summaryrefslogtreecommitdiff
path: root/support/dktools
diff options
context:
space:
mode:
Diffstat (limited to 'support/dktools')
-rw-r--r--support/dktools/Dk4Comparable.cpp58
-rw-r--r--support/dktools/Dk4Comparable.cpt67
-rw-r--r--support/dktools/Dk4Comparable.h87
-rw-r--r--support/dktools/Dk4Container.cpt391
-rw-r--r--support/dktools/Dk4Container.h440
-rw-r--r--support/dktools/Dk4FcsApp.cpp425
-rw-r--r--support/dktools/Dk4FcsApp.cpt418
-rw-r--r--support/dktools/Dk4FcsApp.h95
-rw-r--r--support/dktools/Dk4FcsFrame.cpp1122
-rw-r--r--support/dktools/Dk4FcsFrame.h255
-rw-r--r--support/dktools/Dk4FcsFrame.wxc967
-rw-r--r--support/dktools/Dk4FcsThread.cpp244
-rw-r--r--support/dktools/Dk4FcsThread.h141
-rw-r--r--support/dktools/Dk4WxApplicationHelper.cpp2309
-rw-r--r--support/dktools/Dk4WxApplicationHelper.cpt2677
-rw-r--r--support/dktools/Dk4WxApplicationHelper.h754
-rw-r--r--support/dktools/Dk4WxAutostartController.cpp179
-rw-r--r--support/dktools/Dk4WxAutostartController.cpt302
-rw-r--r--support/dktools/Dk4WxAutostartController.h199
-rw-r--r--support/dktools/Dk4WxControl.cpp304
-rw-r--r--support/dktools/Dk4WxControl.cpt434
-rw-r--r--support/dktools/Dk4WxControl.h237
-rw-r--r--support/dktools/Dk4WxFrame.cpp323
-rw-r--r--support/dktools/Dk4WxFrame.cpt372
-rw-r--r--support/dktools/Dk4WxFrame.h169
-rw-r--r--support/dktools/Dk4WxHelpController.cpp255
-rw-r--r--support/dktools/Dk4WxHelpController.cpt364
-rw-r--r--support/dktools/Dk4WxHelpController.h191
-rw-r--r--support/dktools/Dk4WxProgressControllerBase.h136
-rw-r--r--support/dktools/Dk4WxProgressDialog.cpp416
-rw-r--r--support/dktools/Dk4WxProgressDialog.h246
-rw-r--r--support/dktools/Dk4WxProgressDialog.wxc541
-rw-r--r--support/dktools/DkClockApp.cpp413
-rw-r--r--support/dktools/DkClockApp.cpt421
-rw-r--r--support/dktools/DkClockApp.h94
-rw-r--r--support/dktools/DkClockData.cpp210
-rw-r--r--support/dktools/DkClockData.cpt242
-rw-r--r--support/dktools/DkClockData.h98
-rw-r--r--support/dktools/DkClockFrame.cpp764
-rw-r--r--support/dktools/DkClockFrame.h337
-rw-r--r--support/dktools/DkClockFrame.wxc797
-rw-r--r--support/dktools/DkClockOptionsDialog.cpp353
-rw-r--r--support/dktools/DkClockOptionsDialog.h158
-rw-r--r--support/dktools/DkClockOptionsDialog.wxc236
-rw-r--r--support/dktools/DkClockTaskbarIcon.cpp149
-rw-r--r--support/dktools/DkClockTaskbarIcon.cpt151
-rw-r--r--support/dktools/DkClockTaskbarIcon.h100
-rw-r--r--support/dktools/DkClockView.cpp376
-rw-r--r--support/dktools/DkClockView.cpt482
-rw-r--r--support/dktools/DkClockView.h196
-rw-r--r--support/dktools/DkWxAppHelper.cpp1403
-rw-r--r--support/dktools/DkWxAppHelper.cpt1465
-rw-r--r--support/dktools/DkWxAppHelper.h369
-rw-r--r--support/dktools/DkWxBmepsApp.cpp655
-rw-r--r--support/dktools/DkWxBmepsApp.cpt746
-rw-r--r--support/dktools/DkWxBmepsApp.h82
-rw-r--r--support/dktools/DkWxBmepsFrame.cpp1321
-rw-r--r--support/dktools/DkWxBmepsFrame.h389
-rw-r--r--support/dktools/DkWxBmepsFrame.wxc1171
-rw-r--r--support/dktools/DkWxBmepsOptionsDialog.cpp1216
-rw-r--r--support/dktools/DkWxBmepsOptionsDialog.h402
-rw-r--r--support/dktools/DkWxBmepsOptionsDialog.wxc913
-rw-r--r--support/dktools/DkWxBmepsThread.cpp581
-rw-r--r--support/dktools/DkWxBmepsThread.cpt622
-rw-r--r--support/dktools/DkWxBmepsThread.h163
-rw-r--r--support/dktools/DkWxBufferedControl.cpp342
-rw-r--r--support/dktools/DkWxBufferedControl.cpt431
-rw-r--r--support/dktools/DkWxBufferedControl.h225
-rw-r--r--support/dktools/DkWxColorView.cpp247
-rw-r--r--support/dktools/DkWxColorView.cpt385
-rw-r--r--support/dktools/DkWxColorView.h223
-rw-r--r--support/dktools/DkWxCommunicator.cpp529
-rw-r--r--support/dktools/DkWxCommunicator.cpt697
-rw-r--r--support/dktools/DkWxCommunicator.h306
-rw-r--r--support/dktools/DkWxDialog.cpp38
-rw-r--r--support/dktools/DkWxDialog.cpt56
-rw-r--r--support/dktools/DkWxDialog.h46
-rw-r--r--support/dktools/DkWxFrame.cpp422
-rw-r--r--support/dktools/DkWxFrame.cpt417
-rw-r--r--support/dktools/DkWxFrame.h149
-rw-r--r--support/dktools/DkWxHelpController.cpp172
-rw-r--r--support/dktools/DkWxHelpController.cpt200
-rw-r--r--support/dktools/DkWxHelpController.h126
-rw-r--r--support/dktools/DkWxHtbApp.cpp360
-rw-r--r--support/dktools/DkWxHtbApp.cpt388
-rw-r--r--support/dktools/DkWxHtbApp.h94
-rw-r--r--support/dktools/DkWxHtbFrame.cpp361
-rw-r--r--support/dktools/DkWxHtbFrame.h214
-rw-r--r--support/dktools/DkWxHtbFrame.wxc379
-rw-r--r--support/dktools/DkWxImgszApp.cpp404
-rw-r--r--support/dktools/DkWxImgszApp.cpt452
-rw-r--r--support/dktools/DkWxImgszApp.h84
-rw-r--r--support/dktools/DkWxImgszFrame.cpp1075
-rw-r--r--support/dktools/DkWxImgszFrame.h404
-rw-r--r--support/dktools/DkWxImgszFrame.wxc960
-rw-r--r--support/dktools/DkWxImgszOptionsDialog.cpp219
-rw-r--r--support/dktools/DkWxImgszOptionsDialog.h158
-rw-r--r--support/dktools/DkWxImgszOptionsDialog.wxc206
-rw-r--r--support/dktools/DkWxPathApp.cpp276
-rw-r--r--support/dktools/DkWxPathApp.cpt279
-rw-r--r--support/dktools/DkWxPathApp.h79
-rw-r--r--support/dktools/DkWxPathFrame.cpp1044
-rw-r--r--support/dktools/DkWxPathFrame.h158
-rw-r--r--support/dktools/DkWxPathFrame.wxc972
-rw-r--r--support/dktools/DkWxProcessingController.cpp79
-rw-r--r--support/dktools/DkWxProcessingController.cpt96
-rw-r--r--support/dktools/DkWxProcessingController.h97
-rw-r--r--support/dktools/DkWxProcessingIdleController.cpp89
-rw-r--r--support/dktools/DkWxProcessingIdleController.cpt97
-rw-r--r--support/dktools/DkWxProcessingIdleController.h88
-rw-r--r--support/dktools/DkWxProgressDialog.cpp360
-rw-r--r--support/dktools/DkWxProgressDialog.h166
-rw-r--r--support/dktools/DkWxProgressDialog.wxc318
-rw-r--r--support/dktools/DkWxTraceApp.cpp562
-rw-r--r--support/dktools/DkWxTraceApp.cpt594
-rw-r--r--support/dktools/DkWxTraceApp.h82
-rw-r--r--support/dktools/DkWxTraceFrame.cpp1037
-rw-r--r--support/dktools/DkWxTraceFrame.h345
-rw-r--r--support/dktools/DkWxTraceFrame.wxc1017
-rw-r--r--support/dktools/DkWxTraceOptionsDialog.cpp557
-rw-r--r--support/dktools/DkWxTraceOptionsDialog.h237
-rw-r--r--support/dktools/DkWxTraceOptionsDialog.wxc418
-rw-r--r--support/dktools/DkWxTraceThread.cpp413
-rw-r--r--support/dktools/DkWxTraceThread.cpt425
-rw-r--r--support/dktools/DkWxTraceThread.h152
-rw-r--r--support/dktools/Doxyfile2362
-rw-r--r--support/dktools/INSTALL112
-rw-r--r--support/dktools/LICENSE19
-rw-r--r--support/dktools/Makefile3069
-rw-r--r--support/dktools/Makefile.in3008
-rw-r--r--support/dktools/README105
-rw-r--r--support/dktools/ScreenSizeApp.cpp409
-rw-r--r--support/dktools/ScreenSizeApp.cpt455
-rw-r--r--support/dktools/ScreenSizeApp.h99
-rw-r--r--support/dktools/ScreenSizeFrame.cpp897
-rw-r--r--support/dktools/ScreenSizeFrame.h329
-rw-r--r--support/dktools/ScreenSizeFrame.wxc788
-rw-r--r--support/dktools/TODO15
-rw-r--r--support/dktools/WinprintApp.cpp556
-rw-r--r--support/dktools/WinprintApp.cpt635
-rw-r--r--support/dktools/WinprintApp.h120
-rw-r--r--support/dktools/WinprintChooserDialog.cpp259
-rw-r--r--support/dktools/WinprintChooserDialog.h164
-rw-r--r--support/dktools/WinprintChooserDialog.wxc253
-rw-r--r--support/dktools/WinprintFrame.cpp923
-rw-r--r--support/dktools/WinprintFrame.h326
-rw-r--r--support/dktools/WinprintFrame.wxc875
-rw-r--r--support/dktools/WinprintThread.cpp319
-rw-r--r--support/dktools/WinprintThread.cpt337
-rw-r--r--support/dktools/WinprintThread.h122
-rw-r--r--support/dktools/WxpqdicApp.cpp549
-rw-r--r--support/dktools/WxpqdicApp.cpt569
-rw-r--r--support/dktools/WxpqdicApp.h106
-rw-r--r--support/dktools/WxpqdicFrame.cpp1592
-rw-r--r--support/dktools/WxpqdicFrame.h453
-rw-r--r--support/dktools/WxpqdicFrame.wxc1540
-rw-r--r--support/dktools/aclocal.m4251
-rw-r--r--support/dktools/addctrld.c202
-rw-r--r--support/dktools/addctrld.ctr190
-rw-r--r--support/dktools/addctrld.rc37
-rw-r--r--support/dktools/autom4te.cache/output.015822
-rw-r--r--support/dktools/autom4te.cache/requests79
-rw-r--r--support/dktools/autom4te.cache/traces.02757
-rw-r--r--support/dktools/bmeps3.c1349
-rw-r--r--support/dktools/bmeps3.ctr1205
-rw-r--r--support/dktools/bmeps3.h47
-rw-r--r--support/dktools/bmpp.rc37
-rw-r--r--support/dktools/bsdlic.txt35
-rw-r--r--support/dktools/changes.dox89
-rw-r--r--support/dktools/choose-dir.xpm38
-rw-r--r--support/dktools/conceptions.dox179
-rw-r--r--support/dktools/conf.vc312
-rwxr-xr-xsupport/dktools/config.guess1421
-rw-r--r--support/dktools/config.h.in1334
-rwxr-xr-xsupport/dktools/config.sub1807
-rwxr-xr-xsupport/dktools/configure15822
-rw-r--r--support/dktools/configure.ac3498
-rw-r--r--support/dktools/contrib/README13
-rw-r--r--support/dktools/contrib/gs-fonts-svg/COPYING674
-rw-r--r--support/dktools/contrib/gs-fonts-svg/INSTALL71
-rw-r--r--support/dktools/contrib/gs-fonts-svg/README42
-rw-r--r--support/dktools/contrib/gs-fonts-svg/crpfb.cmd41
-rwxr-xr-xsupport/dktools/contrib/gs-fonts-svg/crpfb.sh72
-rwxr-xr-xsupport/dktools/contrib/gs-fonts-svg/crsvg.sh77
-rwxr-xr-xsupport/dktools/contrib/gs-fonts-svg/crttf.sh73
-rw-r--r--support/dktools/contrib/gs-fonts-svg/index.html51
-rw-r--r--support/dktools/contrib/gs-fonts-svg/metadata.sed4
-rw-r--r--support/dktools/contrib/gs-fonts-svg/pfb2svg.pe5
-rwxr-xr-xsupport/dktools/debian-jessie-build-deb.sh73
-rwxr-xr-xsupport/dktools/debian-jessie-build-live.sh2037
-rwxr-xr-xsupport/dktools/debian-jessie-prepare.sh53
-rw-r--r--support/dktools/debian/README.source10
-rw-r--r--support/dktools/debian/changelog830
-rw-r--r--support/dktools/debian/changelog.in5
-rw-r--r--support/dktools/debian/compat1
-rw-r--r--support/dktools/debian/control69
-rw-r--r--support/dktools/debian/control.in69
-rw-r--r--support/dktools/debian/copyright41
-rw-r--r--support/dktools/debian/dktools-data.install4
-rw-r--r--support/dktools/debian/dktools-doc.docs1
-rw-r--r--support/dktools/debian/dktools-doc.install1
-rw-r--r--support/dktools/debian/dktools-lib-4.8-dev.install3
-rw-r--r--support/dktools/debian/dktools-lib-4.8.install1
-rw-r--r--support/dktools/debian/dktools-lib-4.8.lintian-overrides1
-rw-r--r--support/dktools/debian/dktools-lib-4.8.postinst55
-rw-r--r--support/dktools/debian/dktools-lib-4.8.postrm47
-rw-r--r--support/dktools/debian/dktools-lib-data.install1
-rw-r--r--support/dktools/debian/dktools-lib-dev.install.in3
-rw-r--r--support/dktools/debian/dktools-lib.install.in1
-rw-r--r--support/dktools/debian/dktools-lib.postinst.in55
-rw-r--r--support/dktools/debian/dktools-lib.postrm.in47
-rw-r--r--support/dktools/debian/dktools.install2
-rw-r--r--support/dktools/debian/dktools.manpages56
-rw-r--r--support/dktools/debian/docs3
-rw-r--r--support/dktools/debian/rules33
-rw-r--r--support/dktools/debian/source/format1
-rw-r--r--support/dktools/dk-blks.c1012
-rw-r--r--support/dktools/dk-blks.ctr959
-rw-r--r--support/dktools/dk-blks.rc37
-rw-r--r--support/dktools/dk-bmm.c2119
-rw-r--r--support/dktools/dk-bmm.ctr1944
-rw-r--r--support/dktools/dk-bmm.rc37
-rw-r--r--support/dktools/dk-cat.c2433
-rw-r--r--support/dktools/dk-cat.ctr2236
-rw-r--r--support/dktools/dk-cat.rc37
-rw-r--r--support/dktools/dk-db2t.c1189
-rw-r--r--support/dktools/dk-db2t.ctr1135
-rw-r--r--support/dktools/dk-db2t.rc37
-rw-r--r--support/dktools/dk-dbco.c1097
-rw-r--r--support/dktools/dk-dbco.ctr1025
-rw-r--r--support/dktools/dk-dbco.rc37
-rw-r--r--support/dktools/dk-eradisk.c959
-rw-r--r--support/dktools/dk-eradisk.ctr920
-rw-r--r--support/dktools/dk-eradisk.rc37
-rw-r--r--support/dktools/dk-fic.c2210
-rw-r--r--support/dktools/dk-fic.ctr2047
-rw-r--r--support/dktools/dk-fic.rc37
-rw-r--r--support/dktools/dk-hex.c1201
-rw-r--r--support/dktools/dk-hex.ctr1162
-rw-r--r--support/dktools/dk-hex.rc37
-rw-r--r--support/dktools/dk-ls-to.c270
-rw-r--r--support/dktools/dk-ls-to.ctr229
-rw-r--r--support/dktools/dk-ls.c3242
-rw-r--r--support/dktools/dk-ls.ctr3073
-rw-r--r--support/dktools/dk-ls.h119
-rw-r--r--support/dktools/dk-ls.rc37
-rw-r--r--support/dktools/dk-pwd.c432
-rw-r--r--support/dktools/dk-pwd.ctr395
-rw-r--r--support/dktools/dk-pwg-rnd.c510
-rw-r--r--support/dktools/dk-pwg-rnd.ctr555
-rw-r--r--support/dktools/dk-pwg-rnd.h129
-rw-r--r--support/dktools/dk-pwgen.c2179
-rw-r--r--support/dktools/dk-pwgen.ctr2056
-rw-r--r--support/dktools/dk-pwgen.rc37
-rw-r--r--support/dktools/dk-rand.c1034
-rw-r--r--support/dktools/dk-rand.ctr999
-rw-r--r--support/dktools/dk-rand.rc37
-rw-r--r--support/dktools/dk-recv.c1226
-rw-r--r--support/dktools/dk-recv.ctr1112
-rw-r--r--support/dktools/dk-recv.rc37
-rw-r--r--support/dktools/dk-send.c1901
-rw-r--r--support/dktools/dk-send.ctr1807
-rw-r--r--support/dktools/dk-send.rc37
-rw-r--r--support/dktools/dk-sort.c1855
-rw-r--r--support/dktools/dk-sort.ctr1728
-rw-r--r--support/dktools/dk-sort.rc37
-rw-r--r--support/dktools/dk-sqlsplit.c982
-rw-r--r--support/dktools/dk-sqlsplit.ctr582
-rw-r--r--support/dktools/dk-sqlsplit.rc37
-rw-r--r--support/dktools/dk-t2db.c1629
-rw-r--r--support/dktools/dk-t2db.ctr1538
-rw-r--r--support/dktools/dk-t2db.rc37
-rw-r--r--support/dktools/dk-t2h.c2342
-rw-r--r--support/dktools/dk-t2h.ctr2172
-rw-r--r--support/dktools/dk-t2h.rc37
-rw-r--r--support/dktools/dk-t2l.c2026
-rw-r--r--support/dktools/dk-t2l.ctr1955
-rw-r--r--support/dktools/dk-t2l.rc37
-rw-r--r--support/dktools/dk-uid.c937
-rw-r--r--support/dktools/dk-uid.ctr891
-rw-r--r--support/dktools/dk3.h13
-rw-r--r--support/dktools/dk3all.h267
-rw-r--r--support/dktools/dk3app.c6979
-rw-r--r--support/dktools/dk3app.ctr7422
-rw-r--r--support/dktools/dk3app.h733
-rw-r--r--support/dktools/dk3appr.c857
-rw-r--r--support/dktools/dk3appr.ctr759
-rw-r--r--support/dktools/dk3bb.c223
-rw-r--r--support/dktools/dk3bb.ctr225
-rw-r--r--support/dktools/dk3bb.h118
-rw-r--r--support/dktools/dk3bezcu.c455
-rw-r--r--support/dktools/dk3bezcu.ctr408
-rw-r--r--support/dktools/dk3bezcu.h98
-rw-r--r--support/dktools/dk3bf.c760
-rw-r--r--support/dktools/dk3bf.ctr766
-rw-r--r--support/dktools/dk3bf.h139
-rw-r--r--support/dktools/dk3bif.c3171
-rw-r--r--support/dktools/dk3bif.ctr3115
-rw-r--r--support/dktools/dk3bif.h428
-rw-r--r--support/dktools/dk3bifa.c602
-rw-r--r--support/dktools/dk3bifa.ctr608
-rw-r--r--support/dktools/dk3bifa.h86
-rw-r--r--support/dktools/dk3bits.c81
-rw-r--r--support/dktools/dk3bits.ctr69
-rw-r--r--support/dktools/dk3bits.h64
-rw-r--r--support/dktools/dk3bm.c4365
-rw-r--r--support/dktools/dk3bm.ctr4006
-rw-r--r--support/dktools/dk3bm.h141
-rw-r--r--support/dktools/dk3bmeo.c1995
-rw-r--r--support/dktools/dk3bmeo.ctr1904
-rw-r--r--support/dktools/dk3bmeo.h356
-rw-r--r--support/dktools/dk3bmep.c41
-rw-r--r--support/dktools/dk3bmep.ctr25
-rw-r--r--support/dktools/dk3bmep.h61
-rw-r--r--support/dktools/dk3bmeps.c308
-rw-r--r--support/dktools/dk3bmeps.ctr320
-rw-r--r--support/dktools/dk3bmeps.h69
-rw-r--r--support/dktools/dk3bmj.c584
-rw-r--r--support/dktools/dk3bmj.ctr780
-rw-r--r--support/dktools/dk3bmj.h338
-rw-r--r--support/dktools/dk3bom.c223
-rw-r--r--support/dktools/dk3bom.ctr258
-rw-r--r--support/dktools/dk3bom.h109
-rw-r--r--support/dktools/dk3chks.c397
-rw-r--r--support/dktools/dk3chks.ctr416
-rw-r--r--support/dktools/dk3chks.h101
-rw-r--r--support/dktools/dk3conf.cross2795
-rw-r--r--support/dktools/dk3conf.cross.in2094
-rw-r--r--support/dktools/dk3conf.h4234
-rw-r--r--support/dktools/dk3confd.h194
-rw-r--r--support/dktools/dk3config.c4486
-rw-r--r--support/dktools/dk3conft.h21
-rw-r--r--support/dktools/dk3const.h2013
-rw-r--r--support/dktools/dk3cores.c460
-rw-r--r--support/dktools/dk3cores.ctr436
-rw-r--r--support/dktools/dk3cores.h80
-rw-r--r--support/dktools/dk3ct.c108
-rw-r--r--support/dktools/dk3ct.ctr99
-rw-r--r--support/dktools/dk3ct.h82
-rw-r--r--support/dktools/dk3dbi.c2738
-rw-r--r--support/dktools/dk3dbi.ctr2726
-rw-r--r--support/dktools/dk3dbi.h407
-rw-r--r--support/dktools/dk3dir.c1484
-rw-r--r--support/dktools/dk3dir.ctr1394
-rw-r--r--support/dktools/dk3dir.h159
-rw-r--r--support/dktools/dk3echo.c316
-rw-r--r--support/dktools/dk3echo.ctr441
-rw-r--r--support/dktools/dk3echo.h203
-rw-r--r--support/dktools/dk3enc.c1880
-rw-r--r--support/dktools/dk3enc.ctr2020
-rw-r--r--support/dktools/dk3enc.h347
-rw-r--r--support/dktools/dk3fig.c1456
-rw-r--r--support/dktools/dk3fig.ctr2380
-rw-r--r--support/dktools/dk3fig.h1146
-rw-r--r--support/dktools/dk3figah.c7098
-rw-r--r--support/dktools/dk3figah.ctr6281
-rw-r--r--support/dktools/dk3figah.h75
-rw-r--r--support/dktools/dk3figbb.c650
-rw-r--r--support/dktools/dk3figbb.ctr641
-rw-r--r--support/dktools/dk3figbb.h161
-rw-r--r--support/dktools/dk3figpr.c1390
-rw-r--r--support/dktools/dk3figpr.ctr1259
-rw-r--r--support/dktools/dk3figpr.h83
-rw-r--r--support/dktools/dk3figrd.c2128
-rw-r--r--support/dktools/dk3figrd.ctr1803
-rw-r--r--support/dktools/dk3figrd.h80
-rw-r--r--support/dktools/dk3figto.c1007
-rw-r--r--support/dktools/dk3figto.ctr1152
-rw-r--r--support/dktools/dk3figto.h319
-rw-r--r--support/dktools/dk3font.c979
-rw-r--r--support/dktools/dk3font.ctr996
-rw-r--r--support/dktools/dk3font.h167
-rw-r--r--support/dktools/dk3info.c193
-rw-r--r--support/dktools/dk3info.ctr161
-rw-r--r--support/dktools/dk3info.rc37
-rw-r--r--support/dktools/dk3info1.c1705
-rw-r--r--support/dktools/dk3inst.c50
-rw-r--r--support/dktools/dk3inst.h34
-rw-r--r--support/dktools/dk3kv.c114
-rw-r--r--support/dktools/dk3kv.ctr116
-rw-r--r--support/dktools/dk3kv.h80
-rw-r--r--support/dktools/dk3ma.h72
-rw-r--r--support/dktools/dk3mad.c517
-rw-r--r--support/dktools/dk3mad.ctr577
-rw-r--r--support/dktools/dk3mad.h193
-rw-r--r--support/dktools/dk3madfo.c227
-rw-r--r--support/dktools/dk3madfo.ctr243
-rw-r--r--support/dktools/dk3madfo.h100
-rw-r--r--support/dktools/dk3madic.c91
-rw-r--r--support/dktools/dk3madic.ctr112
-rw-r--r--support/dktools/dk3madic.h96
-rw-r--r--support/dktools/dk3madlc.c706
-rw-r--r--support/dktools/dk3madlc.ctr767
-rw-r--r--support/dktools/dk3madlc.h174
-rw-r--r--support/dktools/dk3madsc.c90
-rw-r--r--support/dktools/dk3madsc.ctr115
-rw-r--r--support/dktools/dk3madsc.h101
-rw-r--r--support/dktools/dk3madsi.c194
-rw-r--r--support/dktools/dk3madsi.ctr206
-rw-r--r--support/dktools/dk3madsi.h104
-rw-r--r--support/dktools/dk3madso.c137
-rw-r--r--support/dktools/dk3madso.ctr159
-rw-r--r--support/dktools/dk3madso.h98
-rw-r--r--support/dktools/dk3mafpe.c245
-rw-r--r--support/dktools/dk3mafpe.ctr458
-rw-r--r--support/dktools/dk3mafpe.h293
-rw-r--r--support/dktools/dk3mai.c224
-rw-r--r--support/dktools/dk3mai.ctr289
-rw-r--r--support/dktools/dk3mai.h140
-rw-r--r--support/dktools/dk3maid8.c542
-rw-r--r--support/dktools/dk3maid8.ctr705
-rw-r--r--support/dktools/dk3maid8.h256
-rw-r--r--support/dktools/dk3maidd.c592
-rw-r--r--support/dktools/dk3maidd.ctr754
-rw-r--r--support/dktools/dk3maidd.h255
-rw-r--r--support/dktools/dk3maih8.c657
-rw-r--r--support/dktools/dk3maih8.ctr819
-rw-r--r--support/dktools/dk3maih8.h255
-rw-r--r--support/dktools/dk3maihd.c706
-rw-r--r--support/dktools/dk3maihd.ctr869
-rw-r--r--support/dktools/dk3maihd.h256
-rw-r--r--support/dktools/dk3mal.c680
-rw-r--r--support/dktools/dk3mal.ctr943
-rw-r--r--support/dktools/dk3mal.h338
-rw-r--r--support/dktools/dk3maod8.c148
-rw-r--r--support/dktools/dk3maod8.ctr170
-rw-r--r--support/dktools/dk3maod8.h97
-rw-r--r--support/dktools/dk3maodd.c157
-rw-r--r--support/dktools/dk3maodd.ctr179
-rw-r--r--support/dktools/dk3maodd.h97
-rw-r--r--support/dktools/dk3maoh8.c178
-rw-r--r--support/dktools/dk3maoh8.ctr204
-rw-r--r--support/dktools/dk3maoh8.h101
-rw-r--r--support/dktools/dk3maohd.c169
-rw-r--r--support/dktools/dk3maohd.ctr195
-rw-r--r--support/dktools/dk3maohd.h101
-rw-r--r--support/dktools/dk3mas.c232
-rw-r--r--support/dktools/dk3mas.ctr297
-rw-r--r--support/dktools/dk3mas.h140
-rw-r--r--support/dktools/dk3masts.c189
-rw-r--r--support/dktools/dk3masts.ctr147
-rw-r--r--support/dktools/dk3masts.h71
-rw-r--r--support/dktools/dk3maui.c114
-rw-r--r--support/dktools/dk3maui.ctr169
-rw-r--r--support/dktools/dk3maui.h130
-rw-r--r--support/dktools/dk3maul.c601
-rw-r--r--support/dktools/dk3maul.ctr707
-rw-r--r--support/dktools/dk3maul.h303
-rw-r--r--support/dktools/dk3maus.c114
-rw-r--r--support/dktools/dk3maus.ctr169
-rw-r--r--support/dktools/dk3maus.h130
-rw-r--r--support/dktools/dk3md.c644
-rw-r--r--support/dktools/dk3md.ctr886
-rw-r--r--support/dktools/dk3md.h319
-rw-r--r--support/dktools/dk3mem.c348
-rw-r--r--support/dktools/dk3mem.ctr450
-rw-r--r--support/dktools/dk3mem.h201
-rw-r--r--support/dktools/dk3nettp.h103
-rw-r--r--support/dktools/dk3numco.h640
-rw-r--r--support/dktools/dk3of.c1376
-rw-r--r--support/dktools/dk3of.ctr1335
-rw-r--r--support/dktools/dk3of.h185
-rw-r--r--support/dktools/dk3opt.c754
-rw-r--r--support/dktools/dk3opt.ctr769
-rw-r--r--support/dktools/dk3opt.h203
-rw-r--r--support/dktools/dk3paper.c542
-rw-r--r--support/dktools/dk3paper.ctr500
-rw-r--r--support/dktools/dk3paper.h92
-rw-r--r--support/dktools/dk3pdf.c4295
-rw-r--r--support/dktools/dk3pdf.ctr4233
-rw-r--r--support/dktools/dk3pdf.h428
-rw-r--r--support/dktools/dk3pixre.c453
-rw-r--r--support/dktools/dk3pixre.ctr485
-rw-r--r--support/dktools/dk3pixre.h110
-rw-r--r--support/dktools/dk3prcfg.c2187
-rw-r--r--support/dktools/dk3prcfg.ctr1960
-rw-r--r--support/dktools/dk3prcfg.h62
-rw-r--r--support/dktools/dk3print.c1269
-rw-r--r--support/dktools/dk3print.ctr1297
-rw-r--r--support/dktools/dk3print.h172
-rw-r--r--support/dktools/dk3prreq.c298
-rw-r--r--support/dktools/dk3prreq.ctr305
-rw-r--r--support/dktools/dk3prreq.h33
-rw-r--r--support/dktools/dk3range.h15
-rw-r--r--support/dktools/dk3se.c502
-rw-r--r--support/dktools/dk3se.ctr516
-rw-r--r--support/dktools/dk3se.h133
-rw-r--r--support/dktools/dk3sf.c4291
-rw-r--r--support/dktools/dk3sf.ctr4689
-rw-r--r--support/dktools/dk3sf.h783
-rw-r--r--support/dktools/dk3signl.c151
-rw-r--r--support/dktools/dk3signl.ctr155
-rw-r--r--support/dktools/dk3signl.h82
-rw-r--r--support/dktools/dk3srch.c237
-rw-r--r--support/dktools/dk3srch.ctr242
-rw-r--r--support/dktools/dk3srch.h96
-rw-r--r--support/dktools/dk3stm.h24
-rw-r--r--support/dktools/dk3sto.c2238
-rw-r--r--support/dktools/dk3sto.ctr2147
-rw-r--r--support/dktools/dk3sto.h290
-rw-r--r--support/dktools/dk3str.c4640
-rw-r--r--support/dktools/dk3str.ctr5904
-rw-r--r--support/dktools/dk3str.h1463
-rw-r--r--support/dktools/dk3strkv.c674
-rw-r--r--support/dktools/dk3strkv.ctr344
-rw-r--r--support/dktools/dk3strkv.h44
-rw-r--r--support/dktools/dk3strm.c2808
-rw-r--r--support/dktools/dk3strm.ctr2886
-rw-r--r--support/dktools/dk3strm.h459
-rw-r--r--support/dktools/dk3strmb.c161
-rw-r--r--support/dktools/dk3strmb.ctr127
-rw-r--r--support/dktools/dk3strmg.c160
-rw-r--r--support/dktools/dk3strmg.ctr126
-rw-r--r--support/dktools/dk3trace.c309
-rw-r--r--support/dktools/dk3trace.ctr432
-rw-r--r--support/dktools/dk3trace.h199
-rw-r--r--support/dktools/dk3types.h2702
-rw-r--r--support/dktools/dk3uc2l.c2223
-rw-r--r--support/dktools/dk3uc2l.ctr2062
-rw-r--r--support/dktools/dk3uc2l.h194
-rw-r--r--support/dktools/dk3ufi.c438
-rw-r--r--support/dktools/dk3ufi.ctr423
-rw-r--r--support/dktools/dk3ufi.h118
-rw-r--r--support/dktools/dk3usewx.c7
-rw-r--r--support/dktools/dk3wreg.c782
-rw-r--r--support/dktools/dk3wreg.ctr835
-rw-r--r--support/dktools/dk3wreg.h237
-rw-r--r--support/dktools/dk3wxcs.h12
-rw-r--r--support/dktools/dk3wxs.cpp934
-rw-r--r--support/dktools/dk3wxs.cpt1190
-rw-r--r--support/dktools/dk3wxs.h369
-rw-r--r--support/dktools/dk3xsp.c1722
-rw-r--r--support/dktools/dk3xsp.ctr1660
-rw-r--r--support/dktools/dk3xsp.h297
-rw-r--r--support/dktools/dk4.dox127
-rw-r--r--support/dktools/dk4.h16
-rw-r--r--support/dktools/dk4a85d.c348
-rw-r--r--support/dktools/dk4a85d.ctr402
-rw-r--r--support/dktools/dk4a85d.h151
-rw-r--r--support/dktools/dk4a85e.c309
-rw-r--r--support/dktools/dk4a85e.ctr345
-rw-r--r--support/dktools/dk4a85e.h159
-rw-r--r--support/dktools/dk4ahd.c239
-rw-r--r--support/dktools/dk4ahd.ctr298
-rw-r--r--support/dktools/dk4ahd.h134
-rw-r--r--support/dktools/dk4align.h53
-rw-r--r--support/dktools/dk4ansi.c156
-rw-r--r--support/dktools/dk4ansi.ctr172
-rw-r--r--support/dktools/dk4ansi.h89
-rw-r--r--support/dktools/dk4aopt.h482
-rw-r--r--support/dktools/dk4aopt01.c72
-rw-r--r--support/dktools/dk4aopt01.ctr41
-rw-r--r--support/dktools/dk4aopt02.c72
-rw-r--r--support/dktools/dk4aopt02.ctr41
-rw-r--r--support/dktools/dk4aopt03.c74
-rw-r--r--support/dktools/dk4aopt03.ctr43
-rw-r--r--support/dktools/dk4aopt04.c102
-rw-r--r--support/dktools/dk4aopt04.ctr49
-rw-r--r--support/dktools/dk4aopt05.c72
-rw-r--r--support/dktools/dk4aopt05.ctr41
-rw-r--r--support/dktools/dk4aopt06.c74
-rw-r--r--support/dktools/dk4aopt06.ctr43
-rw-r--r--support/dktools/dk4aopt07.c73
-rw-r--r--support/dktools/dk4aopt07.ctr42
-rw-r--r--support/dktools/dk4aopt08.c74
-rw-r--r--support/dktools/dk4aopt08.ctr43
-rw-r--r--support/dktools/dk4aopt09.c74
-rw-r--r--support/dktools/dk4aopt09.ctr43
-rw-r--r--support/dktools/dk4aopt10.c74
-rw-r--r--support/dktools/dk4aopt10.ctr43
-rw-r--r--support/dktools/dk4aopt11.c72
-rw-r--r--support/dktools/dk4aopt11.ctr41
-rw-r--r--support/dktools/dk4aopt12.c74
-rw-r--r--support/dktools/dk4aopt12.ctr43
-rw-r--r--support/dktools/dk4aopt13.c72
-rw-r--r--support/dktools/dk4aopt13.ctr41
-rw-r--r--support/dktools/dk4aopt14.c74
-rw-r--r--support/dktools/dk4aopt14.ctr43
-rw-r--r--support/dktools/dk4aopt15.c94
-rw-r--r--support/dktools/dk4aopt15.ctr55
-rw-r--r--support/dktools/dk4aopt16.c95
-rw-r--r--support/dktools/dk4aopt16.ctr56
-rw-r--r--support/dktools/dk4app.h1351
-rw-r--r--support/dktools/dk4app/de/dk4base.str444
-rw-r--r--support/dktools/dk4app/de/dk4debug.str89
-rw-r--r--support/dktools/dk4app/de/dk4sock.str506
-rw-r--r--support/dktools/dk4app/de/dk4wxbase.str24
-rw-r--r--support/dktools/dk4appargs.c69
-rw-r--r--support/dktools/dk4appargs.ctr39
-rw-r--r--support/dktools/dk4appdeldir.c259
-rw-r--r--support/dktools/dk4appdeldir.ctr216
-rw-r--r--support/dktools/dk4appdelfile.c243
-rw-r--r--support/dktools/dk4appdelfile.ctr212
-rw-r--r--support/dktools/dk4appdeltree.c716
-rw-r--r--support/dktools/dk4appdeltree.ctr581
-rw-r--r--support/dktools/dk4appenc.c156
-rw-r--r--support/dktools/dk4appenc.ctr123
-rw-r--r--support/dktools/dk4appfne.c144
-rw-r--r--support/dktools/dk4appfne.ctr113
-rw-r--r--support/dktools/dk4appfs01.c113
-rw-r--r--support/dktools/dk4appfs01.ctr82
-rw-r--r--support/dktools/dk4appfs02.c143
-rw-r--r--support/dktools/dk4appfs02.ctr94
-rw-r--r--support/dktools/dk4appfs03.c176
-rw-r--r--support/dktools/dk4appfs03.ctr127
-rw-r--r--support/dktools/dk4appfs04.c156
-rw-r--r--support/dktools/dk4appfs04.ctr123
-rw-r--r--support/dktools/dk4apphlv.c281
-rw-r--r--support/dktools/dk4apphlv.ctr248
-rw-r--r--support/dktools/dk4appi.c92
-rw-r--r--support/dktools/dk4applog.c1666
-rw-r--r--support/dktools/dk4applog.ctr1475
-rw-r--r--support/dktools/dk4appmkdh.c402
-rw-r--r--support/dktools/dk4appmkdh.ctr407
-rw-r--r--support/dktools/dk4appmkdh.h86
-rw-r--r--support/dktools/dk4appop.c3113
-rw-r--r--support/dktools/dk4appop.ctr2692
-rw-r--r--support/dktools/dk4appstt.c190
-rw-r--r--support/dktools/dk4appstt.ctr119
-rw-r--r--support/dktools/dk4apref.c288
-rw-r--r--support/dktools/dk4apref.ctr216
-rw-r--r--support/dktools/dk4aprgs.c357
-rw-r--r--support/dktools/dk4aprgs.ctr292
-rw-r--r--support/dktools/dk4bf.c151
-rw-r--r--support/dktools/dk4bf.ctr193
-rw-r--r--support/dktools/dk4bf.h117
-rw-r--r--support/dktools/dk4binenc.c258
-rw-r--r--support/dktools/dk4binenc.ctr291
-rw-r--r--support/dktools/dk4binenc.h126
-rw-r--r--support/dktools/dk4bitsh.c149
-rw-r--r--support/dktools/dk4bitsh.ctr195
-rw-r--r--support/dktools/dk4bitsh.h121
-rw-r--r--support/dktools/dk4bom.c274
-rw-r--r--support/dktools/dk4bom.ctr383
-rw-r--r--support/dktools/dk4bom.h184
-rw-r--r--support/dktools/dk4c32.c144
-rw-r--r--support/dktools/dk4c32.ctr180
-rw-r--r--support/dktools/dk4c32.h109
-rw-r--r--support/dktools/dk4c8dbl.c455
-rw-r--r--support/dktools/dk4c8dbl.ctr483
-rw-r--r--support/dktools/dk4c8dbl.h133
-rw-r--r--support/dktools/dk4conf.cross3410
-rw-r--r--support/dktools/dk4conf.h1170
-rw-r--r--support/dktools/dk4config.cpp2372
-rw-r--r--support/dktools/dk4const.h60
-rw-r--r--support/dktools/dk4ctime.c199
-rw-r--r--support/dktools/dk4ctime.ctr289
-rw-r--r--support/dktools/dk4ctime.h163
-rw-r--r--support/dktools/dk4dbi.c1983
-rw-r--r--support/dktools/dk4dbi.ctr2284
-rw-r--r--support/dktools/dk4dbi.h588
-rw-r--r--support/dktools/dk4dbia.c231
-rw-r--r--support/dktools/dk4dbia.ctr317
-rw-r--r--support/dktools/dk4dbia.h163
-rw-r--r--support/dktools/dk4dbit.c121
-rw-r--r--support/dktools/dk4dbit.ctr230
-rw-r--r--support/dktools/dk4dbit.h184
-rw-r--r--support/dktools/dk4dbit8.c292
-rw-r--r--support/dktools/dk4dbit8.ctr342
-rw-r--r--support/dktools/dk4dbit8.h179
-rw-r--r--support/dktools/dk4dbitw.c256
-rw-r--r--support/dktools/dk4dbitw.ctr366
-rw-r--r--support/dktools/dk4dbitw.h185
-rw-r--r--support/dktools/dk4dblc8.c126
-rw-r--r--support/dktools/dk4dblc8.ctr147
-rw-r--r--support/dktools/dk4dblc8.h95
-rw-r--r--support/dktools/dk4dbldk.c61
-rw-r--r--support/dktools/dk4dbldk.ctr76
-rw-r--r--support/dktools/dk4dbldk.h90
-rw-r--r--support/dktools/dk4dblwc.c168
-rw-r--r--support/dktools/dk4dblwc.ctr196
-rw-r--r--support/dktools/dk4dblwc.h101
-rw-r--r--support/dktools/dk4dec.h27
-rw-r--r--support/dktools/dk4deldir.c65
-rw-r--r--support/dktools/dk4deldir.ctr83
-rw-r--r--support/dktools/dk4deldir.h91
-rw-r--r--support/dktools/dk4deldir08.c133
-rw-r--r--support/dktools/dk4deldir08.ctr141
-rw-r--r--support/dktools/dk4deldir08.h91
-rw-r--r--support/dktools/dk4deldirwc.c118
-rw-r--r--support/dktools/dk4deldirwc.ctr136
-rw-r--r--support/dktools/dk4deldirwc.h91
-rw-r--r--support/dktools/dk4delfile.c61
-rw-r--r--support/dktools/dk4delfile.ctr78
-rw-r--r--support/dktools/dk4delfile.h90
-rw-r--r--support/dktools/dk4delfile08.c137
-rw-r--r--support/dktools/dk4delfile08.ctr156
-rw-r--r--support/dktools/dk4delfile08.h92
-rw-r--r--support/dktools/dk4delfilewc.c144
-rw-r--r--support/dktools/dk4delfilewc.ctr163
-rw-r--r--support/dktools/dk4delfilewc.h92
-rw-r--r--support/dktools/dk4dir.c145
-rw-r--r--support/dktools/dk4dir.ctr270
-rw-r--r--support/dktools/dk4dir.h198
-rw-r--r--support/dktools/dk4dir08.c540
-rw-r--r--support/dktools/dk4dir08.ctr588
-rw-r--r--support/dktools/dk4dir08.h178
-rw-r--r--support/dktools/dk4dira.c212
-rw-r--r--support/dktools/dk4dira.ctr207
-rw-r--r--support/dktools/dk4dira.h70
-rw-r--r--support/dktools/dk4dirwc.c457
-rw-r--r--support/dktools/dk4dirwc.ctr559
-rw-r--r--support/dktools/dk4dirwc.h178
-rw-r--r--support/dktools/dk4dmt.c608
-rw-r--r--support/dktools/dk4dmt.ctr668
-rw-r--r--support/dktools/dk4dmt.h135
-rw-r--r--support/dktools/dk4edstm.h58
-rw-r--r--support/dktools/dk4enc.c338
-rw-r--r--support/dktools/dk4enc.ctr379
-rw-r--r--support/dktools/dk4enc.h170
-rw-r--r--support/dktools/dk4error.c234
-rw-r--r--support/dktools/dk4error.ctr693
-rw-r--r--support/dktools/dk4error.h547
-rw-r--r--support/dktools/dk4exep.c58
-rw-r--r--support/dktools/dk4exep8.c381
-rw-r--r--support/dktools/dk4exep8.ctr361
-rw-r--r--support/dktools/dk4exep8.h89
-rw-r--r--support/dktools/dk4exepd.c58
-rw-r--r--support/dktools/dk4exepd.ctr65
-rw-r--r--support/dktools/dk4exepd.h80
-rw-r--r--support/dktools/dk4exepw.c190
-rw-r--r--support/dktools/dk4exepw.ctr187
-rw-r--r--support/dktools/dk4exepw.h86
-rw-r--r--support/dktools/dk4fd.c313
-rw-r--r--support/dktools/dk4fd.ctr530
-rw-r--r--support/dktools/dk4fd.h292
-rw-r--r--support/dktools/dk4fdrda.c142
-rw-r--r--support/dktools/dk4fdrda.ctr125
-rw-r--r--support/dktools/dk4fdrda.h73
-rw-r--r--support/dktools/dk4fdrde.c168
-rw-r--r--support/dktools/dk4fdrde.ctr161
-rw-r--r--support/dktools/dk4fdrde.h66
-rw-r--r--support/dktools/dk4fdwre.c181
-rw-r--r--support/dktools/dk4fdwre.ctr174
-rw-r--r--support/dktools/dk4fdwre.h68
-rw-r--r--support/dktools/dk4file8.c205
-rw-r--r--support/dktools/dk4file8.ctr255
-rw-r--r--support/dktools/dk4file8.h123
-rw-r--r--support/dktools/dk4filed.c86
-rw-r--r--support/dktools/dk4filed.ctr137
-rw-r--r--support/dktools/dk4filed.h124
-rw-r--r--support/dktools/dk4filei.c270
-rw-r--r--support/dktools/dk4filei.ctr572
-rw-r--r--support/dktools/dk4filei.h412
-rw-r--r--support/dktools/dk4filei8.c228
-rw-r--r--support/dktools/dk4filei8.ctr197
-rw-r--r--support/dktools/dk4filei8.h78
-rw-r--r--support/dktools/dk4fileia.c228
-rw-r--r--support/dktools/dk4fileia.ctr240
-rw-r--r--support/dktools/dk4fileia.h91
-rw-r--r--support/dktools/dk4fileid.c61
-rw-r--r--support/dktools/dk4fileid.ctr30
-rw-r--r--support/dktools/dk4fileid.h80
-rw-r--r--support/dktools/dk4fileig8.c530
-rw-r--r--support/dktools/dk4fileig8.ctr495
-rw-r--r--support/dktools/dk4fileig8.h89
-rw-r--r--support/dktools/dk4fileigd.c75
-rw-r--r--support/dktools/dk4fileigd.ctr44
-rw-r--r--support/dktools/dk4fileigw.c79
-rw-r--r--support/dktools/dk4fileigw.ctr48
-rw-r--r--support/dktools/dk4fileit.h107
-rw-r--r--support/dktools/dk4fileiu.c128
-rw-r--r--support/dktools/dk4fileiu.ctr95
-rw-r--r--support/dktools/dk4fileiu.h88
-rw-r--r--support/dktools/dk4fileiw.c273
-rw-r--r--support/dktools/dk4fileiw.ctr198
-rw-r--r--support/dktools/dk4fileiw.h81
-rw-r--r--support/dktools/dk4filew.c172
-rw-r--r--support/dktools/dk4filew.ctr228
-rw-r--r--support/dktools/dk4filew.h129
-rw-r--r--support/dktools/dk4fne.c65
-rw-r--r--support/dktools/dk4fne.ctr94
-rw-r--r--support/dktools/dk4fne.h103
-rw-r--r--support/dktools/dk4fne08.c184
-rw-r--r--support/dktools/dk4fne08.ctr199
-rw-r--r--support/dktools/dk4fne08.h96
-rw-r--r--support/dktools/dk4fnewc.c227
-rw-r--r--support/dktools/dk4fnewc.ctr214
-rw-r--r--support/dktools/dk4fnewc.h96
-rw-r--r--support/dktools/dk4font.c493
-rw-r--r--support/dktools/dk4font.ctr364
-rw-r--r--support/dktools/dk4font.h166
-rw-r--r--support/dktools/dk4fopc8.c350
-rw-r--r--support/dktools/dk4fopc8.ctr388
-rw-r--r--support/dktools/dk4fopc8.h143
-rw-r--r--support/dktools/dk4fopd.c64
-rw-r--r--support/dktools/dk4fopd.ctr106
-rw-r--r--support/dktools/dk4fopd.h115
-rw-r--r--support/dktools/dk4fopda.c186
-rw-r--r--support/dktools/dk4fopda.ctr183
-rw-r--r--support/dktools/dk4fopda.h72
-rw-r--r--support/dktools/dk4fopt.h71
-rw-r--r--support/dktools/dk4fopwc.c309
-rw-r--r--support/dktools/dk4fopwc.ctr353
-rw-r--r--support/dktools/dk4fopwc.h145
-rw-r--r--support/dktools/dk4fpe.c224
-rw-r--r--support/dktools/dk4fpe.ctr383
-rw-r--r--support/dktools/dk4fpe.h233
-rw-r--r--support/dktools/dk4fput.c285
-rw-r--r--support/dktools/dk4fput.ctr367
-rw-r--r--support/dktools/dk4fput.h161
-rw-r--r--support/dktools/dk4fs.c982
-rw-r--r--support/dktools/dk4fs.ctr1371
-rw-r--r--support/dktools/dk4fs.h526
-rw-r--r--support/dktools/dk4ft.h99
-rw-r--r--support/dktools/dk4ftime.c89
-rw-r--r--support/dktools/dk4ftime.ctr235
-rw-r--r--support/dktools/dk4ftime.h219
-rw-r--r--support/dktools/dk4ftime08.c87
-rw-r--r--support/dktools/dk4ftime08.ctr56
-rw-r--r--support/dktools/dk4ftimedk.c65
-rw-r--r--support/dktools/dk4ftimedk.ctr34
-rw-r--r--support/dktools/dk4ftimewc.c87
-rw-r--r--support/dktools/dk4ftimewc.ctr56
-rw-r--r--support/dktools/dk4fwra.c81
-rw-r--r--support/dktools/dk4fwra.ctr93
-rw-r--r--support/dktools/dk4fwra.h87
-rw-r--r--support/dktools/dk4getcwd8.c155
-rw-r--r--support/dktools/dk4getcwd8.ctr150
-rw-r--r--support/dktools/dk4getcwd8.h68
-rw-r--r--support/dktools/dk4getcwdd.c73
-rw-r--r--support/dktools/dk4getcwdd.ctr68
-rw-r--r--support/dktools/dk4getcwdd.h70
-rw-r--r--support/dktools/dk4getcwdw.c143
-rw-r--r--support/dktools/dk4getcwdw.ctr140
-rw-r--r--support/dktools/dk4getcwdw.h72
-rw-r--r--support/dktools/dk4getpid.c70
-rw-r--r--support/dktools/dk4getpid.ctr97
-rw-r--r--support/dktools/dk4getpid.h100
-rw-r--r--support/dktools/dk4hname8.c108
-rw-r--r--support/dktools/dk4hname8.ctr122
-rw-r--r--support/dktools/dk4hname8.h87
-rw-r--r--support/dktools/dk4hnamed.c54
-rw-r--r--support/dktools/dk4hnamed.ctr77
-rw-r--r--support/dktools/dk4hnamed.h98
-rw-r--r--support/dktools/dk4hnamew.c93
-rw-r--r--support/dktools/dk4hnamew.ctr109
-rw-r--r--support/dktools/dk4hnamew.h89
-rw-r--r--support/dktools/dk4info.c521
-rw-r--r--support/dktools/dk4info.ctr444
-rw-r--r--support/dktools/dk4info.rc37
-rw-r--r--support/dktools/dk4info1.c1795
-rw-r--r--support/dktools/dk4inst.c62
-rw-r--r--support/dktools/dk4inst.h151
-rw-r--r--support/dktools/dk4isadm.c111
-rw-r--r--support/dktools/dk4isadm.ctr99
-rw-r--r--support/dktools/dk4isadm.h62
-rw-r--r--support/dktools/dk4istty.c104
-rw-r--r--support/dktools/dk4istty.ctr132
-rw-r--r--support/dktools/dk4istty.h101
-rw-r--r--support/dktools/dk4loc.c374
-rw-r--r--support/dktools/dk4loc.ctr353
-rw-r--r--support/dktools/dk4loc.h99
-rw-r--r--support/dktools/dk4lprng.h63
-rw-r--r--support/dktools/dk4lzwe.c580
-rw-r--r--support/dktools/dk4lzwe.ctr614
-rw-r--r--support/dktools/dk4lzwe.h213
-rw-r--r--support/dktools/dk4ma.h715
-rw-r--r--support/dktools/dk4maac.c177
-rw-r--r--support/dktools/dk4maac.ctr228
-rw-r--r--support/dktools/dk4maac.h132
-rw-r--r--support/dktools/dk4maadi.c139
-rw-r--r--support/dktools/dk4maadi.ctr198
-rw-r--r--support/dktools/dk4maadi.h133
-rw-r--r--support/dktools/dk4maadu.c121
-rw-r--r--support/dktools/dk4maadu.ctr170
-rw-r--r--support/dktools/dk4maadu.h122
-rw-r--r--support/dktools/dk4maai.c170
-rw-r--r--support/dktools/dk4maai.ctr229
-rw-r--r--support/dktools/dk4maai.h133
-rw-r--r--support/dktools/dk4maai16.c209
-rw-r--r--support/dktools/dk4maai16.ctr299
-rw-r--r--support/dktools/dk4maai16.h166
-rw-r--r--support/dktools/dk4maai32.c209
-rw-r--r--support/dktools/dk4maai32.ctr299
-rw-r--r--support/dktools/dk4maai32.h166
-rw-r--r--support/dktools/dk4maal.c170
-rw-r--r--support/dktools/dk4maal.ctr229
-rw-r--r--support/dktools/dk4maal.h133
-rw-r--r--support/dktools/dk4maall.c173
-rw-r--r--support/dktools/dk4maall.ctr236
-rw-r--r--support/dktools/dk4maall.h137
-rw-r--r--support/dktools/dk4maalu.c114
-rw-r--r--support/dktools/dk4maalu.ctr159
-rw-r--r--support/dktools/dk4maalu.h126
-rw-r--r--support/dktools/dk4maami.c173
-rw-r--r--support/dktools/dk4maami.ctr236
-rw-r--r--support/dktools/dk4maami.h137
-rw-r--r--support/dktools/dk4maamu.c99
-rw-r--r--support/dktools/dk4maamu.ctr152
-rw-r--r--support/dktools/dk4maamu.h126
-rw-r--r--support/dktools/dk4maas.c170
-rw-r--r--support/dktools/dk4maas.ctr229
-rw-r--r--support/dktools/dk4maas.h132
-rw-r--r--support/dktools/dk4maasz.c103
-rw-r--r--support/dktools/dk4maasz.ctr128
-rw-r--r--support/dktools/dk4maasz.h99
-rw-r--r--support/dktools/dk4maau16.c136
-rw-r--r--support/dktools/dk4maau16.ctr212
-rw-r--r--support/dktools/dk4maau16.h152
-rw-r--r--support/dktools/dk4maau32.c136
-rw-r--r--support/dktools/dk4maau32.ctr212
-rw-r--r--support/dktools/dk4maau32.h152
-rw-r--r--support/dktools/dk4maauc.c94
-rw-r--r--support/dktools/dk4maauc.ctr143
-rw-r--r--support/dktools/dk4maauc.h122
-rw-r--r--support/dktools/dk4maaui.c94
-rw-r--r--support/dktools/dk4maaui.ctr143
-rw-r--r--support/dktools/dk4maaui.h122
-rw-r--r--support/dktools/dk4maaul.c118
-rw-r--r--support/dktools/dk4maaul.ctr153
-rw-r--r--support/dktools/dk4maaul.h122
-rw-r--r--support/dktools/dk4maaus.c94
-rw-r--r--support/dktools/dk4maaus.ctr143
-rw-r--r--support/dktools/dk4maaus.h122
-rw-r--r--support/dktools/dk4macc.c61
-rw-r--r--support/dktools/dk4macc.ctr54
-rw-r--r--support/dktools/dk4macc.h67
-rw-r--r--support/dktools/dk4macd.c70
-rw-r--r--support/dktools/dk4macd.ctr72
-rw-r--r--support/dktools/dk4macd.h75
-rw-r--r--support/dktools/dk4maci.c61
-rw-r--r--support/dktools/dk4maci.ctr55
-rw-r--r--support/dktools/dk4maci.h67
-rw-r--r--support/dktools/dk4maci16.c62
-rw-r--r--support/dktools/dk4maci16.ctr85
-rw-r--r--support/dktools/dk4maci16.h97
-rw-r--r--support/dktools/dk4maci32.c62
-rw-r--r--support/dktools/dk4maci32.ctr85
-rw-r--r--support/dktools/dk4maci32.h97
-rw-r--r--support/dktools/dk4macl.c61
-rw-r--r--support/dktools/dk4macl.ctr55
-rw-r--r--support/dktools/dk4macl.h67
-rw-r--r--support/dktools/dk4macll.c65
-rw-r--r--support/dktools/dk4macll.ctr73
-rw-r--r--support/dktools/dk4macll.h81
-rw-r--r--support/dktools/dk4macm.c67
-rw-r--r--support/dktools/dk4macm.ctr75
-rw-r--r--support/dktools/dk4macm.h81
-rw-r--r--support/dktools/dk4macs.c61
-rw-r--r--support/dktools/dk4macs.ctr55
-rw-r--r--support/dktools/dk4macs.h67
-rw-r--r--support/dktools/dk4mai8dbl.c226
-rw-r--r--support/dktools/dk4mai8dbl.ctr261
-rw-r--r--support/dktools/dk4mai8dbl.h108
-rw-r--r--support/dktools/dk4mai8ddi.c124
-rw-r--r--support/dktools/dk4mai8ddi.ctr129
-rw-r--r--support/dktools/dk4mai8ddi.h102
-rw-r--r--support/dktools/dk4mai8ddu.c196
-rw-r--r--support/dktools/dk4mai8ddu.ctr195
-rw-r--r--support/dktools/dk4mai8ddu.h102
-rw-r--r--support/dktools/dk4mai8dic.c70
-rw-r--r--support/dktools/dk4mai8dic.ctr99
-rw-r--r--support/dktools/dk4mai8dic.h103
-rw-r--r--support/dktools/dk4mai8dii.c69
-rw-r--r--support/dktools/dk4mai8dii.ctr98
-rw-r--r--support/dktools/dk4mai8dii.h102
-rw-r--r--support/dktools/dk4mai8dil.c73
-rw-r--r--support/dktools/dk4mai8dil.ctr102
-rw-r--r--support/dktools/dk4mai8dil.h102
-rw-r--r--support/dktools/dk4mai8dis.c69
-rw-r--r--support/dktools/dk4mai8dis.ctr98
-rw-r--r--support/dktools/dk4mai8dis.h102
-rw-r--r--support/dktools/dk4mai8dli.c79
-rw-r--r--support/dktools/dk4mai8dli.ctr112
-rw-r--r--support/dktools/dk4mai8dli.h106
-rw-r--r--support/dktools/dk4mai8dlu.c79
-rw-r--r--support/dktools/dk4mai8dlu.ctr112
-rw-r--r--support/dktools/dk4mai8dlu.h106
-rw-r--r--support/dktools/dk4mai8dmi.c66
-rw-r--r--support/dktools/dk4mai8dmi.ctr100
-rw-r--r--support/dktools/dk4mai8dmi.h107
-rw-r--r--support/dktools/dk4mai8dmu.c66
-rw-r--r--support/dktools/dk4mai8dmu.ctr100
-rw-r--r--support/dktools/dk4mai8dmu.h107
-rw-r--r--support/dktools/dk4mai8dsz.c245
-rw-r--r--support/dktools/dk4mai8dsz.ctr276
-rw-r--r--support/dktools/dk4mai8dsz.h104
-rw-r--r--support/dktools/dk4mai8duc.c69
-rw-r--r--support/dktools/dk4mai8duc.ctr98
-rw-r--r--support/dktools/dk4mai8duc.h102
-rw-r--r--support/dktools/dk4mai8dui.c69
-rw-r--r--support/dktools/dk4mai8dui.ctr98
-rw-r--r--support/dktools/dk4mai8dui.h102
-rw-r--r--support/dktools/dk4mai8dul.c73
-rw-r--r--support/dktools/dk4mai8dul.ctr102
-rw-r--r--support/dktools/dk4mai8dul.h102
-rw-r--r--support/dktools/dk4mai8dus.c69
-rw-r--r--support/dktools/dk4mai8dus.ctr98
-rw-r--r--support/dktools/dk4mai8dus.h102
-rw-r--r--support/dktools/dk4mai8hdi.c116
-rw-r--r--support/dktools/dk4mai8hdi.ctr127
-rw-r--r--support/dktools/dk4mai8hdi.h104
-rw-r--r--support/dktools/dk4mai8hdu.c189
-rw-r--r--support/dktools/dk4mai8hdu.ctr206
-rw-r--r--support/dktools/dk4mai8hdu.h104
-rw-r--r--support/dktools/dk4mai8hic.c70
-rw-r--r--support/dktools/dk4mai8hic.ctr99
-rw-r--r--support/dktools/dk4mai8hic.h103
-rw-r--r--support/dktools/dk4mai8hii.c69
-rw-r--r--support/dktools/dk4mai8hii.ctr98
-rw-r--r--support/dktools/dk4mai8hii.h102
-rw-r--r--support/dktools/dk4mai8hil.c73
-rw-r--r--support/dktools/dk4mai8hil.ctr102
-rw-r--r--support/dktools/dk4mai8hil.h102
-rw-r--r--support/dktools/dk4mai8his.c69
-rw-r--r--support/dktools/dk4mai8his.ctr98
-rw-r--r--support/dktools/dk4mai8his.h102
-rw-r--r--support/dktools/dk4mai8hli.c79
-rw-r--r--support/dktools/dk4mai8hli.ctr112
-rw-r--r--support/dktools/dk4mai8hli.h106
-rw-r--r--support/dktools/dk4mai8hlu.c79
-rw-r--r--support/dktools/dk4mai8hlu.ctr112
-rw-r--r--support/dktools/dk4mai8hlu.h106
-rw-r--r--support/dktools/dk4mai8hmi.c66
-rw-r--r--support/dktools/dk4mai8hmi.ctr100
-rw-r--r--support/dktools/dk4mai8hmi.h107
-rw-r--r--support/dktools/dk4mai8hmu.c66
-rw-r--r--support/dktools/dk4mai8hmu.ctr100
-rw-r--r--support/dktools/dk4mai8hmu.h107
-rw-r--r--support/dktools/dk4mai8huc.c69
-rw-r--r--support/dktools/dk4mai8huc.ctr98
-rw-r--r--support/dktools/dk4mai8huc.h102
-rw-r--r--support/dktools/dk4mai8hui.c69
-rw-r--r--support/dktools/dk4mai8hui.ctr98
-rw-r--r--support/dktools/dk4mai8hui.h102
-rw-r--r--support/dktools/dk4mai8hul.c73
-rw-r--r--support/dktools/dk4mai8hul.ctr102
-rw-r--r--support/dktools/dk4mai8hul.h102
-rw-r--r--support/dktools/dk4mai8hus.c69
-rw-r--r--support/dktools/dk4mai8hus.ctr98
-rw-r--r--support/dktools/dk4mai8hus.h102
-rw-r--r--support/dktools/dk4maiddbl.c66
-rw-r--r--support/dktools/dk4maiddbl.ctr102
-rw-r--r--support/dktools/dk4maiddbl.h109
-rw-r--r--support/dktools/dk4maidddi.c71
-rw-r--r--support/dktools/dk4maidddi.ctr98
-rw-r--r--support/dktools/dk4maidddi.h100
-rw-r--r--support/dktools/dk4maidddu.c71
-rw-r--r--support/dktools/dk4maidddu.ctr98
-rw-r--r--support/dktools/dk4maidddu.h100
-rw-r--r--support/dktools/dk4maiddic.c71
-rw-r--r--support/dktools/dk4maiddic.ctr98
-rw-r--r--support/dktools/dk4maiddic.h100
-rw-r--r--support/dktools/dk4maiddii.c71
-rw-r--r--support/dktools/dk4maiddii.ctr98
-rw-r--r--support/dktools/dk4maiddii.h100
-rw-r--r--support/dktools/dk4maiddil.c71
-rw-r--r--support/dktools/dk4maiddil.ctr98
-rw-r--r--support/dktools/dk4maiddil.h100
-rw-r--r--support/dktools/dk4maiddis.c71
-rw-r--r--support/dktools/dk4maiddis.ctr98
-rw-r--r--support/dktools/dk4maiddis.h100
-rw-r--r--support/dktools/dk4maiddli.c71
-rw-r--r--support/dktools/dk4maiddli.ctr98
-rw-r--r--support/dktools/dk4maiddli.h100
-rw-r--r--support/dktools/dk4maiddlu.c71
-rw-r--r--support/dktools/dk4maiddlu.ctr98
-rw-r--r--support/dktools/dk4maiddlu.h100
-rw-r--r--support/dktools/dk4maiddmi.c80
-rw-r--r--support/dktools/dk4maiddmi.ctr110
-rw-r--r--support/dktools/dk4maiddmi.h103
-rw-r--r--support/dktools/dk4maiddmu.c83
-rw-r--r--support/dktools/dk4maiddmu.ctr114
-rw-r--r--support/dktools/dk4maiddmu.h104
-rw-r--r--support/dktools/dk4maiddsz.c71
-rw-r--r--support/dktools/dk4maiddsz.ctr98
-rw-r--r--support/dktools/dk4maiddsz.h100
-rw-r--r--support/dktools/dk4maidduc.c71
-rw-r--r--support/dktools/dk4maidduc.ctr98
-rw-r--r--support/dktools/dk4maidduc.h100
-rw-r--r--support/dktools/dk4maiddui.c71
-rw-r--r--support/dktools/dk4maiddui.ctr98
-rw-r--r--support/dktools/dk4maiddui.h100
-rw-r--r--support/dktools/dk4maiddul.c71
-rw-r--r--support/dktools/dk4maiddul.ctr98
-rw-r--r--support/dktools/dk4maiddul.h100
-rw-r--r--support/dktools/dk4maiddus.c71
-rw-r--r--support/dktools/dk4maiddus.ctr98
-rw-r--r--support/dktools/dk4maiddus.h100
-rw-r--r--support/dktools/dk4maidhdi.c71
-rw-r--r--support/dktools/dk4maidhdi.ctr98
-rw-r--r--support/dktools/dk4maidhdi.h100
-rw-r--r--support/dktools/dk4maidhdu.c71
-rw-r--r--support/dktools/dk4maidhdu.ctr98
-rw-r--r--support/dktools/dk4maidhdu.h100
-rw-r--r--support/dktools/dk4maidhic.c71
-rw-r--r--support/dktools/dk4maidhic.ctr98
-rw-r--r--support/dktools/dk4maidhic.h100
-rw-r--r--support/dktools/dk4maidhii.c71
-rw-r--r--support/dktools/dk4maidhii.ctr98
-rw-r--r--support/dktools/dk4maidhii.h100
-rw-r--r--support/dktools/dk4maidhil.c71
-rw-r--r--support/dktools/dk4maidhil.ctr98
-rw-r--r--support/dktools/dk4maidhil.h100
-rw-r--r--support/dktools/dk4maidhis.c71
-rw-r--r--support/dktools/dk4maidhis.ctr98
-rw-r--r--support/dktools/dk4maidhis.h100
-rw-r--r--support/dktools/dk4maidhli.c71
-rw-r--r--support/dktools/dk4maidhli.ctr98
-rw-r--r--support/dktools/dk4maidhli.h100
-rw-r--r--support/dktools/dk4maidhlu.c71
-rw-r--r--support/dktools/dk4maidhlu.ctr98
-rw-r--r--support/dktools/dk4maidhlu.h100
-rw-r--r--support/dktools/dk4maidhmi.c80
-rw-r--r--support/dktools/dk4maidhmi.ctr110
-rw-r--r--support/dktools/dk4maidhmi.h103
-rw-r--r--support/dktools/dk4maidhmu.c79
-rw-r--r--support/dktools/dk4maidhmu.ctr109
-rw-r--r--support/dktools/dk4maidhmu.h103
-rw-r--r--support/dktools/dk4maidhsz.c71
-rw-r--r--support/dktools/dk4maidhsz.ctr98
-rw-r--r--support/dktools/dk4maidhsz.h100
-rw-r--r--support/dktools/dk4maidhuc.c71
-rw-r--r--support/dktools/dk4maidhuc.ctr98
-rw-r--r--support/dktools/dk4maidhuc.h100
-rw-r--r--support/dktools/dk4maidhui.c71
-rw-r--r--support/dktools/dk4maidhui.ctr98
-rw-r--r--support/dktools/dk4maidhui.h100
-rw-r--r--support/dktools/dk4maidhul.c71
-rw-r--r--support/dktools/dk4maidhul.ctr98
-rw-r--r--support/dktools/dk4maidhul.h100
-rw-r--r--support/dktools/dk4maidhus.c71
-rw-r--r--support/dktools/dk4maidhus.ctr98
-rw-r--r--support/dktools/dk4maidhus.h100
-rw-r--r--support/dktools/dk4maiwdbl.c215
-rw-r--r--support/dktools/dk4maiwdbl.ctr251
-rw-r--r--support/dktools/dk4maiwdbl.h109
-rw-r--r--support/dktools/dk4maiwddi.c92
-rw-r--r--support/dktools/dk4maiwddi.ctr120
-rw-r--r--support/dktools/dk4maiwddi.h101
-rw-r--r--support/dktools/dk4maiwddu.c255
-rw-r--r--support/dktools/dk4maiwddu.ctr260
-rw-r--r--support/dktools/dk4maiwddu.h102
-rw-r--r--support/dktools/dk4maiwdic.c70
-rw-r--r--support/dktools/dk4maiwdic.ctr99
-rw-r--r--support/dktools/dk4maiwdic.h103
-rw-r--r--support/dktools/dk4maiwdii.c69
-rw-r--r--support/dktools/dk4maiwdii.ctr98
-rw-r--r--support/dktools/dk4maiwdii.h102
-rw-r--r--support/dktools/dk4maiwdil.c73
-rw-r--r--support/dktools/dk4maiwdil.ctr102
-rw-r--r--support/dktools/dk4maiwdil.h102
-rw-r--r--support/dktools/dk4maiwdis.c69
-rw-r--r--support/dktools/dk4maiwdis.ctr98
-rw-r--r--support/dktools/dk4maiwdis.h102
-rw-r--r--support/dktools/dk4maiwdli.c79
-rw-r--r--support/dktools/dk4maiwdli.ctr112
-rw-r--r--support/dktools/dk4maiwdli.h106
-rw-r--r--support/dktools/dk4maiwdlu.c79
-rw-r--r--support/dktools/dk4maiwdlu.ctr112
-rw-r--r--support/dktools/dk4maiwdlu.h106
-rw-r--r--support/dktools/dk4maiwdmi.c66
-rw-r--r--support/dktools/dk4maiwdmi.ctr100
-rw-r--r--support/dktools/dk4maiwdmi.h107
-rw-r--r--support/dktools/dk4maiwdmu.c66
-rw-r--r--support/dktools/dk4maiwdmu.ctr100
-rw-r--r--support/dktools/dk4maiwdmu.h107
-rw-r--r--support/dktools/dk4maiwdsz.c153
-rw-r--r--support/dktools/dk4maiwdsz.ctr182
-rw-r--r--support/dktools/dk4maiwdsz.h102
-rw-r--r--support/dktools/dk4maiwduc.c71
-rw-r--r--support/dktools/dk4maiwduc.ctr101
-rw-r--r--support/dktools/dk4maiwduc.h103
-rw-r--r--support/dktools/dk4maiwdui.c69
-rw-r--r--support/dktools/dk4maiwdui.ctr98
-rw-r--r--support/dktools/dk4maiwdui.h102
-rw-r--r--support/dktools/dk4maiwdul.c73
-rw-r--r--support/dktools/dk4maiwdul.ctr102
-rw-r--r--support/dktools/dk4maiwdul.h102
-rw-r--r--support/dktools/dk4maiwdus.c69
-rw-r--r--support/dktools/dk4maiwdus.ctr98
-rw-r--r--support/dktools/dk4maiwdus.h102
-rw-r--r--support/dktools/dk4maiwhdi.c115
-rw-r--r--support/dktools/dk4maiwhdi.ctr126
-rw-r--r--support/dktools/dk4maiwhdi.h104
-rw-r--r--support/dktools/dk4maiwhdu.c281
-rw-r--r--support/dktools/dk4maiwhdu.ctr298
-rw-r--r--support/dktools/dk4maiwhdu.h102
-rw-r--r--support/dktools/dk4maiwhic.c70
-rw-r--r--support/dktools/dk4maiwhic.ctr99
-rw-r--r--support/dktools/dk4maiwhic.h103
-rw-r--r--support/dktools/dk4maiwhii.c69
-rw-r--r--support/dktools/dk4maiwhii.ctr98
-rw-r--r--support/dktools/dk4maiwhii.h102
-rw-r--r--support/dktools/dk4maiwhil.c73
-rw-r--r--support/dktools/dk4maiwhil.ctr102
-rw-r--r--support/dktools/dk4maiwhil.h102
-rw-r--r--support/dktools/dk4maiwhis.c69
-rw-r--r--support/dktools/dk4maiwhis.ctr98
-rw-r--r--support/dktools/dk4maiwhis.h102
-rw-r--r--support/dktools/dk4maiwhli.c79
-rw-r--r--support/dktools/dk4maiwhli.ctr112
-rw-r--r--support/dktools/dk4maiwhli.h106
-rw-r--r--support/dktools/dk4maiwhlu.c79
-rw-r--r--support/dktools/dk4maiwhlu.ctr112
-rw-r--r--support/dktools/dk4maiwhlu.h106
-rw-r--r--support/dktools/dk4maiwhmi.c66
-rw-r--r--support/dktools/dk4maiwhmi.ctr100
-rw-r--r--support/dktools/dk4maiwhmi.h107
-rw-r--r--support/dktools/dk4maiwhmu.c66
-rw-r--r--support/dktools/dk4maiwhmu.ctr100
-rw-r--r--support/dktools/dk4maiwhmu.h107
-rw-r--r--support/dktools/dk4maiwhuc.c71
-rw-r--r--support/dktools/dk4maiwhuc.ctr101
-rw-r--r--support/dktools/dk4maiwhuc.h103
-rw-r--r--support/dktools/dk4maiwhui.c69
-rw-r--r--support/dktools/dk4maiwhui.ctr98
-rw-r--r--support/dktools/dk4maiwhui.h102
-rw-r--r--support/dktools/dk4maiwhul.c73
-rw-r--r--support/dktools/dk4maiwhul.ctr102
-rw-r--r--support/dktools/dk4maiwhul.h102
-rw-r--r--support/dktools/dk4maiwhus.c69
-rw-r--r--support/dktools/dk4maiwhus.ctr98
-rw-r--r--support/dktools/dk4maiwhus.h102
-rw-r--r--support/dktools/dk4maixdbl.cpp82
-rw-r--r--support/dktools/dk4maixdbl.cpt147
-rw-r--r--support/dktools/dk4maixdbl.h138
-rw-r--r--support/dktools/dk4maixddi.cpp84
-rw-r--r--support/dktools/dk4maixddi.cpt139
-rw-r--r--support/dktools/dk4maixddi.h128
-rw-r--r--support/dktools/dk4maixddu.cpp83
-rw-r--r--support/dktools/dk4maixddu.cpt138
-rw-r--r--support/dktools/dk4maixddu.h128
-rw-r--r--support/dktools/dk4maixdic.cpp83
-rw-r--r--support/dktools/dk4maixdic.cpt141
-rw-r--r--support/dktools/dk4maixdic.h131
-rw-r--r--support/dktools/dk4maixdii.cpp83
-rw-r--r--support/dktools/dk4maixdii.cpt143
-rw-r--r--support/dktools/dk4maixdii.h133
-rw-r--r--support/dktools/dk4maixdil.cpp83
-rw-r--r--support/dktools/dk4maixdil.cpt144
-rw-r--r--support/dktools/dk4maixdil.h134
-rw-r--r--support/dktools/dk4maixdis.cpp83
-rw-r--r--support/dktools/dk4maixdis.cpt145
-rw-r--r--support/dktools/dk4maixdis.h135
-rw-r--r--support/dktools/dk4maixdli.cpp83
-rw-r--r--support/dktools/dk4maixdli.cpt145
-rw-r--r--support/dktools/dk4maixdli.h135
-rw-r--r--support/dktools/dk4maixdlu.cpp83
-rw-r--r--support/dktools/dk4maixdlu.cpt144
-rw-r--r--support/dktools/dk4maixdlu.h134
-rw-r--r--support/dktools/dk4maixdmi.cpp91
-rw-r--r--support/dktools/dk4maixdmi.cpt156
-rw-r--r--support/dktools/dk4maixdmi.h138
-rw-r--r--support/dktools/dk4maixdmu.cpp96
-rw-r--r--support/dktools/dk4maixdmu.cpt163
-rw-r--r--support/dktools/dk4maixdmu.h140
-rw-r--r--support/dktools/dk4maixdsz.cpp83
-rw-r--r--support/dktools/dk4maixdsz.cpt145
-rw-r--r--support/dktools/dk4maixdsz.h135
-rw-r--r--support/dktools/dk4maixduc.cpp83
-rw-r--r--support/dktools/dk4maixduc.cpt144
-rw-r--r--support/dktools/dk4maixduc.h134
-rw-r--r--support/dktools/dk4maixdui.cpp83
-rw-r--r--support/dktools/dk4maixdui.cpt146
-rw-r--r--support/dktools/dk4maixdui.h136
-rw-r--r--support/dktools/dk4maixdul.cpp83
-rw-r--r--support/dktools/dk4maixdul.cpt145
-rw-r--r--support/dktools/dk4maixdul.h135
-rw-r--r--support/dktools/dk4maixdus.cpp83
-rw-r--r--support/dktools/dk4maixdus.cpt145
-rw-r--r--support/dktools/dk4maixdus.h135
-rw-r--r--support/dktools/dk4mao8d.c190
-rw-r--r--support/dktools/dk4mao8d.ctr214
-rw-r--r--support/dktools/dk4mao8d.h99
-rw-r--r--support/dktools/dk4mao8dbl.c359
-rw-r--r--support/dktools/dk4mao8dbl.ctr352
-rw-r--r--support/dktools/dk4mao8dbl.h99
-rw-r--r--support/dktools/dk4mao8h.c218
-rw-r--r--support/dktools/dk4mao8h.ctr188
-rw-r--r--support/dktools/dk4mao8h.h99
-rw-r--r--support/dktools/dk4maodd.c85
-rw-r--r--support/dktools/dk4maodd.ctr114
-rw-r--r--support/dktools/dk4maodd.h102
-rw-r--r--support/dktools/dk4maoddbl.c63
-rw-r--r--support/dktools/dk4maoddbl.ctr82
-rw-r--r--support/dktools/dk4maoddbl.h94
-rw-r--r--support/dktools/dk4maodh.c81
-rw-r--r--support/dktools/dk4maodh.ctr107
-rw-r--r--support/dktools/dk4maodh.h99
-rw-r--r--support/dktools/dk4maodo.c133
-rw-r--r--support/dktools/dk4maodo.ctr137
-rw-r--r--support/dktools/dk4maodo.h81
-rw-r--r--support/dktools/dk4maowd.c187
-rw-r--r--support/dktools/dk4maowd.ctr211
-rw-r--r--support/dktools/dk4maowd.h99
-rw-r--r--support/dktools/dk4maowdbl.c385
-rw-r--r--support/dktools/dk4maowdbl.ctr400
-rw-r--r--support/dktools/dk4maowdbl.h106
-rw-r--r--support/dktools/dk4maowh.c155
-rw-r--r--support/dktools/dk4maowh.ctr181
-rw-r--r--support/dktools/dk4maowh.h99
-rw-r--r--support/dktools/dk4maoxd.cpp96
-rw-r--r--support/dktools/dk4maoxd.cpt159
-rw-r--r--support/dktools/dk4maoxd.h136
-rw-r--r--support/dktools/dk4maoxdbl.cpp78
-rw-r--r--support/dktools/dk4maoxdbl.cpt132
-rw-r--r--support/dktools/dk4maoxdbl.h129
-rw-r--r--support/dktools/dk4masz.c92
-rw-r--r--support/dktools/dk4masz.ctr106
-rw-r--r--support/dktools/dk4masz.h88
-rw-r--r--support/dktools/dk4mbstrm.c102
-rw-r--r--support/dktools/dk4mbstrm.ctr106
-rw-r--r--support/dktools/dk4mbstrm.h81
-rw-r--r--support/dktools/dk4md.c550
-rw-r--r--support/dktools/dk4md.ctr741
-rw-r--r--support/dktools/dk4md.h285
-rw-r--r--support/dktools/dk4mdch.c159
-rw-r--r--support/dktools/dk4mdch.ctr122
-rw-r--r--support/dktools/dk4mem.c378
-rw-r--r--support/dktools/dk4mem.ctr1030
-rw-r--r--support/dktools/dk4mem.h732
-rw-r--r--support/dktools/dk4mema.c97
-rw-r--r--support/dktools/dk4mema.ctr116
-rw-r--r--support/dktools/dk4mema.h92
-rw-r--r--support/dktools/dk4membf.c81
-rw-r--r--support/dktools/dk4membf.ctr81
-rw-r--r--support/dktools/dk4membf.h73
-rw-r--r--support/dktools/dk4membs.c71
-rw-r--r--support/dktools/dk4membs.ctr67
-rw-r--r--support/dktools/dk4membs.h69
-rw-r--r--support/dktools/dk4membuf.c216
-rw-r--r--support/dktools/dk4membuf.ctr268
-rw-r--r--support/dktools/dk4membuf.h128
-rw-r--r--support/dktools/dk4memcpl.c59
-rw-r--r--support/dktools/dk4memcpl.ctr52
-rw-r--r--support/dktools/dk4memcpl.h67
-rw-r--r--support/dktools/dk4memrs.c111
-rw-r--r--support/dktools/dk4memrs.ctr149
-rw-r--r--support/dktools/dk4memrs.h112
-rw-r--r--support/dktools/dk4mkdh.c65
-rw-r--r--support/dktools/dk4mkdh.ctr84
-rw-r--r--support/dktools/dk4mkdh.h92
-rw-r--r--support/dktools/dk4mkdh8.c887
-rw-r--r--support/dktools/dk4mkdh8.ctr964
-rw-r--r--support/dktools/dk4mkdh8.h188
-rw-r--r--support/dktools/dk4mkdhw.c602
-rw-r--r--support/dktools/dk4mkdhw.ctr645
-rw-r--r--support/dktools/dk4mkdhw.h144
-rw-r--r--support/dktools/dk4mm.c76
-rw-r--r--support/dktools/dk4mm.ctr74
-rw-r--r--support/dktools/dk4mm.h74
-rw-r--r--support/dktools/dk4mpl.h62
-rw-r--r--support/dktools/dk4numco.h451
-rw-r--r--support/dktools/dk4numl.c129
-rw-r--r--support/dktools/dk4numl.ctr135
-rw-r--r--support/dktools/dk4numl.h79
-rw-r--r--support/dktools/dk4opt.c235
-rw-r--r--support/dktools/dk4opt.ctr489
-rw-r--r--support/dktools/dk4opt.h335
-rw-r--r--support/dktools/dk4opt01.c117
-rw-r--r--support/dktools/dk4opt01.ctr84
-rw-r--r--support/dktools/dk4opt02.c121
-rw-r--r--support/dktools/dk4opt02.ctr88
-rw-r--r--support/dktools/dk4opt03.c116
-rw-r--r--support/dktools/dk4opt03.ctr83
-rw-r--r--support/dktools/dk4opt04.c113
-rw-r--r--support/dktools/dk4opt04.ctr80
-rw-r--r--support/dktools/dk4opt05.c107
-rw-r--r--support/dktools/dk4opt05.ctr76
-rw-r--r--support/dktools/dk4opt06.c126
-rw-r--r--support/dktools/dk4opt06.ctr93
-rw-r--r--support/dktools/dk4opt07.c646
-rw-r--r--support/dktools/dk4opt07.ctr588
-rw-r--r--support/dktools/dk4papea.c576
-rw-r--r--support/dktools/dk4papea.ctr506
-rw-r--r--support/dktools/dk4papea.h90
-rw-r--r--support/dktools/dk4paper.c948
-rw-r--r--support/dktools/dk4paper.ctr1053
-rw-r--r--support/dktools/dk4paper.h321
-rw-r--r--support/dktools/dk4path8.c292
-rw-r--r--support/dktools/dk4path8.ctr360
-rw-r--r--support/dktools/dk4path8.h142
-rw-r--r--support/dktools/dk4pathd.c194
-rw-r--r--support/dktools/dk4pathd.ctr272
-rw-r--r--support/dktools/dk4pathd.h167
-rw-r--r--support/dktools/dk4pathw.c307
-rw-r--r--support/dktools/dk4pathw.ctr376
-rw-r--r--support/dktools/dk4pathw.h143
-rw-r--r--support/dktools/dk4pref.c159
-rw-r--r--support/dktools/dk4pref.conf10
-rw-r--r--support/dktools/dk4pref.ctr195
-rw-r--r--support/dktools/dk4pref.h125
-rw-r--r--support/dktools/dk4rec.h113
-rw-r--r--support/dktools/dk4rec01.c81
-rw-r--r--support/dktools/dk4rec01.ctr98
-rw-r--r--support/dktools/dk4rec01.h91
-rw-r--r--support/dktools/dk4rec02.c83
-rw-r--r--support/dktools/dk4rec02.ctr100
-rw-r--r--support/dktools/dk4rec02.h91
-rw-r--r--support/dktools/dk4rec03.c133
-rw-r--r--support/dktools/dk4rec03.ctr167
-rw-r--r--support/dktools/dk4rec03.h108
-rw-r--r--support/dktools/dk4rec04.c156
-rw-r--r--support/dktools/dk4rec04.ctr190
-rw-r--r--support/dktools/dk4rec04.h108
-rw-r--r--support/dktools/dk4rec05.c142
-rw-r--r--support/dktools/dk4rec05.ctr177
-rw-r--r--support/dktools/dk4rec05.h109
-rw-r--r--support/dktools/dk4rec06.c160
-rw-r--r--support/dktools/dk4rec06.ctr196
-rw-r--r--support/dktools/dk4rec06.h110
-rw-r--r--support/dktools/dk4rec07.c89
-rw-r--r--support/dktools/dk4rec07.ctr107
-rw-r--r--support/dktools/dk4rec07.h92
-rw-r--r--support/dktools/dk4rec08.c97
-rw-r--r--support/dktools/dk4rec08.ctr115
-rw-r--r--support/dktools/dk4rec08.h92
-rw-r--r--support/dktools/dk4rec09.c97
-rw-r--r--support/dktools/dk4rec09.ctr115
-rw-r--r--support/dktools/dk4rec09.h92
-rw-r--r--support/dktools/dk4rec10.c99
-rw-r--r--support/dktools/dk4rec10.ctr117
-rw-r--r--support/dktools/dk4rec10.h92
-rw-r--r--support/dktools/dk4rec11.c178
-rw-r--r--support/dktools/dk4rec11.ctr211
-rw-r--r--support/dktools/dk4rec11.h109
-rw-r--r--support/dktools/dk4rec12.c160
-rw-r--r--support/dktools/dk4rec12.ctr194
-rw-r--r--support/dktools/dk4rec12.h108
-rw-r--r--support/dktools/dk4rec13.c73
-rw-r--r--support/dktools/dk4rec13.ctr90
-rw-r--r--support/dktools/dk4rec13.h91
-rw-r--r--support/dktools/dk4rec14.c80
-rw-r--r--support/dktools/dk4rec14.ctr97
-rw-r--r--support/dktools/dk4rec14.h91
-rw-r--r--support/dktools/dk4rec15.c80
-rw-r--r--support/dktools/dk4rec15.ctr98
-rw-r--r--support/dktools/dk4rec15.h92
-rw-r--r--support/dktools/dk4rec16.c81
-rw-r--r--support/dktools/dk4rec16.ctr98
-rw-r--r--support/dktools/dk4rec16.h91
-rw-r--r--support/dktools/dk4rec17.c151
-rw-r--r--support/dktools/dk4rec17.ctr184
-rw-r--r--support/dktools/dk4rec17.h109
-rw-r--r--support/dktools/dk4rec18.c138
-rw-r--r--support/dktools/dk4rec18.ctr169
-rw-r--r--support/dktools/dk4rec18.h107
-rw-r--r--support/dktools/dk4rec19.c91
-rw-r--r--support/dktools/dk4rec19.ctr109
-rw-r--r--support/dktools/dk4rec19.h92
-rw-r--r--support/dktools/dk4rec20.c90
-rw-r--r--support/dktools/dk4rec20.ctr107
-rw-r--r--support/dktools/dk4rec20.h91
-rw-r--r--support/dktools/dk4rec21.c84
-rw-r--r--support/dktools/dk4rec21.ctr110
-rw-r--r--support/dktools/dk4rec21.h99
-rw-r--r--support/dktools/dk4rec22.c79
-rw-r--r--support/dktools/dk4rec22.ctr96
-rw-r--r--support/dktools/dk4rec22.h92
-rw-r--r--support/dktools/dk4rec23.c82
-rw-r--r--support/dktools/dk4rec23.ctr99
-rw-r--r--support/dktools/dk4rec23.h92
-rw-r--r--support/dktools/dk4rec24.c75
-rw-r--r--support/dktools/dk4rec24.ctr97
-rw-r--r--support/dktools/dk4rec24.h95
-rw-r--r--support/dktools/dk4rec25.c169
-rw-r--r--support/dktools/dk4rec25.ctr175
-rw-r--r--support/dktools/dk4rec25.h80
-rw-r--r--support/dktools/dk4recwx.cpp471
-rw-r--r--support/dktools/dk4recwx.cpt539
-rw-r--r--support/dktools/dk4recwx.h191
-rw-r--r--support/dktools/dk4rld.c212
-rw-r--r--support/dktools/dk4rld.ctr274
-rw-r--r--support/dktools/dk4rld.h154
-rw-r--r--support/dktools/dk4rle.c835
-rw-r--r--support/dktools/dk4rle.ctr835
-rw-r--r--support/dktools/dk4rle.h159
-rw-r--r--support/dktools/dk4serf.c301
-rw-r--r--support/dktools/dk4serf.ctr405
-rw-r--r--support/dktools/dk4serf.h180
-rw-r--r--support/dktools/dk4sock.h2765
-rw-r--r--support/dktools/dk4sock01.c177
-rw-r--r--support/dktools/dk4sock01.ctr140
-rw-r--r--support/dktools/dk4sock02.c453
-rw-r--r--support/dktools/dk4sock02.ctr423
-rw-r--r--support/dktools/dk4sock03.c436
-rw-r--r--support/dktools/dk4sock03.ctr386
-rw-r--r--support/dktools/dk4sock04.c376
-rw-r--r--support/dktools/dk4sock04.ctr368
-rw-r--r--support/dktools/dk4sock05.c95
-rw-r--r--support/dktools/dk4sock05.ctr64
-rw-r--r--support/dktools/dk4sock06.c629
-rw-r--r--support/dktools/dk4sock06.ctr588
-rw-r--r--support/dktools/dk4sock07.c94
-rw-r--r--support/dktools/dk4sock07.ctr61
-rw-r--r--support/dktools/dk4sock08.c60
-rw-r--r--support/dktools/dk4sock08.ctr29
-rw-r--r--support/dktools/dk4sock09.c113
-rw-r--r--support/dktools/dk4sock09.ctr64
-rw-r--r--support/dktools/dk4sock10.c175
-rw-r--r--support/dktools/dk4sock10.ctr133
-rw-r--r--support/dktools/dk4sock11.c102
-rw-r--r--support/dktools/dk4sock11.ctr68
-rw-r--r--support/dktools/dk4sock12.c196
-rw-r--r--support/dktools/dk4sock12.ctr146
-rw-r--r--support/dktools/dk4sock13.c361
-rw-r--r--support/dktools/dk4sock13.ctr305
-rw-r--r--support/dktools/dk4sock14.c179
-rw-r--r--support/dktools/dk4sock14.ctr124
-rw-r--r--support/dktools/dk4sock15.c138
-rw-r--r--support/dktools/dk4sock15.ctr105
-rw-r--r--support/dktools/dk4sock16.c380
-rw-r--r--support/dktools/dk4sock16.ctr274
-rw-r--r--support/dktools/dk4sock17.c505
-rw-r--r--support/dktools/dk4sock17.ctr414
-rw-r--r--support/dktools/dk4sock18.c487
-rw-r--r--support/dktools/dk4sock18.ctr404
-rw-r--r--support/dktools/dk4sock19.c104
-rw-r--r--support/dktools/dk4sock19.ctr94
-rw-r--r--support/dktools/dk4sock20.c287
-rw-r--r--support/dktools/dk4sock20.ctr254
-rw-r--r--support/dktools/dk4sock21.c326
-rw-r--r--support/dktools/dk4sock21.ctr293
-rw-r--r--support/dktools/dk4sock22.c139
-rw-r--r--support/dktools/dk4sock22.ctr106
-rw-r--r--support/dktools/dk4sock23.c223
-rw-r--r--support/dktools/dk4sock23.ctr172
-rw-r--r--support/dktools/dk4sock24.c296
-rw-r--r--support/dktools/dk4sock24.ctr232
-rw-r--r--support/dktools/dk4sock25.c341
-rw-r--r--support/dktools/dk4sock25.ctr298
-rw-r--r--support/dktools/dk4sock26.c289
-rw-r--r--support/dktools/dk4sock26.ctr228
-rw-r--r--support/dktools/dk4sock27.c215
-rw-r--r--support/dktools/dk4sock27.ctr183
-rw-r--r--support/dktools/dk4sock28.c268
-rw-r--r--support/dktools/dk4sock28.ctr205
-rw-r--r--support/dktools/dk4sock29.c242
-rw-r--r--support/dktools/dk4sock29.ctr179
-rw-r--r--support/dktools/dk4sock30.c306
-rw-r--r--support/dktools/dk4sock30.ctr238
-rw-r--r--support/dktools/dk4sock31.c347
-rw-r--r--support/dktools/dk4sock31.ctr298
-rw-r--r--support/dktools/dk4sock32.c158
-rw-r--r--support/dktools/dk4sock32.ctr117
-rw-r--r--support/dktools/dk4sock33.c366
-rw-r--r--support/dktools/dk4sock33.ctr241
-rw-r--r--support/dktools/dk4sock34.c441
-rw-r--r--support/dktools/dk4sock34.ctr326
-rw-r--r--support/dktools/dk4sock35.c114
-rw-r--r--support/dktools/dk4sock35.ctr61
-rw-r--r--support/dktools/dk4sock36.c103
-rw-r--r--support/dktools/dk4sock36.ctr56
-rw-r--r--support/dktools/dk4sock37.c126
-rw-r--r--support/dktools/dk4sock37.ctr79
-rw-r--r--support/dktools/dk4socka.h415
-rw-r--r--support/dktools/dk4socka01.c1758
-rw-r--r--support/dktools/dk4socka01.ctr1799
-rw-r--r--support/dktools/dk4socka02.c84
-rw-r--r--support/dktools/dk4socka02.ctr52
-rw-r--r--support/dktools/dk4socka03.c91
-rw-r--r--support/dktools/dk4socka03.ctr60
-rw-r--r--support/dktools/dk4socka04.c83
-rw-r--r--support/dktools/dk4socka04.ctr50
-rw-r--r--support/dktools/dk4socka05.c84
-rw-r--r--support/dktools/dk4socka05.ctr53
-rw-r--r--support/dktools/dk4socka06.c83
-rw-r--r--support/dktools/dk4socka06.ctr50
-rw-r--r--support/dktools/dk4socka07.c1748
-rw-r--r--support/dktools/dk4socka07.ctr1599
-rw-r--r--support/dktools/dk4socka08.c146
-rw-r--r--support/dktools/dk4socka08.ctr112
-rw-r--r--support/dktools/dk4socka09.c152
-rw-r--r--support/dktools/dk4socka09.ctr119
-rw-r--r--support/dktools/dk4stat.c138
-rw-r--r--support/dktools/dk4stat.ctr173
-rw-r--r--support/dktools/dk4stat.h112
-rw-r--r--support/dktools/dk4stat8.c140
-rw-r--r--support/dktools/dk4stat8.ctr174
-rw-r--r--support/dktools/dk4stat8.h109
-rw-r--r--support/dktools/dk4statd.c69
-rw-r--r--support/dktools/dk4statd.ctr98
-rw-r--r--support/dktools/dk4statd.h102
-rw-r--r--support/dktools/dk4statt.h288
-rw-r--r--support/dktools/dk4statw.c114
-rw-r--r--support/dktools/dk4statw.ctr148
-rw-r--r--support/dktools/dk4statw.h109
-rw-r--r--support/dktools/dk4sto.c2235
-rw-r--r--support/dktools/dk4sto.ctr2340
-rw-r--r--support/dktools/dk4sto.h483
-rw-r--r--support/dktools/dk4str.c222
-rw-r--r--support/dktools/dk4str8.c981
-rw-r--r--support/dktools/dk4str8.ctr1305
-rw-r--r--support/dktools/dk4str8.h434
-rw-r--r--support/dktools/dk4strd.c390
-rw-r--r--support/dktools/dk4strd.ctr682
-rw-r--r--support/dktools/dk4strd.h365
-rw-r--r--support/dktools/dk4strda.c100
-rw-r--r--support/dktools/dk4strda.ctr108
-rw-r--r--support/dktools/dk4strda.h83
-rw-r--r--support/dktools/dk4strm.c777
-rw-r--r--support/dktools/dk4strm.ctr978
-rw-r--r--support/dktools/dk4strm.h390
-rw-r--r--support/dktools/dk4strmb.c150
-rw-r--r--support/dktools/dk4strmb.ctr203
-rw-r--r--support/dktools/dk4strmb.h126
-rw-r--r--support/dktools/dk4strmco.c1033
-rw-r--r--support/dktools/dk4strmco.ctr976
-rw-r--r--support/dktools/dk4strmco.h149
-rw-r--r--support/dktools/dk4strmf.c147
-rw-r--r--support/dktools/dk4strmf.ctr211
-rw-r--r--support/dktools/dk4strmf.h137
-rw-r--r--support/dktools/dk4strmg.c151
-rw-r--r--support/dktools/dk4strmg.ctr203
-rw-r--r--support/dktools/dk4strmg.h125
-rw-r--r--support/dktools/dk4strmh.c201
-rw-r--r--support/dktools/dk4strmh.ctr272
-rw-r--r--support/dktools/dk4strmh.h144
-rw-r--r--support/dktools/dk4strmo08.c134
-rw-r--r--support/dktools/dk4strmo08.ctr144
-rw-r--r--support/dktools/dk4strmo08.h83
-rw-r--r--support/dktools/dk4strmo16.c121
-rw-r--r--support/dktools/dk4strmo16.ctr133
-rw-r--r--support/dktools/dk4strmo16.h85
-rw-r--r--support/dktools/dk4strmo32.c297
-rw-r--r--support/dktools/dk4strmo32.ctr295
-rw-r--r--support/dktools/dk4strmo32.h128
-rw-r--r--support/dktools/dk4strmodk.c62
-rw-r--r--support/dktools/dk4strmodk.ctr74
-rw-r--r--support/dktools/dk4strmodk.h85
-rw-r--r--support/dktools/dk4strmr.c309
-rw-r--r--support/dktools/dk4strmr.ctr295
-rw-r--r--support/dktools/dk4strmr.h102
-rw-r--r--support/dktools/dk4strms.c218
-rw-r--r--support/dktools/dk4strms.ctr403
-rw-r--r--support/dktools/dk4strms.h260
-rw-r--r--support/dktools/dk4strmu.c361
-rw-r--r--support/dktools/dk4strmu.ctr542
-rw-r--r--support/dktools/dk4strmu.h256
-rw-r--r--support/dktools/dk4strmw.c391
-rw-r--r--support/dktools/dk4strmw.ctr342
-rw-r--r--support/dktools/dk4strmw.h105
-rw-r--r--support/dktools/dk4strw.c1151
-rw-r--r--support/dktools/dk4strw.ctr1480
-rw-r--r--support/dktools/dk4strw.h445
-rw-r--r--support/dktools/dk4strx.cpp331
-rw-r--r--support/dktools/dk4strx.cpt601
-rw-r--r--support/dktools/dk4strx.h347
-rw-r--r--support/dktools/dk4stt.c397
-rw-r--r--support/dktools/dk4stt.ctr391
-rw-r--r--support/dktools/dk4stt.h132
-rw-r--r--support/dktools/dk4svbuf.c110
-rw-r--r--support/dktools/dk4svbuf.ctr127
-rw-r--r--support/dktools/dk4svbuf.h94
-rw-r--r--support/dktools/dk4svbufa.c90
-rw-r--r--support/dktools/dk4svbufa.ctr107
-rw-r--r--support/dktools/dk4svbufa.h94
-rw-r--r--support/dktools/dk4symlink.c365
-rw-r--r--support/dktools/dk4symlink.ctr357
-rw-r--r--support/dktools/dk4symlink.h93
-rw-r--r--support/dktools/dk4time.c66
-rw-r--r--support/dktools/dk4time.ctr106
-rw-r--r--support/dktools/dk4time.h113
-rw-r--r--support/dktools/dk4time08.c295
-rw-r--r--support/dktools/dk4time08.ctr370
-rw-r--r--support/dktools/dk4time08.h165
-rw-r--r--support/dktools/dk4timec.h33
-rw-r--r--support/dktools/dk4timedk.c104
-rw-r--r--support/dktools/dk4timedk.ctr195
-rw-r--r--support/dktools/dk4timedk.h164
-rw-r--r--support/dktools/dk4timewc.c164
-rw-r--r--support/dktools/dk4timewc.ctr255
-rw-r--r--support/dktools/dk4timewc.h164
-rw-r--r--support/dktools/dk4tsp.h43
-rw-r--r--support/dktools/dk4tsp08.c936
-rw-r--r--support/dktools/dk4tsp08.ctr991
-rw-r--r--support/dktools/dk4tsp08.h286
-rw-r--r--support/dktools/dk4tsp16.c750
-rw-r--r--support/dktools/dk4tsp16.ctr897
-rw-r--r--support/dktools/dk4tsp16.h247
-rw-r--r--support/dktools/dk4tsp32.c646
-rw-r--r--support/dktools/dk4tsp32.ctr790
-rw-r--r--support/dktools/dk4tsp32.h247
-rw-r--r--support/dktools/dk4tspdk.c175
-rw-r--r--support/dktools/dk4tspdk.ctr339
-rw-r--r--support/dktools/dk4tspdk.h237
-rw-r--r--support/dktools/dk4tspwx.cpp197
-rw-r--r--support/dktools/dk4tspwx.cpt383
-rw-r--r--support/dktools/dk4tspwx.h266
-rw-r--r--support/dktools/dk4types.h428
-rw-r--r--support/dktools/dk4uc2l.c2358
-rw-r--r--support/dktools/dk4uc2l.ctr2357
-rw-r--r--support/dktools/dk4uc2l.h270
-rw-r--r--support/dktools/dk4ufi.c75
-rw-r--r--support/dktools/dk4ufi.ctr92
-rw-r--r--support/dktools/dk4ufi.h90
-rw-r--r--support/dktools/dk4ufi08.c221
-rw-r--r--support/dktools/dk4ufi08.ctr272
-rw-r--r--support/dktools/dk4ufi08.h126
-rw-r--r--support/dktools/dk4ufic.c102
-rw-r--r--support/dktools/dk4ufic.ctr97
-rw-r--r--support/dktools/dk4ufic.h69
-rw-r--r--support/dktools/dk4ufit.h36
-rw-r--r--support/dktools/dk4ufiwc.c198
-rw-r--r--support/dktools/dk4ufiwc.ctr250
-rw-r--r--support/dktools/dk4ufiwc.h126
-rw-r--r--support/dktools/dk4user.c538
-rw-r--r--support/dktools/dk4user.ctr470
-rw-r--r--support/dktools/dk4user.h119
-rw-r--r--support/dktools/dk4userf.c388
-rw-r--r--support/dktools/dk4userf.ctr480
-rw-r--r--support/dktools/dk4userf.h179
-rw-r--r--support/dktools/dk4utf16.c361
-rw-r--r--support/dktools/dk4utf16.ctr459
-rw-r--r--support/dktools/dk4utf16.h203
-rw-r--r--support/dktools/dk4utf8.c355
-rw-r--r--support/dktools/dk4utf8.ctr429
-rw-r--r--support/dktools/dk4utf8.h153
-rw-r--r--support/dktools/dk4vers.h15
-rw-r--r--support/dktools/dk4verswx.h27
-rw-r--r--support/dktools/dk4wreg.c129
-rw-r--r--support/dktools/dk4wreg8.c459
-rw-r--r--support/dktools/dk4wreg8.ctr573
-rw-r--r--support/dktools/dk4wreg8.h225
-rw-r--r--support/dktools/dk4wregc.c92
-rw-r--r--support/dktools/dk4wregc.ctr98
-rw-r--r--support/dktools/dk4wregc.h81
-rw-r--r--support/dktools/dk4wregd.c165
-rw-r--r--support/dktools/dk4wregd.ctr316
-rw-r--r--support/dktools/dk4wregd.h226
-rw-r--r--support/dktools/dk4wregk.h34
-rw-r--r--support/dktools/dk4wregt.h34
-rw-r--r--support/dktools/dk4wregw.c457
-rw-r--r--support/dktools/dk4wregw.ctr576
-rw-r--r--support/dktools/dk4wregw.h224
-rw-r--r--support/dktools/dk4wxcs.cross37
-rw-r--r--support/dktools/dk4wxcs.h12
-rw-r--r--support/dktools/dk4wxpref.cpp645
-rw-r--r--support/dktools/dk4wxpref.cpt758
-rw-r--r--support/dktools/dk4wxpref.h192
-rw-r--r--support/dktools/dk4wxstt.cpp426
-rw-r--r--support/dktools/dk4wxstt.cpt459
-rw-r--r--support/dktools/dk4wxstt.h178
-rw-r--r--support/dktools/dk4wxtypes.h47
-rw-r--r--support/dktools/dkclock.icobin0 -> 20454 bytes
-rw-r--r--support/dktools/dkclock.xpm40
-rw-r--r--support/dktools/dkconfig.cpp1935
-rw-r--r--support/dktools/dkct-au.c1831
-rw-r--r--support/dktools/dkct-au.ctr1688
-rw-r--r--support/dktools/dkct-gui.c10505
-rw-r--r--support/dktools/dkct-gui.ctr10374
-rw-r--r--support/dktools/dkct-gui.h631
-rw-r--r--support/dktools/dkct-str.c508
-rw-r--r--support/dktools/dkct-str.ctr552
-rw-r--r--support/dktools/dkct-str.h81
-rw-r--r--support/dktools/dkct-to.c181
-rw-r--r--support/dktools/dkct-to.ctr217
-rw-r--r--support/dktools/dkct-to.h114
-rw-r--r--support/dktools/dkct-tr.c3842
-rw-r--r--support/dktools/dkct-tr.ctr3589
-rw-r--r--support/dktools/dkct-tr.h368
-rw-r--r--support/dktools/dkct.c921
-rw-r--r--support/dktools/dkct.ctr837
-rw-r--r--support/dktools/dkct.h64
-rw-r--r--support/dktools/dkct.rc37
-rw-r--r--support/dktools/dkctinst.icobin0 -> 21542 bytes
-rw-r--r--support/dktools/dkctunin.icobin0 -> 21542 bytes
-rw-r--r--support/dktools/dkdbt.c2475
-rw-r--r--support/dktools/dkdbt.ctr2023
-rw-r--r--support/dktools/dkdbt.rc37
-rw-r--r--support/dktools/dkdbt2.c903
-rw-r--r--support/dktools/dkdbt2.ctr804
-rw-r--r--support/dktools/dkicon.icobin0 -> 21542 bytes
-rw-r--r--support/dktools/dkicon.xpm40
-rw-r--r--support/dktools/dkt-version.h25
-rw-r--r--support/dktools/dkt.h608
-rw-r--r--support/dktools/dktools-el.spec254
-rw-r--r--support/dktools/dktools-el6.spec673
-rw-r--r--support/dktools/dktools-el6.spec.in673
-rw-r--r--support/dktools/dktools-el7.spec701
-rw-r--r--support/dktools/dktools-fedora.spec673
-rw-r--r--support/dktools/dktools.pc.in12
-rw-r--r--support/dktools/dktools/charmap/currency-europe.t2l1
-rw-r--r--support/dktools/dktools/charmap/dingbats.t2l162
-rw-r--r--support/dktools/dktools/charmap/iso-latin-1.t2l187
-rw-r--r--support/dktools/dktools/charmap/latin-extended-a.t2l125
-rw-r--r--support/dktools/dktools/charmap/textsym.t2l9
-rw-r--r--support/dktools/dktools/de/bmpp.txt243
-rw-r--r--support/dktools/dktools/de/dk-blks.str37
-rw-r--r--support/dktools/dktools/de/dk-blks.txt44
-rw-r--r--support/dktools/dktools/de/dk-bmm.str56
-rw-r--r--support/dktools/dktools/de/dk-bmm.txt63
-rw-r--r--support/dktools/dktools/de/dk-cat.str68
-rw-r--r--support/dktools/dktools/de/dk-cat.txt91
-rw-r--r--support/dktools/dktools/de/dk-db2t.str28
-rw-r--r--support/dktools/dktools/de/dk-db2t.txt107
-rw-r--r--support/dktools/dktools/de/dk-dbco.str32
-rw-r--r--support/dktools/dktools/de/dk-dbco.txt89
-rw-r--r--support/dktools/dktools/de/dk-fic.str116
-rw-r--r--support/dktools/dktools/de/dk-fic.txt95
-rw-r--r--support/dktools/dktools/de/dk-hex.str24
-rw-r--r--support/dktools/dktools/de/dk-hex.txt50
-rw-r--r--support/dktools/dktools/de/dk-ls.str93
-rw-r--r--support/dktools/dktools/de/dk-ls.txt288
-rw-r--r--support/dktools/dktools/de/dk-pwd.str2
-rw-r--r--support/dktools/dktools/de/dk-pwd.txt40
-rw-r--r--support/dktools/dktools/de/dk-pwgen.str110
-rw-r--r--support/dktools/dktools/de/dk-pwgen.txt127
-rw-r--r--support/dktools/dktools/de/dk-recv.str35
-rw-r--r--support/dktools/dktools/de/dk-recv.txt67
-rw-r--r--support/dktools/dktools/de/dk-send.str71
-rw-r--r--support/dktools/dktools/de/dk-send.txt79
-rw-r--r--support/dktools/dktools/de/dk-sort.str36
-rw-r--r--support/dktools/dktools/de/dk-sort.txt112
-rw-r--r--support/dktools/dktools/de/dk-sqlsplit.txt45
-rw-r--r--support/dktools/dktools/de/dk-t2db.str76
-rw-r--r--support/dktools/dktools/de/dk-t2db.txt124
-rw-r--r--support/dktools/dktools/de/dk-t2h.str66
-rw-r--r--support/dktools/dktools/de/dk-t2h.txt63
-rw-r--r--support/dktools/dktools/de/dk-t2l.str71
-rw-r--r--support/dktools/dktools/de/dk-t2l.txt117
-rw-r--r--support/dktools/dktools/de/dk-uid.str49
-rw-r--r--support/dktools/dktools/de/dk-uid.txt38
-rw-r--r--support/dktools/dktools/de/dk3app.str1362
-rw-r--r--support/dktools/dktools/de/dk3bifa.str42
-rw-r--r--support/dktools/dktools/de/dk3bmeps.str254
-rw-r--r--support/dktools/dktools/de/dk3fig.str45
-rw-r--r--support/dktools/dktools/de/dk3print.str223
-rw-r--r--support/dktools/dktools/de/dk3wreg.str82
-rw-r--r--support/dktools/dktools/de/dk4dbia.str40
-rw-r--r--support/dktools/dktools/de/dk4info.str15
-rw-r--r--support/dktools/dktools/de/dk4info.txt40
-rw-r--r--support/dktools/dktools/de/dk4uc2l.str67
-rw-r--r--support/dktools/dktools/de/dkct.txt94
-rw-r--r--support/dktools/dktools/de/dkct3.str389
-rw-r--r--support/dktools/dktools/de/dkdbtool.str95
-rw-r--r--support/dktools/dktools/de/dkdbtool.txt111
-rw-r--r--support/dktools/dktools/de/dknet4.str217
-rw-r--r--support/dktools/dktools/de/dknet4.txt70
-rw-r--r--support/dktools/dktools/de/dkwt-boot.txt55
-rw-r--r--support/dktools/dktools/de/dkwt-clp.txt44
-rw-r--r--support/dktools/dktools/de/dkwt-env.txt117
-rw-r--r--support/dktools/dktools/de/dkwt-groups.txt41
-rw-r--r--support/dktools/dktools/de/dkwt-help.txt202
-rw-r--r--support/dktools/dktools/de/dkwt-keep.txt42
-rw-r--r--support/dktools/dktools/de/dkwt-login.txt55
-rw-r--r--support/dktools/dktools/de/dkwt-logout.txt55
-rw-r--r--support/dktools/dktools/de/dkwt-print.txt37
-rw-r--r--support/dktools/dktools/de/dkwt-printers.txt37
-rw-r--r--support/dktools/dktools/de/dkwt-shutdown.txt55
-rw-r--r--support/dktools/dktools/de/dkwt-unkeep.txt38
-rw-r--r--support/dktools/dktools/de/dkwt-users.txt41
-rw-r--r--support/dktools/dktools/de/dkwt.str501
-rw-r--r--support/dktools/dktools/de/dkwx.str45
-rw-r--r--support/dktools/dktools/de/dkwxpath.str88
-rw-r--r--support/dktools/dktools/de/dkwxwiz.str66
-rw-r--r--support/dktools/dktools/de/dkwxwiz.txt89
-rw-r--r--support/dktools/dktools/de/fig2lat.str147
-rw-r--r--support/dktools/dktools/de/fig2lat.txt265
-rw-r--r--support/dktools/dktools/de/htmlbook.str313
-rw-r--r--support/dktools/dktools/de/htmlbook.txt327
-rw-r--r--support/dktools/dktools/de/itadmin.str961
-rw-r--r--support/dktools/dktools/de/lprngcl.str53
-rw-r--r--support/dktools/dktools/de/lprngcl.txt70
-rw-r--r--support/dktools/dktools/de/pjsnmp.str355
-rw-r--r--support/dktools/dktools/de/plpdftex.str156
-rw-r--r--support/dktools/dktools/de/printqd.str60
-rw-r--r--support/dktools/dktools/de/printqda.str65
-rw-r--r--support/dktools/dktools/de/printqdc.str132
-rw-r--r--support/dktools/dktools/de/printqdi.str56
-rw-r--r--support/dktools/dktools/de/winprint.str184
-rw-r--r--support/dktools/dktools/de/wprclean.str21
-rw-r--r--support/dktools/dktools/de/wprclean.txt66
-rw-r--r--support/dktools/dktools/de/wxbmpp.str482
-rw-r--r--support/dktools/dktools/de/wxdkclock.str116
-rw-r--r--support/dktools/dktools/de/wxdkct.str333
-rw-r--r--support/dktools/dktools/de/wxdkfcs.str79
-rw-r--r--support/dktools/dktools/de/wxdkhtb.str76
-rw-r--r--support/dktools/dktools/de/wxdkscrsz.str120
-rw-r--r--support/dktools/dktools/de/wximgsz.str225
-rw-r--r--support/dktools/dktools/de/wxpqdc.str189
-rw-r--r--support/dktools/dktools/de/x.txt46
-rw-r--r--support/dktools/dktools/dkwxwiza.txt419
-rw-r--r--support/dktools/dktools/dkwxwizc.txt45
-rw-r--r--support/dktools/dktools/dkwxwizf.txt371
-rw-r--r--support/dktools/dktools/dkwxwizh.txt131
-rw-r--r--support/dktools/dktools/dkwxwizm.txt85
-rw-r--r--support/dktools/dktools/dkwxwizr.txt37
-rw-r--r--support/dktools/dktools/dkwxwizv.txt404
-rw-r--r--support/dktools/dktools/dkwxwizx.txt43
-rw-r--r--support/dktools/dktools/en/ChooseDirectory.pngbin0 -> 259 bytes
-rw-r--r--support/dktools/dktools/en/Exit.pngbin0 -> 303 bytes
-rw-r--r--support/dktools/dktools/en/Options.pngbin0 -> 336 bytes
-rw-r--r--support/dktools/dktools/en/Run.pngbin0 -> 318 bytes
-rw-r--r--support/dktools/dktools/en/dk-blks.txt42
-rw-r--r--support/dktools/dktools/en/dk-bmm.txt63
-rw-r--r--support/dktools/dktools/en/dk-cat.txt85
-rw-r--r--support/dktools/dktools/en/dk-db2t.txt102
-rw-r--r--support/dktools/dktools/en/dk-dbco.txt82
-rw-r--r--support/dktools/dktools/en/dk-fic.txt96
-rw-r--r--support/dktools/dktools/en/dk-hex.txt51
-rw-r--r--support/dktools/dktools/en/dk-ls.txt271
-rw-r--r--support/dktools/dktools/en/dk-pwd.txt39
-rw-r--r--support/dktools/dktools/en/dk-pwgen.txt139
-rw-r--r--support/dktools/dktools/en/dk-recv.txt66
-rw-r--r--support/dktools/dktools/en/dk-send.txt77
-rw-r--r--support/dktools/dktools/en/dk-sort.txt106
-rw-r--r--support/dktools/dktools/en/dk-sqlsplit.txt42
-rw-r--r--support/dktools/dktools/en/dk-t2db.txt116
-rw-r--r--support/dktools/dktools/en/dk-t2h.txt61
-rw-r--r--support/dktools/dktools/en/dk-t2l.txt114
-rw-r--r--support/dktools/dktools/en/dk-uid.txt38
-rw-r--r--support/dktools/dktools/en/dk4info.txt40
-rw-r--r--support/dktools/dktools/en/lprngcl.txt69
-rw-r--r--support/dktools/dktools/en/x.txt47
-rw-r--r--support/dktools/dktools/htmlbook/GNUmakefile145
-rw-r--r--support/dktools/dktools/htmlbook/chm.hbt1
-rw-r--r--support/dktools/dktools/htmlbook/home.fig22
-rw-r--r--support/dktools/dktools/htmlbook/home.pngbin0 -> 1145 bytes
-rw-r--r--support/dktools/dktools/htmlbook/index.fig24
-rw-r--r--support/dktools/dktools/htmlbook/index.pngbin0 -> 1474 bytes
-rw-r--r--support/dktools/dktools/htmlbook/index.prj186
-rw-r--r--support/dktools/dktools/htmlbook/math-img.tex34
-rw-r--r--support/dktools/dktools/htmlbook/next.fig22
-rw-r--r--support/dktools/dktools/htmlbook/next.pngbin0 -> 1155 bytes
-rw-r--r--support/dktools/dktools/htmlbook/prev.fig22
-rw-r--r--support/dktools/dktools/htmlbook/prev.pngbin0 -> 1150 bytes
-rw-r--r--support/dktools/dktools/htmlbook/style.css1295
-rw-r--r--support/dktools/dktools/htmlbook/toc.fig36
-rw-r--r--support/dktools/dktools/htmlbook/toc.pngbin0 -> 1091 bytes
-rw-r--r--support/dktools/dktools/htmlbook/web.hbt24
-rw-r--r--support/dktools/dktools/itadmin/it-de.sql314
-rw-r--r--support/dktools/dktools/itadmin/it-latin1.sql312
-rw-r--r--support/dktools/dktools/itadmin/it-utf8.sql312
-rw-r--r--support/dktools/dktools/print-snmp.conf174
-rw-r--r--support/dktools/dkwt-ac.c411
-rw-r--r--support/dktools/dkwt-ac.ctr378
-rw-r--r--support/dktools/dkwt-cp.c793
-rw-r--r--support/dktools/dkwt-cp.ctr716
-rw-r--r--support/dktools/dkwt-env.c633
-rw-r--r--support/dktools/dkwt-env.ctr596
-rw-r--r--support/dktools/dkwt-ev.c2143
-rw-r--r--support/dktools/dkwt-ev.ctr1876
-rw-r--r--support/dktools/dkwt-gr.c226
-rw-r--r--support/dktools/dkwt-gr.ctr193
-rw-r--r--support/dktools/dkwt-pr.c665
-rw-r--r--support/dktools/dkwt-pr.ctr562
-rw-r--r--support/dktools/dkwt-to.c1450
-rw-r--r--support/dktools/dkwt-to.ctr1317
-rw-r--r--support/dktools/dkwt.c1828
-rw-r--r--support/dktools/dkwt.ctr1827
-rw-r--r--support/dktools/dkwt.h463
-rw-r--r--support/dktools/dkwt.rc37
-rw-r--r--support/dktools/dkwtadm.rc37
-rw-r--r--support/dktools/dkwxpath.h46
-rw-r--r--support/dktools/dkwxpath.rc37
-rw-r--r--support/dktools/dkwxpqdc.h153
-rw-r--r--support/dktools/dkwxtrace.h96
-rw-r--r--support/dktools/dkwxwiz.c1393
-rw-r--r--support/dktools/dkwxwiz.ctr1300
-rw-r--r--support/dktools/dkwxwiz.rc37
-rw-r--r--support/dktools/etc-dk3app/dk3paper.conf25
-rw-r--r--support/dktools/ex-sto.c616
-rw-r--r--support/dktools/ex-sto.ctr585
-rw-r--r--support/dktools/ex-sto.in12
-rw-r--r--support/dktools/exit-program.xpm39
-rw-r--r--support/dktools/f2leps.c1831
-rw-r--r--support/dktools/f2leps.ctr2432
-rw-r--r--support/dktools/f2leps.h721
-rw-r--r--support/dktools/f2ll2l.c353
-rw-r--r--support/dktools/f2ll2l.ctr345
-rw-r--r--support/dktools/f2ll2l.h71
-rw-r--r--support/dktools/f2lopt.c1365
-rw-r--r--support/dktools/f2lopt.ctr1271
-rw-r--r--support/dktools/f2lopt.h64
-rw-r--r--support/dktools/f2lpara.c97
-rw-r--r--support/dktools/f2lpara.ctr110
-rw-r--r--support/dktools/f2lpara.h89
-rw-r--r--support/dktools/f2lpdf.c1493
-rw-r--r--support/dktools/f2lpdf.ctr1990
-rw-r--r--support/dktools/f2lpdf.h734
-rw-r--r--support/dktools/f2lpgf.c1630
-rw-r--r--support/dktools/f2lpgf.ctr2235
-rw-r--r--support/dktools/f2lpgf.h791
-rw-r--r--support/dktools/f2lsvg.c3590
-rw-r--r--support/dktools/f2lsvg.ctr3275
-rw-r--r--support/dktools/f2lsvg.h63
-rw-r--r--support/dktools/f2lsvgst.c3412
-rw-r--r--support/dktools/f2lsvgst.ctr3467
-rw-r--r--support/dktools/f2lsvgst.h445
-rw-r--r--support/dktools/f2lto.c1424
-rw-r--r--support/dktools/f2lto.ctr1616
-rw-r--r--support/dktools/f2lto.h298
-rw-r--r--support/dktools/f2lud.c4012
-rw-r--r--support/dktools/f2lud.ctr3800
-rw-r--r--support/dktools/f2lud.h238
-rw-r--r--support/dktools/f2ludpat.c1598
-rw-r--r--support/dktools/f2ludpat.ctr1549
-rw-r--r--support/dktools/f2ludpat.h71
-rw-r--r--support/dktools/favicon.icobin0 -> 21542 bytes
-rw-r--r--support/dktools/fig2lat.c1484
-rw-r--r--support/dktools/fig2lat.ctr1505
-rw-r--r--support/dktools/fig2lat.h244
-rw-r--r--support/dktools/fig2lat.rc37
-rw-r--r--support/dktools/filelist.txt2472
-rw-r--r--support/dktools/hbchm.c865
-rw-r--r--support/dktools/hbchm.ctr752
-rw-r--r--support/dktools/hbchm.h69
-rw-r--r--support/dktools/hbconf.c1485
-rw-r--r--support/dktools/hbconf.ctr1455
-rw-r--r--support/dktools/hbconf.h136
-rw-r--r--support/dktools/hbcont.c1415
-rw-r--r--support/dktools/hbcont.ctr1273
-rw-r--r--support/dktools/hbcont.h94
-rw-r--r--support/dktools/hbhtml.c6882
-rw-r--r--support/dktools/hbhtml.ctr5633
-rw-r--r--support/dktools/hbhtml.h119
-rw-r--r--support/dktools/hbimgdim.c182
-rw-r--r--support/dktools/hbimgdim.ctr192
-rw-r--r--support/dktools/hbimgdim.h104
-rw-r--r--support/dktools/hbindex.c209
-rw-r--r--support/dktools/hbindex.ctr226
-rw-r--r--support/dktools/hbindex.h69
-rw-r--r--support/dktools/hbnode.c539
-rw-r--r--support/dktools/hbnode.ctr503
-rw-r--r--support/dktools/hbnode.h120
-rw-r--r--support/dktools/hbtool.c400
-rw-r--r--support/dktools/hbtool.ctr432
-rw-r--r--support/dktools/hbtool.h148
-rw-r--r--support/dktools/help-chm/de/winprint.chmbin0 -> 159810 bytes
-rw-r--r--support/dktools/help-chm/de/wxbmpp.chmbin0 -> 213128 bytes
-rw-r--r--support/dktools/help-chm/de/wxdkclock.chmbin0 -> 85271 bytes
-rw-r--r--support/dktools/help-chm/de/wxdkct.chmbin0 -> 102122 bytes
-rw-r--r--support/dktools/help-chm/de/wxdkfcs.chmbin0 -> 32411 bytes
-rw-r--r--support/dktools/help-chm/de/wxdkscrsz.chmbin0 -> 30744 bytes
-rw-r--r--support/dktools/help-chm/de/wximgsz.chmbin0 -> 110141 bytes
-rw-r--r--support/dktools/help-chm/de/wxpqdic.chmbin0 -> 32521 bytes
-rw-r--r--support/dktools/help-chm/en/winprint.chmbin0 -> 141564 bytes
-rw-r--r--support/dktools/help-chm/en/wxbmpp.chmbin0 -> 201960 bytes
-rw-r--r--support/dktools/help-chm/en/wxdkclock.chmbin0 -> 83859 bytes
-rw-r--r--support/dktools/help-chm/en/wxdkct.chmbin0 -> 91148 bytes
-rw-r--r--support/dktools/help-chm/en/wxdkfcs.chmbin0 -> 32131 bytes
-rw-r--r--support/dktools/help-chm/en/wxdkscrsz.chmbin0 -> 30488 bytes
-rw-r--r--support/dktools/help-chm/en/wximgsz.chmbin0 -> 108103 bytes
-rw-r--r--support/dktools/help-chm/en/wxpqdic.chmbin0 -> 31873 bytes
-rw-r--r--support/dktools/help-htb/de/winprint.htbbin0 -> 161462 bytes
-rw-r--r--support/dktools/help-htb/de/wxbmpp.htbbin0 -> 216533 bytes
-rw-r--r--support/dktools/help-htb/de/wxdkclock.htbbin0 -> 87549 bytes
-rw-r--r--support/dktools/help-htb/de/wxdkct.htbbin0 -> 101343 bytes
-rw-r--r--support/dktools/help-htb/de/wxdkfcs.htbbin0 -> 34013 bytes
-rw-r--r--support/dktools/help-htb/de/wxdkscrsz.htbbin0 -> 30353 bytes
-rw-r--r--support/dktools/help-htb/de/wximgsz.htbbin0 -> 108978 bytes
-rw-r--r--support/dktools/help-htb/de/wxpqdic.htbbin0 -> 32950 bytes
-rw-r--r--support/dktools/help-htb/en/winprint.htbbin0 -> 142007 bytes
-rw-r--r--support/dktools/help-htb/en/wxbmpp.htbbin0 -> 206219 bytes
-rw-r--r--support/dktools/help-htb/en/wxdkclock.htbbin0 -> 85707 bytes
-rw-r--r--support/dktools/help-htb/en/wxdkct.htbbin0 -> 90608 bytes
-rw-r--r--support/dktools/help-htb/en/wxdkfcs.htbbin0 -> 33615 bytes
-rw-r--r--support/dktools/help-htb/en/wxdkscrsz.htbbin0 -> 30005 bytes
-rw-r--r--support/dktools/help-htb/en/wximgsz.htbbin0 -> 107354 bytes
-rw-r--r--support/dktools/help-htb/en/wxpqdic.htbbin0 -> 32252 bytes
-rw-r--r--support/dktools/htmlbook.c2699
-rw-r--r--support/dktools/htmlbook.ctr2867
-rw-r--r--support/dktools/htmlbook.h407
-rw-r--r--support/dktools/htmlbook.rc37
-rw-r--r--support/dktools/initd-printqd.in60
-rwxr-xr-xsupport/dktools/install-sh501
-rwxr-xr-xsupport/dktools/itaclean.sh62
-rw-r--r--support/dktools/itacomp.c890
-rw-r--r--support/dktools/itacomp.ctr860
-rw-r--r--support/dktools/itaconf.c826
-rw-r--r--support/dktools/itaconf.ctr697
-rw-r--r--support/dktools/itadata.c78
-rw-r--r--support/dktools/itadata.ctr41
-rw-r--r--support/dktools/itadhcp.c1161
-rw-r--r--support/dktools/itadhcp.ctr1008
-rw-r--r--support/dktools/itadmin.c2537
-rw-r--r--support/dktools/itadmin.ctr4125
-rw-r--r--support/dktools/itadmin.h1790
-rw-r--r--support/dktools/itadmin.rc37
-rw-r--r--support/dktools/itaether.c229
-rw-r--r--support/dktools/itaether.ctr199
-rw-r--r--support/dktools/itahosts.c321
-rw-r--r--support/dktools/itahosts.ctr288
-rw-r--r--support/dktools/italic.c1297
-rw-r--r--support/dktools/italic.ctr1260
-rw-r--r--support/dktools/itamem.c1721
-rw-r--r--support/dktools/itamem.ctr1506
-rw-r--r--support/dktools/itamysql.c2353
-rw-r--r--support/dktools/itamysql.ctr1969
-rw-r--r--support/dktools/itanetd.c1322
-rw-r--r--support/dktools/itanetd.ctr1256
-rw-r--r--support/dktools/itange.c325
-rw-r--r--support/dktools/itange.ctr248
-rw-r--r--support/dktools/itareg.c2235
-rw-r--r--support/dktools/itareg.ctr1862
-rw-r--r--support/dktools/itatool.c537
-rw-r--r--support/dktools/itatool.ctr511
-rw-r--r--support/dktools/libdk4app.dox36
-rw-r--r--support/dktools/libdk4base.dox21
-rw-r--r--support/dktools/libdk4c.dox262
-rw-r--r--support/dktools/libdk4dbi.dox46
-rw-r--r--support/dktools/libdk4dbia.dox11
-rw-r--r--support/dktools/libdk4lat.dox15
-rw-r--r--support/dktools/libdk4ma.dox42
-rw-r--r--support/dktools/libdk4maio8d.dox39
-rw-r--r--support/dktools/libdk4maio8h.dox36
-rw-r--r--support/dktools/libdk4maiodd.dox39
-rw-r--r--support/dktools/libdk4maiodh.dox36
-rw-r--r--support/dktools/libdk4maiowd.dox39
-rw-r--r--support/dktools/libdk4maiowh.dox36
-rw-r--r--support/dktools/libdk4mdrnd.dox15
-rw-r--r--support/dktools/libdk4pppt.dox7
-rw-r--r--support/dktools/libdk4sock.dox9
-rw-r--r--support/dktools/libdk4socka.dox10
-rw-r--r--support/dktools/libdk4wx.dox23
-rw-r--r--support/dktools/livesys-data/apt-pinning.txt20
-rw-r--r--support/dktools/livesys-data/apt_pinning.txt2
-rwxr-xr-xsupport/dktools/livesys-data/hook_autologin.txt18
-rw-r--r--support/dktools/livesys-data/hook_bootbeep.txt5
-rwxr-xr-xsupport/dktools/livesys-data/hook_etcfiles.txt18
-rw-r--r--support/dktools/livesys-data/msg_nonfree.txt6
-rw-r--r--support/dktools/livesys-data/pkg_base.txt88
-rw-r--r--support/dktools/livesys-data/pkg_firmware.txt23
-rw-r--r--support/dktools/livesys-data/pkg_lang_base.txt62
-rw-r--r--support/dktools/livesys-data/pkg_lang_desktop.txt72
-rw-r--r--support/dktools/livesys-data/pkg_local.txt23
-rw-r--r--support/dktools/livesys-data/pkg_xfce.txt40
-rw-r--r--support/dktools/livesys-data/root-cli/usr/share/dktoolian/getty.sed1
-rwxr-xr-xsupport/dktools/livesys-data/root/usr/local/bin/dktoolian-etc19
-rwxr-xr-xsupport/dktools/livesys-data/root/usr/local/bin/dktoolian-ntp2
-rw-r--r--support/dktools/livesys-data/root/usr/share/dktoolian/etc-files.sed2
-rw-r--r--support/dktools/livesys-data/root/usr/share/dktoolian/ntp.conf.template14
-rw-r--r--support/dktools/livesys-data/sed_isolinux.txt2
-rw-r--r--support/dktools/livesys-data/sed_menu.txt2
-rw-r--r--support/dktools/livesys-data/sed_nobeep.txt1
-rw-r--r--support/dktools/lprngcl.c1398
-rw-r--r--support/dktools/lprngcl.ctr1149
-rw-r--r--support/dktools/lprngcl.rc37
-rw-r--r--support/dktools/makefile.vc1342
-rw-r--r--support/dktools/man/man1/addctrld.196
-rw-r--r--support/dktools/man/man1/bmpp.1361
-rw-r--r--support/dktools/man/man1/dk-blks.1102
-rw-r--r--support/dktools/man/man1/dk-bmm.1160
-rw-r--r--support/dktools/man/man1/dk-cat.1203
-rw-r--r--support/dktools/man/man1/dk-db2t.1223
-rw-r--r--support/dktools/man/man1/dk-dbco.1185
-rw-r--r--support/dktools/man/man1/dk-eradisk.1110
-rw-r--r--support/dktools/man/man1/dk-fic.1144
-rw-r--r--support/dktools/man/man1/dk-hex.1118
-rw-r--r--support/dktools/man/man1/dk-ls.1762
-rw-r--r--support/dktools/man/man1/dk-pwd.1105
-rw-r--r--support/dktools/man/man1/dk-pwgen.1231
-rw-r--r--support/dktools/man/man1/dk-rand.1132
-rw-r--r--support/dktools/man/man1/dk-recv.1150
-rw-r--r--support/dktools/man/man1/dk-send.1175
-rw-r--r--support/dktools/man/man1/dk-sort.1232
-rw-r--r--support/dktools/man/man1/dk-sqlsplit.199
-rw-r--r--support/dktools/man/man1/dk-t2db.1232
-rw-r--r--support/dktools/man/man1/dk-t2h.1186
-rw-r--r--support/dktools/man/man1/dk-t2l.1236
-rw-r--r--support/dktools/man/man1/dk-uid.1117
-rw-r--r--support/dktools/man/man1/dk3info.197
-rw-r--r--support/dktools/man/man1/dk4info.197
-rw-r--r--support/dktools/man/man1/dkct.1201
-rw-r--r--support/dktools/man/man1/dkdbt.1326
-rw-r--r--support/dktools/man/man1/dktools.1406
-rw-r--r--support/dktools/man/man1/dkwxwiz.1214
-rw-r--r--support/dktools/man/man1/fig2lat.1540
-rw-r--r--support/dktools/man/man1/htmlbook.1202
-rw-r--r--support/dktools/man/man1/itaclean.1212
-rw-r--r--support/dktools/man/man1/itadmin.1191
-rw-r--r--support/dktools/man/man1/lprngcl.1134
-rw-r--r--support/dktools/man/man1/pjsnmp.11211
-rw-r--r--support/dktools/man/man1/plpdftex.1123
-rw-r--r--support/dktools/man/man1/printqd.1260
-rw-r--r--support/dktools/man/man1/printqda.1263
-rw-r--r--support/dktools/man/man1/printqdc.1270
-rw-r--r--support/dktools/man/man1/printqdi.1162
-rw-r--r--support/dktools/man/man1/prmonsnmp.1202
-rw-r--r--support/dktools/man/man1/rshdown.1402
-rw-r--r--support/dktools/man/man1/wxbmpp.1132
-rw-r--r--support/dktools/man/man1/wxdkclock.194
-rw-r--r--support/dktools/man/man1/wxdkct.1169
-rw-r--r--support/dktools/man/man1/wxdkfcs.191
-rw-r--r--support/dktools/man/man1/wxdkhtb.194
-rw-r--r--support/dktools/man/man1/wximgsz.1154
-rw-r--r--support/dktools/man/man1/wxpqdic.1154
-rw-r--r--support/dktools/man/man5/dkct-wxgui.51510
-rw-r--r--support/dktools/man/man5/dkct.5635
-rw-r--r--support/dktools/man/man5/htmlbook-project.5319
-rw-r--r--support/dktools/man/man5/htmlbook-template.5505
-rw-r--r--support/dktools/man/man5/htmlbook-text.5538
-rw-r--r--support/dktools/man/man5/printqd.conf.5259
-rw-r--r--support/dktools/man/man5/printqd.db.5124
-rw-r--r--support/dktools/man/man5/printqd.protocol.5204
-rw-r--r--support/dktools/mod-dkconfig.sed2
-rw-r--r--support/dktools/modsnmp.sed3
-rw-r--r--support/dktools/pjsnmp.c6379
-rw-r--r--support/dktools/pjsnmp.ctr5367
-rw-r--r--support/dktools/pjsnmp.h246
-rw-r--r--support/dktools/pkginfo9
-rw-r--r--support/dktools/pkginfo.in9
-rw-r--r--support/dktools/plpdftex.c3175
-rw-r--r--support/dktools/plpdftex.ctr2923
-rw-r--r--support/dktools/plpdftex.h132
-rw-r--r--support/dktools/plpdftex.rc37
-rw-r--r--support/dktools/plptcol.c304
-rw-r--r--support/dktools/plptcol.ctr295
-rw-r--r--support/dktools/plptcol.h98
-rw-r--r--support/dktools/printqd.c8356
-rw-r--r--support/dktools/printqd.conf.sample206
-rw-r--r--support/dktools/printqd.ctr7389
-rw-r--r--support/dktools/printqd.h242
-rw-r--r--support/dktools/printqda.c1200
-rw-r--r--support/dktools/printqda.ctr1038
-rw-r--r--support/dktools/printqda.h64
-rw-r--r--support/dktools/printqdc.c1563
-rw-r--r--support/dktools/printqdc.ctr1359
-rw-r--r--support/dktools/printqds.h19
-rw-r--r--support/dktools/prmonsnmp.c2090
-rw-r--r--support/dktools/prmonsnmp.ctr1958
-rw-r--r--support/dktools/resources/GNUmakefile60
-rw-r--r--support/dktools/resources/choose-dir.fig20
-rw-r--r--support/dktools/resources/dkclock.fig27
-rw-r--r--support/dktools/resources/dkctinst.fig13
-rw-r--r--support/dktools/resources/dkctunin.fig13
-rw-r--r--support/dktools/resources/dkicon.fig13
-rw-r--r--support/dktools/resources/exit-program.fig18
-rw-r--r--support/dktools/resources/favicon.fig13
-rw-r--r--support/dktools/resources/run-conversion.fig13
-rw-r--r--support/dktools/resources/run2.fig13
-rw-r--r--support/dktools/resources/set-options.fig15
-rw-r--r--support/dktools/resources/splash-dktoolian.fig20
-rw-r--r--support/dktools/resources/toolbase.fig14
-rw-r--r--support/dktools/resources/wxdkscrsz.fig25
-rw-r--r--support/dktools/rshdown.c2789
-rw-r--r--support/dktools/rshdown.conf.sample40
-rw-r--r--support/dktools/rshdown.ctr2379
-rw-r--r--support/dktools/run-conversion.xpm39
-rw-r--r--support/dktools/run2.xpm31
-rwxr-xr-xsupport/dktools/scripts/build-help.sh106
-rw-r--r--support/dktools/scripts/build-help.sh.in106
-rwxr-xr-xsupport/dktools/scripts/check_config_have.pl98
-rwxr-xr-xsupport/dktools/scripts/clean-for-fig.sh57
-rwxr-xr-xsupport/dktools/scripts/clean-for-tex.sh50
-rwxr-xr-xsupport/dktools/scripts/clean-help-doc.sh53
-rwxr-xr-xsupport/dktools/scripts/clean-resources.sh44
-rwxr-xr-xsupport/dktools/scripts/clean.sh88
-rwxr-xr-xsupport/dktools/scripts/create-debian-changelog.pl137
-rw-r--r--support/dktools/scripts/create-desktop-files.sh.in133
-rwxr-xr-xsupport/dktools/scripts/create-distribution.sh229
-rw-r--r--support/dktools/scripts/create-iss.sed6
-rwxr-xr-xsupport/dktools/scripts/create-spec-iss.sh78
-rwxr-xr-xsupport/dktools/scripts/distrenew.sh69
-rwxr-xr-xsupport/dktools/scripts/dkmkproto.pl248
-rwxr-xr-xsupport/dktools/scripts/doc-install.sh44
-rwxr-xr-xsupport/dktools/scripts/filechk.pl80
-rwxr-xr-xsupport/dktools/scripts/find-headers-without-modules.sh61
-rwxr-xr-xsupport/dktools/scripts/git-add.sh95
-rwxr-xr-xsupport/dktools/scripts/make-resources.sh44
-rwxr-xr-xsupport/dktools/scripts/man-install.sh44
-rwxr-xr-xsupport/dktools/scripts/mkrc.pl647
-rwxr-xr-xsupport/dktools/scripts/show-dependencies.pl98
-rwxr-xr-xsupport/dktools/scripts/transform-config.pl302
-rwxr-xr-xsupport/dktools/scripts/update-doxyfile.sh47
-rw-r--r--support/dktools/scripts/wr-dk3inst.sh.in106
-rw-r--r--support/dktools/scripts/wr-dk4inst.sh.in274
-rw-r--r--support/dktools/sep.txt2
-rw-r--r--support/dktools/set-options.xpm38
-rw-r--r--support/dktools/sf-readme/readme.md79
-rwxr-xr-xsupport/dktools/sl6-build-rpm.sh76
-rwxr-xr-xsupport/dktools/sl6-prepare.sh28
-rwxr-xr-xsupport/dktools/sl7-build-rpm.sh76
-rw-r--r--support/dktools/splash-dktoolian.eps945
-rw-r--r--support/dktools/splash-dktoolian.pngbin0 -> 6839 bytes
-rw-r--r--support/dktools/standard-headers.txt29
-rw-r--r--support/dktools/sttfiles.dox89
-rw-r--r--support/dktools/test-a85d.c148
-rw-r--r--support/dktools/test-a85d.ctr129
-rw-r--r--support/dktools/test-a85e.c134
-rw-r--r--support/dktools/test-a85e.ctr115
-rw-r--r--support/dktools/test-binenc.c45
-rw-r--r--support/dktools/test-binenc.ctr33
-rw-r--r--support/dktools/test-bool.c210
-rw-r--r--support/dktools/test-bool.ctr86
-rw-r--r--support/dktools/test-container.cpp132
-rw-r--r--support/dktools/test-container.cpt121
-rw-r--r--support/dktools/test-deldir.c132
-rw-r--r--support/dktools/test-deldir.ctr106
-rw-r--r--support/dktools/test-deldirwc.c29
-rw-r--r--support/dktools/test-deldirwc.ctr17
-rw-r--r--support/dktools/test-deltree.c132
-rw-r--r--support/dktools/test-deltree.ctr106
-rw-r--r--support/dktools/test-dk4c8dbl.c260
-rw-r--r--support/dktools/test-dk4c8dbl.ctr102
-rw-r--r--support/dktools/test-dk4dir.c141
-rw-r--r--support/dktools/test-dk4dir.ctr115
-rw-r--r--support/dktools/test-dk4dir08.c54
-rw-r--r--support/dktools/test-dk4dir08.ctr34
-rw-r--r--support/dktools/test-dk4enc.c41
-rw-r--r--support/dktools/test-dk4enc.ctr29
-rw-r--r--support/dktools/test-dk4exep8.c48
-rw-r--r--support/dktools/test-dk4exep8.ctr26
-rw-r--r--support/dktools/test-dk4loc.c86
-rw-r--r--support/dktools/test-dk4loc.ctr56
-rw-r--r--support/dktools/test-dk4maac.c110
-rw-r--r--support/dktools/test-dk4maac.ctr88
-rw-r--r--support/dktools/test-dk4maai.c109
-rw-r--r--support/dktools/test-dk4maai.ctr87
-rw-r--r--support/dktools/test-dk4maal.c109
-rw-r--r--support/dktools/test-dk4maal.ctr87
-rw-r--r--support/dktools/test-dk4maall.c109
-rw-r--r--support/dktools/test-dk4maall.ctr87
-rw-r--r--support/dktools/test-dk4maami.c109
-rw-r--r--support/dktools/test-dk4maami.ctr87
-rw-r--r--support/dktools/test-dk4maamu.c109
-rw-r--r--support/dktools/test-dk4maamu.ctr87
-rw-r--r--support/dktools/test-dk4maas.c109
-rw-r--r--support/dktools/test-dk4maas.ctr87
-rw-r--r--support/dktools/test-dk4maauc.c110
-rw-r--r--support/dktools/test-dk4maauc.ctr88
-rw-r--r--support/dktools/test-dk4maaui.c110
-rw-r--r--support/dktools/test-dk4maaui.ctr88
-rw-r--r--support/dktools/test-dk4maaul.c109
-rw-r--r--support/dktools/test-dk4maaul.ctr87
-rw-r--r--support/dktools/test-dk4maaull.c109
-rw-r--r--support/dktools/test-dk4maaull.ctr87
-rw-r--r--support/dktools/test-dk4maaus.c110
-rw-r--r--support/dktools/test-dk4maaus.ctr88
-rw-r--r--support/dktools/test-dk4mai8dbl.c35
-rw-r--r--support/dktools/test-dk4mai8dbl.ctr23
-rw-r--r--support/dktools/test-dk4mai8ddi.c52
-rw-r--r--support/dktools/test-dk4mai8ddi.ctr40
-rw-r--r--support/dktools/test-dk4mai8ddu.c52
-rw-r--r--support/dktools/test-dk4mai8ddu.ctr40
-rw-r--r--support/dktools/test-dk4mai8dsz.c52
-rw-r--r--support/dktools/test-dk4mai8dsz.ctr40
-rw-r--r--support/dktools/test-dk4mai8sz.c52
-rw-r--r--support/dktools/test-dk4numl.c36
-rw-r--r--support/dktools/test-dk4numl.ctr24
-rw-r--r--support/dktools/test-dk4path8.c54
-rw-r--r--support/dktools/test-dk4path8.ctr42
-rw-r--r--support/dktools/test-dk4str8.c60
-rw-r--r--support/dktools/test-dk4str8.ctr40
-rw-r--r--support/dktools/test-dk4strm.c89
-rw-r--r--support/dktools/test-dk4strm.ctr63
-rw-r--r--support/dktools/test-dk4strmco.c101
-rw-r--r--support/dktools/test-dk4strmco.ctr79
-rw-r--r--support/dktools/test-dk4time.c32
-rw-r--r--support/dktools/test-dk4time.ctr20
-rw-r--r--support/dktools/test-dk4time08.c32
-rw-r--r--support/dktools/test-dk4time08.ctr20
-rw-r--r--support/dktools/test-dk4tsp08.c191
-rw-r--r--support/dktools/test-dk4tsp08.ctr157
-rw-r--r--support/dktools/test-dk4user.c75
-rw-r--r--support/dktools/test-dk4user.ctr53
-rw-r--r--support/dktools/test-dk4wxah.cpp69
-rw-r--r--support/dktools/test-dk4wxah.cpt43
-rw-r--r--support/dktools/test-eradisk.c48
-rw-r--r--support/dktools/test-eradisk.ctr36
-rw-r--r--support/dktools/test-filei.c86
-rw-r--r--support/dktools/test-filei.ctr52
-rw-r--r--support/dktools/test-fne.c42
-rw-r--r--support/dktools/test-fne.ctr30
-rw-r--r--support/dktools/test-home.c58
-rw-r--r--support/dktools/test-home.ctr40
-rw-r--r--support/dktools/test-inet-pton.c133
-rw-r--r--support/dktools/test-inet-pton.ctr91
-rw-r--r--support/dktools/test-mbstr.c51
-rw-r--r--support/dktools/test-mbstr.ctr39
-rw-r--r--support/dktools/test-membuf.c60
-rw-r--r--support/dktools/test-membuf.ctr48
-rw-r--r--support/dktools/test-mkdir.c132
-rw-r--r--support/dktools/test-mkdir.ctr106
-rw-r--r--support/dktools/test-opt.c102
-rw-r--r--support/dktools/test-opt.ctr80
-rw-r--r--support/dktools/test-paper.c132
-rw-r--r--support/dktools/test-paper.ctr106
-rw-r--r--support/dktools/test-peer.c160
-rw-r--r--support/dktools/test-peer.ctr115
-rw-r--r--support/dktools/test-rld.c124
-rw-r--r--support/dktools/test-rld.ctr112
-rwxr-xr-xsupport/dktools/test-rle-rld.sh14
-rw-r--r--support/dktools/test-rle.c181
-rw-r--r--support/dktools/test-rle.ctr123
-rw-r--r--support/dktools/test-ser.c162
-rw-r--r--support/dktools/test-ser.ctr146
-rw-r--r--support/dktools/test-skip.c31
-rw-r--r--support/dktools/test-skip.ctr19
-rw-r--r--support/dktools/test-sock.c253
-rw-r--r--support/dktools/test-sock.ctr173
-rw-r--r--support/dktools/test-sqdbl.c51
-rw-r--r--support/dktools/test-sqdbl.ctr37
-rw-r--r--support/dktools/test-strms.c48
-rw-r--r--support/dktools/test-strms.ctr36
-rw-r--r--support/dktools/test-strmu.c116
-rw-r--r--support/dktools/test-strmu.ctr104
-rw-r--r--support/dktools/test-strmw.c360
-rw-r--r--support/dktools/test-strmw.ctr336
-rw-r--r--support/dktools/test-udpa.c99
-rw-r--r--support/dktools/test-udpa.ctr87
-rw-r--r--support/dktools/test-unser.c164
-rw-r--r--support/dktools/test-unser.ctr146
-rw-r--r--support/dktools/testlzw.c109
-rw-r--r--support/dktools/testlzw.ctr75
-rw-r--r--support/dktools/testlzws.c73
-rw-r--r--support/dktools/testlzws.ctr51
-rwxr-xr-xsupport/dktools/translate-wxcs.pl6
-rw-r--r--support/dktools/translate.vc675
-rw-r--r--support/dktools/version.txt1
-rw-r--r--support/dktools/win32/dk3conf.h4222
-rw-r--r--support/dktools/win32/dk3wxcs.h9
-rw-r--r--support/dktools/win32/dk4conf.h2204
-rw-r--r--support/dktools/win32/dk4wxcs.h9
-rw-r--r--support/dktools/win32/user32.iss59
-rw-r--r--support/dktools/win32/user64.iss60
-rw-r--r--support/dktools/win32/user64.iss.in60
-rw-r--r--support/dktools/winprint.h95
-rw-r--r--support/dktools/winprint.rc37
-rw-r--r--support/dktools/wprclean.c800
-rw-r--r--support/dktools/wprclean.ctr702
-rw-r--r--support/dktools/wprclean.h68
-rw-r--r--support/dktools/wprclean.rc37
-rw-r--r--support/dktools/wprclean2.c1178
-rw-r--r--support/dktools/wprclean2.ctr1014
-rw-r--r--support/dktools/wxbmeps.h119
-rw-r--r--support/dktools/wxbmpp.desktop12
-rw-r--r--support/dktools/wxbmpp.rc37
-rw-r--r--support/dktools/wxcs.cpp53
-rw-r--r--support/dktools/wxdkclock.desktop12
-rw-r--r--support/dktools/wxdkclock.h123
-rw-r--r--support/dktools/wxdkclock.rc37
-rw-r--r--support/dktools/wxdkct.desktop11
-rw-r--r--support/dktools/wxdkct.rc37
-rw-r--r--support/dktools/wxdkfcs.desktop11
-rw-r--r--support/dktools/wxdkfcs.h147
-rw-r--r--support/dktools/wxdkfcs.rc37
-rw-r--r--support/dktools/wxdkfcs.str83
-rw-r--r--support/dktools/wxdkhtb.h80
-rw-r--r--support/dktools/wxdkhtb.rc37
-rw-r--r--support/dktools/wxdkscrsz.h145
-rw-r--r--support/dktools/wxdkscrsz.icobin0 -> 21542 bytes
-rw-r--r--support/dktools/wxdkscrsz.rc37
-rw-r--r--support/dktools/wxdkscrsz.xpm38
-rw-r--r--support/dktools/wximgsz.desktop11
-rw-r--r--support/dktools/wximgsz.h86
-rw-r--r--support/dktools/wximgsz.rc37
-rw-r--r--support/dktools/wxpqdic.h265
-rw-r--r--support/dktools/wxpqdic.rc37
-rw-r--r--support/dktools/x.sed3
2443 files changed, 956431 insertions, 0 deletions
diff --git a/support/dktools/Dk4Comparable.cpp b/support/dktools/Dk4Comparable.cpp
new file mode 100644
index 0000000000..a712e3d8ee
--- /dev/null
+++ b/support/dktools/Dk4Comparable.cpp
@@ -0,0 +1,58 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: Dk4Comparable.cpt
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file Dk4Comparable.cpp The Dk4Comparable module.
+*/
+
+
+#line 50 "Dk4Comparable.cpt"
+
+#include "Dk4Comparable.h"
+
+int
+DkTools4::Comparable::compareTwoPointers(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ if(l) {
+ if(r) {
+ DkTools4::Comparable const *pl = (DkTools4::Comparable const *)l;
+ back = pl->compareAgainst(r, cr);
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ }
+ return back;
+}
+
diff --git a/support/dktools/Dk4Comparable.cpt b/support/dktools/Dk4Comparable.cpt
new file mode 100644
index 0000000000..17158666b7
--- /dev/null
+++ b/support/dktools/Dk4Comparable.cpt
@@ -0,0 +1,67 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2013-xxxx
+license = bsd
+
+%% header
+
+namespace DkTools4 {
+
+ /** Comparable is a general base class for the library.
+ */
+ class Comparable
+ {
+ public:
+ /** Compare object against another object or some data.
+ This comparison is used by sorted containers.
+ Example: When storing persons (name and age) we can use
+ crit=0 as comparison criteria in the container to compare
+ person object against person object. When searching the container
+ for an object with a specific name we can use crit=1 for comparisons
+ of the object against a string.
+ @param ptr Address of other object or data.
+ @param crit Comparison criteria, see documentation of
+ derived classes for class-specific numbers.
+ @return Positive number if larger than ptr, 0 if evaluates
+ equal to ptr, negative number if smaller than ptr.
+ */
+ virtual
+ int
+ compareAgainst(void const *ptr, int crit) const = 0;
+
+ /** Compare two pointers
+ @param l Left pointer.
+ @param r Right pointer.
+ @param cr Comparison criteria.
+ @return 1 for left object is large, 0 for right object
+ is large, 0 for objects evaluating equally.
+ */
+ static
+ int
+ compareTwoPointers(void const *l, void const *r, int cr);
+
+ }; /* End of class Comparable. */
+
+} /* End of namespace DkTools4 */
+
+
+%% module
+
+#include "Dk4Comparable.h"
+
+int
+DkTools4::Comparable::compareTwoPointers(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ if(l) {
+ if(r) {
+ DkTools4::Comparable const *pl = (DkTools4::Comparable const *)l;
+ back = pl->compareAgainst(r, cr);
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ }
+ return back;
+}
+
diff --git a/support/dktools/Dk4Comparable.h b/support/dktools/Dk4Comparable.h
new file mode 100644
index 0000000000..36f5335181
--- /dev/null
+++ b/support/dktools/Dk4Comparable.h
@@ -0,0 +1,87 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: Dk4Comparable.cpt
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file Dk4Comparable.h Header file for the Dk4Comparable module.
+*/
+
+#ifndef DK4COMPARABLE_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4COMPARABLE_H_INCLUDED 1
+
+
+#line 8 "Dk4Comparable.cpt"
+
+namespace DkTools4 {
+
+ /** Comparable is a general base class for the library.
+ */
+ class Comparable
+ {
+ public:
+ /** Compare object against another object or some data.
+ This comparison is used by sorted containers.
+ Example: When storing persons (name and age) we can use
+ crit=0 as comparison criteria in the container to compare
+ person object against person object. When searching the container
+ for an object with a specific name we can use crit=1 for comparisons
+ of the object against a string.
+ @param ptr Address of other object or data.
+ @param crit Comparison criteria, see documentation of
+ derived classes for class-specific numbers.
+ @return Positive number if larger than ptr, 0 if evaluates
+ equal to ptr, negative number if smaller than ptr.
+ */
+ virtual
+ int
+ compareAgainst(void const *ptr, int crit) const = 0;
+
+ /** Compare two pointers
+ @param l Left pointer.
+ @param r Right pointer.
+ @param cr Comparison criteria.
+ @return 1 for left object is large, 0 for right object
+ is large, 0 for objects evaluating equally.
+ */
+ static
+ int
+ compareTwoPointers(void const *l, void const *r, int cr);
+
+ }; /* End of class Comparable. */
+
+} /* End of namespace DkTools4 */
+
+
+
+#endif
diff --git a/support/dktools/Dk4Container.cpt b/support/dktools/Dk4Container.cpt
new file mode 100644
index 0000000000..be082f5619
--- /dev/null
+++ b/support/dktools/Dk4Container.cpt
@@ -0,0 +1,391 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2013-xxxx
+license = bsd
+
+%% header
+
+#include <dk4error.h>
+#include <dk4sto.h>
+
+#include <stdexcept>
+#include <new>
+
+#include "Dk4Comparable.h"
+
+
+namespace DkTools4 {
+
+ template<class T> class Container;
+ template<class T> class Iterator;
+
+ /** A container class for sorted storage.
+ The objects must be derived from the Comparable class.
+ */
+ template<class T>
+ class Container
+ {
+ friend class Iterator<T>;
+
+ private:
+
+ /** Storage to store elements.
+ */
+ dk4_sto_t *sto;
+
+ /** Iterator, used in destructor.
+ */
+ dk4_sto_it_t *it;
+
+ /** Comparison criteria for ordering elements.
+ */
+ int cr;
+
+ /** Flag: Container is owner of the objects and in charge
+ for destruction.
+ */
+ bool bOwner;
+
+ public:
+ /** Create container.
+ @param crit Sort criteria for objects in container.
+ @param owner Owner flag value. If a container is the
+ owner of the objects stored in it, the objects are deleted
+ in the containers destructor.
+ */
+ Container<T>(int crit, bool owner = false) throw (std::bad_alloc);
+
+ /** Destructor.
+ */
+ ~Container<T>();
+
+ /** Add an object to the container.
+ @param ptr Pointer to add.
+ @return True on success, false on error (object not added).
+ */
+ bool
+ add(T *ptr);
+
+ /** Remove object from container.
+ @param ptr Pointer to remove.
+ @return True on success, false on error.
+ */
+ bool
+ remove(T *ptr);
+
+ /** Check owner flag.
+ @return Owner flag value.
+ */
+ void
+ isOwner(void) const;
+
+ /** Reset iterator.
+ */
+ void
+ reset(void);
+
+ /** Set iterator to exact position.
+ @param data
+ @param crit
+ @return Pointer to found object on success, NULL otherwise.
+ */
+ T *
+ findExact(void const *data, int crit);
+
+ /** Set iterator to object evaluating equally.
+ @param data
+ @param crit
+ @return Pointer to found object on success, NULL otherwise.
+ */
+ T *
+ findLike(void const *data, int crit);
+
+ /** Step to next element.
+ @return Pointe to next object (if there is one), NULL
+ if there is no next object.
+ */
+ T *
+ next(void);
+
+
+
+ }; /* End of class Container */
+
+ /** An iterator class to traverse a Containter.
+ */
+ template<class T>
+ class Iterator
+ {
+ private:
+ /** Low-level iterator.
+ */
+ dk4_sto_it_t *it;
+
+ public:
+ /** Constructor.
+ @param cont Container for which the iterator is for.
+ */
+ Iterator<T>(Container<T>& cont) throw (std::bad_alloc);
+
+ /** Destructor.
+ */
+ ~Iterator<T>();
+
+ /** Reset iterator.
+ */
+ void
+ reset(void);
+
+ /** Set iterator to exact position.
+ @param data
+ @param crit
+ @return Pointer to found object on success, NULL otherwise.
+ */
+ T *
+ findExact(void const *data, int crit);
+
+ /** Set iterator to object evaluating equally.
+ @param data
+ @param crit
+ @return Pointer to found object on success, NULL otherwise.
+ */
+ T *
+ findLike(void const *data, int crit);
+
+ /** Step to next element.
+ @return Pointe to next object (if there is one), NULL
+ if there is no next object.
+ */
+ T *
+ next(void);
+
+ }; /* End of class Iterator */
+
+
+} /* End of namespace DkTools4 */
+
+
+
+$*
+ Implementation for container methods.
+$*
+
+template<class T>
+DkTools4::Container<T>::Container(int crit, bool owner) throw (std::bad_alloc)
+{
+ bool mustThrow = true;
+
+ bOwner = owner;
+ cr = crit;
+ it = NULL;
+ sto = dk4sto_open(NULL);
+ if(NULL != sto) {
+ dk4sto_set_comp(sto,DkTools4::Comparable::compareTwoPointers,crit);
+ it = dk4sto_it_open(sto, NULL);
+ if (NULL != it) {
+ mustThrow = false;
+ } else {
+ dk4sto_close(sto);
+ sto = NULL;
+ }
+ }
+ if (mustThrow) {
+ throw(std::bad_alloc());
+ }
+}
+
+
+
+/* The destructor is also called when an exception is thrown by
+ the constructor. So we must check the sto and it component for
+ being not NULL.
+*/
+
+template<class T>
+DkTools4::Container<T>::~Container<T>()
+{
+ T *ptr;
+
+ if (NULL != it) {
+ if (bOwner) {
+ dk4sto_it_reset(it);
+ while(NULL != (ptr = (T *)dk4sto_it_next(it))) {
+ delete ptr;
+ }
+ }
+ dk4sto_it_close(it);
+ }
+ if (NULL != sto) {
+ dk4sto_close(sto);
+ }
+ sto = NULL;
+ it = NULL;
+ cr = 0;
+ bOwner = false;
+}
+
+
+
+/* The remaining container methods are not called if there was
+ an exception from the constructor. So no NULL pointer checks
+ are necessary here.
+*/
+
+
+template<class T>
+bool
+DkTools4::Container<T>::add(T *ptr)
+{
+ bool back = false;
+ if(0 != dk4sto_add(sto, (void *)ptr, NULL)) {
+ back = true;
+ }
+ return back;
+}
+
+
+
+template<class T>
+bool
+DkTools4::Container<T>::remove(T *ptr)
+{
+ bool back = false;
+ if(0 != dk4sto_remove(sto, (void *)ptr, NULL)) {
+ back = true;
+ }
+ return back;
+}
+
+
+
+template<class T>
+void
+DkTools4::Container<T>::isOwner(void) const
+{
+ return bOwner;
+}
+
+
+
+/* The remaining iterator methods are not invoked if the constructor
+ throws an exception, so we do not need to check the it component.
+*/
+
+template<class T>
+void
+DkTools4::Container<T>::reset(void)
+{
+ dk4sto_it_reset(it);
+}
+
+
+
+template<class T>
+T *
+DkTools4::Container<T>::findExact(void const *data, int crit)
+{
+ T *back = NULL;
+ back = (T *)dk4sto_it_find_exact(it, data);
+ return back;
+}
+
+
+
+template<class T>
+T *
+DkTools4::Container<T>::findLike(void const *data, int crit)
+{
+ T *back;
+ back = (T *)dk4sto_it_find_like(it, data, crit);
+ return back;
+}
+
+
+
+template<class T>
+T *
+DkTools4::Container<T>::next(void)
+{
+ T *back = NULL;
+ back = (T *)dk4sto_it_next(it);
+ return back;
+}
+
+
+
+$*
+ Implementation for iterator methods.
+$*
+
+template<class T>
+DkTools4::Iterator<T>::Iterator(Container<T>& cont) throw (std::bad_alloc)
+{
+ it = dk4sto_it_open(cont.sto, NULL);
+ if(NULL != it) {
+ dk4sto_it_reset(it);
+ } else {
+ throw(std::bad_alloc());
+ }
+}
+
+
+
+/* The iterators destructor is also invoked if the constructor throws
+ an exception. So we must check the it component to be not NULL.
+*/
+
+template<class T>
+DkTools4::Iterator<T>::~Iterator<T>()
+{
+ if (NULL != it) {
+ dk4sto_it_close(it); it = NULL;
+ }
+}
+
+
+
+/* The remaining iterator methods are not invoked if the constructor
+ throws an exception, so we do not need to check the it component.
+*/
+
+template<class T>
+void
+DkTools4::Iterator<T>::reset(void)
+{
+ dk4sto_it_reset(it);
+}
+
+
+
+template<class T>
+T *
+DkTools4::Iterator<T>::findExact(void const *data, int crit)
+{
+ T *back = NULL;
+ back = (T *)dk4sto_it_find_exact(it, data);
+ return back;
+}
+
+
+
+template<class T>
+T *
+DkTools4::Iterator<T>::findLike(void const *data, int crit)
+{
+ T *back;
+ back = (T *)dk4sto_it_find_like(it, data, crit);
+ return back;
+}
+
+
+
+template<class T>
+T *
+DkTools4::Iterator<T>::next(void)
+{
+ T *back = NULL;
+ back = (T *)dk4sto_it_next(it);
+ return back;
+}
+
diff --git a/support/dktools/Dk4Container.h b/support/dktools/Dk4Container.h
new file mode 100644
index 0000000000..4a616209a8
--- /dev/null
+++ b/support/dktools/Dk4Container.h
@@ -0,0 +1,440 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: Dk4Container.cpt
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file Dk4Container.h Header file for the Dk4Container module.
+*/
+
+#ifndef DK4CONTAINER_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4CONTAINER_H_INCLUDED 1
+
+
+#line 8 "Dk4Container.cpt"
+
+#include <dk4error.h>
+#include <dk4sto.h>
+
+#include <stdexcept>
+#include <new>
+
+#include "Dk4Comparable.h"
+
+
+namespace DkTools4 {
+
+ template<class T> class Container;
+ template<class T> class Iterator;
+
+ /** A container class for sorted storage.
+ The objects must be derived from the Comparable class.
+ */
+ template<class T>
+ class Container
+ {
+ friend class Iterator<T>;
+
+ private:
+
+ /** Storage to store elements.
+ */
+ dk4_sto_t *sto;
+
+ /** Iterator, used in destructor.
+ */
+ dk4_sto_it_t *it;
+
+ /** Comparison criteria for ordering elements.
+ */
+ int cr;
+
+ /** Flag: Container is owner of the objects and in charge
+ for destruction.
+ */
+ bool bOwner;
+
+ public:
+ /** Create container.
+ @param crit Sort criteria for objects in container.
+ @param owner Owner flag value. If a container is the
+ owner of the objects stored in it, the objects are deleted
+ in the containers destructor.
+ */
+ Container<T>(int crit, bool owner = false) throw (std::bad_alloc);
+
+ /** Destructor.
+ */
+ ~Container<T>();
+
+ /** Add an object to the container.
+ @param ptr Pointer to add.
+ @return True on success, false on error (object not added).
+ */
+ bool
+ add(T *ptr);
+
+ /** Remove object from container.
+ @param ptr Pointer to remove.
+ @return True on success, false on error.
+ */
+ bool
+ remove(T *ptr);
+
+ /** Check owner flag.
+ @return Owner flag value.
+ */
+ void
+ isOwner(void) const;
+
+ /** Reset iterator.
+ */
+ void
+ reset(void);
+
+ /** Set iterator to exact position.
+ @param data
+ @param crit
+ @return Pointer to found object on success, NULL otherwise.
+ */
+ T *
+ findExact(void const *data, int crit);
+
+ /** Set iterator to object evaluating equally.
+ @param data
+ @param crit
+ @return Pointer to found object on success, NULL otherwise.
+ */
+ T *
+ findLike(void const *data, int crit);
+
+ /** Step to next element.
+ @return Pointe to next object (if there is one), NULL
+ if there is no next object.
+ */
+ T *
+ next(void);
+
+
+
+ }; /* End of class Container */
+
+ /** An iterator class to traverse a Containter.
+ */
+ template<class T>
+ class Iterator
+ {
+ private:
+ /** Low-level iterator.
+ */
+ dk4_sto_it_t *it;
+
+ public:
+ /** Constructor.
+ @param cont Container for which the iterator is for.
+ */
+ Iterator<T>(Container<T>& cont) throw (std::bad_alloc);
+
+ /** Destructor.
+ */
+ ~Iterator<T>();
+
+ /** Reset iterator.
+ */
+ void
+ reset(void);
+
+ /** Set iterator to exact position.
+ @param data
+ @param crit
+ @return Pointer to found object on success, NULL otherwise.
+ */
+ T *
+ findExact(void const *data, int crit);
+
+ /** Set iterator to object evaluating equally.
+ @param data
+ @param crit
+ @return Pointer to found object on success, NULL otherwise.
+ */
+ T *
+ findLike(void const *data, int crit);
+
+ /** Step to next element.
+ @return Pointe to next object (if there is one), NULL
+ if there is no next object.
+ */
+ T *
+ next(void);
+
+ }; /* End of class Iterator */
+
+
+} /* End of namespace DkTools4 */
+
+
+
+/* ************************************************************************ */
+/* * * */
+/* * Implementation for container methods. * */
+/* * * */
+/* ************************************************************************ */
+
+
+#line 173 "Dk4Container.cpt"
+
+template<class T>
+DkTools4::Container<T>::Container(int crit, bool owner) throw (std::bad_alloc)
+{
+ bool mustThrow = true;
+
+ bOwner = owner;
+ cr = crit;
+ it = NULL;
+ sto = dk4sto_open(NULL);
+ if(NULL != sto) {
+ dk4sto_set_comp(sto,DkTools4::Comparable::compareTwoPointers,crit);
+ it = dk4sto_it_open(sto, NULL);
+ if (NULL != it) {
+ mustThrow = false;
+ } else {
+ dk4sto_close(sto);
+ sto = NULL;
+ }
+ }
+ if (mustThrow) {
+ throw(std::bad_alloc());
+ }
+}
+
+
+
+/* The destructor is also called when an exception is thrown by
+ the constructor. So we must check the sto and it component for
+ being not NULL.
+*/
+
+template<class T>
+DkTools4::Container<T>::~Container<T>()
+{
+ T *ptr;
+
+ if (NULL != it) {
+ if (bOwner) {
+ dk4sto_it_reset(it);
+ while(NULL != (ptr = (T *)dk4sto_it_next(it))) {
+ delete ptr;
+ }
+ }
+ dk4sto_it_close(it);
+ }
+ if (NULL != sto) {
+ dk4sto_close(sto);
+ }
+ sto = NULL;
+ it = NULL;
+ cr = 0;
+ bOwner = false;
+}
+
+
+
+/* The remaining container methods are not called if there was
+ an exception from the constructor. So no NULL pointer checks
+ are necessary here.
+*/
+
+
+template<class T>
+bool
+DkTools4::Container<T>::add(T *ptr)
+{
+ bool back = false;
+ if(0 != dk4sto_add(sto, (void *)ptr, NULL)) {
+ back = true;
+ }
+ return back;
+}
+
+
+
+template<class T>
+bool
+DkTools4::Container<T>::remove(T *ptr)
+{
+ bool back = false;
+ if(0 != dk4sto_remove(sto, (void *)ptr, NULL)) {
+ back = true;
+ }
+ return back;
+}
+
+
+
+template<class T>
+void
+DkTools4::Container<T>::isOwner(void) const
+{
+ return bOwner;
+}
+
+
+
+/* The remaining iterator methods are not invoked if the constructor
+ throws an exception, so we do not need to check the it component.
+*/
+
+template<class T>
+void
+DkTools4::Container<T>::reset(void)
+{
+ dk4sto_it_reset(it);
+}
+
+
+
+template<class T>
+T *
+DkTools4::Container<T>::findExact(void const *data, int crit)
+{
+ T *back = NULL;
+ back = (T *)dk4sto_it_find_exact(it, data);
+ return back;
+}
+
+
+
+template<class T>
+T *
+DkTools4::Container<T>::findLike(void const *data, int crit)
+{
+ T *back;
+ back = (T *)dk4sto_it_find_like(it, data, crit);
+ return back;
+}
+
+
+
+template<class T>
+T *
+DkTools4::Container<T>::next(void)
+{
+ T *back = NULL;
+ back = (T *)dk4sto_it_next(it);
+ return back;
+}
+
+
+
+/* ************************************************************************ */
+/* * * */
+/* * Implementation for iterator methods. * */
+/* * * */
+/* ************************************************************************ */
+
+
+#line 320 "Dk4Container.cpt"
+
+template<class T>
+DkTools4::Iterator<T>::Iterator(Container<T>& cont) throw (std::bad_alloc)
+{
+ it = dk4sto_it_open(cont.sto, NULL);
+ if(NULL != it) {
+ dk4sto_it_reset(it);
+ } else {
+ throw(std::bad_alloc());
+ }
+}
+
+
+
+/* The iterators destructor is also invoked if the constructor throws
+ an exception. So we must check the it component to be not NULL.
+*/
+
+template<class T>
+DkTools4::Iterator<T>::~Iterator<T>()
+{
+ if (NULL != it) {
+ dk4sto_it_close(it); it = NULL;
+ }
+}
+
+
+
+/* The remaining iterator methods are not invoked if the constructor
+ throws an exception, so we do not need to check the it component.
+*/
+
+template<class T>
+void
+DkTools4::Iterator<T>::reset(void)
+{
+ dk4sto_it_reset(it);
+}
+
+
+
+template<class T>
+T *
+DkTools4::Iterator<T>::findExact(void const *data, int crit)
+{
+ T *back = NULL;
+ back = (T *)dk4sto_it_find_exact(it, data);
+ return back;
+}
+
+
+
+template<class T>
+T *
+DkTools4::Iterator<T>::findLike(void const *data, int crit)
+{
+ T *back;
+ back = (T *)dk4sto_it_find_like(it, data, crit);
+ return back;
+}
+
+
+
+template<class T>
+T *
+DkTools4::Iterator<T>::next(void)
+{
+ T *back = NULL;
+ back = (T *)dk4sto_it_next(it);
+ return back;
+}
+
+
+#endif
diff --git a/support/dktools/Dk4FcsApp.cpp b/support/dktools/Dk4FcsApp.cpp
new file mode 100644
index 0000000000..b92af6f0a3
--- /dev/null
+++ b/support/dktools/Dk4FcsApp.cpp
@@ -0,0 +1,425 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: Dk4FcsApp.cpt
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file Dk4FcsApp.cpp The Dk4FcsApp module.
+*/
+
+
+#line 63 "Dk4FcsApp.cpt"
+
+#include "wxdkfcs.h"
+
+
+
+
+
+#line 69 "Dk4FcsApp.cpt"
+
+
+
+/** Localized wxChar texts.
+*/
+static wxChar const * wxdkfcs_texts[] = {
+/* 0 */
+wxT("File"),
+
+/* 1 */
+wxT("Quit"),
+
+/* 2 */
+wxT("Exit the application"),
+
+/* 3 */
+wxT("Help"),
+
+/* 4 */
+wxT("About"),
+
+/* 5 */
+wxT("Show version information"),
+
+/* 6 */
+wxT("Contents"),
+
+/* 7 */
+wxT("Open table of contents"),
+
+/* 8 */
+wxT("Ready"),
+
+/* 9 */
+wxT("Copyright (c) "),
+
+/* 10 */
+wxT("About "),
+
+/* 11 */
+wxT("This program uses the following libraries:"),
+
+/* 12 */
+wxT("See:"),
+
+/* 13 */
+wxT("File:"),
+
+/* 14 */
+wxT("MD5"),
+
+/* 15 */
+wxT("RIPEMD-160"),
+
+/* 16 */
+wxT("SHA-1"),
+
+/* 17 */
+wxT("SHA-224"),
+
+/* 18 */
+wxT("SHA-256"),
+
+/* 19 */
+wxT("SHA-384"),
+
+/* 20 */
+wxT("SHA-512"),
+
+/* 21 */
+wxT("Checksum"),
+
+/* 22 */
+wxT("Choose a file"),
+
+/* 23 */
+wxT("Open"),
+
+/* 24 */
+wxT("Open a file"),
+
+NULL
+
+
+#line 156 "Dk4FcsApp.cpt"
+};
+
+
+
+/** Non-localized wxChar texts.
+*/
+static wxChar const * wxdkfcs_nl_wx[] = {
+/* 0 */
+wxT("wxdkfcs"),
+
+/* 1 */
+wxT("4.0.0"),
+
+/* 2 */
+wxT("Dirk Krause"),
+
+/* 3 */
+wxT("DKrause"),
+
+/* 4 */
+wxT("aaaaa"),
+
+/* 5 */
+wxT(""),
+
+/* 6 */
+wxT(""),
+
+/* 7 */
+wxT(" "),
+
+/* 8 */
+wxT("\n"),
+
+/* 9 */
+wxT("DK tools, wxWidgets, OpenSSL, libpng, libjpeg, libtiff, zlib."),
+
+/* 10 */
+wxT("http://dktools.sourceforge.net"),
+
+/* 11 */
+wxT("http://www.wxwidgets.org"),
+
+/* 12 */
+wxT("http://www.openssl.org"),
+
+/* 13 */
+wxT("http://www.libpng.org/pub/png/libpng.html"),
+
+/* 14 */
+wxT("http://www.ijg.org"),
+
+/* 15 */
+wxT("http://www.remotesensing.org/libtiff"),
+
+/* 16 */
+wxT("http://www.zlib.net"),
+
+/* 17 */
+wxT("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"),
+
+/* 18 */
+wxT("This product includes software developed by the OpenSSL Project for use in"),
+
+/* 19 */
+wxT("the OpenSSL Toolkit (http://www.openssl.org/)."),
+
+/* 20 */
+wxT("This product includes cryptographic software written by"),
+
+/* 21 */
+wxT("Eric Young (eay@cryptsoft.com)."),
+
+/* 22 */
+wxT("This product includes software written by Tim Hudson (tjh@cryptsoft.com)."),
+
+/* 23 */
+wxT("Error"),
+
+/* 24 */
+wxT("Not enough memory (RAM)!"),
+
+NULL
+
+
+#line 229 "Dk4FcsApp.cpt"
+};
+
+
+
+/** Non-localized dkChar texts.
+*/
+static dkChar const * wxdkfcs_nl_dk[] = {
+/* 0 */
+dkT("dktools"),
+
+/* 1 */
+dkT("wxdkfcs.str"),
+
+/* 2 */
+dkT("wxdkfcs.chm"),
+
+/* 3 */
+dkT("wxdkfcs.htb"),
+
+NULL
+
+
+#line 254 "Dk4FcsApp.cpt"
+};
+
+
+
+/** Implementation of the wxApp functionality.
+*/
+IMPLEMENT_APP(Dk4FcsApp)
+
+
+bool
+Dk4FcsApp::OnInit()
+{
+ Dk4FcsFrame *frame = NULL;
+ wxChar const * const *localizedTexts = NULL;
+ wxPNGHandler *phPng = NULL;
+ wxXPMHandler *phXpm = NULL;
+ wxICOHandler *phIco = NULL;
+ wxArchiveFSHandler *phArchiveFs = NULL;
+ bool back = false;
+
+
+
+#line 275 "Dk4FcsApp.cpt"
+ /* Initialize members. */
+ pAh = NULL;
+ pHc = NULL;
+
+ /* Initialize further members here.
+ */
+
+ /* Set up helper object. */
+ pAh = new Dk4WxApplicationHelper();
+ if (NULL == pAh) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ if (!(pAh->Initialize(argv[0], wxdkfcs_nl_wx[3], wxdkfcs_nl_dk[0])))
+ {
+ goto finished;
+ }
+
+
+#line 293 "Dk4FcsApp.cpt"
+
+ /* Add image and file system handlers for online help. */
+ phPng = new wxPNGHandler();
+ if (NULL != phPng) {
+ wxImage::AddHandler(phPng);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phXpm = new wxXPMHandler();
+ if (NULL != phXpm) {
+ wxImage::AddHandler(phXpm);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phIco = new wxICOHandler();
+ if (NULL != phIco) {
+ wxImage::AddHandler(phIco);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+
+#line 317 "Dk4FcsApp.cpt"
+ phArchiveFs = new wxArchiveFSHandler();
+ if (NULL != phArchiveFs) {
+ wxFileSystem::AddHandler(phArchiveFs);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ pHc = new Dk4WxHelpController();
+ if (NULL == pHc) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ if (!(pHc->Initialize(pAh, wxdkfcs_nl_dk[2], wxdkfcs_nl_dk[3])))
+ {
+ goto finished;
+ }
+
+
+#line 335 "Dk4FcsApp.cpt"
+
+ localizedTexts = pAh->GetStringTable(wxdkfcs_nl_dk[1], wxdkfcs_texts);
+ if(!(localizedTexts)) { localizedTexts = wxdkfcs_texts; }
+
+
+
+#line 340 "Dk4FcsApp.cpt"
+ /* Create and show frame. */
+ frame = new Dk4FcsFrame(
+ Dk4FcsFrame_MainWindow,
+ pAh,
+ pHc,
+ argc,
+ argv,
+ localizedTexts,
+ wxdkfcs_nl_wx,
+ wxdkfcs_nl_dk
+ );
+ if(!(frame)) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+
+
+#line 357 "Dk4FcsApp.cpt"
+ frame->Show();
+ frame->RestorePosition();
+
+
+#line 360 "Dk4FcsApp.cpt"
+ back = true;
+
+ /* Release resources if initialization failed. */
+ finished:
+ if(!(back)) {
+
+#line 365 "Dk4FcsApp.cpt"
+ if (NULL != pHc) {
+ pHc->Cleanup(); delete(pHc); pHc = NULL;
+ }
+ if (NULL != pAh) {
+ pAh->Cleanup(); delete(pAh); pAh = NULL;
+ }
+ }
+
+
+#line 373 "Dk4FcsApp.cpt"
+ return back;
+}
+
+
+
+int
+Dk4FcsApp::OnExit()
+{
+ int back = 0;
+
+ /* Release resources allocated by further members.
+ */
+
+ /* Release resources. */
+ if (NULL != pHc) {
+ pHc->Cleanup(); delete(pHc); pHc = NULL;
+ }
+ if (NULL != pAh) {
+ pAh->Cleanup(); delete(pAh); pAh = NULL;
+ }
+
+ /* Set back to exit status code.
+ */
+ return back;
+}
+
+
+void
+Dk4FcsApp::ShowMemoryErrorMessage(void)
+{
+ const wxChar *s_title = NULL;
+ const wxChar *s_text = NULL;
+
+ if (NULL != pAh) {
+ s_title = pAh->GetBasicString(6);
+ s_text = pAh->GetBasicString(7);
+ }
+ if (NULL == s_title) {
+ s_title = wxdkfcs_nl_wx[23];
+ }
+ if (NULL == s_text) {
+ s_text = wxdkfcs_nl_wx[24];
+ }
+ wxMessageBox(s_text, s_title, (wxOK | wxCENTRE | wxICON_ERROR));
+}
+
diff --git a/support/dktools/Dk4FcsApp.cpt b/support/dktools/Dk4FcsApp.cpt
new file mode 100644
index 0000000000..a1fc98f48e
--- /dev/null
+++ b/support/dktools/Dk4FcsApp.cpt
@@ -0,0 +1,418 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file Dk4FcsApp.h The Dk4FcsApp class.
+*/
+
+
+
+/** Application class, derived from wxApp, one instance per program.
+*/
+class Dk4FcsApp : public wxApp
+{
+ protected:
+
+ /** Helper object.
+ */
+ Dk4WxApplicationHelper *pAh;
+
+ /** Controller fr online help.
+ */
+ Dk4WxHelpController *pHc;
+
+ protected:
+
+ /** Show error message if not sufficient memory available.
+ */
+ void
+ ShowMemoryErrorMessage(void);
+
+ public:
+
+ /** Application initialization.
+ @return true on success, false on error.
+ */
+ virtual
+ bool
+ OnInit();
+
+ /** Application shutdown.
+ @return 0 on success, any other value indicates an error.
+ */
+ virtual
+ int
+ OnExit();
+};
+
+
+
+/** Declaration as the wxApp object.
+*/
+DECLARE_APP(Dk4FcsApp)
+
+
+
+%% module
+
+#include "wxdkfcs.h"
+
+
+
+$!trace-include
+
+
+
+/** Localized wxChar texts.
+*/
+static wxChar const * wxdkfcs_texts[] = {
+$!string-table macro=wxT
+#
+# 0: Menu "File"
+#
+File
+#
+# 1: Menu item "File/Exit"
+#
+Quit
+#
+# 2: Tool tip text for menu item "File/Exit"
+#
+Exit the application
+#
+# 3: Menu "Help"
+#
+Help
+#
+# 4: Menu item "Help/About"
+#
+About
+#
+# 5: Tooltip text for menu item "Help/About"
+#
+Show version information
+#
+# 6: Menu item "Help/Contents"
+#
+Contents
+#
+# 7: Tooltip text for menu item "Help/Contents"
+#
+Open table of contents
+#
+# 8: Initial status text
+#
+Ready
+#
+# 9: Copyright notice.
+#
+Copyright (c)
+#
+# 10: Dialog box title "About ..."
+#
+About
+#
+# 11: This program uses the following libraries
+#
+This program uses the following libraries:
+#
+# 12: See
+#
+See:
+#
+# 13: __CHANGE__ 015: Text for dummy label, can be reused if lDummy removed.
+#
+File:
+#
+# 14 ... 20: Label MD5
+#
+MD5
+RIPEMD-160
+SHA-1
+SHA-224
+SHA-256
+SHA-384
+SHA-512
+#
+# 21: Column head
+#
+Checksum
+#
+# 22: wxFileDialog header line
+#
+Choose a file
+#
+# 23 24: Menu item File/Open
+#
+Open
+Open a file
+$!end
+};
+
+
+
+/** Non-localized wxChar texts.
+*/
+static wxChar const * wxdkfcs_nl_wx[] = {
+$!string-table macro=wxT
+#
+# 0: Program name.
+#
+wxdkfcs
+#
+# 1: Program version.
+#
+4.0.0
+#
+# 2: Copyright owner name.
+#
+Dirk Krause
+#
+# 3: Software vendor name.
+#
+DKrause
+#
+# 4: Resource name of Windows icon
+#
+aaaaa
+#
+# 5: Empty string to reset table cells
+#
+
+#
+# 6: UNUSED (previously non-Windows htb help file name)
+#
+
+#
+# 7: Space
+#
+
+#
+# 8: Newline
+#
+\n
+#
+# 9 10 11 12 13 14 15 16: List of libraries used.
+#
+DK tools, wxWidgets, OpenSSL, libpng, libjpeg, libtiff, zlib.
+http://dktools.sourceforge.net
+http://www.wxwidgets.org
+http://www.openssl.org
+http://www.libpng.org/pub/png/libpng.html
+http://www.ijg.org
+http://www.remotesensing.org/libtiff
+http://www.zlib.net
+#
+# 17 Default string for values.
+#
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+#
+# 18 - 22 OpenSSL license text.
+#
+This product includes software developed by the OpenSSL Project for use in
+the OpenSSL Toolkit (http://www.openssl.org/).
+This product includes cryptographic software written by
+Eric Young (eay@cryptsoft.com).
+This product includes software written by Tim Hudson (tjh@cryptsoft.com).
+#
+# 23 24
+#
+Error
+Not enough memory (RAM)!
+$!end
+};
+
+
+
+/** Non-localized dkChar texts.
+*/
+static dkChar const * wxdkfcs_nl_dk[] = {
+$!string-table macro=dkT
+#
+# 0: Program group name.
+#
+dktools
+#
+# 1: String table name.
+#
+wxdkfcs.str
+#
+# 2: CHM help file name
+#
+wxdkfcs.chm
+#
+# 3: HTB help file name
+#
+wxdkfcs.htb
+$!end
+};
+
+
+
+/** Implementation of the wxApp functionality.
+*/
+IMPLEMENT_APP(Dk4FcsApp)
+
+
+bool
+Dk4FcsApp::OnInit()
+{
+ Dk4FcsFrame *frame = NULL;
+ wxChar const * const *localizedTexts = NULL;
+ wxPNGHandler *phPng = NULL;
+ wxXPMHandler *phXpm = NULL;
+ wxICOHandler *phIco = NULL;
+ wxArchiveFSHandler *phArchiveFs = NULL;
+ bool back = false;
+
+ $? "+ OnInit"
+ /* Initialize members. */
+ pAh = NULL;
+ pHc = NULL;
+
+ /* Initialize further members here.
+ */
+
+ /* Set up helper object. */
+ pAh = new Dk4WxApplicationHelper();
+ if (NULL == pAh) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ if (!(pAh->Initialize(argv[0], wxdkfcs_nl_wx[3], wxdkfcs_nl_dk[0])))
+ {
+ goto finished;
+ }
+ $? ". app helper ok"
+
+ /* Add image and file system handlers for online help. */
+ phPng = new wxPNGHandler();
+ if (NULL != phPng) {
+ wxImage::AddHandler(phPng);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phXpm = new wxXPMHandler();
+ if (NULL != phXpm) {
+ wxImage::AddHandler(phXpm);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phIco = new wxICOHandler();
+ if (NULL != phIco) {
+ wxImage::AddHandler(phIco);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ $? ". image handlers ok"
+ phArchiveFs = new wxArchiveFSHandler();
+ if (NULL != phArchiveFs) {
+ wxFileSystem::AddHandler(phArchiveFs);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ pHc = new Dk4WxHelpController();
+ if (NULL == pHc) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ if (!(pHc->Initialize(pAh, wxdkfcs_nl_dk[2], wxdkfcs_nl_dk[3])))
+ {
+ goto finished;
+ }
+ $? ". help controller ok"
+
+ localizedTexts = pAh->GetStringTable(wxdkfcs_nl_dk[1], wxdkfcs_texts);
+ if(!(localizedTexts)) { localizedTexts = wxdkfcs_texts; }
+
+ $? ". localized texts ok"
+ /* Create and show frame. */
+ frame = new Dk4FcsFrame(
+ Dk4FcsFrame_MainWindow,
+ pAh,
+ pHc,
+ argc,
+ argv,
+ localizedTexts,
+ wxdkfcs_nl_wx,
+ wxdkfcs_nl_dk
+ );
+ if(!(frame)) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ $? ". frame created"
+ frame->Show();
+ frame->RestorePosition();
+ $? ". frame shown"
+ back = true;
+
+ /* Release resources if initialization failed. */
+ finished:
+ if(!(back)) { $? "! errors, clean up"
+ if (NULL != pHc) {
+ pHc->Cleanup(); delete(pHc); pHc = NULL;
+ }
+ if (NULL != pAh) {
+ pAh->Cleanup(); delete(pAh); pAh = NULL;
+ }
+ }
+ $? "- OnInit %d", (int)back
+ return back;
+}
+
+
+
+int
+Dk4FcsApp::OnExit()
+{
+ int back = 0;
+
+ /* Release resources allocated by further members.
+ */
+
+ /* Release resources. */
+ if (NULL != pHc) {
+ pHc->Cleanup(); delete(pHc); pHc = NULL;
+ }
+ if (NULL != pAh) {
+ pAh->Cleanup(); delete(pAh); pAh = NULL;
+ }
+
+ /* Set back to exit status code.
+ */
+ return back;
+}
+
+
+void
+Dk4FcsApp::ShowMemoryErrorMessage(void)
+{
+ const wxChar *s_title = NULL;
+ const wxChar *s_text = NULL;
+
+ if (NULL != pAh) {
+ s_title = pAh->GetBasicString(6);
+ s_text = pAh->GetBasicString(7);
+ }
+ if (NULL == s_title) {
+ s_title = wxdkfcs_nl_wx[23];
+ }
+ if (NULL == s_text) {
+ s_text = wxdkfcs_nl_wx[24];
+ }
+ wxMessageBox(s_text, s_title, (wxOK | wxCENTRE | wxICON_ERROR));
+}
+
diff --git a/support/dktools/Dk4FcsApp.h b/support/dktools/Dk4FcsApp.h
new file mode 100644
index 0000000000..f3b83d9f7f
--- /dev/null
+++ b/support/dktools/Dk4FcsApp.h
@@ -0,0 +1,95 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: Dk4FcsApp.cpt
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4FCSAPP_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4FCSAPP_H_INCLUDED 1
+
+
+#line 10 "Dk4FcsApp.cpt"
+
+/** @file Dk4FcsApp.h The Dk4FcsApp class.
+*/
+
+
+
+/** Application class, derived from wxApp, one instance per program.
+*/
+class Dk4FcsApp : public wxApp
+{
+ protected:
+
+ /** Helper object.
+ */
+ Dk4WxApplicationHelper *pAh;
+
+ /** Controller fr online help.
+ */
+ Dk4WxHelpController *pHc;
+
+ protected:
+
+ /** Show error message if not sufficient memory available.
+ */
+ void
+ ShowMemoryErrorMessage(void);
+
+ public:
+
+ /** Application initialization.
+ @return true on success, false on error.
+ */
+ virtual
+ bool
+ OnInit();
+
+ /** Application shutdown.
+ @return 0 on success, any other value indicates an error.
+ */
+ virtual
+ int
+ OnExit();
+};
+
+
+
+/** Declaration as the wxApp object.
+*/
+DECLARE_APP(Dk4FcsApp)
+
+
+
+
+#endif
diff --git a/support/dktools/Dk4FcsFrame.cpp b/support/dktools/Dk4FcsFrame.cpp
new file mode 100644
index 0000000000..9ece3feffb
--- /dev/null
+++ b/support/dktools/Dk4FcsFrame.cpp
@@ -0,0 +1,1122 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: Dk4FcsFrame.wxc
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file Dk4FcsFrame.cpp The Dk4FcsFrame module.
+*/
+
+
+#line 246 "Dk4FcsFrame.wxc"
+
+#include "wxdkfcs.h"
+
+#include "dk4mem.h"
+
+#include "dk4verswx.h"
+
+
+#if DK4_HAVE_OPENSSL_MD5_H
+#ifndef OPENSSL_MD5_H_INCLUDED
+#include <openssl/md5.h>
+#define OPENSSL_MD5_H_INCLUDED 1
+#endif
+#endif
+#if DK4_HAVE_OPENSSL_RIPEMD_H
+#ifndef OPENSSL_RIPEMD_H_INCLUDED
+#include <openssl/ripemd.h>
+#define OPENSSL_RIPEMD_H_INCLUDED 1
+#endif
+#endif
+#if DK4_HAVE_OPENSSL_SHA_H
+#ifndef OPENSSL_SHA_H_INCLUDED
+#include <openssl/sha.h>
+#define OPENSSL_SHA_H_INCLUDED 1
+#endif
+#endif
+
+#if !defined(__WXMSW__)
+#include "dkicon.xpm"
+#endif
+
+
+
+
+
+#line 280 "Dk4FcsFrame.wxc"
+
+
+
+BEGIN_EVENT_TABLE(Dk4FcsFrame, wxFrame)
+ EVT_MENU(Dk4FcsFrame_Quit, Dk4FcsFrame::OnQuit)
+ EVT_MENU(Dk4FcsFrame_Open, Dk4FcsFrame::OnOpen)
+ EVT_MENU(Dk4FcsFrame_Help_About, Dk4FcsFrame::OnAbout)
+ EVT_MENU(Dk4FcsFrame_Help_Contents, Dk4FcsFrame::OnHelpContents)
+ EVT_IDLE(Dk4FcsFrame::OnIdle)
+END_EVENT_TABLE()
+
+
+
+typedef struct {
+/*
+ Message digests contexts.
+*/
+#if DK4_HAVE_OPENSSL_MD5_H
+ MD5_CTX md5; /**< MD5 context. */
+#endif
+#if DK4_HAVE_OPENSSL_RIPEMD_H
+ RIPEMD160_CTX ripemd160; /**< RIPEMD-160 context. */
+#endif
+#if DK4_HAVE_OPENSSL_SHA_H
+ SHA_CTX sha; /**< SHA-1 context. */
+#if DK4_HAVE_SHA224
+ SHA256_CTX sha224; /**< SHA-224 context. */
+#endif
+#if DK4_HAVE_SHA256
+ SHA256_CTX sha256; /**< SHA-256 context. */
+#endif
+#if DK4_HAVE_SHA384
+ SHA512_CTX sha384; /**< SHA-384 context. */
+#endif
+#if DK4_HAVE_SHA512
+ SHA512_CTX sha512; /**< SHA-512 context. */
+#endif
+#endif
+ int iMd5; /**< Flag: Can use Md5. */
+ int iRipemd160; /**< Flag: Can use RIPEMD-160. */
+ int iSha1; /**< Flag: Can use SHA-1. */
+ int iSha224; /**< Flag: Can use SHA-224. */
+ int iSha256; /**< Flag: Can use SHA-256. */
+ int iSha384; /**< Flag: Can use SHA-384. */
+ int iSha512; /**< Flag: Can use SHA-512. */
+} MULTI_CTX;
+
+
+
+static const wxChar dk4fcs_frame_version[] = { DKT_VERSION_WX };
+
+
+
+static
+void
+multi_ctx_init(MULTI_CTX *mptr)
+{
+
+
+#line 338 "Dk4FcsFrame.wxc"
+ DK4_MEMRES(mptr, sizeof(MULTI_CTX));
+#if DK4_HAVE_OPENSSL_MD5_H
+ if (1 == MD5_Init(&(mptr->md5))) {
+ mptr->iMd5 = 1;
+
+#line 342 "Dk4FcsFrame.wxc"
+ }
+#endif
+#if DK4_HAVE_OPENSSL_RIPEMD_H
+ if (1 == RIPEMD160_Init(&(mptr->ripemd160))) {
+ mptr->iRipemd160 = 1;
+
+#line 347 "Dk4FcsFrame.wxc"
+ }
+#endif
+#if DK4_HAVE_OPENSSL_SHA_H
+ if (1 == SHA1_Init(&(mptr->sha))) {
+ mptr->iSha1 = 1;
+
+#line 352 "Dk4FcsFrame.wxc"
+ }
+#if DK4_HAVE_SHA224
+ if (1 == SHA224_Init(&(mptr->sha224))) {
+ mptr->iSha224 = 1;
+
+#line 356 "Dk4FcsFrame.wxc"
+ }
+#endif
+#if DK4_HAVE_SHA256
+ if (1 == SHA256_Init(&(mptr->sha256))) {
+ mptr->iSha256 = 1;
+
+#line 361 "Dk4FcsFrame.wxc"
+ }
+#endif
+#if DK4_HAVE_SHA384
+ if (1 == SHA384_Init(&(mptr->sha384))) {
+ mptr->iSha384 = 1;
+
+#line 366 "Dk4FcsFrame.wxc"
+ }
+#endif
+#if DK4_HAVE_SHA512
+ if (1 == SHA512_Init(&(mptr->sha512))) {
+ mptr->iSha512 = 1;
+
+#line 371 "Dk4FcsFrame.wxc"
+ }
+#endif
+#endif
+
+
+#line 375 "Dk4FcsFrame.wxc"
+}
+
+
+
+static
+void
+multi_ctx_add(MULTI_CTX *mptr, void *buffer, size_t sz)
+{
+
+
+#line 384 "Dk4FcsFrame.wxc"
+#if DK4_HAVE_OPENSSL_MD5_H
+ if (1 != MD5_Update(&(mptr->md5), buffer, (unsigned long)sz)) {
+ mptr->iMd5 = 0;
+
+#line 387 "Dk4FcsFrame.wxc"
+ }
+#endif
+#if DK4_HAVE_OPENSSL_RIPEMD_H
+ if (1 != RIPEMD160_Update(&(mptr->ripemd160), buffer, (unsigned long)sz)) {
+ mptr->iRipemd160 = 0;
+
+#line 392 "Dk4FcsFrame.wxc"
+ }
+#endif
+#if DK4_HAVE_OPENSSL_SHA_H
+ if (1 != SHA1_Update(&(mptr->sha), buffer, (unsigned long)sz)) {
+ mptr->iSha1 = 0;
+
+#line 397 "Dk4FcsFrame.wxc"
+ }
+#if DK4_HAVE_SHA224
+ if (1 != SHA224_Update(&(mptr->sha224), buffer, (unsigned long)sz)) {
+ mptr->iSha224 = 0;
+
+#line 401 "Dk4FcsFrame.wxc"
+ }
+#endif
+#if DK4_HAVE_SHA256
+ if (1 != SHA256_Update(&(mptr->sha256), buffer, (unsigned long)sz)) {
+ mptr->iSha256 = 0;
+
+#line 406 "Dk4FcsFrame.wxc"
+ }
+#endif
+#if DK4_HAVE_SHA384
+ if (1 != SHA384_Update(&(mptr->sha384), buffer, (unsigned long)sz)) {
+ mptr->iSha384 = 0;
+
+#line 411 "Dk4FcsFrame.wxc"
+ }
+#endif
+#if DK4_HAVE_SHA512
+ if (1 != SHA512_Update(&(mptr->sha512), buffer, (unsigned long)sz)) {
+ mptr->iSha512 = 0;
+
+#line 416 "Dk4FcsFrame.wxc"
+ }
+#endif
+#endif
+
+
+#line 420 "Dk4FcsFrame.wxc"
+}
+
+
+
+/** Thread runs while progress dialog is shown.
+ This is a ``fire and forget'' thread destroying itself after running.
+*/
+class Dk4FcsThread : public wxThread
+{
+ protected:
+
+ /** Buffer for reading input file.
+ */
+ unsigned char buf[4096];
+
+ /** Progress dialog.
+ */
+ Dk4WxProgressDialog *pPd;
+
+ /** Multiple message digest contexts.
+ */
+ MULTI_CTX *pCtx;
+
+ /** File to read from.
+ */
+ wxFile *pWxf;
+
+ public:
+
+ /** Constructor.
+ @param pd Pointer to progress dialog.
+ @param ctx Pointer to multiple digest contexts collection.
+ @param wxf Pointer to file we read from.
+ */
+ Dk4FcsThread(
+ Dk4WxProgressDialog *pd,
+ MULTI_CTX *ctx,
+ wxFile *wxf
+ );
+
+ /** Thread function.
+ @return Pointer which is ignored.
+ */
+ virtual
+ void *
+ Entry();
+
+ /** Method executed at end of thread.
+ */
+ virtual
+ void
+ OnExit();
+};
+
+
+
+Dk4FcsThread::Dk4FcsThread(
+ Dk4WxProgressDialog *pd,
+ MULTI_CTX *ctx,
+ wxFile *wxf
+)
+{
+
+
+#line 483 "Dk4FcsFrame.wxc"
+ pPd = pd;
+ pCtx = ctx;
+ pWxf = wxf;
+
+
+#line 487 "Dk4FcsFrame.wxc"
+}
+
+
+
+void *
+Dk4FcsThread::Entry()
+{
+ wxFileOffset fileSize = (wxFileOffset)0UL;
+ wxFileOffset bytesRead = (wxFileOffset)0UL;
+ size_t bytes = 0U;
+ int gauge = 0;
+ int ogauge = 0;
+ bool canContinue = true;
+ bool success = true;
+
+
+#line 502 "Dk4FcsFrame.wxc"
+ fileSize = pWxf->Length();
+ while(canContinue) {
+
+#line 504 "Dk4FcsFrame.wxc"
+ if (pPd->CanContinue()) {
+
+#line 505 "Dk4FcsFrame.wxc"
+ bytes = pWxf->Read(buf, sizeof(buf));
+
+
+#line 507 "Dk4FcsFrame.wxc"
+ if (0 < bytes) {
+
+#line 508 "Dk4FcsFrame.wxc"
+ if ((size_t)(wxInvalidOffset) != bytes) {
+
+#line 509 "Dk4FcsFrame.wxc"
+ multi_ctx_add(pCtx, buf, bytes);
+ bytesRead += (wxFileOffset)bytes;
+ if (bytesRead >= fileSize) {
+ gauge = 1000;
+
+#line 513 "Dk4FcsFrame.wxc"
+ } else {
+ gauge = (int)((1000.0 * (double)bytesRead) / ((double)fileSize));
+ if (1000 < gauge) {
+ gauge = 1000;
+
+#line 517 "Dk4FcsFrame.wxc"
+ }
+ }
+ if (gauge != ogauge) {
+
+#line 520 "Dk4FcsFrame.wxc"
+ pPd->SetGauge(gauge);
+ ogauge = gauge;
+ }
+ } else {
+
+#line 524 "Dk4FcsFrame.wxc"
+ canContinue = false;
+ success = false;
+ }
+ } else {
+
+#line 528 "Dk4FcsFrame.wxc"
+ canContinue = false;
+ }
+ } else {
+
+#line 531 "Dk4FcsFrame.wxc"
+ canContinue = false;
+ success = false;
+ }
+
+#line 534 "Dk4FcsFrame.wxc"
+ }
+
+
+#line 536 "Dk4FcsFrame.wxc"
+ pPd->EndProcessing(success);
+
+
+#line 538 "Dk4FcsFrame.wxc"
+ return NULL;
+}
+
+
+
+void
+Dk4FcsThread::OnExit()
+{
+
+
+#line 547 "Dk4FcsFrame.wxc"
+
+
+#line 548 "Dk4FcsFrame.wxc"
+}
+
+
+
+
+#line 553 "Dk4FcsFrame.wxc"
+Dk4FcsFrame::Dk4FcsFrame(
+ int wxid,
+ Dk4WxApplicationHelper *applicationHelper,
+ Dk4WxHelpController *hc,
+ int argc,
+ wxChar **argv,
+ wxChar const * const *localizedTexts,
+ wxChar const * const *nlWx,
+ dkChar const * const *nlDk
+) : Dk4WxFrame(nlWx[0], applicationHelper, hc, wxid)
+{
+
+
+#line 565 "Dk4FcsFrame.wxc"
+ /* Further local variables.
+ */
+
+ /* Initialize further local variables.
+ */
+
+ sTexts = localizedTexts;
+ sNlWx = nlWx;
+ sNlDk = nlDk;
+#if defined(__WXMSW__)
+ wxIcon wxdkfcs_icon(sNlWx[4]);
+#else
+ wxIcon wxdkfcs_icon(xpm_dkicon);
+#endif
+ /* Initialize further class members.
+ */
+ bActive = true;
+ sFileName = wxEmptyString;
+ sDirectory = wxEmptyString;
+ if (1 < argc) {
+ sFileName = argv[1];
+ oAsc.SetAutoStart(true);
+ {
+ wxFileName wxfn(sFileName);
+ sDirectory = wxfn.GetPath();
+ }
+#if 0
+ /* Just to test auto exit.
+ */
+ oAsc.SetAutoExit(true);
+#endif
+ }
+ dkctGUILayoutOK = false;
+ dkctGUIContentsPanel = NULL;
+ mainSizer = NULL;
+ mbMain = NULL;
+ menuFile = NULL;
+ menuHelp = NULL;
+ miFileOpen = NULL;
+ miFileExit = NULL;
+ miHelpAbout = NULL;
+ miHelpContents = NULL;
+ verticalSizer = NULL;
+ contentsSizer = NULL;
+ lFile = NULL;
+ tFile = NULL;
+ gResults = NULL;
+ dkctGUIContentsPanel = new wxPanel(this);
+ if(!(dkctGUIContentsPanel)) {
+ goto dkctGUILayoutFinished;
+ }
+#if wxUSE_MENUS
+ mbMain = new wxMenuBar(
+ );
+ if(!(mbMain)) {
+ goto dkctGUILayoutFinished;
+ }
+ menuFile = new wxMenu(
+ );
+ if(!(menuFile)) {
+ goto dkctGUILayoutFinished;
+ }
+ miFileOpen = menuFile->Append(
+ Dk4FcsFrame_Open,
+ sTexts[23],
+ sTexts[24]
+ );
+ if(!(miFileOpen)) {
+ goto dkctGUILayoutFinished;
+ }
+ miFileExit = menuFile->Append(
+ Dk4FcsFrame_Quit,
+ sTexts[1],
+ sTexts[2]
+ );
+ if(!(miFileExit)) {
+ goto dkctGUILayoutFinished;
+ }
+ mbMain->Append(menuFile, sTexts[0]);
+ menuHelp = new wxMenu(
+ );
+ if(!(menuHelp)) {
+ goto dkctGUILayoutFinished;
+ }
+ miHelpAbout = menuHelp->Append(
+ Dk4FcsFrame_Help_About,
+ sTexts[4],
+ sTexts[5]
+ );
+ if(!(miHelpAbout)) {
+ goto dkctGUILayoutFinished;
+ }
+ miHelpContents = menuHelp->Append(
+ Dk4FcsFrame_Help_Contents,
+ sTexts[6],
+ sTexts[7]
+ );
+ if(!(miHelpContents)) {
+ goto dkctGUILayoutFinished;
+ }
+ mbMain->Append(menuHelp, sTexts[3]);
+ SetMenuBar(mbMain);
+#endif
+ mainSizer = new wxBoxSizer(
+ wxHORIZONTAL
+ );
+ if(!(mainSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ mainSizer->Add(10, 10, 0);
+ verticalSizer = new wxBoxSizer(
+ wxVERTICAL
+ );
+ if(!(verticalSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ verticalSizer->Add(10, 10, 0);
+ contentsSizer = new wxGridBagSizer(
+ 5, 5
+ );
+ if(!(contentsSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ lFile = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[13]
+ );
+ if(!(lFile)) {
+ goto dkctGUILayoutFinished;
+ }
+ contentsSizer->Add(
+ lFile,
+ wxGBPosition(0, 0),
+ wxGBSpan(1, 1),
+ wxALIGN_RIGHT
+ );
+ tFile = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ wxT("")
+ );
+ if(!(tFile)) {
+ goto dkctGUILayoutFinished;
+ }
+ contentsSizer->Add(
+ tFile,
+ wxGBPosition(0, 1),
+ wxGBSpan(1, 1),
+ wxALIGN_LEFT
+ );
+ gResults = new wxGrid(
+ dkctGUIContentsPanel,
+ wxID_ANY
+ );
+ if(!(gResults)) {
+ goto dkctGUILayoutFinished;
+ }
+ gResults->CreateGrid(7, 1);
+ gResults->SetColLabelValue(0, sTexts[21]);
+ gResults->SetRowLabelValue(0, sTexts[14]);
+ gResults->SetRowLabelValue(1, sTexts[15]);
+ gResults->SetRowLabelValue(2, sTexts[16]);
+ gResults->SetRowLabelValue(3, sTexts[17]);
+ gResults->SetRowLabelValue(4, sTexts[18]);
+ gResults->SetRowLabelValue(5, sTexts[19]);
+ gResults->SetRowLabelValue(6, sTexts[20]);
+ gResults->SetCellValue(0, 0, sNlWx[17]);
+ gResults->SetCellValue(1, 0, sNlWx[17]);
+ gResults->SetCellValue(2, 0, sNlWx[17]);
+ gResults->SetCellValue(3, 0, sNlWx[17]);
+ gResults->SetCellValue(4, 0, sNlWx[17]);
+ gResults->SetCellValue(5, 0, sNlWx[17]);
+ gResults->SetCellValue(6, 0, sNlWx[17]);
+ gResults->SetRowLabelSize(wxGRID_AUTOSIZE);
+ gResults->SetColLabelSize(wxGRID_AUTOSIZE);
+ gResults->AutoSize();
+ gResults->EnableEditing(false);
+ gResults->SetMinSize(wxSize(300, 200));
+ contentsSizer->Add(
+ gResults,
+ wxGBPosition(1, 0),
+ wxGBSpan(1, 2),
+ wxALIGN_LEFT|wxGROW
+ );
+ contentsSizer->AddGrowableRow(1);
+ contentsSizer->AddGrowableCol(1);
+ verticalSizer->Add(
+ contentsSizer,
+ 1,
+ wxGROW
+ );
+ verticalSizer->Add(10, 10, 0);
+ mainSizer->Add(
+ verticalSizer,
+ 1,
+ wxGROW
+ );
+ mainSizer->Add(10, 10, 0);
+ dkctGUIContentsPanel->SetSizer(mainSizer);
+ SetIcon(wxdkfcs_icon);
+ dkctGUILayoutOK = true;
+ dkctGUILayoutFinished:
+#if wxUSE_STATUSBAR
+ if(dkctGUILayoutOK) {
+ CreateStatusBar(1);
+ SetStatusText(sTexts[8]);
+ }
+#endif
+ if(dkctGUILayoutOK) {
+ mainSizer->Fit(this);
+ mainSizer->SetSizeHints(this);
+ }
+
+#line 598 "Dk4FcsFrame.wxc"
+ if(dkctGUILayoutOK) {
+ SetTitle(nlWx[0]);
+ if (1 < argc) {
+ tFile->SetLabel(sFileName);
+ }
+#if 0
+ RestorePosition();
+#endif
+ gResults->SetCellValue(0, 0, sNlWx[5]);
+ gResults->SetCellValue(1, 0, sNlWx[5]);
+ gResults->SetCellValue(2, 0, sNlWx[5]);
+ gResults->SetCellValue(3, 0, sNlWx[5]);
+ gResults->SetCellValue(4, 0, sNlWx[5]);
+ gResults->SetCellValue(5, 0, sNlWx[5]);
+ gResults->SetCellValue(6, 0, sNlWx[5]);
+ }
+
+ /* Release resources allocated by local variables.
+ */
+
+
+#line 618 "Dk4FcsFrame.wxc"
+}
+
+
+#line 621 "Dk4FcsFrame.wxc"
+
+
+
+Dk4FcsFrame::~Dk4FcsFrame()
+{
+
+
+#line 627 "Dk4FcsFrame.wxc"
+ /* Release resources allocated by further class members.
+ */
+
+
+#line 630 "Dk4FcsFrame.wxc"
+}
+
+
+
+bool
+Dk4FcsFrame::CanClose(bool isFinal)
+{
+ bool back = true;
+
+
+#line 639 "Dk4FcsFrame.wxc"
+
+
+#line 640 "Dk4FcsFrame.wxc"
+ return back;
+}
+
+
+
+void
+Dk4FcsFrame::OnQuit(wxCommandEvent & event)
+{
+
+
+#line 649 "Dk4FcsFrame.wxc"
+ Close();
+
+
+#line 651 "Dk4FcsFrame.wxc"
+}
+
+
+
+void
+Dk4FcsFrame::OnAbout(wxCommandEvent & event)
+{
+ wxString text(wxT(""));
+ wxString title(wxT(""));
+
+
+#line 661 "Dk4FcsFrame.wxc"
+ /* Construct message text. */
+ text.Append(sNlWx[0]);
+ text.Append(sNlWx[7]);
+ text.Append(dk4fcs_frame_version);
+#if 0
+ text.Append(sNlWx[1]);
+#endif
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[9]);
+ text.Append(sNlWx[2]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[11]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[9]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[12]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[10]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[11]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[12]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[13]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[14]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[15]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[16]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[18]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[19]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[20]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[21]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[22]);
+
+ /* Construct dialog box title. */
+ title.Append(sTexts[10]);
+ title.Append(sNlWx[0]);
+
+ /* Show dialog box. */
+ wxMessageBox(text, title);
+
+
+#line 712 "Dk4FcsFrame.wxc"
+}
+
+
+
+void
+Dk4FcsFrame::OnHelpContents(wxCommandEvent & event)
+{
+
+
+#line 720 "Dk4FcsFrame.wxc"
+ DisplayContents();
+
+
+#line 722 "Dk4FcsFrame.wxc"
+}
+
+
+
+/* __CHANGE__ 017: Event handlers for further events.
+*/
+
+
+
+/** Hexadecimal digits.
+*/
+static const wxChar hexdig[] = { wxT("0123456789abcdef") };
+
+
+
+void
+Dk4FcsFrame::SetCellValueBinary(
+ int rowno,
+ unsigned char *buf,
+ size_t bytes
+)
+{
+ wxChar obuf[144];
+ wxChar *obptr;
+ unsigned short u;
+
+
+#line 748 "Dk4FcsFrame.wxc"
+ if (64 >= bytes) {
+ obptr = obuf;
+ while(bytes--) {
+ u = (unsigned short)(*buf);
+ u = u >> 4;
+ u &= 15;
+ *(obptr++) = hexdig[u];
+
+#line 755 "Dk4FcsFrame.wxc"
+ u = (unsigned short)(*buf);
+ u &= 15;
+ *(obptr++) = hexdig[u];
+
+#line 758 "Dk4FcsFrame.wxc"
+ buf++;
+ }
+ *obptr = wxT('\0');
+ {
+ wxString testString(obuf);
+ gResults->SetCellValue(rowno, 0, testString);
+ }
+ } else {
+ /* ERROR: message digest too long, need larger obuf! */
+ }
+
+
+#line 769 "Dk4FcsFrame.wxc"
+}
+
+
+
+bool
+Dk4FcsFrame::RunChecksumming(void)
+{
+ MULTI_CTX ctx; // Digests contexts collection
+ unsigned char obuf[128]; // Binary message digests
+ Dk4WxProgressDialog *pd = NULL; // Progress dialog
+ Dk4FcsThread *pt = NULL; // Thread
+ int res = 0; // Operation result
+ bool updateTable = false; // Flag: Update the table
+
+
+#line 783 "Dk4FcsFrame.wxc"
+ /* Reset all values.
+ */
+ gResults->BeginBatch();
+ gResults->SetCellValue(0, 0, sNlWx[5]);
+ gResults->SetCellValue(1, 0, sNlWx[5]);
+ gResults->SetCellValue(2, 0, sNlWx[5]);
+ gResults->SetCellValue(3, 0, sNlWx[5]);
+ gResults->SetCellValue(4, 0, sNlWx[5]);
+ gResults->SetCellValue(5, 0, sNlWx[5]);
+ gResults->SetCellValue(6, 0, sNlWx[5]);
+ gResults->EndBatch();
+ gResults->ForceRefresh();
+ Refresh();
+ Update();
+
+ /* Attempt to build checksum.
+ */
+ if (wxFile::Exists(sFileName)) {
+
+#line 801 "Dk4FcsFrame.wxc"
+ {
+ wxFile wxf(sFileName);
+ if (wxf.IsOpened()) {
+
+#line 804 "Dk4FcsFrame.wxc"
+ pd = new Dk4WxProgressDialog(this, pAppHelp);
+ if (NULL != pd) {
+
+#line 806 "Dk4FcsFrame.wxc"
+ pt = new Dk4FcsThread(pd, &ctx, &wxf);
+ if (NULL != pt) {
+
+#line 808 "Dk4FcsFrame.wxc"
+ multi_ctx_init(&ctx);
+ if(wxTHREAD_NO_ERROR == pt->Create()) {
+
+#line 810 "Dk4FcsFrame.wxc"
+ pt->SetPriority(WXTHREAD_DEFAULT_PRIORITY);
+ pt->Run();
+ res = pd->ShowModal();
+ if (wxID_OK == res) {
+
+#line 814 "Dk4FcsFrame.wxc"
+ updateTable = true;
+ } else {
+
+#line 816 "Dk4FcsFrame.wxc"
+ /* !!!!! ERROR: Aborted by user */
+ }
+ } else {
+
+#line 819 "Dk4FcsFrame.wxc"
+ delete(pt);
+ pt = NULL;
+ /* !!!!! ERROR: Failed to create thread */
+ }
+ } else {
+
+#line 824 "Dk4FcsFrame.wxc"
+ /* !!!!! ERROR: No thread */
+ }
+ pd->Destroy();
+ } else {
+
+#line 828 "Dk4FcsFrame.wxc"
+ /* !!!!! ERROR: No progress dialog */
+ }
+ } else {
+
+#line 831 "Dk4FcsFrame.wxc"
+ /* !!!!! ERROR: Failed to open file */
+ }
+ }
+ if (updateTable) {
+
+#line 835 "Dk4FcsFrame.wxc"
+ gResults->BeginBatch();
+#if DK4_HAVE_OPENSSL_MD5_H
+ if (0 != ctx.iMd5) {
+
+#line 838 "Dk4FcsFrame.wxc"
+ if (1 == MD5_Final(obuf, &(ctx.md5))) {
+
+#line 839 "Dk4FcsFrame.wxc"
+ SetCellValueBinary(0, obuf, 16);
+ }
+ }
+#endif
+#if DK4_HAVE_OPENSSL_RIPEMD_H
+ if (0 != ctx.iRipemd160) {
+
+#line 845 "Dk4FcsFrame.wxc"
+ if (1 == RIPEMD160_Final(obuf, &(ctx.ripemd160))) {
+ SetCellValueBinary(1, obuf, 20);
+
+#line 847 "Dk4FcsFrame.wxc"
+ }
+ }
+#endif
+#if DK4_HAVE_OPENSSL_SHA_H
+ if (0 != ctx.iSha1) {
+
+#line 852 "Dk4FcsFrame.wxc"
+ if (1 == SHA1_Final(obuf, &(ctx.sha))) {
+
+#line 853 "Dk4FcsFrame.wxc"
+ SetCellValueBinary(2, obuf, 20);
+ }
+ }
+#if DK4_HAVE_SHA224
+ if (0 != ctx.iSha224) {
+
+#line 858 "Dk4FcsFrame.wxc"
+ if (1 == SHA224_Final(obuf, &(ctx.sha224))) {
+
+#line 859 "Dk4FcsFrame.wxc"
+ SetCellValueBinary(3, obuf, 28);
+ }
+ }
+#endif
+#if DK4_HAVE_SHA256
+ if (0 != ctx.iSha256) {
+
+#line 865 "Dk4FcsFrame.wxc"
+ if (1 == SHA256_Final(obuf, &(ctx.sha256))) {
+
+#line 866 "Dk4FcsFrame.wxc"
+ SetCellValueBinary(4, obuf, 32);
+ }
+ }
+#endif
+#if DK4_HAVE_SHA384
+ if (0 != ctx.iSha384) {
+
+#line 872 "Dk4FcsFrame.wxc"
+ if (1 == SHA384_Final(obuf, &(ctx.sha384))) {
+
+#line 873 "Dk4FcsFrame.wxc"
+ SetCellValueBinary(5, obuf, 48);
+ }
+ }
+#endif
+#if DK4_HAVE_SHA512
+ if (0 != ctx.iSha512) {
+
+#line 879 "Dk4FcsFrame.wxc"
+ if (1 == SHA512_Final(obuf, &(ctx.sha512))) {
+
+#line 880 "Dk4FcsFrame.wxc"
+ SetCellValueBinary(6, obuf, 64);
+ }
+ }
+#endif
+#endif
+ gResults->AutoSize();
+ gResults->EndBatch();
+ gResults->ForceRefresh();
+ {
+ int x, y, w, h;
+ GetPosition(&x, &y);
+ GetSize(&w, &h);
+ mainSizer->Fit(this);
+ SetSize(x, y, w, h);
+ }
+ Refresh();
+ Update();
+ } else {
+
+#line 898 "Dk4FcsFrame.wxc"
+ }
+ } else {
+
+#line 900 "Dk4FcsFrame.wxc"
+ /* !!!!! ERROR: File does not exist */
+ }
+
+
+#line 903 "Dk4FcsFrame.wxc"
+ return updateTable;
+}
+
+
+
+void
+Dk4FcsFrame::OnOpen(wxCommandEvent & event)
+{
+ bool canRun = true;
+ int res = 0;
+
+
+#line 914 "Dk4FcsFrame.wxc"
+ {
+ wxFileDialog dlg(this, sTexts[22], sDirectory);
+ res = dlg.ShowModal();
+ if (wxID_OK == res) {
+ sFileName = dlg.GetPath();
+ tFile->SetLabel(sFileName);
+ {
+ wxFileName wxfn(sFileName);
+ sDirectory = wxfn.GetPath();
+ }
+ canRun = true;
+ } else {
+ canRun = false;
+ }
+ }
+ if (canRun) {
+ (void)RunChecksumming();
+ }
+
+
+#line 933 "Dk4FcsFrame.wxc"
+}
+
+
+
+void
+Dk4FcsFrame::OnIdle(wxIdleEvent & event)
+{
+ bool success = false;
+
+
+#line 942 "Dk4FcsFrame.wxc"
+ if (bActive) {
+ /* event.RequestMore(); */
+ switch (oAsc.GetReaction()) {
+#if 0
+ case DK4WX_AUTOSTART_REACTION_IGNORE : {
+ } break;
+#endif
+ case DK4WX_AUTOSTART_REACTION_START : {
+ oAsc.StartProcessing();
+ success = RunChecksumming();
+ oAsc.EndProcessing(success);
+ } break;
+ case DK4WX_AUTOSTART_REACTION_MORE : {
+ event.RequestMore();
+ } break;
+ case DK4WX_AUTOSTART_REACTION_EXIT : {
+ bActive = false;
+ Close();
+ } break;
+ }
+ }
+ event.Skip();
+
+
+#line 965 "Dk4FcsFrame.wxc"
+}
+
+
diff --git a/support/dktools/Dk4FcsFrame.h b/support/dktools/Dk4FcsFrame.h
new file mode 100644
index 0000000000..4ccc581993
--- /dev/null
+++ b/support/dktools/Dk4FcsFrame.h
@@ -0,0 +1,255 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: Dk4FcsFrame.wxc
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file Dk4FcsFrame.h Header file for the Dk4FcsFrame module.
+*/
+
+#ifndef DK4FCSFRAME_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4FCSFRAME_H_INCLUDED 1
+
+
+#line 112 "Dk4FcsFrame.wxc"
+
+
+
+
+#line 116 "Dk4FcsFrame.wxc"
+class Dk4FcsFrame : public Dk4WxFrame
+{
+ private:
+
+ /** Event table for frame.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ /** Autostart controller.
+ */
+ Dk4WxAutostartController oAsc;
+
+ /** Localized texts.
+ */
+ wxChar const * const *sTexts;
+
+ /** Non-localized texts.
+ */
+ wxChar const * const *sNlWx;
+
+ /** Non-localized texts.
+ */
+ dkChar const * const *sNlDk;
+
+ /** File name to process.
+ */
+ wxString sFileName;
+
+ /** Default directory.
+ */
+ wxString sDirectory;
+
+ /** Flag: Active (responding to idle events).
+ */
+ bool bActive;
+
+ /** Flag: GUI ok.
+ */
+ bool dkctGUILayoutOK;
+
+ /** Contents panel.
+ */
+ wxPanel *dkctGUIContentsPanel;
+
+ /** GUI element mainSizer.
+ */
+#line 57 "Dk4FcsFrame.wxc"
+ wxBoxSizer *mainSizer;
+
+ /** GUI element mbMain.
+ */
+#line 23 "Dk4FcsFrame.wxc"
+ wxMenuBar *mbMain;
+
+ /** GUI element menuFile.
+ */
+#line 27 "Dk4FcsFrame.wxc"
+ wxMenu *menuFile;
+
+ /** GUI element menuHelp.
+ */
+#line 42 "Dk4FcsFrame.wxc"
+ wxMenu *menuHelp;
+
+ /** GUI element miFileOpen.
+ */
+#line 32 "Dk4FcsFrame.wxc"
+ wxMenuItem *miFileOpen;
+
+ /** GUI element miFileExit.
+ */
+#line 37 "Dk4FcsFrame.wxc"
+ wxMenuItem *miFileExit;
+
+ /** GUI element miHelpAbout.
+ */
+#line 47 "Dk4FcsFrame.wxc"
+ wxMenuItem *miHelpAbout;
+
+ /** GUI element miHelpContents.
+ */
+#line 52 "Dk4FcsFrame.wxc"
+ wxMenuItem *miHelpContents;
+
+ /** GUI element verticalSizer.
+ */
+#line 65 "Dk4FcsFrame.wxc"
+ wxBoxSizer *verticalSizer;
+
+ /** GUI element contentsSizer.
+ */
+#line 73 "Dk4FcsFrame.wxc"
+ wxGridBagSizer *contentsSizer;
+
+ /** GUI element lFile.
+ */
+#line 83 "Dk4FcsFrame.wxc"
+ wxStaticText *lFile;
+
+ /** GUI element tFile.
+ */
+#line 86 "Dk4FcsFrame.wxc"
+ wxStaticText *tFile;
+
+ /** GUI element gResults.
+ */
+#line 89 "Dk4FcsFrame.wxc"
+ wxGrid *gResults;
+
+
+#line 155 "Dk4FcsFrame.wxc"
+
+ public:
+
+ /** Constructor.
+ @param wxid Window ID.
+ @param applicationHelper Application helper object.
+ @param hc Help controller for online help.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @param localizedTexts Localized wxChar texts.
+ @param nlWx Non-localized wxChar texts.
+ @param nlDk Non-localized dkChar texts.
+ */
+ Dk4FcsFrame(
+ int wxid,
+ Dk4WxApplicationHelper *applicationHelper,
+ Dk4WxHelpController *hc,
+ int argc,
+ wxChar **argv,
+ wxChar const * const *localizedTexts,
+ wxChar const * const *nlWx,
+ dkChar const * const *nlDk
+ );
+
+ /** Destructor.
+ */
+ ~Dk4FcsFrame();
+
+ /** Check whether we can close the window.
+ @param isFinal Flag: Last main window to close.
+ */
+ bool
+ CanClose(bool isFinal);
+
+ /** Open a file and create checksums for it.
+ @param event Event to process.
+ */
+ void
+ OnOpen(wxCommandEvent & event);
+
+ /** Handler for File/Exit.
+ @param event Event to process.
+ */
+ void
+ OnQuit(wxCommandEvent & event);
+
+ /** Handler for Help/About.
+ @param event Event to process.
+ */
+ void
+ OnAbout(wxCommandEvent & event);
+
+ /** Handler for Help/Contents.
+ @param event Event to process.
+ */
+ void
+ OnHelpContents(wxCommandEvent & event);
+
+ /** Handler for idle events.
+ */
+ void
+ OnIdle(wxIdleEvent & event);
+
+ /* Event handlers for further events.
+ */
+
+ /* Further methods.
+ */
+ private:
+
+ /** Convert binary data to hex notation and set grid cell.
+ @param rowno Row number in table.
+ @param buf Buffer containing binary data.
+ @param bytes Number of bytes in buffer.
+ */
+ void
+ SetCellValueBinary(
+ int rowno,
+ unsigned char *buf,
+ size_t bytes
+ );
+
+ /** Produce checksums.
+ */
+ bool
+ RunChecksumming(void);
+};
+
+
+#line 244 "Dk4FcsFrame.wxc"
+
+
+#endif
diff --git a/support/dktools/Dk4FcsFrame.wxc b/support/dktools/Dk4FcsFrame.wxc
new file mode 100644
index 0000000000..63f1ff147f
--- /dev/null
+++ b/support/dktools/Dk4FcsFrame.wxc
@@ -0,0 +1,967 @@
+%% options
+
+# __CHANGE__ 001: Correct copyright owner if necessary.
+copyright owner = Dirk Krause
+
+# __CHANGE__ 003: Correct copyright year(s) if necessary.
+copyright year = 2015-xxxx
+
+# __CHANGE__ 002: Correct license type if necessary.
+# Use "bsd", "gpl", "lgpl", or "commercial".
+license = bsd
+
+
+
+%% wx-gui
+
+type = frame
+contents = mainSizer
+icon = wxdkfcs_icon
+status bar = 1 sTexts[8]
+menu bar = mbMain
+
+[wxMenuBar mbMain]
+contents = menuFile
+contents = menuHelp
+
+[wxMenu menuFile]
+text = sTexts[0]
+contents = miFileOpen
+contents = miFileExit
+
+[wxMenuItem miFileOpen]
+id = Dk4FcsFrame_Open
+text = sTexts[23]
+tip = sTexts[24]
+
+[wxMenuItem miFileExit]
+id = Dk4FcsFrame_Quit
+text = sTexts[1]
+tip = sTexts[2]
+
+[wxMenu menuHelp]
+text = sTexts[3]
+contents = miHelpAbout
+contents = miHelpContents
+
+[wxMenuItem miHelpAbout]
+id = Dk4FcsFrame_Help_About
+text = sTexts[4]
+tip = sTexts[5]
+
+[wxMenuItem miHelpContents]
+id = Dk4FcsFrame_Help_Contents
+text = sTexts[6]
+tip = sTexts[7]
+
+[wxBoxSizer mainSizer]
+direction = horizontal
+grow = yes
+proportion = 1
+contents = $space(10)
+contents = verticalSizer
+contents = $space(10)
+
+[wxBoxSizer verticalSizer]
+direction = vertical
+grow = yes
+proportion = 1
+contents = $space(10)
+contents = contentsSizer
+contents = $space(10)
+
+[wxGridBagSizer contentsSizer]
+grid = 5 5
+grow = yes
+proportion = 1
+growable column = 1
+growable row = 1
+contents = lFile 0 0 1 1 right
+contents = tFile . +1 1 1 left
+contents = gResults +1 0 1 2 left
+
+[wxStaticText lFile]
+text = sTexts[13]
+
+[wxStaticText tFile]
+text = wxT("")
+
+[wxGrid gResults]
+grow = yes
+proportion = 1
+text style = readonly
+minimum size = 300 200
+column head = sTexts[21]
+row head = sTexts[14]
+row head = sTexts[15]
+row head = sTexts[16]
+row head = sTexts[17]
+row head = sTexts[18]
+row head = sTexts[19]
+row head = sTexts[20]
+cell data = 0 0 sNlWx[17]
+cell data = 1 0 sNlWx[17]
+cell data = 2 0 sNlWx[17]
+cell data = 3 0 sNlWx[17]
+cell data = 4 0 sNlWx[17]
+cell data = 5 0 sNlWx[17]
+cell data = 6 0 sNlWx[17]
+grid style = autosize-data autosize-labels
+
+%% header start
+
+
+
+%% class start
+class Dk4FcsFrame : public Dk4WxFrame
+{
+ private:
+
+ /** Event table for frame.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ /** Autostart controller.
+ */
+ Dk4WxAutostartController oAsc;
+
+ /** Localized texts.
+ */
+ wxChar const * const *sTexts;
+
+ /** Non-localized texts.
+ */
+ wxChar const * const *sNlWx;
+
+ /** Non-localized texts.
+ */
+ dkChar const * const *sNlDk;
+
+ /** File name to process.
+ */
+ wxString sFileName;
+
+ /** Default directory.
+ */
+ wxString sDirectory;
+
+ /** Flag: Active (responding to idle events).
+ */
+ bool bActive;
+
+%% class end
+
+ public:
+
+ /** Constructor.
+ @param wxid Window ID.
+ @param applicationHelper Application helper object.
+ @param hc Help controller for online help.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @param localizedTexts Localized wxChar texts.
+ @param nlWx Non-localized wxChar texts.
+ @param nlDk Non-localized dkChar texts.
+ */
+ Dk4FcsFrame(
+ int wxid,
+ Dk4WxApplicationHelper *applicationHelper,
+ Dk4WxHelpController *hc,
+ int argc,
+ wxChar **argv,
+ wxChar const * const *localizedTexts,
+ wxChar const * const *nlWx,
+ dkChar const * const *nlDk
+ );
+
+ /** Destructor.
+ */
+ ~Dk4FcsFrame();
+
+ /** Check whether we can close the window.
+ @param isFinal Flag: Last main window to close.
+ */
+ bool
+ CanClose(bool isFinal);
+
+ /** Open a file and create checksums for it.
+ @param event Event to process.
+ */
+ void
+ OnOpen(wxCommandEvent & event);
+
+ /** Handler for File/Exit.
+ @param event Event to process.
+ */
+ void
+ OnQuit(wxCommandEvent & event);
+
+ /** Handler for Help/About.
+ @param event Event to process.
+ */
+ void
+ OnAbout(wxCommandEvent & event);
+
+ /** Handler for Help/Contents.
+ @param event Event to process.
+ */
+ void
+ OnHelpContents(wxCommandEvent & event);
+
+ /** Handler for idle events.
+ */
+ void
+ OnIdle(wxIdleEvent & event);
+
+ /* Event handlers for further events.
+ */
+
+ /* Further methods.
+ */
+ private:
+
+ /** Convert binary data to hex notation and set grid cell.
+ @param rowno Row number in table.
+ @param buf Buffer containing binary data.
+ @param bytes Number of bytes in buffer.
+ */
+ void
+ SetCellValueBinary(
+ int rowno,
+ unsigned char *buf,
+ size_t bytes
+ );
+
+ /** Produce checksums.
+ */
+ bool
+ RunChecksumming(void);
+};
+
+%% header end
+
+%% module start
+
+#include "wxdkfcs.h"
+
+#include "dk4mem.h"
+
+#include "dk4verswx.h"
+
+
+#if DK4_HAVE_OPENSSL_MD5_H
+#ifndef OPENSSL_MD5_H_INCLUDED
+#include <openssl/md5.h>
+#define OPENSSL_MD5_H_INCLUDED 1
+#endif
+#endif
+#if DK4_HAVE_OPENSSL_RIPEMD_H
+#ifndef OPENSSL_RIPEMD_H_INCLUDED
+#include <openssl/ripemd.h>
+#define OPENSSL_RIPEMD_H_INCLUDED 1
+#endif
+#endif
+#if DK4_HAVE_OPENSSL_SHA_H
+#ifndef OPENSSL_SHA_H_INCLUDED
+#include <openssl/sha.h>
+#define OPENSSL_SHA_H_INCLUDED 1
+#endif
+#endif
+
+#if !defined(__WXMSW__)
+#include "dkicon.xpm"
+#endif
+
+
+
+$!trace-include
+
+
+
+BEGIN_EVENT_TABLE(Dk4FcsFrame, wxFrame)
+ EVT_MENU(Dk4FcsFrame_Quit, Dk4FcsFrame::OnQuit)
+ EVT_MENU(Dk4FcsFrame_Open, Dk4FcsFrame::OnOpen)
+ EVT_MENU(Dk4FcsFrame_Help_About, Dk4FcsFrame::OnAbout)
+ EVT_MENU(Dk4FcsFrame_Help_Contents, Dk4FcsFrame::OnHelpContents)
+ EVT_IDLE(Dk4FcsFrame::OnIdle)
+END_EVENT_TABLE()
+
+
+
+typedef struct {
+/*
+ Message digests contexts.
+*/
+#if DK4_HAVE_OPENSSL_MD5_H
+ MD5_CTX md5; /**< MD5 context. */
+#endif
+#if DK4_HAVE_OPENSSL_RIPEMD_H
+ RIPEMD160_CTX ripemd160; /**< RIPEMD-160 context. */
+#endif
+#if DK4_HAVE_OPENSSL_SHA_H
+ SHA_CTX sha; /**< SHA-1 context. */
+#if DK4_HAVE_SHA224
+ SHA256_CTX sha224; /**< SHA-224 context. */
+#endif
+#if DK4_HAVE_SHA256
+ SHA256_CTX sha256; /**< SHA-256 context. */
+#endif
+#if DK4_HAVE_SHA384
+ SHA512_CTX sha384; /**< SHA-384 context. */
+#endif
+#if DK4_HAVE_SHA512
+ SHA512_CTX sha512; /**< SHA-512 context. */
+#endif
+#endif
+ int iMd5; /**< Flag: Can use Md5. */
+ int iRipemd160; /**< Flag: Can use RIPEMD-160. */
+ int iSha1; /**< Flag: Can use SHA-1. */
+ int iSha224; /**< Flag: Can use SHA-224. */
+ int iSha256; /**< Flag: Can use SHA-256. */
+ int iSha384; /**< Flag: Can use SHA-384. */
+ int iSha512; /**< Flag: Can use SHA-512. */
+} MULTI_CTX;
+
+
+
+static const wxChar dk4fcs_frame_version[] = { DKT_VERSION_WX };
+
+
+
+static
+void
+multi_ctx_init(MULTI_CTX *mptr)
+{
+ $? "+ multi_ctx_init"
+ DK4_MEMRES(mptr, sizeof(MULTI_CTX));
+#if DK4_HAVE_OPENSSL_MD5_H
+ if (1 == MD5_Init(&(mptr->md5))) {
+ mptr->iMd5 = 1; $? ". MD5"
+ }
+#endif
+#if DK4_HAVE_OPENSSL_RIPEMD_H
+ if (1 == RIPEMD160_Init(&(mptr->ripemd160))) {
+ mptr->iRipemd160 = 1; $? ". RIPEMD-160"
+ }
+#endif
+#if DK4_HAVE_OPENSSL_SHA_H
+ if (1 == SHA1_Init(&(mptr->sha))) {
+ mptr->iSha1 = 1; $? ". SHA-1"
+ }
+#if DK4_HAVE_SHA224
+ if (1 == SHA224_Init(&(mptr->sha224))) {
+ mptr->iSha224 = 1; $? ". SHA-224"
+ }
+#endif
+#if DK4_HAVE_SHA256
+ if (1 == SHA256_Init(&(mptr->sha256))) {
+ mptr->iSha256 = 1; $? ". SHA-256"
+ }
+#endif
+#if DK4_HAVE_SHA384
+ if (1 == SHA384_Init(&(mptr->sha384))) {
+ mptr->iSha384 = 1; $? ". SHA-384"
+ }
+#endif
+#if DK4_HAVE_SHA512
+ if (1 == SHA512_Init(&(mptr->sha512))) {
+ mptr->iSha512 = 1; $? ". SHA-512"
+ }
+#endif
+#endif
+ $? "- multi_ctx_init"
+}
+
+
+
+static
+void
+multi_ctx_add(MULTI_CTX *mptr, void *buffer, size_t sz)
+{
+ $? "+ multi_ctx_add"
+#if DK4_HAVE_OPENSSL_MD5_H
+ if (1 != MD5_Update(&(mptr->md5), buffer, (unsigned long)sz)) {
+ mptr->iMd5 = 0; $? "! MD5"
+ }
+#endif
+#if DK4_HAVE_OPENSSL_RIPEMD_H
+ if (1 != RIPEMD160_Update(&(mptr->ripemd160), buffer, (unsigned long)sz)) {
+ mptr->iRipemd160 = 0; $? "! RIPEMD-160"
+ }
+#endif
+#if DK4_HAVE_OPENSSL_SHA_H
+ if (1 != SHA1_Update(&(mptr->sha), buffer, (unsigned long)sz)) {
+ mptr->iSha1 = 0; $? "! SHA-1"
+ }
+#if DK4_HAVE_SHA224
+ if (1 != SHA224_Update(&(mptr->sha224), buffer, (unsigned long)sz)) {
+ mptr->iSha224 = 0; $? "! SHA-224"
+ }
+#endif
+#if DK4_HAVE_SHA256
+ if (1 != SHA256_Update(&(mptr->sha256), buffer, (unsigned long)sz)) {
+ mptr->iSha256 = 0; $? "! SHA-256"
+ }
+#endif
+#if DK4_HAVE_SHA384
+ if (1 != SHA384_Update(&(mptr->sha384), buffer, (unsigned long)sz)) {
+ mptr->iSha384 = 0; $? "! SHA-384"
+ }
+#endif
+#if DK4_HAVE_SHA512
+ if (1 != SHA512_Update(&(mptr->sha512), buffer, (unsigned long)sz)) {
+ mptr->iSha512 = 0; $? "! SHA-512"
+ }
+#endif
+#endif
+ $? "- multi_ctx_add"
+}
+
+
+
+/** Thread runs while progress dialog is shown.
+ This is a ``fire and forget'' thread destroying itself after running.
+*/
+class Dk4FcsThread : public wxThread
+{
+ protected:
+
+ /** Buffer for reading input file.
+ */
+ unsigned char buf[4096];
+
+ /** Progress dialog.
+ */
+ Dk4WxProgressDialog *pPd;
+
+ /** Multiple message digest contexts.
+ */
+ MULTI_CTX *pCtx;
+
+ /** File to read from.
+ */
+ wxFile *pWxf;
+
+ public:
+
+ /** Constructor.
+ @param pd Pointer to progress dialog.
+ @param ctx Pointer to multiple digest contexts collection.
+ @param wxf Pointer to file we read from.
+ */
+ Dk4FcsThread(
+ Dk4WxProgressDialog *pd,
+ MULTI_CTX *ctx,
+ wxFile *wxf
+ );
+
+ /** Thread function.
+ @return Pointer which is ignored.
+ */
+ virtual
+ void *
+ Entry();
+
+ /** Method executed at end of thread.
+ */
+ virtual
+ void
+ OnExit();
+};
+
+
+
+Dk4FcsThread::Dk4FcsThread(
+ Dk4WxProgressDialog *pd,
+ MULTI_CTX *ctx,
+ wxFile *wxf
+)
+{
+ $? "+ Dk4FcsThread::Dk4FcsThread"
+ pPd = pd;
+ pCtx = ctx;
+ pWxf = wxf;
+ $? "- Dk4FcsThread::Dk4FcsThread"
+}
+
+
+
+void *
+Dk4FcsThread::Entry()
+{
+ wxFileOffset fileSize = (wxFileOffset)0UL;
+ wxFileOffset bytesRead = (wxFileOffset)0UL;
+ size_t bytes = 0U;
+ int gauge = 0;
+ int ogauge = 0;
+ bool canContinue = true;
+ bool success = true;
+ $? "+ Dk4FcsThread::Entry"
+ fileSize = pWxf->Length();
+ while(canContinue) { $? ". loop start"
+ if (pPd->CanContinue()) { $? ". can continue"
+ bytes = pWxf->Read(buf, sizeof(buf));
+ $? ". bytes = %lu", (unsigned long) bytes
+ if (0 < bytes) { $? ". positive number of bytes"
+ if ((size_t)(wxInvalidOffset) != bytes) { $? ". have bytes"
+ multi_ctx_add(pCtx, buf, bytes);
+ bytesRead += (wxFileOffset)bytes;
+ if (bytesRead >= fileSize) {
+ gauge = 1000; $? ". gauge = %d", gauge
+ } else {
+ gauge = (int)((1000.0 * (double)bytesRead) / ((double)fileSize));
+ if (1000 < gauge) {
+ gauge = 1000; $? ". gauge = %d", gauge
+ }
+ }
+ if (gauge != ogauge) { $? ". update gauge in progress dialog"
+ pPd->SetGauge(gauge);
+ ogauge = gauge;
+ }
+ } else { $? "! read error"
+ canContinue = false;
+ success = false;
+ }
+ } else { $? ". 0 bytes, finished"
+ canContinue = false;
+ }
+ } else { $? ". aborted"
+ canContinue = false;
+ success = false;
+ } $? ". loop end"
+ }
+ $? ". loop finished"
+ pPd->EndProcessing(success);
+ $? "- Dk4FcsThread::Entry"
+ return NULL;
+}
+
+
+
+void
+Dk4FcsThread::OnExit()
+{
+ $? "+ Dk4FcsThread::OnExit"
+ $? "- Dk4FcsThread::OnExit"
+}
+
+
+
+%% constructor start
+Dk4FcsFrame::Dk4FcsFrame(
+ int wxid,
+ Dk4WxApplicationHelper *applicationHelper,
+ Dk4WxHelpController *hc,
+ int argc,
+ wxChar **argv,
+ wxChar const * const *localizedTexts,
+ wxChar const * const *nlWx,
+ dkChar const * const *nlDk
+) : Dk4WxFrame(nlWx[0], applicationHelper, hc, wxid)
+{
+ $? "+ Dk4FcsFrame"
+ /* Further local variables.
+ */
+
+ /* Initialize further local variables.
+ */
+
+ sTexts = localizedTexts;
+ sNlWx = nlWx;
+ sNlDk = nlDk;
+#if defined(__WXMSW__)
+ wxIcon wxdkfcs_icon(sNlWx[4]);
+#else
+ wxIcon wxdkfcs_icon(xpm_dkicon);
+#endif
+ /* Initialize further class members.
+ */
+ bActive = true;
+ sFileName = wxEmptyString;
+ sDirectory = wxEmptyString;
+ if (1 < argc) {
+ sFileName = argv[1];
+ oAsc.SetAutoStart(true);
+ {
+ wxFileName wxfn(sFileName);
+ sDirectory = wxfn.GetPath();
+ }
+#if 0
+ /* Just to test auto exit.
+ */
+ oAsc.SetAutoExit(true);
+#endif
+ }
+%% constructor end
+ if(dkctGUILayoutOK) {
+ SetTitle(nlWx[0]);
+ if (1 < argc) {
+ tFile->SetLabel(sFileName);
+ }
+#if 0
+ RestorePosition();
+#endif
+ gResults->SetCellValue(0, 0, sNlWx[5]);
+ gResults->SetCellValue(1, 0, sNlWx[5]);
+ gResults->SetCellValue(2, 0, sNlWx[5]);
+ gResults->SetCellValue(3, 0, sNlWx[5]);
+ gResults->SetCellValue(4, 0, sNlWx[5]);
+ gResults->SetCellValue(5, 0, sNlWx[5]);
+ gResults->SetCellValue(6, 0, sNlWx[5]);
+ }
+
+ /* Release resources allocated by local variables.
+ */
+ $? "- Dk4FcsFrame"
+}
+
+%% module end
+
+
+
+Dk4FcsFrame::~Dk4FcsFrame()
+{
+ $? "+ ~Dk4FcsFrame"
+ /* Release resources allocated by further class members.
+ */
+ $? "- ~Dk4FcsFrame"
+}
+
+
+
+bool
+Dk4FcsFrame::CanClose(bool isFinal)
+{
+ bool back = true;
+ $? "+ CanClose"
+ $? "- CanClose"
+ return back;
+}
+
+
+
+void
+Dk4FcsFrame::OnQuit(wxCommandEvent & event)
+{
+ $? "+ OnQuit"
+ Close();
+ $? "- OnQuit"
+}
+
+
+
+void
+Dk4FcsFrame::OnAbout(wxCommandEvent & event)
+{
+ wxString text(wxT(""));
+ wxString title(wxT(""));
+ $? "+ OnAbout"
+ /* Construct message text. */
+ text.Append(sNlWx[0]);
+ text.Append(sNlWx[7]);
+ text.Append(dk4fcs_frame_version);
+#if 0
+ text.Append(sNlWx[1]);
+#endif
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[9]);
+ text.Append(sNlWx[2]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[11]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[9]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[12]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[10]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[11]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[12]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[13]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[14]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[15]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[16]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[18]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[19]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[20]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[21]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[22]);
+
+ /* Construct dialog box title. */
+ title.Append(sTexts[10]);
+ title.Append(sNlWx[0]);
+
+ /* Show dialog box. */
+ wxMessageBox(text, title);
+ $? "- OnAbout"
+}
+
+
+
+void
+Dk4FcsFrame::OnHelpContents(wxCommandEvent & event)
+{
+ $? "+ OnHelpContents"
+ DisplayContents();
+ $? "- OnHelpContents"
+}
+
+
+
+/* __CHANGE__ 017: Event handlers for further events.
+*/
+
+
+
+/** Hexadecimal digits.
+*/
+static const wxChar hexdig[] = { wxT("0123456789abcdef") };
+
+
+
+void
+Dk4FcsFrame::SetCellValueBinary(
+ int rowno,
+ unsigned char *buf,
+ size_t bytes
+)
+{
+ wxChar obuf[144];
+ wxChar *obptr;
+ unsigned short u;
+ $? "+ SetCellValueBinary %lu", (unsigned long)bytes
+ if (64 >= bytes) {
+ obptr = obuf;
+ while(bytes--) {
+ u = (unsigned short)(*buf);
+ u = u >> 4;
+ u &= 15;
+ *(obptr++) = hexdig[u]; $? ". hexdig = %!wc", hexdig[u]
+ u = (unsigned short)(*buf);
+ u &= 15;
+ *(obptr++) = hexdig[u]; $? ". hexdig = %!wc", hexdig[u]
+ buf++;
+ }
+ *obptr = wxT('\0');
+ {
+ wxString testString(obuf);
+ gResults->SetCellValue(rowno, 0, testString);
+ }
+ } else {
+ /* ERROR: message digest too long, need larger obuf! */
+ }
+ $? "- SetCellValueBinary"
+}
+
+
+
+bool
+Dk4FcsFrame::RunChecksumming(void)
+{
+ MULTI_CTX ctx; // Digests contexts collection
+ unsigned char obuf[128]; // Binary message digests
+ Dk4WxProgressDialog *pd = NULL; // Progress dialog
+ Dk4FcsThread *pt = NULL; // Thread
+ int res = 0; // Operation result
+ bool updateTable = false; // Flag: Update the table
+ $? "+ RunChecksumming"
+ /* Reset all values.
+ */
+ gResults->BeginBatch();
+ gResults->SetCellValue(0, 0, sNlWx[5]);
+ gResults->SetCellValue(1, 0, sNlWx[5]);
+ gResults->SetCellValue(2, 0, sNlWx[5]);
+ gResults->SetCellValue(3, 0, sNlWx[5]);
+ gResults->SetCellValue(4, 0, sNlWx[5]);
+ gResults->SetCellValue(5, 0, sNlWx[5]);
+ gResults->SetCellValue(6, 0, sNlWx[5]);
+ gResults->EndBatch();
+ gResults->ForceRefresh();
+ Refresh();
+ Update();
+
+ /* Attempt to build checksum.
+ */
+ if (wxFile::Exists(sFileName)) { $? ". file exists"
+ {
+ wxFile wxf(sFileName);
+ if (wxf.IsOpened()) { $? ". file opened"
+ pd = new Dk4WxProgressDialog(this, pAppHelp);
+ if (NULL != pd) { $? ". progress dialog"
+ pt = new Dk4FcsThread(pd, &ctx, &wxf);
+ if (NULL != pt) { $? ". thread instance"
+ multi_ctx_init(&ctx);
+ if(wxTHREAD_NO_ERROR == pt->Create()) { $? ". thread create"
+ pt->SetPriority(WXTHREAD_DEFAULT_PRIORITY);
+ pt->Run();
+ res = pd->ShowModal();
+ if (wxID_OK == res) { $? ". success"
+ updateTable = true;
+ } else { $? "! aborted"
+ /* !!!!! ERROR: Aborted by user */
+ }
+ } else { $? "! thread create"
+ delete(pt);
+ pt = NULL;
+ /* !!!!! ERROR: Failed to create thread */
+ }
+ } else { $? "! thread instance"
+ /* !!!!! ERROR: No thread */
+ }
+ pd->Destroy();
+ } else { $? "! progress dialog"
+ /* !!!!! ERROR: No progress dialog */
+ }
+ } else { $? "! failed to open file"
+ /* !!!!! ERROR: Failed to open file */
+ }
+ }
+ if (updateTable) { $? ". table update"
+ gResults->BeginBatch();
+#if DK4_HAVE_OPENSSL_MD5_H
+ if (0 != ctx.iMd5) { $? ". MD5"
+ if (1 == MD5_Final(obuf, &(ctx.md5))) { $? ". MD5 final"
+ SetCellValueBinary(0, obuf, 16);
+ }
+ }
+#endif
+#if DK4_HAVE_OPENSSL_RIPEMD_H
+ if (0 != ctx.iRipemd160) { $? ". RIPEMD-160"
+ if (1 == RIPEMD160_Final(obuf, &(ctx.ripemd160))) {
+ SetCellValueBinary(1, obuf, 20); $? ". RIPEMD-160 final"
+ }
+ }
+#endif
+#if DK4_HAVE_OPENSSL_SHA_H
+ if (0 != ctx.iSha1) { $? ". SHA-1"
+ if (1 == SHA1_Final(obuf, &(ctx.sha))) { $? ". SHA-1 final"
+ SetCellValueBinary(2, obuf, 20);
+ }
+ }
+#if DK4_HAVE_SHA224
+ if (0 != ctx.iSha224) { $? ". SHA-224"
+ if (1 == SHA224_Final(obuf, &(ctx.sha224))) { $? ". SHA-224 final"
+ SetCellValueBinary(3, obuf, 28);
+ }
+ }
+#endif
+#if DK4_HAVE_SHA256
+ if (0 != ctx.iSha256) { $? ". SHA-256"
+ if (1 == SHA256_Final(obuf, &(ctx.sha256))) { $? ". SHA-256 final"
+ SetCellValueBinary(4, obuf, 32);
+ }
+ }
+#endif
+#if DK4_HAVE_SHA384
+ if (0 != ctx.iSha384) { $? ". SHA-384"
+ if (1 == SHA384_Final(obuf, &(ctx.sha384))) { $? ". SHA-384 final"
+ SetCellValueBinary(5, obuf, 48);
+ }
+ }
+#endif
+#if DK4_HAVE_SHA512
+ if (0 != ctx.iSha512) { $? ". SHA-512"
+ if (1 == SHA512_Final(obuf, &(ctx.sha512))) { $? ". SHA-512 final"
+ SetCellValueBinary(6, obuf, 64);
+ }
+ }
+#endif
+#endif
+ gResults->AutoSize();
+ gResults->EndBatch();
+ gResults->ForceRefresh();
+ {
+ int x, y, w, h;
+ GetPosition(&x, &y);
+ GetSize(&w, &h);
+ mainSizer->Fit(this);
+ SetSize(x, y, w, h);
+ }
+ Refresh();
+ Update();
+ } else { $? ". no table update"
+ }
+ } else { $? "! file does not exist"
+ /* !!!!! ERROR: File does not exist */
+ }
+ $? "- RunChecksumming"
+ return updateTable;
+}
+
+
+
+void
+Dk4FcsFrame::OnOpen(wxCommandEvent & event)
+{
+ bool canRun = true;
+ int res = 0;
+ $? "+ OnOpen"
+ {
+ wxFileDialog dlg(this, sTexts[22], sDirectory);
+ res = dlg.ShowModal();
+ if (wxID_OK == res) {
+ sFileName = dlg.GetPath();
+ tFile->SetLabel(sFileName);
+ {
+ wxFileName wxfn(sFileName);
+ sDirectory = wxfn.GetPath();
+ }
+ canRun = true;
+ } else {
+ canRun = false;
+ }
+ }
+ if (canRun) {
+ (void)RunChecksumming();
+ }
+ $? "- OnOpen"
+}
+
+
+
+void
+Dk4FcsFrame::OnIdle(wxIdleEvent & event)
+{
+ bool success = false;
+ $? "+ OnIdle"
+ if (bActive) {
+ /* event.RequestMore(); */
+ switch (oAsc.GetReaction()) {
+#if 0
+ case DK4WX_AUTOSTART_REACTION_IGNORE : {
+ } break;
+#endif
+ case DK4WX_AUTOSTART_REACTION_START : {
+ oAsc.StartProcessing();
+ success = RunChecksumming();
+ oAsc.EndProcessing(success);
+ } break;
+ case DK4WX_AUTOSTART_REACTION_MORE : {
+ event.RequestMore();
+ } break;
+ case DK4WX_AUTOSTART_REACTION_EXIT : {
+ bActive = false;
+ Close();
+ } break;
+ }
+ }
+ event.Skip();
+ $? "- OnIdle"
+}
+
+
diff --git a/support/dktools/Dk4FcsThread.cpp b/support/dktools/Dk4FcsThread.cpp
new file mode 100644
index 0000000000..5afedd6720
--- /dev/null
+++ b/support/dktools/Dk4FcsThread.cpp
@@ -0,0 +1,244 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: Dk4FcsThread.cpt
+*/
+
+/*
+Copyright (C) 2015, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file Dk4FcsThread.cpp The Dk4FcsThread module.
+*/
+
+
+#line 108 "Dk4FcsThread.cpt"
+
+
+#include "dk4mem.h"
+#include "wxdkfcs.h"
+
+
+
+static
+void
+ctx_collection_init(dk4fcs_ctx_t *ptr)
+{
+ dk4mem_reset(ptr, sizeof(dk4fcs_ctx_t), NULL);
+#if DK4_HAVE_OPENSSL_MD5_H
+ MD5_Init(&(ptr->md5));
+#endif
+#if DK4_HAVE_OPENSSL_RIPEMD_H
+ RIPEMD160_Init(&(ptr->ripemd160));
+#endif
+#if DK4_HAVE_OPENSSL_SHA_H
+ SHA1_Init(&(ptr->sha1));
+#if DK4_HAVE_SHA224
+ SHA224_Init(&(ptr->sha224));
+#endif
+#if DK4_HAVE_SHA256
+ SHA256_Init(&(ptr->sha256));
+#endif
+#if DK4_HAVE_SHA384
+ SHA384_Init(&(ptr->sha384));
+#endif
+#if DK4_HAVE_SHA512
+ SHA512_Init(&(ptr->sha512));
+#endif
+#endif
+}
+
+
+
+static
+void
+ctx_collection_add(dk4fcs_ctx_t *ptr, void *data, size_t sz)
+{
+#if DK4_HAVE_OPENSSL_MD5_H
+ MD5_Update(&(ptr->md5), data, sz);
+#endif
+#if DK4_HAVE_OPENSSL_RIPEMD_H
+ RIPEMD160_Update(&(ptr->ripemd160), data, sz);
+#endif
+#if DK4_HAVE_OPENSSL_SHA_H
+ SHA1_Update(&(ptr->sha1), data, sz);
+#if DK4_HAVE_SHA224
+ SHA224_Update(&(ptr->sha224), data, sz);
+#endif
+#if DK4_HAVE_SHA256
+ SHA256_Update(&(ptr->sha256), data, sz);
+#endif
+#if DK4_HAVE_SHA384
+ SHA384_Update(&(ptr->sha384), data, sz);
+#endif
+#if DK4_HAVE_SHA512
+ SHA512_Update(&(ptr->sha512), data, sz);
+#endif
+#endif
+}
+
+
+
+static
+void
+ctx_collection_finish(dk4fcs_ctx_t *ptr)
+{
+#if DK4_HAVE_OPENSSL_MD5_H
+ MD5_Final(&(ptr->md5bytes[0]), &(ptr->md5));
+#endif
+#if DK4_HAVE_OPENSSL_RIPEMD_H
+ RIPEMD160_Final(&(ptr->ripemd160bytes[0]), &(ptr->ripemd160));
+#endif
+#if DK4_HAVE_OPENSSL_SHA_H
+ SHA1_Final(&(ptr->sha1bytes[0]), &(ptr->sha1));
+#if DK4_HAVE_SHA224
+ SHA224_Final(&(ptr->sha224bytes[0]), &(ptr->sha224));
+#endif
+#if DK4_HAVE_SHA256
+ SHA256_Final(&(ptr->sha256bytes[0]), &(ptr->sha256));
+#endif
+#if DK4_HAVE_SHA384
+ SHA384_Final(&(ptr->sha384bytes[0]), &(ptr->sha384));
+#endif
+#if DK4_HAVE_SHA512
+ SHA512_Final(&(ptr->sha512bytes[0]), &(ptr->sha512));
+#endif
+#endif
+}
+
+
+
+Dk4FcsThread::Dk4FcsThread(
+ wxFile *wxf,
+ Dk4WxProcessingController *proCo,
+ dk4fcs_ctx_t *ctx
+)
+{
+ pWxFile = wxf;
+ pProCo = proCo;
+ pCtx = ctx;
+}
+
+
+
+void *
+Dk4FcsThread::Entry()
+{
+ unsigned char buf[4096];
+ void *back = NULL;
+ wxFileOffset fileSize = (wxFileOffset)0UL;
+ wxFileOffset summary = (wxFileOffset)0UL;
+ size_t rdb = 0;
+ int gv = 0;
+ int ogv = 0;
+ bool cc = true; // Flag: Can continue
+ bool succ = true; // Flag: Success
+
+
+
+#line 230 "Dk4FcsThread.cpt"
+ /* Initialize variables.
+ */
+ fileSize = pWxFile->Length();
+ ctx_collection_init(pCtx);
+
+
+#line 235 "Dk4FcsThread.cpt"
+ /* Run in a loop.
+ */
+ do {
+ if (pProCo->canContinue()) {
+
+#line 239 "Dk4FcsThread.cpt"
+ rdb = pWxFile->Read(buf, sizeof(buf));
+ if (0 < rdb) {
+
+#line 241 "Dk4FcsThread.cpt"
+ ctx_collection_add(pCtx, buf, rdb);
+
+#line 242 "Dk4FcsThread.cpt"
+ summary += (wxFileOffset)rdb;
+ if ((wxFileOffset)0UL < fileSize) {
+ if (summary < fileSize) {
+ gv = (int)((1000.0 * (double)summary) / (double)fileSize);
+ } else {
+ gv = 1000;
+ }
+ } else {
+ gv = 1000;
+ }
+ if (gv != ogv) {
+
+#line 253 "Dk4FcsThread.cpt"
+ pProCo->setGaugeValue(gv);
+ ogv = gv;
+ }
+ } else {
+
+#line 257 "Dk4FcsThread.cpt"
+ if (summary != fileSize) {
+ succ = false;
+
+#line 259 "Dk4FcsThread.cpt"
+ }
+ cc = false;
+ }
+ } else {
+
+#line 263 "Dk4FcsThread.cpt"
+ cc = false;
+ succ = false; // Aborted by user.
+ }
+ } while(cc);
+
+
+#line 268 "Dk4FcsThread.cpt"
+ /* Finish contexts.
+ */
+ ctx_collection_finish(pCtx);
+
+
+#line 272 "Dk4FcsThread.cpt"
+ /* End processsing
+ */
+ pProCo->endProcessing(succ);
+
+
+#line 276 "Dk4FcsThread.cpt"
+ return back;
+}
+
+
+
+void
+Dk4FcsThread::OnExit()
+{
+
+}
+
+
diff --git a/support/dktools/Dk4FcsThread.h b/support/dktools/Dk4FcsThread.h
new file mode 100644
index 0000000000..a2297f9210
--- /dev/null
+++ b/support/dktools/Dk4FcsThread.h
@@ -0,0 +1,141 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: Dk4FcsThread.cpt
+*/
+
+/*
+Copyright (C) 2015, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4FCSTHREAD_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4FCSTHREAD_H_INCLUDED 1
+
+
+#line 9 "Dk4FcsThread.cpt"
+
+/** @file Dk4FcsThread.h Thread for the wxdkfcs program.
+*/
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_OPENSSL_MD5_H
+#ifndef OPENSSL_MD5_H_INCLUDED
+#include <openssl/md5.h>
+#define OPENSSL_MD5_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_OPENSSL_SHA_H
+#ifndef OPENSSL_SHA_H_INCLUDED
+#include <openssl/sha.h>
+#define OPENSSL_SHA_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_OPENSSL_RIPEMD_H
+#ifndef OPENSSL_RIPEMD_H_INCLUDED
+#include <openssl/ripemd.h>
+#define OPENSSL_RIPEMD_H_INCLUDED 1
+#endif
+#endif
+
+
+
+/** Checksum context collection.
+*/
+typedef struct {
+#if DK4_HAVE_OPENSSL_MD5_H
+ MD5_CTX md5; /**< MD5 context. */
+#endif
+#if DK4_HAVE_OPENSSL_RIPEMD_H
+ RIPEMD160_CTX ripemd160; /**< RIPEMD-160 context. */
+#endif
+#if DK4_HAVE_OPENSSL_SHA_H
+ SHA_CTX sha1; /**< SHA-1 context. */
+#if DK4_HAVE_SHA224
+ SHA256_CTX sha224; /**< SHA-224 context. */
+#endif
+#if DK4_HAVE_SHA256
+ SHA256_CTX sha256; /**< SHA-256 context. */
+#endif
+#if DK4_HAVE_SHA384
+ SHA512_CTX sha384; /**< SHA-384 context. */
+#endif
+#if DK4_HAVE_SHA512
+ SHA512_CTX sha512; /**< ShA-512 context. */
+#endif
+#endif
+ unsigned char sha512bytes[64];
+ unsigned char sha384bytes[48];
+ unsigned char sha256bytes[32];
+ unsigned char sha224bytes[28];
+ unsigned char ripemd160bytes[20];
+ unsigned char sha1bytes[20];
+ unsigned char md5bytes[16];
+} dk4fcs_ctx_t;
+
+
+
+class Dk4FcsThread : public wxThread
+{
+ protected:
+
+ /** File to process.
+ */
+ wxFile *pWxFile;
+
+ /** Processing controller.
+ */
+ Dk4WxProcessingController *pProCo;
+
+ /** Message digest context collection.
+ */
+ dk4fcs_ctx_t *pCtx;
+
+ public:
+
+ Dk4FcsThread(
+ wxFile *wxf,
+ Dk4WxProcessingController *proCo,
+ dk4fcs_ctx_t *ctx
+ );
+
+ virtual
+ void *
+ Entry();
+
+ virtual
+ void
+ OnExit();
+};
+
+
+
+#endif
diff --git a/support/dktools/Dk4WxApplicationHelper.cpp b/support/dktools/Dk4WxApplicationHelper.cpp
new file mode 100644
index 0000000000..ded5250739
--- /dev/null
+++ b/support/dktools/Dk4WxApplicationHelper.cpp
@@ -0,0 +1,2309 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: Dk4WxApplicationHelper.cpt
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file Dk4WxApplicationHelper.cpp The Dk4WxApplicationHelper module.
+*/
+
+
+#line 721 "Dk4WxApplicationHelper.cpt"
+
+#include "Dk4WxApplicationHelper.h"
+
+#include "dk4mem.h"
+#include "dk4enc.h"
+#include "dk4strd.h"
+#include "dk4strx.h"
+#include "dk4recwx.h"
+#include "dk4wxpref.h"
+#include "dk4wxstt.h"
+#include "dk4hnamed.h"
+#include "dk4loc.h"
+#include "dk4user.h"
+#include "dk4mpl.h"
+#include "dk4vers.h"
+#include "dk4exepd.h"
+#include "dk4inst.h"
+#include "dk4pathd.h"
+#if DK4_SIZEOF_WXCHAR > 1
+#include "dk4strw.h"
+#include "dk4maiwdil.h"
+#include "dk4maiwdbl.h"
+#else
+#include "dk4str8.h"
+#include "dk4mai8dil.h"
+#include "dk4mai8dbl.h"
+#endif
+
+
+
+
+
+#line 752 "Dk4WxApplicationHelper.cpt"
+
+
+
+/* ************************************************************************ */
+/* * * */
+/* * Type definitions. * */
+/* * * */
+/* ************************************************************************ */
+
+
+#line 758 "Dk4WxApplicationHelper.cpt"
+
+
+
+/** Pointer to constant wxChar.
+*/
+typedef const wxChar *PCWXCHAR;
+
+
+
+/** Error codes in Initialize().
+*/
+enum {
+ /** No error occured.
+ */
+ ERROR_NONE = 0,
+
+ /** Not enough memory.
+ */
+ ERROR_MEMORY ,
+
+ /** Failed to find host name.
+ */
+ ERROR_HOSTNAME ,
+
+ /** Failed to find localization settings.
+ */
+ ERROR_LANG_REG_ENC ,
+
+ /** Failed to find login name.
+ */
+ ERROR_LOGNAME ,
+
+ /** Failed to find home directory.
+ */
+ ERROR_HOMEDIR ,
+
+ /** Failed to find path name of executable.
+ */
+ ERROR_EXECUTABLE ,
+
+ /** Executable file name too long.
+ */
+ ERROR_EXEC_TOO_LONG ,
+
+ /** Invalid arguments were passed to Initialize().
+ */
+ ERROR_ARGUMENTS ,
+};
+
+
+
+/* ************************************************************************ */
+/* * * */
+/* * Variables. * */
+/* * * */
+/* ************************************************************************ */
+
+
+#line 812 "Dk4WxApplicationHelper.cpt"
+
+
+
+/** Empty string, returned for all strings not found.
+*/
+static const wxChar dk4wxah_empty_string[] = { wxT("") };
+
+
+
+/** File name separator string
+*/
+static const dkChar dk4wxah_fnsep_str[] = {
+#if DK4_ON_WINDOWS
+dkT("\\")
+#else
+dkT("/")
+#endif
+} ;
+
+
+
+/** Texts used in error message boxes in the Initialize() function.
+*/
+static const wxChar * const dkwxah_msgb_texts[] = {
+/* 0 */
+wxT("Initialization failed!"),
+
+/* 1 */
+wxT("Not enough memory!"),
+
+/* 2 */
+wxT("Failed to find current host name!"),
+
+/* 3 */
+wxT("Failed to find language, region, and encoding settings!"),
+
+/* 4 */
+wxT("Failed to find users login name!"),
+
+/* 5 */
+wxT("Failed to find users home directory!"),
+
+/* 6 */
+wxT("Failed to find executable file name!"),
+
+/* 7 */
+wxT("Executable file name too long!"),
+
+/* 8 */
+wxT("Illegal arguments (NULL pointers) to Initialize() function!"),
+
+NULL
+
+
+#line 874 "Dk4WxApplicationHelper.cpt"
+};
+
+
+
+/** Constant text keywords used by module, not localized.
+*/
+static const dkChar * const dk4wxah_kwnl_dk[] = {
+/* 0 */
+dkT("dk4wxbase.str"),
+
+NULL
+
+
+#line 887 "Dk4WxApplicationHelper.cpt"
+};
+
+
+
+/** Constant text strings used by the module, not localized.
+*/
+static const char * const dk4wxah_kwnl_c8[] = {
+/* 0 */
+"C",
+
+NULL
+
+
+#line 897 "Dk4WxApplicationHelper.cpt"
+};
+
+
+
+/** Final directory names for good installations.
+*/
+static const dkChar * const dk4wxah_final_directories[] = {
+/* 0 */
+dkT("bin"),
+
+/* 1 */
+dkT("sbin"),
+
+/* 2 */
+dkT("libexec"),
+
+/* 3 */
+dkT("lib"),
+
+NULL
+
+
+#line 910 "Dk4WxApplicationHelper.cpt"
+};
+
+
+
+/** New final directory names to append.
+*/
+static const dkChar * const dk4wxah_new_directories[] = {
+/* 0 */
+dkT("etc"),
+
+/* 1 */
+dkT("share"),
+
+NULL
+
+
+#line 921 "Dk4WxApplicationHelper.cpt"
+};
+
+
+
+/** Basic strings, replaced by localized texts later.
+*/
+static const wxChar * const dk4wxah_basic_strings[] = {
+/* 0 */
+wxT("Help file not found"),
+
+/* 1 */
+wxT("The file containing online help text was not found on your computer!"),
+
+/* 2 */
+wxT("Processing in progress"),
+
+/* 3 */
+wxT("Cancel"),
+
+/* 4 */
+wxT("Abort current operation"),
+
+/* 5 */
+wxT("Abortion scheduled, wait please!"),
+
+/* 6 */
+wxT("Error"),
+
+/* 7 */
+wxT("Not enough memory (RAM)!"),
+
+/* 8 */
+wxT("Illegal arguments in Dk4WxHelpController constructor (bug)!"),
+
+NULL
+
+
+#line 954 "Dk4WxApplicationHelper.cpt"
+};
+
+
+
+/* ************************************************************************ */
+/* * * */
+/* * Internal tool functions, not object-oriented. * */
+/* * * */
+/* ************************************************************************ */
+
+
+#line 961 "Dk4WxApplicationHelper.cpt"
+
+
+
+/** Check whether a directory or file name ends in one of
+ the names mentioned in array.
+ @param dirname Directory name to check.
+ @param array String array containing name ends.
+ @return 1 on success with prefix in dirname, 0 on error.
+*/
+static
+int
+dk4wxapplicationhelper_isinsub(dkChar *dirname, const dkChar * const *array)
+{
+ dkChar *p1;
+ dkChar *p2;
+ int cc; /* Flag: Can continue */
+ int back = 0; /* Function result */
+
+
+#line 979 "Dk4WxApplicationHelper.cpt"
+ do {
+ cc = 0;
+ p1 = dirname; p2 = NULL;
+ while (dkT('\0') != *p1) {
+ if ((dkT('/') == *p1) || (dkT('\\') == *p1)) { p2 = p1; }
+ p1++;
+ }
+ if (NULL != p2) {
+ *(p2++) = dkT('\0');
+ cc = 1;
+#if DK4_HAVE_CASE_INSENSITIVE_PATHNAMES
+ if (0 <= dk4str_array_index(array, p2, 0))
+#else
+ if (0 <= dk4str_array_index(array, p2, 1))
+#endif
+ {
+ back = 1;
+ cc = 0;
+ }
+ } else {
+ }
+ } while ((1 == cc) && (0 == back));
+
+
+#line 1002 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+
+
+/* ************************************************************************ */
+/* * * */
+/* * Constructor, destructor, initialization and cleanup. * */
+/* * * */
+/* ************************************************************************ */
+
+
+#line 1010 "Dk4WxApplicationHelper.cpt"
+
+
+
+Dk4WxApplicationHelper::Dk4WxApplicationHelper()
+{
+ /* Set all member variables to "resource not available".
+ Real initialization is in the Initialize() method.
+ */
+
+
+#line 1019 "Dk4WxApplicationHelper.cpt"
+ ppBasicStrings = NULL;
+ pcwxsArgv0 = NULL;
+ pcwxsVendor = NULL;
+ pcdksGroup = NULL;
+ pwxsApp = NULL;
+ pdksHost = NULL;
+ pdksLogname = NULL;
+ pdksHome = NULL;
+ pdksApp = NULL;
+ pdksSysconf = NULL;
+ pdksShare = NULL;
+ pdksLanguage = NULL;
+ pdksRegion = NULL;
+ sStt = NULL;
+ iStt = NULL;
+ sPrSys = NULL;
+ iPrSys = NULL;
+ sPrUser = NULL;
+ iPrUser = NULL;
+ nBasicStrings = 0;
+ iDkEncoding = DK4_ENCODING_ASCII;
+ iWxEncoding = DK4_ENCODING_ASCII;
+ iFiEncoding = DK4_FILE_ENCODING_ASCII;
+ bActive = false;
+
+
+#line 1044 "Dk4WxApplicationHelper.cpt"
+}
+
+
+/*
+ We do not need a critical section locker as Initialize()
+ is invoked from the applications OnInit() method. At this
+ time there is no top level window or worker thread yet.
+*/
+bool
+Dk4WxApplicationHelper::Initialize(
+ const wxChar *argv0,
+ const wxChar *vendorName,
+ const dkChar *groupName,
+ dk4_er_t *erp
+)
+{
+ dkChar labuf[DK4_MAX_PATH];
+ dkChar rebuf[DK4_MAX_PATH];
+ wxChar anbuf[DK4_MAX_PATH];
+ const wxChar *msgbtext = NULL;
+ const wxChar *msgbtitle = NULL;
+ dkChar *p1;
+ dkChar *p2;
+#if DK4_ON_WINDOWS
+ dkChar *p4;
+#endif
+ size_t szrebuf = DK4_SIZEOF(rebuf,dkChar);
+ size_t szlabuf = DK4_SIZEOF(labuf,dkChar);
+ size_t szanbuf = DK4_SIZEOF(anbuf,wxChar);
+ int errc = ERROR_NONE;
+ int res;
+ int pn;
+ bool back = false;
+
+
+#line 1078 "Dk4WxApplicationHelper.cpt"
+ /* Keep some of the arguments.
+ */
+ if ((NULL == argv0) || (NULL == vendorName) || (NULL == groupName)) {
+ errc = ERROR_ARGUMENTS;
+ goto finished;
+ }
+ pcwxsArgv0 = argv0;
+ pcwxsVendor = vendorName;
+ pcdksGroup = groupName;
+
+
+#line 1088 "Dk4WxApplicationHelper.cpt"
+
+ /* Some default values.
+ */
+ ppBasicStrings = dk4wxah_basic_strings;
+ nBasicStrings = DK4_SIZEOF(dk4wxah_basic_strings,PCWXCHAR) - 1;
+
+
+#line 1094 "Dk4WxApplicationHelper.cpt"
+
+ /* Host name.
+ */
+ if (0 != dk4hostname(labuf, szlabuf, NULL)) {
+ p1 = dk4str_chr(labuf, dkT('.'));
+ if (NULL != p1) { *p1 = dkT('\0'); }
+ pdksHost = dk4str_dup(labuf, NULL);
+ if (NULL == pdksHost) {
+ errc = ERROR_MEMORY;
+ goto finished;
+ }
+ } else {
+ errc = ERROR_HOSTNAME;
+ goto finished;
+ }
+
+
+#line 1110 "Dk4WxApplicationHelper.cpt"
+
+ /* Language and encoding.
+ */
+ res = dk4loc_get_settings(labuf, szlabuf, rebuf, szrebuf, &iDkEncoding, erp);
+ if (0 == res) {
+ errc = ERROR_LANG_REG_ENC;
+ goto finished;
+ }
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR > 2
+ iWxEncoding = DK4_ENCODING_32;
+#else
+ iWxEncoding = DK4_ENCODING_UTF16;
+#endif
+#else
+ switch (iDkEncoding) {
+ case DK4_ENCODING_ANSI : {
+ iWxEncoding = DK4_ENCODING_ANSI;
+ } break;
+ case DK4_ENCODING_UTF8 : {
+ iWxEncoding = DK4_ENCODING_UTF8;
+ } break;
+ default : {
+ iWxEncoding = DK4_ENCODING_ASCII;
+ } break;
+ }
+#endif
+ switch (iDkEncoding) {
+ case DK4_ENCODING_ANSI : {
+ iFiEncoding = DK4_ENCODING_ANSI;
+ } break;
+ case DK4_ENCODING_UTF8 : {
+ iFiEncoding = DK4_ENCODING_UTF8;
+ } break;
+ default : {
+ iFiEncoding = DK4_ENCODING_ASCII;
+ } break;
+ }
+ if (0 < dk4str_len(labuf)) {
+ pdksLanguage = dk4str_dup(labuf, erp);
+ if (NULL == pdksLanguage) {
+ errc = ERROR_MEMORY;
+ goto finished;
+ }
+ }
+ if (0 < dk4str_len(rebuf)) {
+ pdksRegion = dk4str_dup(rebuf, erp);
+ if (NULL == pdksRegion) {
+ errc = ERROR_MEMORY;
+ goto finished;
+ }
+ }
+
+
+#line 1163 "Dk4WxApplicationHelper.cpt"
+
+ /* Login name and home directory.
+ */
+ res = dk4user_get_logname(labuf, szlabuf, 0, erp);
+ if (0 == res) {
+ errc = ERROR_LOGNAME;
+ goto finished;
+ }
+ pdksLogname = dk4str_dup(labuf, erp);
+ if (NULL == pdksLogname) {
+ errc = ERROR_MEMORY;
+ goto finished;
+ }
+ res = dk4user_get_homedir(labuf, szlabuf, 0, erp);
+ if (0 == res) {
+
+#line 1178 "Dk4WxApplicationHelper.cpt"
+ errc = ERROR_HOMEDIR;
+ goto finished;
+ }
+ pdksHome = dk4str_dup(labuf, erp);
+ if (NULL == pdksHome) {
+
+#line 1183 "Dk4WxApplicationHelper.cpt"
+ errc = ERROR_MEMORY;
+ goto finished;
+ }
+
+
+#line 1187 "Dk4WxApplicationHelper.cpt"
+
+ /* System configuration and data directory.
+ */
+ res = dk4recwx_wxchar_to_dkchar(
+ labuf, szlabuf, iDkEncoding, argv0, iWxEncoding, erp
+ );
+
+#line 1193 "Dk4WxApplicationHelper.cpt"
+ res = dk4execpath(
+ rebuf, szrebuf, ((0 != res) ? labuf : NULL), erp
+ );
+ if (0 == res) {
+
+#line 1197 "Dk4WxApplicationHelper.cpt"
+ errc = ERROR_EXECUTABLE;
+ goto finished;
+ }
+
+#line 1200 "Dk4WxApplicationHelper.cpt"
+ p1 = rebuf;
+ p2 = NULL;
+ while (dkT('\0') != *p1) {
+ if (dk4wxah_fnsep_str[0] == *p1) { p2 = p1; }
+ /* We must increase this pointer.
+ */
+ p1++;
+ }
+ if (NULL == p2) {
+
+#line 1209 "Dk4WxApplicationHelper.cpt"
+ errc = ERROR_EXECUTABLE;
+ goto finished;
+ }
+ *(p2++) = dkT('\0');
+ /* Binary directory in rebuf, p2 is application name */
+#if DK4_ON_WINDOWS
+ /* On Windows, strip .exe suffix.
+ */
+ p4 = dk4path_get_suffix(p2, NULL);
+ if (NULL != p4) { *p4 = dkT('\0'); }
+#endif
+ pdksApp = dk4str_dup(p2, NULL);
+ if (NULL == pdksApp) {
+ errc = ERROR_MEMORY;
+ goto finished;
+ }
+ res = dk4recwx_dkchar_to_wxchar(
+ anbuf, szanbuf, iWxEncoding, pdksApp, iDkEncoding, NULL
+ );
+ if (0 == res) {
+
+#line 1229 "Dk4WxApplicationHelper.cpt"
+ errc = ERROR_EXECUTABLE;
+ goto finished;
+ }
+ pwxsApp = dk4strx_dup(anbuf, NULL);
+ if (NULL == pwxsApp) {
+ errc = ERROR_MEMORY;
+ goto finished;
+ }
+ /* Check whether the binary resides in one of the installation directories */
+ res = 0;
+ if (0 != dk4path_is_in_subdir(rebuf, dk4inst_get_directory(4), NULL)) {
+ res = 1;
+ }
+ if (0 == res) {
+ if (0 != dk4path_is_in_subdir(rebuf, dk4inst_get_directory(5), NULL)) {
+ res = 1;
+ }
+ }
+ if (0 == res) {
+ if (0 != dk4path_is_in_subdir(rebuf, dk4inst_get_directory(6), NULL)) {
+ res = 1;
+ }
+ }
+ if (0 == res) {
+ if (0 != dk4path_is_in_subdir(rebuf, dk4inst_get_directory(10), NULL)) {
+ res = 1;
+ }
+ }
+ if (0 != res) {
+ pdksSysconf = dk4str_dup(dk4inst_get_directory(1), NULL);
+ pdksShare = dk4str_dup(dk4inst_get_directory(2), NULL);
+ if ((NULL == pdksSysconf) || (NULL == pdksShare)) {
+ errc = ERROR_MEMORY;
+ goto finished;
+ }
+ } else {
+ dk4str_cpy_s(labuf, szlabuf, rebuf, NULL);
+ if (0 != dk4wxapplicationhelper_isinsub(labuf, dk4wxah_final_directories)) {
+ res = 0;
+ if (0 != dk4str_cpy_s(rebuf, szrebuf, labuf, NULL)) {
+ if (0 != dk4str_cat_s(rebuf, szrebuf, dk4wxah_fnsep_str, NULL)) {
+ if (0 != dk4str_cat_s(rebuf,szrebuf,dk4wxah_new_directories[0],NULL))
+ {
+ res = 1;
+ }
+ }
+ }
+ if (0 != res) {
+ pdksSysconf = dk4str_dup(rebuf, NULL);
+ if (NULL == pdksSysconf) {
+ errc = ERROR_MEMORY;
+ goto finished;
+ }
+ } else {
+ errc = ERROR_EXEC_TOO_LONG;
+ goto finished;
+ }
+ res = 0;
+ if (0 != dk4str_cpy_s(rebuf, szrebuf, labuf, NULL)) {
+ if (0 != dk4str_cat_s(rebuf, szrebuf, dk4wxah_fnsep_str, NULL)) {
+ if (0 != dk4str_cat_s(rebuf,szrebuf,dk4wxah_new_directories[1],NULL))
+ {
+ res = 1;
+ }
+ }
+ }
+ if (0 != res) {
+ pdksShare = dk4str_dup(rebuf, NULL);
+ if (NULL == pdksShare) {
+ errc = ERROR_MEMORY;
+ goto finished;
+ }
+ } else {
+ errc = ERROR_EXEC_TOO_LONG;
+ goto finished;
+ }
+ } else {
+ pdksSysconf = dk4str_dup(rebuf, NULL);
+ pdksShare = dk4str_dup(rebuf, NULL);
+ if ((NULL == pdksSysconf) || (NULL == pdksShare)) {
+ errc = ERROR_MEMORY;
+ goto finished;
+ }
+ }
+ }
+
+
+#line 1315 "Dk4WxApplicationHelper.cpt"
+
+ /* Containers and iterators for string tables and preferences.
+ */
+ sStt = dk4sto_open(NULL);
+ if (NULL == sStt) {
+ errc = ERROR_MEMORY;
+ goto finished;
+ }
+ dk4sto_set_comp(sStt, dk4wxstt_compare, 0);
+ iStt = dk4sto_it_open(sStt, NULL);
+ if (NULL == iStt) {
+ errc = ERROR_MEMORY;
+ goto finished;
+ }
+ sPrSys = dk4sto_open(NULL);
+ if (NULL == sPrSys) {
+ errc = ERROR_MEMORY;
+ goto finished;
+ }
+ dk4sto_set_comp(sPrSys, dk4wxpref_compare, 0);
+ iPrSys = dk4sto_it_open(sPrSys, NULL);
+ if (NULL == iPrSys) {
+ errc = ERROR_MEMORY;
+ goto finished;
+ }
+ sPrUser = dk4sto_open(NULL);
+ if (NULL == sPrUser) {
+ errc = ERROR_MEMORY;
+ goto finished;
+ }
+ dk4sto_set_comp(sPrUser, dk4wxpref_compare, 0);
+ iPrUser = dk4sto_it_open(sPrUser, NULL);
+ if (NULL == iPrUser) {
+ errc = ERROR_MEMORY;
+ goto finished;
+ }
+
+
+#line 1352 "Dk4WxApplicationHelper.cpt"
+
+ /* Read preference files.
+ */
+ for (pn = 0; pn <= DK4_FS_CONF_MAX; pn++) {
+ dk4wxpref_one_pass(
+ ((DK4_FS_CONF_SYS_MAX < pn) ? sPrUser : sPrSys),
+ ((DK4_FS_CONF_SYS_MAX < pn) ? iPrUser : iPrSys),
+ pdksApp,
+ pcdksGroup,
+ pdksLogname,
+ pdksHost,
+ pdksLanguage,
+ pdksRegion,
+ pdksHome,
+ pdksSysconf,
+ pdksShare,
+ iWxEncoding,
+ iDkEncoding,
+ (
+ (DK4_ENCODING_UTF8 == iDkEncoding)
+ ? DK4_FILE_ENCODING_UTF8 : DK4_FILE_ENCODING_ASCII
+ ),
+ pn
+ );
+ }
+
+
+#line 1378 "Dk4WxApplicationHelper.cpt"
+
+ /* Localized basic strings.
+ */
+ ppBasicStrings = InternalGetStringTable(
+ dk4wxah_kwnl_dk[0], (DK4_SIZEOF(dk4wxah_basic_strings,PCWXCHAR) - 1)
+ );
+ if (NULL == ppBasicStrings) { ppBasicStrings = dk4wxah_basic_strings; }
+ nBasicStrings = Dk4WxApplicationHelper::StringTableSize(ppBasicStrings);
+
+
+#line 1387 "Dk4WxApplicationHelper.cpt"
+
+ /* Finally mark success.
+ */
+ bActive = back = true;
+
+ /* Clean up if not successfully.
+ */
+ finished:
+ if (!(back)) {
+
+#line 1396 "Dk4WxApplicationHelper.cpt"
+ switch (errc) {
+ case ERROR_MEMORY : {
+
+#line 1398 "Dk4WxApplicationHelper.cpt"
+ msgbtext = dkwxah_msgb_texts[1];
+ msgbtitle = dkwxah_msgb_texts[0];
+ } break;
+ case ERROR_HOSTNAME : {
+
+#line 1402 "Dk4WxApplicationHelper.cpt"
+ msgbtext = dkwxah_msgb_texts[2];
+ msgbtitle = dkwxah_msgb_texts[0];
+ } break;
+ case ERROR_LANG_REG_ENC : {
+
+#line 1406 "Dk4WxApplicationHelper.cpt"
+ msgbtext = dkwxah_msgb_texts[3];
+ msgbtitle = dkwxah_msgb_texts[0];
+ } break;
+ case ERROR_LOGNAME : {
+
+#line 1410 "Dk4WxApplicationHelper.cpt"
+ msgbtext = dkwxah_msgb_texts[4];
+ msgbtitle = dkwxah_msgb_texts[0];
+ } break;
+ case ERROR_HOMEDIR : {
+
+#line 1414 "Dk4WxApplicationHelper.cpt"
+ msgbtext = dkwxah_msgb_texts[5];
+ msgbtitle = dkwxah_msgb_texts[0];
+ } break;
+ case ERROR_EXECUTABLE : {
+
+#line 1418 "Dk4WxApplicationHelper.cpt"
+ msgbtext = dkwxah_msgb_texts[6];
+ msgbtitle = dkwxah_msgb_texts[0];
+ } break;
+ case ERROR_EXEC_TOO_LONG : {
+
+#line 1422 "Dk4WxApplicationHelper.cpt"
+ msgbtext = dkwxah_msgb_texts[7];
+ msgbtitle = dkwxah_msgb_texts[0];
+ } break;
+ case ERROR_ARGUMENTS : {
+
+#line 1426 "Dk4WxApplicationHelper.cpt"
+ msgbtext = dkwxah_msgb_texts[8];
+ msgbtitle = dkwxah_msgb_texts[0];
+ } break;
+ }
+ if ((NULL != msgbtext) && (NULL != msgbtitle)) {
+ wxMessageBox(
+ msgbtext, msgbtitle, (wxOK | wxCENTRE | wxICON_ERROR)
+ );
+ }
+ InternalCleanup();
+ }
+
+
+#line 1438 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+
+
+void
+Dk4WxApplicationHelper::InternalCleanup(void)
+{
+ dk4_wx_string_table_t *wxsttptr;
+ dk4_wx_pref_t *pptr;
+
+
+#line 1449 "Dk4WxApplicationHelper.cpt"
+ bActive = false; // Object can not longer be used.
+ ppBasicStrings = NULL;
+ pcwxsArgv0 = NULL;
+ pcwxsVendor = NULL;
+ pcdksGroup = NULL;
+ if (NULL != sPrUser) {
+ if (NULL != iPrUser) {
+ dk4sto_it_reset(iPrUser);
+ do {
+ pptr = (dk4_wx_pref_t *)dk4sto_it_next(iPrUser);
+ if (NULL != pptr) { dk4wxpref_close(pptr); }
+ } while (NULL != pptr);
+ dk4sto_it_close(iPrUser);
+ iPrUser = NULL;
+ }
+ dk4sto_close(sPrUser);
+ sPrUser = NULL;
+ }
+ if (NULL != sPrSys) {
+ if (NULL != iPrSys) {
+ dk4sto_it_reset(iPrSys);
+ do {
+ pptr = (dk4_wx_pref_t *)dk4sto_it_next(iPrSys);
+ if (NULL != pptr) { dk4wxpref_close(pptr); }
+ } while (NULL != pptr);
+ dk4sto_it_close(iPrSys);
+ iPrSys = NULL;
+ }
+ dk4sto_close(sPrSys);
+ sPrSys = NULL;
+ }
+ if (NULL != sStt) {
+ if (NULL != iStt) {
+ dk4sto_it_reset(iStt);
+ do {
+ wxsttptr = (dk4_wx_string_table_t *)dk4sto_it_next(iStt);
+ if (NULL != wxsttptr) { dk4wxstt_close(wxsttptr); }
+ } while (NULL != wxsttptr);
+ dk4sto_it_close(iStt);
+ iStt = NULL;
+ }
+ dk4sto_close(sStt);
+ sStt = NULL;
+ }
+ nBasicStrings = 0;
+#if 0
+ /* Leave these integer variables as is.
+ */
+ iDkEncoding = DK4_ENCODING_ASCII;
+ iWxEncoding = DK4_ENCODING_ASCII;
+ iFiEncoding = DK4_FILE_ENCODING_ASCII;
+#endif
+ dk4mem_release(pdksRegion);
+ dk4mem_release(pdksLanguage);
+ dk4mem_release(pdksShare);
+ dk4mem_release(pdksSysconf);
+ dk4mem_release(pdksApp);
+ dk4mem_release(pdksHost);
+ dk4mem_release(pwxsApp);
+ dk4mem_release(pdksLogname);
+ dk4mem_release(pdksHome);
+
+
+#line 1511 "Dk4WxApplicationHelper.cpt"
+}
+
+
+
+void
+Dk4WxApplicationHelper::Cleanup(void)
+{
+
+
+#line 1519 "Dk4WxApplicationHelper.cpt"
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ InternalCleanup();
+ }
+
+
+#line 1524 "Dk4WxApplicationHelper.cpt"
+}
+
+
+
+/*
+ We do not need a critical section locker as the destructor
+ is invoked from the applications destructor. At this
+ we have no more top level windows or worker threads.
+*/
+Dk4WxApplicationHelper::~Dk4WxApplicationHelper()
+{
+
+
+#line 1536 "Dk4WxApplicationHelper.cpt"
+ InternalCleanup();
+
+
+#line 1538 "Dk4WxApplicationHelper.cpt"
+}
+
+
+
+/* ************************************************************************ */
+/* * * */
+/* * Internal functions. * */
+/* * These functions do not attempt synchronization. * */
+/* * * */
+/* ************************************************************************ */
+
+
+#line 1546 "Dk4WxApplicationHelper.cpt"
+
+
+bool
+Dk4WxApplicationHelper::InternalStringToWx(
+ wxChar *dptr, size_t dsz, const dkChar *sptr, dk4_er_t *erp
+)
+{
+ int res = 0;
+ bool back = false;
+
+
+#line 1556 "Dk4WxApplicationHelper.cpt"
+ res = dk4recwx_dkchar_to_wxchar(dptr,dsz,iWxEncoding,sptr,iDkEncoding,erp);
+ if (0 != res) { back = true; }
+
+
+#line 1559 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::InternalStringToDk(
+ dkChar *dptr, size_t dsz, const wxChar *sptr, dk4_er_t *erp
+)
+{
+ int res = 0;
+ bool back = false;
+
+
+#line 1572 "Dk4WxApplicationHelper.cpt"
+ res = dk4recwx_wxchar_to_dkchar(dptr,dsz,iDkEncoding,sptr,iWxEncoding,erp);
+ if (0 != res) { back = true; }
+
+
+#line 1575 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::InternalFindDataFile(
+ dkChar *fnb,
+ size_t szfnb,
+ dkChar const *sfn,
+ int maxpass,
+ bool aco
+)
+{
+ int passno = 0;
+ int res = 0;
+ bool back = false;
+
+
+#line 1593 "Dk4WxApplicationHelper.cpt"
+ for (passno = 0; ((passno < maxpass) && (!(back))); passno++) {
+ res = dk4fs_data_one(
+ fnb, szfnb, sfn,
+ pdksShare, pdksHome, pdksApp, pcdksGroup,
+ pdksLanguage, pdksRegion,
+ passno, ((aco) ? 1 : 0), NULL
+ );
+ if (0 != res) { back = true; }
+ }
+
+#line 1602 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+
+
+
+#if DK4_SIZEOF_WXCHAR != DK4_CHAR_SIZE
+
+bool
+Dk4WxApplicationHelper::InternalFindDataFile(
+ wxChar *fnb,
+ size_t szfnb,
+ dkChar const *sfn,
+ int maxpass,
+ bool aco
+)
+{
+ dkChar buf[DK4_MAX_PATH];
+ size_t szbuf = DK4_SIZEOF(buf,dkChar);
+ bool back = false;
+
+
+#line 1623 "Dk4WxApplicationHelper.cpt"
+ back = InternalFindDataFile(buf, szbuf, sfn, maxpass, aco);
+ if (back) {
+ back = InternalStringToWx(fnb, szfnb, buf, NULL);
+ }
+
+#line 1627 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+#endif
+
+
+
+const wxChar * const *
+Dk4WxApplicationHelper::InternalGetStringTable(
+ const dkChar *tableName,
+ size_t tableSize
+)
+{
+ dkChar fnb[DK4_MAX_PATH];
+ dk4_er_t e1;
+ dk4_er_t e2;
+ const wxChar * const *back = NULL;
+ dk4_wx_string_table_t *tabptr = NULL;
+ dk4_stream_t *strm = NULL;
+ size_t szfnb = DK4_SIZEOF(fnb,dkChar);
+
+
+#line 1648 "Dk4WxApplicationHelper.cpt"
+ tabptr = (dk4_wx_string_table_t *)dk4sto_it_find_like(iStt, tableName, 1);
+ if (NULL == tabptr) {
+ if (InternalFindDataFile(fnb, szfnb, tableName, DK4_FS_DATA_MAX_SYS, 1)) {
+ strm = dk4stream_open_file_reader(fnb, NULL);
+ if (NULL != strm) {
+ tabptr = dk4wxstt_open(tableName, tableSize, NULL);
+ if (NULL != tabptr) {
+ if (0 != dk4sto_add(sStt, tabptr, NULL)) {
+ dk4error_init(&e1);
+ dk4error_init(&e2);
+ if (!dk4wxstt_apply_stream(tabptr, strm, iWxEncoding, &e1, &e2)) {
+ dk4wxstt_shutdown(tabptr);
+ }
+ } else {
+ dk4wxstt_close(tabptr);
+ tabptr = NULL;
+ }
+ }
+ dk4stream_close(strm, NULL);
+ }
+ }
+ }
+ if (NULL != tabptr) {
+ if (tabptr->nstrings >= tableSize) {
+ back = (const wxChar * const *)(tabptr->strings);
+ }
+ }
+
+#line 1675 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::InternalSetMultiple(
+ const wxChar * const *names, long *array, size_t sz
+)
+{
+ wxConfig conf(pwxsApp, pcwxsVendor);
+ size_t i = 0;
+ bool back = false;
+
+
+#line 1689 "Dk4WxApplicationHelper.cpt"
+ if ((NULL != names) && (NULL != array) && (0 < sz)) {
+ back = true;
+ for (i = 0; i < sz; i++) {
+ if (!(conf.Write(names[i], array[i]))) {
+ back = false;
+ }
+ }
+ }
+
+#line 1697 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::InternalSetMultiple(
+ const wxChar * const *names, int *array, size_t sz
+)
+{
+ wxConfig conf(pwxsApp, pcwxsVendor);
+ size_t i = 0;
+ bool back = false;
+
+
+#line 1711 "Dk4WxApplicationHelper.cpt"
+ if ((NULL != names) && (NULL != array) && (0 < sz)) {
+ back = true;
+ for (i = 0; i < sz; i++) {
+ if (!(conf.Write(names[i], array[i]))) {
+ back = false;
+ }
+ }
+ }
+
+#line 1719 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::InternalSetMultiple(
+ const wxChar * const *names, bool *array, size_t sz
+)
+{
+ wxConfig conf(pwxsApp, pcwxsVendor);
+ size_t i = 0;
+ bool back = false;
+
+
+#line 1733 "Dk4WxApplicationHelper.cpt"
+ if ((NULL != names) && (NULL != array) && (0 < sz)) {
+ back = true;
+ for (i = 0; i < sz; i++) {
+ if (!(conf.Write(names[i], array[i]))) {
+ back = false;
+ }
+ }
+ }
+
+#line 1741 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::InternalSetMultiple(
+ const wxChar * const *names, double *array, size_t sz
+)
+{
+ wxConfig conf(pwxsApp, pcwxsVendor);
+ size_t i = 0;
+ bool back = false;
+
+
+#line 1755 "Dk4WxApplicationHelper.cpt"
+ if ((NULL != names) && (NULL != array) && (0 < sz)) {
+ back = true;
+ for (i = 0; i < sz; i++) {
+ if (!(conf.Write(names[i], array[i]))) {
+ back = false;
+ }
+ }
+ }
+
+#line 1763 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::InternalSetMultiple(
+ const wxChar * const *names, const wxChar * const *array, size_t sz
+)
+{
+ wxConfig conf(pwxsApp, pcwxsVendor);
+ size_t i = 0;
+ bool back = false;
+
+
+#line 1777 "Dk4WxApplicationHelper.cpt"
+ if ((NULL != names) && (NULL != array) && (0 < sz)) {
+ back = true;
+ for (i = 0; i < sz; i++) {
+ if (!(conf.Write(names[i], array[i]))) {
+ back = false;
+ }
+ }
+ }
+
+#line 1785 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::InternalGetMultiple(
+ const wxChar * const *names, long *array, size_t sz
+)
+{
+ wxConfig conf(pwxsApp, pcwxsVendor);
+ dk4_wx_pref_t *pptr = NULL;
+#if DK4_SIZEOF_WXCHAR > 1
+ const wchar_t *ep = NULL;
+#else
+ const char *ep = NULL;
+#endif
+ size_t i;
+ long l;
+ int res;
+ bool back = false;
+
+
+#line 1807 "Dk4WxApplicationHelper.cpt"
+ back = true;
+ for (i = 0; i < sz; i++) {
+ l = 0L;
+ if (conf.Read(names[i], &l)) {
+ array[i] = l;
+ } else {
+ pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrUser, names[i], 1);
+ if (NULL == pptr) {
+ pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrSys, names[i], 1);
+ }
+ if (NULL != pptr) {
+#if DK4_SIZEOF_WXCHAR > 1
+ res = dk4ma_input_wc_dec_long(&l, pptr->value, &ep, 1, NULL);
+#else
+ res = dk4ma_input_c8_dec_long(&l, pptr->value, &ep, 1, NULL);
+#endif
+ if (0 != res) {
+ array[i] = l;
+ } else {
+ back = false;
+ }
+ }
+ }
+ }
+
+
+#line 1832 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::InternalGetMultiple(
+ const wxChar * const *names, int *array, size_t sz
+)
+{
+ wxConfig conf(pwxsApp, pcwxsVendor);
+ dk4_wx_pref_t *pptr = NULL;
+#if DK4_SIZEOF_WXCHAR > 1
+ const wchar_t *ep = NULL;
+#else
+ const char *ep = NULL;
+#endif
+ size_t i;
+ long l;
+ int res;
+ bool back = false;
+
+
+#line 1854 "Dk4WxApplicationHelper.cpt"
+ back = true;
+ for (i = 0; i < sz; i++) {
+ l = 0L;
+ if (conf.Read(names[i], &l)) {
+ if (((long)(INT_MIN) <= l) && ((long)(INT_MAX) >= l)) {
+ array[i] = (int)l;
+ } else {
+ back = false;
+ }
+ } else {
+ pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrUser, names[i], 1);
+ if (NULL == pptr) {
+ pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrSys, names[i], 1);
+ }
+ if (NULL != pptr) {
+#if DK4_SIZEOF_WXCHAR > 1
+ res = dk4ma_input_wc_dec_long(&l, pptr->value, &ep, 1, NULL);
+#else
+ res = dk4ma_input_c8_dec_long(&l, pptr->value, &ep, 1, NULL);
+#endif
+ if (0 != res) {
+ if (((long)(INT_MIN) <= l) && ((long)(INT_MAX) >= l)) {
+ array[i] = (int)l;
+ } else {
+ back = false;
+ }
+ } else {
+ back = false;
+ }
+ }
+ }
+ }
+
+
+#line 1887 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::InternalGetMultiple(
+ const wxChar * const *names, bool *array, size_t sz
+)
+{
+ wxConfig conf(pwxsApp, pcwxsVendor);
+ dk4_wx_pref_t *pptr = NULL;
+ size_t i;
+ bool l;
+ bool back = false;
+
+
+#line 1903 "Dk4WxApplicationHelper.cpt"
+ back = true;
+ for (i = 0; i < sz; i++) {
+ l = 0L;
+
+
+#line 1907 "Dk4WxApplicationHelper.cpt"
+ if (conf.Read(names[i], &l)) {
+ array[i] = l;
+ } else {
+ pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrUser, names[i], 1);
+ if (NULL == pptr) {
+ pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrSys, names[i], 1);
+ }
+ if (NULL != pptr) {
+
+#line 1915 "Dk4WxApplicationHelper.cpt"
+
+
+#line 1916 "Dk4WxApplicationHelper.cpt"
+
+
+#line 1917 "Dk4WxApplicationHelper.cpt"
+#if DK4_SIZEOF_WXCHAR > 1
+
+
+#line 1919 "Dk4WxApplicationHelper.cpt"
+ if (0 != dk4strw_is_bool(pptr->value)) {
+ if (0 != dk4strw_is_on(pptr->value)) {
+ array[i] = true;
+
+#line 1922 "Dk4WxApplicationHelper.cpt"
+ } else {
+ array[i] = false;
+
+#line 1924 "Dk4WxApplicationHelper.cpt"
+ }
+ } else {
+
+#line 1926 "Dk4WxApplicationHelper.cpt"
+ back = false;
+ }
+#else
+
+
+#line 1930 "Dk4WxApplicationHelper.cpt"
+ if (0 != dk4str8_is_bool(pptr->value)) {
+ if (0 != dk4str8_is_on(pptr->value)) {
+ array[i] = true;
+
+#line 1933 "Dk4WxApplicationHelper.cpt"
+ } else {
+ array[i] = false;
+
+#line 1935 "Dk4WxApplicationHelper.cpt"
+ }
+ } else {
+ back = false;
+
+#line 1938 "Dk4WxApplicationHelper.cpt"
+ }
+#endif
+ } else {
+
+#line 1941 "Dk4WxApplicationHelper.cpt"
+ }
+ }
+ }
+
+
+#line 1945 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::InternalGetMultiple(
+ const wxChar * const *names, double *array, size_t sz
+)
+{
+ wxConfig conf(pwxsApp, pcwxsVendor);
+ dk4_wx_pref_t *pptr = NULL;
+#if DK4_SIZEOF_WXCHAR > 1
+ const wchar_t *ep = NULL;
+#else
+ const char *ep = NULL;
+#endif
+#if DK4_HAVE_SETLOCALE
+ char *oldloc = NULL;
+#endif
+ double l;
+ size_t i;
+ int res;
+ bool back = false;
+
+
+#line 1970 "Dk4WxApplicationHelper.cpt"
+ back = true;
+ for (i = 0; i < sz; i++) {
+ l = 0.0;
+ if (conf.Read(names[i], &l)) {
+ array[i] = l;
+ } else {
+ pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrUser, names[i], 1);
+ if (NULL == pptr) {
+ pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrSys, names[i], 1);
+ }
+ if (NULL != pptr) {
+#if DK4_HAVE_SETLOCALE
+ oldloc = setlocale(LC_NUMERIC, dk4wxah_kwnl_c8[0]);
+#endif
+#if DK4_SIZEOF_WXCHAR > 1
+ res = dk4ma_input_wc_double(&l, pptr->value, &ep, 1, NULL);
+#else
+ res = dk4ma_input_c8_double(&l, pptr->value, &ep, 1, NULL);
+#endif
+#if DK4_HAVE_SETLOCALE
+ if (NULL != oldloc) { setlocale(LC_NUMERIC, oldloc); }
+#endif
+ if (0 != res) {
+ array[i] = l;
+ } else {
+ back = false;
+ }
+ }
+ }
+ }
+
+
+#line 2001 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::InternalGetMultiple(
+ const wxChar * const *names, wxChar **array, size_t sz, bool ov
+)
+{
+ wxConfig conf(pwxsApp, pcwxsVendor);
+ dk4_wx_pref_t *pptr = NULL;
+ const wxChar *vptr = NULL;
+ wxChar *nptr = NULL;
+ size_t i;
+ bool back = false;
+
+
+#line 2018 "Dk4WxApplicationHelper.cpt"
+ back = true;
+ for (i = 0; i < sz; i++) {
+ if ((NULL == array[i]) || (ov)) {
+ wxString value = wxEmptyString;
+ if (conf.Read(names[i], &value)) {
+ vptr = value.c_str();
+ if (NULL != vptr) {
+ nptr = dk4strx_dup(vptr, NULL);
+ if (NULL != nptr) {
+ if (NULL != array[i]) { dk4mem_free(array[i]); }
+ array[i] = nptr;
+ } else {
+ back = false;
+ }
+ } else {
+ back = false;
+ }
+ } else {
+ pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrUser, names[i], 1);
+ if (NULL == pptr) {
+ pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrSys, names[i], 1);
+ }
+ if (NULL != pptr) {
+ nptr = dk4strx_dup(pptr->value, NULL);
+ if (nptr) {
+ if (NULL != array[i]) { dk4mem_free(array[i]); }
+ array[i] = nptr;
+ } else {
+ back = false;
+ }
+ }
+ }
+ }
+ }
+
+
+#line 2053 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+
+
+/* ************************************************************************ */
+/* * * */
+/* * Public interface. * */
+/* * The methods must * */
+/* * (a) synchronize access attempts from multiple threads and * */
+/* * (b) ensure the object is in a usable state. * */
+/* * * */
+/* ************************************************************************ */
+
+
+#line 2064 "Dk4WxApplicationHelper.cpt"
+
+
+bool
+Dk4WxApplicationHelper::FindDataFile(
+ dkChar *fnb,
+ size_t szfnb,
+ dkChar const *sfn,
+ int maxpass,
+ bool aco
+)
+{
+ bool back = false;
+
+
+#line 2077 "Dk4WxApplicationHelper.cpt"
+ if ((NULL != fnb) && (NULL != sfn) && (0 < szfnb)) {
+ wxCriticalSectionLocker lock(csProtect);
+ if (bActive) {
+ back = InternalFindDataFile(fnb, szfnb, sfn, maxpass, aco);
+ }
+ }
+
+#line 2083 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+
+
+
+#if DK4_SIZEOF_WXCHAR != DK4_CHAR_SIZE
+
+bool
+Dk4WxApplicationHelper::FindDataFile(
+ wxChar *fnb,
+ size_t szfnb,
+ dkChar const *sfn,
+ int maxpass,
+ bool aco
+)
+{
+ bool back = false;
+
+
+#line 2102 "Dk4WxApplicationHelper.cpt"
+ if ((NULL != fnb) && (NULL != sfn) && (0 < szfnb)) {
+ wxCriticalSectionLocker lock(csProtect);
+ if (bActive) {
+ back = InternalFindDataFile(fnb, szfnb, sfn, maxpass, aco);
+ }
+ }
+
+#line 2108 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+#endif
+
+
+
+int
+Dk4WxApplicationHelper::GetDkEncoding(void)
+{
+ int back = DK4_ENCODING_ASCII;
+
+
+#line 2120 "Dk4WxApplicationHelper.cpt"
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ back = iDkEncoding;
+ }
+
+#line 2124 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+
+
+int
+Dk4WxApplicationHelper::GetWxEncoding(void)
+{
+ int back = DK4_ENCODING_ASCII;
+
+
+#line 2134 "Dk4WxApplicationHelper.cpt"
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ back = iWxEncoding;
+ }
+
+#line 2138 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+
+
+int
+Dk4WxApplicationHelper::GetFiEncoding(void)
+{
+ int back = DK4_ENCODING_ASCII;
+
+
+#line 2148 "Dk4WxApplicationHelper.cpt"
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ back = iFiEncoding;
+ }
+
+#line 2152 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+
+
+const wxChar * const *
+Dk4WxApplicationHelper::GetStringTable(
+ const dkChar *tableName,
+ const wxChar * const *defaultTable
+)
+{
+ const wxChar * const *back = NULL;
+ size_t sz = 0;
+
+
+#line 2166 "Dk4WxApplicationHelper.cpt"
+ if ((NULL != tableName) && (NULL != defaultTable)) {
+ sz = Dk4WxApplicationHelper::StringTableSize(defaultTable);
+ if (0 < sz) {
+ wxCriticalSectionLocker lock(csProtect);
+ if (bActive) {
+ back = InternalGetStringTable(tableName, sz);
+ }
+ }
+ }
+ if (NULL == back) { back = defaultTable; }
+
+
+#line 2177 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+
+
+const wxChar *
+Dk4WxApplicationHelper::GetBasicString(
+ size_t numstr
+)
+{
+ const wxChar *back = NULL;
+
+
+#line 2189 "Dk4WxApplicationHelper.cpt"
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ if (bActive) {
+ if ((NULL != ppBasicStrings) && (0 < nBasicStrings)) {
+ if (numstr < nBasicStrings) {
+ back = ppBasicStrings[numstr];
+ }
+ }
+ }
+ }
+ if (NULL == back) {
+ if (numstr < (DK4_SIZEOF(dk4wxah_basic_strings,wxChar) - 1)) {
+ back = dk4wxah_basic_strings[numstr];
+ } else {
+ back = dk4wxah_empty_string;
+ }
+ }
+
+#line 2206 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+
+
+const wxChar * const *
+Dk4WxApplicationHelper::GetBasicStrings(
+ size_t *pNumBasicStrings
+)
+{
+ const wxChar * const *back = NULL;
+
+
+#line 2218 "Dk4WxApplicationHelper.cpt"
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ if (bActive) {
+ back = ppBasicStrings;
+ if (NULL != pNumBasicStrings) { *pNumBasicStrings = nBasicStrings; }
+ }
+ }
+ if (NULL == back) {
+ back = dk4wxah_basic_strings;
+ if (NULL != pNumBasicStrings) {
+ *pNumBasicStrings = DK4_SIZEOF(dk4wxah_basic_strings,wxChar) - 1;
+ }
+ }
+
+#line 2231 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::StringToWx(
+ wxChar *dptr, size_t dsz, const dkChar *sptr, dk4_er_t *erp
+)
+{
+ int res = 0;
+ int wxe = DK4_ENCODING_ASCII;
+ int dke = DK4_ENCODING_ASCII;
+ bool back = false;
+
+
+#line 2246 "Dk4WxApplicationHelper.cpt"
+ if ((NULL != dptr) && (NULL != sptr) && (0 < dsz)) {
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ wxe = iWxEncoding;
+ dke = iDkEncoding;
+ }
+ res = dk4recwx_dkchar_to_wxchar(dptr, dsz, wxe, sptr, dke, erp);
+ if (0 != res) { back = true; }
+ }
+
+#line 2255 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::StringToDk(
+ dkChar *dptr, size_t dsz, const wxChar *sptr, dk4_er_t *erp
+)
+{
+ int res = 0;
+ int wxe = DK4_ENCODING_ASCII;
+ int dke = DK4_ENCODING_ASCII;
+ bool back = false;
+
+
+#line 2270 "Dk4WxApplicationHelper.cpt"
+ if ((NULL != dptr) && (NULL != sptr) && (0 < dsz)) {
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ wxe = iWxEncoding;
+ dke = iDkEncoding;
+ }
+ res = dk4recwx_wxchar_to_dkchar(dptr, dsz, dke, sptr, wxe, erp);
+ if (0 != res) { back = true; }
+ }
+
+#line 2279 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::StringToChar(
+ char *dptr, size_t dsz, const wxChar *sptr, dk4_er_t *erp
+)
+{
+ int res = 0;
+ int wxe = DK4_ENCODING_ASCII;
+ int dke = DK4_ENCODING_ASCII;
+ bool back = false;
+ if ((NULL != dptr) && (NULL != sptr) && (0 < dsz)) {
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ wxe = iWxEncoding;
+ dke = iDkEncoding;
+ }
+ if (DK4_ENCODING_UTF8 != dke) {
+ if (DK4_ENCODING_ANSI != dke) {
+ dke = DK4_ENCODING_ASCII;
+ }
+ }
+ res = dk4recwx_wxchar_to_char(dptr, dsz, dke, sptr, wxe, erp);
+ if (0 != res) { back = true; }
+ }
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::SetMultiple(
+ const wxChar * const *names, long *array, size_t sz
+)
+{
+ bool back = false;
+
+
+#line 2319 "Dk4WxApplicationHelper.cpt"
+ if ((NULL != names) && (NULL != array) && (0 < sz)) {
+ wxCriticalSectionLocker lock(csProtect);
+ if (bActive) {
+ back = InternalSetMultiple(names, array, sz);
+ } else {
+ /* Object not active */
+ }
+ }
+
+#line 2327 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::SetMultiple(
+ const wxChar * const *names, int *array, size_t sz
+)
+{
+ bool back = false;
+
+
+#line 2339 "Dk4WxApplicationHelper.cpt"
+ if ((NULL != names) && (NULL != array) && (0 < sz)) {
+ wxCriticalSectionLocker lock(csProtect);
+ if (bActive) {
+ back = InternalSetMultiple(names, array, sz);
+ } else {
+ /* Object not active */
+ }
+ }
+
+#line 2347 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::SetMultiple(
+ const wxChar * const *names, bool *array, size_t sz
+)
+{
+ bool back = false;
+
+
+#line 2359 "Dk4WxApplicationHelper.cpt"
+ if ((NULL != names) && (NULL != array) && (0 < sz)) {
+ wxCriticalSectionLocker lock(csProtect);
+ if (bActive) {
+ back = InternalSetMultiple(names, array, sz);
+ } else {
+ /* Object not active */
+ }
+ }
+
+#line 2367 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::SetMultiple(
+ const wxChar * const *names, double *array, size_t sz
+)
+{
+ bool back = false;
+
+
+#line 2379 "Dk4WxApplicationHelper.cpt"
+ if ((NULL != names) && (NULL != array) && (0 < sz)) {
+ wxCriticalSectionLocker lock(csProtect);
+ if (bActive) {
+ back = InternalSetMultiple(names, array, sz);
+ } else {
+ /* Object not active */
+ }
+ }
+
+#line 2387 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::SetMultiple(
+ const wxChar * const *names, const wxChar * const *array, size_t sz
+)
+{
+ bool back = false;
+
+
+#line 2399 "Dk4WxApplicationHelper.cpt"
+ if ((NULL != names) && (NULL != array) && (0 < sz)) {
+ wxCriticalSectionLocker lock(csProtect);
+ if (bActive) {
+ back = InternalSetMultiple(names, array, sz);
+ } else {
+ /* Object not active */
+ }
+ }
+
+#line 2407 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::GetMultiple(
+ const wxChar * const *names, long *array, size_t sz
+)
+{
+ bool back = false;
+
+
+#line 2419 "Dk4WxApplicationHelper.cpt"
+ if ((NULL != names) && (NULL != array) && (0 < sz)) {
+ wxCriticalSectionLocker lock(csProtect);
+ if (bActive) {
+ back = InternalGetMultiple(names, array, sz);
+ } else {
+ /* Object not active */
+ }
+ }
+
+#line 2427 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::GetMultiple(
+ const wxChar * const *names, int *array, size_t sz
+)
+{
+ bool back = false;
+
+
+#line 2439 "Dk4WxApplicationHelper.cpt"
+ if ((NULL != names) && (NULL != array) && (0 < sz)) {
+ wxCriticalSectionLocker lock(csProtect);
+ if (bActive) {
+ back = InternalGetMultiple(names, array, sz);
+ } else {
+ /* Object not active */
+ }
+ }
+
+#line 2447 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::GetMultiple(
+ const wxChar * const *names, bool *array, size_t sz
+)
+{
+ bool back = false;
+
+
+#line 2459 "Dk4WxApplicationHelper.cpt"
+ if ((NULL != names) && (NULL != array) && (0 < sz)) {
+ wxCriticalSectionLocker lock(csProtect);
+ if (bActive) {
+ back = InternalGetMultiple(names, array, sz);
+ } else {
+ /* Object not active */
+ }
+ }
+
+#line 2467 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::GetMultiple(
+ const wxChar * const *names, double *array, size_t sz
+)
+{
+ bool back = false;
+
+
+#line 2479 "Dk4WxApplicationHelper.cpt"
+ if ((NULL != names) && (NULL != array) && (0 < sz)) {
+ wxCriticalSectionLocker lock(csProtect);
+ if (bActive) {
+ back = InternalGetMultiple(names, array, sz);
+ } else {
+ /* Object not active */
+ }
+ }
+
+#line 2487 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::GetMultiple(
+ const wxChar * const *names, wxChar **array, size_t sz, bool ov
+)
+{
+ bool back = false;
+
+
+#line 2499 "Dk4WxApplicationHelper.cpt"
+ if ((NULL != names) && (NULL != array) && (0 < sz)) {
+ wxCriticalSectionLocker lock(csProtect);
+ if (bActive) {
+ back = InternalGetMultiple(names, array, sz, ov);
+ } else {
+ /* Object not active */
+ }
+ }
+
+#line 2507 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+
+
+/* ************************************************************************ */
+/* * * */
+/* * Static class functions. * */
+/* * * */
+/* ************************************************************************ */
+
+
+#line 2515 "Dk4WxApplicationHelper.cpt"
+
+
+void
+Dk4WxApplicationHelper::CorrectPosition(
+ int & x, int & y, int & w, int & h
+)
+{
+ wxSize scsz;
+
+
+#line 2524 "Dk4WxApplicationHelper.cpt"
+ scsz = wxGetDisplaySize();
+ if (0 > x) { x = (scsz.x - w) / 2; }
+ if (0 > y) { y = (scsz.y - h) / 2; }
+ if (scsz.x < (x + w)) { x = scsz.x - w; }
+ if (scsz.y < (y + h)) { y = scsz.y - h; }
+ if (0 > x) { x = 0; }
+ if (0 > y) { y = 0; }
+
+
+#line 2532 "Dk4WxApplicationHelper.cpt"
+}
+
+
+
+void
+Dk4WxApplicationHelper::CorrectPosition(
+ wxWindow & wnd
+)
+{
+ int x, y, w, h;
+
+
+#line 2543 "Dk4WxApplicationHelper.cpt"
+ wnd.GetPosition(&x, &y);
+ wnd.GetSize(&w, &h);
+ Dk4WxApplicationHelper::CorrectPosition(x, y, w, h);
+ wnd.SetSize(x, y, w, h);
+
+
+#line 2548 "Dk4WxApplicationHelper.cpt"
+}
+
+
+
+void
+Dk4WxApplicationHelper::ChooseChildPosition(
+ const wxWindow & p, wxWindow & c, bool beside
+)
+{
+ wxSize scsz = wxGetDisplaySize();
+ int px = 0;
+ int py = 0;
+ int pw = 0;
+ int ph = 0;
+ int cx = 0;
+ int cy = 0;
+ int cw = 0;
+ int ch = 0;
+ bool done = false;
+ bool findy = false;
+
+
+#line 2569 "Dk4WxApplicationHelper.cpt"
+ p.GetPosition(&px, &py);
+ p.GetSize(&pw, &ph);
+ c.GetSize(&cw, &ch);
+ if (beside) {
+ /* Attempt right side */
+ if (scsz.x > px + pw + cw) {
+ cx = px + pw;
+ done = true;
+ findy = true;
+ }
+ /* Attempt bottom side */
+ if (!done) {
+ if (scsz.y > py + ph + ch) {
+ cy = py + ph;
+ done = true;
+ }
+ }
+ /* Attempt left side */
+ if (!done) {
+ if (px > cw) {
+ cx = px - cw;
+ done = true;
+ findy = true;
+ }
+ }
+ /* Attempt top side */
+ if (!done) {
+ if (py < ch) {
+ cy = py - ch;
+ done = true;
+ }
+ }
+ if (done) {
+ if (findy) {
+ if (scsz.y > (py + ch)) {
+ cy = py;
+ } else {
+ if (0 <= (py + ph - ch)) {
+ cy = py + ph - ch;
+ } else {
+ cy = py + (ph - ch) / 2;
+ if (scsz.y <= (cy + ch)) {
+ cy = scsz.y - ch - 1;
+ }
+ if (0 > cy) {
+ cy = 0;
+ }
+ }
+ }
+ } else {
+ if (scsz.x > (px + cw)) {
+ cx = px;
+ } else {
+ if (0 <= (px + pw - cw)) {
+ cx = px + pw - cw;
+ } else {
+ cx = px + (pw - cw) / 2;
+ if (scsz.x <= (cx + cw)) {
+ cx = scsz.x - cw - 1;
+ }
+ if (0 > cx) {
+ cx = 0;
+ }
+ }
+ }
+ }
+ c.SetSize(cx, cy, cw, ch);
+ }
+ }
+ if (!done) {
+ cx = px + (pw - cw) / 2;
+ cy = py + (ph - ch) / 2;
+ Dk4WxApplicationHelper::CorrectPosition(cx, cy, cw, ch);
+ c.SetSize(cx, cy, cw, ch);
+ }
+
+
+#line 2645 "Dk4WxApplicationHelper.cpt"
+}
+
+
+
+size_t
+Dk4WxApplicationHelper::StringTableSize(const wxChar * const *sttptr)
+{
+ size_t back = 0;
+
+
+#line 2654 "Dk4WxApplicationHelper.cpt"
+ if (NULL != sttptr) {
+ while (NULL != *(sttptr++)) { back++; }
+ }
+
+#line 2657 "Dk4WxApplicationHelper.cpt"
+ return back;
+}
+
+
+
+void
+Dk4WxApplicationHelper::ReleaseWxcharStringArray(
+ wxChar **array, size_t sz, bool ea
+)
+{
+ wxChar **ap;
+ if ((NULL != array) && (0 < sz)) {
+ ap = array;
+ while (0 < sz--) {
+ dk4mem_release(*array);
+ array++;
+ }
+ if (ea) { dk4mem_free(ap); }
+ }
+}
+
diff --git a/support/dktools/Dk4WxApplicationHelper.cpt b/support/dktools/Dk4WxApplicationHelper.cpt
new file mode 100644
index 0000000000..f81e068a47
--- /dev/null
+++ b/support/dktools/Dk4WxApplicationHelper.cpt
@@ -0,0 +1,2677 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file Dk4WxApplicationHelper.h The Dk4WxApplicationHelper
+ class.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4CONST_H_INCLUDED
+#include "dk4const.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4STO_H_INCLUDED
+#include "dk4sto.h"
+#endif
+
+#ifndef DK4WXCS_H_INCLUDED
+#include "dk4wxcs.h"
+#endif
+
+#ifndef DK4FSH_H_INCLUDED
+#include "dk4fs.h"
+#endif
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include "wx/wxprec.h"
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#ifndef WX_WX_H_INCLUDED
+#include "wx/wx.h"
+#define WX_WX_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef WX_CONFIG_H_INCLUDED
+#include <wx/config.h>
+#define WX_CONFIG_H_INCLUDED 1
+#endif
+
+#ifndef WX_FILENAME_H_INCLUDED
+#include <wx/filename.h>
+#define WX_FILENAME_H_INCLUDED 1
+#endif
+
+#ifndef WX_THREAD_H_INCLUDED
+#include <wx/thread.h>
+#define WX_THREAD_H_INCLUDED 1
+#endif
+
+#ifndef DK4WXSTT_H_INCLUDED
+#include "dk4wxstt.h"
+#endif
+
+
+/** Application helper.
+ Each application should have one application helper object
+ as the member of the wxApp-derived application class.
+ In the applications OnInit() method call the Initialize() method.
+*/
+class Dk4WxApplicationHelper
+{
+ protected:
+
+ /** Synchronization for access from multiple threads.
+ */
+ wxCriticalSection csProtect;
+
+ /** The basic strings for GUIs.
+ */
+ const wxChar * const *ppBasicStrings;
+
+ /** Software vendor name.
+ */
+ const wxChar *pcwxsVendor;
+
+ /** First command line argument.
+ */
+ const wxChar *pcwxsArgv0;
+
+ /** Application group name.
+ */
+ const dkChar *pcdksGroup;
+
+ /** Application name.
+ */
+ wxChar *pwxsApp;
+
+ /** Host name.
+ */
+ dkChar *pdksHost;
+
+ /** Users login name.
+ */
+ dkChar *pdksLogname;
+
+ /** Home directory.
+ */
+ dkChar *pdksHome;
+
+ /** Application name.
+ */
+ dkChar *pdksApp;
+
+ /** System configuration directory.
+ */
+ dkChar *pdksSysconf;
+
+ /** Data directory.
+ */
+ dkChar *pdksShare;
+
+ /** Users language.
+ */
+ dkChar *pdksLanguage;
+
+ /** Users region.
+ */
+ dkChar *pdksRegion;
+
+ /** String tables storage.
+ */
+ dk4_sto_t *sStt;
+
+ /** String tables storage iterator.
+ */
+ dk4_sto_it_t *iStt;
+
+ /** System preferences storage.
+ */
+ dk4_sto_t *sPrSys;
+
+ /** System preferences storage iterator.
+ */
+ dk4_sto_it_t *iPrSys;
+
+ /** User preferences storage.
+ */
+ dk4_sto_t *sPrUser;
+
+ /** User preferences storage iterator.
+ */
+ dk4_sto_it_t *iPrUser;
+
+ /** Number of strings in the ppBasicStrings array.
+ */
+ size_t nBasicStrings;
+
+ /** Encoding for dkChar strings.
+ */
+ int iDkEncoding;
+
+ /** Encoding for wxChar strings.
+ */
+ int iWxEncoding;
+
+ /** Expected encoding for file input.
+ */
+ int iFiEncoding;
+
+ /** Flag: Controller is set up and can be used.
+ */
+ bool bActive;
+
+ protected:
+
+ /** Clean up internal data structures.
+ */
+ void
+ InternalCleanup(void);
+
+
+ /** Search for data file.
+ @param fnb File name buffer.
+ @param szfnb Buffer size (number of dkChar).
+ @param sfn Short file name.
+ @param maxpass Maximum pass number for search.
+ @param aco Flag: Allow compressed versions.
+ @return True if the file was found (name in fnb), false otherwise.
+ */
+ bool
+ InternalFindDataFile(
+ dkChar *fnb,
+ size_t szfnb,
+ dkChar const *sfn,
+ int maxpass,
+ bool aco
+ );
+
+#if DK4_SIZEOF_WXCHAR != DK4_CHAR_SIZE
+
+ /** Search for data file.
+ @param fnb File name buffer.
+ @param szfnb Buffer size (number of wxChar).
+ @param sfn Short file name.
+ @param maxpass Maximum pass number for search.
+ @param aco Flag: Allow compressed versions.
+ @return True if the file was found (name in fnb), false otherwise.
+ */
+ bool
+ InternalFindDataFile(
+ wxChar *fnb,
+ size_t szfnb,
+ dkChar const *sfn,
+ int maxpass,
+ bool aco
+ );
+
+#endif
+
+ /** Convert dkChar string to wxChar string.
+ @param dptr Result buffer.
+ @param dsz Buffer size (number of wxChar).
+ @param sptr Source string.
+ @param erp Error report, may be NULL.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or sptr is NULL or dsz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dptr is too small,
+ - DK4_E_SYNTAX<br>
+ if a non-recodable character was found.
+ */
+ bool
+ InternalStringToWx(
+ wxChar *dptr, size_t dsz, const dkChar *sptr, dk4_er_t *erp
+ );
+
+ /** Convert wxChar string to dkChar string.
+ @param dptr Result buffer.
+ @param dsz Result buffer size (number of dkChar).
+ @param sptr Source string.
+ @param erp Error report, may be NULL.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or sptr is NULL or dsz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dptr is too small,
+ - DK4_E_SYNTAX<br>
+ if a non-recodable character was found.
+ */
+ bool
+ InternalStringToDk(
+ dkChar *dptr, size_t dsz, const wxChar *sptr, dk4_er_t *erp
+ );
+
+ /** Retrieve a string table.
+ @param tableName Short string table file name.
+ @param tableSize Minimum number of elements required in table.
+ @return Pointer to string table found or NULL.
+ */
+ const wxChar * const *
+ InternalGetStringTable(
+ const dkChar *tableName,
+ size_t tableSize
+ );
+
+ /** Save multiple long values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @return True on success, false on error.
+ */
+ bool
+ InternalSetMultiple(const wxChar * const *names, long *array, size_t sz);
+
+ /** Save multiple int values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @return True on success, false on error.
+ */
+ bool
+ InternalSetMultiple(const wxChar * const *names, int *array, size_t sz);
+
+ /** Save multiple bool values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @return True on success, false on error.
+ */
+ bool
+ InternalSetMultiple(const wxChar * const *names, bool *array, size_t sz);
+
+ /** Save multiple double values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @return True on success, false on error.
+ */
+ bool
+ InternalSetMultiple(const wxChar * const *names, double *array, size_t sz);
+
+ /** Save multiple string values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @return True on success, false on error.
+ */
+ bool
+ InternalSetMultiple(
+ const wxChar * const *names, const wxChar * const *array, size_t sz
+ );
+
+ /** Retrieve multiple long values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @return True on success, false on error.
+ */
+ bool
+ InternalGetMultiple(const wxChar * const *names, long *array, size_t sz);
+
+ /** Retrieve multiple int values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @return True on success, false on error.
+ */
+ bool
+ InternalGetMultiple(const wxChar * const *names, int *array, size_t sz);
+
+ /** Retrieve multiple bool values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @return True on success, false on error.
+ */
+ bool
+ InternalGetMultiple(const wxChar * const *names, bool *array, size_t sz);
+
+ /** Retrieve multiple double values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @return True on success, false on error.
+ */
+ bool
+ InternalGetMultiple(const wxChar * const *names, double *array, size_t sz);
+
+ /** Retrieve multiple string values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @param ov Flag: Overwrite existing strings.
+ Memory for already existing strings is freed, memory for the new
+ found string is allocated if the flag is set. Existing strings
+ are left untouched if the flag is not set.
+ @return True on success, false on error.
+ */
+ bool
+ InternalGetMultiple(
+ const wxChar * const *names, wxChar **array, size_t sz, bool ov = true
+ );
+
+ public:
+
+ /** Default constructor.
+ */
+ Dk4WxApplicationHelper();
+
+ /** Destructor.
+ */
+ ~Dk4WxApplicationHelper();
+
+ /** Initialize before used, called from the applications OnInit() method.
+ If this method returns false, the OnInit() method should return
+ false too.
+ @param argv0 First command line argument.
+ @param vendorName Software vendor name.
+ @param groupName Application group name.
+ @param erp Error report, may be NULL.
+ @return True if initialized successfully, false otherwise.
+
+ Error codes:
+ - DK4_E_NOT_FOUND<br>
+ if the system function(s) failed to find the name of the
+ file currently executed or the users home directory
+ or the users home directory or login name,
+ - DK4_E_SYSTEM<br>
+ if the function failed to find the current working directory,
+ - DK4_E_SYNTAX<br>
+ if there are string conversion problems,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the internal buffer is too small to hold the file name
+ of the executed file, the users home directory, login name
+ or a conversion buffer is too small,
+ - DK4_E_SYNTAX<br>
+ if a Windows registry entry differs from the expected type.
+ - DK4_E_MATH_OVERFLOW<br>
+ if a numeric overflow occured in a memory allocation size
+ calculation,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if a memory allocation attempt failed due to insufficient memory.
+
+ */
+ bool
+ Initialize(
+ const wxChar *argv0,
+ const wxChar *vendorName,
+ const dkChar *groupName,
+ dk4_er_t *erp = NULL
+ );
+
+ /** Clean up internal data structures.
+ You should call this from the applications OnExit() method.
+ */
+ void
+ Cleanup(void);
+
+ /** Search for data file.
+ @param fnb File name buffer.
+ @param szfnb Buffer size (number of dkChar).
+ @param sfn Short file name.
+ @param maxpass Maximum pass number for search.
+ @param aco Flag: Allow compressed versions.
+ @return True if the file was found (name in fnb), false otherwise.
+ */
+ bool
+ FindDataFile(
+ dkChar *fnb,
+ size_t szfnb,
+ dkChar const *sfn,
+ int maxpass = DK4_FS_DATA_MAX_SYS,
+ bool aco = false
+ );
+
+#if DK4_SIZEOF_WXCHAR != DK4_CHAR_SIZE
+
+ /** Search for data file.
+ @param fnb File name buffer.
+ @param szfnb Buffer size (number of wxChar).
+ @param sfn Short file name.
+ @param maxpass Maximum pass number for search.
+ @param aco Flag: Allow compressed versions.
+ @return True if the file was found (name in fnb), false otherwise.
+ */
+ bool
+ FindDataFile(
+ wxChar *fnb,
+ size_t szfnb,
+ dkChar const *sfn,
+ int maxpass = DK4_FS_DATA_MAX_SYS,
+ bool aco = false
+ );
+
+#endif
+
+ /** Retrieve dkChar encoding.
+ @return Encoding.
+ */
+ int
+ GetDkEncoding(void);
+
+ /** Retrieve wxChar encoding.
+ @return Encoding.
+ */
+ int
+ GetWxEncoding(void);
+
+ /** Retrieve expected input encoding when reading files.
+ @return Encoding.
+ */
+ int
+ GetFiEncoding(void);
+
+ /** Retrieve a string table.
+ @param tableName Short string table file name.
+ @param defaultTable Default strings to use if not found.
+ @return Pointer to string table found or defaultTable.
+ */
+ const wxChar * const *
+ GetStringTable(
+ const dkChar *tableName,
+ const wxChar * const *defaultTable
+ );
+
+ /** Retrieve one of the basic strings.
+ @param numstr Index of string in basic strings array.
+ @return String pointer on success, NULL on error (index out of range).
+ */
+ const wxChar *
+ GetBasicString(size_t numstr);
+
+ /** Retrieve entire basic strings array.
+ @param pNumBasicStrings Address of variable to store the
+ array length, may be NULL.
+ @return Pointer to array of basic strings.
+ */
+ const wxChar * const *
+ GetBasicStrings(size_t *pNumBasicStrings = NULL);
+
+ /** Convert dkChar string to wxChar string.
+ @param dptr Result buffer.
+ @param dsz Buffer size (number of wxChar).
+ @param sptr Source string.
+ @param erp Error report, may be NULL.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or sptr is NULL or dsz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dptr is too small,
+ - DK4_E_SYNTAX<br>
+ if a non-recodable character was found.
+ */
+ bool
+ StringToWx(
+ wxChar *dptr, size_t dsz, const dkChar *sptr, dk4_er_t *erp = NULL
+ );
+
+ /** Convert wxChar string to dkChar string.
+ @param dptr Result buffer.
+ @param dsz Result buffer size (number of dkChar).
+ @param sptr Source string.
+ @param erp Error report, may be NULL.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or sptr is NULL or dsz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dptr is too small,
+ - DK4_E_SYNTAX<br>
+ if a non-recodable character was found.
+ */
+ bool
+ StringToDk(
+ dkChar *dptr, size_t dsz, const wxChar *sptr, dk4_er_t *erp = NULL
+ );
+
+ /** Convert wxChar string to char string.
+ @param dptr Result buffer.
+ @param dsz Result buffer size (number of char).
+ @param sptr Source string.
+ @param erp Error report, may be NULL.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or sptr is NULL or dsz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dptr is too small,
+ - DK4_E_SYNTAX<br>
+ if a non-recodable character was found.
+ */
+ bool
+ StringToChar(
+ char *dptr, size_t dsz, const wxChar *sptr, dk4_er_t *erp = NULL
+ );
+
+ /** Save multiple long values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @return True on success, false on error.
+ */
+ bool
+ SetMultiple(const wxChar * const *names, long *array, size_t sz);
+
+ /** Save multiple int values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @return True on success, false on error.
+ */
+ bool
+ SetMultiple(const wxChar * const *names, int *array, size_t sz);
+
+ /** Save multiple bool values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @return True on success, false on error.
+ */
+ bool
+ SetMultiple(const wxChar * const *names, bool *array, size_t sz);
+
+ /** Save multiple double values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @return True on success, false on error.
+ */
+ bool
+ SetMultiple(const wxChar * const *names, double *array, size_t sz);
+
+ /** Save multiple string values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @return True on success, false on error.
+ */
+ bool
+ SetMultiple(
+ const wxChar * const *names, const wxChar * const *array, size_t sz
+ );
+
+ /** Retrieve multiple long values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @return True on success, false on error.
+ */
+ bool
+ GetMultiple(const wxChar * const *names, long *array, size_t sz);
+
+ /** Retrieve multiple int values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @return True on success, false on error.
+ */
+ bool
+ GetMultiple(const wxChar * const *names, int *array, size_t sz);
+
+ /** Retrieve multiple bool values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @return True on success, false on error.
+ */
+ bool
+ GetMultiple(const wxChar * const *names, bool *array, size_t sz);
+
+ /** Retrieve multiple double values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @return True on success, false on error.
+ */
+ bool
+ GetMultiple(const wxChar * const *names, double *array, size_t sz);
+
+ /** Retrieve multiple string values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @param ov Flag: Overwrite existing strings.
+ Memory for already existing strings is freed, memory for the new
+ found string is allocated if the flag is set. Existing strings
+ are left untouched if the flag is not set.
+ @return True on success, false on error.
+ */
+ bool
+ GetMultiple(
+ const wxChar * const *names, wxChar **array, size_t sz, bool ov = true
+ );
+
+ /** Correct top level frame position.
+ @param x Window x position.
+ @param y Window y position.
+ @param w Window width.
+ @param h Window height.
+ */
+ static
+ void
+ CorrectPosition(int & x, int & y, int & w, int & h);
+
+ /** Correct position of a top level window (frame or dialog).
+ @param w Window to correct.
+ */
+ static
+ void
+ CorrectPosition(wxWindow & w);
+
+ /** Choose position for a child top level window (frame or dialog).
+ @param p Parent window, unchanged.
+ @param c Child window, position is set.
+ @param beside Flag: Position child beside parent, not on top.
+ */
+ static
+ void
+ ChooseChildPosition(
+ const wxWindow & p, wxWindow & c, bool beside = false
+ );
+
+ /** Find string table size (number of strings in table).
+ @param sttptr String table to find size for.
+ @return Size of string table.
+ */
+ static
+ size_t
+ StringTableSize(const wxChar * const *sttptr);
+
+ /** Release array of wxChar strings.
+ @param array Array, array contents is to release.
+ @param sz Array size.
+ @param ea Flag: After releasing contents, release array itself.
+ */
+ static
+ void
+ ReleaseWxcharStringArray(wxChar **array, size_t sz, bool ea = false);
+
+};
+
+
+%% module
+
+#include "Dk4WxApplicationHelper.h"
+
+#include "dk4mem.h"
+#include "dk4enc.h"
+#include "dk4strd.h"
+#include "dk4strx.h"
+#include "dk4recwx.h"
+#include "dk4wxpref.h"
+#include "dk4wxstt.h"
+#include "dk4hnamed.h"
+#include "dk4loc.h"
+#include "dk4user.h"
+#include "dk4mpl.h"
+#include "dk4vers.h"
+#include "dk4exepd.h"
+#include "dk4inst.h"
+#include "dk4pathd.h"
+#if DK4_SIZEOF_WXCHAR > 1
+#include "dk4strw.h"
+#include "dk4maiwdil.h"
+#include "dk4maiwdbl.h"
+#else
+#include "dk4str8.h"
+#include "dk4mai8dil.h"
+#include "dk4mai8dbl.h"
+#endif
+
+
+
+$!trace-include
+
+
+
+$*
+ Type definitions.
+$*
+
+
+
+/** Pointer to constant wxChar.
+*/
+typedef const wxChar *PCWXCHAR;
+
+
+
+/** Error codes in Initialize().
+*/
+enum {
+ /** No error occured.
+ */
+ ERROR_NONE = 0,
+
+ /** Not enough memory.
+ */
+ ERROR_MEMORY ,
+
+ /** Failed to find host name.
+ */
+ ERROR_HOSTNAME ,
+
+ /** Failed to find localization settings.
+ */
+ ERROR_LANG_REG_ENC ,
+
+ /** Failed to find login name.
+ */
+ ERROR_LOGNAME ,
+
+ /** Failed to find home directory.
+ */
+ ERROR_HOMEDIR ,
+
+ /** Failed to find path name of executable.
+ */
+ ERROR_EXECUTABLE ,
+
+ /** Executable file name too long.
+ */
+ ERROR_EXEC_TOO_LONG ,
+
+ /** Invalid arguments were passed to Initialize().
+ */
+ ERROR_ARGUMENTS ,
+};
+
+
+
+$*
+ Variables.
+$*
+
+
+
+/** Empty string, returned for all strings not found.
+*/
+static const wxChar dk4wxah_empty_string[] = { wxT("") };
+
+
+
+/** File name separator string
+*/
+static const dkChar dk4wxah_fnsep_str[] = {
+#if DK4_ON_WINDOWS
+dkT("\\")
+#else
+dkT("/")
+#endif
+} ;
+
+
+
+/** Texts used in error message boxes in the Initialize() function.
+*/
+static const wxChar * const dkwxah_msgb_texts[] = {
+$!string-table macro=wxT
+#
+# 0 Initialization failed!
+#
+Initialization failed!
+#
+# 1 Not enough memory!
+#
+Not enough memory!
+#
+# 2 Failed to find current host name!
+#
+Failed to find current host name!
+#
+# 3 Failed to find language, region, and encoding settings!
+#
+Failed to find language, region, and encoding settings!
+#
+# 4 Failed to find users login name!
+#
+Failed to find users login name!
+#
+# 5 Failed to find users home directory!
+#
+Failed to find users home directory!
+#
+# 6 Failed to find executable file name!
+#
+Failed to find executable file name!
+#
+# 7 Executable file name too long!
+#
+Executable file name too long!
+#
+# 8 Illegal arguments (NULL pointers) to Initialize() function!
+#
+Illegal arguments (NULL pointers) to Initialize() function!
+$!end
+};
+
+
+
+/** Constant text keywords used by module, not localized.
+*/
+static const dkChar * const dk4wxah_kwnl_dk[] = {
+$!string-table macro=dkT
+#
+# 0 String table file name for basic strings.
+#
+dk4wxbase.str
+$!end
+};
+
+
+
+/** Constant text strings used by the module, not localized.
+*/
+static const char * const dk4wxah_kwnl_c8[] = {
+$!string-table
+C
+$!end
+};
+
+
+
+/** Final directory names for good installations.
+*/
+static const dkChar * const dk4wxah_final_directories[] = {
+$!string-table macro=dkT
+bin
+sbin
+libexec
+lib
+$!end
+};
+
+
+
+/** New final directory names to append.
+*/
+static const dkChar * const dk4wxah_new_directories[] = {
+$!string-table macro=dkT
+etc
+share
+$!end
+};
+
+
+
+/** Basic strings, replaced by localized texts later.
+*/
+static const wxChar * const dk4wxah_basic_strings[] = {
+$!string-table macro=wxT
+#
+# 0 Dialog box title: Help file not found
+#
+Help file not found
+#
+# 1 Dialog box text: Help file not found!
+#
+The file containing online help text was not found on your computer!
+#
+# 2 Progress dialog title
+#
+Processing in progress
+#
+# 3 4 5 Progress dialog cancel button, tooltip and response
+#
+Cancel
+Abort current operation
+Abortion scheduled, wait please!
+#
+# 6 7 8 Further error messages printed by Dk4WxHelpController
+#
+Error
+Not enough memory (RAM)!
+Illegal arguments in Dk4WxHelpController constructor (bug)!
+$!end
+};
+
+
+
+$*
+ Internal tool functions, not object-oriented.
+$*
+
+
+
+/** Check whether a directory or file name ends in one of
+ the names mentioned in array.
+ @param dirname Directory name to check.
+ @param array String array containing name ends.
+ @return 1 on success with prefix in dirname, 0 on error.
+*/
+static
+int
+dk4wxapplicationhelper_isinsub(dkChar *dirname, const dkChar * const *array)
+{
+ dkChar *p1;
+ dkChar *p2;
+ int cc; /* Flag: Can continue */
+ int back = 0; /* Function result */
+ $? "+ dk4wxapplicationhelper_isinsub"
+ do {
+ cc = 0;
+ p1 = dirname; p2 = NULL;
+ while (dkT('\0') != *p1) {
+ if ((dkT('/') == *p1) || (dkT('\\') == *p1)) { p2 = p1; }
+ p1++;
+ }
+ if (NULL != p2) {
+ *(p2++) = dkT('\0');
+ cc = 1;
+#if DK4_HAVE_CASE_INSENSITIVE_PATHNAMES
+ if (0 <= dk4str_array_index(array, p2, 0))
+#else
+ if (0 <= dk4str_array_index(array, p2, 1))
+#endif
+ {
+ back = 1;
+ cc = 0;
+ }
+ } else {
+ }
+ } while ((1 == cc) && (0 == back));
+ $? "- dk4wxapplicationhelper_isinsub %d", back
+ return back;
+}
+
+
+
+$*
+ Constructor, destructor, initialization and cleanup.
+$*
+
+
+
+Dk4WxApplicationHelper::Dk4WxApplicationHelper()
+{
+ /* Set all member variables to "resource not available".
+ Real initialization is in the Initialize() method.
+ */
+ $? "+ Dk4WxApplicationHelper"
+ ppBasicStrings = NULL;
+ pcwxsArgv0 = NULL;
+ pcwxsVendor = NULL;
+ pcdksGroup = NULL;
+ pwxsApp = NULL;
+ pdksHost = NULL;
+ pdksLogname = NULL;
+ pdksHome = NULL;
+ pdksApp = NULL;
+ pdksSysconf = NULL;
+ pdksShare = NULL;
+ pdksLanguage = NULL;
+ pdksRegion = NULL;
+ sStt = NULL;
+ iStt = NULL;
+ sPrSys = NULL;
+ iPrSys = NULL;
+ sPrUser = NULL;
+ iPrUser = NULL;
+ nBasicStrings = 0;
+ iDkEncoding = DK4_ENCODING_ASCII;
+ iWxEncoding = DK4_ENCODING_ASCII;
+ iFiEncoding = DK4_FILE_ENCODING_ASCII;
+ bActive = false;
+ $? "- Dk4WxApplicationHelper"
+}
+
+
+/*
+ We do not need a critical section locker as Initialize()
+ is invoked from the applications OnInit() method. At this
+ time there is no top level window or worker thread yet.
+*/
+bool
+Dk4WxApplicationHelper::Initialize(
+ const wxChar *argv0,
+ const wxChar *vendorName,
+ const dkChar *groupName,
+ dk4_er_t *erp
+)
+{
+ dkChar labuf[DK4_MAX_PATH];
+ dkChar rebuf[DK4_MAX_PATH];
+ wxChar anbuf[DK4_MAX_PATH];
+ const wxChar *msgbtext = NULL;
+ const wxChar *msgbtitle = NULL;
+ dkChar *p1;
+ dkChar *p2;
+#if DK4_ON_WINDOWS
+ dkChar *p4;
+#endif
+ size_t szrebuf = DK4_SIZEOF(rebuf,dkChar);
+ size_t szlabuf = DK4_SIZEOF(labuf,dkChar);
+ size_t szanbuf = DK4_SIZEOF(anbuf,wxChar);
+ int errc = ERROR_NONE;
+ int res;
+ int pn;
+ bool back = false;
+ $? "+ Initialize"
+ /* Keep some of the arguments.
+ */
+ if ((NULL == argv0) || (NULL == vendorName) || (NULL == groupName)) {
+ errc = ERROR_ARGUMENTS;
+ goto finished;
+ }
+ pcwxsArgv0 = argv0;
+ pcwxsVendor = vendorName;
+ pcdksGroup = groupName;
+ $? ". function call arguments saved"
+
+ /* Some default values.
+ */
+ ppBasicStrings = dk4wxah_basic_strings;
+ nBasicStrings = DK4_SIZEOF(dk4wxah_basic_strings,PCWXCHAR) - 1;
+ $? ". default basic strings set up"
+
+ /* Host name.
+ */
+ if (0 != dk4hostname(labuf, szlabuf, NULL)) {
+ p1 = dk4str_chr(labuf, dkT('.'));
+ if (NULL != p1) { *p1 = dkT('\0'); }
+ pdksHost = dk4str_dup(labuf, NULL);
+ if (NULL == pdksHost) {
+ errc = ERROR_MEMORY;
+ goto finished;
+ }
+ } else {
+ errc = ERROR_HOSTNAME;
+ goto finished;
+ }
+ $? ". host name found"
+
+ /* Language and encoding.
+ */
+ res = dk4loc_get_settings(labuf, szlabuf, rebuf, szrebuf, &iDkEncoding, erp);
+ if (0 == res) {
+ errc = ERROR_LANG_REG_ENC;
+ goto finished;
+ }
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR > 2
+ iWxEncoding = DK4_ENCODING_32;
+#else
+ iWxEncoding = DK4_ENCODING_UTF16;
+#endif
+#else
+ switch (iDkEncoding) {
+ case DK4_ENCODING_ANSI : {
+ iWxEncoding = DK4_ENCODING_ANSI;
+ } break;
+ case DK4_ENCODING_UTF8 : {
+ iWxEncoding = DK4_ENCODING_UTF8;
+ } break;
+ default : {
+ iWxEncoding = DK4_ENCODING_ASCII;
+ } break;
+ }
+#endif
+ switch (iDkEncoding) {
+ case DK4_ENCODING_ANSI : {
+ iFiEncoding = DK4_ENCODING_ANSI;
+ } break;
+ case DK4_ENCODING_UTF8 : {
+ iFiEncoding = DK4_ENCODING_UTF8;
+ } break;
+ default : {
+ iFiEncoding = DK4_ENCODING_ASCII;
+ } break;
+ }
+ if (0 < dk4str_len(labuf)) {
+ pdksLanguage = dk4str_dup(labuf, erp);
+ if (NULL == pdksLanguage) {
+ errc = ERROR_MEMORY;
+ goto finished;
+ }
+ }
+ if (0 < dk4str_len(rebuf)) {
+ pdksRegion = dk4str_dup(rebuf, erp);
+ if (NULL == pdksRegion) {
+ errc = ERROR_MEMORY;
+ goto finished;
+ }
+ }
+ $? ". language encoding region ok"
+
+ /* Login name and home directory.
+ */
+ res = dk4user_get_logname(labuf, szlabuf, 0, erp);
+ if (0 == res) {
+ errc = ERROR_LOGNAME;
+ goto finished;
+ }
+ pdksLogname = dk4str_dup(labuf, erp);
+ if (NULL == pdksLogname) {
+ errc = ERROR_MEMORY;
+ goto finished;
+ }
+ res = dk4user_get_homedir(labuf, szlabuf, 0, erp);
+ if (0 == res) { $? "! home dir not found"
+ errc = ERROR_HOMEDIR;
+ goto finished;
+ }
+ pdksHome = dk4str_dup(labuf, erp);
+ if (NULL == pdksHome) { $? "! memory"
+ errc = ERROR_MEMORY;
+ goto finished;
+ }
+ $? ". login name and home directory found"
+
+ /* System configuration and data directory.
+ */
+ res = dk4recwx_wxchar_to_dkchar(
+ labuf, szlabuf, iDkEncoding, argv0, iWxEncoding, erp
+ ); $? ". dk4recwx_wxchar_to_dkchar=%d", res
+ res = dk4execpath(
+ rebuf, szrebuf, ((0 != res) ? labuf : NULL), erp
+ );
+ if (0 == res) { $? "! executable not found"
+ errc = ERROR_EXECUTABLE;
+ goto finished;
+ } $? ". got executable"
+ p1 = rebuf;
+ p2 = NULL;
+ while (dkT('\0') != *p1) {
+ if (dk4wxah_fnsep_str[0] == *p1) { p2 = p1; }
+ /* We must increase this pointer.
+ */
+ p1++;
+ }
+ if (NULL == p2) { $? "! separator not found"
+ errc = ERROR_EXECUTABLE;
+ goto finished;
+ }
+ *(p2++) = dkT('\0');
+ /* Binary directory in rebuf, p2 is application name */
+#if DK4_ON_WINDOWS
+ /* On Windows, strip .exe suffix.
+ */
+ p4 = dk4path_get_suffix(p2, NULL);
+ if (NULL != p4) { *p4 = dkT('\0'); }
+#endif
+ pdksApp = dk4str_dup(p2, NULL);
+ if (NULL == pdksApp) {
+ errc = ERROR_MEMORY;
+ goto finished;
+ }
+ res = dk4recwx_dkchar_to_wxchar(
+ anbuf, szanbuf, iWxEncoding, pdksApp, iDkEncoding, NULL
+ );
+ if (0 == res) { $? "! dk4recwx_dkchar_to_wxchar"
+ errc = ERROR_EXECUTABLE;
+ goto finished;
+ }
+ pwxsApp = dk4strx_dup(anbuf, NULL);
+ if (NULL == pwxsApp) {
+ errc = ERROR_MEMORY;
+ goto finished;
+ }
+ /* Check whether the binary resides in one of the installation directories */
+ res = 0;
+ if (0 != dk4path_is_in_subdir(rebuf, dk4inst_get_directory(4), NULL)) {
+ res = 1;
+ }
+ if (0 == res) {
+ if (0 != dk4path_is_in_subdir(rebuf, dk4inst_get_directory(5), NULL)) {
+ res = 1;
+ }
+ }
+ if (0 == res) {
+ if (0 != dk4path_is_in_subdir(rebuf, dk4inst_get_directory(6), NULL)) {
+ res = 1;
+ }
+ }
+ if (0 == res) {
+ if (0 != dk4path_is_in_subdir(rebuf, dk4inst_get_directory(10), NULL)) {
+ res = 1;
+ }
+ }
+ if (0 != res) {
+ pdksSysconf = dk4str_dup(dk4inst_get_directory(1), NULL);
+ pdksShare = dk4str_dup(dk4inst_get_directory(2), NULL);
+ if ((NULL == pdksSysconf) || (NULL == pdksShare)) {
+ errc = ERROR_MEMORY;
+ goto finished;
+ }
+ } else {
+ dk4str_cpy_s(labuf, szlabuf, rebuf, NULL);
+ if (0 != dk4wxapplicationhelper_isinsub(labuf, dk4wxah_final_directories)) {
+ res = 0;
+ if (0 != dk4str_cpy_s(rebuf, szrebuf, labuf, NULL)) {
+ if (0 != dk4str_cat_s(rebuf, szrebuf, dk4wxah_fnsep_str, NULL)) {
+ if (0 != dk4str_cat_s(rebuf,szrebuf,dk4wxah_new_directories[0],NULL))
+ {
+ res = 1;
+ }
+ }
+ }
+ if (0 != res) {
+ pdksSysconf = dk4str_dup(rebuf, NULL);
+ if (NULL == pdksSysconf) {
+ errc = ERROR_MEMORY;
+ goto finished;
+ }
+ } else {
+ errc = ERROR_EXEC_TOO_LONG;
+ goto finished;
+ }
+ res = 0;
+ if (0 != dk4str_cpy_s(rebuf, szrebuf, labuf, NULL)) {
+ if (0 != dk4str_cat_s(rebuf, szrebuf, dk4wxah_fnsep_str, NULL)) {
+ if (0 != dk4str_cat_s(rebuf,szrebuf,dk4wxah_new_directories[1],NULL))
+ {
+ res = 1;
+ }
+ }
+ }
+ if (0 != res) {
+ pdksShare = dk4str_dup(rebuf, NULL);
+ if (NULL == pdksShare) {
+ errc = ERROR_MEMORY;
+ goto finished;
+ }
+ } else {
+ errc = ERROR_EXEC_TOO_LONG;
+ goto finished;
+ }
+ } else {
+ pdksSysconf = dk4str_dup(rebuf, NULL);
+ pdksShare = dk4str_dup(rebuf, NULL);
+ if ((NULL == pdksSysconf) || (NULL == pdksShare)) {
+ errc = ERROR_MEMORY;
+ goto finished;
+ }
+ }
+ }
+ $? ". sysconf and data dir found"
+
+ /* Containers and iterators for string tables and preferences.
+ */
+ sStt = dk4sto_open(NULL);
+ if (NULL == sStt) {
+ errc = ERROR_MEMORY;
+ goto finished;
+ }
+ dk4sto_set_comp(sStt, dk4wxstt_compare, 0);
+ iStt = dk4sto_it_open(sStt, NULL);
+ if (NULL == iStt) {
+ errc = ERROR_MEMORY;
+ goto finished;
+ }
+ sPrSys = dk4sto_open(NULL);
+ if (NULL == sPrSys) {
+ errc = ERROR_MEMORY;
+ goto finished;
+ }
+ dk4sto_set_comp(sPrSys, dk4wxpref_compare, 0);
+ iPrSys = dk4sto_it_open(sPrSys, NULL);
+ if (NULL == iPrSys) {
+ errc = ERROR_MEMORY;
+ goto finished;
+ }
+ sPrUser = dk4sto_open(NULL);
+ if (NULL == sPrUser) {
+ errc = ERROR_MEMORY;
+ goto finished;
+ }
+ dk4sto_set_comp(sPrUser, dk4wxpref_compare, 0);
+ iPrUser = dk4sto_it_open(sPrUser, NULL);
+ if (NULL == iPrUser) {
+ errc = ERROR_MEMORY;
+ goto finished;
+ }
+ $? ". storages created"
+
+ /* Read preference files.
+ */
+ for (pn = 0; pn <= DK4_FS_CONF_MAX; pn++) {
+ dk4wxpref_one_pass(
+ ((DK4_FS_CONF_SYS_MAX < pn) ? sPrUser : sPrSys),
+ ((DK4_FS_CONF_SYS_MAX < pn) ? iPrUser : iPrSys),
+ pdksApp,
+ pcdksGroup,
+ pdksLogname,
+ pdksHost,
+ pdksLanguage,
+ pdksRegion,
+ pdksHome,
+ pdksSysconf,
+ pdksShare,
+ iWxEncoding,
+ iDkEncoding,
+ (
+ (DK4_ENCODING_UTF8 == iDkEncoding)
+ ? DK4_FILE_ENCODING_UTF8 : DK4_FILE_ENCODING_ASCII
+ ),
+ pn
+ );
+ }
+ $? ". preference files processed"
+
+ /* Localized basic strings.
+ */
+ ppBasicStrings = InternalGetStringTable(
+ dk4wxah_kwnl_dk[0], (DK4_SIZEOF(dk4wxah_basic_strings,PCWXCHAR) - 1)
+ );
+ if (NULL == ppBasicStrings) { ppBasicStrings = dk4wxah_basic_strings; }
+ nBasicStrings = Dk4WxApplicationHelper::StringTableSize(ppBasicStrings);
+ $? ". localized strings found"
+
+ /* Finally mark success.
+ */
+ bActive = back = true;
+
+ /* Clean up if not successfully.
+ */
+ finished:
+ if (!(back)) { $? "! error"
+ switch (errc) {
+ case ERROR_MEMORY : { $? "! memory"
+ msgbtext = dkwxah_msgb_texts[1];
+ msgbtitle = dkwxah_msgb_texts[0];
+ } break;
+ case ERROR_HOSTNAME : { $? "! host name not found"
+ msgbtext = dkwxah_msgb_texts[2];
+ msgbtitle = dkwxah_msgb_texts[0];
+ } break;
+ case ERROR_LANG_REG_ENC : { $? "! region/encoding not found"
+ msgbtext = dkwxah_msgb_texts[3];
+ msgbtitle = dkwxah_msgb_texts[0];
+ } break;
+ case ERROR_LOGNAME : { $? "! log name not found"
+ msgbtext = dkwxah_msgb_texts[4];
+ msgbtitle = dkwxah_msgb_texts[0];
+ } break;
+ case ERROR_HOMEDIR : { $? "! home directory not found"
+ msgbtext = dkwxah_msgb_texts[5];
+ msgbtitle = dkwxah_msgb_texts[0];
+ } break;
+ case ERROR_EXECUTABLE : { $? "! executable file name not found"
+ msgbtext = dkwxah_msgb_texts[6];
+ msgbtitle = dkwxah_msgb_texts[0];
+ } break;
+ case ERROR_EXEC_TOO_LONG : { $? "! executable file name too long"
+ msgbtext = dkwxah_msgb_texts[7];
+ msgbtitle = dkwxah_msgb_texts[0];
+ } break;
+ case ERROR_ARGUMENTS : { $? "! invalid arguments"
+ msgbtext = dkwxah_msgb_texts[8];
+ msgbtitle = dkwxah_msgb_texts[0];
+ } break;
+ }
+ if ((NULL != msgbtext) && (NULL != msgbtitle)) {
+ wxMessageBox(
+ msgbtext, msgbtitle, (wxOK | wxCENTRE | wxICON_ERROR)
+ );
+ }
+ InternalCleanup();
+ }
+ $? "- Initialize %d", ((back) ? 1 : 0)
+ return back;
+}
+
+
+
+void
+Dk4WxApplicationHelper::InternalCleanup(void)
+{
+ dk4_wx_string_table_t *wxsttptr;
+ dk4_wx_pref_t *pptr;
+ $? "+ InternalCleanup"
+ bActive = false; // Object can not longer be used.
+ ppBasicStrings = NULL;
+ pcwxsArgv0 = NULL;
+ pcwxsVendor = NULL;
+ pcdksGroup = NULL;
+ if (NULL != sPrUser) {
+ if (NULL != iPrUser) {
+ dk4sto_it_reset(iPrUser);
+ do {
+ pptr = (dk4_wx_pref_t *)dk4sto_it_next(iPrUser);
+ if (NULL != pptr) { dk4wxpref_close(pptr); }
+ } while (NULL != pptr);
+ dk4sto_it_close(iPrUser);
+ iPrUser = NULL;
+ }
+ dk4sto_close(sPrUser);
+ sPrUser = NULL;
+ }
+ if (NULL != sPrSys) {
+ if (NULL != iPrSys) {
+ dk4sto_it_reset(iPrSys);
+ do {
+ pptr = (dk4_wx_pref_t *)dk4sto_it_next(iPrSys);
+ if (NULL != pptr) { dk4wxpref_close(pptr); }
+ } while (NULL != pptr);
+ dk4sto_it_close(iPrSys);
+ iPrSys = NULL;
+ }
+ dk4sto_close(sPrSys);
+ sPrSys = NULL;
+ }
+ if (NULL != sStt) {
+ if (NULL != iStt) {
+ dk4sto_it_reset(iStt);
+ do {
+ wxsttptr = (dk4_wx_string_table_t *)dk4sto_it_next(iStt);
+ if (NULL != wxsttptr) { dk4wxstt_close(wxsttptr); }
+ } while (NULL != wxsttptr);
+ dk4sto_it_close(iStt);
+ iStt = NULL;
+ }
+ dk4sto_close(sStt);
+ sStt = NULL;
+ }
+ nBasicStrings = 0;
+#if 0
+ /* Leave these integer variables as is.
+ */
+ iDkEncoding = DK4_ENCODING_ASCII;
+ iWxEncoding = DK4_ENCODING_ASCII;
+ iFiEncoding = DK4_FILE_ENCODING_ASCII;
+#endif
+ dk4mem_release(pdksRegion);
+ dk4mem_release(pdksLanguage);
+ dk4mem_release(pdksShare);
+ dk4mem_release(pdksSysconf);
+ dk4mem_release(pdksApp);
+ dk4mem_release(pdksHost);
+ dk4mem_release(pwxsApp);
+ dk4mem_release(pdksLogname);
+ dk4mem_release(pdksHome);
+ $? "- InternalCleanup"
+}
+
+
+
+void
+Dk4WxApplicationHelper::Cleanup(void)
+{
+ $? "+ Cleanup"
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ InternalCleanup();
+ }
+ $? "- Cleanup"
+}
+
+
+
+/*
+ We do not need a critical section locker as the destructor
+ is invoked from the applications destructor. At this
+ we have no more top level windows or worker threads.
+*/
+Dk4WxApplicationHelper::~Dk4WxApplicationHelper()
+{
+ $? "+ ~Dk4WxApplicationHelper"
+ InternalCleanup();
+ $? "- ~Dk4WxApplicationHelper"
+}
+
+
+
+$*
+ Internal functions.
+ These functions do not attempt synchronization.
+$*
+
+
+bool
+Dk4WxApplicationHelper::InternalStringToWx(
+ wxChar *dptr, size_t dsz, const dkChar *sptr, dk4_er_t *erp
+)
+{
+ int res = 0;
+ bool back = false;
+ $? "+ InternalStringToWx"
+ res = dk4recwx_dkchar_to_wxchar(dptr,dsz,iWxEncoding,sptr,iDkEncoding,erp);
+ if (0 != res) { back = true; }
+ $? "- InternalStringToWx %d", (int)back
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::InternalStringToDk(
+ dkChar *dptr, size_t dsz, const wxChar *sptr, dk4_er_t *erp
+)
+{
+ int res = 0;
+ bool back = false;
+ $? "+ InternalStringToDk"
+ res = dk4recwx_wxchar_to_dkchar(dptr,dsz,iDkEncoding,sptr,iWxEncoding,erp);
+ if (0 != res) { back = true; }
+ $? "- InternalStringToDk %d", (int)back
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::InternalFindDataFile(
+ dkChar *fnb,
+ size_t szfnb,
+ dkChar const *sfn,
+ int maxpass,
+ bool aco
+)
+{
+ int passno = 0;
+ int res = 0;
+ bool back = false;
+ $? "+ InternalFindDataFile dkChar"
+ for (passno = 0; ((passno < maxpass) && (!(back))); passno++) {
+ res = dk4fs_data_one(
+ fnb, szfnb, sfn,
+ pdksShare, pdksHome, pdksApp, pcdksGroup,
+ pdksLanguage, pdksRegion,
+ passno, ((aco) ? 1 : 0), NULL
+ );
+ if (0 != res) { back = true; }
+ } $? "- InternalFindDataFile %d", (back ? 1 : 0)
+ return back;
+}
+
+
+
+
+#if DK4_SIZEOF_WXCHAR != DK4_CHAR_SIZE
+
+bool
+Dk4WxApplicationHelper::InternalFindDataFile(
+ wxChar *fnb,
+ size_t szfnb,
+ dkChar const *sfn,
+ int maxpass,
+ bool aco
+)
+{
+ dkChar buf[DK4_MAX_PATH];
+ size_t szbuf = DK4_SIZEOF(buf,dkChar);
+ bool back = false;
+ $? "+ InternalFindDataFile wxChar"
+ back = InternalFindDataFile(buf, szbuf, sfn, maxpass, aco);
+ if (back) {
+ back = InternalStringToWx(fnb, szfnb, buf, NULL);
+ } $? "- InternalFindDataFile %d", (back ? 1 : 0)
+ return back;
+}
+
+#endif
+
+
+
+const wxChar * const *
+Dk4WxApplicationHelper::InternalGetStringTable(
+ const dkChar *tableName,
+ size_t tableSize
+)
+{
+ dkChar fnb[DK4_MAX_PATH];
+ dk4_er_t e1;
+ dk4_er_t e2;
+ const wxChar * const *back = NULL;
+ dk4_wx_string_table_t *tabptr = NULL;
+ dk4_stream_t *strm = NULL;
+ size_t szfnb = DK4_SIZEOF(fnb,dkChar);
+ $? "+ InternalGetStringTable"
+ tabptr = (dk4_wx_string_table_t *)dk4sto_it_find_like(iStt, tableName, 1);
+ if (NULL == tabptr) {
+ if (InternalFindDataFile(fnb, szfnb, tableName, DK4_FS_DATA_MAX_SYS, 1)) {
+ strm = dk4stream_open_file_reader(fnb, NULL);
+ if (NULL != strm) {
+ tabptr = dk4wxstt_open(tableName, tableSize, NULL);
+ if (NULL != tabptr) {
+ if (0 != dk4sto_add(sStt, tabptr, NULL)) {
+ dk4error_init(&e1);
+ dk4error_init(&e2);
+ if (!dk4wxstt_apply_stream(tabptr, strm, iWxEncoding, &e1, &e2)) {
+ dk4wxstt_shutdown(tabptr);
+ }
+ } else {
+ dk4wxstt_close(tabptr);
+ tabptr = NULL;
+ }
+ }
+ dk4stream_close(strm, NULL);
+ }
+ }
+ }
+ if (NULL != tabptr) {
+ if (tabptr->nstrings >= tableSize) {
+ back = (const wxChar * const *)(tabptr->strings);
+ }
+ } $? "- InternalGetStringTable %d", ((NULL != back) ? 1 : 0)
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::InternalSetMultiple(
+ const wxChar * const *names, long *array, size_t sz
+)
+{
+ wxConfig conf(pwxsApp, pcwxsVendor);
+ size_t i = 0;
+ bool back = false;
+ $? "+ InternalSetMultiple long"
+ if ((NULL != names) && (NULL != array) && (0 < sz)) {
+ back = true;
+ for (i = 0; i < sz; i++) {
+ if (!(conf.Write(names[i], array[i]))) {
+ back = false;
+ }
+ }
+ } $? "- InternalSetMultiple %d", (int)back
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::InternalSetMultiple(
+ const wxChar * const *names, int *array, size_t sz
+)
+{
+ wxConfig conf(pwxsApp, pcwxsVendor);
+ size_t i = 0;
+ bool back = false;
+ $? "+ InternalSetMultiple int"
+ if ((NULL != names) && (NULL != array) && (0 < sz)) {
+ back = true;
+ for (i = 0; i < sz; i++) {
+ if (!(conf.Write(names[i], array[i]))) {
+ back = false;
+ }
+ }
+ } $? "- InternalSetMultiple %d", (int)back
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::InternalSetMultiple(
+ const wxChar * const *names, bool *array, size_t sz
+)
+{
+ wxConfig conf(pwxsApp, pcwxsVendor);
+ size_t i = 0;
+ bool back = false;
+ $? "+ InternalSetMultiple bool"
+ if ((NULL != names) && (NULL != array) && (0 < sz)) {
+ back = true;
+ for (i = 0; i < sz; i++) {
+ if (!(conf.Write(names[i], array[i]))) {
+ back = false;
+ }
+ }
+ } $? "- InternalSetMultiple %d", (int)back
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::InternalSetMultiple(
+ const wxChar * const *names, double *array, size_t sz
+)
+{
+ wxConfig conf(pwxsApp, pcwxsVendor);
+ size_t i = 0;
+ bool back = false;
+ $? "+ InternalSetMultiple double"
+ if ((NULL != names) && (NULL != array) && (0 < sz)) {
+ back = true;
+ for (i = 0; i < sz; i++) {
+ if (!(conf.Write(names[i], array[i]))) {
+ back = false;
+ }
+ }
+ } $? "- InternalSetMultiple %d", (int)back
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::InternalSetMultiple(
+ const wxChar * const *names, const wxChar * const *array, size_t sz
+)
+{
+ wxConfig conf(pwxsApp, pcwxsVendor);
+ size_t i = 0;
+ bool back = false;
+ $? "+ InternalSetMultiple string"
+ if ((NULL != names) && (NULL != array) && (0 < sz)) {
+ back = true;
+ for (i = 0; i < sz; i++) {
+ if (!(conf.Write(names[i], array[i]))) {
+ back = false;
+ }
+ }
+ } $? "- InternalSetMultiple %d", (int)back
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::InternalGetMultiple(
+ const wxChar * const *names, long *array, size_t sz
+)
+{
+ wxConfig conf(pwxsApp, pcwxsVendor);
+ dk4_wx_pref_t *pptr = NULL;
+#if DK4_SIZEOF_WXCHAR > 1
+ const wchar_t *ep = NULL;
+#else
+ const char *ep = NULL;
+#endif
+ size_t i;
+ long l;
+ int res;
+ bool back = false;
+ $? "+ InternalGetMultiple"
+ back = true;
+ for (i = 0; i < sz; i++) {
+ l = 0L;
+ if (conf.Read(names[i], &l)) {
+ array[i] = l;
+ } else {
+ pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrUser, names[i], 1);
+ if (NULL == pptr) {
+ pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrSys, names[i], 1);
+ }
+ if (NULL != pptr) {
+#if DK4_SIZEOF_WXCHAR > 1
+ res = dk4ma_input_wc_dec_long(&l, pptr->value, &ep, 1, NULL);
+#else
+ res = dk4ma_input_c8_dec_long(&l, pptr->value, &ep, 1, NULL);
+#endif
+ if (0 != res) {
+ array[i] = l;
+ } else {
+ back = false;
+ }
+ }
+ }
+ }
+ $? "- InternalGetMultiple %d", (int)back
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::InternalGetMultiple(
+ const wxChar * const *names, int *array, size_t sz
+)
+{
+ wxConfig conf(pwxsApp, pcwxsVendor);
+ dk4_wx_pref_t *pptr = NULL;
+#if DK4_SIZEOF_WXCHAR > 1
+ const wchar_t *ep = NULL;
+#else
+ const char *ep = NULL;
+#endif
+ size_t i;
+ long l;
+ int res;
+ bool back = false;
+ $? "+ InternalGetMultiple"
+ back = true;
+ for (i = 0; i < sz; i++) {
+ l = 0L;
+ if (conf.Read(names[i], &l)) {
+ if (((long)(INT_MIN) <= l) && ((long)(INT_MAX) >= l)) {
+ array[i] = (int)l;
+ } else {
+ back = false;
+ }
+ } else {
+ pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrUser, names[i], 1);
+ if (NULL == pptr) {
+ pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrSys, names[i], 1);
+ }
+ if (NULL != pptr) {
+#if DK4_SIZEOF_WXCHAR > 1
+ res = dk4ma_input_wc_dec_long(&l, pptr->value, &ep, 1, NULL);
+#else
+ res = dk4ma_input_c8_dec_long(&l, pptr->value, &ep, 1, NULL);
+#endif
+ if (0 != res) {
+ if (((long)(INT_MIN) <= l) && ((long)(INT_MAX) >= l)) {
+ array[i] = (int)l;
+ } else {
+ back = false;
+ }
+ } else {
+ back = false;
+ }
+ }
+ }
+ }
+ $? "- InternalGetMultiple %d", (int)back
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::InternalGetMultiple(
+ const wxChar * const *names, bool *array, size_t sz
+)
+{
+ wxConfig conf(pwxsApp, pcwxsVendor);
+ dk4_wx_pref_t *pptr = NULL;
+ size_t i;
+ bool l;
+ bool back = false;
+ $? "+ InternalGetMultiple bool"
+ back = true;
+ for (i = 0; i < sz; i++) {
+ l = 0L;
+ $? ". name \"%!ws\"", TR_WXSTR(names[i])
+ if (conf.Read(names[i], &l)) {
+ array[i] = l;
+ } else {
+ pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrUser, names[i], 1);
+ if (NULL == pptr) {
+ pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrSys, names[i], 1);
+ }
+ if (NULL != pptr) { $? ". found"
+ $? ". pptr"
+ $? ". pptr->value = %!ws", TR_WXSTR(pptr->value)
+#if DK4_SIZEOF_WXCHAR > 1
+ $? ". wide"
+ if (0 != dk4strw_is_bool(pptr->value)) {
+ if (0 != dk4strw_is_on(pptr->value)) {
+ array[i] = true; $? ". on"
+ } else {
+ array[i] = false; $? ". off"
+ }
+ } else { $? "! not boolean"
+ back = false;
+ }
+#else
+ $? ". 8 bit"
+ if (0 != dk4str8_is_bool(pptr->value)) {
+ if (0 != dk4str8_is_on(pptr->value)) {
+ array[i] = true; $? ". on"
+ } else {
+ array[i] = false; $? ". off"
+ }
+ } else {
+ back = false; $? "! not boolean"
+ }
+#endif
+ } else { $? ". not found"
+ }
+ }
+ }
+ $? "- InternalGetMultiple %d", (int)back
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::InternalGetMultiple(
+ const wxChar * const *names, double *array, size_t sz
+)
+{
+ wxConfig conf(pwxsApp, pcwxsVendor);
+ dk4_wx_pref_t *pptr = NULL;
+#if DK4_SIZEOF_WXCHAR > 1
+ const wchar_t *ep = NULL;
+#else
+ const char *ep = NULL;
+#endif
+#if DK4_HAVE_SETLOCALE
+ char *oldloc = NULL;
+#endif
+ double l;
+ size_t i;
+ int res;
+ bool back = false;
+ $? "+ InternalGetMultiple"
+ back = true;
+ for (i = 0; i < sz; i++) {
+ l = 0.0;
+ if (conf.Read(names[i], &l)) {
+ array[i] = l;
+ } else {
+ pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrUser, names[i], 1);
+ if (NULL == pptr) {
+ pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrSys, names[i], 1);
+ }
+ if (NULL != pptr) {
+#if DK4_HAVE_SETLOCALE
+ oldloc = setlocale(LC_NUMERIC, dk4wxah_kwnl_c8[0]);
+#endif
+#if DK4_SIZEOF_WXCHAR > 1
+ res = dk4ma_input_wc_double(&l, pptr->value, &ep, 1, NULL);
+#else
+ res = dk4ma_input_c8_double(&l, pptr->value, &ep, 1, NULL);
+#endif
+#if DK4_HAVE_SETLOCALE
+ if (NULL != oldloc) { setlocale(LC_NUMERIC, oldloc); }
+#endif
+ if (0 != res) {
+ array[i] = l;
+ } else {
+ back = false;
+ }
+ }
+ }
+ }
+ $? "- InternalGetMultiple %d", (int)back
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::InternalGetMultiple(
+ const wxChar * const *names, wxChar **array, size_t sz, bool ov
+)
+{
+ wxConfig conf(pwxsApp, pcwxsVendor);
+ dk4_wx_pref_t *pptr = NULL;
+ const wxChar *vptr = NULL;
+ wxChar *nptr = NULL;
+ size_t i;
+ bool back = false;
+ $? "+ InternalGetMultiple strings"
+ back = true;
+ for (i = 0; i < sz; i++) {
+ if ((NULL == array[i]) || (ov)) {
+ wxString value = wxEmptyString;
+ if (conf.Read(names[i], &value)) {
+ vptr = value.c_str();
+ if (NULL != vptr) {
+ nptr = dk4strx_dup(vptr, NULL);
+ if (NULL != nptr) {
+ if (NULL != array[i]) { dk4mem_free(array[i]); }
+ array[i] = nptr;
+ } else {
+ back = false;
+ }
+ } else {
+ back = false;
+ }
+ } else {
+ pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrUser, names[i], 1);
+ if (NULL == pptr) {
+ pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(iPrSys, names[i], 1);
+ }
+ if (NULL != pptr) {
+ nptr = dk4strx_dup(pptr->value, NULL);
+ if (nptr) {
+ if (NULL != array[i]) { dk4mem_free(array[i]); }
+ array[i] = nptr;
+ } else {
+ back = false;
+ }
+ }
+ }
+ }
+ }
+ $? "- InternalGetMultiple %d", (int)back
+ return back;
+}
+
+
+
+$*
+ Public interface.
+ The methods must
+ (a) synchronize access attempts from multiple threads and
+ (b) ensure the object is in a usable state.
+$*
+
+
+bool
+Dk4WxApplicationHelper::FindDataFile(
+ dkChar *fnb,
+ size_t szfnb,
+ dkChar const *sfn,
+ int maxpass,
+ bool aco
+)
+{
+ bool back = false;
+ $? "+ FindDataFile dkChar"
+ if ((NULL != fnb) && (NULL != sfn) && (0 < szfnb)) {
+ wxCriticalSectionLocker lock(csProtect);
+ if (bActive) {
+ back = InternalFindDataFile(fnb, szfnb, sfn, maxpass, aco);
+ }
+ } $? "- FindDataFile %d", (int)back
+ return back;
+}
+
+
+
+
+#if DK4_SIZEOF_WXCHAR != DK4_CHAR_SIZE
+
+bool
+Dk4WxApplicationHelper::FindDataFile(
+ wxChar *fnb,
+ size_t szfnb,
+ dkChar const *sfn,
+ int maxpass,
+ bool aco
+)
+{
+ bool back = false;
+ $? "+ FindDataFile wxChar"
+ if ((NULL != fnb) && (NULL != sfn) && (0 < szfnb)) {
+ wxCriticalSectionLocker lock(csProtect);
+ if (bActive) {
+ back = InternalFindDataFile(fnb, szfnb, sfn, maxpass, aco);
+ }
+ } $? "- FindDataFile %d", (int)back
+ return back;
+}
+
+#endif
+
+
+
+int
+Dk4WxApplicationHelper::GetDkEncoding(void)
+{
+ int back = DK4_ENCODING_ASCII;
+ $? "+ GetDkEncoding"
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ back = iDkEncoding;
+ } $? "- GetDkEncoding %d", back
+ return back;
+}
+
+
+
+int
+Dk4WxApplicationHelper::GetWxEncoding(void)
+{
+ int back = DK4_ENCODING_ASCII;
+ $? "+ GetWxEncoding"
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ back = iWxEncoding;
+ } $? "- GetWxEncoding %d", back
+ return back;
+}
+
+
+
+int
+Dk4WxApplicationHelper::GetFiEncoding(void)
+{
+ int back = DK4_ENCODING_ASCII;
+ $? "+ GetFiEncoding"
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ back = iFiEncoding;
+ } $? "- GetFiEncoding %d", back
+ return back;
+}
+
+
+
+const wxChar * const *
+Dk4WxApplicationHelper::GetStringTable(
+ const dkChar *tableName,
+ const wxChar * const *defaultTable
+)
+{
+ const wxChar * const *back = NULL;
+ size_t sz = 0;
+ $? "+ GetStringTable"
+ if ((NULL != tableName) && (NULL != defaultTable)) {
+ sz = Dk4WxApplicationHelper::StringTableSize(defaultTable);
+ if (0 < sz) {
+ wxCriticalSectionLocker lock(csProtect);
+ if (bActive) {
+ back = InternalGetStringTable(tableName, sz);
+ }
+ }
+ }
+ if (NULL == back) { back = defaultTable; }
+ $? "- GetStringTable %d", ((NULL != back) ? 1 : 0)
+ return back;
+}
+
+
+
+const wxChar *
+Dk4WxApplicationHelper::GetBasicString(
+ size_t numstr
+)
+{
+ const wxChar *back = NULL;
+ $? "+ GetBasicString"
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ if (bActive) {
+ if ((NULL != ppBasicStrings) && (0 < nBasicStrings)) {
+ if (numstr < nBasicStrings) {
+ back = ppBasicStrings[numstr];
+ }
+ }
+ }
+ }
+ if (NULL == back) {
+ if (numstr < (DK4_SIZEOF(dk4wxah_basic_strings,wxChar) - 1)) {
+ back = dk4wxah_basic_strings[numstr];
+ } else {
+ back = dk4wxah_empty_string;
+ }
+ } $? "- GetBasicString %d", ((NULL != back) ? 1 : 0)
+ return back;
+}
+
+
+
+const wxChar * const *
+Dk4WxApplicationHelper::GetBasicStrings(
+ size_t *pNumBasicStrings
+)
+{
+ const wxChar * const *back = NULL;
+ $? "+ GetBasicStrings"
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ if (bActive) {
+ back = ppBasicStrings;
+ if (NULL != pNumBasicStrings) { *pNumBasicStrings = nBasicStrings; }
+ }
+ }
+ if (NULL == back) {
+ back = dk4wxah_basic_strings;
+ if (NULL != pNumBasicStrings) {
+ *pNumBasicStrings = DK4_SIZEOF(dk4wxah_basic_strings,wxChar) - 1;
+ }
+ } $? "- GetBasicStrings %d", ((NULL != back) ? 1 : 0)
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::StringToWx(
+ wxChar *dptr, size_t dsz, const dkChar *sptr, dk4_er_t *erp
+)
+{
+ int res = 0;
+ int wxe = DK4_ENCODING_ASCII;
+ int dke = DK4_ENCODING_ASCII;
+ bool back = false;
+ $? "+ StringToWx"
+ if ((NULL != dptr) && (NULL != sptr) && (0 < dsz)) {
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ wxe = iWxEncoding;
+ dke = iDkEncoding;
+ }
+ res = dk4recwx_dkchar_to_wxchar(dptr, dsz, wxe, sptr, dke, erp);
+ if (0 != res) { back = true; }
+ } $? "- StringToWx %d", (int)back
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::StringToDk(
+ dkChar *dptr, size_t dsz, const wxChar *sptr, dk4_er_t *erp
+)
+{
+ int res = 0;
+ int wxe = DK4_ENCODING_ASCII;
+ int dke = DK4_ENCODING_ASCII;
+ bool back = false;
+ $? "+ StringToDk"
+ if ((NULL != dptr) && (NULL != sptr) && (0 < dsz)) {
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ wxe = iWxEncoding;
+ dke = iDkEncoding;
+ }
+ res = dk4recwx_wxchar_to_dkchar(dptr, dsz, dke, sptr, wxe, erp);
+ if (0 != res) { back = true; }
+ } $? "- StringToDk %d", (int)back
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::StringToChar(
+ char *dptr, size_t dsz, const wxChar *sptr, dk4_er_t *erp
+)
+{
+ int res = 0;
+ int wxe = DK4_ENCODING_ASCII;
+ int dke = DK4_ENCODING_ASCII;
+ bool back = false;
+ if ((NULL != dptr) && (NULL != sptr) && (0 < dsz)) {
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ wxe = iWxEncoding;
+ dke = iDkEncoding;
+ }
+ if (DK4_ENCODING_UTF8 != dke) {
+ if (DK4_ENCODING_ANSI != dke) {
+ dke = DK4_ENCODING_ASCII;
+ }
+ }
+ res = dk4recwx_wxchar_to_char(dptr, dsz, dke, sptr, wxe, erp);
+ if (0 != res) { back = true; }
+ }
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::SetMultiple(
+ const wxChar * const *names, long *array, size_t sz
+)
+{
+ bool back = false;
+ $? "+ SetMultiple long"
+ if ((NULL != names) && (NULL != array) && (0 < sz)) {
+ wxCriticalSectionLocker lock(csProtect);
+ if (bActive) {
+ back = InternalSetMultiple(names, array, sz);
+ } else {
+ /* Object not active */
+ }
+ } $? "- SetMultiple %d", (int)back
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::SetMultiple(
+ const wxChar * const *names, int *array, size_t sz
+)
+{
+ bool back = false;
+ $? "+ SetMultiple int"
+ if ((NULL != names) && (NULL != array) && (0 < sz)) {
+ wxCriticalSectionLocker lock(csProtect);
+ if (bActive) {
+ back = InternalSetMultiple(names, array, sz);
+ } else {
+ /* Object not active */
+ }
+ } $? "- SetMultiple %d", (int)back
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::SetMultiple(
+ const wxChar * const *names, bool *array, size_t sz
+)
+{
+ bool back = false;
+ $? "+ SetMultiple bool"
+ if ((NULL != names) && (NULL != array) && (0 < sz)) {
+ wxCriticalSectionLocker lock(csProtect);
+ if (bActive) {
+ back = InternalSetMultiple(names, array, sz);
+ } else {
+ /* Object not active */
+ }
+ } $? "- SetMultiple %d", (int)back
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::SetMultiple(
+ const wxChar * const *names, double *array, size_t sz
+)
+{
+ bool back = false;
+ $? "+ SetMultiple double"
+ if ((NULL != names) && (NULL != array) && (0 < sz)) {
+ wxCriticalSectionLocker lock(csProtect);
+ if (bActive) {
+ back = InternalSetMultiple(names, array, sz);
+ } else {
+ /* Object not active */
+ }
+ } $? "- SetMultiple %d", (int)back
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::SetMultiple(
+ const wxChar * const *names, const wxChar * const *array, size_t sz
+)
+{
+ bool back = false;
+ $? "+ SetMultiple strings"
+ if ((NULL != names) && (NULL != array) && (0 < sz)) {
+ wxCriticalSectionLocker lock(csProtect);
+ if (bActive) {
+ back = InternalSetMultiple(names, array, sz);
+ } else {
+ /* Object not active */
+ }
+ } $? "- SetMultiple %d", (int)back
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::GetMultiple(
+ const wxChar * const *names, long *array, size_t sz
+)
+{
+ bool back = false;
+ $? "+ GetMultiple long"
+ if ((NULL != names) && (NULL != array) && (0 < sz)) {
+ wxCriticalSectionLocker lock(csProtect);
+ if (bActive) {
+ back = InternalGetMultiple(names, array, sz);
+ } else {
+ /* Object not active */
+ }
+ } $? "- GetMultiple %d", (int)back
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::GetMultiple(
+ const wxChar * const *names, int *array, size_t sz
+)
+{
+ bool back = false;
+ $? "+ GetMultiple int"
+ if ((NULL != names) && (NULL != array) && (0 < sz)) {
+ wxCriticalSectionLocker lock(csProtect);
+ if (bActive) {
+ back = InternalGetMultiple(names, array, sz);
+ } else {
+ /* Object not active */
+ }
+ } $? "- GetMultiple %d", (int)back
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::GetMultiple(
+ const wxChar * const *names, bool *array, size_t sz
+)
+{
+ bool back = false;
+ $? "+ GetMultiple bool"
+ if ((NULL != names) && (NULL != array) && (0 < sz)) {
+ wxCriticalSectionLocker lock(csProtect);
+ if (bActive) {
+ back = InternalGetMultiple(names, array, sz);
+ } else {
+ /* Object not active */
+ }
+ } $? "- GetMultiple %d", (int)back
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::GetMultiple(
+ const wxChar * const *names, double *array, size_t sz
+)
+{
+ bool back = false;
+ $? "+ GetMultiple double"
+ if ((NULL != names) && (NULL != array) && (0 < sz)) {
+ wxCriticalSectionLocker lock(csProtect);
+ if (bActive) {
+ back = InternalGetMultiple(names, array, sz);
+ } else {
+ /* Object not active */
+ }
+ } $? "- GetMultiple %d", (int)back
+ return back;
+}
+
+
+
+bool
+Dk4WxApplicationHelper::GetMultiple(
+ const wxChar * const *names, wxChar **array, size_t sz, bool ov
+)
+{
+ bool back = false;
+ $? "+ GetMultiple strings"
+ if ((NULL != names) && (NULL != array) && (0 < sz)) {
+ wxCriticalSectionLocker lock(csProtect);
+ if (bActive) {
+ back = InternalGetMultiple(names, array, sz, ov);
+ } else {
+ /* Object not active */
+ }
+ } $? "- GetMultiple %d", (int)back
+ return back;
+}
+
+
+
+$*
+ Static class functions.
+$*
+
+
+void
+Dk4WxApplicationHelper::CorrectPosition(
+ int & x, int & y, int & w, int & h
+)
+{
+ wxSize scsz;
+ $? "+ CorrectPosition %d %d %d %d", x, y, w, h
+ scsz = wxGetDisplaySize();
+ if (0 > x) { x = (scsz.x - w) / 2; }
+ if (0 > y) { y = (scsz.y - h) / 2; }
+ if (scsz.x < (x + w)) { x = scsz.x - w; }
+ if (scsz.y < (y + h)) { y = scsz.y - h; }
+ if (0 > x) { x = 0; }
+ if (0 > y) { y = 0; }
+ $? "- CorrectPosition %d %d %d %d", x, y, w, h
+}
+
+
+
+void
+Dk4WxApplicationHelper::CorrectPosition(
+ wxWindow & wnd
+)
+{
+ int x, y, w, h;
+ $? "+ CorrectPosition window"
+ wnd.GetPosition(&x, &y);
+ wnd.GetSize(&w, &h);
+ Dk4WxApplicationHelper::CorrectPosition(x, y, w, h);
+ wnd.SetSize(x, y, w, h);
+ $? "- CorrectPosition"
+}
+
+
+
+void
+Dk4WxApplicationHelper::ChooseChildPosition(
+ const wxWindow & p, wxWindow & c, bool beside
+)
+{
+ wxSize scsz = wxGetDisplaySize();
+ int px = 0;
+ int py = 0;
+ int pw = 0;
+ int ph = 0;
+ int cx = 0;
+ int cy = 0;
+ int cw = 0;
+ int ch = 0;
+ bool done = false;
+ bool findy = false;
+ $? "+ ChooseChildPosition"
+ p.GetPosition(&px, &py);
+ p.GetSize(&pw, &ph);
+ c.GetSize(&cw, &ch);
+ if (beside) {
+ /* Attempt right side */
+ if (scsz.x > px + pw + cw) {
+ cx = px + pw;
+ done = true;
+ findy = true;
+ }
+ /* Attempt bottom side */
+ if (!done) {
+ if (scsz.y > py + ph + ch) {
+ cy = py + ph;
+ done = true;
+ }
+ }
+ /* Attempt left side */
+ if (!done) {
+ if (px > cw) {
+ cx = px - cw;
+ done = true;
+ findy = true;
+ }
+ }
+ /* Attempt top side */
+ if (!done) {
+ if (py < ch) {
+ cy = py - ch;
+ done = true;
+ }
+ }
+ if (done) {
+ if (findy) {
+ if (scsz.y > (py + ch)) {
+ cy = py;
+ } else {
+ if (0 <= (py + ph - ch)) {
+ cy = py + ph - ch;
+ } else {
+ cy = py + (ph - ch) / 2;
+ if (scsz.y <= (cy + ch)) {
+ cy = scsz.y - ch - 1;
+ }
+ if (0 > cy) {
+ cy = 0;
+ }
+ }
+ }
+ } else {
+ if (scsz.x > (px + cw)) {
+ cx = px;
+ } else {
+ if (0 <= (px + pw - cw)) {
+ cx = px + pw - cw;
+ } else {
+ cx = px + (pw - cw) / 2;
+ if (scsz.x <= (cx + cw)) {
+ cx = scsz.x - cw - 1;
+ }
+ if (0 > cx) {
+ cx = 0;
+ }
+ }
+ }
+ }
+ c.SetSize(cx, cy, cw, ch);
+ }
+ }
+ if (!done) {
+ cx = px + (pw - cw) / 2;
+ cy = py + (ph - ch) / 2;
+ Dk4WxApplicationHelper::CorrectPosition(cx, cy, cw, ch);
+ c.SetSize(cx, cy, cw, ch);
+ }
+ $? "- ChooseChildPosition"
+}
+
+
+
+size_t
+Dk4WxApplicationHelper::StringTableSize(const wxChar * const *sttptr)
+{
+ size_t back = 0;
+ $? "+ StringTableSize"
+ if (NULL != sttptr) {
+ while (NULL != *(sttptr++)) { back++; }
+ } $? "- StringTableSize %lu", (unsigned long)back
+ return back;
+}
+
+
+
+void
+Dk4WxApplicationHelper::ReleaseWxcharStringArray(
+ wxChar **array, size_t sz, bool ea
+)
+{
+ wxChar **ap;
+ if ((NULL != array) && (0 < sz)) {
+ ap = array;
+ while (0 < sz--) {
+ dk4mem_release(*array);
+ array++;
+ }
+ if (ea) { dk4mem_free(ap); }
+ }
+}
+
diff --git a/support/dktools/Dk4WxApplicationHelper.h b/support/dktools/Dk4WxApplicationHelper.h
new file mode 100644
index 0000000000..e84a29d0b2
--- /dev/null
+++ b/support/dktools/Dk4WxApplicationHelper.h
@@ -0,0 +1,754 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: Dk4WxApplicationHelper.cpt
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4WXAPPLICATIONHELPER_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4WXAPPLICATIONHELPER_H_INCLUDED 1
+
+
+#line 9 "Dk4WxApplicationHelper.cpt"
+
+/** @file Dk4WxApplicationHelper.h The Dk4WxApplicationHelper
+ class.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4CONST_H_INCLUDED
+#include "dk4const.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4STO_H_INCLUDED
+#include "dk4sto.h"
+#endif
+
+#ifndef DK4WXCS_H_INCLUDED
+#include "dk4wxcs.h"
+#endif
+
+#ifndef DK4FSH_H_INCLUDED
+#include "dk4fs.h"
+#endif
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include "wx/wxprec.h"
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#ifndef WX_WX_H_INCLUDED
+#include "wx/wx.h"
+#define WX_WX_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef WX_CONFIG_H_INCLUDED
+#include <wx/config.h>
+#define WX_CONFIG_H_INCLUDED 1
+#endif
+
+#ifndef WX_FILENAME_H_INCLUDED
+#include <wx/filename.h>
+#define WX_FILENAME_H_INCLUDED 1
+#endif
+
+#ifndef WX_THREAD_H_INCLUDED
+#include <wx/thread.h>
+#define WX_THREAD_H_INCLUDED 1
+#endif
+
+#ifndef DK4WXSTT_H_INCLUDED
+#include "dk4wxstt.h"
+#endif
+
+
+/** Application helper.
+ Each application should have one application helper object
+ as the member of the wxApp-derived application class.
+ In the applications OnInit() method call the Initialize() method.
+*/
+class Dk4WxApplicationHelper
+{
+ protected:
+
+ /** Synchronization for access from multiple threads.
+ */
+ wxCriticalSection csProtect;
+
+ /** The basic strings for GUIs.
+ */
+ const wxChar * const *ppBasicStrings;
+
+ /** Software vendor name.
+ */
+ const wxChar *pcwxsVendor;
+
+ /** First command line argument.
+ */
+ const wxChar *pcwxsArgv0;
+
+ /** Application group name.
+ */
+ const dkChar *pcdksGroup;
+
+ /** Application name.
+ */
+ wxChar *pwxsApp;
+
+ /** Host name.
+ */
+ dkChar *pdksHost;
+
+ /** Users login name.
+ */
+ dkChar *pdksLogname;
+
+ /** Home directory.
+ */
+ dkChar *pdksHome;
+
+ /** Application name.
+ */
+ dkChar *pdksApp;
+
+ /** System configuration directory.
+ */
+ dkChar *pdksSysconf;
+
+ /** Data directory.
+ */
+ dkChar *pdksShare;
+
+ /** Users language.
+ */
+ dkChar *pdksLanguage;
+
+ /** Users region.
+ */
+ dkChar *pdksRegion;
+
+ /** String tables storage.
+ */
+ dk4_sto_t *sStt;
+
+ /** String tables storage iterator.
+ */
+ dk4_sto_it_t *iStt;
+
+ /** System preferences storage.
+ */
+ dk4_sto_t *sPrSys;
+
+ /** System preferences storage iterator.
+ */
+ dk4_sto_it_t *iPrSys;
+
+ /** User preferences storage.
+ */
+ dk4_sto_t *sPrUser;
+
+ /** User preferences storage iterator.
+ */
+ dk4_sto_it_t *iPrUser;
+
+ /** Number of strings in the ppBasicStrings array.
+ */
+ size_t nBasicStrings;
+
+ /** Encoding for dkChar strings.
+ */
+ int iDkEncoding;
+
+ /** Encoding for wxChar strings.
+ */
+ int iWxEncoding;
+
+ /** Expected encoding for file input.
+ */
+ int iFiEncoding;
+
+ /** Flag: Controller is set up and can be used.
+ */
+ bool bActive;
+
+ protected:
+
+ /** Clean up internal data structures.
+ */
+ void
+ InternalCleanup(void);
+
+
+ /** Search for data file.
+ @param fnb File name buffer.
+ @param szfnb Buffer size (number of dkChar).
+ @param sfn Short file name.
+ @param maxpass Maximum pass number for search.
+ @param aco Flag: Allow compressed versions.
+ @return True if the file was found (name in fnb), false otherwise.
+ */
+ bool
+ InternalFindDataFile(
+ dkChar *fnb,
+ size_t szfnb,
+ dkChar const *sfn,
+ int maxpass,
+ bool aco
+ );
+
+#if DK4_SIZEOF_WXCHAR != DK4_CHAR_SIZE
+
+ /** Search for data file.
+ @param fnb File name buffer.
+ @param szfnb Buffer size (number of wxChar).
+ @param sfn Short file name.
+ @param maxpass Maximum pass number for search.
+ @param aco Flag: Allow compressed versions.
+ @return True if the file was found (name in fnb), false otherwise.
+ */
+ bool
+ InternalFindDataFile(
+ wxChar *fnb,
+ size_t szfnb,
+ dkChar const *sfn,
+ int maxpass,
+ bool aco
+ );
+
+#endif
+
+ /** Convert dkChar string to wxChar string.
+ @param dptr Result buffer.
+ @param dsz Buffer size (number of wxChar).
+ @param sptr Source string.
+ @param erp Error report, may be NULL.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or sptr is NULL or dsz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dptr is too small,
+ - DK4_E_SYNTAX<br>
+ if a non-recodable character was found.
+ */
+ bool
+ InternalStringToWx(
+ wxChar *dptr, size_t dsz, const dkChar *sptr, dk4_er_t *erp
+ );
+
+ /** Convert wxChar string to dkChar string.
+ @param dptr Result buffer.
+ @param dsz Result buffer size (number of dkChar).
+ @param sptr Source string.
+ @param erp Error report, may be NULL.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or sptr is NULL or dsz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dptr is too small,
+ - DK4_E_SYNTAX<br>
+ if a non-recodable character was found.
+ */
+ bool
+ InternalStringToDk(
+ dkChar *dptr, size_t dsz, const wxChar *sptr, dk4_er_t *erp
+ );
+
+ /** Retrieve a string table.
+ @param tableName Short string table file name.
+ @param tableSize Minimum number of elements required in table.
+ @return Pointer to string table found or NULL.
+ */
+ const wxChar * const *
+ InternalGetStringTable(
+ const dkChar *tableName,
+ size_t tableSize
+ );
+
+ /** Save multiple long values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @return True on success, false on error.
+ */
+ bool
+ InternalSetMultiple(const wxChar * const *names, long *array, size_t sz);
+
+ /** Save multiple int values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @return True on success, false on error.
+ */
+ bool
+ InternalSetMultiple(const wxChar * const *names, int *array, size_t sz);
+
+ /** Save multiple bool values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @return True on success, false on error.
+ */
+ bool
+ InternalSetMultiple(const wxChar * const *names, bool *array, size_t sz);
+
+ /** Save multiple double values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @return True on success, false on error.
+ */
+ bool
+ InternalSetMultiple(const wxChar * const *names, double *array, size_t sz);
+
+ /** Save multiple string values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @return True on success, false on error.
+ */
+ bool
+ InternalSetMultiple(
+ const wxChar * const *names, const wxChar * const *array, size_t sz
+ );
+
+ /** Retrieve multiple long values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @return True on success, false on error.
+ */
+ bool
+ InternalGetMultiple(const wxChar * const *names, long *array, size_t sz);
+
+ /** Retrieve multiple int values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @return True on success, false on error.
+ */
+ bool
+ InternalGetMultiple(const wxChar * const *names, int *array, size_t sz);
+
+ /** Retrieve multiple bool values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @return True on success, false on error.
+ */
+ bool
+ InternalGetMultiple(const wxChar * const *names, bool *array, size_t sz);
+
+ /** Retrieve multiple double values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @return True on success, false on error.
+ */
+ bool
+ InternalGetMultiple(const wxChar * const *names, double *array, size_t sz);
+
+ /** Retrieve multiple string values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @param ov Flag: Overwrite existing strings.
+ Memory for already existing strings is freed, memory for the new
+ found string is allocated if the flag is set. Existing strings
+ are left untouched if the flag is not set.
+ @return True on success, false on error.
+ */
+ bool
+ InternalGetMultiple(
+ const wxChar * const *names, wxChar **array, size_t sz, bool ov = true
+ );
+
+ public:
+
+ /** Default constructor.
+ */
+ Dk4WxApplicationHelper();
+
+ /** Destructor.
+ */
+ ~Dk4WxApplicationHelper();
+
+ /** Initialize before used, called from the applications OnInit() method.
+ If this method returns false, the OnInit() method should return
+ false too.
+ @param argv0 First command line argument.
+ @param vendorName Software vendor name.
+ @param groupName Application group name.
+ @param erp Error report, may be NULL.
+ @return True if initialized successfully, false otherwise.
+
+ Error codes:
+ - DK4_E_NOT_FOUND<br>
+ if the system function(s) failed to find the name of the
+ file currently executed or the users home directory
+ or the users home directory or login name,
+ - DK4_E_SYSTEM<br>
+ if the function failed to find the current working directory,
+ - DK4_E_SYNTAX<br>
+ if there are string conversion problems,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the internal buffer is too small to hold the file name
+ of the executed file, the users home directory, login name
+ or a conversion buffer is too small,
+ - DK4_E_SYNTAX<br>
+ if a Windows registry entry differs from the expected type.
+ - DK4_E_MATH_OVERFLOW<br>
+ if a numeric overflow occured in a memory allocation size
+ calculation,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if a memory allocation attempt failed due to insufficient memory.
+
+ */
+ bool
+ Initialize(
+ const wxChar *argv0,
+ const wxChar *vendorName,
+ const dkChar *groupName,
+ dk4_er_t *erp = NULL
+ );
+
+ /** Clean up internal data structures.
+ You should call this from the applications OnExit() method.
+ */
+ void
+ Cleanup(void);
+
+ /** Search for data file.
+ @param fnb File name buffer.
+ @param szfnb Buffer size (number of dkChar).
+ @param sfn Short file name.
+ @param maxpass Maximum pass number for search.
+ @param aco Flag: Allow compressed versions.
+ @return True if the file was found (name in fnb), false otherwise.
+ */
+ bool
+ FindDataFile(
+ dkChar *fnb,
+ size_t szfnb,
+ dkChar const *sfn,
+ int maxpass = DK4_FS_DATA_MAX_SYS,
+ bool aco = false
+ );
+
+#if DK4_SIZEOF_WXCHAR != DK4_CHAR_SIZE
+
+ /** Search for data file.
+ @param fnb File name buffer.
+ @param szfnb Buffer size (number of wxChar).
+ @param sfn Short file name.
+ @param maxpass Maximum pass number for search.
+ @param aco Flag: Allow compressed versions.
+ @return True if the file was found (name in fnb), false otherwise.
+ */
+ bool
+ FindDataFile(
+ wxChar *fnb,
+ size_t szfnb,
+ dkChar const *sfn,
+ int maxpass = DK4_FS_DATA_MAX_SYS,
+ bool aco = false
+ );
+
+#endif
+
+ /** Retrieve dkChar encoding.
+ @return Encoding.
+ */
+ int
+ GetDkEncoding(void);
+
+ /** Retrieve wxChar encoding.
+ @return Encoding.
+ */
+ int
+ GetWxEncoding(void);
+
+ /** Retrieve expected input encoding when reading files.
+ @return Encoding.
+ */
+ int
+ GetFiEncoding(void);
+
+ /** Retrieve a string table.
+ @param tableName Short string table file name.
+ @param defaultTable Default strings to use if not found.
+ @return Pointer to string table found or defaultTable.
+ */
+ const wxChar * const *
+ GetStringTable(
+ const dkChar *tableName,
+ const wxChar * const *defaultTable
+ );
+
+ /** Retrieve one of the basic strings.
+ @param numstr Index of string in basic strings array.
+ @return String pointer on success, NULL on error (index out of range).
+ */
+ const wxChar *
+ GetBasicString(size_t numstr);
+
+ /** Retrieve entire basic strings array.
+ @param pNumBasicStrings Address of variable to store the
+ array length, may be NULL.
+ @return Pointer to array of basic strings.
+ */
+ const wxChar * const *
+ GetBasicStrings(size_t *pNumBasicStrings = NULL);
+
+ /** Convert dkChar string to wxChar string.
+ @param dptr Result buffer.
+ @param dsz Buffer size (number of wxChar).
+ @param sptr Source string.
+ @param erp Error report, may be NULL.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or sptr is NULL or dsz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dptr is too small,
+ - DK4_E_SYNTAX<br>
+ if a non-recodable character was found.
+ */
+ bool
+ StringToWx(
+ wxChar *dptr, size_t dsz, const dkChar *sptr, dk4_er_t *erp = NULL
+ );
+
+ /** Convert wxChar string to dkChar string.
+ @param dptr Result buffer.
+ @param dsz Result buffer size (number of dkChar).
+ @param sptr Source string.
+ @param erp Error report, may be NULL.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or sptr is NULL or dsz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dptr is too small,
+ - DK4_E_SYNTAX<br>
+ if a non-recodable character was found.
+ */
+ bool
+ StringToDk(
+ dkChar *dptr, size_t dsz, const wxChar *sptr, dk4_er_t *erp = NULL
+ );
+
+ /** Convert wxChar string to char string.
+ @param dptr Result buffer.
+ @param dsz Result buffer size (number of char).
+ @param sptr Source string.
+ @param erp Error report, may be NULL.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or sptr is NULL or dsz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dptr is too small,
+ - DK4_E_SYNTAX<br>
+ if a non-recodable character was found.
+ */
+ bool
+ StringToChar(
+ char *dptr, size_t dsz, const wxChar *sptr, dk4_er_t *erp = NULL
+ );
+
+ /** Save multiple long values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @return True on success, false on error.
+ */
+ bool
+ SetMultiple(const wxChar * const *names, long *array, size_t sz);
+
+ /** Save multiple int values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @return True on success, false on error.
+ */
+ bool
+ SetMultiple(const wxChar * const *names, int *array, size_t sz);
+
+ /** Save multiple bool values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @return True on success, false on error.
+ */
+ bool
+ SetMultiple(const wxChar * const *names, bool *array, size_t sz);
+
+ /** Save multiple double values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @return True on success, false on error.
+ */
+ bool
+ SetMultiple(const wxChar * const *names, double *array, size_t sz);
+
+ /** Save multiple string values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @return True on success, false on error.
+ */
+ bool
+ SetMultiple(
+ const wxChar * const *names, const wxChar * const *array, size_t sz
+ );
+
+ /** Retrieve multiple long values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @return True on success, false on error.
+ */
+ bool
+ GetMultiple(const wxChar * const *names, long *array, size_t sz);
+
+ /** Retrieve multiple int values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @return True on success, false on error.
+ */
+ bool
+ GetMultiple(const wxChar * const *names, int *array, size_t sz);
+
+ /** Retrieve multiple bool values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @return True on success, false on error.
+ */
+ bool
+ GetMultiple(const wxChar * const *names, bool *array, size_t sz);
+
+ /** Retrieve multiple double values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @return True on success, false on error.
+ */
+ bool
+ GetMultiple(const wxChar * const *names, double *array, size_t sz);
+
+ /** Retrieve multiple string values.
+ @param names Entry names array, sz elements.
+ @param array Values, sz elements.
+ @param sz Array size for names and array.
+ @param ov Flag: Overwrite existing strings.
+ Memory for already existing strings is freed, memory for the new
+ found string is allocated if the flag is set. Existing strings
+ are left untouched if the flag is not set.
+ @return True on success, false on error.
+ */
+ bool
+ GetMultiple(
+ const wxChar * const *names, wxChar **array, size_t sz, bool ov = true
+ );
+
+ /** Correct top level frame position.
+ @param x Window x position.
+ @param y Window y position.
+ @param w Window width.
+ @param h Window height.
+ */
+ static
+ void
+ CorrectPosition(int & x, int & y, int & w, int & h);
+
+ /** Correct position of a top level window (frame or dialog).
+ @param w Window to correct.
+ */
+ static
+ void
+ CorrectPosition(wxWindow & w);
+
+ /** Choose position for a child top level window (frame or dialog).
+ @param p Parent window, unchanged.
+ @param c Child window, position is set.
+ @param beside Flag: Position child beside parent, not on top.
+ */
+ static
+ void
+ ChooseChildPosition(
+ const wxWindow & p, wxWindow & c, bool beside = false
+ );
+
+ /** Find string table size (number of strings in table).
+ @param sttptr String table to find size for.
+ @return Size of string table.
+ */
+ static
+ size_t
+ StringTableSize(const wxChar * const *sttptr);
+
+ /** Release array of wxChar strings.
+ @param array Array, array contents is to release.
+ @param sz Array size.
+ @param ea Flag: After releasing contents, release array itself.
+ */
+ static
+ void
+ ReleaseWxcharStringArray(wxChar **array, size_t sz, bool ea = false);
+
+};
+
+
+
+#endif
diff --git a/support/dktools/Dk4WxAutostartController.cpp b/support/dktools/Dk4WxAutostartController.cpp
new file mode 100644
index 0000000000..81522bc2ee
--- /dev/null
+++ b/support/dktools/Dk4WxAutostartController.cpp
@@ -0,0 +1,179 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: Dk4WxAutostartController.cpt
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file Dk4WxAutostartController.cpp The Dk4WxAutostartController module.
+*/
+
+
+#line 166 "Dk4WxAutostartController.cpt"
+
+
+#include "Dk4WxAutostartController.h"
+
+
+
+
+
+#line 173 "Dk4WxAutostartController.cpt"
+
+
+
+/** Internal controller state.
+*/
+enum {
+
+ /** No idle event received yet.
+ */
+ DK4WX_AUTOSTART_STATE_NONE = 0 ,
+
+ /** Expecting start processing.
+ */
+ DK4WX_AUTOSTART_STATE_EXPECT_START ,
+
+ /** In processing.
+ */
+ DK4WX_AUTOSTART_STATE_PROCESSING ,
+
+ /** Processing finished,
+ expecting application end.
+ */
+ DK4WX_AUTOSTART_STATE_EXPECT_EXIT ,
+
+ /** Processing finished.
+ */
+ DK4WX_AUTOSTART_STATE_FINISHED
+};
+
+
+
+Dk4WxAutostartController::Dk4WxAutostartController()
+{
+ iExitTime = (dk4_time_t)0UL;
+ iState = DK4WX_AUTOSTART_STATE_NONE;
+ bAutostart = false;
+ bAutoexit = false;
+}
+
+
+
+void
+Dk4WxAutostartController::SetAutoStart(bool fl)
+{
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ bAutostart = fl;
+ }
+}
+
+
+
+void
+Dk4WxAutostartController::SetAutoExit(bool fl)
+{
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ bAutoexit = fl;
+ }
+}
+
+
+
+int
+Dk4WxAutostartController::GetReaction(void)
+{
+ dk4_time_t timer = (dk4_time_t)0UL;
+ int back = DK4WX_AUTOSTART_REACTION_IGNORE;
+
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ switch (iState) {
+ case DK4WX_AUTOSTART_STATE_NONE : {
+ if (bAutostart) {
+ back = DK4WX_AUTOSTART_REACTION_START;
+ iState = DK4WX_AUTOSTART_STATE_EXPECT_START;
+ }
+ } break;
+#if 0
+ case DK4WX_AUTOSTART_STATE_EXPECT_START : {
+ } break;
+ case DK4WX_AUTOSTART_STATE_PROCESSING : {
+ } break;
+#endif
+ case DK4WX_AUTOSTART_STATE_EXPECT_EXIT : {
+ back = DK4WX_AUTOSTART_REACTION_MORE;
+ dk4time_get(&timer);
+ if (timer >= iExitTime) {
+ iState = DK4WX_AUTOSTART_STATE_FINISHED;
+ back = DK4WX_AUTOSTART_REACTION_EXIT;
+ }
+ } break;
+#if 0
+ case DK4WX_AUTOSTART_STATE_FINISHED : {
+ } break;
+#endif
+ }
+ }
+ return back;
+}
+
+
+
+void
+Dk4WxAutostartController::StartProcessing(void)
+{
+ wxCriticalSectionLocker lock(csProtect);
+ iState = DK4WX_AUTOSTART_STATE_PROCESSING;
+}
+
+
+
+void
+Dk4WxAutostartController::EndProcessing(bool success)
+{
+ dk4_time_t timer = (dk4_time_t)0UL;
+ dk4time_get(&timer);
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ if ((bAutostart) && (bAutoexit) && (success)) {
+ iExitTime = timer + (dk4_time_t)2UL;
+ iState = DK4WX_AUTOSTART_STATE_EXPECT_EXIT;
+ } else {
+ iState = DK4WX_AUTOSTART_STATE_FINISHED;
+ }
+ }
+}
+
+
+
diff --git a/support/dktools/Dk4WxAutostartController.cpt b/support/dktools/Dk4WxAutostartController.cpt
new file mode 100644
index 0000000000..d18022d60b
--- /dev/null
+++ b/support/dktools/Dk4WxAutostartController.cpt
@@ -0,0 +1,302 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file Dk4WxAutostartController.h Autostart controller.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4CONST_H_INCLUDED
+#include "dk4const.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4TIME_H_INCLUDED
+#include "dk4time.h"
+#endif
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include "wx/wxprec.h"
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#ifndef WX_WX_H_INCLUDED
+#include "wx/wx.h"
+#define WX_WX_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef WX_THREAD_H_INCLUDED
+#include <wx/thread.h>
+#define WX_THREAD_H_INCLUDED 1
+#endif
+
+
+/** Reactions on idle events.
+*/
+enum {
+
+ /** Ignore the event, we are done.
+ */
+ DK4WX_AUTOSTART_REACTION_IGNORE = 0 ,
+
+ /** Start autorun.
+ */
+ DK4WX_AUTOSTART_REACTION_START ,
+
+ /** Request more idle events.
+ */
+ DK4WX_AUTOSTART_REACTION_MORE ,
+
+ /** Exit the application.
+ */
+ DK4WX_AUTOSTART_REACTION_EXIT
+};
+
+
+/** Controller to check whether or not to start an autostart run
+ on idle events.
+*/
+class Dk4WxAutostartController
+{
+ protected:
+
+ /** Synchronize access from multiple threads or events.
+ */
+ wxCriticalSection csProtect;
+
+ /** Time for automatic exit.
+ */
+ dk4_time_t iExitTime;
+
+ /** Current controller state.
+ */
+ int iState;
+
+ /** Flag: Start automatically.
+ */
+ bool bAutostart;
+
+ /** Flag: Exit after successfull processing via autostart.
+ */
+ bool bAutoexit;
+
+ public:
+
+ /** Default controller.
+ */
+ Dk4WxAutostartController();
+
+ /** Enable auto start.
+ Call this function from the frames constructor.
+ @param fl Flag to enable/disable auto start.
+ */
+ void
+ SetAutoStart(bool fl);
+
+ /** Enable auto exit.
+ An application can exit automatically if no feedback is required
+ after an automatic one-time processing resulting in success.
+ Example: A program to schedule a file to a print queue invoked
+ via the file managers context menu. The program should immediately
+ transfer the file to the print queue, so you enable auto start.
+ After completing successfully you want the program to exit immediately.
+ Call this function from the frames constructor.
+ @param fl Flag to enable/disable auto exit.
+ */
+ void
+ SetAutoExit(bool fl);
+
+ /** Get reaction for one idle event.
+ This function is typically called from the frames idle event
+ handler to decide what to do.
+ @return One from:
+ - DK4WX_AUTOSTART_REACTION_IGNORE<br>
+ to ignore the idle event,
+ - DK4WX_AUTOSTART_REACTION_START<br>
+ to start an automatic run,
+ - DK4WX_AUTOSTART_REACTION_MORE<br>
+ to request more idle events, or
+ - DK4WX_AUTOSTART_REACTION_EXIT<br>
+ to exit the application.
+ */
+ int
+ GetReaction(void);
+
+ /** Indicate to the controller that processing was started.
+ Call this function to indicate start of processing.
+ Should be called for both auto start runs and manually started runs.
+ */
+ void
+ StartProcessing(void);
+
+ /** Indicate end of processing.
+ Should be called for both auto start runs and manually started runs.
+ @param success Result from processing.
+ */
+ void
+ EndProcessing(bool success = true);
+
+};
+
+
+
+
+%% module
+
+
+#include "Dk4WxAutostartController.h"
+
+
+
+$!trace-include
+
+
+
+/** Internal controller state.
+*/
+enum {
+
+ /** No idle event received yet.
+ */
+ DK4WX_AUTOSTART_STATE_NONE = 0 ,
+
+ /** Expecting start processing.
+ */
+ DK4WX_AUTOSTART_STATE_EXPECT_START ,
+
+ /** In processing.
+ */
+ DK4WX_AUTOSTART_STATE_PROCESSING ,
+
+ /** Processing finished,
+ expecting application end.
+ */
+ DK4WX_AUTOSTART_STATE_EXPECT_EXIT ,
+
+ /** Processing finished.
+ */
+ DK4WX_AUTOSTART_STATE_FINISHED
+};
+
+
+
+Dk4WxAutostartController::Dk4WxAutostartController()
+{
+ iExitTime = (dk4_time_t)0UL;
+ iState = DK4WX_AUTOSTART_STATE_NONE;
+ bAutostart = false;
+ bAutoexit = false;
+}
+
+
+
+void
+Dk4WxAutostartController::SetAutoStart(bool fl)
+{
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ bAutostart = fl;
+ }
+}
+
+
+
+void
+Dk4WxAutostartController::SetAutoExit(bool fl)
+{
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ bAutoexit = fl;
+ }
+}
+
+
+
+int
+Dk4WxAutostartController::GetReaction(void)
+{
+ dk4_time_t timer = (dk4_time_t)0UL;
+ int back = DK4WX_AUTOSTART_REACTION_IGNORE;
+
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ switch (iState) {
+ case DK4WX_AUTOSTART_STATE_NONE : {
+ if (bAutostart) {
+ back = DK4WX_AUTOSTART_REACTION_START;
+ iState = DK4WX_AUTOSTART_STATE_EXPECT_START;
+ }
+ } break;
+#if 0
+ case DK4WX_AUTOSTART_STATE_EXPECT_START : {
+ } break;
+ case DK4WX_AUTOSTART_STATE_PROCESSING : {
+ } break;
+#endif
+ case DK4WX_AUTOSTART_STATE_EXPECT_EXIT : {
+ back = DK4WX_AUTOSTART_REACTION_MORE;
+ dk4time_get(&timer);
+ if (timer >= iExitTime) {
+ iState = DK4WX_AUTOSTART_STATE_FINISHED;
+ back = DK4WX_AUTOSTART_REACTION_EXIT;
+ }
+ } break;
+#if 0
+ case DK4WX_AUTOSTART_STATE_FINISHED : {
+ } break;
+#endif
+ }
+ }
+ return back;
+}
+
+
+
+void
+Dk4WxAutostartController::StartProcessing(void)
+{
+ wxCriticalSectionLocker lock(csProtect);
+ iState = DK4WX_AUTOSTART_STATE_PROCESSING;
+}
+
+
+
+void
+Dk4WxAutostartController::EndProcessing(bool success)
+{
+ dk4_time_t timer = (dk4_time_t)0UL;
+ dk4time_get(&timer);
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ if ((bAutostart) && (bAutoexit) && (success)) {
+ iExitTime = timer + (dk4_time_t)2UL;
+ iState = DK4WX_AUTOSTART_STATE_EXPECT_EXIT;
+ } else {
+ iState = DK4WX_AUTOSTART_STATE_FINISHED;
+ }
+ }
+}
+
+
+
diff --git a/support/dktools/Dk4WxAutostartController.h b/support/dktools/Dk4WxAutostartController.h
new file mode 100644
index 0000000000..edcc68791b
--- /dev/null
+++ b/support/dktools/Dk4WxAutostartController.h
@@ -0,0 +1,199 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: Dk4WxAutostartController.cpt
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4WXAUTOSTARTCONTROLLER_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4WXAUTOSTARTCONTROLLER_H_INCLUDED 1
+
+
+#line 9 "Dk4WxAutostartController.cpt"
+
+/** @file Dk4WxAutostartController.h Autostart controller.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4CONST_H_INCLUDED
+#include "dk4const.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4TIME_H_INCLUDED
+#include "dk4time.h"
+#endif
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include "wx/wxprec.h"
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#ifndef WX_WX_H_INCLUDED
+#include "wx/wx.h"
+#define WX_WX_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef WX_THREAD_H_INCLUDED
+#include <wx/thread.h>
+#define WX_THREAD_H_INCLUDED 1
+#endif
+
+
+/** Reactions on idle events.
+*/
+enum {
+
+ /** Ignore the event, we are done.
+ */
+ DK4WX_AUTOSTART_REACTION_IGNORE = 0 ,
+
+ /** Start autorun.
+ */
+ DK4WX_AUTOSTART_REACTION_START ,
+
+ /** Request more idle events.
+ */
+ DK4WX_AUTOSTART_REACTION_MORE ,
+
+ /** Exit the application.
+ */
+ DK4WX_AUTOSTART_REACTION_EXIT
+};
+
+
+/** Controller to check whether or not to start an autostart run
+ on idle events.
+*/
+class Dk4WxAutostartController
+{
+ protected:
+
+ /** Synchronize access from multiple threads or events.
+ */
+ wxCriticalSection csProtect;
+
+ /** Time for automatic exit.
+ */
+ dk4_time_t iExitTime;
+
+ /** Current controller state.
+ */
+ int iState;
+
+ /** Flag: Start automatically.
+ */
+ bool bAutostart;
+
+ /** Flag: Exit after successfull processing via autostart.
+ */
+ bool bAutoexit;
+
+ public:
+
+ /** Default controller.
+ */
+ Dk4WxAutostartController();
+
+ /** Enable auto start.
+ Call this function from the frames constructor.
+ @param fl Flag to enable/disable auto start.
+ */
+ void
+ SetAutoStart(bool fl);
+
+ /** Enable auto exit.
+ An application can exit automatically if no feedback is required
+ after an automatic one-time processing resulting in success.
+ Example: A program to schedule a file to a print queue invoked
+ via the file managers context menu. The program should immediately
+ transfer the file to the print queue, so you enable auto start.
+ After completing successfully you want the program to exit immediately.
+ Call this function from the frames constructor.
+ @param fl Flag to enable/disable auto exit.
+ */
+ void
+ SetAutoExit(bool fl);
+
+ /** Get reaction for one idle event.
+ This function is typically called from the frames idle event
+ handler to decide what to do.
+ @return One from:
+ - DK4WX_AUTOSTART_REACTION_IGNORE<br>
+ to ignore the idle event,
+ - DK4WX_AUTOSTART_REACTION_START<br>
+ to start an automatic run,
+ - DK4WX_AUTOSTART_REACTION_MORE<br>
+ to request more idle events, or
+ - DK4WX_AUTOSTART_REACTION_EXIT<br>
+ to exit the application.
+ */
+ int
+ GetReaction(void);
+
+ /** Indicate to the controller that processing was started.
+ Call this function to indicate start of processing.
+ Should be called for both auto start runs and manually started runs.
+ */
+ void
+ StartProcessing(void);
+
+ /** Indicate end of processing.
+ Should be called for both auto start runs and manually started runs.
+ @param success Result from processing.
+ */
+ void
+ EndProcessing(bool success = true);
+
+};
+
+
+
+
+
+#endif
diff --git a/support/dktools/Dk4WxControl.cpp b/support/dktools/Dk4WxControl.cpp
new file mode 100644
index 0000000000..49fc86e6ff
--- /dev/null
+++ b/support/dktools/Dk4WxControl.cpp
@@ -0,0 +1,304 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: Dk4WxControl.cpt
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file Dk4WxControl.cpp The Dk4WxControl module.
+*/
+
+
+#line 205 "Dk4WxControl.cpt"
+
+#include "Dk4WxControl.h"
+
+
+
+
+
+#line 211 "Dk4WxControl.cpt"
+
+
+
+const wxChar Dk4WxControl::Dk4WxControlName[] = { wxT("Dk4WxControl") };
+
+
+IMPLEMENT_DYNAMIC_CLASS(Dk4WxControl, wxControl)
+
+BEGIN_EVENT_TABLE(Dk4WxControl, wxControl)
+ EVT_ERASE_BACKGROUND(Dk4WxControl::OnErase)
+ EVT_PAINT(Dk4WxControl::OnPaint)
+END_EVENT_TABLE()
+
+
+
+Dk4WxControl::Dk4WxControl()
+: wxControl()
+{
+
+
+#line 230 "Dk4WxControl.cpt"
+ pBitmap = NULL;
+ iBmWidth = -1;
+ iBmHeight = -1;
+ SetBackgroundStyle(wxBG_STYLE_CUSTOM);
+
+
+#line 235 "Dk4WxControl.cpt"
+}
+
+
+
+bool
+Dk4WxControl::Create(
+ wxWindow *parent,
+ wxWindowID wid,
+ const wxPoint & pos,
+ const wxSize & size,
+ long style,
+ const wxValidator & validator,
+ const wxChar *name
+)
+{
+ bool back;
+
+
+#line 252 "Dk4WxControl.cpt"
+ back = wxControl::Create(
+ parent, wid, pos, size, style, validator, name
+ );
+ pBitmap = NULL;
+ iBmWidth = -1;
+ iBmHeight = -1;
+ SetBackgroundStyle(wxBG_STYLE_CUSTOM);
+
+
+#line 260 "Dk4WxControl.cpt"
+ return back;
+}
+
+
+
+Dk4WxControl::Dk4WxControl(
+ wxWindow *parent,
+ wxWindowID wid,
+ const wxPoint & pos,
+ const wxSize & size,
+ long style,
+ const wxValidator & validator,
+ const wxChar *name
+)
+: wxControl( parent, wid, pos, size, style, validator, wxString(name))
+{
+
+
+#line 277 "Dk4WxControl.cpt"
+ pBitmap = NULL;
+ iBmWidth = -1;
+ iBmHeight = -1;
+ SetBackgroundStyle(wxBG_STYLE_CUSTOM);
+
+
+#line 282 "Dk4WxControl.cpt"
+}
+
+
+
+Dk4WxControl::~Dk4WxControl()
+{
+
+
+#line 289 "Dk4WxControl.cpt"
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ if (NULL != pBitmap) { delete(pBitmap); }
+ pBitmap = NULL;
+ iBmWidth = -1;
+ iBmHeight = -1;
+ }
+
+
+#line 297 "Dk4WxControl.cpt"
+}
+
+
+
+void
+Dk4WxControl::OnErase(wxEraseEvent & event)
+{
+
+
+#line 305 "Dk4WxControl.cpt"
+
+
+#line 306 "Dk4WxControl.cpt"
+}
+
+
+
+void
+Dk4WxControl::PaintOperation(
+ wxDC & pdc,
+ wxPaintEvent & event,
+ bool buffered,
+ int clWidth,
+ int clHeight
+)
+{
+ pdc.SetBrush(*wxWHITE_BRUSH);
+ pdc.DrawRectangle(0, 0, clWidth, clHeight);
+}
+
+
+
+void
+Dk4WxControl::InternalPaint(
+ wxDC & pdc,
+ wxPaintEvent & event,
+ bool buffered,
+ int clWidth,
+ int clHeight
+)
+{
+ /* Save current DC settings.
+ */
+ wxBrush const br = pdc.GetBrush();
+ wxBrush const bg = pdc.GetBackground();
+ wxFont const fn = pdc.GetFont();
+ wxPen const pn = pdc.GetPen();
+ wxColour const tbg = pdc.GetTextBackground();
+ wxColour const tfg = pdc.GetTextForeground();
+ int bgm = pdc.GetBackgroundMode();
+
+
+#line 344 "Dk4WxControl.cpt"
+ /* Do the real pain operation.
+ */
+ PaintOperation(pdc, event, buffered, clWidth, clHeight);
+ /* Restore DC settings from start.
+ */
+ pdc.SetBackgroundMode(bgm);
+ pdc.SetTextForeground(tfg);
+ pdc.SetTextBackground(tbg);
+ pdc.SetPen(pn);
+ pdc.SetFont(fn);
+ pdc.SetBackground(bg);
+ pdc.SetBrush(br);
+
+
+#line 357 "Dk4WxControl.cpt"
+}
+
+
+
+void
+Dk4WxControl::OnPaint(wxPaintEvent & event)
+{
+ wxPaintDC paintDC(this);
+ int w = 0;
+ int h = 0;
+ bool mustDraw = false;
+ bool done = false;
+
+
+#line 370 "Dk4WxControl.cpt"
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ wxSize sz = GetClientSize();
+ mustDraw = bUpdate;
+#if VERSION_BEFORE_20150821
+ w = iBmWidth;
+ h = iBmHeight;
+#endif
+ if (NULL != pBitmap) {
+ if ((iBmWidth != sz.x) || (iBmHeight != sz.y)) {
+ delete(pBitmap);
+ pBitmap = NULL;
+ }
+ }
+ w = iBmWidth = sz.x;
+ h = iBmHeight = sz.y;
+ if (NULL == pBitmap) {
+ pBitmap = new wxBitmap(iBmWidth, iBmHeight);
+ mustDraw = true;
+ }
+ if (NULL != pBitmap) {
+ if (mustDraw) {
+ wxMemoryDC memDC;
+ memDC.SelectObject(*pBitmap);
+ InternalPaint(memDC, event, true, w, h);
+ memDC.SelectObject(wxNullBitmap);
+ bUpdate = false;
+ }
+ paintDC.DrawBitmap(*pBitmap, 0, 0, false);
+ done = true;
+ }
+ }
+ if (!(done)) {
+ InternalPaint(paintDC, event, false, w, h);
+ }
+
+
+#line 406 "Dk4WxControl.cpt"
+}
+
+
+
+void
+Dk4WxControl::SetUpdate(bool flag)
+{
+
+
+#line 414 "Dk4WxControl.cpt"
+ if (flag) {
+ wxCriticalSectionLocker lock(csProtect);
+ bUpdate = true;
+ }
+
+
+#line 419 "Dk4WxControl.cpt"
+}
+
+
+
+void
+Dk4WxControl::ReleaseBuffer(void)
+{
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ if (NULL != pBitmap) {
+ delete(pBitmap);
+ pBitmap = NULL;
+ }
+ }
+}
+
diff --git a/support/dktools/Dk4WxControl.cpt b/support/dktools/Dk4WxControl.cpt
new file mode 100644
index 0000000000..76a0ffc8c7
--- /dev/null
+++ b/support/dktools/Dk4WxControl.cpt
@@ -0,0 +1,434 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file Dk4WxControl.h Triple-buffered control.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED 1
+#endif
+#endif
+
+
+
+/** Base class for user-defined controls.
+ Like double-buffering we write the windows contents
+ to an image and finally transfer the entire image
+ to the device context.
+ Additionally we keep the image between the paint events
+ and rebuild the image only if necessary (data to show
+ has changed).
+
+ When the frame containing your view becomes invisible
+ (frame iconized or hidden) you should use the ReleaseBuffer()
+ method to decrease the memory footprint of the program.
+
+ In your derived class, call the Dk4WxControl constructors from
+ the constructors.
+ From Create() call Dk4WxControl::Create().
+
+ You should also use DECLARE_DYNAMIC_CLASS() and
+ IMPLEMENT_DYNAMIC_CLASS().
+*/
+class Dk4WxControl : public wxControl
+{
+ private:
+
+ /** For RTTI.
+ */
+ DECLARE_DYNAMIC_CLASS(Dk4WxControl)
+
+ /** Event table.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ /** Class name.
+ */
+ static const wxChar Dk4WxControlName[];
+
+ /** Protection against simultaneous access.
+ */
+ wxCriticalSection csProtect;
+
+ /** Bitmap to cache contents.
+ */
+ wxBitmap *pBitmap;
+
+ /** Bitmap width.
+ */
+ int iBmWidth;
+
+ /** Bitmap height.
+ */
+ int iBmHeight;
+
+ /** Flag: Must update contents.
+ */
+ bool bUpdate;
+
+ protected:
+
+ /** Overwrite this method to do the real drawing.
+ @param pdc Device context to draw to.
+ @param event Paint event to draw for.
+ @param buffered Flag: Operating on memory DC.
+ @param clWidth Client area width.
+ @param clHeight Client area height.
+ */
+ virtual
+ void
+ PaintOperation(
+ wxDC & pdc,
+ wxPaintEvent & event,
+ bool buffered,
+ int clWidth,
+ int clHeight
+ );
+
+ /** Internal paint operation.
+ @param pdc Device context to draw to.
+ @param event Paint event to draw for.
+ @param buffered Flag: Operating on memory DC.
+ @param clWidth Client area width.
+ @param clHeight Client area height.
+ */
+ void
+ InternalPaint(
+ wxDC & pdc,
+ wxPaintEvent & event,
+ bool buffered,
+ int clWidth,
+ int clHeight
+ );
+
+ public:
+
+ /** Default constructor.
+ */
+ Dk4WxControl();
+
+ /** Useful constructor.
+ @param parent Parent window.
+ @param wid Window ID.
+ @param pos Position.
+ @param size Size.
+ @param style Style.
+ @param validator Validator.
+ @param name Type name.
+ */
+ Dk4WxControl(
+ wxWindow *parent,
+ wxWindowID wid = wxID_ANY,
+ const wxPoint & pos = wxDefaultPosition,
+ const wxSize & size = wxDefaultSize,
+ long style = 0L,
+ const wxValidator & validator = wxDefaultValidator,
+ const wxChar *name = Dk4WxControlName
+ );
+
+ /** Create window after using default constructor.
+ @param parent Parent window.
+ @param wid Window ID.
+ @param pos Position.
+ @param size Size.
+ @param style Style.
+ @param validator Validator.
+ @param name Type name.
+ */
+ bool
+ Create(
+ wxWindow *parent,
+ wxWindowID wid = wxID_ANY,
+ const wxPoint & pos = wxDefaultPosition,
+ const wxSize & size = wxDefaultSize,
+ long style = 0L,
+ const wxValidator & validator = wxDefaultValidator,
+ const wxChar *name = Dk4WxControlName
+ );
+
+ /** Destructor.
+ */
+ ~Dk4WxControl();
+
+ /** Mark update necessarity.
+ */
+ void
+ SetUpdate(bool flag = true);
+
+ /** Handler for erase background event.
+ @param event Event to process.
+ */
+ void
+ OnErase(wxEraseEvent & event);
+
+ /** Handler for paint event.
+ @param event Event to process.
+ */
+ void
+ OnPaint(wxPaintEvent & event);
+
+ /** Release buffer when frame is iconized or hidden.
+ */
+ void
+ ReleaseBuffer(void);
+};
+
+
+
+%% module
+
+#include "Dk4WxControl.h"
+
+
+
+$!trace-include
+
+
+
+const wxChar Dk4WxControl::Dk4WxControlName[] = { wxT("Dk4WxControl") };
+
+
+IMPLEMENT_DYNAMIC_CLASS(Dk4WxControl, wxControl)
+
+BEGIN_EVENT_TABLE(Dk4WxControl, wxControl)
+ EVT_ERASE_BACKGROUND(Dk4WxControl::OnErase)
+ EVT_PAINT(Dk4WxControl::OnPaint)
+END_EVENT_TABLE()
+
+
+
+Dk4WxControl::Dk4WxControl()
+: wxControl()
+{
+ $? "+ Dk4WxControl()"
+ pBitmap = NULL;
+ iBmWidth = -1;
+ iBmHeight = -1;
+ SetBackgroundStyle(wxBG_STYLE_CUSTOM);
+ $? "- Dk4WxControl()"
+}
+
+
+
+bool
+Dk4WxControl::Create(
+ wxWindow *parent,
+ wxWindowID wid,
+ const wxPoint & pos,
+ const wxSize & size,
+ long style,
+ const wxValidator & validator,
+ const wxChar *name
+)
+{
+ bool back;
+ $? "+ Create"
+ back = wxControl::Create(
+ parent, wid, pos, size, style, validator, name
+ );
+ pBitmap = NULL;
+ iBmWidth = -1;
+ iBmHeight = -1;
+ SetBackgroundStyle(wxBG_STYLE_CUSTOM);
+ $? "- Create"
+ return back;
+}
+
+
+
+Dk4WxControl::Dk4WxControl(
+ wxWindow *parent,
+ wxWindowID wid,
+ const wxPoint & pos,
+ const wxSize & size,
+ long style,
+ const wxValidator & validator,
+ const wxChar *name
+)
+: wxControl( parent, wid, pos, size, style, validator, wxString(name))
+{
+ $? "+ Dk4WxControl(...)"
+ pBitmap = NULL;
+ iBmWidth = -1;
+ iBmHeight = -1;
+ SetBackgroundStyle(wxBG_STYLE_CUSTOM);
+ $? "- Dk4WxControl(...)"
+}
+
+
+
+Dk4WxControl::~Dk4WxControl()
+{
+ $? "+ ~Dk4WxControl"
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ if (NULL != pBitmap) { delete(pBitmap); }
+ pBitmap = NULL;
+ iBmWidth = -1;
+ iBmHeight = -1;
+ }
+ $? "- ~Dk4WxControl"
+}
+
+
+
+void
+Dk4WxControl::OnErase(wxEraseEvent & event)
+{
+ $? "+ OnErase"
+ $? "- OnErase"
+}
+
+
+
+void
+Dk4WxControl::PaintOperation(
+ wxDC & pdc,
+ wxPaintEvent & event,
+ bool buffered,
+ int clWidth,
+ int clHeight
+)
+{
+ pdc.SetBrush(*wxWHITE_BRUSH);
+ pdc.DrawRectangle(0, 0, clWidth, clHeight);
+}
+
+
+
+void
+Dk4WxControl::InternalPaint(
+ wxDC & pdc,
+ wxPaintEvent & event,
+ bool buffered,
+ int clWidth,
+ int clHeight
+)
+{
+ /* Save current DC settings.
+ */
+ wxBrush const br = pdc.GetBrush();
+ wxBrush const bg = pdc.GetBackground();
+ wxFont const fn = pdc.GetFont();
+ wxPen const pn = pdc.GetPen();
+ wxColour const tbg = pdc.GetTextBackground();
+ wxColour const tfg = pdc.GetTextForeground();
+ int bgm = pdc.GetBackgroundMode();
+ $? "+ InternalPaint"
+ /* Do the real pain operation.
+ */
+ PaintOperation(pdc, event, buffered, clWidth, clHeight);
+ /* Restore DC settings from start.
+ */
+ pdc.SetBackgroundMode(bgm);
+ pdc.SetTextForeground(tfg);
+ pdc.SetTextBackground(tbg);
+ pdc.SetPen(pn);
+ pdc.SetFont(fn);
+ pdc.SetBackground(bg);
+ pdc.SetBrush(br);
+ $? "- InternalPaint"
+}
+
+
+
+void
+Dk4WxControl::OnPaint(wxPaintEvent & event)
+{
+ wxPaintDC paintDC(this);
+ int w = 0;
+ int h = 0;
+ bool mustDraw = false;
+ bool done = false;
+ $? "+ OnPaint"
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ wxSize sz = GetClientSize();
+ mustDraw = bUpdate;
+#if VERSION_BEFORE_20150821
+ w = iBmWidth;
+ h = iBmHeight;
+#endif
+ if (NULL != pBitmap) {
+ if ((iBmWidth != sz.x) || (iBmHeight != sz.y)) {
+ delete(pBitmap);
+ pBitmap = NULL;
+ }
+ }
+ w = iBmWidth = sz.x;
+ h = iBmHeight = sz.y;
+ if (NULL == pBitmap) {
+ pBitmap = new wxBitmap(iBmWidth, iBmHeight);
+ mustDraw = true;
+ }
+ if (NULL != pBitmap) {
+ if (mustDraw) {
+ wxMemoryDC memDC;
+ memDC.SelectObject(*pBitmap);
+ InternalPaint(memDC, event, true, w, h);
+ memDC.SelectObject(wxNullBitmap);
+ bUpdate = false;
+ }
+ paintDC.DrawBitmap(*pBitmap, 0, 0, false);
+ done = true;
+ }
+ }
+ if (!(done)) {
+ InternalPaint(paintDC, event, false, w, h);
+ }
+ $? "- OnPaint"
+}
+
+
+
+void
+Dk4WxControl::SetUpdate(bool flag)
+{
+ $? "+ SetUpdate"
+ if (flag) {
+ wxCriticalSectionLocker lock(csProtect);
+ bUpdate = true;
+ }
+ $? "- SetUpdate"
+}
+
+
+
+void
+Dk4WxControl::ReleaseBuffer(void)
+{
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ if (NULL != pBitmap) {
+ delete(pBitmap);
+ pBitmap = NULL;
+ }
+ }
+}
+
diff --git a/support/dktools/Dk4WxControl.h b/support/dktools/Dk4WxControl.h
new file mode 100644
index 0000000000..26ec3a9934
--- /dev/null
+++ b/support/dktools/Dk4WxControl.h
@@ -0,0 +1,237 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: Dk4WxControl.cpt
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4WXCONTROL_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4WXCONTROL_H_INCLUDED 1
+
+
+#line 10 "Dk4WxControl.cpt"
+
+/** @file Dk4WxControl.h Triple-buffered control.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED 1
+#endif
+#endif
+
+
+
+/** Base class for user-defined controls.
+ Like double-buffering we write the windows contents
+ to an image and finally transfer the entire image
+ to the device context.
+ Additionally we keep the image between the paint events
+ and rebuild the image only if necessary (data to show
+ has changed).
+
+ When the frame containing your view becomes invisible
+ (frame iconized or hidden) you should use the ReleaseBuffer()
+ method to decrease the memory footprint of the program.
+
+ In your derived class, call the Dk4WxControl constructors from
+ the constructors.
+ From Create() call Dk4WxControl::Create().
+
+ You should also use DECLARE_DYNAMIC_CLASS() and
+ IMPLEMENT_DYNAMIC_CLASS().
+*/
+class Dk4WxControl : public wxControl
+{
+ private:
+
+ /** For RTTI.
+ */
+ DECLARE_DYNAMIC_CLASS(Dk4WxControl)
+
+ /** Event table.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ /** Class name.
+ */
+ static const wxChar Dk4WxControlName[];
+
+ /** Protection against simultaneous access.
+ */
+ wxCriticalSection csProtect;
+
+ /** Bitmap to cache contents.
+ */
+ wxBitmap *pBitmap;
+
+ /** Bitmap width.
+ */
+ int iBmWidth;
+
+ /** Bitmap height.
+ */
+ int iBmHeight;
+
+ /** Flag: Must update contents.
+ */
+ bool bUpdate;
+
+ protected:
+
+ /** Overwrite this method to do the real drawing.
+ @param pdc Device context to draw to.
+ @param event Paint event to draw for.
+ @param buffered Flag: Operating on memory DC.
+ @param clWidth Client area width.
+ @param clHeight Client area height.
+ */
+ virtual
+ void
+ PaintOperation(
+ wxDC & pdc,
+ wxPaintEvent & event,
+ bool buffered,
+ int clWidth,
+ int clHeight
+ );
+
+ /** Internal paint operation.
+ @param pdc Device context to draw to.
+ @param event Paint event to draw for.
+ @param buffered Flag: Operating on memory DC.
+ @param clWidth Client area width.
+ @param clHeight Client area height.
+ */
+ void
+ InternalPaint(
+ wxDC & pdc,
+ wxPaintEvent & event,
+ bool buffered,
+ int clWidth,
+ int clHeight
+ );
+
+ public:
+
+ /** Default constructor.
+ */
+ Dk4WxControl();
+
+ /** Useful constructor.
+ @param parent Parent window.
+ @param wid Window ID.
+ @param pos Position.
+ @param size Size.
+ @param style Style.
+ @param validator Validator.
+ @param name Type name.
+ */
+ Dk4WxControl(
+ wxWindow *parent,
+ wxWindowID wid = wxID_ANY,
+ const wxPoint & pos = wxDefaultPosition,
+ const wxSize & size = wxDefaultSize,
+ long style = 0L,
+ const wxValidator & validator = wxDefaultValidator,
+ const wxChar *name = Dk4WxControlName
+ );
+
+ /** Create window after using default constructor.
+ @param parent Parent window.
+ @param wid Window ID.
+ @param pos Position.
+ @param size Size.
+ @param style Style.
+ @param validator Validator.
+ @param name Type name.
+ */
+ bool
+ Create(
+ wxWindow *parent,
+ wxWindowID wid = wxID_ANY,
+ const wxPoint & pos = wxDefaultPosition,
+ const wxSize & size = wxDefaultSize,
+ long style = 0L,
+ const wxValidator & validator = wxDefaultValidator,
+ const wxChar *name = Dk4WxControlName
+ );
+
+ /** Destructor.
+ */
+ ~Dk4WxControl();
+
+ /** Mark update necessarity.
+ */
+ void
+ SetUpdate(bool flag = true);
+
+ /** Handler for erase background event.
+ @param event Event to process.
+ */
+ void
+ OnErase(wxEraseEvent & event);
+
+ /** Handler for paint event.
+ @param event Event to process.
+ */
+ void
+ OnPaint(wxPaintEvent & event);
+
+ /** Release buffer when frame is iconized or hidden.
+ */
+ void
+ ReleaseBuffer(void);
+};
+
+
+
+
+#endif
diff --git a/support/dktools/Dk4WxFrame.cpp b/support/dktools/Dk4WxFrame.cpp
new file mode 100644
index 0000000000..ead3817166
--- /dev/null
+++ b/support/dktools/Dk4WxFrame.cpp
@@ -0,0 +1,323 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: Dk4WxFrame.cpt
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file Dk4WxFrame.cpp The Dk4WxFrame module.
+*/
+
+
+#line 136 "Dk4WxFrame.cpt"
+
+
+#include "Dk4WxFrame.h"
+
+
+
+
+
+#line 143 "Dk4WxFrame.cpt"
+
+
+
+
+/** Protection for number of instances.
+*/
+wxCriticalSection Dk4WxFrame::csInstances;
+
+
+
+/** Number of instances.
+*/
+int Dk4WxFrame::iInstances = 0;
+
+
+
+/** Keywords to save and restore window size and position.
+*/
+static const wxChar * const dk4wxframe_kw_size[] = {
+/* 0 */
+wxT("window.x"),
+
+/* 1 */
+wxT("window.y"),
+
+/* 2 */
+wxT("window.w"),
+
+/* 3 */
+wxT("window.h"),
+
+/* 4 */
+wxT("window.maximized"),
+
+/* 5 */
+wxT("window.iconized"),
+
+NULL
+
+
+#line 170 "Dk4WxFrame.cpt"
+};
+
+
+
+/** Keywords to restore maximized and iconized state.
+*/
+static const wxChar * const dk4wxframe_kw_restore[] = {
+/* 0 */
+wxT("window.restore-maximized"),
+
+/* 1 */
+wxT("window.restore-iconized"),
+
+/* 2 */
+wxT("window.restore-size"),
+
+NULL
+
+
+#line 182 "Dk4WxFrame.cpt"
+};
+
+
+
+Dk4WxFrame::Dk4WxFrame(
+ const wxString & appName,
+ Dk4WxApplicationHelper *appHelper,
+ Dk4WxHelpController *helpController,
+ int wxid
+)
+: wxFrame(NULL, wxid, appName)
+{
+ pAppHelp = appHelper;
+ pHelp = helpController;
+ sAppName = appName;
+ {
+ wxCriticalSectionLocker lock(csInstances);
+ iInstances++;
+ }
+ Connect(wxid, wxEVT_CLOSE_WINDOW, wxCloseEventHandler(Dk4WxFrame::OnClose));
+}
+
+
+
+void
+Dk4WxFrame::OnClose(wxCloseEvent & event)
+{
+ bool doClose = true;
+ bool isFinal = false;
+ bool savePos = false;
+
+ {
+ wxCriticalSectionLocker lock(csInstances);
+ if (1 == iInstances) {
+ isFinal = true;
+ }
+ }
+ if (event.CanVeto()) {
+ doClose = CanClose(isFinal);
+ } else {
+ (void)CanClose(isFinal);
+ }
+ if (doClose) {
+ {
+ wxCriticalSectionLocker lock(csInstances);
+ if (1 == iInstances--) { savePos = true; }
+ }
+ if (savePos) {
+ SavePosition();
+ }
+ event.Skip();
+ } else {
+ event.Veto();
+ }
+}
+
+
+
+bool
+Dk4WxFrame::CanClose(bool isFinal)
+{
+ return true;
+}
+
+
+void
+Dk4WxFrame::SavePosition(void)
+{
+ int iv[6];
+ if (NULL != pAppHelp) {
+ iv[4] = iv[5] = 0;
+ if (IsIconized()) {
+ iv[5] = 1;
+ Iconize(false);
+ }
+ if (IsMaximized()) {
+ iv[4] = 1;
+ Maximize(false);
+ }
+ GetPosition(&(iv[0]), &(iv[1]));
+ GetSize(&(iv[2]), &(iv[3]));
+
+
+#line 264 "Dk4WxFrame.cpt"
+
+
+#line 265 "Dk4WxFrame.cpt"
+
+
+#line 266 "Dk4WxFrame.cpt"
+
+
+#line 267 "Dk4WxFrame.cpt"
+
+
+#line 268 "Dk4WxFrame.cpt"
+ pAppHelp->SetMultiple(dk4wxframe_kw_size, iv, 6);
+ }
+}
+
+
+
+void
+Dk4WxFrame::RestorePosition(void)
+{
+ int iv[6]; /* Values stored in config */
+ bool bv[3]; /* Feature restore */
+ int x; /* X position */
+ int y; /* Y position */
+ int w; /* Width */
+ int h; /* Height */
+
+
+
+#line 285 "Dk4WxFrame.cpt"
+
+#if wxCHECK_VERSION(3,0,0)
+ bv[2] = false;
+#else
+ bv[2] = true;
+#endif
+
+ /* Initialize variables.
+ */
+ iv[0] = iv[1] = -1;
+ iv[2] = iv[3] = iv[4] = iv[5] = 0;
+ bv[0] = bv[1] = false;
+
+ /* Retrieve stored values if found.
+ */
+ if (NULL != pAppHelp) {
+ pAppHelp->GetMultiple(dk4wxframe_kw_size, iv, 6);
+ pAppHelp->GetMultiple(dk4wxframe_kw_restore, bv, 3);
+ }
+
+ /* Find size if not stored.
+ */
+ GetSize(&w, &h);
+ x = iv[0];
+ y = iv[1];
+
+ /* Correct size if size restoration wanted, increase if necessary.
+ */
+ if (bv[2]) {
+
+#line 314 "Dk4WxFrame.cpt"
+ if (iv[2] > w) { w = iv[2]; }
+ if (iv[3] > h) { h = iv[3]; }
+ }
+
+ /* Correct values, no parts of window should be outside screen.
+ */
+ Dk4WxApplicationHelper::CorrectPosition(x, y, w, h);
+
+ /* Set position and optionally size.
+ */
+ if (bv[2]) {
+
+#line 325 "Dk4WxFrame.cpt"
+ SetSize(x, y, w, h);
+ } else {
+ SetPosition( wxPoint(x,y) );
+ }
+
+ /* Restore maximized or iconized state if required.
+ */
+ if (bv[0]) {
+
+#line 333 "Dk4WxFrame.cpt"
+ Maximize(0 != iv[4]);
+ }
+ if (bv[1]) {
+
+#line 336 "Dk4WxFrame.cpt"
+ Iconize(0 != iv[5]);
+ }
+
+
+
+#line 340 "Dk4WxFrame.cpt"
+}
+
+
+
+void
+Dk4WxFrame::DisplayContents(void)
+{
+ if (NULL != pHelp) {
+ pHelp->DisplayContents();
+ }
+}
+
+
+
+void
+Dk4WxFrame::DisplaySection(wxString const & name)
+{
+ if (NULL != pHelp) {
+ pHelp->DisplaySection(name);
+ }
+}
+
+
+
+void
+Dk4WxFrame::DisplaySection(int number)
+{
+ if (NULL != pHelp) {
+ pHelp->DisplaySection(number);
+ }
+}
+
+
diff --git a/support/dktools/Dk4WxFrame.cpt b/support/dktools/Dk4WxFrame.cpt
new file mode 100644
index 0000000000..ad5ed4e6d8
--- /dev/null
+++ b/support/dktools/Dk4WxFrame.cpt
@@ -0,0 +1,372 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file Dk4WxFrame.h Base class for top level frames.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef DK4WXAPPLICATIONHELPER_H_INCLUDED
+#include "Dk4WxApplicationHelper.h"
+#endif
+
+#ifndef DK4WXHELPCONTROLLER_H_INCLUDED
+#include "Dk4WxHelpController.h"
+#endif
+
+
+
+/** Frame (top level window).
+*/
+class Dk4WxFrame : public wxFrame
+{
+ protected:
+
+ /** Application helper.
+ */
+ Dk4WxApplicationHelper *pAppHelp;
+
+ /** Help controller for online help.
+ */
+ Dk4WxHelpController *pHelp;
+
+ /** Application name.
+ */
+ wxString sAppName;
+
+
+ /** Synchronize access to iInstances.
+ */
+ static wxCriticalSection csInstances;
+
+ /** Number of instances.
+ */
+ static int iInstances;
+
+ public:
+
+ /** Constructor.
+ @param appName Application name.
+ @param appHelper Application helper.
+ @param helpController Help controller.
+ @param wxid Window ID.
+ */
+ Dk4WxFrame(
+ const wxString & appName,
+ Dk4WxApplicationHelper *appHelper,
+ Dk4WxHelpController *helpController,
+ int wxid
+ );
+
+ /** Restore previously saved window position.
+ */
+ void
+ RestorePosition(void);
+
+ /** Handler for close event.
+ @param event Event to process.
+ */
+ void
+ OnClose(wxCloseEvent & event);
+
+ /** Decide whether we can close the frame.
+ @param isFinal Flag: Final frame.
+ @return True to close the frame, false to keep it.
+ */
+ virtual
+ bool
+ CanClose(bool isFinal);
+
+
+ /** Open help system.
+ */
+ void
+ DisplayContents(void);
+
+ /** Open help section specified by name.
+ @param name Section name.
+ */
+ void
+ DisplaySection(wxString const & name);
+
+ /** Open a help section specified by number.
+ @param number Section number (context ID).
+ */
+ void
+ DisplaySection(int number);
+
+ protected:
+
+ /** Save current window position.
+ */
+ void
+ SavePosition(void);
+
+};
+
+
+
+%% module
+
+
+#include "Dk4WxFrame.h"
+
+
+
+$!trace-include
+
+
+
+
+/** Protection for number of instances.
+*/
+wxCriticalSection Dk4WxFrame::csInstances;
+
+
+
+/** Number of instances.
+*/
+int Dk4WxFrame::iInstances = 0;
+
+
+
+/** Keywords to save and restore window size and position.
+*/
+static const wxChar * const dk4wxframe_kw_size[] = {
+$!string-table macro=wxT
+window.x
+window.y
+window.w
+window.h
+window.maximized
+window.iconized
+$!end
+};
+
+
+
+/** Keywords to restore maximized and iconized state.
+*/
+static const wxChar * const dk4wxframe_kw_restore[] = {
+$!string-table macro=wxT
+window.restore-maximized
+window.restore-iconized
+window.restore-size
+$!end
+};
+
+
+
+Dk4WxFrame::Dk4WxFrame(
+ const wxString & appName,
+ Dk4WxApplicationHelper *appHelper,
+ Dk4WxHelpController *helpController,
+ int wxid
+)
+: wxFrame(NULL, wxid, appName)
+{
+ pAppHelp = appHelper;
+ pHelp = helpController;
+ sAppName = appName;
+ {
+ wxCriticalSectionLocker lock(csInstances);
+ iInstances++;
+ }
+ Connect(wxid, wxEVT_CLOSE_WINDOW, wxCloseEventHandler(Dk4WxFrame::OnClose));
+}
+
+
+
+void
+Dk4WxFrame::OnClose(wxCloseEvent & event)
+{
+ bool doClose = true;
+ bool isFinal = false;
+ bool savePos = false;
+
+ {
+ wxCriticalSectionLocker lock(csInstances);
+ if (1 == iInstances) {
+ isFinal = true;
+ }
+ }
+ if (event.CanVeto()) {
+ doClose = CanClose(isFinal);
+ } else {
+ (void)CanClose(isFinal);
+ }
+ if (doClose) {
+ {
+ wxCriticalSectionLocker lock(csInstances);
+ if (1 == iInstances--) { savePos = true; }
+ }
+ if (savePos) {
+ SavePosition();
+ }
+ event.Skip();
+ } else {
+ event.Veto();
+ }
+}
+
+
+
+bool
+Dk4WxFrame::CanClose(bool isFinal)
+{
+ return true;
+}
+
+
+void
+Dk4WxFrame::SavePosition(void)
+{
+ int iv[6];
+ if (NULL != pAppHelp) {
+ iv[4] = iv[5] = 0;
+ if (IsIconized()) {
+ iv[5] = 1;
+ Iconize(false);
+ }
+ if (IsMaximized()) {
+ iv[4] = 1;
+ Maximize(false);
+ }
+ GetPosition(&(iv[0]), &(iv[1]));
+ GetSize(&(iv[2]), &(iv[3]));
+ $? ". saving current size"
+ $? ". x = %d", iv[0]
+ $? ". y = %d", iv[1]
+ $? ". w = %d", iv[2]
+ $? ". h = %d", iv[3]
+ pAppHelp->SetMultiple(dk4wxframe_kw_size, iv, 6);
+ }
+}
+
+
+
+void
+Dk4WxFrame::RestorePosition(void)
+{
+ int iv[6]; /* Values stored in config */
+ bool bv[3]; /* Feature restore */
+ int x; /* X position */
+ int y; /* Y position */
+ int w; /* Width */
+ int h; /* Height */
+
+ $? "+ Dk4WxFrame::RestorePosition"
+
+#if wxCHECK_VERSION(3,0,0)
+ bv[2] = false;
+#else
+ bv[2] = true;
+#endif
+
+ /* Initialize variables.
+ */
+ iv[0] = iv[1] = -1;
+ iv[2] = iv[3] = iv[4] = iv[5] = 0;
+ bv[0] = bv[1] = false;
+
+ /* Retrieve stored values if found.
+ */
+ if (NULL != pAppHelp) {
+ pAppHelp->GetMultiple(dk4wxframe_kw_size, iv, 6);
+ pAppHelp->GetMultiple(dk4wxframe_kw_restore, bv, 3);
+ }
+
+ /* Find size if not stored.
+ */
+ GetSize(&w, &h);
+ x = iv[0];
+ y = iv[1];
+
+ /* Correct size if size restoration wanted, increase if necessary.
+ */
+ if (bv[2]) { $? ". bv[2]"
+ if (iv[2] > w) { w = iv[2]; }
+ if (iv[3] > h) { h = iv[3]; }
+ }
+
+ /* Correct values, no parts of window should be outside screen.
+ */
+ Dk4WxApplicationHelper::CorrectPosition(x, y, w, h);
+
+ /* Set position and optionally size.
+ */
+ if (bv[2]) { $? ". bv[2]"
+ SetSize(x, y, w, h);
+ } else {
+ SetPosition( wxPoint(x,y) );
+ }
+
+ /* Restore maximized or iconized state if required.
+ */
+ if (bv[0]) { $? ". bv[0]"
+ Maximize(0 != iv[4]);
+ }
+ if (bv[1]) { $? ". bv[1]"
+ Iconize(0 != iv[5]);
+ }
+
+ $? "- Dk4WxFrame::RestorePosition"
+}
+
+
+
+void
+Dk4WxFrame::DisplayContents(void)
+{
+ if (NULL != pHelp) {
+ pHelp->DisplayContents();
+ }
+}
+
+
+
+void
+Dk4WxFrame::DisplaySection(wxString const & name)
+{
+ if (NULL != pHelp) {
+ pHelp->DisplaySection(name);
+ }
+}
+
+
+
+void
+Dk4WxFrame::DisplaySection(int number)
+{
+ if (NULL != pHelp) {
+ pHelp->DisplaySection(number);
+ }
+}
+
+
diff --git a/support/dktools/Dk4WxFrame.h b/support/dktools/Dk4WxFrame.h
new file mode 100644
index 0000000000..fd23b89d09
--- /dev/null
+++ b/support/dktools/Dk4WxFrame.h
@@ -0,0 +1,169 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: Dk4WxFrame.cpt
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4WXFRAME_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4WXFRAME_H_INCLUDED 1
+
+
+#line 9 "Dk4WxFrame.cpt"
+
+/** @file Dk4WxFrame.h Base class for top level frames.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef DK4WXAPPLICATIONHELPER_H_INCLUDED
+#include "Dk4WxApplicationHelper.h"
+#endif
+
+#ifndef DK4WXHELPCONTROLLER_H_INCLUDED
+#include "Dk4WxHelpController.h"
+#endif
+
+
+
+/** Frame (top level window).
+*/
+class Dk4WxFrame : public wxFrame
+{
+ protected:
+
+ /** Application helper.
+ */
+ Dk4WxApplicationHelper *pAppHelp;
+
+ /** Help controller for online help.
+ */
+ Dk4WxHelpController *pHelp;
+
+ /** Application name.
+ */
+ wxString sAppName;
+
+
+ /** Synchronize access to iInstances.
+ */
+ static wxCriticalSection csInstances;
+
+ /** Number of instances.
+ */
+ static int iInstances;
+
+ public:
+
+ /** Constructor.
+ @param appName Application name.
+ @param appHelper Application helper.
+ @param helpController Help controller.
+ @param wxid Window ID.
+ */
+ Dk4WxFrame(
+ const wxString & appName,
+ Dk4WxApplicationHelper *appHelper,
+ Dk4WxHelpController *helpController,
+ int wxid
+ );
+
+ /** Restore previously saved window position.
+ */
+ void
+ RestorePosition(void);
+
+ /** Handler for close event.
+ @param event Event to process.
+ */
+ void
+ OnClose(wxCloseEvent & event);
+
+ /** Decide whether we can close the frame.
+ @param isFinal Flag: Final frame.
+ @return True to close the frame, false to keep it.
+ */
+ virtual
+ bool
+ CanClose(bool isFinal);
+
+
+ /** Open help system.
+ */
+ void
+ DisplayContents(void);
+
+ /** Open help section specified by name.
+ @param name Section name.
+ */
+ void
+ DisplaySection(wxString const & name);
+
+ /** Open a help section specified by number.
+ @param number Section number (context ID).
+ */
+ void
+ DisplaySection(int number);
+
+ protected:
+
+ /** Save current window position.
+ */
+ void
+ SavePosition(void);
+
+};
+
+
+
+
+#endif
diff --git a/support/dktools/Dk4WxHelpController.cpp b/support/dktools/Dk4WxHelpController.cpp
new file mode 100644
index 0000000000..c30bb46d3b
--- /dev/null
+++ b/support/dktools/Dk4WxHelpController.cpp
@@ -0,0 +1,255 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: Dk4WxHelpController.cpt
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file Dk4WxHelpController.cpp The Dk4WxHelpController module.
+*/
+
+
+#line 158 "Dk4WxHelpController.cpt"
+
+#include "dk4strd.h"
+#include "dk4strx.h"
+#include "dk4fs.h"
+#include "dk4mem.h"
+#include "dk4mpl.h"
+#include "Dk4WxHelpController.h"
+
+
+
+
+
+#line 169 "Dk4WxHelpController.cpt"
+
+
+
+static const wxChar * const dk4wxhc_kw_def[] = {
+/* 0 */
+wxT("Help file not found"),
+
+/* 1 */
+wxT("The file containing online help text was not found on your computer!"),
+
+NULL
+
+
+#line 177 "Dk4WxHelpController.cpt"
+};
+
+
+
+Dk4WxHelpController::Dk4WxHelpController()
+#ifdef __WXMSW__
+
+#else
+: oHelpController(wxHF_DEFAULT_STYLE | wxHF_MERGE_BOOKS)
+#endif
+{
+ pAppHelp = NULL;
+ pdksShortFileName = NULL;
+ bLoaded = false;
+ bFileFound = false;
+}
+
+
+
+Dk4WxHelpController::~Dk4WxHelpController()
+{
+ dk4mem_release(pdksShortFileName);
+ pAppHelp = NULL;
+ bLoaded = false;
+ bFileFound = false;
+}
+
+
+
+bool
+Dk4WxHelpController::Initialize(
+ Dk4WxApplicationHelper *ahptr,
+ const dkChar *chmName,
+ const dkChar *htbName
+)
+{
+ const dkChar *fn = NULL;
+ bool back = false;
+#ifdef __WXMSW__
+ fn = chmName;
+#else
+ fn = htbName;
+#endif
+ if ((NULL != ahptr) && (NULL != fn)) {
+ pAppHelp = ahptr;
+ bLoaded = false;
+ bFileFound = false;
+ pdksShortFileName = dk4str_dup(fn, NULL);
+ if (NULL != pdksShortFileName) {
+ back = true;
+ } else {
+ /* ERROR: Memory */
+ ShowErrorMessage(6, 7);
+ }
+ } else {
+ /* ERROR: Illegal arguments to function */
+ ShowErrorMessage(6, 8);
+ }
+ return back;
+}
+
+
+
+void
+Dk4WxHelpController::Cleanup(void)
+{
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ dk4mem_release(pdksShortFileName);
+ pAppHelp = NULL;
+ bLoaded = false;
+ bFileFound = false;
+ }
+}
+
+
+
+void
+Dk4WxHelpController::AttemptToLoadFile(void)
+{
+ wxChar fnb[DK4_MAX_PATH];
+ size_t szfnb = DK4_SIZEOF(fnb,wxChar);
+
+ if (!bLoaded) {
+ bLoaded = true;
+ if ((NULL != pAppHelp) && (NULL != pdksShortFileName)) {
+ if (pAppHelp->FindDataFile(fnb, szfnb, pdksShortFileName)) {
+ bFileFound = true;
+#ifdef __WXMSW__
+ oHelpController.Initialize(fnb);
+#else
+ oHelpController.AddBook(fnb);
+#endif
+ }
+ }
+ }
+}
+
+
+
+void
+Dk4WxHelpController::ShowErrorMessage(size_t i_title, size_t i_text)
+{
+ const wxChar *strTitle = NULL;
+ const wxChar *strText = NULL;
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ if (NULL != pAppHelp) {
+ strTitle = pAppHelp->GetBasicString(i_title);
+ strText = pAppHelp->GetBasicString(i_text);
+ }
+ }
+ if (NULL == strTitle) {
+ strTitle = dk4wxhc_kw_def[i_title];
+ }
+ if (NULL == strText) {
+ strText = dk4wxhc_kw_def[i_text];
+ }
+ wxMessageBox(strText, strTitle, (wxOK | wxCENTRE | wxICON_ERROR));
+}
+
+
+
+void
+Dk4WxHelpController::DisplayContents()
+{
+ bool canOpenHelp = false;
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ AttemptToLoadFile();
+ if (bLoaded) {
+ if (bFileFound) {
+ canOpenHelp = true;
+ }
+ }
+ }
+ if (canOpenHelp) {
+ oHelpController.DisplayContents();
+ } else {
+ ShowErrorMessage();
+ }
+}
+
+
+
+void
+Dk4WxHelpController::DisplaySection(wxString const & name)
+{
+ bool canOpenHelp = false;
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ AttemptToLoadFile();
+ if (bLoaded) {
+ if (bFileFound) {
+ canOpenHelp = true;
+ }
+ }
+ }
+ if (canOpenHelp) {
+ oHelpController.DisplaySection(name);
+ } else {
+ ShowErrorMessage();
+ }
+}
+
+
+
+void
+Dk4WxHelpController::DisplaySection(int number)
+{
+ bool canOpenHelp = false;
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ AttemptToLoadFile();
+ if (bLoaded) {
+ if (bFileFound) {
+ canOpenHelp = true;
+ }
+ }
+ }
+ if (canOpenHelp) {
+ oHelpController.DisplaySection(number);
+ } else {
+ ShowErrorMessage();
+ }
+}
+
+
diff --git a/support/dktools/Dk4WxHelpController.cpt b/support/dktools/Dk4WxHelpController.cpt
new file mode 100644
index 0000000000..431202061f
--- /dev/null
+++ b/support/dktools/Dk4WxHelpController.cpt
@@ -0,0 +1,364 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file Dk4WxHelpController.h Help controller class.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED 1
+#endif
+#endif
+#ifndef WX_CONFIG_H_INCLUDED
+#include <wx/config.h>
+#define WX_CONFIG_H_INCLUDED 1
+#endif
+#ifndef WX_FILENAME_H_INCLUDED
+#include <wx/filename.h>
+#define WX_FILENAME_H_INCLUDED 1
+#endif
+#ifndef WX_HELP_H_INCLUDED
+#include <wx/help.h>
+#define WX_HELP_H_INCLUDED 1
+#endif
+#ifndef WX_FS_ZIP_H_INCLUDED
+#include <wx/fs_zip.h>
+#define WX_FS_ZIP_H_INCLUDED 1
+#endif
+#ifndef WX_THREAD_H_INCLUDED
+#include <wx/thread.h>
+#define WX_THREAD_H_INCLUDED 1
+#endif
+
+#ifndef DK4WXAPPLICATIONHELPER_H_INCLUDED
+#include "Dk4WxApplicationHelper.h"
+#endif
+
+
+/** Help controller dealing with both CHM and HTB files.
+*/
+class Dk4WxHelpController
+{
+ protected:
+
+ /** Synchronized access.
+ */
+ wxCriticalSection csProtect;
+
+#ifdef __WXMSW__
+ /** Help controller for CHM files used on Windows.
+ */
+ wxCHMHelpController oHelpController;
+#else
+ /** Help controller for HTB files used on non-Windows systems.
+ */
+ wxHtmlHelpController oHelpController;
+#endif
+
+ /** Application helper, used for for search.
+ */
+ Dk4WxApplicationHelper *pAppHelp;
+
+ /** Short file name of help file.
+ */
+ dkChar *pdksShortFileName;
+
+ /** Flag: Contents was already loaded.
+ */
+ bool bLoaded;
+
+ /** Flag: Help file was found.
+ */
+ bool bFileFound;
+
+ protected:
+
+ /** Attempt to load the help file.
+ */
+ void
+ AttemptToLoadFile(void);
+
+ /** Show error message.
+ */
+ void
+ ShowErrorMessage(size_t i_title = 0, size_t i_text = 1);
+
+ public:
+
+ /** Default constructor.
+ Just set the pointers to NULL.
+ */
+ Dk4WxHelpController();
+
+ /** Destructor.
+ */
+ ~Dk4WxHelpController();
+
+ /** Initialize the controller (keep pointers).
+ @param ahptr Application helper for file search.
+ @param chmName CHM help file name for windows.
+ @param htbName HTB help file name for other systems.
+ @return True on success, false on error.
+ */
+ bool
+ Initialize(
+ Dk4WxApplicationHelper *ahptr,
+ const dkChar *chmName,
+ const dkChar *htbName
+ );
+
+ /** Clean up.
+ */
+ void
+ Cleanup(void);
+
+ /** Open help system.
+ */
+ void
+ DisplayContents(void);
+
+ /** Open help section specified by name.
+ @param name Section name.
+ */
+ void
+ DisplaySection(wxString const & name);
+
+ /** Open a help section specified by number.
+ @param number Section number (context ID).
+ */
+ void
+ DisplaySection(int number);
+
+};
+
+%% module
+
+#include "dk4strd.h"
+#include "dk4strx.h"
+#include "dk4fs.h"
+#include "dk4mem.h"
+#include "dk4mpl.h"
+#include "Dk4WxHelpController.h"
+
+
+
+$!trace-include
+
+
+
+static const wxChar * const dk4wxhc_kw_def[] = {
+$!string-table macro=wxT
+Help file not found
+The file containing online help text was not found on your computer!
+$!end
+};
+
+
+
+Dk4WxHelpController::Dk4WxHelpController()
+#ifdef __WXMSW__
+
+#else
+: oHelpController(wxHF_DEFAULT_STYLE | wxHF_MERGE_BOOKS)
+#endif
+{
+ pAppHelp = NULL;
+ pdksShortFileName = NULL;
+ bLoaded = false;
+ bFileFound = false;
+}
+
+
+
+Dk4WxHelpController::~Dk4WxHelpController()
+{
+ dk4mem_release(pdksShortFileName);
+ pAppHelp = NULL;
+ bLoaded = false;
+ bFileFound = false;
+}
+
+
+
+bool
+Dk4WxHelpController::Initialize(
+ Dk4WxApplicationHelper *ahptr,
+ const dkChar *chmName,
+ const dkChar *htbName
+)
+{
+ const dkChar *fn = NULL;
+ bool back = false;
+#ifdef __WXMSW__
+ fn = chmName;
+#else
+ fn = htbName;
+#endif
+ if ((NULL != ahptr) && (NULL != fn)) {
+ pAppHelp = ahptr;
+ bLoaded = false;
+ bFileFound = false;
+ pdksShortFileName = dk4str_dup(fn, NULL);
+ if (NULL != pdksShortFileName) {
+ back = true;
+ } else {
+ /* ERROR: Memory */
+ ShowErrorMessage(6, 7);
+ }
+ } else {
+ /* ERROR: Illegal arguments to function */
+ ShowErrorMessage(6, 8);
+ }
+ return back;
+}
+
+
+
+void
+Dk4WxHelpController::Cleanup(void)
+{
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ dk4mem_release(pdksShortFileName);
+ pAppHelp = NULL;
+ bLoaded = false;
+ bFileFound = false;
+ }
+}
+
+
+
+void
+Dk4WxHelpController::AttemptToLoadFile(void)
+{
+ wxChar fnb[DK4_MAX_PATH];
+ size_t szfnb = DK4_SIZEOF(fnb,wxChar);
+
+ if (!bLoaded) {
+ bLoaded = true;
+ if ((NULL != pAppHelp) && (NULL != pdksShortFileName)) {
+ if (pAppHelp->FindDataFile(fnb, szfnb, pdksShortFileName)) {
+ bFileFound = true;
+#ifdef __WXMSW__
+ oHelpController.Initialize(fnb);
+#else
+ oHelpController.AddBook(fnb);
+#endif
+ }
+ }
+ }
+}
+
+
+
+void
+Dk4WxHelpController::ShowErrorMessage(size_t i_title, size_t i_text)
+{
+ const wxChar *strTitle = NULL;
+ const wxChar *strText = NULL;
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ if (NULL != pAppHelp) {
+ strTitle = pAppHelp->GetBasicString(i_title);
+ strText = pAppHelp->GetBasicString(i_text);
+ }
+ }
+ if (NULL == strTitle) {
+ strTitle = dk4wxhc_kw_def[i_title];
+ }
+ if (NULL == strText) {
+ strText = dk4wxhc_kw_def[i_text];
+ }
+ wxMessageBox(strText, strTitle, (wxOK | wxCENTRE | wxICON_ERROR));
+}
+
+
+
+void
+Dk4WxHelpController::DisplayContents()
+{
+ bool canOpenHelp = false;
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ AttemptToLoadFile();
+ if (bLoaded) {
+ if (bFileFound) {
+ canOpenHelp = true;
+ }
+ }
+ }
+ if (canOpenHelp) {
+ oHelpController.DisplayContents();
+ } else {
+ ShowErrorMessage();
+ }
+}
+
+
+
+void
+Dk4WxHelpController::DisplaySection(wxString const & name)
+{
+ bool canOpenHelp = false;
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ AttemptToLoadFile();
+ if (bLoaded) {
+ if (bFileFound) {
+ canOpenHelp = true;
+ }
+ }
+ }
+ if (canOpenHelp) {
+ oHelpController.DisplaySection(name);
+ } else {
+ ShowErrorMessage();
+ }
+}
+
+
+
+void
+Dk4WxHelpController::DisplaySection(int number)
+{
+ bool canOpenHelp = false;
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ AttemptToLoadFile();
+ if (bLoaded) {
+ if (bFileFound) {
+ canOpenHelp = true;
+ }
+ }
+ }
+ if (canOpenHelp) {
+ oHelpController.DisplaySection(number);
+ } else {
+ ShowErrorMessage();
+ }
+}
+
+
diff --git a/support/dktools/Dk4WxHelpController.h b/support/dktools/Dk4WxHelpController.h
new file mode 100644
index 0000000000..8a6615aaa8
--- /dev/null
+++ b/support/dktools/Dk4WxHelpController.h
@@ -0,0 +1,191 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: Dk4WxHelpController.cpt
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4WXHELPCONTROLLER_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4WXHELPCONTROLLER_H_INCLUDED 1
+
+
+#line 9 "Dk4WxHelpController.cpt"
+
+/** @file Dk4WxHelpController.h Help controller class.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED 1
+#endif
+#endif
+#ifndef WX_CONFIG_H_INCLUDED
+#include <wx/config.h>
+#define WX_CONFIG_H_INCLUDED 1
+#endif
+#ifndef WX_FILENAME_H_INCLUDED
+#include <wx/filename.h>
+#define WX_FILENAME_H_INCLUDED 1
+#endif
+#ifndef WX_HELP_H_INCLUDED
+#include <wx/help.h>
+#define WX_HELP_H_INCLUDED 1
+#endif
+#ifndef WX_FS_ZIP_H_INCLUDED
+#include <wx/fs_zip.h>
+#define WX_FS_ZIP_H_INCLUDED 1
+#endif
+#ifndef WX_THREAD_H_INCLUDED
+#include <wx/thread.h>
+#define WX_THREAD_H_INCLUDED 1
+#endif
+
+#ifndef DK4WXAPPLICATIONHELPER_H_INCLUDED
+#include "Dk4WxApplicationHelper.h"
+#endif
+
+
+/** Help controller dealing with both CHM and HTB files.
+*/
+class Dk4WxHelpController
+{
+ protected:
+
+ /** Synchronized access.
+ */
+ wxCriticalSection csProtect;
+
+#ifdef __WXMSW__
+ /** Help controller for CHM files used on Windows.
+ */
+ wxCHMHelpController oHelpController;
+#else
+ /** Help controller for HTB files used on non-Windows systems.
+ */
+ wxHtmlHelpController oHelpController;
+#endif
+
+ /** Application helper, used for for search.
+ */
+ Dk4WxApplicationHelper *pAppHelp;
+
+ /** Short file name of help file.
+ */
+ dkChar *pdksShortFileName;
+
+ /** Flag: Contents was already loaded.
+ */
+ bool bLoaded;
+
+ /** Flag: Help file was found.
+ */
+ bool bFileFound;
+
+ protected:
+
+ /** Attempt to load the help file.
+ */
+ void
+ AttemptToLoadFile(void);
+
+ /** Show error message.
+ */
+ void
+ ShowErrorMessage(size_t i_title = 0, size_t i_text = 1);
+
+ public:
+
+ /** Default constructor.
+ Just set the pointers to NULL.
+ */
+ Dk4WxHelpController();
+
+ /** Destructor.
+ */
+ ~Dk4WxHelpController();
+
+ /** Initialize the controller (keep pointers).
+ @param ahptr Application helper for file search.
+ @param chmName CHM help file name for windows.
+ @param htbName HTB help file name for other systems.
+ @return True on success, false on error.
+ */
+ bool
+ Initialize(
+ Dk4WxApplicationHelper *ahptr,
+ const dkChar *chmName,
+ const dkChar *htbName
+ );
+
+ /** Clean up.
+ */
+ void
+ Cleanup(void);
+
+ /** Open help system.
+ */
+ void
+ DisplayContents(void);
+
+ /** Open help section specified by name.
+ @param name Section name.
+ */
+ void
+ DisplaySection(wxString const & name);
+
+ /** Open a help section specified by number.
+ @param number Section number (context ID).
+ */
+ void
+ DisplaySection(int number);
+
+};
+
+
+#endif
diff --git a/support/dktools/Dk4WxProgressControllerBase.h b/support/dktools/Dk4WxProgressControllerBase.h
new file mode 100644
index 0000000000..f73165ff42
--- /dev/null
+++ b/support/dktools/Dk4WxProgressControllerBase.h
@@ -0,0 +1,136 @@
+/** @file Dk4WxProgressControllerBase.h Progress controller base class.
+*/
+#ifndef DK4WXPROGRESSCONTROLLERBASE_H_INCLUDED
+#define DK4WXPROGRESSCONTROLLERBASE_H_INCLUDED 1
+
+/** Base class for progress controllers interface to worker thread.
+*/
+class Dk4WxProgressControllerWorkerBase
+{
+
+ public:
+
+ /*
+ While the worker thread is running, it can
+ - check whether the worker thread is allowed to continue,
+ - set a new gauge value for the progress bar in the progress dialog,
+ - indicate that the main thread should show a dialog box after
+ the worker thread has finished,
+ - indicate end of processing immediately before finishing.
+ */
+
+ /** Check whether worker thread is allowed to continue processing.
+ @return True if worker thread can continue normally, false
+ if worker thread should abort.
+ */
+ virtual
+ bool
+ CanContinue(void) = 0;
+
+ /** Set gauge value for progress dialog.
+ @param value New value for gauge.
+ */
+ virtual
+ void
+ SetGauge(int value) = 0;
+
+ /** Indicate that a dialog box should be shown by the main thread
+ after the worker thread has finished.
+ @param title Message box title.
+ @param msg Message box text.
+ @param st Message box style.
+ */
+ virtual
+ void
+ SetDialogData(
+ const wxString & title,
+ const wxString & msg,
+ int st = wxID_OK
+ ) = 0;
+
+ /** End processing.
+ Called from worker thread immediately before finished.
+ Note: If you want to call SetGaugeValue() or SetDialogData(),
+ call these functions before EndProcessing().
+ @param success Flag: Successful processing.
+ */
+ virtual
+ void
+ EndProcessing(bool success = true) = 0;
+
+};
+
+
+/** Progress controllers interface to event processing (main) thread.
+*/
+class Dk4WxProgressControllerOwnerBase
+{
+ public:
+
+ /*
+ Before the worker thread is started either the main
+ thread or the worker thread should indicate start of processing.
+ */
+
+ /** Start processing. Optionally called from worker thread
+ or main thread.
+ Must be called if a controller is used multiple times.
+ */
+ virtual
+ void
+ StartProcessing(void) = 0;
+
+ /*
+ While the worker thread is running, the main thread (event thread) can
+ - check whether the worker thread finished processing,
+ - retrieve the current gauge value,
+ - abort processing on behalf of the progress dialogs cancel button.
+ */
+
+ /** Check whether the worker thread is finished.
+ @return True if the worker thread is finished, false while running.
+ */
+ virtual
+ bool
+ IsFinished(void) = 0;
+
+ /** Retrieve gauge value.
+ @return Current value for progress gauge.
+ */
+ virtual
+ int
+ GetGauge(void) = 0;
+
+ /** Abort processing. Called from the progress dialogs Cancel button.
+ */
+ virtual
+ void
+ AbortProcessing(void) = 0;
+
+ /*
+ After the worker thread finished processing, the event thread can:
+ - check whether the worker thread finished successfully,
+ - check whether a dialog box should show a processing summary.
+ */
+
+ /** Check whether the worker thread finished successfully.
+ @return True to indicate success, false otherwise.
+ */
+ virtual
+ bool
+ GetSuccess(void) = 0;
+
+ /** Check whether a dialog should be shown.
+ @param title Result variable for message box title.
+ @param msg Result variable for message text.
+ @param style Result variable for dialog box style.
+ @return True to show a dialog, false otherwise.
+ */
+ virtual
+ bool
+ GetDialogData(wxString & title, wxString & msg, int & style) = 0;
+
+};
+
+#endif
+
diff --git a/support/dktools/Dk4WxProgressDialog.cpp b/support/dktools/Dk4WxProgressDialog.cpp
new file mode 100644
index 0000000000..a4a1b85cc0
--- /dev/null
+++ b/support/dktools/Dk4WxProgressDialog.cpp
@@ -0,0 +1,416 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: Dk4WxProgressDialog.wxc
+*/
+
+/** @file Dk4WxProgressDialog.cpp The Dk4WxProgressDialog module.
+*/
+
+
+#line 249 "Dk4WxProgressDialog.wxc"
+
+#include "Dk4WxProgressDialog.h"
+
+
+
+
+
+#line 255 "Dk4WxProgressDialog.wxc"
+
+
+
+BEGIN_EVENT_TABLE(Dk4WxProgressDialog,wxDialog)
+ EVT_IDLE( Dk4WxProgressDialog::OnIdle)
+ EVT_BUTTON(wxID_CANCEL, Dk4WxProgressDialog::OnCancel)
+END_EVENT_TABLE()
+
+
+static const wxChar * dk4wx_progress_kw_wx[] = {
+/* 0 */
+wxT("Operation in progress"),
+
+/* 1 */
+wxT("Cancel"),
+
+/* 2 */
+wxT("Abort operation"),
+
+/* 3 */
+wxT("Abortion scheduled, please wait."),
+
+NULL
+
+
+#line 274 "Dk4WxProgressDialog.wxc"
+};
+
+
+
+/** Integer preference names.
+*/
+static const wxChar * const names[] = {
+/* 0 */
+wxT("progress.min-width"),
+
+NULL
+
+
+#line 284 "Dk4WxProgressDialog.wxc"
+};
+
+
+
+#line 288 "Dk4WxProgressDialog.wxc"
+Dk4WxProgressDialog::Dk4WxProgressDialog(
+ wxFrame *parent,
+ Dk4WxApplicationHelper *pAppHelp
+)
+: wxDialog(
+ parent, wxID_ANY,
+ (
+ (NULL != pAppHelp)
+ ? (pAppHelp->GetBasicString(2))
+ : (dk4wx_progress_kw_wx[0])
+ ),
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxDEFAULT_DIALOG_STYLE
+)
+{
+ const wxChar *labelText = NULL;
+ int minWidth = 300;
+
+ labelText = dk4wx_progress_kw_wx[0];
+ if (NULL != pAppHelp) {
+ labelText = pAppHelp->GetBasicString(2);
+ pAppHelp->GetMultiple(names, &minWidth, 1);
+ if (0 > minWidth) { minWidth = 300; }
+ }
+
+ iOld = 0;
+ iNew = 0;
+ bActive = true;
+ bAborted = false;
+ bFinished = false;
+ bSuccess = false;
+ bHaveDialog = false;
+ sDialogTitle = wxEmptyString;
+ sDialogText = wxEmptyString;
+ iDialogStyle = wxID_OK;
+ if (NULL != pAppHelp) {
+ sText[0] = pAppHelp->GetBasicString(3); // Button label
+ sText[1] = pAppHelp->GetBasicString(4); // Button tooltip
+ sText[2] = pAppHelp->GetBasicString(5); // Text hint
+ } else {
+ sText[0] = dk4wx_progress_kw_wx[1];
+ sText[1] = dk4wx_progress_kw_wx[2];
+ sText[2] = dk4wx_progress_kw_wx[3];
+ }
+ dkctGUILayoutOK = false;
+ sDialog = NULL;
+ verticalSizer = NULL;
+ sttInProgress = NULL;
+ gaugeProgress = NULL;
+ sttWait = NULL;
+ bCancel = NULL;
+ sDialog = new wxBoxSizer(
+ wxHORIZONTAL
+ );
+ if(!(sDialog)) {
+ goto dkctGUILayoutFinished;
+ }
+ sDialog->Add(10, 10, 0);
+ verticalSizer = new wxBoxSizer(
+ wxVERTICAL
+ );
+ if(!(verticalSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ verticalSizer->Add(10, 10, 0);
+ sttInProgress = new wxStaticText(
+ this,
+ wxID_ANY,
+ labelText,
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxALIGN_CENTRE
+ );
+ if(!(sttInProgress)) {
+ goto dkctGUILayoutFinished;
+ }
+ verticalSizer->Add(
+ sttInProgress
+ );
+ verticalSizer->Add(10, 10, 0);
+ gaugeProgress = new wxGauge(
+ this,
+ wxID_ANY,
+ 1000
+ );
+ if(!(gaugeProgress)) {
+ goto dkctGUILayoutFinished;
+ }
+ verticalSizer->Add(
+ gaugeProgress,
+ 1,
+ wxALIGN_CENTER_HORIZONTAL|wxGROW
+ );
+ verticalSizer->Add(10, 10, 0);
+ sttWait = new wxStaticText(
+ this,
+ wxID_ANY,
+ wxT(""),
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxALIGN_CENTRE
+ );
+ if(!(sttWait)) {
+ goto dkctGUILayoutFinished;
+ }
+ verticalSizer->Add(
+ sttWait,
+ 1,
+ wxALIGN_CENTER_HORIZONTAL|wxGROW
+ );
+ verticalSizer->Add(10, 10, 0);
+ bCancel = new wxButton(
+ this,
+ wxID_CANCEL,
+ sText[0]
+ );
+ if(!(bCancel)) {
+ goto dkctGUILayoutFinished;
+ }
+ bCancel->SetToolTip(sText[1]);
+ verticalSizer->Add(
+ bCancel,
+ 0,
+ wxALIGN_CENTER_HORIZONTAL
+ );
+ verticalSizer->Add(10, 10, 0);
+ sDialog->Add(
+ verticalSizer,
+ 1,
+ wxGROW
+ );
+ sDialog->Add(10, 10, 0);
+ SetSizer(sDialog);
+ dkctGUILayoutOK = true;
+ dkctGUILayoutFinished:
+ if(dkctGUILayoutOK) {
+ sDialog->Fit(this);
+ sDialog->SetSizeHints(this);
+ }
+
+#line 334 "Dk4WxProgressDialog.wxc"
+ if (dkctGUILayoutOK) {
+ wxSize gaugeSize = gaugeProgress->GetMinSize();
+ if (300 > gaugeSize.GetWidth()) {
+ gaugeSize.SetWidth(300);
+ gaugeProgress->SetMinSize(gaugeSize);
+ }
+ sDialog->Fit(this);
+ sDialog->SetSizeHints(this);
+ }
+}
+
+
+#line 346 "Dk4WxProgressDialog.wxc"
+
+
+
+void
+Dk4WxProgressDialog::OnIdle(wxIdleEvent & event)
+{
+ int result;
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ if (bActive) {
+ if (bFinished) {
+ bActive = false;
+ result = wxID_OK;
+ if ((bAborted) || (!(bSuccess))) { result = wxID_CANCEL; }
+ if (IsModal()) {
+ EndModal(result);
+ } else {
+ SetReturnCode((bSuccess) && (!(bAborted)));
+ Show(false);
+ }
+ } else {
+ if (iNew != iOld) {
+ iOld = iNew;
+ gaugeProgress->SetValue(iNew);
+ Refresh();
+ Update();
+ }
+ event.RequestMore();
+ }
+ }
+ }
+ event.Skip();
+}
+
+
+
+void
+Dk4WxProgressDialog::OnCancel(wxCommandEvent & WXUNUSED(event))
+{
+ bCancel->Enable(false);
+ bCancel->SetToolTip(sText[2]);
+ Refresh();
+ Update();
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ if (!(bFinished)) {
+ bAborted = true;
+ }
+ }
+}
+
+
+
+void
+Dk4WxProgressDialog::SetGauge(int value)
+{
+ wxCriticalSectionLocker lock(csProtect);
+ iNew = value;
+}
+
+
+
+void
+Dk4WxProgressDialog::SetDialogData(
+ const wxString & title,
+ const wxString & msg,
+ int st
+)
+{
+ wxCriticalSectionLocker lock(csProtect);
+ bHaveDialog = true;
+ sDialogTitle = title;
+ sDialogText = msg;
+ iDialogStyle = st;
+}
+
+
+
+void
+Dk4WxProgressDialog::StartProcessing(void)
+{
+ wxCriticalSectionLocker lock(csProtect);
+ bActive = true;
+ sDialogTitle = wxEmptyString;
+ sDialogText = wxEmptyString;
+ iOld = 0;
+ iNew = 0;
+ bAborted = false;
+ bFinished = false;
+ bSuccess = true;
+ bActive = true;
+ bHaveDialog = false;
+}
+
+
+
+void
+Dk4WxProgressDialog::EndProcessing(bool success)
+{
+ wxCriticalSectionLocker lock(csProtect);
+ bFinished = true;
+ if (!(bAborted)) {
+ bSuccess = success;
+ }
+}
+
+
+
+bool
+Dk4WxProgressDialog::CanContinue(void)
+{
+ bool back = true;
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ if ((bAborted) || (bFinished)) {
+ back = false;
+ }
+ }
+ return back;
+}
+
+
+
+bool
+Dk4WxProgressDialog::IsFinished(void)
+{
+ bool back = false;
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ back = bFinished;
+ }
+ return back;
+}
+
+
+
+int
+Dk4WxProgressDialog::GetGauge(void)
+{
+ int back = 0;
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ back = iNew;
+ }
+ return back;
+}
+
+
+
+void
+Dk4WxProgressDialog::AbortProcessing(void)
+{
+ wxCriticalSectionLocker lock(csProtect);
+ if (!(bFinished)) {
+ bAborted = true;
+ }
+}
+
+
+
+bool
+Dk4WxProgressDialog::GetSuccess(void)
+{
+ bool back = false;
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ if (bFinished) {
+ back = true;
+ if ((bAborted) || (!(bSuccess))) { back = false; }
+ }
+ }
+ return back;
+}
+
+
+
+bool
+Dk4WxProgressDialog::GetDialogData(
+ wxString & title,
+ wxString & msg,
+ int & style
+)
+{
+ bool back = false;
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ if (bHaveDialog) {
+ title = sDialogTitle;
+ msg = sDialogText;
+ style = iDialogStyle;
+ back = true;
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/Dk4WxProgressDialog.h b/support/dktools/Dk4WxProgressDialog.h
new file mode 100644
index 0000000000..8906e768ab
--- /dev/null
+++ b/support/dktools/Dk4WxProgressDialog.h
@@ -0,0 +1,246 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: Dk4WxProgressDialog.wxc
+*/
+
+#ifndef DK4WXPROGRESSDIALOG_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4WXPROGRESSDIALOG_H_INCLUDED 1
+
+
+#line 54 "Dk4WxProgressDialog.wxc"
+
+/** @file Dk4WxProgressDialog.h Progress dialog.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef DK4WXAPPLICATIONHELPER_H_INCLUDED
+#include "Dk4WxApplicationHelper.h"
+#endif
+
+#ifndef DK4WXPROGRESSCONTROLLERBASE_H_INCLUDED
+#include "Dk4WxProgressControllerBase.h"
+#endif
+
+
+
+#line 90 "Dk4WxProgressDialog.wxc"
+
+/** Progress dialog (progress bar and cancel button).
+*/
+class Dk4WxProgressDialog :
+ public wxDialog,
+ public Dk4WxProgressControllerWorkerBase,
+ Dk4WxProgressControllerOwnerBase
+{
+ private:
+
+ /** Event table.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ /** Synchronize access from multiple threads.
+ */
+ wxCriticalSection csProtect;
+
+ /** Text for dialog title.
+ */
+ wxString sDialogTitle;
+
+ /** Text for dialog box.
+ */
+ wxString sDialogText;
+
+ /** Three text strings shown in the dialog.
+ */
+ const wxChar *sText[3];
+
+ /** Current gauge value.
+ */
+ int iOld;
+
+ /** New gauge value, set by worker thread.
+ */
+ int iNew;
+
+ /** Dialog box style.
+ */
+ int iDialogStyle;
+
+ /** Flag: Aborted via Cancel button.
+ */
+ bool bAborted;
+
+ /** Worker thread finished.
+ */
+ bool bFinished;
+
+ /** Success indicator from worker thread.
+ */
+ bool bSuccess;
+
+ /** Flag: Still active, not yet closed.
+ */
+ bool bActive;
+
+ /** Flag: Data to show a message box is available.
+ */
+ bool bHaveDialog;
+
+ public:
+
+ /** Constructor.
+ */
+ Dk4WxProgressDialog(
+ wxFrame *parent,
+ Dk4WxApplicationHelper *pAppHelp
+ );
+
+ /** Handler for idle events.
+ @param event Event to process.
+ */
+ void
+ OnIdle(wxIdleEvent & event);
+
+ /** Handler for cancel button.
+ @param event Event to process.
+ */
+ void
+ OnCancel(wxCommandEvent & WXUNUSED(event));
+
+ /** Set new gauge value, called from worker thread.
+ */
+ void
+ SetGauge(int value);
+
+ /** Indicate that a dialog box should be shown by the main thread
+ after the worker thread has finished.
+ @param title Message box title.
+ @param msg Message box text.
+ @param st Message box style.
+ */
+ void
+ SetDialogData(
+ const wxString & title,
+ const wxString & msg,
+ int st = wxID_OK
+ );
+
+ /** Start processing. Does nothing, just implement the
+ Dk4WxProgressControllerBase interface.
+ */
+ void
+ StartProcessing(void);
+
+ /** Indicate end of processing, called from worker thread.
+ @param success Flag: Successful processing.
+ */
+ void
+ EndProcessing(bool success = true);
+
+ /** Check whether we can continue.
+ */
+ bool
+ CanContinue(void);
+
+ /** Check whether the worker thread is finished.
+ @return True if the worker thread is finished, false while running.
+ */
+ bool
+ IsFinished(void);
+
+ /** Retrieve gauge value.
+ @return Current value for progress gauge.
+ */
+ int
+ GetGauge(void);
+
+ /** Abort processing. Called from the progress dialogs Cancel button.
+ */
+ void
+ AbortProcessing(void);
+
+ /** Check whether the worker thread finished successfully.
+ @return True to indicate success, false otherwise.
+ */
+ bool
+ GetSuccess(void);
+
+ /** Check whether a dialog should be shown.
+ @param title Result variable for message box title.
+ @param msg Result variable for message text.
+ @param style Result variable for dialog box style.
+ @return True to show a dialog, false otherwise.
+ */
+ bool
+ GetDialogData(wxString & title, wxString & msg, int & style);
+
+ /** Flag: GUI ok.
+ */
+ bool dkctGUILayoutOK;
+
+ /** GUI element sDialog.
+ */
+#line 9 "Dk4WxProgressDialog.wxc"
+ wxBoxSizer *sDialog;
+
+ /** GUI element verticalSizer.
+ */
+#line 17 "Dk4WxProgressDialog.wxc"
+ wxBoxSizer *verticalSizer;
+
+ /** GUI element sttInProgress.
+ */
+#line 37 "Dk4WxProgressDialog.wxc"
+ wxStaticText *sttInProgress;
+
+ /** GUI element gaugeProgress.
+ */
+#line 31 "Dk4WxProgressDialog.wxc"
+ wxGauge *gaugeProgress;
+
+ /** GUI element sttWait.
+ */
+#line 41 "Dk4WxProgressDialog.wxc"
+ wxStaticText *sttWait;
+
+ /** GUI element bCancel.
+ */
+#line 47 "Dk4WxProgressDialog.wxc"
+ wxButton *bCancel;
+
+
+#line 243 "Dk4WxProgressDialog.wxc"
+};
+
+
+#line 246 "Dk4WxProgressDialog.wxc"
+
+
+
+#endif
diff --git a/support/dktools/Dk4WxProgressDialog.wxc b/support/dktools/Dk4WxProgressDialog.wxc
new file mode 100644
index 0000000000..0e4173d14e
--- /dev/null
+++ b/support/dktools/Dk4WxProgressDialog.wxc
@@ -0,0 +1,541 @@
+%% options
+
+
+%% wx-gui
+
+type = dialog
+contents = sDialog
+
+[wxBoxSizer sDialog]
+direction = horizontal
+grow = yes
+proportion = 1
+contents = $space(10)
+contents = verticalSizer
+contents = $space(10)
+
+[wxBoxSizer verticalSizer]
+direction = vertical
+grow = yes
+proportion = 1
+contents = $space(10)
+contents = sttInProgress
+contents = $space(10)
+contents = gaugeProgress centered-x
+contents = $space(10)
+contents = sttWait centered-x
+contents = $space(10)
+contents = bCancel centered-x
+contents = $space(10)
+
+[wxGauge gaugeProgress]
+range = 1000
+value = 0
+grow = yes
+proportion = 1
+
+[wxStaticText sttInProgress]
+text = labelText
+text style = centered no-auto-resize
+
+[wxStaticText sttWait]
+text = wxT("")
+text style = centered no-auto-resize
+grow = yes
+proportion = 1
+
+[wxButton bCancel]
+text = sText[0]
+tip = sText[1]
+id = wxID_CANCEL
+
+
+%% header start
+
+/** @file Dk4WxProgressDialog.h Progress dialog.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef DK4WXAPPLICATIONHELPER_H_INCLUDED
+#include "Dk4WxApplicationHelper.h"
+#endif
+
+#ifndef DK4WXPROGRESSCONTROLLERBASE_H_INCLUDED
+#include "Dk4WxProgressControllerBase.h"
+#endif
+
+
+%% class start
+
+/** Progress dialog (progress bar and cancel button).
+*/
+class Dk4WxProgressDialog :
+ public wxDialog,
+ public Dk4WxProgressControllerWorkerBase,
+ Dk4WxProgressControllerOwnerBase
+{
+ private:
+
+ /** Event table.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ /** Synchronize access from multiple threads.
+ */
+ wxCriticalSection csProtect;
+
+ /** Text for dialog title.
+ */
+ wxString sDialogTitle;
+
+ /** Text for dialog box.
+ */
+ wxString sDialogText;
+
+ /** Three text strings shown in the dialog.
+ */
+ const wxChar *sText[3];
+
+ /** Current gauge value.
+ */
+ int iOld;
+
+ /** New gauge value, set by worker thread.
+ */
+ int iNew;
+
+ /** Dialog box style.
+ */
+ int iDialogStyle;
+
+ /** Flag: Aborted via Cancel button.
+ */
+ bool bAborted;
+
+ /** Worker thread finished.
+ */
+ bool bFinished;
+
+ /** Success indicator from worker thread.
+ */
+ bool bSuccess;
+
+ /** Flag: Still active, not yet closed.
+ */
+ bool bActive;
+
+ /** Flag: Data to show a message box is available.
+ */
+ bool bHaveDialog;
+
+ public:
+
+ /** Constructor.
+ */
+ Dk4WxProgressDialog(
+ wxFrame *parent,
+ Dk4WxApplicationHelper *pAppHelp
+ );
+
+ /** Handler for idle events.
+ @param event Event to process.
+ */
+ void
+ OnIdle(wxIdleEvent & event);
+
+ /** Handler for cancel button.
+ @param event Event to process.
+ */
+ void
+ OnCancel(wxCommandEvent & WXUNUSED(event));
+
+ /** Set new gauge value, called from worker thread.
+ */
+ void
+ SetGauge(int value);
+
+ /** Indicate that a dialog box should be shown by the main thread
+ after the worker thread has finished.
+ @param title Message box title.
+ @param msg Message box text.
+ @param st Message box style.
+ */
+ void
+ SetDialogData(
+ const wxString & title,
+ const wxString & msg,
+ int st = wxID_OK
+ );
+
+ /** Start processing. Does nothing, just implement the
+ Dk4WxProgressControllerBase interface.
+ */
+ void
+ StartProcessing(void);
+
+ /** Indicate end of processing, called from worker thread.
+ @param success Flag: Successful processing.
+ */
+ void
+ EndProcessing(bool success = true);
+
+ /** Check whether we can continue.
+ */
+ bool
+ CanContinue(void);
+
+ /** Check whether the worker thread is finished.
+ @return True if the worker thread is finished, false while running.
+ */
+ bool
+ IsFinished(void);
+
+ /** Retrieve gauge value.
+ @return Current value for progress gauge.
+ */
+ int
+ GetGauge(void);
+
+ /** Abort processing. Called from the progress dialogs Cancel button.
+ */
+ void
+ AbortProcessing(void);
+
+ /** Check whether the worker thread finished successfully.
+ @return True to indicate success, false otherwise.
+ */
+ bool
+ GetSuccess(void);
+
+ /** Check whether a dialog should be shown.
+ @param title Result variable for message box title.
+ @param msg Result variable for message text.
+ @param style Result variable for dialog box style.
+ @return True to show a dialog, false otherwise.
+ */
+ bool
+ GetDialogData(wxString & title, wxString & msg, int & style);
+
+%% class end
+};
+
+%% header end
+
+
+%% module start
+
+#include "Dk4WxProgressDialog.h"
+
+
+
+$!trace-include
+
+
+
+BEGIN_EVENT_TABLE(Dk4WxProgressDialog,wxDialog)
+ EVT_IDLE( Dk4WxProgressDialog::OnIdle)
+ EVT_BUTTON(wxID_CANCEL, Dk4WxProgressDialog::OnCancel)
+END_EVENT_TABLE()
+
+
+static const wxChar * dk4wx_progress_kw_wx[] = {
+$!string-table macro=wxT
+#
+# 0 Default title
+#
+Operation in progress
+Cancel
+Abort operation
+Abortion scheduled, please wait.
+$!end
+};
+
+
+
+/** Integer preference names.
+*/
+static const wxChar * const names[] = {
+$!string-table macro=wxT
+progress.min-width
+$!end
+};
+
+
+%% constructor start
+Dk4WxProgressDialog::Dk4WxProgressDialog(
+ wxFrame *parent,
+ Dk4WxApplicationHelper *pAppHelp
+)
+: wxDialog(
+ parent, wxID_ANY,
+ (
+ (NULL != pAppHelp)
+ ? (pAppHelp->GetBasicString(2))
+ : (dk4wx_progress_kw_wx[0])
+ ),
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxDEFAULT_DIALOG_STYLE
+)
+{
+ const wxChar *labelText = NULL;
+ int minWidth = 300;
+
+ labelText = dk4wx_progress_kw_wx[0];
+ if (NULL != pAppHelp) {
+ labelText = pAppHelp->GetBasicString(2);
+ pAppHelp->GetMultiple(names, &minWidth, 1);
+ if (0 > minWidth) { minWidth = 300; }
+ }
+
+ iOld = 0;
+ iNew = 0;
+ bActive = true;
+ bAborted = false;
+ bFinished = false;
+ bSuccess = false;
+ bHaveDialog = false;
+ sDialogTitle = wxEmptyString;
+ sDialogText = wxEmptyString;
+ iDialogStyle = wxID_OK;
+ if (NULL != pAppHelp) {
+ sText[0] = pAppHelp->GetBasicString(3); // Button label
+ sText[1] = pAppHelp->GetBasicString(4); // Button tooltip
+ sText[2] = pAppHelp->GetBasicString(5); // Text hint
+ } else {
+ sText[0] = dk4wx_progress_kw_wx[1];
+ sText[1] = dk4wx_progress_kw_wx[2];
+ sText[2] = dk4wx_progress_kw_wx[3];
+ }
+%% constructor end
+ if (dkctGUILayoutOK) {
+ wxSize gaugeSize = gaugeProgress->GetMinSize();
+ if (300 > gaugeSize.GetWidth()) {
+ gaugeSize.SetWidth(300);
+ gaugeProgress->SetMinSize(gaugeSize);
+ }
+ sDialog->Fit(this);
+ sDialog->SetSizeHints(this);
+ }
+}
+
+%% module end
+
+
+
+void
+Dk4WxProgressDialog::OnIdle(wxIdleEvent & event)
+{
+ int result;
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ if (bActive) {
+ if (bFinished) {
+ bActive = false;
+ result = wxID_OK;
+ if ((bAborted) || (!(bSuccess))) { result = wxID_CANCEL; }
+ if (IsModal()) {
+ EndModal(result);
+ } else {
+ SetReturnCode((bSuccess) && (!(bAborted)));
+ Show(false);
+ }
+ } else {
+ if (iNew != iOld) {
+ iOld = iNew;
+ gaugeProgress->SetValue(iNew);
+ Refresh();
+ Update();
+ }
+ event.RequestMore();
+ }
+ }
+ }
+ event.Skip();
+}
+
+
+
+void
+Dk4WxProgressDialog::OnCancel(wxCommandEvent & WXUNUSED(event))
+{
+ bCancel->Enable(false);
+ bCancel->SetToolTip(sText[2]);
+ Refresh();
+ Update();
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ if (!(bFinished)) {
+ bAborted = true;
+ }
+ }
+}
+
+
+
+void
+Dk4WxProgressDialog::SetGauge(int value)
+{
+ wxCriticalSectionLocker lock(csProtect);
+ iNew = value;
+}
+
+
+
+void
+Dk4WxProgressDialog::SetDialogData(
+ const wxString & title,
+ const wxString & msg,
+ int st
+)
+{
+ wxCriticalSectionLocker lock(csProtect);
+ bHaveDialog = true;
+ sDialogTitle = title;
+ sDialogText = msg;
+ iDialogStyle = st;
+}
+
+
+
+void
+Dk4WxProgressDialog::StartProcessing(void)
+{
+ wxCriticalSectionLocker lock(csProtect);
+ bActive = true;
+ sDialogTitle = wxEmptyString;
+ sDialogText = wxEmptyString;
+ iOld = 0;
+ iNew = 0;
+ bAborted = false;
+ bFinished = false;
+ bSuccess = true;
+ bActive = true;
+ bHaveDialog = false;
+}
+
+
+
+void
+Dk4WxProgressDialog::EndProcessing(bool success)
+{
+ wxCriticalSectionLocker lock(csProtect);
+ bFinished = true;
+ if (!(bAborted)) {
+ bSuccess = success;
+ }
+}
+
+
+
+bool
+Dk4WxProgressDialog::CanContinue(void)
+{
+ bool back = true;
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ if ((bAborted) || (bFinished)) {
+ back = false;
+ }
+ }
+ return back;
+}
+
+
+
+bool
+Dk4WxProgressDialog::IsFinished(void)
+{
+ bool back = false;
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ back = bFinished;
+ }
+ return back;
+}
+
+
+
+int
+Dk4WxProgressDialog::GetGauge(void)
+{
+ int back = 0;
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ back = iNew;
+ }
+ return back;
+}
+
+
+
+void
+Dk4WxProgressDialog::AbortProcessing(void)
+{
+ wxCriticalSectionLocker lock(csProtect);
+ if (!(bFinished)) {
+ bAborted = true;
+ }
+}
+
+
+
+bool
+Dk4WxProgressDialog::GetSuccess(void)
+{
+ bool back = false;
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ if (bFinished) {
+ back = true;
+ if ((bAborted) || (!(bSuccess))) { back = false; }
+ }
+ }
+ return back;
+}
+
+
+
+bool
+Dk4WxProgressDialog::GetDialogData(
+ wxString & title,
+ wxString & msg,
+ int & style
+)
+{
+ bool back = false;
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ if (bHaveDialog) {
+ title = sDialogTitle;
+ msg = sDialogText;
+ style = iDialogStyle;
+ back = true;
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/DkClockApp.cpp b/support/dktools/DkClockApp.cpp
new file mode 100644
index 0000000000..da18278fea
--- /dev/null
+++ b/support/dktools/DkClockApp.cpp
@@ -0,0 +1,413 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkClockApp.cpt
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkClockApp.cpp The DkClockApp module.
+*/
+
+
+#line 59 "DkClockApp.cpt"
+
+#include "wxdkclock.h"
+
+
+
+
+#line 64 "DkClockApp.cpt"
+
+
+
+/** Localized wxChar texts.
+*/
+static wxChar const * wxdkclock_texts[] = {
+/* 0 */
+wxT("File"),
+
+/* 1 */
+wxT("Exit"),
+
+/* 2 */
+wxT("Exit the application"),
+
+/* 3 */
+wxT("Help"),
+
+/* 4 */
+wxT("About"),
+
+/* 5 */
+wxT("Show version information"),
+
+/* 6 */
+wxT("Contents"),
+
+/* 7 */
+wxT("Open table of contents"),
+
+/* 8 */
+wxT("Alert "),
+
+/* 9 */
+wxT("Copyright (c) "),
+
+/* 10 */
+wxT("About "),
+
+/* 11 */
+wxT("This program uses the following libraries:"),
+
+/* 12 */
+wxT("See:"),
+
+/* 13 */
+wxT("Options"),
+
+/* 14 */
+wxT("Alert"),
+
+/* 15 */
+wxT("Enable/disable alert, set alert time"),
+
+/* 16 */
+wxT("Options"),
+
+/* 17 */
+wxT("OK"),
+
+/* 18 */
+wxT("Apply settings and close dialog box."),
+
+/* 19 */
+wxT("Cancel"),
+
+/* 20 */
+wxT("Close dialog box and discard settings"),
+
+/* 21 */
+wxT("Minute:"),
+
+/* 22 */
+wxT("Hour:"),
+
+/* 23 */
+wxT("Enable or disable alert"),
+
+/* 24 */
+wxT("Choose alert time (hour)"),
+
+/* 25 */
+wxT("Choose alert time (minute)"),
+
+/* 26 */
+wxT("Restore window"),
+
+/* 27 */
+wxT("Exit application"),
+
+/* 28 */
+wxT("Hide"),
+
+/* 29 */
+wxT("Hide main window"),
+
+/* 30 */
+wxT("Colour"),
+
+/* 31 */
+wxT("Normal"),
+
+/* 32 */
+wxT("Clock colour in normal state"),
+
+/* 33 */
+wxT("Alert"),
+
+/* 34 */
+wxT("Clock colour in alert state"),
+
+NULL
+
+
+#line 188 "DkClockApp.cpt"
+};
+
+
+
+/** Non-localized wxChar texts.
+*/
+static wxChar const * wxdkclock_nl_wx[] = {
+/* 0 */
+wxT("WxDkClock"),
+
+/* 1 */
+wxT("3.0.6"),
+
+/* 2 */
+wxT("Dirk Krause"),
+
+/* 3 */
+wxT("DKrause"),
+
+/* 4 */
+wxT("aaaaa"),
+
+/* 5 */
+wxT("wxdkclock.chm"),
+
+/* 6 */
+wxT("wxdkclock.htb"),
+
+/* 7 */
+wxT(" "),
+
+/* 8 */
+wxT("\n"),
+
+/* 9 */
+wxT("DK tools, wxWidgets, libpng, libjpeg, libtiff, zlib."),
+
+/* 10 */
+wxT("http://dktools.sourceforge.net"),
+
+/* 11 */
+wxT("http://www.wxwidgets.org"),
+
+/* 12 */
+wxT("http://www.libpng.org/pub/png/libpng.html"),
+
+/* 13 */
+wxT("http://www.ijg.org"),
+
+/* 14 */
+wxT("http://www.remotesensing.org/libtiff"),
+
+/* 15 */
+wxT("http://www.zlib.net"),
+
+/* 16 */
+wxT("Error"),
+
+/* 17 */
+wxT("Not enough memory (RAM)!"),
+
+NULL
+
+
+#line 248 "DkClockApp.cpt"
+};
+
+
+
+/** Non-localized dkChar texts.
+*/
+static dkChar const * wxdkclock_nl_dk[] = {
+/* 0 */
+dkT("dktools"),
+
+/* 1 */
+dkT("wxdkclock.str"),
+
+NULL
+
+
+#line 265 "DkClockApp.cpt"
+};
+
+
+
+/** Implementation of the wxApp functionality.
+*/
+IMPLEMENT_APP(DkClockApp)
+
+
+bool
+DkClockApp::OnInit()
+{
+ DkClockFrame *frame = NULL;
+ wxChar const * const *localizedTexts = NULL;
+ wxPNGHandler *phPng = NULL;
+ wxXPMHandler *phXpm = NULL;
+ wxICOHandler *phIco = NULL;
+ wxZipFSHandler *phZipFs = NULL;
+ bool back = false;
+
+#if USE_WXAPP_ONINIT
+ if(wxApp::OnInit()) {
+#endif
+
+
+#line 289 "DkClockApp.cpt"
+
+
+#line 290 "DkClockApp.cpt"
+ /* Initialize members. */
+ pHelper = NULL;
+ helpController = NULL;
+
+ /* Set up helper object. */
+ pHelper = new DkWxAppHelper(
+ argv[0],
+ wxdkclock_nl_wx[3],
+ wxdkclock_nl_dk[0]
+ );
+ if(!(pHelper)) { ShowMemoryErrorMessage(); goto finished; }
+ if(!(pHelper->checkSetup())) { goto finished; }
+
+ /* Add image and file system handlers for online help. */
+ phPng = new wxPNGHandler();
+ if (NULL != phPng) {
+ wxImage::AddHandler(phPng);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phXpm = new wxXPMHandler();
+ if (NULL != phXpm) {
+ wxImage::AddHandler(phXpm);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phIco = new wxICOHandler();
+ if (NULL != phIco) {
+ wxImage::AddHandler(phIco);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phZipFs = new wxZipFSHandler();
+ if (NULL != phZipFs) {
+ wxFileSystem::AddHandler(phZipFs);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ localizedTexts = pHelper->getStringTable(
+ wxdkclock_texts, wxdkclock_nl_dk[1]
+ );
+ if(!(localizedTexts)) { localizedTexts = wxdkclock_texts; }
+
+ /* Set up online help controller. */
+ helpController = new DkWxHelpController(
+ pHelper,
+ wxdkclock_nl_wx[5],
+ wxdkclock_nl_wx[6]
+ );
+ if(!(helpController)) { ShowMemoryErrorMessage(); goto finished; }
+
+ /* Create and show frame. */
+ frame = new DkClockFrame(
+ DkClockFrame_MainWindow,
+ pHelper,
+ helpController,
+ argc,
+ argv,
+ localizedTexts,
+ wxdkclock_nl_wx,
+ wxdkclock_nl_dk
+ );
+ if(!(frame)) { ShowMemoryErrorMessage(); goto finished; }
+ frame->Show();
+ frame->restorePosition();
+ back = true;
+
+ /* Release resources if initialization failed. */
+ finished:
+ if(!(back)) {
+ if(helpController) {
+ delete(helpController);
+ helpController = NULL;
+ }
+ if(pHelper) {
+ delete(pHelper);
+ pHelper = NULL;
+ }
+ }
+
+#line 374 "DkClockApp.cpt"
+#if USE_WXAPP_ONINIT
+ }
+#endif
+ return back;
+}
+
+
+
+int
+DkClockApp::OnExit()
+{
+ int back = 0;
+
+
+#line 387 "DkClockApp.cpt"
+ /* Release resources. */
+ if(helpController) {
+ delete(helpController);
+ helpController = NULL;
+ }
+ if(pHelper) {
+ delete(pHelper);
+ pHelper = NULL;
+ }
+
+
+#line 397 "DkClockApp.cpt"
+
+
+#line 398 "DkClockApp.cpt"
+ return back;
+}
+
+
+
+void
+DkClockApp::ShowMemoryErrorMessage(void)
+{
+ const wxChar *s_title = NULL;
+ const wxChar *s_text = NULL;
+
+ if (NULL != pHelper) {
+ s_title = pHelper->getBasicString(3);
+ s_text = pHelper->getBasicString(9);
+ }
+ if (NULL == s_title) {
+ s_title = wxdkclock_nl_wx[16];
+ }
+ if (NULL == s_text) {
+ s_text = wxdkclock_nl_wx[17];
+ }
+ wxMessageBox(s_text, s_title, (wxOK | wxCENTRE | wxICON_ERROR));
+}
+
diff --git a/support/dktools/DkClockApp.cpt b/support/dktools/DkClockApp.cpt
new file mode 100644
index 0000000000..307d8e776e
--- /dev/null
+++ b/support/dktools/DkClockApp.cpt
@@ -0,0 +1,421 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2013-xxxx
+license = bsd
+
+
+
+%% header
+
+
+/** Application class, derived from wxApp, one instance per program.
+*/
+class DkClockApp : public wxApp
+{
+ protected:
+
+ /** Helper object.
+ */
+ DkWxAppHelper *pHelper;
+
+ /** Controller fr online help.
+ */
+ DkWxHelpController *helpController;
+
+ protected:
+
+ /** Show error message if there is not sufficient memory available.
+ */
+ void
+ ShowMemoryErrorMessage(void);
+
+ public:
+
+ /** Application initialization.
+ @return true on success, false on error.
+ */
+ virtual
+ bool
+ OnInit();
+
+ /** Application shutdown.
+ @return 0 on success, any other value indicates an error.
+ */
+ virtual
+ int
+ OnExit();
+};
+
+
+
+/** Declaration as the wxApp object.
+*/
+DECLARE_APP(DkClockApp)
+
+
+
+%% module
+
+#include "wxdkclock.h"
+
+
+$!trace-include
+
+
+
+/** Localized wxChar texts.
+*/
+static wxChar const * wxdkclock_texts[] = {
+$!string-table macro=wxT
+#
+# 0: Menu "File"
+#
+File
+#
+# 1: Menu item "File/Exit"
+#
+Exit
+#
+# 2: Tool tip text for menu item "File/Exit"
+#
+Exit the application
+#
+# 3: Menu "Help"
+#
+Help
+#
+# 4: Menu item "Help/About"
+#
+About
+#
+# 5: Tooltip text for menu item "Help/About"
+#
+Show version information
+#
+# 6: Menu item "Help/Contents"
+#
+Contents
+#
+# 7: Tooltip text for menu item "Help/Contents"
+#
+Open table of contents
+#
+# 8: Check box in options dialog
+#
+Alert
+#
+# 9: Copyright notice.
+#
+Copyright (c)
+#
+# 10: Dialog box title "About ..."
+#
+About
+#
+# 11: This program uses the following libraries
+#
+This program uses the following libraries:
+#
+# 12: See
+#
+See:
+#
+# 13: __CHANGE__ 015: Text for dummy label, can be reused if lDummy removed.
+#
+Options
+#
+# 14 15: Menu item: Options
+#
+Alert
+Enable/disable alert, set alert time
+#
+# 16: Dialog box title
+#
+Options
+#
+# 17 18: OK button
+#
+OK
+Apply settings and close dialog box.
+#
+# 19 20: Cancel button
+#
+Cancel
+Close dialog box and discard settings
+#
+# 21: Minute
+#
+Minute:
+#
+# 22: Hour
+#
+Hour:
+#
+# 23: Tool tip "Enable or disable alert"
+#
+Enable or disable alert
+#
+# 24 25: Tool tips Choose alert time.
+#
+Choose alert time (hour)
+Choose alert time (minute)
+#
+# 26 27: Task bar icon popup menu entries
+#
+Restore window
+Exit application
+#
+# 28 29 Menu item: Hide
+#
+Hide
+Hide main window
+#
+# 30 Menu: Colour
+#
+Colour
+#
+# 31 32 Menu item: Normal state
+#
+Normal
+Clock colour in normal state
+#
+# 33 34 Menu item: Alert state
+#
+Alert
+Clock colour in alert state
+$!end
+};
+
+
+
+/** Non-localized wxChar texts.
+*/
+static wxChar const * wxdkclock_nl_wx[] = {
+$!string-table macro=wxT
+#
+# 0: Program name.
+#
+WxDkClock
+#
+# 1: Program version.
+#
+3.0.6
+#
+# 2: Copyright owner name.
+#
+Dirk Krause
+#
+# 3: Software vendor name.
+#
+DKrause
+#
+# 4: Resource name of Windows icon
+#
+aaaaa
+#
+# 5: Windows chm help file name
+#
+wxdkclock.chm
+#
+# 6: non-Windows htb help file name
+#
+wxdkclock.htb
+#
+# 7: Space
+#
+
+#
+# 8: Newline
+#
+\n
+#
+# 9 10 11 12 13 14 15: List of libraries used.
+#
+DK tools, wxWidgets, libpng, libjpeg, libtiff, zlib.
+http://dktools.sourceforge.net
+http://www.wxwidgets.org
+http://www.libpng.org/pub/png/libpng.html
+http://www.ijg.org
+http://www.remotesensing.org/libtiff
+http://www.zlib.net
+#
+# 16 17
+#
+Error
+Not enough memory (RAM)!
+$!end
+};
+
+
+
+/** Non-localized dkChar texts.
+*/
+static dkChar const * wxdkclock_nl_dk[] = {
+$!string-table macro=dkT
+#
+# 0: Program group name.
+#
+dktools
+#
+# 1: String table name.
+#
+wxdkclock.str
+$!end
+};
+
+
+
+/** Implementation of the wxApp functionality.
+*/
+IMPLEMENT_APP(DkClockApp)
+
+
+bool
+DkClockApp::OnInit()
+{
+ DkClockFrame *frame = NULL;
+ wxChar const * const *localizedTexts = NULL;
+ wxPNGHandler *phPng = NULL;
+ wxXPMHandler *phXpm = NULL;
+ wxICOHandler *phIco = NULL;
+ wxZipFSHandler *phZipFs = NULL;
+ bool back = false;
+
+#if USE_WXAPP_ONINIT
+ if(wxApp::OnInit()) {
+#endif
+ $!trace-init wxdkclock.deb
+ $? "+ DkClockApp::OnInit"
+ /* Initialize members. */
+ pHelper = NULL;
+ helpController = NULL;
+
+ /* Set up helper object. */
+ pHelper = new DkWxAppHelper(
+ argv[0],
+ wxdkclock_nl_wx[3],
+ wxdkclock_nl_dk[0]
+ );
+ if(!(pHelper)) { ShowMemoryErrorMessage(); goto finished; }
+ if(!(pHelper->checkSetup())) { goto finished; }
+
+ /* Add image and file system handlers for online help. */
+ phPng = new wxPNGHandler();
+ if (NULL != phPng) {
+ wxImage::AddHandler(phPng);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phXpm = new wxXPMHandler();
+ if (NULL != phXpm) {
+ wxImage::AddHandler(phXpm);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phIco = new wxICOHandler();
+ if (NULL != phIco) {
+ wxImage::AddHandler(phIco);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phZipFs = new wxZipFSHandler();
+ if (NULL != phZipFs) {
+ wxFileSystem::AddHandler(phZipFs);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ localizedTexts = pHelper->getStringTable(
+ wxdkclock_texts, wxdkclock_nl_dk[1]
+ );
+ if(!(localizedTexts)) { localizedTexts = wxdkclock_texts; }
+
+ /* Set up online help controller. */
+ helpController = new DkWxHelpController(
+ pHelper,
+ wxdkclock_nl_wx[5],
+ wxdkclock_nl_wx[6]
+ );
+ if(!(helpController)) { ShowMemoryErrorMessage(); goto finished; }
+
+ /* Create and show frame. */
+ frame = new DkClockFrame(
+ DkClockFrame_MainWindow,
+ pHelper,
+ helpController,
+ argc,
+ argv,
+ localizedTexts,
+ wxdkclock_nl_wx,
+ wxdkclock_nl_dk
+ );
+ if(!(frame)) { ShowMemoryErrorMessage(); goto finished; }
+ frame->Show();
+ frame->restorePosition();
+ back = true;
+
+ /* Release resources if initialization failed. */
+ finished:
+ if(!(back)) {
+ if(helpController) {
+ delete(helpController);
+ helpController = NULL;
+ }
+ if(pHelper) {
+ delete(pHelper);
+ pHelper = NULL;
+ }
+ } $? "- DkClockApp::OnInit %d", ((back) ? 1 : 0)
+#if USE_WXAPP_ONINIT
+ }
+#endif
+ return back;
+}
+
+
+
+int
+DkClockApp::OnExit()
+{
+ int back = 0;
+ $? "+ DkClockApp::OnExit"
+ /* Release resources. */
+ if(helpController) {
+ delete(helpController);
+ helpController = NULL;
+ }
+ if(pHelper) {
+ delete(pHelper);
+ pHelper = NULL;
+ }
+ $? "- DkClockApp::OnExit %d", back
+ $!trace-end
+ return back;
+}
+
+
+
+void
+DkClockApp::ShowMemoryErrorMessage(void)
+{
+ const wxChar *s_title = NULL;
+ const wxChar *s_text = NULL;
+
+ if (NULL != pHelper) {
+ s_title = pHelper->getBasicString(3);
+ s_text = pHelper->getBasicString(9);
+ }
+ if (NULL == s_title) {
+ s_title = wxdkclock_nl_wx[16];
+ }
+ if (NULL == s_text) {
+ s_text = wxdkclock_nl_wx[17];
+ }
+ wxMessageBox(s_text, s_title, (wxOK | wxCENTRE | wxICON_ERROR));
+}
+
diff --git a/support/dktools/DkClockApp.h b/support/dktools/DkClockApp.h
new file mode 100644
index 0000000000..58b794419d
--- /dev/null
+++ b/support/dktools/DkClockApp.h
@@ -0,0 +1,94 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkClockApp.cpt
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkClockApp.h Header file for the DkClockApp module.
+*/
+
+#ifndef DKCLOCKAPP_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DKCLOCKAPP_H_INCLUDED 1
+
+
+#line 10 "DkClockApp.cpt"
+
+
+/** Application class, derived from wxApp, one instance per program.
+*/
+class DkClockApp : public wxApp
+{
+ protected:
+
+ /** Helper object.
+ */
+ DkWxAppHelper *pHelper;
+
+ /** Controller fr online help.
+ */
+ DkWxHelpController *helpController;
+
+ protected:
+
+ /** Show error message if there is not sufficient memory available.
+ */
+ void
+ ShowMemoryErrorMessage(void);
+
+ public:
+
+ /** Application initialization.
+ @return true on success, false on error.
+ */
+ virtual
+ bool
+ OnInit();
+
+ /** Application shutdown.
+ @return 0 on success, any other value indicates an error.
+ */
+ virtual
+ int
+ OnExit();
+};
+
+
+
+/** Declaration as the wxApp object.
+*/
+DECLARE_APP(DkClockApp)
+
+
+
+
+#endif
diff --git a/support/dktools/DkClockData.cpp b/support/dktools/DkClockData.cpp
new file mode 100644
index 0000000000..e9c407dd42
--- /dev/null
+++ b/support/dktools/DkClockData.cpp
@@ -0,0 +1,210 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkClockData.cpt
+*/
+
+/** @file DkClockData.cpp The DkClockData module.
+*/
+
+
+#line 85 "DkClockData.cpt"
+
+#include "wxdkclock.h"
+
+
+
+
+#line 90 "DkClockData.cpt"
+
+
+DkClockData::DkClockData()
+{
+
+
+#line 95 "DkClockData.cpt"
+ clvd.h = 0;
+ clvd.m = 0;
+ clvd.s = 0;
+ clvd.a = 0;
+ iAlertHour = 0;
+ iAlertMinute = 0;
+ iAlertEnabled = 0;
+ iAlertState = 0;
+ tmCurrent.Y = 0;
+ tmCurrent.M = 0;
+ tmCurrent.D = 0;
+ tmCurrent.h = 0;
+ tmCurrent.m = 0;
+ tmCurrent.s = 0;
+
+
+#line 110 "DkClockData.cpt"
+}
+
+
+
+void
+DkClockData::getData(clockview_data_t *dptr)
+{
+
+
+#line 118 "DkClockData.cpt"
+ if(dptr) {
+ wxMutexLocker lock(mxProtectData);
+ dk3mem_cpy((void *)dptr, (void *)(&clvd), sizeof(clockview_data_t));
+ }
+
+
+#line 123 "DkClockData.cpt"
+}
+
+
+
+int
+DkClockData::setTime(dk3_time_t *ct)
+{
+ dk3_tm_t lct;
+ int back = 0;
+
+
+#line 133 "DkClockData.cpt"
+ if(dk3sf_localtime_app(&lct, ct, NULL)) {
+ wxMutexLocker lock(mxProtectData);
+ /*
+ Check date change.
+ */
+ if(2 == iAlertState) {
+ if(lct.Y != tmCurrent.Y) {
+ iAlertState = 0;
+ } else {
+ if(lct.M != tmCurrent.M) {
+ iAlertState = 0;
+ } else {
+ if(lct.D != tmCurrent.D) {
+ iAlertState = 0;
+ }
+ }
+ }
+ }
+ /*
+ Check alert state change.
+ */
+ if((0 != iAlertEnabled) && (0 == iAlertState)) {
+ if(lct.h > iAlertHour) {
+ iAlertState = 1; back = 1;
+ } else {
+ if(lct.h == iAlertHour) {
+ if(lct.m >= iAlertMinute) {
+ iAlertState = 1; back = 1;
+ }
+ }
+ }
+ }
+ /*
+ Copy current time.
+ */
+ dk3mem_cpy((void *)(&tmCurrent), (void *)(&lct), sizeof(dk3_tm_t));
+ /*
+ Copy to output structure.
+ */
+ clvd.h = lct.h;
+ clvd.m = lct.m;
+ clvd.s = lct.s;
+ clvd.a = ((1 == iAlertState) ? 1 : 0);
+ }
+
+#line 177 "DkClockData.cpt"
+ return back;
+}
+
+
+
+void
+DkClockData::setAlert(bool flag, int hour, int min)
+{
+
+
+#line 186 "DkClockData.cpt"
+ iAlertState = 0;
+ {
+ wxMutexLocker lock(mxProtectData);
+ if(flag) {
+
+#line 190 "DkClockData.cpt"
+ if((0 <= hour) && (23 >= hour) && (0 <= min) && (59 >= min)) {
+ iAlertEnabled = 1;
+
+#line 192 "DkClockData.cpt"
+ iAlertHour = hour;
+ iAlertMinute = min;
+ if(tmCurrent.h > hour) {
+ iAlertState = 2;
+ } else {
+ if(tmCurrent.h == hour) {
+ if(tmCurrent.m >= min) {
+ iAlertState = 2;
+ }
+ }
+ }
+ } else {
+
+#line 204 "DkClockData.cpt"
+ iAlertEnabled = 0;
+ iAlertHour = 0;
+ iAlertMinute = 0;
+ }
+ } else {
+
+#line 209 "DkClockData.cpt"
+ iAlertEnabled = 0;
+ iAlertHour = 0;
+ iAlertMinute = 0;
+ }
+ }
+
+#line 214 "DkClockData.cpt"
+}
+
+
+
+void
+DkClockData::endAlert(void)
+{
+
+
+#line 222 "DkClockData.cpt"
+ {
+ wxMutexLocker lock(mxProtectData);
+ if(1 == iAlertState) {
+ iAlertState = 2;
+ }
+ }
+
+#line 228 "DkClockData.cpt"
+}
+
+
+
+void
+DkClockData::getAlertData(int *en, int *h, int *m)
+{
+
+
+#line 236 "DkClockData.cpt"
+ if((en) && (h) && (m)) {
+ wxMutexLocker lock(mxProtectData);
+ *en = iAlertEnabled;
+
+#line 239 "DkClockData.cpt"
+ *h = iAlertHour;
+
+#line 240 "DkClockData.cpt"
+ *m = iAlertMinute;
+
+#line 241 "DkClockData.cpt"
+ }
+
+#line 242 "DkClockData.cpt"
+}
diff --git a/support/dktools/DkClockData.cpt b/support/dktools/DkClockData.cpt
new file mode 100644
index 0000000000..6005298186
--- /dev/null
+++ b/support/dktools/DkClockData.cpt
@@ -0,0 +1,242 @@
+%% options
+
+%% header
+
+/** Data of interest for the DkClockView class.
+*/
+typedef struct {
+ int h; /**< Current hour. */
+ int m; /**< Current minute. */
+ int s; /**< Current second. */
+ int a; /**< Flag: In alert. */
+} clockview_data_t;
+
+/** Data for DkClock.
+*/
+class DkClockData
+{
+ protected:
+
+ /** Protect data against concurrent access.
+ */
+ wxMutex mxProtectData;
+
+ /** Current time.
+ */
+ dk3_tm_t tmCurrent;
+
+ /** Output data structure.
+ */
+ clockview_data_t clvd;
+
+ /** Hour of alert.
+ */
+ int iAlertHour;
+
+ /** Minute of alert.
+ */
+ int iAlertMinute;
+
+ /** Flag: Alert enabled.
+ */
+ int iAlertEnabled;
+
+ /** Alert state (0=before alert, 1=in alert, 2=after alert).
+ */
+ int iAlertState;
+
+ public:
+
+ /** Constructor.
+ */
+ DkClockData();
+
+ /** Retrieve data from object into buffer.
+ @param dptr Buffer pointer.
+ */
+ void getData(clockview_data_t *dptr);
+
+ /** Get alert settings.
+ @param en Pointer to enabled variable.
+ @param h Pointer to hour variable.
+ @param m Pointer to minute variable.
+ */
+ void getAlertData(int *en, int *h, int *m);
+
+ /** Set new current time.
+ @param ct Current time.
+ @return 1 to maximize and raise the window, 0 to do nothing.
+ */
+ int setTime(dk3_time_t *ct);
+
+ /** Enable or disable alert, set time when enabling.
+ @param flag Flag to enable or disable alert.
+ @param hour Hour of alert.
+ @param min Minute of alert.
+ */
+ void setAlert(bool flag, int hour, int min);
+
+ /** End a running alert.
+ */
+ void endAlert(void);
+};
+
+%% module
+
+#include "wxdkclock.h"
+
+
+$!trace-include
+
+
+DkClockData::DkClockData()
+{
+ $? "+ DkClockData::DkClockData"
+ clvd.h = 0;
+ clvd.m = 0;
+ clvd.s = 0;
+ clvd.a = 0;
+ iAlertHour = 0;
+ iAlertMinute = 0;
+ iAlertEnabled = 0;
+ iAlertState = 0;
+ tmCurrent.Y = 0;
+ tmCurrent.M = 0;
+ tmCurrent.D = 0;
+ tmCurrent.h = 0;
+ tmCurrent.m = 0;
+ tmCurrent.s = 0;
+ $? "- DkClockData::DkClockData"
+}
+
+
+
+void
+DkClockData::getData(clockview_data_t *dptr)
+{
+ $? "+ DkClockData::getData PTR=%d", TR_IPTR(dptr)
+ if(dptr) {
+ wxMutexLocker lock(mxProtectData);
+ dk3mem_cpy((void *)dptr, (void *)(&clvd), sizeof(clockview_data_t));
+ }
+ $? "- DkClockData::getData"
+}
+
+
+
+int
+DkClockData::setTime(dk3_time_t *ct)
+{
+ dk3_tm_t lct;
+ int back = 0;
+ $? "+ DkClockData::setTime"
+ if(dk3sf_localtime_app(&lct, ct, NULL)) {
+ wxMutexLocker lock(mxProtectData);
+ /*
+ Check date change.
+ */
+ if(2 == iAlertState) {
+ if(lct.Y != tmCurrent.Y) {
+ iAlertState = 0;
+ } else {
+ if(lct.M != tmCurrent.M) {
+ iAlertState = 0;
+ } else {
+ if(lct.D != tmCurrent.D) {
+ iAlertState = 0;
+ }
+ }
+ }
+ }
+ /*
+ Check alert state change.
+ */
+ if((0 != iAlertEnabled) && (0 == iAlertState)) {
+ if(lct.h > iAlertHour) {
+ iAlertState = 1; back = 1;
+ } else {
+ if(lct.h == iAlertHour) {
+ if(lct.m >= iAlertMinute) {
+ iAlertState = 1; back = 1;
+ }
+ }
+ }
+ }
+ /*
+ Copy current time.
+ */
+ dk3mem_cpy((void *)(&tmCurrent), (void *)(&lct), sizeof(dk3_tm_t));
+ /*
+ Copy to output structure.
+ */
+ clvd.h = lct.h;
+ clvd.m = lct.m;
+ clvd.s = lct.s;
+ clvd.a = ((1 == iAlertState) ? 1 : 0);
+ } $? "- DkClockData::setTime %d", back
+ return back;
+}
+
+
+
+void
+DkClockData::setAlert(bool flag, int hour, int min)
+{
+ $? "+ DkClockData::setAlert %d %d %d", ((flag) ? 1 : 0), hour, min
+ iAlertState = 0;
+ {
+ wxMutexLocker lock(mxProtectData);
+ if(flag) { $? ". enabled"
+ if((0 <= hour) && (23 >= hour) && (0 <= min) && (59 >= min)) {
+ iAlertEnabled = 1; $? ". values ok"
+ iAlertHour = hour;
+ iAlertMinute = min;
+ if(tmCurrent.h > hour) {
+ iAlertState = 2;
+ } else {
+ if(tmCurrent.h == hour) {
+ if(tmCurrent.m >= min) {
+ iAlertState = 2;
+ }
+ }
+ }
+ } else { $? "! wrong values"
+ iAlertEnabled = 0;
+ iAlertHour = 0;
+ iAlertMinute = 0;
+ }
+ } else { $? ". disabled"
+ iAlertEnabled = 0;
+ iAlertHour = 0;
+ iAlertMinute = 0;
+ }
+ } $? "- DkClockData::setAlert"
+}
+
+
+
+void
+DkClockData::endAlert(void)
+{
+ $? "+ DkClockData::endAlert"
+ {
+ wxMutexLocker lock(mxProtectData);
+ if(1 == iAlertState) {
+ iAlertState = 2;
+ }
+ }$? "- DkClockData::endAlert"
+}
+
+
+
+void
+DkClockData::getAlertData(int *en, int *h, int *m)
+{
+ $? "+ DkClockData::getAlertData"
+ if((en) && (h) && (m)) {
+ wxMutexLocker lock(mxProtectData);
+ *en = iAlertEnabled; $? ". iAlertEnabled %d", iAlertEnabled
+ *h = iAlertHour; $? ". iAlertHour %d", iAlertHour
+ *m = iAlertMinute; $? ". iAlertMinute %d", iAlertMinute
+ } $? "- DkClockData::getAlertData"
+}
diff --git a/support/dktools/DkClockData.h b/support/dktools/DkClockData.h
new file mode 100644
index 0000000000..2a8c8152fb
--- /dev/null
+++ b/support/dktools/DkClockData.h
@@ -0,0 +1,98 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkClockData.cpt
+*/
+
+/** @file DkClockData.h Header file for the DkClockData module.
+*/
+
+#ifndef DKCLOCKDATA_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DKCLOCKDATA_H_INCLUDED 1
+
+
+#line 4 "DkClockData.cpt"
+
+/** Data of interest for the DkClockView class.
+*/
+typedef struct {
+ int h; /**< Current hour. */
+ int m; /**< Current minute. */
+ int s; /**< Current second. */
+ int a; /**< Flag: In alert. */
+} clockview_data_t;
+
+/** Data for DkClock.
+*/
+class DkClockData
+{
+ protected:
+
+ /** Protect data against concurrent access.
+ */
+ wxMutex mxProtectData;
+
+ /** Current time.
+ */
+ dk3_tm_t tmCurrent;
+
+ /** Output data structure.
+ */
+ clockview_data_t clvd;
+
+ /** Hour of alert.
+ */
+ int iAlertHour;
+
+ /** Minute of alert.
+ */
+ int iAlertMinute;
+
+ /** Flag: Alert enabled.
+ */
+ int iAlertEnabled;
+
+ /** Alert state (0=before alert, 1=in alert, 2=after alert).
+ */
+ int iAlertState;
+
+ public:
+
+ /** Constructor.
+ */
+ DkClockData();
+
+ /** Retrieve data from object into buffer.
+ @param dptr Buffer pointer.
+ */
+ void getData(clockview_data_t *dptr);
+
+ /** Get alert settings.
+ @param en Pointer to enabled variable.
+ @param h Pointer to hour variable.
+ @param m Pointer to minute variable.
+ */
+ void getAlertData(int *en, int *h, int *m);
+
+ /** Set new current time.
+ @param ct Current time.
+ @return 1 to maximize and raise the window, 0 to do nothing.
+ */
+ int setTime(dk3_time_t *ct);
+
+ /** Enable or disable alert, set time when enabling.
+ @param flag Flag to enable or disable alert.
+ @param hour Hour of alert.
+ @param min Minute of alert.
+ */
+ void setAlert(bool flag, int hour, int min);
+
+ /** End a running alert.
+ */
+ void endAlert(void);
+};
+
+
+#endif
diff --git a/support/dktools/DkClockFrame.cpp b/support/dktools/DkClockFrame.cpp
new file mode 100644
index 0000000000..84adb6f1b1
--- /dev/null
+++ b/support/dktools/DkClockFrame.cpp
@@ -0,0 +1,764 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkClockFrame.wxc
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkClockFrame.cpp The DkClockFrame module.
+*/
+
+
+#line 305 "DkClockFrame.wxc"
+
+#include "wxdkclock.h"
+#include "dk4verswx.h"
+
+
+#if !defined(__WXMSW__)
+#include "dkclock.xpm"
+#endif
+
+
+
+
+
+#line 317 "DkClockFrame.wxc"
+
+
+
+BEGIN_EVENT_TABLE(DkClockFrame, wxFrame)
+ EVT_MENU(DkClockFrame_Quit, DkClockFrame::OnQuit)
+ EVT_MENU(DkClockFrame_Help_About, DkClockFrame::OnAbout)
+ EVT_MENU(DkClockFrame_Help_Contents, DkClockFrame::OnHelpContents)
+ EVT_MENU(DkClockFrame_Edit_Options, DkClockFrame::OnEditOptions)
+ EVT_MENU(DkClockFrame_Hide, DkClockFrame::OnHide)
+ EVT_MENU(DkClockFrame_NormalColour, DkClockFrame::OnColourNormal)
+ EVT_MENU(DkClockFrame_AlertColour, DkClockFrame::OnColourAlert)
+ EVT_TIMER(DkClockFrame_Timer, DkClockFrame::OnTimer)
+ EVT_IDLE(DkClockFrame::OnIdle)
+ EVT_ICONIZE(DkClockFrame::OnIconize)
+END_EVENT_TABLE()
+
+
+
+wxChar const * const DkClockFrame::kwConfInt[] = {
+/* 0 */ wxT("alert.enabled"),
+/* 1 */ wxT("alert.hour"),
+/* 2 */ wxT("alert.minute"),
+/* 3 */ wxT("colour.clock.red"),
+/* 4 */ wxT("colour.clock.green"),
+/* 5 */ wxT("colour.clock.blue"),
+/* 6 */ wxT("colour.alert.red"),
+/* 7 */ wxT("colour.alert.green"),
+/* 8 */ wxT("colour.alert.blue"),
+NULL
+};
+
+
+
+dkChar const * const DkClockFrame::colPrefKeys[] = {
+/* 0 */ dkT("/colour/clock/red"),
+/* 1 */ dkT("/colour/clock/green"),
+/* 2 */ dkT("/colour/clock/blue"),
+/* 3 */ dkT("/colour/alert/red"),
+/* 4 */ dkT("/colour/alert/green"),
+/* 5 */ dkT("/colour/alert/blue"),
+NULL
+};
+
+
+
+/** Allowed command line arguments.
+*/
+static const wxCmdLineEntryDesc dkclock_cmd_line_desc[] = {
+ {
+ wxCMD_LINE_SWITCH,
+ wxT_2("t"),
+ wxT_2("taskbar"),
+ wxT_2("Hide behind task bar icon"),
+ },
+ { wxCMD_LINE_NONE }
+};
+
+
+
+
+#line 377 "DkClockFrame.wxc"
+DkClockFrame::DkClockFrame(
+ int wxid,
+ DkWxAppHelper *applicationHelper,
+ DkWxHelpController *hc,
+ int argc,
+ wxChar **argv,
+ wxChar const * const *localizedTexts,
+ wxChar const * const *nlWx,
+ dkChar const * const *nlDk
+) : DkWxFrame(nlWx[0], applicationHelper, hc, wxid),
+ tiTenPerSecond(this, DkClockFrame_Timer),
+ pcIdle(),
+ pcTimer(),
+ clockData()
+{
+ dk3_time_t ct;
+ size_t szres;
+ int alval[9];
+ int res = -1;
+
+
+#line 397 "DkClockFrame.wxc"
+ iconTb = NULL;
+#if defined(__WXCOCOA__)
+ iconDock = NULL;
+#endif
+ sTexts = localizedTexts;
+ sNlWx = nlWx;
+ sNlDk = nlDk;
+ bIsFirstIdleEvent = true;
+ currentTime = (dk3_time_t)0UL;
+ bHaveBuffer = true;
+ bIsHidden = false;
+ bShouldHide = false;
+ odx = ody = -1;
+ cdx = cdy = -1;
+#if defined(__WXMSW__)
+ wxIcon wxdkclock_icon(sNlWx[4]);
+#else
+ wxIcon wxdkclock_icon(xpm_dkclock);
+#endif
+ dkctGUILayoutOK = false;
+ dkctGUIContentsPanel = NULL;
+ mainSizer = NULL;
+ mbMain = NULL;
+ menuFile = NULL;
+ menuOptions = NULL;
+ menuHelp = NULL;
+ miFileExit = NULL;
+ miOptionsAlert = NULL;
+ miOptionsHide = NULL;
+ mOptionsColour = NULL;
+ miOptionsColourNormal = NULL;
+ miOptionsColourAlert = NULL;
+ miHelpAbout = NULL;
+ miHelpContents = NULL;
+ verticalSizer = NULL;
+ clv = NULL;
+ dkctGUIContentsPanel = new wxPanel(this);
+ if(!(dkctGUIContentsPanel)) {
+ goto dkctGUILayoutFinished;
+ }
+#if wxUSE_MENUS
+ mbMain = new wxMenuBar(
+ );
+ if(!(mbMain)) {
+ goto dkctGUILayoutFinished;
+ }
+ menuFile = new wxMenu(
+ );
+ if(!(menuFile)) {
+ goto dkctGUILayoutFinished;
+ }
+ miFileExit = menuFile->Append(
+ DkClockFrame_Quit,
+ sTexts[1],
+ sTexts[2]
+ );
+ if(!(miFileExit)) {
+ goto dkctGUILayoutFinished;
+ }
+ mbMain->Append(menuFile, sTexts[0]);
+ menuOptions = new wxMenu(
+ );
+ if(!(menuOptions)) {
+ goto dkctGUILayoutFinished;
+ }
+ miOptionsAlert = menuOptions->Append(
+ DkClockFrame_Edit_Options,
+ sTexts[14],
+ sTexts[15]
+ );
+ if(!(miOptionsAlert)) {
+ goto dkctGUILayoutFinished;
+ }
+ miOptionsHide = menuOptions->AppendCheckItem(
+ DkClockFrame_Hide,
+ sTexts[28],
+ sTexts[29]
+ );
+ if(!(miOptionsHide)) {
+ goto dkctGUILayoutFinished;
+ }
+ mOptionsColour = new wxMenu(
+ );
+ if(!(mOptionsColour)) {
+ goto dkctGUILayoutFinished;
+ }
+ miOptionsColourNormal = mOptionsColour->Append(
+ DkClockFrame_NormalColour,
+ sTexts[31],
+ sTexts[32]
+ );
+ if(!(miOptionsColourNormal)) {
+ goto dkctGUILayoutFinished;
+ }
+ miOptionsColourAlert = mOptionsColour->Append(
+ DkClockFrame_AlertColour,
+ sTexts[33],
+ sTexts[34]
+ );
+ if(!(miOptionsColourAlert)) {
+ goto dkctGUILayoutFinished;
+ }
+ menuOptions->Append(wxID_ANY, sTexts[30], mOptionsColour);
+ mbMain->Append(menuOptions, sTexts[13]);
+ menuHelp = new wxMenu(
+ );
+ if(!(menuHelp)) {
+ goto dkctGUILayoutFinished;
+ }
+ miHelpAbout = menuHelp->Append(
+ DkClockFrame_Help_About,
+ sTexts[4],
+ sTexts[5]
+ );
+ if(!(miHelpAbout)) {
+ goto dkctGUILayoutFinished;
+ }
+ miHelpContents = menuHelp->Append(
+ DkClockFrame_Help_Contents,
+ sTexts[6],
+ sTexts[7]
+ );
+ if(!(miHelpContents)) {
+ goto dkctGUILayoutFinished;
+ }
+ mbMain->Append(menuHelp, sTexts[3]);
+ SetMenuBar(mbMain);
+#endif
+ mainSizer = new wxBoxSizer(
+ wxHORIZONTAL
+ );
+ if(!(mainSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ mainSizer->Add(1, 1, 0);
+ verticalSizer = new wxBoxSizer(
+ wxVERTICAL
+ );
+ if(!(verticalSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ verticalSizer->Add(1, 1, 0);
+ clv = new DkClockView(
+ dkctGUIContentsPanel,wxID_ANY,&clockData
+ );
+ if(!(clv)) {
+ goto dkctGUILayoutFinished;
+ }
+ clv->SetMinSize(wxSize(150, 150));
+ verticalSizer->Add(
+ clv,
+ 1,
+ wxGROW
+ );
+ verticalSizer->Add(1, 1, 0);
+ mainSizer->Add(
+ verticalSizer,
+ 1,
+ wxGROW
+ );
+ mainSizer->Add(1, 1, 0);
+ dkctGUIContentsPanel->SetSizer(mainSizer);
+ SetIcon(wxdkclock_icon);
+ dkctGUILayoutOK = true;
+ dkctGUILayoutFinished:
+ if(dkctGUILayoutOK) {
+ mainSizer->Fit(this);
+ mainSizer->SetSizeHints(this);
+ }
+
+#line 417 "DkClockFrame.wxc"
+ if(dkctGUILayoutOK) {
+ miOptionsHide->Enable(false);
+ SetTitle(nlWx[0]);
+#if 0
+ restorePosition();
+#endif
+ dk3sf_time(&ct);
+ alval[0] = 0; alval[1] = 0; alval[2] = 0;
+ /* When running for the first time, use defaults set by the system
+ administrator.
+ */
+ alval[3] = dk3app_get_pref_int(pHelper->getApp(), colPrefKeys[0], 0);
+ alval[4] = dk3app_get_pref_int(pHelper->getApp(), colPrefKeys[1], 0);
+ alval[5] = dk3app_get_pref_int(pHelper->getApp(), colPrefKeys[2], 0);
+#if DK3_ON_WINDOWS
+ alval[6] = dk3app_get_pref_int(pHelper->getApp(), colPrefKeys[3], 127);
+#else
+ alval[6] = dk3app_get_pref_int(pHelper->getApp(), colPrefKeys[3], 191);
+#endif
+ alval[7] = dk3app_get_pref_int(pHelper->getApp(), colPrefKeys[4], 0);
+ alval[8] = dk3app_get_pref_int(pHelper->getApp(), colPrefKeys[5], 0);
+ szres = pHelper->retrieveMultipleInts(kwConfInt, alval);
+ if(3 <= szres) {
+
+#line 440 "DkClockFrame.wxc"
+ if(0 != alval[0]) {
+
+#line 441 "DkClockFrame.wxc"
+ if((0 <= alval[1]) && (23 >= alval[1])) {
+
+#line 442 "DkClockFrame.wxc"
+ if((0 <= alval[2]) && (59 >= alval[2])) {
+
+#line 443 "DkClockFrame.wxc"
+ clockData.setAlert(true, alval[1], alval[2]);
+ }
+ }
+ } else {
+
+#line 447 "DkClockFrame.wxc"
+ }
+ } else {
+
+#line 449 "DkClockFrame.wxc"
+ }
+ clv->setNormal(alval[3], alval[4], alval[5]);
+ clv->setAlert(alval[6], alval[7], alval[8]);
+ clockData.setTime(&ct);
+ clockData.endAlert();
+ clv->SetMustUpdate();
+#if 0
+ if(wxTaskBarIcon::IsAvailable()) {
+#endif
+ iconTb = new DkClockTaskbarIcon(this, sTexts);
+ if(!(iconTb->SetIcon(wxdkclock_icon, sNlWx[0]))) {
+ delete iconTb;
+ iconTb = NULL;
+ }
+ if(iconTb) {
+ miOptionsHide->Enable(true);
+ }
+#if defined(__WXCOCOA__)
+ if(iconTb) {
+ iconDock = new DkClockTaskbarIcon(this, sTexts, wxTaskBarIcon::DOCK);
+ }
+#endif
+#if 0
+ }
+#endif
+ miOptionsHide->Check(false);
+ {
+ wxCmdLineParser parser(dkclock_cmd_line_desc, argc, argv);
+ {
+ wxLogNull log;
+ res = parser.Parse(false);
+ }
+ if(0 == res) {
+ if(parser.Found(wxT("t"))) {
+ if(iconTb) {
+ bShouldHide = true;
+ miOptionsHide->Check(true);
+ }
+ }
+ }
+ }
+ }
+
+
+#line 492 "DkClockFrame.wxc"
+}
+
+
+#line 495 "DkClockFrame.wxc"
+
+
+
+DkClockFrame::~DkClockFrame()
+{
+
+
+#line 501 "DkClockFrame.wxc"
+ if(iconTb) {
+ delete iconTb;
+ iconTb = NULL;
+ }
+#if defined(__WXCOCOA__)
+ if(iconDock) {
+ delete iconDock;
+ iconDock = NULL;
+ }
+#endif
+
+
+#line 512 "DkClockFrame.wxc"
+}
+
+
+
+void
+DkClockFrame::saveSettings(void)
+{
+ int alval[9];
+
+
+#line 521 "DkClockFrame.wxc"
+ alval[0] = alval[1] = alval[2] = 0;
+ alval[3] = clv->getNormalRed();
+ alval[4] = clv->getNormalGreen();
+ alval[5] = clv->getNormalBlue();
+ alval[6] = clv->getAlertRed();
+ alval[7] = clv->getAlertGreen();
+ alval[8] = clv->getAlertBlue();
+ clockData.getAlertData(&(alval[0]), &(alval[1]), &(alval[2]));
+ pHelper->saveMultipleInts(kwConfInt, alval);
+
+
+#line 531 "DkClockFrame.wxc"
+}
+
+
+bool
+DkClockFrame::canClose(bool isLast)
+{
+#if VERSION_BEFORE_20140410
+ int alval[9];
+#endif
+ bool back = true;
+
+
+#line 542 "DkClockFrame.wxc"
+ tiTenPerSecond.Stop();
+#if VERSION_BEFORE_20140410
+ alval[0] = alval[1] = alval[2] = 0;
+ alval[3] = clv->getNormalRed();
+ alval[4] = clv->getNormalGreen();
+ alval[5] = clv->getNormalBlue();
+ alval[6] = clv->getAlertRed();
+ alval[7] = clv->getAlertGreen();
+ alval[8] = clv->getAlertBlue();
+ clockData.getAlertData(&(alval[0]), &(alval[1]), &(alval[2]));
+ pHelper->saveMultipleInts(kwConfInt, alval);
+#else
+ saveSettings();
+#endif
+
+
+#line 557 "DkClockFrame.wxc"
+ return back;
+}
+
+
+void
+DkClockFrame::OnQuit(wxCommandEvent & event)
+{
+
+
+#line 565 "DkClockFrame.wxc"
+ Close();
+}
+
+
+
+void
+DkClockFrame::OnAbout(wxCommandEvent & event)
+{
+ wxString text(wxT(""));
+ wxString title(wxT(""));
+
+
+#line 576 "DkClockFrame.wxc"
+ /* Construct message text. */
+ text.Append(sNlWx[0]);
+ text.Append(sNlWx[7]);
+#if 0
+ text.Append(sNlWx[1]);
+#else
+ text.Append( DKT_VERSION_WX );
+#endif
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[9]);
+ text.Append(sNlWx[2]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[11]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[9]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[12]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[10]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[11]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[12]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[13]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[14]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[15]);
+ text.Append(sNlWx[8]);
+
+ /* Construct dialog box title. */
+ title.Append(sTexts[10]);
+ title.Append(sNlWx[0]);
+
+ /* Show dialog box. */
+ wxMessageBox(text, title);
+
+
+#line 616 "DkClockFrame.wxc"
+}
+
+
+
+void
+DkClockFrame::OnHelpContents(wxCommandEvent & event)
+{
+
+
+#line 624 "DkClockFrame.wxc"
+ openHelp();
+
+
+#line 626 "DkClockFrame.wxc"
+}
+
+
+
+void
+DkClockFrame::OnEditOptions(wxCommandEvent & event)
+{
+
+
+#line 634 "DkClockFrame.wxc"
+ DkClockOptionsDialog dlg((DkWxFrame *)this, sTexts[16], sTexts, &clockData);
+ pHelper->setRelatedPosition(this, &dlg, &odx, &ody);
+ if(wxID_OK == dlg.ShowModal()) {
+ saveSettings();
+ }
+ dlg.GetPosition(&odx, &ody);
+
+
+#line 641 "DkClockFrame.wxc"
+}
+
+
+void
+DkClockFrame::OnIdle(wxIdleEvent & event)
+{
+
+
+#line 648 "DkClockFrame.wxc"
+ if(pcIdle.canBeginProcessing()) {
+ if(bIsFirstIdleEvent) {
+ bIsFirstIdleEvent = false;
+ tiTenPerSecond.Start(100);
+ if((NULL != iconTb) && (bShouldHide)) {
+ bIsHidden = true;
+ Show(false);
+ }
+ }
+ pcIdle.endProcessing();
+ }
+ event.Skip();
+
+
+#line 661 "DkClockFrame.wxc"
+}
+
+
+
+void
+DkClockFrame::OnTimer(wxTimerEvent & event)
+{
+ dk3_time_t newTime;
+ int res;
+
+
+#line 671 "DkClockFrame.wxc"
+ if(pcTimer.canBeginProcessing()) {
+
+#line 672 "DkClockFrame.wxc"
+ if(dk3sf_time(&newTime)) {
+
+#line 673 "DkClockFrame.wxc"
+ if(newTime > currentTime) {
+
+#line 674 "DkClockFrame.wxc"
+ currentTime = newTime;
+ res = clockData.setTime(&currentTime);
+ if(1 == res) {
+
+#line 677 "DkClockFrame.wxc"
+ bHaveBuffer = true;
+ bIsHidden = false;
+ Show(true);
+ Iconize(false);
+ Maximize(true);
+ Raise();
+ clv->SetMustUpdate();
+ clv->Refresh();
+ clv->Update();
+ } else {
+
+#line 687 "DkClockFrame.wxc"
+ if((IsIconized()) || (bIsHidden)) {
+
+#line 688 "DkClockFrame.wxc"
+ if(bHaveBuffer) {
+
+#line 689 "DkClockFrame.wxc"
+ bHaveBuffer = false;
+ clv->releaseBuffer();
+ }
+ } else {
+
+#line 693 "DkClockFrame.wxc"
+ bHaveBuffer = true;
+
+#line 694 "DkClockFrame.wxc"
+ clv->SetMustUpdate();
+ clv->Refresh();
+ clv->Update();
+ }
+ }
+ }
+ }
+ pcTimer.endProcessing();
+ }
+
+#line 703 "DkClockFrame.wxc"
+}
+
+
+
+void
+DkClockFrame::OnHide(wxCommandEvent & event)
+{
+
+
+#line 711 "DkClockFrame.wxc"
+ if(miOptionsHide->IsChecked()) {
+ bShouldHide = true;
+ bIsHidden = true;
+ Show(false);
+ } else {
+ bShouldHide = false;
+ }
+
+
+#line 719 "DkClockFrame.wxc"
+}
+
+
+
+void
+DkClockFrame::OnColourNormal(wxCommandEvent & event)
+{
+ wxColourData wxcd;
+ wxcd.SetColour(
+ wxColour(
+ clv->getNormalRed(),
+ clv->getNormalGreen(),
+ clv->getNormalBlue()
+ )
+ );
+ wxColourDialog dlg(this, &wxcd);
+ pHelper->setRelatedPosition(this, &dlg, &cdx, &cdy);
+ if(dlg.ShowModal() == wxID_OK) {
+ wxColour c = dlg.GetColourData().GetColour();
+ clv->setNormal(c.Red(), c.Green(), c.Blue());
+ saveSettings();
+ }
+ dlg.GetPosition(&cdx, &cdy);
+}
+
+
+
+void
+DkClockFrame::OnColourAlert(wxCommandEvent & event)
+{
+ wxColourData wxcd;
+ wxcd.SetColour(
+ wxColour(
+ clv->getAlertRed(),
+ clv->getAlertGreen(),
+ clv->getAlertBlue()
+ )
+ );
+ wxColourDialog dlg(this, &wxcd);
+ pHelper->setRelatedPosition(this, &dlg, &cdx, &cdy);
+ if(dlg.ShowModal() == wxID_OK) {
+ wxColour c = dlg.GetColourData().GetColour();
+ clv->setAlert(c.Red(), c.Green(), c.Blue());
+ saveSettings();
+ }
+ dlg.GetPosition(&cdx, &cdy);
+}
+
+
+
+void
+DkClockFrame::SetHidden(bool b)
+{
+
+
+#line 773 "DkClockFrame.wxc"
+ bIsHidden = b;
+
+
+#line 775 "DkClockFrame.wxc"
+}
+
+
+
+void
+DkClockFrame::OnIconize(wxIconizeEvent & event)
+{
+#if wxCHECK_VERSION(3,0,0)
+ if(event.IsIconized())
+#else
+ if(event.Iconized())
+#endif
+ {
+ if(bShouldHide) {
+ if(NULL != iconTb) {
+ bIsHidden = true;
+ Show(false);
+ }
+ }
+ }
+}
+
+
diff --git a/support/dktools/DkClockFrame.h b/support/dktools/DkClockFrame.h
new file mode 100644
index 0000000000..948a8a0cf0
--- /dev/null
+++ b/support/dktools/DkClockFrame.h
@@ -0,0 +1,337 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkClockFrame.wxc
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkClockFrame.h Header file for the DkClockFrame module.
+*/
+
+#ifndef DKCLOCKFRAME_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DKCLOCKFRAME_H_INCLUDED 1
+
+
+#line 99 "DkClockFrame.wxc"
+
+
+#line 101 "DkClockFrame.wxc"
+class DkClockFrame : public DkWxFrame
+{
+ private:
+
+ /** Event table for frame.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ /** Timer.
+ */
+ wxTimer tiTenPerSecond;
+
+ /** Controller for idle processing.
+ */
+ DkWxProcessingIdleController pcIdle;
+
+ /** Processing controller for timer events.
+ */
+ DkWxProcessingController pcTimer;
+
+ /* Clock data including timer settings and current time.
+ */
+ DkClockData clockData;
+
+ /** Keywords for configuration entries.
+ */
+ static wxChar const * const kwConfInt[];
+
+ /** Colour preference keys.
+ */
+ static dkChar const * const colPrefKeys[];
+
+ /** Localized texts.
+ */
+ wxChar const * const *sTexts;
+
+ /** Non-localized texts.
+ */
+ wxChar const * const *sNlWx;
+
+ /** Non-localized texts.
+ */
+ dkChar const * const *sNlDk;
+
+ /** Task bar icon.
+ */
+ DkClockTaskbarIcon *iconTb;
+
+#if defined(__WXCOCOA__)
+ /** Dock icon.
+ */
+ DkClockTaskbarIcon *iconDock;
+#endif
+
+ /** Last current time saved.
+ */
+ dk3_time_t currentTime;
+
+ /** Previous options dialog x position.
+ */
+ int odx;
+
+ /** Previous options dialog y position.
+ */
+ int ody;
+
+ /** Colour dialog x position.
+ */
+ int cdx;
+
+ /** Colour dialog y position.
+ */
+ int cdy;
+
+ /** Flag: Is first idle event.
+ */
+ bool bIsFirstIdleEvent;
+
+ /** Flag: First time iconized.
+ */
+ bool bHaveBuffer;
+
+ /** Flag: Application is hidden behind task bar icon.
+ */
+ bool bIsHidden;
+
+ /** Flag: Option -h specified to hide at startup.
+ */
+ bool bShouldHide;
+
+ /** Flag: GUI ok.
+ */
+ bool dkctGUILayoutOK;
+
+ /** Contents panel.
+ */
+ wxPanel *dkctGUIContentsPanel;
+
+ /** GUI element mainSizer.
+ */
+#line 77 "DkClockFrame.wxc"
+ wxBoxSizer *mainSizer;
+
+ /** GUI element mbMain.
+ */
+#line 16 "DkClockFrame.wxc"
+ wxMenuBar *mbMain;
+
+ /** GUI element menuFile.
+ */
+#line 21 "DkClockFrame.wxc"
+ wxMenu *menuFile;
+
+ /** GUI element menuOptions.
+ */
+#line 30 "DkClockFrame.wxc"
+ wxMenu *menuOptions;
+
+ /** GUI element menuHelp.
+ */
+#line 62 "DkClockFrame.wxc"
+ wxMenu *menuHelp;
+
+ /** GUI element miFileExit.
+ */
+#line 25 "DkClockFrame.wxc"
+ wxMenuItem *miFileExit;
+
+ /** GUI element miOptionsAlert.
+ */
+#line 36 "DkClockFrame.wxc"
+ wxMenuItem *miOptionsAlert;
+
+ /** GUI element miOptionsHide.
+ */
+#line 41 "DkClockFrame.wxc"
+ wxMenuItem *miOptionsHide;
+
+ /** GUI element mOptionsColour.
+ */
+#line 47 "DkClockFrame.wxc"
+ wxMenu *mOptionsColour;
+
+ /** GUI element miOptionsColourNormal.
+ */
+#line 52 "DkClockFrame.wxc"
+ wxMenuItem *miOptionsColourNormal;
+
+ /** GUI element miOptionsColourAlert.
+ */
+#line 57 "DkClockFrame.wxc"
+ wxMenuItem *miOptionsColourAlert;
+
+ /** GUI element miHelpAbout.
+ */
+#line 67 "DkClockFrame.wxc"
+ wxMenuItem *miHelpAbout;
+
+ /** GUI element miHelpContents.
+ */
+#line 72 "DkClockFrame.wxc"
+ wxMenuItem *miHelpContents;
+
+ /** GUI element verticalSizer.
+ */
+#line 83 "DkClockFrame.wxc"
+ wxBoxSizer *verticalSizer;
+
+ /** GUI element clv.
+ */
+#line 91 "DkClockFrame.wxc"
+ DkClockView *clv;
+
+
+#line 194 "DkClockFrame.wxc"
+
+ protected:
+
+ /** Save all settings.
+ */
+ void
+ saveSettings(void);
+
+ public:
+
+ /** Constructor.
+ @param wxid Window ID.
+ @param applicationHelper Application helper object.
+ @param hc Help controller for online help.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @param localizedTexts Localized wxChar texts.
+ @param nlWx Non-localized wxChar texts.
+ @param nlDk Non-localized dkChar texts.
+ */
+ DkClockFrame(
+ int wxid,
+ DkWxAppHelper *applicationHelper,
+ DkWxHelpController *hc,
+ int argc,
+ wxChar **argv,
+ wxChar const * const *localizedTexts,
+ wxChar const * const *nlWx,
+ dkChar const * const *nlDk
+ );
+
+ /** Destructor.
+ */
+ ~DkClockFrame();
+
+ /** Check whether we can close the window.
+ @param isLast Flag: Last main window to close.
+ */
+ bool
+ canClose(bool isLast);
+
+ /** Handler for File/Exit.
+ @param event Event to process.
+ */
+ void
+ OnQuit(wxCommandEvent & event);
+
+ /** Handler for Help/About.
+ @param event Event to process.
+ */
+ void
+ OnAbout(wxCommandEvent & event);
+
+ /** Handler for Help/Contents.
+ @param event Event to process.
+ */
+ void
+ OnHelpContents(wxCommandEvent & event);
+
+ /** Handler for Edit/Options.
+ @param event Event to process.
+ */
+ void
+ OnEditOptions(wxCommandEvent & event);
+
+ /** Handler for idle events.
+ @param event Event to process.
+ */
+ void
+ OnIdle(wxIdleEvent & event);
+
+ /** Handler for timer events.
+ @param event Event to process.
+ */
+ void
+ OnTimer(wxTimerEvent & event);
+
+ /** Handler for hide menu item.
+ @param event Event to process.
+ */
+ void
+ OnHide(wxCommandEvent & event);
+
+ /** Handler for normal colour menu item.
+ @param event Event to process.
+ */
+ void
+ OnColourNormal(wxCommandEvent & event);
+
+ /** Handler for alert colour menu item.
+ @param event Event to process.
+ */
+ void
+ OnColourAlert(wxCommandEvent & event);
+
+ /** Handler for iconize.
+ @param event Event to process.
+ */
+ void
+ OnIconize(wxIconizeEvent & event);
+
+ /** Notify window whether or not it is hidden.
+ */
+ void
+ SetHidden(bool b);
+
+};
+
+
+#line 303 "DkClockFrame.wxc"
+
+
+#endif
diff --git a/support/dktools/DkClockFrame.wxc b/support/dktools/DkClockFrame.wxc
new file mode 100644
index 0000000000..61ef19ed9a
--- /dev/null
+++ b/support/dktools/DkClockFrame.wxc
@@ -0,0 +1,797 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2013-xxxx
+license = bsd
+
+
+
+%% wx-gui
+
+type = frame
+contents = mainSizer
+icon = wxdkclock_icon
+menu bar = mbMain
+
+[wxMenuBar mbMain]
+contents = menuFile
+contents = menuOptions
+contents = menuHelp
+
+[wxMenu menuFile]
+text = sTexts[0]
+contents = miFileExit
+
+[wxMenuItem miFileExit]
+id = DkClockFrame_Quit
+text = sTexts[1]
+tip = sTexts[2]
+
+[wxMenu menuOptions]
+text = sTexts[13]
+contents = miOptionsAlert
+contents = miOptionsHide
+contents = mOptionsColour
+
+[wxMenuItem miOptionsAlert]
+id = DkClockFrame_Edit_Options
+text = sTexts[14]
+tip = sTexts[15]
+
+[wxMenuItem miOptionsHide]
+id = DkClockFrame_Hide
+text = sTexts[28]
+tip = sTexts[29]
+menu item style = check
+
+[wxMenu mOptionsColour]
+text = sTexts[30]
+contents = miOptionsColourNormal
+contents = miOptionsColourAlert
+
+[wxMenuItem miOptionsColourNormal]
+id = DkClockFrame_NormalColour
+text = sTexts[31]
+tip = sTexts[32]
+
+[wxMenuItem miOptionsColourAlert]
+id = DkClockFrame_AlertColour
+text = sTexts[33]
+tip = sTexts[34]
+
+[wxMenu menuHelp]
+text = sTexts[3]
+contents = miHelpAbout
+contents = miHelpContents
+
+[wxMenuItem miHelpAbout]
+id = DkClockFrame_Help_About
+text = sTexts[4]
+tip = sTexts[5]
+
+[wxMenuItem miHelpContents]
+id = DkClockFrame_Help_Contents
+text = sTexts[6]
+tip = sTexts[7]
+
+[wxBoxSizer mainSizer]
+direction = horizontal
+contents = $space(1)
+contents = verticalSizer
+contents = $space(1)
+
+[wxBoxSizer verticalSizer]
+direction = vertical
+grow = yes
+proportion = 1
+contents = $space(1)
+contents = clv
+contents = $space(1)
+
+[DkClockView clv]
+grow = yes
+proportion = 1
+id = wxID_ANY
+constructor = &clockData
+minimum size = 150 150
+
+%% header start
+
+%% class start
+class DkClockFrame : public DkWxFrame
+{
+ private:
+
+ /** Event table for frame.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ /** Timer.
+ */
+ wxTimer tiTenPerSecond;
+
+ /** Controller for idle processing.
+ */
+ DkWxProcessingIdleController pcIdle;
+
+ /** Processing controller for timer events.
+ */
+ DkWxProcessingController pcTimer;
+
+ /* Clock data including timer settings and current time.
+ */
+ DkClockData clockData;
+
+ /** Keywords for configuration entries.
+ */
+ static wxChar const * const kwConfInt[];
+
+ /** Colour preference keys.
+ */
+ static dkChar const * const colPrefKeys[];
+
+ /** Localized texts.
+ */
+ wxChar const * const *sTexts;
+
+ /** Non-localized texts.
+ */
+ wxChar const * const *sNlWx;
+
+ /** Non-localized texts.
+ */
+ dkChar const * const *sNlDk;
+
+ /** Task bar icon.
+ */
+ DkClockTaskbarIcon *iconTb;
+
+#if defined(__WXCOCOA__)
+ /** Dock icon.
+ */
+ DkClockTaskbarIcon *iconDock;
+#endif
+
+ /** Last current time saved.
+ */
+ dk3_time_t currentTime;
+
+ /** Previous options dialog x position.
+ */
+ int odx;
+
+ /** Previous options dialog y position.
+ */
+ int ody;
+
+ /** Colour dialog x position.
+ */
+ int cdx;
+
+ /** Colour dialog y position.
+ */
+ int cdy;
+
+ /** Flag: Is first idle event.
+ */
+ bool bIsFirstIdleEvent;
+
+ /** Flag: First time iconized.
+ */
+ bool bHaveBuffer;
+
+ /** Flag: Application is hidden behind task bar icon.
+ */
+ bool bIsHidden;
+
+ /** Flag: Option -h specified to hide at startup.
+ */
+ bool bShouldHide;
+
+%% class end
+
+ protected:
+
+ /** Save all settings.
+ */
+ void
+ saveSettings(void);
+
+ public:
+
+ /** Constructor.
+ @param wxid Window ID.
+ @param applicationHelper Application helper object.
+ @param hc Help controller for online help.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @param localizedTexts Localized wxChar texts.
+ @param nlWx Non-localized wxChar texts.
+ @param nlDk Non-localized dkChar texts.
+ */
+ DkClockFrame(
+ int wxid,
+ DkWxAppHelper *applicationHelper,
+ DkWxHelpController *hc,
+ int argc,
+ wxChar **argv,
+ wxChar const * const *localizedTexts,
+ wxChar const * const *nlWx,
+ dkChar const * const *nlDk
+ );
+
+ /** Destructor.
+ */
+ ~DkClockFrame();
+
+ /** Check whether we can close the window.
+ @param isLast Flag: Last main window to close.
+ */
+ bool
+ canClose(bool isLast);
+
+ /** Handler for File/Exit.
+ @param event Event to process.
+ */
+ void
+ OnQuit(wxCommandEvent & event);
+
+ /** Handler for Help/About.
+ @param event Event to process.
+ */
+ void
+ OnAbout(wxCommandEvent & event);
+
+ /** Handler for Help/Contents.
+ @param event Event to process.
+ */
+ void
+ OnHelpContents(wxCommandEvent & event);
+
+ /** Handler for Edit/Options.
+ @param event Event to process.
+ */
+ void
+ OnEditOptions(wxCommandEvent & event);
+
+ /** Handler for idle events.
+ @param event Event to process.
+ */
+ void
+ OnIdle(wxIdleEvent & event);
+
+ /** Handler for timer events.
+ @param event Event to process.
+ */
+ void
+ OnTimer(wxTimerEvent & event);
+
+ /** Handler for hide menu item.
+ @param event Event to process.
+ */
+ void
+ OnHide(wxCommandEvent & event);
+
+ /** Handler for normal colour menu item.
+ @param event Event to process.
+ */
+ void
+ OnColourNormal(wxCommandEvent & event);
+
+ /** Handler for alert colour menu item.
+ @param event Event to process.
+ */
+ void
+ OnColourAlert(wxCommandEvent & event);
+
+ /** Handler for iconize.
+ @param event Event to process.
+ */
+ void
+ OnIconize(wxIconizeEvent & event);
+
+ /** Notify window whether or not it is hidden.
+ */
+ void
+ SetHidden(bool b);
+
+};
+
+%% header end
+
+%% module start
+
+#include "wxdkclock.h"
+#include "dk4verswx.h"
+
+
+#if !defined(__WXMSW__)
+#include "dkclock.xpm"
+#endif
+
+
+
+$!trace-include
+
+
+
+BEGIN_EVENT_TABLE(DkClockFrame, wxFrame)
+ EVT_MENU(DkClockFrame_Quit, DkClockFrame::OnQuit)
+ EVT_MENU(DkClockFrame_Help_About, DkClockFrame::OnAbout)
+ EVT_MENU(DkClockFrame_Help_Contents, DkClockFrame::OnHelpContents)
+ EVT_MENU(DkClockFrame_Edit_Options, DkClockFrame::OnEditOptions)
+ EVT_MENU(DkClockFrame_Hide, DkClockFrame::OnHide)
+ EVT_MENU(DkClockFrame_NormalColour, DkClockFrame::OnColourNormal)
+ EVT_MENU(DkClockFrame_AlertColour, DkClockFrame::OnColourAlert)
+ EVT_TIMER(DkClockFrame_Timer, DkClockFrame::OnTimer)
+ EVT_IDLE(DkClockFrame::OnIdle)
+ EVT_ICONIZE(DkClockFrame::OnIconize)
+END_EVENT_TABLE()
+
+
+
+wxChar const * const DkClockFrame::kwConfInt[] = {
+/* 0 */ wxT("alert.enabled"),
+/* 1 */ wxT("alert.hour"),
+/* 2 */ wxT("alert.minute"),
+/* 3 */ wxT("colour.clock.red"),
+/* 4 */ wxT("colour.clock.green"),
+/* 5 */ wxT("colour.clock.blue"),
+/* 6 */ wxT("colour.alert.red"),
+/* 7 */ wxT("colour.alert.green"),
+/* 8 */ wxT("colour.alert.blue"),
+NULL
+};
+
+
+
+dkChar const * const DkClockFrame::colPrefKeys[] = {
+/* 0 */ dkT("/colour/clock/red"),
+/* 1 */ dkT("/colour/clock/green"),
+/* 2 */ dkT("/colour/clock/blue"),
+/* 3 */ dkT("/colour/alert/red"),
+/* 4 */ dkT("/colour/alert/green"),
+/* 5 */ dkT("/colour/alert/blue"),
+NULL
+};
+
+
+
+/** Allowed command line arguments.
+*/
+static const wxCmdLineEntryDesc dkclock_cmd_line_desc[] = {
+ {
+ wxCMD_LINE_SWITCH,
+ wxT_2("t"),
+ wxT_2("taskbar"),
+ wxT_2("Hide behind task bar icon"),
+ },
+ { wxCMD_LINE_NONE }
+};
+
+
+
+%% constructor start
+DkClockFrame::DkClockFrame(
+ int wxid,
+ DkWxAppHelper *applicationHelper,
+ DkWxHelpController *hc,
+ int argc,
+ wxChar **argv,
+ wxChar const * const *localizedTexts,
+ wxChar const * const *nlWx,
+ dkChar const * const *nlDk
+) : DkWxFrame(nlWx[0], applicationHelper, hc, wxid),
+ tiTenPerSecond(this, DkClockFrame_Timer),
+ pcIdle(),
+ pcTimer(),
+ clockData()
+{
+ dk3_time_t ct;
+ size_t szres;
+ int alval[9];
+ int res = -1;
+ $? "+ DkClockFrame::DkClockFrame"
+ iconTb = NULL;
+#if defined(__WXCOCOA__)
+ iconDock = NULL;
+#endif
+ sTexts = localizedTexts;
+ sNlWx = nlWx;
+ sNlDk = nlDk;
+ bIsFirstIdleEvent = true;
+ currentTime = (dk3_time_t)0UL;
+ bHaveBuffer = true;
+ bIsHidden = false;
+ bShouldHide = false;
+ odx = ody = -1;
+ cdx = cdy = -1;
+#if defined(__WXMSW__)
+ wxIcon wxdkclock_icon(sNlWx[4]);
+#else
+ wxIcon wxdkclock_icon(xpm_dkclock);
+#endif
+%% constructor end
+ if(dkctGUILayoutOK) {
+ miOptionsHide->Enable(false);
+ SetTitle(nlWx[0]);
+#if 0
+ restorePosition();
+#endif
+ dk3sf_time(&ct);
+ alval[0] = 0; alval[1] = 0; alval[2] = 0;
+ /* When running for the first time, use defaults set by the system
+ administrator.
+ */
+ alval[3] = dk3app_get_pref_int(pHelper->getApp(), colPrefKeys[0], 0);
+ alval[4] = dk3app_get_pref_int(pHelper->getApp(), colPrefKeys[1], 0);
+ alval[5] = dk3app_get_pref_int(pHelper->getApp(), colPrefKeys[2], 0);
+#if DK3_ON_WINDOWS
+ alval[6] = dk3app_get_pref_int(pHelper->getApp(), colPrefKeys[3], 127);
+#else
+ alval[6] = dk3app_get_pref_int(pHelper->getApp(), colPrefKeys[3], 191);
+#endif
+ alval[7] = dk3app_get_pref_int(pHelper->getApp(), colPrefKeys[4], 0);
+ alval[8] = dk3app_get_pref_int(pHelper->getApp(), colPrefKeys[5], 0);
+ szres = pHelper->retrieveMultipleInts(kwConfInt, alval);
+ if(3 <= szres) { $? ". retrieve"
+ if(0 != alval[0]) { $? ". enabled"
+ if((0 <= alval[1]) && (23 >= alval[1])) { $? ". hour ok"
+ if((0 <= alval[2]) && (59 >= alval[2])) { $? ". min ok"
+ clockData.setAlert(true, alval[1], alval[2]);
+ }
+ }
+ } else { $? ". not enabled"
+ }
+ } else { $? "! retrieve"
+ }
+ clv->setNormal(alval[3], alval[4], alval[5]);
+ clv->setAlert(alval[6], alval[7], alval[8]);
+ clockData.setTime(&ct);
+ clockData.endAlert();
+ clv->SetMustUpdate();
+#if 0
+ if(wxTaskBarIcon::IsAvailable()) {
+#endif
+ iconTb = new DkClockTaskbarIcon(this, sTexts);
+ if(!(iconTb->SetIcon(wxdkclock_icon, sNlWx[0]))) {
+ delete iconTb;
+ iconTb = NULL;
+ }
+ if(iconTb) {
+ miOptionsHide->Enable(true);
+ }
+#if defined(__WXCOCOA__)
+ if(iconTb) {
+ iconDock = new DkClockTaskbarIcon(this, sTexts, wxTaskBarIcon::DOCK);
+ }
+#endif
+#if 0
+ }
+#endif
+ miOptionsHide->Check(false);
+ {
+ wxCmdLineParser parser(dkclock_cmd_line_desc, argc, argv);
+ {
+ wxLogNull log;
+ res = parser.Parse(false);
+ }
+ if(0 == res) {
+ if(parser.Found(wxT("t"))) {
+ if(iconTb) {
+ bShouldHide = true;
+ miOptionsHide->Check(true);
+ }
+ }
+ }
+ }
+ }
+ $? "- DkClockFrame::DkClockFrame %d", ((dkctGUILayoutOK) ? 1 : 0)
+}
+
+%% module end
+
+
+
+DkClockFrame::~DkClockFrame()
+{
+ $? "+ DkClockFrame::~DkClockFrame"
+ if(iconTb) {
+ delete iconTb;
+ iconTb = NULL;
+ }
+#if defined(__WXCOCOA__)
+ if(iconDock) {
+ delete iconDock;
+ iconDock = NULL;
+ }
+#endif
+ $? "- DkClockFrame::~DkClockFrame"
+}
+
+
+
+void
+DkClockFrame::saveSettings(void)
+{
+ int alval[9];
+ $? "+ DkClockFrame::saveSettings"
+ alval[0] = alval[1] = alval[2] = 0;
+ alval[3] = clv->getNormalRed();
+ alval[4] = clv->getNormalGreen();
+ alval[5] = clv->getNormalBlue();
+ alval[6] = clv->getAlertRed();
+ alval[7] = clv->getAlertGreen();
+ alval[8] = clv->getAlertBlue();
+ clockData.getAlertData(&(alval[0]), &(alval[1]), &(alval[2]));
+ pHelper->saveMultipleInts(kwConfInt, alval);
+ $? "- DkClockFrame::saveSettings"
+}
+
+
+bool
+DkClockFrame::canClose(bool isLast)
+{
+#if VERSION_BEFORE_20140410
+ int alval[9];
+#endif
+ bool back = true;
+ $? "+ DkClockFrame::canClose"
+ tiTenPerSecond.Stop();
+#if VERSION_BEFORE_20140410
+ alval[0] = alval[1] = alval[2] = 0;
+ alval[3] = clv->getNormalRed();
+ alval[4] = clv->getNormalGreen();
+ alval[5] = clv->getNormalBlue();
+ alval[6] = clv->getAlertRed();
+ alval[7] = clv->getAlertGreen();
+ alval[8] = clv->getAlertBlue();
+ clockData.getAlertData(&(alval[0]), &(alval[1]), &(alval[2]));
+ pHelper->saveMultipleInts(kwConfInt, alval);
+#else
+ saveSettings();
+#endif
+ $? "- DkClockFrame::canClose %d", ((back) ? 1 : 0)
+ return back;
+}
+
+
+void
+DkClockFrame::OnQuit(wxCommandEvent & event)
+{
+ $? "= DkClockFrame::OnQuit"
+ Close();
+}
+
+
+
+void
+DkClockFrame::OnAbout(wxCommandEvent & event)
+{
+ wxString text(wxT(""));
+ wxString title(wxT(""));
+ $? "+ DkClockFrame::OnAbout"
+ /* Construct message text. */
+ text.Append(sNlWx[0]);
+ text.Append(sNlWx[7]);
+#if 0
+ text.Append(sNlWx[1]);
+#else
+ text.Append( DKT_VERSION_WX );
+#endif
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[9]);
+ text.Append(sNlWx[2]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[11]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[9]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[12]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[10]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[11]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[12]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[13]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[14]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[15]);
+ text.Append(sNlWx[8]);
+
+ /* Construct dialog box title. */
+ title.Append(sTexts[10]);
+ title.Append(sNlWx[0]);
+
+ /* Show dialog box. */
+ wxMessageBox(text, title);
+ $? "- DkClockFrame::OnAbout"
+}
+
+
+
+void
+DkClockFrame::OnHelpContents(wxCommandEvent & event)
+{
+ $? "+ DkClockFrame::OnHelpContents"
+ openHelp();
+ $? "- DkClockFrame::OnHelpContents"
+}
+
+
+
+void
+DkClockFrame::OnEditOptions(wxCommandEvent & event)
+{
+ $? "+ DkClockFrame::OnEditOptions"
+ DkClockOptionsDialog dlg((DkWxFrame *)this, sTexts[16], sTexts, &clockData);
+ pHelper->setRelatedPosition(this, &dlg, &odx, &ody);
+ if(wxID_OK == dlg.ShowModal()) {
+ saveSettings();
+ }
+ dlg.GetPosition(&odx, &ody);
+ $? "- DkClockFrame::OnEditOptions"
+}
+
+
+void
+DkClockFrame::OnIdle(wxIdleEvent & event)
+{
+ $? "+ DkClockFrame::OnIdle"
+ if(pcIdle.canBeginProcessing()) {
+ if(bIsFirstIdleEvent) {
+ bIsFirstIdleEvent = false;
+ tiTenPerSecond.Start(100);
+ if((NULL != iconTb) && (bShouldHide)) {
+ bIsHidden = true;
+ Show(false);
+ }
+ }
+ pcIdle.endProcessing();
+ }
+ event.Skip();
+ $? "- DkClockFrame::OnIdle"
+}
+
+
+
+void
+DkClockFrame::OnTimer(wxTimerEvent & event)
+{
+ dk3_time_t newTime;
+ int res;
+ $? "+ DkClockFrame::OnTimer"
+ if(pcTimer.canBeginProcessing()) { $? ". can begin processing"
+ if(dk3sf_time(&newTime)) { $? ". time found"
+ if(newTime > currentTime) { $? ". new second"
+ currentTime = newTime;
+ res = clockData.setTime(&currentTime);
+ if(1 == res) { $? ". now in alert state"
+ bHaveBuffer = true;
+ bIsHidden = false;
+ Show(true);
+ Iconize(false);
+ Maximize(true);
+ Raise();
+ clv->SetMustUpdate();
+ clv->Refresh();
+ clv->Update();
+ } else { $? ". state unchanged"
+ if((IsIconized()) || (bIsHidden)) { $? ". iconized"
+ if(bHaveBuffer) { $? ". first time iconized"
+ bHaveBuffer = false;
+ clv->releaseBuffer();
+ }
+ } else { $? ". not iconized"
+ bHaveBuffer = true; $? ". refresh view"
+ clv->SetMustUpdate();
+ clv->Refresh();
+ clv->Update();
+ }
+ }
+ }
+ }
+ pcTimer.endProcessing();
+ } $? "- DkClockFrame::OnTimer"
+}
+
+
+
+void
+DkClockFrame::OnHide(wxCommandEvent & event)
+{
+ $? "+ DkClockFrame::OnHide"
+ if(miOptionsHide->IsChecked()) {
+ bShouldHide = true;
+ bIsHidden = true;
+ Show(false);
+ } else {
+ bShouldHide = false;
+ }
+ $? "- DkClockFrame::OnHide"
+}
+
+
+
+void
+DkClockFrame::OnColourNormal(wxCommandEvent & event)
+{
+ wxColourData wxcd;
+ wxcd.SetColour(
+ wxColour(
+ clv->getNormalRed(),
+ clv->getNormalGreen(),
+ clv->getNormalBlue()
+ )
+ );
+ wxColourDialog dlg(this, &wxcd);
+ pHelper->setRelatedPosition(this, &dlg, &cdx, &cdy);
+ if(dlg.ShowModal() == wxID_OK) {
+ wxColour c = dlg.GetColourData().GetColour();
+ clv->setNormal(c.Red(), c.Green(), c.Blue());
+ saveSettings();
+ }
+ dlg.GetPosition(&cdx, &cdy);
+}
+
+
+
+void
+DkClockFrame::OnColourAlert(wxCommandEvent & event)
+{
+ wxColourData wxcd;
+ wxcd.SetColour(
+ wxColour(
+ clv->getAlertRed(),
+ clv->getAlertGreen(),
+ clv->getAlertBlue()
+ )
+ );
+ wxColourDialog dlg(this, &wxcd);
+ pHelper->setRelatedPosition(this, &dlg, &cdx, &cdy);
+ if(dlg.ShowModal() == wxID_OK) {
+ wxColour c = dlg.GetColourData().GetColour();
+ clv->setAlert(c.Red(), c.Green(), c.Blue());
+ saveSettings();
+ }
+ dlg.GetPosition(&cdx, &cdy);
+}
+
+
+
+void
+DkClockFrame::SetHidden(bool b)
+{
+ $? "+ DkClockFrame::SetHidden %d", ((b) ? 1 : 0)
+ bIsHidden = b;
+ $? "- DkClockFrame::SetHidden"
+}
+
+
+
+void
+DkClockFrame::OnIconize(wxIconizeEvent & event)
+{
+#if wxCHECK_VERSION(3,0,0)
+ if(event.IsIconized())
+#else
+ if(event.Iconized())
+#endif
+ {
+ if(bShouldHide) {
+ if(NULL != iconTb) {
+ bIsHidden = true;
+ Show(false);
+ }
+ }
+ }
+}
+
+
diff --git a/support/dktools/DkClockOptionsDialog.cpp b/support/dktools/DkClockOptionsDialog.cpp
new file mode 100644
index 0000000000..c26ee021ea
--- /dev/null
+++ b/support/dktools/DkClockOptionsDialog.cpp
@@ -0,0 +1,353 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkClockOptionsDialog.wxc
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkClockOptionsDialog.cpp The DkClockOptionsDialog module.
+*/
+
+
+#line 124 "DkClockOptionsDialog.wxc"
+
+#include "wxdkclock.h"
+
+
+
+
+#line 129 "DkClockOptionsDialog.wxc"
+
+
+BEGIN_EVENT_TABLE(DkClockOptionsDialog, wxDialog)
+ EVT_BUTTON(wxID_OK, DkClockOptionsDialog::OnOk)
+ EVT_BUTTON(wxID_CANCEL, DkClockOptionsDialog::OnCancel)
+ EVT_CHECKBOX(DkClockOptions_Enable, DkClockOptionsDialog::OnCheckbox)
+END_EVENT_TABLE()
+
+
+
+
+#line 140 "DkClockOptionsDialog.wxc"
+DkClockOptionsDialog::DkClockOptionsDialog(
+ DkWxFrame *parent,
+ wxChar const *title,
+ wxChar const * const *messageTexts,
+ DkClockData *clockData
+) : wxDialog(
+ parent,
+ wxID_ANY,
+ title,
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxDEFAULT_DIALOG_STYLE
+)
+{
+ int en = 0;
+ int h = 0;
+ int m = 0;
+
+
+#line 158 "DkClockOptionsDialog.wxc"
+ sTexts = messageTexts;
+ cld = clockData;
+ dkctGUILayoutOK = false;
+ sDialog = NULL;
+ vSizer = NULL;
+ cSizer = NULL;
+ bSizer = NULL;
+ cbAlert = NULL;
+ tHour = NULL;
+ scHour = NULL;
+ tMinute = NULL;
+ scMinute = NULL;
+ bOK = NULL;
+ bCancel = NULL;
+ sDialog = new wxBoxSizer(
+ wxHORIZONTAL
+ );
+ if(!(sDialog)) {
+ goto dkctGUILayoutFinished;
+ }
+ sDialog->Add(10, 10, 1);
+ vSizer = new wxBoxSizer(
+ wxVERTICAL
+ );
+ if(!(vSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ vSizer->Add(10, 10, 1);
+ cSizer = new wxGridBagSizer(
+ 5, 5
+ );
+ if(!(cSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ cbAlert = new wxCheckBox(
+ this,
+ DkClockOptions_Enable,
+ sTexts[8]
+ );
+ if(!(cbAlert)) {
+ goto dkctGUILayoutFinished;
+ }
+ cbAlert->SetToolTip(sTexts[23]);
+ cSizer->Add(
+ cbAlert,
+ wxGBPosition(0, 0),
+ wxGBSpan(1, 2)
+ );
+ tHour = new wxStaticText(
+ this,
+ wxID_ANY,
+ sTexts[22]
+ );
+ if(!(tHour)) {
+ goto dkctGUILayoutFinished;
+ }
+ cSizer->Add(
+ tHour,
+ wxGBPosition(1, 0),
+ wxGBSpan(1, 1),
+ wxALIGN_RIGHT
+ );
+ scHour = new wxSpinCtrl(
+ this,
+ wxID_ANY,
+ wxEmptyString,
+ wxDefaultPosition,
+ wxDefaultSize,
+ 0,
+ 0,
+ 23
+ );
+ if(!(scHour)) {
+ goto dkctGUILayoutFinished;
+ }
+ scHour->SetToolTip(sTexts[24]);
+ cSizer->Add(
+ scHour,
+ wxGBPosition(1, 1),
+ wxGBSpan(1, 1),
+ wxALIGN_LEFT
+ );
+ tMinute = new wxStaticText(
+ this,
+ wxID_ANY,
+ sTexts[21]
+ );
+ if(!(tMinute)) {
+ goto dkctGUILayoutFinished;
+ }
+ cSizer->Add(
+ tMinute,
+ wxGBPosition(2, 0),
+ wxGBSpan(1, 1),
+ wxALIGN_RIGHT
+ );
+ scMinute = new wxSpinCtrl(
+ this,
+ wxID_ANY,
+ wxEmptyString,
+ wxDefaultPosition,
+ wxDefaultSize,
+ 0,
+ 0,
+ 59
+ );
+ if(!(scMinute)) {
+ goto dkctGUILayoutFinished;
+ }
+ scMinute->SetToolTip(sTexts[25]);
+ cSizer->Add(
+ scMinute,
+ wxGBPosition(2, 1),
+ wxGBSpan(1, 1),
+ wxALIGN_LEFT
+ );
+ vSizer->Add(
+ cSizer,
+ 0,
+ wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL
+ );
+ vSizer->Add(10, 10, 1);
+ bSizer = new wxStdDialogButtonSizer(
+ );
+ if(!(bSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ bOK = new wxButton(
+ this,
+ wxID_OK,
+ sTexts[17]
+ );
+ if(!(bOK)) {
+ goto dkctGUILayoutFinished;
+ }
+ bOK->SetToolTip(sTexts[18]);
+ bSizer->AddButton(
+ bOK
+ );
+ bCancel = new wxButton(
+ this,
+ wxID_CANCEL,
+ sTexts[19]
+ );
+ if(!(bCancel)) {
+ goto dkctGUILayoutFinished;
+ }
+ bCancel->SetToolTip(sTexts[20]);
+ bSizer->AddButton(
+ bCancel
+ );
+ bSizer->Realize();
+ vSizer->Add(
+ bSizer,
+ 0,
+ wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL
+ );
+ vSizer->Add(10, 10, 1);
+ sDialog->Add(
+ vSizer
+ );
+ sDialog->Add(10, 10, 1);
+ SetSizer(sDialog);
+ dkctGUILayoutOK = true;
+ dkctGUILayoutFinished:
+ if(dkctGUILayoutOK) {
+ sDialog->Fit(this);
+ sDialog->SetSizeHints(this);
+ }
+
+#line 161 "DkClockOptionsDialog.wxc"
+ if(dkctGUILayoutOK) {
+
+#line 162 "DkClockOptionsDialog.wxc"
+ cld->getAlertData(&en, &h, &m);
+
+
+#line 164 "DkClockOptionsDialog.wxc"
+ scHour->SetValue(h);
+ scMinute->SetValue(m);
+ if(en) {
+
+#line 167 "DkClockOptionsDialog.wxc"
+ cbAlert->SetValue(true);
+ scHour->Enable(true);
+ scMinute->Enable(true);
+ } else {
+
+#line 171 "DkClockOptionsDialog.wxc"
+ cbAlert->SetValue(false);
+ scHour->Enable(false);
+ scMinute->Enable(false);
+ }
+ }
+
+#line 176 "DkClockOptionsDialog.wxc"
+}
+
+
+
+#line 180 "DkClockOptionsDialog.wxc"
+
+
+void
+DkClockOptionsDialog::OnOk(wxCommandEvent & event)
+{
+ bool en = false;
+ int h = 0;
+ int m = 0;
+
+
+#line 189 "DkClockOptionsDialog.wxc"
+ if(cbAlert->GetValue()) {
+ en = true;
+ h = scHour->GetValue();
+ m = scMinute->GetValue();
+ }
+ cld->setAlert(en, h, m);
+ cld->endAlert();
+ if(IsModal()) {
+ EndModal(wxID_OK);
+ } else {
+ SetReturnCode(wxID_OK);
+ Show(false);
+ }
+
+#line 202 "DkClockOptionsDialog.wxc"
+}
+
+
+
+void
+DkClockOptionsDialog::OnCancel(wxCommandEvent & event)
+{
+
+
+#line 210 "DkClockOptionsDialog.wxc"
+ if(IsModal()) {
+ EndModal(wxID_CANCEL);
+ } else {
+ SetReturnCode(wxID_CANCEL);
+ Show(false);
+ }
+
+#line 216 "DkClockOptionsDialog.wxc"
+}
+
+
+
+void
+DkClockOptionsDialog::OnCheckbox(wxCommandEvent & event)
+{
+
+
+#line 224 "DkClockOptionsDialog.wxc"
+ if(cbAlert->GetValue()) {
+
+#line 225 "DkClockOptionsDialog.wxc"
+ scHour->Enable(true);
+ scMinute->Enable(true);
+ } else {
+
+#line 228 "DkClockOptionsDialog.wxc"
+ scHour->Enable(false);
+ scMinute->Enable(false);
+ }
+ Refresh();
+ Update();
+
+
+#line 234 "DkClockOptionsDialog.wxc"
+}
+
+
diff --git a/support/dktools/DkClockOptionsDialog.h b/support/dktools/DkClockOptionsDialog.h
new file mode 100644
index 0000000000..8df1dc5aba
--- /dev/null
+++ b/support/dktools/DkClockOptionsDialog.h
@@ -0,0 +1,158 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkClockOptionsDialog.wxc
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkClockOptionsDialog.h Header file for the DkClockOptionsDialog module.
+*/
+
+#ifndef DKCLOCKOPTIONSDIALOG_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DKCLOCKOPTIONSDIALOG_H_INCLUDED 1
+
+
+#line 73 "DkClockOptionsDialog.wxc"
+
+
+#line 75 "DkClockOptionsDialog.wxc"
+class DkClockOptionsDialog : public wxDialog
+{
+ private:
+
+ /** Event table.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ /** Localized texts.
+ */
+ wxChar const * const *sTexts;
+
+ /** Data set to configure.
+ */
+ DkClockData *cld;
+
+ /** Flag: GUI ok.
+ */
+ bool dkctGUILayoutOK;
+
+ /** GUI element sDialog.
+ */
+#line 13 "DkClockOptionsDialog.wxc"
+ wxBoxSizer *sDialog;
+
+ /** GUI element vSizer.
+ */
+#line 19 "DkClockOptionsDialog.wxc"
+ wxBoxSizer *vSizer;
+
+ /** GUI element cSizer.
+ */
+#line 27 "DkClockOptionsDialog.wxc"
+ wxGridBagSizer *cSizer;
+
+ /** GUI element bSizer.
+ */
+#line 56 "DkClockOptionsDialog.wxc"
+ wxStdDialogButtonSizer *bSizer;
+
+ /** GUI element cbAlert.
+ */
+#line 35 "DkClockOptionsDialog.wxc"
+ wxCheckBox *cbAlert;
+
+ /** GUI element tHour.
+ */
+#line 40 "DkClockOptionsDialog.wxc"
+ wxStaticText *tHour;
+
+ /** GUI element scHour.
+ */
+#line 43 "DkClockOptionsDialog.wxc"
+ wxSpinCtrl *scHour;
+
+ /** GUI element tMinute.
+ */
+#line 48 "DkClockOptionsDialog.wxc"
+ wxStaticText *tMinute;
+
+ /** GUI element scMinute.
+ */
+#line 51 "DkClockOptionsDialog.wxc"
+ wxSpinCtrl *scMinute;
+
+ /** GUI element bOK.
+ */
+#line 60 "DkClockOptionsDialog.wxc"
+ wxButton *bOK;
+
+ /** GUI element bCancel.
+ */
+#line 65 "DkClockOptionsDialog.wxc"
+ wxButton *bCancel;
+
+
+#line 94 "DkClockOptionsDialog.wxc"
+
+ public:
+
+ DkClockOptionsDialog(
+ DkWxFrame *parent,
+ wxChar const *title,
+ wxChar const * const *messageTexts,
+ DkClockData *clockData
+ );
+
+ /** Handler for OK button.
+ @param event Event to process.
+ */
+ void
+ OnOk(wxCommandEvent & WXUNUSED(event));
+
+ /** Handler for Cancel button.
+ @param event Event to process.
+ */
+ void
+ OnCancel(wxCommandEvent & WXUNUSED(event));
+
+ void
+ OnCheckbox(wxCommandEvent & event);
+
+};
+
+
+#line 122 "DkClockOptionsDialog.wxc"
+
+
+#endif
diff --git a/support/dktools/DkClockOptionsDialog.wxc b/support/dktools/DkClockOptionsDialog.wxc
new file mode 100644
index 0000000000..c27b44feab
--- /dev/null
+++ b/support/dktools/DkClockOptionsDialog.wxc
@@ -0,0 +1,236 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2013-xxxx
+license = bsd
+
+
+%% wx-gui
+
+type = dialog
+contents = sDialog
+
+[wxBoxSizer sDialog]
+direction = horizontal
+contents = $stretch(10)
+contents = vSizer
+contents = $stretch(10)
+
+[wxBoxSizer vSizer]
+direction = vertical
+contents = $stretch(10)
+contents = cSizer centered
+contents = $stretch(10)
+contents = bSizer centered
+contents = $stretch(10)
+
+[wxGridBagSizer cSizer]
+grid = 5 5
+contents = cbAlert 0 0 1 2
+contents = tHour +1 0 1 1 right
+contents = scHour . +1 1 1 left
+contents = tMinute +1 0 1 1 right
+contents = scMinute . +1 1 1 left
+
+[wxCheckBox cbAlert]
+text = sTexts[8]
+tip = sTexts[23]
+id = DkClockOptions_Enable
+
+[wxStaticText tHour]
+text = sTexts[22]
+
+[wxSpinCtrl scHour]
+range = 0 23
+value = 0
+tip = sTexts[24]
+
+[wxStaticText tMinute]
+text = sTexts[21]
+
+[wxSpinCtrl scMinute]
+range = 0 59
+value = 0
+tip = sTexts[25]
+
+[wxStdDialogButtonSizer bSizer]
+contents = bOK
+contents = bCancel
+
+[wxButton bOK]
+id = wxID_OK
+text = sTexts[17]
+tip = sTexts[18]
+
+[wxButton bCancel]
+id = wxID_CANCEL
+text = sTexts[19]
+tip = sTexts[20]
+
+
+
+%% header start
+
+%% class start
+class DkClockOptionsDialog : public wxDialog
+{
+ private:
+
+ /** Event table.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ /** Localized texts.
+ */
+ wxChar const * const *sTexts;
+
+ /** Data set to configure.
+ */
+ DkClockData *cld;
+
+%% class end
+
+ public:
+
+ DkClockOptionsDialog(
+ DkWxFrame *parent,
+ wxChar const *title,
+ wxChar const * const *messageTexts,
+ DkClockData *clockData
+ );
+
+ /** Handler for OK button.
+ @param event Event to process.
+ */
+ void
+ OnOk(wxCommandEvent & WXUNUSED(event));
+
+ /** Handler for Cancel button.
+ @param event Event to process.
+ */
+ void
+ OnCancel(wxCommandEvent & WXUNUSED(event));
+
+ void
+ OnCheckbox(wxCommandEvent & event);
+
+};
+
+%% header end
+
+%% module start
+
+#include "wxdkclock.h"
+
+
+$!trace-include
+
+
+BEGIN_EVENT_TABLE(DkClockOptionsDialog, wxDialog)
+ EVT_BUTTON(wxID_OK, DkClockOptionsDialog::OnOk)
+ EVT_BUTTON(wxID_CANCEL, DkClockOptionsDialog::OnCancel)
+ EVT_CHECKBOX(DkClockOptions_Enable, DkClockOptionsDialog::OnCheckbox)
+END_EVENT_TABLE()
+
+
+
+%% constructor start
+DkClockOptionsDialog::DkClockOptionsDialog(
+ DkWxFrame *parent,
+ wxChar const *title,
+ wxChar const * const *messageTexts,
+ DkClockData *clockData
+) : wxDialog(
+ parent,
+ wxID_ANY,
+ title,
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxDEFAULT_DIALOG_STYLE
+)
+{
+ int en = 0;
+ int h = 0;
+ int m = 0;
+ $? "+ DkClockOptionsDialog::DkClockOptionsDialog"
+ sTexts = messageTexts;
+ cld = clockData;
+%% constructor end
+ if(dkctGUILayoutOK) { $? ". GUI layout ok"
+ cld->getAlertData(&en, &h, &m);
+ $? ". en=%d h=%d m=%d", en, h, m
+ scHour->SetValue(h);
+ scMinute->SetValue(m);
+ if(en) { $? ". alert enabled"
+ cbAlert->SetValue(true);
+ scHour->Enable(true);
+ scMinute->Enable(true);
+ } else { $? ". alert not enabled"
+ cbAlert->SetValue(false);
+ scHour->Enable(false);
+ scMinute->Enable(false);
+ }
+ } $? "- DkClockOptionsDialog::DkClockOptionsDialog"
+}
+
+
+%% module end
+
+
+void
+DkClockOptionsDialog::OnOk(wxCommandEvent & event)
+{
+ bool en = false;
+ int h = 0;
+ int m = 0;
+ $? "+ DkClockOptionsDialog::OnOk"
+ if(cbAlert->GetValue()) {
+ en = true;
+ h = scHour->GetValue();
+ m = scMinute->GetValue();
+ }
+ cld->setAlert(en, h, m);
+ cld->endAlert();
+ if(IsModal()) {
+ EndModal(wxID_OK);
+ } else {
+ SetReturnCode(wxID_OK);
+ Show(false);
+ } $? "- DkClockOptionsDialog::OnOk"
+}
+
+
+
+void
+DkClockOptionsDialog::OnCancel(wxCommandEvent & event)
+{
+ $? "+ DkClockOptionsDialog::OnCancel"
+ if(IsModal()) {
+ EndModal(wxID_CANCEL);
+ } else {
+ SetReturnCode(wxID_CANCEL);
+ Show(false);
+ } $? "- DkClockOptionsDialog::OnCancel"
+}
+
+
+
+void
+DkClockOptionsDialog::OnCheckbox(wxCommandEvent & event)
+{
+ $? "+ DkClockOptionsDialog::OnCheckbox"
+ if(cbAlert->GetValue()) { $? ". checkbox enabled"
+ scHour->Enable(true);
+ scMinute->Enable(true);
+ } else { $? ". checkbox disabled"
+ scHour->Enable(false);
+ scMinute->Enable(false);
+ }
+ Refresh();
+ Update();
+ $? "- DkClockOptionsDialog::OnCheckbox"
+}
+
+
diff --git a/support/dktools/DkClockTaskbarIcon.cpp b/support/dktools/DkClockTaskbarIcon.cpp
new file mode 100644
index 0000000000..4f94fc00b1
--- /dev/null
+++ b/support/dktools/DkClockTaskbarIcon.cpp
@@ -0,0 +1,149 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkClockTaskbarIcon.cpt
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkClockTaskbarIcon.cpp The DkClockTaskbarIcon module.
+*/
+
+
+#line 65 "DkClockTaskbarIcon.cpt"
+
+
+#include "wxdkclock.h"
+
+
+
+
+
+#line 72 "DkClockTaskbarIcon.cpt"
+
+
+
+BEGIN_EVENT_TABLE(DkClockTaskbarIcon, wxTaskBarIcon)
+ EVT_TASKBAR_LEFT_DCLICK(DkClockTaskbarIcon::OnLeftButtonDoubleClick)
+ EVT_MENU(DkClockTaskBar_Restore, DkClockTaskbarIcon::OnMenuRestore)
+ EVT_MENU(DkClockTaskBar_Exit, DkClockTaskbarIcon::OnMenuExit)
+END_EVENT_TABLE()
+
+
+
+DkClockTaskbarIcon::DkClockTaskbarIcon(
+ wxFrame *pParent,
+ wxChar const * const *localizedTexts
+#if defined(__WXCOCOA__)
+ , wxTaskBarIconType iconType
+#endif
+)
+#if defined(__WXCOCOA__)
+: wxTaskBarIcon(iconType)
+#endif
+{
+
+
+#line 95 "DkClockTaskbarIcon.cpt"
+ wParent = pParent;
+ sTexts = localizedTexts;
+
+
+#line 98 "DkClockTaskbarIcon.cpt"
+}
+
+
+
+void
+DkClockTaskbarIcon::OnLeftButtonDoubleClick(wxTaskBarIconEvent & event)
+{
+
+
+#line 106 "DkClockTaskbarIcon.cpt"
+ if(wParent) {
+ ((DkClockFrame *)wParent)->SetHidden(false);
+ wParent->Iconize(false);
+ wParent->Show(true);
+ }
+
+#line 111 "DkClockTaskbarIcon.cpt"
+}
+
+
+
+void
+DkClockTaskbarIcon::OnMenuRestore(wxCommandEvent & event)
+{
+
+
+#line 119 "DkClockTaskbarIcon.cpt"
+ if(wParent) {
+ ((DkClockFrame *)wParent)->SetHidden(false);
+ wParent->Iconize(false);
+ wParent->Show(true);
+ }
+
+#line 124 "DkClockTaskbarIcon.cpt"
+}
+
+
+
+void
+DkClockTaskbarIcon::OnMenuExit(wxCommandEvent & event)
+{
+
+
+#line 132 "DkClockTaskbarIcon.cpt"
+ if(wParent) {
+ wParent->Close(true);
+ }
+
+#line 135 "DkClockTaskbarIcon.cpt"
+}
+
+
+
+wxMenu *
+DkClockTaskbarIcon::CreatePopupMenu()
+{
+ wxMenu *back = new wxMenu;
+
+
+#line 144 "DkClockTaskbarIcon.cpt"
+ if(back) {
+ back->Append(DkClockTaskBar_Restore, sTexts[26]);
+ back->Append(DkClockTaskBar_Exit, sTexts[27]);
+ }
+
+#line 148 "DkClockTaskbarIcon.cpt"
+ return back;
+}
+
+
diff --git a/support/dktools/DkClockTaskbarIcon.cpt b/support/dktools/DkClockTaskbarIcon.cpt
new file mode 100644
index 0000000000..fba2474ddc
--- /dev/null
+++ b/support/dktools/DkClockTaskbarIcon.cpt
@@ -0,0 +1,151 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2013-xxxx
+license = bsd
+
+
+
+%% header
+
+class DkClockTaskbarIcon : public wxTaskBarIcon
+{
+ private:
+
+ /** Localized texts.
+ */
+ wxChar const * const *sTexts;
+
+ /** Parent window.
+ */
+ wxFrame *wParent;
+
+ public:
+
+ /** Constructor.
+ @param pParent Parent window.
+ @param localizedTexts Localized texts.
+ */
+ DkClockTaskbarIcon(
+ wxFrame *pParent,
+ wxChar const * const *localizedTexts
+#if defined(__WXCOCOA__)
+ , wxTaskBarIconType iconType = DEFAULT_TYPE
+#endif
+ );
+
+ /** Handler for double-click on taskbar icon.
+ */
+ void
+ OnLeftButtonDoubleClick(wxTaskBarIconEvent & event);
+
+ /** Handler for menu item to restore window.
+ */
+ void
+ OnMenuRestore(wxCommandEvent & event);
+
+ /** Handler for menu item to exit application.
+ */
+ void
+ OnMenuExit(wxCommandEvent & event);
+
+ /** Create popup menu for taskbar icon.
+ @return The menu just created.
+ */
+ virtual
+ wxMenu *
+ CreatePopupMenu();
+
+ /** Event table for task bar icon.
+ */
+ DECLARE_EVENT_TABLE()
+};
+
+%% module
+
+
+#include "wxdkclock.h"
+
+
+
+$!trace-include
+
+
+
+BEGIN_EVENT_TABLE(DkClockTaskbarIcon, wxTaskBarIcon)
+ EVT_TASKBAR_LEFT_DCLICK(DkClockTaskbarIcon::OnLeftButtonDoubleClick)
+ EVT_MENU(DkClockTaskBar_Restore, DkClockTaskbarIcon::OnMenuRestore)
+ EVT_MENU(DkClockTaskBar_Exit, DkClockTaskbarIcon::OnMenuExit)
+END_EVENT_TABLE()
+
+
+
+DkClockTaskbarIcon::DkClockTaskbarIcon(
+ wxFrame *pParent,
+ wxChar const * const *localizedTexts
+#if defined(__WXCOCOA__)
+ , wxTaskBarIconType iconType
+#endif
+)
+#if defined(__WXCOCOA__)
+: wxTaskBarIcon(iconType)
+#endif
+{
+ $? "+ DkClockTaskbarIcon::DkClockTaskbarIcon"
+ wParent = pParent;
+ sTexts = localizedTexts;
+ $? "- DkClockTaskbarIcon::DkClockTaskbarIcon"
+}
+
+
+
+void
+DkClockTaskbarIcon::OnLeftButtonDoubleClick(wxTaskBarIconEvent & event)
+{
+ $? "+ DkClockTaskbarIcon::OnLeftButtonDoubleClick"
+ if(wParent) {
+ ((DkClockFrame *)wParent)->SetHidden(false);
+ wParent->Iconize(false);
+ wParent->Show(true);
+ } $? "- DkClockTaskbarIcon::OnLeftButtonDoubleClick"
+}
+
+
+
+void
+DkClockTaskbarIcon::OnMenuRestore(wxCommandEvent & event)
+{
+ $? "+ DkClockTaskbarIcon::OnMenuRestore"
+ if(wParent) {
+ ((DkClockFrame *)wParent)->SetHidden(false);
+ wParent->Iconize(false);
+ wParent->Show(true);
+ } $? "- DkClockTaskbarIcon::OnMenuRestore"
+}
+
+
+
+void
+DkClockTaskbarIcon::OnMenuExit(wxCommandEvent & event)
+{
+ $? "+ DkClockTaskbarIcon::OnMenuExit"
+ if(wParent) {
+ wParent->Close(true);
+ } $? "- DkClockTaskbarIcon::OnMenuExit"
+}
+
+
+
+wxMenu *
+DkClockTaskbarIcon::CreatePopupMenu()
+{
+ wxMenu *back = new wxMenu;
+ $? "+ DkClockTaskbarIcon::CreatePopupMenu"
+ if(back) {
+ back->Append(DkClockTaskBar_Restore, sTexts[26]);
+ back->Append(DkClockTaskBar_Exit, sTexts[27]);
+ } $? "- DkClockTaskbarIcon::CreatePopupMenu PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
diff --git a/support/dktools/DkClockTaskbarIcon.h b/support/dktools/DkClockTaskbarIcon.h
new file mode 100644
index 0000000000..24c3bbcc8e
--- /dev/null
+++ b/support/dktools/DkClockTaskbarIcon.h
@@ -0,0 +1,100 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkClockTaskbarIcon.cpt
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkClockTaskbarIcon.h Header file for the DkClockTaskbarIcon module.
+*/
+
+#ifndef DKCLOCKTASKBARICON_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DKCLOCKTASKBARICON_H_INCLUDED 1
+
+
+#line 10 "DkClockTaskbarIcon.cpt"
+
+class DkClockTaskbarIcon : public wxTaskBarIcon
+{
+ private:
+
+ /** Localized texts.
+ */
+ wxChar const * const *sTexts;
+
+ /** Parent window.
+ */
+ wxFrame *wParent;
+
+ public:
+
+ /** Constructor.
+ @param pParent Parent window.
+ @param localizedTexts Localized texts.
+ */
+ DkClockTaskbarIcon(
+ wxFrame *pParent,
+ wxChar const * const *localizedTexts
+#if defined(__WXCOCOA__)
+ , wxTaskBarIconType iconType = DEFAULT_TYPE
+#endif
+ );
+
+ /** Handler for double-click on taskbar icon.
+ */
+ void
+ OnLeftButtonDoubleClick(wxTaskBarIconEvent & event);
+
+ /** Handler for menu item to restore window.
+ */
+ void
+ OnMenuRestore(wxCommandEvent & event);
+
+ /** Handler for menu item to exit application.
+ */
+ void
+ OnMenuExit(wxCommandEvent & event);
+
+ /** Create popup menu for taskbar icon.
+ @return The menu just created.
+ */
+ virtual
+ wxMenu *
+ CreatePopupMenu();
+
+ /** Event table for task bar icon.
+ */
+ DECLARE_EVENT_TABLE()
+};
+
+
+#endif
diff --git a/support/dktools/DkClockView.cpp b/support/dktools/DkClockView.cpp
new file mode 100644
index 0000000000..9c694cc37f
--- /dev/null
+++ b/support/dktools/DkClockView.cpp
@@ -0,0 +1,376 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkClockView.cpt
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkClockView.cpp The DkClockView module.
+*/
+
+
+#line 161 "DkClockView.cpt"
+
+
+#include "wxdkclock.h"
+
+
+
+
+#line 167 "DkClockView.cpt"
+
+IMPLEMENT_DYNAMIC_CLASS(DkClockView, DkWxBufferedControl)
+
+/** Event handler table.
+*/
+BEGIN_EVENT_TABLE(DkClockView, DkWxBufferedControl)
+ EVT_LEFT_DOWN(DkClockView::OnLeftDown)
+END_EVENT_TABLE()
+
+
+
+wxChar const DkClockView::windowtypename[] = { wxT("DkClockView") };
+
+
+
+DkClockView::DkClockView()
+:
+cBlack(0, 0, 0),
+#if defined(__WXMSW__)
+cRed(127, 0, 0)
+#else
+cRed(191, 0, 0)
+#endif
+{
+ bUseRed = false;
+ cld = NULL;
+}
+
+
+
+DkClockView::DkClockView(
+ wxWindow *wParent,
+ wxWindowID wid,
+ DkClockData *clockData,
+ const wxPoint & pos,
+ const wxSize & size,
+ long style
+) : DkWxBufferedControl(
+ wParent,
+ wid,
+ pos,
+ size,
+ (style | wxFULL_REPAINT_ON_RESIZE),
+ wxDefaultValidator,
+ wxString(windowtypename)
+),
+cBlack(0, 0, 0),
+#if defined(__WXMSW__)
+cRed(127, 0, 0)
+#else
+cRed(191, 0, 0)
+#endif
+{
+
+
+#line 221 "DkClockView.cpt"
+ bUseRed = false;
+ cld = clockData;
+
+
+#line 224 "DkClockView.cpt"
+}
+
+
+
+bool
+DkClockView::Create(
+ wxWindow *wParent,
+ wxWindowID wid,
+ DkClockData *clockData,
+ const wxPoint & pos,
+ const wxSize & size,
+ long style
+)
+{
+ bool back;
+ back = DkWxBufferedControl::Create(
+ wParent, wid, pos, size, (style | wxFULL_REPAINT_ON_RESIZE),
+ wxDefaultValidator, wxString(windowtypename)
+ );
+ bUseRed = false;
+ cld = clockData;
+ return back;
+}
+
+
+
+void
+DkClockView::PaintOperation(
+ wxDC & pdc, wxPaintEvent & event, bool buffered, int clWidth, int clHeight
+)
+{
+ clockview_data_t clvdata; /* Clock data. */
+ double alpha; /* Current angle in radians. */
+ int cx; /* Center x. */
+ int cy; /* Center y. */
+ int ro; /* Outer radius. */
+ int rd; /* Radius 5-minutes dot. */
+ int rc; /* Center points radius. */
+ int ri; /* Inner radius. */
+ int lw; /* Line width of minute dots. */
+ int r1; /* Inner radius minute dots. */
+ int r2; /* Outer radius minute dots. */
+ int rs; /* Radius seconds arrow. */
+ int rm; /* Radius minuts arrow. */
+ int rh; /* Radius hours arrow. */
+ int aw; /* Width minutes and hours. */
+ int i; /* Current index. */
+ int x; /* Current x. */
+ int y; /* Current y. */
+
+
+#line 274 "DkClockView.cpt"
+ pdc.SetBackground(*wxWHITE_BRUSH);
+ pdc.Clear();
+ cld->getData(&clvdata);
+ if(clvdata.a) {
+ bUseRed = ((bUseRed) ? false : true);
+ } else {
+ bUseRed = false;
+ }
+ cx = clWidth / 2;
+ cy = clHeight / 2;
+ ro = cx; if(cy < ro) { ro = cy; }
+ ro = (int)(0.95 * (double)ro);
+ rd = (int)(0.0497331 * (double)ro);
+ if(rd < 1) { rd = 1; }
+ rc = ro - rd;
+ if(rc < 0) { rc = 0; }
+ ri = ro - (2 * rd);
+ if(ri < 0) { ri = 0; }
+ lw = rd / 2;
+ if(lw < 1) { lw = 1; }
+ r1 = ri + (lw / 2);
+ r2 = ro - (lw / 2);
+ rs = ri - rd - (lw / 2);
+ if(rs < 1) { rs = 1; }
+ aw = rd;
+ rm = ri - (2 * rd) - (aw / 2);
+ if(rm < 1) { rm = 1; }
+ rh = (int)(0.75 * (double)rm);
+ if(rm < 1) { rh = 1; }
+ /*
+ 5-minute dots.
+ */
+ pdc.SetPen(*wxTRANSPARENT_PEN);
+ if(bUseRed) {
+ pdc.SetBrush(cRed);
+ } else {
+ pdc.SetBrush(cBlack);
+ }
+ for(i = 0; i < 12; i++) {
+ alpha = (2.0 * M_PI * (double)i) / 12.0;
+ x = cx + (int)((double)rc * cos(alpha));
+ y = cy + (int)((double)rc * sin(alpha));
+ pdc.DrawCircle(x, y, rd);
+ }
+ /*
+ Other minute ticks.
+ */
+ pdc.SetBrush(wxNullBrush);
+ if(bUseRed) {
+ pdc.SetPen(wxPen(cRed, lw));
+ } else{
+ pdc.SetPen(wxPen(cBlack, lw));
+ }
+ for(i = 0; i < 60; i++) {
+ if(i % 5) {
+ alpha = (2.0 * M_PI * (double)i) / 60.0;
+ pdc.DrawLine(
+ (cx + (int)((double)r1 * cos(alpha))),
+ (cy + (int)((double)r1 * sin(alpha))),
+ (cx + (int)((double)r2 * cos(alpha))),
+ (cy + (int)((double)r2 * sin(alpha)))
+ );
+ }
+ }
+ /*
+ Hours arrow.
+ */
+ pdc.SetBrush(wxNullBrush);
+ if(bUseRed) {
+ pdc.SetPen(wxPen(cRed, aw));
+ } else{
+ pdc.SetPen(wxPen(cBlack, aw));
+ }
+ alpha = M_PI_2 - ((4.0 * M_PI * (double)(clvdata.h)) / 24.0);
+ alpha = alpha - ((M_PI * (double)(clvdata.m)) / 360.0);
+ pdc.DrawLine(
+ cx, cy,
+ (cx + (int)((double)rh * cos(alpha))),
+ (cy - (int)((double)rh * sin(alpha)))
+ );
+ /*
+ Minutes arrow.
+ */
+ alpha = M_PI_2 - ((2.0 * M_PI * (double)(clvdata.m)) / 60.0);
+ pdc.DrawLine(
+ cx, cy,
+ (cx + (int)((double)rm * cos(alpha))),
+ (cy - (int)((double)rm * sin(alpha)))
+ );
+ /*
+ Seconds arrow.
+ */
+ pdc.SetBrush(wxNullBrush);
+ if(bUseRed) {
+ pdc.SetPen(wxPen(cRed, lw));
+ } else{
+ pdc.SetPen(wxPen(cBlack, lw));
+ }
+ alpha = M_PI_2 - ((2.0 * M_PI * (int)(clvdata.s)) / 60.0);
+ pdc.DrawLine(
+ cx, cy,
+ (cx + (int)((double)rs * cos(alpha))),
+ (cy - (int)((double)rs * sin(alpha)))
+ );
+ /*
+ Before leaving the function choose stock objects.
+ */
+ pdc.SetBrush(wxNullBrush);
+ pdc.SetBackground(wxNullBrush);
+ pdc.SetPen(wxNullPen);
+
+
+#line 385 "DkClockView.cpt"
+}
+
+
+
+void
+DkClockView::OnLeftDown(wxMouseEvent & event)
+{
+
+
+#line 393 "DkClockView.cpt"
+ if(cld) {
+ cld->endAlert();
+ SetMustUpdate();
+ Refresh();
+ Update();
+ }
+
+#line 399 "DkClockView.cpt"
+}
+
+
+
+int
+DkClockView::getNormalRed(void) const
+{
+ int back;
+ back = cBlack.Red();
+ if(back < 0) { back = back + 256; }
+ return back;
+}
+
+
+
+int
+DkClockView::getNormalGreen(void) const
+{
+ int back;
+ back = cBlack.Green();
+ if(back < 0) { back = back + 256; }
+ return back;
+}
+
+
+
+int
+DkClockView::getNormalBlue(void) const
+{
+ int back;
+ back = cBlack.Blue();
+ if(back < 0) { back = back + 256; }
+ return back;
+}
+
+
+
+int
+DkClockView::getAlertRed(void) const
+{
+ int back;
+ back = cRed.Red();
+ if(back < 0) { back = back + 256; }
+ return back;
+}
+
+
+
+int
+DkClockView::getAlertGreen(void) const
+{
+ int back;
+ back = cRed.Green();
+ if(back < 0) { back = back + 256; }
+ return back;
+}
+
+
+
+int
+DkClockView::getAlertBlue(void) const
+{
+ int back;
+ back = cRed.Blue();
+ if(back < 0) { back = back + 256; }
+ return back;
+}
+
+
+
+void
+DkClockView::setNormal(int r, int g, int b)
+{
+ cBlack.Set((unsigned char)r, (unsigned char)g, (unsigned char)b);
+}
+
+
+
+void
+DkClockView::setAlert(int r, int g, int b)
+{
+ cRed.Set((unsigned char)r, (unsigned char)g, (unsigned char)b);
+}
+
diff --git a/support/dktools/DkClockView.cpt b/support/dktools/DkClockView.cpt
new file mode 100644
index 0000000000..8513233719
--- /dev/null
+++ b/support/dktools/DkClockView.cpt
@@ -0,0 +1,482 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2013-xxxx
+license = bsd
+
+
+
+%% header
+
+class DkClockView : public DkWxBufferedControl
+{
+ private:
+
+ DECLARE_DYNAMIC_CLASS(DkClockView)
+
+ /** Event table.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ /** Black colour for normal mode.
+ */
+ wxColour cBlack;
+
+ /** Red colour for alert mode.
+ */
+ wxColour cRed;
+
+ /** Clock data to show.
+ */
+ DkClockData *cld;
+
+ /** Widget type name.
+ */
+ static wxChar const windowtypename[];
+
+ /** Flag: Use red colour instead of black.
+ */
+ bool bUseRed;
+
+ public:
+
+ /** Default constructor.
+ */
+ DkClockView();
+
+ /** Constructor.
+ @param wParent Parent window.
+ @param wid Window ID.
+ @param clockData Clock data to show.
+ @param pos Window position.
+ @param size Window size.
+ @param style Window style.
+ */
+ DkClockView(
+ wxWindow *wParent,
+ wxWindowID wid,
+ DkClockData *clockData,
+ const wxPoint & pos = wxDefaultPosition,
+ const wxSize & size = wxDefaultSize,
+ long style = 0L
+ );
+
+ /** Create window after using the default constructor.
+ @param wParent Parent window.
+ @param wid Window ID.
+ @param clockData Clock data to show.
+ @param pos Window position.
+ @param size Window size.
+ @param style Window style.
+ @return true on success, false on error.
+ */
+ bool
+ Create(
+ wxWindow *wParent,
+ wxWindowID wid,
+ DkClockData *clockData,
+ const wxPoint & pos = wxDefaultPosition,
+ const wxSize & size = wxDefaultSize,
+ long style = 0L
+ );
+
+ /** Draw operation.
+ @param pdc Device context to draw to.
+ @param event Event to process.
+ @param buffered Flag: Drawing into bitmap buffer.
+ @param clWidth Client area width.
+ @param clHeight Client area height.
+ */
+ void
+ PaintOperation(
+ wxDC & pdc,
+ wxPaintEvent & event,
+ bool buffered,
+ int clWidth,
+ int clHeight
+ );
+
+ /** Handler for mouse click.
+ @param event Event to process.
+ */
+ void
+ OnLeftDown(wxMouseEvent & event);
+
+ /** Get red component of normal clock colour.
+ @return Red value.
+ */
+ int
+ getNormalRed(void) const;
+
+ /** Get green component of normal clock colour.
+ @return Green value.
+ */
+ int
+ getNormalGreen(void) const;
+
+ /** Get blue component of normal clock colour.
+ @return Blue value.
+ */
+ int
+ getNormalBlue(void) const;
+
+ /** Get red component of alert clock colour.
+ @return Red value.
+ */
+ int
+ getAlertRed(void) const;
+
+ /** Get green component of alert clock colour.
+ @return Green value.
+ */
+ int
+ getAlertGreen(void) const;
+
+ /** Get blue component of alert clock colour.
+ @return Blue value.
+ */
+ int
+ getAlertBlue(void) const;
+
+ /** Set normal colour.
+ @param r Red value.
+ @param g Green value.
+ @param b Blue value.
+ */
+ void
+ setNormal(int r, int g, int b);
+
+ /** Set alert colour.
+ @param r Red value.
+ @param g Green value.
+ @param b Blue value.
+ */
+ void
+ setAlert(int r, int g, int b);
+};
+
+%% module
+
+
+#include "wxdkclock.h"
+
+
+$!trace-include
+
+IMPLEMENT_DYNAMIC_CLASS(DkClockView, DkWxBufferedControl)
+
+/** Event handler table.
+*/
+BEGIN_EVENT_TABLE(DkClockView, DkWxBufferedControl)
+ EVT_LEFT_DOWN(DkClockView::OnLeftDown)
+END_EVENT_TABLE()
+
+
+
+wxChar const DkClockView::windowtypename[] = { wxT("DkClockView") };
+
+
+
+DkClockView::DkClockView()
+:
+cBlack(0, 0, 0),
+#if defined(__WXMSW__)
+cRed(127, 0, 0)
+#else
+cRed(191, 0, 0)
+#endif
+{
+ bUseRed = false;
+ cld = NULL;
+}
+
+
+
+DkClockView::DkClockView(
+ wxWindow *wParent,
+ wxWindowID wid,
+ DkClockData *clockData,
+ const wxPoint & pos,
+ const wxSize & size,
+ long style
+) : DkWxBufferedControl(
+ wParent,
+ wid,
+ pos,
+ size,
+ (style | wxFULL_REPAINT_ON_RESIZE),
+ wxDefaultValidator,
+ wxString(windowtypename)
+),
+cBlack(0, 0, 0),
+#if defined(__WXMSW__)
+cRed(127, 0, 0)
+#else
+cRed(191, 0, 0)
+#endif
+{
+ $? "+ DkClockView::DkClockView"
+ bUseRed = false;
+ cld = clockData;
+ $? "- DkClockView::DkClockView"
+}
+
+
+
+bool
+DkClockView::Create(
+ wxWindow *wParent,
+ wxWindowID wid,
+ DkClockData *clockData,
+ const wxPoint & pos,
+ const wxSize & size,
+ long style
+)
+{
+ bool back;
+ back = DkWxBufferedControl::Create(
+ wParent, wid, pos, size, (style | wxFULL_REPAINT_ON_RESIZE),
+ wxDefaultValidator, wxString(windowtypename)
+ );
+ bUseRed = false;
+ cld = clockData;
+ return back;
+}
+
+
+
+void
+DkClockView::PaintOperation(
+ wxDC & pdc, wxPaintEvent & event, bool buffered, int clWidth, int clHeight
+)
+{
+ clockview_data_t clvdata; /* Clock data. */
+ double alpha; /* Current angle in radians. */
+ int cx; /* Center x. */
+ int cy; /* Center y. */
+ int ro; /* Outer radius. */
+ int rd; /* Radius 5-minutes dot. */
+ int rc; /* Center points radius. */
+ int ri; /* Inner radius. */
+ int lw; /* Line width of minute dots. */
+ int r1; /* Inner radius minute dots. */
+ int r2; /* Outer radius minute dots. */
+ int rs; /* Radius seconds arrow. */
+ int rm; /* Radius minuts arrow. */
+ int rh; /* Radius hours arrow. */
+ int aw; /* Width minutes and hours. */
+ int i; /* Current index. */
+ int x; /* Current x. */
+ int y; /* Current y. */
+ $? "+ DkClockView::PaintOperation"
+ pdc.SetBackground(*wxWHITE_BRUSH);
+ pdc.Clear();
+ cld->getData(&clvdata);
+ if(clvdata.a) {
+ bUseRed = ((bUseRed) ? false : true);
+ } else {
+ bUseRed = false;
+ }
+ cx = clWidth / 2;
+ cy = clHeight / 2;
+ ro = cx; if(cy < ro) { ro = cy; }
+ ro = (int)(0.95 * (double)ro);
+ rd = (int)(0.0497331 * (double)ro);
+ if(rd < 1) { rd = 1; }
+ rc = ro - rd;
+ if(rc < 0) { rc = 0; }
+ ri = ro - (2 * rd);
+ if(ri < 0) { ri = 0; }
+ lw = rd / 2;
+ if(lw < 1) { lw = 1; }
+ r1 = ri + (lw / 2);
+ r2 = ro - (lw / 2);
+ rs = ri - rd - (lw / 2);
+ if(rs < 1) { rs = 1; }
+ aw = rd;
+ rm = ri - (2 * rd) - (aw / 2);
+ if(rm < 1) { rm = 1; }
+ rh = (int)(0.75 * (double)rm);
+ if(rm < 1) { rh = 1; }
+ /*
+ 5-minute dots.
+ */
+ pdc.SetPen(*wxTRANSPARENT_PEN);
+ if(bUseRed) {
+ pdc.SetBrush(cRed);
+ } else {
+ pdc.SetBrush(cBlack);
+ }
+ for(i = 0; i < 12; i++) {
+ alpha = (2.0 * M_PI * (double)i) / 12.0;
+ x = cx + (int)((double)rc * cos(alpha));
+ y = cy + (int)((double)rc * sin(alpha));
+ pdc.DrawCircle(x, y, rd);
+ }
+ /*
+ Other minute ticks.
+ */
+ pdc.SetBrush(wxNullBrush);
+ if(bUseRed) {
+ pdc.SetPen(wxPen(cRed, lw));
+ } else{
+ pdc.SetPen(wxPen(cBlack, lw));
+ }
+ for(i = 0; i < 60; i++) {
+ if(i % 5) {
+ alpha = (2.0 * M_PI * (double)i) / 60.0;
+ pdc.DrawLine(
+ (cx + (int)((double)r1 * cos(alpha))),
+ (cy + (int)((double)r1 * sin(alpha))),
+ (cx + (int)((double)r2 * cos(alpha))),
+ (cy + (int)((double)r2 * sin(alpha)))
+ );
+ }
+ }
+ /*
+ Hours arrow.
+ */
+ pdc.SetBrush(wxNullBrush);
+ if(bUseRed) {
+ pdc.SetPen(wxPen(cRed, aw));
+ } else{
+ pdc.SetPen(wxPen(cBlack, aw));
+ }
+ alpha = M_PI_2 - ((4.0 * M_PI * (double)(clvdata.h)) / 24.0);
+ alpha = alpha - ((M_PI * (double)(clvdata.m)) / 360.0);
+ pdc.DrawLine(
+ cx, cy,
+ (cx + (int)((double)rh * cos(alpha))),
+ (cy - (int)((double)rh * sin(alpha)))
+ );
+ /*
+ Minutes arrow.
+ */
+ alpha = M_PI_2 - ((2.0 * M_PI * (double)(clvdata.m)) / 60.0);
+ pdc.DrawLine(
+ cx, cy,
+ (cx + (int)((double)rm * cos(alpha))),
+ (cy - (int)((double)rm * sin(alpha)))
+ );
+ /*
+ Seconds arrow.
+ */
+ pdc.SetBrush(wxNullBrush);
+ if(bUseRed) {
+ pdc.SetPen(wxPen(cRed, lw));
+ } else{
+ pdc.SetPen(wxPen(cBlack, lw));
+ }
+ alpha = M_PI_2 - ((2.0 * M_PI * (int)(clvdata.s)) / 60.0);
+ pdc.DrawLine(
+ cx, cy,
+ (cx + (int)((double)rs * cos(alpha))),
+ (cy - (int)((double)rs * sin(alpha)))
+ );
+ /*
+ Before leaving the function choose stock objects.
+ */
+ pdc.SetBrush(wxNullBrush);
+ pdc.SetBackground(wxNullBrush);
+ pdc.SetPen(wxNullPen);
+ $? "- DkClockView::PaintOperation"
+}
+
+
+
+void
+DkClockView::OnLeftDown(wxMouseEvent & event)
+{
+ $? "+ DkClockView::OnLeftDown"
+ if(cld) {
+ cld->endAlert();
+ SetMustUpdate();
+ Refresh();
+ Update();
+ } $? "- DkClockView::OnLeftDown"
+}
+
+
+
+int
+DkClockView::getNormalRed(void) const
+{
+ int back;
+ back = cBlack.Red();
+ if(back < 0) { back = back + 256; }
+ return back;
+}
+
+
+
+int
+DkClockView::getNormalGreen(void) const
+{
+ int back;
+ back = cBlack.Green();
+ if(back < 0) { back = back + 256; }
+ return back;
+}
+
+
+
+int
+DkClockView::getNormalBlue(void) const
+{
+ int back;
+ back = cBlack.Blue();
+ if(back < 0) { back = back + 256; }
+ return back;
+}
+
+
+
+int
+DkClockView::getAlertRed(void) const
+{
+ int back;
+ back = cRed.Red();
+ if(back < 0) { back = back + 256; }
+ return back;
+}
+
+
+
+int
+DkClockView::getAlertGreen(void) const
+{
+ int back;
+ back = cRed.Green();
+ if(back < 0) { back = back + 256; }
+ return back;
+}
+
+
+
+int
+DkClockView::getAlertBlue(void) const
+{
+ int back;
+ back = cRed.Blue();
+ if(back < 0) { back = back + 256; }
+ return back;
+}
+
+
+
+void
+DkClockView::setNormal(int r, int g, int b)
+{
+ cBlack.Set((unsigned char)r, (unsigned char)g, (unsigned char)b);
+}
+
+
+
+void
+DkClockView::setAlert(int r, int g, int b)
+{
+ cRed.Set((unsigned char)r, (unsigned char)g, (unsigned char)b);
+}
+
diff --git a/support/dktools/DkClockView.h b/support/dktools/DkClockView.h
new file mode 100644
index 0000000000..4f503e0ca0
--- /dev/null
+++ b/support/dktools/DkClockView.h
@@ -0,0 +1,196 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkClockView.cpt
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkClockView.h Header file for the DkClockView module.
+*/
+
+#ifndef DKCLOCKVIEW_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DKCLOCKVIEW_H_INCLUDED 1
+
+
+#line 10 "DkClockView.cpt"
+
+class DkClockView : public DkWxBufferedControl
+{
+ private:
+
+ DECLARE_DYNAMIC_CLASS(DkClockView)
+
+ /** Event table.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ /** Black colour for normal mode.
+ */
+ wxColour cBlack;
+
+ /** Red colour for alert mode.
+ */
+ wxColour cRed;
+
+ /** Clock data to show.
+ */
+ DkClockData *cld;
+
+ /** Widget type name.
+ */
+ static wxChar const windowtypename[];
+
+ /** Flag: Use red colour instead of black.
+ */
+ bool bUseRed;
+
+ public:
+
+ /** Default constructor.
+ */
+ DkClockView();
+
+ /** Constructor.
+ @param wParent Parent window.
+ @param wid Window ID.
+ @param clockData Clock data to show.
+ @param pos Window position.
+ @param size Window size.
+ @param style Window style.
+ */
+ DkClockView(
+ wxWindow *wParent,
+ wxWindowID wid,
+ DkClockData *clockData,
+ const wxPoint & pos = wxDefaultPosition,
+ const wxSize & size = wxDefaultSize,
+ long style = 0L
+ );
+
+ /** Create window after using the default constructor.
+ @param wParent Parent window.
+ @param wid Window ID.
+ @param clockData Clock data to show.
+ @param pos Window position.
+ @param size Window size.
+ @param style Window style.
+ @return true on success, false on error.
+ */
+ bool
+ Create(
+ wxWindow *wParent,
+ wxWindowID wid,
+ DkClockData *clockData,
+ const wxPoint & pos = wxDefaultPosition,
+ const wxSize & size = wxDefaultSize,
+ long style = 0L
+ );
+
+ /** Draw operation.
+ @param pdc Device context to draw to.
+ @param event Event to process.
+ @param buffered Flag: Drawing into bitmap buffer.
+ @param clWidth Client area width.
+ @param clHeight Client area height.
+ */
+ void
+ PaintOperation(
+ wxDC & pdc,
+ wxPaintEvent & event,
+ bool buffered,
+ int clWidth,
+ int clHeight
+ );
+
+ /** Handler for mouse click.
+ @param event Event to process.
+ */
+ void
+ OnLeftDown(wxMouseEvent & event);
+
+ /** Get red component of normal clock colour.
+ @return Red value.
+ */
+ int
+ getNormalRed(void) const;
+
+ /** Get green component of normal clock colour.
+ @return Green value.
+ */
+ int
+ getNormalGreen(void) const;
+
+ /** Get blue component of normal clock colour.
+ @return Blue value.
+ */
+ int
+ getNormalBlue(void) const;
+
+ /** Get red component of alert clock colour.
+ @return Red value.
+ */
+ int
+ getAlertRed(void) const;
+
+ /** Get green component of alert clock colour.
+ @return Green value.
+ */
+ int
+ getAlertGreen(void) const;
+
+ /** Get blue component of alert clock colour.
+ @return Blue value.
+ */
+ int
+ getAlertBlue(void) const;
+
+ /** Set normal colour.
+ @param r Red value.
+ @param g Green value.
+ @param b Blue value.
+ */
+ void
+ setNormal(int r, int g, int b);
+
+ /** Set alert colour.
+ @param r Red value.
+ @param g Green value.
+ @param b Blue value.
+ */
+ void
+ setAlert(int r, int g, int b);
+};
+
+
+#endif
diff --git a/support/dktools/DkWxAppHelper.cpp b/support/dktools/DkWxAppHelper.cpp
new file mode 100644
index 0000000000..46e65d4b04
--- /dev/null
+++ b/support/dktools/DkWxAppHelper.cpp
@@ -0,0 +1,1403 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxAppHelper.cpt
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxAppHelper.cpp The DkWxAppHelper module.
+*/
+
+
+#line 334 "DkWxAppHelper.cpt"
+
+
+#include <dk3all.h>
+#include "DkWxAppHelper.h"
+
+
+#include "dk3wxs.h"
+
+
+
+
+
+#line 345 "DkWxAppHelper.cpt"
+
+
+
+/** Storage entry for wxChar string table.
+*/
+typedef struct {
+ wxChar const **array; /**< String table contents. */
+ dkChar const *name; /**< String table name. */
+ size_t nelem; /**< Number of elements. */
+} DkAppHelperWxStringTable;
+
+
+
+/** Pointer to constant wxChar string.
+*/
+typedef wxChar const *wxConstPtr;
+
+
+
+/** Error codes.
+*/
+enum {
+ /** No error occured.
+ */
+ ERROR_NONE = 0,
+
+ /** Failed to encode arg0 to dkChar.
+ */
+ ERROR_ENCODE_ARG0 ,
+};
+
+
+
+/** Basic texts issued by wxWidgets applications.
+*/
+static wxChar const * const dkwxapphelper_defwxappstr[] = {
+/* 0 */
+wxT("Error worse than Panic"),
+
+/* 1 */
+wxT("Panic"),
+
+/* 2 */
+wxT("Fatal error"),
+
+/* 3 */
+wxT("Error"),
+
+/* 4 */
+wxT("Warning"),
+
+/* 5 */
+wxT("Information"),
+
+/* 6 */
+wxT("Progress"),
+
+/* 7 */
+wxT("Debug"),
+
+/* 8 */
+wxT("Ignore"),
+
+/* 9 */
+wxT("Not enough memory!"),
+
+/* 10 */
+wxT("Help file not found!"),
+
+/* 11 */
+wxT("Failed to initialize application structure!"),
+
+/* 12 */
+wxT("Failed to recode command line!"),
+
+NULL
+
+
+#line 435 "DkWxAppHelper.cpt"
+};
+
+
+
+/** String table file containing localized versions of the
+ texts in \a dkwxapphelper_defwxappstr.
+*/
+static dkChar const dkwxapphelper_sttname[] = { dkT("dkwx.str") };
+
+
+
+/** Compare two string table entries.
+ @param l Left entry.
+ @param r Right entry.
+ @param cr Comparison criteria (0=entry/entry, 1=entr/name).
+ @return Comparison result.
+*/
+static
+int
+dkwxah_string_table_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ DkAppHelperWxStringTable const *pl;
+ DkAppHelperWxStringTable const *pr;
+ if(l) {
+ if(r) {
+ pl = (DkAppHelperWxStringTable const *)l;
+ pr = (DkAppHelperWxStringTable const *)r;
+ switch(cr) {
+ case 1: {
+ if(pl->name) {
+ back = dk3str_cmp(pl->name, (dkChar const *)r);
+ } else { back = -1; }
+ } break;
+ default: {
+ if(pl->name) {
+ if(pr->name) {
+ back = dk3str_cmp(pl->name, pr->name);
+ } else { back = 1;}
+ } else {
+ if(pr->name) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ if(back < -1) { back = -1; }
+ if(back > 1) { back = 1; }
+ return back;
+}
+
+
+
+/** Close string table.
+ @param p String table to close.
+*/
+static
+void
+dkwxah_string_table_close(DkAppHelperWxStringTable *p)
+{
+ wxChar const **ptr;
+ size_t i;
+
+
+#line 500 "DkWxAppHelper.cpt"
+ if(p) {
+ if(p->array) {
+ if(p->nelem) {
+
+#line 503 "DkWxAppHelper.cpt"
+ ptr = p->array;
+ for(i = 0; i < p->nelem; i++) {
+ if(*ptr) {
+
+#line 506 "DkWxAppHelper.cpt"
+ }
+ dk3_release(*ptr);
+ ptr++;
+ }
+ }
+ dk3_delete(p->array);
+ }
+ dk3_release(p->name);
+ dk3_delete(p);
+ }
+
+#line 516 "DkWxAppHelper.cpt"
+}
+
+
+
+
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+/** Separator character for file names.
+*/
+#define SEP wxT('\\')
+#else
+/** Separator character for file names.
+*/
+#define SEP wxT('/')
+#endif
+
+
+
+/** Non-localized keywords, 8-bit characters.
+*/
+static char const * const dkwxapphelper_c8_kw[] = {
+/* 0 */ "UTF-8",
+/* 1 */ "utf8",
+NULL
+};
+
+
+
+DkWxAppHelper::DkWxAppHelper(
+ wxChar const *arg0,
+ wxChar const *vName,
+ dkChar const *groupName
+)
+{
+ dkChar dkcb[DK3_MAX_PATH];
+ dkChar *newargv[2];
+ wxChar *ptr;
+ wxChar const *cptr;
+ wxChar const * const *ptrGetNumBasicStrings;
+
+
+#line 555 "DkWxAppHelper.cpt"
+ newargv[0] = NULL;
+ app = NULL;
+ sStringTables = NULL;
+ iStringTables = NULL;
+ basicStrings = NULL;
+ nBasicStrings = 0;
+ cmdName = NULL;
+ appName = NULL;
+ vendorName = NULL;
+ errorCode = ERROR_NONE;
+ dkEncoding = DK3_ENCODING_PLAIN;
+ wxEncoding = DK3_ENCODING_PLAIN;
+ if(DK3_CHAR_SIZE > 1) {
+ if(DK3_CHAR_SIZE > 2) {
+ dkEncoding = DK3_ENCODING_UNICODE;
+ } else {
+ dkEncoding = DK3_ENCODING_UTF16;
+ }
+ } else {
+ /* dkChar is 1 byte. */
+#if DK3_ON_WINDOWS
+#else
+ char *ptr;
+ ptr = getenv("LANG");
+ if(ptr) {
+ ptr = dk3str_c8_chr(ptr, '.');
+ if(ptr) {
+ ptr++;
+ if(dk3str_c8_casecmp(dkwxapphelper_c8_kw[0], ptr) == 0) {
+ dkEncoding = DK3_ENCODING_UTF8;
+ } else {
+ if(dk3str_c8_casecmp(dkwxapphelper_c8_kw[1], ptr) == 0) {
+ dkEncoding = DK3_ENCODING_UTF8;
+ }
+ }
+ }
+ }
+#endif
+ }
+ if(sizeof(wxChar) > 1) {
+ if(sizeof(wxChar) > 2) {
+ wxEncoding = DK3_ENCODING_UNICODE;
+ } else {
+ wxEncoding = DK3_ENCODING_UTF16;
+ }
+ } else {
+#if DK3_ON_WINDOWS
+#else
+ char *ptr;
+ ptr = getenv("LANG");
+ if(ptr) {
+ ptr = dk3str_c8_chr(ptr, '.');
+ if(ptr) {
+ ptr++;
+ if(dk3str_c8_casecmp(dkwxapphelper_c8_kw[0], ptr) == 0) {
+ wxEncoding = DK3_ENCODING_UTF8;
+ } else {
+ if(dk3str_c8_casecmp(dkwxapphelper_c8_kw[1], ptr) == 0) {
+ wxEncoding = DK3_ENCODING_UTF8;
+ }
+ }
+ }
+ }
+#endif
+ }
+ if(dk3wxs_to_dkstr(dkcb,DK3_SIZEOF(dkcb,dkChar),dkEncoding,arg0,wxEncoding))
+ {
+ newargv[0] = dkcb,
+ newargv[1] = 0;
+ app = dk3app_open_gui(1, newargv, groupName);
+ if(app) {
+ sStringTables = dk3sto_open_app(app);
+ if(sStringTables) {
+ dk3sto_set_comp(sStringTables, dkwxah_string_table_compare, 0);
+ iStringTables = dk3sto_it_open(sStringTables);
+ if(iStringTables) {
+ }
+ }
+ }
+ }
+ else
+ {
+ errorCode = ERROR_ENCODE_ARG0;
+ }
+ cmdName = dk3wxs_dup_app(arg0, app);
+ if(cmdName) {
+ cptr = dk3wxs_rchr(cmdName, SEP);
+ if(cptr) {
+ cptr++;
+ } else {
+ cptr = cmdName;
+ }
+ appName = dk3wxs_dup_app(cptr, app);
+ if(appName) {
+ ptr = dk3wxs_rchr(appName, '.');
+ if(ptr) { *ptr = wxT('\0'); }
+ }
+ }
+ vendorName = dk3wxs_dup_app(vName, app);
+ /*
+ Finally retrieve the basic application strings.
+ */
+ ptrGetNumBasicStrings = dkwxapphelper_defwxappstr;
+ while(*(ptrGetNumBasicStrings++)) { nBasicStrings++; }
+ basicStrings = getStringTable(
+ dkwxapphelper_defwxappstr,
+ dkwxapphelper_sttname
+ );
+ reportProblemsIfAny();
+
+
+#line 665 "DkWxAppHelper.cpt"
+}
+
+
+
+DkWxAppHelper::~DkWxAppHelper()
+{
+
+
+#line 672 "DkWxAppHelper.cpt"
+ DkAppHelperWxStringTable *e;
+ basicStrings = NULL;
+ if(sStringTables) {
+ if(iStringTables) {
+ dk3sto_it_reset(iStringTables);
+ do {
+ e = (DkAppHelperWxStringTable *)dk3sto_it_next(iStringTables);
+ if(e) {
+ dkwxah_string_table_close(e);
+ }
+ } while(e != NULL);
+ dk3sto_it_close(iStringTables);
+ }
+ dk3sto_close(sStringTables);
+ } sStringTables = NULL; iStringTables = NULL;
+ if(app) {
+ dk3app_close(app); app = NULL;
+ }
+ dk3_release(cmdName);
+ dk3_release(appName);
+ dk3_release(vendorName);
+
+
+#line 694 "DkWxAppHelper.cpt"
+}
+
+
+
+int
+DkWxAppHelper::checkSetup() const
+{
+ int back = 0;
+
+
+#line 703 "DkWxAppHelper.cpt"
+ if(app) {
+
+#line 704 "DkWxAppHelper.cpt"
+ if(sStringTables) {
+
+#line 705 "DkWxAppHelper.cpt"
+ if(iStringTables) {
+
+#line 706 "DkWxAppHelper.cpt"
+ if(cmdName) {
+
+#line 707 "DkWxAppHelper.cpt"
+ if(appName) {
+
+#line 708 "DkWxAppHelper.cpt"
+ if(vendorName) {
+
+#line 709 "DkWxAppHelper.cpt"
+ back = 1;
+ } else {
+
+#line 711 "DkWxAppHelper.cpt"
+ }
+ } else {
+
+#line 713 "DkWxAppHelper.cpt"
+ }
+ } else {
+
+#line 715 "DkWxAppHelper.cpt"
+ }
+ } else {
+
+#line 717 "DkWxAppHelper.cpt"
+ }
+ } else {
+
+#line 719 "DkWxAppHelper.cpt"
+ }
+ } else {
+
+#line 721 "DkWxAppHelper.cpt"
+ }
+
+#line 722 "DkWxAppHelper.cpt"
+ return back;
+}
+
+
+
+wxChar const * const *
+DkWxAppHelper::getStringTable(
+ wxChar const * const *dt,
+ dkChar const *tn
+)
+{
+#if 0
+ wxChar const * const *back = NULL;
+ wxChar const * *wxptr;
+ DkAppHelperWxStringTable *tp = NULL;
+ FILE *fipo = NULL;
+ dkChar const *oldsource = NULL;
+#if 0
+ dkChar dkb[4096];
+#endif
+ dkChar fnb[DK3_MAX_PATH];
+ wxChar wxb[4096];
+ char il[4096];
+ unsigned long lineno = 0UL;
+ unsigned long oldline = 0UL;
+ size_t nelem = 0;
+ size_t i = 0;
+ int cc = 1;
+ int ok = 0;
+
+
+
+#line 753 "DkWxAppHelper.cpt"
+ if((dt) && (tn)) {
+
+#line 754 "DkWxAppHelper.cpt"
+ if(checkSetup()) {
+
+#line 755 "DkWxAppHelper.cpt"
+ tp = (DkAppHelperWxStringTable *)dk3sto_it_find_like(
+ iStringTables, (void *)tn, 1
+ );
+ if(!(tp)) {
+
+#line 759 "DkWxAppHelper.cpt"
+ if(dk3app_find_data_file(app, tn, fnb, DK3_SIZEOF(fnb,dkChar))) {
+
+#line 760 "DkWxAppHelper.cpt"
+ fipo = dk3sf_fopen_app(fnb, dk3app_not_localized(22), app);
+ if(fipo) {
+
+#line 762 "DkWxAppHelper.cpt"
+ wxptr = (wxChar const **)dt; nelem = 0;
+ while(*(wxptr++)) { nelem++; }
+ if(nelem) {
+
+#line 765 "DkWxAppHelper.cpt"
+ tp = dk3_new_app(DkAppHelperWxStringTable,1,app);
+ if(tp) {
+
+#line 767 "DkWxAppHelper.cpt"
+ ok = 0;
+ tp->array = NULL;
+ tp->nelem = nelem;
+ tp->name = dk3str_dup_app(tn, app);
+ if(tp->name) {
+
+#line 772 "DkWxAppHelper.cpt"
+ tp->array = dk3_new_app(wxConstPtr,nelem,app);
+ if(tp->array) {
+
+#line 774 "DkWxAppHelper.cpt"
+ wxptr = tp->array;
+ tp->nelem = nelem;
+ for(i = 0; i < nelem; i++) { *(wxptr++) = NULL; }
+ if(dk3sto_add(sStringTables, (void *)tp)) {
+
+#line 778 "DkWxAppHelper.cpt"
+ ok = 1;
+ oldsource = dk3app_get_source_file(app);
+ oldline = dk3app_get_source_line(app);
+ dk3app_set_source_file(app, fnb);
+ dk3app_set_source_line(app, 0UL);
+ lineno = 0UL;
+ wxptr = tp->array; nelem = 0;
+ do {
+
+#line 786 "DkWxAppHelper.cpt"
+ cc = 0;
+ if(fgets(il, sizeof(il), fipo)) {
+
+#line 788 "DkWxAppHelper.cpt"
+ dk3app_set_source_line(app, ++lineno);
+ cc = 1;
+ if(il[0] != '#') {
+
+#line 791 "DkWxAppHelper.cpt"
+ dk3app_squeeze_line(il);
+ if(dk3wxs_from_utf8(wxb,DK3_SIZEOF(wxb,wxChar),il))
+ {
+ *wxptr = dk3wxs_dup_app(wxb, app);
+ if(!(*wxptr)) {
+
+#line 796 "DkWxAppHelper.cpt"
+ ok = 0;
+ }
+ wxptr++;
+ }
+ else
+ {
+ ok = 0;
+
+#line 803 "DkWxAppHelper.cpt"
+ }
+ } else {
+
+#line 805 "DkWxAppHelper.cpt"
+ }
+ if(nelem >= tp->nelem) { cc = 0; }
+ } else {
+
+#line 808 "DkWxAppHelper.cpt"
+ }
+ } while((cc) && (ok));
+ if(nelem < tp->nelem) {
+ ok = 0;
+ }
+ dk3app_set_source_file(app, oldsource);
+ dk3app_set_source_line(app, oldline);
+ } else {
+
+#line 816 "DkWxAppHelper.cpt"
+ }
+ } else {
+
+#line 818 "DkWxAppHelper.cpt"
+ }
+ } else {
+
+#line 820 "DkWxAppHelper.cpt"
+ }
+ if(ok) {
+ back = (wxChar const * const *)(tp->array);
+ } else {
+ dkwxah_string_table_close(tp);
+ }
+ } else {
+
+#line 827 "DkWxAppHelper.cpt"
+ }
+ } else {
+
+#line 829 "DkWxAppHelper.cpt"
+ }
+ fclose(fipo);
+ } else {
+
+#line 832 "DkWxAppHelper.cpt"
+ }
+ } else {
+
+#line 834 "DkWxAppHelper.cpt"
+ }
+ } else {
+
+#line 836 "DkWxAppHelper.cpt"
+ }
+ if(tp) {
+
+#line 838 "DkWxAppHelper.cpt"
+ back = (wxChar const * const *)(tp->array);
+ }
+ } else {
+
+#line 841 "DkWxAppHelper.cpt"
+ }
+ } else {
+
+#line 843 "DkWxAppHelper.cpt"
+ }
+ if(!(back)) {
+ back = dt;
+ }
+
+#line 847 "DkWxAppHelper.cpt"
+#else
+ dkChar fnb[DK3_MAX_PATH]; /* Full file name. */
+ char il[4096]; /* Input line */
+ wxChar wxb[sizeof(il)];
+ wxChar const * const *back = NULL;
+ DkAppHelperWxStringTable *tp; /* String table if exists. */
+ wxChar const * *wxptr; /* Traverse dt array. */
+ FILE *fipo; /* Read input file. */
+#if VERSION_BEFORE_20150821
+ unsigned long lineno; /* Current line. */
+#endif
+ size_t nelem; /* Number of elements in dt. */
+ size_t i; /* Current string to process. */
+ int res; /* Search result. */
+ int cc; /* Flag: Can continue. */
+ int ok; /* Flag: All strings read succes. */
+
+
+#line 864 "DkWxAppHelper.cpt"
+ if((dt) && (tn)) {
+
+#line 865 "DkWxAppHelper.cpt"
+ if(checkSetup()) {
+
+#line 866 "DkWxAppHelper.cpt"
+ tp = (DkAppHelperWxStringTable *)dk3sto_it_find_like(
+ iStringTables, (void *)tn, 1
+ );
+ if(!(tp)) {
+
+#line 870 "DkWxAppHelper.cpt"
+ res = dk3app_find_data_file(app,tn,fnb,DK3_SIZEOF(fnb,dkChar));
+
+
+#line 872 "DkWxAppHelper.cpt"
+ if(res) {
+
+#line 873 "DkWxAppHelper.cpt"
+ fipo = dk3sf_fopen_app(fnb, dk3app_not_localized(22), app);
+ if(fipo) {
+
+#line 875 "DkWxAppHelper.cpt"
+ wxptr = (wxChar const **)dt; nelem = 0;
+ while(*(wxptr++)) { nelem++; }
+ if(nelem) {
+ tp = dk3_new_app(DkAppHelperWxStringTable,1,app);
+ if(tp) {
+ tp->array = NULL;
+ tp->nelem = nelem;
+ tp->name = NULL;
+ tp->name = dk3str_dup_app(tn, app);
+ if(tp->name) {
+ tp->array = dk3_new_app(wxConstPtr,nelem,app);
+ if(tp->array) {
+ wxptr = tp->array;
+ tp->nelem = nelem;
+ for(i = 0; i < nelem; i++) { *(wxptr++) = NULL; }
+ wxptr = tp->array; nelem = 0;
+#if VERSION_BEFORE_20150821
+ lineno = 0UL;
+#endif
+#if VERSION_BEFORE_20150821
+ cc = 1;
+#endif
+ ok = 1;
+ do {
+ cc = 0;
+ if(fgets(il, sizeof(il), fipo)) {
+ cc = 1;
+
+#line 902 "DkWxAppHelper.cpt"
+ if(il[0] != '#') {
+
+#line 903 "DkWxAppHelper.cpt"
+ dk3app_squeeze_line(il);
+ if(dk3wxs_from_utf8(wxb,DK3_SIZEOF(wxb,wxChar),il)) {
+ *wxptr = dk3wxs_dup_app(wxb, app);
+ if(*wxptr) {
+ nelem++;
+ if(nelem >= tp->nelem) {
+ cc = 0;
+ }
+ } else {
+ ok = 0; cc = 0;
+ }
+ wxptr++;
+ } else {
+
+#line 916 "DkWxAppHelper.cpt"
+ ok = 0; cc = 0;
+ }
+ } else {
+
+#line 919 "DkWxAppHelper.cpt"
+ }
+ }
+ } while(cc);
+ if(nelem < tp->nelem) {
+ ok = 0;
+
+#line 924 "DkWxAppHelper.cpt"
+ }
+ if(ok) {
+
+#line 926 "DkWxAppHelper.cpt"
+ if(!dk3sto_add(sStringTables, (void *)tp)) {
+ dkwxah_string_table_close(tp);
+
+#line 928 "DkWxAppHelper.cpt"
+ tp = NULL;
+ }
+ } else {
+
+#line 931 "DkWxAppHelper.cpt"
+ dkwxah_string_table_close(tp);
+ tp = NULL;
+ }
+ } else {
+ dkwxah_string_table_close(tp);
+ tp = NULL;
+ }
+ } else {
+ dkwxah_string_table_close(tp);
+ tp = NULL;
+ }
+ } else {
+
+#line 943 "DkWxAppHelper.cpt"
+ }
+ }
+ fclose(fipo);
+ } else {
+
+#line 947 "DkWxAppHelper.cpt"
+ }
+ } else {
+
+#line 949 "DkWxAppHelper.cpt"
+ }
+ }
+ if(tp) {
+
+#line 952 "DkWxAppHelper.cpt"
+ back = (wxChar const * const *)(tp->array);
+ }
+ } else {
+
+#line 955 "DkWxAppHelper.cpt"
+ }
+ } else {
+
+#line 957 "DkWxAppHelper.cpt"
+ }
+ if(!(back)) {
+
+#line 959 "DkWxAppHelper.cpt"
+ back = dt;
+ }
+
+#line 961 "DkWxAppHelper.cpt"
+#endif
+ return back;
+}
+
+
+size_t
+DkWxAppHelper::retrieveMultipleInts(
+ wxChar const * const *names,
+ int *values
+) const
+{
+ size_t back = 0;
+ wxChar const * const *nptr;
+ int *vptr;
+ long l;
+
+
+#line 977 "DkWxAppHelper.cpt"
+ if((appName) && (vendorName) && (names) && (values)) {
+ wxConfig *conf = new wxConfig(appName, vendorName);
+ if(conf) {
+ nptr = names; vptr = values;
+ while(*nptr) {
+ l = 0L;
+ if(conf->Read(*nptr, &l)) {
+ *vptr = (int)l;
+ back++;
+ }
+ nptr++; vptr++;
+ }
+ delete(conf);
+ }
+ }
+
+#line 992 "DkWxAppHelper.cpt"
+ return back;
+}
+
+
+
+size_t
+DkWxAppHelper::retrieveMultipleLongs(
+ wxChar const * const *names,
+ long *values
+) const
+{
+ size_t back = 0;
+ wxChar const * const *nptr;
+ long *vptr;
+ long l;
+
+
+#line 1008 "DkWxAppHelper.cpt"
+ if((appName) && (vendorName) && (names) && (values)) {
+ wxConfig *conf = new wxConfig(appName, vendorName);
+ if(conf) {
+ nptr = names; vptr = values;
+ while(*nptr) {
+ l = 0L;
+ if(conf->Read(*nptr, &l)) {
+ *vptr = l;
+ back++;
+ }
+ nptr++; vptr++;
+ }
+ delete(conf);
+ }
+ }
+
+
+#line 1024 "DkWxAppHelper.cpt"
+ return back;
+}
+
+
+size_t
+DkWxAppHelper::retrieveMultipleDoubles(
+ wxChar const * const *names,
+ double *values
+) const
+{
+ size_t back = 0;
+ double d;
+ wxChar const * const *nptr;
+ double *vptr;
+
+
+#line 1039 "DkWxAppHelper.cpt"
+ if((appName) && (vendorName) && (names) && (values)) {
+ wxConfig *conf = new wxConfig(appName, vendorName);
+ if(conf) {
+ nptr = names; vptr = values;
+ while(*nptr) {
+ d = 0.0;
+ if(conf->Read(*nptr, &d)) {
+ *vptr = d;
+ back++;
+ }
+ nptr++; vptr++;
+ }
+ delete(conf);
+ }
+ }
+
+#line 1054 "DkWxAppHelper.cpt"
+ return back;
+}
+
+
+size_t
+DkWxAppHelper::saveMultipleInts(
+ wxChar const * const *names,
+ int *values
+) const
+{
+ size_t back = 0;
+ wxChar const * const *nptr;
+ int *vptr;
+ long l;
+
+
+#line 1069 "DkWxAppHelper.cpt"
+ if((appName) && (vendorName) && (names) && (values)) {
+ wxConfig *conf = new wxConfig(appName, vendorName);
+ if(conf) {
+
+#line 1072 "DkWxAppHelper.cpt"
+ nptr = names; vptr = values;
+ while(*nptr) {
+
+#line 1074 "DkWxAppHelper.cpt"
+ l = (long)(*vptr);
+ if(conf->Write(*nptr, l)) {
+ back++;
+ }
+ nptr++; vptr++;
+ }
+ delete(conf);
+ }
+ }
+
+#line 1083 "DkWxAppHelper.cpt"
+ return back;
+}
+
+
+
+size_t
+DkWxAppHelper::saveMultipleLongs(
+ wxChar const * const *names,
+ long *values
+) const
+{
+ size_t back = 0;
+ wxChar const * const *nptr;
+ long *vptr;
+ long l;
+
+
+#line 1099 "DkWxAppHelper.cpt"
+ if((appName) && (vendorName) && (names) && (values)) {
+ wxConfig *conf = new wxConfig(appName, vendorName);
+ if(conf) {
+ nptr = names; vptr = values;
+ while(*nptr) {
+ l = *vptr;
+ if(conf->Write(*nptr, l)) {
+ back++;
+ }
+ nptr++; vptr++;
+ }
+ delete(conf);
+ }
+ }
+
+
+#line 1114 "DkWxAppHelper.cpt"
+ return back;
+}
+
+
+
+size_t
+DkWxAppHelper::saveMultipleDoubles(
+ wxChar const * const *names,
+ double *values
+) const
+{
+ size_t back = 0;
+ double d;
+ wxChar const * const *nptr;
+ double *vptr;
+
+
+#line 1130 "DkWxAppHelper.cpt"
+ if((appName) && (vendorName) && (names) && (values)) {
+ wxConfig *conf = new wxConfig(appName, vendorName);
+ if(conf) {
+ nptr = names; vptr = values;
+ while(*nptr) {
+ d = *vptr;
+ if(conf->Write(*nptr, d)) {
+ back++;
+ }
+ nptr++; vptr++;
+ }
+ delete(conf);
+ }
+ }
+
+#line 1144 "DkWxAppHelper.cpt"
+ return back;
+}
+
+
+
+wxChar const *
+DkWxAppHelper::retrieveString(
+ wxChar const *name
+) const
+{
+ wxChar const *back = NULL;
+ wxChar const *ptr;
+
+
+#line 1157 "DkWxAppHelper.cpt"
+ if((name) && (appName) && (vendorName)) {
+ wxConfig *conf = new wxConfig(appName, vendorName);
+ if(conf) {
+ wxString str;
+ if(conf->Read(name, &str)) {
+ ptr = str.c_str();
+ if(ptr) {
+ back = dk3wxs_dup_app(ptr, app);
+ }
+ }
+ delete(conf);
+ }
+ }
+
+#line 1170 "DkWxAppHelper.cpt"
+ return back;
+}
+
+
+
+int
+DkWxAppHelper::saveString(
+ wxChar const *name,
+ wxChar const *value
+) const
+{
+ int back = 0;
+
+
+#line 1183 "DkWxAppHelper.cpt"
+ if((name) && (value) && (appName) && (vendorName)) {
+ wxConfig *conf = new wxConfig(appName, vendorName);
+ if(conf) {
+ conf->Write(name, value);
+ delete(conf);
+ }
+ }
+
+#line 1190 "DkWxAppHelper.cpt"
+ return back;
+}
+
+
+
+int
+DkWxAppHelper::getWxEncoding() const
+{
+
+
+#line 1199 "DkWxAppHelper.cpt"
+ return wxEncoding;
+}
+
+
+
+int
+DkWxAppHelper::getDkEncoding() const
+{
+
+
+#line 1208 "DkWxAppHelper.cpt"
+ return dkEncoding;
+}
+
+
+
+int
+DkWxAppHelper::getC8Encoding() const
+{
+ int back;
+
+
+#line 1218 "DkWxAppHelper.cpt"
+ back = dkEncoding;
+ if(DK3_ENCODING_UTF8 != back) {
+ back = DK3_ENCODING_PLAIN;
+ }
+
+#line 1222 "DkWxAppHelper.cpt"
+ return back;
+}
+
+
+
+dk3_app_t *
+DkWxAppHelper::getApp() const
+{
+
+
+#line 1231 "DkWxAppHelper.cpt"
+ return app;
+}
+
+
+
+int
+DkWxAppHelper::findDataFile(wxChar const *fn, wxChar *fnb, size_t szfnb)
+{
+ dkChar shnDk[DK3_MAX_PATH];
+ dkChar ffnDk[DK3_MAX_PATH];
+ int back = 0;
+
+
+#line 1243 "DkWxAppHelper.cpt"
+ if((fn) && (fnb) && (szfnb)) {
+
+#line 1244 "DkWxAppHelper.cpt"
+ if(checkSetup()) {
+
+#line 1245 "DkWxAppHelper.cpt"
+ if(dk3wxs_to_dkstr(
+ shnDk, DK3_SIZEOF(shnDk,dkChar), dkEncoding, fn, wxEncoding
+ )
+ )
+ {
+ if(app) {
+
+#line 1251 "DkWxAppHelper.cpt"
+ if(dk3app_find_data_file(app,shnDk,ffnDk,DK3_SIZEOF(ffnDk,dkChar))) {
+ if(dk3wxs_from_dkstr(fnb, szfnb, wxEncoding, ffnDk, dkEncoding)) {
+ back = 1;
+
+#line 1254 "DkWxAppHelper.cpt"
+ } else {
+
+#line 1255 "DkWxAppHelper.cpt"
+ }
+ } else {
+
+#line 1257 "DkWxAppHelper.cpt"
+ }
+ } else {
+
+#line 1259 "DkWxAppHelper.cpt"
+ }
+ } else {
+
+#line 1261 "DkWxAppHelper.cpt"
+ }
+ }
+ }
+
+#line 1264 "DkWxAppHelper.cpt"
+ return back;
+}
+
+
+
+wxChar const *
+DkWxAppHelper::getBasicString(size_t i) const
+{
+ wxChar const *back = NULL;
+
+
+#line 1274 "DkWxAppHelper.cpt"
+ if(basicStrings) {
+ if(i < nBasicStrings) {
+ back = basicStrings[i];
+ }
+ }
+
+#line 1279 "DkWxAppHelper.cpt"
+ return back;
+}
+
+
+
+wxChar const * const *
+DkWxAppHelper::getBasicStrings() const
+{
+
+
+#line 1288 "DkWxAppHelper.cpt"
+ return basicStrings;
+}
+
+
+
+size_t
+DkWxAppHelper::getBasicStringNumbers() const
+{
+
+
+#line 1297 "DkWxAppHelper.cpt"
+ return nBasicStrings;
+}
+
+
+
+bool
+DkWxAppHelper::wxToDk(dkChar *bu, size_t sz, wxChar const *src) const
+{
+ bool back = false;
+
+
+#line 1307 "DkWxAppHelper.cpt"
+ if((bu) && (sz) && (src)) {
+ if(dk3wxs_to_dkstr(bu, sz, dkEncoding, src, wxEncoding)) {
+ back = true;
+ }
+ }
+
+#line 1312 "DkWxAppHelper.cpt"
+ return back;
+}
+
+
+
+bool
+DkWxAppHelper::wxToC8(char *bu, size_t sz, wxChar const *src) const
+{
+ bool back = false;
+
+
+#line 1322 "DkWxAppHelper.cpt"
+ if((bu) && (sz) && (src)) {
+ if(dk3wxs_to_c8(bu, sz, getC8Encoding(), src, wxEncoding)) {
+ back = true;
+ }
+ }
+
+#line 1327 "DkWxAppHelper.cpt"
+ return back;
+}
+
+
+
+bool
+DkWxAppHelper::wxToC8(char *bu, size_t sz, wxString & str) const
+{
+ bool back = false;
+ wxChar const *ptr;
+
+
+#line 1338 "DkWxAppHelper.cpt"
+ if((bu) && (sz)) {
+ ptr = str.c_str();
+ if(ptr) {
+ back = wxToC8(bu, sz, ptr);
+ }
+ }
+
+#line 1344 "DkWxAppHelper.cpt"
+ return back;
+}
+
+
+
+bool
+DkWxAppHelper::dkToWx(wxChar *bu, size_t sz, dkChar const *src) const
+{
+ bool back = false;
+
+
+#line 1354 "DkWxAppHelper.cpt"
+ if((bu) && (sz) && (src)) {
+ if(dk3wxs_from_dkstr(bu, sz, wxEncoding, src, dkEncoding)) {
+ back = true;
+ }
+ }
+
+#line 1359 "DkWxAppHelper.cpt"
+ return back;
+}
+
+
+void
+DkWxAppHelper::setRelatedPosition(
+ wxWindow *parent,
+ wxWindow *child,
+ int *pcx,
+ int *pcy
+) const
+{
+ int px = 0; /* Parent x position. */
+ int py = 0; /* Parent y position. */
+ int pw = 0; /* Parent width. */
+ int ph = 0; /* Parent height. */
+ int cx = 0; /* Child x position. */
+ int cy = 0; /* Child y position. */
+ int cw = 0; /* Child width. */
+ int ch = 0; /* Child height. */
+ wxSize scsz; /* Screen size. */
+
+ scsz = wxGetDisplaySize();
+ parent->GetPosition(&px, &py);
+ parent->GetSize(&pw, &ph);
+ child->GetSize(&cw, &ch);
+ cx = px + (pw - cw) / 2;
+ cy = py + (ph - ch) / 2;
+ if((cx + cw) > scsz.x) {
+ cx = scsz.x - cw;
+ }
+ if((cy + ch) > scsz.y) {
+ cy = scsz.y - ch;
+ }
+ if(cx < 0) {
+ cx = 0;
+ }
+ if(cy < 0) {
+ cy = 0;
+ }
+ if((pcx) && (pcy)) {
+ if(((*pcx) >= 0) && ((*pcy) >= 0)) {
+ cx = *pcx;
+ cy = *pcy;
+ }
+ }
+ child->SetSize(cx, cy, cw, ch);
+}
+
+
+void
+DkWxAppHelper::reportProblemsIfAny(void)
+{
+ bool didReport = false;
+
+ if (!didReport) {
+ if (NULL == app) {
+ didReport = true;
+ switch (errorCode) {
+ case ERROR_ENCODE_ARG0 : {
+ /* ERROR: Failed to encode arg0 to dkChar */
+ showErrorMessage(3, 12);
+ } break;
+ default : {
+ /* ERROR: Failed to initialize application structure */
+ showErrorMessage(3, 11);
+ } break;
+ }
+ }
+ }
+ if (!didReport) {
+ if (NULL != app) {
+ if ((NULL == sStringTables) || (NULL == iStringTables)) {
+ didReport = true;
+ /* ERROR: Memory */
+ showErrorMessage(3, 9);
+ }
+ }
+ }
+ if (!didReport) {
+ if ((NULL == cmdName) || (NULL == appName) || (NULL == vendorName)) {
+ didReport = true;
+ /* ERROR: Memory */
+ showErrorMessage(3, 9);
+ }
+ }
+}
+
+
+
+void
+DkWxAppHelper::showErrorMessage(size_t i_title, size_t i_text)
+{
+ const wxChar *str_title = NULL;
+ const wxChar *str_text = NULL;
+ if (NULL != basicStrings) {
+ str_title = basicStrings[i_title];
+ str_text = basicStrings[i_text];
+ } else {
+ str_title = dkwxapphelper_defwxappstr[i_title];
+ str_text = dkwxapphelper_defwxappstr[i_text];
+ }
+ wxMessageBox(str_text, str_title, (wxOK | wxCENTRE | wxICON_ERROR));
+}
+
+
+
diff --git a/support/dktools/DkWxAppHelper.cpt b/support/dktools/DkWxAppHelper.cpt
new file mode 100644
index 0000000000..c2d4f55ae8
--- /dev/null
+++ b/support/dktools/DkWxAppHelper.cpt
@@ -0,0 +1,1465 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% header
+
+#if 0
+#include <dk3all.h>
+#else
+#include <dk3conf.h>
+#include <dk3types.h>
+#include <dk3const.h>
+#endif
+
+
+
+#include <wx/wxprec.h>
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#include <wx/wx.h>
+#endif
+#include <wx/config.h>
+#include <wx/filename.h>
+
+/** Application helper class, provides file search, internationalization
+ and some functions for GUI development using the wxWidgets libraries.
+*/
+class DkWxAppHelper
+{
+ protected:
+
+ /** Application structure.
+ */
+ dk3_app_t *app;
+
+ /** Storage for string tables.
+ */
+ dk3_sto_t *sStringTables;
+
+ /** Iterator through string tables storage.
+ */
+ dk3_sto_it_t *iStringTables;
+
+ /** Basic strings used by wxWidgets applications.
+ */
+ wxChar const * const *basicStrings;
+
+ /** First command line argument.
+ */
+ wxChar const *cmdName;
+
+ /** Application name.
+ */
+ wxChar const *appName;
+
+ /** Software vendor name.
+ */
+ wxChar const *vendorName;
+
+ /** Number of entries in the basicStrings array.
+ */
+ size_t nBasicStrings;
+
+ /** Encoding for dkChar.
+ */
+ int dkEncoding;
+
+ /** Encoding for wxChar.
+ */
+ int wxEncoding;
+
+ /** Code for errors from constructor.
+ */
+ int errorCode;
+
+ protected:
+
+ /** Report problems within the constructor, if any.
+ */
+ void
+ reportProblemsIfAny(void);
+
+ /** Show an error message.
+ @param i_title Index of dialog title in basic strings.
+ @param i_text Index of message text in basic strings.
+ */
+ void
+ showErrorMessage(size_t i_title, size_t i_text);
+
+ public:
+
+ /** Constructor.
+ @param arg0 First command line argument.
+ @param vName Software vendor name.
+ @param groupName Application group name.
+ */
+ DkWxAppHelper(
+ wxChar const *arg0,
+ wxChar const *vName,
+ dkChar const *groupName
+ );
+
+ /** Destructor.
+ */
+ ~DkWxAppHelper();
+
+ /** Check whether application helper object is set up correctly
+ and is ready to use.
+ @return 1 on success, 0 on error.
+ */
+ int
+ checkSetup() const;
+
+ /** Retrieve array of localized texts.
+ @param dt Default texts, used if problems occur.
+ @param tn Table name.
+ @return Pointer to localized messages array or dt.
+ */
+ wxChar const * const *
+ getStringTable(
+ wxChar const * const *dt,
+ dkChar const *tn
+ );
+
+ /** Find data file name. Provide a short file name like "x.y",
+ on success the program writes a full path like
+ "/usr/share/myapp/en/x.y" to the result buffer.
+ @param fn Short file name.
+ @param fnb Buffer for full path name.
+ @param szfnb Size of @arg fnb (number of wxChar).
+ @return 1 on success, 0 on error.
+ */
+ int
+ findDataFile(wxChar const *fn, wxChar *fnb, size_t szfnb);
+
+ /** Retrieve multiple int settings at once.
+ @param names Pointer to names array, must be terminated
+ by a NULL pointer.
+ @param values Pointer to destination value array.
+ @return Number of items read successfully.
+ */
+ size_t
+ retrieveMultipleInts(
+ wxChar const * const *names,
+ int *values
+ ) const;
+
+ /** Retrieve multiple long settings at once.
+ @param names Pointer to names array, must be terminated
+ by a NULL pointer.
+ @param values Pointer to destination value array.
+ @return Number of items read successfully.
+ */
+ size_t
+ retrieveMultipleLongs(
+ wxChar const * const *names,
+ long *values
+ ) const;
+
+ /** Save multiple int settings at once.
+ @param names Pointer to names array, must be terminated by
+ a NULL pointer.
+ @param values Pointer to values array.
+ @return Number of items successfully written.
+ */
+ size_t
+ saveMultipleInts(
+ wxChar const * const *names,
+ int *values
+ ) const;
+
+ /** Save multiple long settings at once.
+ @param names Pointer to names array, must be terminated by
+ a NULL pointer.
+ @param values Pointer to values array.
+ @return Number of items successfully written.
+ */
+ size_t
+ saveMultipleLongs(
+ wxChar const * const *names,
+ long *values
+ ) const;
+
+ /** Retrieve multiple double settings at once.
+ @param names Pointer to names array, must be terminated by
+ a NULL pointer.
+ @param values Pointer to values array.
+ @return Number of items successfully read.
+ */
+ size_t
+ retrieveMultipleDoubles(
+ wxChar const * const *names,
+ double *values
+ ) const;
+
+ /** Save multiple doubles at once.
+ @param names Pointer to names array, must be terminated by
+ a NULL pointer.
+ @param values Pointer to values array.
+ @return Number of items successfully written.
+ */
+ size_t
+ saveMultipleDoubles(
+ wxChar const * const *names,
+ double *values
+ ) const;
+
+ /** Retrieve a string preference.
+ @param name Preference name.
+ @return Pointer to new string on success, NULL on error.
+ */
+ wxChar const *
+ retrieveString(
+ wxChar const *name
+ ) const;
+
+ /** Save a string entry.
+ @param name Entry name.
+ @param value Entry value.
+ @return 1 on success, 0 on error.
+ */
+ int
+ saveString(
+ wxChar const *name,
+ wxChar const *value
+ ) const;
+
+ /** Retrieve encoding for wxChar.
+ @return Encoding used for wxChar.
+ */
+ int
+ getWxEncoding() const;
+
+ /** Retrieve encoding for dkChar.
+ @return Encoding used for dkChar.
+ */
+ int
+ getDkEncoding() const;
+
+ /** Retrieve encoding to use for 8 bit characters.
+ @return Encoding to use for 8 bit character strings.
+ */
+ int
+ getC8Encoding() const;
+
+ /** Retrieve application structure.
+ @return Application structure on success, NULL on error.
+ */
+ dk3_app_t *
+ getApp() const;
+
+ /** Get one of the basic application strings.
+ @param i Index of string in array.
+ @return String pointer on success or NULL on error.
+ */
+ wxChar const *
+ getBasicString(size_t i) const;
+
+ /** Get basic strings array.
+ @return Array pointer to basic strings.
+ */
+ wxChar const * const *
+ getBasicStrings() const;
+
+ /** Find number of basic strings stored in the \a basicStrings array.
+ @return Number of strings in the array.
+ */
+ size_t
+ getBasicStringNumbers() const;
+
+ /** Convert wxChar string to dkChar string.
+ @param bu Destination buffer.
+ @param sz Destination buffer size (number of dkChar).
+ @param src Source buffer.
+ @return true on success, false on error.
+ */
+ bool
+ wxToDk(dkChar *bu, size_t sz, wxChar const *src) const;
+
+ /** Convert wxChar string to 8-bit char string.
+ @param bu Destination buffer.
+ @param sz Destination buffer size.
+ @param src Source buffer.
+ @return true on success, false on error.
+ */
+ bool
+ wxToC8(char *bu, size_t sz, wxChar const *src) const;
+
+ /** Convert wxChar string to 8-bit char string.
+ @param bu Destination buffer.
+ @param sz Destination buffer size.
+ @param str Source string.
+ @return true on success, false on error.
+ */
+ bool
+ wxToC8(char *bu, size_t sz, wxString & str) const;
+
+ /** Convert dkChar string to wxChar string.
+ @param bu Destination buffer.
+ @param sz Destination buffer size (number of wxChar).
+ @param src Source buffer.
+ @return true on success, false on error.
+ */
+ bool
+ dkToWx(wxChar *bu, size_t sz, dkChar const *src) const;
+
+ /** Set related position (child over parent), the child
+ is either placed on a known previous position or placed
+ centered on top of the parent.
+ @param parent Parent top level window (frame).
+ @param child Child top level window (dialog).
+ @param pcx Pointer to previous child x position.
+ @param pcy Pointer to previous child y position.
+ */
+ void
+ setRelatedPosition(
+ wxWindow *parent,
+ wxWindow *child,
+ int *pcx = NULL,
+ int *pcy = NULL
+ ) const;
+
+};
+
+
+
+%% module
+
+
+#include <dk3all.h>
+#include "DkWxAppHelper.h"
+
+
+#include "dk3wxs.h"
+
+
+
+$!trace-include
+
+
+
+/** Storage entry for wxChar string table.
+*/
+typedef struct {
+ wxChar const **array; /**< String table contents. */
+ dkChar const *name; /**< String table name. */
+ size_t nelem; /**< Number of elements. */
+} DkAppHelperWxStringTable;
+
+
+
+/** Pointer to constant wxChar string.
+*/
+typedef wxChar const *wxConstPtr;
+
+
+
+/** Error codes.
+*/
+enum {
+ /** No error occured.
+ */
+ ERROR_NONE = 0,
+
+ /** Failed to encode arg0 to dkChar.
+ */
+ ERROR_ENCODE_ARG0 ,
+};
+
+
+
+/** Basic texts issued by wxWidgets applications.
+*/
+static wxChar const * const dkwxapphelper_defwxappstr[] = {
+$!string-table macro=wxT
+#
+# 0: Log level: Worse than panic
+#
+Error worse than Panic
+#
+# 1: Log level: Panic
+#
+Panic
+#
+# 2: Log level: Fatal error
+#
+Fatal error
+#
+# 3: Log level: Error
+#
+Error
+#
+# 4: Log level: Warning
+#
+Warning
+#
+# 5: Log level: Information
+#
+Information
+#
+# 6: Log level: Progress message
+#
+Progress
+#
+# 7: Log level: Debug message
+#
+Debug
+#
+# 8: Log level: Ignore message
+#
+Ignore
+#
+# 9: Error: Not enough memory!
+#
+Not enough memory!
+#
+# 10: Error: Help file not found!
+#
+Help file not found!
+#
+# 11: Error: Failed to initialize application structure!
+#
+Failed to initialize application structure!
+#
+# 12: Error: Failed to recode command line!
+#
+Failed to recode command line!
+$!end
+};
+
+
+
+/** String table file containing localized versions of the
+ texts in \a dkwxapphelper_defwxappstr.
+*/
+static dkChar const dkwxapphelper_sttname[] = { dkT("dkwx.str") };
+
+
+
+/** Compare two string table entries.
+ @param l Left entry.
+ @param r Right entry.
+ @param cr Comparison criteria (0=entry/entry, 1=entr/name).
+ @return Comparison result.
+*/
+static
+int
+dkwxah_string_table_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ DkAppHelperWxStringTable const *pl;
+ DkAppHelperWxStringTable const *pr;
+ if(l) {
+ if(r) {
+ pl = (DkAppHelperWxStringTable const *)l;
+ pr = (DkAppHelperWxStringTable const *)r;
+ switch(cr) {
+ case 1: {
+ if(pl->name) {
+ back = dk3str_cmp(pl->name, (dkChar const *)r);
+ } else { back = -1; }
+ } break;
+ default: {
+ if(pl->name) {
+ if(pr->name) {
+ back = dk3str_cmp(pl->name, pr->name);
+ } else { back = 1;}
+ } else {
+ if(pr->name) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ if(back < -1) { back = -1; }
+ if(back > 1) { back = 1; }
+ return back;
+}
+
+
+
+/** Close string table.
+ @param p String table to close.
+*/
+static
+void
+dkwxah_string_table_close(DkAppHelperWxStringTable *p)
+{
+ wxChar const **ptr;
+ size_t i;
+ $? "+ dkwxah_string_table_close PTR=%d", TR_IPTR(p)
+ if(p) {
+ if(p->array) {
+ if(p->nelem) { $? ". %lu elements", (unsigned long)(p->nelem)
+ ptr = p->array;
+ for(i = 0; i < p->nelem; i++) {
+ if(*ptr) { $? ". delete element %lu", (unsigned long)i
+ }
+ dk3_release(*ptr);
+ ptr++;
+ }
+ }
+ dk3_delete(p->array);
+ }
+ dk3_release(p->name);
+ dk3_delete(p);
+ } $? "- dkwxah_string_table_close"
+}
+
+
+
+
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+/** Separator character for file names.
+*/
+#define SEP wxT('\\')
+#else
+/** Separator character for file names.
+*/
+#define SEP wxT('/')
+#endif
+
+
+
+/** Non-localized keywords, 8-bit characters.
+*/
+static char const * const dkwxapphelper_c8_kw[] = {
+/* 0 */ "UTF-8",
+/* 1 */ "utf8",
+NULL
+};
+
+
+
+DkWxAppHelper::DkWxAppHelper(
+ wxChar const *arg0,
+ wxChar const *vName,
+ dkChar const *groupName
+)
+{
+ dkChar dkcb[DK3_MAX_PATH];
+ dkChar *newargv[2];
+ wxChar *ptr;
+ wxChar const *cptr;
+ wxChar const * const *ptrGetNumBasicStrings;
+ $? "+ DkWxAppHelper::DkWxAppHelper"
+ newargv[0] = NULL;
+ app = NULL;
+ sStringTables = NULL;
+ iStringTables = NULL;
+ basicStrings = NULL;
+ nBasicStrings = 0;
+ cmdName = NULL;
+ appName = NULL;
+ vendorName = NULL;
+ errorCode = ERROR_NONE;
+ dkEncoding = DK3_ENCODING_PLAIN;
+ wxEncoding = DK3_ENCODING_PLAIN;
+ if(DK3_CHAR_SIZE > 1) {
+ if(DK3_CHAR_SIZE > 2) {
+ dkEncoding = DK3_ENCODING_UNICODE;
+ } else {
+ dkEncoding = DK3_ENCODING_UTF16;
+ }
+ } else {
+ /* dkChar is 1 byte. */
+#if DK3_ON_WINDOWS
+#else
+ char *ptr;
+ ptr = getenv("LANG");
+ if(ptr) {
+ ptr = dk3str_c8_chr(ptr, '.');
+ if(ptr) {
+ ptr++;
+ if(dk3str_c8_casecmp(dkwxapphelper_c8_kw[0], ptr) == 0) {
+ dkEncoding = DK3_ENCODING_UTF8;
+ } else {
+ if(dk3str_c8_casecmp(dkwxapphelper_c8_kw[1], ptr) == 0) {
+ dkEncoding = DK3_ENCODING_UTF8;
+ }
+ }
+ }
+ }
+#endif
+ }
+ if(sizeof(wxChar) > 1) {
+ if(sizeof(wxChar) > 2) {
+ wxEncoding = DK3_ENCODING_UNICODE;
+ } else {
+ wxEncoding = DK3_ENCODING_UTF16;
+ }
+ } else {
+#if DK3_ON_WINDOWS
+#else
+ char *ptr;
+ ptr = getenv("LANG");
+ if(ptr) {
+ ptr = dk3str_c8_chr(ptr, '.');
+ if(ptr) {
+ ptr++;
+ if(dk3str_c8_casecmp(dkwxapphelper_c8_kw[0], ptr) == 0) {
+ wxEncoding = DK3_ENCODING_UTF8;
+ } else {
+ if(dk3str_c8_casecmp(dkwxapphelper_c8_kw[1], ptr) == 0) {
+ wxEncoding = DK3_ENCODING_UTF8;
+ }
+ }
+ }
+ }
+#endif
+ }
+ if(dk3wxs_to_dkstr(dkcb,DK3_SIZEOF(dkcb,dkChar),dkEncoding,arg0,wxEncoding))
+ {
+ newargv[0] = dkcb,
+ newargv[1] = 0;
+ app = dk3app_open_gui(1, newargv, groupName);
+ if(app) {
+ sStringTables = dk3sto_open_app(app);
+ if(sStringTables) {
+ dk3sto_set_comp(sStringTables, dkwxah_string_table_compare, 0);
+ iStringTables = dk3sto_it_open(sStringTables);
+ if(iStringTables) {
+ }
+ }
+ }
+ }
+ else
+ {
+ errorCode = ERROR_ENCODE_ARG0;
+ }
+ cmdName = dk3wxs_dup_app(arg0, app);
+ if(cmdName) {
+ cptr = dk3wxs_rchr(cmdName, SEP);
+ if(cptr) {
+ cptr++;
+ } else {
+ cptr = cmdName;
+ }
+ appName = dk3wxs_dup_app(cptr, app);
+ if(appName) {
+ ptr = dk3wxs_rchr(appName, '.');
+ if(ptr) { *ptr = wxT('\0'); }
+ }
+ }
+ vendorName = dk3wxs_dup_app(vName, app);
+ /*
+ Finally retrieve the basic application strings.
+ */
+ ptrGetNumBasicStrings = dkwxapphelper_defwxappstr;
+ while(*(ptrGetNumBasicStrings++)) { nBasicStrings++; }
+ basicStrings = getStringTable(
+ dkwxapphelper_defwxappstr,
+ dkwxapphelper_sttname
+ );
+ reportProblemsIfAny();
+ $? "- DkWxAppHelper::DkWxAppHelper"
+}
+
+
+
+DkWxAppHelper::~DkWxAppHelper()
+{
+ $? "+ DkWxAppHelper::~DkWxAppHelper"
+ DkAppHelperWxStringTable *e;
+ basicStrings = NULL;
+ if(sStringTables) {
+ if(iStringTables) {
+ dk3sto_it_reset(iStringTables);
+ do {
+ e = (DkAppHelperWxStringTable *)dk3sto_it_next(iStringTables);
+ if(e) {
+ dkwxah_string_table_close(e);
+ }
+ } while(e != NULL);
+ dk3sto_it_close(iStringTables);
+ }
+ dk3sto_close(sStringTables);
+ } sStringTables = NULL; iStringTables = NULL;
+ if(app) {
+ dk3app_close(app); app = NULL;
+ }
+ dk3_release(cmdName);
+ dk3_release(appName);
+ dk3_release(vendorName);
+ $? "- DkWxAppHelper::~DkWxAppHelper"
+}
+
+
+
+int
+DkWxAppHelper::checkSetup() const
+{
+ int back = 0;
+ $? "+ DkWxAppHelper::checkSetup"
+ if(app) { $? ". app ok"
+ if(sStringTables) { $? ". string table storage ok"
+ if(iStringTables) { $? ". string table iterator ok"
+ if(cmdName) { $? ". cmdName ok"
+ if(appName) { $? ". appName ok"
+ if(vendorName) { $? ". vendorName ok"
+ back = 1;
+ } else { $? "! vendorName"
+ }
+ } else { $? "! appName"
+ }
+ } else { $? "! cmdName"
+ }
+ } else { $? "! string table iterator"
+ }
+ } else { $? "! string table storage"
+ }
+ } else { $? "! app"
+ } $? "- DkWxAppHelper::checkSetup %d", back
+ return back;
+}
+
+
+
+wxChar const * const *
+DkWxAppHelper::getStringTable(
+ wxChar const * const *dt,
+ dkChar const *tn
+)
+{
+#if 0
+ wxChar const * const *back = NULL;
+ wxChar const * *wxptr;
+ DkAppHelperWxStringTable *tp = NULL;
+ FILE *fipo = NULL;
+ dkChar const *oldsource = NULL;
+#if 0
+ dkChar dkb[4096];
+#endif
+ dkChar fnb[DK3_MAX_PATH];
+ wxChar wxb[4096];
+ char il[4096];
+ unsigned long lineno = 0UL;
+ unsigned long oldline = 0UL;
+ size_t nelem = 0;
+ size_t i = 0;
+ int cc = 1;
+ int ok = 0;
+
+ $? "+ DkWxAppHelper::getStringTable \"%!ds\"", TR_STR(tn)
+ if((dt) && (tn)) { $? ". args ok"
+ if(checkSetup()) { $? ". setup ok"
+ tp = (DkAppHelperWxStringTable *)dk3sto_it_find_like(
+ iStringTables, (void *)tn, 1
+ );
+ if(!(tp)) { $? ". must read from file"
+ if(dk3app_find_data_file(app, tn, fnb, DK3_SIZEOF(fnb,dkChar))) { $? ". find"
+ fipo = dk3sf_fopen_app(fnb, dk3app_not_localized(22), app);
+ if(fipo) { $? ". fopen ok"
+ wxptr = (wxChar const **)dt; nelem = 0;
+ while(*(wxptr++)) { nelem++; }
+ if(nelem) { $? ". have %lu elements", (unsigned long)nelem
+ tp = dk3_new_app(DkAppHelperWxStringTable,1,app);
+ if(tp) { $? ". allocation ok"
+ ok = 0;
+ tp->array = NULL;
+ tp->nelem = nelem;
+ tp->name = dk3str_dup_app(tn, app);
+ if(tp->name) { $? ". dup ok for name"
+ tp->array = dk3_new_app(wxConstPtr,nelem,app);
+ if(tp->array) { $? ". array allocation ok"
+ wxptr = tp->array;
+ tp->nelem = nelem;
+ for(i = 0; i < nelem; i++) { *(wxptr++) = NULL; }
+ if(dk3sto_add(sStringTables, (void *)tp)) { $? ". add ok"
+ ok = 1;
+ oldsource = dk3app_get_source_file(app);
+ oldline = dk3app_get_source_line(app);
+ dk3app_set_source_file(app, fnb);
+ dk3app_set_source_line(app, 0UL);
+ lineno = 0UL;
+ wxptr = tp->array; nelem = 0;
+ do { $? ". loop start"
+ cc = 0;
+ if(fgets(il, sizeof(il), fipo)) { $? ". line ok"
+ dk3app_set_source_line(app, ++lineno);
+ cc = 1;
+ if(il[0] != '#') { $? ". no comment"
+ dk3app_squeeze_line(il);
+ if(dk3wxs_from_utf8(wxb,DK3_SIZEOF(wxb,wxChar),il))
+ {
+ *wxptr = dk3wxs_dup_app(wxb, app);
+ if(!(*wxptr)) { $? "! dup failed"
+ ok = 0;
+ }
+ wxptr++;
+ }
+ else
+ {
+ ok = 0; $? "! conversion failed"
+ }
+ } else { $? ". comment line"
+ }
+ if(nelem >= tp->nelem) { cc = 0; }
+ } else { $? "! no more lines"
+ }
+ } while((cc) && (ok));
+ if(nelem < tp->nelem) {
+ ok = 0;
+ }
+ dk3app_set_source_file(app, oldsource);
+ dk3app_set_source_line(app, oldline);
+ } else { $? "! add failed"
+ }
+ } else { $? "! array allocation failed"
+ }
+ } else { $? "! dup failed for name"
+ }
+ if(ok) {
+ back = (wxChar const * const *)(tp->array);
+ } else {
+ dkwxah_string_table_close(tp);
+ }
+ } else { $? "! allocation failed"
+ }
+ } else { $? "! defaults array empty"
+ }
+ fclose(fipo);
+ } else { $? "! fopen"
+ }
+ } else { $? "! not found"
+ }
+ } else { $? ". found in storage"
+ }
+ if(tp) { $? ". have entry"
+ back = (wxChar const * const *)(tp->array);
+ }
+ } else { $? "! setup"
+ }
+ } else { $? "! args"
+ }
+ if(!(back)) {
+ back = dt;
+ } $? "- DkWxAppHelper::getStringTable PTR=%d", TR_IPTR(back)
+#else
+ dkChar fnb[DK3_MAX_PATH]; /* Full file name. */
+ char il[4096]; /* Input line */
+ wxChar wxb[sizeof(il)];
+ wxChar const * const *back = NULL;
+ DkAppHelperWxStringTable *tp; /* String table if exists. */
+ wxChar const * *wxptr; /* Traverse dt array. */
+ FILE *fipo; /* Read input file. */
+#if VERSION_BEFORE_20150821
+ unsigned long lineno; /* Current line. */
+#endif
+ size_t nelem; /* Number of elements in dt. */
+ size_t i; /* Current string to process. */
+ int res; /* Search result. */
+ int cc; /* Flag: Can continue. */
+ int ok; /* Flag: All strings read succes. */
+ $? "+ getStringTable"
+ if((dt) && (tn)) { $? ". args ok"
+ if(checkSetup()) { $? ". controller setup ok"
+ tp = (DkAppHelperWxStringTable *)dk3sto_it_find_like(
+ iStringTables, (void *)tn, 1
+ );
+ if(!(tp)) { $? ". table not yet found, must read"
+ res = dk3app_find_data_file(app,tn,fnb,DK3_SIZEOF(fnb,dkChar));
+ $? ". res = %d", res
+ if(res) { $? ". file found"
+ fipo = dk3sf_fopen_app(fnb, dk3app_not_localized(22), app);
+ if(fipo) { $? ". file opened"
+ wxptr = (wxChar const **)dt; nelem = 0;
+ while(*(wxptr++)) { nelem++; }
+ if(nelem) {
+ tp = dk3_new_app(DkAppHelperWxStringTable,1,app);
+ if(tp) {
+ tp->array = NULL;
+ tp->nelem = nelem;
+ tp->name = NULL;
+ tp->name = dk3str_dup_app(tn, app);
+ if(tp->name) {
+ tp->array = dk3_new_app(wxConstPtr,nelem,app);
+ if(tp->array) {
+ wxptr = tp->array;
+ tp->nelem = nelem;
+ for(i = 0; i < nelem; i++) { *(wxptr++) = NULL; }
+ wxptr = tp->array; nelem = 0;
+#if VERSION_BEFORE_20150821
+ lineno = 0UL;
+#endif
+#if VERSION_BEFORE_20150821
+ cc = 1;
+#endif
+ ok = 1;
+ do {
+ cc = 0;
+ if(fgets(il, sizeof(il), fipo)) {
+ cc = 1; $? ". line \"%!8s\"", il
+ if(il[0] != '#') { $? ". no comment"
+ dk3app_squeeze_line(il);
+ if(dk3wxs_from_utf8(wxb,DK3_SIZEOF(wxb,wxChar),il)) {
+ *wxptr = dk3wxs_dup_app(wxb, app);
+ if(*wxptr) {
+ nelem++;
+ if(nelem >= tp->nelem) {
+ cc = 0;
+ }
+ } else {
+ ok = 0; cc = 0;
+ }
+ wxptr++;
+ } else { $? "! conversion failed"
+ ok = 0; cc = 0;
+ }
+ } else { $? ". comment"
+ }
+ }
+ } while(cc);
+ if(nelem < tp->nelem) {
+ ok = 0; $? "! too few elements"
+ }
+ if(ok) { $? ". success so far"
+ if(!dk3sto_add(sStringTables, (void *)tp)) {
+ dkwxah_string_table_close(tp); $? "! memory"
+ tp = NULL;
+ }
+ } else { $? "! anything wrong"
+ dkwxah_string_table_close(tp);
+ tp = NULL;
+ }
+ } else {
+ dkwxah_string_table_close(tp);
+ tp = NULL;
+ }
+ } else {
+ dkwxah_string_table_close(tp);
+ tp = NULL;
+ }
+ } else { $? "! memory"
+ }
+ }
+ fclose(fipo);
+ } else { $? "! failed to open file"
+ }
+ } else { $? "! file not found"
+ }
+ }
+ if(tp) { $? ". table found"
+ back = (wxChar const * const *)(tp->array);
+ }
+ } else { $? "! controller setup not ok"
+ }
+ } else { $? "! invalid args"
+ }
+ if(!(back)) { $? "! no result, using default texts"
+ back = dt;
+ } $? "- getStringTable PTR=%d", TR_IPTR(back)
+#endif
+ return back;
+}
+
+
+size_t
+DkWxAppHelper::retrieveMultipleInts(
+ wxChar const * const *names,
+ int *values
+) const
+{
+ size_t back = 0;
+ wxChar const * const *nptr;
+ int *vptr;
+ long l;
+ $? "+ DkWxAppHelper::retrieveMultipleInts"
+ if((appName) && (vendorName) && (names) && (values)) {
+ wxConfig *conf = new wxConfig(appName, vendorName);
+ if(conf) {
+ nptr = names; vptr = values;
+ while(*nptr) {
+ l = 0L;
+ if(conf->Read(*nptr, &l)) {
+ *vptr = (int)l;
+ back++;
+ }
+ nptr++; vptr++;
+ }
+ delete(conf);
+ }
+ } $? "- DkWxAppHelper::retrieveMultipleInts %lu", (unsigned long)back
+ return back;
+}
+
+
+
+size_t
+DkWxAppHelper::retrieveMultipleLongs(
+ wxChar const * const *names,
+ long *values
+) const
+{
+ size_t back = 0;
+ wxChar const * const *nptr;
+ long *vptr;
+ long l;
+ $? "+ DkWxAppHelper::retrieveMultipleLongs"
+ if((appName) && (vendorName) && (names) && (values)) {
+ wxConfig *conf = new wxConfig(appName, vendorName);
+ if(conf) {
+ nptr = names; vptr = values;
+ while(*nptr) {
+ l = 0L;
+ if(conf->Read(*nptr, &l)) {
+ *vptr = l;
+ back++;
+ }
+ nptr++; vptr++;
+ }
+ delete(conf);
+ }
+ }
+ $? "- DkWxAppHelper::retrieveMultipleLongs %u", (unsigned)back
+ return back;
+}
+
+
+size_t
+DkWxAppHelper::retrieveMultipleDoubles(
+ wxChar const * const *names,
+ double *values
+) const
+{
+ size_t back = 0;
+ double d;
+ wxChar const * const *nptr;
+ double *vptr;
+ $? "+ DkWxAppHelper::retrieveMultipleDoubles"
+ if((appName) && (vendorName) && (names) && (values)) {
+ wxConfig *conf = new wxConfig(appName, vendorName);
+ if(conf) {
+ nptr = names; vptr = values;
+ while(*nptr) {
+ d = 0.0;
+ if(conf->Read(*nptr, &d)) {
+ *vptr = d;
+ back++;
+ }
+ nptr++; vptr++;
+ }
+ delete(conf);
+ }
+ } $? "- DkWxAppHelper::retrieveMultipleDoubles %u", (unsigned)back
+ return back;
+}
+
+
+size_t
+DkWxAppHelper::saveMultipleInts(
+ wxChar const * const *names,
+ int *values
+) const
+{
+ size_t back = 0;
+ wxChar const * const *nptr;
+ int *vptr;
+ long l;
+ $? "+ DkWxAppHelper::saveMultipleInts"
+ if((appName) && (vendorName) && (names) && (values)) {
+ wxConfig *conf = new wxConfig(appName, vendorName);
+ if(conf) { $? ". conf ok"
+ nptr = names; vptr = values;
+ while(*nptr) { $? ". write entry"
+ l = (long)(*vptr);
+ if(conf->Write(*nptr, l)) {
+ back++;
+ }
+ nptr++; vptr++;
+ }
+ delete(conf);
+ }
+ } $? "- DkWxAppHelper::saveMultipleInts %lu", (unsigned long)back
+ return back;
+}
+
+
+
+size_t
+DkWxAppHelper::saveMultipleLongs(
+ wxChar const * const *names,
+ long *values
+) const
+{
+ size_t back = 0;
+ wxChar const * const *nptr;
+ long *vptr;
+ long l;
+ $? "+ DkWxAppHelper::saveMultipleLongs"
+ if((appName) && (vendorName) && (names) && (values)) {
+ wxConfig *conf = new wxConfig(appName, vendorName);
+ if(conf) {
+ nptr = names; vptr = values;
+ while(*nptr) {
+ l = *vptr;
+ if(conf->Write(*nptr, l)) {
+ back++;
+ }
+ nptr++; vptr++;
+ }
+ delete(conf);
+ }
+ }
+ $? "- DkWxAppHelper::saveMultipleLongs %u", (unsigned)back
+ return back;
+}
+
+
+
+size_t
+DkWxAppHelper::saveMultipleDoubles(
+ wxChar const * const *names,
+ double *values
+) const
+{
+ size_t back = 0;
+ double d;
+ wxChar const * const *nptr;
+ double *vptr;
+ $? "+ DkWxAppHelper::saveMultipleDoubles"
+ if((appName) && (vendorName) && (names) && (values)) {
+ wxConfig *conf = new wxConfig(appName, vendorName);
+ if(conf) {
+ nptr = names; vptr = values;
+ while(*nptr) {
+ d = *vptr;
+ if(conf->Write(*nptr, d)) {
+ back++;
+ }
+ nptr++; vptr++;
+ }
+ delete(conf);
+ }
+ } $? "- DkWxAppHelper::saveMultipleDoubles %u", (unsigned)back
+ return back;
+}
+
+
+
+wxChar const *
+DkWxAppHelper::retrieveString(
+ wxChar const *name
+) const
+{
+ wxChar const *back = NULL;
+ wxChar const *ptr;
+ $? "+ DkWxAppHelper::retrieveString"
+ if((name) && (appName) && (vendorName)) {
+ wxConfig *conf = new wxConfig(appName, vendorName);
+ if(conf) {
+ wxString str;
+ if(conf->Read(name, &str)) {
+ ptr = str.c_str();
+ if(ptr) {
+ back = dk3wxs_dup_app(ptr, app);
+ }
+ }
+ delete(conf);
+ }
+ } $? "- DkWxAppHelper::retrieveString PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+int
+DkWxAppHelper::saveString(
+ wxChar const *name,
+ wxChar const *value
+) const
+{
+ int back = 0;
+ $? "+ DkWxAppHelper::saveString"
+ if((name) && (value) && (appName) && (vendorName)) {
+ wxConfig *conf = new wxConfig(appName, vendorName);
+ if(conf) {
+ conf->Write(name, value);
+ delete(conf);
+ }
+ } $? "- DkWxAppHelper::saveString %d", back
+ return back;
+}
+
+
+
+int
+DkWxAppHelper::getWxEncoding() const
+{
+ $? "= getWxEncoding %d", wxEncoding
+ return wxEncoding;
+}
+
+
+
+int
+DkWxAppHelper::getDkEncoding() const
+{
+ $? "= getDkEncoding %d", dkEncoding
+ return dkEncoding;
+}
+
+
+
+int
+DkWxAppHelper::getC8Encoding() const
+{
+ int back;
+ $? "+ DkWxAppHelper::getC8Encoding"
+ back = dkEncoding;
+ if(DK3_ENCODING_UTF8 != back) {
+ back = DK3_ENCODING_PLAIN;
+ } $? "- DkWxAppHelper::getC8Encoding %d", back
+ return back;
+}
+
+
+
+dk3_app_t *
+DkWxAppHelper::getApp() const
+{
+ $? "= DkWxAppHelper::getApp PTR=%d", TR_IPTR(app)
+ return app;
+}
+
+
+
+int
+DkWxAppHelper::findDataFile(wxChar const *fn, wxChar *fnb, size_t szfnb)
+{
+ dkChar shnDk[DK3_MAX_PATH];
+ dkChar ffnDk[DK3_MAX_PATH];
+ int back = 0;
+ $? "+ findDataFile"
+ if((fn) && (fnb) && (szfnb)) { $? ". args ok"
+ if(checkSetup()) { $? ". setup ok"
+ if(dk3wxs_to_dkstr(
+ shnDk, DK3_SIZEOF(shnDk,dkChar), dkEncoding, fn, wxEncoding
+ )
+ )
+ {
+ if(app) { $? ". app available"
+ if(dk3app_find_data_file(app,shnDk,ffnDk,DK3_SIZEOF(ffnDk,dkChar))) {
+ if(dk3wxs_from_dkstr(fnb, szfnb, wxEncoding, ffnDk, dkEncoding)) {
+ back = 1; $? ". found"
+ } else { $? "! conversion failed"
+ }
+ } else { $? "! not found"
+ }
+ } else { $? "! no app"
+ }
+ } else { $? "! conversion failed"
+ }
+ }
+ } $? "- findDataFile %d", back
+ return back;
+}
+
+
+
+wxChar const *
+DkWxAppHelper::getBasicString(size_t i) const
+{
+ wxChar const *back = NULL;
+ $? "+ DkWxAppHelper::getBasicString"
+ if(basicStrings) {
+ if(i < nBasicStrings) {
+ back = basicStrings[i];
+ }
+ } $? "- DkWxAppHelper::getBasicString PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+wxChar const * const *
+DkWxAppHelper::getBasicStrings() const
+{
+ $? "= DkWxAppHelper::getBasicStrings PTR=%d", TR_IPTR(basicStrings)
+ return basicStrings;
+}
+
+
+
+size_t
+DkWxAppHelper::getBasicStringNumbers() const
+{
+ $? "= DkWxAppHelper::getBasicStringNumbers %u", (unsigned)nBasicStrings
+ return nBasicStrings;
+}
+
+
+
+bool
+DkWxAppHelper::wxToDk(dkChar *bu, size_t sz, wxChar const *src) const
+{
+ bool back = false;
+ $? "+ DkWxAppHelper::wxToDk"
+ if((bu) && (sz) && (src)) {
+ if(dk3wxs_to_dkstr(bu, sz, dkEncoding, src, wxEncoding)) {
+ back = true;
+ }
+ } $? "- DkWxAppHelper::wxToDk %d", ((back) ? 1 : 0)
+ return back;
+}
+
+
+
+bool
+DkWxAppHelper::wxToC8(char *bu, size_t sz, wxChar const *src) const
+{
+ bool back = false;
+ $? "+ DkWxAppHelper::wxToC8"
+ if((bu) && (sz) && (src)) {
+ if(dk3wxs_to_c8(bu, sz, getC8Encoding(), src, wxEncoding)) {
+ back = true;
+ }
+ } $? "- DkWxAppHelper::wxToC8 %d", (back ? 1 : 0)
+ return back;
+}
+
+
+
+bool
+DkWxAppHelper::wxToC8(char *bu, size_t sz, wxString & str) const
+{
+ bool back = false;
+ wxChar const *ptr;
+ $? "+ DkWxAppHelper::wxToC8"
+ if((bu) && (sz)) {
+ ptr = str.c_str();
+ if(ptr) {
+ back = wxToC8(bu, sz, ptr);
+ }
+ } $? "- DkWxAppHelper::wxToC8 %d", ((back) ? 1 : 0)
+ return back;
+}
+
+
+
+bool
+DkWxAppHelper::dkToWx(wxChar *bu, size_t sz, dkChar const *src) const
+{
+ bool back = false;
+ $? "+ DkWxAppHelper::dkToWx"
+ if((bu) && (sz) && (src)) {
+ if(dk3wxs_from_dkstr(bu, sz, wxEncoding, src, dkEncoding)) {
+ back = true;
+ }
+ } $? "- DkWxAppHelper::dkToWx %d", ((back) ? 1 : 0)
+ return back;
+}
+
+
+void
+DkWxAppHelper::setRelatedPosition(
+ wxWindow *parent,
+ wxWindow *child,
+ int *pcx,
+ int *pcy
+) const
+{
+ int px = 0; /* Parent x position. */
+ int py = 0; /* Parent y position. */
+ int pw = 0; /* Parent width. */
+ int ph = 0; /* Parent height. */
+ int cx = 0; /* Child x position. */
+ int cy = 0; /* Child y position. */
+ int cw = 0; /* Child width. */
+ int ch = 0; /* Child height. */
+ wxSize scsz; /* Screen size. */
+
+ scsz = wxGetDisplaySize();
+ parent->GetPosition(&px, &py);
+ parent->GetSize(&pw, &ph);
+ child->GetSize(&cw, &ch);
+ cx = px + (pw - cw) / 2;
+ cy = py + (ph - ch) / 2;
+ if((cx + cw) > scsz.x) {
+ cx = scsz.x - cw;
+ }
+ if((cy + ch) > scsz.y) {
+ cy = scsz.y - ch;
+ }
+ if(cx < 0) {
+ cx = 0;
+ }
+ if(cy < 0) {
+ cy = 0;
+ }
+ if((pcx) && (pcy)) {
+ if(((*pcx) >= 0) && ((*pcy) >= 0)) {
+ cx = *pcx;
+ cy = *pcy;
+ }
+ }
+ child->SetSize(cx, cy, cw, ch);
+}
+
+
+void
+DkWxAppHelper::reportProblemsIfAny(void)
+{
+ bool didReport = false;
+
+ if (!didReport) {
+ if (NULL == app) {
+ didReport = true;
+ switch (errorCode) {
+ case ERROR_ENCODE_ARG0 : {
+ /* ERROR: Failed to encode arg0 to dkChar */
+ showErrorMessage(3, 12);
+ } break;
+ default : {
+ /* ERROR: Failed to initialize application structure */
+ showErrorMessage(3, 11);
+ } break;
+ }
+ }
+ }
+ if (!didReport) {
+ if (NULL != app) {
+ if ((NULL == sStringTables) || (NULL == iStringTables)) {
+ didReport = true;
+ /* ERROR: Memory */
+ showErrorMessage(3, 9);
+ }
+ }
+ }
+ if (!didReport) {
+ if ((NULL == cmdName) || (NULL == appName) || (NULL == vendorName)) {
+ didReport = true;
+ /* ERROR: Memory */
+ showErrorMessage(3, 9);
+ }
+ }
+}
+
+
+
+void
+DkWxAppHelper::showErrorMessage(size_t i_title, size_t i_text)
+{
+ const wxChar *str_title = NULL;
+ const wxChar *str_text = NULL;
+ if (NULL != basicStrings) {
+ str_title = basicStrings[i_title];
+ str_text = basicStrings[i_text];
+ } else {
+ str_title = dkwxapphelper_defwxappstr[i_title];
+ str_text = dkwxapphelper_defwxappstr[i_text];
+ }
+ wxMessageBox(str_text, str_title, (wxOK | wxCENTRE | wxICON_ERROR));
+}
+
+
+
diff --git a/support/dktools/DkWxAppHelper.h b/support/dktools/DkWxAppHelper.h
new file mode 100644
index 0000000000..c4ec96724e
--- /dev/null
+++ b/support/dktools/DkWxAppHelper.h
@@ -0,0 +1,369 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxAppHelper.cpt
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxAppHelper.h Header file for the DkWxAppHelper module.
+*/
+
+#ifndef DKWXAPPHELPER_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DKWXAPPHELPER_H_INCLUDED 1
+
+
+#line 10 "DkWxAppHelper.cpt"
+
+#if 0
+#include <dk3all.h>
+#else
+#include <dk3conf.h>
+#include <dk3types.h>
+#include <dk3const.h>
+#endif
+
+
+
+#include <wx/wxprec.h>
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#include <wx/wx.h>
+#endif
+#include <wx/config.h>
+#include <wx/filename.h>
+
+/** Application helper class, provides file search, internationalization
+ and some functions for GUI development using the wxWidgets libraries.
+*/
+class DkWxAppHelper
+{
+ protected:
+
+ /** Application structure.
+ */
+ dk3_app_t *app;
+
+ /** Storage for string tables.
+ */
+ dk3_sto_t *sStringTables;
+
+ /** Iterator through string tables storage.
+ */
+ dk3_sto_it_t *iStringTables;
+
+ /** Basic strings used by wxWidgets applications.
+ */
+ wxChar const * const *basicStrings;
+
+ /** First command line argument.
+ */
+ wxChar const *cmdName;
+
+ /** Application name.
+ */
+ wxChar const *appName;
+
+ /** Software vendor name.
+ */
+ wxChar const *vendorName;
+
+ /** Number of entries in the basicStrings array.
+ */
+ size_t nBasicStrings;
+
+ /** Encoding for dkChar.
+ */
+ int dkEncoding;
+
+ /** Encoding for wxChar.
+ */
+ int wxEncoding;
+
+ /** Code for errors from constructor.
+ */
+ int errorCode;
+
+ protected:
+
+ /** Report problems within the constructor, if any.
+ */
+ void
+ reportProblemsIfAny(void);
+
+ /** Show an error message.
+ @param i_title Index of dialog title in basic strings.
+ @param i_text Index of message text in basic strings.
+ */
+ void
+ showErrorMessage(size_t i_title, size_t i_text);
+
+ public:
+
+ /** Constructor.
+ @param arg0 First command line argument.
+ @param vName Software vendor name.
+ @param groupName Application group name.
+ */
+ DkWxAppHelper(
+ wxChar const *arg0,
+ wxChar const *vName,
+ dkChar const *groupName
+ );
+
+ /** Destructor.
+ */
+ ~DkWxAppHelper();
+
+ /** Check whether application helper object is set up correctly
+ and is ready to use.
+ @return 1 on success, 0 on error.
+ */
+ int
+ checkSetup() const;
+
+ /** Retrieve array of localized texts.
+ @param dt Default texts, used if problems occur.
+ @param tn Table name.
+ @return Pointer to localized messages array or dt.
+ */
+ wxChar const * const *
+ getStringTable(
+ wxChar const * const *dt,
+ dkChar const *tn
+ );
+
+ /** Find data file name. Provide a short file name like "x.y",
+ on success the program writes a full path like
+ "/usr/share/myapp/en/x.y" to the result buffer.
+ @param fn Short file name.
+ @param fnb Buffer for full path name.
+ @param szfnb Size of @arg fnb (number of wxChar).
+ @return 1 on success, 0 on error.
+ */
+ int
+ findDataFile(wxChar const *fn, wxChar *fnb, size_t szfnb);
+
+ /** Retrieve multiple int settings at once.
+ @param names Pointer to names array, must be terminated
+ by a NULL pointer.
+ @param values Pointer to destination value array.
+ @return Number of items read successfully.
+ */
+ size_t
+ retrieveMultipleInts(
+ wxChar const * const *names,
+ int *values
+ ) const;
+
+ /** Retrieve multiple long settings at once.
+ @param names Pointer to names array, must be terminated
+ by a NULL pointer.
+ @param values Pointer to destination value array.
+ @return Number of items read successfully.
+ */
+ size_t
+ retrieveMultipleLongs(
+ wxChar const * const *names,
+ long *values
+ ) const;
+
+ /** Save multiple int settings at once.
+ @param names Pointer to names array, must be terminated by
+ a NULL pointer.
+ @param values Pointer to values array.
+ @return Number of items successfully written.
+ */
+ size_t
+ saveMultipleInts(
+ wxChar const * const *names,
+ int *values
+ ) const;
+
+ /** Save multiple long settings at once.
+ @param names Pointer to names array, must be terminated by
+ a NULL pointer.
+ @param values Pointer to values array.
+ @return Number of items successfully written.
+ */
+ size_t
+ saveMultipleLongs(
+ wxChar const * const *names,
+ long *values
+ ) const;
+
+ /** Retrieve multiple double settings at once.
+ @param names Pointer to names array, must be terminated by
+ a NULL pointer.
+ @param values Pointer to values array.
+ @return Number of items successfully read.
+ */
+ size_t
+ retrieveMultipleDoubles(
+ wxChar const * const *names,
+ double *values
+ ) const;
+
+ /** Save multiple doubles at once.
+ @param names Pointer to names array, must be terminated by
+ a NULL pointer.
+ @param values Pointer to values array.
+ @return Number of items successfully written.
+ */
+ size_t
+ saveMultipleDoubles(
+ wxChar const * const *names,
+ double *values
+ ) const;
+
+ /** Retrieve a string preference.
+ @param name Preference name.
+ @return Pointer to new string on success, NULL on error.
+ */
+ wxChar const *
+ retrieveString(
+ wxChar const *name
+ ) const;
+
+ /** Save a string entry.
+ @param name Entry name.
+ @param value Entry value.
+ @return 1 on success, 0 on error.
+ */
+ int
+ saveString(
+ wxChar const *name,
+ wxChar const *value
+ ) const;
+
+ /** Retrieve encoding for wxChar.
+ @return Encoding used for wxChar.
+ */
+ int
+ getWxEncoding() const;
+
+ /** Retrieve encoding for dkChar.
+ @return Encoding used for dkChar.
+ */
+ int
+ getDkEncoding() const;
+
+ /** Retrieve encoding to use for 8 bit characters.
+ @return Encoding to use for 8 bit character strings.
+ */
+ int
+ getC8Encoding() const;
+
+ /** Retrieve application structure.
+ @return Application structure on success, NULL on error.
+ */
+ dk3_app_t *
+ getApp() const;
+
+ /** Get one of the basic application strings.
+ @param i Index of string in array.
+ @return String pointer on success or NULL on error.
+ */
+ wxChar const *
+ getBasicString(size_t i) const;
+
+ /** Get basic strings array.
+ @return Array pointer to basic strings.
+ */
+ wxChar const * const *
+ getBasicStrings() const;
+
+ /** Find number of basic strings stored in the \a basicStrings array.
+ @return Number of strings in the array.
+ */
+ size_t
+ getBasicStringNumbers() const;
+
+ /** Convert wxChar string to dkChar string.
+ @param bu Destination buffer.
+ @param sz Destination buffer size (number of dkChar).
+ @param src Source buffer.
+ @return true on success, false on error.
+ */
+ bool
+ wxToDk(dkChar *bu, size_t sz, wxChar const *src) const;
+
+ /** Convert wxChar string to 8-bit char string.
+ @param bu Destination buffer.
+ @param sz Destination buffer size.
+ @param src Source buffer.
+ @return true on success, false on error.
+ */
+ bool
+ wxToC8(char *bu, size_t sz, wxChar const *src) const;
+
+ /** Convert wxChar string to 8-bit char string.
+ @param bu Destination buffer.
+ @param sz Destination buffer size.
+ @param str Source string.
+ @return true on success, false on error.
+ */
+ bool
+ wxToC8(char *bu, size_t sz, wxString & str) const;
+
+ /** Convert dkChar string to wxChar string.
+ @param bu Destination buffer.
+ @param sz Destination buffer size (number of wxChar).
+ @param src Source buffer.
+ @return true on success, false on error.
+ */
+ bool
+ dkToWx(wxChar *bu, size_t sz, dkChar const *src) const;
+
+ /** Set related position (child over parent), the child
+ is either placed on a known previous position or placed
+ centered on top of the parent.
+ @param parent Parent top level window (frame).
+ @param child Child top level window (dialog).
+ @param pcx Pointer to previous child x position.
+ @param pcy Pointer to previous child y position.
+ */
+ void
+ setRelatedPosition(
+ wxWindow *parent,
+ wxWindow *child,
+ int *pcx = NULL,
+ int *pcy = NULL
+ ) const;
+
+};
+
+
+
+
+#endif
diff --git a/support/dktools/DkWxBmepsApp.cpp b/support/dktools/DkWxBmepsApp.cpp
new file mode 100644
index 0000000000..30c27651db
--- /dev/null
+++ b/support/dktools/DkWxBmepsApp.cpp
@@ -0,0 +1,655 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxBmepsApp.cpt
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxBmepsApp.cpp The DkWxBmepsApp module.
+*/
+
+
+#line 47 "DkWxBmepsApp.cpt"
+
+
+#include "wxbmeps.h"
+
+
+
+
+#line 53 "DkWxBmepsApp.cpt"
+
+
+/** Implementation of DkWxBmepsApp.
+*/
+IMPLEMENT_APP(DkWxBmepsApp)
+
+
+
+/** Default texts, replaced by localized versions.
+*/
+wxChar const * const defaultTexts[] = {
+/* 0 */
+wxT("wxbmpp"),
+
+/* 1 */
+wxT("dktools"),
+
+/* 2 */
+wxT("Dirk Krause"),
+
+/* 3 */
+wxT(""),
+
+/* 4 */
+wxT("Directory"),
+
+/* 5 */
+wxT("Choose the directory to process"),
+
+/* 6 */
+wxT("Options"),
+
+/* 7 */
+wxT("Set conversion options"),
+
+/* 8 */
+wxT("Run"),
+
+/* 9 */
+wxT("Run conversion"),
+
+/* 10 */
+wxT("Exit"),
+
+/* 11 */
+wxT("Exit the application"),
+
+/* 12 */
+wxT("&File"),
+
+/* 13 */
+wxT("&Help"),
+
+/* 14 */
+wxT("&Directory...\tAlt-D"),
+
+/* 15 */
+wxT("Choose directory"),
+
+/* 16 */
+wxT("&Options\tAlt-O"),
+
+/* 17 */
+wxT("Conversion options"),
+
+/* 18 */
+wxT("&Run\tAlt-R"),
+
+/* 19 */
+wxT("Run conversion"),
+
+/* 20 */
+wxT("E&xit\tAlt-X"),
+
+/* 21 */
+wxT("Exit the application"),
+
+/* 22 */
+wxT("&Contents\tF1"),
+
+/* 23 */
+wxT("Show table of contents"),
+
+/* 24 */
+wxT("&About\tAlt-A"),
+
+/* 25 */
+wxT("Show version number"),
+
+/* 26 */
+wxT("Directory: "),
+
+/* 27 */
+wxT(""),
+
+/* 28 */
+wxT(""),
+
+/* 29 */
+wxT("Choose Directory"),
+
+/* 30 */
+wxT("Processing succeeded, application will exit."),
+
+/* 31 */
+wxT("Automatic run canceled due to errors!"),
+
+/* 32 */
+wxT("Conversion progress"),
+
+/* 33 */
+wxT("Cancel"),
+
+/* 34 */
+wxT("Abort conversion after finishing current file"),
+
+/* 35 */
+wxT("Cancel command scheduled... wait, please!"),
+
+/* 36 */
+wxT("Conversion Options"),
+
+/* 37 */
+wxT("General"),
+
+/* 38 */
+wxT("Make mode"),
+
+/* 39 */
+wxT("Run conversion only if destination file is not up to date."),
+
+/* 40 */
+wxT("Output"),
+
+/* 41 */
+wxT("Output format:"),
+
+/* 42 */
+wxT("PS"),
+
+/* 43 */
+wxT("EPS"),
+
+/* 44 */
+wxT("PDF"),
+
+/* 45 */
+wxT("Bounding Box"),
+
+/* 46 */
+wxT("Output mode:"),
+
+/* 47 */
+wxT("Image"),
+
+/* 48 */
+wxT("Object"),
+
+/* 49 */
+wxT("Document"),
+
+/* 50 */
+wxT("Finishing:"),
+
+/* 51 */
+wxT("Single-side"),
+
+/* 52 */
+wxT("Duplex (book)"),
+
+/* 53 */
+wxT("Duplex (calendar)"),
+
+/* 54 */
+wxT("Draft mode"),
+
+/* 55 */
+wxT("Create placeholder image only"),
+
+/* 56 */
+wxT("Color"),
+
+/* 57 */
+wxT("Enable colored output"),
+
+/* 58 */
+wxT("Output size"),
+
+/* 59 */
+wxT("Resolution:"),
+
+/* 60 */
+wxT("1px=1pt"),
+
+/* 61 */
+wxT("input file"),
+
+/* 62 */
+wxT("as specified:"),
+
+/* 63 */
+wxT("Paper size:"),
+
+/* 64 */
+wxT("Image quality"),
+
+/* 65 */
+wxT("Image interpolation"),
+
+/* 66 */
+wxT("Enable image interpolation"),
+
+/* 67 */
+wxT("Image interpolation for JPEG files"),
+
+/* 68 */
+wxT("Enable image interpolation for JPEG files too"),
+
+/* 69 */
+wxT("Transparency"),
+
+/* 70 */
+wxT("Background color:"),
+
+/* 71 */
+wxT("Force background color"),
+
+/* 72 */
+wxT("Always use the specified background color, ignore background color chunks"),
+
+/* 73 */
+wxT("Output format details"),
+
+/* 74 */
+wxT("PS level:"),
+
+/* 75 */
+wxT("Predictor:"),
+
+/* 76 */
+wxT("None"),
+
+/* 77 */
+wxT("TIFF"),
+
+/* 78 */
+wxT("PNG-SUB"),
+
+/* 79 */
+wxT("PNG-UP"),
+
+/* 80 */
+wxT("PNG-AVERAGE"),
+
+/* 81 */
+wxT("PNG-PAETH"),
+
+/* 82 */
+wxT("DSC"),
+
+/* 83 */
+wxT("Write DSC comments to PS output"),
+
+/* 84 */
+wxT("OK"),
+
+/* 85 */
+wxT("Confirm settings, leave this dialog box"),
+
+/* 86 */
+wxT("Cancel"),
+
+/* 87 */
+wxT("Discard settings, leave this dialog box"),
+
+/* 88 */
+wxT("Click to change the default background color"),
+
+/* 89 */
+wxT("Re-use JPEG DCT data"),
+
+/* 90 */
+wxT("Allow direct re-use of DCT compressed data from JPEG files instead of decoding and re-encoding it"),
+
+/* 91 */
+wxT("Choose an output format: PS / EPS / PDF or Bounding Box"),
+
+/* 92 */
+wxT("Choose an output type: Image for standalone viewing / Object for use with LaTeX / Document for print jobs or multipage images"),
+
+/* 93 */
+wxT("Choose finishing: Single-sided / Duplex like a book / Duplex like a calendar"),
+
+/* 94 */
+wxT("Choose resolution handling: 1 pixel = 1 PS point / Specify a resolution / Fit image to a paper size"),
+
+/* 95 */
+wxT("Choose a paper size. Difference between A4 and a4: A4 uses the entire page without leaving a border, a4 leaves some border unused"),
+
+/* 96 */
+wxT("Choose a PS level (2 or 3)"),
+
+/* 97 */
+wxT("Choose a predictor for flate compression"),
+
+/* 98 */
+wxT("Specify the resolution in dpi"),
+
+/* 99 */
+wxT("Setup...\tAlt-S"),
+
+/* 100 */
+wxT("Set conversion options"),
+
+/* 101 */
+wxT("Reset...\tAlt-R"),
+
+/* 102 */
+wxT("Reset conversion options to default values"),
+
+/* 103 */
+wxT("Do you really want to reset all conversion options to default values?"),
+
+/* 104 */
+wxT("Are you sure?"),
+
+/* 105 */
+wxT("Not enough memory!"),
+
+/* 106 */
+wxT("Processing directory \""),
+
+/* 107 */
+wxT("\" (start)."),
+
+/* 108 */
+wxT("Processing directory \""),
+
+/* 109 */
+wxT("\" (finished)."),
+
+/* 110 */
+wxT("\n"),
+
+/* 111 */
+wxT("File name too long:\n\""),
+
+/* 112 */
+wxT("\"!"),
+
+/* 113 */
+wxT("No conversion candidate files found!"),
+
+/* 114 */
+wxT("Processing file \""),
+
+/* 115 */
+wxT("\"."),
+
+/* 116 */
+wxT("Processing file \""),
+
+/* 117 */
+wxT("\" (finished)."),
+
+/* 118 */
+wxT("File name \""),
+
+/* 119 */
+wxT("\" contains unconvertable characters!"),
+
+/* 120 */
+wxT("Reduce bits per components"),
+
+/* 121 */
+wxT("Reduce bits per components if possible"),
+
+/* 122 */
+wxT("About wxbmpp"),
+
+/* 123 */
+wxT("This program uses libraries from the following projects:\n"),
+
+/* 124 */
+wxT("See:"),
+
+NULL
+
+
+#line 548 "DkWxBmepsApp.cpt"
+};
+
+
+/** Constant texts, not localized.
+*/
+static wxChar const * const wxbmpp_nl_wx[] = {
+/* 0 */
+wxT("Error"),
+
+/* 1 */
+wxT("Not enough memory (RAM)!"),
+
+NULL
+
+
+#line 558 "DkWxBmepsApp.cpt"
+};
+
+/** Application group name.
+*/
+static dkChar const dkwxbmepsapp_groupname[] = { dkT("dktools") };
+
+
+
+/** Name for string table file to load.
+*/
+static dkChar const dkwxbmeps_string_table_name[] = { dkT("wxbmpp.str") };
+
+
+
+/** Help file to be used on Windows systems.
+*/
+static wxChar const dkwxbmeps_chm_helpfile[] = { wxT("wxbmpp.chm") };
+
+
+
+/** Help file to be used on non-Windows systems.
+*/
+static wxChar const dkwxbmeps_htb_helpfile[] = { wxT("wxbmpp.htb") };
+
+
+
+bool
+DkWxBmepsApp::OnInit()
+{
+ bool back = false;
+ wxChar const * const *localizedTexts = defaultTexts;
+ dkChar const * const *msg = NULL;
+ DkWxBmepsFrame *frame = NULL;
+ wxPNGHandler *phPng = NULL;
+ wxXPMHandler *phXpm = NULL;
+ wxICOHandler *phIco = NULL;
+ wxZipFSHandler *phZipFs = NULL;
+
+
+
+#line 597 "DkWxBmepsApp.cpt"
+
+
+#line 598 "DkWxBmepsApp.cpt"
+
+ /* Initialize elements.
+ */
+ pHelper = NULL;
+ helpController = NULL;
+
+ /* Get elements.
+ */
+ pHelper = new DkWxAppHelper(argv[0],defaultTexts[2],dkwxbmepsapp_groupname);
+ if (NULL == pHelper) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ if (!(pHelper->checkSetup())) {
+ goto finished;
+ }
+ msg = dk3app_messages(
+ pHelper->getApp(),
+ dk3bmep_str_get_string_table_name(),
+ (dkChar const **)dk3bmep_str_get_message_texts()
+ );
+ if (NULL == msg) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ localizedTexts =
+ pHelper->getStringTable(defaultTexts, dkwxbmeps_string_table_name);
+ if (NULL == localizedTexts) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ /* Set image and zip fs handler for online help.
+ */
+ phPng = new wxPNGHandler();
+ if (NULL != phPng) {
+ wxImage::AddHandler(phPng);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phXpm = new wxXPMHandler();
+ if (NULL != phXpm) {
+ wxImage::AddHandler(phXpm);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phIco = new wxICOHandler();
+ if (NULL != phIco) {
+ wxImage::AddHandler(phIco);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phZipFs = new wxZipFSHandler();
+ if (NULL != phZipFs) {
+ wxFileSystem::AddHandler(phZipFs);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ /* Get help controller
+ */
+ helpController =
+ new DkWxHelpController(pHelper,dkwxbmeps_chm_helpfile,dkwxbmeps_htb_helpfile);
+ if (NULL == helpController) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ /* Create frame.
+ */
+ frame = new DkWxBmepsFrame(
+ defaultTexts[0], localizedTexts, msg, pHelper, DkWxBmeps_MainWindow,
+ helpController, argc, argv
+ );
+ if (NULL == frame) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ /* Show frame and inidicate success.
+ */
+ frame->Show();
+ frame->restorePosition();
+ back = true;
+
+ /* Clean up on problems.
+ */
+ finished:
+ if (!(back)) {
+ if (NULL != helpController) {
+ delete(helpController);
+ helpController = NULL;
+ }
+ if (NULL != pHelper) {
+ delete(pHelper);
+ pHelper = NULL;
+ }
+ }
+
+
+
+#line 702 "DkWxBmepsApp.cpt"
+ return back;
+}
+
+
+
+int
+DkWxBmepsApp::OnExit()
+{
+ int back = 0;
+
+
+#line 712 "DkWxBmepsApp.cpt"
+ /*
+ Release elements.
+ */
+ if(helpController) {
+ delete(helpController); helpController = NULL;
+ }
+ if(pHelper) {
+ delete(pHelper); pHelper = NULL;
+ }
+
+
+#line 722 "DkWxBmepsApp.cpt"
+
+
+#line 723 "DkWxBmepsApp.cpt"
+ return back;
+}
+
+
+
+void
+DkWxBmepsApp::ShowMemoryErrorMessage(void)
+{
+ const wxChar *s_title = NULL;
+ const wxChar *s_text = NULL;
+
+ if (NULL != pHelper) {
+ s_title = pHelper->getBasicString(3);
+ s_text = pHelper->getBasicString(9);
+ }
+ if (NULL == s_title) {
+ s_title = wxbmpp_nl_wx[0];
+ }
+ if (NULL == s_text) {
+ s_text = wxbmpp_nl_wx[1];
+ }
+ wxMessageBox(s_text, s_title, (wxOK | wxCENTRE | wxICON_ERROR));
+}
+
diff --git a/support/dktools/DkWxBmepsApp.cpt b/support/dktools/DkWxBmepsApp.cpt
new file mode 100644
index 0000000000..2755bcdbd3
--- /dev/null
+++ b/support/dktools/DkWxBmepsApp.cpt
@@ -0,0 +1,746 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% header
+
+/** Application class for wxbmeps.
+*/
+class DkWxBmepsApp : public wxApp
+{
+ protected:
+
+ /** Helper object.
+ */
+ DkWxAppHelper *pHelper;
+
+ /** Help controller.
+ */
+ DkWxHelpController *helpController;
+
+ protected:
+
+ /** Show error message if there is not sufficient memory available.
+ */
+ void
+ ShowMemoryErrorMessage(void);
+
+ public:
+ /** Initialize application.
+ */
+ virtual bool OnInit();
+
+ /** Clean up after running.
+ */
+ virtual int OnExit();
+};
+
+DECLARE_APP(DkWxBmepsApp)
+
+
+
+%% module
+
+
+#include "wxbmeps.h"
+
+
+$!trace-include
+
+
+/** Implementation of DkWxBmepsApp.
+*/
+IMPLEMENT_APP(DkWxBmepsApp)
+
+
+
+/** Default texts, replaced by localized versions.
+*/
+wxChar const * const defaultTexts[] = {
+$!string-table macro=wxT
+#
+# 0: Program name
+#
+wxbmpp
+#
+# 1: Application group name
+#
+dktools
+#
+# 2: Software vendor name
+#
+Dirk Krause
+#
+# 3: Empty text.
+#
+
+#
+# 4: Toolbar button text: Directory
+#
+Directory
+#
+# 5: Toolbar button tip text: Choose the directory to process.
+#
+Choose the directory to process
+#
+# 6: Toolbar button text: Options
+#
+Options
+#
+# 7: Toolbar button tip text: Set conversion options.
+#
+Set conversion options
+#
+# 8: Toolbar button text: Run
+#
+Run
+#
+# 9: Toolbar button tip text: Run conversion
+#
+Run conversion
+#
+# 10: Toolbar button text: Exit
+#
+Exit
+#
+# 11: Toolbar button tip text: Exit the application
+#
+Exit the application
+#
+# 12: Menu text: File
+#
+&File
+#
+# 13: Menu text: Help
+#
+&Help
+#
+# 14: Menu item text: Directory
+#
+&Directory... Alt-D
+#
+# 15: Menu item tip text: Choose directory
+#
+Choose directory
+#
+# 16: Menu item text: Options
+#
+&Options Alt-O
+#
+# 17: Menu item tip text: Set conversion options
+#
+Conversion options
+#
+# 18: Menu item text: Run
+#
+&Run Alt-R
+#
+# 19: Menu item tip text: Run conversion
+#
+Run conversion
+#
+# 20: Menu item text: Exit
+#
+E&xit Alt-X
+#
+# 21: Menu item tip text: Exit the application
+#
+Exit the application
+#
+# 22: Menu item: Contents
+#
+&Contents F1
+#
+# 23: Menu item tip text: Show table of contents
+#
+Show table of contents
+#
+# 24: Menu item text: About
+#
+&About Alt-A
+#
+# 25: Menu item tip text: Show version number
+#
+Show version number
+#
+# 26: Label text: Directory:
+#
+Directory:
+#
+# 27: Empty string to indicate no directory name available
+#
+
+#
+# 28: Empty string for initial status text
+#
+
+#
+# 29: Directory dialog title: Choose directory
+#
+Choose Directory
+#
+# 30: Autorun result: Processing succeeded, application will exit.
+#
+Processing succeeded, application will exit.
+#
+# 31: ERROR: Automatic run canceled due to errors.
+#
+Automatic run canceled due to errors!
+#
+# 32: Progress dialog title: Conversion progress
+#
+Conversion progress
+#
+# 33: Progress dialog button title: Cancel
+#
+Cancel
+#
+# 34: Progress dialog button tool tip: Abort after current file
+#
+Abort conversion after finishing current file
+#
+# 35: Notification text: Cancel command scheduled... wait, please!
+#
+Cancel command scheduled... wait, please!
+#
+# 36: Options dialog box title
+#
+Conversion Options
+#
+# 37: Options dialog box paragraph: General
+#
+General
+#
+# 38: Checkbox: Make mode
+#
+Make mode
+#
+# 39: Tool tip for checkbox make mode
+#
+Run conversion only if destination file is not up to date.
+#
+# 40: Dialog box paragraph: Output
+#
+Output
+#
+# 41: Label output format
+#
+Output format:
+#
+# 42: Output format PS
+#
+PS
+#
+# 43: Output format EPS
+#
+EPS
+#
+# 44: Output format PDF
+#
+PDF
+#
+# 45: Output format: Bounding box
+#
+Bounding Box
+#
+# 46: Label output type
+#
+Output mode:
+#
+# 47: Output mode image
+#
+Image
+#
+# 48: Output mode object
+#
+Object
+#
+# 49: Output mode document
+#
+Document
+#
+# 50: Label finishing
+#
+Finishing:
+#
+# 51: Finishing Single-side
+#
+Single-side
+#
+# 52: Finishing duplex, no tumble
+#
+Duplex (book)
+#
+# 53: Finishing duplex and tumble
+#
+Duplex (calendar)
+#
+# 54: Checkbox draft mode
+#
+Draft mode
+#
+# 55: Tool tip text for draft checkbox
+#
+Create placeholder image only
+#
+# 56: Checkbox color
+#
+Color
+#
+# 57: Tool tip text for checkbox color
+#
+Enable colored output
+#
+# 58: Paragraph output size
+#
+Output size
+#
+# 59: label resolution
+#
+Resolution:
+#
+# 60: Resolution 1 pixel = 1 point
+#
+1px=1pt
+#
+# 61: Resolution as specified in input file
+#
+input file
+#
+# 62: Resolution as specified
+#
+as specified:
+#
+# 63: Label paper size
+#
+Paper size:
+#
+# 64: Paragraph image quality
+#
+Image quality
+#
+# 65: Checkbox image interpolation
+#
+Image interpolation
+#
+# 66: Tool tip text for checkbox image interpolation
+#
+Enable image interpolation
+#
+# 67: Checkbox image interpolation for JPEG
+#
+Image interpolation for JPEG files
+#
+# 68: Tool tip text for checkbox image interpolation for JPEG files
+#
+Enable image interpolation for JPEG files too
+#
+# 69: Paragraph transparency
+#
+Transparency
+#
+# 70: Label background color
+#
+Background color:
+#
+# 71: Checkbox Force background color
+#
+Force background color
+#
+# 72: Tool tip text for checkbox force background
+#
+Always use the specified background color, ignore background color chunks
+#
+# 73: Paragraph output format details
+#
+Output format details
+#
+# 74: Label PS level
+#
+PS level:
+#
+# 75: Label predictor
+#
+Predictor:
+#
+# 76: Predictor none
+#
+None
+#
+# 77: Predictor tiff
+#
+TIFF
+#
+# 78: Predictor sub
+#
+PNG-SUB
+#
+# 79: Predictor up
+#
+PNG-UP
+#
+# 80: Predictor average
+#
+PNG-AVERAGE
+#
+# 81: Predictor paeth
+#
+PNG-PAETH
+#
+# 82: Checkbox DSC
+#
+DSC
+#
+# 83: Tool tip text for checkbox dsc
+#
+Write DSC comments to PS output
+#
+# 84: Button text OK
+#
+OK
+#
+# 85: Tool tip for OK button
+#
+Confirm settings, leave this dialog box
+#
+# 86: Button Cancel
+#
+Cancel
+#
+# 87: Tool tip for cancel button
+#
+Discard settings, leave this dialog box
+#
+# 88: Tool tip for color viewer.
+#
+Click to change the default background color
+#
+# 89: Check box: Use DCT compressed data from JPEGs directly
+#
+Re-use JPEG DCT data
+#
+# 90: Tool tip text: Allow direct re-usse of DCT compressed data from JPEGs
+#
+Allow direct re-use of DCT compressed data from JPEG files instead of decoding and re-encoding it
+#
+# 91: Tool tip: Choose output format
+#
+Choose an output format: PS / EPS / PDF or Bounding Box
+#
+# 92: Tool tip: Choose output type
+#
+Choose an output type: Image for standalone viewing / Object for use with LaTeX / Document for print jobs or multipage images
+#
+# 93: Tool tip: Choose finishing
+#
+Choose finishing: Single-sided / Duplex like a book / Duplex like a calendar
+#
+# 94: Tool tip: Choose resolution handling
+#
+Choose resolution handling: 1 pixel = 1 PS point / Specify a resolution / Fit image to a paper size
+#
+# 95: Tool tip: Choose a paper size
+#
+Choose a paper size. Difference between A4 and a4: A4 uses the entire page without leaving a border, a4 leaves some border unused
+#
+# 96: Tool tip: Choose a PS level
+#
+Choose a PS level (2 or 3)
+#
+# 97: Tool tip: Choose a predictor for flate compression
+#
+Choose a predictor for flate compression
+#
+# 98: Tool tip: Specify a resolution in dpi
+#
+Specify the resolution in dpi
+#
+# 99: Menu item: Setup...
+#
+Setup... Alt-S
+#
+# 100: Tool tip for menu item Setup
+#
+Set conversion options
+#
+# 101: Menu item: Reset options
+#
+Reset... Alt-R
+#
+# 102: Tool tip for menu item Reset options
+#
+Reset conversion options to default values
+#
+# 103: Question: Do you really want to reset all options to default values?
+#
+Do you really want to reset all conversion options to default values?
+#
+# 104: Message box title: Reset all conversion options to default values
+#
+Are you sure?
+#
+# 105: Error: Not enough memory!
+#
+Not enough memory!
+#
+# 106/107: Message: Processing directory "..." (start).
+#
+Processing directory "
+" (start).
+#
+# 108/109: Message: Processing directory "..." (finished).
+#
+Processing directory "
+" (finished).
+#
+# 110: Newline
+#
+\n
+#
+# 111/112: Error: File name too long!
+#
+File name too long:\n"
+"!
+#
+# 113: Error: No file found to convert
+#
+No conversion candidate files found!
+#
+# 114/115: Message: Processing file "..." (start).
+#
+Processing file "
+".
+#
+# 116/117: Message: Processing file "..." (finished).
+#
+Processing file "
+" (finished).
+#
+# 118/119: Error: File name "..." contains unconvertable characters!
+#
+File name "
+" contains unconvertable characters!
+#
+# 120: Checkbox: Reduce bits per components
+#
+Reduce bits per components
+#
+# 121: Tool tip text: Reduce bits per component if possible
+#
+Reduce bits per components if possible
+#
+# 122: About dialog box title
+#
+About wxbmpp
+#
+# 123: This program uses libraries from the following projects:
+#
+This program uses libraries from the following projects:\n
+#
+# 124: See
+#
+See:
+$!end
+};
+
+
+/** Constant texts, not localized.
+*/
+static wxChar const * const wxbmpp_nl_wx[] = {
+$!string-table macro=wxT
+Error
+Not enough memory (RAM)!
+$!end
+};
+
+/** Application group name.
+*/
+static dkChar const dkwxbmepsapp_groupname[] = { dkT("dktools") };
+
+
+
+/** Name for string table file to load.
+*/
+static dkChar const dkwxbmeps_string_table_name[] = { dkT("wxbmpp.str") };
+
+
+
+/** Help file to be used on Windows systems.
+*/
+static wxChar const dkwxbmeps_chm_helpfile[] = { wxT("wxbmpp.chm") };
+
+
+
+/** Help file to be used on non-Windows systems.
+*/
+static wxChar const dkwxbmeps_htb_helpfile[] = { wxT("wxbmpp.htb") };
+
+
+
+bool
+DkWxBmepsApp::OnInit()
+{
+ bool back = false;
+ wxChar const * const *localizedTexts = defaultTexts;
+ dkChar const * const *msg = NULL;
+ DkWxBmepsFrame *frame = NULL;
+ wxPNGHandler *phPng = NULL;
+ wxXPMHandler *phXpm = NULL;
+ wxICOHandler *phIco = NULL;
+ wxZipFSHandler *phZipFs = NULL;
+
+ $!trace-init wxbmpp.deb
+ $? "+ DkWxBmepsApp::OnInit"
+
+ /* Initialize elements.
+ */
+ pHelper = NULL;
+ helpController = NULL;
+
+ /* Get elements.
+ */
+ pHelper = new DkWxAppHelper(argv[0],defaultTexts[2],dkwxbmepsapp_groupname);
+ if (NULL == pHelper) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ if (!(pHelper->checkSetup())) {
+ goto finished;
+ }
+ msg = dk3app_messages(
+ pHelper->getApp(),
+ dk3bmep_str_get_string_table_name(),
+ (dkChar const **)dk3bmep_str_get_message_texts()
+ );
+ if (NULL == msg) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ localizedTexts =
+ pHelper->getStringTable(defaultTexts, dkwxbmeps_string_table_name);
+ if (NULL == localizedTexts) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ /* Set image and zip fs handler for online help.
+ */
+ phPng = new wxPNGHandler();
+ if (NULL != phPng) {
+ wxImage::AddHandler(phPng);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phXpm = new wxXPMHandler();
+ if (NULL != phXpm) {
+ wxImage::AddHandler(phXpm);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phIco = new wxICOHandler();
+ if (NULL != phIco) {
+ wxImage::AddHandler(phIco);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phZipFs = new wxZipFSHandler();
+ if (NULL != phZipFs) {
+ wxFileSystem::AddHandler(phZipFs);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ /* Get help controller
+ */
+ helpController =
+ new DkWxHelpController(pHelper,dkwxbmeps_chm_helpfile,dkwxbmeps_htb_helpfile);
+ if (NULL == helpController) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ /* Create frame.
+ */
+ frame = new DkWxBmepsFrame(
+ defaultTexts[0], localizedTexts, msg, pHelper, DkWxBmeps_MainWindow,
+ helpController, argc, argv
+ );
+ if (NULL == frame) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ /* Show frame and inidicate success.
+ */
+ frame->Show();
+ frame->restorePosition();
+ back = true;
+
+ /* Clean up on problems.
+ */
+ finished:
+ if (!(back)) {
+ if (NULL != helpController) {
+ delete(helpController);
+ helpController = NULL;
+ }
+ if (NULL != pHelper) {
+ delete(pHelper);
+ pHelper = NULL;
+ }
+ }
+
+ $? "- DkWxBmepsApp::OnInit %d", ((back) ? 1 : 0)
+ return back;
+}
+
+
+
+int
+DkWxBmepsApp::OnExit()
+{
+ int back = 0;
+ $? "+ DkWxBmepsApp::OnExit"
+ /*
+ Release elements.
+ */
+ if(helpController) {
+ delete(helpController); helpController = NULL;
+ }
+ if(pHelper) {
+ delete(pHelper); pHelper = NULL;
+ }
+ $? "- DkWxBmepsApp::OnExit %d", back
+ $!trace-end
+ return back;
+}
+
+
+
+void
+DkWxBmepsApp::ShowMemoryErrorMessage(void)
+{
+ const wxChar *s_title = NULL;
+ const wxChar *s_text = NULL;
+
+ if (NULL != pHelper) {
+ s_title = pHelper->getBasicString(3);
+ s_text = pHelper->getBasicString(9);
+ }
+ if (NULL == s_title) {
+ s_title = wxbmpp_nl_wx[0];
+ }
+ if (NULL == s_text) {
+ s_text = wxbmpp_nl_wx[1];
+ }
+ wxMessageBox(s_text, s_title, (wxOK | wxCENTRE | wxICON_ERROR));
+}
+
diff --git a/support/dktools/DkWxBmepsApp.h b/support/dktools/DkWxBmepsApp.h
new file mode 100644
index 0000000000..2f973cfc1f
--- /dev/null
+++ b/support/dktools/DkWxBmepsApp.h
@@ -0,0 +1,82 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxBmepsApp.cpt
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxBmepsApp.h Header file for the DkWxBmepsApp module.
+*/
+
+#ifndef DKWXBMEPSAPP_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DKWXBMEPSAPP_H_INCLUDED 1
+
+
+#line 10 "DkWxBmepsApp.cpt"
+
+/** Application class for wxbmeps.
+*/
+class DkWxBmepsApp : public wxApp
+{
+ protected:
+
+ /** Helper object.
+ */
+ DkWxAppHelper *pHelper;
+
+ /** Help controller.
+ */
+ DkWxHelpController *helpController;
+
+ protected:
+
+ /** Show error message if there is not sufficient memory available.
+ */
+ void
+ ShowMemoryErrorMessage(void);
+
+ public:
+ /** Initialize application.
+ */
+ virtual bool OnInit();
+
+ /** Clean up after running.
+ */
+ virtual int OnExit();
+};
+
+DECLARE_APP(DkWxBmepsApp)
+
+
+
+
+#endif
diff --git a/support/dktools/DkWxBmepsFrame.cpp b/support/dktools/DkWxBmepsFrame.cpp
new file mode 100644
index 0000000000..1cd130f8fb
--- /dev/null
+++ b/support/dktools/DkWxBmepsFrame.cpp
@@ -0,0 +1,1321 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxBmepsFrame.wxc
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxBmepsFrame.cpp The DkWxBmepsFrame module.
+*/
+
+
+#line 364 "DkWxBmepsFrame.wxc"
+
+
+
+#include "wxbmeps.h"
+
+/*
+ Icons and bitmaps
+*/
+#include "dkicon.xpm"
+#include "choose-dir.xpm"
+#include "exit-program.xpm"
+#include "run-conversion.xpm"
+#include "set-options.xpm"
+#include "dk4verswx.h"
+
+
+
+
+
+#line 382 "DkWxBmepsFrame.wxc"
+
+
+
+/** Start of version information.
+*/
+static wxChar const wxbmpp_version[] = {
+ wxT("wxbmpp (part of dktools-")
+};
+
+
+
+/** Version number for version information.
+*/
+static wxChar const wxbmpp_versnumber[] = {
+ DKT_VERSION_WX
+};
+
+
+
+/** End of version information.
+*/
+static wxChar const wxbmpp_versend[] = {
+ wxT(")")
+};
+
+
+
+/** Setting names for string settings.
+*/
+wxChar const * const dkwxbmeps_string_setting_names[] = {
+/* 0 */
+wxT("wxbmeps.directory"),
+
+/* 1 */
+wxT("wxbmeps.paper-size"),
+
+NULL
+
+
+#line 422 "DkWxBmepsFrame.wxc"
+};
+
+
+
+/** Setting names for double settings.
+*/
+wxChar const * const dkwxbmeps_double_setting_names[] = {
+/* 0 */
+wxT("wxbmeps.area.w"),
+
+/* 1 */
+wxT("wxbmeps.area.h"),
+
+/* 2 */
+wxT("wxbmeps.area.border.left"),
+
+/* 3 */
+wxT("wxbmeps.area.border.right"),
+
+/* 4 */
+wxT("wxbmeps.area.border.top"),
+
+/* 5 */
+wxT("wxbmeps.area.border.bottom"),
+
+/* 6 */
+wxT("wxbmeps.resolution"),
+
+NULL
+
+
+#line 438 "DkWxBmepsFrame.wxc"
+};
+
+
+
+/** Setting names for int settings.
+*/
+wxChar const * const dkwxbmeps_int_setting_names[] = {
+/* 0 */
+wxT("wxbmeps.driver"),
+
+/* 1 */
+wxT("wxbmeps.mode"),
+
+/* 2 */
+wxT("wxbmeps.size-mode"),
+
+/* 3 */
+wxT("wxbmeps.color"),
+
+/* 4 */
+wxT("wxbmeps.predictor"),
+
+/* 5 */
+wxT("wxbmeps.image-origin-point"),
+
+/* 6 */
+wxT("wxbmeps.draft"),
+
+/* 7 */
+wxT("wxbmeps.duplex"),
+
+/* 8 */
+wxT("wxbmeps.tumble"),
+
+/* 9 */
+wxT("wxbmeps.ps-level"),
+
+/* 10 */
+wxT("wxbmeps.dsc"),
+
+/* 11 */
+wxT("wxbmeps.dct"),
+
+/* 12 */
+wxT("wxbmeps.keep-aspect-ratio"),
+
+/* 13 */
+wxT("wxbmeps.bg.red"),
+
+/* 14 */
+wxT("wxbmeps.bg.green"),
+
+/* 15 */
+wxT("wxbmeps.bg.blue"),
+
+/* 16 */
+wxT("wxbmeps.bg.force"),
+
+/* 17 */
+wxT("wxbmeps.interpolation"),
+
+/* 18 */
+wxT("wxbmeps.interpolation-for-jpeg"),
+
+/* 19 */
+wxT("wxbmeps.make"),
+
+/* 20 */
+wxT("wxbmeps.reduce-bits-per-component"),
+
+NULL
+
+
+#line 468 "DkWxBmepsFrame.wxc"
+};
+
+
+
+static const wxCmdLineEntryDesc wxbmepsframe_cmd_line_desc[] = {
+ {
+ wxCMD_LINE_OPTION,
+ wxT_2("l"),
+ wxT_2("language"),
+ wxT_2("Choose output language"),
+ wxCMD_LINE_VAL_STRING
+ },
+ {
+ wxCMD_LINE_SWITCH,
+ wxT_2("m"),
+ wxT_2("make"),
+ wxT_2("Run in make mode")
+ },
+ {
+ wxCMD_LINE_SWITCH,
+ wxT_2("r"),
+ wxT_2("run"),
+ wxT_2("Run immediately")
+ },
+ {
+ wxCMD_LINE_PARAM,
+ NULL,
+ NULL,
+ wxT_2("input file"),
+ wxCMD_LINE_VAL_STRING,
+ wxCMD_LINE_PARAM_OPTIONAL
+ },
+ { wxCMD_LINE_NONE }
+};
+
+
+/** Event table for the DkWxBmepsFrame class.
+*/
+BEGIN_EVENT_TABLE(DkWxBmepsFrame, wxFrame)
+ EVT_MENU(DkWxBmeps_Quit, DkWxBmepsFrame::OnQuit)
+ EVT_MENU(DkWxBmeps_Help_Contents, DkWxBmepsFrame::OnHelpContents)
+ EVT_MENU(DkWxBmeps_About, DkWxBmepsFrame::OnAbout)
+ EVT_MENU(DkWxBmeps_ChooseDirectory, DkWxBmepsFrame::OnChooseDirectory)
+ EVT_MENU(DkWxBmeps_SetOptions, DkWxBmepsFrame::OnSetOptions)
+ EVT_MENU(DkWxBmeps_ResetOptions, DkWxBmepsFrame::OnResetOptions)
+ EVT_MENU(DkWxBmeps_Run, DkWxBmepsFrame::OnRunConversion)
+ EVT_IDLE(DkWxBmepsFrame::OnIdle)
+END_EVENT_TABLE()
+
+
+
+
+#line 520 "DkWxBmepsFrame.wxc"
+DkWxBmepsFrame::DkWxBmepsFrame(
+ wxChar const *applicationName,
+ wxChar const * const *messageTexts,
+ dkChar const * const *m,
+ DkWxAppHelper *applicationHelper,
+ int wxid,
+ DkWxHelpController *hc,
+ int argc,
+ wxChar **argv
+) : DkWxFrame(applicationName, applicationHelper, hc, wxid)
+{
+#if defined(__WXMSW__)
+ wxIcon dkicon_bitmap(wxT("aaaaa")); /* from resource file */
+#else
+ wxIcon dkicon_bitmap(xpm_dkicon); /* from included xpm */
+#endif
+
+
+#line 537 "DkWxBmepsFrame.wxc"
+ ddx = -1;
+ ddy = -1;
+ odx = -1;
+ ody = -1;
+ pComm = NULL;
+ timeClose = (dk3_time_t)0UL;
+ bSetupChecked = false;
+ sTexts = messageTexts;
+ msg = m;
+ bSaveSettings = true;
+ bGuiActive = true;
+ bCloseScheduled = false;
+ bAutostartWanted = false;
+ bAutostartDone = false;
+ sDirectory = NULL;
+ cBlack = NULL;
+ cGreen = NULL;
+ cRed = NULL;
+ dk3bmeo_init(&bmeo);
+ bmeo.app = applicationHelper->getApp();
+ dk3bmeo_apply_preferences(&bmeo);
+ asPaperSizes = new wxArrayString();
+ paperSizes = NULL;
+ nPaperSizes = 0;
+ currentPaperSize = 0;
+ findPaperSizes();
+ retrieveData();
+ dkctGUILayoutOK = false;
+ dkctGUIContentsPanel = NULL;
+ mbMain = NULL;
+ mainSizer = NULL;
+ tbMain = NULL;
+ bDir = NULL;
+ bOptions = NULL;
+ bRun = NULL;
+ bExit = NULL;
+ menuFile = NULL;
+ menuHelp = NULL;
+ miFileDir = NULL;
+ miFileOptions = NULL;
+ miFileRun = NULL;
+ miFileExit = NULL;
+ miHelpContents = NULL;
+ miHelpAbout = NULL;
+ miFileOptionsSetup = NULL;
+ miFileOptionsReset = NULL;
+ verticalSizer = NULL;
+ contentsSizer = NULL;
+ tLogmessages = NULL;
+ tStatus = NULL;
+ lDirectory = NULL;
+ tDirectory = NULL;
+ dkctGUIContentsPanel = new wxPanel(this);
+ if(!(dkctGUIContentsPanel)) {
+ goto dkctGUILayoutFinished;
+ }
+#if wxUSE_MENUS
+ mbMain = new wxMenuBar(
+ );
+ if(!(mbMain)) {
+ goto dkctGUILayoutFinished;
+ }
+ menuFile = new wxMenu(
+ );
+ if(!(menuFile)) {
+ goto dkctGUILayoutFinished;
+ }
+ miFileDir = menuFile->Append(
+ DkWxBmeps_ChooseDirectory,
+ sTexts[14],
+ sTexts[15]
+ );
+ if(!(miFileDir)) {
+ goto dkctGUILayoutFinished;
+ }
+ miFileOptions = new wxMenu(
+ );
+ if(!(miFileOptions)) {
+ goto dkctGUILayoutFinished;
+ }
+ miFileOptionsSetup = miFileOptions->Append(
+ DkWxBmeps_SetOptions,
+ sTexts[99],
+ sTexts[100]
+ );
+ if(!(miFileOptionsSetup)) {
+ goto dkctGUILayoutFinished;
+ }
+ miFileOptionsReset = miFileOptions->Append(
+ DkWxBmeps_ResetOptions,
+ sTexts[101],
+ sTexts[102]
+ );
+ if(!(miFileOptionsReset)) {
+ goto dkctGUILayoutFinished;
+ }
+ menuFile->Append(wxID_ANY, sTexts[16], miFileOptions, sTexts[17]);
+ miFileRun = menuFile->Append(
+ DkWxBmeps_Run,
+ sTexts[18],
+ sTexts[19]
+ );
+ if(!(miFileRun)) {
+ goto dkctGUILayoutFinished;
+ }
+ miFileExit = menuFile->Append(
+ DkWxBmeps_Quit,
+ sTexts[20],
+ sTexts[21]
+ );
+ if(!(miFileExit)) {
+ goto dkctGUILayoutFinished;
+ }
+ mbMain->Append(menuFile, sTexts[12]);
+ menuHelp = new wxMenu(
+ );
+ if(!(menuHelp)) {
+ goto dkctGUILayoutFinished;
+ }
+ miHelpContents = menuHelp->Append(
+ DkWxBmeps_Help_Contents,
+ sTexts[22],
+ sTexts[23]
+ );
+ if(!(miHelpContents)) {
+ goto dkctGUILayoutFinished;
+ }
+ miHelpAbout = menuHelp->Append(
+ DkWxBmeps_About,
+ sTexts[24],
+ sTexts[25]
+ );
+ if(!(miHelpAbout)) {
+ goto dkctGUILayoutFinished;
+ }
+ mbMain->Append(menuHelp, sTexts[13]);
+ SetMenuBar(mbMain);
+#endif
+#if wxUSE_TOOLBAR
+ tbMain = new wxToolBar(
+ this,
+ wxID_ANY
+ );
+ if(!(tbMain)) {
+ goto dkctGUILayoutFinished;
+ }
+ bDir = tbMain->AddTool(
+ DkWxBmeps_ChooseDirectory,
+ sTexts[4],
+ xpm_choose_dir,
+ wxNullBitmap,
+ wxITEM_NORMAL,
+ sTexts[5]
+ );
+ if(!(bDir)) {
+ goto dkctGUILayoutFinished;
+ }
+ bOptions = tbMain->AddTool(
+ DkWxBmeps_SetOptions,
+ sTexts[6],
+ xpm_set_options,
+ wxNullBitmap,
+ wxITEM_NORMAL,
+ sTexts[7]
+ );
+ if(!(bOptions)) {
+ goto dkctGUILayoutFinished;
+ }
+ bRun = tbMain->AddTool(
+ DkWxBmeps_Run,
+ sTexts[8],
+ xpm_run_conversion,
+ wxNullBitmap,
+ wxITEM_NORMAL,
+ sTexts[9]
+ );
+ if(!(bRun)) {
+ goto dkctGUILayoutFinished;
+ }
+ bExit = tbMain->AddTool(
+ DkWxBmeps_Quit,
+ sTexts[10],
+ xpm_exit_program,
+ wxNullBitmap,
+ wxITEM_NORMAL,
+ sTexts[11]
+ );
+ if(!(bExit)) {
+ goto dkctGUILayoutFinished;
+ }
+ tbMain->Realize();
+ SetToolBar(tbMain);
+#endif
+ mainSizer = new wxBoxSizer(
+ wxHORIZONTAL
+ );
+ if(!(mainSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ mainSizer->Add(10, 10, 0);
+ verticalSizer = new wxBoxSizer(
+ wxVERTICAL
+ );
+ if(!(verticalSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ verticalSizer->Add(10, 10, 0);
+ contentsSizer = new wxGridBagSizer(
+ 5, 5
+ );
+ if(!(contentsSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ lDirectory = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[26]
+ );
+ if(!(lDirectory)) {
+ goto dkctGUILayoutFinished;
+ }
+ contentsSizer->Add(
+ lDirectory,
+ wxGBPosition(0, 0),
+ wxGBSpan(1, 1),
+ wxALIGN_RIGHT
+ );
+ tDirectory = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ ((sDirectory) ? sDirectory : sTexts[27])
+ );
+ if(!(tDirectory)) {
+ goto dkctGUILayoutFinished;
+ }
+ contentsSizer->Add(
+ tDirectory,
+ wxGBPosition(0, 1),
+ wxGBSpan(1, 1)
+ );
+ verticalSizer->Add(
+ contentsSizer,
+ 0,
+ wxALIGN_LEFT
+ );
+ verticalSizer->Add(10, 10, 0);
+ tLogmessages = new wxTextCtrl(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[28],
+ wxDefaultPosition,
+ wxSize(400, 60),
+ wxTE_MULTILINE|wxTE_READONLY|wxTE_NOHIDESEL|wxTE_LEFT|wxTE_DONTWRAP
+ );
+ if(!(tLogmessages)) {
+ goto dkctGUILayoutFinished;
+ }
+ verticalSizer->Add(
+ tLogmessages,
+ 1,
+ wxALIGN_LEFT|wxALIGN_TOP|wxGROW
+ );
+ verticalSizer->Add(10, 10, 0);
+ tStatus = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[28]
+ );
+ if(!(tStatus)) {
+ goto dkctGUILayoutFinished;
+ }
+ verticalSizer->Add(
+ tStatus,
+ 0,
+ wxALIGN_LEFT
+ );
+ verticalSizer->Add(10, 10, 0);
+ mainSizer->Add(
+ verticalSizer,
+ 1,
+ wxGROW
+ );
+ mainSizer->Add(10, 10, 0);
+ dkctGUIContentsPanel->SetSizer(mainSizer);
+ SetIcon(dkicon_bitmap);
+ dkctGUILayoutOK = true;
+ dkctGUILayoutFinished:
+#if wxUSE_STATUSBAR
+ if(dkctGUILayoutOK) {
+ CreateStatusBar(1);
+ SetStatusText(sTexts[3]);
+ }
+#endif
+ if(dkctGUILayoutOK) {
+ mainSizer->Fit(this);
+ mainSizer->SetSizeHints(this);
+ }
+
+#line 565 "DkWxBmepsFrame.wxc"
+ pComm = new DkWxCommunicator(
+ applicationHelper->getWxEncoding(),
+ applicationHelper->getDkEncoding()
+ );
+ cBlack = new wxColour(0x00, 0x00, 0x00);
+ cGreen = new wxColour(0x00, 0x7F, 0x00);
+ cRed = new wxColour(0x7F, 0x00, 0x00);
+ if(argc > 1) { /* Any option or argument, no persistent settings. */
+ bSaveSettings = false;
+ dk3bmeo_init(&bmeo);
+#if VERSION_BEFORE_20131020
+ bAutostartWanted = true;
+ if(pComm) {
+
+#line 578 "DkWxBmepsFrame.wxc"
+ pComm->autostartEnable(true);
+ }
+#endif
+ /* ##### Process command line arguments. */
+ {
+ int res = -1;
+ wxCmdLineParser parser(wxbmepsframe_cmd_line_desc, argc, argv);
+ {
+ wxLogNull log;
+ res = parser.Parse(false);
+ }
+ if(res == 0) {
+ wxString sLanguage(wxT(""));
+ dkChar bu[1024];
+ wxChar const *ptr;
+ if(parser.Found(wxT("r"))) {
+ bAutostartWanted = true;
+ if(pComm) {
+
+#line 596 "DkWxBmepsFrame.wxc"
+ pComm->autostartEnable(true);
+ }
+ }
+ if(parser.Found(wxT("m"))) {
+ bmeo.make = 1;
+ }
+ if(parser.Found(wxT("l"), &sLanguage)) {
+ ptr = sLanguage.c_str();
+ if(ptr) {
+ if(applicationHelper->wxToDk(bu, DK3_SIZEOF(bu,dkChar), ptr)) {
+ (void)dk3bmeo_set_language(
+ &bmeo, bu, applicationHelper->getApp()
+ );
+ }
+ }
+ }
+ if(parser.GetParamCount() > 0) {
+
+#line 613 "DkWxBmepsFrame.wxc"
+ wxString cmdfn;
+ wxChar const *newfn;
+ cmdfn = parser.GetParam(0);
+ wxFileName fn(cmdfn);
+ fn.Normalize(
+ wxPATH_NORM_LONG | wxPATH_NORM_DOTS
+ | wxPATH_NORM_TILDE | wxPATH_NORM_ABSOLUTE
+ );
+ if(fn.FileExists()) {
+ bAutostartWanted = true;
+ if(pComm) {
+
+#line 624 "DkWxBmepsFrame.wxc"
+ pComm->autostartEnable(true);
+ }
+ }
+ cmdfn = fn.GetFullPath();
+ newfn = cmdfn.c_str();
+ if(newfn) {
+
+#line 630 "DkWxBmepsFrame.wxc"
+ newfn = dk3wxs_dup_app(newfn, applicationHelper->getApp());
+ if(newfn) {
+
+#line 632 "DkWxBmepsFrame.wxc"
+ dk3_release(sDirectory);
+ sDirectory = newfn;
+ } else {
+
+#line 635 "DkWxBmepsFrame.wxc"
+ }
+ } else {
+
+#line 637 "DkWxBmepsFrame.wxc"
+ }
+ } else {
+
+#line 639 "DkWxBmepsFrame.wxc"
+ }
+ }
+ }
+ /* (void)dk3bmeo_check(&bmeo, 0, applicationHelper->getApp(), NULL); */
+ }
+
+
+#line 645 "DkWxBmepsFrame.wxc"
+
+
+#line 646 "DkWxBmepsFrame.wxc"
+
+
+#line 647 "DkWxBmepsFrame.wxc"
+
+
+#line 648 "DkWxBmepsFrame.wxc"
+
+
+#line 649 "DkWxBmepsFrame.wxc"
+
+
+#line 650 "DkWxBmepsFrame.wxc"
+
+
+#line 651 "DkWxBmepsFrame.wxc"
+
+
+#line 652 "DkWxBmepsFrame.wxc"
+
+
+#line 653 "DkWxBmepsFrame.wxc"
+
+
+#line 654 "DkWxBmepsFrame.wxc"
+
+
+#line 655 "DkWxBmepsFrame.wxc"
+
+
+#line 656 "DkWxBmepsFrame.wxc"
+
+
+#line 657 "DkWxBmepsFrame.wxc"
+
+
+#line 658 "DkWxBmepsFrame.wxc"
+
+
+#line 659 "DkWxBmepsFrame.wxc"
+
+
+#line 660 "DkWxBmepsFrame.wxc"
+
+
+#line 661 "DkWxBmepsFrame.wxc"
+
+
+#line 662 "DkWxBmepsFrame.wxc"
+#if 0
+ restorePosition();
+#endif
+
+
+#line 666 "DkWxBmepsFrame.wxc"
+}
+
+
+#line 669 "DkWxBmepsFrame.wxc"
+
+
+DkWxBmepsFrame::~DkWxBmepsFrame()
+{
+
+
+#line 674 "DkWxBmepsFrame.wxc"
+ dk3_release(paperSizes);
+ dk3_release(sDirectory);
+ dk3_cpp_release(pComm);
+ dk3_cpp_release(cBlack);
+ dk3_cpp_release(cGreen);
+ dk3_cpp_release(cRed);
+ dk3_cpp_release(asPaperSizes);
+
+
+#line 682 "DkWxBmepsFrame.wxc"
+}
+
+
+
+void
+DkWxBmepsFrame::saveData()
+{
+ double d[7];
+ int i[21];
+
+
+#line 692 "DkWxBmepsFrame.wxc"
+ d[0] = bmeo.ima.ps.w;
+ d[1] = bmeo.ima.ps.h;
+ d[2] = bmeo.ima.ps.i;
+ d[3] = bmeo.ima.ps.o;
+ d[4] = bmeo.ima.ps.t;
+ d[5] = bmeo.ima.ps.b;
+ d[6] = bmeo.resolution;
+ i[0] = bmeo.dr;
+ i[1] = bmeo.mode;
+ i[2] = bmeo.szmode;
+ /* i[3] = bmeo.color; */
+ i[3] = 0;
+ i[4] = bmeo.pred;
+ i[5] = bmeo.io;
+ i[6] = bmeo.draft;
+ i[7] = bmeo.duplex;
+ i[8] = bmeo.tumble;
+ i[9] = bmeo.psl;
+ i[10] = bmeo.dsc;
+ i[11] = bmeo.dct;
+ i[12] = bmeo.kar;
+ i[13] = bmeo.bgr;
+ i[14] = bmeo.bgg;
+ i[15] = bmeo.bgb;
+ i[16] = bmeo.fbg;
+ i[17] = bmeo.ip;
+ i[18] = bmeo.jip;
+ i[19] = bmeo.make;
+ i[20] = bmeo.rbpc;
+ pHelper->saveMultipleDoubles(dkwxbmeps_double_setting_names, d);
+ pHelper->saveMultipleInts(dkwxbmeps_int_setting_names, i);
+ if(sDirectory) {
+ pHelper->saveString(dkwxbmeps_string_setting_names[0], sDirectory);
+ }
+ pHelper->saveString(
+ dkwxbmeps_string_setting_names[1],
+ asPaperSizes->Item(currentPaperSize)
+ );
+ /* ##### */
+
+
+#line 732 "DkWxBmepsFrame.wxc"
+}
+
+
+
+void
+DkWxBmepsFrame::retrieveData()
+{
+ double d[7];
+ int i[21];
+
+
+#line 742 "DkWxBmepsFrame.wxc"
+ d[0] = bmeo.ima.ps.w;
+ d[1] = bmeo.ima.ps.h;
+ d[2] = bmeo.ima.ps.i;
+ d[3] = bmeo.ima.ps.o;
+ d[4] = bmeo.ima.ps.t;
+ d[5] = bmeo.ima.ps.b;
+ d[6] = bmeo.resolution;
+ i[0] = bmeo.dr;
+ i[1] = bmeo.mode;
+ i[2] = bmeo.szmode;
+ /* i[3] = bmeo.color; */
+ i[3] = 0;
+ i[4] = bmeo.pred;
+ i[5] = bmeo.io;
+ i[6] = bmeo.draft;
+ i[7] = bmeo.duplex;
+ i[8] = bmeo.tumble;
+ i[9] = bmeo.psl;
+ i[10] = bmeo.dsc;
+ i[11] = bmeo.dct;
+ i[12] = bmeo.kar;
+ i[13] = bmeo.bgr;
+ i[14] = bmeo.bgg;
+ i[15] = bmeo.bgb;
+ i[16] = bmeo.fbg;
+ i[17] = bmeo.ip;
+ i[18] = bmeo.jip;
+ i[19] = bmeo.make;
+ i[20] = bmeo.rbpc;
+ pHelper->retrieveMultipleDoubles(dkwxbmeps_double_setting_names, d);
+ bmeo.ima.ps.w = d[0];
+ bmeo.ima.ps.h = d[1];
+ bmeo.ima.ps.i = d[2];
+ bmeo.ima.ps.o = d[3];
+ bmeo.ima.ps.t = d[4];
+ bmeo.ima.ps.b = d[5];
+ bmeo.resolution = d[6];
+ pHelper->retrieveMultipleInts(dkwxbmeps_int_setting_names, i);
+ bmeo.dr = i[0];
+ bmeo.mode = i[1];
+ bmeo.szmode = i[2];
+
+#line 783 "DkWxBmepsFrame.wxc"
+ /* bmeo.color = i[3]; */
+ bmeo.pred = i[4];
+ bmeo.io = i[5];
+ bmeo.draft = i[6];
+ bmeo.duplex = i[7];
+ bmeo.tumble = i[8];
+ bmeo.psl = i[9];
+ bmeo.dsc = i[10];
+ bmeo.dct = i[11];
+ bmeo.kar = i[12];
+ bmeo.bgr = i[13];
+ bmeo.bgg = i[14];
+ bmeo.bgb = i[15];
+ bmeo.fbg = i[16];
+ bmeo.ip = i[17];
+ bmeo.jip = i[18];
+ bmeo.make = i[19];
+ bmeo.rbpc = i[20];
+ currentPaperSize = 0;
+ sDirectory = pHelper->retrieveString(dkwxbmeps_string_setting_names[0]);
+ {
+ wxChar const *psn;
+ int j;
+ psn = pHelper->retrieveString(dkwxbmeps_string_setting_names[1]);
+ if(psn) {
+ j = asPaperSizes->Index(psn);
+ if(j != wxNOT_FOUND) {
+ currentPaperSize = (size_t)j;
+ }
+ dk3_release(psn);
+ }
+ }
+
+
+#line 816 "DkWxBmepsFrame.wxc"
+ /* ##### */
+}
+
+
+
+void
+DkWxBmepsFrame::runConversion(void)
+{
+ DkWxProgressDialog *pd = NULL;
+ DkWxBmepsThread *pt = NULL;
+
+
+#line 827 "DkWxBmepsFrame.wxc"
+ if(tStatus) {
+ tStatus->SetLabel(sTexts[28]);
+ if(cBlack) {
+ tStatus->SetForegroundColour(*cBlack);
+ }
+ }
+ if(pComm) {
+ pComm->prepareRun();
+ pd = new DkWxProgressDialog(
+ (DkWxFrame *)this,
+ pComm,
+ tLogmessages,
+ sTexts[32], /* title */
+ sTexts[28], /* file name */
+ sTexts[33], /* button text */
+ sTexts[34], /* button tool tip */
+ sTexts[35] /* wait text */
+ );
+ if(pd) {
+ pt = new DkWxBmepsThread(
+ pComm,
+ sTexts,
+ msg,
+ sDirectory,
+ pHelper,
+ pHelper->getWxEncoding(),
+ pHelper->getDkEncoding(),
+ &bmeo
+ );
+ if(pt) {
+ if(pt->checkSetup()) {
+ if(pt->Create() == wxTHREAD_NO_ERROR) {
+ pt->SetPriority(WXTHREAD_DEFAULT_PRIORITY);
+ pt->Run();
+ pd->chooseModalPosition();
+ pd->ShowModal();
+ if(pComm->getLogLevel() <= DK3_LL_WARNING) {
+ bGuiActive = true;
+ }
+ } else {
+
+#line 867 "DkWxBmepsFrame.wxc"
+ delete(pt);
+ /* ##### ERROR: Failed to create new thread! */
+ }
+ } else {
+ /* ##### ERROR: Memory! */
+ delete(pt);
+ }
+ } else {
+
+#line 875 "DkWxBmepsFrame.wxc"
+ /* ##### ERROR: Failed to construct new thread! */
+ }
+ pd->Destroy();
+ } else {
+
+#line 879 "DkWxBmepsFrame.wxc"
+ /* ##### ERROR: Failed to create progress dialog! */
+ }
+ } else {
+
+#line 882 "DkWxBmepsFrame.wxc"
+ /* ##### ERROR: Setup incomplete! */
+ }
+
+
+#line 885 "DkWxBmepsFrame.wxc"
+}
+
+
+
+void
+DkWxBmepsFrame::OnIdle(wxIdleEvent & event)
+{
+ dk3_time_t ct; /* Current time. */
+
+
+#line 894 "DkWxBmepsFrame.wxc"
+ if(!bCloseScheduled) {
+ if(!bSetupChecked) {
+ bSetupChecked = true;
+ if(!checkSetup()) {
+ bCloseScheduled = true;
+ /* ##### Show message: Failed to initialize! */
+ Show(false);
+ Close();
+ }
+ }
+ if(!bCloseScheduled) {
+
+#line 905 "DkWxBmepsFrame.wxc"
+ if(pComm->autostartCanRun()) {
+
+#line 906 "DkWxBmepsFrame.wxc"
+ runConversion();
+ } else {
+
+#line 908 "DkWxBmepsFrame.wxc"
+ if(pComm->autostartIsFinished()) {
+
+#line 909 "DkWxBmepsFrame.wxc"
+ if(!(timeClose)) {
+ if(pComm->getLogLevel() > DK3_LL_WARNING) {
+ dk3sf_time(&timeClose);
+ event.RequestMore();
+ tStatus->SetLabel(sTexts[30]);
+ if((cGreen) && (cBlack)) {
+ tStatus->SetForegroundColour(*cGreen);
+ }
+ Refresh();
+ Update();
+ }
+ }
+ }
+ }
+ if(timeClose) {
+ dk3sf_time(&ct);
+ if(ct > (timeClose + (dk3_time_t)1UL)) {
+ timeClose = (dk3_time_t)0UL;
+ bCloseScheduled = true;
+ Show(false);
+ Close();
+ } else {
+ event.RequestMore();
+ }
+ }
+ }
+ }
+
+
+#line 937 "DkWxBmepsFrame.wxc"
+}
+
+
+
+void
+DkWxBmepsFrame::OnChooseDirectory(wxCommandEvent& WXUNUSED(event))
+{
+ wxChar const *ptr;
+ wxChar const *np;
+
+
+#line 947 "DkWxBmepsFrame.wxc"
+ if(isGuiActive()) {
+ wxDirDialog dd(
+ this, sTexts[29],
+ ((sDirectory) ? sDirectory : wxEmptyString),
+ (wxDD_DIR_MUST_EXIST | wxDD_CHANGE_DIR)
+ );
+ pHelper->setRelatedPosition(this, &dd, &ddx, &ddy);
+ if(dd.ShowModal() == wxID_OK) {
+ wxString path = dd.GetPath();
+ ptr = path.c_str();
+ if(ptr) {
+ np = dk3wxs_dup_app(ptr, pHelper->getApp());
+ if(np) {
+ dk3_release(sDirectory);
+ sDirectory = np;
+ if(tDirectory) {
+ tDirectory->SetLabel(sDirectory);
+ Refresh();
+ Update();
+ }
+ }
+ }
+ }
+ dd.GetPosition(&ddx, &ddy);
+ }
+
+#line 972 "DkWxBmepsFrame.wxc"
+}
+
+
+
+void
+DkWxBmepsFrame::OnRunConversion(wxCommandEvent& WXUNUSED(event))
+{
+
+
+#line 980 "DkWxBmepsFrame.wxc"
+ if(isGuiActive()) {
+ runConversion();
+ }
+
+
+#line 984 "DkWxBmepsFrame.wxc"
+}
+
+
+
+bool
+DkWxBmepsFrame::isGuiActive()
+{
+ bool back;
+ back = bGuiActive;
+
+
+#line 994 "DkWxBmepsFrame.wxc"
+ if(bCloseScheduled) { back = false; }
+
+
+#line 996 "DkWxBmepsFrame.wxc"
+ return back;
+}
+
+
+
+bool
+DkWxBmepsFrame::canClose(bool isLast)
+{
+
+
+#line 1005 "DkWxBmepsFrame.wxc"
+ if(isLast) {
+ if(bSaveSettings) {
+ saveData();
+ }
+ }
+
+#line 1010 "DkWxBmepsFrame.wxc"
+ return true;
+}
+
+
+
+void
+DkWxBmepsFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
+{
+
+
+#line 1019 "DkWxBmepsFrame.wxc"
+ if(isGuiActive()) {
+ bCloseScheduled = true;
+ Show(false);
+ Close();
+ }
+
+
+#line 1025 "DkWxBmepsFrame.wxc"
+}
+
+
+
+bool
+DkWxBmepsFrame::checkSetup()
+{
+ bool back = false;
+ if(pComm) {
+ if((cBlack) && (cGreen) && (cRed)) {
+ if((asPaperSizes) && (paperSizes)) {
+ back = true;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void
+DkWxBmepsFrame::OnSetOptions(wxCommandEvent& WXUNUSED(event))
+{
+ int dke;
+ int wxe;
+
+
+#line 1051 "DkWxBmepsFrame.wxc"
+ dke = pHelper->getDkEncoding();
+ wxe = pHelper->getWxEncoding();
+ if(isGuiActive()) {
+ DkWxBmepsOptionsDialog dlg(
+ (DkWxBmepsFrame *)this, sTexts[36], sTexts, asPaperSizes,
+ &bmeo, paperSizes, &currentPaperSize, pHelper, dke, wxe
+ );
+ pHelper->setRelatedPosition(this, &dlg, &odx, &ody);
+ dlg.dataIn();
+ if(dlg.ShowModal() == wxID_OK) {
+ dk3mem_cpy(
+ (void *)(&(bmeo.ima.ps)),
+ (void *)(&(paperSizes[currentPaperSize])),
+ sizeof(dk3_paper_size_t)
+ );
+
+
+#line 1067 "DkWxBmepsFrame.wxc"
+ }
+ dlg.GetPosition(&odx, &ody);
+ }
+
+
+#line 1071 "DkWxBmepsFrame.wxc"
+}
+
+
+
+void
+DkWxBmepsFrame::OnResetOptions(wxCommandEvent& WXUNUSED(event))
+{
+ int res;
+ res = wxMessageBox(
+ sTexts[103],
+ sTexts[104],
+ wxNO_DEFAULT|wxYES_NO
+ );
+ if(res == wxYES) {
+ dk3bmeo_init(&bmeo);
+ }
+}
+
+
+
+void
+DkWxBmepsFrame::findPaperSizes()
+{
+ wxChar bu[64];
+ dk3_paper_size_collection_t *psc;
+ dk3_named_paper_size_t const *nsz;
+ dk3_paper_size_t *pps;
+ dk3_app_t *app;
+
+
+#line 1100 "DkWxBmepsFrame.wxc"
+ if(asPaperSizes) {
+
+#line 1101 "DkWxBmepsFrame.wxc"
+ app = pHelper->getApp();
+ psc = dk3paper_open_app(app);
+ if(psc) {
+
+#line 1104 "DkWxBmepsFrame.wxc"
+ dk3paper_reset(psc);
+ while((nsz = dk3paper_next(psc)) != NULL) {
+ if(nsz->name) {
+ if(pHelper->dkToWx(bu, DK3_SIZEOF(bu,wxChar), nsz->name)) {
+
+
+#line 1109 "DkWxBmepsFrame.wxc"
+ asPaperSizes->Add(bu);
+ nPaperSizes++;
+ }
+ }
+ }
+ if(nPaperSizes) {
+
+#line 1115 "DkWxBmepsFrame.wxc"
+ paperSizes = dk3_new_app(dk3_paper_size_t,nPaperSizes,app);
+ if(paperSizes) {
+
+#line 1117 "DkWxBmepsFrame.wxc"
+ pps = paperSizes;
+ dk3paper_reset(psc);
+ while((nsz = dk3paper_next(psc)) != NULL) {
+ if(nsz->name) {
+ if(pHelper->dkToWx(bu, DK3_SIZEOF(bu,wxChar), nsz->name))
+ {
+
+#line 1123 "DkWxBmepsFrame.wxc"
+ dk3mem_cpy(
+ (void *)pps,
+ (void *)(&(nsz->size)),
+ sizeof(dk3_paper_size_t)
+ );
+ pps++;
+ }
+ }
+ }
+ }
+ }
+ dk3paper_close(psc);
+ }
+ }
+
+
+#line 1138 "DkWxBmepsFrame.wxc"
+}
+
+
+
+void
+DkWxBmepsFrame::OnHelpContents(wxCommandEvent& WXUNUSED(event))
+{
+ openHelp();
+}
+
+
+
+void
+DkWxBmepsFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
+{
+ if(isGuiActive()) {
+ wxString sVersion(wxbmpp_version);
+ sVersion.Append(wxbmpp_versnumber);
+ sVersion.Append(wxbmpp_versend);
+ sVersion.Append(wxT("\nCopyright (c) 2013-2016 - Dirk Krause\n\n"));
+ sVersion.Append(sTexts[123]);
+ sVersion.Append(wxT("DK tools, wxWidgets, libpng, libjpeg, libtiff, zlib."));
+ sVersion.Append(wxT("\n\n"));
+ sVersion.Append(sTexts[124]);
+ sVersion.Append(wxT("http://dktools.sourceforge.net\n"));
+ sVersion.Append(wxT("http://www.wxwidgets.org\n"));
+ sVersion.Append(wxT("http://www.libpng.org/pub/png/libpng.html\n"));
+ sVersion.Append(wxT("http://www.ijg.org\n"));
+ sVersion.Append(wxT("http://www.remotesensing.org/libtiff\n"));
+ sVersion.Append(wxT("http://www.zlib.org"));
+ wxMessageBox(sVersion, sTexts[122]);
+ }
+}
+
diff --git a/support/dktools/DkWxBmepsFrame.h b/support/dktools/DkWxBmepsFrame.h
new file mode 100644
index 0000000000..34419dd5ed
--- /dev/null
+++ b/support/dktools/DkWxBmepsFrame.h
@@ -0,0 +1,389 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxBmepsFrame.wxc
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxBmepsFrame.h Header file for the DkWxBmepsFrame module.
+*/
+
+#ifndef DKWXBMEPSFRAME_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DKWXBMEPSFRAME_H_INCLUDED 1
+
+
+#line 146 "DkWxBmepsFrame.wxc"
+
+
+#line 148 "DkWxBmepsFrame.wxc"
+
+/** Top-level frame for the wxbmeps application.
+*/
+class DkWxBmepsFrame : public DkWxFrame
+{
+ private:
+
+ /** Event table.
+ */
+ DECLARE_EVENT_TABLE()
+
+ void
+ findPaperSizes();
+
+ protected:
+
+ /** Conversion options.
+ */
+ dk3_bm_eps_options_t bmeo;
+
+ /** Timestamp to close the application.
+ */
+ dk3_time_t timeClose;
+
+ /** Localized texts.
+ */
+ wxChar const * const *sTexts;
+
+ /** Localized dkChar texts.
+ */
+ dkChar const * const *msg;
+
+ /** Directory or file nameto process.
+ */
+ wxChar const *sDirectory;
+
+ /** Communication object for main thread and worker thread.
+ */
+ DkWxCommunicator *pComm;
+
+ /** Color: Black.
+ */
+ wxColour *cBlack;
+
+ /** Color: Green.
+ */
+ wxColour *cGreen;
+
+ /** Color: Red.
+ */
+ wxColour *cRed;
+
+ /** Paper sizes list.
+ */
+ wxArrayString *asPaperSizes;
+
+ /** Paper sizes array.
+ */
+ dk3_paper_size_t *paperSizes;
+
+ /** Number of paper sizes in the array.
+ */
+ size_t nPaperSizes;
+
+ /** Index of current paper size in asPaperSizes and paperSizes.
+ */
+ size_t currentPaperSize;
+
+ /** Directory dialog x position.
+ */
+ int ddx;
+
+ /** Directory dialog y position.
+ */
+ int ddy;
+
+ /** Options dialog x position.
+ */
+ int odx;
+
+ /** Options dialog y position.
+ */
+ int ody;
+
+ /** Flag: Save settings when the program exits.
+ */
+ bool bSaveSettings;
+
+ /** Flag: Command line options require automatic start.
+ */
+ bool bAutostartWanted;
+
+ /** Flag: Automatic start initialized.
+ */
+ bool bAutostartDone;
+
+ /** Flag: GUI active.
+ */
+ bool bGuiActive;
+
+ /** Flag: Close operation scheduled.
+ */
+ bool bCloseScheduled;
+
+ /** Flag: Setup was checked.
+ */
+ bool bSetupChecked;
+
+ /** Flag: GUI ok.
+ */
+ bool dkctGUILayoutOK;
+
+ /** Contents panel.
+ */
+ wxPanel *dkctGUIContentsPanel;
+
+ /** GUI element mbMain.
+ */
+#line 46 "DkWxBmepsFrame.wxc"
+ wxMenuBar *mbMain;
+
+ /** GUI element mainSizer.
+ */
+#line 104 "DkWxBmepsFrame.wxc"
+ wxBoxSizer *mainSizer;
+
+ /** GUI element tbMain.
+ */
+#line 16 "DkWxBmepsFrame.wxc"
+ wxToolBar *tbMain;
+
+ /** GUI element bDir.
+ */
+#line 22 "DkWxBmepsFrame.wxc"
+ wxToolBarToolBase *bDir;
+
+ /** GUI element bOptions.
+ */
+#line 28 "DkWxBmepsFrame.wxc"
+ wxToolBarToolBase *bOptions;
+
+ /** GUI element bRun.
+ */
+#line 34 "DkWxBmepsFrame.wxc"
+ wxToolBarToolBase *bRun;
+
+ /** GUI element bExit.
+ */
+#line 40 "DkWxBmepsFrame.wxc"
+ wxToolBarToolBase *bExit;
+
+ /** GUI element menuFile.
+ */
+#line 50 "DkWxBmepsFrame.wxc"
+ wxMenu *menuFile;
+
+ /** GUI element menuHelp.
+ */
+#line 57 "DkWxBmepsFrame.wxc"
+ wxMenu *menuHelp;
+
+ /** GUI element miFileDir.
+ */
+#line 62 "DkWxBmepsFrame.wxc"
+ wxMenuItem *miFileDir;
+
+ /** GUI element miFileOptions.
+ */
+#line 67 "DkWxBmepsFrame.wxc"
+ wxMenu *miFileOptions;
+
+ /** GUI element miFileRun.
+ */
+#line 84 "DkWxBmepsFrame.wxc"
+ wxMenuItem *miFileRun;
+
+ /** GUI element miFileExit.
+ */
+#line 89 "DkWxBmepsFrame.wxc"
+ wxMenuItem *miFileExit;
+
+ /** GUI element miHelpContents.
+ */
+#line 94 "DkWxBmepsFrame.wxc"
+ wxMenuItem *miHelpContents;
+
+ /** GUI element miHelpAbout.
+ */
+#line 99 "DkWxBmepsFrame.wxc"
+ wxMenuItem *miHelpAbout;
+
+ /** GUI element miFileOptionsSetup.
+ */
+#line 73 "DkWxBmepsFrame.wxc"
+ wxMenuItem *miFileOptionsSetup;
+
+ /** GUI element miFileOptionsReset.
+ */
+#line 78 "DkWxBmepsFrame.wxc"
+ wxMenuItem *miFileOptionsReset;
+
+ /** GUI element verticalSizer.
+ */
+#line 110 "DkWxBmepsFrame.wxc"
+ wxBoxSizer *verticalSizer;
+
+ /** GUI element contentsSizer.
+ */
+#line 122 "DkWxBmepsFrame.wxc"
+ wxGridBagSizer *contentsSizer;
+
+ /** GUI element tLogmessages.
+ */
+#line 133 "DkWxBmepsFrame.wxc"
+ wxTextCtrl *tLogmessages;
+
+ /** GUI element tStatus.
+ */
+#line 140 "DkWxBmepsFrame.wxc"
+ wxStaticText *tStatus;
+
+ /** GUI element lDirectory.
+ */
+#line 127 "DkWxBmepsFrame.wxc"
+ wxStaticText *lDirectory;
+
+ /** GUI element tDirectory.
+ */
+#line 130 "DkWxBmepsFrame.wxc"
+ wxStaticText *tDirectory;
+
+
+#line 257 "DkWxBmepsFrame.wxc"
+ public:
+
+ /** Constructor.
+ @param applicationName Application name.
+ @param messageTexts Localized texts.
+ @param ms Localized texts as dkChar strings.
+ @param applicationHelper Application helper.
+ @param wxid Window ID.
+ @param hc Help controller.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ */
+ DkWxBmepsFrame(
+ wxChar const *applicationName,
+ wxChar const * const *messageTexts,
+ dkChar const * const *ms,
+ DkWxAppHelper *applicationHelper,
+ int wxid,
+ DkWxHelpController *hc,
+ int argc,
+ wxChar **argv
+ );
+
+ /** Destructor.
+ */
+ ~DkWxBmepsFrame();
+
+ /** Check whether we can close the window.
+ @param isLast Flag: Last top level window.
+ */
+ bool
+ canClose(bool isLast);
+
+ /** Retrieve data from wxConfig.
+ */
+ void
+ retrieveData();
+
+ /** Save data to wxConfig.
+ */
+ void
+ saveData();
+
+ /** Menu event handler for File / Quit.
+ @param event Event to process.
+ */
+ void
+ OnQuit(wxCommandEvent& event);
+
+ /** Menu event handler for File / Directory.
+ */
+ void
+ OnChooseDirectory(wxCommandEvent& event);
+
+ /** Menu event handler for File / Options / Set.
+ */
+ void
+ OnSetOptions(wxCommandEvent& event);
+
+ /** Menu event handler for File / Options / Reset.
+ */
+ void
+ OnResetOptions(wxCommandEvent& event);
+
+
+ /** Menu event handler to run a conversion.
+ */
+ void
+ OnRunConversion(wxCommandEvent& event);
+
+ /** Menu event handler to show helpt contents.
+ */
+ void
+ OnHelpContents(wxCommandEvent& event);
+
+ /** Menu event handler to show version number.
+ */
+ void
+ OnAbout(wxCommandEvent& event);
+
+ /** Idle event handler
+ */
+ void
+ OnIdle(wxIdleEvent & event);
+
+ /** Run a conversion.
+ */
+ void
+ runConversion(void);
+
+ /** Check whether GUI is active.
+ @return Flag, GUI is active.
+ */
+ bool
+ isGuiActive();
+
+ /** Check setup.
+ @return Flag to indicate setup ok or not.
+ */
+ bool
+ checkSetup();
+};
+
+
+
+#line 362 "DkWxBmepsFrame.wxc"
+
+
+#endif
diff --git a/support/dktools/DkWxBmepsFrame.wxc b/support/dktools/DkWxBmepsFrame.wxc
new file mode 100644
index 0000000000..1d367de58a
--- /dev/null
+++ b/support/dktools/DkWxBmepsFrame.wxc
@@ -0,0 +1,1171 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+%% wx-gui
+
+type = frame
+menu bar = mbMain
+contents = mainSizer
+tool bar = tbMain
+icon = dkicon_bitmap
+status bar = 1 sTexts[3]
+
+[wxToolBar tbMain]
+contents = bDir
+contents = bOptions
+contents = bRun
+contents = bExit
+
+[wxToolBarToolBase bDir]
+text = sTexts[4]
+bitmap = xpm_choose_dir
+id = DkWxBmeps_ChooseDirectory
+tip = sTexts[5]
+
+[wxToolBarToolBase bOptions]
+text = sTexts[6]
+bitmap = xpm_set_options
+id = DkWxBmeps_SetOptions
+tip = sTexts[7]
+
+[wxToolBarToolBase bRun]
+text = sTexts[8]
+bitmap = xpm_run_conversion
+id = DkWxBmeps_Run
+tip = sTexts[9]
+
+[wxToolBarToolBase bExit]
+text = sTexts[10]
+bitmap = xpm_exit_program
+id = DkWxBmeps_Quit
+tip = sTexts[11]
+
+[wxMenuBar mbMain]
+contents = menuFile
+contents = menuHelp
+
+[wxMenu menuFile]
+contents = miFileDir
+contents = miFileOptions
+contents = miFileRun
+contents = miFileExit
+text = sTexts[12]
+
+[wxMenu menuHelp]
+contents = miHelpContents
+contents = miHelpAbout
+text = sTexts[13]
+
+[wxMenuItem miFileDir]
+id = DkWxBmeps_ChooseDirectory
+text = sTexts[14]
+tip = sTexts[15]
+
+[wxMenu miFileOptions]
+text = sTexts[16]
+tip = sTexts[17]
+contents = miFileOptionsSetup
+contents = miFileOptionsReset
+
+[wxMenuItem miFileOptionsSetup]
+id = DkWxBmeps_SetOptions
+text = sTexts[99]
+tip = sTexts[100]
+
+[wxMenuItem miFileOptionsReset]
+id = DkWxBmeps_ResetOptions
+text = sTexts[101]
+tip = sTexts[102]
+
+
+[wxMenuItem miFileRun]
+id = DkWxBmeps_Run
+text = sTexts[18]
+tip = sTexts[19]
+
+[wxMenuItem miFileExit]
+id = DkWxBmeps_Quit
+text = sTexts[20]
+tip = sTexts[21]
+
+[wxMenuItem miHelpContents]
+id = DkWxBmeps_Help_Contents
+text = sTexts[22]
+tip = sTexts[23]
+
+[wxMenuItem miHelpAbout]
+id = DkWxBmeps_About
+text = sTexts[24]
+tip = sTexts[25]
+
+[wxBoxSizer mainSizer]
+direction = horizontal
+contents = $space(10)
+contents = verticalSizer
+contents = $space(10)
+
+[wxBoxSizer verticalSizer]
+direction = vertical
+grow = yes
+proportion = 1
+contents = $space(10)
+contents = contentsSizer left
+contents = $space(10)
+contents = tLogmessages left top
+contents = $space(10)
+contents = tStatus left
+contents = $space(10)
+
+[wxGridBagSizer contentsSizer]
+grid = 5 5
+contents = lDirectory 0 0 1 1 right
+contents = tDirectory . 1 1 1
+
+[wxStaticText lDirectory]
+text = sTexts[26]
+
+[wxStaticText tDirectory]
+text = ((sDirectory) ? sDirectory : sTexts[27])
+
+[wxTextCtrl tLogmessages]
+grow = yes
+proportion = 1
+size = 400 60
+text style = readonly multiline left no-wrap selection
+text = sTexts[28]
+
+[wxStaticText tStatus]
+text = sTexts[28]
+
+
+
+%% header start
+
+%% class start
+
+/** Top-level frame for the wxbmeps application.
+*/
+class DkWxBmepsFrame : public DkWxFrame
+{
+ private:
+
+ /** Event table.
+ */
+ DECLARE_EVENT_TABLE()
+
+ void
+ findPaperSizes();
+
+ protected:
+
+ /** Conversion options.
+ */
+ dk3_bm_eps_options_t bmeo;
+
+ /** Timestamp to close the application.
+ */
+ dk3_time_t timeClose;
+
+ /** Localized texts.
+ */
+ wxChar const * const *sTexts;
+
+ /** Localized dkChar texts.
+ */
+ dkChar const * const *msg;
+
+ /** Directory or file nameto process.
+ */
+ wxChar const *sDirectory;
+
+ /** Communication object for main thread and worker thread.
+ */
+ DkWxCommunicator *pComm;
+
+ /** Color: Black.
+ */
+ wxColour *cBlack;
+
+ /** Color: Green.
+ */
+ wxColour *cGreen;
+
+ /** Color: Red.
+ */
+ wxColour *cRed;
+
+ /** Paper sizes list.
+ */
+ wxArrayString *asPaperSizes;
+
+ /** Paper sizes array.
+ */
+ dk3_paper_size_t *paperSizes;
+
+ /** Number of paper sizes in the array.
+ */
+ size_t nPaperSizes;
+
+ /** Index of current paper size in asPaperSizes and paperSizes.
+ */
+ size_t currentPaperSize;
+
+ /** Directory dialog x position.
+ */
+ int ddx;
+
+ /** Directory dialog y position.
+ */
+ int ddy;
+
+ /** Options dialog x position.
+ */
+ int odx;
+
+ /** Options dialog y position.
+ */
+ int ody;
+
+ /** Flag: Save settings when the program exits.
+ */
+ bool bSaveSettings;
+
+ /** Flag: Command line options require automatic start.
+ */
+ bool bAutostartWanted;
+
+ /** Flag: Automatic start initialized.
+ */
+ bool bAutostartDone;
+
+ /** Flag: GUI active.
+ */
+ bool bGuiActive;
+
+ /** Flag: Close operation scheduled.
+ */
+ bool bCloseScheduled;
+
+ /** Flag: Setup was checked.
+ */
+ bool bSetupChecked;
+
+%% class end
+ public:
+
+ /** Constructor.
+ @param applicationName Application name.
+ @param messageTexts Localized texts.
+ @param ms Localized texts as dkChar strings.
+ @param applicationHelper Application helper.
+ @param wxid Window ID.
+ @param hc Help controller.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ */
+ DkWxBmepsFrame(
+ wxChar const *applicationName,
+ wxChar const * const *messageTexts,
+ dkChar const * const *ms,
+ DkWxAppHelper *applicationHelper,
+ int wxid,
+ DkWxHelpController *hc,
+ int argc,
+ wxChar **argv
+ );
+
+ /** Destructor.
+ */
+ ~DkWxBmepsFrame();
+
+ /** Check whether we can close the window.
+ @param isLast Flag: Last top level window.
+ */
+ bool
+ canClose(bool isLast);
+
+ /** Retrieve data from wxConfig.
+ */
+ void
+ retrieveData();
+
+ /** Save data to wxConfig.
+ */
+ void
+ saveData();
+
+ /** Menu event handler for File / Quit.
+ @param event Event to process.
+ */
+ void
+ OnQuit(wxCommandEvent& event);
+
+ /** Menu event handler for File / Directory.
+ */
+ void
+ OnChooseDirectory(wxCommandEvent& event);
+
+ /** Menu event handler for File / Options / Set.
+ */
+ void
+ OnSetOptions(wxCommandEvent& event);
+
+ /** Menu event handler for File / Options / Reset.
+ */
+ void
+ OnResetOptions(wxCommandEvent& event);
+
+
+ /** Menu event handler to run a conversion.
+ */
+ void
+ OnRunConversion(wxCommandEvent& event);
+
+ /** Menu event handler to show helpt contents.
+ */
+ void
+ OnHelpContents(wxCommandEvent& event);
+
+ /** Menu event handler to show version number.
+ */
+ void
+ OnAbout(wxCommandEvent& event);
+
+ /** Idle event handler
+ */
+ void
+ OnIdle(wxIdleEvent & event);
+
+ /** Run a conversion.
+ */
+ void
+ runConversion(void);
+
+ /** Check whether GUI is active.
+ @return Flag, GUI is active.
+ */
+ bool
+ isGuiActive();
+
+ /** Check setup.
+ @return Flag to indicate setup ok or not.
+ */
+ bool
+ checkSetup();
+};
+
+
+%% header end
+
+%% module start
+
+
+
+#include "wxbmeps.h"
+
+/*
+ Icons and bitmaps
+*/
+#include "dkicon.xpm"
+#include "choose-dir.xpm"
+#include "exit-program.xpm"
+#include "run-conversion.xpm"
+#include "set-options.xpm"
+#include "dk4verswx.h"
+
+
+
+$!trace-include
+
+
+
+/** Start of version information.
+*/
+static wxChar const wxbmpp_version[] = {
+ wxT("wxbmpp (part of dktools-")
+};
+
+
+
+/** Version number for version information.
+*/
+static wxChar const wxbmpp_versnumber[] = {
+ DKT_VERSION_WX
+};
+
+
+
+/** End of version information.
+*/
+static wxChar const wxbmpp_versend[] = {
+ wxT(")")
+};
+
+
+
+/** Setting names for string settings.
+*/
+wxChar const * const dkwxbmeps_string_setting_names[] = {
+$!string-table macro=wxT
+#
+# 0: Current directory
+#
+wxbmeps.directory
+#
+#
+#
+wxbmeps.paper-size
+$!end
+};
+
+
+
+/** Setting names for double settings.
+*/
+wxChar const * const dkwxbmeps_double_setting_names[] = {
+$!string-table macro=wxT
+wxbmeps.area.w
+wxbmeps.area.h
+wxbmeps.area.border.left
+wxbmeps.area.border.right
+wxbmeps.area.border.top
+wxbmeps.area.border.bottom
+wxbmeps.resolution
+$!end
+};
+
+
+
+/** Setting names for int settings.
+*/
+wxChar const * const dkwxbmeps_int_setting_names[] = {
+$!string-table macro=wxT
+wxbmeps.driver
+wxbmeps.mode
+wxbmeps.size-mode
+wxbmeps.color
+wxbmeps.predictor
+wxbmeps.image-origin-point
+wxbmeps.draft
+wxbmeps.duplex
+wxbmeps.tumble
+wxbmeps.ps-level
+wxbmeps.dsc
+wxbmeps.dct
+wxbmeps.keep-aspect-ratio
+wxbmeps.bg.red
+wxbmeps.bg.green
+wxbmeps.bg.blue
+wxbmeps.bg.force
+wxbmeps.interpolation
+wxbmeps.interpolation-for-jpeg
+wxbmeps.make
+wxbmeps.reduce-bits-per-component
+$!end
+};
+
+
+
+static const wxCmdLineEntryDesc wxbmepsframe_cmd_line_desc[] = {
+ {
+ wxCMD_LINE_OPTION,
+ wxT_2("l"),
+ wxT_2("language"),
+ wxT_2("Choose output language"),
+ wxCMD_LINE_VAL_STRING
+ },
+ {
+ wxCMD_LINE_SWITCH,
+ wxT_2("m"),
+ wxT_2("make"),
+ wxT_2("Run in make mode")
+ },
+ {
+ wxCMD_LINE_SWITCH,
+ wxT_2("r"),
+ wxT_2("run"),
+ wxT_2("Run immediately")
+ },
+ {
+ wxCMD_LINE_PARAM,
+ NULL,
+ NULL,
+ wxT_2("input file"),
+ wxCMD_LINE_VAL_STRING,
+ wxCMD_LINE_PARAM_OPTIONAL
+ },
+ { wxCMD_LINE_NONE }
+};
+
+
+/** Event table for the DkWxBmepsFrame class.
+*/
+BEGIN_EVENT_TABLE(DkWxBmepsFrame, wxFrame)
+ EVT_MENU(DkWxBmeps_Quit, DkWxBmepsFrame::OnQuit)
+ EVT_MENU(DkWxBmeps_Help_Contents, DkWxBmepsFrame::OnHelpContents)
+ EVT_MENU(DkWxBmeps_About, DkWxBmepsFrame::OnAbout)
+ EVT_MENU(DkWxBmeps_ChooseDirectory, DkWxBmepsFrame::OnChooseDirectory)
+ EVT_MENU(DkWxBmeps_SetOptions, DkWxBmepsFrame::OnSetOptions)
+ EVT_MENU(DkWxBmeps_ResetOptions, DkWxBmepsFrame::OnResetOptions)
+ EVT_MENU(DkWxBmeps_Run, DkWxBmepsFrame::OnRunConversion)
+ EVT_IDLE(DkWxBmepsFrame::OnIdle)
+END_EVENT_TABLE()
+
+
+
+%% constructor start
+DkWxBmepsFrame::DkWxBmepsFrame(
+ wxChar const *applicationName,
+ wxChar const * const *messageTexts,
+ dkChar const * const *m,
+ DkWxAppHelper *applicationHelper,
+ int wxid,
+ DkWxHelpController *hc,
+ int argc,
+ wxChar **argv
+) : DkWxFrame(applicationName, applicationHelper, hc, wxid)
+{
+#if defined(__WXMSW__)
+ wxIcon dkicon_bitmap(wxT("aaaaa")); /* from resource file */
+#else
+ wxIcon dkicon_bitmap(xpm_dkicon); /* from included xpm */
+#endif
+ $? "+ DkWxBmepsFrame::DkWxBmepsFrame %d", argc
+ ddx = -1;
+ ddy = -1;
+ odx = -1;
+ ody = -1;
+ pComm = NULL;
+ timeClose = (dk3_time_t)0UL;
+ bSetupChecked = false;
+ sTexts = messageTexts;
+ msg = m;
+ bSaveSettings = true;
+ bGuiActive = true;
+ bCloseScheduled = false;
+ bAutostartWanted = false;
+ bAutostartDone = false;
+ sDirectory = NULL;
+ cBlack = NULL;
+ cGreen = NULL;
+ cRed = NULL;
+ dk3bmeo_init(&bmeo);
+ bmeo.app = applicationHelper->getApp();
+ dk3bmeo_apply_preferences(&bmeo);
+ asPaperSizes = new wxArrayString();
+ paperSizes = NULL;
+ nPaperSizes = 0;
+ currentPaperSize = 0;
+ findPaperSizes();
+ retrieveData();
+%% constructor end
+ pComm = new DkWxCommunicator(
+ applicationHelper->getWxEncoding(),
+ applicationHelper->getDkEncoding()
+ );
+ cBlack = new wxColour(0x00, 0x00, 0x00);
+ cGreen = new wxColour(0x00, 0x7F, 0x00);
+ cRed = new wxColour(0x7F, 0x00, 0x00);
+ if(argc > 1) { /* Any option or argument, no persistent settings. */
+ bSaveSettings = false;
+ dk3bmeo_init(&bmeo);
+#if VERSION_BEFORE_20131020
+ bAutostartWanted = true;
+ if(pComm) { $? ". enable autostart"
+ pComm->autostartEnable(true);
+ }
+#endif
+ /* ##### Process command line arguments. */
+ {
+ int res = -1;
+ wxCmdLineParser parser(wxbmepsframe_cmd_line_desc, argc, argv);
+ {
+ wxLogNull log;
+ res = parser.Parse(false);
+ }
+ if(res == 0) {
+ wxString sLanguage(wxT(""));
+ dkChar bu[1024];
+ wxChar const *ptr;
+ if(parser.Found(wxT("r"))) {
+ bAutostartWanted = true;
+ if(pComm) { $? ". enable autostart"
+ pComm->autostartEnable(true);
+ }
+ }
+ if(parser.Found(wxT("m"))) {
+ bmeo.make = 1;
+ }
+ if(parser.Found(wxT("l"), &sLanguage)) {
+ ptr = sLanguage.c_str();
+ if(ptr) {
+ if(applicationHelper->wxToDk(bu, DK3_SIZEOF(bu,dkChar), ptr)) {
+ (void)dk3bmeo_set_language(
+ &bmeo, bu, applicationHelper->getApp()
+ );
+ }
+ }
+ }
+ if(parser.GetParamCount() > 0) { $? ". parameters available"
+ wxString cmdfn;
+ wxChar const *newfn;
+ cmdfn = parser.GetParam(0);
+ wxFileName fn(cmdfn);
+ fn.Normalize(
+ wxPATH_NORM_LONG | wxPATH_NORM_DOTS
+ | wxPATH_NORM_TILDE | wxPATH_NORM_ABSOLUTE
+ );
+ if(fn.FileExists()) {
+ bAutostartWanted = true;
+ if(pComm) { $? ". enable autostart"
+ pComm->autostartEnable(true);
+ }
+ }
+ cmdfn = fn.GetFullPath();
+ newfn = cmdfn.c_str();
+ if(newfn) { $? ". newfn (1)"
+ newfn = dk3wxs_dup_app(newfn, applicationHelper->getApp());
+ if(newfn) { $? ". newfn (2)"
+ dk3_release(sDirectory);
+ sDirectory = newfn;
+ } else { $? "! newfn (2)"
+ }
+ } else { $? "! newfn (1)"
+ }
+ } else { $? ". no parameters"
+ }
+ }
+ }
+ /* (void)dk3bmeo_check(&bmeo, 0, applicationHelper->getApp(), NULL); */
+ }
+ $? ". sDirectory = \"%ls\"", sDirectory
+ $? ". make = %d", bmeo.make
+ $? ". driver = %d", bmeo.dr
+ $? ". mode = %d", bmeo.mode
+ $? ". ps level = %d", bmeo.psl
+ $? ". dsc = %d", bmeo.dsc
+ $? ". draft = %d", bmeo.draft
+ $? ". szmode = %d", bmeo.szmode
+ $? ". resolution = %lg", bmeo.resolution
+ $? ". area = %lg %lg", bmeo.ima.ps.w, bmeo.ima.ps.h
+ $? ". keep aspect = %d", bmeo.kar
+ $? ". duplex = %d", bmeo.duplex
+ $? ". tumble = %d", bmeo.tumble
+ $? ". origin = %d", bmeo.io
+ $? ". dct = %d", bmeo.dct
+ $? ". predicotr = %d", bmeo.pred
+ $? ". background = %d %d %d %d", bmeo.bgr, bmeo.bgg, bmeo.bgb, bmeo.fbg
+ $? ". interpolate = %d %d", bmeo.ip, bmeo.jip
+#if 0
+ restorePosition();
+#endif
+ $? "- DkWxBmepsFrame::DkWxBmepsFrame"
+}
+
+%% module end
+
+
+DkWxBmepsFrame::~DkWxBmepsFrame()
+{
+ $? "+ DkWxBmepsFrame::~DkWxBmepsFrame"
+ dk3_release(paperSizes);
+ dk3_release(sDirectory);
+ dk3_cpp_release(pComm);
+ dk3_cpp_release(cBlack);
+ dk3_cpp_release(cGreen);
+ dk3_cpp_release(cRed);
+ dk3_cpp_release(asPaperSizes);
+ $? "- DkWxBmepsFrame::~DkWxBmepsFrame"
+}
+
+
+
+void
+DkWxBmepsFrame::saveData()
+{
+ double d[7];
+ int i[21];
+ $? "+ DkWxBmepsFrame::saveData"
+ d[0] = bmeo.ima.ps.w;
+ d[1] = bmeo.ima.ps.h;
+ d[2] = bmeo.ima.ps.i;
+ d[3] = bmeo.ima.ps.o;
+ d[4] = bmeo.ima.ps.t;
+ d[5] = bmeo.ima.ps.b;
+ d[6] = bmeo.resolution;
+ i[0] = bmeo.dr;
+ i[1] = bmeo.mode;
+ i[2] = bmeo.szmode;
+ /* i[3] = bmeo.color; */
+ i[3] = 0;
+ i[4] = bmeo.pred;
+ i[5] = bmeo.io;
+ i[6] = bmeo.draft;
+ i[7] = bmeo.duplex;
+ i[8] = bmeo.tumble;
+ i[9] = bmeo.psl;
+ i[10] = bmeo.dsc;
+ i[11] = bmeo.dct;
+ i[12] = bmeo.kar;
+ i[13] = bmeo.bgr;
+ i[14] = bmeo.bgg;
+ i[15] = bmeo.bgb;
+ i[16] = bmeo.fbg;
+ i[17] = bmeo.ip;
+ i[18] = bmeo.jip;
+ i[19] = bmeo.make;
+ i[20] = bmeo.rbpc;
+ pHelper->saveMultipleDoubles(dkwxbmeps_double_setting_names, d);
+ pHelper->saveMultipleInts(dkwxbmeps_int_setting_names, i);
+ if(sDirectory) {
+ pHelper->saveString(dkwxbmeps_string_setting_names[0], sDirectory);
+ }
+ pHelper->saveString(
+ dkwxbmeps_string_setting_names[1],
+ asPaperSizes->Item(currentPaperSize)
+ );
+ /* ##### */
+ $? "- DkWxBmepsFrame::saveData"
+}
+
+
+
+void
+DkWxBmepsFrame::retrieveData()
+{
+ double d[7];
+ int i[21];
+ $? "+ DkWxBmepsFrame::retrieveData"
+ d[0] = bmeo.ima.ps.w;
+ d[1] = bmeo.ima.ps.h;
+ d[2] = bmeo.ima.ps.i;
+ d[3] = bmeo.ima.ps.o;
+ d[4] = bmeo.ima.ps.t;
+ d[5] = bmeo.ima.ps.b;
+ d[6] = bmeo.resolution;
+ i[0] = bmeo.dr;
+ i[1] = bmeo.mode;
+ i[2] = bmeo.szmode;
+ /* i[3] = bmeo.color; */
+ i[3] = 0;
+ i[4] = bmeo.pred;
+ i[5] = bmeo.io;
+ i[6] = bmeo.draft;
+ i[7] = bmeo.duplex;
+ i[8] = bmeo.tumble;
+ i[9] = bmeo.psl;
+ i[10] = bmeo.dsc;
+ i[11] = bmeo.dct;
+ i[12] = bmeo.kar;
+ i[13] = bmeo.bgr;
+ i[14] = bmeo.bgg;
+ i[15] = bmeo.bgb;
+ i[16] = bmeo.fbg;
+ i[17] = bmeo.ip;
+ i[18] = bmeo.jip;
+ i[19] = bmeo.make;
+ i[20] = bmeo.rbpc;
+ pHelper->retrieveMultipleDoubles(dkwxbmeps_double_setting_names, d);
+ bmeo.ima.ps.w = d[0];
+ bmeo.ima.ps.h = d[1];
+ bmeo.ima.ps.i = d[2];
+ bmeo.ima.ps.o = d[3];
+ bmeo.ima.ps.t = d[4];
+ bmeo.ima.ps.b = d[5];
+ bmeo.resolution = d[6];
+ pHelper->retrieveMultipleInts(dkwxbmeps_int_setting_names, i);
+ bmeo.dr = i[0];
+ bmeo.mode = i[1];
+ bmeo.szmode = i[2]; $? ". szmode = %d", bmeo.szmode
+ /* bmeo.color = i[3]; */
+ bmeo.pred = i[4];
+ bmeo.io = i[5];
+ bmeo.draft = i[6];
+ bmeo.duplex = i[7];
+ bmeo.tumble = i[8];
+ bmeo.psl = i[9];
+ bmeo.dsc = i[10];
+ bmeo.dct = i[11];
+ bmeo.kar = i[12];
+ bmeo.bgr = i[13];
+ bmeo.bgg = i[14];
+ bmeo.bgb = i[15];
+ bmeo.fbg = i[16];
+ bmeo.ip = i[17];
+ bmeo.jip = i[18];
+ bmeo.make = i[19];
+ bmeo.rbpc = i[20];
+ currentPaperSize = 0;
+ sDirectory = pHelper->retrieveString(dkwxbmeps_string_setting_names[0]);
+ {
+ wxChar const *psn;
+ int j;
+ psn = pHelper->retrieveString(dkwxbmeps_string_setting_names[1]);
+ if(psn) {
+ j = asPaperSizes->Index(psn);
+ if(j != wxNOT_FOUND) {
+ currentPaperSize = (size_t)j;
+ }
+ dk3_release(psn);
+ }
+ }
+ $? "- DkWxBmepsFrame::retrieveData"
+ /* ##### */
+}
+
+
+
+void
+DkWxBmepsFrame::runConversion(void)
+{
+ DkWxProgressDialog *pd = NULL;
+ DkWxBmepsThread *pt = NULL;
+ $? "+ runConversion"
+ if(tStatus) {
+ tStatus->SetLabel(sTexts[28]);
+ if(cBlack) {
+ tStatus->SetForegroundColour(*cBlack);
+ }
+ }
+ if(pComm) {
+ pComm->prepareRun();
+ pd = new DkWxProgressDialog(
+ (DkWxFrame *)this,
+ pComm,
+ tLogmessages,
+ sTexts[32], /* title */
+ sTexts[28], /* file name */
+ sTexts[33], /* button text */
+ sTexts[34], /* button tool tip */
+ sTexts[35] /* wait text */
+ );
+ if(pd) {
+ pt = new DkWxBmepsThread(
+ pComm,
+ sTexts,
+ msg,
+ sDirectory,
+ pHelper,
+ pHelper->getWxEncoding(),
+ pHelper->getDkEncoding(),
+ &bmeo
+ );
+ if(pt) {
+ if(pt->checkSetup()) {
+ if(pt->Create() == wxTHREAD_NO_ERROR) {
+ pt->SetPriority(WXTHREAD_DEFAULT_PRIORITY);
+ pt->Run();
+ pd->chooseModalPosition();
+ pd->ShowModal();
+ if(pComm->getLogLevel() <= DK3_LL_WARNING) {
+ bGuiActive = true;
+ }
+ } else { $? "! pt->Create()"
+ delete(pt);
+ /* ##### ERROR: Failed to create new thread! */
+ }
+ } else {
+ /* ##### ERROR: Memory! */
+ delete(pt);
+ }
+ } else { $? "! pt"
+ /* ##### ERROR: Failed to construct new thread! */
+ }
+ pd->Destroy();
+ } else { $? "! pd"
+ /* ##### ERROR: Failed to create progress dialog! */
+ }
+ } else { $? "! pComm"
+ /* ##### ERROR: Setup incomplete! */
+ }
+ $? "- runConversion"
+}
+
+
+
+void
+DkWxBmepsFrame::OnIdle(wxIdleEvent & event)
+{
+ dk3_time_t ct; /* Current time. */
+ $? "+ DkWxBmepsFrame::OnIdle"
+ if(!bCloseScheduled) {
+ if(!bSetupChecked) {
+ bSetupChecked = true;
+ if(!checkSetup()) {
+ bCloseScheduled = true;
+ /* ##### Show message: Failed to initialize! */
+ Show(false);
+ Close();
+ }
+ }
+ if(!bCloseScheduled) { $? ". no close scheduled"
+ if(pComm->autostartCanRun()) { $? ". can autostart"
+ runConversion();
+ } else { $? ". can not autostart"
+ if(pComm->autostartIsFinished()) { $? ". autostart finished"
+ if(!(timeClose)) {
+ if(pComm->getLogLevel() > DK3_LL_WARNING) {
+ dk3sf_time(&timeClose);
+ event.RequestMore();
+ tStatus->SetLabel(sTexts[30]);
+ if((cGreen) && (cBlack)) {
+ tStatus->SetForegroundColour(*cGreen);
+ }
+ Refresh();
+ Update();
+ }
+ }
+ }
+ }
+ if(timeClose) {
+ dk3sf_time(&ct);
+ if(ct > (timeClose + (dk3_time_t)1UL)) {
+ timeClose = (dk3_time_t)0UL;
+ bCloseScheduled = true;
+ Show(false);
+ Close();
+ } else {
+ event.RequestMore();
+ }
+ }
+ }
+ }
+ $? "- DkWxBmepsFrame::OnIdle"
+}
+
+
+
+void
+DkWxBmepsFrame::OnChooseDirectory(wxCommandEvent& WXUNUSED(event))
+{
+ wxChar const *ptr;
+ wxChar const *np;
+ $? "+ DkWxBmepsFrame::OnChooseDirectory"
+ if(isGuiActive()) {
+ wxDirDialog dd(
+ this, sTexts[29],
+ ((sDirectory) ? sDirectory : wxEmptyString),
+ (wxDD_DIR_MUST_EXIST | wxDD_CHANGE_DIR)
+ );
+ pHelper->setRelatedPosition(this, &dd, &ddx, &ddy);
+ if(dd.ShowModal() == wxID_OK) {
+ wxString path = dd.GetPath();
+ ptr = path.c_str();
+ if(ptr) {
+ np = dk3wxs_dup_app(ptr, pHelper->getApp());
+ if(np) {
+ dk3_release(sDirectory);
+ sDirectory = np;
+ if(tDirectory) {
+ tDirectory->SetLabel(sDirectory);
+ Refresh();
+ Update();
+ }
+ }
+ }
+ }
+ dd.GetPosition(&ddx, &ddy);
+ } $? "- DkWxBmepsFrame::OnChooseDirectory"
+}
+
+
+
+void
+DkWxBmepsFrame::OnRunConversion(wxCommandEvent& WXUNUSED(event))
+{
+ $? "+ DkWxBmepsFrame::OnRunConversion"
+ if(isGuiActive()) {
+ runConversion();
+ }
+ $? "- DkWxBmepsFrame::OnRunConversion"
+}
+
+
+
+bool
+DkWxBmepsFrame::isGuiActive()
+{
+ bool back;
+ back = bGuiActive;
+ $? "+ DkWxBmepsFrame::isGuiActive"
+ if(bCloseScheduled) { back = false; }
+ $? "- DkWxBmepsFrame::isGuiActive"
+ return back;
+}
+
+
+
+bool
+DkWxBmepsFrame::canClose(bool isLast)
+{
+ $? "+ DkWxBmepsFrame::canClose %d", (isLast ? 1 : 0)
+ if(isLast) {
+ if(bSaveSettings) {
+ saveData();
+ }
+ } $? "- DkWxBmepsFrame::canClose 1"
+ return true;
+}
+
+
+
+void
+DkWxBmepsFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
+{
+ $? "+ DkWxBmepsFrame::OnQuit"
+ if(isGuiActive()) {
+ bCloseScheduled = true;
+ Show(false);
+ Close();
+ }
+ $? "- DkWxBmepsFrame::OnQuit"
+}
+
+
+
+bool
+DkWxBmepsFrame::checkSetup()
+{
+ bool back = false;
+ if(pComm) {
+ if((cBlack) && (cGreen) && (cRed)) {
+ if((asPaperSizes) && (paperSizes)) {
+ back = true;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void
+DkWxBmepsFrame::OnSetOptions(wxCommandEvent& WXUNUSED(event))
+{
+ int dke;
+ int wxe;
+ $? "+ OnSetOptions"
+ dke = pHelper->getDkEncoding();
+ wxe = pHelper->getWxEncoding();
+ if(isGuiActive()) {
+ DkWxBmepsOptionsDialog dlg(
+ (DkWxBmepsFrame *)this, sTexts[36], sTexts, asPaperSizes,
+ &bmeo, paperSizes, &currentPaperSize, pHelper, dke, wxe
+ );
+ pHelper->setRelatedPosition(this, &dlg, &odx, &ody);
+ dlg.dataIn();
+ if(dlg.ShowModal() == wxID_OK) {
+ dk3mem_cpy(
+ (void *)(&(bmeo.ima.ps)),
+ (void *)(&(paperSizes[currentPaperSize])),
+ sizeof(dk3_paper_size_t)
+ );
+ $? "%lg %lg %lg %lg %lg %lg", bmeo.ima.ps.w, bmeo.ima.ps.h, bmeo.ima.ps.i, bmeo.ima.ps.o, bmeo.ima.ps.t, bmeo.ima.ps.b
+ }
+ dlg.GetPosition(&odx, &ody);
+ }
+ $? "- OnSetOptions"
+}
+
+
+
+void
+DkWxBmepsFrame::OnResetOptions(wxCommandEvent& WXUNUSED(event))
+{
+ int res;
+ res = wxMessageBox(
+ sTexts[103],
+ sTexts[104],
+ wxNO_DEFAULT|wxYES_NO
+ );
+ if(res == wxYES) {
+ dk3bmeo_init(&bmeo);
+ }
+}
+
+
+
+void
+DkWxBmepsFrame::findPaperSizes()
+{
+ wxChar bu[64];
+ dk3_paper_size_collection_t *psc;
+ dk3_named_paper_size_t const *nsz;
+ dk3_paper_size_t *pps;
+ dk3_app_t *app;
+ $? "+ DkWxBmepsFrame::findPaperSizes"
+ if(asPaperSizes) { $? ". asPaperSizes ok"
+ app = pHelper->getApp();
+ psc = dk3paper_open_app(app);
+ if(psc) { $? ". psc ok"
+ dk3paper_reset(psc);
+ while((nsz = dk3paper_next(psc)) != NULL) {
+ if(nsz->name) {
+ if(pHelper->dkToWx(bu, DK3_SIZEOF(bu,wxChar), nsz->name)) {
+ $? ". register \"%!ds\"", nsz->name
+ asPaperSizes->Add(bu);
+ nPaperSizes++;
+ }
+ }
+ }
+ if(nPaperSizes) { $? ". nPaperSizes %u", (unsigned)nPaperSizes
+ paperSizes = dk3_new_app(dk3_paper_size_t,nPaperSizes,app);
+ if(paperSizes) { $? ". paperSizes ok"
+ pps = paperSizes;
+ dk3paper_reset(psc);
+ while((nsz = dk3paper_next(psc)) != NULL) {
+ if(nsz->name) {
+ if(pHelper->dkToWx(bu, DK3_SIZEOF(bu,wxChar), nsz->name))
+ { $? ". register \"%!ds\"", nsz->name
+ dk3mem_cpy(
+ (void *)pps,
+ (void *)(&(nsz->size)),
+ sizeof(dk3_paper_size_t)
+ );
+ pps++;
+ }
+ }
+ }
+ }
+ }
+ dk3paper_close(psc);
+ }
+ }
+ $? "- DkWxBmepsFrame::findPaperSizes"
+}
+
+
+
+void
+DkWxBmepsFrame::OnHelpContents(wxCommandEvent& WXUNUSED(event))
+{
+ openHelp();
+}
+
+
+
+void
+DkWxBmepsFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
+{
+ if(isGuiActive()) {
+ wxString sVersion(wxbmpp_version);
+ sVersion.Append(wxbmpp_versnumber);
+ sVersion.Append(wxbmpp_versend);
+ sVersion.Append(wxT("\nCopyright (c) 2013-2016 - Dirk Krause\n\n"));
+ sVersion.Append(sTexts[123]);
+ sVersion.Append(wxT("DK tools, wxWidgets, libpng, libjpeg, libtiff, zlib."));
+ sVersion.Append(wxT("\n\n"));
+ sVersion.Append(sTexts[124]);
+ sVersion.Append(wxT("http://dktools.sourceforge.net\n"));
+ sVersion.Append(wxT("http://www.wxwidgets.org\n"));
+ sVersion.Append(wxT("http://www.libpng.org/pub/png/libpng.html\n"));
+ sVersion.Append(wxT("http://www.ijg.org\n"));
+ sVersion.Append(wxT("http://www.remotesensing.org/libtiff\n"));
+ sVersion.Append(wxT("http://www.zlib.org"));
+ wxMessageBox(sVersion, sTexts[122]);
+ }
+}
+
diff --git a/support/dktools/DkWxBmepsOptionsDialog.cpp b/support/dktools/DkWxBmepsOptionsDialog.cpp
new file mode 100644
index 0000000000..f81c179881
--- /dev/null
+++ b/support/dktools/DkWxBmepsOptionsDialog.cpp
@@ -0,0 +1,1216 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxBmepsOptionsDialog.wxc
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxBmepsOptionsDialog.cpp The DkWxBmepsOptionsDialog module.
+*/
+
+
+#line 384 "DkWxBmepsOptionsDialog.wxc"
+
+#include "wxbmeps.h"
+
+
+
+
+
+#line 390 "DkWxBmepsOptionsDialog.wxc"
+
+BEGIN_EVENT_TABLE(DkWxBmepsOptionsDialog, wxDialog)
+ EVT_BUTTON(wxID_OK, DkWxBmepsOptionsDialog::OnOK)
+ EVT_BUTTON(wxID_CANCEL, DkWxBmepsOptionsDialog::OnCancel)
+ EVT_CHOICE(DkWxBmeps_OuputFormat, DkWxBmepsOptionsDialog::OnOutputFormat)
+ EVT_CHOICE(DkWxBmeps_OutputType, DkWxBmepsOptionsDialog::OnOutputType)
+ EVT_CHOICE(DkWxBmeps_ResolutionType, DkWxBmepsOptionsDialog::OnResolution)
+ EVT_CHECKBOX(DkWxBmeps_Draft, DkWxBmepsOptionsDialog::OnDraft)
+ EVT_CHOICE(DkWxBmeps_PsLevel, DkWxBmepsOptionsDialog::OnPsLevel)
+ EVT_CHECKBOX(DkWxBmeps_Interpolation, DkWxBmepsOptionsDialog::OnInterpolation)
+END_EVENT_TABLE()
+
+
+
+
+#line 405 "DkWxBmepsOptionsDialog.wxc"
+DkWxBmepsOptionsDialog::DkWxBmepsOptionsDialog(
+ DkWxBmepsFrame *parent,
+ wxChar const *title,
+ wxChar const * const *messageTexts,
+ wxArrayString *asPaperSizes,
+ dk3_bm_eps_options_t *opt,
+ dk3_paper_size_t *pps,
+ size_t *sps,
+ DkWxAppHelper *applicationHelper,
+ int de,
+ int we
+) : wxDialog(
+ parent,
+ wxID_ANY,
+ title,
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxDEFAULT_DIALOG_STYLE
+)
+{
+ pHelper = applicationHelper;
+ dke = de; wxe = we;
+ arrayStringPaperSizeNames = asPaperSizes;
+ bmepsOptions = opt;
+ paperSizes = pps;
+ selectedPaperSize = sps;
+ bIsCorrecting = false;
+ wxColour cRed(0x7F, 0x00, 0x00);
+ wxString saOutputFormat[] = {
+ wxString(messageTexts[42]),
+ wxString(messageTexts[43]),
+ wxString(messageTexts[44]),
+ wxString(messageTexts[45])
+ };
+ wxString saOutputType[] = {
+ wxString(messageTexts[47]),
+ wxString(messageTexts[48]),
+ wxString(messageTexts[49])
+ };
+ wxString saFinishing[] = {
+ wxString(messageTexts[51]),
+ wxString(messageTexts[52]),
+ wxString(messageTexts[53])
+ };
+ wxString saResolution[] = {
+ wxString(messageTexts[60]),
+ wxString(messageTexts[61]),
+ wxString(messageTexts[62])
+ };
+ wxString saPsLevel[] = {
+ wxString(wxT("2")),
+ wxString(wxT("3"))
+ };
+ wxString saPredictor[] = {
+ wxString(messageTexts[76]),
+ wxString(messageTexts[77]),
+ wxString(messageTexts[78]),
+ wxString(messageTexts[79]),
+ wxString(messageTexts[80]),
+ wxString(messageTexts[81])
+ };
+ sTexts = messageTexts;
+ dkctGUILayoutOK = false;
+ sDialog = NULL;
+ verticalSizer = NULL;
+ sSetup = NULL;
+ sButtons = NULL;
+ sttGeneral = NULL;
+ cbMakeMode = NULL;
+ sttOutput = NULL;
+ sttOutputDetails = NULL;
+ sttOutputFormat = NULL;
+ cobOutputFormat = NULL;
+ cbDraft = NULL;
+ sttPsLevel = NULL;
+ cobPsLevel = NULL;
+ cbDsc = NULL;
+ sttOutputType = NULL;
+ cobOutputType = NULL;
+ sttPredictor = NULL;
+ cobPredictor = NULL;
+ sttFinishing = NULL;
+ cobFinishing = NULL;
+ cbDCT = NULL;
+ cbBpc = NULL;
+ sttOutputSize = NULL;
+ sttInterpolation = NULL;
+ sttResolution = NULL;
+ cobResolution = NULL;
+ txtResolution = NULL;
+ cbInterNormal = NULL;
+ sttPaperSize = NULL;
+ cobPaperSize = NULL;
+ cbInterJpeg = NULL;
+ sttTransparency = NULL;
+ sttBackground = NULL;
+ cvBackground = NULL;
+ cbForceBackground = NULL;
+ bOK = NULL;
+ bCancel = NULL;
+ sDialog = new wxBoxSizer(
+ wxHORIZONTAL
+ );
+ if(!(sDialog)) {
+ goto dkctGUILayoutFinished;
+ }
+ sDialog->Add(10, 10, 1);
+ verticalSizer = new wxBoxSizer(
+ wxVERTICAL
+ );
+ if(!(verticalSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ verticalSizer->Add(10, 10, 1);
+ sSetup = new wxGridBagSizer(
+ 5, 5
+ );
+ if(!(sSetup)) {
+ goto dkctGUILayoutFinished;
+ }
+ sttGeneral = new wxStaticText(
+ this,
+ wxID_ANY,
+ sTexts[37]
+ );
+ if(!(sttGeneral)) {
+ goto dkctGUILayoutFinished;
+ }
+ sSetup->Add(
+ sttGeneral,
+ wxGBPosition(0, 0),
+ wxGBSpan(1, 5),
+ wxALIGN_LEFT
+ );
+ cbMakeMode = new wxCheckBox(
+ this,
+ wxID_ANY,
+ sTexts[38]
+ );
+ if(!(cbMakeMode)) {
+ goto dkctGUILayoutFinished;
+ }
+ cbMakeMode->SetToolTip(sTexts[39]);
+ sSetup->Add(
+ cbMakeMode,
+ wxGBPosition(1, 0),
+ wxGBSpan(1, 3),
+ wxALIGN_LEFT
+ );
+ sSetup->Add(10, 1, wxGBPosition(1, 3), wxGBSpan(1, 1));
+ sSetup->Add(1, 10, wxGBPosition(2, 0), wxGBSpan(1, 5));
+ sttOutput = new wxStaticText(
+ this,
+ wxID_ANY,
+ sTexts[40]
+ );
+ if(!(sttOutput)) {
+ goto dkctGUILayoutFinished;
+ }
+ sSetup->Add(
+ sttOutput,
+ wxGBPosition(3, 0),
+ wxGBSpan(1, 5),
+ wxALIGN_LEFT
+ );
+ sSetup->Add(30, 1, wxGBPosition(3, 5), wxGBSpan(1, 1));
+ sttOutputDetails = new wxStaticText(
+ this,
+ wxID_ANY,
+ sTexts[73]
+ );
+ if(!(sttOutputDetails)) {
+ goto dkctGUILayoutFinished;
+ }
+ sSetup->Add(
+ sttOutputDetails,
+ wxGBPosition(3, 6),
+ wxGBSpan(1, 5),
+ wxALIGN_LEFT
+ );
+ sttOutputFormat = new wxStaticText(
+ this,
+ wxID_ANY,
+ sTexts[41],
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxALIGN_RIGHT
+ );
+ if(!(sttOutputFormat)) {
+ goto dkctGUILayoutFinished;
+ }
+ sSetup->Add(
+ sttOutputFormat,
+ wxGBPosition(4, 0),
+ wxGBSpan(1, 1),
+ wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL
+ );
+ cobOutputFormat = new wxChoice(
+ this,
+ DkWxBmeps_OuputFormat,
+ wxDefaultPosition,
+ wxDefaultSize,
+ 4,
+ saOutputFormat
+ );
+ if(!(cobOutputFormat)) {
+ goto dkctGUILayoutFinished;
+ }
+ cobOutputFormat->SetToolTip(sTexts[91]);
+ sSetup->Add(
+ cobOutputFormat,
+ wxGBPosition(4, 1),
+ wxGBSpan(1, 2),
+ wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxGROW
+ );
+ cbDraft = new wxCheckBox(
+ this,
+ DkWxBmeps_Draft,
+ sTexts[54]
+ );
+ if(!(cbDraft)) {
+ goto dkctGUILayoutFinished;
+ }
+ cbDraft->SetToolTip(sTexts[55]);
+ sSetup->Add(
+ cbDraft,
+ wxGBPosition(4, 4),
+ wxGBSpan(1, 1),
+ wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL
+ );
+ sttPsLevel = new wxStaticText(
+ this,
+ wxID_ANY,
+ sTexts[74]
+ );
+ if(!(sttPsLevel)) {
+ goto dkctGUILayoutFinished;
+ }
+ sSetup->Add(
+ sttPsLevel,
+ wxGBPosition(4, 6),
+ wxGBSpan(1, 1),
+ wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL
+ );
+ cobPsLevel = new wxChoice(
+ this,
+ DkWxBmeps_PsLevel,
+ wxDefaultPosition,
+ wxDefaultSize,
+ 2,
+ saPsLevel
+ );
+ if(!(cobPsLevel)) {
+ goto dkctGUILayoutFinished;
+ }
+ cobPsLevel->SetToolTip(sTexts[96]);
+ sSetup->Add(
+ cobPsLevel,
+ wxGBPosition(4, 7),
+ wxGBSpan(1, 1),
+ wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL
+ );
+ sSetup->Add(10, 1, wxGBPosition(4, 8), wxGBSpan(1, 1));
+ cbDsc = new wxCheckBox(
+ this,
+ wxID_ANY,
+ sTexts[82]
+ );
+ if(!(cbDsc)) {
+ goto dkctGUILayoutFinished;
+ }
+ cbDsc->SetToolTip(sTexts[83]);
+ sSetup->Add(
+ cbDsc,
+ wxGBPosition(4, 9),
+ wxGBSpan(1, 1),
+ wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL
+ );
+ sSetup->Add(10, 10, wxGBPosition(4, 10), wxGBSpan(1, 1));
+ sttOutputType = new wxStaticText(
+ this,
+ wxID_ANY,
+ sTexts[46]
+ );
+ if(!(sttOutputType)) {
+ goto dkctGUILayoutFinished;
+ }
+ sSetup->Add(
+ sttOutputType,
+ wxGBPosition(5, 0),
+ wxGBSpan(1, 1),
+ wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL
+ );
+ cobOutputType = new wxChoice(
+ this,
+ DkWxBmeps_OutputType,
+ wxDefaultPosition,
+ wxDefaultSize,
+ 3,
+ saOutputType
+ );
+ if(!(cobOutputType)) {
+ goto dkctGUILayoutFinished;
+ }
+ cobOutputType->SetToolTip(sTexts[92]);
+ sSetup->Add(
+ cobOutputType,
+ wxGBPosition(5, 1),
+ wxGBSpan(1, 2),
+ wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxGROW
+ );
+ sttPredictor = new wxStaticText(
+ this,
+ wxID_ANY,
+ sTexts[75],
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxALIGN_RIGHT
+ );
+ if(!(sttPredictor)) {
+ goto dkctGUILayoutFinished;
+ }
+ sSetup->Add(
+ sttPredictor,
+ wxGBPosition(5, 6),
+ wxGBSpan(1, 1),
+ wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL
+ );
+ cobPredictor = new wxChoice(
+ this,
+ wxID_ANY,
+ wxDefaultPosition,
+ wxDefaultSize,
+ 6,
+ saPredictor
+ );
+ if(!(cobPredictor)) {
+ goto dkctGUILayoutFinished;
+ }
+ cobPredictor->SetToolTip(sTexts[97]);
+ sSetup->Add(
+ cobPredictor,
+ wxGBPosition(5, 7),
+ wxGBSpan(1, 3),
+ wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL
+ );
+ sttFinishing = new wxStaticText(
+ this,
+ wxID_ANY,
+ sTexts[50]
+ );
+ if(!(sttFinishing)) {
+ goto dkctGUILayoutFinished;
+ }
+ sSetup->Add(
+ sttFinishing,
+ wxGBPosition(6, 0),
+ wxGBSpan(1, 1),
+ wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL
+ );
+ cobFinishing = new wxChoice(
+ this,
+ wxID_ANY,
+ wxDefaultPosition,
+ wxDefaultSize,
+ 3,
+ saFinishing
+ );
+ if(!(cobFinishing)) {
+ goto dkctGUILayoutFinished;
+ }
+ cobFinishing->SetToolTip(sTexts[93]);
+ sSetup->Add(
+ cobFinishing,
+ wxGBPosition(6, 1),
+ wxGBSpan(1, 2),
+ wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxGROW
+ );
+ cbDCT = new wxCheckBox(
+ this,
+ wxID_ANY,
+ sTexts[89]
+ );
+ if(!(cbDCT)) {
+ goto dkctGUILayoutFinished;
+ }
+ cbDCT->SetToolTip(sTexts[90]);
+ sSetup->Add(
+ cbDCT,
+ wxGBPosition(6, 6),
+ wxGBSpan(1, 4),
+ wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL
+ );
+ cbBpc = new wxCheckBox(
+ this,
+ wxID_ANY,
+ sTexts[120]
+ );
+ if(!(cbBpc)) {
+ goto dkctGUILayoutFinished;
+ }
+ cbBpc->SetToolTip(sTexts[121]);
+ sSetup->Add(
+ cbBpc,
+ wxGBPosition(7, 6),
+ wxGBSpan(1, 4),
+ wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL
+ );
+ sSetup->Add(1, 10, wxGBPosition(8, 0), wxGBSpan(1, 5));
+ sttOutputSize = new wxStaticText(
+ this,
+ wxID_ANY,
+ sTexts[58]
+ );
+ if(!(sttOutputSize)) {
+ goto dkctGUILayoutFinished;
+ }
+ sSetup->Add(
+ sttOutputSize,
+ wxGBPosition(9, 0),
+ wxGBSpan(1, 5),
+ wxALIGN_LEFT
+ );
+ sttInterpolation = new wxStaticText(
+ this,
+ wxID_ANY,
+ sTexts[64]
+ );
+ if(!(sttInterpolation)) {
+ goto dkctGUILayoutFinished;
+ }
+ sSetup->Add(
+ sttInterpolation,
+ wxGBPosition(9, 6),
+ wxGBSpan(1, 5),
+ wxALIGN_LEFT
+ );
+ sttResolution = new wxStaticText(
+ this,
+ wxID_ANY,
+ sTexts[59],
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxALIGN_RIGHT
+ );
+ if(!(sttResolution)) {
+ goto dkctGUILayoutFinished;
+ }
+ sSetup->Add(
+ sttResolution,
+ wxGBPosition(10, 0),
+ wxGBSpan(1, 1),
+ wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL
+ );
+ cobResolution = new wxChoice(
+ this,
+ DkWxBmeps_ResolutionType,
+ wxDefaultPosition,
+ wxDefaultSize,
+ 3,
+ saResolution
+ );
+ if(!(cobResolution)) {
+ goto dkctGUILayoutFinished;
+ }
+ cobResolution->SetToolTip(sTexts[94]);
+ sSetup->Add(
+ cobResolution,
+ wxGBPosition(10, 1),
+ wxGBSpan(1, 1),
+ wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL
+ );
+ txtResolution = new wxTextCtrl(
+ this,
+ wxID_ANY,
+ wxT(" ")
+ );
+ if(!(txtResolution)) {
+ goto dkctGUILayoutFinished;
+ }
+ txtResolution->SetToolTip(sTexts[98]);
+ sSetup->Add(
+ txtResolution,
+ wxGBPosition(10, 2),
+ wxGBSpan(1, 2),
+ wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL
+ );
+ cbInterNormal = new wxCheckBox(
+ this,
+ DkWxBmeps_Interpolation,
+ sTexts[65]
+ );
+ if(!(cbInterNormal)) {
+ goto dkctGUILayoutFinished;
+ }
+ cbInterNormal->SetToolTip(sTexts[66]);
+ sSetup->Add(
+ cbInterNormal,
+ wxGBPosition(10, 6),
+ wxGBSpan(1, 5),
+ wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL
+ );
+ sttPaperSize = new wxStaticText(
+ this,
+ wxID_ANY,
+ sTexts[63],
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxALIGN_RIGHT
+ );
+ if(!(sttPaperSize)) {
+ goto dkctGUILayoutFinished;
+ }
+ sSetup->Add(
+ sttPaperSize,
+ wxGBPosition(11, 0),
+ wxGBSpan(1, 1),
+ wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL
+ );
+ cobPaperSize = new wxChoice(
+ this,
+ wxID_ANY,
+ wxDefaultPosition,
+ wxDefaultSize,
+ *asPaperSizes
+ );
+ if(!(cobPaperSize)) {
+ goto dkctGUILayoutFinished;
+ }
+ cobPaperSize->SetToolTip(sTexts[95]);
+ sSetup->Add(
+ cobPaperSize,
+ wxGBPosition(11, 1),
+ wxGBSpan(1, 2),
+ wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxGROW
+ );
+ cbInterJpeg = new wxCheckBox(
+ this,
+ wxID_ANY,
+ sTexts[67]
+ );
+ if(!(cbInterJpeg)) {
+ goto dkctGUILayoutFinished;
+ }
+ cbInterJpeg->SetToolTip(sTexts[68]);
+ sSetup->Add(
+ cbInterJpeg,
+ wxGBPosition(11, 6),
+ wxGBSpan(1, 5),
+ wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL
+ );
+ sSetup->Add(1, 10, wxGBPosition(12, 0), wxGBSpan(1, 1));
+ sttTransparency = new wxStaticText(
+ this,
+ wxID_ANY,
+ sTexts[69]
+ );
+ if(!(sttTransparency)) {
+ goto dkctGUILayoutFinished;
+ }
+ sSetup->Add(
+ sttTransparency,
+ wxGBPosition(13, 6),
+ wxGBSpan(1, 5),
+ wxALIGN_LEFT
+ );
+ sttBackground = new wxStaticText(
+ this,
+ wxID_ANY,
+ sTexts[70],
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxALIGN_RIGHT
+ );
+ if(!(sttBackground)) {
+ goto dkctGUILayoutFinished;
+ }
+ sSetup->Add(
+ sttBackground,
+ wxGBPosition(14, 6),
+ wxGBSpan(1, 2),
+ wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL
+ );
+ cvBackground = new DkWxColorView(
+ this,wxID_ANY,pHelper,255,255,255
+ );
+ if(!(cvBackground)) {
+ goto dkctGUILayoutFinished;
+ }
+ sSetup->Add(
+ cvBackground,
+ wxGBPosition(14, 8),
+ wxGBSpan(1, 1),
+ wxALIGN_CENTER_VERTICAL
+ );
+ cbForceBackground = new wxCheckBox(
+ this,
+ wxID_ANY,
+ sTexts[71]
+ );
+ if(!(cbForceBackground)) {
+ goto dkctGUILayoutFinished;
+ }
+ cbForceBackground->SetToolTip(sTexts[72]);
+ sSetup->Add(
+ cbForceBackground,
+ wxGBPosition(15, 6),
+ wxGBSpan(1, 5),
+ wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL
+ );
+ verticalSizer->Add(
+ sSetup
+ );
+ verticalSizer->Add(10, 10, 1);
+ sButtons = new wxStdDialogButtonSizer(
+ );
+ if(!(sButtons)) {
+ goto dkctGUILayoutFinished;
+ }
+ bOK = new wxButton(
+ this,
+ wxID_OK,
+ sTexts[84]
+ );
+ if(!(bOK)) {
+ goto dkctGUILayoutFinished;
+ }
+ bOK->SetToolTip(sTexts[85]);
+ sButtons->AddButton(
+ bOK
+ );
+ bCancel = new wxButton(
+ this,
+ wxID_CANCEL,
+ sTexts[86]
+ );
+ if(!(bCancel)) {
+ goto dkctGUILayoutFinished;
+ }
+ bCancel->SetToolTip(sTexts[87]);
+ sButtons->AddButton(
+ bCancel
+ );
+ sButtons->Realize();
+ verticalSizer->Add(
+ sButtons,
+ 0,
+ wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL
+ );
+ verticalSizer->Add(10, 10, 1);
+ sDialog->Add(
+ verticalSizer,
+ 0,
+ wxGROW
+ );
+ sDialog->Add(10, 10, 1);
+ SetSizer(sDialog);
+ dkctGUILayoutOK = true;
+ dkctGUILayoutFinished:
+ if(dkctGUILayoutOK) {
+ sDialog->Fit(this);
+ sDialog->SetSizeHints(this);
+ }
+
+#line 468 "DkWxBmepsOptionsDialog.wxc"
+ cvBackground->SetToolTip(messageTexts[88]);
+ sttGeneral->SetForegroundColour(cRed);
+ sttOutput->SetForegroundColour(cRed);
+ sttOutputDetails->SetForegroundColour(cRed);
+ sttOutputSize->SetForegroundColour(cRed);
+ sttInterpolation->SetForegroundColour(cRed);
+ sttTransparency->SetForegroundColour(cRed);
+ txtResolution->ChangeValue(sTexts[3]);
+}
+
+
+#line 479 "DkWxBmepsOptionsDialog.wxc"
+
+
+
+void
+DkWxBmepsOptionsDialog::OnOK(
+ wxCommandEvent & event
+)
+{
+
+
+#line 488 "DkWxBmepsOptionsDialog.wxc"
+ dataOut();
+ if(IsModal()) {
+ EndModal(wxID_OK);
+ } else {
+ SetReturnCode(wxID_OK);
+ Show(false);
+ }
+
+
+#line 496 "DkWxBmepsOptionsDialog.wxc"
+}
+
+
+
+void
+DkWxBmepsOptionsDialog::OnCancel(
+ wxCommandEvent & event
+)
+{
+ if(IsModal()) {
+ EndModal(wxID_CANCEL);
+ } else {
+ SetReturnCode(wxID_CANCEL);
+ Show(false);
+ }
+}
+
+
+
+void
+DkWxBmepsOptionsDialog::dataOut()
+{
+ int i;
+
+
+#line 520 "DkWxBmepsOptionsDialog.wxc"
+ /* Make mode cbMakeMode */
+ bmepsOptions->make = ((cbMakeMode->GetValue()) ? 1 : 0);
+ /* Output format cobOutputFormat */
+ i = cobOutputFormat->GetSelection();
+ if((i >= 0) && (i <= DK3_BMEPS_DRIVER_BB)) {
+ bmepsOptions->dr = i;
+ } else {
+ bmepsOptions->dr = 0;
+ }
+ /* Output type cobOutputType */
+ i = cobOutputType->GetSelection();
+ if((i >= 0) && (i <= DK3_BMEPS_MODE_DOCUMENT)) {
+ bmepsOptions->mode = i;
+
+#line 533 "DkWxBmepsOptionsDialog.wxc"
+ } else {
+ bmepsOptions->mode = 0;
+ }
+ /* Finishing cobFinishing */
+ i = cobFinishing->GetSelection();
+
+#line 538 "DkWxBmepsOptionsDialog.wxc"
+ switch(i) {
+ case 1: {
+ bmepsOptions->duplex = 1; bmepsOptions->tumble = 0;
+ } break;
+ case 2: {
+ bmepsOptions->duplex = 1; bmepsOptions->tumble = 1;
+ } break;
+ default: {
+ bmepsOptions->duplex = 0; bmepsOptions->tumble = 0;
+ } break;
+ }
+ /* Draft cbDraft */
+ bmepsOptions->draft = ((cbDraft->GetValue()) ? 1 : 0);
+ /* Color cbColor */
+ /* bmepsOptions->color = ((cbColor->GetValue()) ? 1 : 0); */
+ /* Resolution choice cobResolution */
+#if VERSION_BEFORE_20140902
+ bmepsOptions->szmode = cobResolution->GetSelection();
+#else
+ switch (bmepsOptions->mode) {
+ case DK3_BMEPS_MODE_DOCUMENT: {
+ bmepsOptions->szmode = DK3_BMEPS_SIZE_PAPER;
+
+
+#line 561 "DkWxBmepsOptionsDialog.wxc"
+ } break;
+ default: {
+ bmepsOptions->szmode = cobResolution->GetSelection();
+
+
+#line 565 "DkWxBmepsOptionsDialog.wxc"
+ } break;
+ }
+#endif
+ /* Resolution value txtResolution */
+ if(bmepsOptions->szmode == DK3_BMEPS_SIZE_SPECIFIED) {
+ dkChar bu[64];
+ dkChar *ptr;
+ double v = 0.0;
+ wxString resText = txtResolution->GetValue();
+ wxChar const *txt = resText.c_str();
+
+
+#line 576 "DkWxBmepsOptionsDialog.wxc"
+ if(txt) {
+
+#line 577 "DkWxBmepsOptionsDialog.wxc"
+ if(dk3wxs_to_dkstr(bu,DK3_SIZEOF(bu,dkChar),dke,txt,wxe)) {
+ ptr = bu;
+
+#line 579 "DkWxBmepsOptionsDialog.wxc"
+ while(*ptr) {
+ if(*ptr == dkT(',')) { *ptr = dkT('.'); }
+ ptr++;
+ }
+
+#line 583 "DkWxBmepsOptionsDialog.wxc"
+ if(dk3sf_scan_double_app(bu,&v,NULL)) {
+
+#line 584 "DkWxBmepsOptionsDialog.wxc"
+ bmepsOptions->resolution = v;
+
+#line 585 "DkWxBmepsOptionsDialog.wxc"
+ } else {
+ bmepsOptions->resolution = 0.0;
+ }
+ } else {
+ bmepsOptions->resolution = 0.0;
+ }
+ } else {
+ bmepsOptions->resolution = 0.0;
+ }
+ } else {
+
+#line 595 "DkWxBmepsOptionsDialog.wxc"
+ bmepsOptions->resolution = 0.0;
+ }
+ /* Paper size cobPaperSize */
+ if(selectedPaperSize) {
+ *selectedPaperSize = (size_t)(cobPaperSize->GetSelection());
+
+
+#line 601 "DkWxBmepsOptionsDialog.wxc"
+ }
+ /* PS level cobPsLevel */
+ i = cobPsLevel->GetSelection();
+ bmepsOptions->psl = ((i == 1) ? 3 : 2);
+ /* DSC cbDsc */
+ bmepsOptions->dsc = ((cbDsc->GetValue()) ? 1 : 0);
+ /* Predictor cobPredictor */
+ bmepsOptions->pred = cobPredictor->GetSelection();
+ /* DCT cbDCT */
+ bmepsOptions->dct = ((cbDCT->GetValue()) ? 1 : 0);
+ /* Bits per component cbBpc */
+ bmepsOptions->rbpc = ((cbBpc->GetValue()) ? 1 : 0);
+ /* Image interpolation cbInterNormal */
+ bmepsOptions->ip = ((cbInterNormal->GetValue()) ? 1 : 0);
+ /* Interpolation for JPEG cbInterJpeg */
+ bmepsOptions->jip = ((cbInterJpeg->GetValue()) ? 1 : 0);
+ /* Background color cvBackground */
+ bmepsOptions->bgr = cvBackground->getRed();
+ bmepsOptions->bgg = cvBackground->getGreen();
+ bmepsOptions->bgb = cvBackground->getBlue();
+ /* Force background color cbForceBackground*/
+ bmepsOptions->fbg = ((cbForceBackground->GetValue()) ? 1 : 0);
+ (void)dk3bmeo_check(bmepsOptions, 0, bmepsOptions->app, NULL);
+
+
+#line 625 "DkWxBmepsOptionsDialog.wxc"
+}
+
+
+
+void
+DkWxBmepsOptionsDialog::dataIn()
+{
+ /* Make mode cbMakeMode */
+ cbMakeMode->SetValue((bmepsOptions->make) ? true : false);
+ /* Output format cobOutputFormat */
+ setChoice(cobOutputFormat, bmepsOptions->dr);
+ /* Output type cobOutputType */
+ setChoice(cobOutputType, bmepsOptions->mode);
+ /* Finishing cobFinishing */
+ if(bmepsOptions->duplex) {
+ if(bmepsOptions->tumble) {
+ cobFinishing->SetSelection(2);
+ } else {
+ cobFinishing->SetSelection(1);
+ }
+ } else {
+ cobFinishing->SetSelection(0);
+ }
+ /* Draft cbDraft */
+ cbDraft->SetValue((bmepsOptions->draft) ? true : false);
+ /* Color cbColor */
+ /* cbColor->SetValue((bmepsOptions->color) ? true : false); */
+ /* Resolution choice cobResolution */
+
+
+#line 654 "DkWxBmepsOptionsDialog.wxc"
+ setChoice(cobResolution, bmepsOptions->szmode);
+ /* Resolution value txtResolution */
+ if(bmepsOptions->szmode == 2) {
+
+#line 657 "DkWxBmepsOptionsDialog.wxc"
+ txtResolution->ChangeValue(
+ wxString::Format(wxT("%lg"), bmepsOptions->resolution)
+ );
+ } else {
+ txtResolution->ChangeValue(sTexts[3]);
+ }
+ /* Paper size cobPaperSize */
+ if(selectedPaperSize) {
+ setChoice(cobPaperSize, (int)(*selectedPaperSize));
+ } else {
+ cobPaperSize->SetSelection(0);
+ }
+ /* PS level cobPsLevel */
+ if(bmepsOptions->psl == 3) {
+ cobPsLevel->SetSelection(1);
+ } else {
+ cobPsLevel->SetSelection(0);
+ }
+ /* DSC cbDsc */
+ cbDsc->SetValue((bmepsOptions->dsc) ? true : false);
+ /* Predictor cobPredictor */
+ setChoice(cobPredictor, bmepsOptions->pred);
+ /* DCT cbDCT */
+ cbDCT->SetValue((bmepsOptions->dct) ? true : false);
+ /* Reduce bits per component cbBpc */
+ cbBpc->SetValue((bmepsOptions->rbpc) ? true : false);
+ /* Image interpolation cbInterNormal */
+ cbInterNormal->SetValue((bmepsOptions->ip) ? true : false);
+ /* Interpolation for JPEG cbInterJpeg */
+ cbInterJpeg->SetValue((bmepsOptions->jip) ? true : false);
+ /* Background color cvBackground */
+ cvBackground->setRGB(
+ intToRange(0,255,bmepsOptions->bgr),
+ intToRange(0,255,bmepsOptions->bgg),
+ intToRange(0,255,bmepsOptions->bgb)
+ );
+ /* Force background color cbForceBackground*/
+ cbForceBackground->SetValue((bmepsOptions->fbg) ? true : false);
+ correctGUI();
+}
+
+
+
+int
+DkWxBmepsOptionsDialog::intToRange(int min, int max, int val)
+{
+ int back = val;
+ if(back < min) back = min;
+ if(back > max) back = max;
+ return back;
+}
+
+
+
+void
+DkWxBmepsOptionsDialog::setChoice(wxChoice *ch, int val)
+{
+ if(ch) {
+ unsigned max = ch->GetCount();
+ if(val == wxNOT_FOUND) {
+ ch->SetSelection(val);
+ } else {
+ ch->SetSelection(intToRange(0, ((int)max - 1), val));
+ }
+ }
+}
+
+
+
+void
+DkWxBmepsOptionsDialog::OnOutputFormat(wxCommandEvent & event)
+{
+ correctGUI();
+}
+
+
+
+void
+DkWxBmepsOptionsDialog::OnOutputType(wxCommandEvent & event)
+{
+ correctGUI();
+}
+
+
+
+void
+DkWxBmepsOptionsDialog::OnResolution(wxCommandEvent & event)
+{
+ correctGUI();
+}
+
+
+
+void
+DkWxBmepsOptionsDialog::OnDraft(wxCommandEvent & event)
+{
+ correctGUI();
+}
+
+
+
+void
+DkWxBmepsOptionsDialog::OnPsLevel(wxCommandEvent & event)
+{
+ correctGUI();
+}
+
+
+
+void
+DkWxBmepsOptionsDialog::OnInterpolation(wxCommandEvent & event)
+{
+ correctGUI();
+}
+
+
+
+void
+DkWxBmepsOptionsDialog::correctGUI()
+{
+ bool doEnable;
+
+
+#line 779 "DkWxBmepsOptionsDialog.wxc"
+ if(!bIsCorrecting) {
+ bIsCorrecting = true;
+ /* Output type */
+ if(cobOutputFormat->GetSelection() == 3) {
+ cobOutputType->SetSelection(1);
+ cobOutputType->Enable(false);
+ } else {
+ cobOutputType->Enable(true);
+ }
+ /* Finishing */
+ if(cobOutputType->GetSelection() == 2) {
+ cobFinishing->Enable(true);
+ } else {
+ cobFinishing->Enable(false);
+ }
+ /* Resolution type */
+ switch(cobOutputType->GetSelection()) {
+ case 0: {
+ cobResolution->Enable(true);
+ } break;
+ case 1: {
+ cobResolution->SetSelection(0);
+ cobResolution->Enable(false);
+ } break;
+ case 2: {
+ cobResolution->Enable(false);
+ } break;
+ }
+ /* Resolution text */
+ if(cobResolution->GetSelection() == 2) {
+ txtResolution->Enable(true);
+ } else {
+ txtResolution->Enable(false);
+ }
+ /* Paper size */
+ if(cobOutputType->GetSelection() == 2) {
+ cobPaperSize->Enable(true);
+ } else {
+ cobPaperSize->Enable(false);
+ }
+ /* Draft mode */
+ if(cobOutputFormat->GetSelection() == 3) {
+ cbDraft->Enable(false);
+ } else {
+ if(cobOutputType->GetSelection() == 2) {
+ cbDraft->Enable(false);
+ } else {
+ cbDraft->Enable(true);
+ }
+ }
+ /* Color */
+ if(cobOutputFormat->GetSelection() == 3) {
+ /* cbColor->Enable(false); */
+ } else {
+ if(cbDraft->GetValue()) {
+ /* cbColor->Enable(false); */
+ } else {
+ /* cbColor->Enable(true); */
+ }
+ }
+ /* PS level and DSC */
+ switch(cobOutputFormat->GetSelection()) {
+ case 0: case 1: {
+ cobPsLevel->Enable(true);
+ cbDsc->Enable(true);
+ } break;
+ default: {
+ cobPsLevel->Enable(false);
+ cbDsc->Enable(false);
+ } break;
+ }
+ /* Predictor */
+ doEnable = false;
+ switch(cobOutputFormat->GetSelection()) {
+ case 0: case 1: {
+ if(cobPsLevel->GetSelection() == 1) {
+ doEnable = true;
+ }
+ } break;
+ case 2: {
+ doEnable = true;
+ } break;
+ }
+ if(cbDraft->GetValue()) { doEnable = false; }
+ cobPredictor->Enable(doEnable);
+ /* Re-use JPEG DCT data */
+ if(cobOutputFormat->GetSelection() == 3) {
+ cbDCT->Enable(false);
+ } else {
+ if(cbDraft->GetValue()) {
+ cbDCT->Enable(false);
+ } else {
+ cbDCT->Enable(true);
+ }
+ }
+ /* Normal interpolation */
+ if(cobOutputFormat->GetSelection() == 3) {
+ cbInterNormal->Enable(false);
+ } else {
+ if(cbDraft->GetValue()) {
+ cbInterNormal->Enable(false);
+ } else {
+ cbInterNormal->Enable(true);
+ }
+ }
+ /* Interpolation for JPEG */
+ if(cobOutputFormat->GetSelection() == 3) {
+ cbInterJpeg->Enable(false);
+ } else {
+ if(cbInterNormal->GetValue()) {
+ if(cbDraft->GetValue()) {
+ cbInterJpeg->Enable(false);
+ } else {
+ cbInterJpeg->Enable(true);
+ }
+ } else {
+ cbInterJpeg->Enable(false);
+ }
+ }
+ /* Force background */
+ if(cobOutputFormat->GetSelection() == 3) {
+ cbForceBackground->Enable(false);
+ } else {
+ if(cbDraft->GetValue()) {
+ cbForceBackground->Enable(false);
+ } else {
+ cbForceBackground->Enable(true);
+ }
+ }
+ bIsCorrecting = false;
+ Refresh();
+ Update();
+ }
+
+#line 912 "DkWxBmepsOptionsDialog.wxc"
+}
+
diff --git a/support/dktools/DkWxBmepsOptionsDialog.h b/support/dktools/DkWxBmepsOptionsDialog.h
new file mode 100644
index 0000000000..88b50f3d47
--- /dev/null
+++ b/support/dktools/DkWxBmepsOptionsDialog.h
@@ -0,0 +1,402 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxBmepsOptionsDialog.wxc
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxBmepsOptionsDialog.h Header file for the DkWxBmepsOptionsDialog module.
+*/
+
+#ifndef DKWXBMEPSOPTIONSDIALOG_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DKWXBMEPSOPTIONSDIALOG_H_INCLUDED 1
+
+
+#line 219 "DkWxBmepsOptionsDialog.wxc"
+
+
+#line 221 "DkWxBmepsOptionsDialog.wxc"
+
+
+
+/** Options dialog for the wxbmpp program.
+*/
+class DkWxBmepsOptionsDialog : public wxDialog
+{
+
+ private:
+
+ /** Flag: Already in correction, do not enter correction again.
+ */
+ bool bIsCorrecting;
+
+ /** Event table.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ /** Application helper object.
+ */
+ DkWxAppHelper *pHelper;
+
+ /** Localized texts.
+ */
+ wxChar const * const *sTexts;
+
+ /** Paper size names.
+ */
+ wxArrayString *arrayStringPaperSizeNames;
+
+ /** Conversion options.
+ */
+ dk3_bm_eps_options_t *bmepsOptions;
+
+ /** Paper sizes in PS points.
+ */
+ dk3_paper_size_t *paperSizes;
+
+ /** Pointer to variable for selected paper size.
+ */
+ size_t *selectedPaperSize;
+
+ /** Encoding of dkChar.
+ */
+ int dke;
+
+ /** Encoding of wxChar.
+ */
+ int wxe;
+
+ /** Handler for OK button.
+ @param event Event to process.
+ */
+ void
+ OnOK(wxCommandEvent& WXUNUSED(event));
+
+ /** Handler for Cancel button.
+ @param event Event to process.
+ */
+ void
+ OnCancel(wxCommandEvent& WXUNUSED(event));
+
+ /** Handler for output format change.
+ @param event Event to process.
+ */
+ void
+ OnOutputFormat(wxCommandEvent & event);
+
+ /** Handler for output type change.
+ @param event Event to process.
+ */
+ void
+ OnOutputType(wxCommandEvent & event);
+
+ /** Handler for resolution change.
+ @param event Event to process.
+ */
+ void
+ OnResolution(wxCommandEvent & event);
+
+ /** Handler changed draft setting.
+ @param event Event to process.
+ */
+ void
+ OnDraft(wxCommandEvent & event);
+
+ /** Handler for changed PS level.
+ @param event Event to process.
+ */
+ void
+ OnPsLevel(wxCommandEvent & event);
+
+ /** Handler changed interpolation setting.
+ @param event Event to process.
+ */
+ void
+ OnInterpolation(wxCommandEvent & event);
+
+ /** Correct GUI (enable/disable elements based on last decision).
+ */
+ void
+ correctGUI();
+
+
+ /** Flag: GUI ok.
+ */
+ bool dkctGUILayoutOK;
+
+ /** GUI element sDialog.
+ */
+#line 12 "DkWxBmepsOptionsDialog.wxc"
+ wxBoxSizer *sDialog;
+
+ /** GUI element verticalSizer.
+ */
+#line 18 "DkWxBmepsOptionsDialog.wxc"
+ wxBoxSizer *verticalSizer;
+
+ /** GUI element sSetup.
+ */
+#line 27 "DkWxBmepsOptionsDialog.wxc"
+ wxGridBagSizer *sSetup;
+
+ /** GUI element sButtons.
+ */
+#line 201 "DkWxBmepsOptionsDialog.wxc"
+ wxStdDialogButtonSizer *sButtons;
+
+ /** GUI element sttGeneral.
+ */
+#line 70 "DkWxBmepsOptionsDialog.wxc"
+ wxStaticText *sttGeneral;
+
+ /** GUI element cbMakeMode.
+ */
+#line 73 "DkWxBmepsOptionsDialog.wxc"
+ wxCheckBox *cbMakeMode;
+
+ /** GUI element sttOutput.
+ */
+#line 78 "DkWxBmepsOptionsDialog.wxc"
+ wxStaticText *sttOutput;
+
+ /** GUI element sttOutputDetails.
+ */
+#line 151 "DkWxBmepsOptionsDialog.wxc"
+ wxStaticText *sttOutputDetails;
+
+ /** GUI element sttOutputFormat.
+ */
+#line 81 "DkWxBmepsOptionsDialog.wxc"
+ wxStaticText *sttOutputFormat;
+
+ /** GUI element cobOutputFormat.
+ */
+#line 85 "DkWxBmepsOptionsDialog.wxc"
+ wxChoice *cobOutputFormat;
+
+ /** GUI element cbDraft.
+ */
+#line 91 "DkWxBmepsOptionsDialog.wxc"
+ wxCheckBox *cbDraft;
+
+ /** GUI element sttPsLevel.
+ */
+#line 154 "DkWxBmepsOptionsDialog.wxc"
+ wxStaticText *sttPsLevel;
+
+ /** GUI element cobPsLevel.
+ */
+#line 157 "DkWxBmepsOptionsDialog.wxc"
+ wxChoice *cobPsLevel;
+
+ /** GUI element cbDsc.
+ */
+#line 162 "DkWxBmepsOptionsDialog.wxc"
+ wxCheckBox *cbDsc;
+
+ /** GUI element sttOutputType.
+ */
+#line 96 "DkWxBmepsOptionsDialog.wxc"
+ wxStaticText *sttOutputType;
+
+ /** GUI element cobOutputType.
+ */
+#line 99 "DkWxBmepsOptionsDialog.wxc"
+ wxChoice *cobOutputType;
+
+ /** GUI element sttPredictor.
+ */
+#line 166 "DkWxBmepsOptionsDialog.wxc"
+ wxStaticText *sttPredictor;
+
+ /** GUI element cobPredictor.
+ */
+#line 170 "DkWxBmepsOptionsDialog.wxc"
+ wxChoice *cobPredictor;
+
+ /** GUI element sttFinishing.
+ */
+#line 109 "DkWxBmepsOptionsDialog.wxc"
+ wxStaticText *sttFinishing;
+
+ /** GUI element cobFinishing.
+ */
+#line 112 "DkWxBmepsOptionsDialog.wxc"
+ wxChoice *cobFinishing;
+
+ /** GUI element cbDCT.
+ */
+#line 117 "DkWxBmepsOptionsDialog.wxc"
+ wxCheckBox *cbDCT;
+
+ /** GUI element cbBpc.
+ */
+#line 121 "DkWxBmepsOptionsDialog.wxc"
+ wxCheckBox *cbBpc;
+
+ /** GUI element sttOutputSize.
+ */
+#line 125 "DkWxBmepsOptionsDialog.wxc"
+ wxStaticText *sttOutputSize;
+
+ /** GUI element sttInterpolation.
+ */
+#line 174 "DkWxBmepsOptionsDialog.wxc"
+ wxStaticText *sttInterpolation;
+
+ /** GUI element sttResolution.
+ */
+#line 128 "DkWxBmepsOptionsDialog.wxc"
+ wxStaticText *sttResolution;
+
+ /** GUI element cobResolution.
+ */
+#line 132 "DkWxBmepsOptionsDialog.wxc"
+ wxChoice *cobResolution;
+
+ /** GUI element txtResolution.
+ */
+#line 137 "DkWxBmepsOptionsDialog.wxc"
+ wxTextCtrl *txtResolution;
+
+ /** GUI element cbInterNormal.
+ */
+#line 177 "DkWxBmepsOptionsDialog.wxc"
+ wxCheckBox *cbInterNormal;
+
+ /** GUI element sttPaperSize.
+ */
+#line 142 "DkWxBmepsOptionsDialog.wxc"
+ wxStaticText *sttPaperSize;
+
+ /** GUI element cobPaperSize.
+ */
+#line 146 "DkWxBmepsOptionsDialog.wxc"
+ wxChoice *cobPaperSize;
+
+ /** GUI element cbInterJpeg.
+ */
+#line 182 "DkWxBmepsOptionsDialog.wxc"
+ wxCheckBox *cbInterJpeg;
+
+ /** GUI element sttTransparency.
+ */
+#line 186 "DkWxBmepsOptionsDialog.wxc"
+ wxStaticText *sttTransparency;
+
+ /** GUI element sttBackground.
+ */
+#line 189 "DkWxBmepsOptionsDialog.wxc"
+ wxStaticText *sttBackground;
+
+ /** GUI element cvBackground.
+ */
+#line 193 "DkWxBmepsOptionsDialog.wxc"
+ DkWxColorView *cvBackground;
+
+ /** GUI element cbForceBackground.
+ */
+#line 197 "DkWxBmepsOptionsDialog.wxc"
+ wxCheckBox *cbForceBackground;
+
+ /** GUI element bOK.
+ */
+#line 206 "DkWxBmepsOptionsDialog.wxc"
+ wxButton *bOK;
+
+ /** GUI element bCancel.
+ */
+#line 211 "DkWxBmepsOptionsDialog.wxc"
+ wxButton *bCancel;
+
+
+#line 328 "DkWxBmepsOptionsDialog.wxc"
+ public:
+
+ /** Constructor.
+ @param parent Parent window.
+ @param title Dialog box title.
+ @param messageTexts Localized message texts.
+ @param asPaperSizes Known paper size names.
+ @param opt Conversion options.
+ @param pps Known paper sizes array.
+ @param sps Size of @arg pps (number of elements in array).
+ @param applicationHelper Application helper object.
+ @param de Character encoding used for dkChar strings.
+ @param we Character encoding used for wxChar strings.
+ */
+ DkWxBmepsOptionsDialog(
+ DkWxBmepsFrame *parent,
+ wxChar const *title,
+ wxChar const * const *messageTexts,
+ wxArrayString *asPaperSizes,
+ dk3_bm_eps_options_t *opt,
+ dk3_paper_size_t *pps,
+ size_t *sps,
+ DkWxAppHelper *applicationHelper,
+ int de,
+ int we
+ );
+
+ /** Transfer data from GUI controls to configuration structure.
+ */
+ void dataOut();
+
+ /** Transfer data from configuration structure to GUI controls.
+ */
+ void dataIn();
+
+ /** Restrict a number to a range.
+ @param min Range minimum.
+ @param max Range maximum.
+ @param val Value to use.
+ @return The value fitted into the range.
+ */
+ int
+ intToRange(int min, int max, int val);
+
+ /** Set a wxChoice selection.
+ @param ch Choice to modify.
+ @param val New selection index.
+ */
+ void
+ setChoice(wxChoice *ch, int val);
+};
+
+
+#line 381 "DkWxBmepsOptionsDialog.wxc"
+
+
+
+#endif
diff --git a/support/dktools/DkWxBmepsOptionsDialog.wxc b/support/dktools/DkWxBmepsOptionsDialog.wxc
new file mode 100644
index 0000000000..a4c58287da
--- /dev/null
+++ b/support/dktools/DkWxBmepsOptionsDialog.wxc
@@ -0,0 +1,913 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+%% wx-gui
+type = dialog
+contents = sDialog
+
+[wxBoxSizer sDialog]
+direction = horizontal
+contents = $stretch(10)
+contents = verticalSizer
+contents = $stretch(10)
+
+[wxBoxSizer verticalSizer]
+direction = vertical
+grow = yes
+contents = $stretch(10)
+contents = sSetup
+contents = $stretch(10)
+contents = sButtons centered
+contents = $stretch(10)
+
+[wxGridBagSizer sSetup]
+grid = 5 5
+contents = sttGeneral 0 0 1 5 left
+contents = cbMakeMode +1 0 1 3 left
+contents = $space(10,1) . 3 1 1 left
+contents = $space(1,10) +1 0 1 5 left
+contents = sttOutput +1 0 1 5 left
+contents = $space(30,1) . 5 1 1 left
+contents = sttOutputDetails . 6 1 5 left
+contents = sttOutputFormat +1 0 1 1 right centered-y
+contents = cobOutputFormat . 1 1 2 left centered-y
+contents = cbDraft . 4 1 1 left centered-y
+contents = sttPsLevel . 6 1 1 right centered-y
+contents = cobPsLevel . 7 1 1 left centered-y
+contents = $space(10,1) . 8 1 1 left
+contents = cbDsc . 9 1 1 left centered-y
+contents = $stretch(10) . 10 1 1 left
+contents = sttOutputType +1 0 1 1 right centered-y
+contents = cobOutputType . 1 1 2 left centered-y
+# contents = cbColor . 4 1 1 left centered-y
+contents = sttPredictor . 6 1 1 right centered-y
+contents = cobPredictor . 7 1 3 left centered-y
+contents = sttFinishing +1 0 1 1 right centered-y
+contents = cobFinishing . 1 1 2 left centered-y
+contents = cbDCT . 6 1 4 left centered-y
+contents = cbBpc +1 6 1 4 left centered-y
+contents = $space(1,10) +1 0 1 5 left
+contents = sttOutputSize +1 0 1 5 left
+contents = sttInterpolation . 6 1 5 left
+contents = sttResolution +1 0 1 1 right centered-y
+contents = cobResolution . 1 1 1 left centered-y
+contents = txtResolution . 2 1 2 left centered-y
+contents = cbInterNormal . 6 1 5 left centered-y
+contents = sttPaperSize +1 0 1 1 right centered-y
+contents = cobPaperSize . 1 1 2 left centered-y
+contents = cbInterJpeg . 6 1 5 left centered-y
+contents = $space(1,10) +1 0 1 1
+contents = sttTransparency +1 6 1 5 left
+contents = sttBackground +1 6 1 2 right centered-y
+contents = cvBackground . 8 1 1 centered-y
+contents = cbForceBackground +1 6 1 5 left centered-y
+
+
+[wxStaticText sttGeneral]
+text = sTexts[37]
+
+[wxCheckBox cbMakeMode]
+# id = ...
+text = sTexts[38]
+tip = sTexts[39]
+
+[wxStaticText sttOutput]
+text = sTexts[40]
+
+[wxStaticText sttOutputFormat]
+text = sTexts[41]
+text style = right
+
+[wxChoice cobOutputFormat]
+choices = 4 saOutputFormat
+tip = sTexts[91]
+grow = yes
+id = DkWxBmeps_OuputFormat
+
+[wxCheckBox cbDraft]
+text = sTexts[54]
+tip = sTexts[55]
+id = DkWxBmeps_Draft
+
+[wxStaticText sttOutputType]
+text = sTexts[46]
+
+[wxChoice cobOutputType]
+choices = 3 saOutputType
+tip = sTexts[92]
+grow = yes
+id = DkWxBmeps_OutputType
+
+# [wxCheckBox cbColor]
+# text = sTexts[56]
+# tip = sTexts[57]
+
+[wxStaticText sttFinishing]
+text = sTexts[50]
+
+[wxChoice cobFinishing]
+choices = 3 saFinishing
+tip = sTexts[93]
+grow = yes
+
+[wxCheckBox cbDCT]
+text = sTexts[89]
+tip = sTexts[90]
+
+[wxCheckBox cbBpc]
+text = sTexts[120]
+tip = sTexts[121]
+
+[wxStaticText sttOutputSize]
+text = sTexts[58]
+
+[wxStaticText sttResolution]
+text = sTexts[59]
+text style = right
+
+[wxChoice cobResolution]
+choices = 3 saResolution
+tip = sTexts[94]
+id = DkWxBmeps_ResolutionType
+
+[wxTextCtrl txtResolution]
+text = wxT(" ")
+tip = sTexts[98]
+
+
+[wxStaticText sttPaperSize]
+text = sTexts[63]
+text style = right
+
+[wxChoice cobPaperSize]
+choices = *asPaperSizes
+tip = sTexts[95]
+grow = yes
+
+[wxStaticText sttOutputDetails]
+text = sTexts[73]
+
+[wxStaticText sttPsLevel]
+text = sTexts[74]
+
+[wxChoice cobPsLevel]
+choices = 2 saPsLevel
+tip = sTexts[96]
+id = DkWxBmeps_PsLevel
+
+[wxCheckBox cbDsc]
+text = sTexts[82]
+tip = sTexts[83]
+
+[wxStaticText sttPredictor]
+text = sTexts[75]
+text style = right
+
+[wxChoice cobPredictor]
+choices = 6 saPredictor
+tip = sTexts[97]
+
+[wxStaticText sttInterpolation]
+text = sTexts[64]
+
+[wxCheckBox cbInterNormal]
+text = sTexts[65]
+tip = sTexts[66]
+id = DkWxBmeps_Interpolation
+
+[wxCheckBox cbInterJpeg]
+text = sTexts[67]
+tip = sTexts[68]
+
+[wxStaticText sttTransparency]
+text = sTexts[69]
+
+[wxStaticText sttBackground]
+text = sTexts[70]
+text style = right
+
+[DkWxColorView cvBackground]
+constructor = pHelper,255,255,255
+id = wxID_ANY
+
+[wxCheckBox cbForceBackground]
+text = sTexts[71]
+tip = sTexts[72]
+
+[wxStdDialogButtonSizer sButtons]
+contents = bOK
+contents = bCancel
+
+
+[wxButton bOK]
+id = wxID_OK
+text = sTexts[84]
+tip = sTexts[85]
+
+[wxButton bCancel]
+id = wxID_CANCEL
+text = sTexts[86]
+tip = sTexts[87]
+
+
+
+%% header start
+
+%% class start
+
+
+
+/** Options dialog for the wxbmpp program.
+*/
+class DkWxBmepsOptionsDialog : public wxDialog
+{
+
+ private:
+
+ /** Flag: Already in correction, do not enter correction again.
+ */
+ bool bIsCorrecting;
+
+ /** Event table.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ /** Application helper object.
+ */
+ DkWxAppHelper *pHelper;
+
+ /** Localized texts.
+ */
+ wxChar const * const *sTexts;
+
+ /** Paper size names.
+ */
+ wxArrayString *arrayStringPaperSizeNames;
+
+ /** Conversion options.
+ */
+ dk3_bm_eps_options_t *bmepsOptions;
+
+ /** Paper sizes in PS points.
+ */
+ dk3_paper_size_t *paperSizes;
+
+ /** Pointer to variable for selected paper size.
+ */
+ size_t *selectedPaperSize;
+
+ /** Encoding of dkChar.
+ */
+ int dke;
+
+ /** Encoding of wxChar.
+ */
+ int wxe;
+
+ /** Handler for OK button.
+ @param event Event to process.
+ */
+ void
+ OnOK(wxCommandEvent& WXUNUSED(event));
+
+ /** Handler for Cancel button.
+ @param event Event to process.
+ */
+ void
+ OnCancel(wxCommandEvent& WXUNUSED(event));
+
+ /** Handler for output format change.
+ @param event Event to process.
+ */
+ void
+ OnOutputFormat(wxCommandEvent & event);
+
+ /** Handler for output type change.
+ @param event Event to process.
+ */
+ void
+ OnOutputType(wxCommandEvent & event);
+
+ /** Handler for resolution change.
+ @param event Event to process.
+ */
+ void
+ OnResolution(wxCommandEvent & event);
+
+ /** Handler changed draft setting.
+ @param event Event to process.
+ */
+ void
+ OnDraft(wxCommandEvent & event);
+
+ /** Handler for changed PS level.
+ @param event Event to process.
+ */
+ void
+ OnPsLevel(wxCommandEvent & event);
+
+ /** Handler changed interpolation setting.
+ @param event Event to process.
+ */
+ void
+ OnInterpolation(wxCommandEvent & event);
+
+ /** Correct GUI (enable/disable elements based on last decision).
+ */
+ void
+ correctGUI();
+
+
+%% class end
+ public:
+
+ /** Constructor.
+ @param parent Parent window.
+ @param title Dialog box title.
+ @param messageTexts Localized message texts.
+ @param asPaperSizes Known paper size names.
+ @param opt Conversion options.
+ @param pps Known paper sizes array.
+ @param sps Size of @arg pps (number of elements in array).
+ @param applicationHelper Application helper object.
+ @param de Character encoding used for dkChar strings.
+ @param we Character encoding used for wxChar strings.
+ */
+ DkWxBmepsOptionsDialog(
+ DkWxBmepsFrame *parent,
+ wxChar const *title,
+ wxChar const * const *messageTexts,
+ wxArrayString *asPaperSizes,
+ dk3_bm_eps_options_t *opt,
+ dk3_paper_size_t *pps,
+ size_t *sps,
+ DkWxAppHelper *applicationHelper,
+ int de,
+ int we
+ );
+
+ /** Transfer data from GUI controls to configuration structure.
+ */
+ void dataOut();
+
+ /** Transfer data from configuration structure to GUI controls.
+ */
+ void dataIn();
+
+ /** Restrict a number to a range.
+ @param min Range minimum.
+ @param max Range maximum.
+ @param val Value to use.
+ @return The value fitted into the range.
+ */
+ int
+ intToRange(int min, int max, int val);
+
+ /** Set a wxChoice selection.
+ @param ch Choice to modify.
+ @param val New selection index.
+ */
+ void
+ setChoice(wxChoice *ch, int val);
+};
+
+%% header end
+
+
+%% module start
+
+#include "wxbmeps.h"
+
+
+
+$!trace-include
+
+BEGIN_EVENT_TABLE(DkWxBmepsOptionsDialog, wxDialog)
+ EVT_BUTTON(wxID_OK, DkWxBmepsOptionsDialog::OnOK)
+ EVT_BUTTON(wxID_CANCEL, DkWxBmepsOptionsDialog::OnCancel)
+ EVT_CHOICE(DkWxBmeps_OuputFormat, DkWxBmepsOptionsDialog::OnOutputFormat)
+ EVT_CHOICE(DkWxBmeps_OutputType, DkWxBmepsOptionsDialog::OnOutputType)
+ EVT_CHOICE(DkWxBmeps_ResolutionType, DkWxBmepsOptionsDialog::OnResolution)
+ EVT_CHECKBOX(DkWxBmeps_Draft, DkWxBmepsOptionsDialog::OnDraft)
+ EVT_CHOICE(DkWxBmeps_PsLevel, DkWxBmepsOptionsDialog::OnPsLevel)
+ EVT_CHECKBOX(DkWxBmeps_Interpolation, DkWxBmepsOptionsDialog::OnInterpolation)
+END_EVENT_TABLE()
+
+
+
+%% constructor start
+DkWxBmepsOptionsDialog::DkWxBmepsOptionsDialog(
+ DkWxBmepsFrame *parent,
+ wxChar const *title,
+ wxChar const * const *messageTexts,
+ wxArrayString *asPaperSizes,
+ dk3_bm_eps_options_t *opt,
+ dk3_paper_size_t *pps,
+ size_t *sps,
+ DkWxAppHelper *applicationHelper,
+ int de,
+ int we
+) : wxDialog(
+ parent,
+ wxID_ANY,
+ title,
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxDEFAULT_DIALOG_STYLE
+)
+{
+ pHelper = applicationHelper;
+ dke = de; wxe = we;
+ arrayStringPaperSizeNames = asPaperSizes;
+ bmepsOptions = opt;
+ paperSizes = pps;
+ selectedPaperSize = sps;
+ bIsCorrecting = false;
+ wxColour cRed(0x7F, 0x00, 0x00);
+ wxString saOutputFormat[] = {
+ wxString(messageTexts[42]),
+ wxString(messageTexts[43]),
+ wxString(messageTexts[44]),
+ wxString(messageTexts[45])
+ };
+ wxString saOutputType[] = {
+ wxString(messageTexts[47]),
+ wxString(messageTexts[48]),
+ wxString(messageTexts[49])
+ };
+ wxString saFinishing[] = {
+ wxString(messageTexts[51]),
+ wxString(messageTexts[52]),
+ wxString(messageTexts[53])
+ };
+ wxString saResolution[] = {
+ wxString(messageTexts[60]),
+ wxString(messageTexts[61]),
+ wxString(messageTexts[62])
+ };
+ wxString saPsLevel[] = {
+ wxString(wxT("2")),
+ wxString(wxT("3"))
+ };
+ wxString saPredictor[] = {
+ wxString(messageTexts[76]),
+ wxString(messageTexts[77]),
+ wxString(messageTexts[78]),
+ wxString(messageTexts[79]),
+ wxString(messageTexts[80]),
+ wxString(messageTexts[81])
+ };
+ sTexts = messageTexts;
+%% constructor end
+ cvBackground->SetToolTip(messageTexts[88]);
+ sttGeneral->SetForegroundColour(cRed);
+ sttOutput->SetForegroundColour(cRed);
+ sttOutputDetails->SetForegroundColour(cRed);
+ sttOutputSize->SetForegroundColour(cRed);
+ sttInterpolation->SetForegroundColour(cRed);
+ sttTransparency->SetForegroundColour(cRed);
+ txtResolution->ChangeValue(sTexts[3]);
+}
+
+%% module end
+
+
+
+void
+DkWxBmepsOptionsDialog::OnOK(
+ wxCommandEvent & event
+)
+{
+ $? "+ DkWxBmepsOptionsDialog::OnOK"
+ dataOut();
+ if(IsModal()) {
+ EndModal(wxID_OK);
+ } else {
+ SetReturnCode(wxID_OK);
+ Show(false);
+ }
+ $? "- DkWxBmepsOptionsDialog::OnOK"
+}
+
+
+
+void
+DkWxBmepsOptionsDialog::OnCancel(
+ wxCommandEvent & event
+)
+{
+ if(IsModal()) {
+ EndModal(wxID_CANCEL);
+ } else {
+ SetReturnCode(wxID_CANCEL);
+ Show(false);
+ }
+}
+
+
+
+void
+DkWxBmepsOptionsDialog::dataOut()
+{
+ int i;
+ $? "+ DkWxBmepsOptionsDialog::dataOut"
+ /* Make mode cbMakeMode */
+ bmepsOptions->make = ((cbMakeMode->GetValue()) ? 1 : 0);
+ /* Output format cobOutputFormat */
+ i = cobOutputFormat->GetSelection();
+ if((i >= 0) && (i <= DK3_BMEPS_DRIVER_BB)) {
+ bmepsOptions->dr = i;
+ } else {
+ bmepsOptions->dr = 0;
+ }
+ /* Output type cobOutputType */
+ i = cobOutputType->GetSelection();
+ if((i >= 0) && (i <= DK3_BMEPS_MODE_DOCUMENT)) {
+ bmepsOptions->mode = i; $? ". output type %d", i
+ } else {
+ bmepsOptions->mode = 0;
+ }
+ /* Finishing cobFinishing */
+ i = cobFinishing->GetSelection(); $? ". finishing %d", i
+ switch(i) {
+ case 1: {
+ bmepsOptions->duplex = 1; bmepsOptions->tumble = 0;
+ } break;
+ case 2: {
+ bmepsOptions->duplex = 1; bmepsOptions->tumble = 1;
+ } break;
+ default: {
+ bmepsOptions->duplex = 0; bmepsOptions->tumble = 0;
+ } break;
+ }
+ /* Draft cbDraft */
+ bmepsOptions->draft = ((cbDraft->GetValue()) ? 1 : 0);
+ /* Color cbColor */
+ /* bmepsOptions->color = ((cbColor->GetValue()) ? 1 : 0); */
+ /* Resolution choice cobResolution */
+#if VERSION_BEFORE_20140902
+ bmepsOptions->szmode = cobResolution->GetSelection();
+#else
+ switch (bmepsOptions->mode) {
+ case DK3_BMEPS_MODE_DOCUMENT: {
+ bmepsOptions->szmode = DK3_BMEPS_SIZE_PAPER;
+ $? ". szmode = paper"
+ } break;
+ default: {
+ bmepsOptions->szmode = cobResolution->GetSelection();
+ $? ". szmode = %d", bmepsOptions->szmode
+ } break;
+ }
+#endif
+ /* Resolution value txtResolution */
+ if(bmepsOptions->szmode == DK3_BMEPS_SIZE_SPECIFIED) {
+ dkChar bu[64];
+ dkChar *ptr;
+ double v = 0.0;
+ wxString resText = txtResolution->GetValue();
+ wxChar const *txt = resText.c_str();
+ $? ". szmode: specified"
+ if(txt) { $? ". have txt"
+ if(dk3wxs_to_dkstr(bu,DK3_SIZEOF(bu,dkChar),dke,txt,wxe)) {
+ ptr = bu; $? ". dkChar encoding ok \"%s\"", bu
+ while(*ptr) {
+ if(*ptr == dkT(',')) { *ptr = dkT('.'); }
+ ptr++;
+ } $? ". bu = \"%!ds\"", bu
+ if(dk3sf_scan_double_app(bu,&v,NULL)) { $? ". sscanf ok"
+ bmepsOptions->resolution = v; $? ". v = %lf", v
+ } else {
+ bmepsOptions->resolution = 0.0;
+ }
+ } else {
+ bmepsOptions->resolution = 0.0;
+ }
+ } else {
+ bmepsOptions->resolution = 0.0;
+ }
+ } else { $? ". szmode: other"
+ bmepsOptions->resolution = 0.0;
+ }
+ /* Paper size cobPaperSize */
+ if(selectedPaperSize) {
+ *selectedPaperSize = (size_t)(cobPaperSize->GetSelection());
+ $? ". paper size index %d", (int)(cobPaperSize->GetSelection())
+ }
+ /* PS level cobPsLevel */
+ i = cobPsLevel->GetSelection();
+ bmepsOptions->psl = ((i == 1) ? 3 : 2);
+ /* DSC cbDsc */
+ bmepsOptions->dsc = ((cbDsc->GetValue()) ? 1 : 0);
+ /* Predictor cobPredictor */
+ bmepsOptions->pred = cobPredictor->GetSelection();
+ /* DCT cbDCT */
+ bmepsOptions->dct = ((cbDCT->GetValue()) ? 1 : 0);
+ /* Bits per component cbBpc */
+ bmepsOptions->rbpc = ((cbBpc->GetValue()) ? 1 : 0);
+ /* Image interpolation cbInterNormal */
+ bmepsOptions->ip = ((cbInterNormal->GetValue()) ? 1 : 0);
+ /* Interpolation for JPEG cbInterJpeg */
+ bmepsOptions->jip = ((cbInterJpeg->GetValue()) ? 1 : 0);
+ /* Background color cvBackground */
+ bmepsOptions->bgr = cvBackground->getRed();
+ bmepsOptions->bgg = cvBackground->getGreen();
+ bmepsOptions->bgb = cvBackground->getBlue();
+ /* Force background color cbForceBackground*/
+ bmepsOptions->fbg = ((cbForceBackground->GetValue()) ? 1 : 0);
+ (void)dk3bmeo_check(bmepsOptions, 0, bmepsOptions->app, NULL);
+ $? "- DkWxBmepsOptionsDialog::dataOut"
+}
+
+
+
+void
+DkWxBmepsOptionsDialog::dataIn()
+{
+ /* Make mode cbMakeMode */
+ cbMakeMode->SetValue((bmepsOptions->make) ? true : false);
+ /* Output format cobOutputFormat */
+ setChoice(cobOutputFormat, bmepsOptions->dr);
+ /* Output type cobOutputType */
+ setChoice(cobOutputType, bmepsOptions->mode);
+ /* Finishing cobFinishing */
+ if(bmepsOptions->duplex) {
+ if(bmepsOptions->tumble) {
+ cobFinishing->SetSelection(2);
+ } else {
+ cobFinishing->SetSelection(1);
+ }
+ } else {
+ cobFinishing->SetSelection(0);
+ }
+ /* Draft cbDraft */
+ cbDraft->SetValue((bmepsOptions->draft) ? true : false);
+ /* Color cbColor */
+ /* cbColor->SetValue((bmepsOptions->color) ? true : false); */
+ /* Resolution choice cobResolution */
+ $? ". szmode: %d", bmepsOptions->szmode
+ setChoice(cobResolution, bmepsOptions->szmode);
+ /* Resolution value txtResolution */
+ if(bmepsOptions->szmode == 2) { $? ". szmode: 2"
+ txtResolution->ChangeValue(
+ wxString::Format(wxT("%lg"), bmepsOptions->resolution)
+ );
+ } else {
+ txtResolution->ChangeValue(sTexts[3]);
+ }
+ /* Paper size cobPaperSize */
+ if(selectedPaperSize) {
+ setChoice(cobPaperSize, (int)(*selectedPaperSize));
+ } else {
+ cobPaperSize->SetSelection(0);
+ }
+ /* PS level cobPsLevel */
+ if(bmepsOptions->psl == 3) {
+ cobPsLevel->SetSelection(1);
+ } else {
+ cobPsLevel->SetSelection(0);
+ }
+ /* DSC cbDsc */
+ cbDsc->SetValue((bmepsOptions->dsc) ? true : false);
+ /* Predictor cobPredictor */
+ setChoice(cobPredictor, bmepsOptions->pred);
+ /* DCT cbDCT */
+ cbDCT->SetValue((bmepsOptions->dct) ? true : false);
+ /* Reduce bits per component cbBpc */
+ cbBpc->SetValue((bmepsOptions->rbpc) ? true : false);
+ /* Image interpolation cbInterNormal */
+ cbInterNormal->SetValue((bmepsOptions->ip) ? true : false);
+ /* Interpolation for JPEG cbInterJpeg */
+ cbInterJpeg->SetValue((bmepsOptions->jip) ? true : false);
+ /* Background color cvBackground */
+ cvBackground->setRGB(
+ intToRange(0,255,bmepsOptions->bgr),
+ intToRange(0,255,bmepsOptions->bgg),
+ intToRange(0,255,bmepsOptions->bgb)
+ );
+ /* Force background color cbForceBackground*/
+ cbForceBackground->SetValue((bmepsOptions->fbg) ? true : false);
+ correctGUI();
+}
+
+
+
+int
+DkWxBmepsOptionsDialog::intToRange(int min, int max, int val)
+{
+ int back = val;
+ if(back < min) back = min;
+ if(back > max) back = max;
+ return back;
+}
+
+
+
+void
+DkWxBmepsOptionsDialog::setChoice(wxChoice *ch, int val)
+{
+ if(ch) {
+ unsigned max = ch->GetCount();
+ if(val == wxNOT_FOUND) {
+ ch->SetSelection(val);
+ } else {
+ ch->SetSelection(intToRange(0, ((int)max - 1), val));
+ }
+ }
+}
+
+
+
+void
+DkWxBmepsOptionsDialog::OnOutputFormat(wxCommandEvent & event)
+{
+ correctGUI();
+}
+
+
+
+void
+DkWxBmepsOptionsDialog::OnOutputType(wxCommandEvent & event)
+{
+ correctGUI();
+}
+
+
+
+void
+DkWxBmepsOptionsDialog::OnResolution(wxCommandEvent & event)
+{
+ correctGUI();
+}
+
+
+
+void
+DkWxBmepsOptionsDialog::OnDraft(wxCommandEvent & event)
+{
+ correctGUI();
+}
+
+
+
+void
+DkWxBmepsOptionsDialog::OnPsLevel(wxCommandEvent & event)
+{
+ correctGUI();
+}
+
+
+
+void
+DkWxBmepsOptionsDialog::OnInterpolation(wxCommandEvent & event)
+{
+ correctGUI();
+}
+
+
+
+void
+DkWxBmepsOptionsDialog::correctGUI()
+{
+ bool doEnable;
+ $? "+ DkWxBmepsOptionsDialog::correctGUI"
+ if(!bIsCorrecting) {
+ bIsCorrecting = true;
+ /* Output type */
+ if(cobOutputFormat->GetSelection() == 3) {
+ cobOutputType->SetSelection(1);
+ cobOutputType->Enable(false);
+ } else {
+ cobOutputType->Enable(true);
+ }
+ /* Finishing */
+ if(cobOutputType->GetSelection() == 2) {
+ cobFinishing->Enable(true);
+ } else {
+ cobFinishing->Enable(false);
+ }
+ /* Resolution type */
+ switch(cobOutputType->GetSelection()) {
+ case 0: {
+ cobResolution->Enable(true);
+ } break;
+ case 1: {
+ cobResolution->SetSelection(0);
+ cobResolution->Enable(false);
+ } break;
+ case 2: {
+ cobResolution->Enable(false);
+ } break;
+ }
+ /* Resolution text */
+ if(cobResolution->GetSelection() == 2) {
+ txtResolution->Enable(true);
+ } else {
+ txtResolution->Enable(false);
+ }
+ /* Paper size */
+ if(cobOutputType->GetSelection() == 2) {
+ cobPaperSize->Enable(true);
+ } else {
+ cobPaperSize->Enable(false);
+ }
+ /* Draft mode */
+ if(cobOutputFormat->GetSelection() == 3) {
+ cbDraft->Enable(false);
+ } else {
+ if(cobOutputType->GetSelection() == 2) {
+ cbDraft->Enable(false);
+ } else {
+ cbDraft->Enable(true);
+ }
+ }
+ /* Color */
+ if(cobOutputFormat->GetSelection() == 3) {
+ /* cbColor->Enable(false); */
+ } else {
+ if(cbDraft->GetValue()) {
+ /* cbColor->Enable(false); */
+ } else {
+ /* cbColor->Enable(true); */
+ }
+ }
+ /* PS level and DSC */
+ switch(cobOutputFormat->GetSelection()) {
+ case 0: case 1: {
+ cobPsLevel->Enable(true);
+ cbDsc->Enable(true);
+ } break;
+ default: {
+ cobPsLevel->Enable(false);
+ cbDsc->Enable(false);
+ } break;
+ }
+ /* Predictor */
+ doEnable = false;
+ switch(cobOutputFormat->GetSelection()) {
+ case 0: case 1: {
+ if(cobPsLevel->GetSelection() == 1) {
+ doEnable = true;
+ }
+ } break;
+ case 2: {
+ doEnable = true;
+ } break;
+ }
+ if(cbDraft->GetValue()) { doEnable = false; }
+ cobPredictor->Enable(doEnable);
+ /* Re-use JPEG DCT data */
+ if(cobOutputFormat->GetSelection() == 3) {
+ cbDCT->Enable(false);
+ } else {
+ if(cbDraft->GetValue()) {
+ cbDCT->Enable(false);
+ } else {
+ cbDCT->Enable(true);
+ }
+ }
+ /* Normal interpolation */
+ if(cobOutputFormat->GetSelection() == 3) {
+ cbInterNormal->Enable(false);
+ } else {
+ if(cbDraft->GetValue()) {
+ cbInterNormal->Enable(false);
+ } else {
+ cbInterNormal->Enable(true);
+ }
+ }
+ /* Interpolation for JPEG */
+ if(cobOutputFormat->GetSelection() == 3) {
+ cbInterJpeg->Enable(false);
+ } else {
+ if(cbInterNormal->GetValue()) {
+ if(cbDraft->GetValue()) {
+ cbInterJpeg->Enable(false);
+ } else {
+ cbInterJpeg->Enable(true);
+ }
+ } else {
+ cbInterJpeg->Enable(false);
+ }
+ }
+ /* Force background */
+ if(cobOutputFormat->GetSelection() == 3) {
+ cbForceBackground->Enable(false);
+ } else {
+ if(cbDraft->GetValue()) {
+ cbForceBackground->Enable(false);
+ } else {
+ cbForceBackground->Enable(true);
+ }
+ }
+ bIsCorrecting = false;
+ Refresh();
+ Update();
+ } $? "- DkWxBmepsOptionsDialog::correctGUI"
+}
+
diff --git a/support/dktools/DkWxBmepsThread.cpp b/support/dktools/DkWxBmepsThread.cpp
new file mode 100644
index 0000000000..f79a017cda
--- /dev/null
+++ b/support/dktools/DkWxBmepsThread.cpp
@@ -0,0 +1,581 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxBmepsThread.cpt
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxBmepsThread.cpp The DkWxBmepsThread module.
+*/
+
+
+#line 127 "DkWxBmepsThread.cpt"
+
+#include "wxbmeps.h"
+
+
+
+#line 131 "DkWxBmepsThread.cpt"
+
+
+
+/** File name separator.
+*/
+static wxChar const dkwxbmeps_fnsep[] = {
+DK3_WX_CHAR_SEP , wxT('\0')
+};
+
+
+
+static wxChar const * const dkwxbmeps_output_suffixes[] = {
+wxT(".ps"),
+wxT(".eps"),
+wxT(".pdf"),
+wxT(".bb")
+};
+
+
+
+
+/** Non-localized keywords used by this module.
+*/
+static wxChar const * const dkwxbmeps_thread_kw[] = {
+/* 0 */
+wxT("*.*"),
+
+NULL
+
+
+#line 161 "DkWxBmepsThread.cpt"
+};
+
+
+
+/** File suffixes we can handle.
+*/
+static wxChar const * const dkwxbmeps_thread_suffixes[] = {
+#if DK3_HAVE_PNG_H
+wxT(".png"),
+#endif
+#if DK3_HAVE_JPEGLIB_H
+wxT(".jpg"),
+wxT(".jpeg"),
+#endif
+#if DK3_HAVE_TIFF_H
+wxT(".tif"),
+wxT(".tiff"),
+#endif
+NULL
+};
+
+
+
+DkWxBmepsThread::DkWxBmepsThread(
+ DkWxCommunicator *pc,
+ wxChar const * const *st,
+ dkChar const * const *m,
+ wxChar const *sd,
+ DkWxAppHelper *ph,
+ int wxe,
+ int dke,
+ dk3_bm_eps_options_t *bmeoptr
+)
+{
+
+
+#line 196 "DkWxBmepsThread.cpt"
+ pComm = pc;
+ sTexts = st;
+ msg = m;
+ sDirectory = dk3wxs_dup_app(sd, ph->getApp());
+ pHelper = ph;
+ wxenc = wxe;
+ dkenc = dke;
+ dk3mem_cpy((void *)(&bmeo), (void *)bmeoptr, sizeof(dk3_bm_eps_options_t));
+ bmeo.to_stdout = 0;
+
+
+#line 206 "DkWxBmepsThread.cpt"
+}
+
+
+
+bool
+DkWxBmepsThread::checkSetup()
+{
+ bool back = false;
+
+
+#line 215 "DkWxBmepsThread.cpt"
+ if(sDirectory) {
+ back = true;
+ }
+
+#line 218 "DkWxBmepsThread.cpt"
+ return back;
+}
+
+
+
+DkWxBmepsThread::~DkWxBmepsThread()
+{
+
+
+#line 226 "DkWxBmepsThread.cpt"
+ dk3_release(sDirectory);
+
+
+#line 228 "DkWxBmepsThread.cpt"
+}
+
+
+
+void *
+DkWxBmepsThread::Entry()
+{
+#if 0
+ /*
+ Simple test thread without practical use.
+ */
+ int i = 0;
+ int cc = 1;
+ int numbreak = -1;
+ do {
+ this->Sleep(100);
+ i++;
+ if(i >= 10) {
+ cc = 0;
+ }
+ pComm->setUpdates(wxT("test-file"), (100*i));
+ if(pComm->getCanContinue() == 0) {
+ if(numbreak == -1) {
+ numbreak = i;
+ } else {
+ if(i >= numbreak + 15) {
+ cc = 0;
+ }
+ }
+ }
+ pComm->addWxText(wxT("Test mit einer ganz ganz ganz ganz langen Zeile\n"));
+ } while(cc);
+ pComm->setRunning(0);
+#else
+
+
+#line 263 "DkWxBmepsThread.cpt"
+ if(wxFileName::DirExists(sDirectory)) {
+
+#line 264 "DkWxBmepsThread.cpt"
+ runForDirectory(sDirectory);
+ } else {
+
+#line 266 "DkWxBmepsThread.cpt"
+ if(wxFileName::FileExists(sDirectory)) {
+
+#line 267 "DkWxBmepsThread.cpt"
+ runForFile(sDirectory, 0, 1000);
+ } else {
+
+#line 269 "DkWxBmepsThread.cpt"
+ /* ##### ERROR: No such file or directory! */
+ }
+ }
+ pComm->setRunning(0);
+
+#line 273 "DkWxBmepsThread.cpt"
+#endif
+ return NULL;
+}
+
+
+
+void
+DkWxBmepsThread::OnExit()
+{
+ /* Doing nothing. */
+
+
+#line 284 "DkWxBmepsThread.cpt"
+}
+
+
+
+/** Compare two wxChar file names.
+ @param l Left file name.
+ @param r Right file name.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+static
+int
+dkwxbmeps_compare_filenames(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ if(l) {
+ if(r) {
+#if DK3_HAVE_FNCASEINS
+ back = dk3wxs_casecmp((wxChar const *)l, (wxChar const *)r);
+#else
+ back = dk3wxs_cmp((wxChar const *)l, (wxChar const *)r);
+#endif
+ if(back < -1) back = -1;
+ if(back > 1) back = 1;
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+void
+DkWxBmepsThread::runForFile(wxChar const *fn, int ming, int maxg)
+{
+ dkChar sfn[DK3_MAX_PATH];
+ wxChar const *shortname;
+
+
+#line 327 "DkWxBmepsThread.cpt"
+ shortname = shortFileName(fn);
+ if(dk3wxs_to_dkstr(
+ sfn,
+ DK3_SIZEOF(sfn,dkChar),
+ pHelper->getDkEncoding(),
+ fn,
+ pHelper->getWxEncoding()
+ )
+ )
+ {
+ /* PROGRESS MESSAGE Start */
+ pComm->addWxText(sTexts[114]);
+ pComm->addWxText(shortname);
+ pComm->addWxText(sTexts[115]);
+ pComm->addWxText(sTexts[110]);
+ (void)dk3bm_process_file_name(
+ &bmeo,
+ sfn,
+ DK3_BIF_IMAGE_TYPE_UNKNOWN,
+ ming,
+ maxg,
+ (void *)pComm
+ );
+ /* PROGRESS MESSAGE Finished */
+#if 0
+ pComm->addWxText(sTexts[116]);
+ pComm->addWxText(shortname);
+ pComm->addWxText(sTexts[117]);
+ pComm->addWxText(sTexts[110]);
+#endif
+ pComm->addWxText(sTexts[110]);
+ } else {
+
+#line 359 "DkWxBmepsThread.cpt"
+ /* ERROR: Failed to convert file name! */
+ pComm->addWxText(sTexts[118]);
+ pComm->addWxText(shortname);
+ pComm->addWxText(sTexts[119]);
+ pComm->addWxText(sTexts[110]);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ }
+ pComm->setUpdates(NULL, maxg);
+
+
+#line 368 "DkWxBmepsThread.cpt"
+}
+
+
+
+
+
+
+void
+DkWxBmepsThread::runForDirectory(wxChar const *dn)
+{
+ wxChar namein[DK3_MAX_PATH];
+ wxChar const *currentfn;
+ wxChar const *cfilename;
+ wxChar *suffix;
+ dk3_sto_t *sFiles;
+ dk3_sto_it_t *iFiles;
+ size_t fnlgt;
+ int namesFound;
+ int i;
+ int promille;
+ int cc;
+
+
+
+#line 391 "DkWxBmepsThread.cpt"
+ pComm->addWxText(sTexts[106]);
+ pComm->addWxText(dn);
+ pComm->addWxText(sTexts[107]);
+ pComm->addWxText(sTexts[110]);
+ pComm->addWxText(sTexts[110]);
+ sFiles = dk3sto_open_app(pHelper->getApp());
+ if(sFiles) {
+ dk3sto_set_comp(sFiles, dkwxbmeps_compare_filenames, 0);
+ iFiles = dk3sto_it_open(sFiles);
+ if(iFiles) {
+ /*
+ Find all input filename candidates.
+ */
+ namesFound = 0;
+ {
+ wxLogNull lognull;
+ bool canContinue;
+ wxDir directory(sDirectory);
+ if(directory.IsOpened()) {
+ wxString filename;
+ canContinue = directory.GetFirst(
+ &filename, dkwxbmeps_thread_kw[0], wxDIR_FILES
+ );
+ while(canContinue) {
+ cfilename = filename.c_str();
+ if(cfilename) {
+ if(dk3wxs_len(cfilename) < DK3_SIZEOF(namein,wxChar)) {
+ dk3wxs_cpy(namein, cfilename);
+ suffix = dk3wxs_get_suffix(namein);
+ if(suffix) {
+ if(dk3wxs_array_index(dkwxbmeps_thread_suffixes,suffix,0)
+ > -1
+ )
+ {
+ suffix = dk3wxs_dup_app(namein, pHelper->getApp());
+ if(suffix) {
+ if(dk3sto_add(sFiles, suffix)) {
+ namesFound++;
+
+#line 429 "DkWxBmepsThread.cpt"
+ } else {
+ /* ERROR: Memory */
+ dk3_release(suffix);
+ pComm->addWxText(sTexts[105]);
+ pComm->addWxText(sTexts[110]);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ }
+ } else {
+ /* ERROR: Memory */
+ pComm->addWxText(sTexts[105]);
+ pComm->addWxText(sTexts[110]);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ }
+ }
+ }
+ } else {
+ /* ERROR: Name too long! */
+ pComm->addWxText(sTexts[111]);
+ pComm->addWxText(cfilename);
+ pComm->addWxText(sTexts[112]);
+ pComm->addWxText(sTexts[110]);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ }
+ }
+ canContinue = directory.GetNext(&filename);
+ }
+ }
+ }
+ pComm->setUpdates(NULL, 50);
+ /*
+ Process all input file name candidates.
+ */
+ if(namesFound > 0) {
+ dk3sto_it_reset(iFiles);
+ i = 0;
+#if VERSION_BEFORE_20150821
+ /* Immediately set to 0 at loop begin */
+ cc = 1;
+#endif
+ do {
+ cc = 0;
+ cfilename = (wxChar const *)dk3sto_it_next(iFiles);
+ if(cfilename) {
+ cc = 1;
+ promille = 50 + (950 * i )/namesFound;
+ if(promille >= 1000) { promille = 999; }
+ pComm->setUpdates(cfilename, promille);
+
+
+#line 477 "DkWxBmepsThread.cpt"
+ fnlgt = dk3wxs_len(sDirectory);
+ fnlgt += dk3wxs_len(cfilename);
+ fnlgt += 1;
+ if(fnlgt < DK3_SIZEOF(namein,wxChar)) {
+ dk3wxs_cpy(namein, sDirectory);
+ dk3wxs_cat(namein, dkwxbmeps_fnsep);
+ dk3wxs_cat(namein, cfilename);
+ if(checkMustRun(namein)) {
+ runForFile(
+ namein,
+ 50 + (950 * i )/namesFound,
+ 50 + (950 * (i + 1))/namesFound
+ );
+ }
+ } else {
+ /* ERROR: File name too long for buffer */
+ pComm->addWxText(sTexts[111]);
+ pComm->addWxText(sDirectory);
+ pComm->addWxText(dkwxbmeps_fnsep);
+ pComm->addWxText(cfilename);
+ pComm->addWxText(sTexts[112]);
+ pComm->addWxText(sTexts[110]);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ }
+ i++;
+ promille = 50 + (950 * i )/namesFound;
+ if(promille >= 1000) { promille = 999; }
+ pComm->setUpdates(cfilename, promille);
+ if(!(pComm->getCanContinue())) {
+ cc = 0;
+ }
+ }
+ } while(cc);
+ pComm->setUpdates(cfilename, 1000);
+ } else {
+ /* ERROR: No names found! */
+ pComm->addWxText(sTexts[113]);
+ pComm->addWxText(sTexts[110]);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ }
+ /*
+ Release the file names.
+ */
+ dk3sto_it_reset(iFiles);
+ while((currentfn = (wxChar const *)dk3sto_it_next(iFiles)) != NULL) {
+ dk3_release(currentfn);
+ }
+ dk3sto_it_close(iFiles);
+ } else {
+ pComm->addWxText(sTexts[105]);
+ pComm->addWxText(sTexts[110]);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ }
+ dk3sto_close(sFiles);
+ } else {
+ pComm->addWxText(sTexts[105]);
+ pComm->addWxText(sTexts[110]);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ }
+ pComm->addWxText(sTexts[108]);
+ pComm->addWxText(dn);
+ pComm->addWxText(sTexts[109]);
+ pComm->addWxText(sTexts[110]);
+
+
+#line 541 "DkWxBmepsThread.cpt"
+}
+
+
+
+bool
+DkWxBmepsThread::checkMustRun(wxChar const *sfn)
+{
+ wxChar nameout[DK3_MAX_PATH];
+ wxChar *suffix;
+ wxChar const *nsuffix;
+ bool back = true;
+ if(bmeo.make) {
+ dk3wxs_cpy(nameout, sfn);
+ suffix = dk3wxs_get_suffix(nameout);
+ if(suffix) {
+ *suffix = wxT('\0');
+ nsuffix = NULL;
+ switch(bmeo.dr) {
+ case DK3_BMEPS_DRIVER_PS: {
+ nsuffix = dkwxbmeps_output_suffixes[0];
+ } break;
+ case DK3_BMEPS_DRIVER_EPS: {
+ nsuffix = dkwxbmeps_output_suffixes[1];
+ } break;
+ case DK3_BMEPS_DRIVER_PDF: {
+ nsuffix = dkwxbmeps_output_suffixes[2];
+ } break;
+ case DK3_BMEPS_DRIVER_BB: {
+ nsuffix = dkwxbmeps_output_suffixes[3];
+ } break;
+ }
+ if(nsuffix) {
+ if((dk3wxs_len(nameout) + dk3wxs_len(nsuffix))
+ < DK3_SIZEOF(nameout,wxChar)
+ )
+ {
+ dk3wxs_cat(nameout, nsuffix);
+ if(wxFileName::FileExists(sfn)) {
+ if(wxFileName::FileExists(nameout)) {
+ wxFileName fni(sfn);
+ wxFileName fno(nameout);
+ if(fno.GetModificationTime() > fni.GetModificationTime()) {
+ back = false;
+ }
+ }
+ } else {
+ /* ##### BUG: Source file does not exist, should not happen. */
+ }
+ } else {
+ /* ##### ERROR: Name too long! */
+ }
+ } else {
+
+#line 593 "DkWxBmepsThread.cpt"
+ /* BUG: Illegal output driver, should not happen. */
+ }
+ }
+ }
+ return back;
+}
+
+
+
+wxChar const *
+DkWxBmepsThread::shortFileName(wxChar const *longName)
+{
+ wxChar const *back = NULL;
+ wxChar const *ptr;
+
+ if(longName) {
+ ptr = longName;
+ while(*ptr) {
+ if(*ptr == DK3_WX_CHAR_SEP) {
+ back = ptr;
+ }
+ ptr++;
+ }
+ if(back) { back++; }
+ else { back = longName; }
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/DkWxBmepsThread.cpt b/support/dktools/DkWxBmepsThread.cpt
new file mode 100644
index 0000000000..6e5e44fcbe
--- /dev/null
+++ b/support/dktools/DkWxBmepsThread.cpt
@@ -0,0 +1,622 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+%% header
+
+
+/** Worker thread for wxbmeps.
+*/
+class DkWxBmepsThread : public wxThread
+{
+ protected:
+
+ /** Conversion options.
+ */
+ dk3_bm_eps_options_t bmeo;
+
+ /** Communication object to communicate with main thread.
+ */
+ DkWxCommunicator *pComm;
+
+ /** Localized messages, wxChar strings.
+ */
+ wxChar const * const *sTexts;
+
+ /** Localized messages, dkChar strings.
+ */
+ dkChar const * const *msg;
+
+ /** Directory or file name.
+ */
+ wxChar const *sDirectory;
+
+ /** Application helper.
+ */
+ DkWxAppHelper *pHelper;
+
+ /** Encoding for wxChar strings.
+ */
+ int wxenc;
+
+ /** Encoding for dkChar strings.
+ */
+ int dkenc;
+
+ public:
+
+ /** Constructor.
+ @param pc Communication object.
+ @param st Localized messages, wxChar strings.
+ @param m Localized messages, dkChar strings.
+ @param sd Directory or file name.
+ @param ph Application helper.
+ @param wxe Encoding for wxChar strings.
+ @param dke Encoding for dkChar strings.
+ @param bmeoptr Conversion options.
+ */
+ DkWxBmepsThread(
+ DkWxCommunicator *pc,
+ wxChar const * const *st,
+ dkChar const * const *m,
+ wxChar const *sd,
+ DkWxAppHelper *ph,
+ int wxe,
+ int dke,
+ dk3_bm_eps_options_t *bmeoptr
+ );
+
+ /** Destructor.
+ */
+ ~DkWxBmepsThread();
+
+ /** Check setup (memory allocations succeeded).
+ @return Test result, true on success, false on error.
+ */
+ bool
+ checkSetup();
+
+ /** Thread function.
+ @return A pointer which is ignored.
+ */
+ virtual
+ void *
+ Entry();
+
+ /** Function executed at end of thread, does nothing.
+ */
+ virtual
+ void
+ OnExit();
+
+ /** Run for one file.
+ @param fn File name.
+ @param ming Minimum value for progress bar.
+ @param maxg Maximum value for progress bar.
+ */
+ void
+ runForFile(wxChar const *fn, int ming, int maxg);
+
+ /** Run for one directory.
+ @param dn Directory name.
+ */
+ void
+ runForDirectory(wxChar const *dn);
+
+ /** Check whether we must run for a file.
+ @param sfn Source file name.
+ @return true for must run, false for not necessary.
+ */
+ bool
+ checkMustRun(wxChar const *sfn);
+
+ /** Get short file name.
+ @param longName Full file name.
+ @return Pointer to short file name on success, NULL on error.
+ */
+ wxChar const *
+ shortFileName(wxChar const *longName);
+};
+
+
+
+%% module
+
+#include "wxbmeps.h"
+
+$!trace-include
+
+
+
+/** File name separator.
+*/
+static wxChar const dkwxbmeps_fnsep[] = {
+DK3_WX_CHAR_SEP , wxT('\0')
+};
+
+
+
+static wxChar const * const dkwxbmeps_output_suffixes[] = {
+wxT(".ps"),
+wxT(".eps"),
+wxT(".pdf"),
+wxT(".bb")
+};
+
+
+
+
+/** Non-localized keywords used by this module.
+*/
+static wxChar const * const dkwxbmeps_thread_kw[] = {
+$!string-table macro=wxT
+#
+# 0: File specification.
+#
+*.*
+$!end
+};
+
+
+
+/** File suffixes we can handle.
+*/
+static wxChar const * const dkwxbmeps_thread_suffixes[] = {
+#if DK3_HAVE_PNG_H
+wxT(".png"),
+#endif
+#if DK3_HAVE_JPEGLIB_H
+wxT(".jpg"),
+wxT(".jpeg"),
+#endif
+#if DK3_HAVE_TIFF_H
+wxT(".tif"),
+wxT(".tiff"),
+#endif
+NULL
+};
+
+
+
+DkWxBmepsThread::DkWxBmepsThread(
+ DkWxCommunicator *pc,
+ wxChar const * const *st,
+ dkChar const * const *m,
+ wxChar const *sd,
+ DkWxAppHelper *ph,
+ int wxe,
+ int dke,
+ dk3_bm_eps_options_t *bmeoptr
+)
+{
+ $? "+ DkWxBmepsThread::DkWxBmepsThread"
+ pComm = pc;
+ sTexts = st;
+ msg = m;
+ sDirectory = dk3wxs_dup_app(sd, ph->getApp());
+ pHelper = ph;
+ wxenc = wxe;
+ dkenc = dke;
+ dk3mem_cpy((void *)(&bmeo), (void *)bmeoptr, sizeof(dk3_bm_eps_options_t));
+ bmeo.to_stdout = 0;
+ $? "- DkWxBmepsThread::DkWxBmepsThread"
+}
+
+
+
+bool
+DkWxBmepsThread::checkSetup()
+{
+ bool back = false;
+ $? "+ DkWxBmepsThread::checkSetup"
+ if(sDirectory) {
+ back = true;
+ } $? "- DkWxBmepsThread::checkSetup %d", (back ? 1 : 0)
+ return back;
+}
+
+
+
+DkWxBmepsThread::~DkWxBmepsThread()
+{
+ $? "+ DkWxBmepsThread::~DkWxBmepsThread"
+ dk3_release(sDirectory);
+ $? "- DkWxBmepsThread::~DkWxBmepsThread"
+}
+
+
+
+void *
+DkWxBmepsThread::Entry()
+{
+#if 0
+ /*
+ Simple test thread without practical use.
+ */
+ int i = 0;
+ int cc = 1;
+ int numbreak = -1;
+ do {
+ this->Sleep(100);
+ i++;
+ if(i >= 10) {
+ cc = 0;
+ }
+ pComm->setUpdates(wxT("test-file"), (100*i));
+ if(pComm->getCanContinue() == 0) {
+ if(numbreak == -1) {
+ numbreak = i;
+ } else {
+ if(i >= numbreak + 15) {
+ cc = 0;
+ }
+ }
+ }
+ pComm->addWxText(wxT("Test mit einer ganz ganz ganz ganz langen Zeile\n"));
+ } while(cc);
+ pComm->setRunning(0);
+#else
+ $? "+ DkWxBmepsThread::Entry"
+ if(wxFileName::DirExists(sDirectory)) { $? ". handle directory"
+ runForDirectory(sDirectory);
+ } else { $? ". check for single file"
+ if(wxFileName::FileExists(sDirectory)) { $? ". file"
+ runForFile(sDirectory, 0, 1000);
+ } else { $? "! no such file"
+ /* ##### ERROR: No such file or directory! */
+ }
+ }
+ pComm->setRunning(0); $? "- DkWxBmepsThread::Entry"
+#endif
+ return NULL;
+}
+
+
+
+void
+DkWxBmepsThread::OnExit()
+{
+ /* Doing nothing. */
+ $? "= DkWxBmepsThread::OnExit"
+}
+
+
+
+/** Compare two wxChar file names.
+ @param l Left file name.
+ @param r Right file name.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+static
+int
+dkwxbmeps_compare_filenames(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ if(l) {
+ if(r) {
+#if DK3_HAVE_FNCASEINS
+ back = dk3wxs_casecmp((wxChar const *)l, (wxChar const *)r);
+#else
+ back = dk3wxs_cmp((wxChar const *)l, (wxChar const *)r);
+#endif
+ if(back < -1) back = -1;
+ if(back > 1) back = 1;
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+void
+DkWxBmepsThread::runForFile(wxChar const *fn, int ming, int maxg)
+{
+ dkChar sfn[DK3_MAX_PATH];
+ wxChar const *shortname;
+ $? "+ DkWxBmepsThread::runForFile \"%ls\"", fn
+ shortname = shortFileName(fn);
+ if(dk3wxs_to_dkstr(
+ sfn,
+ DK3_SIZEOF(sfn,dkChar),
+ pHelper->getDkEncoding(),
+ fn,
+ pHelper->getWxEncoding()
+ )
+ )
+ {
+ /* PROGRESS MESSAGE Start */
+ pComm->addWxText(sTexts[114]);
+ pComm->addWxText(shortname);
+ pComm->addWxText(sTexts[115]);
+ pComm->addWxText(sTexts[110]);
+ (void)dk3bm_process_file_name(
+ &bmeo,
+ sfn,
+ DK3_BIF_IMAGE_TYPE_UNKNOWN,
+ ming,
+ maxg,
+ (void *)pComm
+ );
+ /* PROGRESS MESSAGE Finished */
+#if 0
+ pComm->addWxText(sTexts[116]);
+ pComm->addWxText(shortname);
+ pComm->addWxText(sTexts[117]);
+ pComm->addWxText(sTexts[110]);
+#endif
+ pComm->addWxText(sTexts[110]);
+ } else { $? "! failed to convert file name to dkChar string"
+ /* ERROR: Failed to convert file name! */
+ pComm->addWxText(sTexts[118]);
+ pComm->addWxText(shortname);
+ pComm->addWxText(sTexts[119]);
+ pComm->addWxText(sTexts[110]);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ }
+ pComm->setUpdates(NULL, maxg);
+ $? "- DkWxBmepsThread::runForFile"
+}
+
+
+
+
+
+
+void
+DkWxBmepsThread::runForDirectory(wxChar const *dn)
+{
+ wxChar namein[DK3_MAX_PATH];
+ wxChar const *currentfn;
+ wxChar const *cfilename;
+ wxChar *suffix;
+ dk3_sto_t *sFiles;
+ dk3_sto_it_t *iFiles;
+ size_t fnlgt;
+ int namesFound;
+ int i;
+ int promille;
+ int cc;
+
+ $? "+ DkWxBmepsThread::runForDirectory \"%ls\"", dn
+ pComm->addWxText(sTexts[106]);
+ pComm->addWxText(dn);
+ pComm->addWxText(sTexts[107]);
+ pComm->addWxText(sTexts[110]);
+ pComm->addWxText(sTexts[110]);
+ sFiles = dk3sto_open_app(pHelper->getApp());
+ if(sFiles) {
+ dk3sto_set_comp(sFiles, dkwxbmeps_compare_filenames, 0);
+ iFiles = dk3sto_it_open(sFiles);
+ if(iFiles) {
+ /*
+ Find all input filename candidates.
+ */
+ namesFound = 0;
+ {
+ wxLogNull lognull;
+ bool canContinue;
+ wxDir directory(sDirectory);
+ if(directory.IsOpened()) {
+ wxString filename;
+ canContinue = directory.GetFirst(
+ &filename, dkwxbmeps_thread_kw[0], wxDIR_FILES
+ );
+ while(canContinue) {
+ cfilename = filename.c_str();
+ if(cfilename) {
+ if(dk3wxs_len(cfilename) < DK3_SIZEOF(namein,wxChar)) {
+ dk3wxs_cpy(namein, cfilename);
+ suffix = dk3wxs_get_suffix(namein);
+ if(suffix) {
+ if(dk3wxs_array_index(dkwxbmeps_thread_suffixes,suffix,0)
+ > -1
+ )
+ {
+ suffix = dk3wxs_dup_app(namein, pHelper->getApp());
+ if(suffix) {
+ if(dk3sto_add(sFiles, suffix)) {
+ namesFound++; $? ". registered \"%ls\"", suffix
+ } else {
+ /* ERROR: Memory */
+ dk3_release(suffix);
+ pComm->addWxText(sTexts[105]);
+ pComm->addWxText(sTexts[110]);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ }
+ } else {
+ /* ERROR: Memory */
+ pComm->addWxText(sTexts[105]);
+ pComm->addWxText(sTexts[110]);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ }
+ }
+ }
+ } else {
+ /* ERROR: Name too long! */
+ pComm->addWxText(sTexts[111]);
+ pComm->addWxText(cfilename);
+ pComm->addWxText(sTexts[112]);
+ pComm->addWxText(sTexts[110]);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ }
+ }
+ canContinue = directory.GetNext(&filename);
+ }
+ }
+ }
+ pComm->setUpdates(NULL, 50);
+ /*
+ Process all input file name candidates.
+ */
+ if(namesFound > 0) {
+ dk3sto_it_reset(iFiles);
+ i = 0;
+#if VERSION_BEFORE_20150821
+ /* Immediately set to 0 at loop begin */
+ cc = 1;
+#endif
+ do {
+ cc = 0;
+ cfilename = (wxChar const *)dk3sto_it_next(iFiles);
+ if(cfilename) {
+ cc = 1;
+ promille = 50 + (950 * i )/namesFound;
+ if(promille >= 1000) { promille = 999; }
+ pComm->setUpdates(cfilename, promille);
+ $? ". file \"%ls\"", cfilename
+ fnlgt = dk3wxs_len(sDirectory);
+ fnlgt += dk3wxs_len(cfilename);
+ fnlgt += 1;
+ if(fnlgt < DK3_SIZEOF(namein,wxChar)) {
+ dk3wxs_cpy(namein, sDirectory);
+ dk3wxs_cat(namein, dkwxbmeps_fnsep);
+ dk3wxs_cat(namein, cfilename);
+ if(checkMustRun(namein)) {
+ runForFile(
+ namein,
+ 50 + (950 * i )/namesFound,
+ 50 + (950 * (i + 1))/namesFound
+ );
+ }
+ } else {
+ /* ERROR: File name too long for buffer */
+ pComm->addWxText(sTexts[111]);
+ pComm->addWxText(sDirectory);
+ pComm->addWxText(dkwxbmeps_fnsep);
+ pComm->addWxText(cfilename);
+ pComm->addWxText(sTexts[112]);
+ pComm->addWxText(sTexts[110]);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ }
+ i++;
+ promille = 50 + (950 * i )/namesFound;
+ if(promille >= 1000) { promille = 999; }
+ pComm->setUpdates(cfilename, promille);
+ if(!(pComm->getCanContinue())) {
+ cc = 0;
+ }
+ }
+ } while(cc);
+ pComm->setUpdates(cfilename, 1000);
+ } else {
+ /* ERROR: No names found! */
+ pComm->addWxText(sTexts[113]);
+ pComm->addWxText(sTexts[110]);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ }
+ /*
+ Release the file names.
+ */
+ dk3sto_it_reset(iFiles);
+ while((currentfn = (wxChar const *)dk3sto_it_next(iFiles)) != NULL) {
+ dk3_release(currentfn);
+ }
+ dk3sto_it_close(iFiles);
+ } else {
+ pComm->addWxText(sTexts[105]);
+ pComm->addWxText(sTexts[110]);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ }
+ dk3sto_close(sFiles);
+ } else {
+ pComm->addWxText(sTexts[105]);
+ pComm->addWxText(sTexts[110]);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ }
+ pComm->addWxText(sTexts[108]);
+ pComm->addWxText(dn);
+ pComm->addWxText(sTexts[109]);
+ pComm->addWxText(sTexts[110]);
+ $? "- DkWxBmepsThread::runForDirectory"
+}
+
+
+
+bool
+DkWxBmepsThread::checkMustRun(wxChar const *sfn)
+{
+ wxChar nameout[DK3_MAX_PATH];
+ wxChar *suffix;
+ wxChar const *nsuffix;
+ bool back = true;
+ if(bmeo.make) {
+ dk3wxs_cpy(nameout, sfn);
+ suffix = dk3wxs_get_suffix(nameout);
+ if(suffix) {
+ *suffix = wxT('\0');
+ nsuffix = NULL;
+ switch(bmeo.dr) {
+ case DK3_BMEPS_DRIVER_PS: {
+ nsuffix = dkwxbmeps_output_suffixes[0];
+ } break;
+ case DK3_BMEPS_DRIVER_EPS: {
+ nsuffix = dkwxbmeps_output_suffixes[1];
+ } break;
+ case DK3_BMEPS_DRIVER_PDF: {
+ nsuffix = dkwxbmeps_output_suffixes[2];
+ } break;
+ case DK3_BMEPS_DRIVER_BB: {
+ nsuffix = dkwxbmeps_output_suffixes[3];
+ } break;
+ }
+ if(nsuffix) {
+ if((dk3wxs_len(nameout) + dk3wxs_len(nsuffix))
+ < DK3_SIZEOF(nameout,wxChar)
+ )
+ {
+ dk3wxs_cat(nameout, nsuffix);
+ if(wxFileName::FileExists(sfn)) {
+ if(wxFileName::FileExists(nameout)) {
+ wxFileName fni(sfn);
+ wxFileName fno(nameout);
+ if(fno.GetModificationTime() > fni.GetModificationTime()) {
+ back = false;
+ }
+ }
+ } else {
+ /* ##### BUG: Source file does not exist, should not happen. */
+ }
+ } else {
+ /* ##### ERROR: Name too long! */
+ }
+ } else { $? "! Bug, illegal output driver"
+ /* BUG: Illegal output driver, should not happen. */
+ }
+ }
+ }
+ return back;
+}
+
+
+
+wxChar const *
+DkWxBmepsThread::shortFileName(wxChar const *longName)
+{
+ wxChar const *back = NULL;
+ wxChar const *ptr;
+
+ if(longName) {
+ ptr = longName;
+ while(*ptr) {
+ if(*ptr == DK3_WX_CHAR_SEP) {
+ back = ptr;
+ }
+ ptr++;
+ }
+ if(back) { back++; }
+ else { back = longName; }
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/DkWxBmepsThread.h b/support/dktools/DkWxBmepsThread.h
new file mode 100644
index 0000000000..19e6e9e27c
--- /dev/null
+++ b/support/dktools/DkWxBmepsThread.h
@@ -0,0 +1,163 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxBmepsThread.cpt
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxBmepsThread.h Header file for the DkWxBmepsThread module.
+*/
+
+#ifndef DKWXBMEPSTHREAD_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DKWXBMEPSTHREAD_H_INCLUDED 1
+
+
+#line 9 "DkWxBmepsThread.cpt"
+
+
+/** Worker thread for wxbmeps.
+*/
+class DkWxBmepsThread : public wxThread
+{
+ protected:
+
+ /** Conversion options.
+ */
+ dk3_bm_eps_options_t bmeo;
+
+ /** Communication object to communicate with main thread.
+ */
+ DkWxCommunicator *pComm;
+
+ /** Localized messages, wxChar strings.
+ */
+ wxChar const * const *sTexts;
+
+ /** Localized messages, dkChar strings.
+ */
+ dkChar const * const *msg;
+
+ /** Directory or file name.
+ */
+ wxChar const *sDirectory;
+
+ /** Application helper.
+ */
+ DkWxAppHelper *pHelper;
+
+ /** Encoding for wxChar strings.
+ */
+ int wxenc;
+
+ /** Encoding for dkChar strings.
+ */
+ int dkenc;
+
+ public:
+
+ /** Constructor.
+ @param pc Communication object.
+ @param st Localized messages, wxChar strings.
+ @param m Localized messages, dkChar strings.
+ @param sd Directory or file name.
+ @param ph Application helper.
+ @param wxe Encoding for wxChar strings.
+ @param dke Encoding for dkChar strings.
+ @param bmeoptr Conversion options.
+ */
+ DkWxBmepsThread(
+ DkWxCommunicator *pc,
+ wxChar const * const *st,
+ dkChar const * const *m,
+ wxChar const *sd,
+ DkWxAppHelper *ph,
+ int wxe,
+ int dke,
+ dk3_bm_eps_options_t *bmeoptr
+ );
+
+ /** Destructor.
+ */
+ ~DkWxBmepsThread();
+
+ /** Check setup (memory allocations succeeded).
+ @return Test result, true on success, false on error.
+ */
+ bool
+ checkSetup();
+
+ /** Thread function.
+ @return A pointer which is ignored.
+ */
+ virtual
+ void *
+ Entry();
+
+ /** Function executed at end of thread, does nothing.
+ */
+ virtual
+ void
+ OnExit();
+
+ /** Run for one file.
+ @param fn File name.
+ @param ming Minimum value for progress bar.
+ @param maxg Maximum value for progress bar.
+ */
+ void
+ runForFile(wxChar const *fn, int ming, int maxg);
+
+ /** Run for one directory.
+ @param dn Directory name.
+ */
+ void
+ runForDirectory(wxChar const *dn);
+
+ /** Check whether we must run for a file.
+ @param sfn Source file name.
+ @return true for must run, false for not necessary.
+ */
+ bool
+ checkMustRun(wxChar const *sfn);
+
+ /** Get short file name.
+ @param longName Full file name.
+ @return Pointer to short file name on success, NULL on error.
+ */
+ wxChar const *
+ shortFileName(wxChar const *longName);
+};
+
+
+
+
+#endif
diff --git a/support/dktools/DkWxBufferedControl.cpp b/support/dktools/DkWxBufferedControl.cpp
new file mode 100644
index 0000000000..b13c94bfb9
--- /dev/null
+++ b/support/dktools/DkWxBufferedControl.cpp
@@ -0,0 +1,342 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxBufferedControl.cpt
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxBufferedControl.cpp The DkWxBufferedControl module.
+*/
+
+
+#line 188 "DkWxBufferedControl.cpt"
+
+
+
+#include "DkWxBufferedControl.h"
+
+
+
+
+#line 195 "DkWxBufferedControl.cpt"
+
+
+
+wxChar const DkWxBufferedControl::DkWxBufferedControlName[] = {
+ wxT("DkWxBufferedControl")
+};
+
+
+IMPLEMENT_DYNAMIC_CLASS(DkWxBufferedControl, wxControl)
+
+BEGIN_EVENT_TABLE(DkWxBufferedControl,wxControl)
+ EVT_ERASE_BACKGROUND(DkWxBufferedControl::OnErase)
+ EVT_PAINT(DkWxBufferedControl::OnPaint)
+END_EVENT_TABLE()
+
+
+
+DkWxBufferedControl::DkWxBufferedControl()
+{
+
+
+#line 215 "DkWxBufferedControl.cpt"
+ pBitmap = NULL;
+ iWidth = -1;
+ iHeight = -1;
+ bMustDraw = true;
+ SetBackgroundStyle(wxBG_STYLE_CUSTOM);
+
+
+#line 221 "DkWxBufferedControl.cpt"
+}
+
+
+
+bool
+DkWxBufferedControl::Create(
+ wxWindow *pParent,
+ wxWindowID wid,
+ const wxPoint & pos,
+ const wxSize & size,
+ long style,
+ const wxValidator & validator,
+ wxChar const *name
+)
+{
+ bool back;
+ back = wxControl::Create(
+ pParent, wid, pos, size, style, validator, wxString(name)
+ );
+ pBitmap = NULL;
+ iWidth = -1;
+ iHeight = -1;
+ bMustDraw = true;
+ SetBackgroundStyle(wxBG_STYLE_CUSTOM);
+ return back;
+}
+
+
+
+DkWxBufferedControl::DkWxBufferedControl(
+ wxWindow *pParent,
+ wxWindowID wid,
+ const wxPoint & pos,
+ const wxSize & size,
+ long style,
+ const wxValidator & validator,
+ wxChar const *name
+)
+: wxControl(
+ pParent,
+ wid,
+ pos,
+ size,
+ style,
+ validator,
+ wxString(name)
+)
+{
+
+
+#line 270 "DkWxBufferedControl.cpt"
+ pBitmap = NULL;
+ iWidth = -1;
+ iHeight = -1;
+ bMustDraw = true;
+ SetBackgroundStyle(wxBG_STYLE_CUSTOM);
+
+
+#line 276 "DkWxBufferedControl.cpt"
+}
+
+
+
+DkWxBufferedControl::~DkWxBufferedControl()
+{
+
+
+#line 283 "DkWxBufferedControl.cpt"
+ {
+ wxMutexLocker lock(mxProtectData);
+ if(NULL != pBitmap) {
+
+#line 286 "DkWxBufferedControl.cpt"
+ delete(pBitmap);
+ pBitmap = NULL;
+ }
+ iWidth = -1;
+ iHeight = -1;
+ bMustDraw = false;
+ }
+
+
+#line 294 "DkWxBufferedControl.cpt"
+}
+
+
+
+void
+DkWxBufferedControl::OnErase(wxEraseEvent & event)
+{
+
+
+#line 302 "DkWxBufferedControl.cpt"
+ /* Do nothing here. */
+
+
+#line 304 "DkWxBufferedControl.cpt"
+}
+
+
+
+void
+DkWxBufferedControl::OnPaint(wxPaintEvent & event)
+{
+ bool mustdraw = false;
+ bool done = false;
+ int w = 0;
+ int h = 0;
+
+
+#line 316 "DkWxBufferedControl.cpt"
+ wxPaintDC paintDC(this);
+ {
+ wxMutexLocker lock(mxProtectData);
+#if VERSION_BEFORE_20150821
+ w = iWidth;
+ h = iHeight;
+#endif
+ wxSize sz = GetClientSize();
+ if(NULL != pBitmap) {
+ if((iWidth != sz.x) || (iHeight != sz.y)) {
+ delete(pBitmap);
+
+#line 327 "DkWxBufferedControl.cpt"
+ pBitmap = NULL;
+ mustdraw = true;
+
+#line 329 "DkWxBufferedControl.cpt"
+ }
+ }
+ w = iWidth = sz.x; h = iHeight = sz.y;
+ if(NULL == pBitmap) {
+
+#line 333 "DkWxBufferedControl.cpt"
+ pBitmap = new wxBitmap(iWidth, iHeight);
+ mustdraw = true;
+
+#line 335 "DkWxBufferedControl.cpt"
+ }
+ if(NULL != pBitmap) {
+
+#line 337 "DkWxBufferedControl.cpt"
+ if(false == mustdraw) {
+ if(bMustDraw) {
+
+#line 339 "DkWxBufferedControl.cpt"
+ mustdraw = true;
+ }
+ }
+ if(mustdraw) {
+
+#line 343 "DkWxBufferedControl.cpt"
+ wxMemoryDC memDC;
+ memDC.SelectObject(*pBitmap);
+ InternalPaint(memDC, event, true, w, h);
+ memDC.SelectObject(wxNullBitmap);
+ bMustDraw = false;
+
+#line 348 "DkWxBufferedControl.cpt"
+ } else {
+
+#line 349 "DkWxBufferedControl.cpt"
+ }
+ paintDC.DrawBitmap(*pBitmap, 0, 0, false);
+ done = true;
+ }
+ }
+ if(!(done)) {
+
+#line 355 "DkWxBufferedControl.cpt"
+ InternalPaint(paintDC, event, false, w, h);
+ }
+
+#line 357 "DkWxBufferedControl.cpt"
+}
+
+
+
+void
+DkWxBufferedControl::PaintOperation(
+ wxDC & pdc,
+ wxPaintEvent & event,
+ bool buffered,
+ int clWidth,
+ int clHeight
+)
+{
+ /* The default implementation intentionally does nothing. */
+}
+
+
+
+void
+DkWxBufferedControl::InternalPaint(
+ wxDC & pdc,
+ wxPaintEvent & event,
+ bool buffered,
+ int clWidth,
+ int clHeight
+)
+{
+ wxBrush const br = pdc.GetBrush();
+ wxBrush const bg = pdc.GetBackground();
+ wxFont const fn = pdc.GetFont();
+ wxPen const pn = pdc.GetPen();
+ wxColour const tbg = pdc.GetTextBackground();
+ wxColour const tfg = pdc.GetTextForeground();
+ int bgm = pdc.GetBackgroundMode();
+
+
+#line 392 "DkWxBufferedControl.cpt"
+ PaintOperation(pdc, event, buffered, clWidth, clHeight);
+
+ pdc.SetBackgroundMode(bgm);
+ pdc.SetTextForeground(tfg);
+ pdc.SetTextBackground(tbg);
+ pdc.SetPen(pn);
+ pdc.SetFont(fn);
+ pdc.SetBackground(bg);
+ pdc.SetBrush(br);
+
+
+#line 402 "DkWxBufferedControl.cpt"
+}
+
+
+
+void
+DkWxBufferedControl::SetMustUpdate(bool flag)
+{
+
+
+#line 410 "DkWxBufferedControl.cpt"
+ {
+ wxMutexLocker lock(mxProtectData);
+ bMustDraw = flag;
+ }
+
+
+#line 415 "DkWxBufferedControl.cpt"
+}
+
+
+
+void
+DkWxBufferedControl::releaseBuffer(void)
+{
+
+
+#line 423 "DkWxBufferedControl.cpt"
+ {
+ wxMutexLocker lock(mxProtectData);
+ if(pBitmap) {
+
+#line 426 "DkWxBufferedControl.cpt"
+ delete(pBitmap);
+ pBitmap = NULL;
+ }
+ }
+
+#line 430 "DkWxBufferedControl.cpt"
+}
+
diff --git a/support/dktools/DkWxBufferedControl.cpt b/support/dktools/DkWxBufferedControl.cpt
new file mode 100644
index 0000000000..3b78151c5b
--- /dev/null
+++ b/support/dktools/DkWxBufferedControl.cpt
@@ -0,0 +1,431 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2013-xxxx
+license = bsd
+
+%% header
+
+#include <dk3all.h>
+
+#include <wx/wxprec.h>
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#include <wx/wx.h>
+#endif
+
+/** This is a base class for triple-buffered views.
+ Like double-buffering we write the windows contents
+ to an image and finally transfer the entire image
+ to the device context.
+ Additionally we keep the image between the paint events
+ and rebuild the image only if necessary (data to show
+ has changed).
+
+ When the frame containing your view becomes invisible
+ (frame iconized or hidden) you should use the releaseBuffer()
+ method to decrease the memory footprint of the program.
+
+ In your derived class, call the DkWxBufferedControl constructors from
+ the constructors.
+ From Create() call DkWxBufferedControl::Create().
+
+ You should also use DECLARE_DYNAMIC_CLASS() and
+ IMPLEMENT_DYNAMIC_CLASS().
+*/
+class DkWxBufferedControl : public wxControl
+{
+ private:
+
+ /** Avoid simultaneous access from multiple threads.
+ */
+ wxMutex mxProtectData;
+
+ /** Bitmap for buffered drawing operations.
+ */
+ wxBitmap *pBitmap;
+
+ /** Flag: Must redraw.
+ */
+ bool bMustDraw;
+
+ /** Bitmap width, window width.
+ */
+ int iWidth;
+
+ /** Bitmap height, window height.
+ */
+ int iHeight;
+
+ /** For RTTI.
+ */
+ DECLARE_DYNAMIC_CLASS(DkWxBufferedControl)
+
+ /** Event table.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ static wxChar const DkWxBufferedControlName[];
+
+ /** Internal method to paint.
+ This method saves some DC attributes and restores them
+ before returning.
+ @param pdc Device context to draw to.
+ @param event Paint event to process.
+ @param buffered Flag: Operating on a memory DC.
+ @param clWidth Client area width.
+ @param clHeight Client area height.
+ */
+ void InternalPaint(
+ wxDC & pdc,
+ wxPaintEvent & event,
+ bool buffered,
+ int clWidth,
+ int clHeight
+ );
+
+ public:
+
+ /** Default constructor.
+ */
+ DkWxBufferedControl();
+
+ /** Constructor.
+ @param pParent Parent window.
+ @param wid Window ID
+ @param pos Window position.
+ @param size Window size.
+ @param style Window style.
+ @param validator Validator for control.
+ @param name Window type name.
+ */
+ DkWxBufferedControl(
+ wxWindow *pParent,
+ wxWindowID wid = wxID_ANY,
+ const wxPoint & pos = wxDefaultPosition,
+ const wxSize & size = wxDefaultSize,
+ long style = 0L,
+ const wxValidator & validator = wxDefaultValidator,
+ wxChar const *name = DkWxBufferedControlName
+ );
+
+ /** Create after using the default constructor.
+ @param pParent Parent window.
+ @param wid Window ID
+ @param pos Window position.
+ @param size Window size.
+ @param style Window style.
+ @param validator Validator for control.
+ @param name Window type name.
+ */
+ bool
+ Create(
+ wxWindow *pParent,
+ wxWindowID wid = wxID_ANY,
+ const wxPoint & pos = wxDefaultPosition,
+ const wxSize & size = wxDefaultSize,
+ long style = 0L,
+ const wxValidator & validator = wxDefaultValidator,
+ const wxChar *name = DkWxBufferedControlName
+ );
+
+ /** Destructor.
+ */
+ ~DkWxBufferedControl();
+
+ /** Indicate that data has changed so on next
+ paint we must rebuild the bitmap.
+ @param flag: Flag to turn bMustDraw on or off.
+ */
+ void
+ SetMustUpdate(bool flag = true);
+
+ /** Release bitmap buffer. This function should be called
+ when the frame or dialog containing this view is iconized
+ or hidden.
+ */
+ void
+ releaseBuffer(void);
+
+ /** Handler for erase background event.
+ @param event Event to process.
+ */
+ void
+ OnErase(wxEraseEvent & event);
+
+ /** Handler for paint event.
+ @param event Event to process.
+ */
+ void
+ OnPaint(wxPaintEvent & event);
+
+ /** Overwrite this method to do the real drawing.
+ @param pdc Device context to draw to.
+ Normally a memory dc, but may be a direct
+ dc in special situations (failed to allocate
+ bitmap).
+ @param event Paint event to process.
+ @param buffered Flag: Operating on a memory DC.
+ @param clWidth Client area width.
+ @param clHeight Client area height.
+ */
+ virtual
+ void PaintOperation(
+ wxDC & pdc,
+ wxPaintEvent & event,
+ bool buffered,
+ int clWidth,
+ int clHeight
+ );
+
+};
+
+%% module
+
+
+
+#include "DkWxBufferedControl.h"
+
+
+$!trace-include
+
+
+
+wxChar const DkWxBufferedControl::DkWxBufferedControlName[] = {
+ wxT("DkWxBufferedControl")
+};
+
+
+IMPLEMENT_DYNAMIC_CLASS(DkWxBufferedControl, wxControl)
+
+BEGIN_EVENT_TABLE(DkWxBufferedControl,wxControl)
+ EVT_ERASE_BACKGROUND(DkWxBufferedControl::OnErase)
+ EVT_PAINT(DkWxBufferedControl::OnPaint)
+END_EVENT_TABLE()
+
+
+
+DkWxBufferedControl::DkWxBufferedControl()
+{
+ $? "+ DkWxBufferedControl::DkWxBufferedControl"
+ pBitmap = NULL;
+ iWidth = -1;
+ iHeight = -1;
+ bMustDraw = true;
+ SetBackgroundStyle(wxBG_STYLE_CUSTOM);
+ $? "- DkWxBufferedControl::DkWxBufferedControl"
+}
+
+
+
+bool
+DkWxBufferedControl::Create(
+ wxWindow *pParent,
+ wxWindowID wid,
+ const wxPoint & pos,
+ const wxSize & size,
+ long style,
+ const wxValidator & validator,
+ wxChar const *name
+)
+{
+ bool back;
+ back = wxControl::Create(
+ pParent, wid, pos, size, style, validator, wxString(name)
+ );
+ pBitmap = NULL;
+ iWidth = -1;
+ iHeight = -1;
+ bMustDraw = true;
+ SetBackgroundStyle(wxBG_STYLE_CUSTOM);
+ return back;
+}
+
+
+
+DkWxBufferedControl::DkWxBufferedControl(
+ wxWindow *pParent,
+ wxWindowID wid,
+ const wxPoint & pos,
+ const wxSize & size,
+ long style,
+ const wxValidator & validator,
+ wxChar const *name
+)
+: wxControl(
+ pParent,
+ wid,
+ pos,
+ size,
+ style,
+ validator,
+ wxString(name)
+)
+{
+ $? "+ DkWxBufferedControl::DkWxBufferedControl"
+ pBitmap = NULL;
+ iWidth = -1;
+ iHeight = -1;
+ bMustDraw = true;
+ SetBackgroundStyle(wxBG_STYLE_CUSTOM);
+ $? "- DkWxBufferedControl::DkWxBufferedControl"
+}
+
+
+
+DkWxBufferedControl::~DkWxBufferedControl()
+{
+ $? "+ DkWxBufferedControl::~DkWxBufferedControl"
+ {
+ wxMutexLocker lock(mxProtectData);
+ if(NULL != pBitmap) { $? ". delete bitmap buffer (destructor)"
+ delete(pBitmap);
+ pBitmap = NULL;
+ }
+ iWidth = -1;
+ iHeight = -1;
+ bMustDraw = false;
+ }
+ $? "- DkWxBufferedControl::~DkWxBufferedControl"
+}
+
+
+
+void
+DkWxBufferedControl::OnErase(wxEraseEvent & event)
+{
+ $? "+ DkWxBufferedControl::OnErase"
+ /* Do nothing here. */
+ $? "- DkWxBufferedControl::OnErase"
+}
+
+
+
+void
+DkWxBufferedControl::OnPaint(wxPaintEvent & event)
+{
+ bool mustdraw = false;
+ bool done = false;
+ int w = 0;
+ int h = 0;
+ $? "+ DkWxBufferedControl::OnPaint"
+ wxPaintDC paintDC(this);
+ {
+ wxMutexLocker lock(mxProtectData);
+#if VERSION_BEFORE_20150821
+ w = iWidth;
+ h = iHeight;
+#endif
+ wxSize sz = GetClientSize();
+ if(NULL != pBitmap) {
+ if((iWidth != sz.x) || (iHeight != sz.y)) {
+ delete(pBitmap); $? ". delete bitmap buffer (size)"
+ pBitmap = NULL;
+ mustdraw = true; $? ". bitmap size mismatch"
+ }
+ }
+ w = iWidth = sz.x; h = iHeight = sz.y;
+ if(NULL == pBitmap) { $? ". allocate bitmap buffer"
+ pBitmap = new wxBitmap(iWidth, iHeight);
+ mustdraw = true; $? ". new bitmap PTR=%d", TR_IPTR(pBitmap)
+ }
+ if(NULL != pBitmap) { $? ". have bitmap"
+ if(false == mustdraw) {
+ if(bMustDraw) { $? ". must redraw, requested"
+ mustdraw = true;
+ }
+ }
+ if(mustdraw) { $? ". must redraw, use bitmap"
+ wxMemoryDC memDC;
+ memDC.SelectObject(*pBitmap);
+ InternalPaint(memDC, event, true, w, h);
+ memDC.SelectObject(wxNullBitmap);
+ bMustDraw = false; $? ". result saved in bitmap"
+ } else { $? ". simply use existing bitmap"
+ }
+ paintDC.DrawBitmap(*pBitmap, 0, 0, false);
+ done = true;
+ }
+ }
+ if(!(done)) { $? ". paint unbuffered"
+ InternalPaint(paintDC, event, false, w, h);
+ } $? "- DkWxBufferedControl::OnPaint"
+}
+
+
+
+void
+DkWxBufferedControl::PaintOperation(
+ wxDC & pdc,
+ wxPaintEvent & event,
+ bool buffered,
+ int clWidth,
+ int clHeight
+)
+{
+ /* The default implementation intentionally does nothing. */
+}
+
+
+
+void
+DkWxBufferedControl::InternalPaint(
+ wxDC & pdc,
+ wxPaintEvent & event,
+ bool buffered,
+ int clWidth,
+ int clHeight
+)
+{
+ wxBrush const br = pdc.GetBrush();
+ wxBrush const bg = pdc.GetBackground();
+ wxFont const fn = pdc.GetFont();
+ wxPen const pn = pdc.GetPen();
+ wxColour const tbg = pdc.GetTextBackground();
+ wxColour const tfg = pdc.GetTextForeground();
+ int bgm = pdc.GetBackgroundMode();
+ $? "+ DkWxBufferedControl::InternalPaint"
+ PaintOperation(pdc, event, buffered, clWidth, clHeight);
+
+ pdc.SetBackgroundMode(bgm);
+ pdc.SetTextForeground(tfg);
+ pdc.SetTextBackground(tbg);
+ pdc.SetPen(pn);
+ pdc.SetFont(fn);
+ pdc.SetBackground(bg);
+ pdc.SetBrush(br);
+ $? "- DkWxBufferedControl::InternalPaint"
+}
+
+
+
+void
+DkWxBufferedControl::SetMustUpdate(bool flag)
+{
+ $? "+ DkWxBufferedControl::SetMustUpdate"
+ {
+ wxMutexLocker lock(mxProtectData);
+ bMustDraw = flag;
+ }
+ $? "- DkWxBufferedControl::SetMustUpdate"
+}
+
+
+
+void
+DkWxBufferedControl::releaseBuffer(void)
+{
+ $? "+ DkWxBufferedControl::releaseBuffer"
+ {
+ wxMutexLocker lock(mxProtectData);
+ if(pBitmap) { $? ". delete bitmap buffer (explicit release)"
+ delete(pBitmap);
+ pBitmap = NULL;
+ }
+ } $? "- DkWxBufferedControl::releaseBuffer"
+}
+
diff --git a/support/dktools/DkWxBufferedControl.h b/support/dktools/DkWxBufferedControl.h
new file mode 100644
index 0000000000..1886135ac0
--- /dev/null
+++ b/support/dktools/DkWxBufferedControl.h
@@ -0,0 +1,225 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxBufferedControl.cpt
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxBufferedControl.h Header file for the DkWxBufferedControl module.
+*/
+
+#ifndef DKWXBUFFEREDCONTROL_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DKWXBUFFEREDCONTROL_H_INCLUDED 1
+
+
+#line 8 "DkWxBufferedControl.cpt"
+
+#include <dk3all.h>
+
+#include <wx/wxprec.h>
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#include <wx/wx.h>
+#endif
+
+/** This is a base class for triple-buffered views.
+ Like double-buffering we write the windows contents
+ to an image and finally transfer the entire image
+ to the device context.
+ Additionally we keep the image between the paint events
+ and rebuild the image only if necessary (data to show
+ has changed).
+
+ When the frame containing your view becomes invisible
+ (frame iconized or hidden) you should use the releaseBuffer()
+ method to decrease the memory footprint of the program.
+
+ In your derived class, call the DkWxBufferedControl constructors from
+ the constructors.
+ From Create() call DkWxBufferedControl::Create().
+
+ You should also use DECLARE_DYNAMIC_CLASS() and
+ IMPLEMENT_DYNAMIC_CLASS().
+*/
+class DkWxBufferedControl : public wxControl
+{
+ private:
+
+ /** Avoid simultaneous access from multiple threads.
+ */
+ wxMutex mxProtectData;
+
+ /** Bitmap for buffered drawing operations.
+ */
+ wxBitmap *pBitmap;
+
+ /** Flag: Must redraw.
+ */
+ bool bMustDraw;
+
+ /** Bitmap width, window width.
+ */
+ int iWidth;
+
+ /** Bitmap height, window height.
+ */
+ int iHeight;
+
+ /** For RTTI.
+ */
+ DECLARE_DYNAMIC_CLASS(DkWxBufferedControl)
+
+ /** Event table.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ static wxChar const DkWxBufferedControlName[];
+
+ /** Internal method to paint.
+ This method saves some DC attributes and restores them
+ before returning.
+ @param pdc Device context to draw to.
+ @param event Paint event to process.
+ @param buffered Flag: Operating on a memory DC.
+ @param clWidth Client area width.
+ @param clHeight Client area height.
+ */
+ void InternalPaint(
+ wxDC & pdc,
+ wxPaintEvent & event,
+ bool buffered,
+ int clWidth,
+ int clHeight
+ );
+
+ public:
+
+ /** Default constructor.
+ */
+ DkWxBufferedControl();
+
+ /** Constructor.
+ @param pParent Parent window.
+ @param wid Window ID
+ @param pos Window position.
+ @param size Window size.
+ @param style Window style.
+ @param validator Validator for control.
+ @param name Window type name.
+ */
+ DkWxBufferedControl(
+ wxWindow *pParent,
+ wxWindowID wid = wxID_ANY,
+ const wxPoint & pos = wxDefaultPosition,
+ const wxSize & size = wxDefaultSize,
+ long style = 0L,
+ const wxValidator & validator = wxDefaultValidator,
+ wxChar const *name = DkWxBufferedControlName
+ );
+
+ /** Create after using the default constructor.
+ @param pParent Parent window.
+ @param wid Window ID
+ @param pos Window position.
+ @param size Window size.
+ @param style Window style.
+ @param validator Validator for control.
+ @param name Window type name.
+ */
+ bool
+ Create(
+ wxWindow *pParent,
+ wxWindowID wid = wxID_ANY,
+ const wxPoint & pos = wxDefaultPosition,
+ const wxSize & size = wxDefaultSize,
+ long style = 0L,
+ const wxValidator & validator = wxDefaultValidator,
+ const wxChar *name = DkWxBufferedControlName
+ );
+
+ /** Destructor.
+ */
+ ~DkWxBufferedControl();
+
+ /** Indicate that data has changed so on next
+ paint we must rebuild the bitmap.
+ @param flag: Flag to turn bMustDraw on or off.
+ */
+ void
+ SetMustUpdate(bool flag = true);
+
+ /** Release bitmap buffer. This function should be called
+ when the frame or dialog containing this view is iconized
+ or hidden.
+ */
+ void
+ releaseBuffer(void);
+
+ /** Handler for erase background event.
+ @param event Event to process.
+ */
+ void
+ OnErase(wxEraseEvent & event);
+
+ /** Handler for paint event.
+ @param event Event to process.
+ */
+ void
+ OnPaint(wxPaintEvent & event);
+
+ /** Overwrite this method to do the real drawing.
+ @param pdc Device context to draw to.
+ Normally a memory dc, but may be a direct
+ dc in special situations (failed to allocate
+ bitmap).
+ @param event Paint event to process.
+ @param buffered Flag: Operating on a memory DC.
+ @param clWidth Client area width.
+ @param clHeight Client area height.
+ */
+ virtual
+ void PaintOperation(
+ wxDC & pdc,
+ wxPaintEvent & event,
+ bool buffered,
+ int clWidth,
+ int clHeight
+ );
+
+};
+
+
+#endif
diff --git a/support/dktools/DkWxColorView.cpp b/support/dktools/DkWxColorView.cpp
new file mode 100644
index 0000000000..0d5fd18b6a
--- /dev/null
+++ b/support/dktools/DkWxColorView.cpp
@@ -0,0 +1,247 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxColorView.cpt
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxColorView.cpp The DkWxColorView module.
+*/
+
+
+#line 187 "DkWxColorView.cpt"
+
+#include "DkWxColorView.h"
+
+#include <wx/dcbuffer.h>
+#include <wx/colordlg.h>
+
+
+
+
+
+#line 196 "DkWxColorView.cpt"
+
+
+
+BEGIN_EVENT_TABLE(DkWxColorView, wxControl)
+ EVT_ERASE_BACKGROUND(DkWxColorView::OnErase)
+ EVT_PAINT(DkWxColorView::OnPaint)
+ EVT_LEFT_DOWN(DkWxColorView::OnLeftMouseButtonDown)
+END_EVENT_TABLE()
+
+IMPLEMENT_DYNAMIC_CLASS(DkWxColorView, wxControl)
+
+
+
+
+wxChar const DkWxColorView::DkWxColorViewName[] = { wxT("DkWxColorView") } ;
+
+
+
+DkWxColorView::DkWxColorView()
+{
+ pParentWindow = NULL;
+ pHelper = NULL;
+ w = -1;
+ h = -1;
+ r = 255;
+ g = 255;
+ b = 255;
+ ccdx = -1;
+ ccdy = -1;
+}
+
+
+
+DkWxColorView::DkWxColorView(
+ wxWindow *pParent,
+ wxWindowID wxid,
+ DkWxAppHelper *appHelper,
+ int red,
+ int green,
+ int blue,
+ wxPoint const & pos,
+ wxSize const & size,
+ long style,
+ wxChar const *name
+)
+: wxControl(
+ pParent, wxid, pos, size, style, wxDefaultValidator,
+ wxString(name)
+)
+{
+ pParentWindow = pParent;
+ pHelper = appHelper;
+ w = size.x;
+ h = size.y;
+ r = red;
+ g = green;
+ b = blue;
+ ccdx = -1;
+ ccdy = -1;
+}
+
+
+
+bool
+DkWxColorView::Create(
+ wxWindow *pParent,
+ wxWindowID wxid,
+ DkWxAppHelper *appHelper,
+ int red,
+ int green,
+ int blue,
+ wxPoint const & pos,
+ wxSize const & size,
+ long style,
+ wxChar const *name
+)
+{
+ bool back;
+ back = wxControl::Create(
+ pParent, wxid, pos, size, style, wxDefaultValidator,
+ wxString(name)
+ );
+ pParentWindow = pParent;
+ pHelper = appHelper;
+ w = size.x;
+ h = size.y;
+ r = red;
+ g = green;
+ b = blue;
+ return back;
+}
+
+
+
+wxSize
+DkWxColorView::DoGetBestSize() const
+{
+ wxSize back(((-1 < w) ? w : 20), ((-1 < h) ? h : 20));
+ return back;
+}
+
+
+
+void
+DkWxColorView::OnErase(wxEraseEvent & event)
+{
+}
+
+
+
+void
+DkWxColorView::OnPaint(wxPaintEvent & event)
+{
+ wxBufferedPaintDC useDC(this);
+ wxSize sz = GetClientSize();
+ wxColour mycolor(r, g, b);
+ wxBrush myBrush(mycolor, wxSOLID);
+ const wxBrush oldBrush = useDC.GetBrush();
+ useDC.SetBrush(myBrush);
+ useDC.DrawRectangle(0, 0, sz.GetWidth(), sz.GetHeight());
+ useDC.SetBrush(wxNullBrush);
+}
+
+
+
+void
+DkWxColorView::OnLeftMouseButtonDown(wxMouseEvent & event)
+{
+
+
+#line 325 "DkWxColorView.cpt"
+ wxColourDialog dlg(this);
+ if(pParentWindow) {
+ if(pHelper) {
+
+#line 328 "DkWxColorView.cpt"
+ pHelper->setRelatedPosition(pParentWindow, &dlg, &ccdx, &ccdy);
+ }
+ }
+ if(dlg.ShowModal() == wxID_OK) {
+ wxColour col = dlg.GetColourData().GetColour();
+ r = col.Red();
+ g = col.Green();
+ b = col.Blue();
+ dlg.GetPosition(&ccdx, &ccdy);
+ Refresh();
+ Update();
+ } else {
+ dlg.GetPosition(&ccdx, &ccdy);
+ }
+
+
+#line 343 "DkWxColorView.cpt"
+}
+
+
+
+int
+DkWxColorView::getRed() const
+{
+ return r;
+}
+
+
+
+
+int
+DkWxColorView::getGreen() const
+{
+ return g;
+}
+
+
+
+int
+DkWxColorView::getBlue() const
+{
+ return b;
+}
+
+
+
+void
+DkWxColorView::setRGB(int red, int green, int blue)
+{
+ r = red;
+ g = green;
+ b = blue;
+ if(r < 0) r = 0;
+ if(g < 0) g = 0;
+ if(b < 0) b = 0;
+ if(r > 255) r = 255;
+ if(g > 255) g = 255;
+ if(b > 255) b = 255;
+}
+
diff --git a/support/dktools/DkWxColorView.cpt b/support/dktools/DkWxColorView.cpt
new file mode 100644
index 0000000000..7f575a4a9d
--- /dev/null
+++ b/support/dktools/DkWxColorView.cpt
@@ -0,0 +1,385 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+%% header
+
+#include <dk3all.h>
+
+#include <wx/wxprec.h>
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#include <wx/wx.h>
+#endif
+
+#include <DkWxAppHelper.h>
+
+
+/** Show color setting, show colour chooser on mouse click.
+*/
+class DkWxColorView : public wxControl
+{
+
+ /** Declare class as dynamic.
+ */
+ DECLARE_DYNAMIC_CLASS(DkWxColorView)
+
+ /** Event table for control.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ /** Parent window.
+ */
+ wxWindow *pParentWindow;
+
+ /** Application helper, used to position color chooser dialog.
+ */
+ DkWxAppHelper *pHelper;
+
+ /** Class name, used in constructor and Create().
+ */
+ static wxChar const DkWxColorViewName[];
+
+ /** Height.
+ */
+ int w;
+
+ /** Width.
+ */
+ int h;
+
+ /** Red component of color to show.
+ */
+ int r;
+
+ /** Green component of color to show.
+ */
+ int g;
+
+ /** Blue component of color to show.
+ */
+ int b;
+
+ /** Previous x position of color chooser dialog.
+ */
+ int ccdx;
+
+ /** Previous y position of color chooser dialog.
+ */
+ int ccdy;
+
+ public:
+
+ /** Default constructor.
+ */
+ DkWxColorView();
+
+ /** Constructor.
+ @param pParent Parent window.
+ @param wxid Window ID.
+ @param appHelper Application helper.
+ @param red Red component of color to show.
+ @param green Green component of color to show.
+ @param blue Blue component of color to show.
+ @param pos Object position.
+ @param size Object minimum size.
+ @param style Style for control.
+ @param name Class name.
+ */
+ DkWxColorView(
+ wxWindow *pParent,
+ wxWindowID wxid,
+ DkWxAppHelper *appHelper,
+ int red,
+ int green,
+ int blue,
+ wxPoint const & pos = wxDefaultPosition,
+ wxSize const & size = wxDefaultSize,
+ long style = wxBORDER_NONE,
+ wxChar const *name = DkWxColorViewName
+ );
+
+ /** Create object after using default constructor.
+ @param pParent Parent window.
+ @param wxid Window ID.
+ @param appHelper Application helper.
+ @param red Red component of color to show.
+ @param green Green component of color to show.
+ @param blue Blue component of color to show.
+ @param pos Object position.
+ @param size Object minimum size.
+ @param style Style for control.
+ @param name Class name.
+ @return true on success, false on error.
+ */
+ bool
+ Create(
+ wxWindow *pParent,
+ wxWindowID wxid,
+ DkWxAppHelper *appHelper,
+ int red = 255,
+ int green = 255,
+ int blue = 255,
+ wxPoint const & pos = wxDefaultPosition,
+ wxSize const & size = wxDefaultSize,
+ long style = wxBORDER_NONE,
+ wxChar const *name = DkWxColorViewName
+ );
+
+ /** Find minimum size.
+ */
+ wxSize DoGetBestSize() const;
+
+ /** Get red component of current color.
+ @return Red.
+ */
+ int
+ getRed() const;
+
+ /** Get green component of current color.
+ @return Green.
+ */
+ int
+ getGreen() const;
+
+ /** Get blue component of current color.
+ @return Blue.
+ */
+ int
+ getBlue() const;
+
+ /** Set new current color.
+ @param red Red.
+ @param green Green.
+ @param blue Blue.
+ */
+ void
+ setRGB(int red, int green, int blue);
+
+ /** Handler for erase event.
+ @param event Event to process.
+ */
+ void
+ OnErase(wxEraseEvent & event);
+
+ /** Handler for paint event.
+ @param event Event to process.
+ */
+ void
+ OnPaint(wxPaintEvent & event);
+
+ /** Handler for mouse click event.
+ @param event Event to process.
+ */
+ void
+ OnLeftMouseButtonDown(wxMouseEvent & event);
+
+};
+
+%% module
+
+#include "DkWxColorView.h"
+
+#include <wx/dcbuffer.h>
+#include <wx/colordlg.h>
+
+
+
+$!trace-include
+
+
+
+BEGIN_EVENT_TABLE(DkWxColorView, wxControl)
+ EVT_ERASE_BACKGROUND(DkWxColorView::OnErase)
+ EVT_PAINT(DkWxColorView::OnPaint)
+ EVT_LEFT_DOWN(DkWxColorView::OnLeftMouseButtonDown)
+END_EVENT_TABLE()
+
+IMPLEMENT_DYNAMIC_CLASS(DkWxColorView, wxControl)
+
+
+
+
+wxChar const DkWxColorView::DkWxColorViewName[] = { wxT("DkWxColorView") } ;
+
+
+
+DkWxColorView::DkWxColorView()
+{
+ pParentWindow = NULL;
+ pHelper = NULL;
+ w = -1;
+ h = -1;
+ r = 255;
+ g = 255;
+ b = 255;
+ ccdx = -1;
+ ccdy = -1;
+}
+
+
+
+DkWxColorView::DkWxColorView(
+ wxWindow *pParent,
+ wxWindowID wxid,
+ DkWxAppHelper *appHelper,
+ int red,
+ int green,
+ int blue,
+ wxPoint const & pos,
+ wxSize const & size,
+ long style,
+ wxChar const *name
+)
+: wxControl(
+ pParent, wxid, pos, size, style, wxDefaultValidator,
+ wxString(name)
+)
+{
+ pParentWindow = pParent;
+ pHelper = appHelper;
+ w = size.x;
+ h = size.y;
+ r = red;
+ g = green;
+ b = blue;
+ ccdx = -1;
+ ccdy = -1;
+}
+
+
+
+bool
+DkWxColorView::Create(
+ wxWindow *pParent,
+ wxWindowID wxid,
+ DkWxAppHelper *appHelper,
+ int red,
+ int green,
+ int blue,
+ wxPoint const & pos,
+ wxSize const & size,
+ long style,
+ wxChar const *name
+)
+{
+ bool back;
+ back = wxControl::Create(
+ pParent, wxid, pos, size, style, wxDefaultValidator,
+ wxString(name)
+ );
+ pParentWindow = pParent;
+ pHelper = appHelper;
+ w = size.x;
+ h = size.y;
+ r = red;
+ g = green;
+ b = blue;
+ return back;
+}
+
+
+
+wxSize
+DkWxColorView::DoGetBestSize() const
+{
+ wxSize back(((-1 < w) ? w : 20), ((-1 < h) ? h : 20));
+ return back;
+}
+
+
+
+void
+DkWxColorView::OnErase(wxEraseEvent & event)
+{
+}
+
+
+
+void
+DkWxColorView::OnPaint(wxPaintEvent & event)
+{
+ wxBufferedPaintDC useDC(this);
+ wxSize sz = GetClientSize();
+ wxColour mycolor(r, g, b);
+ wxBrush myBrush(mycolor, wxSOLID);
+ const wxBrush oldBrush = useDC.GetBrush();
+ useDC.SetBrush(myBrush);
+ useDC.DrawRectangle(0, 0, sz.GetWidth(), sz.GetHeight());
+ useDC.SetBrush(wxNullBrush);
+}
+
+
+
+void
+DkWxColorView::OnLeftMouseButtonDown(wxMouseEvent & event)
+{
+ $? "+ DkWxColorView::OnLeftMouseButtonDown"
+ wxColourDialog dlg(this);
+ if(pParentWindow) {
+ if(pHelper) { $? ". pParent pHelper %d %d", ccdx, ccdy
+ pHelper->setRelatedPosition(pParentWindow, &dlg, &ccdx, &ccdy);
+ }
+ }
+ if(dlg.ShowModal() == wxID_OK) {
+ wxColour col = dlg.GetColourData().GetColour();
+ r = col.Red();
+ g = col.Green();
+ b = col.Blue();
+ dlg.GetPosition(&ccdx, &ccdy);
+ Refresh();
+ Update();
+ } else {
+ dlg.GetPosition(&ccdx, &ccdy);
+ }
+ $? "- DkWxColorView::OnLeftMouseButtonDown"
+}
+
+
+
+int
+DkWxColorView::getRed() const
+{
+ return r;
+}
+
+
+
+
+int
+DkWxColorView::getGreen() const
+{
+ return g;
+}
+
+
+
+int
+DkWxColorView::getBlue() const
+{
+ return b;
+}
+
+
+
+void
+DkWxColorView::setRGB(int red, int green, int blue)
+{
+ r = red;
+ g = green;
+ b = blue;
+ if(r < 0) r = 0;
+ if(g < 0) g = 0;
+ if(b < 0) b = 0;
+ if(r > 255) r = 255;
+ if(g > 255) g = 255;
+ if(b > 255) b = 255;
+}
+
diff --git a/support/dktools/DkWxColorView.h b/support/dktools/DkWxColorView.h
new file mode 100644
index 0000000000..0a8430cc1f
--- /dev/null
+++ b/support/dktools/DkWxColorView.h
@@ -0,0 +1,223 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxColorView.cpt
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxColorView.h Header file for the DkWxColorView module.
+*/
+
+#ifndef DKWXCOLORVIEW_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DKWXCOLORVIEW_H_INCLUDED 1
+
+
+#line 9 "DkWxColorView.cpt"
+
+#include <dk3all.h>
+
+#include <wx/wxprec.h>
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#include <wx/wx.h>
+#endif
+
+#include <DkWxAppHelper.h>
+
+
+/** Show color setting, show colour chooser on mouse click.
+*/
+class DkWxColorView : public wxControl
+{
+
+ /** Declare class as dynamic.
+ */
+ DECLARE_DYNAMIC_CLASS(DkWxColorView)
+
+ /** Event table for control.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ /** Parent window.
+ */
+ wxWindow *pParentWindow;
+
+ /** Application helper, used to position color chooser dialog.
+ */
+ DkWxAppHelper *pHelper;
+
+ /** Class name, used in constructor and Create().
+ */
+ static wxChar const DkWxColorViewName[];
+
+ /** Height.
+ */
+ int w;
+
+ /** Width.
+ */
+ int h;
+
+ /** Red component of color to show.
+ */
+ int r;
+
+ /** Green component of color to show.
+ */
+ int g;
+
+ /** Blue component of color to show.
+ */
+ int b;
+
+ /** Previous x position of color chooser dialog.
+ */
+ int ccdx;
+
+ /** Previous y position of color chooser dialog.
+ */
+ int ccdy;
+
+ public:
+
+ /** Default constructor.
+ */
+ DkWxColorView();
+
+ /** Constructor.
+ @param pParent Parent window.
+ @param wxid Window ID.
+ @param appHelper Application helper.
+ @param red Red component of color to show.
+ @param green Green component of color to show.
+ @param blue Blue component of color to show.
+ @param pos Object position.
+ @param size Object minimum size.
+ @param style Style for control.
+ @param name Class name.
+ */
+ DkWxColorView(
+ wxWindow *pParent,
+ wxWindowID wxid,
+ DkWxAppHelper *appHelper,
+ int red,
+ int green,
+ int blue,
+ wxPoint const & pos = wxDefaultPosition,
+ wxSize const & size = wxDefaultSize,
+ long style = wxBORDER_NONE,
+ wxChar const *name = DkWxColorViewName
+ );
+
+ /** Create object after using default constructor.
+ @param pParent Parent window.
+ @param wxid Window ID.
+ @param appHelper Application helper.
+ @param red Red component of color to show.
+ @param green Green component of color to show.
+ @param blue Blue component of color to show.
+ @param pos Object position.
+ @param size Object minimum size.
+ @param style Style for control.
+ @param name Class name.
+ @return true on success, false on error.
+ */
+ bool
+ Create(
+ wxWindow *pParent,
+ wxWindowID wxid,
+ DkWxAppHelper *appHelper,
+ int red = 255,
+ int green = 255,
+ int blue = 255,
+ wxPoint const & pos = wxDefaultPosition,
+ wxSize const & size = wxDefaultSize,
+ long style = wxBORDER_NONE,
+ wxChar const *name = DkWxColorViewName
+ );
+
+ /** Find minimum size.
+ */
+ wxSize DoGetBestSize() const;
+
+ /** Get red component of current color.
+ @return Red.
+ */
+ int
+ getRed() const;
+
+ /** Get green component of current color.
+ @return Green.
+ */
+ int
+ getGreen() const;
+
+ /** Get blue component of current color.
+ @return Blue.
+ */
+ int
+ getBlue() const;
+
+ /** Set new current color.
+ @param red Red.
+ @param green Green.
+ @param blue Blue.
+ */
+ void
+ setRGB(int red, int green, int blue);
+
+ /** Handler for erase event.
+ @param event Event to process.
+ */
+ void
+ OnErase(wxEraseEvent & event);
+
+ /** Handler for paint event.
+ @param event Event to process.
+ */
+ void
+ OnPaint(wxPaintEvent & event);
+
+ /** Handler for mouse click event.
+ @param event Event to process.
+ */
+ void
+ OnLeftMouseButtonDown(wxMouseEvent & event);
+
+};
+
+
+#endif
diff --git a/support/dktools/DkWxCommunicator.cpp b/support/dktools/DkWxCommunicator.cpp
new file mode 100644
index 0000000000..582f9c5bc2
--- /dev/null
+++ b/support/dktools/DkWxCommunicator.cpp
@@ -0,0 +1,529 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxCommunicator.cpt
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxCommunicator.cpp The DkWxCommunicator module.
+*/
+
+
+#line 271 "DkWxCommunicator.cpt"
+
+
+#include "dk3wxs.h"
+#include <dk3mem.h>
+#include "DkWxCommunicator.h"
+
+
+
+
+#line 279 "DkWxCommunicator.cpt"
+
+
+
+/** Empty text to use if no file name is specified.
+*/
+static wxChar const dkwx_communicator_empty_text[] = { wxT("") } ;
+
+/** Newline.
+*/
+static wxChar const dkwx_communicator_newline[] = { wxT("\n") } ;
+
+
+DkWxCommunicator::DkWxCommunicator(int we, int de)
+{
+
+
+#line 294 "DkWxCommunicator.cpt"
+ wxe = we;
+ dke = de;
+ iRunning = 0;
+ iAutostart = DK3_WX_AUTOSTART_NORMAL;
+
+#line 298 "DkWxCommunicator.cpt"
+ sMessages = NULL;
+ sFilename = NULL;
+ iGauge = 0;
+ iUpdated = 0;
+ iCanContinue = 1;
+ iLogLevelMax = DK3_LL_IGNORE;
+ sMessages = new wxString(dkwx_communicator_empty_text);
+
+
+#line 306 "DkWxCommunicator.cpt"
+}
+
+
+
+DkWxCommunicator::~DkWxCommunicator()
+{
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ }
+ if(sMessages) {
+ delete sMessages;
+ }
+ if(sFilename) {
+ dk3_release(sFilename);
+ }
+ iRunning = 0;
+ iGauge = 0;
+ iUpdated = 0;
+ iCanContinue = 0;
+}
+
+
+
+int
+DkWxCommunicator::checkSetup() const
+{
+ int back = 0;
+ if(sMessages) {
+ back = 1;
+ }
+ return back;
+}
+
+
+
+int
+DkWxCommunicator::getUpdates(
+ wxWindow *wDialog,
+ wxStaticText *tFilename,
+ wxGauge *gProgress
+)
+{
+ int back = 0;
+ wxCriticalSectionLocker lock(csProtect);
+ if(iUpdated) {
+ back |= DK_WX_COMMUNICATOR_STATUS_UPDATE;
+ if(tFilename) {
+ if(sFilename) {
+ tFilename->SetLabel(sFilename);
+ } else {
+ tFilename->SetLabel(dkwx_communicator_empty_text);
+ }
+ }
+ if(gProgress) {
+ gProgress->SetValue(iGauge);
+ }
+ iUpdated = 0;
+ }
+ if(iRunning) {
+ back |= DK_WX_COMMUNICATOR_STATUS_RUNNING;
+ }
+ return back;
+}
+
+
+
+void
+DkWxCommunicator::internalSetGauge(int newValue)
+{
+ int nv;
+ nv = newValue;
+ if(nv < 0) nv = 0;
+ if(nv > 1000) nv = 1000;
+ if(iRunning) {
+ if(nv == 1000) nv = 999;
+ }
+ if(nv != iGauge) {
+ iGauge = nv;
+ iUpdated = 1;
+ }
+}
+
+
+
+int
+DkWxCommunicator::internalSetFilename(wxChar const *newFileName)
+{
+ int back = 0;
+ if(newFileName) {
+ if(sFilename) {
+ if(dk3wxs_cmp(newFileName, sFilename)) {
+ dk3_release(sFilename);
+ sFilename = dk3wxs_dup(newFileName);
+ if(sFilename) {
+ back = 1;
+ }
+ iUpdated = 1;
+ } else {
+ back = 1;
+ }
+ } else {
+ sFilename = dk3wxs_dup(newFileName);
+ if(sFilename) {
+ iUpdated = 1;
+ back = 1;
+ }
+ }
+ } else {
+ if(sFilename) {
+ dk3_release(sFilename);
+ sFilename = NULL;
+ iUpdated = 1;
+ }
+ back = 1;
+ }
+ return back;
+}
+
+
+
+int
+DkWxCommunicator::setUpdates(wxChar const *fn, int nv)
+{
+ int back = 0;
+ wxCriticalSectionLocker lock(csProtect);
+ if(internalSetFilename(fn)) { back = 1; }
+ internalSetGauge(nv);
+ return back;
+}
+
+
+
+void
+DkWxCommunicator::updateGauge(int nv)
+{
+ wxCriticalSectionLocker lock(csProtect);
+ internalSetGauge(nv);
+}
+
+
+
+void
+DkWxCommunicator::prepareRun()
+{
+ wxCriticalSectionLocker lock(csProtect);
+ internalSetFilename(NULL);
+ internalSetGauge(0);
+ iRunning = 1;
+ iCanContinue = 1;
+ sMessages->Empty();
+ iUpdated = 1;
+ iLogLevelMax = DK3_LL_IGNORE;
+}
+
+
+
+void
+DkWxCommunicator::setCanContinue(int nv)
+{
+ wxCriticalSectionLocker lock(csProtect);
+ iCanContinue = nv;
+}
+
+
+
+int
+DkWxCommunicator::getCanContinue()
+{
+ int back = 0;
+ wxCriticalSectionLocker lock(csProtect);
+ back = iCanContinue;
+ return back;
+}
+
+
+
+void
+DkWxCommunicator::setRunning(int nv)
+{
+
+
+#line 486 "DkWxCommunicator.cpt"
+ wxCriticalSectionLocker lock(csProtect);
+ /*
+ Set new value.
+ */
+ iRunning = nv;
+ /*
+ If we are no longer running we have finished
+ the autostart job.
+ */
+ if(nv == 0) {
+
+#line 496 "DkWxCommunicator.cpt"
+ if(iAutostart == DK3_WX_AUTOSTART_RUNNING) {
+
+#line 497 "DkWxCommunicator.cpt"
+ iAutostart = DK3_WX_AUTOSTART_FINISHED;
+
+#line 498 "DkWxCommunicator.cpt"
+ }
+ }
+
+#line 500 "DkWxCommunicator.cpt"
+}
+
+
+
+int
+DkWxCommunicator::getRunning()
+{
+ int back = 1;
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ back = iRunning;
+ }
+ return back;
+}
+
+
+
+void
+DkWxCommunicator::getText( wxTextCtrl *tc)
+{
+ wxCriticalSectionLocker lock(csProtect);
+ if(tc) {
+ if(sMessages) {
+ tc->ChangeValue(*sMessages);
+ }
+ }
+}
+
+
+
+void
+DkWxCommunicator::addWxText(wxChar const *t)
+{
+
+
+#line 534 "DkWxCommunicator.cpt"
+ if(sMessages) {
+
+#line 535 "DkWxCommunicator.cpt"
+ if(t) {
+
+#line 536 "DkWxCommunicator.cpt"
+ wxCriticalSectionLocker lock(csProtect);
+
+
+#line 538 "DkWxCommunicator.cpt"
+ sMessages->Append(t);
+
+
+#line 540 "DkWxCommunicator.cpt"
+ }
+ }
+
+#line 542 "DkWxCommunicator.cpt"
+}
+
+
+
+void
+DkWxCommunicator::addDkText(dkChar const *t)
+{
+ wxChar bu[2 * DK3_MAX_PATH];
+
+ if(sMessages) {
+ if(t) {
+ if(dk3wxs_from_dkstr(bu, DK3_SIZEOF(bu,wxChar), wxe, t, dke)) {
+ wxCriticalSectionLocker lock(csProtect);
+ sMessages->Append(bu);
+ }
+ }
+ }
+}
+
+
+
+void
+DkWxCommunicator::addCharText(char const *t)
+{
+ wxChar bu[2 * DK3_MAX_PATH];
+
+ if(sMessages) {
+ if(t) {
+ if(dk3wxs_from_plain(bu, DK3_SIZEOF(bu,wxChar), t)) {
+ wxCriticalSectionLocker lock(csProtect);
+ sMessages->Append(bu);
+ }
+ }
+ }
+}
+
+
+void
+DkWxCommunicator::nl()
+{
+ if(sMessages) {
+ wxCriticalSectionLocker lock(csProtect);
+ sMessages->Append(dkwx_communicator_newline);
+ }
+}
+
+
+
+int
+DkWxCommunicator::autostartCanRun()
+{
+ int back = 0;
+
+
+#line 595 "DkWxCommunicator.cpt"
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ if(iAutostart == DK3_WX_AUTOSTART_START) {
+
+#line 598 "DkWxCommunicator.cpt"
+ iAutostart = DK3_WX_AUTOSTART_RUNNING;
+
+#line 599 "DkWxCommunicator.cpt"
+ back = 1;
+ }
+ }
+
+#line 602 "DkWxCommunicator.cpt"
+ return back;
+}
+
+
+
+void
+DkWxCommunicator::autostartSetFinished()
+{
+
+
+#line 611 "DkWxCommunicator.cpt"
+ wxCriticalSectionLocker lock(csProtect);
+ if(iAutostart == DK3_WX_AUTOSTART_RUNNING) {
+ iAutostart = DK3_WX_AUTOSTART_FINISHED;
+
+#line 614 "DkWxCommunicator.cpt"
+ }
+
+#line 615 "DkWxCommunicator.cpt"
+}
+
+
+
+int
+DkWxCommunicator::autostartIsFinished()
+{
+ int back = 0;
+
+
+#line 624 "DkWxCommunicator.cpt"
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ if(iAutostart == DK3_WX_AUTOSTART_FINISHED) {
+ iAutostart = DK3_WX_AUTOSTART_WAIT_FOR_EXIT;
+
+#line 628 "DkWxCommunicator.cpt"
+ back = 1;
+ }
+ }
+
+#line 631 "DkWxCommunicator.cpt"
+ return back;
+}
+
+
+
+int
+DkWxCommunicator::autostartGet()
+{
+ int back;
+
+
+#line 641 "DkWxCommunicator.cpt"
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ back = iAutostart;
+ }
+
+#line 645 "DkWxCommunicator.cpt"
+ return back;
+}
+
+
+
+void
+DkWxCommunicator::autostartEnable(bool nv)
+{
+
+
+#line 654 "DkWxCommunicator.cpt"
+ wxCriticalSectionLocker lock(csProtect);
+ if(nv) {
+ iAutostart = DK3_WX_AUTOSTART_START;
+
+#line 657 "DkWxCommunicator.cpt"
+ } else {
+ iAutostart = DK3_WX_AUTOSTART_NORMAL;
+
+#line 659 "DkWxCommunicator.cpt"
+ }
+
+#line 660 "DkWxCommunicator.cpt"
+}
+
+
+void
+DkWxCommunicator::setLogLevel(int nv)
+{
+ wxCriticalSectionLocker lock(csProtect);
+ if(nv < iLogLevelMax) {
+ iLogLevelMax = nv;
+ }
+}
+
+
+
+int
+DkWxCommunicator::getLogLevel()
+{
+ int back = DK3_LL_IGNORE;
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ back = iLogLevelMax;
+ }
+ return back;
+}
+
+
+
+wxString
+DkWxCommunicator::getText()
+{
+ wxString back(wxT(""));
+ if(sMessages) {
+ back = *sMessages;
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/DkWxCommunicator.cpt b/support/dktools/DkWxCommunicator.cpt
new file mode 100644
index 0000000000..d5efa83382
--- /dev/null
+++ b/support/dktools/DkWxCommunicator.cpt
@@ -0,0 +1,697 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% header
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED 1
+#endif
+#endif
+
+/** Synchronized communication between a worker thread and a
+ progress dialog (ie DkWxProgressDialog).
+*/
+class DkWxCommunicator
+{
+ protected:
+
+ /** Grant access to only one thread at a time to other members.
+ */
+ wxCriticalSection csProtect;
+
+ /** Flag: Thread is still running.
+ */
+ int iRunning;
+
+ /** Autostart state.
+ */
+ int iAutostart;
+
+ /** Flag: Worker thread can continue.
+ */
+ int iCanContinue;
+
+ /** String containing all the messages produced by worker thread.
+ */
+ wxString *sMessages;
+
+ /** Current file name processed.
+ */
+ wxChar *sFilename;
+
+ /** Current gauge value (0-1000).
+ */
+ int iGauge;
+
+ /** Flag: Update required.
+ */
+ int iUpdated;
+
+ /** Encoding for wxChar.
+ */
+ int wxe;
+
+ /** Encoding for dkChar.
+ */
+ int dke;
+
+ /** Most significant log level.
+ */
+ int iLogLevelMax;
+
+ /** Change file name, set iUpdated if new file name differs from
+ previous one.
+ @param newFileName New file name.
+ @return 1 on success (new file name saved), 0 on error.
+ */
+ int
+ internalSetFilename(wxChar const *newFileName);
+
+ /** Change gauge value, set iUpdated if new value differs
+ from previous one.
+ @param newValue New gauge value.
+ */
+ void
+ internalSetGauge(int newValue);
+
+ public:
+
+ /** Constructor.
+ @param we Encoding used for wxChar strings.
+ @param de Encoding used for dkChar strings.
+ */
+ DkWxCommunicator(int we, int de);
+
+ /** Destructor.
+ */
+ ~DkWxCommunicator();
+
+ /** Check whether the object has set up correctly and is ready to use.
+ @return 1 if setup is ok, 0 for error.
+ */
+ int
+ checkSetup() const;
+
+ /** Update GUI elements.
+ @param wDialog Progress dialog.
+ @param tFilename Static text to show file name.
+ @param gProgress Progress bar.
+ @return Or-combination of DK_WX_COMMUNICATOR_STATUS_RUNNING
+ and DK_WX_COMMUNICATOR_STATUS_UPDATE.
+ If the thread is no longer running, you can close the progress
+ dialog. If there was an update to file name or progress bar
+ value you need to call Refresh() and Update().
+ */
+ int
+ getUpdates(
+ wxWindow *wDialog,
+ wxStaticText *tFilename,
+ wxGauge *gProgress
+ );
+
+ /** Set new file name and gauge value, may be used by a worker thread.
+ @param fn New file name.
+ @param nv New gauge value.
+ @return 1 on success, 0 on error.
+ */
+ int
+ setUpdates(wxChar const *fn, int nv);
+
+ /** Update gauge value only, leave file name untouched.
+ @param nv New gauge value.
+ */
+ void
+ updateGauge(int nv);
+
+ /** Set text to text control.
+ @param tc Text control to use for log messages from
+ worker thread.
+ */
+ void
+ getText(
+ wxTextCtrl *tc
+ );
+
+ /** Prepare to run a worker thread.
+ */
+ void
+ prepareRun();
+
+ /** Set can-continue flag.
+ @param nv New flag value (1=can continue, 0=must stop).
+ Set to 0 if a "Cancel" button was pressed in the
+ progress dialog.
+ */
+ void
+ setCanContinue(int nv);
+
+ /** Get can-continue flag, used by the worker thread to react
+ on "Cancel" button.
+ @return 1 on success (can continue), 0 on error (cancel button pressed).
+ */
+ int
+ getCanContinue();
+
+ /** Set iRunning.
+ A worker thread uses setRunning(0) to inidicate it is finished.
+ @param nv New iRunning value.
+ */
+ void
+ setRunning(int nv);
+
+ /** Check whether the thread is still running.
+ @return 1 for thread still running, 0 for thread finished.
+ */
+ int
+ getRunning();
+
+ /** Enable/disable autostart job.
+ @param nv New autostart flag.
+ */
+ void
+ autostartEnable(bool nv = true);
+
+ /** Check whether we can run an autostart job.
+ On success we change the internal autostart variable to indicate
+ that an autostart job is currently running.
+ @return 1 to run autostart job, 0 otherwise.
+ */
+ int
+ autostartCanRun();
+
+ /** Mark autostart job as finished. This is typically invoked
+ at the end of the autostart worker thread.
+ */
+ void
+ autostartSetFinished();
+
+ /** Check whether the autostart job is completed so we can close the
+ window.
+ @return 1 to close the window, 0 otherwise.
+ */
+ int
+ autostartIsFinished();
+
+ /** Add text to log messages string.
+ @param t Text to add.
+ */
+ void
+ addWxText(wxChar const *t);
+
+ /** Add text to log messages string.
+ @param t Text to add.
+ */
+ void
+ addDkText(dkChar const * t);
+
+ /** Add text to log messages string.
+ @param t Text to add.
+ */
+ void
+ addCharText(char const *t);
+
+ /** Add newline to log messages string.
+ */
+ void
+ nl();
+
+ /** Set most significant log level.
+ @param nv Log level occured.
+ */
+ void
+ setLogLevel(int nv);
+
+ /** Retrieve most significant log level.
+ @return Log level.
+ */
+ int
+ getLogLevel();
+
+ /** Retrieve autostart information.
+ @return Current iAutostart value.
+ */
+ int
+ autostartGet();
+
+ /** Get current messages text.
+ @return Current text stored.
+ */
+ wxString getText();
+};
+
+
+
+/** Status: Thread is still running.
+*/
+#define DK_WX_COMMUNICATOR_STATUS_RUNNING 1
+
+/** Status: Thread updated data since last request.
+*/
+#define DK_WX_COMMUNICATOR_STATUS_UPDATE 2
+
+%% module
+
+
+#include "dk3wxs.h"
+#include <dk3mem.h>
+#include "DkWxCommunicator.h"
+
+
+$!trace-include
+
+
+
+/** Empty text to use if no file name is specified.
+*/
+static wxChar const dkwx_communicator_empty_text[] = { wxT("") } ;
+
+/** Newline.
+*/
+static wxChar const dkwx_communicator_newline[] = { wxT("\n") } ;
+
+
+DkWxCommunicator::DkWxCommunicator(int we, int de)
+{
+ $? "+ DkWxCommunicator::DkWxCommunicator"
+ wxe = we;
+ dke = de;
+ iRunning = 0;
+ iAutostart = DK3_WX_AUTOSTART_NORMAL; $? ". normal start %d", iAutostart
+ sMessages = NULL;
+ sFilename = NULL;
+ iGauge = 0;
+ iUpdated = 0;
+ iCanContinue = 1;
+ iLogLevelMax = DK3_LL_IGNORE;
+ sMessages = new wxString(dkwx_communicator_empty_text);
+ $? "- DkWxCommunicator::DkWxCommunicator"
+}
+
+
+
+DkWxCommunicator::~DkWxCommunicator()
+{
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ }
+ if(sMessages) {
+ delete sMessages;
+ }
+ if(sFilename) {
+ dk3_release(sFilename);
+ }
+ iRunning = 0;
+ iGauge = 0;
+ iUpdated = 0;
+ iCanContinue = 0;
+}
+
+
+
+int
+DkWxCommunicator::checkSetup() const
+{
+ int back = 0;
+ if(sMessages) {
+ back = 1;
+ }
+ return back;
+}
+
+
+
+int
+DkWxCommunicator::getUpdates(
+ wxWindow *wDialog,
+ wxStaticText *tFilename,
+ wxGauge *gProgress
+)
+{
+ int back = 0;
+ wxCriticalSectionLocker lock(csProtect);
+ if(iUpdated) {
+ back |= DK_WX_COMMUNICATOR_STATUS_UPDATE;
+ if(tFilename) {
+ if(sFilename) {
+ tFilename->SetLabel(sFilename);
+ } else {
+ tFilename->SetLabel(dkwx_communicator_empty_text);
+ }
+ }
+ if(gProgress) {
+ gProgress->SetValue(iGauge);
+ }
+ iUpdated = 0;
+ }
+ if(iRunning) {
+ back |= DK_WX_COMMUNICATOR_STATUS_RUNNING;
+ }
+ return back;
+}
+
+
+
+void
+DkWxCommunicator::internalSetGauge(int newValue)
+{
+ int nv;
+ nv = newValue;
+ if(nv < 0) nv = 0;
+ if(nv > 1000) nv = 1000;
+ if(iRunning) {
+ if(nv == 1000) nv = 999;
+ }
+ if(nv != iGauge) {
+ iGauge = nv;
+ iUpdated = 1;
+ }
+}
+
+
+
+int
+DkWxCommunicator::internalSetFilename(wxChar const *newFileName)
+{
+ int back = 0;
+ if(newFileName) {
+ if(sFilename) {
+ if(dk3wxs_cmp(newFileName, sFilename)) {
+ dk3_release(sFilename);
+ sFilename = dk3wxs_dup(newFileName);
+ if(sFilename) {
+ back = 1;
+ }
+ iUpdated = 1;
+ } else {
+ back = 1;
+ }
+ } else {
+ sFilename = dk3wxs_dup(newFileName);
+ if(sFilename) {
+ iUpdated = 1;
+ back = 1;
+ }
+ }
+ } else {
+ if(sFilename) {
+ dk3_release(sFilename);
+ sFilename = NULL;
+ iUpdated = 1;
+ }
+ back = 1;
+ }
+ return back;
+}
+
+
+
+int
+DkWxCommunicator::setUpdates(wxChar const *fn, int nv)
+{
+ int back = 0;
+ wxCriticalSectionLocker lock(csProtect);
+ if(internalSetFilename(fn)) { back = 1; }
+ internalSetGauge(nv);
+ return back;
+}
+
+
+
+void
+DkWxCommunicator::updateGauge(int nv)
+{
+ wxCriticalSectionLocker lock(csProtect);
+ internalSetGauge(nv);
+}
+
+
+
+void
+DkWxCommunicator::prepareRun()
+{
+ wxCriticalSectionLocker lock(csProtect);
+ internalSetFilename(NULL);
+ internalSetGauge(0);
+ iRunning = 1;
+ iCanContinue = 1;
+ sMessages->Empty();
+ iUpdated = 1;
+ iLogLevelMax = DK3_LL_IGNORE;
+}
+
+
+
+void
+DkWxCommunicator::setCanContinue(int nv)
+{
+ wxCriticalSectionLocker lock(csProtect);
+ iCanContinue = nv;
+}
+
+
+
+int
+DkWxCommunicator::getCanContinue()
+{
+ int back = 0;
+ wxCriticalSectionLocker lock(csProtect);
+ back = iCanContinue;
+ return back;
+}
+
+
+
+void
+DkWxCommunicator::setRunning(int nv)
+{
+ $? "+ DkWxCommunicator::setRunning %d", nv
+ wxCriticalSectionLocker lock(csProtect);
+ /*
+ Set new value.
+ */
+ iRunning = nv;
+ /*
+ If we are no longer running we have finished
+ the autostart job.
+ */
+ if(nv == 0) { $? ". no longer running"
+ if(iAutostart == DK3_WX_AUTOSTART_RUNNING) { $? ". was autostart"
+ iAutostart = DK3_WX_AUTOSTART_FINISHED; $? ". autostart finished %d", iAutostart
+ }
+ } $? "- DkWxCommunicator::setRunning"
+}
+
+
+
+int
+DkWxCommunicator::getRunning()
+{
+ int back = 1;
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ back = iRunning;
+ }
+ return back;
+}
+
+
+
+void
+DkWxCommunicator::getText( wxTextCtrl *tc)
+{
+ wxCriticalSectionLocker lock(csProtect);
+ if(tc) {
+ if(sMessages) {
+ tc->ChangeValue(*sMessages);
+ }
+ }
+}
+
+
+
+void
+DkWxCommunicator::addWxText(wxChar const *t)
+{
+ $? "+ addWxText \"%ls\"", t
+ if(sMessages) { $? ". sMessages ok"
+ if(t) { $? ". t ok"
+ wxCriticalSectionLocker lock(csProtect);
+ $? ". before Append"
+ sMessages->Append(t);
+ $? ". after Append"
+ }
+ } $? "- addWxText"
+}
+
+
+
+void
+DkWxCommunicator::addDkText(dkChar const *t)
+{
+ wxChar bu[2 * DK3_MAX_PATH];
+
+ if(sMessages) {
+ if(t) {
+ if(dk3wxs_from_dkstr(bu, DK3_SIZEOF(bu,wxChar), wxe, t, dke)) {
+ wxCriticalSectionLocker lock(csProtect);
+ sMessages->Append(bu);
+ }
+ }
+ }
+}
+
+
+
+void
+DkWxCommunicator::addCharText(char const *t)
+{
+ wxChar bu[2 * DK3_MAX_PATH];
+
+ if(sMessages) {
+ if(t) {
+ if(dk3wxs_from_plain(bu, DK3_SIZEOF(bu,wxChar), t)) {
+ wxCriticalSectionLocker lock(csProtect);
+ sMessages->Append(bu);
+ }
+ }
+ }
+}
+
+
+void
+DkWxCommunicator::nl()
+{
+ if(sMessages) {
+ wxCriticalSectionLocker lock(csProtect);
+ sMessages->Append(dkwx_communicator_newline);
+ }
+}
+
+
+
+int
+DkWxCommunicator::autostartCanRun()
+{
+ int back = 0;
+ $? "+ DkWxCommunicator::autostartCanRun"
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ if(iAutostart == DK3_WX_AUTOSTART_START) { $? ". autostart wanted"
+ iAutostart = DK3_WX_AUTOSTART_RUNNING; $? ". autostart running %d", iAutostart
+ back = 1;
+ }
+ } $? "- DkWxCommunicator::autostartCanRun %d", back
+ return back;
+}
+
+
+
+void
+DkWxCommunicator::autostartSetFinished()
+{
+ $? "+ DkWxCommunicator::autostartSetFinished"
+ wxCriticalSectionLocker lock(csProtect);
+ if(iAutostart == DK3_WX_AUTOSTART_RUNNING) {
+ iAutostart = DK3_WX_AUTOSTART_FINISHED; $? ". autostart finished %d", iAutostart
+ } $? "- DkWxCommunicator::autostartSetFinished"
+}
+
+
+
+int
+DkWxCommunicator::autostartIsFinished()
+{
+ int back = 0;
+ $? "+ DkWxCommunicator::autostartIsFinished"
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ if(iAutostart == DK3_WX_AUTOSTART_FINISHED) {
+ iAutostart = DK3_WX_AUTOSTART_WAIT_FOR_EXIT; $? ". autostart waiting for exit %d", iAutostart
+ back = 1;
+ }
+ } $? "- DkWxCommunicator::autostartIsFinished %d", back
+ return back;
+}
+
+
+
+int
+DkWxCommunicator::autostartGet()
+{
+ int back;
+ $? "+ DkWxCommunicator::autostartGet"
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ back = iAutostart;
+ } $? "- DkWxCommunicator::autostartGet %d", back
+ return back;
+}
+
+
+
+void
+DkWxCommunicator::autostartEnable(bool nv)
+{
+ $? "+ DkWxCommunicator::autostartEnable %d", ((nv) ? 1 : 0)
+ wxCriticalSectionLocker lock(csProtect);
+ if(nv) {
+ iAutostart = DK3_WX_AUTOSTART_START; $? ". autostart enabled %d", iAutostart
+ } else {
+ iAutostart = DK3_WX_AUTOSTART_NORMAL; $? ". autostart disabled %d", iAutostart
+ } $? "- DkWxCommunicator::autostartEnable"
+}
+
+
+void
+DkWxCommunicator::setLogLevel(int nv)
+{
+ wxCriticalSectionLocker lock(csProtect);
+ if(nv < iLogLevelMax) {
+ iLogLevelMax = nv;
+ }
+}
+
+
+
+int
+DkWxCommunicator::getLogLevel()
+{
+ int back = DK3_LL_IGNORE;
+ {
+ wxCriticalSectionLocker lock(csProtect);
+ back = iLogLevelMax;
+ }
+ return back;
+}
+
+
+
+wxString
+DkWxCommunicator::getText()
+{
+ wxString back(wxT(""));
+ if(sMessages) {
+ back = *sMessages;
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/DkWxCommunicator.h b/support/dktools/DkWxCommunicator.h
new file mode 100644
index 0000000000..e21319fc41
--- /dev/null
+++ b/support/dktools/DkWxCommunicator.h
@@ -0,0 +1,306 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxCommunicator.cpt
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxCommunicator.h Header file for the DkWxCommunicator module.
+*/
+
+#ifndef DKWXCOMMUNICATOR_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DKWXCOMMUNICATOR_H_INCLUDED 1
+
+
+#line 10 "DkWxCommunicator.cpt"
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED 1
+#endif
+#endif
+
+/** Synchronized communication between a worker thread and a
+ progress dialog (ie DkWxProgressDialog).
+*/
+class DkWxCommunicator
+{
+ protected:
+
+ /** Grant access to only one thread at a time to other members.
+ */
+ wxCriticalSection csProtect;
+
+ /** Flag: Thread is still running.
+ */
+ int iRunning;
+
+ /** Autostart state.
+ */
+ int iAutostart;
+
+ /** Flag: Worker thread can continue.
+ */
+ int iCanContinue;
+
+ /** String containing all the messages produced by worker thread.
+ */
+ wxString *sMessages;
+
+ /** Current file name processed.
+ */
+ wxChar *sFilename;
+
+ /** Current gauge value (0-1000).
+ */
+ int iGauge;
+
+ /** Flag: Update required.
+ */
+ int iUpdated;
+
+ /** Encoding for wxChar.
+ */
+ int wxe;
+
+ /** Encoding for dkChar.
+ */
+ int dke;
+
+ /** Most significant log level.
+ */
+ int iLogLevelMax;
+
+ /** Change file name, set iUpdated if new file name differs from
+ previous one.
+ @param newFileName New file name.
+ @return 1 on success (new file name saved), 0 on error.
+ */
+ int
+ internalSetFilename(wxChar const *newFileName);
+
+ /** Change gauge value, set iUpdated if new value differs
+ from previous one.
+ @param newValue New gauge value.
+ */
+ void
+ internalSetGauge(int newValue);
+
+ public:
+
+ /** Constructor.
+ @param we Encoding used for wxChar strings.
+ @param de Encoding used for dkChar strings.
+ */
+ DkWxCommunicator(int we, int de);
+
+ /** Destructor.
+ */
+ ~DkWxCommunicator();
+
+ /** Check whether the object has set up correctly and is ready to use.
+ @return 1 if setup is ok, 0 for error.
+ */
+ int
+ checkSetup() const;
+
+ /** Update GUI elements.
+ @param wDialog Progress dialog.
+ @param tFilename Static text to show file name.
+ @param gProgress Progress bar.
+ @return Or-combination of DK_WX_COMMUNICATOR_STATUS_RUNNING
+ and DK_WX_COMMUNICATOR_STATUS_UPDATE.
+ If the thread is no longer running, you can close the progress
+ dialog. If there was an update to file name or progress bar
+ value you need to call Refresh() and Update().
+ */
+ int
+ getUpdates(
+ wxWindow *wDialog,
+ wxStaticText *tFilename,
+ wxGauge *gProgress
+ );
+
+ /** Set new file name and gauge value, may be used by a worker thread.
+ @param fn New file name.
+ @param nv New gauge value.
+ @return 1 on success, 0 on error.
+ */
+ int
+ setUpdates(wxChar const *fn, int nv);
+
+ /** Update gauge value only, leave file name untouched.
+ @param nv New gauge value.
+ */
+ void
+ updateGauge(int nv);
+
+ /** Set text to text control.
+ @param tc Text control to use for log messages from
+ worker thread.
+ */
+ void
+ getText(
+ wxTextCtrl *tc
+ );
+
+ /** Prepare to run a worker thread.
+ */
+ void
+ prepareRun();
+
+ /** Set can-continue flag.
+ @param nv New flag value (1=can continue, 0=must stop).
+ Set to 0 if a "Cancel" button was pressed in the
+ progress dialog.
+ */
+ void
+ setCanContinue(int nv);
+
+ /** Get can-continue flag, used by the worker thread to react
+ on "Cancel" button.
+ @return 1 on success (can continue), 0 on error (cancel button pressed).
+ */
+ int
+ getCanContinue();
+
+ /** Set iRunning.
+ A worker thread uses setRunning(0) to inidicate it is finished.
+ @param nv New iRunning value.
+ */
+ void
+ setRunning(int nv);
+
+ /** Check whether the thread is still running.
+ @return 1 for thread still running, 0 for thread finished.
+ */
+ int
+ getRunning();
+
+ /** Enable/disable autostart job.
+ @param nv New autostart flag.
+ */
+ void
+ autostartEnable(bool nv = true);
+
+ /** Check whether we can run an autostart job.
+ On success we change the internal autostart variable to indicate
+ that an autostart job is currently running.
+ @return 1 to run autostart job, 0 otherwise.
+ */
+ int
+ autostartCanRun();
+
+ /** Mark autostart job as finished. This is typically invoked
+ at the end of the autostart worker thread.
+ */
+ void
+ autostartSetFinished();
+
+ /** Check whether the autostart job is completed so we can close the
+ window.
+ @return 1 to close the window, 0 otherwise.
+ */
+ int
+ autostartIsFinished();
+
+ /** Add text to log messages string.
+ @param t Text to add.
+ */
+ void
+ addWxText(wxChar const *t);
+
+ /** Add text to log messages string.
+ @param t Text to add.
+ */
+ void
+ addDkText(dkChar const * t);
+
+ /** Add text to log messages string.
+ @param t Text to add.
+ */
+ void
+ addCharText(char const *t);
+
+ /** Add newline to log messages string.
+ */
+ void
+ nl();
+
+ /** Set most significant log level.
+ @param nv Log level occured.
+ */
+ void
+ setLogLevel(int nv);
+
+ /** Retrieve most significant log level.
+ @return Log level.
+ */
+ int
+ getLogLevel();
+
+ /** Retrieve autostart information.
+ @return Current iAutostart value.
+ */
+ int
+ autostartGet();
+
+ /** Get current messages text.
+ @return Current text stored.
+ */
+ wxString getText();
+};
+
+
+
+/** Status: Thread is still running.
+*/
+#define DK_WX_COMMUNICATOR_STATUS_RUNNING 1
+
+/** Status: Thread updated data since last request.
+*/
+#define DK_WX_COMMUNICATOR_STATUS_UPDATE 2
+
+
+#endif
diff --git a/support/dktools/DkWxDialog.cpp b/support/dktools/DkWxDialog.cpp
new file mode 100644
index 0000000000..84477aef2c
--- /dev/null
+++ b/support/dktools/DkWxDialog.cpp
@@ -0,0 +1,38 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxDialog.cpt
+*/
+
+/** @file DkWxDialog.cpp The DkWxDialog module.
+*/
+
+
+#line 33 "DkWxDialog.cpt"
+
+
+#include "DkWxDialog.h"
+
+
+
+
+
+#line 40 "DkWxDialog.cpt"
+
+
+
+DkWxDialog::DkWxDialog(
+ wxWindow *parent,
+ wxWindowID wid,
+ wxChar const *title
+) : wxDialog(
+ parent,
+ wid,
+ title,
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxDEFAULT_DIALOG_STYLE
+)
+{
+}
diff --git a/support/dktools/DkWxDialog.cpt b/support/dktools/DkWxDialog.cpt
new file mode 100644
index 0000000000..ac097bc337
--- /dev/null
+++ b/support/dktools/DkWxDialog.cpt
@@ -0,0 +1,56 @@
+%% options
+
+%% header
+
+#include <dk3all.h>
+
+#include <wx/wxprec.h>
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#include <wx/wx.h>
+#endif
+
+/** Base class for dialogs.
+*/
+class DkWxDialog : public wxDialog
+{
+ public:
+ /** Constructor.
+ @param parent Parent frame or dialog.
+ @param wid Windows ID.
+ @param title Dialog box title.
+ */
+ DkWxDialog(
+ wxWindow *parent,
+ wxWindowID wid,
+ wxChar const *title
+ );
+};
+
+%% module
+
+
+#include "DkWxDialog.h"
+
+
+
+$!trace-include
+
+
+
+DkWxDialog::DkWxDialog(
+ wxWindow *parent,
+ wxWindowID wid,
+ wxChar const *title
+) : wxDialog(
+ parent,
+ wid,
+ title,
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxDEFAULT_DIALOG_STYLE
+)
+{
+}
diff --git a/support/dktools/DkWxDialog.h b/support/dktools/DkWxDialog.h
new file mode 100644
index 0000000000..f26f3fe79d
--- /dev/null
+++ b/support/dktools/DkWxDialog.h
@@ -0,0 +1,46 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxDialog.cpt
+*/
+
+/** @file DkWxDialog.h Header file for the DkWxDialog module.
+*/
+
+#ifndef DKWXDIALOG_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DKWXDIALOG_H_INCLUDED 1
+
+
+#line 4 "DkWxDialog.cpt"
+
+#include <dk3all.h>
+
+#include <wx/wxprec.h>
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#include <wx/wx.h>
+#endif
+
+/** Base class for dialogs.
+*/
+class DkWxDialog : public wxDialog
+{
+ public:
+ /** Constructor.
+ @param parent Parent frame or dialog.
+ @param wid Windows ID.
+ @param title Dialog box title.
+ */
+ DkWxDialog(
+ wxWindow *parent,
+ wxWindowID wid,
+ wxChar const *title
+ );
+};
+
+
+#endif
diff --git a/support/dktools/DkWxFrame.cpp b/support/dktools/DkWxFrame.cpp
new file mode 100644
index 0000000000..c9f01499c1
--- /dev/null
+++ b/support/dktools/DkWxFrame.cpp
@@ -0,0 +1,422 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxFrame.cpt
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#line 113 "DkWxFrame.cpt"
+
+/** @file DkWxFrame.cpp Implementation of DkWxFrame.
+*/
+
+#include "DkWxFrame.h"
+
+
+
+
+#line 121 "DkWxFrame.cpt"
+
+
+
+int DkWxFrame::iInstances = 0;
+
+
+
+wxChar const * const DkWxFrame::kwSizePos[] = {
+/* 0 */ wxT("window.x"),
+/* 1 */ wxT("window.y"),
+/* 2 */ wxT("window.w"),
+/* 3 */ wxT("window.h"),
+/* 4 */ wxT("window.maximized"),
+/* 5 */ wxT("window.iconized"),
+NULL
+};
+
+
+
+dkChar const * const DkWxFrame::kwRestoreFeatures[] = {
+/* 0 */ dkT("/window/restore-maximized"),
+/* 1 */ dkT("/window/restore-iconized"),
+/* 2 */ dkT("/window/restore-size"),
+NULL
+};
+
+
+
+DkWxFrame::DkWxFrame(
+ wxChar const *applicationName,
+ DkWxAppHelper *applicationHelper,
+ DkWxHelpController *applicationHelp,
+ int wxid
+) : wxFrame(NULL, wxid, applicationName)
+{
+
+
+#line 157 "DkWxFrame.cpt"
+ /*
+ Initialize elements.
+ */
+ pHelper = NULL;
+ helpController = applicationHelp;
+ /*
+ Set elements.
+ */
+ pHelper = applicationHelper;
+ iInstances++;
+ Connect(wxid, wxEVT_CLOSE_WINDOW, wxCloseEventHandler(DkWxFrame::OnClose));
+
+
+#line 169 "DkWxFrame.cpt"
+}
+
+
+
+void DkWxFrame::OnClose(wxCloseEvent & event)
+{
+ bool doClose = true;
+
+
+#line 177 "DkWxFrame.cpt"
+ if(event.CanVeto()) {
+ doClose = canClose(iInstances == 1);
+ } else {
+ canClose(iInstances == 1);
+ }
+ if(doClose) {
+
+#line 183 "DkWxFrame.cpt"
+ /*
+ For last instance save position.
+ */
+ if(iInstances-- == 1) {
+
+#line 187 "DkWxFrame.cpt"
+ savePosition();
+ }
+ /*
+ Process close event.
+ */
+ event.Skip();
+ } else {
+
+#line 194 "DkWxFrame.cpt"
+ /*
+ Do not close the window.
+ */
+ event.Veto();
+ }
+
+#line 199 "DkWxFrame.cpt"
+}
+
+
+
+void
+DkWxFrame::restorePosition()
+{
+ int p[6]; /* Values retrieved from application helper */
+ wxSize scsz; /* Screen size */
+ int x; /* X position */
+ int y; /* Y position */
+ int w; /* Width */
+ int h; /* Height */
+ int rs; /* Flag: Attempt to restore size */
+ p[0] = p[1] = -1;
+ p[2] = p[3] = p[4] = w = h = 0;
+ pHelper->retrieveMultipleInts(kwSizePos, p);
+ if ((0 > p[0]) || (0 > p[1])) {
+ CentreOnScreen();
+ } else {
+ scsz = wxGetDisplaySize();
+ x = p[0];
+ y = p[1];
+ GetSize(&w, &h);
+#if wxCHECK_VERSION(3,0,0)
+ rs = 0;
+#else
+ rs = 1;
+#endif
+ rs = dk3app_get_pref_bool(pHelper->getApp(), kwRestoreFeatures[2], rs);
+ if (0 != rs) {
+ if (p[2] > w) { w = p[2]; }
+ if (p[3] > h) { h = p[3]; }
+ }
+ if ((x + w) >= scsz.GetWidth()) { x = scsz.GetWidth() - w; }
+ if ((y + h) >= scsz.GetHeight()) { y = scsz.GetHeight() - h; }
+ if (0 > x) { x = 0; }
+ if (0 > y) { y = 0; }
+ if (0 != rs) {
+ SetSize(x, y, w, h);
+ } else {
+ SetPosition(wxPoint(x, y));
+ }
+ if (0 != dk3app_get_pref_bool(pHelper->getApp(), kwRestoreFeatures[0], 0))
+ {
+ if (0 != p[4]) {
+ Maximize(true);
+ }
+ }
+ if (0 != dk3app_get_pref_bool(pHelper->getApp(), kwRestoreFeatures[1], 0))
+ {
+ if (0 != p[5]) {
+ Iconize(true);
+ }
+ }
+ }
+}
+
+
+
+#if VERSION_BEFORE_20160902
+void
+DkWxFrame::restorePosition()
+{
+#if 1
+ int p[6];
+ size_t num;
+ int w, h;
+ int restoreFeature;
+
+
+#line 269 "DkWxFrame.cpt"
+ p[0] = p[1] = p[2] = p[3] p[4] = p[5] = w = h = 0;
+ if((num = pHelper->retrieveMultipleInts(kwSizePos, p)) >= 4) {
+
+
+#line 272 "DkWxFrame.cpt"
+
+
+#line 273 "DkWxFrame.cpt"
+
+
+#line 274 "DkWxFrame.cpt"
+
+
+#line 275 "DkWxFrame.cpt"
+
+
+#line 276 "DkWxFrame.cpt"
+
+
+#line 277 "DkWxFrame.cpt"
+
+
+#line 278 "DkWxFrame.cpt"
+ wxSize scsz = wxGetDisplaySize();
+ GetSize(&w, &h);
+
+
+#line 281 "DkWxFrame.cpt"
+
+
+#line 282 "DkWxFrame.cpt"
+
+
+#line 283 "DkWxFrame.cpt"
+ if(w > p[2]) { p[2] = w; }
+ if(h > p[3]) { p[3] = h; }
+
+
+#line 286 "DkWxFrame.cpt"
+
+
+#line 287 "DkWxFrame.cpt"
+#if wxCHECK_VERSION(3,0,0)
+ {
+ wxSize minSize = GetMinSize();
+ if (p[2] < minSize.x) { p[2] = minSize.x; }
+ if (p[3] < minSize.y) { p[3] = minSize.y; }
+ }
+#endif
+ if((p[0] + p[2]) > scsz.GetWidth()) { p[0] = scsz.GetWidth() - p[2]; }
+ if((p[1] + p[3]) > scsz.GetHeight()) { p[1] = scsz.GetHeight() - p[3]; }
+ if(p[0] < 0) { p[0] = 0; }
+ if(p[1] < 0) { p[1] = 0; }
+
+
+#line 299 "DkWxFrame.cpt"
+
+
+#line 300 "DkWxFrame.cpt"
+
+
+#line 301 "DkWxFrame.cpt"
+
+
+#line 302 "DkWxFrame.cpt"
+
+
+#line 303 "DkWxFrame.cpt"
+ /* This variant allows to decrease the frame below the minimum size.
+ */
+#if wxCHECK_VERSION(3,0,0)
+ SetPosition(wxPoint(p[0], p[1]));
+#else
+ SetSize(p[0], p[1], p[2], p[3]);
+#endif
+ restoreFeature = dk3app_get_pref_bool(
+ pHelper->getApp(),
+ kwRestoreFeatures[0],
+ 0
+ );
+ if((restoreFeature) && (4 < num)) {
+ if(0 != p[4]) {
+ Maximize(true);
+ }
+ }
+ restoreFeature = dk3app_get_pref_bool(
+ pHelper->getApp(),
+ kwRestoreFeatures[1],
+ 0
+ );
+ if((restoreFeature) && (5 < num)) {
+ if(0 != p[5]) {
+ Iconize(true);
+ }
+ }
+ } else {
+ CentreOnScreen();
+ }
+
+#line 333 "DkWxFrame.cpt"
+#else
+ int x = 0;
+ int y = 0;
+ int w = 0;
+ int h = 0;
+ wxSize scsz = wxGetDisplaySize();
+ GetPosition(&x, &y);
+ GetSize(&w, &h);
+#endif
+}
+#endif
+/* VERSION_BEFORE_20160902 */
+
+
+
+void
+DkWxFrame::savePosition()
+{
+ int p[6];
+
+
+#line 353 "DkWxFrame.cpt"
+ p[4] = 0;
+ p[5] = 0;
+ if(IsIconized()) {
+ p[5] = 1;
+ Iconize(false);
+ }
+ if(IsMaximized()) {
+ p[4] = 1;
+ Maximize(false);
+ }
+ GetPosition(&(p[0]), &(p[1]));
+ GetSize(&(p[2]), &(p[3]));
+ if(pHelper) {
+
+
+#line 367 "DkWxFrame.cpt"
+
+
+#line 368 "DkWxFrame.cpt"
+
+
+#line 369 "DkWxFrame.cpt"
+
+
+#line 370 "DkWxFrame.cpt"
+ pHelper->saveMultipleInts(kwSizePos, p);
+ }
+
+#line 372 "DkWxFrame.cpt"
+}
+
+
+
+bool
+DkWxFrame::canClose(bool isLast)
+{
+
+
+#line 380 "DkWxFrame.cpt"
+ return true;
+}
+
+
+
+void
+DkWxFrame::openHelp()
+{
+
+
+#line 389 "DkWxFrame.cpt"
+ if(helpController) {
+ helpController->openHelp((wxFrame *)this);
+ }
+
+#line 392 "DkWxFrame.cpt"
+}
+
+
+
+void
+DkWxFrame::openHelpSectionByName(wxString const & name)
+{
+
+
+#line 400 "DkWxFrame.cpt"
+ if (helpController) {
+ helpController->openHelpSectionByName((wxFrame *)this, name);
+ }
+
+
+#line 404 "DkWxFrame.cpt"
+}
+
+
+
+void
+DkWxFrame::openHelpSectionByNumber(int number)
+{
+
+
+#line 412 "DkWxFrame.cpt"
+ if (helpController) {
+ helpController->openHelpSectionByNumber((wxFrame *)this, number);
+ }
+
+
+#line 416 "DkWxFrame.cpt"
+}
+
diff --git a/support/dktools/DkWxFrame.cpt b/support/dktools/DkWxFrame.cpt
new file mode 100644
index 0000000000..329f2d28e3
--- /dev/null
+++ b/support/dktools/DkWxFrame.cpt
@@ -0,0 +1,417 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+%% header
+
+#include <dk3all.h>
+
+#include <wx/wxprec.h>
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#include <wx/wx.h>
+#endif
+
+
+#include "DkWxAppHelper.h"
+#include "DkWxHelpController.h"
+
+
+
+/** Base class for top-level frames. This class keeps pointers to an
+ application helper for file search and localization and a
+ pointer to a help controller object managing online help
+ for both *.chm and *.htb based help.
+
+ Derive your applications frames from this class.
+*/
+class DkWxFrame : public wxFrame
+{
+ private:
+
+ /** Number of windows currently open.
+ */
+ static int iInstances;
+
+ /** Keywords to save and retrieve size and position data.
+ */
+ static wxChar const * const kwSizePos[];
+
+ /** Preference keys whether or not to restore maxizmed and iconized.
+ */
+ static dkChar const * const kwRestoreFeatures[];
+
+ protected:
+
+ /** Helper object for file search and internationalization.
+ */
+ DkWxAppHelper *pHelper;
+
+ /** Help controller for chm and htb based help files.
+ */
+ DkWxHelpController *helpController;
+
+ /** Save current position.
+ */
+ void savePosition();
+
+ public:
+
+ /** Constructor.
+ @param applicationName Application name.
+ @param applicationHelper Helper object.
+ @param applicationHelp Help controller.
+ @param wxid Window ID.
+ */
+ DkWxFrame(
+ wxChar const *applicationName,
+ DkWxAppHelper *applicationHelper,
+ DkWxHelpController *applicationHelp,
+ int wxid
+ );
+
+ /** Restore previous position or center on screen.
+ */
+ void restorePosition();
+
+ /** Handler for close event.
+ @param event Event to process.
+ */
+ void OnClose(wxCloseEvent & event);
+
+ /** Check whether we can close the frame.
+ @param isLast Flag: Last frame instance of application.
+ @return Permission to close.
+ */
+ virtual bool canClose(bool isLast);
+
+ /** Open help system if help controller available.
+ */
+ void openHelp();
+
+ /** Open help section specified by name.
+ @param name Section name.
+ */
+ void
+ openHelpSectionByName(wxString const & name);
+
+ /** Open help section specified by section number.
+ @param number Section number (context ID).
+ */
+ void
+ openHelpSectionByNumber(int number);
+};
+
+
+
+%% module
+
+/** @file DkWxFrame.cpp Implementation of DkWxFrame.
+*/
+
+#include "DkWxFrame.h"
+
+
+$!trace-include
+
+
+
+int DkWxFrame::iInstances = 0;
+
+
+
+wxChar const * const DkWxFrame::kwSizePos[] = {
+/* 0 */ wxT("window.x"),
+/* 1 */ wxT("window.y"),
+/* 2 */ wxT("window.w"),
+/* 3 */ wxT("window.h"),
+/* 4 */ wxT("window.maximized"),
+/* 5 */ wxT("window.iconized"),
+NULL
+};
+
+
+
+dkChar const * const DkWxFrame::kwRestoreFeatures[] = {
+/* 0 */ dkT("/window/restore-maximized"),
+/* 1 */ dkT("/window/restore-iconized"),
+/* 2 */ dkT("/window/restore-size"),
+NULL
+};
+
+
+
+DkWxFrame::DkWxFrame(
+ wxChar const *applicationName,
+ DkWxAppHelper *applicationHelper,
+ DkWxHelpController *applicationHelp,
+ int wxid
+) : wxFrame(NULL, wxid, applicationName)
+{
+ $? "+ DkWxFrame::DkWxFrame"
+ /*
+ Initialize elements.
+ */
+ pHelper = NULL;
+ helpController = applicationHelp;
+ /*
+ Set elements.
+ */
+ pHelper = applicationHelper;
+ iInstances++;
+ Connect(wxid, wxEVT_CLOSE_WINDOW, wxCloseEventHandler(DkWxFrame::OnClose));
+ $? "- DkWxFrame::DkWxFrame"
+}
+
+
+
+void DkWxFrame::OnClose(wxCloseEvent & event)
+{
+ bool doClose = true;
+ $? "+ DkWxFrame::OnClose"
+ if(event.CanVeto()) {
+ doClose = canClose(iInstances == 1);
+ } else {
+ canClose(iInstances == 1);
+ }
+ if(doClose) { $? ". close window"
+ /*
+ For last instance save position.
+ */
+ if(iInstances-- == 1) { $? ". save position"
+ savePosition();
+ }
+ /*
+ Process close event.
+ */
+ event.Skip();
+ } else { $? ". veto event"
+ /*
+ Do not close the window.
+ */
+ event.Veto();
+ } $? "- DkWxFrame::OnClose"
+}
+
+
+
+void
+DkWxFrame::restorePosition()
+{
+ int p[6]; /* Values retrieved from application helper */
+ wxSize scsz; /* Screen size */
+ int x; /* X position */
+ int y; /* Y position */
+ int w; /* Width */
+ int h; /* Height */
+ int rs; /* Flag: Attempt to restore size */
+ p[0] = p[1] = -1;
+ p[2] = p[3] = p[4] = w = h = 0;
+ pHelper->retrieveMultipleInts(kwSizePos, p);
+ if ((0 > p[0]) || (0 > p[1])) {
+ CentreOnScreen();
+ } else {
+ scsz = wxGetDisplaySize();
+ x = p[0];
+ y = p[1];
+ GetSize(&w, &h);
+#if wxCHECK_VERSION(3,0,0)
+ rs = 0;
+#else
+ rs = 1;
+#endif
+ rs = dk3app_get_pref_bool(pHelper->getApp(), kwRestoreFeatures[2], rs);
+ if (0 != rs) {
+ if (p[2] > w) { w = p[2]; }
+ if (p[3] > h) { h = p[3]; }
+ }
+ if ((x + w) >= scsz.GetWidth()) { x = scsz.GetWidth() - w; }
+ if ((y + h) >= scsz.GetHeight()) { y = scsz.GetHeight() - h; }
+ if (0 > x) { x = 0; }
+ if (0 > y) { y = 0; }
+ if (0 != rs) {
+ SetSize(x, y, w, h);
+ } else {
+ SetPosition(wxPoint(x, y));
+ }
+ if (0 != dk3app_get_pref_bool(pHelper->getApp(), kwRestoreFeatures[0], 0))
+ {
+ if (0 != p[4]) {
+ Maximize(true);
+ }
+ }
+ if (0 != dk3app_get_pref_bool(pHelper->getApp(), kwRestoreFeatures[1], 0))
+ {
+ if (0 != p[5]) {
+ Iconize(true);
+ }
+ }
+ }
+}
+
+
+
+#if VERSION_BEFORE_20160902
+void
+DkWxFrame::restorePosition()
+{
+#if 1
+ int p[6];
+ size_t num;
+ int w, h;
+ int restoreFeature;
+ $? "+ DkWxFrame::restorePosition"
+ p[0] = p[1] = p[2] = p[3] p[4] = p[5] = w = h = 0;
+ if((num = pHelper->retrieveMultipleInts(kwSizePos, p)) >= 4) {
+ $? ". saved coordinates"
+ $? ". x = %d", p[0]
+ $? ". y = %d", p[1]
+ $? ". w = %d", p[2]
+ $? ". h = %d", p[3]
+ $? ". m = %d", p[4]
+ $? ". i = %d", p[5]
+ wxSize scsz = wxGetDisplaySize();
+ GetSize(&w, &h);
+ $? ". current coordinates"
+ $? ". w = %d", w
+ $? ". h = %d", h
+ if(w > p[2]) { p[2] = w; }
+ if(h > p[3]) { p[3] = h; }
+ $? ". screen width = %d %d", scsz.GetWidth(), scsz.x
+ $? ". screen height = %d %d", scsz.GetHeight(), scsz.y
+#if wxCHECK_VERSION(3,0,0)
+ {
+ wxSize minSize = GetMinSize();
+ if (p[2] < minSize.x) { p[2] = minSize.x; }
+ if (p[3] < minSize.y) { p[3] = minSize.y; }
+ }
+#endif
+ if((p[0] + p[2]) > scsz.GetWidth()) { p[0] = scsz.GetWidth() - p[2]; }
+ if((p[1] + p[3]) > scsz.GetHeight()) { p[1] = scsz.GetHeight() - p[3]; }
+ if(p[0] < 0) { p[0] = 0; }
+ if(p[1] < 0) { p[1] = 0; }
+ $? ". new coordinates"
+ $? ". x = %d", p[0]
+ $? ". y = %d", p[1]
+ $? ". w = %d", p[2]
+ $? ". h = %d", p[3]
+ /* This variant allows to decrease the frame below the minimum size.
+ */
+#if wxCHECK_VERSION(3,0,0)
+ SetPosition(wxPoint(p[0], p[1]));
+#else
+ SetSize(p[0], p[1], p[2], p[3]);
+#endif
+ restoreFeature = dk3app_get_pref_bool(
+ pHelper->getApp(),
+ kwRestoreFeatures[0],
+ 0
+ );
+ if((restoreFeature) && (4 < num)) {
+ if(0 != p[4]) {
+ Maximize(true);
+ }
+ }
+ restoreFeature = dk3app_get_pref_bool(
+ pHelper->getApp(),
+ kwRestoreFeatures[1],
+ 0
+ );
+ if((restoreFeature) && (5 < num)) {
+ if(0 != p[5]) {
+ Iconize(true);
+ }
+ }
+ } else {
+ CentreOnScreen();
+ } $? "- DkWxFrame::restorePosition"
+#else
+ int x = 0;
+ int y = 0;
+ int w = 0;
+ int h = 0;
+ wxSize scsz = wxGetDisplaySize();
+ GetPosition(&x, &y);
+ GetSize(&w, &h);
+#endif
+}
+#endif
+/* VERSION_BEFORE_20160902 */
+
+
+
+void
+DkWxFrame::savePosition()
+{
+ int p[6];
+ $? "+ DkWxFrame::savePosition"
+ p[4] = 0;
+ p[5] = 0;
+ if(IsIconized()) {
+ p[5] = 1;
+ Iconize(false);
+ }
+ if(IsMaximized()) {
+ p[4] = 1;
+ Maximize(false);
+ }
+ GetPosition(&(p[0]), &(p[1]));
+ GetSize(&(p[2]), &(p[3]));
+ if(pHelper) {
+ $? ". x = %d", p[0]
+ $? ". y = %d", p[1]
+ $? ". w = %d", p[2]
+ $? ". h = %d", p[3]
+ pHelper->saveMultipleInts(kwSizePos, p);
+ } $? "- DkWxFrame::savePosition"
+}
+
+
+
+bool
+DkWxFrame::canClose(bool isLast)
+{
+ $? "= DkWxFrame::canClose 1"
+ return true;
+}
+
+
+
+void
+DkWxFrame::openHelp()
+{
+ $? "+ DkWxFrame::openHelp"
+ if(helpController) {
+ helpController->openHelp((wxFrame *)this);
+ } $? "- DkWxFrame::openHelp"
+}
+
+
+
+void
+DkWxFrame::openHelpSectionByName(wxString const & name)
+{
+ $? "+ DkWxFrame::openHelpSectionByName"
+ if (helpController) {
+ helpController->openHelpSectionByName((wxFrame *)this, name);
+ }
+ $? "- DkWxFrame::openHelpSectionByName"
+}
+
+
+
+void
+DkWxFrame::openHelpSectionByNumber(int number)
+{
+ $? "+ DkWxFrame::openHelpSectionByNumber"
+ if (helpController) {
+ helpController->openHelpSectionByNumber((wxFrame *)this, number);
+ }
+ $? "- DkWxFrame::openHelpSectionByNumber"
+}
+
diff --git a/support/dktools/DkWxFrame.h b/support/dktools/DkWxFrame.h
new file mode 100644
index 0000000000..cb2ee2787f
--- /dev/null
+++ b/support/dktools/DkWxFrame.h
@@ -0,0 +1,149 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxFrame.cpt
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxFrame.h Header file for the DkWxFrame module.
+*/
+
+#ifndef DKWXFRAME_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DKWXFRAME_H_INCLUDED 1
+
+
+#line 9 "DkWxFrame.cpt"
+
+#include <dk3all.h>
+
+#include <wx/wxprec.h>
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#include <wx/wx.h>
+#endif
+
+
+#include "DkWxAppHelper.h"
+#include "DkWxHelpController.h"
+
+
+
+/** Base class for top-level frames. This class keeps pointers to an
+ application helper for file search and localization and a
+ pointer to a help controller object managing online help
+ for both *.chm and *.htb based help.
+
+ Derive your applications frames from this class.
+*/
+class DkWxFrame : public wxFrame
+{
+ private:
+
+ /** Number of windows currently open.
+ */
+ static int iInstances;
+
+ /** Keywords to save and retrieve size and position data.
+ */
+ static wxChar const * const kwSizePos[];
+
+ /** Preference keys whether or not to restore maxizmed and iconized.
+ */
+ static dkChar const * const kwRestoreFeatures[];
+
+ protected:
+
+ /** Helper object for file search and internationalization.
+ */
+ DkWxAppHelper *pHelper;
+
+ /** Help controller for chm and htb based help files.
+ */
+ DkWxHelpController *helpController;
+
+ /** Save current position.
+ */
+ void savePosition();
+
+ public:
+
+ /** Constructor.
+ @param applicationName Application name.
+ @param applicationHelper Helper object.
+ @param applicationHelp Help controller.
+ @param wxid Window ID.
+ */
+ DkWxFrame(
+ wxChar const *applicationName,
+ DkWxAppHelper *applicationHelper,
+ DkWxHelpController *applicationHelp,
+ int wxid
+ );
+
+ /** Restore previous position or center on screen.
+ */
+ void restorePosition();
+
+ /** Handler for close event.
+ @param event Event to process.
+ */
+ void OnClose(wxCloseEvent & event);
+
+ /** Check whether we can close the frame.
+ @param isLast Flag: Last frame instance of application.
+ @return Permission to close.
+ */
+ virtual bool canClose(bool isLast);
+
+ /** Open help system if help controller available.
+ */
+ void openHelp();
+
+ /** Open help section specified by name.
+ @param name Section name.
+ */
+ void
+ openHelpSectionByName(wxString const & name);
+
+ /** Open help section specified by section number.
+ @param number Section number (context ID).
+ */
+ void
+ openHelpSectionByNumber(int number);
+};
+
+
+
+
+#endif
diff --git a/support/dktools/DkWxHelpController.cpp b/support/dktools/DkWxHelpController.cpp
new file mode 100644
index 0000000000..7acf21d5b2
--- /dev/null
+++ b/support/dktools/DkWxHelpController.cpp
@@ -0,0 +1,172 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxHelpController.cpt
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxHelpController.cpp The DkWxHelpController module.
+*/
+
+
+#line 91 "DkWxHelpController.cpt"
+
+#include "dk3all.h"
+
+#include "DkWxAppHelper.h"
+#include "DkWxHelpController.h"
+
+#include "dk3wxs.h"
+
+
+
+
+#line 101 "DkWxHelpController.cpt"
+
+
+
+
+DkWxHelpController::DkWxHelpController(
+ DkWxAppHelper *ah,
+ wxChar const *chmName,
+ wxChar const *htbName
+)
+#ifdef __WXMSW__
+#else
+ : hc(wxHF_DEFAULT_STYLE | wxHF_MERGE_BOOKS)
+#endif
+{
+ wxChar fnb[DK3_MAX_PATH];
+
+ appHelper = ah;
+ bFileFound = false;
+
+
+#line 120 "DkWxHelpController.cpt"
+#ifdef __WXMSW__
+
+
+#line 122 "DkWxHelpController.cpt"
+ if((appHelper) && (chmName)) {
+ if(appHelper->findDataFile(chmName, fnb, DK3_SIZEOF(fnb,wxChar))) {
+ hc.Initialize(fnb);
+ bFileFound = true;
+ }
+ }
+#else
+ wxZipFSHandler *zfsh;
+
+
+#line 131 "DkWxHelpController.cpt"
+ if((ah) && (htbName)) {
+ if(appHelper->findDataFile(htbName, fnb, DK3_SIZEOF(fnb,wxChar))) {
+ zfsh = new wxZipFSHandler();
+ if(zfsh) {
+ wxFileSystem::AddHandler(zfsh);
+ hc.AddBook(fnb);
+ bFileFound = true;
+ }
+ }
+ }
+#endif
+
+
+#line 143 "DkWxHelpController.cpt"
+}
+
+
+
+void
+DkWxHelpController::openHelp(wxFrame *wxf)
+{
+ wxChar const *titleString;
+ wxChar const *msgString;
+
+
+#line 153 "DkWxHelpController.cpt"
+ if(bFileFound) {
+ hc.DisplayContents();
+ } else {
+ if(appHelper) {
+ titleString = appHelper->getBasicString(3);
+ msgString = appHelper->getBasicString(10);
+ wxMessageBox(msgString, titleString, wxOK, wxf);
+ }
+ }
+
+#line 162 "DkWxHelpController.cpt"
+}
+
+
+
+void
+DkWxHelpController::openHelpSectionByName(wxFrame *wxf, wxString const & name)
+{
+ wxChar const *titleString;
+ wxChar const *msgString;
+
+
+#line 172 "DkWxHelpController.cpt"
+ if (bFileFound) {
+ hc.DisplaySection(name);
+ } else {
+ if (appHelper) {
+ titleString = appHelper->getBasicString(3);
+ msgString = appHelper->getBasicString(10);
+ wxMessageBox(msgString, titleString, wxOK, wxf);
+ }
+ }
+
+
+#line 182 "DkWxHelpController.cpt"
+}
+
+
+
+void
+DkWxHelpController::openHelpSectionByNumber(wxFrame *wxf, int number)
+{
+ wxChar const *titleString;
+ wxChar const *msgString;
+
+
+#line 192 "DkWxHelpController.cpt"
+ if (bFileFound) {
+ hc.DisplaySection(number);
+ } else {
+ titleString = appHelper->getBasicString(3);
+ msgString = appHelper->getBasicString(10);
+ wxMessageBox(msgString, titleString, wxOK, wxf);
+ }
+
+
+#line 200 "DkWxHelpController.cpt"
+}
diff --git a/support/dktools/DkWxHelpController.cpt b/support/dktools/DkWxHelpController.cpt
new file mode 100644
index 0000000000..9a3954ef6b
--- /dev/null
+++ b/support/dktools/DkWxHelpController.cpt
@@ -0,0 +1,200 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% header
+
+#include <dk3conf.h>
+#include <dk3types.h>
+
+#include <wx/wxprec.h>
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#include <wx/wx.h>
+#endif
+#include <wx/config.h>
+#include <wx/filename.h>
+#include <wx/help.h>
+#include <wx/fs_zip.h>
+
+#include <DkWxAppHelper.h>
+
+
+
+/** Help controller covering both chm and htb help files.
+*/
+class DkWxHelpController
+{
+ private:
+
+ /** Application helper, used to find the help files.
+ */
+ DkWxAppHelper *appHelper;
+
+ /** Flag: Help file was found.
+ */
+ bool bFileFound;
+
+#ifdef __WXMSW__
+ /** Use CHM help controller on Windows systems.
+ */
+ wxCHMHelpController hc;
+#else
+ /** Use HTML help controller on all other systems.
+ */
+ wxHtmlHelpController hc;
+#endif
+
+ public:
+ /** Constructor.
+ @param ah Application helper.
+ @param chmName Short file name of chm file, without leading directory.
+ @param htbName Short file name of htb file, without leading directory.
+ */
+ DkWxHelpController(
+ DkWxAppHelper *ah,
+ wxChar const *chmName,
+ wxChar const *htbName
+ );
+
+ /** Open help system.
+ @param wxf Parent frame.
+ */
+ void
+ openHelp(wxFrame *wxf);
+
+ /** Open a help section specified by name.
+ @param wxf Parent frame.
+ @param name Section name.
+ */
+ void
+ openHelpSectionByName(wxFrame *wxf, wxString const & name);
+
+ /** Open a help section specified by number.
+ @param wxf Parent frame.
+ @param number Section number (context ID).
+ */
+ void
+ openHelpSectionByNumber(wxFrame *wxf, int number);
+
+};
+
+
+
+%% module
+
+#include "dk3all.h"
+
+#include "DkWxAppHelper.h"
+#include "DkWxHelpController.h"
+
+#include "dk3wxs.h"
+
+
+$!trace-include
+
+
+
+
+DkWxHelpController::DkWxHelpController(
+ DkWxAppHelper *ah,
+ wxChar const *chmName,
+ wxChar const *htbName
+)
+#ifdef __WXMSW__
+#else
+ : hc(wxHF_DEFAULT_STYLE | wxHF_MERGE_BOOKS)
+#endif
+{
+ wxChar fnb[DK3_MAX_PATH];
+
+ appHelper = ah;
+ bFileFound = false;
+ $? "+ DkWxHelpController::DkWxHelpController"
+#ifdef __WXMSW__
+ $? ". Windows variant"
+ if((appHelper) && (chmName)) {
+ if(appHelper->findDataFile(chmName, fnb, DK3_SIZEOF(fnb,wxChar))) {
+ hc.Initialize(fnb);
+ bFileFound = true;
+ }
+ }
+#else
+ wxZipFSHandler *zfsh;
+ $? ". UNIX variant"
+ if((ah) && (htbName)) {
+ if(appHelper->findDataFile(htbName, fnb, DK3_SIZEOF(fnb,wxChar))) {
+ zfsh = new wxZipFSHandler();
+ if(zfsh) {
+ wxFileSystem::AddHandler(zfsh);
+ hc.AddBook(fnb);
+ bFileFound = true;
+ }
+ }
+ }
+#endif
+ $? "- DkWxHelpController::DkWxHelpController"
+}
+
+
+
+void
+DkWxHelpController::openHelp(wxFrame *wxf)
+{
+ wxChar const *titleString;
+ wxChar const *msgString;
+ $? "+ DkWxHelpController::openHelp"
+ if(bFileFound) {
+ hc.DisplayContents();
+ } else {
+ if(appHelper) {
+ titleString = appHelper->getBasicString(3);
+ msgString = appHelper->getBasicString(10);
+ wxMessageBox(msgString, titleString, wxOK, wxf);
+ }
+ } $? "- DkWxHelpController::openHelp"
+}
+
+
+
+void
+DkWxHelpController::openHelpSectionByName(wxFrame *wxf, wxString const & name)
+{
+ wxChar const *titleString;
+ wxChar const *msgString;
+ $? "+ DkWxHelpController::openHelpSectionByName"
+ if (bFileFound) {
+ hc.DisplaySection(name);
+ } else {
+ if (appHelper) {
+ titleString = appHelper->getBasicString(3);
+ msgString = appHelper->getBasicString(10);
+ wxMessageBox(msgString, titleString, wxOK, wxf);
+ }
+ }
+ $? "- DkWxHelpController::openHelpSectionByName"
+}
+
+
+
+void
+DkWxHelpController::openHelpSectionByNumber(wxFrame *wxf, int number)
+{
+ wxChar const *titleString;
+ wxChar const *msgString;
+ $? "+ DkWxHelpController::openHelpSectionByNumber"
+ if (bFileFound) {
+ hc.DisplaySection(number);
+ } else {
+ titleString = appHelper->getBasicString(3);
+ msgString = appHelper->getBasicString(10);
+ wxMessageBox(msgString, titleString, wxOK, wxf);
+ }
+ $? "- DkWxHelpController::openHelpSectionByNumber"
+}
diff --git a/support/dktools/DkWxHelpController.h b/support/dktools/DkWxHelpController.h
new file mode 100644
index 0000000000..918b3f17ca
--- /dev/null
+++ b/support/dktools/DkWxHelpController.h
@@ -0,0 +1,126 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxHelpController.cpt
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxHelpController.h Header file for the DkWxHelpController module.
+*/
+
+#ifndef DKWXHELPCONTROLLER_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DKWXHELPCONTROLLER_H_INCLUDED 1
+
+
+#line 10 "DkWxHelpController.cpt"
+
+#include <dk3conf.h>
+#include <dk3types.h>
+
+#include <wx/wxprec.h>
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#include <wx/wx.h>
+#endif
+#include <wx/config.h>
+#include <wx/filename.h>
+#include <wx/help.h>
+#include <wx/fs_zip.h>
+
+#include <DkWxAppHelper.h>
+
+
+
+/** Help controller covering both chm and htb help files.
+*/
+class DkWxHelpController
+{
+ private:
+
+ /** Application helper, used to find the help files.
+ */
+ DkWxAppHelper *appHelper;
+
+ /** Flag: Help file was found.
+ */
+ bool bFileFound;
+
+#ifdef __WXMSW__
+ /** Use CHM help controller on Windows systems.
+ */
+ wxCHMHelpController hc;
+#else
+ /** Use HTML help controller on all other systems.
+ */
+ wxHtmlHelpController hc;
+#endif
+
+ public:
+ /** Constructor.
+ @param ah Application helper.
+ @param chmName Short file name of chm file, without leading directory.
+ @param htbName Short file name of htb file, without leading directory.
+ */
+ DkWxHelpController(
+ DkWxAppHelper *ah,
+ wxChar const *chmName,
+ wxChar const *htbName
+ );
+
+ /** Open help system.
+ @param wxf Parent frame.
+ */
+ void
+ openHelp(wxFrame *wxf);
+
+ /** Open a help section specified by name.
+ @param wxf Parent frame.
+ @param name Section name.
+ */
+ void
+ openHelpSectionByName(wxFrame *wxf, wxString const & name);
+
+ /** Open a help section specified by number.
+ @param wxf Parent frame.
+ @param number Section number (context ID).
+ */
+ void
+ openHelpSectionByNumber(wxFrame *wxf, int number);
+
+};
+
+
+
+
+#endif
diff --git a/support/dktools/DkWxHtbApp.cpp b/support/dktools/DkWxHtbApp.cpp
new file mode 100644
index 0000000000..5ec60b4ece
--- /dev/null
+++ b/support/dktools/DkWxHtbApp.cpp
@@ -0,0 +1,360 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxHtbApp.cpt
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxHtbApp.cpp The DkWxHtbApp module.
+*/
+
+
+#line 59 "DkWxHtbApp.cpt"
+
+#include "wxdkhtb.h"
+
+
+
+
+#line 64 "DkWxHtbApp.cpt"
+
+
+
+/** Localized wxChar texts.
+*/
+static wxChar const * wxdkhtb_texts[] = {
+/* 0 */
+wxT("File"),
+
+/* 1 */
+wxT("Exit"),
+
+/* 2 */
+wxT("Exit the application"),
+
+/* 3 */
+wxT("Help"),
+
+/* 4 */
+wxT("About"),
+
+/* 5 */
+wxT("Show version information"),
+
+/* 6 */
+wxT("Contents"),
+
+/* 7 */
+wxT("Open table of contents"),
+
+/* 8 */
+wxT("Ready"),
+
+/* 9 */
+wxT("Copyright (c) "),
+
+/* 10 */
+wxT("About "),
+
+/* 11 */
+wxT("This program uses the following libraries:"),
+
+/* 12 */
+wxT("See:"),
+
+/* 13 */
+wxT("HTB viewer main window"),
+
+/* 14 */
+wxT("No help controller was created!"),
+
+/* 15 */
+wxT("Error"),
+
+/* 16 */
+wxT("No *.htb file name was specified on the command line!"),
+
+/* 17 */
+wxT("The specified file does not exist!"),
+
+/* 18 */
+wxT("Failed to create help controller, resources/memory problem!"),
+
+NULL
+
+
+#line 148 "DkWxHtbApp.cpt"
+};
+
+
+
+/** Non-localized wxChar texts.
+*/
+static wxChar const * wxdkhtb_nl_wx[] = {
+/* 0 */
+wxT("wxdkhtb"),
+
+/* 1 */
+wxT("1.0.0"),
+
+/* 2 */
+wxT("Dirk Krause"),
+
+/* 3 */
+wxT("DirkKrause"),
+
+/* 4 */
+wxT("aaaaa"),
+
+/* 5 */
+wxT("wxdkhtb.chm"),
+
+/* 6 */
+wxT("wxdkhtb.htb"),
+
+/* 7 */
+wxT(" "),
+
+/* 8 */
+wxT("\n"),
+
+/* 9 */
+wxT("DK tools, wxWidgets, libpng, libjpeg, libtiff, zlib."),
+
+/* 10 */
+wxT("http://dktools.sourceforge.net"),
+
+/* 11 */
+wxT("http://www.wxwidgets.org"),
+
+/* 12 */
+wxT("http://www.libpng.org/pub/png/libpng.html"),
+
+/* 13 */
+wxT("http://www.ijg.org"),
+
+/* 14 */
+wxT("http://www.remotesensing.org/libtiff"),
+
+/* 15 */
+wxT("http://www.zlib.net"),
+
+/* 16 */
+wxT("Error"),
+
+/* 17 */
+wxT("Not enough memory (RAM)!"),
+
+NULL
+
+
+#line 208 "DkWxHtbApp.cpt"
+};
+
+
+
+/** Non-localized dkChar texts.
+*/
+static dkChar const * wxdkhtb_nl_dk[] = {
+/* 0 */
+dkT("dktools"),
+
+/* 1 */
+dkT("wxdkhtb.str"),
+
+NULL
+
+
+#line 225 "DkWxHtbApp.cpt"
+};
+
+
+
+/** Implementation of the wxApp functionality.
+*/
+IMPLEMENT_APP(DkWxHtbApp)
+
+
+bool
+DkWxHtbApp::OnInit()
+{
+ DkWxHtbFrame *frame = NULL;
+ wxChar const * const *localizedTexts = NULL;
+ wxPNGHandler *phPng = NULL;
+ wxXPMHandler *phXpm = NULL;
+ wxICOHandler *phIco = NULL;
+ wxZipFSHandler *phZipFs = NULL;
+ bool back = false;
+ int iStatus = 0;
+ /* 0 No file name
+ 1 File does not exist
+ 2 Not enough memory to create controller
+ 3 Everything ok
+ */
+
+ /* Initialize members. */
+ pHelper = NULL;
+ helpController = NULL;
+
+ /* Set up helper object. */
+ pHelper = new DkWxAppHelper(
+ argv[0],
+ wxdkhtb_nl_wx[3],
+ wxdkhtb_nl_dk[0]
+ );
+ if(!(pHelper)) { ShowMemoryErrorMessage(); goto finished; }
+ if(!(pHelper->checkSetup())) { goto finished; }
+
+ /* Add image and file system handlers for online help. */
+ phPng = new wxPNGHandler();
+ if (NULL != phPng) {
+ wxImage::AddHandler(phPng);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phXpm = new wxXPMHandler();
+ if (NULL != phXpm) {
+ wxImage::AddHandler(phXpm);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phIco = new wxICOHandler();
+ if (NULL != phIco) {
+ wxImage::AddHandler(phIco);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phZipFs = new wxZipFSHandler();
+ if (NULL != phZipFs) {
+ wxFileSystem::AddHandler(phZipFs);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ localizedTexts = pHelper->getStringTable(wxdkhtb_texts, wxdkhtb_nl_dk[1]);
+ if(!(localizedTexts)) { localizedTexts = wxdkhtb_texts; }
+
+ /* Set up online help controller. */
+ if (1 < argc) {
+ wxString fullPath;
+ wxFileName fn(argv[1]);
+ iStatus = 1;
+ fn.Normalize(
+ wxPATH_NORM_LONG | wxPATH_NORM_DOTS
+ | wxPATH_NORM_TILDE | wxPATH_NORM_ABSOLUTE
+ );
+ if (fn.FileExists()) {
+ iStatus = 2;
+ fullPath = fn.GetFullPath();
+ helpController = new wxHtmlHelpController(
+ wxHF_DEFAULT_STYLE | wxHF_MERGE_BOOKS
+ );
+ if (helpController) {
+ helpController->Initialize(fullPath);
+ iStatus = 3;
+ }
+ }
+ }
+ /* Create and show frame. */
+ frame = new DkWxHtbFrame(
+ DkWxHtbFrame_MainWindow,
+ pHelper,
+ helpController,
+ argc,
+ argv,
+ localizedTexts,
+ wxdkhtb_nl_wx,
+ wxdkhtb_nl_dk,
+ iStatus
+ );
+ if(!(frame)) { ShowMemoryErrorMessage(); goto finished; }
+ frame->Show();
+ frame->restorePosition();
+ back = true;
+
+ /* Release resources if initialization failed. */
+ finished:
+ if(!(back)) {
+ if(helpController) {
+ delete(helpController);
+ helpController = NULL;
+ }
+ if(pHelper) {
+ delete(pHelper);
+ pHelper = NULL;
+ }
+ }
+ return back;
+}
+
+
+
+int
+DkWxHtbApp::OnExit()
+{
+ int back = 0;
+
+ /* Release resources. */
+ if(helpController) {
+ delete(helpController);
+ helpController = NULL;
+ }
+ if(pHelper) {
+ delete(pHelper);
+ pHelper = NULL;
+ }
+ return back;
+}
+
+
+
+void
+DkWxHtbApp::ShowMemoryErrorMessage(void)
+{
+ const wxChar *s_title = NULL;
+ const wxChar *s_text = NULL;
+
+ if (NULL != pHelper) {
+ s_title = pHelper->getBasicString(3);
+ s_text = pHelper->getBasicString(9);
+ }
+ if (NULL == s_title) {
+ s_title = wxdkhtb_nl_wx[16];
+ }
+ if (NULL == s_text) {
+ s_text = wxdkhtb_nl_wx[17];
+ }
+ wxMessageBox(s_text, s_title, (wxOK | wxCENTRE | wxICON_ERROR));
+}
diff --git a/support/dktools/DkWxHtbApp.cpt b/support/dktools/DkWxHtbApp.cpt
new file mode 100644
index 0000000000..b2356787e3
--- /dev/null
+++ b/support/dktools/DkWxHtbApp.cpt
@@ -0,0 +1,388 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2014-xxxx
+license = bsd
+
+
+
+%% header
+
+
+/** Application class, derived from wxApp, one instance per program.
+*/
+class DkWxHtbApp : public wxApp
+{
+ protected:
+
+ /** Helper object.
+ */
+ DkWxAppHelper *pHelper;
+
+ /** Controller fr online help.
+ */
+ wxHtmlHelpController *helpController;
+
+ protected:
+
+ /** Show error message if there is not sufficient memory available.
+ */
+ void
+ ShowMemoryErrorMessage(void);
+
+ public:
+
+ /** Application initialization.
+ @return true on success, false on error.
+ */
+ virtual
+ bool
+ OnInit();
+
+ /** Application shutdown.
+ @return 0 on success, any other value indicates an error.
+ */
+ virtual
+ int
+ OnExit();
+};
+
+
+
+/** Declaration as the wxApp object.
+*/
+DECLARE_APP(DkWxHtbApp)
+
+
+
+%% module
+
+#include "wxdkhtb.h"
+
+
+$!trace-include
+
+
+
+/** Localized wxChar texts.
+*/
+static wxChar const * wxdkhtb_texts[] = {
+$!string-table macro=wxT
+#
+# 0: Menu "File"
+#
+File
+#
+# 1: Menu item "File/Exit"
+#
+Exit
+#
+# 2: Tool tip text for menu item "File/Exit"
+#
+Exit the application
+#
+# 3: Menu "Help"
+#
+Help
+#
+# 4: Menu item "Help/About"
+#
+About
+#
+# 5: Tooltip text for menu item "Help/About"
+#
+Show version information
+#
+# 6: Menu item "Help/Contents"
+#
+Contents
+#
+# 7: Tooltip text for menu item "Help/Contents"
+#
+Open table of contents
+#
+# 8: Initial status text
+#
+Ready
+#
+# 9: Copyright notice.
+#
+Copyright (c)
+#
+# 10: Dialog box title "About ..."
+#
+About
+#
+# 11: This program uses the following libraries
+#
+This program uses the following libraries:
+#
+# 12: See
+#
+See:
+#
+# 13: Text for dummy label, can be reused if lDummy removed.
+#
+HTB viewer main window
+#
+# 14: No help controller created
+#
+No help controller was created!
+#
+# 15: Error
+#
+Error
+#
+# 16
+#
+No *.htb file name was specified on the command line!
+#
+# 17
+#
+The specified file does not exist!
+#
+# 18
+#
+Failed to create help controller, resources/memory problem!
+$!end
+};
+
+
+
+/** Non-localized wxChar texts.
+*/
+static wxChar const * wxdkhtb_nl_wx[] = {
+$!string-table macro=wxT
+#
+# 0: Program name.
+#
+wxdkhtb
+#
+# 1: Program version.
+#
+1.0.0
+#
+# 2: Copyright owner name.
+#
+Dirk Krause
+#
+# 3: Software vendor name.
+#
+DirkKrause
+#
+# 4: Resource name of Windows icon
+#
+aaaaa
+#
+# 5: Windows chm help file name
+#
+wxdkhtb.chm
+#
+# 6: non-Windows htb help file name
+#
+wxdkhtb.htb
+#
+# 7: Space
+#
+
+#
+# 8: Newline
+#
+\n
+#
+# 9 10 11 12 13 14 15: List of libraries used.
+#
+DK tools, wxWidgets, libpng, libjpeg, libtiff, zlib.
+http://dktools.sourceforge.net
+http://www.wxwidgets.org
+http://www.libpng.org/pub/png/libpng.html
+http://www.ijg.org
+http://www.remotesensing.org/libtiff
+http://www.zlib.net
+#
+#
+#
+Error
+Not enough memory (RAM)!
+$!end
+};
+
+
+
+/** Non-localized dkChar texts.
+*/
+static dkChar const * wxdkhtb_nl_dk[] = {
+$!string-table macro=dkT
+#
+# 0: Program group name.
+#
+dktools
+#
+# 1: String table name.
+#
+wxdkhtb.str
+$!end
+};
+
+
+
+/** Implementation of the wxApp functionality.
+*/
+IMPLEMENT_APP(DkWxHtbApp)
+
+
+bool
+DkWxHtbApp::OnInit()
+{
+ DkWxHtbFrame *frame = NULL;
+ wxChar const * const *localizedTexts = NULL;
+ wxPNGHandler *phPng = NULL;
+ wxXPMHandler *phXpm = NULL;
+ wxICOHandler *phIco = NULL;
+ wxZipFSHandler *phZipFs = NULL;
+ bool back = false;
+ int iStatus = 0;
+ /* 0 No file name
+ 1 File does not exist
+ 2 Not enough memory to create controller
+ 3 Everything ok
+ */
+
+ /* Initialize members. */
+ pHelper = NULL;
+ helpController = NULL;
+
+ /* Set up helper object. */
+ pHelper = new DkWxAppHelper(
+ argv[0],
+ wxdkhtb_nl_wx[3],
+ wxdkhtb_nl_dk[0]
+ );
+ if(!(pHelper)) { ShowMemoryErrorMessage(); goto finished; }
+ if(!(pHelper->checkSetup())) { goto finished; }
+
+ /* Add image and file system handlers for online help. */
+ phPng = new wxPNGHandler();
+ if (NULL != phPng) {
+ wxImage::AddHandler(phPng);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phXpm = new wxXPMHandler();
+ if (NULL != phXpm) {
+ wxImage::AddHandler(phXpm);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phIco = new wxICOHandler();
+ if (NULL != phIco) {
+ wxImage::AddHandler(phIco);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phZipFs = new wxZipFSHandler();
+ if (NULL != phZipFs) {
+ wxFileSystem::AddHandler(phZipFs);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ localizedTexts = pHelper->getStringTable(wxdkhtb_texts, wxdkhtb_nl_dk[1]);
+ if(!(localizedTexts)) { localizedTexts = wxdkhtb_texts; }
+
+ /* Set up online help controller. */
+ if (1 < argc) {
+ wxString fullPath;
+ wxFileName fn(argv[1]);
+ iStatus = 1;
+ fn.Normalize(
+ wxPATH_NORM_LONG | wxPATH_NORM_DOTS
+ | wxPATH_NORM_TILDE | wxPATH_NORM_ABSOLUTE
+ );
+ if (fn.FileExists()) {
+ iStatus = 2;
+ fullPath = fn.GetFullPath();
+ helpController = new wxHtmlHelpController(
+ wxHF_DEFAULT_STYLE | wxHF_MERGE_BOOKS
+ );
+ if (helpController) {
+ helpController->Initialize(fullPath);
+ iStatus = 3;
+ }
+ }
+ }
+ /* Create and show frame. */
+ frame = new DkWxHtbFrame(
+ DkWxHtbFrame_MainWindow,
+ pHelper,
+ helpController,
+ argc,
+ argv,
+ localizedTexts,
+ wxdkhtb_nl_wx,
+ wxdkhtb_nl_dk,
+ iStatus
+ );
+ if(!(frame)) { ShowMemoryErrorMessage(); goto finished; }
+ frame->Show();
+ frame->restorePosition();
+ back = true;
+
+ /* Release resources if initialization failed. */
+ finished:
+ if(!(back)) {
+ if(helpController) {
+ delete(helpController);
+ helpController = NULL;
+ }
+ if(pHelper) {
+ delete(pHelper);
+ pHelper = NULL;
+ }
+ }
+ return back;
+}
+
+
+
+int
+DkWxHtbApp::OnExit()
+{
+ int back = 0;
+
+ /* Release resources. */
+ if(helpController) {
+ delete(helpController);
+ helpController = NULL;
+ }
+ if(pHelper) {
+ delete(pHelper);
+ pHelper = NULL;
+ }
+ return back;
+}
+
+
+
+void
+DkWxHtbApp::ShowMemoryErrorMessage(void)
+{
+ const wxChar *s_title = NULL;
+ const wxChar *s_text = NULL;
+
+ if (NULL != pHelper) {
+ s_title = pHelper->getBasicString(3);
+ s_text = pHelper->getBasicString(9);
+ }
+ if (NULL == s_title) {
+ s_title = wxdkhtb_nl_wx[16];
+ }
+ if (NULL == s_text) {
+ s_text = wxdkhtb_nl_wx[17];
+ }
+ wxMessageBox(s_text, s_title, (wxOK | wxCENTRE | wxICON_ERROR));
+}
diff --git a/support/dktools/DkWxHtbApp.h b/support/dktools/DkWxHtbApp.h
new file mode 100644
index 0000000000..12a6314fc3
--- /dev/null
+++ b/support/dktools/DkWxHtbApp.h
@@ -0,0 +1,94 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxHtbApp.cpt
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxHtbApp.h Header file for the DkWxHtbApp module.
+*/
+
+#ifndef DKWXHTBAPP_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DKWXHTBAPP_H_INCLUDED 1
+
+
+#line 10 "DkWxHtbApp.cpt"
+
+
+/** Application class, derived from wxApp, one instance per program.
+*/
+class DkWxHtbApp : public wxApp
+{
+ protected:
+
+ /** Helper object.
+ */
+ DkWxAppHelper *pHelper;
+
+ /** Controller fr online help.
+ */
+ wxHtmlHelpController *helpController;
+
+ protected:
+
+ /** Show error message if there is not sufficient memory available.
+ */
+ void
+ ShowMemoryErrorMessage(void);
+
+ public:
+
+ /** Application initialization.
+ @return true on success, false on error.
+ */
+ virtual
+ bool
+ OnInit();
+
+ /** Application shutdown.
+ @return 0 on success, any other value indicates an error.
+ */
+ virtual
+ int
+ OnExit();
+};
+
+
+
+/** Declaration as the wxApp object.
+*/
+DECLARE_APP(DkWxHtbApp)
+
+
+
+
+#endif
diff --git a/support/dktools/DkWxHtbFrame.cpp b/support/dktools/DkWxHtbFrame.cpp
new file mode 100644
index 0000000000..c641b05b60
--- /dev/null
+++ b/support/dktools/DkWxHtbFrame.cpp
@@ -0,0 +1,361 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxHtbFrame.wxc
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxHtbFrame.cpp The DkWxHtbFrame module.
+*/
+
+
+#line 182 "DkWxHtbFrame.wxc"
+
+#include "wxdkhtb.h"
+#include "dk4verswx.h"
+
+#if !defined(__WXMSW__)
+#include "dkicon.xpm"
+#endif
+
+
+
+
+
+#line 193 "DkWxHtbFrame.wxc"
+
+
+
+BEGIN_EVENT_TABLE(DkWxHtbFrame, wxFrame)
+ EVT_MENU(DkWxHtbFrame_Quit, DkWxHtbFrame::OnQuit)
+ EVT_MENU(DkWxHtbFrame_Help_About, DkWxHtbFrame::OnAbout)
+ EVT_MENU(DkWxHtbFrame_Help_Contents, DkWxHtbFrame::OnHelpContents)
+ EVT_IDLE(DkWxHtbFrame::OnIdle)
+END_EVENT_TABLE()
+
+
+
+/** Version number for version information.
+*/
+static wxChar const wxdkhtb_versnumber[] = {
+ DKT_VERSION_WX
+};
+
+
+
+
+#line 214 "DkWxHtbFrame.wxc"
+DkWxHtbFrame::DkWxHtbFrame(
+ int wxid,
+ DkWxAppHelper *applicationHelper,
+ wxHtmlHelpController *hc,
+ int argc,
+ wxChar **argv,
+ wxChar const * const *localizedTexts,
+ wxChar const * const *nlWx,
+ dkChar const * const *nlDk,
+ int is
+) : DkWxFrame(nlWx[0], applicationHelper, NULL, wxid)
+{
+ bCanRun = true;
+ htbController = hc;
+ iStatus = is;
+ sTexts = localizedTexts;
+ sNlWx = nlWx;
+ sNlDk = nlDk;
+#if defined(__WXMSW__)
+ wxIcon wxdkhtb_icon(sNlWx[4]);
+#else
+ wxIcon wxdkhtb_icon(xpm_dkicon);
+#endif
+ dkctGUILayoutOK = false;
+ dkctGUIContentsPanel = NULL;
+ mainSizer = NULL;
+ mbMain = NULL;
+ menuFile = NULL;
+ menuHelp = NULL;
+ miFileExit = NULL;
+ miHelpAbout = NULL;
+ miHelpContents = NULL;
+ verticalSizer = NULL;
+ contentsSizer = NULL;
+ lDummy = NULL;
+ dkctGUIContentsPanel = new wxPanel(this);
+ if(!(dkctGUIContentsPanel)) {
+ goto dkctGUILayoutFinished;
+ }
+#if wxUSE_MENUS
+ mbMain = new wxMenuBar(
+ );
+ if(!(mbMain)) {
+ goto dkctGUILayoutFinished;
+ }
+ menuFile = new wxMenu(
+ );
+ if(!(menuFile)) {
+ goto dkctGUILayoutFinished;
+ }
+ miFileExit = menuFile->Append(
+ DkWxHtbFrame_Quit,
+ sTexts[1],
+ sTexts[2]
+ );
+ if(!(miFileExit)) {
+ goto dkctGUILayoutFinished;
+ }
+ mbMain->Append(menuFile, sTexts[0]);
+ menuHelp = new wxMenu(
+ );
+ if(!(menuHelp)) {
+ goto dkctGUILayoutFinished;
+ }
+ miHelpAbout = menuHelp->Append(
+ DkWxHtbFrame_Help_About,
+ sTexts[4],
+ sTexts[5]
+ );
+ if(!(miHelpAbout)) {
+ goto dkctGUILayoutFinished;
+ }
+ miHelpContents = menuHelp->Append(
+ DkWxHtbFrame_Help_Contents,
+ sTexts[6],
+ sTexts[7]
+ );
+ if(!(miHelpContents)) {
+ goto dkctGUILayoutFinished;
+ }
+ mbMain->Append(menuHelp, sTexts[3]);
+ SetMenuBar(mbMain);
+#endif
+ mainSizer = new wxBoxSizer(
+ wxHORIZONTAL
+ );
+ if(!(mainSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ mainSizer->Add(10, 10, 0);
+ verticalSizer = new wxBoxSizer(
+ wxVERTICAL
+ );
+ if(!(verticalSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ verticalSizer->Add(10, 10, 0);
+ contentsSizer = new wxGridBagSizer(
+ 5, 5
+ );
+ if(!(contentsSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ lDummy = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[13]
+ );
+ if(!(lDummy)) {
+ goto dkctGUILayoutFinished;
+ }
+ contentsSizer->Add(
+ lDummy,
+ wxGBPosition(0, 0),
+ wxGBSpan(1, 1),
+ wxALIGN_LEFT
+ );
+ verticalSizer->Add(
+ contentsSizer
+ );
+ verticalSizer->Add(10, 10, 0);
+ mainSizer->Add(
+ verticalSizer,
+ 1,
+ wxGROW
+ );
+ mainSizer->Add(10, 10, 0);
+ dkctGUIContentsPanel->SetSizer(mainSizer);
+ SetIcon(wxdkhtb_icon);
+ dkctGUILayoutOK = true;
+ dkctGUILayoutFinished:
+#if wxUSE_STATUSBAR
+ if(dkctGUILayoutOK) {
+ CreateStatusBar(1);
+ SetStatusText(sTexts[8]);
+ }
+#endif
+ if(dkctGUILayoutOK) {
+ mainSizer->Fit(this);
+ mainSizer->SetSizeHints(this);
+ }
+
+#line 238 "DkWxHtbFrame.wxc"
+ if(dkctGUILayoutOK) {
+ SetTitle(nlWx[0]);
+#if 0
+ restorePosition();
+#endif
+ }
+}
+
+
+#line 247 "DkWxHtbFrame.wxc"
+
+
+
+DkWxHtbFrame::~DkWxHtbFrame()
+{
+}
+
+
+
+bool
+DkWxHtbFrame::canClose(bool isLast)
+{
+ bool back = true;
+ return back;
+}
+
+
+void
+DkWxHtbFrame::OnQuit(wxCommandEvent & event)
+{
+ Close();
+}
+
+
+
+void
+DkWxHtbFrame::OnAbout(wxCommandEvent & event)
+{
+ wxString text(wxT(""));
+ wxString title(wxT(""));
+
+ /* Construct message text. */
+ text.Append(sNlWx[0]);
+ text.Append(sNlWx[7]);
+#if 0
+ text.Append(sNlWx[1]);
+#else
+ text.append(wxdkhtb_versnumber);
+#endif
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[9]);
+ text.Append(sNlWx[2]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[11]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[9]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[12]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[10]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[11]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[12]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[13]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[14]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[15]);
+ text.Append(sNlWx[8]);
+
+ /* Construct dialog box title. */
+ title.Append(sTexts[10]);
+ title.Append(sNlWx[0]);
+
+ /* Show dialog box. */
+ wxMessageBox(text, title);
+
+ /* __CHANGE__ 019: Create better about box.
+ */
+}
+
+
+
+void
+DkWxHtbFrame::OnHelpContents(wxCommandEvent & event)
+{
+#if 0
+ openHelp();
+#endif
+ if (htbController) {
+ htbController->DisplayContents();
+ }
+}
+
+
+
+void
+DkWxHtbFrame::OnIdle(wxIdleEvent & event)
+{
+ bool bRun = false;
+
+ {
+ wxMutexLocker lock(mProtectCanRun);
+ bRun = bCanRun;
+ bCanRun = false;
+ }
+ if (bRun) {
+ switch (iStatus) {
+ case 3: {
+ if (htbController) {
+ htbController->DisplayContents();
+ } else {
+ wxMessageBox(sTexts[14], sTexts[15], (wxICON_ERROR | wxOK), this);
+ Show(false);
+ Close();
+ }
+ } break;
+ case 2: { /* Failed to create controller, not enough memory */
+ wxMessageBox(sTexts[18], sTexts[15], (wxICON_ERROR | wxOK), this);
+ Show(false);
+ Close();
+ } break;
+ case 1: { /* File does not exist */
+ wxMessageBox(sTexts[17], sTexts[15], (wxICON_ERROR | wxOK), this);
+ Show(false);
+ Close();
+ } break;
+ case 0: { /* No file specified */
+ wxMessageBox(sTexts[16], sTexts[15], (wxICON_ERROR | wxOK), this);
+ Show(false);
+ Close();
+ } break;
+ }
+ }
+ /* event.RequestMore(); */
+ event.Skip();
+}
+
+
diff --git a/support/dktools/DkWxHtbFrame.h b/support/dktools/DkWxHtbFrame.h
new file mode 100644
index 0000000000..090b52f361
--- /dev/null
+++ b/support/dktools/DkWxHtbFrame.h
@@ -0,0 +1,214 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxHtbFrame.wxc
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxHtbFrame.h Header file for the DkWxHtbFrame module.
+*/
+
+#ifndef DKWXHTBFRAME_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DKWXHTBFRAME_H_INCLUDED 1
+
+
+#line 74 "DkWxHtbFrame.wxc"
+
+
+#line 76 "DkWxHtbFrame.wxc"
+class DkWxHtbFrame : public DkWxFrame
+{
+ private:
+
+ /** Event table for frame.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ /** Localized texts.
+ */
+ wxChar const * const *sTexts;
+
+ /** Non-localized texts.
+ */
+ wxChar const * const *sNlWx;
+
+ /** Non-localized texts.
+ */
+ dkChar const * const *sNlDk;
+
+ /** Help controller for htb file.
+ */
+ wxHtmlHelpController *htbController;
+
+ /** Status from help viewer creation.
+ */
+ int iStatus;
+
+ /** Flag: Can start to run.
+ */
+ bool bCanRun;
+
+ /** Mutex to protect access to bCanRun.
+ */
+ wxMutex mProtectCanRun;
+
+ /** Flag: GUI ok.
+ */
+ bool dkctGUILayoutOK;
+
+ /** Contents panel.
+ */
+ wxPanel *dkctGUIContentsPanel;
+
+ /** GUI element mainSizer.
+ */
+#line 45 "DkWxHtbFrame.wxc"
+ wxBoxSizer *mainSizer;
+
+ /** GUI element mbMain.
+ */
+#line 17 "DkWxHtbFrame.wxc"
+ wxMenuBar *mbMain;
+
+ /** GUI element menuFile.
+ */
+#line 21 "DkWxHtbFrame.wxc"
+ wxMenu *menuFile;
+
+ /** GUI element menuHelp.
+ */
+#line 30 "DkWxHtbFrame.wxc"
+ wxMenu *menuHelp;
+
+ /** GUI element miFileExit.
+ */
+#line 25 "DkWxHtbFrame.wxc"
+ wxMenuItem *miFileExit;
+
+ /** GUI element miHelpAbout.
+ */
+#line 35 "DkWxHtbFrame.wxc"
+ wxMenuItem *miHelpAbout;
+
+ /** GUI element miHelpContents.
+ */
+#line 40 "DkWxHtbFrame.wxc"
+ wxMenuItem *miHelpContents;
+
+ /** GUI element verticalSizer.
+ */
+#line 51 "DkWxHtbFrame.wxc"
+ wxBoxSizer *verticalSizer;
+
+ /** GUI element contentsSizer.
+ */
+#line 59 "DkWxHtbFrame.wxc"
+ wxGridBagSizer *contentsSizer;
+
+ /** GUI element lDummy.
+ */
+#line 68 "DkWxHtbFrame.wxc"
+ wxStaticText *lDummy;
+
+
+#line 115 "DkWxHtbFrame.wxc"
+
+ public:
+
+ /** Constructor.
+ @param wxid Window ID.
+ @param applicationHelper Application helper object.
+ @param hc Help controller for online help.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @param localizedTexts Localized wxChar texts.
+ @param nlWx Non-localized wxChar texts.
+ @param nlDk Non-localized dkChar texts.
+ @param is Status from help viewer creation.
+ */
+ DkWxHtbFrame(
+ int wxid,
+ DkWxAppHelper *applicationHelper,
+ wxHtmlHelpController *hc,
+ int argc,
+ wxChar **argv,
+ wxChar const * const *localizedTexts,
+ wxChar const * const *nlWx,
+ dkChar const * const *nlDk,
+ int is
+ );
+
+ /** Destructor.
+ */
+ ~DkWxHtbFrame();
+
+ /** Check whether we can close the window.
+ @param isLast Flag: Last main window to close.
+ */
+ bool
+ canClose(bool isLast);
+
+ /** Handler for File/Exit.
+ @param event Event to process.
+ */
+ void
+ OnQuit(wxCommandEvent & event);
+
+ /** Handler for Help/About.
+ @param event Event to process.
+ */
+ void
+ OnAbout(wxCommandEvent & event);
+
+ /** Handler for Help/Contents.
+ @param event Event to process.
+ */
+ void
+ OnHelpContents(wxCommandEvent & event);
+
+ /** Handler for idle events.
+ */
+ void
+ OnIdle(wxIdleEvent & event);
+
+ /* __CHANGE__ 014: Add further methods.
+ */
+
+};
+
+
+#line 180 "DkWxHtbFrame.wxc"
+
+
+#endif
diff --git a/support/dktools/DkWxHtbFrame.wxc b/support/dktools/DkWxHtbFrame.wxc
new file mode 100644
index 0000000000..f0a807e233
--- /dev/null
+++ b/support/dktools/DkWxHtbFrame.wxc
@@ -0,0 +1,379 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2014-xxxx
+license = bsd
+
+
+
+%% wx-gui
+
+type = frame
+contents = mainSizer
+icon = wxdkhtb_icon
+status bar = 1 sTexts[8]
+menu bar = mbMain
+
+[wxMenuBar mbMain]
+contents = menuFile
+contents = menuHelp
+
+[wxMenu menuFile]
+text = sTexts[0]
+contents = miFileExit
+
+[wxMenuItem miFileExit]
+id = DkWxHtbFrame_Quit
+text = sTexts[1]
+tip = sTexts[2]
+
+[wxMenu menuHelp]
+text = sTexts[3]
+contents = miHelpAbout
+contents = miHelpContents
+
+[wxMenuItem miHelpAbout]
+id = DkWxHtbFrame_Help_About
+text = sTexts[4]
+tip = sTexts[5]
+
+[wxMenuItem miHelpContents]
+id = DkWxHtbFrame_Help_Contents
+text = sTexts[6]
+tip = sTexts[7]
+
+[wxBoxSizer mainSizer]
+direction = horizontal
+contents = $space(10)
+contents = verticalSizer
+contents = $space(10)
+
+[wxBoxSizer verticalSizer]
+direction = vertical
+grow = yes
+proportion = 1
+contents = $space(10)
+contents = contentsSizer
+contents = $space(10)
+
+[wxGridBagSizer contentsSizer]
+grid = 5 5
+
+# __CHANGE__ 015: The dummy label was added to have at least
+# one GUI element in the sizer.
+# Remove lDummy (next 4 lines) and add the real
+# window contents here.
+contents = lDummy 0 0 1 1 left
+
+[wxStaticText lDummy]
+text = sTexts[13]
+
+
+
+%% header start
+
+%% class start
+class DkWxHtbFrame : public DkWxFrame
+{
+ private:
+
+ /** Event table for frame.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ /** Localized texts.
+ */
+ wxChar const * const *sTexts;
+
+ /** Non-localized texts.
+ */
+ wxChar const * const *sNlWx;
+
+ /** Non-localized texts.
+ */
+ dkChar const * const *sNlDk;
+
+ /** Help controller for htb file.
+ */
+ wxHtmlHelpController *htbController;
+
+ /** Status from help viewer creation.
+ */
+ int iStatus;
+
+ /** Flag: Can start to run.
+ */
+ bool bCanRun;
+
+ /** Mutex to protect access to bCanRun.
+ */
+ wxMutex mProtectCanRun;
+
+%% class end
+
+ public:
+
+ /** Constructor.
+ @param wxid Window ID.
+ @param applicationHelper Application helper object.
+ @param hc Help controller for online help.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @param localizedTexts Localized wxChar texts.
+ @param nlWx Non-localized wxChar texts.
+ @param nlDk Non-localized dkChar texts.
+ @param is Status from help viewer creation.
+ */
+ DkWxHtbFrame(
+ int wxid,
+ DkWxAppHelper *applicationHelper,
+ wxHtmlHelpController *hc,
+ int argc,
+ wxChar **argv,
+ wxChar const * const *localizedTexts,
+ wxChar const * const *nlWx,
+ dkChar const * const *nlDk,
+ int is
+ );
+
+ /** Destructor.
+ */
+ ~DkWxHtbFrame();
+
+ /** Check whether we can close the window.
+ @param isLast Flag: Last main window to close.
+ */
+ bool
+ canClose(bool isLast);
+
+ /** Handler for File/Exit.
+ @param event Event to process.
+ */
+ void
+ OnQuit(wxCommandEvent & event);
+
+ /** Handler for Help/About.
+ @param event Event to process.
+ */
+ void
+ OnAbout(wxCommandEvent & event);
+
+ /** Handler for Help/Contents.
+ @param event Event to process.
+ */
+ void
+ OnHelpContents(wxCommandEvent & event);
+
+ /** Handler for idle events.
+ */
+ void
+ OnIdle(wxIdleEvent & event);
+
+ /* __CHANGE__ 014: Add further methods.
+ */
+
+};
+
+%% header end
+
+%% module start
+
+#include "wxdkhtb.h"
+#include "dk4verswx.h"
+
+#if !defined(__WXMSW__)
+#include "dkicon.xpm"
+#endif
+
+
+
+$!trace-include
+
+
+
+BEGIN_EVENT_TABLE(DkWxHtbFrame, wxFrame)
+ EVT_MENU(DkWxHtbFrame_Quit, DkWxHtbFrame::OnQuit)
+ EVT_MENU(DkWxHtbFrame_Help_About, DkWxHtbFrame::OnAbout)
+ EVT_MENU(DkWxHtbFrame_Help_Contents, DkWxHtbFrame::OnHelpContents)
+ EVT_IDLE(DkWxHtbFrame::OnIdle)
+END_EVENT_TABLE()
+
+
+
+/** Version number for version information.
+*/
+static wxChar const wxdkhtb_versnumber[] = {
+ DKT_VERSION_WX
+};
+
+
+
+%% constructor start
+DkWxHtbFrame::DkWxHtbFrame(
+ int wxid,
+ DkWxAppHelper *applicationHelper,
+ wxHtmlHelpController *hc,
+ int argc,
+ wxChar **argv,
+ wxChar const * const *localizedTexts,
+ wxChar const * const *nlWx,
+ dkChar const * const *nlDk,
+ int is
+) : DkWxFrame(nlWx[0], applicationHelper, NULL, wxid)
+{
+ bCanRun = true;
+ htbController = hc;
+ iStatus = is;
+ sTexts = localizedTexts;
+ sNlWx = nlWx;
+ sNlDk = nlDk;
+#if defined(__WXMSW__)
+ wxIcon wxdkhtb_icon(sNlWx[4]);
+#else
+ wxIcon wxdkhtb_icon(xpm_dkicon);
+#endif
+%% constructor end
+ if(dkctGUILayoutOK) {
+ SetTitle(nlWx[0]);
+#if 0
+ restorePosition();
+#endif
+ }
+}
+
+%% module end
+
+
+
+DkWxHtbFrame::~DkWxHtbFrame()
+{
+}
+
+
+
+bool
+DkWxHtbFrame::canClose(bool isLast)
+{
+ bool back = true;
+ return back;
+}
+
+
+void
+DkWxHtbFrame::OnQuit(wxCommandEvent & event)
+{
+ Close();
+}
+
+
+
+void
+DkWxHtbFrame::OnAbout(wxCommandEvent & event)
+{
+ wxString text(wxT(""));
+ wxString title(wxT(""));
+
+ /* Construct message text. */
+ text.Append(sNlWx[0]);
+ text.Append(sNlWx[7]);
+#if 0
+ text.Append(sNlWx[1]);
+#else
+ text.append(wxdkhtb_versnumber);
+#endif
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[9]);
+ text.Append(sNlWx[2]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[11]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[9]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[12]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[10]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[11]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[12]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[13]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[14]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[15]);
+ text.Append(sNlWx[8]);
+
+ /* Construct dialog box title. */
+ title.Append(sTexts[10]);
+ title.Append(sNlWx[0]);
+
+ /* Show dialog box. */
+ wxMessageBox(text, title);
+
+ /* __CHANGE__ 019: Create better about box.
+ */
+}
+
+
+
+void
+DkWxHtbFrame::OnHelpContents(wxCommandEvent & event)
+{
+#if 0
+ openHelp();
+#endif
+ if (htbController) {
+ htbController->DisplayContents();
+ }
+}
+
+
+
+void
+DkWxHtbFrame::OnIdle(wxIdleEvent & event)
+{
+ bool bRun = false;
+
+ {
+ wxMutexLocker lock(mProtectCanRun);
+ bRun = bCanRun;
+ bCanRun = false;
+ }
+ if (bRun) {
+ switch (iStatus) {
+ case 3: {
+ if (htbController) {
+ htbController->DisplayContents();
+ } else {
+ wxMessageBox(sTexts[14], sTexts[15], (wxICON_ERROR | wxOK), this);
+ Show(false);
+ Close();
+ }
+ } break;
+ case 2: { /* Failed to create controller, not enough memory */
+ wxMessageBox(sTexts[18], sTexts[15], (wxICON_ERROR | wxOK), this);
+ Show(false);
+ Close();
+ } break;
+ case 1: { /* File does not exist */
+ wxMessageBox(sTexts[17], sTexts[15], (wxICON_ERROR | wxOK), this);
+ Show(false);
+ Close();
+ } break;
+ case 0: { /* No file specified */
+ wxMessageBox(sTexts[16], sTexts[15], (wxICON_ERROR | wxOK), this);
+ Show(false);
+ Close();
+ } break;
+ }
+ }
+ /* event.RequestMore(); */
+ event.Skip();
+}
+
+
diff --git a/support/dktools/DkWxImgszApp.cpp b/support/dktools/DkWxImgszApp.cpp
new file mode 100644
index 0000000000..4b42f9c4b1
--- /dev/null
+++ b/support/dktools/DkWxImgszApp.cpp
@@ -0,0 +1,404 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxImgszApp.cpt
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxImgszApp.cpp The DkWxImgszApp module.
+*/
+
+
+#line 47 "DkWxImgszApp.cpt"
+
+
+#include "wximgsz.h"
+
+
+
+
+
+#line 54 "DkWxImgszApp.cpt"
+
+
+
+IMPLEMENT_APP(DkWxImgszApp)
+
+
+
+/** Application group name.
+*/
+static dkChar const wximgsz_group_name[] = { dkT("dktools") };
+
+
+
+/** File name for string table.
+*/
+static dkChar const wximgsz_string_table_name[] = { dkT("wximgsz.str") };
+
+
+
+/** Help file name on Windows.
+*/
+static wxChar const wximgsz_chm_helpfile[] = {
+ wxT("wximgsz.chm")
+};
+
+
+
+/** Help file name for other platforms.
+*/
+static wxChar const wximgsz_htb_helpfile[] = {
+ wxT("wximgsz.htb")
+};
+
+
+
+/** Default texts to use if no localized texts are found.
+*/
+static wxChar const * const wximgsz_default_texts[] = {
+/* 0 */
+wxT("wximgsz"),
+
+/* 1 */
+wxT("File"),
+
+/* 2 */
+wxT("Exit"),
+
+/* 3 */
+wxT("Width"),
+
+/* 4 */
+wxT("Height"),
+
+/* 5 */
+wxT("Factor"),
+
+/* 6 */
+wxT("Original image"),
+
+/* 7 */
+wxT("Results"),
+
+/* 8 */
+wxT("Width:"),
+
+/* 9 */
+wxT("Height:"),
+
+/* 10 */
+wxT("Intended change"),
+
+/* 11 */
+wxT("Action:"),
+
+/* 12 */
+wxT("Decrease image"),
+
+/* 13 */
+wxT("Width range"),
+
+/* 14 */
+wxT("Height range"),
+
+/* 15 */
+wxT("Minimum:"),
+
+/* 16 */
+wxT("Maximum:"),
+
+/* 17 */
+wxT(">>>"),
+
+/* 18 */
+wxT(""),
+
+/* 19 */
+wxT("Exit the application"),
+
+/* 20 */
+wxT("Enter original image width (positive integer number)."),
+
+/* 21 */
+wxT("Enter original image height (positive integer number)."),
+
+/* 22 */
+wxT("Choose modification action."),
+
+/* 23 */
+wxT("Inter intended minimum for image width or height (positive integer number)."),
+
+/* 24 */
+wxT("Enter intended maximum for image width or height (positive integer number)."),
+
+/* 25 */
+wxT("Calculate new image sizes."),
+
+/* 26 */
+wxT(" "),
+
+/* 27 */
+wxT("Help"),
+
+/* 28 */
+wxT("Contents"),
+
+/* 29 */
+wxT("About..."),
+
+/* 30 */
+wxT("Open table of contents"),
+
+/* 31 */
+wxT("Show version number dialog box"),
+
+/* 32 */
+wxT("Incorrect input"),
+
+/* 33 */
+wxT("Please enter a positive integer number."),
+
+/* 34 */
+wxT("No results found!"),
+
+/* 35 */
+wxT("About wximgsz"),
+
+/* 36 */
+wxT("++"),
+
+/* 37 */
+wxT("+"),
+
+/* 38 */
+wxT("Extras"),
+
+/* 39 */
+wxT("Options"),
+
+/* 40 */
+wxT("Set options"),
+
+/* 41 */
+wxT("Options"),
+
+/* 42 */
+wxT("Background colour for scale factor"),
+
+/* 43 */
+wxT("Indicate scale factor quality by background colour (otherwise in extra column)."),
+
+/* 44 */
+wxT("OK"),
+
+/* 45 */
+wxT("Cancel"),
+
+/* 46 */
+wxT("Apply settings and exit dialog."),
+
+/* 47 */
+wxT("Skip settings and exit dialog."),
+
+/* 48 */
+wxT("Choose input bitmap image to open"),
+
+/* 49 */
+wxT("Open\tAlt-O"),
+
+/* 50 */
+wxT("Retrieve dimensions from bitmap image file."),
+
+/* 51 */
+wxT("Failed to load image file!\nFile probably damaged or not a supported image type."),
+
+/* 52 */
+wxT("Failed to load image!"),
+
+/* 53 */
+wxT("\n"),
+
+/* 54 */
+wxT("This program uses libraries from the following projects:\n"),
+
+/* 55 */
+wxT("See:\n"),
+
+NULL
+
+
+#line 318 "DkWxImgszApp.cpt"
+};
+
+
+
+/** Constant texts, not localized.
+*/
+static wxChar const * const wximgsz_nl_wx[] = {
+/* 0 */
+wxT("Error"),
+
+/* 1 */
+wxT("Not enough memory (RAM)!"),
+
+NULL
+
+
+#line 329 "DkWxImgszApp.cpt"
+};
+
+
+
+bool
+DkWxImgszApp::OnInit()
+{
+ wxChar const * const *lt = NULL; /* Localized texts. */
+ DkWxImgszFrame *frame = NULL;
+ wxZipFSHandler *phZipFs = NULL;
+ bool back = false;
+
+
+#line 341 "DkWxImgszApp.cpt"
+
+ /* Initialize elements.
+ */
+ pHelper = NULL;
+ pHelpController = NULL;
+
+ /* Get elements.
+ */
+ pHelper =
+ new DkWxAppHelper(argv[0], wximgsz_default_texts[0], wximgsz_group_name);
+ if (NULL == pHelper) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ if (!(pHelper->checkSetup())) {
+ goto finished;
+ }
+ lt =
+ pHelper->getStringTable(wximgsz_default_texts, wximgsz_string_table_name);
+ if (NULL == lt) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ /* Add image and zip fs handler.
+ */
+ wxInitAllImageHandlers();
+ phZipFs = new wxZipFSHandler();
+ if (NULL != phZipFs) {
+ wxFileSystem::AddHandler(phZipFs);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ /* Get help controller
+ */
+ pHelpController =
+ new DkWxHelpController(pHelper, wximgsz_chm_helpfile, wximgsz_htb_helpfile);
+ if (NULL == pHelpController) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ /* Create frame.
+ */
+ frame = new DkWxImgszFrame(
+ wximgsz_default_texts[0], lt, pHelper, pHelpController,
+ DkWxImgsz_MainWindow, argc, argv
+ );
+ if (NULL == frame) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ /* Show frame and indicate success.
+ */
+ frame->Show();
+ frame->restorePosition();
+ back = true;
+
+ finished:
+ if (!(back)) {
+ if (NULL != pHelpController) {
+ delete(pHelpController);
+ pHelpController = NULL;
+ }
+ if (NULL != pHelper) {
+ delete(pHelper);
+ pHelper = NULL;
+ }
+ }
+ return back;
+}
+
+
+
+int
+DkWxImgszApp::OnExit()
+{
+ int back = 0;
+ if(pHelpController) {
+ delete(pHelpController); pHelpController = NULL;
+ }
+ if(pHelper) {
+ delete(pHelper); pHelper = NULL;
+ }
+
+
+#line 429 "DkWxImgszApp.cpt"
+ return back;
+}
+
+
+
+void
+DkWxImgszApp::ShowMemoryErrorMessage(void)
+{
+ const wxChar *s_title = NULL;
+ const wxChar *s_text = NULL;
+
+ if (NULL != pHelper) {
+ s_title = pHelper->getBasicString(3);
+ s_text = pHelper->getBasicString(9);
+ }
+ if (NULL == s_title) {
+ s_title = wximgsz_nl_wx[0];
+ }
+ if (NULL == s_text) {
+ s_text = wximgsz_nl_wx[1];
+ }
+ wxMessageBox(s_text, s_title, (wxOK | wxCENTRE | wxICON_ERROR));
+}
+
diff --git a/support/dktools/DkWxImgszApp.cpt b/support/dktools/DkWxImgszApp.cpt
new file mode 100644
index 0000000000..d950f74fc0
--- /dev/null
+++ b/support/dktools/DkWxImgszApp.cpt
@@ -0,0 +1,452 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+%% header
+
+
+
+/** Application class for the wximgsz program.
+*/
+class DkWxImgszApp : public wxApp
+{
+ protected:
+ /** Application helper.
+ */
+ DkWxAppHelper *pHelper;
+
+ /** Controller for online-help.
+ */
+ DkWxHelpController *pHelpController;
+
+ protected:
+
+ /** Show error message if there is not sufficient memory available.
+ */
+ void
+ ShowMemoryErrorMessage(void);
+
+ public:
+ /** Initialize application.
+ @return True on success (can run), false on error (abort).
+ */
+ virtual bool OnInit();
+
+ /** Clean up after running.
+ @return Exit status code.
+ */
+ virtual int OnExit();
+};
+
+DECLARE_APP(DkWxImgszApp)
+
+
+%% module
+
+
+#include "wximgsz.h"
+
+
+
+$!trace-include
+
+
+
+IMPLEMENT_APP(DkWxImgszApp)
+
+
+
+/** Application group name.
+*/
+static dkChar const wximgsz_group_name[] = { dkT("dktools") };
+
+
+
+/** File name for string table.
+*/
+static dkChar const wximgsz_string_table_name[] = { dkT("wximgsz.str") };
+
+
+
+/** Help file name on Windows.
+*/
+static wxChar const wximgsz_chm_helpfile[] = {
+ wxT("wximgsz.chm")
+};
+
+
+
+/** Help file name for other platforms.
+*/
+static wxChar const wximgsz_htb_helpfile[] = {
+ wxT("wximgsz.htb")
+};
+
+
+
+/** Default texts to use if no localized texts are found.
+*/
+static wxChar const * const wximgsz_default_texts[] = {
+$!string-table macro=wxT
+#
+# 0 Program name.
+#
+wximgsz
+#
+# 1 Menu name: File
+#
+File
+#
+# 2 Menu item: File => Exit
+#
+Exit
+#
+# 3 Data grid column head: Width
+#
+Width
+#
+# 4 Data grid column head: Height
+#
+Height
+#
+# 5 Data grid column head: Factor
+#
+Factor
+#
+# 6 Label text: Original image
+#
+Original image
+#
+# 7 Label text: Results
+#
+Results
+#
+# 8 Label text: Width:
+#
+Width:
+#
+# 9 Label text: Height:
+#
+Height:
+#
+# 10 Label text: Intended change
+#
+Intended change
+#
+# 11 Label text: Action:
+#
+Action:
+#
+# 12 Choice: Decrease image
+#
+Decrease image
+#
+# 13 Choice: Width range
+#
+Width range
+#
+# 14 Choice: Height range
+#
+Height range
+#
+# 15 Label: Minimum:
+#
+Minimum:
+#
+# 16 Label: Maximum:
+#
+Maximum:
+#
+# 17 Button label: Run
+#
+>>>
+#
+# 18 Empty text for initial status
+#
+
+#
+# 19 Tooltip: Exit the application
+#
+Exit the application
+#
+# 20 Tooltip: Specify original image width
+#
+Enter original image width (positive integer number).
+#
+# 21 Tooltip: Specify original image height
+#
+Enter original image height (positive integer number).
+#
+# 22 Tooltip: Choose type of modification
+#
+Choose modification action.
+#
+# 23 Tooltip: Specify intended minimum for image width or height
+#
+Inter intended minimum for image width or height (positive integer number).
+#
+# 24 Tooltip: Specify intended maximum for image width or height
+#
+Enter intended maximum for image width or height (positive integer number).
+#
+# 25 Tooltip: Calculate new image sizes
+#
+Calculate new image sizes.
+#
+# 26 Spaces to initialize text fields
+#
+
+#
+# 27 Menu: Help
+#
+Help
+#
+# 28 Menu item: Contents
+#
+Contents
+#
+# 29 Menu item: About
+#
+About...
+#
+# 30 Menu tip: Open table of contents
+#
+Open table of contents
+#
+# 31 Menu tip: Show version number dialog box
+#
+Show version number dialog box
+#
+# 32 Error message title: Incorrect input
+#
+Incorrect input
+#
+# 33 Error message text: Please enter a postivie integer number.
+#
+Please enter a positive integer number.
+#
+# 34 Status message: No results found!
+#
+No results found!
+#
+# 35
+#
+About wximgsz
+#
+# 36 Indicator for best quality
+#
+++
+#
+# 37 Indicator for good quality
+#
++
+#
+# 38 Menu: Extras
+#
+Extras
+#
+# 39 Menu item: Options
+#
+Options
+#
+# 40 Tip: Set options
+#
+Set options
+#
+# 41 Dialog box title: Options
+#
+Options
+#
+# 42 Checkbox text: Choose background color by scale factor quality
+#
+Background colour for scale factor
+#
+# 43 Tooltip text: Indicate scale factor quality by background colour.
+#
+Indicate scale factor quality by background colour (otherwise in extra column).
+#
+# 44 Button: OK
+#
+OK
+#
+# 45 Button: Cancel
+#
+Cancel
+#
+# 46 Tool tip text: Apply settings and exit dialog.
+#
+Apply settings and exit dialog.
+#
+# 47 Tool tip text: Skip settings and exit dialog.
+#
+Skip settings and exit dialog.
+#
+# 48
+#
+Choose input bitmap image to open
+#
+# 49
+#
+Open Alt-O
+#
+# 50
+#
+Retrieve dimensions from bitmap image file.
+#
+# 51
+#
+Failed to load image file!\nFile probably damaged or not a supported image type.
+#
+# 52
+#
+Failed to load image!
+#
+# 53
+#
+\n
+#
+# 54
+#
+This program uses libraries from the following projects:\n
+#
+# 55
+#
+See:\n
+$!end
+};
+
+
+
+/** Constant texts, not localized.
+*/
+static wxChar const * const wximgsz_nl_wx[] = {
+$!string-table macro=wxT
+Error
+Not enough memory (RAM)!
+$!end
+};
+
+
+
+bool
+DkWxImgszApp::OnInit()
+{
+ wxChar const * const *lt = NULL; /* Localized texts. */
+ DkWxImgszFrame *frame = NULL;
+ wxZipFSHandler *phZipFs = NULL;
+ bool back = false;
+ $!trace-init wximgsz.deb
+
+ /* Initialize elements.
+ */
+ pHelper = NULL;
+ pHelpController = NULL;
+
+ /* Get elements.
+ */
+ pHelper =
+ new DkWxAppHelper(argv[0], wximgsz_default_texts[0], wximgsz_group_name);
+ if (NULL == pHelper) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ if (!(pHelper->checkSetup())) {
+ goto finished;
+ }
+ lt =
+ pHelper->getStringTable(wximgsz_default_texts, wximgsz_string_table_name);
+ if (NULL == lt) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ /* Add image and zip fs handler.
+ */
+ wxInitAllImageHandlers();
+ phZipFs = new wxZipFSHandler();
+ if (NULL != phZipFs) {
+ wxFileSystem::AddHandler(phZipFs);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ /* Get help controller
+ */
+ pHelpController =
+ new DkWxHelpController(pHelper, wximgsz_chm_helpfile, wximgsz_htb_helpfile);
+ if (NULL == pHelpController) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ /* Create frame.
+ */
+ frame = new DkWxImgszFrame(
+ wximgsz_default_texts[0], lt, pHelper, pHelpController,
+ DkWxImgsz_MainWindow, argc, argv
+ );
+ if (NULL == frame) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ /* Show frame and indicate success.
+ */
+ frame->Show();
+ frame->restorePosition();
+ back = true;
+
+ finished:
+ if (!(back)) {
+ if (NULL != pHelpController) {
+ delete(pHelpController);
+ pHelpController = NULL;
+ }
+ if (NULL != pHelper) {
+ delete(pHelper);
+ pHelper = NULL;
+ }
+ }
+ return back;
+}
+
+
+
+int
+DkWxImgszApp::OnExit()
+{
+ int back = 0;
+ if(pHelpController) {
+ delete(pHelpController); pHelpController = NULL;
+ }
+ if(pHelper) {
+ delete(pHelper); pHelper = NULL;
+ }
+ $!trace-end
+ return back;
+}
+
+
+
+void
+DkWxImgszApp::ShowMemoryErrorMessage(void)
+{
+ const wxChar *s_title = NULL;
+ const wxChar *s_text = NULL;
+
+ if (NULL != pHelper) {
+ s_title = pHelper->getBasicString(3);
+ s_text = pHelper->getBasicString(9);
+ }
+ if (NULL == s_title) {
+ s_title = wximgsz_nl_wx[0];
+ }
+ if (NULL == s_text) {
+ s_text = wximgsz_nl_wx[1];
+ }
+ wxMessageBox(s_text, s_title, (wxOK | wxCENTRE | wxICON_ERROR));
+}
+
diff --git a/support/dktools/DkWxImgszApp.h b/support/dktools/DkWxImgszApp.h
new file mode 100644
index 0000000000..f1e6d14b9b
--- /dev/null
+++ b/support/dktools/DkWxImgszApp.h
@@ -0,0 +1,84 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxImgszApp.cpt
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxImgszApp.h Header file for the DkWxImgszApp module.
+*/
+
+#ifndef DKWXIMGSZAPP_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DKWXIMGSZAPP_H_INCLUDED 1
+
+
+#line 8 "DkWxImgszApp.cpt"
+
+
+
+/** Application class for the wximgsz program.
+*/
+class DkWxImgszApp : public wxApp
+{
+ protected:
+ /** Application helper.
+ */
+ DkWxAppHelper *pHelper;
+
+ /** Controller for online-help.
+ */
+ DkWxHelpController *pHelpController;
+
+ protected:
+
+ /** Show error message if there is not sufficient memory available.
+ */
+ void
+ ShowMemoryErrorMessage(void);
+
+ public:
+ /** Initialize application.
+ @return True on success (can run), false on error (abort).
+ */
+ virtual bool OnInit();
+
+ /** Clean up after running.
+ @return Exit status code.
+ */
+ virtual int OnExit();
+};
+
+DECLARE_APP(DkWxImgszApp)
+
+
+
+#endif
diff --git a/support/dktools/DkWxImgszFrame.cpp b/support/dktools/DkWxImgszFrame.cpp
new file mode 100644
index 0000000000..07267945fa
--- /dev/null
+++ b/support/dktools/DkWxImgszFrame.cpp
@@ -0,0 +1,1075 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxImgszFrame.wxc
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxImgszFrame.cpp The DkWxImgszFrame module.
+*/
+
+
+#line 374 "DkWxImgszFrame.wxc"
+
+#include "wximgsz.h"
+#include "dkicon.xpm"
+#include "dk4verswx.h"
+#include "run2.xpm"
+
+
+
+#line 381 "DkWxImgszFrame.wxc"
+
+
+
+/** Event table for the DkWxImgszFrame class.
+*/
+BEGIN_EVENT_TABLE(DkWxImgszFrame, wxFrame)
+ EVT_MENU(DkWxImgsz_Quit, DkWxImgszFrame::OnQuit)
+ EVT_MENU(DkWxImgsz_Help, DkWxImgszFrame::OnHelp)
+ EVT_MENU(DkWxImgsz_About, DkWxImgszFrame::OnAbout)
+ EVT_MENU(DkWxImgsz_Options, DkWxImgszFrame::OnOptions)
+ EVT_MENU(DkWxImgsz_Open, DkWxImgszFrame::OnOpen)
+ EVT_BUTTON(DkWxImgsz_Run, DkWxImgszFrame::OnRun)
+ EVT_CHOICE(DkWxImgsz_Choice, DkWxImgszFrame::OnChoice)
+END_EVENT_TABLE()
+
+
+
+
+#line 399 "DkWxImgszFrame.wxc"
+
+DkWxImgszFrame::DkWxImgszFrame(
+ wxChar const *applicationName,
+ wxChar const * const *localizedMessages,
+ DkWxAppHelper *applicationHelper,
+ DkWxHelpController *helpController,
+ int wxid,
+ int argc,
+ wxChar **argv
+) : DkWxFrame(applicationName, applicationHelper, helpController, wxid),
+ cRed(255, 91, 91),
+ cNotSoDarkRed(127, 0, 0),
+ cGreen(127, 255, 127),
+ cBlack(0, 0, 0),
+ cDarkRed(63, 0, 0),
+ cYellow(255, 255, 0),
+ sCurrentDir(wxT(""))
+{
+ /*
+ Icon for main window.
+ */
+#if defined(__WXMSW__)
+ wxIcon dkicon_bitmap(wxT("aaaaa"));
+#else
+ wxIcon dkicon_bitmap(xpm_dkicon);
+#endif
+ wxIcon run2_bitmap(xpm_run2);
+ fdx = -1; fdy = -1;
+ odx = -1; ody = -1;
+ sTexts = localizedMessages;
+ wxString saAction[] = {
+ wxString(localizedMessages[12]),
+ wxString(localizedMessages[13]),
+ wxString(localizedMessages[14])
+ };
+ bUseColour = true;
+ dkctGUILayoutOK = false;
+ dkctGUIContentsPanel = NULL;
+ mbMain = NULL;
+ mainSizer = NULL;
+ mFile = NULL;
+ mExtras = NULL;
+ mHelp = NULL;
+ miOpen = NULL;
+ miExit = NULL;
+ miOptions = NULL;
+ miHelpContents = NULL;
+ miHelpAbout = NULL;
+ horizontalSizer = NULL;
+ statusSizer = NULL;
+ inputDataSizer = NULL;
+ bCalculate = NULL;
+ outputDataSizer = NULL;
+ lOriginalImage = NULL;
+ lWidth = NULL;
+ tWidth = NULL;
+ lHeight = NULL;
+ tHeight = NULL;
+ lChangeType = NULL;
+ lAction = NULL;
+ cbAction = NULL;
+ lMinimum = NULL;
+ tMinimum = NULL;
+ lMaximum = NULL;
+ tMaximum = NULL;
+ lResults = NULL;
+ dataGrid = NULL;
+ lStatus = NULL;
+ dkctGUIContentsPanel = new wxPanel(this);
+ if(!(dkctGUIContentsPanel)) {
+ goto dkctGUILayoutFinished;
+ }
+#if wxUSE_MENUS
+ mbMain = new wxMenuBar(
+ );
+ if(!(mbMain)) {
+ goto dkctGUILayoutFinished;
+ }
+ mFile = new wxMenu(
+ );
+ if(!(mFile)) {
+ goto dkctGUILayoutFinished;
+ }
+ miOpen = mFile->Append(
+ DkWxImgsz_Open,
+ sTexts[49],
+ sTexts[50]
+ );
+ if(!(miOpen)) {
+ goto dkctGUILayoutFinished;
+ }
+ miExit = mFile->Append(
+ DkWxImgsz_Quit,
+ sTexts[2],
+ sTexts[19]
+ );
+ if(!(miExit)) {
+ goto dkctGUILayoutFinished;
+ }
+ mbMain->Append(mFile, sTexts[1]);
+ mExtras = new wxMenu(
+ );
+ if(!(mExtras)) {
+ goto dkctGUILayoutFinished;
+ }
+ miOptions = mExtras->Append(
+ DkWxImgsz_Options,
+ sTexts[39],
+ sTexts[40]
+ );
+ if(!(miOptions)) {
+ goto dkctGUILayoutFinished;
+ }
+ mbMain->Append(mExtras, sTexts[38]);
+ mHelp = new wxMenu(
+ );
+ if(!(mHelp)) {
+ goto dkctGUILayoutFinished;
+ }
+ miHelpContents = mHelp->Append(
+ DkWxImgsz_Help,
+ sTexts[28],
+ sTexts[30]
+ );
+ if(!(miHelpContents)) {
+ goto dkctGUILayoutFinished;
+ }
+ miHelpAbout = mHelp->Append(
+ DkWxImgsz_About,
+ sTexts[29],
+ sTexts[31]
+ );
+ if(!(miHelpAbout)) {
+ goto dkctGUILayoutFinished;
+ }
+ mbMain->Append(mHelp, sTexts[27]);
+ SetMenuBar(mbMain);
+#endif
+ mainSizer = new wxBoxSizer(
+ wxVERTICAL
+ );
+ if(!(mainSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ mainSizer->Add(10, 10, 0);
+ horizontalSizer = new wxBoxSizer(
+ wxHORIZONTAL
+ );
+ if(!(horizontalSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ horizontalSizer->Add(10, 10, 0);
+ inputDataSizer = new wxGridBagSizer(
+ 5, 5
+ );
+ if(!(inputDataSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ lOriginalImage = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[6]
+ );
+ if(!(lOriginalImage)) {
+ goto dkctGUILayoutFinished;
+ }
+ inputDataSizer->Add(
+ lOriginalImage,
+ wxGBPosition(0, 0),
+ wxGBSpan(1, 2),
+ wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL
+ );
+ lWidth = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[8]
+ );
+ if(!(lWidth)) {
+ goto dkctGUILayoutFinished;
+ }
+ inputDataSizer->Add(
+ lWidth,
+ wxGBPosition(1, 0),
+ wxGBSpan(1, 1),
+ wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL
+ );
+ tWidth = new wxTextCtrl(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[26]
+ );
+ if(!(tWidth)) {
+ goto dkctGUILayoutFinished;
+ }
+ tWidth->SetToolTip(sTexts[20]);
+ inputDataSizer->Add(
+ tWidth,
+ wxGBPosition(1, 1),
+ wxGBSpan(1, 1),
+ wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL
+ );
+ lHeight = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[9]
+ );
+ if(!(lHeight)) {
+ goto dkctGUILayoutFinished;
+ }
+ inputDataSizer->Add(
+ lHeight,
+ wxGBPosition(2, 0),
+ wxGBSpan(1, 1),
+ wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL
+ );
+ tHeight = new wxTextCtrl(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[26]
+ );
+ if(!(tHeight)) {
+ goto dkctGUILayoutFinished;
+ }
+ tHeight->SetToolTip(sTexts[21]);
+ inputDataSizer->Add(
+ tHeight,
+ wxGBPosition(2, 1),
+ wxGBSpan(1, 1),
+ wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL
+ );
+ inputDataSizer->Add(10, 10, wxGBPosition(3, 0), wxGBSpan(1, 1));
+ lChangeType = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[10]
+ );
+ if(!(lChangeType)) {
+ goto dkctGUILayoutFinished;
+ }
+ inputDataSizer->Add(
+ lChangeType,
+ wxGBPosition(4, 0),
+ wxGBSpan(1, 2),
+ wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL
+ );
+ lAction = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[11]
+ );
+ if(!(lAction)) {
+ goto dkctGUILayoutFinished;
+ }
+ inputDataSizer->Add(
+ lAction,
+ wxGBPosition(5, 0),
+ wxGBSpan(1, 1),
+ wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL
+ );
+ cbAction = new wxChoice(
+ dkctGUIContentsPanel,
+ DkWxImgsz_Choice,
+ wxDefaultPosition,
+ wxDefaultSize,
+ 3,
+ saAction
+ );
+ if(!(cbAction)) {
+ goto dkctGUILayoutFinished;
+ }
+ cbAction->SetToolTip(sTexts[22]);
+ inputDataSizer->Add(
+ cbAction,
+ wxGBPosition(5, 1),
+ wxGBSpan(1, 1),
+ wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL
+ );
+ lMinimum = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[15]
+ );
+ if(!(lMinimum)) {
+ goto dkctGUILayoutFinished;
+ }
+ inputDataSizer->Add(
+ lMinimum,
+ wxGBPosition(6, 0),
+ wxGBSpan(1, 1),
+ wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL
+ );
+ tMinimum = new wxTextCtrl(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[26]
+ );
+ if(!(tMinimum)) {
+ goto dkctGUILayoutFinished;
+ }
+ tMinimum->SetToolTip(sTexts[23]);
+ inputDataSizer->Add(
+ tMinimum,
+ wxGBPosition(6, 1),
+ wxGBSpan(1, 1),
+ wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL
+ );
+ lMaximum = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[16]
+ );
+ if(!(lMaximum)) {
+ goto dkctGUILayoutFinished;
+ }
+ inputDataSizer->Add(
+ lMaximum,
+ wxGBPosition(7, 0),
+ wxGBSpan(1, 1),
+ wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL
+ );
+ tMaximum = new wxTextCtrl(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[26]
+ );
+ if(!(tMaximum)) {
+ goto dkctGUILayoutFinished;
+ }
+ tMaximum->SetToolTip(sTexts[24]);
+ inputDataSizer->Add(
+ tMaximum,
+ wxGBPosition(7, 1),
+ wxGBSpan(1, 1),
+ wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL
+ );
+ horizontalSizer->Add(
+ inputDataSizer,
+ 0,
+ wxALIGN_LEFT|wxALIGN_TOP
+ );
+ horizontalSizer->Add(10, 10, 0);
+ bCalculate = new wxBitmapButton(
+ dkctGUIContentsPanel,
+ DkWxImgsz_Run,
+ run2_bitmap
+ );
+ if(!(bCalculate)) {
+ goto dkctGUILayoutFinished;
+ }
+ bCalculate->SetToolTip(sTexts[25]);
+ horizontalSizer->Add(
+ bCalculate,
+ 0,
+ wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL
+ );
+ horizontalSizer->Add(10, 10, 0);
+ outputDataSizer = new wxGridBagSizer(
+ 5, 5
+ );
+ if(!(outputDataSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ lResults = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[7]
+ );
+ if(!(lResults)) {
+ goto dkctGUILayoutFinished;
+ }
+ outputDataSizer->Add(
+ lResults,
+ wxGBPosition(0, 0),
+ wxGBSpan(1, 2),
+ wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL
+ );
+ dataGrid = new wxGrid(
+ dkctGUIContentsPanel,
+ wxID_ANY
+ );
+ if(!(dataGrid)) {
+ goto dkctGUILayoutFinished;
+ }
+ dataGrid->CreateGrid(16, 4);
+ dataGrid->SetColLabelValue(0, sTexts[3]);
+ dataGrid->SetColLabelValue(1, sTexts[4]);
+ dataGrid->SetColLabelValue(2, sTexts[5]);
+ dataGrid->SetColLabelValue(3, sTexts[18]);
+ dataGrid->EnableEditing(false);
+ dataGrid->SetMinSize(wxSize(300, 200));
+ outputDataSizer->Add(
+ dataGrid,
+ wxGBPosition(1, 0),
+ wxGBSpan(2, 2),
+ wxALIGN_LEFT|wxALIGN_TOP|wxGROW
+ );
+ outputDataSizer->AddGrowableRow(2);
+ outputDataSizer->AddGrowableCol(1);
+ horizontalSizer->Add(
+ outputDataSizer,
+ 1,
+ wxALIGN_LEFT|wxALIGN_TOP|wxGROW
+ );
+ horizontalSizer->Add(10, 10, 0);
+ mainSizer->Add(
+ horizontalSizer,
+ 1,
+ wxGROW
+ );
+ mainSizer->Add(10, 10, 0);
+ statusSizer = new wxBoxSizer(
+ wxHORIZONTAL
+ );
+ if(!(statusSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ statusSizer->Add(10, 10, 0);
+ lStatus = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[18]
+ );
+ if(!(lStatus)) {
+ goto dkctGUILayoutFinished;
+ }
+ statusSizer->Add(
+ lStatus
+ );
+ statusSizer->Add(10, 10, 0);
+ mainSizer->Add(
+ statusSizer
+ );
+ mainSizer->Add(10, 10, 0);
+ dkctGUIContentsPanel->SetSizer(mainSizer);
+ SetIcon(dkicon_bitmap);
+ dkctGUILayoutOK = true;
+ dkctGUILayoutFinished:
+ if(dkctGUILayoutOK) {
+ mainSizer->Fit(this);
+ mainSizer->SetSizeHints(this);
+ }
+
+#line 436 "DkWxImgszFrame.wxc"
+ if (lOriginalImage) {
+ lOriginalImage->SetForegroundColour(cNotSoDarkRed);
+ }
+ if (lChangeType) {
+ lChangeType->SetForegroundColour(cNotSoDarkRed);
+ }
+ if (lResults) {
+ lResults->SetForegroundColour(cNotSoDarkRed);
+ }
+ SetTitle(localizedMessages[0]);
+#if 0
+ restorePosition();
+#endif
+ restoreData();
+ enableDisableMinimumMaximum();
+}
+
+
+#line 454 "DkWxImgszFrame.wxc"
+
+void
+DkWxImgszFrame::OnHelp(wxCommandEvent& WXUNUSED(event))
+{
+ openHelp();
+}
+
+
+static wxChar const wximgsz_version[] = {
+ wxT("wximgsz (part of dktools-")
+};
+
+static wxChar const wximgsz_versnumber[] = {
+ DKT_VERSION_WX
+};
+
+static wxChar const wximgsz_versend[] = {
+ wxT(")")
+};
+void
+DkWxImgszFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
+{
+ wxString sVersion(wximgsz_version);
+ sVersion.Append(wximgsz_versnumber);
+ sVersion.Append(wximgsz_versend);
+ sVersion.Append(sTexts[53]);
+ sVersion.Append(wxT("Copyright (c) 2013-2016 Dirk Krause"));
+ sVersion.Append(sTexts[53]);
+ sVersion.Append(sTexts[53]);
+ sVersion.Append(sTexts[54]);
+ sVersion.Append(wxT("DK tools, wxWidgets, libpng, libjpeg, libtiff, zlib."));
+ sVersion.Append(sTexts[53]);
+ sVersion.Append(sTexts[53]);
+ sVersion.Append(sTexts[55]);
+ sVersion.Append(wxT("http://dktools.sourceforge.net\n"));
+ sVersion.Append(wxT("http://www.wxwidgets.org\n"));
+ sVersion.Append(wxT("http://www.libpng.org/pub/png/libpng.html\n"));
+ sVersion.Append(wxT("http://www.ijg.org\n"));
+ sVersion.Append(wxT("http://www.remotesensing.org/libtiff\n"));
+ sVersion.Append(wxT("http://www.zlib.org"));
+ wxMessageBox(sVersion, sTexts[35]);
+}
+
+
+void
+DkWxImgszFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
+{
+
+
+#line 502 "DkWxImgszFrame.wxc"
+ Show(false);
+ Close();
+
+
+#line 505 "DkWxImgszFrame.wxc"
+}
+
+
+
+void
+DkWxImgszFrame::OnOpen(wxCommandEvent& WXUNUSED(event))
+{
+ wxString s(wxT(""));
+
+
+#line 514 "DkWxImgszFrame.wxc"
+ s.Append(wxT("BMP files (*.bmp)|*.bmp"));
+ s.Append(wxT("|PNG files (*.png)|*.png"));
+ s.Append(wxT("|JPEG files (*.jpg)|*.jpg|JPEG files (*.jpeg)|*.jpeg"));
+ s.Append(wxT("|TIFF files (*.tif)|*.tif|TIFF files (*.tiff)|*.tiff"));
+ s.Append(wxT("|XPM files (*.xpm)|*.xpm"));
+ s.Append(wxT("|All files (*.*)|*.*"));
+#if wxCHECK_VERSION(2, 9, 0)
+ wxFileDialog dlg(this, sTexts[48], sCurrentDir, wxT(""), s, wxFD_OPEN);
+#else
+ wxFileDialog dlg(this, sTexts[48], sCurrentDir, wxT(""), s, wxOPEN);
+#endif
+ pHelper->setRelatedPosition(this, &dlg, &fdx, &fdy);
+ if(wxID_OK == dlg.ShowModal()) {
+ wxString path = dlg.GetPath();
+ wxImage img;
+ if(img.LoadFile(path)) {
+ int w = img.GetWidth();
+ int h = img.GetHeight();
+ if((w > 0) && (h > 0)) {
+ wxString sWidth;
+ wxString sHeight;
+ sWidth.Printf(wxT("%d"), w);
+ sHeight.Printf(wxT("%d"), h);
+ if((tWidth) && (tHeight)) {
+ tWidth->SetValue(sWidth);
+ tHeight->SetValue(sHeight);
+ Refresh();
+ Update();
+ run(false);
+ }
+ } else {
+ /* ERROR: Illegal image dimensions! */
+ wxMessageBox(sTexts[51], sTexts[52], (wxOK | wxICON_ERROR), this);
+ }
+ } else {
+ /* ERROR: Failed to load file! */
+ wxMessageBox(sTexts[51], sTexts[52], (wxOK | wxICON_ERROR), this);
+ }
+ }
+ dlg.GetPosition(&fdx, &fdy);
+
+
+#line 555 "DkWxImgszFrame.wxc"
+}
+
+
+
+void
+DkWxImgszFrame::OnOptions(wxCommandEvent& WXUNUSED(event))
+{
+
+
+#line 563 "DkWxImgszFrame.wxc"
+ DkWxImgszOptionsDialog dlg(this, sTexts[41], sTexts);
+ pHelper->setRelatedPosition(this, &dlg, &odx, &ody);
+ dlg.SetValue(bUseColour);
+ if(dlg.ShowModal() == wxID_OK) {
+ bUseColour = dlg.GetValue();
+ }
+ dlg.GetPosition(&odx, &ody);
+
+
+#line 571 "DkWxImgszFrame.wxc"
+}
+
+
+void
+DkWxImgszFrame::run(bool bShowErrors)
+{
+ long w = 0L;
+ long h = 0L;
+ long min = 0L;
+ long max = 0L;
+ int action = 0;
+
+
+#line 583 "DkWxImgszFrame.wxc"
+ w = getTextCtrlContents(tWidth, bShowErrors);
+ if(w > 0L) {
+ h = getTextCtrlContents(tHeight, bShowErrors);
+ if(h > 0L) {
+ switch((action = cbAction->GetCurrentSelection())) {
+ case 2: {
+ min = getTextCtrlContents(tMinimum, bShowErrors);
+ if(min > 0L) {
+ max = getTextCtrlContents(tMaximum, bShowErrors);
+ }
+ } break;
+ case 1: {
+ min = getTextCtrlContents(tMinimum, bShowErrors);
+ if(min > 0L) {
+ max = getTextCtrlContents(tMaximum, bShowErrors);
+ }
+ } break;
+ default: {
+ min = 1L; max = w; action = 1;
+ } break;
+ }
+ if((w > 0L) && (h > 0L) && (min > 0L) && (max > 0L)) {
+ switch(action) {
+ case 2: {
+ runForNumbers(h, w, min, max, 1);
+ } break;
+ default: {
+ runForNumbers(w, h, min, max, 0);
+ } break;
+ }
+ }
+ }
+ }
+
+
+#line 617 "DkWxImgszFrame.wxc"
+}
+
+
+
+void
+DkWxImgszFrame::OnRun(wxCommandEvent& WXUNUSED(event))
+{
+
+
+#line 625 "DkWxImgszFrame.wxc"
+ run(true);
+
+
+#line 627 "DkWxImgszFrame.wxc"
+}
+
+
+
+DkWxImgszFrame::~DkWxImgszFrame()
+{
+}
+
+
+
+bool
+DkWxImgszFrame::canClose(bool isLast)
+{
+
+
+#line 641 "DkWxImgszFrame.wxc"
+ if(isLast) {
+ saveData();
+ }
+
+#line 644 "DkWxImgszFrame.wxc"
+ return true;
+}
+
+
+
+static wxChar const * const wximgsz_keys[] = {
+/* 0 */
+wxT("wximgsz.width"),
+
+/* 1 */
+wxT("wximgsz.height"),
+
+/* 2 */
+wxT("wximgsz.selection"),
+
+/* 3 */
+wxT("wximgsz.minimum"),
+
+/* 4 */
+wxT("wximgsz.maximum"),
+
+/* 5 */
+wxT("wximgsz.colours"),
+
+NULL
+
+
+#line 658 "DkWxImgszFrame.wxc"
+};
+
+void
+DkWxImgszFrame::saveData()
+{
+ long i[] = {
+ 0L, // Width
+ 0L, // Height
+ 0L, // Selection
+ 0L, // Minimum
+ 0L, // Maximum
+ 0L // bUseColour
+ };
+ long l;
+ if((tWidth->GetValue()).ToLong(&l)) {
+ i[0] = l;
+ }
+ if((tHeight->GetValue()).ToLong(&l)) {
+ i[1] = l;
+ }
+ i[2] = (long)(cbAction->GetCurrentSelection());
+ if(i[2] < 0L) i[2] = 0L;
+ if((tMinimum->GetValue()).ToLong(&l)) {
+ i[3] = l;
+ }
+ if((tMaximum->GetValue()).ToLong(&l)) {
+ i[4] = l;
+ }
+ i[5] = ((bUseColour) ? 1L : 0L);
+ if(pHelper) {
+ pHelper->saveMultipleLongs(wximgsz_keys, i);
+ }
+}
+
+
+void
+DkWxImgszFrame::restoreData()
+{
+ wxString sWidth;
+ wxString sHeight;
+ wxString sMinimum;
+ wxString sMaximum;
+ long i[] = {
+ 1024L, // Width
+ 768L, // Height
+ 0L, // Selection
+ 200L, // Minimum
+ 800L, // Maximum
+ 1L // bUseColour
+ };
+ if(pHelper) {
+ pHelper->retrieveMultipleLongs(wximgsz_keys, i);
+ sWidth.Printf(wxT("%ld"), i[0]);
+ sHeight.Printf(wxT("%ld"), i[1]);
+ sMinimum.Printf(wxT("%ld"), i[3]);
+ sMaximum.Printf(wxT("%ld"), i[4]);
+ tWidth->SetValue(sWidth);
+ tHeight->SetValue(sHeight);
+ tMinimum->SetValue(sMinimum);
+ tMaximum->SetValue(sMaximum);
+ cbAction->SetSelection((int)(i[2]));
+ bUseColour = ((i[5]) ? true : false);
+ }
+}
+
+
+
+void
+DkWxImgszFrame::enableDisableMinimumMaximum()
+{
+ if(0 == cbAction->GetCurrentSelection()) {
+ tMinimum->SetEditable(false);
+ tMaximum->SetEditable(false);
+ tMinimum->Enable(false);
+ tMaximum->Enable(false);
+ } else {
+ tMinimum->SetEditable(true);
+ tMaximum->SetEditable(true);
+ tMinimum->Enable(true);
+ tMaximum->Enable(true);
+ }
+}
+
+
+
+void
+DkWxImgszFrame::OnChoice(wxCommandEvent & event)
+{
+ enableDisableMinimumMaximum();
+}
+
+
+
+long
+DkWxImgszFrame::gcd(long aa, long bb)
+{
+ long back = 0L;
+ long h = 0L;
+ long a;
+ long b;
+
+ a = aa;
+ b = bb;
+ while(b > 0L) {
+ h = a % b;
+ a = b;
+ b = h;
+ }
+ back = a;
+ return back;
+}
+
+
+long
+DkWxImgszFrame::getTextCtrlContents(wxTextCtrl *tf, bool bShowErrors)
+{
+ long back = 0L;
+ long l = 0L;
+ if((tf->GetValue()).ToLong(&l)) {
+ back = l;
+ }
+ if(0 >= back) {
+ if(bShowErrors) {
+ tf->SetFocus();
+ wxMessageBox(sTexts[33], sTexts[32], (wxOK | wxICON_ERROR), this);
+ }
+ }
+ return back;
+}
+
+
+
+void
+DkWxImgszFrame::runForNumbers(long w, long h, long min, long max, int inverted)
+{
+ long gd;
+ long w0;
+ long h0;
+ long nw;
+ long nh;
+ long i;
+ long z;
+ long n;
+ long g2;
+ int lineno;
+ int cl;
+ int rows;
+ int found = 0;
+
+ gd = gcd(w, h);
+ if(gd > 0L) {
+ /*
+ Minimum rectangle.
+ */
+ w0 = w / gd;
+ h0 = h / gd;
+ /*
+ Remove all grid lines.
+ */
+ rows = dataGrid->GetNumberRows();
+ dataGrid->DeleteRows(0, rows);
+ /*
+ Build and fill new grid.
+ */
+ lineno = 0;
+ i = 1;
+ lStatus->SetForegroundColour(cBlack);
+ lStatus->SetLabel(sTexts[18]);
+ while((i * w0) <= max) {
+ if((i * w0) >= min) {
+ found = 1;
+ nw = i * w0;
+ nh = i * h0;
+ /* Classify factor. */
+ cl = classifyFactor(nw, w);
+ g2 = gcd(nw, w);
+ z = nw / g2; n = w / g2;
+ dataGrid->AppendRows(1);
+ dataGrid->SetCellTextColour(lineno, 0, cBlack);
+ dataGrid->SetCellTextColour(lineno, 1, cBlack);
+ dataGrid->SetCellTextColour(lineno, 2, cBlack);
+ switch(cl) {
+ case 2: {
+ if(bUseColour) {
+ dataGrid->SetCellBackgroundColour(lineno, 2, cGreen);
+ } else {
+ dataGrid->SetCellValue(lineno, 3, sTexts[36]);
+ }
+ } break;
+ case 1: {
+ if(bUseColour) {
+ dataGrid->SetCellBackgroundColour(lineno, 2, cYellow);
+ } else {
+ dataGrid->SetCellValue(lineno, 3, sTexts[37]);
+ }
+ } break;
+ default: {
+ if(bUseColour) {
+ dataGrid->SetCellBackgroundColour(lineno, 2, cRed);
+ } else {
+ dataGrid->SetCellValue(lineno, 3, wxT(""));
+ }
+ } break;
+ }
+ if(bUseColour) {
+ dataGrid->SetCellValue(lineno, 3, wxT(""));
+ }
+ {
+ wxString sRowHead;
+ wxString sFactor;
+ wxString sWidth;
+ wxString sHeight;
+
+ sRowHead.Printf(wxT("%d"), (lineno + 1));
+ if(n > 1L) {
+ sFactor.Printf(wxT("%ld / %ld"), z, n);
+ } else {
+ sFactor.Printf(wxT("%ld"), z);
+ }
+ if(inverted) {
+ sWidth.Printf(wxT("%ld"), nh);
+ sHeight.Printf(wxT("%ld"), nw);
+ } else {
+ sWidth.Printf(wxT("%ld"), nw);
+ sHeight.Printf(wxT("%ld"), nh);
+ }
+ dataGrid->SetRowLabelValue(lineno, sRowHead);
+ dataGrid->SetCellValue(lineno, 0, sWidth);
+ dataGrid->SetCellValue(lineno, 1, sHeight);
+ dataGrid->SetCellValue(lineno, 2, sFactor);
+ dataGrid->SetCellAlignment(lineno, 0, wxALIGN_CENTRE, wxALIGN_CENTRE);
+ dataGrid->SetCellAlignment(lineno, 1, wxALIGN_CENTRE, wxALIGN_CENTRE);
+ dataGrid->SetCellAlignment(lineno, 2, wxALIGN_CENTRE, wxALIGN_CENTRE);
+ dataGrid->SetCellAlignment(lineno, 3, wxALIGN_CENTRE, wxALIGN_CENTRE);
+ }
+ lineno++;
+ }
+ i++;
+ }
+ dataGrid->AutoSizeColumns();
+ dataGrid->EnableDragColSize(true);
+ if(0 == found) {
+ lStatus->SetLabel(sTexts[34]);
+ lStatus->SetForegroundColour(cDarkRed);
+ }
+ Refresh();
+ Update();
+ }
+}
+
+
+
+int
+DkWxImgszFrame::classifyFactor(long n, long o)
+{
+ long max;
+ long min;
+ int back = 0;
+ if(n > o) {
+ max = n; min = o;
+ } else {
+ max = o; min = n;
+ }
+ if(max % min) {
+ back = 0;
+ } else {
+ back = 1;
+ max = max / min;
+ if(countBits(max) == 1) {
+ back = 2;
+ }
+ }
+ return back;
+}
+
+
+int
+DkWxImgszFrame::countBits(long v)
+{
+#if DK3_SIZEOF_LONG > 2
+#if DK3_SIZEOF_LONG > 4
+ long bitmask = 0x4000000000000000L;
+ int attempts = 63;
+#else
+ long bitmask = 0x40000000L;
+ int attempts = 31;
+#endif
+#else
+ long bitmask = 0x4000L;
+ int attempts = 15;
+#endif
+ int back = 0;
+
+ while(attempts--) {
+ if(v & bitmask) {
+ back++;
+ }
+ bitmask = bitmask >> 1;
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/DkWxImgszFrame.h b/support/dktools/DkWxImgszFrame.h
new file mode 100644
index 0000000000..a8bb67de5f
--- /dev/null
+++ b/support/dktools/DkWxImgszFrame.h
@@ -0,0 +1,404 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxImgszFrame.wxc
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxImgszFrame.h Header file for the DkWxImgszFrame module.
+*/
+
+#ifndef DKWXIMGSZFRAME_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DKWXIMGSZFRAME_H_INCLUDED 1
+
+
+#line 176 "DkWxImgszFrame.wxc"
+
+
+
+#line 179 "DkWxImgszFrame.wxc"
+
+
+/** Main window class for the wximgsz program.
+*/
+class DkWxImgszFrame : public DkWxFrame
+{
+ private:
+
+ /** Event table.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ /** Localized message texts.
+ */
+ wxChar const * const *sTexts;
+
+ /** Red (used as background color).
+ */
+ wxColour cRed;
+
+ /** Red 127.
+ */
+ wxColour cNotSoDarkRed;
+
+ /** Green (used as background color).
+ */
+ wxColour cGreen;
+
+ /** Black (used as text color).
+ */
+ wxColour cBlack;
+
+ /** Dark red (used as text color).
+ */
+ wxColour cDarkRed;
+
+ /** Yellow (used as background color).
+ */
+ wxColour cYellow;
+
+ /** File dialog x position.
+ */
+ int fdx;
+
+ /** File dialog y position.
+ */
+ int fdy;
+
+ /** Options dialog x position.
+ */
+ int odx;
+
+ /** Options dialog y position.
+ */
+ int ody;
+
+ /** Flag: Use background colors to indicate scale factor quality.
+ */
+ bool bUseColour;
+
+ /** Current directory.
+ */
+ wxString sCurrentDir;
+
+ /** Flag: GUI ok.
+ */
+ bool dkctGUILayoutOK;
+
+ /** Contents panel.
+ */
+ wxPanel *dkctGUIContentsPanel;
+
+ /** GUI element mbMain.
+ */
+#line 15 "DkWxImgszFrame.wxc"
+ wxMenuBar *mbMain;
+
+ /** GUI element mainSizer.
+ */
+#line 59 "DkWxImgszFrame.wxc"
+ wxBoxSizer *mainSizer;
+
+ /** GUI element mFile.
+ */
+#line 20 "DkWxImgszFrame.wxc"
+ wxMenu *mFile;
+
+ /** GUI element mExtras.
+ */
+#line 35 "DkWxImgszFrame.wxc"
+ wxMenu *mExtras;
+
+ /** GUI element mHelp.
+ */
+#line 44 "DkWxImgszFrame.wxc"
+ wxMenu *mHelp;
+
+ /** GUI element miOpen.
+ */
+#line 25 "DkWxImgszFrame.wxc"
+ wxMenuItem *miOpen;
+
+ /** GUI element miExit.
+ */
+#line 30 "DkWxImgszFrame.wxc"
+ wxMenuItem *miExit;
+
+ /** GUI element miOptions.
+ */
+#line 39 "DkWxImgszFrame.wxc"
+ wxMenuItem *miOptions;
+
+ /** GUI element miHelpContents.
+ */
+#line 49 "DkWxImgszFrame.wxc"
+ wxMenuItem *miHelpContents;
+
+ /** GUI element miHelpAbout.
+ */
+#line 54 "DkWxImgszFrame.wxc"
+ wxMenuItem *miHelpAbout;
+
+ /** GUI element horizontalSizer.
+ */
+#line 67 "DkWxImgszFrame.wxc"
+ wxBoxSizer *horizontalSizer;
+
+ /** GUI element statusSizer.
+ */
+#line 166 "DkWxImgszFrame.wxc"
+ wxBoxSizer *statusSizer;
+
+ /** GUI element inputDataSizer.
+ */
+#line 78 "DkWxImgszFrame.wxc"
+ wxGridBagSizer *inputDataSizer;
+
+ /** GUI element bCalculate.
+ */
+#line 137 "DkWxImgszFrame.wxc"
+ wxBitmapButton *bCalculate;
+
+ /** GUI element outputDataSizer.
+ */
+#line 143 "DkWxImgszFrame.wxc"
+ wxGridBagSizer *outputDataSizer;
+
+ /** GUI element lOriginalImage.
+ */
+#line 94 "DkWxImgszFrame.wxc"
+ wxStaticText *lOriginalImage;
+
+ /** GUI element lWidth.
+ */
+#line 97 "DkWxImgszFrame.wxc"
+ wxStaticText *lWidth;
+
+ /** GUI element tWidth.
+ */
+#line 100 "DkWxImgszFrame.wxc"
+ wxTextCtrl *tWidth;
+
+ /** GUI element lHeight.
+ */
+#line 104 "DkWxImgszFrame.wxc"
+ wxStaticText *lHeight;
+
+ /** GUI element tHeight.
+ */
+#line 107 "DkWxImgszFrame.wxc"
+ wxTextCtrl *tHeight;
+
+ /** GUI element lChangeType.
+ */
+#line 111 "DkWxImgszFrame.wxc"
+ wxStaticText *lChangeType;
+
+ /** GUI element lAction.
+ */
+#line 114 "DkWxImgszFrame.wxc"
+ wxStaticText *lAction;
+
+ /** GUI element cbAction.
+ */
+#line 117 "DkWxImgszFrame.wxc"
+ wxChoice *cbAction;
+
+ /** GUI element lMinimum.
+ */
+#line 123 "DkWxImgszFrame.wxc"
+ wxStaticText *lMinimum;
+
+ /** GUI element tMinimum.
+ */
+#line 126 "DkWxImgszFrame.wxc"
+ wxTextCtrl *tMinimum;
+
+ /** GUI element lMaximum.
+ */
+#line 130 "DkWxImgszFrame.wxc"
+ wxStaticText *lMaximum;
+
+ /** GUI element tMaximum.
+ */
+#line 133 "DkWxImgszFrame.wxc"
+ wxTextCtrl *tMaximum;
+
+ /** GUI element lResults.
+ */
+#line 152 "DkWxImgszFrame.wxc"
+ wxStaticText *lResults;
+
+ /** GUI element dataGrid.
+ */
+#line 155 "DkWxImgszFrame.wxc"
+ wxGrid *dataGrid;
+
+ /** GUI element lStatus.
+ */
+#line 171 "DkWxImgszFrame.wxc"
+ wxStaticText *lStatus;
+
+
+#line 246 "DkWxImgszFrame.wxc"
+ public:
+ /** Constructor.
+ */
+ DkWxImgszFrame(
+ wxChar const *applicationName,
+ wxChar const * const *localizedMessages,
+ DkWxAppHelper *applicationHelper,
+ DkWxHelpController *helpController,
+ int wxid,
+ int argc,
+ wxChar **argv
+ );
+
+ /** Destructor.
+ */
+ ~DkWxImgszFrame();
+
+ /** Check whether we can close the window.
+ @param isLast Flag: Last top level window.
+ */
+ bool
+ canClose(bool isLast);
+
+ /** Event handler to open a file.
+ @param event Event to process.
+ */
+ void
+ OnOpen(wxCommandEvent& WXUNUSED(event));
+
+ /** Event handler to quit application.
+ @param event Event to process.
+ */
+ void
+ OnQuit(wxCommandEvent& WXUNUSED(event));
+
+ /** Event handler to show help contents.
+ @param event Event to process.
+ */
+ void
+ OnHelp(wxCommandEvent& WXUNUSED(event));
+
+ /** Event handler to show version number.
+ @param event Event to process.
+ */
+ void
+ OnAbout(wxCommandEvent& WXUNUSED(event));
+
+ /** Event handler: Run calculation.
+ @param event Event to process.
+ */
+ void
+ OnRun(wxCommandEvent& WXUNUSED(event));
+
+ /** Event handler: Choice made.
+ @param event Event to process.
+ */
+ void
+ OnChoice(wxCommandEvent & event);
+
+ /** Event handler to set options.
+ @param event Event to process.
+ */
+ void
+ OnOptions(wxCommandEvent& WXUNUSED(event));
+
+ protected:
+
+ /** Save data entered into text fields.
+ */
+ void saveData();
+
+ /** Restore data entered in text fields.
+ */
+ void restoreData();
+
+ /** Enable/disable the lower text fields depending
+ on the current choice selection.
+ */
+ void
+ enableDisableMinimumMaximum();
+
+ /** Calculate largest common divisor.
+ @param aa One number.
+ @param bb Other number.
+ @return Largest common divisor of aa and bb.
+ */
+ long gcd(long aa, long bb);
+
+ /** Retrieve positive long number from text field.
+ @param tf Text field to process.
+ @param bShowErrors Flag: Show message boxes for errors.
+ @return Positive number on success, 0L on error.
+ */
+ long getTextCtrlContents(wxTextCtrl *tf, bool bShowErrors);
+
+ /** Run calculation.
+ */
+ void
+ run(bool bShowErrors);
+
+ /** Run for a set of numbers.
+ @param w Width (or height, if inverted).
+ @param h Height (or width, if inverted).
+ @param min Minimum value.
+ @param max maximum value.
+ @param inverted Flag: w contains the hight, h the width.
+ */
+ void
+ runForNumbers(long w, long h, long min, long max, int inverted);
+
+ /** Classify factor.
+ @param n New value.
+ @param o Old value.
+ @return 2 for powers of 2, 1 for integer factors, 0 otherwise.
+ */
+ int classifyFactor(long n, long o);
+
+ /** Count bit number in a long value.
+ @param v Value to check.
+ @return Number of bits set.
+ */
+ int countBits(long v);
+};
+
+
+#line 371 "DkWxImgszFrame.wxc"
+
+
+
+#endif
diff --git a/support/dktools/DkWxImgszFrame.wxc b/support/dktools/DkWxImgszFrame.wxc
new file mode 100644
index 0000000000..40be8be76c
--- /dev/null
+++ b/support/dktools/DkWxImgszFrame.wxc
@@ -0,0 +1,960 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+
+%% wx-gui
+
+type = frame
+icon = dkicon_bitmap
+menu bar = mbMain
+contents = mainSizer
+
+[wxMenuBar mbMain]
+contents = mFile
+contents = mExtras
+contents = mHelp
+
+[wxMenu mFile]
+contents = miOpen
+contents = miExit
+text = sTexts[1]
+
+[wxMenuItem miOpen]
+text = sTexts[49]
+id = DkWxImgsz_Open
+tip = sTexts[50]
+
+[wxMenuItem miExit]
+text = sTexts[2]
+id = DkWxImgsz_Quit
+tip = sTexts[19]
+
+[wxMenu mExtras]
+text = sTexts[38]
+contents = miOptions
+
+[wxMenuItem miOptions]
+text = sTexts[39]
+tip = sTexts[40]
+id = DkWxImgsz_Options
+
+[wxMenu mHelp]
+text = sTexts[27]
+contents = miHelpContents
+contents = miHelpAbout
+
+[wxMenuItem miHelpContents]
+text = sTexts[28]
+tip = sTexts[30]
+id = DkWxImgsz_Help
+
+[wxMenuItem miHelpAbout]
+text = sTexts[29]
+tip = sTexts[31]
+id = DkWxImgsz_About
+
+[wxBoxSizer mainSizer]
+direction = vertical
+contents = $space(10)
+contents = horizontalSizer
+contents = $space(10)
+contents = statusSizer
+contents = $space(10)
+
+[wxBoxSizer horizontalSizer]
+grow = yes
+proportion = 1
+contents = $space(10)
+contents = inputDataSizer left top
+contents = $space(10)
+contents = bCalculate centered-x centered-y
+contents = $space(10)
+contents = outputDataSizer left top
+contents = $space(10)
+
+[wxGridBagSizer inputDataSizer]
+grid = 5 5
+contents = lOriginalImage 0 0 1 2 left centered-y
+contents = lWidth +1 0 1 1 right centered-y
+contents = tWidth . +1 1 1 left centered-y
+contents = lHeight +1 0 1 1 right centered-y
+contents = tHeight . +1 1 1 left centered-y
+contents = $space(10) +1 0 1 1 left
+contents = lChangeType +1 0 1 2 left centered-y
+contents = lAction +1 0 1 1 right centered-y
+contents = cbAction . +1 1 1 left centered-y
+contents = lMinimum +1 0 1 1 right centered-y
+contents = tMinimum . +1 1 1 left centered-y
+contents = lMaximum +1 0 1 1 right centered-y
+contents = tMaximum . +1 1 1 left centered-y
+
+[wxStaticText lOriginalImage]
+text = sTexts[6]
+
+[wxStaticText lWidth]
+text = sTexts[8]
+
+[wxTextCtrl tWidth]
+tip = sTexts[20]
+text = sTexts[26]
+
+[wxStaticText lHeight]
+text = sTexts[9]
+
+[wxTextCtrl tHeight]
+tip = sTexts[21]
+text = sTexts[26]
+
+[wxStaticText lChangeType]
+text = sTexts[10]
+
+[wxStaticText lAction]
+text = sTexts[11]
+
+[wxChoice cbAction]
+choices = 3 saAction
+tip = sTexts[22]
+# grow = yes
+id = DkWxImgsz_Choice
+
+[wxStaticText lMinimum]
+text = sTexts[15]
+
+[wxTextCtrl tMinimum]
+tip = sTexts[23]
+text = sTexts[26]
+
+[wxStaticText lMaximum]
+text = sTexts[16]
+
+[wxTextCtrl tMaximum]
+tip = sTexts[24]
+text = sTexts[26]
+
+[wxBitmapButton bCalculate]
+# text = sTexts[17]
+bitmap = run2_bitmap
+tip = sTexts[25]
+id = DkWxImgsz_Run
+
+[wxGridBagSizer outputDataSizer]
+grid = 5 5
+grow = yes
+proportion = 1
+contents = lResults 0 0 1 2 left centered-y
+contents = dataGrid +1 0 2 2 left top
+growable row = 2
+growable column = 1
+
+[wxStaticText lResults]
+text = sTexts[7]
+
+[wxGrid dataGrid]
+text style = readonly
+column head = sTexts[3]
+column head = sTexts[4]
+column head = sTexts[5]
+column head = sTexts[18]
+rows = 16
+minimum size = 300 200
+grow = true
+proportion = 1
+
+[wxBoxSizer statusSizer]
+contents = $space(10)
+contents = lStatus
+contents = $space(10)
+
+[wxStaticText lStatus]
+text = sTexts[18]
+
+
+%% header start
+
+
+%% class start
+
+
+/** Main window class for the wximgsz program.
+*/
+class DkWxImgszFrame : public DkWxFrame
+{
+ private:
+
+ /** Event table.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ /** Localized message texts.
+ */
+ wxChar const * const *sTexts;
+
+ /** Red (used as background color).
+ */
+ wxColour cRed;
+
+ /** Red 127.
+ */
+ wxColour cNotSoDarkRed;
+
+ /** Green (used as background color).
+ */
+ wxColour cGreen;
+
+ /** Black (used as text color).
+ */
+ wxColour cBlack;
+
+ /** Dark red (used as text color).
+ */
+ wxColour cDarkRed;
+
+ /** Yellow (used as background color).
+ */
+ wxColour cYellow;
+
+ /** File dialog x position.
+ */
+ int fdx;
+
+ /** File dialog y position.
+ */
+ int fdy;
+
+ /** Options dialog x position.
+ */
+ int odx;
+
+ /** Options dialog y position.
+ */
+ int ody;
+
+ /** Flag: Use background colors to indicate scale factor quality.
+ */
+ bool bUseColour;
+
+ /** Current directory.
+ */
+ wxString sCurrentDir;
+
+%% class end
+ public:
+ /** Constructor.
+ */
+ DkWxImgszFrame(
+ wxChar const *applicationName,
+ wxChar const * const *localizedMessages,
+ DkWxAppHelper *applicationHelper,
+ DkWxHelpController *helpController,
+ int wxid,
+ int argc,
+ wxChar **argv
+ );
+
+ /** Destructor.
+ */
+ ~DkWxImgszFrame();
+
+ /** Check whether we can close the window.
+ @param isLast Flag: Last top level window.
+ */
+ bool
+ canClose(bool isLast);
+
+ /** Event handler to open a file.
+ @param event Event to process.
+ */
+ void
+ OnOpen(wxCommandEvent& WXUNUSED(event));
+
+ /** Event handler to quit application.
+ @param event Event to process.
+ */
+ void
+ OnQuit(wxCommandEvent& WXUNUSED(event));
+
+ /** Event handler to show help contents.
+ @param event Event to process.
+ */
+ void
+ OnHelp(wxCommandEvent& WXUNUSED(event));
+
+ /** Event handler to show version number.
+ @param event Event to process.
+ */
+ void
+ OnAbout(wxCommandEvent& WXUNUSED(event));
+
+ /** Event handler: Run calculation.
+ @param event Event to process.
+ */
+ void
+ OnRun(wxCommandEvent& WXUNUSED(event));
+
+ /** Event handler: Choice made.
+ @param event Event to process.
+ */
+ void
+ OnChoice(wxCommandEvent & event);
+
+ /** Event handler to set options.
+ @param event Event to process.
+ */
+ void
+ OnOptions(wxCommandEvent& WXUNUSED(event));
+
+ protected:
+
+ /** Save data entered into text fields.
+ */
+ void saveData();
+
+ /** Restore data entered in text fields.
+ */
+ void restoreData();
+
+ /** Enable/disable the lower text fields depending
+ on the current choice selection.
+ */
+ void
+ enableDisableMinimumMaximum();
+
+ /** Calculate largest common divisor.
+ @param aa One number.
+ @param bb Other number.
+ @return Largest common divisor of aa and bb.
+ */
+ long gcd(long aa, long bb);
+
+ /** Retrieve positive long number from text field.
+ @param tf Text field to process.
+ @param bShowErrors Flag: Show message boxes for errors.
+ @return Positive number on success, 0L on error.
+ */
+ long getTextCtrlContents(wxTextCtrl *tf, bool bShowErrors);
+
+ /** Run calculation.
+ */
+ void
+ run(bool bShowErrors);
+
+ /** Run for a set of numbers.
+ @param w Width (or height, if inverted).
+ @param h Height (or width, if inverted).
+ @param min Minimum value.
+ @param max maximum value.
+ @param inverted Flag: w contains the hight, h the width.
+ */
+ void
+ runForNumbers(long w, long h, long min, long max, int inverted);
+
+ /** Classify factor.
+ @param n New value.
+ @param o Old value.
+ @return 2 for powers of 2, 1 for integer factors, 0 otherwise.
+ */
+ int classifyFactor(long n, long o);
+
+ /** Count bit number in a long value.
+ @param v Value to check.
+ @return Number of bits set.
+ */
+ int countBits(long v);
+};
+
+%% header end
+
+
+%% module start
+
+#include "wximgsz.h"
+#include "dkicon.xpm"
+#include "dk4verswx.h"
+#include "run2.xpm"
+
+$!trace-include
+
+
+
+/** Event table for the DkWxImgszFrame class.
+*/
+BEGIN_EVENT_TABLE(DkWxImgszFrame, wxFrame)
+ EVT_MENU(DkWxImgsz_Quit, DkWxImgszFrame::OnQuit)
+ EVT_MENU(DkWxImgsz_Help, DkWxImgszFrame::OnHelp)
+ EVT_MENU(DkWxImgsz_About, DkWxImgszFrame::OnAbout)
+ EVT_MENU(DkWxImgsz_Options, DkWxImgszFrame::OnOptions)
+ EVT_MENU(DkWxImgsz_Open, DkWxImgszFrame::OnOpen)
+ EVT_BUTTON(DkWxImgsz_Run, DkWxImgszFrame::OnRun)
+ EVT_CHOICE(DkWxImgsz_Choice, DkWxImgszFrame::OnChoice)
+END_EVENT_TABLE()
+
+
+
+%% constructor start
+
+DkWxImgszFrame::DkWxImgszFrame(
+ wxChar const *applicationName,
+ wxChar const * const *localizedMessages,
+ DkWxAppHelper *applicationHelper,
+ DkWxHelpController *helpController,
+ int wxid,
+ int argc,
+ wxChar **argv
+) : DkWxFrame(applicationName, applicationHelper, helpController, wxid),
+ cRed(255, 91, 91),
+ cNotSoDarkRed(127, 0, 0),
+ cGreen(127, 255, 127),
+ cBlack(0, 0, 0),
+ cDarkRed(63, 0, 0),
+ cYellow(255, 255, 0),
+ sCurrentDir(wxT(""))
+{
+ /*
+ Icon for main window.
+ */
+#if defined(__WXMSW__)
+ wxIcon dkicon_bitmap(wxT("aaaaa"));
+#else
+ wxIcon dkicon_bitmap(xpm_dkicon);
+#endif
+ wxIcon run2_bitmap(xpm_run2);
+ fdx = -1; fdy = -1;
+ odx = -1; ody = -1;
+ sTexts = localizedMessages;
+ wxString saAction[] = {
+ wxString(localizedMessages[12]),
+ wxString(localizedMessages[13]),
+ wxString(localizedMessages[14])
+ };
+ bUseColour = true;
+%% constructor end
+ if (lOriginalImage) {
+ lOriginalImage->SetForegroundColour(cNotSoDarkRed);
+ }
+ if (lChangeType) {
+ lChangeType->SetForegroundColour(cNotSoDarkRed);
+ }
+ if (lResults) {
+ lResults->SetForegroundColour(cNotSoDarkRed);
+ }
+ SetTitle(localizedMessages[0]);
+#if 0
+ restorePosition();
+#endif
+ restoreData();
+ enableDisableMinimumMaximum();
+}
+
+%% module end
+
+void
+DkWxImgszFrame::OnHelp(wxCommandEvent& WXUNUSED(event))
+{
+ openHelp();
+}
+
+
+static wxChar const wximgsz_version[] = {
+ wxT("wximgsz (part of dktools-")
+};
+
+static wxChar const wximgsz_versnumber[] = {
+ DKT_VERSION_WX
+};
+
+static wxChar const wximgsz_versend[] = {
+ wxT(")")
+};
+void
+DkWxImgszFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
+{
+ wxString sVersion(wximgsz_version);
+ sVersion.Append(wximgsz_versnumber);
+ sVersion.Append(wximgsz_versend);
+ sVersion.Append(sTexts[53]);
+ sVersion.Append(wxT("Copyright (c) 2013-2016 Dirk Krause"));
+ sVersion.Append(sTexts[53]);
+ sVersion.Append(sTexts[53]);
+ sVersion.Append(sTexts[54]);
+ sVersion.Append(wxT("DK tools, wxWidgets, libpng, libjpeg, libtiff, zlib."));
+ sVersion.Append(sTexts[53]);
+ sVersion.Append(sTexts[53]);
+ sVersion.Append(sTexts[55]);
+ sVersion.Append(wxT("http://dktools.sourceforge.net\n"));
+ sVersion.Append(wxT("http://www.wxwidgets.org\n"));
+ sVersion.Append(wxT("http://www.libpng.org/pub/png/libpng.html\n"));
+ sVersion.Append(wxT("http://www.ijg.org\n"));
+ sVersion.Append(wxT("http://www.remotesensing.org/libtiff\n"));
+ sVersion.Append(wxT("http://www.zlib.org"));
+ wxMessageBox(sVersion, sTexts[35]);
+}
+
+
+void
+DkWxImgszFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
+{
+ $? "+ DkWxImgszFrame::OnQuit"
+ Show(false);
+ Close();
+ $? "- DkWxBmepsFrame::OnQuit"
+}
+
+
+
+void
+DkWxImgszFrame::OnOpen(wxCommandEvent& WXUNUSED(event))
+{
+ wxString s(wxT(""));
+ $? "+ DkWxImgszFrame::OnOpen"
+ s.Append(wxT("BMP files (*.bmp)|*.bmp"));
+ s.Append(wxT("|PNG files (*.png)|*.png"));
+ s.Append(wxT("|JPEG files (*.jpg)|*.jpg|JPEG files (*.jpeg)|*.jpeg"));
+ s.Append(wxT("|TIFF files (*.tif)|*.tif|TIFF files (*.tiff)|*.tiff"));
+ s.Append(wxT("|XPM files (*.xpm)|*.xpm"));
+ s.Append(wxT("|All files (*.*)|*.*"));
+#if wxCHECK_VERSION(2, 9, 0)
+ wxFileDialog dlg(this, sTexts[48], sCurrentDir, wxT(""), s, wxFD_OPEN);
+#else
+ wxFileDialog dlg(this, sTexts[48], sCurrentDir, wxT(""), s, wxOPEN);
+#endif
+ pHelper->setRelatedPosition(this, &dlg, &fdx, &fdy);
+ if(wxID_OK == dlg.ShowModal()) {
+ wxString path = dlg.GetPath();
+ wxImage img;
+ if(img.LoadFile(path)) {
+ int w = img.GetWidth();
+ int h = img.GetHeight();
+ if((w > 0) && (h > 0)) {
+ wxString sWidth;
+ wxString sHeight;
+ sWidth.Printf(wxT("%d"), w);
+ sHeight.Printf(wxT("%d"), h);
+ if((tWidth) && (tHeight)) {
+ tWidth->SetValue(sWidth);
+ tHeight->SetValue(sHeight);
+ Refresh();
+ Update();
+ run(false);
+ }
+ } else {
+ /* ERROR: Illegal image dimensions! */
+ wxMessageBox(sTexts[51], sTexts[52], (wxOK | wxICON_ERROR), this);
+ }
+ } else {
+ /* ERROR: Failed to load file! */
+ wxMessageBox(sTexts[51], sTexts[52], (wxOK | wxICON_ERROR), this);
+ }
+ }
+ dlg.GetPosition(&fdx, &fdy);
+ $? "- DkWxBmepsFrame::OnOpen"
+}
+
+
+
+void
+DkWxImgszFrame::OnOptions(wxCommandEvent& WXUNUSED(event))
+{
+ $? "+ DkWxImgszFrame::OnOptions"
+ DkWxImgszOptionsDialog dlg(this, sTexts[41], sTexts);
+ pHelper->setRelatedPosition(this, &dlg, &odx, &ody);
+ dlg.SetValue(bUseColour);
+ if(dlg.ShowModal() == wxID_OK) {
+ bUseColour = dlg.GetValue();
+ }
+ dlg.GetPosition(&odx, &ody);
+ $? "- DkWxBmepsFrame::OnOptions"
+}
+
+
+void
+DkWxImgszFrame::run(bool bShowErrors)
+{
+ long w = 0L;
+ long h = 0L;
+ long min = 0L;
+ long max = 0L;
+ int action = 0;
+ $? "+ DkWxImgszFrame::run"
+ w = getTextCtrlContents(tWidth, bShowErrors);
+ if(w > 0L) {
+ h = getTextCtrlContents(tHeight, bShowErrors);
+ if(h > 0L) {
+ switch((action = cbAction->GetCurrentSelection())) {
+ case 2: {
+ min = getTextCtrlContents(tMinimum, bShowErrors);
+ if(min > 0L) {
+ max = getTextCtrlContents(tMaximum, bShowErrors);
+ }
+ } break;
+ case 1: {
+ min = getTextCtrlContents(tMinimum, bShowErrors);
+ if(min > 0L) {
+ max = getTextCtrlContents(tMaximum, bShowErrors);
+ }
+ } break;
+ default: {
+ min = 1L; max = w; action = 1;
+ } break;
+ }
+ if((w > 0L) && (h > 0L) && (min > 0L) && (max > 0L)) {
+ switch(action) {
+ case 2: {
+ runForNumbers(h, w, min, max, 1);
+ } break;
+ default: {
+ runForNumbers(w, h, min, max, 0);
+ } break;
+ }
+ }
+ }
+ }
+ $? "- DkWxImgszFrame::run"
+}
+
+
+
+void
+DkWxImgszFrame::OnRun(wxCommandEvent& WXUNUSED(event))
+{
+ $? "+ DkWxImgszFrame::OnRun"
+ run(true);
+ $? "- DkWxImgszFrame::OnRun"
+}
+
+
+
+DkWxImgszFrame::~DkWxImgszFrame()
+{
+}
+
+
+
+bool
+DkWxImgszFrame::canClose(bool isLast)
+{
+ $? "+ DkWxBmepsFrame::canClose %d", (isLast ? 1 : 0)
+ if(isLast) {
+ saveData();
+ } $? "- DkWxBmepsFrame::canClose 1"
+ return true;
+}
+
+
+
+static wxChar const * const wximgsz_keys[] = {
+$!string-table macro=wxT
+wximgsz.width
+wximgsz.height
+wximgsz.selection
+wximgsz.minimum
+wximgsz.maximum
+wximgsz.colours
+$!end
+};
+
+void
+DkWxImgszFrame::saveData()
+{
+ long i[] = {
+ 0L, // Width
+ 0L, // Height
+ 0L, // Selection
+ 0L, // Minimum
+ 0L, // Maximum
+ 0L // bUseColour
+ };
+ long l;
+ if((tWidth->GetValue()).ToLong(&l)) {
+ i[0] = l;
+ }
+ if((tHeight->GetValue()).ToLong(&l)) {
+ i[1] = l;
+ }
+ i[2] = (long)(cbAction->GetCurrentSelection());
+ if(i[2] < 0L) i[2] = 0L;
+ if((tMinimum->GetValue()).ToLong(&l)) {
+ i[3] = l;
+ }
+ if((tMaximum->GetValue()).ToLong(&l)) {
+ i[4] = l;
+ }
+ i[5] = ((bUseColour) ? 1L : 0L);
+ if(pHelper) {
+ pHelper->saveMultipleLongs(wximgsz_keys, i);
+ }
+}
+
+
+void
+DkWxImgszFrame::restoreData()
+{
+ wxString sWidth;
+ wxString sHeight;
+ wxString sMinimum;
+ wxString sMaximum;
+ long i[] = {
+ 1024L, // Width
+ 768L, // Height
+ 0L, // Selection
+ 200L, // Minimum
+ 800L, // Maximum
+ 1L // bUseColour
+ };
+ if(pHelper) {
+ pHelper->retrieveMultipleLongs(wximgsz_keys, i);
+ sWidth.Printf(wxT("%ld"), i[0]);
+ sHeight.Printf(wxT("%ld"), i[1]);
+ sMinimum.Printf(wxT("%ld"), i[3]);
+ sMaximum.Printf(wxT("%ld"), i[4]);
+ tWidth->SetValue(sWidth);
+ tHeight->SetValue(sHeight);
+ tMinimum->SetValue(sMinimum);
+ tMaximum->SetValue(sMaximum);
+ cbAction->SetSelection((int)(i[2]));
+ bUseColour = ((i[5]) ? true : false);
+ }
+}
+
+
+
+void
+DkWxImgszFrame::enableDisableMinimumMaximum()
+{
+ if(0 == cbAction->GetCurrentSelection()) {
+ tMinimum->SetEditable(false);
+ tMaximum->SetEditable(false);
+ tMinimum->Enable(false);
+ tMaximum->Enable(false);
+ } else {
+ tMinimum->SetEditable(true);
+ tMaximum->SetEditable(true);
+ tMinimum->Enable(true);
+ tMaximum->Enable(true);
+ }
+}
+
+
+
+void
+DkWxImgszFrame::OnChoice(wxCommandEvent & event)
+{
+ enableDisableMinimumMaximum();
+}
+
+
+
+long
+DkWxImgszFrame::gcd(long aa, long bb)
+{
+ long back = 0L;
+ long h = 0L;
+ long a;
+ long b;
+
+ a = aa;
+ b = bb;
+ while(b > 0L) {
+ h = a % b;
+ a = b;
+ b = h;
+ }
+ back = a;
+ return back;
+}
+
+
+long
+DkWxImgszFrame::getTextCtrlContents(wxTextCtrl *tf, bool bShowErrors)
+{
+ long back = 0L;
+ long l = 0L;
+ if((tf->GetValue()).ToLong(&l)) {
+ back = l;
+ }
+ if(0 >= back) {
+ if(bShowErrors) {
+ tf->SetFocus();
+ wxMessageBox(sTexts[33], sTexts[32], (wxOK | wxICON_ERROR), this);
+ }
+ }
+ return back;
+}
+
+
+
+void
+DkWxImgszFrame::runForNumbers(long w, long h, long min, long max, int inverted)
+{
+ long gd;
+ long w0;
+ long h0;
+ long nw;
+ long nh;
+ long i;
+ long z;
+ long n;
+ long g2;
+ int lineno;
+ int cl;
+ int rows;
+ int found = 0;
+
+ gd = gcd(w, h);
+ if(gd > 0L) {
+ /*
+ Minimum rectangle.
+ */
+ w0 = w / gd;
+ h0 = h / gd;
+ /*
+ Remove all grid lines.
+ */
+ rows = dataGrid->GetNumberRows();
+ dataGrid->DeleteRows(0, rows);
+ /*
+ Build and fill new grid.
+ */
+ lineno = 0;
+ i = 1;
+ lStatus->SetForegroundColour(cBlack);
+ lStatus->SetLabel(sTexts[18]);
+ while((i * w0) <= max) {
+ if((i * w0) >= min) {
+ found = 1;
+ nw = i * w0;
+ nh = i * h0;
+ /* Classify factor. */
+ cl = classifyFactor(nw, w);
+ g2 = gcd(nw, w);
+ z = nw / g2; n = w / g2;
+ dataGrid->AppendRows(1);
+ dataGrid->SetCellTextColour(lineno, 0, cBlack);
+ dataGrid->SetCellTextColour(lineno, 1, cBlack);
+ dataGrid->SetCellTextColour(lineno, 2, cBlack);
+ switch(cl) {
+ case 2: {
+ if(bUseColour) {
+ dataGrid->SetCellBackgroundColour(lineno, 2, cGreen);
+ } else {
+ dataGrid->SetCellValue(lineno, 3, sTexts[36]);
+ }
+ } break;
+ case 1: {
+ if(bUseColour) {
+ dataGrid->SetCellBackgroundColour(lineno, 2, cYellow);
+ } else {
+ dataGrid->SetCellValue(lineno, 3, sTexts[37]);
+ }
+ } break;
+ default: {
+ if(bUseColour) {
+ dataGrid->SetCellBackgroundColour(lineno, 2, cRed);
+ } else {
+ dataGrid->SetCellValue(lineno, 3, wxT(""));
+ }
+ } break;
+ }
+ if(bUseColour) {
+ dataGrid->SetCellValue(lineno, 3, wxT(""));
+ }
+ {
+ wxString sRowHead;
+ wxString sFactor;
+ wxString sWidth;
+ wxString sHeight;
+
+ sRowHead.Printf(wxT("%d"), (lineno + 1));
+ if(n > 1L) {
+ sFactor.Printf(wxT("%ld / %ld"), z, n);
+ } else {
+ sFactor.Printf(wxT("%ld"), z);
+ }
+ if(inverted) {
+ sWidth.Printf(wxT("%ld"), nh);
+ sHeight.Printf(wxT("%ld"), nw);
+ } else {
+ sWidth.Printf(wxT("%ld"), nw);
+ sHeight.Printf(wxT("%ld"), nh);
+ }
+ dataGrid->SetRowLabelValue(lineno, sRowHead);
+ dataGrid->SetCellValue(lineno, 0, sWidth);
+ dataGrid->SetCellValue(lineno, 1, sHeight);
+ dataGrid->SetCellValue(lineno, 2, sFactor);
+ dataGrid->SetCellAlignment(lineno, 0, wxALIGN_CENTRE, wxALIGN_CENTRE);
+ dataGrid->SetCellAlignment(lineno, 1, wxALIGN_CENTRE, wxALIGN_CENTRE);
+ dataGrid->SetCellAlignment(lineno, 2, wxALIGN_CENTRE, wxALIGN_CENTRE);
+ dataGrid->SetCellAlignment(lineno, 3, wxALIGN_CENTRE, wxALIGN_CENTRE);
+ }
+ lineno++;
+ }
+ i++;
+ }
+ dataGrid->AutoSizeColumns();
+ dataGrid->EnableDragColSize(true);
+ if(0 == found) {
+ lStatus->SetLabel(sTexts[34]);
+ lStatus->SetForegroundColour(cDarkRed);
+ }
+ Refresh();
+ Update();
+ }
+}
+
+
+
+int
+DkWxImgszFrame::classifyFactor(long n, long o)
+{
+ long max;
+ long min;
+ int back = 0;
+ if(n > o) {
+ max = n; min = o;
+ } else {
+ max = o; min = n;
+ }
+ if(max % min) {
+ back = 0;
+ } else {
+ back = 1;
+ max = max / min;
+ if(countBits(max) == 1) {
+ back = 2;
+ }
+ }
+ return back;
+}
+
+
+int
+DkWxImgszFrame::countBits(long v)
+{
+#if DK3_SIZEOF_LONG > 2
+#if DK3_SIZEOF_LONG > 4
+ long bitmask = 0x4000000000000000L;
+ int attempts = 63;
+#else
+ long bitmask = 0x40000000L;
+ int attempts = 31;
+#endif
+#else
+ long bitmask = 0x4000L;
+ int attempts = 15;
+#endif
+ int back = 0;
+
+ while(attempts--) {
+ if(v & bitmask) {
+ back++;
+ }
+ bitmask = bitmask >> 1;
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/DkWxImgszOptionsDialog.cpp b/support/dktools/DkWxImgszOptionsDialog.cpp
new file mode 100644
index 0000000000..06b6793982
--- /dev/null
+++ b/support/dktools/DkWxImgszOptionsDialog.cpp
@@ -0,0 +1,219 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxImgszOptionsDialog.wxc
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxImgszOptionsDialog.cpp The DkWxImgszOptionsDialog module.
+*/
+
+
+#line 126 "DkWxImgszOptionsDialog.wxc"
+
+#include "wximgsz.h"
+
+
+
+#line 130 "DkWxImgszOptionsDialog.wxc"
+
+BEGIN_EVENT_TABLE(DkWxImgszOptionsDialog, wxDialog)
+ EVT_BUTTON(wxID_OK, DkWxImgszOptionsDialog::OnOK)
+ EVT_BUTTON(wxID_CANCEL, DkWxImgszOptionsDialog::OnCancel)
+END_EVENT_TABLE()
+
+
+
+#line 138 "DkWxImgszOptionsDialog.wxc"
+DkWxImgszOptionsDialog::DkWxImgszOptionsDialog
+(
+ DkWxImgszFrame *parent,
+ wxChar const *title,
+ wxChar const * const *messageTexts
+) : wxDialog(
+ parent,
+ wxID_ANY,
+ title,
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxDEFAULT_DIALOG_STYLE
+)
+{
+ sTexts = messageTexts;
+ dkctGUILayoutOK = false;
+ sDialog = NULL;
+ verticalSizer = NULL;
+ cbUseColours = NULL;
+ buttonSizer = NULL;
+ realButtonSizer = NULL;
+ bOK = NULL;
+ bCancel = NULL;
+ sDialog = new wxBoxSizer(
+ wxHORIZONTAL
+ );
+ if(!(sDialog)) {
+ goto dkctGUILayoutFinished;
+ }
+ sDialog->Add(10, 10, 1);
+ verticalSizer = new wxBoxSizer(
+ wxVERTICAL
+ );
+ if(!(verticalSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ verticalSizer->Add(10, 10, 1);
+ cbUseColours = new wxCheckBox(
+ this,
+ wxID_ANY,
+ sTexts[42]
+ );
+ if(!(cbUseColours)) {
+ goto dkctGUILayoutFinished;
+ }
+ cbUseColours->SetToolTip(sTexts[43]);
+ verticalSizer->Add(
+ cbUseColours
+ );
+ verticalSizer->Add(10, 10, 0);
+ buttonSizer = new wxBoxSizer(
+ wxHORIZONTAL
+ );
+ if(!(buttonSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ buttonSizer->Add(1, 1, 1);
+ realButtonSizer = new wxStdDialogButtonSizer(
+ );
+ if(!(realButtonSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ bOK = new wxButton(
+ this,
+ wxID_OK,
+ sTexts[44]
+ );
+ if(!(bOK)) {
+ goto dkctGUILayoutFinished;
+ }
+ bOK->SetToolTip(sTexts[46]);
+ realButtonSizer->AddButton(
+ bOK
+ );
+ bCancel = new wxButton(
+ this,
+ wxID_CANCEL,
+ sTexts[45]
+ );
+ if(!(bCancel)) {
+ goto dkctGUILayoutFinished;
+ }
+ bCancel->SetToolTip(sTexts[47]);
+ realButtonSizer->AddButton(
+ bCancel
+ );
+ realButtonSizer->Realize();
+ buttonSizer->Add(
+ realButtonSizer,
+ 1,
+ wxGROW
+ );
+ buttonSizer->Add(1, 1, 1);
+ verticalSizer->Add(
+ buttonSizer
+ );
+ verticalSizer->Add(10, 10, 1);
+ sDialog->Add(
+ verticalSizer
+ );
+ sDialog->Add(10, 10, 1);
+ SetSizer(sDialog);
+ dkctGUILayoutOK = true;
+ dkctGUILayoutFinished:
+ if(dkctGUILayoutOK) {
+ sDialog->Fit(this);
+ sDialog->SetSizeHints(this);
+ }
+
+#line 154 "DkWxImgszOptionsDialog.wxc"
+}
+
+
+#line 157 "DkWxImgszOptionsDialog.wxc"
+
+
+void
+DkWxImgszOptionsDialog::OnOK(wxCommandEvent & event)
+{
+ if(IsModal()) {
+ value = cbUseColours->GetValue();
+ EndModal(wxID_OK);
+ } else {
+ SetReturnCode(wxID_OK);
+ Show(false);
+ }
+}
+
+
+
+void
+DkWxImgszOptionsDialog::OnCancel(wxCommandEvent & event)
+{
+ if(IsModal()) {
+ EndModal(wxID_CANCEL);
+ } else {
+ SetReturnCode(wxID_CANCEL);
+ Show(false);
+ }
+}
+
+
+void
+DkWxImgszOptionsDialog::SetValue(bool b)
+{
+ value = b;
+ cbUseColours->SetValue(b);
+}
+
+
+
+bool
+DkWxImgszOptionsDialog::GetValue()
+{
+ return value;
+}
+
+
+
+DkWxImgszOptionsDialog::~DkWxImgszOptionsDialog()
+{
+}
+
+
diff --git a/support/dktools/DkWxImgszOptionsDialog.h b/support/dktools/DkWxImgszOptionsDialog.h
new file mode 100644
index 0000000000..2dfeee3ba3
--- /dev/null
+++ b/support/dktools/DkWxImgszOptionsDialog.h
@@ -0,0 +1,158 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxImgszOptionsDialog.wxc
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxImgszOptionsDialog.h Header file for the DkWxImgszOptionsDialog module.
+*/
+
+#ifndef DKWXIMGSZOPTIONSDIALOG_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DKWXIMGSZOPTIONSDIALOG_H_INCLUDED 1
+
+
+#line 55 "DkWxImgszOptionsDialog.wxc"
+
+
+#line 57 "DkWxImgszOptionsDialog.wxc"
+
+/** Options dialog for the wximgsz program.
+*/
+class DkWxImgszOptionsDialog : public wxDialog
+{
+ private:
+
+ /** Event table.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ /** Localized text messages.
+ */
+ wxChar const * const *sTexts;
+
+ /** Checkbox value.
+ */
+ bool value;
+
+ /** Flag: GUI ok.
+ */
+ bool dkctGUILayoutOK;
+
+ /** GUI element sDialog.
+ */
+#line 13 "DkWxImgszOptionsDialog.wxc"
+ wxBoxSizer *sDialog;
+
+ /** GUI element verticalSizer.
+ */
+#line 19 "DkWxImgszOptionsDialog.wxc"
+ wxBoxSizer *verticalSizer;
+
+ /** GUI element cbUseColours.
+ */
+#line 27 "DkWxImgszOptionsDialog.wxc"
+ wxCheckBox *cbUseColours;
+
+ /** GUI element buttonSizer.
+ */
+#line 31 "DkWxImgszOptionsDialog.wxc"
+ wxBoxSizer *buttonSizer;
+
+ /** GUI element realButtonSizer.
+ */
+#line 37 "DkWxImgszOptionsDialog.wxc"
+ wxStdDialogButtonSizer *realButtonSizer;
+
+ /** GUI element bOK.
+ */
+#line 43 "DkWxImgszOptionsDialog.wxc"
+ wxButton *bOK;
+
+ /** GUI element bCancel.
+ */
+#line 48 "DkWxImgszOptionsDialog.wxc"
+ wxButton *bCancel;
+
+
+#line 79 "DkWxImgszOptionsDialog.wxc"
+
+ public:
+
+ /** Constructor.
+ @param parent Parent window.
+ @param title Window title.
+ @param messageTexts Localized message texts.
+ */
+ DkWxImgszOptionsDialog(
+ DkWxImgszFrame *parent,
+ wxChar const *title,
+ wxChar const * const *messageTexts
+ );
+
+ /** Destructor.
+ */
+ ~DkWxImgszOptionsDialog();
+
+ /** Event handler: OK button pressed.
+ @param event Event to process.
+ */
+ void
+ OnOK(wxCommandEvent & event);
+
+ /** Event handler: Cancel button pressed.
+ @param event Event to process.
+ */
+ void
+ OnCancel(wxCommandEvent & event);
+
+ /** Set new checkbox value.
+ @param b New checkbox value.
+ */
+ void
+ SetValue(bool b);
+
+ /** Get checkbox value.
+ @return Checkbox value.
+ */
+ bool
+ GetValue();
+
+};
+
+
+#line 124 "DkWxImgszOptionsDialog.wxc"
+
+
+#endif
diff --git a/support/dktools/DkWxImgszOptionsDialog.wxc b/support/dktools/DkWxImgszOptionsDialog.wxc
new file mode 100644
index 0000000000..06c65be35d
--- /dev/null
+++ b/support/dktools/DkWxImgszOptionsDialog.wxc
@@ -0,0 +1,206 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+
+%% wx-gui
+
+type = dialog
+contents = sDialog
+
+[wxBoxSizer sDialog]
+direction = horizontal
+contents = $stretch(10)
+contents = verticalSizer
+contents = $stretch(10)
+
+[wxBoxSizer verticalSizer]
+direction = vertical
+contents = $stretch(10)
+contents = cbUseColours
+contents = $space(10)
+contents = buttonSizer
+contents = $stretch(10)
+
+[wxCheckBox cbUseColours]
+text = sTexts[42]
+tip = sTexts[43]
+
+[wxBoxSizer buttonSizer]
+direction = horizontal
+contents = $stretch(1)
+contents = realButtonSizer
+contents = $stretch(1)
+
+[wxStdDialogButtonSizer realButtonSizer]
+grow = yes
+proportion = 1
+contents = bOK
+contents = bCancel
+
+[wxButton bOK]
+id = wxID_OK
+text = sTexts[44]
+tip = sTexts[46]
+
+[wxButton bCancel]
+id = wxID_CANCEL
+text = sTexts[45]
+tip = sTexts[47]
+
+
+%% header start
+
+%% class start
+
+/** Options dialog for the wximgsz program.
+*/
+class DkWxImgszOptionsDialog : public wxDialog
+{
+ private:
+
+ /** Event table.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ /** Localized text messages.
+ */
+ wxChar const * const *sTexts;
+
+ /** Checkbox value.
+ */
+ bool value;
+
+%% class end
+
+ public:
+
+ /** Constructor.
+ @param parent Parent window.
+ @param title Window title.
+ @param messageTexts Localized message texts.
+ */
+ DkWxImgszOptionsDialog(
+ DkWxImgszFrame *parent,
+ wxChar const *title,
+ wxChar const * const *messageTexts
+ );
+
+ /** Destructor.
+ */
+ ~DkWxImgszOptionsDialog();
+
+ /** Event handler: OK button pressed.
+ @param event Event to process.
+ */
+ void
+ OnOK(wxCommandEvent & event);
+
+ /** Event handler: Cancel button pressed.
+ @param event Event to process.
+ */
+ void
+ OnCancel(wxCommandEvent & event);
+
+ /** Set new checkbox value.
+ @param b New checkbox value.
+ */
+ void
+ SetValue(bool b);
+
+ /** Get checkbox value.
+ @return Checkbox value.
+ */
+ bool
+ GetValue();
+
+};
+
+%% header end
+
+%% module start
+
+#include "wximgsz.h"
+
+$!trace-include
+
+BEGIN_EVENT_TABLE(DkWxImgszOptionsDialog, wxDialog)
+ EVT_BUTTON(wxID_OK, DkWxImgszOptionsDialog::OnOK)
+ EVT_BUTTON(wxID_CANCEL, DkWxImgszOptionsDialog::OnCancel)
+END_EVENT_TABLE()
+
+
+%% constructor start
+DkWxImgszOptionsDialog::DkWxImgszOptionsDialog
+(
+ DkWxImgszFrame *parent,
+ wxChar const *title,
+ wxChar const * const *messageTexts
+) : wxDialog(
+ parent,
+ wxID_ANY,
+ title,
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxDEFAULT_DIALOG_STYLE
+)
+{
+ sTexts = messageTexts;
+%% constructor end
+}
+
+%% module end
+
+
+void
+DkWxImgszOptionsDialog::OnOK(wxCommandEvent & event)
+{
+ if(IsModal()) {
+ value = cbUseColours->GetValue();
+ EndModal(wxID_OK);
+ } else {
+ SetReturnCode(wxID_OK);
+ Show(false);
+ }
+}
+
+
+
+void
+DkWxImgszOptionsDialog::OnCancel(wxCommandEvent & event)
+{
+ if(IsModal()) {
+ EndModal(wxID_CANCEL);
+ } else {
+ SetReturnCode(wxID_CANCEL);
+ Show(false);
+ }
+}
+
+
+void
+DkWxImgszOptionsDialog::SetValue(bool b)
+{
+ value = b;
+ cbUseColours->SetValue(b);
+}
+
+
+
+bool
+DkWxImgszOptionsDialog::GetValue()
+{
+ return value;
+}
+
+
+
+DkWxImgszOptionsDialog::~DkWxImgszOptionsDialog()
+{
+}
+
+
diff --git a/support/dktools/DkWxPathApp.cpp b/support/dktools/DkWxPathApp.cpp
new file mode 100644
index 0000000000..a5a83bafbb
--- /dev/null
+++ b/support/dktools/DkWxPathApp.cpp
@@ -0,0 +1,276 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxPathApp.cpt
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxPathApp.cpp The DkWxPathApp module.
+*/
+
+
+#line 44 "DkWxPathApp.cpt"
+
+#include "dkwxpath.h"
+
+
+
+
+#line 49 "DkWxPathApp.cpt"
+
+
+
+/** Implementation of application methods.
+*/
+IMPLEMENT_APP(DkWxPathApp)
+
+
+/** Default texts used if no localized texts found.
+*/
+wxChar const * const dkwxpath_default_texts[] = {
+/* 0 */
+wxT("dkwxpath"),
+
+/* 1 */
+wxT("dktools"),
+
+/* 2 */
+wxT("Dirk Krause"),
+
+/* 3 */
+wxT("Modifying PATH environment variable."),
+
+/* 4 */
+wxT("dktools setup"),
+
+/* 5 */
+wxT("PATH modification failed!"),
+
+/* 6 */
+wxT("Failed to modify PATH environment variable!"),
+
+/* 7 */
+wxT("Please add "),
+
+/* 8 */
+wxT("to the PATH environment variable"),
+
+/* 9 */
+wxT("Please remove "),
+
+/* 10 */
+wxT("from the PATH environment variable"),
+
+/* 11 */
+wxT("and reboot the computer as soon as possible."),
+
+/* 12 */
+wxT("WxBmpp - EPS image"),
+
+/* 13 */
+wxT("WxBmpp - PDF image"),
+
+/* 14 */
+wxT("WxBmpp - PDF object"),
+
+/* 15 */
+wxT("WxBmpp - PDF document"),
+
+/* 16 */
+wxT("WxBmpp - PS document"),
+
+/* 17 */
+wxT("WinPrint - default printer"),
+
+/* 18 */
+wxT("WinPrint - specify printer"),
+
+/* 19 */
+wxT("Open in WxBmpp"),
+
+/* 20 */
+wxT("Open in WxDkct"),
+
+/* 21 */
+wxT("Checksums"),
+
+NULL
+
+
+#line 150 "DkWxPathApp.cpt"
+};
+
+
+
+/** Constant texts, not localized.
+*/
+wxChar const * const dkwxpath_nl_wx[] = {
+/* 0 */
+wxT("Error"),
+
+/* 1 */
+wxT("Not enough memory (RAM)!"),
+
+NULL
+
+
+#line 161 "DkWxPathApp.cpt"
+};
+
+
+static dkChar const dkwxpath_groupname[] = { dkT("dktools") };
+
+
+
+static dkChar const dkwxpath_string_table[] = { dkT("dkwxpath.str") };
+
+
+
+bool
+DkWxPathApp::OnInit()
+{
+ bool back = false;
+ DkWxPathFrame *frame = NULL;
+ wxChar const * const *localizedTexts = NULL;
+ dkChar const * const *dkLocalizedTexts = NULL;
+ wxXPMHandler *phXpm = NULL;
+ wxICOHandler *phIco = NULL;
+
+
+
+#line 183 "DkWxPathApp.cpt"
+
+
+#line 184 "DkWxPathApp.cpt"
+
+ pHelper =
+ new DkWxAppHelper(argv[0], dkwxpath_default_texts[2], dkwxpath_groupname);
+ if (NULL == pHelper) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ if (!(pHelper->checkSetup())) {
+ goto finished;
+ }
+
+ localizedTexts =
+ pHelper->getStringTable(dkwxpath_default_texts, dkwxpath_string_table);
+ dkLocalizedTexts = dk3app_messages(
+ pHelper->getApp(), dkwxpath_string_table,
+ (dkChar const **)dkwxpath_default_texts
+ );
+ if ((NULL == localizedTexts) || (NULL == dkLocalizedTexts)) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ phXpm = new wxXPMHandler();
+ if (NULL != phXpm) {
+ wxImage::AddHandler(phXpm);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phIco = new wxICOHandler();
+ if (NULL != phIco) {
+ wxImage::AddHandler(phIco);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ frame = new DkWxPathFrame(
+ dkwxpath_default_texts[4], localizedTexts, dkLocalizedTexts, pHelper,
+ DkWxPath_MainWindow, argc, argv
+ );
+ if (NULL == frame) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ frame->Show();
+ frame->restorePosition();
+ back = true;
+
+ finished:
+ if (!(back)) {
+ if (NULL != pHelper) {
+ delete(pHelper); pHelper = NULL;
+ }
+ }
+
+
+#line 241 "DkWxPathApp.cpt"
+ return back;
+}
+
+
+
+int
+DkWxPathApp::OnExit()
+{
+ int back = 0;
+
+
+#line 251 "DkWxPathApp.cpt"
+ if(pHelper) {
+ delete(pHelper); pHelper = NULL;
+ }
+
+
+#line 255 "DkWxPathApp.cpt"
+
+
+#line 256 "DkWxPathApp.cpt"
+ return back;
+}
+
+
+
+void
+DkWxPathApp::ShowMemoryErrorMessage(void)
+{
+ const wxChar *s_title = NULL;
+ const wxChar *s_text = NULL;
+
+ if (NULL != pHelper) {
+ s_title = pHelper->getBasicString(3);
+ s_text = pHelper->getBasicString(9);
+ }
+ if (NULL == s_title) {
+ s_title = dkwxpath_nl_wx[0];
+ }
+ if (NULL == s_text) {
+ s_text = dkwxpath_nl_wx[1];
+ }
+ wxMessageBox(s_text, s_title, (wxOK | wxCENTRE | wxICON_ERROR));
+}
+
diff --git a/support/dktools/DkWxPathApp.cpt b/support/dktools/DkWxPathApp.cpt
new file mode 100644
index 0000000000..333d187f79
--- /dev/null
+++ b/support/dktools/DkWxPathApp.cpt
@@ -0,0 +1,279 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% header
+
+/** Application to set PATH variable for DK tools.
+*/
+class DkWxPathApp : public wxApp
+{
+ protected:
+
+ /** Helper object.
+ */
+ DkWxAppHelper *pHelper;
+
+ protected:
+
+ /** Show error message if not sufficient memory available.
+ */
+ void
+ ShowMemoryErrorMessage(void);
+
+ public:
+
+ /** Initialize the application.
+ */
+ virtual bool OnInit();
+
+ /** Clean up after running.
+ */
+ virtual int OnExit();
+};
+
+DECLARE_APP(DkWxPathApp)
+
+
+
+%% module
+
+#include "dkwxpath.h"
+
+
+$!trace-include
+
+
+
+/** Implementation of application methods.
+*/
+IMPLEMENT_APP(DkWxPathApp)
+
+
+/** Default texts used if no localized texts found.
+*/
+wxChar const * const dkwxpath_default_texts[] = {
+$!string-table macro=wxT
+#
+# 0: Program name
+#
+dkwxpath
+#
+# 1: Application group name
+#
+dktools
+#
+# 2: Software vendor name
+#
+Dirk Krause
+#
+# 3: Label text: Modifying PATH environment variable.
+#
+Modifying PATH environment variable.
+#
+# 4: Window title
+#
+dktools setup
+#
+# 5: Dialog title: Failed to modify PATH variable.
+#
+PATH modification failed!
+#
+# 6: Start of label text: Failed to modify PATH environment variable!
+#
+Failed to modify PATH environment variable!
+#
+# 7: Label text contents: Please add
+#
+Please add
+#
+# 8: Label text contents: to the PATH environment variable
+#
+to the PATH environment variable
+#
+# 9: Label text contents: Please remove
+#
+Please remove
+#
+# 10: Label text contents: from the PATH environment variable
+#
+from the PATH environment variable
+#
+# 11: Label text contents: and reboot the computer as soon as possible.
+#
+and reboot the computer as soon as possible.
+#
+# 12
+#
+WxBmpp - EPS image
+#
+# 13
+#
+WxBmpp - PDF image
+#
+# 14
+#
+WxBmpp - PDF object
+#
+# 15
+#
+WxBmpp - PDF document
+#
+# 16
+#
+WxBmpp - PS document
+#
+# 17
+#
+WinPrint - default printer
+#
+# 18
+#
+WinPrint - specify printer
+#
+# 19
+#
+Open in WxBmpp
+#
+# 20
+#
+Open in WxDkct
+#
+# 21
+#
+Checksums
+$!end
+};
+
+
+
+/** Constant texts, not localized.
+*/
+wxChar const * const dkwxpath_nl_wx[] = {
+$!string-table macro=wxT
+Error
+Not enough memory (RAM)!
+$!end
+};
+
+
+static dkChar const dkwxpath_groupname[] = { dkT("dktools") };
+
+
+
+static dkChar const dkwxpath_string_table[] = { dkT("dkwxpath.str") };
+
+
+
+bool
+DkWxPathApp::OnInit()
+{
+ bool back = false;
+ DkWxPathFrame *frame = NULL;
+ wxChar const * const *localizedTexts = NULL;
+ dkChar const * const *dkLocalizedTexts = NULL;
+ wxXPMHandler *phXpm = NULL;
+ wxICOHandler *phIco = NULL;
+
+ $!trace-init c:\\temp\\dkwpath.deb
+ $? " + OnInit"
+
+ pHelper =
+ new DkWxAppHelper(argv[0], dkwxpath_default_texts[2], dkwxpath_groupname);
+ if (NULL == pHelper) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ if (!(pHelper->checkSetup())) {
+ goto finished;
+ }
+
+ localizedTexts =
+ pHelper->getStringTable(dkwxpath_default_texts, dkwxpath_string_table);
+ dkLocalizedTexts = dk3app_messages(
+ pHelper->getApp(), dkwxpath_string_table,
+ (dkChar const **)dkwxpath_default_texts
+ );
+ if ((NULL == localizedTexts) || (NULL == dkLocalizedTexts)) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ phXpm = new wxXPMHandler();
+ if (NULL != phXpm) {
+ wxImage::AddHandler(phXpm);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phIco = new wxICOHandler();
+ if (NULL != phIco) {
+ wxImage::AddHandler(phIco);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ frame = new DkWxPathFrame(
+ dkwxpath_default_texts[4], localizedTexts, dkLocalizedTexts, pHelper,
+ DkWxPath_MainWindow, argc, argv
+ );
+ if (NULL == frame) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ frame->Show();
+ frame->restorePosition();
+ back = true;
+
+ finished:
+ if (!(back)) {
+ if (NULL != pHelper) {
+ delete(pHelper); pHelper = NULL;
+ }
+ }
+ $? "- OnInit %d", (int)back
+ return back;
+}
+
+
+
+int
+DkWxPathApp::OnExit()
+{
+ int back = 0;
+ $? "+ OnExit"
+ if(pHelper) {
+ delete(pHelper); pHelper = NULL;
+ }
+ $? "- OnExit"
+ $!trace-end
+ return back;
+}
+
+
+
+void
+DkWxPathApp::ShowMemoryErrorMessage(void)
+{
+ const wxChar *s_title = NULL;
+ const wxChar *s_text = NULL;
+
+ if (NULL != pHelper) {
+ s_title = pHelper->getBasicString(3);
+ s_text = pHelper->getBasicString(9);
+ }
+ if (NULL == s_title) {
+ s_title = dkwxpath_nl_wx[0];
+ }
+ if (NULL == s_text) {
+ s_text = dkwxpath_nl_wx[1];
+ }
+ wxMessageBox(s_text, s_title, (wxOK | wxCENTRE | wxICON_ERROR));
+}
+
diff --git a/support/dktools/DkWxPathApp.h b/support/dktools/DkWxPathApp.h
new file mode 100644
index 0000000000..1a4a2b4bd2
--- /dev/null
+++ b/support/dktools/DkWxPathApp.h
@@ -0,0 +1,79 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxPathApp.cpt
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxPathApp.h Header file for the DkWxPathApp module.
+*/
+
+#ifndef DKWXPATHAPP_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DKWXPATHAPP_H_INCLUDED 1
+
+
+#line 10 "DkWxPathApp.cpt"
+
+/** Application to set PATH variable for DK tools.
+*/
+class DkWxPathApp : public wxApp
+{
+ protected:
+
+ /** Helper object.
+ */
+ DkWxAppHelper *pHelper;
+
+ protected:
+
+ /** Show error message if not sufficient memory available.
+ */
+ void
+ ShowMemoryErrorMessage(void);
+
+ public:
+
+ /** Initialize the application.
+ */
+ virtual bool OnInit();
+
+ /** Clean up after running.
+ */
+ virtual int OnExit();
+};
+
+DECLARE_APP(DkWxPathApp)
+
+
+
+
+#endif
diff --git a/support/dktools/DkWxPathFrame.cpp b/support/dktools/DkWxPathFrame.cpp
new file mode 100644
index 0000000000..0e166e3445
--- /dev/null
+++ b/support/dktools/DkWxPathFrame.cpp
@@ -0,0 +1,1044 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxPathFrame.wxc
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxPathFrame.cpp The DkWxPathFrame module.
+*/
+
+
+#line 118 "DkWxPathFrame.wxc"
+
+#include "dk3conf.h"
+#include "dk3types.h"
+#include "dk3wreg.h"
+#include "dkwxpath.h"
+#include "dkicon.xpm"
+
+
+
+#line 126 "DkWxPathFrame.wxc"
+
+
+BEGIN_EVENT_TABLE(DkWxPathFrame, wxFrame)
+ EVT_IDLE(DkWxPathFrame::OnIdle)
+END_EVENT_TABLE()
+
+
+
+/** Description of a context menu item.
+*/
+typedef struct {
+ dkChar const *menuitem; /**< Context menu item text. */
+ dkChar const *progname; /**< Program name. */
+ dkChar const *arguments; /**< Program command line arguments. */
+} dkwxpath_action_t;
+
+
+
+/** File suffix information.
+*/
+typedef struct {
+ dkChar const *suffix; /**< File type suffix including the dot. */
+ dkChar const *classname; /**< Class name if no class assigned yet. */
+ dkwxpath_action_t *items; /**< Context menu items. */
+} dkwxpath_filetype_t;
+
+
+
+/** Context menu items for PNG.
+*/
+static dkwxpath_action_t dkwxpath_png_actions[] = {
+ { NULL /* 12 */ , dkT("wxbmpp.exe"), dkT("-leps.image \"%1\"") },
+ { NULL /* 13 */ , dkT("wxbmpp.exe"), dkT("-lpdf.image \"%1\"") },
+ { NULL /* 14 */ , dkT("wxbmpp.exe"), dkT("-lpdf.object \"%1\"") },
+ { NULL, NULL, NULL }
+};
+
+/** Context menu items for JPEG.
+*/
+static dkwxpath_action_t dkwxpath_jpeg_actions[] = {
+ { NULL /* 12 */ , dkT("wxbmpp.exe"), dkT("-leps.image \"%1\"") },
+ { NULL /* 13 */ , dkT("wxbmpp.exe"), dkT("-lpdf.image \"%1\"") },
+ { NULL, NULL, NULL }
+};
+
+/** Context menu items for TIFF.
+*/
+static dkwxpath_action_t dkwxpath_tiff_actions[] = {
+ { NULL /* 12 */ , dkT("wxbmpp.exe"), dkT("-leps.image \"%1\"") },
+ { NULL /* 15 */ , dkT("wxbmpp.exe"), dkT("-lpdf.document \"%1\"") },
+ { NULL /* 13 */ , dkT("wxbmpp.exe"), dkT("-lpdf.image \"%1\"") },
+ { NULL /* 14 */ , dkT("wxbmpp.exe"), dkT("-lpdf.object \"%1\"") },
+ { NULL /* 16 */ , dkT("wxbmpp.exe"), dkT("-lps.document \"%1\"") },
+ { NULL, NULL, NULL }
+};
+
+/** Context menu items for PRN and PS files.
+*/
+static dkwxpath_action_t dkwxpath_ps_actions[] = {
+ { NULL /* 17 */ , dkT("winprint.exe"), dkT("-d \"%1\"") },
+ { NULL /* 18 */ , dkT("winprint.exe"), dkT("\"%1\"") },
+ { NULL, NULL, NULL }
+};
+
+/** Context menu items for directories.
+*/
+static dkwxpath_action_t dkwxpath_directory_actions[] = {
+ { NULL /* 19 */ , dkT("wxbmpp.exe"), dkT("\"%1\"") },
+ { NULL /* 20 */ , dkT("wxdkct.exe"), dkT("\"%1\"") },
+ { NULL, NULL, NULL }
+};
+
+
+/** File types to set up.
+*/
+static dkwxpath_filetype_t dkwxpath_filetypes[] = {
+ { dkT(".png"), dkT("pngfile"), dkwxpath_png_actions },
+ { dkT(".jpg"), dkT("jpegfile"), dkwxpath_jpeg_actions},
+ { dkT(".jpeg"), dkT("jpegfile"), dkwxpath_jpeg_actions},
+ { dkT(".tif"), dkT("tifffile"), dkwxpath_tiff_actions},
+ { dkT(".tiff"), dkT("tifffile"), dkwxpath_tiff_actions},
+ { dkT(".prn"), dkT("prnfile"), dkwxpath_ps_actions},
+ { dkT(".ps"), dkT("psfile"), dkwxpath_ps_actions},
+ { NULL, NULL, NULL }
+};
+
+
+
+dkChar const * const dkwxpath_noloc[] = {
+/* 0 */
+dkT("\\shell"),
+
+/* 1 */
+dkT("\\command"),
+
+/* 2 */
+dkT("\""),
+
+/* 3 */
+dkT(" "),
+
+/* 4 */
+dkT("\\"),
+
+/* 5 */
+dkT("Directory"),
+
+/* 6 */
+dkT("wxdkfcs.exe"),
+
+/* 7 */
+dkT("\"%1\""),
+
+/* 8 */
+dkT("*\\shell"),
+
+NULL
+
+
+#line 253 "DkWxPathFrame.wxc"
+};
+
+#if DK3_ON_WINDOWS && ((DK3_CHAR_SIZE == 1) || (DK3_CHAR_SIZE == 2))
+
+/** Registry key in HKLM containing system environment variables.
+*/
+static dkChar const dkwxpath_registry_key[] = {
+dkT("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment")
+};
+
+/** Registry value name.
+*/
+static dkChar const dkwxpath_registry_name[] = {
+dkT("Path")
+};
+
+
+/** Separator of PATH components.
+*/
+static dkChar const dkwxpath_sep[] = {
+dkT(";")
+};
+
+#endif
+/* if DK3_ON_WINDOWS */
+
+
+#if DK3_ON_WINDOWS && ((DK3_CHAR_SIZE == 1) || (DK3_CHAR_SIZE == 2))
+/** Check whether or not a directory is already contained in the PATH.
+ @param bu Current PATH value.
+ @param dn Directory name to check for.
+ @return 1 on success (@a dn already contained), 0 otherwise.
+*/
+static
+int
+dk3_win_check_path(dkChar *bu, dkChar const *dn)
+{
+ dkChar *pc;
+ dkChar *pn;
+ int back = 0;
+
+
+#line 294 "DkWxPathFrame.wxc"
+ pc = bu;
+ while((pc) && (0 == back)) {
+ pn = dk3str_chr(pc, dkT(';'));
+ if(pn) { *(pn++) = dkT('\0'); }
+ if(0 == dk3str_fncmp(pc, dn)) {
+ back = 1;
+ }
+ pc = pn;
+ }
+
+#line 303 "DkWxPathFrame.wxc"
+ return back;
+}
+#endif
+/* if DK3_ON_WINDOWS */
+
+
+
+/** Register context menu entries.
+ @param dn Installation directory name, bin subdirectory.
+ @param cl Class name.
+ @param act Actions list.
+ @param app Application structure for diagnostics, may be NULL.
+*/
+static
+void
+dkwxpath_register_context_entries(
+ dkChar const *dn, dkChar const *cl, dkwxpath_action_t *act, dk3_app_t *app
+)
+{
+ dkChar kn1[DK3_MAX_PATH];
+ dkChar kn2[DK3_SIZEOF(kn1,dkChar)];
+ dkwxpath_action_t *acp;
+ size_t szk;
+ size_t szv;
+ HKEY hk;
+
+
+#line 329 "DkWxPathFrame.wxc"
+ acp = act;
+ while((acp->menuitem) && (acp->progname) && (acp->arguments)) {
+ szk = 2 + dk3str_len(cl) + dk3str_len(dkwxpath_noloc[0])
+ + dk3str_len(acp->menuitem) + dk3str_len(dkwxpath_noloc[1]);
+ szv = 5 + dk3str_len(dn) + dk3str_len(acp->progname)
+ + dk3str_len(acp->arguments);
+ if((szk < DK3_MAX_PATH) && (szv < DK3_MAX_PATH)) {
+ dk3str_cpy(kn1, cl);
+
+#line 337 "DkWxPathFrame.wxc"
+ if(dk3wreg_key_create_read(HKEY_CLASSES_ROOT, kn1, &hk, app)) {
+ dk3wreg_key_close(hk, kn1, app);
+ dk3str_cpy(kn1, cl);
+ dk3str_cat(kn1, dkwxpath_noloc[0]);
+
+#line 341 "DkWxPathFrame.wxc"
+ if(dk3wreg_key_create_read(HKEY_CLASSES_ROOT, kn1, &hk, app)) {
+ dk3wreg_key_close(hk, kn1, app);
+ dk3str_cpy(kn1, cl);
+ dk3str_cat(kn1, dkwxpath_noloc[0]);
+ dk3str_cat(kn1, dkwxpath_noloc[4]);
+ dk3str_cat(kn1, acp->menuitem);
+
+#line 347 "DkWxPathFrame.wxc"
+ if(dk3wreg_key_create_read(HKEY_CLASSES_ROOT, kn1, &hk, app)) {
+ dk3wreg_key_close(hk, kn1, app);
+ dk3str_cpy(kn1, cl);
+ dk3str_cat(kn1, dkwxpath_noloc[0]);
+ dk3str_cat(kn1, dkwxpath_noloc[4]);
+ dk3str_cat(kn1, acp->menuitem);
+ dk3str_cat(kn1, dkwxpath_noloc[1]);
+
+#line 354 "DkWxPathFrame.wxc"
+ dk3str_cpy(kn2, dkwxpath_noloc[2]);
+ dk3str_cat(kn2, dn);
+ dk3str_cat(kn2, dkwxpath_noloc[4]);
+ dk3str_cat(kn2, acp->progname);
+ dk3str_cat(kn2, dkwxpath_noloc[2]);
+ dk3str_cat(kn2, dkwxpath_noloc[3]);
+ dk3str_cat(kn2, acp->arguments);
+
+#line 361 "DkWxPathFrame.wxc"
+ if(dk3wreg_key_create_modify(HKEY_CLASSES_ROOT, kn1, &hk, app)) {
+ (void)dk3wreg_set_sz(hk, NULL, kn2, app);
+
+#line 363 "DkWxPathFrame.wxc"
+ dk3wreg_key_close(hk, kn1, app);
+ }
+ }
+ }
+ }
+ }
+ acp++;
+ }
+ /* Checksums for files */
+
+
+#line 373 "DkWxPathFrame.wxc"
+}
+
+
+
+/** Remove context menu items.
+ @param dn Base directory name.
+ @param cl Class name.
+ @param act Actions to delete.
+ @param app Application structure for diagnostics, may be NULL.
+*/
+static
+void
+dkwxpath_unregister_context_entries(
+ dkChar const *dn, dkChar const *cl, dkwxpath_action_t *act, dk3_app_t *app
+)
+{
+ dkChar kn1[DK3_MAX_PATH];
+ dkwxpath_action_t *acp;
+ size_t szk;
+
+
+#line 393 "DkWxPathFrame.wxc"
+ acp = act;
+ while((acp->menuitem) && (acp->progname) && (acp->arguments)) {
+ szk = 2 + dk3str_len(cl) + dk3str_len(dkwxpath_noloc[0])
+ + dk3str_len(acp->menuitem);
+ if(szk < DK3_MAX_PATH) {
+ dk3str_cpy(kn1, cl);
+ dk3str_cat(kn1, dkwxpath_noloc[0]);
+ dk3str_cat(kn1, dkwxpath_noloc[4]);
+ dk3str_cat(kn1, acp->menuitem);
+
+#line 402 "DkWxPathFrame.wxc"
+ (void)dk3wreg_key_delete(HKEY_CLASSES_ROOT, kn1, app);
+ }
+ acp++;
+ }
+
+
+#line 407 "DkWxPathFrame.wxc"
+}
+
+
+
+/** Register context menus.
+ @param dn Directory name (bin subdirectory).
+ @param app Application structure for diagnostics, may be NULL.
+*/
+static
+void
+dkwxpath_register_context_menus(
+ dkChar const *dn, dk3_app_t *app, const dkChar *cmn
+)
+{
+ dkChar cln[DK3_MAX_PATH];
+ dkChar clo[DK3_MAX_PATH];
+ dkwxpath_filetype_t *ftp;
+ size_t szcln = DK3_SIZEOF(cln,dkChar);
+ size_t szk;
+ size_t szv;
+ int hcl;
+ HKEY hk;
+
+
+#line 430 "DkWxPathFrame.wxc"
+ ftp = dkwxpath_filetypes;
+ while((ftp->suffix) && (ftp->classname) && (ftp->items)) {
+
+
+#line 433 "DkWxPathFrame.wxc"
+
+
+#line 434 "DkWxPathFrame.wxc"
+ cln[0] = dkT('\0');
+ hcl = 0;
+ if(dk3wreg_key_create_modify(HKEY_CLASSES_ROOT, ftp->suffix, &hk, app)) {
+ if(dk3wreg_get_sz(hk, NULL, cln, DK3_SIZEOF(cln,dkChar), app)) {
+ if(0 < dk3str_len(cln)) {
+ hcl = 1;
+ }
+ }
+ if(0 == hcl) {
+ dk3wreg_set_sz(hk, NULL, ftp->classname, app);
+ }
+ dk3wreg_key_close(hk, ftp->suffix, app);
+ if(hcl) {
+ dkwxpath_register_context_entries(dn, cln, ftp->items, app);
+ } else {
+ dkwxpath_register_context_entries(dn, ftp->classname, ftp->items, app);
+ }
+ }
+ ftp++;
+ }
+ dkwxpath_register_context_entries(
+ dn, dkwxpath_noloc[5], dkwxpath_directory_actions, app
+ );
+ szk = dk3str_len(dkwxpath_noloc[8])
+ + dk3str_len(dkwxpath_noloc[4])
+ + dk3str_len(cmn)
+ + dk3str_len(dkwxpath_noloc[1]);
+ szv = 2 * dk3str_len(dkwxpath_noloc[2]) + dk3str_len(dn)
+ + dk3str_len(dkwxpath_noloc[4])
+ + dk3str_len(dkwxpath_noloc[6])
+ + dk3str_len(dkwxpath_noloc[3])
+ + dk3str_len(dkwxpath_noloc[7]);
+ if ((szk < szcln) && (szv < szcln)) {
+ dk3str_cpy(clo, dkwxpath_noloc[2]);
+ dk3str_cat(clo, dn);
+ dk3str_cat(clo, dkwxpath_noloc[4]);
+ dk3str_cat(clo, dkwxpath_noloc[6]);
+ dk3str_cat(clo, dkwxpath_noloc[2]);
+ dk3str_cat(clo, dkwxpath_noloc[3]);
+ dk3str_cat(clo, dkwxpath_noloc[7]);
+ dk3str_cpy(cln, dkwxpath_noloc[8]);
+ dk3str_cat(cln, dkwxpath_noloc[4]);
+ dk3str_cat(cln, cmn);
+ if(dk3wreg_key_create_modify(HKEY_CLASSES_ROOT, cln, &hk, app)) {
+ dk3wreg_key_close(hk, cln, app);
+ }
+ dk3str_cat(cln, dkwxpath_noloc[1]);
+ if(dk3wreg_key_create_modify(HKEY_CLASSES_ROOT, cln, &hk, app)) {
+ (void)dk3wreg_set_sz(hk, NULL, clo, app);
+ dk3wreg_key_close(hk, cln, app);
+ }
+ }
+
+
+#line 487 "DkWxPathFrame.wxc"
+}
+
+
+
+static
+void
+dkwxpath_unregister_context_menus(
+ dkChar const *dn, dk3_app_t *app, const dkChar *cmn
+)
+{
+ dkChar cln[DK3_MAX_PATH];
+ dkwxpath_filetype_t *ftp;
+ size_t szcln = DK3_SIZEOF(cln,dkChar);
+ size_t szk;
+ int hcl;
+ HKEY hk;
+
+
+#line 504 "DkWxPathFrame.wxc"
+ ftp = dkwxpath_filetypes;
+ while((ftp->suffix) && (ftp->classname) && (ftp->items)) {
+
+
+#line 507 "DkWxPathFrame.wxc"
+
+
+#line 508 "DkWxPathFrame.wxc"
+ cln[0] = dkT('\0');
+ hcl = 0;
+ if(dk3wreg_key_create_modify(HKEY_CLASSES_ROOT, ftp->suffix, &hk, app)) {
+ if(dk3wreg_get_sz(hk, NULL, cln, DK3_SIZEOF(cln,dkChar), app)) {
+ if(0 < dk3str_len(cln)) {
+ hcl = 1;
+ }
+ }
+ dk3wreg_key_close(hk, ftp->suffix, app);
+ if(hcl) {
+ dkwxpath_unregister_context_entries(dn, cln, ftp->items, app);
+ }
+ }
+ ftp++;
+ }
+ dkwxpath_unregister_context_entries(
+ dn, dkwxpath_noloc[5], dkwxpath_directory_actions, app
+ );
+ szk = dk3str_len(dkwxpath_noloc[8])
+ + dk3str_len(dkwxpath_noloc[4])
+ + dk3str_len(cmn);
+ if (szk < szcln) {
+ dk3str_cpy(cln, dkwxpath_noloc[8]);
+ dk3str_cat(cln, dkwxpath_noloc[4]);
+ dk3str_cat(cln, cmn);
+ (void)dk3wreg_key_delete(HKEY_CLASSES_ROOT, cln, app);
+ }
+
+
+#line 536 "DkWxPathFrame.wxc"
+}
+
+
+
+/** Ensure dn is listed in the PATH environment variable.
+ @param dn New component to include in PATH.
+ @return 0 on failure, 1 on success (added),
+ 2 on success (dn already in PATH).
+*/
+static
+int
+dkwxpath_set_regentry(dkChar const *dn, dk3_app_t *app, const dkChar *cmn)
+{
+ int back = 0;
+#if DK3_ON_WINDOWS && ((DK3_CHAR_SIZE == 1) || (DK3_CHAR_SIZE == 2))
+ dkChar b1[16 * DK3_MAX_PATH];
+ dkChar b2[16 * DK3_MAX_PATH];
+ DWORD dwType;
+ DWORD dwSz;
+ LONG res;
+ size_t sl;
+ REGSAM regsam;
+ HKEY regkey;
+
+
+#line 560 "DkWxPathFrame.wxc"
+ regsam = KEY_ALL_ACCESS;
+#if DK3_CHAR_SIZE == 2
+ res = RegOpenKeyExW(
+ HKEY_LOCAL_MACHINE, dkwxpath_registry_key, (DWORD)0UL, regsam, &regkey
+ );
+#else
+ res = RegOpenKeyExA(
+ HKEY_LOCAL_MACHINE, dkwxpath_registry_key, (DWORD)0UL, regsam, &regkey
+ );
+#endif
+ if(ERROR_SUCCESS == res) {
+
+#line 571 "DkWxPathFrame.wxc"
+ dwType = REG_EXPAND_SZ;
+ dwSz = (DWORD)sizeof(b1);
+#if DK3_CHAR_SIZE == 2
+ res = RegQueryValueExW(
+ regkey, dkwxpath_registry_name, NULL, &dwType,
+ (LPBYTE)b1, &dwSz
+ );
+#else
+ res = RegQueryValueExA(
+ regkey, dkwxpath_registry_name, NULL, &dwType,
+ (LPBYTE)b1, &dwSz
+ );
+#endif
+ if(ERROR_SUCCESS == res) {
+
+#line 585 "DkWxPathFrame.wxc"
+ res = 1L;
+#if DK3_CHAR_SIZE == 2
+ if(dwSz % (DWORD)2L) {
+
+#line 588 "DkWxPathFrame.wxc"
+ res = 0L;
+ } else {
+
+#line 590 "DkWxPathFrame.wxc"
+ dwSz = dwSz / (DWORD)2L;
+ }
+#endif
+ if(dwType != REG_SZ) {
+ if(dwType != REG_EXPAND_SZ) {
+
+#line 595 "DkWxPathFrame.wxc"
+ res = 0L;
+ }
+ }
+ if(1L == res) {
+
+#line 599 "DkWxPathFrame.wxc"
+ if((DWORD)0L < dwSz) {
+
+#line 600 "DkWxPathFrame.wxc"
+ if(dwSz < DK3_SIZEOF(b1,dkChar)) {
+
+#line 601 "DkWxPathFrame.wxc"
+ b1[dwSz] = dkT('\0');
+ dk3str_cpy(b2, b1);
+ if(dk3_win_check_path(b2, dn)) {
+ back = 2;
+ } else {
+ sl = dk3str_len(b1);
+ sl += dk3str_len(dn);
+ sl += 1;
+ if(sl < DK3_SIZEOF(b2,dkChar)) {
+ dk3str_cpy(b2, dn);
+ dk3str_cat(b2, dkwxpath_sep);
+ dk3str_cat(b2, b1);
+#if DK3_CHAR_SIZE == 2
+ res = RegSetValueExW(
+ regkey, dkwxpath_registry_name, (DWORD)0L, dwType,
+ (BYTE const *)b2,
+ (DWORD)(2 * (1 + dk3str_len(b2)))
+ );
+#else
+ res = RegSetValueExA(
+ regkey, dkwxpath_registry_name, (DWORD)0L, dwType,
+ (BYTE const *)b2,
+ (DWORD)(1 + dk3str_len(b2))
+ );
+#endif
+ if(ERROR_SUCCESS == res) {
+ back = 1;
+ }
+ } else {
+
+#line 630 "DkWxPathFrame.wxc"
+ }
+ }
+ } else {
+
+#line 633 "DkWxPathFrame.wxc"
+ }
+ } else {
+
+#line 635 "DkWxPathFrame.wxc"
+ }
+ }
+ } else {
+
+#line 638 "DkWxPathFrame.wxc"
+ }
+ RegCloseKey(regkey);
+ } else {
+
+#line 641 "DkWxPathFrame.wxc"
+ }
+ dkwxpath_register_context_menus(dn, app, cmn);
+#else
+ /* Simulate results to test dialogs. */
+#endif
+/* if DK3_ON_WINDOWS ... */
+
+
+#line 648 "DkWxPathFrame.wxc"
+ return back;
+}
+
+
+
+#if DK3_ON_WINDOWS && ((DK3_CHAR_SIZE == 2) || (DK3_CHAR_SIZE == 1))
+static
+void
+dkwxpath_remove(dkChar *dp, dkChar *sp, dkChar const *dn)
+{
+ dkChar *pc;
+ dkChar *pn;
+ bool isfirst = true;
+
+ *dp = dkT('\0');
+ pc = sp;
+ while(pc) {
+ pn = dk3str_chr(pc, dkT(';'));
+ if(pn) { *(pn++) = dkT('\0'); }
+ if(dk3str_fncmp(pc, dn)) {
+ if(isfirst) {
+ isfirst = false;
+ dk3str_cpy(dp, pc);
+ } else {
+ dk3str_cat(dp, dkwxpath_sep);
+ dk3str_cat(dp, pc);
+ }
+ }
+ pc = pn;
+ }
+}
+#endif
+/* if DK3_ON_WINDOWS && ... */
+
+
+/** Ensure dn is not listed in the PATH environment variable.
+ @param dn Component to exclude from PATH.
+ @return 0 on failure, 1 on success (removed),
+ 2 on success (dn not contained).
+*/
+static
+int
+dkwxpath_unset_regentry(dkChar const *dn, dk3_app_t *app, const dkChar *cmn)
+{
+ int back = 0;
+
+
+#line 694 "DkWxPathFrame.wxc"
+#if DK3_ON_WINDOWS && ((DK3_CHAR_SIZE == 1) || (DK3_CHAR_SIZE == 2))
+ dkChar b1[16 * DK3_MAX_PATH];
+ dkChar b2[16 * DK3_MAX_PATH];
+ DWORD dwType;
+ DWORD dwSz;
+ LONG res;
+ REGSAM regsam;
+ HKEY regkey;
+
+ regsam = KEY_ALL_ACCESS;
+#if DK3_CHAR_SIZE == 2
+ res = RegOpenKeyExW(
+ HKEY_LOCAL_MACHINE, dkwxpath_registry_key, (DWORD)0UL, regsam, &regkey
+ );
+#else
+ res = RegOpenKeyExA(
+ HKEY_LOCAL_MACHINE, dkwxpath_registry_key, (DWORD)0UL, regsam, &regkey
+ );
+#endif
+ if(ERROR_SUCCESS == res) {
+
+#line 714 "DkWxPathFrame.wxc"
+ dwType = REG_EXPAND_SZ;
+ dwSz = (DWORD)sizeof(b1);
+#if DK3_CHAR_SIZE == 2
+ res = RegQueryValueExW(
+ regkey, dkwxpath_registry_name, NULL, &dwType,
+ (LPBYTE)b1, &dwSz
+ );
+#else
+ res = RegQueryValueExA(
+ regkey, dkwxpath_registry_name, NULL, &dwType,
+ (LPBYTE)b1, &dwSz
+ );
+#endif
+ if(ERROR_SUCCESS == res) {
+
+#line 728 "DkWxPathFrame.wxc"
+ res = 1L;
+#if DK3_CHAR_SIZE == 2
+ if(dwSz % (DWORD)2L) {
+ res = 0L;
+ } else {
+ dwSz = dwSz / (DWORD)2L;
+ }
+#endif
+ if(dwType != REG_SZ) {
+ if(dwType != REG_EXPAND_SZ) {
+ res = 0L;
+ }
+ }
+ if(1L == res) {
+
+#line 742 "DkWxPathFrame.wxc"
+ if((DWORD)0L < dwSz) {
+
+#line 743 "DkWxPathFrame.wxc"
+ if(dwSz < DK3_SIZEOF(b1,dkChar)) {
+ b1[dwSz] = dkT('\0');
+ dkwxpath_remove(b2, b1, dn);
+#if DK3_CHAR_SIZE == 2
+ res = RegSetValueExW(
+ regkey, dkwxpath_registry_name, (DWORD)0L, dwType,
+ (BYTE const *)b2,
+ (DWORD)(2 * (1 + dk3str_len(b2)))
+ );
+#else
+ res = RegSetValueExA(
+ regkey, dkwxpath_registry_name, (DWORD)0L, dwType,
+ (BYTE const *)b2,
+ (DWORD)(1 + dk3str_len(b2))
+ );
+#endif
+ if(ERROR_SUCCESS == res) {
+
+#line 760 "DkWxPathFrame.wxc"
+ back = 1;
+ } else {
+
+#line 762 "DkWxPathFrame.wxc"
+ }
+ }
+ } else {
+
+#line 765 "DkWxPathFrame.wxc"
+ }
+ } else {
+
+#line 767 "DkWxPathFrame.wxc"
+ }
+ } else {
+
+#line 769 "DkWxPathFrame.wxc"
+ }
+ RegCloseKey(regkey);
+ } else {
+
+#line 772 "DkWxPathFrame.wxc"
+ }
+ dkwxpath_unregister_context_menus(dn, app, cmn);
+#endif
+
+
+#line 776 "DkWxPathFrame.wxc"
+ return back;
+}
+
+
+
+
+#line 782 "DkWxPathFrame.wxc"
+DkWxPathFrame::DkWxPathFrame(
+ wxChar const *applicationName,
+ wxChar const * const *localizedTexts,
+ dkChar const * const *dkLocalizedTexts,
+ DkWxAppHelper *applicationHelper,
+ int idMain,
+ int argc,
+ wxChar **argv
+) : DkWxFrame(applicationName, applicationHelper, NULL, idMain),
+ mProtectData(wxMUTEX_DEFAULT)
+{
+#if defined(__WXMSW__)
+ wxIcon dkicon_bitmap(wxT("aaaaa"));
+#else
+ wxIcon dkicon_bitmap(dkicon_xpm);
+#endif
+ sTexts = localizedTexts;
+ dkTexts = dkLocalizedTexts;
+ bRunning = false;
+ bUninstall = false;
+ dkctGUILayoutOK = false;
+ dkctGUIContentsPanel = NULL;
+ mainSizer = NULL;
+ horizontalSizer = NULL;
+ lModifying = NULL;
+ dkctGUIContentsPanel = new wxPanel(this);
+ if(!(dkctGUIContentsPanel)) {
+ goto dkctGUILayoutFinished;
+ }
+ mainSizer = new wxBoxSizer(
+ wxVERTICAL
+ );
+ if(!(mainSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ mainSizer->Add(10, 10, 0);
+ horizontalSizer = new wxBoxSizer(
+ wxHORIZONTAL
+ );
+ if(!(horizontalSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ horizontalSizer->Add(10, 10, 0);
+ lModifying = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[3]
+ );
+ if(!(lModifying)) {
+ goto dkctGUILayoutFinished;
+ }
+ horizontalSizer->Add(
+ lModifying
+ );
+ horizontalSizer->Add(10, 10, 0);
+ mainSizer->Add(
+ horizontalSizer
+ );
+ mainSizer->Add(10, 10, 0);
+ dkctGUIContentsPanel->SetSizer(mainSizer);
+ SetIcon(dkicon_bitmap);
+ dkctGUILayoutOK = true;
+ dkctGUILayoutFinished:
+ if(dkctGUILayoutOK) {
+ mainSizer->Fit(this);
+ mainSizer->SetSizeHints(this);
+ }
+
+#line 803 "DkWxPathFrame.wxc"
+#if 0
+ restorePosition();
+#endif
+ processArguments(argc, argv);
+ /* Set context menu item texts
+ */
+ dkwxpath_png_actions[0].menuitem = dkLocalizedTexts[12];
+ dkwxpath_png_actions[1].menuitem = dkLocalizedTexts[13];
+ dkwxpath_png_actions[2].menuitem = dkLocalizedTexts[14];
+ dkwxpath_jpeg_actions[0].menuitem = dkLocalizedTexts[12];
+ dkwxpath_jpeg_actions[1].menuitem = dkLocalizedTexts[13];
+ dkwxpath_tiff_actions[0].menuitem = dkLocalizedTexts[12];
+ dkwxpath_tiff_actions[1].menuitem = dkLocalizedTexts[15];
+ dkwxpath_tiff_actions[2].menuitem = dkLocalizedTexts[13];
+ dkwxpath_tiff_actions[3].menuitem = dkLocalizedTexts[14];
+ dkwxpath_tiff_actions[4].menuitem = dkLocalizedTexts[16];
+ dkwxpath_ps_actions[0].menuitem = dkLocalizedTexts[17];
+ dkwxpath_ps_actions[1].menuitem = dkLocalizedTexts[18];
+ dkwxpath_directory_actions[0].menuitem = dkLocalizedTexts[19];
+ dkwxpath_directory_actions[1].menuitem = dkLocalizedTexts[20];
+}
+
+
+#line 826 "DkWxPathFrame.wxc"
+
+
+
+bool
+DkWxPathFrame::mustStart()
+{
+ bool back = false;
+ {
+ wxMutexLocker lock(mProtectData);
+ if(lock.IsOk()) {
+ if(!bRunning) {
+ back = true;
+ bRunning = true;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void DkWxPathFrame::OnIdle(wxIdleEvent & event)
+{
+ wxChar bindir[DK3_MAX_PATH];
+ dk3_app_t *app;
+ dkChar const *dkbindir;
+ bool doRun;
+ bool haveBinDir;
+ int res;
+
+ haveBinDir = false;
+ app = NULL;
+ dkbindir = NULL;
+ doRun = mustStart();
+ /*
+ Modify PATH variable.
+ */
+ if(doRun) {
+ res = 1;
+#if DK3_ON_WINDOWS && ((DK3_CHAR_SIZE == 1) || (DK3_CHAR_SIZE == 2))
+ res = 0;
+ app = pHelper->getApp();
+ if(app) {
+ dkbindir = dk3app_get_bindir(app);
+ if(dkbindir) {
+ if(bUninstall) {
+ res = dkwxpath_unset_regentry(dkbindir, app, dkTexts[21]);
+ } else {
+ res = dkwxpath_set_regentry(dkbindir, app, dkTexts[21]);
+ }
+ Sleep(250);
+ }
+ }
+#endif
+ if(0 == res) {
+ app = pHelper->getApp();
+ if(app) {
+ dkbindir = dk3app_get_bindir(app);
+ if(dkbindir) {
+ haveBinDir = pHelper->dkToWx(
+ bindir, DK3_SIZEOF(bindir,wxChar), dkbindir
+ );
+ }
+ }
+ wxString msg(wxT(""));
+ msg.Append(sTexts[6]);
+ msg.Append(wxT("\n"));
+ if(bUninstall) {
+ msg.Append(sTexts[9]);
+ msg.Append(wxT("\n"));
+ if(haveBinDir) {
+ msg.Append(wxT("\n"));
+ msg.Append(bindir);
+ msg.Append(wxT("\n"));
+ msg.Append(wxT("\n"));
+ }
+ msg.Append(sTexts[10]);
+ } else {
+ msg.Append(sTexts[7]);
+ msg.Append(wxT("\n"));
+ if(haveBinDir) {
+ msg.Append(wxT("\n"));
+ msg.Append(bindir);
+ msg.Append(wxT("\n"));
+ msg.Append(wxT("\n"));
+ }
+ msg.Append(sTexts[8]);
+ }
+ msg.Append(wxT("\n"));
+ msg.Append(sTexts[11]);
+ wxMessageBox(msg, sTexts[5], (wxOK | wxICON_ERROR), this);
+ }
+ }
+ /*
+ Skip further event processing.
+ */
+ event.Skip();
+ /*
+ Close window.
+ */
+ if(doRun) {
+ Show(false);
+ Close();
+ }
+}
+
+
+bool
+DkWxPathFrame::canClose(bool isLast)
+{
+ if(isLast) {
+ savePosition();
+ }
+ return true;
+}
+
+
+
+
+static const wxCmdLineEntryDesc dkwxpath_cmd_line_desc[] = {
+ {
+ wxCMD_LINE_SWITCH,
+ wxT_2("u"),
+ wxT_2("uninstall"),
+ wxT_2("Uninstall DK tools and libraries")
+ },
+ { wxCMD_LINE_NONE }
+};
+
+
+
+void
+DkWxPathFrame::processArguments(int argc, wxChar **argv)
+{
+ wxLogNull log;
+ int res;
+
+
+#line 963 "DkWxPathFrame.wxc"
+ wxCmdLineParser parser(dkwxpath_cmd_line_desc, argc, argv);
+ res = parser.Parse(false);
+ if(0 == res) {
+
+#line 966 "DkWxPathFrame.wxc"
+ if(parser.Found(wxT("u"))) {
+
+#line 967 "DkWxPathFrame.wxc"
+ bUninstall = true;
+ }
+ }
+
+#line 970 "DkWxPathFrame.wxc"
+}
+
+
diff --git a/support/dktools/DkWxPathFrame.h b/support/dktools/DkWxPathFrame.h
new file mode 100644
index 0000000000..27ea56f001
--- /dev/null
+++ b/support/dktools/DkWxPathFrame.h
@@ -0,0 +1,158 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxPathFrame.wxc
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxPathFrame.h Header file for the DkWxPathFrame module.
+*/
+
+#ifndef DKWXPATHFRAME_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DKWXPATHFRAME_H_INCLUDED 1
+
+
+#line 31 "DkWxPathFrame.wxc"
+
+
+#line 33 "DkWxPathFrame.wxc"
+
+/** Main window for dkwxpath.
+*/
+class DkWxPathFrame : public DkWxFrame
+{
+ private:
+
+ /** Event table.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ /** Mutex to protect access to internal data.
+ */
+ wxMutex mProtectData;
+
+ /** Flag: A run was already initiated.
+ */
+ bool bRunning;
+
+ /** Flag: Do uninstallation instead of installation.
+ */
+ bool bUninstall;
+
+ /** Localized texts.
+ */
+ wxChar const * const *sTexts;
+
+ /** Localized texts.
+ */
+ dkChar const * const *dkTexts;
+ /** Flag: GUI ok.
+ */
+ bool dkctGUILayoutOK;
+
+ /** Contents panel.
+ */
+ wxPanel *dkctGUIContentsPanel;
+
+ /** GUI element mainSizer.
+ */
+#line 14 "DkWxPathFrame.wxc"
+ wxBoxSizer *mainSizer;
+
+ /** GUI element horizontalSizer.
+ */
+#line 20 "DkWxPathFrame.wxc"
+ wxBoxSizer *horizontalSizer;
+
+ /** GUI element lModifying.
+ */
+#line 25 "DkWxPathFrame.wxc"
+ wxStaticText *lModifying;
+
+
+#line 66 "DkWxPathFrame.wxc"
+
+ public:
+
+ /** Constructor.
+ @param applicationName Application name.
+ @param localizedTexts Localized texts used by object.
+ @param dkLocalizedTexts Localized texts used by object.
+ @param applicationHelper Application helper object.
+ @param idMain Window ID.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ */
+ DkWxPathFrame(
+ wxChar const *applicationName,
+ wxChar const * const *localizedTexts,
+ dkChar const * const *dkLocalizedTexts,
+ DkWxAppHelper *applicationHelper,
+ int idMain,
+ int argc,
+ wxChar **argv
+ );
+
+ /** Check whether the window can be closed.
+ @param isLast Flag: Last windows of it's type in application.
+ @return True to close the frame, false to keep it open.
+ */
+ bool canClose(bool isLast);
+
+ /** Reaction on idle event.
+ @param event Event to process.
+ */
+ void OnIdle(wxIdleEvent & event);
+
+ protected:
+
+ /** Check whether or not we must start the action when idle.
+ @return True to start action, false otherwise.
+ */
+ bool mustStart();
+
+ /** Process command line arguments.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ */
+ void
+ processArguments(int argc, wxChar **argv);
+};
+
+
+#line 115 "DkWxPathFrame.wxc"
+
+
+
+#endif
diff --git a/support/dktools/DkWxPathFrame.wxc b/support/dktools/DkWxPathFrame.wxc
new file mode 100644
index 0000000000..ba354defd1
--- /dev/null
+++ b/support/dktools/DkWxPathFrame.wxc
@@ -0,0 +1,972 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+%% wx-gui
+
+type = frame
+icon = dkicon_bitmap
+contents = mainSizer
+
+[wxBoxSizer mainSizer]
+direction = vertical
+contents = $space(10)
+contents = horizontalSizer
+contents = $space(10)
+
+[wxBoxSizer horizontalSizer]
+contents = $space(10)
+contents = lModifying
+contents = $space(10)
+
+[wxStaticText lModifying]
+text = sTexts[3]
+
+
+
+%% header start
+
+%% class start
+
+/** Main window for dkwxpath.
+*/
+class DkWxPathFrame : public DkWxFrame
+{
+ private:
+
+ /** Event table.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ /** Mutex to protect access to internal data.
+ */
+ wxMutex mProtectData;
+
+ /** Flag: A run was already initiated.
+ */
+ bool bRunning;
+
+ /** Flag: Do uninstallation instead of installation.
+ */
+ bool bUninstall;
+
+ /** Localized texts.
+ */
+ wxChar const * const *sTexts;
+
+ /** Localized texts.
+ */
+ dkChar const * const *dkTexts;
+%% class end
+
+ public:
+
+ /** Constructor.
+ @param applicationName Application name.
+ @param localizedTexts Localized texts used by object.
+ @param dkLocalizedTexts Localized texts used by object.
+ @param applicationHelper Application helper object.
+ @param idMain Window ID.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ */
+ DkWxPathFrame(
+ wxChar const *applicationName,
+ wxChar const * const *localizedTexts,
+ dkChar const * const *dkLocalizedTexts,
+ DkWxAppHelper *applicationHelper,
+ int idMain,
+ int argc,
+ wxChar **argv
+ );
+
+ /** Check whether the window can be closed.
+ @param isLast Flag: Last windows of it's type in application.
+ @return True to close the frame, false to keep it open.
+ */
+ bool canClose(bool isLast);
+
+ /** Reaction on idle event.
+ @param event Event to process.
+ */
+ void OnIdle(wxIdleEvent & event);
+
+ protected:
+
+ /** Check whether or not we must start the action when idle.
+ @return True to start action, false otherwise.
+ */
+ bool mustStart();
+
+ /** Process command line arguments.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ */
+ void
+ processArguments(int argc, wxChar **argv);
+};
+
+%% header end
+
+
+%% module start
+
+#include "dk3conf.h"
+#include "dk3types.h"
+#include "dk3wreg.h"
+#include "dkwxpath.h"
+#include "dkicon.xpm"
+
+$!trace-include
+
+
+BEGIN_EVENT_TABLE(DkWxPathFrame, wxFrame)
+ EVT_IDLE(DkWxPathFrame::OnIdle)
+END_EVENT_TABLE()
+
+
+
+/** Description of a context menu item.
+*/
+typedef struct {
+ dkChar const *menuitem; /**< Context menu item text. */
+ dkChar const *progname; /**< Program name. */
+ dkChar const *arguments; /**< Program command line arguments. */
+} dkwxpath_action_t;
+
+
+
+/** File suffix information.
+*/
+typedef struct {
+ dkChar const *suffix; /**< File type suffix including the dot. */
+ dkChar const *classname; /**< Class name if no class assigned yet. */
+ dkwxpath_action_t *items; /**< Context menu items. */
+} dkwxpath_filetype_t;
+
+
+
+/** Context menu items for PNG.
+*/
+static dkwxpath_action_t dkwxpath_png_actions[] = {
+ { NULL /* 12 */ , dkT("wxbmpp.exe"), dkT("-leps.image \"%1\"") },
+ { NULL /* 13 */ , dkT("wxbmpp.exe"), dkT("-lpdf.image \"%1\"") },
+ { NULL /* 14 */ , dkT("wxbmpp.exe"), dkT("-lpdf.object \"%1\"") },
+ { NULL, NULL, NULL }
+};
+
+/** Context menu items for JPEG.
+*/
+static dkwxpath_action_t dkwxpath_jpeg_actions[] = {
+ { NULL /* 12 */ , dkT("wxbmpp.exe"), dkT("-leps.image \"%1\"") },
+ { NULL /* 13 */ , dkT("wxbmpp.exe"), dkT("-lpdf.image \"%1\"") },
+ { NULL, NULL, NULL }
+};
+
+/** Context menu items for TIFF.
+*/
+static dkwxpath_action_t dkwxpath_tiff_actions[] = {
+ { NULL /* 12 */ , dkT("wxbmpp.exe"), dkT("-leps.image \"%1\"") },
+ { NULL /* 15 */ , dkT("wxbmpp.exe"), dkT("-lpdf.document \"%1\"") },
+ { NULL /* 13 */ , dkT("wxbmpp.exe"), dkT("-lpdf.image \"%1\"") },
+ { NULL /* 14 */ , dkT("wxbmpp.exe"), dkT("-lpdf.object \"%1\"") },
+ { NULL /* 16 */ , dkT("wxbmpp.exe"), dkT("-lps.document \"%1\"") },
+ { NULL, NULL, NULL }
+};
+
+/** Context menu items for PRN and PS files.
+*/
+static dkwxpath_action_t dkwxpath_ps_actions[] = {
+ { NULL /* 17 */ , dkT("winprint.exe"), dkT("-d \"%1\"") },
+ { NULL /* 18 */ , dkT("winprint.exe"), dkT("\"%1\"") },
+ { NULL, NULL, NULL }
+};
+
+/** Context menu items for directories.
+*/
+static dkwxpath_action_t dkwxpath_directory_actions[] = {
+ { NULL /* 19 */ , dkT("wxbmpp.exe"), dkT("\"%1\"") },
+ { NULL /* 20 */ , dkT("wxdkct.exe"), dkT("\"%1\"") },
+ { NULL, NULL, NULL }
+};
+
+
+/** File types to set up.
+*/
+static dkwxpath_filetype_t dkwxpath_filetypes[] = {
+ { dkT(".png"), dkT("pngfile"), dkwxpath_png_actions },
+ { dkT(".jpg"), dkT("jpegfile"), dkwxpath_jpeg_actions},
+ { dkT(".jpeg"), dkT("jpegfile"), dkwxpath_jpeg_actions},
+ { dkT(".tif"), dkT("tifffile"), dkwxpath_tiff_actions},
+ { dkT(".tiff"), dkT("tifffile"), dkwxpath_tiff_actions},
+ { dkT(".prn"), dkT("prnfile"), dkwxpath_ps_actions},
+ { dkT(".ps"), dkT("psfile"), dkwxpath_ps_actions},
+ { NULL, NULL, NULL }
+};
+
+
+
+dkChar const * const dkwxpath_noloc[] = {
+$!string-table macro=dkT
+#
+# 0
+#
+\\shell
+#
+# 1
+#
+\\command
+#
+# 2
+#
+"
+#
+# 3 (space)
+#
+
+#
+# 4
+#
+\\
+#
+# 5
+#
+Directory
+#
+# 6
+#
+wxdkfcs.exe
+#
+# 7
+#
+"%1"
+#
+# 8
+#
+*\\shell
+$!end
+};
+
+#if DK3_ON_WINDOWS && ((DK3_CHAR_SIZE == 1) || (DK3_CHAR_SIZE == 2))
+
+/** Registry key in HKLM containing system environment variables.
+*/
+static dkChar const dkwxpath_registry_key[] = {
+dkT("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment")
+};
+
+/** Registry value name.
+*/
+static dkChar const dkwxpath_registry_name[] = {
+dkT("Path")
+};
+
+
+/** Separator of PATH components.
+*/
+static dkChar const dkwxpath_sep[] = {
+dkT(";")
+};
+
+#endif
+/* if DK3_ON_WINDOWS */
+
+
+#if DK3_ON_WINDOWS && ((DK3_CHAR_SIZE == 1) || (DK3_CHAR_SIZE == 2))
+/** Check whether or not a directory is already contained in the PATH.
+ @param bu Current PATH value.
+ @param dn Directory name to check for.
+ @return 1 on success (@a dn already contained), 0 otherwise.
+*/
+static
+int
+dk3_win_check_path(dkChar *bu, dkChar const *dn)
+{
+ dkChar *pc;
+ dkChar *pn;
+ int back = 0;
+ $? "+ dk3_win_check_path dn=\"%!ds\"", TR_STR(dn)
+ pc = bu;
+ while((pc) && (0 == back)) {
+ pn = dk3str_chr(pc, dkT(';'));
+ if(pn) { *(pn++) = dkT('\0'); }
+ if(0 == dk3str_fncmp(pc, dn)) {
+ back = 1;
+ }
+ pc = pn;
+ } $? "- dk3_win_check_path %d", back
+ return back;
+}
+#endif
+/* if DK3_ON_WINDOWS */
+
+
+
+/** Register context menu entries.
+ @param dn Installation directory name, bin subdirectory.
+ @param cl Class name.
+ @param act Actions list.
+ @param app Application structure for diagnostics, may be NULL.
+*/
+static
+void
+dkwxpath_register_context_entries(
+ dkChar const *dn, dkChar const *cl, dkwxpath_action_t *act, dk3_app_t *app
+)
+{
+ dkChar kn1[DK3_MAX_PATH];
+ dkChar kn2[DK3_SIZEOF(kn1,dkChar)];
+ dkwxpath_action_t *acp;
+ size_t szk;
+ size_t szv;
+ HKEY hk;
+ $? "+ dkwxpath_register_context_entries dn=\"%!ds\" cl=\"%!ds\"", TR_STR(dn), TR_STR(cl)
+ acp = act;
+ while((acp->menuitem) && (acp->progname) && (acp->arguments)) {
+ szk = 2 + dk3str_len(cl) + dk3str_len(dkwxpath_noloc[0])
+ + dk3str_len(acp->menuitem) + dk3str_len(dkwxpath_noloc[1]);
+ szv = 5 + dk3str_len(dn) + dk3str_len(acp->progname)
+ + dk3str_len(acp->arguments);
+ if((szk < DK3_MAX_PATH) && (szv < DK3_MAX_PATH)) {
+ dk3str_cpy(kn1, cl); $? ". key = \"%!ds\"", kn1
+ if(dk3wreg_key_create_read(HKEY_CLASSES_ROOT, kn1, &hk, app)) {
+ dk3wreg_key_close(hk, kn1, app);
+ dk3str_cpy(kn1, cl);
+ dk3str_cat(kn1, dkwxpath_noloc[0]); $? ". key = \"%!ds\"", kn1
+ if(dk3wreg_key_create_read(HKEY_CLASSES_ROOT, kn1, &hk, app)) {
+ dk3wreg_key_close(hk, kn1, app);
+ dk3str_cpy(kn1, cl);
+ dk3str_cat(kn1, dkwxpath_noloc[0]);
+ dk3str_cat(kn1, dkwxpath_noloc[4]);
+ dk3str_cat(kn1, acp->menuitem); $? ". key = \"%!ds\"", kn1
+ if(dk3wreg_key_create_read(HKEY_CLASSES_ROOT, kn1, &hk, app)) {
+ dk3wreg_key_close(hk, kn1, app);
+ dk3str_cpy(kn1, cl);
+ dk3str_cat(kn1, dkwxpath_noloc[0]);
+ dk3str_cat(kn1, dkwxpath_noloc[4]);
+ dk3str_cat(kn1, acp->menuitem);
+ dk3str_cat(kn1, dkwxpath_noloc[1]); $? ". key = \"%!ds\"", kn1
+ dk3str_cpy(kn2, dkwxpath_noloc[2]);
+ dk3str_cat(kn2, dn);
+ dk3str_cat(kn2, dkwxpath_noloc[4]);
+ dk3str_cat(kn2, acp->progname);
+ dk3str_cat(kn2, dkwxpath_noloc[2]);
+ dk3str_cat(kn2, dkwxpath_noloc[3]);
+ dk3str_cat(kn2, acp->arguments); $? ". val = \"%!ds\"", kn2
+ if(dk3wreg_key_create_modify(HKEY_CLASSES_ROOT, kn1, &hk, app)) {
+ (void)dk3wreg_set_sz(hk, NULL, kn2, app); $? ". set"
+ dk3wreg_key_close(hk, kn1, app);
+ }
+ }
+ }
+ }
+ }
+ acp++;
+ }
+ /* Checksums for files */
+ $? "- dkwxpath_register_context_entries"
+}
+
+
+
+/** Remove context menu items.
+ @param dn Base directory name.
+ @param cl Class name.
+ @param act Actions to delete.
+ @param app Application structure for diagnostics, may be NULL.
+*/
+static
+void
+dkwxpath_unregister_context_entries(
+ dkChar const *dn, dkChar const *cl, dkwxpath_action_t *act, dk3_app_t *app
+)
+{
+ dkChar kn1[DK3_MAX_PATH];
+ dkwxpath_action_t *acp;
+ size_t szk;
+ $? "+ dkwxpath_unregister_context_entries dn=\"%!ds\" cl=\"%!ds\"", TR_STR(dn), TR_STR(cl)
+ acp = act;
+ while((acp->menuitem) && (acp->progname) && (acp->arguments)) {
+ szk = 2 + dk3str_len(cl) + dk3str_len(dkwxpath_noloc[0])
+ + dk3str_len(acp->menuitem);
+ if(szk < DK3_MAX_PATH) {
+ dk3str_cpy(kn1, cl);
+ dk3str_cat(kn1, dkwxpath_noloc[0]);
+ dk3str_cat(kn1, dkwxpath_noloc[4]);
+ dk3str_cat(kn1, acp->menuitem); $? ". key = \"%!ds\"", kn1
+ (void)dk3wreg_key_delete(HKEY_CLASSES_ROOT, kn1, app);
+ }
+ acp++;
+ }
+ $? "- dkwxpath_unregister_context_entries"
+}
+
+
+
+/** Register context menus.
+ @param dn Directory name (bin subdirectory).
+ @param app Application structure for diagnostics, may be NULL.
+*/
+static
+void
+dkwxpath_register_context_menus(
+ dkChar const *dn, dk3_app_t *app, const dkChar *cmn
+)
+{
+ dkChar cln[DK3_MAX_PATH];
+ dkChar clo[DK3_MAX_PATH];
+ dkwxpath_filetype_t *ftp;
+ size_t szcln = DK3_SIZEOF(cln,dkChar);
+ size_t szk;
+ size_t szv;
+ int hcl;
+ HKEY hk;
+ $? "+ dkwxpath_register_context_menus dn=\"%!ds\"", TR_STR(dn)
+ ftp = dkwxpath_filetypes;
+ while((ftp->suffix) && (ftp->classname) && (ftp->items)) {
+ $? ". suffix = \"%!ds\"", ftp->suffix
+ $? ". class = \"%!ds\"", ftp->classname
+ cln[0] = dkT('\0');
+ hcl = 0;
+ if(dk3wreg_key_create_modify(HKEY_CLASSES_ROOT, ftp->suffix, &hk, app)) {
+ if(dk3wreg_get_sz(hk, NULL, cln, DK3_SIZEOF(cln,dkChar), app)) {
+ if(0 < dk3str_len(cln)) {
+ hcl = 1;
+ }
+ }
+ if(0 == hcl) {
+ dk3wreg_set_sz(hk, NULL, ftp->classname, app);
+ }
+ dk3wreg_key_close(hk, ftp->suffix, app);
+ if(hcl) {
+ dkwxpath_register_context_entries(dn, cln, ftp->items, app);
+ } else {
+ dkwxpath_register_context_entries(dn, ftp->classname, ftp->items, app);
+ }
+ }
+ ftp++;
+ }
+ dkwxpath_register_context_entries(
+ dn, dkwxpath_noloc[5], dkwxpath_directory_actions, app
+ );
+ szk = dk3str_len(dkwxpath_noloc[8])
+ + dk3str_len(dkwxpath_noloc[4])
+ + dk3str_len(cmn)
+ + dk3str_len(dkwxpath_noloc[1]);
+ szv = 2 * dk3str_len(dkwxpath_noloc[2]) + dk3str_len(dn)
+ + dk3str_len(dkwxpath_noloc[4])
+ + dk3str_len(dkwxpath_noloc[6])
+ + dk3str_len(dkwxpath_noloc[3])
+ + dk3str_len(dkwxpath_noloc[7]);
+ if ((szk < szcln) && (szv < szcln)) {
+ dk3str_cpy(clo, dkwxpath_noloc[2]);
+ dk3str_cat(clo, dn);
+ dk3str_cat(clo, dkwxpath_noloc[4]);
+ dk3str_cat(clo, dkwxpath_noloc[6]);
+ dk3str_cat(clo, dkwxpath_noloc[2]);
+ dk3str_cat(clo, dkwxpath_noloc[3]);
+ dk3str_cat(clo, dkwxpath_noloc[7]);
+ dk3str_cpy(cln, dkwxpath_noloc[8]);
+ dk3str_cat(cln, dkwxpath_noloc[4]);
+ dk3str_cat(cln, cmn);
+ if(dk3wreg_key_create_modify(HKEY_CLASSES_ROOT, cln, &hk, app)) {
+ dk3wreg_key_close(hk, cln, app);
+ }
+ dk3str_cat(cln, dkwxpath_noloc[1]);
+ if(dk3wreg_key_create_modify(HKEY_CLASSES_ROOT, cln, &hk, app)) {
+ (void)dk3wreg_set_sz(hk, NULL, clo, app);
+ dk3wreg_key_close(hk, cln, app);
+ }
+ }
+ $? "- dkwxpath_register_context_menus"
+}
+
+
+
+static
+void
+dkwxpath_unregister_context_menus(
+ dkChar const *dn, dk3_app_t *app, const dkChar *cmn
+)
+{
+ dkChar cln[DK3_MAX_PATH];
+ dkwxpath_filetype_t *ftp;
+ size_t szcln = DK3_SIZEOF(cln,dkChar);
+ size_t szk;
+ int hcl;
+ HKEY hk;
+ $? "+ dkwxpath_unregister_context_menus dn=\"%!ds\"", TR_STR(dn)
+ ftp = dkwxpath_filetypes;
+ while((ftp->suffix) && (ftp->classname) && (ftp->items)) {
+ $? ". suffix = \"%!ds\"", ftp->suffix
+ $? ". class = \"%!ds\"", ftp->classname
+ cln[0] = dkT('\0');
+ hcl = 0;
+ if(dk3wreg_key_create_modify(HKEY_CLASSES_ROOT, ftp->suffix, &hk, app)) {
+ if(dk3wreg_get_sz(hk, NULL, cln, DK3_SIZEOF(cln,dkChar), app)) {
+ if(0 < dk3str_len(cln)) {
+ hcl = 1;
+ }
+ }
+ dk3wreg_key_close(hk, ftp->suffix, app);
+ if(hcl) {
+ dkwxpath_unregister_context_entries(dn, cln, ftp->items, app);
+ }
+ }
+ ftp++;
+ }
+ dkwxpath_unregister_context_entries(
+ dn, dkwxpath_noloc[5], dkwxpath_directory_actions, app
+ );
+ szk = dk3str_len(dkwxpath_noloc[8])
+ + dk3str_len(dkwxpath_noloc[4])
+ + dk3str_len(cmn);
+ if (szk < szcln) {
+ dk3str_cpy(cln, dkwxpath_noloc[8]);
+ dk3str_cat(cln, dkwxpath_noloc[4]);
+ dk3str_cat(cln, cmn);
+ (void)dk3wreg_key_delete(HKEY_CLASSES_ROOT, cln, app);
+ }
+ $? "- dkwxpath_unregister_context_menus"
+}
+
+
+
+/** Ensure dn is listed in the PATH environment variable.
+ @param dn New component to include in PATH.
+ @return 0 on failure, 1 on success (added),
+ 2 on success (dn already in PATH).
+*/
+static
+int
+dkwxpath_set_regentry(dkChar const *dn, dk3_app_t *app, const dkChar *cmn)
+{
+ int back = 0;
+#if DK3_ON_WINDOWS && ((DK3_CHAR_SIZE == 1) || (DK3_CHAR_SIZE == 2))
+ dkChar b1[16 * DK3_MAX_PATH];
+ dkChar b2[16 * DK3_MAX_PATH];
+ DWORD dwType;
+ DWORD dwSz;
+ LONG res;
+ size_t sl;
+ REGSAM regsam;
+ HKEY regkey;
+ $? "+ dkwxpath_set_regentry dn=\"%!ds\"", TR_STR(dn)
+ regsam = KEY_ALL_ACCESS;
+#if DK3_CHAR_SIZE == 2
+ res = RegOpenKeyExW(
+ HKEY_LOCAL_MACHINE, dkwxpath_registry_key, (DWORD)0UL, regsam, &regkey
+ );
+#else
+ res = RegOpenKeyExA(
+ HKEY_LOCAL_MACHINE, dkwxpath_registry_key, (DWORD)0UL, regsam, &regkey
+ );
+#endif
+ if(ERROR_SUCCESS == res) { $? ". reg key opened"
+ dwType = REG_EXPAND_SZ;
+ dwSz = (DWORD)sizeof(b1);
+#if DK3_CHAR_SIZE == 2
+ res = RegQueryValueExW(
+ regkey, dkwxpath_registry_name, NULL, &dwType,
+ (LPBYTE)b1, &dwSz
+ );
+#else
+ res = RegQueryValueExA(
+ regkey, dkwxpath_registry_name, NULL, &dwType,
+ (LPBYTE)b1, &dwSz
+ );
+#endif
+ if(ERROR_SUCCESS == res) { $? ". query value ok"
+ res = 1L;
+#if DK3_CHAR_SIZE == 2
+ if(dwSz % (DWORD)2L) { $? "! not wide characters"
+ res = 0L;
+ } else { $? ". wide characters"
+ dwSz = dwSz / (DWORD)2L;
+ }
+#endif
+ if(dwType != REG_SZ) {
+ if(dwType != REG_EXPAND_SZ) { $? "! wrong value type"
+ res = 0L;
+ }
+ }
+ if(1L == res) { $? ". ok so far"
+ if((DWORD)0L < dwSz) { $? ". have string"
+ if(dwSz < DK3_SIZEOF(b1,dkChar)) { $? ". length ok"
+ b1[dwSz] = dkT('\0');
+ dk3str_cpy(b2, b1);
+ if(dk3_win_check_path(b2, dn)) {
+ back = 2;
+ } else {
+ sl = dk3str_len(b1);
+ sl += dk3str_len(dn);
+ sl += 1;
+ if(sl < DK3_SIZEOF(b2,dkChar)) {
+ dk3str_cpy(b2, dn);
+ dk3str_cat(b2, dkwxpath_sep);
+ dk3str_cat(b2, b1);
+#if DK3_CHAR_SIZE == 2
+ res = RegSetValueExW(
+ regkey, dkwxpath_registry_name, (DWORD)0L, dwType,
+ (BYTE const *)b2,
+ (DWORD)(2 * (1 + dk3str_len(b2)))
+ );
+#else
+ res = RegSetValueExA(
+ regkey, dkwxpath_registry_name, (DWORD)0L, dwType,
+ (BYTE const *)b2,
+ (DWORD)(1 + dk3str_len(b2))
+ );
+#endif
+ if(ERROR_SUCCESS == res) {
+ back = 1;
+ }
+ } else { $? "! strings too long"
+ }
+ }
+ } else { $? "! string too long"
+ }
+ } else { $? "! empty string"
+ }
+ }
+ } else { $? "! failed to query value"
+ }
+ RegCloseKey(regkey);
+ } else { $? "! failed to open reg key"
+ }
+ dkwxpath_register_context_menus(dn, app, cmn);
+#else
+ /* Simulate results to test dialogs. */
+#endif
+/* if DK3_ON_WINDOWS ... */
+ $? "- dkwxpath_set_regentry %d", back
+ return back;
+}
+
+
+
+#if DK3_ON_WINDOWS && ((DK3_CHAR_SIZE == 2) || (DK3_CHAR_SIZE == 1))
+static
+void
+dkwxpath_remove(dkChar *dp, dkChar *sp, dkChar const *dn)
+{
+ dkChar *pc;
+ dkChar *pn;
+ bool isfirst = true;
+
+ *dp = dkT('\0');
+ pc = sp;
+ while(pc) {
+ pn = dk3str_chr(pc, dkT(';'));
+ if(pn) { *(pn++) = dkT('\0'); }
+ if(dk3str_fncmp(pc, dn)) {
+ if(isfirst) {
+ isfirst = false;
+ dk3str_cpy(dp, pc);
+ } else {
+ dk3str_cat(dp, dkwxpath_sep);
+ dk3str_cat(dp, pc);
+ }
+ }
+ pc = pn;
+ }
+}
+#endif
+/* if DK3_ON_WINDOWS && ... */
+
+
+/** Ensure dn is not listed in the PATH environment variable.
+ @param dn Component to exclude from PATH.
+ @return 0 on failure, 1 on success (removed),
+ 2 on success (dn not contained).
+*/
+static
+int
+dkwxpath_unset_regentry(dkChar const *dn, dk3_app_t *app, const dkChar *cmn)
+{
+ int back = 0;
+ $? "+ dkwxpath_unset_regentry"
+#if DK3_ON_WINDOWS && ((DK3_CHAR_SIZE == 1) || (DK3_CHAR_SIZE == 2))
+ dkChar b1[16 * DK3_MAX_PATH];
+ dkChar b2[16 * DK3_MAX_PATH];
+ DWORD dwType;
+ DWORD dwSz;
+ LONG res;
+ REGSAM regsam;
+ HKEY regkey;
+
+ regsam = KEY_ALL_ACCESS;
+#if DK3_CHAR_SIZE == 2
+ res = RegOpenKeyExW(
+ HKEY_LOCAL_MACHINE, dkwxpath_registry_key, (DWORD)0UL, regsam, &regkey
+ );
+#else
+ res = RegOpenKeyExA(
+ HKEY_LOCAL_MACHINE, dkwxpath_registry_key, (DWORD)0UL, regsam, &regkey
+ );
+#endif
+ if(ERROR_SUCCESS == res) { $? ". reg key open"
+ dwType = REG_EXPAND_SZ;
+ dwSz = (DWORD)sizeof(b1);
+#if DK3_CHAR_SIZE == 2
+ res = RegQueryValueExW(
+ regkey, dkwxpath_registry_name, NULL, &dwType,
+ (LPBYTE)b1, &dwSz
+ );
+#else
+ res = RegQueryValueExA(
+ regkey, dkwxpath_registry_name, NULL, &dwType,
+ (LPBYTE)b1, &dwSz
+ );
+#endif
+ if(ERROR_SUCCESS == res) { $? ". reg query"
+ res = 1L;
+#if DK3_CHAR_SIZE == 2
+ if(dwSz % (DWORD)2L) {
+ res = 0L;
+ } else {
+ dwSz = dwSz / (DWORD)2L;
+ }
+#endif
+ if(dwType != REG_SZ) {
+ if(dwType != REG_EXPAND_SZ) {
+ res = 0L;
+ }
+ }
+ if(1L == res) { $? ". type and length ok"
+ if((DWORD)0L < dwSz) { $? ". contents in string"
+ if(dwSz < DK3_SIZEOF(b1,dkChar)) {
+ b1[dwSz] = dkT('\0');
+ dkwxpath_remove(b2, b1, dn);
+#if DK3_CHAR_SIZE == 2
+ res = RegSetValueExW(
+ regkey, dkwxpath_registry_name, (DWORD)0L, dwType,
+ (BYTE const *)b2,
+ (DWORD)(2 * (1 + dk3str_len(b2)))
+ );
+#else
+ res = RegSetValueExA(
+ regkey, dkwxpath_registry_name, (DWORD)0L, dwType,
+ (BYTE const *)b2,
+ (DWORD)(1 + dk3str_len(b2))
+ );
+#endif
+ if(ERROR_SUCCESS == res) { $? ". reg set"
+ back = 1;
+ } else { $? "! reg set"
+ }
+ }
+ } else { $? "! empty string"
+ }
+ } else { $? "! type or length"
+ }
+ } else { $? "! reg query"
+ }
+ RegCloseKey(regkey);
+ } else { $? "! reg key open"
+ }
+ dkwxpath_unregister_context_menus(dn, app, cmn);
+#endif
+ $? "- dkwxpath_unset_regentry %d", back
+ return back;
+}
+
+
+
+%% constructor start
+DkWxPathFrame::DkWxPathFrame(
+ wxChar const *applicationName,
+ wxChar const * const *localizedTexts,
+ dkChar const * const *dkLocalizedTexts,
+ DkWxAppHelper *applicationHelper,
+ int idMain,
+ int argc,
+ wxChar **argv
+) : DkWxFrame(applicationName, applicationHelper, NULL, idMain),
+ mProtectData(wxMUTEX_DEFAULT)
+{
+#if defined(__WXMSW__)
+ wxIcon dkicon_bitmap(wxT("aaaaa"));
+#else
+ wxIcon dkicon_bitmap(dkicon_xpm);
+#endif
+ sTexts = localizedTexts;
+ dkTexts = dkLocalizedTexts;
+ bRunning = false;
+ bUninstall = false;
+%% constructor end
+#if 0
+ restorePosition();
+#endif
+ processArguments(argc, argv);
+ /* Set context menu item texts
+ */
+ dkwxpath_png_actions[0].menuitem = dkLocalizedTexts[12];
+ dkwxpath_png_actions[1].menuitem = dkLocalizedTexts[13];
+ dkwxpath_png_actions[2].menuitem = dkLocalizedTexts[14];
+ dkwxpath_jpeg_actions[0].menuitem = dkLocalizedTexts[12];
+ dkwxpath_jpeg_actions[1].menuitem = dkLocalizedTexts[13];
+ dkwxpath_tiff_actions[0].menuitem = dkLocalizedTexts[12];
+ dkwxpath_tiff_actions[1].menuitem = dkLocalizedTexts[15];
+ dkwxpath_tiff_actions[2].menuitem = dkLocalizedTexts[13];
+ dkwxpath_tiff_actions[3].menuitem = dkLocalizedTexts[14];
+ dkwxpath_tiff_actions[4].menuitem = dkLocalizedTexts[16];
+ dkwxpath_ps_actions[0].menuitem = dkLocalizedTexts[17];
+ dkwxpath_ps_actions[1].menuitem = dkLocalizedTexts[18];
+ dkwxpath_directory_actions[0].menuitem = dkLocalizedTexts[19];
+ dkwxpath_directory_actions[1].menuitem = dkLocalizedTexts[20];
+}
+
+%% module end
+
+
+
+bool
+DkWxPathFrame::mustStart()
+{
+ bool back = false;
+ {
+ wxMutexLocker lock(mProtectData);
+ if(lock.IsOk()) {
+ if(!bRunning) {
+ back = true;
+ bRunning = true;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void DkWxPathFrame::OnIdle(wxIdleEvent & event)
+{
+ wxChar bindir[DK3_MAX_PATH];
+ dk3_app_t *app;
+ dkChar const *dkbindir;
+ bool doRun;
+ bool haveBinDir;
+ int res;
+
+ haveBinDir = false;
+ app = NULL;
+ dkbindir = NULL;
+ doRun = mustStart();
+ /*
+ Modify PATH variable.
+ */
+ if(doRun) {
+ res = 1;
+#if DK3_ON_WINDOWS && ((DK3_CHAR_SIZE == 1) || (DK3_CHAR_SIZE == 2))
+ res = 0;
+ app = pHelper->getApp();
+ if(app) {
+ dkbindir = dk3app_get_bindir(app);
+ if(dkbindir) {
+ if(bUninstall) {
+ res = dkwxpath_unset_regentry(dkbindir, app, dkTexts[21]);
+ } else {
+ res = dkwxpath_set_regentry(dkbindir, app, dkTexts[21]);
+ }
+ Sleep(250);
+ }
+ }
+#endif
+ if(0 == res) {
+ app = pHelper->getApp();
+ if(app) {
+ dkbindir = dk3app_get_bindir(app);
+ if(dkbindir) {
+ haveBinDir = pHelper->dkToWx(
+ bindir, DK3_SIZEOF(bindir,wxChar), dkbindir
+ );
+ }
+ }
+ wxString msg(wxT(""));
+ msg.Append(sTexts[6]);
+ msg.Append(wxT("\n"));
+ if(bUninstall) {
+ msg.Append(sTexts[9]);
+ msg.Append(wxT("\n"));
+ if(haveBinDir) {
+ msg.Append(wxT("\n"));
+ msg.Append(bindir);
+ msg.Append(wxT("\n"));
+ msg.Append(wxT("\n"));
+ }
+ msg.Append(sTexts[10]);
+ } else {
+ msg.Append(sTexts[7]);
+ msg.Append(wxT("\n"));
+ if(haveBinDir) {
+ msg.Append(wxT("\n"));
+ msg.Append(bindir);
+ msg.Append(wxT("\n"));
+ msg.Append(wxT("\n"));
+ }
+ msg.Append(sTexts[8]);
+ }
+ msg.Append(wxT("\n"));
+ msg.Append(sTexts[11]);
+ wxMessageBox(msg, sTexts[5], (wxOK | wxICON_ERROR), this);
+ }
+ }
+ /*
+ Skip further event processing.
+ */
+ event.Skip();
+ /*
+ Close window.
+ */
+ if(doRun) {
+ Show(false);
+ Close();
+ }
+}
+
+
+bool
+DkWxPathFrame::canClose(bool isLast)
+{
+ if(isLast) {
+ savePosition();
+ }
+ return true;
+}
+
+
+
+
+static const wxCmdLineEntryDesc dkwxpath_cmd_line_desc[] = {
+ {
+ wxCMD_LINE_SWITCH,
+ wxT_2("u"),
+ wxT_2("uninstall"),
+ wxT_2("Uninstall DK tools and libraries")
+ },
+ { wxCMD_LINE_NONE }
+};
+
+
+
+void
+DkWxPathFrame::processArguments(int argc, wxChar **argv)
+{
+ wxLogNull log;
+ int res;
+ $? "+ DkWxPathFrame::processArguments"
+ wxCmdLineParser parser(dkwxpath_cmd_line_desc, argc, argv);
+ res = parser.Parse(false);
+ if(0 == res) { $? ". arguments parsed successfully"
+ if(parser.Found(wxT("u"))) { $? ". uninstall"
+ bUninstall = true;
+ }
+ } $? "- DkWxPathFrame::processArguments"
+}
+
+
diff --git a/support/dktools/DkWxProcessingController.cpp b/support/dktools/DkWxProcessingController.cpp
new file mode 100644
index 0000000000..2aae78f48e
--- /dev/null
+++ b/support/dktools/DkWxProcessingController.cpp
@@ -0,0 +1,79 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxProcessingController.cpt
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxProcessingController.cpp The DkWxProcessingController module.
+*/
+
+
+#line 60 "DkWxProcessingController.cpt"
+
+#include "DkWxProcessingController.h"
+
+
+
+#line 64 "DkWxProcessingController.cpt"
+
+DkWxProcessingController::DkWxProcessingController()
+{
+ bIsRunning = false;
+}
+
+
+
+bool
+DkWxProcessingController::canBeginProcessing(void)
+{
+ bool back = false;
+ {
+ wxMutexLocker lock(mxProtectProcessing);
+ if(!(bIsRunning)) {
+ bIsRunning = true;
+ back = true;
+ }
+ }
+ return back;
+}
+
+
+
+void
+DkWxProcessingController::endProcessing(void)
+{
+ wxMutexLocker lock(mxProtectProcessing);
+ bIsRunning = false;
+}
+
+
+
diff --git a/support/dktools/DkWxProcessingController.cpt b/support/dktools/DkWxProcessingController.cpt
new file mode 100644
index 0000000000..6bd67dc7b0
--- /dev/null
+++ b/support/dktools/DkWxProcessingController.cpt
@@ -0,0 +1,96 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2013-xxxx
+license = bsd
+
+%% header
+
+#include <dk3conf.h>
+#include <dk3types.h>
+#include <dk3const.h>
+
+#include <wx/wxprec.h>
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#include <wx/wx.h>
+#endif
+#include <wx/thread.h>
+
+
+
+/** Protect code from concurrent execution, mainly for timer handlers.
+ In contrast to a critical section which delays execution of
+ code to avoid concurrent access to data this class skips
+ the execution of concurrent code.
+*/
+class DkWxProcessingController
+{
+ protected:
+
+ /** Prevent concurrent access.
+ */
+ wxMutex mxProtectProcessing;
+
+ /** Flag: Processing is running.
+ */
+ bool bIsRunning;
+
+ public:
+ /** Default constructor.
+ */
+ DkWxProcessingController();
+
+ /** Begin processing if not already running.
+ If the function returns true you must invoke endProcessing()
+ when your processing is finished.
+ @return true to start processing, false if processing is running.
+ */
+ bool canBeginProcessing(void);
+
+ /** End processing. Call this function after finishing the
+ critical code.
+ */
+ void endProcessing(void);
+};
+
+%% module
+
+#include "DkWxProcessingController.h"
+
+$!trace-include
+
+DkWxProcessingController::DkWxProcessingController()
+{
+ bIsRunning = false;
+}
+
+
+
+bool
+DkWxProcessingController::canBeginProcessing(void)
+{
+ bool back = false;
+ {
+ wxMutexLocker lock(mxProtectProcessing);
+ if(!(bIsRunning)) {
+ bIsRunning = true;
+ back = true;
+ }
+ }
+ return back;
+}
+
+
+
+void
+DkWxProcessingController::endProcessing(void)
+{
+ wxMutexLocker lock(mxProtectProcessing);
+ bIsRunning = false;
+}
+
+
+
diff --git a/support/dktools/DkWxProcessingController.h b/support/dktools/DkWxProcessingController.h
new file mode 100644
index 0000000000..222ba9e084
--- /dev/null
+++ b/support/dktools/DkWxProcessingController.h
@@ -0,0 +1,97 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxProcessingController.cpt
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxProcessingController.h Header file for the DkWxProcessingController module.
+*/
+
+#ifndef DKWXPROCESSINGCONTROLLER_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DKWXPROCESSINGCONTROLLER_H_INCLUDED 1
+
+
+#line 8 "DkWxProcessingController.cpt"
+
+#include <dk3conf.h>
+#include <dk3types.h>
+#include <dk3const.h>
+
+#include <wx/wxprec.h>
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#include <wx/wx.h>
+#endif
+#include <wx/thread.h>
+
+
+
+/** Protect code from concurrent execution, mainly for timer handlers.
+ In contrast to a critical section which delays execution of
+ code to avoid concurrent access to data this class skips
+ the execution of concurrent code.
+*/
+class DkWxProcessingController
+{
+ protected:
+
+ /** Prevent concurrent access.
+ */
+ wxMutex mxProtectProcessing;
+
+ /** Flag: Processing is running.
+ */
+ bool bIsRunning;
+
+ public:
+ /** Default constructor.
+ */
+ DkWxProcessingController();
+
+ /** Begin processing if not already running.
+ If the function returns true you must invoke endProcessing()
+ when your processing is finished.
+ @return true to start processing, false if processing is running.
+ */
+ bool canBeginProcessing(void);
+
+ /** End processing. Call this function after finishing the
+ critical code.
+ */
+ void endProcessing(void);
+};
+
+
+#endif
diff --git a/support/dktools/DkWxProcessingIdleController.cpp b/support/dktools/DkWxProcessingIdleController.cpp
new file mode 100644
index 0000000000..96eded06bd
--- /dev/null
+++ b/support/dktools/DkWxProcessingIdleController.cpp
@@ -0,0 +1,89 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxProcessingIdleController.cpt
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxProcessingIdleController.cpp The DkWxProcessingIdleController module.
+*/
+
+
+#line 51 "DkWxProcessingIdleController.cpt"
+
+#include "DkWxProcessingIdleController.h"
+
+
+
+
+
+#line 57 "DkWxProcessingIdleController.cpt"
+
+
+
+DkWxProcessingIdleController::DkWxProcessingIdleController()
+: DkWxProcessingController()
+{
+ bWantMore = false;
+}
+
+
+
+void
+DkWxProcessingIdleController::setWantMore(bool value)
+{
+ wxMutexLocker lock(mxProtectWantMore);
+ bWantMore = value;
+}
+
+
+
+void
+DkWxProcessingIdleController::resetWantMore(void)
+{
+ wxMutexLocker lock(mxProtectWantMore);
+ bWantMore = false;
+}
+
+
+
+bool
+DkWxProcessingIdleController::wantMore(void)
+{
+ bool back = false;
+ {
+ wxMutexLocker lock(mxProtectWantMore);
+ back = bWantMore;
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/DkWxProcessingIdleController.cpt b/support/dktools/DkWxProcessingIdleController.cpt
new file mode 100644
index 0000000000..0fb8f45420
--- /dev/null
+++ b/support/dktools/DkWxProcessingIdleController.cpt
@@ -0,0 +1,97 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2013-xxxx
+license = bsd
+
+%% header
+
+#include <DkWxProcessingController.h>
+
+/** Protect idle event handler from concurrent execution.
+ In contrast to a critical section which delays execution of
+ code this class skips the code execution.
+*/
+class DkWxProcessingIdleController : public DkWxProcessingController
+{
+ protected:
+
+ /** Avoid concurrent access to bWantMore.
+ */
+ wxMutex mxProtectWantMore;
+
+ /** Flag: More idle events wanted.
+ */
+ bool bWantMore;
+
+ public:
+
+ /** Constructor.
+ */
+ DkWxProcessingIdleController();
+
+ /** Indicate interest in more idle events (thread-safe).
+ @param value New flag value.
+ */
+ void setWantMore(bool value = true);
+
+ /** Indicate no more interest in further idle events (thread-safe).
+ */
+ void resetWantMore(void);
+
+ /** Check for interest in further idle events (thread-safe).
+ @return true to ask for further events, false otherwise.
+ */
+ bool wantMore(void);
+
+};
+
+
+%% module
+
+#include "DkWxProcessingIdleController.h"
+
+
+
+$!trace-include
+
+
+
+DkWxProcessingIdleController::DkWxProcessingIdleController()
+: DkWxProcessingController()
+{
+ bWantMore = false;
+}
+
+
+
+void
+DkWxProcessingIdleController::setWantMore(bool value)
+{
+ wxMutexLocker lock(mxProtectWantMore);
+ bWantMore = value;
+}
+
+
+
+void
+DkWxProcessingIdleController::resetWantMore(void)
+{
+ wxMutexLocker lock(mxProtectWantMore);
+ bWantMore = false;
+}
+
+
+
+bool
+DkWxProcessingIdleController::wantMore(void)
+{
+ bool back = false;
+ {
+ wxMutexLocker lock(mxProtectWantMore);
+ back = bWantMore;
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/DkWxProcessingIdleController.h b/support/dktools/DkWxProcessingIdleController.h
new file mode 100644
index 0000000000..dc1bf8afd2
--- /dev/null
+++ b/support/dktools/DkWxProcessingIdleController.h
@@ -0,0 +1,88 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxProcessingIdleController.cpt
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxProcessingIdleController.h Header file for the DkWxProcessingIdleController module.
+*/
+
+#ifndef DKWXPROCESSINGIDLECONTROLLER_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DKWXPROCESSINGIDLECONTROLLER_H_INCLUDED 1
+
+
+#line 8 "DkWxProcessingIdleController.cpt"
+
+#include <DkWxProcessingController.h>
+
+/** Protect idle event handler from concurrent execution.
+ In contrast to a critical section which delays execution of
+ code this class skips the code execution.
+*/
+class DkWxProcessingIdleController : public DkWxProcessingController
+{
+ protected:
+
+ /** Avoid concurrent access to bWantMore.
+ */
+ wxMutex mxProtectWantMore;
+
+ /** Flag: More idle events wanted.
+ */
+ bool bWantMore;
+
+ public:
+
+ /** Constructor.
+ */
+ DkWxProcessingIdleController();
+
+ /** Indicate interest in more idle events (thread-safe).
+ @param value New flag value.
+ */
+ void setWantMore(bool value = true);
+
+ /** Indicate no more interest in further idle events (thread-safe).
+ */
+ void resetWantMore(void);
+
+ /** Check for interest in further idle events (thread-safe).
+ @return true to ask for further events, false otherwise.
+ */
+ bool wantMore(void);
+
+};
+
+
+
+#endif
diff --git a/support/dktools/DkWxProgressDialog.cpp b/support/dktools/DkWxProgressDialog.cpp
new file mode 100644
index 0000000000..70fb55d5c9
--- /dev/null
+++ b/support/dktools/DkWxProgressDialog.cpp
@@ -0,0 +1,360 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxProgressDialog.wxc
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxProgressDialog.cpp The DkWxProgressDialog module.
+*/
+
+
+#line 142 "DkWxProgressDialog.wxc"
+
+#include "dkwxtrace.h"
+
+
+
+#line 146 "DkWxProgressDialog.wxc"
+
+BEGIN_EVENT_TABLE(DkWxProgressDialog,wxDialog)
+ EVT_IDLE(DkWxProgressDialog::OnIdle)
+ EVT_BUTTON(wxID_CANCEL, DkWxProgressDialog::OnCancel)
+END_EVENT_TABLE()
+
+
+
+/** Default texts to use if the constructor has NULL pointer arguments.
+*/
+wxChar const * const dkwx_pd_def_texts[] = {
+/* 0 */
+wxT(""),
+
+/* 1 */
+wxT("Progress"),
+
+/* 2 */
+wxT("Cancel"),
+
+/* 3 */
+wxT("Push button to interrupt processing."),
+
+/* 4 */
+wxT("Cancel command scheduled... Wait, please!"),
+
+NULL
+
+
+#line 179 "DkWxProgressDialog.wxc"
+};
+
+
+
+
+#line 184 "DkWxProgressDialog.wxc"
+DkWxProgressDialog::DkWxProgressDialog(
+ DkWxFrame *parent,
+ DkWxCommunicator *comm,
+ wxTextCtrl *tc,
+ wxChar const *title,
+ wxChar const *firstFileName,
+ wxChar const *buttonText,
+ wxChar const *buttonTip,
+ wxChar const *waitText
+) : wxDialog(
+ parent,
+ wxID_ANY,
+ ((title) ? title : dkwx_pd_def_texts[1]),
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxDEFAULT_DIALOG_STYLE
+)
+{
+
+
+#line 203 "DkWxProgressDialog.wxc"
+ pParent = parent;
+ pLogTextField = tc;
+ pComm = comm;
+ sWaitPlease = ((waitText) ? waitText : dkwx_pd_def_texts[4]);
+ dkctGUILayoutOK = false;
+ sDialog = NULL;
+ verticalSizer = NULL;
+ sttFilename = NULL;
+ gaugeProgress = NULL;
+ sttWait = NULL;
+ bCancel = NULL;
+ sDialog = new wxBoxSizer(
+ wxHORIZONTAL
+ );
+ if(!(sDialog)) {
+ goto dkctGUILayoutFinished;
+ }
+ sDialog->Add(10, 10, 0);
+ verticalSizer = new wxBoxSizer(
+ wxVERTICAL
+ );
+ if(!(verticalSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ verticalSizer->Add(10, 10, 0);
+ sttFilename = new wxStaticText(
+ this,
+ wxID_ANY,
+ ((firstFileName) ? firstFileName : dkwx_pd_def_texts[0]),
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxALIGN_CENTRE
+ );
+ if(!(sttFilename)) {
+ goto dkctGUILayoutFinished;
+ }
+ verticalSizer->Add(
+ sttFilename,
+ 1,
+ wxALIGN_LEFT|wxGROW
+ );
+ verticalSizer->Add(10, 10, 0);
+ gaugeProgress = new wxGauge(
+ this,
+ wxID_ANY,
+ 1000
+ );
+ if(!(gaugeProgress)) {
+ goto dkctGUILayoutFinished;
+ }
+ verticalSizer->Add(
+ gaugeProgress,
+ 0,
+ wxALIGN_CENTER_HORIZONTAL|wxGROW
+ );
+ verticalSizer->Add(10, 10, 0);
+ sttWait = new wxStaticText(
+ this,
+ wxID_ANY,
+ ((waitText) ? waitText : dkwx_pd_def_texts[4]),
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxALIGN_LEFT
+ );
+ if(!(sttWait)) {
+ goto dkctGUILayoutFinished;
+ }
+ verticalSizer->Add(
+ sttWait,
+ 0,
+ wxALIGN_LEFT
+ );
+ verticalSizer->Add(10, 10, 0);
+ bCancel = new wxButton(
+ this,
+ wxID_CANCEL,
+ ((buttonText) ? buttonText : dkwx_pd_def_texts[2])
+ );
+ if(!(bCancel)) {
+ goto dkctGUILayoutFinished;
+ }
+ bCancel->SetToolTip(((buttonTip) ? buttonTip : dkwx_pd_def_texts[3]));
+ verticalSizer->Add(
+ bCancel,
+ 0,
+ wxALIGN_CENTER_HORIZONTAL
+ );
+ verticalSizer->Add(10, 10, 0);
+ sDialog->Add(
+ verticalSizer,
+ 1,
+ wxGROW
+ );
+ sDialog->Add(10, 10, 0);
+ SetSizer(sDialog);
+ dkctGUILayoutOK = true;
+ dkctGUILayoutFinished:
+ if(dkctGUILayoutOK) {
+ sDialog->Fit(this);
+ sDialog->SetSizeHints(this);
+ }
+
+#line 208 "DkWxProgressDialog.wxc"
+ if(dkctGUILayoutOK) {
+ if(sttWait) {
+ sttWait->SetLabel(dkwx_pd_def_texts[0]);
+ }
+ }
+
+
+#line 214 "DkWxProgressDialog.wxc"
+}
+
+
+
+
+#line 219 "DkWxProgressDialog.wxc"
+
+
+void
+DkWxProgressDialog::OnIdle(wxIdleEvent & event)
+{
+ int canContinue = 1;
+ int res;
+
+
+#line 227 "DkWxProgressDialog.wxc"
+ if(pComm) {
+
+#line 228 "DkWxProgressDialog.wxc"
+ res = pComm->getUpdates(this, sttFilename, gaugeProgress);
+
+
+#line 230 "DkWxProgressDialog.wxc"
+ if(res & DK_WX_COMMUNICATOR_STATUS_UPDATE) {
+
+#line 231 "DkWxProgressDialog.wxc"
+ Refresh();
+ Update();
+ } else {
+
+#line 234 "DkWxProgressDialog.wxc"
+ }
+ if(res & DK_WX_COMMUNICATOR_STATUS_RUNNING) {
+
+#line 236 "DkWxProgressDialog.wxc"
+ canContinue = 1;
+ } else {
+
+#line 238 "DkWxProgressDialog.wxc"
+ canContinue = 0;
+ }
+ } else {
+
+#line 241 "DkWxProgressDialog.wxc"
+ canContinue = 0;
+ }
+ if(canContinue) {
+
+#line 244 "DkWxProgressDialog.wxc"
+ event.RequestMore();
+ } else {
+
+#line 246 "DkWxProgressDialog.wxc"
+ canContinue = 1;
+ if(pComm) {
+ canContinue = pComm->getCanContinue();
+ if(pLogTextField) {
+
+#line 250 "DkWxProgressDialog.wxc"
+ pComm->getText(pLogTextField);
+ if(pParent) {
+
+#line 252 "DkWxProgressDialog.wxc"
+ pParent->Refresh();
+ } else {
+
+#line 254 "DkWxProgressDialog.wxc"
+ pLogTextField->Refresh();
+ }
+ }
+ }
+ if(IsModal()) {
+
+#line 259 "DkWxProgressDialog.wxc"
+ EndModal((canContinue) ? wxID_OK : wxID_CANCEL);
+ } else {
+
+#line 261 "DkWxProgressDialog.wxc"
+ SetReturnCode((canContinue) ? wxID_OK : wxID_CANCEL);
+ Show(false);
+ }
+ }
+ event.Skip();
+
+#line 266 "DkWxProgressDialog.wxc"
+}
+
+
+
+void
+DkWxProgressDialog::OnCancel(wxCommandEvent & event)
+{
+
+
+#line 274 "DkWxProgressDialog.wxc"
+ if(pComm) {
+ pComm->setCanContinue(0);
+ }
+ if(sttWait) {
+ sttWait->SetLabel(sWaitPlease);
+ }
+ if(bCancel) {
+ bCancel->Enable(false);
+ bCancel->SetToolTip(sWaitPlease);
+ }
+ Refresh();
+ Update();
+
+
+#line 287 "DkWxProgressDialog.wxc"
+}
+
+
+
+void
+DkWxProgressDialog::chooseModalPosition()
+{
+ int px = 0; /* Parent x position. */
+ int py = 0; /* Parent y position. */
+ int pw = 0; /* Parent width. */
+ int ph = 0; /* Parent height. */
+ int x = 0; /* X position. */
+ int y = 0; /* Y position. */
+ int w = 0; /* Width. */
+ int h = 0; /* Height. */
+
+
+#line 303 "DkWxProgressDialog.wxc"
+ /* Sceen size */
+ wxSize scsz = wxGetDisplaySize();
+ pParent->GetPosition(&px, &py);
+ pParent->GetSize(&pw, &ph);
+ GetSize(&w, &h);
+ x = px + (pw - w) / 2;
+ y = py + (ph - h) / 2;
+ if((x + w) > scsz.x) { x = scsz.x - w; }
+ if((y + h) > scsz.y) { y = scsz.y - h; }
+ if(x < 0) { x = 0; }
+ if(y < 0) { y = 0; }
+ SetSize(x, y, w, h);
+
+
+#line 316 "DkWxProgressDialog.wxc"
+}
+
+
diff --git a/support/dktools/DkWxProgressDialog.h b/support/dktools/DkWxProgressDialog.h
new file mode 100644
index 0000000000..ccec5bee0c
--- /dev/null
+++ b/support/dktools/DkWxProgressDialog.h
@@ -0,0 +1,166 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxProgressDialog.wxc
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxProgressDialog.h Header file for the DkWxProgressDialog module.
+*/
+
+#ifndef DKWXPROGRESSDIALOG_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DKWXPROGRESSDIALOG_H_INCLUDED 1
+
+
+#line 58 "DkWxProgressDialog.wxc"
+
+#include <DkWxCommunicator.h>
+
+
+
+
+#line 64 "DkWxProgressDialog.wxc"
+
+/** Progress dialog showing currently process file, progress bar
+ and a button to abort operation.
+*/
+class DkWxProgressDialog : public wxDialog
+{
+ private:
+ /** Event table.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ /** Communicator object delivering the file name and progress bar
+ value.
+ */
+ DkWxCommunicator *pComm;
+
+ /** String: Cancel operation scheduled. Please wait.
+ */
+ wxChar const *sWaitPlease;
+
+ /** Parent frame.
+ */
+ DkWxFrame *pParent;
+
+ /** Log text field to receive the messages.
+ */
+ wxTextCtrl *pLogTextField;
+
+ /** Flag: GUI ok.
+ */
+ bool dkctGUILayoutOK;
+
+ /** GUI element sDialog.
+ */
+#line 15 "DkWxProgressDialog.wxc"
+ wxBoxSizer *sDialog;
+
+ /** GUI element verticalSizer.
+ */
+#line 21 "DkWxProgressDialog.wxc"
+ wxBoxSizer *verticalSizer;
+
+ /** GUI element sttFilename.
+ */
+#line 35 "DkWxProgressDialog.wxc"
+ wxStaticText *sttFilename;
+
+ /** GUI element gaugeProgress.
+ */
+#line 41 "DkWxProgressDialog.wxc"
+ wxGauge *gaugeProgress;
+
+ /** GUI element sttWait.
+ */
+#line 51 "DkWxProgressDialog.wxc"
+ wxStaticText *sttWait;
+
+ /** GUI element bCancel.
+ */
+#line 46 "DkWxProgressDialog.wxc"
+ wxButton *bCancel;
+
+
+#line 95 "DkWxProgressDialog.wxc"
+ public:
+
+ /** Constructor.
+ @param parent Parent window.
+ @param comm Communicator object.
+ @param tc Text control to show messages.
+ @param title Title text.
+ @param firstFileName First file name to show.
+ @param buttonText Text for "Cancel" button.
+ @param buttonTip Tooltip text for button.
+ @param waitText Button to show while waiting for thread exit.
+ */
+ DkWxProgressDialog(
+ DkWxFrame *parent,
+ DkWxCommunicator *comm,
+ wxTextCtrl *tc,
+ wxChar const *title,
+ wxChar const *firstFileName,
+ wxChar const *buttonText,
+ wxChar const *buttonTip,
+ wxChar const *waitText
+ );
+
+ /** Handler for idle events.
+ We request the current file name and progress bar from
+ the communicator object and update the information shown
+ in the dialog.
+ */
+ void
+ OnIdle(wxIdleEvent & event);
+
+ /** Handler for cancel button.
+ */
+ void
+ OnCancel(wxCommandEvent & WXUNUSED(event));
+
+ /** Choose a modal position centered on the parent.
+ */
+ void chooseModalPosition();
+
+};
+
+
+
+
+#line 140 "DkWxProgressDialog.wxc"
+
+
+#endif
diff --git a/support/dktools/DkWxProgressDialog.wxc b/support/dktools/DkWxProgressDialog.wxc
new file mode 100644
index 0000000000..942d0d56d3
--- /dev/null
+++ b/support/dktools/DkWxProgressDialog.wxc
@@ -0,0 +1,318 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+%% wx-gui
+
+type = dialog
+contents = sDialog
+# status bar = 1 dkwx_pd_def_texts[0]
+# title = ((title) ? title : dkwx_pd_def_texts[1])
+
+[wxBoxSizer sDialog]
+direction = horizontal
+contents = $space(10)
+contents = verticalSizer
+contents = $space(10)
+
+[wxBoxSizer verticalSizer]
+direction = vertical
+grow = yes
+proportion = 1
+contents = $space(10)
+contents = sttFilename left
+contents = $space(10)
+contents = gaugeProgress centered-x
+contents = $space(10)
+contents = sttWait left
+contents = $space(10)
+contents = bCancel centered-x
+contents = $space(10)
+
+[wxStaticText sttFilename]
+text = ((firstFileName) ? firstFileName : dkwx_pd_def_texts[0])
+text style = centered
+grow = yes
+proportion = 1
+
+[wxGauge gaugeProgress]
+range = 1000
+value = 0
+grow = yes
+
+[wxButton bCancel]
+text = ((buttonText) ? buttonText : dkwx_pd_def_texts[2])
+tip = ((buttonTip) ? buttonTip : dkwx_pd_def_texts[3])
+id = wxID_CANCEL
+
+[wxStaticText sttWait]
+text = ((waitText) ? waitText : dkwx_pd_def_texts[4])
+text style = left no-auto-resize
+
+
+
+%% header start
+
+#include <DkWxCommunicator.h>
+
+
+
+%% class start
+
+/** Progress dialog showing currently process file, progress bar
+ and a button to abort operation.
+*/
+class DkWxProgressDialog : public wxDialog
+{
+ private:
+ /** Event table.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ /** Communicator object delivering the file name and progress bar
+ value.
+ */
+ DkWxCommunicator *pComm;
+
+ /** String: Cancel operation scheduled. Please wait.
+ */
+ wxChar const *sWaitPlease;
+
+ /** Parent frame.
+ */
+ DkWxFrame *pParent;
+
+ /** Log text field to receive the messages.
+ */
+ wxTextCtrl *pLogTextField;
+
+%% class end
+ public:
+
+ /** Constructor.
+ @param parent Parent window.
+ @param comm Communicator object.
+ @param tc Text control to show messages.
+ @param title Title text.
+ @param firstFileName First file name to show.
+ @param buttonText Text for "Cancel" button.
+ @param buttonTip Tooltip text for button.
+ @param waitText Button to show while waiting for thread exit.
+ */
+ DkWxProgressDialog(
+ DkWxFrame *parent,
+ DkWxCommunicator *comm,
+ wxTextCtrl *tc,
+ wxChar const *title,
+ wxChar const *firstFileName,
+ wxChar const *buttonText,
+ wxChar const *buttonTip,
+ wxChar const *waitText
+ );
+
+ /** Handler for idle events.
+ We request the current file name and progress bar from
+ the communicator object and update the information shown
+ in the dialog.
+ */
+ void
+ OnIdle(wxIdleEvent & event);
+
+ /** Handler for cancel button.
+ */
+ void
+ OnCancel(wxCommandEvent & WXUNUSED(event));
+
+ /** Choose a modal position centered on the parent.
+ */
+ void chooseModalPosition();
+
+};
+
+
+
+%% header end
+
+%% module start
+
+#include "dkwxtrace.h"
+
+$!trace-include
+
+BEGIN_EVENT_TABLE(DkWxProgressDialog,wxDialog)
+ EVT_IDLE(DkWxProgressDialog::OnIdle)
+ EVT_BUTTON(wxID_CANCEL, DkWxProgressDialog::OnCancel)
+END_EVENT_TABLE()
+
+
+
+/** Default texts to use if the constructor has NULL pointer arguments.
+*/
+wxChar const * const dkwx_pd_def_texts[] = {
+$!string-table macro=wxT
+#
+# 0: Empty string
+#
+
+#
+# 1: Default title.
+#
+Progress
+#
+# 2: Button text.
+#
+Cancel
+#
+# 3: Button tool tip.
+#
+Push button to interrupt processing.
+#
+# 4: Notification, user should wait.
+#
+Cancel command scheduled... Wait, please!
+$!end
+};
+
+
+
+%% constructor start
+DkWxProgressDialog::DkWxProgressDialog(
+ DkWxFrame *parent,
+ DkWxCommunicator *comm,
+ wxTextCtrl *tc,
+ wxChar const *title,
+ wxChar const *firstFileName,
+ wxChar const *buttonText,
+ wxChar const *buttonTip,
+ wxChar const *waitText
+) : wxDialog(
+ parent,
+ wxID_ANY,
+ ((title) ? title : dkwx_pd_def_texts[1]),
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxDEFAULT_DIALOG_STYLE
+)
+{
+ $? "+ DkWxProgressDialog::DkWxProgressDialog"
+ pParent = parent;
+ pLogTextField = tc;
+ pComm = comm;
+ sWaitPlease = ((waitText) ? waitText : dkwx_pd_def_texts[4]);
+%% constructor end
+ if(dkctGUILayoutOK) {
+ if(sttWait) {
+ sttWait->SetLabel(dkwx_pd_def_texts[0]);
+ }
+ }
+ $? "- DkWxProgressDialog::DkWxProgressDialog"
+}
+
+
+
+%% module end
+
+
+void
+DkWxProgressDialog::OnIdle(wxIdleEvent & event)
+{
+ int canContinue = 1;
+ int res;
+ $? "+ DkWxProgressDialog::OnIdle"
+ if(pComm) { $? ". pComm ok"
+ res = pComm->getUpdates(this, sttFilename, gaugeProgress);
+ $? ". res = %d", res
+ if(res & DK_WX_COMMUNICATOR_STATUS_UPDATE) { $? ". must update"
+ Refresh();
+ Update();
+ } else { $? ". no update"
+ }
+ if(res & DK_WX_COMMUNICATOR_STATUS_RUNNING) { $? ". can continue"
+ canContinue = 1;
+ } else { $? ". finished, end indicated"
+ canContinue = 0;
+ }
+ } else { $? "! no pComm"
+ canContinue = 0;
+ }
+ if(canContinue) { $? ". can continue"
+ event.RequestMore();
+ } else { $? ". finished"
+ canContinue = 1;
+ if(pComm) {
+ canContinue = pComm->getCanContinue();
+ if(pLogTextField) { $? ". transfer text"
+ pComm->getText(pLogTextField);
+ if(pParent) { $? ". refresh win"
+ pParent->Refresh();
+ } else { $? ". refresh text"
+ pLogTextField->Refresh();
+ }
+ }
+ }
+ if(IsModal()) { $? ". end modal"
+ EndModal((canContinue) ? wxID_OK : wxID_CANCEL);
+ } else { $? ". show false"
+ SetReturnCode((canContinue) ? wxID_OK : wxID_CANCEL);
+ Show(false);
+ }
+ }
+ event.Skip(); $? "- DkWxProgressDialog::OnIdle"
+}
+
+
+
+void
+DkWxProgressDialog::OnCancel(wxCommandEvent & event)
+{
+ $? "+ DkWxProgressDialog::OnCancel"
+ if(pComm) {
+ pComm->setCanContinue(0);
+ }
+ if(sttWait) {
+ sttWait->SetLabel(sWaitPlease);
+ }
+ if(bCancel) {
+ bCancel->Enable(false);
+ bCancel->SetToolTip(sWaitPlease);
+ }
+ Refresh();
+ Update();
+ $? "- DkWxProgressDialog::OnCancel"
+}
+
+
+
+void
+DkWxProgressDialog::chooseModalPosition()
+{
+ int px = 0; /* Parent x position. */
+ int py = 0; /* Parent y position. */
+ int pw = 0; /* Parent width. */
+ int ph = 0; /* Parent height. */
+ int x = 0; /* X position. */
+ int y = 0; /* Y position. */
+ int w = 0; /* Width. */
+ int h = 0; /* Height. */
+ $? "+ DkWxProgressDialog::chooseModalPosition"
+ /* Sceen size */
+ wxSize scsz = wxGetDisplaySize();
+ pParent->GetPosition(&px, &py);
+ pParent->GetSize(&pw, &ph);
+ GetSize(&w, &h);
+ x = px + (pw - w) / 2;
+ y = py + (ph - h) / 2;
+ if((x + w) > scsz.x) { x = scsz.x - w; }
+ if((y + h) > scsz.y) { y = scsz.y - h; }
+ if(x < 0) { x = 0; }
+ if(y < 0) { y = 0; }
+ SetSize(x, y, w, h);
+ $? "- DkWxProgressDialog::chooseModalPosition"
+}
+
+
diff --git a/support/dktools/DkWxTraceApp.cpp b/support/dktools/DkWxTraceApp.cpp
new file mode 100644
index 0000000000..66156853eb
--- /dev/null
+++ b/support/dktools/DkWxTraceApp.cpp
@@ -0,0 +1,562 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxTraceApp.cpt
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxTraceApp.cpp The DkWxTraceApp module.
+*/
+
+
+#line 47 "DkWxTraceApp.cpt"
+
+#include "dkwxtrace.h"
+
+
+
+
+
+#line 53 "DkWxTraceApp.cpt"
+
+
+/** Implementation of DkWxTraceApp.
+*/
+IMPLEMENT_APP(DkWxTraceApp)
+
+
+
+/** Default texts, replace by localized texts if available.
+*/
+wxChar const * const defaultTexts[] = {
+/* 0 */
+wxT("wxdkct"),
+
+/* 1 */
+wxT("dktools"),
+
+/* 2 */
+wxT("Dirk Krause"),
+
+/* 3 */
+wxT("&File"),
+
+/* 4 */
+wxT("&Help"),
+
+/* 5 */
+wxT("E&xit\tAlt-X"),
+
+/* 6 */
+wxT("&About...\tAlt-A"),
+
+/* 7 */
+wxT("Exit the program"),
+
+/* 8 */
+wxT("Show version information"),
+
+/* 9 */
+wxT("&Contents\tF1"),
+
+/* 10 */
+wxT("Show online help contents"),
+
+/* 11 */
+wxT("Directory:"),
+
+/* 12 */
+wxT("&Directory\tAlt-D"),
+
+/* 13 */
+wxT("Choose source directory"),
+
+/* 14 */
+wxT("&Setup\tAlt-S"),
+
+/* 15 */
+wxT("Set conversion options"),
+
+/* 16 */
+wxT("yes, to stdout"),
+
+/* 17 */
+wxT("Directory"),
+
+/* 18 */
+wxT("Options"),
+
+/* 19 */
+wxT("Run"),
+
+/* 20 */
+wxT("Exit"),
+
+/* 21 */
+wxT("Choose directory"),
+
+/* 22 */
+wxT("Set options"),
+
+/* 23 */
+wxT("Run conversion"),
+
+/* 24 */
+wxT("Exit the application"),
+
+/* 25 */
+wxT("."),
+
+/* 26 */
+wxT("OK"),
+
+/* 27 */
+wxT("Cancel"),
+
+/* 28 */
+wxT("Close dialog and apply settings"),
+
+/* 29 */
+wxT("Close dialog and discard settings"),
+
+/* 30 */
+wxT("Options"),
+
+/* 31 */
+wxT("Use make mode"),
+
+/* 32 */
+wxT("Run conversions only if necessary."),
+
+/* 33 */
+wxT("General options"),
+
+/* 34 */
+wxT("Output"),
+
+/* 35 */
+wxT("Line numbers"),
+
+/* 36 */
+wxT("Debug"),
+
+/* 37 */
+wxT("Create debug output"),
+
+/* 38 */
+wxT("Debug to standard output"),
+
+/* 39 */
+wxT("Include timestamp"),
+
+/* 40 */
+wxT("Use \"trace\" keyword"),
+
+/* 41 */
+wxT("Wide-character support"),
+
+/* 42 */
+wxT("Create line number directives"),
+
+/* 43 */
+wxT("Generate code for trace/debug messages"),
+
+/* 44 */
+wxT("Write trace/debug messages to standard output"),
+
+/* 45 */
+wxT("Include a timestamp into trace/debug messages"),
+
+/* 46 */
+wxT("Include the \"trace\" keyword into debug messages"),
+
+/* 47 */
+wxT("Add support for TRACE_WIDE (debug messages in wide characters)"),
+
+/* 48 */
+wxT("Conversion progress"),
+
+/* 49 */
+wxT(""),
+
+/* 50 */
+wxT("Cancel"),
+
+/* 51 */
+wxT("Abort conversion after finishing current file"),
+
+/* 52 */
+wxT("Cancel command scheduled... Wait, please!"),
+
+/* 53 */
+wxT("Choose directory"),
+
+/* 54 */
+wxT("Directory: "),
+
+/* 55 */
+wxT("Destination files up to date."),
+
+/* 56 */
+wxT("Processing succeeded."),
+
+/* 57 */
+wxT("Processing failed!"),
+
+/* 58 */
+wxT("ERROR: Can not handle directory name!"),
+
+/* 59 */
+wxT("ERROR: Failed to open directory \""),
+
+/* 60 */
+wxT("\"!"),
+
+/* 61 */
+wxT("ERROR: File name is not plain ASCII text: \""),
+
+/* 62 */
+wxT("\"!"),
+
+/* 63 */
+wxT("ERROR: Not enough memory (RAM/swap space)!"),
+
+/* 64 */
+wxT("&Run\tAlt-R"),
+
+/* 65 */
+wxT("Start conversion"),
+
+/* 66 */
+wxT("About wxdkct"),
+
+/* 67 */
+wxT(""),
+
+/* 68 */
+wxT("Processing succeeded"),
+
+/* 69 */
+wxT("Warnings occured"),
+
+/* 70 */
+wxT("Errors occured"),
+
+/* 71 */
+wxT("Automatic run cancelled due to errors!"),
+
+/* 72 */
+wxT("Processing succeeded, application will exit."),
+
+/* 73 */
+wxT("\n"),
+
+/* 74 */
+wxT("This program uses libraries from the following projects:\n"),
+
+/* 75 */
+wxT("See:\n"),
+
+/* 76 */
+wxT("@"),
+
+/* 77 */
+wxT("^"),
+
+/* 78 */
+wxT("°"),
+
+/* 79 */
+wxT("!"),
+
+/* 80 */
+wxT("\""),
+
+/* 81 */
+wxT("§"),
+
+/* 82 */
+wxT("$"),
+
+/* 83 */
+wxT("%"),
+
+/* 84 */
+wxT("&"),
+
+/* 85 */
+wxT("?"),
+
+/* 86 */
+wxT("~"),
+
+/* 87 */
+wxT("#"),
+
+/* 88 */
+wxT("|"),
+
+/* 89 */
+wxT(","),
+
+/* 90 */
+wxT(";"),
+
+/* 91 */
+wxT("."),
+
+/* 92 */
+wxT(":"),
+
+/* 93 */
+wxT("_"),
+
+/* 94 */
+wxT("Comments for splint"),
+
+/* 95 */
+wxT("Write comments for splint"),
+
+/* 96 */
+wxT("Choose the comment character for splint"),
+
+/* 97 */
+wxT("Portable debug code"),
+
+/* 98 */
+wxT("Produce portable code for trace messages"),
+
+NULL
+
+
+#line 399 "DkWxTraceApp.cpt"
+};
+
+
+
+/** Constant texts, not localized.
+*/
+static wxChar const * const wxdkct_nl_wx[] = {
+/* 0 */
+wxT("Error"),
+
+/* 1 */
+wxT("Not enough memory (RAM)!"),
+
+NULL
+
+
+#line 410 "DkWxTraceApp.cpt"
+};
+
+
+
+/** Application group name.
+*/
+static dkChar const dkwxtraceapp_groupname[] = { dkT("dktools") };
+
+
+
+/** String table file name.
+*/
+static dkChar const dkwxtrace_string_table_name[] = { dkT("wxdkct.str") };
+
+
+
+/** Help file for use on Windows systems.
+*/
+static wxChar const dkwxtrace_chm_helpfile[] = { wxT("wxdkct.chm") };
+
+
+
+/** Help file for use on non-Windows systems.
+*/
+static wxChar const dkwxtrace_htb_helpfile[] = { wxT("wxdkct.htb") };
+
+
+
+bool
+DkWxTraceApp::OnInit()
+{
+ bool back = false;
+ wxChar const * const *localizedTexts = defaultTexts;
+ dkChar const * const *msg = NULL;
+ DkWxTraceFrame *frame = NULL;
+ wxPNGHandler *phPng = NULL;
+ wxXPMHandler *phXpm = NULL;
+ wxICOHandler *phIco = NULL;
+ wxZipFSHandler *phZipFs = NULL;
+
+ /* Initialize elements.
+ */
+ pHelper = NULL;
+ helpController = NULL;
+
+ /* Create application helper.
+ */
+ pHelper =
+ new DkWxAppHelper(argv[0], defaultTexts[2], dkwxtraceapp_groupname);
+ if (NULL == pHelper) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ if (!(pHelper->checkSetup())) {
+ goto finished;
+ }
+
+ /* Get message texts.
+ */
+ msg = dk3app_messages(
+ pHelper->getApp(), dkct_str_get_string_table_file_name(),
+ (dkChar const **)dkct_str_get_message_texts()
+ );
+ if (NULL == msg) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ localizedTexts =
+ pHelper->getStringTable(defaultTexts, dkwxtrace_string_table_name);
+ if (NULL == localizedTexts) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ /* Initialize image handlers and zip fs handler.
+ */
+ phPng = new wxPNGHandler();
+ if (NULL != phPng) {
+ wxImage::AddHandler(phPng);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phXpm = new wxXPMHandler();
+ if (NULL != phXpm) {
+ wxImage::AddHandler(phXpm);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phIco = new wxICOHandler();
+ if (NULL != phIco) {
+ wxImage::AddHandler(phIco);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phZipFs = new wxZipFSHandler();
+ if (NULL != phZipFs) {
+ wxFileSystem::AddHandler(phZipFs);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ /* Get help controller.
+ */
+ helpController =
+ new DkWxHelpController(pHelper,dkwxtrace_chm_helpfile,dkwxtrace_htb_helpfile);
+ if (NULL == helpController) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ /* Create main frame.
+ */
+ frame = new DkWxTraceFrame(
+ defaultTexts[0], localizedTexts, msg, pHelper, DkWxTrace_MainWindow,
+ helpController, argc, argv
+ );
+ if (NULL == frame) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ /* Show frame and indicate success.
+ */
+ frame->Show();
+ frame->restorePosition();
+ back = true;
+
+ /* Clean up on errors.
+ */
+ finished:
+ if (!(back)) {
+ if (NULL != helpController) {
+ delete(helpController);
+ helpController = NULL;
+ }
+ if (NULL != pHelper) {
+ delete(pHelper);
+ pHelper = NULL;
+ }
+ }
+ return back;
+}
+
+
+
+int
+DkWxTraceApp::OnExit()
+{
+ int back = 0;
+ /*
+ Release elements.
+ */
+ if(helpController) {
+ delete(helpController); helpController = NULL;
+ }
+ if(pHelper) {
+ delete(pHelper); pHelper = NULL;
+ }
+ return back;
+}
+
+
+
+void
+DkWxTraceApp::ShowMemoryErrorMessage(void)
+{
+ const wxChar *s_title = NULL;
+ const wxChar *s_text = NULL;
+
+ if (NULL != pHelper) {
+ s_title = pHelper->getBasicString(3);
+ s_text = pHelper->getBasicString(9);
+ }
+ if (NULL == s_title) {
+ s_title = wxdkct_nl_wx[0];
+ }
+ if (NULL == s_text) {
+ s_text = wxdkct_nl_wx[1];
+ }
+ wxMessageBox(s_text, s_title, (wxOK | wxCENTRE | wxICON_ERROR));
+}
diff --git a/support/dktools/DkWxTraceApp.cpt b/support/dktools/DkWxTraceApp.cpt
new file mode 100644
index 0000000000..76b187339d
--- /dev/null
+++ b/support/dktools/DkWxTraceApp.cpt
@@ -0,0 +1,594 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% header
+
+/** Application class for dkwxtrace.
+*/
+class DkWxTraceApp : public wxApp
+{
+ protected:
+
+ /** Helper object.
+ */
+ DkWxAppHelper *pHelper;
+
+ /** Help controller.
+ */
+ DkWxHelpController *helpController;
+
+ protected:
+
+ /** Show error message if not sufficient memory available.
+ */
+ void
+ ShowMemoryErrorMessage(void);
+
+ public:
+ /** Initialize application.
+ */
+ virtual bool OnInit();
+
+ /** Clean up after running.
+ */
+ virtual int OnExit();
+};
+
+DECLARE_APP(DkWxTraceApp)
+
+
+
+%% module
+
+#include "dkwxtrace.h"
+
+
+
+$!trace-include
+
+
+/** Implementation of DkWxTraceApp.
+*/
+IMPLEMENT_APP(DkWxTraceApp)
+
+
+
+/** Default texts, replace by localized texts if available.
+*/
+wxChar const * const defaultTexts[] = {
+$!string-table macro=wxT
+#
+# 0: Program name
+#
+wxdkct
+#
+# 1: Application group name
+#
+dktools
+#
+# 2: Software vendor name
+#
+Dirk Krause
+#
+# 3: Menu: File
+#
+&File
+#
+# 4: Menu: Help
+#
+&Help
+#
+# 5: Menu: File / Exit
+#
+E&xit Alt-X
+#
+# 6: Menu: Help / About
+#
+&About... Alt-A
+#
+# 7: Tip text for menu entry File / Exit
+#
+Exit the program
+#
+# 8: Tip text for menu entry Help / About
+#
+Show version information
+#
+# 9: Menu Help / Contents
+#
+&Contents F1
+#
+# 10: Menu tool tip: Show online help contents
+#
+Show online help contents
+#
+# 11: Label text: Directory
+#
+Directory:
+#
+# 12: Menu text: Choose Directory
+#
+&Directory Alt-D
+#
+# 13: Menu tool tip: Choose source directory
+#
+Choose source directory
+#
+# 14: Menu text: Setup
+#
+&Setup Alt-S
+#
+# 15: Menu tool tip: Set conversion options
+#
+Set conversion options
+#
+# 16 Label text: yes, to stdout
+#
+yes, to stdout
+#
+# 17: Toolbar button text: Directory
+#
+Directory
+#
+# 18: Toolbar button text: Options
+#
+Options
+#
+# 19: Toolbar button text: Run
+#
+Run
+#
+# 20: Toolbar button text: Exit
+#
+Exit
+#
+# 21: Toolbar button tooltip: Choose directory
+#
+Choose directory
+#
+# 22: Toolbar button tooltip: Set options.
+#
+Set options
+#
+# 23: Toolbar button tooltip: Run conversion
+#
+Run conversion
+#
+# 24: Toolbar button tooltip: Exit the application
+#
+Exit the application
+#
+# 25: Current directory.
+#
+.
+#
+# 26: Button text: OK
+#
+OK
+#
+# 27: Button text: Cancel
+#
+Cancel
+#
+# 28: Button tool tip for OK button.
+#
+Close dialog and apply settings
+#
+# 29: Button tool tip for cancel button.
+#
+Close dialog and discard settings
+#
+# 30: Dialog title: Options
+#
+Options
+#
+# 31: Checkbox label: Use make mode
+#
+Use make mode
+#
+# 32: Checkbox tool tip: Run conversions only if necessary.
+#
+Run conversions only if necessary.
+#
+# 33: Static box title: General options
+#
+General options
+#
+# 34: Static box title: Output
+#
+Output
+#
+# 35: Checkbox label: Line numbers
+#
+Line numbers
+#
+# 36: Static box title: Debug
+#
+Debug
+#
+# 37: Checkbox label: Create debug output
+#
+Create debug output
+#
+# 38: Checkbox label: Debug to standard output
+#
+Debug to standard output
+#
+# 39: Checkbox label: Include timestamp
+#
+Include timestamp
+#
+# 40: Checkbox label: Use trace keyword
+#
+Use "trace" keyword
+#
+# 41: Checkbox label: Wide character support
+#
+Wide-character support
+#
+# 42: Checkbox tool tip: Create line number directives
+#
+Create line number directives
+#
+# 43: Checkbox tool tip: Generate code for debug messages
+#
+Generate code for trace/debug messages
+#
+# 44: Checkbox tool tip: Write trace/debug messages to standard output
+#
+Write trace/debug messages to standard output
+#
+# 45: Checkbox tool tip: Include a timestamp into debug messages
+#
+Include a timestamp into trace/debug messages
+#
+# 46: Checkbox tool tip: Include "trace" keyword into debug messages
+#
+Include the "trace" keyword into debug messages
+#
+# 47: Checkbox tool tip: Add support for TRACE_WIDE
+#
+Add support for TRACE_WIDE (debug messages in wide characters)
+#
+# 48: Dialog title: Conversion progress
+#
+Conversion progress
+#
+# 49: File name (empty string)
+#
+
+#
+# 50: Button text: Cancel
+#
+Cancel
+#
+# 51: Button tool tip: Abort conversion after finishing current file
+#
+Abort conversion after finishing current file
+#
+# 52: Notification text: Cancel command scheduled... Wait, please!
+#
+Cancel command scheduled... Wait, please!
+#
+# 53: Directory dialog title: Choose directory
+#
+Choose directory
+#
+# 54: Message text: Directory:
+#
+Directory:
+#
+# 55: Message text: Destination files up to date.
+#
+Destination files up to date.
+#
+# 56: Message text: Processing succeeded.
+#
+Processing succeeded.
+#
+# 57: Message text:Processing failed!
+#
+Processing failed!
+#
+# 58: Error: Can not handle directory name!
+#
+ERROR: Can not handle directory name!
+#
+# 59/60: Error: Failed to open directory "..."!
+#
+ERROR: Failed to open directory "
+"!
+#
+# 61/62: Error: File name is not plain ASCII text: "..."!
+#
+ERROR: File name is not plain ASCII text: "
+"!
+#
+# 63: Error: Not enough memory!
+#
+ERROR: Not enough memory (RAM/swap space)!
+#
+# 64: Menu item: Run
+#
+&Run Alt-R
+#
+# 65: Menut tool tip: Start conversion
+#
+Start conversion
+#
+# 66: About dialog box title.
+#
+About wxdkct
+#
+# 67: Empty text (initial status text).
+#
+
+#
+# 68: Run result: Processing succeeded
+#
+Processing succeeded
+#
+# 69: Run result: Warnings occured
+#
+Warnings occured
+#
+# 70: Run result: Errors occured
+#
+Errors occured
+#
+# 71: ERROR: Automatic run cancelled due to errors.
+#
+Automatic run cancelled due to errors!
+#
+# 72: Autorun result: Processing succeeded, application will exit.
+#
+Processing succeeded, application will exit.
+#
+# 73: Newline
+#
+\n
+#
+# 74: This program uses libraries from the following projects:
+#
+This program uses libraries from the following projects:\n
+#
+# 75: See
+#
+See:\n
+#
+# 76-93: Special character candidates for splint.
+#
+@
+^
+°
+!
+"
+§
+$
+%
+&
+?
+~
+\#
+|
+,
+;
+.
+:
+_
+#
+# 94-95: Comments for splint
+#
+Comments for splint
+Write comments for splint
+#
+# 96: Choose comment character for splint
+#
+Choose the comment character for splint
+#
+# 97 98 Check box: Portable debug code and tool tip
+#
+Portable debug code
+Produce portable code for trace messages
+$!end
+};
+
+
+
+/** Constant texts, not localized.
+*/
+static wxChar const * const wxdkct_nl_wx[] = {
+$!string-table macro=wxT
+Error
+Not enough memory (RAM)!
+$!end
+};
+
+
+
+/** Application group name.
+*/
+static dkChar const dkwxtraceapp_groupname[] = { dkT("dktools") };
+
+
+
+/** String table file name.
+*/
+static dkChar const dkwxtrace_string_table_name[] = { dkT("wxdkct.str") };
+
+
+
+/** Help file for use on Windows systems.
+*/
+static wxChar const dkwxtrace_chm_helpfile[] = { wxT("wxdkct.chm") };
+
+
+
+/** Help file for use on non-Windows systems.
+*/
+static wxChar const dkwxtrace_htb_helpfile[] = { wxT("wxdkct.htb") };
+
+
+
+bool
+DkWxTraceApp::OnInit()
+{
+ bool back = false;
+ wxChar const * const *localizedTexts = defaultTexts;
+ dkChar const * const *msg = NULL;
+ DkWxTraceFrame *frame = NULL;
+ wxPNGHandler *phPng = NULL;
+ wxXPMHandler *phXpm = NULL;
+ wxICOHandler *phIco = NULL;
+ wxZipFSHandler *phZipFs = NULL;
+
+ /* Initialize elements.
+ */
+ pHelper = NULL;
+ helpController = NULL;
+
+ /* Create application helper.
+ */
+ pHelper =
+ new DkWxAppHelper(argv[0], defaultTexts[2], dkwxtraceapp_groupname);
+ if (NULL == pHelper) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ if (!(pHelper->checkSetup())) {
+ goto finished;
+ }
+
+ /* Get message texts.
+ */
+ msg = dk3app_messages(
+ pHelper->getApp(), dkct_str_get_string_table_file_name(),
+ (dkChar const **)dkct_str_get_message_texts()
+ );
+ if (NULL == msg) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ localizedTexts =
+ pHelper->getStringTable(defaultTexts, dkwxtrace_string_table_name);
+ if (NULL == localizedTexts) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ /* Initialize image handlers and zip fs handler.
+ */
+ phPng = new wxPNGHandler();
+ if (NULL != phPng) {
+ wxImage::AddHandler(phPng);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phXpm = new wxXPMHandler();
+ if (NULL != phXpm) {
+ wxImage::AddHandler(phXpm);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phIco = new wxICOHandler();
+ if (NULL != phIco) {
+ wxImage::AddHandler(phIco);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phZipFs = new wxZipFSHandler();
+ if (NULL != phZipFs) {
+ wxFileSystem::AddHandler(phZipFs);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ /* Get help controller.
+ */
+ helpController =
+ new DkWxHelpController(pHelper,dkwxtrace_chm_helpfile,dkwxtrace_htb_helpfile);
+ if (NULL == helpController) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ /* Create main frame.
+ */
+ frame = new DkWxTraceFrame(
+ defaultTexts[0], localizedTexts, msg, pHelper, DkWxTrace_MainWindow,
+ helpController, argc, argv
+ );
+ if (NULL == frame) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ /* Show frame and indicate success.
+ */
+ frame->Show();
+ frame->restorePosition();
+ back = true;
+
+ /* Clean up on errors.
+ */
+ finished:
+ if (!(back)) {
+ if (NULL != helpController) {
+ delete(helpController);
+ helpController = NULL;
+ }
+ if (NULL != pHelper) {
+ delete(pHelper);
+ pHelper = NULL;
+ }
+ }
+ return back;
+}
+
+
+
+int
+DkWxTraceApp::OnExit()
+{
+ int back = 0;
+ /*
+ Release elements.
+ */
+ if(helpController) {
+ delete(helpController); helpController = NULL;
+ }
+ if(pHelper) {
+ delete(pHelper); pHelper = NULL;
+ }
+ return back;
+}
+
+
+
+void
+DkWxTraceApp::ShowMemoryErrorMessage(void)
+{
+ const wxChar *s_title = NULL;
+ const wxChar *s_text = NULL;
+
+ if (NULL != pHelper) {
+ s_title = pHelper->getBasicString(3);
+ s_text = pHelper->getBasicString(9);
+ }
+ if (NULL == s_title) {
+ s_title = wxdkct_nl_wx[0];
+ }
+ if (NULL == s_text) {
+ s_text = wxdkct_nl_wx[1];
+ }
+ wxMessageBox(s_text, s_title, (wxOK | wxCENTRE | wxICON_ERROR));
+}
diff --git a/support/dktools/DkWxTraceApp.h b/support/dktools/DkWxTraceApp.h
new file mode 100644
index 0000000000..20a97314f4
--- /dev/null
+++ b/support/dktools/DkWxTraceApp.h
@@ -0,0 +1,82 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxTraceApp.cpt
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxTraceApp.h Header file for the DkWxTraceApp module.
+*/
+
+#ifndef DKWXTRACEAPP_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DKWXTRACEAPP_H_INCLUDED 1
+
+
+#line 10 "DkWxTraceApp.cpt"
+
+/** Application class for dkwxtrace.
+*/
+class DkWxTraceApp : public wxApp
+{
+ protected:
+
+ /** Helper object.
+ */
+ DkWxAppHelper *pHelper;
+
+ /** Help controller.
+ */
+ DkWxHelpController *helpController;
+
+ protected:
+
+ /** Show error message if not sufficient memory available.
+ */
+ void
+ ShowMemoryErrorMessage(void);
+
+ public:
+ /** Initialize application.
+ */
+ virtual bool OnInit();
+
+ /** Clean up after running.
+ */
+ virtual int OnExit();
+};
+
+DECLARE_APP(DkWxTraceApp)
+
+
+
+
+#endif
diff --git a/support/dktools/DkWxTraceFrame.cpp b/support/dktools/DkWxTraceFrame.cpp
new file mode 100644
index 0000000000..93f42c669a
--- /dev/null
+++ b/support/dktools/DkWxTraceFrame.cpp
@@ -0,0 +1,1037 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxTraceFrame.wxc
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxTraceFrame.cpp The DkWxTraceFrame module.
+*/
+
+
+#line 323 "DkWxTraceFrame.wxc"
+
+
+
+#include "dkwxtrace.h"
+#include "dk4verswx.h"
+
+
+
+/*
+ Icons and bitmaps
+*/
+#include "dkicon.xpm"
+#include "choose-dir.xpm"
+#include "exit-program.xpm"
+#include "run-conversion.xpm"
+#include "set-options.xpm"
+
+
+
+#line 341 "DkWxTraceFrame.wxc"
+
+
+/** Version for the about dialog (program name).
+*/
+static wxChar const dkwxct_version[] = {
+ wxT("wxdkct (part of dktools-")
+};
+
+/** Version number for the about dialog (version number).
+*/
+static wxChar const dkwxct_versnumber[] = {
+ DKT_VERSION_WX
+};
+
+/** Version number for the about dialog (end).
+*/
+static wxChar const dkwxct_versend[] = {
+ wxT(")")
+};
+
+static wxChar const * const dkwxct_settings_names[] = {
+/* 0 */
+wxT("wxdkct.make"),
+
+/* 1 */
+wxT("wxdkct.line-numbers"),
+
+/* 2 */
+wxT("wxdkct.debug"),
+
+/* 3 */
+wxT("wxdkct.debug.timestamp"),
+
+/* 4 */
+wxT("wxdkct.debug.keyword"),
+
+/* 5 */
+wxT("wxdkct.debug.wide"),
+
+/* 6 */
+wxT("wxdkct.splint.use"),
+
+/* 7 */
+wxT("wxdkct.splint.selected"),
+
+NULL
+
+
+#line 396 "DkWxTraceFrame.wxc"
+};
+
+
+
+static wxChar const * dkwxct_string_settings_names[] = {
+/* 0 */
+wxT("wxdkct.directory"),
+
+NULL
+
+
+#line 407 "DkWxTraceFrame.wxc"
+};
+
+
+/** Event table for the DkWxTraceFrame class.
+ */
+BEGIN_EVENT_TABLE(DkWxTraceFrame, wxFrame)
+ EVT_MENU(DkWxTrace_Quit, DkWxTraceFrame::OnQuit)
+ EVT_MENU(DkWxTrace_Help_Contents, DkWxTraceFrame::OnHelpContents)
+ EVT_MENU(DkWxTrace_About, DkWxTraceFrame::OnAbout)
+ EVT_MENU(DkWxTrace_ChooseDirectory, DkWxTraceFrame::OnChooseDirectory)
+ EVT_MENU(DkWxTrace_SetOptions, DkWxTraceFrame::OnSetOptions)
+ EVT_MENU(DkWxTrace_Run, DkWxTraceFrame::OnRunConversion)
+ EVT_IDLE(DkWxTraceFrame::OnIdle)
+END_EVENT_TABLE()
+
+
+
+static const wxCmdLineEntryDesc wxdkctframe_cmd_line_desc[] = {
+ {
+ wxCMD_LINE_SWITCH,
+ wxT_2("r"),
+ wxT_2("run"),
+ wxT_2("Run conversion")
+ },
+ {
+ wxCMD_LINE_SWITCH,
+ wxT_2("R"),
+ wxT_2("reset"),
+ wxT_2("Reset all options")
+ },
+ {
+ wxCMD_LINE_SWITCH,
+ wxT_2("m"),
+ wxT_2("make"),
+ wxT_2("Run in make mode")
+ },
+ {
+ wxCMD_LINE_SWITCH,
+ wxT_2("l"),
+ wxT_2("line-numbers"),
+ wxT_2("Run conversion")
+ },
+ {
+ wxCMD_LINE_OPTION,
+ wxT_2("b"),
+ wxT_2("box"),
+ wxT_2("Box width"),
+ wxCMD_LINE_VAL_NUMBER
+ },
+
+ {
+ wxCMD_LINE_SWITCH,
+ wxT_2("d"),
+ wxT_2("debug"),
+ wxT_2("Create debug output")
+ },
+ {
+ wxCMD_LINE_SWITCH,
+ wxT_2("s"),
+ wxT_2("debug-stdout"),
+ wxT_2("Send debug output to standard output")
+ },
+ {
+ wxCMD_LINE_SWITCH,
+ wxT_2("t"),
+ wxT_2("time"),
+ wxT_2("Include timestamps in debug output")
+ },
+ {
+ wxCMD_LINE_SWITCH,
+ wxT_2("k"),
+ wxT_2("keyword"),
+ wxT_2("Include \"trace\" keyword in debug output")
+ },
+ {
+ wxCMD_LINE_SWITCH,
+ wxT_2("w"),
+ wxT_2("wide"),
+ wxT_2("Allow wide character debug output")
+ },
+ {
+ wxCMD_LINE_PARAM,
+ NULL,
+ NULL,
+ wxT_2("input file"),
+ wxCMD_LINE_VAL_STRING,
+ wxCMD_LINE_PARAM_OPTIONAL
+ },
+ { wxCMD_LINE_NONE }
+};
+
+
+
+#line 500 "DkWxTraceFrame.wxc"
+DkWxTraceFrame::DkWxTraceFrame(
+ wxChar const *applicationName,
+ wxChar const * const *messageTexts,
+ dkChar const * const *m,
+ DkWxAppHelper *applicationHelper,
+ int wxid,
+ DkWxHelpController *hc,
+ int argc,
+ wxChar **argv
+) : DkWxFrame(applicationName, applicationHelper, hc, wxid)
+{
+
+
+#line 512 "DkWxTraceFrame.wxc"
+ ddx = -1; ddy = -1;
+ odx = -1; ody = -1;
+ bAutoStartRequested = false;
+ pComm = NULL;
+ cBlack = NULL;
+ cGreen = NULL;
+ cRed = NULL;
+ sDirectory = NULL;
+ sTexts = messageTexts;
+ msg = m;
+ bSaveSettings = true;
+ bSaveDirectory = true;
+ bCloseScheduled = false;
+ bGuiActive = true;
+#if defined(__WXMSW__)
+ wxIcon dkicon_bitmap(wxT("aaaaa")); /* from resource file */
+#else
+ wxIcon dkicon_bitmap(xpm_dkicon); /* from included xpm */
+#endif
+ options.deb = 0;
+ options.deben = 1;
+ options.lnn = 0;
+ options.mak = 0;
+ options.sty = 0;
+ options.bw = 75;
+ options.tkw = 0;
+ options.ts = 0;
+ options.win = 0;
+ options.tip = 0;
+ timeClose = (dk3_time_t)0UL;
+ getData();
+ dkctGUILayoutOK = false;
+ dkctGUIContentsPanel = NULL;
+ mbMain = NULL;
+ mainSizer = NULL;
+ tbMain = NULL;
+ bDir = NULL;
+ bOptions = NULL;
+ bRun = NULL;
+ bExit = NULL;
+ menuFile = NULL;
+ menuHelp = NULL;
+ miFileDir = NULL;
+ miFileOptions = NULL;
+ miFileRun = NULL;
+ miFileExit = NULL;
+ miHelpContents = NULL;
+ miHelpAbout = NULL;
+ verticalSizer = NULL;
+ contentsSizer = NULL;
+ tLogmessages = NULL;
+ tStatus = NULL;
+ lDirectory = NULL;
+ tDirectory = NULL;
+ dkctGUIContentsPanel = new wxPanel(this);
+ if(!(dkctGUIContentsPanel)) {
+ goto dkctGUILayoutFinished;
+ }
+#if wxUSE_MENUS
+ mbMain = new wxMenuBar(
+ );
+ if(!(mbMain)) {
+ goto dkctGUILayoutFinished;
+ }
+ menuFile = new wxMenu(
+ );
+ if(!(menuFile)) {
+ goto dkctGUILayoutFinished;
+ }
+ miFileDir = menuFile->Append(
+ DkWxTrace_ChooseDirectory,
+ sTexts[12],
+ sTexts[13]
+ );
+ if(!(miFileDir)) {
+ goto dkctGUILayoutFinished;
+ }
+ miFileOptions = menuFile->Append(
+ DkWxTrace_SetOptions,
+ sTexts[14],
+ sTexts[15]
+ );
+ if(!(miFileOptions)) {
+ goto dkctGUILayoutFinished;
+ }
+ miFileRun = menuFile->Append(
+ DkWxTrace_Run,
+ sTexts[64],
+ sTexts[65]
+ );
+ if(!(miFileRun)) {
+ goto dkctGUILayoutFinished;
+ }
+ miFileExit = menuFile->Append(
+ DkWxTrace_Quit,
+ sTexts[5],
+ sTexts[7]
+ );
+ if(!(miFileExit)) {
+ goto dkctGUILayoutFinished;
+ }
+ mbMain->Append(menuFile, sTexts[3]);
+ menuHelp = new wxMenu(
+ );
+ if(!(menuHelp)) {
+ goto dkctGUILayoutFinished;
+ }
+ miHelpContents = menuHelp->Append(
+ DkWxTrace_Help_Contents,
+ sTexts[9],
+ sTexts[10]
+ );
+ if(!(miHelpContents)) {
+ goto dkctGUILayoutFinished;
+ }
+ miHelpAbout = menuHelp->Append(
+ DkWxTrace_About,
+ sTexts[6],
+ sTexts[8]
+ );
+ if(!(miHelpAbout)) {
+ goto dkctGUILayoutFinished;
+ }
+ mbMain->Append(menuHelp, sTexts[4]);
+ SetMenuBar(mbMain);
+#endif
+#if wxUSE_TOOLBAR
+ tbMain = new wxToolBar(
+ this,
+ wxID_ANY
+ );
+ if(!(tbMain)) {
+ goto dkctGUILayoutFinished;
+ }
+ bDir = tbMain->AddTool(
+ DkWxTrace_ChooseDirectory,
+ sTexts[17],
+ xpm_choose_dir,
+ wxNullBitmap,
+ wxITEM_NORMAL,
+ sTexts[21]
+ );
+ if(!(bDir)) {
+ goto dkctGUILayoutFinished;
+ }
+ bOptions = tbMain->AddTool(
+ DkWxTrace_SetOptions,
+ sTexts[18],
+ xpm_set_options,
+ wxNullBitmap,
+ wxITEM_NORMAL,
+ sTexts[22]
+ );
+ if(!(bOptions)) {
+ goto dkctGUILayoutFinished;
+ }
+ bRun = tbMain->AddTool(
+ DkWxTrace_Run,
+ sTexts[19],
+ xpm_run_conversion,
+ wxNullBitmap,
+ wxITEM_NORMAL,
+ sTexts[23]
+ );
+ if(!(bRun)) {
+ goto dkctGUILayoutFinished;
+ }
+ bExit = tbMain->AddTool(
+ DkWxTrace_Quit,
+ sTexts[20],
+ xpm_exit_program,
+ wxNullBitmap,
+ wxITEM_NORMAL,
+ sTexts[24]
+ );
+ if(!(bExit)) {
+ goto dkctGUILayoutFinished;
+ }
+ tbMain->Realize();
+ SetToolBar(tbMain);
+#endif
+ mainSizer = new wxBoxSizer(
+ wxHORIZONTAL
+ );
+ if(!(mainSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ mainSizer->Add(10, 10, 0);
+ verticalSizer = new wxBoxSizer(
+ wxVERTICAL
+ );
+ if(!(verticalSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ verticalSizer->Add(10, 10, 0);
+ contentsSizer = new wxGridBagSizer(
+ 5, 5
+ );
+ if(!(contentsSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ lDirectory = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[11]
+ );
+ if(!(lDirectory)) {
+ goto dkctGUILayoutFinished;
+ }
+ contentsSizer->Add(
+ lDirectory,
+ wxGBPosition(0, 0),
+ wxGBSpan(1, 1),
+ wxALIGN_RIGHT
+ );
+ tDirectory = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ ((sDirectory) ? sDirectory : sTexts[25])
+ );
+ if(!(tDirectory)) {
+ goto dkctGUILayoutFinished;
+ }
+ contentsSizer->Add(
+ tDirectory,
+ wxGBPosition(0, 1),
+ wxGBSpan(1, 1)
+ );
+ verticalSizer->Add(
+ contentsSizer,
+ 0,
+ wxALIGN_LEFT
+ );
+ verticalSizer->Add(10, 10, 0);
+ tLogmessages = new wxTextCtrl(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ wxEmptyString,
+ wxDefaultPosition,
+ wxSize(200, 30),
+ wxTE_MULTILINE|wxTE_READONLY|wxTE_NOHIDESEL|wxTE_LEFT|wxTE_DONTWRAP
+ );
+ if(!(tLogmessages)) {
+ goto dkctGUILayoutFinished;
+ }
+ verticalSizer->Add(
+ tLogmessages,
+ 1,
+ wxALIGN_LEFT|wxALIGN_TOP|wxGROW
+ );
+ verticalSizer->Add(10, 10, 0);
+ tStatus = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[67]
+ );
+ if(!(tStatus)) {
+ goto dkctGUILayoutFinished;
+ }
+ verticalSizer->Add(
+ tStatus,
+ 0,
+ wxALIGN_LEFT
+ );
+ verticalSizer->Add(10, 10, 0);
+ mainSizer->Add(
+ verticalSizer,
+ 1,
+ wxGROW
+ );
+ mainSizer->Add(10, 10, 0);
+ dkctGUIContentsPanel->SetSizer(mainSizer);
+ SetIcon(dkicon_bitmap);
+ dkctGUILayoutOK = true;
+ dkctGUILayoutFinished:
+#if wxUSE_STATUSBAR
+ if(dkctGUILayoutOK) {
+ CreateStatusBar(1);
+ SetStatusText(sTexts[67]);
+ }
+#endif
+ if(dkctGUILayoutOK) {
+ mainSizer->Fit(this);
+ mainSizer->SetSizeHints(this);
+ }
+
+#line 544 "DkWxTraceFrame.wxc"
+
+
+#line 545 "DkWxTraceFrame.wxc"
+ pComm = new DkWxCommunicator(
+ applicationHelper->getWxEncoding(),
+ applicationHelper->getDkEncoding()
+ );
+ cBlack = new wxColour(0x00, 0x00, 0x00);
+ cGreen = new wxColour(0x00, 0x7F, 0x00);
+ cRed = new wxColour(0x7f, 0x00, 0x00);
+ if(argc > 1) {
+#if VERSION_BEFORE_20150821
+ int res = -1;
+#endif
+ long l = 0L;
+ wxString cmdfn;
+ wxCmdLineParser parser(wxdkctframe_cmd_line_desc, argc, argv);
+ bSaveSettings = false; bSaveDirectory = false;
+ {
+ wxLogNull log;
+#if VERSION_BEFORE_20150821
+ res = parser.Parse(false);
+#endif
+ parser.Parse(false);
+ }
+ if(parser.Found(wxT("r"))) {
+ if(pComm) {
+ pComm->autostartEnable(true);
+ bGuiActive = false;
+ bAutoStartRequested = true;
+ }
+ }
+ if(parser.Found(wxT("R"))) {
+ options.deb = 0;
+ options.deben = 1;
+ options.lnn = 0;
+ options.mak = 0;
+ options.sty = 0;
+ options.bw = 75;
+ options.tkw = 0;
+ options.ts = 0;
+ options.win = 0;
+ options.tip = 0;
+ }
+ if(parser.Found(wxT("d"))) {
+ options.deb = 1; options.deben = 1;
+ }
+ if(parser.Found(wxT("s"))) {
+ options.deb = 2; options.deben = 1;
+ }
+ if(parser.Found(wxT("l"))) {
+ options.lnn = 1;
+ }
+ if(parser.Found(wxT("m"))) {
+ options.mak = 1;
+ }
+ if(parser.Found(wxT("b"), &l)) {
+ if((l > 20L) && (l < 128L)) {
+ options.bw = (int)l;
+ }
+ }
+ if(options.deb) {
+ if(parser.Found(wxT("t"))) {
+ options.ts = 1;
+ }
+ if(parser.Found(wxT("k"))) {
+ options.tkw = 1;
+ }
+ if(parser.Found(wxT("w"))) {
+ options.win = 1;
+ }
+ }
+ if(parser.GetParamCount() > 0) {
+
+#line 615 "DkWxTraceFrame.wxc"
+ wxChar const *nd;
+ cmdfn = parser.GetParam(0);
+ wxFileName fn(cmdfn);
+ fn.Normalize(
+ wxPATH_NORM_LONG
+ | wxPATH_NORM_DOTS
+ | wxPATH_NORM_TILDE
+ | wxPATH_NORM_ABSOLUTE
+ );
+ cmdfn = fn.GetFullPath();
+ if(wxFileName::DirExists(cmdfn)) {
+
+#line 626 "DkWxTraceFrame.wxc"
+ nd = cmdfn.c_str();
+ if(nd) {
+
+#line 628 "DkWxTraceFrame.wxc"
+ nd = dk3wxs_dup_app(nd, applicationHelper->getApp());
+ if(nd) {
+
+#line 630 "DkWxTraceFrame.wxc"
+ dk3_release(sDirectory);
+ sDirectory = nd;
+ if(tDirectory) {
+ tDirectory->SetLabel(sDirectory);
+ }
+ } else {
+
+#line 636 "DkWxTraceFrame.wxc"
+ pComm->autostartEnable(false);
+ bGuiActive = true;
+ if(bAutoStartRequested) {
+ tStatus->SetLabel(sTexts[71]);
+ if((cBlack) && (cRed)) { tStatus->SetForegroundColour(*cRed); }
+ bAutoStartRequested = false;
+ }
+ }
+ } else {
+
+#line 645 "DkWxTraceFrame.wxc"
+ pComm->autostartEnable(false);
+ bGuiActive = true;
+ if(bAutoStartRequested) {
+ tStatus->SetLabel(sTexts[71]);
+ if((cBlack) && (cRed)) { tStatus->SetForegroundColour(*cRed); }
+ bAutoStartRequested = false;
+ }
+ }
+ } else {
+
+#line 654 "DkWxTraceFrame.wxc"
+ pComm->autostartEnable(false);
+ bGuiActive = true;
+ if(bAutoStartRequested) {
+ tStatus->SetLabel(sTexts[71]);
+ if((cBlack) && (cRed)) { tStatus->SetForegroundColour(*cRed); }
+ bAutoStartRequested = false;
+ }
+ }
+ } else {
+ pComm->autostartEnable(false);
+ bGuiActive = true;
+ if(bAutoStartRequested) {
+ tStatus->SetLabel(sTexts[71]);
+ if((cBlack) && (cRed)) { tStatus->SetForegroundColour(*cRed); }
+ bAutoStartRequested = false;
+ }
+ }
+ }
+#if 0
+ restorePosition();
+#endif
+
+
+#line 676 "DkWxTraceFrame.wxc"
+}
+
+
+
+#line 680 "DkWxTraceFrame.wxc"
+
+
+
+DkWxTraceFrame::~DkWxTraceFrame()
+{
+ dk3_cpp_release(pComm);
+ dk3_cpp_release(cBlack);
+ dk3_cpp_release(cGreen);
+ dk3_cpp_release(cRed);
+}
+
+
+
+void DkWxTraceFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
+{
+ if(isGuiActive()) {
+ bCloseScheduled = true;
+ Close();
+ }
+}
+
+
+
+void DkWxTraceFrame::OnHelpContents(wxCommandEvent& WXUNUSED(event))
+{
+
+
+#line 706 "DkWxTraceFrame.wxc"
+ openHelp();
+
+
+#line 708 "DkWxTraceFrame.wxc"
+}
+
+
+
+void DkWxTraceFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
+{
+
+
+#line 715 "DkWxTraceFrame.wxc"
+ if(isGuiActive()) {
+ wxString sVersion(dkwxct_version);
+ sVersion.Append(dkwxct_versnumber);
+ sVersion.Append(dkwxct_versend);
+ sVersion.Append(sTexts[73]);
+ sVersion.Append(wxT("Copyright (c) 2013-2016 Dirk Krause"));
+ sVersion.Append(sTexts[73]);
+ sVersion.Append(sTexts[73]);
+ sVersion.Append(sTexts[74]);
+ sVersion.Append(wxT("DK tools, wxWidgets, libpng, libjpeg, libtiff, zlib."));
+ sVersion.Append(sTexts[73]);
+ sVersion.Append(sTexts[73]);
+ sVersion.Append(sTexts[75]);
+ sVersion.Append(wxT("http://dktools.sourceforge.net\n"));
+ sVersion.Append(wxT("http://www.wxwidgets.org\n"));
+ sVersion.Append(wxT("http://www.libpng.org/pub/png/libpng.html\n"));
+ sVersion.Append(wxT("http://www.ijg.org\n"));
+ sVersion.Append(wxT("http://www.remotesensing.org/libtiff\n"));
+ sVersion.Append(wxT("http://www.zlib.net\n"));
+ wxMessageBox(sVersion, sTexts[66]);
+ }
+
+
+#line 737 "DkWxTraceFrame.wxc"
+}
+
+
+
+void DkWxTraceFrame::OnChooseDirectory(wxCommandEvent& WXUNUSED(event))
+{
+ wxChar const *ptr;
+ wxChar const *np;
+
+
+#line 746 "DkWxTraceFrame.wxc"
+ if(isGuiActive()) {
+ wxDirDialog dd(
+ this,
+ sTexts[53],
+ ((sDirectory) ? sDirectory : wxEmptyString),
+ (wxDD_DIR_MUST_EXIST | wxDD_CHANGE_DIR)
+ );
+ pHelper->setRelatedPosition(this, &dd, &ddx, &ddy);
+ if(dd.ShowModal() == wxID_OK) {
+ wxString path = dd.GetPath();
+ ptr = path.c_str();
+ if(ptr) {
+ np = dk3wxs_dup_app(ptr, pHelper->getApp());
+ if(np) {
+ dk3_release(sDirectory);
+ sDirectory = np;
+ if(tDirectory) {
+ tDirectory->SetLabel(sDirectory);
+ Refresh();
+ Update();
+ }
+ }
+ }
+ }
+ dd.GetPosition(&ddx, &ddy);
+ }
+
+
+#line 773 "DkWxTraceFrame.wxc"
+}
+
+
+
+void DkWxTraceFrame::OnSetOptions(wxCommandEvent& WXUNUSED(event))
+{
+
+
+#line 780 "DkWxTraceFrame.wxc"
+ if(isGuiActive()) {
+ DkWxTraceOptionsDialog dlg(
+ (DkWxTraceFrame *)this, sTexts[30], sTexts, &options
+ );
+ dlg.dataIn();
+ pHelper->setRelatedPosition(this, &dlg, &odx, &ody);
+ dlg.ShowModal();
+ dlg.GetPosition(&odx, &ody);
+ }
+
+
+#line 790 "DkWxTraceFrame.wxc"
+}
+
+
+
+void DkWxTraceFrame::runConversion()
+{
+ DkWxProgressDialog *pd = NULL;
+ DkWxTraceThread *pt = NULL;
+#if VERSION_BEFORE_20150821
+ int ok = 0;
+#endif
+
+
+#line 802 "DkWxTraceFrame.wxc"
+ /* SetStatusText(sTexts[67]); */
+ tStatus->SetLabel(sTexts[67]);
+ if(cBlack) { tStatus->SetForegroundColour(*cBlack); }
+ if(pComm) {
+ pComm->prepareRun();
+ pd = new DkWxProgressDialog(
+ (DkWxFrame *)this,
+ pComm,
+ tLogmessages,
+ sTexts[48], /* title */
+ sTexts[49], /* file name */
+ sTexts[50], /* button text */
+ sTexts[51], /* button tool tip */
+ sTexts[52] /* wait text */
+ );
+ if(pd) {
+ pt = new DkWxTraceThread(
+ pComm,
+ sTexts,
+ msg,
+ sDirectory,
+ pHelper,
+ &options,
+ pHelper->getWxEncoding(),
+ pHelper->getDkEncoding()
+ );
+ if(pt) {
+ if(pt->Create() == wxTHREAD_NO_ERROR) {
+ pt->SetPriority(WXTHREAD_DEFAULT_PRIORITY);
+#if 0
+ if(iRunState == DK3_WX_RUN_STATE_START) {
+ iRunState = DK3_WX_RUN_STATE_RUNNING;
+ }
+#endif
+ pt->Run();
+ pd->chooseModalPosition();
+ pd->ShowModal();
+#if VERSION_BEFORE_20150821
+ ok = 1;
+#endif
+ if(pComm->getLogLevel() <= DK3_LL_WARNING) {
+ bGuiActive = true;
+ }
+ } else {
+ delete(pt);
+ /* ##### ERROR: Failed to create new thread! */
+ }
+ } else {
+ /* ##### ERROR: Failed to construct new thread! */
+ }
+ pd->Destroy();
+ } else {
+ /* ##### ERROR: Failed to construct new progress dialog! */
+ }
+ if(tLogmessages) {
+ pComm->getText(tLogmessages);
+ }
+ if(pComm->getLogLevel() > DK3_LL_WARNING) {
+ /* SetStatusText(sTexts[68]); */
+ if(bAutoStartRequested) {
+ tStatus->SetLabel(sTexts[72]);
+ } else {
+ tStatus->SetLabel(sTexts[68]);
+ }
+ if((cBlack) && (cGreen)) { tStatus->SetForegroundColour(*cGreen); }
+ } else {
+ if(pComm->getLogLevel() < DK3_LL_WARNING) {
+ /* SetStatusText(sTexts[70]); */
+ tStatus->SetLabel(sTexts[70]);
+ if((cBlack) && (cRed)) { tStatus->SetForegroundColour(*cRed); }
+ } else {
+ /* SetStatusText(sTexts[69]); */
+ tStatus->SetLabel(sTexts[69]);
+ if((cBlack) && (cRed)) { tStatus->SetForegroundColour(*cRed); }
+ }
+ }
+ Refresh();
+ Update();
+ }
+
+#line 881 "DkWxTraceFrame.wxc"
+}
+
+
+
+void DkWxTraceFrame::OnRunConversion(wxCommandEvent& WXUNUSED(event))
+{
+ if(isGuiActive()) {
+ runConversion();
+ }
+}
+
+
+
+bool DkWxTraceFrame::canClose(bool isLast)
+{
+ bool back = true;
+ int values_to_save[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0
+ };
+ if(isLast) {
+ if(bSaveSettings) {
+ values_to_save[0] = options.mak;
+ values_to_save[1] = options.lnn;
+ values_to_save[2] = options.deb;
+ values_to_save[3] = options.ts;
+ values_to_save[4] = options.tkw;
+ values_to_save[5] = options.win;
+ values_to_save[6] = (('\0' != options.spls) ? 1 : 0);
+ values_to_save[7] = findSplintCharacterIndex(options.spls);
+ pHelper->saveMultipleInts(dkwxct_settings_names, values_to_save);
+ }
+ if(bSaveDirectory) {
+ if(sDirectory) {
+ pHelper->saveString(dkwxct_string_settings_names[0], sDirectory);
+ }
+ }
+ }
+ dk3_cpp_release(pComm);
+ dk3_release(sDirectory);
+ return back;
+}
+
+
+
+void DkWxTraceFrame::getData()
+{
+ int values_to_save[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0
+ };
+ pHelper->retrieveMultipleInts(dkwxct_settings_names, values_to_save);
+ options.mak = values_to_save[0];
+ options.lnn = values_to_save[1];
+ options.deb = values_to_save[2];
+ options.ts = values_to_save[3];
+ options.tkw = values_to_save[4];
+ options.win = values_to_save[5];
+ options.spls = '\0';
+ if ((values_to_save[6])
+ && ((0 <= values_to_save[7]) && (18 > values_to_save[7])))
+ {
+ options.spls = (char)((sTexts[76 + values_to_save[7]])[0]);
+ }
+ sDirectory = pHelper->retrieveString(dkwxct_string_settings_names[0]);
+}
+
+
+void
+DkWxTraceFrame::OnIdle(wxIdleEvent & event)
+{
+ dk3_time_t ct;
+
+
+#line 952 "DkWxTraceFrame.wxc"
+ if(!bCloseScheduled) {
+ if(pComm) {
+ if(pComm->autostartCanRun()) {
+
+#line 955 "DkWxTraceFrame.wxc"
+ runConversion();
+ } else {
+ if(pComm->autostartIsFinished()) {
+
+#line 958 "DkWxTraceFrame.wxc"
+ if(!(timeClose)) {
+ if(pComm->getLogLevel() > DK3_LL_WARNING) {
+ dk3sf_time(&timeClose);
+ event.RequestMore();
+ tStatus->SetLabel(sTexts[72]);
+ if((cGreen) && (cBlack)) {
+ tStatus->SetForegroundColour(*cGreen);
+ }
+ Refresh();
+ Update();
+ }
+ }
+ }
+ }
+ }
+ if(timeClose) {
+ dk3sf_time(&ct);
+ if(ct > (timeClose + (dk3_time_t)1UL)) {
+ timeClose = (dk3_time_t)0UL;
+ bCloseScheduled = true;
+ Show(false);
+ Close();
+ } else {
+ event.RequestMore();
+ }
+ }
+ }
+
+
+#line 986 "DkWxTraceFrame.wxc"
+ event.Skip();
+}
+
+
+
+bool
+DkWxTraceFrame::isGuiActive()
+{
+ bool back = false;
+ if(!(bCloseScheduled)) {
+ back = bGuiActive;
+ }
+ return back;
+}
+
+
+
+int
+DkWxTraceFrame::findSplintCharacterIndex(char c)
+{
+ int back = 0;
+ int i; /* Traverse 0 to 17 */
+ bool found = false; /* Flag: Character was found */
+ for (i = 0; ((i < 18) && (!(found))); i++) {
+ if (c == (sTexts[76 + i])[0]) {
+ found = true;
+ back = i;
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/DkWxTraceFrame.h b/support/dktools/DkWxTraceFrame.h
new file mode 100644
index 0000000000..0ca825b627
--- /dev/null
+++ b/support/dktools/DkWxTraceFrame.h
@@ -0,0 +1,345 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxTraceFrame.wxc
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxTraceFrame.h Header file for the DkWxTraceFrame module.
+*/
+
+#ifndef DKWXTRACEFRAME_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DKWXTRACEFRAME_H_INCLUDED 1
+
+
+#line 139 "DkWxTraceFrame.wxc"
+
+#include "dkct.h"
+
+
+
+#line 144 "DkWxTraceFrame.wxc"
+
+/** Top level frame of the dkwxtrace program.
+*/
+class DkWxTraceFrame : public DkWxFrame
+{
+
+ private:
+
+ /** Event table.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ /** Localized texts.
+ */
+ wxChar const * const *sTexts;
+
+ /** Localized dkChar texts.
+ */
+ dkChar const * const *msg;
+
+ /** Conversion options.
+ */
+ DKCT_OPTION_SET options;
+
+ /** Communication object for main thread and worker thread.
+ */
+ DkWxCommunicator *pComm;
+
+ /** Current directory.
+ */
+ wxChar const *sDirectory;
+
+ /** Color: Black.
+ */
+ wxColour *cBlack;
+
+ /** Color: Dark green.
+ */
+ wxColour *cGreen;
+
+ /** Color: Dark red.
+ */
+ wxColour *cRed;
+
+ /** Timestamp to close the application.
+ */
+ dk3_time_t timeClose;
+
+ /** Directory dialog x position.
+ */
+ int ddx;
+
+ /** Directory dialog y position.
+ */
+ int ddy;
+
+ /** Options dialog x position.
+ */
+ int odx;
+
+ /** Options dialog y position.
+ */
+ int ody;
+
+ /** Must save the current settings.
+ */
+ bool bSaveSettings;
+
+ /** Must save the current directory.
+ */
+ bool bSaveDirectory;
+
+ /** Timestamp for closing the application is scheduled.
+ */
+ bool bCloseScheduled;
+
+ /** GUI elements are active, not automatic closing.
+ */
+ bool bGuiActive;
+
+ /** The run was started automatically.
+ */
+ bool bAutoStartRequested;
+
+ /** Flag: GUI ok.
+ */
+ bool dkctGUILayoutOK;
+
+ /** Contents panel.
+ */
+ wxPanel *dkctGUIContentsPanel;
+
+ /** GUI element mbMain.
+ */
+#line 49 "DkWxTraceFrame.wxc"
+ wxMenuBar *mbMain;
+
+ /** GUI element mainSizer.
+ */
+#line 95 "DkWxTraceFrame.wxc"
+ wxBoxSizer *mainSizer;
+
+ /** GUI element tbMain.
+ */
+#line 19 "DkWxTraceFrame.wxc"
+ wxToolBar *tbMain;
+
+ /** GUI element bDir.
+ */
+#line 25 "DkWxTraceFrame.wxc"
+ wxToolBarToolBase *bDir;
+
+ /** GUI element bOptions.
+ */
+#line 31 "DkWxTraceFrame.wxc"
+ wxToolBarToolBase *bOptions;
+
+ /** GUI element bRun.
+ */
+#line 37 "DkWxTraceFrame.wxc"
+ wxToolBarToolBase *bRun;
+
+ /** GUI element bExit.
+ */
+#line 43 "DkWxTraceFrame.wxc"
+ wxToolBarToolBase *bExit;
+
+ /** GUI element menuFile.
+ */
+#line 53 "DkWxTraceFrame.wxc"
+ wxMenu *menuFile;
+
+ /** GUI element menuHelp.
+ */
+#line 60 "DkWxTraceFrame.wxc"
+ wxMenu *menuHelp;
+
+ /** GUI element miFileDir.
+ */
+#line 65 "DkWxTraceFrame.wxc"
+ wxMenuItem *miFileDir;
+
+ /** GUI element miFileOptions.
+ */
+#line 70 "DkWxTraceFrame.wxc"
+ wxMenuItem *miFileOptions;
+
+ /** GUI element miFileRun.
+ */
+#line 75 "DkWxTraceFrame.wxc"
+ wxMenuItem *miFileRun;
+
+ /** GUI element miFileExit.
+ */
+#line 80 "DkWxTraceFrame.wxc"
+ wxMenuItem *miFileExit;
+
+ /** GUI element miHelpContents.
+ */
+#line 85 "DkWxTraceFrame.wxc"
+ wxMenuItem *miHelpContents;
+
+ /** GUI element miHelpAbout.
+ */
+#line 90 "DkWxTraceFrame.wxc"
+ wxMenuItem *miHelpAbout;
+
+ /** GUI element verticalSizer.
+ */
+#line 101 "DkWxTraceFrame.wxc"
+ wxBoxSizer *verticalSizer;
+
+ /** GUI element contentsSizer.
+ */
+#line 113 "DkWxTraceFrame.wxc"
+ wxGridBagSizer *contentsSizer;
+
+ /** GUI element tLogmessages.
+ */
+#line 128 "DkWxTraceFrame.wxc"
+ wxTextCtrl *tLogmessages;
+
+ /** GUI element tStatus.
+ */
+#line 134 "DkWxTraceFrame.wxc"
+ wxStaticText *tStatus;
+
+ /** GUI element lDirectory.
+ */
+#line 122 "DkWxTraceFrame.wxc"
+ wxStaticText *lDirectory;
+
+ /** GUI element tDirectory.
+ */
+#line 125 "DkWxTraceFrame.wxc"
+ wxStaticText *tDirectory;
+
+
+#line 231 "DkWxTraceFrame.wxc"
+
+ public:
+
+ /** Constructor.
+ @param applicationName Application name.
+ @param messageTexts Localized texts.
+ @param ms Message texts as dkChar strings.
+ @param applicationHelper Application helper.
+ @param wxid Window ID.
+ @param hc Help controller.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ */
+ DkWxTraceFrame(
+ wxChar const *applicationName,
+ wxChar const * const *messageTexts,
+ dkChar const * const *ms,
+ DkWxAppHelper *applicationHelper,
+ int wxid,
+ DkWxHelpController *hc,
+ int argc,
+ wxChar **argv
+ );
+
+
+
+ /** Destructor.
+ */
+ ~DkWxTraceFrame();
+
+ /** Find index for splint special character.
+ @param c Character to find index for.
+ @return Index in range 0 to 17.
+ */
+ int findSplintCharacterIndex(char c);
+
+
+ /** Check whether we can close the window.
+ @param isLast Flag: Last top level window.
+ */
+ bool canClose(bool isLast);
+
+ /** Menu event handler for File / Quit.
+ @param event Event to process.
+ */
+ void OnQuit(wxCommandEvent& event);
+
+ /** Menu event handler for Help / About.
+ */
+ void OnAbout(wxCommandEvent& event);
+
+ /** Menu event handler for Help / Contents.
+ */
+ void OnHelpContents(wxCommandEvent& event);
+
+ /** Menu event handler for File / Directory.
+ */
+ void OnChooseDirectory(wxCommandEvent& event);
+
+ /** Menu event handler for File / Options.
+ */
+ void OnSetOptions(wxCommandEvent& event);
+
+ /** Menu event handler for File / Run.
+ */
+ void OnRunConversion(wxCommandEvent& event);
+
+ /** Handler for idle events.
+ */
+ void OnIdle(wxIdleEvent & event);
+
+ /** Run a conversion.
+ */
+ void runConversion();
+
+ /** Check whether GUI elements are active.
+ @return True if GUI elements can be used, false otherwise
+ (autostart job running).
+ */
+ bool isGuiActive();
+
+ protected:
+
+ /** Retrieve stored preferences.
+ */
+ void getData(void);
+
+};
+
+
+#line 321 "DkWxTraceFrame.wxc"
+
+
+#endif
diff --git a/support/dktools/DkWxTraceFrame.wxc b/support/dktools/DkWxTraceFrame.wxc
new file mode 100644
index 0000000000..1fbc9d2561
--- /dev/null
+++ b/support/dktools/DkWxTraceFrame.wxc
@@ -0,0 +1,1017 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% wx-gui
+
+# . align = left top
+type = frame
+menu bar = mbMain
+contents = mainSizer
+tool bar = tbMain
+icon = dkicon_bitmap
+status bar = 1 sTexts[67]
+
+[wxToolBar tbMain]
+contents = bDir
+contents = bOptions
+contents = bRun
+contents = bExit
+
+[wxToolBarToolBase bDir]
+text = sTexts[17]
+bitmap = xpm_choose_dir
+id = DkWxTrace_ChooseDirectory
+tip = sTexts[21]
+
+[wxToolBarToolBase bOptions]
+text = sTexts[18]
+bitmap = xpm_set_options
+id = DkWxTrace_SetOptions
+tip = sTexts[22]
+
+[wxToolBarToolBase bRun]
+text = sTexts[19]
+bitmap = xpm_run_conversion
+id = DkWxTrace_Run
+tip = sTexts[23]
+
+[wxToolBarToolBase bExit]
+text = sTexts[20]
+bitmap = xpm_exit_program
+id = DkWxTrace_Quit
+tip = sTexts[24]
+
+[wxMenuBar mbMain]
+contents = menuFile
+contents = menuHelp
+
+[wxMenu menuFile]
+contents = miFileDir
+contents = miFileOptions
+contents = miFileRun
+contents = miFileExit
+text = sTexts[3]
+
+[wxMenu menuHelp]
+contents = miHelpContents
+contents = miHelpAbout
+text = sTexts[4]
+
+[wxMenuItem miFileDir]
+id = DkWxTrace_ChooseDirectory
+text = sTexts[12]
+tip = sTexts[13]
+
+[wxMenuItem miFileOptions]
+id = DkWxTrace_SetOptions
+text = sTexts[14]
+tip = sTexts[15]
+
+[wxMenuItem miFileRun]
+id = DkWxTrace_Run
+text = sTexts[64]
+tip = sTexts[65]
+
+[wxMenuItem miFileExit]
+id = DkWxTrace_Quit
+text = sTexts[5]
+tip = sTexts[7]
+
+[wxMenuItem miHelpContents]
+id = DkWxTrace_Help_Contents
+text = sTexts[9]
+tip = sTexts[10]
+
+[wxMenuItem miHelpAbout]
+id = DkWxTrace_About
+text = sTexts[6]
+tip = sTexts[8]
+
+[wxBoxSizer mainSizer]
+direction = horizontal
+contents = $space(10)
+contents = verticalSizer
+contents = $space(10)
+
+[wxBoxSizer verticalSizer]
+direction = vertical
+grow = yes
+proportion = 1
+contents = $space(10)
+contents = contentsSizer left
+contents = $space(10)
+contents = tLogmessages left top
+contents = $space(10)
+contents = tStatus left
+contents = $space(10)
+
+[wxGridBagSizer contentsSizer]
+grid = 5 5
+contents = lDirectory 0 0 1 1 right
+contents = tDirectory . 1 1 1
+# contents = lLines +1 0 1 1 right
+# contents = tLines . 1 1 1
+# contents = lDebug +1 0 1 1 right
+# contents = tDebug . 1 1 1
+
+[wxStaticText lDirectory]
+text = sTexts[11]
+
+[wxStaticText tDirectory]
+text = ((sDirectory) ? sDirectory : sTexts[25])
+
+[wxTextCtrl tLogmessages]
+grow = yes
+proportion = 1
+size = 200 30
+text style = readonly multiline left no-wrap selection
+
+[wxStaticText tStatus]
+text = sTexts[67]
+
+
+%% header start
+
+#include "dkct.h"
+
+
+%% class start
+
+/** Top level frame of the dkwxtrace program.
+*/
+class DkWxTraceFrame : public DkWxFrame
+{
+
+ private:
+
+ /** Event table.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ /** Localized texts.
+ */
+ wxChar const * const *sTexts;
+
+ /** Localized dkChar texts.
+ */
+ dkChar const * const *msg;
+
+ /** Conversion options.
+ */
+ DKCT_OPTION_SET options;
+
+ /** Communication object for main thread and worker thread.
+ */
+ DkWxCommunicator *pComm;
+
+ /** Current directory.
+ */
+ wxChar const *sDirectory;
+
+ /** Color: Black.
+ */
+ wxColour *cBlack;
+
+ /** Color: Dark green.
+ */
+ wxColour *cGreen;
+
+ /** Color: Dark red.
+ */
+ wxColour *cRed;
+
+ /** Timestamp to close the application.
+ */
+ dk3_time_t timeClose;
+
+ /** Directory dialog x position.
+ */
+ int ddx;
+
+ /** Directory dialog y position.
+ */
+ int ddy;
+
+ /** Options dialog x position.
+ */
+ int odx;
+
+ /** Options dialog y position.
+ */
+ int ody;
+
+ /** Must save the current settings.
+ */
+ bool bSaveSettings;
+
+ /** Must save the current directory.
+ */
+ bool bSaveDirectory;
+
+ /** Timestamp for closing the application is scheduled.
+ */
+ bool bCloseScheduled;
+
+ /** GUI elements are active, not automatic closing.
+ */
+ bool bGuiActive;
+
+ /** The run was started automatically.
+ */
+ bool bAutoStartRequested;
+
+%% class end
+
+ public:
+
+ /** Constructor.
+ @param applicationName Application name.
+ @param messageTexts Localized texts.
+ @param ms Message texts as dkChar strings.
+ @param applicationHelper Application helper.
+ @param wxid Window ID.
+ @param hc Help controller.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ */
+ DkWxTraceFrame(
+ wxChar const *applicationName,
+ wxChar const * const *messageTexts,
+ dkChar const * const *ms,
+ DkWxAppHelper *applicationHelper,
+ int wxid,
+ DkWxHelpController *hc,
+ int argc,
+ wxChar **argv
+ );
+
+
+
+ /** Destructor.
+ */
+ ~DkWxTraceFrame();
+
+ /** Find index for splint special character.
+ @param c Character to find index for.
+ @return Index in range 0 to 17.
+ */
+ int findSplintCharacterIndex(char c);
+
+
+ /** Check whether we can close the window.
+ @param isLast Flag: Last top level window.
+ */
+ bool canClose(bool isLast);
+
+ /** Menu event handler for File / Quit.
+ @param event Event to process.
+ */
+ void OnQuit(wxCommandEvent& event);
+
+ /** Menu event handler for Help / About.
+ */
+ void OnAbout(wxCommandEvent& event);
+
+ /** Menu event handler for Help / Contents.
+ */
+ void OnHelpContents(wxCommandEvent& event);
+
+ /** Menu event handler for File / Directory.
+ */
+ void OnChooseDirectory(wxCommandEvent& event);
+
+ /** Menu event handler for File / Options.
+ */
+ void OnSetOptions(wxCommandEvent& event);
+
+ /** Menu event handler for File / Run.
+ */
+ void OnRunConversion(wxCommandEvent& event);
+
+ /** Handler for idle events.
+ */
+ void OnIdle(wxIdleEvent & event);
+
+ /** Run a conversion.
+ */
+ void runConversion();
+
+ /** Check whether GUI elements are active.
+ @return True if GUI elements can be used, false otherwise
+ (autostart job running).
+ */
+ bool isGuiActive();
+
+ protected:
+
+ /** Retrieve stored preferences.
+ */
+ void getData(void);
+
+};
+
+%% header end
+
+%% module start
+
+
+
+#include "dkwxtrace.h"
+#include "dk4verswx.h"
+
+
+
+/*
+ Icons and bitmaps
+*/
+#include "dkicon.xpm"
+#include "choose-dir.xpm"
+#include "exit-program.xpm"
+#include "run-conversion.xpm"
+#include "set-options.xpm"
+
+$!trace-include
+
+
+/** Version for the about dialog (program name).
+*/
+static wxChar const dkwxct_version[] = {
+ wxT("wxdkct (part of dktools-")
+};
+
+/** Version number for the about dialog (version number).
+*/
+static wxChar const dkwxct_versnumber[] = {
+ DKT_VERSION_WX
+};
+
+/** Version number for the about dialog (end).
+*/
+static wxChar const dkwxct_versend[] = {
+ wxT(")")
+};
+
+static wxChar const * const dkwxct_settings_names[] = {
+$!string-table macro=wxT
+#
+# 0: Make mode
+#
+wxdkct.make
+#
+# 1: Show line numbers
+#
+wxdkct.line-numbers
+#
+# 2: Debug (0=no 1=file 2=stdout)
+#
+wxdkct.debug
+#
+# 3: Include timestamp
+#
+wxdkct.debug.timestamp
+#
+# 4: Use trace keyword
+#
+wxdkct.debug.keyword
+#
+# 5: Wide character support.
+#
+wxdkct.debug.wide
+#
+# 6: Use splint
+#
+wxdkct.splint.use
+#
+# 7: Current string index
+#
+wxdkct.splint.selected
+$!end
+};
+
+
+
+static wxChar const * dkwxct_string_settings_names[] = {
+$!string-table macro=wxT
+#
+# 0: Current directory
+#
+wxdkct.directory
+$!end
+};
+
+
+/** Event table for the DkWxTraceFrame class.
+ */
+BEGIN_EVENT_TABLE(DkWxTraceFrame, wxFrame)
+ EVT_MENU(DkWxTrace_Quit, DkWxTraceFrame::OnQuit)
+ EVT_MENU(DkWxTrace_Help_Contents, DkWxTraceFrame::OnHelpContents)
+ EVT_MENU(DkWxTrace_About, DkWxTraceFrame::OnAbout)
+ EVT_MENU(DkWxTrace_ChooseDirectory, DkWxTraceFrame::OnChooseDirectory)
+ EVT_MENU(DkWxTrace_SetOptions, DkWxTraceFrame::OnSetOptions)
+ EVT_MENU(DkWxTrace_Run, DkWxTraceFrame::OnRunConversion)
+ EVT_IDLE(DkWxTraceFrame::OnIdle)
+END_EVENT_TABLE()
+
+
+
+static const wxCmdLineEntryDesc wxdkctframe_cmd_line_desc[] = {
+ {
+ wxCMD_LINE_SWITCH,
+ wxT_2("r"),
+ wxT_2("run"),
+ wxT_2("Run conversion")
+ },
+ {
+ wxCMD_LINE_SWITCH,
+ wxT_2("R"),
+ wxT_2("reset"),
+ wxT_2("Reset all options")
+ },
+ {
+ wxCMD_LINE_SWITCH,
+ wxT_2("m"),
+ wxT_2("make"),
+ wxT_2("Run in make mode")
+ },
+ {
+ wxCMD_LINE_SWITCH,
+ wxT_2("l"),
+ wxT_2("line-numbers"),
+ wxT_2("Run conversion")
+ },
+ {
+ wxCMD_LINE_OPTION,
+ wxT_2("b"),
+ wxT_2("box"),
+ wxT_2("Box width"),
+ wxCMD_LINE_VAL_NUMBER
+ },
+
+ {
+ wxCMD_LINE_SWITCH,
+ wxT_2("d"),
+ wxT_2("debug"),
+ wxT_2("Create debug output")
+ },
+ {
+ wxCMD_LINE_SWITCH,
+ wxT_2("s"),
+ wxT_2("debug-stdout"),
+ wxT_2("Send debug output to standard output")
+ },
+ {
+ wxCMD_LINE_SWITCH,
+ wxT_2("t"),
+ wxT_2("time"),
+ wxT_2("Include timestamps in debug output")
+ },
+ {
+ wxCMD_LINE_SWITCH,
+ wxT_2("k"),
+ wxT_2("keyword"),
+ wxT_2("Include \"trace\" keyword in debug output")
+ },
+ {
+ wxCMD_LINE_SWITCH,
+ wxT_2("w"),
+ wxT_2("wide"),
+ wxT_2("Allow wide character debug output")
+ },
+ {
+ wxCMD_LINE_PARAM,
+ NULL,
+ NULL,
+ wxT_2("input file"),
+ wxCMD_LINE_VAL_STRING,
+ wxCMD_LINE_PARAM_OPTIONAL
+ },
+ { wxCMD_LINE_NONE }
+};
+
+
+%% constructor start
+DkWxTraceFrame::DkWxTraceFrame(
+ wxChar const *applicationName,
+ wxChar const * const *messageTexts,
+ dkChar const * const *m,
+ DkWxAppHelper *applicationHelper,
+ int wxid,
+ DkWxHelpController *hc,
+ int argc,
+ wxChar **argv
+) : DkWxFrame(applicationName, applicationHelper, hc, wxid)
+{
+ $? "+ constructor"
+ ddx = -1; ddy = -1;
+ odx = -1; ody = -1;
+ bAutoStartRequested = false;
+ pComm = NULL;
+ cBlack = NULL;
+ cGreen = NULL;
+ cRed = NULL;
+ sDirectory = NULL;
+ sTexts = messageTexts;
+ msg = m;
+ bSaveSettings = true;
+ bSaveDirectory = true;
+ bCloseScheduled = false;
+ bGuiActive = true;
+#if defined(__WXMSW__)
+ wxIcon dkicon_bitmap(wxT("aaaaa")); /* from resource file */
+#else
+ wxIcon dkicon_bitmap(xpm_dkicon); /* from included xpm */
+#endif
+ options.deb = 0;
+ options.deben = 1;
+ options.lnn = 0;
+ options.mak = 0;
+ options.sty = 0;
+ options.bw = 75;
+ options.tkw = 0;
+ options.ts = 0;
+ options.win = 0;
+ options.tip = 0;
+ timeClose = (dk3_time_t)0UL;
+ getData();
+%% constructor end
+ $? ". GUI finished"
+ pComm = new DkWxCommunicator(
+ applicationHelper->getWxEncoding(),
+ applicationHelper->getDkEncoding()
+ );
+ cBlack = new wxColour(0x00, 0x00, 0x00);
+ cGreen = new wxColour(0x00, 0x7F, 0x00);
+ cRed = new wxColour(0x7f, 0x00, 0x00);
+ if(argc > 1) {
+#if VERSION_BEFORE_20150821
+ int res = -1;
+#endif
+ long l = 0L;
+ wxString cmdfn;
+ wxCmdLineParser parser(wxdkctframe_cmd_line_desc, argc, argv);
+ bSaveSettings = false; bSaveDirectory = false;
+ {
+ wxLogNull log;
+#if VERSION_BEFORE_20150821
+ res = parser.Parse(false);
+#endif
+ parser.Parse(false);
+ }
+ if(parser.Found(wxT("r"))) {
+ if(pComm) {
+ pComm->autostartEnable(true);
+ bGuiActive = false;
+ bAutoStartRequested = true;
+ }
+ }
+ if(parser.Found(wxT("R"))) {
+ options.deb = 0;
+ options.deben = 1;
+ options.lnn = 0;
+ options.mak = 0;
+ options.sty = 0;
+ options.bw = 75;
+ options.tkw = 0;
+ options.ts = 0;
+ options.win = 0;
+ options.tip = 0;
+ }
+ if(parser.Found(wxT("d"))) {
+ options.deb = 1; options.deben = 1;
+ }
+ if(parser.Found(wxT("s"))) {
+ options.deb = 2; options.deben = 1;
+ }
+ if(parser.Found(wxT("l"))) {
+ options.lnn = 1;
+ }
+ if(parser.Found(wxT("m"))) {
+ options.mak = 1;
+ }
+ if(parser.Found(wxT("b"), &l)) {
+ if((l > 20L) && (l < 128L)) {
+ options.bw = (int)l;
+ }
+ }
+ if(options.deb) {
+ if(parser.Found(wxT("t"))) {
+ options.ts = 1;
+ }
+ if(parser.Found(wxT("k"))) {
+ options.tkw = 1;
+ }
+ if(parser.Found(wxT("w"))) {
+ options.win = 1;
+ }
+ }
+ if(parser.GetParamCount() > 0) { $? ". parameter"
+ wxChar const *nd;
+ cmdfn = parser.GetParam(0);
+ wxFileName fn(cmdfn);
+ fn.Normalize(
+ wxPATH_NORM_LONG
+ | wxPATH_NORM_DOTS
+ | wxPATH_NORM_TILDE
+ | wxPATH_NORM_ABSOLUTE
+ );
+ cmdfn = fn.GetFullPath();
+ if(wxFileName::DirExists(cmdfn)) { $? ". is directory"
+ nd = cmdfn.c_str();
+ if(nd) { $? ". text found"
+ nd = dk3wxs_dup_app(nd, applicationHelper->getApp());
+ if(nd) { $? ". allocation ok"
+ dk3_release(sDirectory);
+ sDirectory = nd;
+ if(tDirectory) {
+ tDirectory->SetLabel(sDirectory);
+ }
+ } else { $? "! allocation"
+ pComm->autostartEnable(false);
+ bGuiActive = true;
+ if(bAutoStartRequested) {
+ tStatus->SetLabel(sTexts[71]);
+ if((cBlack) && (cRed)) { tStatus->SetForegroundColour(*cRed); }
+ bAutoStartRequested = false;
+ }
+ }
+ } else { $? "! bug"
+ pComm->autostartEnable(false);
+ bGuiActive = true;
+ if(bAutoStartRequested) {
+ tStatus->SetLabel(sTexts[71]);
+ if((cBlack) && (cRed)) { tStatus->SetForegroundColour(*cRed); }
+ bAutoStartRequested = false;
+ }
+ }
+ } else { $? "! not a directory"
+ pComm->autostartEnable(false);
+ bGuiActive = true;
+ if(bAutoStartRequested) {
+ tStatus->SetLabel(sTexts[71]);
+ if((cBlack) && (cRed)) { tStatus->SetForegroundColour(*cRed); }
+ bAutoStartRequested = false;
+ }
+ }
+ } else {
+ pComm->autostartEnable(false);
+ bGuiActive = true;
+ if(bAutoStartRequested) {
+ tStatus->SetLabel(sTexts[71]);
+ if((cBlack) && (cRed)) { tStatus->SetForegroundColour(*cRed); }
+ bAutoStartRequested = false;
+ }
+ }
+ }
+#if 0
+ restorePosition();
+#endif
+ $? "- constructor"
+}
+
+
+%% module end
+
+
+
+DkWxTraceFrame::~DkWxTraceFrame()
+{
+ dk3_cpp_release(pComm);
+ dk3_cpp_release(cBlack);
+ dk3_cpp_release(cGreen);
+ dk3_cpp_release(cRed);
+}
+
+
+
+void DkWxTraceFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
+{
+ if(isGuiActive()) {
+ bCloseScheduled = true;
+ Close();
+ }
+}
+
+
+
+void DkWxTraceFrame::OnHelpContents(wxCommandEvent& WXUNUSED(event))
+{
+ $? "+ OnHelpContents"
+ openHelp();
+ $? "- OnHelpContents"
+}
+
+
+
+void DkWxTraceFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
+{
+ $? "+ OnAbout"
+ if(isGuiActive()) {
+ wxString sVersion(dkwxct_version);
+ sVersion.Append(dkwxct_versnumber);
+ sVersion.Append(dkwxct_versend);
+ sVersion.Append(sTexts[73]);
+ sVersion.Append(wxT("Copyright (c) 2013-2016 Dirk Krause"));
+ sVersion.Append(sTexts[73]);
+ sVersion.Append(sTexts[73]);
+ sVersion.Append(sTexts[74]);
+ sVersion.Append(wxT("DK tools, wxWidgets, libpng, libjpeg, libtiff, zlib."));
+ sVersion.Append(sTexts[73]);
+ sVersion.Append(sTexts[73]);
+ sVersion.Append(sTexts[75]);
+ sVersion.Append(wxT("http://dktools.sourceforge.net\n"));
+ sVersion.Append(wxT("http://www.wxwidgets.org\n"));
+ sVersion.Append(wxT("http://www.libpng.org/pub/png/libpng.html\n"));
+ sVersion.Append(wxT("http://www.ijg.org\n"));
+ sVersion.Append(wxT("http://www.remotesensing.org/libtiff\n"));
+ sVersion.Append(wxT("http://www.zlib.net\n"));
+ wxMessageBox(sVersion, sTexts[66]);
+ }
+ $? "- OnAbout"
+}
+
+
+
+void DkWxTraceFrame::OnChooseDirectory(wxCommandEvent& WXUNUSED(event))
+{
+ wxChar const *ptr;
+ wxChar const *np;
+ $? "+ OnChooseDirectory"
+ if(isGuiActive()) {
+ wxDirDialog dd(
+ this,
+ sTexts[53],
+ ((sDirectory) ? sDirectory : wxEmptyString),
+ (wxDD_DIR_MUST_EXIST | wxDD_CHANGE_DIR)
+ );
+ pHelper->setRelatedPosition(this, &dd, &ddx, &ddy);
+ if(dd.ShowModal() == wxID_OK) {
+ wxString path = dd.GetPath();
+ ptr = path.c_str();
+ if(ptr) {
+ np = dk3wxs_dup_app(ptr, pHelper->getApp());
+ if(np) {
+ dk3_release(sDirectory);
+ sDirectory = np;
+ if(tDirectory) {
+ tDirectory->SetLabel(sDirectory);
+ Refresh();
+ Update();
+ }
+ }
+ }
+ }
+ dd.GetPosition(&ddx, &ddy);
+ }
+ $? "- OnChooseDirectory"
+}
+
+
+
+void DkWxTraceFrame::OnSetOptions(wxCommandEvent& WXUNUSED(event))
+{
+ $? "+ OnSetOptions"
+ if(isGuiActive()) {
+ DkWxTraceOptionsDialog dlg(
+ (DkWxTraceFrame *)this, sTexts[30], sTexts, &options
+ );
+ dlg.dataIn();
+ pHelper->setRelatedPosition(this, &dlg, &odx, &ody);
+ dlg.ShowModal();
+ dlg.GetPosition(&odx, &ody);
+ }
+ $? "- OnSetOptions"
+}
+
+
+
+void DkWxTraceFrame::runConversion()
+{
+ DkWxProgressDialog *pd = NULL;
+ DkWxTraceThread *pt = NULL;
+#if VERSION_BEFORE_20150821
+ int ok = 0;
+#endif
+ $? "+ OnRunConversion"
+ /* SetStatusText(sTexts[67]); */
+ tStatus->SetLabel(sTexts[67]);
+ if(cBlack) { tStatus->SetForegroundColour(*cBlack); }
+ if(pComm) {
+ pComm->prepareRun();
+ pd = new DkWxProgressDialog(
+ (DkWxFrame *)this,
+ pComm,
+ tLogmessages,
+ sTexts[48], /* title */
+ sTexts[49], /* file name */
+ sTexts[50], /* button text */
+ sTexts[51], /* button tool tip */
+ sTexts[52] /* wait text */
+ );
+ if(pd) {
+ pt = new DkWxTraceThread(
+ pComm,
+ sTexts,
+ msg,
+ sDirectory,
+ pHelper,
+ &options,
+ pHelper->getWxEncoding(),
+ pHelper->getDkEncoding()
+ );
+ if(pt) {
+ if(pt->Create() == wxTHREAD_NO_ERROR) {
+ pt->SetPriority(WXTHREAD_DEFAULT_PRIORITY);
+#if 0
+ if(iRunState == DK3_WX_RUN_STATE_START) {
+ iRunState = DK3_WX_RUN_STATE_RUNNING;
+ }
+#endif
+ pt->Run();
+ pd->chooseModalPosition();
+ pd->ShowModal();
+#if VERSION_BEFORE_20150821
+ ok = 1;
+#endif
+ if(pComm->getLogLevel() <= DK3_LL_WARNING) {
+ bGuiActive = true;
+ }
+ } else {
+ delete(pt);
+ /* ##### ERROR: Failed to create new thread! */
+ }
+ } else {
+ /* ##### ERROR: Failed to construct new thread! */
+ }
+ pd->Destroy();
+ } else {
+ /* ##### ERROR: Failed to construct new progress dialog! */
+ }
+ if(tLogmessages) {
+ pComm->getText(tLogmessages);
+ }
+ if(pComm->getLogLevel() > DK3_LL_WARNING) {
+ /* SetStatusText(sTexts[68]); */
+ if(bAutoStartRequested) {
+ tStatus->SetLabel(sTexts[72]);
+ } else {
+ tStatus->SetLabel(sTexts[68]);
+ }
+ if((cBlack) && (cGreen)) { tStatus->SetForegroundColour(*cGreen); }
+ } else {
+ if(pComm->getLogLevel() < DK3_LL_WARNING) {
+ /* SetStatusText(sTexts[70]); */
+ tStatus->SetLabel(sTexts[70]);
+ if((cBlack) && (cRed)) { tStatus->SetForegroundColour(*cRed); }
+ } else {
+ /* SetStatusText(sTexts[69]); */
+ tStatus->SetLabel(sTexts[69]);
+ if((cBlack) && (cRed)) { tStatus->SetForegroundColour(*cRed); }
+ }
+ }
+ Refresh();
+ Update();
+ } $? "- OnRunConversion"
+}
+
+
+
+void DkWxTraceFrame::OnRunConversion(wxCommandEvent& WXUNUSED(event))
+{
+ if(isGuiActive()) {
+ runConversion();
+ }
+}
+
+
+
+bool DkWxTraceFrame::canClose(bool isLast)
+{
+ bool back = true;
+ int values_to_save[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0
+ };
+ if(isLast) {
+ if(bSaveSettings) {
+ values_to_save[0] = options.mak;
+ values_to_save[1] = options.lnn;
+ values_to_save[2] = options.deb;
+ values_to_save[3] = options.ts;
+ values_to_save[4] = options.tkw;
+ values_to_save[5] = options.win;
+ values_to_save[6] = (('\0' != options.spls) ? 1 : 0);
+ values_to_save[7] = findSplintCharacterIndex(options.spls);
+ pHelper->saveMultipleInts(dkwxct_settings_names, values_to_save);
+ }
+ if(bSaveDirectory) {
+ if(sDirectory) {
+ pHelper->saveString(dkwxct_string_settings_names[0], sDirectory);
+ }
+ }
+ }
+ dk3_cpp_release(pComm);
+ dk3_release(sDirectory);
+ return back;
+}
+
+
+
+void DkWxTraceFrame::getData()
+{
+ int values_to_save[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0
+ };
+ pHelper->retrieveMultipleInts(dkwxct_settings_names, values_to_save);
+ options.mak = values_to_save[0];
+ options.lnn = values_to_save[1];
+ options.deb = values_to_save[2];
+ options.ts = values_to_save[3];
+ options.tkw = values_to_save[4];
+ options.win = values_to_save[5];
+ options.spls = '\0';
+ if ((values_to_save[6])
+ && ((0 <= values_to_save[7]) && (18 > values_to_save[7])))
+ {
+ options.spls = (char)((sTexts[76 + values_to_save[7]])[0]);
+ }
+ sDirectory = pHelper->retrieveString(dkwxct_string_settings_names[0]);
+}
+
+
+void
+DkWxTraceFrame::OnIdle(wxIdleEvent & event)
+{
+ dk3_time_t ct;
+ $? "+ DkWxTraceFrame::OnIdle"
+ if(!bCloseScheduled) {
+ if(pComm) {
+ if(pComm->autostartCanRun()) { $? ". start"
+ runConversion();
+ } else {
+ if(pComm->autostartIsFinished()) { $? ". close"
+ if(!(timeClose)) {
+ if(pComm->getLogLevel() > DK3_LL_WARNING) {
+ dk3sf_time(&timeClose);
+ event.RequestMore();
+ tStatus->SetLabel(sTexts[72]);
+ if((cGreen) && (cBlack)) {
+ tStatus->SetForegroundColour(*cGreen);
+ }
+ Refresh();
+ Update();
+ }
+ }
+ }
+ }
+ }
+ if(timeClose) {
+ dk3sf_time(&ct);
+ if(ct > (timeClose + (dk3_time_t)1UL)) {
+ timeClose = (dk3_time_t)0UL;
+ bCloseScheduled = true;
+ Show(false);
+ Close();
+ } else {
+ event.RequestMore();
+ }
+ }
+ }
+ $? "- DkWxTraceFrame::OnIdle"
+ event.Skip();
+}
+
+
+
+bool
+DkWxTraceFrame::isGuiActive()
+{
+ bool back = false;
+ if(!(bCloseScheduled)) {
+ back = bGuiActive;
+ }
+ return back;
+}
+
+
+
+int
+DkWxTraceFrame::findSplintCharacterIndex(char c)
+{
+ int back = 0;
+ int i; /* Traverse 0 to 17 */
+ bool found = false; /* Flag: Character was found */
+ for (i = 0; ((i < 18) && (!(found))); i++) {
+ if (c == (sTexts[76 + i])[0]) {
+ found = true;
+ back = i;
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/DkWxTraceOptionsDialog.cpp b/support/dktools/DkWxTraceOptionsDialog.cpp
new file mode 100644
index 0000000000..dc17259c9e
--- /dev/null
+++ b/support/dktools/DkWxTraceOptionsDialog.cpp
@@ -0,0 +1,557 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxTraceOptionsDialog.wxc
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxTraceOptionsDialog.cpp The DkWxTraceOptionsDialog module.
+*/
+
+
+#line 203 "DkWxTraceOptionsDialog.wxc"
+
+#include "dkwxtrace.h"
+
+
+
+
+
+#line 209 "DkWxTraceOptionsDialog.wxc"
+
+BEGIN_EVENT_TABLE(DkWxTraceOptionsDialog, wxDialog)
+ EVT_BUTTON(wxID_OK, DkWxTraceOptionsDialog::OnOK)
+ EVT_BUTTON(wxID_CANCEL, DkWxTraceOptionsDialog::OnCancel)
+ EVT_CHECKBOX(DkWxTrace_Debug, DkWxTraceOptionsDialog::OnChangeDebug)
+ EVT_CHECKBOX(DkWxTrace_UseSplint, DkWxTraceOptionsDialog::OnChangeUseSplint)
+END_EVENT_TABLE()
+
+
+#line 218 "DkWxTraceOptionsDialog.wxc"
+DkWxTraceOptionsDialog::DkWxTraceOptionsDialog(
+ DkWxTraceFrame *parent,
+ wxChar const *title,
+ wxChar const * const *messageTexts,
+ DKCT_OPTION_SET *o
+) : wxDialog(
+ parent,
+ wxID_ANY,
+ title,
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxDEFAULT_DIALOG_STYLE
+),
+cRed(0x7F, 0x00, 0x00)
+{
+ wxString splintCommentChars[] = {
+ wxString(messageTexts[76]),
+ wxString(messageTexts[77]),
+ wxString(messageTexts[78]),
+ wxString(messageTexts[79]),
+ wxString(messageTexts[80]),
+ wxString(messageTexts[81]),
+ wxString(messageTexts[82]),
+ wxString(messageTexts[83]),
+ wxString(messageTexts[84]),
+ wxString(messageTexts[85]),
+ wxString(messageTexts[86]),
+ wxString(messageTexts[87]),
+ wxString(messageTexts[88]),
+ wxString(messageTexts[89]),
+ wxString(messageTexts[90]),
+ wxString(messageTexts[91]),
+ wxString(messageTexts[92]),
+ wxString(messageTexts[93]),
+ };
+ pa = parent;
+ sTexts = messageTexts;
+ options = o;
+ is_correcting = 0;
+ dkctGUILayoutOK = false;
+ sDialog = NULL;
+ verticalSizer = NULL;
+ sSetup = NULL;
+ sButtons = NULL;
+ sttGeneral = NULL;
+ cbMake = NULL;
+ sttOutput = NULL;
+ cbLinenumbers = NULL;
+ cbUseSplint = NULL;
+ chSplintChar = NULL;
+ sttDebug = NULL;
+ cbDebug = NULL;
+ cbDebStdout = NULL;
+ cbDebTime = NULL;
+ cbDebTraceKw = NULL;
+ cbDebWide = NULL;
+ cbDebPortable = NULL;
+ bOK = NULL;
+ bCancel = NULL;
+ sDialog = new wxBoxSizer(
+ wxHORIZONTAL
+ );
+ if(!(sDialog)) {
+ goto dkctGUILayoutFinished;
+ }
+ sDialog->Add(10, 10, 1);
+ verticalSizer = new wxBoxSizer(
+ wxVERTICAL
+ );
+ if(!(verticalSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ verticalSizer->Add(10, 10, 1);
+ sSetup = new wxGridBagSizer(
+ );
+ if(!(sSetup)) {
+ goto dkctGUILayoutFinished;
+ }
+ sttGeneral = new wxStaticText(
+ this,
+ wxID_ANY,
+ sTexts[33]
+ );
+ if(!(sttGeneral)) {
+ goto dkctGUILayoutFinished;
+ }
+ sSetup->Add(
+ sttGeneral,
+ wxGBPosition(0, 0),
+ wxGBSpan(1, 4),
+ wxALIGN_LEFT
+ );
+ cbMake = new wxCheckBox(
+ this,
+ wxID_ANY,
+ sTexts[31]
+ );
+ if(!(cbMake)) {
+ goto dkctGUILayoutFinished;
+ }
+ cbMake->SetToolTip(sTexts[32]);
+ sSetup->Add(
+ cbMake,
+ wxGBPosition(1, 0),
+ wxGBSpan(1, 4),
+ wxALIGN_LEFT
+ );
+ sSetup->Add(1, 10, wxGBPosition(2, 0), wxGBSpan(1, 4));
+ sttOutput = new wxStaticText(
+ this,
+ wxID_ANY,
+ sTexts[34]
+ );
+ if(!(sttOutput)) {
+ goto dkctGUILayoutFinished;
+ }
+ sSetup->Add(
+ sttOutput,
+ wxGBPosition(3, 0),
+ wxGBSpan(1, 4),
+ wxALIGN_LEFT
+ );
+ cbLinenumbers = new wxCheckBox(
+ this,
+ wxID_ANY,
+ sTexts[35]
+ );
+ if(!(cbLinenumbers)) {
+ goto dkctGUILayoutFinished;
+ }
+ cbLinenumbers->SetToolTip(sTexts[42]);
+ sSetup->Add(
+ cbLinenumbers,
+ wxGBPosition(4, 0),
+ wxGBSpan(1, 4),
+ wxALIGN_LEFT
+ );
+ cbUseSplint = new wxCheckBox(
+ this,
+ DkWxTrace_UseSplint,
+ sTexts[94]
+ );
+ if(!(cbUseSplint)) {
+ goto dkctGUILayoutFinished;
+ }
+ cbUseSplint->SetToolTip(sTexts[95]);
+ sSetup->Add(
+ cbUseSplint,
+ wxGBPosition(5, 0),
+ wxGBSpan(1, 2),
+ wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL
+ );
+ chSplintChar = new wxChoice(
+ this,
+ DkWxTrace_SplintChar,
+ wxDefaultPosition,
+ wxDefaultSize,
+ 18,
+ splintCommentChars
+ );
+ if(!(chSplintChar)) {
+ goto dkctGUILayoutFinished;
+ }
+ chSplintChar->SetToolTip(sTexts[96]);
+ sSetup->Add(
+ chSplintChar,
+ wxGBPosition(5, 2),
+ wxGBSpan(1, 1),
+ wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL
+ );
+ sSetup->Add(1, 10, wxGBPosition(6, 0), wxGBSpan(1, 4));
+ sttDebug = new wxStaticText(
+ this,
+ wxID_ANY,
+ sTexts[36]
+ );
+ if(!(sttDebug)) {
+ goto dkctGUILayoutFinished;
+ }
+ sSetup->Add(
+ sttDebug,
+ wxGBPosition(7, 0),
+ wxGBSpan(1, 4),
+ wxALIGN_LEFT
+ );
+ cbDebug = new wxCheckBox(
+ this,
+ DkWxTrace_Debug,
+ sTexts[37]
+ );
+ if(!(cbDebug)) {
+ goto dkctGUILayoutFinished;
+ }
+ cbDebug->SetToolTip(sTexts[43]);
+ sSetup->Add(
+ cbDebug,
+ wxGBPosition(8, 0),
+ wxGBSpan(1, 4),
+ wxALIGN_LEFT
+ );
+ sSetup->Add(20, 1, wxGBPosition(9, 0), wxGBSpan(1, 1));
+ cbDebStdout = new wxCheckBox(
+ this,
+ wxID_ANY,
+ sTexts[38]
+ );
+ if(!(cbDebStdout)) {
+ goto dkctGUILayoutFinished;
+ }
+ cbDebStdout->SetToolTip(sTexts[44]);
+ sSetup->Add(
+ cbDebStdout,
+ wxGBPosition(9, 1),
+ wxGBSpan(1, 3),
+ wxALIGN_LEFT
+ );
+ cbDebTime = new wxCheckBox(
+ this,
+ wxID_ANY,
+ sTexts[39]
+ );
+ if(!(cbDebTime)) {
+ goto dkctGUILayoutFinished;
+ }
+ cbDebTime->SetToolTip(sTexts[45]);
+ sSetup->Add(
+ cbDebTime,
+ wxGBPosition(10, 1),
+ wxGBSpan(1, 3),
+ wxALIGN_LEFT
+ );
+ cbDebTraceKw = new wxCheckBox(
+ this,
+ wxID_ANY,
+ sTexts[40]
+ );
+ if(!(cbDebTraceKw)) {
+ goto dkctGUILayoutFinished;
+ }
+ cbDebTraceKw->SetToolTip(sTexts[46]);
+ sSetup->Add(
+ cbDebTraceKw,
+ wxGBPosition(11, 1),
+ wxGBSpan(1, 3),
+ wxALIGN_LEFT
+ );
+ cbDebWide = new wxCheckBox(
+ this,
+ wxID_ANY,
+ sTexts[41]
+ );
+ if(!(cbDebWide)) {
+ goto dkctGUILayoutFinished;
+ }
+ cbDebWide->SetToolTip(sTexts[48]);
+ sSetup->Add(
+ cbDebWide,
+ wxGBPosition(12, 1),
+ wxGBSpan(1, 3),
+ wxALIGN_LEFT
+ );
+ cbDebPortable = new wxCheckBox(
+ this,
+ wxID_ANY,
+ sTexts[97]
+ );
+ if(!(cbDebPortable)) {
+ goto dkctGUILayoutFinished;
+ }
+ cbDebPortable->SetToolTip(sTexts[98]);
+ sSetup->Add(
+ cbDebPortable,
+ wxGBPosition(13, 1),
+ wxGBSpan(1, 3),
+ wxALIGN_LEFT
+ );
+ verticalSizer->Add(
+ sSetup,
+ 0,
+ wxALIGN_CENTER_HORIZONTAL
+ );
+ verticalSizer->Add(10, 10, 1);
+ sButtons = new wxStdDialogButtonSizer(
+ );
+ if(!(sButtons)) {
+ goto dkctGUILayoutFinished;
+ }
+ bOK = new wxButton(
+ this,
+ wxID_OK,
+ sTexts[26]
+ );
+ if(!(bOK)) {
+ goto dkctGUILayoutFinished;
+ }
+ bOK->SetToolTip(sTexts[28]);
+ sButtons->AddButton(
+ bOK
+ );
+ bCancel = new wxButton(
+ this,
+ wxID_CANCEL,
+ sTexts[27]
+ );
+ if(!(bCancel)) {
+ goto dkctGUILayoutFinished;
+ }
+ bCancel->SetToolTip(sTexts[29]);
+ sButtons->AddButton(
+ bCancel
+ );
+ sButtons->Realize();
+ verticalSizer->Add(
+ sButtons,
+ 0,
+ wxALIGN_CENTER_HORIZONTAL
+ );
+ verticalSizer->Add(10, 10, 1);
+ sDialog->Add(
+ verticalSizer,
+ 0,
+ wxGROW
+ );
+ sDialog->Add(10, 10, 1);
+ SetSizer(sDialog);
+ dkctGUILayoutOK = true;
+ dkctGUILayoutFinished:
+ if(dkctGUILayoutOK) {
+ sDialog->Fit(this);
+ sDialog->SetSizeHints(this);
+ }
+
+#line 258 "DkWxTraceOptionsDialog.wxc"
+ if (dkctGUILayoutOK) {
+ sttGeneral->SetForegroundColour(cRed);
+ sttOutput->SetForegroundColour(cRed);
+ sttDebug->SetForegroundColour(cRed);
+ }
+}
+
+
+#line 266 "DkWxTraceOptionsDialog.wxc"
+
+void
+DkWxTraceOptionsDialog::OnOK(
+ wxCommandEvent & event
+)
+{
+ dataOut();
+ if(IsModal()) {
+ EndModal(wxID_OK);
+ } else {
+ SetReturnCode(wxID_OK);
+ Show(false);
+ }
+}
+
+
+void
+DkWxTraceOptionsDialog::OnCancel(
+ wxCommandEvent & event
+)
+{
+ if(IsModal()) {
+ EndModal(wxID_CANCEL);
+ } else {
+ SetReturnCode(wxID_CANCEL);
+ Show(false);
+ }
+}
+
+
+
+void
+DkWxTraceOptionsDialog::OnChangeDebug(
+ wxCommandEvent & event
+)
+{
+ correctGUI();
+}
+
+
+
+void
+DkWxTraceOptionsDialog::OnChangeUseSplint(
+ wxCommandEvent & event
+)
+{
+ correctGUI();
+}
+
+
+void
+DkWxTraceOptionsDialog::dataIn()
+{
+ cbLinenumbers->SetValue((options->lnn) ? true : false);
+ cbMake->SetValue((options->mak) ? true : false);
+ cbDebug->SetValue((options->deb) ? true : false);
+ cbDebStdout->SetValue((options->deb == 2) ? true : false);
+ cbDebWide->SetValue((options->win) ? true : false);
+ cbDebPortable->SetValue((options->port) ? true : false);
+ cbDebTraceKw->SetValue((options->tkw) ? true : false);
+ cbDebTime->SetValue((options->ts) ? true : false);
+ if ('\0' != options->spls) {
+ cbUseSplint->SetValue(true);
+ chSplintChar->SetSelection(pa->findSplintCharacterIndex(options->spls));
+ } else {
+ cbUseSplint->SetValue(false);
+ chSplintChar->SetSelection(0);
+ }
+ correctGUI();
+}
+
+
+
+void
+DkWxTraceOptionsDialog::dataOut()
+{
+ options->deb = (cbDebug->GetValue()) ? (
+ (cbDebStdout->GetValue()) ? 2 : 1
+ ) : 0;
+ options->lnn = (cbLinenumbers->GetValue()) ? 1 : 0;
+ options->mak = (cbMake->GetValue()) ? 1 : 0;
+ options->tkw = (cbDebTraceKw->GetValue()) ? 1 : 0;
+ options->ts = (cbDebTime->GetValue()) ? 1 : 0;
+ options->win = (cbDebWide->GetValue()) ? 1 : 0;
+ options->port = (cbDebPortable->GetValue()) ? 1 : 0;
+ if (cbUseSplint->GetValue()) {
+ options->spls =
+ (char)((sTexts[76 + chSplintChar->GetCurrentSelection()])[0]);
+ } else {
+ options->spls = '\0';
+ }
+}
+
+
+void
+DkWxTraceOptionsDialog::correctGUI()
+{
+ if(!(is_correcting)) {
+ is_correcting = 1;
+ if(cbDebug) {
+ if(cbDebug->GetValue()) {
+ if(cbDebStdout) {
+ cbDebStdout->Enable(true);
+ }
+ if(cbDebTime) {
+ cbDebTime->Enable(true);
+ }
+ if(cbDebTraceKw) {
+ cbDebTraceKw->Enable(true);
+ }
+ if(cbDebWide) {
+ cbDebWide->Enable(true);
+ }
+ if(NULL != cbDebPortable) {
+ cbDebPortable->Enable(true);
+ }
+ } else {
+ if(cbDebStdout) {
+ cbDebStdout->SetValue(false);
+ cbDebStdout->Enable(false);
+ }
+ if(cbDebTime) {
+ cbDebTime->SetValue(false);
+ cbDebTime->Enable(false);
+ }
+ if(cbDebTraceKw) {
+ cbDebTraceKw->SetValue(false);
+ cbDebTraceKw->Enable(false);
+ }
+ if(cbDebWide) {
+ cbDebWide->SetValue(false);
+ cbDebWide->Enable(false);
+ }
+ if(NULL != cbDebPortable) {
+ cbDebPortable->SetValue(false);
+ cbDebPortable->Enable(false);
+ }
+ }
+ }
+ if (cbUseSplint) {
+ if (cbUseSplint->GetValue()) {
+
+#line 407 "DkWxTraceOptionsDialog.wxc"
+ chSplintChar->Enable(true);
+ } else {
+
+#line 409 "DkWxTraceOptionsDialog.wxc"
+ chSplintChar->Enable(false);
+ }
+ }
+ is_correcting = 0;
+ Refresh();
+ Update();
+ }
+}
+
+
diff --git a/support/dktools/DkWxTraceOptionsDialog.h b/support/dktools/DkWxTraceOptionsDialog.h
new file mode 100644
index 0000000000..c19d167bbf
--- /dev/null
+++ b/support/dktools/DkWxTraceOptionsDialog.h
@@ -0,0 +1,237 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxTraceOptionsDialog.wxc
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxTraceOptionsDialog.h Header file for the DkWxTraceOptionsDialog module.
+*/
+
+#ifndef DKWXTRACEOPTIONSDIALOG_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DKWXTRACEOPTIONSDIALOG_H_INCLUDED 1
+
+
+#line 113 "DkWxTraceOptionsDialog.wxc"
+
+
+#line 115 "DkWxTraceOptionsDialog.wxc"
+/** Trace options dialog.
+*/
+class DkWxTraceOptionsDialog : public wxDialog
+{
+ private:
+
+ /** Event table.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ /** Color for section heads.
+ */
+ wxColour cRed;
+
+ /** Parent window.
+ */
+ DkWxTraceFrame *pa;
+
+ /** Message texts.
+ */
+ wxChar const * const *sTexts;
+
+ /** Option set to configure.
+ */
+ DKCT_OPTION_SET *options;
+
+ /** Flag: We are in correction routine.
+ */
+ int is_correcting;
+
+ /** Flag: GUI ok.
+ */
+ bool dkctGUILayoutOK;
+
+ /** GUI element sDialog.
+ */
+#line 13 "DkWxTraceOptionsDialog.wxc"
+ wxBoxSizer *sDialog;
+
+ /** GUI element verticalSizer.
+ */
+#line 19 "DkWxTraceOptionsDialog.wxc"
+ wxBoxSizer *verticalSizer;
+
+ /** GUI element sSetup.
+ */
+#line 28 "DkWxTraceOptionsDialog.wxc"
+ wxGridBagSizer *sSetup;
+
+ /** GUI element sButtons.
+ */
+#line 98 "DkWxTraceOptionsDialog.wxc"
+ wxStdDialogButtonSizer *sButtons;
+
+ /** GUI element sttGeneral.
+ */
+#line 46 "DkWxTraceOptionsDialog.wxc"
+ wxStaticText *sttGeneral;
+
+ /** GUI element cbMake.
+ */
+#line 49 "DkWxTraceOptionsDialog.wxc"
+ wxCheckBox *cbMake;
+
+ /** GUI element sttOutput.
+ */
+#line 53 "DkWxTraceOptionsDialog.wxc"
+ wxStaticText *sttOutput;
+
+ /** GUI element cbLinenumbers.
+ */
+#line 56 "DkWxTraceOptionsDialog.wxc"
+ wxCheckBox *cbLinenumbers;
+
+ /** GUI element cbUseSplint.
+ */
+#line 60 "DkWxTraceOptionsDialog.wxc"
+ wxCheckBox *cbUseSplint;
+
+ /** GUI element chSplintChar.
+ */
+#line 65 "DkWxTraceOptionsDialog.wxc"
+ wxChoice *chSplintChar;
+
+ /** GUI element sttDebug.
+ */
+#line 70 "DkWxTraceOptionsDialog.wxc"
+ wxStaticText *sttDebug;
+
+ /** GUI element cbDebug.
+ */
+#line 73 "DkWxTraceOptionsDialog.wxc"
+ wxCheckBox *cbDebug;
+
+ /** GUI element cbDebStdout.
+ */
+#line 78 "DkWxTraceOptionsDialog.wxc"
+ wxCheckBox *cbDebStdout;
+
+ /** GUI element cbDebTime.
+ */
+#line 82 "DkWxTraceOptionsDialog.wxc"
+ wxCheckBox *cbDebTime;
+
+ /** GUI element cbDebTraceKw.
+ */
+#line 86 "DkWxTraceOptionsDialog.wxc"
+ wxCheckBox *cbDebTraceKw;
+
+ /** GUI element cbDebWide.
+ */
+#line 90 "DkWxTraceOptionsDialog.wxc"
+ wxCheckBox *cbDebWide;
+
+ /** GUI element cbDebPortable.
+ */
+#line 94 "DkWxTraceOptionsDialog.wxc"
+ wxCheckBox *cbDebPortable;
+
+ /** GUI element bOK.
+ */
+#line 102 "DkWxTraceOptionsDialog.wxc"
+ wxButton *bOK;
+
+ /** GUI element bCancel.
+ */
+#line 107 "DkWxTraceOptionsDialog.wxc"
+ wxButton *bCancel;
+
+
+#line 148 "DkWxTraceOptionsDialog.wxc"
+ public:
+
+ /** Constructor.
+ @param parent Parent window.
+ @param title Title text.
+ @param messageTexts Localized message texts.
+ @param o Options set to modify using this dialog.
+ */
+ DkWxTraceOptionsDialog(
+ DkWxTraceFrame *parent,
+ wxChar const *title,
+ wxChar const * const *messageTexts,
+ DKCT_OPTION_SET *o
+ );
+
+ protected:
+
+ /** Handler for OK button.
+ @param event Event to process.
+ */
+ void OnOK(wxCommandEvent& WXUNUSED(event));
+
+ /** Handler for Cancel button.
+ @param event Event to process.
+ */
+ void OnCancel(wxCommandEvent& WXUNUSED(event));
+
+ /** Handler for clicking the debug checkbox.
+ @param event Event to process.
+ */
+ void OnChangeDebug(wxCommandEvent & WXUNUSED(event));
+
+ /** Handler for changing the use splint option.
+ @param event Event to process.
+ */
+ void OnChangeUseSplint(wxCommandEvent & WXUNUSED(event));
+
+ public:
+
+ /** Transfer data from GUI controls to configuration structure.
+ */
+ void dataOut();
+
+ /** Transfer data from configuration structure to GUI controls.
+ */
+ void dataIn();
+
+ /** Correct GUI depending on cbDebug.
+ */
+ void correctGUI();
+};
+
+
+#line 201 "DkWxTraceOptionsDialog.wxc"
+
+
+#endif
diff --git a/support/dktools/DkWxTraceOptionsDialog.wxc b/support/dktools/DkWxTraceOptionsDialog.wxc
new file mode 100644
index 0000000000..348b9008cb
--- /dev/null
+++ b/support/dktools/DkWxTraceOptionsDialog.wxc
@@ -0,0 +1,418 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+%% wx-gui
+
+type = dialog
+contents = sDialog
+
+[wxBoxSizer sDialog]
+direction = horizontal
+contents = $stretch(10)
+contents = verticalSizer
+contents = $stretch(10)
+
+[wxBoxSizer verticalSizer]
+direction = vertical
+grow = yes
+contents = $stretch(10)
+contents = sSetup centered-x
+contents = $stretch(10)
+contents = sButtons centered-x
+contents = $stretch(10)
+
+[wxGridBagSizer sSetup]
+contents = sttGeneral 0 0 1 4 left
+contents = cbMake +1 0 1 4 left
+contents = $space(1,10) +1 0 1 4 left
+contents = sttOutput +1 0 1 4 left
+contents = cbLinenumbers +1 0 1 4 left
+contents = cbUseSplint +1 0 1 2 left centered-y
+contents = chSplintChar . 2 1 1 left centered-y
+contents = $space(1,10) +1 0 1 4 left
+contents = sttDebug +1 0 1 4 left
+contents = cbDebug +1 0 1 4 left
+contents = $space(20,1) +1 0 1 1 left
+contents = cbDebStdout . 1 1 3 left
+contents = cbDebTime +1 1 1 3 left
+contents = cbDebTraceKw +1 1 1 3 left
+contents = cbDebWide +1 1 1 3 left
+contents = cbDebPortable +1 1 1 3 left
+
+[wxStaticText sttGeneral]
+text = sTexts[33]
+
+[wxCheckBox cbMake]
+text = sTexts[31]
+tip = sTexts[32]
+
+[wxStaticText sttOutput]
+text = sTexts[34]
+
+[wxCheckBox cbLinenumbers]
+text = sTexts[35]
+tip = sTexts[42]
+
+[wxCheckBox cbUseSplint]
+text = sTexts[94]
+tip = sTexts[95]
+id = DkWxTrace_UseSplint
+
+[wxChoice chSplintChar]
+choices = 18 splintCommentChars
+tip = sTexts[96]
+id = DkWxTrace_SplintChar
+
+[wxStaticText sttDebug]
+text = sTexts[36]
+
+[wxCheckBox cbDebug]
+text = sTexts[37]
+tip = sTexts[43]
+id = DkWxTrace_Debug
+
+[wxCheckBox cbDebStdout]
+text = sTexts[38]
+tip = sTexts[44]
+
+[wxCheckBox cbDebTime]
+text = sTexts[39]
+tip = sTexts[45]
+
+[wxCheckBox cbDebTraceKw]
+text = sTexts[40]
+tip = sTexts[46]
+
+[wxCheckBox cbDebWide]
+text = sTexts[41]
+tip = sTexts[48]
+
+[wxCheckBox cbDebPortable]
+text = sTexts[97]
+tip = sTexts[98]
+
+[wxStdDialogButtonSizer sButtons]
+contents = bOK
+contents = bCancel
+
+[wxButton bOK]
+id = wxID_OK
+text = sTexts[26]
+tip = sTexts[28]
+
+[wxButton bCancel]
+id = wxID_CANCEL
+text = sTexts[27]
+tip = sTexts[29]
+
+%% header start
+
+%% class start
+/** Trace options dialog.
+*/
+class DkWxTraceOptionsDialog : public wxDialog
+{
+ private:
+
+ /** Event table.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ /** Color for section heads.
+ */
+ wxColour cRed;
+
+ /** Parent window.
+ */
+ DkWxTraceFrame *pa;
+
+ /** Message texts.
+ */
+ wxChar const * const *sTexts;
+
+ /** Option set to configure.
+ */
+ DKCT_OPTION_SET *options;
+
+ /** Flag: We are in correction routine.
+ */
+ int is_correcting;
+
+%% class end
+ public:
+
+ /** Constructor.
+ @param parent Parent window.
+ @param title Title text.
+ @param messageTexts Localized message texts.
+ @param o Options set to modify using this dialog.
+ */
+ DkWxTraceOptionsDialog(
+ DkWxTraceFrame *parent,
+ wxChar const *title,
+ wxChar const * const *messageTexts,
+ DKCT_OPTION_SET *o
+ );
+
+ protected:
+
+ /** Handler for OK button.
+ @param event Event to process.
+ */
+ void OnOK(wxCommandEvent& WXUNUSED(event));
+
+ /** Handler for Cancel button.
+ @param event Event to process.
+ */
+ void OnCancel(wxCommandEvent& WXUNUSED(event));
+
+ /** Handler for clicking the debug checkbox.
+ @param event Event to process.
+ */
+ void OnChangeDebug(wxCommandEvent & WXUNUSED(event));
+
+ /** Handler for changing the use splint option.
+ @param event Event to process.
+ */
+ void OnChangeUseSplint(wxCommandEvent & WXUNUSED(event));
+
+ public:
+
+ /** Transfer data from GUI controls to configuration structure.
+ */
+ void dataOut();
+
+ /** Transfer data from configuration structure to GUI controls.
+ */
+ void dataIn();
+
+ /** Correct GUI depending on cbDebug.
+ */
+ void correctGUI();
+};
+
+%% header end
+
+%% module start
+
+#include "dkwxtrace.h"
+
+
+
+$!trace-include
+
+BEGIN_EVENT_TABLE(DkWxTraceOptionsDialog, wxDialog)
+ EVT_BUTTON(wxID_OK, DkWxTraceOptionsDialog::OnOK)
+ EVT_BUTTON(wxID_CANCEL, DkWxTraceOptionsDialog::OnCancel)
+ EVT_CHECKBOX(DkWxTrace_Debug, DkWxTraceOptionsDialog::OnChangeDebug)
+ EVT_CHECKBOX(DkWxTrace_UseSplint, DkWxTraceOptionsDialog::OnChangeUseSplint)
+END_EVENT_TABLE()
+
+%% constructor start
+DkWxTraceOptionsDialog::DkWxTraceOptionsDialog(
+ DkWxTraceFrame *parent,
+ wxChar const *title,
+ wxChar const * const *messageTexts,
+ DKCT_OPTION_SET *o
+) : wxDialog(
+ parent,
+ wxID_ANY,
+ title,
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxDEFAULT_DIALOG_STYLE
+),
+cRed(0x7F, 0x00, 0x00)
+{
+ wxString splintCommentChars[] = {
+ wxString(messageTexts[76]),
+ wxString(messageTexts[77]),
+ wxString(messageTexts[78]),
+ wxString(messageTexts[79]),
+ wxString(messageTexts[80]),
+ wxString(messageTexts[81]),
+ wxString(messageTexts[82]),
+ wxString(messageTexts[83]),
+ wxString(messageTexts[84]),
+ wxString(messageTexts[85]),
+ wxString(messageTexts[86]),
+ wxString(messageTexts[87]),
+ wxString(messageTexts[88]),
+ wxString(messageTexts[89]),
+ wxString(messageTexts[90]),
+ wxString(messageTexts[91]),
+ wxString(messageTexts[92]),
+ wxString(messageTexts[93]),
+ };
+ pa = parent;
+ sTexts = messageTexts;
+ options = o;
+ is_correcting = 0;
+%% constructor end
+ if (dkctGUILayoutOK) {
+ sttGeneral->SetForegroundColour(cRed);
+ sttOutput->SetForegroundColour(cRed);
+ sttDebug->SetForegroundColour(cRed);
+ }
+}
+
+%% module end
+
+void
+DkWxTraceOptionsDialog::OnOK(
+ wxCommandEvent & event
+)
+{
+ dataOut();
+ if(IsModal()) {
+ EndModal(wxID_OK);
+ } else {
+ SetReturnCode(wxID_OK);
+ Show(false);
+ }
+}
+
+
+void
+DkWxTraceOptionsDialog::OnCancel(
+ wxCommandEvent & event
+)
+{
+ if(IsModal()) {
+ EndModal(wxID_CANCEL);
+ } else {
+ SetReturnCode(wxID_CANCEL);
+ Show(false);
+ }
+}
+
+
+
+void
+DkWxTraceOptionsDialog::OnChangeDebug(
+ wxCommandEvent & event
+)
+{
+ correctGUI();
+}
+
+
+
+void
+DkWxTraceOptionsDialog::OnChangeUseSplint(
+ wxCommandEvent & event
+)
+{
+ correctGUI();
+}
+
+
+void
+DkWxTraceOptionsDialog::dataIn()
+{
+ cbLinenumbers->SetValue((options->lnn) ? true : false);
+ cbMake->SetValue((options->mak) ? true : false);
+ cbDebug->SetValue((options->deb) ? true : false);
+ cbDebStdout->SetValue((options->deb == 2) ? true : false);
+ cbDebWide->SetValue((options->win) ? true : false);
+ cbDebPortable->SetValue((options->port) ? true : false);
+ cbDebTraceKw->SetValue((options->tkw) ? true : false);
+ cbDebTime->SetValue((options->ts) ? true : false);
+ if ('\0' != options->spls) {
+ cbUseSplint->SetValue(true);
+ chSplintChar->SetSelection(pa->findSplintCharacterIndex(options->spls));
+ } else {
+ cbUseSplint->SetValue(false);
+ chSplintChar->SetSelection(0);
+ }
+ correctGUI();
+}
+
+
+
+void
+DkWxTraceOptionsDialog::dataOut()
+{
+ options->deb = (cbDebug->GetValue()) ? (
+ (cbDebStdout->GetValue()) ? 2 : 1
+ ) : 0;
+ options->lnn = (cbLinenumbers->GetValue()) ? 1 : 0;
+ options->mak = (cbMake->GetValue()) ? 1 : 0;
+ options->tkw = (cbDebTraceKw->GetValue()) ? 1 : 0;
+ options->ts = (cbDebTime->GetValue()) ? 1 : 0;
+ options->win = (cbDebWide->GetValue()) ? 1 : 0;
+ options->port = (cbDebPortable->GetValue()) ? 1 : 0;
+ if (cbUseSplint->GetValue()) {
+ options->spls =
+ (char)((sTexts[76 + chSplintChar->GetCurrentSelection()])[0]);
+ } else {
+ options->spls = '\0';
+ }
+}
+
+
+void
+DkWxTraceOptionsDialog::correctGUI()
+{
+ if(!(is_correcting)) {
+ is_correcting = 1;
+ if(cbDebug) {
+ if(cbDebug->GetValue()) {
+ if(cbDebStdout) {
+ cbDebStdout->Enable(true);
+ }
+ if(cbDebTime) {
+ cbDebTime->Enable(true);
+ }
+ if(cbDebTraceKw) {
+ cbDebTraceKw->Enable(true);
+ }
+ if(cbDebWide) {
+ cbDebWide->Enable(true);
+ }
+ if(NULL != cbDebPortable) {
+ cbDebPortable->Enable(true);
+ }
+ } else {
+ if(cbDebStdout) {
+ cbDebStdout->SetValue(false);
+ cbDebStdout->Enable(false);
+ }
+ if(cbDebTime) {
+ cbDebTime->SetValue(false);
+ cbDebTime->Enable(false);
+ }
+ if(cbDebTraceKw) {
+ cbDebTraceKw->SetValue(false);
+ cbDebTraceKw->Enable(false);
+ }
+ if(cbDebWide) {
+ cbDebWide->SetValue(false);
+ cbDebWide->Enable(false);
+ }
+ if(NULL != cbDebPortable) {
+ cbDebPortable->SetValue(false);
+ cbDebPortable->Enable(false);
+ }
+ }
+ }
+ if (cbUseSplint) {
+ if (cbUseSplint->GetValue()) { $? ". enable"
+ chSplintChar->Enable(true);
+ } else { $? ". disable"
+ chSplintChar->Enable(false);
+ }
+ }
+ is_correcting = 0;
+ Refresh();
+ Update();
+ }
+}
+
+
diff --git a/support/dktools/DkWxTraceThread.cpp b/support/dktools/DkWxTraceThread.cpp
new file mode 100644
index 0000000000..d4fa7b6b30
--- /dev/null
+++ b/support/dktools/DkWxTraceThread.cpp
@@ -0,0 +1,413 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxTraceThread.cpt
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxTraceThread.cpp The DkWxTraceThread module.
+*/
+
+
+#line 115 "DkWxTraceThread.cpt"
+
+#include "dkwxtrace.h"
+
+
+
+#line 119 "DkWxTraceThread.cpt"
+
+
+
+/** wxChar keywords used in this module.
+*/
+static wxChar const wxdkct_trace_thread_string_colon[] = { wxT(":") };
+
+
+
+/** Keywords used in this module.
+*/
+static dkChar const * const dkwxtrthr_kw[] = {
+/* 0 */ dkT("."),
+NULL
+};
+
+
+
+static
+void
+dkwxtrthr_check_current_directory(DKCT_SRC *psrc, dkChar const *fn)
+{
+ dkChar curdir[DK3_MAX_PATH];
+ dkChar fndir[DK3_MAX_PATH];
+ dkChar *ptr;
+
+
+#line 145 "DkWxTraceThread.cpt"
+ if(dk3str_len(fn) < DK3_SIZEOF(fndir,dkChar)) {
+ dk3str_cpy(fndir, fn);
+ ptr = dk3str_rchr(fndir, DK3_CHAR_SEP);
+ if(ptr) { *ptr = DK3_CHAR_0; }
+ if(dk3str_cmp(dkwxtrthr_kw[0], fndir) == 0) {
+ psrc->curdi = 1;
+ } else {
+ if(dk3sf_getcwd_app(curdir,DK3_SIZEOF(curdir,dkChar),psrc->app)) {
+ if(dk3str_cmp(curdir, fndir) == 0) {
+ psrc->curdi = 1;
+ }
+ }
+ }
+ }
+
+#line 159 "DkWxTraceThread.cpt"
+}
+
+
+
+DkWxTraceThread::DkWxTraceThread(
+ DkWxCommunicator *comm,
+ wxChar const * const *texts,
+ dkChar const * const *ms,
+ wxChar const *directory,
+ DkWxAppHelper *ah,
+ DKCT_OPTION_SET *o,
+ int we,
+ int de
+) : wxThread(wxTHREAD_DETACHED)
+{
+
+
+#line 175 "DkWxTraceThread.cpt"
+ pComm = comm;
+ wxe = we;
+ dke = de;
+ sTexts = texts;
+ msg = ms;
+ sDirectory = directory;
+ pHelper = ah;
+ app = pHelper->getApp();
+ dk3mem_cpy((void *)(&dkcto),(void *)o,sizeof(DKCT_OPTION_SET));
+
+
+#line 185 "DkWxTraceThread.cpt"
+}
+
+
+
+static wxChar const testfilename[] = { wxT("Test") };
+
+
+
+void
+DkWxTraceThread::runForFile(dkChar const *fn, int sufi)
+{
+ char shn[DK3_MAX_PATH]; /* Short file name. */
+ dkChar const *pstart; /* Start of short file name. */
+ DKCT_SRC *psrc; /* Source structure. */
+ int ie; /* Input encoding. */
+ int ok = 0;
+
+
+#line 202 "DkWxTraceThread.cpt"
+ pstart = dk3str_rchr(fn, DK3_CHAR_SEP);
+ if(pstart) { pstart++; } else { pstart = fn; }
+ ie = dk3app_get_encoding(app);
+ if(dk3str_to_c8p_app(shn, sizeof(shn), pstart, ie, app)) {
+
+#line 206 "DkWxTraceThread.cpt"
+ pComm->addDkText(fn);
+ pComm->addWxText(wxdkct_trace_thread_string_colon);
+ pComm->nl();
+ psrc = dkct_tr_new(&dkcto, shn, sufi, app, fn);
+ if(psrc) {
+
+#line 211 "DkWxTraceThread.cpt"
+ (psrc->dkcto).deben = 1;
+ psrc->msg = msg;
+ psrc->pComm = pComm;
+ dkwxtrthr_check_current_directory(psrc, fn);
+ if(dkct_tr_read(psrc, fn, sufi)) {
+
+#line 216 "DkWxTraceThread.cpt"
+ if(dkct_tr_check(psrc, fn, sufi)) {
+
+#line 217 "DkWxTraceThread.cpt"
+ if(dkct_tr_write(psrc, fn, sufi)) {
+
+#line 218 "DkWxTraceThread.cpt"
+ ok = 1;
+ }
+ }
+ }
+ dkct_tr_delete(psrc); psrc = NULL;
+ } else {
+ /* ERROR: Memory! */
+ pComm->addWxText(sTexts[63]);
+ pComm->nl();
+ }
+
+#line 228 "DkWxTraceThread.cpt"
+ pComm->addWxText(sTexts[(ok) ? 56 : 57]);
+
+#line 229 "DkWxTraceThread.cpt"
+ pComm->nl();
+ pComm->nl();
+ } else {
+
+#line 232 "DkWxTraceThread.cpt"
+ /* ERROR: Can not convert file name to 8-bit characters plain! */
+ pComm->addWxText(sTexts[61]);
+ pComm->addDkText(fn);
+ pComm->addWxText(sTexts[62]);
+ pComm->nl();
+ }
+
+#line 238 "DkWxTraceThread.cpt"
+}
+
+
+
+void
+DkWxTraceThread::checkAndRunFile(dkChar const *fn, int sufi)
+{
+ dkChar b1[DK3_MAX_PATH];
+ dkChar *xsu;
+ dkChar const *pstart;
+ dkChar const * const *lfdsu;
+
+
+#line 250 "DkWxTraceThread.cpt"
+ int must_run = 1;
+ if(dkcto.mak) {
+
+#line 252 "DkWxTraceThread.cpt"
+ /* Check whether we really need to run */
+ if(dk3str_len(fn) < DK3_SIZEOF(b1,dkChar)) {
+ dk3str_cpy(b1, fn);
+ lfdsu = (dkct_str_get_dest_suffixes())[sufi];
+ xsu = dk3str_get_suffix(b1);
+ if(xsu) {
+ must_run = 0;
+ while(*lfdsu) {
+ *xsu = dkT('\0');
+ if((dk3str_len(b1) + dk3str_len(*lfdsu)) < DK3_SIZEOF(b1,dkChar)) {
+ dk3str_cat(b1, *lfdsu);
+ if(dk3sf_must_rebuild(b1,fn)) {
+ must_run = 1;
+ }
+ } else {
+ must_run = 1;
+ }
+ lfdsu++;
+ }
+ }
+ }
+ }
+ if(must_run) {
+
+#line 275 "DkWxTraceThread.cpt"
+ runForFile(fn, sufi);
+ } else {
+ /* Up to date. */
+ pstart = dk3str_rchr(fn, DK3_CHAR_SEP);
+ if(pstart) { pstart++; } else { pstart = fn; }
+ pComm->addDkText(pstart);
+ pComm->addWxText(wxdkct_trace_thread_string_colon);
+ pComm->nl();
+ pComm->addWxText(sTexts[55]);
+ pComm->nl();
+ pComm->nl();
+ }
+
+#line 287 "DkWxTraceThread.cpt"
+}
+
+
+
+void
+DkWxTraceThread::runForDirectory(wxChar const *dirname)
+{
+ dkChar bu[DK3_MAX_PATH];
+ wxChar fnb[DK3_MAX_PATH];
+ dk3_dir_t *dir;
+ dkChar const *en;
+ dkChar const *su;
+ dk3_stat_t const *es;
+ dk3_um_t nFiles;
+ dk3_um_t cFile;
+ dk3_um_t promille;
+ int ai;
+ int cc;
+
+
+#line 306 "DkWxTraceThread.cpt"
+ cFile = DK3_UM_0;
+ cc = 1;
+ if(dk3wxs_to_dkstr(bu, DK3_SIZEOF(bu,dkChar), dke, dirname, wxe)) {
+
+
+#line 310 "DkWxTraceThread.cpt"
+ dir = dk3dir_open_app(bu, app);
+ if(dir) {
+
+#line 312 "DkWxTraceThread.cpt"
+ nFiles = dk3dir_get_number_of_files(dir);
+ if(!(nFiles)) nFiles++;
+ while(cc) {
+
+#line 315 "DkWxTraceThread.cpt"
+ cc = 0;
+ if(dk3dir_get_next_file(dir)) {
+
+#line 317 "DkWxTraceThread.cpt"
+ cc = 1;
+ if(cFile > nFiles) cFile = nFiles;
+ promille = ((dk3_um_t)1000UL * cFile) / nFiles;
+ en = dk3dir_get_fullname(dir);
+ es = dk3dir_get_stat(dir);
+ if((en) && (es)) {
+
+#line 323 "DkWxTraceThread.cpt"
+ if(dk3wxs_from_dkstr(fnb, DK3_SIZEOF(fnb,wxChar), wxe, en, dke)) {
+ pComm->setUpdates(fnb, promille);
+ }
+ switch((es->ft) & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_REGULAR: {
+
+#line 328 "DkWxTraceThread.cpt"
+ su = dk3str_get_suffix(en);
+ if(su) {
+#if DK3_ON_WINDOWS || DK3_HAVE_FNCASEINS
+ ai = dk3str_array_index(dkct_str_get_source_suffixes(), su, 0);
+#else
+ ai = dk3str_array_index(dkct_str_get_source_suffixes(), su, 1);
+#endif
+ if(ai >= 0) {
+ checkAndRunFile(en, ai);
+ }
+ }
+ } break;
+ }
+ }
+ cFile++;
+ }
+ if(!(pComm->getCanContinue())) {
+ cc = 0;
+ }
+ }
+ dk3dir_close(dir);
+ } else {
+
+#line 350 "DkWxTraceThread.cpt"
+ /* ERROR: Failed to open directory! */
+ pComm->addWxText(sTexts[59]);
+ pComm->addWxText(dirname);
+ pComm->addWxText(sTexts[60]);
+ pComm->nl();
+ }
+ } else {
+
+#line 357 "DkWxTraceThread.cpt"
+ /* ERROR: Filename conversion failed! */
+ pComm->addWxText(sTexts[58]);
+ pComm->nl();
+ }
+
+#line 361 "DkWxTraceThread.cpt"
+}
+
+
+
+void *
+DkWxTraceThread::Entry()
+{
+
+
+#line 369 "DkWxTraceThread.cpt"
+#if 0
+ /*
+ Simple test thread witout practical use.
+ */
+ int i = 0;
+ int cc = 1;
+ int numbreak = -1;
+ do {
+ this->Sleep(100);
+ i++;
+ if(i >= 100) {
+ cc = 0;
+ }
+ pComm->setUpdates(testfilename, (10*i));
+ if(pComm->getCanContinue() == 0) {
+ if(numbreak == -1) {
+ numbreak = i;
+ } else {
+ if(i >= numbreak + 15) {
+ cc = 0;
+ }
+ }
+ }
+ pComm->addWxText(wxT("Test mit einer ganz ganz ganz ganz langen Zeile\n"));
+ } while(cc);
+ pComm->setRunning(0);
+#else
+ /*
+ Start message
+ */
+ pComm->addWxText(sTexts[54]);
+ if(sDirectory) {
+ pComm->addWxText(sDirectory);
+ } else {
+ pComm->addWxText(sTexts[25]);
+ }
+ pComm->nl();
+ runForDirectory((sDirectory) ? sDirectory : sTexts[25]);
+ /*
+ Signal finished.
+ */
+ pComm->setRunning(0);
+#endif
+
+
+#line 413 "DkWxTraceThread.cpt"
+ return NULL;
+}
+
+
+
+void
+DkWxTraceThread::OnExit()
+{
+}
+
+
+
+
diff --git a/support/dktools/DkWxTraceThread.cpt b/support/dktools/DkWxTraceThread.cpt
new file mode 100644
index 0000000000..5e68832c72
--- /dev/null
+++ b/support/dktools/DkWxTraceThread.cpt
@@ -0,0 +1,425 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% header
+
+#include "dkwxtrace.h"
+
+$!trace-include
+
+
+
+/** Worker thread for wxdkct.
+*/
+class DkWxTraceThread : public wxThread
+{
+ protected:
+
+ /** Conversion option set.
+ */
+ DKCT_OPTION_SET dkcto;
+
+ /** Communication object between main thread and worker thread.
+ */
+ DkWxCommunicator *pComm;
+
+ /** Localized text messages.
+ */
+ wxChar const * const *sTexts;
+
+ /** Localized dkChar messages.
+ */
+ dkChar const * const *msg;
+
+ /** Directory to process.
+ */
+ wxChar const *sDirectory;
+
+ /** Application helper.
+ */
+ DkWxAppHelper *pHelper;
+
+ /** Application structure.
+ */
+ dk3_app_t *app;
+
+ /** Encoding used for wxChar.
+ */
+ int wxe;
+
+ /** Encoding used for dkChar.
+ */
+ int dke;
+
+ /** Run for one file.
+ @param fn File name.
+ @param sufi Suffix index.
+ */
+ void
+ runForFile(dkChar const *fn, int sufi);
+
+ /** Check one file, run if necessary.
+ @param fn File name.
+ @param sufi Suffix index.
+ */
+ void
+ checkAndRunFile(dkChar const *fn, int sufi);
+
+ /** Run for directory.
+ @param dirname Directory name.
+ */
+ void
+ runForDirectory(wxChar const *dirname);
+
+ public:
+
+ /** Constructor
+ @param comm Communication object.
+ @param texts Localized messages texts.
+ @param ms Localized dkChar message texts.
+ @param directory Directory to process.
+ @param ah Application helper.
+ @param o Conversion option set.
+ @param we Encoding for wxChar.
+ @param de Encoding for dkChar.
+ */
+ DkWxTraceThread(
+ DkWxCommunicator *comm,
+ wxChar const * const *texts,
+ dkChar const * const *ms,
+ wxChar const *directory,
+ DkWxAppHelper *ah,
+ DKCT_OPTION_SET *o,
+ int we,
+ int de
+ );
+
+ /** Thread function.
+ @return A pointer which is ignored.
+ */
+ virtual void *Entry();
+
+ /** Function executed at the end of thread, does nothing.
+ */
+ virtual void OnExit();
+
+};
+
+
+%% module
+
+#include "dkwxtrace.h"
+
+$!trace-include
+
+
+
+/** wxChar keywords used in this module.
+*/
+static wxChar const wxdkct_trace_thread_string_colon[] = { wxT(":") };
+
+
+
+/** Keywords used in this module.
+*/
+static dkChar const * const dkwxtrthr_kw[] = {
+/* 0 */ dkT("."),
+NULL
+};
+
+
+
+static
+void
+dkwxtrthr_check_current_directory(DKCT_SRC *psrc, dkChar const *fn)
+{
+ dkChar curdir[DK3_MAX_PATH];
+ dkChar fndir[DK3_MAX_PATH];
+ dkChar *ptr;
+ $? "+ dkwxtrthr_check_current_directory"
+ if(dk3str_len(fn) < DK3_SIZEOF(fndir,dkChar)) {
+ dk3str_cpy(fndir, fn);
+ ptr = dk3str_rchr(fndir, DK3_CHAR_SEP);
+ if(ptr) { *ptr = DK3_CHAR_0; }
+ if(dk3str_cmp(dkwxtrthr_kw[0], fndir) == 0) {
+ psrc->curdi = 1;
+ } else {
+ if(dk3sf_getcwd_app(curdir,DK3_SIZEOF(curdir,dkChar),psrc->app)) {
+ if(dk3str_cmp(curdir, fndir) == 0) {
+ psrc->curdi = 1;
+ }
+ }
+ }
+ } $? "- dkwxtrthr_check_current_directory %d", psrc->curdi
+}
+
+
+
+DkWxTraceThread::DkWxTraceThread(
+ DkWxCommunicator *comm,
+ wxChar const * const *texts,
+ dkChar const * const *ms,
+ wxChar const *directory,
+ DkWxAppHelper *ah,
+ DKCT_OPTION_SET *o,
+ int we,
+ int de
+) : wxThread(wxTHREAD_DETACHED)
+{
+ $? "+ DkWxTraceThread::DkWxTraceThread"
+ pComm = comm;
+ wxe = we;
+ dke = de;
+ sTexts = texts;
+ msg = ms;
+ sDirectory = directory;
+ pHelper = ah;
+ app = pHelper->getApp();
+ dk3mem_cpy((void *)(&dkcto),(void *)o,sizeof(DKCT_OPTION_SET));
+ $? "- DkWxTraceThread::DkWxTraceThread"
+}
+
+
+
+static wxChar const testfilename[] = { wxT("Test") };
+
+
+
+void
+DkWxTraceThread::runForFile(dkChar const *fn, int sufi)
+{
+ char shn[DK3_MAX_PATH]; /* Short file name. */
+ dkChar const *pstart; /* Start of short file name. */
+ DKCT_SRC *psrc; /* Source structure. */
+ int ie; /* Input encoding. */
+ int ok = 0;
+ $? "+ runForFile"
+ pstart = dk3str_rchr(fn, DK3_CHAR_SEP);
+ if(pstart) { pstart++; } else { pstart = fn; }
+ ie = dk3app_get_encoding(app);
+ if(dk3str_to_c8p_app(shn, sizeof(shn), pstart, ie, app)) { $? ". conv ok"
+ pComm->addDkText(fn);
+ pComm->addWxText(wxdkct_trace_thread_string_colon);
+ pComm->nl();
+ psrc = dkct_tr_new(&dkcto, shn, sufi, app, fn);
+ if(psrc) { $? ". psrc ok"
+ (psrc->dkcto).deben = 1;
+ psrc->msg = msg;
+ psrc->pComm = pComm;
+ dkwxtrthr_check_current_directory(psrc, fn);
+ if(dkct_tr_read(psrc, fn, sufi)) { $? ". read ok"
+ if(dkct_tr_check(psrc, fn, sufi)) { $? ". check ok"
+ if(dkct_tr_write(psrc, fn, sufi)) { $? ". write ok"
+ ok = 1;
+ }
+ }
+ }
+ dkct_tr_delete(psrc); psrc = NULL;
+ } else {
+ /* ERROR: Memory! */
+ pComm->addWxText(sTexts[63]);
+ pComm->nl();
+ } $? ". before addWxText"
+ pComm->addWxText(sTexts[(ok) ? 56 : 57]); $? ". after addWxText"
+ pComm->nl();
+ pComm->nl();
+ } else { $? "! name conversion failed"
+ /* ERROR: Can not convert file name to 8-bit characters plain! */
+ pComm->addWxText(sTexts[61]);
+ pComm->addDkText(fn);
+ pComm->addWxText(sTexts[62]);
+ pComm->nl();
+ } $? "- runForFile"
+}
+
+
+
+void
+DkWxTraceThread::checkAndRunFile(dkChar const *fn, int sufi)
+{
+ dkChar b1[DK3_MAX_PATH];
+ dkChar *xsu;
+ dkChar const *pstart;
+ dkChar const * const *lfdsu;
+ $? "+ checkAndRunFile"
+ int must_run = 1;
+ if(dkcto.mak) { $? ". make mode, check"
+ /* Check whether we really need to run */
+ if(dk3str_len(fn) < DK3_SIZEOF(b1,dkChar)) {
+ dk3str_cpy(b1, fn);
+ lfdsu = (dkct_str_get_dest_suffixes())[sufi];
+ xsu = dk3str_get_suffix(b1);
+ if(xsu) {
+ must_run = 0;
+ while(*lfdsu) {
+ *xsu = dkT('\0');
+ if((dk3str_len(b1) + dk3str_len(*lfdsu)) < DK3_SIZEOF(b1,dkChar)) {
+ dk3str_cat(b1, *lfdsu);
+ if(dk3sf_must_rebuild(b1,fn)) {
+ must_run = 1;
+ }
+ } else {
+ must_run = 1;
+ }
+ lfdsu++;
+ }
+ }
+ }
+ }
+ if(must_run) { $? ". must run"
+ runForFile(fn, sufi);
+ } else {
+ /* Up to date. */
+ pstart = dk3str_rchr(fn, DK3_CHAR_SEP);
+ if(pstart) { pstart++; } else { pstart = fn; }
+ pComm->addDkText(pstart);
+ pComm->addWxText(wxdkct_trace_thread_string_colon);
+ pComm->nl();
+ pComm->addWxText(sTexts[55]);
+ pComm->nl();
+ pComm->nl();
+ } $? "- checkAndRunFile"
+}
+
+
+
+void
+DkWxTraceThread::runForDirectory(wxChar const *dirname)
+{
+ dkChar bu[DK3_MAX_PATH];
+ wxChar fnb[DK3_MAX_PATH];
+ dk3_dir_t *dir;
+ dkChar const *en;
+ dkChar const *su;
+ dk3_stat_t const *es;
+ dk3_um_t nFiles;
+ dk3_um_t cFile;
+ dk3_um_t promille;
+ int ai;
+ int cc;
+ $? "+ runForDirectory \"%ls\"", dirname
+ cFile = DK3_UM_0;
+ cc = 1;
+ if(dk3wxs_to_dkstr(bu, DK3_SIZEOF(bu,dkChar), dke, dirname, wxe)) {
+ $? ". conversion ok"
+ dir = dk3dir_open_app(bu, app);
+ if(dir) { $? ". dir opened"
+ nFiles = dk3dir_get_number_of_files(dir);
+ if(!(nFiles)) nFiles++;
+ while(cc) { $? ". start of loop"
+ cc = 0;
+ if(dk3dir_get_next_file(dir)) { $? ". yet another file"
+ cc = 1;
+ if(cFile > nFiles) cFile = nFiles;
+ promille = ((dk3_um_t)1000UL * cFile) / nFiles;
+ en = dk3dir_get_fullname(dir);
+ es = dk3dir_get_stat(dir);
+ if((en) && (es)) { $? ". file name and stat ok"
+ if(dk3wxs_from_dkstr(fnb, DK3_SIZEOF(fnb,wxChar), wxe, en, dke)) {
+ pComm->setUpdates(fnb, promille);
+ }
+ switch((es->ft) & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_REGULAR: { $? ". regular file"
+ su = dk3str_get_suffix(en);
+ if(su) {
+#if DK3_ON_WINDOWS || DK3_HAVE_FNCASEINS
+ ai = dk3str_array_index(dkct_str_get_source_suffixes(), su, 0);
+#else
+ ai = dk3str_array_index(dkct_str_get_source_suffixes(), su, 1);
+#endif
+ if(ai >= 0) {
+ checkAndRunFile(en, ai);
+ }
+ }
+ } break;
+ }
+ }
+ cFile++;
+ }
+ if(!(pComm->getCanContinue())) {
+ cc = 0;
+ }
+ }
+ dk3dir_close(dir);
+ } else { $? "! failed to open directory"
+ /* ERROR: Failed to open directory! */
+ pComm->addWxText(sTexts[59]);
+ pComm->addWxText(dirname);
+ pComm->addWxText(sTexts[60]);
+ pComm->nl();
+ }
+ } else { $? "! conversion failed"
+ /* ERROR: Filename conversion failed! */
+ pComm->addWxText(sTexts[58]);
+ pComm->nl();
+ } $? "- runForDirectory"
+}
+
+
+
+void *
+DkWxTraceThread::Entry()
+{
+ $? "+ Entry"
+#if 0
+ /*
+ Simple test thread witout practical use.
+ */
+ int i = 0;
+ int cc = 1;
+ int numbreak = -1;
+ do {
+ this->Sleep(100);
+ i++;
+ if(i >= 100) {
+ cc = 0;
+ }
+ pComm->setUpdates(testfilename, (10*i));
+ if(pComm->getCanContinue() == 0) {
+ if(numbreak == -1) {
+ numbreak = i;
+ } else {
+ if(i >= numbreak + 15) {
+ cc = 0;
+ }
+ }
+ }
+ pComm->addWxText(wxT("Test mit einer ganz ganz ganz ganz langen Zeile\n"));
+ } while(cc);
+ pComm->setRunning(0);
+#else
+ /*
+ Start message
+ */
+ pComm->addWxText(sTexts[54]);
+ if(sDirectory) {
+ pComm->addWxText(sDirectory);
+ } else {
+ pComm->addWxText(sTexts[25]);
+ }
+ pComm->nl();
+ runForDirectory((sDirectory) ? sDirectory : sTexts[25]);
+ /*
+ Signal finished.
+ */
+ pComm->setRunning(0);
+#endif
+ $? "- Entry"
+ return NULL;
+}
+
+
+
+void
+DkWxTraceThread::OnExit()
+{
+}
+
+
+
+
diff --git a/support/dktools/DkWxTraceThread.h b/support/dktools/DkWxTraceThread.h
new file mode 100644
index 0000000000..9f5d725579
--- /dev/null
+++ b/support/dktools/DkWxTraceThread.h
@@ -0,0 +1,152 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: DkWxTraceThread.cpt
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file DkWxTraceThread.h Header file for the DkWxTraceThread module.
+*/
+
+#ifndef DKWXTRACETHREAD_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DKWXTRACETHREAD_H_INCLUDED 1
+
+
+#line 10 "DkWxTraceThread.cpt"
+
+#include "dkwxtrace.h"
+
+
+
+#line 14 "DkWxTraceThread.cpt"
+
+
+
+/** Worker thread for wxdkct.
+*/
+class DkWxTraceThread : public wxThread
+{
+ protected:
+
+ /** Conversion option set.
+ */
+ DKCT_OPTION_SET dkcto;
+
+ /** Communication object between main thread and worker thread.
+ */
+ DkWxCommunicator *pComm;
+
+ /** Localized text messages.
+ */
+ wxChar const * const *sTexts;
+
+ /** Localized dkChar messages.
+ */
+ dkChar const * const *msg;
+
+ /** Directory to process.
+ */
+ wxChar const *sDirectory;
+
+ /** Application helper.
+ */
+ DkWxAppHelper *pHelper;
+
+ /** Application structure.
+ */
+ dk3_app_t *app;
+
+ /** Encoding used for wxChar.
+ */
+ int wxe;
+
+ /** Encoding used for dkChar.
+ */
+ int dke;
+
+ /** Run for one file.
+ @param fn File name.
+ @param sufi Suffix index.
+ */
+ void
+ runForFile(dkChar const *fn, int sufi);
+
+ /** Check one file, run if necessary.
+ @param fn File name.
+ @param sufi Suffix index.
+ */
+ void
+ checkAndRunFile(dkChar const *fn, int sufi);
+
+ /** Run for directory.
+ @param dirname Directory name.
+ */
+ void
+ runForDirectory(wxChar const *dirname);
+
+ public:
+
+ /** Constructor
+ @param comm Communication object.
+ @param texts Localized messages texts.
+ @param ms Localized dkChar message texts.
+ @param directory Directory to process.
+ @param ah Application helper.
+ @param o Conversion option set.
+ @param we Encoding for wxChar.
+ @param de Encoding for dkChar.
+ */
+ DkWxTraceThread(
+ DkWxCommunicator *comm,
+ wxChar const * const *texts,
+ dkChar const * const *ms,
+ wxChar const *directory,
+ DkWxAppHelper *ah,
+ DKCT_OPTION_SET *o,
+ int we,
+ int de
+ );
+
+ /** Thread function.
+ @return A pointer which is ignored.
+ */
+ virtual void *Entry();
+
+ /** Function executed at the end of thread, does nothing.
+ */
+ virtual void OnExit();
+
+};
+
+
+
+#endif
diff --git a/support/dktools/Doxyfile b/support/dktools/Doxyfile
new file mode 100644
index 0000000000..c694875970
--- /dev/null
+++ b/support/dktools/Doxyfile
@@ -0,0 +1,2362 @@
+# Doxyfile 1.8.8
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# 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 single 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.
+# The default value is: UTF-8.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
+# double-quotes, unless you are using Doxywizard) that should identify the
+# project for which the documentation is generated. This name is used in the
+# title of most generated pages and in a few other places.
+# The default value is: My Project.
+
+PROJECT_NAME = dktools-4
+
+# 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 = 4.8.3
+
+# 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 = Tools and libraries
+
+# 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) path
+# into which the generated documentation will be written. 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 = ./doc/doxygen
+
+# 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 causes
+# performance problems for the file system.
+# The default value is: NO.
+
+CREATE_SUBDIRS = NO
+
+# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
+# characters to appear in the names of generated files. If set to NO, non-ASCII
+# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
+# U+3044.
+# The default value is: NO.
+
+ALLOW_UNICODE_NAMES = NO
+
+# 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.
+# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
+# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
+# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
+# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
+# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
+# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
+# Ukrainian and Vietnamese.
+# The default value is: English.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES 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.
+# The default value is: YES.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES 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.
+# The default value is: YES.
+
+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 and 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.
+# The default value is: NO.
+
+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.
+# The default value is: NO.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES 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
+# The default value is: YES.
+
+FULL_PATH_NAMES = YES
+
+# 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 can specify absolute paths here, but also relative paths, which
+# will be relative from the directory where doxygen is started.
+# This tag requires that the tag FULL_PATH_NAMES is set to YES.
+
+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 list of 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.
+# The default value is: NO.
+
+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-style will behave just like regular Qt-
+# style comments (thus requiring an explicit @brief command for a brief
+# description.)
+# The default value is: NO.
+
+JAVADOC_AUTOBRIEF = YES
+
+# 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 Qt-style will behave just like regular Qt-style comments (thus
+# requiring an explicit \brief command for a brief description.)
+# The default value is: NO.
+
+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 behavior. 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 behavior instead.
+#
+# Note that setting this tag to YES also means that rational rose comments are
+# not recognized any more.
+# The default value is: NO.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
+# documentation from any documented member that it re-implements.
+# The default value is: YES.
+
+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.
+# The default value is: NO.
+
+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.
+# Minimum value: 1, maximum value: 16, default value: 4.
+
+TAB_SIZE = 8
+
+# This tag can be used to specify a number of aliases that act 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 =
+
+# 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.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
+# Python sources only. Doxygen will then generate output that is more tailored
+# for that language. For instance, namespaces will be presented as packages,
+# qualified scopes will look different, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources. Doxygen will then generate output that is tailored for Fortran.
+# The default value is: NO.
+
+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.
+# The default value is: NO.
+
+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 (fixed format Fortran:
+# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
+# Fortran. In the later case the parser tries to guess whether the code is fixed
+# or free formatted code, this is the default for Fortran type files), VHDL. 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 For files without extension you can use no_extension as a placeholder.
+#
+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
+# the files are not read by doxygen.
+
+EXTENSION_MAPPING =
+
+# If the MARKDOWN_SUPPORT tag is enabled 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.
+# The default value is: YES.
+
+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.
+# The default value is: YES.
+
+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);
+# versus func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+# The default value is: NO.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+# The default value is: NO.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
+# http://www.riverbankcomputing.co.uk/software/sip/intro) 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.
+# The default value is: NO.
+
+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 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.
+# The default value is: YES.
+
+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.
+# The default value is: NO.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES 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.
+# The default value is: YES.
+
+SUBGROUPING = YES
+
+# 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).
+#
+# Note that this feature does not work in combination with
+# SEPARATE_MEMBER_PAGES.
+# The default value is: NO.
+
+INLINE_GROUPED_CLASSES = NO
+
+# 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, structs, classes, and unions are shown on a separate page (for HTML and
+# Man pages) or section (for LaTeX and RTF).
+# The default value is: NO.
+
+INLINE_SIMPLE_STRUCTS = NO
+
+# When TYPEDEF_HIDES_STRUCT tag 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.
+# The default value is: NO.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+# 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 appears 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. At the end of a run doxygen will report the cache usage and suggest
+# the optimal cache size from a speed point of view.
+# Minimum value: 0, maximum value: 9, default value: 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 respectively EXTRACT_STATIC tags are set to YES.
+# Note: This will also disable the warnings about undocumented members that are
+# normally produced when WARNINGS is set to YES.
+# The default value is: NO.
+
+EXTRACT_ALL = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will
+# be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal
+# scope will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PACKAGE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file will be
+# included in the documentation.
+# The default value is: NO.
+
+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. Does not have any effect
+# for Java sources.
+# The default value is: YES.
+
+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 only methods in the interface are
+# included.
+# The default value is: NO.
+
+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.
+# The default value is: NO.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
+# undocumented members inside documented classes or files. If set to NO 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.
+# The default value is: NO.
+
+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 these classes will be included in the various overviews. This option has
+# no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+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 these declarations will be
+# included in the documentation.
+# The default value is: NO.
+
+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 these
+# blocks will be appended to the function's detailed documentation block.
+# The default value is: NO.
+
+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 then the documentation
+# will be excluded. Set it to YES to include the internal documentation.
+# The default value is: NO.
+
+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.
+# The default value is: system dependent.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
+# their full class and namespace scopes in the documentation. If set to YES the
+# scope will be hidden.
+# The default value is: NO.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
+# the files that are included by a file in the documentation of that file.
+# The default value is: YES.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
+# grouped member an include statement to the documentation, telling the reader
+# which file to include in order to use the member.
+# The default value is: NO.
+
+SHOW_GROUPED_MEMB_INC = NO
+
+# 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.
+# The default value is: NO.
+
+FORCE_LOCAL_INCLUDES = NO
+
+# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
+# documentation for inline members.
+# The default value is: YES.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES 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.
+# The default value is: YES.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
+# descriptions of file, namespace and class members alphabetically by member
+# name. If set to NO the members will appear in declaration order. Note that
+# this will also influence the order of the classes in the class list.
+# The default value is: NO.
+
+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 constructors will appear in the
+# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
+# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
+# member documentation.
+# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
+# detailed member documentation.
+# The default value is: 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 group names will
+# appear in their defined order.
+# The default value is: NO.
+
+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 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.
+# The default value is: NO.
+
+SORT_BY_SCOPE_NAME = NO
+
+# 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.
+# The default value is: NO.
+
+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.
+# The default value is: YES.
+
+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 commands in the
+# documentation.
+# The default value is: YES.
+
+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.
+# The default value is: YES.
+
+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.
+# The default value is: YES.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# 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 =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
+# initial value of a variable or macro / define can have 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 value of individual variables and macros / defines can be
+# controlled using \showinitializer or \hideinitializer command in the
+# documentation regardless of this setting.
+# Minimum value: 0, maximum value: 10000, default value: 30.
+
+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.
+# The default value is: YES.
+
+SHOW_USED_FILES = YES
+
+# 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 value 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 value 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 command input-file, where command is the value of the
+# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
+# by doxygen. Whatever the program writes to standard output is used as the file
+# version. For an example see the documentation.
+
+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. 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.
+#
+# Note that if you run doxygen from a directory containing a file called
+# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
+# tag is left empty.
+
+LAYOUT_FILE =
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
+# the reference definitions. This must be a list of .bib files. The .bib
+# extension is automatically appended if omitted. This 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. See also \cite for info how to create references.
+
+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 to
+# standard output by doxygen. If QUIET is set to YES this implies that the
+# messages are off.
+# The default value is: NO.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES
+# this implies that the warnings are on.
+#
+# Tip: Turn warnings on while writing the documentation.
+# The default value is: YES.
+
+WARNINGS = YES
+
+# If the WARN_IF_UNDOCUMENTED tag 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.
+# The default value is: YES.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If the WARN_IF_DOC_ERROR tag 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.
+# The default value is: YES.
+
+WARN_IF_DOC_ERROR = YES
+
+# This 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 doxygen will only warn about wrong or incomplete parameter
+# documentation, but not about the absence of documentation.
+# The default value is: NO.
+
+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)
+# The default value is: $file:$line: $text.
+
+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 standard
+# error (stderr).
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag is 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.
+# Note: If this tag is empty the current directory is searched.
+
+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. Doxygen uses
+# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
+# documentation (see: http://www.gnu.org/software/libiconv) for the list of
+# possible encodings.
+# The default value is: UTF-8.
+
+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 patterns (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, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp,
+# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown,
+# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf,
+# *.qsf, *.as and *.js.
+
+FILE_PATTERNS = dk4*.h \
+ *.dox \
+ Dk4Wx*.h \
+ dk3trace.h
+
+# The RECURSIVE tag can be used to specify whether or not subdirectories should
+# be searched for input files as well.
+# The default value is: NO.
+
+RECURSIVE = NO
+
+# 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 = config.h \
+ test* \
+ dk4svg*
+
+# 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.
+# The default value is: NO.
+
+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 = dk4serf.h
+
+# 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
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories use the pattern */test/*
+
+EXCLUDE_SYMBOLS = HAVE_* \
+ DK4_HAVE_* \
+ *_INC \
+ *_INCLUDED
+
+# 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 = .
+
+# 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.
+# The default value is: NO.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or directories
+# that contain images that are to be 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:
+#
+# <filter> <input-file>
+#
+# where <filter> is the value of the INPUT_FILTER tag, and <input-file> 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 =
+
+# 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 information on how
+# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
+# patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER ) will also be used to filter the input files that are used for
+# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
+# The default value is: NO.
+
+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 tag requires that the tag FILTER_SOURCE_FILES is set to YES.
+
+FILTER_SOURCE_PATTERNS =
+
+# If the USE_MDFILE_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 to 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 that
+# also VERBATIM_HEADERS is set to NO.
+# The default value is: NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body of functions,
+# classes and enums directly into the documentation.
+# The default value is: NO.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
+# special comment blocks from generated source code fragments. Normal C, C++ and
+# Fortran comments will always remain visible.
+# The default value is: YES.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
+# function all documented functions referencing it will be listed.
+# The default value is: NO.
+
+REFERENCED_BY_RELATION = NO
+
+# 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.
+# The default value is: NO.
+
+REFERENCES_RELATION = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES 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.
+# The default value is: YES.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+# source code will show a tooltip with additional information such as prototype,
+# brief description and links to the definition and documentation. Since this
+# will make the HTML file larger and loading of large files a bit slower, you
+# can opt to disable this feature.
+# The default value is: YES.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+SOURCE_TOOLTIPS = 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 will need version
+# 4.8.6 or higher.
+#
+# To use it do the following:
+# - Install the latest version of global
+# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
+# - Make sure the INPUT points to the root of the source tree
+# - Run doxygen as normal
+#
+# Doxygen will invoke htags (and that will in turn invoke gtags), so these
+# tools must be available from the command line (i.e. in the search path).
+#
+# The result: instead of the source browser generated by doxygen, the links to
+# source code will now point to the output of htags.
+# The default value is: NO.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set the YES 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.
+# See also: Section \class.
+# The default value is: YES.
+
+VERBATIM_HEADERS = YES
+
+# If the CLANG_ASSISTED_PARSING tag is set to YES, then doxygen will use the
+# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
+# cost of reduced performance. This can be particularly helpful with template
+# rich C++ code for which doxygen's built-in parser lacks the necessary type
+# information.
+# Note: The availability of this option depends on whether or not doxygen was
+# compiled with the --with-libclang option.
+# The default value is: NO.
+
+CLANG_ASSISTED_PARSING = NO
+
+# If clang assisted parsing is enabled you can provide the compiler with command
+# line options that you would normally use when invoking the compiler. Note that
+# the include paths will already be set by doxygen for the files and directories
+# specified with INPUT and INCLUDE_PATH.
+# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
+
+CLANG_OPTIONS =
+
+#---------------------------------------------------------------------------
+# 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.
+# The default value is: YES.
+
+ALPHABETICAL_INDEX = NO
+
+# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
+# which the alphabetical index list will be split.
+# Minimum value: 1, maximum value: 20, default value: 5.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+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 a prefix (or a list of prefixes) that should be ignored
+# while generating the index headers.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output
+# The default value is: YES.
+
+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.
+# The default directory is: html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+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).
+# The default value is: .html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
+# each generated HTML page. If the tag is left blank doxygen will generate a
+# standard header.
+#
+# To get valid HTML the header file that includes any scripts and style sheets
+# that doxygen needs, which is dependent on the configuration options used (e.g.
+# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
+# default header using
+# doxygen -w html new_header.html new_footer.html new_stylesheet.css
+# YourConfigFile
+# and then modify the file new_header.html. See also section "Doxygen usage"
+# for information on how to generate the default header that doxygen normally
+# uses.
+# Note: The header is subject to change so you typically have to regenerate the
+# default header when upgrading to a newer version of doxygen. For a description
+# of the possible markers and block names see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
+# generated HTML page. If the tag is left blank doxygen will generate a standard
+# footer. See HTML_HEADER for more information on how to generate a default
+# footer and what special commands can be used inside the footer. See also
+# section "Doxygen usage" for information on how to generate the default footer
+# that doxygen normally uses.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+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 left blank doxygen will generate a default style sheet.
+# See also section "Doxygen usage" for information on how to generate the style
+# sheet that doxygen normally uses.
+# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
+# it is more robust and this tag (HTML_STYLESHEET) will in the future become
+# obsolete.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_STYLESHEET =
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# cascading style sheets that are 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 files to the output directory.
+# Note: The order of the extra stylesheet files is of importance (e.g. the last
+# stylesheet in the list overrules the setting of the previous ones in the
+# list). For an example see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+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.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_FILES =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
+# will adjust the colors in the stylesheet 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.
+# Minimum value: 0, maximum value: 359, default value: 220.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+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.
+# Minimum value: 0, maximum value: 255, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+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.
+# Minimum value: 40, maximum value: 240, default value: 80.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+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.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_TIMESTAMP = NO
+
+# 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.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# 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.
+# Minimum value: 0, maximum value: 9999, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+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 (see: http://developer.apple.com/tools/xcode/), 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.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_DOCSET = NO
+
+# This tag determines the name of the docset 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.
+# The default value is: Doxygen generated docs.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# 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.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# The DOCSET_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.
+# The default value is: org.doxygen.Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_ID = org.doxygen.Publisher
+
+# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+# The default value is: Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_NAME = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
+# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
+# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
+# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
+# Windows.
+#
+# The HTML Help Workshop contains a compiler that can convert all HTML output
+# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
+# files are now used as the Windows 98 help format, and will replace the old
+# Windows help format (.hlp) on all Windows platforms in the future. Compressed
+# HTML files also contain an index, a table of contents, and you can search for
+# words in the documentation. The HTML workshop also contains a viewer for
+# compressed HTML files.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_HTMLHELP = 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.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_FILE = dk4.chm
+
+# 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.
+# The file has to be specified with full path.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+HHC_LOCATION =
+
+# 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).
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+GENERATE_CHI = NO
+
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc)
+# and project file content.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_INDEX_ENCODING =
+
+# 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. Furthermore it
+# enables the Previous and Next buttons.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members to
+# the table of contents of the HTML help documentation and to the tree view.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+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.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+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.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QCH_FILE =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
+# Project output. For more information please see Qt Help Project / Namespace
+# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_NAMESPACE =
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
+# Help Project output. For more information please see Qt Help Project / Virtual
+# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
+# folders).
+# The default value is: doc.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_VIRTUAL_FOLDER = doc
+
+# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
+# filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_NAME =
+
+# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+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 (see:
+# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_SECT_FILTER_ATTRS =
+
+# 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.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHG_LOCATION =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
+# generated, together with the HTML files, they 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.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+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. Each documentation set should have its own identifier.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
+
+ECLIPSE_DOC_ID = org.doxygen.Project
+
+# If you want full control over the layout of the generated HTML pages it might
+# be necessary to disable the index and replace it with your own. The
+# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
+# of each HTML page. A value of NO enables the index and the value YES disables
+# it. Since the tabs in the index contain the same information as the navigation
+# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+DISABLE_INDEX = NO
+
+# 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. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can
+# further fine-tune the look of the index. As an example, the default style
+# sheet generated by doxygen has an example that shows how to put an image at
+# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
+# the same information as the tab index, you could consider setting
+# DISABLE_INDEX to YES when enabling this option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_TREEVIEW = NO
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values 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.
+# Minimum value: 0, maximum value: 20, default value: 4.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+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 is shown.
+# Minimum value: 0, maximum value: 1500, default value: 250.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+TREEVIEW_WIDTH = 250
+
+# 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.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+EXT_LINKS_IN_WINDOW = NO
+
+# Use this tag to change the font size of LaTeX formulas included as images in
+# the HTML documentation. 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.
+# Minimum value: 8, maximum value: 50, default value: 10.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+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 directory before the changes have effect.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+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.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+USE_MATHJAX = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. See the MathJax site (see:
+# http://docs.mathjax.org/en/latest/output.html) for more details.
+# Possible values are: HTML-CSS (which is slower, but has the best
+# compatibility), NativeMML (i.e. MathML) and SVG.
+# The default value is: HTML-CSS.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+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.
+# The default value is: http://cdn.mathjax.org/mathjax/latest.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
+# extension names that should be enabled during MathJax rendering. For example
+# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+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. See the MathJax site
+# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
+# example see the documentation.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_CODEFILE =
+
+# 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. It is possible to
+# search using the keyboard; to jump to the search box use <access key> + S
+# (what the <access key> is depends on the OS and browser, but it is typically
+# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
+# key> to jump into the search results window, the results can be navigated
+# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
+# the search. The filter options can be selected when the cursor is inside the
+# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
+# to select a filter and <Enter> or <escape> to activate or cancel the filter
+# option.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+SEARCHENGINE = NO
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a web server instead of a web client using Javascript. There
+# are two flavors of web server based searching 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 section
+# "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SERVER_BASED_SEARCH = NO
+
+# When EXTERNAL_SEARCH tag 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: http://xapian.org/).
+#
+# See the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will return the search results when EXTERNAL_SEARCH is enabled.
+#
+# Doxygen ships with an example indexer ( doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/). See the section "External Indexing and
+# Searching" for details.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+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.
+# The default file is: searchdata.xml.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+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.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+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 = tagname1=loc1 tagname2=loc2 ...
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTRA_SEARCH_MAPPINGS =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output.
+# The default value is: YES.
+
+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.
+# The default directory is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked.
+#
+# 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.
+# The default file is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
+# index for LaTeX.
+# The default file is: makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+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.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+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 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
+# 14 inches) and executive (7.25 x 10.5 inches).
+# The default value is: a4.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
+# that should be included in the LaTeX output. To get the times font for
+# instance you can specify
+# EXTRA_PACKAGES=times
+# If left blank no extra packages will be included.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+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. See
+# section "Doxygen usage" for information on how to let doxygen write the
+# default header to a separate file.
+#
+# Note: Only use a user-defined header if you know what you are doing! The
+# following commands have a special meaning inside the header: $title,
+# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
+# $projectbrief, $projectlogo. Doxygen will replace $title with the empy string,
+# for the replacement values of the other commands the user is refered to
+# HTML_HEADER.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HEADER =
+
+# 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. See
+# LATEX_HEADER for more information on how to generate a default footer and what
+# special commands can be used inside the footer.
+#
+# Note: Only use a user-defined footer if you know what you are doing!
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+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 output
+# directory. Note that the files will be copied as-is; there are no commands or
+# markers available.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+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 or pdflatex). 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.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PDF_HYPERLINKS = YES
+
+# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
+# the PDF file directly from the LaTeX files. Set this option to YES to get a
+# higher quality PDF documentation.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+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. This option is also used
+# when generating formulas in HTML.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BATCHMODE = NO
+
+# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
+# index chapters (such as File Index, Compound Index, etc.) in the output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HIDE_INDICES = NO
+
+# If the LATEX_SOURCE_CODE tag 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.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+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. See
+# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
+# The default value is: plain.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+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 too pretty with other RTF
+# readers/editors.
+# The default value is: NO.
+
+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.
+# The default directory is: rtf.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+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.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+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 some other Word compatible readers that support those
+# fields.
+#
+# Note: WordPad (write) and others do not support links.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+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.
+#
+# See also section "Doxygen usage" for information on how to generate the
+# default style sheet that doxygen normally uses.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an RTF document. Syntax is
+# similar to doxygen's config file. A template extensions file can be generated
+# using doxygen -e rtf extensionFile.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES doxygen will generate man pages for
+# classes and files.
+# The default value is: NO.
+
+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. A directory man3 will be created inside the directory specified by
+# MAN_OUTPUT.
+# The default directory is: man.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to the generated
+# man pages. In case the manual section does not start with a number, the number
+# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
+# optional.
+# The default value is: .3.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_EXTENSION = .3
+
+# The MAN_SUBDIR tag determines the name of the directory created within
+# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
+# MAN_EXTENSION with the initial . removed.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_SUBDIR =
+
+# 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 value is: NO.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+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.
+# The default value is: NO.
+
+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.
+# The default directory is: xml.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_OUTPUT = xml
+
+# 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.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+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.
+# The default value is: NO.
+
+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.
+# The default directory is: docbook.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_OUTPUT = docbook
+
+# If the DOCBOOK_PROGRAMLISTING tag is set to YES doxygen will include the
+# program listings (including syntax highlighting and cross-referencing
+# information) to the DOCBOOK output. Note that enabling this will significantly
+# increase the size of the DOCBOOK output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_PROGRAMLISTING = NO
+
+#---------------------------------------------------------------------------
+# Configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES doxygen will generate an AutoGen
+# Definitions (see http://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.
+# The default value is: NO.
+
+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.
+# The default value is: NO.
+
+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.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+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.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+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.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES doxygen will evaluate all
+# C-preprocessor directives found in the sources and include files.
+# The default value is: YES.
+
+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 only conditional compilation will be
+# performed. Macro expansion can be done in a controlled way by setting
+# EXPAND_ONLY_PREDEF to YES.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set 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.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES the includes files in the
+# INCLUDE_PATH will be searched if a #include is found.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+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.
+# This tag requires that the tag SEARCH_INCLUDES is set to YES.
+
+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.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+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 e.g.
+# 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.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+PREDEFINED = HAVE_CONFIG_H=1 \
+ __cplusplus \
+ WXUNUSED(x)=x
+
+# 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.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_AS_DEFINED = WXUNUSED
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES 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. Such function macros
+# are typically used for boiler-plate code, and will confuse the parser if not
+# removed.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tag files. 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. See the
+# section "Linking to external documentation" for more information about the use
+# of tag files.
+# Note: 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. See section "Linking to
+# external documentation" for more information about the usage of tag files.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external class will be listed in the
+# class index. If set to NO only the inherited external classes will be listed.
+# The default value is: NO.
+
+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.
+# The default value is: YES.
+
+EXTERNAL_GROUPS = YES
+
+# 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.
+# The default value is: YES.
+
+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').
+# The default file (with absolute path) is: /usr/bin/perl.
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES doxygen will generate a class diagram
+# (in HTML 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.
+# The default value is: YES.
+
+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 =
+
+# You can include diagrams made with dia in doxygen documentation. Doxygen will
+# then run dia to produce the diagram and insert it in the documentation. The
+# DIA_PATH tag allows you to specify the directory where the dia binary resides.
+# If left empty dia is assumed to be found in the default search path.
+
+DIA_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.
+# The default value is: YES.
+
+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 (see:
+# http://www.graphviz.org/), 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 value is: YES.
+
+HAVE_DOT = YES
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
+# to run in parallel. When set to 0 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.
+# Minimum value: 0, maximum value: 32, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_NUM_THREADS = 0
+
+# When you want a differently looking font in the dot files that doxygen
+# generates 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.
+# The default value is: Helvetica.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+# DOT_FONTNAME = FreeSans
+
+# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
+# dot graphs.
+# Minimum value: 4, maximum value: 24, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTSIZE = 10
+
+# By default doxygen will tell dot to use the default font as specified with
+# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
+# the path where dot can find it using this tag.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTPATH =
+
+# If the CLASS_GRAPH tag is 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.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH tag is 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.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
+# groups, showing the direct groups dependencies.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+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.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LOOK = NO
+
+# 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. So when you set the threshold to 10, up to 15 fields may appear,
+# but if the number exceeds 15, the total amount of fields shown is limited to
+# 10.
+# Minimum value: 0, maximum value: 100, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LIMIT_NUM_FIELDS = 10
+
+# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
+# collaboration graphs will show the relations between templates and their
+# instances.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+TEMPLATE_RELATIONS = NO
+
+# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES 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.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDE_GRAPH = YES
+
+# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES 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.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+# INCLUDED_BY_GRAPH = YES
+INCLUDED_BY_GRAPH = NO
+# If the CALL_GRAPH tag is 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.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH tag is 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.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
+# hierarchy of all classes instead of a textual one.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH tag is 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.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot.
+# Note: 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).
+# Possible values are: png, png:cairo, png:cairo:cairo, png:cairo:gd, png:gd,
+# png:gd:gd, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd, gif, gif:cairo,
+# gif:cairo:gd, gif:gd, gif:gd:gd and svg.
+# The default value is: png.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_IMAGE_FORMAT = png
+
+# 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.
+# Note: 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.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INTERACTIVE_SVG = NO
+
+# The DOT_PATH tag 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.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+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 \dotfile
+# command).
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOTFILE_DIRS =
+
+# 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 DIAFILE_DIRS tag can be used to specify one or more directories that
+# contain dia files that are included in the documentation (see the \diafile
+# command).
+
+DIAFILE_DIRS =
+
+# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
+# path where java can find the plantuml.jar file. If left blank, it is assumed
+# PlantUML is not used or called during a preprocessing step. Doxygen will
+# generate a warning when it encounters a \startuml command in this case and
+# will not generate output for the diagram.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+PLANTUML_JAR_PATH =
+
+# 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.
+# Minimum value: 0, maximum value: 10000, default value: 50.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+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.
+# Minimum value: 0, maximum value: 1000, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+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).
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+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.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
+# explaining the meaning of the various boxes and arrows in the dot generated
+# graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES doxygen will remove the intermediate dot
+# files that are used to generate the various graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_CLEANUP = YES
diff --git a/support/dktools/INSTALL b/support/dktools/INSTALL
new file mode 100644
index 0000000000..064f245f57
--- /dev/null
+++ b/support/dktools/INSTALL
@@ -0,0 +1,112 @@
+1 Installation on UNIX systems
+1.1 Direct installation from source
+1.2 Installation via RPM
+1.3 Installation via DEB
+2 Installation on Windows systems
+
+1 Installation on UNIX systems
+==============================
+
+1.1 Direct installation from source
+-----------------------------------
+After unpacking the software change into the source directory and run
+
+ ./configure
+ make
+ make install
+
+For help on configure script options, run
+
+ ./configure --help
+
+If you have LPRng installed and you want to use printqd, see the
+``CONFIGURATION'' section in printqd(1). Some directories may need
+ownership and permissions correction.
+
+
+1.2 Installation via RPM
+------------------------
+
+If you are building a package for an ``official'' Linux distribution:
+If the distribution includes the LPRng software, find user and group name
+used to run the LPRng lpd daemon and activate and correct LPUSER and
+LPGROUP in the dktools.spec file in the LINUX DISTRIBUTION PACKAGERS section.
+
+Manual steps
+~~~~~~~~~~~~
+
+The archive contains *.spec files for Scientific Linux (should work on
+other Enterprise Linux clones too) and Fedora core.
+Copy the *.spec file to ~/rpmbuild/SPECS and the dktools-*.tar.gz file
+to ~/rpmbuild/SOURCES.
+Change into the ~/rpmbuild/SPECS directory and run
+
+ rpmbuild -ba dktools.spec
+
+You must be root to install the *.rpm file, change into the
+rpmbuild/RPMS/<architecture> directory and run
+
+ rpm --force -Uhv dktools-<version>-.rpm dktools-debuginfo-<version>.rpm
+
+Use scripts
+~~~~~~~~~~~
+
+The scripts below were created and tested on Scientific Linux 6.
+
+As root run
+ ./sl6-prepare.sh
+to install development tools and development files for required libraries.
+
+As non-privileged user run
+ ./sl6-build-rpm.sh
+to build the RPM file.
+
+
+1.3 Installation via DEB
+------------------------
+The archive contains a ``debian'' subdirectory and two scripts to create
+a *.deb package. The scripts were created and tested on Debian Jessie.
+
+If you are building a package for an ``official'' Linux distribution:
+If the distribution includes the LPRng software, find user and group name
+used to run the LPRng lpd daemon and activate and correct LPUSER and
+LPGROUP in the debian/postinst file
+in the LINUX DISTRIBUTION PACKAGERS section.
+
+As root run:
+ ./debian-jessie-prepare.sh
+to install required packages (development tools, development packages
+for used libraries).
+
+As non-privileged user run:
+ ./debian-jessie-build-deb.sh
+to build the *.deb files.
+
+You should find several *.deb files in the parent directory:
+(1) dktools-lib-data_x.y.z-1_all.deb
+ Data files for the DK tools shared libraries.
+(2) dktools-data_x.y.z-1_all.deb
+ Data files for the DK tools programs.
+(3) dktools-lib-x.y_x.y.z-1_arch.deb
+ The DK tools shared libraries.
+(4) dktools_x.y.z-1_arch.deb
+ The DK tools programs (requires 1, z, and y).
+(5) dktools-dev_x.y.z-1_arch.deb
+ DK tools developer support (requires 1, 2, and 3).
+On normal systems install (1), (2), (3), and (4). For development install
+(5) too.
+
+2 Installation on Windows systems
+=================================
+
+Windows users should obtain dktools-win64-*.exe from the dktools project
+at SourceForge, see
+
+ http://sourceforge.net/projects/dktools
+
+for the download.
+Run the installer and follow the instructions.
+
+See http://dktools.sourceforge.net/install.html for details about the
+installation process.
+
diff --git a/support/dktools/LICENSE b/support/dktools/LICENSE
new file mode 100644
index 0000000000..e3b369c021
--- /dev/null
+++ b/support/dktools/LICENSE
@@ -0,0 +1,19 @@
+1. DK tools and libraries
+2. Live systems created using the scripts from this archive
+
+
+1. DK tools and libraries
+-------------------------
+A 3 clauses BSD style license is used for the "DK tools and libraries"
+project in this archive, see the "bsdlic.txt" file in this archive.
+
+
+2. Live systems created using the scripts from this archive
+-----------------------------------------------------------
+This archive also contains scripts to build live systems based on
+Debian GNU/Linux. The live systems are derived from Debian GNU/Linux,
+the scripts are just helpers to create them.
+So the license conditions for the live systems are exactly the same as
+for the original Debian GNU/Linux.
+The exact distribution terms for each program in the live system are described
+in the individual files in /usr/share/doc/*/copyright.
diff --git a/support/dktools/Makefile b/support/dktools/Makefile
new file mode 100644
index 0000000000..91fff5f4aa
--- /dev/null
+++ b/support/dktools/Makefile
@@ -0,0 +1,3069 @@
+#! /usr/bin/make -f
+# -*- makefile -*-
+
+# GETTING HELP
+# ============
+# Run
+# make help
+# to see a list of Makefile targets.
+
+# INSTALLATION
+# ============
+# The usual triple
+# ./configure
+# make
+# make install
+# should be used to install this software.
+#
+
+# PACKAGES
+# ========
+# Alternatively you can build packages.
+#
+# For RHEL6 and clones:
+# ---------------------
+# (1) As root run:
+# ./sl6-prepare.sh
+# (2) As unprivileged user run:
+# ./sl6-build-rpm.sh
+# (3) Install the RPM:
+# yum install ~/rpmbuild/RPMS/<arch>/dktools-<version>.rpm
+#
+# For Debian Jessie:
+# ------------------
+# (1) As root run
+# ./debian-jessie-prepare.sh
+# (2) As unprivileged user run
+# ./debian-jessie-build-deb.sh
+# (3) Install the *.deb package(s):
+# dpkg -i ~/.../dktools-<version>.deb
+
+
+# Package prefix, used when building packages
+# DESTDIR=
+
+# Version number, derived from version.txt contents
+VERSNO=4.8.3
+
+# Shared library version, first 2 positions of VERSNO
+SOVERS=4.8
+
+# Base directory for files on SourceForge
+SFBASE="http://sourceforge.net/projects/dktools/files/dktools"
+
+# Path variables set by configure script
+prefix=/usr/local
+datarootdir=${prefix}/share
+exec_prefix=${prefix}
+bindir=${exec_prefix}/bin
+sbindir=${exec_prefix}/sbin
+libexecdir=${exec_prefix}/libexec
+datadir=${datarootdir}
+sysconfdir=${prefix}/etc
+scd=${sysconfdir}
+libdir=${exec_prefix}/lib
+sharedlibdir=${libdir}/shared
+mandir=${datarootdir}/man
+includedir=${prefix}/include
+localstatedir=${prefix}/var
+srcdir=.
+top_srcdir=.
+
+
+# Compiler commands and options set by configure script
+
+# Short OS name as returned by the 'uname -s' command
+UNAME=Linux
+
+# C compiler
+CC=gcc
+
+# C compiler preprocessor
+CPP=gcc -E
+
+# C++ compiler
+CXX=g++
+
+# Linker (we use the C compiler driver here as this adds C runtime
+# libraries automaticlly)
+LD=$(CC)
+
+# Definitions for C and C++ compilers, set to -DHAVE_CONFIG_H by configure
+DEFS=-DHAVE_CONFIG_H
+
+# Options for C compiler preprocessor
+CPPFLAGS=
+
+# Options for C++ compiler
+CXXFLAGS=-g -O2
+
+# Options for C compiler
+CFLAGS=-g -O2
+
+# Options for linker
+LDFLAGS=
+
+# Options for C/C++ compiler preprocessor when compiling modules using
+# wxWidgets
+WXCPPFLAGS=-I/usr/lib/x86_64-linux-gnu/wx/include/gtk2-unicode-3.0 -I/usr/include/wx-3.0 -D_FILE_OFFSET_BITS=64 -DWXUSINGDLL -D__WXGTK__
+
+# C++ compiler options when compiling modules using wxWidgets
+WXCXXFLAGS=-I/usr/lib/x86_64-linux-gnu/wx/include/gtk2-unicode-3.0 -I/usr/include/wx-3.0 -D_FILE_OFFSET_BITS=64 -DWXUSINGDLL -D__WXGTK__ -pthread
+
+# C compilter options when compiling modules using wxWidgets
+WXCFLAGS=-I/usr/lib/x86_64-linux-gnu/wx/include/gtk2-unicode-3.0 -I/usr/include/wx-3.0 -D_FILE_OFFSET_BITS=64 -DWXUSINGDLL -D__WXGTK__ -pthread
+
+# Linker options when building executables using wxWidgets
+WXLDFLAGS=-L/usr/lib/x86_64-linux-gnu -pthread -lwx_gtk2u_xrc-3.0 -lwx_gtk2u_html-3.0 -lwx_gtk2u_qa-3.0 -lwx_gtk2u_adv-3.0 -lwx_gtk2u_core-3.0 -lwx_baseu_xml-3.0 -lwx_baseu_net-3.0 -lwx_baseu-3.0
+
+# ?
+LIBS=
+
+# Relocation path -R... set when compiling using Sun Workshop and
+# LD_LIBRARY_PATH is set
+RPATH=
+RPATHLINK=-Wl,-rpath-link,./
+
+# Set to -Wall when all warnings are required
+CWARN=-Wall
+
+# Libraries and features found by configure script
+
+# Set to -D_LARGEFILE64_SOURCE=1 if there is 64-bit file support available
+# and needs to be activated explicitly
+FS64=-D_LARGEFILE64_SOURCE=1
+
+# Linker option to use zlib if available
+ZLIB=-lz
+
+# Linker option to use bzip2 library if available
+BZLIB=-lbz2
+
+# Linker option to use -lcrypto -lssl if available
+CRYPTO=-lcrypto
+
+# Linker option to use -lxnet, -lsocket or none for TCP/IP functionality
+SOCKLIB=
+
+# Linker option to use -lxnet, -lnsl, -lsocket or none for name services
+NSLLIB=
+
+# Linker options to use tiff, jpeg and png libraries if available
+IMGLIBS=-ltiff -ljpeg -lpng
+
+# Linker options to use Berkeley DB library
+DBLIB=-ldb
+
+# Linker options to use socket library required by DBLIB
+DBLIBSOCK=-ldb
+
+# Linker options to use NetSNMP libraries and required libraries if available
+NETSNMP_LIBS=-Wl,-z,relro -Wl,-z,now -L/usr/lib/x86_64-linux-gnu -lnetsnmp -lcrypto -lm
+
+# Linker option to use pthread library if available
+PTHREADLIB=-lpthread
+
+# Linker option to set path for MySQL library
+MYSQLLDFLAGS=
+
+# Linker option for realtime clock library
+RTLIB=-lrt
+
+# AR program to build an archive (a library)
+AR=ar
+
+# NM program to list symbols from a library
+NM=nm
+
+# RANLIB program to create archive (library) index, only required on
+# some platforms
+RANLIB=ranlib
+
+# Command to create soft links
+LN_S=ln -s
+
+# The make program to build projects
+MAKE=make
+
+# File name extension for executable files
+EXEEXT=
+
+# File name extension for object files
+OBJEXT=o
+
+# List of CLI programs using the NetSNMP libraries
+CLI_SNMPPROG=pjsnmp$(EXEEXT)
+
+# List of CLI programs using the MySQL library
+CLI_MYSQLPROG=itadmin$(EXEEXT)
+
+# C/C++ compiler flags to build modules for shared libraries
+CFPIC=-fPIC -D_REENTRANT
+
+# Script to install shared libraries
+INSTALL_LIBS_SHARED=./scripts/install-libs-shared.sh
+
+# A BSD compatible install program
+INSTALL=/usr/bin/install -c
+
+# Program or script to install executable programs
+INSTALL_PROGRAM=${INSTALL}
+
+# Program or script to install script files
+INSTALL_SCRIPT=${INSTALL}
+
+# Program or script to install data files
+INSTALL_DATA=${INSTALL} -m 644
+
+# Base libraries to build the CLI programs on Windows systems
+WINCLILIB=-lkernel32 -lgdi32 -ladvapi32 -luser32 -lnetapi32
+
+# Additional libraries to build the GUI programs on Windows systems
+WINGUILIB=-lole32 -loleaut32 -lshell32 -lcomctl32 -lcomdlg32 -lwinspool
+
+# Type of entry point on Windows
+WINENTRY=-municode
+
+# List of additional libraries to include when building CLI programs
+# $(WINCLILIB) on Windows, empty on other systems
+CLILIB=
+
+# List of additional libraries to include when building GUI programs
+# $(WINGUILIB) on Windows, empty on other systems
+GUILIB=
+
+# Entry point options, $(WINENTRY) on Windows, empty on other systems
+ENTRY=
+
+# Include path for C/C++ compiler
+INCLUDES= \
+ -I. \
+ -I$(srcdir) \
+ -I$(top_srcdir) \
+ -I$(includedir)
+
+# Options used when compiling *.c modules to *.o
+COPTS= \
+ $(DEFS) \
+ $(INCLUDES) \
+ $(CFPIC) \
+ $(CPPFLAGS) \
+ $(CFLAGS) \
+ $(FS64) \
+ $(CWARN)
+
+# Options used when compiling *.cpp or *.cxx modules to *.o
+CCOPTS= \
+ $(DEFS) \
+ $(INCLUDES) \
+ $(CFPIC) \
+ $(CPPFLAGS) \
+ $(CFLAGS) \
+ $(CXXFLAGS) \
+ $(WXCPPFLAGS) \
+ $(WXCXXFLAGS) \
+ $(FS64) \
+ $(CWARN)
+
+# C compiler command including options
+COMPILEC= $(CC) $(COPTS)
+
+# C++ compiler command including options
+COMPILECPP= $(CXX) $(CCOPTS) $(WXCXXFLAGS)
+
+# Linker command
+LD=$(CC)
+
+# Linker command including options
+LINK=$(CC) $(CFLAGS) -L. $(LDFLAGS) $(RPATH) $(RPATHLINK) $(ENTRY)
+
+# Linker command for applications using C++ modules (i.e. wxWidgets libraries)
+LDCPP=$(CXX) $(CFLAGS) $(CXXFLAGS) -L. $(LDFLAGS) $(RPATH) $(RPATHLINK) $(ENTRY)
+
+# Command to build a shared library
+MKSOLIB=$(COMPILEC) -L. $(RPATHLINK) $(LIBRARIES) $(LDFLAGS) -shared -o $@.$(SOVERS) -Wl,-soname,$@.$(SOVERS)
+
+# Shared libraries needed for linking when building other shared libraries
+
+SOLIBZ=-lz
+SOLIBBZ=-lbz2
+SOLIBMATH=-lm
+SOLIBCRYPTO=-lcrypto
+SOLIBNET=
+SOLIBIMG=
+SOLIBSDBI=
+SOLIBWX=-L/usr/lib/x86_64-linux-gnu -pthread -lwx_gtk2u_xrc-3.0 -lwx_gtk2u_html-3.0 -lwx_gtk2u_qa-3.0 -lwx_gtk2u_adv-3.0 -lwx_gtk2u_core-3.0 -lwx_baseu_xml-3.0 -lwx_baseu_net-3.0 -lwx_baseu-3.0
+SOLIBDK3PORT=
+SOLIBDK3C=-ldk3c $(SOLIBBZ) $(SOLIBZ) $(SOLIBMATH)
+SOLIBDK3OF=-ldk3of
+SOLIBDK3CSRND=-ldk3csrnd
+SOLIBDK3BIF=-ldk3bif
+SOLIBDK3DBI=-ldk3dbi
+SOLIBDK3FIG=-ldk3fig
+SOLIBDK3BMEPS=-ldk3bmeps
+SOLIBDK3NET=-ldk3net
+SOLIBDK4BASE=-ldk4base
+SOLIBDK4MA=-ldk4ma
+SOLIBDK4MAIO8H=-ldk4maio8h
+SOLIBDK4MAIOWH=-ldk4maiowh
+SOLIBDK4MAIODH=-ldk4maiodh
+SOLIBDK4MAIO8D=-ldk4maio8d
+SOLIBDK4MAIOWD=-ldk4maiowd
+SOLIBDK4MAIODD=-ldk4maiodd
+SOLIBDK4C=-ldk4c $(SOLIBDK4MAIODD) $(SOLIBDK4MAIO8D) $(SOLIBDK4MA) \
+ $(SOLIBDK4BASE) $(SOLIBBZ) $(SOLIBZ) $(SOLIBMATH)
+SOLIBDK4MDRND=-ldk4mdrnd
+SOLIBDK4PPPT=-ldk4pppt
+SOLIBDK4APP=-ldk4app $(SOLIBDK4C)
+SOLIBDK4LAT=-ldk4lat
+SOLIBDK4SOCK=-ldk4sock
+SOLIBDK4SOCKA=-ldk4socka
+SOLIBDK4DBI=-ldk4dbi
+SOLIBDK4DBIA=-ldk4dbia
+
+
+
+
+# Clean suffixes list
+.SUFFIXES:
+
+# Rebuild new suffixes list
+.SUFFIXES: .o .cpp .c
+
+.c.o:
+ @echo '### Compile C ### ' $<
+ $(COMPILEC) -o $@ -c $<
+
+.cpp.o:
+ @echo '### Compile C++ ### ' $<
+ $(COMPILECPP) -o $@ -c $<
+
+.c:
+ @echo '### Link C ### ' $*
+ $(COMPILEC) $(LDFLAGS) -o $* $*.c $(LIBS)
+ chmod 755 $*
+
+.cpp:
+ @echo '### Link C++ ### ' $*
+ $(COMPILECPP) $(LDFLAGS) -o $* $*.cpp $(LIBS)
+ chmod 755 $*
+
+# Programs to build for rescue system when sockets available
+NET_PROG_RES= \
+ dk-recv$(EXEEXT) \
+ dk-send$(EXEEXT)
+
+# Programs to build for rescue system
+PROG_RES= $(NET_PROG_RES) \
+ dk-cat$(EXEEXT) \
+ dk-blks$(EXEEXT) \
+ dk-eradisk$(EXEEXT) \
+ dk-ls$(EXEEXT)
+
+# Man pages to install on rescue systems
+MAN_RES= \
+ man/man1/dk-blks.1 \
+ man/man1/dk-cat.1 \
+ man/man1/dk-eradisk.1 \
+ man/man1/dk-ls.1 \
+ man/man1/dk-recv.1 \
+ man/man1/dk-send.1
+
+# Resource files to install on rescue systems
+RES_RES_EN= \
+ dktools/en/dk-blks.txt \
+ dktools/en/dk-cat.txt \
+ dktools/en/dk-ls.txt \
+ dktools/en/dk-recv.txt \
+ dktools/en/dk-send.txt
+
+RES_RES_DE= \
+ dktools/de/dk-blks.txt \
+ dktools/de/dk-cat.txt \
+ dktools/de/dk-ls.txt \
+ dktools/de/dk-recv.txt \
+ dktools/de/dk-send.txt
+
+
+# Command line programs to build when sockets available
+NET_PROG_CLI= \
+ printqd$(EXEEXT) \
+ printqdc$(EXEEXT) \
+ lprngcl$(EXEEXT) \
+ rshdown$(EXEEXT)
+
+# Command line programs to build when NetSNMP available
+SNMP_PROG_CLI= \
+ pjsnmp$(EXEEXT) prmonsnmp$(EXEEXT)
+
+# Command line programs to build when MySQL available
+MYSQL_PROG_CLI= \
+ itadmin$(EXEEXT)
+
+# Programs to build for CLI suite
+PROG_CLI= $(PROG_RES) \
+ dk-sqlsplit$(EXEEXT) $(SNMP_PROG_CLI) \
+ dk-sort$(EXEEXT) dk-fic$(EXEEXT) dk-pwgen$(EXEEXT) dk-rand$(EXEEXT) \
+ dk-uid$(EXEEXT) $(NET_PROG_CLI) \
+ dk-t2h$(EXEEXT) $(MYSQL_PROG_CLI) \
+ dk-t2l$(EXEEXT) \
+ dk-hex$(EXEEXT) \
+ dk-bmm$(EXEEXT) \
+ dk-pwd$(EXEEXT) \
+ dkct$(EXEEXT) \
+ addctrld$(EXEEXT) \
+ dk-t2db$(EXEEXT) \
+ dk-db2t$(EXEEXT) \
+ dk-dbco$(EXEEXT) \
+ bmpp$(EXEEXT) \
+ fig2lat$(EXEEXT) \
+ htmlbook$(EXEEXT) \
+ dk3info$(EXEEXT) \
+ dk4info$(EXEEXT) \
+ plpdftex$(EXEEXT) \
+ dkwxwiz$(EXEEXT)
+
+# Programs to build when cross-compiling on Linux for Windows
+PROG_CROSS= $(PROG_RES) \
+ dk-sqlsplit$(EXEEXT) $(SNMP_PROG_CLI) \
+ dk-sort$(EXEEXT) dk-fic$(EXEEXT) dk-pwgen$(EXEEXT) dk-rand$(EXEEXT) \
+ dk-fic$(EXEEXT) $(NET_PROG_CLI) \
+ dk-t2h$(EXEEXT) $(MYSQL_PROG_CLI) \
+ dk-t2l$(EXEEXT) \
+ dk-hex$(EXEEXT) \
+ dk-bmm$(EXEEXT) \
+ dk-pwd$(EXEEXT) \
+ dkct$(EXEEXT) \
+ addctrld$(EXEEXT) \
+ dk-t2db$(EXEEXT) \
+ dk-db2t$(EXEEXT) \
+ dk-dbco$(EXEEXT) \
+ bmpp$(EXEEXT) \
+ fig2lat$(EXEEXT) \
+ htmlbook$(EXEEXT) \
+ dk3info$(EXEEXT) \
+ dk4info$(EXEEXT) \
+ plpdftex$(EXEEXT) \
+ dkwxwiz$(EXEEXT)
+
+# Programs to build for GUI suite
+PROG_GUI= $(PROG_CLI) \
+ wxdkfcs$(EXEEXT) \
+ wxdkct$(EXEEXT) \
+ wxbmpp$(EXEEXT) \
+ wxpqdic$(EXEEXT) \
+ wximgsz$(EXEEXT) \
+ wxdkclock$(EXEEXT) \
+ wxdkhtb$(EXEEXT)
+
+# Static libraries to build for rescue system
+LIB_ST_RES=
+
+# Static libraries to build for CLI suite
+LIB_ST_CLI= $(LIB_ST_RES) \
+ libdk4base.a \
+ libdk4ma.a \
+ libdk4maio8h.a \
+ libdk4maiowh.a \
+ libdk4maiodh.a \
+ libdk4maio8d.a \
+ libdk4maiowd.a \
+ libdk4maiodd.a \
+ libdk4c.a \
+ libdk4pppt.a \
+ libdk4socka.a \
+ libdk4sock.a \
+ libdk4dbia.a \
+ libdk4dbi.a \
+ libdk4app.a \
+ libdk4pppta.a \
+ libdk4lat.a \
+ libdk4mdrnd.a \
+ libdk3c.a \
+ libdk3of.a \
+ libdk3csrnd.a \
+ libdk3bif.a \
+ libdk3dbi.a \
+ libdk3bmeps.a \
+ libdk3fig.a \
+ libdk3trace.a
+
+# Static libraries to build for GUI suite
+LIB_ST_GUI= $(LIB_ST_CLI) \
+ libdk4wx.a \
+ libdk4maioxd.a
+
+# Shared libraries to build for rescue system when no packaging used
+LIB_SH_RES_NO_PACKAGING=
+
+# Shared libraries to build for CLI suite when no packaging used
+LIB_SH_CLI_NO_PACKAGING= $(LIB_SH_RES_NO_PACKAGING) \
+ libdk4base.so \
+ libdk4ma.so \
+ libdk4maio8h.so \
+ libdk4maiowh.so \
+ libdk4maiodh.so \
+ libdk4maio8d.so \
+ libdk4maiowd.so \
+ libdk4maiodd.so \
+ libdk4c.so \
+ libdk4pppt.so \
+ libdk4socka.so \
+ libdk4sock.so \
+ libdk4dbia.so \
+ libdk4dbi.so \
+ libdk4app.so \
+ libdk4pppta.so \
+ libdk4lat.so \
+ libdk4mdrnd.so \
+ libdk3c.so \
+ libdk3of.so \
+ libdk3csrnd.so \
+ libdk3bif.so \
+ libdk3dbi.so \
+ libdk3bmeps.so \
+ libdk3fig.so \
+ libdk3trace.so
+
+# Shared libraries to build for GUI suite when no packaging used
+LIB_SH_GUI_NO_PACKAGING= $(LIB_SH_CLI_NO_PACKAGING) \
+ libdk4wx.so \
+ libdk4maioxd.so \
+ libdk3wx.so
+
+# Shared libraries to build for rescue system when packaging used
+LIB_SH_RES_PACKAGING= \
+ libdk4base.so \
+ libdk4maio8d.so \
+ libdk4maiowd.so \
+ libdk4maiodd.so \
+ libdk4maio8h.so \
+ libdk4maiowh.so \
+ libdk4maiodh.so \
+ libdk4ma.so \
+ libdk4c.so \
+ libdk4socka.so \
+ libdk4sock.so \
+ libdk4app.so \
+ libdk4mdrnd.so
+
+# Shared libraries to build for CLI suite when packaging used
+LIB_SH_CLI_PACKAGING= $(LIB_SH_RES_PACKAGING) \
+ libdk4lat.so \
+ libdk4dbi.so \
+ libdk4dbia.so \
+ libdk4pppt.so \
+ libdk4pppta.so \
+ libdk3c.so \
+ libdk3of.so \
+ libdk3csrnd.so \
+ libdk3bif.so \
+ libdk3dbi.so \
+ libdk3bmeps.so \
+ libdk3fig.so \
+ libdk3trace.so
+
+# Shared libraries to build for GUI suite when packaging used
+LIB_SH_GUI_PACKAGING= $(LIB_SH_CLI_PACKAGING) \
+ libdk4wx.so \
+ libdk4maioxd.so \
+ libdk3wx.so
+
+# Shared libraries to build for rescue system when packaging used
+LIB_SH_RES=$(LIB_SH_RES_NO_PACKAGING)
+
+# Shared libraries to build for CLI suite
+LIB_SH_CLI=$(LIB_SH_CLI_NO_PACKAGING)
+
+# Shared libraries to build for GUI suite
+LIB_SH_GUI=$(LIB_SH_GUI_NO_PACKAGING)
+
+all: # Synonym for build
+all: build
+
+help: # Show targets in Makefile
+ @echo 'Some systems (i.e. Windows) append a special filename extension'
+ @echo '(i.e. .exe) to program file names.'
+ @echo 'On such systems use "make dk-ls.exe" instead of "make dk-ls"'
+ @echo 'to build a program.'
+ @echo 'Here is a list of the targets in this Makefile:'
+ -@egrep '^[^:;=. ]*::?[ ]*' Makefile|grep '#'|grep -v '^#'
+
+build: # Build the software
+build: build-arch build-indep
+
+build-arch: # Build architecture specific files
+build-arch: $(PROG_GUI) $(LIB_SH_GUI)
+
+build-indep: # Build architecture independent files
+ find man -type d -exec chmod 755 {} \;
+ find man -type f -exec chmod 644 {} \;
+
+install: # Install the software
+install: install-arch install-indep
+ [ "X$(DESTDIR)" = "X" -o "X$(UNAME)" != "XSunOS" ] || cp pkginfo $(DESTDIR)/pkginfo
+ [ "X$(DESTDIR)" = "X" -o "X$(UNAME)" != "XSunOS" ] || chmod 644 $(DESTDIR)/pkginfo
+ @echo Finished installation
+ @echo Some directories used by the printqd daemon may need
+ @echo ownership and permission corrections. See 'printqd(1)'.
+
+install-arch: # Install architecture specific files
+install-arch: install-programs i-l-sh i-incl i-r-gui
+ @echo Finished installation of architecture specific files.
+
+# Shared libraries to build and install
+LIBS_SHARED=$(LIB_SH_GUI)
+
+i-l-sh: # Install shared libraries
+i-l-sh: build-arch install-directories
+ $(INSTALL) -c -d "$(DESTDIR)$(libdir)"
+ for i in $(LIBS_SHARED) ; do $(INSTALL) -c -m 644 $$i.$(SOVERS) "$(DESTDIR)$(libdir)" ; done
+ for i in $(LIBS_SHARED) ; do $(LN_S) $$i.$(SOVERS) "$(DESTDIR)$(libdir)/$$i"; done
+ @echo Finished installation of shared libraries.
+
+# Static libraries to build and install
+LIBS_STATIC=$(LIB_ST_GUI)
+
+i-l-st: # Install static libraries
+i-l-st: build-arch install-directories
+ $(INSTALL_DATA) $(LIBS_STATIC) "$(DESTDIR)$(libdir)"
+ @echo Finished installation of static libraries.
+
+i-incl: # Install include files for libraries
+ $(INSTALL_DATA) dk4*.h Dk4*.h dk3trace.h "$(DESTDIR)$(includedir)"
+ @echo Finished installation of include files.
+
+i-r-res: # Install resources for rescue programs
+i-r-res:
+ $(INSTALL) -d "$(DESTDIR)$(datarootdir)/dktools"
+ $(INSTALL) -d "$(DESTDIR)$(datarootdir)/dktools/en"
+ $(INSTALL) -d "$(DESTDIR)$(datarootdir)/dktools/de"
+ $(INSTALL_DATA) $(RES_RES_EN) "$(DESTDIR)$(datarootdir)/dktools/en"
+ $(INSTALL_DATA) $(RES_RES_DE) "$(DESTDIR)$(datarootdir)/dktools/de"
+ @echo Finished resources installation for rescue programs.
+
+i-r-cli: # Install resources for CLI programs
+i-r-cli: install-directories i-r-res
+ find ./dktools -type d -exec chmod 755 {} \;
+ find ./dktools -type f -exec chmod ugo+r,go-w {} \;
+ find ./dk4app -type d -exec chmod 755 {} \;
+ find ./dk4app -type f -exec chmod ugo+r,go-w {} \;
+ (cd ./dktools ; tar cf - .) | (cd "$(DESTDIR)$(datarootdir)/dktools" ; tar xf -)
+ (cd ./dk4app ; tar cf - .) | (cd "$(DESTDIR)$(datarootdir)/dk4app" ; tar xf -)
+ find ./help-chm -type d -exec chmod 755 {} \;
+ find ./help-chm -type f -exec chmod 644 {} \;
+ find ./help-htb -type d -exec chmod 755 {} \;
+ find ./help-htb -type f -exec chmod 644 {} \;
+ (cd ./help-htb ; tar cf - .) | (cd "$(DESTDIR)$(datarootdir)/dktools" ; tar xf -)
+ $(INSTALL_DATA) dktools.pc "$(DESTDIR)$(libdir)/pkgconfig/dktools.pc"
+ $(INSTALL_DATA) etc-dk3app/dk3paper.conf "$(DESTDIR)$(sysconfdir)/dk3app"
+ $(INSTALL_SCRIPT) itaclean.sh "$(DESTDIR)$(bindir)/itaclean"
+ $(INSTALL_DATA) rshdown.conf.sample "$(DESTDIR)$(sysconfdir)/rshdown"
+ $(INSTALL_DATA) printqd.conf.sample "$(DESTDIR)$(sysconfdir)/printqd"
+ @echo Finished resources installation for CLI programs.
+
+i-r-gui: # Install resources for GUI programs
+i-r-gui: install-directories i-r-cli
+ $(INSTALL_DATA) dkicon.ico "$(DESTDIR)$(datarootdir)/dktools"
+ $(INSTALL_DATA) dkclock.ico "$(DESTDIR)$(datarootdir)/dktools"
+ $(INSTALL_DATA) wxbmpp.desktop "$(DESTDIR)$(datarootdir)/applications"
+ $(INSTALL_DATA) wxdkclock.desktop "$(DESTDIR)$(datarootdir)/applications"
+ $(INSTALL_DATA) wxdkct.desktop "$(DESTDIR)$(datarootdir)/applications"
+ $(INSTALL_DATA) wximgsz.desktop "$(DESTDIR)$(datarootdir)/applications"
+ $(INSTALL_DATA) wxdkfcs.desktop "$(DESTDIR)$(datarootdir)/applications"
+ @echo Finished resources installation for GUI programs.
+
+
+install-programs: # Install the executable programs
+install-programs: build-arch install-directories
+ $(INSTALL) $(PROG_GUI) "$(DESTDIR)$(bindir)"
+ @echo Finished installation of executable files.
+
+install-indep: # Install architecture independent files
+install-indep: build-indep install-directories
+ @echo Finished installation of architecture independent files.
+
+install-rescue-man: # Install man pages for rescue systems
+install-rescue-man: build-indep
+ $(INSTALL) -d "$(DESTDIR)$(mandir)/man1"
+ $(INSTALL_DATA) $(MAN_RES) "$(DESTDIR)$(mandir)/man1"
+
+install-manpages: # Install man pages
+install-manpages: build-indep install-directories
+ $(INSTALL_DATA) man/man1/* "$(DESTDIR)$(mandir)/man1"
+ $(INSTALL_DATA) man/man5/* "$(DESTDIR)$(mandir)/man5"
+ @echo Finished installation of manpages.
+
+install-directories: # Create installation directories
+ $(INSTALL) -d "$(DESTDIR)$(libdir)"
+ $(INSTALL) -d "$(DESTDIR)$(libdir)/pkgconfig"
+ $(INSTALL) -d "$(DESTDIR)$(includedir)"
+ $(INSTALL) -d "$(DESTDIR)$(bindir)"
+ $(INSTALL) -d "$(DESTDIR)$(mandir)"
+ $(INSTALL) -d "$(DESTDIR)$(mandir)/man1"
+ $(INSTALL) -d "$(DESTDIR)$(mandir)/man5"
+ $(INSTALL) -d "$(DESTDIR)$(datarootdir)/dktools"
+ $(INSTALL) -d "$(DESTDIR)$(datarootdir)/dk4app"
+ $(INSTALL) -d "$(DESTDIR)$(datarootdir)/applications"
+ $(INSTALL) -d "$(DESTDIR)$(sysconfdir)/dk3app"
+ $(INSTALL) -d "$(DESTDIR)$(sysconfdir)/rshdown"
+ $(INSTALL) -d "$(DESTDIR)$(sysconfdir)/printqd"
+ $(INSTALL) -d "$(DESTDIR)$(localstatedir)/log"
+ $(INSTALL) -d -m 775 "$(DESTDIR)$(localstatedir)/log/printqd"
+ $(INSTALL) -d "$(DESTDIR)$(localstatedir)/run"
+ $(INSTALL) -d -m 775 "$(DESTDIR)$(localstatedir)/lib/printqd"
+ @echo Finished directory creation for installation.
+
+# Test programs for the modules.
+TESTPROGS= \
+ test-dk4maac \
+ test-dk4maauc \
+ test-dk4maas \
+ test-dk4maaus \
+ test-dk4maai \
+ test-dk4maaui \
+ test-dk4maal \
+ test-dk4maaul \
+ test-dk4maall \
+ test-dk4maaull \
+ test-dk4maami \
+ test-dk4maamu \
+ test-dk4mai8ddu \
+ test-dk4mai8ddi \
+ test-dk4mai8dsz \
+ test-dk4str8 \
+ test-dk4loc \
+ test-dk4time \
+ test-dk4exep8 \
+ test-dk4path8 \
+ ex-sto \
+ test-dk4strm \
+ test-dk4numl \
+ test-dk4tsp08 \
+ test-bool \
+ test-dk4enc \
+ test-dk4user \
+ test-container \
+ test-skip
+
+# All test programs found by the configure script
+TESTPROGRAMS= test-a85d \
+ test-a85e \
+ test-binenc \
+ test-bool \
+ test-deldir \
+ test-deldirwc \
+ test-deltree \
+ test-dk4c8dbl \
+ test-dk4dir \
+ test-dk4dir08 \
+ test-dk4enc \
+ test-dk4exep8 \
+ test-dk4loc \
+ test-dk4maac \
+ test-dk4maai \
+ test-dk4maal \
+ test-dk4maall \
+ test-dk4maami \
+ test-dk4maamu \
+ test-dk4maas \
+ test-dk4maauc \
+ test-dk4maaui \
+ test-dk4maaul \
+ test-dk4maaull \
+ test-dk4maaus \
+ test-dk4mai8dbl \
+ test-dk4mai8ddi \
+ test-dk4mai8ddu \
+ test-dk4mai8dsz \
+ test-dk4numl \
+ test-dk4path8 \
+ test-dk4str8 \
+ test-dk4strm \
+ test-dk4strmco \
+ test-dk4time \
+ test-dk4time08 \
+ test-dk4tsp08 \
+ test-dk4user \
+ test-eradisk \
+ test-filei \
+ test-fne \
+ test-home \
+ test-inet-pton \
+ test-mbstr \
+ test-membuf \
+ test-mkdir \
+ test-opt \
+ test-paper \
+ test-peer \
+ test-rld \
+ test-rle \
+ test-ser \
+ test-skip \
+ test-sock \
+ test-sqdbl \
+ test-strms \
+ test-strmu \
+ test-strmw \
+ test-udpa \
+ test-unser \
+ testlzw \
+ testlzws
+
+clean: # Clean up (remove build results)
+ -rm -f errors
+ -rm -f *.deb
+ -rm -f *.o *.obj *.exe
+ -rm -f $(TESTPROGRAMS) $(TESTPROGS) $(PROG_GUI)
+ -rm -f *.a
+ -rm -f *.so.$(SOVERS) *.so
+ -rm -f doxygen.out
+ -rm -f dk4config
+ -rm -f dk3config
+ -rm -f wxcs
+ -rm -f doc/src/*.aux doc/src/*.log doc/src/math-img.pdf
+ -rm -f doc/src/index.pdf doc/src/index.svg
+ -rm -f doc/src/next.pdf doc/src/next.svg
+ -rm -f doc/src/prev.pdf doc/src/prev.svg
+ -rm -f doc/src/toc.pdf doc/src/toc.svg
+ @echo 'Finished cleanup.'
+
+get-orig-source: # Retrieve original source archive
+ wget -O dktools-$(VERSNO) $(SFBASE)/dktools-$(VERSNO).tar.gz/download
+
+# Complete list of all libraries to build
+# Probably not all of them are installed
+LIBRARIESTOBUILD= libdk4wx.$(LIBEXT) \
+ libdk4.a \
+ libdk4maio8d.$(LIBEXT) \
+ libdk4maiowd.$(LIBEXT) \
+ libdk4maiodd.$(LIBEXT) \
+ libdk4maio8h.$(LIBEXT) \
+ libdk4maiowh.$(LIBEXT) \
+ libdk4maiodh.$(LIBEXT) \
+ libdk4ma.$(LIBEXT) \
+ libdk4base.$(LIBEXT) \
+ libdk4c.$(LIBEXT) \
+ libdk4pppt.$(LIBEXT) \
+ libdk4app.$(LIBEXT) \
+ libdk4pppta.$(LIBEXT) \
+ libdk4lat.$(LIBEXT) \
+ libdk4sock.$(LIBEXT) \
+ libdk4socka.$(LIBEXT) \
+ libdk4dbi.$(LIBEXT) \
+ libdk4dbia.$(LIBEXT)
+
+binary: # Build all binaries
+binary: binary-arch binary-indep
+
+binary-arch: # Build architecture-specific binaries
+binary-arch: build-arch $(LIBRARIESTOBUILD) $(PROG_GUI)
+ @echo 'Finished creating the architecture-specific binaries.'
+
+binary-indep: # Build architecture-independent binaries
+binary-indep: build-indep
+ @echo 'There are no architecture-independent binaries in this project.'
+
+# Objects for libdk4wx.so or libdk4wx.a library
+LIBDK4WXOBJ= \
+ Dk4WxControl.o \
+ Dk4WxProgressDialog.o \
+ Dk4WxFrame.o \
+ Dk4WxHelpController.o \
+ Dk4WxAutostartController.o \
+ Dk4WxApplicationHelper.o \
+ dk4wxpref.o \
+ dk4wxstt.o \
+ dk4recwx.o \
+ dk4tspwx.o \
+ dk4strx.o
+
+# Objects for libdk4socka.so or libdk4socka.a library
+LIBDK4SOCKAOBJ= \
+ dk4socka09.o \
+ dk4socka08.o \
+ dk4socka07.o \
+ dk4socka06.o \
+ dk4socka05.o \
+ dk4socka04.o \
+ dk4socka03.o \
+ dk4socka02.o \
+ dk4socka01.o
+
+# Objects for libdk4sock.so or libdk4sock.a library
+LIBDK4SOCKOBJ= \
+ dk4sock37.o \
+ dk4sock36.o \
+ dk4sock35.o \
+ dk4sock34.o \
+ dk4sock33.o \
+ dk4sock32.o \
+ dk4sock31.o \
+ dk4sock30.o \
+ dk4sock29.o \
+ dk4sock28.o \
+ dk4sock27.o \
+ dk4sock26.o \
+ dk4sock25.o \
+ dk4sock24.o \
+ dk4sock23.o \
+ dk4sock22.o \
+ dk4sock21.o \
+ dk4sock20.o \
+ dk4sock19.o \
+ dk4sock18.o \
+ dk4sock17.o \
+ dk4sock16.o \
+ dk4sock15.o \
+ dk4sock14.o \
+ dk4sock13.o \
+ dk4sock12.o \
+ dk4sock11.o \
+ dk4sock10.o \
+ dk4sock09.o \
+ dk4sock08.o \
+ dk4sock07.o \
+ dk4sock06.o \
+ dk4sock05.o \
+ dk4sock04.o \
+ dk4sock03.o \
+ dk4sock02.o \
+ dk4sock01.o
+
+# Objects for libdk4lat.so or libdk4lat.a library
+LIBDK4LATOBJ= \
+ dk4uc2l.o
+
+# Objects for libdk4app.so or libdk4app.a library
+LIBDK4APPOBJ= \
+ dk4fdrda.o \
+ dk4fdrde.o \
+ dk4fdwre.o \
+ dk4mema.o \
+ dk4svbufa.o \
+ dk4fopda.o \
+ dk4appargs.o \
+ dk4appop.o \
+ dk4appmkdh.o \
+ dk4appstt.o \
+ dk4appenc.o \
+ dk4aopt01.o \
+ dk4aopt02.o \
+ dk4aopt03.o \
+ dk4aopt04.o \
+ dk4aopt05.o \
+ dk4aopt06.o \
+ dk4aopt07.o \
+ dk4aopt08.o \
+ dk4aopt09.o \
+ dk4aopt10.o \
+ dk4aopt11.o \
+ dk4aopt12.o \
+ dk4aopt13.o \
+ dk4aopt14.o \
+ dk4aopt15.o \
+ dk4aopt16.o \
+ dk4appfs03.o \
+ dk4appfs04.o \
+ dk4appfs01.o \
+ dk4appfs02.o \
+ dk4appfne.o \
+ dk4dira.o \
+ dk4fileia.o \
+ dk4appdeltree.o \
+ dk4appdeldir.o \
+ dk4appdelfile.o \
+ dk4applog.o \
+ dk4apref.o \
+ dk4aprgs.o \
+ dk4apphlv.o \
+ dk4strda.o
+
+# Objects for libdk4mdrnd.so or libdk4mdrnd.a library
+LIBDK4MDRNDOBJ= \
+ dk4md.o
+
+# Objects for libdk4pppta.so or libdk4pppta.a library
+LIBDK4PPPTAOBJ= \
+ dk4papea.o
+
+# Objects for libdk4pppt.so or libdk4pppt.a library
+LIBDK4PPPTOBJ= \
+ dk4font.o \
+ dk4paper.o
+
+# Object for libdk4c.so or libdk4c.a library
+LIBDK4COBJ= \
+ dk4dmt.o \
+ dk4mdch.o \
+ dk4binenc.o \
+ dk4stt.o \
+ dk4opt.o \
+ dk4opt01.o \
+ dk4opt02.o \
+ dk4opt03.o \
+ dk4opt04.o \
+ dk4opt05.o \
+ dk4opt06.o \
+ dk4opt07.o \
+ dk4pref.o \
+ dk4tspdk.o \
+ dk4tsp32.o \
+ dk4tsp16.o \
+ dk4tsp08.o \
+ dk4strmco.o \
+ dk4lzwe.o \
+ dk4mbstrm.o \
+ dk4membs.o \
+ dk4membf.o \
+ dk4membuf.o \
+ dk4strmu.o \
+ dk4strms.o \
+ dk4strmw.o \
+ dk4strmr.o \
+ dk4strmf.o \
+ dk4strmg.o \
+ dk4strmb.o \
+ dk4strmodk.o \
+ dk4strmo08.o \
+ dk4strmo16.o \
+ dk4strmo32.o \
+ dk4c8dbl.o \
+ dk4strm.o \
+ dk4fput.o \
+ dk4svbuf.o \
+ dk4fopd.o \
+ dk4fopwc.o \
+ dk4fopc8.o \
+ dk4exepd.o \
+ dk4exepw.o \
+ dk4exep8.o \
+ dk4mkdh.o \
+ dk4mkdh8.o \
+ dk4mkdhw.o \
+ dk4symlink.o \
+ dk4fileiu.o \
+ dk4fileigd.o \
+ dk4fileigw.o \
+ dk4fileig8.o \
+ dk4filei.o \
+ dk4fileid.o \
+ dk4fileiw.o \
+ dk4filei8.o \
+ dk4filed.o \
+ dk4filew.o \
+ dk4file8.o \
+ dk4fs.o \
+ dk4mm.o \
+ dk4stat.o \
+ dk4statd.o \
+ dk4statw.o \
+ dk4stat8.o \
+ dk4pathd.o \
+ dk4pathw.o \
+ dk4path8.o \
+ dk4userf.o \
+ dk4enc.o \
+ dk4bom.o \
+ dk4rec25.o \
+ dk4rec24.o \
+ dk4rec23.o \
+ dk4rec22.o \
+ dk4rec21.o \
+ dk4rec20.o \
+ dk4rec19.o \
+ dk4rec18.o \
+ dk4rec17.o \
+ dk4rec16.o \
+ dk4rec15.o \
+ dk4rec14.o \
+ dk4rec13.o \
+ dk4rec12.o \
+ dk4rec11.o \
+ dk4rec10.o \
+ dk4rec09.o \
+ dk4rec08.o \
+ dk4rec07.o \
+ dk4rec06.o \
+ dk4rec05.o \
+ dk4rec04.o \
+ dk4rec03.o \
+ dk4rec02.o \
+ dk4rec01.o \
+ dk4ansi.o \
+ dk4utf8.o \
+ dk4utf16.o \
+ dk4c32.o \
+ dk4loc.o \
+ dk4wregd.o \
+ dk4wregw.o \
+ dk4wreg8.o \
+ dk4wregc.o \
+ dk4fd.o \
+ dk4hnamed.o \
+ dk4hnamew.o \
+ dk4hname8.o \
+ dk4user.o \
+ dk4ufi.o \
+ dk4ufiwc.o \
+ dk4ufi08.o \
+ dk4fne.o \
+ dk4fnewc.o \
+ dk4fne08.o \
+ dk4getcwdd.o \
+ dk4getcwdw.o \
+ dk4getcwd8.o \
+ dk4dir.o \
+ dk4dirwc.o \
+ dk4dir08.o \
+ dk4deldir.o \
+ dk4deldirwc.o \
+ dk4deldir08.o \
+ dk4delfile.o \
+ dk4delfilewc.o \
+ dk4delfile08.o \
+ dk4istty.o \
+ dk4ftimedk.o \
+ dk4ftimewc.o \
+ dk4ftime08.o \
+ dk4ftime.o \
+ dk4ctime.o \
+ dk4time.o \
+ dk4timedk.o \
+ dk4timewc.o \
+ dk4time08.o \
+ dk4inst.o \
+ dk4getpid.o \
+ dk4sto.o \
+ dk4a85e.o \
+ dk4a85d.o \
+ dk4ahd.o \
+ dk4rle.o \
+ dk4rld.o \
+ dk4bf.o \
+ dk4bitsh.o \
+ dk4isadm.o \
+ dk4fpe.o \
+ dk3trace.o
+
+# Objects for libdk4maiodd.so or libdk4maiodd.a library
+LIBDK4MAIODDOBJ= \
+ dk4maoddbl.o \
+ dk4maiddbl.o \
+ dk4maiddic.o \
+ dk4maiddis.o \
+ dk4maiddii.o \
+ dk4maiddmi.o \
+ dk4maiddli.o \
+ dk4maiddil.o \
+ dk4maidddi.o \
+ dk4maidduc.o \
+ dk4maiddus.o \
+ dk4maiddui.o \
+ dk4maiddmu.o \
+ dk4maiddlu.o \
+ dk4maiddul.o \
+ dk4maiddsz.o \
+ dk4maidddu.o \
+ dk4maodd.o
+
+# Objects for libdk4maioxd.so or libdk4maioxd.a library
+LIBDK4MAIOXDOBJ= \
+ dk4maoxdbl.o \
+ dk4maixdbl.o \
+ dk4maixdic.o \
+ dk4maixdis.o \
+ dk4maixdii.o \
+ dk4maixdmi.o \
+ dk4maixdli.o \
+ dk4maixdil.o \
+ dk4maixddi.o \
+ dk4maixduc.o \
+ dk4maixdus.o \
+ dk4maixdui.o \
+ dk4maixdmu.o \
+ dk4maixdlu.o \
+ dk4maixdul.o \
+ dk4maixdsz.o \
+ dk4maixddu.o \
+ dk4maoxd.o
+
+# Objects for libdk4maiodh.so or libdk4maiodh.a library
+LIBDK4MAIODHOBJ= \
+ dk4maidhic.o \
+ dk4maidhis.o \
+ dk4maidhii.o \
+ dk4maidhmi.o \
+ dk4maidhli.o \
+ dk4maidhil.o \
+ dk4maidhdi.o \
+ dk4maidhuc.o \
+ dk4maidhus.o \
+ dk4maidhui.o \
+ dk4maidhmu.o \
+ dk4maidhlu.o \
+ dk4maidhul.o \
+ dk4maidhdu.o \
+ dk4maodh.o \
+ dk4maodo.o
+
+# Objects for libdk4maiowd.so or libdk4maiowd.a library
+LIBDK4MAIOWDOBJ= \
+ dk4maowdbl.o \
+ dk4maiwdbl.o \
+ dk4maiwdic.o \
+ dk4maiwdis.o \
+ dk4maiwdii.o \
+ dk4maiwdmi.o \
+ dk4maiwdli.o \
+ dk4maiwdil.o \
+ dk4maiwduc.o \
+ dk4maiwdus.o \
+ dk4maiwdui.o \
+ dk4maiwdmu.o \
+ dk4maiwdlu.o \
+ dk4maiwdul.o \
+ dk4maiwdsz.o \
+ dk4maiwddi.o \
+ dk4maiwddu.o \
+ dk4maowd.o
+
+# Objects for libdk4maiowh.so or libdk4maiowh.a library
+LIBDK4MAIOWHOBJ= \
+ dk4maiwhic.o \
+ dk4maiwhis.o \
+ dk4maiwhii.o \
+ dk4maiwhmi.o \
+ dk4maiwhli.o \
+ dk4maiwhil.o \
+ dk4maiwhuc.o \
+ dk4maiwhus.o \
+ dk4maiwhui.o \
+ dk4maiwhmu.o \
+ dk4maiwhlu.o \
+ dk4maiwhul.o \
+ dk4maiwhdi.o \
+ dk4maiwhdu.o \
+ dk4maowh.o
+
+# Objects for libdk4maio8d.so or libdk4maio8d.a library
+LIBDK4MAIO8DOBJ= \
+ dk4mao8dbl.o \
+ dk4mai8dbl.o \
+ dk4mai8dic.o \
+ dk4mai8dis.o \
+ dk4mai8dii.o \
+ dk4mai8dmi.o \
+ dk4mai8dli.o \
+ dk4mai8dil.o \
+ dk4mai8ddi.o \
+ dk4mai8duc.o \
+ dk4mai8dus.o \
+ dk4mai8dui.o \
+ dk4mai8dmu.o \
+ dk4mai8dlu.o \
+ dk4mai8dul.o \
+ dk4mai8dsz.o \
+ dk4mai8ddu.o \
+ dk4mao8d.o
+
+# Objects for libdk4maio8h.so or libdk4maio8h.a library
+LIBDK4MAIO8HOBJ= \
+ dk4mai8hic.o \
+ dk4mai8his.o \
+ dk4mai8hii.o \
+ dk4mai8hmi.o \
+ dk4mai8hli.o \
+ dk4mai8hil.o \
+ dk4mai8hdi.o \
+ dk4mai8huc.o \
+ dk4mai8hus.o \
+ dk4mai8hui.o \
+ dk4mai8hmu.o \
+ dk4mai8hlu.o \
+ dk4mai8hul.o \
+ dk4mai8hdu.o \
+ dk4mao8h.o
+
+# Objects for libdk4ma.so or libdk4ma.a library
+LIBDK4MAOBJ= \
+ dk4numl.o \
+ dk4macd.o \
+ dk4macm.o \
+ dk4macll.o \
+ dk4macl.o \
+ dk4maci.o \
+ dk4macs.o \
+ dk4macc.o \
+ dk4maasz.o \
+ dk4maadi.o \
+ dk4maadu.o \
+ dk4maami.o \
+ dk4maamu.o \
+ dk4maall.o \
+ dk4maalu.o \
+ dk4maal.o \
+ dk4maaul.o \
+ dk4maai.o \
+ dk4maaui.o \
+ dk4maas.o \
+ dk4maaus.o \
+ dk4maac.o \
+ dk4maauc.o \
+ dk4maau16.o \
+ dk4maai16.o \
+ dk4maau32.o \
+ dk4maai32.o \
+ dk4maci16.o \
+ dk4maci32.o
+
+# Objects for libdk4dbia.so or libdk4dbia.a library
+LIBDK4DBIAOBJ= \
+ dk4dbia.o
+
+# Objects for libdk4dbi.so or libdk4dbi.a library
+LIBDK4DBIOBJ= \
+ dk4dbit.o \
+ dk4dbitw.o \
+ dk4dbit8.o \
+ dk4dbi.o
+
+# Objects for libdk4base.so or libdk4base.a library
+LIBDK4BASEOBJ= \
+ dk4strd.o \
+ dk4strw.o \
+ dk4str8.o \
+ dk4memcpl.o \
+ dk4memrs.o \
+ dk4mem.o \
+ dk4error.o
+
+# Objects for libdk4.a library
+OBJLIBDK4= $(LIBDK4WXOBJ) \
+ $(LIBDK4LATOBJ) \
+ $(LIBDK4DBIAOBJ) \
+ $(LIBDK4SOCKAOBJ) \
+ $(LIBDK4PPPTAOBJ) \
+ $(LIBDK4APPOBJ) \
+ $(LIBDK4MDRNDOBJ) \
+ $(LIBDK4SOCKOBJ) \
+ $(LIBDK4PPPTOBJ) \
+ $(LIBDK4COBJ) \
+ $(LIBDK4MAIODDOBJ) \
+ $(LIBDK4MAIOWDOBJ) \
+ $(LIBDK4MAIO8DOBJ) \
+ $(LIBDK4MAIODHOBJ) \
+ $(LIBDK4MAIOWHOBJ) \
+ $(LIBDK4MAIO8HOBJ) \
+ $(LIBDK4MAOBJ) \
+ $(LIBDK4DBIOBJ) \
+ $(LIBDK4BASEOBJ)
+
+libdk4.a: # Static library containig all modules
+libdk4.a: $(OBJLIBDK4)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(OBJLIBDK4)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4WXLIBF=libdk4base.so libdk4maio8d.so libdk4maiowd.so libdk4c.so libdk4app.so
+LIBDK4WXLIBS=-ldk4app -ldk4c -ldk4maiowd -ldk4maio8d -ldk4base $(WXLDFLAGS)
+
+libdk4wx.so: # Support for wxWidgets shared
+libdk4wx.so: $(LIBDK4WXLIBF) $(LIBDK4WXOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4WXOBJ) $(LIBDK4WXLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4wx.a: # Support for wxWidgets static
+libdk4wx.a: libdk4c.a $(LIBDK4WXOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4WXOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4SOCKALIBF=libdk4base.so libdk4maio8h.so libdk4maio8d.so libdk4maiodh.so libdk4maiodd.so libdk4sock.so libdk4app.so
+LIBDK4SOCKALIBS=-ldk4app -ldk4sock -ldk4maiodd -ldk4maiodh -ldk4maio8d -ldk4maio8h -ldk4base $(SOCKLIB) $(NSLLIB)
+
+libdk4socka.so: # Socket library with application support
+libdk4socka.so: $(LIBDK4SOCKALIBF) $(LIBDK4SOCKAOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4SOCKAOBJ) $(LIBDK4SOCKALIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4socka.a: # Socket library with application support, static
+libdk4socka.a: libdk4sock.a libdk4app.a $(LIBDK4SOCKAOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4SOCKAOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4DBIALIBF=libdk4base.so libdk4dbi.so libdk4app.so
+LIBDK4DBIALIBS=-ldk4dbi -ldk4app -ldk4base $(DBLIB)
+
+libdk4dbia.so: # Simple database interface with app support
+libdk4dbia.so: $(LIBDK4DBIALIBF) $(LIBDK4DBIAOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4DBIAOBJ) $(LIBDK4DBIALIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4dbia.a: # Simple database interface with app support, static
+libdk4dbia.a: libdk4dbi.a libdk4app.a $(LIBDK4DBIAOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4DBIAOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4SOCKLIBF=libdk4base.so libdk4maio8d.so libdk4c.so
+LIBDK4SOCKLIBS=-ldk4c -ldk4maio8d -ldk4base $(SOCKLIB) $(NSLLIB)
+
+libdk4sock.so: # Socket library without application support
+libdk4sock.so: $(LIBDK4SOCKLIBF) $(LIBDK4SOCKOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4SOCKOBJ) $(LIBDK4SOCKLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4sock.a: # Socket library without app support, static version
+libdk4sock.a: libdk4c.a $(LIBDK4SOCKOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4SOCKOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4LATLIBF=libdk4base.so libdk4ma.so libdk4maio8h.so libdk4maiodh.so libdk4maiodd.so libdk4c.so libdk4app.so
+LIBDK4LATLIBS=-ldk4app -ldk4c -ldk4maiodd -ldk4maiodh -ldk4maio8h -ldk4ma -ldk4base
+
+libdk4lat.so: # Text to LaTeX conversion library
+libdk4lat.so: $(LIBDK4LATLIBF) $(LIBDK4LATOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4LATOBJ) $(LIBDK4LATLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4lat.a: # Text to LaTeX conversion static library
+libdk4lat.a: libdk4c.a $(LIBDK4LATOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4LATOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4PPPTALIBF=libdk4base.so libdk4c.so libdk4pppt.so libdk4app.so
+LIBDK4PPPTALIBS=-ldk4app -ldk4pppt -ldk4c -ldk4base
+
+libdk4pppta.so: # PS+TeX,PDF+TeX,PGF creator library
+libdk4pppta.so: $(LIBDK4PPPTALIBF) $(LIBDK4PPPTAOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4PPPTAOBJ) $(LIBDK4PPPTALIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4pppta.a: # PS+TeX,PDF+TeX,PGF creator library static
+libdk4pppta.a: libdk4app.a libdk4pppt.a $(LIBDK4PPPTAOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4PPPTAOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4APPLIBF=libdk4base.so libdk4ma.so libdk4maio8d.so libdk4maiodd.so libdk4c.so
+LIBDK4APPLIBS=-ldk4c -ldk4maiodd -ldk4maio8d -ldk4ma -ldk4base
+
+libdk4app.so: # Application support library shared
+libdk4app.so: $(LIBDK4APPLIBF) $(LIBDK4APPOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4APPOBJ) $(LIBDK4APPLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4app.a: # Application support library static
+libdk4app.a: libdk4c.a $(LIBDK4APPOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4APPOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4MDRNDLIBF=libdk4base.so libdk4c.so
+LIBDK4MDRNDLIBS=-ldk4c -ldk4base $(CRYPTO)
+
+libdk4mdrnd.so: # Message digest and random library shared
+libdk4mdrnd.so: $(LIBDK4MDRNDLIBF) $(LIBDK4MDRNDOBJ)
+ -[ ! -f $@ ] || rm -fr $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4MDRNDOBJ) $(LIBDK4MDRNDLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4mdrnd.a: # Message digest and random library static
+libdk4mdrnd.a: libdk4c.a $(LIBDK4MDRNDOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4MDRNDOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4PPPTLIBF=libdk4base.so libdk4maiodd.so libdk4c.so
+LIBDK4PPPTLIBS=-ldk4c -ldk4maiodd -ldk4base
+
+libdk4pppt.so: # PS+TeX,PDF+TeX,PGF creator library
+libdk4pppt.so: $(LIBDK4PPPTLIBF) $(LIBDK4PPPTOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4PPPTOBJ) $(LIBDK4PPPTLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4pppt.a: # PS+TeX,PDF+TeX,PGF creator library static
+libdk4pppt.a: libdk4c.a $(LIBDK4PPPTOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4PPPTOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4CLIBF=libdk4base.so libdk4ma.so libdk4maio8d.so libdk4maiodd.so
+LIBDK4CLIBS=-ldk4maiodd -ldk4maio8d -ldk4ma -ldk4base $(BZLIB) $(ZLIB) -lm
+
+libdk4c.so: # General C library shared
+libdk4c.so: $(LIBDK4CLIBF) $(LIBDK4COBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4COBJ) $(LIBDK4CLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4c.a: # General C library static
+libdk4c.a: libdk4maiodd.a $(LIBDK4COBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4COBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4DBILIBF=libdk4base.so libdk4ma.so libdk4c.so
+LIBDK4DBILIBS=-ldk4c -ldk4ma -ldk4base $(DBLIB)
+
+libdk4dbi.so: # Simple database interface
+libdk4dbi.so: $(LIBDK4DBILIBF) $(LIBDK4DBIOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4DBIOBJ) $(LIBDK4DBILIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4dbi.a: # Simple database interface static library
+libdk4dbi.a: libdk4ma.a $(LIBDK4DBIOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4DBIOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4MAIOXDLIBF=libdk4base.so libdk4maio8d.so libdk4maiowd.so
+LIBDK4MAIOXDLIBS=-ldk4maiowd -ldk4maio8d -ldk4base
+
+libdk4maioxd.so: # Numeric values I/O, wxChar, decimal, shared
+libdk4maioxd.so: $(LIBDK4MAIOXDLIBF) $(LIBDK4MAIOXDOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4MAIOXDOBJ) $(LIBDK4MAIOXDLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4maioxd.a: # Numeric values I/O, wxChar, decimal, static
+libdk4maioxd.a: libdk4maio8d.a libdk4ma.a $(LIBDK4MAIOXDOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4MAIOXDOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4MAIODDLIBF=libdk4base.so libdk4maio8d.so
+LIBDK4MAIODDLIBS=-ldk4maio8d -ldk4base
+
+libdk4maiodd.so: # Numeric values I/O, dkChar, decimal, shared
+libdk4maiodd.so: $(LIBDK4MAIODDLIBF) $(LIBDK4MAIODDOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4MAIODDOBJ) $(LIBDK4MAIODDLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4maiodd.a: # Numeric values I/O, dkChar, decimal, static
+libdk4maiodd.a: libdk4maio8d.a libdk4ma.a $(LIBDK4MAIODDOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4MAIODDOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4MAIOWDLIBF=libdk4base.so libdk4ma.so
+LIBDK4MAIOWDLIBS=-ldk4ma -ldk4base
+
+libdk4maiowd.so: # Numeric values I/O, wchar_t, decimal, shared
+libdk4maiowd.so: $(LIBDK4MAIOWDLIBF) $(LIBDK4MAIOWDOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4MAIOWDOBJ) $(LIBDK4MAIOWDLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4maiowd.a: # Numeric values I/O, wchar_t, decimal, static
+libdk4maiowd.a: libdk4ma.a $(LIBDK4MAIOWDOBJ)
+ [ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4MAIOWDOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4MAIO8DLIBF=libdk4base.so libdk4ma.so
+LIBDK4MAIO8DLIBS=-ldk4ma -ldk4base
+
+libdk4maio8d.so: # Numeric values I/O, char, decimal, shared
+libdk4maio8d.so: $(LIBDK4MAIO8DLIBF) $(LIBDK4MAIO8DOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4MAIO8DOBJ) $(LIBDK4MAIO8DLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4maio8d.a: # Numeric values I/O, char, decimal, static
+libdk4maio8d.a: libdk4ma.a $(LIBDK4MAIO8DOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4MAIO8DOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4MAIODHLIBF=libdk4base.so libdk4maio8h.so
+LIBDK4MAIODHLIBS=-ldk4maio8h -ldk4base
+
+libdk4maiodh.so: # Numeric values I/O, dkChar, hexadecimal, shared
+libdk4maiodh.so: $(LIBDK4MAIODHLIBF) $(LIBDK4MAIODHOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4MAIODHOBJ) $(LIBDK4MAIODHLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4maiodh.a: # Numeric values I/O, dkChar, hexadecimal, static
+libdk4maiodh.a: libdk4ma.a $(LIBDK4MAIODHOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4MAIODHOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4MAIOWHLIBF=libdk4base.so
+LIBDK4MAIOWHLIBS=-ldk4base
+
+libdk4maiowh.so: # Numeric values I/O, wchar_t, hexadecimal, shared
+libdk4maiowh.so: $(LIBDK4MAIOWHLIBF) $(LIBDK4MAIOWHOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4MAIOWHOBJ) $(LIBDK4MAIOWHLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4maiowh.a: # Numeric values I/O, wchar_t, hexadecimal, static
+libdk4maiowh.a: libdk4ma.a $(LIBDK4MAIOWHOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4MAIOWHOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4MAIO8HLIBF=libdk4base.so
+LIBDK4MAIO8HLIBS=-ldk4base
+
+libdk4maio8h.so: # Numeric values I/O, char, hexadecimal, shared
+libdk4maio8h.so: $(LIBDK4MAIO8HLIBF) $(LIBDK4MAIO8HOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4MAIO8HOBJ) $(LIBDK4MAIO8HLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4maio8h.a: # Numeric values I/O, char, hexadecimal, static
+libdk4maio8h.a: libdk4ma.a $(LIBDK4MAIO8HOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4MAIO8HOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4MALIBF=libdk4base.so
+LIBDK4MALIBS=-ldk4base
+
+libdk4ma.so: # Mathematics library, shared
+libdk4ma.so: $(LIBDK4MALIBF) $(LIBDK4MAOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4MAOBJ) $(LIBDK4MALIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4ma.a: # Mathematics library, static
+libdk4ma.a: libdk4base.a $(LIBDK4MAOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4MAOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4BASELIBF=
+LIBDK4BASELIBS=
+
+libdk4base.so: # Base library, shared
+libdk4base.so: $(LIBDK4BASELIBF) $(LIBDK4BASEOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4BASEOBJ) $(LIBDK4BASELIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4base.a: # Base library, static
+libdk4base.a: $(LIBDK4BASEOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4BASEOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+#
+# Programs to fix configure script results to DK4_HAVE_... constants
+#
+
+dk3config: # Program: Show configuration for dk3... modules
+dk3config$(EXEEXT): dk3config.c
+ @-[ ! -f dk3conig ] || rm -f dk3config
+ @$(COMPILEC) $(CFLAGS) $(LDFLAGS) -L. -o $@ dk3config.c -lm
+ @chmod 755 dk3config
+
+dk4config: # Program: Show configuration for dk4... modules
+dk4config$(EXEEXT): dk4config.cpp
+ @-[ ! -f $@ ] || rm -f $@
+ @$(COMPILECPP) $(LDFLAGS) $(WXLDFLAGS) -o $@ dk4config.cpp
+ @chmod 755 $@
+
+wxcs: # Program: Show wxChar character size
+wxcs$(EXEEXT): wxcs.cpp
+ @-[ ! -f $@ ] || rm -f $@
+ @$(COMPILECPP) $(LDFLAGS) $(WXLDFLAGS) -o $@ wxcs.cpp
+ @chmod 755 $@
+
+
+
+# ##### Start of dktools-4 section
+
+DKCATLIBF=libdk4.a
+DKCATLIBS=-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)
+
+dk-cat: # Program: Show file contents
+dk-cat$(EXEEXT): $(DKCATLIBF) dk-cat.o
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk-cat.o $(DKCATLIBS)
+ chmod 755 $@
+
+
+
+DKBLKSLIBF=libdk4.a
+DKBLKSLIBS=-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)
+
+dk-blks: # Program: Adjust block size
+dk-blks$(EXEEXT): $(DKBLKSLIBF) dk-blks.o
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk-blks.o $(DKBLKSLIBS)
+ chmod 755 $@
+
+
+
+DKSQLSPLITLIBF=libdk4.a
+DKSQLSPLITLIBS=-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)
+
+dk-sqlsplit: # Program: Split overlong SQL lines
+dk-sqlsplit$(EXEEXT): $(DKSQLSPLITLIBF) dk-sqlsplit.o
+ -[ ! -f $@ ] || rm -fr $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk-sqlsplit.o $(DKSQLSPLITLIBS)
+ chmod 755 $@
+
+
+
+DKERADISKLIBF=libdk4.a
+DKERADISKLIBS=-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)
+
+dk-eradisk: # Program: Create data stream for disk deletion
+dk-eradisk$(EXEEXT): $(DKERADISKLIBF) dk-eradisk.o
+ -[ ! -f $@ ] || rm -fr $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk-eradisk.o $(DKERADISKLIBS)
+ chmod 755 $@
+
+
+
+DKLSOBJ= dk-ls.o dk-ls-to.o
+
+DKLSLIBF=libdk4.a
+DKLSLIBS=-ldk4 $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)
+
+dk-ls: # Program: SHow information about files
+dk-ls$(EXEEXT): $(DKLSLIBF) $(DKLSOBJ)
+ -[ ! -f $@ ] || rm -fr $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ $(DKLSOBJ) $(DKLSLIBS)
+ chmod 755 $@
+
+
+
+DKSORTOBJ= dk-sort.o
+
+DKSORTLIBF=libdk4.a
+DKSORTLIBS=-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)
+
+dk-sort: # Program: Text sorting in different encodings
+dk-sort$(EXEEXT): $(DKSORTLIBF) $(DKSORTOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -L. -o $@ $(DKSORTOBJ) $(DKSORTLIBS)
+ chmod 755 $@
+
+
+
+DKFICLIBF=libdk4.a
+DKFICLIBS=-ldk4 $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)
+
+dk-fic: # Program: File integrity checker (CLI)
+dk-fic$(EXEEXT): $(DKFICLIBF) dk-fic.o
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk-fic.o $(DKFICLIBS)
+ chmod 755 $@
+
+
+
+DKUIDLIBF=libdk4.a
+DKUIDLIBS=-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)
+
+dk-uid: # Program: Find free UID in given range
+dk-uid$(EXEEXT): $(DKUIDLIBF) dk-uid.o
+ [ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk-uid.o $(DKUIDLIBS)
+ chmod 755 $@
+
+
+
+DKPWGENLIBF=libdk4.a
+DKPWGENLIBS=-ldk4 $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)
+
+dk-pwgen: # Program: Passwort/PIN/WiFi key generator
+dk-pwgen$(EXEEXT): $(DKPWGENLIBF) dk-pwgen.o
+ [ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk-pwgen.o $(DKPWGENLIBS)
+ chmod 755 $@
+
+
+
+DKRANDLIBF=libdk4.a
+DKRANDLIBS=-ldk4 $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)
+
+dk-rand: # Program: Random data generator
+dk-rand$(EXEEXT): $(DKRANDLIBF) dk-rand.o
+ [ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk-rand.o $(DKRANDLIBS)
+ chmod 755 $@
+
+
+
+DKT2HLIBF=libdk4.a
+DKT2HLIBS=-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)
+
+dk-t2h: # Program: Convert text to HTML
+dk-t2h$(EXEEXT): $(DKT2HLIBF) dk-t2h.o
+ [ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk-t2h.o $(DKT2HLIBS)
+ chmod 755 $@
+
+
+
+DKT2LLIBF=libdk4.a
+DKT2LLIBS=-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)
+
+dk-t2l: # Program: Convert text to LaTeX
+dk-t2l$(EXEEXT): $(DKT2LLIBF) dk-t2l.o
+ [ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk-t2l.o $(DKT2LLIBS)
+ chmod 755 $@
+
+
+
+DKHEXLIBF=libdk4.a
+DKHEXLIBS=-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)
+
+dk-hex: # Program: Show file contents in hexadecimal notation
+dk-hex$(EXEEXT): $(DKHEXLIBF) dk-hex.o
+ [ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk-hex.o $(DKHEXLIBS)
+ chmod 755 $@
+
+
+
+DKBMMLIBF=libdk4.a
+DKBMMLIBS=-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)
+
+dk-bmm: # Program: Backup media management
+dk-bmm$(EXEEXT): $(DKBMMLIBF) dk-bmm.o
+ [ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk-bmm.o $(DKBMMLIBS)
+ chmod 755 $@
+
+
+
+DKPWDLIBF=libdk4.a
+DKPWDLIBS=-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)
+
+dk-pwd: # Program: Print working directory
+dk-pwd$(EXEEXT): $(DKPWDLIBF) dk-pwd.o
+ [ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk-pwd.o $(DKPWDLIBS)
+ chmod 755 $@
+
+
+
+DKRECVLIBF=libdk4.a
+DKRECVLIBS=-ldk4 $(CLILIB) $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) -lm
+
+dk-recv: # Program: Receive data stream from dk-send process
+dk-recv$(EXEEXT): $(DKRECVLIBF) dk-recv.o
+ [ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk-recv.o $(DKRECVLIBS)
+ chmod 755 $@
+
+
+
+DKSENDLIBF=libdk4.a
+DKSENDLIBS=-ldk4 $(CLILIB) $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) -lm
+
+dk-send: # Program: Send data to one or multiple recipients
+dk-send$(EXEEXT): $(DKSENDLIBF) dk-send.o
+ [ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk-send.o $(DKSENDLIBS)
+ chmod 755 $@
+
+
+
+PRINTQDOBJ= printqd.o
+
+PRINTQDLIBF=libdk4.a
+PRINTQDLIBS=-ldk4 $(DBLIB) $(SOCKLIB) $(NSLLIB)
+
+printqd: # Program: Print quota enforcement daemon
+printqd$(EXEEXT): $(PRINTQDLIBF) $(PRINTQDOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ $(PRINTQDOBJ) $(PRINTQDLIBS)
+ chmod 755 $@
+
+
+
+PRINTQDCOBJ= printqdc.o
+
+PRINTQDCLIBF=libdk4.a
+PRINTQDCLIBS=-ldk4 $(SOCKLIB) $(NSLLIB)
+
+printqdc: # Program: Print quota client
+printqdc$(EXEEXT): $(PRINTQDCLIBF) $(PRINTQDCOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ $(PRINTQDCOBJ) $(PRINTQDCLIBS)
+ chmod 755 $@
+
+
+
+WXPQDICOBJ= WxpqdicApp.o WxpqdicFrame.o
+
+WXPQDICLIBF=libdk4.a
+WXPQDICLIBS=-ldk4 $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)
+
+wxpqdic: # Program: Client for printqd queries
+wxpqdic$(EXEEXT): $(WXPQDICLIBF) $(WXPQDICOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C++) ' $@
+ $(LDCPP) $(ENTRY) -o $@ $(WXPQDICOBJ) $(WXPQDICLIBS)
+ chmod 755 $@
+
+
+
+PJSNMPLIBF=libdk4.a
+PJSNMPLIBS=-ldk4 $(NETSNMP_LIBS) $(SOCKLIB) $(NSLLIB)
+
+pjsnmp: # Program: Print job transfer using TCP and SNMP
+pjsnmp$(EXEEXT): $(PJSNMPLIBF) pjsnmp.o
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ pjsnmp.o $(PJSNMPLIBS)
+ chmod 755 $@
+
+
+
+PRMONSNMPLIBF=libdk4.a
+PRMONSNMPLIBS=-ldk4 $(NETSNMP_LIBS) $(SOCKLIB) $(NSLLIB)
+
+prmonsnmp: # Program: Monitor printers using SNMP
+prmonsnmp$(EXEEXT): $(PRMONSNMPLIBF) prmonsnmp.o
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ prmonsnmp.o $(PRMONSNMPLIBS)
+ chmod 755 $@
+
+
+
+LPRNGCLLIBF=libdk4.a
+LPRNGCLLIBS=-ldk4 $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) -lm
+
+lprngcl: # Program: LPRng queue cleanup
+lprngcl$(EXEEXT): $(LPRNGCLLIBF) lprngcl.o
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ lprngcl.o $(LPRNGCLLIBS)
+ chmod 755 $@
+
+
+
+DKDBT2LIBF=libdk4.a
+DKDBT2LIBS=-ldk4 $(DBLIBSOCK) $(CLILIB) $(BZLIB) $(ZLIB)
+
+dk-db2t: # Program: Convert database to text
+dk-db2t$(EXEEXT): $(DKDBT2LIBF) dk-db2t.o
+ [ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk-db2t.o $(DKDBT2LIBS)
+ chmod 755 $@
+
+dk-dbco: # Program: Copy database
+dk-dbco$(EXEEXT): $(DKDBT2LIBF) dk-dbco.o
+ [ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk-dbco.o $(DKDBT2LIBS)
+ chmod 755 $@
+
+dk-t2db: # Program: Convert text to database
+dk-t2db$(EXEEXT): $(DKDBT2LIBF) dk-t2db.o
+ [ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk-t2db.o $(DKDBT2LIBS)
+ chmod 755 $@
+
+
+
+RSHDOWNLIBF=libdk4.a
+RSHDOWNLIBS=-ldk4 $(SOCKLIB) $(NSLLIB)
+
+rshdown: # Program: Remote shutdown
+rshdown$(EXEEXT): $(RSHDOWNLIBF) rshdown.o
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ rshdown.o $(RSHDOWNLIBS)
+ chmod 755 $@
+
+
+
+DK4INFOLIBF=libdk4.a
+DK4INFOLIBS=-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)
+
+dk4info: # Program: Show information about this build
+dk4info$(EXEEXT): $(DK4INFOLIBF) dk4info.o
+ [ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk4info.o $(DK4INFOLIBS)
+ chmod 755 $@
+
+# ##### End of dktools-4 section
+
+
+
+# ##### Start of dktools-3 section
+
+# Objects for libdk3c.so or libdk3c.a library
+LIBDK3COBJ= \
+ dk3ufi.o \
+ dk3opt.o \
+ dk3bf.o \
+ dk3se.o \
+ dk3app.o \
+ dk3strm.o \
+ dk3print.o \
+ dk3prcfg.o \
+ dk3strkv.o \
+ dk3sto.o \
+ dk3dir.o \
+ dk3enc.o \
+ dk3str.o \
+ dk3cores.o \
+ dk3sf.o \
+ dk3echo.o \
+ dk3signl.o \
+ dk3ct.o \
+ dk3mas.o \
+ dk3maus.o \
+ dk3mai.o \
+ dk3maui.o \
+ dk3mal.o \
+ dk3maul.o \
+ dk3mad.o \
+ dk3madsc.o \
+ dk3madic.o \
+ dk3madlc.o \
+ dk3maidd.o \
+ dk3maihd.o \
+ dk3maodd.o \
+ dk3maohd.o \
+ dk3maid8.o \
+ dk3maih8.o \
+ dk3maod8.o \
+ dk3maoh8.o \
+ dk3masts.o \
+ dk3madfo.o \
+ dk3madso.o \
+ dk3madsi.o \
+ dk3inst.o \
+ dk3srch.o \
+ dk3bits.o \
+ dk3mem.o \
+ dk3bb.o \
+ dk3bezcu.o \
+ dk3xsp.o \
+ dk3kv.o \
+ dk3trace.o
+
+# Objects for libdk3of.so or libdk3of.a library
+LIBDK3OFOBJ= \
+ dk3of.o \
+ dk3strmb.o \
+ dk3strmg.o
+
+# Objects for libdk3csrnd.so or libdk3csrnd.a library
+LIBDK3CSRNDOBJ= \
+ dk3chks.o \
+ dk3appr.o
+
+# Objects for libdk3bif.so or libdk3bif.a library
+LIBDK3BIFOBJ= \
+ dk3bifa.o \
+ dk3bif.o \
+ dk3pixre.o
+
+# Objects for libdk3dbi.so or libdk3dbi.a library
+LIBDK3DBIOBJ= \
+ dk3dbi.o
+
+# Objects for libdk3bmeps.so or libdk3bmeps.a library
+LIBDK3BMEPSOBJ= \
+ dk3bm.o \
+ dk3bmeo.o \
+ dk3bmep.o \
+ dk3bmeps.o \
+ dk3bmj.o \
+ dk3pdf.o \
+ dk3paper.o
+
+# Objects for libdk3fig.so or libdk3fig.a library
+LIBDK3FIGOBJ= \
+ dk3figbb.o \
+ dk3figpr.o \
+ dk3figah.o \
+ dk3figrd.o \
+ dk3figto.o \
+ dk3fig.o \
+ dk3font.o \
+ dk3ct.o
+
+# Objects for libdk3wx.so or libdk3wx.a library
+LIBDK3WXOBJ= \
+ DkWxProgressDialog.o \
+ DkWxCommunicator.o \
+ DkWxFrame.o \
+ DkWxDialog.o \
+ DkWxHelpController.o \
+ DkWxAppHelper.o \
+ DkWxColorView.o \
+ DkWxBufferedControl.o \
+ DkWxProcessingIdleController.o \
+ DkWxProcessingController.o \
+ dk3wxs.o
+
+# Objects for libdk3.a library
+LIBDK3ALLOBJ= $(LIBDK3WXOBJ) \
+ $(LIBDK3FIGOBJ) \
+ $(LIBDK3BMEPSOBJ) \
+ $(LIBDK3BIFOBJ) \
+ $(LIBDK3CSRNDOBJ) \
+ $(LIBDK3DBIOBJ) \
+ $(LIBDK3OFOBJ) \
+ $(LIBDK3COBJ)
+
+
+
+libdk3.a: # Large library containing all dktools-3 modules.
+libdk3.a: $(LIBDK3ALLOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ $(AR) -r $@ $(LIBDK3ALLOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+
+
+LIBDK3TRACELIBF=
+LIBDK3TRACELIBS=
+
+libdk3trace.so: # The libdk3trace library (shared)
+libdk3trace.so: $(LIBDK3TRACELIBF) dk3trace.o
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ $(MKSOLIB) dk3trace.o $(LIBDK3TRACELIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk3trace.a: # The libdk3trace library (static)
+libdk3trace.a: dk3trace.o
+ -[ ! -f $@ ] || rm -f $@
+ $(AR) -r $@ dk3trace.o
+ $(RANLIB) $@
+ chmod 644 $@
+
+
+
+LIBDK3CLIBF=
+LIBDK3CLIBS=$(BZLIB) $(ZLIB) -lm
+
+libdk3c.so: # The libdk3c library (shared).
+libdk3c.so: $(LIBDK3CLIBF) $(LIBDK3COBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ $(MKSOLIB) $(LIBDK3COBJ) $(LIBDK3CLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk3c.a: # The libdk3c library (static).
+libdk3c.a: $(LIBDK3COBJ)
+ -[ ! -f $@ ] || rm -f $@
+ $(AR) -r $@ $(LIBDK3COBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+
+
+LIBDK3OFLIBF=libdk3c.so
+LIBDK3OFLIBS=-ldk3c $(BZLIB) $(ZLIB)
+
+libdk3of.so: # The dktools-3 output filter library (shared).
+libdk3of.so: $(LIBDK3OFLIBF) $(LIBDK3OFOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ $(MKSOLIB) $(LIBDK3OFOBJ) $(LIBDK3OFLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk3of.a: # The dktools-3 output filter library (static).
+libdk3of.a: $(LIBDK3OFOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ $(AR) -r $@ $(LIBDK3OFOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+
+
+LIBDK3CSRNDLIBF=libdk3c.so
+LIBDK3CSRNDLIBS=-ldk3c $(CRYPTO)
+
+libdk3csrnd.so: # The dktools-3 checksum and random library (shared).
+libdk3csrnd.so: $(LIBDK3CSRNDLIBF) $(LIBDK3CSRNDOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ $(MKSOLIB) $(LIBDK3CSRNDOBJ) $(LIBDK3CSRNDLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk3csrnd.a: # The dktools-3 checksum and random library (static).
+libdk3csrnd.a: $(LIBDK3CSRNDOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ $(AR) -r $@ $(LIBDK3CSRNDOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+
+
+LIBDK3BIFLIBF=libdk3c.so
+LIBDK3BIFLIBS=-ldk3c $(IMGLIBS)
+
+libdk3bif.so: # the dktools-3 bitmap image file library (shared).
+libdk3bif.so: $(LIBDK3BIFLIBF) $(LIBDK3BIFOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ $(MKSOLIB) $(LIBDK3BIFOBJ) $(LIBDK3BIFLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk3bif.a: # the dktools-3 bitmap image file library (static).
+libdk3bif.a: $(LIBDK3BIFOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ $(AR) -r $@ $(LIBDK3BIFOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+
+
+LIBDK3DBILIBF=libdk3c.so
+LIBDK3DBILIBS=-ldk3c $(DBLIB)
+
+libdk3dbi.so: # The dktools-3 data base interface library (shared).
+libdk3dbi.so: $(LIBDK3DBILIBF) $(LIBDK3DBIOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ $(MKSOLIB) $(LIBDK3DBIOBJ) $(LIBDK3DBILIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk3dbi.a: # The dktools-3 data base interface library (static).
+libdk3dbi.a: $(LIBDK3DBIOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ $(AR) -r $@ $(LIBDK3DBIOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+
+
+LIBDK3BMEPSLIBF=libdk3c.so libdk3of.so libdk3bif.so
+LIBDK3BMEPSLIBS=-ldk3bif -ldk3of -ldk3c -lm
+
+libdk3bmeps.so: # The dktools-3 bitmap to EPS library (shared).
+libdk3bmeps.so: $(LIBDK3BMEPSLIBF) $(LIBDK3BMEPSOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ $(MKSOLIB) $(LIBDK3BMEPSOBJ) $(LIBDK3BMEPSLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk3bmeps.a: # The dktools-3 bitmap to EPS library (static).
+libdk3bmeps.a: $(LIBDK3BMEPSOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ $(AR) -r $@ $(LIBDK3BMEPSOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+
+
+LIBDK3FIGLIBF=libdk3c.so
+LIBDK3FIGLIBS=-ldk3c -lm
+
+libdk3fig.so: # The dktools-3 Fig file library (shared).
+libdk3fig.so: $(LIBDK3FIGLIBF) $(LIBDK3FIGOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ $(MKSOLIB) $(LIBDK3FIGOBJ) $(LIBDK3FIGLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk3fig.a: # The dktools-3 Fig file library (static).
+libdk3fig.a: $(LIBDK3FIGOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ $(AR) -r $@ $(LIBDK3FIGOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+
+
+LIBDK3WXLIBF=libdk3c.so
+LIBDK3WXLIBS=-ldk3c $(WXLDFLAGS)
+
+libdk3wx.so: # The dktools-3 GUI library (shared).
+libdk3wx.so: $(LIBDK3WXLIBF) $(LIBDK3WXOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ $(MKSOLIB) $(LIBDK3WXOBJ) $(LIBDK3WXLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk3wx.a: # The dktools-3 GUI library (static).
+libdk3wx.a: $(LIBDK3WXOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ $(AR) -r $@ $(LIBDK3WXOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+
+
+DKCTOBJ= dkct.o dkct-str.o dkct-tr.o dkct-au.o dkct-gui.o dkct-to.o
+
+DKCTLIBF=libdk3.a
+DKCTLIBS=-ldk3 $(CLILIB) $(BZLIB) $(ZLIB)
+
+dkct: # Program: Dirk Krause's C tool (CLI)
+dkct$(EXEEXT): $(DKCTLIBF) $(DKCTOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ $(DKCTOBJ) $(DKCTLIBS)
+ chmod 755 $@
+
+
+
+ADDCTRLDLIBF=libdk3.a
+ADDCTRLDLIBS=-ldk3 $(CLILIB) $(BZLIB) $(ZLIB)
+
+addctrld: # Program: Filter to ensure Ctrl-D as final byte
+addctrld$(EXEEXT): $(ADDCTRLDLIBF) addctrld.o
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ addctrld.o $(ADDCTRLDLIBS)
+ chmod 755 $@
+
+
+
+BMPPOBJ= bmeps3.o
+
+BMPPLIBF=libdk3.a
+BMPPLIBS=-ldk3 $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB) -lm
+
+bmpp: # Program: Bitmap to PS/PDF converter (CLI)
+bmpp$(EXEEXT): $(BMPPLIBF) $(BMPPOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ $(BMPPOBJ) $(BMPPLIBS)
+ chmod 755 $@
+
+
+
+FIG2LATOBJ= fig2lat.o f2lopt.o f2lud.o f2ludpat.o f2lpgf.o f2lpdf.o \
+ f2leps.o f2lsvg.o f2lsvgst.o f2lto.o f2lpara.o
+
+FIG2LATLIBF=libdk3.a
+FIG2LATLIBS=-ldk3 $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB) -lm
+
+fig2lat: # Program: Fig to LaTeX converter
+fig2lat$(EXEEXT): $(FIG2LATLIBF) $(FIG2LATOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ $(FIG2LATOBJ) $(FIG2LATLIBS)
+ chmod 755 $@
+
+
+
+HTMLBOOKOBJ= htmlbook.o hbnode.o hbconf.o hbhtml.o hbtool.o hbindex.o \
+ hbcont.o hbimgdim.o hbchm.o
+
+HTMLBOOKLIBF=libdk3.a
+HTMLBOOKLIBS=-ldk3 $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)
+
+htmlbook: # Program: HTML book creator
+htmlbook$(EXEEXT): $(HTMLBOOKLIBF) $(HTMLBOOKOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ $(HTMLBOOKOBJ) $(HTMLBOOKLIBS)
+ chmod 755 $@
+
+
+
+DK3INFOLIBF=libdk3.a
+DK3INFOLIBS=-ldk3 $(CLILIB) $(BZLIB) $(ZLIB)
+
+dk3info: # Program: Information about this installation
+dk3info$(EXEEXT): $(DK3INFOLIBF) dk3info.o
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk3info.o $(DK3INFOLIBS)
+ chmod 755 $@
+
+
+
+PLPDFTEXLIBF=libdk3.a
+PLPDFTEXLIBS=-ldk3 $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB) -lm
+
+plpdftex: # Program: Plot driver for octpgfpl package
+plpdftex$(EXEEXT): $(PLPDFTEXLIBF) plpdftex.o plptcol.o
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ plpdftex.o plptcol.o $(PLPDFTEXLIBS)
+ chmod 755 $@
+
+
+
+DKWXWIZLIBF=libdk3.a
+DKWXWIZLIBS=-ldk3 $(CLILIB) $(BZLIB) $(ZLIB)
+
+dkwxwiz: # Program: Create dktools/wxwidgets based projects
+dkwxwiz$(EXEEXT): $(DKWXWIZLIBF) dkwxwiz.o
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dkwxwiz.o $(DKWXWIZLIBS)
+ chmod 755 $@
+
+
+
+# Some special modules for GUI programs
+
+dkct-str-gui.cpp: dkct-str.c
+ -[ ! -f $@ ] || rm -f $@
+ cat dk3usewx.c dkct-str.c > $@
+
+dkct-tr-gui.cpp: dkct-tr.c
+ -[ ! -f $@ ] || rm -f $@
+ cat dk3usewx.c dkct-tr.c > $@
+
+dkct-au-gui.cpp: dkct-au.c
+ -[ ! -f $@ ] || rm -f $@
+ cat dk3usewx.c dkct-au.c > $@
+
+dkct-gui-gui.cpp: dkct-gui.c
+ -[ ! -f $@ ] || rm -f $@
+ cat dk3usewx.c dkct-gui.c > $@
+
+dkct-to-gui.cpp: dkct-to.c
+ -[ ! -f $@ ] || rm -f $@
+ cat dk3usewx.c dkct-to.c > $@
+
+dk3bm-gui.cpp: dk3bm.c
+ -[ ! -f $@ ] || rm -f $@
+ cat dk3usewx.c dk3bm.c > $@
+
+dk3bmj-gui.cpp: dk3bmj.c
+ -[ ! -f $@ ] || rm -f $@
+ cat dk3usewx.c dk3bmj.c > $@
+
+dk3pdf-gui.cpp: dk3pdf.c
+ -[ ! -f $@ ] || rm -f $@
+ cat dk3usewx.c dk3pdf.c > $@
+
+dk3bifa-gui.cpp: dk3bifa.c
+ -[ ! -f $@ ] || rm -f $@
+ cat dk3usewx.c dk3bifa.c > $@
+
+dk3bif-gui.cpp: dk3bif.c
+ -[ ! -f $@ ] || rm -f $@
+ cat dk3usewx.c dk3bif.c > $@
+
+
+
+DKWXTRACEOBJ= DkWxTraceApp.o DkWxTraceFrame.o DkWxTraceThread.o \
+ DkWxTraceOptionsDialog.o \
+ dkct-str-gui.o dkct-tr-gui.o dkct-au-gui.o dkct-gui-gui.o dkct-to-gui.o
+
+WXDKCTLIBF=libdk3.a
+WXDKCTLIBS=-ldk3 $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)
+
+wxdkct: # Program: Dirk Krause's C tool (GUI)
+wxdkct$(EXEEXT): $(WXDKCTLIBF) $(DKWXTRACEOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C++) ' $@
+ $(LDCPP) $(ENTRY) -o $@ $(DKWXTRACEOBJ) $(WXDKCTLIBS)
+ chmod 755 $@
+
+
+
+WXBMPPOBJ= DkWxBmepsApp.o DkWxBmepsFrame.o DkWxBmepsThread.o \
+ DkWxBmepsOptionsDialog.o \
+ dk3bm-gui.o dk3bmj-gui.o dk3bmeo.o dk3bmeps.o dk3pdf-gui.o dk3paper.o \
+ dk3bifa-gui.o dk3bif-gui.o dk3pixre.o
+
+WXBMPP2OBJ= \
+ DkWxProgressDialog.o DkWxFrame.o DkWxAppHelper.o DkWxHelpController.o \
+ DkWxCommunicator.o DkWxColorView.o dk3wxs.o dk3opt.o dk3app.o \
+ dk3wreg.o dk3of.o dk3strm.o dk3sto.o dk3dir.o dk3enc.o dk3str.o \
+ dk3sf.o dk3maui.o dk3mal.o dk3maul.o dk3mad.o dk3madlc.o \
+ dk3maidd.o dk3maodd.o dk3maid8.o dk3maod8.o dk3madfo.o dk3madso.o \
+ dk3madsi.o dk3inst.o dk3srch.o dk3bits.o dk3mem.o dk3trace.o
+
+WXBMPPLIBF=libdk3.a
+WXBMPPLIBS=-ldk3 $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)
+
+wxbmpp: # Program: Bitmap to PS/PDF converter (GUI)
+wxbmpp$(EXEEXT): $(WXBMPPLIBF) $(WXBMPPOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C++) ' $@
+ $(LDCPP) $(ENTRY) -o $@ $(WXBMPPOBJ) $(WXBMPPLIBS)
+ chmod 755 $@
+
+
+
+WXDKFCSOBJ= Dk4FcsApp.o Dk4FcsFrame.o
+
+WXDKFCSLIBF=libdk4.a
+WXDKFCSLIBS=-ldk4 $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)
+
+wxdkfcs: # Program: File checksums with GUI
+wxdkfcs$(EXEEXT): $(WXDKFCSLIBF) $(WXDKFCSOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C++) ' $@
+ $(LDCPP) $(ENTRY) -o $@ $(WXDKFCSOBJ) $(WXDKFCSLIBS)
+ chmod 755 $@
+
+
+
+WXIMGSZOBJ= DkWxImgszApp.o DkWxImgszFrame.o DkWxImgszOptionsDialog.o
+
+WXIMGSZLIBF=libdk3.a
+WXIMGSZLIBS=-ldk3 $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)
+
+wximgsz: # Program: Image scale suggestions
+wximgsz$(EXEEXT): $(WXIMGSZLIBF) $(WXIMGSZOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C++) ' $@
+ $(LDCPP) $(ENTRY) -o $@ $(WXIMGSZOBJ) $(WXIMGSZLIBS)
+ chmod 755 $@
+
+
+
+WXDKCLOCKOBJ= DkClockApp.o DkClockFrame.o DkClockOptionsDialog.o \
+ DkClockView.o DkClockData.o DkClockTaskbarIcon.o
+
+WXDKCLOCKLIBF=libdk3.a
+WXDKCLOCKLIBS=-ldk3 $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)
+
+wxdkclock: # Program: Screen clock with alert
+wxdkclock$(EXEEXT): $(WXDKCLOCKLIBF) $(WXDKCLOCKOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C++) ' $@
+ $(LDCPP) $(ENTRY) -o $@ $(WXDKCLOCKOBJ) $(WXDKCLOCKLIBS)
+ chmod 755 $@
+
+
+
+WXDKHTBOBJ= DkWxHtbApp.o DkWxHtbFrame.o
+
+WXDKHTBLIBF=libdk3.a
+WXDKHTBLIBS=-ldk3 $(WXLDFLAGS) $(GUILIB) $(CLILIB) $(BZLIB) $(ZLIB)
+
+wxdkhtb: # Program: Viewer for htb help files
+wxdkhtb$(EXEEXT): $(WXDKHTBLIBF) $(WXDKHTBOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C++) ' $@
+ $(LDCPP) $(ENTRY) -o $@ $(WXDKHTBOBJ) $(WXDKHTBLIBS)
+ chmod 755 $@
+
+
+
+ITADMINOBJ= itadmin.o itaconf.o itadata.o itamysql.o itareg.o itamem.o \
+ itacomp.o itange.o itahosts.o itaether.o itadhcp.o itanetd.o italic.o \
+ itatool.o dk3uc2l.o
+
+ITADMINLIBF=libdk3.a
+ITADMINLIBS=-ldk3 -lmysqlclient $(CLILIB) $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) $(RTLIB)
+
+itadmin: # Program: IT administration tool
+itadmin$(EXEEXT): $(ITADMINLIBF) $(ITADMINOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C++) ' $@
+ $(LDCPP) $(MYSQLLDFLAGS) -o $@ $(ITADMINOBJ) $(ITADMINLIBS)
+ chmod 755 $@
+
+
+# ##### End of dktols-3 section
+
+
+tests: testprogs
+ ./test-dk4maac < test-data/dk4maac.in > test-data/dk4maac.out
+ ./test-dk4maauc < test-data/dk4maauc.in > test-data/dk4maauc.out
+
+testprogs: $(TESTPROGS)
+ @echo 'Finished building test programs.'
+
+test-dk4maac: test-dk4maac.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L.-o $@ test-dk4maac.o -ldk4
+ chmod 755 $@
+
+test-dk4maauc: test-dk4maauc.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4maauc.o -ldk4
+ chmod 755 $@
+
+test-dk4maas: test-dk4maas.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4maas.o -ldk4
+ chmod 755 $@
+
+test-dk4maaus: test-dk4maaus.o
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4maaus.o -ldk4
+ chmod 755 $@
+
+test-dk4maai: test-dk4maai.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4maai.o -ldk4
+ chmod 755 $@
+
+test-dk4maaui: test-dk4maaui.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4maaui.o -ldk4
+ chmod 755 $@
+
+test-dk4maal: test-dk4maal.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4maal.o -ldk4
+ chmod 755 $@
+
+test-dk4maaul: test-dk4maaul.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4maaul.o -ldk4
+ chmod 755 $@
+
+test-dk4maall: test-dk4maall.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4maall.o -ldk4
+ chmod 755 $@
+
+test-dk4maaull: test-dk4maaull.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4maaull.o -ldk4
+ chmod 755 $@
+
+test-dk4maami: test-dk4maami.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4maami.o -ldk4
+ chmod 755 $@
+
+test-dk4maamu: test-dk4maamu.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4maamu.o -ldk4
+ chmod 755 $@
+
+test-dk4str8: test-dk4str8.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4str8.o -ldk4
+ chmod 755 $@
+
+test-dk4loc: test-dk4loc.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4loc.o -ldk4
+ chmod 755 $@
+
+test-dk4mai8ddu: test-dk4mai8ddu.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4mai8ddu.o -ldk4
+ chmod 755 $@
+
+test-dk4mai8ddi: test-dk4mai8ddi.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4mai8ddi.o -ldk4
+ chmod 755 $@
+
+test-dk4mai8dsz: test-dk4mai8dsz.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4mai8dsz.o -ldk4
+ chmod 755 $@
+
+test-dk4time: test-dk4time.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4time.o -ldk4
+ chmod 755 $@
+
+test-dk4exep8: test-dk4exep8.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4exep8.o -ldk4
+ chmod 755 $@
+
+test-dk4path8: test-dk4path8.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4path8.o -ldk4
+ chmod 755 $@
+
+ex-sto: ex-sto.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ ex-sto.o -ldk4
+ chmod 755 $@
+
+test-dk4strm: test-dk4strm.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4strm.o -ldk4
+ chmod 755 $@
+
+test-dk4numl: test-dk4numl.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4numl.o -ldk4
+ chmod 755 $@
+
+test-dk4tsp08: test-dk4tsp08.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4tsp08.o -ldk4
+ chmod 755 $@
+
+test-bool: test-bool.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-bool.o -ldk4
+ chmod 755 $@
+
+test-dk4enc: test-dk4enc.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4enc.o -ldk4
+ chmod 755 $@
+
+test-dk4user: test-dk4user.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4user.o -ldk4
+ chmod 755 $@
+
+test-dk4mai8dbl: test-dk4mai8dbl.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4mai8dbl.o -ldk4
+ chmod 755 $@
+
+test-fne: test-fne.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-fne.o -ldk4
+ chmod 755 $@
+
+test-mkdir: test-mkdir.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-mkdir.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-deldir: test-deldir.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-deldir.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-dk4dir08: test-dk4dir08.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4dir08.o -ldk4
+ chmod 755 $@
+
+test-dk4dir: test-dk4dir.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4dir.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-deltree: test-deltree.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-deltree.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-filei: test-filei.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-filei.o -ldk4
+ chmod 755 $@
+
+test-dk4time08: test-dk4time08.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4time08.o -ldk4
+ chmod 755 $@
+
+test-eradisk: test-eradisk.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-eradisk.o -ldk4
+ chmod 755 $@
+
+test-a85e: test-a85e.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-a85e.o -ldk4
+ chmod 755 $@
+
+test-a85d: test-a85d.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-a85d.o -ldk4
+ chmod 755 $@
+
+test-rle: test-rle.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-rle.o -ldk4
+ chmod 755 $@
+
+test-rld: test-rld.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-rld.o -ldk4
+ chmod 755 $@
+
+test-binenc: test-binenc.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-binenc.o -ldk4
+ chmod 755 $@
+
+test-sock: test-sock.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-sock.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-inet-pton: test-inet-pton.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-inet-pton.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-peer: test-peer.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-peer.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-membuf: test-membuf.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-membuf.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-dk4wxah: test-dk4wxah.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4wxah.o -ldk4 $(WXLDFLAGS) $(IMGLIBS) $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+TESTCONTAINEROBJ= test-container.o Dk4Comparable.o
+
+test-container: $(TESTCONTAINEROBJ) libdk4.a
+ $(LDCPP) -o $@ $(TESTCONTAINEROBJ) libdk4.a $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-skip: test-skip.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-skip.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-opt: test-opt.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-opt.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-udpa: test-udpa.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-udpa.o -ldk4 $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-sqdbl: test-sqdbl.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-sqdbl.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-ser: test-ser.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-ser.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-unser: test-unser.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-unser.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-strmw: test-strmw.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-strmw.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-strms: test-strms.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-strms.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-strmu: test-strmu.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-strmu.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-mbstr: test-mbstr.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-mbstr.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-dk4strmco: test-dk4strmco.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4strmco.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-paper: test-paper.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-paper.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+testlzw: testlzw.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ testlzw.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+testlzws: testlzws.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ testlzws.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-dk4c8dbl: test-dk4c8dbl.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4c8dbl.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+distclean: # Clean up (remove build and configure script results)
+distclean: clean
+ -[ ! -f confdefs.h ] || rm -fr confdefs.h
+ -[ ! -f config.h ] || rm -fr config.h
+ -[ ! -f config.log ] || rm -fr config.log
+ -[ ! -f config.status ] || rm -fr config.status
+ -[ ! -f conftest ] || rm -fr conftest
+ -[ ! -f conftest.c ] || rm -fr conftest.c
+ -[ ! -f conftest.er1 ] || rm -fr conftest.er1
+ -[ ! -f config.h ] || rm -f config.h
+ -[ ! -f scripts/wr-dk3inst.sh ] || rm -f scripts/wr-dk3inst.sh
+ -[ ! -f scripts/wr-dk4inst.sh ] || rm -f scripts/wr-dk4inst.sh
+ -[ ! -f scripts/create-desktop-files.sh ] || rm -f scripts/create-desktop-files.sh
+ -[ ! -f initd-printqd ] || rm -f initd-printqd
+ -[ ! -f dktools.pc ] || rm -f dktools.pc
+
+maketest: # Test: Check availability of make programs.
+maketest:
+ @echo OK
+
+cleanest: # NOT FOR END USER: Clean up completely
+cleanest: distclean
+ -[ ! -d autom4te.cache ] || rm -fr autom4te.cache
+ scripts/clean-resources.sh
+ find help-htb -type f -exec rm -f {} \;
+ find help-chm -type f -exec rm -f {} \;
+ find help-html -type f -exec rm -f {} \;
+ find doc/html -type f -exec rm -f {} \;
+ -[ ! -d doc/doxygen ] || find doc/doxygen -type f -exec rm -f {} \;
+ -[ ! -f dk4info1.c ] || rm -f dk4info1.c
+ -find help-src -name '*.html' -exec rm -f {} \;
+ -find help-src -name '*.hhc' -exec rm -f {} \;
+ -find help-src -name '*.hhk' -exec rm -f {} \;
+ -find help-src -name '*.hhp' -exec rm -f {} \;
+ -find help-src -name '*.aux' -exec rm -f {} \;
+ -find doc/src -name '*.html' -exec rm -f {} \;
+ -find doc/src -name '*.hhc' -exec rm -f {} \;
+ -find doc/src -name '*.hhk' -exec rm -f {} \;
+ -find doc/src -name '*.hhp' -exec rm -f {} \;
+ -find doc/src -name '*.aux' -exec rm -f {} \;
+ -find dktools -name '*.chm' -exec rm {} \;
+ -find dktools -name '*.htb' -exec rm {} \;
+ -find . -name '*.ico' -exec rm -f {} \;
+ -find . -name '*.xpm' -exec rm -f {} \;
+ -[ ! -x ./scripts/clean.sh ] || ./scripts/clean.sh
+ -[ ! -x ./scripts/clean-for-fig.sh ] || ./scripts/clean-for-fig.sh
+ -[ ! -x ./scripts/clean-for-tex.sh ] || ./scripts/clean-for-tex.sh
+ -rm -fr *.rc
+ -rm -fr *-gui.cpp
+
+
+check-cleanest: # NOT FOR END USER: Check for unlisted files
+check-cleanest: cleanest
+ perl scripts/filechk.pl
+
+
+distrenew: # NOT FOR END USER: Renew files before creating distro
+distrenew: check-cleanest
+ dkct -l
+ find . -type f -exec touch {} \;
+ sleep 2
+ find . -name '*.pdf' -exec touch {} \;
+ sleep 2
+ find . -name '*.svg' -exec touch {} \;
+ sleep 2
+ find . -name '*.png' -exec touch {} \;
+ find . -name '*.ico' -exec touch {} \;
+ find . -name '*.xpm' -exec touch {} \;
+ scripts/update-doxyfile.sh
+ doxygen
+ scripts/mkrc.pl
+ scripts/make-resources.sh
+ scripts/build-help.sh
+ scripts/doc-install.sh
+ scripts/man-install.sh
+ scripts/transform-config.pl
+ autoconf
+ scripts/create-spec-iss.sh
+ scripts/create-debian-changelog.pl > debian/changelog
+
+dist: # NOT FOR END USER: Create distro archives
+dist: distrenew
+ scripts/create-distribution.sh
+
+doxydoc: # NOT FOR END USER: Documentation created by doxygen
+ -[ ! -d doc/doxygen ] || rm -fr doc/doxygen
+ -[ ! -f doxygen.out ] || rm -fr doxygen.out
+ mkdir doc/doxygen
+ chmod 755 doc/doxygen
+ doxygen Doxyfile > doxygen.out 2>&1
+
+wprclean2: # Temporary: Base for the wprclean rewrite
+wprclean2$(EXEEXT): wprclean2.o libdk4.a
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ wprclean2.o -ldk4 $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) -lm $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
diff --git a/support/dktools/Makefile.in b/support/dktools/Makefile.in
new file mode 100644
index 0000000000..1b97dc7f82
--- /dev/null
+++ b/support/dktools/Makefile.in
@@ -0,0 +1,3008 @@
+#! /usr/bin/make -f
+# -*- makefile -*-
+
+# GETTING HELP
+# ============
+# Run
+# make help
+# to see a list of Makefile targets.
+
+# INSTALLATION
+# ============
+# The usual triple
+# ./configure
+# make
+# make install
+# should be used to install this software.
+#
+
+# PACKAGES
+# ========
+# Alternatively you can build packages.
+#
+# For RHEL6 and clones:
+# ---------------------
+# (1) As root run:
+# ./sl6-prepare.sh
+# (2) As unprivileged user run:
+# ./sl6-build-rpm.sh
+# (3) Install the RPM:
+# yum install ~/rpmbuild/RPMS/<arch>/dktools-<version>.rpm
+#
+# For Debian Jessie:
+# ------------------
+# (1) As root run
+# ./debian-jessie-prepare.sh
+# (2) As unprivileged user run
+# ./debian-jessie-build-deb.sh
+# (3) Install the *.deb package(s):
+# dpkg -i ~/.../dktools-<version>.deb
+
+
+# Package prefix, used when building packages
+# DESTDIR=
+
+# Version number, derived from version.txt contents
+VERSNO=@VERSNO@
+
+# Shared library version, first 2 positions of VERSNO
+SOVERS=@SOVERS@
+
+# Base directory for files on SourceForge
+SFBASE="http://sourceforge.net/projects/dktools/files/dktools"
+
+# Path variables set by configure script
+prefix=@prefix@
+datarootdir=@datarootdir@
+exec_prefix=@exec_prefix@
+bindir=@bindir@
+sbindir=@sbindir@
+libexecdir=@libexecdir@
+datadir=${datarootdir}
+sysconfdir=@sysconfdir@
+scd=${sysconfdir}
+libdir=@libdir@
+sharedlibdir=${libdir}/shared
+mandir=@mandir@
+includedir=@includedir@
+localstatedir=@localstatedir@
+srcdir=@srcdir@
+top_srcdir=@top_srcdir@
+VPATH=@srcdir@
+
+# Compiler commands and options set by configure script
+
+# Short OS name as returned by the 'uname -s' command
+UNAME=@UNAME@
+
+# C compiler
+CC=@CC@
+
+# C compiler preprocessor
+CPP=@CPP@
+
+# C++ compiler
+CXX=@CXX@
+
+# Linker (we use the C compiler driver here as this adds C runtime
+# libraries automaticlly)
+LD=$(CC)
+
+# Definitions for C and C++ compilers, set to -DHAVE_CONFIG_H by configure
+DEFS=@DEFS@
+
+# Options for C compiler preprocessor
+CPPFLAGS=@CPPFLAGS@ @WINUNICODE@
+
+# Options for C++ compiler
+CXXFLAGS=@CXXFLAGS@ @WINUNICODE@
+
+# Options for C compiler
+CFLAGS=@CFLAGS@ @WINUNICODE@
+
+# Options for linker
+LDFLAGS=@LDFLAGS@
+
+# Options for C/C++ compiler preprocessor when compiling modules using
+# wxWidgets
+WXCPPFLAGS=@WXCPPFLAGS@
+
+# C++ compiler options when compiling modules using wxWidgets
+WXCXXFLAGS=@WXCXXFLAGS@
+
+# C compilter options when compiling modules using wxWidgets
+WXCFLAGS=@WXCFLAGS@
+
+# Linker options when building executables using wxWidgets
+WXLDFLAGS=@WXLDFLAGS@
+
+# ?
+LIBS=@LIBS@
+
+# Relocation path -R... set when compiling using Sun Workshop and
+# LD_LIBRARY_PATH is set
+RPATH=@RPATH@
+RPATHLINK=@RPATHLINK@
+
+# Set to -Wall when all warnings are required
+CWARN=@CWARN@
+
+# Libraries and features found by configure script
+
+# Set to -D_LARGEFILE64_SOURCE=1 if there is 64-bit file support available
+# and needs to be activated explicitly
+FS64=@FS64@
+
+# Linker option to use zlib if available
+ZLIB=@ZLIB@
+
+# Linker option to use bzip2 library if available
+BZLIB=@BZLIB@
+
+# Linker option to use -lcrypto -lssl if available
+CRYPTO=@CRYPTO@
+
+# Linker option to use -lxnet, -lsocket or none for TCP/IP functionality
+SOCKLIB=@SOCKLIB@
+
+# Linker option to use -lxnet, -lnsl, -lsocket or none for name services
+NSLLIB=@NSLLIB@
+
+# Linker options to use tiff, jpeg and png libraries if available
+IMGLIBS=@LIBTIFF@ @LIBJPEG@ @LIBPNG@
+
+# Linker options to use Berkeley DB library
+DBLIB=@DBLIB@
+
+# Linker options to use socket library required by DBLIB
+DBLIBSOCK=@DBLIBSOCK@
+
+# Linker options to use NetSNMP libraries and required libraries if available
+NETSNMP_LIBS=@NETSNMP_LIBS@
+
+# Linker option to use pthread library if available
+PTHREADLIB=@PTHREADLIB@
+
+# Linker option to set path for MySQL library
+MYSQLLDFLAGS=@MYSQLLDFLAGS@
+
+# Linker option for realtime clock library
+RTLIB=@RTLIB@
+
+# AR program to build an archive (a library)
+AR=@AR@
+
+# NM program to list symbols from a library
+NM=@NM@
+
+# RANLIB program to create archive (library) index, only required on
+# some platforms
+RANLIB=@RANLIB@
+
+# Command to create soft links
+LN_S=@LN_S@
+
+# The make program to build projects
+MAKE=@MAKE@
+
+# File name extension for executable files
+EXEEXT=@EXEEXT@
+
+# File name extension for object files
+OBJEXT=@OBJEXT@
+
+# List of CLI programs using the NetSNMP libraries
+CLI_SNMPPROG=@CLI_SNMPPROG@
+
+# List of CLI programs using the MySQL library
+CLI_MYSQLPROG=@CLI_MYSQLPROG@
+
+# C/C++ compiler flags to build modules for shared libraries
+CFPIC=@CFPIC@
+
+# Script to install shared libraries
+INSTALL_LIBS_SHARED=./scripts/install-libs-shared.sh
+
+# A BSD compatible install program
+INSTALL=@INSTALL@
+
+# Program or script to install executable programs
+INSTALL_PROGRAM=@INSTALL_PROGRAM@
+
+# Program or script to install script files
+INSTALL_SCRIPT=@INSTALL_SCRIPT@
+
+# Program or script to install data files
+INSTALL_DATA=@INSTALL_DATA@
+
+# Base libraries to build the CLI programs on Windows systems
+WINCLILIB=-lkernel32 -lgdi32 -ladvapi32 -luser32 -lnetapi32
+
+# Additional libraries to build the GUI programs on Windows systems
+WINGUILIB=-lole32 -loleaut32 -lshell32 -lcomctl32 -lcomdlg32 -lwinspool
+
+# Type of entry point on Windows
+WINENTRY=-municode
+
+# List of additional libraries to include when building CLI programs
+# $(WINCLILIB) on Windows, empty on other systems
+CLILIB=@CLILIB@
+
+# List of additional libraries to include when building GUI programs
+# $(WINGUILIB) on Windows, empty on other systems
+GUILIB=@GUILIB@
+
+# Entry point options, $(WINENTRY) on Windows, empty on other systems
+ENTRY=@ENTRY@
+
+# Include path for C/C++ compiler
+INCLUDES= \
+ -I. \
+ -I$(srcdir) \
+ -I$(top_srcdir) \
+ -I$(includedir)
+
+# Options used when compiling *.c modules to *.o
+COPTS= \
+ $(DEFS) \
+ $(INCLUDES) \
+ $(CFPIC) \
+ $(CPPFLAGS) \
+ $(CFLAGS) \
+ $(FS64) \
+ $(CWARN)
+
+# Options used when compiling *.cpp or *.cxx modules to *.o
+CCOPTS= \
+ $(DEFS) \
+ $(INCLUDES) \
+ $(CFPIC) \
+ $(CPPFLAGS) \
+ $(CFLAGS) \
+ $(CXXFLAGS) \
+ $(WXCPPFLAGS) \
+ $(WXCXXFLAGS) \
+ $(FS64) \
+ $(CWARN)
+
+# C compiler command including options
+COMPILEC= $(CC) $(COPTS)
+
+# C++ compiler command including options
+COMPILECPP= $(CXX) $(CCOPTS) $(WXCXXFLAGS)
+
+# Linker command
+LD=$(CC)
+
+# Linker command including options
+LINK=$(CC) $(CFLAGS) -L. $(LDFLAGS) $(RPATH) $(RPATHLINK) $(ENTRY)
+
+# Linker command for applications using C++ modules (i.e. wxWidgets libraries)
+LDCPP=$(CXX) $(CFLAGS) $(CXXFLAGS) -L. $(LDFLAGS) $(RPATH) $(RPATHLINK) $(ENTRY)
+
+# Command to build a shared library
+MKSOLIB=@MKSOLIB@
+
+# Shared libraries needed for linking when building other shared libraries
+
+SOLIBZ=@SOLIBZ@
+SOLIBBZ=@SOLIBBZ@
+SOLIBMATH=@SOLIBMATH@
+SOLIBCRYPTO=@SOLIBCRYPTO@
+SOLIBNET=@SOLIBNET@
+SOLIBIMG=@SOLIBIMG@
+SOLIBSDBI=@SOLIBSDBI@
+SOLIBWX=@SOLIBWX@
+SOLIBDK3PORT=@SOLIBDK3PORT@
+SOLIBDK3C=@SOLIBDK3C@ $(SOLIBBZ) $(SOLIBZ) $(SOLIBMATH)
+SOLIBDK3OF=@SOLIBDK3OF@
+SOLIBDK3CSRND=@SOLIBDK3CSRND@
+SOLIBDK3BIF=@SOLIBDK3BIF@
+SOLIBDK3DBI=@SOLIBDK3DBI@
+SOLIBDK3FIG=@SOLIBDK3FIG@
+SOLIBDK3BMEPS=@SOLIBDK3BMEPS@
+SOLIBDK3NET=@SOLIBDK3NET@
+SOLIBDK4BASE=@SOLIBDK4BASE@
+SOLIBDK4MA=@SOLIBDK4MA@
+SOLIBDK4MAIO8H=@SOLIBDK4MAIO8H@
+SOLIBDK4MAIOWH=@SOLIBDK4MAIOWH@
+SOLIBDK4MAIODH=@SOLIBDK4MAIODH@
+SOLIBDK4MAIO8D=@SOLIBDK4MAIO8D@
+SOLIBDK4MAIOWD=@SOLIBDK4MAIOWD@
+SOLIBDK4MAIODD=@SOLIBDK4MAIODD@
+SOLIBDK4C=@SOLIBDK4C@ $(SOLIBDK4MAIODD) $(SOLIBDK4MAIO8D) $(SOLIBDK4MA) \
+ $(SOLIBDK4BASE) $(SOLIBBZ) $(SOLIBZ) $(SOLIBMATH)
+SOLIBDK4MDRND=@SOLIBDK4MDRND@
+SOLIBDK4PPPT=@SOLIBDK4PPPT@
+SOLIBDK4APP=@SOLIBDK4APP@ $(SOLIBDK4C)
+SOLIBDK4LAT=@SOLIBDK4LAT@
+SOLIBDK4SOCK=@SOLIBDK4SOCK@
+SOLIBDK4SOCKA=@SOLIBDK4SOCKA@
+SOLIBDK4DBI=@SOLIBDK4DBI@
+SOLIBDK4DBIA=@SOLIBDK4DBIA@
+
+
+
+
+# Clean suffixes list
+.SUFFIXES:
+
+# Rebuild new suffixes list
+.SUFFIXES: .o .cpp .c
+
+.c.o:
+ @echo '### Compile C ### ' $<
+ $(COMPILEC) -o $@ -c $<
+
+.cpp.o:
+ @echo '### Compile C++ ### ' $<
+ $(COMPILECPP) -o $@ -c $<
+
+.c:
+ @echo '### Link C ### ' $*
+ $(COMPILEC) $(LDFLAGS) -o $* $*.c $(LIBS)
+ chmod 755 $*
+
+.cpp:
+ @echo '### Link C++ ### ' $*
+ $(COMPILECPP) $(LDFLAGS) -o $* $*.cpp $(LIBS)
+ chmod 755 $*
+
+# Programs to build for rescue system when sockets available
+NET_PROG_RES= \
+ dk-recv$(EXEEXT) \
+ dk-send$(EXEEXT)
+
+# Programs to build for rescue system
+PROG_RES= @NET_PROG_RES@ \
+ dk-cat$(EXEEXT) \
+ dk-blks$(EXEEXT) \
+ dk-eradisk$(EXEEXT) \
+ dk-ls$(EXEEXT)
+
+# Man pages to install on rescue systems
+MAN_RES= \
+ man/man1/dk-blks.1 \
+ man/man1/dk-cat.1 \
+ man/man1/dk-eradisk.1 \
+ man/man1/dk-ls.1 \
+ man/man1/dk-recv.1 \
+ man/man1/dk-send.1
+
+# Resource files to install on rescue systems
+RES_RES_EN= \
+ dktools/en/dk-blks.txt \
+ dktools/en/dk-cat.txt \
+ dktools/en/dk-ls.txt \
+ dktools/en/dk-recv.txt \
+ dktools/en/dk-send.txt
+
+RES_RES_DE= \
+ dktools/de/dk-blks.txt \
+ dktools/de/dk-cat.txt \
+ dktools/de/dk-ls.txt \
+ dktools/de/dk-recv.txt \
+ dktools/de/dk-send.txt
+
+
+# Command line programs to build when sockets available
+NET_PROG_CLI= \
+ printqd$(EXEEXT) \
+ printqdc$(EXEEXT) \
+ lprngcl$(EXEEXT) \
+ rshdown$(EXEEXT)
+
+# Command line programs to build when NetSNMP available
+SNMP_PROG_CLI= \
+ pjsnmp$(EXEEXT) prmonsnmp$(EXEEXT)
+
+# Command line programs to build when MySQL available
+MYSQL_PROG_CLI= \
+ itadmin$(EXEEXT)
+
+# Programs to build for CLI suite
+PROG_CLI= $(PROG_RES) \
+ dk-sqlsplit$(EXEEXT) @SNMP_PROG_CLI@ \
+ dk-sort$(EXEEXT) @PROGSOPENSSL@ \
+ dk-uid$(EXEEXT) @NET_PROG_CLI@ \
+ dk-t2h$(EXEEXT) @MYSQL_PROG_CLI@ \
+ dk-t2l$(EXEEXT) \
+ dk-hex$(EXEEXT) \
+ dk-bmm$(EXEEXT) \
+ dk-pwd$(EXEEXT) \
+ dkct$(EXEEXT) \
+ addctrld$(EXEEXT) \
+ dk-t2db$(EXEEXT) \
+ dk-db2t$(EXEEXT) \
+ dk-dbco$(EXEEXT) \
+ bmpp$(EXEEXT) \
+ fig2lat$(EXEEXT) \
+ htmlbook$(EXEEXT) \
+ dk3info$(EXEEXT) \
+ dk4info$(EXEEXT) \
+ plpdftex$(EXEEXT) \
+ dkwxwiz$(EXEEXT)
+
+# Programs to build when cross-compiling on Linux for Windows
+PROG_CROSS= $(PROG_RES) \
+ dk-sqlsplit$(EXEEXT) @SNMP_PROG_CLI@ \
+ dk-sort$(EXEEXT) @PROGSOPENSSL@ \
+ dk-fic$(EXEEXT) @NET_PROG_CLI@ \
+ dk-t2h$(EXEEXT) @MYSQL_PROG_CLI@ \
+ dk-t2l$(EXEEXT) \
+ dk-hex$(EXEEXT) \
+ dk-bmm$(EXEEXT) \
+ dk-pwd$(EXEEXT) \
+ dkct$(EXEEXT) \
+ addctrld$(EXEEXT) \
+ dk-t2db$(EXEEXT) \
+ dk-db2t$(EXEEXT) \
+ dk-dbco$(EXEEXT) \
+ bmpp$(EXEEXT) \
+ fig2lat$(EXEEXT) \
+ htmlbook$(EXEEXT) \
+ dk3info$(EXEEXT) \
+ dk4info$(EXEEXT) \
+ plpdftex$(EXEEXT) \
+ dkwxwiz$(EXEEXT)
+
+# Programs to build for GUI suite
+PROG_GUI= $(PROG_CLI) \
+ wxdkfcs$(EXEEXT) \
+ wxdkct$(EXEEXT) \
+ wxbmpp$(EXEEXT) \
+ wxpqdic$(EXEEXT) \
+ wximgsz$(EXEEXT) \
+ wxdkclock$(EXEEXT) \
+ wxdkhtb$(EXEEXT)
+
+# Static libraries to build for rescue system
+LIB_ST_RES=
+
+# Static libraries to build for CLI suite
+LIB_ST_CLI= $(LIB_ST_RES) \
+ libdk4base.a \
+ libdk4ma.a \
+ libdk4maio8h.a \
+ libdk4maiowh.a \
+ libdk4maiodh.a \
+ libdk4maio8d.a \
+ libdk4maiowd.a \
+ libdk4maiodd.a \
+ libdk4c.a \
+ libdk4pppt.a \
+ libdk4socka.a \
+ libdk4sock.a \
+ libdk4dbia.a \
+ libdk4dbi.a \
+ libdk4app.a \
+ libdk4pppta.a \
+ libdk4lat.a \
+ libdk4mdrnd.a \
+ libdk3c.a \
+ libdk3of.a \
+ libdk3csrnd.a \
+ libdk3bif.a \
+ libdk3dbi.a \
+ libdk3bmeps.a \
+ libdk3fig.a \
+ libdk3trace.a
+
+# Static libraries to build for GUI suite
+LIB_ST_GUI= $(LIB_ST_CLI) \
+ libdk4wx.a \
+ libdk4maioxd.a
+
+# Shared libraries to build for rescue system when no packaging used
+LIB_SH_RES_NO_PACKAGING=
+
+# Shared libraries to build for CLI suite when no packaging used
+LIB_SH_CLI_NO_PACKAGING= $(LIB_SH_RES_NO_PACKAGING) \
+ libdk4base.so \
+ libdk4ma.so \
+ libdk4maio8h.so \
+ libdk4maiowh.so \
+ libdk4maiodh.so \
+ libdk4maio8d.so \
+ libdk4maiowd.so \
+ libdk4maiodd.so \
+ libdk4c.so \
+ libdk4pppt.so \
+ libdk4socka.so \
+ libdk4sock.so \
+ libdk4dbia.so \
+ libdk4dbi.so \
+ libdk4app.so \
+ libdk4pppta.so \
+ libdk4lat.so \
+ libdk4mdrnd.so \
+ libdk3c.so \
+ libdk3of.so \
+ libdk3csrnd.so \
+ libdk3bif.so \
+ libdk3dbi.so \
+ libdk3bmeps.so \
+ libdk3fig.so \
+ libdk3trace.so
+
+# Shared libraries to build for GUI suite when no packaging used
+LIB_SH_GUI_NO_PACKAGING= $(LIB_SH_CLI_NO_PACKAGING) \
+ libdk4wx.so \
+ libdk4maioxd.so \
+ libdk3wx.so
+
+# Shared libraries to build for rescue system when packaging used
+LIB_SH_RES_PACKAGING= \
+ libdk4base.so \
+ libdk4maio8d.so \
+ libdk4maiowd.so \
+ libdk4maiodd.so \
+ libdk4maio8h.so \
+ libdk4maiowh.so \
+ libdk4maiodh.so \
+ libdk4ma.so \
+ libdk4c.so \
+ libdk4socka.so \
+ libdk4sock.so \
+ libdk4app.so \
+ libdk4mdrnd.so
+
+# Shared libraries to build for CLI suite when packaging used
+LIB_SH_CLI_PACKAGING= $(LIB_SH_RES_PACKAGING) \
+ libdk4lat.so \
+ libdk4dbi.so \
+ libdk4dbia.so \
+ libdk4pppt.so \
+ libdk4pppta.so \
+ libdk3c.so \
+ libdk3of.so \
+ libdk3csrnd.so \
+ libdk3bif.so \
+ libdk3dbi.so \
+ libdk3bmeps.so \
+ libdk3fig.so \
+ libdk3trace.so
+
+# Shared libraries to build for GUI suite when packaging used
+LIB_SH_GUI_PACKAGING= $(LIB_SH_CLI_PACKAGING) \
+ libdk4wx.so \
+ libdk4maioxd.so \
+ libdk3wx.so
+
+# Shared libraries to build for rescue system when packaging used
+LIB_SH_RES=@LIB_SH_RES@
+
+# Shared libraries to build for CLI suite
+LIB_SH_CLI=@LIB_SH_CLI@
+
+# Shared libraries to build for GUI suite
+LIB_SH_GUI=@LIB_SH_GUI@
+
+all: # Synonym for build
+all: build
+
+help: # Show targets in Makefile
+ @echo 'Some systems (i.e. Windows) append a special filename extension'
+ @echo '(i.e. .exe) to program file names.'
+ @echo 'On such systems use "make dk-ls.exe" instead of "make dk-ls"'
+ @echo 'to build a program.'
+ @echo 'Here is a list of the targets in this Makefile:'
+ -@egrep '^[^:;=. ]*::?[ ]*' Makefile|grep '#'|grep -v '^#'
+
+build: # Build the software
+build: build-arch build-indep
+
+build-arch: # Build architecture specific files
+build-arch: @PROGRAMS@ @LIBRARIES@
+
+build-indep: # Build architecture independent files
+ find man -type d -exec chmod 755 {} \;
+ find man -type f -exec chmod 644 {} \;
+
+install: # Install the software
+install: install-arch install-indep
+ [ "X$(DESTDIR)" = "X" -o "X$(UNAME)" != "XSunOS" ] || cp pkginfo $(DESTDIR)/pkginfo
+ [ "X$(DESTDIR)" = "X" -o "X$(UNAME)" != "XSunOS" ] || chmod 644 $(DESTDIR)/pkginfo
+ @echo Finished installation
+ @echo Some directories used by the printqd daemon may need
+ @echo ownership and permission corrections. See 'printqd(1)'.
+
+install-arch: # Install architecture specific files
+install-arch: install-programs @LIBS_INSTALL@ @RES_INSTALL@
+ @echo Finished installation of architecture specific files.
+
+# Shared libraries to build and install
+LIBS_SHARED=@LIBS_SHARED@
+
+i-l-sh: # Install shared libraries
+i-l-sh: build-arch install-directories
+ $(INSTALL) -c -d "$(DESTDIR)$(libdir)"
+ for i in $(LIBS_SHARED) ; do $(INSTALL) -c -m 644 $$i.$(SOVERS) "$(DESTDIR)$(libdir)" ; done
+ for i in $(LIBS_SHARED) ; do $(LN_S) $$i.$(SOVERS) "$(DESTDIR)$(libdir)/$$i"; done
+ @echo Finished installation of shared libraries.
+
+# Static libraries to build and install
+LIBS_STATIC=@LIBS_STATIC@
+
+i-l-st: # Install static libraries
+i-l-st: build-arch install-directories
+ $(INSTALL_DATA) $(LIBS_STATIC) "$(DESTDIR)$(libdir)"
+ @echo Finished installation of static libraries.
+
+i-incl: # Install include files for libraries
+ $(INSTALL_DATA) dk4*.h Dk4*.h dk3trace.h "$(DESTDIR)$(includedir)"
+ @echo Finished installation of include files.
+
+i-r-res: # Install resources for rescue programs
+i-r-res:
+ $(INSTALL) -d "$(DESTDIR)$(datarootdir)/dktools"
+ $(INSTALL) -d "$(DESTDIR)$(datarootdir)/dktools/en"
+ $(INSTALL) -d "$(DESTDIR)$(datarootdir)/dktools/de"
+ $(INSTALL_DATA) $(RES_RES_EN) "$(DESTDIR)$(datarootdir)/dktools/en"
+ $(INSTALL_DATA) $(RES_RES_DE) "$(DESTDIR)$(datarootdir)/dktools/de"
+ @echo Finished resources installation for rescue programs.
+
+i-r-cli: # Install resources for CLI programs
+i-r-cli: install-directories i-r-res
+ find ./dktools -type d -exec chmod 755 {} \;
+ find ./dktools -type f -exec chmod ugo+r,go-w {} \;
+ find ./dk4app -type d -exec chmod 755 {} \;
+ find ./dk4app -type f -exec chmod ugo+r,go-w {} \;
+ (cd ./dktools ; tar cf - .) | (cd "$(DESTDIR)$(datarootdir)/dktools" ; tar xf -)
+ (cd ./dk4app ; tar cf - .) | (cd "$(DESTDIR)$(datarootdir)/dk4app" ; tar xf -)
+ find ./help-chm -type d -exec chmod 755 {} \;
+ find ./help-chm -type f -exec chmod 644 {} \;
+ find ./help-htb -type d -exec chmod 755 {} \;
+ find ./help-htb -type f -exec chmod 644 {} \;
+ (cd ./help-htb ; tar cf - .) | (cd "$(DESTDIR)$(datarootdir)/dktools" ; tar xf -)
+ $(INSTALL_DATA) dktools.pc "$(DESTDIR)$(libdir)/pkgconfig/dktools.pc"
+ $(INSTALL_DATA) etc-dk3app/dk3paper.conf "$(DESTDIR)$(sysconfdir)/dk3app"
+ $(INSTALL_SCRIPT) itaclean.sh "$(DESTDIR)$(bindir)/itaclean"
+ $(INSTALL_DATA) rshdown.conf.sample "$(DESTDIR)$(sysconfdir)/rshdown"
+ $(INSTALL_DATA) printqd.conf.sample "$(DESTDIR)$(sysconfdir)/printqd"
+ @echo Finished resources installation for CLI programs.
+
+i-r-gui: # Install resources for GUI programs
+i-r-gui: install-directories i-r-cli
+ $(INSTALL_DATA) dkicon.ico "$(DESTDIR)$(datarootdir)/dktools"
+ $(INSTALL_DATA) dkclock.ico "$(DESTDIR)$(datarootdir)/dktools"
+ $(INSTALL_DATA) wxbmpp.desktop "$(DESTDIR)$(datarootdir)/applications"
+ $(INSTALL_DATA) wxdkclock.desktop "$(DESTDIR)$(datarootdir)/applications"
+ $(INSTALL_DATA) wxdkct.desktop "$(DESTDIR)$(datarootdir)/applications"
+ $(INSTALL_DATA) wximgsz.desktop "$(DESTDIR)$(datarootdir)/applications"
+ $(INSTALL_DATA) wxdkfcs.desktop "$(DESTDIR)$(datarootdir)/applications"
+ @echo Finished resources installation for GUI programs.
+
+
+install-programs: # Install the executable programs
+install-programs: build-arch install-directories
+ $(INSTALL) @PROGRAMS@ "$(DESTDIR)$(bindir)"
+ @echo Finished installation of executable files.
+
+install-indep: # Install architecture independent files
+install-indep: build-indep install-directories @INSTALLMANPAGES@
+ @echo Finished installation of architecture independent files.
+
+install-rescue-man: # Install man pages for rescue systems
+install-rescue-man: build-indep
+ $(INSTALL) -d "$(DESTDIR)$(mandir)/man1"
+ $(INSTALL_DATA) $(MAN_RES) "$(DESTDIR)$(mandir)/man1"
+
+install-manpages: # Install man pages
+install-manpages: build-indep install-directories
+ $(INSTALL_DATA) man/man1/* "$(DESTDIR)$(mandir)/man1"
+ $(INSTALL_DATA) man/man5/* "$(DESTDIR)$(mandir)/man5"
+ @echo Finished installation of manpages.
+
+install-directories: # Create installation directories
+ $(INSTALL) -d "$(DESTDIR)$(libdir)"
+ $(INSTALL) -d "$(DESTDIR)$(libdir)/pkgconfig"
+ $(INSTALL) -d "$(DESTDIR)$(includedir)"
+ $(INSTALL) -d "$(DESTDIR)$(bindir)"
+ $(INSTALL) -d "$(DESTDIR)$(mandir)"
+ $(INSTALL) -d "$(DESTDIR)$(mandir)/man1"
+ $(INSTALL) -d "$(DESTDIR)$(mandir)/man5"
+ $(INSTALL) -d "$(DESTDIR)$(datarootdir)/dktools"
+ $(INSTALL) -d "$(DESTDIR)$(datarootdir)/dk4app"
+ $(INSTALL) -d "$(DESTDIR)$(datarootdir)/applications"
+ $(INSTALL) -d "$(DESTDIR)$(sysconfdir)/dk3app"
+ $(INSTALL) -d "$(DESTDIR)$(sysconfdir)/rshdown"
+ $(INSTALL) -d "$(DESTDIR)$(sysconfdir)/printqd"
+ $(INSTALL) -d "$(DESTDIR)$(localstatedir)/log"
+ $(INSTALL) -d -m 775 "$(DESTDIR)$(localstatedir)/log/printqd"
+ $(INSTALL) -d "$(DESTDIR)$(localstatedir)/run"
+ $(INSTALL) -d -m 775 "$(DESTDIR)$(localstatedir)/lib/printqd"
+ @echo Finished directory creation for installation.
+
+# Test programs for the modules.
+TESTPROGS= \
+ test-dk4maac \
+ test-dk4maauc \
+ test-dk4maas \
+ test-dk4maaus \
+ test-dk4maai \
+ test-dk4maaui \
+ test-dk4maal \
+ test-dk4maaul \
+ test-dk4maall \
+ test-dk4maaull \
+ test-dk4maami \
+ test-dk4maamu \
+ test-dk4mai8ddu \
+ test-dk4mai8ddi \
+ test-dk4mai8dsz \
+ test-dk4str8 \
+ test-dk4loc \
+ test-dk4time \
+ test-dk4exep8 \
+ test-dk4path8 \
+ ex-sto \
+ test-dk4strm \
+ test-dk4numl \
+ test-dk4tsp08 \
+ test-bool \
+ test-dk4enc \
+ test-dk4user \
+ test-container \
+ test-skip
+
+# All test programs found by the configure script
+TESTPROGRAMS= @TESTPROGRAMS@
+
+clean: # Clean up (remove build results)
+ -rm -f errors
+ -rm -f *.deb
+ -rm -f *.o *.obj *.exe
+ -rm -f $(TESTPROGRAMS) $(TESTPROGS) @PROGRAMS@
+ -rm -f *.a
+ -rm -f *.so.$(SOVERS) *.so
+ -rm -f doxygen.out
+ -rm -f dk4config
+ -rm -f dk3config
+ -rm -f wxcs
+ -rm -f doc/src/*.aux doc/src/*.log doc/src/math-img.pdf
+ -rm -f doc/src/index.pdf doc/src/index.svg
+ -rm -f doc/src/next.pdf doc/src/next.svg
+ -rm -f doc/src/prev.pdf doc/src/prev.svg
+ -rm -f doc/src/toc.pdf doc/src/toc.svg
+ @echo 'Finished cleanup.'
+
+get-orig-source: # Retrieve original source archive
+ @GETSOURCE@
+
+# Complete list of all libraries to build
+# Probably not all of them are installed
+LIBRARIESTOBUILD= @LIBDK4WXTOBUILD@ \
+ libdk4.a \
+ libdk4maio8d.$(LIBEXT) \
+ libdk4maiowd.$(LIBEXT) \
+ libdk4maiodd.$(LIBEXT) \
+ libdk4maio8h.$(LIBEXT) \
+ libdk4maiowh.$(LIBEXT) \
+ libdk4maiodh.$(LIBEXT) \
+ libdk4ma.$(LIBEXT) \
+ libdk4base.$(LIBEXT) \
+ libdk4c.$(LIBEXT) \
+ libdk4pppt.$(LIBEXT) \
+ libdk4app.$(LIBEXT) \
+ libdk4pppta.$(LIBEXT) \
+ libdk4lat.$(LIBEXT) \
+ libdk4sock.$(LIBEXT) \
+ libdk4socka.$(LIBEXT) \
+ libdk4dbi.$(LIBEXT) \
+ libdk4dbia.$(LIBEXT)
+
+binary: # Build all binaries
+binary: binary-arch binary-indep
+
+binary-arch: # Build architecture-specific binaries
+binary-arch: build-arch $(LIBRARIESTOBUILD) @PROGRAMS@
+ @echo 'Finished creating the architecture-specific binaries.'
+
+binary-indep: # Build architecture-independent binaries
+binary-indep: build-indep
+ @echo 'There are no architecture-independent binaries in this project.'
+
+# Objects for libdk4wx.so or libdk4wx.a library
+LIBDK4WXOBJ= \
+ Dk4WxControl.o \
+ Dk4WxProgressDialog.o \
+ Dk4WxFrame.o \
+ Dk4WxHelpController.o \
+ Dk4WxAutostartController.o \
+ Dk4WxApplicationHelper.o \
+ dk4wxpref.o \
+ dk4wxstt.o \
+ dk4recwx.o \
+ dk4tspwx.o \
+ dk4strx.o
+
+# Objects for libdk4socka.so or libdk4socka.a library
+LIBDK4SOCKAOBJ= \
+ dk4socka09.o \
+ dk4socka08.o \
+ dk4socka07.o \
+ dk4socka06.o \
+ dk4socka05.o \
+ dk4socka04.o \
+ dk4socka03.o \
+ dk4socka02.o \
+ dk4socka01.o
+
+# Objects for libdk4sock.so or libdk4sock.a library
+LIBDK4SOCKOBJ= \
+ dk4sock37.o \
+ dk4sock36.o \
+ dk4sock35.o \
+ dk4sock34.o \
+ dk4sock33.o \
+ dk4sock32.o \
+ dk4sock31.o \
+ dk4sock30.o \
+ dk4sock29.o \
+ dk4sock28.o \
+ dk4sock27.o \
+ dk4sock26.o \
+ dk4sock25.o \
+ dk4sock24.o \
+ dk4sock23.o \
+ dk4sock22.o \
+ dk4sock21.o \
+ dk4sock20.o \
+ dk4sock19.o \
+ dk4sock18.o \
+ dk4sock17.o \
+ dk4sock16.o \
+ dk4sock15.o \
+ dk4sock14.o \
+ dk4sock13.o \
+ dk4sock12.o \
+ dk4sock11.o \
+ dk4sock10.o \
+ dk4sock09.o \
+ dk4sock08.o \
+ dk4sock07.o \
+ dk4sock06.o \
+ dk4sock05.o \
+ dk4sock04.o \
+ dk4sock03.o \
+ dk4sock02.o \
+ dk4sock01.o
+
+# Objects for libdk4lat.so or libdk4lat.a library
+LIBDK4LATOBJ= \
+ dk4uc2l.o
+
+# Objects for libdk4app.so or libdk4app.a library
+LIBDK4APPOBJ= \
+ dk4fdrda.o \
+ dk4fdrde.o \
+ dk4fdwre.o \
+ dk4mema.o \
+ dk4svbufa.o \
+ dk4fopda.o \
+ dk4appargs.o \
+ dk4appop.o \
+ dk4appmkdh.o \
+ dk4appstt.o \
+ dk4appenc.o \
+ dk4aopt01.o \
+ dk4aopt02.o \
+ dk4aopt03.o \
+ dk4aopt04.o \
+ dk4aopt05.o \
+ dk4aopt06.o \
+ dk4aopt07.o \
+ dk4aopt08.o \
+ dk4aopt09.o \
+ dk4aopt10.o \
+ dk4aopt11.o \
+ dk4aopt12.o \
+ dk4aopt13.o \
+ dk4aopt14.o \
+ dk4aopt15.o \
+ dk4aopt16.o \
+ dk4appfs03.o \
+ dk4appfs04.o \
+ dk4appfs01.o \
+ dk4appfs02.o \
+ dk4appfne.o \
+ dk4dira.o \
+ dk4fileia.o \
+ dk4appdeltree.o \
+ dk4appdeldir.o \
+ dk4appdelfile.o \
+ dk4applog.o \
+ dk4apref.o \
+ dk4aprgs.o \
+ dk4apphlv.o \
+ dk4strda.o
+
+# Objects for libdk4mdrnd.so or libdk4mdrnd.a library
+LIBDK4MDRNDOBJ= \
+ dk4md.o
+
+# Objects for libdk4pppta.so or libdk4pppta.a library
+LIBDK4PPPTAOBJ= \
+ dk4papea.o
+
+# Objects for libdk4pppt.so or libdk4pppt.a library
+LIBDK4PPPTOBJ= \
+ dk4font.o \
+ dk4paper.o
+
+# Object for libdk4c.so or libdk4c.a library
+LIBDK4COBJ= \
+ dk4dmt.o \
+ dk4mdch.o \
+ dk4binenc.o \
+ dk4stt.o \
+ dk4opt.o \
+ dk4opt01.o \
+ dk4opt02.o \
+ dk4opt03.o \
+ dk4opt04.o \
+ dk4opt05.o \
+ dk4opt06.o \
+ dk4opt07.o \
+ dk4pref.o \
+ dk4tspdk.o \
+ dk4tsp32.o \
+ dk4tsp16.o \
+ dk4tsp08.o \
+ dk4strmco.o \
+ dk4lzwe.o \
+ dk4mbstrm.o \
+ dk4membs.o \
+ dk4membf.o \
+ dk4membuf.o \
+ dk4strmu.o \
+ dk4strms.o \
+ dk4strmw.o \
+ dk4strmr.o \
+ dk4strmf.o \
+ dk4strmg.o \
+ dk4strmb.o \
+ dk4strmodk.o \
+ dk4strmo08.o \
+ dk4strmo16.o \
+ dk4strmo32.o \
+ dk4c8dbl.o \
+ dk4strm.o \
+ dk4fput.o \
+ dk4svbuf.o \
+ dk4fopd.o \
+ dk4fopwc.o \
+ dk4fopc8.o \
+ dk4exepd.o \
+ dk4exepw.o \
+ dk4exep8.o \
+ dk4mkdh.o \
+ dk4mkdh8.o \
+ dk4mkdhw.o \
+ dk4symlink.o \
+ dk4fileiu.o \
+ dk4fileigd.o \
+ dk4fileigw.o \
+ dk4fileig8.o \
+ dk4filei.o \
+ dk4fileid.o \
+ dk4fileiw.o \
+ dk4filei8.o \
+ dk4filed.o \
+ dk4filew.o \
+ dk4file8.o \
+ dk4fs.o \
+ dk4mm.o \
+ dk4stat.o \
+ dk4statd.o \
+ dk4statw.o \
+ dk4stat8.o \
+ dk4pathd.o \
+ dk4pathw.o \
+ dk4path8.o \
+ dk4userf.o \
+ dk4enc.o \
+ dk4bom.o \
+ dk4rec25.o \
+ dk4rec24.o \
+ dk4rec23.o \
+ dk4rec22.o \
+ dk4rec21.o \
+ dk4rec20.o \
+ dk4rec19.o \
+ dk4rec18.o \
+ dk4rec17.o \
+ dk4rec16.o \
+ dk4rec15.o \
+ dk4rec14.o \
+ dk4rec13.o \
+ dk4rec12.o \
+ dk4rec11.o \
+ dk4rec10.o \
+ dk4rec09.o \
+ dk4rec08.o \
+ dk4rec07.o \
+ dk4rec06.o \
+ dk4rec05.o \
+ dk4rec04.o \
+ dk4rec03.o \
+ dk4rec02.o \
+ dk4rec01.o \
+ dk4ansi.o \
+ dk4utf8.o \
+ dk4utf16.o \
+ dk4c32.o \
+ dk4loc.o \
+ dk4wregd.o \
+ dk4wregw.o \
+ dk4wreg8.o \
+ dk4wregc.o \
+ dk4fd.o \
+ dk4hnamed.o \
+ dk4hnamew.o \
+ dk4hname8.o \
+ dk4user.o \
+ dk4ufi.o \
+ dk4ufiwc.o \
+ dk4ufi08.o \
+ dk4fne.o \
+ dk4fnewc.o \
+ dk4fne08.o \
+ dk4getcwdd.o \
+ dk4getcwdw.o \
+ dk4getcwd8.o \
+ dk4dir.o \
+ dk4dirwc.o \
+ dk4dir08.o \
+ dk4deldir.o \
+ dk4deldirwc.o \
+ dk4deldir08.o \
+ dk4delfile.o \
+ dk4delfilewc.o \
+ dk4delfile08.o \
+ dk4istty.o \
+ dk4ftimedk.o \
+ dk4ftimewc.o \
+ dk4ftime08.o \
+ dk4ftime.o \
+ dk4ctime.o \
+ dk4time.o \
+ dk4timedk.o \
+ dk4timewc.o \
+ dk4time08.o \
+ dk4inst.o \
+ dk4getpid.o \
+ dk4sto.o \
+ dk4a85e.o \
+ dk4a85d.o \
+ dk4ahd.o \
+ dk4rle.o \
+ dk4rld.o \
+ dk4bf.o \
+ dk4bitsh.o \
+ dk4isadm.o \
+ dk4fpe.o \
+ dk3trace.o
+
+# Objects for libdk4maiodd.so or libdk4maiodd.a library
+LIBDK4MAIODDOBJ= \
+ dk4maoddbl.o \
+ dk4maiddbl.o \
+ dk4maiddic.o \
+ dk4maiddis.o \
+ dk4maiddii.o \
+ dk4maiddmi.o \
+ dk4maiddli.o \
+ dk4maiddil.o \
+ dk4maidddi.o \
+ dk4maidduc.o \
+ dk4maiddus.o \
+ dk4maiddui.o \
+ dk4maiddmu.o \
+ dk4maiddlu.o \
+ dk4maiddul.o \
+ dk4maiddsz.o \
+ dk4maidddu.o \
+ dk4maodd.o
+
+# Objects for libdk4maioxd.so or libdk4maioxd.a library
+LIBDK4MAIOXDOBJ= \
+ dk4maoxdbl.o \
+ dk4maixdbl.o \
+ dk4maixdic.o \
+ dk4maixdis.o \
+ dk4maixdii.o \
+ dk4maixdmi.o \
+ dk4maixdli.o \
+ dk4maixdil.o \
+ dk4maixddi.o \
+ dk4maixduc.o \
+ dk4maixdus.o \
+ dk4maixdui.o \
+ dk4maixdmu.o \
+ dk4maixdlu.o \
+ dk4maixdul.o \
+ dk4maixdsz.o \
+ dk4maixddu.o \
+ dk4maoxd.o
+
+# Objects for libdk4maiodh.so or libdk4maiodh.a library
+LIBDK4MAIODHOBJ= \
+ dk4maidhic.o \
+ dk4maidhis.o \
+ dk4maidhii.o \
+ dk4maidhmi.o \
+ dk4maidhli.o \
+ dk4maidhil.o \
+ dk4maidhdi.o \
+ dk4maidhuc.o \
+ dk4maidhus.o \
+ dk4maidhui.o \
+ dk4maidhmu.o \
+ dk4maidhlu.o \
+ dk4maidhul.o \
+ dk4maidhdu.o \
+ dk4maodh.o \
+ dk4maodo.o
+
+# Objects for libdk4maiowd.so or libdk4maiowd.a library
+LIBDK4MAIOWDOBJ= \
+ dk4maowdbl.o \
+ dk4maiwdbl.o \
+ dk4maiwdic.o \
+ dk4maiwdis.o \
+ dk4maiwdii.o \
+ dk4maiwdmi.o \
+ dk4maiwdli.o \
+ dk4maiwdil.o \
+ dk4maiwduc.o \
+ dk4maiwdus.o \
+ dk4maiwdui.o \
+ dk4maiwdmu.o \
+ dk4maiwdlu.o \
+ dk4maiwdul.o \
+ dk4maiwdsz.o \
+ dk4maiwddi.o \
+ dk4maiwddu.o \
+ dk4maowd.o
+
+# Objects for libdk4maiowh.so or libdk4maiowh.a library
+LIBDK4MAIOWHOBJ= \
+ dk4maiwhic.o \
+ dk4maiwhis.o \
+ dk4maiwhii.o \
+ dk4maiwhmi.o \
+ dk4maiwhli.o \
+ dk4maiwhil.o \
+ dk4maiwhuc.o \
+ dk4maiwhus.o \
+ dk4maiwhui.o \
+ dk4maiwhmu.o \
+ dk4maiwhlu.o \
+ dk4maiwhul.o \
+ dk4maiwhdi.o \
+ dk4maiwhdu.o \
+ dk4maowh.o
+
+# Objects for libdk4maio8d.so or libdk4maio8d.a library
+LIBDK4MAIO8DOBJ= \
+ dk4mao8dbl.o \
+ dk4mai8dbl.o \
+ dk4mai8dic.o \
+ dk4mai8dis.o \
+ dk4mai8dii.o \
+ dk4mai8dmi.o \
+ dk4mai8dli.o \
+ dk4mai8dil.o \
+ dk4mai8ddi.o \
+ dk4mai8duc.o \
+ dk4mai8dus.o \
+ dk4mai8dui.o \
+ dk4mai8dmu.o \
+ dk4mai8dlu.o \
+ dk4mai8dul.o \
+ dk4mai8dsz.o \
+ dk4mai8ddu.o \
+ dk4mao8d.o
+
+# Objects for libdk4maio8h.so or libdk4maio8h.a library
+LIBDK4MAIO8HOBJ= \
+ dk4mai8hic.o \
+ dk4mai8his.o \
+ dk4mai8hii.o \
+ dk4mai8hmi.o \
+ dk4mai8hli.o \
+ dk4mai8hil.o \
+ dk4mai8hdi.o \
+ dk4mai8huc.o \
+ dk4mai8hus.o \
+ dk4mai8hui.o \
+ dk4mai8hmu.o \
+ dk4mai8hlu.o \
+ dk4mai8hul.o \
+ dk4mai8hdu.o \
+ dk4mao8h.o
+
+# Objects for libdk4ma.so or libdk4ma.a library
+LIBDK4MAOBJ= \
+ dk4numl.o \
+ dk4macd.o \
+ dk4macm.o \
+ dk4macll.o \
+ dk4macl.o \
+ dk4maci.o \
+ dk4macs.o \
+ dk4macc.o \
+ dk4maasz.o \
+ dk4maadi.o \
+ dk4maadu.o \
+ dk4maami.o \
+ dk4maamu.o \
+ dk4maall.o \
+ dk4maalu.o \
+ dk4maal.o \
+ dk4maaul.o \
+ dk4maai.o \
+ dk4maaui.o \
+ dk4maas.o \
+ dk4maaus.o \
+ dk4maac.o \
+ dk4maauc.o \
+ dk4maau16.o \
+ dk4maai16.o \
+ dk4maau32.o \
+ dk4maai32.o \
+ dk4maci16.o \
+ dk4maci32.o
+
+# Objects for libdk4dbia.so or libdk4dbia.a library
+LIBDK4DBIAOBJ= \
+ dk4dbia.o
+
+# Objects for libdk4dbi.so or libdk4dbi.a library
+LIBDK4DBIOBJ= \
+ dk4dbit.o \
+ dk4dbitw.o \
+ dk4dbit8.o \
+ dk4dbi.o
+
+# Objects for libdk4base.so or libdk4base.a library
+LIBDK4BASEOBJ= \
+ dk4strd.o \
+ dk4strw.o \
+ dk4str8.o \
+ dk4memcpl.o \
+ dk4memrs.o \
+ dk4mem.o \
+ dk4error.o
+
+# Objects for libdk4.a library
+OBJLIBDK4= @LIBDK4WXOBJ@ \
+ $(LIBDK4LATOBJ) \
+ $(LIBDK4DBIAOBJ) \
+ $(LIBDK4SOCKAOBJ) \
+ $(LIBDK4PPPTAOBJ) \
+ $(LIBDK4APPOBJ) \
+ $(LIBDK4MDRNDOBJ) \
+ $(LIBDK4SOCKOBJ) \
+ $(LIBDK4PPPTOBJ) \
+ $(LIBDK4COBJ) \
+ $(LIBDK4MAIODDOBJ) \
+ $(LIBDK4MAIOWDOBJ) \
+ $(LIBDK4MAIO8DOBJ) \
+ $(LIBDK4MAIODHOBJ) \
+ $(LIBDK4MAIOWHOBJ) \
+ $(LIBDK4MAIO8HOBJ) \
+ $(LIBDK4MAOBJ) \
+ $(LIBDK4DBIOBJ) \
+ $(LIBDK4BASEOBJ)
+
+libdk4.a: # Static library containig all modules
+libdk4.a: $(OBJLIBDK4)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(OBJLIBDK4)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4WXLIBF=@LIBDK4WXLIBF@
+LIBDK4WXLIBS=@LIBDK4WXLIBS@
+
+libdk4wx.so: # Support for wxWidgets shared
+libdk4wx.so: $(LIBDK4WXLIBF) $(LIBDK4WXOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4WXOBJ) $(LIBDK4WXLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4wx.a: # Support for wxWidgets static
+libdk4wx.a: libdk4c.a $(LIBDK4WXOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4WXOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4SOCKALIBF=@LIBDK4SOCKALIBF@
+LIBDK4SOCKALIBS=@LIBDK4SOCKALIBS@
+
+libdk4socka.so: # Socket library with application support
+libdk4socka.so: $(LIBDK4SOCKALIBF) $(LIBDK4SOCKAOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4SOCKAOBJ) $(LIBDK4SOCKALIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4socka.a: # Socket library with application support, static
+libdk4socka.a: libdk4sock.a libdk4app.a $(LIBDK4SOCKAOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4SOCKAOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4DBIALIBF=@LIBDK4DBIALIBF@
+LIBDK4DBIALIBS=@LIBDK4DBIALIBS@
+
+libdk4dbia.so: # Simple database interface with app support
+libdk4dbia.so: $(LIBDK4DBIALIBF) $(LIBDK4DBIAOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4DBIAOBJ) $(LIBDK4DBIALIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4dbia.a: # Simple database interface with app support, static
+libdk4dbia.a: libdk4dbi.a libdk4app.a $(LIBDK4DBIAOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4DBIAOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4SOCKLIBF=@LIBDK4SOCKLIBF@
+LIBDK4SOCKLIBS=@LIBDK4SOCKLIBS@
+
+libdk4sock.so: # Socket library without application support
+libdk4sock.so: $(LIBDK4SOCKLIBF) $(LIBDK4SOCKOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4SOCKOBJ) $(LIBDK4SOCKLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4sock.a: # Socket library without app support, static version
+libdk4sock.a: libdk4c.a $(LIBDK4SOCKOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4SOCKOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4LATLIBF=@LIBDK4LATLIBF@
+LIBDK4LATLIBS=@LIBDK4LATLIBS@
+
+libdk4lat.so: # Text to LaTeX conversion library
+libdk4lat.so: $(LIBDK4LATLIBF) $(LIBDK4LATOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4LATOBJ) $(LIBDK4LATLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4lat.a: # Text to LaTeX conversion static library
+libdk4lat.a: libdk4c.a $(LIBDK4LATOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4LATOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4PPPTALIBF=@LIBDK4PPPTALIBF@
+LIBDK4PPPTALIBS=@LIBDK4PPPTALIBS@
+
+libdk4pppta.so: # PS+TeX,PDF+TeX,PGF creator library
+libdk4pppta.so: $(LIBDK4PPPTALIBF) $(LIBDK4PPPTAOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4PPPTAOBJ) $(LIBDK4PPPTALIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4pppta.a: # PS+TeX,PDF+TeX,PGF creator library static
+libdk4pppta.a: libdk4app.a libdk4pppt.a $(LIBDK4PPPTAOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4PPPTAOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4APPLIBF=@LIBDK4APPLIBF@
+LIBDK4APPLIBS=@LIBDK4APPLIBS@
+
+libdk4app.so: # Application support library shared
+libdk4app.so: $(LIBDK4APPLIBF) $(LIBDK4APPOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4APPOBJ) $(LIBDK4APPLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4app.a: # Application support library static
+libdk4app.a: libdk4c.a $(LIBDK4APPOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4APPOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4MDRNDLIBF=@LIBDK4MDRNDLIBF@
+LIBDK4MDRNDLIBS=@LIBDK4MDRNDLIBS@
+
+libdk4mdrnd.so: # Message digest and random library shared
+libdk4mdrnd.so: $(LIBDK4MDRNDLIBF) $(LIBDK4MDRNDOBJ)
+ -[ ! -f $@ ] || rm -fr $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4MDRNDOBJ) $(LIBDK4MDRNDLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4mdrnd.a: # Message digest and random library static
+libdk4mdrnd.a: libdk4c.a $(LIBDK4MDRNDOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4MDRNDOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4PPPTLIBF=@LIBDK4PPPTLIBF@
+LIBDK4PPPTLIBS=@LIBDK4PPPTLIBS@
+
+libdk4pppt.so: # PS+TeX,PDF+TeX,PGF creator library
+libdk4pppt.so: $(LIBDK4PPPTLIBF) $(LIBDK4PPPTOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4PPPTOBJ) $(LIBDK4PPPTLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4pppt.a: # PS+TeX,PDF+TeX,PGF creator library static
+libdk4pppt.a: libdk4c.a $(LIBDK4PPPTOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4PPPTOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4CLIBF=@LIBDK4CLIBF@
+LIBDK4CLIBS=@LIBDK4CLIBS@
+
+libdk4c.so: # General C library shared
+libdk4c.so: $(LIBDK4CLIBF) $(LIBDK4COBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4COBJ) $(LIBDK4CLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4c.a: # General C library static
+libdk4c.a: libdk4maiodd.a $(LIBDK4COBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4COBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4DBILIBF=@LIBDK4DBILIBF@
+LIBDK4DBILIBS=@LIBDK4DBILIBS@
+
+libdk4dbi.so: # Simple database interface
+libdk4dbi.so: $(LIBDK4DBILIBF) $(LIBDK4DBIOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4DBIOBJ) $(LIBDK4DBILIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4dbi.a: # Simple database interface static library
+libdk4dbi.a: libdk4ma.a $(LIBDK4DBIOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4DBIOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4MAIOXDLIBF=@LIBDK4MAIOXDLIBF@
+LIBDK4MAIOXDLIBS=@LIBDK4MAIOXDLIBS@
+
+libdk4maioxd.so: # Numeric values I/O, wxChar, decimal, shared
+libdk4maioxd.so: $(LIBDK4MAIOXDLIBF) $(LIBDK4MAIOXDOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4MAIOXDOBJ) $(LIBDK4MAIOXDLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4maioxd.a: # Numeric values I/O, wxChar, decimal, static
+libdk4maioxd.a: libdk4maio8d.a libdk4ma.a $(LIBDK4MAIOXDOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4MAIOXDOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4MAIODDLIBF=@LIBDK4MAIODDLIBF@
+LIBDK4MAIODDLIBS=@LIBDK4MAIODDLIBS@
+
+libdk4maiodd.so: # Numeric values I/O, dkChar, decimal, shared
+libdk4maiodd.so: $(LIBDK4MAIODDLIBF) $(LIBDK4MAIODDOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4MAIODDOBJ) $(LIBDK4MAIODDLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4maiodd.a: # Numeric values I/O, dkChar, decimal, static
+libdk4maiodd.a: libdk4maio8d.a libdk4ma.a $(LIBDK4MAIODDOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4MAIODDOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4MAIOWDLIBF=@LIBDK4MAIOWDLIBF@
+LIBDK4MAIOWDLIBS=@LIBDK4MAIOWDLIBS@
+
+libdk4maiowd.so: # Numeric values I/O, wchar_t, decimal, shared
+libdk4maiowd.so: $(LIBDK4MAIOWDLIBF) $(LIBDK4MAIOWDOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4MAIOWDOBJ) $(LIBDK4MAIOWDLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4maiowd.a: # Numeric values I/O, wchar_t, decimal, static
+libdk4maiowd.a: libdk4ma.a $(LIBDK4MAIOWDOBJ)
+ [ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4MAIOWDOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4MAIO8DLIBF=@LIBDK4MAIO8DLIBF@
+LIBDK4MAIO8DLIBS=@LIBDK4MAIO8DLIBS@
+
+libdk4maio8d.so: # Numeric values I/O, char, decimal, shared
+libdk4maio8d.so: $(LIBDK4MAIO8DLIBF) $(LIBDK4MAIO8DOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4MAIO8DOBJ) $(LIBDK4MAIO8DLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4maio8d.a: # Numeric values I/O, char, decimal, static
+libdk4maio8d.a: libdk4ma.a $(LIBDK4MAIO8DOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4MAIO8DOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4MAIODHLIBF=@LIBDK4MAIODHLIBF@
+LIBDK4MAIODHLIBS=@LIBDK4MAIODHLIBS@
+
+libdk4maiodh.so: # Numeric values I/O, dkChar, hexadecimal, shared
+libdk4maiodh.so: $(LIBDK4MAIODHLIBF) $(LIBDK4MAIODHOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4MAIODHOBJ) $(LIBDK4MAIODHLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4maiodh.a: # Numeric values I/O, dkChar, hexadecimal, static
+libdk4maiodh.a: libdk4ma.a $(LIBDK4MAIODHOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4MAIODHOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4MAIOWHLIBF=@LIBDK4MAIOWHLIBF@
+LIBDK4MAIOWHLIBS=@LIBDK4MAIOWHLIBS@
+
+libdk4maiowh.so: # Numeric values I/O, wchar_t, hexadecimal, shared
+libdk4maiowh.so: $(LIBDK4MAIOWHLIBF) $(LIBDK4MAIOWHOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4MAIOWHOBJ) $(LIBDK4MAIOWHLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4maiowh.a: # Numeric values I/O, wchar_t, hexadecimal, static
+libdk4maiowh.a: libdk4ma.a $(LIBDK4MAIOWHOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4MAIOWHOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4MAIO8HLIBF=@LIBDK4MAIO8HLIBF@
+LIBDK4MAIO8HLIBS=@LIBDK4MAIO8HLIBS@
+
+libdk4maio8h.so: # Numeric values I/O, char, hexadecimal, shared
+libdk4maio8h.so: $(LIBDK4MAIO8HLIBF) $(LIBDK4MAIO8HOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4MAIO8HOBJ) $(LIBDK4MAIO8HLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4maio8h.a: # Numeric values I/O, char, hexadecimal, static
+libdk4maio8h.a: libdk4ma.a $(LIBDK4MAIO8HOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4MAIO8HOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4MALIBF=@LIBDK4MALIBF@
+LIBDK4MALIBS=@LIBDK4MALIBS@
+
+libdk4ma.so: # Mathematics library, shared
+libdk4ma.so: $(LIBDK4MALIBF) $(LIBDK4MAOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4MAOBJ) $(LIBDK4MALIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4ma.a: # Mathematics library, static
+libdk4ma.a: libdk4base.a $(LIBDK4MAOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4MAOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+LIBDK4BASELIBF=@LIBDK4BASELIBF@
+LIBDK4BASELIBS=@LIBDK4BASELIBS@
+
+libdk4base.so: # Base library, shared
+libdk4base.so: $(LIBDK4BASELIBF) $(LIBDK4BASEOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ @echo '### Shared lib ### ' $@
+ $(MKSOLIB) $(LIBDK4BASEOBJ) $(LIBDK4BASELIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk4base.a: # Base library, static
+libdk4base.a: $(LIBDK4BASEOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Static lib ### ' $@
+ $(AR) -r $@ $(LIBDK4BASEOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+#
+# Programs to fix configure script results to DK4_HAVE_... constants
+#
+
+dk3config: # Program: Show configuration for dk3... modules
+dk3config$(EXEEXT): dk3config.c
+ @-[ ! -f dk3conig ] || rm -f dk3config
+ @$(COMPILEC) $(CFLAGS) $(LDFLAGS) -L. -o $@ dk3config.c -lm
+ @chmod 755 dk3config
+
+dk4config: # Program: Show configuration for dk4... modules
+dk4config$(EXEEXT): dk4config.cpp
+ @-[ ! -f $@ ] || rm -f $@
+ @$(COMPILECPP) $(LDFLAGS) $(WXLDFLAGS) -o $@ dk4config.cpp
+ @chmod 755 $@
+
+wxcs: # Program: Show wxChar character size
+wxcs$(EXEEXT): wxcs.cpp
+ @-[ ! -f $@ ] || rm -f $@
+ @$(COMPILECPP) $(LDFLAGS) $(WXLDFLAGS) -o $@ wxcs.cpp
+ @chmod 755 $@
+
+
+
+# ##### Start of dktools-4 section
+
+DKCATLIBF=@DKCATLIBF@
+DKCATLIBS=@DKCATLIBS@
+
+dk-cat: # Program: Show file contents
+dk-cat$(EXEEXT): $(DKCATLIBF) dk-cat.o
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk-cat.o $(DKCATLIBS)
+ chmod 755 $@
+
+
+
+DKBLKSLIBF=@DKBLKSLIBF@
+DKBLKSLIBS=@DKBLKSLIBS@
+
+dk-blks: # Program: Adjust block size
+dk-blks$(EXEEXT): $(DKBLKSLIBF) dk-blks.o
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk-blks.o $(DKBLKSLIBS)
+ chmod 755 $@
+
+
+
+DKSQLSPLITLIBF=@DKSQLSPLITLIBF@
+DKSQLSPLITLIBS=@DKSQLSPLITLIBS@
+
+dk-sqlsplit: # Program: Split overlong SQL lines
+dk-sqlsplit$(EXEEXT): $(DKSQLSPLITLIBF) dk-sqlsplit.o
+ -[ ! -f $@ ] || rm -fr $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk-sqlsplit.o $(DKSQLSPLITLIBS)
+ chmod 755 $@
+
+
+
+DKERADISKLIBF=@DKERADISKLIBF@
+DKERADISKLIBS=@DKERADISKLIBS@
+
+dk-eradisk: # Program: Create data stream for disk deletion
+dk-eradisk$(EXEEXT): $(DKERADISKLIBF) dk-eradisk.o
+ -[ ! -f $@ ] || rm -fr $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk-eradisk.o $(DKERADISKLIBS)
+ chmod 755 $@
+
+
+
+DKLSOBJ= dk-ls.o dk-ls-to.o
+
+DKLSLIBF=@DKLSLIBF@
+DKLSLIBS=@DKLSLIBS@
+
+dk-ls: # Program: SHow information about files
+dk-ls$(EXEEXT): $(DKLSLIBF) $(DKLSOBJ)
+ -[ ! -f $@ ] || rm -fr $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ $(DKLSOBJ) $(DKLSLIBS)
+ chmod 755 $@
+
+
+
+DKSORTOBJ= dk-sort.o
+
+DKSORTLIBF=@DKSORTLIBF@
+DKSORTLIBS=@DKSORTLIBS@
+
+dk-sort: # Program: Text sorting in different encodings
+dk-sort$(EXEEXT): $(DKSORTLIBF) $(DKSORTOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -L. -o $@ $(DKSORTOBJ) $(DKSORTLIBS)
+ chmod 755 $@
+
+
+
+DKFICLIBF=@DKFICLIBF@
+DKFICLIBS=@DKFICLIBS@
+
+dk-fic: # Program: File integrity checker (CLI)
+dk-fic$(EXEEXT): $(DKFICLIBF) dk-fic.o
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk-fic.o $(DKFICLIBS)
+ chmod 755 $@
+
+
+
+DKUIDLIBF=@DKUIDLIBF@
+DKUIDLIBS=@DKUIDLIBS@
+
+dk-uid: # Program: Find free UID in given range
+dk-uid$(EXEEXT): $(DKUIDLIBF) dk-uid.o
+ [ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk-uid.o $(DKUIDLIBS)
+ chmod 755 $@
+
+
+
+DKPWGENLIBF=@DKPWGENLIBF@
+DKPWGENLIBS=@DKPWGENLIBS@
+
+dk-pwgen: # Program: Passwort/PIN/WiFi key generator
+dk-pwgen$(EXEEXT): $(DKPWGENLIBF) dk-pwgen.o
+ [ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk-pwgen.o $(DKPWGENLIBS)
+ chmod 755 $@
+
+
+
+DKRANDLIBF=@DKRANDLIBF@
+DKRANDLIBS=@DKRANDLIBS@
+
+dk-rand: # Program: Random data generator
+dk-rand$(EXEEXT): $(DKRANDLIBF) dk-rand.o
+ [ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk-rand.o $(DKRANDLIBS)
+ chmod 755 $@
+
+
+
+DKT2HLIBF=@DKT2HLIBF@
+DKT2HLIBS=@DKT2HLIBS@
+
+dk-t2h: # Program: Convert text to HTML
+dk-t2h$(EXEEXT): $(DKT2HLIBF) dk-t2h.o
+ [ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk-t2h.o $(DKT2HLIBS)
+ chmod 755 $@
+
+
+
+DKT2LLIBF=@DKT2LLIBF@
+DKT2LLIBS=@DKT2LLIBS@
+
+dk-t2l: # Program: Convert text to LaTeX
+dk-t2l$(EXEEXT): $(DKT2LLIBF) dk-t2l.o
+ [ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk-t2l.o $(DKT2LLIBS)
+ chmod 755 $@
+
+
+
+DKHEXLIBF=@DKHEXLIBF@
+DKHEXLIBS=@DKHEXLIBS@
+
+dk-hex: # Program: Show file contents in hexadecimal notation
+dk-hex$(EXEEXT): $(DKHEXLIBF) dk-hex.o
+ [ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk-hex.o $(DKHEXLIBS)
+ chmod 755 $@
+
+
+
+DKBMMLIBF=@DKBMMLIBF@
+DKBMMLIBS=@DKBMMLIBS@
+
+dk-bmm: # Program: Backup media management
+dk-bmm$(EXEEXT): $(DKBMMLIBF) dk-bmm.o
+ [ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk-bmm.o $(DKBMMLIBS)
+ chmod 755 $@
+
+
+
+DKPWDLIBF=@DKPWDLIBF@
+DKPWDLIBS=@DKPWDLIBS@
+
+dk-pwd: # Program: Print working directory
+dk-pwd$(EXEEXT): $(DKPWDLIBF) dk-pwd.o
+ [ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk-pwd.o $(DKPWDLIBS)
+ chmod 755 $@
+
+
+
+DKRECVLIBF=@DKRECVLIBF@
+DKRECVLIBS=@DKRECVLIBS@
+
+dk-recv: # Program: Receive data stream from dk-send process
+dk-recv$(EXEEXT): $(DKRECVLIBF) dk-recv.o
+ [ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk-recv.o $(DKRECVLIBS)
+ chmod 755 $@
+
+
+
+DKSENDLIBF=@DKSENDLIBF@
+DKSENDLIBS=@DKSENDLIBS@
+
+dk-send: # Program: Send data to one or multiple recipients
+dk-send$(EXEEXT): $(DKSENDLIBF) dk-send.o
+ [ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk-send.o $(DKSENDLIBS)
+ chmod 755 $@
+
+
+
+PRINTQDOBJ= printqd.o
+
+PRINTQDLIBF=@PRINTQDLIBF@
+PRINTQDLIBS=@PRINTQDLIBS@
+
+printqd: # Program: Print quota enforcement daemon
+printqd$(EXEEXT): $(PRINTQDLIBF) $(PRINTQDOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ $(PRINTQDOBJ) $(PRINTQDLIBS)
+ chmod 755 $@
+
+
+
+PRINTQDCOBJ= printqdc.o
+
+PRINTQDCLIBF=@PRINTQDCLIBF@
+PRINTQDCLIBS=@PRINTQDCLIBS@
+
+printqdc: # Program: Print quota client
+printqdc$(EXEEXT): $(PRINTQDCLIBF) $(PRINTQDCOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ $(PRINTQDCOBJ) $(PRINTQDCLIBS)
+ chmod 755 $@
+
+
+
+WXPQDICOBJ= WxpqdicApp.o WxpqdicFrame.o
+
+WXPQDICLIBF=@WXPQDICLIBF@
+WXPQDICLIBS=@WXPQDICLIBS@
+
+wxpqdic: # Program: Client for printqd queries
+wxpqdic$(EXEEXT): $(WXPQDICLIBF) $(WXPQDICOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C++) ' $@
+ $(LDCPP) $(ENTRY) -o $@ $(WXPQDICOBJ) $(WXPQDICLIBS)
+ chmod 755 $@
+
+
+
+PJSNMPLIBF=@PJSNMPLIBF@
+PJSNMPLIBS=@PJSNMPLIBS@
+
+pjsnmp: # Program: Print job transfer using TCP and SNMP
+pjsnmp$(EXEEXT): $(PJSNMPLIBF) pjsnmp.o
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ pjsnmp.o $(PJSNMPLIBS)
+ chmod 755 $@
+
+
+
+PRMONSNMPLIBF=@PRMONSNMPLIBF@
+PRMONSNMPLIBS=@PRMONSNMPLIBS@
+
+prmonsnmp: # Program: Monitor printers using SNMP
+prmonsnmp$(EXEEXT): $(PRMONSNMPLIBF) prmonsnmp.o
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ prmonsnmp.o $(PRMONSNMPLIBS)
+ chmod 755 $@
+
+
+
+LPRNGCLLIBF=@LPRNGCLLIBF@
+LPRNGCLLIBS=@LPRNGCLLIBS@
+
+lprngcl: # Program: LPRng queue cleanup
+lprngcl$(EXEEXT): $(LPRNGCLLIBF) lprngcl.o
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ lprngcl.o $(LPRNGCLLIBS)
+ chmod 755 $@
+
+
+
+DKDBT2LIBF=@DKDBT2LIBF@
+DKDBT2LIBS=@DKDBT2LIBS@
+
+dk-db2t: # Program: Convert database to text
+dk-db2t$(EXEEXT): $(DKDBT2LIBF) dk-db2t.o
+ [ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk-db2t.o $(DKDBT2LIBS)
+ chmod 755 $@
+
+dk-dbco: # Program: Copy database
+dk-dbco$(EXEEXT): $(DKDBT2LIBF) dk-dbco.o
+ [ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk-dbco.o $(DKDBT2LIBS)
+ chmod 755 $@
+
+dk-t2db: # Program: Convert text to database
+dk-t2db$(EXEEXT): $(DKDBT2LIBF) dk-t2db.o
+ [ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk-t2db.o $(DKDBT2LIBS)
+ chmod 755 $@
+
+
+
+RSHDOWNLIBF=@RSHDOWNLIBF@
+RSHDOWNLIBS=@RSHDOWNLIBS@
+
+rshdown: # Program: Remote shutdown
+rshdown$(EXEEXT): $(RSHDOWNLIBF) rshdown.o
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ rshdown.o $(RSHDOWNLIBS)
+ chmod 755 $@
+
+
+
+DK4INFOLIBF=@DK4INFOLIBF@
+DK4INFOLIBS=@DK4INFOLIBS@
+
+dk4info: # Program: Show information about this build
+dk4info$(EXEEXT): $(DK4INFOLIBF) dk4info.o
+ [ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk4info.o $(DK4INFOLIBS)
+ chmod 755 $@
+
+# ##### End of dktools-4 section
+
+
+
+# ##### Start of dktools-3 section
+
+# Objects for libdk3c.so or libdk3c.a library
+LIBDK3COBJ= \
+ dk3ufi.o \
+ dk3opt.o \
+ dk3bf.o \
+ dk3se.o \
+ dk3app.o \
+ dk3strm.o \
+ dk3print.o \
+ dk3prcfg.o \
+ dk3strkv.o \
+ dk3sto.o \
+ dk3dir.o \
+ dk3enc.o \
+ dk3str.o \
+ dk3cores.o \
+ dk3sf.o \
+ dk3echo.o \
+ dk3signl.o \
+ dk3ct.o \
+ dk3mas.o \
+ dk3maus.o \
+ dk3mai.o \
+ dk3maui.o \
+ dk3mal.o \
+ dk3maul.o \
+ dk3mad.o \
+ dk3madsc.o \
+ dk3madic.o \
+ dk3madlc.o \
+ dk3maidd.o \
+ dk3maihd.o \
+ dk3maodd.o \
+ dk3maohd.o \
+ dk3maid8.o \
+ dk3maih8.o \
+ dk3maod8.o \
+ dk3maoh8.o \
+ dk3masts.o \
+ dk3madfo.o \
+ dk3madso.o \
+ dk3madsi.o \
+ dk3inst.o \
+ dk3srch.o \
+ dk3bits.o \
+ dk3mem.o \
+ dk3bb.o \
+ dk3bezcu.o \
+ dk3xsp.o \
+ dk3kv.o \
+ dk3trace.o
+
+# Objects for libdk3of.so or libdk3of.a library
+LIBDK3OFOBJ= \
+ dk3of.o \
+ dk3strmb.o \
+ dk3strmg.o
+
+# Objects for libdk3csrnd.so or libdk3csrnd.a library
+LIBDK3CSRNDOBJ= \
+ dk3chks.o \
+ dk3appr.o
+
+# Objects for libdk3bif.so or libdk3bif.a library
+LIBDK3BIFOBJ= \
+ dk3bifa.o \
+ dk3bif.o \
+ dk3pixre.o
+
+# Objects for libdk3dbi.so or libdk3dbi.a library
+LIBDK3DBIOBJ= \
+ dk3dbi.o
+
+# Objects for libdk3bmeps.so or libdk3bmeps.a library
+LIBDK3BMEPSOBJ= \
+ dk3bm.o \
+ dk3bmeo.o \
+ dk3bmep.o \
+ dk3bmeps.o \
+ dk3bmj.o \
+ dk3pdf.o \
+ dk3paper.o
+
+# Objects for libdk3fig.so or libdk3fig.a library
+LIBDK3FIGOBJ= \
+ dk3figbb.o \
+ dk3figpr.o \
+ dk3figah.o \
+ dk3figrd.o \
+ dk3figto.o \
+ dk3fig.o \
+ dk3font.o \
+ dk3ct.o
+
+# Objects for libdk3wx.so or libdk3wx.a library
+LIBDK3WXOBJ= \
+ DkWxProgressDialog.o \
+ DkWxCommunicator.o \
+ DkWxFrame.o \
+ DkWxDialog.o \
+ DkWxHelpController.o \
+ DkWxAppHelper.o \
+ DkWxColorView.o \
+ DkWxBufferedControl.o \
+ DkWxProcessingIdleController.o \
+ DkWxProcessingController.o \
+ dk3wxs.o
+
+# Objects for libdk3.a library
+LIBDK3ALLOBJ= @LIBDK3WXOBJ@ \
+ $(LIBDK3FIGOBJ) \
+ $(LIBDK3BMEPSOBJ) \
+ $(LIBDK3BIFOBJ) \
+ $(LIBDK3CSRNDOBJ) \
+ $(LIBDK3DBIOBJ) \
+ $(LIBDK3OFOBJ) \
+ $(LIBDK3COBJ)
+
+
+
+libdk3.a: # Large library containing all dktools-3 modules.
+libdk3.a: $(LIBDK3ALLOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ $(AR) -r $@ $(LIBDK3ALLOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+
+
+LIBDK3TRACELIBF=@LIBDK3TRACELIBF@
+LIBDK3TRACELIBS=@LIBDK3TRACELIBS@
+
+libdk3trace.so: # The libdk3trace library (shared)
+libdk3trace.so: $(LIBDK3TRACELIBF) dk3trace.o
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ $(MKSOLIB) dk3trace.o $(LIBDK3TRACELIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk3trace.a: # The libdk3trace library (static)
+libdk3trace.a: dk3trace.o
+ -[ ! -f $@ ] || rm -f $@
+ $(AR) -r $@ dk3trace.o
+ $(RANLIB) $@
+ chmod 644 $@
+
+
+
+LIBDK3CLIBF=@LIBDK3CLIBF@
+LIBDK3CLIBS=@LIBDK3CLIBS@
+
+libdk3c.so: # The libdk3c library (shared).
+libdk3c.so: $(LIBDK3CLIBF) $(LIBDK3COBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ $(MKSOLIB) $(LIBDK3COBJ) $(LIBDK3CLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk3c.a: # The libdk3c library (static).
+libdk3c.a: $(LIBDK3COBJ)
+ -[ ! -f $@ ] || rm -f $@
+ $(AR) -r $@ $(LIBDK3COBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+
+
+LIBDK3OFLIBF=@LIBDK3OFLIBF@
+LIBDK3OFLIBS=@LIBDK3OFLIBS@
+
+libdk3of.so: # The dktools-3 output filter library (shared).
+libdk3of.so: $(LIBDK3OFLIBF) $(LIBDK3OFOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ $(MKSOLIB) $(LIBDK3OFOBJ) $(LIBDK3OFLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk3of.a: # The dktools-3 output filter library (static).
+libdk3of.a: $(LIBDK3OFOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ $(AR) -r $@ $(LIBDK3OFOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+
+
+LIBDK3CSRNDLIBF=@LIBDK3CSRNDLIBF@
+LIBDK3CSRNDLIBS=@LIBDK3CSRNDLIBS@
+
+libdk3csrnd.so: # The dktools-3 checksum and random library (shared).
+libdk3csrnd.so: $(LIBDK3CSRNDLIBF) $(LIBDK3CSRNDOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ $(MKSOLIB) $(LIBDK3CSRNDOBJ) $(LIBDK3CSRNDLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk3csrnd.a: # The dktools-3 checksum and random library (static).
+libdk3csrnd.a: $(LIBDK3CSRNDOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ $(AR) -r $@ $(LIBDK3CSRNDOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+
+
+LIBDK3BIFLIBF=@LIBDK3BIFLIBF@
+LIBDK3BIFLIBS=@LIBDK3BIFLIBS@
+
+libdk3bif.so: # the dktools-3 bitmap image file library (shared).
+libdk3bif.so: $(LIBDK3BIFLIBF) $(LIBDK3BIFOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ $(MKSOLIB) $(LIBDK3BIFOBJ) $(LIBDK3BIFLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk3bif.a: # the dktools-3 bitmap image file library (static).
+libdk3bif.a: $(LIBDK3BIFOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ $(AR) -r $@ $(LIBDK3BIFOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+
+
+LIBDK3DBILIBF=@LIBDK3DBILIBF@
+LIBDK3DBILIBS=@LIBDK3DBILIBS@
+
+libdk3dbi.so: # The dktools-3 data base interface library (shared).
+libdk3dbi.so: $(LIBDK3DBILIBF) $(LIBDK3DBIOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ $(MKSOLIB) $(LIBDK3DBIOBJ) $(LIBDK3DBILIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk3dbi.a: # The dktools-3 data base interface library (static).
+libdk3dbi.a: $(LIBDK3DBIOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ $(AR) -r $@ $(LIBDK3DBIOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+
+
+LIBDK3BMEPSLIBF=@LIBDK3BMEPSLIBF@
+LIBDK3BMEPSLIBS=@LIBDK3BMEPSLIBS@
+
+libdk3bmeps.so: # The dktools-3 bitmap to EPS library (shared).
+libdk3bmeps.so: $(LIBDK3BMEPSLIBF) $(LIBDK3BMEPSOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ $(MKSOLIB) $(LIBDK3BMEPSOBJ) $(LIBDK3BMEPSLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk3bmeps.a: # The dktools-3 bitmap to EPS library (static).
+libdk3bmeps.a: $(LIBDK3BMEPSOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ $(AR) -r $@ $(LIBDK3BMEPSOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+
+
+LIBDK3FIGLIBF=@LIBDK3FIGLIBF@
+LIBDK3FIGLIBS=@LIBDK3FIGLIBS@
+
+libdk3fig.so: # The dktools-3 Fig file library (shared).
+libdk3fig.so: $(LIBDK3FIGLIBF) $(LIBDK3FIGOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ $(MKSOLIB) $(LIBDK3FIGOBJ) $(LIBDK3FIGLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk3fig.a: # The dktools-3 Fig file library (static).
+libdk3fig.a: $(LIBDK3FIGOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ $(AR) -r $@ $(LIBDK3FIGOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+
+
+LIBDK3WXLIBF=@LIBDK3WXLIBF@
+LIBDK3WXLIBS=@LIBDK3WXLIBS@
+
+libdk3wx.so: # The dktools-3 GUI library (shared).
+libdk3wx.so: $(LIBDK3WXLIBF) $(LIBDK3WXOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ -[ ! -f $@.$(SOVERS) ] || rm -f $@.$(SOVERS)
+ $(MKSOLIB) $(LIBDK3WXOBJ) $(LIBDK3WXLIBS)
+ $(LN_S) $@.$(SOVERS) $@
+ chmod 644 $@.$(SOVERS) $@
+
+libdk3wx.a: # The dktools-3 GUI library (static).
+libdk3wx.a: $(LIBDK3WXOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ $(AR) -r $@ $(LIBDK3WXOBJ)
+ $(RANLIB) $@
+ chmod 644 $@
+
+
+
+DKCTOBJ= dkct.o dkct-str.o dkct-tr.o dkct-au.o dkct-gui.o dkct-to.o
+
+DKCTLIBF=@DKCTLIBF@
+DKCTLIBS=@DKCTLIBS@
+
+dkct: # Program: Dirk Krause's C tool (CLI)
+dkct$(EXEEXT): $(DKCTLIBF) $(DKCTOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ $(DKCTOBJ) $(DKCTLIBS)
+ chmod 755 $@
+
+
+
+ADDCTRLDLIBF=@ADDCTRLDLIBF@
+ADDCTRLDLIBS=@ADDCTRLDLIBS@
+
+addctrld: # Program: Filter to ensure Ctrl-D as final byte
+addctrld$(EXEEXT): $(ADDCTRLDLIBF) addctrld.o
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ addctrld.o $(ADDCTRLDLIBS)
+ chmod 755 $@
+
+
+
+BMPPOBJ= bmeps3.o
+
+BMPPLIBF=@BMPPLIBF@
+BMPPLIBS=@BMPPLIBS@
+
+bmpp: # Program: Bitmap to PS/PDF converter (CLI)
+bmpp$(EXEEXT): $(BMPPLIBF) $(BMPPOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ $(BMPPOBJ) $(BMPPLIBS)
+ chmod 755 $@
+
+
+
+FIG2LATOBJ= fig2lat.o f2lopt.o f2lud.o f2ludpat.o f2lpgf.o f2lpdf.o \
+ f2leps.o f2lsvg.o f2lsvgst.o f2lto.o f2lpara.o
+
+FIG2LATLIBF=@FIG2LATLIBF@
+FIG2LATLIBS=@FIG2LATLIBS@
+
+fig2lat: # Program: Fig to LaTeX converter
+fig2lat$(EXEEXT): $(FIG2LATLIBF) $(FIG2LATOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ $(FIG2LATOBJ) $(FIG2LATLIBS)
+ chmod 755 $@
+
+
+
+HTMLBOOKOBJ= htmlbook.o hbnode.o hbconf.o hbhtml.o hbtool.o hbindex.o \
+ hbcont.o hbimgdim.o hbchm.o
+
+HTMLBOOKLIBF=@HTMLBOOKLIBF@
+HTMLBOOKLIBS=@HTMLBOOKLIBS@
+
+htmlbook: # Program: HTML book creator
+htmlbook$(EXEEXT): $(HTMLBOOKLIBF) $(HTMLBOOKOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ $(HTMLBOOKOBJ) $(HTMLBOOKLIBS)
+ chmod 755 $@
+
+
+
+DK3INFOLIBF=@DK3INFOLIBF@
+DK3INFOLIBS=@DK3INFOLIBS@
+
+dk3info: # Program: Information about this installation
+dk3info$(EXEEXT): $(DK3INFOLIBF) dk3info.o
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dk3info.o $(DK3INFOLIBS)
+ chmod 755 $@
+
+
+
+PLPDFTEXLIBF=@PLPDFTEXLIBF@
+PLPDFTEXLIBS=@PLPDFTEXLIBS@
+
+plpdftex: # Program: Plot driver for octpgfpl package
+plpdftex$(EXEEXT): $(PLPDFTEXLIBF) plpdftex.o plptcol.o
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ plpdftex.o plptcol.o $(PLPDFTEXLIBS)
+ chmod 755 $@
+
+
+
+DKWXWIZLIBF=@DKWXWIZLIBF@
+DKWXWIZLIBS=@DKWXWIZLIBS@
+
+dkwxwiz: # Program: Create dktools/wxwidgets based projects
+dkwxwiz$(EXEEXT): $(DKWXWIZLIBF) dkwxwiz.o
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ dkwxwiz.o $(DKWXWIZLIBS)
+ chmod 755 $@
+
+
+
+# Some special modules for GUI programs
+
+dkct-str-gui.cpp: dkct-str.c
+ -[ ! -f $@ ] || rm -f $@
+ cat dk3usewx.c dkct-str.c > $@
+
+dkct-tr-gui.cpp: dkct-tr.c
+ -[ ! -f $@ ] || rm -f $@
+ cat dk3usewx.c dkct-tr.c > $@
+
+dkct-au-gui.cpp: dkct-au.c
+ -[ ! -f $@ ] || rm -f $@
+ cat dk3usewx.c dkct-au.c > $@
+
+dkct-gui-gui.cpp: dkct-gui.c
+ -[ ! -f $@ ] || rm -f $@
+ cat dk3usewx.c dkct-gui.c > $@
+
+dkct-to-gui.cpp: dkct-to.c
+ -[ ! -f $@ ] || rm -f $@
+ cat dk3usewx.c dkct-to.c > $@
+
+dk3bm-gui.cpp: dk3bm.c
+ -[ ! -f $@ ] || rm -f $@
+ cat dk3usewx.c dk3bm.c > $@
+
+dk3bmj-gui.cpp: dk3bmj.c
+ -[ ! -f $@ ] || rm -f $@
+ cat dk3usewx.c dk3bmj.c > $@
+
+dk3pdf-gui.cpp: dk3pdf.c
+ -[ ! -f $@ ] || rm -f $@
+ cat dk3usewx.c dk3pdf.c > $@
+
+dk3bifa-gui.cpp: dk3bifa.c
+ -[ ! -f $@ ] || rm -f $@
+ cat dk3usewx.c dk3bifa.c > $@
+
+dk3bif-gui.cpp: dk3bif.c
+ -[ ! -f $@ ] || rm -f $@
+ cat dk3usewx.c dk3bif.c > $@
+
+
+
+DKWXTRACEOBJ= DkWxTraceApp.o DkWxTraceFrame.o DkWxTraceThread.o \
+ DkWxTraceOptionsDialog.o \
+ dkct-str-gui.o dkct-tr-gui.o dkct-au-gui.o dkct-gui-gui.o dkct-to-gui.o
+
+WXDKCTLIBF=@WXDKCTLIBF@
+WXDKCTLIBS=@WXDKCTLIBS@
+
+wxdkct: # Program: Dirk Krause's C tool (GUI)
+wxdkct$(EXEEXT): $(WXDKCTLIBF) $(DKWXTRACEOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C++) ' $@
+ $(LDCPP) $(ENTRY) -o $@ $(DKWXTRACEOBJ) $(WXDKCTLIBS)
+ chmod 755 $@
+
+
+
+WXBMPPOBJ= DkWxBmepsApp.o DkWxBmepsFrame.o DkWxBmepsThread.o \
+ DkWxBmepsOptionsDialog.o \
+ dk3bm-gui.o dk3bmj-gui.o dk3bmeo.o dk3bmeps.o dk3pdf-gui.o dk3paper.o \
+ dk3bifa-gui.o dk3bif-gui.o dk3pixre.o
+
+WXBMPP2OBJ= \
+ DkWxProgressDialog.o DkWxFrame.o DkWxAppHelper.o DkWxHelpController.o \
+ DkWxCommunicator.o DkWxColorView.o dk3wxs.o dk3opt.o dk3app.o \
+ dk3wreg.o dk3of.o dk3strm.o dk3sto.o dk3dir.o dk3enc.o dk3str.o \
+ dk3sf.o dk3maui.o dk3mal.o dk3maul.o dk3mad.o dk3madlc.o \
+ dk3maidd.o dk3maodd.o dk3maid8.o dk3maod8.o dk3madfo.o dk3madso.o \
+ dk3madsi.o dk3inst.o dk3srch.o dk3bits.o dk3mem.o dk3trace.o
+
+WXBMPPLIBF=@WXBMPPLIBF@
+WXBMPPLIBS=@WXBMPPLIBS@
+
+wxbmpp: # Program: Bitmap to PS/PDF converter (GUI)
+wxbmpp$(EXEEXT): $(WXBMPPLIBF) $(WXBMPPOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C++) ' $@
+ $(LDCPP) $(ENTRY) -o $@ $(WXBMPPOBJ) $(WXBMPPLIBS)
+ chmod 755 $@
+
+
+
+WXDKFCSOBJ= Dk4FcsApp.o Dk4FcsFrame.o
+
+WXDKFCSLIBF=@WXDKFCSLIBF@
+WXDKFCSLIBS=@WXDKFCSLIBS@
+
+wxdkfcs: # Program: File checksums with GUI
+wxdkfcs$(EXEEXT): $(WXDKFCSLIBF) $(WXDKFCSOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C++) ' $@
+ $(LDCPP) $(ENTRY) -o $@ $(WXDKFCSOBJ) $(WXDKFCSLIBS)
+ chmod 755 $@
+
+
+
+WXIMGSZOBJ= DkWxImgszApp.o DkWxImgszFrame.o DkWxImgszOptionsDialog.o
+
+WXIMGSZLIBF=@WXIMGSZLIBF@
+WXIMGSZLIBS=@WXIMGSZLIBS@
+
+wximgsz: # Program: Image scale suggestions
+wximgsz$(EXEEXT): $(WXIMGSZLIBF) $(WXIMGSZOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C++) ' $@
+ $(LDCPP) $(ENTRY) -o $@ $(WXIMGSZOBJ) $(WXIMGSZLIBS)
+ chmod 755 $@
+
+
+
+WXDKCLOCKOBJ= DkClockApp.o DkClockFrame.o DkClockOptionsDialog.o \
+ DkClockView.o DkClockData.o DkClockTaskbarIcon.o
+
+WXDKCLOCKLIBF=@WXDKCLOCKLIBF@
+WXDKCLOCKLIBS=@WXDKCLOCKLIBS@
+
+wxdkclock: # Program: Screen clock with alert
+wxdkclock$(EXEEXT): $(WXDKCLOCKLIBF) $(WXDKCLOCKOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C++) ' $@
+ $(LDCPP) $(ENTRY) -o $@ $(WXDKCLOCKOBJ) $(WXDKCLOCKLIBS)
+ chmod 755 $@
+
+
+
+WXDKHTBOBJ= DkWxHtbApp.o DkWxHtbFrame.o
+
+WXDKHTBLIBF=@WXDKHTBLIBF@
+WXDKHTBLIBS=@WXDKHTBLIBS@
+
+wxdkhtb: # Program: Viewer for htb help files
+wxdkhtb$(EXEEXT): $(WXDKHTBLIBF) $(WXDKHTBOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C++) ' $@
+ $(LDCPP) $(ENTRY) -o $@ $(WXDKHTBOBJ) $(WXDKHTBLIBS)
+ chmod 755 $@
+
+
+
+ITADMINOBJ= itadmin.o itaconf.o itadata.o itamysql.o itareg.o itamem.o \
+ itacomp.o itange.o itahosts.o itaether.o itadhcp.o itanetd.o italic.o \
+ itatool.o dk3uc2l.o
+
+ITADMINLIBF=@ITADMINLIBF@
+ITADMINLIBS=@ITADMINLIBS@
+
+itadmin: # Program: IT administration tool
+itadmin$(EXEEXT): $(ITADMINLIBF) $(ITADMINOBJ)
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C++) ' $@
+ $(LDCPP) $(MYSQLLDFLAGS) -o $@ $(ITADMINOBJ) $(ITADMINLIBS)
+ chmod 755 $@
+
+
+# ##### End of dktols-3 section
+
+
+tests: testprogs
+ ./test-dk4maac < test-data/dk4maac.in > test-data/dk4maac.out
+ ./test-dk4maauc < test-data/dk4maauc.in > test-data/dk4maauc.out
+
+testprogs: $(TESTPROGS)
+ @echo 'Finished building test programs.'
+
+test-dk4maac: test-dk4maac.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L.-o $@ test-dk4maac.o -ldk4
+ chmod 755 $@
+
+test-dk4maauc: test-dk4maauc.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4maauc.o -ldk4
+ chmod 755 $@
+
+test-dk4maas: test-dk4maas.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4maas.o -ldk4
+ chmod 755 $@
+
+test-dk4maaus: test-dk4maaus.o
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4maaus.o -ldk4
+ chmod 755 $@
+
+test-dk4maai: test-dk4maai.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4maai.o -ldk4
+ chmod 755 $@
+
+test-dk4maaui: test-dk4maaui.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4maaui.o -ldk4
+ chmod 755 $@
+
+test-dk4maal: test-dk4maal.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4maal.o -ldk4
+ chmod 755 $@
+
+test-dk4maaul: test-dk4maaul.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4maaul.o -ldk4
+ chmod 755 $@
+
+test-dk4maall: test-dk4maall.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4maall.o -ldk4
+ chmod 755 $@
+
+test-dk4maaull: test-dk4maaull.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4maaull.o -ldk4
+ chmod 755 $@
+
+test-dk4maami: test-dk4maami.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4maami.o -ldk4
+ chmod 755 $@
+
+test-dk4maamu: test-dk4maamu.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4maamu.o -ldk4
+ chmod 755 $@
+
+test-dk4str8: test-dk4str8.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4str8.o -ldk4
+ chmod 755 $@
+
+test-dk4loc: test-dk4loc.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4loc.o -ldk4
+ chmod 755 $@
+
+test-dk4mai8ddu: test-dk4mai8ddu.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4mai8ddu.o -ldk4
+ chmod 755 $@
+
+test-dk4mai8ddi: test-dk4mai8ddi.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4mai8ddi.o -ldk4
+ chmod 755 $@
+
+test-dk4mai8dsz: test-dk4mai8dsz.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4mai8dsz.o -ldk4
+ chmod 755 $@
+
+test-dk4time: test-dk4time.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4time.o -ldk4
+ chmod 755 $@
+
+test-dk4exep8: test-dk4exep8.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4exep8.o -ldk4
+ chmod 755 $@
+
+test-dk4path8: test-dk4path8.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4path8.o -ldk4
+ chmod 755 $@
+
+ex-sto: ex-sto.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ ex-sto.o -ldk4
+ chmod 755 $@
+
+test-dk4strm: test-dk4strm.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4strm.o -ldk4
+ chmod 755 $@
+
+test-dk4numl: test-dk4numl.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4numl.o -ldk4
+ chmod 755 $@
+
+test-dk4tsp08: test-dk4tsp08.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4tsp08.o -ldk4
+ chmod 755 $@
+
+test-bool: test-bool.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-bool.o -ldk4
+ chmod 755 $@
+
+test-dk4enc: test-dk4enc.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4enc.o -ldk4
+ chmod 755 $@
+
+test-dk4user: test-dk4user.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4user.o -ldk4
+ chmod 755 $@
+
+test-dk4mai8dbl: test-dk4mai8dbl.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4mai8dbl.o -ldk4
+ chmod 755 $@
+
+test-fne: test-fne.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-fne.o -ldk4
+ chmod 755 $@
+
+test-mkdir: test-mkdir.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-mkdir.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-deldir: test-deldir.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-deldir.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-dk4dir08: test-dk4dir08.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4dir08.o -ldk4
+ chmod 755 $@
+
+test-dk4dir: test-dk4dir.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4dir.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-deltree: test-deltree.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-deltree.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-filei: test-filei.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-filei.o -ldk4
+ chmod 755 $@
+
+test-dk4time08: test-dk4time08.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4time08.o -ldk4
+ chmod 755 $@
+
+test-eradisk: test-eradisk.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-eradisk.o -ldk4
+ chmod 755 $@
+
+test-a85e: test-a85e.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-a85e.o -ldk4
+ chmod 755 $@
+
+test-a85d: test-a85d.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-a85d.o -ldk4
+ chmod 755 $@
+
+test-rle: test-rle.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-rle.o -ldk4
+ chmod 755 $@
+
+test-rld: test-rld.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-rld.o -ldk4
+ chmod 755 $@
+
+test-binenc: test-binenc.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-binenc.o -ldk4
+ chmod 755 $@
+
+test-sock: test-sock.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-sock.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-inet-pton: test-inet-pton.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-inet-pton.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-peer: test-peer.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-peer.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-membuf: test-membuf.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-membuf.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-dk4wxah: test-dk4wxah.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4wxah.o -ldk4 $(WXLDFLAGS) $(IMGLIBS) $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+TESTCONTAINEROBJ= test-container.o Dk4Comparable.o
+
+test-container: $(TESTCONTAINEROBJ) libdk4.a
+ $(LDCPP) -o $@ $(TESTCONTAINEROBJ) libdk4.a $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-skip: test-skip.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-skip.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-opt: test-opt.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-opt.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-udpa: test-udpa.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-udpa.o -ldk4 $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-sqdbl: test-sqdbl.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-sqdbl.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-ser: test-ser.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-ser.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-unser: test-unser.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-unser.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-strmw: test-strmw.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-strmw.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-strms: test-strms.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-strms.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-strmu: test-strmu.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-strmu.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-mbstr: test-mbstr.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-mbstr.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-dk4strmco: test-dk4strmco.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4strmco.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-paper: test-paper.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-paper.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+testlzw: testlzw.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ testlzw.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+testlzws: testlzws.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ testlzws.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+test-dk4c8dbl: test-dk4c8dbl.o libdk4.a
+ $(LD) $(CFLAGS) $(LDFLAGS) -L. -o $@ test-dk4c8dbl.o -ldk4 $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
+distclean: # Clean up (remove build and configure script results)
+distclean: clean
+ -[ ! -f confdefs.h ] || rm -fr confdefs.h
+ -[ ! -f config.h ] || rm -fr config.h
+ -[ ! -f config.log ] || rm -fr config.log
+ -[ ! -f config.status ] || rm -fr config.status
+ -[ ! -f conftest ] || rm -fr conftest
+ -[ ! -f conftest.c ] || rm -fr conftest.c
+ -[ ! -f conftest.er1 ] || rm -fr conftest.er1
+ -[ ! -f config.h ] || rm -f config.h
+ -[ ! -f scripts/wr-dk3inst.sh ] || rm -f scripts/wr-dk3inst.sh
+ -[ ! -f scripts/wr-dk4inst.sh ] || rm -f scripts/wr-dk4inst.sh
+ -[ ! -f scripts/create-desktop-files.sh ] || rm -f scripts/create-desktop-files.sh
+ -[ ! -f initd-printqd ] || rm -f initd-printqd
+ -[ ! -f dktools.pc ] || rm -f dktools.pc
+
+maketest: # Test: Check availability of make programs.
+maketest:
+ @echo OK
+
+cleanest: # NOT FOR END USER: Clean up completely
+cleanest: distclean
+ -[ ! -d autom4te.cache ] || rm -fr autom4te.cache
+ scripts/clean-resources.sh
+ find help-htb -type f -exec rm -f {} \;
+ find help-chm -type f -exec rm -f {} \;
+ find help-html -type f -exec rm -f {} \;
+ find doc/html -type f -exec rm -f {} \;
+ -[ ! -d doc/doxygen ] || find doc/doxygen -type f -exec rm -f {} \;
+ -[ ! -f dk4info1.c ] || rm -f dk4info1.c
+ -find help-src -name '*.html' -exec rm -f {} \;
+ -find help-src -name '*.hhc' -exec rm -f {} \;
+ -find help-src -name '*.hhk' -exec rm -f {} \;
+ -find help-src -name '*.hhp' -exec rm -f {} \;
+ -find help-src -name '*.aux' -exec rm -f {} \;
+ -find doc/src -name '*.html' -exec rm -f {} \;
+ -find doc/src -name '*.hhc' -exec rm -f {} \;
+ -find doc/src -name '*.hhk' -exec rm -f {} \;
+ -find doc/src -name '*.hhp' -exec rm -f {} \;
+ -find doc/src -name '*.aux' -exec rm -f {} \;
+ -find dktools -name '*.chm' -exec rm {} \;
+ -find dktools -name '*.htb' -exec rm {} \;
+ -find . -name '*.ico' -exec rm -f {} \;
+ -find . -name '*.xpm' -exec rm -f {} \;
+ -[ ! -x ./scripts/clean.sh ] || ./scripts/clean.sh
+ -[ ! -x ./scripts/clean-for-fig.sh ] || ./scripts/clean-for-fig.sh
+ -[ ! -x ./scripts/clean-for-tex.sh ] || ./scripts/clean-for-tex.sh
+ -rm -fr *.rc
+ -rm -fr *-gui.cpp
+
+
+check-cleanest: # NOT FOR END USER: Check for unlisted files
+check-cleanest: cleanest
+ perl scripts/filechk.pl
+
+
+distrenew: # NOT FOR END USER: Renew files before creating distro
+distrenew: check-cleanest
+ dkct -l
+ find . -type f -exec touch {} \;
+ sleep 2
+ find . -name '*.pdf' -exec touch {} \;
+ sleep 2
+ find . -name '*.svg' -exec touch {} \;
+ sleep 2
+ find . -name '*.png' -exec touch {} \;
+ find . -name '*.ico' -exec touch {} \;
+ find . -name '*.xpm' -exec touch {} \;
+ scripts/update-doxyfile.sh
+ doxygen
+ scripts/mkrc.pl
+ scripts/make-resources.sh
+ scripts/build-help.sh
+ scripts/doc-install.sh
+ scripts/man-install.sh
+ scripts/transform-config.pl
+ autoconf
+ scripts/create-spec-iss.sh
+ scripts/create-debian-changelog.pl > debian/changelog
+
+dist: # NOT FOR END USER: Create distro archives
+dist: distrenew
+ scripts/create-distribution.sh
+
+doxydoc: # NOT FOR END USER: Documentation created by doxygen
+ -[ ! -d doc/doxygen ] || rm -fr doc/doxygen
+ -[ ! -f doxygen.out ] || rm -fr doxygen.out
+ mkdir doc/doxygen
+ chmod 755 doc/doxygen
+ doxygen Doxyfile > doxygen.out 2>&1
+
+wprclean2: # Temporary: Base for the wprclean rewrite
+wprclean2$(EXEEXT): wprclean2.o @LPRNGCLLIBF@
+ -[ ! -f $@ ] || rm -f $@
+ @echo '### Link (C) ' $@
+ $(LINK) -o $@ wprclean2.o @LPRNGCLLIBS@ $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) -lm
+ chmod 755 $@
+
diff --git a/support/dktools/README b/support/dktools/README
new file mode 100644
index 0000000000..f2dac11b16
--- /dev/null
+++ b/support/dktools/README
@@ -0,0 +1,105 @@
+DK Tools and Libaries
+=====================
+This package contains Dirk Krause's tools and libraries.
+SourceForge project page: http://sourceforge.net/projects/dktools
+Project home page: http://dktools.sourceforge.net
+
+License
+=======
+The software is licensed to you under the terms of a BSD style license,
+see bsdlic.txt.
+
+The live systems produced by the debian-jessie-build-live.sh
+script are licensed under the same license conditions as Debian GNU/Linux
+itself (the live systems are derived from Debian).
+
+Installation
+============
+See the INSTALL file for installation instructions.
+
+Programs
+========
+
+Graphics conversion
+-------------------
+bmpp Convert PNG, JPEG, TIFF to PDF, PS, EPS
+fig2lat Convrt *.fig to PS(+TeX), PDF(+TeX), PGF
+wximgsz Suggest size pairs to rescale bitmap images
+
+Web publishing
+--------------
+htmlbook Publish HTML like a book
+
+Software development
+--------------------
+dkct C preprocessor for debugging, tracing, state machines wx GUI
+dkwxwiz Create initial files for wxWidgets + DK tools programs
+wxdkhtb View HTB help files
+
+IT administration
+-----------------
+itadmin Create configuration and docu (*.tex) files from MySQL DB
+
+File and directory tols
+-----------------------
+dk-ls List files, output column order is configurable
+dk-fic Check file integrity
+dk-bmm Backup media managements
+dk-blks Create stream with constant block size for use with dd
+dk-eradisk Create data stream to erase a disk
+dk-hex Show file contents in hexadecimal or octal notation
+dk-pwd Clone of the pwd program, intended for Windows
+
+Text tools
+----------
+dk-t2l Convert plain text to LaTeX
+dk-t2h Convert plain text to HTML
+dk-cat Show file contents, some recoding possible
+dk-sort Sort text line by line
+
+
+
+User and password tools
+-----------------------
+dk-uid Find free user ID in a given range
+dk-pwgen Create passwords, PIN number or hexadecimal keys
+dk-rand Create binary random data
+
+Network tools
+-------------
+dk-send Send data stream to one or multiple recipients running dk-recv
+dk-recv Receive data stream from a dk-send process
+rshdown Fast remote shutdown via specific UDP packet
+
+Windows tools
+-------------
+dkwt / dkwtadm List users, groups, printers; keep classroom PCs clean
+winprint Schedule file to Windows print queue
+ChangeScreenSize Switch between different screen sizes
+wprclean Remove a users print jobs from local Windows print queues
+lprngcl Remove a users print jobs from LPRng print queues
+
+Printer administration
+----------------------
+prmonsnmp Monitor a printer using the SNMP protocol
+pjsnmp LPRng filter to send print job to networked printer
+printqd Daemon to enforce print quota on LPRng print systems
+printqdc Client program to query printqd
+wxpqdic GUI client program to query printqd, show users print limit
+addctrld Ensure final CTRL-d at end of data stream
+
+Simple databases tools
+----------------------
+dk-t2db Create simple text data base from plain text
+dk-db2t Convert simple text data base to text
+dk-dbco Copy simple databases
+
+Database tools
+--------------
+dk-sqlsplit Split overlong SQL lines as produced by mysqldump
+
+Other programs
+--------------
+plpdftex Output driver for octpgfpl to produce PDF+TeX
+wxdkclock Simple clock with one alert
+
diff --git a/support/dktools/ScreenSizeApp.cpp b/support/dktools/ScreenSizeApp.cpp
new file mode 100644
index 0000000000..8857b324a1
--- /dev/null
+++ b/support/dktools/ScreenSizeApp.cpp
@@ -0,0 +1,409 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: ScreenSizeApp.cpt
+*/
+
+/*
+Copyright (C) 2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file ScreenSizeApp.cpp The ScreenSizeApp module.
+*/
+
+
+#line 67 "ScreenSizeApp.cpt"
+
+#include "wxdkscrsz.h"
+
+
+
+
+
+#line 73 "ScreenSizeApp.cpt"
+
+
+
+/** Localized wxChar texts.
+*/
+static wxChar const * wxdkscrsz_texts[] = {
+/* 0 */
+wxT("File"),
+
+/* 1 */
+wxT("Quit"),
+
+/* 2 */
+wxT("Exit the application"),
+
+/* 3 */
+wxT("Help"),
+
+/* 4 */
+wxT("About"),
+
+/* 5 */
+wxT("Show version information"),
+
+/* 6 */
+wxT("Contents"),
+
+/* 7 */
+wxT("Open table of contents"),
+
+/* 8 */
+wxT("Ready"),
+
+/* 9 */
+wxT("Copyright (c) "),
+
+/* 10 */
+wxT("About "),
+
+/* 11 */
+wxT("This program uses the following libraries:"),
+
+/* 12 */
+wxT("See:"),
+
+/* 13 */
+wxT("Screen size change:"),
+
+/* 14 */
+wxT("Not yet started"),
+
+/* 15 */
+wxT("Started"),
+
+/* 16 */
+wxT("OK"),
+
+/* 17 */
+wxT("Failed"),
+
+/* 18 */
+wxT("Error"),
+
+/* 19 */
+wxT("Failed to retrieve current screen settings!"),
+
+/* 20 */
+wxT("Failed to change screen size!"),
+
+/* 21 */
+wxT("Only available on Windows platforms!"),
+
+/* 22 */
+wxT("Not an unsigned integer: \""),
+
+/* 23 */
+wxT("\"!"),
+
+/* 24 */
+wxT("Missing command line arguments: width, height."),
+
+/* 25 */
+wxT("Old screen size"),
+
+/* 26 */
+wxT("Width:"),
+
+/* 27 */
+wxT("Height:"),
+
+/* 28 */
+wxT(""),
+
+/* 29 */
+wxT("New screen size"),
+
+/* 30 */
+wxT("Result"),
+
+NULL
+
+
+#line 201 "ScreenSizeApp.cpt"
+};
+
+
+
+/** Non-localized wxChar texts.
+*/
+static wxChar const * wxdkscrsz_nl_wx[] = {
+/* 0 */
+wxT("wxdkscrsz"),
+
+/* 1 */
+wxT("1.0.0"),
+
+/* 2 */
+wxT("Dirk Krause"),
+
+/* 3 */
+wxT("DKrause"),
+
+/* 4 */
+wxT("aaaaa"),
+
+/* 5 */
+wxT(""),
+
+/* 6 */
+wxT(""),
+
+/* 7 */
+wxT(" "),
+
+/* 8 */
+wxT("\n"),
+
+/* 9 */
+wxT("DK tools, wxWidgets, libpng, libjpeg, libtiff, zlib."),
+
+/* 10 */
+wxT("http://dktools.sourceforge.net"),
+
+/* 11 */
+wxT("http://www.wxwidgets.org"),
+
+/* 12 */
+wxT("http://www.libpng.org/pub/png/libpng.html"),
+
+/* 13 */
+wxT("http://www.ijg.org"),
+
+/* 14 */
+wxT("http://www.remotesensing.org/libtiff"),
+
+/* 15 */
+wxT("http://www.zlib.net"),
+
+/* 16 */
+wxT("Error"),
+
+/* 17 */
+wxT("Not enough memory (RAM)!"),
+
+NULL
+
+
+#line 261 "ScreenSizeApp.cpt"
+};
+
+
+
+/** Non-localized dkChar texts.
+*/
+static dkChar const * wxdkscrsz_nl_dk[] = {
+/* 0 */
+dkT("dktools"),
+
+/* 1 */
+dkT("wxdkscrsz.str"),
+
+/* 2 */
+dkT("wxdkscrsz.chm"),
+
+/* 3 */
+dkT("wxdkscrsz.htb"),
+
+NULL
+
+
+#line 286 "ScreenSizeApp.cpt"
+};
+
+
+
+/** Implementation of the wxApp functionality.
+*/
+IMPLEMENT_APP(ScreenSizeApp)
+
+
+bool
+ScreenSizeApp::OnInit()
+{
+ ScreenSizeFrame *frame = NULL;
+ wxChar const * const *localizedTexts = NULL;
+ wxPNGHandler *phPng = NULL;
+ wxXPMHandler *phXpm = NULL;
+ wxICOHandler *phIco = NULL;
+ wxArchiveFSHandler *phArchiveFS = NULL;
+ bool back = false;
+
+ /* Initialize members.
+ */
+ pAh = NULL;
+ pHc = NULL;
+
+ /* __CHANGE__ 009: Initialize further members here.
+ */
+
+ /* Set up helper object.
+ */
+ pAh = new Dk4WxApplicationHelper();
+ if (NULL == pAh) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ if (!(pAh->Initialize(argv[0], wxdkscrsz_nl_wx[3], wxdkscrsz_nl_dk[0]))) {
+ goto finished;
+ }
+
+ /* Add image and file system handlers for online help.
+ */
+ phPng = new wxPNGHandler();
+ if (NULL != phPng) {
+ wxImage::AddHandler(phPng);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phXpm = new wxXPMHandler();
+ if (NULL != phXpm) {
+ wxImage::AddHandler(phXpm);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phIco = new wxICOHandler();
+ if (NULL != phIco) {
+ wxImage::AddHandler(phIco);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phArchiveFS = new wxArchiveFSHandler();
+ if (NULL != phArchiveFS) {
+ wxFileSystem::AddHandler(phArchiveFS);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ /* Set up help controller.
+ */
+ pHc = new Dk4WxHelpController();
+ if (NULL == pHc) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ if (!(pHc->Initialize(pAh, wxdkscrsz_nl_dk[2], wxdkscrsz_nl_dk[3]))) {
+ goto finished;
+ }
+
+ /* Attempt to obtain localized texts in users preferred language.
+ */
+ localizedTexts = pAh->GetStringTable(wxdkscrsz_nl_dk[1], wxdkscrsz_texts);
+ if(!(localizedTexts)) { localizedTexts = wxdkscrsz_texts; }
+
+ /* Create and show frame.
+ */
+ frame = new ScreenSizeFrame(
+ ScreenSizeFrame_MainWindow,
+ pAh,
+ pHc,
+ argc,
+ argv,
+ localizedTexts,
+ wxdkscrsz_nl_wx,
+ wxdkscrsz_nl_dk
+ );
+ if(!(frame)) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ /* Show frame, restore position and indicate success.
+ */
+ frame->Show();
+ frame->RestorePosition();
+ back = true;
+
+ /* Release resources if initialization failed.
+ */
+ finished:
+ if(!(back)) {
+ if (NULL != pHc) {
+ pHc->Cleanup(); delete(pHc); pHc = NULL;
+ }
+ if (NULL != pAh) {
+ pAh->Cleanup(); delete(pAh); pAh = NULL;
+ }
+ }
+ return back;
+}
+
+
+
+int
+ScreenSizeApp::OnExit()
+{
+ int back = 0;
+
+ /* __CHANGE__ 009: Release resources allocated by further members.
+ */
+
+ /* Release resources.
+ */
+ if (NULL != pHc) {
+ pHc->Cleanup(); delete(pHc); pHc = NULL;
+ }
+ if (NULL != pAh) {
+ pAh->Cleanup(); delete(pAh); pAh = NULL;
+ }
+
+ /* Set exit status code.
+ */
+ return back;
+}
+
+
+
+void
+ScreenSizeApp::ShowMemoryErrorMessage(void)
+{
+ const wxChar *s_title = NULL;
+ const wxChar *s_text = NULL;
+
+ if (NULL != pAh) {
+ s_title = pAh->GetBasicString(6);
+ s_text = pAh->GetBasicString(7);
+ }
+ if (NULL == s_title) {
+ s_title = wxdkscrsz_nl_wx[16];
+ }
+ if (NULL == s_text) {
+ s_text = wxdkscrsz_nl_wx[17];
+ }
+ wxMessageBox(s_text, s_title, (wxOK | wxCENTRE | wxICON_ERROR));
+}
+
+/* vim: set ai sw=4 ts=4 : */
+
diff --git a/support/dktools/ScreenSizeApp.cpt b/support/dktools/ScreenSizeApp.cpt
new file mode 100644
index 0000000000..7d40bf76ad
--- /dev/null
+++ b/support/dktools/ScreenSizeApp.cpt
@@ -0,0 +1,455 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2017
+license = bsd
+
+
+
+%% header
+
+/** @file ScreenSizeApp.h The ScreenSizeApp class.
+*/
+
+
+
+/** Application class, derived from wxApp, one instance per program.
+*/
+class ScreenSizeApp : public wxApp
+{
+ protected:
+
+ /** Helper object.
+ */
+ Dk4WxApplicationHelper *pAh;
+
+ /** Controller fr online help.
+ */
+ Dk4WxHelpController *pHc;
+
+ /* __CHANGE__ 009: Add further members here.
+ */
+
+ protected:
+
+ /** Show error message if there is not enough memory available.
+ */
+ void
+ ShowMemoryErrorMessage(void);
+
+ public:
+
+ /** Application initialization.
+ @return true on success, false on error.
+ */
+ virtual
+ bool
+ OnInit();
+
+ /** Application shutdown.
+ @return 0 on success, any other value indicates an error.
+ */
+ virtual
+ int
+ OnExit();
+};
+
+
+
+/** Declaration as the wxApp object.
+*/
+DECLARE_APP(ScreenSizeApp)
+
+
+
+/* vim: set ai sw=4 ts=4 : */
+%% module
+
+#include "wxdkscrsz.h"
+
+
+
+$!trace-include
+
+
+
+/** Localized wxChar texts.
+*/
+static wxChar const * wxdkscrsz_texts[] = {
+$!string-table macro=wxT
+#
+# 0: Menu "File"
+#
+File
+#
+# 1: Menu item "File/Quit"
+#
+Quit
+#
+# 2: Tool tip text for menu item "File/Exit"
+#
+Exit the application
+#
+# 3: Menu "Help"
+#
+Help
+#
+# 4: Menu item "Help/About"
+#
+About
+#
+# 5: Tooltip text for menu item "Help/About"
+#
+Show version information
+#
+# 6: Menu item "Help/Contents"
+#
+Contents
+#
+# 7: Tooltip text for menu item "Help/Contents"
+#
+Open table of contents
+#
+# 8: Initial status text
+#
+Ready
+#
+# 9: Copyright notice.
+#
+Copyright (c)
+#
+# 10: Dialog box title "About ..."
+#
+About
+#
+# 11: This program uses the following libraries
+#
+This program uses the following libraries:
+#
+# 12: See
+#
+See:
+#
+# 13: __CHANGE__ 015: Text for dummy label, can be reused if lDummy removed.
+#
+Screen size change:
+#
+# __CHANGE__ 016: Add further texts as required.
+#
+# 14
+#
+Not yet started
+#
+# 15
+#
+Started
+#
+# 16
+#
+OK
+#
+# 17
+#
+Failed
+#
+# 18
+#
+Error
+#
+# 19
+#
+Failed to retrieve current screen settings!
+#
+# 20
+#
+Failed to change screen size!
+#
+# 21
+#
+Only available on Windows platforms!
+#
+# 22 23
+#
+Not an unsigned integer: "
+"!
+#
+# 24
+#
+Missing command line arguments: width, height.
+#
+# 25
+#
+Old screen size
+#
+# 26 27
+#
+Width:
+Height:
+#
+# 28 Empty string
+#
+
+#
+# 29 New screen size
+#
+New screen size
+#
+# 30 Result
+#
+Result
+$!end
+};
+
+
+
+/** Non-localized wxChar texts.
+*/
+static wxChar const * wxdkscrsz_nl_wx[] = {
+$!string-table macro=wxT
+#
+# 0: Program name.
+#
+wxdkscrsz
+#
+# 1: Program version. __CHANGE__ 005: Correct program version.
+#
+1.0.0
+#
+# 2: Copyright owner name.
+#
+Dirk Krause
+#
+# 3: Software vendor name.
+#
+DKrause
+#
+# 4: Resource name of Windows icon
+#
+aaaaa
+#
+# 5: UNUSED (previously Windows chm help file name)
+#
+
+#
+# 6: UNUSED (previously non-Windows htb help file name)
+#
+
+#
+# 7: Space
+#
+
+#
+# 8: Newline
+#
+\n
+#
+# 9 10 11 12 13 14 15: List of libraries used.
+#
+DK tools, wxWidgets, libpng, libjpeg, libtiff, zlib.
+http://dktools.sourceforge.net
+http://www.wxwidgets.org
+http://www.libpng.org/pub/png/libpng.html
+http://www.ijg.org
+http://www.remotesensing.org/libtiff
+http://www.zlib.net
+#
+# 16 17
+#
+Error
+Not enough memory (RAM)!
+$!end
+};
+
+
+
+/** Non-localized dkChar texts.
+*/
+static dkChar const * wxdkscrsz_nl_dk[] = {
+$!string-table macro=dkT
+#
+# 0: Program group name.
+#
+dktools
+#
+# 1: String table name.
+#
+wxdkscrsz.str
+#
+# 2: CHM help file name
+#
+wxdkscrsz.chm
+#
+# 3: HTB help file name
+#
+wxdkscrsz.htb
+$!end
+};
+
+
+
+/** Implementation of the wxApp functionality.
+*/
+IMPLEMENT_APP(ScreenSizeApp)
+
+
+bool
+ScreenSizeApp::OnInit()
+{
+ ScreenSizeFrame *frame = NULL;
+ wxChar const * const *localizedTexts = NULL;
+ wxPNGHandler *phPng = NULL;
+ wxXPMHandler *phXpm = NULL;
+ wxICOHandler *phIco = NULL;
+ wxArchiveFSHandler *phArchiveFS = NULL;
+ bool back = false;
+
+ /* Initialize members.
+ */
+ pAh = NULL;
+ pHc = NULL;
+
+ /* __CHANGE__ 009: Initialize further members here.
+ */
+
+ /* Set up helper object.
+ */
+ pAh = new Dk4WxApplicationHelper();
+ if (NULL == pAh) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ if (!(pAh->Initialize(argv[0], wxdkscrsz_nl_wx[3], wxdkscrsz_nl_dk[0]))) {
+ goto finished;
+ }
+
+ /* Add image and file system handlers for online help.
+ */
+ phPng = new wxPNGHandler();
+ if (NULL != phPng) {
+ wxImage::AddHandler(phPng);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phXpm = new wxXPMHandler();
+ if (NULL != phXpm) {
+ wxImage::AddHandler(phXpm);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phIco = new wxICOHandler();
+ if (NULL != phIco) {
+ wxImage::AddHandler(phIco);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phArchiveFS = new wxArchiveFSHandler();
+ if (NULL != phArchiveFS) {
+ wxFileSystem::AddHandler(phArchiveFS);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ /* Set up help controller.
+ */
+ pHc = new Dk4WxHelpController();
+ if (NULL == pHc) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ if (!(pHc->Initialize(pAh, wxdkscrsz_nl_dk[2], wxdkscrsz_nl_dk[3]))) {
+ goto finished;
+ }
+
+ /* Attempt to obtain localized texts in users preferred language.
+ */
+ localizedTexts = pAh->GetStringTable(wxdkscrsz_nl_dk[1], wxdkscrsz_texts);
+ if(!(localizedTexts)) { localizedTexts = wxdkscrsz_texts; }
+
+ /* Create and show frame.
+ */
+ frame = new ScreenSizeFrame(
+ ScreenSizeFrame_MainWindow,
+ pAh,
+ pHc,
+ argc,
+ argv,
+ localizedTexts,
+ wxdkscrsz_nl_wx,
+ wxdkscrsz_nl_dk
+ );
+ if(!(frame)) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ /* Show frame, restore position and indicate success.
+ */
+ frame->Show();
+ frame->RestorePosition();
+ back = true;
+
+ /* Release resources if initialization failed.
+ */
+ finished:
+ if(!(back)) {
+ if (NULL != pHc) {
+ pHc->Cleanup(); delete(pHc); pHc = NULL;
+ }
+ if (NULL != pAh) {
+ pAh->Cleanup(); delete(pAh); pAh = NULL;
+ }
+ }
+ return back;
+}
+
+
+
+int
+ScreenSizeApp::OnExit()
+{
+ int back = 0;
+
+ /* __CHANGE__ 009: Release resources allocated by further members.
+ */
+
+ /* Release resources.
+ */
+ if (NULL != pHc) {
+ pHc->Cleanup(); delete(pHc); pHc = NULL;
+ }
+ if (NULL != pAh) {
+ pAh->Cleanup(); delete(pAh); pAh = NULL;
+ }
+
+ /* Set exit status code.
+ */
+ return back;
+}
+
+
+
+void
+ScreenSizeApp::ShowMemoryErrorMessage(void)
+{
+ const wxChar *s_title = NULL;
+ const wxChar *s_text = NULL;
+
+ if (NULL != pAh) {
+ s_title = pAh->GetBasicString(6);
+ s_text = pAh->GetBasicString(7);
+ }
+ if (NULL == s_title) {
+ s_title = wxdkscrsz_nl_wx[16];
+ }
+ if (NULL == s_text) {
+ s_text = wxdkscrsz_nl_wx[17];
+ }
+ wxMessageBox(s_text, s_title, (wxOK | wxCENTRE | wxICON_ERROR));
+}
+
+/* vim: set ai sw=4 ts=4 : */
+
diff --git a/support/dktools/ScreenSizeApp.h b/support/dktools/ScreenSizeApp.h
new file mode 100644
index 0000000000..ae6cfea802
--- /dev/null
+++ b/support/dktools/ScreenSizeApp.h
@@ -0,0 +1,99 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: ScreenSizeApp.cpt
+*/
+
+/*
+Copyright (C) 2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef SCREENSIZEAPP_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define SCREENSIZEAPP_H_INCLUDED 1
+
+
+#line 10 "ScreenSizeApp.cpt"
+
+/** @file ScreenSizeApp.h The ScreenSizeApp class.
+*/
+
+
+
+/** Application class, derived from wxApp, one instance per program.
+*/
+class ScreenSizeApp : public wxApp
+{
+ protected:
+
+ /** Helper object.
+ */
+ Dk4WxApplicationHelper *pAh;
+
+ /** Controller fr online help.
+ */
+ Dk4WxHelpController *pHc;
+
+ /* __CHANGE__ 009: Add further members here.
+ */
+
+ protected:
+
+ /** Show error message if there is not enough memory available.
+ */
+ void
+ ShowMemoryErrorMessage(void);
+
+ public:
+
+ /** Application initialization.
+ @return true on success, false on error.
+ */
+ virtual
+ bool
+ OnInit();
+
+ /** Application shutdown.
+ @return 0 on success, any other value indicates an error.
+ */
+ virtual
+ int
+ OnExit();
+};
+
+
+
+/** Declaration as the wxApp object.
+*/
+DECLARE_APP(ScreenSizeApp)
+
+
+
+/* vim: set ai sw=4 ts=4 : */
+
+#endif
diff --git a/support/dktools/ScreenSizeFrame.cpp b/support/dktools/ScreenSizeFrame.cpp
new file mode 100644
index 0000000000..b22753fde2
--- /dev/null
+++ b/support/dktools/ScreenSizeFrame.cpp
@@ -0,0 +1,897 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: ScreenSizeFrame.wxc
+*/
+
+/*
+Copyright (C) 2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file ScreenSizeFrame.cpp The ScreenSizeFrame module.
+*/
+
+
+#line 294 "ScreenSizeFrame.wxc"
+
+#define AUTO_EXIT_ONLY_ON_SUCCESS 1
+
+
+#include "dk4mem.h"
+#include "wxdkscrsz.h"
+#include <dk4maixdul.h>
+#include "dk4maoxd.h"
+
+#if !defined(__WXMSW__)
+#include "wxdkscrsz.xpm"
+#endif
+
+
+
+
+
+#line 310 "ScreenSizeFrame.wxc"
+
+
+
+static const wxChar * const settingsNames[] = {
+/* 0 */
+wxT("screen.size.normal.width"),
+
+/* 1 */
+wxT("screen.size.normal.height"),
+
+/* 2 */
+wxT("screen.size.alternative.width"),
+
+/* 3 */
+wxT("screen.size.alternative.height"),
+
+NULL
+
+
+#line 320 "ScreenSizeFrame.wxc"
+};
+
+
+/* __CHANGE__ 017: Add further events. */
+/* __CHANGE__ 008: Remove OnIdle if no idle processing required. */
+BEGIN_EVENT_TABLE(ScreenSizeFrame, wxFrame)
+ EVT_MENU(ScreenSizeFrame_Quit, ScreenSizeFrame::OnQuit)
+ EVT_MENU(ScreenSizeFrame_Help_About, ScreenSizeFrame::OnAbout)
+ EVT_MENU(ScreenSizeFrame_Help_Contents, ScreenSizeFrame::OnHelpContents)
+ EVT_IDLE(ScreenSizeFrame::OnIdle)
+END_EVENT_TABLE()
+
+
+
+
+#line 335 "ScreenSizeFrame.wxc"
+ScreenSizeFrame::ScreenSizeFrame(
+ int wxid,
+ Dk4WxApplicationHelper *applicationHelper,
+ Dk4WxHelpController *hc,
+ int argc,
+ wxChar **argv,
+ wxChar const * const *localizedTexts,
+ wxChar const * const *nlWx,
+ dkChar const * const *nlDk
+) : Dk4WxFrame(nlWx[0], applicationHelper, hc, wxid),
+ cGreen(0, 127, 0),
+ cRed(127, 0, 0)
+{
+ /* __CHANGE__ 012: Add further local variables.
+ */
+
+ /* __CHANGE__ 012: Initialize further local variables.
+ */
+
+ sTexts = localizedTexts;
+ sNlWx = nlWx;
+ sNlDk = nlDk;
+#if defined(__WXMSW__)
+ wxIcon wxdkscrsz_icon(sNlWx[4]);
+#else
+ wxIcon wxdkscrsz_icon(xpm_wxdkscrsz);
+#endif
+
+ /* __CHANGE__ 011: Initialize further class members.
+ */
+ bActive = true;
+ iArgc = argc;
+ ppArgv = argv;
+
+ dkctGUILayoutOK = false;
+ dkctGUIContentsPanel = NULL;
+ mainSizer = NULL;
+ mbMain = NULL;
+ menuFile = NULL;
+ menuHelp = NULL;
+ miFileExit = NULL;
+ miHelpAbout = NULL;
+ miHelpContents = NULL;
+ verticalSizer = NULL;
+ contentsSizer = NULL;
+ lOldSize = NULL;
+ lOldWidth = NULL;
+ vOldWidth = NULL;
+ lOldHeight = NULL;
+ vOldHeight = NULL;
+ lNewSize = NULL;
+ lNewWidth = NULL;
+ vNewWidth = NULL;
+ lNewHeight = NULL;
+ vNewHeight = NULL;
+ lResult = NULL;
+ lSsc = NULL;
+ lSsr = NULL;
+ dkctGUIContentsPanel = new wxPanel(this);
+ if(!(dkctGUIContentsPanel)) {
+ goto dkctGUILayoutFinished;
+ }
+#if wxUSE_MENUS
+ mbMain = new wxMenuBar(
+ );
+ if(!(mbMain)) {
+ goto dkctGUILayoutFinished;
+ }
+ menuFile = new wxMenu(
+ );
+ if(!(menuFile)) {
+ goto dkctGUILayoutFinished;
+ }
+ miFileExit = menuFile->Append(
+ ScreenSizeFrame_Quit,
+ sTexts[1],
+ sTexts[2]
+ );
+ if(!(miFileExit)) {
+ goto dkctGUILayoutFinished;
+ }
+ mbMain->Append(menuFile, sTexts[0]);
+ menuHelp = new wxMenu(
+ );
+ if(!(menuHelp)) {
+ goto dkctGUILayoutFinished;
+ }
+ miHelpAbout = menuHelp->Append(
+ ScreenSizeFrame_Help_About,
+ sTexts[4],
+ sTexts[5]
+ );
+ if(!(miHelpAbout)) {
+ goto dkctGUILayoutFinished;
+ }
+ miHelpContents = menuHelp->Append(
+ ScreenSizeFrame_Help_Contents,
+ sTexts[6],
+ sTexts[7]
+ );
+ if(!(miHelpContents)) {
+ goto dkctGUILayoutFinished;
+ }
+ mbMain->Append(menuHelp, sTexts[3]);
+ SetMenuBar(mbMain);
+#endif
+ mainSizer = new wxBoxSizer(
+ wxHORIZONTAL
+ );
+ if(!(mainSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ mainSizer->Add(10, 10, 0);
+ verticalSizer = new wxBoxSizer(
+ wxVERTICAL
+ );
+ if(!(verticalSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ verticalSizer->Add(10, 10, 0);
+ contentsSizer = new wxGridBagSizer(
+ 5, 5
+ );
+ if(!(contentsSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ lOldSize = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[25],
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxALIGN_CENTRE
+ );
+ if(!(lOldSize)) {
+ goto dkctGUILayoutFinished;
+ }
+ contentsSizer->Add(
+ lOldSize,
+ wxGBPosition(0, 0),
+ wxGBSpan(1, 2),
+ wxALIGN_CENTER_HORIZONTAL
+ );
+ lOldWidth = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[26],
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxALIGN_RIGHT
+ );
+ if(!(lOldWidth)) {
+ goto dkctGUILayoutFinished;
+ }
+ contentsSizer->Add(
+ lOldWidth,
+ wxGBPosition(1, 0),
+ wxGBSpan(1, 1),
+ wxALIGN_RIGHT
+ );
+ vOldWidth = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[28],
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxALIGN_LEFT
+ );
+ if(!(vOldWidth)) {
+ goto dkctGUILayoutFinished;
+ }
+ contentsSizer->Add(
+ vOldWidth,
+ wxGBPosition(1, 1),
+ wxGBSpan(1, 1),
+ wxALIGN_LEFT
+ );
+ lOldHeight = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[27],
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxALIGN_RIGHT
+ );
+ if(!(lOldHeight)) {
+ goto dkctGUILayoutFinished;
+ }
+ contentsSizer->Add(
+ lOldHeight,
+ wxGBPosition(2, 0),
+ wxGBSpan(1, 1),
+ wxALIGN_RIGHT
+ );
+ vOldHeight = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[28],
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxALIGN_LEFT
+ );
+ if(!(vOldHeight)) {
+ goto dkctGUILayoutFinished;
+ }
+ contentsSizer->Add(
+ vOldHeight,
+ wxGBPosition(2, 1),
+ wxGBSpan(1, 1),
+ wxALIGN_LEFT
+ );
+ contentsSizer->Add(1, 5, wxGBPosition(3, 0), wxGBSpan(1, 1));
+ lNewSize = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[29],
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxALIGN_CENTRE
+ );
+ if(!(lNewSize)) {
+ goto dkctGUILayoutFinished;
+ }
+ contentsSizer->Add(
+ lNewSize,
+ wxGBPosition(4, 0),
+ wxGBSpan(1, 2),
+ wxALIGN_CENTER_HORIZONTAL
+ );
+ lNewWidth = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[26],
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxALIGN_RIGHT
+ );
+ if(!(lNewWidth)) {
+ goto dkctGUILayoutFinished;
+ }
+ contentsSizer->Add(
+ lNewWidth,
+ wxGBPosition(5, 0),
+ wxGBSpan(1, 1),
+ wxALIGN_RIGHT
+ );
+ vNewWidth = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[28],
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxALIGN_LEFT
+ );
+ if(!(vNewWidth)) {
+ goto dkctGUILayoutFinished;
+ }
+ contentsSizer->Add(
+ vNewWidth,
+ wxGBPosition(5, 1),
+ wxGBSpan(1, 1),
+ wxALIGN_LEFT
+ );
+ lNewHeight = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[27],
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxALIGN_RIGHT
+ );
+ if(!(lNewHeight)) {
+ goto dkctGUILayoutFinished;
+ }
+ contentsSizer->Add(
+ lNewHeight,
+ wxGBPosition(6, 0),
+ wxGBSpan(1, 1),
+ wxALIGN_RIGHT
+ );
+ vNewHeight = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[28],
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxALIGN_LEFT
+ );
+ if(!(vNewHeight)) {
+ goto dkctGUILayoutFinished;
+ }
+ contentsSizer->Add(
+ vNewHeight,
+ wxGBPosition(6, 1),
+ wxGBSpan(1, 1),
+ wxALIGN_LEFT
+ );
+ contentsSizer->Add(1, 5, wxGBPosition(7, 0), wxGBSpan(1, 1));
+ lResult = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[30],
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxALIGN_CENTRE
+ );
+ if(!(lResult)) {
+ goto dkctGUILayoutFinished;
+ }
+ contentsSizer->Add(
+ lResult,
+ wxGBPosition(8, 0),
+ wxGBSpan(1, 2),
+ wxALIGN_CENTER_HORIZONTAL
+ );
+ lSsc = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[13],
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxALIGN_RIGHT
+ );
+ if(!(lSsc)) {
+ goto dkctGUILayoutFinished;
+ }
+ contentsSizer->Add(
+ lSsc,
+ wxGBPosition(9, 0),
+ wxGBSpan(1, 1),
+ wxALIGN_RIGHT
+ );
+ lSsr = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[14],
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxALIGN_LEFT
+ );
+ if(!(lSsr)) {
+ goto dkctGUILayoutFinished;
+ }
+ contentsSizer->Add(
+ lSsr,
+ wxGBPosition(9, 1),
+ wxGBSpan(1, 1),
+ wxALIGN_LEFT
+ );
+ verticalSizer->Add(
+ contentsSizer
+ );
+ verticalSizer->Add(10, 10, 0);
+ mainSizer->Add(
+ verticalSizer,
+ 1,
+ wxGROW
+ );
+ mainSizer->Add(10, 10, 0);
+ dkctGUIContentsPanel->SetSizer(mainSizer);
+ SetIcon(wxdkscrsz_icon);
+ dkctGUILayoutOK = true;
+ dkctGUILayoutFinished:
+#if wxUSE_STATUSBAR
+ if(dkctGUILayoutOK) {
+ CreateStatusBar(1);
+ SetStatusText(sTexts[8]);
+ }
+#endif
+ if(dkctGUILayoutOK) {
+ mainSizer->Fit(this);
+ mainSizer->SetSizeHints(this);
+ }
+
+#line 370 "ScreenSizeFrame.wxc"
+ if(dkctGUILayoutOK) {
+ SetTitle(nlWx[0]);
+#if 0
+ RestorePosition();
+#endif
+ oAsc.SetAutoStart(true);
+ oAsc.SetAutoExit(true);
+ }
+
+ /* __CHANGE__ 012: Release resources allocated by local variables.
+ */
+}
+
+
+#line 384 "ScreenSizeFrame.wxc"
+
+
+
+ScreenSizeFrame::~ScreenSizeFrame()
+{
+
+ /* __CHANGE__ 011: Release resources allocated by further class members.
+ */
+}
+
+
+
+bool
+ScreenSizeFrame::CanClose(bool isLast)
+{
+ bool back = true;
+
+ /* __CHANGE__ 013: Check for unsaved data.
+ */
+
+ return back;
+}
+
+
+void
+ScreenSizeFrame::OnQuit(wxCommandEvent & event)
+{
+ Close();
+}
+
+
+
+void
+ScreenSizeFrame::OnAbout(wxCommandEvent & event)
+{
+ wxString text(wxT(""));
+ wxString title(wxT(""));
+
+ /* Construct message text. */
+ text.Append(sNlWx[0]);
+ text.Append(sNlWx[7]);
+ text.Append(sNlWx[1]);
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[9]);
+ text.Append(sNlWx[2]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[11]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[9]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[12]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[10]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[11]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[12]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[13]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[14]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[15]);
+ text.Append(sNlWx[8]);
+
+ /* Construct dialog box title. */
+ title.Append(sTexts[10]);
+ title.Append(sNlWx[0]);
+
+ /* Show dialog box. */
+ wxMessageBox(text, title);
+
+ /* __CHANGE__ 019: Create better about box.
+ */
+}
+
+
+
+void
+ScreenSizeFrame::OnHelpContents(wxCommandEvent & event)
+{
+ DisplayContents();
+}
+
+/* __CHANGE__ 017: Event handlers for further events.
+*/
+
+/* __CHANGE__ 014: Implementation of further methods.
+*/
+
+#if DK4_ON_WINDOWS
+/** Current device mode.
+*/
+static DEVMODE devmode;
+/** New device mode.
+*/
+static DEVMODE newmode;
+#endif
+
+bool
+ScreenSizeFrame::ModifyScreenSize(const unsigned long *ulp, int action)
+{
+ wxChar b1[64];
+ wxChar b2[64];
+ wxChar b3[64];
+ wxChar b4[64];
+#if DK4_ON_WINDOWS
+ DWORD dmfm = (DM_PELSWIDTH | DM_PELSHEIGHT);
+ DWORD dwfl = 0;
+ LONG res = 0L;
+#endif
+ bool back = false;
+
+ dk4ma_write_wx_decimal_unsigned(
+ b1, DK4_SIZEOF(b1,wxChar), (dk4_um_t)(ulp[0]), 0, NULL
+ );
+ dk4ma_write_wx_decimal_unsigned(
+ b2, DK4_SIZEOF(b2,wxChar), (dk4_um_t)(ulp[1]), 0, NULL
+ );
+ dk4ma_write_wx_decimal_unsigned(
+ b3, DK4_SIZEOF(b3,wxChar), (dk4_um_t)(ulp[2]), 0, NULL
+ );
+ dk4ma_write_wx_decimal_unsigned(
+ b4, DK4_SIZEOF(b4,wxChar), (dk4_um_t)(ulp[3]), 0, NULL
+ );
+ switch (action) {
+ case ACTION_TOGGLE_SCREEN_SIZE : {
+ vOldWidth->SetLabel(b3);
+ vOldHeight->SetLabel(b4);
+ vNewWidth->SetLabel(b1);
+ vNewHeight->SetLabel(b2);
+ } break;
+ default : {
+ vNewWidth->SetLabel(b1);
+ vNewHeight->SetLabel(b2);
+ } break;
+ }
+ Refresh();
+ Update();
+#if DK4_ON_WINDOWS
+ SecureZeroMemory(&devmode, sizeof(DEVMODE));
+ SecureZeroMemory(&newmode, sizeof(DEVMODE));
+ if (EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode)) {
+ if (dmfm == (dmfm & (devmode.dmFields))) {
+ DK4_MEMCPY(&newmode, &devmode, sizeof(DEVMODE));
+
+ dk4ma_write_wx_decimal_unsigned(
+ b1, DK4_SIZEOF(b1,wxChar),
+ (dk4_um_t)(devmode.dmPelsWidth), 0, NULL
+ );
+ dk4ma_write_wx_decimal_unsigned(
+ b2, DK4_SIZEOF(b2,wxChar),
+ (dk4_um_t)(devmode.dmPelsHeight), 0, NULL
+ );
+ vOldWidth->SetLabel(b1);
+ vOldHeight->SetLabel(b2);
+ Refresh();
+ Update();
+ switch (action) {
+ case ACTION_TOGGLE_SCREEN_SIZE : {
+ if (ulp[0] == devmode.dmPelsWidth) {
+ if (ulp[1] == devmode.dmPelsHeight) {
+ newmode.dmPelsWidth = ulp[2];
+ newmode.dmPelsHeight = ulp[3];
+ vOldWidth->SetLabel(b1);
+ vOldHeight->SetLabel(b2);
+ vNewWidth->SetLabel(b3);
+ vNewHeight->SetLabel(b4);
+ Refresh();
+ Update();
+ }
+ else {
+ newmode.dmPelsWidth = ulp[0];
+ newmode.dmPelsHeight = ulp[1];
+ }
+ }
+ else {
+ newmode.dmPelsWidth = ulp[0];
+ newmode.dmPelsHeight = ulp[1];
+ }
+ } break;
+ default : {
+ newmode.dmPelsWidth = ulp[0];
+ newmode.dmPelsHeight = ulp[1];
+ } break;
+ }
+ newmode.dmFields |= dmfm;
+ res = ChangeDisplaySettingsEx(NULL, &newmode, NULL, dwfl, NULL);
+ if (DISP_CHANGE_SUCCESSFUL == res) {
+ back = true;
+ }
+ else {
+ /* ERROR: Failed to change screen size */
+ wxMessageBox(
+ sTexts[20], sTexts[18], (wxOK | wxCENTRE | wxICON_ERROR)
+ );
+ }
+ }
+ else {
+ /* ERROR: Failed to retrieve current settings */
+ wxMessageBox(
+ sTexts[19], sTexts[18], (wxOK | wxCENTRE | wxICON_ERROR)
+ );
+ }
+ }
+ else {
+ /* ERROR: Failed to retrieve current settings */
+ wxMessageBox(
+ sTexts[19], sTexts[18], (wxOK | wxCENTRE | wxICON_ERROR)
+ );
+ }
+#else
+ wxMessageBox(
+ sTexts[21], sTexts[18], (wxOK | wxCENTRE | wxICON_ERROR)
+ );
+ back = false;
+#endif
+ return back;
+}
+
+
+void
+ScreenSizeFrame::ShowUnusableText(const wxChar *str)
+{
+ wxString s(sTexts[22]);
+ s.Append(str);
+ s.Append(sTexts[23]);
+ wxMessageBox(s, sTexts[18], (wxOK | wxCENTRE | wxICON_ERROR));
+}
+
+
+
+bool
+ScreenSizeFrame::ChangeScreenSize(void)
+{
+ const wxChar *ep = NULL;
+ long lv[] = { 0L, 0L, 0L, 0L };
+ unsigned long ulv[] = { 0UL, 0UL, 0UL, 0UL };
+ int action = ACTION_SET_SCREEN_SIZE;
+ int res = 0;
+ bool back = false;
+ bool found = false;
+
+
+#line 629 "ScreenSizeFrame.wxc"
+ switch (iArgc) {
+ case 5 : {
+ back = true;
+ ep = NULL;
+ res = dk4ma_input_wx_dec_ulong(&(ulv[0]), ppArgv[1], &ep, 1, NULL);
+ if (0 == res) {
+ back = false;
+ ShowUnusableText(ppArgv[1]);
+ }
+ if (back) {
+ ep = NULL;
+ res = dk4ma_input_wx_dec_ulong(&(ulv[1]),ppArgv[2],&ep,1,NULL);
+ if (0 == res) {
+ ShowUnusableText(ppArgv[2]);
+ back = false;
+ }
+ }
+ if (back) {
+ ep = NULL;
+ res = dk4ma_input_wx_dec_ulong(&(ulv[2]),ppArgv[3],&ep,1,NULL);
+ if (0 == res) {
+ ShowUnusableText(ppArgv[3]);
+ back = false;
+ }
+ }
+ if (back) {
+ ep = NULL;
+ res = dk4ma_input_wx_dec_ulong(&(ulv[3]),ppArgv[4],&ep,1,NULL);
+ if (0 == res) {
+ ShowUnusableText(ppArgv[4]);
+ back = false;
+ }
+ }
+ if (back) {
+ back = ModifyScreenSize(ulv, ACTION_TOGGLE_SCREEN_SIZE);
+ }
+ } break;
+ case 3 : {
+ back = true;
+ ep = NULL;
+ res = dk4ma_input_wx_dec_ulong(&(ulv[0]), ppArgv[1], &ep, 1, NULL);
+ if (0 == res) {
+ ShowUnusableText(ppArgv[1]);
+ back = false;
+ }
+ if (back) {
+ ep = NULL;
+ res = dk4ma_input_wx_dec_ulong(&(ulv[1]),ppArgv[2],&ep,1,NULL);
+ if (0 == res) {
+ ShowUnusableText(ppArgv[2]);
+ back = false;
+ }
+ }
+ if (back) {
+ back = ModifyScreenSize(ulv, ACTION_SET_SCREEN_SIZE);
+ }
+ } break;
+ case 1 : {
+ action = ACTION_REPORT_NO_ARGS_NO_SETTINGS;
+ if (pAppHelp->GetMultiple(settingsNames, lv, 4)) {
+ if (0L < lv[0]) {
+ if (0L < lv[1]) {
+ if (0L < lv[2]) {
+ if (0L < lv[3]) {
+ ulv[0] = (unsigned long)(lv[0]);
+ ulv[1] = (unsigned long)(lv[1]);
+ ulv[2] = (unsigned long)(lv[2]);
+ ulv[3] = (unsigned long)(lv[3]);
+ found = true;
+ back = ModifyScreenSize(
+ ulv, ACTION_TOGGLE_SCREEN_SIZE
+ );
+ }
+ }
+ else {
+ ulv[0] = (unsigned long)(lv[0]);
+ ulv[1] = (unsigned long)(lv[1]);
+ found = true;
+ back = ModifyScreenSize(
+ ulv, ACTION_SET_SCREEN_SIZE
+ );
+ }
+ }
+ }
+ }
+ else {
+ }
+ if (!(found)) {
+ wxMessageBox(
+ sTexts[24], sTexts[18], (wxOK | wxCENTRE | wxICON_ERROR)
+ );
+ }
+ } break;
+ default : {
+ wxMessageBox(
+ sTexts[24], sTexts[18], (wxOK | wxCENTRE | wxICON_ERROR)
+ );
+ } break;
+ }
+
+ finished:
+ if (back) {
+ lSsr->SetLabel(sTexts[16]);
+ lSsr->SetForegroundColour(cGreen);
+ }
+ else {
+ lSsr->SetLabel(sTexts[17]);
+ lSsr->SetForegroundColour(cRed);
+ }
+ Refresh();
+ Update();
+
+
+#line 741 "ScreenSizeFrame.wxc"
+ return back;
+}
+
+
+/* __CHANGE__ 008: Remove OnIdle if no idle processing required.
+*/
+
+void
+ScreenSizeFrame::OnIdle(wxIdleEvent & event)
+{
+#if AUTO_EXIT_ONLY_ON_SUCCESS
+ bool bSuccess;
+#endif
+
+
+#line 755 "ScreenSizeFrame.wxc"
+ /* __CHANGE__
+ */
+ if (bActive) {
+ switch (oAsc.GetReaction()) {
+#if 0
+ case DK4WX_AUTOSTART_REACTION_IGNORE : {
+ } break;
+#endif
+ case DK4WX_AUTOSTART_REACTION_START : {
+ oAsc.StartProcessing();
+#if AUTO_EXIT_ONLY_ON_SUCCESS
+ bSuccess = ChangeScreenSize();
+ oAsc.EndProcessing(bSuccess);
+#else
+ (void)ChangeScreenSize();
+ oAsc.EndProcessing(true);
+#endif
+ } break;
+ case DK4WX_AUTOSTART_REACTION_MORE : {
+ } break;
+ case DK4WX_AUTOSTART_REACTION_EXIT : {
+ bActive = false;
+ Close();
+ } break;
+ }
+ event.RequestMore();
+ }
+
+
+#line 783 "ScreenSizeFrame.wxc"
+ event.Skip();
+}
+
+
+/* vim: set ai sw=4 ts=4 : */
+
diff --git a/support/dktools/ScreenSizeFrame.h b/support/dktools/ScreenSizeFrame.h
new file mode 100644
index 0000000000..44f1a12949
--- /dev/null
+++ b/support/dktools/ScreenSizeFrame.h
@@ -0,0 +1,329 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: ScreenSizeFrame.wxc
+*/
+
+/*
+Copyright (C) 2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file ScreenSizeFrame.h Header file for the ScreenSizeFrame module.
+*/
+
+#ifndef SCREENSIZEFRAME_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define SCREENSIZEFRAME_H_INCLUDED 1
+
+
+#line 131 "ScreenSizeFrame.wxc"
+
+
+#include <Dk4WxAutostartController.h>
+
+
+enum {
+ /** Set new screen size.
+ */
+ ACTION_SET_SCREEN_SIZE = 0 ,
+
+ /** Toggle between normal and alternative size.
+ */
+ ACTION_TOGGLE_SCREEN_SIZE ,
+
+ ACTION_REPORT_NO_ARGS_NO_SETTINGS
+};
+
+
+#line 149 "ScreenSizeFrame.wxc"
+class ScreenSizeFrame : public Dk4WxFrame
+{
+ private:
+
+ /** Event table for frame.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ /** Controller to start activity at first idle event.
+ */
+ Dk4WxAutostartController oAsc;
+
+ /** Color to indicate success.
+ */
+ wxColour cGreen;
+
+ /** Color to indicate failure.
+ */
+ wxColour cRed;
+
+ /** Localized texts.
+ */
+ wxChar const * const *sTexts;
+
+ /** Non-localized texts.
+ */
+ wxChar const * const *sNlWx;
+
+ /** Non-localized texts.
+ */
+ dkChar const * const *sNlDk;
+
+ /** Private copy of the argv arguments.
+ */
+ wxChar **ppArgv;
+
+ /* __CHANGE__ 011: Add further member variables.
+ */
+
+
+ /** Private copy of the argc arguments.
+ */
+ int iArgc;
+
+ /** Flag: Process idle events.
+ */
+ bool bActive;
+
+ /** Flag: GUI ok.
+ */
+ bool dkctGUILayoutOK;
+
+ /** Contents panel.
+ */
+ wxPanel *dkctGUIContentsPanel;
+
+ /** GUI element mainSizer.
+ */
+#line 45 "ScreenSizeFrame.wxc"
+ wxBoxSizer *mainSizer;
+
+ /** GUI element mbMain.
+ */
+#line 17 "ScreenSizeFrame.wxc"
+ wxMenuBar *mbMain;
+
+ /** GUI element menuFile.
+ */
+#line 21 "ScreenSizeFrame.wxc"
+ wxMenu *menuFile;
+
+ /** GUI element menuHelp.
+ */
+#line 30 "ScreenSizeFrame.wxc"
+ wxMenu *menuHelp;
+
+ /** GUI element miFileExit.
+ */
+#line 25 "ScreenSizeFrame.wxc"
+ wxMenuItem *miFileExit;
+
+ /** GUI element miHelpAbout.
+ */
+#line 35 "ScreenSizeFrame.wxc"
+ wxMenuItem *miHelpAbout;
+
+ /** GUI element miHelpContents.
+ */
+#line 40 "ScreenSizeFrame.wxc"
+ wxMenuItem *miHelpContents;
+
+ /** GUI element verticalSizer.
+ */
+#line 51 "ScreenSizeFrame.wxc"
+ wxBoxSizer *verticalSizer;
+
+ /** GUI element contentsSizer.
+ */
+#line 59 "ScreenSizeFrame.wxc"
+ wxGridBagSizer *contentsSizer;
+
+ /** GUI element lOldSize.
+ */
+#line 77 "ScreenSizeFrame.wxc"
+ wxStaticText *lOldSize;
+
+ /** GUI element lOldWidth.
+ */
+#line 81 "ScreenSizeFrame.wxc"
+ wxStaticText *lOldWidth;
+
+ /** GUI element vOldWidth.
+ */
+#line 85 "ScreenSizeFrame.wxc"
+ wxStaticText *vOldWidth;
+
+ /** GUI element lOldHeight.
+ */
+#line 89 "ScreenSizeFrame.wxc"
+ wxStaticText *lOldHeight;
+
+ /** GUI element vOldHeight.
+ */
+#line 93 "ScreenSizeFrame.wxc"
+ wxStaticText *vOldHeight;
+
+ /** GUI element lNewSize.
+ */
+#line 97 "ScreenSizeFrame.wxc"
+ wxStaticText *lNewSize;
+
+ /** GUI element lNewWidth.
+ */
+#line 101 "ScreenSizeFrame.wxc"
+ wxStaticText *lNewWidth;
+
+ /** GUI element vNewWidth.
+ */
+#line 105 "ScreenSizeFrame.wxc"
+ wxStaticText *vNewWidth;
+
+ /** GUI element lNewHeight.
+ */
+#line 109 "ScreenSizeFrame.wxc"
+ wxStaticText *lNewHeight;
+
+ /** GUI element vNewHeight.
+ */
+#line 113 "ScreenSizeFrame.wxc"
+ wxStaticText *vNewHeight;
+
+ /** GUI element lResult.
+ */
+#line 117 "ScreenSizeFrame.wxc"
+ wxStaticText *lResult;
+
+ /** GUI element lSsc.
+ */
+#line 121 "ScreenSizeFrame.wxc"
+ wxStaticText *lSsc;
+
+ /** GUI element lSsr.
+ */
+#line 125 "ScreenSizeFrame.wxc"
+ wxStaticText *lSsr;
+
+
+#line 200 "ScreenSizeFrame.wxc"
+
+ private:
+
+ void
+ ShowUnusableText(const wxChar *str);
+
+ protected:
+
+ /** Do the real work in the screen size change.
+ @param ulp Address of array containing screen sizes.
+ @param action Action to perform (set or toggle).
+ @return True on success, false on error.
+ */
+ bool
+ ModifyScreenSize(const unsigned long *ulp, int action);
+
+ public:
+
+ /** Constructor.
+ @param wxid Window ID.
+ @param applicationHelper Application helper object.
+ @param hc Help controller for online help.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @param localizedTexts Localized wxChar texts.
+ @param nlWx Non-localized wxChar texts.
+ @param nlDk Non-localized dkChar texts.
+ */
+ ScreenSizeFrame(
+ int wxid,
+ Dk4WxApplicationHelper *applicationHelper,
+ Dk4WxHelpController *hc,
+ int argc,
+ wxChar **argv,
+ wxChar const * const *localizedTexts,
+ wxChar const * const *nlWx,
+ dkChar const * const *nlDk
+ );
+
+ /** Destructor.
+ */
+ ~ScreenSizeFrame();
+
+ /** Check whether we can close the window.
+ @param isLast Flag: Last main window to close.
+ */
+ bool
+ CanClose(bool isFinal);
+
+ /** Handler for File/Exit.
+ @param event Event to process.
+ */
+ void
+ OnQuit(wxCommandEvent & event);
+
+ /** Handler for Help/About.
+ @param event Event to process.
+ */
+ void
+ OnAbout(wxCommandEvent & event);
+
+ /** Handler for Help/Contents.
+ @param event Event to process.
+ */
+ void
+ OnHelpContents(wxCommandEvent & event);
+
+ /* __CHANGE__ 008: Remove OnIdle if no idle processing required.
+ */
+ /** Handler for idle events.
+ */
+ void
+ OnIdle(wxIdleEvent & event);
+
+ /* __CHANGE__ 017: Event handlers for further events.
+ */
+
+ /* __CHANGE__ 014: Add further methods.
+ */
+
+
+ /** Change the screen size.
+ @return True on success, false on error.
+ */
+ bool
+ ChangeScreenSize(void);
+
+};
+
+
+#line 290 "ScreenSizeFrame.wxc"
+
+/* vim: set ai sw=4 ts=4 : */
+
+
+#endif
diff --git a/support/dktools/ScreenSizeFrame.wxc b/support/dktools/ScreenSizeFrame.wxc
new file mode 100644
index 0000000000..72ec946f7a
--- /dev/null
+++ b/support/dktools/ScreenSizeFrame.wxc
@@ -0,0 +1,788 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2017
+license = bsd
+
+
+
+%% wx-gui
+
+type = frame
+contents = mainSizer
+icon = wxdkscrsz_icon
+status bar = 1 sTexts[8]
+menu bar = mbMain
+
+[wxMenuBar mbMain]
+contents = menuFile
+contents = menuHelp
+
+[wxMenu menuFile]
+text = sTexts[0]
+contents = miFileExit
+
+[wxMenuItem miFileExit]
+id = ScreenSizeFrame_Quit
+text = sTexts[1]
+tip = sTexts[2]
+
+[wxMenu menuHelp]
+text = sTexts[3]
+contents = miHelpAbout
+contents = miHelpContents
+
+[wxMenuItem miHelpAbout]
+id = ScreenSizeFrame_Help_About
+text = sTexts[4]
+tip = sTexts[5]
+
+[wxMenuItem miHelpContents]
+id = ScreenSizeFrame_Help_Contents
+text = sTexts[6]
+tip = sTexts[7]
+
+[wxBoxSizer mainSizer]
+direction = horizontal
+contents = $space(10)
+contents = verticalSizer
+contents = $space(10)
+
+[wxBoxSizer verticalSizer]
+direction = vertical
+grow = yes
+proportion = 1
+contents = $space(10)
+contents = contentsSizer
+contents = $space(10)
+
+[wxGridBagSizer contentsSizer]
+grid = 5 5
+contents = lOldSize 0 0 1 2 centered-x
+contents = lOldWidth +1 0 1 1 right
+contents = vOldWidth . 1 1 1 left
+contents = lOldHeight +1 0 1 1 right
+contents = vOldHeight . 1 1 1 left
+contents = $space(1,5) +1 0 1 1 left
+contents = lNewSize +1 0 1 2 centered-x
+contents = lNewWidth +1 0 1 1 right
+contents = vNewWidth . 1 1 1 left
+contents = lNewHeight +1 0 1 1 right
+contents = vNewHeight . 1 1 1 left
+contents = $space(1,5) +1 0 1 1 left
+contents = lResult +1 0 1 2 centered-x
+contents = lSsc +1 0 1 1 right
+contents = lSsr . 1 1 1 left
+
+[wxStaticText lOldSize]
+text = sTexts[25]
+text style = centered
+
+[wxStaticText lOldWidth]
+text = sTexts[26]
+text style = right
+
+[wxStaticText vOldWidth]
+text = sTexts[28]
+text style = left
+
+[wxStaticText lOldHeight]
+text = sTexts[27]
+text style = right
+
+[wxStaticText vOldHeight]
+text = sTexts[28]
+text style = left
+
+[wxStaticText lNewSize]
+text = sTexts[29]
+text style = centered
+
+[wxStaticText lNewWidth]
+text = sTexts[26]
+text style = right
+
+[wxStaticText vNewWidth]
+text = sTexts[28]
+text style = left
+
+[wxStaticText lNewHeight]
+text = sTexts[27]
+text style = right
+
+[wxStaticText vNewHeight]
+text = sTexts[28]
+text style = left
+
+[wxStaticText lResult]
+text = sTexts[30]
+text style = centered
+
+[wxStaticText lSsc]
+text = sTexts[13]
+text style = right
+
+[wxStaticText lSsr]
+text = sTexts[14]
+text style = left
+
+
+%% header start
+
+
+#include <Dk4WxAutostartController.h>
+
+
+enum {
+ /** Set new screen size.
+ */
+ ACTION_SET_SCREEN_SIZE = 0 ,
+
+ /** Toggle between normal and alternative size.
+ */
+ ACTION_TOGGLE_SCREEN_SIZE ,
+
+ ACTION_REPORT_NO_ARGS_NO_SETTINGS
+};
+
+%% class start
+class ScreenSizeFrame : public Dk4WxFrame
+{
+ private:
+
+ /** Event table for frame.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ /** Controller to start activity at first idle event.
+ */
+ Dk4WxAutostartController oAsc;
+
+ /** Color to indicate success.
+ */
+ wxColour cGreen;
+
+ /** Color to indicate failure.
+ */
+ wxColour cRed;
+
+ /** Localized texts.
+ */
+ wxChar const * const *sTexts;
+
+ /** Non-localized texts.
+ */
+ wxChar const * const *sNlWx;
+
+ /** Non-localized texts.
+ */
+ dkChar const * const *sNlDk;
+
+ /** Private copy of the argv arguments.
+ */
+ wxChar **ppArgv;
+
+ /* __CHANGE__ 011: Add further member variables.
+ */
+
+
+ /** Private copy of the argc arguments.
+ */
+ int iArgc;
+
+ /** Flag: Process idle events.
+ */
+ bool bActive;
+
+%% class end
+
+ private:
+
+ void
+ ShowUnusableText(const wxChar *str);
+
+ protected:
+
+ /** Do the real work in the screen size change.
+ @param ulp Address of array containing screen sizes.
+ @param action Action to perform (set or toggle).
+ @return True on success, false on error.
+ */
+ bool
+ ModifyScreenSize(const unsigned long *ulp, int action);
+
+ public:
+
+ /** Constructor.
+ @param wxid Window ID.
+ @param applicationHelper Application helper object.
+ @param hc Help controller for online help.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @param localizedTexts Localized wxChar texts.
+ @param nlWx Non-localized wxChar texts.
+ @param nlDk Non-localized dkChar texts.
+ */
+ ScreenSizeFrame(
+ int wxid,
+ Dk4WxApplicationHelper *applicationHelper,
+ Dk4WxHelpController *hc,
+ int argc,
+ wxChar **argv,
+ wxChar const * const *localizedTexts,
+ wxChar const * const *nlWx,
+ dkChar const * const *nlDk
+ );
+
+ /** Destructor.
+ */
+ ~ScreenSizeFrame();
+
+ /** Check whether we can close the window.
+ @param isLast Flag: Last main window to close.
+ */
+ bool
+ CanClose(bool isFinal);
+
+ /** Handler for File/Exit.
+ @param event Event to process.
+ */
+ void
+ OnQuit(wxCommandEvent & event);
+
+ /** Handler for Help/About.
+ @param event Event to process.
+ */
+ void
+ OnAbout(wxCommandEvent & event);
+
+ /** Handler for Help/Contents.
+ @param event Event to process.
+ */
+ void
+ OnHelpContents(wxCommandEvent & event);
+
+ /* __CHANGE__ 008: Remove OnIdle if no idle processing required.
+ */
+ /** Handler for idle events.
+ */
+ void
+ OnIdle(wxIdleEvent & event);
+
+ /* __CHANGE__ 017: Event handlers for further events.
+ */
+
+ /* __CHANGE__ 014: Add further methods.
+ */
+
+
+ /** Change the screen size.
+ @return True on success, false on error.
+ */
+ bool
+ ChangeScreenSize(void);
+
+};
+
+%% header end
+
+/* vim: set ai sw=4 ts=4 : */
+
+%% module start
+
+#define AUTO_EXIT_ONLY_ON_SUCCESS 1
+
+
+#include "dk4mem.h"
+#include "wxdkscrsz.h"
+#include <dk4maixdul.h>
+#include "dk4maoxd.h"
+
+#if !defined(__WXMSW__)
+#include "wxdkscrsz.xpm"
+#endif
+
+
+
+$!trace-include
+
+
+
+static const wxChar * const settingsNames[] = {
+$!string-table macro=wxT
+screen.size.normal.width
+screen.size.normal.height
+screen.size.alternative.width
+screen.size.alternative.height
+$!end
+};
+
+
+/* __CHANGE__ 017: Add further events. */
+/* __CHANGE__ 008: Remove OnIdle if no idle processing required. */
+BEGIN_EVENT_TABLE(ScreenSizeFrame, wxFrame)
+ EVT_MENU(ScreenSizeFrame_Quit, ScreenSizeFrame::OnQuit)
+ EVT_MENU(ScreenSizeFrame_Help_About, ScreenSizeFrame::OnAbout)
+ EVT_MENU(ScreenSizeFrame_Help_Contents, ScreenSizeFrame::OnHelpContents)
+ EVT_IDLE(ScreenSizeFrame::OnIdle)
+END_EVENT_TABLE()
+
+
+
+%% constructor start
+ScreenSizeFrame::ScreenSizeFrame(
+ int wxid,
+ Dk4WxApplicationHelper *applicationHelper,
+ Dk4WxHelpController *hc,
+ int argc,
+ wxChar **argv,
+ wxChar const * const *localizedTexts,
+ wxChar const * const *nlWx,
+ dkChar const * const *nlDk
+) : Dk4WxFrame(nlWx[0], applicationHelper, hc, wxid),
+ cGreen(0, 127, 0),
+ cRed(127, 0, 0)
+{
+ /* __CHANGE__ 012: Add further local variables.
+ */
+
+ /* __CHANGE__ 012: Initialize further local variables.
+ */
+
+ sTexts = localizedTexts;
+ sNlWx = nlWx;
+ sNlDk = nlDk;
+#if defined(__WXMSW__)
+ wxIcon wxdkscrsz_icon(sNlWx[4]);
+#else
+ wxIcon wxdkscrsz_icon(xpm_wxdkscrsz);
+#endif
+
+ /* __CHANGE__ 011: Initialize further class members.
+ */
+ bActive = true;
+ iArgc = argc;
+ ppArgv = argv;
+
+%% constructor end
+ if(dkctGUILayoutOK) {
+ SetTitle(nlWx[0]);
+#if 0
+ RestorePosition();
+#endif
+ oAsc.SetAutoStart(true);
+ oAsc.SetAutoExit(true);
+ }
+
+ /* __CHANGE__ 012: Release resources allocated by local variables.
+ */
+}
+
+%% module end
+
+
+
+ScreenSizeFrame::~ScreenSizeFrame()
+{
+
+ /* __CHANGE__ 011: Release resources allocated by further class members.
+ */
+}
+
+
+
+bool
+ScreenSizeFrame::CanClose(bool isLast)
+{
+ bool back = true;
+
+ /* __CHANGE__ 013: Check for unsaved data.
+ */
+
+ return back;
+}
+
+
+void
+ScreenSizeFrame::OnQuit(wxCommandEvent & event)
+{
+ Close();
+}
+
+
+
+void
+ScreenSizeFrame::OnAbout(wxCommandEvent & event)
+{
+ wxString text(wxT(""));
+ wxString title(wxT(""));
+
+ /* Construct message text. */
+ text.Append(sNlWx[0]);
+ text.Append(sNlWx[7]);
+ text.Append(sNlWx[1]);
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[9]);
+ text.Append(sNlWx[2]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[11]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[9]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[12]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[10]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[11]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[12]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[13]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[14]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[15]);
+ text.Append(sNlWx[8]);
+
+ /* Construct dialog box title. */
+ title.Append(sTexts[10]);
+ title.Append(sNlWx[0]);
+
+ /* Show dialog box. */
+ wxMessageBox(text, title);
+
+ /* __CHANGE__ 019: Create better about box.
+ */
+}
+
+
+
+void
+ScreenSizeFrame::OnHelpContents(wxCommandEvent & event)
+{
+ DisplayContents();
+}
+
+/* __CHANGE__ 017: Event handlers for further events.
+*/
+
+/* __CHANGE__ 014: Implementation of further methods.
+*/
+
+#if DK4_ON_WINDOWS
+/** Current device mode.
+*/
+static DEVMODE devmode;
+/** New device mode.
+*/
+static DEVMODE newmode;
+#endif
+
+bool
+ScreenSizeFrame::ModifyScreenSize(const unsigned long *ulp, int action)
+{
+ wxChar b1[64];
+ wxChar b2[64];
+ wxChar b3[64];
+ wxChar b4[64];
+#if DK4_ON_WINDOWS
+ DWORD dmfm = (DM_PELSWIDTH | DM_PELSHEIGHT);
+ DWORD dwfl = 0;
+ LONG res = 0L;
+#endif
+ bool back = false;
+
+ dk4ma_write_wx_decimal_unsigned(
+ b1, DK4_SIZEOF(b1,wxChar), (dk4_um_t)(ulp[0]), 0, NULL
+ );
+ dk4ma_write_wx_decimal_unsigned(
+ b2, DK4_SIZEOF(b2,wxChar), (dk4_um_t)(ulp[1]), 0, NULL
+ );
+ dk4ma_write_wx_decimal_unsigned(
+ b3, DK4_SIZEOF(b3,wxChar), (dk4_um_t)(ulp[2]), 0, NULL
+ );
+ dk4ma_write_wx_decimal_unsigned(
+ b4, DK4_SIZEOF(b4,wxChar), (dk4_um_t)(ulp[3]), 0, NULL
+ );
+ switch (action) {
+ case ACTION_TOGGLE_SCREEN_SIZE : {
+ vOldWidth->SetLabel(b3);
+ vOldHeight->SetLabel(b4);
+ vNewWidth->SetLabel(b1);
+ vNewHeight->SetLabel(b2);
+ } break;
+ default : {
+ vNewWidth->SetLabel(b1);
+ vNewHeight->SetLabel(b2);
+ } break;
+ }
+ Refresh();
+ Update();
+#if DK4_ON_WINDOWS
+ SecureZeroMemory(&devmode, sizeof(DEVMODE));
+ SecureZeroMemory(&newmode, sizeof(DEVMODE));
+ if (EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode)) {
+ if (dmfm == (dmfm & (devmode.dmFields))) {
+ DK4_MEMCPY(&newmode, &devmode, sizeof(DEVMODE));
+
+ dk4ma_write_wx_decimal_unsigned(
+ b1, DK4_SIZEOF(b1,wxChar),
+ (dk4_um_t)(devmode.dmPelsWidth), 0, NULL
+ );
+ dk4ma_write_wx_decimal_unsigned(
+ b2, DK4_SIZEOF(b2,wxChar),
+ (dk4_um_t)(devmode.dmPelsHeight), 0, NULL
+ );
+ vOldWidth->SetLabel(b1);
+ vOldHeight->SetLabel(b2);
+ Refresh();
+ Update();
+ switch (action) {
+ case ACTION_TOGGLE_SCREEN_SIZE : {
+ if (ulp[0] == devmode.dmPelsWidth) {
+ if (ulp[1] == devmode.dmPelsHeight) {
+ newmode.dmPelsWidth = ulp[2];
+ newmode.dmPelsHeight = ulp[3];
+ vOldWidth->SetLabel(b1);
+ vOldHeight->SetLabel(b2);
+ vNewWidth->SetLabel(b3);
+ vNewHeight->SetLabel(b4);
+ Refresh();
+ Update();
+ }
+ else {
+ newmode.dmPelsWidth = ulp[0];
+ newmode.dmPelsHeight = ulp[1];
+ }
+ }
+ else {
+ newmode.dmPelsWidth = ulp[0];
+ newmode.dmPelsHeight = ulp[1];
+ }
+ } break;
+ default : {
+ newmode.dmPelsWidth = ulp[0];
+ newmode.dmPelsHeight = ulp[1];
+ } break;
+ }
+ newmode.dmFields |= dmfm;
+ res = ChangeDisplaySettingsEx(NULL, &newmode, NULL, dwfl, NULL);
+ if (DISP_CHANGE_SUCCESSFUL == res) {
+ back = true;
+ }
+ else {
+ /* ERROR: Failed to change screen size */
+ wxMessageBox(
+ sTexts[20], sTexts[18], (wxOK | wxCENTRE | wxICON_ERROR)
+ );
+ }
+ }
+ else {
+ /* ERROR: Failed to retrieve current settings */
+ wxMessageBox(
+ sTexts[19], sTexts[18], (wxOK | wxCENTRE | wxICON_ERROR)
+ );
+ }
+ }
+ else {
+ /* ERROR: Failed to retrieve current settings */
+ wxMessageBox(
+ sTexts[19], sTexts[18], (wxOK | wxCENTRE | wxICON_ERROR)
+ );
+ }
+#else
+ wxMessageBox(
+ sTexts[21], sTexts[18], (wxOK | wxCENTRE | wxICON_ERROR)
+ );
+ back = false;
+#endif
+ return back;
+}
+
+
+void
+ScreenSizeFrame::ShowUnusableText(const wxChar *str)
+{
+ wxString s(sTexts[22]);
+ s.Append(str);
+ s.Append(sTexts[23]);
+ wxMessageBox(s, sTexts[18], (wxOK | wxCENTRE | wxICON_ERROR));
+}
+
+
+
+bool
+ScreenSizeFrame::ChangeScreenSize(void)
+{
+ const wxChar *ep = NULL;
+ long lv[] = { 0L, 0L, 0L, 0L };
+ unsigned long ulv[] = { 0UL, 0UL, 0UL, 0UL };
+ int action = ACTION_SET_SCREEN_SIZE;
+ int res = 0;
+ bool back = false;
+ bool found = false;
+ $? "+ ScreenSizeFrame::ChangeScreenSize"
+ switch (iArgc) {
+ case 5 : {
+ back = true;
+ ep = NULL;
+ res = dk4ma_input_wx_dec_ulong(&(ulv[0]), ppArgv[1], &ep, 1, NULL);
+ if (0 == res) {
+ back = false;
+ ShowUnusableText(ppArgv[1]);
+ }
+ if (back) {
+ ep = NULL;
+ res = dk4ma_input_wx_dec_ulong(&(ulv[1]),ppArgv[2],&ep,1,NULL);
+ if (0 == res) {
+ ShowUnusableText(ppArgv[2]);
+ back = false;
+ }
+ }
+ if (back) {
+ ep = NULL;
+ res = dk4ma_input_wx_dec_ulong(&(ulv[2]),ppArgv[3],&ep,1,NULL);
+ if (0 == res) {
+ ShowUnusableText(ppArgv[3]);
+ back = false;
+ }
+ }
+ if (back) {
+ ep = NULL;
+ res = dk4ma_input_wx_dec_ulong(&(ulv[3]),ppArgv[4],&ep,1,NULL);
+ if (0 == res) {
+ ShowUnusableText(ppArgv[4]);
+ back = false;
+ }
+ }
+ if (back) {
+ back = ModifyScreenSize(ulv, ACTION_TOGGLE_SCREEN_SIZE);
+ }
+ } break;
+ case 3 : {
+ back = true;
+ ep = NULL;
+ res = dk4ma_input_wx_dec_ulong(&(ulv[0]), ppArgv[1], &ep, 1, NULL);
+ if (0 == res) {
+ ShowUnusableText(ppArgv[1]);
+ back = false;
+ }
+ if (back) {
+ ep = NULL;
+ res = dk4ma_input_wx_dec_ulong(&(ulv[1]),ppArgv[2],&ep,1,NULL);
+ if (0 == res) {
+ ShowUnusableText(ppArgv[2]);
+ back = false;
+ }
+ }
+ if (back) {
+ back = ModifyScreenSize(ulv, ACTION_SET_SCREEN_SIZE);
+ }
+ } break;
+ case 1 : {
+ action = ACTION_REPORT_NO_ARGS_NO_SETTINGS;
+ if (pAppHelp->GetMultiple(settingsNames, lv, 4)) {
+ if (0L < lv[0]) {
+ if (0L < lv[1]) {
+ if (0L < lv[2]) {
+ if (0L < lv[3]) {
+ ulv[0] = (unsigned long)(lv[0]);
+ ulv[1] = (unsigned long)(lv[1]);
+ ulv[2] = (unsigned long)(lv[2]);
+ ulv[3] = (unsigned long)(lv[3]);
+ found = true;
+ back = ModifyScreenSize(
+ ulv, ACTION_TOGGLE_SCREEN_SIZE
+ );
+ }
+ }
+ else {
+ ulv[0] = (unsigned long)(lv[0]);
+ ulv[1] = (unsigned long)(lv[1]);
+ found = true;
+ back = ModifyScreenSize(
+ ulv, ACTION_SET_SCREEN_SIZE
+ );
+ }
+ }
+ }
+ }
+ else {
+ }
+ if (!(found)) {
+ wxMessageBox(
+ sTexts[24], sTexts[18], (wxOK | wxCENTRE | wxICON_ERROR)
+ );
+ }
+ } break;
+ default : {
+ wxMessageBox(
+ sTexts[24], sTexts[18], (wxOK | wxCENTRE | wxICON_ERROR)
+ );
+ } break;
+ }
+
+ finished:
+ if (back) {
+ lSsr->SetLabel(sTexts[16]);
+ lSsr->SetForegroundColour(cGreen);
+ }
+ else {
+ lSsr->SetLabel(sTexts[17]);
+ lSsr->SetForegroundColour(cRed);
+ }
+ Refresh();
+ Update();
+ $? "- ScreenSizeFrame::ChangeScreenSize %d", (back ? 1 : 0)
+ return back;
+}
+
+
+/* __CHANGE__ 008: Remove OnIdle if no idle processing required.
+*/
+
+void
+ScreenSizeFrame::OnIdle(wxIdleEvent & event)
+{
+#if AUTO_EXIT_ONLY_ON_SUCCESS
+ bool bSuccess;
+#endif
+ $? "+ ScreenSizeFrame::OnIdle"
+ /* __CHANGE__
+ */
+ if (bActive) {
+ switch (oAsc.GetReaction()) {
+#if 0
+ case DK4WX_AUTOSTART_REACTION_IGNORE : {
+ } break;
+#endif
+ case DK4WX_AUTOSTART_REACTION_START : {
+ oAsc.StartProcessing();
+#if AUTO_EXIT_ONLY_ON_SUCCESS
+ bSuccess = ChangeScreenSize();
+ oAsc.EndProcessing(bSuccess);
+#else
+ (void)ChangeScreenSize();
+ oAsc.EndProcessing(true);
+#endif
+ } break;
+ case DK4WX_AUTOSTART_REACTION_MORE : {
+ } break;
+ case DK4WX_AUTOSTART_REACTION_EXIT : {
+ bActive = false;
+ Close();
+ } break;
+ }
+ event.RequestMore();
+ }
+ $? "- ScreenSizeFrame::OnIdle"
+ event.Skip();
+}
+
+
+/* vim: set ai sw=4 ts=4 : */
+
diff --git a/support/dktools/TODO b/support/dktools/TODO
new file mode 100644
index 0000000000..3bb67beb0f
--- /dev/null
+++ b/support/dktools/TODO
@@ -0,0 +1,15 @@
+dk4strmco-Modul kontrollieren:
+Resourcen-Freigabe noch nicht drin beim Schließen des Streams.
+
+png_set_packing(), falls weniger als 8 bits per component
+
+dk4strmu-Modul
+
+- bmeps-Modul
+
+- PDF-Modul
+
+- EPS-Modul
+
+- wxDraw
+
diff --git a/support/dktools/WinprintApp.cpp b/support/dktools/WinprintApp.cpp
new file mode 100644
index 0000000000..4493c11cd0
--- /dev/null
+++ b/support/dktools/WinprintApp.cpp
@@ -0,0 +1,556 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: WinprintApp.cpt
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file WinprintApp.cpp The WinprintApp module.
+*/
+
+
+#line 91 "WinprintApp.cpt"
+
+#include "winprint.h"
+
+
+
+
+#line 96 "WinprintApp.cpt"
+
+
+
+/** Localized wxChar texts.
+*/
+static wxChar const * winprint_texts[] = {
+/* 0 */
+wxT("File"),
+
+/* 1 */
+wxT("Exit"),
+
+/* 2 */
+wxT("Exit the application"),
+
+/* 3 */
+wxT("Help"),
+
+/* 4 */
+wxT("About"),
+
+/* 5 */
+wxT("Show version information"),
+
+/* 6 */
+wxT("Contents"),
+
+/* 7 */
+wxT("Open table of contents"),
+
+/* 8 */
+wxT("Ready"),
+
+/* 9 */
+wxT("Copyright (c) "),
+
+/* 10 */
+wxT("About "),
+
+/* 11 */
+wxT("This program uses the following libraries:"),
+
+/* 12 */
+wxT("See:"),
+
+/* 13 */
+wxT("Initializing print queue names."),
+
+/* 14 */
+wxT("Success, exiting."),
+
+/* 15 */
+wxT("Print"),
+
+/* 16 */
+wxT("Schedule a file to printer."),
+
+/* 17 */
+wxT("Transferring print data."),
+
+/* 18 */
+wxT("Choose file to print"),
+
+/* 19 */
+wxT("Aborted by user!"),
+
+/* 20 */
+wxT("Data transfer"),
+
+/* 21 */
+wxT("Cancel"),
+
+/* 22 */
+wxT("Cancel data transfer"),
+
+/* 23 */
+wxT("Data transfer cancelled, wait please..."),
+
+/* 24 */
+wxT("ERROR: Bad printer name!"),
+
+/* 25 */
+wxT("ERROR: No default printer found!"),
+
+/* 26 */
+wxT("ERROR: Failed to obtain print configuration!"),
+
+/* 27 */
+wxT("ERROR: Failed to create background thread!"),
+
+/* 28 */
+wxT("ERROR: Failed to create progress dialog!"),
+
+/* 29 */
+wxT("Error while scheduling print data"),
+
+/* 30 */
+wxT("Printer selection"),
+
+/* 31 */
+wxT("Choose printer:"),
+
+/* 32 */
+wxT("OK"),
+
+/* 33 */
+wxT("Use selected printer."),
+
+/* 34 */
+wxT("Cancel"),
+
+/* 35 */
+wxT("Abort operation"),
+
+/* 36 */
+wxT("Choose the destination printer"),
+
+/* 37 */
+wxT("Transfer completed."),
+
+/* 38 */
+wxT("Error while writing print data to job file!"),
+
+/* 39 */
+wxT("Failed to open input file!"),
+
+/* 40 */
+wxT("Failed to schedule job to print queue!"),
+
+/* 41 */
+wxT("Failed to create print job data file!"),
+
+/* 42 */
+wxT("Failed to add print job to queue!"),
+
+/* 43 */
+wxT("Failed to open print queue!"),
+
+/* 44 */
+wxT("File name conversion failed!"),
+
+/* 45 */
+wxT("Printer name conversion failed!"),
+
+NULL
+
+
+#line 288 "WinprintApp.cpt"
+};
+
+
+
+/** Non-localized wxChar texts.
+*/
+static wxChar const * winprint_nl_wx[] = {
+/* 0 */
+wxT("winprint"),
+
+/* 1 */
+wxT("1.0.0"),
+
+/* 2 */
+wxT("Dirk Krause"),
+
+/* 3 */
+wxT("Dirk Krause"),
+
+/* 4 */
+wxT("aaaaa"),
+
+/* 5 */
+wxT("winprint.chm"),
+
+/* 6 */
+wxT("winprint.htb"),
+
+/* 7 */
+wxT(" "),
+
+/* 8 */
+wxT("\n"),
+
+/* 9 */
+wxT("DK tools, wxWidgets, libpng, libjpeg, libtiff, zlib."),
+
+/* 10 */
+wxT("http://dktools.sourceforge.net"),
+
+/* 11 */
+wxT("http://www.wxwidgets.org"),
+
+/* 12 */
+wxT("http://www.libpng.org/pub/png/libpng.html"),
+
+/* 13 */
+wxT("http://www.ijg.org"),
+
+/* 14 */
+wxT("http://www.remotesensing.org/libtiff"),
+
+/* 15 */
+wxT("http://www.zlib.net"),
+
+/* 16 */
+wxT("Error"),
+
+/* 17 */
+wxT("Not enough memory (RAM)!"),
+
+NULL
+
+
+#line 350 "WinprintApp.cpt"
+};
+
+
+
+/** Non-localized dkChar texts.
+*/
+static dkChar const * winprint_nl_dk[] = {
+/* 0 */
+dkT("dktools"),
+
+/* 1 */
+dkT("winprint.str"),
+
+NULL
+
+
+#line 367 "WinprintApp.cpt"
+};
+
+
+
+/** Implementation of the wxApp functionality.
+*/
+IMPLEMENT_APP(WinprintApp)
+
+
+bool
+WinprintApp::OnInit()
+{
+ WinprintFrame *frame = NULL; /* Main window to show. */
+ wxChar const * const *localizedTexts = NULL; /* Localized texts. */
+ wxPNGHandler *phPng = NULL;
+ wxXPMHandler *phXpm = NULL;
+ wxICOHandler *phIco = NULL;
+ wxZipFSHandler *phZipFs = NULL;
+ bool back = false;
+
+
+
+#line 388 "WinprintApp.cpt"
+
+ /* Initialize members. */
+ nDefPrinter = 0;
+ pNames = NULL;
+ pHelper = NULL;
+ helpController = NULL;
+ pc = NULL;
+
+ /* __CHANGE__ 009: Initialize further members here.
+ */
+
+ /* Set up helper object. */
+ pHelper = new DkWxAppHelper(
+ argv[0],
+ winprint_nl_wx[3],
+ winprint_nl_dk[0]
+ );
+ if(!(pHelper)) { ShowMemoryErrorMessage(); goto finished; }
+ if(!(pHelper->checkSetup())) { goto finished; }
+
+ /* Add image and file system handlers for online help. */
+ phPng = new wxPNGHandler();
+ if (NULL != phPng) {
+ wxImage::AddHandler(phPng);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phXpm = new wxXPMHandler();
+ if (NULL != phXpm) {
+ wxImage::AddHandler(phXpm);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phIco = new wxICOHandler();
+ if (NULL != phIco) {
+ wxImage::AddHandler(phIco);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phZipFs = new wxZipFSHandler();
+ if (NULL != phZipFs) {
+ wxFileSystem::AddHandler(phZipFs);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ localizedTexts = pHelper->getStringTable(winprint_texts, winprint_nl_dk[1]);
+ if(!(localizedTexts)) { localizedTexts = winprint_texts; }
+
+ /* Set up online help controller. */
+ helpController = new DkWxHelpController(
+ pHelper,
+ winprint_nl_wx[5],
+ winprint_nl_wx[6]
+ );
+ if(!(helpController)) { ShowMemoryErrorMessage(); goto finished; }
+
+ pc = dk3print_conf_open(pHelper->getApp(), 0);
+ if(!(pc)) { ShowMemoryErrorMessage(); goto finished; }
+
+ setPrinterNames();
+ if(!(pNames)) { ShowMemoryErrorMessage(); goto finished; }
+
+ /* Create and show frame. */
+ frame = new WinprintFrame(
+ WinprintFrame_MainWindow,
+ pHelper,
+ helpController,
+ argc,
+ argv,
+ localizedTexts,
+ winprint_nl_wx,
+ winprint_nl_dk,
+ pc,
+ pNames,
+ nNames,
+ nDefPrinter
+ );
+ if(!(frame)) { ShowMemoryErrorMessage(); goto finished; }
+ frame->Show();
+ frame->restorePosition();
+ back = true;
+
+ /* Release resources if initialization failed. */
+ finished:
+ if(!(back)) {
+ if(pNames) {
+ releasePrinterNames();
+ }
+ if(helpController) {
+ delete(helpController);
+ helpController = NULL;
+ }
+ if(pHelper) {
+ delete(pHelper);
+ pHelper = NULL;
+ }
+ if(pc) {
+ dk3print_conf_close(pc);
+ pc = NULL;
+ }
+ }
+ return back;
+}
+
+
+
+int
+WinprintApp::OnExit()
+{
+ int back = 0;
+
+ /* __CHANGE__ 009: Release resources allocated by further members.
+ */
+
+ /* Release resources. */
+ if(pNames) {
+ releasePrinterNames();
+ }
+ if(pc) {
+ dk3print_conf_close(pc);
+ pc = NULL;
+ }
+ if(helpController) {
+ delete(helpController);
+ helpController = NULL;
+ }
+ if(pHelper) {
+ delete(pHelper);
+ pHelper = NULL;
+ }
+
+
+
+#line 525 "WinprintApp.cpt"
+
+ /* __CHANGE__ 010: Set back to exit status code.
+ */
+ return back;
+}
+
+
+
+void
+WinprintApp::setPrinterNames(void)
+{
+ wxChar buf[512]; /* Conversion buffer. */
+ void *vptr; /* Printer as returned from iterator. */
+ dk3_printer_t *pr; /* Current printer. */
+ DK3_PCWXCHAR *wxptr; /* Printer name in wxChar. */
+ size_t n = 0; /* Number of printers. */
+ size_t i; /* Index of current printer. */
+ int wxe; /* wxChar encoding. */
+ int dke; /* dkChar encoding. */
+
+ if(pc) {
+ dk3sto_it_reset(pc->iPrinters);
+ while(NULL != (vptr = dk3sto_it_next(pc->iPrinters))) {
+ pr = (dk3_printer_t *)vptr;
+ if(DK3_PRINTER_TYPE_WINDOWS == pr->t_p) {
+ if(pr->name) {
+ n++;
+ }
+ }
+ }
+ if(n) {
+ pNames = dk3_new_app(DK3_PCWXCHAR,n,pHelper->getApp());
+ if(pNames) {
+ wxptr = pNames;
+ for(i = 0; i < n; i++) {
+ *(wxptr++) = NULL;
+ }
+ i = 0;
+ wxptr = pNames;
+ dk3sto_it_reset(pc->iPrinters);
+ while(NULL != (vptr = dk3sto_it_next(pc->iPrinters))) {
+ pr = (dk3_printer_t *)vptr;
+ if(DK3_PRINTER_TYPE_WINDOWS == pr->t_p) {
+ if(pr->name) {
+ wxe = pHelper->getWxEncoding();
+ dke = pHelper->getDkEncoding();
+ if(dk3wxs_from_dkstr(buf,DK3_SIZEOF(buf,wxChar),wxe,pr->name,dke))
+ {
+ *wxptr = dk3wxs_dup(buf);
+ if(*wxptr) {
+ if(pc->defPrinter) {
+ if((pc->defPrinter)->name) {
+ if(dk3str_cmp(pr->name, (pc->defPrinter)->name) == 0) {
+ nDefPrinter = (int)i;
+ }
+ }
+ }
+ wxptr++;
+ i++;
+ }
+ }
+ }
+ }
+ }
+ nNames = i;
+ }
+ }
+ }
+}
+
+
+void
+WinprintApp::releasePrinterNames(void)
+{
+ DK3_PCWXCHAR *wxptr; /* Current printer name to release. */
+ size_t i; /* Index of current printer name. */
+
+
+#line 602 "WinprintApp.cpt"
+ if(pNames) {
+ wxptr = pNames;
+ for(i = 0; i < nNames; i++) {
+ if(*wxptr) {
+
+
+#line 607 "WinprintApp.cpt"
+ dk3_release(*wxptr);
+ wxptr++;
+ }
+ }
+ dk3_delete(pNames);
+ pNames = NULL;
+ }
+
+#line 614 "WinprintApp.cpt"
+}
+
+
+
+void
+WinprintApp::ShowMemoryErrorMessage(void)
+{
+ const wxChar *s_title = NULL;
+ const wxChar *s_text = NULL;
+
+ if (NULL != pHelper) {
+ s_title = pHelper->getBasicString(3);
+ s_text = pHelper->getBasicString(9);
+ }
+ if (NULL == s_title) {
+ s_title = winprint_nl_wx[16];
+ }
+ if (NULL == s_text) {
+ s_text = winprint_nl_wx[17];
+ }
+ wxMessageBox(s_text, s_title, (wxOK | wxCENTRE | wxICON_ERROR));
+}
diff --git a/support/dktools/WinprintApp.cpt b/support/dktools/WinprintApp.cpt
new file mode 100644
index 0000000000..e2784892bb
--- /dev/null
+++ b/support/dktools/WinprintApp.cpt
@@ -0,0 +1,635 @@
+%% options
+
+# __CHANGE__ 001: Correct copyright owner if necessary.
+copyright owner = Dirk Krause
+
+# __CHANGE__ 003: Correct copyright year(s) if necessary.
+copyright year = 2013-xxxx
+
+# __CHANGE__ 002: Correct license type if necessary.
+# Use "bsd", "gpl", "lgpl", or "commercial".
+license = bsd
+
+
+
+%% header
+
+
+/** Application class, derived from wxApp, one instance per program.
+*/
+class WinprintApp : public wxApp
+{
+ protected:
+
+ /** Helper object.
+ */
+ DkWxAppHelper *pHelper;
+
+ /** Controller fr online help.
+ */
+ DkWxHelpController *helpController;
+
+ /** Print configuration.
+ */
+ dk3_print_conf_t *pc;
+
+ /** Printer names.
+ */
+ DK3_PCWXCHAR *pNames;
+
+ /** Number of elements in pNames.
+ */
+ size_t nNames;
+
+ /** Index of the default printer in pNames.
+ */
+ int nDefPrinter;
+
+ protected:
+
+ /** Show error message if there is not sufficient memory available.
+ */
+ void
+ ShowMemoryErrorMessage(void);
+
+ public:
+
+ /** Application initialization.
+ @return true on success, false on error.
+ */
+ virtual
+ bool
+ OnInit();
+
+ /** Application shutdown.
+ @return 0 on success, any other value indicates an error.
+ */
+ virtual
+ int
+ OnExit();
+
+ protected:
+
+ /** Set printer names.
+ */
+ void setPrinterNames(void);
+
+ /** Release printer names.
+ */
+ void releasePrinterNames(void);
+};
+
+
+
+/** Declaration as the wxApp object.
+*/
+DECLARE_APP(WinprintApp)
+
+
+
+%% module
+
+#include "winprint.h"
+
+
+$!trace-include
+
+
+
+/** Localized wxChar texts.
+*/
+static wxChar const * winprint_texts[] = {
+$!string-table macro=wxT
+#
+# 0: Menu "File"
+#
+File
+#
+# 1: Menu item "File/Exit"
+#
+Exit
+#
+# 2: Tool tip text for menu item "File/Exit"
+#
+Exit the application
+#
+# 3: Menu "Help"
+#
+Help
+#
+# 4: Menu item "Help/About"
+#
+About
+#
+# 5: Tooltip text for menu item "Help/About"
+#
+Show version information
+#
+# 6: Menu item "Help/Contents"
+#
+Contents
+#
+# 7: Tooltip text for menu item "Help/Contents"
+#
+Open table of contents
+#
+# 8: Initial status text
+#
+Ready
+#
+# 9: Copyright notice.
+#
+Copyright (c)
+#
+# 10: Dialog box title "About ..."
+#
+About
+#
+# 11: This program uses the following libraries
+#
+This program uses the following libraries:
+#
+# 12: See
+#
+See:
+#
+# 13: __CHANGE__ 015: Text for dummy label, can be reused if lDummy removed.
+#
+Initializing print queue names.
+#
+# 14
+#
+Success, exiting.
+#
+# 15
+#
+Print
+#
+# 16
+#
+Schedule a file to printer.
+#
+# 17
+#
+Transferring print data.
+#
+# 18
+#
+Choose file to print
+#
+# 19
+#
+Aborted by user!
+#
+# 20
+#
+Data transfer
+#
+# 21
+#
+Cancel
+#
+# 22
+#
+Cancel data transfer
+#
+# 23
+#
+Data transfer cancelled, wait please...
+#
+# 24
+#
+ERROR: Bad printer name!
+#
+# 25
+#
+ERROR: No default printer found!
+#
+# 26
+#
+ERROR: Failed to obtain print configuration!
+#
+# 27
+#
+ERROR: Failed to create background thread!
+#
+# 28
+#
+ERROR: Failed to create progress dialog!
+#
+# 29
+#
+Error while scheduling print data
+#
+# 30
+#
+Printer selection
+#
+# 31
+#
+Choose printer:
+#
+# 32
+#
+OK
+#
+# 33
+#
+Use selected printer.
+#
+# 34
+#
+Cancel
+#
+# 35
+#
+Abort operation
+#
+# 36
+#
+Choose the destination printer
+#
+# 37
+#
+Transfer completed.
+#
+# 38
+#
+Error while writing print data to job file!
+#
+# 39
+#
+Failed to open input file!
+#
+# 40
+#
+Failed to schedule job to print queue!
+#
+# 41
+#
+Failed to create print job data file!
+#
+# 42
+#
+Failed to add print job to queue!
+#
+# 43
+#
+Failed to open print queue!
+#
+# 44
+#
+File name conversion failed!
+#
+# 45
+#
+Printer name conversion failed!
+$!end
+};
+
+
+
+/** Non-localized wxChar texts.
+*/
+static wxChar const * winprint_nl_wx[] = {
+$!string-table macro=wxT
+#
+# 0: Program name. __CHANGE__ 004: Correct program name.
+#
+winprint
+#
+# 1: Program version. __CHANGE__ 005: Correct program version.
+#
+1.0.0
+#
+# 2: Copyright owner name. __CHANGE__ 001: Correct copyright owner name.
+#
+Dirk Krause
+#
+# 3: Software vendor name. __CHANGE__ 007: Correct software vendor name
+# if necessary. Must be one
+# string without spaces.
+#
+Dirk Krause
+#
+# 4: Resource name of Windows icon
+#
+aaaaa
+#
+# 5: Windows chm help file name
+#
+winprint.chm
+#
+# 6: non-Windows htb help file name
+#
+winprint.htb
+#
+# 7: Space
+#
+
+#
+# 8: Newline
+#
+\n
+#
+# 9 10 11 12 13 14 15: List of libraries used.
+#
+DK tools, wxWidgets, libpng, libjpeg, libtiff, zlib.
+http://dktools.sourceforge.net
+http://www.wxwidgets.org
+http://www.libpng.org/pub/png/libpng.html
+http://www.ijg.org
+http://www.remotesensing.org/libtiff
+http://www.zlib.net
+#
+# 16 17
+#
+Error
+Not enough memory (RAM)!
+$!end
+};
+
+
+
+/** Non-localized dkChar texts.
+*/
+static dkChar const * winprint_nl_dk[] = {
+$!string-table macro=dkT
+#
+# 0: Program group name. __CHANGE__ 006: Correct program group name.
+#
+dktools
+#
+# 1: String table name.
+#
+winprint.str
+$!end
+};
+
+
+
+/** Implementation of the wxApp functionality.
+*/
+IMPLEMENT_APP(WinprintApp)
+
+
+bool
+WinprintApp::OnInit()
+{
+ WinprintFrame *frame = NULL; /* Main window to show. */
+ wxChar const * const *localizedTexts = NULL; /* Localized texts. */
+ wxPNGHandler *phPng = NULL;
+ wxXPMHandler *phXpm = NULL;
+ wxICOHandler *phIco = NULL;
+ wxZipFSHandler *phZipFs = NULL;
+ bool back = false;
+
+ $!trace-init winprint.deb
+
+ /* Initialize members. */
+ nDefPrinter = 0;
+ pNames = NULL;
+ pHelper = NULL;
+ helpController = NULL;
+ pc = NULL;
+
+ /* __CHANGE__ 009: Initialize further members here.
+ */
+
+ /* Set up helper object. */
+ pHelper = new DkWxAppHelper(
+ argv[0],
+ winprint_nl_wx[3],
+ winprint_nl_dk[0]
+ );
+ if(!(pHelper)) { ShowMemoryErrorMessage(); goto finished; }
+ if(!(pHelper->checkSetup())) { goto finished; }
+
+ /* Add image and file system handlers for online help. */
+ phPng = new wxPNGHandler();
+ if (NULL != phPng) {
+ wxImage::AddHandler(phPng);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phXpm = new wxXPMHandler();
+ if (NULL != phXpm) {
+ wxImage::AddHandler(phXpm);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phIco = new wxICOHandler();
+ if (NULL != phIco) {
+ wxImage::AddHandler(phIco);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phZipFs = new wxZipFSHandler();
+ if (NULL != phZipFs) {
+ wxFileSystem::AddHandler(phZipFs);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ localizedTexts = pHelper->getStringTable(winprint_texts, winprint_nl_dk[1]);
+ if(!(localizedTexts)) { localizedTexts = winprint_texts; }
+
+ /* Set up online help controller. */
+ helpController = new DkWxHelpController(
+ pHelper,
+ winprint_nl_wx[5],
+ winprint_nl_wx[6]
+ );
+ if(!(helpController)) { ShowMemoryErrorMessage(); goto finished; }
+
+ pc = dk3print_conf_open(pHelper->getApp(), 0);
+ if(!(pc)) { ShowMemoryErrorMessage(); goto finished; }
+
+ setPrinterNames();
+ if(!(pNames)) { ShowMemoryErrorMessage(); goto finished; }
+
+ /* Create and show frame. */
+ frame = new WinprintFrame(
+ WinprintFrame_MainWindow,
+ pHelper,
+ helpController,
+ argc,
+ argv,
+ localizedTexts,
+ winprint_nl_wx,
+ winprint_nl_dk,
+ pc,
+ pNames,
+ nNames,
+ nDefPrinter
+ );
+ if(!(frame)) { ShowMemoryErrorMessage(); goto finished; }
+ frame->Show();
+ frame->restorePosition();
+ back = true;
+
+ /* Release resources if initialization failed. */
+ finished:
+ if(!(back)) {
+ if(pNames) {
+ releasePrinterNames();
+ }
+ if(helpController) {
+ delete(helpController);
+ helpController = NULL;
+ }
+ if(pHelper) {
+ delete(pHelper);
+ pHelper = NULL;
+ }
+ if(pc) {
+ dk3print_conf_close(pc);
+ pc = NULL;
+ }
+ }
+ return back;
+}
+
+
+
+int
+WinprintApp::OnExit()
+{
+ int back = 0;
+
+ /* __CHANGE__ 009: Release resources allocated by further members.
+ */
+
+ /* Release resources. */
+ if(pNames) {
+ releasePrinterNames();
+ }
+ if(pc) {
+ dk3print_conf_close(pc);
+ pc = NULL;
+ }
+ if(helpController) {
+ delete(helpController);
+ helpController = NULL;
+ }
+ if(pHelper) {
+ delete(pHelper);
+ pHelper = NULL;
+ }
+
+ $!trace-end
+
+ /* __CHANGE__ 010: Set back to exit status code.
+ */
+ return back;
+}
+
+
+
+void
+WinprintApp::setPrinterNames(void)
+{
+ wxChar buf[512]; /* Conversion buffer. */
+ void *vptr; /* Printer as returned from iterator. */
+ dk3_printer_t *pr; /* Current printer. */
+ DK3_PCWXCHAR *wxptr; /* Printer name in wxChar. */
+ size_t n = 0; /* Number of printers. */
+ size_t i; /* Index of current printer. */
+ int wxe; /* wxChar encoding. */
+ int dke; /* dkChar encoding. */
+
+ if(pc) {
+ dk3sto_it_reset(pc->iPrinters);
+ while(NULL != (vptr = dk3sto_it_next(pc->iPrinters))) {
+ pr = (dk3_printer_t *)vptr;
+ if(DK3_PRINTER_TYPE_WINDOWS == pr->t_p) {
+ if(pr->name) {
+ n++;
+ }
+ }
+ }
+ if(n) {
+ pNames = dk3_new_app(DK3_PCWXCHAR,n,pHelper->getApp());
+ if(pNames) {
+ wxptr = pNames;
+ for(i = 0; i < n; i++) {
+ *(wxptr++) = NULL;
+ }
+ i = 0;
+ wxptr = pNames;
+ dk3sto_it_reset(pc->iPrinters);
+ while(NULL != (vptr = dk3sto_it_next(pc->iPrinters))) {
+ pr = (dk3_printer_t *)vptr;
+ if(DK3_PRINTER_TYPE_WINDOWS == pr->t_p) {
+ if(pr->name) {
+ wxe = pHelper->getWxEncoding();
+ dke = pHelper->getDkEncoding();
+ if(dk3wxs_from_dkstr(buf,DK3_SIZEOF(buf,wxChar),wxe,pr->name,dke))
+ {
+ *wxptr = dk3wxs_dup(buf);
+ if(*wxptr) {
+ if(pc->defPrinter) {
+ if((pc->defPrinter)->name) {
+ if(dk3str_cmp(pr->name, (pc->defPrinter)->name) == 0) {
+ nDefPrinter = (int)i;
+ }
+ }
+ }
+ wxptr++;
+ i++;
+ }
+ }
+ }
+ }
+ }
+ nNames = i;
+ }
+ }
+ }
+}
+
+
+void
+WinprintApp::releasePrinterNames(void)
+{
+ DK3_PCWXCHAR *wxptr; /* Current printer name to release. */
+ size_t i; /* Index of current printer name. */
+ $? "+ WinprintApp::releasePrinterNames"
+ if(pNames) {
+ wxptr = pNames;
+ for(i = 0; i < nNames; i++) {
+ if(*wxptr) {
+ $? ". Printer name \"%ls\"", *wxptr
+ dk3_release(*wxptr);
+ wxptr++;
+ }
+ }
+ dk3_delete(pNames);
+ pNames = NULL;
+ } $? "- WinprintApp::releasePrinterNames"
+}
+
+
+
+void
+WinprintApp::ShowMemoryErrorMessage(void)
+{
+ const wxChar *s_title = NULL;
+ const wxChar *s_text = NULL;
+
+ if (NULL != pHelper) {
+ s_title = pHelper->getBasicString(3);
+ s_text = pHelper->getBasicString(9);
+ }
+ if (NULL == s_title) {
+ s_title = winprint_nl_wx[16];
+ }
+ if (NULL == s_text) {
+ s_text = winprint_nl_wx[17];
+ }
+ wxMessageBox(s_text, s_title, (wxOK | wxCENTRE | wxICON_ERROR));
+}
diff --git a/support/dktools/WinprintApp.h b/support/dktools/WinprintApp.h
new file mode 100644
index 0000000000..a8f2653369
--- /dev/null
+++ b/support/dktools/WinprintApp.h
@@ -0,0 +1,120 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: WinprintApp.cpt
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file WinprintApp.h Header file for the WinprintApp module.
+*/
+
+#ifndef WINPRINTAPP_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define WINPRINTAPP_H_INCLUDED 1
+
+
+#line 16 "WinprintApp.cpt"
+
+
+/** Application class, derived from wxApp, one instance per program.
+*/
+class WinprintApp : public wxApp
+{
+ protected:
+
+ /** Helper object.
+ */
+ DkWxAppHelper *pHelper;
+
+ /** Controller fr online help.
+ */
+ DkWxHelpController *helpController;
+
+ /** Print configuration.
+ */
+ dk3_print_conf_t *pc;
+
+ /** Printer names.
+ */
+ DK3_PCWXCHAR *pNames;
+
+ /** Number of elements in pNames.
+ */
+ size_t nNames;
+
+ /** Index of the default printer in pNames.
+ */
+ int nDefPrinter;
+
+ protected:
+
+ /** Show error message if there is not sufficient memory available.
+ */
+ void
+ ShowMemoryErrorMessage(void);
+
+ public:
+
+ /** Application initialization.
+ @return true on success, false on error.
+ */
+ virtual
+ bool
+ OnInit();
+
+ /** Application shutdown.
+ @return 0 on success, any other value indicates an error.
+ */
+ virtual
+ int
+ OnExit();
+
+ protected:
+
+ /** Set printer names.
+ */
+ void setPrinterNames(void);
+
+ /** Release printer names.
+ */
+ void releasePrinterNames(void);
+};
+
+
+
+/** Declaration as the wxApp object.
+*/
+DECLARE_APP(WinprintApp)
+
+
+
+
+#endif
diff --git a/support/dktools/WinprintChooserDialog.cpp b/support/dktools/WinprintChooserDialog.cpp
new file mode 100644
index 0000000000..49ebcd19b8
--- /dev/null
+++ b/support/dktools/WinprintChooserDialog.cpp
@@ -0,0 +1,259 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: WinprintChooserDialog.wxc
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file WinprintChooserDialog.cpp The WinprintChooserDialog module.
+*/
+
+
+#line 134 "WinprintChooserDialog.wxc"
+
+#include "winprint.h"
+
+
+
+
+
+#line 140 "WinprintChooserDialog.wxc"
+
+
+/** Event table.
+*/
+BEGIN_EVENT_TABLE(WinprintChooserDialog, wxDialog)
+ EVT_BUTTON(wxID_OK, WinprintChooserDialog::OnOK)
+ EVT_BUTTON(wxID_CANCEL, WinprintChooserDialog::OnCancel)
+END_EVENT_TABLE()
+
+
+
+#line 151 "WinprintChooserDialog.wxc"
+WinprintChooserDialog::WinprintChooserDialog(
+ DkWxFrame *parent,
+ wxChar const *title,
+ wxChar const * const *messageTexts,
+ wxString const *printerNames,
+ size_t numberOfPrinters
+) : wxDialog(
+ parent,
+ wxID_ANY,
+ title,
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxDEFAULT_DIALOG_STYLE
+)
+{
+ sTexts = messageTexts;
+ cbChoosePrinter = NULL;
+ pNames = printerNames;
+ nNames = numberOfPrinters;
+ dkctGUILayoutOK = false;
+ sDialog = NULL;
+ verticalSizer = NULL;
+ sContents = NULL;
+ sButtons = NULL;
+ lChoosePrinter = NULL;
+ bOK = NULL;
+ bCancel = NULL;
+ sDialog = new wxBoxSizer(
+ wxHORIZONTAL
+ );
+ if(!(sDialog)) {
+ goto dkctGUILayoutFinished;
+ }
+ sDialog->Add(10, 10, 1);
+ verticalSizer = new wxBoxSizer(
+ wxVERTICAL
+ );
+ if(!(verticalSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ verticalSizer->Add(10, 10, 1);
+ sContents = new wxGridBagSizer(
+ 5, 5
+ );
+ if(!(sContents)) {
+ goto dkctGUILayoutFinished;
+ }
+ lChoosePrinter = new wxStaticText(
+ this,
+ wxID_ANY,
+ sTexts[31]
+ );
+ if(!(lChoosePrinter)) {
+ goto dkctGUILayoutFinished;
+ }
+ sContents->Add(
+ lChoosePrinter,
+ wxGBPosition(0, 0),
+ wxGBSpan(1, 1)
+ );
+ verticalSizer->Add(
+ sContents
+ );
+ verticalSizer->Add(10, 10, 1);
+ sButtons = new wxStdDialogButtonSizer(
+ );
+ if(!(sButtons)) {
+ goto dkctGUILayoutFinished;
+ }
+ bOK = new wxButton(
+ this,
+ wxID_OK,
+ sTexts[32]
+ );
+ if(!(bOK)) {
+ goto dkctGUILayoutFinished;
+ }
+ bOK->SetToolTip(sTexts[33]);
+ sButtons->AddButton(
+ bOK
+ );
+ bCancel = new wxButton(
+ this,
+ wxID_CANCEL,
+ sTexts[34]
+ );
+ if(!(bCancel)) {
+ goto dkctGUILayoutFinished;
+ }
+ bCancel->SetToolTip(sTexts[35]);
+ sButtons->AddButton(
+ bCancel
+ );
+ sButtons->Realize();
+ verticalSizer->Add(
+ sButtons,
+ 0,
+ wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL
+ );
+ verticalSizer->Add(10, 10, 1);
+ sDialog->Add(
+ verticalSizer,
+ 0,
+ wxGROW
+ );
+ sDialog->Add(10, 10, 1);
+ SetSizer(sDialog);
+ dkctGUILayoutOK = true;
+ dkctGUILayoutFinished:
+ if(dkctGUILayoutOK) {
+ sDialog->Fit(this);
+ sDialog->SetSizeHints(this);
+ }
+
+#line 171 "WinprintChooserDialog.wxc"
+ if(dkctGUILayoutOK) {
+ if((pNames) && (nNames > 0)) {
+#if VERSION_BEFORE_20140929
+ cbChoosePrinter = new wxChoice(
+ this, wxID_ANY, wxDefaultPosition, wxDefaultSize, nNames, pNames
+ );
+#else
+ if ((dk3_um_t)DK3_I_MAX >= (dk3_um_t)nNames) {
+ cbChoosePrinter = new wxChoice(
+ this, wxID_ANY, wxDefaultPosition, wxDefaultSize, (int)nNames, pNames
+ );
+ }
+#endif
+ if(cbChoosePrinter) {
+ cbChoosePrinter->SetToolTip(sTexts[36]);
+ sContents->Add( cbChoosePrinter, wxGBPosition(0, 1), wxGBSpan(2, 1));
+ sDialog->Fit(this);
+ sDialog->SetSizeHints(this);
+ }
+ }
+ }
+}
+
+
+#line 195 "WinprintChooserDialog.wxc"
+
+
+void
+WinprintChooserDialog::setCurrentPrinter(int i)
+{
+ unsigned count; /* Number of printers in chooser. */
+ int val; /* Corrected index. */
+ if(cbChoosePrinter) {
+ count = cbChoosePrinter->GetCount();
+ val = i;
+ if(i > ((int)count - 1)) {
+ val = (int)count - 1;
+ }
+ if(val < 0) {
+ val = 0;
+ }
+ cbChoosePrinter->SetSelection(val);
+ }
+}
+
+
+
+int
+WinprintChooserDialog::getCurrentPrinter(void)
+{
+ int back = wxNOT_FOUND;
+ if(cbChoosePrinter) {
+ back = cbChoosePrinter->GetSelection();
+ }
+ return back;
+}
+
+
+
+void
+WinprintChooserDialog::OnOK(wxCommandEvent & event)
+{
+ if(IsModal()) {
+ EndModal(wxID_OK);
+ } else {
+ SetReturnCode(wxID_OK);
+ Show(false);
+ }
+}
+
+
+
+void
+WinprintChooserDialog::OnCancel(wxCommandEvent & event)
+{
+ if(IsModal()) {
+ EndModal(wxID_CANCEL);
+ } else {
+ SetReturnCode(wxID_CANCEL);
+ Show(false);
+ }
+}
+
+
diff --git a/support/dktools/WinprintChooserDialog.h b/support/dktools/WinprintChooserDialog.h
new file mode 100644
index 0000000000..0512be7213
--- /dev/null
+++ b/support/dktools/WinprintChooserDialog.h
@@ -0,0 +1,164 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: WinprintChooserDialog.wxc
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file WinprintChooserDialog.h Header file for the WinprintChooserDialog module.
+*/
+
+#ifndef WINPRINTCHOOSERDIALOG_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define WINPRINTCHOOSERDIALOG_H_INCLUDED 1
+
+
+#line 57 "WinprintChooserDialog.wxc"
+
+
+#line 59 "WinprintChooserDialog.wxc"
+/** Dialog to choose a printer.
+*/
+class WinprintChooserDialog : public wxDialog
+{
+ private:
+ /** Event table.
+ */
+ DECLARE_EVENT_TABLE()
+
+ /** Flag: GUI ok.
+ */
+ bool dkctGUILayoutOK;
+
+ /** GUI element sDialog.
+ */
+#line 13 "WinprintChooserDialog.wxc"
+ wxBoxSizer *sDialog;
+
+ /** GUI element verticalSizer.
+ */
+#line 19 "WinprintChooserDialog.wxc"
+ wxBoxSizer *verticalSizer;
+
+ /** GUI element sContents.
+ */
+#line 28 "WinprintChooserDialog.wxc"
+ wxGridBagSizer *sContents;
+
+ /** GUI element sButtons.
+ */
+#line 40 "WinprintChooserDialog.wxc"
+ wxStdDialogButtonSizer *sButtons;
+
+ /** GUI element lChoosePrinter.
+ */
+#line 33 "WinprintChooserDialog.wxc"
+ wxStaticText *lChoosePrinter;
+
+ /** GUI element bOK.
+ */
+#line 44 "WinprintChooserDialog.wxc"
+ wxButton *bOK;
+
+ /** GUI element bCancel.
+ */
+#line 49 "WinprintChooserDialog.wxc"
+ wxButton *bCancel;
+
+
+#line 69 "WinprintChooserDialog.wxc"
+
+ protected:
+
+ /** Localized texts.
+ */
+ wxChar const * const *sTexts;
+
+ /** Choice box containing the printer names.
+ */
+ wxChoice *cbChoosePrinter;
+
+ /** Printer names.
+ */
+ wxString const *pNames;
+
+ /** Number of printer names available.
+ */
+ size_t nNames;
+
+ public:
+
+ /** Constructor.
+ @param parent Parent frame.
+ @param title Dialog title.
+ @param messageTexts Localized texts used in dialog.
+ @param printerNames Printer names array.
+ @param numberOfPrinters Number of printers found.
+ */
+ WinprintChooserDialog(
+ DkWxFrame *parent,
+ wxChar const *title,
+ wxChar const * const *messageTexts,
+ wxString const *printerNames,
+ size_t numberOfPrinters
+ );
+
+ /** Set the current printer selection.
+ @param i Index of the new selection.
+ */
+ void
+ setCurrentPrinter(int i);
+
+ /** Get current printer selection.
+ @return Index of the current selection.
+ */
+ int
+ getCurrentPrinter(void);
+
+ /** Handler for OK button.
+ @param event Event to process.
+ */
+ void
+ OnOK(wxCommandEvent & event);
+
+ /** Handler for Cancel button.
+ @param event Event to process.
+ */
+ void
+ OnCancel(wxCommandEvent & event);
+
+};
+
+
+#line 132 "WinprintChooserDialog.wxc"
+
+
+#endif
diff --git a/support/dktools/WinprintChooserDialog.wxc b/support/dktools/WinprintChooserDialog.wxc
new file mode 100644
index 0000000000..d6bc73dc2b
--- /dev/null
+++ b/support/dktools/WinprintChooserDialog.wxc
@@ -0,0 +1,253 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2013-xxxx
+license = bsd
+
+%% wx-gui
+
+type = dialog
+contents = sDialog
+# title = sTexts[30]
+
+[wxBoxSizer sDialog]
+direction = horizontal
+contents = $stretch(10)
+contents = verticalSizer
+contents = $stretch(10)
+
+[wxBoxSizer verticalSizer]
+direction = vertical
+grow = yes
+contents = $stretch(10)
+contents = sContents
+contents = $stretch(10)
+contents = sButtons centered
+contents = $stretch(10)
+
+[wxGridBagSizer sContents]
+grid = 5 5
+contents = lChoosePrinter 0 0 1 1
+# contents = cbChoosePrinter 0 +1 2 1
+
+[wxStaticText lChoosePrinter]
+text = sTexts[31]
+
+# [wxChoice cbChoosePrinter]
+# choices = 2 pNames
+# tip = sTexts[36]
+
+[wxStdDialogButtonSizer sButtons]
+contents = bOK
+contents = bCancel
+
+[wxButton bOK]
+id = wxID_OK
+text = sTexts[32]
+tip = sTexts[33]
+
+[wxButton bCancel]
+id = wxID_CANCEL
+text = sTexts[34]
+tip = sTexts[35]
+
+
+
+%% header start
+
+%% class start
+/** Dialog to choose a printer.
+*/
+class WinprintChooserDialog : public wxDialog
+{
+ private:
+ /** Event table.
+ */
+ DECLARE_EVENT_TABLE()
+
+%% class end
+
+ protected:
+
+ /** Localized texts.
+ */
+ wxChar const * const *sTexts;
+
+ /** Choice box containing the printer names.
+ */
+ wxChoice *cbChoosePrinter;
+
+ /** Printer names.
+ */
+ wxString const *pNames;
+
+ /** Number of printer names available.
+ */
+ size_t nNames;
+
+ public:
+
+ /** Constructor.
+ @param parent Parent frame.
+ @param title Dialog title.
+ @param messageTexts Localized texts used in dialog.
+ @param printerNames Printer names array.
+ @param numberOfPrinters Number of printers found.
+ */
+ WinprintChooserDialog(
+ DkWxFrame *parent,
+ wxChar const *title,
+ wxChar const * const *messageTexts,
+ wxString const *printerNames,
+ size_t numberOfPrinters
+ );
+
+ /** Set the current printer selection.
+ @param i Index of the new selection.
+ */
+ void
+ setCurrentPrinter(int i);
+
+ /** Get current printer selection.
+ @return Index of the current selection.
+ */
+ int
+ getCurrentPrinter(void);
+
+ /** Handler for OK button.
+ @param event Event to process.
+ */
+ void
+ OnOK(wxCommandEvent & event);
+
+ /** Handler for Cancel button.
+ @param event Event to process.
+ */
+ void
+ OnCancel(wxCommandEvent & event);
+
+};
+
+%% header end
+
+%% module start
+
+#include "winprint.h"
+
+
+
+$!trace-include
+
+
+/** Event table.
+*/
+BEGIN_EVENT_TABLE(WinprintChooserDialog, wxDialog)
+ EVT_BUTTON(wxID_OK, WinprintChooserDialog::OnOK)
+ EVT_BUTTON(wxID_CANCEL, WinprintChooserDialog::OnCancel)
+END_EVENT_TABLE()
+
+
+%% constructor start
+WinprintChooserDialog::WinprintChooserDialog(
+ DkWxFrame *parent,
+ wxChar const *title,
+ wxChar const * const *messageTexts,
+ wxString const *printerNames,
+ size_t numberOfPrinters
+) : wxDialog(
+ parent,
+ wxID_ANY,
+ title,
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxDEFAULT_DIALOG_STYLE
+)
+{
+ sTexts = messageTexts;
+ cbChoosePrinter = NULL;
+ pNames = printerNames;
+ nNames = numberOfPrinters;
+%% constructor end
+ if(dkctGUILayoutOK) {
+ if((pNames) && (nNames > 0)) {
+#if VERSION_BEFORE_20140929
+ cbChoosePrinter = new wxChoice(
+ this, wxID_ANY, wxDefaultPosition, wxDefaultSize, nNames, pNames
+ );
+#else
+ if ((dk3_um_t)DK3_I_MAX >= (dk3_um_t)nNames) {
+ cbChoosePrinter = new wxChoice(
+ this, wxID_ANY, wxDefaultPosition, wxDefaultSize, (int)nNames, pNames
+ );
+ }
+#endif
+ if(cbChoosePrinter) {
+ cbChoosePrinter->SetToolTip(sTexts[36]);
+ sContents->Add( cbChoosePrinter, wxGBPosition(0, 1), wxGBSpan(2, 1));
+ sDialog->Fit(this);
+ sDialog->SetSizeHints(this);
+ }
+ }
+ }
+}
+
+%% module end
+
+
+void
+WinprintChooserDialog::setCurrentPrinter(int i)
+{
+ unsigned count; /* Number of printers in chooser. */
+ int val; /* Corrected index. */
+ if(cbChoosePrinter) {
+ count = cbChoosePrinter->GetCount();
+ val = i;
+ if(i > ((int)count - 1)) {
+ val = (int)count - 1;
+ }
+ if(val < 0) {
+ val = 0;
+ }
+ cbChoosePrinter->SetSelection(val);
+ }
+}
+
+
+
+int
+WinprintChooserDialog::getCurrentPrinter(void)
+{
+ int back = wxNOT_FOUND;
+ if(cbChoosePrinter) {
+ back = cbChoosePrinter->GetSelection();
+ }
+ return back;
+}
+
+
+
+void
+WinprintChooserDialog::OnOK(wxCommandEvent & event)
+{
+ if(IsModal()) {
+ EndModal(wxID_OK);
+ } else {
+ SetReturnCode(wxID_OK);
+ Show(false);
+ }
+}
+
+
+
+void
+WinprintChooserDialog::OnCancel(wxCommandEvent & event)
+{
+ if(IsModal()) {
+ EndModal(wxID_CANCEL);
+ } else {
+ SetReturnCode(wxID_CANCEL);
+ Show(false);
+ }
+}
+
+
diff --git a/support/dktools/WinprintFrame.cpp b/support/dktools/WinprintFrame.cpp
new file mode 100644
index 0000000000..24fbcfe9db
--- /dev/null
+++ b/support/dktools/WinprintFrame.cpp
@@ -0,0 +1,923 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: WinprintFrame.wxc
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file WinprintFrame.cpp The WinprintFrame module.
+*/
+
+
+#line 303 "WinprintFrame.wxc"
+
+#include "winprint.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4verswx.h"
+#include "dk4verswx.h"
+#include "run-conversion.xpm"
+#include "exit-program.xpm"
+
+
+#if !defined(__WXMSW__)
+#include "winprint.xpm"
+#endif
+
+
+
+
+
+#line 321 "WinprintFrame.wxc"
+
+
+
+/* __CHANGE__ 017: Add further events. */
+/* __CHANGE__ 008: Remove OnIdle if no idle processing required. */
+BEGIN_EVENT_TABLE(WinprintFrame, wxFrame)
+ EVT_MENU(WinprintFrame_Quit, WinprintFrame::OnQuit)
+ EVT_MENU(WinprintFrame_Print, WinprintFrame::OnPrint)
+ EVT_MENU(WinprintFrame_Help_About, WinprintFrame::OnAbout)
+ EVT_MENU(WinprintFrame_Help_Contents, WinprintFrame::OnHelpContents)
+ EVT_IDLE(WinprintFrame::OnIdle)
+END_EVENT_TABLE()
+
+
+
+static const wxCmdLineEntryDesc winprint_cmd_line_desc[] = {
+ {
+ wxCMD_LINE_OPTION,
+ wxT_2("P"),
+ wxT_2("printer"),
+ wxT_2("choose printer"),
+ wxCMD_LINE_VAL_STRING
+ },
+ {
+ wxCMD_LINE_SWITCH,
+ wxT_2("d"),
+ wxT_2("default"),
+ wxT_2("Use default printer")
+ },
+ {
+ wxCMD_LINE_PARAM,
+ NULL,
+ NULL,
+ wxT_2("input file"),
+ wxCMD_LINE_VAL_STRING,
+ wxCMD_LINE_PARAM_OPTIONAL
+ },
+ { wxCMD_LINE_NONE }
+};
+
+
+
+#line 363 "WinprintFrame.wxc"
+WinprintFrame::WinprintFrame(
+ int wxid,
+ DkWxAppHelper *applicationHelper,
+ DkWxHelpController *hc,
+ int argc,
+ wxChar **argv,
+ wxChar const * const *localizedTexts,
+ wxChar const * const *nlWx,
+ dkChar const * const *nlDk,
+ dk3_print_conf_t *pPrintConf,
+ DK3_PCWXCHAR *printerNames,
+ size_t numberOfPrinters,
+ int defaultPrinterIndex
+) : DkWxFrame(nlWx[0], applicationHelper, hc, wxid),
+ cBlack(0, 0, 0),
+ cGreen(0, 127, 0),
+ cRed(127, 0, 0)
+{
+ /* __CHANGE__ 012: Add further local variables.
+ */
+ size_t i; /* Traverse pNames when creating wxsNames. */
+
+ /* __CHANGE__ 012: Initialize further local variables.
+ */
+ fdx = -1; fdy = -1;
+ pcx = -1; pcy = -1;
+ wxsNames = NULL;
+ pNames = printerNames;
+ nNames = numberOfPrinters;
+ nDefPrinter = defaultPrinterIndex;
+ pComm = NULL;
+ bCloseScheduled = false;
+ bAutostartWanted = false;
+ timeClose = (dk3_time_t)0UL;
+ sNamedFile = NULL;
+ sNamedPrinter = NULL;
+ bUseDefaultPrinter = false;
+ sTexts = localizedTexts;
+ sNlWx = nlWx;
+ sNlDk = nlDk;
+ pc = pPrintConf;
+#if defined(__WXMSW__)
+ wxIcon winprint_icon(sNlWx[4]);
+#else
+ wxIcon winprint_icon(winprint_xpm);
+#endif
+ /* __CHANGE__ 011: Initialize further class members.
+ */
+ dkctGUILayoutOK = false;
+ dkctGUIContentsPanel = NULL;
+ mainSizer = NULL;
+ tbMain = NULL;
+ mbMain = NULL;
+ bRun = NULL;
+ bExit = NULL;
+ menuFile = NULL;
+ menuHelp = NULL;
+ miFilePrint = NULL;
+ miFileExit = NULL;
+ miHelpAbout = NULL;
+ miHelpContents = NULL;
+ verticalSizer = NULL;
+ contentsSizer = NULL;
+ tStatus = NULL;
+ dkctGUIContentsPanel = new wxPanel(this);
+ if(!(dkctGUIContentsPanel)) {
+ goto dkctGUILayoutFinished;
+ }
+#if wxUSE_MENUS
+ mbMain = new wxMenuBar(
+ );
+ if(!(mbMain)) {
+ goto dkctGUILayoutFinished;
+ }
+ menuFile = new wxMenu(
+ );
+ if(!(menuFile)) {
+ goto dkctGUILayoutFinished;
+ }
+ miFilePrint = menuFile->Append(
+ WinprintFrame_Print,
+ sTexts[15],
+ sTexts[16]
+ );
+ if(!(miFilePrint)) {
+ goto dkctGUILayoutFinished;
+ }
+ miFileExit = menuFile->Append(
+ WinprintFrame_Quit,
+ sTexts[1],
+ sTexts[2]
+ );
+ if(!(miFileExit)) {
+ goto dkctGUILayoutFinished;
+ }
+ mbMain->Append(menuFile, sTexts[0]);
+ menuHelp = new wxMenu(
+ );
+ if(!(menuHelp)) {
+ goto dkctGUILayoutFinished;
+ }
+ miHelpAbout = menuHelp->Append(
+ WinprintFrame_Help_About,
+ sTexts[4],
+ sTexts[5]
+ );
+ if(!(miHelpAbout)) {
+ goto dkctGUILayoutFinished;
+ }
+ miHelpContents = menuHelp->Append(
+ WinprintFrame_Help_Contents,
+ sTexts[6],
+ sTexts[7]
+ );
+ if(!(miHelpContents)) {
+ goto dkctGUILayoutFinished;
+ }
+ mbMain->Append(menuHelp, sTexts[3]);
+ SetMenuBar(mbMain);
+#endif
+#if wxUSE_TOOLBAR
+ tbMain = new wxToolBar(
+ this,
+ wxID_ANY
+ );
+ if(!(tbMain)) {
+ goto dkctGUILayoutFinished;
+ }
+ bRun = tbMain->AddTool(
+ WinprintFrame_Print,
+ sTexts[15],
+ xpm_run_conversion,
+ wxNullBitmap,
+ wxITEM_NORMAL,
+ sTexts[16]
+ );
+ if(!(bRun)) {
+ goto dkctGUILayoutFinished;
+ }
+ bExit = tbMain->AddTool(
+ WinprintFrame_Quit,
+ sTexts[1],
+ xpm_exit_program,
+ wxNullBitmap,
+ wxITEM_NORMAL,
+ sTexts[2]
+ );
+ if(!(bExit)) {
+ goto dkctGUILayoutFinished;
+ }
+ tbMain->Realize();
+ SetToolBar(tbMain);
+#endif
+ mainSizer = new wxBoxSizer(
+ wxHORIZONTAL
+ );
+ if(!(mainSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ mainSizer->Add(10, 10, 0);
+ verticalSizer = new wxBoxSizer(
+ wxVERTICAL
+ );
+ if(!(verticalSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ verticalSizer->Add(10, 10, 0);
+ contentsSizer = new wxGridBagSizer(
+ 5, 5
+ );
+ if(!(contentsSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ tStatus = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[13]
+ );
+ if(!(tStatus)) {
+ goto dkctGUILayoutFinished;
+ }
+ contentsSizer->Add(
+ tStatus,
+ wxGBPosition(0, 0),
+ wxGBSpan(1, 1),
+ wxALIGN_LEFT
+ );
+ verticalSizer->Add(
+ contentsSizer
+ );
+ verticalSizer->Add(10, 10, 0);
+ mainSizer->Add(
+ verticalSizer,
+ 1,
+ wxGROW
+ );
+ mainSizer->Add(10, 10, 0);
+ dkctGUIContentsPanel->SetSizer(mainSizer);
+ SetIcon(winprint_icon);
+ dkctGUILayoutOK = true;
+ dkctGUILayoutFinished:
+#if wxUSE_STATUSBAR
+ if(dkctGUILayoutOK) {
+ CreateStatusBar(1);
+ SetStatusText(sTexts[8]);
+ }
+#endif
+ if(dkctGUILayoutOK) {
+ mainSizer->Fit(this);
+ mainSizer->SetSizeHints(this);
+ }
+
+#line 412 "WinprintFrame.wxc"
+ if(dkctGUILayoutOK) {
+ SetTitle(nlWx[0]);
+#if 0
+ restorePosition();
+#endif
+ }
+ if((pNames) && (nNames > 0)) {
+ wxsNames = new wxString[nNames];
+ if(wxsNames) {
+ for(i = 0; i < nNames; i++) {
+ wxsNames[i] = wxString(pNames[i]);
+ }
+ }
+ }
+ pComm = new DkWxCommunicator(
+ applicationHelper->getWxEncoding(),
+ applicationHelper->getDkEncoding()
+ );
+ if(argc > 1) {
+ bAutostartWanted = true;
+ {
+ wxChar const *ptr;
+ int res = -1;
+ wxCmdLineParser parser(winprint_cmd_line_desc, argc, argv);
+ {
+ wxLogNull log;
+ res = parser.Parse(false);
+ }
+ if(0 == res) {
+ wxString sPrinter(wxT(""));
+ if(pComm) {
+ pComm->autostartEnable(true);
+ }
+ if(parser.Found(wxT("d"))) {
+ /* Use default printer */
+ bUseDefaultPrinter = true;
+ } else {
+ if(parser.Found(wxT("P"), &sPrinter)) {
+ /* Use named printer */
+ ptr = sPrinter.c_str();
+ if(ptr) {
+ if(sNamedPrinter) {
+ dk3_release(sNamedPrinter);
+ }
+ sNamedPrinter = dk3wxs_dup(ptr);
+ }
+ }
+ }
+ if(parser.GetParamCount() > 0) {
+ wxString cmdfn;
+ wxString fullPath;
+ /* Print named file(s) */
+ cmdfn = parser.GetParam(0);
+ wxFileName fn(cmdfn);
+ fn.Normalize(
+ wxPATH_NORM_LONG | wxPATH_NORM_DOTS
+ | wxPATH_NORM_TILDE | wxPATH_NORM_ABSOLUTE
+ );
+ fullPath = fn.GetFullPath();
+ ptr = fullPath.c_str();
+ if(ptr) {
+ if(sNamedFile) {
+ dk3_release(sNamedFile);
+ }
+ sNamedFile = dk3wxs_dup(ptr);
+ }
+ }
+ }
+ }
+ }
+}
+
+
+
+
+#line 487 "WinprintFrame.wxc"
+
+
+
+WinprintFrame::~WinprintFrame()
+{
+ size_t i; /* Index of current string to delete. */
+ /* __CHANGE__ 011: Release resources allocated by further class members.
+ */
+ if(wxsNames) {
+ for(i = 0; i < nNames; i++) {
+ wxsNames[i] = wxString(wxT(""));
+ }
+ delete [] wxsNames;
+ }
+ dk3_cpp_release(pComm);
+ if(sNamedPrinter) {
+ dk3_release(sNamedPrinter);
+ sNamedPrinter = NULL;
+ }
+ if(sNamedFile) {
+ dk3_release(sNamedFile);
+ sNamedFile = NULL;
+ }
+}
+
+
+
+bool
+WinprintFrame::canClose(bool isLast)
+{
+ bool back = true;
+
+ /* __CHANGE__ 013: Check for unsaved data.
+ */
+
+ return back;
+}
+
+
+void
+WinprintFrame::OnQuit(wxCommandEvent & event)
+{
+ Close();
+}
+
+
+
+void
+WinprintFrame::OnAbout(wxCommandEvent & event)
+{
+ wxString text(wxT("")); /* Text to show. */
+ wxString title(wxT("")); /* Windows title. */
+
+ /* Construct message text. */
+ text.Append(sNlWx[0]);
+ text.Append(sNlWx[7]);
+#if 0
+ text.Append(sNlWx[1]);
+#else
+ text.Append( DKT_VERSION_WX );
+#endif
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[9]);
+ text.Append(sNlWx[2]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[11]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[9]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[12]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[10]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[11]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[12]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[13]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[14]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[15]);
+ text.Append(sNlWx[8]);
+
+ /* Construct dialog box title. */
+ title.Append(sTexts[10]);
+ title.Append(sNlWx[0]);
+
+ /* Show dialog box. */
+ wxMessageBox(text, title, wxOK, this);
+
+ /* __CHANGE__ 019: Create better about box.
+ */
+}
+
+
+
+void
+WinprintFrame::OnHelpContents(wxCommandEvent & event)
+{
+ openHelp();
+}
+
+/* __CHANGE__ 017: Event handlers for further events.
+*/
+
+void
+WinprintFrame::OnPrint(wxCommandEvent & event)
+{
+ (void)runJob();
+}
+
+
+/* __CHANGE__ 014: Implementation of further methods.
+*/
+
+
+/* __CHANGE__ 008: Remove OnIdle if no idle processing required.
+*/
+
+void
+WinprintFrame::OnIdle(wxIdleEvent & event)
+{
+ static BOOL firstIdle = true; /* Flag: First idle event of application. */
+ dk3_time_t ct; /* Current time. */
+ int res; /* Operation result. */
+
+
+#line 616 "WinprintFrame.wxc"
+ /* __CHANGE__
+ */
+ if(firstIdle) {
+
+#line 619 "WinprintFrame.wxc"
+ firstIdle = false;
+ tStatus->SetLabel(wxT(""));
+ Refresh();
+ Update();
+ /* For autostart */
+ event.RequestMore();
+ } else {
+
+#line 626 "WinprintFrame.wxc"
+ if(!bCloseScheduled) {
+
+#line 627 "WinprintFrame.wxc"
+ if(pComm) {
+
+#line 628 "WinprintFrame.wxc"
+ if((bAutostartWanted) && (pComm->autostartCanRun())) {
+
+
+#line 630 "WinprintFrame.wxc"
+ res = runJob();
+ if(res > 0) {
+
+#line 632 "WinprintFrame.wxc"
+ event.RequestMore();
+ }
+ } else {
+
+#line 635 "WinprintFrame.wxc"
+ if(pComm->autostartIsFinished()) {
+
+#line 636 "WinprintFrame.wxc"
+ if(!(timeClose)) {
+
+#line 637 "WinprintFrame.wxc"
+ if(pComm->getLogLevel() > DK3_LL_WARNING) {
+
+#line 638 "WinprintFrame.wxc"
+ dk3sf_time(&timeClose);
+
+#line 639 "WinprintFrame.wxc"
+ event.RequestMore();
+ tStatus->SetLabel(sTexts[14]);
+
+#line 641 "WinprintFrame.wxc"
+ tStatus->SetForegroundColour(cGreen);
+ Refresh();
+ Update();
+ } else {
+ tStatus->SetLabel(pComm->getText());
+
+#line 646 "WinprintFrame.wxc"
+ tStatus->SetForegroundColour(cRed);
+ Refresh();
+ Update();
+ wxMessageBox(
+ pComm->getText(), sTexts[29], (wxICON_ERROR | wxOK), this
+ );
+ dk3sf_time(&timeClose);
+
+#line 653 "WinprintFrame.wxc"
+ event.RequestMore();
+ }
+ }
+ }
+ if(timeClose) {
+
+#line 658 "WinprintFrame.wxc"
+ dk3sf_time(&ct);
+ if(ct > (timeClose + (dk3_time_t)1UL)) {
+
+#line 660 "WinprintFrame.wxc"
+ timeClose = (dk3_time_t)0UL;
+ bCloseScheduled = true;
+ Show(false);
+ Close();
+ } else {
+
+#line 665 "WinprintFrame.wxc"
+ event.RequestMore();
+ }
+ }
+ }
+ } else {
+
+#line 670 "WinprintFrame.wxc"
+ /* ERROR: No communicator */
+ if(timeClose) {
+ dk3sf_time(&ct);
+ if(ct > (timeClose * (dk3_time_t)1UL)) {
+ timeClose = (dk3_time_t)0UL;
+ bCloseScheduled = true;
+ Show(false);
+ Close();
+ } else {
+ event.RequestMore();
+ }
+ }
+ }
+ } else {
+
+#line 684 "WinprintFrame.wxc"
+ }
+ }
+ event.Skip();
+
+
+#line 688 "WinprintFrame.wxc"
+}
+
+
+
+int
+WinprintFrame::runJob(void)
+{
+ wxChar prbuf[512]; /* Printer name in system enc. */
+ wxString path; /* File path. */
+ wxChar const *filename = NULL; /* File name. */
+ wxChar const *printername = NULL; /* Printer name. */
+ int res; /* Operation result. */
+ int ok = 0; /* Flag: Success. */
+ int back = 0;
+
+
+#line 703 "WinprintFrame.wxc"
+ tStatus->SetLabel(sTexts[17]);
+
+#line 704 "WinprintFrame.wxc"
+ tStatus->SetForegroundColour(cBlack);
+ Refresh();
+ Update();
+ if(sNamedFile) {
+
+#line 708 "WinprintFrame.wxc"
+ filename = sNamedFile;
+ } else {
+
+#line 710 "WinprintFrame.wxc"
+ wxString s(wxT(""));
+ s.Append(wxT("Print files (*.prn)|*.prn"));
+ s.Append(wxT("|All files (*.*)|*.*"));
+#if wxCHECK_VERSION(2, 9, 0)
+ wxFileDialog dlg(this, sTexts[18], wxT("."), wxT(""), s, wxFD_OPEN);
+#else
+ wxFileDialog dlg(this, sTexts[18], wxT("."), wxT(""), s, wxOPEN);
+#endif
+ pHelper->setRelatedPosition(this, &dlg, &fdx, &fdy);
+ if(wxID_OK == dlg.ShowModal()) {
+ path = dlg.GetPath();
+ filename = path.c_str();
+ } else {
+ /* Aborted by user */
+ setErrorStatus(sTexts[19], NULL);
+
+#line 725 "WinprintFrame.wxc"
+ }
+ dlg.GetPosition(&fdx, &fdy);
+ }
+ if(filename) {
+
+#line 729 "WinprintFrame.wxc"
+ if(bUseDefaultPrinter) {
+
+#line 730 "WinprintFrame.wxc"
+ if(pc) {
+
+#line 731 "WinprintFrame.wxc"
+ if(pc->defPrinter) {
+
+#line 732 "WinprintFrame.wxc"
+ if((pc->defPrinter->name)) {
+
+#line 733 "WinprintFrame.wxc"
+ res = dk3wxs_from_dkstr(
+ prbuf,
+ DK3_SIZEOF(prbuf,wxChar),
+ pHelper->getWxEncoding(),
+ (pc->defPrinter)->name,
+ pHelper->getDkEncoding()
+ );
+ if(res) {
+
+#line 741 "WinprintFrame.wxc"
+ printername = prbuf;
+ } else {
+
+#line 743 "WinprintFrame.wxc"
+ /* ERROR: Failed to convert printer name! */
+ setErrorStatus(sTexts[24], filename);
+
+#line 745 "WinprintFrame.wxc"
+ }
+ } else {
+
+#line 747 "WinprintFrame.wxc"
+ /* ERROR: No default printer name */
+ setErrorStatus(sTexts[25], filename);
+
+#line 749 "WinprintFrame.wxc"
+ }
+ } else {
+
+#line 751 "WinprintFrame.wxc"
+ /* ERROR: No default printer */
+ setErrorStatus(sTexts[25], filename);
+
+#line 753 "WinprintFrame.wxc"
+ }
+ } else {
+
+#line 755 "WinprintFrame.wxc"
+ /* ERROR: No print configuration */
+ setErrorStatus(sTexts[26], filename);
+
+#line 757 "WinprintFrame.wxc"
+ }
+ } else {
+
+#line 759 "WinprintFrame.wxc"
+ if(sNamedPrinter) {
+
+#line 760 "WinprintFrame.wxc"
+ printername = sNamedPrinter;
+ } else {
+
+#line 762 "WinprintFrame.wxc"
+ if((pNames) && (wxsNames) && (nNames > 0)) {
+
+#line 763 "WinprintFrame.wxc"
+ WinprintChooserDialog dlg(this, sTexts[30], sTexts, wxsNames, nNames);
+ dlg.setCurrentPrinter(nDefPrinter);
+ pHelper->setRelatedPosition(this, &dlg, &pcx, &pcy);
+ if(wxID_OK == dlg.ShowModal()) {
+
+#line 767 "WinprintFrame.wxc"
+ nDefPrinter = dlg.getCurrentPrinter();
+ if((nDefPrinter >= 0) && (nDefPrinter < (int)nNames)) {
+
+#line 769 "WinprintFrame.wxc"
+ printername = pNames[nDefPrinter];
+ } else {
+
+#line 771 "WinprintFrame.wxc"
+ /* BUG: Illegal return value from dialog */
+ setErrorStatus(sTexts[26], filename);
+
+#line 773 "WinprintFrame.wxc"
+ }
+ } else {
+
+#line 775 "WinprintFrame.wxc"
+ /* ERROR: Aborted by user */
+ setErrorStatus(sTexts[19], filename);
+
+#line 777 "WinprintFrame.wxc"
+ }
+ dlg.GetPosition(&pcx, &pcy);
+ } else {
+
+#line 780 "WinprintFrame.wxc"
+ /* ERROR: No printer configuration */
+ setErrorStatus(sTexts[26], filename);
+
+#line 782 "WinprintFrame.wxc"
+ }
+ }
+ }
+ } else {
+
+#line 786 "WinprintFrame.wxc"
+ }
+ if((filename) && (printername)) {
+
+#line 788 "WinprintFrame.wxc"
+ /* wxMessageBox(filename, printername); */
+ if(pComm) {
+
+#line 790 "WinprintFrame.wxc"
+ DkWxProgressDialog *pd;
+ pComm->prepareRun();
+ pd = new DkWxProgressDialog(
+ (DkWxFrame *)this,
+ pComm,
+ NULL,
+ sTexts[20],
+ filename,
+ sTexts[21],
+ sTexts[22],
+ sTexts[23]
+ );
+ if(pd) {
+
+#line 803 "WinprintFrame.wxc"
+ WinprintThread *pt;
+ pt = new WinprintThread(
+ pComm, sTexts, pHelper, pc, filename, printername
+ );
+ if(pt) {
+
+#line 808 "WinprintFrame.wxc"
+ if(wxTHREAD_NO_ERROR == pt->Create()) {
+
+#line 809 "WinprintFrame.wxc"
+ pt->SetPriority(WXTHREAD_DEFAULT_PRIORITY);
+ pt->Run();
+ pd->chooseModalPosition();
+ pd->ShowModal();
+ ok = 1;
+ if(pComm->getLogLevel() <= DK3_LL_WARNING) {
+
+#line 815 "WinprintFrame.wxc"
+ /* ERRORS occured */
+ tStatus->SetLabel(pComm->getText());
+
+#line 817 "WinprintFrame.wxc"
+ tStatus->SetForegroundColour(cRed);
+ } else {
+
+#line 819 "WinprintFrame.wxc"
+ /* Transfer succeeeded */
+ if(!(bAutostartWanted)) {
+ tStatus->SetLabel(sTexts[37]);
+
+#line 822 "WinprintFrame.wxc"
+ tStatus->SetForegroundColour(cGreen);
+ }
+ }
+ Refresh();
+ Update();
+ back = 1;
+ } else {
+
+#line 829 "WinprintFrame.wxc"
+ /* ERROR: Create method failed! */
+ setErrorStatus(sTexts[27], filename);
+
+#line 831 "WinprintFrame.wxc"
+ }
+ } else {
+
+#line 833 "WinprintFrame.wxc"
+ /* ERROR: Failed to create thread */
+ setErrorStatus(sTexts[27], filename);
+
+#line 835 "WinprintFrame.wxc"
+ }
+ pd->Destroy();
+ } else {
+
+#line 838 "WinprintFrame.wxc"
+ /* ERROR: Failed to create progress dialog */
+ setErrorStatus(sTexts[28], filename);
+
+#line 840 "WinprintFrame.wxc"
+ }
+ } else {
+
+#line 842 "WinprintFrame.wxc"
+ /* ###### ERROR: No communicator */
+ }
+ } else {
+
+#line 845 "WinprintFrame.wxc"
+ if(pComm) {
+ if(!(filename)) {
+ }
+ if(!(printername)) {
+ }
+ } else {
+ /* ##### ERROR: No communicator */
+ }
+ }
+
+#line 854 "WinprintFrame.wxc"
+ return back;
+}
+
+
+
+void
+WinprintFrame::setErrorStatus(wxChar const *txt, wxChar const *filename)
+{
+ if(pComm) {
+ pComm->prepareRun();
+ pComm->addWxText(txt);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ pComm->setUpdates(((filename) ? filename : wxT("")), 1000);
+ pComm->setRunning(0);
+ }
+ tStatus->SetLabel(txt);
+ tStatus->SetForegroundColour(cRed);
+ Refresh();
+ Update();
+}
+
+
diff --git a/support/dktools/WinprintFrame.h b/support/dktools/WinprintFrame.h
new file mode 100644
index 0000000000..3f13a839a5
--- /dev/null
+++ b/support/dktools/WinprintFrame.h
@@ -0,0 +1,326 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: WinprintFrame.wxc
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file WinprintFrame.h Header file for the WinprintFrame module.
+*/
+
+#ifndef WINPRINTFRAME_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define WINPRINTFRAME_H_INCLUDED 1
+
+
+#line 103 "WinprintFrame.wxc"
+
+#ifdef DK3_USE_WX
+#undef DK3_USE_WX
+#endif
+/** Use wxWidgets libraries to build GUI programs.
+*/
+#define DK3_USE_WX 1
+
+
+
+#line 113 "WinprintFrame.wxc"
+class WinprintFrame : public DkWxFrame
+{
+ private:
+
+ /** Event table for frame.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ /** Black color for status label.
+ */
+ wxColour cBlack;
+
+ /** Green color for status label.
+ */
+ wxColour cGreen;
+
+ /** Red color for status label.
+ */
+ wxColour cRed;
+
+ /** Printer names.
+ */
+ DK3_PCWXCHAR *pNames;
+
+ /** Printer names as wxString array.
+ */
+ wxString *wxsNames;
+
+ /** Size of printer names array.
+ */
+ size_t nNames;
+
+ /** Index of default printer in array.
+ */
+ int nDefPrinter;
+
+ /** File dialog x position.
+ */
+ int fdx;
+
+ /** File dialog y position.
+ */
+ int fdy;
+
+ /** Printer chooser dialog x position.
+ */
+ int pcx;
+
+ /** Printer chooser dialog y position.
+ */
+ int pcy;
+
+ /** Localized texts.
+ */
+ wxChar const * const *sTexts;
+
+ /** Non-localized texts.
+ */
+ wxChar const * const *sNlWx;
+
+ /** Non-localized texts.
+ */
+ dkChar const * const *sNlDk;
+
+ /** Print configuration.
+ */
+ dk3_print_conf_t *pc;
+
+ /** Use default printer.
+ */
+ BOOL bUseDefaultPrinter;
+
+ /** Use named printer.
+ */
+ wxChar const *sNamedPrinter;
+
+ /** Named file to process.
+ */
+ wxChar const *sNamedFile;
+
+ /** Communicator object.
+ */
+ DkWxCommunicator *pComm;
+
+ /** Time to close the application.
+ */
+ dk3_time_t timeClose;
+
+ /** Flag: Closing the application is scheduled.
+ */
+ BOOL bCloseScheduled;
+
+ /** Flag: Autostart wanted.
+ */
+ BOOL bAutostartWanted;
+
+ /** Flag: GUI ok.
+ */
+ bool dkctGUILayoutOK;
+
+ /** Contents panel.
+ */
+ wxPanel *dkctGUIContentsPanel;
+
+ /** GUI element mainSizer.
+ */
+#line 74 "WinprintFrame.wxc"
+ wxBoxSizer *mainSizer;
+
+ /** GUI element tbMain.
+ */
+#line 24 "WinprintFrame.wxc"
+ wxToolBar *tbMain;
+
+ /** GUI element mbMain.
+ */
+#line 40 "WinprintFrame.wxc"
+ wxMenuBar *mbMain;
+
+ /** GUI element bRun.
+ */
+#line 28 "WinprintFrame.wxc"
+ wxToolBarToolBase *bRun;
+
+ /** GUI element bExit.
+ */
+#line 34 "WinprintFrame.wxc"
+ wxToolBarToolBase *bExit;
+
+ /** GUI element menuFile.
+ */
+#line 44 "WinprintFrame.wxc"
+ wxMenu *menuFile;
+
+ /** GUI element menuHelp.
+ */
+#line 59 "WinprintFrame.wxc"
+ wxMenu *menuHelp;
+
+ /** GUI element miFilePrint.
+ */
+#line 49 "WinprintFrame.wxc"
+ wxMenuItem *miFilePrint;
+
+ /** GUI element miFileExit.
+ */
+#line 54 "WinprintFrame.wxc"
+ wxMenuItem *miFileExit;
+
+ /** GUI element miHelpAbout.
+ */
+#line 64 "WinprintFrame.wxc"
+ wxMenuItem *miHelpAbout;
+
+ /** GUI element miHelpContents.
+ */
+#line 69 "WinprintFrame.wxc"
+ wxMenuItem *miHelpContents;
+
+ /** GUI element verticalSizer.
+ */
+#line 80 "WinprintFrame.wxc"
+ wxBoxSizer *verticalSizer;
+
+ /** GUI element contentsSizer.
+ */
+#line 88 "WinprintFrame.wxc"
+ wxGridBagSizer *contentsSizer;
+
+ /** GUI element tStatus.
+ */
+#line 97 "WinprintFrame.wxc"
+ wxStaticText *tStatus;
+
+
+#line 212 "WinprintFrame.wxc"
+
+ public:
+
+ /** Constructor.
+ @param wxid Window ID.
+ @param applicationHelper Application helper object.
+ @param hc Help controller for online help.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @param localizedTexts Localized wxChar texts.
+ @param nlWx Non-localized wxChar texts.
+ @param nlDk Non-localized dkChar texts.
+ @param pPrintConf Print configuration.
+ */
+ WinprintFrame(
+ int wxid,
+ DkWxAppHelper *applicationHelper,
+ DkWxHelpController *hc,
+ int argc,
+ wxChar **argv,
+ wxChar const * const *localizedTexts,
+ wxChar const * const *nlWx,
+ dkChar const * const *nlDk,
+ dk3_print_conf_t *pPrintConf,
+ DK3_PCWXCHAR *printerNames,
+ size_t numberOfPrinters,
+ int defaultPrinterIndex
+ );
+
+ /** Destructor.
+ */
+ ~WinprintFrame();
+
+ /** Check whether we can close the window.
+ @param isLast Flag: Last main window to close.
+ */
+ bool
+ canClose(bool isLast);
+
+ /** Handler for File/Exit.
+ @param event Event to process.
+ */
+ void
+ OnQuit(wxCommandEvent & event);
+
+ /** Handler for Help/About.
+ @param event Event to process.
+ */
+ void
+ OnAbout(wxCommandEvent & event);
+
+ /** Handler for Help/Contents.
+ @param event Event to process.
+ */
+ void
+ OnHelpContents(wxCommandEvent & event);
+
+ /** Handler for print menu item.
+ @param event Event to process.
+ */
+ void
+ OnPrint(wxCommandEvent & event);
+
+ /* __CHANGE__ 008: Remove OnIdle if no idle processing required.
+ */
+ /** Handler for idle events.
+ */
+ void
+ OnIdle(wxIdleEvent & event);
+
+ /* __CHANGE__ 017: Event handlers for further events.
+ */
+
+ /* __CHANGE__ 014: Add further methods.
+ */
+
+ /** Run for a print job.
+ */
+ int runJob(void);
+
+ /** Set error status.
+ @param txt Error message text.
+ @param filename Current filename to process.
+ */
+ void setErrorStatus(wxChar const *txt, wxChar const *filename);
+
+};
+
+
+#line 301 "WinprintFrame.wxc"
+
+
+#endif
diff --git a/support/dktools/WinprintFrame.wxc b/support/dktools/WinprintFrame.wxc
new file mode 100644
index 0000000000..6d92aa94fa
--- /dev/null
+++ b/support/dktools/WinprintFrame.wxc
@@ -0,0 +1,875 @@
+%% options
+
+# __CHANGE__ 001: Correct copyright owner if necessary.
+copyright owner = Dirk Krause
+
+# __CHANGE__ 003: Correct copyright year(s) if necessary.
+copyright year = 2013-xxxx
+
+# __CHANGE__ 002: Correct license type if necessary.
+# Use "bsd", "gpl", "lgpl", or "commercial".
+license = bsd
+
+
+
+%% wx-gui
+
+type = frame
+contents = mainSizer
+icon = winprint_icon
+tool bar = tbMain
+status bar = 1 sTexts[8]
+menu bar = mbMain
+
+[wxToolBar tbMain]
+contents = bRun
+contents = bExit
+
+[wxToolBarToolBase bRun]
+text = sTexts[15]
+bitmap = xpm_run_conversion
+id = WinprintFrame_Print
+tip = sTexts[16]
+
+[wxToolBarToolBase bExit]
+text = sTexts[1]
+bitmap = xpm_exit_program
+id = WinprintFrame_Quit
+tip = sTexts[2]
+
+[wxMenuBar mbMain]
+contents = menuFile
+contents = menuHelp
+
+[wxMenu menuFile]
+text = sTexts[0]
+contents = miFilePrint
+contents = miFileExit
+
+[wxMenuItem miFilePrint]
+id = WinprintFrame_Print
+text = sTexts[15]
+tip = sTexts[16]
+
+[wxMenuItem miFileExit]
+id = WinprintFrame_Quit
+text = sTexts[1]
+tip = sTexts[2]
+
+[wxMenu menuHelp]
+text = sTexts[3]
+contents = miHelpAbout
+contents = miHelpContents
+
+[wxMenuItem miHelpAbout]
+id = WinprintFrame_Help_About
+text = sTexts[4]
+tip = sTexts[5]
+
+[wxMenuItem miHelpContents]
+id = WinprintFrame_Help_Contents
+text = sTexts[6]
+tip = sTexts[7]
+
+[wxBoxSizer mainSizer]
+direction = horizontal
+contents = $space(10)
+contents = verticalSizer
+contents = $space(10)
+
+[wxBoxSizer verticalSizer]
+direction = vertical
+grow = yes
+proportion = 1
+contents = $space(10)
+contents = contentsSizer
+contents = $space(10)
+
+[wxGridBagSizer contentsSizer]
+grid = 5 5
+
+# __CHANGE__ 015: The dummy label was added to have at least
+# one GUI element in the sizer.
+# Remove tStatus (next 4 lines) and add the real
+# window contents here.
+contents = tStatus 0 0 1 1 left
+
+[wxStaticText tStatus]
+text = sTexts[13]
+
+
+
+%% header start
+
+#ifdef DK3_USE_WX
+#undef DK3_USE_WX
+#endif
+/** Use wxWidgets libraries to build GUI programs.
+*/
+#define DK3_USE_WX 1
+
+
+%% class start
+class WinprintFrame : public DkWxFrame
+{
+ private:
+
+ /** Event table for frame.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ /** Black color for status label.
+ */
+ wxColour cBlack;
+
+ /** Green color for status label.
+ */
+ wxColour cGreen;
+
+ /** Red color for status label.
+ */
+ wxColour cRed;
+
+ /** Printer names.
+ */
+ DK3_PCWXCHAR *pNames;
+
+ /** Printer names as wxString array.
+ */
+ wxString *wxsNames;
+
+ /** Size of printer names array.
+ */
+ size_t nNames;
+
+ /** Index of default printer in array.
+ */
+ int nDefPrinter;
+
+ /** File dialog x position.
+ */
+ int fdx;
+
+ /** File dialog y position.
+ */
+ int fdy;
+
+ /** Printer chooser dialog x position.
+ */
+ int pcx;
+
+ /** Printer chooser dialog y position.
+ */
+ int pcy;
+
+ /** Localized texts.
+ */
+ wxChar const * const *sTexts;
+
+ /** Non-localized texts.
+ */
+ wxChar const * const *sNlWx;
+
+ /** Non-localized texts.
+ */
+ dkChar const * const *sNlDk;
+
+ /** Print configuration.
+ */
+ dk3_print_conf_t *pc;
+
+ /** Use default printer.
+ */
+ BOOL bUseDefaultPrinter;
+
+ /** Use named printer.
+ */
+ wxChar const *sNamedPrinter;
+
+ /** Named file to process.
+ */
+ wxChar const *sNamedFile;
+
+ /** Communicator object.
+ */
+ DkWxCommunicator *pComm;
+
+ /** Time to close the application.
+ */
+ dk3_time_t timeClose;
+
+ /** Flag: Closing the application is scheduled.
+ */
+ BOOL bCloseScheduled;
+
+ /** Flag: Autostart wanted.
+ */
+ BOOL bAutostartWanted;
+
+%% class end
+
+ public:
+
+ /** Constructor.
+ @param wxid Window ID.
+ @param applicationHelper Application helper object.
+ @param hc Help controller for online help.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @param localizedTexts Localized wxChar texts.
+ @param nlWx Non-localized wxChar texts.
+ @param nlDk Non-localized dkChar texts.
+ @param pPrintConf Print configuration.
+ */
+ WinprintFrame(
+ int wxid,
+ DkWxAppHelper *applicationHelper,
+ DkWxHelpController *hc,
+ int argc,
+ wxChar **argv,
+ wxChar const * const *localizedTexts,
+ wxChar const * const *nlWx,
+ dkChar const * const *nlDk,
+ dk3_print_conf_t *pPrintConf,
+ DK3_PCWXCHAR *printerNames,
+ size_t numberOfPrinters,
+ int defaultPrinterIndex
+ );
+
+ /** Destructor.
+ */
+ ~WinprintFrame();
+
+ /** Check whether we can close the window.
+ @param isLast Flag: Last main window to close.
+ */
+ bool
+ canClose(bool isLast);
+
+ /** Handler for File/Exit.
+ @param event Event to process.
+ */
+ void
+ OnQuit(wxCommandEvent & event);
+
+ /** Handler for Help/About.
+ @param event Event to process.
+ */
+ void
+ OnAbout(wxCommandEvent & event);
+
+ /** Handler for Help/Contents.
+ @param event Event to process.
+ */
+ void
+ OnHelpContents(wxCommandEvent & event);
+
+ /** Handler for print menu item.
+ @param event Event to process.
+ */
+ void
+ OnPrint(wxCommandEvent & event);
+
+ /* __CHANGE__ 008: Remove OnIdle if no idle processing required.
+ */
+ /** Handler for idle events.
+ */
+ void
+ OnIdle(wxIdleEvent & event);
+
+ /* __CHANGE__ 017: Event handlers for further events.
+ */
+
+ /* __CHANGE__ 014: Add further methods.
+ */
+
+ /** Run for a print job.
+ */
+ int runJob(void);
+
+ /** Set error status.
+ @param txt Error message text.
+ @param filename Current filename to process.
+ */
+ void setErrorStatus(wxChar const *txt, wxChar const *filename);
+
+};
+
+%% header end
+
+%% module start
+
+#include "winprint.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4verswx.h"
+#include "dk4verswx.h"
+#include "run-conversion.xpm"
+#include "exit-program.xpm"
+
+
+#if !defined(__WXMSW__)
+#include "winprint.xpm"
+#endif
+
+
+
+$!trace-include
+
+
+
+/* __CHANGE__ 017: Add further events. */
+/* __CHANGE__ 008: Remove OnIdle if no idle processing required. */
+BEGIN_EVENT_TABLE(WinprintFrame, wxFrame)
+ EVT_MENU(WinprintFrame_Quit, WinprintFrame::OnQuit)
+ EVT_MENU(WinprintFrame_Print, WinprintFrame::OnPrint)
+ EVT_MENU(WinprintFrame_Help_About, WinprintFrame::OnAbout)
+ EVT_MENU(WinprintFrame_Help_Contents, WinprintFrame::OnHelpContents)
+ EVT_IDLE(WinprintFrame::OnIdle)
+END_EVENT_TABLE()
+
+
+
+static const wxCmdLineEntryDesc winprint_cmd_line_desc[] = {
+ {
+ wxCMD_LINE_OPTION,
+ wxT_2("P"),
+ wxT_2("printer"),
+ wxT_2("choose printer"),
+ wxCMD_LINE_VAL_STRING
+ },
+ {
+ wxCMD_LINE_SWITCH,
+ wxT_2("d"),
+ wxT_2("default"),
+ wxT_2("Use default printer")
+ },
+ {
+ wxCMD_LINE_PARAM,
+ NULL,
+ NULL,
+ wxT_2("input file"),
+ wxCMD_LINE_VAL_STRING,
+ wxCMD_LINE_PARAM_OPTIONAL
+ },
+ { wxCMD_LINE_NONE }
+};
+
+
+%% constructor start
+WinprintFrame::WinprintFrame(
+ int wxid,
+ DkWxAppHelper *applicationHelper,
+ DkWxHelpController *hc,
+ int argc,
+ wxChar **argv,
+ wxChar const * const *localizedTexts,
+ wxChar const * const *nlWx,
+ dkChar const * const *nlDk,
+ dk3_print_conf_t *pPrintConf,
+ DK3_PCWXCHAR *printerNames,
+ size_t numberOfPrinters,
+ int defaultPrinterIndex
+) : DkWxFrame(nlWx[0], applicationHelper, hc, wxid),
+ cBlack(0, 0, 0),
+ cGreen(0, 127, 0),
+ cRed(127, 0, 0)
+{
+ /* __CHANGE__ 012: Add further local variables.
+ */
+ size_t i; /* Traverse pNames when creating wxsNames. */
+
+ /* __CHANGE__ 012: Initialize further local variables.
+ */
+ fdx = -1; fdy = -1;
+ pcx = -1; pcy = -1;
+ wxsNames = NULL;
+ pNames = printerNames;
+ nNames = numberOfPrinters;
+ nDefPrinter = defaultPrinterIndex;
+ pComm = NULL;
+ bCloseScheduled = false;
+ bAutostartWanted = false;
+ timeClose = (dk3_time_t)0UL;
+ sNamedFile = NULL;
+ sNamedPrinter = NULL;
+ bUseDefaultPrinter = false;
+ sTexts = localizedTexts;
+ sNlWx = nlWx;
+ sNlDk = nlDk;
+ pc = pPrintConf;
+#if defined(__WXMSW__)
+ wxIcon winprint_icon(sNlWx[4]);
+#else
+ wxIcon winprint_icon(winprint_xpm);
+#endif
+ /* __CHANGE__ 011: Initialize further class members.
+ */
+%% constructor end
+ if(dkctGUILayoutOK) {
+ SetTitle(nlWx[0]);
+#if 0
+ restorePosition();
+#endif
+ }
+ if((pNames) && (nNames > 0)) {
+ wxsNames = new wxString[nNames];
+ if(wxsNames) {
+ for(i = 0; i < nNames; i++) {
+ wxsNames[i] = wxString(pNames[i]);
+ }
+ }
+ }
+ pComm = new DkWxCommunicator(
+ applicationHelper->getWxEncoding(),
+ applicationHelper->getDkEncoding()
+ );
+ if(argc > 1) {
+ bAutostartWanted = true;
+ {
+ wxChar const *ptr;
+ int res = -1;
+ wxCmdLineParser parser(winprint_cmd_line_desc, argc, argv);
+ {
+ wxLogNull log;
+ res = parser.Parse(false);
+ }
+ if(0 == res) {
+ wxString sPrinter(wxT(""));
+ if(pComm) {
+ pComm->autostartEnable(true);
+ }
+ if(parser.Found(wxT("d"))) {
+ /* Use default printer */
+ bUseDefaultPrinter = true;
+ } else {
+ if(parser.Found(wxT("P"), &sPrinter)) {
+ /* Use named printer */
+ ptr = sPrinter.c_str();
+ if(ptr) {
+ if(sNamedPrinter) {
+ dk3_release(sNamedPrinter);
+ }
+ sNamedPrinter = dk3wxs_dup(ptr);
+ }
+ }
+ }
+ if(parser.GetParamCount() > 0) {
+ wxString cmdfn;
+ wxString fullPath;
+ /* Print named file(s) */
+ cmdfn = parser.GetParam(0);
+ wxFileName fn(cmdfn);
+ fn.Normalize(
+ wxPATH_NORM_LONG | wxPATH_NORM_DOTS
+ | wxPATH_NORM_TILDE | wxPATH_NORM_ABSOLUTE
+ );
+ fullPath = fn.GetFullPath();
+ ptr = fullPath.c_str();
+ if(ptr) {
+ if(sNamedFile) {
+ dk3_release(sNamedFile);
+ }
+ sNamedFile = dk3wxs_dup(ptr);
+ }
+ }
+ }
+ }
+ }
+}
+
+
+
+%% module end
+
+
+
+WinprintFrame::~WinprintFrame()
+{
+ size_t i; /* Index of current string to delete. */
+ /* __CHANGE__ 011: Release resources allocated by further class members.
+ */
+ if(wxsNames) {
+ for(i = 0; i < nNames; i++) {
+ wxsNames[i] = wxString(wxT(""));
+ }
+ delete [] wxsNames;
+ }
+ dk3_cpp_release(pComm);
+ if(sNamedPrinter) {
+ dk3_release(sNamedPrinter);
+ sNamedPrinter = NULL;
+ }
+ if(sNamedFile) {
+ dk3_release(sNamedFile);
+ sNamedFile = NULL;
+ }
+}
+
+
+
+bool
+WinprintFrame::canClose(bool isLast)
+{
+ bool back = true;
+
+ /* __CHANGE__ 013: Check for unsaved data.
+ */
+
+ return back;
+}
+
+
+void
+WinprintFrame::OnQuit(wxCommandEvent & event)
+{
+ Close();
+}
+
+
+
+void
+WinprintFrame::OnAbout(wxCommandEvent & event)
+{
+ wxString text(wxT("")); /* Text to show. */
+ wxString title(wxT("")); /* Windows title. */
+
+ /* Construct message text. */
+ text.Append(sNlWx[0]);
+ text.Append(sNlWx[7]);
+#if 0
+ text.Append(sNlWx[1]);
+#else
+ text.Append( DKT_VERSION_WX );
+#endif
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[9]);
+ text.Append(sNlWx[2]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[11]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[9]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[12]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[10]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[11]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[12]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[13]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[14]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[15]);
+ text.Append(sNlWx[8]);
+
+ /* Construct dialog box title. */
+ title.Append(sTexts[10]);
+ title.Append(sNlWx[0]);
+
+ /* Show dialog box. */
+ wxMessageBox(text, title, wxOK, this);
+
+ /* __CHANGE__ 019: Create better about box.
+ */
+}
+
+
+
+void
+WinprintFrame::OnHelpContents(wxCommandEvent & event)
+{
+ openHelp();
+}
+
+/* __CHANGE__ 017: Event handlers for further events.
+*/
+
+void
+WinprintFrame::OnPrint(wxCommandEvent & event)
+{
+ (void)runJob();
+}
+
+
+/* __CHANGE__ 014: Implementation of further methods.
+*/
+
+
+/* __CHANGE__ 008: Remove OnIdle if no idle processing required.
+*/
+
+void
+WinprintFrame::OnIdle(wxIdleEvent & event)
+{
+ static BOOL firstIdle = true; /* Flag: First idle event of application. */
+ dk3_time_t ct; /* Current time. */
+ int res; /* Operation result. */
+ $? "+ WinprintFrame::OnIdle"
+ /* __CHANGE__
+ */
+ if(firstIdle) { $? ". first idle event"
+ firstIdle = false;
+ tStatus->SetLabel(wxT(""));
+ Refresh();
+ Update();
+ /* For autostart */
+ event.RequestMore();
+ } else { $? ". not the first idle event"
+ if(!bCloseScheduled) { $? ". no close scheduled"
+ if(pComm) { $? ". pComm"
+ if((bAutostartWanted) && (pComm->autostartCanRun())) {
+ $? ". autostart wanted and possible"
+ res = runJob();
+ if(res > 0) { $? ". request more"
+ event.RequestMore();
+ }
+ } else { $? ". autostart not wanted or not possible"
+ if(pComm->autostartIsFinished()) { $? ". autostart finished"
+ if(!(timeClose)) { $? ". no close time yet"
+ if(pComm->getLogLevel() > DK3_LL_WARNING) { $? ". can close"
+ dk3sf_time(&timeClose); $? ". close time scheduled"
+ event.RequestMore();
+ tStatus->SetLabel(sTexts[14]); $? ". tStatus 14"
+ tStatus->SetForegroundColour(cGreen);
+ Refresh();
+ Update();
+ } else {
+ tStatus->SetLabel(pComm->getText()); $? ". tStatus pComm"
+ tStatus->SetForegroundColour(cRed);
+ Refresh();
+ Update();
+ wxMessageBox(
+ pComm->getText(), sTexts[29], (wxICON_ERROR | wxOK), this
+ );
+ dk3sf_time(&timeClose); $? ". can close"
+ event.RequestMore();
+ }
+ }
+ }
+ if(timeClose) { $? ". found scheduled close time"
+ dk3sf_time(&ct);
+ if(ct > (timeClose + (dk3_time_t)1UL)) { $? ". close now"
+ timeClose = (dk3_time_t)0UL;
+ bCloseScheduled = true;
+ Show(false);
+ Close();
+ } else { $? ". can not yet close"
+ event.RequestMore();
+ }
+ }
+ }
+ } else { $? "! pComm"
+ /* ERROR: No communicator */
+ if(timeClose) {
+ dk3sf_time(&ct);
+ if(ct > (timeClose * (dk3_time_t)1UL)) {
+ timeClose = (dk3_time_t)0UL;
+ bCloseScheduled = true;
+ Show(false);
+ Close();
+ } else {
+ event.RequestMore();
+ }
+ }
+ }
+ } else { $? ". close scheduled"
+ }
+ }
+ event.Skip();
+ $? "- WinprintFrame::OnIdle"
+}
+
+
+
+int
+WinprintFrame::runJob(void)
+{
+ wxChar prbuf[512]; /* Printer name in system enc. */
+ wxString path; /* File path. */
+ wxChar const *filename = NULL; /* File name. */
+ wxChar const *printername = NULL; /* Printer name. */
+ int res; /* Operation result. */
+ int ok = 0; /* Flag: Success. */
+ int back = 0;
+ $? "+ WinprintFrame::runJob"
+ tStatus->SetLabel(sTexts[17]); $? ". tStatus 17"
+ tStatus->SetForegroundColour(cBlack);
+ Refresh();
+ Update();
+ if(sNamedFile) { $? ". named file"
+ filename = sNamedFile;
+ } else { $? ". no named file"
+ wxString s(wxT(""));
+ s.Append(wxT("Print files (*.prn)|*.prn"));
+ s.Append(wxT("|All files (*.*)|*.*"));
+#if wxCHECK_VERSION(2, 9, 0)
+ wxFileDialog dlg(this, sTexts[18], wxT("."), wxT(""), s, wxFD_OPEN);
+#else
+ wxFileDialog dlg(this, sTexts[18], wxT("."), wxT(""), s, wxOPEN);
+#endif
+ pHelper->setRelatedPosition(this, &dlg, &fdx, &fdy);
+ if(wxID_OK == dlg.ShowModal()) {
+ path = dlg.GetPath();
+ filename = path.c_str();
+ } else {
+ /* Aborted by user */
+ setErrorStatus(sTexts[19], NULL); $? ". setErrorStatus 19"
+ }
+ dlg.GetPosition(&fdx, &fdy);
+ }
+ if(filename) { $? ". have file"
+ if(bUseDefaultPrinter) { $? ". use default printer"
+ if(pc) { $? ". have print conf"
+ if(pc->defPrinter) { $? ". default printer"
+ if((pc->defPrinter->name)) { $? ". default printer name ok"
+ res = dk3wxs_from_dkstr(
+ prbuf,
+ DK3_SIZEOF(prbuf,wxChar),
+ pHelper->getWxEncoding(),
+ (pc->defPrinter)->name,
+ pHelper->getDkEncoding()
+ );
+ if(res) { $? ". name conversion ok"
+ printername = prbuf;
+ } else { $? "! name conversion failed"
+ /* ERROR: Failed to convert printer name! */
+ setErrorStatus(sTexts[24], filename); $? ". setErrorStatus 24"
+ }
+ } else { $? "! no default printer name"
+ /* ERROR: No default printer name */
+ setErrorStatus(sTexts[25], filename); $? ". setErrorStatus 25"
+ }
+ } else { $? "! no default printer"
+ /* ERROR: No default printer */
+ setErrorStatus(sTexts[25], filename); $? ". setErrorStatus 25"
+ }
+ } else { $? "! no print conf"
+ /* ERROR: No print configuration */
+ setErrorStatus(sTexts[26], filename); $? ". setErrorStatus 26"
+ }
+ } else { $? ". non-default printer"
+ if(sNamedPrinter) { $? ". named printer"
+ printername = sNamedPrinter;
+ } else { $? ". choose printer"
+ if((pNames) && (wxsNames) && (nNames > 0)) { $? ". variables"
+ WinprintChooserDialog dlg(this, sTexts[30], sTexts, wxsNames, nNames);
+ dlg.setCurrentPrinter(nDefPrinter);
+ pHelper->setRelatedPosition(this, &dlg, &pcx, &pcy);
+ if(wxID_OK == dlg.ShowModal()) { $? ". dialog ok"
+ nDefPrinter = dlg.getCurrentPrinter();
+ if((nDefPrinter >= 0) && (nDefPrinter < (int)nNames)) { $? ". ok"
+ printername = pNames[nDefPrinter];
+ } else { $? "! wrong index"
+ /* BUG: Illegal return value from dialog */
+ setErrorStatus(sTexts[26], filename); $? ". setErrorStatus 26"
+ }
+ } else { $? ". aborted by user"
+ /* ERROR: Aborted by user */
+ setErrorStatus(sTexts[19], filename); $? ". setErrorStatus 19"
+ }
+ dlg.GetPosition(&pcx, &pcy);
+ } else { $? "! variables"
+ /* ERROR: No printer configuration */
+ setErrorStatus(sTexts[26], filename); $? ". setErrorStatus 26"
+ }
+ }
+ }
+ } else { $? "! no file name"
+ }
+ if((filename) && (printername)) { $? ". both names ok"
+ /* wxMessageBox(filename, printername); */
+ if(pComm) { $? ". communicator ok"
+ DkWxProgressDialog *pd;
+ pComm->prepareRun();
+ pd = new DkWxProgressDialog(
+ (DkWxFrame *)this,
+ pComm,
+ NULL,
+ sTexts[20],
+ filename,
+ sTexts[21],
+ sTexts[22],
+ sTexts[23]
+ );
+ if(pd) { $? ". pd"
+ WinprintThread *pt;
+ pt = new WinprintThread(
+ pComm, sTexts, pHelper, pc, filename, printername
+ );
+ if(pt) { $? ". pt"
+ if(wxTHREAD_NO_ERROR == pt->Create()) { $? ". pt->Create"
+ pt->SetPriority(WXTHREAD_DEFAULT_PRIORITY);
+ pt->Run();
+ pd->chooseModalPosition();
+ pd->ShowModal();
+ ok = 1;
+ if(pComm->getLogLevel() <= DK3_LL_WARNING) { $? "! warning"
+ /* ERRORS occured */
+ tStatus->SetLabel(pComm->getText()); $? ". tStatus pComm"
+ tStatus->SetForegroundColour(cRed);
+ } else { $? ". success"
+ /* Transfer succeeeded */
+ if(!(bAutostartWanted)) {
+ tStatus->SetLabel(sTexts[37]); $? ". tStatus 37"
+ tStatus->SetForegroundColour(cGreen);
+ }
+ }
+ Refresh();
+ Update();
+ back = 1;
+ } else { $? "! pt->Create"
+ /* ERROR: Create method failed! */
+ setErrorStatus(sTexts[27], filename); $? ". setErrorStatus 27"
+ }
+ } else { $? "! pt"
+ /* ERROR: Failed to create thread */
+ setErrorStatus(sTexts[27], filename); $? ". setErrorStatus 27"
+ }
+ pd->Destroy();
+ } else { $? "! pd"
+ /* ERROR: Failed to create progress dialog */
+ setErrorStatus(sTexts[28], filename); $? ". setErrorStatus 28"
+ }
+ } else { $? "! communicator"
+ /* ###### ERROR: No communicator */
+ }
+ } else { $? "! name missing"
+ if(pComm) {
+ if(!(filename)) {
+ }
+ if(!(printername)) {
+ }
+ } else {
+ /* ##### ERROR: No communicator */
+ }
+ } $? "- WinprintFrame::runJob %d", back
+ return back;
+}
+
+
+
+void
+WinprintFrame::setErrorStatus(wxChar const *txt, wxChar const *filename)
+{
+ if(pComm) {
+ pComm->prepareRun();
+ pComm->addWxText(txt);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ pComm->setUpdates(((filename) ? filename : wxT("")), 1000);
+ pComm->setRunning(0);
+ }
+ tStatus->SetLabel(txt);
+ tStatus->SetForegroundColour(cRed);
+ Refresh();
+ Update();
+}
+
+
diff --git a/support/dktools/WinprintThread.cpp b/support/dktools/WinprintThread.cpp
new file mode 100644
index 0000000000..a953b97d90
--- /dev/null
+++ b/support/dktools/WinprintThread.cpp
@@ -0,0 +1,319 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: WinprintThread.cpt
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file WinprintThread.cpp The WinprintThread module.
+*/
+
+
+#line 85 "WinprintThread.cpt"
+
+
+#include "winprint.h"
+
+
+
+
+#line 91 "WinprintThread.cpt"
+
+
+
+WinprintThread::WinprintThread(
+ DkWxCommunicator *communicator,
+ wxChar const * const *localizedTexts,
+ DkWxAppHelper *applicationHelper,
+ dk3_print_conf_t *printConfiguration,
+ wxChar const *fileName,
+ wxChar const *printerName
+)
+{
+
+
+#line 104 "WinprintThread.cpt"
+ pComm = communicator;
+ sTexts = localizedTexts;
+ pHelper = applicationHelper;
+ pc = printConfiguration;
+ dkenc = applicationHelper->getDkEncoding();
+ sFilename = NULL;
+ sPrintername = NULL;
+ if(fileName) {
+ sFilename = dk3wxs_dup(fileName);
+ }
+ if(printerName) {
+ sPrintername = dk3wxs_dup(printerName);
+ }
+
+
+#line 118 "WinprintThread.cpt"
+}
+
+
+
+WinprintThread::~WinprintThread()
+{
+ /* Release resources. */
+
+
+#line 126 "WinprintThread.cpt"
+ dk3_release(sPrintername);
+ dk3_release(sFilename);
+
+
+#line 129 "WinprintThread.cpt"
+}
+
+
+
+bool
+WinprintThread::checkSetup()
+{
+ bool back = false;
+
+
+#line 138 "WinprintThread.cpt"
+ if((sFilename) && (sPrintername)) {
+ back = true;
+ }
+
+#line 141 "WinprintThread.cpt"
+ return back;
+}
+
+
+
+void *
+WinprintThread::Entry()
+{
+ void *back = NULL;
+ /* Switch between a test version (1) and the real version (0).
+ */
+#if 0
+ int i;
+
+
+#line 155 "WinprintThread.cpt"
+ for(i = 0; i < 10; i++) {
+ this->Sleep(200);
+ pComm->setUpdates(sFilename, 100*i);
+ }
+ pComm->setUpdates(sFilename, 1000);
+ pComm->addWxText(wxT("Test error message"));
+ /* pComm->setLogLevel(DK3_LL_ERROR); */
+ pComm->setRunning(0);
+
+
+#line 164 "WinprintThread.cpt"
+#else
+ char buf[4096]; /* Buffer for copying data.*/
+ dkChar pName[DK3_MAX_PATH]; /* Buffer for printer name. */
+ dkChar fName[DK3_MAX_PATH]; /* Buffer for file name. */
+#if DK3_CHAR_SIZE > 1
+ char ajbu[sizeof(ADDJOB_INFO_1W)+(sizeof(dkChar)*DK3_MAX_PATH)];
+ /* Buffer for job creation. */
+ ADDJOB_INFO_1W *aji1; /* Job creation structure. */
+#else
+ char ajbu[sizeof(ADDJOB_INFO_1A)+(sizeof(dkChar)*DK3_MAX_PATH)];
+ /* Buffer for job creation. */
+ ADDJOB_INFO_1A *aji1; /* Job creation structure. */
+#endif
+ dk3_stat_t stb; /* Information about named file. */
+ FILE *ifile; /* Input file. */
+ HANDLE hPr; /* Printer handle. */
+ HANDLE hFile; /* Handle for print job file. */
+ dk3_um_t summary; /* Number of bytes processed. */
+ DWORD dwAcc; /* Access permissions required. */
+ DWORD dwSh; /* Print job file share mode. */
+ DWORD dwDisp; /* Print job file disposition. */
+ DWORD dwAttr; /* Print job file attributes. */
+ DWORD dwSz; /* Buffer size for job creation. */
+ DWORD written; /* NUmber of bytes currently written. */
+ DWORD dwNeeded; /* Number of bytes needed. */
+ size_t szrd; /* Number of bytes read from file. */
+ int dke; /* dkChar encoding. */
+ int wxe; /* wxChar encoding. */
+ int havestat; /* Flag: File information found. */
+ int ok; /* Flag: Success. */
+ int level; /* Data structure level. */
+ BOOL bres; /* Operation result. */
+
+
+#line 197 "WinprintThread.cpt"
+ dke = pHelper->getDkEncoding();
+ wxe = pHelper->getWxEncoding();
+ if(dk3wxs_to_dkstr(pName,DK3_SIZEOF(pName,dkChar),dke,sPrintername,wxe)) {
+ if(dk3wxs_to_dkstr(fName,DK3_SIZEOF(fName,dkChar),dke,sFilename,wxe)) {
+ pComm->setUpdates(sFilename, WINPRINT_LEVEL_1);
+ hPr = INVALID_HANDLE_VALUE;
+#if DK3_CHAR_SIZE > 1
+ bres = OpenPrinterW(pName, &hPr, NULL);
+#else
+ bres = OpenPrinterA(pName, &hPr, NULL);
+#endif
+ if(bres) {
+ dwSz = sizeof(ajbu);
+ dwNeeded = (DWORD)0UL;
+#if DK3_CHAR_SIZE > 1
+ bres = AddJobW(hPr, 1, (LPBYTE)ajbu, dwSz, &dwNeeded);
+#else
+ bres = AddJobA(hPr, 1, (LPBYTE)ajbu, dwSz, &dwNeeded);
+#endif
+ if(bres) {
+ aji1 = (ADDJOB_INFO_1 *)ajbu;
+ if(aji1->Path) {
+ hFile = INVALID_HANDLE_VALUE;
+ dwAcc = GENERIC_WRITE;
+ dwSh = FILE_SHARE_READ;
+ dwDisp = CREATE_ALWAYS;
+ dwAttr = FILE_ATTRIBUTE_NORMAL;
+#if DK3_CHAR_SIZE > 1
+ hFile = CreateFileW(aji1->Path,dwAcc,dwSh,NULL,dwDisp,dwAttr,NULL);
+#else
+ hFile = CreateFileA(aji1->Path,dwAcc,dwSh,NULL,dwDisp,dwAttr,NULL);
+#endif
+ if(INVALID_HANDLE_VALUE != hFile) {
+ if(dk3sf_stat_app(&stb, fName, NULL)) {
+ havestat = 1;
+ }
+ ifile = dk3sf_fopen_app(fName, dkT("rb"), pHelper->getApp());
+ if(ifile) {
+ ok = 1;
+ summary = (dk3_um_t)DK3_UM_0;
+ do {
+ szrd = dk3sf_fread_app(
+ (void *)buf, 1, sizeof(buf), ifile, pHelper->getApp()
+ );
+ if(szrd > 0) {
+ bres = WriteFile(
+ hFile, (LPCVOID)buf, (DWORD)szrd, &written, NULL
+ );
+ if(bres) {
+ if(written == (DWORD)szrd) {
+ summary += (dk3_um_t)written;
+ if(havestat) {
+ level = WINPRINT_LEVEL_1 +
+ (
+ (WINPRINT_LEVEL_2 - WINPRINT_LEVEL_1)
+ * summary
+ ) / stb.sz;
+ if(level >= WINPRINT_LEVEL_2) {
+ level = WINPRINT_LEVEL_2;
+ }
+ pComm->setUpdates(sFilename, level);
+ }
+ } else {
+ ok = 0;
+ /* ERROR: Too few bytes! */
+ pComm->addWxText(sTexts[38]);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ }
+ } else {
+ ok = 0;
+ /* ERROR: Write failed! */
+ pComm->addWxText(sTexts[38]);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ }
+ }
+ } while((szrd > 0) && (ok));
+ fclose(ifile);
+ } else {
+ /* ERROR: Failed to open input file! */
+ pComm->addWxText(sTexts[39]);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ }
+ CloseHandle(hFile);
+ pComm->setUpdates(sFilename, WINPRINT_LEVEL_2);
+ if(ScheduleJob(hPr, aji1->JobId)) {
+ /* ##### SUCCESS */
+ } else {
+ /* ERROR: Failed to schedule job! */
+ pComm->addWxText(sTexts[40]);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ }
+ } else {
+ /* ERROR: Failed to create file! */
+ pComm->addWxText(sTexts[41]);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ }
+ } else {
+ /* ERROR: Path not set in add job info */
+ pComm->addWxText(sTexts[42]);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ }
+ } else {
+ /* ERROR: Failed to add job! */
+ pComm->addWxText(sTexts[42]);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ }
+ ClosePrinter(hPr);
+ } else {
+ /* ERROR: Failed to open printer! */
+ pComm->addWxText(sTexts[43]);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ }
+ } else {
+ /* ERROR: Failed to convert file name! */
+ pComm->addWxText(sTexts[44]);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ }
+ } else {
+ /* ERROR: Failed to convert printer name! */
+ pComm->addWxText(sTexts[45]);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ }
+ pComm->setUpdates(sFilename, 1000);
+ pComm->setRunning(0);
+
+
+#line 322 "WinprintThread.cpt"
+#endif
+ return back;
+}
+
+
+
+void
+WinprintThread::OnExit()
+{
+
+
+#line 332 "WinprintThread.cpt"
+
+
+#line 333 "WinprintThread.cpt"
+}
+
+
+
+
diff --git a/support/dktools/WinprintThread.cpt b/support/dktools/WinprintThread.cpt
new file mode 100644
index 0000000000..c5af61985f
--- /dev/null
+++ b/support/dktools/WinprintThread.cpt
@@ -0,0 +1,337 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2013-xxxx
+license = bsd
+
+%% header
+
+class WinprintThread : public wxThread
+{
+ protected:
+
+ /** File to print.
+ */
+ wxChar const *sFilename;
+
+ /** Printer to use.
+ */
+ dkChar const *sPrintername;
+
+ /** Communicator object.
+ */
+ DkWxCommunicator *pComm;
+
+ /** Localized texts.
+ */
+ wxChar const * const *sTexts;
+
+ /** Application helper.
+ */
+ DkWxAppHelper *pHelper;
+
+ /** Print configuration.
+ */
+ dk3_print_conf_t *pc;
+
+ /** Encoding for dkChar strings.
+ */
+ int dkenc;
+
+ public:
+
+ /** Constructor.
+ @param communicator Communication object.
+ @param localizedTexts Localized texts.
+ @param applicationHelper Application helper object.
+ @param printConfiguration Print configuration.
+ @param fileName File to print.
+ @param printerName Printer to use.
+ */
+ WinprintThread(
+ DkWxCommunicator *communicator,
+ wxChar const * const *localizedTexts,
+ DkWxAppHelper *applicationHelper,
+ dk3_print_conf_t *printConfiguration,
+ wxChar const *fileName,
+ wxChar const *printerName
+ );
+
+ /** Destructor.
+ */
+ ~WinprintThread();
+
+ /** Check setup.
+ @return true on success, false on error.
+ */
+ bool
+ checkSetup();
+
+ /** Thread function.
+ @return Pointer which is ignored.
+ */
+ virtual
+ void *
+ Entry();
+
+ /** Method executed at end of thread, doest nothing.
+ */
+ virtual
+ void
+ OnExit();
+};
+
+%% module
+
+
+#include "winprint.h"
+
+
+$!trace-include
+
+
+
+WinprintThread::WinprintThread(
+ DkWxCommunicator *communicator,
+ wxChar const * const *localizedTexts,
+ DkWxAppHelper *applicationHelper,
+ dk3_print_conf_t *printConfiguration,
+ wxChar const *fileName,
+ wxChar const *printerName
+)
+{
+ $? "+ WinprintThread::WinprintThread"
+ pComm = communicator;
+ sTexts = localizedTexts;
+ pHelper = applicationHelper;
+ pc = printConfiguration;
+ dkenc = applicationHelper->getDkEncoding();
+ sFilename = NULL;
+ sPrintername = NULL;
+ if(fileName) {
+ sFilename = dk3wxs_dup(fileName);
+ }
+ if(printerName) {
+ sPrintername = dk3wxs_dup(printerName);
+ }
+ $? "- WinprintThread::WinprintThread"
+}
+
+
+
+WinprintThread::~WinprintThread()
+{
+ /* Release resources. */
+ $? "+ WinprintThread::~WinprintThread"
+ dk3_release(sPrintername);
+ dk3_release(sFilename);
+ $? "- WinprintThread::~WinprintThread"
+}
+
+
+
+bool
+WinprintThread::checkSetup()
+{
+ bool back = false;
+ $? "+ WinprintThread::checkSetup"
+ if((sFilename) && (sPrintername)) {
+ back = true;
+ } $? "- WinprintThread::checkSetup %d", ((back) ? 1 : 0)
+ return back;
+}
+
+
+
+void *
+WinprintThread::Entry()
+{
+ void *back = NULL;
+ /* Switch between a test version (1) and the real version (0).
+ */
+#if 0
+ int i;
+ $? "+ WinprintThread::Entry (test)"
+ for(i = 0; i < 10; i++) {
+ this->Sleep(200);
+ pComm->setUpdates(sFilename, 100*i);
+ }
+ pComm->setUpdates(sFilename, 1000);
+ pComm->addWxText(wxT("Test error message"));
+ /* pComm->setLogLevel(DK3_LL_ERROR); */
+ pComm->setRunning(0);
+ $? "- WinprintThread::Entry (test)"
+#else
+ char buf[4096]; /* Buffer for copying data.*/
+ dkChar pName[DK3_MAX_PATH]; /* Buffer for printer name. */
+ dkChar fName[DK3_MAX_PATH]; /* Buffer for file name. */
+#if DK3_CHAR_SIZE > 1
+ char ajbu[sizeof(ADDJOB_INFO_1W)+(sizeof(dkChar)*DK3_MAX_PATH)];
+ /* Buffer for job creation. */
+ ADDJOB_INFO_1W *aji1; /* Job creation structure. */
+#else
+ char ajbu[sizeof(ADDJOB_INFO_1A)+(sizeof(dkChar)*DK3_MAX_PATH)];
+ /* Buffer for job creation. */
+ ADDJOB_INFO_1A *aji1; /* Job creation structure. */
+#endif
+ dk3_stat_t stb; /* Information about named file. */
+ FILE *ifile; /* Input file. */
+ HANDLE hPr; /* Printer handle. */
+ HANDLE hFile; /* Handle for print job file. */
+ dk3_um_t summary; /* Number of bytes processed. */
+ DWORD dwAcc; /* Access permissions required. */
+ DWORD dwSh; /* Print job file share mode. */
+ DWORD dwDisp; /* Print job file disposition. */
+ DWORD dwAttr; /* Print job file attributes. */
+ DWORD dwSz; /* Buffer size for job creation. */
+ DWORD written; /* NUmber of bytes currently written. */
+ DWORD dwNeeded; /* Number of bytes needed. */
+ size_t szrd; /* Number of bytes read from file. */
+ int dke; /* dkChar encoding. */
+ int wxe; /* wxChar encoding. */
+ int havestat; /* Flag: File information found. */
+ int ok; /* Flag: Success. */
+ int level; /* Data structure level. */
+ BOOL bres; /* Operation result. */
+ $? "+ WinprintThread::Entry (real)"
+ dke = pHelper->getDkEncoding();
+ wxe = pHelper->getWxEncoding();
+ if(dk3wxs_to_dkstr(pName,DK3_SIZEOF(pName,dkChar),dke,sPrintername,wxe)) {
+ if(dk3wxs_to_dkstr(fName,DK3_SIZEOF(fName,dkChar),dke,sFilename,wxe)) {
+ pComm->setUpdates(sFilename, WINPRINT_LEVEL_1);
+ hPr = INVALID_HANDLE_VALUE;
+#if DK3_CHAR_SIZE > 1
+ bres = OpenPrinterW(pName, &hPr, NULL);
+#else
+ bres = OpenPrinterA(pName, &hPr, NULL);
+#endif
+ if(bres) {
+ dwSz = sizeof(ajbu);
+ dwNeeded = (DWORD)0UL;
+#if DK3_CHAR_SIZE > 1
+ bres = AddJobW(hPr, 1, (LPBYTE)ajbu, dwSz, &dwNeeded);
+#else
+ bres = AddJobA(hPr, 1, (LPBYTE)ajbu, dwSz, &dwNeeded);
+#endif
+ if(bres) {
+ aji1 = (ADDJOB_INFO_1 *)ajbu;
+ if(aji1->Path) {
+ hFile = INVALID_HANDLE_VALUE;
+ dwAcc = GENERIC_WRITE;
+ dwSh = FILE_SHARE_READ;
+ dwDisp = CREATE_ALWAYS;
+ dwAttr = FILE_ATTRIBUTE_NORMAL;
+#if DK3_CHAR_SIZE > 1
+ hFile = CreateFileW(aji1->Path,dwAcc,dwSh,NULL,dwDisp,dwAttr,NULL);
+#else
+ hFile = CreateFileA(aji1->Path,dwAcc,dwSh,NULL,dwDisp,dwAttr,NULL);
+#endif
+ if(INVALID_HANDLE_VALUE != hFile) {
+ if(dk3sf_stat_app(&stb, fName, NULL)) {
+ havestat = 1;
+ }
+ ifile = dk3sf_fopen_app(fName, dkT("rb"), pHelper->getApp());
+ if(ifile) {
+ ok = 1;
+ summary = (dk3_um_t)DK3_UM_0;
+ do {
+ szrd = dk3sf_fread_app(
+ (void *)buf, 1, sizeof(buf), ifile, pHelper->getApp()
+ );
+ if(szrd > 0) {
+ bres = WriteFile(
+ hFile, (LPCVOID)buf, (DWORD)szrd, &written, NULL
+ );
+ if(bres) {
+ if(written == (DWORD)szrd) {
+ summary += (dk3_um_t)written;
+ if(havestat) {
+ level = WINPRINT_LEVEL_1 +
+ (
+ (WINPRINT_LEVEL_2 - WINPRINT_LEVEL_1)
+ * summary
+ ) / stb.sz;
+ if(level >= WINPRINT_LEVEL_2) {
+ level = WINPRINT_LEVEL_2;
+ }
+ pComm->setUpdates(sFilename, level);
+ }
+ } else {
+ ok = 0;
+ /* ERROR: Too few bytes! */
+ pComm->addWxText(sTexts[38]);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ }
+ } else {
+ ok = 0;
+ /* ERROR: Write failed! */
+ pComm->addWxText(sTexts[38]);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ }
+ }
+ } while((szrd > 0) && (ok));
+ fclose(ifile);
+ } else {
+ /* ERROR: Failed to open input file! */
+ pComm->addWxText(sTexts[39]);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ }
+ CloseHandle(hFile);
+ pComm->setUpdates(sFilename, WINPRINT_LEVEL_2);
+ if(ScheduleJob(hPr, aji1->JobId)) {
+ /* ##### SUCCESS */
+ } else {
+ /* ERROR: Failed to schedule job! */
+ pComm->addWxText(sTexts[40]);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ }
+ } else {
+ /* ERROR: Failed to create file! */
+ pComm->addWxText(sTexts[41]);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ }
+ } else {
+ /* ERROR: Path not set in add job info */
+ pComm->addWxText(sTexts[42]);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ }
+ } else {
+ /* ERROR: Failed to add job! */
+ pComm->addWxText(sTexts[42]);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ }
+ ClosePrinter(hPr);
+ } else {
+ /* ERROR: Failed to open printer! */
+ pComm->addWxText(sTexts[43]);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ }
+ } else {
+ /* ERROR: Failed to convert file name! */
+ pComm->addWxText(sTexts[44]);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ }
+ } else {
+ /* ERROR: Failed to convert printer name! */
+ pComm->addWxText(sTexts[45]);
+ pComm->setLogLevel(DK3_LL_ERROR);
+ }
+ pComm->setUpdates(sFilename, 1000);
+ pComm->setRunning(0);
+ $? "- WinprintThread::Entry (real)"
+#endif
+ return back;
+}
+
+
+
+void
+WinprintThread::OnExit()
+{
+ $? "+ WinprintThread::OnExit"
+ $? "- WinprintThread::OnExit"
+}
+
+
+
+
diff --git a/support/dktools/WinprintThread.h b/support/dktools/WinprintThread.h
new file mode 100644
index 0000000000..7b88e4643a
--- /dev/null
+++ b/support/dktools/WinprintThread.h
@@ -0,0 +1,122 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: WinprintThread.cpt
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file WinprintThread.h Header file for the WinprintThread module.
+*/
+
+#ifndef WINPRINTTHREAD_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define WINPRINTTHREAD_H_INCLUDED 1
+
+
+#line 8 "WinprintThread.cpt"
+
+class WinprintThread : public wxThread
+{
+ protected:
+
+ /** File to print.
+ */
+ wxChar const *sFilename;
+
+ /** Printer to use.
+ */
+ dkChar const *sPrintername;
+
+ /** Communicator object.
+ */
+ DkWxCommunicator *pComm;
+
+ /** Localized texts.
+ */
+ wxChar const * const *sTexts;
+
+ /** Application helper.
+ */
+ DkWxAppHelper *pHelper;
+
+ /** Print configuration.
+ */
+ dk3_print_conf_t *pc;
+
+ /** Encoding for dkChar strings.
+ */
+ int dkenc;
+
+ public:
+
+ /** Constructor.
+ @param communicator Communication object.
+ @param localizedTexts Localized texts.
+ @param applicationHelper Application helper object.
+ @param printConfiguration Print configuration.
+ @param fileName File to print.
+ @param printerName Printer to use.
+ */
+ WinprintThread(
+ DkWxCommunicator *communicator,
+ wxChar const * const *localizedTexts,
+ DkWxAppHelper *applicationHelper,
+ dk3_print_conf_t *printConfiguration,
+ wxChar const *fileName,
+ wxChar const *printerName
+ );
+
+ /** Destructor.
+ */
+ ~WinprintThread();
+
+ /** Check setup.
+ @return true on success, false on error.
+ */
+ bool
+ checkSetup();
+
+ /** Thread function.
+ @return Pointer which is ignored.
+ */
+ virtual
+ void *
+ Entry();
+
+ /** Method executed at end of thread, doest nothing.
+ */
+ virtual
+ void
+ OnExit();
+};
+
+
+#endif
diff --git a/support/dktools/WxpqdicApp.cpp b/support/dktools/WxpqdicApp.cpp
new file mode 100644
index 0000000000..33ed4e0895
--- /dev/null
+++ b/support/dktools/WxpqdicApp.cpp
@@ -0,0 +1,549 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: WxpqdicApp.cpt
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file WxpqdicApp.cpp The WxpqdicApp module.
+*/
+
+
+#line 76 "WxpqdicApp.cpt"
+
+#include "wxpqdic.h"
+
+
+
+
+
+#line 82 "WxpqdicApp.cpt"
+
+
+
+/** Localized wxChar texts.
+*/
+static wxChar const * wxpqdic_texts[] = {
+/* 0 */
+wxT("File"),
+
+/* 1 */
+wxT("Quit"),
+
+/* 2 */
+wxT("Exit the application"),
+
+/* 3 */
+wxT("Help"),
+
+/* 4 */
+wxT("About"),
+
+/* 5 */
+wxT("Show version information"),
+
+/* 6 */
+wxT("Contents"),
+
+/* 7 */
+wxT("Open table of contents"),
+
+/* 8 */
+wxT("Ready"),
+
+/* 9 */
+wxT("Copyright (c) "),
+
+/* 10 */
+wxT("About "),
+
+/* 11 */
+wxT("This program uses the following libraries:"),
+
+/* 12 */
+wxT("See:"),
+
+/* 13 */
+wxT("Limit: "),
+
+/* 14 */
+wxT("unlimited"),
+
+/* 15 */
+wxT("Used: "),
+
+/* 16 */
+wxT("00000000"),
+
+/* 17 */
+wxT("Personal print account: "),
+
+/* 18 */
+wxT("Printing allowed: "),
+
+/* 19 */
+wxT("YES"),
+
+/* 20 */
+wxT("NO"),
+
+/* 21 */
+wxT("Waiting for response from server."),
+
+/* 22 */
+wxT("View"),
+
+/* 23 */
+wxT("Update"),
+
+/* 24 */
+wxT("Update information in Window"),
+
+/* 25 */
+wxT("Update"),
+
+/* 26 */
+wxT("Exit"),
+
+/* 27 */
+wxT("unknown"),
+
+/* 28 */
+wxT("Failed to send request!"),
+
+/* 29 */
+wxT("No response from server!"),
+
+/* 30 */
+wxT("Command line"),
+
+/* 31 */
+wxT("Failed to parse command line, illegal options used!"),
+
+/* 32 */
+wxT("Insufficient memory"),
+
+/* 33 */
+wxT("A memory allocation failed due to insufficient memory!"),
+
+/* 34 */
+wxT("Illegal host name"),
+
+/* 35 */
+wxT("Failed to convert host name to portable string!"),
+
+/* 36 */
+wxT("Missing host name"),
+
+/* 37 */
+wxT("No host name specified! Please use\n-h host\nto specify the remote host."),
+
+/* 38 */
+wxT("Illegal queue name"),
+
+/* 39 */
+wxT("Failed to convert queue name to 8 bit character string!"),
+
+/* 40 */
+wxT("Missing queue name"),
+
+/* 41 */
+wxT("No queue name specified! Please use\n-q queue\n to specify the queue name."),
+
+/* 42 */
+wxT("Illegal remote port"),
+
+/* 43 */
+wxT("Remote port number out of 16 bit range!"),
+
+/* 44 */
+wxT("Remote port number 0 can not be used!"),
+
+/* 45 */
+wxT("Illegal user name"),
+
+/* 46 */
+wxT("Failed to convert user name to 8 bit character string!"),
+
+/* 47 */
+wxT("No user name"),
+
+/* 48 */
+wxT("User name not found!"),
+
+/* 49 */
+wxT("Illegal local port"),
+
+/* 50 */
+wxT("Local port number out of 16 bit range!"),
+
+/* 51 */
+wxT("Local port number 0 can not be used!"),
+
+/* 52 */
+wxT("Bug"),
+
+/* 53 */
+wxT("Failed to construct request string!"),
+
+/* 54 */
+wxT("Numeric overflow"),
+
+/* 55 */
+wxT("A numeric overflow occured in size calculation!"),
+
+/* 56 */
+wxT("Network error"),
+
+/* 57 */
+wxT("Failed to create communication socket!"),
+
+/* 58 */
+wxT("Error"),
+
+/* 59 */
+wxT("An unknown error occured during setup!"),
+
+NULL
+
+
+#line 279 "WxpqdicApp.cpt"
+};
+
+
+
+/** Non-localized wxChar texts.
+*/
+static wxChar const * wxpqdic_nl_wx[] = {
+/* 0 */
+wxT("wxpqdic"),
+
+/* 1 */
+wxT("4.3.0"),
+
+/* 2 */
+wxT("Dirk Krause"),
+
+/* 3 */
+wxT("DKrause"),
+
+/* 4 */
+wxT("aaaaa"),
+
+/* 5 */
+wxT(""),
+
+/* 6 */
+wxT(""),
+
+/* 7 */
+wxT(" "),
+
+/* 8 */
+wxT("\n"),
+
+/* 9 */
+wxT("DK tools, wxWidgets, libpng, libjpeg, libtiff, zlib."),
+
+/* 10 */
+wxT("http://dktools.sourceforge.net"),
+
+/* 11 */
+wxT("http://www.wxwidgets.org"),
+
+/* 12 */
+wxT("http://www.libpng.org/pub/png/libpng.html"),
+
+/* 13 */
+wxT("http://www.ijg.org"),
+
+/* 14 */
+wxT("http://www.remotesensing.org/libtiff"),
+
+/* 15 */
+wxT("http://www.zlib.net"),
+
+/* 16 */
+wxT("UTF-8"),
+
+/* 17 */
+wxT("utf8"),
+
+/* 18 */
+wxT("Error"),
+
+/* 19 */
+wxT("Not enough memory (RAM)!"),
+
+NULL
+
+
+#line 346 "WxpqdicApp.cpt"
+};
+
+
+
+/** Non-localized dkChar texts.
+*/
+static dkChar const * wxpqdic_nl_dk[] = {
+/* 0 */
+dkT("dktools"),
+
+/* 1 */
+dkT("wxpqdc.str"),
+
+/* 2 */
+dkT("wxpqdic.chm"),
+
+/* 3 */
+dkT("wxpqdic.htb"),
+
+NULL
+
+
+#line 371 "WxpqdicApp.cpt"
+};
+
+
+
+/** Implementation of the wxApp functionality.
+*/
+IMPLEMENT_APP(WxpqdicApp)
+
+
+bool
+WxpqdicApp::OnInit()
+{
+ WxpqdicFrame *frame = NULL;
+ wxChar const * const *localizedTexts = NULL;
+ wxPNGHandler *phPng = NULL;
+ wxXPMHandler *phXpm = NULL;
+ wxICOHandler *phIco = NULL;
+ wxArchiveFSHandler *phArchiveFS = NULL;
+ bool back = false;
+
+
+
+#line 392 "WxpqdicApp.cpt"
+
+
+#line 393 "WxpqdicApp.cpt"
+
+ /* Initialize members.
+ */
+ pAh = NULL;
+ pHc = NULL;
+
+ /* __CHANGE__ 009: Initialize further members here.
+ */
+ bSocketsInitialized = false;
+
+ /* Set up application helper object.
+ */
+ pAh = new Dk4WxApplicationHelper();
+ if (NULL == pAh) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ if (!(pAh->Initialize(argv[0], wxpqdic_nl_wx[3], wxpqdic_nl_dk[0])))
+ {
+
+#line 412 "WxpqdicApp.cpt"
+ goto finished;
+ }
+
+ /* Add image and file system handlers for online help.
+ */
+ phPng = new wxPNGHandler();
+ if (NULL != phPng) {
+ wxImage::AddHandler(phPng);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phXpm = new wxXPMHandler();
+ if (NULL != phXpm) {
+ wxImage::AddHandler(phXpm);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phIco = new wxICOHandler();
+ if (NULL != phIco) {
+ wxImage::AddHandler(phIco);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phArchiveFS = new wxArchiveFSHandler();
+ if (NULL != phArchiveFS) {
+ wxFileSystem::AddHandler(phArchiveFS);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ /* Set up help controller.
+ */
+ pHc = new Dk4WxHelpController();
+ if (NULL == pHc) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ if (!(pHc->Initialize(pAh, wxpqdic_nl_dk[2], wxpqdic_nl_dk[3])))
+ {
+
+#line 455 "WxpqdicApp.cpt"
+ goto finished;
+ }
+
+ /* Attempt to get localized texts in the users preferred language.
+ */
+ localizedTexts = pAh->GetStringTable(wxpqdic_nl_dk[1], wxpqdic_texts);
+ if(!(localizedTexts)) { localizedTexts = wxpqdic_texts; }
+
+ /* Initialize socket sub system.
+ */
+ dk4error_init(&sockerr);
+ if (DK4_SOCKET_RESULT_SUCCESS == dk4socket_up(&sockerr)) {
+ bSocketsInitialized = true;
+ }
+
+ /* Create and show frame.
+ */
+ frame = new WxpqdicFrame(
+ WxpqdicFrame_MainWindow,
+ pAh,
+ pHc,
+ argc,
+ argv,
+ localizedTexts,
+ wxpqdic_nl_wx,
+ wxpqdic_nl_dk,
+ bSocketsInitialized,
+ &sockerr
+ );
+ if(!(frame)) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ /* Show frame and indicate success.
+ */
+ frame->Show();
+ frame->RestorePosition();
+ back = true;
+
+ /* Release resources if initialization failed.
+ */
+ finished:
+ if(!(back)) {
+ if (NULL != pHc) {
+ pHc->Cleanup();
+ delete(pHc);
+ pHc = NULL;
+ }
+ if (NULL != pAh) {
+ pAh->Cleanup();
+ delete(pAh);
+ pAh = NULL;
+ }
+ }
+
+
+#line 511 "WxpqdicApp.cpt"
+#if 0
+ if(!(back)) {
+
+
+#line 514 "WxpqdicApp.cpt"
+ }
+#endif
+ return back;
+}
+
+
+
+int
+WxpqdicApp::OnExit()
+{
+ int back = 0;
+
+
+#line 526 "WxpqdicApp.cpt"
+ /* __CHANGE__ 009: Release resources allocated by further members.
+ */
+ if (bSocketsInitialized) {
+ dk4socket_down(NULL);
+ }
+
+ /* Release resources. */
+ if (NULL != pHc) {
+ pHc->Cleanup();
+ delete(pHc);
+ pHc = NULL;
+ }
+ if (NULL != pAh) {
+ pAh->Cleanup();
+ delete(pAh);
+ pAh = NULL;
+ }
+
+
+#line 544 "WxpqdicApp.cpt"
+
+
+#line 545 "WxpqdicApp.cpt"
+ return back;
+}
+
+
+
+void
+WxpqdicApp::ShowMemoryErrorMessage(void)
+{
+ const wxChar *s_title = NULL;
+ const wxChar *s_text = NULL;
+
+ if (NULL != pAh) {
+ s_title = pAh->GetBasicString(6);
+ s_text = pAh->GetBasicString(7);
+ }
+ if (NULL == s_title) {
+ s_title = wxpqdic_nl_wx[18];
+ }
+ if (NULL == s_text) {
+ s_text = wxpqdic_nl_wx[19];
+ }
+ wxMessageBox(s_text, s_title, (wxOK | wxCENTRE | wxICON_ERROR));
+}
+
+
diff --git a/support/dktools/WxpqdicApp.cpt b/support/dktools/WxpqdicApp.cpt
new file mode 100644
index 0000000000..bef55e979e
--- /dev/null
+++ b/support/dktools/WxpqdicApp.cpt
@@ -0,0 +1,569 @@
+%% options
+
+copyright owner = Dirk Krause
+
+copyright year = 2016-xxxx
+
+license = bsd
+
+
+
+%% header
+
+/** @file WxpqdicApp.h The WxpqdicApp class.
+*/
+
+
+
+/** Application class, derived from wxApp, one instance per program.
+*/
+class WxpqdicApp : public wxApp
+{
+ protected:
+
+ /** Helper object.
+ */
+ Dk4WxApplicationHelper *pAh;
+
+ /** Controller fr online help.
+ */
+ Dk4WxHelpController *pHc;
+
+ /* __CHANGE__ 009: Add further members here.
+ */
+
+ /** Error report if the initialization of socket subsystem fails.
+ */
+ dk4_er_t sockerr;
+
+ /** Flag: Socket subsystem initialized successfully.
+ */
+ bool bSocketsInitialized;
+
+ protected:
+
+ /** Show error message if there is not enough memory.
+ */
+ void
+ ShowMemoryErrorMessage(void);
+
+ public:
+
+ /** Application initialization.
+ @return true on success, false on error.
+ */
+ virtual
+ bool
+ OnInit();
+
+ /** Application shutdown.
+ @return 0 on success, any other value indicates an error.
+ */
+ virtual
+ int
+ OnExit();
+};
+
+
+
+/** Declaration as the wxApp object.
+*/
+DECLARE_APP(WxpqdicApp)
+
+
+
+%% module
+
+#include "wxpqdic.h"
+
+
+
+$!trace-include
+
+
+
+/** Localized wxChar texts.
+*/
+static wxChar const * wxpqdic_texts[] = {
+$!string-table macro=wxT
+#
+# 0: Menu "File"
+#
+File
+#
+# 1: Menu item "File/Quit"
+#
+Quit
+#
+# 2: Tool tip text for menu item "File/Exit"
+#
+Exit the application
+#
+# 3: Menu "Help"
+#
+Help
+#
+# 4: Menu item "Help/About"
+#
+About
+#
+# 5: Tooltip text for menu item "Help/About"
+#
+Show version information
+#
+# 6: Menu item "Help/Contents"
+#
+Contents
+#
+# 7: Tooltip text for menu item "Help/Contents"
+#
+Open table of contents
+#
+# 8: Initial status text
+#
+Ready
+#
+# 9: Copyright notice.
+#
+Copyright (c)
+#
+# 10: Dialog box title "About ..."
+#
+About
+#
+# 11: This program uses the following libraries
+#
+This program uses the following libraries:
+#
+# 12: See
+#
+See:
+#
+# 13: Label text "Limit:"
+#
+Limit:
+#
+# 14: Limit value "unlimited"
+#
+unlimited
+#
+# 15: Label text "Used:"
+#
+Used:
+#
+# 16: Dummy label text to initialize number of used pages
+#
+00000000
+#
+# 17: Label text "Personal print account:"
+#
+Personal print account:
+#
+# 18: Label text "Printing allowed:"
+#
+Printing allowed:
+#
+# 19 20: Result text values
+#
+YES
+NO
+#
+# 21: Label text "Waiting for response from server."
+#
+Waiting for response from server.
+#
+# 22: Menu "View"
+#
+View
+#
+# 23: Menu item: View -> Update
+#
+Update
+#
+# 24: Tool tip text for menu item: View -> Update
+#
+Update information in Window
+#
+# 25: Toolbar button text "Update"
+#
+Update
+#
+# 26: Toolbar button text "Exit"
+#
+Exit
+#
+# 27: Information: unknown
+#
+unknown
+#
+# 28: Error: Failed to send request
+#
+Failed to send request!
+#
+# 29: Error: No response from server!
+#
+No response from server!
+#
+# 30 31
+#
+Command line
+Failed to parse command line, illegal options used!
+#
+# 32 33
+#
+Insufficient memory
+A memory allocation failed due to insufficient memory!
+#
+# 34 35
+#
+Illegal host name
+Failed to convert host name to portable string!
+#
+# 36 37
+#
+Missing host name
+No host name specified! Please use\n-h host\nto specify the remote host.
+#
+# 38 39
+#
+Illegal queue name
+Failed to convert queue name to 8 bit character string!
+#
+# 40 41
+#
+Missing queue name
+No queue name specified! Please use\n-q queue\n to specify the queue name.
+#
+# 42 43 44
+#
+Illegal remote port
+Remote port number out of 16 bit range!
+Remote port number 0 can not be used!
+#
+# 45 46
+#
+Illegal user name
+Failed to convert user name to 8 bit character string!
+#
+# 47 48
+#
+No user name
+User name not found!
+#
+# 49 50 51
+#
+Illegal local port
+Local port number out of 16 bit range!
+Local port number 0 can not be used!
+#
+# 52 53
+#
+Bug
+Failed to construct request string!
+#
+# 54 55
+#
+Numeric overflow
+A numeric overflow occured in size calculation!
+#
+# 56 57
+#
+Network error
+Failed to create communication socket!
+#
+# 58 59
+#
+Error
+An unknown error occured during setup!
+$!end
+};
+
+
+
+/** Non-localized wxChar texts.
+*/
+static wxChar const * wxpqdic_nl_wx[] = {
+$!string-table macro=wxT
+#
+# 0: Program name.
+#
+wxpqdic
+#
+# 1: Program version.
+#
+4.3.0
+#
+# 2: Copyright owner name.
+#
+Dirk Krause
+#
+# 3: Software vendor name.
+# if necessary. Must be one
+# string without spaces.
+#
+DKrause
+#
+# 4: Resource name of Windows icon
+#
+aaaaa
+#
+# 5: UNUSED (previously Windows chm help file name)
+#
+
+#
+# 6: UNUSED (previously non-Windows htb help file name)
+#
+
+#
+# 7: Space
+#
+
+#
+# 8: Newline
+#
+\n
+#
+# 9 10 11 12 13 14 15: List of libraries used.
+#
+DK tools, wxWidgets, libpng, libjpeg, libtiff, zlib.
+http://dktools.sourceforge.net
+http://www.wxwidgets.org
+http://www.libpng.org/pub/png/libpng.html
+http://www.ijg.org
+http://www.remotesensing.org/libtiff
+http://www.zlib.net
+#
+# 16 17
+#
+UTF-8
+utf8
+#
+# 18 19
+#
+Error
+Not enough memory (RAM)!
+$!end
+};
+
+
+
+/** Non-localized dkChar texts.
+*/
+static dkChar const * wxpqdic_nl_dk[] = {
+$!string-table macro=dkT
+#
+# 0: Program group name.
+#
+dktools
+#
+# 1: String table name.
+#
+wxpqdc.str
+#
+# 2: CHM help file name
+#
+wxpqdic.chm
+#
+# 3: HTB help file name
+#
+wxpqdic.htb
+$!end
+};
+
+
+
+/** Implementation of the wxApp functionality.
+*/
+IMPLEMENT_APP(WxpqdicApp)
+
+
+bool
+WxpqdicApp::OnInit()
+{
+ WxpqdicFrame *frame = NULL;
+ wxChar const * const *localizedTexts = NULL;
+ wxPNGHandler *phPng = NULL;
+ wxXPMHandler *phXpm = NULL;
+ wxICOHandler *phIco = NULL;
+ wxArchiveFSHandler *phArchiveFS = NULL;
+ bool back = false;
+
+ $!trace-init c:\\temp\\wxpqdic.deb
+ $? "+ OnInit"
+
+ /* Initialize members.
+ */
+ pAh = NULL;
+ pHc = NULL;
+
+ /* __CHANGE__ 009: Initialize further members here.
+ */
+ bSocketsInitialized = false;
+
+ /* Set up application helper object.
+ */
+ pAh = new Dk4WxApplicationHelper();
+ if (NULL == pAh) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ if (!(pAh->Initialize(argv[0], wxpqdic_nl_wx[3], wxpqdic_nl_dk[0])))
+ { $? "! pAh failed"
+ goto finished;
+ }
+
+ /* Add image and file system handlers for online help.
+ */
+ phPng = new wxPNGHandler();
+ if (NULL != phPng) {
+ wxImage::AddHandler(phPng);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phXpm = new wxXPMHandler();
+ if (NULL != phXpm) {
+ wxImage::AddHandler(phXpm);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phIco = new wxICOHandler();
+ if (NULL != phIco) {
+ wxImage::AddHandler(phIco);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ phArchiveFS = new wxArchiveFSHandler();
+ if (NULL != phArchiveFS) {
+ wxFileSystem::AddHandler(phArchiveFS);
+ } else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ /* Set up help controller.
+ */
+ pHc = new Dk4WxHelpController();
+ if (NULL == pHc) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ if (!(pHc->Initialize(pAh, wxpqdic_nl_dk[2], wxpqdic_nl_dk[3])))
+ { $? "! pHc failed"
+ goto finished;
+ }
+
+ /* Attempt to get localized texts in the users preferred language.
+ */
+ localizedTexts = pAh->GetStringTable(wxpqdic_nl_dk[1], wxpqdic_texts);
+ if(!(localizedTexts)) { localizedTexts = wxpqdic_texts; }
+
+ /* Initialize socket sub system.
+ */
+ dk4error_init(&sockerr);
+ if (DK4_SOCKET_RESULT_SUCCESS == dk4socket_up(&sockerr)) {
+ bSocketsInitialized = true;
+ }
+
+ /* Create and show frame.
+ */
+ frame = new WxpqdicFrame(
+ WxpqdicFrame_MainWindow,
+ pAh,
+ pHc,
+ argc,
+ argv,
+ localizedTexts,
+ wxpqdic_nl_wx,
+ wxpqdic_nl_dk,
+ bSocketsInitialized,
+ &sockerr
+ );
+ if(!(frame)) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ /* Show frame and indicate success.
+ */
+ frame->Show();
+ frame->RestorePosition();
+ back = true;
+
+ /* Release resources if initialization failed.
+ */
+ finished:
+ if(!(back)) {
+ if (NULL != pHc) {
+ pHc->Cleanup();
+ delete(pHc);
+ pHc = NULL;
+ }
+ if (NULL != pAh) {
+ pAh->Cleanup();
+ delete(pAh);
+ pAh = NULL;
+ }
+ }
+ $? "- OnInit %d", ((back) ? 1 : 0)
+#if 0
+ if(!(back)) {
+ $!trace-end
+ }
+#endif
+ return back;
+}
+
+
+
+int
+WxpqdicApp::OnExit()
+{
+ int back = 0;
+ $? "+ OnExit"
+ /* __CHANGE__ 009: Release resources allocated by further members.
+ */
+ if (bSocketsInitialized) {
+ dk4socket_down(NULL);
+ }
+
+ /* Release resources. */
+ if (NULL != pHc) {
+ pHc->Cleanup();
+ delete(pHc);
+ pHc = NULL;
+ }
+ if (NULL != pAh) {
+ pAh->Cleanup();
+ delete(pAh);
+ pAh = NULL;
+ }
+ $? "- OnExit %d", back
+ $!trace-end
+ return back;
+}
+
+
+
+void
+WxpqdicApp::ShowMemoryErrorMessage(void)
+{
+ const wxChar *s_title = NULL;
+ const wxChar *s_text = NULL;
+
+ if (NULL != pAh) {
+ s_title = pAh->GetBasicString(6);
+ s_text = pAh->GetBasicString(7);
+ }
+ if (NULL == s_title) {
+ s_title = wxpqdic_nl_wx[18];
+ }
+ if (NULL == s_text) {
+ s_text = wxpqdic_nl_wx[19];
+ }
+ wxMessageBox(s_text, s_title, (wxOK | wxCENTRE | wxICON_ERROR));
+}
+
+
diff --git a/support/dktools/WxpqdicApp.h b/support/dktools/WxpqdicApp.h
new file mode 100644
index 0000000000..e7ddc822f9
--- /dev/null
+++ b/support/dktools/WxpqdicApp.h
@@ -0,0 +1,106 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: WxpqdicApp.cpt
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef WXPQDICAPP_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define WXPQDICAPP_H_INCLUDED 1
+
+
+#line 12 "WxpqdicApp.cpt"
+
+/** @file WxpqdicApp.h The WxpqdicApp class.
+*/
+
+
+
+/** Application class, derived from wxApp, one instance per program.
+*/
+class WxpqdicApp : public wxApp
+{
+ protected:
+
+ /** Helper object.
+ */
+ Dk4WxApplicationHelper *pAh;
+
+ /** Controller fr online help.
+ */
+ Dk4WxHelpController *pHc;
+
+ /* __CHANGE__ 009: Add further members here.
+ */
+
+ /** Error report if the initialization of socket subsystem fails.
+ */
+ dk4_er_t sockerr;
+
+ /** Flag: Socket subsystem initialized successfully.
+ */
+ bool bSocketsInitialized;
+
+ protected:
+
+ /** Show error message if there is not enough memory.
+ */
+ void
+ ShowMemoryErrorMessage(void);
+
+ public:
+
+ /** Application initialization.
+ @return true on success, false on error.
+ */
+ virtual
+ bool
+ OnInit();
+
+ /** Application shutdown.
+ @return 0 on success, any other value indicates an error.
+ */
+ virtual
+ int
+ OnExit();
+};
+
+
+
+/** Declaration as the wxApp object.
+*/
+DECLARE_APP(WxpqdicApp)
+
+
+
+
+#endif
diff --git a/support/dktools/WxpqdicFrame.cpp b/support/dktools/WxpqdicFrame.cpp
new file mode 100644
index 0000000000..8de45643d3
--- /dev/null
+++ b/support/dktools/WxpqdicFrame.cpp
@@ -0,0 +1,1592 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: WxpqdicFrame.wxc
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file WxpqdicFrame.cpp The WxpqdicFrame module.
+*/
+
+
+#line 415 "WxpqdicFrame.wxc"
+
+#include "wxpqdic.h"
+#include "dk4user.h"
+#include "dk4enc.h"
+#include "dk4strd.h"
+#include "dk4rec.h"
+#include "dk4str8.h"
+#include "dk4strx.h"
+#include "dk4recwx.h"
+#include "dk4maasz.h"
+#include "dk4mai8ddu.h"
+#include "dk4mai8dii.h"
+#include "dk4mao8d.h"
+#include "dk4maowd.h"
+#include "dk4numco.h"
+
+
+#include "exit-program.xpm"
+#include "run-conversion.xpm"
+
+#include "dk4verswx.h"
+
+#if !defined(__WXMSW__)
+#include "dkicon.xpm"
+#endif
+
+
+
+
+
+#line 444 "WxpqdicFrame.wxc"
+
+
+
+/* __CHANGE__ 017: Add further events. */
+/* __CHANGE__ 008: Remove OnIdle if no idle processing required. */
+BEGIN_EVENT_TABLE(WxpqdicFrame, wxFrame)
+ EVT_MENU(WxpqdicFrame_View_Update, WxpqdicFrame::OnRun)
+ EVT_MENU(WxpqdicFrame_Quit, WxpqdicFrame::OnQuit)
+ EVT_MENU(WxpqdicFrame_Help_About, WxpqdicFrame::OnAbout)
+ EVT_MENU(WxpqdicFrame_Help_Contents, WxpqdicFrame::OnHelpContents)
+ EVT_TIMER(WxpqdicFrame_Timer, WxpqdicFrame::OnTimer)
+ EVT_IDLE(WxpqdicFrame::OnIdle)
+END_EVENT_TABLE()
+
+
+
+static const wxChar versionNumber[] = { DKT_VERSION_WX };
+
+
+
+static const wxCmdLineEntryDesc wxpqdic_cmd_line_entries[] = {
+ {
+ wxCMD_LINE_OPTION,
+ wxT_2("h"),
+ wxT_2("host"),
+ wxT_2("Host to connect to."),
+ wxCMD_LINE_VAL_STRING,
+ 0
+ },
+ {
+ wxCMD_LINE_OPTION,
+ wxT_2("p"),
+ wxT_2("port"),
+ wxT_2("Port number to connect to."),
+ wxCMD_LINE_VAL_NUMBER,
+ 0
+ },
+ {
+ wxCMD_LINE_OPTION,
+ wxT_2("l"),
+ wxT_2("local-port"),
+ wxT_2("Local port number to use."),
+ wxCMD_LINE_VAL_NUMBER,
+ 0
+ },
+ {
+ wxCMD_LINE_OPTION,
+ wxT_2("q"),
+ wxT_2("queue"),
+ wxT_2("Queue name to check."),
+ wxCMD_LINE_VAL_STRING,
+ 0
+ },
+ {
+ wxCMD_LINE_OPTION,
+ wxT_2("u"),
+ wxT_2("user"),
+ wxT_2("User name to check."),
+ wxCMD_LINE_VAL_STRING,
+ 0
+ },
+ {
+ wxCMD_LINE_OPTION,
+ wxT_2("i"),
+ wxT_2("interval"),
+ wxT_2("Time interval for automatic update."),
+ wxCMD_LINE_VAL_NUMBER,
+ 0
+ },
+ {
+ wxCMD_LINE_OPTION,
+ wxT_2("a"),
+ wxT_2("ascii"),
+ wxT_2("Remote host uses ASCII encoding, not UTF-8."),
+ wxCMD_LINE_VAL_NONE,
+ 0
+ },
+ { wxCMD_LINE_NONE }
+};
+
+
+
+/** Key names for preferences.
+*/
+static const wxChar * const wxpqdic_pref_key_names[] = {
+/* 0 */
+wxT("printqd.host"),
+
+/* 1 */
+wxT("printqd.port"),
+
+/* 2 */
+wxT("printqd.queue"),
+
+/* 3 */
+wxT("printqd.interval"),
+
+/* 4 */
+wxT("printqd.local"),
+
+/* 5 */
+wxT("printqd.encoding"),
+
+NULL
+
+
+#line 537 "WxpqdicFrame.wxc"
+};
+
+
+
+/** Constant 8-bit strings, not localized.
+*/
+static const char * const wxpqdic_kw[] = {
+/* 0 */
+"\n",
+
+/* 1 */
+" ",
+
+/* 2 */
+"info",
+
+NULL
+
+
+#line 558 "WxpqdicFrame.wxc"
+};
+
+
+
+#line 562 "WxpqdicFrame.wxc"
+WxpqdicFrame::WxpqdicFrame(
+ int wxid,
+ Dk4WxApplicationHelper *applicationHelper,
+ Dk4WxHelpController *hc,
+ int argc,
+ wxChar **argv,
+ wxChar const * const *localizedTexts,
+ wxChar const * const *nlWx,
+ dkChar const * const *nlDk,
+ bool bSocketsInitialized,
+ dk4_er_t *psockerr
+) : Dk4WxFrame(nlWx[0], applicationHelper, hc, wxid),
+ sHostname(wxT("")),
+ sQueuename(wxT("")),
+ sUsername(wxT("")),
+ cBlack(0, 0, 0),
+ cRed(127, 0, 0),
+ cGreen(0, 127, 0),
+ timer(this, WxpqdicFrame_Timer)
+
+{
+ /* __CHANGE__ 012: Add further local variables.
+ */
+
+ /* __CHANGE__ 012: Initialize further local variables.
+ */
+
+ sTexts = localizedTexts;
+ sNlWx = nlWx;
+ sNlDk = nlDk;
+#if defined(__WXMSW__)
+ wxIcon wxpqdic_icon(sNlWx[4]);
+#else
+ wxIcon wxpqdic_icon(xpm_dkicon);
+#endif
+
+ /* __CHANGE__ 011: Initialize further class members.
+ */
+ bSockInit = bSocketsInitialized;
+ DK4_MEMCPY(&sockerr, psockerr, sizeof(dk4_er_t));
+ pHostname = NULL;
+ pQueuename = NULL;
+ pUsername = NULL;
+ pRequest = NULL;
+ szRequest = (size_t)0UL;
+ lUpdateInterval = 30L;
+ lWaitResponse = 1L;
+ usPortnumber = 9100;
+ usLocalPort = 9100;
+ bIsUtf8 = true;
+ bFirstIdle = true;
+ bFirstResponse = true;
+ bIsInitialized = false;
+ copyArgc = argc;
+ copyArgv = argv;
+ sock = INVALID_SOCKET;
+ iState = WXPQDIC_STATE_OK;
+ tRequestSended = (dk4_time_t)0UL;
+ szResponse = sizeof(bResponse);
+ DK4_MEMRES(&(aAddresses[0]), (2*sizeof(dk4_sockaddr_storage_t)));
+
+ dkctGUILayoutOK = false;
+ dkctGUIContentsPanel = NULL;
+ mainSizer = NULL;
+ mbMain = NULL;
+ tbMain = NULL;
+ menuFile = NULL;
+ menuView = NULL;
+ menuHelp = NULL;
+ miFileExit = NULL;
+ miViewUpdate = NULL;
+ miHelpAbout = NULL;
+ miHelpContents = NULL;
+ verticalSizer = NULL;
+ contentsSizer = NULL;
+ lLimit = NULL;
+ tLimit = NULL;
+ lUsed = NULL;
+ tUsed = NULL;
+ lAccount = NULL;
+ tAccount = NULL;
+ lAllowed = NULL;
+ tAllowed = NULL;
+ lStatus = NULL;
+ bUpdate = NULL;
+ bExit = NULL;
+ dkctGUIContentsPanel = new wxPanel(this);
+ if(!(dkctGUIContentsPanel)) {
+ goto dkctGUILayoutFinished;
+ }
+#if wxUSE_MENUS
+ mbMain = new wxMenuBar(
+ );
+ if(!(mbMain)) {
+ goto dkctGUILayoutFinished;
+ }
+ menuFile = new wxMenu(
+ );
+ if(!(menuFile)) {
+ goto dkctGUILayoutFinished;
+ }
+ miFileExit = menuFile->Append(
+ WxpqdicFrame_Quit,
+ sTexts[1],
+ sTexts[2]
+ );
+ if(!(miFileExit)) {
+ goto dkctGUILayoutFinished;
+ }
+ mbMain->Append(menuFile, sTexts[0]);
+ menuView = new wxMenu(
+ );
+ if(!(menuView)) {
+ goto dkctGUILayoutFinished;
+ }
+ miViewUpdate = menuView->Append(
+ WxpqdicFrame_View_Update,
+ sTexts[23],
+ sTexts[24]
+ );
+ if(!(miViewUpdate)) {
+ goto dkctGUILayoutFinished;
+ }
+ mbMain->Append(menuView, sTexts[22]);
+ menuHelp = new wxMenu(
+ );
+ if(!(menuHelp)) {
+ goto dkctGUILayoutFinished;
+ }
+ miHelpAbout = menuHelp->Append(
+ WxpqdicFrame_Help_About,
+ sTexts[4],
+ sTexts[5]
+ );
+ if(!(miHelpAbout)) {
+ goto dkctGUILayoutFinished;
+ }
+ miHelpContents = menuHelp->Append(
+ WxpqdicFrame_Help_Contents,
+ sTexts[6],
+ sTexts[7]
+ );
+ if(!(miHelpContents)) {
+ goto dkctGUILayoutFinished;
+ }
+ mbMain->Append(menuHelp, sTexts[3]);
+ SetMenuBar(mbMain);
+#endif
+#if wxUSE_TOOLBAR
+ tbMain = new wxToolBar(
+ this,
+ wxID_ANY
+ );
+ if(!(tbMain)) {
+ goto dkctGUILayoutFinished;
+ }
+ bUpdate = tbMain->AddTool(
+ WxpqdicFrame_View_Update,
+ sTexts[25],
+ xpm_run_conversion,
+ wxNullBitmap,
+ wxITEM_NORMAL,
+ sTexts[24]
+ );
+ if(!(bUpdate)) {
+ goto dkctGUILayoutFinished;
+ }
+ bExit = tbMain->AddTool(
+ WxpqdicFrame_Quit,
+ sTexts[26],
+ xpm_exit_program,
+ wxNullBitmap,
+ wxITEM_NORMAL,
+ sTexts[2]
+ );
+ if(!(bExit)) {
+ goto dkctGUILayoutFinished;
+ }
+ tbMain->Realize();
+ SetToolBar(tbMain);
+#endif
+ mainSizer = new wxBoxSizer(
+ wxHORIZONTAL
+ );
+ if(!(mainSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ mainSizer->Add(10, 10, 0);
+ verticalSizer = new wxBoxSizer(
+ wxVERTICAL
+ );
+ if(!(verticalSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ verticalSizer->Add(10, 10, 0);
+ contentsSizer = new wxGridBagSizer(
+ 2, 2
+ );
+ if(!(contentsSizer)) {
+ goto dkctGUILayoutFinished;
+ }
+ lLimit = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[13]
+ );
+ if(!(lLimit)) {
+ goto dkctGUILayoutFinished;
+ }
+ contentsSizer->Add(
+ lLimit,
+ wxGBPosition(0, 0),
+ wxGBSpan(1, 1),
+ wxALIGN_RIGHT
+ );
+ tLimit = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[14]
+ );
+ if(!(tLimit)) {
+ goto dkctGUILayoutFinished;
+ }
+ contentsSizer->Add(
+ tLimit,
+ wxGBPosition(0, 1),
+ wxGBSpan(1, 1)
+ );
+ lUsed = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[15]
+ );
+ if(!(lUsed)) {
+ goto dkctGUILayoutFinished;
+ }
+ contentsSizer->Add(
+ lUsed,
+ wxGBPosition(1, 0),
+ wxGBSpan(1, 1),
+ wxALIGN_RIGHT
+ );
+ tUsed = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[27]
+ );
+ if(!(tUsed)) {
+ goto dkctGUILayoutFinished;
+ }
+ contentsSizer->Add(
+ tUsed,
+ wxGBPosition(1, 1),
+ wxGBSpan(1, 1)
+ );
+ contentsSizer->Add(5, 5, wxGBPosition(2, 0), wxGBSpan(1, 1));
+ lAccount = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[17]
+ );
+ if(!(lAccount)) {
+ goto dkctGUILayoutFinished;
+ }
+ contentsSizer->Add(
+ lAccount,
+ wxGBPosition(3, 0),
+ wxGBSpan(1, 1),
+ wxALIGN_RIGHT
+ );
+ tAccount = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[16]
+ );
+ if(!(tAccount)) {
+ goto dkctGUILayoutFinished;
+ }
+ contentsSizer->Add(
+ tAccount,
+ wxGBPosition(3, 1),
+ wxGBSpan(1, 1)
+ );
+ contentsSizer->Add(5, 5, wxGBPosition(4, 0), wxGBSpan(1, 1));
+ lAllowed = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[18]
+ );
+ if(!(lAllowed)) {
+ goto dkctGUILayoutFinished;
+ }
+ contentsSizer->Add(
+ lAllowed,
+ wxGBPosition(5, 0),
+ wxGBSpan(1, 1),
+ wxALIGN_RIGHT
+ );
+ tAllowed = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[27]
+ );
+ if(!(tAllowed)) {
+ goto dkctGUILayoutFinished;
+ }
+ contentsSizer->Add(
+ tAllowed,
+ wxGBPosition(5, 1),
+ wxGBSpan(1, 1)
+ );
+ contentsSizer->Add(5, 5, wxGBPosition(6, 0), wxGBSpan(1, 1));
+ lStatus = new wxStaticText(
+ dkctGUIContentsPanel,
+ wxID_ANY,
+ sTexts[21]
+ );
+ if(!(lStatus)) {
+ goto dkctGUILayoutFinished;
+ }
+ contentsSizer->Add(
+ lStatus,
+ wxGBPosition(7, 0),
+ wxGBSpan(1, 2)
+ );
+ verticalSizer->Add(
+ contentsSizer
+ );
+ verticalSizer->Add(10, 10, 0);
+ mainSizer->Add(
+ verticalSizer,
+ 1,
+ wxGROW
+ );
+ mainSizer->Add(10, 10, 0);
+ dkctGUIContentsPanel->SetSizer(mainSizer);
+ SetIcon(wxpqdic_icon);
+ dkctGUILayoutOK = true;
+ dkctGUILayoutFinished:
+#if wxUSE_STATUSBAR
+ if(dkctGUILayoutOK) {
+ CreateStatusBar(1);
+ SetStatusText(sTexts[8]);
+ }
+#endif
+ if(dkctGUILayoutOK) {
+ mainSizer->Fit(this);
+ mainSizer->SetSizeHints(this);
+ }
+
+#line 624 "WxpqdicFrame.wxc"
+ if(dkctGUILayoutOK) {
+ SetTitle(nlWx[0]);
+ }
+
+
+ /* __CHANGE__ 012: Release resources allocated by local variables.
+ */
+}
+
+
+#line 634 "WxpqdicFrame.wxc"
+
+
+
+WxpqdicFrame::~WxpqdicFrame()
+{
+
+ /* __CHANGE__ 011: Release resources allocated by further class members.
+ */
+}
+
+
+
+bool
+WxpqdicFrame::CanClose(bool isLast)
+{
+ bool back = true;
+
+ return back;
+}
+
+
+void
+WxpqdicFrame::OnQuit(wxCommandEvent & event)
+{
+ {
+ wxCriticalSectionLocker lockCsProtect(csProtect);
+ if (bIsInitialized) {
+ timer.Stop();
+ bIsInitialized = false;
+ }
+ }
+ if (INVALID_SOCKET != sock) {
+ dk4socket_close(sock, NULL);
+ sock = INVALID_SOCKET;
+ }
+ dk4mem_release(pUsername);
+ dk4mem_release(pQueuename);
+ dk4mem_release(pHostname);
+ dk4mem_release(pRequest);
+ Show(false);
+ /* !!!!! TODO: Release resources */
+ Close();
+}
+
+
+
+void
+WxpqdicFrame::OnAbout(wxCommandEvent & event)
+{
+ wxString text(wxT(""));
+ wxString title(wxT(""));
+
+ /* Construct message text. */
+ text.Append(sNlWx[0]);
+ text.Append(sNlWx[7]);
+#if 0
+ text.Append(sNlWx[1]);
+#endif
+ text.Append(versionNumber);
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[9]);
+ text.Append(sNlWx[2]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[11]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[9]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[12]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[10]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[11]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[12]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[13]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[14]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[15]);
+ text.Append(sNlWx[8]);
+
+ /* Construct dialog box title. */
+ title.Append(sTexts[10]);
+ title.Append(sNlWx[0]);
+
+ /* Show dialog box. */
+ wxMessageBox(text, title);
+
+}
+
+
+
+void
+WxpqdicFrame::OnHelpContents(wxCommandEvent & event)
+{
+ DisplayContents();
+}
+
+/* __CHANGE__ 017: Event handlers for further events.
+*/
+
+/* __CHANGE__ 014: Implementation of further methods.
+*/
+
+
+bool
+WxpqdicFrame::ConfigureAndCheckNeedToClose(int *perrc)
+{
+
+ dkChar buf[1024];
+ char c8b[1024];
+ dk4_er_t er;
+ wxChar *pv[] = { NULL, NULL, NULL, NULL, NULL, NULL };
+ const wxChar *cptr;
+ const size_t szbuf = DK4_SIZEOF(buf,dkChar);
+ const size_t szc8b = sizeof(c8b);
+ long l = 0L;
+ int res = 0;
+ bool back = true;
+
+ /* Retrieve some fallback values from preferences.
+ */
+ pAppHelp->GetMultiple(wxpqdic_pref_key_names, pv, 6);
+
+
+#line 761 "WxpqdicFrame.wxc"
+
+
+#line 762 "WxpqdicFrame.wxc"
+
+
+#line 763 "WxpqdicFrame.wxc"
+
+
+#line 764 "WxpqdicFrame.wxc"
+
+
+#line 765 "WxpqdicFrame.wxc"
+
+
+#line 766 "WxpqdicFrame.wxc"
+
+ /* Check command line arguments
+ */
+ {
+ wxLogNull log;
+ wxCmdLineParser parser(wxpqdic_cmd_line_entries, copyArgc, copyArgv);
+ res = parser.Parse(false);
+ /*
+ Check overall parsing of arguments
+ */
+ if (0 != res) {
+
+#line 777 "WxpqdicFrame.wxc"
+ /* ERROR: Failed to parse command line arguments */
+ *perrc = WXPQDIC_FRAME_ERROR_PARSE;
+ goto finished;
+ }
+ /*
+ Option -a means the remote host wants ASCII data.
+ */
+ if (parser.Found(wxT_2("a"))) {
+ bIsUtf8 = false;
+ } else {
+ if (NULL != pv[5]) {
+ if (0 != dk4strx_casecmp(pv[5], sNlWx[16])) {
+ if (0 != dk4strx_casecmp(pv[5], sNlWx[17])) {
+ bIsUtf8 = false;
+ }
+ }
+ }
+ }
+ /*
+ Try to obtain host name from arguments or from preferences.
+ */
+ dk4error_init(&er);
+ cptr = NULL;
+ if (parser.Found(wxT_2("h"), &sHostname)) {
+ cptr = sHostname.c_str();
+ }
+ else {
+ cptr = pv[0];
+ }
+ if (NULL != cptr) {
+ if (pAppHelp->StringToDk(buf, szbuf, cptr, &er)) {
+ pHostname = dk4str_dup(buf, NULL);
+ if (NULL == pHostname) {
+
+#line 810 "WxpqdicFrame.wxc"
+ /* ERROR: Memory */
+ *perrc = WXPQDIC_FRAME_ERROR_MEMORY;
+ goto finished;
+ }
+ } else {
+ /* ERROR: Failed to convert string */
+ *perrc = WXPQDIC_FRAME_ERROR_STRCONV_HOSTNAME;
+ goto finished;
+ }
+ }
+ if (NULL == pHostname) {
+ /* ERROR: Missing host name */
+ *perrc = WXPQDIC_FRAME_ERROR_HOSTNAME;
+ goto finished;
+ }
+ /*
+ Queue name is required.
+ */
+ cptr = NULL;
+ if (parser.Found(wxT_2("q"), &sQueuename)) {
+ cptr = sQueuename.c_str();
+ }
+ else {
+ cptr = pv[2];
+ }
+ if (NULL != cptr) {
+ res = dk4recwx_wxchar_to_char(
+ c8b, szc8b, ((bIsUtf8) ? (DK4_ENCODING_UTF8) : (DK4_ENCODING_ASCII)),
+ cptr, pAppHelp->GetWxEncoding(), NULL
+ );
+ if (0 != res) {
+ pQueuename = dk4str8_dup(c8b, NULL);
+ if (NULL == pQueuename) {
+
+#line 843 "WxpqdicFrame.wxc"
+ /* ERROR: Memory */
+ *perrc = WXPQDIC_FRAME_ERROR_MEMORY;
+ goto finished;
+ }
+ } else {
+ /* ERROR: String conversion failed */
+ *perrc = WXPQDIC_FRAME_ERROR_STRCONV_QUEUENAME;
+ goto finished;
+ }
+ }
+ else {
+ /* ERROR: Missing queue name */
+ *perrc = WXPQDIC_FRAME_ERROR_QUEUENAME;
+ goto finished;
+ }
+ if (NULL == pQueuename) {
+ /* ERROR: Missing queue name */
+ *perrc = WXPQDIC_FRAME_ERROR_QUEUENAME;
+ goto finished;
+ }
+ /*
+ Port number is optional.
+ */
+ {
+ bool portnoFound = false;
+ l = 0L;
+ if (parser.Found(wxT_2("p"), &l)) {
+ portnoFound = true;
+ }
+ else {
+ if (NULL != pv[1]) {
+ wxString s(pv[1]);
+ if (s.ToLong(&l, 0)) {
+ portnoFound = true;
+ }
+ }
+ }
+ if (portnoFound) {
+ if ((long)(USHRT_MAX) < l) {
+ /* ERROR: Port number out of range */
+ *perrc = WXPQDIC_FRAME_ERROR_PORT_OOR;
+ goto finished;
+ }
+ if (0L == l) {
+ /* ERROR: Illegal port number 0 */
+ *perrc = WXPQDIC_FRAME_ERROR_PORT_ZERO;
+ goto finished;
+ }
+ usPortnumber = (unsigned short)l;
+ }
+ }
+ /*
+ Local port number is optional.
+ */
+ {
+ bool portnoFound = false;
+ l = 0L;
+ if (parser.Found(wxT_2("l"), &l)) {
+ portnoFound = true;
+ }
+ else {
+ if (NULL != pv[4]) {
+ wxString s(pv[4]);
+ if (s.ToLong(&l, 0)) {
+ portnoFound = true;
+ }
+ }
+ }
+ if (portnoFound) {
+ if ((long)(USHRT_MAX) < l) {
+ /* ERROR: Port number out of range */
+ *perrc = WXPQDIC_FRAME_ERROR_LOCALPORT_OOR;
+ goto finished;
+ }
+ if (0L == l) {
+ /* ERROR: Illegal port number 0 */
+ *perrc = WXPQDIC_FRAME_ERROR_LOCALPORT_ZERO;
+ goto finished;
+ }
+ usLocalPort = (unsigned short)l;
+ }
+ }
+ /*
+ User name is optional, use current user by default.
+ */
+ if (parser.Found(wxT_2("u"), &sUsername)) {
+ res = dk4recwx_wxchar_to_char(
+ c8b, szc8b, ((bIsUtf8) ? (DK4_ENCODING_UTF8) : (DK4_ENCODING_ASCII)),
+ sUsername.c_str(), pAppHelp->GetWxEncoding(), NULL
+ );
+ if (0 != res) {
+ pUsername = dk4str8_dup(c8b, NULL);
+ if (NULL == pUsername) {
+ /* ERROR: Memory */
+ *perrc = WXPQDIC_FRAME_ERROR_MEMORY;
+ goto finished;
+ }
+ }
+ else {
+ /* ERROR: Failed to convert user name */
+ *perrc = WXPQDIC_FRAME_ERROR_STRCONV_USERNAME;
+ goto finished;
+ }
+ }
+ else {
+ res = dk4user_get_logname(buf, szbuf, 0, NULL);
+ if (0 != res) {
+ res = dk4recode_dk_to_any(
+ c8b, szc8b, ((bIsUtf8) ? (DK4_ENCODING_UTF8) : (DK4_ENCODING_ASCII)),
+ buf, pAppHelp->GetDkEncoding(), NULL
+ );
+ if (0 != res) {
+ pUsername = dk4str8_dup(c8b, NULL);
+ if (NULL == pUsername) {
+ /* ERROR: Memory */
+ *perrc = WXPQDIC_FRAME_ERROR_MEMORY;
+ goto finished;
+ }
+ }
+ else {
+ /* ERROR: Failed to convert user name */
+ *perrc = WXPQDIC_FRAME_ERROR_STRCONV_USERNAME;
+ goto finished;
+ }
+ } else {
+ /* ERROR: User name not found! */
+ *perrc = WXPQDIC_FRAME_ERROR_USERNAME;
+ goto finished;
+ }
+ }
+ if (NULL == pUsername) {
+ /* ERROR: No user name */
+ *perrc = WXPQDIC_FRAME_ERROR_USERNAME;
+ goto finished;
+ }
+ /*
+ Interval length is optional.
+ */
+ {
+ bool intervalFound = false;
+ l = 0L;
+ if (parser.Found(wxT_2("p"), &l)) {
+ intervalFound = true;
+ }
+ else {
+ if (NULL != pv[3]) {
+ wxString s(pv[3]);
+ if (s.ToLong(&l, 0)) {
+ intervalFound = true;
+ }
+ }
+ }
+ if (intervalFound) {
+ if (5L <= l) {
+ lUpdateInterval = l;
+ } else {
+ lUpdateInterval = 5L;
+ }
+ }
+ }
+ /*
+ Now build request
+ */
+ dk4error_init(&er);
+ szRequest = strlen(wxpqdic_kw[2]);
+ szRequest = dk4ma_size_t_add(szRequest, dk4str8_len(pQueuename), &er);
+ szRequest = dk4ma_size_t_add(szRequest, dk4str8_len(pUsername), &er);
+ szRequest = dk4ma_size_t_add(szRequest, dk4str8_len(wxpqdic_kw[2]), &er);
+ szRequest = dk4ma_size_t_add(szRequest, 4, &er);
+ if (DK4_E_NONE == er.ec) {
+ pRequest = dk4mem_new(char,szRequest,NULL);
+ if (NULL != pRequest) {
+ if (0 == dk4str8_cpy_s(pRequest, szRequest, wxpqdic_kw[2], NULL)) {
+ /* ERROR: BUG */
+ *perrc = WXPQDIC_FRAME_ERROR_BUG;
+ goto finished;
+ }
+ if (0 == dk4str8_cat_s(pRequest, szRequest, wxpqdic_kw[1], NULL)) {
+ /* ERROR: BUG */
+ *perrc = WXPQDIC_FRAME_ERROR_BUG;
+ goto finished;
+ }
+ if (0 == dk4str8_cat_s(pRequest, szRequest, pQueuename, NULL)) {
+ /* ERROR: BUG */
+ *perrc = WXPQDIC_FRAME_ERROR_BUG;
+ goto finished;
+ }
+ if (0 == dk4str8_cat_s(pRequest, szRequest, wxpqdic_kw[1], NULL)) {
+ /* ERROR: BUG */
+ *perrc = WXPQDIC_FRAME_ERROR_BUG;
+ goto finished;
+ }
+ if (0 == dk4str8_cat_s(pRequest, szRequest, pUsername, NULL)) {
+ /* ERROR: BUG */
+ *perrc = WXPQDIC_FRAME_ERROR_BUG;
+ goto finished;
+ }
+ if (0 == dk4str8_cat_s(pRequest, szRequest, wxpqdic_kw[0], NULL)) {
+ /* ERROR: BUG */
+ *perrc = WXPQDIC_FRAME_ERROR_BUG;
+ goto finished;
+ }
+ szRequest = dk4str8_len(pRequest);
+
+
+#line 1047 "WxpqdicFrame.wxc"
+ } else {
+ /* ERROR: Memory */
+ *perrc = WXPQDIC_FRAME_ERROR_MEMORY;
+ goto finished;
+ }
+ } else {
+ /* ERROR: Numeric overflow in size calculation */
+ *perrc = WXPQDIC_FRAME_ERROR_SIZE_CALC_OVERFLOW;
+ goto finished;
+ }
+ /*
+ Create socket.
+ */
+ sock = dk4socket_udp_client_for_host(
+ aAddresses, pHostname, usPortnumber, usLocalPort, 1, NULL
+ );
+ if (INVALID_SOCKET == sock) {
+ *perrc = WXPQDIC_FRAME_ERROR_SOCKET;
+ goto finished;
+ }
+
+ }
+
+
+
+#line 1071 "WxpqdicFrame.wxc"
+
+ tLimit->SetLabel(sTexts[27]);
+ tUsed->SetLabel(sTexts[27]);
+ tAccount->SetLabel(sTexts[27]);
+
+ /* Finally indicate success.
+ */
+ timer.Start(500);
+ bIsInitialized = true;
+ back = false;
+
+ /* Clean up at end and return result.
+ */
+ finished:
+ pAppHelp->ReleaseWxcharStringArray(pv, 6);
+ if (back) {
+ if (INVALID_SOCKET != sock) {
+ dk4socket_close(sock, NULL);
+ sock = INVALID_SOCKET;
+ }
+ dk4mem_release(pUsername);
+ dk4mem_release(pQueuename);
+ dk4mem_release(pHostname);
+ dk4mem_release(pRequest);
+ }
+ return back;
+}
+
+
+
+void
+WxpqdicFrame::OnIdle(wxIdleEvent & event)
+{
+ int errorCode = WXPQDIC_FRAME_ERROR_NONE;
+ bool mustClose = false;
+
+
+#line 1107 "WxpqdicFrame.wxc"
+ /* __CHANGE__
+ */
+ {
+ wxCriticalSectionLocker lockCsProtect(csProtect);
+ if (bFirstIdle) {
+ bFirstIdle = false;
+ mustClose = ConfigureAndCheckNeedToClose(&errorCode);
+ }
+ }
+ if (mustClose) {
+
+#line 1117 "WxpqdicFrame.wxc"
+ const wxChar *ti;
+ const wxChar *tx;
+ ti = sTexts[58]; tx = sTexts[59];
+ switch (errorCode) {
+ case WXPQDIC_FRAME_ERROR_PARSE : {
+ ti = sTexts[30]; tx = sTexts[31];
+ } break;
+ case WXPQDIC_FRAME_ERROR_MEMORY : {
+ ti = sTexts[32]; tx = sTexts[33];
+ } break;
+ case WXPQDIC_FRAME_ERROR_STRCONV_HOSTNAME : {
+ ti = sTexts[34]; tx = sTexts[35];
+ } break;
+ case WXPQDIC_FRAME_ERROR_HOSTNAME : {
+ ti = sTexts[36]; tx = sTexts[37];
+ } break;
+ case WXPQDIC_FRAME_ERROR_STRCONV_QUEUENAME : {
+ ti = sTexts[38]; tx = sTexts[39];
+ } break;
+ case WXPQDIC_FRAME_ERROR_QUEUENAME : {
+ ti = sTexts[40]; tx = sTexts[41];
+ } break;
+ case WXPQDIC_FRAME_ERROR_PORT_OOR : {
+ ti = sTexts[42]; tx = sTexts[43];
+ } break;
+ case WXPQDIC_FRAME_ERROR_PORT_ZERO : {
+ ti = sTexts[42]; tx = sTexts[44];
+ } break;
+ case WXPQDIC_FRAME_ERROR_STRCONV_USERNAME : {
+ ti = sTexts[45]; tx = sTexts[46];
+ } break;
+ case WXPQDIC_FRAME_ERROR_USERNAME : {
+ ti = sTexts[47]; tx = sTexts[48];
+ } break;
+ case WXPQDIC_FRAME_ERROR_LOCALPORT_OOR : {
+ ti = sTexts[49]; tx = sTexts[50];
+ } break;
+ case WXPQDIC_FRAME_ERROR_LOCALPORT_ZERO : {
+ ti = sTexts[49]; tx = sTexts[51];
+ } break;
+ case WXPQDIC_FRAME_ERROR_BUG : {
+ ti = sTexts[52]; tx = sTexts[53];
+ } break;
+ case WXPQDIC_FRAME_ERROR_SIZE_CALC_OVERFLOW : {
+ ti = sTexts[54]; tx = sTexts[55];
+ } break;
+ case WXPQDIC_FRAME_ERROR_SOCKET : {
+ ti = sTexts[56]; tx = sTexts[57];
+ } break;
+ }
+ wxMessageBox(tx, ti, (wxICON_ERROR | wxOK), this);
+ Show(false);
+ Close();
+ }
+
+ /* Allow idle handlers from the base class.
+ */
+
+
+#line 1175 "WxpqdicFrame.wxc"
+ event.Skip();
+}
+
+
+void
+WxpqdicFrame::OnTimer(wxTimerEvent & event)
+{
+ bool mustUpdate = false;
+
+
+#line 1184 "WxpqdicFrame.wxc"
+ {
+ wxCriticalSectionLocker lockCsProtect(csProtect);
+
+
+#line 1187 "WxpqdicFrame.wxc"
+ if (bIsInitialized) {
+
+#line 1188 "WxpqdicFrame.wxc"
+ mustUpdate = DataExchangeWithServer();
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 1192 "WxpqdicFrame.wxc"
+ }
+#endif
+
+
+#line 1195 "WxpqdicFrame.wxc"
+ }
+ if (mustUpdate) {
+ Refresh();
+ Update();
+ }
+
+
+#line 1201 "WxpqdicFrame.wxc"
+}
+
+
+
+bool
+WxpqdicFrame::ProcessResponse(bool & found)
+{
+ wxChar wxb[16*sizeof(dk4_um_t)];
+ char *tokens[8]; /* Tokens in the response */
+ const char *ep; /* End part of text */
+ dk4_um_t limit; /* Print limit */
+ dk4_um_t used; /* Pages used with in limit */
+ dk4_um_t account; /* Personal account */
+ size_t sz; /* Number of tokens used */
+ size_t szwxb; /* Size of wxb */
+ int founddet; /* Details found. */
+ int res; /* Text to number conversion result */
+ int summary; /* Flag: Can print */
+ bool force; /* Flag: Force use of values */
+ bool back = false;
+
+
+#line 1222 "WxpqdicFrame.wxc"
+ sz = dk4str8_tokenize(tokens, 8, bResponse, NULL, NULL);
+ if (4 == sz) {
+
+#line 1224 "WxpqdicFrame.wxc"
+ founddet = 0;
+ force = bFirstResponse;
+ switch (iState) {
+ case WXPQDIC_STATE_TIMEOUT :
+ case WXPQDIC_STATE_SEND_FAILED :
+ {
+ force = true;
+
+#line 1231 "WxpqdicFrame.wxc"
+ } break;
+ }
+
+#line 1233 "WxpqdicFrame.wxc"
+ if (0 == dk4str8_cmp("-1", tokens[0])) {
+
+#line 1234 "WxpqdicFrame.wxc"
+ limit = DK4_UM_MAX;
+ founddet |= 1;
+ } else {
+ limit = (dk4_um_t)0UL;
+ ep = NULL;
+ res = dk4ma_input_c8_dec_dk4_um_t(&limit, tokens[0], &ep, 1, NULL);
+ if (0 != res) {
+
+#line 1241 "WxpqdicFrame.wxc"
+ founddet |= 1;
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 1245 "WxpqdicFrame.wxc"
+ }
+#endif
+ }
+ used = (dk4_um_t)0UL;
+ ep = NULL;
+ res = dk4ma_input_c8_dec_dk4_um_t(&used, tokens[1], &ep, 1, NULL);
+ if (0 != res) {
+
+#line 1252 "WxpqdicFrame.wxc"
+ founddet |= 2;
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 1256 "WxpqdicFrame.wxc"
+ }
+#endif
+ account = (dk4_um_t)0UL;
+ ep = NULL;
+ res = dk4ma_input_c8_dec_dk4_um_t(&account, tokens[2], &ep, 1, NULL);
+ if (0 != res) {
+
+#line 1262 "WxpqdicFrame.wxc"
+ founddet |= 4;
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 1266 "WxpqdicFrame.wxc"
+ }
+#endif
+ summary = 0;
+ ep = NULL;
+ res = dk4ma_input_c8_dec_int(&summary, tokens[3], &ep, 1, NULL);
+ if (0 != res) {
+
+#line 1272 "WxpqdicFrame.wxc"
+ founddet |= 8;
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 1276 "WxpqdicFrame.wxc"
+ }
+#endif
+ if (15 == (15 & founddet)) {
+
+#line 1279 "WxpqdicFrame.wxc"
+ /* Renew text labels
+ */
+#if DK4_SIZEOF_WXCHAR > 1
+ szwxb = DK4_SIZEOF(wxb,wxChar);
+ if ((force) || (limit != uLimit)) {
+ if (DK4_UM_MAX == limit) {
+ tLimit->SetLabel(sTexts[14]);
+ } else {
+ res = dk4ma_write_wc_decimal_unsigned(wxb, szwxb, limit, 0, NULL);
+ if (0 != res) {
+ wxString s(wxb);
+ tLimit->SetLabel(s);
+ }
+ }
+ back = true;
+ }
+ if ((force) || (used != uUsed)) {
+ res = dk4ma_write_wc_decimal_unsigned(wxb, szwxb, used, 0, NULL);
+ if (0 != res) {
+ wxString s(wxb);
+ tUsed->SetLabel(s);
+ }
+ back = true;
+ }
+ if ((force) || (account != uAccount)) {
+ res = dk4ma_write_wc_decimal_unsigned(wxb, szwxb, account, 0, NULL);
+ if (0 != res) {
+ wxString s(wxb);
+ tAccount->SetLabel(s);
+ }
+ back = true;
+ }
+#else
+ if ((force) || (limit != uLimit)) {
+ if (DK4_UM_MAX == limit) {
+ tLimit->SetLabel(sTexts[14]);
+ } else {
+ wxString s(tokens[0]);
+ tLimit->SetLabel(s);
+ }
+ back = true;
+
+#line 1320 "WxpqdicFrame.wxc"
+ }
+ if ((force) || (used != uUsed)) {
+ wxString s(tokens[1]);
+ tUsed->SetLabel(s);
+ back = true;
+
+#line 1325 "WxpqdicFrame.wxc"
+ }
+ if ((force) || (account != uAccount)) {
+ wxString s(tokens[2]);
+ tAccount->SetLabel(s);
+ back = true;
+
+#line 1330 "WxpqdicFrame.wxc"
+ }
+#endif
+ if ((force) || (summary != iSummary)) {
+ wxString s(sTexts[(0 != summary) ? 19 : 20]);
+ tAllowed->SetLabel(s);
+ if (0 != summary) {
+ tAllowed->SetForegroundColour(cGreen);
+ } else {
+ tAllowed->SetForegroundColour(cRed);
+ }
+ back = true;
+
+#line 1341 "WxpqdicFrame.wxc"
+ }
+ if (force) {
+ lStatus->SetLabel(sNlWx[5]);
+ switch (iState) {
+ case WXPQDIC_STATE_TIMEOUT :
+ case WXPQDIC_STATE_SEND_FAILED :
+ {
+ lStatus->SetForegroundColour(cBlack);
+ } break;
+ }
+ }
+ /* Save values for later comparisons
+ */
+ uLimit = limit;
+ uUsed = used;
+ uAccount = account;
+ iSummary = summary;
+ bFirstResponse = false;
+ /* Change state
+ */
+ iState = WXPQDIC_STATE_OK;
+ found = true;
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 1366 "WxpqdicFrame.wxc"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 1371 "WxpqdicFrame.wxc"
+ }
+#endif
+
+
+#line 1374 "WxpqdicFrame.wxc"
+ return back;
+}
+
+
+
+bool
+WxpqdicFrame::RetrieveResponse(void)
+{
+ dk4_sockaddr_storage_t remaddr; /* Source address */
+ size_t sz; /* Buffer size */
+ size_t szrema; /* Address size */
+ int res; /* Conversion result */
+ bool back = false;
+ bool found = false; /* Flag: Found */
+
+
+#line 1389 "WxpqdicFrame.wxc"
+ sz = szResponse;
+ szrema = sizeof(remaddr);
+ res = dk4socket_recvfrom(
+ sock, bResponse, &sz, 0,
+ (struct sockaddr *)(&remaddr), &szrema,
+ 0L, 10000L, NULL
+ );
+ switch (res) {
+ case DK4_SOCKET_RESULT_SUCCESS :
+ case DK4_SOCKET_RESULT_IN_PROGRESS :
+ {
+
+#line 1400 "WxpqdicFrame.wxc"
+ if (0 < sz) {
+
+#line 1401 "WxpqdicFrame.wxc"
+ bResponse[(szResponse > sz) ? (sz) : (szResponse - 1)] = '\0';
+#if TRACE_DEBUG
+ dk4str8_delnl(bResponse);
+
+#line 1404 "WxpqdicFrame.wxc"
+#endif
+ if (1 /* ##### TODO: Compare addresses */ ) {
+
+#line 1406 "WxpqdicFrame.wxc"
+ back = ProcessResponse(found);
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 1410 "WxpqdicFrame.wxc"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 1415 "WxpqdicFrame.wxc"
+ }
+#endif
+ } break;
+ default : {
+
+#line 1419 "WxpqdicFrame.wxc"
+ } break;
+ }
+ if (!(found)) {
+ if (WXPQDIC_STATE_SENDED == iState) {
+ iState = WXPQDIC_STATE_TIMEOUT;
+ tLimit->SetLabel(sTexts[27]);
+ tUsed->SetLabel(sTexts[27]);
+ tAccount->SetLabel(sTexts[27]);
+ tAllowed->SetLabel(sTexts[27]);
+ tAllowed->SetForegroundColour(cBlack);
+ lStatus->SetLabel(sTexts[29]);
+ lStatus->SetForegroundColour(cRed);
+ back = true;
+ }
+ }
+
+
+#line 1435 "WxpqdicFrame.wxc"
+ return back;
+}
+
+
+
+bool
+WxpqdicFrame::SendRequest(bool force)
+{
+ dk4_time_t currenttime = (dk4_time_t)0UL;
+ size_t sz = 0;
+ int res = 0;
+ bool mustsend = false;
+ bool back = false;
+
+
+#line 1449 "WxpqdicFrame.wxc"
+ if ((dk4_time_t)0UL == tRequestSended) {
+ mustsend = true;
+ } else {
+ if (force) {
+ mustsend = true;
+ } else {
+ dk4time_get(&currenttime);
+ if ((tRequestSended + (dk4_time_t)lUpdateInterval) <= currenttime) {
+ mustsend = true;
+ }
+ }
+ }
+ if (mustsend) {
+
+#line 1462 "WxpqdicFrame.wxc"
+ sz = szRequest;
+ if ((dk4_um_t)0UL == currenttime) {
+ dk4time_get(&currenttime);
+ }
+ res = dk4socket_sendto(
+ sock, pRequest, &sz, 0,
+ (struct sockaddr *)(&(aAddresses[0])), sizeof(dk4_sockaddr_storage_t),
+ 0L, 0L, NULL
+ );
+ tRequestSended = currenttime;
+ switch (res) {
+ case DK4_SOCKET_RESULT_SUCCESS :
+ case DK4_SOCKET_RESULT_IN_PROGRESS :
+ {
+
+#line 1476 "WxpqdicFrame.wxc"
+ switch (iState) {
+ case WXPQDIC_STATE_OK : {
+ iState = WXPQDIC_STATE_SENDED;
+ } break;
+ }
+ } break;
+ default : {
+
+#line 1483 "WxpqdicFrame.wxc"
+ if (WXPQDIC_STATE_SEND_FAILED != iState) {
+ tLimit->SetLabel(sTexts[27]);
+ tUsed->SetLabel(sTexts[27]);
+ tAccount->SetLabel(sTexts[27]);
+ tAllowed->SetLabel(sTexts[27]);
+ lStatus->SetLabel(sTexts[28]);
+ lStatus->SetForegroundColour(cRed);
+ back = true;
+ }
+ iState = WXPQDIC_STATE_SEND_FAILED;
+ } break;
+ }
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 1498 "WxpqdicFrame.wxc"
+ }
+#endif
+
+
+#line 1501 "WxpqdicFrame.wxc"
+ return back;
+}
+
+
+
+void
+WxpqdicFrame::OnRun(wxCommandEvent & event)
+{
+ bool mustUpdate = false;
+
+
+#line 1511 "WxpqdicFrame.wxc"
+ {
+ wxCriticalSectionLocker lockCsProtect(csProtect);
+ if (bIsInitialized) {
+ mustUpdate = SendRequest(true);
+ }
+ }
+ if (mustUpdate) {
+ Refresh();
+ Update();
+ }
+
+
+#line 1522 "WxpqdicFrame.wxc"
+}
+
+
+
+bool
+WxpqdicFrame::DataExchangeWithServer(void)
+{
+ bool back = false;
+
+
+#line 1531 "WxpqdicFrame.wxc"
+ if (RetrieveResponse()) {
+ back = true;
+ }
+ if (SendRequest()) {
+ back = true;
+ }
+
+
+#line 1538 "WxpqdicFrame.wxc"
+ return back;
+}
+
diff --git a/support/dktools/WxpqdicFrame.h b/support/dktools/WxpqdicFrame.h
new file mode 100644
index 0000000000..c32313e6c1
--- /dev/null
+++ b/support/dktools/WxpqdicFrame.h
@@ -0,0 +1,453 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: WxpqdicFrame.wxc
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file WxpqdicFrame.h Header file for the WxpqdicFrame module.
+*/
+
+#ifndef WXPQDICFRAME_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define WXPQDICFRAME_H_INCLUDED 1
+
+
+#line 133 "WxpqdicFrame.wxc"
+
+
+
+
+#line 137 "WxpqdicFrame.wxc"
+class WxpqdicFrame : public Dk4WxFrame
+{
+ private:
+
+ /** Event table for frame.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ /** Buffer for response processing.
+ */
+ char bResponse[32 * sizeof(dk4_um_t)];
+
+ /** Address pair, 0=remote, 1=local.
+ */
+ dk4_sockaddr_storage_t aAddresses[2];
+
+ /** Remote host name as wxChar string.
+ */
+ wxString sHostname;
+
+ /** Queue name as wxChar string.
+ */
+ wxString sQueuename;
+
+ /** User name as wxChar string.
+ */
+ wxString sUsername;
+
+ /** Localized texts.
+ */
+ wxChar const * const *sTexts;
+
+ /** Non-localized texts.
+ */
+ wxChar const * const *sNlWx;
+
+ /** Non-localized texts.
+ */
+ dkChar const * const *sNlDk;
+
+ /** Copy of the command line arguments poiner.
+ */
+ wxChar **copyArgv;
+
+ /* __CHANGE__ 011: Add further member variables.
+ */
+
+ /** Critical section to protect socket and timer.
+ */
+ wxCriticalSection csProtect;
+
+ /** Black color for normal status text.
+ */
+ wxColour cBlack;
+
+ /** Red color for not allowed to print.
+ */
+ wxColour cRed;
+
+ /** Green color for allowed to print.
+ */
+ wxColour cGreen;
+
+ /** Timer for periodic updates.
+ */
+ wxTimer timer;
+
+ /** Error report from socket subsystem initialization.
+ */
+ dk4_er_t sockerr;
+
+ /** Host name to query.
+ */
+ dkChar *pHostname;
+
+ /** Print queue to check.
+ */
+ char *pQueuename;
+
+ /** User name to use in check.
+ */
+ char *pUsername;
+
+ /** Request to send to server.
+ */
+ char *pRequest;
+
+ /** Previous limit value.
+ */
+ dk4_um_t uLimit;
+
+ /** Previous used value.
+ */
+ dk4_um_t uUsed;
+
+ /** Previous account value.
+ */
+ dk4_um_t uAccount;
+
+ /** Length of request.
+ */
+ size_t szRequest;
+
+ /** Size of response buffer.
+ */
+ size_t szResponse;
+
+ /** Time last request was sended.
+ */
+ dk4_time_t tRequestSended;
+
+ /** Update interval in seconds.
+ */
+ long lUpdateInterval;
+
+ /** Timeout interval before complaining about missing response.
+ */
+ long lWaitResponse;
+
+ /** Previous summary value.
+ */
+ int iSummary;
+
+ /** Number of command line arguments.
+ */
+ int copyArgc;
+
+ /** Current state.
+ */
+ int iState;
+
+ /** Socket for data exchange
+ */
+ dk4_socket_t sock;
+
+ /** Port number on remote host.
+ */
+ unsigned short usPortnumber;
+
+ /** Local port number to use.
+ */
+ unsigned short usLocalPort;
+
+ /** Flag: Socket subsystem initialized.
+ */
+ bool bSockInit;
+
+ /** Flag: Remote host uses UTF-8 encoding (user name and queue name).
+ */
+ bool bIsUtf8;
+
+ /** Flag: This idle event is the first one (no idle events before).
+ */
+ bool bFirstIdle;
+
+ /** Flag: All components initialized completely.
+ */
+ bool bIsInitialized;
+
+ /** Flag: This is the first response.
+ */
+ bool bFirstResponse;
+
+ /** Flag: GUI ok.
+ */
+ bool dkctGUILayoutOK;
+
+ /** Contents panel.
+ */
+ wxPanel *dkctGUIContentsPanel;
+
+ /** GUI element mainSizer.
+ */
+#line 58 "WxpqdicFrame.wxc"
+ wxBoxSizer *mainSizer;
+
+ /** GUI element mbMain.
+ */
+#line 20 "WxpqdicFrame.wxc"
+ wxMenuBar *mbMain;
+
+ /** GUI element tbMain.
+ */
+#line 115 "WxpqdicFrame.wxc"
+ wxToolBar *tbMain;
+
+ /** GUI element menuFile.
+ */
+#line 25 "WxpqdicFrame.wxc"
+ wxMenu *menuFile;
+
+ /** GUI element menuView.
+ */
+#line 34 "WxpqdicFrame.wxc"
+ wxMenu *menuView;
+
+ /** GUI element menuHelp.
+ */
+#line 43 "WxpqdicFrame.wxc"
+ wxMenu *menuHelp;
+
+ /** GUI element miFileExit.
+ */
+#line 29 "WxpqdicFrame.wxc"
+ wxMenuItem *miFileExit;
+
+ /** GUI element miViewUpdate.
+ */
+#line 38 "WxpqdicFrame.wxc"
+ wxMenuItem *miViewUpdate;
+
+ /** GUI element miHelpAbout.
+ */
+#line 48 "WxpqdicFrame.wxc"
+ wxMenuItem *miHelpAbout;
+
+ /** GUI element miHelpContents.
+ */
+#line 53 "WxpqdicFrame.wxc"
+ wxMenuItem *miHelpContents;
+
+ /** GUI element verticalSizer.
+ */
+#line 64 "WxpqdicFrame.wxc"
+ wxBoxSizer *verticalSizer;
+
+ /** GUI element contentsSizer.
+ */
+#line 72 "WxpqdicFrame.wxc"
+ wxGridBagSizer *contentsSizer;
+
+ /** GUI element lLimit.
+ */
+#line 87 "WxpqdicFrame.wxc"
+ wxStaticText *lLimit;
+
+ /** GUI element tLimit.
+ */
+#line 90 "WxpqdicFrame.wxc"
+ wxStaticText *tLimit;
+
+ /** GUI element lUsed.
+ */
+#line 93 "WxpqdicFrame.wxc"
+ wxStaticText *lUsed;
+
+ /** GUI element tUsed.
+ */
+#line 96 "WxpqdicFrame.wxc"
+ wxStaticText *tUsed;
+
+ /** GUI element lAccount.
+ */
+#line 99 "WxpqdicFrame.wxc"
+ wxStaticText *lAccount;
+
+ /** GUI element tAccount.
+ */
+#line 102 "WxpqdicFrame.wxc"
+ wxStaticText *tAccount;
+
+ /** GUI element lAllowed.
+ */
+#line 105 "WxpqdicFrame.wxc"
+ wxStaticText *lAllowed;
+
+ /** GUI element tAllowed.
+ */
+#line 108 "WxpqdicFrame.wxc"
+ wxStaticText *tAllowed;
+
+ /** GUI element lStatus.
+ */
+#line 111 "WxpqdicFrame.wxc"
+ wxStaticText *lStatus;
+
+ /** GUI element bUpdate.
+ */
+#line 119 "WxpqdicFrame.wxc"
+ wxToolBarToolBase *bUpdate;
+
+ /** GUI element bExit.
+ */
+#line 125 "WxpqdicFrame.wxc"
+ wxToolBarToolBase *bExit;
+
+
+#line 303 "WxpqdicFrame.wxc"
+
+ public:
+
+ /** Constructor.
+ @param wxid Window ID.
+ @param applicationHelper Application helper object.
+ @param hc Help controller for online help.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @param localizedTexts Localized wxChar texts.
+ @param nlWx Non-localized wxChar texts.
+ @param nlDk Non-localized dkChar texts.
+ @param bSocketsInitialized Flag: Socket subsys initialized.
+ @param psockerr Error report from socket initialization.
+ */
+ WxpqdicFrame(
+ int wxid,
+ Dk4WxApplicationHelper *applicationHelper,
+ Dk4WxHelpController *hc,
+ int argc,
+ wxChar **argv,
+ wxChar const * const *localizedTexts,
+ wxChar const * const *nlWx,
+ dkChar const * const *nlDk,
+ bool bSocketsInitialized,
+ dk4_er_t *psockerr
+ );
+
+ /** Destructor.
+ */
+ ~WxpqdicFrame();
+
+ /** Check whether we can close the window.
+ @param isLast Flag: Last main window to close.
+ */
+ bool
+ CanClose(bool isFinal);
+
+ /** Handler for File/Exit.
+ @param event Event to process.
+ */
+ void
+ OnQuit(wxCommandEvent & event);
+
+ /** Handler for File/Update.
+ @param event Event to process.
+ */
+ void
+ OnRun(wxCommandEvent & event);
+
+ /** Handler for Help/About.
+ @param event Event to process.
+ */
+ void
+ OnAbout(wxCommandEvent & event);
+
+ /** Handler for Help/Contents.
+ @param event Event to process.
+ */
+ void
+ OnHelpContents(wxCommandEvent & event);
+
+ /* __CHANGE__ 008: Remove OnIdle if no idle processing required.
+ */
+ /** Handler for idle events.
+ */
+ void
+ OnIdle(wxIdleEvent & event);
+
+ /* __CHANGE__ 017: Event handlers for further events.
+ */
+
+ /** Handler for timer event.
+ @param event Timer event to process.
+ */
+ void
+ OnTimer(wxTimerEvent & event);
+
+
+ /* __CHANGE__ 014: Add further methods.
+ */
+
+ private:
+
+ /** Attempt to configure.
+ @param perrc Address of error code variable.
+ @return True if configuration failed and the application should
+ exit, false on success.
+ */
+ bool
+ ConfigureAndCheckNeedToClose(int *perrc);
+
+ /** Attempt to receive data, send request again if interval is over.
+ @return True if the windows requires an update, false otherwise.
+ */
+ bool
+ DataExchangeWithServer(void);
+
+ bool
+ RetrieveResponse(void);
+
+ bool
+ ProcessResponse(bool & found);
+
+ bool
+ SendRequest(bool force = false);
+
+};
+
+
+#line 413 "WxpqdicFrame.wxc"
+
+
+#endif
diff --git a/support/dktools/WxpqdicFrame.wxc b/support/dktools/WxpqdicFrame.wxc
new file mode 100644
index 0000000000..9b28dae9ab
--- /dev/null
+++ b/support/dktools/WxpqdicFrame.wxc
@@ -0,0 +1,1540 @@
+%% options
+
+copyright owner = Dirk Krause
+
+copyright year = 2016-xxxx
+
+license = bsd
+
+
+
+%% wx-gui
+
+type = frame
+contents = mainSizer
+icon = wxpqdic_icon
+status bar = 1 sTexts[8]
+menu bar = mbMain
+tool bar = tbMain
+
+[wxMenuBar mbMain]
+contents = menuFile
+contents = menuView
+contents = menuHelp
+
+[wxMenu menuFile]
+text = sTexts[0]
+contents = miFileExit
+
+[wxMenuItem miFileExit]
+id = WxpqdicFrame_Quit
+text = sTexts[1]
+tip = sTexts[2]
+
+[wxMenu menuView]
+text = sTexts[22]
+contents = miViewUpdate
+
+[wxMenuItem miViewUpdate]
+id = WxpqdicFrame_View_Update
+text = sTexts[23]
+tip = sTexts[24]
+
+[wxMenu menuHelp]
+text = sTexts[3]
+contents = miHelpAbout
+contents = miHelpContents
+
+[wxMenuItem miHelpAbout]
+id = WxpqdicFrame_Help_About
+text = sTexts[4]
+tip = sTexts[5]
+
+[wxMenuItem miHelpContents]
+id = WxpqdicFrame_Help_Contents
+text = sTexts[6]
+tip = sTexts[7]
+
+[wxBoxSizer mainSizer]
+direction = horizontal
+contents = $space(10)
+contents = verticalSizer
+contents = $space(10)
+
+[wxBoxSizer verticalSizer]
+direction = vertical
+grow = yes
+proportion = 1
+contents = $space(10)
+contents = contentsSizer
+contents = $space(10)
+
+[wxGridBagSizer contentsSizer]
+grid = 2 2
+contents = lLimit 0 0 1 1 right
+contents = tLimit . +1 1 1
+contents = lUsed +1 0 1 1 right
+contents = tUsed . +1 1 1
+contents = $space(5) +1 0 1 1
+contents = lAccount +1 0 1 1 right
+contents = tAccount . +1 1 1
+contents = $space(5) +1 0 1 1
+contents = lAllowed +1 0 1 1 right
+contents = tAllowed . +1 1 1
+contents = $space(5) +1 0 1 1
+contents = lStatus +1 0 1 2
+
+[wxStaticText lLimit]
+text = sTexts[13]
+
+[wxStaticText tLimit]
+text = sTexts[14]
+
+[wxStaticText lUsed]
+text = sTexts[15]
+
+[wxStaticText tUsed]
+text = sTexts[27]
+
+[wxStaticText lAccount]
+text = sTexts[17]
+
+[wxStaticText tAccount]
+text = sTexts[16]
+
+[wxStaticText lAllowed]
+text = sTexts[18]
+
+[wxStaticText tAllowed]
+text = sTexts[27]
+
+[wxStaticText lStatus]
+text = sTexts[21]
+
+
+[wxToolBar tbMain]
+contents = bUpdate
+contents = bExit
+
+[wxToolBarToolBase bUpdate]
+text = sTexts[25]
+tip = sTexts[24]
+bitmap = xpm_run_conversion
+id = WxpqdicFrame_View_Update
+
+[wxToolBarToolBase bExit]
+text = sTexts[26]
+tip = sTexts[2]
+bitmap = xpm_exit_program
+id = WxpqdicFrame_Quit
+
+
+%% header start
+
+
+
+%% class start
+class WxpqdicFrame : public Dk4WxFrame
+{
+ private:
+
+ /** Event table for frame.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ /** Buffer for response processing.
+ */
+ char bResponse[32 * sizeof(dk4_um_t)];
+
+ /** Address pair, 0=remote, 1=local.
+ */
+ dk4_sockaddr_storage_t aAddresses[2];
+
+ /** Remote host name as wxChar string.
+ */
+ wxString sHostname;
+
+ /** Queue name as wxChar string.
+ */
+ wxString sQueuename;
+
+ /** User name as wxChar string.
+ */
+ wxString sUsername;
+
+ /** Localized texts.
+ */
+ wxChar const * const *sTexts;
+
+ /** Non-localized texts.
+ */
+ wxChar const * const *sNlWx;
+
+ /** Non-localized texts.
+ */
+ dkChar const * const *sNlDk;
+
+ /** Copy of the command line arguments poiner.
+ */
+ wxChar **copyArgv;
+
+ /* __CHANGE__ 011: Add further member variables.
+ */
+
+ /** Critical section to protect socket and timer.
+ */
+ wxCriticalSection csProtect;
+
+ /** Black color for normal status text.
+ */
+ wxColour cBlack;
+
+ /** Red color for not allowed to print.
+ */
+ wxColour cRed;
+
+ /** Green color for allowed to print.
+ */
+ wxColour cGreen;
+
+ /** Timer for periodic updates.
+ */
+ wxTimer timer;
+
+ /** Error report from socket subsystem initialization.
+ */
+ dk4_er_t sockerr;
+
+ /** Host name to query.
+ */
+ dkChar *pHostname;
+
+ /** Print queue to check.
+ */
+ char *pQueuename;
+
+ /** User name to use in check.
+ */
+ char *pUsername;
+
+ /** Request to send to server.
+ */
+ char *pRequest;
+
+ /** Previous limit value.
+ */
+ dk4_um_t uLimit;
+
+ /** Previous used value.
+ */
+ dk4_um_t uUsed;
+
+ /** Previous account value.
+ */
+ dk4_um_t uAccount;
+
+ /** Length of request.
+ */
+ size_t szRequest;
+
+ /** Size of response buffer.
+ */
+ size_t szResponse;
+
+ /** Time last request was sended.
+ */
+ dk4_time_t tRequestSended;
+
+ /** Update interval in seconds.
+ */
+ long lUpdateInterval;
+
+ /** Timeout interval before complaining about missing response.
+ */
+ long lWaitResponse;
+
+ /** Previous summary value.
+ */
+ int iSummary;
+
+ /** Number of command line arguments.
+ */
+ int copyArgc;
+
+ /** Current state.
+ */
+ int iState;
+
+ /** Socket for data exchange
+ */
+ dk4_socket_t sock;
+
+ /** Port number on remote host.
+ */
+ unsigned short usPortnumber;
+
+ /** Local port number to use.
+ */
+ unsigned short usLocalPort;
+
+ /** Flag: Socket subsystem initialized.
+ */
+ bool bSockInit;
+
+ /** Flag: Remote host uses UTF-8 encoding (user name and queue name).
+ */
+ bool bIsUtf8;
+
+ /** Flag: This idle event is the first one (no idle events before).
+ */
+ bool bFirstIdle;
+
+ /** Flag: All components initialized completely.
+ */
+ bool bIsInitialized;
+
+ /** Flag: This is the first response.
+ */
+ bool bFirstResponse;
+
+%% class end
+
+ public:
+
+ /** Constructor.
+ @param wxid Window ID.
+ @param applicationHelper Application helper object.
+ @param hc Help controller for online help.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @param localizedTexts Localized wxChar texts.
+ @param nlWx Non-localized wxChar texts.
+ @param nlDk Non-localized dkChar texts.
+ @param bSocketsInitialized Flag: Socket subsys initialized.
+ @param psockerr Error report from socket initialization.
+ */
+ WxpqdicFrame(
+ int wxid,
+ Dk4WxApplicationHelper *applicationHelper,
+ Dk4WxHelpController *hc,
+ int argc,
+ wxChar **argv,
+ wxChar const * const *localizedTexts,
+ wxChar const * const *nlWx,
+ dkChar const * const *nlDk,
+ bool bSocketsInitialized,
+ dk4_er_t *psockerr
+ );
+
+ /** Destructor.
+ */
+ ~WxpqdicFrame();
+
+ /** Check whether we can close the window.
+ @param isLast Flag: Last main window to close.
+ */
+ bool
+ CanClose(bool isFinal);
+
+ /** Handler for File/Exit.
+ @param event Event to process.
+ */
+ void
+ OnQuit(wxCommandEvent & event);
+
+ /** Handler for File/Update.
+ @param event Event to process.
+ */
+ void
+ OnRun(wxCommandEvent & event);
+
+ /** Handler for Help/About.
+ @param event Event to process.
+ */
+ void
+ OnAbout(wxCommandEvent & event);
+
+ /** Handler for Help/Contents.
+ @param event Event to process.
+ */
+ void
+ OnHelpContents(wxCommandEvent & event);
+
+ /* __CHANGE__ 008: Remove OnIdle if no idle processing required.
+ */
+ /** Handler for idle events.
+ */
+ void
+ OnIdle(wxIdleEvent & event);
+
+ /* __CHANGE__ 017: Event handlers for further events.
+ */
+
+ /** Handler for timer event.
+ @param event Timer event to process.
+ */
+ void
+ OnTimer(wxTimerEvent & event);
+
+
+ /* __CHANGE__ 014: Add further methods.
+ */
+
+ private:
+
+ /** Attempt to configure.
+ @param perrc Address of error code variable.
+ @return True if configuration failed and the application should
+ exit, false on success.
+ */
+ bool
+ ConfigureAndCheckNeedToClose(int *perrc);
+
+ /** Attempt to receive data, send request again if interval is over.
+ @return True if the windows requires an update, false otherwise.
+ */
+ bool
+ DataExchangeWithServer(void);
+
+ bool
+ RetrieveResponse(void);
+
+ bool
+ ProcessResponse(bool & found);
+
+ bool
+ SendRequest(bool force = false);
+
+};
+
+%% header end
+
+%% module start
+
+#include "wxpqdic.h"
+#include "dk4user.h"
+#include "dk4enc.h"
+#include "dk4strd.h"
+#include "dk4rec.h"
+#include "dk4str8.h"
+#include "dk4strx.h"
+#include "dk4recwx.h"
+#include "dk4maasz.h"
+#include "dk4mai8ddu.h"
+#include "dk4mai8dii.h"
+#include "dk4mao8d.h"
+#include "dk4maowd.h"
+#include "dk4numco.h"
+
+
+#include "exit-program.xpm"
+#include "run-conversion.xpm"
+
+#include "dk4verswx.h"
+
+#if !defined(__WXMSW__)
+#include "dkicon.xpm"
+#endif
+
+
+
+$!trace-include
+
+
+
+/* __CHANGE__ 017: Add further events. */
+/* __CHANGE__ 008: Remove OnIdle if no idle processing required. */
+BEGIN_EVENT_TABLE(WxpqdicFrame, wxFrame)
+ EVT_MENU(WxpqdicFrame_View_Update, WxpqdicFrame::OnRun)
+ EVT_MENU(WxpqdicFrame_Quit, WxpqdicFrame::OnQuit)
+ EVT_MENU(WxpqdicFrame_Help_About, WxpqdicFrame::OnAbout)
+ EVT_MENU(WxpqdicFrame_Help_Contents, WxpqdicFrame::OnHelpContents)
+ EVT_TIMER(WxpqdicFrame_Timer, WxpqdicFrame::OnTimer)
+ EVT_IDLE(WxpqdicFrame::OnIdle)
+END_EVENT_TABLE()
+
+
+
+static const wxChar versionNumber[] = { DKT_VERSION_WX };
+
+
+
+static const wxCmdLineEntryDesc wxpqdic_cmd_line_entries[] = {
+ {
+ wxCMD_LINE_OPTION,
+ wxT_2("h"),
+ wxT_2("host"),
+ wxT_2("Host to connect to."),
+ wxCMD_LINE_VAL_STRING,
+ 0
+ },
+ {
+ wxCMD_LINE_OPTION,
+ wxT_2("p"),
+ wxT_2("port"),
+ wxT_2("Port number to connect to."),
+ wxCMD_LINE_VAL_NUMBER,
+ 0
+ },
+ {
+ wxCMD_LINE_OPTION,
+ wxT_2("l"),
+ wxT_2("local-port"),
+ wxT_2("Local port number to use."),
+ wxCMD_LINE_VAL_NUMBER,
+ 0
+ },
+ {
+ wxCMD_LINE_OPTION,
+ wxT_2("q"),
+ wxT_2("queue"),
+ wxT_2("Queue name to check."),
+ wxCMD_LINE_VAL_STRING,
+ 0
+ },
+ {
+ wxCMD_LINE_OPTION,
+ wxT_2("u"),
+ wxT_2("user"),
+ wxT_2("User name to check."),
+ wxCMD_LINE_VAL_STRING,
+ 0
+ },
+ {
+ wxCMD_LINE_OPTION,
+ wxT_2("i"),
+ wxT_2("interval"),
+ wxT_2("Time interval for automatic update."),
+ wxCMD_LINE_VAL_NUMBER,
+ 0
+ },
+ {
+ wxCMD_LINE_OPTION,
+ wxT_2("a"),
+ wxT_2("ascii"),
+ wxT_2("Remote host uses ASCII encoding, not UTF-8."),
+ wxCMD_LINE_VAL_NONE,
+ 0
+ },
+ { wxCMD_LINE_NONE }
+};
+
+
+
+/** Key names for preferences.
+*/
+static const wxChar * const wxpqdic_pref_key_names[] = {
+$!string-table macro=wxT
+printqd.host
+printqd.port
+printqd.queue
+printqd.interval
+printqd.local
+printqd.encoding
+$!end
+};
+
+
+
+/** Constant 8-bit strings, not localized.
+*/
+static const char * const wxpqdic_kw[] = {
+$!string-table
+#
+# 0 newline
+#
+\n
+#
+# 1 space
+#
+
+#
+# 2 keyword info
+#
+info
+$!end
+};
+
+
+%% constructor start
+WxpqdicFrame::WxpqdicFrame(
+ int wxid,
+ Dk4WxApplicationHelper *applicationHelper,
+ Dk4WxHelpController *hc,
+ int argc,
+ wxChar **argv,
+ wxChar const * const *localizedTexts,
+ wxChar const * const *nlWx,
+ dkChar const * const *nlDk,
+ bool bSocketsInitialized,
+ dk4_er_t *psockerr
+) : Dk4WxFrame(nlWx[0], applicationHelper, hc, wxid),
+ sHostname(wxT("")),
+ sQueuename(wxT("")),
+ sUsername(wxT("")),
+ cBlack(0, 0, 0),
+ cRed(127, 0, 0),
+ cGreen(0, 127, 0),
+ timer(this, WxpqdicFrame_Timer)
+
+{
+ /* __CHANGE__ 012: Add further local variables.
+ */
+
+ /* __CHANGE__ 012: Initialize further local variables.
+ */
+
+ sTexts = localizedTexts;
+ sNlWx = nlWx;
+ sNlDk = nlDk;
+#if defined(__WXMSW__)
+ wxIcon wxpqdic_icon(sNlWx[4]);
+#else
+ wxIcon wxpqdic_icon(xpm_dkicon);
+#endif
+
+ /* __CHANGE__ 011: Initialize further class members.
+ */
+ bSockInit = bSocketsInitialized;
+ DK4_MEMCPY(&sockerr, psockerr, sizeof(dk4_er_t));
+ pHostname = NULL;
+ pQueuename = NULL;
+ pUsername = NULL;
+ pRequest = NULL;
+ szRequest = (size_t)0UL;
+ lUpdateInterval = 30L;
+ lWaitResponse = 1L;
+ usPortnumber = 9100;
+ usLocalPort = 9100;
+ bIsUtf8 = true;
+ bFirstIdle = true;
+ bFirstResponse = true;
+ bIsInitialized = false;
+ copyArgc = argc;
+ copyArgv = argv;
+ sock = INVALID_SOCKET;
+ iState = WXPQDIC_STATE_OK;
+ tRequestSended = (dk4_time_t)0UL;
+ szResponse = sizeof(bResponse);
+ DK4_MEMRES(&(aAddresses[0]), (2*sizeof(dk4_sockaddr_storage_t)));
+
+%% constructor end
+ if(dkctGUILayoutOK) {
+ SetTitle(nlWx[0]);
+ }
+
+
+ /* __CHANGE__ 012: Release resources allocated by local variables.
+ */
+}
+
+%% module end
+
+
+
+WxpqdicFrame::~WxpqdicFrame()
+{
+
+ /* __CHANGE__ 011: Release resources allocated by further class members.
+ */
+}
+
+
+
+bool
+WxpqdicFrame::CanClose(bool isLast)
+{
+ bool back = true;
+
+ return back;
+}
+
+
+void
+WxpqdicFrame::OnQuit(wxCommandEvent & event)
+{
+ {
+ wxCriticalSectionLocker lockCsProtect(csProtect);
+ if (bIsInitialized) {
+ timer.Stop();
+ bIsInitialized = false;
+ }
+ }
+ if (INVALID_SOCKET != sock) {
+ dk4socket_close(sock, NULL);
+ sock = INVALID_SOCKET;
+ }
+ dk4mem_release(pUsername);
+ dk4mem_release(pQueuename);
+ dk4mem_release(pHostname);
+ dk4mem_release(pRequest);
+ Show(false);
+ /* !!!!! TODO: Release resources */
+ Close();
+}
+
+
+
+void
+WxpqdicFrame::OnAbout(wxCommandEvent & event)
+{
+ wxString text(wxT(""));
+ wxString title(wxT(""));
+
+ /* Construct message text. */
+ text.Append(sNlWx[0]);
+ text.Append(sNlWx[7]);
+#if 0
+ text.Append(sNlWx[1]);
+#endif
+ text.Append(versionNumber);
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[9]);
+ text.Append(sNlWx[2]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[11]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[9]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[12]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[10]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[11]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[12]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[13]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[14]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[15]);
+ text.Append(sNlWx[8]);
+
+ /* Construct dialog box title. */
+ title.Append(sTexts[10]);
+ title.Append(sNlWx[0]);
+
+ /* Show dialog box. */
+ wxMessageBox(text, title);
+
+}
+
+
+
+void
+WxpqdicFrame::OnHelpContents(wxCommandEvent & event)
+{
+ DisplayContents();
+}
+
+/* __CHANGE__ 017: Event handlers for further events.
+*/
+
+/* __CHANGE__ 014: Implementation of further methods.
+*/
+
+
+bool
+WxpqdicFrame::ConfigureAndCheckNeedToClose(int *perrc)
+{
+
+ dkChar buf[1024];
+ char c8b[1024];
+ dk4_er_t er;
+ wxChar *pv[] = { NULL, NULL, NULL, NULL, NULL, NULL };
+ const wxChar *cptr;
+ const size_t szbuf = DK4_SIZEOF(buf,dkChar);
+ const size_t szc8b = sizeof(c8b);
+ long l = 0L;
+ int res = 0;
+ bool back = true;
+
+ /* Retrieve some fallback values from preferences.
+ */
+ pAppHelp->GetMultiple(wxpqdic_pref_key_names, pv, 6);
+ $? ". host = \"%!ws\"", TR_WXSTR(pv[0])
+ $? ". port = \"%!ws\"", TR_WXSTR(pv[1])
+ $? ". queue = \"%!ws\"", TR_WXSTR(pv[2])
+ $? ". interval = \"%!ws\"", TR_WXSTR(pv[3])
+ $? ". local = \"%!ws\"", TR_WXSTR(pv[4])
+ $? ". encoding = \"%!ws\"", TR_WXSTR(pv[5])
+
+ /* Check command line arguments
+ */
+ {
+ wxLogNull log;
+ wxCmdLineParser parser(wxpqdic_cmd_line_entries, copyArgc, copyArgv);
+ res = parser.Parse(false);
+ /*
+ Check overall parsing of arguments
+ */
+ if (0 != res) { $? "! failed to parse cmd line args"
+ /* ERROR: Failed to parse command line arguments */
+ *perrc = WXPQDIC_FRAME_ERROR_PARSE;
+ goto finished;
+ }
+ /*
+ Option -a means the remote host wants ASCII data.
+ */
+ if (parser.Found(wxT_2("a"))) {
+ bIsUtf8 = false;
+ } else {
+ if (NULL != pv[5]) {
+ if (0 != dk4strx_casecmp(pv[5], sNlWx[16])) {
+ if (0 != dk4strx_casecmp(pv[5], sNlWx[17])) {
+ bIsUtf8 = false;
+ }
+ }
+ }
+ }
+ /*
+ Try to obtain host name from arguments or from preferences.
+ */
+ dk4error_init(&er);
+ cptr = NULL;
+ if (parser.Found(wxT_2("h"), &sHostname)) {
+ cptr = sHostname.c_str();
+ }
+ else {
+ cptr = pv[0];
+ }
+ if (NULL != cptr) {
+ if (pAppHelp->StringToDk(buf, szbuf, cptr, &er)) {
+ pHostname = dk4str_dup(buf, NULL);
+ if (NULL == pHostname) { $? ". pHostname = \"%!ds\"", pHostname
+ /* ERROR: Memory */
+ *perrc = WXPQDIC_FRAME_ERROR_MEMORY;
+ goto finished;
+ }
+ } else {
+ /* ERROR: Failed to convert string */
+ *perrc = WXPQDIC_FRAME_ERROR_STRCONV_HOSTNAME;
+ goto finished;
+ }
+ }
+ if (NULL == pHostname) {
+ /* ERROR: Missing host name */
+ *perrc = WXPQDIC_FRAME_ERROR_HOSTNAME;
+ goto finished;
+ }
+ /*
+ Queue name is required.
+ */
+ cptr = NULL;
+ if (parser.Found(wxT_2("q"), &sQueuename)) {
+ cptr = sQueuename.c_str();
+ }
+ else {
+ cptr = pv[2];
+ }
+ if (NULL != cptr) {
+ res = dk4recwx_wxchar_to_char(
+ c8b, szc8b, ((bIsUtf8) ? (DK4_ENCODING_UTF8) : (DK4_ENCODING_ASCII)),
+ cptr, pAppHelp->GetWxEncoding(), NULL
+ );
+ if (0 != res) {
+ pQueuename = dk4str8_dup(c8b, NULL);
+ if (NULL == pQueuename) { $? ". pQueuename = \"%!8s\"", pQueuename
+ /* ERROR: Memory */
+ *perrc = WXPQDIC_FRAME_ERROR_MEMORY;
+ goto finished;
+ }
+ } else {
+ /* ERROR: String conversion failed */
+ *perrc = WXPQDIC_FRAME_ERROR_STRCONV_QUEUENAME;
+ goto finished;
+ }
+ }
+ else {
+ /* ERROR: Missing queue name */
+ *perrc = WXPQDIC_FRAME_ERROR_QUEUENAME;
+ goto finished;
+ }
+ if (NULL == pQueuename) {
+ /* ERROR: Missing queue name */
+ *perrc = WXPQDIC_FRAME_ERROR_QUEUENAME;
+ goto finished;
+ }
+ /*
+ Port number is optional.
+ */
+ {
+ bool portnoFound = false;
+ l = 0L;
+ if (parser.Found(wxT_2("p"), &l)) {
+ portnoFound = true;
+ }
+ else {
+ if (NULL != pv[1]) {
+ wxString s(pv[1]);
+ if (s.ToLong(&l, 0)) {
+ portnoFound = true;
+ }
+ }
+ }
+ if (portnoFound) {
+ if ((long)(USHRT_MAX) < l) {
+ /* ERROR: Port number out of range */
+ *perrc = WXPQDIC_FRAME_ERROR_PORT_OOR;
+ goto finished;
+ }
+ if (0L == l) {
+ /* ERROR: Illegal port number 0 */
+ *perrc = WXPQDIC_FRAME_ERROR_PORT_ZERO;
+ goto finished;
+ }
+ usPortnumber = (unsigned short)l;
+ }
+ }
+ /*
+ Local port number is optional.
+ */
+ {
+ bool portnoFound = false;
+ l = 0L;
+ if (parser.Found(wxT_2("l"), &l)) {
+ portnoFound = true;
+ }
+ else {
+ if (NULL != pv[4]) {
+ wxString s(pv[4]);
+ if (s.ToLong(&l, 0)) {
+ portnoFound = true;
+ }
+ }
+ }
+ if (portnoFound) {
+ if ((long)(USHRT_MAX) < l) {
+ /* ERROR: Port number out of range */
+ *perrc = WXPQDIC_FRAME_ERROR_LOCALPORT_OOR;
+ goto finished;
+ }
+ if (0L == l) {
+ /* ERROR: Illegal port number 0 */
+ *perrc = WXPQDIC_FRAME_ERROR_LOCALPORT_ZERO;
+ goto finished;
+ }
+ usLocalPort = (unsigned short)l;
+ }
+ }
+ /*
+ User name is optional, use current user by default.
+ */
+ if (parser.Found(wxT_2("u"), &sUsername)) {
+ res = dk4recwx_wxchar_to_char(
+ c8b, szc8b, ((bIsUtf8) ? (DK4_ENCODING_UTF8) : (DK4_ENCODING_ASCII)),
+ sUsername.c_str(), pAppHelp->GetWxEncoding(), NULL
+ );
+ if (0 != res) {
+ pUsername = dk4str8_dup(c8b, NULL);
+ if (NULL == pUsername) {
+ /* ERROR: Memory */
+ *perrc = WXPQDIC_FRAME_ERROR_MEMORY;
+ goto finished;
+ }
+ }
+ else {
+ /* ERROR: Failed to convert user name */
+ *perrc = WXPQDIC_FRAME_ERROR_STRCONV_USERNAME;
+ goto finished;
+ }
+ }
+ else {
+ res = dk4user_get_logname(buf, szbuf, 0, NULL);
+ if (0 != res) {
+ res = dk4recode_dk_to_any(
+ c8b, szc8b, ((bIsUtf8) ? (DK4_ENCODING_UTF8) : (DK4_ENCODING_ASCII)),
+ buf, pAppHelp->GetDkEncoding(), NULL
+ );
+ if (0 != res) {
+ pUsername = dk4str8_dup(c8b, NULL);
+ if (NULL == pUsername) {
+ /* ERROR: Memory */
+ *perrc = WXPQDIC_FRAME_ERROR_MEMORY;
+ goto finished;
+ }
+ }
+ else {
+ /* ERROR: Failed to convert user name */
+ *perrc = WXPQDIC_FRAME_ERROR_STRCONV_USERNAME;
+ goto finished;
+ }
+ } else {
+ /* ERROR: User name not found! */
+ *perrc = WXPQDIC_FRAME_ERROR_USERNAME;
+ goto finished;
+ }
+ }
+ if (NULL == pUsername) {
+ /* ERROR: No user name */
+ *perrc = WXPQDIC_FRAME_ERROR_USERNAME;
+ goto finished;
+ }
+ /*
+ Interval length is optional.
+ */
+ {
+ bool intervalFound = false;
+ l = 0L;
+ if (parser.Found(wxT_2("p"), &l)) {
+ intervalFound = true;
+ }
+ else {
+ if (NULL != pv[3]) {
+ wxString s(pv[3]);
+ if (s.ToLong(&l, 0)) {
+ intervalFound = true;
+ }
+ }
+ }
+ if (intervalFound) {
+ if (5L <= l) {
+ lUpdateInterval = l;
+ } else {
+ lUpdateInterval = 5L;
+ }
+ }
+ }
+ /*
+ Now build request
+ */
+ dk4error_init(&er);
+ szRequest = strlen(wxpqdic_kw[2]);
+ szRequest = dk4ma_size_t_add(szRequest, dk4str8_len(pQueuename), &er);
+ szRequest = dk4ma_size_t_add(szRequest, dk4str8_len(pUsername), &er);
+ szRequest = dk4ma_size_t_add(szRequest, dk4str8_len(wxpqdic_kw[2]), &er);
+ szRequest = dk4ma_size_t_add(szRequest, 4, &er);
+ if (DK4_E_NONE == er.ec) {
+ pRequest = dk4mem_new(char,szRequest,NULL);
+ if (NULL != pRequest) {
+ if (0 == dk4str8_cpy_s(pRequest, szRequest, wxpqdic_kw[2], NULL)) {
+ /* ERROR: BUG */
+ *perrc = WXPQDIC_FRAME_ERROR_BUG;
+ goto finished;
+ }
+ if (0 == dk4str8_cat_s(pRequest, szRequest, wxpqdic_kw[1], NULL)) {
+ /* ERROR: BUG */
+ *perrc = WXPQDIC_FRAME_ERROR_BUG;
+ goto finished;
+ }
+ if (0 == dk4str8_cat_s(pRequest, szRequest, pQueuename, NULL)) {
+ /* ERROR: BUG */
+ *perrc = WXPQDIC_FRAME_ERROR_BUG;
+ goto finished;
+ }
+ if (0 == dk4str8_cat_s(pRequest, szRequest, wxpqdic_kw[1], NULL)) {
+ /* ERROR: BUG */
+ *perrc = WXPQDIC_FRAME_ERROR_BUG;
+ goto finished;
+ }
+ if (0 == dk4str8_cat_s(pRequest, szRequest, pUsername, NULL)) {
+ /* ERROR: BUG */
+ *perrc = WXPQDIC_FRAME_ERROR_BUG;
+ goto finished;
+ }
+ if (0 == dk4str8_cat_s(pRequest, szRequest, wxpqdic_kw[0], NULL)) {
+ /* ERROR: BUG */
+ *perrc = WXPQDIC_FRAME_ERROR_BUG;
+ goto finished;
+ }
+ szRequest = dk4str8_len(pRequest);
+ $? ". request = \"%s\"", TR_8STR(pRequest)
+ } else {
+ /* ERROR: Memory */
+ *perrc = WXPQDIC_FRAME_ERROR_MEMORY;
+ goto finished;
+ }
+ } else {
+ /* ERROR: Numeric overflow in size calculation */
+ *perrc = WXPQDIC_FRAME_ERROR_SIZE_CALC_OVERFLOW;
+ goto finished;
+ }
+ /*
+ Create socket.
+ */
+ sock = dk4socket_udp_client_for_host(
+ aAddresses, pHostname, usPortnumber, usLocalPort, 1, NULL
+ );
+ if (INVALID_SOCKET == sock) {
+ *perrc = WXPQDIC_FRAME_ERROR_SOCKET;
+ goto finished;
+ }
+
+ }
+
+ $? ". successfully completed setup"
+
+ tLimit->SetLabel(sTexts[27]);
+ tUsed->SetLabel(sTexts[27]);
+ tAccount->SetLabel(sTexts[27]);
+
+ /* Finally indicate success.
+ */
+ timer.Start(500);
+ bIsInitialized = true;
+ back = false;
+
+ /* Clean up at end and return result.
+ */
+ finished:
+ pAppHelp->ReleaseWxcharStringArray(pv, 6);
+ if (back) {
+ if (INVALID_SOCKET != sock) {
+ dk4socket_close(sock, NULL);
+ sock = INVALID_SOCKET;
+ }
+ dk4mem_release(pUsername);
+ dk4mem_release(pQueuename);
+ dk4mem_release(pHostname);
+ dk4mem_release(pRequest);
+ }
+ return back;
+}
+
+
+
+void
+WxpqdicFrame::OnIdle(wxIdleEvent & event)
+{
+ int errorCode = WXPQDIC_FRAME_ERROR_NONE;
+ bool mustClose = false;
+ $? "+ OnIdle"
+ /* __CHANGE__
+ */
+ {
+ wxCriticalSectionLocker lockCsProtect(csProtect);
+ if (bFirstIdle) {
+ bFirstIdle = false;
+ mustClose = ConfigureAndCheckNeedToClose(&errorCode);
+ }
+ }
+ if (mustClose) { $? "! error in setup, must close window"
+ const wxChar *ti;
+ const wxChar *tx;
+ ti = sTexts[58]; tx = sTexts[59];
+ switch (errorCode) {
+ case WXPQDIC_FRAME_ERROR_PARSE : {
+ ti = sTexts[30]; tx = sTexts[31];
+ } break;
+ case WXPQDIC_FRAME_ERROR_MEMORY : {
+ ti = sTexts[32]; tx = sTexts[33];
+ } break;
+ case WXPQDIC_FRAME_ERROR_STRCONV_HOSTNAME : {
+ ti = sTexts[34]; tx = sTexts[35];
+ } break;
+ case WXPQDIC_FRAME_ERROR_HOSTNAME : {
+ ti = sTexts[36]; tx = sTexts[37];
+ } break;
+ case WXPQDIC_FRAME_ERROR_STRCONV_QUEUENAME : {
+ ti = sTexts[38]; tx = sTexts[39];
+ } break;
+ case WXPQDIC_FRAME_ERROR_QUEUENAME : {
+ ti = sTexts[40]; tx = sTexts[41];
+ } break;
+ case WXPQDIC_FRAME_ERROR_PORT_OOR : {
+ ti = sTexts[42]; tx = sTexts[43];
+ } break;
+ case WXPQDIC_FRAME_ERROR_PORT_ZERO : {
+ ti = sTexts[42]; tx = sTexts[44];
+ } break;
+ case WXPQDIC_FRAME_ERROR_STRCONV_USERNAME : {
+ ti = sTexts[45]; tx = sTexts[46];
+ } break;
+ case WXPQDIC_FRAME_ERROR_USERNAME : {
+ ti = sTexts[47]; tx = sTexts[48];
+ } break;
+ case WXPQDIC_FRAME_ERROR_LOCALPORT_OOR : {
+ ti = sTexts[49]; tx = sTexts[50];
+ } break;
+ case WXPQDIC_FRAME_ERROR_LOCALPORT_ZERO : {
+ ti = sTexts[49]; tx = sTexts[51];
+ } break;
+ case WXPQDIC_FRAME_ERROR_BUG : {
+ ti = sTexts[52]; tx = sTexts[53];
+ } break;
+ case WXPQDIC_FRAME_ERROR_SIZE_CALC_OVERFLOW : {
+ ti = sTexts[54]; tx = sTexts[55];
+ } break;
+ case WXPQDIC_FRAME_ERROR_SOCKET : {
+ ti = sTexts[56]; tx = sTexts[57];
+ } break;
+ }
+ wxMessageBox(tx, ti, (wxICON_ERROR | wxOK), this);
+ Show(false);
+ Close();
+ }
+
+ /* Allow idle handlers from the base class.
+ */
+ $? "- OnIdle"
+ event.Skip();
+}
+
+
+void
+WxpqdicFrame::OnTimer(wxTimerEvent & event)
+{
+ bool mustUpdate = false;
+ $? "+ OnTimer"
+ {
+ wxCriticalSectionLocker lockCsProtect(csProtect);
+ $? ". entered critical section"
+ if (bIsInitialized) { $? ". already initialized"
+ mustUpdate = DataExchangeWithServer();
+ }
+#if TRACE_DEBUG
+ else { $? "! not yet initialized"
+ }
+#endif
+ $? ". exiting critical section"
+ }
+ if (mustUpdate) {
+ Refresh();
+ Update();
+ }
+ $? "- OnTimer"
+}
+
+
+
+bool
+WxpqdicFrame::ProcessResponse(bool & found)
+{
+ wxChar wxb[16*sizeof(dk4_um_t)];
+ char *tokens[8]; /* Tokens in the response */
+ const char *ep; /* End part of text */
+ dk4_um_t limit; /* Print limit */
+ dk4_um_t used; /* Pages used with in limit */
+ dk4_um_t account; /* Personal account */
+ size_t sz; /* Number of tokens used */
+ size_t szwxb; /* Size of wxb */
+ int founddet; /* Details found. */
+ int res; /* Text to number conversion result */
+ int summary; /* Flag: Can print */
+ bool force; /* Flag: Force use of values */
+ bool back = false;
+ $? "+ ProcessResponse"
+ sz = dk4str8_tokenize(tokens, 8, bResponse, NULL, NULL);
+ if (4 == sz) { $? ". 4 tokens"
+ founddet = 0;
+ force = bFirstResponse;
+ switch (iState) {
+ case WXPQDIC_STATE_TIMEOUT :
+ case WXPQDIC_STATE_SEND_FAILED :
+ {
+ force = true; $? ". recover from error"
+ } break;
+ } $? ". force = %d", (force ? 1 : 0)
+ if (0 == dk4str8_cmp("-1", tokens[0])) { $? ". 0 = unlimited"
+ limit = DK4_UM_MAX;
+ founddet |= 1;
+ } else {
+ limit = (dk4_um_t)0UL;
+ ep = NULL;
+ res = dk4ma_input_c8_dec_dk4_um_t(&limit, tokens[0], &ep, 1, NULL);
+ if (0 != res) { $? ". 0 = %lu", (unsigned long)limit
+ founddet |= 1;
+ }
+#if TRACE_DEBUG
+ else { $? "! 0 not a number"
+ }
+#endif
+ }
+ used = (dk4_um_t)0UL;
+ ep = NULL;
+ res = dk4ma_input_c8_dec_dk4_um_t(&used, tokens[1], &ep, 1, NULL);
+ if (0 != res) { $? ". 1 = %lu", (unsigned long)used
+ founddet |= 2;
+ }
+#if TRACE_DEBUG
+ else { $? "! 1 not a number"
+ }
+#endif
+ account = (dk4_um_t)0UL;
+ ep = NULL;
+ res = dk4ma_input_c8_dec_dk4_um_t(&account, tokens[2], &ep, 1, NULL);
+ if (0 != res) { $? ". 2 = %lu", (unsigned long)account
+ founddet |= 4;
+ }
+#if TRACE_DEBUG
+ else { $? "! 2 not a number"
+ }
+#endif
+ summary = 0;
+ ep = NULL;
+ res = dk4ma_input_c8_dec_int(&summary, tokens[3], &ep, 1, NULL);
+ if (0 != res) { $? ". 3 = %d", summary
+ founddet |= 8;
+ }
+#if TRACE_DEBUG
+ else { $? "! 3 not a number"
+ }
+#endif
+ if (15 == (15 & founddet)) { $? ". processed successfully"
+ /* Renew text labels
+ */
+#if DK4_SIZEOF_WXCHAR > 1
+ szwxb = DK4_SIZEOF(wxb,wxChar);
+ if ((force) || (limit != uLimit)) {
+ if (DK4_UM_MAX == limit) {
+ tLimit->SetLabel(sTexts[14]);
+ } else {
+ res = dk4ma_write_wc_decimal_unsigned(wxb, szwxb, limit, 0, NULL);
+ if (0 != res) {
+ wxString s(wxb);
+ tLimit->SetLabel(s);
+ }
+ }
+ back = true;
+ }
+ if ((force) || (used != uUsed)) {
+ res = dk4ma_write_wc_decimal_unsigned(wxb, szwxb, used, 0, NULL);
+ if (0 != res) {
+ wxString s(wxb);
+ tUsed->SetLabel(s);
+ }
+ back = true;
+ }
+ if ((force) || (account != uAccount)) {
+ res = dk4ma_write_wc_decimal_unsigned(wxb, szwxb, account, 0, NULL);
+ if (0 != res) {
+ wxString s(wxb);
+ tAccount->SetLabel(s);
+ }
+ back = true;
+ }
+#else
+ if ((force) || (limit != uLimit)) {
+ if (DK4_UM_MAX == limit) {
+ tLimit->SetLabel(sTexts[14]);
+ } else {
+ wxString s(tokens[0]);
+ tLimit->SetLabel(s);
+ }
+ back = true; $? ". update for limit"
+ }
+ if ((force) || (used != uUsed)) {
+ wxString s(tokens[1]);
+ tUsed->SetLabel(s);
+ back = true; $? ". update for used"
+ }
+ if ((force) || (account != uAccount)) {
+ wxString s(tokens[2]);
+ tAccount->SetLabel(s);
+ back = true; $? ". update for account"
+ }
+#endif
+ if ((force) || (summary != iSummary)) {
+ wxString s(sTexts[(0 != summary) ? 19 : 20]);
+ tAllowed->SetLabel(s);
+ if (0 != summary) {
+ tAllowed->SetForegroundColour(cGreen);
+ } else {
+ tAllowed->SetForegroundColour(cRed);
+ }
+ back = true; $? ". update for summary"
+ }
+ if (force) {
+ lStatus->SetLabel(sNlWx[5]);
+ switch (iState) {
+ case WXPQDIC_STATE_TIMEOUT :
+ case WXPQDIC_STATE_SEND_FAILED :
+ {
+ lStatus->SetForegroundColour(cBlack);
+ } break;
+ }
+ }
+ /* Save values for later comparisons
+ */
+ uLimit = limit;
+ uUsed = used;
+ uAccount = account;
+ iSummary = summary;
+ bFirstResponse = false;
+ /* Change state
+ */
+ iState = WXPQDIC_STATE_OK;
+ found = true;
+ }
+#if TRACE_DEBUG
+ else { $? "! processing failed"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! not 4 tokens"
+ }
+#endif
+ $? "- ProcessResponse %d", ((back) ? (1) : (0))
+ return back;
+}
+
+
+
+bool
+WxpqdicFrame::RetrieveResponse(void)
+{
+ dk4_sockaddr_storage_t remaddr; /* Source address */
+ size_t sz; /* Buffer size */
+ size_t szrema; /* Address size */
+ int res; /* Conversion result */
+ bool back = false;
+ bool found = false; /* Flag: Found */
+ $? "+ RetrieveResponse"
+ sz = szResponse;
+ szrema = sizeof(remaddr);
+ res = dk4socket_recvfrom(
+ sock, bResponse, &sz, 0,
+ (struct sockaddr *)(&remaddr), &szrema,
+ 0L, 10000L, NULL
+ );
+ switch (res) {
+ case DK4_SOCKET_RESULT_SUCCESS :
+ case DK4_SOCKET_RESULT_IN_PROGRESS :
+ { $? ". data"
+ if (0 < sz) { $? ". data length"
+ bResponse[(szResponse > sz) ? (sz) : (szResponse - 1)] = '\0';
+#if TRACE_DEBUG
+ dk4str8_delnl(bResponse); $? ". response = \"%!8s\"", bResponse
+#endif
+ if (1 /* ##### TODO: Compare addresses */ ) { $? ". addr ok"
+ back = ProcessResponse(found);
+ }
+#if TRACE_DEBUG
+ else { $? "! addr mismatch"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! data length 0"
+ }
+#endif
+ } break;
+ default : { $? ". no data"
+ } break;
+ }
+ if (!(found)) {
+ if (WXPQDIC_STATE_SENDED == iState) {
+ iState = WXPQDIC_STATE_TIMEOUT;
+ tLimit->SetLabel(sTexts[27]);
+ tUsed->SetLabel(sTexts[27]);
+ tAccount->SetLabel(sTexts[27]);
+ tAllowed->SetLabel(sTexts[27]);
+ tAllowed->SetForegroundColour(cBlack);
+ lStatus->SetLabel(sTexts[29]);
+ lStatus->SetForegroundColour(cRed);
+ back = true;
+ }
+ }
+ $? "- RetrieveResponse %d", ((back) ? (1) : (0))
+ return back;
+}
+
+
+
+bool
+WxpqdicFrame::SendRequest(bool force)
+{
+ dk4_time_t currenttime = (dk4_time_t)0UL;
+ size_t sz = 0;
+ int res = 0;
+ bool mustsend = false;
+ bool back = false;
+ $? "+ SendRequest"
+ if ((dk4_time_t)0UL == tRequestSended) {
+ mustsend = true;
+ } else {
+ if (force) {
+ mustsend = true;
+ } else {
+ dk4time_get(&currenttime);
+ if ((tRequestSended + (dk4_time_t)lUpdateInterval) <= currenttime) {
+ mustsend = true;
+ }
+ }
+ }
+ if (mustsend) { $? ". must send"
+ sz = szRequest;
+ if ((dk4_um_t)0UL == currenttime) {
+ dk4time_get(&currenttime);
+ }
+ res = dk4socket_sendto(
+ sock, pRequest, &sz, 0,
+ (struct sockaddr *)(&(aAddresses[0])), sizeof(dk4_sockaddr_storage_t),
+ 0L, 0L, NULL
+ );
+ tRequestSended = currenttime;
+ switch (res) {
+ case DK4_SOCKET_RESULT_SUCCESS :
+ case DK4_SOCKET_RESULT_IN_PROGRESS :
+ { $? ". success, sended"
+ switch (iState) {
+ case WXPQDIC_STATE_OK : {
+ iState = WXPQDIC_STATE_SENDED;
+ } break;
+ }
+ } break;
+ default : { $? "! send"
+ if (WXPQDIC_STATE_SEND_FAILED != iState) {
+ tLimit->SetLabel(sTexts[27]);
+ tUsed->SetLabel(sTexts[27]);
+ tAccount->SetLabel(sTexts[27]);
+ tAllowed->SetLabel(sTexts[27]);
+ lStatus->SetLabel(sTexts[28]);
+ lStatus->SetForegroundColour(cRed);
+ back = true;
+ }
+ iState = WXPQDIC_STATE_SEND_FAILED;
+ } break;
+ }
+ }
+#if TRACE_DEBUG
+ else { $? ". no need to send"
+ }
+#endif
+ $? "- SendRequest %d", ((back) ? (1) : (0))
+ return back;
+}
+
+
+
+void
+WxpqdicFrame::OnRun(wxCommandEvent & event)
+{
+ bool mustUpdate = false;
+ $? "+ OnRun"
+ {
+ wxCriticalSectionLocker lockCsProtect(csProtect);
+ if (bIsInitialized) {
+ mustUpdate = SendRequest(true);
+ }
+ }
+ if (mustUpdate) {
+ Refresh();
+ Update();
+ }
+ $? "- OnRun"
+}
+
+
+
+bool
+WxpqdicFrame::DataExchangeWithServer(void)
+{
+ bool back = false;
+ $? "+ DataExchangeWithServer"
+ if (RetrieveResponse()) {
+ back = true;
+ }
+ if (SendRequest()) {
+ back = true;
+ }
+ $? "- DataExchangeWithServer %d", ((back) ? (1) : (0))
+ return back;
+}
+
diff --git a/support/dktools/aclocal.m4 b/support/dktools/aclocal.m4
new file mode 100644
index 0000000000..7deeb8ec90
--- /dev/null
+++ b/support/dktools/aclocal.m4
@@ -0,0 +1,251 @@
+# generated automatically by aclocal 1.15 -*- Autoconf -*-
+
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_prog_cc_for_build.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_PROG_CC_FOR_BUILD
+#
+# DESCRIPTION
+#
+# This macro searches for a C compiler that generates native executables,
+# that is a C compiler that surely is not a cross-compiler. This can be
+# useful if you have to generate source code at compile-time like for
+# example GCC does.
+#
+# The macro sets the CC_FOR_BUILD and CPP_FOR_BUILD macros to anything
+# needed to compile or link (CC_FOR_BUILD) and preprocess (CPP_FOR_BUILD).
+# The value of these variables can be overridden by the user by specifying
+# a compiler with an environment variable (like you do for standard CC).
+#
+# It also sets BUILD_EXEEXT and BUILD_OBJEXT to the executable and object
+# file extensions for the build platform, and GCC_FOR_BUILD to `yes' if
+# the compiler we found is GCC. All these variables but GCC_FOR_BUILD are
+# substituted in the Makefile.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Paolo Bonzini <bonzini@gnu.org>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 8
+
+AU_ALIAS([AC_PROG_CC_FOR_BUILD], [AX_PROG_CC_FOR_BUILD])
+AC_DEFUN([AX_PROG_CC_FOR_BUILD], [dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_CPP])dnl
+AC_REQUIRE([AC_EXEEXT])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+
+dnl Use the standard macros, but make them use other variable names
+dnl
+pushdef([ac_cv_prog_CPP], ac_cv_build_prog_CPP)dnl
+pushdef([ac_cv_prog_gcc], ac_cv_build_prog_gcc)dnl
+pushdef([ac_cv_prog_cc_works], ac_cv_build_prog_cc_works)dnl
+pushdef([ac_cv_prog_cc_cross], ac_cv_build_prog_cc_cross)dnl
+pushdef([ac_cv_prog_cc_g], ac_cv_build_prog_cc_g)dnl
+pushdef([ac_cv_exeext], ac_cv_build_exeext)dnl
+pushdef([ac_cv_objext], ac_cv_build_objext)dnl
+pushdef([ac_exeext], ac_build_exeext)dnl
+pushdef([ac_objext], ac_build_objext)dnl
+pushdef([CC], CC_FOR_BUILD)dnl
+pushdef([CPP], CPP_FOR_BUILD)dnl
+pushdef([CFLAGS], CFLAGS_FOR_BUILD)dnl
+pushdef([CPPFLAGS], CPPFLAGS_FOR_BUILD)dnl
+pushdef([LDFLAGS], LDFLAGS_FOR_BUILD)dnl
+pushdef([host], build)dnl
+pushdef([host_alias], build_alias)dnl
+pushdef([host_cpu], build_cpu)dnl
+pushdef([host_vendor], build_vendor)dnl
+pushdef([host_os], build_os)dnl
+pushdef([ac_cv_host], ac_cv_build)dnl
+pushdef([ac_cv_host_alias], ac_cv_build_alias)dnl
+pushdef([ac_cv_host_cpu], ac_cv_build_cpu)dnl
+pushdef([ac_cv_host_vendor], ac_cv_build_vendor)dnl
+pushdef([ac_cv_host_os], ac_cv_build_os)dnl
+pushdef([ac_cpp], ac_build_cpp)dnl
+pushdef([ac_compile], ac_build_compile)dnl
+pushdef([ac_link], ac_build_link)dnl
+
+save_cross_compiling=$cross_compiling
+save_ac_tool_prefix=$ac_tool_prefix
+cross_compiling=no
+ac_tool_prefix=
+
+AC_PROG_CC
+AC_PROG_CPP
+AC_EXEEXT
+
+ac_tool_prefix=$save_ac_tool_prefix
+cross_compiling=$save_cross_compiling
+
+dnl Restore the old definitions
+dnl
+popdef([ac_link])dnl
+popdef([ac_compile])dnl
+popdef([ac_cpp])dnl
+popdef([ac_cv_host_os])dnl
+popdef([ac_cv_host_vendor])dnl
+popdef([ac_cv_host_cpu])dnl
+popdef([ac_cv_host_alias])dnl
+popdef([ac_cv_host])dnl
+popdef([host_os])dnl
+popdef([host_vendor])dnl
+popdef([host_cpu])dnl
+popdef([host_alias])dnl
+popdef([host])dnl
+popdef([LDFLAGS])dnl
+popdef([CPPFLAGS])dnl
+popdef([CFLAGS])dnl
+popdef([CPP])dnl
+popdef([CC])dnl
+popdef([ac_objext])dnl
+popdef([ac_exeext])dnl
+popdef([ac_cv_objext])dnl
+popdef([ac_cv_exeext])dnl
+popdef([ac_cv_prog_cc_g])dnl
+popdef([ac_cv_prog_cc_cross])dnl
+popdef([ac_cv_prog_cc_works])dnl
+popdef([ac_cv_prog_gcc])dnl
+popdef([ac_cv_prog_CPP])dnl
+
+dnl Finally, set Makefile variables
+dnl
+BUILD_EXEEXT=$ac_build_exeext
+BUILD_OBJEXT=$ac_build_objext
+AC_SUBST(BUILD_EXEEXT)dnl
+AC_SUBST(BUILD_OBJEXT)dnl
+AC_SUBST([CFLAGS_FOR_BUILD])dnl
+AC_SUBST([CPPFLAGS_FOR_BUILD])dnl
+AC_SUBST([LDFLAGS_FOR_BUILD])dnl
+])
+
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_prog_cxx_for_build.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_PROG_CXX_FOR_BUILD
+#
+# DESCRIPTION
+#
+# This macro searches for a C++ compiler that generates native
+# executables, that is a C++ compiler that surely is not a cross-compiler.
+# This can be useful if you have to generate source code at compile-time
+# like for example GCC does.
+#
+# The macro sets the CXX_FOR_BUILD and CXXCPP_FOR_BUILD macros to anything
+# needed to compile or link (CXX_FOR_BUILD) and preprocess
+# (CXXCPP_FOR_BUILD). The value of these variables can be overridden by
+# the user by specifying a compiler with an environment variable (like you
+# do for standard CXX).
+#
+# LICENSE
+#
+# Copyright (c) 2008 Paolo Bonzini <bonzini@gnu.org>
+# Copyright (c) 2012 Avionic Design GmbH
+#
+# Based on the AX_PROG_CC_FOR_BUILD macro by Paolo Bonzini.
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 2
+
+AU_ALIAS([AC_PROG_CXX_FOR_BUILD], [AX_PROG_CXX_FOR_BUILD])
+AC_DEFUN([AX_PROG_CXX_FOR_BUILD], [dnl
+AC_REQUIRE([AX_PROG_CC_FOR_BUILD])dnl
+AC_REQUIRE([AC_PROG_CXX])dnl
+AC_REQUIRE([AC_PROG_CXXCPP])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+
+dnl Use the standard macros, but make them use other variable names
+dnl
+pushdef([ac_cv_prog_CXXCPP], ac_cv_build_prog_CXXCPP)dnl
+pushdef([ac_cv_prog_gxx], ac_cv_build_prog_gxx)dnl
+pushdef([ac_cv_prog_cxx_works], ac_cv_build_prog_cxx_works)dnl
+pushdef([ac_cv_prog_cxx_cross], ac_cv_build_prog_cxx_cross)dnl
+pushdef([ac_cv_prog_cxx_g], ac_cv_build_prog_cxx_g)dnl
+pushdef([CXX], CXX_FOR_BUILD)dnl
+pushdef([CXXCPP], CXXCPP_FOR_BUILD)dnl
+pushdef([CXXFLAGS], CXXFLAGS_FOR_BUILD)dnl
+pushdef([CPPFLAGS], CPPFLAGS_FOR_BUILD)dnl
+pushdef([CXXCPPFLAGS], CXXCPPFLAGS_FOR_BUILD)dnl
+pushdef([host], build)dnl
+pushdef([host_alias], build_alias)dnl
+pushdef([host_cpu], build_cpu)dnl
+pushdef([host_vendor], build_vendor)dnl
+pushdef([host_os], build_os)dnl
+pushdef([ac_cv_host], ac_cv_build)dnl
+pushdef([ac_cv_host_alias], ac_cv_build_alias)dnl
+pushdef([ac_cv_host_cpu], ac_cv_build_cpu)dnl
+pushdef([ac_cv_host_vendor], ac_cv_build_vendor)dnl
+pushdef([ac_cv_host_os], ac_cv_build_os)dnl
+pushdef([ac_cxxcpp], ac_build_cxxcpp)dnl
+pushdef([ac_compile], ac_build_compile)dnl
+pushdef([ac_link], ac_build_link)dnl
+
+save_cross_compiling=$cross_compiling
+save_ac_tool_prefix=$ac_tool_prefix
+cross_compiling=no
+ac_tool_prefix=
+
+AC_PROG_CXX
+AC_PROG_CXXCPP
+
+ac_tool_prefix=$save_ac_tool_prefix
+cross_compiling=$save_cross_compiling
+
+dnl Restore the old definitions
+dnl
+popdef([ac_link])dnl
+popdef([ac_compile])dnl
+popdef([ac_cxxcpp])dnl
+popdef([ac_cv_host_os])dnl
+popdef([ac_cv_host_vendor])dnl
+popdef([ac_cv_host_cpu])dnl
+popdef([ac_cv_host_alias])dnl
+popdef([ac_cv_host])dnl
+popdef([host_os])dnl
+popdef([host_vendor])dnl
+popdef([host_cpu])dnl
+popdef([host_alias])dnl
+popdef([host])dnl
+popdef([CXXCPPFLAGS])dnl
+popdef([CPPFLAGS])dnl
+popdef([CXXFLAGS])dnl
+popdef([CXXCPP])dnl
+popdef([CXX])dnl
+popdef([ac_cv_prog_cxx_g])dnl
+popdef([ac_cv_prog_cxx_cross])dnl
+popdef([ac_cv_prog_cxx_works])dnl
+popdef([ac_cv_prog_gxx])dnl
+popdef([ac_cv_prog_CXXCPP])dnl
+
+dnl Finally, set Makefile variables
+dnl
+AC_SUBST([CXXFLAGS_FOR_BUILD])dnl
+AC_SUBST([CXXCPPFLAGS_FOR_BUILD])dnl
+])
+
diff --git a/support/dktools/addctrld.c b/support/dktools/addctrld.c
new file mode 100644
index 0000000000..7e616817c7
--- /dev/null
+++ b/support/dktools/addctrld.c
@@ -0,0 +1,202 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: addctrld.ctr
+*/
+
+
+#line 1 "addctrld.ctr"
+/*
+Copyright (c) 2001-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms,
+with or without modification, are permitted provided
+that the following conditions are met:
+
+* Redistributions of source code must retain the above
+ copyright notice, this list of conditions and the
+ following disclaimer.
+* Redistributions in binary form must reproduce the above
+ opyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials
+ provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of
+ contributors may be used to endorse or promote
+ products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+*/
+
+/** @file addctrld.c Ensure to have CTRL-D as last byte.
+
+This program is a filter. If the final byte in the input stream
+is not a CTRL-D the program appends a CTRL-D.
+*/
+
+#include "dk4conf.h"
+
+
+#if DK4_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include <stdio.h>
+
+#if DK4_HAVE_IO_H
+#include <io.h>
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#include <process.h>
+#endif
+
+
+
+
+
+#line 71 "addctrld.ctr"
+
+
+
+#if !DK4_HAVE_SSIZE_T
+#ifdef DK4_HAVE_SSIZE_T
+#undef DK4_HAVE_SSIZE_T
+#endif
+/** Data type for read/write operation result.
+*/
+typedef size_t ssize_t;
+
+/** Flag: ssize_t defined.
+*/
+#define DK4_HAVE_SSIZE_T 1
+#endif
+
+
+
+/** Length of output buffer in bytes.
+*/
+#define BUFFER_SIZE 4096
+
+
+/** Output buffer.
+*/
+static char outbuffer[BUFFER_SIZE];
+
+
+/** Number of bytes currently used in output buffer.
+*/
+static size_t outbused;
+
+
+
+/** Flush output buffer.
+*/
+static void flush_buffer(void)
+{
+ if(outbused > 0) {
+#if DK4_ON_WINDOWS
+ (void)_write(1, (void *)outbuffer, (unsigned int)outbused);
+#else
+#if DK4_HAVE_WRITE
+ if (write(1, (void *)outbuffer, outbused) != outbused) {
+ /* Intentionally empty */
+ }
+#else
+#if DK4_HAVE__WRITE
+ if (_write(1, (void *)outbuffer, outbused) != outbused) {
+ /* Intentionally empty */
+ }
+#else
+#error "No write() function"
+#endif
+#endif
+#endif
+ }
+ outbused = 0;
+}
+
+
+
+/** Add one character to output buffer, flush if buffer is full.
+ @param c Character to add.
+*/
+static void add_char(char c)
+{
+ outbuffer[outbused++] = c;
+ if(outbused == sizeof(outbuffer)) {
+ flush_buffer();
+ outbused = 0;
+ }
+}
+
+
+
+/** The main() function of the addctrld program.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, other values indicate errors.
+*/
+int main(int argc, char *argv[])
+{
+ char inbuffer[sizeof(outbuffer)];
+ char *ptr;
+ int ende; ssize_t lgt; int have_ctrld;
+
+ outbused = 0; ende = 0; have_ctrld = 0;
+ while(ende == 0) {
+#if DK4_ON_WINDOWS
+ lgt = _read(0, inbuffer, sizeof(inbuffer));
+#else
+#if DK4_HAVE_READ
+ lgt = read(0, inbuffer, sizeof(inbuffer));
+#else
+#if DK4_HAVE__READ
+ lgt = _read(0, inbuffer, sizeof(inbuffer));
+#else
+#error "No read() function!"
+#endif
+#endif
+#endif
+ if(lgt > 0) {
+ ptr = inbuffer;
+ while(lgt--) {
+ if(*ptr == 0x04) have_ctrld = 1;
+ else have_ctrld = 0;
+ add_char(*(ptr++));
+ }
+ } else {
+ ende = 1;
+ }
+ }
+ if(!have_ctrld) add_char(0x04);
+ flush_buffer();
+ fflush(stdout);
+ exit(0); return 0;
+}
+
+
diff --git a/support/dktools/addctrld.ctr b/support/dktools/addctrld.ctr
new file mode 100644
index 0000000000..dda237d93a
--- /dev/null
+++ b/support/dktools/addctrld.ctr
@@ -0,0 +1,190 @@
+/*
+Copyright (c) 2001-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms,
+with or without modification, are permitted provided
+that the following conditions are met:
+
+* Redistributions of source code must retain the above
+ copyright notice, this list of conditions and the
+ following disclaimer.
+* Redistributions in binary form must reproduce the above
+ opyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials
+ provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of
+ contributors may be used to endorse or promote
+ products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+*/
+
+/** @file addctrld.c Ensure to have CTRL-D as last byte.
+
+This program is a filter. If the final byte in the input stream
+is not a CTRL-D the program appends a CTRL-D.
+*/
+
+#include "dk4conf.h"
+
+
+#if DK4_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include <stdio.h>
+
+#if DK4_HAVE_IO_H
+#include <io.h>
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#include <process.h>
+#endif
+
+
+$(trace-include)
+
+
+
+#if !DK4_HAVE_SSIZE_T
+#ifdef DK4_HAVE_SSIZE_T
+#undef DK4_HAVE_SSIZE_T
+#endif
+/** Data type for read/write operation result.
+*/
+typedef size_t ssize_t;
+
+/** Flag: ssize_t defined.
+*/
+#define DK4_HAVE_SSIZE_T 1
+#endif
+
+
+
+/** Length of output buffer in bytes.
+*/
+#define BUFFER_SIZE 4096
+
+
+/** Output buffer.
+*/
+static char outbuffer[BUFFER_SIZE];
+
+
+/** Number of bytes currently used in output buffer.
+*/
+static size_t outbused;
+
+
+
+/** Flush output buffer.
+*/
+static void flush_buffer(void)
+{
+ if(outbused > 0) {
+#if DK4_ON_WINDOWS
+ (void)_write(1, (void *)outbuffer, (unsigned int)outbused);
+#else
+#if DK4_HAVE_WRITE
+ if (write(1, (void *)outbuffer, outbused) != outbused) {
+ /* Intentionally empty */
+ }
+#else
+#if DK4_HAVE__WRITE
+ if (_write(1, (void *)outbuffer, outbused) != outbused) {
+ /* Intentionally empty */
+ }
+#else
+#error "No write() function"
+#endif
+#endif
+#endif
+ }
+ outbused = 0;
+}
+
+
+
+/** Add one character to output buffer, flush if buffer is full.
+ @param c Character to add.
+*/
+static void add_char(char c)
+{
+ outbuffer[outbused++] = c;
+ if(outbused == sizeof(outbuffer)) {
+ flush_buffer();
+ outbused = 0;
+ }
+}
+
+
+
+/** The main() function of the addctrld program.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, other values indicate errors.
+*/
+int main(int argc, char *argv[])
+{
+ char inbuffer[sizeof(outbuffer)];
+ char *ptr;
+ int ende; ssize_t lgt; int have_ctrld;
+
+ outbused = 0; ende = 0; have_ctrld = 0;
+ while(ende == 0) {
+#if DK4_ON_WINDOWS
+ lgt = _read(0, inbuffer, sizeof(inbuffer));
+#else
+#if DK4_HAVE_READ
+ lgt = read(0, inbuffer, sizeof(inbuffer));
+#else
+#if DK4_HAVE__READ
+ lgt = _read(0, inbuffer, sizeof(inbuffer));
+#else
+#error "No read() function!"
+#endif
+#endif
+#endif
+ if(lgt > 0) {
+ ptr = inbuffer;
+ while(lgt--) {
+ if(*ptr == 0x04) have_ctrld = 1;
+ else have_ctrld = 0;
+ add_char(*(ptr++));
+ }
+ } else {
+ ende = 1;
+ }
+ }
+ if(!have_ctrld) add_char(0x04);
+ flush_buffer();
+ fflush(stdout);
+ exit(0); return 0;
+}
+
+
diff --git a/support/dktools/addctrld.rc b/support/dktools/addctrld.rc
new file mode 100644
index 0000000000..7502b80d97
--- /dev/null
+++ b/support/dktools/addctrld.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Ensure final Ctrl-D\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "Ensure final Ctrl-D\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "addctrld\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/autom4te.cache/output.0 b/support/dktools/autom4te.cache/output.0
new file mode 100644
index 0000000000..9e520f429f
--- /dev/null
+++ b/support/dktools/autom4te.cache/output.0
@@ -0,0 +1,15822 @@
+@%:@! /bin/sh
+@%:@ Guess values for system-dependent variables and create Makefiles.
+@%:@ Generated by GNU Autoconf 2.69.
+@%:@
+@%:@
+@%:@ Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+@%:@
+@%:@
+@%:@ This configure script is free software; the Free Software Foundation
+@%:@ gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in @%:@(
+ *posix*) :
+ set -o posix ;; @%:@(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in @%:@(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in @%:@((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Use a proper internal environment variable to ensure we don't fall
+ # into an infinite loop, continuously re-executing ourselves.
+ if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+ _as_can_reexec=no; export _as_can_reexec;
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in @%:@ ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+ fi
+ # We don't want this to propagate to other subprocesses.
+ { _as_can_reexec=; unset _as_can_reexec;}
+if test "x$CONFIG_SHELL" = x; then
+ as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in @%:@(
+ *posix*) :
+ set -o posix ;; @%:@(
+ *) :
+ ;;
+esac
+fi
+"
+ as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+ exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
+ as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+ as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+ eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+ test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+ if (eval "$as_required") 2>/dev/null; then :
+ as_have_required=yes
+else
+ as_have_required=no
+fi
+ if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ as_found=:
+ case $as_dir in @%:@(
+ /*)
+ for as_base in sh bash ksh sh5; do
+ # Try only shells that exist, to save several forks.
+ as_shell=$as_dir/$as_base
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ CONFIG_SHELL=$as_shell as_have_required=yes
+ if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ break 2
+fi
+fi
+ done;;
+ esac
+ as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+ CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+ if test "x$CONFIG_SHELL" != x; then :
+ export CONFIG_SHELL
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in @%:@ ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+fi
+
+ if test x$as_have_required = xno; then :
+ $as_echo "$0: This script requires a shell more modern than all"
+ $as_echo "$0: the shells that I found on your system."
+ if test x${ZSH_VERSION+set} = xset ; then
+ $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+ $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+ else
+ $as_echo "$0: Please tell bug-autoconf@gnu.org about your system,
+$0: including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
+ fi
+ exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+@%:@ as_fn_unset VAR
+@%:@ ---------------
+@%:@ Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+@%:@ as_fn_set_status STATUS
+@%:@ -----------------------
+@%:@ Set @S|@? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} @%:@ as_fn_set_status
+
+@%:@ as_fn_exit STATUS
+@%:@ -----------------
+@%:@ Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} @%:@ as_fn_exit
+
+@%:@ as_fn_mkdir_p
+@%:@ -------------
+@%:@ Create "@S|@as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} @%:@ as_fn_mkdir_p
+
+@%:@ as_fn_executable_p FILE
+@%:@ -----------------------
+@%:@ Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} @%:@ as_fn_executable_p
+@%:@ as_fn_append VAR VALUE
+@%:@ ----------------------
+@%:@ Append the text in VALUE to the end of the definition contained in VAR. Take
+@%:@ advantage of any shell optimizations that allow amortized linear growth over
+@%:@ repeated appends, instead of the typical quadratic growth present in naive
+@%:@ implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+@%:@ as_fn_arith ARG...
+@%:@ ------------------
+@%:@ Perform arithmetic evaluation on the ARGs, and store the result in the
+@%:@ global @S|@as_val. Take advantage of shells that can avoid forks. The arguments
+@%:@ must be portable across @S|@(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+@%:@ as_fn_error STATUS ERROR [LINENO LOG_FD]
+@%:@ ----------------------------------------
+@%:@ Output "`basename @S|@0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+@%:@ provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+@%:@ script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} @%:@ as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+ as_lineno_1=$LINENO as_lineno_1a=$LINENO
+ as_lineno_2=$LINENO as_lineno_2a=$LINENO
+ eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+ test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+ # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+ # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+ # already done that, so ensure we don't try to do so again and fall
+ # in an infinite loop. This has already happened in practice.
+ _as_can_reexec=no; export _as_can_reexec
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in @%:@(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIB@&t@OBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+PACKAGE_URL=
+
+ac_unique_file="dk4.h"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='LTLIBOBJS
+LIB@&t@OBJS
+LIBDK3WXLIBS
+LIBDK3WXLIBF
+LIBDK3FIGLIBS
+LIBDK3FIGLIBF
+LIBDK3BMEPSLIBS
+LIBDK3BMEPSLIBF
+LIBDK3DBILIBS
+LIBDK3DBILIBF
+LIBDK3BIFLIBS
+LIBDK3BIFLIBF
+LIBDK3CSRNDLIBS
+LIBDK3CSRNDLIBF
+LIBDK3OFLIBS
+LIBDK3OFLIBF
+LIBDK3CLIBS
+LIBDK3CLIBF
+LIBDK3TRACELIBS
+LIBDK3TRACELIBF
+LIBDK4WXLIBS
+LIBDK4WXLIBF
+LIBDK4DBIALIBS
+LIBDK4DBIALIBF
+LIBDK4SOCKALIBS
+LIBDK4SOCKALIBF
+LIBDK4PPPTALIBS
+LIBDK4PPPTALIBF
+LIBDK4APPLIBS
+LIBDK4APPLIBF
+LIBDK4PPPTLIBS
+LIBDK4PPPTLIBF
+LIBDK4MDRNDLIBS
+LIBDK4MDRNDLIBF
+LIBDK4SOCKLIBS
+LIBDK4SOCKLIBF
+LIBDK4LATLIBS
+LIBDK4LATLIBF
+LIBDK4CLIBS
+LIBDK4CLIBF
+LIBDK4DBILIBS
+LIBDK4DBILIBF
+LIBDK4MAIODHLIBS
+LIBDK4MAIODHLIBF
+LIBDK4MAIOWHLIBS
+LIBDK4MAIOWHLIBF
+LIBDK4MAIO8HLIBS
+LIBDK4MAIO8HLIBF
+LIBDK4MAIOXDLIBS
+LIBDK4MAIOXDLIBF
+LIBDK4MAIODDLIBS
+LIBDK4MAIODDLIBF
+LIBDK4MAIOWDLIBS
+LIBDK4MAIOWDLIBF
+LIBDK4MAIO8DLIBS
+LIBDK4MAIO8DLIBF
+LIBDK4MALIBS
+LIBDK4MALIBF
+LIBDK4BASELIBS
+LIBDK4BASELIBF
+RTLIB
+LIBSPRIVATE
+INSTALLMANPAGES
+WINUNICODE
+ENTRY
+GUILIB
+CLILIB
+MAKE
+GETSOURCE
+WXDKFCSLIBS
+WXDKFCSLIBF
+NETSNMP_CFLAGS
+MYSQLLIB
+NETSNMP_LIBS
+SOLIBDK4DBIA
+SOLIBDK4DBI
+SOLIBDK4SOCKA
+SOLIBDK4SOCK
+SOLIBDK4LAT
+SOLIBDK4APP
+SOLIBDK4PPPT
+SOLIBDK4MDRND
+SOLIBDK4C
+SOLIBDK4MAIODD
+SOLIBDK4MAIOWD
+SOLIBDK4MAIO8D
+SOLIBDK4MAIODH
+SOLIBDK4MAIOWH
+SOLIBDK4MAIO8H
+SOLIBDK4MA
+SOLIBDK4BASE
+SOLIBDK3NET
+SOLIBDK3BMEPS
+SOLIBDK3FIG
+SOLIBDK3DBI
+SOLIBDK3BIF
+SOLIBDK3CSRND
+SOLIBDK3OF
+SOLIBDK3C
+SOLIBDK3PORT
+SOLIBWX
+SOLIBSDBI
+SOLIBIMG
+SOLIBNET
+SOLIBCRYPTO
+SOLIBMATH
+SOLIBBZ
+SOLIBZ
+WXLDFLAGS
+WXCFLAGS
+WXCXXFLAGS
+WXCPPFLAGS
+TESTPROGRAMS
+SNMP_PROG_CLI
+MYSQLLDFLAGS
+MYSQL_PROG_CLI
+NET_PROG_CLI
+NET_PROG_RES
+LIB_SH_GUI
+LIB_SH_CLI
+LIB_SH_RES
+NSLLIB
+SOCKLIB
+PROGSOPENSSL
+DK4INFOLIBF
+DK4INFOLIBS
+DKDBT2LIBS
+DKDBT2LIBF
+DKSENDLIBS
+DKSENDLIBF
+DKRECVLIBS
+DKRECVLIBF
+DKPWDLIBS
+DKPWDLIBF
+DKBMMLIBS
+DKBMMLIBF
+DKHEXLIBS
+DKHEXLIBF
+DKT2LLIBS
+DKT2LLIBF
+DKT2HLIBS
+DKT2HLIBF
+DKRANDLIBS
+DKRANDLIBF
+DKPWGENLIBS
+DKPWGENLIBF
+DKUIDLIBS
+DKUIDLIBF
+DKFICLIBS
+DKFICLIBF
+DKSORTLIBS
+DKSORTLIBF
+DKLSLIBS
+DKLSLIBF
+DKERADISKLIBS
+DKERADISKLIBF
+DKSQLSPLITLIBS
+DKSQLSPLITLIBF
+DKBLKSLIBS
+DKBLKSLIBF
+DKCATLIBS
+DKCATLIBF
+CRYPTO
+CWARN
+SOVERS
+VERSNO
+SHLIBSTYLE
+UNAME
+RPATHLINK
+RPATH
+MKSOLIB
+RES_INSTALL
+LIBS_INSTALL
+LIBS_SHARED
+LIBS_STATIC
+LIBRARIES
+PROGRAMS
+CFPIC
+BZLIB
+ZLIB
+FS64
+ITADMINLIBS
+ITADMINLIBF
+LPRNGCLLIBS
+LPRNGCLLIBF
+RSHDOWNLIBS
+RSHDOWNLIBF
+PRINTQDCLIBS
+PRINTQDCLIBF
+PRMONSNMPLIBS
+PRMONSNMPLIBF
+PJSNMPLIBS
+PJSNMPLIBF
+PRINTQDALIBS
+PRINTQDALIBF
+PRINTQDILIBS
+PRINTQDILIBF
+PRINTQDLIBS
+PRINTQDLIBF
+WXDKHTBLIBS
+WXDKHTBLIBF
+WXDKCLOCKLIBS
+WXDKCLOCKLIBF
+WXIMGSZLIBS
+WXIMGSZLIBF
+WXPQDICLIBS
+WXPQDICLIBF
+WXBMPPLIBS
+WXBMPPLIBF
+WXDKCTLIBS
+WXDKCTLIBF
+DKWXWIZLIBS
+DKWXWIZLIBF
+PLPDFTEXLIBS
+PLPDFTEXLIBF
+DK3INFOLIBS
+DK3INFOLIBF
+HTMLBOOKLIBS
+HTMLBOOKLIBF
+FIG2LATLIBS
+FIG2LATLIBF
+BMPPLIBS
+BMPPLIBF
+DKDBTLIBS
+DKDBTLIBF
+ADDCTRLDLIBS
+ADDCTRLDLIBF
+DKCTLIBS
+DKCTLIBF
+LIBDK4WXTOBUILD
+LIBDK4WXOBJ
+LIBDK3WXOBJ
+PTHREADLIB
+CLI_MYSQLPROG
+DBLIBSOCK
+DBLIB
+LIBTIFF
+LIBJPEG
+LIBPNG
+CLI_SNMPPROG
+ANYDB
+CURL
+WGET
+NM
+AR
+RANLIB
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+LN_S
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+SED
+MKDIR_P
+EGREP
+GREP
+ac_ct_CXX
+CXXFLAGS
+CXX
+CPP
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_inline
+enable_static
+enable_shared
+enable_packaging
+enable_ndbm
+enable_warnings
+enable_more_warnings
+with_suite
+with_man
+with_corrections
+with_fallback_limits
+with_printf_scanf
+'
+ ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CPP
+CXX
+CXXFLAGS
+CCC'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval $ac_prev=\$ac_option
+ ac_prev=
+ continue
+ fi
+
+ case $ac_option in
+ *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *=) ac_optarg= ;;
+ *) ac_optarg=yes ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=*)
+ datadir=$ac_optarg ;;
+
+ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+ | --dataroo | --dataro | --datar)
+ ac_prev=datarootdir ;;
+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+ datarootdir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=no ;;
+
+ -docdir | --docdir | --docdi | --doc | --do)
+ ac_prev=docdir ;;
+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+ docdir=$ac_optarg ;;
+
+ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+ ac_prev=dvidir ;;
+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+ dvidir=$ac_optarg ;;
+
+ -enable-* | --enable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=\$ac_optarg ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+ ac_prev=htmldir ;;
+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+ | --ht=*)
+ htmldir=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localedir | --localedir | --localedi | --localed | --locale)
+ ac_prev=localedir ;;
+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+ localedir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst | --locals)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+ ac_prev=pdfdir ;;
+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+ pdfdir=$ac_optarg ;;
+
+ -psdir | --psdir | --psdi | --psd | --ps)
+ ac_prev=psdir ;;
+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+ psdir=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=\$ac_optarg ;;
+
+ -without-* | --without-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=no ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ case $ac_envvar in #(
+ '' | [0-9]* | *[!_$as_cr_alnum]* )
+ as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+ esac
+ eval $ac_envvar=\$ac_optarg
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+ case $enable_option_checking in
+ no) ;;
+ fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+ *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+ esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+ libdir localedir mandir
+do
+ eval ac_val=\$$ac_var
+ # Remove trailing slashes.
+ case $ac_val in
+ */ )
+ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+ eval $ac_var=\$ac_val;;
+ esac
+ # Be sure to have absolute directory names.
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+ esac
+ as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ as_fn_error $? "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then the parent directory.
+ ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_myself" : 'X\(//\)[^/]' \| \
+ X"$as_myself" : 'X\(//\)$' \| \
+ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r "$srcdir/$ac_unique_file"; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+ pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+ srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+ eval ac_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_env_${ac_var}_value=\$${ac_var}
+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking ...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ @<:@@S|@ac_default_prefix@:>@
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ @<:@PREFIX@:>@
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root @<:@DATAROOTDIR/doc/PACKAGE@:>@
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
+_ACEOF
+
+ cat <<\_ACEOF
+
+System types:
+ --build=BUILD configure for building on BUILD [guessed]
+ --host=HOST cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-option-checking ignore unrecognized --enable/--with options
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --enable-inline Allow use of inline keyword (no / yes)
+ --enable-static Allow building static libraries (yes / no)
+ --enable-shared Allow building shared libraries (yes / no)
+ --enable-packaging Binaries use shared libraries (no / yes)
+ --enable-ndbm Explicitly enable/disable NDBM if found
+ --enable-warnings Enable high warning level, gcc only (yes / no)
+ --enable-more-warnings Enable yet more warnings, gcc only (no / yes)
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-suite=name Software suite to build: auto / gui / cli / rescue
+ --with-man Install man pages (auto / yes / no)
+ --with-corrections Enable corrections for Solaris: no / yes
+ --with-fallback-limits Allow use of fallback limits (no / yes)
+ --with-printf-scanf Allow use of printf and scanf (yes / no)
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ LIBS libraries to pass to the linker, e.g. -l<library>
+ CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+ you have headers in a nonstandard directory <include dir>
+ CPP C preprocessor
+ CXX C++ compiler command
+ CXXFLAGS C++ compiler flags
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to the package provider.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d "$ac_dir" ||
+ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+ continue
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+ # Check for guested configure.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+ elif test -f "$ac_srcdir/configure"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure" --help=recursive
+ else
+ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
+ done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+ cat <<\_ACEOF
+configure
+generated by GNU Autoconf 2.69
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+@%:@ ac_fn_c_try_compile LINENO
+@%:@ --------------------------
+@%:@ Try to compile conftest.@S|@ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} @%:@ ac_fn_c_try_compile
+
+@%:@ ac_fn_c_try_cpp LINENO
+@%:@ ----------------------
+@%:@ Try to preprocess conftest.@S|@ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } > conftest.i && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} @%:@ ac_fn_c_try_cpp
+
+@%:@ ac_fn_cxx_try_compile LINENO
+@%:@ ----------------------------
+@%:@ Try to compile conftest.@S|@ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} @%:@ ac_fn_cxx_try_compile
+
+@%:@ ac_fn_c_try_run LINENO
+@%:@ ----------------------
+@%:@ Try to link conftest.@S|@ac_ext, and return whether this succeeded. Assumes
+@%:@ that executables *can* be run.
+ac_fn_c_try_run ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=$ac_status
+fi
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} @%:@ ac_fn_c_try_run
+
+@%:@ ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+@%:@ -------------------------------------------------------
+@%:@ Tests whether HEADER exists and can be compiled using the include files in
+@%:@ INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+@%:@include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} @%:@ ac_fn_c_check_header_compile
+
+@%:@ ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+@%:@ -------------------------------------------------------
+@%:@ Tests whether HEADER exists, giving a warning if it cannot be compiled using
+@%:@ the include files in INCLUDES and setting the cache variable VAR
+@%:@ accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if eval \${$3+:} false; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+@%:@include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_header_compiler=yes
+else
+ ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+@%:@include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ ac_header_preproc=yes
+else
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+ yes:no: )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} @%:@ ac_fn_c_check_header_mongrel
+
+@%:@ ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
+@%:@ --------------------------------------------
+@%:@ Tries to find the compile-time value of EXPR in a program that includes
+@%:@ INCLUDES, setting VAR accordingly. Returns whether the value could be
+@%:@ computed
+ac_fn_c_compute_int ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if test "$cross_compiling" = yes; then
+ # Depending upon the size, compute the lo and hi bounds.
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array @<:@1 - 2 * !(($2) >= 0)@:>@;
+test_array @<:@0@:>@ = 0;
+return test_array @<:@0@:>@;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_lo=0 ac_mid=0
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array @<:@1 - 2 * !(($2) <= $ac_mid)@:>@;
+test_array @<:@0@:>@ = 0;
+return test_array @<:@0@:>@;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=$ac_mid; break
+else
+ as_fn_arith $ac_mid + 1 && ac_lo=$as_val
+ if test $ac_lo -le $ac_mid; then
+ ac_lo= ac_hi=
+ break
+ fi
+ as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array @<:@1 - 2 * !(($2) < 0)@:>@;
+test_array @<:@0@:>@ = 0;
+return test_array @<:@0@:>@;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=-1 ac_mid=-1
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array @<:@1 - 2 * !(($2) >= $ac_mid)@:>@;
+test_array @<:@0@:>@ = 0;
+return test_array @<:@0@:>@;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_lo=$ac_mid; break
+else
+ as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val
+ if test $ac_mid -le $ac_hi; then
+ ac_lo= ac_hi=
+ break
+ fi
+ as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ ac_lo= ac_hi=
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+ as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array @<:@1 - 2 * !(($2) <= $ac_mid)@:>@;
+test_array @<:@0@:>@ = 0;
+return test_array @<:@0@:>@;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=$ac_mid
+else
+ as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in @%:@((
+?*) eval "$3=\$ac_lo"; ac_retval=0 ;;
+'') ac_retval=1 ;;
+esac
+ else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+static long int longval () { return $2; }
+static unsigned long int ulongval () { return $2; }
+@%:@include <stdio.h>
+@%:@include <stdlib.h>
+int
+main ()
+{
+
+ FILE *f = fopen ("conftest.val", "w");
+ if (! f)
+ return 1;
+ if (($2) < 0)
+ {
+ long int i = longval ();
+ if (i != ($2))
+ return 1;
+ fprintf (f, "%ld", i);
+ }
+ else
+ {
+ unsigned long int i = ulongval ();
+ if (i != ($2))
+ return 1;
+ fprintf (f, "%lu", i);
+ }
+ /* Do not output a trailing newline, as this causes \r\n confusion
+ on some platforms. */
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ echo >>conftest.val; read $3 <conftest.val; ac_retval=0
+else
+ ac_retval=1
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+rm -f conftest.val
+
+ fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} @%:@ ac_fn_c_compute_int
+
+@%:@ ac_fn_c_try_link LINENO
+@%:@ -----------------------
+@%:@ Try to link conftest.@S|@ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ test -x conftest$ac_exeext
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} @%:@ ac_fn_c_try_link
+
+@%:@ ac_fn_c_check_func LINENO FUNC VAR
+@%:@ ----------------------------------
+@%:@ Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $2 (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} @%:@ ac_fn_c_check_func
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.69. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ $as_echo "PATH: $as_dir"
+ done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *\'*)
+ ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+ 2)
+ as_fn_append ac_configure_args1 " '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ as_fn_append ac_configure_args " '$ac_arg'"
+ ;;
+ esac
+ done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+(
+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+ (set) 2>&1 |
+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ sed -n \
+ "s/'\''/'\''\\\\'\'''\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+ ;; #(
+ *)
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+)
+ echo
+
+ $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+ echo
+ cat confdefs.h
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ $as_echo "$as_me: caught signal $ac_signal"
+ $as_echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+@%:@define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+@%:@define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+@%:@define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+@%:@define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+@%:@define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+@%:@define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+ # We do not want a PATH search for config.site.
+ case $CONFIG_SITE in @%:@((
+ -*) ac_site_file1=./$CONFIG_SITE;;
+ */*) ac_site_file1=$CONFIG_SITE;;
+ *) ac_site_file1=./$CONFIG_SITE;;
+ esac
+elif test "x$prefix" != xNONE; then
+ ac_site_file1=$prefix/share/config.site
+ ac_site_file2=$prefix/etc/config.site
+else
+ ac_site_file1=$ac_default_prefix/share/config.site
+ ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+ test "x$ac_site_file" = xNONE && continue
+ if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file" \
+ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special files
+ # actually), so we avoid doing that. DJGPP emulates it as a regular file.
+ if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
+ esac
+ fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val=\$ac_cv_env_${ac_var}_value
+ eval ac_new_val=\$ac_env_${ac_var}_value
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ # differences in whitespace do not lead to failure.
+ ac_old_val_w=`echo x $ac_old_val`
+ ac_new_val_w=`echo x $ac_new_val`
+ if test "$ac_old_val_w" != "$ac_new_val_w"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ ac_cache_corrupted=:
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+ eval $ac_var=\$ac_old_val
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
+$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
+$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ac_config_headers="$ac_config_headers config.h"
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $@%:@ != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+ esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link_default") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile. We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+ then :; else
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ fi
+ # We set ac_cv_exeext here because the later test for it is not
+ # safe: cross compilers may not add the suffix if given an `-o'
+ # argument, so we may need to know it at that point already.
+ # Even if this section looks crufty: it has the advantage of
+ # actually working.
+ break;;
+ * )
+ break;;
+ esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+ ac_file=''
+fi
+if test -z "$ac_file"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+@%:@include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+ { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if { ac_try='./conftest$ac_cv_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if ${ac_cv_objext+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ for ac_file in conftest.o conftest.obj conftest.*; do
+ test -f "$ac_file" || continue;
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+else
+ CFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if ${ac_cv_prog_CPP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+@%:@ifdef __STDC__
+@%:@ include <limits.h>
+@%:@else
+@%:@ include <assert.h>
+@%:@endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+@%:@include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+@%:@ifdef __STDC__
+@%:@ include <limits.h>
+@%:@else
+@%:@ include <assert.h>
+@%:@endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+@%:@include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+ if test -n "$CCC"; then
+ CXX=$CCC
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CXX"; then
+ ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CXX" && break
+ done
+fi
+if test -z "$CXX"; then
+ ac_ct_CXX=$CXX
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CXX"; then
+ ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CXX="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CXX" && break
+done
+
+ if test "x$ac_ct_CXX" = x; then
+ CXX="g++"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CXX=$ac_ct_CXX
+ fi
+fi
+
+ fi
+fi
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5
+$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
+if ${ac_cv_cxx_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GXX=yes
+else
+ GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if ${ac_cv_prog_cxx_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+ ac_cxx_werror_flag=yes
+ ac_cv_prog_cxx_g=no
+ CXXFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_prog_cxx_g=yes
+else
+ CXXFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+ CXXFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_prog_cxx_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+ CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+ if test "$GXX" = yes; then
+ CXXFLAGS="-g -O2"
+ else
+ CXXFLAGS="-g"
+ fi
+else
+ if test "$GXX" = yes; then
+ CXXFLAGS="-O2"
+ else
+ CXXFLAGS=
+ fi
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$GREP"; then
+ ac_path_GREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in grep ggrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_GREP" || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+ # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'GREP' >> "conftest.nl"
+ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_GREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_GREP="$ac_path_GREP"
+ ac_path_GREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_GREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_GREP"; then
+ as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+ then ac_cv_path_EGREP="$GREP -E"
+ else
+ if test -z "$EGREP"; then
+ ac_path_EGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in egrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_EGREP" || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+ # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'EGREP' >> "conftest.nl"
+ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_EGREP="$ac_path_EGREP"
+ ac_path_EGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_EGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_EGREP"; then
+ as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_EGREP=$EGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdc=yes
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then :
+ :
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "@%:@define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
+$as_echo_n "checking whether byte ordering is bigendian... " >&6; }
+if ${ac_cv_c_bigendian+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_c_bigendian=unknown
+ # See if we're dealing with a universal compiler.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifndef __APPLE_CC__
+ not a universal capable compiler
+ #endif
+ typedef int dummy;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ # Check for potential -arch flags. It is not universal unless
+ # there are at least two -arch flags with different values.
+ ac_arch=
+ ac_prev=
+ for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do
+ if test -n "$ac_prev"; then
+ case $ac_word in
+ i?86 | x86_64 | ppc | ppc64)
+ if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then
+ ac_arch=$ac_word
+ else
+ ac_cv_c_bigendian=universal
+ break
+ fi
+ ;;
+ esac
+ ac_prev=
+ elif test "x$ac_word" = "x-arch"; then
+ ac_prev=arch
+ fi
+ done
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ if test $ac_cv_c_bigendian = unknown; then
+ # See if sys/param.h defines the BYTE_ORDER macro.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ #include <sys/param.h>
+
+int
+main ()
+{
+#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \
+ && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \
+ && LITTLE_ENDIAN)
+ bogus endian macros
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ # It does; now see whether it defined to BIG_ENDIAN or not.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ #include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_bigendian=yes
+else
+ ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test $ac_cv_c_bigendian = unknown; then
+ # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <limits.h>
+
+int
+main ()
+{
+#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
+ bogus endian macros
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ # It does; now see whether it defined to _BIG_ENDIAN or not.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <limits.h>
+
+int
+main ()
+{
+#ifndef _BIG_ENDIAN
+ not big endian
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_bigendian=yes
+else
+ ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test $ac_cv_c_bigendian = unknown; then
+ # Compile a test program.
+ if test "$cross_compiling" = yes; then :
+ # Try to guess by grepping values from an object file.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+short int ascii_mm[] =
+ { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+ short int ascii_ii[] =
+ { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+ int use_ascii (int i) {
+ return ascii_mm[i] + ascii_ii[i];
+ }
+ short int ebcdic_ii[] =
+ { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+ short int ebcdic_mm[] =
+ { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+ int use_ebcdic (int i) {
+ return ebcdic_mm[i] + ebcdic_ii[i];
+ }
+ extern int foo;
+
+int
+main ()
+{
+return use_ascii (foo) == use_ebcdic (foo);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then
+ ac_cv_c_bigendian=yes
+ fi
+ if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+ if test "$ac_cv_c_bigendian" = unknown; then
+ ac_cv_c_bigendian=no
+ else
+ # finding both strings is unlikely to happen, but who knows?
+ ac_cv_c_bigendian=unknown
+ fi
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+
+ /* Are we little or big endian? From Harbison&Steele. */
+ union
+ {
+ long int l;
+ char c[sizeof (long int)];
+ } u;
+ u.l = 1;
+ return u.c[sizeof (long int) - 1] == 1;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_c_bigendian=no
+else
+ ac_cv_c_bigendian=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5
+$as_echo "$ac_cv_c_bigendian" >&6; }
+ case $ac_cv_c_bigendian in #(
+ yes)
+ $as_echo "@%:@define WORDS_BIGENDIAN 1" >>confdefs.h
+;; #(
+ no)
+ ;; #(
+ universal)
+
+$as_echo "@%:@define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
+
+ ;; #(
+ *)
+ as_fn_error $? "unknown endianness
+ presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
+ esac
+
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+ if test -f "$ac_dir/install-sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f "$ac_dir/install.sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f "$ac_dir/shtool"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
+$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+if test -z "$MKDIR_P"; then
+ if ${ac_cv_path_mkdir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in mkdir gmkdir; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue
+ case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+ 'mkdir (GNU coreutils) '* | \
+ 'mkdir (coreutils) '* | \
+ 'mkdir (fileutils) '4.1*)
+ ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+ break 3;;
+ esac
+ done
+ done
+ done
+IFS=$as_save_IFS
+
+fi
+
+ test -d ./--version && rmdir ./--version
+ if test "${ac_cv_path_mkdir+set}" = set; then
+ MKDIR_P="$ac_cv_path_mkdir -p"
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for MKDIR_P within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ MKDIR_P="$ac_install_sh -d"
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if ${ac_cv_path_SED+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+ for ac_i in 1 2 3 4 5 6 7; do
+ ac_script="$ac_script$as_nl$ac_script"
+ done
+ echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+ { ac_script=; unset ac_script;}
+ if test -z "$SED"; then
+ ac_path_SED_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_SED" || continue
+# Check for GNU ac_path_SED and select it if it is found.
+ # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2>&1` in
+*GNU*)
+ ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo '' >> "conftest.nl"
+ "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_SED_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_SED="$ac_path_SED"
+ ac_path_SED_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_SED_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_SED"; then
+ as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5
+ fi
+else
+ ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+$as_echo "$ac_cv_path_SED" >&6; }
+ SED="$ac_cv_path_SED"
+ rm -f conftest.sed
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if ${ac_cv_path_install+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in @%:@((
+ ./ | .// | /[cC]/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ rm -rf conftest.one conftest.two conftest.dir
+ echo one > conftest.one
+ echo two > conftest.two
+ mkdir conftest.dir
+ if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+ test -s conftest.one && test -s conftest.two &&
+ test -s conftest.dir/conftest.one &&
+ test -s conftest.dir/conftest.two
+ then
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+
+ done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ INSTALL=$ac_install_sh
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
+$as_echo_n "checking whether ln -s works... " >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
+$as_echo "no, using $LN_S" >&6; }
+fi
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+ as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if ${ac_cv_build+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+ ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+ as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if ${ac_cv_host+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$host_alias" = x; then
+ ac_cv_host=$ac_cv_build
+else
+ ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_RANLIB" = x; then
+ RANLIB=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ RANLIB=$ac_ct_RANLIB
+ fi
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ar; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AR="${ac_tool_prefix}ar"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_AR"; then
+ ac_ct_AR=$AR
+ # Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AR"; then
+ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_AR="ar"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_AR" = x; then
+ AR="ar"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ AR=$ac_ct_AR
+ fi
+else
+ AR="$ac_cv_prog_AR"
+fi
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}nm", so it can be a program name with args.
+set dummy ${ac_tool_prefix}nm; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_NM+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NM"; then
+ ac_cv_prog_NM="$NM" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_NM="${ac_tool_prefix}nm"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+NM=$ac_cv_prog_NM
+if test -n "$NM"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NM" >&5
+$as_echo "$NM" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_NM"; then
+ ac_ct_NM=$NM
+ # Extract the first word of "nm", so it can be a program name with args.
+set dummy nm; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_NM+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_NM"; then
+ ac_cv_prog_ac_ct_NM="$ac_ct_NM" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_NM="nm"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_NM=$ac_cv_prog_ac_ct_NM
+if test -n "$ac_ct_NM"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NM" >&5
+$as_echo "$ac_ct_NM" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_NM" = x; then
+ NM="nm"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ NM=$ac_ct_NM
+ fi
+else
+ NM="$ac_cv_prog_NM"
+fi
+
+
+echo 'CC = ' $CC `which $CC`
+echo 'CXX = ' $CXX `which $CXX`
+
+
+
+FORCESOLINKING="no"
+
+USESOLINKING="no"
+
+INSTALLMANPAGES='install-manpages'
+
+LIBSPRIVATE=""
+
+MANINST='auto'
+
+EXVAL=0
+
+SOLCOR='no'
+
+CFPIC=''
+MKSOLIB=''
+SHLIBSTYLE=''
+UNAME=''
+WXCPPFLAGS=''
+WXCXXFLAGS=''
+WXCFLAGS=''
+WXLDFLAGS=''
+SUITE='auto'
+ENASTATIC='auto'
+ENASHARED='auto'
+PROGRAMS=''
+LIBRARIES=''
+LIBS_STATIC=''
+LIBS_SHARED=''
+LIBS_INSTALL=''
+RES_INSTALL=''
+RPATH=''
+RPATHLINK=''
+CWARN=''
+FOUND_GDBM='no'
+FOUND_NDBM='no'
+FOUND_BDB='no'
+USE_NDBM='auto'
+NET_PROG_RES=''
+NET_PROG_CLI=''
+MYSQL_PROG_CLI=''
+SNMP_PROG_CLI=''
+MYSQLLDFLAGS=''
+MYSQLLIB=''
+RTLIB=''
+SOLIBZ=''
+SOLIBBZ=''
+SOLIBMATH=''
+SOLIBCRYPTO=''
+SOLIBNET=''
+SOLIBIMG=''
+SOLIBSDBI=''
+SOLIBWX=''
+SOLIBDK3PORT=''
+SOLIBDK3C=''
+SOLIBDK3OF=''
+SOLIBDK3CSRND=''
+SOLIBDK3BIF=''
+SOLIBDK3DBI=''
+SOLIBDK3FIG=''
+SOLIBDK3BMEPS=''
+SOLIBDK3NET=''
+SOLIBDK4BASE=''
+SOLIBDK4MA=''
+SOLIBDK4MAIO8H=''
+SOLIBDK4MAIOWH=''
+SOLIBDK4MAIODH=''
+SOLIBDK4MAIO8D=''
+SOLIBDK4MAIOWD=''
+SOLIBDK4MAIODD=''
+SOLIBDK4C=''
+SOLIBDK4MDRND=''
+SOLIBDK4PPPT=''
+SOLIBDK4APP=''
+SOLIBDK4LAT=''
+SOLIBDK4SOCK=''
+SOLIBDK4SOCKA=''
+SOLIBDK4DBI=''
+SOLIBDK4DBIA=''
+LIBDK4BASELIBF=''
+LIBDK4BASELIBS=''
+LIBDK4MALIBF=''
+LIBDK4MALIBS=''
+LIBDK4MAIO8DLIBF=''
+LIBDK4MAIO8DLIBS=''
+LIBDK4MAIOWDLIBF=''
+LIBDK4MAIOWDLIBS=''
+LIBDK4MAIODDLIBF=''
+LIBDK4MAIODDLIBS=''
+LIBDK4MAIOXDLIBF=''
+LIBDK4MAIOXDLIBS=''
+LIBDK4MAIO8HLIBF=''
+LIBDK4MAIO8HLIBS=''
+LIBDK4MAIOWHLIBF=''
+LIBDK4MAIOWHLIBS=''
+LIBDK4MAIODHLIBF=''
+LIBDK4MAIODHLIBS=''
+LIBDK4DBILIBF=''
+LIBDK4DBILIBS=''
+LIBDK4CLIBF=''
+LIBDK4CLIBS=''
+LIBDK4LATLIBF=''
+LIBDK4LATLIBS=''
+LIBDK4SOCKLIBF=''
+LIBDK4SOCKLIBS=''
+LIBDK4MDRNDLIBF=''
+LIBDK4MDRNDLIBS=''
+LIBDK4PPPTLIBF=''
+LIBDK4PPPTLIBS=''
+LIBDK4APPLIBF=''
+LIBDK4APPLIBS=''
+LIBDK4PPPTALIBF=''
+LIBDK4PPPTALIBS=''
+LIBDK4SOCKALIBF=''
+LIBDK4SOCKALIBS=''
+LIBDK4DBIALIBF=''
+LIBDK4DBIALIBS=''
+LIBDK4WXLIBF=''
+LIBDK4WXLIBS=''
+LIBDK3TRACELIBF=''
+LIBDK3TRACELIBS=''
+LIBDK3CLIBF=''
+LIBDK3CLIBS=''
+LIBDK3OFLIBF=''
+LIBDK3OFLIBS=''
+LIBDK3CSRNDLIBF=''
+LIBDK3CSRNDLIBS=''
+LIBDK3BIFLIBF=''
+LIBDK3BIFLIBS=''
+LIBDK3DBILIBF=''
+LIBDK3DBILIBS=''
+LIBDK3BMEPSLIBF=''
+LIBDK3BMEPSLIBS=''
+LIBDK3FIGLIBF=''
+LIBDK3FIGLIBS=''
+LIBDK3WXLIBF=''
+LIBDK3WXLIBS=''
+
+
+VERSNO=`cat version.txt`
+SOVERS=`echo $VERSNO | sed -e 's/\.[01-9][01-9]*$//'`
+ENAPACKAGING="auto"
+LIB_SH_RES='$(LIB_SH_RES_NO_PACKAGING)'
+LIB_SH_CLI='$(LIB_SH_CLI_NO_PACKAGING)'
+UNAME=`uname -s`
+GETSOURCE='@echo "ERROR: Neither wget nor curl available, can not download source!" && false'
+WGET=''
+CURL=''
+CLILIB=''
+GUILIB=''
+ENTRY=''
+ONWINDOWS='no'
+WINUNICODE=''
+FOUNDINLINE="no"
+USEINLINE="no"
+CROSSCOMPILING="no"
+
+MAKE="echo No make program found to build"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking GNU make" >&5
+$as_echo_n "checking GNU make... " >&6; }
+gmake maketest > /dev/null 2>&1
+if [ "X$?" = "X0" ]
+then
+ MAKE='gmake'
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking make" >&5
+$as_echo_n "checking make... " >&6; }
+make maketest > /dev/null 2>&1
+if [ "X$?" = "X0" ]
+then
+ MAKE='make'
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+@%:@ Check whether --enable-inline was given.
+if test "${enable_inline+set}" = set; then :
+ enableval=$enable_inline; USEINLINE="$enableval"
+fi
+
+@%:@ Check whether --enable-static was given.
+if test "${enable_static+set}" = set; then :
+ enableval=$enable_static; ENASTATIC="$enableval"
+fi
+
+@%:@ Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then :
+ enableval=$enable_shared; ENASHARED="$enableval"
+fi
+
+@%:@ Check whether --enable-packaging was given.
+if test "${enable_packaging+set}" = set; then :
+ enableval=$enable_packaging; ENAPACKAGING="$enableval"
+fi
+
+@%:@ Check whether --enable-ndbm was given.
+if test "${enable_ndbm+set}" = set; then :
+ enableval=$enable_ndbm; USE_NDBM="$enableval"
+fi
+
+@%:@ Check whether --enable-warnings was given.
+if test "${enable_warnings+set}" = set; then :
+ enableval=$enable_warnings; WARNVAL="$enableval"
+fi
+
+@%:@ Check whether --enable-more-warnings was given.
+if test "${enable_more_warnings+set}" = set; then :
+ enableval=$enable_more_warnings; WARNMOREVAL="$enableval"
+fi
+
+
+@%:@ Check whether --with-suite was given.
+if test "${with_suite+set}" = set; then :
+ withval=$with_suite; SUITE="$withval"
+fi
+
+
+@%:@ Check whether --with-man was given.
+if test "${with_man+set}" = set; then :
+ withval=$with_man; MANINST="$withval"
+fi
+
+
+@%:@ Check whether --with-corrections was given.
+if test "${with_corrections+set}" = set; then :
+ withval=$with_corrections; SOLCOR="$withval"
+fi
+
+
+if [ "X$SOLCOR" = "Xyes" -a "X$UNAME" != "XSunOS" ]
+then
+ echo 'ERROR: The --with-corrections option is for Solaris/SunOS only!'
+ SOLCOR='no'
+fi
+
+if [ "X$host" != "X$build" ]
+then
+ echo 'Building on: ' $build
+ echo 'Building for:' $host
+ CROSSCOMPILING="yes"
+ case "X$SUITE" in
+ "gui")
+ echo "Warning: Cross-compiling, switching suite to cross."
+ ;;
+ "cli")
+ echo "Warning: Cross-compiling, switching suite to cross."
+ ;;
+ esac
+ SUITE="cross"
+fi
+
+case "X$ENAPACKAGING" in
+ "Xauto")
+ if [ "X$SUITE" = "Xrescue" ]
+ then
+ ENAPACKAGING="yes"
+ else
+ ENAPACKAGING="no"
+ fi
+ ;;
+ "Xyes")
+ ENAPACKAGING="yes"
+ ;;
+ *)
+ ENAPACKAGING="no"
+ ;;
+esac
+
+UNAME=`uname -s`
+if [ "X$CC" = "Xgcc" ]
+then
+ SHLIBSTYLE='gcc'
+ RPATHLINK="-Wl,-rpath-link,./"
+elif [ "X$UNAME" = "XSunOS" ]
+then
+ SHLIBSTYLE='workshop'
+fi
+
+if [ "X$CC" = "Xgcc" -a "X$WARNVAL" != "Xno" ]
+then
+ # Enable all warnings and some extra warnings
+ CWARN="-Wall"
+ WARNVAL=yes
+else
+ WARNVAL=no
+fi
+
+if [ "X$CC" = "Xgcc" -a "X$WARNMOREVAL" == "Xyes" ]
+then
+ # Extra warnings
+ CWARN="$CWARN -Wextra"
+ # Overlong strings (C89: 509 characters, C99: 4095 characters)
+ CWARN="$CWARN -Woverlength-strings"
+ # Padding bytes added to structures
+ CWARN="$CWARN -Wpadded"
+ # Redundant declarations
+ CWARN="$CWARN -Wredundant-decls"
+ # Suspicious logical operators in expressions
+ CWARN="$CWARN -Wlogical-op"
+ # Functions returning entire structures
+ CWARN="$CWARN -Waggregate-return"
+ # Prototypes required before function use
+ CWARN="$CWARN -Wstrict-prototypes"
+ # Old style function definitions
+ CWARN="$CWARN -old-style-definition"
+ # Prototypes missing for global functions (must be in a header)
+ CWARN="$CWARN -Wmissing-prototypes"
+ # Global function defined without a previous prototype
+ CWARN="$CWARN -Wmissing-declarations"
+ # "exern" definition in a function
+ CWARN="$CWARN -Wnested-externs"
+ # Unreachable code in a program
+ CWARN="$CWARN -Wunreachable-code"
+ # Failed to inline a function
+ CWARN="$CWARN -Winline"
+ # Invalid PCH file found
+ CWARN="$CWARN -Winvalid-pch"
+ # Variable length array
+ CWARN="$CWARN -Wvla"
+ # Using signed pointers
+ CWARN="$CWARN -Wpointer-sign"
+ # The stack protector can not handle some function
+ CWARN="$CWARN -Wstack-protector"
+ WARNMOREVAL="yes"
+else
+ WARNMOREVAL="no"
+fi
+
+case "X$ENASHARED" in
+ "Xauto")
+ if [ "X$SHLIBSTYLE" = "Xgcc" -o "X$SHLIBSTYLE" = "Xworkshop" ]
+ then
+ ENASHARED='yes'
+ else
+ ENASHARED='no'
+ fi
+ ;;
+ "Xyes")
+ if [ "X$SHLIBSTYLE" = "Xgcc" -o "X$SHLIBSTYLE" = "Xworkshop" ]
+ then
+ ENASHARED='yes'
+ else
+ ENASHARED='no'
+ as_fn_error $? "Can not build shared libraries!" "$LINENO" 5
+ exit 1
+ fi
+ ;;
+ *)
+ ENASHARED='no'
+ ;;
+esac
+
+if [ "X$ENASTATIC" = "Xauto" ]
+then
+ case "X$ENASHARED" in
+ "Xyes")
+ ENASTATIC='no'
+ ;;
+ "Xno")
+ ENASTATIC='yes'
+ ;;
+ esac
+fi
+if [ "X$ENASTATIC" != "Xyes" -a "X$ENASTATIC" != "Xno" ]
+then
+ ENASTATIC='no'
+fi
+
+WXCPPFLAGS=`wx-config --cppflags`
+WXCXXFLAGS=`wx-config --cxxflags`
+WXVERSION=`wx-config --version`
+WXCFLAGS=`wx-config --cflags`
+WXLDFLAGS=`wx-config --libs`
+case "X$SUITE" in
+ "Xauto")
+ SUITE='gui'
+ if [ "X$WXCPPFLAGS" = "X" ]
+ then
+ SUITE="cli"
+ fi
+ if [ "X$WXCXXFLAGS" = "X" ]
+ then
+ SUITE="cli"
+ fi
+ if [ "X$WXCFLAGS" = "X" ]
+ then
+ SUITE="cli"
+ fi
+ if [ "X$WXLDFLAGS" = "X" ]
+ then
+ SUITE="cli"
+ fi
+ ;;
+ "Xgui")
+ if [ "X$WXCPPFLAGS" = "X" ]
+ then
+ SUITE="cli"
+ fi
+ if [ "X$WXCXXFLAGS" = "X" ]
+ then
+ SUITE="cli"
+ fi
+ if [ "X$WXCFLAGS" = "X" ]
+ then
+ SUITE="cli"
+ fi
+ if [ "X$WXLDFLAGS" = "X" ]
+ then
+ SUITE="cli"
+ fi
+ if [ "X$SUITE" != "Xgui" ]
+ then
+ as_fn_error $? "Can not build GUI applications, wxWidgets not found!" "$LINENO" 5
+ exit 1
+ fi
+ ;;
+ "Xcli")
+ SUITE='cli'
+ ;;
+ "Xrescue")
+ SUITE='rescue'
+ ;;
+ "Xcross")
+ SUITE='cross'
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unknown suite type $SUITE changed to cli." >&5
+$as_echo "$as_me: WARNING: Unknown suite type $SUITE changed to cli." >&2;}
+ SUITE='cli'
+ ;;
+esac
+
+if [ "X$RANLIB" = "X:" ]
+then
+ RANLIB="@echo No need to run ranlib"
+fi
+# Extract the first word of "wget", so it can be a program name with args.
+set dummy wget; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_WGET+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$WGET"; then
+ ac_cv_prog_WGET="$WGET" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_WGET="wget"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+WGET=$ac_cv_prog_WGET
+if test -n "$WGET"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WGET" >&5
+$as_echo "$WGET" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of "curl", so it can be a program name with args.
+set dummy curl; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CURL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CURL"; then
+ ac_cv_prog_CURL="$CURL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CURL="curl"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CURL=$ac_cv_prog_CURL
+if test -n "$CURL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CURL" >&5
+$as_echo "$CURL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+if [ "X$SUITE" = "Xrescue" ]
+then
+ PROGRAMS='$(PROG_RES)'
+ LIBS_STATIC='$(LIB_ST_RES)'
+ LIBS_SHARED='$(LIB_SH_RES)'
+ RES_INSTALL='i-r-res'
+ INSTALLMANPAGES='install-rescue-man'
+ case "$ENASHARED/$ENASTATIC" in
+ "yes/yes")
+ LIBRARIES='$(LIB_SH_RES) $(LIB_ST_RES)'
+ ;;
+ "yes/no")
+ LIBRARIES='$(LIB_SH_RES)'
+ ;;
+ "no/yes")
+ LIBRARIES='$(LIB_ST_RES)'
+ ;;
+ esac
+ case "X$ENAPACKAGING" in
+ "Xyes")
+ LIBS_INSTALL='i-l-sh'
+ ;;
+ esac
+ LIBRARIES=''
+elif [ "X$SUITE" = "Xgui" ]
+then
+ PROGRAMS='$(PROG_GUI)'
+ LIBS_STATIC='$(LIB_ST_GUI)'
+ LIBS_SHARED='$(LIB_SH_GUI)'
+ RES_INSTALL='i-r-gui'
+ case "$ENASHARED/$ENASTATIC" in
+ "yes/yes")
+ LIBRARIES='$(LIB_SH_GUI) $(LIB_ST_GUI)'
+ LIBS_INSTALL='i-l-sh i-l-st i-incl'
+ ;;
+ "yes/no")
+ LIBRARIES='$(LIB_SH_GUI)'
+ LIBS_INSTALL='i-l-sh i-incl'
+ ;;
+ "no/yes")
+ LIBRARIES='$(LIB_ST_GUI)'
+ LIBS_INSTALL='i-l-st i-incl'
+ ;;
+ esac
+elif [ "X$SUITE" = "Xcross" ]
+then
+ PROGRAMS='$(PROG_CROSS)'
+ LIBS_STATIC='$(LIB_ST_CLI)'
+ LIBS_SHARED='$(LIB_SH_CLI)'
+ RES_INSTALL='i-r-cli'
+ case "$ENASHARED/$ENASTATIC" in
+ "yes/yes")
+ LIBRARIES='$(LIB_SH_CLI) $(LIB_ST_CLI)'
+ LIBS_INSTALL='i-l-sh i-l-st i-incl'
+ ;;
+ "yes/no")
+ LIBRARIES='$(LIB_SH_CLI)'
+ LIBS_INSTALL='i-l-sh i-incl'
+ ;;
+ "no/yes")
+ LIBRARIES='$(LIB_ST_CLI)'
+ LIBS_INSTALL='i-l-st i-incl'
+ ;;
+ esac
+ LIBRARIES='$(LIB_ST_CLI)'
+ LIBS_INSTALL='i-l-st i-incl'
+ ENASHARED='no'
+ ENASTATIC='yes'
+ case "X$host" in
+ "Xx86_64-w64-mingw32")
+ ONWINDOWS="yes"
+ WINUNICODE="-D_UNICODE=1 -DUNICODE=1"
+ $as_echo "@%:@define HAVE_BACKSLASH_AS_SEP 1" >>confdefs.h
+
+ $as_echo "@%:@define HAVE_LINE_END_CR_NL 1" >>confdefs.h
+
+ $as_echo "@%:@define HAVE_CASE_INSENSITIVE_PATHNAMES 1" >>confdefs.h
+
+ ;;
+ esac
+else
+ PROGRAMS='$(PROG_CLI)'
+ LIBS_STATIC='$(LIB_ST_CLI)'
+ LIBS_SHARED='$(LIB_SH_CLI)'
+ RES_INSTALL='i-r-cli'
+ case "$ENASHARED/$ENASTATIC" in
+ "yes/yes")
+ LIBRARIES='$(LIB_SH_CLI) $(LIB_ST_CLI)'
+ LIBS_INSTALL='i-l-sh i-l-st i-incl'
+ ;;
+ "yes/no")
+ LIBRARIES='$(LIB_SH_CLI)'
+ LIBS_INSTALL='i-l-sh i-incl'
+ ;;
+ "no/yes")
+ LIBRARIES='$(LIB_ST_CLI)'
+ LIBS_INSTALL='i-l-st i-incl'
+ ;;
+ esac
+fi
+
+if [ "X$ENASHARED" = "Xno" ]
+then
+ ENAPACKAGING="no"
+fi
+
+APPLIBF="libdk4app.so libdk4c.so"
+if [ "X$CROSSCOMPILING" = "Xyes" ]
+then
+ APPLIBF="$APPLIBF libdk4ma.so libdk4maiodd.so libdk4maiowd.so libdk4maio8d.so"
+else
+ APPLIBF="$APPLIBF libdk4ma.so libdk4maiodd.so libdk4maio8d.so"
+fi
+APPLIBF="$APPLIBF libdk4base.so"
+
+APPLIBS="-ldk4app -ldk4c"
+if [ "X$CROSSCOMPILING" = "Xyes" ]
+then
+ APPLIBS="$APPLIBS -ldk4ma -ldk4maiodd -ldk4maiowd -ldk4maio8d"
+else
+ APPLIBS="$APPLIBS -ldk4ma -ldk4maiodd -ldk4maio8d"
+fi
+APPLIBS="$APPLIBS -ldk4base"
+
+DKCTLIBF='libdk3.a'
+DKCTLIBS='-ldk3 $(CLILIB) $(BZLIB) $(ZLIB)'
+ADDCTRLDLIBF='libdk3.a'
+ADDCTRLDLIBS='-ldk3 $(CLILIB) $(BZLIB) $(ZLIB)'
+DKDBTLIBF='libdk3.a'
+DKDBTLIBS='-ldk3 $(CLILIB) $(BZLIB) $(ZLIB)'
+ITADMINLIBF='libdk3.a'
+ITADMINLIBS='-ldk3 -lmysqlclient $(CLILIB) $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) $(RTLIB)'
+BMPPLIBF='libdk3.a'
+BMPPLIBS='-ldk3 $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB) -lm'
+FIG2LATLIBF='libdk3.a'
+FIG2LATLIBS='-ldk3 $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB) -lm'
+HTMLBOOKLIBF='libdk3.a'
+HTMLBOOKLIBS='-ldk3 $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+DK3INFOLIBF='libdk3.a'
+DK3INFOLIBS='-ldk3 $(CLILIB) $(BZLIB) $(ZLIB)'
+PLPDFTEXLIBF='libdk3.a'
+PLPDFTEXLIBS='-ldk3 $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB) -lm'
+DKWXWIZLIBF='libdk3.a'
+DKWXWIZLIBS='-ldk3 $(CLILIB) $(BZLIB) $(ZLIB)'
+WXDKCTLIBF='libdk3.a'
+WXDKCTLIBS='-ldk3 $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+WXBMPPLIBF='libdk3.a'
+WXBMPPLIBS='-ldk3 $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+WXIMGSZLIBF='libdk3.a'
+WXIMGSZLIBS='-ldk3 $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+WXDKCLOCKLIBF='libdk3.a'
+WXDKCLOCKLIBS='-ldk3 $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+WXDKHTBLIBF='libdk3.a'
+WXDKHTBLIBS='-ldk3 $(WXLDFLAGS) $(GUILIB) $(CLILIB) $(BZLIB) $(ZLIB)'
+PRINTQDILIBF='libdk3.a'
+PRINTQDILIBS='-ldk3 $(CLILIB) $(BZLIB) $(ZLIB)'
+PRINTQDALIBF='libdk3.a'
+PRINTQDALIBS='-ldk3 $(CLILIB) $(BZLIB) $(ZLIB)'
+
+DKCATLIBF="libdk4.a"
+DKCATLIBS='-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)'
+DKBLKSLIBF="libdk4.a"
+DKBLKSLIBS='-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)'
+DKSQLSPLITLIBF="libdk4.a"
+DKSQLSPLITLIBS='-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)'
+DKERADISKLIBF="libdk4.a"
+DKERADISKLIBS='-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)'
+DKLSLIBF="libdk4.a"
+DKLSLIBS='-ldk4 $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+DKSORTLIBF="libdk4.a"
+DKSORTLIBS='-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)'
+DKFICLIBF="libdk4.a"
+DKFICLIBS='-ldk4 $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+DKUIDLIBF="libdk4.a"
+DKUIDLIBS='-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)'
+DKPWGENLIBF="libdk4.a"
+DKPWGENLIBS='-ldk4 $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+DKRANDLIBF="libdk4.a"
+DKRANDLIBS='-ldk4 $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+DKT2HLIBF="libdk4.a"
+DKT2HLIBS='-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)'
+DKT2LLIBF="libdk4.a"
+DKT2LLIBS='-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)'
+DKHEXLIBF="libdk4.a"
+DKHEXLIBS='-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)'
+DKBMMLIBF="libdk4.a"
+DKBMMLIBS='-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)'
+DKPWDLIBF="libdk4.a"
+DKPWDLIBS='-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)'
+DKRECVLIBF="libdk4.a"
+DKRECVLIBS='-ldk4 $(CLILIB) $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) -lm'
+DKSENDLIBF="libdk4.a"
+DKSENDLIBS='-ldk4 $(CLILIB) $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) -lm'
+DKDBT2LIBF="libdk4.a"
+DKDBT2LIBS='-ldk4 $(DBLIBSOCK) $(CLILIB) $(BZLIB) $(ZLIB)'
+DK4INFOLIBF="libdk4.a"
+DK4INFOLIBS='-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)'
+LPRNGCLLIBF="libdk4.a"
+LPRNGCLLIBS='-ldk4 $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) -lm'
+WXDKFCSLIBF="libdk4.a"
+WXDKFCSLIBS='-ldk4 $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+WXPQDICLIBF="libdk4.a"
+WXPQDICLIBS='-ldk4 $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+PJSNMPLIBF="libdk4.a"
+PJSNMPLIBS='-ldk4 $(NETSNMP_LIBS) $(SOCKLIB) $(NSLLIB)'
+PRMONSNMPLIBF="libdk4.a"
+PRMONSNMPLIBS='-ldk4 $(NETSNMP_LIBS) $(SOCKLIB) $(NSLLIB)'
+PRINTQDLIBF="libdk4.a"
+PRINTQDLIBS='-ldk4 $(DBLIB) $(SOCKLIB) $(NSLLIB)'
+PRINTQDCLIBF="libdk4.a"
+PRINTQDCLIBS='-ldk4 $(SOCKLIB) $(NSLLIB)'
+RSHDOWNLIBF="libdk4.a"
+RSHDOWNLIBS='-ldk4 $(SOCKLIB) $(NSLLIB)'
+
+LIB_SH_RES='$(LIB_SH_RES_NO_PACKAGING)'
+LIB_SH_CLI='$(LIB_SH_CLI_NO_PACKAGING)'
+LIB_SH_GUI='$(LIB_SH_GUI_NO_PACKAGING)'
+if [ "X$ENAPACKAGING" = "Xyes" ]
+then
+LIB_SH_RES='$(LIB_SH_RES_PACKAGING)'
+LIB_SH_CLI='$(LIB_SH_CLI_PACKAGING)'
+LIB_SH_GUI='$(LIB_SH_GUI_PACKAGING)'
+fi
+
+if [ "X$CC" = "Xgcc" -a "X$UNAME" = "XLinux" ]
+then
+ USESOLINKING="yes"
+fi
+if [ "X$SHLIBSTYLE" = "Xworkshop" -o "X$FORCESOLINKING" = "Xyes" ]
+then
+ USESOLINKING="yes"
+fi
+
+
+case "X$SHLIBSTYLE" in
+ "Xgcc")
+ CFPIC='-fPIC -D_REENTRANT'
+ if [ "X$USESOLINKING" = "Xyes" ]
+ then
+ MKSOLIB='$(COMPILEC) -L. $(RPATHLINK) $(LIBRARIES) $(LDFLAGS) -shared -o $@.$(SOVERS) -Wl,-soname,$@.$(SOVERS)'
+ else
+ MKSOLIB='$(COMPILEC) $(LIBRARIES) $(LDFLAGS) -shared -o $@.$(SOVERS) -Wl,-soname,$@.$(SOVERS)'
+ fi
+ ;;
+ "Xworkshop")
+ if [ "X$ENASHARED" != "Xno" ]
+ then
+ CFPIC='-Bdynamic -dy -xcode=pic32 -D_REENTRANT'
+ else
+ CFPIC='-xcode=pic32 -D_REENTRANT'
+ fi
+ MKSOLIB='$(COMPILEC) -L. $(LIBRARIES) $(LDFLAGS) -G -h $@.$(SOVERS) -o $@.$(SOVERS)'
+ ;;
+esac
+
+if [ "X$LD_LIBRARY_PATH" != "X" -a "X$SHLIBSTYLE" = "Xworkshop" ]
+then
+ RPATH="-R${LD_LIBRARY_PATH}"
+fi
+
+ac_fn_c_check_header_mongrel "$LINENO" "errno.h" "ac_cv_header_errno_h" "$ac_includes_default"
+if test "x$ac_cv_header_errno_h" = xyes; then :
+ $as_echo "@%:@define HAVE_ERRNO_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "assert.h" "ac_cv_header_assert_h" "$ac_includes_default"
+if test "x$ac_cv_header_assert_h" = xyes; then :
+ $as_echo "@%:@define HAVE_ASSERT_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "complex.h" "ac_cv_header_complex_h" "$ac_includes_default"
+if test "x$ac_cv_header_complex_h" = xyes; then :
+ $as_echo "@%:@define HAVE_COMPLEX_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "ctype.h" "ac_cv_header_ctype_h" "$ac_includes_default"
+if test "x$ac_cv_header_ctype_h" = xyes; then :
+ $as_echo "@%:@define HAVE_CTYPE_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "fenv.h" "ac_cv_header_fenv_h" "$ac_includes_default"
+if test "x$ac_cv_header_fenv_h" = xyes; then :
+ $as_echo "@%:@define HAVE_FENV_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "float.h" "ac_cv_header_float_h" "$ac_includes_default"
+if test "x$ac_cv_header_float_h" = xyes; then :
+ $as_echo "@%:@define HAVE_FLOAT_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "inttypes.h" "ac_cv_header_inttypes_h" "$ac_includes_default"
+if test "x$ac_cv_header_inttypes_h" = xyes; then :
+ $as_echo "@%:@define HAVE_INTTYPES_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "iso646.h" "ac_cv_header_iso646_h" "$ac_includes_default"
+if test "x$ac_cv_header_iso646_h" = xyes; then :
+ $as_echo "@%:@define HAVE_ISO646_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "limits.h" "ac_cv_header_limits_h" "$ac_includes_default"
+if test "x$ac_cv_header_limits_h" = xyes; then :
+ $as_echo "@%:@define HAVE_LIMITS_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "locale.h" "ac_cv_header_locale_h" "$ac_includes_default"
+if test "x$ac_cv_header_locale_h" = xyes; then :
+ $as_echo "@%:@define HAVE_LOCALE_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "math.h" "ac_cv_header_math_h" "$ac_includes_default"
+if test "x$ac_cv_header_math_h" = xyes; then :
+ $as_echo "@%:@define HAVE_MATH_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "setjmp.h" "ac_cv_header_setjmp_h" "$ac_includes_default"
+if test "x$ac_cv_header_setjmp_h" = xyes; then :
+ $as_echo "@%:@define HAVE_SETJMP_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "signal.h" "ac_cv_header_signal_h" "$ac_includes_default"
+if test "x$ac_cv_header_signal_h" = xyes; then :
+ $as_echo "@%:@define HAVE_SIGNAL_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "stdalign.h" "ac_cv_header_stdalign_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdalign_h" = xyes; then :
+ $as_echo "@%:@define HAVE_STDALIGN_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "stdarg.h" "ac_cv_header_stdarg_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdarg_h" = xyes; then :
+ $as_echo "@%:@define HAVE_STDARG_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "stdatomic.h" "ac_cv_header_stdatomic_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdatomic_h" = xyes; then :
+ $as_echo "@%:@define HAVE_STDATOMIC_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "stdbool.h" "ac_cv_header_stdbool_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdbool_h" = xyes; then :
+ $as_echo "@%:@define HAVE_STDBOOL_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "stddef.h" "ac_cv_header_stddef_h" "$ac_includes_default"
+if test "x$ac_cv_header_stddef_h" = xyes; then :
+ $as_echo "@%:@define HAVE_STDDEF_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "stdint.h" "ac_cv_header_stdint_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdint_h" = xyes; then :
+ $as_echo "@%:@define HAVE_STDINT_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdlib_h" = xyes; then :
+ $as_echo "@%:@define HAVE_STDLIB_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "stdnoreturn.h" "ac_cv_header_stdnoreturn_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdnoreturn_h" = xyes; then :
+ $as_echo "@%:@define HAVE_STDNORETURN_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "string.h" "ac_cv_header_string_h" "$ac_includes_default"
+if test "x$ac_cv_header_string_h" = xyes; then :
+ $as_echo "@%:@define HAVE_STRING_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "tgmath.h" "ac_cv_header_tgmath_h" "$ac_includes_default"
+if test "x$ac_cv_header_tgmath_h" = xyes; then :
+ $as_echo "@%:@define HAVE_TGMATH_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "threads.h" "ac_cv_header_threads_h" "$ac_includes_default"
+if test "x$ac_cv_header_threads_h" = xyes; then :
+ $as_echo "@%:@define HAVE_THREADS_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "time.h" "ac_cv_header_time_h" "$ac_includes_default"
+if test "x$ac_cv_header_time_h" = xyes; then :
+ $as_echo "@%:@define HAVE_TIME_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "uchar.h" "ac_cv_header_uchar_h" "$ac_includes_default"
+if test "x$ac_cv_header_uchar_h" = xyes; then :
+ $as_echo "@%:@define HAVE_UCHAR_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "wchar.h" "ac_cv_header_wchar_h" "$ac_includes_default"
+if test "x$ac_cv_header_wchar_h" = xyes; then :
+ $as_echo "@%:@define HAVE_WCHAR_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "wctype.h" "ac_cv_header_wctype_h" "$ac_includes_default"
+if test "x$ac_cv_header_wctype_h" = xyes; then :
+ $as_echo "@%:@define HAVE_WCTYPE_H 1" >>confdefs.h
+
+fi
+
+
+
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/types.h" "ac_cv_header_sys_types_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_types_h" = xyes; then :
+ $as_echo "@%:@define HAVE_SYS_TYPES_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/param.h" "ac_cv_header_sys_param_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_param_h" = xyes; then :
+ $as_echo "@%:@define HAVE_SYS_PARAM_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/stat.h" "ac_cv_header_sys_stat_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_stat_h" = xyes; then :
+ $as_echo "@%:@define HAVE_SYS_STAT_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/time.h" "ac_cv_header_sys_time_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_time_h" = xyes; then :
+ $as_echo "@%:@define HAVE_SYS_TIME_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/socket.h" "ac_cv_header_sys_socket_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_socket_h" = xyes; then :
+ $as_echo "@%:@define HAVE_SYS_SOCKET_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/select.h" "ac_cv_header_sys_select_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_select_h" = xyes; then :
+ $as_echo "@%:@define HAVE_SYS_SELECT_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/un.h" "ac_cv_header_sys_un_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_un_h" = xyes; then :
+ $as_echo "@%:@define HAVE_SYS_UN_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "netinet/in.h" "ac_cv_header_netinet_in_h" "$ac_includes_default"
+if test "x$ac_cv_header_netinet_in_h" = xyes; then :
+ $as_echo "@%:@define HAVE_NETINET_IN_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "netinet/in6.h" "ac_cv_header_netinet_in6_h" "$ac_includes_default"
+if test "x$ac_cv_header_netinet_in6_h" = xyes; then :
+ $as_echo "@%:@define HAVE_NETINET_IN6_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "netdb.h" "ac_cv_header_netdb_h" "$ac_includes_default"
+if test "x$ac_cv_header_netdb_h" = xyes; then :
+ $as_echo "@%:@define HAVE_NETDB_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "arpa/inet.h" "ac_cv_header_arpa_inet_h" "$ac_includes_default"
+if test "x$ac_cv_header_arpa_inet_h" = xyes; then :
+ $as_echo "@%:@define HAVE_ARPA_INET_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "winsock2.h" "ac_cv_header_winsock2_h" "$ac_includes_default"
+if test "x$ac_cv_header_winsock2_h" = xyes; then :
+ $as_echo "@%:@define HAVE_WINSOCK2_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "ws2tcpip.h" "ac_cv_header_ws2tcpip_h" "$ac_includes_default"
+if test "x$ac_cv_header_ws2tcpip_h" = xyes; then :
+ $as_echo "@%:@define HAVE_WS2TCPIP_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "windows.h" "ac_cv_header_windows_h" "$ac_includes_default"
+if test "x$ac_cv_header_windows_h" = xyes; then :
+ $as_echo "@%:@define HAVE_WINDOWS_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "unistd.h" "ac_cv_header_unistd_h" "$ac_includes_default"
+if test "x$ac_cv_header_unistd_h" = xyes; then :
+ $as_echo "@%:@define HAVE_UNISTD_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "process.h" "ac_cv_header_process_h" "$ac_includes_default"
+if test "x$ac_cv_header_process_h" = xyes; then :
+ $as_echo "@%:@define HAVE_PROCESS_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "fcntl.h" "ac_cv_header_fcntl_h" "$ac_includes_default"
+if test "x$ac_cv_header_fcntl_h" = xyes; then :
+ $as_echo "@%:@define HAVE_FCNTL_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "share.h" "ac_cv_header_share_h" "$ac_includes_default"
+if test "x$ac_cv_header_share_h" = xyes; then :
+ $as_echo "@%:@define HAVE_SHARE_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "pwd.h" "ac_cv_header_pwd_h" "$ac_includes_default"
+if test "x$ac_cv_header_pwd_h" = xyes; then :
+ $as_echo "@%:@define HAVE_PWD_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "strings.h" "ac_cv_header_strings_h" "$ac_includes_default"
+if test "x$ac_cv_header_strings_h" = xyes; then :
+ $as_echo "@%:@define HAVE_STRINGS_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "io.h" "ac_cv_header_io_h" "$ac_includes_default"
+if test "x$ac_cv_header_io_h" = xyes; then :
+ $as_echo "@%:@define HAVE_IO_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "bios.h" "ac_cv_header_bios_h" "$ac_includes_default"
+if test "x$ac_cv_header_bios_h" = xyes; then :
+ $as_echo "@%:@define HAVE_BIOS_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "dos.h" "ac_cv_header_dos_h" "$ac_includes_default"
+if test "x$ac_cv_header_dos_h" = xyes; then :
+ $as_echo "@%:@define HAVE_DOS_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "alloc.h" "ac_cv_header_alloc_h" "$ac_includes_default"
+if test "x$ac_cv_header_alloc_h" = xyes; then :
+ $as_echo "@%:@define HAVE_ALLOC_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "malloc.h" "ac_cv_header_malloc_h" "$ac_includes_default"
+if test "x$ac_cv_header_malloc_h" = xyes; then :
+ $as_echo "@%:@define HAVE_MALLOC_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "dirent.h" "ac_cv_header_dirent_h" "$ac_includes_default"
+if test "x$ac_cv_header_dirent_h" = xyes; then :
+ $as_echo "@%:@define HAVE_DIRENT_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "direct.h" "ac_cv_header_direct_h" "$ac_includes_default"
+if test "x$ac_cv_header_direct_h" = xyes; then :
+ $as_echo "@%:@define HAVE_DIRECT_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_zlib_h" = xyes; then :
+ ZLIB="-lz";$as_echo "@%:@define HAVE_ZLIB_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "bzlib.h" "ac_cv_header_bzlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_bzlib_h" = xyes; then :
+ BZLIB="-lbz2";$as_echo "@%:@define HAVE_BZLIB_H 1" >>confdefs.h
+
+fi
+
+
+
+CRYPTO=""
+PROGSOPENSSL=""
+ac_fn_c_check_header_mongrel "$LINENO" "openssl/rand.h" "ac_cv_header_openssl_rand_h" "$ac_includes_default"
+if test "x$ac_cv_header_openssl_rand_h" = xyes; then :
+
+CRYPTO="-lcrypto"
+PROGSOPENSSL='dk-fic$(EXEEXT) dk-pwgen$(EXEEXT) dk-rand$(EXEEXT)'
+$as_echo "@%:@define HAVE_OPENSSL_RAND_H 1" >>confdefs.h
+
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "openssl/md5.h" "ac_cv_header_openssl_md5_h" "$ac_includes_default"
+if test "x$ac_cv_header_openssl_md5_h" = xyes; then :
+ $as_echo "@%:@define HAVE_OPENSSL_MD5_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "openssl/sha.h" "ac_cv_header_openssl_sha_h" "$ac_includes_default"
+if test "x$ac_cv_header_openssl_sha_h" = xyes; then :
+ $as_echo "@%:@define HAVE_OPENSSL_SHA_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "openssl/ripemd.h" "ac_cv_header_openssl_ripemd_h" "$ac_includes_default"
+if test "x$ac_cv_header_openssl_ripemd_h" = xyes; then :
+ $as_echo "@%:@define HAVE_OPENSSL_RIPEMD_H 1" >>confdefs.h
+
+fi
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5
+$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; }
+if ${ac_cv_header_time+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+
+int
+main ()
+{
+if ((struct tm *) 0)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_time=yes
+else
+ ac_cv_header_time=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5
+$as_echo "$ac_cv_header_time" >&6; }
+if test $ac_cv_header_time = yes; then
+
+$as_echo "@%:@define TIME_WITH_SYS_TIME 1" >>confdefs.h
+
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking longlong" >&5
+$as_echo_n "checking longlong... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+
+int
+main ()
+{
+
+ long long l;
+ l = (long long)0L;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "@%:@define HAVE_LONG_LONG 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking longdouble" >&5
+$as_echo_n "checking longdouble... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <math.h>
+
+int
+main ()
+{
+
+ long double l;
+ l = (long double)0.0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "@%:@define HAVE_LONG_DOUBLE 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+DOINTMAXSIZECHECK="no"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking intmax_t" >&5
+$as_echo_n "checking intmax_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#if HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+int
+main ()
+{
+
+intmax_t im;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ DOINTMAXSIZECHECK="yes";{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "@%:@define HAVE_INTMAX_T 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking volatile" >&5
+$as_echo_n "checking volatile... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+volatile int i = 0;
+
+int
+main ()
+{
+
+i = 1;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "@%:@define HAVE_VOLATILE 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking sig_atomic_t" >&5
+$as_echo_n "checking sig_atomic_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <sys/types.h>
+#include <signal.h>
+
+int
+main ()
+{
+
+sig_atomic_t sat;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "@%:@define HAVE_SIG_ATOMIC_T 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of short" >&5
+$as_echo_n "checking size of short... " >&6; }
+if ${ac_cv_sizeof_short+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (short))" "ac_cv_sizeof_short" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_short" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (short)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_short=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_short" >&5
+$as_echo "$ac_cv_sizeof_short" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+@%:@define SIZEOF_SHORT $ac_cv_sizeof_short
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5
+$as_echo_n "checking size of int... " >&6; }
+if ${ac_cv_sizeof_int+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_int" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (int)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_int=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5
+$as_echo "$ac_cv_sizeof_int" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+@%:@define SIZEOF_INT $ac_cv_sizeof_int
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of size_t" >&5
+$as_echo_n "checking size of size_t... " >&6; }
+if ${ac_cv_sizeof_size_t+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (size_t))" "ac_cv_sizeof_size_t" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_size_t" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (size_t)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_size_t=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_size_t" >&5
+$as_echo "$ac_cv_sizeof_size_t" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+@%:@define SIZEOF_SIZE_T $ac_cv_sizeof_size_t
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5
+$as_echo_n "checking size of long... " >&6; }
+if ${ac_cv_sizeof_long+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_long" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (long)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_long=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5
+$as_echo "$ac_cv_sizeof_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+@%:@define SIZEOF_LONG $ac_cv_sizeof_long
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long long" >&5
+$as_echo_n "checking size of long long... " >&6; }
+if ${ac_cv_sizeof_long_long+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long))" "ac_cv_sizeof_long_long" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_long_long" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (long long)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_long_long=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long" >&5
+$as_echo "$ac_cv_sizeof_long_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+@%:@define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long
+_ACEOF
+
+
+if [ "X$DOINTMAXSIZECHECK" = "Xyes" ]
+then
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of intmax_t" >&5
+$as_echo_n "checking size of intmax_t... " >&6; }
+if ${ac_cv_sizeof_intmax_t+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (intmax_t))" "ac_cv_sizeof_intmax_t" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_intmax_t" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (intmax_t)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_intmax_t=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_intmax_t" >&5
+$as_echo "$ac_cv_sizeof_intmax_t" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+@%:@define SIZEOF_INTMAX_T $ac_cv_sizeof_intmax_t
+_ACEOF
+
+
+fi
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of double" >&5
+$as_echo_n "checking size of double... " >&6; }
+if ${ac_cv_sizeof_double+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (double))" "ac_cv_sizeof_double" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_double" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (double)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_double=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_double" >&5
+$as_echo "$ac_cv_sizeof_double" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+@%:@define SIZEOF_DOUBLE $ac_cv_sizeof_double
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long double" >&5
+$as_echo_n "checking size of long double... " >&6; }
+if ${ac_cv_sizeof_long_double+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long double))" "ac_cv_sizeof_long_double" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_long_double" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (long double)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_long_double=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_double" >&5
+$as_echo "$ac_cv_sizeof_long_double" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+@%:@define SIZEOF_LONG_DOUBLE $ac_cv_sizeof_long_double
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of wchar_t" >&5
+$as_echo_n "checking size of wchar_t... " >&6; }
+if ${ac_cv_sizeof_wchar_t+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (wchar_t))" "ac_cv_sizeof_wchar_t" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_wchar_t" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (wchar_t)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_wchar_t=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_wchar_t" >&5
+$as_echo "$ac_cv_sizeof_wchar_t" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+@%:@define SIZEOF_WCHAR_T $ac_cv_sizeof_wchar_t
+_ACEOF
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking _LARGEFILE64_SOURCE" >&5
+$as_echo_n "checking _LARGEFILE64_SOURCE... " >&6; }
+FS64=''
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#define _LARGEFILE64_SOURCE 1
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+struct stat64 st;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ FS64='-D_LARGEFILE64_SOURCE=1'
+$as_echo "@%:@define HAVE_LARGEFILE64_SOURCE 1" >>confdefs.h
+
+$as_echo "@%:@define HAVE_TYPE_STAT64 1" >>confdefs.h
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+for ac_func in memset bzero memcpy bcopy memcmp bcmp
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in malloc calloc free
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in strcpy_s strcat_s
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in strcasecmp stricmp _stricmp
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in wcslen wcscpy_s wcscpy wcscat_s wcscat wcschr wcsrchr
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in wcscmp _wcscmp wcscasecmp _wcscasecmp wcsicmp _wcsicmp
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in getpid readlink getexecname lstat stat64 lstat64 localtime_r
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in geteuid fopen64 fopen_s _wfopen _wfopen64 _wfopen_s
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in fputws fputwc
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in setbuffer setbuf setvbuf
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in fileno _fileno setmode _setmode isatty _isatty
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in strtod _strtod wcstod _wcstod
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in _snprintf_s _snprintf snprintf _snwprintf_s _snwprintf snwprintf
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in swprintf
+do :
+ ac_fn_c_check_func "$LINENO" "swprintf" "ac_cv_func_swprintf"
+if test "x$ac_cv_func_swprintf" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define HAVE_SWPRINTF 1
+_ACEOF
+
+fi
+done
+
+for ac_func in unlink _unlink wunlink _wunlink
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in rmdir _rmdir wrmdir _wrmdir
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in mkdir _mkdir wmkdir _wmkdir
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in strerror strerror_r
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in sigaction sigset signal sigprocmask sigemptyset
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in setpwent getpwent endpwent
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in getenv getenv_s setlocale select
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in getcwd _getcwd _wgetcwd
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SHA224_Init in -lcrypto" >&5
+$as_echo_n "checking for SHA224_Init in -lcrypto... " >&6; }
+if ${ac_cv_lib_crypto_SHA224_Init+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypto $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char SHA224_Init ();
+int
+main ()
+{
+return SHA224_Init ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_crypto_SHA224_Init=yes
+else
+ ac_cv_lib_crypto_SHA224_Init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_SHA224_Init" >&5
+$as_echo "$ac_cv_lib_crypto_SHA224_Init" >&6; }
+if test "x$ac_cv_lib_crypto_SHA224_Init" = xyes; then :
+ $as_echo "@%:@define HAVE_SHA224 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SHA256_Init in -lcrypto" >&5
+$as_echo_n "checking for SHA256_Init in -lcrypto... " >&6; }
+if ${ac_cv_lib_crypto_SHA256_Init+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypto $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char SHA256_Init ();
+int
+main ()
+{
+return SHA256_Init ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_crypto_SHA256_Init=yes
+else
+ ac_cv_lib_crypto_SHA256_Init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_SHA256_Init" >&5
+$as_echo "$ac_cv_lib_crypto_SHA256_Init" >&6; }
+if test "x$ac_cv_lib_crypto_SHA256_Init" = xyes; then :
+ $as_echo "@%:@define HAVE_SHA256 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SHA384_Init in -lcrypto" >&5
+$as_echo_n "checking for SHA384_Init in -lcrypto... " >&6; }
+if ${ac_cv_lib_crypto_SHA384_Init+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypto $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char SHA384_Init ();
+int
+main ()
+{
+return SHA384_Init ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_crypto_SHA384_Init=yes
+else
+ ac_cv_lib_crypto_SHA384_Init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_SHA384_Init" >&5
+$as_echo "$ac_cv_lib_crypto_SHA384_Init" >&6; }
+if test "x$ac_cv_lib_crypto_SHA384_Init" = xyes; then :
+ $as_echo "@%:@define HAVE_SHA384 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SHA512_Init in -lcrypto" >&5
+$as_echo_n "checking for SHA512_Init in -lcrypto... " >&6; }
+if ${ac_cv_lib_crypto_SHA512_Init+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypto $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char SHA512_Init ();
+int
+main ()
+{
+return SHA512_Init ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_crypto_SHA512_Init=yes
+else
+ ac_cv_lib_crypto_SHA512_Init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_SHA512_Init" >&5
+$as_echo "$ac_cv_lib_crypto_SHA512_Init" >&6; }
+if test "x$ac_cv_lib_crypto_SHA512_Init" = xyes; then :
+ $as_echo "@%:@define HAVE_SHA512 1" >>confdefs.h
+
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking RAND_egd" >&5
+$as_echo_n "checking RAND_egd... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <openssl/rand.h>
+
+int
+main ()
+{
+
+int i;
+i = RAND_egd("/dev/egd");
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "@%:@define HAVE_RAND_EGD 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_gettime in -lrt" >&5
+$as_echo_n "checking for clock_gettime in -lrt... " >&6; }
+if ${ac_cv_lib_rt_clock_gettime+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lrt $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char clock_gettime ();
+int
+main ()
+{
+return clock_gettime ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_rt_clock_gettime=yes
+else
+ ac_cv_lib_rt_clock_gettime=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_clock_gettime" >&5
+$as_echo "$ac_cv_lib_rt_clock_gettime" >&6; }
+if test "x$ac_cv_lib_rt_clock_gettime" = xyes; then :
+ RTLIB="-lrt"
+fi
+
+
+SOCKLIB=''
+NSLLIB=''
+
+for ac_func in socket
+do :
+ ac_fn_c_check_func "$LINENO" "socket" "ac_cv_func_socket"
+if test "x$ac_cv_func_socket" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define HAVE_SOCKET 1
+_ACEOF
+
+NET_PROG_RES='$(NET_PROG_RES)'
+NET_PROG_CLI='$(NET_PROG_CLI)'
+$as_echo "@%:@define HAVE_SOCKET 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lxnet" >&5
+$as_echo_n "checking for socket in -lxnet... " >&6; }
+if ${ac_cv_lib_xnet_socket+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lxnet $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char socket ();
+int
+main ()
+{
+return socket ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_xnet_socket=yes
+else
+ ac_cv_lib_xnet_socket=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xnet_socket" >&5
+$as_echo "$ac_cv_lib_xnet_socket" >&6; }
+if test "x$ac_cv_lib_xnet_socket" = xyes; then :
+
+NET_PROG_RES='$(NET_PROG_RES)'
+NET_PROG_CLI='$(NET_PROG_CLI)'
+$as_echo "@%:@define HAVE_SOCKET 1" >>confdefs.h
+
+SOCKLIB='-lxnet'
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lsocket" >&5
+$as_echo_n "checking for socket in -lsocket... " >&6; }
+if ${ac_cv_lib_socket_socket+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char socket ();
+int
+main ()
+{
+return socket ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_socket_socket=yes
+else
+ ac_cv_lib_socket_socket=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_socket" >&5
+$as_echo "$ac_cv_lib_socket_socket" >&6; }
+if test "x$ac_cv_lib_socket_socket" = xyes; then :
+
+NET_PROG_RES='$(NET_PROG_RES)'
+NET_PROG_CLI='$(NET_PROG_CLI)'
+$as_echo "@%:@define HAVE_SOCKET 1" >>confdefs.h
+
+SOCKLIB='-lsocket'
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lws2_32" >&5
+$as_echo_n "checking for socket in -lws2_32... " >&6; }
+if ${ac_cv_lib_ws2_32_socket+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lws2_32 $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char socket ();
+int
+main ()
+{
+return socket ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_ws2_32_socket=yes
+else
+ ac_cv_lib_ws2_32_socket=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ws2_32_socket" >&5
+$as_echo "$ac_cv_lib_ws2_32_socket" >&6; }
+if test "x$ac_cv_lib_ws2_32_socket" = xyes; then :
+
+NET_PROG_RES='$(NET_PROG_RES)'
+NET_PROG_CLI='$(NET_PROG_CLI)'
+$as_echo "@%:@define HAVE_SOCKET 1" >>confdefs.h
+
+SOCKLIB='-lws2_32'
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+done
+
+
+for ac_func in setsockopt
+do :
+ ac_fn_c_check_func "$LINENO" "setsockopt" "ac_cv_func_setsockopt"
+if test "x$ac_cv_func_setsockopt" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define HAVE_SETSOCKOPT 1
+_ACEOF
+
+$as_echo "@%:@define HAVE_SETSOCKOPT 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for setsockopt in -lxnet" >&5
+$as_echo_n "checking for setsockopt in -lxnet... " >&6; }
+if ${ac_cv_lib_xnet_setsockopt+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lxnet $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char setsockopt ();
+int
+main ()
+{
+return setsockopt ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_xnet_setsockopt=yes
+else
+ ac_cv_lib_xnet_setsockopt=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xnet_setsockopt" >&5
+$as_echo "$ac_cv_lib_xnet_setsockopt" >&6; }
+if test "x$ac_cv_lib_xnet_setsockopt" = xyes; then :
+
+$as_echo "@%:@define HAVE_SETSOCKOPT 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for setsockopt in -lsocket" >&5
+$as_echo_n "checking for setsockopt in -lsocket... " >&6; }
+if ${ac_cv_lib_socket_setsockopt+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char setsockopt ();
+int
+main ()
+{
+return setsockopt ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_socket_setsockopt=yes
+else
+ ac_cv_lib_socket_setsockopt=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_setsockopt" >&5
+$as_echo "$ac_cv_lib_socket_setsockopt" >&6; }
+if test "x$ac_cv_lib_socket_setsockopt" = xyes; then :
+
+$as_echo "@%:@define HAVE_SETSOCKOPT 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for setsockopt in -lws2_32" >&5
+$as_echo_n "checking for setsockopt in -lws2_32... " >&6; }
+if ${ac_cv_lib_ws2_32_setsockopt+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lws2_32 $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char setsockopt ();
+int
+main ()
+{
+return setsockopt ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_ws2_32_setsockopt=yes
+else
+ ac_cv_lib_ws2_32_setsockopt=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ws2_32_setsockopt" >&5
+$as_echo "$ac_cv_lib_ws2_32_setsockopt" >&6; }
+if test "x$ac_cv_lib_ws2_32_setsockopt" = xyes; then :
+
+$as_echo "@%:@define HAVE_SETSOCKOPT 1" >>confdefs.h
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+done
+
+
+for ac_func in getaddrinfo
+do :
+ ac_fn_c_check_func "$LINENO" "getaddrinfo" "ac_cv_func_getaddrinfo"
+if test "x$ac_cv_func_getaddrinfo" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define HAVE_GETADDRINFO 1
+_ACEOF
+
+$as_echo "@%:@define HAVE_GETADDRINFO 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getaddrinfo in -lxnet" >&5
+$as_echo_n "checking for getaddrinfo in -lxnet... " >&6; }
+if ${ac_cv_lib_xnet_getaddrinfo+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lxnet $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getaddrinfo ();
+int
+main ()
+{
+return getaddrinfo ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_xnet_getaddrinfo=yes
+else
+ ac_cv_lib_xnet_getaddrinfo=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xnet_getaddrinfo" >&5
+$as_echo "$ac_cv_lib_xnet_getaddrinfo" >&6; }
+if test "x$ac_cv_lib_xnet_getaddrinfo" = xyes; then :
+
+NSLLIB='-lxnet'
+$as_echo "@%:@define HAVE_GETADDRINFO 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getaddrinfo in -lnsl" >&5
+$as_echo_n "checking for getaddrinfo in -lnsl... " >&6; }
+if ${ac_cv_lib_nsl_getaddrinfo+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getaddrinfo ();
+int
+main ()
+{
+return getaddrinfo ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_nsl_getaddrinfo=yes
+else
+ ac_cv_lib_nsl_getaddrinfo=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_getaddrinfo" >&5
+$as_echo "$ac_cv_lib_nsl_getaddrinfo" >&6; }
+if test "x$ac_cv_lib_nsl_getaddrinfo" = xyes; then :
+
+NSLLIB='-lnsl'
+$as_echo "@%:@define HAVE_GETADDRINFO 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getaddrinfo in -lsocket" >&5
+$as_echo_n "checking for getaddrinfo in -lsocket... " >&6; }
+if ${ac_cv_lib_socket_getaddrinfo+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getaddrinfo ();
+int
+main ()
+{
+return getaddrinfo ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_socket_getaddrinfo=yes
+else
+ ac_cv_lib_socket_getaddrinfo=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_getaddrinfo" >&5
+$as_echo "$ac_cv_lib_socket_getaddrinfo" >&6; }
+if test "x$ac_cv_lib_socket_getaddrinfo" = xyes; then :
+
+NSLLIB='-lsocket'
+$as_echo "@%:@define HAVE_GETADDRINFO 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getaddrinfo in -lws2_32" >&5
+$as_echo_n "checking for getaddrinfo in -lws2_32... " >&6; }
+if ${ac_cv_lib_ws2_32_getaddrinfo+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lws2_32 $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getaddrinfo ();
+int
+main ()
+{
+return getaddrinfo ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_ws2_32_getaddrinfo=yes
+else
+ ac_cv_lib_ws2_32_getaddrinfo=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ws2_32_getaddrinfo" >&5
+$as_echo "$ac_cv_lib_ws2_32_getaddrinfo" >&6; }
+if test "x$ac_cv_lib_ws2_32_getaddrinfo" = xyes; then :
+
+$as_echo "@%:@define HAVE_GETADDRINFO 1" >>confdefs.h
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+done
+
+
+for ac_func in getnameinfo
+do :
+ ac_fn_c_check_func "$LINENO" "getnameinfo" "ac_cv_func_getnameinfo"
+if test "x$ac_cv_func_getnameinfo" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define HAVE_GETNAMEINFO 1
+_ACEOF
+
+$as_echo "@%:@define HAVE_GETNAMEINFO 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getnameinfo in -lxnet" >&5
+$as_echo_n "checking for getnameinfo in -lxnet... " >&6; }
+if ${ac_cv_lib_xnet_getnameinfo+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lxnet $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getnameinfo ();
+int
+main ()
+{
+return getnameinfo ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_xnet_getnameinfo=yes
+else
+ ac_cv_lib_xnet_getnameinfo=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xnet_getnameinfo" >&5
+$as_echo "$ac_cv_lib_xnet_getnameinfo" >&6; }
+if test "x$ac_cv_lib_xnet_getnameinfo" = xyes; then :
+
+$as_echo "@%:@define HAVE_GETNAMEINFO 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getnameinfo in -lnsl" >&5
+$as_echo_n "checking for getnameinfo in -lnsl... " >&6; }
+if ${ac_cv_lib_nsl_getnameinfo+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getnameinfo ();
+int
+main ()
+{
+return getnameinfo ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_nsl_getnameinfo=yes
+else
+ ac_cv_lib_nsl_getnameinfo=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_getnameinfo" >&5
+$as_echo "$ac_cv_lib_nsl_getnameinfo" >&6; }
+if test "x$ac_cv_lib_nsl_getnameinfo" = xyes; then :
+
+$as_echo "@%:@define HAVE_GETNAMEINFO 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getnameinfo in -lsocket" >&5
+$as_echo_n "checking for getnameinfo in -lsocket... " >&6; }
+if ${ac_cv_lib_socket_getnameinfo+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getnameinfo ();
+int
+main ()
+{
+return getnameinfo ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_socket_getnameinfo=yes
+else
+ ac_cv_lib_socket_getnameinfo=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_getnameinfo" >&5
+$as_echo "$ac_cv_lib_socket_getnameinfo" >&6; }
+if test "x$ac_cv_lib_socket_getnameinfo" = xyes; then :
+
+$as_echo "@%:@define HAVE_GETNAMEINFO 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getnameinfo in -lws2_32" >&5
+$as_echo_n "checking for getnameinfo in -lws2_32... " >&6; }
+if ${ac_cv_lib_ws2_32_getnameinfo+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lws2_32 $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getnameinfo ();
+int
+main ()
+{
+return getnameinfo ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_ws2_32_getnameinfo=yes
+else
+ ac_cv_lib_ws2_32_getnameinfo=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ws2_32_getnameinfo" >&5
+$as_echo "$ac_cv_lib_ws2_32_getnameinfo" >&6; }
+if test "x$ac_cv_lib_ws2_32_getnameinfo" = xyes; then :
+
+$as_echo "@%:@define HAVE_GETNAMEINFO 1" >>confdefs.h
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+done
+
+
+for ac_func in gethostbyname
+do :
+ ac_fn_c_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname"
+if test "x$ac_cv_func_gethostbyname" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define HAVE_GETHOSTBYNAME 1
+_ACEOF
+
+$as_echo "@%:@define HAVE_GETHOSTBYNAME 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lxnet" >&5
+$as_echo_n "checking for gethostbyname in -lxnet... " >&6; }
+if ${ac_cv_lib_xnet_gethostbyname+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lxnet $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gethostbyname ();
+int
+main ()
+{
+return gethostbyname ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_xnet_gethostbyname=yes
+else
+ ac_cv_lib_xnet_gethostbyname=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xnet_gethostbyname" >&5
+$as_echo "$ac_cv_lib_xnet_gethostbyname" >&6; }
+if test "x$ac_cv_lib_xnet_gethostbyname" = xyes; then :
+
+$as_echo "@%:@define HAVE_GETHOSTBYNAME 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5
+$as_echo_n "checking for gethostbyname in -lnsl... " >&6; }
+if ${ac_cv_lib_nsl_gethostbyname+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gethostbyname ();
+int
+main ()
+{
+return gethostbyname ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_nsl_gethostbyname=yes
+else
+ ac_cv_lib_nsl_gethostbyname=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5
+$as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; }
+if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then :
+
+$as_echo "@%:@define HAVE_GETHOSTBYNAME 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lsocket" >&5
+$as_echo_n "checking for gethostbyname in -lsocket... " >&6; }
+if ${ac_cv_lib_socket_gethostbyname+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gethostbyname ();
+int
+main ()
+{
+return gethostbyname ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_socket_gethostbyname=yes
+else
+ ac_cv_lib_socket_gethostbyname=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_gethostbyname" >&5
+$as_echo "$ac_cv_lib_socket_gethostbyname" >&6; }
+if test "x$ac_cv_lib_socket_gethostbyname" = xyes; then :
+
+$as_echo "@%:@define HAVE_GETHOSTBYNAME 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lws3_32" >&5
+$as_echo_n "checking for gethostbyname in -lws3_32... " >&6; }
+if ${ac_cv_lib_ws3_32_gethostbyname+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lws3_32 $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gethostbyname ();
+int
+main ()
+{
+return gethostbyname ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_ws3_32_gethostbyname=yes
+else
+ ac_cv_lib_ws3_32_gethostbyname=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ws3_32_gethostbyname" >&5
+$as_echo "$ac_cv_lib_ws3_32_gethostbyname" >&6; }
+if test "x$ac_cv_lib_ws3_32_gethostbyname" = xyes; then :
+
+$as_echo "@%:@define HAVE_GETHOSTBYNAME 1" >>confdefs.h
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+done
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking htons" >&5
+$as_echo_n "checking htons... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+int
+main ()
+{
+
+ unsigned short s;
+ s = htons(5);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+$as_echo "@%:@define HAVE_HTONS 1" >>confdefs.h
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking ntohs" >&5
+$as_echo_n "checking ntohs... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+int
+main ()
+{
+
+ unsigned short s;
+ s = ntohs(5);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+$as_echo "@%:@define HAVE_NTOHS 1" >>confdefs.h
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking htonl" >&5
+$as_echo_n "checking htonl... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+int
+main ()
+{
+
+ unsigned long s;
+ s = htonl(5);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+$as_echo "@%:@define HAVE_HTONL 1" >>confdefs.h
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking ntohl" >&5
+$as_echo_n "checking ntohl... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+int
+main ()
+{
+
+ unsigned long s;
+ s = ntohl(5);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+$as_echo "@%:@define HAVE_NTOHL 1" >>confdefs.h
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+for ac_func in inet_addr
+do :
+ ac_fn_c_check_func "$LINENO" "inet_addr" "ac_cv_func_inet_addr"
+if test "x$ac_cv_func_inet_addr" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define HAVE_INET_ADDR 1
+_ACEOF
+
+$as_echo "@%:@define HAVE_INET_ADDR 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_addr in -lxnet" >&5
+$as_echo_n "checking for inet_addr in -lxnet... " >&6; }
+if ${ac_cv_lib_xnet_inet_addr+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lxnet $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_addr ();
+int
+main ()
+{
+return inet_addr ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_xnet_inet_addr=yes
+else
+ ac_cv_lib_xnet_inet_addr=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xnet_inet_addr" >&5
+$as_echo "$ac_cv_lib_xnet_inet_addr" >&6; }
+if test "x$ac_cv_lib_xnet_inet_addr" = xyes; then :
+
+$as_echo "@%:@define HAVE_INET_ADDR 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_addr in -lnsl" >&5
+$as_echo_n "checking for inet_addr in -lnsl... " >&6; }
+if ${ac_cv_lib_nsl_inet_addr+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_addr ();
+int
+main ()
+{
+return inet_addr ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_nsl_inet_addr=yes
+else
+ ac_cv_lib_nsl_inet_addr=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_inet_addr" >&5
+$as_echo "$ac_cv_lib_nsl_inet_addr" >&6; }
+if test "x$ac_cv_lib_nsl_inet_addr" = xyes; then :
+
+$as_echo "@%:@define HAVE_INET_ADDR 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_addr in -lsocket" >&5
+$as_echo_n "checking for inet_addr in -lsocket... " >&6; }
+if ${ac_cv_lib_socket_inet_addr+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_addr ();
+int
+main ()
+{
+return inet_addr ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_socket_inet_addr=yes
+else
+ ac_cv_lib_socket_inet_addr=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_inet_addr" >&5
+$as_echo "$ac_cv_lib_socket_inet_addr" >&6; }
+if test "x$ac_cv_lib_socket_inet_addr" = xyes; then :
+
+$as_echo "@%:@define HAVE_INET_ADDR 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_addr in -lws2_32" >&5
+$as_echo_n "checking for inet_addr in -lws2_32... " >&6; }
+if ${ac_cv_lib_ws2_32_inet_addr+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lws2_32 $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_addr ();
+int
+main ()
+{
+return inet_addr ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_ws2_32_inet_addr=yes
+else
+ ac_cv_lib_ws2_32_inet_addr=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ws2_32_inet_addr" >&5
+$as_echo "$ac_cv_lib_ws2_32_inet_addr" >&6; }
+if test "x$ac_cv_lib_ws2_32_inet_addr" = xyes; then :
+
+$as_echo "@%:@define HAVE_INET_ADDR 1" >>confdefs.h
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+done
+
+
+for ac_func in inet_aton
+do :
+ ac_fn_c_check_func "$LINENO" "inet_aton" "ac_cv_func_inet_aton"
+if test "x$ac_cv_func_inet_aton" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define HAVE_INET_ATON 1
+_ACEOF
+
+$as_echo "@%:@define HAVE_INET_ATON 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_aton in -lxnet" >&5
+$as_echo_n "checking for inet_aton in -lxnet... " >&6; }
+if ${ac_cv_lib_xnet_inet_aton+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lxnet $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_aton ();
+int
+main ()
+{
+return inet_aton ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_xnet_inet_aton=yes
+else
+ ac_cv_lib_xnet_inet_aton=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xnet_inet_aton" >&5
+$as_echo "$ac_cv_lib_xnet_inet_aton" >&6; }
+if test "x$ac_cv_lib_xnet_inet_aton" = xyes; then :
+
+$as_echo "@%:@define HAVE_INET_ATON 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_aton in -lnsl" >&5
+$as_echo_n "checking for inet_aton in -lnsl... " >&6; }
+if ${ac_cv_lib_nsl_inet_aton+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_aton ();
+int
+main ()
+{
+return inet_aton ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_nsl_inet_aton=yes
+else
+ ac_cv_lib_nsl_inet_aton=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_inet_aton" >&5
+$as_echo "$ac_cv_lib_nsl_inet_aton" >&6; }
+if test "x$ac_cv_lib_nsl_inet_aton" = xyes; then :
+
+$as_echo "@%:@define HAVE_INET_ATON 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_aton in -lsocket" >&5
+$as_echo_n "checking for inet_aton in -lsocket... " >&6; }
+if ${ac_cv_lib_socket_inet_aton+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_aton ();
+int
+main ()
+{
+return inet_aton ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_socket_inet_aton=yes
+else
+ ac_cv_lib_socket_inet_aton=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_inet_aton" >&5
+$as_echo "$ac_cv_lib_socket_inet_aton" >&6; }
+if test "x$ac_cv_lib_socket_inet_aton" = xyes; then :
+
+$as_echo "@%:@define HAVE_INET_ATON 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_aton in -lws2_32" >&5
+$as_echo_n "checking for inet_aton in -lws2_32... " >&6; }
+if ${ac_cv_lib_ws2_32_inet_aton+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lws2_32 $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_aton ();
+int
+main ()
+{
+return inet_aton ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_ws2_32_inet_aton=yes
+else
+ ac_cv_lib_ws2_32_inet_aton=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ws2_32_inet_aton" >&5
+$as_echo "$ac_cv_lib_ws2_32_inet_aton" >&6; }
+if test "x$ac_cv_lib_ws2_32_inet_aton" = xyes; then :
+
+$as_echo "@%:@define HAVE_INET_ATON 1" >>confdefs.h
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+done
+
+
+for ac_func in inet_pton
+do :
+ ac_fn_c_check_func "$LINENO" "inet_pton" "ac_cv_func_inet_pton"
+if test "x$ac_cv_func_inet_pton" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define HAVE_INET_PTON 1
+_ACEOF
+
+$as_echo "@%:@define HAVE_INET_PTON 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_pton in -lxnet" >&5
+$as_echo_n "checking for inet_pton in -lxnet... " >&6; }
+if ${ac_cv_lib_xnet_inet_pton+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lxnet $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_pton ();
+int
+main ()
+{
+return inet_pton ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_xnet_inet_pton=yes
+else
+ ac_cv_lib_xnet_inet_pton=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xnet_inet_pton" >&5
+$as_echo "$ac_cv_lib_xnet_inet_pton" >&6; }
+if test "x$ac_cv_lib_xnet_inet_pton" = xyes; then :
+
+$as_echo "@%:@define HAVE_INET_PTON 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_pton in -lnsl" >&5
+$as_echo_n "checking for inet_pton in -lnsl... " >&6; }
+if ${ac_cv_lib_nsl_inet_pton+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_pton ();
+int
+main ()
+{
+return inet_pton ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_nsl_inet_pton=yes
+else
+ ac_cv_lib_nsl_inet_pton=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_inet_pton" >&5
+$as_echo "$ac_cv_lib_nsl_inet_pton" >&6; }
+if test "x$ac_cv_lib_nsl_inet_pton" = xyes; then :
+
+$as_echo "@%:@define HAVE_INET_PTON 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_pton in -lsocket" >&5
+$as_echo_n "checking for inet_pton in -lsocket... " >&6; }
+if ${ac_cv_lib_socket_inet_pton+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_pton ();
+int
+main ()
+{
+return inet_pton ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_socket_inet_pton=yes
+else
+ ac_cv_lib_socket_inet_pton=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_inet_pton" >&5
+$as_echo "$ac_cv_lib_socket_inet_pton" >&6; }
+if test "x$ac_cv_lib_socket_inet_pton" = xyes; then :
+
+$as_echo "@%:@define HAVE_INET_PTON 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_pton in -lws2_32" >&5
+$as_echo_n "checking for inet_pton in -lws2_32... " >&6; }
+if ${ac_cv_lib_ws2_32_inet_pton+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lws2_32 $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_pton ();
+int
+main ()
+{
+return inet_pton ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_ws2_32_inet_pton=yes
+else
+ ac_cv_lib_ws2_32_inet_pton=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ws2_32_inet_pton" >&5
+$as_echo "$ac_cv_lib_ws2_32_inet_pton" >&6; }
+if test "x$ac_cv_lib_ws2_32_inet_pton" = xyes; then :
+
+$as_echo "@%:@define HAVE_INET_PTON 1" >>confdefs.h
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+done
+
+
+for ac_func in inet_ntop
+do :
+ ac_fn_c_check_func "$LINENO" "inet_ntop" "ac_cv_func_inet_ntop"
+if test "x$ac_cv_func_inet_ntop" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define HAVE_INET_NTOP 1
+_ACEOF
+
+$as_echo "@%:@define HAVE_INET_NTOP 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_ntop in -lxnet" >&5
+$as_echo_n "checking for inet_ntop in -lxnet... " >&6; }
+if ${ac_cv_lib_xnet_inet_ntop+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lxnet $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_ntop ();
+int
+main ()
+{
+return inet_ntop ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_xnet_inet_ntop=yes
+else
+ ac_cv_lib_xnet_inet_ntop=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xnet_inet_ntop" >&5
+$as_echo "$ac_cv_lib_xnet_inet_ntop" >&6; }
+if test "x$ac_cv_lib_xnet_inet_ntop" = xyes; then :
+
+$as_echo "@%:@define HAVE_INET_NTOP 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_ntop in -lnsl" >&5
+$as_echo_n "checking for inet_ntop in -lnsl... " >&6; }
+if ${ac_cv_lib_nsl_inet_ntop+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_ntop ();
+int
+main ()
+{
+return inet_ntop ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_nsl_inet_ntop=yes
+else
+ ac_cv_lib_nsl_inet_ntop=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_inet_ntop" >&5
+$as_echo "$ac_cv_lib_nsl_inet_ntop" >&6; }
+if test "x$ac_cv_lib_nsl_inet_ntop" = xyes; then :
+
+$as_echo "@%:@define HAVE_INET_NTOP 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_ntop in -lsocket" >&5
+$as_echo_n "checking for inet_ntop in -lsocket... " >&6; }
+if ${ac_cv_lib_socket_inet_ntop+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_ntop ();
+int
+main ()
+{
+return inet_ntop ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_socket_inet_ntop=yes
+else
+ ac_cv_lib_socket_inet_ntop=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_inet_ntop" >&5
+$as_echo "$ac_cv_lib_socket_inet_ntop" >&6; }
+if test "x$ac_cv_lib_socket_inet_ntop" = xyes; then :
+
+$as_echo "@%:@define HAVE_INET_NTOP 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_ntop in -lws2_32" >&5
+$as_echo_n "checking for inet_ntop in -lws2_32... " >&6; }
+if ${ac_cv_lib_ws2_32_inet_ntop+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lws2_32 $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_ntop ();
+int
+main ()
+{
+return inet_ntop ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_ws2_32_inet_ntop=yes
+else
+ ac_cv_lib_ws2_32_inet_ntop=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ws2_32_inet_ntop" >&5
+$as_echo "$ac_cv_lib_ws2_32_inet_ntop" >&6; }
+if test "x$ac_cv_lib_ws2_32_inet_ntop" = xyes; then :
+
+$as_echo "@%:@define HAVE_INET_NTOP 1" >>confdefs.h
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+done
+
+
+if [ "X$SOCKLIB" = "X$NSLLIB" ]
+then
+NSLLIB=''
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking /proc/.../exe symbolic link" >&5
+$as_echo_n "checking /proc/.../exe symbolic link... " >&6; }
+if test "$cross_compiling" = yes; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no - test not possible" >&5
+$as_echo "no - test not possible" >&6; }
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+
+/* Buffer for result */
+char prog[1024];
+
+#ifdef __cplusplus
+int main(int argc, char *argv[])
+#else
+int main(argc, argv) int argc; char *argv[];
+#endif
+{
+ char buf[64];
+ struct stat stbuf;
+ int exv = 1;
+ ssize_t res;
+#if HAVE_STDINT_H
+ sprintf(buf, "/proc/%ju/exe", (uintmax_t)getpid());
+#else
+ sprintf(buf, "/proc/%lu/exe", (unsigned long)getpid());
+#endif
+ res = readlink(buf, prog, sizeof(prog));
+ if ((0 < res) && (sizeof(prog) > res)) {
+ prog[res] = '\0';
+ if (0 == stat(prog, &stbuf)) {
+ exv = 0;
+ }
+ }
+ return exv;
+}
+
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "@%:@define HAVE_PROC_PID_EXE 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking ssize_t" >&5
+$as_echo_n "checking ssize_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+int
+main ()
+{
+
+ ssize_t sz;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "@%:@define HAVE_SSIZE_T 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking int8_t" >&5
+$as_echo_n "checking int8_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+int
+main ()
+{
+
+int8_t i8 = 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "@%:@define HAVE_INT8_T 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking int16_t" >&5
+$as_echo_n "checking int16_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+int
+main ()
+{
+
+int16_t i16 = 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "@%:@define HAVE_INT16_T 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking int32_t" >&5
+$as_echo_n "checking int32_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+int
+main ()
+{
+
+int32_t i32 = 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "@%:@define HAVE_INT32_T 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking uint8_t" >&5
+$as_echo_n "checking uint8_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+int
+main ()
+{
+
+ uint8_t sz;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "@%:@define HAVE_UINT8_T 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking uint16_t" >&5
+$as_echo_n "checking uint16_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+int
+main ()
+{
+
+ uint16_t sz;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "@%:@define HAVE_UINT16_T 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking uint32_t" >&5
+$as_echo_n "checking uint32_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+int
+main ()
+{
+
+ uint32_t sz;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "@%:@define HAVE_UINT32_T 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dev_t" >&5
+$as_echo_n "checking dev_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+ dev_t devno;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "@%:@define HAVE_DEV_T 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking _dev_t" >&5
+$as_echo_n "checking _dev_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+ _dev_t devno;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "@%:@define HAVE__DEV_T 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking ino_t" >&5
+$as_echo_n "checking ino_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+ ino_t devno;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "@%:@define HAVE_INO_T 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking _ino_t" >&5
+$as_echo_n "checking _ino_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+ _ino_t devno;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "@%:@define HAVE__INO_T 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking ino64_t" >&5
+$as_echo_n "checking ino64_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#define _LARGEFILE64_SOURCE 1
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+ ino64_t devno;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "@%:@define HAVE_INO64_T 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking mode_t" >&5
+$as_echo_n "checking mode_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+ mode_t devno;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "@%:@define HAVE_MODE_T 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking nlink_t" >&5
+$as_echo_n "checking nlink_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+ nlink_t devno;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "@%:@define HAVE_NLINK_T 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking uid_t" >&5
+$as_echo_n "checking uid_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+ uid_t devno;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "@%:@define HAVE_UID_T 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking gid_t" >&5
+$as_echo_n "checking gid_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+ gid_t devno;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "@%:@define HAVE_GID_T 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking off_t" >&5
+$as_echo_n "checking off_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+ off_t devno;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "@%:@define HAVE_OFF_T 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking off64_t" >&5
+$as_echo_n "checking off64_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#define _LARGEFILE64_SOURCE 1
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+ off64_t devno;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "@%:@define HAVE_OFF64_T 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking blksize_t" >&5
+$as_echo_n "checking blksize_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+ blksize_t devno;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "@%:@define HAVE_BLKSIZE_T 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking blkcnt_t" >&5
+$as_echo_n "checking blkcnt_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+ blkcnt_t devno;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "@%:@define HAVE_BLKCNT_T 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking fpos_t" >&5
+$as_echo_n "checking fpos_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+ fpos_t devno;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "@%:@define HAVE_FPOS_T 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking blocksize and blockcount in stat output" >&5
+$as_echo_n "checking blocksize and blockcount in stat output... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#define _LARGEFILE64_SOURCE 1
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+#if HAVE_TYPE_STAT64
+ struct stat64 stb;
+ stb.st_blksize = 0;
+ stb.st_blocks = 0;
+#else
+ struct stat stb;
+ stb.st_blksize = 0;
+ stb.st_blocks = 0;
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "@%:@define HAVE_FILE_BLKSIZECNT 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking _fpos_t" >&5
+$as_echo_n "checking _fpos_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+ _fpos_t devno;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "@%:@define HAVE__FPOS_T 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking socklen_t" >&5
+$as_echo_n "checking socklen_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+socklen_t sz;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "@%:@define HAVE_SOCKLEN_T 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking struct sockaddr_in" >&5
+$as_echo_n "checking struct sockaddr_in... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+struct sockaddr_in sain;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "@%:@define HAVE_STRUCT_SOCKADDR_IN 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking struct sockaddr_in6" >&5
+$as_echo_n "checking struct sockaddr_in6... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+struct sockaddr_in6 sain;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "@%:@define HAVE_STRUCT_SOCKADDR_IN6 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking struct sockaddr_un" >&5
+$as_echo_n "checking struct sockaddr_un... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_SYS_UN_H
+#include <sys/un.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+struct sockaddr_un sain;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "@%:@define HAVE_STRUCT_SOCKADDR_UN 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking struct addrinfo" >&5
+$as_echo_n "checking struct addrinfo... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+struct addrinfo adi;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "@%:@define HAVE_STRUCT_ADDRINFO 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking struct sockaddr_storage" >&5
+$as_echo_n "checking struct sockaddr_storage... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+struct sockaddr_storage sain;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "@%:@define HAVE_STRUCT_SOCKADDR_STORAGE 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking IN_ADDR" >&5
+$as_echo_n "checking IN_ADDR... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
+#if HAVE_WS2TCPIP_H
+#include <ws2tcpip.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+int
+main ()
+{
+
+IN_ADDR addr;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "@%:@define HAVE_IN_ADDR 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking IN6_ADDR" >&5
+$as_echo_n "checking IN6_ADDR... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
+#if HAVE_WS2TCPIP_H
+#include <ws2tcpip.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+int
+main ()
+{
+
+IN6_ADDR addr;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "@%:@define HAVE_IN6_ADDR 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking rand srand" >&5
+$as_echo_n "checking rand srand... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+main ()
+{
+
+ srand(25);
+ printf("%d\n", rand());
+ printf("%d\n", RAND_MAX);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "@%:@define HAVE_RAND 1" >>confdefs.h
+
+$as_echo "@%:@define HAVE_SRAND 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking initstate setstate random" >&5
+$as_echo_n "checking initstate setstate random... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+main ()
+{
+
+char rs[256];
+initstate(25, rs, sizeof(rs));
+setstate(rs);
+printf("%ld\n", random());
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "@%:@define HAVE_INITSTATE 1" >>confdefs.h
+
+$as_echo "@%:@define HAVE_SETSTATE 1" >>confdefs.h
+
+$as_echo "@%:@define HAVE_RANDOM 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking lrand48 nrand48 seed48" >&5
+$as_echo_n "checking lrand48 nrand48 seed48... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+main ()
+{
+
+unsigned short sv[3];
+sv[0] = 0;
+sv[1] = 1;
+sv[2] = 2;
+seed48(sv);
+printf("%ld\n", lrand48());
+printf("%ld\n", nrand48(sv));
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "@%:@define HAVE_LRAND48 1" >>confdefs.h
+
+$as_echo "@%:@define HAVE_NRAND48 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of off_t" >&5
+$as_echo_n "checking size of off_t... " >&6; }
+if ${ac_cv_sizeof_off_t+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (off_t))" "ac_cv_sizeof_off_t" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_off_t" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (off_t)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_off_t=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_off_t" >&5
+$as_echo "$ac_cv_sizeof_off_t" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+@%:@define SIZEOF_OFF_T $ac_cv_sizeof_off_t
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of off64_t" >&5
+$as_echo_n "checking size of off64_t... " >&6; }
+if ${ac_cv_sizeof_off64_t+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (off64_t))" "ac_cv_sizeof_off64_t" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_off64_t" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (off64_t)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_off64_t=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_off64_t" >&5
+$as_echo "$ac_cv_sizeof_off64_t" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+@%:@define SIZEOF_OFF64_T $ac_cv_sizeof_off64_t
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of ino_t" >&5
+$as_echo_n "checking size of ino_t... " >&6; }
+if ${ac_cv_sizeof_ino_t+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (ino_t))" "ac_cv_sizeof_ino_t" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_ino_t" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (ino_t)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_ino_t=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_ino_t" >&5
+$as_echo "$ac_cv_sizeof_ino_t" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+@%:@define SIZEOF_INO_T $ac_cv_sizeof_ino_t
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of ino64_t" >&5
+$as_echo_n "checking size of ino64_t... " >&6; }
+if ${ac_cv_sizeof_ino64_t+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (ino64_t))" "ac_cv_sizeof_ino64_t" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_ino64_t" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (ino64_t)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_ino64_t=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_ino64_t" >&5
+$as_echo "$ac_cv_sizeof_ino64_t" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+@%:@define SIZEOF_INO64_T $ac_cv_sizeof_ino64_t
+_ACEOF
+
+
+
+
+@%:@ Check whether --with-fallback-limits was given.
+if test "${with_fallback_limits+set}" = set; then :
+ withval=$with_fallback_limits; $as_echo "@%:@define USE_FALLBACK_NUMERIC_LIMITS 1" >>confdefs.h
+
+fi
+
+
+
+@%:@ Check whether --with-printf-scanf was given.
+if test "${with_printf_scanf+set}" = set; then :
+ withval=$with_printf_scanf; CAN_USE_PRINTF_SCANF="$withval"
+fi
+
+
+if [ "X$CAN_USE_PRINTF_SCANF" != "Xno" ]
+then
+ $as_echo "@%:@define USE_PRINTF_SCANF 1" >>confdefs.h
+
+fi
+
+$as_echo "@%:@define HAVE_FILE_DEVINO 1" >>confdefs.h
+
+$as_echo "@%:@define HAVE_FILE_UIDGID 1" >>confdefs.h
+
+$as_echo "@%:@define HAVE_FILE_ATIMECTIME 1" >>confdefs.h
+
+
+$as_echo "@%:@define HAVE_COMPATDKTOOLS3 1" >>confdefs.h
+
+
+SEP=`cat sep.txt`
+for i in test*.ctr
+do
+j=`echo $i | sed -e 's/\.ctr//g'`
+if [ "X$TESTPROGRAMS" = "X" ]
+then
+ TESTPROGRAMS="$j"
+else
+ TESTPROGRAMS="${TESTPROGRAMS} ${SEP}$j"
+fi
+done
+
+if [ "X$SUITE" = "Xgui" ]
+then
+ $as_echo "@%:@define HAVE_WXWIDGETS 1" >>confdefs.h
+
+else
+ WXCPPFLAGS=''
+ WXCXXFLAGS=''
+ WXCFLAGS=''
+ WXLDFLAGS=''
+fi
+
+WXMAJOR=''
+WXMINOR=''
+
+if [ "X$WXVERSION" != "X" ]
+then
+ WXMAJOR=`echo $WXVERSION | cut -f 1 -d .`
+ WXMINOR=`echo $WXVERSION | cut -f 2 -d .`
+fi
+[ "X$WXMAJOR" != "X" ] || WXMAJOR="0"
+
+if [ "$WXMAJOR" -ge 3 ]
+then
+$as_echo "@%:@define HAVE_WX_CHARTYPE_H 1" >>confdefs.h
+
+elif [ "$WXMAJOR" -ge 2 ]
+then
+$as_echo "@%:@define HAVE_WX_WXCHAR_H 1" >>confdefs.h
+
+fi
+
+LIBPNG=''
+LIBJPEG=''
+LIBTIFF=''
+ANYDB=''
+SNMPPROG=''
+MYSQLPROG=''
+PTHREADLIB=''
+LIBDK3WXOBJ=''
+LIBDK4WXOBJ=''
+LIBDK4WXTOBUILD=''
+DBLIB=''
+DBLIBSOCK=''
+NETSNMP_LIBS=''
+NETSNMP_CFLAGS=''
+NETSNMP_LIBS=`net-snmp-config --libs`
+NETSNMP_CFLAGS=`net-snmp-config --cflags`
+ac_fn_c_check_header_mongrel "$LINENO" "stdio.h" "ac_cv_header_stdio_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdio_h" = xyes; then :
+ $as_echo "@%:@define HAVE_STDIO_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "conio.h" "ac_cv_header_conio_h" "$ac_includes_default"
+if test "x$ac_cv_header_conio_h" = xyes; then :
+ $as_echo "@%:@define HAVE_CONIO_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "grp.h" "ac_cv_header_grp_h" "$ac_includes_default"
+if test "x$ac_cv_header_grp_h" = xyes; then :
+ $as_echo "@%:@define HAVE_GRP_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "gdbm.h" "ac_cv_header_gdbm_h" "$ac_includes_default"
+if test "x$ac_cv_header_gdbm_h" = xyes; then :
+ FOUND_GDBM='yes'
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "ndbm.h" "ac_cv_header_ndbm_h" "$ac_includes_default"
+if test "x$ac_cv_header_ndbm_h" = xyes; then :
+ FOUND_NDBM='yes'
+fi
+
+
+case "X${FOUND_NDBM}${USE_NDBM}${FOUND_GDBM}" in
+ "Xyesyesyes")
+ $as_echo "@%:@define HAVE_NDBM_H 1" >>confdefs.h
+
+ ANYDB='ndbm'
+ ;;
+ "Xyesyesno")
+ $as_echo "@%:@define HAVE_NDBM_H 1" >>confdefs.h
+
+ ANYDB='ndbm'
+ ;;
+ "Xyesautono")
+ $as_echo "@%:@define HAVE_NDBM_H 1" >>confdefs.h
+
+ ANYDB='ndbm'
+ ;;
+esac
+if [ "X$ANYDB" != "Xndbm" -a "X$FOUND_GDBM" = "Xyes" ]
+then
+ $as_echo "@%:@define HAVE_GDBM_H 1" >>confdefs.h
+
+fi
+ac_fn_c_check_header_mongrel "$LINENO" "db.h" "ac_cv_header_db_h" "$ac_includes_default"
+if test "x$ac_cv_header_db_h" = xyes; then :
+ FOUND_BDB='yes';ANYDB='db';DBLIB="-ldb";$as_echo "@%:@define HAVE_DB_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "dir.h" "ac_cv_header_dir_h" "$ac_includes_default"
+if test "x$ac_cv_header_dir_h" = xyes; then :
+ $as_echo "@%:@define HAVE_DIR_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "err.h" "ac_cv_header_err_h" "$ac_includes_default"
+if test "x$ac_cv_header_err_h" = xyes; then :
+ $as_echo "@%:@define HAVE_ERR_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "shadow.h" "ac_cv_header_shadow_h" "$ac_includes_default"
+if test "x$ac_cv_header_shadow_h" = xyes; then :
+ $as_echo "@%:@define HAVE_SHADOW_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "stropts.h" "ac_cv_header_stropts_h" "$ac_includes_default"
+if test "x$ac_cv_header_stropts_h" = xyes; then :
+ $as_echo "@%:@define HAVE_STROPTS_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "syslog.h" "ac_cv_header_syslog_h" "$ac_includes_default"
+if test "x$ac_cv_header_syslog_h" = xyes; then :
+ $as_echo "@%:@define HAVE_SYSLOG_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sysres.h" "ac_cv_header_sysres_h" "$ac_includes_default"
+if test "x$ac_cv_header_sysres_h" = xyes; then :
+ $as_echo "@%:@define HAVE_SYSRES_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "termios.h" "ac_cv_header_termios_h" "$ac_includes_default"
+if test "x$ac_cv_header_termios_h" = xyes; then :
+ $as_echo "@%:@define HAVE_TERMIOS_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "vararg.h" "ac_cv_header_vararg_h" "$ac_includes_default"
+if test "x$ac_cv_header_vararg_h" = xyes; then :
+ $as_echo "@%:@define HAVE_VARARG_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "varargs.h" "ac_cv_header_varargs_h" "$ac_includes_default"
+if test "x$ac_cv_header_varargs_h" = xyes; then :
+ $as_echo "@%:@define HAVE_VARARGS_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "ntifs.h" "ac_cv_header_ntifs_h" "$ac_includes_default"
+if test "x$ac_cv_header_ntifs_h" = xyes; then :
+ $as_echo "@%:@define HAVE_NTIFS_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/file.h" "ac_cv_header_sys_file_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_file_h" = xyes; then :
+ $as_echo "@%:@define HAVE_SYS_FILE_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/resource.h" "ac_cv_header_sys_resource_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_resource_h" = xyes; then :
+ $as_echo "@%:@define HAVE_SYS_RESOURCE_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/statvfs.h" "ac_cv_header_sys_statvfs_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_statvfs_h" = xyes; then :
+ $as_echo "@%:@define HAVE_SYS_STATVFS_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/stropts.h" "ac_cv_header_sys_stropts_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_stropts_h" = xyes; then :
+ $as_echo "@%:@define HAVE_SYS_STROPTS_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/sunddi.h" "ac_cv_header_sys_sunddi_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_sunddi_h" = xyes; then :
+ $as_echo "@%:@define HAVE_SYS_SUNDDI_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/sysctl.h" "ac_cv_header_sys_sysctl_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_sysctl_h" = xyes; then :
+ $as_echo "@%:@define HAVE_SYS_SYSCTL_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/systeminfo.h" "ac_cv_header_sys_systeminfo_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_systeminfo_h" = xyes; then :
+ $as_echo "@%:@define HAVE_SYS_SYSTEMINFO_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/termios.h" "ac_cv_header_sys_termios_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_termios_h" = xyes; then :
+ $as_echo "@%:@define HAVE_SYS_TERMIOS_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/ttold.h" "ac_cv_header_sys_ttold_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_ttold_h" = xyes; then :
+ $as_echo "@%:@define HAVE_SYS_TTOLD_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/uio.h" "ac_cv_header_sys_uio_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_uio_h" = xyes; then :
+ $as_echo "@%:@define HAVE_SYS_UIO_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/wait.h" "ac_cv_header_sys_wait_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_wait_h" = xyes; then :
+ $as_echo "@%:@define HAVE_SYS_WAIT_H 1" >>confdefs.h
+
+fi
+
+
+
+ac_fn_c_check_header_compile "$LINENO" "winbase.h" "ac_cv_header_winbase_h" "
+#if HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+
+"
+if test "x$ac_cv_header_winbase_h" = xyes; then :
+ $as_echo "@%:@define HAVE_WINBASE_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_compile "$LINENO" "winreg.h" "ac_cv_header_winreg_h" "
+#if HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+#if HAVE_WINBASE_H
+#include <winbase.h>
+#endif
+
+"
+if test "x$ac_cv_header_winreg_h" = xyes; then :
+ $as_echo "@%:@define HAVE_WINREG_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_compile "$LINENO" "wincon.h" "ac_cv_header_wincon_h" "
+#if HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+#if HAVE_WINBASE_H
+#include <winbase.h>
+#endif
+
+"
+if test "x$ac_cv_header_wincon_h" = xyes; then :
+ $as_echo "@%:@define HAVE_WINCON_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "png.h" "ac_cv_header_png_h" "$ac_includes_default"
+if test "x$ac_cv_header_png_h" = xyes; then :
+ LIBPNG="-lpng";$as_echo "@%:@define HAVE_PNG_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "jpeglib.h" "ac_cv_header_jpeglib_h" "$ac_includes_default"
+if test "x$ac_cv_header_jpeglib_h" = xyes; then :
+ LIBJPEG="-ljpeg";$as_echo "@%:@define HAVE_JPEGLIB_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "tiff.h" "ac_cv_header_tiff_h" "$ac_includes_default"
+if test "x$ac_cv_header_tiff_h" = xyes; then :
+ LIBTIFF="-ltiff";$as_echo "@%:@define HAVE_TIFF_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "mysql/mysql.h" "ac_cv_header_mysql_mysql_h" "$ac_includes_default"
+if test "x$ac_cv_header_mysql_mysql_h" = xyes; then :
+
+MYSQLPROG='mysqlprog'
+MYSQLLIB='-lmysqlclient'
+$as_echo "@%:@define HAVE_MYSQL_MYSQL_H 1" >>confdefs.h
+
+
+else
+
+ac_fn_c_check_header_mongrel "$LINENO" "mysql.h" "ac_cv_header_mysql_h" "$ac_includes_default"
+if test "x$ac_cv_header_mysql_h" = xyes; then :
+
+MYSQLPROG='mysqlprog'
+MYSQLLIB='-lmysqlclient'
+$as_echo "@%:@define HAVE_MYSQL_H 1" >>confdefs.h
+
+
+
+fi
+
+
+
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "lprng.h" "ac_cv_header_lprng_h" "$ac_includes_default"
+if test "x$ac_cv_header_lprng_h" = xyes; then :
+ $as_echo "@%:@define HAVE_LPRNG_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "pthread.h" "ac_cv_header_pthread_h" "$ac_includes_default"
+if test "x$ac_cv_header_pthread_h" = xyes; then :
+ PTHREADLIB='-lpthread';$as_echo "@%:@define HAVE_PTHREAD_H 1" >>confdefs.h
+
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for acosh in -lm" >&5
+$as_echo_n "checking for acosh in -lm... " >&6; }
+if ${ac_cv_lib_m_acosh+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char acosh ();
+int
+main ()
+{
+return acosh ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_acosh=yes
+else
+ ac_cv_lib_m_acosh=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_acosh" >&5
+$as_echo "$ac_cv_lib_m_acosh" >&6; }
+if test "x$ac_cv_lib_m_acosh" = xyes; then :
+ $as_echo "@%:@define HAVE_ACOSH 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for acoshl in -lm" >&5
+$as_echo_n "checking for acoshl in -lm... " >&6; }
+if ${ac_cv_lib_m_acoshl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char acoshl ();
+int
+main ()
+{
+return acoshl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_acoshl=yes
+else
+ ac_cv_lib_m_acoshl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_acoshl" >&5
+$as_echo "$ac_cv_lib_m_acoshl" >&6; }
+if test "x$ac_cv_lib_m_acoshl" = xyes; then :
+ $as_echo "@%:@define HAVE_ACOSHL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for acosl in -lm" >&5
+$as_echo_n "checking for acosl in -lm... " >&6; }
+if ${ac_cv_lib_m_acosl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char acosl ();
+int
+main ()
+{
+return acosl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_acosl=yes
+else
+ ac_cv_lib_m_acosl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_acosl" >&5
+$as_echo "$ac_cv_lib_m_acosl" >&6; }
+if test "x$ac_cv_lib_m_acosl" = xyes; then :
+ $as_echo "@%:@define HAVE_ACOSL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for asinh in -lm" >&5
+$as_echo_n "checking for asinh in -lm... " >&6; }
+if ${ac_cv_lib_m_asinh+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char asinh ();
+int
+main ()
+{
+return asinh ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_asinh=yes
+else
+ ac_cv_lib_m_asinh=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_asinh" >&5
+$as_echo "$ac_cv_lib_m_asinh" >&6; }
+if test "x$ac_cv_lib_m_asinh" = xyes; then :
+ $as_echo "@%:@define HAVE_ASINH 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for asinhl in -lm" >&5
+$as_echo_n "checking for asinhl in -lm... " >&6; }
+if ${ac_cv_lib_m_asinhl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char asinhl ();
+int
+main ()
+{
+return asinhl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_asinhl=yes
+else
+ ac_cv_lib_m_asinhl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_asinhl" >&5
+$as_echo "$ac_cv_lib_m_asinhl" >&6; }
+if test "x$ac_cv_lib_m_asinhl" = xyes; then :
+ $as_echo "@%:@define HAVE_ASINHL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for asinl in -lm" >&5
+$as_echo_n "checking for asinl in -lm... " >&6; }
+if ${ac_cv_lib_m_asinl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char asinl ();
+int
+main ()
+{
+return asinl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_asinl=yes
+else
+ ac_cv_lib_m_asinl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_asinl" >&5
+$as_echo "$ac_cv_lib_m_asinl" >&6; }
+if test "x$ac_cv_lib_m_asinl" = xyes; then :
+ $as_echo "@%:@define HAVE_ASINL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for atan2 in -lm" >&5
+$as_echo_n "checking for atan2 in -lm... " >&6; }
+if ${ac_cv_lib_m_atan2+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char atan2 ();
+int
+main ()
+{
+return atan2 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_atan2=yes
+else
+ ac_cv_lib_m_atan2=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_atan2" >&5
+$as_echo "$ac_cv_lib_m_atan2" >&6; }
+if test "x$ac_cv_lib_m_atan2" = xyes; then :
+ $as_echo "@%:@define HAVE_ATAN2 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for atan2l in -lm" >&5
+$as_echo_n "checking for atan2l in -lm... " >&6; }
+if ${ac_cv_lib_m_atan2l+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char atan2l ();
+int
+main ()
+{
+return atan2l ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_atan2l=yes
+else
+ ac_cv_lib_m_atan2l=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_atan2l" >&5
+$as_echo "$ac_cv_lib_m_atan2l" >&6; }
+if test "x$ac_cv_lib_m_atan2l" = xyes; then :
+ $as_echo "@%:@define HAVE_ATAN2L 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for atanh in -lm" >&5
+$as_echo_n "checking for atanh in -lm... " >&6; }
+if ${ac_cv_lib_m_atanh+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char atanh ();
+int
+main ()
+{
+return atanh ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_atanh=yes
+else
+ ac_cv_lib_m_atanh=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_atanh" >&5
+$as_echo "$ac_cv_lib_m_atanh" >&6; }
+if test "x$ac_cv_lib_m_atanh" = xyes; then :
+ $as_echo "@%:@define HAVE_ATANH 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for atanhl in -lm" >&5
+$as_echo_n "checking for atanhl in -lm... " >&6; }
+if ${ac_cv_lib_m_atanhl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char atanhl ();
+int
+main ()
+{
+return atanhl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_atanhl=yes
+else
+ ac_cv_lib_m_atanhl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_atanhl" >&5
+$as_echo "$ac_cv_lib_m_atanhl" >&6; }
+if test "x$ac_cv_lib_m_atanhl" = xyes; then :
+ $as_echo "@%:@define HAVE_ATANHL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for atanl in -lm" >&5
+$as_echo_n "checking for atanl in -lm... " >&6; }
+if ${ac_cv_lib_m_atanl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char atanl ();
+int
+main ()
+{
+return atanl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_atanl=yes
+else
+ ac_cv_lib_m_atanl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_atanl" >&5
+$as_echo "$ac_cv_lib_m_atanl" >&6; }
+if test "x$ac_cv_lib_m_atanl" = xyes; then :
+ $as_echo "@%:@define HAVE_ATANL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ceil in -lm" >&5
+$as_echo_n "checking for ceil in -lm... " >&6; }
+if ${ac_cv_lib_m_ceil+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char ceil ();
+int
+main ()
+{
+return ceil ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_ceil=yes
+else
+ ac_cv_lib_m_ceil=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_ceil" >&5
+$as_echo "$ac_cv_lib_m_ceil" >&6; }
+if test "x$ac_cv_lib_m_ceil" = xyes; then :
+ $as_echo "@%:@define HAVE_CEIL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ceill in -lm" >&5
+$as_echo_n "checking for ceill in -lm... " >&6; }
+if ${ac_cv_lib_m_ceill+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char ceill ();
+int
+main ()
+{
+return ceill ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_ceill=yes
+else
+ ac_cv_lib_m_ceill=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_ceill" >&5
+$as_echo "$ac_cv_lib_m_ceill" >&6; }
+if test "x$ac_cv_lib_m_ceill" = xyes; then :
+ $as_echo "@%:@define HAVE_CEILL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for coshl in -lm" >&5
+$as_echo_n "checking for coshl in -lm... " >&6; }
+if ${ac_cv_lib_m_coshl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char coshl ();
+int
+main ()
+{
+return coshl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_coshl=yes
+else
+ ac_cv_lib_m_coshl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_coshl" >&5
+$as_echo "$ac_cv_lib_m_coshl" >&6; }
+if test "x$ac_cv_lib_m_coshl" = xyes; then :
+ $as_echo "@%:@define HAVE_COSHL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for cosl in -lm" >&5
+$as_echo_n "checking for cosl in -lm... " >&6; }
+if ${ac_cv_lib_m_cosl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char cosl ();
+int
+main ()
+{
+return cosl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_cosl=yes
+else
+ ac_cv_lib_m_cosl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_cosl" >&5
+$as_echo "$ac_cv_lib_m_cosl" >&6; }
+if test "x$ac_cv_lib_m_cosl" = xyes; then :
+ $as_echo "@%:@define HAVE_COSL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for expl in -lm" >&5
+$as_echo_n "checking for expl in -lm... " >&6; }
+if ${ac_cv_lib_m_expl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char expl ();
+int
+main ()
+{
+return expl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_expl=yes
+else
+ ac_cv_lib_m_expl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_expl" >&5
+$as_echo "$ac_cv_lib_m_expl" >&6; }
+if test "x$ac_cv_lib_m_expl" = xyes; then :
+ $as_echo "@%:@define HAVE_EXPL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fabs in -lm" >&5
+$as_echo_n "checking for fabs in -lm... " >&6; }
+if ${ac_cv_lib_m_fabs+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char fabs ();
+int
+main ()
+{
+return fabs ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_fabs=yes
+else
+ ac_cv_lib_m_fabs=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_fabs" >&5
+$as_echo "$ac_cv_lib_m_fabs" >&6; }
+if test "x$ac_cv_lib_m_fabs" = xyes; then :
+ $as_echo "@%:@define HAVE_FABS 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fabsl in -lm" >&5
+$as_echo_n "checking for fabsl in -lm... " >&6; }
+if ${ac_cv_lib_m_fabsl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char fabsl ();
+int
+main ()
+{
+return fabsl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_fabsl=yes
+else
+ ac_cv_lib_m_fabsl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_fabsl" >&5
+$as_echo "$ac_cv_lib_m_fabsl" >&6; }
+if test "x$ac_cv_lib_m_fabsl" = xyes; then :
+ $as_echo "@%:@define HAVE_FABSL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for floor in -lm" >&5
+$as_echo_n "checking for floor in -lm... " >&6; }
+if ${ac_cv_lib_m_floor+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char floor ();
+int
+main ()
+{
+return floor ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_floor=yes
+else
+ ac_cv_lib_m_floor=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_floor" >&5
+$as_echo "$ac_cv_lib_m_floor" >&6; }
+if test "x$ac_cv_lib_m_floor" = xyes; then :
+ $as_echo "@%:@define HAVE_FLOOR 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for floorl in -lm" >&5
+$as_echo_n "checking for floorl in -lm... " >&6; }
+if ${ac_cv_lib_m_floorl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char floorl ();
+int
+main ()
+{
+return floorl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_floorl=yes
+else
+ ac_cv_lib_m_floorl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_floorl" >&5
+$as_echo "$ac_cv_lib_m_floorl" >&6; }
+if test "x$ac_cv_lib_m_floorl" = xyes; then :
+ $as_echo "@%:@define HAVE_FLOORL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for labs in -lm" >&5
+$as_echo_n "checking for labs in -lm... " >&6; }
+if ${ac_cv_lib_m_labs+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char labs ();
+int
+main ()
+{
+return labs ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_labs=yes
+else
+ ac_cv_lib_m_labs=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_labs" >&5
+$as_echo "$ac_cv_lib_m_labs" >&6; }
+if test "x$ac_cv_lib_m_labs" = xyes; then :
+ $as_echo "@%:@define HAVE_LABS 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for logl in -lm" >&5
+$as_echo_n "checking for logl in -lm... " >&6; }
+if ${ac_cv_lib_m_logl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char logl ();
+int
+main ()
+{
+return logl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_logl=yes
+else
+ ac_cv_lib_m_logl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_logl" >&5
+$as_echo "$ac_cv_lib_m_logl" >&6; }
+if test "x$ac_cv_lib_m_logl" = xyes; then :
+ $as_echo "@%:@define HAVE_LOGL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for rint in -lm" >&5
+$as_echo_n "checking for rint in -lm... " >&6; }
+if ${ac_cv_lib_m_rint+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char rint ();
+int
+main ()
+{
+return rint ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_rint=yes
+else
+ ac_cv_lib_m_rint=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_rint" >&5
+$as_echo "$ac_cv_lib_m_rint" >&6; }
+if test "x$ac_cv_lib_m_rint" = xyes; then :
+ $as_echo "@%:@define HAVE_RINT 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for rintl in -lm" >&5
+$as_echo_n "checking for rintl in -lm... " >&6; }
+if ${ac_cv_lib_m_rintl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char rintl ();
+int
+main ()
+{
+return rintl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_rintl=yes
+else
+ ac_cv_lib_m_rintl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_rintl" >&5
+$as_echo "$ac_cv_lib_m_rintl" >&6; }
+if test "x$ac_cv_lib_m_rintl" = xyes; then :
+ $as_echo "@%:@define HAVE_RINTL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sinhl in -lm" >&5
+$as_echo_n "checking for sinhl in -lm... " >&6; }
+if ${ac_cv_lib_m_sinhl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char sinhl ();
+int
+main ()
+{
+return sinhl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_sinhl=yes
+else
+ ac_cv_lib_m_sinhl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_sinhl" >&5
+$as_echo "$ac_cv_lib_m_sinhl" >&6; }
+if test "x$ac_cv_lib_m_sinhl" = xyes; then :
+ $as_echo "@%:@define HAVE_SINHL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqrt in -lm" >&5
+$as_echo_n "checking for sqrt in -lm... " >&6; }
+if ${ac_cv_lib_m_sqrt+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char sqrt ();
+int
+main ()
+{
+return sqrt ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_sqrt=yes
+else
+ ac_cv_lib_m_sqrt=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_sqrt" >&5
+$as_echo "$ac_cv_lib_m_sqrt" >&6; }
+if test "x$ac_cv_lib_m_sqrt" = xyes; then :
+ $as_echo "@%:@define HAVE_SQRT 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqrtl in -lm" >&5
+$as_echo_n "checking for sqrtl in -lm... " >&6; }
+if ${ac_cv_lib_m_sqrtl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char sqrtl ();
+int
+main ()
+{
+return sqrtl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_sqrtl=yes
+else
+ ac_cv_lib_m_sqrtl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_sqrtl" >&5
+$as_echo "$ac_cv_lib_m_sqrtl" >&6; }
+if test "x$ac_cv_lib_m_sqrtl" = xyes; then :
+ $as_echo "@%:@define HAVE_SQRTL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sinl in -lm" >&5
+$as_echo_n "checking for sinl in -lm... " >&6; }
+if ${ac_cv_lib_m_sinl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char sinl ();
+int
+main ()
+{
+return sinl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_sinl=yes
+else
+ ac_cv_lib_m_sinl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_sinl" >&5
+$as_echo "$ac_cv_lib_m_sinl" >&6; }
+if test "x$ac_cv_lib_m_sinl" = xyes; then :
+ $as_echo "@%:@define HAVE_SINL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for tanhl in -lm" >&5
+$as_echo_n "checking for tanhl in -lm... " >&6; }
+if ${ac_cv_lib_m_tanhl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char tanhl ();
+int
+main ()
+{
+return tanhl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_tanhl=yes
+else
+ ac_cv_lib_m_tanhl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_tanhl" >&5
+$as_echo "$ac_cv_lib_m_tanhl" >&6; }
+if test "x$ac_cv_lib_m_tanhl" = xyes; then :
+ $as_echo "@%:@define HAVE_TANHL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for tanl in -lm" >&5
+$as_echo_n "checking for tanl in -lm... " >&6; }
+if ${ac_cv_lib_m_tanl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char tanl ();
+int
+main ()
+{
+return tanl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_tanl=yes
+else
+ ac_cv_lib_m_tanl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_tanl" >&5
+$as_echo "$ac_cv_lib_m_tanl" >&6; }
+if test "x$ac_cv_lib_m_tanl" = xyes; then :
+ $as_echo "@%:@define HAVE_TANL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for png_get_pixels_per_inch in -lpng" >&5
+$as_echo_n "checking for png_get_pixels_per_inch in -lpng... " >&6; }
+if ${ac_cv_lib_png_png_get_pixels_per_inch+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpng $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char png_get_pixels_per_inch ();
+int
+main ()
+{
+return png_get_pixels_per_inch ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_png_png_get_pixels_per_inch=yes
+else
+ ac_cv_lib_png_png_get_pixels_per_inch=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_png_png_get_pixels_per_inch" >&5
+$as_echo "$ac_cv_lib_png_png_get_pixels_per_inch" >&6; }
+if test "x$ac_cv_lib_png_png_get_pixels_per_inch" = xyes; then :
+ $as_echo "@%:@define HAVE_PNG_GET_PIXELS_PER_INCH 1" >>confdefs.h
+
+fi
+
+for ac_func in getuid setuid setgid
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in chdir chmod chown
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in opendir readdir closedir
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in getgrent getgrgid getgrnam endgrent setgrent
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in getpwuid getpwnam
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in fopen fclose feof ferror fflush fread fwrite
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in _fclose _feof _ferror _fflush _fopen _fread _fwrite
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in _getenv_s _wgetenv _getpid
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in fetestexcept _clearfp
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in fork getrlimit setpgrp setsid syslog
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in gethostname
+do :
+ ac_fn_c_check_func "$LINENO" "gethostname" "ac_cv_func_gethostname"
+if test "x$ac_cv_func_gethostname" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define HAVE_GETHOSTNAME 1
+_ACEOF
+
+fi
+done
+
+for ac_func in time localtime localtime_s
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in stat stat32 lstat32
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in _stat _stat32 _stat64 _lstat _lstat32 _lstat64
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in mpctl sysconf sysctl
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in popen _popen
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in read write _read _write
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in seed48
+do :
+ ac_fn_c_check_func "$LINENO" "seed48" "ac_cv_func_seed48"
+if test "x$ac_cv_func_seed48" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define HAVE_SEED48 1
+_ACEOF
+
+fi
+done
+
+for ac_func in sprintf_s sscanf_s swscanf_s
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in strcat strchr strcmp strcpy strdup strlen strncmp strncpy _strdup
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in strncpy_s strrchr strtoimax strtol strtoll strtoul strtoull
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in strtoumax
+do :
+ ac_fn_c_check_func "$LINENO" "strtoumax" "ac_cv_func_strtoumax"
+if test "x$ac_cv_func_strtoumax" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define HAVE_STRTOUMAX 1
+_ACEOF
+
+fi
+done
+
+for ac_func in wcsdup wcsncmp wcsncpy wcsncpy_s wcstoimax wcstol wcstoll
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in wcstoul wcstoull wcstoumax
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in _wcscat _wcschr _wcscpy _wcsdup _wcslen _wcsncmp _wcsncpy
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in _wcsrchr
+do :
+ ac_fn_c_check_func "$LINENO" "_wcsrchr" "ac_cv_func__wcsrchr"
+if test "x$ac_cv_func__wcsrchr" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define HAVE__WCSRCHR 1
+_ACEOF
+
+fi
+done
+
+for ac_func in tcflush tcgetattr
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in umask
+do :
+ ac_fn_c_check_func "$LINENO" "umask" "ac_cv_func_umask"
+if test "x$ac_cv_func_umask" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define HAVE_UMASK 1
+_ACEOF
+
+fi
+done
+
+for ac_func in GetFinalPathNameByHandle
+do :
+ ac_fn_c_check_func "$LINENO" "GetFinalPathNameByHandle" "ac_cv_func_GetFinalPathNameByHandle"
+if test "x$ac_cv_func_GetFinalPathNameByHandle" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define HAVE_GETFINALPATHNAMEBYHANDLE 1
+_ACEOF
+
+fi
+done
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking wchar_t" >&5
+$as_echo_n "checking wchar_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <sys/types.h>
+#include <wchar.h>
+
+int
+main ()
+{
+
+ wchar_t chr;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "@%:@define HAVE_WCHAR_T 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking mkdir path mode" >&5
+$as_echo_n "checking mkdir path mode... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+mkdir("test", 0755);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "@%:@define HAVE_MKDIR2 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <db.h>
+
+int
+main ()
+{
+
+DBT k;
+DBT v;
+DBC *cp;
+cp->c_get(cp, &k, &v, DB_FIRST);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ $as_echo "@%:@define HAVE_DB_CURSOR_C_GET 1" >>confdefs.h
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking const" >&5
+$as_echo_n "checking const... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+static char const msg[] = { "Test" };
+
+int
+main ()
+{
+
+fputs(msg, stdout);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "@%:@define HAVE_CONST 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking inline" >&5
+$as_echo_n "checking inline... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+
+inline
+int
+summe(int a, int b)
+{
+ return (a + b);
+}
+
+
+int
+main ()
+{
+
+int i = 5;
+int j = 6;
+int k;
+
+k = summe(i, j);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };FOUNDINLINE="yes"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if [ "X$FOUNDINLINE" = "Xyes" -a "X$USEINLINE" = "Xyes" ]
+then
+ $as_echo "@%:@define HAVE_INLINE 1" >>confdefs.h
+
+fi
+
+if test -b /dev/urandom
+then
+ $as_echo "@%:@define HAVE_DEV_URANDOM 1" >>confdefs.h
+
+fi
+if test -c /dev/urandom
+then
+ $as_echo "@%:@define HAVE_DEV_URANDOM 1" >>confdefs.h
+
+fi
+if test -b /dev/random
+then
+ $as_echo "@%:@define HAVE_DEV_RANDOM 1" >>confdefs.h
+
+fi
+if test -c /dev/random
+then
+ $as_echo "@%:@define HAVE_DEV_RANDOM 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking fpclassify" >&5
+$as_echo_n "checking fpclassify... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#if HAVE_MATH_H
+#include <math.h>
+#endif
+
+int
+main ()
+{
+
+int cl;
+cl = fpclassify(-0.5);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "@%:@define HAVE_FPCLASSIFY 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+for ac_func in getpeername
+do :
+ ac_fn_c_check_func "$LINENO" "getpeername" "ac_cv_func_getpeername"
+if test "x$ac_cv_func_getpeername" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define HAVE_GETPEERNAME 1
+_ACEOF
+
+$as_echo "@%:@define HAVE_GETPEERNAME 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getpeername in -lxnet" >&5
+$as_echo_n "checking for getpeername in -lxnet... " >&6; }
+if ${ac_cv_lib_xnet_getpeername+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lxnet $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getpeername ();
+int
+main ()
+{
+return getpeername ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_xnet_getpeername=yes
+else
+ ac_cv_lib_xnet_getpeername=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xnet_getpeername" >&5
+$as_echo "$ac_cv_lib_xnet_getpeername" >&6; }
+if test "x$ac_cv_lib_xnet_getpeername" = xyes; then :
+
+$as_echo "@%:@define HAVE_GETPEERNAME 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getpeername in -lnsl" >&5
+$as_echo_n "checking for getpeername in -lnsl... " >&6; }
+if ${ac_cv_lib_nsl_getpeername+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getpeername ();
+int
+main ()
+{
+return getpeername ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_nsl_getpeername=yes
+else
+ ac_cv_lib_nsl_getpeername=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_getpeername" >&5
+$as_echo "$ac_cv_lib_nsl_getpeername" >&6; }
+if test "x$ac_cv_lib_nsl_getpeername" = xyes; then :
+
+$as_echo "@%:@define HAVE_GETPEERNAME 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getpeername in -lsocket" >&5
+$as_echo_n "checking for getpeername in -lsocket... " >&6; }
+if ${ac_cv_lib_socket_getpeername+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getpeername ();
+int
+main ()
+{
+return getpeername ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_socket_getpeername=yes
+else
+ ac_cv_lib_socket_getpeername=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_getpeername" >&5
+$as_echo "$ac_cv_lib_socket_getpeername" >&6; }
+if test "x$ac_cv_lib_socket_getpeername" = xyes; then :
+
+$as_echo "@%:@define HAVE_GETPEERNAME 1" >>confdefs.h
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+done
+
+
+for ac_func in getsockname
+do :
+ ac_fn_c_check_func "$LINENO" "getsockname" "ac_cv_func_getsockname"
+if test "x$ac_cv_func_getsockname" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+@%:@define HAVE_GETSOCKNAME 1
+_ACEOF
+
+$as_echo "@%:@define HAVE_GETSOCKNAME 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getsockname in -lxnet" >&5
+$as_echo_n "checking for getsockname in -lxnet... " >&6; }
+if ${ac_cv_lib_xnet_getsockname+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lxnet $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getsockname ();
+int
+main ()
+{
+return getsockname ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_xnet_getsockname=yes
+else
+ ac_cv_lib_xnet_getsockname=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xnet_getsockname" >&5
+$as_echo "$ac_cv_lib_xnet_getsockname" >&6; }
+if test "x$ac_cv_lib_xnet_getsockname" = xyes; then :
+
+$as_echo "@%:@define HAVE_GETSOCKNAME 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getsockname in -lnsl" >&5
+$as_echo_n "checking for getsockname in -lnsl... " >&6; }
+if ${ac_cv_lib_nsl_getsockname+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getsockname ();
+int
+main ()
+{
+return getsockname ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_nsl_getsockname=yes
+else
+ ac_cv_lib_nsl_getsockname=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_getsockname" >&5
+$as_echo "$ac_cv_lib_nsl_getsockname" >&6; }
+if test "x$ac_cv_lib_nsl_getsockname" = xyes; then :
+
+$as_echo "@%:@define HAVE_GETSOCKNAME 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getsockname in -lsocket" >&5
+$as_echo_n "checking for getsockname in -lsocket... " >&6; }
+if ${ac_cv_lib_socket_getsockname+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getsockname ();
+int
+main ()
+{
+return getsockname ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_socket_getsockname=yes
+else
+ ac_cv_lib_socket_getsockname=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_getsockname" >&5
+$as_echo "$ac_cv_lib_socket_getsockname" >&6; }
+if test "x$ac_cv_lib_socket_getsockname" = xyes; then :
+
+$as_echo "@%:@define HAVE_GETSOCKNAME 1" >>confdefs.h
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+done
+
+
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/utilities.h>
+
+int
+main ()
+{
+
+netsnmp_session session, *ss;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+SNMPPROG="snmpprog"
+SNMP_PROG_CLI='$(SNMP_PROG_CLI)'
+$as_echo "@%:@define HAVE_LIBNETSNMP 1" >>confdefs.h
+
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for snmp_enable_filelog in -lnetsnmp" >&5
+$as_echo_n "checking for snmp_enable_filelog in -lnetsnmp... " >&6; }
+if ${ac_cv_lib_netsnmp_snmp_enable_filelog+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnetsnmp $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char snmp_enable_filelog ();
+int
+main ()
+{
+return snmp_enable_filelog ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_netsnmp_snmp_enable_filelog=yes
+else
+ ac_cv_lib_netsnmp_snmp_enable_filelog=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_netsnmp_snmp_enable_filelog" >&5
+$as_echo "$ac_cv_lib_netsnmp_snmp_enable_filelog" >&6; }
+if test "x$ac_cv_lib_netsnmp_snmp_enable_filelog" = xyes; then :
+ SNMPPROG="snmpprog";$as_echo "@%:@define HAVE_SNMP_ENABLE_FILELOG 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for snmp_disable_syslog in -lnetsnmp" >&5
+$as_echo_n "checking for snmp_disable_syslog in -lnetsnmp... " >&6; }
+if ${ac_cv_lib_netsnmp_snmp_disable_syslog+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnetsnmp $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char snmp_disable_syslog ();
+int
+main ()
+{
+return snmp_disable_syslog ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_netsnmp_snmp_disable_syslog=yes
+else
+ ac_cv_lib_netsnmp_snmp_disable_syslog=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_netsnmp_snmp_disable_syslog" >&5
+$as_echo "$ac_cv_lib_netsnmp_snmp_disable_syslog" >&6; }
+if test "x$ac_cv_lib_netsnmp_snmp_disable_syslog" = xyes; then :
+ $as_echo "@%:@define HAVE_SNMP_DISABLE_SYSLOG 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for snmp_disable_stderrlog in -lnetsnmp" >&5
+$as_echo_n "checking for snmp_disable_stderrlog in -lnetsnmp... " >&6; }
+if ${ac_cv_lib_netsnmp_snmp_disable_stderrlog+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnetsnmp $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char snmp_disable_stderrlog ();
+int
+main ()
+{
+return snmp_disable_stderrlog ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_netsnmp_snmp_disable_stderrlog=yes
+else
+ ac_cv_lib_netsnmp_snmp_disable_stderrlog=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_netsnmp_snmp_disable_stderrlog" >&5
+$as_echo "$ac_cv_lib_netsnmp_snmp_disable_stderrlog" >&6; }
+if test "x$ac_cv_lib_netsnmp_snmp_disable_stderrlog" = xyes; then :
+ $as_echo "@%:@define HAVE_SNMP_DISABLE_STDERRLOG 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for snmp_disable_filelog in -lnetsnmp" >&5
+$as_echo_n "checking for snmp_disable_filelog in -lnetsnmp... " >&6; }
+if ${ac_cv_lib_netsnmp_snmp_disable_filelog+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnetsnmp $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char snmp_disable_filelog ();
+int
+main ()
+{
+return snmp_disable_filelog ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_netsnmp_snmp_disable_filelog=yes
+else
+ ac_cv_lib_netsnmp_snmp_disable_filelog=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_netsnmp_snmp_disable_filelog" >&5
+$as_echo "$ac_cv_lib_netsnmp_snmp_disable_filelog" >&6; }
+if test "x$ac_cv_lib_netsnmp_snmp_disable_filelog" = xyes; then :
+ $as_echo "@%:@define HAVE_SNMP_DISABLE_FILELOG 1" >>confdefs.h
+
+fi
+
+IEEE_754_DOUBLE_WISHED='yes'
+IEEE_754_DOUBLE_FOUND='no'
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking IEEE 754 double" >&5
+$as_echo_n "checking IEEE 754 double... " >&6; }
+if test "$cross_compiling" = yes; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no - test not possible" >&5
+$as_echo "no - test not possible" >&6; }
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_STRING_H
+#include <string.h>
+#endif
+#if HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#include <math.h>
+
+static double td[] = {
+ INFINITY,
+ 1234.75,
+ 4.0,
+ 1.0,
+ 0.375,
+ 0.0,
+ -0.625,
+ -1.0,
+ -8.0,
+ -23.875,
+ -INFINITY
+};
+
+#if WORDS_BIGENDIAN
+static unsigned char tuc[] = {
+ /* INF */ 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* 1234.75 */ 0x40, 0x93, 0x4B, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* 4.0 */ 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* 1.0 */ 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* 0.375 */ 0x3F, 0xD8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* 0.0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* -0.625 */ 0xBF, 0xE4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* -1.0 */ 0xBF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* -8.0 */ 0xC0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* -23.875 */ 0xC0, 0x37, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* -INF */ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+#else
+static unsigned char tuc[] = {
+ /* INF */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x7F,
+ /* 1234.75 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x4B, 0x93, 0x40,
+ /* 4.0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40,
+ /* 1.0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F,
+ /* 0.375 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x3F,
+ /* 0.0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* -0.625 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE4, 0xBF,
+ /* -1.0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xBF,
+ /* -8.0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xC0,
+ /* -23.875 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x37, 0xC0,
+ /* -INF */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF
+};
+#endif
+
+static
+#ifdef __cplusplus
+int
+test_double(double *dp, unsigned char *up)
+#else
+int
+test_double(dp, up)
+ double *dp;
+ unsigned char *up;
+#endif
+{
+ int back = 0;
+#if HAVE_MEMCMP
+ if(memcmp(dp, up, 8) == 0) {
+ back = 1;
+ }
+#else
+#if HAVE_BCMP
+ if(bcmp(dp, up, 8) == 0) {
+ back = 1;
+ }
+#else
+ unsigned char *cp1;
+ unsigned char *cp2;
+ size_t i;
+ back = 1;
+ cp1 = (unsigned char *)dp; cp2 = up;
+ for(i = 0; i < 8; i++) {
+ if(*(cp1++) != *(cp2++)) {
+ back = 0;
+ }
+ }
+#endif
+#endif
+ if(1 != back) {
+ printf("ERROR: %lg not conforming to IEEE 754!\n", *dp);
+ }
+ return back;
+}
+
+#ifdef __cplusplus
+int main(int argc, char *argv[])
+#else
+int main(argc, argv)
+ int argc;
+ char *argv[];
+#endif
+{
+ unsigned char *ucp;
+ double *dp;
+ size_t i;
+ int ev = 1;
+
+ if(8 == sizeof(double)) {
+ ev = 0;
+ ucp = tuc; dp = td;
+ for(i = 0; i < (sizeof(td)/sizeof(double)); i++) {
+ if(!test_double(dp, ucp)) {
+ ev = 1;
+ }
+ dp++;
+ ucp += 8;
+ }
+ } else {
+ printf("ERROR: Size of double is not 1!\n");
+ }
+ exit(ev);
+}
+
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };IEEE_754_DOUBLE_FOUND="yes"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; };IEEE_754_DOUBLE_FOUND="no"
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+if [ "X$IEEE_754_DOUBLE_FOUND$IEEE_754_DOUBLE_WISHED" = "Xyesyes" ]
+then
+ $as_echo "@%:@define HAVE_IEEE_754_DOUBLE 1" >>confdefs.h
+
+else
+ IEEE_754_DOUBLE_FOUND='no'
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking isfinite" >&5
+$as_echo_n "checking isfinite... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#if HAVE_MATH_H
+#include <math.h>
+#endif
+
+int
+main ()
+{
+
+ double x;
+ int a = 0;
+ x = 5.0;
+ if (isfinite(x)) {
+ a = 1;
+ }
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "@%:@define HAVE_ISFINITE 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking isnormal" >&5
+$as_echo_n "checking isnormal... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#if HAVE_MATH_H
+#include <math.h>
+#endif
+
+int
+main ()
+{
+
+ double x;
+ int a = 0;
+ x = 5.0;
+ if (isnormal(x)) {
+ a = 1;
+ }
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "@%:@define HAVE_ISNORMAL 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking use of twos complement for negative integers" >&5
+$as_echo_n "checking use of twos complement for negative integers... " >&6; }
+if test "$cross_compiling" = yes; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no - test not possible" >&5
+$as_echo "no - test not possible" >&6; }
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_PROCESS_H
+#include <process.h>
+#endif
+
+int i1 = -1;
+
+#if SIZEOF_INT > 2
+#if SIZEOF_INT > 4
+#if SIZEOF_INT > 8
+#error "No test available yet for integers larger than 8 bytes!"
+#else
+int i2 = 0xFFFFFFFFFFFFFFFF;
+#endif
+#else
+int i2 = 0xFFFFFFFF;
+#endif
+#else
+int i2 = 0xFFFF;
+#endif
+
+int main(int argc, char *argv[])
+{
+ int exval = 1;
+ if (i1 == i2) exval = 0;
+ exit(exval); return exval;
+}
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "@%:@define HAVE_TWOS_COMPLEMENT 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+CLI_SNMPPROG=''
+if [ "X$SNMPPROG" != "X" ]
+then
+ CLI_SNMPPROG='pjsnmp$(EXEEXT)'
+fi
+
+
+CLI_MYSQLPROG=''
+if [ "X$MYSQLPROG" != "X" ]
+then
+ CLI_MYSQLPROG='itadmin$(EXEEXT)'
+ MYSQL_PROG_CLI='$(MYSQL_PROG_CLI)'
+ [ ! -f /usr/lib/mysql/libmysqlclient.so ] || LDFLAGS="$LDFLAGS -L/usr/lib/mysql"
+ [ ! -f /usr/lib/mysql/libmysqlclient.a ] || LDFLAGS="$LDFLAGS -L/usr/lib/mysql"
+ [ ! -f /usr/lib/mysql/libmysqlclient.so ] || MYSQLLDFLAGS="-L/usr/lib/mysql"
+ [ ! -f /usr/lib/mysql/libmysqlclient.a ] || MYSQLLDFLAGS="-L/usr/lib/mysql"
+ [ ! -f /usr/lib64/mysql/libmysqlclient.so ] || LDFLAGS="$LDFLAGS -L/usr/lib64/mysql"
+ [ ! -f /usr/lib64/mysql/libmysqlclient.a ] || LDFLAGS="$LDFLAGS -L/usr/lib64/mysql"
+ [ ! -f /usr/lib64/mysql/libmysqlclient.so ] || MYSQLLDFLAGS="-L/usr/lib64/mysql"
+ [ ! -f /usr/lib64/mysql/libmysqlclient.a ] || MYSQLLDFLAGS="-L/usr/lib64/mysql"
+fi
+
+if [ "X$SUITE" = "Xgui" ]
+then
+ LIBDK3WXOBJ='$(LIBDK3WXOBJ)'
+ LIBDK4WXOBJ='$(LIBDK4WXOBJ)'
+ LIBDK4WXTOBUILD='libdk4wx.$(LIBEXT)'
+fi
+
+
+if [ "X$ENASHARED" = "Xyes" -a "X$USESOLINKING" = "Xyes" ]
+then
+ SOLIBZ="$ZLIB"
+ SOLIBBZ="$BZLIB"
+ SOLIBMATH="-lm"
+ SOLIBCRYPTO="$CRYPTO"
+ SOLIBNET="$NETLIB"
+ SOLIBIMG="$IMGLIBS"
+ SOLIBSDBI="$DKSDBILIBS"
+ SOLIBWX=`wx-config --libs`
+ SOLIBDK3PORT=""
+ SOLIBDK3C="-ldk3c"
+ SOLIBDK3OF="-ldk3of"
+ SOLIBDK3CSRND="-ldk3csrnd"
+ SOLIBDK3BIF="-ldk3bif"
+ SOLIBDK3DBI="-ldk3dbi"
+ SOLIBDK3FIG="-ldk3fig"
+ SOLIBDK3BMEPS="-ldk3bmeps"
+ SOLIBDK3NET="-ldk3net"
+ SOLIBDK4BASE="-ldk4base"
+ SOLIBDK4MA="-ldk4ma"
+ SOLIBDK4MAIO8H="-ldk4maio8h"
+ SOLIBDK4MAIOWH="-ldk4maiowh"
+ SOLIBDK4MAIODH="-ldk4maiodh"
+ SOLIBDK4MAIO8D="-ldk4maio8d"
+ SOLIBDK4MAIOWD="-ldk4maiowd"
+ SOLIBDK4MAIODD="-ldk4maiodd"
+ SOLIBDK4C="-ldk4c"
+ SOLIBDK4MDRND="-ldk4mdrnd"
+ SOLIBDK4PPPT="-ldk4pppt"
+ SOLIBDK4APP="-ldk4app"
+ SOLIBDK4LAT="-ldk4lat"
+ SOLIBDK4SOCK="-ldk4sock"
+ SOLIBDK4SOCKA="-ldk4socka"
+ SOLIBDK4DBI="-ldk4dbi"
+ SOLIBDK4DBIA="-ldk4dbia"
+ LIBDK4MALIBF="libdk4base.so"
+ LIBDK4MALIBS='-ldk4base'
+ LIBDK4MAIO8DLIBF="libdk4base.so libdk4ma.so"
+ LIBDK4MAIO8DLIBS='-ldk4ma -ldk4base'
+ LIBDK4MAIOWDLIBF="libdk4base.so libdk4ma.so"
+ LIBDK4MAIOWDLIBS='-ldk4ma -ldk4base'
+ LIBDK4MAIODDLIBF="libdk4base.so libdk4maio8d.so"
+ LIBDK4MAIODDLIBS='-ldk4maio8d -ldk4base'
+ LIBDK4MAIOXDLIBF="libdk4base.so libdk4maio8d.so libdk4maiowd.so"
+ LIBDK4MAIOXDLIBS='-ldk4maiowd -ldk4maio8d -ldk4base'
+ LIBDK4MAIO8HLIBF="libdk4base.so"
+ LIBDK4MAIO8HLIBS='-ldk4base'
+ LIBDK4MAIOWHLIBF="libdk4base.so"
+ LIBDK4MAIOWHLIBS='-ldk4base'
+ LIBDK4MAIODHLIBF="libdk4base.so libdk4maio8h.so"
+ LIBDK4MAIODHLIBS='-ldk4maio8h -ldk4base'
+ LIBDK4CLIBF="libdk4base.so libdk4ma.so libdk4maio8d.so libdk4maiodd.so"
+ LIBDK4CLIBS='-ldk4maiodd -ldk4maio8d -ldk4ma -ldk4base $(BZLIB) $(ZLIB) -lm'
+ LIBDK4DBILIBF="libdk4base.so libdk4ma.so libdk4c.so"
+ LIBDK4DBILIBS='-ldk4c -ldk4ma -ldk4base $(DBLIB)'
+ LIBDK4SOCKLIBF="libdk4base.so libdk4maio8d.so libdk4c.so"
+ LIBDK4SOCKLIBS='-ldk4c -ldk4maio8d -ldk4base $(SOCKLIB) $(NSLLIB)'
+ LIBDK4MDRNDLIBF="libdk4base.so libdk4c.so"
+ LIBDK4MDRNDLIBS='-ldk4c -ldk4base $(CRYPTO)'
+ LIBDK4PPPTLIBF="libdk4base.so libdk4maiodd.so libdk4c.so"
+ LIBDK4PPPTLIBS='-ldk4c -ldk4maiodd -ldk4base'
+ LIBDK4APPLIBF="libdk4base.so libdk4ma.so libdk4maio8d.so libdk4maiodd.so libdk4c.so"
+ LIBDK4APPLIBS='-ldk4c -ldk4maiodd -ldk4maio8d -ldk4ma -ldk4base'
+ LIBDK4LATLIBF="libdk4base.so libdk4ma.so libdk4maio8h.so libdk4maiodh.so libdk4maiodd.so libdk4c.so libdk4app.so"
+ LIBDK4LATLIBS='-ldk4app -ldk4c -ldk4maiodd -ldk4maiodh -ldk4maio8h -ldk4ma -ldk4base'
+ LIBDK4PPPTALIBF="libdk4base.so libdk4c.so libdk4pppt.so libdk4app.so"
+ LIBDK4PPPTALIBS='-ldk4app -ldk4pppt -ldk4c -ldk4base'
+ LIBDK4SOCKALIBF="libdk4base.so libdk4maio8h.so libdk4maio8d.so libdk4maiodh.so libdk4maiodd.so libdk4sock.so libdk4app.so"
+ LIBDK4SOCKALIBS='-ldk4app -ldk4sock -ldk4maiodd -ldk4maiodh -ldk4maio8d -ldk4maio8h -ldk4base $(SOCKLIB) $(NSLLIB)'
+ LIBDK4DBIALIBF="libdk4base.so libdk4dbi.so libdk4app.so"
+ LIBDK4DBIALIBS='-ldk4dbi -ldk4app -ldk4base $(DBLIB)'
+ LIBDK4WXLIBF="libdk4base.so libdk4maio8d.so libdk4maiowd.so libdk4c.so libdk4app.so"
+ LIBDK4WXLIBS='-ldk4app -ldk4c -ldk4maiowd -ldk4maio8d -ldk4base $(WXLDFLAGS)'
+ LIBDK3TRACELIBF=""
+ LIBDK3TRACELIBS=''
+ LIBDK3CLIBF=""
+ LIBDK3CLIBS='$(BZLIB) $(ZLIB) -lm'
+ LIBDK3OFLIBF="libdk3c.so"
+ LIBDK3OFLIBS='-ldk3c $(BZLIB) $(ZLIB)'
+ LIBDK3CSRNDLIBF="libdk3c.so"
+ LIBDK3CSRNDLIBS='-ldk3c $(CRYPTO)'
+ LIBDK3BIFLIBF="libdk3c.so"
+ LIBDK3BIFLIBS='-ldk3c $(IMGLIBS)'
+ LIBDK3DBILIBF="libdk3c.so"
+ LIBDK3DBILIBS='-ldk3c $(DBLIB)'
+ LIBDK3BMEPSLIBF="libdk3c.so libdk3of.so libdk3bif.so"
+ LIBDK3BMEPSLIBS='-ldk3bif -ldk3of -ldk3c -lm'
+ LIBDK3FIGLIBF="libdk3c.so"
+ LIBDK3FIGLIBS='-ldk3c -lm'
+ LIBDK3WXLIBF="libdk3c.so"
+ LIBDK3WXLIBS='-ldk3c $(WXLDFLAGS)'
+fi
+if [ "X$ENASHARED" = "Xyes" -a "X$USESOLINKING" = "Xyes" -a "X$CROSSCOMPLING" = "Xyes" ]
+then
+ LIBDK4MAIODDLIBF="$LIBDK4MAIODDLIBF libdk4maiowd.so"
+ LIBDK4MAIODDLIBS='-ldk4maiowd $LIBDK4MAIODDLIBS'
+ LIBDK4MAIODHLIBF="$LIBDK4MAIODHLIBF libdk4maiowh.so"
+ LIBDK4MAIODHLIBS='-ldk4maiowh $LIBDK4MAIODHLIBS'
+fi
+
+case "X$ENAPACKAGING/X$USESOLINKING" in
+ "Xyes/Xyes")
+ DKCTLIBF='libdk3c.so'
+ DKCTLIBS='-ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ ADDCTRLDLIBF='libdk3c.so'
+ ADDCTRLDLIBS='-ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKDBTLIBF='libdk3c.so libdk3dbi.so'
+ DKDBTLIBS='-ldk3dbi -ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ ITADMINLIBF='libdk3c.so libdk3of.so'
+ ITADMINLIBS='-ldk3of -ldk3c -lmysqlclient $(CLILIB) $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB)'
+ BMPPLIBF='libdk3c.so libdk3bif.so libdk3of.so libdk3bmeps.so'
+ BMPPLIBS='-ldk3bmeps -ldk3of -ldk3bif -ldk3c $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB) -lm'
+ FIG2LATLIBF='libdk3c.so libdk3bif.so libdk3of.so libdk3bmeps.so libdk3fig.so'
+ FIG2LATLIBS='-ldk3fig -ldk3bmeps -ldk3of -ldk3bif -ldk3c $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB) -lm'
+ HTMLBOOKLIBF='libdk3c.so libdk3bif.so libdk3of.so libdk3bmeps.so'
+ HTMLBOOKLIBS='-ldk3bmeps -ldk3of -ldk3bif -ldk3c $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+ DK3INFOLIBF='libdk3c.so'
+ DK3INFOLIBS='-ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ PLPDFTEXLIBF='libdk3c.so libdk3bif.so libdk3of.so libdk3bmeps.so'
+ PLPDFTEXLIBS='-ldk3bmeps -ldk3of -ldk3bif -ldk3c $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB) -lm'
+ DKWXWIZLIBF='libdk3c.so'
+ DKWXWIZLIBS='-ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ WXDKCTLIBF='libdk3c.so libdk3wx.so'
+ WXDKCTLIBS='-ldk3wx -ldk3c $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+ WXBMPPLIBF='libdk3c.so libdk3bif.so libdk3of.so libdk3bmeps.so libdk3wx.so'
+ WXBMPPLIBS='-ldk3wx -ldk3bmeps -ldk3of -ldk3bif -ldk3c $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+ WXIMGSZLIBF='libdk3c.so libdk3wx.so'
+ WXIMGSZLIBS='-ldk3wx -ldk3c $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+ WXDKCLOCKLIBF='libdk3c.so libdk3wx.so'
+ WXDKCLOCKLIBS='-ldk3wx -ldk3c $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+ WXDKHTBLIBF='libdk3c.so libdk3wx.so'
+ WXDKHTBLIBS='-ldk3wx -ldk3c $(WXLDFLAGS) $(GUILIB) $(CLILIB) $(BZLIB) $(ZLIB)'
+ PRINTQDILIBF='libdk3c.so libdk3dbi.so'
+ PRINTQDILIBS='-ldk3dbi -ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ PRINTQDALIBF='libdk3c.so'
+ PRINTQDALIBS='-ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKCATLIBF='libdk4base.so libdk4c.so libdk4maiodd.so libdk4app.so'
+ DKCATLIBS='-ldk4app -ldk4maiodd -ldk4maio8d -ldk4c -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKBLKSLIBF='libdk4base.so libdk4c.so libdk4app.so'
+ DKBLKSLIBS='-ldk4app -ldk4c -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKSQLSPLITLIBF='libdk4base.so libdk4c.so libdk4app.so'
+ DKSQLSPLITLIBS='-ldk4app -ldk4c -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKERADISKLIBF='libdk4base.so libdk4c.so libdk4app.so'
+ DKERADISKLIBS='-ldk4app -ldk4c -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKLSLIBF='libdk4base.so libdk4c.so libdk4app.so libdk4mdrnd.so'
+ DKLSLIBS='-ldk4app -ldk4maiodd -ldk4maiodh -ldk4ma -ldk4mdrnd -ldk4c -ldk4base $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKSORTLIBF='libdk4base.so libdk4maiodd.so libdk4maiodh.so libdk4c.so libdk4app.so'
+ DKSORTLIBS='-ldk4app -ldk4c -ldk4maiodh -ldk4maiodd -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKFICLIBF='libdk4base.so libdk4ma.so libdk4maiodd.so libdk4c.so libdk4app.so libdk4mdrnd.so'
+ DKFICLIBS='-ldk4app -ldk4mdrnd -ldk4c -ldk4maiodd -ldk4ma -ldk4base $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKUIDLIBF='libdk4base.so libdk4ma.so libdk4maiodd.so libdk4c.so libdk4app.so'
+ DKUIDLIBS='-ldk4app -ldk4c -ldk4maiodd -ldk4ma -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKPWGENLIBF='libdk4base.so libdk4ma.so libdk4maiodd.so libdk4c.so libdk4app.so libdk4mdrnd.so'
+ DKPWGENLIBS='-ldk4app -ldk4mdrnd -ldk4c -ldk4maiodd -ldk4ma -ldk4base $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKRANDLIBF='libdk4base.so libdk4c.so libdk4app.so libdk4mdrnd.so'
+ DKRANDLIBS='-ldk4app -ldk4mdrnd -ldk4c -ldk4base $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKT2HLIBF='libdk4base.so libdk4maio8d.so libdk4maio8h.so libdk4maiodd.so libdk4c.so libdk4app.so'
+ DKT2HLIBS='-ldk4app -ldk4c -ldk4maiodd -ldk4maio8h -ldk4maio8d -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKT2LLIBF='libdk4base.so libdk4maiodd.so libdk4maiodh.so libdk4c.so libdk4app.so libdk4lat.so'
+ DKT2LLIBS='-ldk4lat -ldk4app -ldk4c -ldk4maiodh -ldk4maiodd -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKHEXLIBF='libdk4base.so libdk4c.so libdk4app.so libdk4maiodh.so'
+ DKHEXLIBS='-ldk4app -ldk4maiodh -ldk4c -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKBMMLIBF='libdk4base.so libdk4maio8d.so libdk4maiodd.so libdk4c.so libdk4app.so'
+ DKBMMLIBS='-ldk4app -ldk4c -ldk4maiodd -ldk4maio8d -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKPWDLIBF='libdk4base.so libdk4c.so libdk4app.so'
+ DKPWDLIBS='-ldk4app -ldk4c -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKRECVLIBF='libdk4base.so libdk4c.so libdk4sock.so libdk4app.so libdk4socka.so libdk4maiodd.so'
+ DKRECVLIBS='-ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4base $(CLILIB) $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) -lm'
+ DKSENDLIBF='libdk4base.so libdk4c.so libdk4sock.so libdk4app.so libdk4socka.so libdk4maiodd.so'
+ DKSENDLIBS='-ldk4maiodd -ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4base $(CLILIB) $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) -lm'
+ DKDBT2LIBF='libdk4base.so libdk4ma.so libdk4maiodd.so libdk4c.so libdk4dbi.so libdk4app.so libdk4dbia.so'
+ DKDBT2LIBS='-ldk4dbia -ldk4app -ldk4dbi -ldk4c -ldk4maiodd -ldk4ma -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DK4INFOLIBF='libdk4base.so libdk4maiodd.so libdk4c.so libdk4app.so'
+ DK4INFOLIBS='-ldk4app -ldk4c -ldk4maiodd -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ LPRNGCLLIBF='libdk4base.so libdk4c.so libdk4sock.so libdk4mdrnd.so libdk4app.so libdk4socka.so'
+ LPRNGCLLIBS='-ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4base $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) -lm'
+ WXDKFCSLIBF='libdk4base.so libdk4c.so libdk4mdrnd.so libdk4sock.so libdk4app.so libdk4socka.so libdk4wx.so'
+ WXDKFCSLIBS='-ldk4wx -ldk4socka -ldk4app -ldk4sock -ldk4mdrnd -ldk4c -ldk4base $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+ WXPQDICLIBF='libdk4base.so libdk4ma.so libdk4maio8d.so libdk4maiowd.so libdk4c.so libdk4sock.so libdk4app.so libdk4socka.so libdk4wx.so'
+ WXPQDICLIBS='-ldk4wx -ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4maiowd -ldk4maio8d -ldk4ma -ldk4base $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+ PJSNMPLIBF='libdk4base.so libdk4maio8h.so libdk4maio8d.so libdk4ma.so libdk4c.so libdk4sock.so libdk4app.so libdk4socka.so'
+ PJSNMPLIBS='-ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4ma -ldk4maio8d -ldk4maio8h -ldk4base $(NETSNMP_LIBS) $(SOCKLIB) $(NSLLIB)'
+ PRMONSNMPLIBF='libdk4base.so libdk4maio8h.so libdk4maio8d.so libdk4c.so libdk4sock.so libdk4app.so libdk4socka.so'
+ PRMONSNMPLIBS='-ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4maio8h -ldk4maio8d -ldk4base $(NETSNMP_LIBS) $(SOCKLIB) $(NSLLIB)'
+ PRINTQDLIBF='libdk4base.so libdk4maio8d.so libdk4c.so libdk4dbi.so libdk4sock.so'
+ PRINTQDLIBS='-ldk4sock -ldk4dbi -ldk4c -ldk4maio8d -ldk4base $(SOCKLIB) $(NSLLIB)'
+ PRINTQDCLIBF='libdk4base.so libdk4maio8d.so libdk4c.so libdk4sock.so libdk4app.so libdk4socka.so'
+ PRINTQDCLIBS='-ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4maio8d -ldk4base $(SOCKLIB) $(NSLLIB)'
+ RSHDOWNLIBF='libdk4base.so libdk4maio8d.so libdk4c.so libdk4sock.so'
+ RSHDOWNLIBS='-ldk4sock -ldk4c -ldk4maio8d -ldk4base $(SOCKLIB) $(NSLLIB)'
+ ;;
+ "Yyes/Xno")
+ DKCTLIBF='libdk3c.so'
+ DKCTLIBS='-ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ ADDCTRLDLIBF='libdk3c.so'
+ ADDCTRLDLIBS='-ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKDBTLIBF='libdk3c.so libdk3dbi.so'
+ DKDBTLIBS='-ldk3dbi -ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ ITADMINLIBF='libdk3c.so libdk3of.so'
+ ITADMINLIBS='-ldk3of -ldk3c -lmysqlclient $(CLILIB) $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB)'
+ BMPPLIBF='libdk3c.so libdk3bif.so libdk3of.so libdk3bmeps.so'
+ BMPPLIBS='-ldk3bmeps -ldk3of -ldk3bif -ldk3c $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB) -lm'
+ FIG2LATLIBF='libdk3c.so libdk3bif.so libdk3of.so libdk3bmeps.so libdk3fig.so'
+ FIG2LATLIBS='-ldk3fig -ldk3bmeps -ldk3of -ldk3bif -ldk3c $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB) -lm'
+ HTMLBOOKLIBF='libdk3c.so libdk3bif.so libdk3of.so libdk3bmeps.so'
+ HTMLBOOKLIBS='-ldk3bmeps -ldk3of -ldk3bif -ldk3c $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+ DK3INFOLIBF='libdk3c.so'
+ DK3INFOLIBS='-ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ PLPDFTEXLIBF='libdk3c.so libdk3bif.so libdk3of.so libdk3bmeps.so'
+ PLPDFTEXLIBS='-ldk3bmeps -ldk3of -ldk3bif -ldk3c $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB) -lm'
+ DKWXWIZLIBF='libdk3c.so'
+ DKWXWIZLIBS='-ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ WXDKCTLIBF='libdk3c.so libdk3wx.so'
+ WXDKCTLIBS='-ldk3wx -ldk3c $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+ WXBMPPLIBF='libdk3c.so libdk3bif.so libdk3of.so libdk3bmeps.so libdk3wx.so'
+ WXBMPPLIBS='-ldk3wx -ldk3bmeps -ldk3of -ldk3bif -ldk3c $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+ WXIMGSZLIBF='libdk3c.so libdk3wx.so'
+ WXIMGSZLIBS='-ldk3wx -ldk3c $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+ WXDKCLOCKLIBF='libdk3c.so libdk3wx.so'
+ WXDKCLOCKLIBS='-ldk3wx -ldk3c $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+ WXDKHTBLIBF='libdk3c.so libdk3wx.so'
+ WXDKHTBLIBS='-ldk3wx -ldk3c $(WXLDFLAGS) $(GUILIB) $(CLILIB) $(BZLIB) $(ZLIB)'
+ PRINTQDILIBF='libdk3c.so libdk3dbi.so'
+ PRINTQDILIBS='-ldk3dbi -ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ PRINTQDALIBF='libdk3c.so'
+ PRINTQDALIBS='-ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKCATLIBF='libdk4base.so libdk4c.so libdk4app.so'
+ DKCATLIBS='-ldk4app -ldk4c -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKBLKSLIBF='libdk4base.so libdk4c.so libdk4app.so'
+ DKBLKSLIBS='-ldk4app -ldk4c -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKSQLSPLITLIBF='libdk4base.so libdk4c.so libdk4app.so'
+ DKSQLSPLITLIBS='-ldk4app -ldk4c -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKERADISKLIBF='libdk4base.so libdk4c.so'
+ DKERADISKLIBS='-ldk4c -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKLSLIBF='libdk4base.so libdk4c.so libdk4app.so libdk4mdrnd.so'
+ DKLSLIBS='-ldk4app -ldk4mdrnd -ldk4c -ldk4base $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKSORTLIBF='libdk4base.so libdk4maiodd.so libdk4maiodh.so libdk4c.so libdk4app.so'
+ DKSORTLIBS='-ldk4app -ldk4c -ldk4maiodh -ldk4maiodd -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKFICLIBF='libdk4base.so libdk4ma.so libdk4maiodd.so libdk4c.so libdk4app.so libdk4mdrnd.so'
+ DKFICLIBS='-ldk4app -ldk4mdrnd -ldk4c -ldk4maiodd -ldk4ma -ldk4base $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKUIDLIBF='libdk4base.so libdk4ma.so libdk4maiodd.so libdk4c.so libdk4app.so'
+ DKUIDLIBS='-ldk4app -ldk4c -ldk4maiodd -ldk4ma -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKPWGENLIBF='libdk4base.so libdk4ma.so libdk4maiodd.so libdk4c.so libdk4app.so libdk4mdrnd.so'
+ DKPWGENLIBS='-ldk4app -ldk4mdrnd -ldk4c -ldk4maiodd -ldk4ma -ldk4base $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKRANDLIBF='libdk4base.so libdk4c.so libdk4app.so libdk4mdrnd.so'
+ DKRANDLIBS='-ldk4app -ldk4mdrnd -ldk4c -ldk4base $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKT2HLIBF='libdk4base.so libdk4maio8d.so libdk4maio8h.so libdk4maiodd.so libdk4c.so libdk4app.so'
+ DKT2HLIBS='-ldk4app -ldk4c -ldk4maiodd -ldk4maio8h -ldk4maio8d -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKT2LLIBF='libdk4base.so libdk4maiodd.so libdk4maiodh.so libdk4c.so libdk4app.so libdk4lat.so'
+ DKT2LLIBS='-ldk4lat -ldk4app -ldk4c -ldk4maiodh -ldk4maiodd -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKHEXLIBF='libdk4base.so libdk4c.so libdk4app.so'
+ DKHEXLIBS='-ldk4app -ldk4c -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKBMMLIBF='libdk4base.so libdk4maio8d.so libdk4maiodd.so libdk4c.so libdk4app.so'
+ DKBMMLIBS='-ldk4app -ldk4c -ldk4maiodd -ldk4maio8d -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKPWDLIBF='libdk4base.so libdk4c.so libdk4app.so'
+ DKPWDLIBS='-ldk4app -ldk4c -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKRECVLIBF='libdk4base.so libdk4c.so libdk4sock.so libdk4app.so libdk4socka.so'
+ DKRECVLIBS='-ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4base $(CLILIB) $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) -lm'
+ DKSENDLIBF='libdk4base.so libdk4c.so libdk4sock.so libdk4app.so libdk4socka.so libdk4maiodd.so'
+ DKSENDLIBS='-ldk4maiodd -ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4base $(CLILIB) $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) -lm'
+ DKDBT2LIBF='libdk4base.so libdk4ma.so libdk4maiodd.so libdk4c.so libdk4dbi.so libdk4app.so libdk4dbia.so'
+ DKDBT2LIBS='-ldk4dbia -ldk4app -ldk4dbi -ldk4c -ldk4maiodd -ldk4ma -ldk4base $(DBLIBSOCK) $(CLILIB) $(BZLIB) $(ZLIB)'
+ DK4INFOLIBF='libdk4base.so libdk4maiodd.so libdk4c.so libdk4app.so'
+ DK4INFOLIBS='-ldk4app -ldk4c -ldk4maiodd -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ LPRNGCLLIBF='libdk4base.so libdk4c.so libdk4sock.so libdk4mdrnd.so libdk4app.so libdk4socka.so'
+ LPRNGCLLIBS='-ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4base $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) -lm'
+ WXDKFCSLIBF='libdk4base.so libdk4c.so libdk4mdrnd.so libdk4sock.so libdk4app.so libdk4socka.so libdk4wx.so'
+ WXDKFCSLIBS='-ldk4wx -ldk4socka -ldk4app -ldk4sock -ldk4mdrnd -ldk4c -ldk4base $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+ WXPQDICLIBF='libdk4base.so libdk4ma.so libdk4maio8d.so libdk4maiowd.so libdk4c.so libdk4sock.so libdk4app.so libdk4socka.so libdk4wx.so'
+ WXPQDICLIBS='-ldk4wx -ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4maiowd -ldk4maio8d -ldk4ma -ldk4base $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+ PJSNMPLIBF='libdk4base.so libdk4maio8h.so libdk4maio8d.so libdk4ma.so libdk4c.so libdk4sock.so libdk4app.so libdk4socka.so'
+ PJSNMPLIBS='-ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4ma -ldk4maio8d -ldk4maio8h -ldk4base $(NETSNMP_LIBS) $(SOCKLIB) $(NSLLIB)'
+ PRMONSNMPLIBF='libdk4base.so libdk4maio8d.so libdk4maio8h.so libdk4c.so libdk4sock.so libdk4app.so libdk4socka.so'
+ PRMONSNMPLIBS='-ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4maio8h -ldk4maio8d -ldk4base $(NETSNMP_LIBS) $(SOCKLIB) $(NSLLIB)'
+ PRINTQDLIBF='libdk4base.so libdk4maio8d.so libdk4c.so libdk4dbi.so libdk4sock.so'
+ PRINTQDLIBS='-ldk4sock -ldk4dbi -ldk4c -ldk4maio8d -ldk4base $(DBLIB) $(SOCKLIB) $(NSLLIB)'
+ PRINTQDCLIBF='libdk4base.so libdk4maio8d.so libdk4c.so libdk4sock.so libdk4app.so libdk4socka.so'
+ PRINTQDCLIBS='-ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4maio8d -ldk4base $(SOCKLIB) $(NSLLIB)'
+ RSHDOWNLIBF='libdk4base.so libdk4maio8d.so libdk4c.so libdk4sock.so'
+ RSHDOWNLIBS='-ldk4sock -ldk4c -ldk4maio8d -ldk4base $(SOCKLIB) $(NSLLIB)'
+ ;;
+esac
+
+if [ "X$WGET" != "X" ]
+then
+ GETSOURCE='wget -O dktools-$(VERSNO) $(SFBASE)/dktools-$(VERSNO).tar.gz/download'
+elif [ "X$CURL" != "X" ]
+then
+ GETSOURCE='curl -L $(SFBASE)/dktools-$(VERSNO).tar.gz > dktools-$(VERSNO).tar.gz'
+fi
+
+if [ "X$UNAME" = "XSunOS" -a "X$SOLCOR" = "Xyes" ]
+then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking CFLAGS on Solaris" >&5
+$as_echo_n "checking CFLAGS on Solaris... " >&6; }
+ NETSNMP_LIBS=`echo $NETSNMP_LIBS | sed -f modsnmp.sed`
+ TMPVAR="$WXCPPFLAGS"
+ WXCPPFLAGS=''
+ for i in NOTHING $TMPVAR
+ do
+ case "X$i" in
+ "X-D*")
+ WXCPPFLAGS="$WXCPPFLAGS $i"
+ ;;
+ "X-I*")
+ WXCPPFLAGS="$WXCPPFLAGS $i"
+ ;;
+ esac
+ done
+ TMPVAR="$WXCXXFLAGS"
+ WXCXXFLAGS=''
+ for i in NOTHING $TMPVAR
+ do
+ case "X$i" in
+ "X-D*")
+ WXCXXFLAGS="$WXCXXFLAGS $i"
+ ;;
+ "X-I*")
+ WXCXXFLAGS="$WXCXXFLAGS $i"
+ ;;
+ "X-pthread")
+ WXCXXFLAGS="$WXCXXFLAGS $i"
+ ;;
+ esac
+ done
+ TMPVAR="$WXCFLAGS"
+ WXCFLAGS=''
+ for i in NOTHING $TMPVAR
+ do
+ case "X$i" in
+ "X-D*")
+ WXCFLAGS="$WXCFLAGS $i"
+ ;;
+ "X-I*")
+ WXCFLAGS="$WXCFLAGS $i"
+ ;;
+ "X-pthread")
+ WXCFLAGS="$WXCFLAGS $i"
+ ;;
+ esac
+ done
+ TMPVAR="$WXLDFLAGS"
+ WXLDFLAGS=''
+ for i in NOTHING $TMPVAR
+ do
+ case "X$i" in
+ "X-L*")
+ WXLDFLAGS="$WXLDFLAGS $i"
+ ;;
+ "X-l*")
+ WXLDFLAGS="$WXLDFLAGS $i"
+ ;;
+ "X-pthread")
+ WXLDFLAGS="$WXLDFLAGS $i"
+ ;;
+ esac
+ done
+ SOCKLIB='-lsocket'
+ NSLLIB='-lnsl'
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
+$as_echo "done" >&6; }
+fi
+
+if [ "X$ONWINDOWS" != "Xno" ]
+then
+ CLILIB='$(WINCLILIB)'
+ GUILIB='$(WINGUILIB)'
+ ENTRY='$(WINENTRY)'
+else
+ $as_echo "@%:@define HAVE_INODES 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking manpage installation" >&5
+$as_echo_n "checking manpage installation... " >&6; }
+case "X$MANINST" in
+ "Xauto")
+ if uname -a | grep -q Debian
+ then
+ MANINST='no'
+ else
+ MANINST='yes'
+ fi
+ ;;
+esac
+if [ "X$MANINST" = "Xno" ]
+then
+ INSTALLMANPAGES=''
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANINST" >&5
+$as_echo "$MANINST" >&6; }
+
+DBLIBSOCK="$DBLIB"
+
+if [ "X$UNAME" = "XSunOS" -a "X$SOLCOR" = "Xyes" ]
+then
+ [ "X$DBLIBSOCK" = "X" ] || DBLIBSOCK="$DBLIBSOCK -lrt "'$(SOCKLIB)'
+ [ "X$DBLIB" = "X" ] || DBLIB="$DBLIB -lrt "
+ [ "X$CRYPTO" = "X" ] || CRYPTO="$CRYPTO -lssl "'$(SOCKLIB)'
+ [ "X$MYSQLLIB" = "X" ] || MYSQLLIB="$MYSQLLIB -lrt "'$(SOCKLIB)'
+fi
+
+LIBSPRIVATE="$CRYPTO $MYSQLLIB $DBLIB $LIBTIFF $LIBJPEG $BZLIB"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ac_config_files="$ac_config_files Makefile scripts/wr-dk3inst.sh scripts/wr-dk4inst.sh scripts/create-desktop-files.sh scripts/build-help.sh initd-printqd dktools.pc pkginfo debian/control"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+
+ (set) 2>&1 |
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ # `set' does not quote correctly, so add quotes: double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \.
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;; #(
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+) |
+ sed '
+ /^ac_cv_env_/b end
+ t clear
+ :clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ if test "x$cache_file" != "x/dev/null"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+ if test ! -f "$cache_file" || test -h "$cache_file"; then
+ cat confcache >"$cache_file"
+ else
+ case $cache_file in #(
+ */* | ?:*)
+ mv -f confcache "$cache_file"$$ &&
+ mv -f "$cache_file"$$ "$cache_file" ;; #(
+ *)
+ mv -f confcache "$cache_file" ;;
+ esac
+ fi
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIB@&t@OBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+ ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIB@&t@OBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in @%:@(
+ *posix*) :
+ set -o posix ;; @%:@(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in @%:@(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in @%:@((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+@%:@ as_fn_error STATUS ERROR [LINENO LOG_FD]
+@%:@ ----------------------------------------
+@%:@ Output "`basename @S|@0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+@%:@ provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+@%:@ script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} @%:@ as_fn_error
+
+
+@%:@ as_fn_set_status STATUS
+@%:@ -----------------------
+@%:@ Set @S|@? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} @%:@ as_fn_set_status
+
+@%:@ as_fn_exit STATUS
+@%:@ -----------------
+@%:@ Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} @%:@ as_fn_exit
+
+@%:@ as_fn_unset VAR
+@%:@ ---------------
+@%:@ Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+@%:@ as_fn_append VAR VALUE
+@%:@ ----------------------
+@%:@ Append the text in VALUE to the end of the definition contained in VAR. Take
+@%:@ advantage of any shell optimizations that allow amortized linear growth over
+@%:@ repeated appends, instead of the typical quadratic growth present in naive
+@%:@ implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+@%:@ as_fn_arith ARG...
+@%:@ ------------------
+@%:@ Perform arithmetic evaluation on the ARGs, and store the result in the
+@%:@ global @S|@as_val. Take advantage of shells that can avoid forks. The arguments
+@%:@ must be portable across @S|@(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in @%:@(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+@%:@ as_fn_mkdir_p
+@%:@ -------------
+@%:@ Create "@S|@as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} @%:@ as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+
+@%:@ as_fn_executable_p FILE
+@%:@ -----------------------
+@%:@ Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} @%:@ as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.69. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration. Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ --config print configuration, then exit
+ -q, --quiet, --silent
+ do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+ --header=FILE[:TEMPLATE]
+ instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Report bugs to the package provider."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.69,
+ with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=?*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ --*=)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ $as_echo "$ac_cs_version"; exit ;;
+ --config | --confi | --conf | --con | --co | --c )
+ $as_echo "$ac_cs_config"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ '') as_fn_error $? "missing file argument" ;;
+ esac
+ as_fn_append CONFIG_FILES " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --he | --h)
+ # Conflict between --help and --header
+ as_fn_error $? "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+ --help | --hel | -h )
+ $as_echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+ *) as_fn_append ac_config_targets " $1"
+ ac_need_defaults=false ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+ set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ shift
+ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+ CONFIG_SHELL='$SHELL'
+ export CONFIG_SHELL
+ exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../@%:@@%:@ /;s/...$/ @%:@@%:@/;p;x;p;x' <<_ASBOX
+@%:@@%:@ Running $as_me. @%:@@%:@
+_ASBOX
+ $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+ "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "scripts/wr-dk3inst.sh") CONFIG_FILES="$CONFIG_FILES scripts/wr-dk3inst.sh" ;;
+ "scripts/wr-dk4inst.sh") CONFIG_FILES="$CONFIG_FILES scripts/wr-dk4inst.sh" ;;
+ "scripts/create-desktop-files.sh") CONFIG_FILES="$CONFIG_FILES scripts/create-desktop-files.sh" ;;
+ "scripts/build-help.sh") CONFIG_FILES="$CONFIG_FILES scripts/build-help.sh" ;;
+ "initd-printqd") CONFIG_FILES="$CONFIG_FILES initd-printqd" ;;
+ "dktools.pc") CONFIG_FILES="$CONFIG_FILES dktools.pc" ;;
+ "pkginfo") CONFIG_FILES="$CONFIG_FILES pkginfo" ;;
+ "debian/control") CONFIG_FILES="$CONFIG_FILES debian/control" ;;
+
+ *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp= ac_tmp=
+ trap 'exit_status=$?
+ : "${ac_tmp:=$tmp}"
+ { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+ trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+ eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+ ac_cs_awk_cr='\\r'
+else
+ ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+ echo "cat >conf$$subs.awk <<_ACEOF" &&
+ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+ echo "_ACEOF"
+} >conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ . ./conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+ if test $ac_delim_n = $ac_delim_num; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+ N
+ s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = ""
+
+}
+{
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{
+h
+s///
+s/^/:/
+s/[ ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[ ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+ ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
+ if test -z "$ac_tt"; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any. Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[ ]*#[ ]*define[ ][ ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ for (key in D) D_is_set[key] = 1
+ FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+ line = \$ 0
+ split(line, arg, " ")
+ if (arg[1] == "#") {
+ defundef = arg[2]
+ mac1 = arg[3]
+ } else {
+ defundef = substr(arg[1], 2)
+ mac1 = arg[2]
+ }
+ split(mac1, mac2, "(") #)
+ macro = mac2[1]
+ prefix = substr(line, 1, index(line, defundef) - 1)
+ if (D_is_set[macro]) {
+ # Preserve the white space surrounding the "#".
+ print prefix "define", macro P[macro] D[macro]
+ next
+ } else {
+ # Replace #undef with comments. This is necessary, for example,
+ # in the case of _POSIX_SOURCE, which is predefined and required
+ # on some systems where configure will not decide to define it.
+ if (defundef == "undef") {
+ print "/*", prefix defundef, macro, "*/"
+ next
+ }
+ }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS "
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$ac_tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+ esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ as_fn_append ac_file_inputs " '$ac_f'"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input='Generated from '`
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+ fi
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`$as_echo "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$ac_tmp/stdin" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir="$ac_dir"; as_fn_mkdir_p
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+ esac
+ ac_MKDIR_P=$MKDIR_P
+ case $MKDIR_P in
+ [\\/$]* | ?:[\\/]* ) ;;
+ */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+ esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \
+ "$ac_tmp/out"`; test -z "$ac_out"; } &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&2;}
+
+ rm -f "$ac_tmp/stdin"
+ case $ac_file in
+ -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+ *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+ esac \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+ :H)
+ #
+ # CONFIG_HEADER
+ #
+ if test x"$ac_file" != x-; then
+ {
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
+ } >"$ac_tmp/config.h" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ rm -f "$ac_file"
+ mv "$ac_tmp/config.h" "$ac_file" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ fi
+ else
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
+ || as_fn_error $? "could not create -" "$LINENO" 5
+ fi
+ ;;
+
+
+ esac
+
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+ as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
+
+chmod 755 scripts/*.sh
+
+cp debian/dktools-lib.install.in debian/dktools-lib-${SOVERS}.install
+cp debian/dktools-lib.postinst.in debian/dktools-lib-${SOVERS}.postinst
+cp debian/dktools-lib.postrm.in debian/dktools-lib-${SOVERS}.postrm
+cp debian/dktools-lib-dev.install.in debian/dktools-lib-${SOVERS}-dev.install
+echo package-name-doesnt-match-sonames > debian/dktools-lib-${SOVERS}.lintian-overrides
+chmod 644 debian/dktools-lib-${SOVERS}.install
+chmod 644 debian/dktools-lib-${SOVERS}.postinst
+chmod 644 debian/dktools-lib-${SOVERS}.postrm
+chmod 644 debian/dktools-lib-${SOVERS}-dev.install
+chmod 644 debian/dktools-lib-${SOVERS}.lintian-overrides
+
+[ ! -f dk4config ] || rm -f dk4config
+[ ! -f dk4config.o ] || rm -f dk4config.o
+[ ! -f dk3config ] || rm -f dk3config
+[ ! -f dk3config.o ] || rm -fr dk3config.o
+[ ! -f wxcs ] || rm -f wxcs
+[ ! -f wxcs.o ] || rm -fr wxcs.o
+
+if [ "X$build" != "X$host" ]
+then
+ cp dk3conf.cross dk3conf.h
+ cp dk4conf.cross dk4conf.h
+ cp dk4wxcs.cross dk4wxcs.h
+ echo 'ERROR: Cross-compiling not supported!'
+elif [ "X$SUITE" = "Xgui" ]
+then
+ echo 'Build dk4config (C++)'
+ $MAKE dk4config
+ echo 'Build dk3config (C)'
+ $MAKE dk3config
+ echo 'Build wxcs (C++)'
+ $MAKE wxcs
+ echo 'Generating configuration files'
+ ./dk4config > dk4conf.h
+ ./dk3config > dk3conf.h
+ ./wxcs > dk4wxcs.h
+elif [ "X$CXX" != "X" ]
+then
+ echo 'Build dk4config (C++)'
+ $MAKE dk4config
+ echo 'Build dk3config (C)'
+ $MAKE dk3config
+ echo 'Generating configuration files'
+ cp dk4wxcs.cross dk4wxcs.h
+ ./dk4config > dk4conf.h
+ ./dk3config > dk3conf.h
+else
+ sed -f mod-dkconfig.sed < dk4config.cpp > dk4config.c
+ mv dk4config.cpp dk4config.cpp.bck
+ echo 'Build dk4config (C)'
+ $MAKE dk4config
+ echo 'Build dk3config (C)'
+ $MAKE dk3config
+ mv dk4config.cpp.bck dk4config.cpp
+ rm dk4config.c
+ echo 'Generating configuration files'
+ cp dk4wxcs.cross dk4wxcs.h
+ ./dk4config > dk4conf.h
+ ./dk3config > dk3conf.h
+fi
+sed -e 's/DK4/DK3/g' < dk4wxcs.h > dk3wxcs.h
+
+chmod 755 scripts/wr-dk4inst.sh
+echo './scripts/wr-dk4inst.sh > dk4inst.c'
+./scripts/wr-dk4inst.sh
+chmod 755 scripts/wr-dk3inst.sh
+./scripts/wr-dk3inst.sh > dk3inst.c
+chmod 755 scripts/create-desktop-files.sh
+./scripts/create-desktop-files.sh
+
+VERSNO=`cat version.txt`
+cat > dk4vers.h <<EOF
+#ifndef DK4VERS_H_INCLUDED
+#define DK4VERS_H_INCLUDED 1
+
+/** @file dk4vers.h Version number as text string.
+*/
+
+/** Version number in 8 bit characters.
+*/
+#define DKT_VERSION_C8 "$VERSNO"
+
+/** Version number in dkChar.
+*/
+#define DKT_VERSION_DK dkT("$VERSNO")
+
+#endif
+EOF
+
+cat > dk4verswx.h <<EOF
+#ifndef DK4VERSWX_H_INCLUDED
+/** Protection against multiple inclusions. */
+#define DK4VERSWX_H_INCLUDED 1
+/** @file dk4verswx.h Version number as wxChar string.
+*/
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include "wx/wxprec.h"
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#ifndef WX_WX_H_INCLUDED
+#include "wx/wx.h"
+#define WX_WX_H_INCLUDED 1
+#endif
+#endif
+
+/** Version number as wxChar string.
+*/
+#define DKT_VERSION_WX wxT("$VERSNO")
+
+#endif
+EOF
+
+echo ''
+echo 'Configuration summary'
+echo '====================='
+if [ "X$ZLIB" = "X-lz" ]
+then
+echo 'zlib: found.'
+else
+echo 'zlib: NOT found! Required!'
+echo ' SL 6.x package name: zlib-devel'
+echo ' Debian package name: libz-dev'
+echo ' URL: http://www.zlib.net'
+EXVAL=1
+fi
+if [ "X-lbz2" = "X$BZLIB" ]
+then
+echo 'libbz2: found.'
+else
+echo 'libbz2: NOT found! Recommended.'
+echo ' Bzip compression not available.'
+echo ' SL 6.x package name: bzip2-devel'
+echo ' Debian package name: libbz2-dev'
+echo ' URL: http://www.bzip.org'
+fi
+if [ "X$LIBPNG" = "X-lpng" ]
+then
+echo 'libpng: found.'
+else
+echo 'libpng: NOT found! Required!'
+echo ' SL 6.x package name: libpng-devel'
+echo ' Debian package name: libpng-dev'
+echo ' URL: http://www.libpng.org'
+EXVAL=1
+fi
+if [ "X$LIBJPEG" = "X-ljpeg" ]
+then
+echo 'libjpeg: found.'
+else
+echo 'libjpeg: NOT found! Recommended.'
+echo ' No JPEG support in bmpp and fig2lat.'
+echo ' SL 6.x package name: libjpeg-turbo-devel'
+echo ' Debian package name: libjpeg-dev'
+echo ' URL: http://www.ijg.org/'
+fi
+if [ "X$LIBTIFF" = "X-ltiff" ]
+then
+echo 'libtiff: found.'
+else
+echo 'libtiff: NOT found! Recommended.'
+echo ' No TIFF support in bmpp and fig2lat.'
+echo ' SL 6.x package name: libtiff-devel'
+echo ' Debian package name: libtiff-dev'
+echo ' URL: http://www.remotesensing.org/libtiff/'
+fi
+if [ "X$ANYDB" != "X" ]
+then
+echo "database: $ANYDB"
+else
+echo 'database: NOT found! Recommended.'
+echo ' Skipping printqd build!'
+echo ' SL 6.x package name: db4-devel'
+echo ' Debian package name: libdb-dev'
+echo ' URL: http://www.oracle.com/database/berkeley-db/'
+fi
+if [ "X$MYSQLPROG" = "Xmysqlprog" ]
+then
+echo 'MySQL: found.'
+else
+echo 'MySQL: NOT found! Recommended.'
+echo ' Skipping itadmin build.'
+echo ' SL 6.x package name: mysql-devel'
+echo ' Debian package name: libmysqlclient-dev'
+echo ' URL: http://www.mysql.com/'
+fi
+if [ "X$CRYPTO" != "X" ]
+then
+echo 'OpenSSL: found.'
+else
+echo 'OpenSSL: NOT found!'
+echo ' SL 6.x package name: openssl-devel'
+echo ' Debian package name: libssl-dev'
+echo ' URL: http://www.openssl.org/'
+fi
+if [ "X$WXCPPFLAGS" != "X" ]
+then
+echo 'wxWidgets: found.'
+else
+echo 'wxWidgets: NOT found!'
+echo ' SL 6.x package name: wxGTK-devel'
+echo ' Debian package name: libwxgtk3.0-dev'
+echo ' URL: http://www.wxwidgets.org/'
+fi
+case "X$SUITE" in
+"Xgui")
+echo 'Software bundle: CLI and GUI programs'
+;;
+"Xrescue")
+echo 'Software bundle: Rescue system programs'
+;;
+"*")
+echo 'Software bundle: CLI programs'
+;;
+esac
+if [ "X$ENASTATIC" = "Xyes" ]
+then
+echo 'Install static libraries: yes'
+else
+echo 'Install static libraries: no'
+fi
+if [ "X$ENASHARED" = "Xyes" ]
+then
+echo 'Install shared libraries: yes'
+else
+echo 'Install shared libraries: no'
+fi
+if [ "X$USESOLINKING" = "Xyes" ]
+then
+echo 'Nested shared library linking: yes'
+else
+echo 'Nested shared library linking: no'
+fi
+if [ "X$ENAPACKAGING" = "Xyes" ]
+then
+echo 'Binaries use shared libraries: yes'
+else
+echo 'Binaries use shared libraries: no'
+fi
+echo ''
+echo The INSTALL files describes how to install via '*.rpm' or '.deb' package.
+echo ''
+exit $EXVAL
+
diff --git a/support/dktools/autom4te.cache/requests b/support/dktools/autom4te.cache/requests
new file mode 100644
index 0000000000..cb021fc6bb
--- /dev/null
+++ b/support/dktools/autom4te.cache/requests
@@ -0,0 +1,79 @@
+# This file was generated by Autom4te Sun Aug 31 17:43:43 UTC 2014.
+# It contains the lists of macros which have been traced.
+# It can be safely removed.
+
+@request = (
+ bless( [
+ '0',
+ 1,
+ [
+ '/usr/share/autoconf'
+ ],
+ [
+ '/usr/share/autoconf/autoconf/autoconf.m4f',
+ 'aclocal.m4',
+ 'configure.ac'
+ ],
+ {
+ 'AM_PATH_GUILE' => 1,
+ 'AC_DEFINE_TRACE_LITERAL' => 1,
+ 'sinclude' => 1,
+ 'AM_PROG_FC_C_O' => 1,
+ 'AM_XGETTEXT_OPTION' => 1,
+ 'AM_GNU_GETTEXT_INTL_SUBDIR' => 1,
+ 'AC_CANONICAL_HOST' => 1,
+ 'AM_INIT_AUTOMAKE' => 1,
+ 'AH_OUTPUT' => 1,
+ 'AM_PROG_F77_C_O' => 1,
+ 'AC_CONFIG_LIBOBJ_DIR' => 1,
+ 'AC_FC_FREEFORM' => 1,
+ 'AM_MAINTAINER_MODE' => 1,
+ '_m4_warn' => 1,
+ 'm4_pattern_forbid' => 1,
+ '_AM_COND_ENDIF' => 1,
+ 'AC_FC_SRCEXT' => 1,
+ 'AM_GNU_GETTEXT' => 1,
+ 'AM_CONDITIONAL' => 1,
+ 'AC_CONFIG_AUX_DIR' => 1,
+ 'LT_CONFIG_LTDL_DIR' => 1,
+ 'LT_SUPPORTED_TAG' => 1,
+ 'AM_PROG_MOC' => 1,
+ 'AC_REQUIRE_AUX_FILE' => 1,
+ 'AC_CONFIG_FILES' => 1,
+ '_AM_SUBST_NOTMAKE' => 1,
+ 'AC_FC_PP_DEFINE' => 1,
+ 'AM_PROG_CXX_C_O' => 1,
+ 'm4_include' => 1,
+ 'AC_SUBST' => 1,
+ 'm4_pattern_allow' => 1,
+ 'AM_POT_TOOLS' => 1,
+ 'AM_PROG_LIBTOOL' => 1,
+ 'AC_SUBST_TRACE' => 1,
+ 'AC_LIBSOURCE' => 1,
+ 'AC_CANONICAL_BUILD' => 1,
+ 'AC_CONFIG_HEADERS' => 1,
+ 'AM_PROG_CC_C_O' => 1,
+ '_LT_AC_TAGCONFIG' => 1,
+ '_AM_MAKEFILE_INCLUDE' => 1,
+ 'AM_MAKEFILE_INCLUDE' => 1,
+ 'AM_NLS' => 1,
+ 'AC_INIT' => 1,
+ '_AM_COND_ELSE' => 1,
+ 'AC_PROG_LIBTOOL' => 1,
+ 'AM_ENABLE_MULTILIB' => 1,
+ '_AM_COND_IF' => 1,
+ 'AM_SILENT_RULES' => 1,
+ 'AM_PROG_AR' => 1,
+ 'AC_CONFIG_SUBDIRS' => 1,
+ 'LT_INIT' => 1,
+ 'AC_CANONICAL_TARGET' => 1,
+ 'AM_AUTOMAKE_VERSION' => 1,
+ 'AC_CANONICAL_SYSTEM' => 1,
+ 'm4_sinclude' => 1,
+ 'AC_FC_PP_SRCEXT' => 1,
+ 'AC_CONFIG_LINKS' => 1,
+ 'include' => 1
+ }
+ ], 'Autom4te::Request' )
+ );
+
diff --git a/support/dktools/autom4te.cache/traces.0 b/support/dktools/autom4te.cache/traces.0
new file mode 100644
index 0000000000..900dc56690
--- /dev/null
+++ b/support/dktools/autom4te.cache/traces.0
@@ -0,0 +1,2757 @@
+m4trace:configure.ac:2: -1- AC_INIT([dk4.h])
+m4trace:configure.ac:2: -1- m4_pattern_forbid([^_?A[CHUM]_])
+m4trace:configure.ac:2: -1- m4_pattern_forbid([_AC_])
+m4trace:configure.ac:2: -1- m4_pattern_forbid([^LIBOBJS$], [do not use LIBOBJS directly, use AC_LIBOBJ (see section `AC_LIBOBJ vs LIBOBJS'])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^AS_FLAGS$])
+m4trace:configure.ac:2: -1- m4_pattern_forbid([^_?m4_])
+m4trace:configure.ac:2: -1- m4_pattern_forbid([^dnl$])
+m4trace:configure.ac:2: -1- m4_pattern_forbid([^_?AS_])
+m4trace:configure.ac:2: -1- AC_SUBST([SHELL])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([SHELL])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^SHELL$])
+m4trace:configure.ac:2: -1- AC_SUBST([PATH_SEPARATOR])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([PATH_SEPARATOR])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^PATH_SEPARATOR$])
+m4trace:configure.ac:2: -1- AC_SUBST([PACKAGE_NAME], [m4_ifdef([AC_PACKAGE_NAME], ['AC_PACKAGE_NAME'])])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([PACKAGE_NAME])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^PACKAGE_NAME$])
+m4trace:configure.ac:2: -1- AC_SUBST([PACKAGE_TARNAME], [m4_ifdef([AC_PACKAGE_TARNAME], ['AC_PACKAGE_TARNAME'])])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([PACKAGE_TARNAME])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^PACKAGE_TARNAME$])
+m4trace:configure.ac:2: -1- AC_SUBST([PACKAGE_VERSION], [m4_ifdef([AC_PACKAGE_VERSION], ['AC_PACKAGE_VERSION'])])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([PACKAGE_VERSION])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^PACKAGE_VERSION$])
+m4trace:configure.ac:2: -1- AC_SUBST([PACKAGE_STRING], [m4_ifdef([AC_PACKAGE_STRING], ['AC_PACKAGE_STRING'])])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([PACKAGE_STRING])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^PACKAGE_STRING$])
+m4trace:configure.ac:2: -1- AC_SUBST([PACKAGE_BUGREPORT], [m4_ifdef([AC_PACKAGE_BUGREPORT], ['AC_PACKAGE_BUGREPORT'])])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([PACKAGE_BUGREPORT])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^PACKAGE_BUGREPORT$])
+m4trace:configure.ac:2: -1- AC_SUBST([PACKAGE_URL], [m4_ifdef([AC_PACKAGE_URL], ['AC_PACKAGE_URL'])])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([PACKAGE_URL])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^PACKAGE_URL$])
+m4trace:configure.ac:2: -1- AC_SUBST([exec_prefix], [NONE])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([exec_prefix])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^exec_prefix$])
+m4trace:configure.ac:2: -1- AC_SUBST([prefix], [NONE])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([prefix])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^prefix$])
+m4trace:configure.ac:2: -1- AC_SUBST([program_transform_name], [s,x,x,])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([program_transform_name])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^program_transform_name$])
+m4trace:configure.ac:2: -1- AC_SUBST([bindir], ['${exec_prefix}/bin'])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([bindir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^bindir$])
+m4trace:configure.ac:2: -1- AC_SUBST([sbindir], ['${exec_prefix}/sbin'])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([sbindir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^sbindir$])
+m4trace:configure.ac:2: -1- AC_SUBST([libexecdir], ['${exec_prefix}/libexec'])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([libexecdir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^libexecdir$])
+m4trace:configure.ac:2: -1- AC_SUBST([datarootdir], ['${prefix}/share'])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([datarootdir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^datarootdir$])
+m4trace:configure.ac:2: -1- AC_SUBST([datadir], ['${datarootdir}'])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([datadir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^datadir$])
+m4trace:configure.ac:2: -1- AC_SUBST([sysconfdir], ['${prefix}/etc'])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([sysconfdir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^sysconfdir$])
+m4trace:configure.ac:2: -1- AC_SUBST([sharedstatedir], ['${prefix}/com'])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([sharedstatedir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^sharedstatedir$])
+m4trace:configure.ac:2: -1- AC_SUBST([localstatedir], ['${prefix}/var'])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([localstatedir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^localstatedir$])
+m4trace:configure.ac:2: -1- AC_SUBST([includedir], ['${prefix}/include'])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([includedir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^includedir$])
+m4trace:configure.ac:2: -1- AC_SUBST([oldincludedir], ['/usr/include'])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([oldincludedir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^oldincludedir$])
+m4trace:configure.ac:2: -1- AC_SUBST([docdir], [m4_ifset([AC_PACKAGE_TARNAME],
+ ['${datarootdir}/doc/${PACKAGE_TARNAME}'],
+ ['${datarootdir}/doc/${PACKAGE}'])])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([docdir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^docdir$])
+m4trace:configure.ac:2: -1- AC_SUBST([infodir], ['${datarootdir}/info'])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([infodir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^infodir$])
+m4trace:configure.ac:2: -1- AC_SUBST([htmldir], ['${docdir}'])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([htmldir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^htmldir$])
+m4trace:configure.ac:2: -1- AC_SUBST([dvidir], ['${docdir}'])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([dvidir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^dvidir$])
+m4trace:configure.ac:2: -1- AC_SUBST([pdfdir], ['${docdir}'])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([pdfdir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^pdfdir$])
+m4trace:configure.ac:2: -1- AC_SUBST([psdir], ['${docdir}'])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([psdir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^psdir$])
+m4trace:configure.ac:2: -1- AC_SUBST([libdir], ['${exec_prefix}/lib'])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([libdir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^libdir$])
+m4trace:configure.ac:2: -1- AC_SUBST([localedir], ['${datarootdir}/locale'])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([localedir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^localedir$])
+m4trace:configure.ac:2: -1- AC_SUBST([mandir], ['${datarootdir}/man'])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([mandir])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^mandir$])
+m4trace:configure.ac:2: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_NAME])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^PACKAGE_NAME$])
+m4trace:configure.ac:2: -1- AH_OUTPUT([PACKAGE_NAME], [/* Define to the full name of this package. */
+@%:@undef PACKAGE_NAME])
+m4trace:configure.ac:2: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_TARNAME])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^PACKAGE_TARNAME$])
+m4trace:configure.ac:2: -1- AH_OUTPUT([PACKAGE_TARNAME], [/* Define to the one symbol short name of this package. */
+@%:@undef PACKAGE_TARNAME])
+m4trace:configure.ac:2: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_VERSION])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^PACKAGE_VERSION$])
+m4trace:configure.ac:2: -1- AH_OUTPUT([PACKAGE_VERSION], [/* Define to the version of this package. */
+@%:@undef PACKAGE_VERSION])
+m4trace:configure.ac:2: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_STRING])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^PACKAGE_STRING$])
+m4trace:configure.ac:2: -1- AH_OUTPUT([PACKAGE_STRING], [/* Define to the full name and version of this package. */
+@%:@undef PACKAGE_STRING])
+m4trace:configure.ac:2: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_BUGREPORT])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^PACKAGE_BUGREPORT$])
+m4trace:configure.ac:2: -1- AH_OUTPUT([PACKAGE_BUGREPORT], [/* Define to the address where bug reports for this package should be sent. */
+@%:@undef PACKAGE_BUGREPORT])
+m4trace:configure.ac:2: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_URL])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^PACKAGE_URL$])
+m4trace:configure.ac:2: -1- AH_OUTPUT([PACKAGE_URL], [/* Define to the home page for this package. */
+@%:@undef PACKAGE_URL])
+m4trace:configure.ac:2: -1- AC_SUBST([DEFS])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([DEFS])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^DEFS$])
+m4trace:configure.ac:2: -1- AC_SUBST([ECHO_C])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([ECHO_C])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^ECHO_C$])
+m4trace:configure.ac:2: -1- AC_SUBST([ECHO_N])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([ECHO_N])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^ECHO_N$])
+m4trace:configure.ac:2: -1- AC_SUBST([ECHO_T])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([ECHO_T])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^ECHO_T$])
+m4trace:configure.ac:2: -1- AC_SUBST([LIBS])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([LIBS])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^LIBS$])
+m4trace:configure.ac:2: -1- AC_SUBST([build_alias])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([build_alias])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^build_alias$])
+m4trace:configure.ac:2: -1- AC_SUBST([host_alias])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([host_alias])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^host_alias$])
+m4trace:configure.ac:2: -1- AC_SUBST([target_alias])
+m4trace:configure.ac:2: -1- AC_SUBST_TRACE([target_alias])
+m4trace:configure.ac:2: -1- m4_pattern_allow([^target_alias$])
+m4trace:configure.ac:3: -1- AC_CONFIG_HEADERS([config.h])
+m4trace:configure.ac:4: -1- AC_SUBST([CC])
+m4trace:configure.ac:4: -1- AC_SUBST_TRACE([CC])
+m4trace:configure.ac:4: -1- m4_pattern_allow([^CC$])
+m4trace:configure.ac:4: -1- AC_SUBST([CFLAGS])
+m4trace:configure.ac:4: -1- AC_SUBST_TRACE([CFLAGS])
+m4trace:configure.ac:4: -1- m4_pattern_allow([^CFLAGS$])
+m4trace:configure.ac:4: -1- AC_SUBST([LDFLAGS])
+m4trace:configure.ac:4: -1- AC_SUBST_TRACE([LDFLAGS])
+m4trace:configure.ac:4: -1- m4_pattern_allow([^LDFLAGS$])
+m4trace:configure.ac:4: -1- AC_SUBST([LIBS])
+m4trace:configure.ac:4: -1- AC_SUBST_TRACE([LIBS])
+m4trace:configure.ac:4: -1- m4_pattern_allow([^LIBS$])
+m4trace:configure.ac:4: -1- AC_SUBST([CPPFLAGS])
+m4trace:configure.ac:4: -1- AC_SUBST_TRACE([CPPFLAGS])
+m4trace:configure.ac:4: -1- m4_pattern_allow([^CPPFLAGS$])
+m4trace:configure.ac:4: -1- AC_SUBST([CC])
+m4trace:configure.ac:4: -1- AC_SUBST_TRACE([CC])
+m4trace:configure.ac:4: -1- m4_pattern_allow([^CC$])
+m4trace:configure.ac:4: -1- AC_SUBST([CC])
+m4trace:configure.ac:4: -1- AC_SUBST_TRACE([CC])
+m4trace:configure.ac:4: -1- m4_pattern_allow([^CC$])
+m4trace:configure.ac:4: -1- AC_SUBST([CC])
+m4trace:configure.ac:4: -1- AC_SUBST_TRACE([CC])
+m4trace:configure.ac:4: -1- m4_pattern_allow([^CC$])
+m4trace:configure.ac:4: -1- AC_SUBST([CC])
+m4trace:configure.ac:4: -1- AC_SUBST_TRACE([CC])
+m4trace:configure.ac:4: -1- m4_pattern_allow([^CC$])
+m4trace:configure.ac:4: -1- AC_SUBST([ac_ct_CC])
+m4trace:configure.ac:4: -1- AC_SUBST_TRACE([ac_ct_CC])
+m4trace:configure.ac:4: -1- m4_pattern_allow([^ac_ct_CC$])
+m4trace:configure.ac:4: -1- AC_SUBST([EXEEXT], [$ac_cv_exeext])
+m4trace:configure.ac:4: -1- AC_SUBST_TRACE([EXEEXT])
+m4trace:configure.ac:4: -1- m4_pattern_allow([^EXEEXT$])
+m4trace:configure.ac:4: -1- AC_SUBST([OBJEXT], [$ac_cv_objext])
+m4trace:configure.ac:4: -1- AC_SUBST_TRACE([OBJEXT])
+m4trace:configure.ac:4: -1- m4_pattern_allow([^OBJEXT$])
+m4trace:configure.ac:5: -1- AC_SUBST([CPP])
+m4trace:configure.ac:5: -1- AC_SUBST_TRACE([CPP])
+m4trace:configure.ac:5: -1- m4_pattern_allow([^CPP$])
+m4trace:configure.ac:5: -1- AC_SUBST([CPPFLAGS])
+m4trace:configure.ac:5: -1- AC_SUBST_TRACE([CPPFLAGS])
+m4trace:configure.ac:5: -1- m4_pattern_allow([^CPPFLAGS$])
+m4trace:configure.ac:5: -1- AC_SUBST([CPP])
+m4trace:configure.ac:5: -1- AC_SUBST_TRACE([CPP])
+m4trace:configure.ac:5: -1- m4_pattern_allow([^CPP$])
+m4trace:configure.ac:6: -1- AC_SUBST([CXX])
+m4trace:configure.ac:6: -1- AC_SUBST_TRACE([CXX])
+m4trace:configure.ac:6: -1- m4_pattern_allow([^CXX$])
+m4trace:configure.ac:6: -1- AC_SUBST([CXXFLAGS])
+m4trace:configure.ac:6: -1- AC_SUBST_TRACE([CXXFLAGS])
+m4trace:configure.ac:6: -1- m4_pattern_allow([^CXXFLAGS$])
+m4trace:configure.ac:6: -1- AC_SUBST([LDFLAGS])
+m4trace:configure.ac:6: -1- AC_SUBST_TRACE([LDFLAGS])
+m4trace:configure.ac:6: -1- m4_pattern_allow([^LDFLAGS$])
+m4trace:configure.ac:6: -1- AC_SUBST([LIBS])
+m4trace:configure.ac:6: -1- AC_SUBST_TRACE([LIBS])
+m4trace:configure.ac:6: -1- m4_pattern_allow([^LIBS$])
+m4trace:configure.ac:6: -1- AC_SUBST([CPPFLAGS])
+m4trace:configure.ac:6: -1- AC_SUBST_TRACE([CPPFLAGS])
+m4trace:configure.ac:6: -1- m4_pattern_allow([^CPPFLAGS$])
+m4trace:configure.ac:6: -1- AC_SUBST([CXX])
+m4trace:configure.ac:6: -1- AC_SUBST_TRACE([CXX])
+m4trace:configure.ac:6: -1- m4_pattern_allow([^CXX$])
+m4trace:configure.ac:6: -1- AC_SUBST([ac_ct_CXX])
+m4trace:configure.ac:6: -1- AC_SUBST_TRACE([ac_ct_CXX])
+m4trace:configure.ac:6: -1- m4_pattern_allow([^ac_ct_CXX$])
+m4trace:configure.ac:7: -1- AH_OUTPUT([WORDS_BIGENDIAN], [/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+ significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+# define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+# undef WORDS_BIGENDIAN
+# endif
+#endif])
+m4trace:configure.ac:7: -1- AC_SUBST([GREP])
+m4trace:configure.ac:7: -1- AC_SUBST_TRACE([GREP])
+m4trace:configure.ac:7: -1- m4_pattern_allow([^GREP$])
+m4trace:configure.ac:7: -1- AC_SUBST([EGREP])
+m4trace:configure.ac:7: -1- AC_SUBST_TRACE([EGREP])
+m4trace:configure.ac:7: -1- m4_pattern_allow([^EGREP$])
+m4trace:configure.ac:7: -1- AC_DEFINE_TRACE_LITERAL([STDC_HEADERS])
+m4trace:configure.ac:7: -1- m4_pattern_allow([^STDC_HEADERS$])
+m4trace:configure.ac:7: -1- AH_OUTPUT([STDC_HEADERS], [/* Define to 1 if you have the ANSI C header files. */
+@%:@undef STDC_HEADERS])
+m4trace:configure.ac:7: -1- AH_OUTPUT([HAVE_SYS_TYPES_H], [/* Define to 1 if you have the <sys/types.h> header file. */
+@%:@undef HAVE_SYS_TYPES_H])
+m4trace:configure.ac:7: -1- AH_OUTPUT([HAVE_SYS_STAT_H], [/* Define to 1 if you have the <sys/stat.h> header file. */
+@%:@undef HAVE_SYS_STAT_H])
+m4trace:configure.ac:7: -1- AH_OUTPUT([HAVE_STDLIB_H], [/* Define to 1 if you have the <stdlib.h> header file. */
+@%:@undef HAVE_STDLIB_H])
+m4trace:configure.ac:7: -1- AH_OUTPUT([HAVE_STRING_H], [/* Define to 1 if you have the <string.h> header file. */
+@%:@undef HAVE_STRING_H])
+m4trace:configure.ac:7: -1- AH_OUTPUT([HAVE_MEMORY_H], [/* Define to 1 if you have the <memory.h> header file. */
+@%:@undef HAVE_MEMORY_H])
+m4trace:configure.ac:7: -1- AH_OUTPUT([HAVE_STRINGS_H], [/* Define to 1 if you have the <strings.h> header file. */
+@%:@undef HAVE_STRINGS_H])
+m4trace:configure.ac:7: -1- AH_OUTPUT([HAVE_INTTYPES_H], [/* Define to 1 if you have the <inttypes.h> header file. */
+@%:@undef HAVE_INTTYPES_H])
+m4trace:configure.ac:7: -1- AH_OUTPUT([HAVE_STDINT_H], [/* Define to 1 if you have the <stdint.h> header file. */
+@%:@undef HAVE_STDINT_H])
+m4trace:configure.ac:7: -1- AH_OUTPUT([HAVE_UNISTD_H], [/* Define to 1 if you have the <unistd.h> header file. */
+@%:@undef HAVE_UNISTD_H])
+m4trace:configure.ac:7: -1- AC_DEFINE_TRACE_LITERAL([WORDS_BIGENDIAN])
+m4trace:configure.ac:7: -1- m4_pattern_allow([^WORDS_BIGENDIAN$])
+m4trace:configure.ac:7: -1- AC_DEFINE_TRACE_LITERAL([AC_APPLE_UNIVERSAL_BUILD])
+m4trace:configure.ac:7: -1- m4_pattern_allow([^AC_APPLE_UNIVERSAL_BUILD$])
+m4trace:configure.ac:7: -1- AH_OUTPUT([AC_APPLE_UNIVERSAL_BUILD], [/* Define if building universal (internal helper macro) */
+@%:@undef AC_APPLE_UNIVERSAL_BUILD])
+m4trace:configure.ac:8: -1- AC_REQUIRE_AUX_FILE([install-sh])
+m4trace:configure.ac:8: -1- AC_SUBST([MKDIR_P])
+m4trace:configure.ac:8: -1- AC_SUBST_TRACE([MKDIR_P])
+m4trace:configure.ac:8: -1- m4_pattern_allow([^MKDIR_P$])
+m4trace:configure.ac:9: -1- AC_SUBST([SED])
+m4trace:configure.ac:9: -1- AC_SUBST_TRACE([SED])
+m4trace:configure.ac:9: -1- m4_pattern_allow([^SED$])
+m4trace:configure.ac:10: -1- AC_REQUIRE_AUX_FILE([install-sh])
+m4trace:configure.ac:10: -1- AC_SUBST([INSTALL_PROGRAM])
+m4trace:configure.ac:10: -1- AC_SUBST_TRACE([INSTALL_PROGRAM])
+m4trace:configure.ac:10: -1- m4_pattern_allow([^INSTALL_PROGRAM$])
+m4trace:configure.ac:10: -1- AC_SUBST([INSTALL_SCRIPT])
+m4trace:configure.ac:10: -1- AC_SUBST_TRACE([INSTALL_SCRIPT])
+m4trace:configure.ac:10: -1- m4_pattern_allow([^INSTALL_SCRIPT$])
+m4trace:configure.ac:10: -1- AC_SUBST([INSTALL_DATA])
+m4trace:configure.ac:10: -1- AC_SUBST_TRACE([INSTALL_DATA])
+m4trace:configure.ac:10: -1- m4_pattern_allow([^INSTALL_DATA$])
+m4trace:configure.ac:11: -1- AC_SUBST([LN_S], [$as_ln_s])
+m4trace:configure.ac:11: -1- AC_SUBST_TRACE([LN_S])
+m4trace:configure.ac:11: -1- m4_pattern_allow([^LN_S$])
+m4trace:configure.ac:12: -1- AC_CANONICAL_HOST
+m4trace:configure.ac:12: -1- AC_CANONICAL_BUILD
+m4trace:configure.ac:12: -1- AC_REQUIRE_AUX_FILE([config.sub])
+m4trace:configure.ac:12: -1- AC_REQUIRE_AUX_FILE([config.guess])
+m4trace:configure.ac:12: -1- AC_SUBST([build], [$ac_cv_build])
+m4trace:configure.ac:12: -1- AC_SUBST_TRACE([build])
+m4trace:configure.ac:12: -1- m4_pattern_allow([^build$])
+m4trace:configure.ac:12: -1- AC_SUBST([build_cpu], [$[1]])
+m4trace:configure.ac:12: -1- AC_SUBST_TRACE([build_cpu])
+m4trace:configure.ac:12: -1- m4_pattern_allow([^build_cpu$])
+m4trace:configure.ac:12: -1- AC_SUBST([build_vendor], [$[2]])
+m4trace:configure.ac:12: -1- AC_SUBST_TRACE([build_vendor])
+m4trace:configure.ac:12: -1- m4_pattern_allow([^build_vendor$])
+m4trace:configure.ac:12: -1- AC_SUBST([build_os])
+m4trace:configure.ac:12: -1- AC_SUBST_TRACE([build_os])
+m4trace:configure.ac:12: -1- m4_pattern_allow([^build_os$])
+m4trace:configure.ac:12: -1- AC_SUBST([host], [$ac_cv_host])
+m4trace:configure.ac:12: -1- AC_SUBST_TRACE([host])
+m4trace:configure.ac:12: -1- m4_pattern_allow([^host$])
+m4trace:configure.ac:12: -1- AC_SUBST([host_cpu], [$[1]])
+m4trace:configure.ac:12: -1- AC_SUBST_TRACE([host_cpu])
+m4trace:configure.ac:12: -1- m4_pattern_allow([^host_cpu$])
+m4trace:configure.ac:12: -1- AC_SUBST([host_vendor], [$[2]])
+m4trace:configure.ac:12: -1- AC_SUBST_TRACE([host_vendor])
+m4trace:configure.ac:12: -1- m4_pattern_allow([^host_vendor$])
+m4trace:configure.ac:12: -1- AC_SUBST([host_os])
+m4trace:configure.ac:12: -1- AC_SUBST_TRACE([host_os])
+m4trace:configure.ac:12: -1- m4_pattern_allow([^host_os$])
+m4trace:configure.ac:13: -1- AC_CANONICAL_BUILD
+m4trace:configure.ac:14: -1- AC_SUBST([RANLIB])
+m4trace:configure.ac:14: -1- AC_SUBST_TRACE([RANLIB])
+m4trace:configure.ac:14: -1- m4_pattern_allow([^RANLIB$])
+m4trace:configure.ac:15: -1- AC_SUBST([AR])
+m4trace:configure.ac:15: -1- AC_SUBST_TRACE([AR])
+m4trace:configure.ac:15: -1- m4_pattern_allow([^AR$])
+m4trace:configure.ac:16: -1- AC_SUBST([NM])
+m4trace:configure.ac:16: -1- AC_SUBST_TRACE([NM])
+m4trace:configure.ac:16: -1- m4_pattern_allow([^NM$])
+m4trace:configure.ac:440: -1- AC_SUBST([WGET])
+m4trace:configure.ac:440: -1- AC_SUBST_TRACE([WGET])
+m4trace:configure.ac:440: -1- m4_pattern_allow([^WGET$])
+m4trace:configure.ac:441: -1- AC_SUBST([CURL])
+m4trace:configure.ac:441: -1- AC_SUBST_TRACE([CURL])
+m4trace:configure.ac:441: -1- m4_pattern_allow([^CURL$])
+m4trace:configure.ac:516: -1- AC_DEFINE_TRACE_LITERAL([HAVE_BACKSLASH_AS_SEP])
+m4trace:configure.ac:516: -1- m4_pattern_allow([^HAVE_BACKSLASH_AS_SEP$])
+m4trace:configure.ac:517: -1- AC_DEFINE_TRACE_LITERAL([HAVE_LINE_END_CR_NL])
+m4trace:configure.ac:517: -1- m4_pattern_allow([^HAVE_LINE_END_CR_NL$])
+m4trace:configure.ac:518: -1- AC_DEFINE_TRACE_LITERAL([HAVE_CASE_INSENSITIVE_PATHNAMES])
+m4trace:configure.ac:518: -1- m4_pattern_allow([^HAVE_CASE_INSENSITIVE_PATHNAMES$])
+m4trace:configure.ac:705: -2- AC_DEFINE_TRACE_LITERAL([HAVE_ERRNO_H])
+m4trace:configure.ac:705: -2- m4_pattern_allow([^HAVE_ERRNO_H$])
+m4trace:configure.ac:705: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:705: the top level])
+m4trace:configure.ac:706: -2- AC_DEFINE_TRACE_LITERAL([HAVE_ASSERT_H])
+m4trace:configure.ac:706: -2- m4_pattern_allow([^HAVE_ASSERT_H$])
+m4trace:configure.ac:706: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:706: the top level])
+m4trace:configure.ac:707: -2- AC_DEFINE_TRACE_LITERAL([HAVE_COMPLEX_H])
+m4trace:configure.ac:707: -2- m4_pattern_allow([^HAVE_COMPLEX_H$])
+m4trace:configure.ac:707: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:707: the top level])
+m4trace:configure.ac:708: -2- AC_DEFINE_TRACE_LITERAL([HAVE_CTYPE_H])
+m4trace:configure.ac:708: -2- m4_pattern_allow([^HAVE_CTYPE_H$])
+m4trace:configure.ac:708: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:708: the top level])
+m4trace:configure.ac:709: -2- AC_DEFINE_TRACE_LITERAL([HAVE_FENV_H])
+m4trace:configure.ac:709: -2- m4_pattern_allow([^HAVE_FENV_H$])
+m4trace:configure.ac:709: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:709: the top level])
+m4trace:configure.ac:710: -2- AC_DEFINE_TRACE_LITERAL([HAVE_FLOAT_H])
+m4trace:configure.ac:710: -2- m4_pattern_allow([^HAVE_FLOAT_H$])
+m4trace:configure.ac:710: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:710: the top level])
+m4trace:configure.ac:711: -2- AC_DEFINE_TRACE_LITERAL([HAVE_INTTYPES_H])
+m4trace:configure.ac:711: -2- m4_pattern_allow([^HAVE_INTTYPES_H$])
+m4trace:configure.ac:711: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:711: the top level])
+m4trace:configure.ac:712: -2- AC_DEFINE_TRACE_LITERAL([HAVE_ISO646_H])
+m4trace:configure.ac:712: -2- m4_pattern_allow([^HAVE_ISO646_H$])
+m4trace:configure.ac:712: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:712: the top level])
+m4trace:configure.ac:713: -2- AC_DEFINE_TRACE_LITERAL([HAVE_LIMITS_H])
+m4trace:configure.ac:713: -2- m4_pattern_allow([^HAVE_LIMITS_H$])
+m4trace:configure.ac:713: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:713: the top level])
+m4trace:configure.ac:714: -2- AC_DEFINE_TRACE_LITERAL([HAVE_LOCALE_H])
+m4trace:configure.ac:714: -2- m4_pattern_allow([^HAVE_LOCALE_H$])
+m4trace:configure.ac:714: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:714: the top level])
+m4trace:configure.ac:715: -2- AC_DEFINE_TRACE_LITERAL([HAVE_MATH_H])
+m4trace:configure.ac:715: -2- m4_pattern_allow([^HAVE_MATH_H$])
+m4trace:configure.ac:715: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:715: the top level])
+m4trace:configure.ac:716: -2- AC_DEFINE_TRACE_LITERAL([HAVE_SETJMP_H])
+m4trace:configure.ac:716: -2- m4_pattern_allow([^HAVE_SETJMP_H$])
+m4trace:configure.ac:716: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:716: the top level])
+m4trace:configure.ac:717: -2- AC_DEFINE_TRACE_LITERAL([HAVE_SIGNAL_H])
+m4trace:configure.ac:717: -2- m4_pattern_allow([^HAVE_SIGNAL_H$])
+m4trace:configure.ac:717: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:717: the top level])
+m4trace:configure.ac:718: -2- AC_DEFINE_TRACE_LITERAL([HAVE_STDALIGN_H])
+m4trace:configure.ac:718: -2- m4_pattern_allow([^HAVE_STDALIGN_H$])
+m4trace:configure.ac:718: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:718: the top level])
+m4trace:configure.ac:719: -2- AC_DEFINE_TRACE_LITERAL([HAVE_STDARG_H])
+m4trace:configure.ac:719: -2- m4_pattern_allow([^HAVE_STDARG_H$])
+m4trace:configure.ac:719: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:719: the top level])
+m4trace:configure.ac:720: -2- AC_DEFINE_TRACE_LITERAL([HAVE_STDATOMIC_H])
+m4trace:configure.ac:720: -2- m4_pattern_allow([^HAVE_STDATOMIC_H$])
+m4trace:configure.ac:720: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:720: the top level])
+m4trace:configure.ac:721: -2- AC_DEFINE_TRACE_LITERAL([HAVE_STDBOOL_H])
+m4trace:configure.ac:721: -2- m4_pattern_allow([^HAVE_STDBOOL_H$])
+m4trace:configure.ac:721: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:721: the top level])
+m4trace:configure.ac:722: -2- AC_DEFINE_TRACE_LITERAL([HAVE_STDDEF_H])
+m4trace:configure.ac:722: -2- m4_pattern_allow([^HAVE_STDDEF_H$])
+m4trace:configure.ac:722: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:722: the top level])
+m4trace:configure.ac:723: -2- AC_DEFINE_TRACE_LITERAL([HAVE_STDINT_H])
+m4trace:configure.ac:723: -2- m4_pattern_allow([^HAVE_STDINT_H$])
+m4trace:configure.ac:723: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:723: the top level])
+m4trace:configure.ac:724: -2- AC_DEFINE_TRACE_LITERAL([HAVE_STDLIB_H])
+m4trace:configure.ac:724: -2- m4_pattern_allow([^HAVE_STDLIB_H$])
+m4trace:configure.ac:724: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:724: the top level])
+m4trace:configure.ac:725: -2- AC_DEFINE_TRACE_LITERAL([HAVE_STDNORETURN_H])
+m4trace:configure.ac:725: -2- m4_pattern_allow([^HAVE_STDNORETURN_H$])
+m4trace:configure.ac:725: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:725: the top level])
+m4trace:configure.ac:726: -2- AC_DEFINE_TRACE_LITERAL([HAVE_STRING_H])
+m4trace:configure.ac:726: -2- m4_pattern_allow([^HAVE_STRING_H$])
+m4trace:configure.ac:726: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:726: the top level])
+m4trace:configure.ac:727: -2- AC_DEFINE_TRACE_LITERAL([HAVE_TGMATH_H])
+m4trace:configure.ac:727: -2- m4_pattern_allow([^HAVE_TGMATH_H$])
+m4trace:configure.ac:727: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:727: the top level])
+m4trace:configure.ac:728: -2- AC_DEFINE_TRACE_LITERAL([HAVE_THREADS_H])
+m4trace:configure.ac:728: -2- m4_pattern_allow([^HAVE_THREADS_H$])
+m4trace:configure.ac:728: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:728: the top level])
+m4trace:configure.ac:729: -2- AC_DEFINE_TRACE_LITERAL([HAVE_TIME_H])
+m4trace:configure.ac:729: -2- m4_pattern_allow([^HAVE_TIME_H$])
+m4trace:configure.ac:729: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:729: the top level])
+m4trace:configure.ac:730: -2- AC_DEFINE_TRACE_LITERAL([HAVE_UCHAR_H])
+m4trace:configure.ac:730: -2- m4_pattern_allow([^HAVE_UCHAR_H$])
+m4trace:configure.ac:730: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:730: the top level])
+m4trace:configure.ac:731: -2- AC_DEFINE_TRACE_LITERAL([HAVE_WCHAR_H])
+m4trace:configure.ac:731: -2- m4_pattern_allow([^HAVE_WCHAR_H$])
+m4trace:configure.ac:731: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:731: the top level])
+m4trace:configure.ac:732: -2- AC_DEFINE_TRACE_LITERAL([HAVE_WCTYPE_H])
+m4trace:configure.ac:732: -2- m4_pattern_allow([^HAVE_WCTYPE_H$])
+m4trace:configure.ac:732: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:732: the top level])
+m4trace:configure.ac:737: -2- AC_DEFINE_TRACE_LITERAL([HAVE_SYS_TYPES_H])
+m4trace:configure.ac:737: -2- m4_pattern_allow([^HAVE_SYS_TYPES_H$])
+m4trace:configure.ac:737: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:737: the top level])
+m4trace:configure.ac:738: -2- AC_DEFINE_TRACE_LITERAL([HAVE_SYS_PARAM_H])
+m4trace:configure.ac:738: -2- m4_pattern_allow([^HAVE_SYS_PARAM_H$])
+m4trace:configure.ac:738: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:738: the top level])
+m4trace:configure.ac:739: -2- AC_DEFINE_TRACE_LITERAL([HAVE_SYS_STAT_H])
+m4trace:configure.ac:739: -2- m4_pattern_allow([^HAVE_SYS_STAT_H$])
+m4trace:configure.ac:739: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:739: the top level])
+m4trace:configure.ac:740: -2- AC_DEFINE_TRACE_LITERAL([HAVE_SYS_TIME_H])
+m4trace:configure.ac:740: -2- m4_pattern_allow([^HAVE_SYS_TIME_H$])
+m4trace:configure.ac:740: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:740: the top level])
+m4trace:configure.ac:741: -2- AC_DEFINE_TRACE_LITERAL([HAVE_SYS_SOCKET_H])
+m4trace:configure.ac:741: -2- m4_pattern_allow([^HAVE_SYS_SOCKET_H$])
+m4trace:configure.ac:741: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:741: the top level])
+m4trace:configure.ac:742: -2- AC_DEFINE_TRACE_LITERAL([HAVE_SYS_SELECT_H])
+m4trace:configure.ac:742: -2- m4_pattern_allow([^HAVE_SYS_SELECT_H$])
+m4trace:configure.ac:742: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:742: the top level])
+m4trace:configure.ac:743: -2- AC_DEFINE_TRACE_LITERAL([HAVE_SYS_UN_H])
+m4trace:configure.ac:743: -2- m4_pattern_allow([^HAVE_SYS_UN_H$])
+m4trace:configure.ac:743: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:743: the top level])
+m4trace:configure.ac:744: -2- AC_DEFINE_TRACE_LITERAL([HAVE_NETINET_IN_H])
+m4trace:configure.ac:744: -2- m4_pattern_allow([^HAVE_NETINET_IN_H$])
+m4trace:configure.ac:744: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:744: the top level])
+m4trace:configure.ac:745: -2- AC_DEFINE_TRACE_LITERAL([HAVE_NETINET_IN6_H])
+m4trace:configure.ac:745: -2- m4_pattern_allow([^HAVE_NETINET_IN6_H$])
+m4trace:configure.ac:745: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:745: the top level])
+m4trace:configure.ac:746: -2- AC_DEFINE_TRACE_LITERAL([HAVE_NETDB_H])
+m4trace:configure.ac:746: -2- m4_pattern_allow([^HAVE_NETDB_H$])
+m4trace:configure.ac:746: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:746: the top level])
+m4trace:configure.ac:747: -2- AC_DEFINE_TRACE_LITERAL([HAVE_ARPA_INET_H])
+m4trace:configure.ac:747: -2- m4_pattern_allow([^HAVE_ARPA_INET_H$])
+m4trace:configure.ac:747: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:747: the top level])
+m4trace:configure.ac:748: -2- AC_DEFINE_TRACE_LITERAL([HAVE_WINSOCK2_H])
+m4trace:configure.ac:748: -2- m4_pattern_allow([^HAVE_WINSOCK2_H$])
+m4trace:configure.ac:748: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:748: the top level])
+m4trace:configure.ac:749: -2- AC_DEFINE_TRACE_LITERAL([HAVE_WS2TCPIP_H])
+m4trace:configure.ac:749: -2- m4_pattern_allow([^HAVE_WS2TCPIP_H$])
+m4trace:configure.ac:749: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:749: the top level])
+m4trace:configure.ac:750: -2- AC_DEFINE_TRACE_LITERAL([HAVE_WINDOWS_H])
+m4trace:configure.ac:750: -2- m4_pattern_allow([^HAVE_WINDOWS_H$])
+m4trace:configure.ac:750: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:750: the top level])
+m4trace:configure.ac:751: -2- AC_DEFINE_TRACE_LITERAL([HAVE_UNISTD_H])
+m4trace:configure.ac:751: -2- m4_pattern_allow([^HAVE_UNISTD_H$])
+m4trace:configure.ac:751: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:751: the top level])
+m4trace:configure.ac:752: -2- AC_DEFINE_TRACE_LITERAL([HAVE_PROCESS_H])
+m4trace:configure.ac:752: -2- m4_pattern_allow([^HAVE_PROCESS_H$])
+m4trace:configure.ac:752: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:752: the top level])
+m4trace:configure.ac:753: -2- AC_DEFINE_TRACE_LITERAL([HAVE_FCNTL_H])
+m4trace:configure.ac:753: -2- m4_pattern_allow([^HAVE_FCNTL_H$])
+m4trace:configure.ac:753: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:753: the top level])
+m4trace:configure.ac:754: -2- AC_DEFINE_TRACE_LITERAL([HAVE_SHARE_H])
+m4trace:configure.ac:754: -2- m4_pattern_allow([^HAVE_SHARE_H$])
+m4trace:configure.ac:754: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:754: the top level])
+m4trace:configure.ac:755: -2- AC_DEFINE_TRACE_LITERAL([HAVE_PWD_H])
+m4trace:configure.ac:755: -2- m4_pattern_allow([^HAVE_PWD_H$])
+m4trace:configure.ac:755: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:755: the top level])
+m4trace:configure.ac:756: -2- AC_DEFINE_TRACE_LITERAL([HAVE_STRINGS_H])
+m4trace:configure.ac:756: -2- m4_pattern_allow([^HAVE_STRINGS_H$])
+m4trace:configure.ac:756: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:756: the top level])
+m4trace:configure.ac:757: -2- AC_DEFINE_TRACE_LITERAL([HAVE_IO_H])
+m4trace:configure.ac:757: -2- m4_pattern_allow([^HAVE_IO_H$])
+m4trace:configure.ac:757: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:757: the top level])
+m4trace:configure.ac:758: -2- AC_DEFINE_TRACE_LITERAL([HAVE_BIOS_H])
+m4trace:configure.ac:758: -2- m4_pattern_allow([^HAVE_BIOS_H$])
+m4trace:configure.ac:758: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:758: the top level])
+m4trace:configure.ac:759: -2- AC_DEFINE_TRACE_LITERAL([HAVE_DOS_H])
+m4trace:configure.ac:759: -2- m4_pattern_allow([^HAVE_DOS_H$])
+m4trace:configure.ac:759: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:759: the top level])
+m4trace:configure.ac:760: -2- AC_DEFINE_TRACE_LITERAL([HAVE_ALLOC_H])
+m4trace:configure.ac:760: -2- m4_pattern_allow([^HAVE_ALLOC_H$])
+m4trace:configure.ac:760: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:760: the top level])
+m4trace:configure.ac:761: -2- AC_DEFINE_TRACE_LITERAL([HAVE_MALLOC_H])
+m4trace:configure.ac:761: -2- m4_pattern_allow([^HAVE_MALLOC_H$])
+m4trace:configure.ac:761: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:761: the top level])
+m4trace:configure.ac:762: -2- AC_DEFINE_TRACE_LITERAL([HAVE_DIRENT_H])
+m4trace:configure.ac:762: -2- m4_pattern_allow([^HAVE_DIRENT_H$])
+m4trace:configure.ac:762: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:762: the top level])
+m4trace:configure.ac:763: -2- AC_DEFINE_TRACE_LITERAL([HAVE_DIRECT_H])
+m4trace:configure.ac:763: -2- m4_pattern_allow([^HAVE_DIRECT_H$])
+m4trace:configure.ac:763: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:763: the top level])
+m4trace:configure.ac:764: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:764: the top level])
+m4trace:configure.ac:764: -1- AC_DEFINE_TRACE_LITERAL([HAVE_ZLIB_H])
+m4trace:configure.ac:764: -1- m4_pattern_allow([^HAVE_ZLIB_H$])
+m4trace:configure.ac:765: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:765: the top level])
+m4trace:configure.ac:765: -1- AC_DEFINE_TRACE_LITERAL([HAVE_BZLIB_H])
+m4trace:configure.ac:765: -1- m4_pattern_allow([^HAVE_BZLIB_H$])
+m4trace:configure.ac:770: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:770: the top level])
+m4trace:configure.ac:770: -1- AC_DEFINE_TRACE_LITERAL([HAVE_OPENSSL_RAND_H])
+m4trace:configure.ac:770: -1- m4_pattern_allow([^HAVE_OPENSSL_RAND_H$])
+m4trace:configure.ac:775: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:775: the top level])
+m4trace:configure.ac:775: -1- AC_DEFINE_TRACE_LITERAL([HAVE_OPENSSL_MD5_H])
+m4trace:configure.ac:775: -1- m4_pattern_allow([^HAVE_OPENSSL_MD5_H$])
+m4trace:configure.ac:776: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:776: the top level])
+m4trace:configure.ac:776: -1- AC_DEFINE_TRACE_LITERAL([HAVE_OPENSSL_SHA_H])
+m4trace:configure.ac:776: -1- m4_pattern_allow([^HAVE_OPENSSL_SHA_H$])
+m4trace:configure.ac:777: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:777: the top level])
+m4trace:configure.ac:777: -1- AC_DEFINE_TRACE_LITERAL([HAVE_OPENSSL_RIPEMD_H])
+m4trace:configure.ac:777: -1- m4_pattern_allow([^HAVE_OPENSSL_RIPEMD_H$])
+m4trace:configure.ac:780: -1- AC_DEFINE_TRACE_LITERAL([TIME_WITH_SYS_TIME])
+m4trace:configure.ac:780: -1- m4_pattern_allow([^TIME_WITH_SYS_TIME$])
+m4trace:configure.ac:780: -1- AH_OUTPUT([TIME_WITH_SYS_TIME], [/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+@%:@undef TIME_WITH_SYS_TIME])
+m4trace:configure.ac:784: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:784: the top level])
+m4trace:configure.ac:784: -1- AC_DEFINE_TRACE_LITERAL([HAVE_LONG_LONG])
+m4trace:configure.ac:784: -1- m4_pattern_allow([^HAVE_LONG_LONG$])
+m4trace:configure.ac:793: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:793: the top level])
+m4trace:configure.ac:793: -1- AC_DEFINE_TRACE_LITERAL([HAVE_LONG_DOUBLE])
+m4trace:configure.ac:793: -1- m4_pattern_allow([^HAVE_LONG_DOUBLE$])
+m4trace:configure.ac:804: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:804: the top level])
+m4trace:configure.ac:804: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INTMAX_T])
+m4trace:configure.ac:804: -1- m4_pattern_allow([^HAVE_INTMAX_T$])
+m4trace:configure.ac:818: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:818: the top level])
+m4trace:configure.ac:818: -1- AC_DEFINE_TRACE_LITERAL([HAVE_VOLATILE])
+m4trace:configure.ac:818: -1- m4_pattern_allow([^HAVE_VOLATILE$])
+m4trace:configure.ac:826: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:826: the top level])
+m4trace:configure.ac:826: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SIG_ATOMIC_T])
+m4trace:configure.ac:826: -1- m4_pattern_allow([^HAVE_SIG_ATOMIC_T$])
+m4trace:configure.ac:834: -1- AC_DEFINE_TRACE_LITERAL([SIZEOF_SHORT])
+m4trace:configure.ac:834: -1- m4_pattern_allow([^SIZEOF_SHORT$])
+m4trace:configure.ac:834: -1- AH_OUTPUT([SIZEOF_SHORT], [/* The size of `short\', as computed by sizeof. */
+@%:@undef SIZEOF_SHORT])
+m4trace:configure.ac:835: -1- AC_DEFINE_TRACE_LITERAL([SIZEOF_INT])
+m4trace:configure.ac:835: -1- m4_pattern_allow([^SIZEOF_INT$])
+m4trace:configure.ac:835: -1- AH_OUTPUT([SIZEOF_INT], [/* The size of `int\', as computed by sizeof. */
+@%:@undef SIZEOF_INT])
+m4trace:configure.ac:836: -1- AC_DEFINE_TRACE_LITERAL([SIZEOF_SIZE_T])
+m4trace:configure.ac:836: -1- m4_pattern_allow([^SIZEOF_SIZE_T$])
+m4trace:configure.ac:836: -1- AH_OUTPUT([SIZEOF_SIZE_T], [/* The size of `size_t\', as computed by sizeof. */
+@%:@undef SIZEOF_SIZE_T])
+m4trace:configure.ac:837: -1- AC_DEFINE_TRACE_LITERAL([SIZEOF_LONG])
+m4trace:configure.ac:837: -1- m4_pattern_allow([^SIZEOF_LONG$])
+m4trace:configure.ac:837: -1- AH_OUTPUT([SIZEOF_LONG], [/* The size of `long\', as computed by sizeof. */
+@%:@undef SIZEOF_LONG])
+m4trace:configure.ac:838: -1- AC_DEFINE_TRACE_LITERAL([SIZEOF_LONG_LONG])
+m4trace:configure.ac:838: -1- m4_pattern_allow([^SIZEOF_LONG_LONG$])
+m4trace:configure.ac:838: -1- AH_OUTPUT([SIZEOF_LONG_LONG], [/* The size of `long long\', as computed by sizeof. */
+@%:@undef SIZEOF_LONG_LONG])
+m4trace:configure.ac:841: -1- AC_DEFINE_TRACE_LITERAL([SIZEOF_INTMAX_T])
+m4trace:configure.ac:841: -1- m4_pattern_allow([^SIZEOF_INTMAX_T$])
+m4trace:configure.ac:841: -1- AH_OUTPUT([SIZEOF_INTMAX_T], [/* The size of `intmax_t\', as computed by sizeof. */
+@%:@undef SIZEOF_INTMAX_T])
+m4trace:configure.ac:843: -1- AC_DEFINE_TRACE_LITERAL([SIZEOF_DOUBLE])
+m4trace:configure.ac:843: -1- m4_pattern_allow([^SIZEOF_DOUBLE$])
+m4trace:configure.ac:843: -1- AH_OUTPUT([SIZEOF_DOUBLE], [/* The size of `double\', as computed by sizeof. */
+@%:@undef SIZEOF_DOUBLE])
+m4trace:configure.ac:844: -1- AC_DEFINE_TRACE_LITERAL([SIZEOF_LONG_DOUBLE])
+m4trace:configure.ac:844: -1- m4_pattern_allow([^SIZEOF_LONG_DOUBLE$])
+m4trace:configure.ac:844: -1- AH_OUTPUT([SIZEOF_LONG_DOUBLE], [/* The size of `long double\', as computed by sizeof. */
+@%:@undef SIZEOF_LONG_DOUBLE])
+m4trace:configure.ac:845: -1- AC_DEFINE_TRACE_LITERAL([SIZEOF_WCHAR_T])
+m4trace:configure.ac:845: -1- m4_pattern_allow([^SIZEOF_WCHAR_T$])
+m4trace:configure.ac:845: -1- AH_OUTPUT([SIZEOF_WCHAR_T], [/* The size of `wchar_t\', as computed by sizeof. */
+@%:@undef SIZEOF_WCHAR_T])
+m4trace:configure.ac:850: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:850: the top level])
+m4trace:configure.ac:850: -1- AC_DEFINE_TRACE_LITERAL([HAVE_LARGEFILE64_SOURCE])
+m4trace:configure.ac:850: -1- m4_pattern_allow([^HAVE_LARGEFILE64_SOURCE$])
+m4trace:configure.ac:850: -1- AC_DEFINE_TRACE_LITERAL([HAVE_TYPE_STAT64])
+m4trace:configure.ac:850: -1- m4_pattern_allow([^HAVE_TYPE_STAT64$])
+m4trace:configure.ac:868: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:868: the top level])
+m4trace:configure.ac:868: -1- AH_OUTPUT([HAVE_MEMSET], [/* Define to 1 if you have the `memset\' function. */
+@%:@undef HAVE_MEMSET])
+m4trace:configure.ac:868: -1- AH_OUTPUT([HAVE_BZERO], [/* Define to 1 if you have the `bzero\' function. */
+@%:@undef HAVE_BZERO])
+m4trace:configure.ac:868: -1- AH_OUTPUT([HAVE_MEMCPY], [/* Define to 1 if you have the `memcpy\' function. */
+@%:@undef HAVE_MEMCPY])
+m4trace:configure.ac:868: -1- AH_OUTPUT([HAVE_BCOPY], [/* Define to 1 if you have the `bcopy\' function. */
+@%:@undef HAVE_BCOPY])
+m4trace:configure.ac:868: -1- AH_OUTPUT([HAVE_MEMCMP], [/* Define to 1 if you have the `memcmp\' function. */
+@%:@undef HAVE_MEMCMP])
+m4trace:configure.ac:868: -1- AH_OUTPUT([HAVE_BCMP], [/* Define to 1 if you have the `bcmp\' function. */
+@%:@undef HAVE_BCMP])
+m4trace:configure.ac:869: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:869: the top level])
+m4trace:configure.ac:869: -1- AH_OUTPUT([HAVE_MALLOC], [/* Define to 1 if you have the `malloc\' function. */
+@%:@undef HAVE_MALLOC])
+m4trace:configure.ac:869: -1- AH_OUTPUT([HAVE_CALLOC], [/* Define to 1 if you have the `calloc\' function. */
+@%:@undef HAVE_CALLOC])
+m4trace:configure.ac:869: -1- AH_OUTPUT([HAVE_FREE], [/* Define to 1 if you have the `free\' function. */
+@%:@undef HAVE_FREE])
+m4trace:configure.ac:870: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:870: the top level])
+m4trace:configure.ac:870: -1- AH_OUTPUT([HAVE_STRCPY_S], [/* Define to 1 if you have the `strcpy_s\' function. */
+@%:@undef HAVE_STRCPY_S])
+m4trace:configure.ac:870: -1- AH_OUTPUT([HAVE_STRCAT_S], [/* Define to 1 if you have the `strcat_s\' function. */
+@%:@undef HAVE_STRCAT_S])
+m4trace:configure.ac:871: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:871: the top level])
+m4trace:configure.ac:871: -1- AH_OUTPUT([HAVE_STRCASECMP], [/* Define to 1 if you have the `strcasecmp\' function. */
+@%:@undef HAVE_STRCASECMP])
+m4trace:configure.ac:871: -1- AH_OUTPUT([HAVE_STRICMP], [/* Define to 1 if you have the `stricmp\' function. */
+@%:@undef HAVE_STRICMP])
+m4trace:configure.ac:871: -1- AH_OUTPUT([HAVE__STRICMP], [/* Define to 1 if you have the `_stricmp\' function. */
+@%:@undef HAVE__STRICMP])
+m4trace:configure.ac:872: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:872: the top level])
+m4trace:configure.ac:872: -1- AH_OUTPUT([HAVE_WCSLEN], [/* Define to 1 if you have the `wcslen\' function. */
+@%:@undef HAVE_WCSLEN])
+m4trace:configure.ac:872: -1- AH_OUTPUT([HAVE_WCSCPY_S], [/* Define to 1 if you have the `wcscpy_s\' function. */
+@%:@undef HAVE_WCSCPY_S])
+m4trace:configure.ac:872: -1- AH_OUTPUT([HAVE_WCSCPY], [/* Define to 1 if you have the `wcscpy\' function. */
+@%:@undef HAVE_WCSCPY])
+m4trace:configure.ac:872: -1- AH_OUTPUT([HAVE_WCSCAT_S], [/* Define to 1 if you have the `wcscat_s\' function. */
+@%:@undef HAVE_WCSCAT_S])
+m4trace:configure.ac:872: -1- AH_OUTPUT([HAVE_WCSCAT], [/* Define to 1 if you have the `wcscat\' function. */
+@%:@undef HAVE_WCSCAT])
+m4trace:configure.ac:872: -1- AH_OUTPUT([HAVE_WCSCHR], [/* Define to 1 if you have the `wcschr\' function. */
+@%:@undef HAVE_WCSCHR])
+m4trace:configure.ac:872: -1- AH_OUTPUT([HAVE_WCSRCHR], [/* Define to 1 if you have the `wcsrchr\' function. */
+@%:@undef HAVE_WCSRCHR])
+m4trace:configure.ac:873: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:873: the top level])
+m4trace:configure.ac:873: -1- AH_OUTPUT([HAVE_WCSCMP], [/* Define to 1 if you have the `wcscmp\' function. */
+@%:@undef HAVE_WCSCMP])
+m4trace:configure.ac:873: -1- AH_OUTPUT([HAVE__WCSCMP], [/* Define to 1 if you have the `_wcscmp\' function. */
+@%:@undef HAVE__WCSCMP])
+m4trace:configure.ac:873: -1- AH_OUTPUT([HAVE_WCSCASECMP], [/* Define to 1 if you have the `wcscasecmp\' function. */
+@%:@undef HAVE_WCSCASECMP])
+m4trace:configure.ac:873: -1- AH_OUTPUT([HAVE__WCSCASECMP], [/* Define to 1 if you have the `_wcscasecmp\' function. */
+@%:@undef HAVE__WCSCASECMP])
+m4trace:configure.ac:873: -1- AH_OUTPUT([HAVE_WCSICMP], [/* Define to 1 if you have the `wcsicmp\' function. */
+@%:@undef HAVE_WCSICMP])
+m4trace:configure.ac:873: -1- AH_OUTPUT([HAVE__WCSICMP], [/* Define to 1 if you have the `_wcsicmp\' function. */
+@%:@undef HAVE__WCSICMP])
+m4trace:configure.ac:874: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:874: the top level])
+m4trace:configure.ac:874: -1- AH_OUTPUT([HAVE_GETPID], [/* Define to 1 if you have the `getpid\' function. */
+@%:@undef HAVE_GETPID])
+m4trace:configure.ac:874: -1- AH_OUTPUT([HAVE_READLINK], [/* Define to 1 if you have the `readlink\' function. */
+@%:@undef HAVE_READLINK])
+m4trace:configure.ac:874: -1- AH_OUTPUT([HAVE_GETEXECNAME], [/* Define to 1 if you have the `getexecname\' function. */
+@%:@undef HAVE_GETEXECNAME])
+m4trace:configure.ac:874: -1- AH_OUTPUT([HAVE_LSTAT], [/* Define to 1 if you have the `lstat\' function. */
+@%:@undef HAVE_LSTAT])
+m4trace:configure.ac:874: -1- AH_OUTPUT([HAVE_STAT64], [/* Define to 1 if you have the `stat64\' function. */
+@%:@undef HAVE_STAT64])
+m4trace:configure.ac:874: -1- AH_OUTPUT([HAVE_LSTAT64], [/* Define to 1 if you have the `lstat64\' function. */
+@%:@undef HAVE_LSTAT64])
+m4trace:configure.ac:874: -1- AH_OUTPUT([HAVE_LOCALTIME_R], [/* Define to 1 if you have the `localtime_r\' function. */
+@%:@undef HAVE_LOCALTIME_R])
+m4trace:configure.ac:875: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:875: the top level])
+m4trace:configure.ac:875: -1- AH_OUTPUT([HAVE_GETEUID], [/* Define to 1 if you have the `geteuid\' function. */
+@%:@undef HAVE_GETEUID])
+m4trace:configure.ac:875: -1- AH_OUTPUT([HAVE_FOPEN64], [/* Define to 1 if you have the `fopen64\' function. */
+@%:@undef HAVE_FOPEN64])
+m4trace:configure.ac:875: -1- AH_OUTPUT([HAVE_FOPEN_S], [/* Define to 1 if you have the `fopen_s\' function. */
+@%:@undef HAVE_FOPEN_S])
+m4trace:configure.ac:875: -1- AH_OUTPUT([HAVE__WFOPEN], [/* Define to 1 if you have the `_wfopen\' function. */
+@%:@undef HAVE__WFOPEN])
+m4trace:configure.ac:875: -1- AH_OUTPUT([HAVE__WFOPEN64], [/* Define to 1 if you have the `_wfopen64\' function. */
+@%:@undef HAVE__WFOPEN64])
+m4trace:configure.ac:875: -1- AH_OUTPUT([HAVE__WFOPEN_S], [/* Define to 1 if you have the `_wfopen_s\' function. */
+@%:@undef HAVE__WFOPEN_S])
+m4trace:configure.ac:876: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:876: the top level])
+m4trace:configure.ac:876: -1- AH_OUTPUT([HAVE_FPUTWS], [/* Define to 1 if you have the `fputws\' function. */
+@%:@undef HAVE_FPUTWS])
+m4trace:configure.ac:876: -1- AH_OUTPUT([HAVE_FPUTWC], [/* Define to 1 if you have the `fputwc\' function. */
+@%:@undef HAVE_FPUTWC])
+m4trace:configure.ac:877: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:877: the top level])
+m4trace:configure.ac:877: -1- AH_OUTPUT([HAVE_SETBUFFER], [/* Define to 1 if you have the `setbuffer\' function. */
+@%:@undef HAVE_SETBUFFER])
+m4trace:configure.ac:877: -1- AH_OUTPUT([HAVE_SETBUF], [/* Define to 1 if you have the `setbuf\' function. */
+@%:@undef HAVE_SETBUF])
+m4trace:configure.ac:877: -1- AH_OUTPUT([HAVE_SETVBUF], [/* Define to 1 if you have the `setvbuf\' function. */
+@%:@undef HAVE_SETVBUF])
+m4trace:configure.ac:878: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:878: the top level])
+m4trace:configure.ac:878: -1- AH_OUTPUT([HAVE_FILENO], [/* Define to 1 if you have the `fileno\' function. */
+@%:@undef HAVE_FILENO])
+m4trace:configure.ac:878: -1- AH_OUTPUT([HAVE__FILENO], [/* Define to 1 if you have the `_fileno\' function. */
+@%:@undef HAVE__FILENO])
+m4trace:configure.ac:878: -1- AH_OUTPUT([HAVE_SETMODE], [/* Define to 1 if you have the `setmode\' function. */
+@%:@undef HAVE_SETMODE])
+m4trace:configure.ac:878: -1- AH_OUTPUT([HAVE__SETMODE], [/* Define to 1 if you have the `_setmode\' function. */
+@%:@undef HAVE__SETMODE])
+m4trace:configure.ac:878: -1- AH_OUTPUT([HAVE_ISATTY], [/* Define to 1 if you have the `isatty\' function. */
+@%:@undef HAVE_ISATTY])
+m4trace:configure.ac:878: -1- AH_OUTPUT([HAVE__ISATTY], [/* Define to 1 if you have the `_isatty\' function. */
+@%:@undef HAVE__ISATTY])
+m4trace:configure.ac:879: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:879: the top level])
+m4trace:configure.ac:879: -1- AH_OUTPUT([HAVE_STRTOD], [/* Define to 1 if you have the `strtod\' function. */
+@%:@undef HAVE_STRTOD])
+m4trace:configure.ac:879: -1- AH_OUTPUT([HAVE__STRTOD], [/* Define to 1 if you have the `_strtod\' function. */
+@%:@undef HAVE__STRTOD])
+m4trace:configure.ac:879: -1- AH_OUTPUT([HAVE_WCSTOD], [/* Define to 1 if you have the `wcstod\' function. */
+@%:@undef HAVE_WCSTOD])
+m4trace:configure.ac:879: -1- AH_OUTPUT([HAVE__WCSTOD], [/* Define to 1 if you have the `_wcstod\' function. */
+@%:@undef HAVE__WCSTOD])
+m4trace:configure.ac:880: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:880: the top level])
+m4trace:configure.ac:880: -1- AH_OUTPUT([HAVE__SNPRINTF_S], [/* Define to 1 if you have the `_snprintf_s\' function. */
+@%:@undef HAVE__SNPRINTF_S])
+m4trace:configure.ac:880: -1- AH_OUTPUT([HAVE__SNPRINTF], [/* Define to 1 if you have the `_snprintf\' function. */
+@%:@undef HAVE__SNPRINTF])
+m4trace:configure.ac:880: -1- AH_OUTPUT([HAVE_SNPRINTF], [/* Define to 1 if you have the `snprintf\' function. */
+@%:@undef HAVE_SNPRINTF])
+m4trace:configure.ac:880: -1- AH_OUTPUT([HAVE__SNWPRINTF_S], [/* Define to 1 if you have the `_snwprintf_s\' function. */
+@%:@undef HAVE__SNWPRINTF_S])
+m4trace:configure.ac:880: -1- AH_OUTPUT([HAVE__SNWPRINTF], [/* Define to 1 if you have the `_snwprintf\' function. */
+@%:@undef HAVE__SNWPRINTF])
+m4trace:configure.ac:880: -1- AH_OUTPUT([HAVE_SNWPRINTF], [/* Define to 1 if you have the `snwprintf\' function. */
+@%:@undef HAVE_SNWPRINTF])
+m4trace:configure.ac:881: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:881: the top level])
+m4trace:configure.ac:881: -1- AH_OUTPUT([HAVE_SWPRINTF], [/* Define to 1 if you have the `swprintf\' function. */
+@%:@undef HAVE_SWPRINTF])
+m4trace:configure.ac:881: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SWPRINTF])
+m4trace:configure.ac:881: -1- m4_pattern_allow([^HAVE_SWPRINTF$])
+m4trace:configure.ac:882: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:882: the top level])
+m4trace:configure.ac:882: -1- AH_OUTPUT([HAVE_UNLINK], [/* Define to 1 if you have the `unlink\' function. */
+@%:@undef HAVE_UNLINK])
+m4trace:configure.ac:882: -1- AH_OUTPUT([HAVE__UNLINK], [/* Define to 1 if you have the `_unlink\' function. */
+@%:@undef HAVE__UNLINK])
+m4trace:configure.ac:882: -1- AH_OUTPUT([HAVE_WUNLINK], [/* Define to 1 if you have the `wunlink\' function. */
+@%:@undef HAVE_WUNLINK])
+m4trace:configure.ac:882: -1- AH_OUTPUT([HAVE__WUNLINK], [/* Define to 1 if you have the `_wunlink\' function. */
+@%:@undef HAVE__WUNLINK])
+m4trace:configure.ac:883: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:883: the top level])
+m4trace:configure.ac:883: -1- AH_OUTPUT([HAVE_RMDIR], [/* Define to 1 if you have the `rmdir\' function. */
+@%:@undef HAVE_RMDIR])
+m4trace:configure.ac:883: -1- AH_OUTPUT([HAVE__RMDIR], [/* Define to 1 if you have the `_rmdir\' function. */
+@%:@undef HAVE__RMDIR])
+m4trace:configure.ac:883: -1- AH_OUTPUT([HAVE_WRMDIR], [/* Define to 1 if you have the `wrmdir\' function. */
+@%:@undef HAVE_WRMDIR])
+m4trace:configure.ac:883: -1- AH_OUTPUT([HAVE__WRMDIR], [/* Define to 1 if you have the `_wrmdir\' function. */
+@%:@undef HAVE__WRMDIR])
+m4trace:configure.ac:884: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:884: the top level])
+m4trace:configure.ac:884: -1- AH_OUTPUT([HAVE_MKDIR], [/* Define to 1 if you have the `mkdir\' function. */
+@%:@undef HAVE_MKDIR])
+m4trace:configure.ac:884: -1- AH_OUTPUT([HAVE__MKDIR], [/* Define to 1 if you have the `_mkdir\' function. */
+@%:@undef HAVE__MKDIR])
+m4trace:configure.ac:884: -1- AH_OUTPUT([HAVE_WMKDIR], [/* Define to 1 if you have the `wmkdir\' function. */
+@%:@undef HAVE_WMKDIR])
+m4trace:configure.ac:884: -1- AH_OUTPUT([HAVE__WMKDIR], [/* Define to 1 if you have the `_wmkdir\' function. */
+@%:@undef HAVE__WMKDIR])
+m4trace:configure.ac:885: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:885: the top level])
+m4trace:configure.ac:885: -1- AH_OUTPUT([HAVE_STRERROR], [/* Define to 1 if you have the `strerror\' function. */
+@%:@undef HAVE_STRERROR])
+m4trace:configure.ac:885: -1- AH_OUTPUT([HAVE_STRERROR_R], [/* Define to 1 if you have the `strerror_r\' function. */
+@%:@undef HAVE_STRERROR_R])
+m4trace:configure.ac:886: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:886: the top level])
+m4trace:configure.ac:886: -1- AH_OUTPUT([HAVE_SIGACTION], [/* Define to 1 if you have the `sigaction\' function. */
+@%:@undef HAVE_SIGACTION])
+m4trace:configure.ac:886: -1- AH_OUTPUT([HAVE_SIGSET], [/* Define to 1 if you have the `sigset\' function. */
+@%:@undef HAVE_SIGSET])
+m4trace:configure.ac:886: -1- AH_OUTPUT([HAVE_SIGNAL], [/* Define to 1 if you have the `signal\' function. */
+@%:@undef HAVE_SIGNAL])
+m4trace:configure.ac:886: -1- AH_OUTPUT([HAVE_SIGPROCMASK], [/* Define to 1 if you have the `sigprocmask\' function. */
+@%:@undef HAVE_SIGPROCMASK])
+m4trace:configure.ac:886: -1- AH_OUTPUT([HAVE_SIGEMPTYSET], [/* Define to 1 if you have the `sigemptyset\' function. */
+@%:@undef HAVE_SIGEMPTYSET])
+m4trace:configure.ac:887: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:887: the top level])
+m4trace:configure.ac:887: -1- AH_OUTPUT([HAVE_SETPWENT], [/* Define to 1 if you have the `setpwent\' function. */
+@%:@undef HAVE_SETPWENT])
+m4trace:configure.ac:887: -1- AH_OUTPUT([HAVE_GETPWENT], [/* Define to 1 if you have the `getpwent\' function. */
+@%:@undef HAVE_GETPWENT])
+m4trace:configure.ac:887: -1- AH_OUTPUT([HAVE_ENDPWENT], [/* Define to 1 if you have the `endpwent\' function. */
+@%:@undef HAVE_ENDPWENT])
+m4trace:configure.ac:888: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:888: the top level])
+m4trace:configure.ac:888: -1- AH_OUTPUT([HAVE_GETENV], [/* Define to 1 if you have the `getenv\' function. */
+@%:@undef HAVE_GETENV])
+m4trace:configure.ac:888: -1- AH_OUTPUT([HAVE_GETENV_S], [/* Define to 1 if you have the `getenv_s\' function. */
+@%:@undef HAVE_GETENV_S])
+m4trace:configure.ac:888: -1- AH_OUTPUT([HAVE_SETLOCALE], [/* Define to 1 if you have the `setlocale\' function. */
+@%:@undef HAVE_SETLOCALE])
+m4trace:configure.ac:888: -1- AH_OUTPUT([HAVE_SELECT], [/* Define to 1 if you have the `select\' function. */
+@%:@undef HAVE_SELECT])
+m4trace:configure.ac:889: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:889: the top level])
+m4trace:configure.ac:889: -1- AH_OUTPUT([HAVE_GETCWD], [/* Define to 1 if you have the `getcwd\' function. */
+@%:@undef HAVE_GETCWD])
+m4trace:configure.ac:889: -1- AH_OUTPUT([HAVE__GETCWD], [/* Define to 1 if you have the `_getcwd\' function. */
+@%:@undef HAVE__GETCWD])
+m4trace:configure.ac:889: -1- AH_OUTPUT([HAVE__WGETCWD], [/* Define to 1 if you have the `_wgetcwd\' function. */
+@%:@undef HAVE__WGETCWD])
+m4trace:configure.ac:890: -2- AC_DEFINE_TRACE_LITERAL([HAVE_SHA224])
+m4trace:configure.ac:890: -2- m4_pattern_allow([^HAVE_SHA224$])
+m4trace:configure.ac:891: -2- AC_DEFINE_TRACE_LITERAL([HAVE_SHA256])
+m4trace:configure.ac:891: -2- m4_pattern_allow([^HAVE_SHA256$])
+m4trace:configure.ac:892: -2- AC_DEFINE_TRACE_LITERAL([HAVE_SHA384])
+m4trace:configure.ac:892: -2- m4_pattern_allow([^HAVE_SHA384$])
+m4trace:configure.ac:893: -2- AC_DEFINE_TRACE_LITERAL([HAVE_SHA512])
+m4trace:configure.ac:893: -2- m4_pattern_allow([^HAVE_SHA512$])
+m4trace:configure.ac:896: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:896: the top level])
+m4trace:configure.ac:896: -1- AC_DEFINE_TRACE_LITERAL([HAVE_RAND_EGD])
+m4trace:configure.ac:896: -1- m4_pattern_allow([^HAVE_RAND_EGD$])
+m4trace:configure.ac:909: -1- AH_OUTPUT([HAVE_SOCKET], [/* Define to 1 if you have the `socket\' function. */
+@%:@undef HAVE_SOCKET])
+m4trace:configure.ac:909: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SOCKET])
+m4trace:configure.ac:909: -1- m4_pattern_allow([^HAVE_SOCKET$])
+m4trace:configure.ac:909: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SOCKET])
+m4trace:configure.ac:909: -1- m4_pattern_allow([^HAVE_SOCKET$])
+m4trace:configure.ac:909: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SOCKET])
+m4trace:configure.ac:909: -1- m4_pattern_allow([^HAVE_SOCKET$])
+m4trace:configure.ac:909: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SOCKET])
+m4trace:configure.ac:909: -1- m4_pattern_allow([^HAVE_SOCKET$])
+m4trace:configure.ac:909: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SOCKET])
+m4trace:configure.ac:909: -1- m4_pattern_allow([^HAVE_SOCKET$])
+m4trace:configure.ac:937: -1- AH_OUTPUT([HAVE_SETSOCKOPT], [/* Define to 1 if you have the `setsockopt\' function. */
+@%:@undef HAVE_SETSOCKOPT])
+m4trace:configure.ac:937: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SETSOCKOPT])
+m4trace:configure.ac:937: -1- m4_pattern_allow([^HAVE_SETSOCKOPT$])
+m4trace:configure.ac:937: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SETSOCKOPT])
+m4trace:configure.ac:937: -1- m4_pattern_allow([^HAVE_SETSOCKOPT$])
+m4trace:configure.ac:937: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SETSOCKOPT])
+m4trace:configure.ac:937: -1- m4_pattern_allow([^HAVE_SETSOCKOPT$])
+m4trace:configure.ac:937: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SETSOCKOPT])
+m4trace:configure.ac:937: -1- m4_pattern_allow([^HAVE_SETSOCKOPT$])
+m4trace:configure.ac:937: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SETSOCKOPT])
+m4trace:configure.ac:937: -1- m4_pattern_allow([^HAVE_SETSOCKOPT$])
+m4trace:configure.ac:954: -1- AH_OUTPUT([HAVE_GETADDRINFO], [/* Define to 1 if you have the `getaddrinfo\' function. */
+@%:@undef HAVE_GETADDRINFO])
+m4trace:configure.ac:954: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GETADDRINFO])
+m4trace:configure.ac:954: -1- m4_pattern_allow([^HAVE_GETADDRINFO$])
+m4trace:configure.ac:954: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GETADDRINFO])
+m4trace:configure.ac:954: -1- m4_pattern_allow([^HAVE_GETADDRINFO$])
+m4trace:configure.ac:954: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GETADDRINFO])
+m4trace:configure.ac:954: -1- m4_pattern_allow([^HAVE_GETADDRINFO$])
+m4trace:configure.ac:954: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GETADDRINFO])
+m4trace:configure.ac:954: -1- m4_pattern_allow([^HAVE_GETADDRINFO$])
+m4trace:configure.ac:954: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GETADDRINFO])
+m4trace:configure.ac:954: -1- m4_pattern_allow([^HAVE_GETADDRINFO$])
+m4trace:configure.ac:954: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GETADDRINFO])
+m4trace:configure.ac:954: -1- m4_pattern_allow([^HAVE_GETADDRINFO$])
+m4trace:configure.ac:978: -1- AH_OUTPUT([HAVE_GETNAMEINFO], [/* Define to 1 if you have the `getnameinfo\' function. */
+@%:@undef HAVE_GETNAMEINFO])
+m4trace:configure.ac:978: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GETNAMEINFO])
+m4trace:configure.ac:978: -1- m4_pattern_allow([^HAVE_GETNAMEINFO$])
+m4trace:configure.ac:978: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GETNAMEINFO])
+m4trace:configure.ac:978: -1- m4_pattern_allow([^HAVE_GETNAMEINFO$])
+m4trace:configure.ac:978: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GETNAMEINFO])
+m4trace:configure.ac:978: -1- m4_pattern_allow([^HAVE_GETNAMEINFO$])
+m4trace:configure.ac:978: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GETNAMEINFO])
+m4trace:configure.ac:978: -1- m4_pattern_allow([^HAVE_GETNAMEINFO$])
+m4trace:configure.ac:978: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GETNAMEINFO])
+m4trace:configure.ac:978: -1- m4_pattern_allow([^HAVE_GETNAMEINFO$])
+m4trace:configure.ac:978: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GETNAMEINFO])
+m4trace:configure.ac:978: -1- m4_pattern_allow([^HAVE_GETNAMEINFO$])
+m4trace:configure.ac:999: -1- AH_OUTPUT([HAVE_GETHOSTBYNAME], [/* Define to 1 if you have the `gethostbyname\' function. */
+@%:@undef HAVE_GETHOSTBYNAME])
+m4trace:configure.ac:999: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GETHOSTBYNAME])
+m4trace:configure.ac:999: -1- m4_pattern_allow([^HAVE_GETHOSTBYNAME$])
+m4trace:configure.ac:999: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GETHOSTBYNAME])
+m4trace:configure.ac:999: -1- m4_pattern_allow([^HAVE_GETHOSTBYNAME$])
+m4trace:configure.ac:999: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GETHOSTBYNAME])
+m4trace:configure.ac:999: -1- m4_pattern_allow([^HAVE_GETHOSTBYNAME$])
+m4trace:configure.ac:999: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GETHOSTBYNAME])
+m4trace:configure.ac:999: -1- m4_pattern_allow([^HAVE_GETHOSTBYNAME$])
+m4trace:configure.ac:999: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GETHOSTBYNAME])
+m4trace:configure.ac:999: -1- m4_pattern_allow([^HAVE_GETHOSTBYNAME$])
+m4trace:configure.ac:999: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GETHOSTBYNAME])
+m4trace:configure.ac:999: -1- m4_pattern_allow([^HAVE_GETHOSTBYNAME$])
+m4trace:configure.ac:1021: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1021: the top level])
+m4trace:configure.ac:1021: -1- AC_DEFINE_TRACE_LITERAL([HAVE_HTONS])
+m4trace:configure.ac:1021: -1- m4_pattern_allow([^HAVE_HTONS$])
+m4trace:configure.ac:1049: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1049: the top level])
+m4trace:configure.ac:1049: -1- AC_DEFINE_TRACE_LITERAL([HAVE_NTOHS])
+m4trace:configure.ac:1049: -1- m4_pattern_allow([^HAVE_NTOHS$])
+m4trace:configure.ac:1077: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1077: the top level])
+m4trace:configure.ac:1077: -1- AC_DEFINE_TRACE_LITERAL([HAVE_HTONL])
+m4trace:configure.ac:1077: -1- m4_pattern_allow([^HAVE_HTONL$])
+m4trace:configure.ac:1105: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1105: the top level])
+m4trace:configure.ac:1105: -1- AC_DEFINE_TRACE_LITERAL([HAVE_NTOHL])
+m4trace:configure.ac:1105: -1- m4_pattern_allow([^HAVE_NTOHL$])
+m4trace:configure.ac:1132: -1- AH_OUTPUT([HAVE_INET_ADDR], [/* Define to 1 if you have the `inet_addr\' function. */
+@%:@undef HAVE_INET_ADDR])
+m4trace:configure.ac:1132: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INET_ADDR])
+m4trace:configure.ac:1132: -1- m4_pattern_allow([^HAVE_INET_ADDR$])
+m4trace:configure.ac:1132: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INET_ADDR])
+m4trace:configure.ac:1132: -1- m4_pattern_allow([^HAVE_INET_ADDR$])
+m4trace:configure.ac:1132: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INET_ADDR])
+m4trace:configure.ac:1132: -1- m4_pattern_allow([^HAVE_INET_ADDR$])
+m4trace:configure.ac:1132: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INET_ADDR])
+m4trace:configure.ac:1132: -1- m4_pattern_allow([^HAVE_INET_ADDR$])
+m4trace:configure.ac:1132: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INET_ADDR])
+m4trace:configure.ac:1132: -1- m4_pattern_allow([^HAVE_INET_ADDR$])
+m4trace:configure.ac:1132: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INET_ADDR])
+m4trace:configure.ac:1132: -1- m4_pattern_allow([^HAVE_INET_ADDR$])
+m4trace:configure.ac:1153: -1- AH_OUTPUT([HAVE_INET_ATON], [/* Define to 1 if you have the `inet_aton\' function. */
+@%:@undef HAVE_INET_ATON])
+m4trace:configure.ac:1153: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INET_ATON])
+m4trace:configure.ac:1153: -1- m4_pattern_allow([^HAVE_INET_ATON$])
+m4trace:configure.ac:1153: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INET_ATON])
+m4trace:configure.ac:1153: -1- m4_pattern_allow([^HAVE_INET_ATON$])
+m4trace:configure.ac:1153: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INET_ATON])
+m4trace:configure.ac:1153: -1- m4_pattern_allow([^HAVE_INET_ATON$])
+m4trace:configure.ac:1153: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INET_ATON])
+m4trace:configure.ac:1153: -1- m4_pattern_allow([^HAVE_INET_ATON$])
+m4trace:configure.ac:1153: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INET_ATON])
+m4trace:configure.ac:1153: -1- m4_pattern_allow([^HAVE_INET_ATON$])
+m4trace:configure.ac:1153: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INET_ATON])
+m4trace:configure.ac:1153: -1- m4_pattern_allow([^HAVE_INET_ATON$])
+m4trace:configure.ac:1174: -1- AH_OUTPUT([HAVE_INET_PTON], [/* Define to 1 if you have the `inet_pton\' function. */
+@%:@undef HAVE_INET_PTON])
+m4trace:configure.ac:1174: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INET_PTON])
+m4trace:configure.ac:1174: -1- m4_pattern_allow([^HAVE_INET_PTON$])
+m4trace:configure.ac:1174: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INET_PTON])
+m4trace:configure.ac:1174: -1- m4_pattern_allow([^HAVE_INET_PTON$])
+m4trace:configure.ac:1174: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INET_PTON])
+m4trace:configure.ac:1174: -1- m4_pattern_allow([^HAVE_INET_PTON$])
+m4trace:configure.ac:1174: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INET_PTON])
+m4trace:configure.ac:1174: -1- m4_pattern_allow([^HAVE_INET_PTON$])
+m4trace:configure.ac:1174: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INET_PTON])
+m4trace:configure.ac:1174: -1- m4_pattern_allow([^HAVE_INET_PTON$])
+m4trace:configure.ac:1174: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INET_PTON])
+m4trace:configure.ac:1174: -1- m4_pattern_allow([^HAVE_INET_PTON$])
+m4trace:configure.ac:1195: -1- AH_OUTPUT([HAVE_INET_NTOP], [/* Define to 1 if you have the `inet_ntop\' function. */
+@%:@undef HAVE_INET_NTOP])
+m4trace:configure.ac:1195: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INET_NTOP])
+m4trace:configure.ac:1195: -1- m4_pattern_allow([^HAVE_INET_NTOP$])
+m4trace:configure.ac:1195: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INET_NTOP])
+m4trace:configure.ac:1195: -1- m4_pattern_allow([^HAVE_INET_NTOP$])
+m4trace:configure.ac:1195: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INET_NTOP])
+m4trace:configure.ac:1195: -1- m4_pattern_allow([^HAVE_INET_NTOP$])
+m4trace:configure.ac:1195: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INET_NTOP])
+m4trace:configure.ac:1195: -1- m4_pattern_allow([^HAVE_INET_NTOP$])
+m4trace:configure.ac:1195: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INET_NTOP])
+m4trace:configure.ac:1195: -1- m4_pattern_allow([^HAVE_INET_NTOP$])
+m4trace:configure.ac:1195: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INET_NTOP])
+m4trace:configure.ac:1195: -1- m4_pattern_allow([^HAVE_INET_NTOP$])
+m4trace:configure.ac:1223: -1- _m4_warn([obsolete], [The macro `AC_TRY_RUN' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2764: AC_TRY_RUN is expanded from...
+configure.ac:1223: the top level])
+m4trace:configure.ac:1223: -1- AC_DEFINE_TRACE_LITERAL([HAVE_PROC_PID_EXE])
+m4trace:configure.ac:1223: -1- m4_pattern_allow([^HAVE_PROC_PID_EXE$])
+m4trace:configure.ac:1274: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1274: the top level])
+m4trace:configure.ac:1274: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SSIZE_T])
+m4trace:configure.ac:1274: -1- m4_pattern_allow([^HAVE_SSIZE_T$])
+m4trace:configure.ac:1289: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1289: the top level])
+m4trace:configure.ac:1289: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INT8_T])
+m4trace:configure.ac:1289: -1- m4_pattern_allow([^HAVE_INT8_T$])
+m4trace:configure.ac:1307: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1307: the top level])
+m4trace:configure.ac:1307: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INT16_T])
+m4trace:configure.ac:1307: -1- m4_pattern_allow([^HAVE_INT16_T$])
+m4trace:configure.ac:1325: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1325: the top level])
+m4trace:configure.ac:1325: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INT32_T])
+m4trace:configure.ac:1325: -1- m4_pattern_allow([^HAVE_INT32_T$])
+m4trace:configure.ac:1344: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1344: the top level])
+m4trace:configure.ac:1344: -1- AC_DEFINE_TRACE_LITERAL([HAVE_UINT8_T])
+m4trace:configure.ac:1344: -1- m4_pattern_allow([^HAVE_UINT8_T$])
+m4trace:configure.ac:1363: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1363: the top level])
+m4trace:configure.ac:1363: -1- AC_DEFINE_TRACE_LITERAL([HAVE_UINT16_T])
+m4trace:configure.ac:1363: -1- m4_pattern_allow([^HAVE_UINT16_T$])
+m4trace:configure.ac:1382: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1382: the top level])
+m4trace:configure.ac:1382: -1- AC_DEFINE_TRACE_LITERAL([HAVE_UINT32_T])
+m4trace:configure.ac:1382: -1- m4_pattern_allow([^HAVE_UINT32_T$])
+m4trace:configure.ac:1401: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1401: the top level])
+m4trace:configure.ac:1401: -1- AC_DEFINE_TRACE_LITERAL([HAVE_DEV_T])
+m4trace:configure.ac:1401: -1- m4_pattern_allow([^HAVE_DEV_T$])
+m4trace:configure.ac:1418: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1418: the top level])
+m4trace:configure.ac:1418: -1- AC_DEFINE_TRACE_LITERAL([HAVE__DEV_T])
+m4trace:configure.ac:1418: -1- m4_pattern_allow([^HAVE__DEV_T$])
+m4trace:configure.ac:1435: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1435: the top level])
+m4trace:configure.ac:1435: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INO_T])
+m4trace:configure.ac:1435: -1- m4_pattern_allow([^HAVE_INO_T$])
+m4trace:configure.ac:1452: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1452: the top level])
+m4trace:configure.ac:1452: -1- AC_DEFINE_TRACE_LITERAL([HAVE__INO_T])
+m4trace:configure.ac:1452: -1- m4_pattern_allow([^HAVE__INO_T$])
+m4trace:configure.ac:1469: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1469: the top level])
+m4trace:configure.ac:1469: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INO64_T])
+m4trace:configure.ac:1469: -1- m4_pattern_allow([^HAVE_INO64_T$])
+m4trace:configure.ac:1487: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1487: the top level])
+m4trace:configure.ac:1487: -1- AC_DEFINE_TRACE_LITERAL([HAVE_MODE_T])
+m4trace:configure.ac:1487: -1- m4_pattern_allow([^HAVE_MODE_T$])
+m4trace:configure.ac:1504: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1504: the top level])
+m4trace:configure.ac:1504: -1- AC_DEFINE_TRACE_LITERAL([HAVE_NLINK_T])
+m4trace:configure.ac:1504: -1- m4_pattern_allow([^HAVE_NLINK_T$])
+m4trace:configure.ac:1521: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1521: the top level])
+m4trace:configure.ac:1521: -1- AC_DEFINE_TRACE_LITERAL([HAVE_UID_T])
+m4trace:configure.ac:1521: -1- m4_pattern_allow([^HAVE_UID_T$])
+m4trace:configure.ac:1538: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1538: the top level])
+m4trace:configure.ac:1538: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GID_T])
+m4trace:configure.ac:1538: -1- m4_pattern_allow([^HAVE_GID_T$])
+m4trace:configure.ac:1555: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1555: the top level])
+m4trace:configure.ac:1555: -1- AC_DEFINE_TRACE_LITERAL([HAVE_OFF_T])
+m4trace:configure.ac:1555: -1- m4_pattern_allow([^HAVE_OFF_T$])
+m4trace:configure.ac:1572: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1572: the top level])
+m4trace:configure.ac:1572: -1- AC_DEFINE_TRACE_LITERAL([HAVE_OFF64_T])
+m4trace:configure.ac:1572: -1- m4_pattern_allow([^HAVE_OFF64_T$])
+m4trace:configure.ac:1590: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1590: the top level])
+m4trace:configure.ac:1590: -1- AC_DEFINE_TRACE_LITERAL([HAVE_BLKSIZE_T])
+m4trace:configure.ac:1590: -1- m4_pattern_allow([^HAVE_BLKSIZE_T$])
+m4trace:configure.ac:1607: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1607: the top level])
+m4trace:configure.ac:1607: -1- AC_DEFINE_TRACE_LITERAL([HAVE_BLKCNT_T])
+m4trace:configure.ac:1607: -1- m4_pattern_allow([^HAVE_BLKCNT_T$])
+m4trace:configure.ac:1624: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1624: the top level])
+m4trace:configure.ac:1624: -1- AC_DEFINE_TRACE_LITERAL([HAVE_FPOS_T])
+m4trace:configure.ac:1624: -1- m4_pattern_allow([^HAVE_FPOS_T$])
+m4trace:configure.ac:1642: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1642: the top level])
+m4trace:configure.ac:1642: -1- AC_DEFINE_TRACE_LITERAL([HAVE_FILE_BLKSIZECNT])
+m4trace:configure.ac:1642: -1- m4_pattern_allow([^HAVE_FILE_BLKSIZECNT$])
+m4trace:configure.ac:1670: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1670: the top level])
+m4trace:configure.ac:1670: -1- AC_DEFINE_TRACE_LITERAL([HAVE__FPOS_T])
+m4trace:configure.ac:1670: -1- m4_pattern_allow([^HAVE__FPOS_T$])
+m4trace:configure.ac:1688: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1688: the top level])
+m4trace:configure.ac:1688: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SOCKLEN_T])
+m4trace:configure.ac:1688: -1- m4_pattern_allow([^HAVE_SOCKLEN_T$])
+m4trace:configure.ac:1712: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1712: the top level])
+m4trace:configure.ac:1712: -1- AC_DEFINE_TRACE_LITERAL([HAVE_STRUCT_SOCKADDR_IN])
+m4trace:configure.ac:1712: -1- m4_pattern_allow([^HAVE_STRUCT_SOCKADDR_IN$])
+m4trace:configure.ac:1736: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1736: the top level])
+m4trace:configure.ac:1736: -1- AC_DEFINE_TRACE_LITERAL([HAVE_STRUCT_SOCKADDR_IN6])
+m4trace:configure.ac:1736: -1- m4_pattern_allow([^HAVE_STRUCT_SOCKADDR_IN6$])
+m4trace:configure.ac:1760: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1760: the top level])
+m4trace:configure.ac:1760: -1- AC_DEFINE_TRACE_LITERAL([HAVE_STRUCT_SOCKADDR_UN])
+m4trace:configure.ac:1760: -1- m4_pattern_allow([^HAVE_STRUCT_SOCKADDR_UN$])
+m4trace:configure.ac:1787: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1787: the top level])
+m4trace:configure.ac:1787: -1- AC_DEFINE_TRACE_LITERAL([HAVE_STRUCT_ADDRINFO])
+m4trace:configure.ac:1787: -1- m4_pattern_allow([^HAVE_STRUCT_ADDRINFO$])
+m4trace:configure.ac:1811: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1811: the top level])
+m4trace:configure.ac:1811: -1- AC_DEFINE_TRACE_LITERAL([HAVE_STRUCT_SOCKADDR_STORAGE])
+m4trace:configure.ac:1811: -1- m4_pattern_allow([^HAVE_STRUCT_SOCKADDR_STORAGE$])
+m4trace:configure.ac:1841: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1841: the top level])
+m4trace:configure.ac:1841: -1- AC_DEFINE_TRACE_LITERAL([HAVE_IN_ADDR])
+m4trace:configure.ac:1841: -1- m4_pattern_allow([^HAVE_IN_ADDR$])
+m4trace:configure.ac:1874: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1874: the top level])
+m4trace:configure.ac:1874: -1- AC_DEFINE_TRACE_LITERAL([HAVE_IN6_ADDR])
+m4trace:configure.ac:1874: -1- m4_pattern_allow([^HAVE_IN6_ADDR$])
+m4trace:configure.ac:1907: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1907: the top level])
+m4trace:configure.ac:1907: -1- AC_DEFINE_TRACE_LITERAL([HAVE_RAND])
+m4trace:configure.ac:1907: -1- m4_pattern_allow([^HAVE_RAND$])
+m4trace:configure.ac:1907: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SRAND])
+m4trace:configure.ac:1907: -1- m4_pattern_allow([^HAVE_SRAND$])
+m4trace:configure.ac:1919: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1919: the top level])
+m4trace:configure.ac:1919: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INITSTATE])
+m4trace:configure.ac:1919: -1- m4_pattern_allow([^HAVE_INITSTATE$])
+m4trace:configure.ac:1919: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SETSTATE])
+m4trace:configure.ac:1919: -1- m4_pattern_allow([^HAVE_SETSTATE$])
+m4trace:configure.ac:1919: -1- AC_DEFINE_TRACE_LITERAL([HAVE_RANDOM])
+m4trace:configure.ac:1919: -1- m4_pattern_allow([^HAVE_RANDOM$])
+m4trace:configure.ac:1936: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:1936: the top level])
+m4trace:configure.ac:1936: -1- AC_DEFINE_TRACE_LITERAL([HAVE_LRAND48])
+m4trace:configure.ac:1936: -1- m4_pattern_allow([^HAVE_LRAND48$])
+m4trace:configure.ac:1936: -1- AC_DEFINE_TRACE_LITERAL([HAVE_NRAND48])
+m4trace:configure.ac:1936: -1- m4_pattern_allow([^HAVE_NRAND48$])
+m4trace:configure.ac:1954: -1- AC_DEFINE_TRACE_LITERAL([SIZEOF_OFF_T])
+m4trace:configure.ac:1954: -1- m4_pattern_allow([^SIZEOF_OFF_T$])
+m4trace:configure.ac:1954: -1- AH_OUTPUT([SIZEOF_OFF_T], [/* The size of `off_t\', as computed by sizeof. */
+@%:@undef SIZEOF_OFF_T])
+m4trace:configure.ac:1955: -1- AC_DEFINE_TRACE_LITERAL([SIZEOF_OFF64_T])
+m4trace:configure.ac:1955: -1- m4_pattern_allow([^SIZEOF_OFF64_T$])
+m4trace:configure.ac:1955: -1- AH_OUTPUT([SIZEOF_OFF64_T], [/* The size of `off64_t\', as computed by sizeof. */
+@%:@undef SIZEOF_OFF64_T])
+m4trace:configure.ac:1956: -1- AC_DEFINE_TRACE_LITERAL([SIZEOF_INO_T])
+m4trace:configure.ac:1956: -1- m4_pattern_allow([^SIZEOF_INO_T$])
+m4trace:configure.ac:1956: -1- AH_OUTPUT([SIZEOF_INO_T], [/* The size of `ino_t\', as computed by sizeof. */
+@%:@undef SIZEOF_INO_T])
+m4trace:configure.ac:1957: -1- AC_DEFINE_TRACE_LITERAL([SIZEOF_INO64_T])
+m4trace:configure.ac:1957: -1- m4_pattern_allow([^SIZEOF_INO64_T$])
+m4trace:configure.ac:1957: -1- AH_OUTPUT([SIZEOF_INO64_T], [/* The size of `ino64_t\', as computed by sizeof. */
+@%:@undef SIZEOF_INO64_T])
+m4trace:configure.ac:1962: -1- AC_DEFINE_TRACE_LITERAL([USE_FALLBACK_NUMERIC_LIMITS])
+m4trace:configure.ac:1962: -1- m4_pattern_allow([^USE_FALLBACK_NUMERIC_LIMITS$])
+m4trace:configure.ac:1971: -1- AC_DEFINE_TRACE_LITERAL([USE_PRINTF_SCANF])
+m4trace:configure.ac:1971: -1- m4_pattern_allow([^USE_PRINTF_SCANF$])
+m4trace:configure.ac:1975: -1- AC_DEFINE_TRACE_LITERAL([HAVE_FILE_DEVINO])
+m4trace:configure.ac:1975: -1- m4_pattern_allow([^HAVE_FILE_DEVINO$])
+m4trace:configure.ac:1976: -1- AC_DEFINE_TRACE_LITERAL([HAVE_FILE_UIDGID])
+m4trace:configure.ac:1976: -1- m4_pattern_allow([^HAVE_FILE_UIDGID$])
+m4trace:configure.ac:1977: -1- AC_DEFINE_TRACE_LITERAL([HAVE_FILE_ATIMECTIME])
+m4trace:configure.ac:1977: -1- m4_pattern_allow([^HAVE_FILE_ATIMECTIME$])
+m4trace:configure.ac:1981: -1- AC_DEFINE_TRACE_LITERAL([HAVE_COMPATDKTOOLS3])
+m4trace:configure.ac:1981: -1- m4_pattern_allow([^HAVE_COMPATDKTOOLS3$])
+m4trace:configure.ac:1998: -1- AC_DEFINE_TRACE_LITERAL([HAVE_WXWIDGETS])
+m4trace:configure.ac:1998: -1- m4_pattern_allow([^HAVE_WXWIDGETS$])
+m4trace:configure.ac:2018: -1- AC_DEFINE_TRACE_LITERAL([HAVE_WX_CHARTYPE_H])
+m4trace:configure.ac:2018: -1- m4_pattern_allow([^HAVE_WX_CHARTYPE_H$])
+m4trace:configure.ac:2021: -1- AC_DEFINE_TRACE_LITERAL([HAVE_WX_WXCHAR_H])
+m4trace:configure.ac:2021: -1- m4_pattern_allow([^HAVE_WX_WXCHAR_H$])
+m4trace:configure.ac:2041: -2- AC_DEFINE_TRACE_LITERAL([HAVE_STDIO_H])
+m4trace:configure.ac:2041: -2- m4_pattern_allow([^HAVE_STDIO_H$])
+m4trace:configure.ac:2041: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:2041: the top level])
+m4trace:configure.ac:2042: -2- AC_DEFINE_TRACE_LITERAL([HAVE_CONIO_H])
+m4trace:configure.ac:2042: -2- m4_pattern_allow([^HAVE_CONIO_H$])
+m4trace:configure.ac:2042: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:2042: the top level])
+m4trace:configure.ac:2043: -2- AC_DEFINE_TRACE_LITERAL([HAVE_GRP_H])
+m4trace:configure.ac:2043: -2- m4_pattern_allow([^HAVE_GRP_H$])
+m4trace:configure.ac:2043: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:2043: the top level])
+m4trace:configure.ac:2044: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:2044: the top level])
+m4trace:configure.ac:2045: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:2045: the top level])
+m4trace:configure.ac:2048: -1- AC_DEFINE_TRACE_LITERAL([HAVE_NDBM_H])
+m4trace:configure.ac:2048: -1- m4_pattern_allow([^HAVE_NDBM_H$])
+m4trace:configure.ac:2052: -1- AC_DEFINE_TRACE_LITERAL([HAVE_NDBM_H])
+m4trace:configure.ac:2052: -1- m4_pattern_allow([^HAVE_NDBM_H$])
+m4trace:configure.ac:2056: -1- AC_DEFINE_TRACE_LITERAL([HAVE_NDBM_H])
+m4trace:configure.ac:2056: -1- m4_pattern_allow([^HAVE_NDBM_H$])
+m4trace:configure.ac:2062: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GDBM_H])
+m4trace:configure.ac:2062: -1- m4_pattern_allow([^HAVE_GDBM_H$])
+m4trace:configure.ac:2064: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:2064: the top level])
+m4trace:configure.ac:2064: -1- AC_DEFINE_TRACE_LITERAL([HAVE_DB_H])
+m4trace:configure.ac:2064: -1- m4_pattern_allow([^HAVE_DB_H$])
+m4trace:configure.ac:2065: -2- AC_DEFINE_TRACE_LITERAL([HAVE_DIR_H])
+m4trace:configure.ac:2065: -2- m4_pattern_allow([^HAVE_DIR_H$])
+m4trace:configure.ac:2065: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:2065: the top level])
+m4trace:configure.ac:2066: -2- AC_DEFINE_TRACE_LITERAL([HAVE_ERR_H])
+m4trace:configure.ac:2066: -2- m4_pattern_allow([^HAVE_ERR_H$])
+m4trace:configure.ac:2066: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:2066: the top level])
+m4trace:configure.ac:2067: -2- AC_DEFINE_TRACE_LITERAL([HAVE_SHADOW_H])
+m4trace:configure.ac:2067: -2- m4_pattern_allow([^HAVE_SHADOW_H$])
+m4trace:configure.ac:2067: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:2067: the top level])
+m4trace:configure.ac:2068: -2- AC_DEFINE_TRACE_LITERAL([HAVE_STROPTS_H])
+m4trace:configure.ac:2068: -2- m4_pattern_allow([^HAVE_STROPTS_H$])
+m4trace:configure.ac:2068: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:2068: the top level])
+m4trace:configure.ac:2069: -2- AC_DEFINE_TRACE_LITERAL([HAVE_SYSLOG_H])
+m4trace:configure.ac:2069: -2- m4_pattern_allow([^HAVE_SYSLOG_H$])
+m4trace:configure.ac:2069: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:2069: the top level])
+m4trace:configure.ac:2070: -2- AC_DEFINE_TRACE_LITERAL([HAVE_SYSRES_H])
+m4trace:configure.ac:2070: -2- m4_pattern_allow([^HAVE_SYSRES_H$])
+m4trace:configure.ac:2070: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:2070: the top level])
+m4trace:configure.ac:2071: -2- AC_DEFINE_TRACE_LITERAL([HAVE_TERMIOS_H])
+m4trace:configure.ac:2071: -2- m4_pattern_allow([^HAVE_TERMIOS_H$])
+m4trace:configure.ac:2071: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:2071: the top level])
+m4trace:configure.ac:2072: -2- AC_DEFINE_TRACE_LITERAL([HAVE_VARARG_H])
+m4trace:configure.ac:2072: -2- m4_pattern_allow([^HAVE_VARARG_H$])
+m4trace:configure.ac:2072: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:2072: the top level])
+m4trace:configure.ac:2073: -2- AC_DEFINE_TRACE_LITERAL([HAVE_VARARGS_H])
+m4trace:configure.ac:2073: -2- m4_pattern_allow([^HAVE_VARARGS_H$])
+m4trace:configure.ac:2073: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:2073: the top level])
+m4trace:configure.ac:2074: -2- AC_DEFINE_TRACE_LITERAL([HAVE_NTIFS_H])
+m4trace:configure.ac:2074: -2- m4_pattern_allow([^HAVE_NTIFS_H$])
+m4trace:configure.ac:2074: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:2074: the top level])
+m4trace:configure.ac:2075: -2- AC_DEFINE_TRACE_LITERAL([HAVE_SYS_FILE_H])
+m4trace:configure.ac:2075: -2- m4_pattern_allow([^HAVE_SYS_FILE_H$])
+m4trace:configure.ac:2075: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:2075: the top level])
+m4trace:configure.ac:2076: -2- AC_DEFINE_TRACE_LITERAL([HAVE_SYS_RESOURCE_H])
+m4trace:configure.ac:2076: -2- m4_pattern_allow([^HAVE_SYS_RESOURCE_H$])
+m4trace:configure.ac:2076: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:2076: the top level])
+m4trace:configure.ac:2077: -2- AC_DEFINE_TRACE_LITERAL([HAVE_SYS_STATVFS_H])
+m4trace:configure.ac:2077: -2- m4_pattern_allow([^HAVE_SYS_STATVFS_H$])
+m4trace:configure.ac:2077: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:2077: the top level])
+m4trace:configure.ac:2078: -2- AC_DEFINE_TRACE_LITERAL([HAVE_SYS_STROPTS_H])
+m4trace:configure.ac:2078: -2- m4_pattern_allow([^HAVE_SYS_STROPTS_H$])
+m4trace:configure.ac:2078: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:2078: the top level])
+m4trace:configure.ac:2079: -2- AC_DEFINE_TRACE_LITERAL([HAVE_SYS_SUNDDI_H])
+m4trace:configure.ac:2079: -2- m4_pattern_allow([^HAVE_SYS_SUNDDI_H$])
+m4trace:configure.ac:2079: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:2079: the top level])
+m4trace:configure.ac:2080: -2- AC_DEFINE_TRACE_LITERAL([HAVE_SYS_SYSCTL_H])
+m4trace:configure.ac:2080: -2- m4_pattern_allow([^HAVE_SYS_SYSCTL_H$])
+m4trace:configure.ac:2080: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:2080: the top level])
+m4trace:configure.ac:2081: -2- AC_DEFINE_TRACE_LITERAL([HAVE_SYS_SYSTEMINFO_H])
+m4trace:configure.ac:2081: -2- m4_pattern_allow([^HAVE_SYS_SYSTEMINFO_H$])
+m4trace:configure.ac:2081: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:2081: the top level])
+m4trace:configure.ac:2082: -2- AC_DEFINE_TRACE_LITERAL([HAVE_SYS_TERMIOS_H])
+m4trace:configure.ac:2082: -2- m4_pattern_allow([^HAVE_SYS_TERMIOS_H$])
+m4trace:configure.ac:2082: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:2082: the top level])
+m4trace:configure.ac:2083: -2- AC_DEFINE_TRACE_LITERAL([HAVE_SYS_TTOLD_H])
+m4trace:configure.ac:2083: -2- m4_pattern_allow([^HAVE_SYS_TTOLD_H$])
+m4trace:configure.ac:2083: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:2083: the top level])
+m4trace:configure.ac:2084: -2- AC_DEFINE_TRACE_LITERAL([HAVE_SYS_UIO_H])
+m4trace:configure.ac:2084: -2- m4_pattern_allow([^HAVE_SYS_UIO_H$])
+m4trace:configure.ac:2084: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:2084: the top level])
+m4trace:configure.ac:2085: -2- AC_DEFINE_TRACE_LITERAL([HAVE_SYS_WAIT_H])
+m4trace:configure.ac:2085: -2- m4_pattern_allow([^HAVE_SYS_WAIT_H$])
+m4trace:configure.ac:2085: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:2085: the top level])
+m4trace:configure.ac:2087: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:2087: the top level])
+m4trace:configure.ac:2087: -1- AC_DEFINE_TRACE_LITERAL([HAVE_WINBASE_H])
+m4trace:configure.ac:2087: -1- m4_pattern_allow([^HAVE_WINBASE_H$])
+m4trace:configure.ac:2092: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:2092: the top level])
+m4trace:configure.ac:2092: -1- AC_DEFINE_TRACE_LITERAL([HAVE_WINREG_H])
+m4trace:configure.ac:2092: -1- m4_pattern_allow([^HAVE_WINREG_H$])
+m4trace:configure.ac:2100: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:2100: the top level])
+m4trace:configure.ac:2100: -1- AC_DEFINE_TRACE_LITERAL([HAVE_WINCON_H])
+m4trace:configure.ac:2100: -1- m4_pattern_allow([^HAVE_WINCON_H$])
+m4trace:configure.ac:2108: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:2108: the top level])
+m4trace:configure.ac:2108: -1- AC_DEFINE_TRACE_LITERAL([HAVE_PNG_H])
+m4trace:configure.ac:2108: -1- m4_pattern_allow([^HAVE_PNG_H$])
+m4trace:configure.ac:2109: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:2109: the top level])
+m4trace:configure.ac:2109: -1- AC_DEFINE_TRACE_LITERAL([HAVE_JPEGLIB_H])
+m4trace:configure.ac:2109: -1- m4_pattern_allow([^HAVE_JPEGLIB_H$])
+m4trace:configure.ac:2110: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:2110: the top level])
+m4trace:configure.ac:2110: -1- AC_DEFINE_TRACE_LITERAL([HAVE_TIFF_H])
+m4trace:configure.ac:2110: -1- m4_pattern_allow([^HAVE_TIFF_H$])
+m4trace:configure.ac:2111: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:2111: the top level])
+m4trace:configure.ac:2111: -1- AC_DEFINE_TRACE_LITERAL([HAVE_MYSQL_MYSQL_H])
+m4trace:configure.ac:2111: -1- m4_pattern_allow([^HAVE_MYSQL_MYSQL_H$])
+m4trace:configure.ac:2111: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+../../lib/m4sugar/m4sh.m4:639: AS_IF is expanded from...
+../../lib/autoconf/headers.m4:129: _AC_CHECK_HEADER_MONGREL is expanded from...
+../../lib/autoconf/headers.m4:67: AC_CHECK_HEADER is expanded from...
+../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:2111: the top level])
+m4trace:configure.ac:2111: -1- AC_DEFINE_TRACE_LITERAL([HAVE_MYSQL_H])
+m4trace:configure.ac:2111: -1- m4_pattern_allow([^HAVE_MYSQL_H$])
+m4trace:configure.ac:2124: -2- AC_DEFINE_TRACE_LITERAL([HAVE_LPRNG_H])
+m4trace:configure.ac:2124: -2- m4_pattern_allow([^HAVE_LPRNG_H$])
+m4trace:configure.ac:2124: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:2124: the top level])
+m4trace:configure.ac:2125: -1- _m4_warn([obsolete], [The macro `AC_HEADER_CHECK' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/oldnames.m4:36: AC_HEADER_CHECK is expanded from...
+configure.ac:2125: the top level])
+m4trace:configure.ac:2125: -1- AC_DEFINE_TRACE_LITERAL([HAVE_PTHREAD_H])
+m4trace:configure.ac:2125: -1- m4_pattern_allow([^HAVE_PTHREAD_H$])
+m4trace:configure.ac:2126: -2- AC_DEFINE_TRACE_LITERAL([HAVE_ACOSH])
+m4trace:configure.ac:2126: -2- m4_pattern_allow([^HAVE_ACOSH$])
+m4trace:configure.ac:2127: -2- AC_DEFINE_TRACE_LITERAL([HAVE_ACOSHL])
+m4trace:configure.ac:2127: -2- m4_pattern_allow([^HAVE_ACOSHL$])
+m4trace:configure.ac:2128: -2- AC_DEFINE_TRACE_LITERAL([HAVE_ACOSL])
+m4trace:configure.ac:2128: -2- m4_pattern_allow([^HAVE_ACOSL$])
+m4trace:configure.ac:2129: -2- AC_DEFINE_TRACE_LITERAL([HAVE_ASINH])
+m4trace:configure.ac:2129: -2- m4_pattern_allow([^HAVE_ASINH$])
+m4trace:configure.ac:2130: -2- AC_DEFINE_TRACE_LITERAL([HAVE_ASINHL])
+m4trace:configure.ac:2130: -2- m4_pattern_allow([^HAVE_ASINHL$])
+m4trace:configure.ac:2131: -2- AC_DEFINE_TRACE_LITERAL([HAVE_ASINL])
+m4trace:configure.ac:2131: -2- m4_pattern_allow([^HAVE_ASINL$])
+m4trace:configure.ac:2132: -2- AC_DEFINE_TRACE_LITERAL([HAVE_ATAN2])
+m4trace:configure.ac:2132: -2- m4_pattern_allow([^HAVE_ATAN2$])
+m4trace:configure.ac:2133: -2- AC_DEFINE_TRACE_LITERAL([HAVE_ATAN2L])
+m4trace:configure.ac:2133: -2- m4_pattern_allow([^HAVE_ATAN2L$])
+m4trace:configure.ac:2134: -2- AC_DEFINE_TRACE_LITERAL([HAVE_ATANH])
+m4trace:configure.ac:2134: -2- m4_pattern_allow([^HAVE_ATANH$])
+m4trace:configure.ac:2135: -2- AC_DEFINE_TRACE_LITERAL([HAVE_ATANHL])
+m4trace:configure.ac:2135: -2- m4_pattern_allow([^HAVE_ATANHL$])
+m4trace:configure.ac:2136: -2- AC_DEFINE_TRACE_LITERAL([HAVE_ATANL])
+m4trace:configure.ac:2136: -2- m4_pattern_allow([^HAVE_ATANL$])
+m4trace:configure.ac:2137: -2- AC_DEFINE_TRACE_LITERAL([HAVE_CEIL])
+m4trace:configure.ac:2137: -2- m4_pattern_allow([^HAVE_CEIL$])
+m4trace:configure.ac:2138: -2- AC_DEFINE_TRACE_LITERAL([HAVE_CEILL])
+m4trace:configure.ac:2138: -2- m4_pattern_allow([^HAVE_CEILL$])
+m4trace:configure.ac:2139: -2- AC_DEFINE_TRACE_LITERAL([HAVE_COSHL])
+m4trace:configure.ac:2139: -2- m4_pattern_allow([^HAVE_COSHL$])
+m4trace:configure.ac:2140: -2- AC_DEFINE_TRACE_LITERAL([HAVE_COSL])
+m4trace:configure.ac:2140: -2- m4_pattern_allow([^HAVE_COSL$])
+m4trace:configure.ac:2141: -2- AC_DEFINE_TRACE_LITERAL([HAVE_EXPL])
+m4trace:configure.ac:2141: -2- m4_pattern_allow([^HAVE_EXPL$])
+m4trace:configure.ac:2142: -2- AC_DEFINE_TRACE_LITERAL([HAVE_FABS])
+m4trace:configure.ac:2142: -2- m4_pattern_allow([^HAVE_FABS$])
+m4trace:configure.ac:2143: -2- AC_DEFINE_TRACE_LITERAL([HAVE_FABSL])
+m4trace:configure.ac:2143: -2- m4_pattern_allow([^HAVE_FABSL$])
+m4trace:configure.ac:2144: -2- AC_DEFINE_TRACE_LITERAL([HAVE_FLOOR])
+m4trace:configure.ac:2144: -2- m4_pattern_allow([^HAVE_FLOOR$])
+m4trace:configure.ac:2145: -2- AC_DEFINE_TRACE_LITERAL([HAVE_FLOORL])
+m4trace:configure.ac:2145: -2- m4_pattern_allow([^HAVE_FLOORL$])
+m4trace:configure.ac:2146: -2- AC_DEFINE_TRACE_LITERAL([HAVE_LABS])
+m4trace:configure.ac:2146: -2- m4_pattern_allow([^HAVE_LABS$])
+m4trace:configure.ac:2147: -2- AC_DEFINE_TRACE_LITERAL([HAVE_LOGL])
+m4trace:configure.ac:2147: -2- m4_pattern_allow([^HAVE_LOGL$])
+m4trace:configure.ac:2148: -2- AC_DEFINE_TRACE_LITERAL([HAVE_RINT])
+m4trace:configure.ac:2148: -2- m4_pattern_allow([^HAVE_RINT$])
+m4trace:configure.ac:2149: -2- AC_DEFINE_TRACE_LITERAL([HAVE_RINTL])
+m4trace:configure.ac:2149: -2- m4_pattern_allow([^HAVE_RINTL$])
+m4trace:configure.ac:2150: -2- AC_DEFINE_TRACE_LITERAL([HAVE_SINHL])
+m4trace:configure.ac:2150: -2- m4_pattern_allow([^HAVE_SINHL$])
+m4trace:configure.ac:2151: -2- AC_DEFINE_TRACE_LITERAL([HAVE_SQRT])
+m4trace:configure.ac:2151: -2- m4_pattern_allow([^HAVE_SQRT$])
+m4trace:configure.ac:2152: -2- AC_DEFINE_TRACE_LITERAL([HAVE_SQRTL])
+m4trace:configure.ac:2152: -2- m4_pattern_allow([^HAVE_SQRTL$])
+m4trace:configure.ac:2153: -2- AC_DEFINE_TRACE_LITERAL([HAVE_SINL])
+m4trace:configure.ac:2153: -2- m4_pattern_allow([^HAVE_SINL$])
+m4trace:configure.ac:2154: -2- AC_DEFINE_TRACE_LITERAL([HAVE_TANHL])
+m4trace:configure.ac:2154: -2- m4_pattern_allow([^HAVE_TANHL$])
+m4trace:configure.ac:2155: -2- AC_DEFINE_TRACE_LITERAL([HAVE_TANL])
+m4trace:configure.ac:2155: -2- m4_pattern_allow([^HAVE_TANL$])
+m4trace:configure.ac:2156: -2- AC_DEFINE_TRACE_LITERAL([HAVE_PNG_GET_PIXELS_PER_INCH])
+m4trace:configure.ac:2156: -2- m4_pattern_allow([^HAVE_PNG_GET_PIXELS_PER_INCH$])
+m4trace:configure.ac:2157: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:2157: the top level])
+m4trace:configure.ac:2157: -1- AH_OUTPUT([HAVE_GETUID], [/* Define to 1 if you have the `getuid\' function. */
+@%:@undef HAVE_GETUID])
+m4trace:configure.ac:2157: -1- AH_OUTPUT([HAVE_SETUID], [/* Define to 1 if you have the `setuid\' function. */
+@%:@undef HAVE_SETUID])
+m4trace:configure.ac:2157: -1- AH_OUTPUT([HAVE_SETGID], [/* Define to 1 if you have the `setgid\' function. */
+@%:@undef HAVE_SETGID])
+m4trace:configure.ac:2158: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:2158: the top level])
+m4trace:configure.ac:2158: -1- AH_OUTPUT([HAVE_CHDIR], [/* Define to 1 if you have the `chdir\' function. */
+@%:@undef HAVE_CHDIR])
+m4trace:configure.ac:2158: -1- AH_OUTPUT([HAVE_CHMOD], [/* Define to 1 if you have the `chmod\' function. */
+@%:@undef HAVE_CHMOD])
+m4trace:configure.ac:2158: -1- AH_OUTPUT([HAVE_CHOWN], [/* Define to 1 if you have the `chown\' function. */
+@%:@undef HAVE_CHOWN])
+m4trace:configure.ac:2159: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:2159: the top level])
+m4trace:configure.ac:2159: -1- AH_OUTPUT([HAVE_OPENDIR], [/* Define to 1 if you have the `opendir\' function. */
+@%:@undef HAVE_OPENDIR])
+m4trace:configure.ac:2159: -1- AH_OUTPUT([HAVE_READDIR], [/* Define to 1 if you have the `readdir\' function. */
+@%:@undef HAVE_READDIR])
+m4trace:configure.ac:2159: -1- AH_OUTPUT([HAVE_CLOSEDIR], [/* Define to 1 if you have the `closedir\' function. */
+@%:@undef HAVE_CLOSEDIR])
+m4trace:configure.ac:2160: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:2160: the top level])
+m4trace:configure.ac:2160: -1- AH_OUTPUT([HAVE_GETGRENT], [/* Define to 1 if you have the `getgrent\' function. */
+@%:@undef HAVE_GETGRENT])
+m4trace:configure.ac:2160: -1- AH_OUTPUT([HAVE_GETGRGID], [/* Define to 1 if you have the `getgrgid\' function. */
+@%:@undef HAVE_GETGRGID])
+m4trace:configure.ac:2160: -1- AH_OUTPUT([HAVE_GETGRNAM], [/* Define to 1 if you have the `getgrnam\' function. */
+@%:@undef HAVE_GETGRNAM])
+m4trace:configure.ac:2160: -1- AH_OUTPUT([HAVE_ENDGRENT], [/* Define to 1 if you have the `endgrent\' function. */
+@%:@undef HAVE_ENDGRENT])
+m4trace:configure.ac:2160: -1- AH_OUTPUT([HAVE_SETGRENT], [/* Define to 1 if you have the `setgrent\' function. */
+@%:@undef HAVE_SETGRENT])
+m4trace:configure.ac:2161: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:2161: the top level])
+m4trace:configure.ac:2161: -1- AH_OUTPUT([HAVE_GETPWUID], [/* Define to 1 if you have the `getpwuid\' function. */
+@%:@undef HAVE_GETPWUID])
+m4trace:configure.ac:2161: -1- AH_OUTPUT([HAVE_GETPWNAM], [/* Define to 1 if you have the `getpwnam\' function. */
+@%:@undef HAVE_GETPWNAM])
+m4trace:configure.ac:2162: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:2162: the top level])
+m4trace:configure.ac:2162: -1- AH_OUTPUT([HAVE_FOPEN], [/* Define to 1 if you have the `fopen\' function. */
+@%:@undef HAVE_FOPEN])
+m4trace:configure.ac:2162: -1- AH_OUTPUT([HAVE_FCLOSE], [/* Define to 1 if you have the `fclose\' function. */
+@%:@undef HAVE_FCLOSE])
+m4trace:configure.ac:2162: -1- AH_OUTPUT([HAVE_FEOF], [/* Define to 1 if you have the `feof\' function. */
+@%:@undef HAVE_FEOF])
+m4trace:configure.ac:2162: -1- AH_OUTPUT([HAVE_FERROR], [/* Define to 1 if you have the `ferror\' function. */
+@%:@undef HAVE_FERROR])
+m4trace:configure.ac:2162: -1- AH_OUTPUT([HAVE_FFLUSH], [/* Define to 1 if you have the `fflush\' function. */
+@%:@undef HAVE_FFLUSH])
+m4trace:configure.ac:2162: -1- AH_OUTPUT([HAVE_FREAD], [/* Define to 1 if you have the `fread\' function. */
+@%:@undef HAVE_FREAD])
+m4trace:configure.ac:2162: -1- AH_OUTPUT([HAVE_FWRITE], [/* Define to 1 if you have the `fwrite\' function. */
+@%:@undef HAVE_FWRITE])
+m4trace:configure.ac:2163: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:2163: the top level])
+m4trace:configure.ac:2163: -1- AH_OUTPUT([HAVE__FCLOSE], [/* Define to 1 if you have the `_fclose\' function. */
+@%:@undef HAVE__FCLOSE])
+m4trace:configure.ac:2163: -1- AH_OUTPUT([HAVE__FEOF], [/* Define to 1 if you have the `_feof\' function. */
+@%:@undef HAVE__FEOF])
+m4trace:configure.ac:2163: -1- AH_OUTPUT([HAVE__FERROR], [/* Define to 1 if you have the `_ferror\' function. */
+@%:@undef HAVE__FERROR])
+m4trace:configure.ac:2163: -1- AH_OUTPUT([HAVE__FFLUSH], [/* Define to 1 if you have the `_fflush\' function. */
+@%:@undef HAVE__FFLUSH])
+m4trace:configure.ac:2163: -1- AH_OUTPUT([HAVE__FOPEN], [/* Define to 1 if you have the `_fopen\' function. */
+@%:@undef HAVE__FOPEN])
+m4trace:configure.ac:2163: -1- AH_OUTPUT([HAVE__FREAD], [/* Define to 1 if you have the `_fread\' function. */
+@%:@undef HAVE__FREAD])
+m4trace:configure.ac:2163: -1- AH_OUTPUT([HAVE__FWRITE], [/* Define to 1 if you have the `_fwrite\' function. */
+@%:@undef HAVE__FWRITE])
+m4trace:configure.ac:2164: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:2164: the top level])
+m4trace:configure.ac:2164: -1- AH_OUTPUT([HAVE__GETENV_S], [/* Define to 1 if you have the `_getenv_s\' function. */
+@%:@undef HAVE__GETENV_S])
+m4trace:configure.ac:2164: -1- AH_OUTPUT([HAVE__WGETENV], [/* Define to 1 if you have the `_wgetenv\' function. */
+@%:@undef HAVE__WGETENV])
+m4trace:configure.ac:2164: -1- AH_OUTPUT([HAVE__GETPID], [/* Define to 1 if you have the `_getpid\' function. */
+@%:@undef HAVE__GETPID])
+m4trace:configure.ac:2165: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:2165: the top level])
+m4trace:configure.ac:2165: -1- AH_OUTPUT([HAVE_FETESTEXCEPT], [/* Define to 1 if you have the `fetestexcept\' function. */
+@%:@undef HAVE_FETESTEXCEPT])
+m4trace:configure.ac:2165: -1- AH_OUTPUT([HAVE__CLEARFP], [/* Define to 1 if you have the `_clearfp\' function. */
+@%:@undef HAVE__CLEARFP])
+m4trace:configure.ac:2166: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:2166: the top level])
+m4trace:configure.ac:2166: -1- AH_OUTPUT([HAVE_FORK], [/* Define to 1 if you have the `fork\' function. */
+@%:@undef HAVE_FORK])
+m4trace:configure.ac:2166: -1- AH_OUTPUT([HAVE_GETRLIMIT], [/* Define to 1 if you have the `getrlimit\' function. */
+@%:@undef HAVE_GETRLIMIT])
+m4trace:configure.ac:2166: -1- AH_OUTPUT([HAVE_SETPGRP], [/* Define to 1 if you have the `setpgrp\' function. */
+@%:@undef HAVE_SETPGRP])
+m4trace:configure.ac:2166: -1- AH_OUTPUT([HAVE_SETSID], [/* Define to 1 if you have the `setsid\' function. */
+@%:@undef HAVE_SETSID])
+m4trace:configure.ac:2166: -1- AH_OUTPUT([HAVE_SYSLOG], [/* Define to 1 if you have the `syslog\' function. */
+@%:@undef HAVE_SYSLOG])
+m4trace:configure.ac:2167: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:2167: the top level])
+m4trace:configure.ac:2167: -1- AH_OUTPUT([HAVE_GETHOSTNAME], [/* Define to 1 if you have the `gethostname\' function. */
+@%:@undef HAVE_GETHOSTNAME])
+m4trace:configure.ac:2167: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GETHOSTNAME])
+m4trace:configure.ac:2167: -1- m4_pattern_allow([^HAVE_GETHOSTNAME$])
+m4trace:configure.ac:2168: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:2168: the top level])
+m4trace:configure.ac:2168: -1- AH_OUTPUT([HAVE_TIME], [/* Define to 1 if you have the `time\' function. */
+@%:@undef HAVE_TIME])
+m4trace:configure.ac:2168: -1- AH_OUTPUT([HAVE_LOCALTIME], [/* Define to 1 if you have the `localtime\' function. */
+@%:@undef HAVE_LOCALTIME])
+m4trace:configure.ac:2168: -1- AH_OUTPUT([HAVE_LOCALTIME_S], [/* Define to 1 if you have the `localtime_s\' function. */
+@%:@undef HAVE_LOCALTIME_S])
+m4trace:configure.ac:2169: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:2169: the top level])
+m4trace:configure.ac:2169: -1- AH_OUTPUT([HAVE_STAT], [/* Define to 1 if you have the `stat\' function. */
+@%:@undef HAVE_STAT])
+m4trace:configure.ac:2169: -1- AH_OUTPUT([HAVE_STAT32], [/* Define to 1 if you have the `stat32\' function. */
+@%:@undef HAVE_STAT32])
+m4trace:configure.ac:2169: -1- AH_OUTPUT([HAVE_LSTAT32], [/* Define to 1 if you have the `lstat32\' function. */
+@%:@undef HAVE_LSTAT32])
+m4trace:configure.ac:2170: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:2170: the top level])
+m4trace:configure.ac:2170: -1- AH_OUTPUT([HAVE__STAT], [/* Define to 1 if you have the `_stat\' function. */
+@%:@undef HAVE__STAT])
+m4trace:configure.ac:2170: -1- AH_OUTPUT([HAVE__STAT32], [/* Define to 1 if you have the `_stat32\' function. */
+@%:@undef HAVE__STAT32])
+m4trace:configure.ac:2170: -1- AH_OUTPUT([HAVE__STAT64], [/* Define to 1 if you have the `_stat64\' function. */
+@%:@undef HAVE__STAT64])
+m4trace:configure.ac:2170: -1- AH_OUTPUT([HAVE__LSTAT], [/* Define to 1 if you have the `_lstat\' function. */
+@%:@undef HAVE__LSTAT])
+m4trace:configure.ac:2170: -1- AH_OUTPUT([HAVE__LSTAT32], [/* Define to 1 if you have the `_lstat32\' function. */
+@%:@undef HAVE__LSTAT32])
+m4trace:configure.ac:2170: -1- AH_OUTPUT([HAVE__LSTAT64], [/* Define to 1 if you have the `_lstat64\' function. */
+@%:@undef HAVE__LSTAT64])
+m4trace:configure.ac:2171: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:2171: the top level])
+m4trace:configure.ac:2171: -1- AH_OUTPUT([HAVE_MPCTL], [/* Define to 1 if you have the `mpctl\' function. */
+@%:@undef HAVE_MPCTL])
+m4trace:configure.ac:2171: -1- AH_OUTPUT([HAVE_SYSCONF], [/* Define to 1 if you have the `sysconf\' function. */
+@%:@undef HAVE_SYSCONF])
+m4trace:configure.ac:2171: -1- AH_OUTPUT([HAVE_SYSCTL], [/* Define to 1 if you have the `sysctl\' function. */
+@%:@undef HAVE_SYSCTL])
+m4trace:configure.ac:2172: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:2172: the top level])
+m4trace:configure.ac:2172: -1- AH_OUTPUT([HAVE_POPEN], [/* Define to 1 if you have the `popen\' function. */
+@%:@undef HAVE_POPEN])
+m4trace:configure.ac:2172: -1- AH_OUTPUT([HAVE__POPEN], [/* Define to 1 if you have the `_popen\' function. */
+@%:@undef HAVE__POPEN])
+m4trace:configure.ac:2173: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:2173: the top level])
+m4trace:configure.ac:2173: -1- AH_OUTPUT([HAVE_READ], [/* Define to 1 if you have the `read\' function. */
+@%:@undef HAVE_READ])
+m4trace:configure.ac:2173: -1- AH_OUTPUT([HAVE_WRITE], [/* Define to 1 if you have the `write\' function. */
+@%:@undef HAVE_WRITE])
+m4trace:configure.ac:2173: -1- AH_OUTPUT([HAVE__READ], [/* Define to 1 if you have the `_read\' function. */
+@%:@undef HAVE__READ])
+m4trace:configure.ac:2173: -1- AH_OUTPUT([HAVE__WRITE], [/* Define to 1 if you have the `_write\' function. */
+@%:@undef HAVE__WRITE])
+m4trace:configure.ac:2174: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:2174: the top level])
+m4trace:configure.ac:2174: -1- AH_OUTPUT([HAVE_SEED48], [/* Define to 1 if you have the `seed48\' function. */
+@%:@undef HAVE_SEED48])
+m4trace:configure.ac:2174: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SEED48])
+m4trace:configure.ac:2174: -1- m4_pattern_allow([^HAVE_SEED48$])
+m4trace:configure.ac:2175: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:2175: the top level])
+m4trace:configure.ac:2175: -1- AH_OUTPUT([HAVE_SPRINTF_S], [/* Define to 1 if you have the `sprintf_s\' function. */
+@%:@undef HAVE_SPRINTF_S])
+m4trace:configure.ac:2175: -1- AH_OUTPUT([HAVE_SSCANF_S], [/* Define to 1 if you have the `sscanf_s\' function. */
+@%:@undef HAVE_SSCANF_S])
+m4trace:configure.ac:2175: -1- AH_OUTPUT([HAVE_SWSCANF_S], [/* Define to 1 if you have the `swscanf_s\' function. */
+@%:@undef HAVE_SWSCANF_S])
+m4trace:configure.ac:2176: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:2176: the top level])
+m4trace:configure.ac:2176: -1- AH_OUTPUT([HAVE_STRCAT], [/* Define to 1 if you have the `strcat\' function. */
+@%:@undef HAVE_STRCAT])
+m4trace:configure.ac:2176: -1- AH_OUTPUT([HAVE_STRCHR], [/* Define to 1 if you have the `strchr\' function. */
+@%:@undef HAVE_STRCHR])
+m4trace:configure.ac:2176: -1- AH_OUTPUT([HAVE_STRCMP], [/* Define to 1 if you have the `strcmp\' function. */
+@%:@undef HAVE_STRCMP])
+m4trace:configure.ac:2176: -1- AH_OUTPUT([HAVE_STRCPY], [/* Define to 1 if you have the `strcpy\' function. */
+@%:@undef HAVE_STRCPY])
+m4trace:configure.ac:2176: -1- AH_OUTPUT([HAVE_STRDUP], [/* Define to 1 if you have the `strdup\' function. */
+@%:@undef HAVE_STRDUP])
+m4trace:configure.ac:2176: -1- AH_OUTPUT([HAVE_STRLEN], [/* Define to 1 if you have the `strlen\' function. */
+@%:@undef HAVE_STRLEN])
+m4trace:configure.ac:2176: -1- AH_OUTPUT([HAVE_STRNCMP], [/* Define to 1 if you have the `strncmp\' function. */
+@%:@undef HAVE_STRNCMP])
+m4trace:configure.ac:2176: -1- AH_OUTPUT([HAVE_STRNCPY], [/* Define to 1 if you have the `strncpy\' function. */
+@%:@undef HAVE_STRNCPY])
+m4trace:configure.ac:2176: -1- AH_OUTPUT([HAVE__STRDUP], [/* Define to 1 if you have the `_strdup\' function. */
+@%:@undef HAVE__STRDUP])
+m4trace:configure.ac:2177: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:2177: the top level])
+m4trace:configure.ac:2177: -1- AH_OUTPUT([HAVE_STRNCPY_S], [/* Define to 1 if you have the `strncpy_s\' function. */
+@%:@undef HAVE_STRNCPY_S])
+m4trace:configure.ac:2177: -1- AH_OUTPUT([HAVE_STRRCHR], [/* Define to 1 if you have the `strrchr\' function. */
+@%:@undef HAVE_STRRCHR])
+m4trace:configure.ac:2177: -1- AH_OUTPUT([HAVE_STRTOIMAX], [/* Define to 1 if you have the `strtoimax\' function. */
+@%:@undef HAVE_STRTOIMAX])
+m4trace:configure.ac:2177: -1- AH_OUTPUT([HAVE_STRTOL], [/* Define to 1 if you have the `strtol\' function. */
+@%:@undef HAVE_STRTOL])
+m4trace:configure.ac:2177: -1- AH_OUTPUT([HAVE_STRTOLL], [/* Define to 1 if you have the `strtoll\' function. */
+@%:@undef HAVE_STRTOLL])
+m4trace:configure.ac:2177: -1- AH_OUTPUT([HAVE_STRTOUL], [/* Define to 1 if you have the `strtoul\' function. */
+@%:@undef HAVE_STRTOUL])
+m4trace:configure.ac:2177: -1- AH_OUTPUT([HAVE_STRTOULL], [/* Define to 1 if you have the `strtoull\' function. */
+@%:@undef HAVE_STRTOULL])
+m4trace:configure.ac:2178: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:2178: the top level])
+m4trace:configure.ac:2178: -1- AH_OUTPUT([HAVE_STRTOUMAX], [/* Define to 1 if you have the `strtoumax\' function. */
+@%:@undef HAVE_STRTOUMAX])
+m4trace:configure.ac:2178: -1- AC_DEFINE_TRACE_LITERAL([HAVE_STRTOUMAX])
+m4trace:configure.ac:2178: -1- m4_pattern_allow([^HAVE_STRTOUMAX$])
+m4trace:configure.ac:2179: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:2179: the top level])
+m4trace:configure.ac:2179: -1- AH_OUTPUT([HAVE_WCSDUP], [/* Define to 1 if you have the `wcsdup\' function. */
+@%:@undef HAVE_WCSDUP])
+m4trace:configure.ac:2179: -1- AH_OUTPUT([HAVE_WCSNCMP], [/* Define to 1 if you have the `wcsncmp\' function. */
+@%:@undef HAVE_WCSNCMP])
+m4trace:configure.ac:2179: -1- AH_OUTPUT([HAVE_WCSNCPY], [/* Define to 1 if you have the `wcsncpy\' function. */
+@%:@undef HAVE_WCSNCPY])
+m4trace:configure.ac:2179: -1- AH_OUTPUT([HAVE_WCSNCPY_S], [/* Define to 1 if you have the `wcsncpy_s\' function. */
+@%:@undef HAVE_WCSNCPY_S])
+m4trace:configure.ac:2179: -1- AH_OUTPUT([HAVE_WCSTOIMAX], [/* Define to 1 if you have the `wcstoimax\' function. */
+@%:@undef HAVE_WCSTOIMAX])
+m4trace:configure.ac:2179: -1- AH_OUTPUT([HAVE_WCSTOL], [/* Define to 1 if you have the `wcstol\' function. */
+@%:@undef HAVE_WCSTOL])
+m4trace:configure.ac:2179: -1- AH_OUTPUT([HAVE_WCSTOLL], [/* Define to 1 if you have the `wcstoll\' function. */
+@%:@undef HAVE_WCSTOLL])
+m4trace:configure.ac:2180: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:2180: the top level])
+m4trace:configure.ac:2180: -1- AH_OUTPUT([HAVE_WCSTOUL], [/* Define to 1 if you have the `wcstoul\' function. */
+@%:@undef HAVE_WCSTOUL])
+m4trace:configure.ac:2180: -1- AH_OUTPUT([HAVE_WCSTOULL], [/* Define to 1 if you have the `wcstoull\' function. */
+@%:@undef HAVE_WCSTOULL])
+m4trace:configure.ac:2180: -1- AH_OUTPUT([HAVE_WCSTOUMAX], [/* Define to 1 if you have the `wcstoumax\' function. */
+@%:@undef HAVE_WCSTOUMAX])
+m4trace:configure.ac:2181: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:2181: the top level])
+m4trace:configure.ac:2181: -1- AH_OUTPUT([HAVE__WCSCAT], [/* Define to 1 if you have the `_wcscat\' function. */
+@%:@undef HAVE__WCSCAT])
+m4trace:configure.ac:2181: -1- AH_OUTPUT([HAVE__WCSCHR], [/* Define to 1 if you have the `_wcschr\' function. */
+@%:@undef HAVE__WCSCHR])
+m4trace:configure.ac:2181: -1- AH_OUTPUT([HAVE__WCSCPY], [/* Define to 1 if you have the `_wcscpy\' function. */
+@%:@undef HAVE__WCSCPY])
+m4trace:configure.ac:2181: -1- AH_OUTPUT([HAVE__WCSDUP], [/* Define to 1 if you have the `_wcsdup\' function. */
+@%:@undef HAVE__WCSDUP])
+m4trace:configure.ac:2181: -1- AH_OUTPUT([HAVE__WCSLEN], [/* Define to 1 if you have the `_wcslen\' function. */
+@%:@undef HAVE__WCSLEN])
+m4trace:configure.ac:2181: -1- AH_OUTPUT([HAVE__WCSNCMP], [/* Define to 1 if you have the `_wcsncmp\' function. */
+@%:@undef HAVE__WCSNCMP])
+m4trace:configure.ac:2181: -1- AH_OUTPUT([HAVE__WCSNCPY], [/* Define to 1 if you have the `_wcsncpy\' function. */
+@%:@undef HAVE__WCSNCPY])
+m4trace:configure.ac:2182: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:2182: the top level])
+m4trace:configure.ac:2182: -1- AH_OUTPUT([HAVE__WCSRCHR], [/* Define to 1 if you have the `_wcsrchr\' function. */
+@%:@undef HAVE__WCSRCHR])
+m4trace:configure.ac:2182: -1- AC_DEFINE_TRACE_LITERAL([HAVE__WCSRCHR])
+m4trace:configure.ac:2182: -1- m4_pattern_allow([^HAVE__WCSRCHR$])
+m4trace:configure.ac:2183: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:2183: the top level])
+m4trace:configure.ac:2183: -1- AH_OUTPUT([HAVE_TCFLUSH], [/* Define to 1 if you have the `tcflush\' function. */
+@%:@undef HAVE_TCFLUSH])
+m4trace:configure.ac:2183: -1- AH_OUTPUT([HAVE_TCGETATTR], [/* Define to 1 if you have the `tcgetattr\' function. */
+@%:@undef HAVE_TCGETATTR])
+m4trace:configure.ac:2184: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:2184: the top level])
+m4trace:configure.ac:2184: -1- AH_OUTPUT([HAVE_UMASK], [/* Define to 1 if you have the `umask\' function. */
+@%:@undef HAVE_UMASK])
+m4trace:configure.ac:2184: -1- AC_DEFINE_TRACE_LITERAL([HAVE_UMASK])
+m4trace:configure.ac:2184: -1- m4_pattern_allow([^HAVE_UMASK$])
+m4trace:configure.ac:2185: -1- _m4_warn([obsolete], [The macro `AC_HAVE_FUNCS' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/functions.m4:160: AC_HAVE_FUNCS is expanded from...
+configure.ac:2185: the top level])
+m4trace:configure.ac:2185: -1- AH_OUTPUT([HAVE_GETFINALPATHNAMEBYHANDLE], [/* Define to 1 if you have the `GetFinalPathNameByHandle\' function. */
+@%:@undef HAVE_GETFINALPATHNAMEBYHANDLE])
+m4trace:configure.ac:2185: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GETFINALPATHNAMEBYHANDLE])
+m4trace:configure.ac:2185: -1- m4_pattern_allow([^HAVE_GETFINALPATHNAMEBYHANDLE$])
+m4trace:configure.ac:2189: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:2189: the top level])
+m4trace:configure.ac:2189: -1- AC_DEFINE_TRACE_LITERAL([HAVE_WCHAR_T])
+m4trace:configure.ac:2189: -1- m4_pattern_allow([^HAVE_WCHAR_T$])
+m4trace:configure.ac:2198: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:2198: the top level])
+m4trace:configure.ac:2198: -1- AC_DEFINE_TRACE_LITERAL([HAVE_MKDIR2])
+m4trace:configure.ac:2198: -1- m4_pattern_allow([^HAVE_MKDIR2$])
+m4trace:configure.ac:2216: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:2216: the top level])
+m4trace:configure.ac:2216: -1- AC_DEFINE_TRACE_LITERAL([HAVE_DB_CURSOR_C_GET])
+m4trace:configure.ac:2216: -1- m4_pattern_allow([^HAVE_DB_CURSOR_C_GET$])
+m4trace:configure.ac:2227: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:2227: the top level])
+m4trace:configure.ac:2227: -1- AC_DEFINE_TRACE_LITERAL([HAVE_CONST])
+m4trace:configure.ac:2227: -1- m4_pattern_allow([^HAVE_CONST$])
+m4trace:configure.ac:2236: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:2236: the top level])
+m4trace:configure.ac:2256: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INLINE])
+m4trace:configure.ac:2256: -1- m4_pattern_allow([^HAVE_INLINE$])
+m4trace:configure.ac:2262: -1- AC_DEFINE_TRACE_LITERAL([HAVE_DEV_URANDOM])
+m4trace:configure.ac:2262: -1- m4_pattern_allow([^HAVE_DEV_URANDOM$])
+m4trace:configure.ac:2266: -1- AC_DEFINE_TRACE_LITERAL([HAVE_DEV_URANDOM])
+m4trace:configure.ac:2266: -1- m4_pattern_allow([^HAVE_DEV_URANDOM$])
+m4trace:configure.ac:2270: -1- AC_DEFINE_TRACE_LITERAL([HAVE_DEV_RANDOM])
+m4trace:configure.ac:2270: -1- m4_pattern_allow([^HAVE_DEV_RANDOM$])
+m4trace:configure.ac:2274: -1- AC_DEFINE_TRACE_LITERAL([HAVE_DEV_RANDOM])
+m4trace:configure.ac:2274: -1- m4_pattern_allow([^HAVE_DEV_RANDOM$])
+m4trace:configure.ac:2279: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:2279: the top level])
+m4trace:configure.ac:2279: -1- AC_DEFINE_TRACE_LITERAL([HAVE_FPCLASSIFY])
+m4trace:configure.ac:2279: -1- m4_pattern_allow([^HAVE_FPCLASSIFY$])
+m4trace:configure.ac:2290: -1- AH_OUTPUT([HAVE_GETPEERNAME], [/* Define to 1 if you have the `getpeername\' function. */
+@%:@undef HAVE_GETPEERNAME])
+m4trace:configure.ac:2290: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GETPEERNAME])
+m4trace:configure.ac:2290: -1- m4_pattern_allow([^HAVE_GETPEERNAME$])
+m4trace:configure.ac:2290: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GETPEERNAME])
+m4trace:configure.ac:2290: -1- m4_pattern_allow([^HAVE_GETPEERNAME$])
+m4trace:configure.ac:2290: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GETPEERNAME])
+m4trace:configure.ac:2290: -1- m4_pattern_allow([^HAVE_GETPEERNAME$])
+m4trace:configure.ac:2290: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GETPEERNAME])
+m4trace:configure.ac:2290: -1- m4_pattern_allow([^HAVE_GETPEERNAME$])
+m4trace:configure.ac:2290: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GETPEERNAME])
+m4trace:configure.ac:2290: -1- m4_pattern_allow([^HAVE_GETPEERNAME$])
+m4trace:configure.ac:2307: -1- AH_OUTPUT([HAVE_GETSOCKNAME], [/* Define to 1 if you have the `getsockname\' function. */
+@%:@undef HAVE_GETSOCKNAME])
+m4trace:configure.ac:2307: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GETSOCKNAME])
+m4trace:configure.ac:2307: -1- m4_pattern_allow([^HAVE_GETSOCKNAME$])
+m4trace:configure.ac:2307: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GETSOCKNAME])
+m4trace:configure.ac:2307: -1- m4_pattern_allow([^HAVE_GETSOCKNAME$])
+m4trace:configure.ac:2307: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GETSOCKNAME])
+m4trace:configure.ac:2307: -1- m4_pattern_allow([^HAVE_GETSOCKNAME$])
+m4trace:configure.ac:2307: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GETSOCKNAME])
+m4trace:configure.ac:2307: -1- m4_pattern_allow([^HAVE_GETSOCKNAME$])
+m4trace:configure.ac:2307: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GETSOCKNAME])
+m4trace:configure.ac:2307: -1- m4_pattern_allow([^HAVE_GETSOCKNAME$])
+m4trace:configure.ac:2327: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:2327: the top level])
+m4trace:configure.ac:2327: -1- AC_DEFINE_TRACE_LITERAL([HAVE_LIBNETSNMP])
+m4trace:configure.ac:2327: -1- m4_pattern_allow([^HAVE_LIBNETSNMP$])
+m4trace:configure.ac:2338: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SNMP_ENABLE_FILELOG])
+m4trace:configure.ac:2338: -1- m4_pattern_allow([^HAVE_SNMP_ENABLE_FILELOG$])
+m4trace:configure.ac:2339: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SNMP_DISABLE_SYSLOG])
+m4trace:configure.ac:2339: -1- m4_pattern_allow([^HAVE_SNMP_DISABLE_SYSLOG$])
+m4trace:configure.ac:2340: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SNMP_DISABLE_STDERRLOG])
+m4trace:configure.ac:2340: -1- m4_pattern_allow([^HAVE_SNMP_DISABLE_STDERRLOG$])
+m4trace:configure.ac:2341: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SNMP_DISABLE_FILELOG])
+m4trace:configure.ac:2341: -1- m4_pattern_allow([^HAVE_SNMP_DISABLE_FILELOG$])
+m4trace:configure.ac:2346: -1- _m4_warn([obsolete], [The macro `AC_TRY_RUN' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2764: AC_TRY_RUN is expanded from...
+configure.ac:2346: the top level])
+m4trace:configure.ac:2478: -1- AC_DEFINE_TRACE_LITERAL([HAVE_IEEE_754_DOUBLE])
+m4trace:configure.ac:2478: -1- m4_pattern_allow([^HAVE_IEEE_754_DOUBLE$])
+m4trace:configure.ac:2485: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:2485: the top level])
+m4trace:configure.ac:2485: -1- AC_DEFINE_TRACE_LITERAL([HAVE_ISFINITE])
+m4trace:configure.ac:2485: -1- m4_pattern_allow([^HAVE_ISFINITE$])
+m4trace:configure.ac:2499: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
+configure.ac:2499: the top level])
+m4trace:configure.ac:2499: -1- AC_DEFINE_TRACE_LITERAL([HAVE_ISNORMAL])
+m4trace:configure.ac:2499: -1- m4_pattern_allow([^HAVE_ISNORMAL$])
+m4trace:configure.ac:2516: -1- _m4_warn([obsolete], [The macro `AC_TRY_RUN' is obsolete.
+You should run autoupdate.], [../../lib/autoconf/general.m4:2764: AC_TRY_RUN is expanded from...
+configure.ac:2516: the top level])
+m4trace:configure.ac:2516: -1- AC_DEFINE_TRACE_LITERAL([HAVE_TWOS_COMPLEMENT])
+m4trace:configure.ac:2516: -1- m4_pattern_allow([^HAVE_TWOS_COMPLEMENT$])
+m4trace:configure.ac:2956: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INODES])
+m4trace:configure.ac:2956: -1- m4_pattern_allow([^HAVE_INODES$])
+m4trace:configure.ac:2987: -1- AC_SUBST([ANYDB])
+m4trace:configure.ac:2987: -1- AC_SUBST_TRACE([ANYDB])
+m4trace:configure.ac:2987: -1- m4_pattern_allow([^ANYDB$])
+m4trace:configure.ac:2988: -1- AC_SUBST([CLI_SNMPPROG])
+m4trace:configure.ac:2988: -1- AC_SUBST_TRACE([CLI_SNMPPROG])
+m4trace:configure.ac:2988: -1- m4_pattern_allow([^CLI_SNMPPROG$])
+m4trace:configure.ac:2989: -1- AC_SUBST([LIBPNG])
+m4trace:configure.ac:2989: -1- AC_SUBST_TRACE([LIBPNG])
+m4trace:configure.ac:2989: -1- m4_pattern_allow([^LIBPNG$])
+m4trace:configure.ac:2990: -1- AC_SUBST([LIBJPEG])
+m4trace:configure.ac:2990: -1- AC_SUBST_TRACE([LIBJPEG])
+m4trace:configure.ac:2990: -1- m4_pattern_allow([^LIBJPEG$])
+m4trace:configure.ac:2991: -1- AC_SUBST([LIBTIFF])
+m4trace:configure.ac:2991: -1- AC_SUBST_TRACE([LIBTIFF])
+m4trace:configure.ac:2991: -1- m4_pattern_allow([^LIBTIFF$])
+m4trace:configure.ac:2992: -1- AC_SUBST([DBLIB])
+m4trace:configure.ac:2992: -1- AC_SUBST_TRACE([DBLIB])
+m4trace:configure.ac:2992: -1- m4_pattern_allow([^DBLIB$])
+m4trace:configure.ac:2993: -1- AC_SUBST([DBLIBSOCK])
+m4trace:configure.ac:2993: -1- AC_SUBST_TRACE([DBLIBSOCK])
+m4trace:configure.ac:2993: -1- m4_pattern_allow([^DBLIBSOCK$])
+m4trace:configure.ac:2994: -1- AC_SUBST([CLI_MYSQLPROG])
+m4trace:configure.ac:2994: -1- AC_SUBST_TRACE([CLI_MYSQLPROG])
+m4trace:configure.ac:2994: -1- m4_pattern_allow([^CLI_MYSQLPROG$])
+m4trace:configure.ac:2995: -1- AC_SUBST([PTHREADLIB])
+m4trace:configure.ac:2995: -1- AC_SUBST_TRACE([PTHREADLIB])
+m4trace:configure.ac:2995: -1- m4_pattern_allow([^PTHREADLIB$])
+m4trace:configure.ac:2996: -1- AC_SUBST([LIBDK3WXOBJ])
+m4trace:configure.ac:2996: -1- AC_SUBST_TRACE([LIBDK3WXOBJ])
+m4trace:configure.ac:2996: -1- m4_pattern_allow([^LIBDK3WXOBJ$])
+m4trace:configure.ac:2997: -1- AC_SUBST([LIBDK4WXOBJ])
+m4trace:configure.ac:2997: -1- AC_SUBST_TRACE([LIBDK4WXOBJ])
+m4trace:configure.ac:2997: -1- m4_pattern_allow([^LIBDK4WXOBJ$])
+m4trace:configure.ac:2998: -1- AC_SUBST([LIBDK4WXTOBUILD])
+m4trace:configure.ac:2998: -1- AC_SUBST_TRACE([LIBDK4WXTOBUILD])
+m4trace:configure.ac:2998: -1- m4_pattern_allow([^LIBDK4WXTOBUILD$])
+m4trace:configure.ac:2999: -1- AC_SUBST([DKCTLIBF])
+m4trace:configure.ac:2999: -1- AC_SUBST_TRACE([DKCTLIBF])
+m4trace:configure.ac:2999: -1- m4_pattern_allow([^DKCTLIBF$])
+m4trace:configure.ac:3000: -1- AC_SUBST([DKCTLIBS])
+m4trace:configure.ac:3000: -1- AC_SUBST_TRACE([DKCTLIBS])
+m4trace:configure.ac:3000: -1- m4_pattern_allow([^DKCTLIBS$])
+m4trace:configure.ac:3001: -1- AC_SUBST([ADDCTRLDLIBF])
+m4trace:configure.ac:3001: -1- AC_SUBST_TRACE([ADDCTRLDLIBF])
+m4trace:configure.ac:3001: -1- m4_pattern_allow([^ADDCTRLDLIBF$])
+m4trace:configure.ac:3002: -1- AC_SUBST([ADDCTRLDLIBS])
+m4trace:configure.ac:3002: -1- AC_SUBST_TRACE([ADDCTRLDLIBS])
+m4trace:configure.ac:3002: -1- m4_pattern_allow([^ADDCTRLDLIBS$])
+m4trace:configure.ac:3003: -1- AC_SUBST([DKDBTLIBF])
+m4trace:configure.ac:3003: -1- AC_SUBST_TRACE([DKDBTLIBF])
+m4trace:configure.ac:3003: -1- m4_pattern_allow([^DKDBTLIBF$])
+m4trace:configure.ac:3004: -1- AC_SUBST([DKDBTLIBS])
+m4trace:configure.ac:3004: -1- AC_SUBST_TRACE([DKDBTLIBS])
+m4trace:configure.ac:3004: -1- m4_pattern_allow([^DKDBTLIBS$])
+m4trace:configure.ac:3005: -1- AC_SUBST([BMPPLIBF])
+m4trace:configure.ac:3005: -1- AC_SUBST_TRACE([BMPPLIBF])
+m4trace:configure.ac:3005: -1- m4_pattern_allow([^BMPPLIBF$])
+m4trace:configure.ac:3006: -1- AC_SUBST([BMPPLIBS])
+m4trace:configure.ac:3006: -1- AC_SUBST_TRACE([BMPPLIBS])
+m4trace:configure.ac:3006: -1- m4_pattern_allow([^BMPPLIBS$])
+m4trace:configure.ac:3007: -1- AC_SUBST([FIG2LATLIBF])
+m4trace:configure.ac:3007: -1- AC_SUBST_TRACE([FIG2LATLIBF])
+m4trace:configure.ac:3007: -1- m4_pattern_allow([^FIG2LATLIBF$])
+m4trace:configure.ac:3008: -1- AC_SUBST([FIG2LATLIBS])
+m4trace:configure.ac:3008: -1- AC_SUBST_TRACE([FIG2LATLIBS])
+m4trace:configure.ac:3008: -1- m4_pattern_allow([^FIG2LATLIBS$])
+m4trace:configure.ac:3009: -1- AC_SUBST([HTMLBOOKLIBF])
+m4trace:configure.ac:3009: -1- AC_SUBST_TRACE([HTMLBOOKLIBF])
+m4trace:configure.ac:3009: -1- m4_pattern_allow([^HTMLBOOKLIBF$])
+m4trace:configure.ac:3010: -1- AC_SUBST([HTMLBOOKLIBS])
+m4trace:configure.ac:3010: -1- AC_SUBST_TRACE([HTMLBOOKLIBS])
+m4trace:configure.ac:3010: -1- m4_pattern_allow([^HTMLBOOKLIBS$])
+m4trace:configure.ac:3011: -1- AC_SUBST([DK3INFOLIBF])
+m4trace:configure.ac:3011: -1- AC_SUBST_TRACE([DK3INFOLIBF])
+m4trace:configure.ac:3011: -1- m4_pattern_allow([^DK3INFOLIBF$])
+m4trace:configure.ac:3012: -1- AC_SUBST([DK3INFOLIBS])
+m4trace:configure.ac:3012: -1- AC_SUBST_TRACE([DK3INFOLIBS])
+m4trace:configure.ac:3012: -1- m4_pattern_allow([^DK3INFOLIBS$])
+m4trace:configure.ac:3013: -1- AC_SUBST([PLPDFTEXLIBF])
+m4trace:configure.ac:3013: -1- AC_SUBST_TRACE([PLPDFTEXLIBF])
+m4trace:configure.ac:3013: -1- m4_pattern_allow([^PLPDFTEXLIBF$])
+m4trace:configure.ac:3014: -1- AC_SUBST([PLPDFTEXLIBS])
+m4trace:configure.ac:3014: -1- AC_SUBST_TRACE([PLPDFTEXLIBS])
+m4trace:configure.ac:3014: -1- m4_pattern_allow([^PLPDFTEXLIBS$])
+m4trace:configure.ac:3015: -1- AC_SUBST([DKWXWIZLIBF])
+m4trace:configure.ac:3015: -1- AC_SUBST_TRACE([DKWXWIZLIBF])
+m4trace:configure.ac:3015: -1- m4_pattern_allow([^DKWXWIZLIBF$])
+m4trace:configure.ac:3016: -1- AC_SUBST([DKWXWIZLIBS])
+m4trace:configure.ac:3016: -1- AC_SUBST_TRACE([DKWXWIZLIBS])
+m4trace:configure.ac:3016: -1- m4_pattern_allow([^DKWXWIZLIBS$])
+m4trace:configure.ac:3017: -1- AC_SUBST([WXDKCTLIBF])
+m4trace:configure.ac:3017: -1- AC_SUBST_TRACE([WXDKCTLIBF])
+m4trace:configure.ac:3017: -1- m4_pattern_allow([^WXDKCTLIBF$])
+m4trace:configure.ac:3018: -1- AC_SUBST([WXDKCTLIBS])
+m4trace:configure.ac:3018: -1- AC_SUBST_TRACE([WXDKCTLIBS])
+m4trace:configure.ac:3018: -1- m4_pattern_allow([^WXDKCTLIBS$])
+m4trace:configure.ac:3019: -1- AC_SUBST([WXBMPPLIBF])
+m4trace:configure.ac:3019: -1- AC_SUBST_TRACE([WXBMPPLIBF])
+m4trace:configure.ac:3019: -1- m4_pattern_allow([^WXBMPPLIBF$])
+m4trace:configure.ac:3020: -1- AC_SUBST([WXBMPPLIBS])
+m4trace:configure.ac:3020: -1- AC_SUBST_TRACE([WXBMPPLIBS])
+m4trace:configure.ac:3020: -1- m4_pattern_allow([^WXBMPPLIBS$])
+m4trace:configure.ac:3021: -1- AC_SUBST([WXPQDICLIBF])
+m4trace:configure.ac:3021: -1- AC_SUBST_TRACE([WXPQDICLIBF])
+m4trace:configure.ac:3021: -1- m4_pattern_allow([^WXPQDICLIBF$])
+m4trace:configure.ac:3022: -1- AC_SUBST([WXPQDICLIBS])
+m4trace:configure.ac:3022: -1- AC_SUBST_TRACE([WXPQDICLIBS])
+m4trace:configure.ac:3022: -1- m4_pattern_allow([^WXPQDICLIBS$])
+m4trace:configure.ac:3023: -1- AC_SUBST([WXIMGSZLIBF])
+m4trace:configure.ac:3023: -1- AC_SUBST_TRACE([WXIMGSZLIBF])
+m4trace:configure.ac:3023: -1- m4_pattern_allow([^WXIMGSZLIBF$])
+m4trace:configure.ac:3024: -1- AC_SUBST([WXIMGSZLIBS])
+m4trace:configure.ac:3024: -1- AC_SUBST_TRACE([WXIMGSZLIBS])
+m4trace:configure.ac:3024: -1- m4_pattern_allow([^WXIMGSZLIBS$])
+m4trace:configure.ac:3025: -1- AC_SUBST([WXDKCLOCKLIBF])
+m4trace:configure.ac:3025: -1- AC_SUBST_TRACE([WXDKCLOCKLIBF])
+m4trace:configure.ac:3025: -1- m4_pattern_allow([^WXDKCLOCKLIBF$])
+m4trace:configure.ac:3026: -1- AC_SUBST([WXDKCLOCKLIBS])
+m4trace:configure.ac:3026: -1- AC_SUBST_TRACE([WXDKCLOCKLIBS])
+m4trace:configure.ac:3026: -1- m4_pattern_allow([^WXDKCLOCKLIBS$])
+m4trace:configure.ac:3027: -1- AC_SUBST([WXDKHTBLIBF])
+m4trace:configure.ac:3027: -1- AC_SUBST_TRACE([WXDKHTBLIBF])
+m4trace:configure.ac:3027: -1- m4_pattern_allow([^WXDKHTBLIBF$])
+m4trace:configure.ac:3028: -1- AC_SUBST([WXDKHTBLIBS])
+m4trace:configure.ac:3028: -1- AC_SUBST_TRACE([WXDKHTBLIBS])
+m4trace:configure.ac:3028: -1- m4_pattern_allow([^WXDKHTBLIBS$])
+m4trace:configure.ac:3029: -1- AC_SUBST([PRINTQDLIBF])
+m4trace:configure.ac:3029: -1- AC_SUBST_TRACE([PRINTQDLIBF])
+m4trace:configure.ac:3029: -1- m4_pattern_allow([^PRINTQDLIBF$])
+m4trace:configure.ac:3030: -1- AC_SUBST([PRINTQDLIBS])
+m4trace:configure.ac:3030: -1- AC_SUBST_TRACE([PRINTQDLIBS])
+m4trace:configure.ac:3030: -1- m4_pattern_allow([^PRINTQDLIBS$])
+m4trace:configure.ac:3031: -1- AC_SUBST([PRINTQDILIBF])
+m4trace:configure.ac:3031: -1- AC_SUBST_TRACE([PRINTQDILIBF])
+m4trace:configure.ac:3031: -1- m4_pattern_allow([^PRINTQDILIBF$])
+m4trace:configure.ac:3032: -1- AC_SUBST([PRINTQDILIBS])
+m4trace:configure.ac:3032: -1- AC_SUBST_TRACE([PRINTQDILIBS])
+m4trace:configure.ac:3032: -1- m4_pattern_allow([^PRINTQDILIBS$])
+m4trace:configure.ac:3033: -1- AC_SUBST([PRINTQDALIBF])
+m4trace:configure.ac:3033: -1- AC_SUBST_TRACE([PRINTQDALIBF])
+m4trace:configure.ac:3033: -1- m4_pattern_allow([^PRINTQDALIBF$])
+m4trace:configure.ac:3034: -1- AC_SUBST([PRINTQDALIBS])
+m4trace:configure.ac:3034: -1- AC_SUBST_TRACE([PRINTQDALIBS])
+m4trace:configure.ac:3034: -1- m4_pattern_allow([^PRINTQDALIBS$])
+m4trace:configure.ac:3035: -1- AC_SUBST([PJSNMPLIBF])
+m4trace:configure.ac:3035: -1- AC_SUBST_TRACE([PJSNMPLIBF])
+m4trace:configure.ac:3035: -1- m4_pattern_allow([^PJSNMPLIBF$])
+m4trace:configure.ac:3036: -1- AC_SUBST([PJSNMPLIBS])
+m4trace:configure.ac:3036: -1- AC_SUBST_TRACE([PJSNMPLIBS])
+m4trace:configure.ac:3036: -1- m4_pattern_allow([^PJSNMPLIBS$])
+m4trace:configure.ac:3037: -1- AC_SUBST([PRMONSNMPLIBF])
+m4trace:configure.ac:3037: -1- AC_SUBST_TRACE([PRMONSNMPLIBF])
+m4trace:configure.ac:3037: -1- m4_pattern_allow([^PRMONSNMPLIBF$])
+m4trace:configure.ac:3038: -1- AC_SUBST([PRMONSNMPLIBS])
+m4trace:configure.ac:3038: -1- AC_SUBST_TRACE([PRMONSNMPLIBS])
+m4trace:configure.ac:3038: -1- m4_pattern_allow([^PRMONSNMPLIBS$])
+m4trace:configure.ac:3039: -1- AC_SUBST([PRINTQDCLIBF])
+m4trace:configure.ac:3039: -1- AC_SUBST_TRACE([PRINTQDCLIBF])
+m4trace:configure.ac:3039: -1- m4_pattern_allow([^PRINTQDCLIBF$])
+m4trace:configure.ac:3040: -1- AC_SUBST([PRINTQDCLIBS])
+m4trace:configure.ac:3040: -1- AC_SUBST_TRACE([PRINTQDCLIBS])
+m4trace:configure.ac:3040: -1- m4_pattern_allow([^PRINTQDCLIBS$])
+m4trace:configure.ac:3041: -1- AC_SUBST([RSHDOWNLIBF])
+m4trace:configure.ac:3041: -1- AC_SUBST_TRACE([RSHDOWNLIBF])
+m4trace:configure.ac:3041: -1- m4_pattern_allow([^RSHDOWNLIBF$])
+m4trace:configure.ac:3042: -1- AC_SUBST([RSHDOWNLIBS])
+m4trace:configure.ac:3042: -1- AC_SUBST_TRACE([RSHDOWNLIBS])
+m4trace:configure.ac:3042: -1- m4_pattern_allow([^RSHDOWNLIBS$])
+m4trace:configure.ac:3043: -1- AC_SUBST([LPRNGCLLIBF])
+m4trace:configure.ac:3043: -1- AC_SUBST_TRACE([LPRNGCLLIBF])
+m4trace:configure.ac:3043: -1- m4_pattern_allow([^LPRNGCLLIBF$])
+m4trace:configure.ac:3044: -1- AC_SUBST([LPRNGCLLIBS])
+m4trace:configure.ac:3044: -1- AC_SUBST_TRACE([LPRNGCLLIBS])
+m4trace:configure.ac:3044: -1- m4_pattern_allow([^LPRNGCLLIBS$])
+m4trace:configure.ac:3045: -1- AC_SUBST([ITADMINLIBF])
+m4trace:configure.ac:3045: -1- AC_SUBST_TRACE([ITADMINLIBF])
+m4trace:configure.ac:3045: -1- m4_pattern_allow([^ITADMINLIBF$])
+m4trace:configure.ac:3046: -1- AC_SUBST([ITADMINLIBS])
+m4trace:configure.ac:3046: -1- AC_SUBST_TRACE([ITADMINLIBS])
+m4trace:configure.ac:3046: -1- m4_pattern_allow([^ITADMINLIBS$])
+m4trace:configure.ac:3051: -1- AC_SUBST([CC])
+m4trace:configure.ac:3051: -1- AC_SUBST_TRACE([CC])
+m4trace:configure.ac:3051: -1- m4_pattern_allow([^CC$])
+m4trace:configure.ac:3052: -1- AC_SUBST([CPP])
+m4trace:configure.ac:3052: -1- AC_SUBST_TRACE([CPP])
+m4trace:configure.ac:3052: -1- m4_pattern_allow([^CPP$])
+m4trace:configure.ac:3053: -1- AC_SUBST([CXX])
+m4trace:configure.ac:3053: -1- AC_SUBST_TRACE([CXX])
+m4trace:configure.ac:3053: -1- m4_pattern_allow([^CXX$])
+m4trace:configure.ac:3054: -1- AC_SUBST([DEFS])
+m4trace:configure.ac:3054: -1- AC_SUBST_TRACE([DEFS])
+m4trace:configure.ac:3054: -1- m4_pattern_allow([^DEFS$])
+m4trace:configure.ac:3055: -1- AC_SUBST([CPPFLAGS])
+m4trace:configure.ac:3055: -1- AC_SUBST_TRACE([CPPFLAGS])
+m4trace:configure.ac:3055: -1- m4_pattern_allow([^CPPFLAGS$])
+m4trace:configure.ac:3056: -1- AC_SUBST([CXXFLAGS])
+m4trace:configure.ac:3056: -1- AC_SUBST_TRACE([CXXFLAGS])
+m4trace:configure.ac:3056: -1- m4_pattern_allow([^CXXFLAGS$])
+m4trace:configure.ac:3057: -1- AC_SUBST([CFLAGS])
+m4trace:configure.ac:3057: -1- AC_SUBST_TRACE([CFLAGS])
+m4trace:configure.ac:3057: -1- m4_pattern_allow([^CFLAGS$])
+m4trace:configure.ac:3058: -1- AC_SUBST([LDFLAGS])
+m4trace:configure.ac:3058: -1- AC_SUBST_TRACE([LDFLAGS])
+m4trace:configure.ac:3058: -1- m4_pattern_allow([^LDFLAGS$])
+m4trace:configure.ac:3059: -1- AC_SUBST([LIBS])
+m4trace:configure.ac:3059: -1- AC_SUBST_TRACE([LIBS])
+m4trace:configure.ac:3059: -1- m4_pattern_allow([^LIBS$])
+m4trace:configure.ac:3060: -1- AC_SUBST([FS64])
+m4trace:configure.ac:3060: -1- AC_SUBST_TRACE([FS64])
+m4trace:configure.ac:3060: -1- m4_pattern_allow([^FS64$])
+m4trace:configure.ac:3061: -1- AC_SUBST([ZLIB])
+m4trace:configure.ac:3061: -1- AC_SUBST_TRACE([ZLIB])
+m4trace:configure.ac:3061: -1- m4_pattern_allow([^ZLIB$])
+m4trace:configure.ac:3062: -1- AC_SUBST([BZLIB])
+m4trace:configure.ac:3062: -1- AC_SUBST_TRACE([BZLIB])
+m4trace:configure.ac:3062: -1- m4_pattern_allow([^BZLIB$])
+m4trace:configure.ac:3063: -1- AC_SUBST([RANLIB])
+m4trace:configure.ac:3063: -1- AC_SUBST_TRACE([RANLIB])
+m4trace:configure.ac:3063: -1- m4_pattern_allow([^RANLIB$])
+m4trace:configure.ac:3064: -1- AC_SUBST([CFPIC])
+m4trace:configure.ac:3064: -1- AC_SUBST_TRACE([CFPIC])
+m4trace:configure.ac:3064: -1- m4_pattern_allow([^CFPIC$])
+m4trace:configure.ac:3065: -1- AC_SUBST([PROGRAMS])
+m4trace:configure.ac:3065: -1- AC_SUBST_TRACE([PROGRAMS])
+m4trace:configure.ac:3065: -1- m4_pattern_allow([^PROGRAMS$])
+m4trace:configure.ac:3066: -1- AC_SUBST([LIBRARIES])
+m4trace:configure.ac:3066: -1- AC_SUBST_TRACE([LIBRARIES])
+m4trace:configure.ac:3066: -1- m4_pattern_allow([^LIBRARIES$])
+m4trace:configure.ac:3067: -1- AC_SUBST([LIBS_STATIC])
+m4trace:configure.ac:3067: -1- AC_SUBST_TRACE([LIBS_STATIC])
+m4trace:configure.ac:3067: -1- m4_pattern_allow([^LIBS_STATIC$])
+m4trace:configure.ac:3068: -1- AC_SUBST([LIBS_SHARED])
+m4trace:configure.ac:3068: -1- AC_SUBST_TRACE([LIBS_SHARED])
+m4trace:configure.ac:3068: -1- m4_pattern_allow([^LIBS_SHARED$])
+m4trace:configure.ac:3069: -1- AC_SUBST([LIBS_INSTALL])
+m4trace:configure.ac:3069: -1- AC_SUBST_TRACE([LIBS_INSTALL])
+m4trace:configure.ac:3069: -1- m4_pattern_allow([^LIBS_INSTALL$])
+m4trace:configure.ac:3070: -1- AC_SUBST([RES_INSTALL])
+m4trace:configure.ac:3070: -1- AC_SUBST_TRACE([RES_INSTALL])
+m4trace:configure.ac:3070: -1- m4_pattern_allow([^RES_INSTALL$])
+m4trace:configure.ac:3071: -1- AC_SUBST([MKSOLIB])
+m4trace:configure.ac:3071: -1- AC_SUBST_TRACE([MKSOLIB])
+m4trace:configure.ac:3071: -1- m4_pattern_allow([^MKSOLIB$])
+m4trace:configure.ac:3072: -1- AC_SUBST([RPATH])
+m4trace:configure.ac:3072: -1- AC_SUBST_TRACE([RPATH])
+m4trace:configure.ac:3072: -1- m4_pattern_allow([^RPATH$])
+m4trace:configure.ac:3073: -1- AC_SUBST([RPATHLINK])
+m4trace:configure.ac:3073: -1- AC_SUBST_TRACE([RPATHLINK])
+m4trace:configure.ac:3073: -1- m4_pattern_allow([^RPATHLINK$])
+m4trace:configure.ac:3074: -1- AC_SUBST([UNAME])
+m4trace:configure.ac:3074: -1- AC_SUBST_TRACE([UNAME])
+m4trace:configure.ac:3074: -1- m4_pattern_allow([^UNAME$])
+m4trace:configure.ac:3075: -1- AC_SUBST([SHLIBSTYLE])
+m4trace:configure.ac:3075: -1- AC_SUBST_TRACE([SHLIBSTYLE])
+m4trace:configure.ac:3075: -1- m4_pattern_allow([^SHLIBSTYLE$])
+m4trace:configure.ac:3076: -1- AC_SUBST([VERSNO])
+m4trace:configure.ac:3076: -1- AC_SUBST_TRACE([VERSNO])
+m4trace:configure.ac:3076: -1- m4_pattern_allow([^VERSNO$])
+m4trace:configure.ac:3077: -1- AC_SUBST([SOVERS])
+m4trace:configure.ac:3077: -1- AC_SUBST_TRACE([SOVERS])
+m4trace:configure.ac:3077: -1- m4_pattern_allow([^SOVERS$])
+m4trace:configure.ac:3078: -1- AC_SUBST([CWARN])
+m4trace:configure.ac:3078: -1- AC_SUBST_TRACE([CWARN])
+m4trace:configure.ac:3078: -1- m4_pattern_allow([^CWARN$])
+m4trace:configure.ac:3079: -1- AC_SUBST([CRYPTO])
+m4trace:configure.ac:3079: -1- AC_SUBST_TRACE([CRYPTO])
+m4trace:configure.ac:3079: -1- m4_pattern_allow([^CRYPTO$])
+m4trace:configure.ac:3080: -1- AC_SUBST([DKCATLIBF])
+m4trace:configure.ac:3080: -1- AC_SUBST_TRACE([DKCATLIBF])
+m4trace:configure.ac:3080: -1- m4_pattern_allow([^DKCATLIBF$])
+m4trace:configure.ac:3081: -1- AC_SUBST([DKCATLIBS])
+m4trace:configure.ac:3081: -1- AC_SUBST_TRACE([DKCATLIBS])
+m4trace:configure.ac:3081: -1- m4_pattern_allow([^DKCATLIBS$])
+m4trace:configure.ac:3082: -1- AC_SUBST([DKBLKSLIBF])
+m4trace:configure.ac:3082: -1- AC_SUBST_TRACE([DKBLKSLIBF])
+m4trace:configure.ac:3082: -1- m4_pattern_allow([^DKBLKSLIBF$])
+m4trace:configure.ac:3083: -1- AC_SUBST([DKBLKSLIBS])
+m4trace:configure.ac:3083: -1- AC_SUBST_TRACE([DKBLKSLIBS])
+m4trace:configure.ac:3083: -1- m4_pattern_allow([^DKBLKSLIBS$])
+m4trace:configure.ac:3084: -1- AC_SUBST([DKSQLSPLITLIBF])
+m4trace:configure.ac:3084: -1- AC_SUBST_TRACE([DKSQLSPLITLIBF])
+m4trace:configure.ac:3084: -1- m4_pattern_allow([^DKSQLSPLITLIBF$])
+m4trace:configure.ac:3085: -1- AC_SUBST([DKSQLSPLITLIBS])
+m4trace:configure.ac:3085: -1- AC_SUBST_TRACE([DKSQLSPLITLIBS])
+m4trace:configure.ac:3085: -1- m4_pattern_allow([^DKSQLSPLITLIBS$])
+m4trace:configure.ac:3086: -1- AC_SUBST([DKERADISKLIBF])
+m4trace:configure.ac:3086: -1- AC_SUBST_TRACE([DKERADISKLIBF])
+m4trace:configure.ac:3086: -1- m4_pattern_allow([^DKERADISKLIBF$])
+m4trace:configure.ac:3087: -1- AC_SUBST([DKERADISKLIBS])
+m4trace:configure.ac:3087: -1- AC_SUBST_TRACE([DKERADISKLIBS])
+m4trace:configure.ac:3087: -1- m4_pattern_allow([^DKERADISKLIBS$])
+m4trace:configure.ac:3088: -1- AC_SUBST([DKLSLIBF])
+m4trace:configure.ac:3088: -1- AC_SUBST_TRACE([DKLSLIBF])
+m4trace:configure.ac:3088: -1- m4_pattern_allow([^DKLSLIBF$])
+m4trace:configure.ac:3089: -1- AC_SUBST([DKLSLIBS])
+m4trace:configure.ac:3089: -1- AC_SUBST_TRACE([DKLSLIBS])
+m4trace:configure.ac:3089: -1- m4_pattern_allow([^DKLSLIBS$])
+m4trace:configure.ac:3090: -1- AC_SUBST([DKSORTLIBF])
+m4trace:configure.ac:3090: -1- AC_SUBST_TRACE([DKSORTLIBF])
+m4trace:configure.ac:3090: -1- m4_pattern_allow([^DKSORTLIBF$])
+m4trace:configure.ac:3091: -1- AC_SUBST([DKSORTLIBS])
+m4trace:configure.ac:3091: -1- AC_SUBST_TRACE([DKSORTLIBS])
+m4trace:configure.ac:3091: -1- m4_pattern_allow([^DKSORTLIBS$])
+m4trace:configure.ac:3092: -1- AC_SUBST([DKFICLIBF])
+m4trace:configure.ac:3092: -1- AC_SUBST_TRACE([DKFICLIBF])
+m4trace:configure.ac:3092: -1- m4_pattern_allow([^DKFICLIBF$])
+m4trace:configure.ac:3093: -1- AC_SUBST([DKFICLIBS])
+m4trace:configure.ac:3093: -1- AC_SUBST_TRACE([DKFICLIBS])
+m4trace:configure.ac:3093: -1- m4_pattern_allow([^DKFICLIBS$])
+m4trace:configure.ac:3094: -1- AC_SUBST([DKUIDLIBF])
+m4trace:configure.ac:3094: -1- AC_SUBST_TRACE([DKUIDLIBF])
+m4trace:configure.ac:3094: -1- m4_pattern_allow([^DKUIDLIBF$])
+m4trace:configure.ac:3095: -1- AC_SUBST([DKUIDLIBS])
+m4trace:configure.ac:3095: -1- AC_SUBST_TRACE([DKUIDLIBS])
+m4trace:configure.ac:3095: -1- m4_pattern_allow([^DKUIDLIBS$])
+m4trace:configure.ac:3096: -1- AC_SUBST([DKPWGENLIBF])
+m4trace:configure.ac:3096: -1- AC_SUBST_TRACE([DKPWGENLIBF])
+m4trace:configure.ac:3096: -1- m4_pattern_allow([^DKPWGENLIBF$])
+m4trace:configure.ac:3097: -1- AC_SUBST([DKPWGENLIBS])
+m4trace:configure.ac:3097: -1- AC_SUBST_TRACE([DKPWGENLIBS])
+m4trace:configure.ac:3097: -1- m4_pattern_allow([^DKPWGENLIBS$])
+m4trace:configure.ac:3098: -1- AC_SUBST([DKRANDLIBF])
+m4trace:configure.ac:3098: -1- AC_SUBST_TRACE([DKRANDLIBF])
+m4trace:configure.ac:3098: -1- m4_pattern_allow([^DKRANDLIBF$])
+m4trace:configure.ac:3099: -1- AC_SUBST([DKRANDLIBS])
+m4trace:configure.ac:3099: -1- AC_SUBST_TRACE([DKRANDLIBS])
+m4trace:configure.ac:3099: -1- m4_pattern_allow([^DKRANDLIBS$])
+m4trace:configure.ac:3100: -1- AC_SUBST([DKT2HLIBF])
+m4trace:configure.ac:3100: -1- AC_SUBST_TRACE([DKT2HLIBF])
+m4trace:configure.ac:3100: -1- m4_pattern_allow([^DKT2HLIBF$])
+m4trace:configure.ac:3101: -1- AC_SUBST([DKT2HLIBS])
+m4trace:configure.ac:3101: -1- AC_SUBST_TRACE([DKT2HLIBS])
+m4trace:configure.ac:3101: -1- m4_pattern_allow([^DKT2HLIBS$])
+m4trace:configure.ac:3102: -1- AC_SUBST([DKT2LLIBF])
+m4trace:configure.ac:3102: -1- AC_SUBST_TRACE([DKT2LLIBF])
+m4trace:configure.ac:3102: -1- m4_pattern_allow([^DKT2LLIBF$])
+m4trace:configure.ac:3103: -1- AC_SUBST([DKT2LLIBS])
+m4trace:configure.ac:3103: -1- AC_SUBST_TRACE([DKT2LLIBS])
+m4trace:configure.ac:3103: -1- m4_pattern_allow([^DKT2LLIBS$])
+m4trace:configure.ac:3104: -1- AC_SUBST([DKHEXLIBF])
+m4trace:configure.ac:3104: -1- AC_SUBST_TRACE([DKHEXLIBF])
+m4trace:configure.ac:3104: -1- m4_pattern_allow([^DKHEXLIBF$])
+m4trace:configure.ac:3105: -1- AC_SUBST([DKHEXLIBS])
+m4trace:configure.ac:3105: -1- AC_SUBST_TRACE([DKHEXLIBS])
+m4trace:configure.ac:3105: -1- m4_pattern_allow([^DKHEXLIBS$])
+m4trace:configure.ac:3106: -1- AC_SUBST([DKBMMLIBF])
+m4trace:configure.ac:3106: -1- AC_SUBST_TRACE([DKBMMLIBF])
+m4trace:configure.ac:3106: -1- m4_pattern_allow([^DKBMMLIBF$])
+m4trace:configure.ac:3107: -1- AC_SUBST([DKBMMLIBS])
+m4trace:configure.ac:3107: -1- AC_SUBST_TRACE([DKBMMLIBS])
+m4trace:configure.ac:3107: -1- m4_pattern_allow([^DKBMMLIBS$])
+m4trace:configure.ac:3108: -1- AC_SUBST([DKPWDLIBF])
+m4trace:configure.ac:3108: -1- AC_SUBST_TRACE([DKPWDLIBF])
+m4trace:configure.ac:3108: -1- m4_pattern_allow([^DKPWDLIBF$])
+m4trace:configure.ac:3109: -1- AC_SUBST([DKPWDLIBS])
+m4trace:configure.ac:3109: -1- AC_SUBST_TRACE([DKPWDLIBS])
+m4trace:configure.ac:3109: -1- m4_pattern_allow([^DKPWDLIBS$])
+m4trace:configure.ac:3110: -1- AC_SUBST([DKRECVLIBF])
+m4trace:configure.ac:3110: -1- AC_SUBST_TRACE([DKRECVLIBF])
+m4trace:configure.ac:3110: -1- m4_pattern_allow([^DKRECVLIBF$])
+m4trace:configure.ac:3111: -1- AC_SUBST([DKRECVLIBS])
+m4trace:configure.ac:3111: -1- AC_SUBST_TRACE([DKRECVLIBS])
+m4trace:configure.ac:3111: -1- m4_pattern_allow([^DKRECVLIBS$])
+m4trace:configure.ac:3112: -1- AC_SUBST([DKSENDLIBF])
+m4trace:configure.ac:3112: -1- AC_SUBST_TRACE([DKSENDLIBF])
+m4trace:configure.ac:3112: -1- m4_pattern_allow([^DKSENDLIBF$])
+m4trace:configure.ac:3113: -1- AC_SUBST([DKSENDLIBS])
+m4trace:configure.ac:3113: -1- AC_SUBST_TRACE([DKSENDLIBS])
+m4trace:configure.ac:3113: -1- m4_pattern_allow([^DKSENDLIBS$])
+m4trace:configure.ac:3114: -1- AC_SUBST([DKDBT2LIBF])
+m4trace:configure.ac:3114: -1- AC_SUBST_TRACE([DKDBT2LIBF])
+m4trace:configure.ac:3114: -1- m4_pattern_allow([^DKDBT2LIBF$])
+m4trace:configure.ac:3115: -1- AC_SUBST([DKDBT2LIBS])
+m4trace:configure.ac:3115: -1- AC_SUBST_TRACE([DKDBT2LIBS])
+m4trace:configure.ac:3115: -1- m4_pattern_allow([^DKDBT2LIBS$])
+m4trace:configure.ac:3116: -1- AC_SUBST([DK4INFOLIBS])
+m4trace:configure.ac:3116: -1- AC_SUBST_TRACE([DK4INFOLIBS])
+m4trace:configure.ac:3116: -1- m4_pattern_allow([^DK4INFOLIBS$])
+m4trace:configure.ac:3117: -1- AC_SUBST([DK4INFOLIBF])
+m4trace:configure.ac:3117: -1- AC_SUBST_TRACE([DK4INFOLIBF])
+m4trace:configure.ac:3117: -1- m4_pattern_allow([^DK4INFOLIBF$])
+m4trace:configure.ac:3118: -1- AC_SUBST([PROGSOPENSSL])
+m4trace:configure.ac:3118: -1- AC_SUBST_TRACE([PROGSOPENSSL])
+m4trace:configure.ac:3118: -1- m4_pattern_allow([^PROGSOPENSSL$])
+m4trace:configure.ac:3119: -1- AC_SUBST([SOCKLIB])
+m4trace:configure.ac:3119: -1- AC_SUBST_TRACE([SOCKLIB])
+m4trace:configure.ac:3119: -1- m4_pattern_allow([^SOCKLIB$])
+m4trace:configure.ac:3120: -1- AC_SUBST([NSLLIB])
+m4trace:configure.ac:3120: -1- AC_SUBST_TRACE([NSLLIB])
+m4trace:configure.ac:3120: -1- m4_pattern_allow([^NSLLIB$])
+m4trace:configure.ac:3121: -1- AC_SUBST([LIB_SH_RES])
+m4trace:configure.ac:3121: -1- AC_SUBST_TRACE([LIB_SH_RES])
+m4trace:configure.ac:3121: -1- m4_pattern_allow([^LIB_SH_RES$])
+m4trace:configure.ac:3122: -1- AC_SUBST([LIB_SH_CLI])
+m4trace:configure.ac:3122: -1- AC_SUBST_TRACE([LIB_SH_CLI])
+m4trace:configure.ac:3122: -1- m4_pattern_allow([^LIB_SH_CLI$])
+m4trace:configure.ac:3123: -1- AC_SUBST([LIB_SH_GUI])
+m4trace:configure.ac:3123: -1- AC_SUBST_TRACE([LIB_SH_GUI])
+m4trace:configure.ac:3123: -1- m4_pattern_allow([^LIB_SH_GUI$])
+m4trace:configure.ac:3124: -1- AC_SUBST([NET_PROG_RES])
+m4trace:configure.ac:3124: -1- AC_SUBST_TRACE([NET_PROG_RES])
+m4trace:configure.ac:3124: -1- m4_pattern_allow([^NET_PROG_RES$])
+m4trace:configure.ac:3125: -1- AC_SUBST([NET_PROG_CLI])
+m4trace:configure.ac:3125: -1- AC_SUBST_TRACE([NET_PROG_CLI])
+m4trace:configure.ac:3125: -1- m4_pattern_allow([^NET_PROG_CLI$])
+m4trace:configure.ac:3126: -1- AC_SUBST([MYSQL_PROG_CLI])
+m4trace:configure.ac:3126: -1- AC_SUBST_TRACE([MYSQL_PROG_CLI])
+m4trace:configure.ac:3126: -1- m4_pattern_allow([^MYSQL_PROG_CLI$])
+m4trace:configure.ac:3127: -1- AC_SUBST([MYSQLLDFLAGS])
+m4trace:configure.ac:3127: -1- AC_SUBST_TRACE([MYSQLLDFLAGS])
+m4trace:configure.ac:3127: -1- m4_pattern_allow([^MYSQLLDFLAGS$])
+m4trace:configure.ac:3128: -1- AC_SUBST([SNMP_PROG_CLI])
+m4trace:configure.ac:3128: -1- AC_SUBST_TRACE([SNMP_PROG_CLI])
+m4trace:configure.ac:3128: -1- m4_pattern_allow([^SNMP_PROG_CLI$])
+m4trace:configure.ac:3129: -1- AC_SUBST([TESTPROGRAMS])
+m4trace:configure.ac:3129: -1- AC_SUBST_TRACE([TESTPROGRAMS])
+m4trace:configure.ac:3129: -1- m4_pattern_allow([^TESTPROGRAMS$])
+m4trace:configure.ac:3130: -1- AC_SUBST([WXCPPFLAGS])
+m4trace:configure.ac:3130: -1- AC_SUBST_TRACE([WXCPPFLAGS])
+m4trace:configure.ac:3130: -1- m4_pattern_allow([^WXCPPFLAGS$])
+m4trace:configure.ac:3131: -1- AC_SUBST([WXCXXFLAGS])
+m4trace:configure.ac:3131: -1- AC_SUBST_TRACE([WXCXXFLAGS])
+m4trace:configure.ac:3131: -1- m4_pattern_allow([^WXCXXFLAGS$])
+m4trace:configure.ac:3132: -1- AC_SUBST([WXCFLAGS])
+m4trace:configure.ac:3132: -1- AC_SUBST_TRACE([WXCFLAGS])
+m4trace:configure.ac:3132: -1- m4_pattern_allow([^WXCFLAGS$])
+m4trace:configure.ac:3133: -1- AC_SUBST([WXLDFLAGS])
+m4trace:configure.ac:3133: -1- AC_SUBST_TRACE([WXLDFLAGS])
+m4trace:configure.ac:3133: -1- m4_pattern_allow([^WXLDFLAGS$])
+m4trace:configure.ac:3134: -1- AC_SUBST([SOLIBZ])
+m4trace:configure.ac:3134: -1- AC_SUBST_TRACE([SOLIBZ])
+m4trace:configure.ac:3134: -1- m4_pattern_allow([^SOLIBZ$])
+m4trace:configure.ac:3135: -1- AC_SUBST([SOLIBBZ])
+m4trace:configure.ac:3135: -1- AC_SUBST_TRACE([SOLIBBZ])
+m4trace:configure.ac:3135: -1- m4_pattern_allow([^SOLIBBZ$])
+m4trace:configure.ac:3136: -1- AC_SUBST([SOLIBMATH])
+m4trace:configure.ac:3136: -1- AC_SUBST_TRACE([SOLIBMATH])
+m4trace:configure.ac:3136: -1- m4_pattern_allow([^SOLIBMATH$])
+m4trace:configure.ac:3137: -1- AC_SUBST([SOLIBCRYPTO])
+m4trace:configure.ac:3137: -1- AC_SUBST_TRACE([SOLIBCRYPTO])
+m4trace:configure.ac:3137: -1- m4_pattern_allow([^SOLIBCRYPTO$])
+m4trace:configure.ac:3138: -1- AC_SUBST([SOLIBNET])
+m4trace:configure.ac:3138: -1- AC_SUBST_TRACE([SOLIBNET])
+m4trace:configure.ac:3138: -1- m4_pattern_allow([^SOLIBNET$])
+m4trace:configure.ac:3139: -1- AC_SUBST([SOLIBIMG])
+m4trace:configure.ac:3139: -1- AC_SUBST_TRACE([SOLIBIMG])
+m4trace:configure.ac:3139: -1- m4_pattern_allow([^SOLIBIMG$])
+m4trace:configure.ac:3140: -1- AC_SUBST([SOLIBSDBI])
+m4trace:configure.ac:3140: -1- AC_SUBST_TRACE([SOLIBSDBI])
+m4trace:configure.ac:3140: -1- m4_pattern_allow([^SOLIBSDBI$])
+m4trace:configure.ac:3141: -1- AC_SUBST([SOLIBWX])
+m4trace:configure.ac:3141: -1- AC_SUBST_TRACE([SOLIBWX])
+m4trace:configure.ac:3141: -1- m4_pattern_allow([^SOLIBWX$])
+m4trace:configure.ac:3142: -1- AC_SUBST([SOLIBDK3PORT])
+m4trace:configure.ac:3142: -1- AC_SUBST_TRACE([SOLIBDK3PORT])
+m4trace:configure.ac:3142: -1- m4_pattern_allow([^SOLIBDK3PORT$])
+m4trace:configure.ac:3143: -1- AC_SUBST([SOLIBDK3C])
+m4trace:configure.ac:3143: -1- AC_SUBST_TRACE([SOLIBDK3C])
+m4trace:configure.ac:3143: -1- m4_pattern_allow([^SOLIBDK3C$])
+m4trace:configure.ac:3144: -1- AC_SUBST([SOLIBDK3OF])
+m4trace:configure.ac:3144: -1- AC_SUBST_TRACE([SOLIBDK3OF])
+m4trace:configure.ac:3144: -1- m4_pattern_allow([^SOLIBDK3OF$])
+m4trace:configure.ac:3145: -1- AC_SUBST([SOLIBDK3CSRND])
+m4trace:configure.ac:3145: -1- AC_SUBST_TRACE([SOLIBDK3CSRND])
+m4trace:configure.ac:3145: -1- m4_pattern_allow([^SOLIBDK3CSRND$])
+m4trace:configure.ac:3146: -1- AC_SUBST([SOLIBDK3BIF])
+m4trace:configure.ac:3146: -1- AC_SUBST_TRACE([SOLIBDK3BIF])
+m4trace:configure.ac:3146: -1- m4_pattern_allow([^SOLIBDK3BIF$])
+m4trace:configure.ac:3147: -1- AC_SUBST([SOLIBDK3DBI])
+m4trace:configure.ac:3147: -1- AC_SUBST_TRACE([SOLIBDK3DBI])
+m4trace:configure.ac:3147: -1- m4_pattern_allow([^SOLIBDK3DBI$])
+m4trace:configure.ac:3148: -1- AC_SUBST([SOLIBDK3FIG])
+m4trace:configure.ac:3148: -1- AC_SUBST_TRACE([SOLIBDK3FIG])
+m4trace:configure.ac:3148: -1- m4_pattern_allow([^SOLIBDK3FIG$])
+m4trace:configure.ac:3149: -1- AC_SUBST([SOLIBDK3BMEPS])
+m4trace:configure.ac:3149: -1- AC_SUBST_TRACE([SOLIBDK3BMEPS])
+m4trace:configure.ac:3149: -1- m4_pattern_allow([^SOLIBDK3BMEPS$])
+m4trace:configure.ac:3150: -1- AC_SUBST([SOLIBDK3NET])
+m4trace:configure.ac:3150: -1- AC_SUBST_TRACE([SOLIBDK3NET])
+m4trace:configure.ac:3150: -1- m4_pattern_allow([^SOLIBDK3NET$])
+m4trace:configure.ac:3151: -1- AC_SUBST([SOLIBDK4BASE])
+m4trace:configure.ac:3151: -1- AC_SUBST_TRACE([SOLIBDK4BASE])
+m4trace:configure.ac:3151: -1- m4_pattern_allow([^SOLIBDK4BASE$])
+m4trace:configure.ac:3152: -1- AC_SUBST([SOLIBDK4MA])
+m4trace:configure.ac:3152: -1- AC_SUBST_TRACE([SOLIBDK4MA])
+m4trace:configure.ac:3152: -1- m4_pattern_allow([^SOLIBDK4MA$])
+m4trace:configure.ac:3153: -1- AC_SUBST([SOLIBDK4MAIO8H])
+m4trace:configure.ac:3153: -1- AC_SUBST_TRACE([SOLIBDK4MAIO8H])
+m4trace:configure.ac:3153: -1- m4_pattern_allow([^SOLIBDK4MAIO8H$])
+m4trace:configure.ac:3154: -1- AC_SUBST([SOLIBDK4MAIOWH])
+m4trace:configure.ac:3154: -1- AC_SUBST_TRACE([SOLIBDK4MAIOWH])
+m4trace:configure.ac:3154: -1- m4_pattern_allow([^SOLIBDK4MAIOWH$])
+m4trace:configure.ac:3155: -1- AC_SUBST([SOLIBDK4MAIODH])
+m4trace:configure.ac:3155: -1- AC_SUBST_TRACE([SOLIBDK4MAIODH])
+m4trace:configure.ac:3155: -1- m4_pattern_allow([^SOLIBDK4MAIODH$])
+m4trace:configure.ac:3156: -1- AC_SUBST([SOLIBDK4MAIO8D])
+m4trace:configure.ac:3156: -1- AC_SUBST_TRACE([SOLIBDK4MAIO8D])
+m4trace:configure.ac:3156: -1- m4_pattern_allow([^SOLIBDK4MAIO8D$])
+m4trace:configure.ac:3157: -1- AC_SUBST([SOLIBDK4MAIOWD])
+m4trace:configure.ac:3157: -1- AC_SUBST_TRACE([SOLIBDK4MAIOWD])
+m4trace:configure.ac:3157: -1- m4_pattern_allow([^SOLIBDK4MAIOWD$])
+m4trace:configure.ac:3158: -1- AC_SUBST([SOLIBDK4MAIODD])
+m4trace:configure.ac:3158: -1- AC_SUBST_TRACE([SOLIBDK4MAIODD])
+m4trace:configure.ac:3158: -1- m4_pattern_allow([^SOLIBDK4MAIODD$])
+m4trace:configure.ac:3159: -1- AC_SUBST([SOLIBDK4C])
+m4trace:configure.ac:3159: -1- AC_SUBST_TRACE([SOLIBDK4C])
+m4trace:configure.ac:3159: -1- m4_pattern_allow([^SOLIBDK4C$])
+m4trace:configure.ac:3160: -1- AC_SUBST([SOLIBDK4MDRND])
+m4trace:configure.ac:3160: -1- AC_SUBST_TRACE([SOLIBDK4MDRND])
+m4trace:configure.ac:3160: -1- m4_pattern_allow([^SOLIBDK4MDRND$])
+m4trace:configure.ac:3161: -1- AC_SUBST([SOLIBDK4PPPT])
+m4trace:configure.ac:3161: -1- AC_SUBST_TRACE([SOLIBDK4PPPT])
+m4trace:configure.ac:3161: -1- m4_pattern_allow([^SOLIBDK4PPPT$])
+m4trace:configure.ac:3162: -1- AC_SUBST([SOLIBDK4APP])
+m4trace:configure.ac:3162: -1- AC_SUBST_TRACE([SOLIBDK4APP])
+m4trace:configure.ac:3162: -1- m4_pattern_allow([^SOLIBDK4APP$])
+m4trace:configure.ac:3163: -1- AC_SUBST([SOLIBDK4LAT])
+m4trace:configure.ac:3163: -1- AC_SUBST_TRACE([SOLIBDK4LAT])
+m4trace:configure.ac:3163: -1- m4_pattern_allow([^SOLIBDK4LAT$])
+m4trace:configure.ac:3164: -1- AC_SUBST([SOLIBDK4SOCK])
+m4trace:configure.ac:3164: -1- AC_SUBST_TRACE([SOLIBDK4SOCK])
+m4trace:configure.ac:3164: -1- m4_pattern_allow([^SOLIBDK4SOCK$])
+m4trace:configure.ac:3165: -1- AC_SUBST([SOLIBDK4SOCKA])
+m4trace:configure.ac:3165: -1- AC_SUBST_TRACE([SOLIBDK4SOCKA])
+m4trace:configure.ac:3165: -1- m4_pattern_allow([^SOLIBDK4SOCKA$])
+m4trace:configure.ac:3166: -1- AC_SUBST([SOLIBDK4DBI])
+m4trace:configure.ac:3166: -1- AC_SUBST_TRACE([SOLIBDK4DBI])
+m4trace:configure.ac:3166: -1- m4_pattern_allow([^SOLIBDK4DBI$])
+m4trace:configure.ac:3167: -1- AC_SUBST([SOLIBDK4DBIA])
+m4trace:configure.ac:3167: -1- AC_SUBST_TRACE([SOLIBDK4DBIA])
+m4trace:configure.ac:3167: -1- m4_pattern_allow([^SOLIBDK4DBIA$])
+m4trace:configure.ac:3168: -1- AC_SUBST([NETSNMP_LIBS])
+m4trace:configure.ac:3168: -1- AC_SUBST_TRACE([NETSNMP_LIBS])
+m4trace:configure.ac:3168: -1- m4_pattern_allow([^NETSNMP_LIBS$])
+m4trace:configure.ac:3169: -1- AC_SUBST([MYSQLLIB])
+m4trace:configure.ac:3169: -1- AC_SUBST_TRACE([MYSQLLIB])
+m4trace:configure.ac:3169: -1- m4_pattern_allow([^MYSQLLIB$])
+m4trace:configure.ac:3170: -1- AC_SUBST([NETSNMP_CFLAGS])
+m4trace:configure.ac:3170: -1- AC_SUBST_TRACE([NETSNMP_CFLAGS])
+m4trace:configure.ac:3170: -1- m4_pattern_allow([^NETSNMP_CFLAGS$])
+m4trace:configure.ac:3171: -1- AC_SUBST([WXDKFCSLIBF])
+m4trace:configure.ac:3171: -1- AC_SUBST_TRACE([WXDKFCSLIBF])
+m4trace:configure.ac:3171: -1- m4_pattern_allow([^WXDKFCSLIBF$])
+m4trace:configure.ac:3172: -1- AC_SUBST([WXDKFCSLIBS])
+m4trace:configure.ac:3172: -1- AC_SUBST_TRACE([WXDKFCSLIBS])
+m4trace:configure.ac:3172: -1- m4_pattern_allow([^WXDKFCSLIBS$])
+m4trace:configure.ac:3173: -1- AC_SUBST([GETSOURCE])
+m4trace:configure.ac:3173: -1- AC_SUBST_TRACE([GETSOURCE])
+m4trace:configure.ac:3173: -1- m4_pattern_allow([^GETSOURCE$])
+m4trace:configure.ac:3174: -1- AC_SUBST([MAKE])
+m4trace:configure.ac:3174: -1- AC_SUBST_TRACE([MAKE])
+m4trace:configure.ac:3174: -1- m4_pattern_allow([^MAKE$])
+m4trace:configure.ac:3175: -1- AC_SUBST([CLILIB])
+m4trace:configure.ac:3175: -1- AC_SUBST_TRACE([CLILIB])
+m4trace:configure.ac:3175: -1- m4_pattern_allow([^CLILIB$])
+m4trace:configure.ac:3176: -1- AC_SUBST([GUILIB])
+m4trace:configure.ac:3176: -1- AC_SUBST_TRACE([GUILIB])
+m4trace:configure.ac:3176: -1- m4_pattern_allow([^GUILIB$])
+m4trace:configure.ac:3177: -1- AC_SUBST([ENTRY])
+m4trace:configure.ac:3177: -1- AC_SUBST_TRACE([ENTRY])
+m4trace:configure.ac:3177: -1- m4_pattern_allow([^ENTRY$])
+m4trace:configure.ac:3178: -1- AC_SUBST([WINUNICODE])
+m4trace:configure.ac:3178: -1- AC_SUBST_TRACE([WINUNICODE])
+m4trace:configure.ac:3178: -1- m4_pattern_allow([^WINUNICODE$])
+m4trace:configure.ac:3179: -1- AC_SUBST([INSTALLMANPAGES])
+m4trace:configure.ac:3179: -1- AC_SUBST_TRACE([INSTALLMANPAGES])
+m4trace:configure.ac:3179: -1- m4_pattern_allow([^INSTALLMANPAGES$])
+m4trace:configure.ac:3180: -1- AC_SUBST([LIBSPRIVATE])
+m4trace:configure.ac:3180: -1- AC_SUBST_TRACE([LIBSPRIVATE])
+m4trace:configure.ac:3180: -1- m4_pattern_allow([^LIBSPRIVATE$])
+m4trace:configure.ac:3181: -1- AC_SUBST([RTLIB])
+m4trace:configure.ac:3181: -1- AC_SUBST_TRACE([RTLIB])
+m4trace:configure.ac:3181: -1- m4_pattern_allow([^RTLIB$])
+m4trace:configure.ac:3182: -1- AC_SUBST([LIBDK4BASELIBF])
+m4trace:configure.ac:3182: -1- AC_SUBST_TRACE([LIBDK4BASELIBF])
+m4trace:configure.ac:3182: -1- m4_pattern_allow([^LIBDK4BASELIBF$])
+m4trace:configure.ac:3183: -1- AC_SUBST([LIBDK4BASELIBS])
+m4trace:configure.ac:3183: -1- AC_SUBST_TRACE([LIBDK4BASELIBS])
+m4trace:configure.ac:3183: -1- m4_pattern_allow([^LIBDK4BASELIBS$])
+m4trace:configure.ac:3184: -1- AC_SUBST([LIBDK4MALIBF])
+m4trace:configure.ac:3184: -1- AC_SUBST_TRACE([LIBDK4MALIBF])
+m4trace:configure.ac:3184: -1- m4_pattern_allow([^LIBDK4MALIBF$])
+m4trace:configure.ac:3185: -1- AC_SUBST([LIBDK4MALIBS])
+m4trace:configure.ac:3185: -1- AC_SUBST_TRACE([LIBDK4MALIBS])
+m4trace:configure.ac:3185: -1- m4_pattern_allow([^LIBDK4MALIBS$])
+m4trace:configure.ac:3186: -1- AC_SUBST([LIBDK4MAIO8DLIBF])
+m4trace:configure.ac:3186: -1- AC_SUBST_TRACE([LIBDK4MAIO8DLIBF])
+m4trace:configure.ac:3186: -1- m4_pattern_allow([^LIBDK4MAIO8DLIBF$])
+m4trace:configure.ac:3187: -1- AC_SUBST([LIBDK4MAIO8DLIBS])
+m4trace:configure.ac:3187: -1- AC_SUBST_TRACE([LIBDK4MAIO8DLIBS])
+m4trace:configure.ac:3187: -1- m4_pattern_allow([^LIBDK4MAIO8DLIBS$])
+m4trace:configure.ac:3188: -1- AC_SUBST([LIBDK4MAIOWDLIBF])
+m4trace:configure.ac:3188: -1- AC_SUBST_TRACE([LIBDK4MAIOWDLIBF])
+m4trace:configure.ac:3188: -1- m4_pattern_allow([^LIBDK4MAIOWDLIBF$])
+m4trace:configure.ac:3189: -1- AC_SUBST([LIBDK4MAIOWDLIBS])
+m4trace:configure.ac:3189: -1- AC_SUBST_TRACE([LIBDK4MAIOWDLIBS])
+m4trace:configure.ac:3189: -1- m4_pattern_allow([^LIBDK4MAIOWDLIBS$])
+m4trace:configure.ac:3190: -1- AC_SUBST([LIBDK4MAIODDLIBF])
+m4trace:configure.ac:3190: -1- AC_SUBST_TRACE([LIBDK4MAIODDLIBF])
+m4trace:configure.ac:3190: -1- m4_pattern_allow([^LIBDK4MAIODDLIBF$])
+m4trace:configure.ac:3191: -1- AC_SUBST([LIBDK4MAIODDLIBS])
+m4trace:configure.ac:3191: -1- AC_SUBST_TRACE([LIBDK4MAIODDLIBS])
+m4trace:configure.ac:3191: -1- m4_pattern_allow([^LIBDK4MAIODDLIBS$])
+m4trace:configure.ac:3192: -1- AC_SUBST([LIBDK4MAIOXDLIBF])
+m4trace:configure.ac:3192: -1- AC_SUBST_TRACE([LIBDK4MAIOXDLIBF])
+m4trace:configure.ac:3192: -1- m4_pattern_allow([^LIBDK4MAIOXDLIBF$])
+m4trace:configure.ac:3193: -1- AC_SUBST([LIBDK4MAIOXDLIBS])
+m4trace:configure.ac:3193: -1- AC_SUBST_TRACE([LIBDK4MAIOXDLIBS])
+m4trace:configure.ac:3193: -1- m4_pattern_allow([^LIBDK4MAIOXDLIBS$])
+m4trace:configure.ac:3194: -1- AC_SUBST([LIBDK4MAIO8HLIBF])
+m4trace:configure.ac:3194: -1- AC_SUBST_TRACE([LIBDK4MAIO8HLIBF])
+m4trace:configure.ac:3194: -1- m4_pattern_allow([^LIBDK4MAIO8HLIBF$])
+m4trace:configure.ac:3195: -1- AC_SUBST([LIBDK4MAIO8HLIBS])
+m4trace:configure.ac:3195: -1- AC_SUBST_TRACE([LIBDK4MAIO8HLIBS])
+m4trace:configure.ac:3195: -1- m4_pattern_allow([^LIBDK4MAIO8HLIBS$])
+m4trace:configure.ac:3196: -1- AC_SUBST([LIBDK4MAIOWHLIBF])
+m4trace:configure.ac:3196: -1- AC_SUBST_TRACE([LIBDK4MAIOWHLIBF])
+m4trace:configure.ac:3196: -1- m4_pattern_allow([^LIBDK4MAIOWHLIBF$])
+m4trace:configure.ac:3197: -1- AC_SUBST([LIBDK4MAIOWHLIBS])
+m4trace:configure.ac:3197: -1- AC_SUBST_TRACE([LIBDK4MAIOWHLIBS])
+m4trace:configure.ac:3197: -1- m4_pattern_allow([^LIBDK4MAIOWHLIBS$])
+m4trace:configure.ac:3198: -1- AC_SUBST([LIBDK4MAIODHLIBF])
+m4trace:configure.ac:3198: -1- AC_SUBST_TRACE([LIBDK4MAIODHLIBF])
+m4trace:configure.ac:3198: -1- m4_pattern_allow([^LIBDK4MAIODHLIBF$])
+m4trace:configure.ac:3199: -1- AC_SUBST([LIBDK4MAIODHLIBS])
+m4trace:configure.ac:3199: -1- AC_SUBST_TRACE([LIBDK4MAIODHLIBS])
+m4trace:configure.ac:3199: -1- m4_pattern_allow([^LIBDK4MAIODHLIBS$])
+m4trace:configure.ac:3200: -1- AC_SUBST([LIBDK4DBILIBF])
+m4trace:configure.ac:3200: -1- AC_SUBST_TRACE([LIBDK4DBILIBF])
+m4trace:configure.ac:3200: -1- m4_pattern_allow([^LIBDK4DBILIBF$])
+m4trace:configure.ac:3201: -1- AC_SUBST([LIBDK4DBILIBS])
+m4trace:configure.ac:3201: -1- AC_SUBST_TRACE([LIBDK4DBILIBS])
+m4trace:configure.ac:3201: -1- m4_pattern_allow([^LIBDK4DBILIBS$])
+m4trace:configure.ac:3202: -1- AC_SUBST([LIBDK4CLIBF])
+m4trace:configure.ac:3202: -1- AC_SUBST_TRACE([LIBDK4CLIBF])
+m4trace:configure.ac:3202: -1- m4_pattern_allow([^LIBDK4CLIBF$])
+m4trace:configure.ac:3203: -1- AC_SUBST([LIBDK4CLIBS])
+m4trace:configure.ac:3203: -1- AC_SUBST_TRACE([LIBDK4CLIBS])
+m4trace:configure.ac:3203: -1- m4_pattern_allow([^LIBDK4CLIBS$])
+m4trace:configure.ac:3204: -1- AC_SUBST([LIBDK4LATLIBF])
+m4trace:configure.ac:3204: -1- AC_SUBST_TRACE([LIBDK4LATLIBF])
+m4trace:configure.ac:3204: -1- m4_pattern_allow([^LIBDK4LATLIBF$])
+m4trace:configure.ac:3205: -1- AC_SUBST([LIBDK4LATLIBS])
+m4trace:configure.ac:3205: -1- AC_SUBST_TRACE([LIBDK4LATLIBS])
+m4trace:configure.ac:3205: -1- m4_pattern_allow([^LIBDK4LATLIBS$])
+m4trace:configure.ac:3206: -1- AC_SUBST([LIBDK4SOCKLIBF])
+m4trace:configure.ac:3206: -1- AC_SUBST_TRACE([LIBDK4SOCKLIBF])
+m4trace:configure.ac:3206: -1- m4_pattern_allow([^LIBDK4SOCKLIBF$])
+m4trace:configure.ac:3207: -1- AC_SUBST([LIBDK4SOCKLIBS])
+m4trace:configure.ac:3207: -1- AC_SUBST_TRACE([LIBDK4SOCKLIBS])
+m4trace:configure.ac:3207: -1- m4_pattern_allow([^LIBDK4SOCKLIBS$])
+m4trace:configure.ac:3208: -1- AC_SUBST([LIBDK4MDRNDLIBF])
+m4trace:configure.ac:3208: -1- AC_SUBST_TRACE([LIBDK4MDRNDLIBF])
+m4trace:configure.ac:3208: -1- m4_pattern_allow([^LIBDK4MDRNDLIBF$])
+m4trace:configure.ac:3209: -1- AC_SUBST([LIBDK4MDRNDLIBS])
+m4trace:configure.ac:3209: -1- AC_SUBST_TRACE([LIBDK4MDRNDLIBS])
+m4trace:configure.ac:3209: -1- m4_pattern_allow([^LIBDK4MDRNDLIBS$])
+m4trace:configure.ac:3210: -1- AC_SUBST([LIBDK4PPPTLIBF])
+m4trace:configure.ac:3210: -1- AC_SUBST_TRACE([LIBDK4PPPTLIBF])
+m4trace:configure.ac:3210: -1- m4_pattern_allow([^LIBDK4PPPTLIBF$])
+m4trace:configure.ac:3211: -1- AC_SUBST([LIBDK4PPPTLIBS])
+m4trace:configure.ac:3211: -1- AC_SUBST_TRACE([LIBDK4PPPTLIBS])
+m4trace:configure.ac:3211: -1- m4_pattern_allow([^LIBDK4PPPTLIBS$])
+m4trace:configure.ac:3212: -1- AC_SUBST([LIBDK4APPLIBF])
+m4trace:configure.ac:3212: -1- AC_SUBST_TRACE([LIBDK4APPLIBF])
+m4trace:configure.ac:3212: -1- m4_pattern_allow([^LIBDK4APPLIBF$])
+m4trace:configure.ac:3213: -1- AC_SUBST([LIBDK4APPLIBS])
+m4trace:configure.ac:3213: -1- AC_SUBST_TRACE([LIBDK4APPLIBS])
+m4trace:configure.ac:3213: -1- m4_pattern_allow([^LIBDK4APPLIBS$])
+m4trace:configure.ac:3214: -1- AC_SUBST([LIBDK4PPPTALIBF])
+m4trace:configure.ac:3214: -1- AC_SUBST_TRACE([LIBDK4PPPTALIBF])
+m4trace:configure.ac:3214: -1- m4_pattern_allow([^LIBDK4PPPTALIBF$])
+m4trace:configure.ac:3215: -1- AC_SUBST([LIBDK4PPPTALIBS])
+m4trace:configure.ac:3215: -1- AC_SUBST_TRACE([LIBDK4PPPTALIBS])
+m4trace:configure.ac:3215: -1- m4_pattern_allow([^LIBDK4PPPTALIBS$])
+m4trace:configure.ac:3216: -1- AC_SUBST([LIBDK4SOCKALIBF])
+m4trace:configure.ac:3216: -1- AC_SUBST_TRACE([LIBDK4SOCKALIBF])
+m4trace:configure.ac:3216: -1- m4_pattern_allow([^LIBDK4SOCKALIBF$])
+m4trace:configure.ac:3217: -1- AC_SUBST([LIBDK4SOCKALIBS])
+m4trace:configure.ac:3217: -1- AC_SUBST_TRACE([LIBDK4SOCKALIBS])
+m4trace:configure.ac:3217: -1- m4_pattern_allow([^LIBDK4SOCKALIBS$])
+m4trace:configure.ac:3218: -1- AC_SUBST([LIBDK4DBIALIBF])
+m4trace:configure.ac:3218: -1- AC_SUBST_TRACE([LIBDK4DBIALIBF])
+m4trace:configure.ac:3218: -1- m4_pattern_allow([^LIBDK4DBIALIBF$])
+m4trace:configure.ac:3219: -1- AC_SUBST([LIBDK4DBIALIBS])
+m4trace:configure.ac:3219: -1- AC_SUBST_TRACE([LIBDK4DBIALIBS])
+m4trace:configure.ac:3219: -1- m4_pattern_allow([^LIBDK4DBIALIBS$])
+m4trace:configure.ac:3220: -1- AC_SUBST([LIBDK4WXLIBF])
+m4trace:configure.ac:3220: -1- AC_SUBST_TRACE([LIBDK4WXLIBF])
+m4trace:configure.ac:3220: -1- m4_pattern_allow([^LIBDK4WXLIBF$])
+m4trace:configure.ac:3221: -1- AC_SUBST([LIBDK4WXLIBS])
+m4trace:configure.ac:3221: -1- AC_SUBST_TRACE([LIBDK4WXLIBS])
+m4trace:configure.ac:3221: -1- m4_pattern_allow([^LIBDK4WXLIBS$])
+m4trace:configure.ac:3222: -1- AC_SUBST([LIBDK3TRACELIBF])
+m4trace:configure.ac:3222: -1- AC_SUBST_TRACE([LIBDK3TRACELIBF])
+m4trace:configure.ac:3222: -1- m4_pattern_allow([^LIBDK3TRACELIBF$])
+m4trace:configure.ac:3223: -1- AC_SUBST([LIBDK3TRACELIBS])
+m4trace:configure.ac:3223: -1- AC_SUBST_TRACE([LIBDK3TRACELIBS])
+m4trace:configure.ac:3223: -1- m4_pattern_allow([^LIBDK3TRACELIBS$])
+m4trace:configure.ac:3224: -1- AC_SUBST([LIBDK3CLIBF])
+m4trace:configure.ac:3224: -1- AC_SUBST_TRACE([LIBDK3CLIBF])
+m4trace:configure.ac:3224: -1- m4_pattern_allow([^LIBDK3CLIBF$])
+m4trace:configure.ac:3225: -1- AC_SUBST([LIBDK3CLIBS])
+m4trace:configure.ac:3225: -1- AC_SUBST_TRACE([LIBDK3CLIBS])
+m4trace:configure.ac:3225: -1- m4_pattern_allow([^LIBDK3CLIBS$])
+m4trace:configure.ac:3226: -1- AC_SUBST([LIBDK3OFLIBF])
+m4trace:configure.ac:3226: -1- AC_SUBST_TRACE([LIBDK3OFLIBF])
+m4trace:configure.ac:3226: -1- m4_pattern_allow([^LIBDK3OFLIBF$])
+m4trace:configure.ac:3227: -1- AC_SUBST([LIBDK3OFLIBS])
+m4trace:configure.ac:3227: -1- AC_SUBST_TRACE([LIBDK3OFLIBS])
+m4trace:configure.ac:3227: -1- m4_pattern_allow([^LIBDK3OFLIBS$])
+m4trace:configure.ac:3228: -1- AC_SUBST([LIBDK3CSRNDLIBF])
+m4trace:configure.ac:3228: -1- AC_SUBST_TRACE([LIBDK3CSRNDLIBF])
+m4trace:configure.ac:3228: -1- m4_pattern_allow([^LIBDK3CSRNDLIBF$])
+m4trace:configure.ac:3229: -1- AC_SUBST([LIBDK3CSRNDLIBS])
+m4trace:configure.ac:3229: -1- AC_SUBST_TRACE([LIBDK3CSRNDLIBS])
+m4trace:configure.ac:3229: -1- m4_pattern_allow([^LIBDK3CSRNDLIBS$])
+m4trace:configure.ac:3230: -1- AC_SUBST([LIBDK3BIFLIBF])
+m4trace:configure.ac:3230: -1- AC_SUBST_TRACE([LIBDK3BIFLIBF])
+m4trace:configure.ac:3230: -1- m4_pattern_allow([^LIBDK3BIFLIBF$])
+m4trace:configure.ac:3231: -1- AC_SUBST([LIBDK3BIFLIBS])
+m4trace:configure.ac:3231: -1- AC_SUBST_TRACE([LIBDK3BIFLIBS])
+m4trace:configure.ac:3231: -1- m4_pattern_allow([^LIBDK3BIFLIBS$])
+m4trace:configure.ac:3232: -1- AC_SUBST([LIBDK3DBILIBF])
+m4trace:configure.ac:3232: -1- AC_SUBST_TRACE([LIBDK3DBILIBF])
+m4trace:configure.ac:3232: -1- m4_pattern_allow([^LIBDK3DBILIBF$])
+m4trace:configure.ac:3233: -1- AC_SUBST([LIBDK3DBILIBS])
+m4trace:configure.ac:3233: -1- AC_SUBST_TRACE([LIBDK3DBILIBS])
+m4trace:configure.ac:3233: -1- m4_pattern_allow([^LIBDK3DBILIBS$])
+m4trace:configure.ac:3234: -1- AC_SUBST([LIBDK3BMEPSLIBF])
+m4trace:configure.ac:3234: -1- AC_SUBST_TRACE([LIBDK3BMEPSLIBF])
+m4trace:configure.ac:3234: -1- m4_pattern_allow([^LIBDK3BMEPSLIBF$])
+m4trace:configure.ac:3235: -1- AC_SUBST([LIBDK3BMEPSLIBS])
+m4trace:configure.ac:3235: -1- AC_SUBST_TRACE([LIBDK3BMEPSLIBS])
+m4trace:configure.ac:3235: -1- m4_pattern_allow([^LIBDK3BMEPSLIBS$])
+m4trace:configure.ac:3236: -1- AC_SUBST([LIBDK3FIGLIBF])
+m4trace:configure.ac:3236: -1- AC_SUBST_TRACE([LIBDK3FIGLIBF])
+m4trace:configure.ac:3236: -1- m4_pattern_allow([^LIBDK3FIGLIBF$])
+m4trace:configure.ac:3237: -1- AC_SUBST([LIBDK3FIGLIBS])
+m4trace:configure.ac:3237: -1- AC_SUBST_TRACE([LIBDK3FIGLIBS])
+m4trace:configure.ac:3237: -1- m4_pattern_allow([^LIBDK3FIGLIBS$])
+m4trace:configure.ac:3238: -1- AC_SUBST([LIBDK3WXLIBF])
+m4trace:configure.ac:3238: -1- AC_SUBST_TRACE([LIBDK3WXLIBF])
+m4trace:configure.ac:3238: -1- m4_pattern_allow([^LIBDK3WXLIBF$])
+m4trace:configure.ac:3239: -1- AC_SUBST([LIBDK3WXLIBS])
+m4trace:configure.ac:3239: -1- AC_SUBST_TRACE([LIBDK3WXLIBS])
+m4trace:configure.ac:3239: -1- m4_pattern_allow([^LIBDK3WXLIBS$])
+m4trace:configure.ac:3241: -1- AC_CONFIG_FILES([Makefile scripts/wr-dk3inst.sh scripts/wr-dk4inst.sh scripts/create-desktop-files.sh scripts/build-help.sh initd-printqd dktools.pc pkginfo debian/control])
+m4trace:configure.ac:3241: -1- _m4_warn([obsolete], [AC_OUTPUT should be used without arguments.
+You should run autoupdate.], [])
+m4trace:configure.ac:3241: -1- AC_SUBST([LIB@&t@OBJS], [$ac_libobjs])
+m4trace:configure.ac:3241: -1- AC_SUBST_TRACE([LIB@&t@OBJS])
+m4trace:configure.ac:3241: -1- m4_pattern_allow([^LIB@&t@OBJS$])
+m4trace:configure.ac:3241: -1- AC_SUBST([LTLIBOBJS], [$ac_ltlibobjs])
+m4trace:configure.ac:3241: -1- AC_SUBST_TRACE([LTLIBOBJS])
+m4trace:configure.ac:3241: -1- m4_pattern_allow([^LTLIBOBJS$])
+m4trace:configure.ac:3241: -1- AC_SUBST_TRACE([top_builddir])
+m4trace:configure.ac:3241: -1- AC_SUBST_TRACE([top_build_prefix])
+m4trace:configure.ac:3241: -1- AC_SUBST_TRACE([srcdir])
+m4trace:configure.ac:3241: -1- AC_SUBST_TRACE([abs_srcdir])
+m4trace:configure.ac:3241: -1- AC_SUBST_TRACE([top_srcdir])
+m4trace:configure.ac:3241: -1- AC_SUBST_TRACE([abs_top_srcdir])
+m4trace:configure.ac:3241: -1- AC_SUBST_TRACE([builddir])
+m4trace:configure.ac:3241: -1- AC_SUBST_TRACE([abs_builddir])
+m4trace:configure.ac:3241: -1- AC_SUBST_TRACE([abs_top_builddir])
+m4trace:configure.ac:3241: -1- AC_SUBST_TRACE([INSTALL])
+m4trace:configure.ac:3241: -1- AC_SUBST_TRACE([MKDIR_P])
diff --git a/support/dktools/bmeps3.c b/support/dktools/bmeps3.c
new file mode 100644
index 0000000000..52c7fd0632
--- /dev/null
+++ b/support/dktools/bmeps3.c
@@ -0,0 +1,1349 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: bmeps3.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file bmeps3.c The bmeps3 module.
+*/
+
+
+#line 12 "bmeps3.ctr"
+
+#include "dk3all.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4vers.h"
+#include "dk3bif.h"
+#include "dk3bmeo.h"
+#include "dk3bmeps.h"
+#include "dk3bm.h"
+
+
+
+
+
+#line 26 "bmeps3.ctr"
+
+
+
+/** Help text shown if no help file is found.
+*/
+static dkChar const * const bmeps3_default_help_text[] = {
+dkT(""),
+dkT("NAME"),
+dkT(""),
+dkT(" bmpp - Bitmap to PS/PDF converter"),
+dkT(""),
+dkT("SYNOPSIS"),
+dkT(""),
+dkT(" bmpp [-l<driver>[.<mode>][,<key>[=<value>]...]] [<options>] <file(s)>"),
+dkT(""),
+dkT("DESCRIPTION"),
+dkT(""),
+dkT("The program converts bitmap images from PNG, JPEG, or TIFF to PS/EPS and PDF."),
+dkT(""),
+dkT("Drivers:"),
+dkT("- ps"),
+dkT(" PostScript file, can be used to print."),
+dkT("- eps"),
+dkT(" Encapsulated PostScript (EPS), image for inclusion into documents."),
+dkT("- pdf"),
+dkT(" Portable document format (PDF)."),
+dkT("- bb"),
+dkT(" Bounding box information only, no image."),
+dkT(""),
+dkT("Output modes:"),
+dkT("- object"),
+dkT(" Object which can embedded into a text or drawing by a text processing"),
+dkT(" or drawing software."),
+dkT("- image"),
+dkT(" Image for stand-alone viewing."),
+dkT("- document"),
+dkT(" Fit the output to a given paper size for printing."),
+dkT(""),
+dkT("OPTIONS"),
+dkT(""),
+dkT("-h"),
+dkT("--help"),
+dkT("\tShow help text."),
+dkT(""),
+dkT("-v"),
+dkT("--version"),
+dkT("\tShow version number."),
+dkT(""),
+dkT("-L"),
+dkT("--license-terms"),
+dkT("\tShows license terms."),
+dkT(""),
+dkT("-t <type>"),
+dkT("\tInput image type, \"png\", \"jpeg\", or \"tiff\", must be specified when"),
+dkT("\tprocessing standard input or if the input file name suffix does"),
+dkT("\tnot indicate the type."),
+dkT(""),
+dkT("-m"),
+dkT("\tMake mode: Avoid unnecessary conversions if output file is up to date."),
+dkT("\tOnly used when processing a directory."),
+dkT(""),
+dkT("-s"),
+dkT("\tWrite to standard output, not to a file."),
+dkT(""),
+dkT("-o <key>[=<value>]"),
+dkT("\tDetailed conversion options."),
+dkT(""),
+dkT("NAME=VALUE PAIRS"),
+dkT(""),
+dkT("The key=value pairs set detailed conversion options. For boolean"),
+dkT("settings the value can be omitted, the presence of the name sets the option"),
+dkT("to active."),
+dkT("The following keys (and values) can be used:"),
+dkT(""),
+dkT("level=<pslevel>"),
+dkT("\tPS level, \"2\" or \"3\". Default: 3."),
+dkT(""),
+dkT("color[=<boolean>]"),
+dkT("\tColor output for PS/EPS output. For PDF output color is"),
+dkT("\talways enabled. This setting is ignored when passing DCT data from"),
+dkT("\tJPEG files to output directly."),
+dkT("\tDefault: On."),
+dkT(""),
+dkT("dsc[=<boolean>]"),
+dkT("\tDSC comments when producing PS/EPS output."),
+dkT("\tDefault: Off, except for ps.document."),
+dkT(""),
+dkT("draft[=<boolean>]"),
+dkT("\tDraft mode (small placeholder image only). Default: Off."),
+dkT(""),
+dkT("predictor=<predictor>"),
+dkT("\tPredictor for flate compressions, \"tiff\", \"sub\", \"up\","),
+dkT("\t\"average\", or \"paeth\". Default: none."),
+dkT(""),
+dkT("duplex[=<boolean>]"),
+dkT("\tDuplex mode when producing documents. Default: Off."),
+dkT(""),
+dkT("tumble[=<boolean>]"),
+dkT("\tTumble in addition to duplex mode. Default: Off."),
+dkT(""),
+dkT("dct[=<boolean>]"),
+dkT("\tDirect pass-through of DCT encoded data found in JPEG"),
+dkT("\tfiles. Default: On."),
+dkT(""),
+dkT("bg=<int>:<int>:<int>[:<boolean>]"),
+dkT("\tDefault background RGB color to be used if the input file"),
+dkT("\tdoes not contain a background color chunk. The optional boolean value"),
+dkT("\tat the end can be used to enforce this background over the background"),
+dkT("\tchunk. RGB values are in the range 0...255."),
+dkT("\tDefault: White, off."),
+dkT(""),
+dkT("interpolation[=<boolean>]"),
+dkT("\tImage interpolation. Default: On."),
+dkT(""),
+dkT("jpeg-interpolation[=<boolean>]"),
+dkT("\tImage interpolation if DCT data is passed through directly."),
+dkT("\tDefault: Off."),
+dkT(""),
+dkT("resolution=<resolution>"),
+dkT("\tResolution, either \"1:1\" (use a 1 point x 1 point square for"),
+dkT("\teach source pixel), \"chunk\" (use resolution data from image) or an"),
+dkT("\tinteger value for dpi."),
+dkT("\tDefault: 1:1 for objects, chunk for images,"),
+dkT("\tfit to paper size for documents."),
+dkT(""),
+dkT("paper=<paper>"),
+dkT("\tPaper size for documents. The paper size must be configured"),
+dkT("\tin a dk3paper.conf file. Only one from \"resolution\" or \"paper\" can be"),
+dkT("\tused."),
+dkT(""),
+dkT("make[=<boolean>]"),
+dkT("\tMake mode when processing directories."),
+dkT("\tDefault: Off."),
+dkT(""),
+dkT("bpc[=<boolean>]"),
+dkT("\tReduce the number of bits per component. Default: On."),
+dkT(""),
+dkT("EXIT STATUS"),
+dkT(""),
+dkT("0 on success, all other exit status codes indicate an error."),
+dkT(""),
+dkT("PREFERENCES"),
+dkT(""),
+dkT("/print/ps/level"),
+dkT("\tDefault PS level, 2 or 3."),
+dkT(""),
+dkT("EXAMPLES"),
+dkT(""),
+dkT("bmpp -lps.document,level=2,paper=A4,duplex,bpc myfax.tif"),
+dkT("\tconverts a fax TIFF file \"myfax.tif\" to \"myfax.ps\" for a PS 2 printer."),
+dkT(""),
+dkT("bmpp -l pdf.document,paper=A4,duplex fax.tif"),
+dkT("\tcreates a PDF file fax.pdf."),
+dkT(""),
+dkT("bmpp -l ps.object screenshot.png"),
+dkT("\tcreates a PS object file screenshot.ps for use with latex/dvips."),
+dkT(""),
+dkT("bmpp -l pdf.object screenshot.png"),
+dkT("\tcreates a PDF object file screenshot.pdf for use with pdflatex."),
+dkT(""),
+dkT("bmpp -l ps.image file.png"),
+dkT("\tcreates a PS image file.ps."),
+dkT(""),
+dkT("bmpp -l pdf.image file.png"),
+dkT("\tcreates a PDF image file.pdf."),
+dkT(""),
+dkT("FILES"),
+dkT(""),
+dkT("dk3paper.conf"),
+dkT("\tIf paper=... the named paper size must be configured in a"),
+dkT("\tdk3paper.conf file."),
+dkT(""),
+dkT("RESTRICTIONS"),
+dkT(""),
+dkT("The program uses the TIFFReadRGBAImage() function from the libtiff library to"),
+dkT("read TIFF images. The input file must meet the following conditions:"),
+dkT("- The file must be compliant to the \"TIFF baseline v6.0 standard\"."),
+dkT("- The number of bits of component must be 8 or less."),
+dkT("- The frames must not be too large, the system must be able to allocate the"),
+dkT(" 4*w*h bytes needed for image date in one piece."),
+dkT(""),
+dkT("TIFF refers to a group of different compression and encoding mechanisms."),
+dkT("A TIFF file is a sequence of data chunks, each data chunk contains a tag"),
+dkT("(chunk type identifier). A lot of tags is defined in standards, i.e. the"),
+dkT("\"TIFF baseline v6.0 standard\". Some software vendors add vendor-specific"),
+dkT("or non-standard tags when writing TIFF files."),
+dkT("So when processing TIFF files in bmpp, you should not be surprised to see"),
+dkT("warnings or error messages about unknown TIFF tags."),
+dkT("Neither bmpp nor the tifflib library are to blame for this, it's the"),
+dkT("responsibility of the people adding the non-standard tags."),
+dkT("Sometimes bmpp can read the image despite of the warnings/errors."),
+dkT(""),
+dkT("If you create bitmaps you want to process with bmpp, you should create PNG"),
+dkT("images instead of TIFF images if you have the choice."),
+dkT(""),
+dkT("AUTHOR"),
+dkT(""),
+dkT("Dirk Krause"),
+dkT(""),
+dkT("HISTORY"),
+dkT(""),
+dkT("The bmpp program replaces the bmeps program found in previous versions of"),
+dkT("dktools."),
+dkT(""),
+dkT("COPYRIGHT AND LICENSE"),
+dkT(""),
+dkT("Run"),
+dkT(" bmpp --license-terms"),
+dkT("to see the license conditions."),
+dkT(""),
+dkT("SEE ALSO"),
+dkT(""),
+dkT("http://dktools.sourceforge.net/bmpp.html"),
+dkT("\tThe DK tools and libraries homepage contains more information about"),
+dkT("\tbmpp and other programs."),
+dkT(""),
+dkT("http://gxhints.sourceforge.net"),
+dkT("\tThe Graphics Conversion Hints page recommends programs and shows"),
+dkT("\tprocedures for conversions between recent vector graphics formats."),
+dkT(""),
+dkT("http://netpbm.sourceforge.net (especially pnmtops)"),
+dkT("\tNetPBM is a toolkit for graphics images, including conversion of"),
+dkT("\timages between a variety of different formats."),
+dkT(""),
+NULL
+
+
+#line 252 "bmeps3.ctr"
+};
+
+
+
+/** Strings used to show version number.
+*/
+static dkChar const * const dk3bm_version_strings[] = {
+dkT("bmpp "),
+DKT_VERSION_DK
+};
+
+
+/** Options used by bmeps.
+*/
+static dk3_option_t const bmeps3_options[] = {
+ { dkT('l'), dkT("language"), 1 },
+ { dkT('m'), dkT("make"), 0 },
+ { dkT('s'), dkT("stdout"), 0 },
+ { dkT('t'), dkT("type"), 1 },
+ { dkT('h'), dkT("help"), 0 },
+ { dkT('v'), dkT("version"), 0 },
+ { dkT('L'), dkT("license-terms"), 0 },
+ { dkT('\0'),dkT("license"), 0 }
+};
+
+/** Number of options in @a bmeps3_options.
+*/
+static size_t const bmeps3_szoptions =
+sizeof(bmeps3_options)/sizeof(dk3_option_t);
+
+
+
+/** Names of supported input types.
+*/
+static dkChar const * const bmeps3_image_type_names[] = {
+/* 0 */
+dkT("png"),
+
+/* 1 */
+dkT("jpg"),
+
+/* 2 */
+dkT("jpeg"),
+
+/* 3 */
+dkT("tif"),
+
+/* 4 */
+dkT("tiff"),
+
+NULL
+
+
+#line 294 "bmeps3.ctr"
+};
+
+
+
+/** Suffixes for output files.
+*/
+static dkChar const * const bmeps3_output_suffixes[] = {
+dkT(".ps"),
+dkT(".eps"),
+dkT(".pdf"),
+dkT(".bb")
+};
+
+
+
+/** Strings, not localized.
+*/
+static dkChar const * const bmeps3_kw[] = {
+/* 0 */
+dkT("dktools"),
+
+/* 1 */
+dkT("bmeps3.str"),
+
+/* 2 */
+dkT("option"),
+
+NULL
+
+
+#line 326 "bmeps3.ctr"
+};
+
+
+
+/** Strings, replaced by localized version.
+*/
+static dkChar const * const bmeps3_message_texts[] = {
+/* 0 */
+dkT(""),
+
+NULL
+
+
+#line 336 "bmeps3.ctr"
+};
+
+
+
+/** License overview text.
+*/
+static dkChar const * const bmeps3_overview_license[] = {
+dkT(""),
+dkT("Overview"),
+dkT("========"),
+dkT("This software uses code from the following projects either directly"),
+dkT("or as a library:"),
+dkT(""),
+dkT("dktools\t\tDirk Krause's tools and libraries."),
+dkT("\t\tSee http://dktools.sourceforge.net for information."),
+#if DK3_HAVE_PNG_H
+dkT(""),
+dkT("libpng\t\tPNG reference library."),
+dkT("\t\tSee http://www.libpng.org/pub/png/libpng.html for information."),
+#endif
+#if DK3_HAVE_JPEGLIB_H
+dkT(""),
+dkT("jpeg\t\tIndependent JPEG groups free JPEG library."),
+dkT("\t\tSee http://www.ijg.org/ for information."),
+#endif
+#if DK3_HAVE_TIFF_H
+dkT(""),
+dkT("libtiff\t\tTIFF library."),
+dkT("\t\tSee http://www.remotesensing.org/libtiff/ for information."),
+#endif
+#if DK3_HAVE_ZLIB_H
+dkT(""),
+dkT("zlib\t\tCompression library."),
+dkT("\t\tSee http://www.zlib.net/ for information."),
+#endif
+dkT(""),
+dkT("Your use of the bmpp/wxmbpp program must be in compliance with the"),
+dkT("license conditions for the dktools project and the license conditions"),
+dkT("for all the libraries used by bmpp."),
+dkT(""),
+NULL
+};
+
+
+
+/** License terms for the dktools project itself.
+*/
+static dkChar const * const bmpp_dk_license[] = {
+dkT("License for the dktools project"),
+dkT("==============================="),
+dkT("Copyright (c) 2011-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms,"),
+dkT("with or without modification, are permitted provided"),
+dkT("that the following conditions are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above"),
+dkT(" copyright notice, this list of conditions and the"),
+dkT(" following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above "),
+dkT(" copyright notice, this list of conditions and the following"),
+dkT(" disclaimer in the documentation and/or other materials"),
+dkT(" provided with the distribution."),
+dkT("* Neither the name of the copyright holder(s) nor the names of"),
+dkT(" contributors may be used to endorse or promote"),
+dkT(" products derived from this software without specific"),
+dkT(" prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND"),
+dkT("CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,"),
+dkT("INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF"),
+dkT("MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE"),
+dkT("DISCLAIMED."),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE"),
+dkT("LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,"),
+dkT("EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT"),
+dkT("LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;"),
+dkT("LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)"),
+dkT("HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN"),
+dkT("CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE"),
+dkT("OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS"),
+dkT("SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH"),
+dkT("DAMAGE."),
+dkT(""),
+NULL
+
+
+#line 423 "bmeps3.ctr"
+};
+
+#if DK3_HAVE_PNG_H
+static dkChar const * const bmpp_png_license[] = {
+dkT(""),
+dkT("libpng license"),
+dkT("=============="),
+dkT(""),
+dkT("This copy of the libpng notices is provided for your convenience. In case of"),
+dkT("any discrepancy between this copy and the notices in the file png.h that is"),
+dkT("included in the libpng distribution, the latter shall prevail."),
+dkT(""),
+dkT("COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:"),
+dkT(""),
+dkT("If you modify libpng you may insert additional notices immediately following"),
+dkT("this sentence."),
+dkT(""),
+dkT("This code is released under the libpng license."),
+dkT(""),
+dkT("libpng versions 1.2.6, August 15, 2004, through 1.2.46, July 9, 2011, are"),
+dkT("Copyright (c) 2004, 2006-2009 Glenn Randers-Pehrson, and are"),
+dkT("distributed according to the same disclaimer and license as libpng-1.2.5"),
+dkT("with the following individual added to the list of Contributing Authors"),
+dkT(""),
+dkT(" Cosmin Truta"),
+dkT(""),
+dkT("libpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002, are"),
+dkT("Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are"),
+dkT("distributed according to the same disclaimer and license as libpng-1.0.6"),
+dkT("with the following individuals added to the list of Contributing Authors"),
+dkT(""),
+dkT(" Simon-Pierre Cadieux"),
+dkT(" Eric S. Raymond"),
+dkT(" Gilles Vollant"),
+dkT(""),
+dkT("and with the following additions to the disclaimer:"),
+dkT(""),
+dkT(" There is no warranty against interference with your enjoyment of the"),
+dkT(" library or against infringement. There is no warranty that our"),
+dkT(" efforts or the library will fulfill any of your particular purposes"),
+dkT(" or needs. This library is provided with all faults, and the entire"),
+dkT(" risk of satisfactory quality, performance, accuracy, and effort is with"),
+dkT(" the user."),
+dkT(""),
+dkT("libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are"),
+dkT("Copyright (c) 1998, 1999 Glenn Randers-Pehrson, and are"),
+dkT("distributed according to the same disclaimer and license as libpng-0.96,"),
+dkT("with the following individuals added to the list of Contributing Authors:"),
+dkT(""),
+dkT(" Tom Lane"),
+dkT(" Glenn Randers-Pehrson"),
+dkT(" Willem van Schaik"),
+dkT(""),
+dkT("libpng versions 0.89, June 1996, through 0.96, May 1997, are"),
+dkT("Copyright (c) 1996, 1997 Andreas Dilger"),
+dkT("Distributed according to the same disclaimer and license as libpng-0.88,"),
+dkT("with the following individuals added to the list of Contributing Authors:"),
+dkT(""),
+dkT(" John Bowler"),
+dkT(" Kevin Bracey"),
+dkT(" Sam Bushell"),
+dkT(" Magnus Holmgren"),
+dkT(" Greg Roelofs"),
+dkT(" Tom Tanner"),
+dkT(""),
+dkT("libpng versions 0.5, May 1995, through 0.88, January 1996, are"),
+dkT("Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc."),
+dkT(""),
+dkT("For the purposes of this copyright and license, \"Contributing Authors\""),
+dkT("is defined as the following set of individuals:"),
+dkT(""),
+dkT(" Andreas Dilger"),
+dkT(" Dave Martindale"),
+dkT(" Guy Eric Schalnat"),
+dkT(" Paul Schmidt"),
+dkT(" Tim Wegner"),
+dkT(""),
+dkT("The PNG Reference Library is supplied \"AS IS\". The Contributing Authors"),
+dkT("and Group 42, Inc. disclaim all warranties, expressed or implied,"),
+dkT("including, without limitation, the warranties of merchantability and of"),
+dkT("fitness for any purpose. The Contributing Authors and Group 42, Inc."),
+dkT("assume no liability for direct, indirect, incidental, special, exemplary,"),
+dkT("or consequential damages, which may result from the use of the PNG"),
+dkT("Reference Library, even if advised of the possibility of such damage."),
+dkT(""),
+dkT("Permission is hereby granted to use, copy, modify, and distribute this"),
+dkT("source code, or portions hereof, for any purpose, without fee, subject"),
+dkT("to the following restrictions:"),
+dkT(""),
+dkT("1. The origin of this source code must not be misrepresented."),
+dkT(""),
+dkT("2. Altered versions must be plainly marked as such and must not"),
+dkT(" be misrepresented as being the original source."),
+dkT(""),
+dkT("3. This Copyright notice may not be removed or altered from any"),
+dkT(" source or altered source distribution."),
+dkT(""),
+dkT("The Contributing Authors and Group 42, Inc. specifically permit, without"),
+dkT("fee, and encourage the use of this source code as a component to"),
+dkT("supporting the PNG file format in commercial products. If you use this"),
+dkT("source code in a product, acknowledgment is not required but would be"),
+dkT("appreciated."),
+dkT(""),
+dkT(""),
+dkT("A \"png_get_copyright\" function is available, for convenient use in \"about\""),
+dkT("boxes and the like:"),
+dkT(""),
+dkT(" printf(\"%s\",png_get_copyright(NULL));"),
+dkT(""),
+dkT("Also, the PNG logo (in PNG format, of course) is supplied in the"),
+dkT("files \"pngbar.png\" and \"pngbar.jpg (88x31) and \"pngnow.png\" (98x31)."),
+dkT(""),
+dkT("Libpng is OSI Certified Open Source Software. OSI Certified Open Source is a"),
+dkT("certification mark of the Open Source Initiative."),
+dkT(""),
+dkT("Glenn Randers-Pehrson"),
+dkT("glennrp at users.sourceforge.net"),
+dkT("July 9, 2011"),
+NULL
+
+
+#line 543 "bmeps3.ctr"
+};
+#endif
+#if DK3_HAVE_JPEGLIB_H
+static dkChar const * const bmpp_jpeg_license[] = {
+dkT(""),
+dkT("jpeglib license"),
+dkT("==============="),
+dkT(""),
+dkT("In plain English:"),
+dkT(""),
+dkT("1. We don't promise that this software works. (But if you find any bugs,"),
+dkT(" please let us know!)"),
+dkT("2. You can use this software for whatever you want. You don't have to pay us."),
+dkT("3. You may not pretend that you wrote this software. If you use it in a"),
+dkT(" program, you must acknowledge somewhere in your documentation that"),
+dkT(" you've used the IJG code."),
+dkT(""),
+dkT("In legalese:"),
+dkT(""),
+dkT("The authors make NO WARRANTY or representation, either express or implied,"),
+dkT("with respect to this software, its quality, accuracy, merchantability, or"),
+dkT("fitness for a particular purpose. This software is provided \"AS IS\", and you,"),
+dkT("its user, assume the entire risk as to its quality and accuracy."),
+dkT(""),
+dkT("This software is copyright (C) 1991-1998, Thomas G. Lane."),
+dkT("All Rights Reserved except as specified below."),
+dkT(""),
+dkT("Permission is hereby granted to use, copy, modify, and distribute this"),
+dkT("software (or portions thereof) for any purpose, without fee, subject to these"),
+dkT("conditions:"),
+dkT("(1) If any part of the source code for this software is distributed, then this"),
+dkT("README file must be included, with this copyright and no-warranty notice"),
+dkT("unaltered; and any additions, deletions, or changes to the original files"),
+dkT("must be clearly indicated in accompanying documentation."),
+dkT("(2) If only executable code is distributed, then the accompanying"),
+dkT("documentation must state that \"this software is based in part on the work of"),
+dkT("the Independent JPEG Group\"."),
+dkT("(3) Permission for use of this software is granted only if the user accepts"),
+dkT("full responsibility for any undesirable consequences; the authors accept"),
+dkT("NO LIABILITY for damages of any kind."),
+dkT(""),
+dkT("These conditions apply to any software derived from or based on the IJG code,"),
+dkT("not just to the unmodified library. If you use our work, you ought to"),
+dkT("acknowledge us."),
+dkT(""),
+dkT("Permission is NOT granted for the use of any IJG author's name or company name"),
+dkT("in advertising or publicity relating to this software or products derived from"),
+dkT("it. This software may be referred to only as \"the Independent JPEG Group's"),
+dkT("software\"."),
+dkT(""),
+dkT("We specifically permit and encourage the use of this software as the basis of"),
+dkT("commercial products, provided that all warranty or liability claims are"),
+dkT("assumed by the product vendor."),
+dkT(""),
+dkT(""),
+dkT("ansi2knr.c is included in this distribution by permission of L. Peter Deutsch,"),
+dkT("sole proprietor of its copyright holder, Aladdin Enterprises of Menlo Park, CA."),
+dkT("ansi2knr.c is NOT covered by the above copyright and conditions, but instead"),
+dkT("by the usual distribution terms of the Free Software Foundation; principally,"),
+dkT("that you must include source code if you redistribute it. (See the file"),
+dkT("ansi2knr.c for full details.) However, since ansi2knr.c is not needed as part"),
+dkT("of any program generated from the IJG code, this does not limit you more than"),
+dkT("the foregoing paragraphs do."),
+dkT(""),
+dkT("The Unix configuration script \"configure\" was produced with GNU Autoconf."),
+dkT("It is copyright by the Free Software Foundation but is freely distributable."),
+dkT("The same holds for its supporting scripts (config.guess, config.sub,"),
+dkT("ltconfig, ltmain.sh). Another support script, install-sh, is copyright"),
+dkT("by M.I.T. but is also freely distributable."),
+dkT(""),
+dkT("It appears that the arithmetic coding option of the JPEG spec is covered by"),
+dkT("patents owned by IBM, AT&T, and Mitsubishi. Hence arithmetic coding cannot"),
+dkT("legally be used without obtaining one or more licenses. For this reason,"),
+dkT("support for arithmetic coding has been removed from the free JPEG software."),
+dkT("(Since arithmetic coding provides only a marginal gain over the unpatented"),
+dkT("Huffman mode, it is unlikely that very many implementations will support it.)"),
+dkT("So far as we are aware, there are no patent restrictions on the remaining"),
+dkT("code."),
+dkT(""),
+dkT("The IJG distribution formerly included code to read and write GIF files."),
+dkT("To avoid entanglement with the Unisys LZW patent, GIF reading support has"),
+dkT("been removed altogether, and the GIF writer has been simplified to produce"),
+dkT("\"uncompressed GIFs\". This technique does not use the LZW algorithm; the"),
+dkT("resulting GIF files are larger than usual, but are readable by all standard"),
+dkT("GIF decoders."),
+dkT(""),
+dkT("We are required to state that"),
+dkT(" \"The Graphics Interchange Format(c) is the Copyright property of"),
+dkT(" CompuServe Incorporated. GIF(sm) is a Service Mark property of"),
+dkT(" CompuServe Incorporated.\""),
+dkT(""),
+NULL
+
+
+#line 636 "bmeps3.ctr"
+};
+#endif
+#if DK3_HAVE_TIFF_H
+static dkChar const * const bmpp_tiff_license[] = {
+dkT(""),
+dkT("libtiff license"),
+dkT("==============="),
+dkT(""),
+dkT("Copyright (c) 1988-1997 Sam Leffler"),
+dkT("Copyright (c) 1991-1997 Silicon Graphics, Inc."),
+dkT(""),
+dkT("Permission to use, copy, modify, distribute, and sell this software and "),
+dkT("its documentation for any purpose is hereby granted without fee, provided"),
+dkT("that (i) the above copyright notices and this permission notice appear in"),
+dkT("all copies of the software and related documentation, and (ii) the names of"),
+dkT("Sam Leffler and Silicon Graphics may not be used in any advertising or"),
+dkT("publicity relating to the software without the specific, prior written"),
+dkT("permission of Sam Leffler and Silicon Graphics."),
+dkT(""),
+dkT("THE SOFTWARE IS PROVIDED \"AS-IS\" AND WITHOUT WARRANTY OF ANY KIND, "),
+dkT("EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY "),
+dkT("WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. "),
+dkT(""),
+dkT("IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR"),
+dkT("ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,"),
+dkT("OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,"),
+dkT("WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF "),
+dkT("LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE "),
+dkT("OF THIS SOFTWARE."),
+dkT(""),
+NULL
+
+
+#line 668 "bmeps3.ctr"
+};
+#endif
+#if DK3_HAVE_ZLIB_H
+static dkChar const * const bmpp_zlib_license[] = {
+dkT(""),
+dkT("zlib license"),
+dkT("============"),
+dkT(""),
+dkT(" (C) 1995-2004 Jean-loup Gailly and Mark Adler"),
+dkT(""),
+dkT(" This software is provided 'as-is', without any express or implied"),
+dkT(" warranty. In no event will the authors be held liable for any damages"),
+dkT(" arising from the use of this software."),
+dkT(""),
+dkT(" Permission is granted to anyone to use this software for any purpose,"),
+dkT(" including commercial applications, and to alter it and redistribute it"),
+dkT(" freely, subject to the following restrictions:"),
+dkT(""),
+dkT(" 1. The origin of this software must not be misrepresented; you must not"),
+dkT(" claim that you wrote the original software. If you use this software"),
+dkT(" in a product, an acknowledgment in the product documentation would be"),
+dkT(" appreciated but is not required."),
+dkT(" 2. Altered source versions must be plainly marked as such, and must not be"),
+dkT(" misrepresented as being the original software."),
+dkT(" 3. This notice may not be removed or altered from any source distribution."),
+dkT(""),
+dkT(" Jean-loup Gailly Mark Adler"),
+dkT(" jloup@gzip.org madler@alumni.caltech.edu"),
+dkT(""),
+dkT("If you use the zlib library in a product, we would appreciate *not*"),
+dkT("receiving lengthy legal documents to sign. The sources are provided"),
+dkT("for free but without warranty of any kind. The library has been"),
+dkT("entirely written by Jean-loup Gailly and Mark Adler; it does not"),
+dkT("include third-party code."),
+dkT(""),
+dkT("If you redistribute modified sources, we would appreciate that you include"),
+dkT("in the file ChangeLog history information documenting your changes. Please"),
+dkT("read the FAQ for more information on the distribution of modified source"),
+dkT("versions."),
+dkT(""),
+NULL
+
+
+#line 710 "bmeps3.ctr"
+};
+#endif
+
+
+
+/** Show one section of text.
+ @param ltext Text to show.
+*/
+static
+void
+bmeps3_show_one_license(dkChar const * const *ltext)
+{
+ dkChar const * const * sptr;
+ sptr = ltext;
+ while(*sptr) {
+ dk3sf_fputs(*(sptr++), stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+}
+
+
+
+/** Show license for the program itself and for the used libraries.
+*/
+static
+void
+bmeps3_show_license(void)
+{
+ bmeps3_show_one_license(bmeps3_overview_license);
+ bmeps3_show_one_license(bmpp_dk_license);
+#if DK3_HAVE_PNG_H
+ bmeps3_show_one_license(bmpp_png_license);
+#endif
+#if DK3_HAVE_JPEGLIB_H
+ bmeps3_show_one_license(bmpp_jpeg_license);
+#endif
+#if DK3_HAVE_TIFF_H
+ bmeps3_show_one_license(bmpp_tiff_license);
+#endif
+#if DK3_HAVE_ZLIB_H
+ bmeps3_show_one_license(bmpp_zlib_license);
+#endif
+}
+
+
+
+/** Process a complete directory.
+ @param bmeo Conversion options.
+ @param fnb File name for directory.
+ @param app Application structure for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+bmeps3_process_directory(
+ dk3_bm_eps_options_t *bmeo,
+ dkChar const *fnb,
+ dk3_app_t *app
+)
+{
+ dkChar fni[DK3_MAX_PATH]; /* Input file name. */
+ dkChar fno[DK3_MAX_PATH]; /* output file name. */
+ dkChar const * const *msg; /* Localized message texts. */
+ dk3_dir_t *dir; /* Directory. */
+ dkChar const *en; /* Full file name. */
+ dkChar const *sn; /* Short file name. */
+ dkChar const *nsptr; /* Suffix output file. */
+ dkChar const *oldsourcefile; /* Old source file name. */
+ dkChar *sptr; /* Suffix input file. */
+ dk3_stat_t const *es; /* Stat info input file. */
+ dk3_stat_t stb; /* Stat buffer output file. */
+ int mustrun; /* Flag: Must convert file. */
+ int sit; /* Image type. */
+ int back = 0;
+
+
+#line 785 "bmeps3.ctr"
+ msg = dk3app_messages(
+ app,
+ dk3bmep_str_get_string_table_name(),
+ (dkChar const **)dk3bmep_str_get_message_texts()
+ );
+ if(!(msg)) {
+ msg = dk3bmep_str_get_message_texts();
+ }
+ oldsourcefile = dk3app_get_source_file(app);
+ dir = dk3dir_open_app(fnb, app);
+ if(dir) {
+
+#line 796 "bmeps3.ctr"
+ back = 1;
+
+#line 797 "bmeps3.ctr"
+ while(dk3dir_get_next_file(dir)) {
+
+#line 798 "bmeps3.ctr"
+ en = dk3dir_get_fullname(dir);
+
+#line 799 "bmeps3.ctr"
+ sn = dk3dir_get_shortname(dir);
+ es = dk3dir_get_stat(dir);
+ if((en) && (es)) {
+
+#line 802 "bmeps3.ctr"
+ if(dk3bif_type_supported(sit = dk3bif_check_file_name(en))) {
+
+#line 803 "bmeps3.ctr"
+ if(((es->ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_REGULAR) {
+
+#line 804 "bmeps3.ctr"
+ mustrun = 1;
+ if(bmeo->make) {
+ if(dk3str_len(en) < DK3_SIZEOF(fni,dkChar)) {
+ dk3str_cpy_not_overlapped(fni, en);
+ dk3str_cpy_not_overlapped(fno, en);
+ sptr = dk3str_get_suffix(fno);
+ if(sptr) {
+ *sptr = dkT('\0');
+
+#line 812 "bmeps3.ctr"
+ if((bmeo->dr >= 0) && (bmeo->dr <= 3)) {
+ nsptr = bmeps3_output_suffixes[bmeo->dr];
+ if((dk3str_len(fno) + dk3str_len(nsptr))
+ < DK3_SIZEOF(fno,dkChar)
+ )
+ {
+ dk3str_cpy_not_overlapped(sptr, nsptr);
+
+#line 819 "bmeps3.ctr"
+ if(dk3sf_stat_app(&stb, fno, NULL)) {
+ if(stb.mod > es->mod) {
+ mustrun = 0;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if(mustrun) {
+
+#line 830 "bmeps3.ctr"
+ dk3app_log_3(app, DK3_LL_PROGRESS, msg, 41, 42, ((sn) ? sn : en));
+ dk3app_set_source_file(app, ((sn) ? sn : en));
+ if(!dk3bm_process_file_name(bmeo,en,sit,0,1000,NULL)) {
+ back = 0;
+ }
+ dk3app_set_source_file(app, oldsourcefile);
+ dk3app_log_3(app, DK3_LL_PROGRESS, msg, 43, 44, ((sn) ? sn : en));
+ } else {
+
+#line 838 "bmeps3.ctr"
+ dk3app_log_3(app, DK3_LL_PROGRESS, msg, 45, 46, ((sn) ? sn : en));
+ }
+ } else {
+
+#line 841 "bmeps3.ctr"
+ }
+ } else {
+
+#line 843 "bmeps3.ctr"
+ }
+ } else {
+
+#line 845 "bmeps3.ctr"
+ back = 0;
+ /* BUG: Should be handled by dk3dir. */
+ }
+ }
+ dk3dir_close(dir);
+ } else {
+
+#line 851 "bmeps3.ctr"
+ /* ERROR: Failed to open directory! */
+ }
+ dk3app_set_source_file(app, oldsourcefile);
+
+
+#line 855 "bmeps3.ctr"
+ return back;
+}
+
+
+
+
+/** Copy contents of one file to another.
+ @param fipoout Destination file.
+ @param fipoin Source file.
+ @param app Application structure for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+bmeps3_copy_files(FILE *fipoout, FILE *fipoin, dk3_app_t *app)
+{
+ char bu[4096]; /* Buffer for data. */
+ size_t rb; /* Number of bytes read. */
+ int cc; /* Flag: Can continue. */
+ int back = 1;
+ do {
+ cc = 0;
+ rb = dk3sf_fread_app(bu, 1, sizeof(bu), fipoin, app);
+ if(rb > 0) {
+ cc = 1;
+ if(!dk3sf_fwrite_app(bu, 1, rb, fipoout, app)) {
+ back = 0; cc = 0;
+ }
+ }
+ } while(cc);
+ return back;
+}
+
+
+
+
+/** Run with application structure and localized messages.
+ @param app Application structure.
+ @param msg Localized messages.
+ @param optset Option set.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+bmeps3_run_with_optset(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dk3_option_set_t *optset
+)
+{
+ dkChar fnb[DK3_MAX_PATH]; /* File name. */
+ dk3_bm_eps_options_t bmeo; /* Conversion option set. */
+ dk3_stat_t stb; /* Stat buffer. */
+ dk3_dir_t *fne; /* File name expander. */
+ dk3_stat_t const *es; /* Entry (file) stat information. */
+ FILE *fipo; /* Temporary file. */
+ dkChar const *larg; /* Option argument. */
+ dkChar const *fo; /* Further opt currently processed. */
+ dkChar const *en; /* Entry (file) name. */
+ int fonum; /* Number of further options. */
+ int i; /* Traverse options and arguments. */
+ int sit; /* Standard input image type. */
+ int numargs; /* Number of command line args. */
+ int found; /* Flag: At least one file found. */
+#if DK3_ON_WINDOWS
+ int oldmode; /* Stdin mode before start. */
+#endif
+ int back = 0;
+
+
+#line 924 "bmeps3.ctr"
+ sit = DK3_BIF_IMAGE_TYPE_UNKNOWN;
+ dk3bmeo_init(&bmeo);
+ bmeo.app = app;
+
+#line 927 "bmeps3.ctr"
+ back = 1;
+
+#line 928 "bmeps3.ctr"
+ if(dk3opt_is_set(optset, dkT('l'))) {
+ larg = dk3opt_get_short_arg(optset, dkT('l'));
+ if(larg) {
+ if(!dk3bmeo_set_language(&bmeo, larg, app)) {
+ back = 0;
+ /* ERROR during option processing! */
+ }
+ bmeo.app = app;
+ } else {
+ /* BUG: Option -l set, but no argument. Should be handled by dk3opt. */
+ }
+ }
+
+#line 940 "bmeps3.ctr"
+ if(dk3opt_is_set(optset, dkT('m'))) {
+ bmeo.make = 1;
+ }
+ if(dk3opt_is_set(optset, dkT('s'))) {
+ bmeo.to_stdout = 1;
+ }
+ if(dk3opt_is_set(optset, dkT('t'))) {
+ larg = dk3opt_get_short_arg(optset, dkT('t'));
+ if(larg) {
+ switch(dk3str_array_index(bmeps3_image_type_names, larg, 0)) {
+ case 0: {
+ sit = DK3_BIF_IMAGE_TYPE_PNG;
+ } break;
+ case 1: case 2: {
+ sit = DK3_BIF_IMAGE_TYPE_JPEG;
+ } break;
+ case 3: case 4: {
+ sit = DK3_BIF_IMAGE_TYPE_TIFF;
+ } break;
+ default: {
+ /* ERROR: Unknown file type ... */
+ dk3app_log_3(app, DK3_LL_ERROR, msg, 63, 64, larg);
+ back = 0;
+ } break;
+ }
+ } else {
+ /* BUG: Option -t set, but no argument. Should be handled by dk3opt. */
+ }
+ }
+ if(back) {
+ if((fonum = dk3opt_get_num_fo(optset)) > 0) {
+ for(i = 0; i < fonum; i++) {
+ fo = dk3opt_get_fo(optset, i);
+ if(fo) {
+ if(!dk3bmeo_apply_option(&bmeo, fo, msg)) {
+ back = 0;
+ /* ERROR: Error while adding option! */
+ }
+ } else {
+ /* BUG: Option not available. Should be handled by dk3opt. */
+ }
+ }
+ }
+ }
+
+#line 984 "bmeps3.ctr"
+ if(back) {
+ if(dk3opt_is_set(optset, dkT('h'))
+ || dk3opt_is_set(optset, dkT('v'))
+ || dk3opt_is_set(optset, dkT('L'))
+ )
+ {
+ if(dk3opt_is_set(optset, dkT('v'))) {
+ /* Print version number */
+ dk3sf_initialize_stdout();
+ dk3sf_fputs(dk3bm_version_strings[0], stdout);
+ dk3sf_fputs(dk3bm_version_strings[1], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ if(dk3opt_is_set(optset, dkT('L'))) {
+ dk3sf_initialize_stdout();
+ bmeps3_show_license();
+ } else {
+ if(dk3opt_is_set_long(optset, dkT("license"))) {
+ dk3sf_initialize_stdout();
+ bmeps3_show_license();
+ }
+ }
+ if(dk3opt_is_set(optset, dkT('h'))) {
+ dk3sf_initialize_stdout();
+ dk3app_help(app, dkT("bmpp.txt"), bmeps3_default_help_text);
+ }
+ } else {
+ dk3bmeo_check(&bmeo, 0, app, NULL);
+
+#line 1012 "bmeps3.ctr"
+ numargs = dk3opt_get_num_args(optset);
+ if(numargs > 0) {
+
+#line 1014 "bmeps3.ctr"
+ for(i = 0; i < numargs; i++) {
+ larg = dk3opt_get_arg(optset, i);
+ if(larg) {
+ if(dk3str_len(larg) < DK3_SIZEOF(fnb,dkChar)) {
+ dk3str_cpy_not_overlapped(fnb, larg);
+ dk3str_correct_filename(fnb);
+ if(dk3sf_must_expand(fnb)) {
+
+#line 1021 "bmeps3.ctr"
+ found = 0;
+ fne = dk3dir_fne_open_app(fnb, app);
+ if(fne) {
+ while(dk3dir_get_next_file(fne)) {
+ en = dk3dir_get_fullname(fne);
+ es = dk3dir_get_stat(fne);
+ if((en) && (es)) {
+ if(((es->ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_REGULAR) {
+ sit = DK3_BIF_IMAGE_TYPE_UNKNOWN;
+ if(!dk3bm_process_file_name(&bmeo,en,sit,0,1000,NULL))
+ {
+ back = 0;
+ }
+ } else {
+ /* ERROR: Not a regular file! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 255, 256, fnb);
+ }
+ } else {
+ /* BUG: Should be handled by dk3dir. */
+ back = 0;
+ }
+ }
+ dk3dir_close(fne);
+ if(!(found)) {
+ back = 0;
+ /* ERROR: No such file! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 215, 216, fnb);
+ }
+ } else {
+ /* ERROR: Failed to expand file name! */
+ back = 0;
+ }
+ } else {
+
+#line 1054 "bmeps3.ctr"
+ if(dk3sf_stat_app(&stb, fnb, app)) {
+ switch((stb.ft) & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_DIRECTORY: {
+ if(!bmeps3_process_directory(&bmeo, fnb, app)) {
+ back = 0;
+ }
+ } break;
+ case DK3_FT_REGULAR: {
+ if(!dk3bm_process_file_name(&bmeo,fnb,sit,0,1000,NULL)) {
+ back = 0;
+ }
+ } break;
+ default: {
+ /* ERROR: Illegal file type! */
+ back = 0;
+ dk3app_log_3(app, DK3_LL_ERROR, msg, 65, 66, fnb);
+ } break;
+ }
+ } else {
+ /* ERROR: No information about file! */
+ back = 0;
+ }
+ }
+ } else {
+ /* ERROR: File name too long! */
+ back = 0;
+ dk3app_log_i3(app, DK3_LL_ERROR, 65, 66, larg);
+ }
+ } else {
+
+#line 1083 "bmeps3.ctr"
+ /* BUG: Option not available, should be handled by dk3opt. */
+ }
+ }
+ } else {
+
+#line 1087 "bmeps3.ctr"
+ if(sit != DK3_BIF_IMAGE_TYPE_UNKNOWN) {
+ if(dk3app_get_temp_file_name(app, fnb, DK3_SIZEOF(fnb,dkChar))) {
+ fipo = dk3sf_fopen_app(fnb, dk3app_not_localized(53), app);
+ if(fipo) {
+#if DK3_ON_WINDOWS
+ oldmode = _setmode(_fileno(stdin), _O_BINARY);
+#endif
+ i = bmeps3_copy_files(fipo, stdin, app);
+#if DK3_ON_WINDOWS
+ _setmode(_fileno(stdin), oldmode);
+#endif
+#if VERSION_BEFORE_2012_04_19
+ fclose(fipo);
+#else
+ if(!dk3sf_fclose_fn_app(fipo, fnb, app)) {
+ i = 0;
+ }
+#endif
+ if(i) {
+ bmeo.to_stdout = 1;
+ back = dk3bm_process_file_name(&bmeo,fnb,sit,0,1000,NULL);
+ }
+ } else {
+ /* ERROR: Failed to open file for writing! */
+ back = 0;
+ }
+ } else {
+ back = 0;
+ /* ERROR: Failed to obtain temporary file name! */
+ }
+ } else {
+ /* ERROR: No file type specified for standard input! */
+ back = 0;
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 67);
+ }
+ }
+ }
+ }
+
+
+#line 1126 "bmeps3.ctr"
+ return back;
+}
+
+
+
+/** Run with application structure and localized messages.
+ @param app Application structure.
+ @param msg Localized messages.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+bmeps3_run_with_app(dk3_app_t *app, dkChar const * const *msg)
+{
+ dk3_option_set_t *optset; /* Options provided on command line. */
+ int back = 0;
+
+
+#line 1143 "bmeps3.ctr"
+ optset = dk3opt_open_from_app(
+ bmeps3_options,
+ bmeps3_szoptions,
+ dkT('o'),
+ bmeps3_kw[2],
+ app
+ );
+ if(optset) {
+
+#line 1151 "bmeps3.ctr"
+ if(0 == dk3opt_get_error_code(optset)) {
+
+#line 1152 "bmeps3.ctr"
+ back = bmeps3_run_with_optset(app, msg, optset);
+ } else {
+
+#line 1154 "bmeps3.ctr"
+ /* ERROR: Error in options */
+ }
+ dk3opt_close(optset);
+ } else {
+
+#line 1158 "bmeps3.ctr"
+ }
+
+#line 1159 "bmeps3.ctr"
+ return back;
+}
+
+
+
+/** The main() function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, any other value indicates an error.
+*/
+DK3_MAIN
+{
+ dk3_app_t *app; /* Application structure. */
+ dkChar const * const *msg; /* Localizd messages. */
+ int exval; /* Exit code. */
+
+
+
+#line 1176 "bmeps3.ctr"
+
+
+#line 1177 "bmeps3.ctr"
+ exval = 1;
+ app = dk3app_open_command(
+ argc, (dkChar const * const *)argv, bmeps3_kw[0]
+ );
+ if(app) {
+
+#line 1182 "bmeps3.ctr"
+ msg = dk3app_messages(
+ app,
+ dk3bmep_str_get_string_table_name(),
+ (dkChar const **)dk3bmep_str_get_message_texts()
+ );
+ if(msg) {
+
+#line 1188 "bmeps3.ctr"
+ if(bmeps3_run_with_app(app, msg)) {
+ exval = 0;
+ }
+ } else {
+
+#line 1192 "bmeps3.ctr"
+ /* BUG: Should not happen, as the fucntion returns the default array! */
+ }
+ dk3app_close(app);
+ } else {
+
+#line 1196 "bmeps3.ctr"
+ /* ERROR: Memory */
+ fputs("ERROR: Not enough memory (RAM/swap space)!\n", stderr);
+ fflush(stderr);
+ }
+
+
+#line 1201 "bmeps3.ctr"
+
+
+#line 1202 "bmeps3.ctr"
+ fflush(stdout);
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/bmeps3.ctr b/support/dktools/bmeps3.ctr
new file mode 100644
index 0000000000..f5ba076867
--- /dev/null
+++ b/support/dktools/bmeps3.ctr
@@ -0,0 +1,1205 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% header
+
+%% module
+
+#include "dk3all.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4vers.h"
+#include "dk3bif.h"
+#include "dk3bmeo.h"
+#include "dk3bmeps.h"
+#include "dk3bm.h"
+
+
+
+$!trace-include
+
+
+
+/** Help text shown if no help file is found.
+*/
+static dkChar const * const bmeps3_default_help_text[] = {
+$!text macro=dkT
+
+NAME
+
+ bmpp - Bitmap to PS/PDF converter
+
+SYNOPSIS
+
+ bmpp [-l<driver>[.<mode>][,<key>[=<value>]...]] [<options>] <file(s)>
+
+DESCRIPTION
+
+The program converts bitmap images from PNG, JPEG, or TIFF to PS/EPS and PDF.
+
+Drivers:
+- ps
+ PostScript file, can be used to print.
+- eps
+ Encapsulated PostScript (EPS), image for inclusion into documents.
+- pdf
+ Portable document format (PDF).
+- bb
+ Bounding box information only, no image.
+
+Output modes:
+- object
+ Object which can embedded into a text or drawing by a text processing
+ or drawing software.
+- image
+ Image for stand-alone viewing.
+- document
+ Fit the output to a given paper size for printing.
+
+OPTIONS
+
+-h
+--help
+ Show help text.
+
+-v
+--version
+ Show version number.
+
+-L
+--license-terms
+ Shows license terms.
+
+-t <type>
+ Input image type, "png", "jpeg", or "tiff", must be specified when
+ processing standard input or if the input file name suffix does
+ not indicate the type.
+
+-m
+ Make mode: Avoid unnecessary conversions if output file is up to date.
+ Only used when processing a directory.
+
+-s
+ Write to standard output, not to a file.
+
+-o <key>[=<value>]
+ Detailed conversion options.
+
+NAME=VALUE PAIRS
+
+The key=value pairs set detailed conversion options. For boolean
+settings the value can be omitted, the presence of the name sets the option
+to active.
+The following keys (and values) can be used:
+
+level=<pslevel>
+ PS level, "2" or "3". Default: 3.
+
+color[=<boolean>]
+ Color output for PS/EPS output. For PDF output color is
+ always enabled. This setting is ignored when passing DCT data from
+ JPEG files to output directly.
+ Default: On.
+
+dsc[=<boolean>]
+ DSC comments when producing PS/EPS output.
+ Default: Off, except for ps.document.
+
+draft[=<boolean>]
+ Draft mode (small placeholder image only). Default: Off.
+
+predictor=<predictor>
+ Predictor for flate compressions, "tiff", "sub", "up",
+ "average", or "paeth". Default: none.
+
+duplex[=<boolean>]
+ Duplex mode when producing documents. Default: Off.
+
+tumble[=<boolean>]
+ Tumble in addition to duplex mode. Default: Off.
+
+dct[=<boolean>]
+ Direct pass-through of DCT encoded data found in JPEG
+ files. Default: On.
+
+bg=<int>:<int>:<int>[:<boolean>]
+ Default background RGB color to be used if the input file
+ does not contain a background color chunk. The optional boolean value
+ at the end can be used to enforce this background over the background
+ chunk. RGB values are in the range 0...255.
+ Default: White, off.
+
+interpolation[=<boolean>]
+ Image interpolation. Default: On.
+
+jpeg-interpolation[=<boolean>]
+ Image interpolation if DCT data is passed through directly.
+ Default: Off.
+
+resolution=<resolution>
+ Resolution, either "1:1" (use a 1 point x 1 point square for
+ each source pixel), "chunk" (use resolution data from image) or an
+ integer value for dpi.
+ Default: 1:1 for objects, chunk for images,
+ fit to paper size for documents.
+
+paper=<paper>
+ Paper size for documents. The paper size must be configured
+ in a dk3paper.conf file. Only one from "resolution" or "paper" can be
+ used.
+
+make[=<boolean>]
+ Make mode when processing directories.
+ Default: Off.
+
+bpc[=<boolean>]
+ Reduce the number of bits per component. Default: On.
+
+EXIT STATUS
+
+0 on success, all other exit status codes indicate an error.
+
+PREFERENCES
+
+/print/ps/level
+ Default PS level, 2 or 3.
+
+EXAMPLES
+
+bmpp -lps.document,level=2,paper=A4,duplex,bpc myfax.tif
+ converts a fax TIFF file "myfax.tif" to "myfax.ps" for a PS 2 printer.
+
+bmpp -l pdf.document,paper=A4,duplex fax.tif
+ creates a PDF file fax.pdf.
+
+bmpp -l ps.object screenshot.png
+ creates a PS object file screenshot.ps for use with latex/dvips.
+
+bmpp -l pdf.object screenshot.png
+ creates a PDF object file screenshot.pdf for use with pdflatex.
+
+bmpp -l ps.image file.png
+ creates a PS image file.ps.
+
+bmpp -l pdf.image file.png
+ creates a PDF image file.pdf.
+
+FILES
+
+dk3paper.conf
+ If paper=... the named paper size must be configured in a
+ dk3paper.conf file.
+
+RESTRICTIONS
+
+The program uses the TIFFReadRGBAImage() function from the libtiff library to
+read TIFF images. The input file must meet the following conditions:
+- The file must be compliant to the "TIFF baseline v6.0 standard".
+- The number of bits of component must be 8 or less.
+- The frames must not be too large, the system must be able to allocate the
+ 4*w*h bytes needed for image date in one piece.
+
+TIFF refers to a group of different compression and encoding mechanisms.
+A TIFF file is a sequence of data chunks, each data chunk contains a tag
+(chunk type identifier). A lot of tags is defined in standards, i.e. the
+"TIFF baseline v6.0 standard". Some software vendors add vendor-specific
+or non-standard tags when writing TIFF files.
+So when processing TIFF files in bmpp, you should not be surprised to see
+warnings or error messages about unknown TIFF tags.
+Neither bmpp nor the tifflib library are to blame for this, it's the
+responsibility of the people adding the non-standard tags.
+Sometimes bmpp can read the image despite of the warnings/errors.
+
+If you create bitmaps you want to process with bmpp, you should create PNG
+images instead of TIFF images if you have the choice.
+
+AUTHOR
+
+Dirk Krause
+
+HISTORY
+
+The bmpp program replaces the bmeps program found in previous versions of
+dktools.
+
+COPYRIGHT AND LICENSE
+
+Run
+ bmpp --license-terms
+to see the license conditions.
+
+SEE ALSO
+
+http://dktools.sourceforge.net/bmpp.html
+ The DK tools and libraries homepage contains more information about
+ bmpp and other programs.
+
+http://gxhints.sourceforge.net
+ The Graphics Conversion Hints page recommends programs and shows
+ procedures for conversions between recent vector graphics formats.
+
+http://netpbm.sourceforge.net (especially pnmtops)
+ NetPBM is a toolkit for graphics images, including conversion of
+ images between a variety of different formats.
+
+$!end
+};
+
+
+
+/** Strings used to show version number.
+*/
+static dkChar const * const dk3bm_version_strings[] = {
+dkT("bmpp "),
+DKT_VERSION_DK
+};
+
+
+/** Options used by bmeps.
+*/
+static dk3_option_t const bmeps3_options[] = {
+ { dkT('l'), dkT("language"), 1 },
+ { dkT('m'), dkT("make"), 0 },
+ { dkT('s'), dkT("stdout"), 0 },
+ { dkT('t'), dkT("type"), 1 },
+ { dkT('h'), dkT("help"), 0 },
+ { dkT('v'), dkT("version"), 0 },
+ { dkT('L'), dkT("license-terms"), 0 },
+ { dkT('\0'),dkT("license"), 0 }
+};
+
+/** Number of options in @a bmeps3_options.
+*/
+static size_t const bmeps3_szoptions =
+sizeof(bmeps3_options)/sizeof(dk3_option_t);
+
+
+
+/** Names of supported input types.
+*/
+static dkChar const * const bmeps3_image_type_names[] = {
+$!string-table macro=dkT
+png
+jpg
+jpeg
+tif
+tiff
+$!end
+};
+
+
+
+/** Suffixes for output files.
+*/
+static dkChar const * const bmeps3_output_suffixes[] = {
+dkT(".ps"),
+dkT(".eps"),
+dkT(".pdf"),
+dkT(".bb")
+};
+
+
+
+/** Strings, not localized.
+*/
+static dkChar const * const bmeps3_kw[] = {
+$!string-table macro=dkT
+#
+# 0: Program name
+#
+dktools
+#
+# 1: String table name
+#
+bmeps3.str
+#
+# 2: Option keyword
+#
+option
+$!end
+};
+
+
+
+/** Strings, replaced by localized version.
+*/
+static dkChar const * const bmeps3_message_texts[] = {
+$!string-table macro=dkT
+
+$!end
+};
+
+
+
+/** License overview text.
+*/
+static dkChar const * const bmeps3_overview_license[] = {
+dkT(""),
+dkT("Overview"),
+dkT("========"),
+dkT("This software uses code from the following projects either directly"),
+dkT("or as a library:"),
+dkT(""),
+dkT("dktools\t\tDirk Krause's tools and libraries."),
+dkT("\t\tSee http://dktools.sourceforge.net for information."),
+#if DK3_HAVE_PNG_H
+dkT(""),
+dkT("libpng\t\tPNG reference library."),
+dkT("\t\tSee http://www.libpng.org/pub/png/libpng.html for information."),
+#endif
+#if DK3_HAVE_JPEGLIB_H
+dkT(""),
+dkT("jpeg\t\tIndependent JPEG groups free JPEG library."),
+dkT("\t\tSee http://www.ijg.org/ for information."),
+#endif
+#if DK3_HAVE_TIFF_H
+dkT(""),
+dkT("libtiff\t\tTIFF library."),
+dkT("\t\tSee http://www.remotesensing.org/libtiff/ for information."),
+#endif
+#if DK3_HAVE_ZLIB_H
+dkT(""),
+dkT("zlib\t\tCompression library."),
+dkT("\t\tSee http://www.zlib.net/ for information."),
+#endif
+dkT(""),
+dkT("Your use of the bmpp/wxmbpp program must be in compliance with the"),
+dkT("license conditions for the dktools project and the license conditions"),
+dkT("for all the libraries used by bmpp."),
+dkT(""),
+NULL
+};
+
+
+
+/** License terms for the dktools project itself.
+*/
+static dkChar const * const bmpp_dk_license[] = {
+$!text macro=dkT
+License for the dktools project
+===============================
+Copyright (c) 2011-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms,
+with or without modification, are permitted provided
+that the following conditions are met:
+
+* Redistributions of source code must retain the above
+ copyright notice, this list of conditions and the
+ following disclaimer.
+* Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials
+ provided with the distribution.
+* Neither the name of the copyright holder(s) nor the names of
+ contributors may be used to endorse or promote
+ products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+
+$!end
+};
+
+#if DK3_HAVE_PNG_H
+static dkChar const * const bmpp_png_license[] = {
+$!text macro=dkT
+
+libpng license
+==============
+
+This copy of the libpng notices is provided for your convenience. In case of
+any discrepancy between this copy and the notices in the file png.h that is
+included in the libpng distribution, the latter shall prevail.
+
+COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
+
+If you modify libpng you may insert additional notices immediately following
+this sentence.
+
+This code is released under the libpng license.
+
+libpng versions 1.2.6, August 15, 2004, through 1.2.46, July 9, 2011, are
+Copyright (c) 2004, 2006-2009 Glenn Randers-Pehrson, and are
+distributed according to the same disclaimer and license as libpng-1.2.5
+with the following individual added to the list of Contributing Authors
+
+ Cosmin Truta
+
+libpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002, are
+Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are
+distributed according to the same disclaimer and license as libpng-1.0.6
+with the following individuals added to the list of Contributing Authors
+
+ Simon-Pierre Cadieux
+ Eric S. Raymond
+ Gilles Vollant
+
+and with the following additions to the disclaimer:
+
+ There is no warranty against interference with your enjoyment of the
+ library or against infringement. There is no warranty that our
+ efforts or the library will fulfill any of your particular purposes
+ or needs. This library is provided with all faults, and the entire
+ risk of satisfactory quality, performance, accuracy, and effort is with
+ the user.
+
+libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
+Copyright (c) 1998, 1999 Glenn Randers-Pehrson, and are
+distributed according to the same disclaimer and license as libpng-0.96,
+with the following individuals added to the list of Contributing Authors:
+
+ Tom Lane
+ Glenn Randers-Pehrson
+ Willem van Schaik
+
+libpng versions 0.89, June 1996, through 0.96, May 1997, are
+Copyright (c) 1996, 1997 Andreas Dilger
+Distributed according to the same disclaimer and license as libpng-0.88,
+with the following individuals added to the list of Contributing Authors:
+
+ John Bowler
+ Kevin Bracey
+ Sam Bushell
+ Magnus Holmgren
+ Greg Roelofs
+ Tom Tanner
+
+libpng versions 0.5, May 1995, through 0.88, January 1996, are
+Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+
+For the purposes of this copyright and license, "Contributing Authors"
+is defined as the following set of individuals:
+
+ Andreas Dilger
+ Dave Martindale
+ Guy Eric Schalnat
+ Paul Schmidt
+ Tim Wegner
+
+The PNG Reference Library is supplied "AS IS". The Contributing Authors
+and Group 42, Inc. disclaim all warranties, expressed or implied,
+including, without limitation, the warranties of merchantability and of
+fitness for any purpose. The Contributing Authors and Group 42, Inc.
+assume no liability for direct, indirect, incidental, special, exemplary,
+or consequential damages, which may result from the use of the PNG
+Reference Library, even if advised of the possibility of such damage.
+
+Permission is hereby granted to use, copy, modify, and distribute this
+source code, or portions hereof, for any purpose, without fee, subject
+to the following restrictions:
+
+1. The origin of this source code must not be misrepresented.
+
+2. Altered versions must be plainly marked as such and must not
+ be misrepresented as being the original source.
+
+3. This Copyright notice may not be removed or altered from any
+ source or altered source distribution.
+
+The Contributing Authors and Group 42, Inc. specifically permit, without
+fee, and encourage the use of this source code as a component to
+supporting the PNG file format in commercial products. If you use this
+source code in a product, acknowledgment is not required but would be
+appreciated.
+
+
+A "png_get_copyright" function is available, for convenient use in "about"
+boxes and the like:
+
+ printf("%s",png_get_copyright(NULL));
+
+Also, the PNG logo (in PNG format, of course) is supplied in the
+files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
+
+Libpng is OSI Certified Open Source Software. OSI Certified Open Source is a
+certification mark of the Open Source Initiative.
+
+Glenn Randers-Pehrson
+glennrp at users.sourceforge.net
+July 9, 2011
+$!end
+};
+#endif
+#if DK3_HAVE_JPEGLIB_H
+static dkChar const * const bmpp_jpeg_license[] = {
+$!text macro=dkT
+
+jpeglib license
+===============
+
+In plain English:
+
+1. We don't promise that this software works. (But if you find any bugs,
+ please let us know!)
+2. You can use this software for whatever you want. You don't have to pay us.
+3. You may not pretend that you wrote this software. If you use it in a
+ program, you must acknowledge somewhere in your documentation that
+ you've used the IJG code.
+
+In legalese:
+
+The authors make NO WARRANTY or representation, either express or implied,
+with respect to this software, its quality, accuracy, merchantability, or
+fitness for a particular purpose. This software is provided "AS IS", and you,
+its user, assume the entire risk as to its quality and accuracy.
+
+This software is copyright (C) 1991-1998, Thomas G. Lane.
+All Rights Reserved except as specified below.
+
+Permission is hereby granted to use, copy, modify, and distribute this
+software (or portions thereof) for any purpose, without fee, subject to these
+conditions:
+(1) If any part of the source code for this software is distributed, then this
+README file must be included, with this copyright and no-warranty notice
+unaltered; and any additions, deletions, or changes to the original files
+must be clearly indicated in accompanying documentation.
+(2) If only executable code is distributed, then the accompanying
+documentation must state that "this software is based in part on the work of
+the Independent JPEG Group".
+(3) Permission for use of this software is granted only if the user accepts
+full responsibility for any undesirable consequences; the authors accept
+NO LIABILITY for damages of any kind.
+
+These conditions apply to any software derived from or based on the IJG code,
+not just to the unmodified library. If you use our work, you ought to
+acknowledge us.
+
+Permission is NOT granted for the use of any IJG author's name or company name
+in advertising or publicity relating to this software or products derived from
+it. This software may be referred to only as "the Independent JPEG Group's
+software".
+
+We specifically permit and encourage the use of this software as the basis of
+commercial products, provided that all warranty or liability claims are
+assumed by the product vendor.
+
+
+ansi2knr.c is included in this distribution by permission of L. Peter Deutsch,
+sole proprietor of its copyright holder, Aladdin Enterprises of Menlo Park, CA.
+ansi2knr.c is NOT covered by the above copyright and conditions, but instead
+by the usual distribution terms of the Free Software Foundation; principally,
+that you must include source code if you redistribute it. (See the file
+ansi2knr.c for full details.) However, since ansi2knr.c is not needed as part
+of any program generated from the IJG code, this does not limit you more than
+the foregoing paragraphs do.
+
+The Unix configuration script "configure" was produced with GNU Autoconf.
+It is copyright by the Free Software Foundation but is freely distributable.
+The same holds for its supporting scripts (config.guess, config.sub,
+ltconfig, ltmain.sh). Another support script, install-sh, is copyright
+by M.I.T. but is also freely distributable.
+
+It appears that the arithmetic coding option of the JPEG spec is covered by
+patents owned by IBM, AT&T, and Mitsubishi. Hence arithmetic coding cannot
+legally be used without obtaining one or more licenses. For this reason,
+support for arithmetic coding has been removed from the free JPEG software.
+(Since arithmetic coding provides only a marginal gain over the unpatented
+Huffman mode, it is unlikely that very many implementations will support it.)
+So far as we are aware, there are no patent restrictions on the remaining
+code.
+
+The IJG distribution formerly included code to read and write GIF files.
+To avoid entanglement with the Unisys LZW patent, GIF reading support has
+been removed altogether, and the GIF writer has been simplified to produce
+"uncompressed GIFs". This technique does not use the LZW algorithm; the
+resulting GIF files are larger than usual, but are readable by all standard
+GIF decoders.
+
+We are required to state that
+ "The Graphics Interchange Format(c) is the Copyright property of
+ CompuServe Incorporated. GIF(sm) is a Service Mark property of
+ CompuServe Incorporated."
+
+$!end
+};
+#endif
+#if DK3_HAVE_TIFF_H
+static dkChar const * const bmpp_tiff_license[] = {
+$!text macro=dkT
+
+libtiff license
+===============
+
+Copyright (c) 1988-1997 Sam Leffler
+Copyright (c) 1991-1997 Silicon Graphics, Inc.
+
+Permission to use, copy, modify, distribute, and sell this software and
+its documentation for any purpose is hereby granted without fee, provided
+that (i) the above copyright notices and this permission notice appear in
+all copies of the software and related documentation, and (ii) the names of
+Sam Leffler and Silicon Graphics may not be used in any advertising or
+publicity relating to the software without the specific, prior written
+permission of Sam Leffler and Silicon Graphics.
+
+THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+OF THIS SOFTWARE.
+
+$!end
+};
+#endif
+#if DK3_HAVE_ZLIB_H
+static dkChar const * const bmpp_zlib_license[] = {
+$!text macro=dkT
+
+zlib license
+============
+
+ (C) 1995-2004 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
+
+If you use the zlib library in a product, we would appreciate *not*
+receiving lengthy legal documents to sign. The sources are provided
+for free but without warranty of any kind. The library has been
+entirely written by Jean-loup Gailly and Mark Adler; it does not
+include third-party code.
+
+If you redistribute modified sources, we would appreciate that you include
+in the file ChangeLog history information documenting your changes. Please
+read the FAQ for more information on the distribution of modified source
+versions.
+
+$!end
+};
+#endif
+
+
+
+/** Show one section of text.
+ @param ltext Text to show.
+*/
+static
+void
+bmeps3_show_one_license(dkChar const * const *ltext)
+{
+ dkChar const * const * sptr;
+ sptr = ltext;
+ while(*sptr) {
+ dk3sf_fputs(*(sptr++), stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+}
+
+
+
+/** Show license for the program itself and for the used libraries.
+*/
+static
+void
+bmeps3_show_license(void)
+{
+ bmeps3_show_one_license(bmeps3_overview_license);
+ bmeps3_show_one_license(bmpp_dk_license);
+#if DK3_HAVE_PNG_H
+ bmeps3_show_one_license(bmpp_png_license);
+#endif
+#if DK3_HAVE_JPEGLIB_H
+ bmeps3_show_one_license(bmpp_jpeg_license);
+#endif
+#if DK3_HAVE_TIFF_H
+ bmeps3_show_one_license(bmpp_tiff_license);
+#endif
+#if DK3_HAVE_ZLIB_H
+ bmeps3_show_one_license(bmpp_zlib_license);
+#endif
+}
+
+
+
+/** Process a complete directory.
+ @param bmeo Conversion options.
+ @param fnb File name for directory.
+ @param app Application structure for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+bmeps3_process_directory(
+ dk3_bm_eps_options_t *bmeo,
+ dkChar const *fnb,
+ dk3_app_t *app
+)
+{
+ dkChar fni[DK3_MAX_PATH]; /* Input file name. */
+ dkChar fno[DK3_MAX_PATH]; /* output file name. */
+ dkChar const * const *msg; /* Localized message texts. */
+ dk3_dir_t *dir; /* Directory. */
+ dkChar const *en; /* Full file name. */
+ dkChar const *sn; /* Short file name. */
+ dkChar const *nsptr; /* Suffix output file. */
+ dkChar const *oldsourcefile; /* Old source file name. */
+ dkChar *sptr; /* Suffix input file. */
+ dk3_stat_t const *es; /* Stat info input file. */
+ dk3_stat_t stb; /* Stat buffer output file. */
+ int mustrun; /* Flag: Must convert file. */
+ int sit; /* Image type. */
+ int back = 0;
+ $? "+ bmeps3_process_directory"
+ msg = dk3app_messages(
+ app,
+ dk3bmep_str_get_string_table_name(),
+ (dkChar const **)dk3bmep_str_get_message_texts()
+ );
+ if(!(msg)) {
+ msg = dk3bmep_str_get_message_texts();
+ }
+ oldsourcefile = dk3app_get_source_file(app);
+ dir = dk3dir_open_app(fnb, app);
+ if(dir) { $? ". dr: %d", bmeo->dr
+ back = 1; $? ". bmeo.app: %!8s", TR_8PTR(bmeo->app)
+ while(dk3dir_get_next_file(dir)) { $? ". yet another entry"
+ en = dk3dir_get_fullname(dir); $? ". entry \"%!ds\"", en
+ sn = dk3dir_get_shortname(dir);
+ es = dk3dir_get_stat(dir);
+ if((en) && (es)) { $? ". have name and stat"
+ if(dk3bif_type_supported(sit = dk3bif_check_file_name(en))) { $? ". ok"
+ if(((es->ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_REGULAR) { $? ".ft"
+ mustrun = 1;
+ if(bmeo->make) {
+ if(dk3str_len(en) < DK3_SIZEOF(fni,dkChar)) {
+ dk3str_cpy_not_overlapped(fni, en);
+ dk3str_cpy_not_overlapped(fno, en);
+ sptr = dk3str_get_suffix(fno);
+ if(sptr) {
+ *sptr = dkT('\0'); $? ". dr: %d", bmeo->dr
+ if((bmeo->dr >= 0) && (bmeo->dr <= 3)) {
+ nsptr = bmeps3_output_suffixes[bmeo->dr];
+ if((dk3str_len(fno) + dk3str_len(nsptr))
+ < DK3_SIZEOF(fno,dkChar)
+ )
+ {
+ dk3str_cpy_not_overlapped(sptr, nsptr); $? ". check \"%!ds\"", fno
+ if(dk3sf_stat_app(&stb, fno, NULL)) {
+ if(stb.mod > es->mod) {
+ mustrun = 0;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if(mustrun) { $? ". run for \"%!ds\" dr: %d", en, bmeo->dr
+ dk3app_log_3(app, DK3_LL_PROGRESS, msg, 41, 42, ((sn) ? sn : en));
+ dk3app_set_source_file(app, ((sn) ? sn : en));
+ if(!dk3bm_process_file_name(bmeo,en,sit,0,1000,NULL)) {
+ back = 0;
+ }
+ dk3app_set_source_file(app, oldsourcefile);
+ dk3app_log_3(app, DK3_LL_PROGRESS, msg, 43, 44, ((sn) ? sn : en));
+ } else { $? ". no need to run for \"%!ds\"", en
+ dk3app_log_3(app, DK3_LL_PROGRESS, msg, 45, 46, ((sn) ? sn : en));
+ }
+ } else { $? ". not a regular file"
+ }
+ } else { $? ". no need to process this file"
+ }
+ } else { $? "! name or stat missing"
+ back = 0;
+ /* BUG: Should be handled by dk3dir. */
+ }
+ }
+ dk3dir_close(dir);
+ } else { $? "! failed to open dir"
+ /* ERROR: Failed to open directory! */
+ }
+ dk3app_set_source_file(app, oldsourcefile);
+ $? "- bmeps3_process_directory %d", back
+ return back;
+}
+
+
+
+
+/** Copy contents of one file to another.
+ @param fipoout Destination file.
+ @param fipoin Source file.
+ @param app Application structure for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+bmeps3_copy_files(FILE *fipoout, FILE *fipoin, dk3_app_t *app)
+{
+ char bu[4096]; /* Buffer for data. */
+ size_t rb; /* Number of bytes read. */
+ int cc; /* Flag: Can continue. */
+ int back = 1;
+ do {
+ cc = 0;
+ rb = dk3sf_fread_app(bu, 1, sizeof(bu), fipoin, app);
+ if(rb > 0) {
+ cc = 1;
+ if(!dk3sf_fwrite_app(bu, 1, rb, fipoout, app)) {
+ back = 0; cc = 0;
+ }
+ }
+ } while(cc);
+ return back;
+}
+
+
+
+
+/** Run with application structure and localized messages.
+ @param app Application structure.
+ @param msg Localized messages.
+ @param optset Option set.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+bmeps3_run_with_optset(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dk3_option_set_t *optset
+)
+{
+ dkChar fnb[DK3_MAX_PATH]; /* File name. */
+ dk3_bm_eps_options_t bmeo; /* Conversion option set. */
+ dk3_stat_t stb; /* Stat buffer. */
+ dk3_dir_t *fne; /* File name expander. */
+ dk3_stat_t const *es; /* Entry (file) stat information. */
+ FILE *fipo; /* Temporary file. */
+ dkChar const *larg; /* Option argument. */
+ dkChar const *fo; /* Further opt currently processed. */
+ dkChar const *en; /* Entry (file) name. */
+ int fonum; /* Number of further options. */
+ int i; /* Traverse options and arguments. */
+ int sit; /* Standard input image type. */
+ int numargs; /* Number of command line args. */
+ int found; /* Flag: At least one file found. */
+#if DK3_ON_WINDOWS
+ int oldmode; /* Stdin mode before start. */
+#endif
+ int back = 0;
+ $? "+ bmeps3_run_with_optset"
+ sit = DK3_BIF_IMAGE_TYPE_UNKNOWN;
+ dk3bmeo_init(&bmeo);
+ bmeo.app = app; $? ". app: %!8s", TR_8PTR(app)
+ back = 1; $? ". dr: %d", bmeo.dr
+ if(dk3opt_is_set(optset, dkT('l'))) {
+ larg = dk3opt_get_short_arg(optset, dkT('l'));
+ if(larg) {
+ if(!dk3bmeo_set_language(&bmeo, larg, app)) {
+ back = 0;
+ /* ERROR during option processing! */
+ }
+ bmeo.app = app;
+ } else {
+ /* BUG: Option -l set, but no argument. Should be handled by dk3opt. */
+ }
+ } $? ". dr: %d", bmeo.dr
+ if(dk3opt_is_set(optset, dkT('m'))) {
+ bmeo.make = 1;
+ }
+ if(dk3opt_is_set(optset, dkT('s'))) {
+ bmeo.to_stdout = 1;
+ }
+ if(dk3opt_is_set(optset, dkT('t'))) {
+ larg = dk3opt_get_short_arg(optset, dkT('t'));
+ if(larg) {
+ switch(dk3str_array_index(bmeps3_image_type_names, larg, 0)) {
+ case 0: {
+ sit = DK3_BIF_IMAGE_TYPE_PNG;
+ } break;
+ case 1: case 2: {
+ sit = DK3_BIF_IMAGE_TYPE_JPEG;
+ } break;
+ case 3: case 4: {
+ sit = DK3_BIF_IMAGE_TYPE_TIFF;
+ } break;
+ default: {
+ /* ERROR: Unknown file type ... */
+ dk3app_log_3(app, DK3_LL_ERROR, msg, 63, 64, larg);
+ back = 0;
+ } break;
+ }
+ } else {
+ /* BUG: Option -t set, but no argument. Should be handled by dk3opt. */
+ }
+ }
+ if(back) {
+ if((fonum = dk3opt_get_num_fo(optset)) > 0) {
+ for(i = 0; i < fonum; i++) {
+ fo = dk3opt_get_fo(optset, i);
+ if(fo) {
+ if(!dk3bmeo_apply_option(&bmeo, fo, msg)) {
+ back = 0;
+ /* ERROR: Error while adding option! */
+ }
+ } else {
+ /* BUG: Option not available. Should be handled by dk3opt. */
+ }
+ }
+ }
+ } $? ". dr: %d", bmeo.dr
+ if(back) {
+ if(dk3opt_is_set(optset, dkT('h'))
+ || dk3opt_is_set(optset, dkT('v'))
+ || dk3opt_is_set(optset, dkT('L'))
+ )
+ {
+ if(dk3opt_is_set(optset, dkT('v'))) {
+ /* Print version number */
+ dk3sf_initialize_stdout();
+ dk3sf_fputs(dk3bm_version_strings[0], stdout);
+ dk3sf_fputs(dk3bm_version_strings[1], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ if(dk3opt_is_set(optset, dkT('L'))) {
+ dk3sf_initialize_stdout();
+ bmeps3_show_license();
+ } else {
+ if(dk3opt_is_set_long(optset, dkT("license"))) {
+ dk3sf_initialize_stdout();
+ bmeps3_show_license();
+ }
+ }
+ if(dk3opt_is_set(optset, dkT('h'))) {
+ dk3sf_initialize_stdout();
+ dk3app_help(app, dkT("bmpp.txt"), bmeps3_default_help_text);
+ }
+ } else {
+ dk3bmeo_check(&bmeo, 0, app, NULL); $? ". dr: %d", bmeo.dr
+ numargs = dk3opt_get_num_args(optset);
+ if(numargs > 0) { $? ". file and/or directory names."
+ for(i = 0; i < numargs; i++) {
+ larg = dk3opt_get_arg(optset, i);
+ if(larg) {
+ if(dk3str_len(larg) < DK3_SIZEOF(fnb,dkChar)) {
+ dk3str_cpy_not_overlapped(fnb, larg);
+ dk3str_correct_filename(fnb);
+ if(dk3sf_must_expand(fnb)) { $? ". must expand fnb"
+ found = 0;
+ fne = dk3dir_fne_open_app(fnb, app);
+ if(fne) {
+ while(dk3dir_get_next_file(fne)) {
+ en = dk3dir_get_fullname(fne);
+ es = dk3dir_get_stat(fne);
+ if((en) && (es)) {
+ if(((es->ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_REGULAR) {
+ sit = DK3_BIF_IMAGE_TYPE_UNKNOWN;
+ if(!dk3bm_process_file_name(&bmeo,en,sit,0,1000,NULL))
+ {
+ back = 0;
+ }
+ } else {
+ /* ERROR: Not a regular file! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 255, 256, fnb);
+ }
+ } else {
+ /* BUG: Should be handled by dk3dir. */
+ back = 0;
+ }
+ }
+ dk3dir_close(fne);
+ if(!(found)) {
+ back = 0;
+ /* ERROR: No such file! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 215, 216, fnb);
+ }
+ } else {
+ /* ERROR: Failed to expand file name! */
+ back = 0;
+ }
+ } else { $? ". use fnb directly"
+ if(dk3sf_stat_app(&stb, fnb, app)) {
+ switch((stb.ft) & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_DIRECTORY: {
+ if(!bmeps3_process_directory(&bmeo, fnb, app)) {
+ back = 0;
+ }
+ } break;
+ case DK3_FT_REGULAR: {
+ if(!dk3bm_process_file_name(&bmeo,fnb,sit,0,1000,NULL)) {
+ back = 0;
+ }
+ } break;
+ default: {
+ /* ERROR: Illegal file type! */
+ back = 0;
+ dk3app_log_3(app, DK3_LL_ERROR, msg, 65, 66, fnb);
+ } break;
+ }
+ } else {
+ /* ERROR: No information about file! */
+ back = 0;
+ }
+ }
+ } else {
+ /* ERROR: File name too long! */
+ back = 0;
+ dk3app_log_i3(app, DK3_LL_ERROR, 65, 66, larg);
+ }
+ } else { $? "! arg not available"
+ /* BUG: Option not available, should be handled by dk3opt. */
+ }
+ }
+ } else { $? ". no arguments, process standard input."
+ if(sit != DK3_BIF_IMAGE_TYPE_UNKNOWN) {
+ if(dk3app_get_temp_file_name(app, fnb, DK3_SIZEOF(fnb,dkChar))) {
+ fipo = dk3sf_fopen_app(fnb, dk3app_not_localized(53), app);
+ if(fipo) {
+#if DK3_ON_WINDOWS
+ oldmode = _setmode(_fileno(stdin), _O_BINARY);
+#endif
+ i = bmeps3_copy_files(fipo, stdin, app);
+#if DK3_ON_WINDOWS
+ _setmode(_fileno(stdin), oldmode);
+#endif
+#if VERSION_BEFORE_2012_04_19
+ fclose(fipo);
+#else
+ if(!dk3sf_fclose_fn_app(fipo, fnb, app)) {
+ i = 0;
+ }
+#endif
+ if(i) {
+ bmeo.to_stdout = 1;
+ back = dk3bm_process_file_name(&bmeo,fnb,sit,0,1000,NULL);
+ }
+ } else {
+ /* ERROR: Failed to open file for writing! */
+ back = 0;
+ }
+ } else {
+ back = 0;
+ /* ERROR: Failed to obtain temporary file name! */
+ }
+ } else {
+ /* ERROR: No file type specified for standard input! */
+ back = 0;
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 67);
+ }
+ }
+ }
+ }
+ $? "- bmeps3_run_with_optset %d", back
+ return back;
+}
+
+
+
+/** Run with application structure and localized messages.
+ @param app Application structure.
+ @param msg Localized messages.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+bmeps3_run_with_app(dk3_app_t *app, dkChar const * const *msg)
+{
+ dk3_option_set_t *optset; /* Options provided on command line. */
+ int back = 0;
+ $? "+ bmeps3_run_with_app"
+ optset = dk3opt_open_from_app(
+ bmeps3_options,
+ bmeps3_szoptions,
+ dkT('o'),
+ bmeps3_kw[2],
+ app
+ );
+ if(optset) { $? ". optset"
+ if(0 == dk3opt_get_error_code(optset)) { $? ". optset no error"
+ back = bmeps3_run_with_optset(app, msg, optset);
+ } else { $? "! optset error"
+ /* ERROR: Error in options */
+ }
+ dk3opt_close(optset);
+ } else { $? "! optset"
+ } $? "- bmeps3_run_with_app %d", back
+ return back;
+}
+
+
+
+/** The main() function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, any other value indicates an error.
+*/
+DK3_MAIN
+{
+ dk3_app_t *app; /* Application structure. */
+ dkChar const * const *msg; /* Localizd messages. */
+ int exval; /* Exit code. */
+
+ $!trace-init bmeps3.deb
+ $? "+ main"
+ exval = 1;
+ app = dk3app_open_command(
+ argc, (dkChar const * const *)argv, bmeps3_kw[0]
+ );
+ if(app) { $? ". app ok"
+ msg = dk3app_messages(
+ app,
+ dk3bmep_str_get_string_table_name(),
+ (dkChar const **)dk3bmep_str_get_message_texts()
+ );
+ if(msg) { $? ". msg ok"
+ if(bmeps3_run_with_app(app, msg)) {
+ exval = 0;
+ }
+ } else { $? "! msg"
+ /* BUG: Should not happen, as the fucntion returns the default array! */
+ }
+ dk3app_close(app);
+ } else { $? "! app"
+ /* ERROR: Memory */
+ fputs("ERROR: Not enough memory (RAM/swap space)!\n", stderr);
+ fflush(stderr);
+ }
+ $? "- main %d", exval
+ $!trace-end
+ fflush(stdout);
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/bmeps3.h b/support/dktools/bmeps3.h
new file mode 100644
index 0000000000..cdb3c6a61e
--- /dev/null
+++ b/support/dktools/bmeps3.h
@@ -0,0 +1,47 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: bmeps3.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file bmeps3.h Header file for the bmeps3 module.
+*/
+
+#ifndef BMEPS3_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define BMEPS3_H_INCLUDED 1
+
+
+#line 10 "bmeps3.ctr"
+
+
+#endif
diff --git a/support/dktools/bmpp.rc b/support/dktools/bmpp.rc
new file mode 100644
index 0000000000..6501936c49
--- /dev/null
+++ b/support/dktools/bmpp.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Bitmap to PS/PDF converter\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "Bitmap to PS/PDF converter\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "bmpp\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/bsdlic.txt b/support/dktools/bsdlic.txt
new file mode 100644
index 0000000000..2bcfaf4b19
--- /dev/null
+++ b/support/dktools/bsdlic.txt
@@ -0,0 +1,35 @@
+Copyright (c) 2002-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms,
+with or without modification, are permitted provided
+that the following conditions are met:
+
+* Redistributions of source code must retain the above
+ copyright notice, this list of conditions and the
+ following disclaimer.
+* Redistributions in binary form must reproduce the above
+ opyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials
+ provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of
+ contributors may be used to endorse or promote
+ products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+
diff --git a/support/dktools/changes.dox b/support/dktools/changes.dox
new file mode 100644
index 0000000000..5d3b9d081d
--- /dev/null
+++ b/support/dktools/changes.dox
@@ -0,0 +1,89 @@
+/** @page changes Changes since version 3.
+
+@section errorreporting Error reporting
+
+@subsection errorreportold Old behaviour
+In version 3.x.x many functions had a final dk3_app_t pointer
+argument for diagnostics. This argument was allowed to be NULL if
+no error reporting was intended.
+
+Use of these functions pulled the dk3app modules into the project
+and other modules required by this one...
+
+A resource for error reporting was passed from the calling function
+to the called function.
+
+@subsection errorreportnew New behaviour
+Now the dk4_er_t data type can be used to pass error information
+from a called function back to the caller.
+
+A calling function initializes an error report using the
+dk4error_init() function, this function sets a special error code
+indicating ``No error occured''. The address of the error report
+is passed to called functions.
+
+If an error occurs within a called function, the function uses
+one of the dk4error_set...() functions or dk4error_copy() to place
+an error code and optionally details in the error report.
+
+Sometimes one error results in further errors. In such situations information
+about the first error is of most interest. So the dk4error_set...() and
+dk4error_copy() functions leave the error report unchanged if it already
+contains information about an error.
+
+Information about errors is passed from the called function back to the
+caller, it is up to the caller whether to use this information or not.
+
+
+@section microcontrollers Microcontrollers
+Using a function from the printf()/scanf() function family pulls many
+modules from the standard library into the executable to build.
+
+This is not a problem on desktop or server systems, but microcontroller
+systems have a limited amount of memory available.
+So the printf()/scanf() functions should not be used when programming
+for microcontrollers.
+
+So these functions are used only in a very few places in the
+libdk4c library, mainly in the dk4ma*dbl.c modules.
+When programming for microcontrollers, you should avoid to use these modules.
+
+The printf()/scanf() functions are used in some modules of the dk4app
+library, this library is not intended for use on microcontrollers.
+
+@section wincrt Windows and the C runtime library
+You can not rely on having the C runtime library available on Windows
+systems. The CRT is typically installed during Visual Studio installation
+and is available in MS Download Center.
+
+When developing Windows extension DLLs, Windows drivers or Windows services
+you should not use the C runtime library (CRT), use the Windows API instead.
+
+For some tasks (i.e. memory allocation, string copying...)
+the Windows API contains mechanisms equivalent to the CRT mechanisms.
+
+For other tasks (i.e. finding a character in a string) there is no
+Windows API function available, but the DK libraries contain a self-made
+fallback function.
+
+For some mechanisms from CRT (i.e. FILE I/O using functions like
+printf()) there is no equivalent mechanism in the Windows API.
+
+You can define DK4_WIN_AVOID_CRT to a non-zero value. This avoids use of the
+CRT for mechanisms having an equivalent in the Windows API and for
+mechanisms with self-made fallback functions. For mechanisms not available
+in the Windows API the CRT functions are used.
+
+You can define DK4_WIN_DENY_CRT to a non-zero value. This completely
+denies the use of CRT functions. Some of the DK library modules can not
+be compiled this way (i.e. the dk4fop*.c and the dk4fd.c module).
+
+When using Windows API instead of CRT some DK library functions will
+produce less descriptive diagnostic messages.
+POSIX and Linux man pages for a CRT function contain an ``ERRORS'' section
+with a complete list of errno codes for the function.
+A programmer using a CRT function on POSIX or Linux systems can check
+for all errors which might happen in the function and produce
+descriptive messages for all of them.
+
+*/
diff --git a/support/dktools/choose-dir.xpm b/support/dktools/choose-dir.xpm
new file mode 100644
index 0000000000..e2e52ce4a6
--- /dev/null
+++ b/support/dktools/choose-dir.xpm
@@ -0,0 +1,38 @@
+/* XPM */
+static const char *xpm_choose_dir[] = {
+/* width height ncolors chars_per_pixel */
+"16 15 16 1",
+/* colors */
+" c #AFAFAF",
+". c #786401",
+"X c #9B8202",
+"o c #FFD400",
+"O c #ECECEC",
+"+ c #A68C05",
+"@ c #B69700",
+"# c #B0B0B0",
+"$ c #846E00",
+"% c #403502",
+"& c #6B5A01",
+"* c #FFFFFF",
+"= c #BFBFBF",
+"- c #AF9100",
+"; c #B3B3B3",
+": c None",
+/* pixels */
+"::::::::::::::::",
+"::::::::::::::::",
+"::::&++X%X++&%::",
+":::%X@@%$@@@$.::",
+"::&...&&...X-X::",
+"::-oooooooooo-::",
+"::-oooooooooo-::",
+"::-oooooooooo-::",
+"::-oooooooooo-::",
+"::-oooooooooo-::",
+"::-oooooooooo-::",
+"::-oooooooooo-::",
+"::.++++++++++.::",
+"::::::::::::::::",
+"::::::::::::::::"
+};
diff --git a/support/dktools/conceptions.dox b/support/dktools/conceptions.dox
new file mode 100644
index 0000000000..a2e5ebada6
--- /dev/null
+++ b/support/dktools/conceptions.dox
@@ -0,0 +1,179 @@
+/** @page conceptions Conceptions
+
+@section secdkchar dkChar
+
+POSIX systems use the char data type for both non-localized and localized
+texts. An encoding specification configured either in configuration
+files or as appendix in the LANG environment variable chooses a character
+encoding. Most Linux systems today use UTF-8 encoding, the LANG variable
+ends in "utf8" or "UTF-8".
+
+Windows systems use the wchar_t data type (16 bit wide on Windows) for
+localized texts, the encoding is UTF-16. When saving texts to file the
+least significant byte of a wchar_t is written first.
+
+For portability the dkChar data type is mapped to char on non-Windows
+systems and to wchar_t on Windows.
+
+@section secerrorrep Error reporting
+
+A called function should be able to report errors to the caller.
+The DK libraries use the dk4_er_t (DK4 error report type) data type.
+It consists of error code (type int), optionally there are details like
+an error position when processing text or a byte number for a failed
+memory allocation.
+
+If a function detects an error, it can use the functions from
+dk4error.h to fill the report. If the report already contains data for a
+previous error, the report is not overwritten. Sometimes one error results
+in further errors, information about the first error is of most interest
+in these situations.
+
+You can pass a NULL pointer to functions expecting a dk4_er_t pointer argument
+if you are not interested in error details.
+
+If you write functions expecting a dk4_er_t pointer argument you do not need
+special preparations for NULL pointers, as the dk4error.h functions check
+their dk4_er_t pointer argument.
+
+So you can simply write:
+
+~~~~~~~~~~~~~~~{.c}
+dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+~~~~~~~~~~~~~~~
+
+There is no need to bloat the code size for checks like:
+
+~~~~~~~~~~~~~~~{.c}
+if (NULL != erp) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+}
+~~~~~~~~~~~~~~~
+
+@section secintmax intmax_t, uintmax_t, dk4_im_t, dk4_um_t
+
+Recent C standards have the data types intmax_t/uintmax_t available.
+You can cast every signed/unsigned integer value to these data types without
+loss.
+Unfortunately there are compilers without these data types.
+The dk4_im_t/dk4_um_t types from the DK libraries are for the same purpose.
+They are typedefed to intmax_t/uintmax_t if these types are available,
+otherwise long long/unsigned long long or long/unsigned long are used.
+
+@section sectextproc Text processing
+
+Most DK libraries functions use the dkChar data type to store text in the
+computers memory while the program is running.
+
+Depending on the text origin text in files can be in different encodings,
+i.e.:
+
+- ASCII
+- ANSI
+- UTF-8
+- UTF-16, least significant byte first
+- UTF-16, most significant byte first
+- 32 bit, least significant byte first (rarely used)
+- 32 bit, most significant byte first (rarely used)
+
+So when reading text from files or other data sources into dkChar strings
+we first need to know the file encoding. Text files can have a byte order
+mark (BOM) - Unicode U+FEFF (zero width no-break space) - at start of text.
+For UTF-16/LSB the file starts with 0xFF, 0xFE. For UTF-16/MSB it starts
+with 0xFE, 0xFF. For UTF-8 it starts with 0xEF, 0xBB, 0xBF.
+
+So when processing text you need to know the dkChar size and encoding
+to use in memory and the expected file encoding used by the input.
+After inspecting the start of input one can decide about the input encoding
+really used and recode the bytes to the desired dkChar size and encoding.
+
+Text processing is done using state machines in the DK libraries.
+You provide a callback function handling either a single dkChar character
+or a dkChar line. For line processing you also have to provide buffers
+to store the line.
+After setup you feed the bytes into the state machine, it inspects input
+for BOM, recodes if necessary and calls the callback functions...
+
+Look at the dk-cat program for a working example of characterwise processing.
+
+For linewise processing see the dk-sort program.
+
+@section secgenio Generic I/O using dk4_stream_t
+
+The dk4strm module and related modules provide a generic interface
+to read from or write to a data stream. A data stream can be connected
+to a plain file, a gzip or bzip2 compressed file or any other data source
+or sink.
+
+To construct a stream one has to provide the address of a low level
+data object to handle I/O requests (i.e. a file) and a handler function.
+
+Convenience functions are available in the dk4strmr and dk4strmw modules
+to open plain files, gzip or bzip2 compressed files for reading and writing.
+
+Different strategies are available to use the streams:
+
+- Read and write arbitrary data.<br>
+ The functions from the dk4strm module can be used to read and
+ write buffers by specifying buffer start address and buffer size
+ in bytes.
+- Serialize data to and unserialize data from stream.<br>
+ The functions from the dk4strms and dk4strmu modules can be used
+ to read/write int16_t, uint16_t, int32_t, uint32_t, double values
+ and char strings.<br>
+ Integer numbers are stored LSB first.
+ For strings the uint16_t string length is written first, text follows.
+ The finalizing 0x00 byte is both counted in the string length and
+ included in the data. String length is limited to 65534 characters.
+ No specific encoding is required for char strings, but UTF-8 is
+ recommended.<br>
+ For double values the value is converted to string and written as string.
+ Routines unserializing data from stream must know which data types
+ need to be read in which order.
+- Write text, adjust encoding automatically.<br>
+ When writing pure text to stream, one can use the
+ dk4stream_set_output_encoding() function from the dk4strmo32 module
+ to set the desired output encoding. Now you can use the
+ dk4stream_c08_puts() and equivalent functions from the
+ dk4strmo08, dk4strmo16, dk4strmo32 and dk4strmodk modules to pass
+ texts in a given encoding to the stream, they are converted to the
+ desired output encoding automatically.
+
+@section secwincrt Windows and the C runtime
+
+The C runtime libraries should not be used on Windows for
+- drivers,
+- services or
+- programs using threads.
+
+The C runtime libraries are not included in a default Windows installation,
+they are available as separated downloads. So they are probably not present
+when the driver/service is installed (reason for 1, 2).
+Using the C runtime libraries in threads may result in memory leaks
+(reason for 3).
+
+May be the information in the paragraph above is out of date now,
+but I did not hear about all-clear.
+
+The build process for DK tools and libraries on Windows typically uses
+C runtime functions and links static multithreaded release
+runtime libraries.
+
+For most of the modules use in a Windows driver or service is unlikely,
+except:
+- dk4error (required by the modules below)
+- dk4mem
+- dk4sto
+- dk4strw
+- dk4maa*
+
+If you want to use these modules in a project for a Windows driver
+or service, you should copy the modules into your project and use the
+
+~~~~~~~~~~~~~~~
+-DDK4_WIN_DENY_CRT=1
+~~~~~~~~~~~~~~~
+
+C compiler option.
+
+*/
diff --git a/support/dktools/conf.vc b/support/dktools/conf.vc
new file mode 100644
index 0000000000..bb4f93b31b
--- /dev/null
+++ b/support/dktools/conf.vc
@@ -0,0 +1,312 @@
+# System bit width, either 32 or 64
+CONF_BITS=64
+
+# Visual Studio version: 2013, 2012, 2008, 2005, 2003, 6 or 5
+CONF_VSTUDIO=2013
+
+# Platform SDK version: 8.1, 8, 7 or none
+# 8.1 Visual Studio 2013
+# 8 Visual Studio 2012
+# 7 Visual Studio 2008
+CONF_PSDK=8.1
+
+# Build GUI programs
+# yes Build GUI and CLI programs
+# no Build CLI programs only (no wxWidgets available)
+CONF_GUI=yes
+
+# Compile for legacy versions (i.e. Windows XP)
+# Legacy mode disables RegDeleteTree and IPv6 Winsock functions.
+# no No restrictions on used functions
+# yes Legacy mode
+CONF_LEGACY=no
+
+# Base directory with include and lib subdirectories for used libraries.
+# If there is only one version of Visual Studio on your computer you
+# might remove the final -VS$(CONF_VSTUDIO) part.
+CONF_USEDLIBDIR=C:\P\LIB-STT$(CONF_BITS)-VS$(CONF_VSTUDIO)
+
+# MS Visual C Runtime Library type:
+# 0 Static libraries
+# 1 DLL
+CONF_MSVCRT_DLL=0
+
+# MS Visual C Runtime Library debug:
+# 0 Release
+# 1 Debug
+CONF_MSVCRT_DEBUG=0
+
+# MS Visual C Runtime Library threads:
+# 0 Single thread
+# 1 Multithread-ready
+CONF_MSVCRT_THREADED=1
+
+# Unicode support
+# 1 Unicode enabled
+# 0 Unicode disabled
+CONF_UNICODE=1
+
+# Output directory for "make install" on developer PC
+CONF_OUTPUTDIR=C:\Krause\bindist
+
+# Directory for programs
+# CONF_PROGRAMS=C:\Programme (on older Windows versions)
+CONF_PROGRAMS=C:\Program Files
+
+# Installation directory on end user PC (used as default by the installer)
+CONF_PREFIX=$(CONF_PROGRAMS)\Krause
+
+# Directory for *.exe files on end user PC
+CONF_BINDIR=$(CONF_PROGRAMS)\Krause\bin
+
+# Directory for configuration files on end user PC
+CONF_SYSCONFDIR=$(CONF_PROGRAMS)\Krause\etc
+
+# Directory for data files on end user PC
+CONF_DATADIR=$(CONF_PROGRAMS)\Krause\share
+
+# Directory for *.h files on end user PC
+CONF_INCLUDEDIR=$(CONF_PROGRAMS)\Krause\include
+
+# Directory for *.lib files on end user PC
+CONF_LIBDIR=$(CONF_PROGRAMS)\Krause\lib
+
+
+
+# ##### Some popular libraries (start)
+
+# If one of the libraries is not present, change CONF_..._AVAILABLE to 0.
+# For libraries present, make sure the DEF, INCLUDE, LIBDIR and LIBFILE
+# settings are correct.
+
+# zlib (general purpose compression library)
+CONF_ZLIB_AVAILABLE=1
+CONF_ZLIB_DEF=-DDK4_HAVE_ZLIB_H=1 -DDK3_HAVE_ZLIB_H=1
+CONF_ZLIB_INCLUDE=/I$(CONF_USEDLIBDIR)\include
+CONF_ZLIB_LIBDIR=/LIBPATH:"$(CONF_USEDLIBDIR)\lib"
+CONF_ZLIB_LIBFILE=zlib.lib
+
+# bzip2 (general purpose compression library)
+CONF_BZIP2_AVAILABLE=1
+CONF_BZIP2_DEF=-DDK4_HAVE_BZLIB_H=1 -DDK3_HAVE_BZLIB_H=1
+CONF_BZIP2_INCLUDE=/IC:\P\$(CONF_USEDLIBDIR)\include
+CONF_BZIP2_LIBDIR=/LIBPATH:"$(CONF_USEDLIBDIR)\lib"
+CONF_BZIP2_LIBFILE=libbz2.lib
+
+# libpng (PNG image reference library)
+CONF_PNG_AVAILABLE=1
+CONF_PNG_DEF=-DDK4_HAVE_PNG_H=1 -DDK3_HAVE_PNG_H=1 -DDK3_HAVE_LIBPNG
+CONF_PNG_INCLUDE=/I$(CONF_USEDLIBDIR)\include
+CONF_PNG_LIBDIR=/LIBPATH:"$(CONF_USEDLIBDIR)\lib"
+CONF_PNG_LIBFILE=libpng.lib
+
+# jpeglib (Independent JPEG groups library)
+CONF_JPG_AVAILABLE=1
+CONF_JPG_DEF=-DDK4_HAVE_JPEGLIB_H=1 -DDK3_HAVE_JPEGLIB_H=1
+CONF_JPG_INCLUDE=/I$(CONF_USEDLIBDIR)\include
+CONF_JPG_LIBDIR=/LIBPATH:"$(CONF_USEDLIBDIR)\lib"
+CONF_JPG_LIBFILE=libjpeg.lib
+
+# libtiff (library to read TIFF images)
+CONF_TIFF_AVAILABLE=1
+CONF_TIFF_DEF=-DDK4_HAVE_TIFF_H=1 -DDK3_HAVE_TIFF_H=1
+CONF_TIFF_INCLUDE=/I$(CONF_USEDLIBDIR)\include
+CONF_TIFF_LIBDIR=/LIBPATH:"$(CONF_USEDLIBDIR)\lib"
+CONF_TIFF_LIBFILE=libtiff.lib
+
+# OpenSSL (cryptographic library, used for message digests and random data here)
+CONF_OPENSSL_AVAILABLE=1
+CONF_OPENSSL_DEF= \
+ -DDK4_HAVE_OPENSSL_MD5_H=1 \
+ -DDK4_HAVE_OPENSSL_SHA_H=1 \
+ -DDK4_HAVE_OPENSSL_RIPEMD_H=1 \
+ -DDK4_HAVE_OPENSSL_SHA224=1 \
+ -DDK4_HAVE_OPENSSL_SHA256=1 \
+ -DDK4_HAVE_OPENSSL_SHA384=1 \
+ -DDK4_HAVE_OPENSSL_SHA512=1 \
+ -DDK4_HAVE_OPENSSL_RAND_H=1 \
+ -DDK3_HAVE_OPENSSL_MD5_H=1 \
+ -DDK3_HAVE_OPENSSL_SHA_H=1 \
+ -DDK3_HAVE_OPENSSL_RIPEMD_H=1 \
+ -DDK3_HAVE_OPENSSL_SHA224=1 \
+ -DDK3_HAVE_OPENSSL_SHA256=1 \
+ -DDK3_HAVE_OPENSSL_SHA384=1 \
+ -DDK3_HAVE_OPENSSL_SHA512=1 \
+ -DDK3_HAVE_OPENSSL_RAND_H=1
+CONF_OPENSSL_INCLUDE=/I$(CONF_USEDLIBDIR)\include
+CONF_OPENSSL_LIBDIR=/LIBPATH:"$(CONF_USEDLIBDIR)\lib"
+CONF_OPENSSL_LIBFILE=libcrypto.lib libssl.lib crypt32.lib ws2_32.lib
+
+# NetSNMP (correct DK4_HAVE_NETSNMP_ENABLE_FILELOG if necessary)
+CONF_NETSNMP_AVAILABLE=0
+CONF_NETSNMP_DEF= \
+ -DDK4_HAVE_LIBNETSNMP=1 -DDK3_HAVE_LIBNETSNMP=1 \
+ -DDK4_HAVE_LIBUCDSNMP=0 -DDK3_HAVE_LIBUCDSNMP=0 \
+ -D_WINDOWS=1 \
+ -DDK4_HAVE_NETSNMP_ENABLE_FILELOG=1 \
+ -DDK3_HAVE_NETSNMP_ENABLE_FILELOG=1
+CONF_NETSNMP_INCLUDE=/I$(CONF_USEDLIBDIR)\include
+CONF_NETSNMP_LIBDIR=/LIBPATH:"$(CONF_USEDLIBDIR)\lib"
+CONF_NETSNMP_LIBFILE=netsnmp.lib
+
+CONF_WX_AVAILABLE=1
+CONF_WX_VERSION=3.1.0
+# CONF_WX_VERSION=3.0.2
+# CONF_WX_VERSION=2.8.12
+CONF_WX_SHORTVERSION=31
+# CONF_WX_SHORTVERSION=30
+# CONF_WX_SHORTVERSION=28
+CONF_WX_DEF=-DDK4_HAVE_WXWIDGETS=1 -DDK3_HAVE_WXWIDGETS=1 \
+ -DDK4_HAVE_WX_CHARTYPE_H=1 -DDK3_HAVE_WX_CHARTYPE_H=1
+CONF_WX_DIR=C:\P\wxWidgets-$(CONF_WX_VERSION)-stt$(CONF_BITS)-vs$(CONF_VSTUDIO)
+CONF_WX_INCLUDE=/I"$(CONF_WX_DIR)\include"
+!IF "$(CONF_WX_VERSION)" != "2.8.12"
+CONF_WX_LIBDIR=/LIBPATH:"$(CONF_WX_DIR)\lib\vc_x64_lib"
+!ELSE
+CONF_WX_LIBDIR=/LIBPATH:"$(CONF_WX_DIR)\lib"
+!ENDIF
+CONF_WX_LIBFILE= \
+ wxbase$(CONF_WX_SHORTVERSION)u.lib \
+ wxbase$(CONF_WX_SHORTVERSION)u_net.lib \
+ wxbase$(CONF_WX_SHORTVERSION)u_xml.lib \
+ wxmsw$(CONF_WX_SHORTVERSION)u_adv.lib \
+ wxmsw$(CONF_WX_SHORTVERSION)u_aui.lib \
+ wxmsw$(CONF_WX_SHORTVERSION)u_core.lib \
+ wxmsw$(CONF_WX_SHORTVERSION)u_html.lib \
+ wxmsw$(CONF_WX_SHORTVERSION)u_media.lib \
+ wxmsw$(CONF_WX_SHORTVERSION)u_qa.lib \
+ wxmsw$(CONF_WX_SHORTVERSION)u_richtext.lib \
+ wxmsw$(CONF_WX_SHORTVERSION)u_xrc.lib \
+ wxexpat.lib \
+ wxregexu.lib \
+ wxtiff.lib wxjpeg.lib wxpng.lib wxzlib.lib
+
+# ##### Some popular libraries (end)
+
+
+
+# ##### Room for more libraries
+
+CONF_L01_AVAILABLE=0
+CONF_L01_DEF=
+CONF_L01_INCLUDE=
+CONF_L01_LIBDIR=
+CONF_L01_LIBFILE=
+
+CONF_L02_AVAILABLE=0
+CONF_L02_DEF=
+CONF_L02_INCLUDE=
+CONF_L02_LIBDIR=
+CONF_L02_LIBFILE=
+
+CONF_L03_AVAILABLE=0
+CONF_L03_DEF=
+CONF_L03_INCLUDE=
+CONF_L03_LIBDIR=
+CONF_L03_LIBFILE=
+
+CONF_L04_AVAILABLE=0
+CONF_L04_DEF=
+CONF_L04_INCLUDE=
+CONF_L04_LIBDIR=
+CONF_L04_LIBFILE=
+
+CONF_L05_AVAILABLE=0
+CONF_L05_DEF=
+CONF_L05_INCLUDE=
+CONF_L05_LIBDIR=
+CONF_L05_LIBFILE=
+
+CONF_L06_AVAILABLE=0
+CONF_L06_DEF=
+CONF_L06_INCLUDE=
+CONF_L06_LIBDIR=
+CONF_L06_LIBFILE=
+
+CONF_L07_AVAILABLE=0
+CONF_L07_DEF=
+CONF_L07_INCLUDE=
+CONF_L07_LIBDIR=
+CONF_L07_LIBFILE=
+
+CONF_L08_AVAILABLE=0
+CONF_L08_DEF=
+CONF_L08_INCLUDE=
+CONF_L08_LIBDIR=
+CONF_L08_LIBFILE=
+
+CONF_L09_AVAILABLE=0
+CONF_L09_DEF=
+CONF_L09_INCLUDE=
+CONF_L09_LIBDIR=
+CONF_L09_LIBFILE=
+
+CONF_L10_AVAILABLE=0
+CONF_L10_DEF=
+CONF_L10_INCLUDE=
+CONF_L10_LIBDIR=
+CONF_L10_LIBFILE=
+
+CONF_L11_AVAILABLE=0
+CONF_L11_DEF=
+CONF_L11_INCLUDE=
+CONF_L11_LIBDIR=
+CONF_L11_LIBFILE=
+
+CONF_L12_AVAILABLE=0
+CONF_L12_DEF=
+CONF_L12_INCLUDE=
+CONF_L12_LIBDIR=
+CONF_L12_LIBFILE=
+
+CONF_L13_AVAILABLE=0
+CONF_L13_DEF=
+CONF_L13_INCLUDE=
+CONF_L13_LIBDIR=
+CONF_L13_LIBFILE=
+
+CONF_L14_AVAILABLE=0
+CONF_L14_DEF=
+CONF_L14_INCLUDE=
+CONF_L14_LIBDIR=
+CONF_L14_LIBFILE=
+
+CONF_L15_AVAILABLE=0
+CONF_L15_DEF=
+CONF_L15_INCLUDE=
+CONF_L15_LIBDIR=
+CONF_L15_LIBFILE=
+
+CONF_L16_AVAILABLE=0
+CONF_L16_DEF=
+CONF_L16_INCLUDE=
+CONF_L16_LIBDIR=
+CONF_L16_LIBFILE=
+
+CONF_L17_AVAILABLE=0
+CONF_L17_DEF=
+CONF_L17_INCLUDE=
+CONF_L17_LIBDIR=
+CONF_L17_LIBFILE=
+
+CONF_L18_AVAILABLE=0
+CONF_L18_DEF=
+CONF_L18_INCLUDE=
+CONF_L18_LIBDIR=
+CONF_L18_LIBFILE=
+
+CONF_L19_AVAILABLE=0
+CONF_L19_DEF=
+CONF_L19_INCLUDE=
+CONF_L19_LIBDIR=
+CONF_L19_LIBFILE=
+
+CONF_L20_AVAILABLE=0
+CONF_L20_DEF=
+CONF_L20_INCLUDE=
+CONF_L20_LIBDIR=
+CONF_L20_LIBFILE=
+
+# add further sections as needed, add corresponding sections to the
+# translate.vc file
+
diff --git a/support/dktools/config.guess b/support/dktools/config.guess
new file mode 100755
index 0000000000..6c32c8645c
--- /dev/null
+++ b/support/dktools/config.guess
@@ -0,0 +1,1421 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright 1992-2014 Free Software Foundation, Inc.
+
+timestamp='2014-11-04'
+
+# This file 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.
+#
+# This program 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 this program; if not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that
+# program. This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+#
+# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
+#
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+#
+# Please send patches to <config-patches@gnu.org>.
+
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright 1992-2014 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help" >&2
+ exit 1 ;;
+ * )
+ break ;;
+ esac
+done
+
+if test $# != 0; then
+ echo "$me: too many arguments$help" >&2
+ exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,) echo "int x;" > $dummy.c ;
+ for c in cc gcc c89 c99 ; do
+ if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+ CC_FOR_BUILD="$c"; break ;
+ fi ;
+ done ;
+ if test x"$CC_FOR_BUILD" = x ; then
+ CC_FOR_BUILD=no_compiler_found ;
+ fi
+ ;;
+ ,,*) CC_FOR_BUILD=$CC ;;
+ ,*,*) CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+case "${UNAME_SYSTEM}" in
+Linux|GNU|GNU/*)
+ # If the system lacks a compiler, then just pick glibc.
+ # We could probably try harder.
+ LIBC=gnu
+
+ eval $set_cc_for_build
+ cat <<-EOF > $dummy.c
+ #include <features.h>
+ #if defined(__UCLIBC__)
+ LIBC=uclibc
+ #elif defined(__dietlibc__)
+ LIBC=dietlibc
+ #else
+ LIBC=gnu
+ #endif
+ EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
+ ;;
+esac
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ *:NetBSD:*:*)
+ # NetBSD (nbsd) targets should (where applicable) match one or
+ # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+ # compatibility and a consistent mechanism for selecting the
+ # object file format.
+ #
+ # Note: NetBSD doesn't particularly care about the vendor
+ # portion of the name. We always set it to "unknown".
+ sysctl="sysctl -n hw.machine_arch"
+ UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+ /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+ case "${UNAME_MACHINE_ARCH}" in
+ armeb) machine=armeb-unknown ;;
+ arm*) machine=arm-unknown ;;
+ sh3el) machine=shl-unknown ;;
+ sh3eb) machine=sh-unknown ;;
+ sh5el) machine=sh5le-unknown ;;
+ *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+ esac
+ # The Operating System including object format, if it has switched
+ # to ELF recently, or will in the future.
+ case "${UNAME_MACHINE_ARCH}" in
+ arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ eval $set_cc_for_build
+ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ELF__
+ then
+ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+ # Return netbsd for either. FIX?
+ os=netbsd
+ else
+ os=netbsdelf
+ fi
+ ;;
+ *)
+ os=netbsd
+ ;;
+ esac
+ # The OS release
+ # Debian GNU/NetBSD machines have a different userland, and
+ # thus, need a distinct triplet. However, they do not need
+ # kernel version information, so it can be replaced with a
+ # suitable tag, in the style of linux-gnu.
+ case "${UNAME_VERSION}" in
+ Debian*)
+ release='-gnu'
+ ;;
+ *)
+ release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ ;;
+ esac
+ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+ # contains redundant information, the shorter form:
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "${machine}-${os}${release}"
+ exit ;;
+ *:Bitrig:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
+ exit ;;
+ *:OpenBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+ exit ;;
+ *:ekkoBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+ exit ;;
+ *:SolidBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+ exit ;;
+ macppc:MirBSD:*:*)
+ echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ *:MirBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ alpha:OSF1:*:*)
+ case $UNAME_RELEASE in
+ *4.0)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ ;;
+ *5.*)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ ;;
+ esac
+ # According to Compaq, /usr/sbin/psrinfo has been available on
+ # OSF/1 and Tru64 systems produced since 1995. I hope that
+ # covers most systems running today. This code pipes the CPU
+ # types through head -n 1, so we only detect the type of CPU 0.
+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ case "$ALPHA_CPU_TYPE" in
+ "EV4 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "EV4.5 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "LCA4 (21066/21068)")
+ UNAME_MACHINE="alpha" ;;
+ "EV5 (21164)")
+ UNAME_MACHINE="alphaev5" ;;
+ "EV5.6 (21164A)")
+ UNAME_MACHINE="alphaev56" ;;
+ "EV5.6 (21164PC)")
+ UNAME_MACHINE="alphapca56" ;;
+ "EV5.7 (21164PC)")
+ UNAME_MACHINE="alphapca57" ;;
+ "EV6 (21264)")
+ UNAME_MACHINE="alphaev6" ;;
+ "EV6.7 (21264A)")
+ UNAME_MACHINE="alphaev67" ;;
+ "EV6.8CB (21264C)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8AL (21264B)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8CX (21264D)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.9A (21264/EV69A)")
+ UNAME_MACHINE="alphaev69" ;;
+ "EV7 (21364)")
+ UNAME_MACHINE="alphaev7" ;;
+ "EV7.9 (21364A)")
+ UNAME_MACHINE="alphaev79" ;;
+ esac
+ # A Pn.n version is a patched version.
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+ exitcode=$?
+ trap '' 0
+ exit $exitcode ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+ # of the specific Alpha model?
+ echo alpha-pc-interix
+ exit ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-unknown-sysv4
+ exit ;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit ;;
+ *:[Mm]orph[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-morphos
+ exit ;;
+ *:OS/390:*:*)
+ echo i370-ibm-openedition
+ exit ;;
+ *:z/VM:*:*)
+ echo s390-ibm-zvmoe
+ exit ;;
+ *:OS400:*:*)
+ echo powerpc-ibm-os400
+ exit ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit ;;
+ arm*:riscos:*:*|arm*:RISCOS:*:*)
+ echo arm-unknown-riscos
+ exit ;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit ;;
+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit ;;
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit ;;
+ DRS?6000:unix:4.0:6*)
+ echo sparc-icl-nx6
+ exit ;;
+ DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+ case `/usr/bin/uname -p` in
+ sparc) echo sparc-icl-nx7; exit ;;
+ esac ;;
+ s390x:SunOS:*:*)
+ echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+ echo i386-pc-auroraux${UNAME_RELEASE}
+ exit ;;
+ i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+ eval $set_cc_for_build
+ SUN_ARCH="i386"
+ # If there is a compiler, see if it is configured for 64-bit objects.
+ # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+ # This test works for both compilers.
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ SUN_ARCH="x86_64"
+ fi
+ fi
+ echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit ;;
+ # The situation for MiNT is a little confusing. The machine name
+ # can be virtually everything (everything which is not
+ # "atarist" or "atariste" at least should have a processor
+ # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
+ # to the lowercase version "mint" (or "freemint"). Finally
+ # the system name "TOS" denotes a system which is actually not
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit ;;
+ m68k:machten:*:*)
+ echo m68k-apple-machten${UNAME_RELEASE}
+ exit ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c &&
+ dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+ SYSTEM_NAME=`$dummy $dummyarg` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit ;;
+ Motorola:PowerMAX_OS:*:*)
+ echo powerpc-motorola-powermax
+ exit ;;
+ Motorola:*:4.3:PL8-*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+ [ ${TARGET_BINARY_INTERFACE}x = x ]
+ then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i*86:AIX:*:*)
+ echo i386-ibm-aix
+ exit ;;
+ ia64:AIX:*:*)
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+ then
+ echo "$SYSTEM_NAME"
+ else
+ echo rs6000-ibm-aix3.2.5
+ fi
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit ;;
+ *:AIX:*:[4567])
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/lslpp ] ; then
+ IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
+ awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit ;;
+ 9000/[34678]??:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/[678][0-9][0-9])
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "${sc_cpu_version}" in
+ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "${sc_kernel_bits}" in
+ 32) HP_ARCH="hppa2.0n" ;;
+ 64) HP_ARCH="hppa2.0w" ;;
+ '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
+ esac ;;
+ esac
+ fi
+ if [ "${HP_ARCH}" = "" ]; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ test -z "$HP_ARCH" && HP_ARCH=hppa
+ fi ;;
+ esac
+ if [ ${HP_ARCH} = "hppa2.0w" ]
+ then
+ eval $set_cc_for_build
+
+ # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+ # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
+ # generating 64-bit code. GNU and HP use different nomenclature:
+ #
+ # $ CC_FOR_BUILD=cc ./config.guess
+ # => hppa2.0w-hp-hpux11.23
+ # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+ # => hppa64-hp-hpux11.23
+
+ if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+ grep -q __LP64__
+ then
+ HP_ARCH="hppa2.0w"
+ else
+ HP_ARCH="hppa64"
+ fi
+ fi
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit ;;
+ ia64:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ia64-hp-hpux${HPUX_REV}
+ exit ;;
+ 3050*:HI-UX:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo unknown-hitachi-hiuxwe2
+ exit ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit ;;
+ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit ;;
+ i*86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+ -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*T3E:*:*:*)
+ echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*SV1:*:*:*)
+ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ *:UNICOS/mp:*:*)
+ echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ 5000:UNIX_System_V:4.*:*)
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:FreeBSD:*:*)
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ case ${UNAME_PROCESSOR} in
+ amd64)
+ echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ *)
+ echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ esac
+ exit ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit ;;
+ *:MINGW64*:*)
+ echo ${UNAME_MACHINE}-pc-mingw64
+ exit ;;
+ *:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit ;;
+ *:MSYS*:*)
+ echo ${UNAME_MACHINE}-pc-msys
+ exit ;;
+ i*:windows32*:*)
+ # uname -m includes "-pc" on this system.
+ echo ${UNAME_MACHINE}-mingw32
+ exit ;;
+ i*:PW*:*)
+ echo ${UNAME_MACHINE}-pc-pw32
+ exit ;;
+ *:Interix*:*)
+ case ${UNAME_MACHINE} in
+ x86)
+ echo i586-pc-interix${UNAME_RELEASE}
+ exit ;;
+ authenticamd | genuineintel | EM64T)
+ echo x86_64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ IA64)
+ echo ia64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ esac ;;
+ [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+ echo i${UNAME_MACHINE}-pc-mks
+ exit ;;
+ 8664:Windows_NT:*)
+ echo x86_64-pc-mks
+ exit ;;
+ i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+ # UNAME_MACHINE based on the output of uname instead of i386?
+ echo i586-pc-interix
+ exit ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
+ exit ;;
+ amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+ echo x86_64-unknown-cygwin
+ exit ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ *:GNU:*:*)
+ # the GNU system
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit ;;
+ *:GNU/*:*:*)
+ # other systems with GNU libc and userland
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
+ exit ;;
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+ exit ;;
+ aarch64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ aarch64_be:Linux:*:*)
+ UNAME_MACHINE=aarch64_be
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ alpha:Linux:*:*)
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+ EV56) UNAME_MACHINE=alphaev56 ;;
+ PCA56) UNAME_MACHINE=alphapca56 ;;
+ PCA57) UNAME_MACHINE=alphapca56 ;;
+ EV6) UNAME_MACHINE=alphaev6 ;;
+ EV67) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+ esac
+ objdump --private-headers /bin/sh | grep -q ld.so.1
+ if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ arc:Linux:*:* | arceb:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ arm*:Linux:*:*)
+ eval $set_cc_for_build
+ if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_EABI__
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ else
+ if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_PCS_VFP
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
+ else
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
+ fi
+ fi
+ exit ;;
+ avr32*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ cris:Linux:*:*)
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ exit ;;
+ crisv32:Linux:*:*)
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ exit ;;
+ frv:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ hexagon:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ i*86:Linux:*:*)
+ echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+ exit ;;
+ ia64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ m32r*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ m68*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ mips:Linux:*:* | mips64:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef ${UNAME_MACHINE}
+ #undef ${UNAME_MACHINE}el
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=${UNAME_MACHINE}el
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=${UNAME_MACHINE}
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
+ ;;
+ openrisc*:Linux:*:*)
+ echo or1k-unknown-linux-${LIBC}
+ exit ;;
+ or32:Linux:*:* | or1k*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ padre:Linux:*:*)
+ echo sparc-unknown-linux-${LIBC}
+ exit ;;
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-${LIBC}
+ exit ;;
+ parisc:Linux:*:* | hppa:Linux:*:*)
+ # Look for CPU level
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+ PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
+ PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
+ *) echo hppa-unknown-linux-${LIBC} ;;
+ esac
+ exit ;;
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-${LIBC}
+ exit ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-${LIBC}
+ exit ;;
+ ppc64le:Linux:*:*)
+ echo powerpc64le-unknown-linux-${LIBC}
+ exit ;;
+ ppcle:Linux:*:*)
+ echo powerpcle-unknown-linux-${LIBC}
+ exit ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+ echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
+ exit ;;
+ sh64*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ sh*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ tile*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ vax:Linux:*:*)
+ echo ${UNAME_MACHINE}-dec-linux-${LIBC}
+ exit ;;
+ x86_64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ xtensa*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ i*86:DYNIX/ptx:4*:*)
+ # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+ # earlier versions are messed up and put the nodename in both
+ # sysname and nodename.
+ echo i386-sequent-sysv4
+ exit ;;
+ i*86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit ;;
+ i*86:OS/2:*:*)
+ # If we were able to find `uname', then EMX Unix compatibility
+ # is probably installed.
+ echo ${UNAME_MACHINE}-pc-os2-emx
+ exit ;;
+ i*86:XTS-300:*:STOP)
+ echo ${UNAME_MACHINE}-unknown-stop
+ exit ;;
+ i*86:atheos:*:*)
+ echo ${UNAME_MACHINE}-unknown-atheos
+ exit ;;
+ i*86:syllable:*:*)
+ echo ${UNAME_MACHINE}-pc-syllable
+ exit ;;
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ i*86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit ;;
+ i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+ UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ fi
+ exit ;;
+ i*86:*:5:[678]*)
+ # UnixWare 7.x, OpenUNIX and OpenServer 6.
+ case `/bin/uname -X | grep "^Machine"` in
+ *486*) UNAME_MACHINE=i486 ;;
+ *Pentium) UNAME_MACHINE=i586 ;;
+ *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+ esac
+ echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ exit ;;
+ i*86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit ;;
+ pc:*:*:*)
+ # Left here for compatibility:
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i586.
+ # Note: whatever this is, it MUST be the same as what config.sub
+ # prints for the "djgpp" host, or else GDB configury will decide that
+ # this is a cross-build.
+ echo i586-pc-msdosdjgpp
+ exit ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit ;;
+ mc68k:UNIX:SYSTEM5:3.51m)
+ echo m68k-convergent-sysv
+ exit ;;
+ M680?0:D-NIX:5.3:*)
+ echo m68k-diab-dnix
+ exit ;;
+ M68*:*:R3V[5678]*:*)
+ test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+ 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4; exit; } ;;
+ NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+ OS_REL='.3'
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ rs6000:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
+ echo powerpc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit ;;
+ i*86:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo ${UNAME_MACHINE}-stratus-vos
+ exit ;;
+ *:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo hppa1.1-stratus-vos
+ exit ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit ;;
+ news*:NEWS-OS:6*:*)
+ echo mips-sony-newsos6
+ exit ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit ;;
+ BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
+ echo i586-pc-haiku
+ exit ;;
+ x86_64:Haiku:*:*)
+ echo x86_64-unknown-haiku
+ exit ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-6:SUPER-UX:*:*)
+ echo sx6-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-7:SUPER-UX:*:*)
+ echo sx7-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8:SUPER-UX:*:*)
+ echo sx8-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8R:SUPER-UX:*:*)
+ echo sx8r-nec-superux${UNAME_RELEASE}
+ exit ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Darwin:*:*)
+ UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+ eval $set_cc_for_build
+ if test "$UNAME_PROCESSOR" = unknown ; then
+ UNAME_PROCESSOR=powerpc
+ fi
+ if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ case $UNAME_PROCESSOR in
+ i386) UNAME_PROCESSOR=x86_64 ;;
+ powerpc) UNAME_PROCESSOR=powerpc64 ;;
+ esac
+ fi
+ fi
+ elif test "$UNAME_PROCESSOR" = i386 ; then
+ # Avoid executing cc on OS X 10.9, as it ships with a stub
+ # that puts up a graphical alert prompting to install
+ # developer tools. Any system running Mac OS X 10.7 or
+ # later (Darwin 11 and later) is required to have a 64-bit
+ # processor. This is not true of the ARM version of Darwin
+ # that Apple uses in portable devices.
+ UNAME_PROCESSOR=x86_64
+ fi
+ echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ exit ;;
+ *:procnto*:*:* | *:QNX:[0123456789]*:*)
+ UNAME_PROCESSOR=`uname -p`
+ if test "$UNAME_PROCESSOR" = "x86"; then
+ UNAME_PROCESSOR=i386
+ UNAME_MACHINE=pc
+ fi
+ echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+ exit ;;
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit ;;
+ NEO-?:NONSTOP_KERNEL:*:*)
+ echo neo-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSE-*:NONSTOP_KERNEL:*:*)
+ echo nse-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSR-?:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ *:NonStop-UX:*:*)
+ echo mips-compaq-nonstopux
+ exit ;;
+ BS2000:POSIX*:*:*)
+ echo bs2000-siemens-sysv
+ exit ;;
+ DS/*:UNIX_System_V:*:*)
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+ exit ;;
+ *:Plan9:*:*)
+ # "uname -m" is not consistent, so use $cputype instead. 386
+ # is converted to i386 for consistency with other x86
+ # operating systems.
+ if test "$cputype" = "386"; then
+ UNAME_MACHINE=i386
+ else
+ UNAME_MACHINE="$cputype"
+ fi
+ echo ${UNAME_MACHINE}-unknown-plan9
+ exit ;;
+ *:TOPS-10:*:*)
+ echo pdp10-unknown-tops10
+ exit ;;
+ *:TENEX:*:*)
+ echo pdp10-unknown-tenex
+ exit ;;
+ KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+ echo pdp10-dec-tops20
+ exit ;;
+ XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+ echo pdp10-xkl-tops20
+ exit ;;
+ *:TOPS-20:*:*)
+ echo pdp10-unknown-tops20
+ exit ;;
+ *:ITS:*:*)
+ echo pdp10-unknown-its
+ exit ;;
+ SEI:*:*:SEIUX)
+ echo mips-sei-seiux${UNAME_RELEASE}
+ exit ;;
+ *:DragonFly:*:*)
+ echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit ;;
+ *:*VMS:*:*)
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ case "${UNAME_MACHINE}" in
+ A*) echo alpha-dec-vms ; exit ;;
+ I*) echo ia64-dec-vms ; exit ;;
+ V*) echo vax-dec-vms ; exit ;;
+ esac ;;
+ *:XENIX:*:SysV)
+ echo i386-pc-xenix
+ exit ;;
+ i*86:skyos:*:*)
+ echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+ exit ;;
+ i*86:rdos:*:*)
+ echo ${UNAME_MACHINE}-pc-rdos
+ exit ;;
+ i*86:AROS:*:*)
+ echo ${UNAME_MACHINE}-pc-aros
+ exit ;;
+ x86_64:VMkernel:*:*)
+ echo ${UNAME_MACHINE}-unknown-esx
+ exit ;;
+esac
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+and
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo = `(hostinfo) 2>/dev/null`
+/bin/universe = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/support/dktools/config.h.in b/support/dktools/config.h.in
new file mode 100644
index 0000000000..e12e8d3030
--- /dev/null
+++ b/support/dktools/config.h.in
@@ -0,0 +1,1334 @@
+/** @file config.h Configure script constant names.
+
+ALL NAMES LISTED HERE MUST ALSO BE DEFINED IN THE win32/dk4conf.h FILE!
+=======================================================================
+The win32/dk4conf.h is used on systems where the configure script
+can not be run.
+
+*/
+
+#ifndef CONFIG_H_INCLUDED
+/** Protection against multiple inclusion.
+*/
+#define CONFIG_H_INCLUDED 1
+
+/** The inline keyword for the C programming language.
+ Only set if both: (1) the keyword is available and
+ (2) enabled by --enable-inline in the configure script.
+*/
+#define HAVE_INLINE 0
+
+/** Net-SNMP library.
+*/
+#define HAVE_LIBNETSNMP 0
+
+/** Enable file log function in Net-SNMP
+*/
+#define HAVE_SNMP_ENABLE_FILELOG 0
+
+/** Disable logging to syslog.
+*/
+#define HAVE_SNMP_DISABLE_SYSLOG 0
+
+/** Disable logging to stderr.
+*/
+#define HAVE_SNMP_DISABLE_STDERRLOG 0
+
+/** Disable logging to file.
+*/
+#define HAVE_SNMP_DISABLE_FILELOG 0
+
+/** Error codes.
+*/
+#define HAVE_ERRNO_H 0
+
+/** Declarations for functions on UNIX/POSIX systems.
+*/
+#define HAVE_UNISTD_H 0
+
+/** The process.h file declares the exit() function on Windows systems.
+*/
+#define HAVE_PROCESS_H 0
+
+/** Character classification.
+*/
+#define HAVE_CTYPE_H 0
+
+/** Unicode character data type.
+*/
+#define HAVE_UCHAR_H 0
+
+/** Wide character data type.
+*/
+#define HAVE_WCHAR_H 0
+
+/** Wide character classification.
+*/
+#define HAVE_WCTYPE_H 0
+
+/** Integer types up to maximum size.
+*/
+#define HAVE_STDINT_H 0
+
+/** Integer types in different sizes.
+*/
+#define HAVE_INTTYPES_H 0
+
+/** Limits for different integer types.
+*/
+#define HAVE_LIMITS_H 0
+
+/** String functions.
+*/
+#define HAVE_STRING_H 0
+
+/** Source code assertion.
+*/
+#define HAVE_ASSERT_H 0
+
+/** Signal handling.
+*/
+#define HAVE_SIGNAL_H 0
+
+/** Mathematic functions and constants.
+*/
+#define HAVE_MATH_H 0
+
+/** Floating point status word, exceptions, setup.
+*/
+#define HAVE_FENV_H 0
+
+/** Floating point calculations.
+*/
+#define HAVE_FLOAT_H 0
+
+/** Complex numbers.
+*/
+#define HAVE_COMPLEX_H 0
+
+/** Date and time.
+*/
+#define HAVE_TIME_H 0
+
+/** Jump buffers for horrible error handling.
+*/
+#define HAVE_SETJMP_H 0
+
+/** Locale settings.
+*/
+#define HAVE_LOCALE_H 0
+
+/** Unkown.
+*/
+#define HAVE_ISO646_H 0
+
+/** Unknown.
+*/
+#define HAVE_STDALIGN_H 0
+
+/** Function argument processing.
+*/
+#define HAVE_STDARG_H 0
+
+/** Unknown.
+*/
+#define HAVE_STDATOMIC_H 0
+
+/** Definition of boolean type.
+*/
+#define HAVE_STDBOOL_H 0
+
+/** Unknown.
+*/
+#define HAVE_STDDEF_H 0
+
+/** Unknown.
+*/
+#define HAVE_STDNORETURN_H 0
+
+/** Standard library.
+*/
+#define HAVE_STDLIB_H 0
+
+/** Type generic mathematics.
+*/
+#define HAVE_TGMATH_H 0
+
+/** Threads, not standard yet.
+*/
+#define HAVE_THREADS_H 0
+
+/** Data type definitions.
+*/
+#define HAVE_SYS_TYPES_H 0
+
+/** Socket functions.
+*/
+#define HAVE_SYS_SOCKET_H 0
+
+#define HAVE_SYS_UN_H 0
+
+/** The select() function.
+*/
+#define HAVE_SYS_SELECT_H 0
+
+#define HAVE_NETINET_IN_H 0
+
+#define HAVE_NETINET_IN6_H 0
+
+#define HAVE_NETDB_H 0
+
+#define HAVE_ARPA_INET_H 0
+
+/** Get user info.
+*/
+#define HAVE_PWD_H 0
+
+/** Get group info.
+*/
+#define HAVE_GRP_H 0
+
+/**
+*/
+#define HAVE_SYS_PARAM_H 0
+
+/** File and file systems statistics.
+*/
+#define HAVE_SYS_STAT_H 0
+
+/** Time handling functions.
+*/
+#define HAVE_SYS_TIME_H 0
+
+/** Further string functions on some systems.
+*/
+#define HAVE_STRINGS_H 0
+
+/** Input and output functions on Windows systems.
+*/
+#define HAVE_IO_H 0
+
+/** File control functions.
+*/
+#define HAVE_FCNTL_H 0
+
+/** File share modes.
+*/
+#define HAVE_SHARE_H 0
+
+/** Access BIOS functions.
+*/
+#define HAVE_BIOS_H 0
+
+/** DOS related things on Windows.
+*/
+#define HAVE_DOS_H 0
+
+/** Memory allocation functions.
+*/
+#define HAVE_ALLOC_H 0
+
+/** Memory allocation functions.
+*/
+#define HAVE_MALLOC_H 0
+
+/** Linux and Unix directory traversal.
+*/
+#define HAVE_DIRENT_H 0
+
+#define HAVE_WINDOWS_H 0
+
+#define HAVE_WINSOCK2_H 0
+
+#define HAVE_WS2TCPIP_H 0
+
+/** Windows functions for directory handling.
+*/
+#define HAVE_DIRECT_H 0
+
+/** zlib compression library.
+*/
+#define HAVE_ZLIB_H 0
+
+/** bzip2 compression library.
+*/
+#define HAVE_BZLIB_H 0
+
+/** OpenSSL library, random number generator.
+*/
+#define HAVE_OPENSSL_RAND_H 0
+
+/** OpenSSL library, MD5 message digest.
+*/
+#define HAVE_OPENSSL_MD5_H 0
+
+/** OpenSSL library, SHA-1 and others.
+*/
+#define HAVE_OPENSSL_SHA_H 0
+
+/** OpenSSL library, RIPEMD-160 message digest.
+*/
+#define HAVE_OPENSSL_RIPEMD_H 0
+
+/** Berkeley DB
+*/
+#define HAVE_DB_H 0
+
+/** NDBM database.
+*/
+#define HAVE_NDBM_H 0
+
+/** Include file ntifs.h
+*/
+#define HAVE_NTIFS_H 0
+
+/** wxWidgets library.
+*/
+#define HAVE_WXWIDGETS 0
+
+/** Size of long long data type.
+*/
+#define HAVE_LONG_LONG 0
+
+/** Test: Have long double.
+*/
+#define HAVE_LONG_DOUBLE 0
+
+/** Test: Have intmax_t.
+*/
+#define HAVE_INTMAX_T 0
+
+/** Test: Keyword volatile.
+*/
+#define HAVE_VOLATILE 0
+
+/** Test: Data type sig_atomic_t.
+*/
+#define HAVE_SIG_ATOMIC_T 0
+
+/** Size of short data type.
+*/
+#define SIZEOF_SHORT 0
+
+/** Size of int data type.
+*/
+#define SIZEOF_INT 0
+
+/** Size of size_t data type.
+*/
+#define SIZEOF_SIZE_T 0
+
+/** Size of long data type.
+*/
+#define SIZEOF_LONG 0
+
+/** Size of long long data type.
+*/
+#define SIZEOF_LONG_LONG 0
+
+/** Size of intmax_t data type.
+*/
+#define SIZEOF_INTMAX_T 0
+
+/** Size of double data type.
+*/
+#define SIZEOF_DOUBLE 0
+
+/** Size of long double data type.
+*/
+#define SIZEOF_LONG_DOUBLE 0
+
+/** Size of wchar_t data type.
+*/
+#define SIZEOF_WCHAR_T 0
+
+/** Size of off_t data type.
+*/
+#define SIZEOF_OFF_T 0
+
+/** Size of ino_t data type.
+*/
+#define SIZEOF_INO_T 0
+
+/** Size of off64_t data type.
+*/
+#define SIZEOF_OFF64_T 0
+
+/** Size of ino64_t data type.
+*/
+#define SIZEOF_INO64_T 0
+
+/** Flag: Use time.h and sys/time.h together.
+*/
+#define TIME_WITH_SYS_TIME 0
+
+/** Bigendian byte order.
+*/
+#define WORDS_BIGENDIAN 0
+
+/** Function memset() available.
+*/
+#define HAVE_MEMSET 0
+
+/** Function bzero() available.
+*/
+#define HAVE_BZERO 0
+
+/** Function memcpy() available.
+*/
+#define HAVE_MEMCPY 0
+
+/** Function bcopy() available.
+*/
+#define HAVE_BCOPY 0
+
+/** Function memcmp() available.
+*/
+#define HAVE_MEMCMP 0
+
+/** Function bcmp() available.
+*/
+#define HAVE_BCMP 0
+
+/** Function malloc() available.
+*/
+#define HAVE_MALLOC 0
+
+/** Function calloc().
+*/
+#define HAVE_CALLOC 0
+
+/** Function free().
+*/
+#define HAVE_FREE 0
+
+/** Function strcpy_s().
+*/
+#define HAVE_STRCPY_S 0
+
+/** Function strcat_s().
+*/
+#define HAVE_STRCAT_S 0
+
+/** Function strcasecmp().
+*/
+#define HAVE_STRCASECMP 0
+
+/** Function stricmp().
+*/
+#define HAVE_STRICMP 0
+
+/** Function _stricmp().
+*/
+#define HAVE__STRICMP 0
+
+/** Function wcslen().
+*/
+#define HAVE_WCSLEN 0
+
+/** Function wcscpy_s().
+*/
+#define HAVE_WCSCPY_S 0
+
+/** Function wcscpy().
+*/
+#define HAVE_WCSCPY 0
+
+/** Function wcscat_s().
+*/
+#define HAVE_WCSCAT_S 0
+
+/** Function wcscat().
+*/
+#define HAVE_WCSCAT 0
+
+/** Function wcschr().
+*/
+#define HAVE_WCSCHR 0
+
+/** Function wcsrchr().
+*/
+#define HAVE_WCSRCHR 0
+
+/** Function wcscmp().
+*/
+#define HAVE_WCSCMP 0
+
+/** Function _wcscmp().
+*/
+#define HAVE__WCSCMP 0
+
+/** Function wcsncmp().
+*/
+#define HAVE_WCSNCMP 0
+
+/** Function _wcsncmp().
+*/
+#define HAVE__WCSNCMP 0
+
+/** Function wcscasecmp().
+*/
+#define HAVE_WCSCASECMP 0
+
+/** Function _wcscasecmp().
+*/
+#define HAVE__WCSCASECMP 0
+
+/** Function wcsicmp().
+*/
+#define HAVE_WCSICMP 0
+
+/** Function _wcsicmp().
+*/
+#define HAVE__WCSICMP 0
+
+/** Function getpid().
+*/
+#define HAVE_GETPID 0
+
+/** Function readlink().
+*/
+#define HAVE_READLINK 0
+
+/** Facility to retrieve executable file name via /proc/.../exe file.
+*/
+#define HAVE_PROC_PID_EXE 0
+
+/** Function getexecname().
+*/
+#define HAVE_GETEXECNAME 0
+
+/** Function lstat().
+*/
+#define HAVE_LSTAT 0
+
+/** Function stat64().
+*/
+#define HAVE_STAT64 0
+
+/** Function lstat64().
+*/
+#define HAVE_LSTAT64 0
+
+/** Function localtime_r().
+*/
+#define HAVE_LOCALTIME_R 0
+
+/** Function geteuid().
+*/
+#define HAVE_GETEUID 0
+
+/** Function fopen64().
+*/
+#define HAVE_FOPEN64 0
+
+/** Function fopen_s().
+*/
+#define HAVE_FOPEN_S 0
+
+/** Function _wfopen().
+*/
+#define HAVE__WFOPEN 0
+
+/** Function _wfopen64().
+*/
+#define HAVE__WFOPEN64 0
+
+/** Function _wfopen_s().
+*/
+#define HAVE__WFOPEN_S 0
+
+/** Function fputws().
+*/
+#define HAVE_FPUTWS 0
+
+/** Function fputwc().
+*/
+#define HAVE_FPUTWC 0
+
+/** Function setbuffer().
+*/
+#define HAVE_SETBUFFER 0
+
+/** Function setbuf().
+*/
+#define HAVE_SETBUF 0
+
+/** Function fileno().
+*/
+#define HAVE_FILENO 0
+
+/** Function _fileno().
+*/
+#define HAVE__FILENO 0
+
+/** Function setmode().
+*/
+#define HAVE_SETMODE 0
+
+/** Function _setmode().
+*/
+#define HAVE__SETMODE 0
+
+/** Function isatty().
+*/
+#define HAVE_ISATTY 0
+
+/** Function _isatty().
+*/
+#define HAVE__ISATTY 0
+
+/** Function strtod().
+*/
+#define HAVE_STRTOD 0
+
+/** Function _strtod().
+*/
+#define HAVE__STRTOD 0
+
+/** Function wcstod().
+*/
+#define HAVE_WCSTOD 0
+
+/** Function _wcstod().
+*/
+#define HAVE__WCSTOD 0
+
+/** Function _snprintf_s().
+*/
+#define HAVE__SNPRINTF_S 0
+
+/** Function _snprintf().
+*/
+#define HAVE__SNPRINTF 0
+
+/** Function snprintf().
+*/
+#define HAVE_SNPRINTF 0
+
+/** Function _snwprintf_s().
+*/
+#define HAVE__SNWPRINTF_S 0
+
+/** Function _snwprintf().
+*/
+#define HAVE__SNWPRINTF 0
+
+/** Function snwprintf().
+*/
+#define HAVE_SNWPRINTF 0
+
+/** Function swprintf().
+*/
+#define HAVE_SWPRINTF 0
+
+/** Function unlink().
+*/
+#define HAVE_UNLINK 0
+
+/** Function _unlink().
+*/
+#define HAVE__UNLINK 0
+
+/** Function wunlink().
+*/
+#define HAVE_WUNLINK 0
+
+/** Function _wunlink().
+*/
+#define HAVE__WUNLINK 0
+
+/** Function rmdir().
+*/
+#define HAVE_RMDIR 0
+
+/** Function _rmdir().
+*/
+#define HAVE__RMDIR 0
+
+/** Function wrmdir().
+*/
+#define HAVE_WRMDIR 0
+
+/** Function _wrmdir().
+*/
+#define HAVE__WRMDIR 0
+
+/** Function mkdir().
+*/
+#define HAVE_MKDIR 0
+
+/** Function _mkdir().
+*/
+#define HAVE__MKDIR 0
+
+/** Function wmkdir().
+*/
+#define HAVE_WMKDIR 0
+
+/** Function _wmkdir().
+*/
+#define HAVE__WMKDIR 0
+
+/** Function sigaction().
+*/
+#define HAVE_SIGACTION 0
+
+/** Function sigset().
+*/
+#define HAVE_SIGSET 0
+
+/** Function signal().
+*/
+#define HAVE_SIGNAL 0
+
+/** Function sigprocmask().
+*/
+#define HAVE_SIGPROCMASK 0
+
+/** Function sigemtpyset().
+*/
+#define HAVE_SIGEMPTYSET 0
+
+/** Function setpwent().
+*/
+#define HAVE_SETPWENT 0
+
+/** Function getpwent().
+*/
+#define HAVE_GETPWENT 0
+
+/** Function endpwent().
+*/
+#define HAVE_ENDPWENT 0
+
+/** Function getpwnam().
+*/
+#define HAVE_GETPWNAM 0
+
+/** Function getpwuid().
+*/
+#define HAVE_GETPWUID 0
+
+/** Function setgrent().
+*/
+#define HAVE_SETGRENT 0
+
+/** Function getgrent().
+*/
+#define HAVE_GETGRENT 0
+
+/** Function getgrgid().
+*/
+#define HAVE_GETGRGID 0
+
+/** Function getgrnam().
+*/
+#define HAVE_GETGRNAM 0
+
+/** Function endgrent().
+*/
+#define HAVE_ENDGRENT 0
+
+/** Function strerror().
+*/
+#define HAVE_STRERROR 0
+
+/** Function strerror_r().
+*/
+#define HAVE_STRERROR_R 0
+
+/** Function rand().
+*/
+#define HAVE_RAND 0
+
+/** Function srand().
+*/
+#define HAVE_SRAND 0
+
+/** Function initstate().
+*/
+#define HAVE_INITSTATE 0
+
+/** Function setstate().
+*/
+#define HAVE_SETSTATE 0
+
+/** Function random().
+*/
+#define HAVE_RANDOM 0
+
+/** Function nrand48().
+*/
+#define HAVE_NRAND48 0
+
+/** Function lrand48().
+*/
+#define HAVE_LRAND48 0
+
+/** Function socket().
+*/
+#define HAVE_SOCKET 0
+
+/** Function getenv().
+*/
+#define HAVE_GETENV 0
+
+/** Function getenv_s().
+*/
+#define HAVE_GETENV_S 0
+
+/** Function setlocale().
+*/
+#define HAVE_SETLOCALE 0
+
+/** Function select().
+*/
+#define HAVE_SELECT 0
+
+/** Function inet_addr().
+*/
+#define HAVE_INET_ADDR 0
+
+/** Function inet_aton().
+*/
+#define HAVE_INET_ATON 0
+
+/** Function inet_pton().
+*/
+#define HAVE_INET_PTON 0
+
+/** Function inet_ntop
+*/
+#define HAVE_INET_NTOP 0
+
+/** Function setsockopt().
+*/
+#define HAVE_SETSOCKOPT 0
+
+/** Function getaddrinfo().
+*/
+#define HAVE_GETADDRINFO 0
+
+/** Function getnameinfo().
+*/
+#define HAVE_GETNAMEINFO 0
+
+/** Function gethostbyname().
+*/
+#define HAVE_GETHOSTBYNAME 0
+
+/** Function htons().
+*/
+#define HAVE_HTONS 0
+
+/** Function ntohs().
+*/
+#define HAVE_NTOHS 0
+
+/** Function htonl().
+*/
+#define HAVE_HTONL 0
+
+/** Function ntohl().
+*/
+#define HAVE_NTOHL 0
+
+/** Function _getcwd().
+*/
+#define HAVE__GETCWD 0
+
+/** Function _wgetcwd().
+*/
+#define HAVE__WGETCWD 0
+
+/** Function getcwd().
+*/
+#define HAVE_GETCWD 0
+
+/** Function GetFinalPathNameByHandle().
+*/
+#define HAVE_GETFINALPATHNAMEBYHANDLE 0
+
+/** Function db_cursor_c_get().
+*/
+#define HAVE_DB_CURSOR_C_GET 0
+
+/** Function chmod().
+*/
+#define HAVE_CHMOD 0
+
+/** Function chown().
+*/
+#define HAVE_CHOWN 0
+
+/** Function setvbuf().
+*/
+#define HAVE_SETVBUF 0
+
+/** Makro isfinite().
+*/
+#define HAVE_ISFINITE 0
+
+/** Makro isnormal().
+*/
+#define HAVE_ISNORMAL 0
+
+/** Makro _finite().
+*/
+#define HAVE__FINITE 0
+
+/** Data type and functions for SHA-224 in OpenSSL.
+*/
+#define HAVE_SHA224 0
+
+/** Data type and functions for SHA-256 in OpenSSL.
+*/
+#define HAVE_SHA256 0
+
+/** Data type and functions for SHA-384 in OpenSSL.
+*/
+#define HAVE_SHA384 0
+
+/** Data type and functions for SHA-512 in OpenSSL.
+*/
+#define HAVE_SHA512 0
+
+/** Function RAND_egd().
+*/
+#define HAVE_RAND_EGD 0
+
+/** Data type int8_t.
+*/
+#define HAVE_INT8_T 0
+
+/** Data type int16_t.
+*/
+#define HAVE_INT16_T 0
+
+/** Data type int32_t.
+*/
+#define HAVE_INT32_T 0
+
+/** Data type uint8_t.
+*/
+#define HAVE_UINT8_T 0
+
+/** Data type uint16_t.
+*/
+#define HAVE_UINT16_T 0
+
+/** Data type uint32_t.
+*/
+#define HAVE_UINT32_T 0
+
+/** Data type ssize_t.
+*/
+#define HAVE_SSIZE_T 0
+
+/** Data type dev_t.
+*/
+#define HAVE_DEV_T 0
+
+/** Data type _dev_t.
+*/
+#define HAVE__DEV_T 0
+
+/** Data type ino_t.
+*/
+#define HAVE_INO_T 0
+
+/** Data type _ino_t.
+*/
+#define HAVE__INO_T 0
+
+/** Data type ino64_t.
+*/
+#define HAVE_INO64_T 0
+
+/** Data type _ino64_t.
+*/
+#define HAVE__INO64_T 0
+
+/** Data type mode_t.
+*/
+#define HAVE_MODE_T 0
+
+/** Data type nlink_t.
+*/
+#define HAVE_NLINK_T 0
+
+/** Data type uid_t.
+*/
+#define HAVE_UID_T 0
+
+/** Data type gid_t.
+*/
+#define HAVE_GID_T 0
+
+/** Data type off_t.
+*/
+#define HAVE_OFF_T 0
+
+/** Data type _off_t.
+*/
+#define HAVE__OFF_T 0
+
+/** Data type off64_t.
+*/
+#define HAVE_OFF64_T 0
+
+/** Data type _off64_t.
+*/
+#define HAVE__OFF64_T 0
+
+/** Data type blksize_t.
+*/
+#define HAVE_BLKSIZE_T 0
+
+/** Data type blkcnt_t.
+*/
+#define HAVE_BLKCNT_T 0
+
+/** Data type fpos_t.
+*/
+#define HAVE_FPOS_T 0
+
+/** Data type _fpos_t.
+*/
+#define HAVE__FPOS_T 0
+
+/** Data type socklen_t.
+*/
+#define HAVE_SOCKLEN_T 0
+
+/** Data type struct sockaddr_in.
+*/
+#define HAVE_STRUCT_SOCKADDR_IN 0
+
+/** Data type struct sockaddr_in6.
+*/
+#define HAVE_STRUCT_SOCKADDR_IN6 0
+
+/** Data type struct sockaddr_un.
+*/
+#define HAVE_STRUCT_SOCKADDR_UN 0
+
+/** Data type struct addrinfo.
+*/
+#define HAVE_STRUCT_ADDRINFO 0
+
+/** Data t ype struct sockaddr_storage.
+*/
+#define HAVE_STRUCT_SOCKADDR_STORAGE 0
+
+/** Typedef IN_ADDR.
+*/
+#define HAVE_IN_ADDR 0
+
+/** Typedef IN6_ADDR.
+*/
+#define HAVE_IN6_ADDR 0
+
+/** Data type struct stat64.
+*/
+#define HAVE_TYPE_STAT64 0
+
+/** Use large file functions to process files.
+*/
+#define HAVE_LARGEFILE64_SOURCE 0
+
+/** Feature: If minimum/maximum definitions for integral data
+ types are missing, use builtin defaults.
+*/
+#define USE_FALLBACK_NUMERIC_LIMITS 0
+
+/** Feature: Use LocalAlloc()/LocalFree() on Windows.
+*/
+#define USE_WINDOWS_LOCAL_ALLOC 0
+
+/** Feature: Path components are separated by backslash.
+*/
+#define HAVE_BACKSLASH_AS_SEP 0
+
+/** Feature: DOS/Windows line ends consisting of carriage return and
+ newline.
+*/
+#define HAVE_LINE_END_CR_NL 0
+
+/** Feature: Path names are case insensitive.
+*/
+#define HAVE_CASE_INSENSITIVE_PATHNAMES 0
+
+/** Feature: User names are case insensitive.
+*/
+#define HAVE_CASE_INSENSITIVE_USERNAMES 0
+
+/** Feature: Device and inode number in stat() results have
+ useful contents.
+*/
+#define HAVE_FILE_DEVINO 0
+
+/** Feature: Uid and gid numbers in stat() results have
+ useful contents.
+*/
+#define HAVE_FILE_UIDGID 0
+
+/** Feature: Block size and count in stat() results have useful contents.
+*/
+#define HAVE_FILE_BLKSIZECNT 0
+
+/** Feature: access and modification timestamps in stat() results
+ have useful contents.
+*/
+#define HAVE_FILE_ATIMECTIME 0
+
+/** Feature: Distinction between text and binary mode for files.
+*/
+#define HAVE_FILEMODE_BINARY 0
+
+/** Feature: Use printf()/scanf() function families.
+*/
+#define USE_PRINTF_SCANF 0
+
+/** Feature: Compatible configuration file search.
+*/
+#define HAVE_COMPATDKTOOLS3 0
+
+/** Function setuid().
+*/
+#define HAVE_SETUID 0
+
+/** Function setgid().
+*/
+#define HAVE_SETGID 0
+
+/** Function setpgrp().
+*/
+#define HAVE_SETPGRP 0
+
+/** Function setsid().
+*/
+#define HAVE_SETSID 0
+
+/** Include file sys/resource.h.
+*/
+#define HAVE_SYS_RESOURCE_H 0
+
+/** Function getrlimit().
+*/
+#define HAVE_GETRLIMIT 0
+
+/** Function set syslog.
+*/
+#define HAVE_SYSLOG 0
+
+/** Include file syslog.h
+*/
+#define HAVE_SYSLOG_H 0
+
+/** Function _read().
+*/
+#define HAVE__READ 0
+
+/** Function _write().
+*/
+#define HAVE__WRITE 0
+
+/** Function read().
+*/
+#define HAVE_READ 0
+
+/** Function write().
+*/
+#define HAVE_WRITE 0
+
+/** Function have_png_get_pixels_per_inch().
+*/
+#define HAVE_PNG_GET_PIXELS_PER_INCH 0
+
+/** Header file png.h.
+*/
+#define HAVE_PNG_H 0
+
+/** Header file jpeglib.h.
+*/
+#define HAVE_JPEGLIB_H 0
+
+/** Header file tiff.h.
+*/
+#define HAVE_TIFF_H 0
+
+/*
+ Backward compatibility section start
+*/
+
+#define HAVE_ACOSH 0
+#define HAVE_ACOSHL 0
+#define HAVE_ACOSL 0
+#define HAVE_ASINH 0
+#define HAVE_ASINHL 0
+#define HAVE_ASINL 0
+#define HAVE_ATAN2 0
+#define HAVE_ATAN2L 0
+#define HAVE_ATANH 0
+#define HAVE_ATANHL 0
+#define HAVE_ATANL 0
+#define HAVE_BACKSLASH 0
+#define HAVE_CEIL 0
+#define HAVE_CEILL 0
+#define HAVE_CHDIR 0
+#define HAVE_CLOSEDIR 0
+#define HAVE_CONIO_H 0
+#define HAVE_CONST 0
+#define HAVE_COSHL 0
+#define HAVE_COSL 0
+#define HAVE_DEV_RANDOM 0
+#define HAVE_DEV_URANDOM 0
+#define HAVE_DIR_H 0
+#define HAVE_ERR_H 0
+#define HAVE_EXPL 0
+#define HAVE_FABS 0
+#define HAVE_FABSL 0
+#define HAVE_FCLOSE 0
+#define HAVE_FEOF 0
+#define HAVE_FERROR 0
+#define HAVE_FETESTEXCEPT 0
+#define HAVE_FFLUSH 0
+#define HAVE_FLOOR 0
+#define HAVE_FLOORL 0
+#define HAVE_FNCASEINS 0
+#define HAVE_FOPEN 0
+#define HAVE_FORK 0
+#define HAVE_FPCLASSIFY 0
+#define HAVE_FREAD 0
+#define HAVE_FWRITE 0
+#define HAVE_GDBM_H 0
+#define HAVE_GETHOSTNAME 0
+#define HAVE_GETPEERNAME 0
+#define HAVE_GETSOCKNAME 0
+#define HAVE_GETUID 0
+#define HAVE_IEEE_754_DOUBLE 0
+#define HAVE_INODES 0
+#define HAVE_LABS 0
+#define HAVE_LOCALTIME 0
+#define HAVE_LOCALTIME_S 0
+#define HAVE_LOGL 0
+#define HAVE_LPRNG_H 0
+#define HAVE_LSTAT32 0
+#define HAVE_MKDIR2 0
+#define HAVE_MPCTL 0
+#define HAVE_MYSQL_LIBRARY_END 0
+#define HAVE_MYSQL_LIBRARY_INIT 0
+#define HAVE_MYSQL_MYSQL_H 0
+#define HAVE_MYSQL_H 0
+#define HAVE_MYSQL_SET_CHARACTER_SET 0
+#define HAVE_OPENDIR 0
+#define HAVE_POPEN 0
+#define HAVE_PTHREAD_H 0
+#define HAVE_READDIR 0
+#define HAVE_RFC_2249 0
+#define HAVE_RINT 0
+#define HAVE_RINTL 0
+#define HAVE_SEED48 0
+#define HAVE_SHADOW_H 0
+#define HAVE_SINHL 0
+#define HAVE_SINL 0
+#define HAVE_SPRINTF_S 0
+#define HAVE_SQRT 0
+#define HAVE_SQRTL 0
+#define HAVE_SSCANF_S 0
+#define HAVE_STAT 0
+#define HAVE_STAT32 0
+#define HAVE_STDIO_H 0
+#define HAVE_STRCAT 0
+#define HAVE_STRCHR 0
+#define HAVE_STRCMP 0
+#define HAVE_STRCPY 0
+#define HAVE_STRDUP 0
+#define HAVE_STRLEN 0
+#define HAVE_STRNCMP 0
+#define HAVE_STRNCPY 0
+#define HAVE_STRNCPY_S 0
+#define HAVE_STROPTS_H 0
+#define HAVE_STRRCHR 0
+#define HAVE_STRTOIMAX 0
+#define HAVE_STRTOL 0
+#define HAVE_STRTOLL 0
+#define HAVE_STRTOUL 0
+#define HAVE_STRTOULL 0
+#define HAVE_STRTOUMAX 0
+#define HAVE_SWSCANF_S 0
+#define HAVE_SYSCONF 0
+#define HAVE_SYSCTL 0
+#define HAVE_SYSRES_H 0
+#define HAVE_SYS_FILE_H 0
+#define HAVE_SYS_STATVFS_H 0
+#define HAVE_SYS_STROPTS_H 0
+#define HAVE_SYS_SUNDDI_H 0
+#define HAVE_SYS_SYSCTL_H 0
+#define HAVE_SYS_SYSTEMINFO_H 0
+#define HAVE_SYS_TERMIOS_H 0
+#define HAVE_SYS_TTOLD_H 0
+#define HAVE_SYS_UIO_H 0
+#define HAVE_SYS_WAIT_H 0
+#define HAVE_TANHL 0
+#define HAVE_TANL 0
+#define HAVE_TCFLUSH 0
+#define HAVE_TCGETATTR 0
+#define HAVE_TERMIOS_H 0
+#define HAVE_TIME 0
+#define HAVE_TWOS_COMPLEMENT 0
+#define HAVE_UMASK 0
+#define HAVE_USER_NAMES_CASE_INSENSITIVE 0
+#define HAVE_VARARGS_H 0
+#define HAVE_VARARG_H 0
+#define HAVE_WCHAR_T 0
+#define HAVE_WCSDUP 0
+#define HAVE_WCSNCPY 0
+#define HAVE_WCSNCPY_S 0
+#define HAVE_WCSTOIMAX 0
+#define HAVE_WCSTOL 0
+#define HAVE_WCSTOLL 0
+#define HAVE_WCSTOUL 0
+#define HAVE_WCSTOULL 0
+#define HAVE_WCSTOUMAX 0
+#define HAVE_WINBASE_H 0
+#define HAVE_WINCON_H 0
+#define HAVE_WINREG_H 0
+#define HAVE__CLEARFP 0
+#define HAVE__FCLOSE 0
+#define HAVE__FEOF 0
+#define HAVE__FERROR 0
+#define HAVE__FFLUSH 0
+#define HAVE__FOPEN 0
+#define HAVE__FREAD 0
+#define HAVE__FWRITE 0
+#define HAVE__GETENV_S 0
+#define HAVE__GETPID 0
+#define HAVE__LSTAT 0
+#define HAVE__LSTAT32 0
+#define HAVE__LSTAT64 0
+#define HAVE__POPEN 0
+#define HAVE__STAT 0
+#define HAVE__STAT32 0
+#define HAVE__STAT64 0
+#define HAVE__STRDUP 0
+#define HAVE__WCSCAT 0
+#define HAVE__WCSCHR 0
+#define HAVE__WCSCPY 0
+#define HAVE__WCSDUP 0
+#define HAVE__WCSLEN 0
+#define HAVE__WCSNCPY 0
+#define HAVE__WCSRCHR 0
+#define HAVE__WGETENV 0
+#define HAVE_REPARSE_DATA_BUFFER 0
+
+/*
+ Backward compatibility section end
+*/
+
+
+#endif
+/* ifndef CONFIG_H_INCLUDED */
+
diff --git a/support/dktools/config.sub b/support/dktools/config.sub
new file mode 100755
index 0000000000..7ffe373784
--- /dev/null
+++ b/support/dktools/config.sub
@@ -0,0 +1,1807 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+# Copyright 1992-2014 Free Software Foundation, Inc.
+
+timestamp='2014-12-03'
+
+# This file 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.
+#
+# This program 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 this program; if not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that
+# program. This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+
+
+# Please send patches to <config-patches@gnu.org>.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+ $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright 1992-2014 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help"
+ exit 1 ;;
+
+ *local*)
+ # First pass through any local machine types.
+ echo $1
+ exit ;;
+
+ * )
+ break ;;
+ esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+ exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+ exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+ knetbsd*-gnu* | netbsd*-gnu* | \
+ kopensolaris*-gnu* | \
+ storm-chaos* | os2-emx* | rtmk-nova*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ android-linux)
+ os=-linux-android
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple | -axis | -knuth | -cray | -microblaze*)
+ os=
+ basic_machine=$1
+ ;;
+ -bluegene*)
+ os=-cnk
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+ ;;
+ -scout)
+ ;;
+ -wrs)
+ os=-vxworks
+ basic_machine=$1
+ ;;
+ -chorusos*)
+ os=-chorusos
+ basic_machine=$1
+ ;;
+ -chorusrdb)
+ os=-chorusrdb
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco6)
+ os=-sco5v6
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5v6*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*178)
+ os=-lynxos178
+ ;;
+ -lynx*5)
+ os=-lynxos5
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+ -mint | -mint[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ 1750a | 580 \
+ | a29k \
+ | aarch64 | aarch64_be \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | am33_2.0 \
+ | arc | arceb \
+ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
+ | avr | avr32 \
+ | be32 | be64 \
+ | bfin \
+ | c4x | c8051 | clipper \
+ | d10v | d30v | dlx | dsp16xx \
+ | epiphany \
+ | fido | fr30 | frv \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | hexagon \
+ | i370 | i860 | i960 | ia64 \
+ | ip2k | iq2000 \
+ | k1om \
+ | le32 | le64 \
+ | lm32 \
+ | m32c | m32r | m32rle | m68000 | m68k | m88k \
+ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+ | mips64octeon | mips64octeonel \
+ | mips64orion | mips64orionel \
+ | mips64r5900 | mips64r5900el \
+ | mips64vr | mips64vrel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mips64vr5900 | mips64vr5900el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa32r6 | mipsisa32r6el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64r6 | mipsisa64r6el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipsr5900 | mipsr5900el \
+ | mipstx39 | mipstx39el \
+ | mn10200 | mn10300 \
+ | moxie \
+ | mt \
+ | msp430 \
+ | nds32 | nds32le | nds32be \
+ | nios | nios2 | nios2eb | nios2el \
+ | ns16k | ns32k \
+ | open8 | or1k | or1knd | or32 \
+ | pdp10 | pdp11 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle \
+ | pyramid \
+ | riscv32 | riscv64 \
+ | rl78 | rx \
+ | score \
+ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+ | spu \
+ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+ | ubicom32 \
+ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+ | visium \
+ | we32k \
+ | x86 | xc16x | xstormy16 | xtensa \
+ | z8k | z80)
+ basic_machine=$basic_machine-unknown
+ ;;
+ c54x)
+ basic_machine=tic54x-unknown
+ ;;
+ c55x)
+ basic_machine=tic55x-unknown
+ ;;
+ c6x)
+ basic_machine=tic6x-unknown
+ ;;
+ leon|leon[3-9])
+ basic_machine=sparc-$basic_machine
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ ;;
+ ms1)
+ basic_machine=mt-unknown
+ ;;
+
+ strongarm | thumb | xscale)
+ basic_machine=arm-unknown
+ ;;
+ xgate)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ xscaleeb)
+ basic_machine=armeb-unknown
+ ;;
+
+ xscaleel)
+ basic_machine=armel-unknown
+ ;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i*86 | x86_64)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ 580-* \
+ | a29k-* \
+ | aarch64-* | aarch64_be-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+ | avr-* | avr32-* \
+ | be32-* | be64-* \
+ | bfin-* | bs2000-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* \
+ | c8051-* | clipper-* | craynv-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
+ | elxsi-* \
+ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | hexagon-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | ip2k-* | iq2000-* \
+ | k1om-* \
+ | le32-* | le64-* \
+ | lm32-* \
+ | m32c-* | m32r-* | m32rle-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
+ | microblaze-* | microblazeel-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+ | mips64octeon-* | mips64octeonel-* \
+ | mips64orion-* | mips64orionel-* \
+ | mips64r5900-* | mips64r5900el-* \
+ | mips64vr-* | mips64vrel-* \
+ | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* \
+ | mips64vr5000-* | mips64vr5000el-* \
+ | mips64vr5900-* | mips64vr5900el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa32r2-* | mipsisa32r2el-* \
+ | mipsisa32r6-* | mipsisa32r6el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64r2-* | mipsisa64r2el-* \
+ | mipsisa64r6-* | mipsisa64r6el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipsr5900-* | mipsr5900el-* \
+ | mipstx39-* | mipstx39el-* \
+ | mmix-* \
+ | mt-* \
+ | msp430-* \
+ | nds32-* | nds32le-* | nds32be-* \
+ | nios-* | nios2-* | nios2eb-* | nios2el-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
+ | open8-* \
+ | or1k*-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+ | pyramid-* \
+ | rl78-* | romp-* | rs6000-* | rx-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+ | sparclite-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
+ | tahoe-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tile*-* \
+ | tron-* \
+ | ubicom32-* \
+ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+ | vax-* \
+ | visium-* \
+ | we32k-* \
+ | x86-* | x86_64-* | xc16x-* | xps100-* \
+ | xstormy16-* | xtensa*-* \
+ | ymp-* \
+ | z8k-* | z80-*)
+ ;;
+ # Recognize the basic CPU types without company name, with glob match.
+ xtensa*)
+ basic_machine=$basic_machine-unknown
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd)
+ basic_machine=i386-unknown
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ abacus)
+ basic_machine=abacus-unknown
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amd64)
+ basic_machine=x86_64-pc
+ ;;
+ amd64-*)
+ basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-unknown
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aros)
+ basic_machine=i386-pc
+ os=-aros
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ blackfin)
+ basic_machine=bfin-unknown
+ os=-linux
+ ;;
+ blackfin-*)
+ basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ bluegene*)
+ basic_machine=powerpc-ibm
+ os=-cnk
+ ;;
+ c54x-*)
+ basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c55x-*)
+ basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c6x-*)
+ basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ cegcc)
+ basic_machine=arm-unknown
+ os=-cegcc
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | j90)
+ basic_machine=j90-cray
+ os=-unicos
+ ;;
+ craynv)
+ basic_machine=craynv-cray
+ os=-unicosmp
+ ;;
+ cr16 | cr16-*)
+ basic_machine=cr16-unknown
+ os=-elf
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ crisv32 | crisv32-* | etraxfs*)
+ basic_machine=crisv32-axis
+ ;;
+ cris | cris-* | etrax*)
+ basic_machine=cris-axis
+ ;;
+ crx)
+ basic_machine=crx-unknown
+ os=-elf
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ decsystem10* | dec10*)
+ basic_machine=pdp10-dec
+ os=-tops10
+ ;;
+ decsystem20* | dec20*)
+ basic_machine=pdp10-dec
+ os=-tops20
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ dicos)
+ basic_machine=i686-pc
+ os=-dicos
+ ;;
+ djgpp)
+ basic_machine=i586-pc
+ os=-msdosdjgpp
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ os=-go32
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+ i*86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i*86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i*86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i*86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ i386-vsta | vsta)
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ leon-*|leon[3-9]-*)
+ basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
+ ;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=-linux
+ ;;
+ m68knommu-*)
+ basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ microblaze*)
+ basic_machine=microblaze-xilinx
+ ;;
+ mingw64)
+ basic_machine=x86_64-pc
+ os=-mingw64
+ ;;
+ mingw32)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ mingw32ce)
+ basic_machine=arm-unknown
+ os=-mingw32ce
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
+ moxiebox)
+ basic_machine=moxie-unknown
+ os=-moxiebox
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=-msdos
+ ;;
+ ms1-*)
+ basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+ ;;
+ msys)
+ basic_machine=i686-pc
+ os=-msys
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+ nacl)
+ basic_machine=le32-unknown
+ os=-nacl
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ os=-nonstopux
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ neo-tandem)
+ basic_machine=neo-tandem
+ ;;
+ nse-tandem)
+ basic_machine=nse-tandem
+ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ openrisc | openrisc-*)
+ basic_machine=or32-unknown
+ ;;
+ os400)
+ basic_machine=powerpc-ibm
+ os=-os400
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ parisc)
+ basic_machine=hppa-unknown
+ os=-linux
+ ;;
+ parisc-*)
+ basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pc98)
+ basic_machine=i386-pc
+ ;;
+ pc98-*)
+ basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium | p5 | k5 | k6 | nexgen | viac3)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | 6x86 | athlon | athlon_*)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2 | pentiumiii | pentium3)
+ basic_machine=i686-pc
+ ;;
+ pentium4)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | 6x86-* | athlon-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium4-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=power-ibm
+ ;;
+ ppc | ppcbe) basic_machine=powerpc-unknown
+ ;;
+ ppc-* | ppcbe-*)
+ basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64) basic_machine=powerpc64-unknown
+ ;;
+ ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+ basic_machine=powerpc64le-unknown
+ ;;
+ ppc64le-* | powerpc64little-*)
+ basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ os=-pw32
+ ;;
+ rdos | rdos64)
+ basic_machine=x86_64-pc
+ os=-rdos
+ ;;
+ rdos32)
+ basic_machine=i386-pc
+ os=-rdos
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ s390 | s390-*)
+ basic_machine=s390-ibm
+ ;;
+ s390x | s390x-*)
+ basic_machine=s390x-ibm
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sb1)
+ basic_machine=mipsisa64sb1-unknown
+ ;;
+ sb1el)
+ basic_machine=mipsisa64sb1el-unknown
+ ;;
+ sde)
+ basic_machine=mipsisa32-sde
+ os=-elf
+ ;;
+ sei)
+ basic_machine=mips-sei
+ os=-seiux
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sh5el)
+ basic_machine=sh5le-unknown
+ ;;
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
+ sparclite-wrs | simso-wrs)
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ strongarm-* | thumb-*)
+ basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=-unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ t3e)
+ basic_machine=alphaev5-cray
+ os=-unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
+ os=-unicos
+ ;;
+ tile*)
+ basic_machine=$basic_machine-unknown
+ os=-linux-gnu
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=-tops20
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ tpf)
+ basic_machine=s390x-ibm
+ os=-tpf
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ xbox)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ xscale-* | xscalee[bl]-*)
+ basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ z8k-*-coff)
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
+ z80-*-coff)
+ basic_machine=z80-unknown
+ os=-sim
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n)
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c)
+ basic_machine=hppa1.1-oki
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ mmix)
+ basic_machine=mmix-knuth
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp10)
+ # there are many clones, so DEC is not a safe bet
+ basic_machine=pdp10-unknown
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+ basic_machine=sh-unknown
+ ;;
+ sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw)
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw)
+ basic_machine=powerpc-apple
+ ;;
+ *-unknown)
+ # Make sure to match an already-canonicalized machine name.
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -auroraux)
+ os=-auroraux
+ ;;
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+ | -sym* | -kopensolaris* | -plan9* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* | -aros* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+ | -bitrig* | -openbsd* | -solidbsd* \
+ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -chorusos* | -chorusrdb* | -cegcc* \
+ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+ | -linux-newlib* | -linux-musl* | -linux-uclibc* \
+ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+ case $basic_machine in
+ x86-* | i*86-*)
+ ;;
+ *)
+ os=-nto$os
+ ;;
+ esac
+ ;;
+ -nto-qnx*)
+ ;;
+ -nto*)
+ os=`echo $os | sed -e 's|nto|nto-qnx|'`
+ ;;
+ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ ;;
+ -mac*)
+ os=`echo $os | sed -e 's|mac|macos|'`
+ ;;
+ -linux-dietlibc)
+ os=-linux-dietlibc
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -opened*)
+ os=-openedition
+ ;;
+ -os400*)
+ os=-os400
+ ;;
+ -wince*)
+ os=-wince
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -atheos*)
+ os=-atheos
+ ;;
+ -syllable*)
+ os=-syllable
+ ;;
+ -386bsd)
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -nova*)
+ os=-rtmk-nova
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ -nsk*)
+ os=-nsk
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -tpf*)
+ os=-tpf
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*)
+ os=-ose
+ ;;
+ -es1800*)
+ os=-ose
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
+ ;;
+ -aros*)
+ os=-aros
+ ;;
+ -zvmoe)
+ os=-zvmoe
+ ;;
+ -dicos*)
+ os=-dicos
+ ;;
+ -nacl*)
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ score-*)
+ os=-elf
+ ;;
+ spu-*)
+ os=-elf
+ ;;
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
+ c8051-*)
+ os=-elf
+ ;;
+ hexagon-*)
+ os=-elf
+ ;;
+ tic54x-*)
+ os=-coff
+ ;;
+ tic55x-*)
+ os=-coff
+ ;;
+ tic6x-*)
+ os=-coff
+ ;;
+ # This must come before the *-dec entry.
+ pdp10-*)
+ os=-tops20
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mep-*)
+ os=-elf
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ or32-*)
+ os=-coff
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-haiku)
+ os=-haiku
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-knuth)
+ os=-mmixware
+ ;;
+ *-wec)
+ os=-proelf
+ ;;
+ *-winbond)
+ os=-proelf
+ ;;
+ *-oki)
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f30[01]-fujitsu | f700-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
+ os=-coff
+ ;;
+ *-*bug)
+ os=-coff
+ ;;
+ *-apple)
+ os=-macos
+ ;;
+ *-atari*)
+ os=-mint
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -cnk*|-aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs* | -opened*)
+ vendor=ibm
+ ;;
+ -os400*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -tpf*)
+ vendor=ibm
+ ;;
+ -vxsim* | -vxworks* | -windiss*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*)
+ vendor=apple
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ vendor=atari
+ ;;
+ -vos*)
+ vendor=stratus
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/support/dktools/configure b/support/dktools/configure
new file mode 100755
index 0000000000..1ef2e963d4
--- /dev/null
+++ b/support/dktools/configure
@@ -0,0 +1,15822 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.69.
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Use a proper internal environment variable to ensure we don't fall
+ # into an infinite loop, continuously re-executing ourselves.
+ if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+ _as_can_reexec=no; export _as_can_reexec;
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+ fi
+ # We don't want this to propagate to other subprocesses.
+ { _as_can_reexec=; unset _as_can_reexec;}
+if test "x$CONFIG_SHELL" = x; then
+ as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+"
+ as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+ exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
+ as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+ as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+ eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+ test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+ if (eval "$as_required") 2>/dev/null; then :
+ as_have_required=yes
+else
+ as_have_required=no
+fi
+ if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ as_found=:
+ case $as_dir in #(
+ /*)
+ for as_base in sh bash ksh sh5; do
+ # Try only shells that exist, to save several forks.
+ as_shell=$as_dir/$as_base
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ CONFIG_SHELL=$as_shell as_have_required=yes
+ if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ break 2
+fi
+fi
+ done;;
+ esac
+ as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+ CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+ if test "x$CONFIG_SHELL" != x; then :
+ export CONFIG_SHELL
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+fi
+
+ if test x$as_have_required = xno; then :
+ $as_echo "$0: This script requires a shell more modern than all"
+ $as_echo "$0: the shells that I found on your system."
+ if test x${ZSH_VERSION+set} = xset ; then
+ $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+ $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+ else
+ $as_echo "$0: Please tell bug-autoconf@gnu.org about your system,
+$0: including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
+ fi
+ exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+ as_lineno_1=$LINENO as_lineno_1a=$LINENO
+ as_lineno_2=$LINENO as_lineno_2a=$LINENO
+ eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+ test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+ # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+ # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+ # already done that, so ensure we don't try to do so again and fall
+ # in an infinite loop. This has already happened in practice.
+ _as_can_reexec=no; export _as_can_reexec
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+PACKAGE_URL=
+
+ac_unique_file="dk4.h"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='LTLIBOBJS
+LIBOBJS
+LIBDK3WXLIBS
+LIBDK3WXLIBF
+LIBDK3FIGLIBS
+LIBDK3FIGLIBF
+LIBDK3BMEPSLIBS
+LIBDK3BMEPSLIBF
+LIBDK3DBILIBS
+LIBDK3DBILIBF
+LIBDK3BIFLIBS
+LIBDK3BIFLIBF
+LIBDK3CSRNDLIBS
+LIBDK3CSRNDLIBF
+LIBDK3OFLIBS
+LIBDK3OFLIBF
+LIBDK3CLIBS
+LIBDK3CLIBF
+LIBDK3TRACELIBS
+LIBDK3TRACELIBF
+LIBDK4WXLIBS
+LIBDK4WXLIBF
+LIBDK4DBIALIBS
+LIBDK4DBIALIBF
+LIBDK4SOCKALIBS
+LIBDK4SOCKALIBF
+LIBDK4PPPTALIBS
+LIBDK4PPPTALIBF
+LIBDK4APPLIBS
+LIBDK4APPLIBF
+LIBDK4PPPTLIBS
+LIBDK4PPPTLIBF
+LIBDK4MDRNDLIBS
+LIBDK4MDRNDLIBF
+LIBDK4SOCKLIBS
+LIBDK4SOCKLIBF
+LIBDK4LATLIBS
+LIBDK4LATLIBF
+LIBDK4CLIBS
+LIBDK4CLIBF
+LIBDK4DBILIBS
+LIBDK4DBILIBF
+LIBDK4MAIODHLIBS
+LIBDK4MAIODHLIBF
+LIBDK4MAIOWHLIBS
+LIBDK4MAIOWHLIBF
+LIBDK4MAIO8HLIBS
+LIBDK4MAIO8HLIBF
+LIBDK4MAIOXDLIBS
+LIBDK4MAIOXDLIBF
+LIBDK4MAIODDLIBS
+LIBDK4MAIODDLIBF
+LIBDK4MAIOWDLIBS
+LIBDK4MAIOWDLIBF
+LIBDK4MAIO8DLIBS
+LIBDK4MAIO8DLIBF
+LIBDK4MALIBS
+LIBDK4MALIBF
+LIBDK4BASELIBS
+LIBDK4BASELIBF
+RTLIB
+LIBSPRIVATE
+INSTALLMANPAGES
+WINUNICODE
+ENTRY
+GUILIB
+CLILIB
+MAKE
+GETSOURCE
+WXDKFCSLIBS
+WXDKFCSLIBF
+NETSNMP_CFLAGS
+MYSQLLIB
+NETSNMP_LIBS
+SOLIBDK4DBIA
+SOLIBDK4DBI
+SOLIBDK4SOCKA
+SOLIBDK4SOCK
+SOLIBDK4LAT
+SOLIBDK4APP
+SOLIBDK4PPPT
+SOLIBDK4MDRND
+SOLIBDK4C
+SOLIBDK4MAIODD
+SOLIBDK4MAIOWD
+SOLIBDK4MAIO8D
+SOLIBDK4MAIODH
+SOLIBDK4MAIOWH
+SOLIBDK4MAIO8H
+SOLIBDK4MA
+SOLIBDK4BASE
+SOLIBDK3NET
+SOLIBDK3BMEPS
+SOLIBDK3FIG
+SOLIBDK3DBI
+SOLIBDK3BIF
+SOLIBDK3CSRND
+SOLIBDK3OF
+SOLIBDK3C
+SOLIBDK3PORT
+SOLIBWX
+SOLIBSDBI
+SOLIBIMG
+SOLIBNET
+SOLIBCRYPTO
+SOLIBMATH
+SOLIBBZ
+SOLIBZ
+WXLDFLAGS
+WXCFLAGS
+WXCXXFLAGS
+WXCPPFLAGS
+TESTPROGRAMS
+SNMP_PROG_CLI
+MYSQLLDFLAGS
+MYSQL_PROG_CLI
+NET_PROG_CLI
+NET_PROG_RES
+LIB_SH_GUI
+LIB_SH_CLI
+LIB_SH_RES
+NSLLIB
+SOCKLIB
+PROGSOPENSSL
+DK4INFOLIBF
+DK4INFOLIBS
+DKDBT2LIBS
+DKDBT2LIBF
+DKSENDLIBS
+DKSENDLIBF
+DKRECVLIBS
+DKRECVLIBF
+DKPWDLIBS
+DKPWDLIBF
+DKBMMLIBS
+DKBMMLIBF
+DKHEXLIBS
+DKHEXLIBF
+DKT2LLIBS
+DKT2LLIBF
+DKT2HLIBS
+DKT2HLIBF
+DKRANDLIBS
+DKRANDLIBF
+DKPWGENLIBS
+DKPWGENLIBF
+DKUIDLIBS
+DKUIDLIBF
+DKFICLIBS
+DKFICLIBF
+DKSORTLIBS
+DKSORTLIBF
+DKLSLIBS
+DKLSLIBF
+DKERADISKLIBS
+DKERADISKLIBF
+DKSQLSPLITLIBS
+DKSQLSPLITLIBF
+DKBLKSLIBS
+DKBLKSLIBF
+DKCATLIBS
+DKCATLIBF
+CRYPTO
+CWARN
+SOVERS
+VERSNO
+SHLIBSTYLE
+UNAME
+RPATHLINK
+RPATH
+MKSOLIB
+RES_INSTALL
+LIBS_INSTALL
+LIBS_SHARED
+LIBS_STATIC
+LIBRARIES
+PROGRAMS
+CFPIC
+BZLIB
+ZLIB
+FS64
+ITADMINLIBS
+ITADMINLIBF
+LPRNGCLLIBS
+LPRNGCLLIBF
+RSHDOWNLIBS
+RSHDOWNLIBF
+PRINTQDCLIBS
+PRINTQDCLIBF
+PRMONSNMPLIBS
+PRMONSNMPLIBF
+PJSNMPLIBS
+PJSNMPLIBF
+PRINTQDALIBS
+PRINTQDALIBF
+PRINTQDILIBS
+PRINTQDILIBF
+PRINTQDLIBS
+PRINTQDLIBF
+WXDKHTBLIBS
+WXDKHTBLIBF
+WXDKCLOCKLIBS
+WXDKCLOCKLIBF
+WXIMGSZLIBS
+WXIMGSZLIBF
+WXPQDICLIBS
+WXPQDICLIBF
+WXBMPPLIBS
+WXBMPPLIBF
+WXDKCTLIBS
+WXDKCTLIBF
+DKWXWIZLIBS
+DKWXWIZLIBF
+PLPDFTEXLIBS
+PLPDFTEXLIBF
+DK3INFOLIBS
+DK3INFOLIBF
+HTMLBOOKLIBS
+HTMLBOOKLIBF
+FIG2LATLIBS
+FIG2LATLIBF
+BMPPLIBS
+BMPPLIBF
+DKDBTLIBS
+DKDBTLIBF
+ADDCTRLDLIBS
+ADDCTRLDLIBF
+DKCTLIBS
+DKCTLIBF
+LIBDK4WXTOBUILD
+LIBDK4WXOBJ
+LIBDK3WXOBJ
+PTHREADLIB
+CLI_MYSQLPROG
+DBLIBSOCK
+DBLIB
+LIBTIFF
+LIBJPEG
+LIBPNG
+CLI_SNMPPROG
+ANYDB
+CURL
+WGET
+NM
+AR
+RANLIB
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+LN_S
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+SED
+MKDIR_P
+EGREP
+GREP
+ac_ct_CXX
+CXXFLAGS
+CXX
+CPP
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_inline
+enable_static
+enable_shared
+enable_packaging
+enable_ndbm
+enable_warnings
+enable_more_warnings
+with_suite
+with_man
+with_corrections
+with_fallback_limits
+with_printf_scanf
+'
+ ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CPP
+CXX
+CXXFLAGS
+CCC'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval $ac_prev=\$ac_option
+ ac_prev=
+ continue
+ fi
+
+ case $ac_option in
+ *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *=) ac_optarg= ;;
+ *) ac_optarg=yes ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=*)
+ datadir=$ac_optarg ;;
+
+ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+ | --dataroo | --dataro | --datar)
+ ac_prev=datarootdir ;;
+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+ datarootdir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=no ;;
+
+ -docdir | --docdir | --docdi | --doc | --do)
+ ac_prev=docdir ;;
+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+ docdir=$ac_optarg ;;
+
+ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+ ac_prev=dvidir ;;
+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+ dvidir=$ac_optarg ;;
+
+ -enable-* | --enable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=\$ac_optarg ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+ ac_prev=htmldir ;;
+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+ | --ht=*)
+ htmldir=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localedir | --localedir | --localedi | --localed | --locale)
+ ac_prev=localedir ;;
+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+ localedir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst | --locals)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+ ac_prev=pdfdir ;;
+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+ pdfdir=$ac_optarg ;;
+
+ -psdir | --psdir | --psdi | --psd | --ps)
+ ac_prev=psdir ;;
+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+ psdir=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=\$ac_optarg ;;
+
+ -without-* | --without-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=no ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ case $ac_envvar in #(
+ '' | [0-9]* | *[!_$as_cr_alnum]* )
+ as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+ esac
+ eval $ac_envvar=\$ac_optarg
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+ case $enable_option_checking in
+ no) ;;
+ fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+ *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+ esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+ libdir localedir mandir
+do
+ eval ac_val=\$$ac_var
+ # Remove trailing slashes.
+ case $ac_val in
+ */ )
+ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+ eval $ac_var=\$ac_val;;
+ esac
+ # Be sure to have absolute directory names.
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+ esac
+ as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ as_fn_error $? "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then the parent directory.
+ ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_myself" : 'X\(//\)[^/]' \| \
+ X"$as_myself" : 'X\(//\)$' \| \
+ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r "$srcdir/$ac_unique_file"; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+ pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+ srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+ eval ac_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_env_${ac_var}_value=\$${ac_var}
+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking ...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE]
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
+_ACEOF
+
+ cat <<\_ACEOF
+
+System types:
+ --build=BUILD configure for building on BUILD [guessed]
+ --host=HOST cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-option-checking ignore unrecognized --enable/--with options
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --enable-inline Allow use of inline keyword (no / yes)
+ --enable-static Allow building static libraries (yes / no)
+ --enable-shared Allow building shared libraries (yes / no)
+ --enable-packaging Binaries use shared libraries (no / yes)
+ --enable-ndbm Explicitly enable/disable NDBM if found
+ --enable-warnings Enable high warning level, gcc only (yes / no)
+ --enable-more-warnings Enable yet more warnings, gcc only (no / yes)
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-suite=name Software suite to build: auto / gui / cli / rescue
+ --with-man Install man pages (auto / yes / no)
+ --with-corrections Enable corrections for Solaris: no / yes
+ --with-fallback-limits Allow use of fallback limits (no / yes)
+ --with-printf-scanf Allow use of printf and scanf (yes / no)
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ LIBS libraries to pass to the linker, e.g. -l<library>
+ CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+ you have headers in a nonstandard directory <include dir>
+ CPP C preprocessor
+ CXX C++ compiler command
+ CXXFLAGS C++ compiler flags
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to the package provider.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d "$ac_dir" ||
+ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+ continue
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+ # Check for guested configure.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+ elif test -f "$ac_srcdir/configure"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure" --help=recursive
+ else
+ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
+ done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+ cat <<\_ACEOF
+configure
+generated by GNU Autoconf 2.69
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } > conftest.i && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_cxx_try_compile LINENO
+# ----------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_compile
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=$ac_status
+fi
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if eval \${$3+:} false; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_header_compiler=yes
+else
+ ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ ac_header_preproc=yes
+else
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+ yes:no: )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
+# --------------------------------------------
+# Tries to find the compile-time value of EXPR in a program that includes
+# INCLUDES, setting VAR accordingly. Returns whether the value could be
+# computed
+ac_fn_c_compute_int ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if test "$cross_compiling" = yes; then
+ # Depending upon the size, compute the lo and hi bounds.
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= 0)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_lo=0 ac_mid=0
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=$ac_mid; break
+else
+ as_fn_arith $ac_mid + 1 && ac_lo=$as_val
+ if test $ac_lo -le $ac_mid; then
+ ac_lo= ac_hi=
+ break
+ fi
+ as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) < 0)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=-1 ac_mid=-1
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_lo=$ac_mid; break
+else
+ as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val
+ if test $ac_mid -le $ac_hi; then
+ ac_lo= ac_hi=
+ break
+ fi
+ as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ ac_lo= ac_hi=
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+ as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=$ac_mid
+else
+ as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in #((
+?*) eval "$3=\$ac_lo"; ac_retval=0 ;;
+'') ac_retval=1 ;;
+esac
+ else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+static long int longval () { return $2; }
+static unsigned long int ulongval () { return $2; }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+ FILE *f = fopen ("conftest.val", "w");
+ if (! f)
+ return 1;
+ if (($2) < 0)
+ {
+ long int i = longval ();
+ if (i != ($2))
+ return 1;
+ fprintf (f, "%ld", i);
+ }
+ else
+ {
+ unsigned long int i = ulongval ();
+ if (i != ($2))
+ return 1;
+ fprintf (f, "%lu", i);
+ }
+ /* Do not output a trailing newline, as this causes \r\n confusion
+ on some platforms. */
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ echo >>conftest.val; read $3 <conftest.val; ac_retval=0
+else
+ ac_retval=1
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+rm -f conftest.val
+
+ fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_compute_int
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ test -x conftest$ac_exeext
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $2 (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.69. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ $as_echo "PATH: $as_dir"
+ done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *\'*)
+ ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+ 2)
+ as_fn_append ac_configure_args1 " '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ as_fn_append ac_configure_args " '$ac_arg'"
+ ;;
+ esac
+ done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+(
+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+ (set) 2>&1 |
+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ sed -n \
+ "s/'\''/'\''\\\\'\'''\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+ ;; #(
+ *)
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+)
+ echo
+
+ $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+ echo
+ cat confdefs.h
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ $as_echo "$as_me: caught signal $ac_signal"
+ $as_echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+ # We do not want a PATH search for config.site.
+ case $CONFIG_SITE in #((
+ -*) ac_site_file1=./$CONFIG_SITE;;
+ */*) ac_site_file1=$CONFIG_SITE;;
+ *) ac_site_file1=./$CONFIG_SITE;;
+ esac
+elif test "x$prefix" != xNONE; then
+ ac_site_file1=$prefix/share/config.site
+ ac_site_file2=$prefix/etc/config.site
+else
+ ac_site_file1=$ac_default_prefix/share/config.site
+ ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+ test "x$ac_site_file" = xNONE && continue
+ if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file" \
+ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special files
+ # actually), so we avoid doing that. DJGPP emulates it as a regular file.
+ if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
+ esac
+ fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val=\$ac_cv_env_${ac_var}_value
+ eval ac_new_val=\$ac_env_${ac_var}_value
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ # differences in whitespace do not lead to failure.
+ ac_old_val_w=`echo x $ac_old_val`
+ ac_new_val_w=`echo x $ac_new_val`
+ if test "$ac_old_val_w" != "$ac_new_val_w"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ ac_cache_corrupted=:
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+ eval $ac_var=\$ac_old_val
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
+$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
+$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ac_config_headers="$ac_config_headers config.h"
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+ esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link_default") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile. We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+ then :; else
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ fi
+ # We set ac_cv_exeext here because the later test for it is not
+ # safe: cross compilers may not add the suffix if given an `-o'
+ # argument, so we may need to know it at that point already.
+ # Even if this section looks crufty: it has the advantage of
+ # actually working.
+ break;;
+ * )
+ break;;
+ esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+ ac_file=''
+fi
+if test -z "$ac_file"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+ { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if { ac_try='./conftest$ac_cv_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if ${ac_cv_objext+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ for ac_file in conftest.o conftest.obj conftest.*; do
+ test -f "$ac_file" || continue;
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+else
+ CFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if ${ac_cv_prog_CPP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+ if test -n "$CCC"; then
+ CXX=$CCC
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CXX"; then
+ ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CXX" && break
+ done
+fi
+if test -z "$CXX"; then
+ ac_ct_CXX=$CXX
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CXX"; then
+ ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CXX="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CXX" && break
+done
+
+ if test "x$ac_ct_CXX" = x; then
+ CXX="g++"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CXX=$ac_ct_CXX
+ fi
+fi
+
+ fi
+fi
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5
+$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
+if ${ac_cv_cxx_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GXX=yes
+else
+ GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if ${ac_cv_prog_cxx_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+ ac_cxx_werror_flag=yes
+ ac_cv_prog_cxx_g=no
+ CXXFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_prog_cxx_g=yes
+else
+ CXXFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+ CXXFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_prog_cxx_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+ CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+ if test "$GXX" = yes; then
+ CXXFLAGS="-g -O2"
+ else
+ CXXFLAGS="-g"
+ fi
+else
+ if test "$GXX" = yes; then
+ CXXFLAGS="-O2"
+ else
+ CXXFLAGS=
+ fi
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$GREP"; then
+ ac_path_GREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in grep ggrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_GREP" || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+ # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'GREP' >> "conftest.nl"
+ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_GREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_GREP="$ac_path_GREP"
+ ac_path_GREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_GREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_GREP"; then
+ as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+ then ac_cv_path_EGREP="$GREP -E"
+ else
+ if test -z "$EGREP"; then
+ ac_path_EGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in egrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_EGREP" || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+ # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'EGREP' >> "conftest.nl"
+ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_EGREP="$ac_path_EGREP"
+ ac_path_EGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_EGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_EGREP"; then
+ as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_EGREP=$EGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdc=yes
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then :
+ :
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
+$as_echo_n "checking whether byte ordering is bigendian... " >&6; }
+if ${ac_cv_c_bigendian+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_c_bigendian=unknown
+ # See if we're dealing with a universal compiler.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifndef __APPLE_CC__
+ not a universal capable compiler
+ #endif
+ typedef int dummy;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ # Check for potential -arch flags. It is not universal unless
+ # there are at least two -arch flags with different values.
+ ac_arch=
+ ac_prev=
+ for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do
+ if test -n "$ac_prev"; then
+ case $ac_word in
+ i?86 | x86_64 | ppc | ppc64)
+ if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then
+ ac_arch=$ac_word
+ else
+ ac_cv_c_bigendian=universal
+ break
+ fi
+ ;;
+ esac
+ ac_prev=
+ elif test "x$ac_word" = "x-arch"; then
+ ac_prev=arch
+ fi
+ done
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ if test $ac_cv_c_bigendian = unknown; then
+ # See if sys/param.h defines the BYTE_ORDER macro.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ #include <sys/param.h>
+
+int
+main ()
+{
+#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \
+ && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \
+ && LITTLE_ENDIAN)
+ bogus endian macros
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ # It does; now see whether it defined to BIG_ENDIAN or not.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ #include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_bigendian=yes
+else
+ ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test $ac_cv_c_bigendian = unknown; then
+ # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <limits.h>
+
+int
+main ()
+{
+#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
+ bogus endian macros
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ # It does; now see whether it defined to _BIG_ENDIAN or not.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <limits.h>
+
+int
+main ()
+{
+#ifndef _BIG_ENDIAN
+ not big endian
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_bigendian=yes
+else
+ ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test $ac_cv_c_bigendian = unknown; then
+ # Compile a test program.
+ if test "$cross_compiling" = yes; then :
+ # Try to guess by grepping values from an object file.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+short int ascii_mm[] =
+ { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+ short int ascii_ii[] =
+ { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+ int use_ascii (int i) {
+ return ascii_mm[i] + ascii_ii[i];
+ }
+ short int ebcdic_ii[] =
+ { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+ short int ebcdic_mm[] =
+ { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+ int use_ebcdic (int i) {
+ return ebcdic_mm[i] + ebcdic_ii[i];
+ }
+ extern int foo;
+
+int
+main ()
+{
+return use_ascii (foo) == use_ebcdic (foo);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then
+ ac_cv_c_bigendian=yes
+ fi
+ if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+ if test "$ac_cv_c_bigendian" = unknown; then
+ ac_cv_c_bigendian=no
+ else
+ # finding both strings is unlikely to happen, but who knows?
+ ac_cv_c_bigendian=unknown
+ fi
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+
+ /* Are we little or big endian? From Harbison&Steele. */
+ union
+ {
+ long int l;
+ char c[sizeof (long int)];
+ } u;
+ u.l = 1;
+ return u.c[sizeof (long int) - 1] == 1;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_c_bigendian=no
+else
+ ac_cv_c_bigendian=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5
+$as_echo "$ac_cv_c_bigendian" >&6; }
+ case $ac_cv_c_bigendian in #(
+ yes)
+ $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h
+;; #(
+ no)
+ ;; #(
+ universal)
+
+$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
+
+ ;; #(
+ *)
+ as_fn_error $? "unknown endianness
+ presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
+ esac
+
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+ if test -f "$ac_dir/install-sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f "$ac_dir/install.sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f "$ac_dir/shtool"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
+$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+if test -z "$MKDIR_P"; then
+ if ${ac_cv_path_mkdir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in mkdir gmkdir; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue
+ case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+ 'mkdir (GNU coreutils) '* | \
+ 'mkdir (coreutils) '* | \
+ 'mkdir (fileutils) '4.1*)
+ ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+ break 3;;
+ esac
+ done
+ done
+ done
+IFS=$as_save_IFS
+
+fi
+
+ test -d ./--version && rmdir ./--version
+ if test "${ac_cv_path_mkdir+set}" = set; then
+ MKDIR_P="$ac_cv_path_mkdir -p"
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for MKDIR_P within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ MKDIR_P="$ac_install_sh -d"
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if ${ac_cv_path_SED+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+ for ac_i in 1 2 3 4 5 6 7; do
+ ac_script="$ac_script$as_nl$ac_script"
+ done
+ echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+ { ac_script=; unset ac_script;}
+ if test -z "$SED"; then
+ ac_path_SED_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_SED" || continue
+# Check for GNU ac_path_SED and select it if it is found.
+ # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2>&1` in
+*GNU*)
+ ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo '' >> "conftest.nl"
+ "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_SED_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_SED="$ac_path_SED"
+ ac_path_SED_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_SED_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_SED"; then
+ as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5
+ fi
+else
+ ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+$as_echo "$ac_cv_path_SED" >&6; }
+ SED="$ac_cv_path_SED"
+ rm -f conftest.sed
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if ${ac_cv_path_install+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+ ./ | .// | /[cC]/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ rm -rf conftest.one conftest.two conftest.dir
+ echo one > conftest.one
+ echo two > conftest.two
+ mkdir conftest.dir
+ if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+ test -s conftest.one && test -s conftest.two &&
+ test -s conftest.dir/conftest.one &&
+ test -s conftest.dir/conftest.two
+ then
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+
+ done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ INSTALL=$ac_install_sh
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
+$as_echo_n "checking whether ln -s works... " >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
+$as_echo "no, using $LN_S" >&6; }
+fi
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+ as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if ${ac_cv_build+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+ ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+ as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if ${ac_cv_host+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$host_alias" = x; then
+ ac_cv_host=$ac_cv_build
+else
+ ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_RANLIB" = x; then
+ RANLIB=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ RANLIB=$ac_ct_RANLIB
+ fi
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ar; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AR="${ac_tool_prefix}ar"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_AR"; then
+ ac_ct_AR=$AR
+ # Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AR"; then
+ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_AR="ar"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_AR" = x; then
+ AR="ar"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ AR=$ac_ct_AR
+ fi
+else
+ AR="$ac_cv_prog_AR"
+fi
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}nm", so it can be a program name with args.
+set dummy ${ac_tool_prefix}nm; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_NM+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NM"; then
+ ac_cv_prog_NM="$NM" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_NM="${ac_tool_prefix}nm"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+NM=$ac_cv_prog_NM
+if test -n "$NM"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NM" >&5
+$as_echo "$NM" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_NM"; then
+ ac_ct_NM=$NM
+ # Extract the first word of "nm", so it can be a program name with args.
+set dummy nm; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_NM+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_NM"; then
+ ac_cv_prog_ac_ct_NM="$ac_ct_NM" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_NM="nm"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_NM=$ac_cv_prog_ac_ct_NM
+if test -n "$ac_ct_NM"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NM" >&5
+$as_echo "$ac_ct_NM" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_NM" = x; then
+ NM="nm"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ NM=$ac_ct_NM
+ fi
+else
+ NM="$ac_cv_prog_NM"
+fi
+
+
+echo 'CC = ' $CC `which $CC`
+echo 'CXX = ' $CXX `which $CXX`
+
+
+
+FORCESOLINKING="no"
+
+USESOLINKING="no"
+
+INSTALLMANPAGES='install-manpages'
+
+LIBSPRIVATE=""
+
+MANINST='auto'
+
+EXVAL=0
+
+SOLCOR='no'
+
+CFPIC=''
+MKSOLIB=''
+SHLIBSTYLE=''
+UNAME=''
+WXCPPFLAGS=''
+WXCXXFLAGS=''
+WXCFLAGS=''
+WXLDFLAGS=''
+SUITE='auto'
+ENASTATIC='auto'
+ENASHARED='auto'
+PROGRAMS=''
+LIBRARIES=''
+LIBS_STATIC=''
+LIBS_SHARED=''
+LIBS_INSTALL=''
+RES_INSTALL=''
+RPATH=''
+RPATHLINK=''
+CWARN=''
+FOUND_GDBM='no'
+FOUND_NDBM='no'
+FOUND_BDB='no'
+USE_NDBM='auto'
+NET_PROG_RES=''
+NET_PROG_CLI=''
+MYSQL_PROG_CLI=''
+SNMP_PROG_CLI=''
+MYSQLLDFLAGS=''
+MYSQLLIB=''
+RTLIB=''
+SOLIBZ=''
+SOLIBBZ=''
+SOLIBMATH=''
+SOLIBCRYPTO=''
+SOLIBNET=''
+SOLIBIMG=''
+SOLIBSDBI=''
+SOLIBWX=''
+SOLIBDK3PORT=''
+SOLIBDK3C=''
+SOLIBDK3OF=''
+SOLIBDK3CSRND=''
+SOLIBDK3BIF=''
+SOLIBDK3DBI=''
+SOLIBDK3FIG=''
+SOLIBDK3BMEPS=''
+SOLIBDK3NET=''
+SOLIBDK4BASE=''
+SOLIBDK4MA=''
+SOLIBDK4MAIO8H=''
+SOLIBDK4MAIOWH=''
+SOLIBDK4MAIODH=''
+SOLIBDK4MAIO8D=''
+SOLIBDK4MAIOWD=''
+SOLIBDK4MAIODD=''
+SOLIBDK4C=''
+SOLIBDK4MDRND=''
+SOLIBDK4PPPT=''
+SOLIBDK4APP=''
+SOLIBDK4LAT=''
+SOLIBDK4SOCK=''
+SOLIBDK4SOCKA=''
+SOLIBDK4DBI=''
+SOLIBDK4DBIA=''
+LIBDK4BASELIBF=''
+LIBDK4BASELIBS=''
+LIBDK4MALIBF=''
+LIBDK4MALIBS=''
+LIBDK4MAIO8DLIBF=''
+LIBDK4MAIO8DLIBS=''
+LIBDK4MAIOWDLIBF=''
+LIBDK4MAIOWDLIBS=''
+LIBDK4MAIODDLIBF=''
+LIBDK4MAIODDLIBS=''
+LIBDK4MAIOXDLIBF=''
+LIBDK4MAIOXDLIBS=''
+LIBDK4MAIO8HLIBF=''
+LIBDK4MAIO8HLIBS=''
+LIBDK4MAIOWHLIBF=''
+LIBDK4MAIOWHLIBS=''
+LIBDK4MAIODHLIBF=''
+LIBDK4MAIODHLIBS=''
+LIBDK4DBILIBF=''
+LIBDK4DBILIBS=''
+LIBDK4CLIBF=''
+LIBDK4CLIBS=''
+LIBDK4LATLIBF=''
+LIBDK4LATLIBS=''
+LIBDK4SOCKLIBF=''
+LIBDK4SOCKLIBS=''
+LIBDK4MDRNDLIBF=''
+LIBDK4MDRNDLIBS=''
+LIBDK4PPPTLIBF=''
+LIBDK4PPPTLIBS=''
+LIBDK4APPLIBF=''
+LIBDK4APPLIBS=''
+LIBDK4PPPTALIBF=''
+LIBDK4PPPTALIBS=''
+LIBDK4SOCKALIBF=''
+LIBDK4SOCKALIBS=''
+LIBDK4DBIALIBF=''
+LIBDK4DBIALIBS=''
+LIBDK4WXLIBF=''
+LIBDK4WXLIBS=''
+LIBDK3TRACELIBF=''
+LIBDK3TRACELIBS=''
+LIBDK3CLIBF=''
+LIBDK3CLIBS=''
+LIBDK3OFLIBF=''
+LIBDK3OFLIBS=''
+LIBDK3CSRNDLIBF=''
+LIBDK3CSRNDLIBS=''
+LIBDK3BIFLIBF=''
+LIBDK3BIFLIBS=''
+LIBDK3DBILIBF=''
+LIBDK3DBILIBS=''
+LIBDK3BMEPSLIBF=''
+LIBDK3BMEPSLIBS=''
+LIBDK3FIGLIBF=''
+LIBDK3FIGLIBS=''
+LIBDK3WXLIBF=''
+LIBDK3WXLIBS=''
+
+
+VERSNO=`cat version.txt`
+SOVERS=`echo $VERSNO | sed -e 's/\.[01-9][01-9]*$//'`
+ENAPACKAGING="auto"
+LIB_SH_RES='$(LIB_SH_RES_NO_PACKAGING)'
+LIB_SH_CLI='$(LIB_SH_CLI_NO_PACKAGING)'
+UNAME=`uname -s`
+GETSOURCE='@echo "ERROR: Neither wget nor curl available, can not download source!" && false'
+WGET=''
+CURL=''
+CLILIB=''
+GUILIB=''
+ENTRY=''
+ONWINDOWS='no'
+WINUNICODE=''
+FOUNDINLINE="no"
+USEINLINE="no"
+CROSSCOMPILING="no"
+
+MAKE="echo No make program found to build"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking GNU make" >&5
+$as_echo_n "checking GNU make... " >&6; }
+gmake maketest > /dev/null 2>&1
+if [ "X$?" = "X0" ]
+then
+ MAKE='gmake'
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking make" >&5
+$as_echo_n "checking make... " >&6; }
+make maketest > /dev/null 2>&1
+if [ "X$?" = "X0" ]
+then
+ MAKE='make'
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+# Check whether --enable-inline was given.
+if test "${enable_inline+set}" = set; then :
+ enableval=$enable_inline; USEINLINE="$enableval"
+fi
+
+# Check whether --enable-static was given.
+if test "${enable_static+set}" = set; then :
+ enableval=$enable_static; ENASTATIC="$enableval"
+fi
+
+# Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then :
+ enableval=$enable_shared; ENASHARED="$enableval"
+fi
+
+# Check whether --enable-packaging was given.
+if test "${enable_packaging+set}" = set; then :
+ enableval=$enable_packaging; ENAPACKAGING="$enableval"
+fi
+
+# Check whether --enable-ndbm was given.
+if test "${enable_ndbm+set}" = set; then :
+ enableval=$enable_ndbm; USE_NDBM="$enableval"
+fi
+
+# Check whether --enable-warnings was given.
+if test "${enable_warnings+set}" = set; then :
+ enableval=$enable_warnings; WARNVAL="$enableval"
+fi
+
+# Check whether --enable-more-warnings was given.
+if test "${enable_more_warnings+set}" = set; then :
+ enableval=$enable_more_warnings; WARNMOREVAL="$enableval"
+fi
+
+
+# Check whether --with-suite was given.
+if test "${with_suite+set}" = set; then :
+ withval=$with_suite; SUITE="$withval"
+fi
+
+
+# Check whether --with-man was given.
+if test "${with_man+set}" = set; then :
+ withval=$with_man; MANINST="$withval"
+fi
+
+
+# Check whether --with-corrections was given.
+if test "${with_corrections+set}" = set; then :
+ withval=$with_corrections; SOLCOR="$withval"
+fi
+
+
+if [ "X$SOLCOR" = "Xyes" -a "X$UNAME" != "XSunOS" ]
+then
+ echo 'ERROR: The --with-corrections option is for Solaris/SunOS only!'
+ SOLCOR='no'
+fi
+
+if [ "X$host" != "X$build" ]
+then
+ echo 'Building on: ' $build
+ echo 'Building for:' $host
+ CROSSCOMPILING="yes"
+ case "X$SUITE" in
+ "gui")
+ echo "Warning: Cross-compiling, switching suite to cross."
+ ;;
+ "cli")
+ echo "Warning: Cross-compiling, switching suite to cross."
+ ;;
+ esac
+ SUITE="cross"
+fi
+
+case "X$ENAPACKAGING" in
+ "Xauto")
+ if [ "X$SUITE" = "Xrescue" ]
+ then
+ ENAPACKAGING="yes"
+ else
+ ENAPACKAGING="no"
+ fi
+ ;;
+ "Xyes")
+ ENAPACKAGING="yes"
+ ;;
+ *)
+ ENAPACKAGING="no"
+ ;;
+esac
+
+UNAME=`uname -s`
+if [ "X$CC" = "Xgcc" ]
+then
+ SHLIBSTYLE='gcc'
+ RPATHLINK="-Wl,-rpath-link,./"
+elif [ "X$UNAME" = "XSunOS" ]
+then
+ SHLIBSTYLE='workshop'
+fi
+
+if [ "X$CC" = "Xgcc" -a "X$WARNVAL" != "Xno" ]
+then
+ # Enable all warnings and some extra warnings
+ CWARN="-Wall"
+ WARNVAL=yes
+else
+ WARNVAL=no
+fi
+
+if [ "X$CC" = "Xgcc" -a "X$WARNMOREVAL" == "Xyes" ]
+then
+ # Extra warnings
+ CWARN="$CWARN -Wextra"
+ # Overlong strings (C89: 509 characters, C99: 4095 characters)
+ CWARN="$CWARN -Woverlength-strings"
+ # Padding bytes added to structures
+ CWARN="$CWARN -Wpadded"
+ # Redundant declarations
+ CWARN="$CWARN -Wredundant-decls"
+ # Suspicious logical operators in expressions
+ CWARN="$CWARN -Wlogical-op"
+ # Functions returning entire structures
+ CWARN="$CWARN -Waggregate-return"
+ # Prototypes required before function use
+ CWARN="$CWARN -Wstrict-prototypes"
+ # Old style function definitions
+ CWARN="$CWARN -old-style-definition"
+ # Prototypes missing for global functions (must be in a header)
+ CWARN="$CWARN -Wmissing-prototypes"
+ # Global function defined without a previous prototype
+ CWARN="$CWARN -Wmissing-declarations"
+ # "exern" definition in a function
+ CWARN="$CWARN -Wnested-externs"
+ # Unreachable code in a program
+ CWARN="$CWARN -Wunreachable-code"
+ # Failed to inline a function
+ CWARN="$CWARN -Winline"
+ # Invalid PCH file found
+ CWARN="$CWARN -Winvalid-pch"
+ # Variable length array
+ CWARN="$CWARN -Wvla"
+ # Using signed pointers
+ CWARN="$CWARN -Wpointer-sign"
+ # The stack protector can not handle some function
+ CWARN="$CWARN -Wstack-protector"
+ WARNMOREVAL="yes"
+else
+ WARNMOREVAL="no"
+fi
+
+case "X$ENASHARED" in
+ "Xauto")
+ if [ "X$SHLIBSTYLE" = "Xgcc" -o "X$SHLIBSTYLE" = "Xworkshop" ]
+ then
+ ENASHARED='yes'
+ else
+ ENASHARED='no'
+ fi
+ ;;
+ "Xyes")
+ if [ "X$SHLIBSTYLE" = "Xgcc" -o "X$SHLIBSTYLE" = "Xworkshop" ]
+ then
+ ENASHARED='yes'
+ else
+ ENASHARED='no'
+ as_fn_error $? "Can not build shared libraries!" "$LINENO" 5
+ exit 1
+ fi
+ ;;
+ *)
+ ENASHARED='no'
+ ;;
+esac
+
+if [ "X$ENASTATIC" = "Xauto" ]
+then
+ case "X$ENASHARED" in
+ "Xyes")
+ ENASTATIC='no'
+ ;;
+ "Xno")
+ ENASTATIC='yes'
+ ;;
+ esac
+fi
+if [ "X$ENASTATIC" != "Xyes" -a "X$ENASTATIC" != "Xno" ]
+then
+ ENASTATIC='no'
+fi
+
+WXCPPFLAGS=`wx-config --cppflags`
+WXCXXFLAGS=`wx-config --cxxflags`
+WXVERSION=`wx-config --version`
+WXCFLAGS=`wx-config --cflags`
+WXLDFLAGS=`wx-config --libs`
+case "X$SUITE" in
+ "Xauto")
+ SUITE='gui'
+ if [ "X$WXCPPFLAGS" = "X" ]
+ then
+ SUITE="cli"
+ fi
+ if [ "X$WXCXXFLAGS" = "X" ]
+ then
+ SUITE="cli"
+ fi
+ if [ "X$WXCFLAGS" = "X" ]
+ then
+ SUITE="cli"
+ fi
+ if [ "X$WXLDFLAGS" = "X" ]
+ then
+ SUITE="cli"
+ fi
+ ;;
+ "Xgui")
+ if [ "X$WXCPPFLAGS" = "X" ]
+ then
+ SUITE="cli"
+ fi
+ if [ "X$WXCXXFLAGS" = "X" ]
+ then
+ SUITE="cli"
+ fi
+ if [ "X$WXCFLAGS" = "X" ]
+ then
+ SUITE="cli"
+ fi
+ if [ "X$WXLDFLAGS" = "X" ]
+ then
+ SUITE="cli"
+ fi
+ if [ "X$SUITE" != "Xgui" ]
+ then
+ as_fn_error $? "Can not build GUI applications, wxWidgets not found!" "$LINENO" 5
+ exit 1
+ fi
+ ;;
+ "Xcli")
+ SUITE='cli'
+ ;;
+ "Xrescue")
+ SUITE='rescue'
+ ;;
+ "Xcross")
+ SUITE='cross'
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unknown suite type $SUITE changed to cli." >&5
+$as_echo "$as_me: WARNING: Unknown suite type $SUITE changed to cli." >&2;}
+ SUITE='cli'
+ ;;
+esac
+
+if [ "X$RANLIB" = "X:" ]
+then
+ RANLIB="@echo No need to run ranlib"
+fi
+# Extract the first word of "wget", so it can be a program name with args.
+set dummy wget; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_WGET+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$WGET"; then
+ ac_cv_prog_WGET="$WGET" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_WGET="wget"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+WGET=$ac_cv_prog_WGET
+if test -n "$WGET"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WGET" >&5
+$as_echo "$WGET" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of "curl", so it can be a program name with args.
+set dummy curl; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CURL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CURL"; then
+ ac_cv_prog_CURL="$CURL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CURL="curl"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CURL=$ac_cv_prog_CURL
+if test -n "$CURL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CURL" >&5
+$as_echo "$CURL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+if [ "X$SUITE" = "Xrescue" ]
+then
+ PROGRAMS='$(PROG_RES)'
+ LIBS_STATIC='$(LIB_ST_RES)'
+ LIBS_SHARED='$(LIB_SH_RES)'
+ RES_INSTALL='i-r-res'
+ INSTALLMANPAGES='install-rescue-man'
+ case "$ENASHARED/$ENASTATIC" in
+ "yes/yes")
+ LIBRARIES='$(LIB_SH_RES) $(LIB_ST_RES)'
+ ;;
+ "yes/no")
+ LIBRARIES='$(LIB_SH_RES)'
+ ;;
+ "no/yes")
+ LIBRARIES='$(LIB_ST_RES)'
+ ;;
+ esac
+ case "X$ENAPACKAGING" in
+ "Xyes")
+ LIBS_INSTALL='i-l-sh'
+ ;;
+ esac
+ LIBRARIES=''
+elif [ "X$SUITE" = "Xgui" ]
+then
+ PROGRAMS='$(PROG_GUI)'
+ LIBS_STATIC='$(LIB_ST_GUI)'
+ LIBS_SHARED='$(LIB_SH_GUI)'
+ RES_INSTALL='i-r-gui'
+ case "$ENASHARED/$ENASTATIC" in
+ "yes/yes")
+ LIBRARIES='$(LIB_SH_GUI) $(LIB_ST_GUI)'
+ LIBS_INSTALL='i-l-sh i-l-st i-incl'
+ ;;
+ "yes/no")
+ LIBRARIES='$(LIB_SH_GUI)'
+ LIBS_INSTALL='i-l-sh i-incl'
+ ;;
+ "no/yes")
+ LIBRARIES='$(LIB_ST_GUI)'
+ LIBS_INSTALL='i-l-st i-incl'
+ ;;
+ esac
+elif [ "X$SUITE" = "Xcross" ]
+then
+ PROGRAMS='$(PROG_CROSS)'
+ LIBS_STATIC='$(LIB_ST_CLI)'
+ LIBS_SHARED='$(LIB_SH_CLI)'
+ RES_INSTALL='i-r-cli'
+ case "$ENASHARED/$ENASTATIC" in
+ "yes/yes")
+ LIBRARIES='$(LIB_SH_CLI) $(LIB_ST_CLI)'
+ LIBS_INSTALL='i-l-sh i-l-st i-incl'
+ ;;
+ "yes/no")
+ LIBRARIES='$(LIB_SH_CLI)'
+ LIBS_INSTALL='i-l-sh i-incl'
+ ;;
+ "no/yes")
+ LIBRARIES='$(LIB_ST_CLI)'
+ LIBS_INSTALL='i-l-st i-incl'
+ ;;
+ esac
+ LIBRARIES='$(LIB_ST_CLI)'
+ LIBS_INSTALL='i-l-st i-incl'
+ ENASHARED='no'
+ ENASTATIC='yes'
+ case "X$host" in
+ "Xx86_64-w64-mingw32")
+ ONWINDOWS="yes"
+ WINUNICODE="-D_UNICODE=1 -DUNICODE=1"
+ $as_echo "#define HAVE_BACKSLASH_AS_SEP 1" >>confdefs.h
+
+ $as_echo "#define HAVE_LINE_END_CR_NL 1" >>confdefs.h
+
+ $as_echo "#define HAVE_CASE_INSENSITIVE_PATHNAMES 1" >>confdefs.h
+
+ ;;
+ esac
+else
+ PROGRAMS='$(PROG_CLI)'
+ LIBS_STATIC='$(LIB_ST_CLI)'
+ LIBS_SHARED='$(LIB_SH_CLI)'
+ RES_INSTALL='i-r-cli'
+ case "$ENASHARED/$ENASTATIC" in
+ "yes/yes")
+ LIBRARIES='$(LIB_SH_CLI) $(LIB_ST_CLI)'
+ LIBS_INSTALL='i-l-sh i-l-st i-incl'
+ ;;
+ "yes/no")
+ LIBRARIES='$(LIB_SH_CLI)'
+ LIBS_INSTALL='i-l-sh i-incl'
+ ;;
+ "no/yes")
+ LIBRARIES='$(LIB_ST_CLI)'
+ LIBS_INSTALL='i-l-st i-incl'
+ ;;
+ esac
+fi
+
+if [ "X$ENASHARED" = "Xno" ]
+then
+ ENAPACKAGING="no"
+fi
+
+APPLIBF="libdk4app.so libdk4c.so"
+if [ "X$CROSSCOMPILING" = "Xyes" ]
+then
+ APPLIBF="$APPLIBF libdk4ma.so libdk4maiodd.so libdk4maiowd.so libdk4maio8d.so"
+else
+ APPLIBF="$APPLIBF libdk4ma.so libdk4maiodd.so libdk4maio8d.so"
+fi
+APPLIBF="$APPLIBF libdk4base.so"
+
+APPLIBS="-ldk4app -ldk4c"
+if [ "X$CROSSCOMPILING" = "Xyes" ]
+then
+ APPLIBS="$APPLIBS -ldk4ma -ldk4maiodd -ldk4maiowd -ldk4maio8d"
+else
+ APPLIBS="$APPLIBS -ldk4ma -ldk4maiodd -ldk4maio8d"
+fi
+APPLIBS="$APPLIBS -ldk4base"
+
+DKCTLIBF='libdk3.a'
+DKCTLIBS='-ldk3 $(CLILIB) $(BZLIB) $(ZLIB)'
+ADDCTRLDLIBF='libdk3.a'
+ADDCTRLDLIBS='-ldk3 $(CLILIB) $(BZLIB) $(ZLIB)'
+DKDBTLIBF='libdk3.a'
+DKDBTLIBS='-ldk3 $(CLILIB) $(BZLIB) $(ZLIB)'
+ITADMINLIBF='libdk3.a'
+ITADMINLIBS='-ldk3 -lmysqlclient $(CLILIB) $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) $(RTLIB)'
+BMPPLIBF='libdk3.a'
+BMPPLIBS='-ldk3 $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB) -lm'
+FIG2LATLIBF='libdk3.a'
+FIG2LATLIBS='-ldk3 $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB) -lm'
+HTMLBOOKLIBF='libdk3.a'
+HTMLBOOKLIBS='-ldk3 $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+DK3INFOLIBF='libdk3.a'
+DK3INFOLIBS='-ldk3 $(CLILIB) $(BZLIB) $(ZLIB)'
+PLPDFTEXLIBF='libdk3.a'
+PLPDFTEXLIBS='-ldk3 $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB) -lm'
+DKWXWIZLIBF='libdk3.a'
+DKWXWIZLIBS='-ldk3 $(CLILIB) $(BZLIB) $(ZLIB)'
+WXDKCTLIBF='libdk3.a'
+WXDKCTLIBS='-ldk3 $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+WXBMPPLIBF='libdk3.a'
+WXBMPPLIBS='-ldk3 $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+WXIMGSZLIBF='libdk3.a'
+WXIMGSZLIBS='-ldk3 $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+WXDKCLOCKLIBF='libdk3.a'
+WXDKCLOCKLIBS='-ldk3 $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+WXDKHTBLIBF='libdk3.a'
+WXDKHTBLIBS='-ldk3 $(WXLDFLAGS) $(GUILIB) $(CLILIB) $(BZLIB) $(ZLIB)'
+PRINTQDILIBF='libdk3.a'
+PRINTQDILIBS='-ldk3 $(CLILIB) $(BZLIB) $(ZLIB)'
+PRINTQDALIBF='libdk3.a'
+PRINTQDALIBS='-ldk3 $(CLILIB) $(BZLIB) $(ZLIB)'
+
+DKCATLIBF="libdk4.a"
+DKCATLIBS='-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)'
+DKBLKSLIBF="libdk4.a"
+DKBLKSLIBS='-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)'
+DKSQLSPLITLIBF="libdk4.a"
+DKSQLSPLITLIBS='-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)'
+DKERADISKLIBF="libdk4.a"
+DKERADISKLIBS='-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)'
+DKLSLIBF="libdk4.a"
+DKLSLIBS='-ldk4 $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+DKSORTLIBF="libdk4.a"
+DKSORTLIBS='-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)'
+DKFICLIBF="libdk4.a"
+DKFICLIBS='-ldk4 $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+DKUIDLIBF="libdk4.a"
+DKUIDLIBS='-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)'
+DKPWGENLIBF="libdk4.a"
+DKPWGENLIBS='-ldk4 $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+DKRANDLIBF="libdk4.a"
+DKRANDLIBS='-ldk4 $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+DKT2HLIBF="libdk4.a"
+DKT2HLIBS='-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)'
+DKT2LLIBF="libdk4.a"
+DKT2LLIBS='-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)'
+DKHEXLIBF="libdk4.a"
+DKHEXLIBS='-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)'
+DKBMMLIBF="libdk4.a"
+DKBMMLIBS='-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)'
+DKPWDLIBF="libdk4.a"
+DKPWDLIBS='-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)'
+DKRECVLIBF="libdk4.a"
+DKRECVLIBS='-ldk4 $(CLILIB) $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) -lm'
+DKSENDLIBF="libdk4.a"
+DKSENDLIBS='-ldk4 $(CLILIB) $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) -lm'
+DKDBT2LIBF="libdk4.a"
+DKDBT2LIBS='-ldk4 $(DBLIBSOCK) $(CLILIB) $(BZLIB) $(ZLIB)'
+DK4INFOLIBF="libdk4.a"
+DK4INFOLIBS='-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)'
+LPRNGCLLIBF="libdk4.a"
+LPRNGCLLIBS='-ldk4 $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) -lm'
+WXDKFCSLIBF="libdk4.a"
+WXDKFCSLIBS='-ldk4 $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+WXPQDICLIBF="libdk4.a"
+WXPQDICLIBS='-ldk4 $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+PJSNMPLIBF="libdk4.a"
+PJSNMPLIBS='-ldk4 $(NETSNMP_LIBS) $(SOCKLIB) $(NSLLIB)'
+PRMONSNMPLIBF="libdk4.a"
+PRMONSNMPLIBS='-ldk4 $(NETSNMP_LIBS) $(SOCKLIB) $(NSLLIB)'
+PRINTQDLIBF="libdk4.a"
+PRINTQDLIBS='-ldk4 $(DBLIB) $(SOCKLIB) $(NSLLIB)'
+PRINTQDCLIBF="libdk4.a"
+PRINTQDCLIBS='-ldk4 $(SOCKLIB) $(NSLLIB)'
+RSHDOWNLIBF="libdk4.a"
+RSHDOWNLIBS='-ldk4 $(SOCKLIB) $(NSLLIB)'
+
+LIB_SH_RES='$(LIB_SH_RES_NO_PACKAGING)'
+LIB_SH_CLI='$(LIB_SH_CLI_NO_PACKAGING)'
+LIB_SH_GUI='$(LIB_SH_GUI_NO_PACKAGING)'
+if [ "X$ENAPACKAGING" = "Xyes" ]
+then
+LIB_SH_RES='$(LIB_SH_RES_PACKAGING)'
+LIB_SH_CLI='$(LIB_SH_CLI_PACKAGING)'
+LIB_SH_GUI='$(LIB_SH_GUI_PACKAGING)'
+fi
+
+if [ "X$CC" = "Xgcc" -a "X$UNAME" = "XLinux" ]
+then
+ USESOLINKING="yes"
+fi
+if [ "X$SHLIBSTYLE" = "Xworkshop" -o "X$FORCESOLINKING" = "Xyes" ]
+then
+ USESOLINKING="yes"
+fi
+
+
+case "X$SHLIBSTYLE" in
+ "Xgcc")
+ CFPIC='-fPIC -D_REENTRANT'
+ if [ "X$USESOLINKING" = "Xyes" ]
+ then
+ MKSOLIB='$(COMPILEC) -L. $(RPATHLINK) $(LIBRARIES) $(LDFLAGS) -shared -o $@.$(SOVERS) -Wl,-soname,$@.$(SOVERS)'
+ else
+ MKSOLIB='$(COMPILEC) $(LIBRARIES) $(LDFLAGS) -shared -o $@.$(SOVERS) -Wl,-soname,$@.$(SOVERS)'
+ fi
+ ;;
+ "Xworkshop")
+ if [ "X$ENASHARED" != "Xno" ]
+ then
+ CFPIC='-Bdynamic -dy -xcode=pic32 -D_REENTRANT'
+ else
+ CFPIC='-xcode=pic32 -D_REENTRANT'
+ fi
+ MKSOLIB='$(COMPILEC) -L. $(LIBRARIES) $(LDFLAGS) -G -h $@.$(SOVERS) -o $@.$(SOVERS)'
+ ;;
+esac
+
+if [ "X$LD_LIBRARY_PATH" != "X" -a "X$SHLIBSTYLE" = "Xworkshop" ]
+then
+ RPATH="-R${LD_LIBRARY_PATH}"
+fi
+
+ac_fn_c_check_header_mongrel "$LINENO" "errno.h" "ac_cv_header_errno_h" "$ac_includes_default"
+if test "x$ac_cv_header_errno_h" = xyes; then :
+ $as_echo "#define HAVE_ERRNO_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "assert.h" "ac_cv_header_assert_h" "$ac_includes_default"
+if test "x$ac_cv_header_assert_h" = xyes; then :
+ $as_echo "#define HAVE_ASSERT_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "complex.h" "ac_cv_header_complex_h" "$ac_includes_default"
+if test "x$ac_cv_header_complex_h" = xyes; then :
+ $as_echo "#define HAVE_COMPLEX_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "ctype.h" "ac_cv_header_ctype_h" "$ac_includes_default"
+if test "x$ac_cv_header_ctype_h" = xyes; then :
+ $as_echo "#define HAVE_CTYPE_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "fenv.h" "ac_cv_header_fenv_h" "$ac_includes_default"
+if test "x$ac_cv_header_fenv_h" = xyes; then :
+ $as_echo "#define HAVE_FENV_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "float.h" "ac_cv_header_float_h" "$ac_includes_default"
+if test "x$ac_cv_header_float_h" = xyes; then :
+ $as_echo "#define HAVE_FLOAT_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "inttypes.h" "ac_cv_header_inttypes_h" "$ac_includes_default"
+if test "x$ac_cv_header_inttypes_h" = xyes; then :
+ $as_echo "#define HAVE_INTTYPES_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "iso646.h" "ac_cv_header_iso646_h" "$ac_includes_default"
+if test "x$ac_cv_header_iso646_h" = xyes; then :
+ $as_echo "#define HAVE_ISO646_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "limits.h" "ac_cv_header_limits_h" "$ac_includes_default"
+if test "x$ac_cv_header_limits_h" = xyes; then :
+ $as_echo "#define HAVE_LIMITS_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "locale.h" "ac_cv_header_locale_h" "$ac_includes_default"
+if test "x$ac_cv_header_locale_h" = xyes; then :
+ $as_echo "#define HAVE_LOCALE_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "math.h" "ac_cv_header_math_h" "$ac_includes_default"
+if test "x$ac_cv_header_math_h" = xyes; then :
+ $as_echo "#define HAVE_MATH_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "setjmp.h" "ac_cv_header_setjmp_h" "$ac_includes_default"
+if test "x$ac_cv_header_setjmp_h" = xyes; then :
+ $as_echo "#define HAVE_SETJMP_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "signal.h" "ac_cv_header_signal_h" "$ac_includes_default"
+if test "x$ac_cv_header_signal_h" = xyes; then :
+ $as_echo "#define HAVE_SIGNAL_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "stdalign.h" "ac_cv_header_stdalign_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdalign_h" = xyes; then :
+ $as_echo "#define HAVE_STDALIGN_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "stdarg.h" "ac_cv_header_stdarg_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdarg_h" = xyes; then :
+ $as_echo "#define HAVE_STDARG_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "stdatomic.h" "ac_cv_header_stdatomic_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdatomic_h" = xyes; then :
+ $as_echo "#define HAVE_STDATOMIC_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "stdbool.h" "ac_cv_header_stdbool_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdbool_h" = xyes; then :
+ $as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "stddef.h" "ac_cv_header_stddef_h" "$ac_includes_default"
+if test "x$ac_cv_header_stddef_h" = xyes; then :
+ $as_echo "#define HAVE_STDDEF_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "stdint.h" "ac_cv_header_stdint_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdint_h" = xyes; then :
+ $as_echo "#define HAVE_STDINT_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdlib_h" = xyes; then :
+ $as_echo "#define HAVE_STDLIB_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "stdnoreturn.h" "ac_cv_header_stdnoreturn_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdnoreturn_h" = xyes; then :
+ $as_echo "#define HAVE_STDNORETURN_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "string.h" "ac_cv_header_string_h" "$ac_includes_default"
+if test "x$ac_cv_header_string_h" = xyes; then :
+ $as_echo "#define HAVE_STRING_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "tgmath.h" "ac_cv_header_tgmath_h" "$ac_includes_default"
+if test "x$ac_cv_header_tgmath_h" = xyes; then :
+ $as_echo "#define HAVE_TGMATH_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "threads.h" "ac_cv_header_threads_h" "$ac_includes_default"
+if test "x$ac_cv_header_threads_h" = xyes; then :
+ $as_echo "#define HAVE_THREADS_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "time.h" "ac_cv_header_time_h" "$ac_includes_default"
+if test "x$ac_cv_header_time_h" = xyes; then :
+ $as_echo "#define HAVE_TIME_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "uchar.h" "ac_cv_header_uchar_h" "$ac_includes_default"
+if test "x$ac_cv_header_uchar_h" = xyes; then :
+ $as_echo "#define HAVE_UCHAR_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "wchar.h" "ac_cv_header_wchar_h" "$ac_includes_default"
+if test "x$ac_cv_header_wchar_h" = xyes; then :
+ $as_echo "#define HAVE_WCHAR_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "wctype.h" "ac_cv_header_wctype_h" "$ac_includes_default"
+if test "x$ac_cv_header_wctype_h" = xyes; then :
+ $as_echo "#define HAVE_WCTYPE_H 1" >>confdefs.h
+
+fi
+
+
+
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/types.h" "ac_cv_header_sys_types_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_types_h" = xyes; then :
+ $as_echo "#define HAVE_SYS_TYPES_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/param.h" "ac_cv_header_sys_param_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_param_h" = xyes; then :
+ $as_echo "#define HAVE_SYS_PARAM_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/stat.h" "ac_cv_header_sys_stat_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_stat_h" = xyes; then :
+ $as_echo "#define HAVE_SYS_STAT_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/time.h" "ac_cv_header_sys_time_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_time_h" = xyes; then :
+ $as_echo "#define HAVE_SYS_TIME_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/socket.h" "ac_cv_header_sys_socket_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_socket_h" = xyes; then :
+ $as_echo "#define HAVE_SYS_SOCKET_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/select.h" "ac_cv_header_sys_select_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_select_h" = xyes; then :
+ $as_echo "#define HAVE_SYS_SELECT_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/un.h" "ac_cv_header_sys_un_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_un_h" = xyes; then :
+ $as_echo "#define HAVE_SYS_UN_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "netinet/in.h" "ac_cv_header_netinet_in_h" "$ac_includes_default"
+if test "x$ac_cv_header_netinet_in_h" = xyes; then :
+ $as_echo "#define HAVE_NETINET_IN_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "netinet/in6.h" "ac_cv_header_netinet_in6_h" "$ac_includes_default"
+if test "x$ac_cv_header_netinet_in6_h" = xyes; then :
+ $as_echo "#define HAVE_NETINET_IN6_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "netdb.h" "ac_cv_header_netdb_h" "$ac_includes_default"
+if test "x$ac_cv_header_netdb_h" = xyes; then :
+ $as_echo "#define HAVE_NETDB_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "arpa/inet.h" "ac_cv_header_arpa_inet_h" "$ac_includes_default"
+if test "x$ac_cv_header_arpa_inet_h" = xyes; then :
+ $as_echo "#define HAVE_ARPA_INET_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "winsock2.h" "ac_cv_header_winsock2_h" "$ac_includes_default"
+if test "x$ac_cv_header_winsock2_h" = xyes; then :
+ $as_echo "#define HAVE_WINSOCK2_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "ws2tcpip.h" "ac_cv_header_ws2tcpip_h" "$ac_includes_default"
+if test "x$ac_cv_header_ws2tcpip_h" = xyes; then :
+ $as_echo "#define HAVE_WS2TCPIP_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "windows.h" "ac_cv_header_windows_h" "$ac_includes_default"
+if test "x$ac_cv_header_windows_h" = xyes; then :
+ $as_echo "#define HAVE_WINDOWS_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "unistd.h" "ac_cv_header_unistd_h" "$ac_includes_default"
+if test "x$ac_cv_header_unistd_h" = xyes; then :
+ $as_echo "#define HAVE_UNISTD_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "process.h" "ac_cv_header_process_h" "$ac_includes_default"
+if test "x$ac_cv_header_process_h" = xyes; then :
+ $as_echo "#define HAVE_PROCESS_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "fcntl.h" "ac_cv_header_fcntl_h" "$ac_includes_default"
+if test "x$ac_cv_header_fcntl_h" = xyes; then :
+ $as_echo "#define HAVE_FCNTL_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "share.h" "ac_cv_header_share_h" "$ac_includes_default"
+if test "x$ac_cv_header_share_h" = xyes; then :
+ $as_echo "#define HAVE_SHARE_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "pwd.h" "ac_cv_header_pwd_h" "$ac_includes_default"
+if test "x$ac_cv_header_pwd_h" = xyes; then :
+ $as_echo "#define HAVE_PWD_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "strings.h" "ac_cv_header_strings_h" "$ac_includes_default"
+if test "x$ac_cv_header_strings_h" = xyes; then :
+ $as_echo "#define HAVE_STRINGS_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "io.h" "ac_cv_header_io_h" "$ac_includes_default"
+if test "x$ac_cv_header_io_h" = xyes; then :
+ $as_echo "#define HAVE_IO_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "bios.h" "ac_cv_header_bios_h" "$ac_includes_default"
+if test "x$ac_cv_header_bios_h" = xyes; then :
+ $as_echo "#define HAVE_BIOS_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "dos.h" "ac_cv_header_dos_h" "$ac_includes_default"
+if test "x$ac_cv_header_dos_h" = xyes; then :
+ $as_echo "#define HAVE_DOS_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "alloc.h" "ac_cv_header_alloc_h" "$ac_includes_default"
+if test "x$ac_cv_header_alloc_h" = xyes; then :
+ $as_echo "#define HAVE_ALLOC_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "malloc.h" "ac_cv_header_malloc_h" "$ac_includes_default"
+if test "x$ac_cv_header_malloc_h" = xyes; then :
+ $as_echo "#define HAVE_MALLOC_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "dirent.h" "ac_cv_header_dirent_h" "$ac_includes_default"
+if test "x$ac_cv_header_dirent_h" = xyes; then :
+ $as_echo "#define HAVE_DIRENT_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "direct.h" "ac_cv_header_direct_h" "$ac_includes_default"
+if test "x$ac_cv_header_direct_h" = xyes; then :
+ $as_echo "#define HAVE_DIRECT_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_zlib_h" = xyes; then :
+ ZLIB="-lz";$as_echo "#define HAVE_ZLIB_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "bzlib.h" "ac_cv_header_bzlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_bzlib_h" = xyes; then :
+ BZLIB="-lbz2";$as_echo "#define HAVE_BZLIB_H 1" >>confdefs.h
+
+fi
+
+
+
+CRYPTO=""
+PROGSOPENSSL=""
+ac_fn_c_check_header_mongrel "$LINENO" "openssl/rand.h" "ac_cv_header_openssl_rand_h" "$ac_includes_default"
+if test "x$ac_cv_header_openssl_rand_h" = xyes; then :
+
+CRYPTO="-lcrypto"
+PROGSOPENSSL='dk-fic$(EXEEXT) dk-pwgen$(EXEEXT) dk-rand$(EXEEXT)'
+$as_echo "#define HAVE_OPENSSL_RAND_H 1" >>confdefs.h
+
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "openssl/md5.h" "ac_cv_header_openssl_md5_h" "$ac_includes_default"
+if test "x$ac_cv_header_openssl_md5_h" = xyes; then :
+ $as_echo "#define HAVE_OPENSSL_MD5_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "openssl/sha.h" "ac_cv_header_openssl_sha_h" "$ac_includes_default"
+if test "x$ac_cv_header_openssl_sha_h" = xyes; then :
+ $as_echo "#define HAVE_OPENSSL_SHA_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "openssl/ripemd.h" "ac_cv_header_openssl_ripemd_h" "$ac_includes_default"
+if test "x$ac_cv_header_openssl_ripemd_h" = xyes; then :
+ $as_echo "#define HAVE_OPENSSL_RIPEMD_H 1" >>confdefs.h
+
+fi
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5
+$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; }
+if ${ac_cv_header_time+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+
+int
+main ()
+{
+if ((struct tm *) 0)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_time=yes
+else
+ ac_cv_header_time=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5
+$as_echo "$ac_cv_header_time" >&6; }
+if test $ac_cv_header_time = yes; then
+
+$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h
+
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking longlong" >&5
+$as_echo_n "checking longlong... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+
+int
+main ()
+{
+
+ long long l;
+ l = (long long)0L;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "#define HAVE_LONG_LONG 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking longdouble" >&5
+$as_echo_n "checking longdouble... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <math.h>
+
+int
+main ()
+{
+
+ long double l;
+ l = (long double)0.0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "#define HAVE_LONG_DOUBLE 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+DOINTMAXSIZECHECK="no"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking intmax_t" >&5
+$as_echo_n "checking intmax_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#if HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+int
+main ()
+{
+
+intmax_t im;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ DOINTMAXSIZECHECK="yes";{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "#define HAVE_INTMAX_T 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking volatile" >&5
+$as_echo_n "checking volatile... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+volatile int i = 0;
+
+int
+main ()
+{
+
+i = 1;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "#define HAVE_VOLATILE 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking sig_atomic_t" >&5
+$as_echo_n "checking sig_atomic_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <sys/types.h>
+#include <signal.h>
+
+int
+main ()
+{
+
+sig_atomic_t sat;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "#define HAVE_SIG_ATOMIC_T 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of short" >&5
+$as_echo_n "checking size of short... " >&6; }
+if ${ac_cv_sizeof_short+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (short))" "ac_cv_sizeof_short" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_short" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (short)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_short=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_short" >&5
+$as_echo "$ac_cv_sizeof_short" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_SHORT $ac_cv_sizeof_short
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5
+$as_echo_n "checking size of int... " >&6; }
+if ${ac_cv_sizeof_int+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_int" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (int)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_int=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5
+$as_echo "$ac_cv_sizeof_int" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_INT $ac_cv_sizeof_int
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of size_t" >&5
+$as_echo_n "checking size of size_t... " >&6; }
+if ${ac_cv_sizeof_size_t+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (size_t))" "ac_cv_sizeof_size_t" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_size_t" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (size_t)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_size_t=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_size_t" >&5
+$as_echo "$ac_cv_sizeof_size_t" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_SIZE_T $ac_cv_sizeof_size_t
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5
+$as_echo_n "checking size of long... " >&6; }
+if ${ac_cv_sizeof_long+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_long" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (long)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_long=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5
+$as_echo "$ac_cv_sizeof_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long long" >&5
+$as_echo_n "checking size of long long... " >&6; }
+if ${ac_cv_sizeof_long_long+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long))" "ac_cv_sizeof_long_long" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_long_long" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (long long)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_long_long=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long" >&5
+$as_echo "$ac_cv_sizeof_long_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long
+_ACEOF
+
+
+if [ "X$DOINTMAXSIZECHECK" = "Xyes" ]
+then
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of intmax_t" >&5
+$as_echo_n "checking size of intmax_t... " >&6; }
+if ${ac_cv_sizeof_intmax_t+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (intmax_t))" "ac_cv_sizeof_intmax_t" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_intmax_t" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (intmax_t)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_intmax_t=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_intmax_t" >&5
+$as_echo "$ac_cv_sizeof_intmax_t" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_INTMAX_T $ac_cv_sizeof_intmax_t
+_ACEOF
+
+
+fi
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of double" >&5
+$as_echo_n "checking size of double... " >&6; }
+if ${ac_cv_sizeof_double+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (double))" "ac_cv_sizeof_double" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_double" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (double)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_double=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_double" >&5
+$as_echo "$ac_cv_sizeof_double" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_DOUBLE $ac_cv_sizeof_double
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long double" >&5
+$as_echo_n "checking size of long double... " >&6; }
+if ${ac_cv_sizeof_long_double+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long double))" "ac_cv_sizeof_long_double" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_long_double" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (long double)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_long_double=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_double" >&5
+$as_echo "$ac_cv_sizeof_long_double" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG_DOUBLE $ac_cv_sizeof_long_double
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of wchar_t" >&5
+$as_echo_n "checking size of wchar_t... " >&6; }
+if ${ac_cv_sizeof_wchar_t+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (wchar_t))" "ac_cv_sizeof_wchar_t" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_wchar_t" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (wchar_t)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_wchar_t=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_wchar_t" >&5
+$as_echo "$ac_cv_sizeof_wchar_t" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_WCHAR_T $ac_cv_sizeof_wchar_t
+_ACEOF
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking _LARGEFILE64_SOURCE" >&5
+$as_echo_n "checking _LARGEFILE64_SOURCE... " >&6; }
+FS64=''
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#define _LARGEFILE64_SOURCE 1
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+struct stat64 st;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ FS64='-D_LARGEFILE64_SOURCE=1'
+$as_echo "#define HAVE_LARGEFILE64_SOURCE 1" >>confdefs.h
+
+$as_echo "#define HAVE_TYPE_STAT64 1" >>confdefs.h
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+for ac_func in memset bzero memcpy bcopy memcmp bcmp
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in malloc calloc free
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in strcpy_s strcat_s
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in strcasecmp stricmp _stricmp
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in wcslen wcscpy_s wcscpy wcscat_s wcscat wcschr wcsrchr
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in wcscmp _wcscmp wcscasecmp _wcscasecmp wcsicmp _wcsicmp
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in getpid readlink getexecname lstat stat64 lstat64 localtime_r
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in geteuid fopen64 fopen_s _wfopen _wfopen64 _wfopen_s
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in fputws fputwc
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in setbuffer setbuf setvbuf
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in fileno _fileno setmode _setmode isatty _isatty
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in strtod _strtod wcstod _wcstod
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in _snprintf_s _snprintf snprintf _snwprintf_s _snwprintf snwprintf
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in swprintf
+do :
+ ac_fn_c_check_func "$LINENO" "swprintf" "ac_cv_func_swprintf"
+if test "x$ac_cv_func_swprintf" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SWPRINTF 1
+_ACEOF
+
+fi
+done
+
+for ac_func in unlink _unlink wunlink _wunlink
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in rmdir _rmdir wrmdir _wrmdir
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in mkdir _mkdir wmkdir _wmkdir
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in strerror strerror_r
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in sigaction sigset signal sigprocmask sigemptyset
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in setpwent getpwent endpwent
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in getenv getenv_s setlocale select
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in getcwd _getcwd _wgetcwd
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SHA224_Init in -lcrypto" >&5
+$as_echo_n "checking for SHA224_Init in -lcrypto... " >&6; }
+if ${ac_cv_lib_crypto_SHA224_Init+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypto $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char SHA224_Init ();
+int
+main ()
+{
+return SHA224_Init ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_crypto_SHA224_Init=yes
+else
+ ac_cv_lib_crypto_SHA224_Init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_SHA224_Init" >&5
+$as_echo "$ac_cv_lib_crypto_SHA224_Init" >&6; }
+if test "x$ac_cv_lib_crypto_SHA224_Init" = xyes; then :
+ $as_echo "#define HAVE_SHA224 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SHA256_Init in -lcrypto" >&5
+$as_echo_n "checking for SHA256_Init in -lcrypto... " >&6; }
+if ${ac_cv_lib_crypto_SHA256_Init+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypto $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char SHA256_Init ();
+int
+main ()
+{
+return SHA256_Init ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_crypto_SHA256_Init=yes
+else
+ ac_cv_lib_crypto_SHA256_Init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_SHA256_Init" >&5
+$as_echo "$ac_cv_lib_crypto_SHA256_Init" >&6; }
+if test "x$ac_cv_lib_crypto_SHA256_Init" = xyes; then :
+ $as_echo "#define HAVE_SHA256 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SHA384_Init in -lcrypto" >&5
+$as_echo_n "checking for SHA384_Init in -lcrypto... " >&6; }
+if ${ac_cv_lib_crypto_SHA384_Init+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypto $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char SHA384_Init ();
+int
+main ()
+{
+return SHA384_Init ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_crypto_SHA384_Init=yes
+else
+ ac_cv_lib_crypto_SHA384_Init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_SHA384_Init" >&5
+$as_echo "$ac_cv_lib_crypto_SHA384_Init" >&6; }
+if test "x$ac_cv_lib_crypto_SHA384_Init" = xyes; then :
+ $as_echo "#define HAVE_SHA384 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SHA512_Init in -lcrypto" >&5
+$as_echo_n "checking for SHA512_Init in -lcrypto... " >&6; }
+if ${ac_cv_lib_crypto_SHA512_Init+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypto $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char SHA512_Init ();
+int
+main ()
+{
+return SHA512_Init ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_crypto_SHA512_Init=yes
+else
+ ac_cv_lib_crypto_SHA512_Init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_SHA512_Init" >&5
+$as_echo "$ac_cv_lib_crypto_SHA512_Init" >&6; }
+if test "x$ac_cv_lib_crypto_SHA512_Init" = xyes; then :
+ $as_echo "#define HAVE_SHA512 1" >>confdefs.h
+
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking RAND_egd" >&5
+$as_echo_n "checking RAND_egd... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <openssl/rand.h>
+
+int
+main ()
+{
+
+int i;
+i = RAND_egd("/dev/egd");
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "#define HAVE_RAND_EGD 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_gettime in -lrt" >&5
+$as_echo_n "checking for clock_gettime in -lrt... " >&6; }
+if ${ac_cv_lib_rt_clock_gettime+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lrt $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char clock_gettime ();
+int
+main ()
+{
+return clock_gettime ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_rt_clock_gettime=yes
+else
+ ac_cv_lib_rt_clock_gettime=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_clock_gettime" >&5
+$as_echo "$ac_cv_lib_rt_clock_gettime" >&6; }
+if test "x$ac_cv_lib_rt_clock_gettime" = xyes; then :
+ RTLIB="-lrt"
+fi
+
+
+SOCKLIB=''
+NSLLIB=''
+
+for ac_func in socket
+do :
+ ac_fn_c_check_func "$LINENO" "socket" "ac_cv_func_socket"
+if test "x$ac_cv_func_socket" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SOCKET 1
+_ACEOF
+
+NET_PROG_RES='$(NET_PROG_RES)'
+NET_PROG_CLI='$(NET_PROG_CLI)'
+$as_echo "#define HAVE_SOCKET 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lxnet" >&5
+$as_echo_n "checking for socket in -lxnet... " >&6; }
+if ${ac_cv_lib_xnet_socket+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lxnet $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char socket ();
+int
+main ()
+{
+return socket ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_xnet_socket=yes
+else
+ ac_cv_lib_xnet_socket=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xnet_socket" >&5
+$as_echo "$ac_cv_lib_xnet_socket" >&6; }
+if test "x$ac_cv_lib_xnet_socket" = xyes; then :
+
+NET_PROG_RES='$(NET_PROG_RES)'
+NET_PROG_CLI='$(NET_PROG_CLI)'
+$as_echo "#define HAVE_SOCKET 1" >>confdefs.h
+
+SOCKLIB='-lxnet'
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lsocket" >&5
+$as_echo_n "checking for socket in -lsocket... " >&6; }
+if ${ac_cv_lib_socket_socket+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char socket ();
+int
+main ()
+{
+return socket ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_socket_socket=yes
+else
+ ac_cv_lib_socket_socket=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_socket" >&5
+$as_echo "$ac_cv_lib_socket_socket" >&6; }
+if test "x$ac_cv_lib_socket_socket" = xyes; then :
+
+NET_PROG_RES='$(NET_PROG_RES)'
+NET_PROG_CLI='$(NET_PROG_CLI)'
+$as_echo "#define HAVE_SOCKET 1" >>confdefs.h
+
+SOCKLIB='-lsocket'
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lws2_32" >&5
+$as_echo_n "checking for socket in -lws2_32... " >&6; }
+if ${ac_cv_lib_ws2_32_socket+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lws2_32 $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char socket ();
+int
+main ()
+{
+return socket ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_ws2_32_socket=yes
+else
+ ac_cv_lib_ws2_32_socket=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ws2_32_socket" >&5
+$as_echo "$ac_cv_lib_ws2_32_socket" >&6; }
+if test "x$ac_cv_lib_ws2_32_socket" = xyes; then :
+
+NET_PROG_RES='$(NET_PROG_RES)'
+NET_PROG_CLI='$(NET_PROG_CLI)'
+$as_echo "#define HAVE_SOCKET 1" >>confdefs.h
+
+SOCKLIB='-lws2_32'
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+done
+
+
+for ac_func in setsockopt
+do :
+ ac_fn_c_check_func "$LINENO" "setsockopt" "ac_cv_func_setsockopt"
+if test "x$ac_cv_func_setsockopt" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SETSOCKOPT 1
+_ACEOF
+
+$as_echo "#define HAVE_SETSOCKOPT 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for setsockopt in -lxnet" >&5
+$as_echo_n "checking for setsockopt in -lxnet... " >&6; }
+if ${ac_cv_lib_xnet_setsockopt+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lxnet $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char setsockopt ();
+int
+main ()
+{
+return setsockopt ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_xnet_setsockopt=yes
+else
+ ac_cv_lib_xnet_setsockopt=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xnet_setsockopt" >&5
+$as_echo "$ac_cv_lib_xnet_setsockopt" >&6; }
+if test "x$ac_cv_lib_xnet_setsockopt" = xyes; then :
+
+$as_echo "#define HAVE_SETSOCKOPT 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for setsockopt in -lsocket" >&5
+$as_echo_n "checking for setsockopt in -lsocket... " >&6; }
+if ${ac_cv_lib_socket_setsockopt+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char setsockopt ();
+int
+main ()
+{
+return setsockopt ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_socket_setsockopt=yes
+else
+ ac_cv_lib_socket_setsockopt=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_setsockopt" >&5
+$as_echo "$ac_cv_lib_socket_setsockopt" >&6; }
+if test "x$ac_cv_lib_socket_setsockopt" = xyes; then :
+
+$as_echo "#define HAVE_SETSOCKOPT 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for setsockopt in -lws2_32" >&5
+$as_echo_n "checking for setsockopt in -lws2_32... " >&6; }
+if ${ac_cv_lib_ws2_32_setsockopt+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lws2_32 $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char setsockopt ();
+int
+main ()
+{
+return setsockopt ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_ws2_32_setsockopt=yes
+else
+ ac_cv_lib_ws2_32_setsockopt=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ws2_32_setsockopt" >&5
+$as_echo "$ac_cv_lib_ws2_32_setsockopt" >&6; }
+if test "x$ac_cv_lib_ws2_32_setsockopt" = xyes; then :
+
+$as_echo "#define HAVE_SETSOCKOPT 1" >>confdefs.h
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+done
+
+
+for ac_func in getaddrinfo
+do :
+ ac_fn_c_check_func "$LINENO" "getaddrinfo" "ac_cv_func_getaddrinfo"
+if test "x$ac_cv_func_getaddrinfo" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_GETADDRINFO 1
+_ACEOF
+
+$as_echo "#define HAVE_GETADDRINFO 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getaddrinfo in -lxnet" >&5
+$as_echo_n "checking for getaddrinfo in -lxnet... " >&6; }
+if ${ac_cv_lib_xnet_getaddrinfo+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lxnet $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getaddrinfo ();
+int
+main ()
+{
+return getaddrinfo ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_xnet_getaddrinfo=yes
+else
+ ac_cv_lib_xnet_getaddrinfo=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xnet_getaddrinfo" >&5
+$as_echo "$ac_cv_lib_xnet_getaddrinfo" >&6; }
+if test "x$ac_cv_lib_xnet_getaddrinfo" = xyes; then :
+
+NSLLIB='-lxnet'
+$as_echo "#define HAVE_GETADDRINFO 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getaddrinfo in -lnsl" >&5
+$as_echo_n "checking for getaddrinfo in -lnsl... " >&6; }
+if ${ac_cv_lib_nsl_getaddrinfo+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getaddrinfo ();
+int
+main ()
+{
+return getaddrinfo ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_nsl_getaddrinfo=yes
+else
+ ac_cv_lib_nsl_getaddrinfo=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_getaddrinfo" >&5
+$as_echo "$ac_cv_lib_nsl_getaddrinfo" >&6; }
+if test "x$ac_cv_lib_nsl_getaddrinfo" = xyes; then :
+
+NSLLIB='-lnsl'
+$as_echo "#define HAVE_GETADDRINFO 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getaddrinfo in -lsocket" >&5
+$as_echo_n "checking for getaddrinfo in -lsocket... " >&6; }
+if ${ac_cv_lib_socket_getaddrinfo+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getaddrinfo ();
+int
+main ()
+{
+return getaddrinfo ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_socket_getaddrinfo=yes
+else
+ ac_cv_lib_socket_getaddrinfo=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_getaddrinfo" >&5
+$as_echo "$ac_cv_lib_socket_getaddrinfo" >&6; }
+if test "x$ac_cv_lib_socket_getaddrinfo" = xyes; then :
+
+NSLLIB='-lsocket'
+$as_echo "#define HAVE_GETADDRINFO 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getaddrinfo in -lws2_32" >&5
+$as_echo_n "checking for getaddrinfo in -lws2_32... " >&6; }
+if ${ac_cv_lib_ws2_32_getaddrinfo+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lws2_32 $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getaddrinfo ();
+int
+main ()
+{
+return getaddrinfo ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_ws2_32_getaddrinfo=yes
+else
+ ac_cv_lib_ws2_32_getaddrinfo=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ws2_32_getaddrinfo" >&5
+$as_echo "$ac_cv_lib_ws2_32_getaddrinfo" >&6; }
+if test "x$ac_cv_lib_ws2_32_getaddrinfo" = xyes; then :
+
+$as_echo "#define HAVE_GETADDRINFO 1" >>confdefs.h
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+done
+
+
+for ac_func in getnameinfo
+do :
+ ac_fn_c_check_func "$LINENO" "getnameinfo" "ac_cv_func_getnameinfo"
+if test "x$ac_cv_func_getnameinfo" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_GETNAMEINFO 1
+_ACEOF
+
+$as_echo "#define HAVE_GETNAMEINFO 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getnameinfo in -lxnet" >&5
+$as_echo_n "checking for getnameinfo in -lxnet... " >&6; }
+if ${ac_cv_lib_xnet_getnameinfo+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lxnet $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getnameinfo ();
+int
+main ()
+{
+return getnameinfo ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_xnet_getnameinfo=yes
+else
+ ac_cv_lib_xnet_getnameinfo=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xnet_getnameinfo" >&5
+$as_echo "$ac_cv_lib_xnet_getnameinfo" >&6; }
+if test "x$ac_cv_lib_xnet_getnameinfo" = xyes; then :
+
+$as_echo "#define HAVE_GETNAMEINFO 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getnameinfo in -lnsl" >&5
+$as_echo_n "checking for getnameinfo in -lnsl... " >&6; }
+if ${ac_cv_lib_nsl_getnameinfo+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getnameinfo ();
+int
+main ()
+{
+return getnameinfo ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_nsl_getnameinfo=yes
+else
+ ac_cv_lib_nsl_getnameinfo=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_getnameinfo" >&5
+$as_echo "$ac_cv_lib_nsl_getnameinfo" >&6; }
+if test "x$ac_cv_lib_nsl_getnameinfo" = xyes; then :
+
+$as_echo "#define HAVE_GETNAMEINFO 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getnameinfo in -lsocket" >&5
+$as_echo_n "checking for getnameinfo in -lsocket... " >&6; }
+if ${ac_cv_lib_socket_getnameinfo+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getnameinfo ();
+int
+main ()
+{
+return getnameinfo ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_socket_getnameinfo=yes
+else
+ ac_cv_lib_socket_getnameinfo=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_getnameinfo" >&5
+$as_echo "$ac_cv_lib_socket_getnameinfo" >&6; }
+if test "x$ac_cv_lib_socket_getnameinfo" = xyes; then :
+
+$as_echo "#define HAVE_GETNAMEINFO 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getnameinfo in -lws2_32" >&5
+$as_echo_n "checking for getnameinfo in -lws2_32... " >&6; }
+if ${ac_cv_lib_ws2_32_getnameinfo+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lws2_32 $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getnameinfo ();
+int
+main ()
+{
+return getnameinfo ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_ws2_32_getnameinfo=yes
+else
+ ac_cv_lib_ws2_32_getnameinfo=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ws2_32_getnameinfo" >&5
+$as_echo "$ac_cv_lib_ws2_32_getnameinfo" >&6; }
+if test "x$ac_cv_lib_ws2_32_getnameinfo" = xyes; then :
+
+$as_echo "#define HAVE_GETNAMEINFO 1" >>confdefs.h
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+done
+
+
+for ac_func in gethostbyname
+do :
+ ac_fn_c_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname"
+if test "x$ac_cv_func_gethostbyname" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_GETHOSTBYNAME 1
+_ACEOF
+
+$as_echo "#define HAVE_GETHOSTBYNAME 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lxnet" >&5
+$as_echo_n "checking for gethostbyname in -lxnet... " >&6; }
+if ${ac_cv_lib_xnet_gethostbyname+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lxnet $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gethostbyname ();
+int
+main ()
+{
+return gethostbyname ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_xnet_gethostbyname=yes
+else
+ ac_cv_lib_xnet_gethostbyname=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xnet_gethostbyname" >&5
+$as_echo "$ac_cv_lib_xnet_gethostbyname" >&6; }
+if test "x$ac_cv_lib_xnet_gethostbyname" = xyes; then :
+
+$as_echo "#define HAVE_GETHOSTBYNAME 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5
+$as_echo_n "checking for gethostbyname in -lnsl... " >&6; }
+if ${ac_cv_lib_nsl_gethostbyname+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gethostbyname ();
+int
+main ()
+{
+return gethostbyname ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_nsl_gethostbyname=yes
+else
+ ac_cv_lib_nsl_gethostbyname=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5
+$as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; }
+if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then :
+
+$as_echo "#define HAVE_GETHOSTBYNAME 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lsocket" >&5
+$as_echo_n "checking for gethostbyname in -lsocket... " >&6; }
+if ${ac_cv_lib_socket_gethostbyname+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gethostbyname ();
+int
+main ()
+{
+return gethostbyname ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_socket_gethostbyname=yes
+else
+ ac_cv_lib_socket_gethostbyname=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_gethostbyname" >&5
+$as_echo "$ac_cv_lib_socket_gethostbyname" >&6; }
+if test "x$ac_cv_lib_socket_gethostbyname" = xyes; then :
+
+$as_echo "#define HAVE_GETHOSTBYNAME 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lws3_32" >&5
+$as_echo_n "checking for gethostbyname in -lws3_32... " >&6; }
+if ${ac_cv_lib_ws3_32_gethostbyname+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lws3_32 $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gethostbyname ();
+int
+main ()
+{
+return gethostbyname ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_ws3_32_gethostbyname=yes
+else
+ ac_cv_lib_ws3_32_gethostbyname=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ws3_32_gethostbyname" >&5
+$as_echo "$ac_cv_lib_ws3_32_gethostbyname" >&6; }
+if test "x$ac_cv_lib_ws3_32_gethostbyname" = xyes; then :
+
+$as_echo "#define HAVE_GETHOSTBYNAME 1" >>confdefs.h
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+done
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking htons" >&5
+$as_echo_n "checking htons... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+int
+main ()
+{
+
+ unsigned short s;
+ s = htons(5);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+$as_echo "#define HAVE_HTONS 1" >>confdefs.h
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking ntohs" >&5
+$as_echo_n "checking ntohs... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+int
+main ()
+{
+
+ unsigned short s;
+ s = ntohs(5);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+$as_echo "#define HAVE_NTOHS 1" >>confdefs.h
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking htonl" >&5
+$as_echo_n "checking htonl... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+int
+main ()
+{
+
+ unsigned long s;
+ s = htonl(5);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+$as_echo "#define HAVE_HTONL 1" >>confdefs.h
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking ntohl" >&5
+$as_echo_n "checking ntohl... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+int
+main ()
+{
+
+ unsigned long s;
+ s = ntohl(5);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+$as_echo "#define HAVE_NTOHL 1" >>confdefs.h
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+for ac_func in inet_addr
+do :
+ ac_fn_c_check_func "$LINENO" "inet_addr" "ac_cv_func_inet_addr"
+if test "x$ac_cv_func_inet_addr" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_INET_ADDR 1
+_ACEOF
+
+$as_echo "#define HAVE_INET_ADDR 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_addr in -lxnet" >&5
+$as_echo_n "checking for inet_addr in -lxnet... " >&6; }
+if ${ac_cv_lib_xnet_inet_addr+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lxnet $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_addr ();
+int
+main ()
+{
+return inet_addr ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_xnet_inet_addr=yes
+else
+ ac_cv_lib_xnet_inet_addr=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xnet_inet_addr" >&5
+$as_echo "$ac_cv_lib_xnet_inet_addr" >&6; }
+if test "x$ac_cv_lib_xnet_inet_addr" = xyes; then :
+
+$as_echo "#define HAVE_INET_ADDR 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_addr in -lnsl" >&5
+$as_echo_n "checking for inet_addr in -lnsl... " >&6; }
+if ${ac_cv_lib_nsl_inet_addr+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_addr ();
+int
+main ()
+{
+return inet_addr ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_nsl_inet_addr=yes
+else
+ ac_cv_lib_nsl_inet_addr=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_inet_addr" >&5
+$as_echo "$ac_cv_lib_nsl_inet_addr" >&6; }
+if test "x$ac_cv_lib_nsl_inet_addr" = xyes; then :
+
+$as_echo "#define HAVE_INET_ADDR 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_addr in -lsocket" >&5
+$as_echo_n "checking for inet_addr in -lsocket... " >&6; }
+if ${ac_cv_lib_socket_inet_addr+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_addr ();
+int
+main ()
+{
+return inet_addr ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_socket_inet_addr=yes
+else
+ ac_cv_lib_socket_inet_addr=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_inet_addr" >&5
+$as_echo "$ac_cv_lib_socket_inet_addr" >&6; }
+if test "x$ac_cv_lib_socket_inet_addr" = xyes; then :
+
+$as_echo "#define HAVE_INET_ADDR 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_addr in -lws2_32" >&5
+$as_echo_n "checking for inet_addr in -lws2_32... " >&6; }
+if ${ac_cv_lib_ws2_32_inet_addr+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lws2_32 $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_addr ();
+int
+main ()
+{
+return inet_addr ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_ws2_32_inet_addr=yes
+else
+ ac_cv_lib_ws2_32_inet_addr=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ws2_32_inet_addr" >&5
+$as_echo "$ac_cv_lib_ws2_32_inet_addr" >&6; }
+if test "x$ac_cv_lib_ws2_32_inet_addr" = xyes; then :
+
+$as_echo "#define HAVE_INET_ADDR 1" >>confdefs.h
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+done
+
+
+for ac_func in inet_aton
+do :
+ ac_fn_c_check_func "$LINENO" "inet_aton" "ac_cv_func_inet_aton"
+if test "x$ac_cv_func_inet_aton" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_INET_ATON 1
+_ACEOF
+
+$as_echo "#define HAVE_INET_ATON 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_aton in -lxnet" >&5
+$as_echo_n "checking for inet_aton in -lxnet... " >&6; }
+if ${ac_cv_lib_xnet_inet_aton+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lxnet $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_aton ();
+int
+main ()
+{
+return inet_aton ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_xnet_inet_aton=yes
+else
+ ac_cv_lib_xnet_inet_aton=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xnet_inet_aton" >&5
+$as_echo "$ac_cv_lib_xnet_inet_aton" >&6; }
+if test "x$ac_cv_lib_xnet_inet_aton" = xyes; then :
+
+$as_echo "#define HAVE_INET_ATON 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_aton in -lnsl" >&5
+$as_echo_n "checking for inet_aton in -lnsl... " >&6; }
+if ${ac_cv_lib_nsl_inet_aton+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_aton ();
+int
+main ()
+{
+return inet_aton ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_nsl_inet_aton=yes
+else
+ ac_cv_lib_nsl_inet_aton=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_inet_aton" >&5
+$as_echo "$ac_cv_lib_nsl_inet_aton" >&6; }
+if test "x$ac_cv_lib_nsl_inet_aton" = xyes; then :
+
+$as_echo "#define HAVE_INET_ATON 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_aton in -lsocket" >&5
+$as_echo_n "checking for inet_aton in -lsocket... " >&6; }
+if ${ac_cv_lib_socket_inet_aton+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_aton ();
+int
+main ()
+{
+return inet_aton ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_socket_inet_aton=yes
+else
+ ac_cv_lib_socket_inet_aton=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_inet_aton" >&5
+$as_echo "$ac_cv_lib_socket_inet_aton" >&6; }
+if test "x$ac_cv_lib_socket_inet_aton" = xyes; then :
+
+$as_echo "#define HAVE_INET_ATON 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_aton in -lws2_32" >&5
+$as_echo_n "checking for inet_aton in -lws2_32... " >&6; }
+if ${ac_cv_lib_ws2_32_inet_aton+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lws2_32 $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_aton ();
+int
+main ()
+{
+return inet_aton ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_ws2_32_inet_aton=yes
+else
+ ac_cv_lib_ws2_32_inet_aton=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ws2_32_inet_aton" >&5
+$as_echo "$ac_cv_lib_ws2_32_inet_aton" >&6; }
+if test "x$ac_cv_lib_ws2_32_inet_aton" = xyes; then :
+
+$as_echo "#define HAVE_INET_ATON 1" >>confdefs.h
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+done
+
+
+for ac_func in inet_pton
+do :
+ ac_fn_c_check_func "$LINENO" "inet_pton" "ac_cv_func_inet_pton"
+if test "x$ac_cv_func_inet_pton" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_INET_PTON 1
+_ACEOF
+
+$as_echo "#define HAVE_INET_PTON 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_pton in -lxnet" >&5
+$as_echo_n "checking for inet_pton in -lxnet... " >&6; }
+if ${ac_cv_lib_xnet_inet_pton+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lxnet $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_pton ();
+int
+main ()
+{
+return inet_pton ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_xnet_inet_pton=yes
+else
+ ac_cv_lib_xnet_inet_pton=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xnet_inet_pton" >&5
+$as_echo "$ac_cv_lib_xnet_inet_pton" >&6; }
+if test "x$ac_cv_lib_xnet_inet_pton" = xyes; then :
+
+$as_echo "#define HAVE_INET_PTON 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_pton in -lnsl" >&5
+$as_echo_n "checking for inet_pton in -lnsl... " >&6; }
+if ${ac_cv_lib_nsl_inet_pton+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_pton ();
+int
+main ()
+{
+return inet_pton ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_nsl_inet_pton=yes
+else
+ ac_cv_lib_nsl_inet_pton=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_inet_pton" >&5
+$as_echo "$ac_cv_lib_nsl_inet_pton" >&6; }
+if test "x$ac_cv_lib_nsl_inet_pton" = xyes; then :
+
+$as_echo "#define HAVE_INET_PTON 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_pton in -lsocket" >&5
+$as_echo_n "checking for inet_pton in -lsocket... " >&6; }
+if ${ac_cv_lib_socket_inet_pton+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_pton ();
+int
+main ()
+{
+return inet_pton ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_socket_inet_pton=yes
+else
+ ac_cv_lib_socket_inet_pton=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_inet_pton" >&5
+$as_echo "$ac_cv_lib_socket_inet_pton" >&6; }
+if test "x$ac_cv_lib_socket_inet_pton" = xyes; then :
+
+$as_echo "#define HAVE_INET_PTON 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_pton in -lws2_32" >&5
+$as_echo_n "checking for inet_pton in -lws2_32... " >&6; }
+if ${ac_cv_lib_ws2_32_inet_pton+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lws2_32 $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_pton ();
+int
+main ()
+{
+return inet_pton ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_ws2_32_inet_pton=yes
+else
+ ac_cv_lib_ws2_32_inet_pton=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ws2_32_inet_pton" >&5
+$as_echo "$ac_cv_lib_ws2_32_inet_pton" >&6; }
+if test "x$ac_cv_lib_ws2_32_inet_pton" = xyes; then :
+
+$as_echo "#define HAVE_INET_PTON 1" >>confdefs.h
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+done
+
+
+for ac_func in inet_ntop
+do :
+ ac_fn_c_check_func "$LINENO" "inet_ntop" "ac_cv_func_inet_ntop"
+if test "x$ac_cv_func_inet_ntop" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_INET_NTOP 1
+_ACEOF
+
+$as_echo "#define HAVE_INET_NTOP 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_ntop in -lxnet" >&5
+$as_echo_n "checking for inet_ntop in -lxnet... " >&6; }
+if ${ac_cv_lib_xnet_inet_ntop+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lxnet $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_ntop ();
+int
+main ()
+{
+return inet_ntop ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_xnet_inet_ntop=yes
+else
+ ac_cv_lib_xnet_inet_ntop=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xnet_inet_ntop" >&5
+$as_echo "$ac_cv_lib_xnet_inet_ntop" >&6; }
+if test "x$ac_cv_lib_xnet_inet_ntop" = xyes; then :
+
+$as_echo "#define HAVE_INET_NTOP 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_ntop in -lnsl" >&5
+$as_echo_n "checking for inet_ntop in -lnsl... " >&6; }
+if ${ac_cv_lib_nsl_inet_ntop+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_ntop ();
+int
+main ()
+{
+return inet_ntop ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_nsl_inet_ntop=yes
+else
+ ac_cv_lib_nsl_inet_ntop=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_inet_ntop" >&5
+$as_echo "$ac_cv_lib_nsl_inet_ntop" >&6; }
+if test "x$ac_cv_lib_nsl_inet_ntop" = xyes; then :
+
+$as_echo "#define HAVE_INET_NTOP 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_ntop in -lsocket" >&5
+$as_echo_n "checking for inet_ntop in -lsocket... " >&6; }
+if ${ac_cv_lib_socket_inet_ntop+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_ntop ();
+int
+main ()
+{
+return inet_ntop ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_socket_inet_ntop=yes
+else
+ ac_cv_lib_socket_inet_ntop=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_inet_ntop" >&5
+$as_echo "$ac_cv_lib_socket_inet_ntop" >&6; }
+if test "x$ac_cv_lib_socket_inet_ntop" = xyes; then :
+
+$as_echo "#define HAVE_INET_NTOP 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_ntop in -lws2_32" >&5
+$as_echo_n "checking for inet_ntop in -lws2_32... " >&6; }
+if ${ac_cv_lib_ws2_32_inet_ntop+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lws2_32 $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_ntop ();
+int
+main ()
+{
+return inet_ntop ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_ws2_32_inet_ntop=yes
+else
+ ac_cv_lib_ws2_32_inet_ntop=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ws2_32_inet_ntop" >&5
+$as_echo "$ac_cv_lib_ws2_32_inet_ntop" >&6; }
+if test "x$ac_cv_lib_ws2_32_inet_ntop" = xyes; then :
+
+$as_echo "#define HAVE_INET_NTOP 1" >>confdefs.h
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+done
+
+
+if [ "X$SOCKLIB" = "X$NSLLIB" ]
+then
+NSLLIB=''
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking /proc/.../exe symbolic link" >&5
+$as_echo_n "checking /proc/.../exe symbolic link... " >&6; }
+if test "$cross_compiling" = yes; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no - test not possible" >&5
+$as_echo "no - test not possible" >&6; }
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+
+/* Buffer for result */
+char prog[1024];
+
+#ifdef __cplusplus
+int main(int argc, char *argv[])
+#else
+int main(argc, argv) int argc; char *argv[];
+#endif
+{
+ char buf[64];
+ struct stat stbuf;
+ int exv = 1;
+ ssize_t res;
+#if HAVE_STDINT_H
+ sprintf(buf, "/proc/%ju/exe", (uintmax_t)getpid());
+#else
+ sprintf(buf, "/proc/%lu/exe", (unsigned long)getpid());
+#endif
+ res = readlink(buf, prog, sizeof(prog));
+ if ((0 < res) && (sizeof(prog) > res)) {
+ prog[res] = '\0';
+ if (0 == stat(prog, &stbuf)) {
+ exv = 0;
+ }
+ }
+ return exv;
+}
+
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "#define HAVE_PROC_PID_EXE 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking ssize_t" >&5
+$as_echo_n "checking ssize_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+int
+main ()
+{
+
+ ssize_t sz;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "#define HAVE_SSIZE_T 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking int8_t" >&5
+$as_echo_n "checking int8_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+int
+main ()
+{
+
+int8_t i8 = 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "#define HAVE_INT8_T 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking int16_t" >&5
+$as_echo_n "checking int16_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+int
+main ()
+{
+
+int16_t i16 = 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "#define HAVE_INT16_T 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking int32_t" >&5
+$as_echo_n "checking int32_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+int
+main ()
+{
+
+int32_t i32 = 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "#define HAVE_INT32_T 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking uint8_t" >&5
+$as_echo_n "checking uint8_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+int
+main ()
+{
+
+ uint8_t sz;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "#define HAVE_UINT8_T 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking uint16_t" >&5
+$as_echo_n "checking uint16_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+int
+main ()
+{
+
+ uint16_t sz;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "#define HAVE_UINT16_T 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking uint32_t" >&5
+$as_echo_n "checking uint32_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+int
+main ()
+{
+
+ uint32_t sz;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "#define HAVE_UINT32_T 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dev_t" >&5
+$as_echo_n "checking dev_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+ dev_t devno;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "#define HAVE_DEV_T 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking _dev_t" >&5
+$as_echo_n "checking _dev_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+ _dev_t devno;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "#define HAVE__DEV_T 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking ino_t" >&5
+$as_echo_n "checking ino_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+ ino_t devno;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "#define HAVE_INO_T 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking _ino_t" >&5
+$as_echo_n "checking _ino_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+ _ino_t devno;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "#define HAVE__INO_T 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking ino64_t" >&5
+$as_echo_n "checking ino64_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#define _LARGEFILE64_SOURCE 1
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+ ino64_t devno;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "#define HAVE_INO64_T 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking mode_t" >&5
+$as_echo_n "checking mode_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+ mode_t devno;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "#define HAVE_MODE_T 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking nlink_t" >&5
+$as_echo_n "checking nlink_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+ nlink_t devno;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "#define HAVE_NLINK_T 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking uid_t" >&5
+$as_echo_n "checking uid_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+ uid_t devno;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "#define HAVE_UID_T 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking gid_t" >&5
+$as_echo_n "checking gid_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+ gid_t devno;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "#define HAVE_GID_T 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking off_t" >&5
+$as_echo_n "checking off_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+ off_t devno;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "#define HAVE_OFF_T 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking off64_t" >&5
+$as_echo_n "checking off64_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#define _LARGEFILE64_SOURCE 1
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+ off64_t devno;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "#define HAVE_OFF64_T 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking blksize_t" >&5
+$as_echo_n "checking blksize_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+ blksize_t devno;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "#define HAVE_BLKSIZE_T 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking blkcnt_t" >&5
+$as_echo_n "checking blkcnt_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+ blkcnt_t devno;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "#define HAVE_BLKCNT_T 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking fpos_t" >&5
+$as_echo_n "checking fpos_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+ fpos_t devno;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "#define HAVE_FPOS_T 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking blocksize and blockcount in stat output" >&5
+$as_echo_n "checking blocksize and blockcount in stat output... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#define _LARGEFILE64_SOURCE 1
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+#if HAVE_TYPE_STAT64
+ struct stat64 stb;
+ stb.st_blksize = 0;
+ stb.st_blocks = 0;
+#else
+ struct stat stb;
+ stb.st_blksize = 0;
+ stb.st_blocks = 0;
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "#define HAVE_FILE_BLKSIZECNT 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking _fpos_t" >&5
+$as_echo_n "checking _fpos_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+ _fpos_t devno;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "#define HAVE__FPOS_T 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking socklen_t" >&5
+$as_echo_n "checking socklen_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+socklen_t sz;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "#define HAVE_SOCKLEN_T 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking struct sockaddr_in" >&5
+$as_echo_n "checking struct sockaddr_in... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+struct sockaddr_in sain;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "#define HAVE_STRUCT_SOCKADDR_IN 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking struct sockaddr_in6" >&5
+$as_echo_n "checking struct sockaddr_in6... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+struct sockaddr_in6 sain;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "#define HAVE_STRUCT_SOCKADDR_IN6 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking struct sockaddr_un" >&5
+$as_echo_n "checking struct sockaddr_un... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_SYS_UN_H
+#include <sys/un.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+struct sockaddr_un sain;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "#define HAVE_STRUCT_SOCKADDR_UN 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking struct addrinfo" >&5
+$as_echo_n "checking struct addrinfo... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+struct addrinfo adi;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "#define HAVE_STRUCT_ADDRINFO 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking struct sockaddr_storage" >&5
+$as_echo_n "checking struct sockaddr_storage... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+struct sockaddr_storage sain;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "#define HAVE_STRUCT_SOCKADDR_STORAGE 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking IN_ADDR" >&5
+$as_echo_n "checking IN_ADDR... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
+#if HAVE_WS2TCPIP_H
+#include <ws2tcpip.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+int
+main ()
+{
+
+IN_ADDR addr;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "#define HAVE_IN_ADDR 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking IN6_ADDR" >&5
+$as_echo_n "checking IN6_ADDR... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
+#if HAVE_WS2TCPIP_H
+#include <ws2tcpip.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+int
+main ()
+{
+
+IN6_ADDR addr;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "#define HAVE_IN6_ADDR 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking rand srand" >&5
+$as_echo_n "checking rand srand... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+main ()
+{
+
+ srand(25);
+ printf("%d\n", rand());
+ printf("%d\n", RAND_MAX);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "#define HAVE_RAND 1" >>confdefs.h
+
+$as_echo "#define HAVE_SRAND 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking initstate setstate random" >&5
+$as_echo_n "checking initstate setstate random... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+main ()
+{
+
+char rs[256];
+initstate(25, rs, sizeof(rs));
+setstate(rs);
+printf("%ld\n", random());
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "#define HAVE_INITSTATE 1" >>confdefs.h
+
+$as_echo "#define HAVE_SETSTATE 1" >>confdefs.h
+
+$as_echo "#define HAVE_RANDOM 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking lrand48 nrand48 seed48" >&5
+$as_echo_n "checking lrand48 nrand48 seed48... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+main ()
+{
+
+unsigned short sv[3];
+sv[0] = 0;
+sv[1] = 1;
+sv[2] = 2;
+seed48(sv);
+printf("%ld\n", lrand48());
+printf("%ld\n", nrand48(sv));
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+$as_echo "#define HAVE_LRAND48 1" >>confdefs.h
+
+$as_echo "#define HAVE_NRAND48 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of off_t" >&5
+$as_echo_n "checking size of off_t... " >&6; }
+if ${ac_cv_sizeof_off_t+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (off_t))" "ac_cv_sizeof_off_t" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_off_t" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (off_t)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_off_t=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_off_t" >&5
+$as_echo "$ac_cv_sizeof_off_t" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_OFF_T $ac_cv_sizeof_off_t
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of off64_t" >&5
+$as_echo_n "checking size of off64_t... " >&6; }
+if ${ac_cv_sizeof_off64_t+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (off64_t))" "ac_cv_sizeof_off64_t" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_off64_t" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (off64_t)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_off64_t=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_off64_t" >&5
+$as_echo "$ac_cv_sizeof_off64_t" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_OFF64_T $ac_cv_sizeof_off64_t
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of ino_t" >&5
+$as_echo_n "checking size of ino_t... " >&6; }
+if ${ac_cv_sizeof_ino_t+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (ino_t))" "ac_cv_sizeof_ino_t" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_ino_t" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (ino_t)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_ino_t=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_ino_t" >&5
+$as_echo "$ac_cv_sizeof_ino_t" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_INO_T $ac_cv_sizeof_ino_t
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of ino64_t" >&5
+$as_echo_n "checking size of ino64_t... " >&6; }
+if ${ac_cv_sizeof_ino64_t+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (ino64_t))" "ac_cv_sizeof_ino64_t" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_ino64_t" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (ino64_t)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_ino64_t=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_ino64_t" >&5
+$as_echo "$ac_cv_sizeof_ino64_t" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_INO64_T $ac_cv_sizeof_ino64_t
+_ACEOF
+
+
+
+
+# Check whether --with-fallback-limits was given.
+if test "${with_fallback_limits+set}" = set; then :
+ withval=$with_fallback_limits; $as_echo "#define USE_FALLBACK_NUMERIC_LIMITS 1" >>confdefs.h
+
+fi
+
+
+
+# Check whether --with-printf-scanf was given.
+if test "${with_printf_scanf+set}" = set; then :
+ withval=$with_printf_scanf; CAN_USE_PRINTF_SCANF="$withval"
+fi
+
+
+if [ "X$CAN_USE_PRINTF_SCANF" != "Xno" ]
+then
+ $as_echo "#define USE_PRINTF_SCANF 1" >>confdefs.h
+
+fi
+
+$as_echo "#define HAVE_FILE_DEVINO 1" >>confdefs.h
+
+$as_echo "#define HAVE_FILE_UIDGID 1" >>confdefs.h
+
+$as_echo "#define HAVE_FILE_ATIMECTIME 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_COMPATDKTOOLS3 1" >>confdefs.h
+
+
+SEP=`cat sep.txt`
+for i in test*.ctr
+do
+j=`echo $i | sed -e 's/\.ctr//g'`
+if [ "X$TESTPROGRAMS" = "X" ]
+then
+ TESTPROGRAMS="$j"
+else
+ TESTPROGRAMS="${TESTPROGRAMS} ${SEP}$j"
+fi
+done
+
+if [ "X$SUITE" = "Xgui" ]
+then
+ $as_echo "#define HAVE_WXWIDGETS 1" >>confdefs.h
+
+else
+ WXCPPFLAGS=''
+ WXCXXFLAGS=''
+ WXCFLAGS=''
+ WXLDFLAGS=''
+fi
+
+WXMAJOR=''
+WXMINOR=''
+
+if [ "X$WXVERSION" != "X" ]
+then
+ WXMAJOR=`echo $WXVERSION | cut -f 1 -d .`
+ WXMINOR=`echo $WXVERSION | cut -f 2 -d .`
+fi
+[ "X$WXMAJOR" != "X" ] || WXMAJOR="0"
+
+if [ "$WXMAJOR" -ge 3 ]
+then
+$as_echo "#define HAVE_WX_CHARTYPE_H 1" >>confdefs.h
+
+elif [ "$WXMAJOR" -ge 2 ]
+then
+$as_echo "#define HAVE_WX_WXCHAR_H 1" >>confdefs.h
+
+fi
+
+LIBPNG=''
+LIBJPEG=''
+LIBTIFF=''
+ANYDB=''
+SNMPPROG=''
+MYSQLPROG=''
+PTHREADLIB=''
+LIBDK3WXOBJ=''
+LIBDK4WXOBJ=''
+LIBDK4WXTOBUILD=''
+DBLIB=''
+DBLIBSOCK=''
+NETSNMP_LIBS=''
+NETSNMP_CFLAGS=''
+NETSNMP_LIBS=`net-snmp-config --libs`
+NETSNMP_CFLAGS=`net-snmp-config --cflags`
+ac_fn_c_check_header_mongrel "$LINENO" "stdio.h" "ac_cv_header_stdio_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdio_h" = xyes; then :
+ $as_echo "#define HAVE_STDIO_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "conio.h" "ac_cv_header_conio_h" "$ac_includes_default"
+if test "x$ac_cv_header_conio_h" = xyes; then :
+ $as_echo "#define HAVE_CONIO_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "grp.h" "ac_cv_header_grp_h" "$ac_includes_default"
+if test "x$ac_cv_header_grp_h" = xyes; then :
+ $as_echo "#define HAVE_GRP_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "gdbm.h" "ac_cv_header_gdbm_h" "$ac_includes_default"
+if test "x$ac_cv_header_gdbm_h" = xyes; then :
+ FOUND_GDBM='yes'
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "ndbm.h" "ac_cv_header_ndbm_h" "$ac_includes_default"
+if test "x$ac_cv_header_ndbm_h" = xyes; then :
+ FOUND_NDBM='yes'
+fi
+
+
+case "X${FOUND_NDBM}${USE_NDBM}${FOUND_GDBM}" in
+ "Xyesyesyes")
+ $as_echo "#define HAVE_NDBM_H 1" >>confdefs.h
+
+ ANYDB='ndbm'
+ ;;
+ "Xyesyesno")
+ $as_echo "#define HAVE_NDBM_H 1" >>confdefs.h
+
+ ANYDB='ndbm'
+ ;;
+ "Xyesautono")
+ $as_echo "#define HAVE_NDBM_H 1" >>confdefs.h
+
+ ANYDB='ndbm'
+ ;;
+esac
+if [ "X$ANYDB" != "Xndbm" -a "X$FOUND_GDBM" = "Xyes" ]
+then
+ $as_echo "#define HAVE_GDBM_H 1" >>confdefs.h
+
+fi
+ac_fn_c_check_header_mongrel "$LINENO" "db.h" "ac_cv_header_db_h" "$ac_includes_default"
+if test "x$ac_cv_header_db_h" = xyes; then :
+ FOUND_BDB='yes';ANYDB='db';DBLIB="-ldb";$as_echo "#define HAVE_DB_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "dir.h" "ac_cv_header_dir_h" "$ac_includes_default"
+if test "x$ac_cv_header_dir_h" = xyes; then :
+ $as_echo "#define HAVE_DIR_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "err.h" "ac_cv_header_err_h" "$ac_includes_default"
+if test "x$ac_cv_header_err_h" = xyes; then :
+ $as_echo "#define HAVE_ERR_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "shadow.h" "ac_cv_header_shadow_h" "$ac_includes_default"
+if test "x$ac_cv_header_shadow_h" = xyes; then :
+ $as_echo "#define HAVE_SHADOW_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "stropts.h" "ac_cv_header_stropts_h" "$ac_includes_default"
+if test "x$ac_cv_header_stropts_h" = xyes; then :
+ $as_echo "#define HAVE_STROPTS_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "syslog.h" "ac_cv_header_syslog_h" "$ac_includes_default"
+if test "x$ac_cv_header_syslog_h" = xyes; then :
+ $as_echo "#define HAVE_SYSLOG_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sysres.h" "ac_cv_header_sysres_h" "$ac_includes_default"
+if test "x$ac_cv_header_sysres_h" = xyes; then :
+ $as_echo "#define HAVE_SYSRES_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "termios.h" "ac_cv_header_termios_h" "$ac_includes_default"
+if test "x$ac_cv_header_termios_h" = xyes; then :
+ $as_echo "#define HAVE_TERMIOS_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "vararg.h" "ac_cv_header_vararg_h" "$ac_includes_default"
+if test "x$ac_cv_header_vararg_h" = xyes; then :
+ $as_echo "#define HAVE_VARARG_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "varargs.h" "ac_cv_header_varargs_h" "$ac_includes_default"
+if test "x$ac_cv_header_varargs_h" = xyes; then :
+ $as_echo "#define HAVE_VARARGS_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "ntifs.h" "ac_cv_header_ntifs_h" "$ac_includes_default"
+if test "x$ac_cv_header_ntifs_h" = xyes; then :
+ $as_echo "#define HAVE_NTIFS_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/file.h" "ac_cv_header_sys_file_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_file_h" = xyes; then :
+ $as_echo "#define HAVE_SYS_FILE_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/resource.h" "ac_cv_header_sys_resource_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_resource_h" = xyes; then :
+ $as_echo "#define HAVE_SYS_RESOURCE_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/statvfs.h" "ac_cv_header_sys_statvfs_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_statvfs_h" = xyes; then :
+ $as_echo "#define HAVE_SYS_STATVFS_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/stropts.h" "ac_cv_header_sys_stropts_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_stropts_h" = xyes; then :
+ $as_echo "#define HAVE_SYS_STROPTS_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/sunddi.h" "ac_cv_header_sys_sunddi_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_sunddi_h" = xyes; then :
+ $as_echo "#define HAVE_SYS_SUNDDI_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/sysctl.h" "ac_cv_header_sys_sysctl_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_sysctl_h" = xyes; then :
+ $as_echo "#define HAVE_SYS_SYSCTL_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/systeminfo.h" "ac_cv_header_sys_systeminfo_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_systeminfo_h" = xyes; then :
+ $as_echo "#define HAVE_SYS_SYSTEMINFO_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/termios.h" "ac_cv_header_sys_termios_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_termios_h" = xyes; then :
+ $as_echo "#define HAVE_SYS_TERMIOS_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/ttold.h" "ac_cv_header_sys_ttold_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_ttold_h" = xyes; then :
+ $as_echo "#define HAVE_SYS_TTOLD_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/uio.h" "ac_cv_header_sys_uio_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_uio_h" = xyes; then :
+ $as_echo "#define HAVE_SYS_UIO_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/wait.h" "ac_cv_header_sys_wait_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_wait_h" = xyes; then :
+ $as_echo "#define HAVE_SYS_WAIT_H 1" >>confdefs.h
+
+fi
+
+
+
+ac_fn_c_check_header_compile "$LINENO" "winbase.h" "ac_cv_header_winbase_h" "
+#if HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+
+"
+if test "x$ac_cv_header_winbase_h" = xyes; then :
+ $as_echo "#define HAVE_WINBASE_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_compile "$LINENO" "winreg.h" "ac_cv_header_winreg_h" "
+#if HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+#if HAVE_WINBASE_H
+#include <winbase.h>
+#endif
+
+"
+if test "x$ac_cv_header_winreg_h" = xyes; then :
+ $as_echo "#define HAVE_WINREG_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_compile "$LINENO" "wincon.h" "ac_cv_header_wincon_h" "
+#if HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+#if HAVE_WINBASE_H
+#include <winbase.h>
+#endif
+
+"
+if test "x$ac_cv_header_wincon_h" = xyes; then :
+ $as_echo "#define HAVE_WINCON_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "png.h" "ac_cv_header_png_h" "$ac_includes_default"
+if test "x$ac_cv_header_png_h" = xyes; then :
+ LIBPNG="-lpng";$as_echo "#define HAVE_PNG_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "jpeglib.h" "ac_cv_header_jpeglib_h" "$ac_includes_default"
+if test "x$ac_cv_header_jpeglib_h" = xyes; then :
+ LIBJPEG="-ljpeg";$as_echo "#define HAVE_JPEGLIB_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "tiff.h" "ac_cv_header_tiff_h" "$ac_includes_default"
+if test "x$ac_cv_header_tiff_h" = xyes; then :
+ LIBTIFF="-ltiff";$as_echo "#define HAVE_TIFF_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "mysql/mysql.h" "ac_cv_header_mysql_mysql_h" "$ac_includes_default"
+if test "x$ac_cv_header_mysql_mysql_h" = xyes; then :
+
+MYSQLPROG='mysqlprog'
+MYSQLLIB='-lmysqlclient'
+$as_echo "#define HAVE_MYSQL_MYSQL_H 1" >>confdefs.h
+
+
+else
+
+ac_fn_c_check_header_mongrel "$LINENO" "mysql.h" "ac_cv_header_mysql_h" "$ac_includes_default"
+if test "x$ac_cv_header_mysql_h" = xyes; then :
+
+MYSQLPROG='mysqlprog'
+MYSQLLIB='-lmysqlclient'
+$as_echo "#define HAVE_MYSQL_H 1" >>confdefs.h
+
+
+
+fi
+
+
+
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "lprng.h" "ac_cv_header_lprng_h" "$ac_includes_default"
+if test "x$ac_cv_header_lprng_h" = xyes; then :
+ $as_echo "#define HAVE_LPRNG_H 1" >>confdefs.h
+
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "pthread.h" "ac_cv_header_pthread_h" "$ac_includes_default"
+if test "x$ac_cv_header_pthread_h" = xyes; then :
+ PTHREADLIB='-lpthread';$as_echo "#define HAVE_PTHREAD_H 1" >>confdefs.h
+
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for acosh in -lm" >&5
+$as_echo_n "checking for acosh in -lm... " >&6; }
+if ${ac_cv_lib_m_acosh+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char acosh ();
+int
+main ()
+{
+return acosh ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_acosh=yes
+else
+ ac_cv_lib_m_acosh=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_acosh" >&5
+$as_echo "$ac_cv_lib_m_acosh" >&6; }
+if test "x$ac_cv_lib_m_acosh" = xyes; then :
+ $as_echo "#define HAVE_ACOSH 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for acoshl in -lm" >&5
+$as_echo_n "checking for acoshl in -lm... " >&6; }
+if ${ac_cv_lib_m_acoshl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char acoshl ();
+int
+main ()
+{
+return acoshl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_acoshl=yes
+else
+ ac_cv_lib_m_acoshl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_acoshl" >&5
+$as_echo "$ac_cv_lib_m_acoshl" >&6; }
+if test "x$ac_cv_lib_m_acoshl" = xyes; then :
+ $as_echo "#define HAVE_ACOSHL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for acosl in -lm" >&5
+$as_echo_n "checking for acosl in -lm... " >&6; }
+if ${ac_cv_lib_m_acosl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char acosl ();
+int
+main ()
+{
+return acosl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_acosl=yes
+else
+ ac_cv_lib_m_acosl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_acosl" >&5
+$as_echo "$ac_cv_lib_m_acosl" >&6; }
+if test "x$ac_cv_lib_m_acosl" = xyes; then :
+ $as_echo "#define HAVE_ACOSL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for asinh in -lm" >&5
+$as_echo_n "checking for asinh in -lm... " >&6; }
+if ${ac_cv_lib_m_asinh+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char asinh ();
+int
+main ()
+{
+return asinh ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_asinh=yes
+else
+ ac_cv_lib_m_asinh=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_asinh" >&5
+$as_echo "$ac_cv_lib_m_asinh" >&6; }
+if test "x$ac_cv_lib_m_asinh" = xyes; then :
+ $as_echo "#define HAVE_ASINH 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for asinhl in -lm" >&5
+$as_echo_n "checking for asinhl in -lm... " >&6; }
+if ${ac_cv_lib_m_asinhl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char asinhl ();
+int
+main ()
+{
+return asinhl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_asinhl=yes
+else
+ ac_cv_lib_m_asinhl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_asinhl" >&5
+$as_echo "$ac_cv_lib_m_asinhl" >&6; }
+if test "x$ac_cv_lib_m_asinhl" = xyes; then :
+ $as_echo "#define HAVE_ASINHL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for asinl in -lm" >&5
+$as_echo_n "checking for asinl in -lm... " >&6; }
+if ${ac_cv_lib_m_asinl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char asinl ();
+int
+main ()
+{
+return asinl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_asinl=yes
+else
+ ac_cv_lib_m_asinl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_asinl" >&5
+$as_echo "$ac_cv_lib_m_asinl" >&6; }
+if test "x$ac_cv_lib_m_asinl" = xyes; then :
+ $as_echo "#define HAVE_ASINL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for atan2 in -lm" >&5
+$as_echo_n "checking for atan2 in -lm... " >&6; }
+if ${ac_cv_lib_m_atan2+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char atan2 ();
+int
+main ()
+{
+return atan2 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_atan2=yes
+else
+ ac_cv_lib_m_atan2=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_atan2" >&5
+$as_echo "$ac_cv_lib_m_atan2" >&6; }
+if test "x$ac_cv_lib_m_atan2" = xyes; then :
+ $as_echo "#define HAVE_ATAN2 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for atan2l in -lm" >&5
+$as_echo_n "checking for atan2l in -lm... " >&6; }
+if ${ac_cv_lib_m_atan2l+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char atan2l ();
+int
+main ()
+{
+return atan2l ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_atan2l=yes
+else
+ ac_cv_lib_m_atan2l=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_atan2l" >&5
+$as_echo "$ac_cv_lib_m_atan2l" >&6; }
+if test "x$ac_cv_lib_m_atan2l" = xyes; then :
+ $as_echo "#define HAVE_ATAN2L 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for atanh in -lm" >&5
+$as_echo_n "checking for atanh in -lm... " >&6; }
+if ${ac_cv_lib_m_atanh+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char atanh ();
+int
+main ()
+{
+return atanh ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_atanh=yes
+else
+ ac_cv_lib_m_atanh=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_atanh" >&5
+$as_echo "$ac_cv_lib_m_atanh" >&6; }
+if test "x$ac_cv_lib_m_atanh" = xyes; then :
+ $as_echo "#define HAVE_ATANH 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for atanhl in -lm" >&5
+$as_echo_n "checking for atanhl in -lm... " >&6; }
+if ${ac_cv_lib_m_atanhl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char atanhl ();
+int
+main ()
+{
+return atanhl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_atanhl=yes
+else
+ ac_cv_lib_m_atanhl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_atanhl" >&5
+$as_echo "$ac_cv_lib_m_atanhl" >&6; }
+if test "x$ac_cv_lib_m_atanhl" = xyes; then :
+ $as_echo "#define HAVE_ATANHL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for atanl in -lm" >&5
+$as_echo_n "checking for atanl in -lm... " >&6; }
+if ${ac_cv_lib_m_atanl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char atanl ();
+int
+main ()
+{
+return atanl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_atanl=yes
+else
+ ac_cv_lib_m_atanl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_atanl" >&5
+$as_echo "$ac_cv_lib_m_atanl" >&6; }
+if test "x$ac_cv_lib_m_atanl" = xyes; then :
+ $as_echo "#define HAVE_ATANL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ceil in -lm" >&5
+$as_echo_n "checking for ceil in -lm... " >&6; }
+if ${ac_cv_lib_m_ceil+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char ceil ();
+int
+main ()
+{
+return ceil ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_ceil=yes
+else
+ ac_cv_lib_m_ceil=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_ceil" >&5
+$as_echo "$ac_cv_lib_m_ceil" >&6; }
+if test "x$ac_cv_lib_m_ceil" = xyes; then :
+ $as_echo "#define HAVE_CEIL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ceill in -lm" >&5
+$as_echo_n "checking for ceill in -lm... " >&6; }
+if ${ac_cv_lib_m_ceill+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char ceill ();
+int
+main ()
+{
+return ceill ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_ceill=yes
+else
+ ac_cv_lib_m_ceill=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_ceill" >&5
+$as_echo "$ac_cv_lib_m_ceill" >&6; }
+if test "x$ac_cv_lib_m_ceill" = xyes; then :
+ $as_echo "#define HAVE_CEILL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for coshl in -lm" >&5
+$as_echo_n "checking for coshl in -lm... " >&6; }
+if ${ac_cv_lib_m_coshl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char coshl ();
+int
+main ()
+{
+return coshl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_coshl=yes
+else
+ ac_cv_lib_m_coshl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_coshl" >&5
+$as_echo "$ac_cv_lib_m_coshl" >&6; }
+if test "x$ac_cv_lib_m_coshl" = xyes; then :
+ $as_echo "#define HAVE_COSHL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for cosl in -lm" >&5
+$as_echo_n "checking for cosl in -lm... " >&6; }
+if ${ac_cv_lib_m_cosl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char cosl ();
+int
+main ()
+{
+return cosl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_cosl=yes
+else
+ ac_cv_lib_m_cosl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_cosl" >&5
+$as_echo "$ac_cv_lib_m_cosl" >&6; }
+if test "x$ac_cv_lib_m_cosl" = xyes; then :
+ $as_echo "#define HAVE_COSL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for expl in -lm" >&5
+$as_echo_n "checking for expl in -lm... " >&6; }
+if ${ac_cv_lib_m_expl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char expl ();
+int
+main ()
+{
+return expl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_expl=yes
+else
+ ac_cv_lib_m_expl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_expl" >&5
+$as_echo "$ac_cv_lib_m_expl" >&6; }
+if test "x$ac_cv_lib_m_expl" = xyes; then :
+ $as_echo "#define HAVE_EXPL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fabs in -lm" >&5
+$as_echo_n "checking for fabs in -lm... " >&6; }
+if ${ac_cv_lib_m_fabs+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char fabs ();
+int
+main ()
+{
+return fabs ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_fabs=yes
+else
+ ac_cv_lib_m_fabs=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_fabs" >&5
+$as_echo "$ac_cv_lib_m_fabs" >&6; }
+if test "x$ac_cv_lib_m_fabs" = xyes; then :
+ $as_echo "#define HAVE_FABS 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fabsl in -lm" >&5
+$as_echo_n "checking for fabsl in -lm... " >&6; }
+if ${ac_cv_lib_m_fabsl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char fabsl ();
+int
+main ()
+{
+return fabsl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_fabsl=yes
+else
+ ac_cv_lib_m_fabsl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_fabsl" >&5
+$as_echo "$ac_cv_lib_m_fabsl" >&6; }
+if test "x$ac_cv_lib_m_fabsl" = xyes; then :
+ $as_echo "#define HAVE_FABSL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for floor in -lm" >&5
+$as_echo_n "checking for floor in -lm... " >&6; }
+if ${ac_cv_lib_m_floor+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char floor ();
+int
+main ()
+{
+return floor ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_floor=yes
+else
+ ac_cv_lib_m_floor=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_floor" >&5
+$as_echo "$ac_cv_lib_m_floor" >&6; }
+if test "x$ac_cv_lib_m_floor" = xyes; then :
+ $as_echo "#define HAVE_FLOOR 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for floorl in -lm" >&5
+$as_echo_n "checking for floorl in -lm... " >&6; }
+if ${ac_cv_lib_m_floorl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char floorl ();
+int
+main ()
+{
+return floorl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_floorl=yes
+else
+ ac_cv_lib_m_floorl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_floorl" >&5
+$as_echo "$ac_cv_lib_m_floorl" >&6; }
+if test "x$ac_cv_lib_m_floorl" = xyes; then :
+ $as_echo "#define HAVE_FLOORL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for labs in -lm" >&5
+$as_echo_n "checking for labs in -lm... " >&6; }
+if ${ac_cv_lib_m_labs+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char labs ();
+int
+main ()
+{
+return labs ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_labs=yes
+else
+ ac_cv_lib_m_labs=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_labs" >&5
+$as_echo "$ac_cv_lib_m_labs" >&6; }
+if test "x$ac_cv_lib_m_labs" = xyes; then :
+ $as_echo "#define HAVE_LABS 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for logl in -lm" >&5
+$as_echo_n "checking for logl in -lm... " >&6; }
+if ${ac_cv_lib_m_logl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char logl ();
+int
+main ()
+{
+return logl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_logl=yes
+else
+ ac_cv_lib_m_logl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_logl" >&5
+$as_echo "$ac_cv_lib_m_logl" >&6; }
+if test "x$ac_cv_lib_m_logl" = xyes; then :
+ $as_echo "#define HAVE_LOGL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for rint in -lm" >&5
+$as_echo_n "checking for rint in -lm... " >&6; }
+if ${ac_cv_lib_m_rint+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char rint ();
+int
+main ()
+{
+return rint ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_rint=yes
+else
+ ac_cv_lib_m_rint=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_rint" >&5
+$as_echo "$ac_cv_lib_m_rint" >&6; }
+if test "x$ac_cv_lib_m_rint" = xyes; then :
+ $as_echo "#define HAVE_RINT 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for rintl in -lm" >&5
+$as_echo_n "checking for rintl in -lm... " >&6; }
+if ${ac_cv_lib_m_rintl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char rintl ();
+int
+main ()
+{
+return rintl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_rintl=yes
+else
+ ac_cv_lib_m_rintl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_rintl" >&5
+$as_echo "$ac_cv_lib_m_rintl" >&6; }
+if test "x$ac_cv_lib_m_rintl" = xyes; then :
+ $as_echo "#define HAVE_RINTL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sinhl in -lm" >&5
+$as_echo_n "checking for sinhl in -lm... " >&6; }
+if ${ac_cv_lib_m_sinhl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char sinhl ();
+int
+main ()
+{
+return sinhl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_sinhl=yes
+else
+ ac_cv_lib_m_sinhl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_sinhl" >&5
+$as_echo "$ac_cv_lib_m_sinhl" >&6; }
+if test "x$ac_cv_lib_m_sinhl" = xyes; then :
+ $as_echo "#define HAVE_SINHL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqrt in -lm" >&5
+$as_echo_n "checking for sqrt in -lm... " >&6; }
+if ${ac_cv_lib_m_sqrt+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char sqrt ();
+int
+main ()
+{
+return sqrt ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_sqrt=yes
+else
+ ac_cv_lib_m_sqrt=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_sqrt" >&5
+$as_echo "$ac_cv_lib_m_sqrt" >&6; }
+if test "x$ac_cv_lib_m_sqrt" = xyes; then :
+ $as_echo "#define HAVE_SQRT 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqrtl in -lm" >&5
+$as_echo_n "checking for sqrtl in -lm... " >&6; }
+if ${ac_cv_lib_m_sqrtl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char sqrtl ();
+int
+main ()
+{
+return sqrtl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_sqrtl=yes
+else
+ ac_cv_lib_m_sqrtl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_sqrtl" >&5
+$as_echo "$ac_cv_lib_m_sqrtl" >&6; }
+if test "x$ac_cv_lib_m_sqrtl" = xyes; then :
+ $as_echo "#define HAVE_SQRTL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sinl in -lm" >&5
+$as_echo_n "checking for sinl in -lm... " >&6; }
+if ${ac_cv_lib_m_sinl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char sinl ();
+int
+main ()
+{
+return sinl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_sinl=yes
+else
+ ac_cv_lib_m_sinl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_sinl" >&5
+$as_echo "$ac_cv_lib_m_sinl" >&6; }
+if test "x$ac_cv_lib_m_sinl" = xyes; then :
+ $as_echo "#define HAVE_SINL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for tanhl in -lm" >&5
+$as_echo_n "checking for tanhl in -lm... " >&6; }
+if ${ac_cv_lib_m_tanhl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char tanhl ();
+int
+main ()
+{
+return tanhl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_tanhl=yes
+else
+ ac_cv_lib_m_tanhl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_tanhl" >&5
+$as_echo "$ac_cv_lib_m_tanhl" >&6; }
+if test "x$ac_cv_lib_m_tanhl" = xyes; then :
+ $as_echo "#define HAVE_TANHL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for tanl in -lm" >&5
+$as_echo_n "checking for tanl in -lm... " >&6; }
+if ${ac_cv_lib_m_tanl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char tanl ();
+int
+main ()
+{
+return tanl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_tanl=yes
+else
+ ac_cv_lib_m_tanl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_tanl" >&5
+$as_echo "$ac_cv_lib_m_tanl" >&6; }
+if test "x$ac_cv_lib_m_tanl" = xyes; then :
+ $as_echo "#define HAVE_TANL 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for png_get_pixels_per_inch in -lpng" >&5
+$as_echo_n "checking for png_get_pixels_per_inch in -lpng... " >&6; }
+if ${ac_cv_lib_png_png_get_pixels_per_inch+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpng $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char png_get_pixels_per_inch ();
+int
+main ()
+{
+return png_get_pixels_per_inch ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_png_png_get_pixels_per_inch=yes
+else
+ ac_cv_lib_png_png_get_pixels_per_inch=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_png_png_get_pixels_per_inch" >&5
+$as_echo "$ac_cv_lib_png_png_get_pixels_per_inch" >&6; }
+if test "x$ac_cv_lib_png_png_get_pixels_per_inch" = xyes; then :
+ $as_echo "#define HAVE_PNG_GET_PIXELS_PER_INCH 1" >>confdefs.h
+
+fi
+
+for ac_func in getuid setuid setgid
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in chdir chmod chown
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in opendir readdir closedir
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in getgrent getgrgid getgrnam endgrent setgrent
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in getpwuid getpwnam
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in fopen fclose feof ferror fflush fread fwrite
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in _fclose _feof _ferror _fflush _fopen _fread _fwrite
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in _getenv_s _wgetenv _getpid
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in fetestexcept _clearfp
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in fork getrlimit setpgrp setsid syslog
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in gethostname
+do :
+ ac_fn_c_check_func "$LINENO" "gethostname" "ac_cv_func_gethostname"
+if test "x$ac_cv_func_gethostname" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_GETHOSTNAME 1
+_ACEOF
+
+fi
+done
+
+for ac_func in time localtime localtime_s
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in stat stat32 lstat32
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in _stat _stat32 _stat64 _lstat _lstat32 _lstat64
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in mpctl sysconf sysctl
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in popen _popen
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in read write _read _write
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in seed48
+do :
+ ac_fn_c_check_func "$LINENO" "seed48" "ac_cv_func_seed48"
+if test "x$ac_cv_func_seed48" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SEED48 1
+_ACEOF
+
+fi
+done
+
+for ac_func in sprintf_s sscanf_s swscanf_s
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in strcat strchr strcmp strcpy strdup strlen strncmp strncpy _strdup
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in strncpy_s strrchr strtoimax strtol strtoll strtoul strtoull
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in strtoumax
+do :
+ ac_fn_c_check_func "$LINENO" "strtoumax" "ac_cv_func_strtoumax"
+if test "x$ac_cv_func_strtoumax" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_STRTOUMAX 1
+_ACEOF
+
+fi
+done
+
+for ac_func in wcsdup wcsncmp wcsncpy wcsncpy_s wcstoimax wcstol wcstoll
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in wcstoul wcstoull wcstoumax
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in _wcscat _wcschr _wcscpy _wcsdup _wcslen _wcsncmp _wcsncpy
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in _wcsrchr
+do :
+ ac_fn_c_check_func "$LINENO" "_wcsrchr" "ac_cv_func__wcsrchr"
+if test "x$ac_cv_func__wcsrchr" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE__WCSRCHR 1
+_ACEOF
+
+fi
+done
+
+for ac_func in tcflush tcgetattr
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in umask
+do :
+ ac_fn_c_check_func "$LINENO" "umask" "ac_cv_func_umask"
+if test "x$ac_cv_func_umask" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_UMASK 1
+_ACEOF
+
+fi
+done
+
+for ac_func in GetFinalPathNameByHandle
+do :
+ ac_fn_c_check_func "$LINENO" "GetFinalPathNameByHandle" "ac_cv_func_GetFinalPathNameByHandle"
+if test "x$ac_cv_func_GetFinalPathNameByHandle" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_GETFINALPATHNAMEBYHANDLE 1
+_ACEOF
+
+fi
+done
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking wchar_t" >&5
+$as_echo_n "checking wchar_t... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <sys/types.h>
+#include <wchar.h>
+
+int
+main ()
+{
+
+ wchar_t chr;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "#define HAVE_WCHAR_T 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking mkdir path mode" >&5
+$as_echo_n "checking mkdir path mode... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+int
+main ()
+{
+
+mkdir("test", 0755);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "#define HAVE_MKDIR2 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <db.h>
+
+int
+main ()
+{
+
+DBT k;
+DBT v;
+DBC *cp;
+cp->c_get(cp, &k, &v, DB_FIRST);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ $as_echo "#define HAVE_DB_CURSOR_C_GET 1" >>confdefs.h
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking const" >&5
+$as_echo_n "checking const... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+static char const msg[] = { "Test" };
+
+int
+main ()
+{
+
+fputs(msg, stdout);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "#define HAVE_CONST 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking inline" >&5
+$as_echo_n "checking inline... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+
+inline
+int
+summe(int a, int b)
+{
+ return (a + b);
+}
+
+
+int
+main ()
+{
+
+int i = 5;
+int j = 6;
+int k;
+
+k = summe(i, j);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };FOUNDINLINE="yes"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if [ "X$FOUNDINLINE" = "Xyes" -a "X$USEINLINE" = "Xyes" ]
+then
+ $as_echo "#define HAVE_INLINE 1" >>confdefs.h
+
+fi
+
+if test -b /dev/urandom
+then
+ $as_echo "#define HAVE_DEV_URANDOM 1" >>confdefs.h
+
+fi
+if test -c /dev/urandom
+then
+ $as_echo "#define HAVE_DEV_URANDOM 1" >>confdefs.h
+
+fi
+if test -b /dev/random
+then
+ $as_echo "#define HAVE_DEV_RANDOM 1" >>confdefs.h
+
+fi
+if test -c /dev/random
+then
+ $as_echo "#define HAVE_DEV_RANDOM 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking fpclassify" >&5
+$as_echo_n "checking fpclassify... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#if HAVE_MATH_H
+#include <math.h>
+#endif
+
+int
+main ()
+{
+
+int cl;
+cl = fpclassify(-0.5);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "#define HAVE_FPCLASSIFY 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+for ac_func in getpeername
+do :
+ ac_fn_c_check_func "$LINENO" "getpeername" "ac_cv_func_getpeername"
+if test "x$ac_cv_func_getpeername" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_GETPEERNAME 1
+_ACEOF
+
+$as_echo "#define HAVE_GETPEERNAME 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getpeername in -lxnet" >&5
+$as_echo_n "checking for getpeername in -lxnet... " >&6; }
+if ${ac_cv_lib_xnet_getpeername+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lxnet $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getpeername ();
+int
+main ()
+{
+return getpeername ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_xnet_getpeername=yes
+else
+ ac_cv_lib_xnet_getpeername=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xnet_getpeername" >&5
+$as_echo "$ac_cv_lib_xnet_getpeername" >&6; }
+if test "x$ac_cv_lib_xnet_getpeername" = xyes; then :
+
+$as_echo "#define HAVE_GETPEERNAME 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getpeername in -lnsl" >&5
+$as_echo_n "checking for getpeername in -lnsl... " >&6; }
+if ${ac_cv_lib_nsl_getpeername+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getpeername ();
+int
+main ()
+{
+return getpeername ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_nsl_getpeername=yes
+else
+ ac_cv_lib_nsl_getpeername=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_getpeername" >&5
+$as_echo "$ac_cv_lib_nsl_getpeername" >&6; }
+if test "x$ac_cv_lib_nsl_getpeername" = xyes; then :
+
+$as_echo "#define HAVE_GETPEERNAME 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getpeername in -lsocket" >&5
+$as_echo_n "checking for getpeername in -lsocket... " >&6; }
+if ${ac_cv_lib_socket_getpeername+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getpeername ();
+int
+main ()
+{
+return getpeername ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_socket_getpeername=yes
+else
+ ac_cv_lib_socket_getpeername=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_getpeername" >&5
+$as_echo "$ac_cv_lib_socket_getpeername" >&6; }
+if test "x$ac_cv_lib_socket_getpeername" = xyes; then :
+
+$as_echo "#define HAVE_GETPEERNAME 1" >>confdefs.h
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+done
+
+
+for ac_func in getsockname
+do :
+ ac_fn_c_check_func "$LINENO" "getsockname" "ac_cv_func_getsockname"
+if test "x$ac_cv_func_getsockname" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_GETSOCKNAME 1
+_ACEOF
+
+$as_echo "#define HAVE_GETSOCKNAME 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getsockname in -lxnet" >&5
+$as_echo_n "checking for getsockname in -lxnet... " >&6; }
+if ${ac_cv_lib_xnet_getsockname+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lxnet $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getsockname ();
+int
+main ()
+{
+return getsockname ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_xnet_getsockname=yes
+else
+ ac_cv_lib_xnet_getsockname=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xnet_getsockname" >&5
+$as_echo "$ac_cv_lib_xnet_getsockname" >&6; }
+if test "x$ac_cv_lib_xnet_getsockname" = xyes; then :
+
+$as_echo "#define HAVE_GETSOCKNAME 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getsockname in -lnsl" >&5
+$as_echo_n "checking for getsockname in -lnsl... " >&6; }
+if ${ac_cv_lib_nsl_getsockname+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getsockname ();
+int
+main ()
+{
+return getsockname ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_nsl_getsockname=yes
+else
+ ac_cv_lib_nsl_getsockname=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_getsockname" >&5
+$as_echo "$ac_cv_lib_nsl_getsockname" >&6; }
+if test "x$ac_cv_lib_nsl_getsockname" = xyes; then :
+
+$as_echo "#define HAVE_GETSOCKNAME 1" >>confdefs.h
+
+
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getsockname in -lsocket" >&5
+$as_echo_n "checking for getsockname in -lsocket... " >&6; }
+if ${ac_cv_lib_socket_getsockname+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getsockname ();
+int
+main ()
+{
+return getsockname ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_socket_getsockname=yes
+else
+ ac_cv_lib_socket_getsockname=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_getsockname" >&5
+$as_echo "$ac_cv_lib_socket_getsockname" >&6; }
+if test "x$ac_cv_lib_socket_getsockname" = xyes; then :
+
+$as_echo "#define HAVE_GETSOCKNAME 1" >>confdefs.h
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+done
+
+
+
+
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/utilities.h>
+
+int
+main ()
+{
+
+netsnmp_session session, *ss;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+SNMPPROG="snmpprog"
+SNMP_PROG_CLI='$(SNMP_PROG_CLI)'
+$as_echo "#define HAVE_LIBNETSNMP 1" >>confdefs.h
+
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for snmp_enable_filelog in -lnetsnmp" >&5
+$as_echo_n "checking for snmp_enable_filelog in -lnetsnmp... " >&6; }
+if ${ac_cv_lib_netsnmp_snmp_enable_filelog+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnetsnmp $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char snmp_enable_filelog ();
+int
+main ()
+{
+return snmp_enable_filelog ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_netsnmp_snmp_enable_filelog=yes
+else
+ ac_cv_lib_netsnmp_snmp_enable_filelog=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_netsnmp_snmp_enable_filelog" >&5
+$as_echo "$ac_cv_lib_netsnmp_snmp_enable_filelog" >&6; }
+if test "x$ac_cv_lib_netsnmp_snmp_enable_filelog" = xyes; then :
+ SNMPPROG="snmpprog";$as_echo "#define HAVE_SNMP_ENABLE_FILELOG 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for snmp_disable_syslog in -lnetsnmp" >&5
+$as_echo_n "checking for snmp_disable_syslog in -lnetsnmp... " >&6; }
+if ${ac_cv_lib_netsnmp_snmp_disable_syslog+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnetsnmp $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char snmp_disable_syslog ();
+int
+main ()
+{
+return snmp_disable_syslog ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_netsnmp_snmp_disable_syslog=yes
+else
+ ac_cv_lib_netsnmp_snmp_disable_syslog=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_netsnmp_snmp_disable_syslog" >&5
+$as_echo "$ac_cv_lib_netsnmp_snmp_disable_syslog" >&6; }
+if test "x$ac_cv_lib_netsnmp_snmp_disable_syslog" = xyes; then :
+ $as_echo "#define HAVE_SNMP_DISABLE_SYSLOG 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for snmp_disable_stderrlog in -lnetsnmp" >&5
+$as_echo_n "checking for snmp_disable_stderrlog in -lnetsnmp... " >&6; }
+if ${ac_cv_lib_netsnmp_snmp_disable_stderrlog+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnetsnmp $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char snmp_disable_stderrlog ();
+int
+main ()
+{
+return snmp_disable_stderrlog ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_netsnmp_snmp_disable_stderrlog=yes
+else
+ ac_cv_lib_netsnmp_snmp_disable_stderrlog=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_netsnmp_snmp_disable_stderrlog" >&5
+$as_echo "$ac_cv_lib_netsnmp_snmp_disable_stderrlog" >&6; }
+if test "x$ac_cv_lib_netsnmp_snmp_disable_stderrlog" = xyes; then :
+ $as_echo "#define HAVE_SNMP_DISABLE_STDERRLOG 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for snmp_disable_filelog in -lnetsnmp" >&5
+$as_echo_n "checking for snmp_disable_filelog in -lnetsnmp... " >&6; }
+if ${ac_cv_lib_netsnmp_snmp_disable_filelog+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnetsnmp $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char snmp_disable_filelog ();
+int
+main ()
+{
+return snmp_disable_filelog ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_netsnmp_snmp_disable_filelog=yes
+else
+ ac_cv_lib_netsnmp_snmp_disable_filelog=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_netsnmp_snmp_disable_filelog" >&5
+$as_echo "$ac_cv_lib_netsnmp_snmp_disable_filelog" >&6; }
+if test "x$ac_cv_lib_netsnmp_snmp_disable_filelog" = xyes; then :
+ $as_echo "#define HAVE_SNMP_DISABLE_FILELOG 1" >>confdefs.h
+
+fi
+
+IEEE_754_DOUBLE_WISHED='yes'
+IEEE_754_DOUBLE_FOUND='no'
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking IEEE 754 double" >&5
+$as_echo_n "checking IEEE 754 double... " >&6; }
+if test "$cross_compiling" = yes; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no - test not possible" >&5
+$as_echo "no - test not possible" >&6; }
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_STRING_H
+#include <string.h>
+#endif
+#if HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#include <math.h>
+
+static double td[] = {
+ INFINITY,
+ 1234.75,
+ 4.0,
+ 1.0,
+ 0.375,
+ 0.0,
+ -0.625,
+ -1.0,
+ -8.0,
+ -23.875,
+ -INFINITY
+};
+
+#if WORDS_BIGENDIAN
+static unsigned char tuc[] = {
+ /* INF */ 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* 1234.75 */ 0x40, 0x93, 0x4B, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* 4.0 */ 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* 1.0 */ 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* 0.375 */ 0x3F, 0xD8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* 0.0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* -0.625 */ 0xBF, 0xE4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* -1.0 */ 0xBF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* -8.0 */ 0xC0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* -23.875 */ 0xC0, 0x37, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* -INF */ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+#else
+static unsigned char tuc[] = {
+ /* INF */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x7F,
+ /* 1234.75 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x4B, 0x93, 0x40,
+ /* 4.0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40,
+ /* 1.0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F,
+ /* 0.375 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x3F,
+ /* 0.0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* -0.625 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE4, 0xBF,
+ /* -1.0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xBF,
+ /* -8.0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xC0,
+ /* -23.875 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x37, 0xC0,
+ /* -INF */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF
+};
+#endif
+
+static
+#ifdef __cplusplus
+int
+test_double(double *dp, unsigned char *up)
+#else
+int
+test_double(dp, up)
+ double *dp;
+ unsigned char *up;
+#endif
+{
+ int back = 0;
+#if HAVE_MEMCMP
+ if(memcmp(dp, up, 8) == 0) {
+ back = 1;
+ }
+#else
+#if HAVE_BCMP
+ if(bcmp(dp, up, 8) == 0) {
+ back = 1;
+ }
+#else
+ unsigned char *cp1;
+ unsigned char *cp2;
+ size_t i;
+ back = 1;
+ cp1 = (unsigned char *)dp; cp2 = up;
+ for(i = 0; i < 8; i++) {
+ if(*(cp1++) != *(cp2++)) {
+ back = 0;
+ }
+ }
+#endif
+#endif
+ if(1 != back) {
+ printf("ERROR: %lg not conforming to IEEE 754!\n", *dp);
+ }
+ return back;
+}
+
+#ifdef __cplusplus
+int main(int argc, char *argv[])
+#else
+int main(argc, argv)
+ int argc;
+ char *argv[];
+#endif
+{
+ unsigned char *ucp;
+ double *dp;
+ size_t i;
+ int ev = 1;
+
+ if(8 == sizeof(double)) {
+ ev = 0;
+ ucp = tuc; dp = td;
+ for(i = 0; i < (sizeof(td)/sizeof(double)); i++) {
+ if(!test_double(dp, ucp)) {
+ ev = 1;
+ }
+ dp++;
+ ucp += 8;
+ }
+ } else {
+ printf("ERROR: Size of double is not 1!\n");
+ }
+ exit(ev);
+}
+
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };IEEE_754_DOUBLE_FOUND="yes"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; };IEEE_754_DOUBLE_FOUND="no"
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+if [ "X$IEEE_754_DOUBLE_FOUND$IEEE_754_DOUBLE_WISHED" = "Xyesyes" ]
+then
+ $as_echo "#define HAVE_IEEE_754_DOUBLE 1" >>confdefs.h
+
+else
+ IEEE_754_DOUBLE_FOUND='no'
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking isfinite" >&5
+$as_echo_n "checking isfinite... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#if HAVE_MATH_H
+#include <math.h>
+#endif
+
+int
+main ()
+{
+
+ double x;
+ int a = 0;
+ x = 5.0;
+ if (isfinite(x)) {
+ a = 1;
+ }
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "#define HAVE_ISFINITE 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking isnormal" >&5
+$as_echo_n "checking isnormal... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#if HAVE_MATH_H
+#include <math.h>
+#endif
+
+int
+main ()
+{
+
+ double x;
+ int a = 0;
+ x = 5.0;
+ if (isnormal(x)) {
+ a = 1;
+ }
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "#define HAVE_ISNORMAL 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking use of twos complement for negative integers" >&5
+$as_echo_n "checking use of twos complement for negative integers... " >&6; }
+if test "$cross_compiling" = yes; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no - test not possible" >&5
+$as_echo "no - test not possible" >&6; }
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_PROCESS_H
+#include <process.h>
+#endif
+
+int i1 = -1;
+
+#if SIZEOF_INT > 2
+#if SIZEOF_INT > 4
+#if SIZEOF_INT > 8
+#error "No test available yet for integers larger than 8 bytes!"
+#else
+int i2 = 0xFFFFFFFFFFFFFFFF;
+#endif
+#else
+int i2 = 0xFFFFFFFF;
+#endif
+#else
+int i2 = 0xFFFF;
+#endif
+
+int main(int argc, char *argv[])
+{
+ int exval = 1;
+ if (i1 == i2) exval = 0;
+ exit(exval); return exval;
+}
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };$as_echo "#define HAVE_TWOS_COMPLEMENT 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+CLI_SNMPPROG=''
+if [ "X$SNMPPROG" != "X" ]
+then
+ CLI_SNMPPROG='pjsnmp$(EXEEXT)'
+fi
+
+
+CLI_MYSQLPROG=''
+if [ "X$MYSQLPROG" != "X" ]
+then
+ CLI_MYSQLPROG='itadmin$(EXEEXT)'
+ MYSQL_PROG_CLI='$(MYSQL_PROG_CLI)'
+ [ ! -f /usr/lib/mysql/libmysqlclient.so ] || LDFLAGS="$LDFLAGS -L/usr/lib/mysql"
+ [ ! -f /usr/lib/mysql/libmysqlclient.a ] || LDFLAGS="$LDFLAGS -L/usr/lib/mysql"
+ [ ! -f /usr/lib/mysql/libmysqlclient.so ] || MYSQLLDFLAGS="-L/usr/lib/mysql"
+ [ ! -f /usr/lib/mysql/libmysqlclient.a ] || MYSQLLDFLAGS="-L/usr/lib/mysql"
+ [ ! -f /usr/lib64/mysql/libmysqlclient.so ] || LDFLAGS="$LDFLAGS -L/usr/lib64/mysql"
+ [ ! -f /usr/lib64/mysql/libmysqlclient.a ] || LDFLAGS="$LDFLAGS -L/usr/lib64/mysql"
+ [ ! -f /usr/lib64/mysql/libmysqlclient.so ] || MYSQLLDFLAGS="-L/usr/lib64/mysql"
+ [ ! -f /usr/lib64/mysql/libmysqlclient.a ] || MYSQLLDFLAGS="-L/usr/lib64/mysql"
+fi
+
+if [ "X$SUITE" = "Xgui" ]
+then
+ LIBDK3WXOBJ='$(LIBDK3WXOBJ)'
+ LIBDK4WXOBJ='$(LIBDK4WXOBJ)'
+ LIBDK4WXTOBUILD='libdk4wx.$(LIBEXT)'
+fi
+
+
+if [ "X$ENASHARED" = "Xyes" -a "X$USESOLINKING" = "Xyes" ]
+then
+ SOLIBZ="$ZLIB"
+ SOLIBBZ="$BZLIB"
+ SOLIBMATH="-lm"
+ SOLIBCRYPTO="$CRYPTO"
+ SOLIBNET="$NETLIB"
+ SOLIBIMG="$IMGLIBS"
+ SOLIBSDBI="$DKSDBILIBS"
+ SOLIBWX=`wx-config --libs`
+ SOLIBDK3PORT=""
+ SOLIBDK3C="-ldk3c"
+ SOLIBDK3OF="-ldk3of"
+ SOLIBDK3CSRND="-ldk3csrnd"
+ SOLIBDK3BIF="-ldk3bif"
+ SOLIBDK3DBI="-ldk3dbi"
+ SOLIBDK3FIG="-ldk3fig"
+ SOLIBDK3BMEPS="-ldk3bmeps"
+ SOLIBDK3NET="-ldk3net"
+ SOLIBDK4BASE="-ldk4base"
+ SOLIBDK4MA="-ldk4ma"
+ SOLIBDK4MAIO8H="-ldk4maio8h"
+ SOLIBDK4MAIOWH="-ldk4maiowh"
+ SOLIBDK4MAIODH="-ldk4maiodh"
+ SOLIBDK4MAIO8D="-ldk4maio8d"
+ SOLIBDK4MAIOWD="-ldk4maiowd"
+ SOLIBDK4MAIODD="-ldk4maiodd"
+ SOLIBDK4C="-ldk4c"
+ SOLIBDK4MDRND="-ldk4mdrnd"
+ SOLIBDK4PPPT="-ldk4pppt"
+ SOLIBDK4APP="-ldk4app"
+ SOLIBDK4LAT="-ldk4lat"
+ SOLIBDK4SOCK="-ldk4sock"
+ SOLIBDK4SOCKA="-ldk4socka"
+ SOLIBDK4DBI="-ldk4dbi"
+ SOLIBDK4DBIA="-ldk4dbia"
+ LIBDK4MALIBF="libdk4base.so"
+ LIBDK4MALIBS='-ldk4base'
+ LIBDK4MAIO8DLIBF="libdk4base.so libdk4ma.so"
+ LIBDK4MAIO8DLIBS='-ldk4ma -ldk4base'
+ LIBDK4MAIOWDLIBF="libdk4base.so libdk4ma.so"
+ LIBDK4MAIOWDLIBS='-ldk4ma -ldk4base'
+ LIBDK4MAIODDLIBF="libdk4base.so libdk4maio8d.so"
+ LIBDK4MAIODDLIBS='-ldk4maio8d -ldk4base'
+ LIBDK4MAIOXDLIBF="libdk4base.so libdk4maio8d.so libdk4maiowd.so"
+ LIBDK4MAIOXDLIBS='-ldk4maiowd -ldk4maio8d -ldk4base'
+ LIBDK4MAIO8HLIBF="libdk4base.so"
+ LIBDK4MAIO8HLIBS='-ldk4base'
+ LIBDK4MAIOWHLIBF="libdk4base.so"
+ LIBDK4MAIOWHLIBS='-ldk4base'
+ LIBDK4MAIODHLIBF="libdk4base.so libdk4maio8h.so"
+ LIBDK4MAIODHLIBS='-ldk4maio8h -ldk4base'
+ LIBDK4CLIBF="libdk4base.so libdk4ma.so libdk4maio8d.so libdk4maiodd.so"
+ LIBDK4CLIBS='-ldk4maiodd -ldk4maio8d -ldk4ma -ldk4base $(BZLIB) $(ZLIB) -lm'
+ LIBDK4DBILIBF="libdk4base.so libdk4ma.so libdk4c.so"
+ LIBDK4DBILIBS='-ldk4c -ldk4ma -ldk4base $(DBLIB)'
+ LIBDK4SOCKLIBF="libdk4base.so libdk4maio8d.so libdk4c.so"
+ LIBDK4SOCKLIBS='-ldk4c -ldk4maio8d -ldk4base $(SOCKLIB) $(NSLLIB)'
+ LIBDK4MDRNDLIBF="libdk4base.so libdk4c.so"
+ LIBDK4MDRNDLIBS='-ldk4c -ldk4base $(CRYPTO)'
+ LIBDK4PPPTLIBF="libdk4base.so libdk4maiodd.so libdk4c.so"
+ LIBDK4PPPTLIBS='-ldk4c -ldk4maiodd -ldk4base'
+ LIBDK4APPLIBF="libdk4base.so libdk4ma.so libdk4maio8d.so libdk4maiodd.so libdk4c.so"
+ LIBDK4APPLIBS='-ldk4c -ldk4maiodd -ldk4maio8d -ldk4ma -ldk4base'
+ LIBDK4LATLIBF="libdk4base.so libdk4ma.so libdk4maio8h.so libdk4maiodh.so libdk4maiodd.so libdk4c.so libdk4app.so"
+ LIBDK4LATLIBS='-ldk4app -ldk4c -ldk4maiodd -ldk4maiodh -ldk4maio8h -ldk4ma -ldk4base'
+ LIBDK4PPPTALIBF="libdk4base.so libdk4c.so libdk4pppt.so libdk4app.so"
+ LIBDK4PPPTALIBS='-ldk4app -ldk4pppt -ldk4c -ldk4base'
+ LIBDK4SOCKALIBF="libdk4base.so libdk4maio8h.so libdk4maio8d.so libdk4maiodh.so libdk4maiodd.so libdk4sock.so libdk4app.so"
+ LIBDK4SOCKALIBS='-ldk4app -ldk4sock -ldk4maiodd -ldk4maiodh -ldk4maio8d -ldk4maio8h -ldk4base $(SOCKLIB) $(NSLLIB)'
+ LIBDK4DBIALIBF="libdk4base.so libdk4dbi.so libdk4app.so"
+ LIBDK4DBIALIBS='-ldk4dbi -ldk4app -ldk4base $(DBLIB)'
+ LIBDK4WXLIBF="libdk4base.so libdk4maio8d.so libdk4maiowd.so libdk4c.so libdk4app.so"
+ LIBDK4WXLIBS='-ldk4app -ldk4c -ldk4maiowd -ldk4maio8d -ldk4base $(WXLDFLAGS)'
+ LIBDK3TRACELIBF=""
+ LIBDK3TRACELIBS=''
+ LIBDK3CLIBF=""
+ LIBDK3CLIBS='$(BZLIB) $(ZLIB) -lm'
+ LIBDK3OFLIBF="libdk3c.so"
+ LIBDK3OFLIBS='-ldk3c $(BZLIB) $(ZLIB)'
+ LIBDK3CSRNDLIBF="libdk3c.so"
+ LIBDK3CSRNDLIBS='-ldk3c $(CRYPTO)'
+ LIBDK3BIFLIBF="libdk3c.so"
+ LIBDK3BIFLIBS='-ldk3c $(IMGLIBS)'
+ LIBDK3DBILIBF="libdk3c.so"
+ LIBDK3DBILIBS='-ldk3c $(DBLIB)'
+ LIBDK3BMEPSLIBF="libdk3c.so libdk3of.so libdk3bif.so"
+ LIBDK3BMEPSLIBS='-ldk3bif -ldk3of -ldk3c -lm'
+ LIBDK3FIGLIBF="libdk3c.so"
+ LIBDK3FIGLIBS='-ldk3c -lm'
+ LIBDK3WXLIBF="libdk3c.so"
+ LIBDK3WXLIBS='-ldk3c $(WXLDFLAGS)'
+fi
+if [ "X$ENASHARED" = "Xyes" -a "X$USESOLINKING" = "Xyes" -a "X$CROSSCOMPLING" = "Xyes" ]
+then
+ LIBDK4MAIODDLIBF="$LIBDK4MAIODDLIBF libdk4maiowd.so"
+ LIBDK4MAIODDLIBS='-ldk4maiowd $LIBDK4MAIODDLIBS'
+ LIBDK4MAIODHLIBF="$LIBDK4MAIODHLIBF libdk4maiowh.so"
+ LIBDK4MAIODHLIBS='-ldk4maiowh $LIBDK4MAIODHLIBS'
+fi
+
+case "X$ENAPACKAGING/X$USESOLINKING" in
+ "Xyes/Xyes")
+ DKCTLIBF='libdk3c.so'
+ DKCTLIBS='-ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ ADDCTRLDLIBF='libdk3c.so'
+ ADDCTRLDLIBS='-ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKDBTLIBF='libdk3c.so libdk3dbi.so'
+ DKDBTLIBS='-ldk3dbi -ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ ITADMINLIBF='libdk3c.so libdk3of.so'
+ ITADMINLIBS='-ldk3of -ldk3c -lmysqlclient $(CLILIB) $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB)'
+ BMPPLIBF='libdk3c.so libdk3bif.so libdk3of.so libdk3bmeps.so'
+ BMPPLIBS='-ldk3bmeps -ldk3of -ldk3bif -ldk3c $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB) -lm'
+ FIG2LATLIBF='libdk3c.so libdk3bif.so libdk3of.so libdk3bmeps.so libdk3fig.so'
+ FIG2LATLIBS='-ldk3fig -ldk3bmeps -ldk3of -ldk3bif -ldk3c $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB) -lm'
+ HTMLBOOKLIBF='libdk3c.so libdk3bif.so libdk3of.so libdk3bmeps.so'
+ HTMLBOOKLIBS='-ldk3bmeps -ldk3of -ldk3bif -ldk3c $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+ DK3INFOLIBF='libdk3c.so'
+ DK3INFOLIBS='-ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ PLPDFTEXLIBF='libdk3c.so libdk3bif.so libdk3of.so libdk3bmeps.so'
+ PLPDFTEXLIBS='-ldk3bmeps -ldk3of -ldk3bif -ldk3c $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB) -lm'
+ DKWXWIZLIBF='libdk3c.so'
+ DKWXWIZLIBS='-ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ WXDKCTLIBF='libdk3c.so libdk3wx.so'
+ WXDKCTLIBS='-ldk3wx -ldk3c $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+ WXBMPPLIBF='libdk3c.so libdk3bif.so libdk3of.so libdk3bmeps.so libdk3wx.so'
+ WXBMPPLIBS='-ldk3wx -ldk3bmeps -ldk3of -ldk3bif -ldk3c $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+ WXIMGSZLIBF='libdk3c.so libdk3wx.so'
+ WXIMGSZLIBS='-ldk3wx -ldk3c $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+ WXDKCLOCKLIBF='libdk3c.so libdk3wx.so'
+ WXDKCLOCKLIBS='-ldk3wx -ldk3c $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+ WXDKHTBLIBF='libdk3c.so libdk3wx.so'
+ WXDKHTBLIBS='-ldk3wx -ldk3c $(WXLDFLAGS) $(GUILIB) $(CLILIB) $(BZLIB) $(ZLIB)'
+ PRINTQDILIBF='libdk3c.so libdk3dbi.so'
+ PRINTQDILIBS='-ldk3dbi -ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ PRINTQDALIBF='libdk3c.so'
+ PRINTQDALIBS='-ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKCATLIBF='libdk4base.so libdk4c.so libdk4maiodd.so libdk4app.so'
+ DKCATLIBS='-ldk4app -ldk4maiodd -ldk4maio8d -ldk4c -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKBLKSLIBF='libdk4base.so libdk4c.so libdk4app.so'
+ DKBLKSLIBS='-ldk4app -ldk4c -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKSQLSPLITLIBF='libdk4base.so libdk4c.so libdk4app.so'
+ DKSQLSPLITLIBS='-ldk4app -ldk4c -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKERADISKLIBF='libdk4base.so libdk4c.so libdk4app.so'
+ DKERADISKLIBS='-ldk4app -ldk4c -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKLSLIBF='libdk4base.so libdk4c.so libdk4app.so libdk4mdrnd.so'
+ DKLSLIBS='-ldk4app -ldk4maiodd -ldk4maiodh -ldk4ma -ldk4mdrnd -ldk4c -ldk4base $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKSORTLIBF='libdk4base.so libdk4maiodd.so libdk4maiodh.so libdk4c.so libdk4app.so'
+ DKSORTLIBS='-ldk4app -ldk4c -ldk4maiodh -ldk4maiodd -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKFICLIBF='libdk4base.so libdk4ma.so libdk4maiodd.so libdk4c.so libdk4app.so libdk4mdrnd.so'
+ DKFICLIBS='-ldk4app -ldk4mdrnd -ldk4c -ldk4maiodd -ldk4ma -ldk4base $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKUIDLIBF='libdk4base.so libdk4ma.so libdk4maiodd.so libdk4c.so libdk4app.so'
+ DKUIDLIBS='-ldk4app -ldk4c -ldk4maiodd -ldk4ma -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKPWGENLIBF='libdk4base.so libdk4ma.so libdk4maiodd.so libdk4c.so libdk4app.so libdk4mdrnd.so'
+ DKPWGENLIBS='-ldk4app -ldk4mdrnd -ldk4c -ldk4maiodd -ldk4ma -ldk4base $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKRANDLIBF='libdk4base.so libdk4c.so libdk4app.so libdk4mdrnd.so'
+ DKRANDLIBS='-ldk4app -ldk4mdrnd -ldk4c -ldk4base $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKT2HLIBF='libdk4base.so libdk4maio8d.so libdk4maio8h.so libdk4maiodd.so libdk4c.so libdk4app.so'
+ DKT2HLIBS='-ldk4app -ldk4c -ldk4maiodd -ldk4maio8h -ldk4maio8d -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKT2LLIBF='libdk4base.so libdk4maiodd.so libdk4maiodh.so libdk4c.so libdk4app.so libdk4lat.so'
+ DKT2LLIBS='-ldk4lat -ldk4app -ldk4c -ldk4maiodh -ldk4maiodd -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKHEXLIBF='libdk4base.so libdk4c.so libdk4app.so libdk4maiodh.so'
+ DKHEXLIBS='-ldk4app -ldk4maiodh -ldk4c -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKBMMLIBF='libdk4base.so libdk4maio8d.so libdk4maiodd.so libdk4c.so libdk4app.so'
+ DKBMMLIBS='-ldk4app -ldk4c -ldk4maiodd -ldk4maio8d -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKPWDLIBF='libdk4base.so libdk4c.so libdk4app.so'
+ DKPWDLIBS='-ldk4app -ldk4c -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKRECVLIBF='libdk4base.so libdk4c.so libdk4sock.so libdk4app.so libdk4socka.so libdk4maiodd.so'
+ DKRECVLIBS='-ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4base $(CLILIB) $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) -lm'
+ DKSENDLIBF='libdk4base.so libdk4c.so libdk4sock.so libdk4app.so libdk4socka.so libdk4maiodd.so'
+ DKSENDLIBS='-ldk4maiodd -ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4base $(CLILIB) $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) -lm'
+ DKDBT2LIBF='libdk4base.so libdk4ma.so libdk4maiodd.so libdk4c.so libdk4dbi.so libdk4app.so libdk4dbia.so'
+ DKDBT2LIBS='-ldk4dbia -ldk4app -ldk4dbi -ldk4c -ldk4maiodd -ldk4ma -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DK4INFOLIBF='libdk4base.so libdk4maiodd.so libdk4c.so libdk4app.so'
+ DK4INFOLIBS='-ldk4app -ldk4c -ldk4maiodd -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ LPRNGCLLIBF='libdk4base.so libdk4c.so libdk4sock.so libdk4mdrnd.so libdk4app.so libdk4socka.so'
+ LPRNGCLLIBS='-ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4base $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) -lm'
+ WXDKFCSLIBF='libdk4base.so libdk4c.so libdk4mdrnd.so libdk4sock.so libdk4app.so libdk4socka.so libdk4wx.so'
+ WXDKFCSLIBS='-ldk4wx -ldk4socka -ldk4app -ldk4sock -ldk4mdrnd -ldk4c -ldk4base $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+ WXPQDICLIBF='libdk4base.so libdk4ma.so libdk4maio8d.so libdk4maiowd.so libdk4c.so libdk4sock.so libdk4app.so libdk4socka.so libdk4wx.so'
+ WXPQDICLIBS='-ldk4wx -ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4maiowd -ldk4maio8d -ldk4ma -ldk4base $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+ PJSNMPLIBF='libdk4base.so libdk4maio8h.so libdk4maio8d.so libdk4ma.so libdk4c.so libdk4sock.so libdk4app.so libdk4socka.so'
+ PJSNMPLIBS='-ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4ma -ldk4maio8d -ldk4maio8h -ldk4base $(NETSNMP_LIBS) $(SOCKLIB) $(NSLLIB)'
+ PRMONSNMPLIBF='libdk4base.so libdk4maio8h.so libdk4maio8d.so libdk4c.so libdk4sock.so libdk4app.so libdk4socka.so'
+ PRMONSNMPLIBS='-ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4maio8h -ldk4maio8d -ldk4base $(NETSNMP_LIBS) $(SOCKLIB) $(NSLLIB)'
+ PRINTQDLIBF='libdk4base.so libdk4maio8d.so libdk4c.so libdk4dbi.so libdk4sock.so'
+ PRINTQDLIBS='-ldk4sock -ldk4dbi -ldk4c -ldk4maio8d -ldk4base $(SOCKLIB) $(NSLLIB)'
+ PRINTQDCLIBF='libdk4base.so libdk4maio8d.so libdk4c.so libdk4sock.so libdk4app.so libdk4socka.so'
+ PRINTQDCLIBS='-ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4maio8d -ldk4base $(SOCKLIB) $(NSLLIB)'
+ RSHDOWNLIBF='libdk4base.so libdk4maio8d.so libdk4c.so libdk4sock.so'
+ RSHDOWNLIBS='-ldk4sock -ldk4c -ldk4maio8d -ldk4base $(SOCKLIB) $(NSLLIB)'
+ ;;
+ "Yyes/Xno")
+ DKCTLIBF='libdk3c.so'
+ DKCTLIBS='-ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ ADDCTRLDLIBF='libdk3c.so'
+ ADDCTRLDLIBS='-ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKDBTLIBF='libdk3c.so libdk3dbi.so'
+ DKDBTLIBS='-ldk3dbi -ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ ITADMINLIBF='libdk3c.so libdk3of.so'
+ ITADMINLIBS='-ldk3of -ldk3c -lmysqlclient $(CLILIB) $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB)'
+ BMPPLIBF='libdk3c.so libdk3bif.so libdk3of.so libdk3bmeps.so'
+ BMPPLIBS='-ldk3bmeps -ldk3of -ldk3bif -ldk3c $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB) -lm'
+ FIG2LATLIBF='libdk3c.so libdk3bif.so libdk3of.so libdk3bmeps.so libdk3fig.so'
+ FIG2LATLIBS='-ldk3fig -ldk3bmeps -ldk3of -ldk3bif -ldk3c $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB) -lm'
+ HTMLBOOKLIBF='libdk3c.so libdk3bif.so libdk3of.so libdk3bmeps.so'
+ HTMLBOOKLIBS='-ldk3bmeps -ldk3of -ldk3bif -ldk3c $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+ DK3INFOLIBF='libdk3c.so'
+ DK3INFOLIBS='-ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ PLPDFTEXLIBF='libdk3c.so libdk3bif.so libdk3of.so libdk3bmeps.so'
+ PLPDFTEXLIBS='-ldk3bmeps -ldk3of -ldk3bif -ldk3c $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB) -lm'
+ DKWXWIZLIBF='libdk3c.so'
+ DKWXWIZLIBS='-ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ WXDKCTLIBF='libdk3c.so libdk3wx.so'
+ WXDKCTLIBS='-ldk3wx -ldk3c $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+ WXBMPPLIBF='libdk3c.so libdk3bif.so libdk3of.so libdk3bmeps.so libdk3wx.so'
+ WXBMPPLIBS='-ldk3wx -ldk3bmeps -ldk3of -ldk3bif -ldk3c $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+ WXIMGSZLIBF='libdk3c.so libdk3wx.so'
+ WXIMGSZLIBS='-ldk3wx -ldk3c $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+ WXDKCLOCKLIBF='libdk3c.so libdk3wx.so'
+ WXDKCLOCKLIBS='-ldk3wx -ldk3c $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+ WXDKHTBLIBF='libdk3c.so libdk3wx.so'
+ WXDKHTBLIBS='-ldk3wx -ldk3c $(WXLDFLAGS) $(GUILIB) $(CLILIB) $(BZLIB) $(ZLIB)'
+ PRINTQDILIBF='libdk3c.so libdk3dbi.so'
+ PRINTQDILIBS='-ldk3dbi -ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ PRINTQDALIBF='libdk3c.so'
+ PRINTQDALIBS='-ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKCATLIBF='libdk4base.so libdk4c.so libdk4app.so'
+ DKCATLIBS='-ldk4app -ldk4c -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKBLKSLIBF='libdk4base.so libdk4c.so libdk4app.so'
+ DKBLKSLIBS='-ldk4app -ldk4c -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKSQLSPLITLIBF='libdk4base.so libdk4c.so libdk4app.so'
+ DKSQLSPLITLIBS='-ldk4app -ldk4c -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKERADISKLIBF='libdk4base.so libdk4c.so'
+ DKERADISKLIBS='-ldk4c -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKLSLIBF='libdk4base.so libdk4c.so libdk4app.so libdk4mdrnd.so'
+ DKLSLIBS='-ldk4app -ldk4mdrnd -ldk4c -ldk4base $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKSORTLIBF='libdk4base.so libdk4maiodd.so libdk4maiodh.so libdk4c.so libdk4app.so'
+ DKSORTLIBS='-ldk4app -ldk4c -ldk4maiodh -ldk4maiodd -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKFICLIBF='libdk4base.so libdk4ma.so libdk4maiodd.so libdk4c.so libdk4app.so libdk4mdrnd.so'
+ DKFICLIBS='-ldk4app -ldk4mdrnd -ldk4c -ldk4maiodd -ldk4ma -ldk4base $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKUIDLIBF='libdk4base.so libdk4ma.so libdk4maiodd.so libdk4c.so libdk4app.so'
+ DKUIDLIBS='-ldk4app -ldk4c -ldk4maiodd -ldk4ma -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKPWGENLIBF='libdk4base.so libdk4ma.so libdk4maiodd.so libdk4c.so libdk4app.so libdk4mdrnd.so'
+ DKPWGENLIBS='-ldk4app -ldk4mdrnd -ldk4c -ldk4maiodd -ldk4ma -ldk4base $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKRANDLIBF='libdk4base.so libdk4c.so libdk4app.so libdk4mdrnd.so'
+ DKRANDLIBS='-ldk4app -ldk4mdrnd -ldk4c -ldk4base $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKT2HLIBF='libdk4base.so libdk4maio8d.so libdk4maio8h.so libdk4maiodd.so libdk4c.so libdk4app.so'
+ DKT2HLIBS='-ldk4app -ldk4c -ldk4maiodd -ldk4maio8h -ldk4maio8d -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKT2LLIBF='libdk4base.so libdk4maiodd.so libdk4maiodh.so libdk4c.so libdk4app.so libdk4lat.so'
+ DKT2LLIBS='-ldk4lat -ldk4app -ldk4c -ldk4maiodh -ldk4maiodd -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKHEXLIBF='libdk4base.so libdk4c.so libdk4app.so'
+ DKHEXLIBS='-ldk4app -ldk4c -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKBMMLIBF='libdk4base.so libdk4maio8d.so libdk4maiodd.so libdk4c.so libdk4app.so'
+ DKBMMLIBS='-ldk4app -ldk4c -ldk4maiodd -ldk4maio8d -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKPWDLIBF='libdk4base.so libdk4c.so libdk4app.so'
+ DKPWDLIBS='-ldk4app -ldk4c -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKRECVLIBF='libdk4base.so libdk4c.so libdk4sock.so libdk4app.so libdk4socka.so'
+ DKRECVLIBS='-ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4base $(CLILIB) $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) -lm'
+ DKSENDLIBF='libdk4base.so libdk4c.so libdk4sock.so libdk4app.so libdk4socka.so libdk4maiodd.so'
+ DKSENDLIBS='-ldk4maiodd -ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4base $(CLILIB) $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) -lm'
+ DKDBT2LIBF='libdk4base.so libdk4ma.so libdk4maiodd.so libdk4c.so libdk4dbi.so libdk4app.so libdk4dbia.so'
+ DKDBT2LIBS='-ldk4dbia -ldk4app -ldk4dbi -ldk4c -ldk4maiodd -ldk4ma -ldk4base $(DBLIBSOCK) $(CLILIB) $(BZLIB) $(ZLIB)'
+ DK4INFOLIBF='libdk4base.so libdk4maiodd.so libdk4c.so libdk4app.so'
+ DK4INFOLIBS='-ldk4app -ldk4c -ldk4maiodd -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ LPRNGCLLIBF='libdk4base.so libdk4c.so libdk4sock.so libdk4mdrnd.so libdk4app.so libdk4socka.so'
+ LPRNGCLLIBS='-ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4base $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) -lm'
+ WXDKFCSLIBF='libdk4base.so libdk4c.so libdk4mdrnd.so libdk4sock.so libdk4app.so libdk4socka.so libdk4wx.so'
+ WXDKFCSLIBS='-ldk4wx -ldk4socka -ldk4app -ldk4sock -ldk4mdrnd -ldk4c -ldk4base $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+ WXPQDICLIBF='libdk4base.so libdk4ma.so libdk4maio8d.so libdk4maiowd.so libdk4c.so libdk4sock.so libdk4app.so libdk4socka.so libdk4wx.so'
+ WXPQDICLIBS='-ldk4wx -ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4maiowd -ldk4maio8d -ldk4ma -ldk4base $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+ PJSNMPLIBF='libdk4base.so libdk4maio8h.so libdk4maio8d.so libdk4ma.so libdk4c.so libdk4sock.so libdk4app.so libdk4socka.so'
+ PJSNMPLIBS='-ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4ma -ldk4maio8d -ldk4maio8h -ldk4base $(NETSNMP_LIBS) $(SOCKLIB) $(NSLLIB)'
+ PRMONSNMPLIBF='libdk4base.so libdk4maio8d.so libdk4maio8h.so libdk4c.so libdk4sock.so libdk4app.so libdk4socka.so'
+ PRMONSNMPLIBS='-ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4maio8h -ldk4maio8d -ldk4base $(NETSNMP_LIBS) $(SOCKLIB) $(NSLLIB)'
+ PRINTQDLIBF='libdk4base.so libdk4maio8d.so libdk4c.so libdk4dbi.so libdk4sock.so'
+ PRINTQDLIBS='-ldk4sock -ldk4dbi -ldk4c -ldk4maio8d -ldk4base $(DBLIB) $(SOCKLIB) $(NSLLIB)'
+ PRINTQDCLIBF='libdk4base.so libdk4maio8d.so libdk4c.so libdk4sock.so libdk4app.so libdk4socka.so'
+ PRINTQDCLIBS='-ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4maio8d -ldk4base $(SOCKLIB) $(NSLLIB)'
+ RSHDOWNLIBF='libdk4base.so libdk4maio8d.so libdk4c.so libdk4sock.so'
+ RSHDOWNLIBS='-ldk4sock -ldk4c -ldk4maio8d -ldk4base $(SOCKLIB) $(NSLLIB)'
+ ;;
+esac
+
+if [ "X$WGET" != "X" ]
+then
+ GETSOURCE='wget -O dktools-$(VERSNO) $(SFBASE)/dktools-$(VERSNO).tar.gz/download'
+elif [ "X$CURL" != "X" ]
+then
+ GETSOURCE='curl -L $(SFBASE)/dktools-$(VERSNO).tar.gz > dktools-$(VERSNO).tar.gz'
+fi
+
+if [ "X$UNAME" = "XSunOS" -a "X$SOLCOR" = "Xyes" ]
+then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking CFLAGS on Solaris" >&5
+$as_echo_n "checking CFLAGS on Solaris... " >&6; }
+ NETSNMP_LIBS=`echo $NETSNMP_LIBS | sed -f modsnmp.sed`
+ TMPVAR="$WXCPPFLAGS"
+ WXCPPFLAGS=''
+ for i in NOTHING $TMPVAR
+ do
+ case "X$i" in
+ "X-D*")
+ WXCPPFLAGS="$WXCPPFLAGS $i"
+ ;;
+ "X-I*")
+ WXCPPFLAGS="$WXCPPFLAGS $i"
+ ;;
+ esac
+ done
+ TMPVAR="$WXCXXFLAGS"
+ WXCXXFLAGS=''
+ for i in NOTHING $TMPVAR
+ do
+ case "X$i" in
+ "X-D*")
+ WXCXXFLAGS="$WXCXXFLAGS $i"
+ ;;
+ "X-I*")
+ WXCXXFLAGS="$WXCXXFLAGS $i"
+ ;;
+ "X-pthread")
+ WXCXXFLAGS="$WXCXXFLAGS $i"
+ ;;
+ esac
+ done
+ TMPVAR="$WXCFLAGS"
+ WXCFLAGS=''
+ for i in NOTHING $TMPVAR
+ do
+ case "X$i" in
+ "X-D*")
+ WXCFLAGS="$WXCFLAGS $i"
+ ;;
+ "X-I*")
+ WXCFLAGS="$WXCFLAGS $i"
+ ;;
+ "X-pthread")
+ WXCFLAGS="$WXCFLAGS $i"
+ ;;
+ esac
+ done
+ TMPVAR="$WXLDFLAGS"
+ WXLDFLAGS=''
+ for i in NOTHING $TMPVAR
+ do
+ case "X$i" in
+ "X-L*")
+ WXLDFLAGS="$WXLDFLAGS $i"
+ ;;
+ "X-l*")
+ WXLDFLAGS="$WXLDFLAGS $i"
+ ;;
+ "X-pthread")
+ WXLDFLAGS="$WXLDFLAGS $i"
+ ;;
+ esac
+ done
+ SOCKLIB='-lsocket'
+ NSLLIB='-lnsl'
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
+$as_echo "done" >&6; }
+fi
+
+if [ "X$ONWINDOWS" != "Xno" ]
+then
+ CLILIB='$(WINCLILIB)'
+ GUILIB='$(WINGUILIB)'
+ ENTRY='$(WINENTRY)'
+else
+ $as_echo "#define HAVE_INODES 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking manpage installation" >&5
+$as_echo_n "checking manpage installation... " >&6; }
+case "X$MANINST" in
+ "Xauto")
+ if uname -a | grep -q Debian
+ then
+ MANINST='no'
+ else
+ MANINST='yes'
+ fi
+ ;;
+esac
+if [ "X$MANINST" = "Xno" ]
+then
+ INSTALLMANPAGES=''
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANINST" >&5
+$as_echo "$MANINST" >&6; }
+
+DBLIBSOCK="$DBLIB"
+
+if [ "X$UNAME" = "XSunOS" -a "X$SOLCOR" = "Xyes" ]
+then
+ [ "X$DBLIBSOCK" = "X" ] || DBLIBSOCK="$DBLIBSOCK -lrt "'$(SOCKLIB)'
+ [ "X$DBLIB" = "X" ] || DBLIB="$DBLIB -lrt "
+ [ "X$CRYPTO" = "X" ] || CRYPTO="$CRYPTO -lssl "'$(SOCKLIB)'
+ [ "X$MYSQLLIB" = "X" ] || MYSQLLIB="$MYSQLLIB -lrt "'$(SOCKLIB)'
+fi
+
+LIBSPRIVATE="$CRYPTO $MYSQLLIB $DBLIB $LIBTIFF $LIBJPEG $BZLIB"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ac_config_files="$ac_config_files Makefile scripts/wr-dk3inst.sh scripts/wr-dk4inst.sh scripts/create-desktop-files.sh scripts/build-help.sh initd-printqd dktools.pc pkginfo debian/control"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+
+ (set) 2>&1 |
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ # `set' does not quote correctly, so add quotes: double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \.
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;; #(
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+) |
+ sed '
+ /^ac_cv_env_/b end
+ t clear
+ :clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ if test "x$cache_file" != "x/dev/null"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+ if test ! -f "$cache_file" || test -h "$cache_file"; then
+ cat confcache >"$cache_file"
+ else
+ case $cache_file in #(
+ */* | ?:*)
+ mv -f confcache "$cache_file"$$ &&
+ mv -f "$cache_file"$$ "$cache_file" ;; #(
+ *)
+ mv -f confcache "$cache_file" ;;
+ esac
+ fi
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+ ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.69. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration. Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ --config print configuration, then exit
+ -q, --quiet, --silent
+ do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+ --header=FILE[:TEMPLATE]
+ instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Report bugs to the package provider."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.69,
+ with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=?*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ --*=)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ $as_echo "$ac_cs_version"; exit ;;
+ --config | --confi | --conf | --con | --co | --c )
+ $as_echo "$ac_cs_config"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ '') as_fn_error $? "missing file argument" ;;
+ esac
+ as_fn_append CONFIG_FILES " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --he | --h)
+ # Conflict between --help and --header
+ as_fn_error $? "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+ --help | --hel | -h )
+ $as_echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+ *) as_fn_append ac_config_targets " $1"
+ ac_need_defaults=false ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+ set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ shift
+ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+ CONFIG_SHELL='$SHELL'
+ export CONFIG_SHELL
+ exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+ "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "scripts/wr-dk3inst.sh") CONFIG_FILES="$CONFIG_FILES scripts/wr-dk3inst.sh" ;;
+ "scripts/wr-dk4inst.sh") CONFIG_FILES="$CONFIG_FILES scripts/wr-dk4inst.sh" ;;
+ "scripts/create-desktop-files.sh") CONFIG_FILES="$CONFIG_FILES scripts/create-desktop-files.sh" ;;
+ "scripts/build-help.sh") CONFIG_FILES="$CONFIG_FILES scripts/build-help.sh" ;;
+ "initd-printqd") CONFIG_FILES="$CONFIG_FILES initd-printqd" ;;
+ "dktools.pc") CONFIG_FILES="$CONFIG_FILES dktools.pc" ;;
+ "pkginfo") CONFIG_FILES="$CONFIG_FILES pkginfo" ;;
+ "debian/control") CONFIG_FILES="$CONFIG_FILES debian/control" ;;
+
+ *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp= ac_tmp=
+ trap 'exit_status=$?
+ : "${ac_tmp:=$tmp}"
+ { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+ trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+ eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+ ac_cs_awk_cr='\\r'
+else
+ ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+ echo "cat >conf$$subs.awk <<_ACEOF" &&
+ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+ echo "_ACEOF"
+} >conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ . ./conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+ if test $ac_delim_n = $ac_delim_num; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+ N
+ s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = ""
+
+}
+{
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{
+h
+s///
+s/^/:/
+s/[ ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[ ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+ ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
+ if test -z "$ac_tt"; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any. Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[ ]*#[ ]*define[ ][ ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ for (key in D) D_is_set[key] = 1
+ FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+ line = \$ 0
+ split(line, arg, " ")
+ if (arg[1] == "#") {
+ defundef = arg[2]
+ mac1 = arg[3]
+ } else {
+ defundef = substr(arg[1], 2)
+ mac1 = arg[2]
+ }
+ split(mac1, mac2, "(") #)
+ macro = mac2[1]
+ prefix = substr(line, 1, index(line, defundef) - 1)
+ if (D_is_set[macro]) {
+ # Preserve the white space surrounding the "#".
+ print prefix "define", macro P[macro] D[macro]
+ next
+ } else {
+ # Replace #undef with comments. This is necessary, for example,
+ # in the case of _POSIX_SOURCE, which is predefined and required
+ # on some systems where configure will not decide to define it.
+ if (defundef == "undef") {
+ print "/*", prefix defundef, macro, "*/"
+ next
+ }
+ }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS "
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$ac_tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+ esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ as_fn_append ac_file_inputs " '$ac_f'"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input='Generated from '`
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+ fi
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`$as_echo "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$ac_tmp/stdin" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir="$ac_dir"; as_fn_mkdir_p
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+ esac
+ ac_MKDIR_P=$MKDIR_P
+ case $MKDIR_P in
+ [\\/$]* | ?:[\\/]* ) ;;
+ */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+ esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \
+ "$ac_tmp/out"`; test -z "$ac_out"; } &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&2;}
+
+ rm -f "$ac_tmp/stdin"
+ case $ac_file in
+ -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+ *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+ esac \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+ :H)
+ #
+ # CONFIG_HEADER
+ #
+ if test x"$ac_file" != x-; then
+ {
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
+ } >"$ac_tmp/config.h" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ rm -f "$ac_file"
+ mv "$ac_tmp/config.h" "$ac_file" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ fi
+ else
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
+ || as_fn_error $? "could not create -" "$LINENO" 5
+ fi
+ ;;
+
+
+ esac
+
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+ as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
+
+chmod 755 scripts/*.sh
+
+cp debian/dktools-lib.install.in debian/dktools-lib-${SOVERS}.install
+cp debian/dktools-lib.postinst.in debian/dktools-lib-${SOVERS}.postinst
+cp debian/dktools-lib.postrm.in debian/dktools-lib-${SOVERS}.postrm
+cp debian/dktools-lib-dev.install.in debian/dktools-lib-${SOVERS}-dev.install
+echo package-name-doesnt-match-sonames > debian/dktools-lib-${SOVERS}.lintian-overrides
+chmod 644 debian/dktools-lib-${SOVERS}.install
+chmod 644 debian/dktools-lib-${SOVERS}.postinst
+chmod 644 debian/dktools-lib-${SOVERS}.postrm
+chmod 644 debian/dktools-lib-${SOVERS}-dev.install
+chmod 644 debian/dktools-lib-${SOVERS}.lintian-overrides
+
+[ ! -f dk4config ] || rm -f dk4config
+[ ! -f dk4config.o ] || rm -f dk4config.o
+[ ! -f dk3config ] || rm -f dk3config
+[ ! -f dk3config.o ] || rm -fr dk3config.o
+[ ! -f wxcs ] || rm -f wxcs
+[ ! -f wxcs.o ] || rm -fr wxcs.o
+
+if [ "X$build" != "X$host" ]
+then
+ cp dk3conf.cross dk3conf.h
+ cp dk4conf.cross dk4conf.h
+ cp dk4wxcs.cross dk4wxcs.h
+ echo 'ERROR: Cross-compiling not supported!'
+elif [ "X$SUITE" = "Xgui" ]
+then
+ echo 'Build dk4config (C++)'
+ $MAKE dk4config
+ echo 'Build dk3config (C)'
+ $MAKE dk3config
+ echo 'Build wxcs (C++)'
+ $MAKE wxcs
+ echo 'Generating configuration files'
+ ./dk4config > dk4conf.h
+ ./dk3config > dk3conf.h
+ ./wxcs > dk4wxcs.h
+elif [ "X$CXX" != "X" ]
+then
+ echo 'Build dk4config (C++)'
+ $MAKE dk4config
+ echo 'Build dk3config (C)'
+ $MAKE dk3config
+ echo 'Generating configuration files'
+ cp dk4wxcs.cross dk4wxcs.h
+ ./dk4config > dk4conf.h
+ ./dk3config > dk3conf.h
+else
+ sed -f mod-dkconfig.sed < dk4config.cpp > dk4config.c
+ mv dk4config.cpp dk4config.cpp.bck
+ echo 'Build dk4config (C)'
+ $MAKE dk4config
+ echo 'Build dk3config (C)'
+ $MAKE dk3config
+ mv dk4config.cpp.bck dk4config.cpp
+ rm dk4config.c
+ echo 'Generating configuration files'
+ cp dk4wxcs.cross dk4wxcs.h
+ ./dk4config > dk4conf.h
+ ./dk3config > dk3conf.h
+fi
+sed -e 's/DK4/DK3/g' < dk4wxcs.h > dk3wxcs.h
+
+chmod 755 scripts/wr-dk4inst.sh
+echo './scripts/wr-dk4inst.sh > dk4inst.c'
+./scripts/wr-dk4inst.sh
+chmod 755 scripts/wr-dk3inst.sh
+./scripts/wr-dk3inst.sh > dk3inst.c
+chmod 755 scripts/create-desktop-files.sh
+./scripts/create-desktop-files.sh
+
+VERSNO=`cat version.txt`
+cat > dk4vers.h <<EOF
+#ifndef DK4VERS_H_INCLUDED
+#define DK4VERS_H_INCLUDED 1
+
+/** @file dk4vers.h Version number as text string.
+*/
+
+/** Version number in 8 bit characters.
+*/
+#define DKT_VERSION_C8 "$VERSNO"
+
+/** Version number in dkChar.
+*/
+#define DKT_VERSION_DK dkT("$VERSNO")
+
+#endif
+EOF
+
+cat > dk4verswx.h <<EOF
+#ifndef DK4VERSWX_H_INCLUDED
+/** Protection against multiple inclusions. */
+#define DK4VERSWX_H_INCLUDED 1
+/** @file dk4verswx.h Version number as wxChar string.
+*/
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include "wx/wxprec.h"
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#ifndef WX_WX_H_INCLUDED
+#include "wx/wx.h"
+#define WX_WX_H_INCLUDED 1
+#endif
+#endif
+
+/** Version number as wxChar string.
+*/
+#define DKT_VERSION_WX wxT("$VERSNO")
+
+#endif
+EOF
+
+echo ''
+echo 'Configuration summary'
+echo '====================='
+if [ "X$ZLIB" = "X-lz" ]
+then
+echo 'zlib: found.'
+else
+echo 'zlib: NOT found! Required!'
+echo ' SL 6.x package name: zlib-devel'
+echo ' Debian package name: libz-dev'
+echo ' URL: http://www.zlib.net'
+EXVAL=1
+fi
+if [ "X-lbz2" = "X$BZLIB" ]
+then
+echo 'libbz2: found.'
+else
+echo 'libbz2: NOT found! Recommended.'
+echo ' Bzip compression not available.'
+echo ' SL 6.x package name: bzip2-devel'
+echo ' Debian package name: libbz2-dev'
+echo ' URL: http://www.bzip.org'
+fi
+if [ "X$LIBPNG" = "X-lpng" ]
+then
+echo 'libpng: found.'
+else
+echo 'libpng: NOT found! Required!'
+echo ' SL 6.x package name: libpng-devel'
+echo ' Debian package name: libpng-dev'
+echo ' URL: http://www.libpng.org'
+EXVAL=1
+fi
+if [ "X$LIBJPEG" = "X-ljpeg" ]
+then
+echo 'libjpeg: found.'
+else
+echo 'libjpeg: NOT found! Recommended.'
+echo ' No JPEG support in bmpp and fig2lat.'
+echo ' SL 6.x package name: libjpeg-turbo-devel'
+echo ' Debian package name: libjpeg-dev'
+echo ' URL: http://www.ijg.org/'
+fi
+if [ "X$LIBTIFF" = "X-ltiff" ]
+then
+echo 'libtiff: found.'
+else
+echo 'libtiff: NOT found! Recommended.'
+echo ' No TIFF support in bmpp and fig2lat.'
+echo ' SL 6.x package name: libtiff-devel'
+echo ' Debian package name: libtiff-dev'
+echo ' URL: http://www.remotesensing.org/libtiff/'
+fi
+if [ "X$ANYDB" != "X" ]
+then
+echo "database: $ANYDB"
+else
+echo 'database: NOT found! Recommended.'
+echo ' Skipping printqd build!'
+echo ' SL 6.x package name: db4-devel'
+echo ' Debian package name: libdb-dev'
+echo ' URL: http://www.oracle.com/database/berkeley-db/'
+fi
+if [ "X$MYSQLPROG" = "Xmysqlprog" ]
+then
+echo 'MySQL: found.'
+else
+echo 'MySQL: NOT found! Recommended.'
+echo ' Skipping itadmin build.'
+echo ' SL 6.x package name: mysql-devel'
+echo ' Debian package name: libmysqlclient-dev'
+echo ' URL: http://www.mysql.com/'
+fi
+if [ "X$CRYPTO" != "X" ]
+then
+echo 'OpenSSL: found.'
+else
+echo 'OpenSSL: NOT found!'
+echo ' SL 6.x package name: openssl-devel'
+echo ' Debian package name: libssl-dev'
+echo ' URL: http://www.openssl.org/'
+fi
+if [ "X$WXCPPFLAGS" != "X" ]
+then
+echo 'wxWidgets: found.'
+else
+echo 'wxWidgets: NOT found!'
+echo ' SL 6.x package name: wxGTK-devel'
+echo ' Debian package name: libwxgtk3.0-dev'
+echo ' URL: http://www.wxwidgets.org/'
+fi
+case "X$SUITE" in
+"Xgui")
+echo 'Software bundle: CLI and GUI programs'
+;;
+"Xrescue")
+echo 'Software bundle: Rescue system programs'
+;;
+"*")
+echo 'Software bundle: CLI programs'
+;;
+esac
+if [ "X$ENASTATIC" = "Xyes" ]
+then
+echo 'Install static libraries: yes'
+else
+echo 'Install static libraries: no'
+fi
+if [ "X$ENASHARED" = "Xyes" ]
+then
+echo 'Install shared libraries: yes'
+else
+echo 'Install shared libraries: no'
+fi
+if [ "X$USESOLINKING" = "Xyes" ]
+then
+echo 'Nested shared library linking: yes'
+else
+echo 'Nested shared library linking: no'
+fi
+if [ "X$ENAPACKAGING" = "Xyes" ]
+then
+echo 'Binaries use shared libraries: yes'
+else
+echo 'Binaries use shared libraries: no'
+fi
+echo ''
+echo The INSTALL files describes how to install via '*.rpm' or '.deb' package.
+echo ''
+exit $EXVAL
+
diff --git a/support/dktools/configure.ac b/support/dktools/configure.ac
new file mode 100644
index 0000000000..e296baa982
--- /dev/null
+++ b/support/dktools/configure.ac
@@ -0,0 +1,3498 @@
+dnl configure-script
+AC_INIT(dk4.h)
+AC_CONFIG_HEADER(config.h)
+AC_PROG_CC
+AC_PROG_CPP
+AC_PROG_CXX
+AC_C_BIGENDIAN
+AC_PROG_MKDIR_P
+AC_PROG_SED
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_CANONICAL_HOST
+AC_CANONICAL_BUILD
+AC_CHECK_TOOL([RANLIB],[ranlib],[:])
+AC_CHECK_TOOL([AR],[ar],[ar])
+AC_CHECK_TOOL([NM],[nm],[nm])
+
+echo 'CC = ' $CC `which $CC`
+echo 'CXX = ' $CXX `which $CXX`
+
+dnl Some default values
+
+dnl If shared library A uses procedures from shared library B we can
+dnl either use -lB when building library A or build libraries indepently
+dnl one from another and use -lA -lB when building executables using
+dnl library A and probably B.
+dnl The first variant is called SOLINKING here.
+
+dnl Force the SOLINKING mechanism.
+FORCESOLINKING="no"
+
+dnl Default value for SOLINKING when not forced.
+USESOLINKING="no"
+
+dnl Makefile target to install man pages.
+dnl We install man pages from the Makefile on non-Debian systems.
+dnl On Debian man pages are handled by the package building system.
+INSTALLMANPAGES='install-manpages'
+
+LIBSPRIVATE=""
+
+dnl Automatically find whether or not to install man pages.
+MANINST='auto'
+
+dnl Exit status code.
+EXVAL=0
+
+dnl Flag: Apply corrections for Solaris.
+SOLCOR='no'
+
+dnl C compiler options for relocatable modules.
+CFPIC=''
+MKSOLIB=''
+SHLIBSTYLE=''
+UNAME=''
+WXCPPFLAGS=''
+WXCXXFLAGS=''
+WXCFLAGS=''
+WXLDFLAGS=''
+SUITE='auto'
+ENASTATIC='auto'
+ENASHARED='auto'
+PROGRAMS=''
+LIBRARIES=''
+LIBS_STATIC=''
+LIBS_SHARED=''
+LIBS_INSTALL=''
+RES_INSTALL=''
+RPATH=''
+RPATHLINK=''
+CWARN=''
+FOUND_GDBM='no'
+FOUND_NDBM='no'
+FOUND_BDB='no'
+USE_NDBM='auto'
+NET_PROG_RES=''
+NET_PROG_CLI=''
+MYSQL_PROG_CLI=''
+SNMP_PROG_CLI=''
+MYSQLLDFLAGS=''
+MYSQLLIB=''
+RTLIB=''
+SOLIBZ=''
+SOLIBBZ=''
+SOLIBMATH=''
+SOLIBCRYPTO=''
+SOLIBNET=''
+SOLIBIMG=''
+SOLIBSDBI=''
+SOLIBWX=''
+SOLIBDK3PORT=''
+SOLIBDK3C=''
+SOLIBDK3OF=''
+SOLIBDK3CSRND=''
+SOLIBDK3BIF=''
+SOLIBDK3DBI=''
+SOLIBDK3FIG=''
+SOLIBDK3BMEPS=''
+SOLIBDK3NET=''
+SOLIBDK4BASE=''
+SOLIBDK4MA=''
+SOLIBDK4MAIO8H=''
+SOLIBDK4MAIOWH=''
+SOLIBDK4MAIODH=''
+SOLIBDK4MAIO8D=''
+SOLIBDK4MAIOWD=''
+SOLIBDK4MAIODD=''
+SOLIBDK4C=''
+SOLIBDK4MDRND=''
+SOLIBDK4PPPT=''
+SOLIBDK4APP=''
+SOLIBDK4LAT=''
+SOLIBDK4SOCK=''
+SOLIBDK4SOCKA=''
+SOLIBDK4DBI=''
+SOLIBDK4DBIA=''
+LIBDK4BASELIBF=''
+LIBDK4BASELIBS=''
+LIBDK4MALIBF=''
+LIBDK4MALIBS=''
+LIBDK4MAIO8DLIBF=''
+LIBDK4MAIO8DLIBS=''
+LIBDK4MAIOWDLIBF=''
+LIBDK4MAIOWDLIBS=''
+LIBDK4MAIODDLIBF=''
+LIBDK4MAIODDLIBS=''
+LIBDK4MAIOXDLIBF=''
+LIBDK4MAIOXDLIBS=''
+LIBDK4MAIO8HLIBF=''
+LIBDK4MAIO8HLIBS=''
+LIBDK4MAIOWHLIBF=''
+LIBDK4MAIOWHLIBS=''
+LIBDK4MAIODHLIBF=''
+LIBDK4MAIODHLIBS=''
+LIBDK4DBILIBF=''
+LIBDK4DBILIBS=''
+LIBDK4CLIBF=''
+LIBDK4CLIBS=''
+LIBDK4LATLIBF=''
+LIBDK4LATLIBS=''
+LIBDK4SOCKLIBF=''
+LIBDK4SOCKLIBS=''
+LIBDK4MDRNDLIBF=''
+LIBDK4MDRNDLIBS=''
+LIBDK4PPPTLIBF=''
+LIBDK4PPPTLIBS=''
+LIBDK4APPLIBF=''
+LIBDK4APPLIBS=''
+LIBDK4PPPTALIBF=''
+LIBDK4PPPTALIBS=''
+LIBDK4SOCKALIBF=''
+LIBDK4SOCKALIBS=''
+LIBDK4DBIALIBF=''
+LIBDK4DBIALIBS=''
+LIBDK4WXLIBF=''
+LIBDK4WXLIBS=''
+LIBDK3TRACELIBF=''
+LIBDK3TRACELIBS=''
+LIBDK3CLIBF=''
+LIBDK3CLIBS=''
+LIBDK3OFLIBF=''
+LIBDK3OFLIBS=''
+LIBDK3CSRNDLIBF=''
+LIBDK3CSRNDLIBS=''
+LIBDK3BIFLIBF=''
+LIBDK3BIFLIBS=''
+LIBDK3DBILIBF=''
+LIBDK3DBILIBS=''
+LIBDK3BMEPSLIBF=''
+LIBDK3BMEPSLIBS=''
+LIBDK3FIGLIBF=''
+LIBDK3FIGLIBS=''
+LIBDK3WXLIBF=''
+LIBDK3WXLIBS=''
+
+
+VERSNO=`cat version.txt`
+SOVERS=`echo $VERSNO | sed -e 's/\.[[01-9]][[01-9]]*$//'`
+ENAPACKAGING="auto"
+LIB_SH_RES='$(LIB_SH_RES_NO_PACKAGING)'
+LIB_SH_CLI='$(LIB_SH_CLI_NO_PACKAGING)'
+UNAME=`uname -s`
+GETSOURCE='@echo "ERROR: Neither wget nor curl available, can not download source!" && false'
+WGET=''
+CURL=''
+CLILIB=''
+GUILIB=''
+ENTRY=''
+ONWINDOWS='no'
+WINUNICODE=''
+FOUNDINLINE="no"
+USEINLINE="no"
+CROSSCOMPILING="no"
+
+MAKE="echo No make program found to build"
+
+AC_MSG_CHECKING(GNU make)
+gmake maketest > /dev/null 2>&1
+if [[ "X$?" = "X0" ]]
+then
+ MAKE='gmake'
+ AC_MSG_RESULT(yes)
+else
+ AC_MSG_RESULT(no)
+fi
+
+AC_MSG_CHECKING(make)
+make maketest > /dev/null 2>&1
+if [[ "X$?" = "X0" ]]
+then
+ MAKE='make'
+ AC_MSG_RESULT(yes)
+else
+ AC_MSG_RESULT(no)
+fi
+
+dnl Check whether to build shared/static libraries
+AC_ARG_ENABLE(inline,[AS_HELP_STRING([--enable-inline],[Allow use of inline keyword (no / yes)])],[USEINLINE="$enableval"])
+AC_ARG_ENABLE(static,[AS_HELP_STRING([--enable-static],[Allow building static libraries (yes / no)])],[ENASTATIC="$enableval"])
+AC_ARG_ENABLE(shared,[AS_HELP_STRING([--enable-shared],[Allow building shared libraries (yes / no)])],[ENASHARED="$enableval"])
+AC_ARG_ENABLE(packaging,[AS_HELP_STRING([--enable-packaging],[Binaries use shared libraries (no / yes)])],[ENAPACKAGING="$enableval"])
+AC_ARG_ENABLE(ndbm,[AS_HELP_STRING([--enable-ndbm],[Explicitly enable/disable NDBM if found])],[USE_NDBM="$enableval"])
+AC_ARG_ENABLE(warnings,[AS_HELP_STRING([--enable-warnings],[Enable high warning level, gcc only (yes / no)])],[WARNVAL="$enableval"])
+AC_ARG_ENABLE(more-warnings,[AS_HELP_STRING([--enable-more-warnings],[Enable yet more warnings, gcc only (no / yes)])],[WARNMOREVAL="$enableval"])
+AC_ARG_WITH(suite,[AS_HELP_STRING([--with-suite=name],[Software suite to build: auto / gui / cli / rescue])],[SUITE="$withval"])
+AC_ARG_WITH(man,[AS_HELP_STRING([--with-man],[Install man pages (auto / yes / no)])],[MANINST="$withval"])
+AC_ARG_WITH(corrections,[AS_HELP_STRING([--with-corrections],[Enable corrections for Solaris: no / yes])],[SOLCOR="$withval"])
+
+if [[ "X$SOLCOR" = "Xyes" -a "X$UNAME" != "XSunOS" ]]
+then
+ echo 'ERROR: The --with-corrections option is for Solaris/SunOS only!'
+ SOLCOR='no'
+fi
+
+if [[ "X$host" != "X$build" ]]
+then
+ echo 'Building on: ' $build
+ echo 'Building for:' $host
+ CROSSCOMPILING="yes"
+ case "X$SUITE" in
+ "gui")
+ echo "Warning: Cross-compiling, switching suite to cross."
+ ;;
+ "cli")
+ echo "Warning: Cross-compiling, switching suite to cross."
+ ;;
+ esac
+ SUITE="cross"
+fi
+
+case "X$ENAPACKAGING" in
+ "Xauto")
+ if [[ "X$SUITE" = "Xrescue" ]]
+ then
+ ENAPACKAGING="yes"
+ else
+ ENAPACKAGING="no"
+ fi
+ ;;
+ "Xyes")
+ ENAPACKAGING="yes"
+ ;;
+ *)
+ ENAPACKAGING="no"
+ ;;
+esac
+
+dnl Check how to build shared libraries
+UNAME=`uname -s`
+if [[ "X$CC" = "Xgcc" ]]
+then
+ SHLIBSTYLE='gcc'
+ RPATHLINK="-Wl,-rpath-link,./"
+elif [[ "X$UNAME" = "XSunOS" ]]
+then
+ SHLIBSTYLE='workshop'
+fi
+
+if [[ "X$CC" = "Xgcc" -a "X$WARNVAL" != "Xno" ]]
+then
+ # Enable all warnings and some extra warnings
+ CWARN="-Wall"
+ WARNVAL=yes
+else
+ WARNVAL=no
+fi
+
+if [[ "X$CC" = "Xgcc" -a "X$WARNMOREVAL" == "Xyes" ]]
+then
+ # Extra warnings
+ CWARN="$CWARN -Wextra"
+ # Overlong strings (C89: 509 characters, C99: 4095 characters)
+ CWARN="$CWARN -Woverlength-strings"
+ # Padding bytes added to structures
+ CWARN="$CWARN -Wpadded"
+ # Redundant declarations
+ CWARN="$CWARN -Wredundant-decls"
+ # Suspicious logical operators in expressions
+ CWARN="$CWARN -Wlogical-op"
+ # Functions returning entire structures
+ CWARN="$CWARN -Waggregate-return"
+ # Prototypes required before function use
+ CWARN="$CWARN -Wstrict-prototypes"
+ # Old style function definitions
+ CWARN="$CWARN -old-style-definition"
+ # Prototypes missing for global functions (must be in a header)
+ CWARN="$CWARN -Wmissing-prototypes"
+ # Global function defined without a previous prototype
+ CWARN="$CWARN -Wmissing-declarations"
+ # "exern" definition in a function
+ CWARN="$CWARN -Wnested-externs"
+ # Unreachable code in a program
+ CWARN="$CWARN -Wunreachable-code"
+ # Failed to inline a function
+ CWARN="$CWARN -Winline"
+ # Invalid PCH file found
+ CWARN="$CWARN -Winvalid-pch"
+ # Variable length array
+ CWARN="$CWARN -Wvla"
+ # Using signed pointers
+ CWARN="$CWARN -Wpointer-sign"
+ # The stack protector can not handle some function
+ CWARN="$CWARN -Wstack-protector"
+ WARNMOREVAL="yes"
+else
+ WARNMOREVAL="no"
+fi
+
+dnl Check whether we can build shared libraries
+case "X$ENASHARED" in
+ "Xauto")
+ if [[ "X$SHLIBSTYLE" = "Xgcc" -o "X$SHLIBSTYLE" = "Xworkshop" ]]
+ then
+ ENASHARED='yes'
+ else
+ ENASHARED='no'
+ fi
+ ;;
+ "Xyes")
+ if [[ "X$SHLIBSTYLE" = "Xgcc" -o "X$SHLIBSTYLE" = "Xworkshop" ]]
+ then
+ ENASHARED='yes'
+ else
+ ENASHARED='no'
+ AC_MSG_ERROR([Can not build shared libraries!])
+ exit 1
+ fi
+ ;;
+ *)
+ ENASHARED='no'
+ ;;
+esac
+
+dnl Check whether to build static libraries
+if [[ "X$ENASTATIC" = "Xauto" ]]
+then
+ case "X$ENASHARED" in
+ "Xyes")
+ ENASTATIC='no'
+ ;;
+ "Xno")
+ ENASTATIC='yes'
+ ;;
+ esac
+fi
+if [[ "X$ENASTATIC" != "Xyes" -a "X$ENASTATIC" != "Xno" ]]
+then
+ ENASTATIC='no'
+fi
+
+dnl Check software suite to build
+WXCPPFLAGS=`wx-config --cppflags`
+WXCXXFLAGS=`wx-config --cxxflags`
+WXVERSION=`wx-config --version`
+WXCFLAGS=`wx-config --cflags`
+WXLDFLAGS=`wx-config --libs`
+case "X$SUITE" in
+ "Xauto")
+ SUITE='gui'
+ if [[ "X$WXCPPFLAGS" = "X" ]]
+ then
+ SUITE="cli"
+ fi
+ if [[ "X$WXCXXFLAGS" = "X" ]]
+ then
+ SUITE="cli"
+ fi
+ if [[ "X$WXCFLAGS" = "X" ]]
+ then
+ SUITE="cli"
+ fi
+ if [[ "X$WXLDFLAGS" = "X" ]]
+ then
+ SUITE="cli"
+ fi
+ ;;
+ "Xgui")
+ if [[ "X$WXCPPFLAGS" = "X" ]]
+ then
+ SUITE="cli"
+ fi
+ if [[ "X$WXCXXFLAGS" = "X" ]]
+ then
+ SUITE="cli"
+ fi
+ if [[ "X$WXCFLAGS" = "X" ]]
+ then
+ SUITE="cli"
+ fi
+ if [[ "X$WXLDFLAGS" = "X" ]]
+ then
+ SUITE="cli"
+ fi
+ if [[ "X$SUITE" != "Xgui" ]]
+ then
+ AC_MSG_ERROR([Can not build GUI applications, wxWidgets not found!])
+ exit 1
+ fi
+ ;;
+ "Xcli")
+ SUITE='cli'
+ ;;
+ "Xrescue")
+ SUITE='rescue'
+ ;;
+ "Xcross")
+ SUITE='cross'
+ ;;
+ *)
+ AC_MSG_WARN([Unknown suite type $SUITE changed to cli.])
+ SUITE='cli'
+ ;;
+esac
+
+dnl Check presence of programs
+if [[ "X$RANLIB" = "X:" ]]
+then
+ RANLIB="@echo No need to run ranlib"
+fi
+AC_CHECK_PROG(WGET,wget,wget)
+AC_CHECK_PROG(CURL,curl,curl)
+
+dnl Decide which programs and libraries to build
+if [[ "X$SUITE" = "Xrescue" ]]
+then
+ PROGRAMS='$(PROG_RES)'
+ LIBS_STATIC='$(LIB_ST_RES)'
+ LIBS_SHARED='$(LIB_SH_RES)'
+ RES_INSTALL='i-r-res'
+ INSTALLMANPAGES='install-rescue-man'
+ case "$ENASHARED/$ENASTATIC" in
+ "yes/yes")
+ LIBRARIES='$(LIB_SH_RES) $(LIB_ST_RES)'
+ ;;
+ "yes/no")
+ LIBRARIES='$(LIB_SH_RES)'
+ ;;
+ "no/yes")
+ LIBRARIES='$(LIB_ST_RES)'
+ ;;
+ esac
+ case "X$ENAPACKAGING" in
+ "Xyes")
+ LIBS_INSTALL='i-l-sh'
+ ;;
+ esac
+ LIBRARIES=''
+elif [[ "X$SUITE" = "Xgui" ]]
+then
+ PROGRAMS='$(PROG_GUI)'
+ LIBS_STATIC='$(LIB_ST_GUI)'
+ LIBS_SHARED='$(LIB_SH_GUI)'
+ RES_INSTALL='i-r-gui'
+ case "$ENASHARED/$ENASTATIC" in
+ "yes/yes")
+ LIBRARIES='$(LIB_SH_GUI) $(LIB_ST_GUI)'
+ LIBS_INSTALL='i-l-sh i-l-st i-incl'
+ ;;
+ "yes/no")
+ LIBRARIES='$(LIB_SH_GUI)'
+ LIBS_INSTALL='i-l-sh i-incl'
+ ;;
+ "no/yes")
+ LIBRARIES='$(LIB_ST_GUI)'
+ LIBS_INSTALL='i-l-st i-incl'
+ ;;
+ esac
+elif [[ "X$SUITE" = "Xcross" ]]
+then
+ PROGRAMS='$(PROG_CROSS)'
+ LIBS_STATIC='$(LIB_ST_CLI)'
+ LIBS_SHARED='$(LIB_SH_CLI)'
+ RES_INSTALL='i-r-cli'
+ case "$ENASHARED/$ENASTATIC" in
+ "yes/yes")
+ LIBRARIES='$(LIB_SH_CLI) $(LIB_ST_CLI)'
+ LIBS_INSTALL='i-l-sh i-l-st i-incl'
+ ;;
+ "yes/no")
+ LIBRARIES='$(LIB_SH_CLI)'
+ LIBS_INSTALL='i-l-sh i-incl'
+ ;;
+ "no/yes")
+ LIBRARIES='$(LIB_ST_CLI)'
+ LIBS_INSTALL='i-l-st i-incl'
+ ;;
+ esac
+ LIBRARIES='$(LIB_ST_CLI)'
+ LIBS_INSTALL='i-l-st i-incl'
+ ENASHARED='no'
+ ENASTATIC='yes'
+ case "X$host" in
+ "Xx86_64-w64-mingw32")
+ ONWINDOWS="yes"
+ WINUNICODE="-D_UNICODE=1 -DUNICODE=1"
+ AC_DEFINE(HAVE_BACKSLASH_AS_SEP)
+ AC_DEFINE(HAVE_LINE_END_CR_NL)
+ AC_DEFINE(HAVE_CASE_INSENSITIVE_PATHNAMES)
+ ;;
+ esac
+else
+ PROGRAMS='$(PROG_CLI)'
+ LIBS_STATIC='$(LIB_ST_CLI)'
+ LIBS_SHARED='$(LIB_SH_CLI)'
+ RES_INSTALL='i-r-cli'
+ case "$ENASHARED/$ENASTATIC" in
+ "yes/yes")
+ LIBRARIES='$(LIB_SH_CLI) $(LIB_ST_CLI)'
+ LIBS_INSTALL='i-l-sh i-l-st i-incl'
+ ;;
+ "yes/no")
+ LIBRARIES='$(LIB_SH_CLI)'
+ LIBS_INSTALL='i-l-sh i-incl'
+ ;;
+ "no/yes")
+ LIBRARIES='$(LIB_ST_CLI)'
+ LIBS_INSTALL='i-l-st i-incl'
+ ;;
+ esac
+fi
+
+if [[ "X$ENASHARED" = "Xno" ]]
+then
+ ENAPACKAGING="no"
+fi
+
+APPLIBF="libdk4app.so libdk4c.so"
+if [[ "X$CROSSCOMPILING" = "Xyes" ]]
+then
+ APPLIBF="$APPLIBF libdk4ma.so libdk4maiodd.so libdk4maiowd.so libdk4maio8d.so"
+else
+ APPLIBF="$APPLIBF libdk4ma.so libdk4maiodd.so libdk4maio8d.so"
+fi
+APPLIBF="$APPLIBF libdk4base.so"
+
+APPLIBS="-ldk4app -ldk4c"
+if [[ "X$CROSSCOMPILING" = "Xyes" ]]
+then
+ APPLIBS="$APPLIBS -ldk4ma -ldk4maiodd -ldk4maiowd -ldk4maio8d"
+else
+ APPLIBS="$APPLIBS -ldk4ma -ldk4maiodd -ldk4maio8d"
+fi
+APPLIBS="$APPLIBS -ldk4base"
+
+DKCTLIBF='libdk3.a'
+DKCTLIBS='-ldk3 $(CLILIB) $(BZLIB) $(ZLIB)'
+ADDCTRLDLIBF='libdk3.a'
+ADDCTRLDLIBS='-ldk3 $(CLILIB) $(BZLIB) $(ZLIB)'
+DKDBTLIBF='libdk3.a'
+DKDBTLIBS='-ldk3 $(CLILIB) $(BZLIB) $(ZLIB)'
+ITADMINLIBF='libdk3.a'
+ITADMINLIBS='-ldk3 -lmysqlclient $(CLILIB) $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) $(RTLIB)'
+BMPPLIBF='libdk3.a'
+BMPPLIBS='-ldk3 $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB) -lm'
+FIG2LATLIBF='libdk3.a'
+FIG2LATLIBS='-ldk3 $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB) -lm'
+HTMLBOOKLIBF='libdk3.a'
+HTMLBOOKLIBS='-ldk3 $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+DK3INFOLIBF='libdk3.a'
+DK3INFOLIBS='-ldk3 $(CLILIB) $(BZLIB) $(ZLIB)'
+PLPDFTEXLIBF='libdk3.a'
+PLPDFTEXLIBS='-ldk3 $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB) -lm'
+DKWXWIZLIBF='libdk3.a'
+DKWXWIZLIBS='-ldk3 $(CLILIB) $(BZLIB) $(ZLIB)'
+WXDKCTLIBF='libdk3.a'
+WXDKCTLIBS='-ldk3 $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+WXBMPPLIBF='libdk3.a'
+WXBMPPLIBS='-ldk3 $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+WXIMGSZLIBF='libdk3.a'
+WXIMGSZLIBS='-ldk3 $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+WXDKCLOCKLIBF='libdk3.a'
+WXDKCLOCKLIBS='-ldk3 $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+WXDKHTBLIBF='libdk3.a'
+WXDKHTBLIBS='-ldk3 $(WXLDFLAGS) $(GUILIB) $(CLILIB) $(BZLIB) $(ZLIB)'
+PRINTQDILIBF='libdk3.a'
+PRINTQDILIBS='-ldk3 $(CLILIB) $(BZLIB) $(ZLIB)'
+PRINTQDALIBF='libdk3.a'
+PRINTQDALIBS='-ldk3 $(CLILIB) $(BZLIB) $(ZLIB)'
+
+DKCATLIBF="libdk4.a"
+DKCATLIBS='-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)'
+DKBLKSLIBF="libdk4.a"
+DKBLKSLIBS='-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)'
+DKSQLSPLITLIBF="libdk4.a"
+DKSQLSPLITLIBS='-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)'
+DKERADISKLIBF="libdk4.a"
+DKERADISKLIBS='-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)'
+DKLSLIBF="libdk4.a"
+DKLSLIBS='-ldk4 $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+DKSORTLIBF="libdk4.a"
+DKSORTLIBS='-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)'
+DKFICLIBF="libdk4.a"
+DKFICLIBS='-ldk4 $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+DKUIDLIBF="libdk4.a"
+DKUIDLIBS='-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)'
+DKPWGENLIBF="libdk4.a"
+DKPWGENLIBS='-ldk4 $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+DKRANDLIBF="libdk4.a"
+DKRANDLIBS='-ldk4 $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+DKT2HLIBF="libdk4.a"
+DKT2HLIBS='-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)'
+DKT2LLIBF="libdk4.a"
+DKT2LLIBS='-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)'
+DKHEXLIBF="libdk4.a"
+DKHEXLIBS='-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)'
+DKBMMLIBF="libdk4.a"
+DKBMMLIBS='-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)'
+DKPWDLIBF="libdk4.a"
+DKPWDLIBS='-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)'
+DKRECVLIBF="libdk4.a"
+DKRECVLIBS='-ldk4 $(CLILIB) $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) -lm'
+DKSENDLIBF="libdk4.a"
+DKSENDLIBS='-ldk4 $(CLILIB) $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) -lm'
+DKDBT2LIBF="libdk4.a"
+DKDBT2LIBS='-ldk4 $(DBLIBSOCK) $(CLILIB) $(BZLIB) $(ZLIB)'
+DK4INFOLIBF="libdk4.a"
+DK4INFOLIBS='-ldk4 $(CLILIB) $(BZLIB) $(ZLIB)'
+LPRNGCLLIBF="libdk4.a"
+LPRNGCLLIBS='-ldk4 $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) -lm'
+WXDKFCSLIBF="libdk4.a"
+WXDKFCSLIBS='-ldk4 $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+WXPQDICLIBF="libdk4.a"
+WXPQDICLIBS='-ldk4 $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+PJSNMPLIBF="libdk4.a"
+PJSNMPLIBS='-ldk4 $(NETSNMP_LIBS) $(SOCKLIB) $(NSLLIB)'
+PRMONSNMPLIBF="libdk4.a"
+PRMONSNMPLIBS='-ldk4 $(NETSNMP_LIBS) $(SOCKLIB) $(NSLLIB)'
+PRINTQDLIBF="libdk4.a"
+PRINTQDLIBS='-ldk4 $(DBLIB) $(SOCKLIB) $(NSLLIB)'
+PRINTQDCLIBF="libdk4.a"
+PRINTQDCLIBS='-ldk4 $(SOCKLIB) $(NSLLIB)'
+RSHDOWNLIBF="libdk4.a"
+RSHDOWNLIBS='-ldk4 $(SOCKLIB) $(NSLLIB)'
+
+LIB_SH_RES='$(LIB_SH_RES_NO_PACKAGING)'
+LIB_SH_CLI='$(LIB_SH_CLI_NO_PACKAGING)'
+LIB_SH_GUI='$(LIB_SH_GUI_NO_PACKAGING)'
+if [[ "X$ENAPACKAGING" = "Xyes" ]]
+then
+LIB_SH_RES='$(LIB_SH_RES_PACKAGING)'
+LIB_SH_CLI='$(LIB_SH_CLI_PACKAGING)'
+LIB_SH_GUI='$(LIB_SH_GUI_PACKAGING)'
+fi
+
+dnl Check whether to link so files with so files
+if [[ "X$CC" = "Xgcc" -a "X$UNAME" = "XLinux" ]]
+then
+ USESOLINKING="yes"
+fi
+if [[ "X$SHLIBSTYLE" = "Xworkshop" -o "X$FORCESOLINKING" = "Xyes" ]]
+then
+ USESOLINKING="yes"
+fi
+
+
+dnl Set compiler and linker flags for shared libraries
+case "X$SHLIBSTYLE" in
+ "Xgcc")
+ CFPIC='-fPIC -D_REENTRANT'
+ if [[ "X$USESOLINKING" = "Xyes" ]]
+ then
+ MKSOLIB='$(COMPILEC) -L. $(RPATHLINK) $(LIBRARIES) $(LDFLAGS) -shared -o $@.$(SOVERS) -Wl,-soname,$@.$(SOVERS)'
+ else
+ MKSOLIB='$(COMPILEC) $(LIBRARIES) $(LDFLAGS) -shared -o $@.$(SOVERS) -Wl,-soname,$@.$(SOVERS)'
+ fi
+ ;;
+ "Xworkshop")
+ if [[ "X$ENASHARED" != "Xno" ]]
+ then
+ CFPIC='-Bdynamic -dy -xcode=pic32 -D_REENTRANT'
+ else
+ CFPIC='-xcode=pic32 -D_REENTRANT'
+ fi
+ MKSOLIB='$(COMPILEC) -L. $(LIBRARIES) $(LDFLAGS) -G -h $@.$(SOVERS) -o $@.$(SOVERS)'
+ ;;
+esac
+
+dnl Create -R option for linker
+if [[ "X$LD_LIBRARY_PATH" != "X" -a "X$SHLIBSTYLE" = "Xworkshop" ]]
+then
+ RPATH="-R${LD_LIBRARY_PATH}"
+fi
+
+dnl Standard headers mentioned in C coding standard
+AC_HEADER_CHECK(errno.h, AC_DEFINE(HAVE_ERRNO_H))
+AC_HEADER_CHECK(assert.h, AC_DEFINE(HAVE_ASSERT_H))
+AC_HEADER_CHECK(complex.h, AC_DEFINE(HAVE_COMPLEX_H))
+AC_HEADER_CHECK(ctype.h, AC_DEFINE(HAVE_CTYPE_H))
+AC_HEADER_CHECK(fenv.h, AC_DEFINE(HAVE_FENV_H))
+AC_HEADER_CHECK(float.h, AC_DEFINE(HAVE_FLOAT_H))
+AC_HEADER_CHECK(inttypes.h, AC_DEFINE(HAVE_INTTYPES_H))
+AC_HEADER_CHECK(iso646.h, AC_DEFINE(HAVE_ISO646_H))
+AC_HEADER_CHECK(limits.h, AC_DEFINE(HAVE_LIMITS_H))
+AC_HEADER_CHECK(locale.h, AC_DEFINE(HAVE_LOCALE_H))
+AC_HEADER_CHECK(math.h, AC_DEFINE(HAVE_MATH_H))
+AC_HEADER_CHECK(setjmp.h, AC_DEFINE(HAVE_SETJMP_H))
+AC_HEADER_CHECK(signal.h, AC_DEFINE(HAVE_SIGNAL_H))
+AC_HEADER_CHECK(stdalign.h, AC_DEFINE(HAVE_STDALIGN_H))
+AC_HEADER_CHECK(stdarg.h, AC_DEFINE(HAVE_STDARG_H))
+AC_HEADER_CHECK(stdatomic.h, AC_DEFINE(HAVE_STDATOMIC_H))
+AC_HEADER_CHECK(stdbool.h, AC_DEFINE(HAVE_STDBOOL_H))
+AC_HEADER_CHECK(stddef.h, AC_DEFINE(HAVE_STDDEF_H))
+AC_HEADER_CHECK(stdint.h, AC_DEFINE(HAVE_STDINT_H))
+AC_HEADER_CHECK(stdlib.h, AC_DEFINE(HAVE_STDLIB_H))
+AC_HEADER_CHECK(stdnoreturn.h, AC_DEFINE(HAVE_STDNORETURN_H))
+AC_HEADER_CHECK(string.h, AC_DEFINE(HAVE_STRING_H))
+AC_HEADER_CHECK(tgmath.h, AC_DEFINE(HAVE_TGMATH_H))
+AC_HEADER_CHECK(threads.h, AC_DEFINE(HAVE_THREADS_H))
+AC_HEADER_CHECK(time.h, AC_DEFINE(HAVE_TIME_H))
+AC_HEADER_CHECK(uchar.h, AC_DEFINE(HAVE_UCHAR_H))
+AC_HEADER_CHECK(wchar.h, AC_DEFINE(HAVE_WCHAR_H))
+AC_HEADER_CHECK(wctype.h, AC_DEFINE(HAVE_WCTYPE_H))
+
+
+
+dnl Further headers
+AC_HEADER_CHECK(sys/types.h, AC_DEFINE(HAVE_SYS_TYPES_H))
+AC_HEADER_CHECK(sys/param.h, AC_DEFINE(HAVE_SYS_PARAM_H))
+AC_HEADER_CHECK(sys/stat.h, AC_DEFINE(HAVE_SYS_STAT_H))
+AC_HEADER_CHECK(sys/time.h, AC_DEFINE(HAVE_SYS_TIME_H))
+AC_HEADER_CHECK(sys/socket.h, AC_DEFINE(HAVE_SYS_SOCKET_H))
+AC_HEADER_CHECK(sys/select.h, AC_DEFINE(HAVE_SYS_SELECT_H))
+AC_HEADER_CHECK(sys/un.h, AC_DEFINE(HAVE_SYS_UN_H))
+AC_HEADER_CHECK(netinet/in.h, AC_DEFINE(HAVE_NETINET_IN_H))
+AC_HEADER_CHECK(netinet/in6.h, AC_DEFINE(HAVE_NETINET_IN6_H))
+AC_HEADER_CHECK(netdb.h, AC_DEFINE(HAVE_NETDB_H))
+AC_HEADER_CHECK(arpa/inet.h, AC_DEFINE(HAVE_ARPA_INET_H))
+AC_HEADER_CHECK(winsock2.h, AC_DEFINE(HAVE_WINSOCK2_H))
+AC_HEADER_CHECK(ws2tcpip.h, AC_DEFINE(HAVE_WS2TCPIP_H))
+AC_HEADER_CHECK(windows.h, AC_DEFINE(HAVE_WINDOWS_H))
+AC_HEADER_CHECK(unistd.h, AC_DEFINE(HAVE_UNISTD_H))
+AC_HEADER_CHECK(process.h, AC_DEFINE(HAVE_PROCESS_H))
+AC_HEADER_CHECK(fcntl.h, AC_DEFINE(HAVE_FCNTL_H))
+AC_HEADER_CHECK(share.h, AC_DEFINE(HAVE_SHARE_H))
+AC_HEADER_CHECK(pwd.h, AC_DEFINE(HAVE_PWD_H))
+AC_HEADER_CHECK(strings.h, AC_DEFINE(HAVE_STRINGS_H))
+AC_HEADER_CHECK(io.h, AC_DEFINE(HAVE_IO_H))
+AC_HEADER_CHECK(bios.h, AC_DEFINE(HAVE_BIOS_H))
+AC_HEADER_CHECK(dos.h, AC_DEFINE(HAVE_DOS_H))
+AC_HEADER_CHECK(alloc.h, AC_DEFINE(HAVE_ALLOC_H))
+AC_HEADER_CHECK(malloc.h, AC_DEFINE(HAVE_MALLOC_H))
+AC_HEADER_CHECK(dirent.h, AC_DEFINE(HAVE_DIRENT_H))
+AC_HEADER_CHECK(direct.h, AC_DEFINE(HAVE_DIRECT_H))
+AC_HEADER_CHECK(zlib.h, [ZLIB="-lz";AC_DEFINE(HAVE_ZLIB_H)])
+AC_HEADER_CHECK(bzlib.h, [BZLIB="-lbz2";AC_DEFINE(HAVE_BZLIB_H)])
+
+dnl OpenSSL Random number generation and message digests.
+CRYPTO=""
+PROGSOPENSSL=""
+AC_HEADER_CHECK(openssl/rand.h, [
+CRYPTO="-lcrypto"
+PROGSOPENSSL='dk-fic$(EXEEXT) dk-pwgen$(EXEEXT) dk-rand$(EXEEXT)'
+AC_DEFINE(HAVE_OPENSSL_RAND_H)
+])
+AC_HEADER_CHECK(openssl/md5.h, [AC_DEFINE(HAVE_OPENSSL_MD5_H)])
+AC_HEADER_CHECK(openssl/sha.h, [AC_DEFINE(HAVE_OPENSSL_SHA_H)])
+AC_HEADER_CHECK(openssl/ripemd.h, [AC_DEFINE(HAVE_OPENSSL_RIPEMD_H)])
+
+dnl time headers, use both
+AC_HEADER_TIME
+
+dnl Data type long long
+AC_MSG_CHECKING(longlong)
+AC_TRY_COMPILE([
+#include <stdio.h>
+],[
+ long long l;
+ l = (long long)0L;
+],[AC_MSG_RESULT(yes);AC_DEFINE(HAVE_LONG_LONG)],[AC_MSG_RESULT(no)])
+
+dnl Data type long double
+AC_MSG_CHECKING(longdouble)
+AC_TRY_COMPILE([
+#include <stdio.h>
+#include <math.h>
+],[
+ long double l;
+ l = (long double)0.0;
+],[AC_MSG_RESULT(yes);AC_DEFINE(HAVE_LONG_DOUBLE)],[AC_MSG_RESULT(no)])
+DOINTMAXSIZECHECK="no"
+
+dnl Data type intmax_t
+AC_MSG_CHECKING(intmax_t)
+AC_TRY_COMPILE([
+#include <stdio.h>
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#if HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+],[
+intmax_t im;
+],[DOINTMAXSIZECHECK="yes";AC_MSG_RESULT(yes);AC_DEFINE(HAVE_INTMAX_T)],[AC_MSG_RESULT(no)])
+
+dnl Keyword volatile
+AC_MSG_CHECKING(volatile)
+AC_TRY_COMPILE([
+volatile int i = 0;
+],[
+i = 1;
+],[AC_MSG_RESULT(yes);AC_DEFINE(HAVE_VOLATILE)],[AC_MSG_RESULT(no)])
+
+dnl Data type sig_atomic_t
+AC_MSG_CHECKING(sig_atomic_t)
+AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <signal.h>
+],[
+sig_atomic_t sat;
+],[AC_MSG_RESULT(yes);AC_DEFINE(HAVE_SIG_ATOMIC_T)],[AC_MSG_RESULT(no)])
+
+dnl Data type sizes
+AC_CHECK_SIZEOF(short)
+AC_CHECK_SIZEOF(int)
+AC_CHECK_SIZEOF(size_t)
+AC_CHECK_SIZEOF(long)
+AC_CHECK_SIZEOF(long long)
+if [[ "X$DOINTMAXSIZECHECK" = "Xyes" ]]
+then
+AC_CHECK_SIZEOF(intmax_t)
+fi
+AC_CHECK_SIZEOF(double)
+AC_CHECK_SIZEOF(long double)
+AC_CHECK_SIZEOF(wchar_t)
+
+dnl Feature large file functions
+AC_MSG_CHECKING(_LARGEFILE64_SOURCE)
+FS64=''
+AC_TRY_COMPILE([
+#define _LARGEFILE64_SOURCE 1
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+],[struct stat64 st;],[FS64='-D_LARGEFILE64_SOURCE=1'
+AC_DEFINE(HAVE_LARGEFILE64_SOURCE)
+AC_DEFINE(HAVE_TYPE_STAT64)
+AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no)])
+
+dnl Check for functions
+AC_HAVE_FUNCS(memset bzero memcpy bcopy memcmp bcmp)
+AC_HAVE_FUNCS(malloc calloc free)
+AC_HAVE_FUNCS(strcpy_s strcat_s)
+AC_HAVE_FUNCS(strcasecmp stricmp _stricmp)
+AC_HAVE_FUNCS(wcslen wcscpy_s wcscpy wcscat_s wcscat wcschr wcsrchr)
+AC_HAVE_FUNCS(wcscmp _wcscmp wcscasecmp _wcscasecmp wcsicmp _wcsicmp)
+AC_HAVE_FUNCS(getpid readlink getexecname lstat stat64 lstat64 localtime_r)
+AC_HAVE_FUNCS(geteuid fopen64 fopen_s _wfopen _wfopen64 _wfopen_s)
+AC_HAVE_FUNCS(fputws fputwc)
+AC_HAVE_FUNCS(setbuffer setbuf setvbuf)
+AC_HAVE_FUNCS(fileno _fileno setmode _setmode isatty _isatty)
+AC_HAVE_FUNCS(strtod _strtod wcstod _wcstod)
+AC_HAVE_FUNCS(_snprintf_s _snprintf snprintf _snwprintf_s _snwprintf snwprintf)
+AC_HAVE_FUNCS(swprintf)
+AC_HAVE_FUNCS(unlink _unlink wunlink _wunlink)
+AC_HAVE_FUNCS(rmdir _rmdir wrmdir _wrmdir)
+AC_HAVE_FUNCS(mkdir _mkdir wmkdir _wmkdir)
+AC_HAVE_FUNCS(strerror strerror_r)
+AC_HAVE_FUNCS(sigaction sigset signal sigprocmask sigemptyset)
+AC_HAVE_FUNCS(setpwent getpwent endpwent)
+AC_HAVE_FUNCS(getenv getenv_s setlocale select)
+AC_HAVE_FUNCS(getcwd _getcwd _wgetcwd)
+AC_CHECK_LIB(crypto, SHA224_Init,AC_DEFINE(HAVE_SHA224))
+AC_CHECK_LIB(crypto, SHA256_Init,AC_DEFINE(HAVE_SHA256))
+AC_CHECK_LIB(crypto, SHA384_Init,AC_DEFINE(HAVE_SHA384))
+AC_CHECK_LIB(crypto, SHA512_Init,AC_DEFINE(HAVE_SHA512))
+
+AC_MSG_CHECKING(RAND_egd)
+AC_TRY_COMPILE([
+#include <openssl/rand.h>
+],[
+int i;
+i = RAND_egd("/dev/egd");
+],[AC_MSG_RESULT(yes);AC_DEFINE(HAVE_RAND_EGD)],[AC_MSG_RESULT(no)])
+
+AC_CHECK_LIB(rt,clock_gettime,[RTLIB="-lrt"])
+
+SOCKLIB=''
+NSLLIB=''
+
+dnl Function socket in standard library, -lxnet and -lsocket
+AC_CHECK_FUNCS(socket,[
+NET_PROG_RES='$(NET_PROG_RES)'
+NET_PROG_CLI='$(NET_PROG_CLI)'
+AC_DEFINE(HAVE_SOCKET)
+],[
+AC_CHECK_LIB(xnet,socket,[
+NET_PROG_RES='$(NET_PROG_RES)'
+NET_PROG_CLI='$(NET_PROG_CLI)'
+AC_DEFINE(HAVE_SOCKET)
+SOCKLIB='-lxnet'
+],[
+AC_CHECK_LIB(socket,socket,[
+NET_PROG_RES='$(NET_PROG_RES)'
+NET_PROG_CLI='$(NET_PROG_CLI)'
+AC_DEFINE(HAVE_SOCKET)
+SOCKLIB='-lsocket'
+],[
+AC_CHECK_LIB(ws2_32,socket,[
+NET_PROG_RES='$(NET_PROG_RES)'
+NET_PROG_CLI='$(NET_PROG_CLI)'
+AC_DEFINE(HAVE_SOCKET)
+SOCKLIB='-lws2_32'
+])
+])
+])
+])
+
+dnl Function setsockopt
+AC_CHECK_FUNCS(setsockopt,[
+AC_DEFINE(HAVE_SETSOCKOPT)
+],[
+AC_CHECK_LIB(xnet,setsockopt,[
+AC_DEFINE(HAVE_SETSOCKOPT)
+],[
+AC_CHECK_LIB(socket,setsockopt,[
+AC_DEFINE(HAVE_SETSOCKOPT)
+],[
+AC_CHECK_LIB(ws2_32,setsockopt,[
+AC_DEFINE(HAVE_SETSOCKOPT)
+])
+])
+])
+])
+
+dnl Function getaddrinfo
+AC_CHECK_FUNCS(getaddrinfo,[
+AC_DEFINE(HAVE_GETADDRINFO)
+],[
+AC_CHECK_LIB(xnet,getaddrinfo,[
+NSLLIB='-lxnet'
+AC_DEFINE(HAVE_GETADDRINFO)
+],[
+AC_CHECK_LIB(nsl,getaddrinfo,[
+NSLLIB='-lnsl'
+AC_DEFINE(HAVE_GETADDRINFO)
+],[
+AC_CHECK_LIB(socket,getaddrinfo,[
+NSLLIB='-lsocket'
+AC_DEFINE(HAVE_GETADDRINFO)
+],[
+AC_CHECK_LIB(ws2_32,getaddrinfo,[
+AC_DEFINE(HAVE_GETADDRINFO)
+])
+])
+])
+])
+])
+
+dnl Function getnameinfo (reverse getaddrinfo)
+AC_CHECK_FUNCS(getnameinfo,[
+AC_DEFINE(HAVE_GETNAMEINFO)
+],[
+AC_CHECK_LIB(xnet,getnameinfo,[
+AC_DEFINE(HAVE_GETNAMEINFO)
+],[
+AC_CHECK_LIB(nsl,getnameinfo,[
+AC_DEFINE(HAVE_GETNAMEINFO)
+],[
+AC_CHECK_LIB(socket,getnameinfo,[
+AC_DEFINE(HAVE_GETNAMEINFO)
+],[
+AC_CHECK_LIB(ws2_32,getnameinfo,[
+AC_DEFINE(HAVE_GETNAMEINFO)
+])
+])
+])
+])
+])
+
+dnl Function gethostbyname
+AC_CHECK_FUNCS(gethostbyname,[
+AC_DEFINE(HAVE_GETHOSTBYNAME)
+],[
+AC_CHECK_LIB(xnet,gethostbyname,[
+AC_DEFINE(HAVE_GETHOSTBYNAME)
+],[
+AC_CHECK_LIB(nsl,gethostbyname,[
+AC_DEFINE(HAVE_GETHOSTBYNAME)
+],[
+AC_CHECK_LIB(socket,gethostbyname,[
+AC_DEFINE(HAVE_GETHOSTBYNAME)
+],[
+AC_CHECK_LIB(ws3_32,gethostbyname,[
+AC_DEFINE(HAVE_GETHOSTBYNAME)
+])
+])
+])
+])
+])
+
+dnl Function or macro htons
+AC_MSG_CHECKING(htons)
+AC_TRY_COMPILE([
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+],[
+ unsigned short s;
+ s = htons(5);
+],[
+AC_DEFINE(HAVE_HTONS)
+AC_MSG_RESULT(yes)
+],[
+AC_MSG_RESULT(no)
+])
+
+dnl Function or macro ntohs
+AC_MSG_CHECKING(ntohs)
+AC_TRY_COMPILE([
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+],[
+ unsigned short s;
+ s = ntohs(5);
+],[
+AC_DEFINE(HAVE_NTOHS)
+AC_MSG_RESULT(yes)
+],[
+AC_MSG_RESULT(no)
+])
+
+dnl Function or macro htonl
+AC_MSG_CHECKING(htonl)
+AC_TRY_COMPILE([
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+],[
+ unsigned long s;
+ s = htonl(5);
+],[
+AC_DEFINE(HAVE_HTONL)
+AC_MSG_RESULT(yes)
+],[
+AC_MSG_RESULT(no)
+])
+
+dnl Function or macro ntohl
+AC_MSG_CHECKING(ntohl)
+AC_TRY_COMPILE([
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+],[
+ unsigned long s;
+ s = ntohl(5);
+],[
+AC_DEFINE(HAVE_NTOHL)
+AC_MSG_RESULT(yes)
+],[
+AC_MSG_RESULT(no)
+])
+
+dnl Function inet_addr
+AC_CHECK_FUNCS(inet_addr,[
+AC_DEFINE(HAVE_INET_ADDR)
+],[
+AC_CHECK_LIB(xnet,inet_addr,[
+AC_DEFINE(HAVE_INET_ADDR)
+],[
+AC_CHECK_LIB(nsl,inet_addr,[
+AC_DEFINE(HAVE_INET_ADDR)
+],[
+AC_CHECK_LIB(socket,inet_addr,[
+AC_DEFINE(HAVE_INET_ADDR)
+],[
+AC_CHECK_LIB(ws2_32,inet_addr,[
+AC_DEFINE(HAVE_INET_ADDR)
+])
+])
+])
+])
+])
+
+dnl Function inet_aton
+AC_CHECK_FUNCS(inet_aton,[
+AC_DEFINE(HAVE_INET_ATON)
+],[
+AC_CHECK_LIB(xnet,inet_aton,[
+AC_DEFINE(HAVE_INET_ATON)
+],[
+AC_CHECK_LIB(nsl,inet_aton,[
+AC_DEFINE(HAVE_INET_ATON)
+],[
+AC_CHECK_LIB(socket,inet_aton,[
+AC_DEFINE(HAVE_INET_ATON)
+],[
+AC_CHECK_LIB(ws2_32,inet_aton,[
+AC_DEFINE(HAVE_INET_ATON)
+])
+])
+])
+])
+])
+
+dnl Function inet_pton
+AC_CHECK_FUNCS(inet_pton,[
+AC_DEFINE(HAVE_INET_PTON)
+],[
+AC_CHECK_LIB(xnet,inet_pton,[
+AC_DEFINE(HAVE_INET_PTON)
+],[
+AC_CHECK_LIB(nsl,inet_pton,[
+AC_DEFINE(HAVE_INET_PTON)
+],[
+AC_CHECK_LIB(socket,inet_pton,[
+AC_DEFINE(HAVE_INET_PTON)
+],[
+AC_CHECK_LIB(ws2_32,inet_pton,[
+AC_DEFINE(HAVE_INET_PTON)
+])
+])
+])
+])
+])
+
+dnl Function inet_ntop (reverse inet_pton)
+AC_CHECK_FUNCS(inet_ntop,[
+AC_DEFINE(HAVE_INET_NTOP)
+],[
+AC_CHECK_LIB(xnet,inet_ntop,[
+AC_DEFINE(HAVE_INET_NTOP)
+],[
+AC_CHECK_LIB(nsl,inet_ntop,[
+AC_DEFINE(HAVE_INET_NTOP)
+],[
+AC_CHECK_LIB(socket,inet_ntop,[
+AC_DEFINE(HAVE_INET_NTOP)
+],[
+AC_CHECK_LIB(ws2_32,inet_ntop,[
+AC_DEFINE(HAVE_INET_NTOP)
+])
+])
+])
+])
+])
+
+if [[ "X$SOCKLIB" = "X$NSLLIB" ]]
+then
+NSLLIB=''
+fi
+
+dnl Feature Checking for /proc/.../exe symbolic link
+dnl http://stackoverflow.com/questions/1023306/finding-current-executables-path-without-proc-self-exe
+AC_MSG_CHECKING(/proc/.../exe symbolic link)
+AC_TRY_RUN([
+#include <stdio.h>
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+
+/* Buffer for result */
+char prog[1024];
+
+#ifdef __cplusplus
+int main(int argc, char *argv[])
+#else
+int main(argc, argv) int argc; char *argv[];
+#endif
+{
+ char buf[64];
+ struct stat stbuf;
+ int exv = 1;
+ ssize_t res;
+#if HAVE_STDINT_H
+ sprintf(buf, "/proc/%ju/exe", (uintmax_t)getpid());
+#else
+ sprintf(buf, "/proc/%lu/exe", (unsigned long)getpid());
+#endif
+ res = readlink(buf, prog, sizeof(prog));
+ if ((0 < res) && (sizeof(prog) > res)) {
+ prog[res] = '\0';
+ if (0 == stat(prog, &stbuf)) {
+ exv = 0;
+ }
+ }
+ return exv;
+}
+
+],[AC_MSG_RESULT(yes);AC_DEFINE(HAVE_PROC_PID_EXE)],[AC_MSG_RESULT(no)],[AC_MSG_RESULT([no - test not possible])])
+
+dnl Data type ssize_t
+AC_MSG_CHECKING(ssize_t)
+AC_TRY_COMPILE([
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+],[
+ ssize_t sz;
+],[
+AC_MSG_RESULT(yes)
+AC_DEFINE(HAVE_SSIZE_T)
+],[AC_MSG_RESULT(no)])
+
+AC_MSG_CHECKING(int8_t)
+AC_TRY_COMPILE([
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+],[
+int8_t i8 = 0;
+],[
+AC_MSG_RESULT(yes)
+AC_DEFINE(HAVE_INT8_T)
+],[AC_MSG_RESULT(no)])
+
+AC_MSG_CHECKING(int16_t)
+AC_TRY_COMPILE([
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+],[
+int16_t i16 = 0;
+],[
+AC_MSG_RESULT(yes)
+AC_DEFINE(HAVE_INT16_T)
+],[AC_MSG_RESULT(no)])
+
+AC_MSG_CHECKING(int32_t)
+AC_TRY_COMPILE([
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+],[
+int32_t i32 = 0;
+],[
+AC_MSG_RESULT(yes)
+AC_DEFINE(HAVE_INT32_T)
+],[AC_MSG_RESULT(no)])
+
+dnl Data type uint8_t
+AC_MSG_CHECKING(uint8_t)
+AC_TRY_COMPILE([
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+],[
+ uint8_t sz;
+],[
+AC_MSG_RESULT(yes)
+AC_DEFINE(HAVE_UINT8_T)
+],[AC_MSG_RESULT(no)])
+
+dnl Data type uint16_t
+AC_MSG_CHECKING(uint16_t)
+AC_TRY_COMPILE([
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+],[
+ uint16_t sz;
+],[
+AC_MSG_RESULT(yes)
+AC_DEFINE(HAVE_UINT16_T)
+],[AC_MSG_RESULT(no)])
+
+dnl Data type uint32_t
+AC_MSG_CHECKING(uint32_t)
+AC_TRY_COMPILE([
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+],[
+ uint32_t sz;
+],[
+AC_MSG_RESULT(yes)
+AC_DEFINE(HAVE_UINT32_T)
+],[AC_MSG_RESULT(no)])
+
+dnl Data types for file stat
+AC_MSG_CHECKING(dev_t)
+AC_TRY_COMPILE([
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+],[
+ dev_t devno;
+],[AC_MSG_RESULT(yes);AC_DEFINE(HAVE_DEV_T)],[AC_MSG_RESULT(no)])
+
+AC_MSG_CHECKING(_dev_t)
+AC_TRY_COMPILE([
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+],[
+ _dev_t devno;
+],[AC_MSG_RESULT(yes);AC_DEFINE(HAVE__DEV_T)],[AC_MSG_RESULT(no)])
+
+AC_MSG_CHECKING(ino_t)
+AC_TRY_COMPILE([
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+],[
+ ino_t devno;
+],[AC_MSG_RESULT(yes);AC_DEFINE(HAVE_INO_T)],[AC_MSG_RESULT(no)])
+
+AC_MSG_CHECKING(_ino_t)
+AC_TRY_COMPILE([
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+],[
+ _ino_t devno;
+],[AC_MSG_RESULT(yes);AC_DEFINE(HAVE__INO_T)],[AC_MSG_RESULT(no)])
+
+AC_MSG_CHECKING(ino64_t)
+AC_TRY_COMPILE([
+#define _LARGEFILE64_SOURCE 1
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+],[
+ ino64_t devno;
+],[AC_MSG_RESULT(yes);AC_DEFINE(HAVE_INO64_T)],[AC_MSG_RESULT(no)])
+
+AC_MSG_CHECKING(mode_t)
+AC_TRY_COMPILE([
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+],[
+ mode_t devno;
+],[AC_MSG_RESULT(yes);AC_DEFINE(HAVE_MODE_T)],[AC_MSG_RESULT(no)])
+
+AC_MSG_CHECKING(nlink_t)
+AC_TRY_COMPILE([
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+],[
+ nlink_t devno;
+],[AC_MSG_RESULT(yes);AC_DEFINE(HAVE_NLINK_T)],[AC_MSG_RESULT(no)])
+
+AC_MSG_CHECKING(uid_t)
+AC_TRY_COMPILE([
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+],[
+ uid_t devno;
+],[AC_MSG_RESULT(yes);AC_DEFINE(HAVE_UID_T)],[AC_MSG_RESULT(no)])
+
+AC_MSG_CHECKING(gid_t)
+AC_TRY_COMPILE([
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+],[
+ gid_t devno;
+],[AC_MSG_RESULT(yes);AC_DEFINE(HAVE_GID_T)],[AC_MSG_RESULT(no)])
+
+AC_MSG_CHECKING(off_t)
+AC_TRY_COMPILE([
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+],[
+ off_t devno;
+],[AC_MSG_RESULT(yes);AC_DEFINE(HAVE_OFF_T)],[AC_MSG_RESULT(no)])
+
+AC_MSG_CHECKING(off64_t)
+AC_TRY_COMPILE([
+#define _LARGEFILE64_SOURCE 1
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+],[
+ off64_t devno;
+],[AC_MSG_RESULT(yes);AC_DEFINE(HAVE_OFF64_T)],[AC_MSG_RESULT(no)])
+
+AC_MSG_CHECKING(blksize_t)
+AC_TRY_COMPILE([
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+],[
+ blksize_t devno;
+],[AC_MSG_RESULT(yes);AC_DEFINE(HAVE_BLKSIZE_T)],[AC_MSG_RESULT(no)])
+
+AC_MSG_CHECKING(blkcnt_t)
+AC_TRY_COMPILE([
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+],[
+ blkcnt_t devno;
+],[AC_MSG_RESULT(yes);AC_DEFINE(HAVE_BLKCNT_T)],[AC_MSG_RESULT(no)])
+
+AC_MSG_CHECKING(fpos_t)
+AC_TRY_COMPILE([
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+],[
+ fpos_t devno;
+],[AC_MSG_RESULT(yes);AC_DEFINE(HAVE_FPOS_T)],[AC_MSG_RESULT(no)])
+
+
+AC_MSG_CHECKING(blocksize and blockcount in stat output)
+AC_TRY_COMPILE([
+#define _LARGEFILE64_SOURCE 1
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+],[
+#if HAVE_TYPE_STAT64
+ struct stat64 stb;
+ stb.st_blksize = 0;
+ stb.st_blocks = 0;
+#else
+ struct stat stb;
+ stb.st_blksize = 0;
+ stb.st_blocks = 0;
+#endif
+],[AC_MSG_RESULT(yes)
+AC_DEFINE(HAVE_FILE_BLKSIZECNT)],[AC_MSG_RESULT(no)])
+
+
+AC_MSG_CHECKING(_fpos_t)
+AC_TRY_COMPILE([
+#include <stdio.h>
+#include <stdlib.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+],[
+ _fpos_t devno;
+],[AC_MSG_RESULT(yes);AC_DEFINE(HAVE__FPOS_T)],[AC_MSG_RESULT(no)])
+
+dnl Data type socklen_t
+AC_MSG_CHECKING(socklen_t)
+AC_TRY_COMPILE([
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+],[
+socklen_t sz;
+],[
+AC_MSG_RESULT(yes)
+AC_DEFINE(HAVE_SOCKLEN_T)
+],[
+AC_MSG_RESULT(no)
+])
+
+dnl Data type struct sockaddr_in
+AC_MSG_CHECKING(struct sockaddr_in)
+AC_TRY_COMPILE([
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+],[
+struct sockaddr_in sain;
+],[
+AC_MSG_RESULT(yes)
+AC_DEFINE(HAVE_STRUCT_SOCKADDR_IN)
+],[
+AC_MSG_RESULT(no)
+])
+
+dnl Data type struct sockaddr_in6
+AC_MSG_CHECKING(struct sockaddr_in6)
+AC_TRY_COMPILE([
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+],[
+struct sockaddr_in6 sain;
+],[
+AC_MSG_RESULT(yes)
+AC_DEFINE(HAVE_STRUCT_SOCKADDR_IN6)
+],[
+AC_MSG_RESULT(no)
+])
+
+dnl Data type struct sockaddr_un
+AC_MSG_CHECKING(struct sockaddr_un)
+AC_TRY_COMPILE([
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_SYS_UN_H
+#include <sys/un.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+],[
+struct sockaddr_un sain;
+],[
+AC_MSG_RESULT(yes)
+AC_DEFINE(HAVE_STRUCT_SOCKADDR_UN)
+],[
+AC_MSG_RESULT(no)
+])
+
+dnl Data type struct addrinfo
+AC_MSG_CHECKING(struct addrinfo)
+AC_TRY_COMPILE([
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+],[
+struct addrinfo adi;
+],[
+AC_MSG_RESULT(yes)
+AC_DEFINE(HAVE_STRUCT_ADDRINFO)
+],[
+AC_MSG_RESULT(no)
+])
+
+dnl Data type sockaddr_storage
+AC_MSG_CHECKING(struct sockaddr_storage)
+AC_TRY_COMPILE([
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+],[
+struct sockaddr_storage sain;
+],[
+AC_MSG_RESULT(yes)
+AC_DEFINE(HAVE_STRUCT_SOCKADDR_STORAGE)
+],[
+AC_MSG_RESULT(no)
+])
+
+dnl Typedef IN_ADDR
+AC_MSG_CHECKING(IN_ADDR)
+AC_TRY_COMPILE([
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
+#if HAVE_WS2TCPIP_H
+#include <ws2tcpip.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+],[
+IN_ADDR addr;
+],[
+AC_MSG_RESULT(yes)
+AC_DEFINE(HAVE_IN_ADDR)
+],[
+AC_MSG_RESULT(no)
+])
+
+dnl Typedef IN6_ADDR
+AC_MSG_CHECKING(IN6_ADDR)
+AC_TRY_COMPILE([
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
+#if HAVE_WS2TCPIP_H
+#include <ws2tcpip.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+],[
+IN6_ADDR addr;
+],[
+AC_MSG_RESULT(yes)
+AC_DEFINE(HAVE_IN6_ADDR)
+],[
+AC_MSG_RESULT(no)
+])
+
+dnl Functions rand and srand
+AC_MSG_CHECKING(rand srand)
+AC_TRY_COMPILE([
+#include <stdio.h>
+#include <stdlib.h>
+],[
+ srand(25);
+ printf("%d\n", rand());
+ printf("%d\n", RAND_MAX);
+],[AC_MSG_RESULT(yes)
+AC_DEFINE(HAVE_RAND)
+AC_DEFINE(HAVE_SRAND)],[AC_MSG_RESULT(no)])
+
+AC_MSG_CHECKING(initstate setstate random)
+AC_TRY_COMPILE([
+#include <stdio.h>
+#include <stdlib.h>
+],[
+char rs[256];
+initstate(25, rs, sizeof(rs));
+setstate(rs);
+printf("%ld\n", random());
+],[
+AC_MSG_RESULT(yes)
+AC_DEFINE(HAVE_INITSTATE)
+AC_DEFINE(HAVE_SETSTATE)
+AC_DEFINE(HAVE_RANDOM)
+],[AC_MSG_RESULT(no)])
+
+dnl Functions lrand48 nrand48 seed48
+AC_MSG_CHECKING(lrand48 nrand48 seed48)
+AC_TRY_COMPILE([
+#include <stdio.h>
+#include <stdlib.h>
+],[
+unsigned short sv[3];
+sv[0] = 0;
+sv[1] = 1;
+sv[2] = 2;
+seed48(sv);
+printf("%ld\n", lrand48());
+printf("%ld\n", nrand48(sv));
+],[
+AC_MSG_RESULT(yes)
+AC_DEFINE(HAVE_LRAND48)
+AC_DEFINE(HAVE_NRAND48)
+],[AC_MSG_RESULT(no)])
+
+dnl Size of some types
+AC_CHECK_SIZEOF(off_t)
+AC_CHECK_SIZEOF(off64_t)
+AC_CHECK_SIZEOF(ino_t)
+AC_CHECK_SIZEOF(ino64_t)
+
+dnl Check whether to use fallback numeric limits
+dnl Not handled by configure script. Set manually if needed.
+dnl AC_ARG_WITH(fallback-limits,[ --with-fallback-limits Allow use of fallback limits (no)],[AC_DEFINE(USE_FALLBACK_NUMERIC_LIMITS)])
+AC_ARG_WITH(fallback-limits,[AS_HELP_STRING([--with-fallback-limits],[Allow use of fallback limits (no / yes)])],[AC_DEFINE(USE_FALLBACK_NUMERIC_LIMITS)])
+
+dnl Check whether we are allowed to use printf and scanf
+dnl Not handled by configure script. Set manually if needed.
+dnl AC_ARG_WITH(printf-scanf,[ --with-printf-scanf Allow use of printf and scanf (yes)],[CAN_USE_PRINTF_SCANF="$withval"])
+AC_ARG_WITH(printf-scanf,[AS_HELP_STRING([--with-printf-scanf],[Allow use of printf and scanf (yes / no)])],[CAN_USE_PRINTF_SCANF="$withval"])
+
+if [[ "X$CAN_USE_PRINTF_SCANF" != "Xno" ]]
+then
+ AC_DEFINE(USE_PRINTF_SCANF)
+fi
+
+dnl Defaults differung between POSIX and Windows
+AC_DEFINE(HAVE_FILE_DEVINO)
+AC_DEFINE(HAVE_FILE_UIDGID)
+AC_DEFINE(HAVE_FILE_ATIMECTIME)
+
+dnl As long as software from DK tools 3 and 4 coexist, allow
+dnl backward compatibility in DK tools 4.
+AC_DEFINE(HAVE_COMPATDKTOOLS3)
+
+dnl Find names of test programs
+SEP=`cat sep.txt`
+for i in test*.ctr
+do
+j=`echo $i | sed -e 's/\.ctr//g'`
+if [[ "X$TESTPROGRAMS" = "X" ]]
+then
+ TESTPROGRAMS="$j"
+else
+ TESTPROGRAMS="${TESTPROGRAMS} ${SEP}$j"
+fi
+done
+
+if [[ "X$SUITE" = "Xgui" ]]
+then
+ AC_DEFINE(HAVE_WXWIDGETS)
+else
+ WXCPPFLAGS=''
+ WXCXXFLAGS=''
+ WXCFLAGS=''
+ WXLDFLAGS=''
+fi
+
+WXMAJOR=''
+WXMINOR=''
+
+if [[ "X$WXVERSION" != "X" ]]
+then
+ WXMAJOR=`echo $WXVERSION | cut -f 1 -d .`
+ WXMINOR=`echo $WXVERSION | cut -f 2 -d .`
+fi
+[[ "X$WXMAJOR" != "X" ]] || WXMAJOR="0"
+
+if [[ "$WXMAJOR" -ge 3 ]]
+then
+AC_DEFINE(HAVE_WX_CHARTYPE_H)
+elif [[ "$WXMAJOR" -ge 2 ]]
+then
+AC_DEFINE(HAVE_WX_WXCHAR_H)
+fi
+
+dnl BACKWARD COMPATIBILITY SECTION (VERSION 3) START
+LIBPNG=''
+LIBJPEG=''
+LIBTIFF=''
+ANYDB=''
+SNMPPROG=''
+MYSQLPROG=''
+PTHREADLIB=''
+LIBDK3WXOBJ=''
+LIBDK4WXOBJ=''
+LIBDK4WXTOBUILD=''
+DBLIB=''
+DBLIBSOCK=''
+NETSNMP_LIBS=''
+NETSNMP_CFLAGS=''
+NETSNMP_LIBS=`net-snmp-config --libs`
+NETSNMP_CFLAGS=`net-snmp-config --cflags`
+AC_HEADER_CHECK(stdio.h, AC_DEFINE(HAVE_STDIO_H))
+AC_HEADER_CHECK(conio.h, AC_DEFINE(HAVE_CONIO_H))
+AC_HEADER_CHECK(grp.h, AC_DEFINE(HAVE_GRP_H))
+AC_HEADER_CHECK(gdbm.h, [FOUND_GDBM='yes'])
+AC_HEADER_CHECK(ndbm.h, [FOUND_NDBM='yes'])
+case "X${FOUND_NDBM}${USE_NDBM}${FOUND_GDBM}" in
+ "Xyesyesyes")
+ AC_DEFINE(HAVE_NDBM_H)
+ ANYDB='ndbm'
+ ;;
+ "Xyesyesno")
+ AC_DEFINE(HAVE_NDBM_H)
+ ANYDB='ndbm'
+ ;;
+ "Xyesautono")
+ AC_DEFINE(HAVE_NDBM_H)
+ ANYDB='ndbm'
+ ;;
+esac
+if [[ "X$ANYDB" != "Xndbm" -a "X$FOUND_GDBM" = "Xyes" ]]
+then
+ AC_DEFINE(HAVE_GDBM_H)
+fi
+AC_HEADER_CHECK(db.h, [FOUND_BDB='yes';ANYDB='db';DBLIB="-ldb";AC_DEFINE(HAVE_DB_H)])
+AC_HEADER_CHECK(dir.h, AC_DEFINE(HAVE_DIR_H))
+AC_HEADER_CHECK(err.h, AC_DEFINE(HAVE_ERR_H))
+AC_HEADER_CHECK(shadow.h, AC_DEFINE(HAVE_SHADOW_H))
+AC_HEADER_CHECK(stropts.h, AC_DEFINE(HAVE_STROPTS_H))
+AC_HEADER_CHECK(syslog.h, AC_DEFINE(HAVE_SYSLOG_H))
+AC_HEADER_CHECK(sysres.h, AC_DEFINE(HAVE_SYSRES_H))
+AC_HEADER_CHECK(termios.h, AC_DEFINE(HAVE_TERMIOS_H))
+AC_HEADER_CHECK(vararg.h, AC_DEFINE(HAVE_VARARG_H))
+AC_HEADER_CHECK(varargs.h, AC_DEFINE(HAVE_VARARGS_H))
+AC_HEADER_CHECK(ntifs.h, AC_DEFINE(HAVE_NTIFS_H))
+AC_HEADER_CHECK(sys/file.h, AC_DEFINE(HAVE_SYS_FILE_H))
+AC_HEADER_CHECK(sys/resource.h, AC_DEFINE(HAVE_SYS_RESOURCE_H))
+AC_HEADER_CHECK(sys/statvfs.h, AC_DEFINE(HAVE_SYS_STATVFS_H))
+AC_HEADER_CHECK(sys/stropts.h, AC_DEFINE(HAVE_SYS_STROPTS_H))
+AC_HEADER_CHECK(sys/sunddi.h, AC_DEFINE(HAVE_SYS_SUNDDI_H))
+AC_HEADER_CHECK(sys/sysctl.h, AC_DEFINE(HAVE_SYS_SYSCTL_H))
+AC_HEADER_CHECK(sys/systeminfo.h, AC_DEFINE(HAVE_SYS_SYSTEMINFO_H))
+AC_HEADER_CHECK(sys/termios.h, AC_DEFINE(HAVE_SYS_TERMIOS_H))
+AC_HEADER_CHECK(sys/ttold.h, AC_DEFINE(HAVE_SYS_TTOLD_H))
+AC_HEADER_CHECK(sys/uio.h, AC_DEFINE(HAVE_SYS_UIO_H))
+AC_HEADER_CHECK(sys/wait.h,AC_DEFINE(HAVE_SYS_WAIT_H))
+
+AC_HEADER_CHECK(winbase.h,[AC_DEFINE(HAVE_WINBASE_H)],[],[
+#if HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+])
+AC_HEADER_CHECK(winreg.h,[AC_DEFINE(HAVE_WINREG_H)],[],[
+#if HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+#if HAVE_WINBASE_H
+#include <winbase.h>
+#endif
+])
+AC_HEADER_CHECK(wincon.h,[AC_DEFINE(HAVE_WINCON_H)],[],[
+#if HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+#if HAVE_WINBASE_H
+#include <winbase.h>
+#endif
+])
+AC_HEADER_CHECK(png.h, [LIBPNG="-lpng";AC_DEFINE(HAVE_PNG_H)])
+AC_HEADER_CHECK(jpeglib.h, [LIBJPEG="-ljpeg";AC_DEFINE(HAVE_JPEGLIB_H)])
+AC_HEADER_CHECK(tiff.h, [LIBTIFF="-ltiff";AC_DEFINE(HAVE_TIFF_H)])
+AC_HEADER_CHECK(mysql/mysql.h, [
+MYSQLPROG='mysqlprog'
+MYSQLLIB='-lmysqlclient'
+AC_DEFINE(HAVE_MYSQL_MYSQL_H)
+],[
+AC_HEADER_CHECK(mysql.h, [
+MYSQLPROG='mysqlprog'
+MYSQLLIB='-lmysqlclient'
+AC_DEFINE(HAVE_MYSQL_H)
+]
+)
+]
+)
+AC_HEADER_CHECK(lprng.h, AC_DEFINE(HAVE_LPRNG_H))
+AC_HEADER_CHECK(pthread.h, [PTHREADLIB='-lpthread';AC_DEFINE(HAVE_PTHREAD_H)])
+AC_CHECK_LIB(m,acosh,AC_DEFINE(HAVE_ACOSH))
+AC_CHECK_LIB(m,acoshl,AC_DEFINE(HAVE_ACOSHL))
+AC_CHECK_LIB(m,acosl,AC_DEFINE(HAVE_ACOSL))
+AC_CHECK_LIB(m,asinh,AC_DEFINE(HAVE_ASINH))
+AC_CHECK_LIB(m,asinhl,AC_DEFINE(HAVE_ASINHL))
+AC_CHECK_LIB(m,asinl,AC_DEFINE(HAVE_ASINL))
+AC_CHECK_LIB(m,atan2,AC_DEFINE(HAVE_ATAN2))
+AC_CHECK_LIB(m,atan2l,AC_DEFINE(HAVE_ATAN2L))
+AC_CHECK_LIB(m,atanh,AC_DEFINE(HAVE_ATANH))
+AC_CHECK_LIB(m,atanhl,AC_DEFINE(HAVE_ATANHL))
+AC_CHECK_LIB(m,atanl,AC_DEFINE(HAVE_ATANL))
+AC_CHECK_LIB(m,ceil,AC_DEFINE(HAVE_CEIL))
+AC_CHECK_LIB(m,ceill,AC_DEFINE(HAVE_CEILL))
+AC_CHECK_LIB(m,coshl,AC_DEFINE(HAVE_COSHL))
+AC_CHECK_LIB(m,cosl,AC_DEFINE(HAVE_COSL))
+AC_CHECK_LIB(m,expl,AC_DEFINE(HAVE_EXPL))
+AC_CHECK_LIB(m,fabs,AC_DEFINE(HAVE_FABS))
+AC_CHECK_LIB(m,fabsl,AC_DEFINE(HAVE_FABSL))
+AC_CHECK_LIB(m,floor,AC_DEFINE(HAVE_FLOOR))
+AC_CHECK_LIB(m,floorl,AC_DEFINE(HAVE_FLOORL))
+AC_CHECK_LIB(m,labs,AC_DEFINE(HAVE_LABS))
+AC_CHECK_LIB(m,logl,AC_DEFINE(HAVE_LOGL))
+AC_CHECK_LIB(m,rint,AC_DEFINE(HAVE_RINT))
+AC_CHECK_LIB(m,rintl,AC_DEFINE(HAVE_RINTL))
+AC_CHECK_LIB(m,sinhl,AC_DEFINE(HAVE_SINHL))
+AC_CHECK_LIB(m,sqrt,AC_DEFINE(HAVE_SQRT))
+AC_CHECK_LIB(m,sqrtl,AC_DEFINE(HAVE_SQRTL))
+AC_CHECK_LIB(m,sinl,AC_DEFINE(HAVE_SINL))
+AC_CHECK_LIB(m,tanhl,AC_DEFINE(HAVE_TANHL))
+AC_CHECK_LIB(m,tanl,AC_DEFINE(HAVE_TANL))
+AC_CHECK_LIB(png, png_get_pixels_per_inch,AC_DEFINE(HAVE_PNG_GET_PIXELS_PER_INCH))
+AC_HAVE_FUNCS(getuid setuid setgid)
+AC_HAVE_FUNCS(chdir chmod chown)
+AC_HAVE_FUNCS(opendir readdir closedir)
+AC_HAVE_FUNCS(getgrent getgrgid getgrnam endgrent setgrent)
+AC_HAVE_FUNCS(getpwuid getpwnam)
+AC_HAVE_FUNCS(fopen fclose feof ferror fflush fread fwrite)
+AC_HAVE_FUNCS(_fclose _feof _ferror _fflush _fopen _fread _fwrite)
+AC_HAVE_FUNCS(_getenv_s _wgetenv _getpid)
+AC_HAVE_FUNCS(fetestexcept _clearfp)
+AC_HAVE_FUNCS(fork getrlimit setpgrp setsid syslog)
+AC_HAVE_FUNCS(gethostname)
+AC_HAVE_FUNCS(time localtime localtime_s)
+AC_HAVE_FUNCS(stat stat32 lstat32)
+AC_HAVE_FUNCS(_stat _stat32 _stat64 _lstat _lstat32 _lstat64)
+AC_HAVE_FUNCS(mpctl sysconf sysctl)
+AC_HAVE_FUNCS(popen _popen)
+AC_HAVE_FUNCS(read write _read _write)
+AC_HAVE_FUNCS(seed48)
+AC_HAVE_FUNCS(sprintf_s sscanf_s swscanf_s)
+AC_HAVE_FUNCS(strcat strchr strcmp strcpy strdup strlen strncmp strncpy _strdup)
+AC_HAVE_FUNCS(strncpy_s strrchr strtoimax strtol strtoll strtoul strtoull)
+AC_HAVE_FUNCS(strtoumax)
+AC_HAVE_FUNCS(wcsdup wcsncmp wcsncpy wcsncpy_s wcstoimax wcstol wcstoll)
+AC_HAVE_FUNCS(wcstoul wcstoull wcstoumax)
+AC_HAVE_FUNCS(_wcscat _wcschr _wcscpy _wcsdup _wcslen _wcsncmp _wcsncpy)
+AC_HAVE_FUNCS(_wcsrchr)
+AC_HAVE_FUNCS(tcflush tcgetattr)
+AC_HAVE_FUNCS(umask)
+AC_HAVE_FUNCS(GetFinalPathNameByHandle)
+
+dnl wchar_t data type
+AC_MSG_CHECKING(wchar_t)
+AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <wchar.h>
+],[
+ wchar_t chr;
+],[AC_MSG_RESULT(yes);AC_DEFINE(HAVE_WCHAR_T)],[AC_MSG_RESULT(no)])
+
+dnl mkdir with 2 arguments
+AC_MSG_CHECKING(mkdir path mode)
+AC_TRY_COMPILE([
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+],[
+mkdir("test", 0755);
+],[AC_MSG_RESULT(yes);AC_DEFINE(HAVE_MKDIR2)],[AC_MSG_RESULT(no)])
+
+dnl HAVE_DB_CURSOR_C_GET
+AC_TRY_COMPILE([
+#include <db.h>
+],[
+DBT k;
+DBT v;
+DBC *cp;
+cp->c_get(cp, &k, &v, DB_FIRST);
+],[AC_DEFINE(HAVE_DB_CURSOR_C_GET)])
+
+dnl const
+AC_MSG_CHECKING(const)
+AC_TRY_COMPILE([
+#include <stdio.h>
+static char const msg[] = { "Test" };
+],[
+fputs(msg, stdout);
+],[AC_MSG_RESULT(yes);AC_DEFINE(HAVE_CONST)],[AC_MSG_RESULT(no)])
+
+dnl inline
+AC_MSG_CHECKING(inline)
+AC_TRY_COMPILE([
+#include <stdio.h>
+
+inline
+int
+summe(int a, int b)
+{
+ return (a + b);
+}
+
+],[
+int i = 5;
+int j = 6;
+int k;
+
+k = summe(i, j);
+],[AC_MSG_RESULT(yes);FOUNDINLINE="yes"],[AC_MSG_RESULT(no)])
+
+if [[ "X$FOUNDINLINE" = "Xyes" -a "X$USEINLINE" = "Xyes" ]]
+then
+ AC_DEFINE(HAVE_INLINE)
+fi
+
+dnl /dev/random and /dev/urandom
+if test -b /dev/urandom
+then
+ AC_DEFINE(HAVE_DEV_URANDOM)
+fi
+if test -c /dev/urandom
+then
+ AC_DEFINE(HAVE_DEV_URANDOM)
+fi
+if test -b /dev/random
+then
+ AC_DEFINE(HAVE_DEV_RANDOM)
+fi
+if test -c /dev/random
+then
+ AC_DEFINE(HAVE_DEV_RANDOM)
+fi
+
+dnl fpclassify
+AC_MSG_CHECKING(fpclassify)
+AC_TRY_COMPILE([
+#include <stdio.h>
+#if HAVE_MATH_H
+#include <math.h>
+#endif
+],[
+int cl;
+cl = fpclassify(-0.5);
+],[AC_MSG_RESULT(yes);AC_DEFINE(HAVE_FPCLASSIFY)],[AC_MSG_RESULT(no)])
+
+dnl Function getpeername
+AC_CHECK_FUNCS(getpeername,[
+AC_DEFINE(HAVE_GETPEERNAME)
+],[
+AC_CHECK_LIB(xnet,getpeername,[
+AC_DEFINE(HAVE_GETPEERNAME)
+],[
+AC_CHECK_LIB(nsl,getpeername,[
+AC_DEFINE(HAVE_GETPEERNAME)
+],[
+AC_CHECK_LIB(socket,getpeername,[
+AC_DEFINE(HAVE_GETPEERNAME)
+])
+])
+])
+])
+
+dnl Function getsockname
+AC_CHECK_FUNCS(getsockname,[
+AC_DEFINE(HAVE_GETSOCKNAME)
+],[
+AC_CHECK_LIB(xnet,getsockname,[
+AC_DEFINE(HAVE_GETSOCKNAME)
+],[
+AC_CHECK_LIB(nsl,getsockname,[
+AC_DEFINE(HAVE_GETSOCKNAME)
+],[
+AC_CHECK_LIB(socket,getsockname,[
+AC_DEFINE(HAVE_GETSOCKNAME)
+])
+])
+])
+])
+
+
+
+
+dnl NetSNMP library
+AC_TRY_COMPILE([
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/utilities.h>
+],[
+netsnmp_session session, *ss;
+],[
+SNMPPROG="snmpprog"
+SNMP_PROG_CLI='$(SNMP_PROG_CLI)'
+AC_DEFINE(HAVE_LIBNETSNMP)
+])
+AC_CHECK_LIB(netsnmp,snmp_enable_filelog,[SNMPPROG="snmpprog";AC_DEFINE(HAVE_SNMP_ENABLE_FILELOG)])
+AC_CHECK_LIB(netsnmp,snmp_disable_syslog,[AC_DEFINE(HAVE_SNMP_DISABLE_SYSLOG)])
+AC_CHECK_LIB(netsnmp,snmp_disable_stderrlog,[AC_DEFINE(HAVE_SNMP_DISABLE_STDERRLOG)])
+AC_CHECK_LIB(netsnmp,snmp_disable_filelog,[AC_DEFINE(HAVE_SNMP_DISABLE_FILELOG)])
+dnl IEEE 754 double
+IEEE_754_DOUBLE_WISHED='yes'
+IEEE_754_DOUBLE_FOUND='no'
+AC_MSG_CHECKING(IEEE 754 double)
+AC_TRY_RUN([
+#include <stdio.h>
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_STRING_H
+#include <string.h>
+#endif
+#if HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#include <math.h>
+
+static double td[] = {
+ INFINITY,
+ 1234.75,
+ 4.0,
+ 1.0,
+ 0.375,
+ 0.0,
+ -0.625,
+ -1.0,
+ -8.0,
+ -23.875,
+ -INFINITY
+};
+
+#if WORDS_BIGENDIAN
+static unsigned char tuc[] = {
+ /* INF */ 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* 1234.75 */ 0x40, 0x93, 0x4B, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* 4.0 */ 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* 1.0 */ 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* 0.375 */ 0x3F, 0xD8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* 0.0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* -0.625 */ 0xBF, 0xE4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* -1.0 */ 0xBF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* -8.0 */ 0xC0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* -23.875 */ 0xC0, 0x37, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* -INF */ 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+#else
+static unsigned char tuc[] = {
+ /* INF */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x7F,
+ /* 1234.75 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x4B, 0x93, 0x40,
+ /* 4.0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40,
+ /* 1.0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F,
+ /* 0.375 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x3F,
+ /* 0.0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* -0.625 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE4, 0xBF,
+ /* -1.0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xBF,
+ /* -8.0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xC0,
+ /* -23.875 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x37, 0xC0,
+ /* -INF */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF
+};
+#endif
+
+static
+#ifdef __cplusplus
+int
+test_double(double *dp, unsigned char *up)
+#else
+int
+test_double(dp, up)
+ double *dp;
+ unsigned char *up;
+#endif
+{
+ int back = 0;
+#if HAVE_MEMCMP
+ if(memcmp(dp, up, 8) == 0) {
+ back = 1;
+ }
+#else
+#if HAVE_BCMP
+ if(bcmp(dp, up, 8) == 0) {
+ back = 1;
+ }
+#else
+ unsigned char *cp1;
+ unsigned char *cp2;
+ size_t i;
+ back = 1;
+ cp1 = (unsigned char *)dp; cp2 = up;
+ for(i = 0; i < 8; i++) {
+ if(*(cp1++) != *(cp2++)) {
+ back = 0;
+ }
+ }
+#endif
+#endif
+ if(1 != back) {
+ printf("ERROR: %lg not conforming to IEEE 754!\n", *dp);
+ }
+ return back;
+}
+
+#ifdef __cplusplus
+int main(int argc, char *argv[])
+#else
+int main(argc, argv)
+ int argc;
+ char *argv[];
+#endif
+{
+ unsigned char *ucp;
+ double *dp;
+ size_t i;
+ int ev = 1;
+
+ if(8 == sizeof(double)) {
+ ev = 0;
+ ucp = tuc; dp = td;
+ for(i = 0; i < (sizeof(td)/sizeof(double)); i++) {
+ if(!test_double(dp, ucp)) {
+ ev = 1;
+ }
+ dp++;
+ ucp += 8;
+ }
+ } else {
+ printf("ERROR: Size of double is not 1!\n");
+ }
+ exit(ev);
+}
+
+],[AC_MSG_RESULT(yes);IEEE_754_DOUBLE_FOUND="yes"],[AC_MSG_RESULT(no);IEEE_754_DOUBLE_FOUND="no"],[AC_MSG_RESULT([no - test not possible])])
+if [[ "X$IEEE_754_DOUBLE_FOUND$IEEE_754_DOUBLE_WISHED" = "Xyesyes" ]]
+then
+ AC_DEFINE(HAVE_IEEE_754_DOUBLE)
+else
+ IEEE_754_DOUBLE_FOUND='no'
+fi
+
+dnl isfinite isnormal
+AC_MSG_CHECKING(isfinite)
+AC_TRY_COMPILE([
+#include <stdio.h>
+#if HAVE_MATH_H
+#include <math.h>
+#endif
+],[
+ double x;
+ int a = 0;
+ x = 5.0;
+ if (isfinite(x)) {
+ a = 1;
+ }
+],[AC_MSG_RESULT(yes);AC_DEFINE(HAVE_ISFINITE)],[AC_MSG_RESULT(no)])
+AC_MSG_CHECKING(isnormal)
+AC_TRY_COMPILE([
+#include <stdio.h>
+#if HAVE_MATH_H
+#include <math.h>
+#endif
+],[
+ double x;
+ int a = 0;
+ x = 5.0;
+ if (isnormal(x)) {
+ a = 1;
+ }
+],[AC_MSG_RESULT(yes);AC_DEFINE(HAVE_ISNORMAL)],[AC_MSG_RESULT(no)])
+
+
+dnl Twos complement for negative integers
+AC_MSG_CHECKING(use of twos complement for negative integers)
+AC_TRY_RUN([
+#include <stdio.h>
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_PROCESS_H
+#include <process.h>
+#endif
+
+int i1 = -1;
+
+#if SIZEOF_INT > 2
+#if SIZEOF_INT > 4
+#if SIZEOF_INT > 8
+#error "No test available yet for integers larger than 8 bytes!"
+#else
+int i2 = 0xFFFFFFFFFFFFFFFF;
+#endif
+#else
+int i2 = 0xFFFFFFFF;
+#endif
+#else
+int i2 = 0xFFFF;
+#endif
+
+int main(int argc, char *argv[])
+{
+ int exval = 1;
+ if (i1 == i2) exval = 0;
+ exit(exval); return exval;
+}
+],[AC_MSG_RESULT(yes);AC_DEFINE(HAVE_TWOS_COMPLEMENT)],[AC_MSG_RESULT(no)],[AC_MSG_RESULT([no - test not possible])])
+
+CLI_SNMPPROG=''
+if [[ "X$SNMPPROG" != "X" ]]
+then
+ CLI_SNMPPROG='pjsnmp$(EXEEXT)'
+fi
+
+
+dnl Check for MySQL client library
+CLI_MYSQLPROG=''
+if [[ "X$MYSQLPROG" != "X" ]]
+then
+ CLI_MYSQLPROG='itadmin$(EXEEXT)'
+ MYSQL_PROG_CLI='$(MYSQL_PROG_CLI)'
+ [[ ! -f /usr/lib/mysql/libmysqlclient.so ]] || LDFLAGS="$LDFLAGS -L/usr/lib/mysql"
+ [[ ! -f /usr/lib/mysql/libmysqlclient.a ]] || LDFLAGS="$LDFLAGS -L/usr/lib/mysql"
+ [[ ! -f /usr/lib/mysql/libmysqlclient.so ]] || MYSQLLDFLAGS="-L/usr/lib/mysql"
+ [[ ! -f /usr/lib/mysql/libmysqlclient.a ]] || MYSQLLDFLAGS="-L/usr/lib/mysql"
+ [[ ! -f /usr/lib64/mysql/libmysqlclient.so ]] || LDFLAGS="$LDFLAGS -L/usr/lib64/mysql"
+ [[ ! -f /usr/lib64/mysql/libmysqlclient.a ]] || LDFLAGS="$LDFLAGS -L/usr/lib64/mysql"
+ [[ ! -f /usr/lib64/mysql/libmysqlclient.so ]] || MYSQLLDFLAGS="-L/usr/lib64/mysql"
+ [[ ! -f /usr/lib64/mysql/libmysqlclient.a ]] || MYSQLLDFLAGS="-L/usr/lib64/mysql"
+fi
+
+if [[ "X$SUITE" = "Xgui" ]]
+then
+ LIBDK3WXOBJ='$(LIBDK3WXOBJ)'
+ LIBDK4WXOBJ='$(LIBDK4WXOBJ)'
+ LIBDK4WXTOBUILD='libdk4wx.$(LIBEXT)'
+fi
+
+
+if [[ "X$ENASHARED" = "Xyes" -a "X$USESOLINKING" = "Xyes" ]]
+then
+ SOLIBZ="$ZLIB"
+ SOLIBBZ="$BZLIB"
+ SOLIBMATH="-lm"
+ SOLIBCRYPTO="$CRYPTO"
+ SOLIBNET="$NETLIB"
+ SOLIBIMG="$IMGLIBS"
+ SOLIBSDBI="$DKSDBILIBS"
+ SOLIBWX=`wx-config --libs`
+ SOLIBDK3PORT=""
+ SOLIBDK3C="-ldk3c"
+ SOLIBDK3OF="-ldk3of"
+ SOLIBDK3CSRND="-ldk3csrnd"
+ SOLIBDK3BIF="-ldk3bif"
+ SOLIBDK3DBI="-ldk3dbi"
+ SOLIBDK3FIG="-ldk3fig"
+ SOLIBDK3BMEPS="-ldk3bmeps"
+ SOLIBDK3NET="-ldk3net"
+ SOLIBDK4BASE="-ldk4base"
+ SOLIBDK4MA="-ldk4ma"
+ SOLIBDK4MAIO8H="-ldk4maio8h"
+ SOLIBDK4MAIOWH="-ldk4maiowh"
+ SOLIBDK4MAIODH="-ldk4maiodh"
+ SOLIBDK4MAIO8D="-ldk4maio8d"
+ SOLIBDK4MAIOWD="-ldk4maiowd"
+ SOLIBDK4MAIODD="-ldk4maiodd"
+ SOLIBDK4C="-ldk4c"
+ SOLIBDK4MDRND="-ldk4mdrnd"
+ SOLIBDK4PPPT="-ldk4pppt"
+ SOLIBDK4APP="-ldk4app"
+ SOLIBDK4LAT="-ldk4lat"
+ SOLIBDK4SOCK="-ldk4sock"
+ SOLIBDK4SOCKA="-ldk4socka"
+ SOLIBDK4DBI="-ldk4dbi"
+ SOLIBDK4DBIA="-ldk4dbia"
+ LIBDK4MALIBF="libdk4base.so"
+ LIBDK4MALIBS='-ldk4base'
+ LIBDK4MAIO8DLIBF="libdk4base.so libdk4ma.so"
+ LIBDK4MAIO8DLIBS='-ldk4ma -ldk4base'
+ LIBDK4MAIOWDLIBF="libdk4base.so libdk4ma.so"
+ LIBDK4MAIOWDLIBS='-ldk4ma -ldk4base'
+ LIBDK4MAIODDLIBF="libdk4base.so libdk4maio8d.so"
+ LIBDK4MAIODDLIBS='-ldk4maio8d -ldk4base'
+ LIBDK4MAIOXDLIBF="libdk4base.so libdk4maio8d.so libdk4maiowd.so"
+ LIBDK4MAIOXDLIBS='-ldk4maiowd -ldk4maio8d -ldk4base'
+ LIBDK4MAIO8HLIBF="libdk4base.so"
+ LIBDK4MAIO8HLIBS='-ldk4base'
+ LIBDK4MAIOWHLIBF="libdk4base.so"
+ LIBDK4MAIOWHLIBS='-ldk4base'
+ LIBDK4MAIODHLIBF="libdk4base.so libdk4maio8h.so"
+ LIBDK4MAIODHLIBS='-ldk4maio8h -ldk4base'
+ LIBDK4CLIBF="libdk4base.so libdk4ma.so libdk4maio8d.so libdk4maiodd.so"
+ LIBDK4CLIBS='-ldk4maiodd -ldk4maio8d -ldk4ma -ldk4base $(BZLIB) $(ZLIB) -lm'
+ LIBDK4DBILIBF="libdk4base.so libdk4ma.so libdk4c.so"
+ LIBDK4DBILIBS='-ldk4c -ldk4ma -ldk4base $(DBLIB)'
+ LIBDK4SOCKLIBF="libdk4base.so libdk4maio8d.so libdk4c.so"
+ LIBDK4SOCKLIBS='-ldk4c -ldk4maio8d -ldk4base $(SOCKLIB) $(NSLLIB)'
+ LIBDK4MDRNDLIBF="libdk4base.so libdk4c.so"
+ LIBDK4MDRNDLIBS='-ldk4c -ldk4base $(CRYPTO)'
+ LIBDK4PPPTLIBF="libdk4base.so libdk4maiodd.so libdk4c.so"
+ LIBDK4PPPTLIBS='-ldk4c -ldk4maiodd -ldk4base'
+ LIBDK4APPLIBF="libdk4base.so libdk4ma.so libdk4maio8d.so libdk4maiodd.so libdk4c.so"
+ LIBDK4APPLIBS='-ldk4c -ldk4maiodd -ldk4maio8d -ldk4ma -ldk4base'
+ LIBDK4LATLIBF="libdk4base.so libdk4ma.so libdk4maio8h.so libdk4maiodh.so libdk4maiodd.so libdk4c.so libdk4app.so"
+ LIBDK4LATLIBS='-ldk4app -ldk4c -ldk4maiodd -ldk4maiodh -ldk4maio8h -ldk4ma -ldk4base'
+ LIBDK4PPPTALIBF="libdk4base.so libdk4c.so libdk4pppt.so libdk4app.so"
+ LIBDK4PPPTALIBS='-ldk4app -ldk4pppt -ldk4c -ldk4base'
+ LIBDK4SOCKALIBF="libdk4base.so libdk4maio8h.so libdk4maio8d.so libdk4maiodh.so libdk4maiodd.so libdk4sock.so libdk4app.so"
+ LIBDK4SOCKALIBS='-ldk4app -ldk4sock -ldk4maiodd -ldk4maiodh -ldk4maio8d -ldk4maio8h -ldk4base $(SOCKLIB) $(NSLLIB)'
+ LIBDK4DBIALIBF="libdk4base.so libdk4dbi.so libdk4app.so"
+ LIBDK4DBIALIBS='-ldk4dbi -ldk4app -ldk4base $(DBLIB)'
+ LIBDK4WXLIBF="libdk4base.so libdk4maio8d.so libdk4maiowd.so libdk4c.so libdk4app.so"
+ LIBDK4WXLIBS='-ldk4app -ldk4c -ldk4maiowd -ldk4maio8d -ldk4base $(WXLDFLAGS)'
+ LIBDK3TRACELIBF=""
+ LIBDK3TRACELIBS=''
+ LIBDK3CLIBF=""
+ LIBDK3CLIBS='$(BZLIB) $(ZLIB) -lm'
+ LIBDK3OFLIBF="libdk3c.so"
+ LIBDK3OFLIBS='-ldk3c $(BZLIB) $(ZLIB)'
+ LIBDK3CSRNDLIBF="libdk3c.so"
+ LIBDK3CSRNDLIBS='-ldk3c $(CRYPTO)'
+ LIBDK3BIFLIBF="libdk3c.so"
+ LIBDK3BIFLIBS='-ldk3c $(IMGLIBS)'
+ LIBDK3DBILIBF="libdk3c.so"
+ LIBDK3DBILIBS='-ldk3c $(DBLIB)'
+ LIBDK3BMEPSLIBF="libdk3c.so libdk3of.so libdk3bif.so"
+ LIBDK3BMEPSLIBS='-ldk3bif -ldk3of -ldk3c -lm'
+ LIBDK3FIGLIBF="libdk3c.so"
+ LIBDK3FIGLIBS='-ldk3c -lm'
+ LIBDK3WXLIBF="libdk3c.so"
+ LIBDK3WXLIBS='-ldk3c $(WXLDFLAGS)'
+fi
+if [[ "X$ENASHARED" = "Xyes" -a "X$USESOLINKING" = "Xyes" -a "X$CROSSCOMPLING" = "Xyes" ]]
+then
+ LIBDK4MAIODDLIBF="$LIBDK4MAIODDLIBF libdk4maiowd.so"
+ LIBDK4MAIODDLIBS='-ldk4maiowd $LIBDK4MAIODDLIBS'
+ LIBDK4MAIODHLIBF="$LIBDK4MAIODHLIBF libdk4maiowh.so"
+ LIBDK4MAIODHLIBS='-ldk4maiowh $LIBDK4MAIODHLIBS'
+fi
+
+case "X$ENAPACKAGING/X$USESOLINKING" in
+ "Xyes/Xyes")
+ DKCTLIBF='libdk3c.so'
+ DKCTLIBS='-ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ ADDCTRLDLIBF='libdk3c.so'
+ ADDCTRLDLIBS='-ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKDBTLIBF='libdk3c.so libdk3dbi.so'
+ DKDBTLIBS='-ldk3dbi -ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ ITADMINLIBF='libdk3c.so libdk3of.so'
+ ITADMINLIBS='-ldk3of -ldk3c -lmysqlclient $(CLILIB) $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB)'
+ BMPPLIBF='libdk3c.so libdk3bif.so libdk3of.so libdk3bmeps.so'
+ BMPPLIBS='-ldk3bmeps -ldk3of -ldk3bif -ldk3c $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB) -lm'
+ FIG2LATLIBF='libdk3c.so libdk3bif.so libdk3of.so libdk3bmeps.so libdk3fig.so'
+ FIG2LATLIBS='-ldk3fig -ldk3bmeps -ldk3of -ldk3bif -ldk3c $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB) -lm'
+ HTMLBOOKLIBF='libdk3c.so libdk3bif.so libdk3of.so libdk3bmeps.so'
+ HTMLBOOKLIBS='-ldk3bmeps -ldk3of -ldk3bif -ldk3c $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+ DK3INFOLIBF='libdk3c.so'
+ DK3INFOLIBS='-ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ PLPDFTEXLIBF='libdk3c.so libdk3bif.so libdk3of.so libdk3bmeps.so'
+ PLPDFTEXLIBS='-ldk3bmeps -ldk3of -ldk3bif -ldk3c $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB) -lm'
+ DKWXWIZLIBF='libdk3c.so'
+ DKWXWIZLIBS='-ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ WXDKCTLIBF='libdk3c.so libdk3wx.so'
+ WXDKCTLIBS='-ldk3wx -ldk3c $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+ WXBMPPLIBF='libdk3c.so libdk3bif.so libdk3of.so libdk3bmeps.so libdk3wx.so'
+ WXBMPPLIBS='-ldk3wx -ldk3bmeps -ldk3of -ldk3bif -ldk3c $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+ WXIMGSZLIBF='libdk3c.so libdk3wx.so'
+ WXIMGSZLIBS='-ldk3wx -ldk3c $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+ WXDKCLOCKLIBF='libdk3c.so libdk3wx.so'
+ WXDKCLOCKLIBS='-ldk3wx -ldk3c $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+ WXDKHTBLIBF='libdk3c.so libdk3wx.so'
+ WXDKHTBLIBS='-ldk3wx -ldk3c $(WXLDFLAGS) $(GUILIB) $(CLILIB) $(BZLIB) $(ZLIB)'
+ PRINTQDILIBF='libdk3c.so libdk3dbi.so'
+ PRINTQDILIBS='-ldk3dbi -ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ PRINTQDALIBF='libdk3c.so'
+ PRINTQDALIBS='-ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKCATLIBF='libdk4base.so libdk4c.so libdk4maiodd.so libdk4app.so'
+ DKCATLIBS='-ldk4app -ldk4maiodd -ldk4maio8d -ldk4c -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKBLKSLIBF='libdk4base.so libdk4c.so libdk4app.so'
+ DKBLKSLIBS='-ldk4app -ldk4c -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKSQLSPLITLIBF='libdk4base.so libdk4c.so libdk4app.so'
+ DKSQLSPLITLIBS='-ldk4app -ldk4c -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKERADISKLIBF='libdk4base.so libdk4c.so libdk4app.so'
+ DKERADISKLIBS='-ldk4app -ldk4c -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKLSLIBF='libdk4base.so libdk4c.so libdk4app.so libdk4mdrnd.so'
+ DKLSLIBS='-ldk4app -ldk4maiodd -ldk4maiodh -ldk4ma -ldk4mdrnd -ldk4c -ldk4base $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKSORTLIBF='libdk4base.so libdk4maiodd.so libdk4maiodh.so libdk4c.so libdk4app.so'
+ DKSORTLIBS='-ldk4app -ldk4c -ldk4maiodh -ldk4maiodd -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKFICLIBF='libdk4base.so libdk4ma.so libdk4maiodd.so libdk4c.so libdk4app.so libdk4mdrnd.so'
+ DKFICLIBS='-ldk4app -ldk4mdrnd -ldk4c -ldk4maiodd -ldk4ma -ldk4base $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKUIDLIBF='libdk4base.so libdk4ma.so libdk4maiodd.so libdk4c.so libdk4app.so'
+ DKUIDLIBS='-ldk4app -ldk4c -ldk4maiodd -ldk4ma -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKPWGENLIBF='libdk4base.so libdk4ma.so libdk4maiodd.so libdk4c.so libdk4app.so libdk4mdrnd.so'
+ DKPWGENLIBS='-ldk4app -ldk4mdrnd -ldk4c -ldk4maiodd -ldk4ma -ldk4base $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKRANDLIBF='libdk4base.so libdk4c.so libdk4app.so libdk4mdrnd.so'
+ DKRANDLIBS='-ldk4app -ldk4mdrnd -ldk4c -ldk4base $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKT2HLIBF='libdk4base.so libdk4maio8d.so libdk4maio8h.so libdk4maiodd.so libdk4c.so libdk4app.so'
+ DKT2HLIBS='-ldk4app -ldk4c -ldk4maiodd -ldk4maio8h -ldk4maio8d -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKT2LLIBF='libdk4base.so libdk4maiodd.so libdk4maiodh.so libdk4c.so libdk4app.so libdk4lat.so'
+ DKT2LLIBS='-ldk4lat -ldk4app -ldk4c -ldk4maiodh -ldk4maiodd -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKHEXLIBF='libdk4base.so libdk4c.so libdk4app.so libdk4maiodh.so'
+ DKHEXLIBS='-ldk4app -ldk4maiodh -ldk4c -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKBMMLIBF='libdk4base.so libdk4maio8d.so libdk4maiodd.so libdk4c.so libdk4app.so'
+ DKBMMLIBS='-ldk4app -ldk4c -ldk4maiodd -ldk4maio8d -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKPWDLIBF='libdk4base.so libdk4c.so libdk4app.so'
+ DKPWDLIBS='-ldk4app -ldk4c -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKRECVLIBF='libdk4base.so libdk4c.so libdk4sock.so libdk4app.so libdk4socka.so libdk4maiodd.so'
+ DKRECVLIBS='-ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4base $(CLILIB) $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) -lm'
+ DKSENDLIBF='libdk4base.so libdk4c.so libdk4sock.so libdk4app.so libdk4socka.so libdk4maiodd.so'
+ DKSENDLIBS='-ldk4maiodd -ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4base $(CLILIB) $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) -lm'
+ DKDBT2LIBF='libdk4base.so libdk4ma.so libdk4maiodd.so libdk4c.so libdk4dbi.so libdk4app.so libdk4dbia.so'
+ DKDBT2LIBS='-ldk4dbia -ldk4app -ldk4dbi -ldk4c -ldk4maiodd -ldk4ma -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DK4INFOLIBF='libdk4base.so libdk4maiodd.so libdk4c.so libdk4app.so'
+ DK4INFOLIBS='-ldk4app -ldk4c -ldk4maiodd -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ LPRNGCLLIBF='libdk4base.so libdk4c.so libdk4sock.so libdk4mdrnd.so libdk4app.so libdk4socka.so'
+ LPRNGCLLIBS='-ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4base $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) -lm'
+ WXDKFCSLIBF='libdk4base.so libdk4c.so libdk4mdrnd.so libdk4sock.so libdk4app.so libdk4socka.so libdk4wx.so'
+ WXDKFCSLIBS='-ldk4wx -ldk4socka -ldk4app -ldk4sock -ldk4mdrnd -ldk4c -ldk4base $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+ WXPQDICLIBF='libdk4base.so libdk4ma.so libdk4maio8d.so libdk4maiowd.so libdk4c.so libdk4sock.so libdk4app.so libdk4socka.so libdk4wx.so'
+ WXPQDICLIBS='-ldk4wx -ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4maiowd -ldk4maio8d -ldk4ma -ldk4base $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+ PJSNMPLIBF='libdk4base.so libdk4maio8h.so libdk4maio8d.so libdk4ma.so libdk4c.so libdk4sock.so libdk4app.so libdk4socka.so'
+ PJSNMPLIBS='-ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4ma -ldk4maio8d -ldk4maio8h -ldk4base $(NETSNMP_LIBS) $(SOCKLIB) $(NSLLIB)'
+ PRMONSNMPLIBF='libdk4base.so libdk4maio8h.so libdk4maio8d.so libdk4c.so libdk4sock.so libdk4app.so libdk4socka.so'
+ PRMONSNMPLIBS='-ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4maio8h -ldk4maio8d -ldk4base $(NETSNMP_LIBS) $(SOCKLIB) $(NSLLIB)'
+ PRINTQDLIBF='libdk4base.so libdk4maio8d.so libdk4c.so libdk4dbi.so libdk4sock.so'
+ PRINTQDLIBS='-ldk4sock -ldk4dbi -ldk4c -ldk4maio8d -ldk4base $(SOCKLIB) $(NSLLIB)'
+ PRINTQDCLIBF='libdk4base.so libdk4maio8d.so libdk4c.so libdk4sock.so libdk4app.so libdk4socka.so'
+ PRINTQDCLIBS='-ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4maio8d -ldk4base $(SOCKLIB) $(NSLLIB)'
+ RSHDOWNLIBF='libdk4base.so libdk4maio8d.so libdk4c.so libdk4sock.so'
+ RSHDOWNLIBS='-ldk4sock -ldk4c -ldk4maio8d -ldk4base $(SOCKLIB) $(NSLLIB)'
+ ;;
+ "Yyes/Xno")
+ DKCTLIBF='libdk3c.so'
+ DKCTLIBS='-ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ ADDCTRLDLIBF='libdk3c.so'
+ ADDCTRLDLIBS='-ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKDBTLIBF='libdk3c.so libdk3dbi.so'
+ DKDBTLIBS='-ldk3dbi -ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ ITADMINLIBF='libdk3c.so libdk3of.so'
+ ITADMINLIBS='-ldk3of -ldk3c -lmysqlclient $(CLILIB) $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB)'
+ BMPPLIBF='libdk3c.so libdk3bif.so libdk3of.so libdk3bmeps.so'
+ BMPPLIBS='-ldk3bmeps -ldk3of -ldk3bif -ldk3c $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB) -lm'
+ FIG2LATLIBF='libdk3c.so libdk3bif.so libdk3of.so libdk3bmeps.so libdk3fig.so'
+ FIG2LATLIBS='-ldk3fig -ldk3bmeps -ldk3of -ldk3bif -ldk3c $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB) -lm'
+ HTMLBOOKLIBF='libdk3c.so libdk3bif.so libdk3of.so libdk3bmeps.so'
+ HTMLBOOKLIBS='-ldk3bmeps -ldk3of -ldk3bif -ldk3c $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+ DK3INFOLIBF='libdk3c.so'
+ DK3INFOLIBS='-ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ PLPDFTEXLIBF='libdk3c.so libdk3bif.so libdk3of.so libdk3bmeps.so'
+ PLPDFTEXLIBS='-ldk3bmeps -ldk3of -ldk3bif -ldk3c $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB) -lm'
+ DKWXWIZLIBF='libdk3c.so'
+ DKWXWIZLIBS='-ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ WXDKCTLIBF='libdk3c.so libdk3wx.so'
+ WXDKCTLIBS='-ldk3wx -ldk3c $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+ WXBMPPLIBF='libdk3c.so libdk3bif.so libdk3of.so libdk3bmeps.so libdk3wx.so'
+ WXBMPPLIBS='-ldk3wx -ldk3bmeps -ldk3of -ldk3bif -ldk3c $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+ WXIMGSZLIBF='libdk3c.so libdk3wx.so'
+ WXIMGSZLIBS='-ldk3wx -ldk3c $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+ WXDKCLOCKLIBF='libdk3c.so libdk3wx.so'
+ WXDKCLOCKLIBS='-ldk3wx -ldk3c $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+ WXDKHTBLIBF='libdk3c.so libdk3wx.so'
+ WXDKHTBLIBS='-ldk3wx -ldk3c $(WXLDFLAGS) $(GUILIB) $(CLILIB) $(BZLIB) $(ZLIB)'
+ PRINTQDILIBF='libdk3c.so libdk3dbi.so'
+ PRINTQDILIBS='-ldk3dbi -ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ PRINTQDALIBF='libdk3c.so'
+ PRINTQDALIBS='-ldk3c $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKCATLIBF='libdk4base.so libdk4c.so libdk4app.so'
+ DKCATLIBS='-ldk4app -ldk4c -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKBLKSLIBF='libdk4base.so libdk4c.so libdk4app.so'
+ DKBLKSLIBS='-ldk4app -ldk4c -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKSQLSPLITLIBF='libdk4base.so libdk4c.so libdk4app.so'
+ DKSQLSPLITLIBS='-ldk4app -ldk4c -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKERADISKLIBF='libdk4base.so libdk4c.so'
+ DKERADISKLIBS='-ldk4c -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKLSLIBF='libdk4base.so libdk4c.so libdk4app.so libdk4mdrnd.so'
+ DKLSLIBS='-ldk4app -ldk4mdrnd -ldk4c -ldk4base $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKSORTLIBF='libdk4base.so libdk4maiodd.so libdk4maiodh.so libdk4c.so libdk4app.so'
+ DKSORTLIBS='-ldk4app -ldk4c -ldk4maiodh -ldk4maiodd -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKFICLIBF='libdk4base.so libdk4ma.so libdk4maiodd.so libdk4c.so libdk4app.so libdk4mdrnd.so'
+ DKFICLIBS='-ldk4app -ldk4mdrnd -ldk4c -ldk4maiodd -ldk4ma -ldk4base $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKUIDLIBF='libdk4base.so libdk4ma.so libdk4maiodd.so libdk4c.so libdk4app.so'
+ DKUIDLIBS='-ldk4app -ldk4c -ldk4maiodd -ldk4ma -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKPWGENLIBF='libdk4base.so libdk4ma.so libdk4maiodd.so libdk4c.so libdk4app.so libdk4mdrnd.so'
+ DKPWGENLIBS='-ldk4app -ldk4mdrnd -ldk4c -ldk4maiodd -ldk4ma -ldk4base $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKRANDLIBF='libdk4base.so libdk4c.so libdk4app.so libdk4mdrnd.so'
+ DKRANDLIBS='-ldk4app -ldk4mdrnd -ldk4c -ldk4base $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKT2HLIBF='libdk4base.so libdk4maio8d.so libdk4maio8h.so libdk4maiodd.so libdk4c.so libdk4app.so'
+ DKT2HLIBS='-ldk4app -ldk4c -ldk4maiodd -ldk4maio8h -ldk4maio8d -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKT2LLIBF='libdk4base.so libdk4maiodd.so libdk4maiodh.so libdk4c.so libdk4app.so libdk4lat.so'
+ DKT2LLIBS='-ldk4lat -ldk4app -ldk4c -ldk4maiodh -ldk4maiodd -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKHEXLIBF='libdk4base.so libdk4c.so libdk4app.so'
+ DKHEXLIBS='-ldk4app -ldk4c -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKBMMLIBF='libdk4base.so libdk4maio8d.so libdk4maiodd.so libdk4c.so libdk4app.so'
+ DKBMMLIBS='-ldk4app -ldk4c -ldk4maiodd -ldk4maio8d -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKPWDLIBF='libdk4base.so libdk4c.so libdk4app.so'
+ DKPWDLIBS='-ldk4app -ldk4c -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ DKRECVLIBF='libdk4base.so libdk4c.so libdk4sock.so libdk4app.so libdk4socka.so'
+ DKRECVLIBS='-ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4base $(CLILIB) $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) -lm'
+ DKSENDLIBF='libdk4base.so libdk4c.so libdk4sock.so libdk4app.so libdk4socka.so libdk4maiodd.so'
+ DKSENDLIBS='-ldk4maiodd -ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4base $(CLILIB) $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) -lm'
+ DKDBT2LIBF='libdk4base.so libdk4ma.so libdk4maiodd.so libdk4c.so libdk4dbi.so libdk4app.so libdk4dbia.so'
+ DKDBT2LIBS='-ldk4dbia -ldk4app -ldk4dbi -ldk4c -ldk4maiodd -ldk4ma -ldk4base $(DBLIBSOCK) $(CLILIB) $(BZLIB) $(ZLIB)'
+ DK4INFOLIBF='libdk4base.so libdk4maiodd.so libdk4c.so libdk4app.so'
+ DK4INFOLIBS='-ldk4app -ldk4c -ldk4maiodd -ldk4base $(CLILIB) $(BZLIB) $(ZLIB)'
+ LPRNGCLLIBF='libdk4base.so libdk4c.so libdk4sock.so libdk4mdrnd.so libdk4app.so libdk4socka.so'
+ LPRNGCLLIBS='-ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4base $(SOCKLIB) $(NSLLIB) $(BZLIB) $(ZLIB) -lm'
+ WXDKFCSLIBF='libdk4base.so libdk4c.so libdk4mdrnd.so libdk4sock.so libdk4app.so libdk4socka.so libdk4wx.so'
+ WXDKFCSLIBS='-ldk4wx -ldk4socka -ldk4app -ldk4sock -ldk4mdrnd -ldk4c -ldk4base $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CRYPTO) $(CLILIB) $(BZLIB) $(ZLIB)'
+ WXPQDICLIBF='libdk4base.so libdk4ma.so libdk4maio8d.so libdk4maiowd.so libdk4c.so libdk4sock.so libdk4app.so libdk4socka.so libdk4wx.so'
+ WXPQDICLIBS='-ldk4wx -ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4maiowd -ldk4maio8d -ldk4ma -ldk4base $(WXLDFLAGS) $(GUILIB) $(IMGLIBS) $(CLILIB) $(BZLIB) $(ZLIB)'
+ PJSNMPLIBF='libdk4base.so libdk4maio8h.so libdk4maio8d.so libdk4ma.so libdk4c.so libdk4sock.so libdk4app.so libdk4socka.so'
+ PJSNMPLIBS='-ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4ma -ldk4maio8d -ldk4maio8h -ldk4base $(NETSNMP_LIBS) $(SOCKLIB) $(NSLLIB)'
+ PRMONSNMPLIBF='libdk4base.so libdk4maio8d.so libdk4maio8h.so libdk4c.so libdk4sock.so libdk4app.so libdk4socka.so'
+ PRMONSNMPLIBS='-ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4maio8h -ldk4maio8d -ldk4base $(NETSNMP_LIBS) $(SOCKLIB) $(NSLLIB)'
+ PRINTQDLIBF='libdk4base.so libdk4maio8d.so libdk4c.so libdk4dbi.so libdk4sock.so'
+ PRINTQDLIBS='-ldk4sock -ldk4dbi -ldk4c -ldk4maio8d -ldk4base $(DBLIB) $(SOCKLIB) $(NSLLIB)'
+ PRINTQDCLIBF='libdk4base.so libdk4maio8d.so libdk4c.so libdk4sock.so libdk4app.so libdk4socka.so'
+ PRINTQDCLIBS='-ldk4socka -ldk4app -ldk4sock -ldk4c -ldk4maio8d -ldk4base $(SOCKLIB) $(NSLLIB)'
+ RSHDOWNLIBF='libdk4base.so libdk4maio8d.so libdk4c.so libdk4sock.so'
+ RSHDOWNLIBS='-ldk4sock -ldk4c -ldk4maio8d -ldk4base $(SOCKLIB) $(NSLLIB)'
+ ;;
+esac
+
+if [[ "X$WGET" != "X" ]]
+then
+ GETSOURCE='wget -O dktools-$(VERSNO) $(SFBASE)/dktools-$(VERSNO).tar.gz/download'
+elif [[ "X$CURL" != "X" ]]
+then
+ GETSOURCE='curl -L $(SFBASE)/dktools-$(VERSNO).tar.gz > dktools-$(VERSNO).tar.gz'
+fi
+
+dnl Corrections for Solaris and --with-corrections
+if [[ "X$UNAME" = "XSunOS" -a "X$SOLCOR" = "Xyes" ]]
+then
+ AC_MSG_CHECKING(CFLAGS on Solaris)
+ NETSNMP_LIBS=`echo $NETSNMP_LIBS | sed -f modsnmp.sed`
+ dnl WXCPPFLAGS
+ TMPVAR="$WXCPPFLAGS"
+ WXCPPFLAGS=''
+ for i in NOTHING $TMPVAR
+ do
+ case "X$i" in
+ "X-D*")
+ WXCPPFLAGS="$WXCPPFLAGS $i"
+ ;;
+ "X-I*")
+ WXCPPFLAGS="$WXCPPFLAGS $i"
+ ;;
+ esac
+ done
+ dnl WXCXXFLAGS
+ TMPVAR="$WXCXXFLAGS"
+ WXCXXFLAGS=''
+ for i in NOTHING $TMPVAR
+ do
+ case "X$i" in
+ "X-D*")
+ WXCXXFLAGS="$WXCXXFLAGS $i"
+ ;;
+ "X-I*")
+ WXCXXFLAGS="$WXCXXFLAGS $i"
+ ;;
+ "X-pthread")
+ WXCXXFLAGS="$WXCXXFLAGS $i"
+ ;;
+ esac
+ done
+ dnl WXCFLAGS
+ TMPVAR="$WXCFLAGS"
+ WXCFLAGS=''
+ for i in NOTHING $TMPVAR
+ do
+ case "X$i" in
+ "X-D*")
+ WXCFLAGS="$WXCFLAGS $i"
+ ;;
+ "X-I*")
+ WXCFLAGS="$WXCFLAGS $i"
+ ;;
+ "X-pthread")
+ WXCFLAGS="$WXCFLAGS $i"
+ ;;
+ esac
+ done
+ dnl WXLDFLAGS
+ TMPVAR="$WXLDFLAGS"
+ WXLDFLAGS=''
+ for i in NOTHING $TMPVAR
+ do
+ case "X$i" in
+ "X-L*")
+ WXLDFLAGS="$WXLDFLAGS $i"
+ ;;
+ "X-l*")
+ WXLDFLAGS="$WXLDFLAGS $i"
+ ;;
+ "X-pthread")
+ WXLDFLAGS="$WXLDFLAGS $i"
+ ;;
+ esac
+ done
+ SOCKLIB='-lsocket'
+ NSLLIB='-lnsl'
+ AC_MSG_RESULT(done)
+fi
+
+if [[ "X$ONWINDOWS" != "Xno" ]]
+then
+ CLILIB='$(WINCLILIB)'
+ GUILIB='$(WINGUILIB)'
+ ENTRY='$(WINENTRY)'
+else
+ AC_DEFINE(HAVE_INODES)
+fi
+
+AC_MSG_CHECKING(manpage installation)
+case "X$MANINST" in
+ "Xauto")
+ if uname -a | grep -q Debian
+ then
+ MANINST='no'
+ else
+ MANINST='yes'
+ fi
+ ;;
+esac
+if [[ "X$MANINST" = "Xno" ]]
+then
+ INSTALLMANPAGES=''
+fi
+AC_MSG_RESULT($MANINST)
+
+DBLIBSOCK="$DBLIB"
+
+if [[ "X$UNAME" = "XSunOS" -a "X$SOLCOR" = "Xyes" ]]
+then
+ [[ "X$DBLIBSOCK" = "X" ]] || DBLIBSOCK="$DBLIBSOCK -lrt "'$(SOCKLIB)'
+ [[ "X$DBLIB" = "X" ]] || DBLIB="$DBLIB -lrt "
+ [[ "X$CRYPTO" = "X" ]] || CRYPTO="$CRYPTO -lssl "'$(SOCKLIB)'
+ [[ "X$MYSQLLIB" = "X" ]] || MYSQLLIB="$MYSQLLIB -lrt "'$(SOCKLIB)'
+fi
+
+LIBSPRIVATE="$CRYPTO $MYSQLLIB $DBLIB $LIBTIFF $LIBJPEG $BZLIB"
+AC_SUBST(ANYDB)
+AC_SUBST(CLI_SNMPPROG)
+AC_SUBST(LIBPNG)
+AC_SUBST(LIBJPEG)
+AC_SUBST(LIBTIFF)
+AC_SUBST(DBLIB)
+AC_SUBST(DBLIBSOCK)
+AC_SUBST(CLI_MYSQLPROG)
+AC_SUBST(PTHREADLIB)
+AC_SUBST(LIBDK3WXOBJ)
+AC_SUBST(LIBDK4WXOBJ)
+AC_SUBST(LIBDK4WXTOBUILD)
+AC_SUBST(DKCTLIBF)
+AC_SUBST(DKCTLIBS)
+AC_SUBST(ADDCTRLDLIBF)
+AC_SUBST(ADDCTRLDLIBS)
+AC_SUBST(DKDBTLIBF)
+AC_SUBST(DKDBTLIBS)
+AC_SUBST(BMPPLIBF)
+AC_SUBST(BMPPLIBS)
+AC_SUBST(FIG2LATLIBF)
+AC_SUBST(FIG2LATLIBS)
+AC_SUBST(HTMLBOOKLIBF)
+AC_SUBST(HTMLBOOKLIBS)
+AC_SUBST(DK3INFOLIBF)
+AC_SUBST(DK3INFOLIBS)
+AC_SUBST(PLPDFTEXLIBF)
+AC_SUBST(PLPDFTEXLIBS)
+AC_SUBST(DKWXWIZLIBF)
+AC_SUBST(DKWXWIZLIBS)
+AC_SUBST(WXDKCTLIBF)
+AC_SUBST(WXDKCTLIBS)
+AC_SUBST(WXBMPPLIBF)
+AC_SUBST(WXBMPPLIBS)
+AC_SUBST(WXPQDICLIBF)
+AC_SUBST(WXPQDICLIBS)
+AC_SUBST(WXIMGSZLIBF)
+AC_SUBST(WXIMGSZLIBS)
+AC_SUBST(WXDKCLOCKLIBF)
+AC_SUBST(WXDKCLOCKLIBS)
+AC_SUBST(WXDKHTBLIBF)
+AC_SUBST(WXDKHTBLIBS)
+AC_SUBST(PRINTQDLIBF)
+AC_SUBST(PRINTQDLIBS)
+AC_SUBST(PRINTQDILIBF)
+AC_SUBST(PRINTQDILIBS)
+AC_SUBST(PRINTQDALIBF)
+AC_SUBST(PRINTQDALIBS)
+AC_SUBST(PJSNMPLIBF)
+AC_SUBST(PJSNMPLIBS)
+AC_SUBST(PRMONSNMPLIBF)
+AC_SUBST(PRMONSNMPLIBS)
+AC_SUBST(PRINTQDCLIBF)
+AC_SUBST(PRINTQDCLIBS)
+AC_SUBST(RSHDOWNLIBF)
+AC_SUBST(RSHDOWNLIBS)
+AC_SUBST(LPRNGCLLIBF)
+AC_SUBST(LPRNGCLLIBS)
+AC_SUBST(ITADMINLIBF)
+AC_SUBST(ITADMINLIBS)
+dnl BACKWARD COMPATIBILITY SECTION (VERSION 3) END
+
+
+dnl Transfer variables to output files
+AC_SUBST(CC)
+AC_SUBST(CPP)
+AC_SUBST(CXX)
+AC_SUBST(DEFS)
+AC_SUBST(CPPFLAGS)
+AC_SUBST(CXXFLAGS)
+AC_SUBST(CFLAGS)
+AC_SUBST(LDFLAGS)
+AC_SUBST(LIBS)
+AC_SUBST(FS64)
+AC_SUBST(ZLIB)
+AC_SUBST(BZLIB)
+AC_SUBST(RANLIB)
+AC_SUBST(CFPIC)
+AC_SUBST(PROGRAMS)
+AC_SUBST(LIBRARIES)
+AC_SUBST(LIBS_STATIC)
+AC_SUBST(LIBS_SHARED)
+AC_SUBST(LIBS_INSTALL)
+AC_SUBST(RES_INSTALL)
+AC_SUBST(MKSOLIB)
+AC_SUBST(RPATH)
+AC_SUBST(RPATHLINK)
+AC_SUBST(UNAME)
+AC_SUBST(SHLIBSTYLE)
+AC_SUBST(VERSNO)
+AC_SUBST(SOVERS)
+AC_SUBST(CWARN)
+AC_SUBST(CRYPTO)
+AC_SUBST(DKCATLIBF)
+AC_SUBST(DKCATLIBS)
+AC_SUBST(DKBLKSLIBF)
+AC_SUBST(DKBLKSLIBS)
+AC_SUBST(DKSQLSPLITLIBF)
+AC_SUBST(DKSQLSPLITLIBS)
+AC_SUBST(DKERADISKLIBF)
+AC_SUBST(DKERADISKLIBS)
+AC_SUBST(DKLSLIBF)
+AC_SUBST(DKLSLIBS)
+AC_SUBST(DKSORTLIBF)
+AC_SUBST(DKSORTLIBS)
+AC_SUBST(DKFICLIBF)
+AC_SUBST(DKFICLIBS)
+AC_SUBST(DKUIDLIBF)
+AC_SUBST(DKUIDLIBS)
+AC_SUBST(DKPWGENLIBF)
+AC_SUBST(DKPWGENLIBS)
+AC_SUBST(DKRANDLIBF)
+AC_SUBST(DKRANDLIBS)
+AC_SUBST(DKT2HLIBF)
+AC_SUBST(DKT2HLIBS)
+AC_SUBST(DKT2LLIBF)
+AC_SUBST(DKT2LLIBS)
+AC_SUBST(DKHEXLIBF)
+AC_SUBST(DKHEXLIBS)
+AC_SUBST(DKBMMLIBF)
+AC_SUBST(DKBMMLIBS)
+AC_SUBST(DKPWDLIBF)
+AC_SUBST(DKPWDLIBS)
+AC_SUBST(DKRECVLIBF)
+AC_SUBST(DKRECVLIBS)
+AC_SUBST(DKSENDLIBF)
+AC_SUBST(DKSENDLIBS)
+AC_SUBST(DKDBT2LIBF)
+AC_SUBST(DKDBT2LIBS)
+AC_SUBST(DK4INFOLIBS)
+AC_SUBST(DK4INFOLIBF)
+AC_SUBST(PROGSOPENSSL)
+AC_SUBST(SOCKLIB)
+AC_SUBST(NSLLIB)
+AC_SUBST(LIB_SH_RES)
+AC_SUBST(LIB_SH_CLI)
+AC_SUBST(LIB_SH_GUI)
+AC_SUBST(NET_PROG_RES)
+AC_SUBST(NET_PROG_CLI)
+AC_SUBST(MYSQL_PROG_CLI)
+AC_SUBST(MYSQLLDFLAGS)
+AC_SUBST(SNMP_PROG_CLI)
+AC_SUBST(TESTPROGRAMS)
+AC_SUBST(WXCPPFLAGS)
+AC_SUBST(WXCXXFLAGS)
+AC_SUBST(WXCFLAGS)
+AC_SUBST(WXLDFLAGS)
+AC_SUBST(SOLIBZ)
+AC_SUBST(SOLIBBZ)
+AC_SUBST(SOLIBMATH)
+AC_SUBST(SOLIBCRYPTO)
+AC_SUBST(SOLIBNET)
+AC_SUBST(SOLIBIMG)
+AC_SUBST(SOLIBSDBI)
+AC_SUBST(SOLIBWX)
+AC_SUBST(SOLIBDK3PORT)
+AC_SUBST(SOLIBDK3C)
+AC_SUBST(SOLIBDK3OF)
+AC_SUBST(SOLIBDK3CSRND)
+AC_SUBST(SOLIBDK3BIF)
+AC_SUBST(SOLIBDK3DBI)
+AC_SUBST(SOLIBDK3FIG)
+AC_SUBST(SOLIBDK3BMEPS)
+AC_SUBST(SOLIBDK3NET)
+AC_SUBST(SOLIBDK4BASE)
+AC_SUBST(SOLIBDK4MA)
+AC_SUBST(SOLIBDK4MAIO8H)
+AC_SUBST(SOLIBDK4MAIOWH)
+AC_SUBST(SOLIBDK4MAIODH)
+AC_SUBST(SOLIBDK4MAIO8D)
+AC_SUBST(SOLIBDK4MAIOWD)
+AC_SUBST(SOLIBDK4MAIODD)
+AC_SUBST(SOLIBDK4C)
+AC_SUBST(SOLIBDK4MDRND)
+AC_SUBST(SOLIBDK4PPPT)
+AC_SUBST(SOLIBDK4APP)
+AC_SUBST(SOLIBDK4LAT)
+AC_SUBST(SOLIBDK4SOCK)
+AC_SUBST(SOLIBDK4SOCKA)
+AC_SUBST(SOLIBDK4DBI)
+AC_SUBST(SOLIBDK4DBIA)
+AC_SUBST(NETSNMP_LIBS)
+AC_SUBST(MYSQLLIB)
+AC_SUBST(NETSNMP_CFLAGS)
+AC_SUBST(WXDKFCSLIBF)
+AC_SUBST(WXDKFCSLIBS)
+AC_SUBST(GETSOURCE)
+AC_SUBST(MAKE)
+AC_SUBST(CLILIB)
+AC_SUBST(GUILIB)
+AC_SUBST(ENTRY)
+AC_SUBST(WINUNICODE)
+AC_SUBST(INSTALLMANPAGES)
+AC_SUBST(LIBSPRIVATE)
+AC_SUBST(RTLIB)
+AC_SUBST(LIBDK4BASELIBF)
+AC_SUBST(LIBDK4BASELIBS)
+AC_SUBST(LIBDK4MALIBF)
+AC_SUBST(LIBDK4MALIBS)
+AC_SUBST(LIBDK4MAIO8DLIBF)
+AC_SUBST(LIBDK4MAIO8DLIBS)
+AC_SUBST(LIBDK4MAIOWDLIBF)
+AC_SUBST(LIBDK4MAIOWDLIBS)
+AC_SUBST(LIBDK4MAIODDLIBF)
+AC_SUBST(LIBDK4MAIODDLIBS)
+AC_SUBST(LIBDK4MAIOXDLIBF)
+AC_SUBST(LIBDK4MAIOXDLIBS)
+AC_SUBST(LIBDK4MAIO8HLIBF)
+AC_SUBST(LIBDK4MAIO8HLIBS)
+AC_SUBST(LIBDK4MAIOWHLIBF)
+AC_SUBST(LIBDK4MAIOWHLIBS)
+AC_SUBST(LIBDK4MAIODHLIBF)
+AC_SUBST(LIBDK4MAIODHLIBS)
+AC_SUBST(LIBDK4DBILIBF)
+AC_SUBST(LIBDK4DBILIBS)
+AC_SUBST(LIBDK4CLIBF)
+AC_SUBST(LIBDK4CLIBS)
+AC_SUBST(LIBDK4LATLIBF)
+AC_SUBST(LIBDK4LATLIBS)
+AC_SUBST(LIBDK4SOCKLIBF)
+AC_SUBST(LIBDK4SOCKLIBS)
+AC_SUBST(LIBDK4MDRNDLIBF)
+AC_SUBST(LIBDK4MDRNDLIBS)
+AC_SUBST(LIBDK4PPPTLIBF)
+AC_SUBST(LIBDK4PPPTLIBS)
+AC_SUBST(LIBDK4APPLIBF)
+AC_SUBST(LIBDK4APPLIBS)
+AC_SUBST(LIBDK4PPPTALIBF)
+AC_SUBST(LIBDK4PPPTALIBS)
+AC_SUBST(LIBDK4SOCKALIBF)
+AC_SUBST(LIBDK4SOCKALIBS)
+AC_SUBST(LIBDK4DBIALIBF)
+AC_SUBST(LIBDK4DBIALIBS)
+AC_SUBST(LIBDK4WXLIBF)
+AC_SUBST(LIBDK4WXLIBS)
+AC_SUBST(LIBDK3TRACELIBF)
+AC_SUBST(LIBDK3TRACELIBS)
+AC_SUBST(LIBDK3CLIBF)
+AC_SUBST(LIBDK3CLIBS)
+AC_SUBST(LIBDK3OFLIBF)
+AC_SUBST(LIBDK3OFLIBS)
+AC_SUBST(LIBDK3CSRNDLIBF)
+AC_SUBST(LIBDK3CSRNDLIBS)
+AC_SUBST(LIBDK3BIFLIBF)
+AC_SUBST(LIBDK3BIFLIBS)
+AC_SUBST(LIBDK3DBILIBF)
+AC_SUBST(LIBDK3DBILIBS)
+AC_SUBST(LIBDK3BMEPSLIBF)
+AC_SUBST(LIBDK3BMEPSLIBS)
+AC_SUBST(LIBDK3FIGLIBF)
+AC_SUBST(LIBDK3FIGLIBS)
+AC_SUBST(LIBDK3WXLIBF)
+AC_SUBST(LIBDK3WXLIBS)
+
+AC_OUTPUT([Makefile scripts/wr-dk3inst.sh scripts/wr-dk4inst.sh scripts/create-desktop-files.sh scripts/build-help.sh initd-printqd dktools.pc pkginfo debian/control])
+
+chmod 755 scripts/*.sh
+
+dnl For Debian packaging
+cp debian/dktools-lib.install.in debian/dktools-lib-${SOVERS}.install
+cp debian/dktools-lib.postinst.in debian/dktools-lib-${SOVERS}.postinst
+cp debian/dktools-lib.postrm.in debian/dktools-lib-${SOVERS}.postrm
+cp debian/dktools-lib-dev.install.in debian/dktools-lib-${SOVERS}-dev.install
+echo package-name-doesnt-match-sonames > debian/dktools-lib-${SOVERS}.lintian-overrides
+chmod 644 debian/dktools-lib-${SOVERS}.install
+chmod 644 debian/dktools-lib-${SOVERS}.postinst
+chmod 644 debian/dktools-lib-${SOVERS}.postrm
+chmod 644 debian/dktools-lib-${SOVERS}-dev.install
+chmod 644 debian/dktools-lib-${SOVERS}.lintian-overrides
+
+[[ ! -f dk4config ]] || rm -f dk4config
+[[ ! -f dk4config.o ]] || rm -f dk4config.o
+[[ ! -f dk3config ]] || rm -f dk3config
+[[ ! -f dk3config.o ]] || rm -fr dk3config.o
+[[ ! -f wxcs ]] || rm -f wxcs
+[[ ! -f wxcs.o ]] || rm -fr wxcs.o
+
+if [[ "X$build" != "X$host" ]]
+then
+ cp dk3conf.cross dk3conf.h
+ cp dk4conf.cross dk4conf.h
+ cp dk4wxcs.cross dk4wxcs.h
+ echo 'ERROR: Cross-compiling not supported!'
+elif [[ "X$SUITE" = "Xgui" ]]
+then
+ echo 'Build dk4config (C++)'
+ $MAKE dk4config
+ echo 'Build dk3config (C)'
+ $MAKE dk3config
+ echo 'Build wxcs (C++)'
+ $MAKE wxcs
+ echo 'Generating configuration files'
+ ./dk4config > dk4conf.h
+ ./dk3config > dk3conf.h
+ ./wxcs > dk4wxcs.h
+elif [[ "X$CXX" != "X" ]]
+then
+ echo 'Build dk4config (C++)'
+ $MAKE dk4config
+ echo 'Build dk3config (C)'
+ $MAKE dk3config
+ echo 'Generating configuration files'
+ cp dk4wxcs.cross dk4wxcs.h
+ ./dk4config > dk4conf.h
+ ./dk3config > dk3conf.h
+else
+ sed -f mod-dkconfig.sed < dk4config.cpp > dk4config.c
+ mv dk4config.cpp dk4config.cpp.bck
+ echo 'Build dk4config (C)'
+ $MAKE dk4config
+ echo 'Build dk3config (C)'
+ $MAKE dk3config
+ mv dk4config.cpp.bck dk4config.cpp
+ rm dk4config.c
+ echo 'Generating configuration files'
+ cp dk4wxcs.cross dk4wxcs.h
+ ./dk4config > dk4conf.h
+ ./dk3config > dk3conf.h
+fi
+sed -e 's/DK4/DK3/g' < dk4wxcs.h > dk3wxcs.h
+
+dnl Produce dk4inst.c file
+chmod 755 scripts/wr-dk4inst.sh
+echo './scripts/wr-dk4inst.sh > dk4inst.c'
+./scripts/wr-dk4inst.sh
+chmod 755 scripts/wr-dk3inst.sh
+./scripts/wr-dk3inst.sh > dk3inst.c
+chmod 755 scripts/create-desktop-files.sh
+./scripts/create-desktop-files.sh
+
+dnl Produce dk4vers.h file
+VERSNO=`cat version.txt`
+cat > dk4vers.h <<EOF
+#ifndef DK4VERS_H_INCLUDED
+#define DK4VERS_H_INCLUDED 1
+
+/** @file dk4vers.h Version number as text string.
+*/
+
+/** Version number in 8 bit characters.
+*/
+#define DKT_VERSION_C8 "$VERSNO"
+
+/** Version number in dkChar.
+*/
+#define DKT_VERSION_DK dkT("$VERSNO")
+
+#endif
+EOF
+
+cat > dk4verswx.h <<EOF
+#ifndef DK4VERSWX_H_INCLUDED
+/** Protection against multiple inclusions. */
+#define DK4VERSWX_H_INCLUDED 1
+/** @file dk4verswx.h Version number as wxChar string.
+*/
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include "wx/wxprec.h"
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#ifndef WX_WX_H_INCLUDED
+#include "wx/wx.h"
+#define WX_WX_H_INCLUDED 1
+#endif
+#endif
+
+/** Version number as wxChar string.
+*/
+#define DKT_VERSION_WX wxT("$VERSNO")
+
+#endif
+EOF
+
+dnl Write summary
+echo ''
+echo 'Configuration summary'
+echo '====================='
+if [[ "X$ZLIB" = "X-lz" ]]
+then
+echo 'zlib: found.'
+else
+echo 'zlib: NOT found! Required!'
+echo ' SL 6.x package name: zlib-devel'
+echo ' Debian package name: libz-dev'
+echo ' URL: http://www.zlib.net'
+EXVAL=1
+fi
+if [[ "X-lbz2" = "X$BZLIB" ]]
+then
+echo 'libbz2: found.'
+else
+echo 'libbz2: NOT found! Recommended.'
+echo ' Bzip compression not available.'
+echo ' SL 6.x package name: bzip2-devel'
+echo ' Debian package name: libbz2-dev'
+echo ' URL: http://www.bzip.org'
+fi
+if [[ "X$LIBPNG" = "X-lpng" ]]
+then
+echo 'libpng: found.'
+else
+echo 'libpng: NOT found! Required!'
+echo ' SL 6.x package name: libpng-devel'
+echo ' Debian package name: libpng-dev'
+echo ' URL: http://www.libpng.org'
+EXVAL=1
+fi
+if [[ "X$LIBJPEG" = "X-ljpeg" ]]
+then
+echo 'libjpeg: found.'
+else
+echo 'libjpeg: NOT found! Recommended.'
+echo ' No JPEG support in bmpp and fig2lat.'
+echo ' SL 6.x package name: libjpeg-turbo-devel'
+echo ' Debian package name: libjpeg-dev'
+echo ' URL: http://www.ijg.org/'
+fi
+if [[ "X$LIBTIFF" = "X-ltiff" ]]
+then
+echo 'libtiff: found.'
+else
+echo 'libtiff: NOT found! Recommended.'
+echo ' No TIFF support in bmpp and fig2lat.'
+echo ' SL 6.x package name: libtiff-devel'
+echo ' Debian package name: libtiff-dev'
+echo ' URL: http://www.remotesensing.org/libtiff/'
+fi
+if [[ "X$ANYDB" != "X" ]]
+then
+echo "database: $ANYDB"
+else
+echo 'database: NOT found! Recommended.'
+echo ' Skipping printqd build!'
+echo ' SL 6.x package name: db4-devel'
+echo ' Debian package name: libdb-dev'
+echo ' URL: http://www.oracle.com/database/berkeley-db/'
+fi
+if [[ "X$MYSQLPROG" = "Xmysqlprog" ]]
+then
+echo 'MySQL: found.'
+else
+echo 'MySQL: NOT found! Recommended.'
+echo ' Skipping itadmin build.'
+echo ' SL 6.x package name: mysql-devel'
+echo ' Debian package name: libmysqlclient-dev'
+echo ' URL: http://www.mysql.com/'
+fi
+if [[ "X$CRYPTO" != "X" ]]
+then
+echo 'OpenSSL: found.'
+else
+echo 'OpenSSL: NOT found!'
+echo ' SL 6.x package name: openssl-devel'
+echo ' Debian package name: libssl-dev'
+echo ' URL: http://www.openssl.org/'
+fi
+if [[ "X$WXCPPFLAGS" != "X" ]]
+then
+echo 'wxWidgets: found.'
+else
+echo 'wxWidgets: NOT found!'
+echo ' SL 6.x package name: wxGTK-devel'
+echo ' Debian package name: libwxgtk3.0-dev'
+echo ' URL: http://www.wxwidgets.org/'
+fi
+case "X$SUITE" in
+"Xgui")
+echo 'Software bundle: CLI and GUI programs'
+;;
+"Xrescue")
+echo 'Software bundle: Rescue system programs'
+;;
+"*")
+echo 'Software bundle: CLI programs'
+;;
+esac
+if [[ "X$ENASTATIC" = "Xyes" ]]
+then
+echo 'Install static libraries: yes'
+else
+echo 'Install static libraries: no'
+fi
+if [[ "X$ENASHARED" = "Xyes" ]]
+then
+echo 'Install shared libraries: yes'
+else
+echo 'Install shared libraries: no'
+fi
+if [[ "X$USESOLINKING" = "Xyes" ]]
+then
+echo 'Nested shared library linking: yes'
+else
+echo 'Nested shared library linking: no'
+fi
+if [[ "X$ENAPACKAGING" = "Xyes" ]]
+then
+echo 'Binaries use shared libraries: yes'
+else
+echo 'Binaries use shared libraries: no'
+fi
+echo ''
+echo The INSTALL files describes how to install via '*.rpm' or '.deb' package.
+echo ''
+exit $EXVAL
+
diff --git a/support/dktools/contrib/README b/support/dktools/contrib/README
new file mode 100644
index 0000000000..a3592b39ae
--- /dev/null
+++ b/support/dktools/contrib/README
@@ -0,0 +1,13 @@
+The contrib directory contains files for use together with other
+software projects.
+
+- gs-fonts-svg Convert GhostScript fonts to other file types
+ In *.fig files (from XFig, jFig, or WinFIG) PS fonts can
+ be used for text labels. When converting from *.fig to other files
+ we probably need PS fonts in specific file formats.
+ Using the scripts in the gs-fonts-svg directory you can convert
+ the GhostScript fonts to other file formats.
+ NOTE: The GhostScript project uses the GPL. If you convert the
+ GhostScript fonts to other file formats you can distribute the
+ resulting font files under GPL only.
+
diff --git a/support/dktools/contrib/gs-fonts-svg/COPYING b/support/dktools/contrib/gs-fonts-svg/COPYING
new file mode 100644
index 0000000000..94a9ed024d
--- /dev/null
+++ b/support/dktools/contrib/gs-fonts-svg/COPYING
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program 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.
+
+ This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/support/dktools/contrib/gs-fonts-svg/INSTALL b/support/dktools/contrib/gs-fonts-svg/INSTALL
new file mode 100644
index 0000000000..55a7e60091
--- /dev/null
+++ b/support/dktools/contrib/gs-fonts-svg/INSTALL
@@ -0,0 +1,71 @@
+Scripts to create SVG variants of the GhostScript fonts
+=======================================================
+
+This directory contains scripts to convert the GhostScript fonts to
+SVG, TTF, or PFB files.
+For licensing reasons I can not bundle converted GhostScript font
+files with dktools (GhostScript is a GPL project, dktools uses a
+BSD-style license). So you have to download GhostScript separately
+and do the conversion yourself.
+
+Linux, Unix...
+--------------
+
+* Make sure you have the following software installed:
+ - fontforge
+ - python
+
+* Obtain a recent GhostScript source archive (the procedure shown here
+ was tested using version 9.06).
+
+* Unpack the archive.
+
+* After unpacking you will find a Resource/Font directory in the directory
+ created by unpacking the archive.
+
+* Copy all files from this directory into the Resource/Font directory.
+
+* Change into the Resource/Font directory.
+
+* Choose a name for a directory where to place the SVG files,
+ i.e. "/usr/share/gs-fonts-svg". Do not use a directory which already
+ exists.
+
+* Run
+ ./crsvg.sh /usr/share/gs-fonts-svg
+ specify the destination directory as command line argument.
+
+* The scripts crttf.sh or crpfb.sh can be used to convert to *.ttf or
+ *.pfb files.
+
+* The procedure for making the fonts available to your SVG viewer depends
+ on the SVG viewer software used.
+
+
+Windows
+-------
+
+* Obtain a recent GhostScript source archive (the procedure shown here
+ was tested using version 9.06).
+
+* Unpack the archive.
+
+* After unpacking you will find a Resource/Font directory in the directory
+ created by unpacking the archive.
+
+* Copy all files from this directory into the Resource/Font directory.
+
+* Change into the Resource/Font directory.
+
+* Run the crpfb.cmd script
+ ./crpfb.cmd
+
+* The script has created a C:\Temp\PfbFonts directory.
+
+* Open the C:\Temp\PfbFonts directory in the Windows Explorer.
+
+* Mark all the *.pfb files.
+
+* After clicking the right mouse key, a context menu appears.
+ Choose "install font(s)".
+
diff --git a/support/dktools/contrib/gs-fonts-svg/README b/support/dktools/contrib/gs-fonts-svg/README
new file mode 100644
index 0000000000..d4b1ca94b9
--- /dev/null
+++ b/support/dktools/contrib/gs-fonts-svg/README
@@ -0,0 +1,42 @@
+Scripts to create SVG variants of the GhostScript fonts
+=======================================================
+
+This directory contains scripts to convert the GhostScript fonts to
+SVG files and other file formats.
+
+
+INSTALLATION
+------------
+To use the scripts, follow the instructions in the INSTALL file.
+
+FILES
+-----
+COPYING GPL license, this file is copied to the destination
+ directory for your *.svg, *.ttf, or *.pfb files.
+crpfb.cmd Batch file for use on Windows to produce *.pfb files.
+crpfb.sh Shell script to produce *.pfb files on Linux/Unix.
+crsvg.sh Shell script to produce *.svg files on Linux/Unix.
+crttf.sh Shell script to produce *.ttf files on Linux/Unix.
+index.html File listing for the destination directory.
+INSTALL Installation instructions.
+metadata.sed Script to edit metadata in *.svg fonts using sed.
+pfb2svg.pe Fontforge script, used in the conversions.
+README This README file.
+
+
+Note: The COPYING file does not apply to the following files
+ (these files from the dktools project are BSD-style licensed):
+ crpfb.cmd, crpfb.sh, crsvg.sh, crttf.sh, index.html, INSTALL, metadata.sed,
+ pfb2svg.pe, README
+
+The COPYING file is copied into the destination directory where the
+GhostScript fonts converted to other file types will reside.
+GhostScript, the original GhostScript fonts and the GhostScript fonts
+converted to other file formats are GPL licensed, so we have to provide
+the COPYING file along with these files.
+
+Note: The index.html file is not a description of the contrib/gs-fonts-svg
+ subdirectory of the dktools project, it is copied to the output
+ directory where the conversion results are placed as an index for that
+ directory.
+
diff --git a/support/dktools/contrib/gs-fonts-svg/crpfb.cmd b/support/dktools/contrib/gs-fonts-svg/crpfb.cmd
new file mode 100644
index 0000000000..2162040926
--- /dev/null
+++ b/support/dktools/contrib/gs-fonts-svg/crpfb.cmd
@@ -0,0 +1,41 @@
+@echo on
+copy NimbusRomNo9L-Regu n021003l.pfb
+copy NimbusRomNo9L-ReguItal n021023l.pfb
+copy NimbusRomNo9L-Medi n021004l.pfb
+copy NimbusRomNo9L-MediItal n021024l.pfb
+copy URWGothicL-Book a010013l.pfb
+copy URWGothicL-BookObli a010033l.pfb
+copy URWGothicL-Demi a010015l.pfb
+copy URWGothicL-DemiObli a010035l.pfb
+copy URWBookmanL-Ligh b018012l.pfb
+copy URWBookmanL-LighItal b018032l.pfb
+copy URWBookmanL-DemiBold b018015l.pfb
+copy URWBookmanL-DemiBoldItal b018035l.pfb
+copy NimbusMonL-Regu n022003l.pfb
+copy NimbusMonL-ReguObli n022023l.pfb
+copy NimbusMonL-Bold n022004l.pfb
+copy NimbusMonL-BoldObli n022024l.pfb
+copy NimbusSanL-Regu n019003l.pfb
+copy NimbusSanL-ReguItal n019023l.pfb
+copy NimbusSanL-Bold n019004l.pfb
+copy NimbusSanL-BoldItal n019024l.pfb
+copy NimbusSanL-ReguCond n019043l.pfb
+copy NimbusSanL-ReguCondItal n019063l.pfb
+copy NimbusSanL-BoldCond n019044l.pfb
+copy NimbusSanL-BoldCondItal n019064l.pfb
+copy CenturySchL-Roma c059013l.pfb
+copy CenturySchL-Ital c059033l.pfb
+copy CenturySchL-Bold c059016l.pfb
+copy CenturySchL-BoldItal c059036l.pfb
+copy URWPalladioL-Roma p052003l.pfb
+copy URWPalladioL-Ital p052023l.pfb
+copy URWPalladioL-Bold p052004l.pfb
+copy URWPalladioL-BoldItal p052024l.pfb
+copy StandardSymL s050000l.pfb
+copy URWChanceryL-MediItal z003034l.pfb
+copy Dingbats d050000l.pfb
+
+mkdir C:\Temp
+mkdir C:\Temp\PfbFonts
+xcopy *.pfb C:\Temp\PfbFonts\
+
diff --git a/support/dktools/contrib/gs-fonts-svg/crpfb.sh b/support/dktools/contrib/gs-fonts-svg/crpfb.sh
new file mode 100755
index 0000000000..3ce65cf1d0
--- /dev/null
+++ b/support/dktools/contrib/gs-fonts-svg/crpfb.sh
@@ -0,0 +1,72 @@
+#! /bin/sh
+
+DIR="$1"
+
+if [ "X$DIR" = "X" ]
+then
+ echo 'ERROR: Please specify destination directory as command line argument!'
+ exit 1
+fi
+
+FF=`which fontforge`
+if [ "X$FF" = "X" ]
+then
+ echo 'ERROR: The fontforge program was not found!'
+ exit 1
+fi
+
+export DIR
+
+[ -d "$DIR" ] || (mkdir $DIR ; chmod 755 $DIR)
+
+# Argument 1: GhostScript font name.
+# Argument 2: PFB font name without the .pfb suffix
+create_pfb_font() {
+ cp $1 $2.pfb
+ cp $2.pfb $DIR
+}
+
+create_pfb_font NimbusRomNo9L-Regu n021003l
+create_pfb_font NimbusRomNo9L-ReguItal n021023l
+create_pfb_font NimbusRomNo9L-Medi n021004l
+create_pfb_font NimbusRomNo9L-MediItal n021024l
+create_pfb_font URWGothicL-Book a010013l
+create_pfb_font URWGothicL-BookObli a010033l
+create_pfb_font URWGothicL-Demi a010015l
+create_pfb_font URWGothicL-DemiObli a010035l
+create_pfb_font URWBookmanL-Ligh b018012l
+create_pfb_font URWBookmanL-LighItal b018032l
+create_pfb_font URWBookmanL-DemiBold b018015l
+create_pfb_font URWBookmanL-DemiBoldItal b018035l
+create_pfb_font NimbusMonL-Regu n022003l
+create_pfb_font NimbusMonL-ReguObli n022023l
+create_pfb_font NimbusMonL-Bold n022004l
+create_pfb_font NimbusMonL-BoldObli n022024l
+create_pfb_font NimbusSanL-Regu n019003l
+create_pfb_font NimbusSanL-ReguItal n019023l
+create_pfb_font NimbusSanL-Bold n019004l
+create_pfb_font NimbusSanL-BoldItal n019024l
+create_pfb_font NimbusSanL-ReguCond n019043l
+create_pfb_font NimbusSanL-ReguCondItal n019063l
+create_pfb_font NimbusSanL-BoldCond n019044l
+create_pfb_font NimbusSanL-BoldCondItal n019064l
+create_pfb_font CenturySchL-Roma c059013l
+create_pfb_font CenturySchL-Ital c059033l
+create_pfb_font CenturySchL-Bold c059016l
+create_pfb_font CenturySchL-BoldItal c059036l
+create_pfb_font URWPalladioL-Roma p052003l
+create_pfb_font URWPalladioL-Ital p052023l
+create_pfb_font URWPalladioL-Bold p052004l
+create_pfb_font URWPalladioL-BoldItal p052024l
+create_pfb_font StandardSymL s050000l
+create_pfb_font URWChanceryL-MediItal z003034l
+create_pfb_font Dingbats d050000l
+
+cp crsvg.sh $DIR
+cp crpfb.sh $DIR
+cp crttf.sh $DIR
+cp metadata.sed $DIR
+cp pfb2svg.pe $DIR
+cp README $DIR
+cp COPYING $DIR
+
diff --git a/support/dktools/contrib/gs-fonts-svg/crsvg.sh b/support/dktools/contrib/gs-fonts-svg/crsvg.sh
new file mode 100755
index 0000000000..1840f7287a
--- /dev/null
+++ b/support/dktools/contrib/gs-fonts-svg/crsvg.sh
@@ -0,0 +1,77 @@
+#! /bin/sh
+
+DIR="$1"
+
+if [ "X$DIR" = "X" ]
+then
+ echo 'ERROR: Please specify destination directory as command line argument!'
+ exit 1
+fi
+
+FF=`which fontforge`
+if [ "X$FF" = "X" ]
+then
+ echo 'ERROR: The fontforge program was not found!'
+ exit 1
+fi
+
+export DIR
+
+[ -d "$DIR" ] || (mkdir $DIR ; chmod 755 $DIR)
+
+# Argument 1: GhostScript font name.
+# Argument 2: SVG font name without the .svg suffix
+create_svg_font() {
+ cp $1 $2.pfb
+ fontforge -script pfb2svg.pe $2.pfb $2.svg
+ [ ! -f test.svg ] || rm -f test.svg
+ mv $2.svg test.svg
+ sed -f metadata.sed < test.svg > $2.svg
+ [ ! -f test.svg ] || rm -f test.svg
+ cp $2.svg $DIR
+}
+
+create_svg_font NimbusRomNo9L-Regu n021003l
+create_svg_font NimbusRomNo9L-ReguItal n021023l
+create_svg_font NimbusRomNo9L-Medi n021004l
+create_svg_font NimbusRomNo9L-MediItal n021024l
+create_svg_font URWGothicL-Book a010013l
+create_svg_font URWGothicL-BookObli a010033l
+create_svg_font URWGothicL-Demi a010015l
+create_svg_font URWGothicL-DemiObli a010035l
+create_svg_font URWBookmanL-Ligh b018012l
+create_svg_font URWBookmanL-LighItal b018032l
+create_svg_font URWBookmanL-DemiBold b018015l
+create_svg_font URWBookmanL-DemiBoldItal b018035l
+create_svg_font NimbusMonL-Regu n022003l
+create_svg_font NimbusMonL-ReguObli n022023l
+create_svg_font NimbusMonL-Bold n022004l
+create_svg_font NimbusMonL-BoldObli n022024l
+create_svg_font NimbusSanL-Regu n019003l
+create_svg_font NimbusSanL-ReguItal n019023l
+create_svg_font NimbusSanL-Bold n019004l
+create_svg_font NimbusSanL-BoldItal n019024l
+create_svg_font NimbusSanL-ReguCond n019043l
+create_svg_font NimbusSanL-ReguCondItal n019063l
+create_svg_font NimbusSanL-BoldCond n019044l
+create_svg_font NimbusSanL-BoldCondItal n019064l
+create_svg_font CenturySchL-Roma c059013l
+create_svg_font CenturySchL-Ital c059033l
+create_svg_font CenturySchL-Bold c059016l
+create_svg_font CenturySchL-BoldItal c059036l
+create_svg_font URWPalladioL-Roma p052003l
+create_svg_font URWPalladioL-Ital p052023l
+create_svg_font URWPalladioL-Bold p052004l
+create_svg_font URWPalladioL-BoldItal p052024l
+create_svg_font StandardSymL s050000l
+create_svg_font URWChanceryL-MediItal z003034l
+create_svg_font Dingbats d050000l
+
+cp crsvg.sh $DIR
+cp crpfb.sh $DIR
+cp crttf.sh $DIR
+cp metadata.sed $DIR
+cp pfb2svg.pe $DIR
+cp README $DIR
+cp COPYING $DIR
+
diff --git a/support/dktools/contrib/gs-fonts-svg/crttf.sh b/support/dktools/contrib/gs-fonts-svg/crttf.sh
new file mode 100755
index 0000000000..10c5d535f8
--- /dev/null
+++ b/support/dktools/contrib/gs-fonts-svg/crttf.sh
@@ -0,0 +1,73 @@
+#! /bin/sh
+
+DIR="$1"
+
+if [ "X$DIR" = "X" ]
+then
+ echo 'ERROR: Please specify destination directory as command line argument!'
+ exit 1
+fi
+
+FF=`which fontforge`
+if [ "X$FF" = "X" ]
+then
+ echo 'ERROR: The fontforge program was not found!'
+ exit 1
+fi
+
+export DIR
+
+[ -d "$DIR" ] || (mkdir $DIR ; chmod 755 $DIR)
+
+# Argument 1: GhostScript font name.
+# Argument 2: TTF font name without the .ttf suffix
+create_ttf_font() {
+ cp $1 $2.pfb
+ fontforge -script pfb2svg.pe $2.pfb $2.ttf
+ cp $2.ttf $DIR
+}
+
+create_ttf_font NimbusRomNo9L-Regu n021003l
+create_ttf_font NimbusRomNo9L-ReguItal n021023l
+create_ttf_font NimbusRomNo9L-Medi n021004l
+create_ttf_font NimbusRomNo9L-MediItal n021024l
+create_ttf_font URWGothicL-Book a010013l
+create_ttf_font URWGothicL-BookObli a010033l
+create_ttf_font URWGothicL-Demi a010015l
+create_ttf_font URWGothicL-DemiObli a010035l
+create_ttf_font URWBookmanL-Ligh b018012l
+create_ttf_font URWBookmanL-LighItal b018032l
+create_ttf_font URWBookmanL-DemiBold b018015l
+create_ttf_font URWBookmanL-DemiBoldItal b018035l
+create_ttf_font NimbusMonL-Regu n022003l
+create_ttf_font NimbusMonL-ReguObli n022023l
+create_ttf_font NimbusMonL-Bold n022004l
+create_ttf_font NimbusMonL-BoldObli n022024l
+create_ttf_font NimbusSanL-Regu n019003l
+create_ttf_font NimbusSanL-ReguItal n019023l
+create_ttf_font NimbusSanL-Bold n019004l
+create_ttf_font NimbusSanL-BoldItal n019024l
+create_ttf_font NimbusSanL-ReguCond n019043l
+create_ttf_font NimbusSanL-ReguCondItal n019063l
+create_ttf_font NimbusSanL-BoldCond n019044l
+create_ttf_font NimbusSanL-BoldCondItal n019064l
+create_ttf_font CenturySchL-Roma c059013l
+create_ttf_font CenturySchL-Ital c059033l
+create_ttf_font CenturySchL-Bold c059016l
+create_ttf_font CenturySchL-BoldItal c059036l
+create_ttf_font URWPalladioL-Roma p052003l
+create_ttf_font URWPalladioL-Ital p052023l
+create_ttf_font URWPalladioL-Bold p052004l
+create_ttf_font URWPalladioL-BoldItal p052024l
+create_ttf_font StandardSymL s050000l
+create_ttf_font URWChanceryL-MediItal z003034l
+create_ttf_font Dingbats d050000l
+
+cp crsvg.sh $DIR
+cp crpfb.sh $DIR
+cp crttf.sh $DIR
+cp metadata.sed $DIR
+cp pfb2svg.pe $DIR
+cp README $DIR
+cp COPYING $DIR
+
diff --git a/support/dktools/contrib/gs-fonts-svg/index.html b/support/dktools/contrib/gs-fonts-svg/index.html
new file mode 100644
index 0000000000..06f1b9fef2
--- /dev/null
+++ b/support/dktools/contrib/gs-fonts-svg/index.html
@@ -0,0 +1,51 @@
+<html>
+<head>
+<title>GhostScript fonts converted to SVG files</title>
+</head>
+<body>
+<h1>Overview</h1>
+<p>This directory contains the GhostScript fonts converted to SVG files.
+</p>
+<p>As a part of GhostScript, the fonts are licensed under the terms
+of the Gnu General Public License (GPL).<br>
+So we make access to all sources needed to convert the GhostScript fonts
+to SVG as easy as obtaining the converted fonts.
+</p>
+<h1>Files in this directory</h1>
+<ul>
+<li><a href="ghostscript-9.06.tar.gz">ghostscript-9.06.tar.gz</a><br>
+is the GhostScript archive containing the original fonts.
+</li>
+<li><a href="README">README</a><br>
+is the readme file.
+</li>
+<li><a href="metadata.sed">metadata.sed</a> and
+<a href="pfb2svg.pe">pfb2svg.pe</a><br>
+are used by the conversion.
+</li>
+<li><a href="crsvg.sh">crsvg.sh</a><br>
+is the script to run the conversion.
+</li>
+<li><a href="crpfb.sh">crpfb.sh</a><br>
+is the script to rename the fonts, so the suffix *.pfb indicates the type.
+</li>
+<li><a href="crpfb.cmd">crpfb.cmd</a><br>
+is the script to rename the fonts, so the suffix *.pfb indicates the type.
+This script is intended for use on Windows systems.
+</li>
+<li><a href="crttf.sh">crttf.sh</a><br>
+is the script to convert the fonts to *.ttf files.
+</li>
+<li><a href="INSTALL">INSTALL</a><br>
+is a text file documenting how to do the conversion.
+</li>
+<li><a href="COPYING">COPYING</a><br>
+contains the text of the Gnu General Public License, version 3.
+</li>
+</ul>
+<p>To do the conversion yourself, download all the files listed above,
+make sure you have Python and FontForge installed, and follow the
+instructions in the INSTALL file.
+</p>
+</body>
+</html>
diff --git a/support/dktools/contrib/gs-fonts-svg/metadata.sed b/support/dktools/contrib/gs-fonts-svg/metadata.sed
new file mode 100644
index 0000000000..3dec81ce0b
--- /dev/null
+++ b/support/dktools/contrib/gs-fonts-svg/metadata.sed
@@ -0,0 +1,4 @@
+/<metadata>/,/<\/metadata>/ {
+ / By /d
+}
+
diff --git a/support/dktools/contrib/gs-fonts-svg/pfb2svg.pe b/support/dktools/contrib/gs-fonts-svg/pfb2svg.pe
new file mode 100644
index 0000000000..91bd07e912
--- /dev/null
+++ b/support/dktools/contrib/gs-fonts-svg/pfb2svg.pe
@@ -0,0 +1,5 @@
+#! /usr/local/bin/fontforge
+
+Open($1);
+Generate($2);
+Close();
diff --git a/support/dktools/debian-jessie-build-deb.sh b/support/dktools/debian-jessie-build-deb.sh
new file mode 100755
index 0000000000..056c075b34
--- /dev/null
+++ b/support/dktools/debian-jessie-build-deb.sh
@@ -0,0 +1,73 @@
+#! /bin/sh
+
+umask 022
+
+VERSION=`cat version.txt`
+
+# Make sure to run the script as unprivileged user
+
+if [ "X$LOGNAME" = "Xroot" ]
+then
+ echo 'ERROR: This script must not be run as root!'
+ exit 1
+fi
+
+
+# Make sure we are in the correct directory
+
+if [ "X$VERSION" = "X" ]
+then
+ echo 'ERROR: Failed to find version number!'
+ echo 'Make sure to call this script in the correct directory!'
+ exit 1
+fi
+
+
+# Make sure the original archive is still in the parent directory
+
+if [ ! -f ../dktools-${VERSION}.tar.gz ]
+then
+ echo 'ERROR: File' ../dktools-${VERSION}.tar.gz 'not found!'
+ exit 1
+fi
+
+
+# Create a .orig copy of the original archive
+
+if [ -f ../dktools_${VERSION}.orig.tar.gz ]
+then
+ rm -f ../dktools_${VERSION}.orig.tar.gz
+fi
+ln ../dktools-${VERSION}.tar.gz ../dktools_${VERSION}.orig.tar.gz
+
+
+# The 'debian' subdirectory must be present
+
+if [ ! -d debian ]
+then
+ echo 'ERROR: Missing directory debian!'
+ exit 1
+fi
+
+
+# Build the package, save output for later inspection
+
+if [ "X$DEB_SIGN_KEYID" != "X" ]
+then
+ dpkg-buildpackage 2>&1 | tee ../dpkg-buildpackage.out
+else
+ dpkg-buildpackage -us -uc 2>&1 | tee ../dpkg-buildpackage.out
+fi
+
+# Finally list the created packages and show some notes
+
+echo 'If the dpkg-buildpackage command succeeded, you should find the'
+echo '*.deb archive in the parent directory.'
+echo ''
+ls -l ../dktools*${VERSION}*.deb
+echo ''
+echo 'Otherwise you should inspect the ../dpkg-buildpackage.out file'
+echo 'for error messages.'
+echo ''
+
+exit 0
diff --git a/support/dktools/debian-jessie-build-live.sh b/support/dktools/debian-jessie-build-live.sh
new file mode 100755
index 0000000000..71ec977400
--- /dev/null
+++ b/support/dktools/debian-jessie-build-live.sh
@@ -0,0 +1,2037 @@
+#! /bin/sh
+# Copyright (c) 2016, Dirk Krause
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# * Neither the name of the Dirk Krause nor the names of contributors may be
+# used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.
+#
+# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+# ##### START OF CONFIGURATION SECTION #####
+#
+#
+
+# GUI or CLI live system.
+# -----------------------
+# Boolean flag, "yes" indicates a GUI live system, "no" a CLI live system.
+GUI="no"
+
+# Allow or deny installation of recommended packages
+# --------------------------------------------------
+# Boolean flag, "yes" or "no".
+# Only used if GUI=no. Recommended value: yes.
+APTRECOMMENDS="yes"
+
+# Flag: Allow to run "apt-get -y update && apt-get -y upgrade"
+# ------------------------------------------------------------
+# Set to "yes" or "no" to allow or deny a system upgrade before
+# building the live system.
+ALLOWUPGRADE="yes"
+
+# Flag: Allow installation of unsigned (self-made) packages
+# ---------------------------------------------------------
+# Set to "yes" or "no".
+# Only needed to install self-made package which are not signed.
+ALLOWUNSIGNEDPKG="no"
+
+# Flag: Allow to use firmware from "non-free" and "contrib".
+# ----------------------------------------------------------
+# Set to "yes" to place non-free firmware files in the live system,
+# "no" to build a live system without non-free firmware files.
+# Some components in computers (mostly WiFi chips, but some ethernet and other
+# chips too) require firmware files to work.
+# ----- Start of opinion section, no legal advice. -----
+# Unfortunately some firmware files are not available under a free license
+# allowing to distribute them together with GPL-licensed software.
+# If you configure the use of such non-free firmware files here, the resulting
+# live system may be undistributable (you can use it for your own purposes
+# but are not allowed to distribute it to other users).
+# ----- End of opinion section, no legal advice. -----
+# ----- Start of disclaimer -----
+# The section above is an opinion piece and does not contain legal advice.
+# You should consult a lawyer to obtain legal advice about the legal status
+# of distributing live systems containing non-free firmware files.
+# ----- End of disclaimer -----
+ALLOWNONFREE="no"
+
+# Live system type.
+# -----------------
+# One from:
+# hybrid for USB drives, CDROM or DVD
+# hdd for USB drives only
+# nfs for network boot DHCP/TFTP/NFS (requires NFSSERVER and NFSPATH).
+LIVETYPE="hybrid"
+
+# NFS server name for LIVETYPE=nfs.
+# ---------------------------------
+# Must be specified for LIVETYPE=nfs.
+# Recommendation: Use IP address.
+# NFSSERVER="nfs.my-domain.com"
+NFSSERVER=""
+
+# NFS root file system path for LIVETYPE=nfs.
+# -------------------------------------------
+# Must be specified for LIVETYPE=nfs.
+# NFSPATH="/opt/nfs/netboot"
+NFSPATH=""
+
+# Flag: Configuration done.
+# -------------------------
+# After adjusting the settings in this section, change this to "yes".
+CONFIGURED="no"
+
+# Directory for additional data
+# -----------------------------
+# Leave empty to use the default /usr/local/livesys directory.
+# Use
+# DATADIR="-"
+# to skip copying additional data into the live system.
+DATADIR=""
+
+# MIRRORS TO USE WHEN BUILDING AND RUNNING THE LIVE SYSTEM
+# ========================================================
+# Leave empty for automatic selection and/or defaults.
+
+# Mirror for bootstrapping
+# ------------------------
+# Default: http://ftp.de.debian.org/debian/
+# This is probably not a good choice for users from outside Europe.
+PARENTMIRRORBOOTSTRAP=""
+
+# Mirror used in the chroot stage
+# -------------------------------
+# Default: $PARENTMIRRORBOOTSTRAP
+PARENTMIRRORCHROOT=""
+
+# Mirror for security updates used in the chroot stage
+# ----------------------------------------------------
+# Default: http://security.debian.org/debian/
+PARENTMIRRORCHROOTSECURITY=""
+
+# Mirror for package updates used in the chroot stage
+# ---------------------------------------------------
+# Default: PARENTMIRRORCHROOT
+PARENTMIRRORCHROOTUPDATES=""
+
+# Mirror for backports used in the chroot stage.
+# ----------------------------------------------
+# Default: http://backports.debian.org/debian-backports/
+PARENTMIRRORCHROOTBACKPORTS=""
+
+# Mirror used by the live system
+# ------------------------------
+# Default: http://http.debian.net/debian/
+PARENTMIRRORBINARY=""
+
+# Mirror for security updates used by the live system
+# ---------------------------------------------------
+# Default: http://security.debian.org/
+PARENTMIRRORBINARYSECURITY=""
+
+# Mirror for packages updates used by the live system
+# ---------------------------------------------------
+# Default: PARENTMIRRORBINARY
+PARENTMIRRORBINARYUPDATES=""
+
+# Mirror for backports used by the live system
+# --------------------------------------------
+# Default: http://backports.debian.org/debian-backports/
+PARENTMIRRORBINARYBACKPORTS=""
+
+# Mirror to fetch Debian installer images from
+# --------------------------------------------
+# Default: PARENTMIRRORBOOTSTRAP
+PARENTMIRRORDEBIANINSTALLER=""
+
+# Mirror used to bootstrap the derivative from
+# --------------------------------------------
+# Default: http://ftp.de.debian.org/debian/
+MIRRORBOOTSTRAP=""
+
+# Mirror used in the chroot stage to build the derivative
+# -------------------------------------------------------
+# Default: MIRRORBOOTSTRAP
+MIRRORCHROOT=""
+
+# Mirror for security updates used in the chroot stage to build the derivative
+# ----------------------------------------------------------------------------
+# Default: http://security.debian.org/debian/
+MIRRORCHROOTSECURITY=""
+
+# Mirror for package updates used in the chroot stage to build the derivative
+# ---------------------------------------------------------------------------
+# Default: MIRRORCHROOT
+MIRRORCHROOTUPDATES=""
+
+# Mirror for backports used in the chroot stage to build the derivative
+# ---------------------------------------------------------------------
+# Default: http://backports.debian.org/debian-backports/
+MIRRORCHROOTBACKPORTS=""
+
+# Derivative package mirror used by the live system
+# -------------------------------------------------
+MIRRORBINARY=""
+
+# Derivatives security package mirror used by the live system
+# -----------------------------------------------------------
+MIRRORBINARYSECURITY=""
+
+# Derivatives update package mirror used by the live system
+# ---------------------------------------------------------
+MIRRORBINARYUPDATES=""
+
+# Derivatives backports package mirror used by the live system
+# ------------------------------------------------------------
+MIRRORBINARYBACKPORTS=""
+
+# Derivatives mirror used to fetch Debian installer images
+# --------------------------------------------------------
+# Default: $MIRRORBOOTSTRAP
+MIRRORDEBIANINSTALLER=""
+
+
+
+# Short language setting.
+# -----------------------
+# Short language definition, i.e. "en", "de", ...
+# Leave empty for automatic selection (language currently used).
+LANGSHORT=""
+
+# Full locale setting.
+# --------------------
+# Full language definition including region and encoding, i.e.
+# "en_US.utf8", "de_DE.utf8" ...
+# Leave empty for automatic selection (language currently used).
+LANGFULL=""
+
+# List of locales to append to kernel parameters.
+# -----------------------------------------------
+# Full language definition including region and encoding, i.e.
+# "en_US.utf8", "de_DE.utf8" ...
+# Leave empty for automatic selection (language currently used).
+# Set
+# LIVEAPPENDLOCALES="-"
+# to avoid appending locales.
+LIVEAPPENDLOCALES=""
+
+# Timezone to append to kernel parameters.
+# ----------------------------------------
+# Specify a continent/city combination, i.e. "Europe/Berlin"...
+# Leave empty for automatic selection (currently used timezone).
+# Set
+# LIVEAPPENDTIMEZONE="-"
+# to avoid appending a timezone
+LIVEAPPENDTIMEZONE=""
+
+# List of keyboard layouts to append to kernel parameters.
+# --------------------------------------------------------
+# Leave empty for automatic selection (short language name).
+# Set
+# LIVEAPPENDKBDLAYOUTS="-"
+# to avoid appending keyboard layouts
+LIVEAPPENDKBDLAYOUTS=""
+
+# VGA mode to append to kernel parameters.
+# ----------------------------------------
+# Only used for CLI live systems, ignored if GUI=yes.
+# Set to empty string to append no VGA setting and let the system choose one.
+# Use LIVEAPPENDVGA="0x0F00" to stay at 25 lines x 80 columns.
+# LIVEAPPENDVGA=""
+LIVEAPPENDVGA="0x0F00"
+
+# IP settings to append to kernel parameters.
+# -------------------------------------------
+# Arguments for ip=... kernel parameter.
+# Leave empty to omit the kernel parameter.
+# Normally DHCP is enabled by default (without the kernel parameter).
+# For nfsroot images DHCP is disabled by default, so you should enable
+# it here.
+#
+# Either device:address:netmask:gateway:nameserver:
+# LIVEAPPENDIP="eth0:192.0.2.42:255.255.255.0:192.0.2.1:192.0.2.50"
+# Or one from the methods below:
+# Use DHCP protocol
+# LIVEAPPENDIP="dhcp"
+# Use older BOOTP protocol
+# LIVEAPPENDIP="bootp"
+# Use older RARP protocol
+# LIVEAPPENDIP="rarp"
+# Use all three: DHCP, BOOTP, RARP
+# LIVEAPPENDIP="on"
+# LIVEAPPENDIP="any"
+# Not documented
+# LIVEAPPENDIP="both"
+# Inspect the live systems /etc/network/interfaces file
+# LIVEAPPENDIP="frommedia"
+# Disable networking (use neither DHCP, BOOTP or RARP)
+# LIVEAPPENDIP="none"
+# LIVEAPPENDIP="off"
+LIVEAPPENDIP=""
+
+# Keyboard mapping to use when booting a command line (non-GUI) live system.
+# --------------------------------------------------------------------------
+# Keyboard mapping file in subdirectories of the /usr/share/keymaps directory.
+# The keymaps are in the console-data package.
+# Run commands like:
+# for i in `find /usr/share/keymaps -name '*.kmap.gz'`
+# do
+# echo '#####' $i
+# gzip -dc $i | grep '^#'
+# echo ''
+# done
+# to see comments from the available map files.
+# Leave empty for automatic selection (depending on language).
+# NOTE: Automatic selection means guessing.
+# Set
+# CONSKEYMAP="-"
+# to avoid loading a keyboard mapping.
+CONSKEYMAP=""
+
+# NTP server to query during boot process.
+# ----------------------------------------
+# Host name or IP address of NTP server to query during boot.
+# Leave empty to omit the query.
+# If USENTPDAEMON="yes", the server is queried periodically by ntpd instead
+# of running ntpdate once at boot.
+NTPSERVER=""
+
+# Use NTP daemon.
+# ---------------
+# Boolean flag, "yes" or "no".
+USENTPDAEMON="no"
+
+# Beep when boot menu is shown.
+# -----------------------------
+# Boolean flag, use "yes" to make the boot menu beep.
+# The beep might inform visually impaired or blind people about the presence
+# of the boot menu, so they can append kernel options for screen readers...
+# When restoring one PC in a computer class while a lecture is in progress,
+# any noise disturbs.
+BOOTMENUBEEP="yes"
+
+# Live system publisher name.
+# ---------------------------
+# Use your full name here.
+# PUBLISHER="John Smith"
+PUBLISHER=""
+
+#
+#
+# ##### END OF CONFIGURATION SECTION #####
+
+
+
+# There should be no need to apply changes below this line!
+
+
+
+# ##### Automatically complete setup
+#
+#
+
+EXVAL="0"
+
+if [ "X$LANGSHORT" = "X" ]
+then
+ LANGSHORT=`echo $LANG | cut -f 1 -d '.' | cut -f 1 -d _`
+fi
+if [ "X$LANGFULL" = "X" ]
+then
+ LANGFULL=`grep "^LANG=" /etc/default/locale | cut -f 2 -d '"'`
+fi
+if [ "X$LANGFULL" = "X" ]
+then
+ LANGFULL="$LANG"
+fi
+if [ "X$LIVEAPPENDLOCALES" = "X" -a "X$LANGFULL" != "X" ]
+then
+ echo sed change UTF-8 encoding
+ LIVEAPPENDLOCALES=`echo $LANGFULL | sed -e 's/UTF\-8/utf8/g'`
+fi
+if [ "X$LIVEAPPENDKBDLAYOUTS" = "X" -a "X$LANGSHORT" != "X" ]
+then
+ LIVEAPPENDKBDLAYOUTS="$LANGSHORT"
+fi
+if [ "X$LIVEAPPENDTIMEZONE" = "X" -a -f /etc/timezone ]
+then
+ LIVEAPPENDTIMEZONE=`cat /etc/timezone`
+fi
+LANGREG=`echo $LANGFULL | cut -f 1 -d .`
+if [ "X$PUBLISHER" = "X" ]
+then
+ PUBLISHER=`getent passwd | grep "^${LOGNAME}:" | cut -f 5 -d :`
+fi
+if [ "X$PUBLISHER" = "X" ]
+then
+ PUBLISHER="An Unknown Live System Creator"
+fi
+if [ "X$DATADIR" = "X" ]
+then
+ DATADIR="/usr/local/livesys"
+fi
+[ "X$LIVETYPE" != "X" ] || LIVETYPE="hybrid"
+if [ "X$APTRECOMMENDS" != "Xyes" -a "X$APTRECOMMENDS" != "Xno" ]
+then
+ APTRECOMMENDS="yes"
+fi
+
+
+# ----- Start of console keymapping subsection
+#
+#
+
+# Guess console keymap from language.
+# The _last_ line in each branch wins.
+# So change line order within branches to change priority.
+
+# This subsection may need correction, as I only know about keyboards
+# for german language.
+
+if [ "X$CONSKEYMAP" = "X" ]
+then
+ case "X$LANGSHORT" in
+ "Xar")
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/ar.kmap.gz"
+ ;;
+ "Xbe")
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/by.kmap.gz"
+ ;;
+ "Xbg")
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/bg-cp1251.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/bg.kmap.gz"
+ ;;
+ "Xbr")
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/br-abnt2.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/br-latin1.kmap.gz"
+ ;;
+ "Xcs")
+ CONSKEYMAP="/usr/share/keymaps/sun/sunt5-cz-us.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/sun/sunt5-us-cz.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwertz/cz-us-qwertz.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/cz-us-qwerty.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/cz-lat2-prog.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/cz-lat2.kmap.gz"
+ ;;
+ "Xda")
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/mac-usb-dk-latin1.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/dk-latin1.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/dk.kmap.gz"
+ ;;
+ "Xde")
+ CONSKEYMAP="/usr/share/keymaps/atari/atari-de-deadkeys.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/atari/atari-de.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/amiga/amiga-de.kmap.gz"
+ [ "X$LANGREG" != "Xde_CH" ] || CONSKEYMAP="/usr/share/keymaps/amiga/amiga-sg.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/sun/sunt5-de-latin1.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/dvorak/dvorak-de.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwertz/mac-usb-de-latin1-nodeadkeys.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwertz/mac-usb-de-latin1.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/mac/mac-ibook-de.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/mac/mac-ibook-de-deadkeys.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/mac/mac-macbook-de.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/mac/mac-de2-ext.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/mac/mac-de-latin1.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/mac/mac-de-latin1-nodeadkeys.kmap.gz"
+ [ "X$LANGREG" != "Xde_CH" ] || CONSKEYMAP="/usr/share/keymaps/i386/qwertz/mac-usb-de_CH.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwertz/de.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwertz/de-latin1-nodeadkeys.kmap.gz"
+ ;;
+ "Xen")
+ [ "X$LANGREG" != "Xen_US" ] || CONSKEYMAP="/usr/share/keymaps/atari/atari-us-deadkeys.kmap.gz"
+ [ "X$LANGREG" != "Xen_US" ] || CONSKEYMAP="/usr/share/keymaps/atari/atari-us.kmap.gz"
+ [ "X$LANGREG" != "Xen_UK" ] || CONSKEYMAP="/usr/share/keymaps/atari/atari-uk-deadkeys.kmap.gz"
+ [ "X$LANGREG" != "Xen_UK" ] || CONSKEYMAP="/usr/share/keymaps/atari/atari-uk.kmap.gz"
+ [ "X$LANGREG" != "Xen_UK" ] || CONSKEYMAP="/usr/share/keymaps/amiga/amiga-us.kmap.gz"
+ [ "X$LANGREG" != "Xen_UK" ] || CONSKEYMAP="/usr/share/keymaps/sun/sunt5-uk.kmap.gz"
+ [ "X$LANGREG" != "Xen_UK" ] || CONSKEYMAP="/usr/share/keymaps/sun/sunt6-uk.kmap.gz"
+ [ "X$LANGREG" != "Xen_UK" ] || CONSKEYMAP="/usr/share/keymaps/i386/dvorak/dvorak-uk.kmap.gz"
+ [ "X$LANGREG" != "Xen_UK" ] || CONSKEYMAP="/usr/share/keymaps/mac/mac-uk.kmap.gz"
+ [ "X$LANGREG" != "Xen_US" ] || CONSKEYMAP="/usr/share/keymaps/mac/mac-us-ext.kmap.gz"
+ [ "X$LANGREG" != "Xen_US" ] || CONSKEYMAP="/usr/share/keymaps/mac/mac-us-std.kmap.gz"
+ [ "X$LANGREG" != "Xen_US" ] || CONSKEYMAP="/usr/share/keymaps/mac/mac-us.kmap.gz"
+ [ "X$LANGREG" != "Xen_UK" ] || CONSKEYMAP="/usr/share/keymaps/i386/qwerty/mac-usb-uk.kmap.gz"
+ [ "X$LANGREG" != "Xen_US" ] || CONSKEYMAP="/usr/share/keymaps/i386/qwerty/mac-usb-us.kmap.gz"
+ [ "X$LANGREG" != "Xen_US" ] || CONSKEYMAP="/usr/share/keymaps/i386/qwerty/us-intl.iso01.kmap.gz"
+ [ "X$LANGREG" != "Xen_US" ] || CONSKEYMAP="/usr/share/keymaps/i386/qwerty/us-intl.iso15.kmap.gz"
+ [ "X$LANGREG" != "Xen_CA" ] || CONSKEYMAP="/usr/share/keymaps/i386/qwerty/us-latin1.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/us.kmap.gz"
+ [ "X$LANGREG" != "Xen_UK" ] || CONSKEYMAP="/usr/share/keymaps/i386/qwerty/uk.kmap.gz"
+ [ "X$LANGREG" != "Xen_CA" ] || CONSKEYMAP="/usr/share/keymaps/i386/qwerty/ca-multi.kmap.gz"
+ ;;
+ "Xel")
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/gr-pc.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/gr-utf8.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/gr.kmap.gz"
+ ;;
+ "Xes")
+ CONSKEYMAP="/usr/share/keymaps/amiga/amiga-es.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/sun/sunt4-es.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/sun/sunt5-es.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/mac/mac-es.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/mac-usb-es.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/es.kmap.gz"
+ ;;
+ "Xet")
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/et.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/et-nodeadkeys.kmap.gz"
+ ;;
+ "Xfa")
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/ar.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/fa.kmap.gz"
+ ;;
+ "Xfi")
+ CONSKEYMAP="/usr/share/keymaps/sun/sunt4-fi-latin1.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/sun/sunt5-fi-latin1.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/mac/mac-fi-latin1.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/mac-usb-fi-latin1.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/fi-latin1.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/se-fi-lat6.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/se-fi-ir209.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/fi.kmap.gz"
+ ;;
+ "Xfr")
+ CONSKEYMAP="/usr/share/keymaps/atari/atari-fr.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/amiga/amiga-fr.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/sun/sunt5-fr-latin1.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/dvorak/dvorak-fr-bepo-utf8.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/dvorak/dvorak-fr-bepo.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/dvorak/dvorak-fr.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/mac/mac-macbook-fr.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/azerty/mac-usb-fr.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/mac/mac-fr-ext.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/mac/mac-fr.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/mac/mac-fr2-ext.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/mac/mac-fr3.kmap.gz"
+ [ "X$LANGREG" != "Xfr_BE" ] || CONSKEYMAP="/usr/share/keymaps/i386/azerty/mac-usb-be.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/azerty/fr-pc.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/azerty/fr-latin0.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/azerty/fr-latin9.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/azerty/fr-latin1.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/azerty/fr-x11.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/azerty/fr.kmap.gz"
+ [ "X$LANGREG" != "Xfr_BE" ] || CONSKEYMAP="/usr/share/keymaps/i386/azerty/wangbe.kmap.gz"
+ [ "X$LANGREG" != "Xfr_BE" ] || CONSKEYMAP="/usr/share/keymaps/i386/azerty/be-latin1.kmap.gz"
+ [ "X$LANGREG" != "Xfr_BE" ] || CONSKEYMAP="/usr/share/keymaps/i386/azerty/be2-latin1.kmap.gz"
+ [ "X$LANGREG" != "Xfr_CH" ] || CONSKEYMAP="/usr/share/keymaps/i386/qwertz/mac-usb-fr_CH-latin1.kmap.gz"
+ [ "X$LANGREG" != "Xfr_CH" ] || CONSKEYMAP="/usr/share/keymaps/i386/qwertz/fr_CH-latin1.kmap.gz"
+ [ "X$LANGREG" != "Xfr_CH" ] || CONSKEYMAP="/usr/share/keymaps/i386/qwertz/fr_CH.kmap.gz"
+ [ "X$LANGREG" != "Xfr_CA" ] || CONSKEYMAP="/usr/share/keymaps/i386/qwerty/cf.kmap.gz"
+ [ "X$LANGREG" != "Xfr_CA" ] || CONSKEYMAP="/usr/share/keymaps/i386/qwerty/ca-multi.kmap.gz"
+ ;;
+ "Xhe")
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/hebrew.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/il-heb.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/il.kmap.gz"
+ ;;
+ "Xhr")
+ CONSKEYMAP="/usr/share/keymaps/i386/qwertz/croat.kmap.gz"
+ ;;
+ "Xhu")
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/hu101.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwertz/hu.kmap.gz"
+ ;;
+ "Xis")
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/is-latin1-us.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/is-latin1.kmap.gz"
+ ;;
+ "Xit")
+ CONSKEYMAP="/usr/share/keymaps/amiga/amiga-it.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/mac/ibook-it.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/mac/mac-it.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/azerty/mac-usb-it.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/it-ibm.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/it.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/it2.kmap.gz"
+ ;;
+ "Xja")
+ CONSKEYMAP="/usr/share/keymaps/sun/sunt4-ja.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/sun/sunt5-ja.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/pc110.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/jp106.kmap.gz"
+ ;;
+ "Xkk")
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/kk.kmap.gz"
+ ;;
+ "Xky")
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/kg.kmap.gz"
+ ;;
+ "Xla")
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/la-latin1.kmap.gz"
+ ;;
+ "Xlt")
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/lt.l4.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/lt.kmap.gz"
+ ;;
+ "Xlv")
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/lv-latin4.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/lv-latin7.kmap.gz"
+ ;;
+ "Xmk")
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/mk.kmap.gz"
+ ;;
+ "Xnl")
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/nl.kmap.gz"
+ [ "X$LANGREG" != "Xnl_BE" ] || CONSKEYMAP="/usr/share/keymaps/i386/azerty/mac-usb-be.kmap.gz"
+ [ "X$LANGREG" != "Xnl_BE" ] || CONSKEYMAP="/usr/share/keymaps/i386/azerty/wangbe.kmap.gz"
+ [ "X$LANGREG" != "Xnl_BE" ] || CONSKEYMAP="/usr/share/keymaps/i386/azerty/be-latin1.kmap.gz"
+ [ "X$LANGREG" != "Xnl_BE" ] || CONSKEYMAP="/usr/share/keymaps/i386/azerty/be2-latin1.kmap.gz"
+ ;;
+ "Xno")
+ CONSKEYMAP="/usr/share/keymaps/sun/sunt4-no-latin1.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/sun/sunt5-no.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/no.kmap.gz"
+ ;;
+ "Xpl")
+ CONSKEYMAP="/usr/share/keymaps/sun/sun-pl.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/sun/sun-pl-altgraph.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/mac/mac-pl_m-ext1.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwertz/pl-qwertz.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/pl.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/pl1.kmap.gz"
+ ;;
+ "Xpt")
+ CONSKEYMAP="/usr/share/keymaps/mac/mac-pt-latin1.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwertz/mac-usb-pt-latin1.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/pt-old.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/pt-latin1.kmap.gz"
+ ;;
+ "Xro")
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/ro-comma.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/ro-academic.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/ro.kmap.gz"
+ ;;
+ "Xru")
+ CONSKEYMAP="/usr/share/keymaps/sun/sunt5-ru.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/dvorak/dvorak-ru.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/ru_win.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/ru-yawerty.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/ru-ms.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/ru-cp1251.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/ru.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/ru1.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/ru2.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/ru3.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/ru4.kmap.gz"
+ ;;
+ "Xse")
+ CONSKEYMAP="/usr/share/keymaps/atari/atari-se.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/atari/atari-se-deadkeys.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/amiga/amiga-se.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/mac/mac-se.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/mac-usb-se.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/se-ir209.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/se-fi-lat6.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/se-fi-ir209.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/se-latin1.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/se-lat6.kmap.gz"
+ ;;
+ "Xsg")
+ CONSKEYMAP="/usr/share/keymaps/i386/qwertz/sg-latin1.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwertz/sg.kmap.gz"
+ ;;
+ "Xsk")
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/sk-prog.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/sk-prog-qwerty.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwertz/sk-prog-qwertz.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/sk-qwerty.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwertz/sk-qwertz.kmap.gz"
+ ;;
+ "Xsl")
+ CONSKEYMAP="/usr/share/keymaps/i386/qwertz/slovene.kmap.gz"
+ ;;
+ "Xsr")
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/sr-cy.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwertz/sr.kmap.gz"
+ ;;
+ "Xth")
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/th-tis.kmap.gz"
+ ;;
+ "Xtr")
+ CONSKEYMAP="/usr/share/keymaps/sun/sunt5-trqalt.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/tr_q-latin5.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/tralt.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/trq.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/fgGIod/trfu.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/fgGIod/tr_f-latin5.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/fgGIod/trf.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/trqu.kmap.gz"
+ ;;
+ "Xuk")
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/ua.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/uaw_uni.kmap.gz"
+ CONSKEYMAP="/usr/share/keymaps/i386/qwerty/uaw.kmap.gz"
+ ;;
+ "Xwo")
+ CONSKEYMAP="/usr/share/keymaps/i386/azerty/wo.kmap.gz"
+ ;;
+ esac
+fi
+
+#
+#
+# ----- Start of console keymapping subsection
+
+
+
+# Check whether setup is completed.
+# ---------------------------------
+if [ "X$CONFIGURED" = "Xno" ]
+then
+ echo 'ERROR: Script not configured yet!'
+ echo 'Please edit the scripts configuration section.'
+ echo 'The section is located at start of file, below the copyright notice.'
+ exit 1
+fi
+
+
+# Check for root privileges
+# -------------------------
+if [ "X$LOGNAME" != "Xroot" ]
+then
+ echo 'ERROR: Root privileges required!'
+ echo 'Please run this script as user root only.'
+ exit 1
+fi
+
+
+# Save current working directory.
+DIR=`pwd`
+if [ "X$DIR" = "X" ]
+then
+ echo 'ERROR: Failed to find current directory name!'
+ exit 1
+fi
+
+
+echo Start
+date
+
+# Inherited umask may be wrong.
+umask 022
+
+# Build live system on up-to-date host.
+if [ "X$ALLOWUPGRADE" = "Xyes" ]
+then
+ apt-get -y update && apt-get -y upgrade
+fi
+
+# Make sure to have all required packages for build and live build.
+apt-get install `sed -e 's/[ \t]*#.*$//g' livesys-data/pkg_local.txt`
+
+
+# Create live system directory.
+[ ! -d livesys ] || rm -fr livesys
+mkdir -p livesys
+chmod 755 livesys
+
+# Configure and build the software, do not install yet.
+./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var --enable-shared --disable-static --enable-packaging --with-suite=rescue --with-man=yes
+make
+
+OPTCONF=""
+
+if [ "X$LIVETYPE" = "Xnfs" -a "X$NFSSERVER" != "X" -a "X$NFSPATH" != "X" ]
+then
+ OPTCONF="$OPTCONF -b netboot"
+ OPTCONF="$OPTCONF --net-root-server $NFSSERVER"
+ OPTCONF="$OPTCONF --net-root-path $NFSPATH"
+elif [ "X$LIVETYPE" = "Xhdd" ]
+then
+ OPTCONF="$OPTCONF -b hdd"
+elif [ "X$LIVETYPE" = "Xnfs" ]
+then
+ echo 'ERROR: Missing NFSSERVER and/or NFSPATH configuration!'
+ exit 1
+fi
+
+
+# No apt index files in live system to save disk space
+OPTCONF="$OPTCONF --apt-indices false"
+
+# Avoid installation of recommended packages to save disk space
+if [ "X$GUI" != "Xyes" -a "X$APTRECOMMENDS" != "Xyes" ]
+then
+ OPTCONF="$OPTCONF --apt-recommends false"
+fi
+
+# Minimum base bootstrap
+OPTCONF="$OPTCONF --debootstrap-options --variant=minbase"
+
+# Include firmware into live system
+# It depends on the ALLOWNONFREE setting whether or not non-free firmware
+# is added to the live system:
+# no: Only free firmware files are used.
+# yes: Free and non-free firmware files are used.
+OPTCONF="$OPTCONF --firmware-chroot true"
+
+# No firmware in the binary stage, the live system does not contain installers.
+OPTCONF="$OPTCONF --firmware-binary false"
+
+# No memory test program in live system
+OPTCONF="$OPTCONF --memtest none"
+
+# Do not required valid signatures
+if [ "X$ALLOWUNSIGNEDPKG" = "Xyes" ]
+then
+ OPTCONF="$OPTCONF --apt-secure false"
+fi
+
+if [ "X$PARENTMIRRORBOOTSTRAP" != "X" ]
+then
+ OPTCONF="$OPTCONF --parent-mirror-bootstrap $PARENTMIRRORBOOTSTRAP"
+fi
+
+if [ "X$PARENTMIRRORCHROOT" != "X" ]
+then
+ OPTCONF="$OPTCONF --parent-mirror-chroot $PARENTMIRRORCHROOT"
+fi
+
+if [ "X$PARENTMIRRORCHROOTSECURITY" != "X" ]
+then
+ OPTCONF="$OPTCONF --parent-mirror-chroot-security $PARENTMIRRORCHROOTSECURITY"
+fi
+
+if [ "X$PARENTMIRRORCHROOTUPDATES" != "X" ]
+then
+ OPTCONF="$OPTCONF --parent-mirror-chroot-updates $PARENTMIRRORCHROOTUPDATES"
+fi
+
+if [ "X$PARENTMIRRORCHROOTBACKPORTS" != "X" ]
+then
+ OPTCONF="$OPTCONF --parent-mirror-chroot-backports $PARENTMIRRORCHROOTBACKPORTS"
+fi
+
+if [ "X$PARENTMIRRORBINARY" != "X" ]
+then
+ OPTCONF="$OPTCONF --parent-mirror-binary $PARENTMIRRORBINARY"
+fi
+
+if [ "X$PARENTMIRRORBINARYSECURITY" != "X" ]
+then
+ OPTCONF="$OPTCONF --parent-mirror-binary-security $PARENTMIRRORBINARYSECURITY"
+fi
+
+if [ "X$PARENTMIRRORBINARYUPDATES" != "X" ]
+then
+ OPTCONF="$OPTCONF --parent-mirror-binary-updates $PARENTMIRRORBINARYUPDATES"
+fi
+
+if [ "X$PARENTMIRRORBINARYBACKPORTS" != "X" ]
+then
+ OPTCONF="$OPTCONF --parent-mirror-binary-backports $PARENTMIRRORBINARYBACKPORTS"
+fi
+
+if [ "X$PARENTMIRRORDEBIANINSTALLER" != "X" ]
+then
+ OPTCONF="$OPTCONF --parent-mirror-debian-installer $PARENTMIRRORDEBIANINSTALLER"
+fi
+
+if [ "X$MIRRORBOOTSTRAP" != "X" ]
+then
+ OPTCONF="$OPTCONF --mirror-bootstrap $MIRRORBOOTSTRAP"
+fi
+
+if [ "X$MIRRORCHROOT" != "X" ]
+then
+ OPTCONF="$OPTCONF --mirror-chroot $MIRRORCHROOT"
+fi
+
+if [ "X$MIRRORCHROOTSECURITY" != "X" ]
+then
+ OPTCONF="$OPTCONF --mirror-chroot-security $MIRRORCHROOTSECURITY"
+fi
+
+if [ "X$MIRRORCHROOTUPDATES" != "X" ]
+then
+ OPTCONF="$OPTCONF --mirror-chroot-updates $MIRRORCHROOTUPDATES"
+fi
+
+if [ "X$MIRRORCHROOTBACKPORTS" != "X" ]
+then
+ OPTCONF="$OPTCONF --mirror-chroot-backports $MIRRORCHROOTBACKPORTS"
+fi
+
+if [ "X$MIRRORBINARY" != "X" ]
+then
+ OPTCONF="$OPTCONF --mirror-binary $MIRRORBINARY"
+fi
+
+if [ "X$MIRRORBINARYSECURITY" != "X" ]
+then
+ OPTCONF="$OPTCONF --mirror-binary-security $MIRRORBINARYSECURITY"
+fi
+
+if [ "X$MIRRORBINARYUPDATES" != "X" ]
+then
+ OPTCONF="$OPTCONF --mirror-binary-updates $MIRRORBINARYUPDATES"
+fi
+
+if [ "X$MIRRORBINARYBACKPORTS" != "X" ]
+then
+ OPTCONF="$OPTCONF --mirror-binary-backports $MIRRORBINARYBACKPORTS"
+fi
+
+if [ "X$MIRRORDEBIANINSTALLER" != "X" ]
+then
+ OPTCONF="$OPTCONF --mirror-debian-installer $MIRRORDEBIANINSTALLER"
+fi
+
+# Live system requires configuration
+OPTLIVEAPPEND="boot=live components live-config.utc=no"
+
+# Add configuration hints
+if [ "X$LIVEAPPENDLOCALES" != "X" -a "X$LIVEAPPENDLOCALES" != "X-" ]
+then
+ OPTLIVEAPPEND="$OPTLIVEAPPEND live-config.locales=$LIVEAPPENDLOCALES locales=$LIVEAPPENDLOCALES"
+fi
+if [ "X$LIVEAPPENDKBDLAYOUTS" != "X" -a "X$LIVEAPPENDKBDLAYOUTS" != "X-" ]
+then
+ OPTLIVEAPPEND="$OPTLIVEAPPEND live-config.keyboard-layouts=$LIVEAPPENDKBDLAYOUTS"
+fi
+if [ "X$LIVEAPPENDTIMEZONE" != "X" -a "X$LIVEAPPENDTIMEZONE" != "X-" ]
+then
+ OPTLIVEAPPEND="$OPTLIVEAPPEND live-config.timezone=$LIVEAPPENDTIMEZONE"
+fi
+if [ "X$LIVEAPPENDVGA" != "X" -a "X$GUI" != "Xyes" ]
+then
+ OPTLIVEAPPEND="$OPTLIVEAPPEND nomodeset vga=$LIVEAPPENDVGA"
+fi
+if [ "X$LIVEAPPENDIP" != "X" ]
+then
+ OPTLIVEAPPEND="$OPTLIVEAPPEND ip=$LIVEAPPENDIP"
+fi
+if [ "X$LIVETYPE" = "Xnfs" ]
+then
+ OPTLIVEAPPEND="$OPTLIVEAPPEND netboot=nfs nfsroot=${NFSSERVER}:${NFSPATH}"
+fi
+
+[ "X$PUBLISHER" != "X" ] || PUBLISHER="An Unknown Live System Builder"
+PKGLOC=""
+
+cd livesys
+ lb init
+ if [ "X$ALLOWNONFREE" = "Xyes" -a "X$ALLOWUNSIGNEDPKG" = "Xyes" ]
+ then
+ lb config \
+ $OPTCONF \
+ --archive-areas "main contrib non-free" \
+ --apt-options "--yes --allow-unauthenticated" \
+ --iso-publisher "$PUBLISHER" \
+ --iso-volume DKTOOLIAN \
+ --bootappend-live "$OPTLIVEAPPEND"
+ elif [ "X$ALLOWNONFREE" = "Xyes" ]
+ then
+ lb config \
+ $OPTCONF \
+ --archive-areas "main contrib non-free" \
+ --apt-options "--yes" \
+ --iso-publisher "$PUBLISHER" \
+ --iso-volume DKTOOLIAN \
+ --bootappend-live "$OPTLIVEAPPEND"
+ elif [ "X$ALLOWUNSIGNEDPKG" = "Xyes" ]
+ then
+ lb config \
+ $OPTCONF \
+ --apt-options "--yes --allow-unauthenticated" \
+ --iso-publisher "$PUBLISHER" \
+ --iso-volume DKTOOLIAN \
+ --bootappend-live "$OPTLIVEAPPEND"
+ else
+ lb config \
+ $OPTCONF \
+ --apt-options "--yes" \
+ --iso-publisher "$PUBLISHER" \
+ --iso-volume DKTOOLIAN \
+ --bootappend-live "$OPTLIVEAPPEND"
+ fi
+ echo sed remove comments
+ if [ ! -d config/archives ]
+ then
+ mkdir -p config/archives
+ chmod 755 config/archives
+ fi
+ if [ ! -d config/includes.chroot ]
+ then
+ mkdir -p config/includes.chroot
+ chmod 755 config/includes.chroot
+ fi
+ if [ ! -d config/includes.chroot/usr/share/doc/dktools ]
+ then
+ mkdir -p config/includes.chroot/usr/share/doc/dktools
+ chmod 755 config/includes.chroot/usr/share/doc/dktools
+ fi
+ if [ ! -d config/includes.chroot/etc/apt ]
+ then
+ mkdir -p config/includes.chroot/etc/apt
+ chmod 755 config/includes.chroot/etc/apt
+ fi
+ for i in README LICENSE bsdlic.txt version.txt
+ do
+ cp ../$i config/includes.chroot/usr/share/doc/dktools/$i
+ chmod 644 config/includes.chroot/usr/share/doc/dktools/$i
+ done
+ cp ../debian/copyright config/includes.chroot/usr/share/doc/copyright
+ chmod 644 config/includes.chroot/usr/share/doc/copyright
+ # cp ../livesys-data/apt-pinning.txt config/archives/apt-pinning.pref.chroot
+ cp ../livesys-data/apt-pinning.txt config/includes.chroot/etc/apt/preferences
+ if [ "X$ALLOWNONFREE" = "Xyes" ]
+ then
+ sed -e 's/[ \t]*#.*$//g' < ../livesys-data/pkg_firmware.txt >> config/package-lists/dktoolian.list.chroot
+ fi
+ echo sed remove comments
+ sed -e 's/[ \t]*#.*$//g' < ../livesys-data/pkg_base.txt >> config/package-lists/dktoolian.list.chroot
+ if [ "X$GUI" = "Xyes" ]
+ then
+ echo sed remove comments
+ sed -e 's/[ \t]*#.*$//g' < ../livesys-data/pkg_xfce.txt >> config/package-lists/dktoolian.list.chroot
+ fi
+ if [ "X$NTPSERVER" != "X" -a "X$USENTPDAEMON" = "Xyes" ]
+ then
+ echo ntp >> config/package-lists/dktoolian.list.chroot
+ else
+ echo ntpdate >> config/package-lists/dktoolian.list.chroot
+ fi
+ case "X$LANGSHORT" in
+ "Xaf")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ if [ "X$GUI" = "Xyes" ]
+ then
+ echo "iceweasel-l10n-af" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xam")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-amharic"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="$PKGLOC task-amharic-desktop"
+ fi
+ ;;
+ "Xan")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ if [ "X$GUI" = "Xyes" ]
+ then
+ echo "iceweasel-l10n-an" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xar")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-arabic"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-arabic task-arabic-desktop"
+ echo "iceweasel-l10n-ar" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xast")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-asturian"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-asturian task-asturian-desktop"
+ echo "iceweasel-l10n-ast" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xaz")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ if [ "X$GUI" = "Xyes" ]
+ then
+ echo "iceweasel-l10n-az" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xbe")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-belarusian"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-belarusian task-belarusian-desktop"
+ echo "iceweasel-l10n-be" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xbg")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-bulgarian"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-bulgarian task-bulgarian-desktop"
+ echo "iceweasel-l10n-bg" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xbn")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-bengali"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-bengali task-bengali-desktop"
+ if [ "X$LANGREG" = "Xbn_BD" ]
+ then
+ echo "iceweasel-l10n-bn-bd" >> config/package-lists/dktoolian.list.chroot
+ else
+ echo "iceweasel-l10n-bn-in" >> config/package-lists/dktoolian.list.chroot
+ fi
+ fi
+ ;;
+ "Xbr")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ if [ "X$GUI" = "Xyes" ]
+ then
+ echo "iceweasel-l10n-br" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xbs")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-bosnian"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-bosnian task-bosnian-desktop"
+ echo "iceweasel-l10n-bs" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xca")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-catalan"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-catalan task-catalan-desktop"
+ echo "iceweasel-l10n-ca" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xcs")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-czech"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-czech task-czech-desktop"
+ echo "iceweasel-l10n-cs" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xcy")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-welsh"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-welsh task-welsh-desktop"
+ echo "iceweasel-l10n-cy" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xda")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-danish"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-danish task-danish-desktop"
+ echo "iceweasel-l10n-da" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xde")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-german"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-german task-german-desktop"
+ echo "iceweasel-l10n-de" >> config/package-lists/dktoolian.list.chroot
+ fi
+ if [ "X$GUI" = "Xyes" -a "X$LANGREG" = "Xde_DE" ]
+ then
+ echo "iceweasel-l10n-dsb" >> config/package-lists/dktoolian.list.chroot
+ echo "iceweasel-l10n-hsb" >> config/package-lists/dktoolian.list.chroot
+ fi
+ if [ "X$GUI" = "Xyes" -a "X$LANGREG" = "Xde_CH" ]
+ then
+ echo "iceweasel-l10n-rm" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xdz")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-dzongkha"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-dzongkha task-dzongkha-desktop"
+ fi
+ ;;
+ "Xel")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-greek"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-greek task-greek-desktop"
+ echo "iceweasel-l10n-el" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xen")
+ echo "locales" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-english"
+ if [ "X$GUI" = "Xyes" -a "X$LANGREN" = "Xen_GB" ]
+ then
+ PKGLOC="task-english task-british-desktop"
+ echo "iceweasel-l10n-en-gb" >> config/package-lists/dktoolian.list.chroot
+ echo "iceweasel-l10n-gd" >> config/package-lists/dktoolian.list.chroot
+ elif [ "X$GUI" = "Xyes" -a "X$LANGREN" = "Xen_ZA" ]
+ then
+ PKGLOC="task-english task-south-african-english-desktop"
+ echo "iceweasel-l10n-en-za" >> config/package-lists/dktoolian.list.chroot
+ echo "iceweasel-l10n-af" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xeo")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-esperanto"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-esperanto task-esperanto-desktop"
+ echo "iceweasel-l10n-eo" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xes")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-spanish"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-spanish task-spanish-desktop"
+ fi
+ if [ "X$GUI" = "Xyes" -a "X$LANGREG" = "Xes_AR" ]
+ then
+ echo "iceweasel-l10n-es-ar" >> config/package-lists/dktoolian.list.chroot
+ elif [ "X$GUI" = "Xyes" -a "X$LANGREG" = "Xes_CL" ]
+ then
+ echo "iceweasel-l10n-es-cl" >> config/package-lists/dktoolian.list.chroot
+ elif [ "X$GUI" = "Xyes" -a "X$LANGREG" = "Xes_MX" ]
+ then
+ echo "iceweasel-l10n-es-mx" >> config/package-lists/dktoolian.list.chroot
+ else
+ echo "iceweasel-l10n-es-es" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xet")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-estonian"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-estonian task-estonian-desktop"
+ echo "iceweasel-l10n-et" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xeu")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-basque"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-basque task-basque-desktop"
+ echo "iceweasel-l10n-eu" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xfa")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-persian"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-persian task-persian-desktop"
+ echo "iceweasel-l10n-fa" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xff")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ if [ "X$GUI" = "Xyes" ]
+ then
+ echo "iceweasel-l10n-ff" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xfi")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-finnish"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-finnish task-finnish-desktop"
+ echo "iceweasel-l10n-fi" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xfr")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-french"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-french task-french-desktop"
+ echo "iceweasel-l10n-fr" >> config/package-lists/dktoolian.list.chroot
+ fi
+ if [ "X$GUI" = "Xyes" -a "X$LANGREG" = "Xfr_CH" ]
+ then
+ echo "iceweasel-l10n-rm" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xfub")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ if [ "X$GUI" = "Xyes" ]
+ then
+ echo "iceweasel-l10n-ff" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xfue")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ if [ "X$GUI" = "Xyes" ]
+ then
+ echo "iceweasel-l10n-ff" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xfuh")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ if [ "X$GUI" = "Xyes" ]
+ then
+ echo "iceweasel-l10n-ff" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xfui")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ if [ "X$GUI" = "Xyes" ]
+ then
+ echo "iceweasel-l10n-ff" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xfuq")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ if [ "X$GUI" = "Xyes" ]
+ then
+ echo "iceweasel-l10n-ff" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xfuv")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ if [ "X$GUI" = "Xyes" ]
+ then
+ echo "iceweasel-l10n-ff" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xfy")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ if [ "X$GUI" = "Xyes" ]
+ then
+ echo "iceweasel-l10n-fy-nl" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xga")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-irish"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-irish task-irish-desktop"
+ echo "iceweasel-l10n-ga-ie" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xgl")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-galician"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-galician task-galician-desktop"
+ echo "iceweasel-l10n-gl" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xgu")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-gujarati"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-gujarati task-gujarati-desktop"
+ echo "iceweasel-l10n-gu-in" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xhe")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-hebrew"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ echo "task-hebrew-desktop" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-hebrew task-hebrew-desktop"
+ echo "iceweasel-l10n-he" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xhi")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-hindi"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-hindi task-hindi-desktop"
+ echo "iceweasel-l10n-hi-in" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xhr")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-croatian"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-croatian task-croatian-desktop"
+ echo "iceweasel-l10n-hr" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xhu")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-hungarian"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-hungarian task-hungarian-desktop"
+ echo "iceweasel-l10n-hu" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xhy")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ if [ "X$GUI" = "Xyes" ]
+ then
+ echo "iceweasel-l10n-hy-am" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xid")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-indonesian-desktop"
+ echo "iceweasel-l10n-id" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xis")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-icelandic"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ echo "task-icelandic-desktop" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-icelandic task-icelandic-desktop"
+ echo "iceweasel-l10n-is" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xit")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-italian"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-italian task-italian-desktop"
+ echo "iceweasel-l10n-it" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xja")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-japanese"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-japanese task-japanese-desktop"
+ echo "iceweasel-l10n-ja" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xka")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-cyrillic"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-cyrillic task-cyrillic-desktop task-georgian-desktop"
+ echo "iceweasel-l10n-ar" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xkk")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-kazakh"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-kazakh task-kazakh-desktop"
+ echo "iceweasel-l10n-kk" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xkm")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-khmer"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-khmer task-khmer-desktop"
+ echo "iceweasel-l10n-km" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xkn")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-kannada-desktop"
+ echo "iceweasel-l10n-kn" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xko")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-korean"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-korean task-korean-desktop"
+ echo "iceweasel-l10n-ko" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xku")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-kurdish"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-kurdish task-kurdish-desktop"
+ fi
+ ;;
+ "Xlij")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ if [ "X$GUI" = "Xyes" ]
+ then
+ echo "iceweasel-l10n-lij" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xlt")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-lithuanian"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-lithuanian task-lithuanian-desktop"
+ echo "iceweasel-l10n-lt" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xlv")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-latvian"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-latvian task-latvian-desktop"
+ echo "iceweasel-l10n-lv" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xmai")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ if [ "X$GUI" = "Xyes" ]
+ then
+ echo "iceweasel-l10n-mai" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xmk")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-macedonian"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-macedonian task-macedonian-desktop"
+ echo "iceweasel-l10n-mk" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xml")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-malayalam"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-malayalam task-malayalam-desktop"
+ echo "iceweasel-l10n-ml" >> config/package-lists/dktoolian.list.chroot
+ echo "iceweasel-l10n-ms" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xmr")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-marathi"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-marathi task-marathi-desktop"
+ echo "iceweasel-l10n-mr" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xms")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ if [ "X$GUI" = "Xyes" ]
+ then
+ echo "iceweasel-l10n-ms" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xne")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-nepali-desktop"
+ fi
+ ;;
+ "Xnl")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-dutch"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-dutch task-dutch-desktop"
+ echo "iceweasel-l10n-nl" >> config/package-lists/dktoolian.list.chroot
+ echo "iceweasel-l10n-fy-nl" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xnb")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-norwegian"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-norwegian task-norwegian-desktop"
+ echo "iceweasel-l10n-nb-no" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xnn")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-norwegian"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-norwegian task-norwegian-desktop"
+ echo "iceweasel-l10n-nn-no" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xno")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-norwegian"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-norwegian task-norwegian-desktop"
+ echo "iceweasel-l10n-nb-no" >> config/package-lists/dktoolian.list.chroot
+ echo "iceweasel-l10n-nn-no" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xor")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ if [ "X$GUI" = "Xyes" ]
+ then
+ echo "iceweasel-l10n-or" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xpa")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-punjabi"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-punjabi task-punjabi-desktop"
+ echo "iceweasel-l10n-pa-in" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xpl")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-polish"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-polish task-polish-desktop"
+ echo "iceweasel-l10n-pl" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xpt")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ if [ "X$LANGREG" = "Xpt_BR" ]
+ then
+ PKGLOC="task-brazilian-portuguese"
+ else
+ PKGLOC="task-portuguese"
+ fi
+ if [ "X$LANGREG" = "Xpt_BR" -a "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-brazilian-portuguese task-brazilian-portuguese-desktop"
+ echo "iceweasel-l10n-pt-br" >> config/package-lists/dktoolian.list.chroot
+ elif [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-portuguese task-portuguese-desktop"
+ echo "iceweasel-l10n-pt-pt" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xrm")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ if [ "X$GUI" = "Xyes" ]
+ then
+ echo "iceweasel-l10n-rm" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xro")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-romanian"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-romanian task-romanian-desktop"
+ echo "iceweasel-l10n-ro" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xru")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-cyrillic task-russian"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="$PKGLOC task-cyrillic-desktop task-russian-desktop"
+ echo "iceweasel-l10n-ru" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xse")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-northern-sami"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-northern-sami task-northern-sami-desktop"
+ fi
+ ;;
+ "Xses")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ if [ "X$GUI" = "Xyes" ]
+ then
+ echo "iceweasel-l10n-son" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xsi")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-sinhala-desktop"
+ echo "iceweasel-l10n-si" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xsk")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-slovak"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-slovak task-slovak-desktop"
+ echo "iceweasel-l10n-sk" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xsl")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-slovenian"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-slovenian task-slovenian-desktop"
+ echo "iceweasel-l10n-sl" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xson")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ if [ "X$GUI" = "Xyes" ]
+ then
+ echo "iceweasel-l10n-son" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xsq")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-albanian-desktop"
+ echo "iceweasel-l10n-sq" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xsr")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-serbian"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-serbian task-serbian-desktop"
+ echo "iceweasel-l10n-sr" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xsv")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-swedish"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-swedish task-swedish-desktop"
+ echo "iceweasel-l10n-sv-se" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xta")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-tamil"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-tamil task-tamil-desktop"
+ echo "iceweasel-l10n-ta" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xte")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-telugu"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-telugu task-telugu-desktop"
+ echo "iceweasel-l10n-te" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xth")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-thai"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-thai task-thai-desktop"
+ echo "iceweasel-l10n-th" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xtr")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-turkish"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-turkish task-turkish-desktop"
+ echo "iceweasel-l10n-tr" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xug")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-uyghur"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-uyghur task-uyghur-desktop"
+ fi
+ ;;
+ "Xuk")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-ukrainian"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-ukrainian task-ukrainian-desktop"
+ echo "iceweasel-l10n-uk" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xuz")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ if [ "X$GUI" = "Xyes" ]
+ then
+ echo "iceweasel-l10n-uz" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xvi")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-vietnamese-desktop"
+ echo "iceweasel-l10n-vi" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xxh")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="task-xhosa-desktop"
+ echo "iceweasel-l10n-xh" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "Xza")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ PKGLOC="task-chinese-s task-chinese-t"
+ if [ "X$GUI" = "Xyes" ]
+ then
+ PKGLOC="$PKGLOC task-chinese-s-desktop task-chinese-t-desktop"
+ fi
+ if [ "X$GUI" = "Xyes" -a "X$LANGREG" = "Xzh_TW" ]
+ then
+ echo "iceweasel-l10n-zh-tw" >> config/package-lists/dktoolian.list.chroot
+ else
+ echo "iceweasel-l10n-zh-cn" >> config/package-lists/dktoolian.list.chroot
+ fi
+ ;;
+ "*")
+ echo "locales-all" >> config/package-lists/dktoolian.list.chroot
+ echo sed remove comments
+ sed -e 's/[ \t]*#.*$//g' < ../livesys-data/pkg_lang_base.txt >> config/package-lists/dktoolian.list.chroot
+ if [ "X$GUI" = "Xyes" ]
+ then
+ echo sed remove comments
+ sed -e 's/[ \t]*#.*$//g' < ../livesys-data/pkg_lang_desktop.txt >> config/package-lists/dktoolian.list.chroot
+
+ fi
+ ;;
+ esac
+ chmod 644 config/package-lists/dktoolian.list.chroot
+ if [ "X$CONSKEYMAP" != "X" -a "X$CONSKEYMAP" != "X-" -a "X$GUI" != "Xyes" ]
+ then
+ echo sed correct console keymap name
+cat - > config/hooks/0500-console-keyboard.hook.chroot <<EOF
+#! /bin/sh
+set -e
+echo HOOK chroot 0500-console-keyboard.hook.chroot
+sed -i -e '/^[ \t]*exit.*0/cloadkeys $CONSKEYMAP\nexit 0\n' /etc/rc.local
+EOF
+ chmod 755 config/hooks/0500-console-keyboard.hook.chroot
+ fi
+cd ..
+
+
+
+# Create /etc/default/locale and /etc/timezone
+if [ ! -d "${DIR}/livesys/config/includes.chroot" ]
+then
+ mkdir -p "${DIR}/livesys/config/includes.chroot"
+ chmod 755 "${DIR}/livesys/config/includes.chroot"
+fi
+if [ ! -d "${DIR}/livesys/config/includes.chroot/etc/default" ]
+then
+ mkdir -p "${DIR}/livesys/config/includes.chroot/etc/default"
+ chmod 755 "${DIR}/livesys/config/includes.chroot/etc/default"
+fi
+make DESTDIR="${DIR}/livesys/config/includes.chroot" install
+if [ "X$LANGFULL" != "X" ]
+then
+ echo "# File generated by update-locale" > "${DIR}/livesys/config/includes.chroot/etc/default/locale"
+ echo "LANG=$LANGFULL" >> "${DIR}/livesys/config/includes.chroot/etc/default/locale"
+ chmod 755 "${DIR}/livesys/config/includes.chroot/etc/default/locale"
+fi
+if [ "X$LIVEAPPENDTIMEZONE" != "X" ]
+then
+ echo $LIVEAPPENDTIMEZONE > "${DIR}/livesys/config/includes.chroot/etc/timezone"
+fi
+
+
+
+# Copy additional data.
+# Step 1: Files shipped with DK tools
+[ -d ${DIR}/livesys/config/includes.chroot ] || mkdir -p ${DIR}/livesys/config/includes.chroot
+(cd "${DIR}/livesys-data/root" ; tar cf - .) | (cd ${DIR}/livesys/config/includes.chroot ; tar xf -)
+
+if [ "X$GUI" = "Xyes" -a -d "${DIR}/livesys-data/root-gui" ]
+then
+ (cd "${DIR}/livesys-data/root-gui" ; tar cf - .) | (cd ${DIR}/livesys/config/includes.chroot ; tar xf -)
+fi
+
+if [ "X$GUI" != "Xyes" -a -d "${DIR}/livesys-data/root-cli" ]
+then
+ (cd "${DIR}/livesys-data/root-cli" ; tar cf - .) | (cd ${DIR}/livesys/config/includes.chroot ; tar xf -)
+fi
+
+# Step 2: Files created by user
+if [ "X${DATADIR}" != "X-" -a -d "${DATADIR}" ]
+then
+ (cd "${DATADIR}" ; tar cf - .) | (cd ${DIR}/livesys/config/includes.chroot ; tar xf -)
+fi
+if [ "X${DATADIR}" != "X-" -a -d "${DATADIR}-cli" -a "X$GUI" != "Xyes" ]
+then
+ (cd "${DATADIR}-cli" ; tar cf - .) | (cd ${DIR}/livesys/config/includes.chroot ; tar xf -)
+fi
+if [ "X${DATADIR}" != "X-" -a -d "${DATADIR}-gui" -a "X$GUI" = "Xyes" ]
+then
+ (cd "${DATADIR}-gui" ; tar cf - .) | (cd ${DIR}/livesys/config/includes.chroot ; tar xf -)
+fi
+
+# Step 3: Ownership and permissions
+chown -R root:root "${DIR}/livesys/config/includes.chroot"
+find "${DIR}/livesys/config/includes.chroot" -type d -exec chmod ugo+rx {} \;
+find "${DIR}/livesys/config/includes.chroot" -type f -exec chmod ugo+r {} \;
+
+
+
+# Hooks
+
+# chroot stage: Copy files from /usr/share/dktoolian/etc to /etc
+cp "${DIR}/livesys-data/hook_etcfiles.txt" "${DIR}/livesys/config/hooks/0501-etcfiles.hook.chroot"
+chmod 755 "${DIR}/livesys/config/hooks/0501-etcfiles.hook.chroot"
+
+# chroot stage: Modify /etc/rc.local to copy files to /etc again
+cat - > "${DIR}/livesys/config/hooks/0502-etc-files-again.hook.chroot" <<EOF
+#! /bin/sh
+echo HOOK chroot 0502-etc-files-again.hook.chroot
+sed -i -f /usr/share/dktoolian/etc-files.sed /etc/rc.local
+rm /usr/share/dktoolian/etc-files.sed
+EOF
+
+# chroot stage: Automatic login as root for CLI boot
+if [ "X$GUI" != "Xyes" ]
+then
+ cp "${DIR}/livesys-data/hook_autologin.txt" "${DIR}/livesys/config/hooks/0503-autologin.hook.chroot"
+ chmod 755 "${DIR}/livesys/config/hooks/0503-autologin.hook.chroot"
+fi
+
+# chroot stage: Install localization packages without recommended packages
+if [ "X$PKGLOC" != "X" ]
+then
+ touch ${DIR}/livesys/config/package-lists/localize.list.chroot
+ chmod 644 ${DIR}/livesys/config/package-lists/localize.list.chroot
+ for locpkg in $PKGLOC
+ do
+ echo $locpkg >> ${DIR}/livesys/config/package-lists/localize.list.chroot
+ done
+ # echo "#! /bin/sh" > "${DIR}/livesys/config/hooks/0504-localize.hook.chroot"
+ # echo "echo HOOK 0504-localize.hook.chroot" >> "${DIR}/livesys/config/hooks/0504-localize.hook.chroot"
+ # echo "apt-get update && apt-get --no-install-recommends --yes install $PKGLOC" >> "${DIR}/livesys/config/hooks/0504-localize.hook.chroot"
+ # chmod 755 "${DIR}/livesys/config/hooks/0504-localize.hook.chroot"
+fi
+
+# chroot stage: NTP query during system boot
+cat - > ${DIR}/livesys/config/includes.chroot/usr/share/dktoolian/ntpserver.sed <<EOF
+/^[ \t]*exit[ \t][ \t]*0[ \t]*$/cntpdate ${NTPSERVER} > /dev/null 2>&1\nexit 0
+
+EOF
+echo '#! /bin/sh' > "${DIR}/livesys/config/hooks/0505-ntpdate.hook.chroot"
+if [ "X$NTPSERVER" != "X" -a "X$USENTPDAEMON" != "Xyes" ]
+then
+ echo "sed -i -f /usr/share/dktoolian/ntpserver.sed /etc/rc.local" >> "${DIR}/livesys/config/hooks/0505-ntpdate.hook.chroot"
+fi
+echo "# rm -fr /usr/share/dktoolian/ntpserver.sed" >> "${DIR}/livesys/config/hooks/0505-ntpdate.hook.chroot"
+echo "/usr/local/bin/dktoolian-ntp $NTPSERVER" >> "${DIR}/livesys/config/hooks/0505-ntpdate.hook.chroot"
+echo "rm -fr /usr/local/bin/dktoolian-ntp" >> "${DIR}/livesys/config/hooks/0505-ntpdate.hook.chroot"
+echo "rm -fr /usr/share/dktoolian/ntp.conf.template" >> "${DIR}/livesys/config/hooks/0505-ntpdate.hook.chroot"
+chmod 755 "${DIR}/livesys/config/hooks/0505-ntpdate.hook.chroot"
+
+# binary stage: modify boot menu, avoid installation items
+
+BOOTMENUCFG="binary/isolinux/menu.cfg"
+ISOLINUXCFG="binary/isolinux/isolinux.cfg"
+SPLASHPNG="binary/isolinux/splash.png"
+if [ "X$LIVETYPE" = "Xnfs" ]
+then
+ BOOTMENUCFG="tftpboot/menu.cfg"
+ ISOLINUXCFG="tftpboot/pxelinux.cfg/default"
+ SPLASHPNG="tftpboot/splash.png"
+fi
+
+cat - > ${DIR}/livesys/config/hooks/0990-isolinux.hook.binary <<EOF
+#! /bin/sh
+echo HOOK binary 0990-isolinux.hook.binary
+EOF
+if [ "X$BOOTMENUBEEP" != "Xyes" ]
+then
+ echo "sed -i -f \"${DIR}/livesys-data/sed_nobeep.txt\" \"${DIR}/livesys/${BOOTMENUCFG}\"" >> "${DIR}/livesys/config/hooks/0990-isolinux.hook.binary"
+fi
+cat - >> ${DIR}/livesys/config/hooks/0990-isolinux.hook.binary <<EOF
+sed -i -f "${DIR}/livesys-data/sed_isolinux.txt" "${DIR}/livesys/${ISOLINUXCFG}"
+sed -i -f "${DIR}/livesys-data/sed_menu.txt" "${DIR}/livesys/${BOOTMENUCFG}"
+cp "${DIR}/splash-dktoolian.png" "${DIR}/livesys/${SPLASHPNG}"
+chmod 644 "${DIR}/livesys/${SPLASHPNG}"
+EOF
+chmod 755 "${DIR}/livesys/config/hooks/0990-isolinux.hook.binary"
+
+# Now build live system
+cd livesys
+ echo Building live system
+ lb build || EXVAL="1"
+cd ..
+
+
+
+echo 'MIRROR ' $MIRROR
+echo 'LIVETYPE ' $LIVETYPE
+echo 'GUI ' $GUI
+echo 'LANGSHORT ' $LANGSHORT
+echo 'LANGFULL ' $LANGFULL
+echo 'LIVEAPPENDLOCALES ' $LIVEAPPENDLOCALES
+echo 'LIVEAPPENDTIMEZONE ' $LIVEAPPENDTIMEZONE
+echo 'LIVEAPPENDKBDLAYOUTS' $LIVEAPPENDKBDLAYOUTS
+echo 'LIVEAPPENDVGA ' $LIVEAPPENDVGA
+echo 'CONSKEYMAP ' $CONSKEYMAP
+echo 'PUBLISHER ' $PUBLISHER
+echo 'NFSSERVER ' $NFSSERVER
+echo 'NFSPATH ' $NFSPATH
+echo 'ALLOWUPGRADE ' $ALLOWUPGRADE
+echo 'CONFIGURED ' $CONFIGURED
+
+echo Finished
+date
+
+if [ "X$ALLOWNONFREE" = "Xyes" ]
+then
+ cat "${DIR}/livesys-data/msg_nonfree.txt"
+fi
+
+exit $EXVAL
+
diff --git a/support/dktools/debian-jessie-prepare.sh b/support/dktools/debian-jessie-prepare.sh
new file mode 100755
index 0000000000..4cac8d588e
--- /dev/null
+++ b/support/dktools/debian-jessie-prepare.sh
@@ -0,0 +1,53 @@
+#! /bin/sh
+
+# CORRECTION: Probably the version numbers for libjpeg-turbo and
+# wxWidgets need a change in later Debian versions or on non-Debian systems.
+
+WXVERS="3.0"
+LJTVERS="62"
+
+# Ensure to run the script as root
+
+if [ "X$LOGNAME" != "Xroot" ]
+then
+ echo 'ERROR: This script must be run as root!'
+ exit 1
+fi
+
+
+# Make sure system is up to date
+
+apt-get -y update
+apt-get -y upgrade
+
+
+# Installing everything needed to build a kernel should cover
+# most development tools
+# You should activate (uncomment) the following line only if necessary.
+
+# apt-get -y build-dep kernel
+
+
+# Install developer tools and DK tools library dependencies
+
+P="aptitude build-essential autoconf automake autotools-dev"
+P="$P dh-make debhelper"
+P="$P devscripts fakeroot file gfortran git gnupg fp-compiler"
+P="$P lintian patch patchutils pbuilder perl python"
+P="$P quilt xutils-dev make gcc g++"
+P="$P zlib1g-dev libbz2-dev libssl-dev libdb-dev libmysqlclient-dev"
+P="$P libpng-dev libjpeg-dev libopenjpeg-dev libtiff-dev"
+P="$P libjpeg${LJTVERS}-turbo-dev libsnmp-dev"
+P="$P wx${WXVERS}-headers"
+P="$P libwxgtk${WXVERS}-dev"
+P="$P libwxbase${WXVERS}-dev"
+P="$P libwxsvg-dev"
+apt-get install $P
+
+
+# Finally write hint to switch back to unprivileged user
+
+echo ''
+echo 'Remember to switch back to an unprivileged user to build the DEB file.'
+echo ''
+
diff --git a/support/dktools/debian/README.source b/support/dktools/debian/README.source
new file mode 100644
index 0000000000..60927f95ea
--- /dev/null
+++ b/support/dktools/debian/README.source
@@ -0,0 +1,10 @@
+dktools for Debian
+------------------
+
+<this file describes information about the source package, see Debian policy
+manual section 4.14. You WILL either need to modify or delete this file>
+
+
+
+ -- Dirk Krause <krause.dirk@web.de> Sun, 11 Oct 2015 17:26:12 +0200
+
diff --git a/support/dktools/debian/changelog b/support/dktools/debian/changelog
new file mode 100644
index 0000000000..bc18aa29a8
--- /dev/null
+++ b/support/dktools/debian/changelog
@@ -0,0 +1,830 @@
+# DO NOT EDIT THIS FILE!
+# It is generated automatically from the dktools-el6.spec.in
+# file.
+dktools (4.8.3-1) unstable; urgency=low
+
+ * Followed improvement suggestions from the CTAN team.
+
+ -- Dirk Krause <krause.dirk@web.de> Tue, 28 Mar 2017 20:00:00 +0200
+
+
+dktools (4.8.2-1) unstable; urgency=low
+
+ * Modified bmpp to write a /CropBox in addition to /MediaBox in PDF output.
+
+ -- Dirk Krause <krause.dirk@web.de> Fri, 24 Mar 2017 20:00:00 +0200
+
+
+dktools (4.8.1-1) unstable; urgency=low
+
+ * Modified dk-send to stop reading input if all clients disconnected
+ unexpectedly.
+
+ -- Dirk Krause <krause.dirk@web.de> Wed, 22 Mar 2017 20:00:00 +0200
+
+
+dktools (4.8.0-1) unstable; urgency=low
+
+ * Library libdk4maioxd added (wxChar numbers input and output).
+ * Package lshw added to package list for DKtoolian.
+ * Configure script and Makefile.in modified to have less warnings from
+ Debian package building.
+
+ -- Dirk Krause <krause.dirk@web.de> Sun, 19 Mar 2017 20:00:00 +0200
+
+
+dktools (4.7.0-1) unstable; urgency=low
+
+ * "xxxx" can be used as copyright end year in the "copyright year"
+ setting in options sections of *.ctr, *.wxc and *.cpt files.
+ * New modules dk4paper and dk4papea to read papersizes configuration
+ files.
+
+ -- Dirk Krause <krause.dirk@web.de> Fri, 03 Feb 2017 20:00:00 +0200
+
+
+dktools (4.6.0-1) unstable; urgency=low
+
+ * New functions in dk4memrs, dk4str8, dk4strw and dk4str to sanitize
+ buffers and strings.
+
+ -- Dirk Krause <krause.dirk@web.de> Sun, 11 Dec 2016 20:00:00 +0200
+
+
+dktools (4.5.0-1) unstable; urgency=low
+
+ * Added support for meta/description and meta/keywords tags to htmlbook.
+ * New modules for arithmetic operations on int16_t, uint16_t, int32_t, uint32_t.
+ * New modules to serialize data to stream, unserialize from stream.
+ * New module for compressed/encoded output on a dk4_stream_t.
+
+ -- Dirk Krause <krause.dirk@web.de> Thu, 27 Oct 2016 20:00:00 +0200
+
+
+dktools (4.4.0-1) unstable; urgency=low
+
+ * Configuration option for itadmin to release lease on shutdown.
+ * Markers in dhcpd.conf produced by itadmin for easier post-processing.
+ * New module dk4strmw to open a file stream for writing.
+ * New module dk4fpe to check for floating point exceptions.
+ * New modules to read double from string and write double to string.
+ * Mathematical operations on int16_t, int32_t, uint16_t and uint32_t
+ including error checking.
+ * Inline functions or macros to copy, reset and compare memory buffers.
+ * Modules dk4mai8dbl, dk4maiddbl, dk4maiwdbl, dk4mao8dbl, dk4maoddbl
+ and dk4maowdbl to read double from string and write double to string.
+ * API change in dk4stream_write(): the buffer argument is const now.
+ * Optimization in dk4stream_write().
+ * Bugfixes in GUI applications: No wxXXX objects must survive OnExit().
+ * Bugfixes in the dk4strw module.
+ * Bugfixes in checking for mysql.h file.
+ * Code cleanup in DkWxBmepsApp.cpt, DkWxImgszApp.cpt and DkWxTraceApp.cpt
+ to improve readability.
+
+ -- Dirk Krause <krause.dirk@web.de> Wed, 07 Sep 2016 20:00:00 +0200
+
+
+dktools (4.3.6-1) unstable; urgency=low
+
+ * Bugfix for Windows (try multiple sources to get home directory).
+ * Replacements for GetVersionEx() function in Windows.
+ * Docu update for installation using stow.
+
+ -- Dirk Krause <krause.dirk@web.de> Tue, 12 Jul 2016 20:00:00 +0200
+
+
+dktools (4.3.5-1) unstable; urgency=low
+
+ * New hint special command for htmlbook.
+ * Scripts to produce live systems.
+
+ -- Dirk Krause <krause.dirk@web.de> Sat, 02 Jul 2016 20:00:00 +0200
+
+
+dktools (4.3.4-1) unstable; urgency=low
+
+ * Added span.hint to style.css for htmlbook.
+ * Smaller changes related to Debian packaging.
+
+ -- Dirk Krause <krause.dirk@web.de> Fri, 10 Jun 2016 20:00:00 +0200
+
+
+dktools (4.3.3-1) unstable; urgency=low
+
+ * Debian packaging changed, developer package is dktools-lib-$(SOVERS)-dev.
+ * RPM packaging changed, shared library symlinks now in devel package.
+ * New script to generate debian/changelog from dktools-el6.spec.in file.
+
+ -- Dirk Krause <krause.dirk@web.de> Sat, 28 May 2016 20:00:00 +0200
+
+
+dktools (4.3.2-1) unstable; urgency=low
+
+ * New special command "htmlname" in htmlbook program.
+ * Directory structure in build process changed due to lintian complaints.
+ * Bugfix in dktools.pc, Libs.private now set correctly.
+ * Script itaclean.sh renamed to itaclean (due to lintian complaints).
+
+ -- Dirk Krause <krause.dirk@web.de> Fri, 27 May 2016 20:00:00 +0200
+
+
+dktools (4.3.1-1) unstable; urgency=low
+
+ * Printqdc now accepts empty input lines.
+
+ -- Dirk Krause <krause.dirk@web.de> Mon, 25 Apr 2016 20:00:00 +0200
+
+
+dktools (4.3.0-1) unstable; urgency=low
+
+ * Printqd and related programs rewritten completely.
+ * Rshdown is back on a users request, ported to library version 4.
+ * Print order character 'N' added to dk-ls (do not show symlink target).
+ * Option -b for dk-pwgen on non-Windows systems (create binary random data).
+ * New program dk-rand to generate binary random data.
+ * Modifications to dk4_app_t and dk3_app_t modules: create log and tmp
+ directories only when needed.
+ * Modified dk4inst.h header: Compiler constant texts for directories.
+ * Module dk4dmt added, tool functions for standing daemons.
+ * Modified dk4sock13 module, delete existing UNIX domain sockets.
+ * Modified DkWxFrame and Dk4WxFrame, restore position when frame is shown.
+ * Bugfix in dkwxwiz data files, typo corrected.
+ * Bugfix in dk4dbi module, must set ulen, not size when retrieving data.
+ * Retired dk3sock module, all networking programs use library version 4 now.
+
+ -- Dirk Krause <krause.dirk@web.de> Tue, 19 Apr 2016 20:00:00 +0200
+
+
+dktools (4.2.2-1) unstable; urgency=low
+
+ * Modified dk-cat, dk-hex, dk-pwgen, dk-t2h, dk-t2l, dk-db2t:
+ No error message for SIGPIPE received.
+ * Some modifications following suggestions from clang static code analysis.
+
+ -- Dirk Krause <krause.dirk@web.de> Fri, 22 Jan 2016 20:00:00 +0200
+
+
+dktools (4.2.1-1) unstable; urgency=low
+
+ * Modifications in Makefile.in and scripts/dkmkproto.pl for SVR4 packaging.
+
+ -- Dirk Krause <krause.dirk@web.de> Tue, 19 Jan 2016 20:00:00 +0200
+
+
+dktools (4.2.0-1) unstable; urgency=low
+
+ * Performance fix for dk-send/dk-recv: Use larger buffers.
+ * Performance fix for dk-ls: Avoid unnecessary size calculations.
+ * Programs dk-t2db, dk-db2t and dk-dbco to replace dkdbt.
+ * Libraries dk4dbia and dk4dbi added to replace dk3dbi.
+ * Bugfix in dk4loc module, set encoding even if no LANG variable available.
+
+ -- Dirk Krause <krause.dirk@web.de> Mon, 18 Jan 2016 20:00:00 +0200
+
+
+dktools (4.1.0-1) unstable; urgency=low
+
+ * Added -s option to dk-ls, show summary at end.
+ * Manpage installation avoided, when building on Debian
+ (manpage installation on Debian is done by package management).
+ * New functions to retrieve and expand strings from Windows registry.
+ * Changes in makefiles for Visual Studio for Desktop on Windows.
+ * Bugfix in dk4user module: Must expand user profile string from registry.
+ * Bugfix in DkClockFrame.wxc: Minimum size specified.
+ * Bugfix in DkWxImgszFrame.wxc: Format specifier corrected.
+ * Bugfix in DkWxImgszApp.cpt: Load all image handlers wxInitAllImageHandlers()
+
+ -- Dirk Krause <krause.dirk@web.de> Mon, 14 Dec 2015 20:00:00 +0200
+
+
+dktools (4.0.10-1) unstable; urgency=low
+
+ * Man pages added, required for Debian packaging.
+ * Build process on Windows can now use different library directories.
+ * Bugfix in dkdbt program: No longer error messages for comment lines.
+ * First release after changing Linux distribution to Debian on my laptop.
+
+ -- Dirk Krause <krause.dirk@web.de> Fri, 04 Dec 2015 20:00:00 +0200
+
+
+dktools (4.0.9-1) unstable; urgency=low
+
+ * Bugfix in Makefile.in: Some programs were mentioned twice.
+
+ -- Dirk Krause <krause.dirk@web.de> Tue, 10 Nov 2015 20:00:00 +0200
+
+
+dktools (4.0.8-1) unstable; urgency=low
+
+ * Number of duplicated files in source archive reduced by use of hard links.
+
+ -- Dirk Krause <krause.dirk@web.de> Sun, 08 Nov 2015 20:00:00 +0200
+
+
+dktools (4.0.7-1) unstable; urgency=low
+
+ * Bugfix in dk4loc module: Use "en" as default language.
+ * Bugfix in configure.ac: Install shared libraries for rescue systems too.
+
+ -- Dirk Krause <krause.dirk@web.de> Fri, 16 Oct 2015 20:00:00 +0200
+
+
+dktools (4.0.6-1) unstable; urgency=low
+
+ * Added -t option to dk-sort.
+ * Only one AC_OUTPUT line in Makefile.in.
+
+ -- Dirk Krause <krause.dirk@web.de> Sat, 10 Oct 2015 20:00:00 +0200
+
+
+dktools (4.0.5-1) unstable; urgency=low
+
+ * Help text for dk-recv corrected, host and port are mandatory.
+ * Compiler flags for wxcs added in Makefile.in.
+ * Removed some dead assignments after static analysis.
+
+ -- Dirk Krause <krause.dirk@web.de> Tue, 06 Oct 2015 20:00:00 +0200
+
+
+dktools (4.0.4-1) unstable; urgency=low
+
+ * Makefile.in: Use C++ compiler to drive linker if any C++ module in project.
+ * Makefile.in: libdk4wx.a in the LIB_ST_GUI group, not LIB_ST_CLI.
+ * dktools.pc.in: Correct variable for version number used now.
+ * dk3strkv/dk-sqlsplit: S_ERROR replaced by ST_ERROR.
+ * configure.ac: No -Bdynamic -dy -KPIC -D_REENTRANT for static builds.
+ * configure.ac: Option --with-corrections for some Solaris systems.
+
+ -- Dirk Krause <krause.dirk@web.de> Wed, 23 Sep 2015 20:00:00 +0200
+
+
+dktools (4.0.3-1) unstable; urgency=low
+
+ * Module dk3uc2l rewritten to use the *.t2l files.
+
+ -- Dirk Krause <krause.dirk@web.de> Tue, 11 Aug 2015 20:00:00 +0200
+
+
+dktools (4.0.2-1) unstable; urgency=low
+
+ * Setting for tooltip flag added to dkct.
+
+ -- Dirk Krause <krause.dirk@web.de> Tue, 04 Aug 2015 20:00:00 +0200
+
+
+dktools (4.0.1-1) unstable; urgency=low
+
+ * dkct: Special placeholders in $? format string.
+ * dkct: Option -p added for portable debug output code.
+
+ -- Dirk Krause <krause.dirk@web.de> Tue, 04 Aug 2015 20:00:00 +0200
+
+
+dktools (4.0.0-1) unstable; urgency=low
+
+ * New rewritten library modules dk4*.
+ * Simplified error reporting from callee to caller via dk4_er_t structure.
+ * Reduced use of runtime library on Windows systems.
+ * Text stream processing functions recognize BOM at start of data.
+ * Multiple dk4sock* modules instead of one large module.
+ * wxdkfcs: GUI program to inspect file checksums.
+ * dkt: Replaced by multiple smaller programs.
+ * dkct: Cell contents for wxGrid in wx gui section.
+
+ -- Dirk Krause <krause.dirk@web.de> Tue, 04 Aug 2015 20:00:00 +0200
+
+
+dktools (3.18.10-1) unstable; urgency=low
+
+ * dk-tape: Code simplified.
+
+ -- Dirk Krause <krause.dirk@web.de> Thu, 09 Jul 2015 20:00:00 +0200
+
+
+dktools (3.18.9-1) unstable; urgency=low
+
+ * Modified configure script and Makefile for --enable-packaging option.
+
+ -- Dirk Krause <krause.dirk@web.de> Thu, 02 Apr 2015 20:00:00 +0200
+
+
+dktools (3.18.8-1) unstable; urgency=low
+
+ * Modified configure script and Makefile.
+
+ -- Dirk Krause <krause.dirk@web.de> Fri, 13 Mar 2015 20:00:00 +0200
+
+
+dktools (3.18.7-1) unstable; urgency=low
+
+ * dkct: Bugfix, doxygen allows pure @file lines.
+
+ -- Dirk Krause <krause.dirk@web.de> Sat, 21 Feb 2015 20:00:00 +0200
+
+
+dktools (3.18.6-1) unstable; urgency=low
+
+ * Bugfix in plpdftex: smash used only for texts aligned by base line.
+
+ -- Dirk Krause <krause.dirk@web.de> Wed, 28 Jan 2015 20:00:00 +0200
+
+
+dktools (3.18.5-1) unstable; urgency=low
+
+ * Bugfix in dkt tape: wrong number printed.
+ * Bugfix in plpdftex: smash not for texts in boxes.
+ * Modified pjsnmp: Added pjsnmpreadystates configuration option
+ * Modified pjsnmp: Message texts modified, distinction errors/warnings.
+
+ -- Dirk Krause <krause.dirk@web.de> Thu, 22 Jan 2015 20:00:00 +0200
+
+
+dktools (3.18.4-1) unstable; urgency=low
+
+ * Bugfix in plpdftex: sometimes invalid *.tex output.
+
+ -- Dirk Krause <krause.dirk@web.de> Mon, 08 Dec 2014 20:00:00 +0200
+
+
+dktools (3.18.3-1) unstable; urgency=low
+
+ * Bugfix in UTF-16 encoding: Surrogate range was wrong.
+
+ -- Dirk Krause <krause.dirk@web.de> Mon, 01 Dec 2014 20:00:00 +0200
+
+
+dktools (3.18.2-1) unstable; urgency=low
+
+ * Modified dkct: No @file line added if @file line is already present.
+ * Data type dk3_c32_t changed to unsigned if unsigned is 4 bytes long.
+ * Check whether password memory really was reset.
+
+ -- Dirk Krause <krause.dirk@web.de> Wed, 26 Nov 2014 20:00:00 +0200
+
+
+dktools (3.18.1-1) unstable; urgency=low
+
+ * Bugfix in multiplication overflow detection in dk3mas/dk3mai/dk3mal modules.
+
+ -- Dirk Krause <krause.dirk@web.de> Tue, 21 Oct 2014 20:00:00 +0200
+
+
+dktools (3.18.0-1) unstable; urgency=low
+
+ * Copyright year check in dkct.
+ * API bugfix in dk3str32/dk3str16: Use correct character size now.
+ * Bugfix in htmlbook for using dkChar.
+ * Bugfix in dkdbt for using dkChar.
+ * Splitted dk3mastr module into several modules.
+ * Most uses of sscanf() and dk3sf_sscanf3() replaced by other functions.
+
+ -- Dirk Krause <krause.dirk@web.de> Thu, 16 Oct 2014 20:00:00 +0200
+
+
+dktools (3.17.2-1) unstable; urgency=low
+
+ * Bugfix in dk3sock: WSAEWOULDBLOCK is used for connect in progress.
+
+ -- Dirk Krause <krause.dirk@web.de> Wed, 24 Sep 2014 20:00:00 +0200
+
+
+dktools (3.17.1-1) unstable; urgency=low
+
+ * Bugfix in archive creation: Permissions are correct now.
+
+ -- Dirk Krause <krause.dirk@web.de> Fri, 12 Sep 2014 20:00:00 +0200
+
+
+dktools (3.17.0-1) unstable; urgency=low
+
+ * Appendices k, M, G for block size added for dkt blks/ dkt ed/dkt rnd.
+ * Bugfix in fig2lat: EPS/PDF/PGF output driver, corner radius.
+ * Bugfix in wxbmpp dk3paper module.
+ * Bugfix in wxbmpp: Fitting to a paper size.
+
+ -- Dirk Krause <krause.dirk@web.de> Wed, 03 Sep 2014 20:00:00 +0200
+
+
+dktools (3.16.3-1) unstable; urgency=low
+
+ * Changed build process for Linux/Unix.
+
+ -- Dirk Krause <krause.dirk@web.de> Thu, 07 Aug 2014 20:00:00 +0200
+
+
+dktools (3.16.2-1) unstable; urgency=low
+
+ * Changed build process for Linux/Unix, removed options from configure.
+
+ -- Dirk Krause <krause.dirk@web.de> Tue, 05 Aug 2014 20:00:00 +0200
+
+
+dktools (3.16.1-1) unstable; urgency=low
+
+ * Use wxFD_OPEN instead of wxOPEN.
+ * Bugfix in makefile: CLFAGS was a typo.
+
+ -- Dirk Krause <krause.dirk@web.de> Tue, 05 Aug 2014 20:00:00 +0200
+
+
+dktools (3.16.0-1) unstable; urgency=low
+
+ * New program plpdftex added, output driver for octpgfpl.
+ * Prefer sigaction() over sigset().
+ * Function-like macros replaced by functions.
+ * Modified overflow check for conversion from unsigned long to size_t.
+ * Modified dk3ma module: Splitted into several smaller modules.
+ * Functions dk3strm_double_c8_no_sci()... added.
+ * Function dk3pdf_write_double() treats small numbers as 0.
+
+ -- Dirk Krause <krause.dirk@web.de> Mon, 28 Jul 2014 20:00:00 +0200
+
+
+dktools (3.15.0-1) unstable; urgency=low
+
+ * Source code reorganized.
+
+ -- Dirk Krause <krause.dirk@web.de> Sat, 28 Jun 2014 20:00:00 +0200
+
+
+dktools (3.14.0-1) unstable; urgency=low
+
+ * Options -S... added to dkct and wxdkct.
+ * Memory usage reorganized for bit matrices.
+ * Cache friendly algorithm for bit matrix expansion.
+ * dktools.spec file modified to build sub-packages lib and devel.
+
+ -- Dirk Krause <krause.dirk@web.de> Thu, 19 Jun 2014 20:00:00 +0200
+
+
+dktools (3.13.0-1) unstable; urgency=low
+
+ * Modified htmlbook: Line numbering for source code.
+ * Modified dkt html: Line numbering for source code.
+ * Added *.desktop files for GUI programs.
+
+ -- Dirk Krause <krause.dirk@web.de> Tue, 27 May 2014 20:00:00 +0200
+
+
+dktools (3.12.0-1) unstable; urgency=low
+
+ * New application wxdkhtb added to view help text files.
+ * Modified htmlbook: enable/disable full text search in *.chm output.
+ * Installation bugfix: Forgot to install libdk3wx.so.
+ * HTML files for online help now created by htmlbook.
+ * API change in DkWxFrame class: Methods added.
+
+ -- Dirk Krause <krause.dirk@web.de> Wed, 30 Apr 2014 20:00:00 +0200
+
+
+dktools (3.11.0-1) unstable; urgency=low
+
+ * htmlbook: Writing project.xml file.
+ * htmlbook: New option chm full text search.
+ * htmlbook: Section number optional before section title in index and pos.
+ * htmlbook: Titles for links in keyword index.
+ * htmlbook: Bugfix, all *.html files listed in files section.
+ * htmlbook: Bugfix, added missing closing OBJECT tag.
+ * htmlbook: Bugfix, copy index.hhp, index.hhc and index.hhk to destination.
+ * htmlbook: Bugfix, root object now in TOC as first object.
+ * printqd: Attempt to remove existing local socket before creating new one.
+ * printqd: Bugfix, endless loop.
+ * wxdkclock: Save changed options immediately.
+
+ -- Dirk Krause <krause.dirk@web.de> Wed, 23 Apr 2014 20:00:00 +0200
+
+
+dktools (3.10.0-1) unstable; urgency=low
+
+ * Modified fig2lat: Fast splines for arrowheads.
+ * Modified fig2lat: Configurable base line width.
+
+ -- Dirk Krause <krause.dirk@web.de> Mon, 31 Mar 2014 20:00:00 +0200
+
+
+dktools (3.9.0-1) unstable; urgency=low
+
+ * Bugfix in bmpp/wxbmpp: Bits per component analysis rewritten.
+
+ -- Dirk Krause <krause.dirk@web.de> Mon, 24 Mar 2014 20:00:00 +0200
+
+
+dktools (3.8.3-1) unstable; urgency=low
+
+ * Bugfix bmpp/wxbmpp: Automatic bits per component analysis disabled.
+ * Modified htmlbook: New classes for table cells added to style.css file.
+
+ -- Dirk Krause <krause.dirk@web.de> Sun, 02 Mar 2014 20:00:00 +0200
+
+
+dktools (3.8.2-1) unstable; urgency=low
+
+ * Modified htmlbook: New no-vspace option for img special command.
+ * Modified htmlbook: Shortcuts for images.
+
+ -- Dirk Krause <krause.dirk@web.de> Thu, 06 Feb 2014 20:00:00 +0200
+
+
+dktools (3.8.1-1) unstable; urgency=low
+
+ * Modified htmlbook: Set permissions for destination directory contents.
+ * Modified htmlbook: Change in style.css, added top and bottom margin.
+ * Bugfix in htmlbook: Crashes on filenames without suffix.
+
+ -- Dirk Krause <krause.dirk@web.de> Wed, 29 Jan 2014 20:00:00 +0200
+
+
+dktools (3.8.0-1) unstable; urgency=low
+
+ * New application htmlbook added.
+ * Bugfix in dk3enc module: Wrong range delimiter for Unicode characters.
+
+ -- Dirk Krause <krause.dirk@web.de> Tue, 21 Jan 2014 20:00:00 +0200
+
+
+dktools (3.7.0-1) unstable; urgency=low
+
+ * Modified dkt latex: Euro currency symbol added to translation table.
+ * Modified dkma: long long, unsigned long long, intmax_t, uintmax_t.
+
+ -- Dirk Krause <krause.dirk@web.de> Fri, 29 Nov 2013 20:00:00 +0200
+
+
+dktools (3.6.0-1) unstable; urgency=low
+
+ * Modified fig2lat: New cofop option for filled open graphics paths.
+ * Bugfix in fig2lat: Must encode some characters.
+ * Modified dk3ma: Function and constants names changed for consistent naming.
+
+ -- Dirk Krause <krause.dirk@web.de> Thu, 14 Nov 2013 20:00:00 +0200
+
+
+dktools (3.5.0-1) unstable; urgency=low
+
+ * Modified wxbmpp: No automatic start when running on a directory.
+
+ -- Dirk Krause <krause.dirk@web.de> Wed, 23 Oct 2013 20:00:00 +0200
+
+
+dktools (3.4.0-1) unstable; urgency=low
+
+ * Modified dkt blocksize: Performance optimizations, use memcpy().
+ * Modified dk3sock module: Handle incomplete send requests.
+ * Modified dk3str module: Use existing functions if available.
+
+ -- Dirk Krause <krause.dirk@web.de> Tue, 01 Oct 2013 20:00:00 +0200
+
+
+dktools (3.3.3-1) unstable; urgency=low
+
+ * Option -s for dkt blocksize added.
+ * Modified itadmin: Increased possible length for DHCP options values.
+ * Bugfix in itadmin: DHCP options for hosts are written now.
+
+ -- Dirk Krause <krause.dirk@web.de> Fri, 20 Sep 2013 20:00:00 +0200
+
+
+dktools (3.3.2-1) unstable; urgency=low
+
+ * Modified dk3sto module: Keyword const added to some functions.
+
+ -- Dirk Krause <krause.dirk@web.de> Tue, 30 Jul 2013 20:00:00 +0200
+
+
+dktools (3.3.1-1) unstable; urgency=low
+
+ * Bugfix in distribution and build system.
+
+ -- Dirk Krause <krause.dirk@web.de> Mon, 29 Jul 2013 20:00:00 +0200
+
+
+dktools (3.3.0-1) unstable; urgency=low
+
+ * API change, comparison and evaluation functions operate on const * pointers.
+
+ -- Dirk Krause <krause.dirk@web.de> Sun, 28 Jul 2013 20:00:00 +0200
+
+
+dktools (3.2.2-1) unstable; urgency=low
+
+ * More useful error message for malformed path to dkt ls on Windows
+ (paths in double quotes where backslash escapes closing double quote).
+
+ -- Dirk Krause <krause.dirk@web.de> Wed, 24 Jul 2013 20:00:00 +0200
+
+
+dktools (3.0.6-1) unstable; urgency=low
+
+ * dkct enhanced for unknown classes.
+
+ -- Dirk Krause <krause.dirk@web.de> Thu, 20 Mar 2013 20:00:00 +0200
+
+
+dktools (3.0.5-1) unstable; urgency=low
+
+ * Bugfix: Use AddButton method of wxStdButtonSizer, not Add.
+
+ -- Dirk Krause <krause.dirk@web.de> Wed, 20 Mar 2013 20:00:00 +0200
+
+
+dktools (3.0.4-1) unstable; urgency=low
+
+ * The dk3sock4 module was added.
+
+ -- Dirk Krause <krause.dirk@web.de> Sun, 17 Mar 2013 20:00:00 +0200
+
+
+dktools (3.0.3-1) unstable; urgency=low
+
+ * Online documentation updated for the -f option in dknet.
+
+ -- Dirk Krause <krause.dirk@web.de> Sat, 16 Mar 2013 20:00:00 +0200
+
+
+dktools (3.0.2-1) unstable; urgency=low
+
+ * The dknet program is more verbose now when run as sender.
+
+ -- Dirk Krause <krause.dirk@web.de> Thu, 14 Mar 2013 20:00:00 +0200
+
+
+dktools (3.0.1-1) unstable; urgency=low
+
+ * The dkwxwiz program was added.
+ * The winprint program (for Windows) was added.
+ * The wprclean program (for Windows) was added.
+ * The lprngcl program (for Windows) was added.
+ * Option bbts for fig2lat.
+ * Bugfix in Win32 setup: The dk3paper.conf file was not installed.
+
+ -- Dirk Krause <krause.dirk@web.de> Sun, 03 Feb 2013 20:00:00 +0200
+
+
+dktools (3.0.0-1) unstable; urgency=low
+
+ * Code for 3.0.0 release finished.
+
+ -- Dirk Krause <krause.dirk@web.de> Thu, 31 Jan 2013 20:00:00 +0200
+
+
+dktools (2.2.22-1) unstable; urgency=low
+
+ * Bugfix in the configure script: Unnecessary call to wx-config removed.
+
+ -- Dirk Krause <krause.dirk@web.de> Wed, 02 Nov 2011 20:00:00 +0200
+
+
+dktools (2.2.21-1) unstable; urgency=low
+
+ * The hostsadm.pl script now adds a netgroup triple containing
+ the IP address to the netgroup.ldif file.
+ * The "ctrl database-cleanup" operation for prqd now removes
+ print accounts and page counts with value 0.
+
+ -- Dirk Krause <krause.dirk@web.de> Tue, 01 Nov 2011 20:00:00 +0200
+
+
+dktools (2.2.20-1) unstable; urgency=low
+
+ * Program imgsize renamed to chimgsize to avoid name conflicts
+ with perl-Image-Size RPM.
+
+ -- Dirk Krause <krause.dirk@web.de> Sun, 06 Jun 2011 20:00:00 +0200
+
+
+dktools (2.2.19-1) unstable; urgency=low
+
+ * Bugfix in text2htm, wrong format specification.
+
+ -- Dirk Krause <krause.dirk@web.de> Sun, 19 Apr 2011 20:00:00 +0200
+
+
+dktools (2.2.18-1) unstable; urgency=low
+
+ * The function dkstr_w_cat() (a fallback implementation for systems without
+ the wcscat() function) was added.
+ * New programs kwintool and kwindown for Windows.
+
+ -- Dirk Krause <krause.dirk@web.de> Sun, 14 Nov 2010 20:00:00 +0200
+
+
+dktools (2.2.17-1) unstable; urgency=low
+
+ * New option ``create accounts automatically'' for prqd. By default
+ we avoid to create personal print accounts automatically to keep
+ the database small.
+ * Improvements in the GUI of the PrintLimit application.
+
+ -- Dirk Krause <krause.dirk@web.de> Tue, 26 Oct 2010 20:00:00 +0200
+
+
+dktools (2.2.16-1) unstable; urgency=low
+
+ * New Java application PrintLimit for users of LPRng/prqd to show
+ users print quota information.
+ * The dklibsj.html page was improved. Tutorial and short reference added.
+
+ -- Dirk Krause <krause.dirk@web.de> Sun, 24 Oct 2010 20:00:00 +0200
+
+
+dktools (2.2.15-1) unstable; urgency=low
+
+ * The LANG environment variable is now tested for both ".UTF-8"
+ and ".utf8" to indicate the use of UTF-8 encoding.
+
+ -- Dirk Krause <krause.dirk@web.de> Wed, 20 Oct 2010 20:00:00 +0200
+
+
+dktools (2.2.14-1) unstable; urgency=low
+
+ * Documentation update: Notes about differences in the appearance of
+ interpolated splines in Xfig/transfig and fig2vect. Recommendations how
+ to modify the sources of Xfig and transfig.
+
+ -- Dirk Krause <krause.dirk@web.de> Wed, 15 Sep 2010 20:00:00 +0200
+
+
+dktools (2.2.13-1) unstable; urgency=low
+
+ * Corrected typographic errors in the DKrause::Diagram documentation.
+
+ -- Dirk Krause <krause.dirk@web.de> Tue, 14 Sep 2010 20:00:00 +0200
+
+
+dktools (2.2.12-1) unstable; urgency=low
+
+ * The *.jar files were missing in the Windows executable setup of
+ 2.2.11. Here they are back.
+
+ -- Dirk Krause <krause.dirk@web.de> Tue, 13 Sep 2010 20:00:00 +0200
+
+
+dktools (2.2.11-1) unstable; urgency=low
+
+ * Unnecessary line end correction removed from fig2vect.
+ * New Perl module DKrause::Diagram added
+
+ -- Dirk Krause <krause.dirk@web.de> Tue, 31 Aug 2010 20:00:00 +0200
+
+
+dktools (2.2.10-1) unstable; urgency=low
+
+ * Documentation corrections.
+
+ -- Dirk Krause <krause.dirk@web.de> Tue, 20 Jul 2010 20:00:00 +0200
+
+
+dktools (2.2.9-1) unstable; urgency=low
+
+ * Bugfix in tracecc, application group name corrected.
+
+ -- Dirk Krause <krause.dirk@web.de> Fri, 16 Jul 2010 20:00:00 +0200
+
+
+dktools (2.2.8-1) unstable; urgency=low
+
+ * Modifications in configure script for build process on Mac.
+
+ -- Dirk Krause <krause.dirk@web.de> Mon, 12 Jul 2010 20:00:00 +0200
+
+
+dktools (2.2.6-1) unstable; urgency=low
+
+ * Bugfix in bmeps, bits per component reduction disabled.
+ * Modifications in HTML documentation due to validation results.
+ * New option "doxygen comments" for genau.
+ * Script "make-pkg.sh" to build SVR4 packages.
+ * Doxygen comments added.
+
+ -- Dirk Krause <krause.dirk@web.de> Sat, 26 Jun 2010 20:00:00 +0200
+
+
+dktools (2.2.5-1) unstable; urgency=low
+
+ * Modified hostsadm: UTF-8 to ISO-LATIN-1 conversion.
+ * Code cleanup.
+
+ -- Dirk Krause <krause.dirk@web.de> Fri, 18 Jun 2010 20:00:00 +0200
+
+
+dktools (2.2.4-1) unstable; urgency=low
+
+ * File dktools.spec added.
+ * Start scripts for prqd, rshdown, useraud now installed to /etc/init.d.
+
+ -- Dirk Krause <krause.dirk@web.de> Sun, 13 Jun 2010 20:00:00 +0200
+
+
+dktools (2.2.3-1) unstable; urgency=low
+
+ * DESTDIR variable added to makefile for RPM builders.
+
+ -- Dirk Krause <krause.dirk@web.de> Sat, 12 Jun 2010 20:00:00 +0200
+
+
+dktools (2.2.2-1) unstable; urgency=low
+
+ * Bugfix for preference file location.
+
+ -- Dirk Krause <krause.dirk@web.de> Thu, 03 Jun 2010 20:00:00 +0200
+
diff --git a/support/dktools/debian/changelog.in b/support/dktools/debian/changelog.in
new file mode 100644
index 0000000000..c1a8accb28
--- /dev/null
+++ b/support/dktools/debian/changelog.in
@@ -0,0 +1,5 @@
+dktools (@VERSION@-1) unstable; urgency=low
+
+ * Initial release (Closes: #nnnn) <nnnn is the bug number of your ITP>
+
+ -- Dirk Krause <krause.dirk@web.de> Sun, 11 Oct 2015 17:26:12 +0200
diff --git a/support/dktools/debian/compat b/support/dktools/debian/compat
new file mode 100644
index 0000000000..ec635144f6
--- /dev/null
+++ b/support/dktools/debian/compat
@@ -0,0 +1 @@
+9
diff --git a/support/dktools/debian/control b/support/dktools/debian/control
new file mode 100644
index 0000000000..6fb4f3cd0c
--- /dev/null
+++ b/support/dktools/debian/control
@@ -0,0 +1,69 @@
+Source: dktools
+Section: misc
+Priority: optional
+Maintainer: Dirk Krause <krause.dirk@web.de>
+Build-Depends: debhelper (>= 9), autotools-dev, zlib1g-dev, libbz2-dev, libssl-dev, libdb-dev, libmysqlclient-dev, libpng-dev, libjpeg-dev, libopenjpeg-dev, libtiff-dev, libsnmp-dev, wx3.0-headers, libwxgtk3.0-dev, libwxbase3.0-dev, libwxsvg-dev
+Standards-Version: 3.9.5
+Homepage: http://dktools.sourceforge.net
+#Vcs-Git: git://anonscm.debian.org/collab-maint/dktools.git
+#Vcs-Browser: http://anonscm.debian.org/?p=collab-maint/dktools.git;a=summary
+
+Package: dktools
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}, dktools-data (>= 4.8.3), dktools-lib-4.8 (>= 4.8.0), libc6, libgcc1, libstdc++6, zlib1g, libbz2-1.0, libdb5.3, libmysqlclient18, libjpeg62-turbo, libpng12-0, libtiff5, libsnmp30, libssl1.0.0, libwxbase3.0-0, libwxgtk3.0-0
+Description: DK tools - runtime
+ This package contains the executable programs.
+ bmpp /wxbmpp Convert PNG/JPEG/TIFF to PS/EPS/PDF
+ fig2lat Convert Fig to PDF+TeX
+ wximgsz Suggest new size pairs to rescale bitmap images
+ htmlbook Publish HTML like a book
+ dkct / wxdkct C tracing and debugging preprocessor
+ dkwxwiz Wizard to create DK tools + wxWidgets based applications
+ wxdkhtb HTB help file viewer
+ itadmin Use a MySQL database to manage your IT
+ dk-ls ls clone, configurable output column order
+ dk-fic File integrity checker
+ dk-bmm Backup media management (10 tape rotation scheme)
+ dk-blks Blocksize corrector (to pass a data stream to dd)
+ dk-eradisk Produce data stream to erase a disk or partition
+ dk-hex Show file contents in hexadecimal or octal notation
+ dk-cat cat clone, recoding between ASCII/UTF-8/UTF-16
+ dk-sort sort clone, handles ASCII/UTF-8/UTF-16, unsigned/signed/float
+ dk-t2h Text to HTML conversion
+ dk-t2l Text to LaTeX conversion
+ dk-sqlsplit Split overlong SQL lines i.e. from mysqldump
+ dkdbt Convert simple databases to text and vice versa
+ dk-uid Find free user ID in given range
+ dk-pwgen Create passwords, PINs or WiFi keys
+ dk-send Send a data stream to one or multiple recipients
+ dk-recv Receive data stream from a dk-send process
+ printqd Print quota daemon for use with LPRng
+ wxpqdic GUI client to check print quota in printqd
+ addctrld Add final CTRL-D to data stream if not yet present
+ wxdkclock Simple clock with one alert
+ plpdftex Output driver for octpgfpl
+
+Package: dktools-lib-4.8
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}, dktools-lib-data (>= 4.8.3), libc6, libgcc1, libstdc++6, zlib1g, libbz2-1.0, libdb5.3, libmysqlclient18, libjpeg62-turbo, libpng12-0, libtiff5, libsnmp30, libssl1.0.0, libwxbase3.0-0, libwxgtk3.0-0
+Description: DK tools - shared libraries
+ This package contains the shared libraries from the DK tools project.
+
+Package: dktools-data
+Architecture: all
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: DK tools - data files
+ This package contains the data files needed by dktools.
+
+Package: dktools-lib-data
+Architecture: all
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: DK tools - Data files for shared libraries
+ This package contains the data files for the DK tools shared libraries.
+
+Package: dktools-lib-4.8-dev
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}, debhelper (>= 9), autotools-dev, dktools-lib-4.8 (>= 4.8.3), dktools-lib-data (>= 4.8.3), zlib1g-dev, libbz2-dev, libssl-dev, libdb-dev, libmysqlclient-dev, libpng-dev, libjpeg-dev, libopenjpeg-dev, libtiff-dev, libsnmp-dev, wx3.0-headers, libwxgtk3.0-dev, libwxbase3.0-dev, libwxsvg-dev
+Description: DK tools - developer support
+ This package contains the DK tools developer support.
+
diff --git a/support/dktools/debian/control.in b/support/dktools/debian/control.in
new file mode 100644
index 0000000000..ef606a83bc
--- /dev/null
+++ b/support/dktools/debian/control.in
@@ -0,0 +1,69 @@
+Source: dktools
+Section: misc
+Priority: optional
+Maintainer: Dirk Krause <krause.dirk@web.de>
+Build-Depends: debhelper (>= 9), autotools-dev, zlib1g-dev, libbz2-dev, libssl-dev, libdb-dev, libmysqlclient-dev, libpng-dev, libjpeg-dev, libopenjpeg-dev, libtiff-dev, libsnmp-dev, wx3.0-headers, libwxgtk3.0-dev, libwxbase3.0-dev, libwxsvg-dev
+Standards-Version: 3.9.5
+Homepage: http://dktools.sourceforge.net
+#Vcs-Git: git://anonscm.debian.org/collab-maint/dktools.git
+#Vcs-Browser: http://anonscm.debian.org/?p=collab-maint/dktools.git;a=summary
+
+Package: dktools
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}, dktools-data (>= @VERSNO@), dktools-lib-@SOVERS@ (>= @SOVERS@.0), libc6, libgcc1, libstdc++6, zlib1g, libbz2-1.0, libdb5.3, libmysqlclient18, libjpeg62-turbo, libpng12-0, libtiff5, libsnmp30, libssl1.0.0, libwxbase3.0-0, libwxgtk3.0-0
+Description: DK tools - runtime
+ This package contains the executable programs.
+ bmpp /wxbmpp Convert PNG/JPEG/TIFF to PS/EPS/PDF
+ fig2lat Convert Fig to PDF+TeX
+ wximgsz Suggest new size pairs to rescale bitmap images
+ htmlbook Publish HTML like a book
+ dkct / wxdkct C tracing and debugging preprocessor
+ dkwxwiz Wizard to create DK tools + wxWidgets based applications
+ wxdkhtb HTB help file viewer
+ itadmin Use a MySQL database to manage your IT
+ dk-ls ls clone, configurable output column order
+ dk-fic File integrity checker
+ dk-bmm Backup media management (10 tape rotation scheme)
+ dk-blks Blocksize corrector (to pass a data stream to dd)
+ dk-eradisk Produce data stream to erase a disk or partition
+ dk-hex Show file contents in hexadecimal or octal notation
+ dk-cat cat clone, recoding between ASCII/UTF-8/UTF-16
+ dk-sort sort clone, handles ASCII/UTF-8/UTF-16, unsigned/signed/float
+ dk-t2h Text to HTML conversion
+ dk-t2l Text to LaTeX conversion
+ dk-sqlsplit Split overlong SQL lines i.e. from mysqldump
+ dkdbt Convert simple databases to text and vice versa
+ dk-uid Find free user ID in given range
+ dk-pwgen Create passwords, PINs or WiFi keys
+ dk-send Send a data stream to one or multiple recipients
+ dk-recv Receive data stream from a dk-send process
+ printqd Print quota daemon for use with LPRng
+ wxpqdic GUI client to check print quota in printqd
+ addctrld Add final CTRL-D to data stream if not yet present
+ wxdkclock Simple clock with one alert
+ plpdftex Output driver for octpgfpl
+
+Package: dktools-lib-@SOVERS@
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}, dktools-lib-data (>= @VERSNO@), libc6, libgcc1, libstdc++6, zlib1g, libbz2-1.0, libdb5.3, libmysqlclient18, libjpeg62-turbo, libpng12-0, libtiff5, libsnmp30, libssl1.0.0, libwxbase3.0-0, libwxgtk3.0-0
+Description: DK tools - shared libraries
+ This package contains the shared libraries from the DK tools project.
+
+Package: dktools-data
+Architecture: all
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: DK tools - data files
+ This package contains the data files needed by dktools.
+
+Package: dktools-lib-data
+Architecture: all
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: DK tools - Data files for shared libraries
+ This package contains the data files for the DK tools shared libraries.
+
+Package: dktools-lib-@SOVERS@-dev
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}, debhelper (>= 9), autotools-dev, dktools-lib-@SOVERS@ (>= @VERSNO@), dktools-lib-data (>= @VERSNO@), zlib1g-dev, libbz2-dev, libssl-dev, libdb-dev, libmysqlclient-dev, libpng-dev, libjpeg-dev, libopenjpeg-dev, libtiff-dev, libsnmp-dev, wx3.0-headers, libwxgtk3.0-dev, libwxbase3.0-dev, libwxsvg-dev
+Description: DK tools - developer support
+ This package contains the DK tools developer support.
+
diff --git a/support/dktools/debian/copyright b/support/dktools/debian/copyright
new file mode 100644
index 0000000000..2de1bdf3ef
--- /dev/null
+++ b/support/dktools/debian/copyright
@@ -0,0 +1,41 @@
+Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: dktools
+Source: http://dktools.sourceforge.net
+
+Files: *
+Copyright: 2015 Dirk Krause <krause.dirk@web.de>
+License: BSD
+ All rights reserved.
+ .
+ Redistribution and use in source and binary forms,
+ with or without modification, are permitted provided
+ that the following conditions are met:
+ .
+ * Redistributions of source code must retain the above
+ copyright notice, this list of conditions and the
+ following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ opyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials
+ provided with the distribution.
+ * Neither the name of the Dirk Krause nor the names of
+ contributors may be used to endorse or promote
+ products derived from this software without specific
+ prior written permission.
+ .
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ DAMAGE.
+
diff --git a/support/dktools/debian/dktools-data.install b/support/dktools/debian/dktools-data.install
new file mode 100644
index 0000000000..e629daa95c
--- /dev/null
+++ b/support/dktools/debian/dktools-data.install
@@ -0,0 +1,4 @@
+etc/dk3app
+etc/printqd
+etc/rshdown
+usr/share/dktools
diff --git a/support/dktools/debian/dktools-doc.docs b/support/dktools/debian/dktools-doc.docs
new file mode 100644
index 0000000000..d4f4542584
--- /dev/null
+++ b/support/dktools/debian/dktools-doc.docs
@@ -0,0 +1 @@
+#DOCS#
diff --git a/support/dktools/debian/dktools-doc.install b/support/dktools/debian/dktools-doc.install
new file mode 100644
index 0000000000..d4f4542584
--- /dev/null
+++ b/support/dktools/debian/dktools-doc.install
@@ -0,0 +1 @@
+#DOCS#
diff --git a/support/dktools/debian/dktools-lib-4.8-dev.install b/support/dktools/debian/dktools-lib-4.8-dev.install
new file mode 100644
index 0000000000..951b0df296
--- /dev/null
+++ b/support/dktools/debian/dktools-lib-4.8-dev.install
@@ -0,0 +1,3 @@
+usr/include
+usr/lib/*/lib*.so
+usr/lib/*/pkgconfig/*.pc
diff --git a/support/dktools/debian/dktools-lib-4.8.install b/support/dktools/debian/dktools-lib-4.8.install
new file mode 100644
index 0000000000..3ddde58419
--- /dev/null
+++ b/support/dktools/debian/dktools-lib-4.8.install
@@ -0,0 +1 @@
+usr/lib/*/lib*.so.*
diff --git a/support/dktools/debian/dktools-lib-4.8.lintian-overrides b/support/dktools/debian/dktools-lib-4.8.lintian-overrides
new file mode 100644
index 0000000000..8675979362
--- /dev/null
+++ b/support/dktools/debian/dktools-lib-4.8.lintian-overrides
@@ -0,0 +1 @@
+package-name-doesnt-match-sonames
diff --git a/support/dktools/debian/dktools-lib-4.8.postinst b/support/dktools/debian/dktools-lib-4.8.postinst
new file mode 100644
index 0000000000..73da26cc9f
--- /dev/null
+++ b/support/dktools/debian/dktools-lib-4.8.postinst
@@ -0,0 +1,55 @@
+#!/bin/sh
+# postinst script for dktools
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+# * <postinst> `configure' <most-recently-configured-version>
+# * <old-postinst> `abort-upgrade' <new version>
+# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
+# <new-version>
+# * <postinst> `abort-remove'
+# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
+# <failed-install-package> <version> `removing'
+# <conflicting-package> <version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+ configure)
+ # ##### LINUX DISTRIBUTION PACKAGERS #####
+ # ##### If your distribution contains the LPRng software, please
+ # ##### check LPUSER and LPGROUP to meet the user and group used
+ # ##### to run the LPRng lpd daemon on your distribution.
+ # ##### Correct the lines if necessary.
+ #
+ LPUSER="daemon"
+ LPGROUP="daemon"
+ #
+ # #####
+ for i in /var/run/printqd /var/log/printqd /var/printqd
+ do
+ [ -d $i ] || mkdir $i
+ chown -R ${LPUSER}:${LPGROUP} $i
+ chmod 770 $i
+ done
+ ;;
+
+ abort-upgrade|abort-remove|abort-deconfigure)
+ ;;
+
+ *)
+ echo "postinst called with unknown argument \`$1'" >&2
+ exit 1
+ ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
diff --git a/support/dktools/debian/dktools-lib-4.8.postrm b/support/dktools/debian/dktools-lib-4.8.postrm
new file mode 100644
index 0000000000..783d414cdc
--- /dev/null
+++ b/support/dktools/debian/dktools-lib-4.8.postrm
@@ -0,0 +1,47 @@
+#!/bin/sh
+# postrm script for dktools
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+# * <postrm> `remove'
+# * <postrm> `purge'
+# * <old-postrm> `upgrade' <new-version>
+# * <new-postrm> `failed-upgrade' <old-version>
+# * <new-postrm> `abort-install'
+# * <new-postrm> `abort-install' <old-version>
+# * <new-postrm> `abort-upgrade' <old-version>
+# * <disappearer's-postrm> `disappear' <overwriter>
+# <overwriter-version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+ remove)
+ [ ! -d /var/run/printqd ] || rm -fr /var/run/printqd
+ [ ! -d /var/log/printqd ] || rm -fr /var/log/printqd
+ ;;
+ purge)
+ [ ! -d /var/run/printqd ] || rm -fr /var/run/printqd
+ [ ! -d /var/log/printqd ] || rm -fr /var/log/printqd
+ [ ! -d /etc/printqd ] || rm -fr /etc/printqd
+ [ ! -d /var/printqd ] || rm -fr /var/printqd
+ ;;
+ upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
+ ;;
+
+ *)
+ echo "postrm called with unknown argument \`$1'" >&2
+ exit 1
+ ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
diff --git a/support/dktools/debian/dktools-lib-data.install b/support/dktools/debian/dktools-lib-data.install
new file mode 100644
index 0000000000..5b3bf665e8
--- /dev/null
+++ b/support/dktools/debian/dktools-lib-data.install
@@ -0,0 +1 @@
+usr/share/dk4app
diff --git a/support/dktools/debian/dktools-lib-dev.install.in b/support/dktools/debian/dktools-lib-dev.install.in
new file mode 100644
index 0000000000..951b0df296
--- /dev/null
+++ b/support/dktools/debian/dktools-lib-dev.install.in
@@ -0,0 +1,3 @@
+usr/include
+usr/lib/*/lib*.so
+usr/lib/*/pkgconfig/*.pc
diff --git a/support/dktools/debian/dktools-lib.install.in b/support/dktools/debian/dktools-lib.install.in
new file mode 100644
index 0000000000..3ddde58419
--- /dev/null
+++ b/support/dktools/debian/dktools-lib.install.in
@@ -0,0 +1 @@
+usr/lib/*/lib*.so.*
diff --git a/support/dktools/debian/dktools-lib.postinst.in b/support/dktools/debian/dktools-lib.postinst.in
new file mode 100644
index 0000000000..73da26cc9f
--- /dev/null
+++ b/support/dktools/debian/dktools-lib.postinst.in
@@ -0,0 +1,55 @@
+#!/bin/sh
+# postinst script for dktools
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+# * <postinst> `configure' <most-recently-configured-version>
+# * <old-postinst> `abort-upgrade' <new version>
+# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
+# <new-version>
+# * <postinst> `abort-remove'
+# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
+# <failed-install-package> <version> `removing'
+# <conflicting-package> <version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+ configure)
+ # ##### LINUX DISTRIBUTION PACKAGERS #####
+ # ##### If your distribution contains the LPRng software, please
+ # ##### check LPUSER and LPGROUP to meet the user and group used
+ # ##### to run the LPRng lpd daemon on your distribution.
+ # ##### Correct the lines if necessary.
+ #
+ LPUSER="daemon"
+ LPGROUP="daemon"
+ #
+ # #####
+ for i in /var/run/printqd /var/log/printqd /var/printqd
+ do
+ [ -d $i ] || mkdir $i
+ chown -R ${LPUSER}:${LPGROUP} $i
+ chmod 770 $i
+ done
+ ;;
+
+ abort-upgrade|abort-remove|abort-deconfigure)
+ ;;
+
+ *)
+ echo "postinst called with unknown argument \`$1'" >&2
+ exit 1
+ ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
diff --git a/support/dktools/debian/dktools-lib.postrm.in b/support/dktools/debian/dktools-lib.postrm.in
new file mode 100644
index 0000000000..783d414cdc
--- /dev/null
+++ b/support/dktools/debian/dktools-lib.postrm.in
@@ -0,0 +1,47 @@
+#!/bin/sh
+# postrm script for dktools
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+# * <postrm> `remove'
+# * <postrm> `purge'
+# * <old-postrm> `upgrade' <new-version>
+# * <new-postrm> `failed-upgrade' <old-version>
+# * <new-postrm> `abort-install'
+# * <new-postrm> `abort-install' <old-version>
+# * <new-postrm> `abort-upgrade' <old-version>
+# * <disappearer's-postrm> `disappear' <overwriter>
+# <overwriter-version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+ remove)
+ [ ! -d /var/run/printqd ] || rm -fr /var/run/printqd
+ [ ! -d /var/log/printqd ] || rm -fr /var/log/printqd
+ ;;
+ purge)
+ [ ! -d /var/run/printqd ] || rm -fr /var/run/printqd
+ [ ! -d /var/log/printqd ] || rm -fr /var/log/printqd
+ [ ! -d /etc/printqd ] || rm -fr /etc/printqd
+ [ ! -d /var/printqd ] || rm -fr /var/printqd
+ ;;
+ upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
+ ;;
+
+ *)
+ echo "postrm called with unknown argument \`$1'" >&2
+ exit 1
+ ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
diff --git a/support/dktools/debian/dktools.install b/support/dktools/debian/dktools.install
new file mode 100644
index 0000000000..e0b64c8aea
--- /dev/null
+++ b/support/dktools/debian/dktools.install
@@ -0,0 +1,2 @@
+usr/bin
+usr/share/applications/*.desktop
diff --git a/support/dktools/debian/dktools.manpages b/support/dktools/debian/dktools.manpages
new file mode 100644
index 0000000000..ddf7abb0d5
--- /dev/null
+++ b/support/dktools/debian/dktools.manpages
@@ -0,0 +1,56 @@
+man/man1/addctrld.1
+man/man1/bmpp.1
+man/man1/dk3info.1
+man/man1/dk4info.1
+man/man1/dk-blks.1
+man/man1/dk-bmm.1
+man/man1/dk-cat.1
+man/man1/dkct.1
+man/man1/dk-db2t.1
+man/man1/dk-dbco.1
+man/man1/dkdbt.1
+man/man1/dk-eradisk.1
+man/man1/dk-fic.1
+man/man1/dk-hex.1
+man/man1/dk-ls.1
+man/man1/dk-pwd.1
+man/man1/dk-pwgen.1
+man/man1/dk-rand.1
+man/man1/dk-recv.1
+man/man1/dk-send.1
+man/man1/dk-sort.1
+man/man1/dk-sqlsplit.1
+man/man1/dk-t2db.1
+man/man1/dk-t2h.1
+man/man1/dk-t2l.1
+man/man1/dktools.1
+man/man1/dk-uid.1
+man/man1/dkwxwiz.1
+man/man1/fig2lat.1
+man/man1/htmlbook.1
+man/man1/itaclean.1
+man/man1/itadmin.1
+man/man1/lprngcl.1
+man/man1/pjsnmp.1
+man/man1/plpdftex.1
+man/man1/printqd.1
+man/man1/printqda.1
+man/man1/printqdc.1
+man/man1/printqdi.1
+man/man1/prmonsnmp.1
+man/man1/rshdown.1
+man/man1/wxbmpp.1
+man/man1/wxdkclock.1
+man/man1/wxdkct.1
+man/man1/wxdkfcs.1
+man/man1/wxdkhtb.1
+man/man1/wximgsz.1
+man/man1/wxpqdic.1
+man/man5/dkct.5
+man/man5/dkct-wxgui.5
+man/man5/htmlbook-project.5
+man/man5/htmlbook-template.5
+man/man5/htmlbook-text.5
+man/man5/printqd.conf.5
+man/man5/printqd.db.5
+man/man5/printqd.protocol.5
diff --git a/support/dktools/debian/docs b/support/dktools/debian/docs
new file mode 100644
index 0000000000..c0b4a20a6c
--- /dev/null
+++ b/support/dktools/debian/docs
@@ -0,0 +1,3 @@
+bsdlic.txt
+README
+version.txt
diff --git a/support/dktools/debian/rules b/support/dktools/debian/rules
new file mode 100644
index 0000000000..b079e9cb56
--- /dev/null
+++ b/support/dktools/debian/rules
@@ -0,0 +1,33 @@
+#!/usr/bin/make -f
+# See debhelper(7) (uncomment to enable)
+# output every command that modifies files on the build system.
+DH_VERBOSE = 1
+
+# see EXAMPLES in dpkg-buildflags(1) and read /usr/share/dpkg/*
+DPKG_EXPORT_BUILDFLAGS = 1
+include /usr/share/dpkg/default.mk
+
+# see FEATURE AREAS in dpkg-buildflags(1)
+#export DEB_BUILD_MAINT_OPTIONS = hardening=+all
+
+# see ENVIRONMENT in dpkg-buildflags(1)
+# package maintainers to append CFLAGS
+#export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic
+# package maintainers to append LDFLAGS
+#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
+
+
+# main packaging script based on dh7 syntax
+%:
+ dh $@ --with autotools-dev
+
+# debmake generated override targets
+# This is example for Cmake (See http://bugs.debian.org/641051 )
+#override_dh_auto_configure:
+# dh_auto_configure -- \
+# -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH)
+
+
+
+override_dh_auto_configure:
+ dh_auto_configure -- --enable-packaging
diff --git a/support/dktools/debian/source/format b/support/dktools/debian/source/format
new file mode 100644
index 0000000000..163aaf8d82
--- /dev/null
+++ b/support/dktools/debian/source/format
@@ -0,0 +1 @@
+3.0 (quilt)
diff --git a/support/dktools/dk-blks.c b/support/dktools/dk-blks.c
new file mode 100644
index 0000000000..80a5ae9a9b
--- /dev/null
+++ b/support/dktools/dk-blks.c
@@ -0,0 +1,1012 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk-blks.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#line 10 "dk-blks.ctr"
+
+/** @file dk-blks.c The dk-blks program.
+ the help_text array below shows details.
+*/
+
+
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4vers.h"
+#include "dk4app.h"
+#include "dk4aopt.h"
+#include "dk4mem.h"
+#include "dk4mema.h"
+#include "dk4memrs.h"
+#include "dk4numco.h"
+#include "dk4fdrde.h"
+#include "dk4fdwre.h"
+
+
+
+
+
+#line 98 "dk-blks.ctr"
+
+
+
+#ifndef DK_BLKS_DEFAULT_BLOCK_SIZE
+/** Default suitable for hard disks.
+*/
+#define DK_BLKS_DEFAULT_BLOCK_SIZE 4096
+#endif
+
+
+
+/** Default help text, shown if help text file is not found.
+*/
+static const dkChar * const help_text[] = {
+dkT(""),
+dkT("Create sequence of fixed size blocks."),
+dkT(""),
+dkT("dk-blks [<options>]"),
+dkT(""),
+dkT("Options:"),
+dkT("-b <size>\tBlock size, positive integer number."),
+dkT("\t\tYou can append `k', `m', `g', or `t' for multiples of 1024"),
+dkT("\t\tor powers of it (i.e. 4k = 4096 bytes, 1m = 1048576 bytes...)."),
+dkT(""),
+dkT("--help\t\tShow this short help text."),
+dkT("--manual\t*** SHOW FULL MANUAL. ***"),
+dkT("--version\tShow version information."),
+dkT("--license\tShow license information."),
+dkT(""),
+dkT("http://dktools.sourceforge.net"),
+dkT(""),
+NULL
+
+
+#line 131 "dk-blks.ctr"
+};
+
+
+/** License conditions.
+*/
+static const dkChar * const license_text[] = {
+dkT("This software uses code from the following projects, either directly or as"),
+dkT("a library:"),
+dkT(""),
+dkT("dktools\t\tDirk Krause's tools and libraries."),
+dkT("\t\tSee http://dktools.sourceforge.net/ for more information."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT("zlib\t\tData compression library."),
+dkT("\t\tSee http://www.zlib.net/ for more information."),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT("bzip2\t\tData compression program and library."),
+dkT("\t\tSee http://www.bzip.org/ for more information."),
+#endif
+dkT(""),
+dkT("All the licenses below apply to the program."),
+dkT("Licenses for used libraries are shown as found on my Scientific Linux 6.x"),
+dkT("computer in the /usr/share/doc directory on 2015-04-01. Check the project"),
+dkT("homepages of the used libraries for additional information and/or updated"),
+dkT("license terms."),
+dkT(""),
+dkT(""),
+dkT("DK tools and libraries license"),
+dkT("=============================="),
+dkT("Copyright (c) 2015-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above copyright notice,"),
+dkT(" this list of conditions and the following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("* Neither the name of the Dirk Krause nor the names of contributors may be"),
+dkT(" used to endorse or promote products derived from this software without"),
+dkT(" specific prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\""),
+dkT("AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED."),
+dkT(""),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,"),
+dkT("INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,"),
+dkT("BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,"),
+dkT("DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY"),
+dkT("OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,"),
+dkT("EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT(""),
+dkT("Zlib license"),
+dkT("============"),
+dkT("(C) 1995-2004 Jean-loup Gailly and Mark Adler"),
+dkT(""),
+dkT("This software is provided 'as-is', without any express or implied"),
+dkT("warranty. In no event will the authors be held liable for any damages"),
+dkT("arising from the use of this software."),
+dkT(""),
+dkT("Permission is granted to anyone to use this software for any purpose,"),
+dkT("including commercial applications, and to alter it and redistribute it"),
+dkT("freely, subject to the following restrictions:"),
+dkT(""),
+dkT("1. The origin of this software must not be misrepresented; you must not"),
+dkT(" claim that you wrote the original software. If you use this software"),
+dkT(" in a product, an acknowledgment in the product documentation would be"),
+dkT(" appreciated but is not required."),
+dkT("2. Altered source versions must be plainly marked as such, and must not be"),
+dkT(" misrepresented as being the original software."),
+dkT("3. This notice may not be removed or altered from any source distribution."),
+dkT(""),
+dkT("Jean-loup Gailly Mark Adler"),
+dkT("jloup@gzip.org madler@alumni.caltech.edu"),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT(""),
+dkT("Bzip2 and libbzip2 library license"),
+dkT("=================================="),
+dkT("This program, \"bzip2\", the associated library \"libbzip2\", and all"),
+dkT("documentation, are copyright (C) 1996-2007 Julian R Seward. All"),
+dkT("rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions"),
+dkT("are met:"),
+dkT(""),
+dkT("1. Redistributions of source code must retain the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer."),
+dkT(""),
+dkT("2. The origin of this software must not be misrepresented; you must "),
+dkT(" not claim that you wrote the original software. If you use this "),
+dkT(" software in a product, an acknowledgment in the product "),
+dkT(" documentation would be appreciated but is not required."),
+dkT(""),
+dkT("3. Altered source versions must be plainly marked as such, and must"),
+dkT(" not be misrepresented as being the original software."),
+dkT(""),
+dkT("4. The name of the author may not be used to endorse or promote "),
+dkT(" products derived from this software without specific prior written "),
+dkT(" permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS"),
+dkT("OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED"),
+dkT("WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE"),
+dkT("GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS"),
+dkT("INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,"),
+dkT("WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS"),
+dkT("SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+dkT(""),
+dkT("Julian Seward, jseward@bzip.org"),
+dkT("bzip2/libbzip2 version 1.0.5 of 10 December 2007"),
+#endif
+dkT(""),
+NULL
+
+
+#line 261 "dk-blks.ctr"
+};
+
+
+
+/** Options used by program.
+*/
+static const dk4_option_specification_t options[] = {
+ { dkT('b'), dkT("block-size"), DK4_OPT_ARG_SIZE }
+};
+
+/** Number of elements in options array.
+*/
+static const size_t sz_options =
+sizeof(options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Keywords used by the program, not localized.
+*/
+static const dkChar * const kwnl[] = {
+/* 0 */
+dkT("dktools"),
+
+/* 1 */
+dkT("dk-blks.txt"),
+
+/* 2 */
+dkT("dk-blks.str"),
+
+/* 3 */
+dkT("stdin"),
+
+/* 4 */
+dkT("stdout"),
+
+NULL
+
+
+#line 300 "dk-blks.ctr"
+};
+
+
+
+/** Constant texts used by the program, replaced by localized texts
+ if available.
+*/
+static const dkChar * const kw_def[] = {
+/* 0 */
+dkT("Write operation partially failed!"),
+
+/* 1 */
+dkT("Failed to cleanup buffer!"),
+
+/* 2 */
+dkT("Block size too large!"),
+
+/* 3 */
+dkT("Block size must not be 0!"),
+
+/* 4 */
+dkT("Failed to set up signal handlers!"),
+
+/* 5 */
+dkT("Failed to restore signal handlers!"),
+
+/* 6 */
+dkT("Signal SIGPIPE received, write operation failed!"),
+
+/* 7 */
+dkT("Signal SIGINT received, program aborted!"),
+
+/* 8 */
+dkT("Unexpected command line argument \""),
+
+/* 9 */
+dkT("\" ignored!"),
+
+NULL
+
+
+#line 347 "dk-blks.ctr"
+};
+
+
+
+/** Message texts, localized texts are used if available.
+*/
+static const dkChar * const *dk_blks_msg = kw_def;
+
+
+
+/** Number of elements in dk_blks_msg array.
+*/
+static size_t sz_msg =
+sizeof(kw_def)/sizeof(DK4_PCDKCHAR) - 1;
+
+
+
+/** Exit status code.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Input buffer for buffer sizes up to DK_BLKS_DEFAULT_BLOCK_SIZE.
+*/
+static char default_input_buffer[DK_BLKS_DEFAULT_BLOCK_SIZE];
+
+
+
+/** Output buffer for buffer sizes up to DK_BLKS_DEFAULT_BLOCK_SIZE.
+*/
+static char default_output_buffer[sizeof(default_input_buffer)];
+
+
+
+#ifdef RW_MAX
+#undef RW_MAX
+#endif
+
+#if DK4_ON_WINDOWS
+/** Maximum number of bytes for read or write operation.
+*/
+#define RW_MAX (INT_MAX)
+#else
+/** Maximum number of bytes for read or write operation.
+*/
+#define RW_MAX ((SIZE_MAX) / 2U)
+#endif
+
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+/** Check whether we can continue or if a signal was received.
+ @param check_pipe Flag: Check for occured SIGPIPE signal too.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(int check_pipe)
+{
+ int back = 1;
+#ifdef SIGPIPE
+ if (0 != check_pipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_int )) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+static
+void
+dk_blks_transfer(char *ib, char *ob, size_t bs)
+{
+ int cc = 1; /* Flag: Can continue */
+ size_t irdb = 0; /* Bytes in input buffer */
+ size_t iused = 0; /* Input bytes used */
+ size_t oused = 0; /* Output bytes used */
+ size_t iavail; /* Input bytes available */
+ size_t oavail; /* Output bytes available */
+ size_t bcp; /* Bytes to copy */
+#if DK4_ON_WINDOWS
+ int rdres; /* Number of bytes read */
+ int wrres; /* Number of bytes written */
+#else
+ ssize_t rdres; /* Number of bytes read */
+ ssize_t wrres; /* Number of bytes written */
+#endif
+ dk4_sig_atomic_t shp; /* Had pipe */
+
+
+#line 519 "dk-blks.ctr"
+ /* Process input
+ */
+ exval = EXIT_SUCCESS;
+ do {
+ if (1 == sig_can_continue(0)) {
+ errno = 0;
+
+#line 525 "dk-blks.ctr"
+#if DK4_ON_WINDOWS
+ rdres = _read(0, ib, (unsigned)bs);
+#else
+ rdres = read(0, ib, bs);
+#endif
+ if (0 < rdres) {
+
+#line 531 "dk-blks.ctr"
+ irdb = rdres;
+ iused = 0;
+ while(iused < irdb) {
+ /* Find number of bytes we can add to output buffer */
+ iavail = irdb - iused;
+ oavail = bs - oused;
+ if (iavail < oavail) {
+ bcp = iavail;
+ } else {
+ bcp = oavail;
+ }
+ /* Add bytes to output buffer */
+ DK4_MEMCPY(&(ob[oused]), &(ib[iused]), bcp);
+ /* Increased number of used bytes for both input and output */
+ oused += bcp;
+ iused += bcp;
+ /* Flush output buffer when full */
+ if (oused >= bs) {
+#ifdef SIGPIPE
+ shp = sig_read_atomic(&sig_had_pipe);
+#else
+ shp = 0;
+#endif
+ if (0 == shp) {
+ errno = 0;
+#if DK4_ON_WINDOWS
+ wrres = _write(1, ob, (unsigned)bs);
+#else
+ wrres = write(1, ob, bs);
+#endif
+ if (0 <= wrres) {
+ if (wrres < bs) {
+ /* ERROR: Not all bytes written */
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 0);
+ exval = EXIT_FAILURE;
+ cc = -1;
+ }
+ } else {
+ /* ERROR Write attempt failed */
+ dk4fd_write_error_msg(app, kwnl[4], errno);
+ exval = EXIT_FAILURE;
+ cc = -1;
+ }
+ }
+ oused = 0;
+ }
+ }
+ } else {
+ if (0 == rdres) {
+
+#line 580 "dk-blks.ctr"
+ cc = 0;
+ } else {
+
+#line 582 "dk-blks.ctr"
+ /* ERROR: Read operation failed */
+ dk4fd_read_error_msg(app, kwnl[3], errno);
+ cc = 0;
+ exval = EXIT_FAILURE;
+ }
+ }
+#if DK4_ON_WINDOWS
+ if (_eof(0)) {
+ cc = 0;
+ }
+#endif
+ } else {
+ cc = -1;
+ }
+ } while (1 == cc);
+
+ /* Flush output buffer */
+ if (0 == cc) {
+ if (0 < oused) {
+#ifdef SIGPIPE
+ shp = sig_read_atomic(&sig_had_pipe);
+#else
+ shp = 0;
+#endif
+ if (0 == shp) {
+ errno = 0;
+#if DK4_ON_WINDOWS
+ wrres = _write(1, ob, (unsigned)oused);
+#else
+ wrres = write(1, ob, oused);
+#endif
+ if (0 <= wrres) {
+ if (wrres < oused) {
+ /* ERROR: Not all bytes written */
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 0);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Write attempt failed */
+ dk4fd_write_error_msg(app, kwnl[4], errno);
+ exval = EXIT_FAILURE;
+ }
+ }
+ }
+ }
+
+ /* Finally zero-fill used buffers.
+ */
+ if (0 == dk4mem_reset_secure(ib, bs, NULL)) {
+ /* ERROR: Secure memory reset failed */
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 1);
+ exval = EXIT_FAILURE;
+ }
+ if (0 == dk4mem_reset_secure(ob, bs, NULL)) {
+ /* ERROR: Secure memory reset failed */
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 1);
+ exval = EXIT_FAILURE;
+ }
+
+
+
+#line 642 "dk-blks.ctr"
+}
+
+
+
+static
+void
+dk_blks_with_buffers(char *ib, char *ob, size_t bs)
+{
+#if DK4_ON_WINDOWS
+ int oldinmode = 0;
+ int oldoutmode = 0;
+#endif
+ if ((dk4_um_t)RW_MAX >= (dk4_um_t)bs) {
+#if DK4_ON_WINDOWS
+ oldinmode = _setmode(0, _O_BINARY);
+ oldoutmode = _setmode(1, _O_BINARY);
+#endif
+ dk_blks_transfer(ib, ob, bs);
+#if DK4_ON_WINDOWS
+ _setmode(1, oldoutmode);
+ _setmode(0, oldinmode);
+#endif
+ } else {
+ /* ERROR: Block size too large */
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 2);
+ }
+}
+
+
+
+/** Run normally.
+*/
+static
+void
+dk_blks_normal_run(void)
+{
+ char *myib;
+ char *myob;
+ size_t mybs = DK_BLKS_DEFAULT_BLOCK_SIZE;
+ int res = 0;
+
+
+#line 683 "dk-blks.ctr"
+ if (0 != dk4app_opt_is_set_short(app, dkT('b'), NULL)) {
+ res = dk4app_opt_get_size_short(&mybs, app, dkT('b'), NULL);
+ if (0 == res) {
+ mybs = DK_BLKS_DEFAULT_BLOCK_SIZE;
+ }
+ }
+ if ((0 < mybs) && (mybs <= DK_BLKS_DEFAULT_BLOCK_SIZE)) {
+ dk_blks_with_buffers(
+ default_input_buffer,
+ default_output_buffer,
+ mybs
+ );
+ } else {
+ if (0 < mybs) {
+ myib = (char *)dk4mem_calloc_app(1, mybs, app);
+ if (NULL != myib) {
+ myob = (char *)dk4mem_calloc_app(1, mybs, app);
+ if (NULL != myob) {
+ dk_blks_with_buffers(myib, myob, mybs);
+ dk4mem_free(myob);
+ }
+ dk4mem_free(myib);
+ }
+ } else {
+ /* ERROR: Illegal block size */
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 3);
+ }
+ }
+
+
+#line 712 "dk-blks.ctr"
+}
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+run_with_signals(void)
+{
+#ifdef SIGPIPE
+ struct sigaction opipe;
+#endif
+ struct sigaction oint;
+ struct sigaction oterm;
+#ifdef SIGPIPE
+ struct sigaction npipe;
+#endif
+ struct sigaction nint;
+ struct sigaction nterm;
+ int success = 0;
+
+#ifdef SIGPIPE
+ /* Set up signal handling for SIGPIPE.
+ */
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 4);
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 4);
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 4);
+ goto finished;
+ }
+#endif
+
+ /* Set up signal handling for SIGINT.
+ */
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 4);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 4);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 4);
+ goto restore_old_pipe;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 4);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 4);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 4);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ dk_blks_normal_run();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 5);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 5);
+ success = 0;
+ }
+
+#ifdef SIGPIPE
+ /* Restore signal handling for SIGPIPE.
+ */
+ restore_old_pipe:
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 5);
+ success = 0;
+ }
+#endif
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+run_with_signals(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ dk_blks_normal_run();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+#ifdef SIGPIPE
+ sigset(SIGPIPE, oldpipe);
+#endif
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+run_with_signals(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = signal(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ dk_blks_normal_run();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+#ifdef SIGPIPE
+ signal(SIGPIPE, oldpipe);
+#endif
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+run_with_signals(void)
+{
+ dk_blks_normal_run();
+}
+#endif
+#endif
+#endif
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ dkChar const *xargv;
+ int xargc;
+ int i;
+
+
+#line 917 "dk-blks.ctr"
+
+
+#line 918 "dk-blks.ctr"
+ app = dk4app_open_cmd(
+ argc, argv, options, sz_options, kwnl[0], DKT_VERSION_DK,
+ kwnl[1], help_text, license_text
+ );
+ if (NULL != app) {
+ sz_msg = dk4app_string_table_size(kw_def);
+ dk_blks_msg = dk4app_string_table(app, kwnl[2], kw_def);
+ if (0 != dk4app_can_run_normally(app)) {
+ run_with_signals();
+ xargc = dk4app_get_argc(app);
+ if (0 < xargc) {
+ for (i = 0; i < xargc; i++) {
+ xargv = dk4app_get_argv(app, i);
+ if (NULL != xargv) {
+ dk4app_log_3(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 8, 9, xargv);
+ exval = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef SIGPIPE
+ if (0 != sig_read_atomic(&sig_had_pipe)) {
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 6);
+ exval = EXIT_FAILURE;
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_int)) {
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 7);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ dk4app_close(app); app = NULL;
+ } else {
+ }
+
+
+#line 956 "dk-blks.ctr"
+
+
+#line 957 "dk-blks.ctr"
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/dk-blks.ctr b/support/dktools/dk-blks.ctr
new file mode 100644
index 0000000000..12829bc381
--- /dev/null
+++ b/support/dktools/dk-blks.ctr
@@ -0,0 +1,959 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+/** @file dk-blks.c The dk-blks program.
+ the help_text array below shows details.
+*/
+
+
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4vers.h"
+#include "dk4app.h"
+#include "dk4aopt.h"
+#include "dk4mem.h"
+#include "dk4mema.h"
+#include "dk4memrs.h"
+#include "dk4numco.h"
+#include "dk4fdrde.h"
+#include "dk4fdwre.h"
+
+
+
+$!trace-include
+
+
+
+#ifndef DK_BLKS_DEFAULT_BLOCK_SIZE
+/** Default suitable for hard disks.
+*/
+#define DK_BLKS_DEFAULT_BLOCK_SIZE 4096
+#endif
+
+
+
+/** Default help text, shown if help text file is not found.
+*/
+static const dkChar * const help_text[] = {
+$!text macro=dkT,preprocessor
+
+Create sequence of fixed size blocks.
+
+dk-blks [<options>]
+
+Options:
+-b <size> Block size, positive integer number.
+ You can append `k', `m', `g', or `t' for multiples of 1024
+ or powers of it (i.e. 4k = 4096 bytes, 1m = 1048576 bytes...).
+
+--help Show this short help text.
+--manual *** SHOW FULL MANUAL. ***
+--version Show version information.
+--license Show license information.
+
+http://dktools.sourceforge.net
+
+$!end
+};
+
+
+/** License conditions.
+*/
+static const dkChar * const license_text[] = {
+$!text macro=dkT,preprocessor
+This software uses code from the following projects, either directly or as
+a library:
+
+dktools Dirk Krause's tools and libraries.
+ See http://dktools.sourceforge.net/ for more information.
+#if DK4_HAVE_ZLIB_H
+
+zlib Data compression library.
+ See http://www.zlib.net/ for more information.
+#endif
+#if DK4_HAVE_BZLIB_H
+
+bzip2 Data compression program and library.
+ See http://www.bzip.org/ for more information.
+#endif
+
+All the licenses below apply to the program.
+Licenses for used libraries are shown as found on my Scientific Linux 6.x
+computer in the /usr/share/doc directory on 2015-04-01. Check the project
+homepages of the used libraries for additional information and/or updated
+license terms.
+
+
+DK tools and libraries license
+==============================
+Copyright (c) 2015-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#if DK4_HAVE_ZLIB_H
+
+
+Zlib license
+============
+(C) 1995-2004 Jean-loup Gailly and Mark Adler
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+
+Jean-loup Gailly Mark Adler
+jloup@gzip.org madler@alumni.caltech.edu
+#endif
+#if DK4_HAVE_BZLIB_H
+
+
+Bzip2 and libbzip2 library license
+==================================
+This program, "bzip2", the associated library "libbzip2", and all
+documentation, are copyright (C) 1996-2007 Julian R Seward. All
+rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+3. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Julian Seward, jseward@bzip.org
+bzip2/libbzip2 version 1.0.5 of 10 December 2007
+#endif
+
+$!end
+};
+
+
+
+/** Options used by program.
+*/
+static const dk4_option_specification_t options[] = {
+ { dkT('b'), dkT("block-size"), DK4_OPT_ARG_SIZE }
+};
+
+/** Number of elements in options array.
+*/
+static const size_t sz_options =
+sizeof(options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Keywords used by the program, not localized.
+*/
+static const dkChar * const kwnl[] = {
+$!string-table macro=dkT
+#
+# 0 Program group name
+#
+dktools
+#
+# 1 Help text file name
+#
+dk-blks.txt
+#
+# 2 String table file name
+#
+dk-blks.str
+#
+# 3 4 File names for reporting read and write errors
+#
+stdin
+stdout
+$!end
+};
+
+
+
+/** Constant texts used by the program, replaced by localized texts
+ if available.
+*/
+static const dkChar * const kw_def[] = {
+$!string-table macro=dkT
+#
+# 0 Error message: Not all bytes written
+#
+Write operation partially failed!
+#
+# 1 Error message: Failed to clean up buffer
+#
+Failed to cleanup buffer!
+#
+# 2 Error message: Block size too large!
+#
+Block size too large!
+#
+# 3 Error message: Block size must not be 0!
+#
+Block size must not be 0!
+#
+# 4 Error message: Failed to set up signal handlers!
+#
+Failed to set up signal handlers!
+#
+# 5 Error message: Failed to restore signal handlers!
+#
+Failed to restore signal handlers!
+#
+# 6 Error message: Signal SIGPIPE received!
+#
+Signal SIGPIPE received, write operation failed!
+#
+# 7 Error message: Signal SIGINT received!
+#
+Signal SIGINT received, program aborted!
+#
+# 8 9 Error message: Unexpected command line argument ... ignored!
+#
+Unexpected command line argument "
+" ignored!
+$!end
+};
+
+
+
+/** Message texts, localized texts are used if available.
+*/
+static const dkChar * const *dk_blks_msg = kw_def;
+
+
+
+/** Number of elements in dk_blks_msg array.
+*/
+static size_t sz_msg =
+sizeof(kw_def)/sizeof(DK4_PCDKCHAR) - 1;
+
+
+
+/** Exit status code.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Input buffer for buffer sizes up to DK_BLKS_DEFAULT_BLOCK_SIZE.
+*/
+static char default_input_buffer[DK_BLKS_DEFAULT_BLOCK_SIZE];
+
+
+
+/** Output buffer for buffer sizes up to DK_BLKS_DEFAULT_BLOCK_SIZE.
+*/
+static char default_output_buffer[sizeof(default_input_buffer)];
+
+
+
+#ifdef RW_MAX
+#undef RW_MAX
+#endif
+
+#if DK4_ON_WINDOWS
+/** Maximum number of bytes for read or write operation.
+*/
+#define RW_MAX (INT_MAX)
+#else
+/** Maximum number of bytes for read or write operation.
+*/
+#define RW_MAX ((SIZE_MAX) / 2U)
+#endif
+
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+/** Check whether we can continue or if a signal was received.
+ @param check_pipe Flag: Check for occured SIGPIPE signal too.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(int check_pipe)
+{
+ int back = 1;
+#ifdef SIGPIPE
+ if (0 != check_pipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_int )) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+static
+void
+dk_blks_transfer(char *ib, char *ob, size_t bs)
+{
+ int cc = 1; /* Flag: Can continue */
+ size_t irdb = 0; /* Bytes in input buffer */
+ size_t iused = 0; /* Input bytes used */
+ size_t oused = 0; /* Output bytes used */
+ size_t iavail; /* Input bytes available */
+ size_t oavail; /* Output bytes available */
+ size_t bcp; /* Bytes to copy */
+#if DK4_ON_WINDOWS
+ int rdres; /* Number of bytes read */
+ int wrres; /* Number of bytes written */
+#else
+ ssize_t rdres; /* Number of bytes read */
+ ssize_t wrres; /* Number of bytes written */
+#endif
+ dk4_sig_atomic_t shp; /* Had pipe */
+ $? "+ dk_blks_transfer"
+ /* Process input
+ */
+ exval = EXIT_SUCCESS;
+ do {
+ if (1 == sig_can_continue(0)) {
+ errno = 0; $? ". attempt to read"
+#if DK4_ON_WINDOWS
+ rdres = _read(0, ib, (unsigned)bs);
+#else
+ rdres = read(0, ib, bs);
+#endif
+ if (0 < rdres) { $? ". bytes found %u", (unsigned)rdres
+ irdb = rdres;
+ iused = 0;
+ while(iused < irdb) {
+ /* Find number of bytes we can add to output buffer */
+ iavail = irdb - iused;
+ oavail = bs - oused;
+ if (iavail < oavail) {
+ bcp = iavail;
+ } else {
+ bcp = oavail;
+ }
+ /* Add bytes to output buffer */
+ DK4_MEMCPY(&(ob[oused]), &(ib[iused]), bcp);
+ /* Increased number of used bytes for both input and output */
+ oused += bcp;
+ iused += bcp;
+ /* Flush output buffer when full */
+ if (oused >= bs) {
+#ifdef SIGPIPE
+ shp = sig_read_atomic(&sig_had_pipe);
+#else
+ shp = 0;
+#endif
+ if (0 == shp) {
+ errno = 0;
+#if DK4_ON_WINDOWS
+ wrres = _write(1, ob, (unsigned)bs);
+#else
+ wrres = write(1, ob, bs);
+#endif
+ if (0 <= wrres) {
+ if (wrres < bs) {
+ /* ERROR: Not all bytes written */
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 0);
+ exval = EXIT_FAILURE;
+ cc = -1;
+ }
+ } else {
+ /* ERROR Write attempt failed */
+ dk4fd_write_error_msg(app, kwnl[4], errno);
+ exval = EXIT_FAILURE;
+ cc = -1;
+ }
+ }
+ oused = 0;
+ }
+ }
+ } else {
+ if (0 == rdres) { $? ". end of input"
+ cc = 0;
+ } else { $? ". read error"
+ /* ERROR: Read operation failed */
+ dk4fd_read_error_msg(app, kwnl[3], errno);
+ cc = 0;
+ exval = EXIT_FAILURE;
+ }
+ }
+#if DK4_ON_WINDOWS
+ if (_eof(0)) {
+ cc = 0;
+ }
+#endif
+ } else {
+ cc = -1;
+ }
+ } while (1 == cc);
+
+ /* Flush output buffer */
+ if (0 == cc) {
+ if (0 < oused) {
+#ifdef SIGPIPE
+ shp = sig_read_atomic(&sig_had_pipe);
+#else
+ shp = 0;
+#endif
+ if (0 == shp) {
+ errno = 0;
+#if DK4_ON_WINDOWS
+ wrres = _write(1, ob, (unsigned)oused);
+#else
+ wrres = write(1, ob, oused);
+#endif
+ if (0 <= wrres) {
+ if (wrres < oused) {
+ /* ERROR: Not all bytes written */
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 0);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Write attempt failed */
+ dk4fd_write_error_msg(app, kwnl[4], errno);
+ exval = EXIT_FAILURE;
+ }
+ }
+ }
+ }
+
+ /* Finally zero-fill used buffers.
+ */
+ if (0 == dk4mem_reset_secure(ib, bs, NULL)) {
+ /* ERROR: Secure memory reset failed */
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 1);
+ exval = EXIT_FAILURE;
+ }
+ if (0 == dk4mem_reset_secure(ob, bs, NULL)) {
+ /* ERROR: Secure memory reset failed */
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 1);
+ exval = EXIT_FAILURE;
+ }
+
+ $? "- dk_blks_transfer"
+}
+
+
+
+static
+void
+dk_blks_with_buffers(char *ib, char *ob, size_t bs)
+{
+#if DK4_ON_WINDOWS
+ int oldinmode = 0;
+ int oldoutmode = 0;
+#endif
+ if ((dk4_um_t)RW_MAX >= (dk4_um_t)bs) {
+#if DK4_ON_WINDOWS
+ oldinmode = _setmode(0, _O_BINARY);
+ oldoutmode = _setmode(1, _O_BINARY);
+#endif
+ dk_blks_transfer(ib, ob, bs);
+#if DK4_ON_WINDOWS
+ _setmode(1, oldoutmode);
+ _setmode(0, oldinmode);
+#endif
+ } else {
+ /* ERROR: Block size too large */
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 2);
+ }
+}
+
+
+
+/** Run normally.
+*/
+static
+void
+dk_blks_normal_run(void)
+{
+ char *myib;
+ char *myob;
+ size_t mybs = DK_BLKS_DEFAULT_BLOCK_SIZE;
+ int res = 0;
+ $? "+ dk_blks_normal_run"
+ if (0 != dk4app_opt_is_set_short(app, dkT('b'), NULL)) {
+ res = dk4app_opt_get_size_short(&mybs, app, dkT('b'), NULL);
+ if (0 == res) {
+ mybs = DK_BLKS_DEFAULT_BLOCK_SIZE;
+ }
+ }
+ if ((0 < mybs) && (mybs <= DK_BLKS_DEFAULT_BLOCK_SIZE)) {
+ dk_blks_with_buffers(
+ default_input_buffer,
+ default_output_buffer,
+ mybs
+ );
+ } else {
+ if (0 < mybs) {
+ myib = (char *)dk4mem_calloc_app(1, mybs, app);
+ if (NULL != myib) {
+ myob = (char *)dk4mem_calloc_app(1, mybs, app);
+ if (NULL != myob) {
+ dk_blks_with_buffers(myib, myob, mybs);
+ dk4mem_free(myob);
+ }
+ dk4mem_free(myib);
+ }
+ } else {
+ /* ERROR: Illegal block size */
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 3);
+ }
+ }
+ $? "- dk_blks_normal_run"
+}
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+run_with_signals(void)
+{
+#ifdef SIGPIPE
+ struct sigaction opipe;
+#endif
+ struct sigaction oint;
+ struct sigaction oterm;
+#ifdef SIGPIPE
+ struct sigaction npipe;
+#endif
+ struct sigaction nint;
+ struct sigaction nterm;
+ int success = 0;
+
+#ifdef SIGPIPE
+ /* Set up signal handling for SIGPIPE.
+ */
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 4);
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 4);
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 4);
+ goto finished;
+ }
+#endif
+
+ /* Set up signal handling for SIGINT.
+ */
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 4);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 4);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 4);
+ goto restore_old_pipe;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 4);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 4);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 4);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ dk_blks_normal_run();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 5);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 5);
+ success = 0;
+ }
+
+#ifdef SIGPIPE
+ /* Restore signal handling for SIGPIPE.
+ */
+ restore_old_pipe:
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 5);
+ success = 0;
+ }
+#endif
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+run_with_signals(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ dk_blks_normal_run();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+#ifdef SIGPIPE
+ sigset(SIGPIPE, oldpipe);
+#endif
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+run_with_signals(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = signal(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ dk_blks_normal_run();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+#ifdef SIGPIPE
+ signal(SIGPIPE, oldpipe);
+#endif
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+run_with_signals(void)
+{
+ dk_blks_normal_run();
+}
+#endif
+#endif
+#endif
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ dkChar const *xargv;
+ int xargc;
+ int i;
+ $!trace-init dk-blks.deb
+ $? "+ main"
+ app = dk4app_open_cmd(
+ argc, argv, options, sz_options, kwnl[0], DKT_VERSION_DK,
+ kwnl[1], help_text, license_text
+ );
+ if (NULL != app) {
+ sz_msg = dk4app_string_table_size(kw_def);
+ dk_blks_msg = dk4app_string_table(app, kwnl[2], kw_def);
+ if (0 != dk4app_can_run_normally(app)) {
+ run_with_signals();
+ xargc = dk4app_get_argc(app);
+ if (0 < xargc) {
+ for (i = 0; i < xargc; i++) {
+ xargv = dk4app_get_argv(app, i);
+ if (NULL != xargv) {
+ dk4app_log_3(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 8, 9, xargv);
+ exval = EXIT_FAILURE;
+ }
+ }
+ }
+#ifdef SIGPIPE
+ if (0 != sig_read_atomic(&sig_had_pipe)) {
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 6);
+ exval = EXIT_FAILURE;
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_int)) {
+ dk4app_log_1(app, dk_blks_msg, sz_msg, DK4_LL_ERROR, 7);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ dk4app_close(app); app = NULL;
+ } else {
+ }
+ $? "- main %d", exval
+ $!trace-end
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/dk-blks.rc b/support/dktools/dk-blks.rc
new file mode 100644
index 0000000000..809f56dcc9
--- /dev/null
+++ b/support/dktools/dk-blks.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Blocksize corrector, creates sequence of fixed size blocks\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "Blocksize corrector, creates sequence of fixed size blocks\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "dk-blks\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/dk-bmm.c b/support/dktools/dk-bmm.c
new file mode 100644
index 0000000000..701155d934
--- /dev/null
+++ b/support/dktools/dk-bmm.c
@@ -0,0 +1,2119 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk-bmm.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk-bmm.c The dk-bmm module.
+*/
+
+
+#line 10 "dk-bmm.ctr"
+
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_TIME_WITH_SYS_TIME
+#ifndef SYS_TIME_H_INCLUDED
+#include <sys/time.h>
+#define SYS_TIME_H_INCLUDED 1
+#endif
+#ifndef TIME_H_INCLUDED
+#include <time.h>
+#define TIME_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_TIME_H
+#ifndef TIME_H_INCLUDED
+#include <time.h>
+#define TIME_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_SYS_TIME_H
+#ifndef SYS_TIME_H_INCLUDED
+#include <sys/time.h>
+#define SYS_TIME_H_INCLUDED 1
+#endif
+#endif
+#endif
+#endif
+
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4mem.h"
+#include "dk4app.h"
+#include "dk4vers.h"
+#include "dk4fput.h"
+#include "dk4str8.h"
+#include "dk4strd.h"
+#include "dk4enc.h"
+#include "dk4tsp08.h"
+#include "dk4tspdk.h"
+#include "dk4mai8dus.h"
+#include "dk4mai8ddu.h"
+#include "dk4maidddu.h"
+#include "dk4mao8d.h"
+#include "dk4maodd.h"
+#include "dk4fopda.h"
+#include "dk4isadm.h"
+#include "dk4timec.h"
+#include "dk4time08.h"
+#include "dk4aopt.h"
+#include "dk4mpl.h"
+#include "dk4pathd.h"
+
+
+
+
+
+#line 131 "dk-bmm.ctr"
+
+
+
+/** Information about one media.
+*/
+typedef struct {
+ unsigned short year; /**< Year of last backup. */
+ unsigned short month; /**< Month of last backup. */
+ unsigned short day; /**< Day within month of last backup. */
+ unsigned short hour; /**< Hour of last backup. */
+ unsigned short minute; /**< Minute of last backup. */
+ unsigned short second; /**< Second of last backup. */
+ unsigned short times; /**< How many times was the media used. */
+} dk_bmm_media_t;
+
+
+
+/** Line handler object.
+*/
+typedef struct {
+ int *backptr; /**< Address of result variable. */
+} dk_bmm_lh_obj_t;
+
+
+
+/** Help text shown if no help text file found.
+*/
+static const dkChar * const dk_bmm_help_text[] = {
+dkT(""),
+dkT("Backup media management"),
+dkT(""),
+dkT("dk-bmm [<option(s)>] [<file>]"),
+dkT(""),
+dkT("Options:"),
+dkT("-s\t--set\t\tUse media sets instead of media."),
+dkT("-c\t--confirm\tConfirm success for backup."),
+dkT("-r\t--report\tCreate tape usage report."),
+dkT(""),
+dkT("--help\t\t\tShow this short help text."),
+dkT("--manual\t\t*** SHOW FULL MANUAL. ***"),
+dkT("--version\t\tShow version information."),
+dkT("--license\t\tShow version information."),
+dkT(""),
+dkT("Typical operations:"),
+dkT("dk-bmm -s <set-names-file>\tFind name of current backup set."),
+dkT("dk-bmm <media-file>\t\tFind number of current media in set."),
+dkT("dk-bmm -c <media-file>\t\tConfirm successful backup to current media."),
+dkT("dk-bmm -c -s <set-names-file>\tConfirm successful backup for current set."),
+dkT(""),
+dkT("http://dktools.sourceforge.net"),
+dkT(""),
+NULL
+
+
+#line 184 "dk-bmm.ctr"
+};
+
+
+
+/** License conditions.
+*/
+static const dkChar * const dk_bmm_license_text[] = {
+dkT(""),
+dkT("This software uses code from the following projects, either directly or as"),
+dkT("a library:"),
+dkT(""),
+dkT("dktools\t\tDirk Krause's tools and libraries."),
+dkT("\t\tSee http://dktools.sourceforge.net/ for more information."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT("zlib\t\tData compression library."),
+dkT("\t\tSee http://www.zlib.net/ for more information."),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT("bzip2\t\tData compression program and library."),
+dkT("\t\tSee http://www.bzip.org/ for more information."),
+#endif
+dkT(""),
+dkT("All the licenses below apply to the program."),
+dkT("Licenses for used libraries are shown as found on my Scientific Linux 6.x"),
+dkT("computer in the /usr/share/doc directory on 2015-04-01. Check the project"),
+dkT("homepages of the used libraries for additional information and/or updated"),
+dkT("license terms."),
+dkT(""),
+dkT(""),
+dkT("DK tools and libraries license"),
+dkT("=============================="),
+dkT("Copyright (c) 2015-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above copyright notice,"),
+dkT(" this list of conditions and the following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("* Neither the name of the Dirk Krause nor the names of contributors may be"),
+dkT(" used to endorse or promote products derived from this software without"),
+dkT(" specific prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\""),
+dkT("AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED."),
+dkT(""),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,"),
+dkT("INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,"),
+dkT("BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,"),
+dkT("DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY"),
+dkT("OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,"),
+dkT("EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT(""),
+dkT("Zlib license"),
+dkT("============"),
+dkT("(C) 1995-2004 Jean-loup Gailly and Mark Adler"),
+dkT(""),
+dkT("This software is provided 'as-is', without any express or implied"),
+dkT("warranty. In no event will the authors be held liable for any damages"),
+dkT("arising from the use of this software."),
+dkT(""),
+dkT("Permission is granted to anyone to use this software for any purpose,"),
+dkT("including commercial applications, and to alter it and redistribute it"),
+dkT("freely, subject to the following restrictions:"),
+dkT(""),
+dkT("1. The origin of this software must not be misrepresented; you must not"),
+dkT(" claim that you wrote the original software. If you use this software"),
+dkT(" in a product, an acknowledgment in the product documentation would be"),
+dkT(" appreciated but is not required."),
+dkT("2. Altered source versions must be plainly marked as such, and must not be"),
+dkT(" misrepresented as being the original software."),
+dkT("3. This notice may not be removed or altered from any source distribution."),
+dkT(""),
+dkT("Jean-loup Gailly Mark Adler"),
+dkT("jloup@gzip.org madler@alumni.caltech.edu"),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT(""),
+dkT("Bzip2 and libbzip2 library license"),
+dkT("=================================="),
+dkT("This program, \"bzip2\", the associated library \"libbzip2\", and all"),
+dkT("documentation, are copyright (C) 1996-2007 Julian R Seward. All"),
+dkT("rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions"),
+dkT("are met:"),
+dkT(""),
+dkT("1. Redistributions of source code must retain the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer."),
+dkT(""),
+dkT("2. The origin of this software must not be misrepresented; you must "),
+dkT(" not claim that you wrote the original software. If you use this "),
+dkT(" software in a product, an acknowledgment in the product "),
+dkT(" documentation would be appreciated but is not required."),
+dkT(""),
+dkT("3. Altered source versions must be plainly marked as such, and must"),
+dkT(" not be misrepresented as being the original software."),
+dkT(""),
+dkT("4. The name of the author may not be used to endorse or promote "),
+dkT(" products derived from this software without specific prior written "),
+dkT(" permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS"),
+dkT("OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED"),
+dkT("WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE"),
+dkT("GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS"),
+dkT("INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,"),
+dkT("WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS"),
+dkT("SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+dkT(""),
+dkT("Julian Seward, jseward@bzip.org"),
+dkT("bzip2/libbzip2 version 1.0.5 of 10 December 2007"),
+#endif
+dkT(""),
+NULL
+
+
+#line 316 "dk-bmm.ctr"
+};
+
+
+
+/** Buffer to save set names line.
+*/
+static dkChar dk_bmm_set_line[1024];
+
+
+
+/** Buffer for reading the line.
+*/
+static dkChar dk_bmm_set_buffer[1024];
+
+
+
+/** Pointers to all the set names.
+*/
+static dkChar *dk_bmm_set_names[512];
+
+
+
+/** Constant text keywords used by the program, not localized.
+*/
+static const dkChar * const dk_bmm_kwnl[] = {
+/* 0 */
+dkT("dktools"),
+
+/* 1 */
+dkT("dk-bmm.txt"),
+
+/* 2 */
+dkT("dk-bmm.str"),
+
+/* 3 */
+dkT("\\"),
+
+/* 4 */
+dkT("rb"),
+
+/* 5 */
+dkT("w"),
+
+NULL
+
+
+#line 367 "dk-bmm.ctr"
+};
+
+
+
+/** Constant text keywords used by the program, localized.
+*/
+static const dkChar * const dk_bmm_kw_def[] = {
+/* 0 */
+dkT("Failed to set up signal handlers!"),
+
+/* 1 */
+dkT("Failed to restore signal handlers!"),
+
+/* 2 */
+dkT("Write attempt to standard output failed!"),
+
+/* 3 */
+dkT("SIGPIPE signal received!"),
+
+/* 4 */
+dkT("Aborted by SIGINT signal!"),
+
+/* 5 */
+dkT("Aborted by SIGTERM signal!"),
+
+/* 6 */
+dkT(" (previous cycle)"),
+
+/* 7 */
+dkT("Media number for next backup: "),
+
+/* 8 */
+dkT("Option -r is not available for a set names file."),
+
+/* 9 */
+dkT("Failed to read file, probably not a dk-bmm file!"),
+
+/* 10 */
+dkT("Exactly one file name allowed!"),
+
+/* 11 */
+dkT("Cycle completed, please renew media set!"),
+
+/* 12 */
+dkT("Failed to write new set file!"),
+
+/* 13 */
+dkT("Not a set names file!"),
+
+NULL
+
+
+#line 432 "dk-bmm.ctr"
+};
+
+
+
+/** Options understood by the program.
+*/
+static const dk4_option_specification_t dk_bmm_options[] = {
+ /*
+ Process media sets, not media.
+ */
+ { dkT('s'), dkT("set"), DK4_OPT_ARG_NONE },
+
+ /*
+ Confirm previously requested media set or media.
+ */
+ { dkT('c'), dkT("confirm"), DK4_OPT_ARG_NONE },
+
+ /*
+ Report media.
+ */
+ { dkT('r'), dkT("report"), DK4_OPT_ARG_NONE },
+};
+
+
+
+/** Media numbers in order of usage.
+ This implements the 10 tape rotation scheme.
+ At every time we will have backups of different ages.
+ During 200 backups each of the 10 media is used 20 times.
+*/
+static const unsigned char dk_bmm_media_numbers[] = {
+ 1, 2, 3, 4, 5, 1, 2, 3, 4, 6,
+ 1, 2, 3, 4, 7, 1, 2, 3, 4, 8,
+ 2, 3, 4, 5, 6, 2, 3, 4, 5, 7,
+ 2, 3, 4, 5, 8, 2, 3, 4, 5, 9,
+ 3, 4, 5, 6, 7, 3, 4, 5, 6, 8,
+ 3, 4, 5, 6, 9, 3, 4, 5, 6, 10,
+ 4, 5, 6, 7, 8, 4, 5, 6, 7, 9,
+ 4, 5, 6, 7, 10, 4, 5, 6, 7, 1,
+ 5, 6, 7, 8, 9, 5, 6, 7, 8, 10,
+ 5, 6, 7, 8, 1, 5, 6, 7, 8, 2,
+ 6, 7, 8, 9, 10, 6, 7, 8, 9, 1,
+ 6, 7, 8, 9, 2, 6, 7, 8, 9, 3,
+ 7, 8, 9, 10, 1, 7, 8, 9, 10, 2,
+ 7, 8, 9, 10, 3, 7, 8, 9, 10, 4,
+ 8, 9, 10, 1, 2, 8, 9, 10, 1, 3,
+ 8, 9, 10, 1, 4, 8, 9, 10, 1, 5,
+ 9, 10, 1, 2, 3, 9, 10, 1, 2, 4,
+ 9, 10, 1, 2, 5, 9, 10, 1, 2, 6,
+ 10, 1, 2, 3, 4, 10, 1, 2, 3, 5,
+ 10, 1, 2, 3, 6, 10, 1, 2, 3, 7
+};
+
+
+/** Information for the 10 media in the backup scheme.
+*/
+static dk_bmm_media_t media_info[10];
+
+
+
+/** Flag: Media found for recoding.
+*/
+static unsigned short media_found[10];
+
+
+
+/** Pointer to either localized messages or default texts.
+*/
+static const dkChar * const *dk_bmm_msg = dk_bmm_kw_def;
+
+
+
+/** Application structure for diagnostics.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Number of used names in dk_bmm_set_names.
+*/
+static size_t dk_bmm_n_set_names = 0;
+
+
+
+/** Number of elements in the dk_bmm_options array.
+*/
+static const size_t dk_bmm_sz_options =
+sizeof(dk_bmm_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Number of elements in the dk_bmm_msg array.
+*/
+static size_t dk_bmm_sz_msg =
+sizeof(dk_bmm_kw_def)/sizeof(DK4_PCDKCHAR) - 1;
+
+
+
+/** Exit status code of the program.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+/** Flag: Dealing with media set.
+*/
+static int dk_bmm_handle_set = 0;
+
+
+
+/** Flag: Confirm previous media or set.
+*/
+static int dk_bmm_do_confirm = 0;
+
+
+
+/** Flag: Write report.
+*/
+static int dk_bmm_do_report = 0;
+
+
+
+/** Flag: Output mode for stdout was changed.
+*/
+static int dk_bmm_mod_stdout = 0;
+
+
+
+/** Number of recent day within backup cycle.
+*/
+static int dk_bmm_day_in_cycle = 0;
+
+
+
+/** Flag: Cycle was completed.
+*/
+static int dk_bmm_cycle_completed = 0;
+
+
+/** Flag: Write attempt to stdout failed.
+*/
+static int output_error = 0;
+
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+/** Check whether we can continue or if a signal was received.
+ @param check_pipe Flag: Check for occured SIGPIPE signal too.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(int check_pipe)
+{
+ int back = 1;
+#ifdef SIGPIPE
+ if (0 != check_pipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_int )) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+/** Check whether we can continue.
+ @return 1 for yes, 0 for no.
+*/
+static
+int
+dk_bmm_can_continue(void)
+{
+ int back = 1;
+ if (0 == sig_can_continue(1)) {
+ back = 0;
+ }
+ return back;
+}
+
+
+
+/** Handler function for text lines.
+ @param obj Object to modify while processing the character.
+ @param line Text line to process.
+ @param lineno Current line number.
+ @param erp Error report, may be NULL.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+dk_bmm_sets_line_handler(
+ void *obj,
+ dkChar *line,
+ dk4_um_t lineno,
+ dk4_er_t *erp
+)
+{
+ dk_bmm_lh_obj_t *lhoptr;
+ dkChar *p1;
+ const dkChar *pe;
+ dk4_um_t um;
+ size_t i;
+ size_t al;
+ int res;
+ int back = DK4_TSP_RES_FATAL;
+
+
+#line 722 "dk-bmm.ctr"
+ lhoptr = (dk_bmm_lh_obj_t *)obj;
+ if ((dk4_um_t)1UL == lineno) {
+
+#line 724 "dk-bmm.ctr"
+ dk4str_delnl(line);
+ res = dk4str_cpy_s(
+ dk_bmm_set_line, DK4_SIZEOF(dk_bmm_set_line,dkChar), line, NULL
+ );
+ if (0 != res) {
+ al = sizeof(dk_bmm_set_names)/sizeof(DK4_PDKCHAR);
+ for (i = 0; i < al; i++) { dk_bmm_set_names[i] = NULL; }
+ i = dk4str_tokenize(dk_bmm_set_names, al, dk_bmm_set_line, NULL, NULL);
+ if (0 < i) {
+ dk_bmm_n_set_names = i;
+ back = DK4_TSP_RES_OK;
+ }
+ }
+ } else {
+ if ((dk4_um_t)2UL == lineno) {
+
+#line 739 "dk-bmm.ctr"
+ dk4str_delnl(line);
+ p1 = dk4str_start(line, NULL);
+ if (NULL != p1) {
+ pe = NULL;
+ um = (dk4_um_t)0UL;
+ res = dk4ma_input_dk_dec_dk4_um_t(
+ &um, p1, &pe, 1, NULL
+ );
+ if (0 != res) {
+ if ((dk4_um_t)INT_MAX >= um) {
+ dk_bmm_day_in_cycle = (int)um;
+ if ((dk4_um_t)dk_bmm_n_set_names > dk_bmm_day_in_cycle) {
+ back = DK4_TSP_RES_OK;
+ }
+ }
+ }
+ } else {
+ back = DK4_TSP_RES_OK;
+ }
+ } else {
+
+#line 759 "dk-bmm.ctr"
+ }
+ }
+ if ((DK4_TSP_RES_FATAL == back) || (DK4_TSP_RES_ERROR == back)) {
+ *(lhoptr->backptr) = 0;
+ }
+
+#line 764 "dk-bmm.ctr"
+ return back;
+}
+
+
+
+/** Read sets file.
+ @param filename Name of file to read.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk_bmm_read_sets_file(const dkChar *filename)
+{
+ dk4_er_t er;
+ dk4_tspdk_t tspdk;
+ dk_bmm_lh_obj_t lhoptr;
+ FILE *fipo;
+ int res;
+ int c;
+ int cc = 1;
+ int back = 0;
+
+
+#line 786 "dk-bmm.ctr"
+ fipo = dk4fopen_app(filename, dk_bmm_kwnl[4], DK4_FOPEN_SC_IS_REGULAR, app);
+ if (NULL != fipo) {
+ lhoptr.backptr = &back;
+ dk4error_init(&er);
+ res = dk4tspdk_setup_line(
+ &tspdk, &lhoptr, dk_bmm_sets_line_handler,
+ dk_bmm_set_buffer, DK4_SIZEOF(dk_bmm_set_buffer,dkChar),
+ dk4app_get_encoding(app),
+ dk4app_get_file_in_encoding(app),
+ &er
+ );
+ if (0 != res) {
+ back = 1;
+ while (1 == cc) {
+ if (0 != dk_bmm_can_continue()) {
+ c = fgetc(fipo);
+ if (EOF != c) {
+ if (0 != feof(fipo)) { cc = 0; }
+ res = dk4tspdk_add_one_byte(&tspdk, (unsigned char)c);
+ switch (res) {
+ case DK4_TSP_RES_ERROR: case DK4_TSP_RES_FATAL: {
+ cc = -1;
+ } break;
+ }
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = -1;
+ }
+ }
+ if (0 == cc) {
+ res = dk4tspdk_finish(&tspdk);
+ switch (res) {
+ case DK4_TSP_RES_ERROR: case DK4_TSP_RES_FATAL: {
+ back = 0;
+ } break;
+ }
+ } else {
+ back = 0;
+ }
+ } else {
+ /* ERROR: Failed to set up line processing, bug */
+ }
+ fclose(fipo);
+ }
+
+#line 832 "dk-bmm.ctr"
+ return back;
+}
+
+
+
+
+/** Initialize the media_info structures.
+*/
+static
+void
+dk_bmm_initialize_media_info(void)
+{
+ size_t i;
+ for (i = 0; i < 10; i++) {
+ media_info[i].year =
+ media_info[i].month =
+ media_info[i].day =
+ media_info[i].hour =
+ media_info[i].minute =
+ media_info[i].second =
+ media_info[i].times = 0U;
+ }
+}
+
+
+
+static
+int
+dk_bmm_data_line(dk_bmm_media_t *mptr, char *line)
+{
+ const char *ep;
+ int back = 0;
+
+
+#line 865 "dk-bmm.ctr"
+ if (21 > dk4str8_len(line)) {
+
+
+#line 867 "dk-bmm.ctr"
+ goto finished;
+ }
+ if ('-' != line[4]) {
+
+
+#line 871 "dk-bmm.ctr"
+ goto finished;
+ }
+ line[4] = '\0';
+ if ('-' != line[7]) {
+
+
+#line 876 "dk-bmm.ctr"
+ goto finished;
+ }
+ line[7] = '\0';
+ if (' ' != line[10]) {
+
+
+#line 881 "dk-bmm.ctr"
+ goto finished;
+ }
+ line[10] = '\0';
+ if (':' != line[13]) {
+
+
+#line 886 "dk-bmm.ctr"
+ goto finished;
+ }
+ line[13] = '\0';
+ if (':' != line[16]) {
+
+
+#line 891 "dk-bmm.ctr"
+ goto finished;
+ }
+ line[16] = '\0';
+ if (' ' != line[19]) {
+
+
+#line 896 "dk-bmm.ctr"
+ goto finished;
+ }
+ line[19] = '\0';
+ ep = NULL;
+ if (0 == dk4ma_input_c8_dec_ushort(&(mptr->year), line, &ep, 0, NULL)) {
+
+
+#line 902 "dk-bmm.ctr"
+ goto finished;
+ }
+ if (0 == dk4ma_input_c8_dec_ushort(&(mptr->month),&(line[5]),&ep,0,NULL)) {
+
+
+#line 906 "dk-bmm.ctr"
+ goto finished;
+ }
+ if (0 == dk4ma_input_c8_dec_ushort(&(mptr->day),&(line[8]),&ep,0,NULL)) {
+
+
+#line 910 "dk-bmm.ctr"
+ goto finished;
+ }
+ if (0 == dk4ma_input_c8_dec_ushort(&(mptr->hour),&(line[11]),&ep,0,NULL)) {
+
+
+#line 914 "dk-bmm.ctr"
+ goto finished;
+ }
+ if (0 == dk4ma_input_c8_dec_ushort(&(mptr->minute),&(line[14]),&ep,0,NULL)) {
+
+
+#line 918 "dk-bmm.ctr"
+ goto finished;
+ }
+ if (0 == dk4ma_input_c8_dec_ushort(&(mptr->second),&(line[17]),&ep,0,NULL)) {
+
+
+#line 922 "dk-bmm.ctr"
+ goto finished;
+ }
+ if (0 == dk4ma_input_c8_dec_ushort(&(mptr->times),(&line[20]),&ep,0,NULL)) {
+
+
+#line 926 "dk-bmm.ctr"
+ goto finished;
+ }
+ back = 1;
+ finished:
+
+
+#line 931 "dk-bmm.ctr"
+ return back;
+}
+
+
+
+/** Handler function for text lines.
+ @param obj Object to modify while processing the character.
+ @param line Text line to process.
+ @param lineno Current line number.
+ @param erp Error report, may be NULL.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+dk_bmm_media_line_handler(
+ void *obj,
+ char *line,
+ dk4_um_t lineno,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er;
+ dk_bmm_lh_obj_t *lhoptr;
+ const char *endptr = NULL;
+ dk4_um_t um;
+ int res;
+ int back = DK4_TSP_RES_FATAL;
+
+
+#line 964 "dk-bmm.ctr"
+ lhoptr = (dk_bmm_lh_obj_t *)obj;
+ dk4str8_delnl(line);
+ if ((dk4_um_t)1UL == lineno) {
+
+#line 967 "dk-bmm.ctr"
+ /*
+ Process first line
+ */
+ dk4error_init(&er);
+ res = dk4ma_input_c8_dec_dk4_um_t(&um, line, &endptr, 1, &er);
+ if (0 != res) {
+ if ((dk4_um_t)200UL > um) {
+ dk_bmm_day_in_cycle = (int)um;
+ back = DK4_TSP_RES_OK;
+ } else {
+ /* ERROR: Out of range */
+ }
+ } else {
+ /* ERROR: Failed to read number */
+ }
+ } else {
+ if (((dk4_um_t)2UL <= lineno) && ((dk4_um_t)11UL >= lineno)) {
+ /*
+ Process data line
+ */
+ lineno -= (dk4_um_t)2UL;
+
+#line 988 "dk-bmm.ctr"
+ if (0 != dk_bmm_data_line(&(media_info[(size_t)lineno]), line)) {
+ back = DK4_TSP_RES_OK;
+ } else {
+ /* ERROR: Syntax */
+ }
+ } else {
+
+#line 994 "dk-bmm.ctr"
+ /* ERROR: Syntax, too many lines */
+ }
+ }
+ if (DK4_TSP_RES_OK != back) { *(lhoptr->backptr) = 0; }
+
+
+#line 999 "dk-bmm.ctr"
+ return back;
+}
+
+
+
+/** Read media file.
+ @param filename Name of media file to read.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk_bmm_read_media_file(const dkChar *filename)
+{
+ char inb[256];
+ dk4_tsp08_t tsp08;
+ dk4_er_t er;
+ dk_bmm_lh_obj_t obj;
+ FILE *fipo = NULL;
+ int c;
+ int res;
+ int cc = 1;
+ int back = 0;
+
+
+#line 1022 "dk-bmm.ctr"
+ obj.backptr = &back;
+ fipo = dk4fopen_app(filename, dk_bmm_kwnl[4], DK4_FOPEN_SC_IS_REGULAR, app);
+ if (NULL != fipo) {
+ dk4error_init(&er);
+ res = dk4tsp08_setup_line(
+ &tsp08, &obj, dk_bmm_media_line_handler, inb, sizeof(inb),
+ DK4_ENCODING_ASCII, dk4app_get_file_in_encoding(app), &er
+ );
+ if (0 != res) {
+ back = 1;
+ while (1 == cc) {
+ if (0 != dk_bmm_can_continue()) {
+ c = fgetc(fipo);
+ if (EOF != c) {
+ if (0 != feof(fipo)) { cc = 0; }
+ res = dk4tsp08_add_one_byte(&tsp08, (unsigned char)c);
+ switch (res) {
+ case DK4_TSP_RES_ERROR: case DK4_TSP_RES_FATAL: {
+ cc = -1;
+ /* ERROR: Processing one byte failed */
+ } break;
+ }
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = -1;
+ }
+ }
+ if (0 == cc) {
+ res = dk4tsp08_finish(&tsp08);
+ switch (res) {
+ case DK4_TSP_RES_ERROR: case DK4_TSP_RES_FATAL: {
+ back = 0;
+ /* ERROR: Completing failed */
+ } break;
+ }
+ } else {
+ back = 0;
+ }
+ } else {
+ /* ERROR: Failed to set up line processing */
+ }
+ fclose(fipo);
+ } else {
+ back = 1;
+ }
+
+#line 1069 "dk-bmm.ctr"
+ return back;
+}
+
+
+
+static
+void
+dk_bmm_show_current_media_number(void)
+{
+ char buf[16*sizeof(dk4_um_t)];
+ int res;
+ unsigned char uc;
+
+ uc = dk_bmm_media_numbers[dk_bmm_day_in_cycle];
+ res = dk4ma_write_c8_decimal_unsigned(
+ buf, sizeof(buf), (dk4_um_t)uc, 0, NULL
+ );
+ if (0 != res) {
+ if (EOF == fputs(buf, stdout)) { output_error = 1; }
+ if (EOF == fputc('\n', stdout)) { output_error = 1; }
+ fflush(stdout);
+ } else {
+ /* ERROR: Failed to convert number, bug as buffer size is large enough. */
+ exval = EXIT_FAILURE;
+ }
+}
+
+
+
+static
+void
+dk_bmm_update_media_info(dk_bmm_media_t *mptr)
+{
+#if DK4_ON_WINDOWS
+ SYSTEMTIME st;
+ GetLocalTime(&st);
+ mptr->year = st.wYear;
+ mptr->month = st.wMonth;
+ mptr->day = st.wDay;
+ mptr->hour = st.wHour;
+ mptr->minute = st.wMinute;
+ mptr->second = st.wSecond;
+#else
+ time_t timer;
+ struct tm *tm;
+ time(&timer);
+ tm = localtime(&timer);
+ if (NULL != tm) {
+ mptr->year = 1900 + tm->tm_year;
+ mptr->month = 1 + tm->tm_mon;
+ mptr->day = tm->tm_mday;
+ mptr->hour = tm->tm_hour;
+ mptr->minute = tm->tm_min;
+ mptr->second = tm->tm_sec;
+ }
+#endif
+ mptr->times += 1;
+}
+
+
+
+static
+int
+dk_bmm_switch_to_next(const dkChar *filename)
+{
+ char buf[128];
+ FILE *fipo;
+ size_t mediano;
+ int tests;
+ int res;
+ int back = 0;
+
+
+#line 1141 "dk-bmm.ctr"
+ mediano = (size_t)(dk_bmm_media_numbers[dk_bmm_day_in_cycle]);
+
+
+#line 1143 "dk-bmm.ctr"
+ dk_bmm_update_media_info(&(media_info[mediano - 1]));
+ if (++dk_bmm_day_in_cycle >= 200) {
+
+#line 1145 "dk-bmm.ctr"
+ dk_bmm_day_in_cycle = 0;
+ dk_bmm_cycle_completed = 1;
+ for (mediano = 0; mediano < 10; mediano++) {
+ media_info[mediano].times = 0;
+ }
+ }
+ tests = DK4_FOPEN_SC_USER;
+ if (1 == dk4isadmin()) { tests = DK4_FOPEN_SC_PRIVILEGED; }
+ fipo = dk4fopen_app(filename, dk_bmm_kwnl[5], tests, app);
+ if (NULL != fipo) {
+
+#line 1155 "dk-bmm.ctr"
+ back = 1;
+ res = dk4ma_write_c8_decimal_signed(
+ buf, sizeof(buf), (dk4_im_t)dk_bmm_day_in_cycle, 0, NULL
+ );
+ if (0 != res) {
+
+#line 1160 "dk-bmm.ctr"
+ if (EOF == fputs(buf, fipo)) { back = 0; }
+ if (EOF == fputc('\n', fipo)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ for (mediano = 0; mediano < 10; mediano++) {
+ res = dk4time_to_text_c8(
+ buf, sizeof(buf), DK4_TIMEFORMAT_DATE_TIME,
+ media_info[mediano].year,
+ media_info[mediano].month,
+ media_info[mediano].day,
+ media_info[mediano].hour,
+ media_info[mediano].minute,
+ media_info[mediano].second,
+ NULL
+ );
+ if (0 != res) {
+
+#line 1177 "dk-bmm.ctr"
+ if (EOF == fputs(buf, fipo)) { back = 0; }
+ if (EOF == fputc(' ', fipo)) { back = 0; }
+ res = dk4ma_write_c8_decimal_unsigned(
+ buf, sizeof(buf), (dk4_um_t)(media_info[mediano].times), 0, NULL
+ );
+ if (0 != res) {
+ if (EOF == fputs(buf, fipo)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ if (EOF == fputc('\n', fipo)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ }
+ if (0 != fclose(fipo)) { back = 0; }
+ if (0 == back) {
+ exval = EXIT_FAILURE;
+ }
+ } else {
+
+#line 1197 "dk-bmm.ctr"
+ exval = EXIT_FAILURE;
+ }
+
+#line 1199 "dk-bmm.ctr"
+ return back;
+}
+
+
+
+/** Write a report of used media.
+*/
+static
+void
+dk_bmm_report_media(void)
+{
+ dkChar b1[16*sizeof(dk4_um_t)];
+ dkChar b3[16*sizeof(dk4_um_t)];
+ char b2[128];
+ char *ptr;
+ size_t i;
+ size_t j;
+ size_t mediano;
+ int res;
+ unsigned short nextlevel = 1;
+ for (i = 0; i < 10; i++) { media_found[i] = 0; }
+
+ if (0 < dk_bmm_day_in_cycle) {
+ for (i = 0; i < (size_t)dk_bmm_day_in_cycle; i++) {
+ j = (size_t)dk_bmm_day_in_cycle - 1 - i;
+ mediano = (size_t)(dk_bmm_media_numbers[j]);
+ if (0 == media_found[mediano - 1]) {
+ media_found[mediano - 1] = nextlevel++;
+
+
+#line 1228 "dk-bmm.ctr"
+ }
+ }
+ }
+ for (i = (size_t)dk_bmm_day_in_cycle; i < 200; i++) {
+ j = 199 - i;
+ mediano = (size_t)(dk_bmm_media_numbers[j]);
+ if (0 == media_found[mediano - 1]) {
+ media_found[mediano - 1] = nextlevel++;
+
+
+#line 1237 "dk-bmm.ctr"
+ }
+ }
+ dk_bmm_mod_stdout = 1;
+
+#line 1240 "dk-bmm.ctr"
+ dk4fput_initialize_stdout();
+ res = dk4ma_write_decimal_unsigned(
+ b1, DK4_SIZEOF(b1,dkChar),
+ (dk4_um_t)(dk_bmm_media_numbers[dk_bmm_day_in_cycle]),
+ 0, NULL
+ );
+ if (0 != res) {
+ if (0 == dk4fputs(dk_bmm_kw_def[7], stdout, NULL)) {
+ output_error = 1;
+ }
+ if (0 == dk4fputs(b1, stdout, NULL)) { output_error = 1; }
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) { output_error = 1; }
+ } else {
+ /* ERROR: Number conversion failed, bug as buffer is large enough. */
+ exval = EXIT_FAILURE;
+ }
+ for (i = 1; i < 11; i++) {
+ for (mediano = 1; mediano < 11; mediano++) {
+ if (media_found[mediano - 1] == i) {
+ res = dk4ma_write_decimal_unsigned(
+ b1, DK4_SIZEOF(b1,dkChar), (dk4_um_t)mediano, 2, NULL
+ );
+ if (0 != res) {
+ res = dk4time_to_text_c8(
+ b2, sizeof(b2), DK4_TIMEFORMAT_DATE_TIME,
+ media_info[mediano - 1].year,
+ media_info[mediano - 1].month,
+ media_info[mediano - 1].day,
+ media_info[mediano - 1].hour,
+ media_info[mediano - 1].minute,
+ media_info[mediano - 1].second,
+ NULL
+ );
+ if (0 != res) {
+ res = dk4ma_write_decimal_unsigned(
+ b3, DK4_SIZEOF(b3,dkChar),
+ (dk4_um_t)(media_info[mediano - 1].times),
+ 2, NULL
+ );
+ if (0 != res) {
+ if (0 == dk4fputs(b1, stdout, NULL)) { output_error = 1; }
+ for (j = 0; j < 3; j++) {
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) { output_error = 1; }
+ }
+ ptr = b2;
+ while ('\0' != *ptr) {
+ if (0 == dk4fputc((dkChar)(*(ptr++)), stdout, NULL)) {
+ output_error = 1;
+ }
+ }
+ for (j = 0; j < 3; j++) {
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) { output_error = 1; }
+ }
+ if (0 == dk4fputs(b3, stdout, NULL)) { output_error = 1; }
+ if (0 == media_info[mediano - 1].times) {
+ if (0 == dk4fputs(dk_bmm_kw_def[6], stdout, NULL)) {
+ output_error = 1;
+ }
+ }
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) { output_error = 1; }
+ } else {
+ /* ERROR: Number conversion failed, bug. */
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Date and time conversion failed, bug. */
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Number conversion failed, bug. */
+ exval = EXIT_FAILURE;
+ }
+ }
+ }
+ }
+}
+
+
+
+static
+void
+dk4_bmm_write_set_file(const dkChar *filename)
+{
+ dkChar buf[16*sizeof(dk4_um_t)];
+ const dkChar *oldsourcefile;
+ FILE *fipo = NULL;
+ dk4_um_t oldsourceline;
+ size_t i;
+ int res;
+ int we = 0;
+ int tests = DK4_FOPEN_SC_USER;
+
+
+#line 1332 "dk-bmm.ctr"
+ if (1 == dk4isadmin()) { tests = DK4_FOPEN_SC_PRIVILEGED; }
+ fipo = dk4fopen_app(filename, dk_bmm_kwnl[5], tests, app);
+ if (NULL != fipo) {
+
+#line 1335 "dk-bmm.ctr"
+ dk4fput_initialize_file(fipo);
+ for (i = 0; i < dk_bmm_n_set_names; i++) {
+ if (0 != i) {
+ if (0 == dk4fputc(dkT(' '), fipo, NULL)) {
+ we = 1;
+
+#line 1340 "dk-bmm.ctr"
+ }
+ }
+ if (0 == dk4fputs(dk_bmm_set_names[i], fipo, NULL)) {
+ we = 1;
+
+#line 1344 "dk-bmm.ctr"
+ }
+ }
+ if (0 == dk4fputc(dkT('\n'), fipo, NULL)) {
+
+#line 1347 "dk-bmm.ctr"
+ we = 1;
+ }
+ res = dk4ma_write_decimal_unsigned(
+ buf, DK4_SIZEOF(buf,dkChar), (dk4_um_t)dk_bmm_day_in_cycle, 0, NULL
+ );
+ if (0 != res) {
+ if (0 == dk4fputs(buf, fipo, NULL)) {
+
+#line 1354 "dk-bmm.ctr"
+ we = 1;
+ }
+ if (0 == dk4fputc(dkT('\n'), fipo, NULL)) {
+
+#line 1357 "dk-bmm.ctr"
+ we = 1;
+ }
+ } else {
+
+#line 1360 "dk-bmm.ctr"
+ /* ERROR: Number conversion failed, bug */
+ exval = EXIT_FAILURE;
+ }
+ if (0 != fclose(fipo)) {
+
+#line 1364 "dk-bmm.ctr"
+ we = 1;
+ }
+ if (0 != we) {
+ /* ERROR: Writing to file failed */
+ oldsourcefile = dk4app_get_log_source_file(app);
+ oldsourceline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_file(app, filename);
+ dk4app_set_log_source_line(app, (dk4_um_t)0UL);
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 12);
+ dk4app_set_log_source_file(app, oldsourcefile);
+ dk4app_set_log_source_line(app, oldsourceline);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ exval = EXIT_FAILURE;
+ }
+
+
+#line 1381 "dk-bmm.ctr"
+}
+
+
+
+#if DK4_CHAR_SIZE > 1
+
+/** Check whether a string can be written using 8 bit character width.
+ @param str String to test.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk_bmm_can_write_8bit(const dkChar *str)
+{
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ int back = 1;
+
+
+#line 1399 "dk-bmm.ctr"
+ while ((dkT('\0') != *str) && (1 == back)) {
+ if (dkC32(0xFF) < *str) {
+ back = 0;
+ }
+ str++;
+ }
+
+#line 1405 "dk-bmm.ctr"
+ return back;
+#else
+ dk4_utf16_decoder_t dec;
+ dk4_c32_t c32;
+ int back = 1;
+
+
+#line 1411 "dk-bmm.ctr"
+ dk4utf16_init(&dec);
+ while((dkT('\0') != *str) && (1 == back)) {
+ switch (dk4utf16_add(&dec, *str)) {
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf16_get(&dec);
+ if (dkC32(0x7F) < c32) {
+ back = 0;
+ }
+ } break;
+ case DK4_EDSTM_ERROR: {
+ back = 0;
+ } break;
+ }
+ str++;
+ }
+ if (1 == back) {
+ if (0 == dk4utf16_is_empty(&dec)) { back = 0; }
+ }
+
+#line 1429 "dk-bmm.ctr"
+ return back;
+#endif
+#else
+
+
+#line 1433 "dk-bmm.ctr"
+ return 1;
+#endif
+}
+
+
+
+/** Write string using 8 bit character functions.
+ @param str String to write.
+*/
+static
+void
+dk_bmm_write_8bit(const dkChar *str)
+{
+#if DK4_CHAR_SIZE > 2
+
+
+#line 1448 "dk-bmm.ctr"
+ while (dkT('\0') != *str) {
+ if (EOF == fputc((char)((unsigned char)(*(str++))), stdout)) {
+ output_error = 1;
+ }
+ } $$? "- dk_bmm_write_8bit"
+#else
+ dk4_utf16_decoder_t dec;
+ dk4_c32_t c32;
+ int back = 1;
+
+
+#line 1458 "dk-bmm.ctr"
+ dk4utf16_init(&dec);
+ while((dkT('\0') != *str) && (1 == back)) {
+ switch (dk4utf16_add(&dec, *str)) {
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf16_get(&dec);
+ if (dkC32(0xF0) > c32) {
+ if (EOF == fputc((char)((unsigned char)c32), stdout)) {
+ output_error = 1;
+ back = 0;
+ }
+ }
+ } break;
+ case DK4_EDSTM_ERROR: {
+ back = 0;
+ } break;
+ }
+ str++;
+ }
+
+#line 1476 "dk-bmm.ctr"
+#endif
+}
+
+#endif
+
+
+
+/** Write current media set name to stdout.
+*/
+static
+void
+dk_bmm_write_set_name(void)
+{
+ const dkChar *sn = NULL;
+
+
+#line 1491 "dk-bmm.ctr"
+ if ((dk4_um_t)dk_bmm_day_in_cycle < (dk4_um_t)dk_bmm_n_set_names) {
+ sn = dk_bmm_set_names[(size_t)dk_bmm_day_in_cycle];
+ }
+ if (NULL != sn) {
+#if DK4_CHAR_SIZE > 1
+
+
+#line 1497 "dk-bmm.ctr"
+ if (0 != dk_bmm_can_write_8bit(sn)) {
+
+#line 1498 "dk-bmm.ctr"
+ dk_bmm_write_8bit(sn);
+ if (EOF == fputc('\n', stdout)) { output_error = 1; }
+ } else {
+
+#line 1501 "dk-bmm.ctr"
+ dk_bmm_mod_stdout = 1;
+
+#line 1502 "dk-bmm.ctr"
+ dk4fput_initialize_stdout();
+ if (0 == dk4fputs(sn, stdout, NULL)) { output_error = 1; }
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) { output_error = 1; }
+ }
+#else
+
+
+#line 1508 "dk-bmm.ctr"
+ if (EOF == fputs(sn, stdout)) { output_error = 1; }
+ if (EOF == fputc('\n', stdout)) { output_error = 1; }
+#endif
+ fflush(stdout);
+ }
+
+
+#line 1514 "dk-bmm.ctr"
+}
+
+
+
+/** Process the specified file.
+ @param filename Name of file to process.
+*/
+static
+void
+dk_bmm_run_for_file(const dkChar *filename)
+{
+ const dkChar *oldsourcefile;
+ dk4_um_t oldsourceline;
+
+
+#line 1528 "dk-bmm.ctr"
+ if (0 != dk_bmm_handle_set) {
+ if (0 != dk_bmm_do_report) {
+ /* ERROR: Option -r not available for sets */
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 8);
+ } else {
+ if (0 != dk_bmm_read_sets_file(filename)) {
+ if (0 != dk_bmm_do_confirm) {
+ /* TODO: Confirm current media set */
+ exval = EXIT_SUCCESS;
+ dk_bmm_day_in_cycle++;
+ if (0 > dk_bmm_day_in_cycle) { dk_bmm_day_in_cycle = 0; }
+ if ((dk4_um_t)dk_bmm_day_in_cycle >= (dk4_um_t)dk_bmm_n_set_names) {
+ dk_bmm_day_in_cycle = 0;
+ }
+ dk4_bmm_write_set_file(filename);
+ dk_bmm_write_set_name();
+ } else {
+ exval = EXIT_SUCCESS;
+ dk_bmm_write_set_name();
+ }
+ } else {
+ /* ERROR: Not a set file name */
+ oldsourcefile = dk4app_get_log_source_file(app);
+ oldsourceline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_file(app, filename);
+ dk4app_set_log_source_line(app, (dk4_um_t)0UL);
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 13);
+ dk4app_set_log_source_file(app, oldsourcefile);
+ dk4app_set_log_source_line(app, oldsourceline);
+ }
+ }
+ } else {
+ dk_bmm_initialize_media_info();
+ if (dk_bmm_read_media_file(filename)) {
+ if (0 != dk_bmm_do_report) {
+ exval = EXIT_SUCCESS;
+ dk_bmm_report_media();
+ } else {
+ if (0 != dk_bmm_do_confirm) {
+ exval = EXIT_SUCCESS;
+ dk_bmm_switch_to_next(filename);
+ dk_bmm_show_current_media_number();
+ } else {
+ exval = EXIT_SUCCESS;
+ dk_bmm_show_current_media_number();
+ }
+ }
+ } else {
+ /* ERROR: Failed to read file, probably not a dk-bmm file. */
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 9);
+ }
+ }
+
+
+#line 1581 "dk-bmm.ctr"
+}
+
+
+
+#if DK4_ON_WINDOWS
+
+static
+int
+dk_bmm_expand_pattern(const dkChar *pattern)
+{
+ dkChar buf[DK4_MAX_PATH];
+ dk4_dir_t *fne;
+ const dkChar *shf;
+ const dkChar *pth;
+ int back = 0;
+
+
+#line 1597 "dk-bmm.ctr"
+ fne = dk4app_fne_open(pattern, app);
+ if (NULL != fne) {
+ shf = dk4dir_next_file(fne);
+ if (NULL != shf) {
+ if (NULL == dk4dir_next_file(fne)) {
+ pth = dk4dir_get_path(fne);
+ if (NULL != pth) {
+ if (0 != dk4str_cpy_s(buf, DK4_SIZEOF(buf,dkChar), pth, NULL)) {
+ if(0!=dk4str_cat_s(buf,DK4_SIZEOF(buf,dkChar),dk_bmm_kwnl[3],NULL))
+ {
+ if(0 != dk4str_cat_s(buf, DK4_SIZEOF(buf,dkChar), shf, NULL)) {
+ dk_bmm_run_for_file(buf);
+ } else {
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ }
+ } else {
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ }
+ } else {
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ }
+ } else {
+ dk_bmm_run_for_file(shf);
+ }
+ } else {
+ /* ERROR: Multiple files */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 106, pattern);
+ }
+ } else {
+ /* ERROR: No file found */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 107, pattern);
+ }
+ dk4dir_close(fne);
+ }
+
+
+#line 1635 "dk-bmm.ctr"
+ return back;
+}
+
+#endif
+
+
+
+/** Run after installing signal handlers.
+*/
+static
+void
+dk_bmm_normal_run(void)
+{
+ const dkChar *xargv;
+
+
+#line 1650 "dk-bmm.ctr"
+ if (0 != dk4app_opt_is_set_short(app, dkT('c'), NULL)) {
+ dk_bmm_do_confirm = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('r'), NULL)) {
+ dk_bmm_do_report = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('s'), NULL)) {
+ dk_bmm_handle_set = 1;
+ }
+ if (dk4app_get_argc(app) == 1) {
+ xargv = dk4app_get_argv(app, 0);
+ if (NULL != xargv) {
+#if DK4_ON_WINDOWS
+ if (0 != dk4path_must_expand(xargv)) {
+ dk_bmm_expand_pattern(xargv);
+ } else {
+#endif
+ dk_bmm_run_for_file(xargv);
+#if DK4_ON_WINDOWS
+ }
+#endif
+ } else {
+ /* ERROR: Exactly one file allowed! */
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 10);
+ }
+ } else {
+ /* ERROR: Exactly one file allowed! */
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 10);
+ }
+
+
+#line 1680 "dk-bmm.ctr"
+}
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+dk_bmm_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ struct sigaction opipe;
+#endif
+ struct sigaction oint;
+#ifdef SIGPIPE
+ struct sigaction npipe;
+#endif
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+ int success = 0;
+
+#ifdef SIGPIPE
+ /* Set up signal handling for SIGPIPE.
+ */
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+#endif
+
+ /* Set up signal handling for SIGINT.
+ */
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ dk_bmm_normal_run();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+#ifdef SIGPIPE
+ /* Restore signal handling for SIGPIPE.
+ */
+ restore_old_pipe:
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+#endif
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+dk_bmm_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ dk_bmm_normal_run();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+#ifdef SIGPIPE
+ sigset(SIGPIPE, oldpipe);
+#endif
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+dk_bmm_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = signal(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ dk_bmm_normal_run();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+#ifdef SIGPIPE
+ signal(SIGPIPE, oldpipe);
+#endif
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+dk_bmm_run_with_signal_handlers(void)
+{
+ dk_bmm_normal_run();
+}
+#endif
+#endif
+#endif
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ int oldstdlevel;
+ int oldfilelevel;
+
+
+#line 1885 "dk-bmm.ctr"
+
+
+#line 1886 "dk-bmm.ctr"
+ dk4fput_initialize_stderr();
+ app = dk4app_open_cmd(
+ argc, argv, dk_bmm_options, dk_bmm_sz_options,
+ dk_bmm_kwnl[0], DKT_VERSION_DK,
+ dk_bmm_kwnl[1], dk_bmm_help_text, dk_bmm_license_text
+ );
+ if (NULL != app) {
+ dk_bmm_sz_msg = dk4app_string_table_size(dk_bmm_kw_def);
+ dk_bmm_msg = dk4app_string_table(app, dk_bmm_kwnl[2], dk_bmm_kw_def);
+ if (0 != dk4app_can_run_normally(app)) {
+ dk_bmm_run_with_signal_handlers();
+ if (0 != dk_bmm_cycle_completed) {
+ /* INFO: Cycle completed, change media set */
+ oldstdlevel = app->ll_stderr;
+ oldfilelevel = app->ll_file;
+ app->ll_file = DK4_LL_INFO;
+ app->ll_stderr = DK4_LL_INFO;
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_INFO, 11);
+ app->ll_file = oldfilelevel;
+ app->ll_stderr = oldstdlevel;
+ }
+ if (0 != output_error) {
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 2);
+ exval = EXIT_FAILURE;
+ }
+#ifdef SIGPIPE
+ if (0 != sig_read_atomic(&sig_had_pipe)) {
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 3);
+ exval = EXIT_FAILURE;
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_term)) {
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 5);
+ exval = EXIT_FAILURE;
+ }
+ if (0 != sig_read_atomic(&sig_had_int)) {
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 4);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ dk4fput_initialize_stdout();
+ dk_bmm_mod_stdout = 1;
+
+#line 1928 "dk-bmm.ctr"
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ dk4app_close(app); app = NULL;
+ }
+ fflush(stdout);
+ fflush(stderr);
+ dk4fput_cleanup_stderr();
+ if (0 != dk_bmm_mod_stdout) {
+ dk4fput_cleanup_stdout();
+ }
+
+
+#line 1941 "dk-bmm.ctr"
+
+
+#line 1942 "dk-bmm.ctr"
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/dk-bmm.ctr b/support/dktools/dk-bmm.ctr
new file mode 100644
index 0000000000..a4fd766c76
--- /dev/null
+++ b/support/dktools/dk-bmm.ctr
@@ -0,0 +1,1944 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_TIME_WITH_SYS_TIME
+#ifndef SYS_TIME_H_INCLUDED
+#include <sys/time.h>
+#define SYS_TIME_H_INCLUDED 1
+#endif
+#ifndef TIME_H_INCLUDED
+#include <time.h>
+#define TIME_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_TIME_H
+#ifndef TIME_H_INCLUDED
+#include <time.h>
+#define TIME_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_SYS_TIME_H
+#ifndef SYS_TIME_H_INCLUDED
+#include <sys/time.h>
+#define SYS_TIME_H_INCLUDED 1
+#endif
+#endif
+#endif
+#endif
+
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4mem.h"
+#include "dk4app.h"
+#include "dk4vers.h"
+#include "dk4fput.h"
+#include "dk4str8.h"
+#include "dk4strd.h"
+#include "dk4enc.h"
+#include "dk4tsp08.h"
+#include "dk4tspdk.h"
+#include "dk4mai8dus.h"
+#include "dk4mai8ddu.h"
+#include "dk4maidddu.h"
+#include "dk4mao8d.h"
+#include "dk4maodd.h"
+#include "dk4fopda.h"
+#include "dk4isadm.h"
+#include "dk4timec.h"
+#include "dk4time08.h"
+#include "dk4aopt.h"
+#include "dk4mpl.h"
+#include "dk4pathd.h"
+
+
+
+$!trace-include
+
+
+
+/** Information about one media.
+*/
+typedef struct {
+ unsigned short year; /**< Year of last backup. */
+ unsigned short month; /**< Month of last backup. */
+ unsigned short day; /**< Day within month of last backup. */
+ unsigned short hour; /**< Hour of last backup. */
+ unsigned short minute; /**< Minute of last backup. */
+ unsigned short second; /**< Second of last backup. */
+ unsigned short times; /**< How many times was the media used. */
+} dk_bmm_media_t;
+
+
+
+/** Line handler object.
+*/
+typedef struct {
+ int *backptr; /**< Address of result variable. */
+} dk_bmm_lh_obj_t;
+
+
+
+/** Help text shown if no help text file found.
+*/
+static const dkChar * const dk_bmm_help_text[] = {
+$!text macro=dkT
+
+Backup media management
+
+dk-bmm [<option(s)>] [<file>]
+
+Options:
+-s --set Use media sets instead of media.
+-c --confirm Confirm success for backup.
+-r --report Create tape usage report.
+
+--help Show this short help text.
+--manual *** SHOW FULL MANUAL. ***
+--version Show version information.
+--license Show version information.
+
+Typical operations:
+dk-bmm -s <set-names-file> Find name of current backup set.
+dk-bmm <media-file> Find number of current media in set.
+dk-bmm -c <media-file> Confirm successful backup to current media.
+dk-bmm -c -s <set-names-file> Confirm successful backup for current set.
+
+http://dktools.sourceforge.net
+
+$!end
+};
+
+
+
+/** License conditions.
+*/
+static const dkChar * const dk_bmm_license_text[] = {
+$!text macro=dkT,preprocessor
+
+This software uses code from the following projects, either directly or as
+a library:
+
+dktools Dirk Krause's tools and libraries.
+ See http://dktools.sourceforge.net/ for more information.
+#if DK4_HAVE_ZLIB_H
+
+zlib Data compression library.
+ See http://www.zlib.net/ for more information.
+#endif
+#if DK4_HAVE_BZLIB_H
+
+bzip2 Data compression program and library.
+ See http://www.bzip.org/ for more information.
+#endif
+
+All the licenses below apply to the program.
+Licenses for used libraries are shown as found on my Scientific Linux 6.x
+computer in the /usr/share/doc directory on 2015-04-01. Check the project
+homepages of the used libraries for additional information and/or updated
+license terms.
+
+
+DK tools and libraries license
+==============================
+Copyright (c) 2015-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#if DK4_HAVE_ZLIB_H
+
+
+Zlib license
+============
+(C) 1995-2004 Jean-loup Gailly and Mark Adler
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+
+Jean-loup Gailly Mark Adler
+jloup@gzip.org madler@alumni.caltech.edu
+#endif
+#if DK4_HAVE_BZLIB_H
+
+
+Bzip2 and libbzip2 library license
+==================================
+This program, "bzip2", the associated library "libbzip2", and all
+documentation, are copyright (C) 1996-2007 Julian R Seward. All
+rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+3. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Julian Seward, jseward@bzip.org
+bzip2/libbzip2 version 1.0.5 of 10 December 2007
+#endif
+
+$!end
+};
+
+
+
+/** Buffer to save set names line.
+*/
+static dkChar dk_bmm_set_line[1024];
+
+
+
+/** Buffer for reading the line.
+*/
+static dkChar dk_bmm_set_buffer[1024];
+
+
+
+/** Pointers to all the set names.
+*/
+static dkChar *dk_bmm_set_names[512];
+
+
+
+/** Constant text keywords used by the program, not localized.
+*/
+static const dkChar * const dk_bmm_kwnl[] = {
+$!string-table macro=dkT
+#
+# 0 Program group name
+#
+dktools
+#
+# 1 Help text file name
+#
+dk-bmm.txt
+#
+# 2 String table file name
+#
+dk-bmm.str
+#
+# 3 Path separator for Windows
+#
+\\
+#
+# 4 File open mode: Read binary.
+#
+rb
+#
+# 5 File open mode: Write
+#
+w
+$!end
+};
+
+
+
+/** Constant text keywords used by the program, localized.
+*/
+static const dkChar * const dk_bmm_kw_def[] = {
+$!string-table macro=dkT
+#
+# 0 Error: Failed to set up signal handlers!
+#
+Failed to set up signal handlers!
+#
+# 1 Error: Failed to restore signal handlers!
+#
+Failed to restore signal handlers!
+#
+# 2 Error: Write attempt to standard output failed!
+#
+Write attempt to standard output failed!
+#
+# 3 Error: SIGPIPE signal received!
+#
+SIGPIPE signal received!
+#
+# 4 Error: Aborted by SIGINT signal!
+#
+Aborted by SIGINT signal!
+#
+# 5 Error: Aborted by SIGTERM signal!
+#
+Aborted by SIGTERM signal!
+#
+# 6 Hint: Tape was not used in this cycle yet.
+#
+ (previous cycle)
+#
+# 7 Text: Media number for next backup
+#
+Media number for next backup:
+#
+# 8 ERROR: Option -r is not available for a set names file.
+#
+Option -r is not available for a set names file.
+#
+# 9 ERROR: Failed to read file, probably not a dk-bmm file!
+#
+Failed to read file, probably not a dk-bmm file!
+#
+# 10 ERROR: Exactly one file name allowed!
+#
+Exactly one file name allowed!
+#
+# 11 Info: Cycle completed, please renew media set!
+#
+Cycle completed, please renew media set!
+#
+# 12
+#
+Failed to write new set file!
+#
+# 13
+#
+Not a set names file!
+$!end
+};
+
+
+
+/** Options understood by the program.
+*/
+static const dk4_option_specification_t dk_bmm_options[] = {
+ /*
+ Process media sets, not media.
+ */
+ { dkT('s'), dkT("set"), DK4_OPT_ARG_NONE },
+
+ /*
+ Confirm previously requested media set or media.
+ */
+ { dkT('c'), dkT("confirm"), DK4_OPT_ARG_NONE },
+
+ /*
+ Report media.
+ */
+ { dkT('r'), dkT("report"), DK4_OPT_ARG_NONE },
+};
+
+
+
+/** Media numbers in order of usage.
+ This implements the 10 tape rotation scheme.
+ At every time we will have backups of different ages.
+ During 200 backups each of the 10 media is used 20 times.
+*/
+static const unsigned char dk_bmm_media_numbers[] = {
+ 1, 2, 3, 4, 5, 1, 2, 3, 4, 6,
+ 1, 2, 3, 4, 7, 1, 2, 3, 4, 8,
+ 2, 3, 4, 5, 6, 2, 3, 4, 5, 7,
+ 2, 3, 4, 5, 8, 2, 3, 4, 5, 9,
+ 3, 4, 5, 6, 7, 3, 4, 5, 6, 8,
+ 3, 4, 5, 6, 9, 3, 4, 5, 6, 10,
+ 4, 5, 6, 7, 8, 4, 5, 6, 7, 9,
+ 4, 5, 6, 7, 10, 4, 5, 6, 7, 1,
+ 5, 6, 7, 8, 9, 5, 6, 7, 8, 10,
+ 5, 6, 7, 8, 1, 5, 6, 7, 8, 2,
+ 6, 7, 8, 9, 10, 6, 7, 8, 9, 1,
+ 6, 7, 8, 9, 2, 6, 7, 8, 9, 3,
+ 7, 8, 9, 10, 1, 7, 8, 9, 10, 2,
+ 7, 8, 9, 10, 3, 7, 8, 9, 10, 4,
+ 8, 9, 10, 1, 2, 8, 9, 10, 1, 3,
+ 8, 9, 10, 1, 4, 8, 9, 10, 1, 5,
+ 9, 10, 1, 2, 3, 9, 10, 1, 2, 4,
+ 9, 10, 1, 2, 5, 9, 10, 1, 2, 6,
+ 10, 1, 2, 3, 4, 10, 1, 2, 3, 5,
+ 10, 1, 2, 3, 6, 10, 1, 2, 3, 7
+};
+
+
+/** Information for the 10 media in the backup scheme.
+*/
+static dk_bmm_media_t media_info[10];
+
+
+
+/** Flag: Media found for recoding.
+*/
+static unsigned short media_found[10];
+
+
+
+/** Pointer to either localized messages or default texts.
+*/
+static const dkChar * const *dk_bmm_msg = dk_bmm_kw_def;
+
+
+
+/** Application structure for diagnostics.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Number of used names in dk_bmm_set_names.
+*/
+static size_t dk_bmm_n_set_names = 0;
+
+
+
+/** Number of elements in the dk_bmm_options array.
+*/
+static const size_t dk_bmm_sz_options =
+sizeof(dk_bmm_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Number of elements in the dk_bmm_msg array.
+*/
+static size_t dk_bmm_sz_msg =
+sizeof(dk_bmm_kw_def)/sizeof(DK4_PCDKCHAR) - 1;
+
+
+
+/** Exit status code of the program.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+/** Flag: Dealing with media set.
+*/
+static int dk_bmm_handle_set = 0;
+
+
+
+/** Flag: Confirm previous media or set.
+*/
+static int dk_bmm_do_confirm = 0;
+
+
+
+/** Flag: Write report.
+*/
+static int dk_bmm_do_report = 0;
+
+
+
+/** Flag: Output mode for stdout was changed.
+*/
+static int dk_bmm_mod_stdout = 0;
+
+
+
+/** Number of recent day within backup cycle.
+*/
+static int dk_bmm_day_in_cycle = 0;
+
+
+
+/** Flag: Cycle was completed.
+*/
+static int dk_bmm_cycle_completed = 0;
+
+
+/** Flag: Write attempt to stdout failed.
+*/
+static int output_error = 0;
+
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+/** Check whether we can continue or if a signal was received.
+ @param check_pipe Flag: Check for occured SIGPIPE signal too.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(int check_pipe)
+{
+ int back = 1;
+#ifdef SIGPIPE
+ if (0 != check_pipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_int )) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+/** Check whether we can continue.
+ @return 1 for yes, 0 for no.
+*/
+static
+int
+dk_bmm_can_continue(void)
+{
+ int back = 1;
+ if (0 == sig_can_continue(1)) {
+ back = 0;
+ }
+ return back;
+}
+
+
+
+/** Handler function for text lines.
+ @param obj Object to modify while processing the character.
+ @param line Text line to process.
+ @param lineno Current line number.
+ @param erp Error report, may be NULL.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+dk_bmm_sets_line_handler(
+ void *obj,
+ dkChar *line,
+ dk4_um_t lineno,
+ dk4_er_t *erp
+)
+{
+ dk_bmm_lh_obj_t *lhoptr;
+ dkChar *p1;
+ const dkChar *pe;
+ dk4_um_t um;
+ size_t i;
+ size_t al;
+ int res;
+ int back = DK4_TSP_RES_FATAL;
+ $? "+ dk_bmm_sets_line_handler %lu", (unsigned long)lineno
+ lhoptr = (dk_bmm_lh_obj_t *)obj;
+ if ((dk4_um_t)1UL == lineno) { $? ". first line"
+ dk4str_delnl(line);
+ res = dk4str_cpy_s(
+ dk_bmm_set_line, DK4_SIZEOF(dk_bmm_set_line,dkChar), line, NULL
+ );
+ if (0 != res) {
+ al = sizeof(dk_bmm_set_names)/sizeof(DK4_PDKCHAR);
+ for (i = 0; i < al; i++) { dk_bmm_set_names[i] = NULL; }
+ i = dk4str_tokenize(dk_bmm_set_names, al, dk_bmm_set_line, NULL, NULL);
+ if (0 < i) {
+ dk_bmm_n_set_names = i;
+ back = DK4_TSP_RES_OK;
+ }
+ }
+ } else {
+ if ((dk4_um_t)2UL == lineno) { $? ". second line"
+ dk4str_delnl(line);
+ p1 = dk4str_start(line, NULL);
+ if (NULL != p1) {
+ pe = NULL;
+ um = (dk4_um_t)0UL;
+ res = dk4ma_input_dk_dec_dk4_um_t(
+ &um, p1, &pe, 1, NULL
+ );
+ if (0 != res) {
+ if ((dk4_um_t)INT_MAX >= um) {
+ dk_bmm_day_in_cycle = (int)um;
+ if ((dk4_um_t)dk_bmm_n_set_names > dk_bmm_day_in_cycle) {
+ back = DK4_TSP_RES_OK;
+ }
+ }
+ }
+ } else {
+ back = DK4_TSP_RES_OK;
+ }
+ } else { $? "! other line"
+ }
+ }
+ if ((DK4_TSP_RES_FATAL == back) || (DK4_TSP_RES_ERROR == back)) {
+ *(lhoptr->backptr) = 0;
+ } $? "- dk_bmm_sets_line_handler %d", back
+ return back;
+}
+
+
+
+/** Read sets file.
+ @param filename Name of file to read.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk_bmm_read_sets_file(const dkChar *filename)
+{
+ dk4_er_t er;
+ dk4_tspdk_t tspdk;
+ dk_bmm_lh_obj_t lhoptr;
+ FILE *fipo;
+ int res;
+ int c;
+ int cc = 1;
+ int back = 0;
+ $? "+ dk_bmm_read_sets_file \"%!ds\"", filename
+ fipo = dk4fopen_app(filename, dk_bmm_kwnl[4], DK4_FOPEN_SC_IS_REGULAR, app);
+ if (NULL != fipo) {
+ lhoptr.backptr = &back;
+ dk4error_init(&er);
+ res = dk4tspdk_setup_line(
+ &tspdk, &lhoptr, dk_bmm_sets_line_handler,
+ dk_bmm_set_buffer, DK4_SIZEOF(dk_bmm_set_buffer,dkChar),
+ dk4app_get_encoding(app),
+ dk4app_get_file_in_encoding(app),
+ &er
+ );
+ if (0 != res) {
+ back = 1;
+ while (1 == cc) {
+ if (0 != dk_bmm_can_continue()) {
+ c = fgetc(fipo);
+ if (EOF != c) {
+ if (0 != feof(fipo)) { cc = 0; }
+ res = dk4tspdk_add_one_byte(&tspdk, (unsigned char)c);
+ switch (res) {
+ case DK4_TSP_RES_ERROR: case DK4_TSP_RES_FATAL: {
+ cc = -1;
+ } break;
+ }
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = -1;
+ }
+ }
+ if (0 == cc) {
+ res = dk4tspdk_finish(&tspdk);
+ switch (res) {
+ case DK4_TSP_RES_ERROR: case DK4_TSP_RES_FATAL: {
+ back = 0;
+ } break;
+ }
+ } else {
+ back = 0;
+ }
+ } else {
+ /* ERROR: Failed to set up line processing, bug */
+ }
+ fclose(fipo);
+ } $? "- dk_bmm_read_sets_file %d", back
+ return back;
+}
+
+
+
+
+/** Initialize the media_info structures.
+*/
+static
+void
+dk_bmm_initialize_media_info(void)
+{
+ size_t i;
+ for (i = 0; i < 10; i++) {
+ media_info[i].year =
+ media_info[i].month =
+ media_info[i].day =
+ media_info[i].hour =
+ media_info[i].minute =
+ media_info[i].second =
+ media_info[i].times = 0U;
+ }
+}
+
+
+
+static
+int
+dk_bmm_data_line(dk_bmm_media_t *mptr, char *line)
+{
+ const char *ep;
+ int back = 0;
+ $? "+ dk_bmm_data_line \"%!8s\"", line
+ if (21 > dk4str8_len(line)) {
+ $? "! line too short"
+ goto finished;
+ }
+ if ('-' != line[4]) {
+ $? "! separator year month"
+ goto finished;
+ }
+ line[4] = '\0';
+ if ('-' != line[7]) {
+ $? "! separator month day"
+ goto finished;
+ }
+ line[7] = '\0';
+ if (' ' != line[10]) {
+ $? "! separator day hour"
+ goto finished;
+ }
+ line[10] = '\0';
+ if (':' != line[13]) {
+ $? "! separator hour minute"
+ goto finished;
+ }
+ line[13] = '\0';
+ if (':' != line[16]) {
+ $? "! separator minute second"
+ goto finished;
+ }
+ line[16] = '\0';
+ if (' ' != line[19]) {
+ $? "! separator second times"
+ goto finished;
+ }
+ line[19] = '\0';
+ ep = NULL;
+ if (0 == dk4ma_input_c8_dec_ushort(&(mptr->year), line, &ep, 0, NULL)) {
+ $? "! year"
+ goto finished;
+ }
+ if (0 == dk4ma_input_c8_dec_ushort(&(mptr->month),&(line[5]),&ep,0,NULL)) {
+ $? "! month"
+ goto finished;
+ }
+ if (0 == dk4ma_input_c8_dec_ushort(&(mptr->day),&(line[8]),&ep,0,NULL)) {
+ $? "! day"
+ goto finished;
+ }
+ if (0 == dk4ma_input_c8_dec_ushort(&(mptr->hour),&(line[11]),&ep,0,NULL)) {
+ $? "! hour"
+ goto finished;
+ }
+ if (0 == dk4ma_input_c8_dec_ushort(&(mptr->minute),&(line[14]),&ep,0,NULL)) {
+ $? "! minute"
+ goto finished;
+ }
+ if (0 == dk4ma_input_c8_dec_ushort(&(mptr->second),&(line[17]),&ep,0,NULL)) {
+ $? "! second"
+ goto finished;
+ }
+ if (0 == dk4ma_input_c8_dec_ushort(&(mptr->times),(&line[20]),&ep,0,NULL)) {
+ $? "! times"
+ goto finished;
+ }
+ back = 1;
+ finished:
+ $? "- dk_bmm_data_line %d", back
+ return back;
+}
+
+
+
+/** Handler function for text lines.
+ @param obj Object to modify while processing the character.
+ @param line Text line to process.
+ @param lineno Current line number.
+ @param erp Error report, may be NULL.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+dk_bmm_media_line_handler(
+ void *obj,
+ char *line,
+ dk4_um_t lineno,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er;
+ dk_bmm_lh_obj_t *lhoptr;
+ const char *endptr = NULL;
+ dk4_um_t um;
+ int res;
+ int back = DK4_TSP_RES_FATAL;
+ $? "+ dk_bmm_media_line_handler %lu \"%!8s\"", (unsigned long)lineno, line
+ lhoptr = (dk_bmm_lh_obj_t *)obj;
+ dk4str8_delnl(line);
+ if ((dk4_um_t)1UL == lineno) { $? ". first line"
+ /*
+ Process first line
+ */
+ dk4error_init(&er);
+ res = dk4ma_input_c8_dec_dk4_um_t(&um, line, &endptr, 1, &er);
+ if (0 != res) {
+ if ((dk4_um_t)200UL > um) {
+ dk_bmm_day_in_cycle = (int)um;
+ back = DK4_TSP_RES_OK;
+ } else {
+ /* ERROR: Out of range */
+ }
+ } else {
+ /* ERROR: Failed to read number */
+ }
+ } else {
+ if (((dk4_um_t)2UL <= lineno) && ((dk4_um_t)11UL >= lineno)) {
+ /*
+ Process data line
+ */
+ lineno -= (dk4_um_t)2UL; $? ". media line"
+ if (0 != dk_bmm_data_line(&(media_info[(size_t)lineno]), line)) {
+ back = DK4_TSP_RES_OK;
+ } else {
+ /* ERROR: Syntax */
+ }
+ } else { $? ". too many lines"
+ /* ERROR: Syntax, too many lines */
+ }
+ }
+ if (DK4_TSP_RES_OK != back) { *(lhoptr->backptr) = 0; }
+ $? "- dk_bmm_media_line_handler %d", back
+ return back;
+}
+
+
+
+/** Read media file.
+ @param filename Name of media file to read.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk_bmm_read_media_file(const dkChar *filename)
+{
+ char inb[256];
+ dk4_tsp08_t tsp08;
+ dk4_er_t er;
+ dk_bmm_lh_obj_t obj;
+ FILE *fipo = NULL;
+ int c;
+ int res;
+ int cc = 1;
+ int back = 0;
+ $? "+ dk_bmm_read_media_file \"%!ds\"", filename
+ obj.backptr = &back;
+ fipo = dk4fopen_app(filename, dk_bmm_kwnl[4], DK4_FOPEN_SC_IS_REGULAR, app);
+ if (NULL != fipo) {
+ dk4error_init(&er);
+ res = dk4tsp08_setup_line(
+ &tsp08, &obj, dk_bmm_media_line_handler, inb, sizeof(inb),
+ DK4_ENCODING_ASCII, dk4app_get_file_in_encoding(app), &er
+ );
+ if (0 != res) {
+ back = 1;
+ while (1 == cc) {
+ if (0 != dk_bmm_can_continue()) {
+ c = fgetc(fipo);
+ if (EOF != c) {
+ if (0 != feof(fipo)) { cc = 0; }
+ res = dk4tsp08_add_one_byte(&tsp08, (unsigned char)c);
+ switch (res) {
+ case DK4_TSP_RES_ERROR: case DK4_TSP_RES_FATAL: {
+ cc = -1;
+ /* ERROR: Processing one byte failed */
+ } break;
+ }
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = -1;
+ }
+ }
+ if (0 == cc) {
+ res = dk4tsp08_finish(&tsp08);
+ switch (res) {
+ case DK4_TSP_RES_ERROR: case DK4_TSP_RES_FATAL: {
+ back = 0;
+ /* ERROR: Completing failed */
+ } break;
+ }
+ } else {
+ back = 0;
+ }
+ } else {
+ /* ERROR: Failed to set up line processing */
+ }
+ fclose(fipo);
+ } else {
+ back = 1;
+ } $? "- dk_bmm_read_media_file %d", back
+ return back;
+}
+
+
+
+static
+void
+dk_bmm_show_current_media_number(void)
+{
+ char buf[16*sizeof(dk4_um_t)];
+ int res;
+ unsigned char uc;
+
+ uc = dk_bmm_media_numbers[dk_bmm_day_in_cycle];
+ res = dk4ma_write_c8_decimal_unsigned(
+ buf, sizeof(buf), (dk4_um_t)uc, 0, NULL
+ );
+ if (0 != res) {
+ if (EOF == fputs(buf, stdout)) { output_error = 1; }
+ if (EOF == fputc('\n', stdout)) { output_error = 1; }
+ fflush(stdout);
+ } else {
+ /* ERROR: Failed to convert number, bug as buffer size is large enough. */
+ exval = EXIT_FAILURE;
+ }
+}
+
+
+
+static
+void
+dk_bmm_update_media_info(dk_bmm_media_t *mptr)
+{
+#if DK4_ON_WINDOWS
+ SYSTEMTIME st;
+ GetLocalTime(&st);
+ mptr->year = st.wYear;
+ mptr->month = st.wMonth;
+ mptr->day = st.wDay;
+ mptr->hour = st.wHour;
+ mptr->minute = st.wMinute;
+ mptr->second = st.wSecond;
+#else
+ time_t timer;
+ struct tm *tm;
+ time(&timer);
+ tm = localtime(&timer);
+ if (NULL != tm) {
+ mptr->year = 1900 + tm->tm_year;
+ mptr->month = 1 + tm->tm_mon;
+ mptr->day = tm->tm_mday;
+ mptr->hour = tm->tm_hour;
+ mptr->minute = tm->tm_min;
+ mptr->second = tm->tm_sec;
+ }
+#endif
+ mptr->times += 1;
+}
+
+
+
+static
+int
+dk_bmm_switch_to_next(const dkChar *filename)
+{
+ char buf[128];
+ FILE *fipo;
+ size_t mediano;
+ int tests;
+ int res;
+ int back = 0;
+ $? "+ dk_bmm_switch_to_next"
+ mediano = (size_t)(dk_bmm_media_numbers[dk_bmm_day_in_cycle]);
+ $? ". mediano = %lu", (unsigned long)mediano
+ dk_bmm_update_media_info(&(media_info[mediano - 1]));
+ if (++dk_bmm_day_in_cycle >= 200) { $? ". cycle completed"
+ dk_bmm_day_in_cycle = 0;
+ dk_bmm_cycle_completed = 1;
+ for (mediano = 0; mediano < 10; mediano++) {
+ media_info[mediano].times = 0;
+ }
+ }
+ tests = DK4_FOPEN_SC_USER;
+ if (1 == dk4isadmin()) { tests = DK4_FOPEN_SC_PRIVILEGED; }
+ fipo = dk4fopen_app(filename, dk_bmm_kwnl[5], tests, app);
+ if (NULL != fipo) { $? ". file opened"
+ back = 1;
+ res = dk4ma_write_c8_decimal_signed(
+ buf, sizeof(buf), (dk4_im_t)dk_bmm_day_in_cycle, 0, NULL
+ );
+ if (0 != res) { $? ". day in cycle: %!8s", buf
+ if (EOF == fputs(buf, fipo)) { back = 0; }
+ if (EOF == fputc('\n', fipo)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ for (mediano = 0; mediano < 10; mediano++) {
+ res = dk4time_to_text_c8(
+ buf, sizeof(buf), DK4_TIMEFORMAT_DATE_TIME,
+ media_info[mediano].year,
+ media_info[mediano].month,
+ media_info[mediano].day,
+ media_info[mediano].hour,
+ media_info[mediano].minute,
+ media_info[mediano].second,
+ NULL
+ );
+ if (0 != res) { $? ". media %u text %!8s", (unsigned)mediano,buf
+ if (EOF == fputs(buf, fipo)) { back = 0; }
+ if (EOF == fputc(' ', fipo)) { back = 0; }
+ res = dk4ma_write_c8_decimal_unsigned(
+ buf, sizeof(buf), (dk4_um_t)(media_info[mediano].times), 0, NULL
+ );
+ if (0 != res) {
+ if (EOF == fputs(buf, fipo)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ if (EOF == fputc('\n', fipo)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ }
+ if (0 != fclose(fipo)) { back = 0; }
+ if (0 == back) {
+ exval = EXIT_FAILURE;
+ }
+ } else { $? "! fopen failed"
+ exval = EXIT_FAILURE;
+ } $? "- dk_bmm_switch_to_next %d", back
+ return back;
+}
+
+
+
+/** Write a report of used media.
+*/
+static
+void
+dk_bmm_report_media(void)
+{
+ dkChar b1[16*sizeof(dk4_um_t)];
+ dkChar b3[16*sizeof(dk4_um_t)];
+ char b2[128];
+ char *ptr;
+ size_t i;
+ size_t j;
+ size_t mediano;
+ int res;
+ unsigned short nextlevel = 1;
+ for (i = 0; i < 10; i++) { media_found[i] = 0; }
+
+ if (0 < dk_bmm_day_in_cycle) {
+ for (i = 0; i < (size_t)dk_bmm_day_in_cycle; i++) {
+ j = (size_t)dk_bmm_day_in_cycle - 1 - i;
+ mediano = (size_t)(dk_bmm_media_numbers[j]);
+ if (0 == media_found[mediano - 1]) {
+ media_found[mediano - 1] = nextlevel++;
+ $? ". mediano %u level %u", (unsigned)mediano, (unsigned)nextlevel
+ }
+ }
+ }
+ for (i = (size_t)dk_bmm_day_in_cycle; i < 200; i++) {
+ j = 199 - i;
+ mediano = (size_t)(dk_bmm_media_numbers[j]);
+ if (0 == media_found[mediano - 1]) {
+ media_found[mediano - 1] = nextlevel++;
+ $? ". mediano %u level %u", (unsigned)mediano, (unsigned)nextlevel
+ }
+ }
+ dk_bmm_mod_stdout = 1; $? ". mod stdout"
+ dk4fput_initialize_stdout();
+ res = dk4ma_write_decimal_unsigned(
+ b1, DK4_SIZEOF(b1,dkChar),
+ (dk4_um_t)(dk_bmm_media_numbers[dk_bmm_day_in_cycle]),
+ 0, NULL
+ );
+ if (0 != res) {
+ if (0 == dk4fputs(dk_bmm_kw_def[7], stdout, NULL)) {
+ output_error = 1;
+ }
+ if (0 == dk4fputs(b1, stdout, NULL)) { output_error = 1; }
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) { output_error = 1; }
+ } else {
+ /* ERROR: Number conversion failed, bug as buffer is large enough. */
+ exval = EXIT_FAILURE;
+ }
+ for (i = 1; i < 11; i++) {
+ for (mediano = 1; mediano < 11; mediano++) {
+ if (media_found[mediano - 1] == i) {
+ res = dk4ma_write_decimal_unsigned(
+ b1, DK4_SIZEOF(b1,dkChar), (dk4_um_t)mediano, 2, NULL
+ );
+ if (0 != res) {
+ res = dk4time_to_text_c8(
+ b2, sizeof(b2), DK4_TIMEFORMAT_DATE_TIME,
+ media_info[mediano - 1].year,
+ media_info[mediano - 1].month,
+ media_info[mediano - 1].day,
+ media_info[mediano - 1].hour,
+ media_info[mediano - 1].minute,
+ media_info[mediano - 1].second,
+ NULL
+ );
+ if (0 != res) {
+ res = dk4ma_write_decimal_unsigned(
+ b3, DK4_SIZEOF(b3,dkChar),
+ (dk4_um_t)(media_info[mediano - 1].times),
+ 2, NULL
+ );
+ if (0 != res) {
+ if (0 == dk4fputs(b1, stdout, NULL)) { output_error = 1; }
+ for (j = 0; j < 3; j++) {
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) { output_error = 1; }
+ }
+ ptr = b2;
+ while ('\0' != *ptr) {
+ if (0 == dk4fputc((dkChar)(*(ptr++)), stdout, NULL)) {
+ output_error = 1;
+ }
+ }
+ for (j = 0; j < 3; j++) {
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) { output_error = 1; }
+ }
+ if (0 == dk4fputs(b3, stdout, NULL)) { output_error = 1; }
+ if (0 == media_info[mediano - 1].times) {
+ if (0 == dk4fputs(dk_bmm_kw_def[6], stdout, NULL)) {
+ output_error = 1;
+ }
+ }
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) { output_error = 1; }
+ } else {
+ /* ERROR: Number conversion failed, bug. */
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Date and time conversion failed, bug. */
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Number conversion failed, bug. */
+ exval = EXIT_FAILURE;
+ }
+ }
+ }
+ }
+}
+
+
+
+static
+void
+dk4_bmm_write_set_file(const dkChar *filename)
+{
+ dkChar buf[16*sizeof(dk4_um_t)];
+ const dkChar *oldsourcefile;
+ FILE *fipo = NULL;
+ dk4_um_t oldsourceline;
+ size_t i;
+ int res;
+ int we = 0;
+ int tests = DK4_FOPEN_SC_USER;
+ $? "+ dk4_bmm_write_set_file \"%!ds\"", filename
+ if (1 == dk4isadmin()) { tests = DK4_FOPEN_SC_PRIVILEGED; }
+ fipo = dk4fopen_app(filename, dk_bmm_kwnl[5], tests, app);
+ if (NULL != fipo) { $? ". file opened"
+ dk4fput_initialize_file(fipo);
+ for (i = 0; i < dk_bmm_n_set_names; i++) {
+ if (0 != i) {
+ if (0 == dk4fputc(dkT(' '), fipo, NULL)) {
+ we = 1; $? "! write error"
+ }
+ }
+ if (0 == dk4fputs(dk_bmm_set_names[i], fipo, NULL)) {
+ we = 1; $? "! write error"
+ }
+ }
+ if (0 == dk4fputc(dkT('\n'), fipo, NULL)) { $? "! write error"
+ we = 1;
+ }
+ res = dk4ma_write_decimal_unsigned(
+ buf, DK4_SIZEOF(buf,dkChar), (dk4_um_t)dk_bmm_day_in_cycle, 0, NULL
+ );
+ if (0 != res) {
+ if (0 == dk4fputs(buf, fipo, NULL)) { $? "! write error"
+ we = 1;
+ }
+ if (0 == dk4fputc(dkT('\n'), fipo, NULL)) { $? "! write error"
+ we = 1;
+ }
+ } else { $? "! conversion"
+ /* ERROR: Number conversion failed, bug */
+ exval = EXIT_FAILURE;
+ }
+ if (0 != fclose(fipo)) { $? "! write error"
+ we = 1;
+ }
+ if (0 != we) {
+ /* ERROR: Writing to file failed */
+ oldsourcefile = dk4app_get_log_source_file(app);
+ oldsourceline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_file(app, filename);
+ dk4app_set_log_source_line(app, (dk4_um_t)0UL);
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 12);
+ dk4app_set_log_source_file(app, oldsourcefile);
+ dk4app_set_log_source_line(app, oldsourceline);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ exval = EXIT_FAILURE;
+ }
+ $? "- dk4_bmm_write_set_file"
+}
+
+
+
+#if DK4_CHAR_SIZE > 1
+
+/** Check whether a string can be written using 8 bit character width.
+ @param str String to test.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk_bmm_can_write_8bit(const dkChar *str)
+{
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ int back = 1;
+ $? "+ dk_bmm_can_write_8bit 4"
+ while ((dkT('\0') != *str) && (1 == back)) {
+ if (dkC32(0xFF) < *str) {
+ back = 0;
+ }
+ str++;
+ } $? "- dk_bmm_can_write_8bit %d", back
+ return back;
+#else
+ dk4_utf16_decoder_t dec;
+ dk4_c32_t c32;
+ int back = 1;
+ $? "+ dk_bmm_can_write_8bit 2"
+ dk4utf16_init(&dec);
+ while((dkT('\0') != *str) && (1 == back)) {
+ switch (dk4utf16_add(&dec, *str)) {
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf16_get(&dec);
+ if (dkC32(0x7F) < c32) {
+ back = 0;
+ }
+ } break;
+ case DK4_EDSTM_ERROR: {
+ back = 0;
+ } break;
+ }
+ str++;
+ }
+ if (1 == back) {
+ if (0 == dk4utf16_is_empty(&dec)) { back = 0; }
+ } $? "- dk_bmm_can_write_8bit %d", back
+ return back;
+#endif
+#else
+ $? "= dk_bmm_can_write_8bit 1 1"
+ return 1;
+#endif
+}
+
+
+
+/** Write string using 8 bit character functions.
+ @param str String to write.
+*/
+static
+void
+dk_bmm_write_8bit(const dkChar *str)
+{
+#if DK4_CHAR_SIZE > 2
+ $? "+ dk_bmm_write_8bit 4"
+ while (dkT('\0') != *str) {
+ if (EOF == fputc((char)((unsigned char)(*(str++))), stdout)) {
+ output_error = 1;
+ }
+ } $$? "- dk_bmm_write_8bit"
+#else
+ dk4_utf16_decoder_t dec;
+ dk4_c32_t c32;
+ int back = 1;
+ $? "+ dk_bmm_write_8bit 2"
+ dk4utf16_init(&dec);
+ while((dkT('\0') != *str) && (1 == back)) {
+ switch (dk4utf16_add(&dec, *str)) {
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf16_get(&dec);
+ if (dkC32(0xF0) > c32) {
+ if (EOF == fputc((char)((unsigned char)c32), stdout)) {
+ output_error = 1;
+ back = 0;
+ }
+ }
+ } break;
+ case DK4_EDSTM_ERROR: {
+ back = 0;
+ } break;
+ }
+ str++;
+ } $? "- dk_bmm_write_8bit"
+#endif
+}
+
+#endif
+
+
+
+/** Write current media set name to stdout.
+*/
+static
+void
+dk_bmm_write_set_name(void)
+{
+ const dkChar *sn = NULL;
+ $? "+ dk_bmm_write_set_name"
+ if ((dk4_um_t)dk_bmm_day_in_cycle < (dk4_um_t)dk_bmm_n_set_names) {
+ sn = dk_bmm_set_names[(size_t)dk_bmm_day_in_cycle];
+ }
+ if (NULL != sn) {
+#if DK4_CHAR_SIZE > 1
+ $? ". wide characters dk_bmm_mod_stdout=%d", dk_bmm_mod_stdout
+ if (0 != dk_bmm_can_write_8bit(sn)) { $? ". use 8 bits"
+ dk_bmm_write_8bit(sn);
+ if (EOF == fputc('\n', stdout)) { output_error = 1; }
+ } else { $? ". use wide strings"
+ dk_bmm_mod_stdout = 1; $? ". mod stdout"
+ dk4fput_initialize_stdout();
+ if (0 == dk4fputs(sn, stdout, NULL)) { output_error = 1; }
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) { output_error = 1; }
+ }
+#else
+ $? ". 8 bit characters"
+ if (EOF == fputs(sn, stdout)) { output_error = 1; }
+ if (EOF == fputc('\n', stdout)) { output_error = 1; }
+#endif
+ fflush(stdout);
+ }
+ $? "- dk_bmm_write_set_name"
+}
+
+
+
+/** Process the specified file.
+ @param filename Name of file to process.
+*/
+static
+void
+dk_bmm_run_for_file(const dkChar *filename)
+{
+ const dkChar *oldsourcefile;
+ dk4_um_t oldsourceline;
+ $? "+ dk_bmm_run_for_file \"%!ds\"", filename
+ if (0 != dk_bmm_handle_set) {
+ if (0 != dk_bmm_do_report) {
+ /* ERROR: Option -r not available for sets */
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 8);
+ } else {
+ if (0 != dk_bmm_read_sets_file(filename)) {
+ if (0 != dk_bmm_do_confirm) {
+ /* TODO: Confirm current media set */
+ exval = EXIT_SUCCESS;
+ dk_bmm_day_in_cycle++;
+ if (0 > dk_bmm_day_in_cycle) { dk_bmm_day_in_cycle = 0; }
+ if ((dk4_um_t)dk_bmm_day_in_cycle >= (dk4_um_t)dk_bmm_n_set_names) {
+ dk_bmm_day_in_cycle = 0;
+ }
+ dk4_bmm_write_set_file(filename);
+ dk_bmm_write_set_name();
+ } else {
+ exval = EXIT_SUCCESS;
+ dk_bmm_write_set_name();
+ }
+ } else {
+ /* ERROR: Not a set file name */
+ oldsourcefile = dk4app_get_log_source_file(app);
+ oldsourceline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_file(app, filename);
+ dk4app_set_log_source_line(app, (dk4_um_t)0UL);
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 13);
+ dk4app_set_log_source_file(app, oldsourcefile);
+ dk4app_set_log_source_line(app, oldsourceline);
+ }
+ }
+ } else {
+ dk_bmm_initialize_media_info();
+ if (dk_bmm_read_media_file(filename)) {
+ if (0 != dk_bmm_do_report) {
+ exval = EXIT_SUCCESS;
+ dk_bmm_report_media();
+ } else {
+ if (0 != dk_bmm_do_confirm) {
+ exval = EXIT_SUCCESS;
+ dk_bmm_switch_to_next(filename);
+ dk_bmm_show_current_media_number();
+ } else {
+ exval = EXIT_SUCCESS;
+ dk_bmm_show_current_media_number();
+ }
+ }
+ } else {
+ /* ERROR: Failed to read file, probably not a dk-bmm file. */
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 9);
+ }
+ }
+ $? "- dk_bmm_run_for_file"
+}
+
+
+
+#if DK4_ON_WINDOWS
+
+static
+int
+dk_bmm_expand_pattern(const dkChar *pattern)
+{
+ dkChar buf[DK4_MAX_PATH];
+ dk4_dir_t *fne;
+ const dkChar *shf;
+ const dkChar *pth;
+ int back = 0;
+ $? "+ dk_bmm_expand_pattern"
+ fne = dk4app_fne_open(pattern, app);
+ if (NULL != fne) {
+ shf = dk4dir_next_file(fne);
+ if (NULL != shf) {
+ if (NULL == dk4dir_next_file(fne)) {
+ pth = dk4dir_get_path(fne);
+ if (NULL != pth) {
+ if (0 != dk4str_cpy_s(buf, DK4_SIZEOF(buf,dkChar), pth, NULL)) {
+ if(0!=dk4str_cat_s(buf,DK4_SIZEOF(buf,dkChar),dk_bmm_kwnl[3],NULL))
+ {
+ if(0 != dk4str_cat_s(buf, DK4_SIZEOF(buf,dkChar), shf, NULL)) {
+ dk_bmm_run_for_file(buf);
+ } else {
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ }
+ } else {
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ }
+ } else {
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ }
+ } else {
+ dk_bmm_run_for_file(shf);
+ }
+ } else {
+ /* ERROR: Multiple files */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 106, pattern);
+ }
+ } else {
+ /* ERROR: No file found */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 107, pattern);
+ }
+ dk4dir_close(fne);
+ }
+ $? "- dk_bmm_expand_pattern %d", back
+ return back;
+}
+
+#endif
+
+
+
+/** Run after installing signal handlers.
+*/
+static
+void
+dk_bmm_normal_run(void)
+{
+ const dkChar *xargv;
+ $? "+ dk_bmm_normal_run"
+ if (0 != dk4app_opt_is_set_short(app, dkT('c'), NULL)) {
+ dk_bmm_do_confirm = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('r'), NULL)) {
+ dk_bmm_do_report = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('s'), NULL)) {
+ dk_bmm_handle_set = 1;
+ }
+ if (dk4app_get_argc(app) == 1) {
+ xargv = dk4app_get_argv(app, 0);
+ if (NULL != xargv) {
+#if DK4_ON_WINDOWS
+ if (0 != dk4path_must_expand(xargv)) {
+ dk_bmm_expand_pattern(xargv);
+ } else {
+#endif
+ dk_bmm_run_for_file(xargv);
+#if DK4_ON_WINDOWS
+ }
+#endif
+ } else {
+ /* ERROR: Exactly one file allowed! */
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 10);
+ }
+ } else {
+ /* ERROR: Exactly one file allowed! */
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 10);
+ }
+ $? "- dk_bmm_normal_run"
+}
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+dk_bmm_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ struct sigaction opipe;
+#endif
+ struct sigaction oint;
+#ifdef SIGPIPE
+ struct sigaction npipe;
+#endif
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+ int success = 0;
+
+#ifdef SIGPIPE
+ /* Set up signal handling for SIGPIPE.
+ */
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+#endif
+
+ /* Set up signal handling for SIGINT.
+ */
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ dk_bmm_normal_run();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+#ifdef SIGPIPE
+ /* Restore signal handling for SIGPIPE.
+ */
+ restore_old_pipe:
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+#endif
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+dk_bmm_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ dk_bmm_normal_run();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+#ifdef SIGPIPE
+ sigset(SIGPIPE, oldpipe);
+#endif
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+dk_bmm_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = signal(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ dk_bmm_normal_run();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+#ifdef SIGPIPE
+ signal(SIGPIPE, oldpipe);
+#endif
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+dk_bmm_run_with_signal_handlers(void)
+{
+ dk_bmm_normal_run();
+}
+#endif
+#endif
+#endif
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ int oldstdlevel;
+ int oldfilelevel;
+ $!trace-init dk-bmm.deb
+ $? "+ main"
+ dk4fput_initialize_stderr();
+ app = dk4app_open_cmd(
+ argc, argv, dk_bmm_options, dk_bmm_sz_options,
+ dk_bmm_kwnl[0], DKT_VERSION_DK,
+ dk_bmm_kwnl[1], dk_bmm_help_text, dk_bmm_license_text
+ );
+ if (NULL != app) {
+ dk_bmm_sz_msg = dk4app_string_table_size(dk_bmm_kw_def);
+ dk_bmm_msg = dk4app_string_table(app, dk_bmm_kwnl[2], dk_bmm_kw_def);
+ if (0 != dk4app_can_run_normally(app)) {
+ dk_bmm_run_with_signal_handlers();
+ if (0 != dk_bmm_cycle_completed) {
+ /* INFO: Cycle completed, change media set */
+ oldstdlevel = app->ll_stderr;
+ oldfilelevel = app->ll_file;
+ app->ll_file = DK4_LL_INFO;
+ app->ll_stderr = DK4_LL_INFO;
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_INFO, 11);
+ app->ll_file = oldfilelevel;
+ app->ll_stderr = oldstdlevel;
+ }
+ if (0 != output_error) {
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 2);
+ exval = EXIT_FAILURE;
+ }
+#ifdef SIGPIPE
+ if (0 != sig_read_atomic(&sig_had_pipe)) {
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 3);
+ exval = EXIT_FAILURE;
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_term)) {
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 5);
+ exval = EXIT_FAILURE;
+ }
+ if (0 != sig_read_atomic(&sig_had_int)) {
+ dk4app_log_1(app, dk_bmm_msg, dk_bmm_sz_msg, DK4_LL_ERROR, 4);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ dk4fput_initialize_stdout();
+ dk_bmm_mod_stdout = 1; $? ". mod stdout"
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ dk4app_close(app); app = NULL;
+ }
+ fflush(stdout);
+ fflush(stderr);
+ dk4fput_cleanup_stderr();
+ if (0 != dk_bmm_mod_stdout) {
+ dk4fput_cleanup_stdout();
+ }
+ $? "- main %d", exval
+ $!trace-end
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/dk-bmm.rc b/support/dktools/dk-bmm.rc
new file mode 100644
index 0000000000..40d61c3eb9
--- /dev/null
+++ b/support/dktools/dk-bmm.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Backup media manager\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "Backup media manager\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "dk-bmm\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/dk-cat.c b/support/dktools/dk-cat.c
new file mode 100644
index 0000000000..63b35118ff
--- /dev/null
+++ b/support/dktools/dk-cat.c
@@ -0,0 +1,2433 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk-cat.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#line 10 "dk-cat.ctr"
+
+/** @file dk-cat.c The dk-cat program.
+ The dk_cat_help_text array below shows details.
+*/
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4vers.h"
+#include "dk4app.h"
+#include "dk4aopt.h"
+#include "dk4enc.h"
+#include "dk4mem.h"
+#include "dk4strm.h"
+#include "dk4strmf.h"
+#include "dk4strmo32.h"
+#include "dk4istty.h"
+#include "dk4fopda.h"
+#include "dk4tsp32.h"
+#include "dk4tspdk.h"
+#include "dk4mao8d.h"
+#include "dk4str8.h"
+#include "dk4strd.h"
+#include "dk4pathd.h"
+#include "dk4fput.h"
+#include "dk4maodd.h"
+#include "dk4mpl.h"
+#include "dk4isadm.h"
+
+
+
+
+
+#line 94 "dk-cat.ctr"
+
+
+
+#ifndef DK_CAT_INPUT_BUFFER_SIZE
+/** Input buffer size.
+*/
+#define DK_CAT_INPUT_BUFFER_SIZE 4096
+#endif
+
+
+
+/** Default text, used if help text file is not found.
+*/
+static const dkChar * const dk_cat_help_text[] = {
+dkT(""),
+dkT("Show text files"),
+dkT(""),
+dkT("dk-cat [<options>] [<files>]"),
+dkT(""),
+dkT("Options:"),
+dkT("-c <bool> Enable CR/NL -n Write line numbers"),
+dkT("-i <encoding> Expected input encoding -w Normalize text lines"),
+dkT("-o <encoding> Output encoding -p No unneccessary decoding/encoding"),
+dkT("--help Show this short help text. --manual *** SHOW FULL MANUAL. ***"),
+dkT("--version Show version information. --license Show license information."),
+dkT("--verbose Error message on SIGPIPE"),
+dkT("--line-number-width=<int> Minimum line number width."),
+dkT(""),
+dkT("Encoding names: plain (ASCII text), ascii (synonym for plain), ansi, utf-8,"),
+dkT("utf-16, utf-16le (little-endian) utf-16be (big-endian),"),
+dkT("c32 (32 bit characters), c32le, c32be."),
+dkT(""),
+dkT("http://dktools.sourceforge.net"),
+dkT(""),
+NULL
+
+
+#line 130 "dk-cat.ctr"
+};
+
+
+
+/** License conditions.
+*/
+static const dkChar * const dk_cat_license_text[] = {
+dkT(""),
+dkT("This software uses code from the following projects, either directly or as"),
+dkT("a library:"),
+dkT(""),
+dkT("dktools\t\tDirk Krause's tools and libraries."),
+dkT("\t\tSee http://dktools.sourceforge.net/ for more information."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT("zlib\t\tData compression library."),
+dkT("\t\tSee http://www.zlib.net/ for more information."),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT("bzip2\t\tData compression program and library."),
+dkT("\t\tSee http://www.bzip.org/ for more information."),
+#endif
+dkT(""),
+dkT("All the licenses below apply to the program."),
+dkT("Licenses for used libraries are shown as found on my Scientific Linux 6.x"),
+dkT("computer in the /usr/share/doc directory on 2015-04-01. Check the project"),
+dkT("homepages of the used libraries for additional information and/or updated"),
+dkT("license terms."),
+dkT(""),
+dkT(""),
+dkT("DK tools and libraries license"),
+dkT("=============================="),
+dkT("Copyright (c) 2015-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above copyright notice,"),
+dkT(" this list of conditions and the following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("* Neither the name of the Dirk Krause nor the names of contributors may be"),
+dkT(" used to endorse or promote products derived from this software without"),
+dkT(" specific prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\""),
+dkT("AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED."),
+dkT(""),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,"),
+dkT("INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,"),
+dkT("BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,"),
+dkT("DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY"),
+dkT("OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,"),
+dkT("EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT(""),
+dkT("Zlib license"),
+dkT("============"),
+dkT("(C) 1995-2004 Jean-loup Gailly and Mark Adler"),
+dkT(""),
+dkT("This software is provided 'as-is', without any express or implied"),
+dkT("warranty. In no event will the authors be held liable for any damages"),
+dkT("arising from the use of this software."),
+dkT(""),
+dkT("Permission is granted to anyone to use this software for any purpose,"),
+dkT("including commercial applications, and to alter it and redistribute it"),
+dkT("freely, subject to the following restrictions:"),
+dkT(""),
+dkT("1. The origin of this software must not be misrepresented; you must not"),
+dkT(" claim that you wrote the original software. If you use this software"),
+dkT(" in a product, an acknowledgment in the product documentation would be"),
+dkT(" appreciated but is not required."),
+dkT("2. Altered source versions must be plainly marked as such, and must not be"),
+dkT(" misrepresented as being the original software."),
+dkT("3. This notice may not be removed or altered from any source distribution."),
+dkT(""),
+dkT("Jean-loup Gailly Mark Adler"),
+dkT("jloup@gzip.org madler@alumni.caltech.edu"),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT(""),
+dkT("Bzip2 and libbzip2 library license"),
+dkT("=================================="),
+dkT("This program, \"bzip2\", the associated library \"libbzip2\", and all"),
+dkT("documentation, are copyright (C) 1996-2007 Julian R Seward. All"),
+dkT("rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions"),
+dkT("are met:"),
+dkT(""),
+dkT("1. Redistributions of source code must retain the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer."),
+dkT(""),
+dkT("2. The origin of this software must not be misrepresented; you must "),
+dkT(" not claim that you wrote the original software. If you use this "),
+dkT(" software in a product, an acknowledgment in the product "),
+dkT(" documentation would be appreciated but is not required."),
+dkT(""),
+dkT("3. Altered source versions must be plainly marked as such, and must"),
+dkT(" not be misrepresented as being the original software."),
+dkT(""),
+dkT("4. The name of the author may not be used to endorse or promote "),
+dkT(" products derived from this software without specific prior written "),
+dkT(" permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS"),
+dkT("OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED"),
+dkT("WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE"),
+dkT("GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS"),
+dkT("INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,"),
+dkT("WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS"),
+dkT("SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+dkT(""),
+dkT("Julian Seward, jseward@bzip.org"),
+dkT("bzip2/libbzip2 version 1.0.5 of 10 December 2007"),
+#endif
+dkT(""),
+NULL
+
+
+#line 262 "dk-cat.ctr"
+};
+
+
+
+/** Constant texts used by program, not localized.
+*/
+static const dkChar * const dk_cat_kwnl[] = {
+/* 0 */
+dkT("dktools"),
+
+/* 1 */
+dkT("dk-cat.txt"),
+
+/* 2 */
+dkT("dk-cat.str"),
+
+/* 3 */
+dkT("line-number-width"),
+
+/* 4 */
+dkT("stdin"),
+
+/* 5 */
+dkT("\\"),
+
+/* 6 */
+dkT("verbose"),
+
+NULL
+
+
+#line 299 "dk-cat.ctr"
+};
+
+
+
+/** Constant texts used by program, replaced by localized texts
+ if available.
+*/
+static const dkChar * const dk_cat_kw_def[] = {
+/* 0 */
+dkT("Decoding error!\n\tByte: "),
+
+/* 1 */
+dkT("Another decoding error!"),
+
+/* 2 */
+dkT("Further decoding errors!"),
+
+/* 3 */
+dkT("Encoding error!\n\tByte: "),
+
+/* 4 */
+dkT("Another encoding error!"),
+
+/* 5 */
+dkT("Further encoding errors!"),
+
+/* 6 */
+dkT("Processing error!\n\tByte: "),
+
+/* 7 */
+dkT("Another processing error!"),
+
+/* 8 */
+dkT("Further processing errors!"),
+
+/* 9 */
+dkT(",\n\tCharacter: "),
+
+/* 10 */
+dkT(",\n\tPosition in line: "),
+
+/* 11 */
+dkT("Decoding error!"),
+
+/* 12 */
+dkT("Encoding error!"),
+
+/* 13 */
+dkT("Processing error!"),
+
+/* 14 */
+dkT("."),
+
+/* 15 */
+dkT("Illegal input encoding: \""),
+
+/* 16 */
+dkT("\"!"),
+
+/* 17 */
+dkT("Illegal output encoding: \""),
+
+/* 18 */
+dkT("\"!"),
+
+/* 19 */
+dkT("Line number width must be larger than 0!"),
+
+/* 20 */
+dkT("Failed to write text to output!"),
+
+/* 21 */
+dkT("Numeric conversion failed (should not happen, probably bug in program)!"),
+
+/* 22 */
+dkT("Failed to set up signal handlers!"),
+
+/* 23 */
+dkT("Failed to restore signal handlers!"),
+
+/* 24 */
+dkT("Signal received: SIGPIPE!"),
+
+/* 25 */
+dkT("Signal received: SIGINT!"),
+
+NULL
+
+
+#line 377 "dk-cat.ctr"
+};
+
+
+
+/** Message texts, uses localized texts if possible.
+*/
+static const dkChar * const *msg = dk_cat_kw_def;
+
+
+
+/** Options used by program.
+*/
+static const dk4_option_specification_t dk_cat_options[] = {
+
+ /* Flag: Line end consists of carriage return and newline.
+ */
+ { dkT('c'), dkT("crnl"), DK4_OPT_ARG_BOOL },
+
+ /* Show line numbers.
+ */
+ { dkT('n'), dkT("line-numbers"), DK4_OPT_ARG_NONE },
+
+ /* Number of digits for line numbers.
+ */
+ { dkT('\0'), dkT("line-number-width"), DK4_OPT_ARG_SIZE },
+
+ /* Flag: Normalize text lines.
+ */
+ { dkT('w'), dkT("normalize"), DK4_OPT_ARG_NONE },
+
+ /* Expected input encoding.
+ */
+ { dkT('i'), dkT("input-encoding"), DK4_OPT_ARG_STRING },
+
+ /* Output encoding to produce.
+ */
+ { dkT('o'), dkT("output-encoding"), DK4_OPT_ARG_STRING },
+
+ /* Pass-through UTF-8 data.
+ */
+ { dkT('p'), dkT("pass-through"), DK4_OPT_ARG_NONE },
+
+ /* Verbose output.
+ */
+ { dkT('\0'), dkT("verbose"), DK4_OPT_ARG_NONE }
+
+};
+
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+/** Check whether we can continue or if a signal was received.
+ @param check_pipe Flag: Check for occured SIGPIPE signal too.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(int check_pipe)
+{
+ int back = 1;
+#ifdef SIGPIPE
+ if (0 != check_pipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_int )) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Number of elements in the dk_cat_options array.
+*/
+static const size_t dk_cat_sz_options =
+sizeof(dk_cat_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Number of usable elements in the dk_cat_kw_def array and in msg.
+*/
+static size_t sz_msg = (sizeof(dk_cat_kw_def)/sizeof(DK4_PDKCHAR) - 1);
+
+
+/** Name of current input file processed.
+*/
+static const dkChar *input_file_name = NULL;
+
+
+/** Flag: Output already initialized.
+*/
+static int output_initialized = 0;
+
+
+#if DK4_ON_WINDOWS
+/** Original mode for stdout.
+*/
+static int old_output_mode = 0;
+#endif
+
+
+/** Flag: Use stream instead output to stdout.
+*/
+static int use_stream = 1;
+
+
+/** System output encoding.
+*/
+static int oenc_sys = DK4_FILE_ENCODING_ASCII;
+
+
+/** Default output encoding on the system.
+*/
+static int oenc_def = DK4_FILE_ENCODING_ASCII;
+
+
+
+/** Output encoding specified on command line.
+*/
+static int oenc = DK4_FILE_ENCODING_ASCII;
+
+
+/** System setting whether or not to write a BOM.
+*/
+static int obom_sys = 0;
+
+
+/** Flag: Write BOM. -1=auto, 0=no, 1=yes.
+*/
+static int obom = -1;
+
+
+/** Default CR/NL sequence setting.
+*/
+static int crnl_def = DK4_HAVE_LINE_END_CR_NL;
+
+
+/** CR/NL sequence setting from options if available.
+*/
+static int crnl = DK4_HAVE_LINE_END_CR_NL;
+
+
+/** Input encoding specified on the command line.
+*/
+static int ienc_def = DK4_FILE_ENCODING_ASCII;
+
+
+/** Flag: Show line numbers (from options).
+*/
+static int line_numbers = 0;
+
+
+/** Current line number.
+*/
+static dk4_um_t line_number = (dk4_um_t)1UL;
+
+
+/** Flag: Previous character was carriage return.
+*/
+static int previous_was_cr = 0;
+
+
+/** Flag: Previous character was not a whitespace.
+*/
+static int previous_was_text = 0;
+
+
+/** Flag: Previous character was a newline.
+*/
+static int previous_was_nl = 0;
+
+
+/** Flag: We already had text in this line.
+*/
+static int text_in_line = 0;
+
+
+/** Flag: We had any output for this file.
+*/
+static int there_was_text = 0;
+
+
+/** Flag: Line number was already printed for current line.
+*/
+static int line_number_printed = 0;
+
+
+/** Line number width.
+*/
+static size_t line_number_width = 5;
+
+
+/** Flag: Normalize lines.
+*/
+static int normalize_lines = 0;
+
+
+/** Exit status code.
+*/
+static int exval = EXIT_FAILURE;
+
+
+/** Flag: Already reported encoding errors for this file.
+*/
+static int had_encoding_error = 0;
+
+/** Flag: Already reported decoding errors for this file.
+*/
+static int had_decoding_error = 0;
+
+/** Flag: Already reported processing errors for this file.
+*/
+static int had_processing_error = 0;
+
+/** Flag: Had error while writing to stdout.
+*/
+static int had_write_error = 0;
+
+/** Flag: Verbose output (report SIGPIPE).
+*/
+static int verbose = 0;
+
+
+/** Output stream.
+*/
+static dk4_stream_t *output_stream = NULL;
+
+
+
+/*
+ We can output to stdout using dk4fputc() if all the conditions
+ below are true:
+ - output encoding is system output encoding and
+ - CR/NL setting is system CR/NL setting and
+ - BOM settings is ``automatic'' or is system BOM setting.
+
+ Otherwise we set stdout in binary mode (on Windows only)
+ and use a dk4_stream_t to process 32 bit characters.
+*/
+
+/** Initialize settings from application.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+initialize_from_app(void)
+{
+ dkChar buf[32];
+ int res = 0; /* Operation result */
+ int back = 1;
+
+
+#line 711 "dk-cat.ctr"
+
+ /* String tables and defaults.
+ */
+
+
+#line 715 "dk-cat.ctr"
+ oenc_sys = dk4app_get_stdout_encoding(app);
+ oenc_def = oenc_sys;
+ ienc_def = dk4app_get_stdin_encoding(app);
+
+
+#line 719 "dk-cat.ctr"
+ if (0 < dk4app_get_argc(app)) {
+ ienc_def = dk4app_get_file_in_encoding(app);
+
+
+#line 722 "dk-cat.ctr"
+ }
+
+ /* Set verbose flag if -v was used.
+ */
+ if (0 != dk4app_opt_is_set_long(app, dk_cat_kwnl[6], NULL)) {
+ verbose = 1;
+ }
+
+ /* Output encoding to produce (-o)
+ */
+
+
+#line 733 "dk-cat.ctr"
+ if (0 != dk4app_opt_is_set_short(app, dkT('o'), NULL)) {
+
+#line 734 "dk-cat.ctr"
+ res = dk4app_opt_get_string_short(
+ buf, DK4_SIZEOF(buf,dkChar), app, dkT('o'), NULL
+ );
+ if (0 != res) {
+
+#line 738 "dk-cat.ctr"
+ res = dk4enc_find(&oenc_def, &obom, buf, NULL);
+ if (0 == res) {
+
+#line 740 "dk-cat.ctr"
+ /* ERROR: Illegal output encoding */
+ dk4app_log_3(app, msg, sz_msg, DK4_LL_ERROR, 17, 18, buf);
+ back = 0;
+ }
+ } else {
+
+#line 745 "dk-cat.ctr"
+ /* ERROR: BUG, No option argument */
+ back = 0;
+ }
+ }
+
+ /* Expected input encoding (-i)
+ */
+
+
+#line 753 "dk-cat.ctr"
+ if (0 != dk4app_opt_is_set_short(app, dkT('i'), NULL)) {
+
+#line 754 "dk-cat.ctr"
+ res = dk4app_opt_get_string_short(
+ buf, DK4_SIZEOF(buf,dkChar), app, dkT('i'), NULL
+ );
+ if (0 != res) {
+
+#line 758 "dk-cat.ctr"
+ res = dk4enc_find(&ienc_def, NULL, buf, NULL);
+ if (0 == res) {
+
+#line 760 "dk-cat.ctr"
+ /* ERROR: Illegal input encoding */
+ dk4app_log_3(app, msg, sz_msg, DK4_LL_ERROR, 15, 16, buf);
+ back = 0;
+ }
+ } else {
+
+#line 765 "dk-cat.ctr"
+ /* ERROR: BUG, No option argument */
+ back = 0;
+ }
+ }
+
+ /* CR/NL (-c)
+ */
+
+
+#line 773 "dk-cat.ctr"
+ if (0 != dk4app_opt_is_set_short(app, dkT('c'), NULL)) {
+
+#line 774 "dk-cat.ctr"
+ if (0 == dk4app_opt_get_bool_short(&crnl, app, dkT('c'), NULL)) {
+ /* ERROR: BUG, No option argument */
+ back = 0;
+
+#line 777 "dk-cat.ctr"
+ }
+ }
+
+ /* Line numbers (-n)
+ */
+
+
+#line 783 "dk-cat.ctr"
+ if (0 != dk4app_opt_is_set_short(app, dkT('n'), NULL)) {
+
+#line 784 "dk-cat.ctr"
+ line_numbers = 1;
+ }
+
+ /* Line number width (--line-number-width)
+ */
+
+
+#line 790 "dk-cat.ctr"
+ if (0 != dk4app_opt_is_set_long(app, dk_cat_kwnl[3], NULL)) {
+
+#line 791 "dk-cat.ctr"
+ if (0 == dk4app_opt_get_size_long(&line_number_width, app, dk_cat_kwnl[3], NULL)) {
+ /* ERROR: BUG, No option argument */
+ back = 0;
+
+#line 794 "dk-cat.ctr"
+ } else {
+ if (0 == line_number_width) {
+
+#line 796 "dk-cat.ctr"
+ /* ERROR: Illegal line number width */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 19);
+ back = 0;
+ }
+ }
+ }
+
+ /* Normalize text (-w)
+ */
+
+
+#line 806 "dk-cat.ctr"
+ if (0 != dk4app_opt_is_set_short(app, dkT('w'), NULL)) {
+
+#line 807 "dk-cat.ctr"
+ normalize_lines = 1;
+ }
+
+
+
+#line 811 "dk-cat.ctr"
+ switch (oenc_sys) {
+ case DK4_FILE_ENCODING_ASCII :
+ case DK4_FILE_ENCODING_ANSI :
+ case DK4_FILE_ENCODING_UTF8 :
+ {
+ obom_sys = 0;
+ } break;
+ default :
+ {
+ if (0 == dk4istty(1, NULL)) {
+ obom_sys = 1;
+ }
+ } break;
+ }
+ oenc = oenc_def;
+
+
+
+#line 828 "dk-cat.ctr"
+ return back;
+}
+
+
+
+/** Check whether we can write to standard output directly.
+*/
+static
+void
+decide_for_output_type(void)
+{
+ if (oenc_def == oenc_sys) {
+ if (crnl == crnl_def) {
+ if ((-1 == obom) || (obom_sys == obom)) {
+ use_stream = 0;
+ }
+ }
+ }
+}
+
+
+
+/** Initialize output structures before writing first output.
+*/
+static
+void
+initialize_output(void)
+{
+ dk4_er_t er;
+
+
+#line 858 "dk-cat.ctr"
+ if (0 == output_initialized) {
+ output_initialized = 1;
+ if (0 != use_stream) {
+ dk4error_init(&er);
+#if DK4_ON_WINDOWS
+
+
+#line 864 "dk-cat.ctr"
+ old_output_mode = _setmode(_fileno(stdout), _O_BINARY);
+#endif
+ output_stream = dk4stream_open_for_file(
+ stdout, DK4_STREAM_WRITE, 0, 4096, &er
+ );
+ if (NULL != output_stream) {
+ dk4stream_set_output_encoding(output_stream, oenc);
+ switch (obom) {
+ case 1: {
+ if(0 == dk4stream_c32_putc(output_stream, dkC32(0xFEFF), NULL)) {
+ /* ERROR: Failed to write BOM */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 20);
+ exval = EXIT_FAILURE;
+ }
+ } break;
+ case -1: {
+ if (1 == obom_sys) {
+ if(0 == dk4stream_c32_putc(output_stream,dkC32(0xFEFF),NULL)) {
+ /* ERROR: Failed to write BOM */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 20);
+ exval = EXIT_FAILURE;
+ }
+ }
+ } break;
+ }
+ } else {
+ /* ERROR: Failed to create stream */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ }
+ } else {
+ dk4fput_initialize_stdout();
+ }
+ }
+
+#line 897 "dk-cat.ctr"
+}
+
+
+
+/** Close stream, or set mode for stdout back to original mode.
+*/
+static
+void
+cleanup_output(void)
+{
+ dk4_er_t er;
+
+
+#line 909 "dk-cat.ctr"
+ if (0 != output_initialized) {
+ if (0 != use_stream) {
+ if (NULL != output_stream) {
+ /* Close output stream.
+ */
+ dk4error_init(&er);
+ if (0 == dk4stream_close(output_stream, &er)) {
+ /* ERROR: Closing the stream failed */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 20);
+ exval = EXIT_FAILURE;
+ }
+ }
+#if DK4_ON_WINDOWS
+ /* Set stdout to original mode.
+ */
+
+
+#line 925 "dk-cat.ctr"
+ _setmode(_fileno(stdout), old_output_mode);
+#endif
+ } else {
+ dk4fput_cleanup_stdout();
+ }
+ }
+
+#line 931 "dk-cat.ctr"
+}
+
+
+
+/** Report an error with position in source line.
+ @param i1 Index of first message part in array.
+ @param i2 Index of alternative first message part.
+ @param bno Byte processed.
+ @param lno Current line number.
+ @param cno Current character number.
+ @param cil Current character number in line.
+*/
+static
+void
+report_with_position(
+ size_t i1,
+ size_t i2,
+ dk4_um_t bno,
+ dk4_um_t lno,
+ dk4_um_t cno,
+ dk4_um_t cil
+)
+{
+ dkChar b1[8*(1+sizeof(dk4_um_t))];
+ dkChar b2[8*(1+sizeof(dk4_um_t))];
+ dkChar b3[8*(1+sizeof(dk4_um_t))];
+ const dkChar *oldlogname = NULL;
+ dk4_um_t oldlogline = (dk4_um_t)0UL;
+ int allbuffersok = 0;
+
+ oldlogname = dk4app_get_log_source_file(app);
+ oldlogline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_file(app, input_file_name);
+ dk4app_set_log_source_line(app, lno);
+ if (0 != dk4ma_write_decimal_unsigned(b3,DK4_SIZEOF(b3,dkChar),cil,0,NULL)) {
+ if (0 != dk4ma_write_decimal_unsigned(b2,DK4_SIZEOF(b2,dkChar),cno,0,NULL)) {
+ if (0 != dk4ma_write_decimal_unsigned(b1,DK4_SIZEOF(b1,dkChar),bno,0,NULL)) {
+ allbuffersok = 1;
+ }
+ }
+ }
+ if (0 != allbuffersok) {
+ dk4app_log_7(
+ app, msg, sz_msg, DK4_LL_ERROR, i1, 9, 10, 14, b1, b2, b3
+ );
+ } else {
+ dk4app_log_1(
+ app, msg, sz_msg, DK4_LL_ERROR, i2
+ );
+ }
+ dk4app_set_log_source_file(app, oldlogname);
+ dk4app_set_log_source_line(app, oldlogline);
+}
+
+
+
+/** Report an error occured while writing 32 bit character to
+ output stream.
+ @param erp Error information returned by dk4stream_c32_putc().
+ @param pos Position information.
+*/
+static
+void
+error_while_writing_c32(dk4_er_t *erp, dk4_text_stream_position_t *pos)
+{
+ dk4_um_t bytes = (dk4_um_t)0UL;
+ dk4_um_t lineno = (dk4_um_t)0UL;
+ dk4_um_t chars = (dk4_um_t)0UL;
+ dk4_um_t charil = (dk4_um_t)0UL;
+ switch (erp->ec) {
+ case DK4_E_ENCODING_FAILED : {
+ if (NULL != pos) {
+ bytes = pos->bytes;
+ lineno = pos->lineno;
+ chars = pos->chars;
+ charil = pos->charil;
+ }
+ if ((dk4_um_t)0UL < bytes) { bytes = bytes - (dk4_um_t)1UL; }
+ if ((dk4_um_t)0UL < chars) { chars = chars - (dk4_um_t)1UL; }
+ if ((dk4_um_t)0UL < charil) { charil = charil - (dk4_um_t)1UL; }
+ report_with_position(3, 12, bytes, lineno, chars, charil);
+ } break;
+ default: {
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 20);
+ } break;
+ }
+}
+
+
+
+/** Write one 32 bit character to output.
+ If the character is a newline, convert to carriage return and
+ newline sequence if required by crnl settings.
+ @param obj Object to modify while processing the character
+ (NULL here).
+ @param c Character to process.
+ @param pos Current position in file or data stream.
+ @param erp Error report, may be NULL.
+ @return Result code:
+ - DK4_TSP_RES_OK if the character was processed successfully,
+ - DK4_TSP_RES_ERROR if there was an error but we can continue,
+ - DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+c32_real_output(
+ void *obj,
+ dk4_c32_t c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er;
+ int back = DK4_TSP_RES_OK;
+ dk4_sig_atomic_t shp;
+
+
+
+#line 1049 "dk-cat.ctr"
+ initialize_output();
+ if (0 != use_stream) {
+ if (NULL != output_stream) {
+ dk4error_init(&er);
+#ifdef SIGPIPE
+ shp = sig_read_atomic(&sig_had_pipe);
+#else
+ shp = 0;
+#endif
+ if (0 == shp) {
+ if ((dkC32(0x0A) == c) && (0 != crnl)) {
+ if (0 == dk4stream_c32_putc(output_stream, dkC32(0x0D), &er)) {
+ /* ERROR: Failed to write output character */
+ error_while_writing_c32(&er, pos);
+ back = DK4_TSP_RES_FATAL;
+ }
+ }
+ if (0 == dk4stream_c32_putc(output_stream, c, &er)) {
+ /* ERROR: Failed to write output character */
+ error_while_writing_c32(&er, pos);
+ back = DK4_TSP_RES_FATAL;
+ }
+ }
+ } else {
+ /* ERROR: Failed to create output stream (already reported) */
+ back = DK4_TSP_RES_FATAL;
+ }
+ } else {
+ }
+ if (dkC32(0x0A) == c) {
+ previous_was_nl = 1;
+ } else {
+ previous_was_nl = 0;
+ }
+ there_was_text = 1;
+
+
+#line 1085 "dk-cat.ctr"
+ return back;
+}
+
+
+
+/** Check whether a character is the first character in a line,
+ write line number if necessary and write the character.
+ @param obj Object to modify while processing the character
+ (NULL here).
+ @param c Character to process.
+ @param pos Current position in file or data stream.
+ @param erp Error report, may be NULL.
+ @return Result code:
+ - DK4_TSP_RES_OK if the character was processed successfully,
+ - DK4_TSP_RES_ERROR if there was an error but we can continue,
+ - DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+c32_after_normalize(
+ void *obj,
+ dk4_c32_t c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+)
+{
+ char buf[8*(1+sizeof(dk4_um_t))];
+ char *ptr = NULL;
+ size_t i = 0;
+ int res = 0;
+ int back = DK4_TSP_RES_OK;
+
+
+#line 1118 "dk-cat.ctr"
+ if (0 != line_numbers) {
+ if (0 == line_number_printed) {
+ line_number_printed = 1;
+ res = dk4ma_write_c8_decimal_unsigned(
+ buf, sizeof(buf), line_number, 0, NULL
+ );
+ if (0 != res) {
+ /* Spaces before line number.
+ */
+ i = dk4str8_len(buf);
+ while (i < line_number_width) {
+ switch (c32_real_output(obj, dkC32(0x20), pos, erp)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ i++;
+ }
+ /* Line number
+ */
+ ptr = buf;
+ while ('\0' != *ptr) {
+ res = c32_real_output(
+ obj, (dk4_c32_t)((unsigned char)(*(ptr++))), pos, erp
+ );
+ switch (res) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ }
+ /* Trailing space after line number
+ */
+ switch (c32_real_output(obj, dkC32(0x20), pos, erp)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ } else {
+ /* ERROR: Failed to convert line number. */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 21);
+ back = DK4_TSP_RES_FATAL;
+ }
+ }
+ switch (c32_real_output(obj, c, pos, erp)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ } else {
+ back = c32_real_output(obj, c, pos, erp);
+ }
+
+#line 1190 "dk-cat.ctr"
+ return back;
+}
+
+
+
+/** Normalize the text if required and pass characters downwards.
+ @param obj Object to modify while processing the character
+ (NULL here).
+ @param c Character to process.
+ @param pos Current position in file or data stream.
+ @param erp Error report, may be NULL.
+ @return Result code:
+ - DK4_TSP_RES_OK if the character was processed successfully,
+ - DK4_TSP_RES_ERROR if there was an error but we can continue,
+ - DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+c32_after_cr_nl(
+ void *obj,
+ dk4_c32_t c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_TSP_RES_OK;
+
+
+#line 1218 "dk-cat.ctr"
+ if (0 != normalize_lines) {
+ if ((dkC32(0x09) == c) || (dkC32(0x20) == c) || (dkC32(0x0D) == c)) {
+ previous_was_text = 0;
+ } else {
+ if (dkC32(0x0A) == c) {
+ previous_was_text = 0;
+ back = c32_after_normalize(obj, c, pos, erp);
+ text_in_line = 0;
+ } else {
+ if ((0 == previous_was_text) && (0 != text_in_line)) {
+ back = c32_after_normalize(obj, dkC32(0x20), pos, erp);
+ }
+ switch (c32_after_normalize(obj, c, pos, erp)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ previous_was_text = 1;
+ text_in_line = 1;
+ }
+ }
+ } else {
+ back = c32_after_normalize(obj, c, pos, erp);
+ }
+
+#line 1247 "dk-cat.ctr"
+ return back;
+}
+
+
+
+/** Handler function for single characters.
+ @param obj Object to modify while processing the character.
+ @param c Character to process.
+ @param pos Current position in file or data stream.
+ @param erp Error report, may be NULL.
+ @return Result code:
+ - DK4_TSP_RES_OK if the character was processed successfully,
+ - DK4_TSP_RES_ERROR if there was an error but we can continue,
+ - DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+c32_handler(
+ void *obj,
+ dk4_c32_t c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_TSP_RES_OK;
+
+
+#line 1274 "dk-cat.ctr"
+ dk4app_set_log_source_line(app, line_number);
+ if (dkC32(0x0D) == c) {
+
+#line 1276 "dk-cat.ctr"
+ if (0 != previous_was_cr) {
+ back = c32_after_cr_nl(obj, dkC32(0x0D), pos, erp);
+ }
+ previous_was_cr = 1;
+ } else {
+ if (dkC32(0x0A) == c) {
+
+#line 1282 "dk-cat.ctr"
+ back = c32_after_cr_nl(obj, c, pos, erp);
+ line_number++;
+ dk4app_set_log_source_line(app, line_number);
+ line_number_printed = 0;
+ text_in_line = 0;
+ } else {
+
+#line 1288 "dk-cat.ctr"
+ if (0 != previous_was_cr) {
+ back = c32_after_cr_nl(obj, dkC32(0x0D), pos, erp);
+ }
+ switch (c32_after_cr_nl(obj, c, pos, erp)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ }
+ previous_was_cr = 0;
+ }
+
+#line 1304 "dk-cat.ctr"
+ return back;
+}
+
+
+
+/** Write one dkChar to output (for a newline write a carriage
+ return, newline sequence if required).
+ @param obj Object to modify while processing the character
+ (NULL here).
+ @param c Character to process.
+ @param pos Current position in file or data stream.
+ @param erp Error report, may be NULL.
+ @return Result code:
+ - DK4_TSP_RES_OK if the character was processed successfully,
+ - DK4_TSP_RES_ERROR if there was an error but we can continue,
+ - DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+dkc_real_output(
+ void *obj,
+ dkChar c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er;
+ int back = DK4_TSP_RES_OK;
+ dk4_sig_atomic_t shp;
+
+
+#line 1335 "dk-cat.ctr"
+ initialize_output();
+ dk4error_init(&er);
+#ifdef SIGPIPE
+ shp = sig_read_atomic(&sig_had_pipe);
+#else
+ shp = 0;
+#endif
+ if (0 == shp) {
+ if (0 == dk4fputc(c, stdout, &er)) {
+ /* ERROR while writing to standard output */
+#if 0
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 20);
+#endif
+ had_write_error = 0;
+ back = DK4_TSP_RES_FATAL;
+ exval = EXIT_FAILURE;
+ }
+ }
+ if (dkT('\n') == c) {
+ previous_was_nl = 1;
+ } else {
+ previous_was_nl = 0;
+ }
+ there_was_text = 1;
+
+
+#line 1360 "dk-cat.ctr"
+ return back;
+}
+
+
+
+/** Pass character downwards to dkc_real_output().
+ If the character is the first in the line, prepend line
+ number if required.
+ @param obj Object to modify while processing the character
+ (NULL here).
+ @param c Character to process.
+ @param pos Current position in file or data stream.
+ @param erp Error report, may be NULL.
+ @return Result code:
+ - DK4_TSP_RES_OK if the character was processed successfully,
+ - DK4_TSP_RES_ERROR if there was an error but we can continue,
+ - DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+dkc_after_normalize(
+ void *obj,
+ dkChar c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+)
+{
+ char buf[8*(1+sizeof(dk4_um_t))];
+ char *ptr = NULL;
+ size_t i = 0;
+ int res = 0;
+ int back = DK4_TSP_RES_OK;
+
+
+#line 1394 "dk-cat.ctr"
+ if (0 != line_numbers) {
+ if (0 == line_number_printed) {
+ line_number_printed = 1;
+ res = dk4ma_write_c8_decimal_unsigned(
+ buf, sizeof(buf), line_number, 0, NULL
+ );
+ if (0 != res) {
+ /* Spaces before line number.
+ */
+ i = dk4str8_len(buf);
+ while (i < line_number_width) {
+ switch (dkc_real_output(obj, dkT(' '), pos, erp)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ i++;
+ }
+ /* Line number
+ */
+ ptr = buf;
+ while ('\0' != *ptr) {
+ res = dkc_real_output(
+ obj, (dkChar)((unsigned char)(*(ptr++))), pos, erp
+ );
+ switch (res) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ }
+ /* Trailing space after line number
+ */
+ switch (dkc_real_output(obj, dkT(' '), pos, erp)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ } else {
+ /* ERROR: Failed to convert line number. */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 21);
+ back = DK4_TSP_RES_FATAL;
+ }
+ }
+ switch (dkc_real_output(obj, c, pos, erp)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ } else {
+ back = dkc_real_output(obj, c, pos, erp);
+ }
+
+#line 1466 "dk-cat.ctr"
+ return back;
+}
+
+
+
+/** Normalize text if required and pass characters downwards.
+ @param obj Object to modify while processing the character
+ (NULL here).
+ @param c Character to process.
+ @param pos Current position in file or data stream.
+ @param erp Error report, may be NULL.
+ @return Result code:
+ - DK4_TSP_RES_OK if the character was processed successfully,
+ - DK4_TSP_RES_ERROR if there was an error but we can continue,
+ - DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+dkc_after_cr_nl(
+ void *obj,
+ dkChar c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_TSP_RES_OK;
+
+
+#line 1494 "dk-cat.ctr"
+ if (0 != normalize_lines) {
+ if ((dkT('\t') == c) || (dkT(' ') == c) || (dkT('\r') == c)) {
+ previous_was_text = 0;
+ } else {
+ if (dkT('\n') == c) {
+ previous_was_text = 0;
+ back = dkc_after_normalize(obj, c, pos, erp);
+ text_in_line = 0;
+ } else {
+ if ((0 == previous_was_text) && (0 != text_in_line)) {
+ back = dkc_after_normalize(obj, dkT(' '), pos, erp);
+ }
+ switch (dkc_after_normalize(obj, c, pos, erp)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ previous_was_text = 1;
+ text_in_line = 1;
+ }
+ }
+ } else {
+ back = dkc_after_normalize(obj, c, pos, erp);
+ }
+
+#line 1523 "dk-cat.ctr"
+ return back;
+}
+
+
+
+/** Handler function for single characters.
+ @param obj Object to modify while processing the character
+ (NULL here).
+ @param c Character to process.
+ @param pos Current position in file or data stream.
+ @param erp Error report, may be NULL.
+ @return Result code:
+ - DK4_TSP_RES_OK if the character was processed successfully,
+ - DK4_TSP_RES_ERROR if there was an error but we can continue,
+ - DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+dkc_handler(
+ void *obj,
+ dkChar c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_TSP_RES_OK;
+
+
+#line 1551 "dk-cat.ctr"
+ dk4app_set_log_source_line(app, line_number);
+ if (dkT('\r') == c) {
+ if (0 != previous_was_cr) {
+ back = dkc_after_cr_nl(obj, dkT('\r'), pos, erp);
+ }
+ previous_was_cr = 1;
+ } else {
+ if (dkT('\n') == c) {
+ back = dkc_after_cr_nl(obj, c, pos, erp);
+ line_number++;
+ dk4app_set_log_source_line(app, line_number);
+ line_number_printed = 0;
+ text_in_line = 0;
+ } else {
+ if (0 != previous_was_cr) {
+ back = dkc_after_cr_nl(obj, dkT('\r'), pos, erp);
+ }
+ switch (dkc_after_cr_nl(obj, c, pos, erp)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ }
+ previous_was_cr = 0;
+ }
+
+
+#line 1582 "dk-cat.ctr"
+ return back;
+}
+
+
+
+/** Initialize variables like line number and others for one file.
+*/
+static
+void
+initialize_for_one_file(void)
+{
+
+
+#line 1594 "dk-cat.ctr"
+ line_number = (dk4_um_t)1UL;
+ previous_was_cr = 0;
+ previous_was_nl = 0;
+ previous_was_text = 0;
+ line_number_printed = 0;
+ there_was_text = 0;
+ had_encoding_error = 0;
+ had_decoding_error = 0;
+ had_processing_error = 0;
+ text_in_line = 0;
+
+
+#line 1605 "dk-cat.ctr"
+}
+
+
+
+/** Report errors indicated by text processing.
+ @param er_en Error report for decoding and encoding errors.
+ @param er_pr Error report for processing errors.
+*/
+static
+void
+report_errors(dk4_er_t *er_en, dk4_er_t *er_pr)
+{
+ if (NULL != er_en) {
+ switch (er_en->ec) {
+ case DK4_E_DECODING_FAILED: {
+ switch (had_decoding_error) {
+ case 0: case 1: {
+ report_with_position(
+ ((0 == had_decoding_error) ? 0 : 1), 11,
+ er_en->dt.fpos.byteno,
+ er_en->dt.fpos.lineno,
+ er_en->dt.fpos.charno,
+ er_en->dt.fpos.charinline
+ );
+ } break;
+ case 2: {
+ } break;
+ }
+ if (3 > had_decoding_error) { had_decoding_error++; }
+ } break;
+ case DK4_E_ENCODING_FAILED: {
+ switch (had_encoding_error) {
+ case 0: case 1: {
+ report_with_position(
+ ((0 == had_encoding_error) ? 3 : 4), 12,
+ er_en->dt.fpos.byteno,
+ er_en->dt.fpos.lineno,
+ er_en->dt.fpos.charno,
+ er_en->dt.fpos.charinline
+ );
+ } break;
+ case 2: {
+ } break;
+ }
+ if (3 > had_encoding_error) { had_encoding_error++; }
+ } break;
+ }
+ }
+ if (NULL != er_pr) {
+ if (DK4_E_NONE != er_pr->ec) {
+ switch (had_processing_error) {
+ case 0: case 1: {
+ report_with_position(
+ ((0 == had_processing_error) ? 6 : 7), 13,
+ er_en->dt.fpos.byteno,
+ er_en->dt.fpos.lineno,
+ er_en->dt.fpos.charno,
+ er_en->dt.fpos.charinline
+ );
+ } break;
+ case 2: {
+ } break;
+ }
+ if (3 > had_processing_error) { had_processing_error++; }
+ }
+ }
+}
+
+
+
+/** Process one input file.
+ @param fipo File to process.
+*/
+static
+void
+process_one_file(FILE *fipo)
+{
+ dk4_tsp32_t tsp32;
+ dk4_tspdk_t tspdk;
+ dk4_er_t er;
+ dk4_er_t er_en;
+ dk4_er_t er_pr;
+#if VERSION_1
+ size_t sz;
+#endif
+ int res;
+ int cc;
+ int c;
+ unsigned char ub;
+
+
+
+#line 1696 "dk-cat.ctr"
+ cc = 1;
+ initialize_for_one_file();
+ dk4error_init(&er);
+ if (0 != use_stream) {
+
+#line 1700 "dk-cat.ctr"
+ res = dk4tsp32_setup_char(
+ &tsp32, NULL, c32_handler, ienc_def, &er
+ );
+ if (0 != res) {
+
+#line 1704 "dk-cat.ctr"
+ do {
+ if (0 != sig_can_continue(0)) {
+ c = fgetc(fipo);
+ if (EOF != c) {
+ ub = (unsigned char)c;
+ switch (dk4tsp32_add_one_byte(&tsp32, ub)) {
+ case DK4_TSP_RES_ERROR: {
+ exval = EXIT_FAILURE;
+ dk4tsp32_get_errors(&er_en, &er_pr, &tsp32);
+ report_errors(&er_en, &er_pr);
+ } break;
+ case DK4_TSP_RES_FATAL: {
+ cc = -1;
+ exval = EXIT_FAILURE;
+ dk4tsp32_get_errors(&er_en, &er_pr, &tsp32);
+ report_errors(&er_en, &er_pr);
+ } break;
+ default: {
+ } break;
+ }
+ } else {
+ cc = 0;
+ }
+ if (0 != feof(fipo)) { if (1 == cc) { cc = 0; } }
+ } else {
+ cc = -1;
+ }
+ } while (1 == cc);
+ if (0 == cc) {
+
+#line 1733 "dk-cat.ctr"
+ res = dk4tsp32_finish(&tsp32);
+ switch (res) {
+ case DK4_TSP_RES_ERROR: {
+
+#line 1736 "dk-cat.ctr"
+ exval = EXIT_FAILURE;
+ dk4tsp32_get_errors(&er_en, &er_pr, &tsp32);
+ report_errors(&er_en, &er_pr);
+ } break;
+ case DK4_TSP_RES_FATAL: {
+
+#line 1741 "dk-cat.ctr"
+ exval = EXIT_FAILURE;
+ dk4tsp32_get_errors(&er_en, &er_pr, &tsp32);
+ report_errors(&er_en, &er_pr);
+ } break;
+ }
+ }
+ if (0 != sig_can_continue(0)) {
+ if ((0 != there_was_text) && (0 == previous_was_nl)) {
+ res = c32_real_output(NULL, dkC32(0x0A), NULL, NULL);
+ switch (res) {
+ case DK4_TSP_RES_ERROR: {
+
+#line 1752 "dk-cat.ctr"
+ exval = EXIT_FAILURE;
+ } break;
+ case DK4_TSP_RES_FATAL: {
+
+#line 1755 "dk-cat.ctr"
+ exval = EXIT_FAILURE;
+ } break;
+ }
+ }
+ }
+ } else {
+
+#line 1761 "dk-cat.ctr"
+ /* BUG, Should not happen */
+ exval = EXIT_FAILURE;
+ }
+ } else {
+
+#line 1765 "dk-cat.ctr"
+ res = dk4tspdk_setup_char(
+ &tspdk, NULL, dkc_handler, oenc_sys, ienc_def, &er
+ );
+ if (0 != res) {
+ if (0 != dk4app_opt_is_set_short(app, dkT('p'), NULL)) {
+
+
+#line 1771 "dk-cat.ctr"
+ dk4tspdk_enable_utf8_pass_through(&tspdk, 1);
+ }
+ do {
+ c = fgetc(fipo);
+ if (EOF != c) {
+ ub = (unsigned char)c;
+ switch (dk4tspdk_add_one_byte(&tspdk, ub)) {
+ case DK4_TSP_RES_FATAL: {
+ cc = -1;
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tspdk);
+ report_errors(&er_en, &er_pr);
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tspdk);
+ report_errors(&er_en, &er_pr);
+ } break;
+ default: {
+ } break;
+ }
+ } else {
+ cc = 0;
+ }
+ if (0 != feof(fipo)) { if (1 == cc) { cc = 0; } }
+ } while (1 == cc);
+ if (0 == cc) {
+ res = dk4tspdk_finish(&tspdk);
+ switch (res) {
+ case DK4_TSP_RES_ERROR: {
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tspdk);
+ report_errors(&er_en, &er_pr);
+ } break;
+ case DK4_TSP_RES_FATAL: {
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tspdk);
+ report_errors(&er_en, &er_pr);
+ } break;
+ }
+ }
+ if ((0 != there_was_text) && (0 == previous_was_nl)) {
+ res = dkc_real_output(NULL, dkT('\n'), NULL, NULL);
+ switch (res) {
+ case DK4_TSP_RES_ERROR: {
+ exval = EXIT_FAILURE;
+ } break;
+ case DK4_TSP_RES_FATAL: {
+ exval = EXIT_FAILURE;
+ } break;
+ }
+ }
+ }
+ }
+
+
+#line 1826 "dk-cat.ctr"
+}
+
+
+
+/** Process one input file specified by name.
+ @param filename Name of input file to process.
+*/
+static
+void
+process_one_file_name(const dkChar *filename)
+{
+ dk4_er_t er;
+ FILE *fipo = NULL;
+ const dkChar *oldsourcefile;
+ dk4_um_t oldsourceline;
+ int tests = DK4_FOPEN_SC_USER;
+
+
+#line 1843 "dk-cat.ctr"
+ dk4error_init(&er);
+ oldsourcefile = dk4app_get_log_source_file(app);
+ oldsourceline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_file(app, filename);
+ dk4app_set_log_source_line(app, (dk4_um_t)0UL);
+#if 0
+ /* File is opened for reading only.
+ */
+ if (1 == dk4isadmin()) { tests = DK4_FOPEN_SC_PRIVILEGED; }
+#endif
+ if (0 != sig_can_continue(1)) {
+ fipo = dk4fopen_app(filename, dkT("rb"), tests, app);
+ if (NULL != fipo) {
+ input_file_name = filename;
+ process_one_file(fipo);
+ fclose(fipo);
+ } else {
+ /* ERROR: Failed to open file (already reported) */
+ exval = EXIT_FAILURE;
+ }
+ }
+ dk4app_set_log_source_file(app, oldsourcefile);
+ dk4app_set_log_source_line(app, oldsourceline);
+
+
+#line 1867 "dk-cat.ctr"
+}
+
+
+
+#if DK4_ON_WINDOWS
+
+static
+void
+expand_and_process(const dkChar *pattern)
+{
+ dkChar buf[DK4_MAX_PATH];
+ dk4_dir_t *fne;
+ const dkChar *shf; /* Short file name */
+ const dkChar *pth; /* Path */
+ int any_file_found = 0; /* Flag: Any file found */
+ int can_continue;
+
+ fne = dk4app_fne_open(pattern, app);
+ if (NULL != fne) {
+ can_continue = 1;
+ while ((0 != can_continue) && (NULL != (shf = dk4dir_next_file(fne)))) {
+ any_file_found = 1;
+ pth = dk4dir_get_path(fne);
+ if (NULL != pth) {
+ if (0 != dk4str_cpy_s(buf, DK4_SIZEOF(buf,dkChar), pth, NULL)) {
+ if(0 != dk4str_cat_s(buf,DK4_SIZEOF(buf,dkChar),dk_cat_kwnl[5],NULL))
+ {
+ if(0 != dk4str_cat_s(buf, DK4_SIZEOF(buf,dkChar), shf, NULL)) {
+ process_one_file_name(buf);
+ } else {
+ exval = EXIT_FAILURE;
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 105, pattern);
+ }
+ }
+ else
+ {
+ exval = EXIT_FAILURE;
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 105, pattern);
+ }
+ } else {
+ exval = EXIT_FAILURE;
+ /* ERROR: Path too long! */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 105, pattern);
+ }
+ } else {
+ process_one_file_name(shf);
+ }
+ can_continue = sig_can_continue(1);
+ }
+ dk4dir_close(fne);
+ if (0 == any_file_found) {
+ /* ERROR: No such file */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 107, pattern);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Failed to open file name expander (already reported) */
+ exval = EXIT_FAILURE;
+ }
+}
+
+#endif
+
+
+
+/** Process all input files specified on command line or standard
+ input if no file name is found.
+*/
+static
+void
+process_files(void)
+{
+ int argc;
+ int i;
+ const dkChar *fn;
+#if DK4_ON_WINDOWS
+ int oldmode;
+#endif
+
+
+#line 1948 "dk-cat.ctr"
+ argc = dk4app_get_argc(app);
+ if (0 < argc) {
+
+#line 1950 "dk-cat.ctr"
+ for (i = 0; ((i < argc) && (0 != sig_can_continue(1))); i++) {
+ fn = dk4app_get_argv(app, i);
+ if (NULL != fn) {
+#if DK4_ON_WINDOWS
+ if (0 != dk4path_must_expand(fn)) {
+ expand_and_process(fn);
+ } else {
+#endif
+ process_one_file_name(fn);
+#if DK4_ON_WINDOWS
+ }
+#endif
+ }
+ }
+ } else {
+
+#line 1965 "dk-cat.ctr"
+#if DK4_ON_WINDOWS
+
+
+#line 1967 "dk-cat.ctr"
+ oldmode = _setmode(_fileno(stdin), _O_BINARY);
+#endif
+ input_file_name = dk_cat_kwnl[4];
+ process_one_file(stdin);
+#if DK4_ON_WINDOWS
+
+
+#line 1973 "dk-cat.ctr"
+ _setmode(_fileno(stdin), oldmode);
+#endif
+ }
+
+
+#line 1977 "dk-cat.ctr"
+}
+
+
+
+static
+void
+run_the_functions(void)
+{
+ process_files();
+ fflush(stdout);
+ cleanup_output();
+}
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+run_with_signals(void)
+{
+#ifdef SIGPIPE
+ struct sigaction opipe;
+#endif
+ struct sigaction oint;
+ struct sigaction oterm;
+#ifdef SIGPIPE
+ struct sigaction npipe;
+#endif
+ struct sigaction nint;
+ struct sigaction nterm;
+ int success = 0;
+
+#ifdef SIGPIPE
+ /* Set up signal handling for SIGPIPE.
+ */
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 22);
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 22);
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 22);
+ goto finished;
+ }
+#endif
+
+ /* Set up signal handling for SIGINT.
+ */
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 22);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 22);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 22);
+ goto restore_old_pipe;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 22);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 22);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 22);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ run_the_functions();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 23);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 23);
+ success = 0;
+ }
+
+#ifdef SIGPIPE
+ /* Restore signal handling for SIGPIPE.
+ */
+ restore_old_pipe:
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 23);
+ success = 0;
+ }
+#endif
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+run_with_signals(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ run_the_functions();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+#ifdef SIGPIPE
+ sigset(SIGPIPE, oldpipe);
+#endif
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+run_with_signals(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+#ifdef SIGPIPE
+ oldpipe = signal(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ run_the_functions();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+#ifdef SIGPIPE
+ signal(SIGPIPE, oldpipe);
+#endif
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+run_with_signals(void)
+{
+ run_the_functions();
+}
+#endif
+#endif
+#endif
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ dk4_sig_atomic_t shp;
+
+
+#line 2191 "dk-cat.ctr"
+
+
+#line 2192 "dk-cat.ctr"
+ app = dk4app_open_cmd(
+ argc, argv, dk_cat_options, dk_cat_sz_options,
+ dk_cat_kwnl[0], DKT_VERSION_DK,
+ dk_cat_kwnl[1], dk_cat_help_text, dk_cat_license_text
+ );
+ if (NULL != app) {
+ sz_msg = dk4app_string_table_size(dk_cat_kw_def);
+ msg = dk4app_string_table(app, dk_cat_kwnl[2], dk_cat_kw_def);
+ if (0 != dk4app_can_run_normally(app)) {
+ if (0 != initialize_from_app()) {
+ decide_for_output_type();
+ exval = EXIT_SUCCESS;
+ run_with_signals();
+#ifdef SIGPIPE
+ shp = sig_read_atomic(&sig_had_pipe);
+#else
+ shp = 0;
+#endif
+ if (0 != shp) {
+ if (0 != verbose) {
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 24);
+ }
+ exval = EXIT_FAILURE;
+ } else {
+ if (0 != had_write_error) {
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 20);
+ exval = EXIT_FAILURE;
+ }
+ }
+ if (0 != sig_read_atomic(&sig_had_int)) {
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 25);
+ }
+ }
+ } else {
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ dk4app_close(app);
+ }
+
+
+#line 2233 "dk-cat.ctr"
+
+
+#line 2234 "dk-cat.ctr"
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/dk-cat.ctr b/support/dktools/dk-cat.ctr
new file mode 100644
index 0000000000..11b0eca270
--- /dev/null
+++ b/support/dktools/dk-cat.ctr
@@ -0,0 +1,2236 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+/** @file dk-cat.c The dk-cat program.
+ The dk_cat_help_text array below shows details.
+*/
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4vers.h"
+#include "dk4app.h"
+#include "dk4aopt.h"
+#include "dk4enc.h"
+#include "dk4mem.h"
+#include "dk4strm.h"
+#include "dk4strmf.h"
+#include "dk4strmo32.h"
+#include "dk4istty.h"
+#include "dk4fopda.h"
+#include "dk4tsp32.h"
+#include "dk4tspdk.h"
+#include "dk4mao8d.h"
+#include "dk4str8.h"
+#include "dk4strd.h"
+#include "dk4pathd.h"
+#include "dk4fput.h"
+#include "dk4maodd.h"
+#include "dk4mpl.h"
+#include "dk4isadm.h"
+
+
+
+$!trace-include
+
+
+
+#ifndef DK_CAT_INPUT_BUFFER_SIZE
+/** Input buffer size.
+*/
+#define DK_CAT_INPUT_BUFFER_SIZE 4096
+#endif
+
+
+
+/** Default text, used if help text file is not found.
+*/
+static const dkChar * const dk_cat_help_text[] = {
+$!text macro=dkT,preprocessor
+
+Show text files
+
+dk-cat [<options>] [<files>]
+
+Options:
+-c <bool> Enable CR/NL -n Write line numbers
+-i <encoding> Expected input encoding -w Normalize text lines
+-o <encoding> Output encoding -p No unneccessary decoding/encoding
+--help Show this short help text. --manual *** SHOW FULL MANUAL. ***
+--version Show version information. --license Show license information.
+--verbose Error message on SIGPIPE
+--line-number-width=<int> Minimum line number width.
+
+Encoding names: plain (ASCII text), ascii (synonym for plain), ansi, utf-8,
+utf-16, utf-16le (little-endian) utf-16be (big-endian),
+c32 (32 bit characters), c32le, c32be.
+
+http://dktools.sourceforge.net
+
+$!end
+};
+
+
+
+/** License conditions.
+*/
+static const dkChar * const dk_cat_license_text[] = {
+$!text macro=dkT,preprocessor
+
+This software uses code from the following projects, either directly or as
+a library:
+
+dktools Dirk Krause's tools and libraries.
+ See http://dktools.sourceforge.net/ for more information.
+#if DK4_HAVE_ZLIB_H
+
+zlib Data compression library.
+ See http://www.zlib.net/ for more information.
+#endif
+#if DK4_HAVE_BZLIB_H
+
+bzip2 Data compression program and library.
+ See http://www.bzip.org/ for more information.
+#endif
+
+All the licenses below apply to the program.
+Licenses for used libraries are shown as found on my Scientific Linux 6.x
+computer in the /usr/share/doc directory on 2015-04-01. Check the project
+homepages of the used libraries for additional information and/or updated
+license terms.
+
+
+DK tools and libraries license
+==============================
+Copyright (c) 2015-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#if DK4_HAVE_ZLIB_H
+
+
+Zlib license
+============
+(C) 1995-2004 Jean-loup Gailly and Mark Adler
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+
+Jean-loup Gailly Mark Adler
+jloup@gzip.org madler@alumni.caltech.edu
+#endif
+#if DK4_HAVE_BZLIB_H
+
+
+Bzip2 and libbzip2 library license
+==================================
+This program, "bzip2", the associated library "libbzip2", and all
+documentation, are copyright (C) 1996-2007 Julian R Seward. All
+rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+3. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Julian Seward, jseward@bzip.org
+bzip2/libbzip2 version 1.0.5 of 10 December 2007
+#endif
+
+$!end
+};
+
+
+
+/** Constant texts used by program, not localized.
+*/
+static const dkChar * const dk_cat_kwnl[] = {
+$!string-table macro=dkT
+#
+# 0 Program group name
+#
+dktools
+#
+# 1 Help text file name
+#
+dk-cat.txt
+#
+# 2 String table file
+#
+dk-cat.str
+#
+# 3 Long option line-number-width
+#
+line-number-width
+#
+# 4 Default file name "stdin"
+#
+stdin
+#
+# 5 Windows path name separator
+#
+\\
+#
+# 6 Long option name for verbose mode
+#
+verbose
+$!end
+};
+
+
+
+/** Constant texts used by program, replaced by localized texts
+ if available.
+*/
+static const dkChar * const dk_cat_kw_def[] = {
+$!string-table macro=dkT
+#
+# 0 1 2 Decoding error
+#
+Decoding error!\n\tByte:
+Another decoding error!
+Further decoding errors!
+#
+# 3 4 5 Encoding error
+#
+Encoding error!\n\tByte:
+Another encoding error!
+Further encoding errors!
+#
+# 6 7 8 Processing error
+#
+Processing error!\n\tByte:
+Another processing error!
+Further processing errors!
+#
+# 9 10 Position in line
+#
+,\n\tCharacter:
+,\n\tPosition in line:
+#
+# 11 12 13 Default messages
+#
+Decoding error!
+Encoding error!
+Processing error!
+#
+# 14 End of message.
+#
+.
+#
+# 15 16 17 18 Error messages for illegal encodings
+#
+Illegal input encoding: "
+"!
+Illegal output encoding: "
+"!
+#
+# 19
+#
+Line number width must be larger than 0!
+#
+# 20
+#
+Failed to write text to output!
+#
+# 21
+#
+Numeric conversion failed (should not happen, probably bug in program)!
+#
+# 22
+#
+Failed to set up signal handlers!
+#
+# 23
+#
+Failed to restore signal handlers!
+#
+# 24
+#
+Signal received: SIGPIPE!
+#
+# 25
+#
+Signal received: SIGINT!
+$!end
+};
+
+
+
+/** Message texts, uses localized texts if possible.
+*/
+static const dkChar * const *msg = dk_cat_kw_def;
+
+
+
+/** Options used by program.
+*/
+static const dk4_option_specification_t dk_cat_options[] = {
+
+ /* Flag: Line end consists of carriage return and newline.
+ */
+ { dkT('c'), dkT("crnl"), DK4_OPT_ARG_BOOL },
+
+ /* Show line numbers.
+ */
+ { dkT('n'), dkT("line-numbers"), DK4_OPT_ARG_NONE },
+
+ /* Number of digits for line numbers.
+ */
+ { dkT('\0'), dkT("line-number-width"), DK4_OPT_ARG_SIZE },
+
+ /* Flag: Normalize text lines.
+ */
+ { dkT('w'), dkT("normalize"), DK4_OPT_ARG_NONE },
+
+ /* Expected input encoding.
+ */
+ { dkT('i'), dkT("input-encoding"), DK4_OPT_ARG_STRING },
+
+ /* Output encoding to produce.
+ */
+ { dkT('o'), dkT("output-encoding"), DK4_OPT_ARG_STRING },
+
+ /* Pass-through UTF-8 data.
+ */
+ { dkT('p'), dkT("pass-through"), DK4_OPT_ARG_NONE },
+
+ /* Verbose output.
+ */
+ { dkT('\0'), dkT("verbose"), DK4_OPT_ARG_NONE }
+
+};
+
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+/** Check whether we can continue or if a signal was received.
+ @param check_pipe Flag: Check for occured SIGPIPE signal too.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(int check_pipe)
+{
+ int back = 1;
+#ifdef SIGPIPE
+ if (0 != check_pipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_int )) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Number of elements in the dk_cat_options array.
+*/
+static const size_t dk_cat_sz_options =
+sizeof(dk_cat_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Number of usable elements in the dk_cat_kw_def array and in msg.
+*/
+static size_t sz_msg = (sizeof(dk_cat_kw_def)/sizeof(DK4_PDKCHAR) - 1);
+
+
+/** Name of current input file processed.
+*/
+static const dkChar *input_file_name = NULL;
+
+
+/** Flag: Output already initialized.
+*/
+static int output_initialized = 0;
+
+
+#if DK4_ON_WINDOWS
+/** Original mode for stdout.
+*/
+static int old_output_mode = 0;
+#endif
+
+
+/** Flag: Use stream instead output to stdout.
+*/
+static int use_stream = 1;
+
+
+/** System output encoding.
+*/
+static int oenc_sys = DK4_FILE_ENCODING_ASCII;
+
+
+/** Default output encoding on the system.
+*/
+static int oenc_def = DK4_FILE_ENCODING_ASCII;
+
+
+
+/** Output encoding specified on command line.
+*/
+static int oenc = DK4_FILE_ENCODING_ASCII;
+
+
+/** System setting whether or not to write a BOM.
+*/
+static int obom_sys = 0;
+
+
+/** Flag: Write BOM. -1=auto, 0=no, 1=yes.
+*/
+static int obom = -1;
+
+
+/** Default CR/NL sequence setting.
+*/
+static int crnl_def = DK4_HAVE_LINE_END_CR_NL;
+
+
+/** CR/NL sequence setting from options if available.
+*/
+static int crnl = DK4_HAVE_LINE_END_CR_NL;
+
+
+/** Input encoding specified on the command line.
+*/
+static int ienc_def = DK4_FILE_ENCODING_ASCII;
+
+
+/** Flag: Show line numbers (from options).
+*/
+static int line_numbers = 0;
+
+
+/** Current line number.
+*/
+static dk4_um_t line_number = (dk4_um_t)1UL;
+
+
+/** Flag: Previous character was carriage return.
+*/
+static int previous_was_cr = 0;
+
+
+/** Flag: Previous character was not a whitespace.
+*/
+static int previous_was_text = 0;
+
+
+/** Flag: Previous character was a newline.
+*/
+static int previous_was_nl = 0;
+
+
+/** Flag: We already had text in this line.
+*/
+static int text_in_line = 0;
+
+
+/** Flag: We had any output for this file.
+*/
+static int there_was_text = 0;
+
+
+/** Flag: Line number was already printed for current line.
+*/
+static int line_number_printed = 0;
+
+
+/** Line number width.
+*/
+static size_t line_number_width = 5;
+
+
+/** Flag: Normalize lines.
+*/
+static int normalize_lines = 0;
+
+
+/** Exit status code.
+*/
+static int exval = EXIT_FAILURE;
+
+
+/** Flag: Already reported encoding errors for this file.
+*/
+static int had_encoding_error = 0;
+
+/** Flag: Already reported decoding errors for this file.
+*/
+static int had_decoding_error = 0;
+
+/** Flag: Already reported processing errors for this file.
+*/
+static int had_processing_error = 0;
+
+/** Flag: Had error while writing to stdout.
+*/
+static int had_write_error = 0;
+
+/** Flag: Verbose output (report SIGPIPE).
+*/
+static int verbose = 0;
+
+
+/** Output stream.
+*/
+static dk4_stream_t *output_stream = NULL;
+
+
+
+/*
+ We can output to stdout using dk4fputc() if all the conditions
+ below are true:
+ - output encoding is system output encoding and
+ - CR/NL setting is system CR/NL setting and
+ - BOM settings is ``automatic'' or is system BOM setting.
+
+ Otherwise we set stdout in binary mode (on Windows only)
+ and use a dk4_stream_t to process 32 bit characters.
+*/
+
+/** Initialize settings from application.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+initialize_from_app(void)
+{
+ dkChar buf[32];
+ int res = 0; /* Operation result */
+ int back = 1;
+ $? "+ initialize_from_app"
+
+ /* String tables and defaults.
+ */
+ $? ". get string tables"
+ oenc_sys = dk4app_get_stdout_encoding(app);
+ oenc_def = oenc_sys;
+ ienc_def = dk4app_get_stdin_encoding(app);
+ $? ". stdin encoding %d", ienc_def
+ if (0 < dk4app_get_argc(app)) {
+ ienc_def = dk4app_get_file_in_encoding(app);
+ $? ". file in encoding %d", ienc_def
+ }
+
+ /* Set verbose flag if -v was used.
+ */
+ if (0 != dk4app_opt_is_set_long(app, dk_cat_kwnl[6], NULL)) {
+ verbose = 1;
+ }
+
+ /* Output encoding to produce (-o)
+ */
+ $? ". check for output encoding"
+ if (0 != dk4app_opt_is_set_short(app, dkT('o'), NULL)) { $? ". -o found"
+ res = dk4app_opt_get_string_short(
+ buf, DK4_SIZEOF(buf,dkChar), app, dkT('o'), NULL
+ );
+ if (0 != res) { $? ". arg found"
+ res = dk4enc_find(&oenc_def, &obom, buf, NULL);
+ if (0 == res) { $? "! encoding"
+ /* ERROR: Illegal output encoding */
+ dk4app_log_3(app, msg, sz_msg, DK4_LL_ERROR, 17, 18, buf);
+ back = 0;
+ }
+ } else { $? "! arg"
+ /* ERROR: BUG, No option argument */
+ back = 0;
+ }
+ }
+
+ /* Expected input encoding (-i)
+ */
+ $? ". check for input encoding"
+ if (0 != dk4app_opt_is_set_short(app, dkT('i'), NULL)) { $? ". -i found"
+ res = dk4app_opt_get_string_short(
+ buf, DK4_SIZEOF(buf,dkChar), app, dkT('i'), NULL
+ );
+ if (0 != res) { $? ". -i arg ok"
+ res = dk4enc_find(&ienc_def, NULL, buf, NULL);
+ if (0 == res) { $? "! encoding"
+ /* ERROR: Illegal input encoding */
+ dk4app_log_3(app, msg, sz_msg, DK4_LL_ERROR, 15, 16, buf);
+ back = 0;
+ }
+ } else { $? "! -i arg"
+ /* ERROR: BUG, No option argument */
+ back = 0;
+ }
+ }
+
+ /* CR/NL (-c)
+ */
+ $? ". check for CR/NL setup"
+ if (0 != dk4app_opt_is_set_short(app, dkT('c'), NULL)) { $? ". -c found"
+ if (0 == dk4app_opt_get_bool_short(&crnl, app, dkT('c'), NULL)) {
+ /* ERROR: BUG, No option argument */
+ back = 0; $? "! -c arg"
+ }
+ }
+
+ /* Line numbers (-n)
+ */
+ $? ". check for line number setting"
+ if (0 != dk4app_opt_is_set_short(app, dkT('n'), NULL)) { $? ". -l found"
+ line_numbers = 1;
+ }
+
+ /* Line number width (--line-number-width)
+ */
+ $? ". check for line number width"
+ if (0 != dk4app_opt_is_set_long(app, dk_cat_kwnl[3], NULL)) { $? ". --lnw"
+ if (0 == dk4app_opt_get_size_long(&line_number_width, app, dk_cat_kwnl[3], NULL)) {
+ /* ERROR: BUG, No option argument */
+ back = 0; $? "! --lnw arg"
+ } else {
+ if (0 == line_number_width) { $? "! lnw"
+ /* ERROR: Illegal line number width */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 19);
+ back = 0;
+ }
+ }
+ }
+
+ /* Normalize text (-w)
+ */
+ $? ". check for normalize text"
+ if (0 != dk4app_opt_is_set_short(app, dkT('w'), NULL)) { $? ". -w found"
+ normalize_lines = 1;
+ }
+
+ $? ". check for bom writing"
+ switch (oenc_sys) {
+ case DK4_FILE_ENCODING_ASCII :
+ case DK4_FILE_ENCODING_ANSI :
+ case DK4_FILE_ENCODING_UTF8 :
+ {
+ obom_sys = 0;
+ } break;
+ default :
+ {
+ if (0 == dk4istty(1, NULL)) {
+ obom_sys = 1;
+ }
+ } break;
+ }
+ oenc = oenc_def;
+
+ $? "- initialize_from_app %d", back
+ return back;
+}
+
+
+
+/** Check whether we can write to standard output directly.
+*/
+static
+void
+decide_for_output_type(void)
+{
+ if (oenc_def == oenc_sys) {
+ if (crnl == crnl_def) {
+ if ((-1 == obom) || (obom_sys == obom)) {
+ use_stream = 0;
+ }
+ }
+ }
+}
+
+
+
+/** Initialize output structures before writing first output.
+*/
+static
+void
+initialize_output(void)
+{
+ dk4_er_t er;
+ $? "+ initialize_output"
+ if (0 == output_initialized) {
+ output_initialized = 1;
+ if (0 != use_stream) {
+ dk4error_init(&er);
+#if DK4_ON_WINDOWS
+ $? ". _setmode stdout _O_BINARY"
+ old_output_mode = _setmode(_fileno(stdout), _O_BINARY);
+#endif
+ output_stream = dk4stream_open_for_file(
+ stdout, DK4_STREAM_WRITE, 0, 4096, &er
+ );
+ if (NULL != output_stream) {
+ dk4stream_set_output_encoding(output_stream, oenc);
+ switch (obom) {
+ case 1: {
+ if(0 == dk4stream_c32_putc(output_stream, dkC32(0xFEFF), NULL)) {
+ /* ERROR: Failed to write BOM */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 20);
+ exval = EXIT_FAILURE;
+ }
+ } break;
+ case -1: {
+ if (1 == obom_sys) {
+ if(0 == dk4stream_c32_putc(output_stream,dkC32(0xFEFF),NULL)) {
+ /* ERROR: Failed to write BOM */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 20);
+ exval = EXIT_FAILURE;
+ }
+ }
+ } break;
+ }
+ } else {
+ /* ERROR: Failed to create stream */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ }
+ } else {
+ dk4fput_initialize_stdout();
+ }
+ } $? "- initialize_output"
+}
+
+
+
+/** Close stream, or set mode for stdout back to original mode.
+*/
+static
+void
+cleanup_output(void)
+{
+ dk4_er_t er;
+ $? "+ cleanup_output"
+ if (0 != output_initialized) {
+ if (0 != use_stream) {
+ if (NULL != output_stream) {
+ /* Close output stream.
+ */
+ dk4error_init(&er);
+ if (0 == dk4stream_close(output_stream, &er)) {
+ /* ERROR: Closing the stream failed */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 20);
+ exval = EXIT_FAILURE;
+ }
+ }
+#if DK4_ON_WINDOWS
+ /* Set stdout to original mode.
+ */
+ $? "_setmode stdout old_output_mode"
+ _setmode(_fileno(stdout), old_output_mode);
+#endif
+ } else {
+ dk4fput_cleanup_stdout();
+ }
+ } $? "- cleanup_output"
+}
+
+
+
+/** Report an error with position in source line.
+ @param i1 Index of first message part in array.
+ @param i2 Index of alternative first message part.
+ @param bno Byte processed.
+ @param lno Current line number.
+ @param cno Current character number.
+ @param cil Current character number in line.
+*/
+static
+void
+report_with_position(
+ size_t i1,
+ size_t i2,
+ dk4_um_t bno,
+ dk4_um_t lno,
+ dk4_um_t cno,
+ dk4_um_t cil
+)
+{
+ dkChar b1[8*(1+sizeof(dk4_um_t))];
+ dkChar b2[8*(1+sizeof(dk4_um_t))];
+ dkChar b3[8*(1+sizeof(dk4_um_t))];
+ const dkChar *oldlogname = NULL;
+ dk4_um_t oldlogline = (dk4_um_t)0UL;
+ int allbuffersok = 0;
+
+ oldlogname = dk4app_get_log_source_file(app);
+ oldlogline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_file(app, input_file_name);
+ dk4app_set_log_source_line(app, lno);
+ if (0 != dk4ma_write_decimal_unsigned(b3,DK4_SIZEOF(b3,dkChar),cil,0,NULL)) {
+ if (0 != dk4ma_write_decimal_unsigned(b2,DK4_SIZEOF(b2,dkChar),cno,0,NULL)) {
+ if (0 != dk4ma_write_decimal_unsigned(b1,DK4_SIZEOF(b1,dkChar),bno,0,NULL)) {
+ allbuffersok = 1;
+ }
+ }
+ }
+ if (0 != allbuffersok) {
+ dk4app_log_7(
+ app, msg, sz_msg, DK4_LL_ERROR, i1, 9, 10, 14, b1, b2, b3
+ );
+ } else {
+ dk4app_log_1(
+ app, msg, sz_msg, DK4_LL_ERROR, i2
+ );
+ }
+ dk4app_set_log_source_file(app, oldlogname);
+ dk4app_set_log_source_line(app, oldlogline);
+}
+
+
+
+/** Report an error occured while writing 32 bit character to
+ output stream.
+ @param erp Error information returned by dk4stream_c32_putc().
+ @param pos Position information.
+*/
+static
+void
+error_while_writing_c32(dk4_er_t *erp, dk4_text_stream_position_t *pos)
+{
+ dk4_um_t bytes = (dk4_um_t)0UL;
+ dk4_um_t lineno = (dk4_um_t)0UL;
+ dk4_um_t chars = (dk4_um_t)0UL;
+ dk4_um_t charil = (dk4_um_t)0UL;
+ switch (erp->ec) {
+ case DK4_E_ENCODING_FAILED : {
+ if (NULL != pos) {
+ bytes = pos->bytes;
+ lineno = pos->lineno;
+ chars = pos->chars;
+ charil = pos->charil;
+ }
+ if ((dk4_um_t)0UL < bytes) { bytes = bytes - (dk4_um_t)1UL; }
+ if ((dk4_um_t)0UL < chars) { chars = chars - (dk4_um_t)1UL; }
+ if ((dk4_um_t)0UL < charil) { charil = charil - (dk4_um_t)1UL; }
+ report_with_position(3, 12, bytes, lineno, chars, charil);
+ } break;
+ default: {
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 20);
+ } break;
+ }
+}
+
+
+
+/** Write one 32 bit character to output.
+ If the character is a newline, convert to carriage return and
+ newline sequence if required by crnl settings.
+ @param obj Object to modify while processing the character
+ (NULL here).
+ @param c Character to process.
+ @param pos Current position in file or data stream.
+ @param erp Error report, may be NULL.
+ @return Result code:
+ - DK4_TSP_RES_OK if the character was processed successfully,
+ - DK4_TSP_RES_ERROR if there was an error but we can continue,
+ - DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+c32_real_output(
+ void *obj,
+ dk4_c32_t c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er;
+ int back = DK4_TSP_RES_OK;
+ dk4_sig_atomic_t shp;
+
+ $? "+ c32_real_output"
+ initialize_output();
+ if (0 != use_stream) {
+ if (NULL != output_stream) {
+ dk4error_init(&er);
+#ifdef SIGPIPE
+ shp = sig_read_atomic(&sig_had_pipe);
+#else
+ shp = 0;
+#endif
+ if (0 == shp) {
+ if ((dkC32(0x0A) == c) && (0 != crnl)) {
+ if (0 == dk4stream_c32_putc(output_stream, dkC32(0x0D), &er)) {
+ /* ERROR: Failed to write output character */
+ error_while_writing_c32(&er, pos);
+ back = DK4_TSP_RES_FATAL;
+ }
+ }
+ if (0 == dk4stream_c32_putc(output_stream, c, &er)) {
+ /* ERROR: Failed to write output character */
+ error_while_writing_c32(&er, pos);
+ back = DK4_TSP_RES_FATAL;
+ }
+ }
+ } else {
+ /* ERROR: Failed to create output stream (already reported) */
+ back = DK4_TSP_RES_FATAL;
+ }
+ } else {
+ }
+ if (dkC32(0x0A) == c) {
+ previous_was_nl = 1;
+ } else {
+ previous_was_nl = 0;
+ }
+ there_was_text = 1;
+ $? "- c32_real_output %d", back
+ return back;
+}
+
+
+
+/** Check whether a character is the first character in a line,
+ write line number if necessary and write the character.
+ @param obj Object to modify while processing the character
+ (NULL here).
+ @param c Character to process.
+ @param pos Current position in file or data stream.
+ @param erp Error report, may be NULL.
+ @return Result code:
+ - DK4_TSP_RES_OK if the character was processed successfully,
+ - DK4_TSP_RES_ERROR if there was an error but we can continue,
+ - DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+c32_after_normalize(
+ void *obj,
+ dk4_c32_t c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+)
+{
+ char buf[8*(1+sizeof(dk4_um_t))];
+ char *ptr = NULL;
+ size_t i = 0;
+ int res = 0;
+ int back = DK4_TSP_RES_OK;
+ $? "+ c32_after_normalize"
+ if (0 != line_numbers) {
+ if (0 == line_number_printed) {
+ line_number_printed = 1;
+ res = dk4ma_write_c8_decimal_unsigned(
+ buf, sizeof(buf), line_number, 0, NULL
+ );
+ if (0 != res) {
+ /* Spaces before line number.
+ */
+ i = dk4str8_len(buf);
+ while (i < line_number_width) {
+ switch (c32_real_output(obj, dkC32(0x20), pos, erp)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ i++;
+ }
+ /* Line number
+ */
+ ptr = buf;
+ while ('\0' != *ptr) {
+ res = c32_real_output(
+ obj, (dk4_c32_t)((unsigned char)(*(ptr++))), pos, erp
+ );
+ switch (res) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ }
+ /* Trailing space after line number
+ */
+ switch (c32_real_output(obj, dkC32(0x20), pos, erp)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ } else {
+ /* ERROR: Failed to convert line number. */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 21);
+ back = DK4_TSP_RES_FATAL;
+ }
+ }
+ switch (c32_real_output(obj, c, pos, erp)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ } else {
+ back = c32_real_output(obj, c, pos, erp);
+ } $? "- c32_after_normalize %d", back
+ return back;
+}
+
+
+
+/** Normalize the text if required and pass characters downwards.
+ @param obj Object to modify while processing the character
+ (NULL here).
+ @param c Character to process.
+ @param pos Current position in file or data stream.
+ @param erp Error report, may be NULL.
+ @return Result code:
+ - DK4_TSP_RES_OK if the character was processed successfully,
+ - DK4_TSP_RES_ERROR if there was an error but we can continue,
+ - DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+c32_after_cr_nl(
+ void *obj,
+ dk4_c32_t c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_TSP_RES_OK;
+ $? "+ c32_after_cr_nl"
+ if (0 != normalize_lines) {
+ if ((dkC32(0x09) == c) || (dkC32(0x20) == c) || (dkC32(0x0D) == c)) {
+ previous_was_text = 0;
+ } else {
+ if (dkC32(0x0A) == c) {
+ previous_was_text = 0;
+ back = c32_after_normalize(obj, c, pos, erp);
+ text_in_line = 0;
+ } else {
+ if ((0 == previous_was_text) && (0 != text_in_line)) {
+ back = c32_after_normalize(obj, dkC32(0x20), pos, erp);
+ }
+ switch (c32_after_normalize(obj, c, pos, erp)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ previous_was_text = 1;
+ text_in_line = 1;
+ }
+ }
+ } else {
+ back = c32_after_normalize(obj, c, pos, erp);
+ } $? "- c32_after_cr_nl %d", back
+ return back;
+}
+
+
+
+/** Handler function for single characters.
+ @param obj Object to modify while processing the character.
+ @param c Character to process.
+ @param pos Current position in file or data stream.
+ @param erp Error report, may be NULL.
+ @return Result code:
+ - DK4_TSP_RES_OK if the character was processed successfully,
+ - DK4_TSP_RES_ERROR if there was an error but we can continue,
+ - DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+c32_handler(
+ void *obj,
+ dk4_c32_t c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_TSP_RES_OK;
+ $? "+ c32_handler"
+ dk4app_set_log_source_line(app, line_number);
+ if (dkC32(0x0D) == c) { $? ". carriage return"
+ if (0 != previous_was_cr) {
+ back = c32_after_cr_nl(obj, dkC32(0x0D), pos, erp);
+ }
+ previous_was_cr = 1;
+ } else {
+ if (dkC32(0x0A) == c) { $? ". newline"
+ back = c32_after_cr_nl(obj, c, pos, erp);
+ line_number++;
+ dk4app_set_log_source_line(app, line_number);
+ line_number_printed = 0;
+ text_in_line = 0;
+ } else { $? ". other character"
+ if (0 != previous_was_cr) {
+ back = c32_after_cr_nl(obj, dkC32(0x0D), pos, erp);
+ }
+ switch (c32_after_cr_nl(obj, c, pos, erp)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ }
+ previous_was_cr = 0;
+ } $? "- c32_handler %d", back
+ return back;
+}
+
+
+
+/** Write one dkChar to output (for a newline write a carriage
+ return, newline sequence if required).
+ @param obj Object to modify while processing the character
+ (NULL here).
+ @param c Character to process.
+ @param pos Current position in file or data stream.
+ @param erp Error report, may be NULL.
+ @return Result code:
+ - DK4_TSP_RES_OK if the character was processed successfully,
+ - DK4_TSP_RES_ERROR if there was an error but we can continue,
+ - DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+dkc_real_output(
+ void *obj,
+ dkChar c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er;
+ int back = DK4_TSP_RES_OK;
+ dk4_sig_atomic_t shp;
+ $? "+ dkc_real_output %lx", (unsigned long)c
+ initialize_output();
+ dk4error_init(&er);
+#ifdef SIGPIPE
+ shp = sig_read_atomic(&sig_had_pipe);
+#else
+ shp = 0;
+#endif
+ if (0 == shp) {
+ if (0 == dk4fputc(c, stdout, &er)) {
+ /* ERROR while writing to standard output */
+#if 0
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 20);
+#endif
+ had_write_error = 0;
+ back = DK4_TSP_RES_FATAL;
+ exval = EXIT_FAILURE;
+ }
+ }
+ if (dkT('\n') == c) {
+ previous_was_nl = 1;
+ } else {
+ previous_was_nl = 0;
+ }
+ there_was_text = 1;
+ $? "- dkc_real_output %d", back
+ return back;
+}
+
+
+
+/** Pass character downwards to dkc_real_output().
+ If the character is the first in the line, prepend line
+ number if required.
+ @param obj Object to modify while processing the character
+ (NULL here).
+ @param c Character to process.
+ @param pos Current position in file or data stream.
+ @param erp Error report, may be NULL.
+ @return Result code:
+ - DK4_TSP_RES_OK if the character was processed successfully,
+ - DK4_TSP_RES_ERROR if there was an error but we can continue,
+ - DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+dkc_after_normalize(
+ void *obj,
+ dkChar c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+)
+{
+ char buf[8*(1+sizeof(dk4_um_t))];
+ char *ptr = NULL;
+ size_t i = 0;
+ int res = 0;
+ int back = DK4_TSP_RES_OK;
+ $? "+ dkc_after_normalize %lx", (unsigned long)c
+ if (0 != line_numbers) {
+ if (0 == line_number_printed) {
+ line_number_printed = 1;
+ res = dk4ma_write_c8_decimal_unsigned(
+ buf, sizeof(buf), line_number, 0, NULL
+ );
+ if (0 != res) {
+ /* Spaces before line number.
+ */
+ i = dk4str8_len(buf);
+ while (i < line_number_width) {
+ switch (dkc_real_output(obj, dkT(' '), pos, erp)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ i++;
+ }
+ /* Line number
+ */
+ ptr = buf;
+ while ('\0' != *ptr) {
+ res = dkc_real_output(
+ obj, (dkChar)((unsigned char)(*(ptr++))), pos, erp
+ );
+ switch (res) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ }
+ /* Trailing space after line number
+ */
+ switch (dkc_real_output(obj, dkT(' '), pos, erp)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ } else {
+ /* ERROR: Failed to convert line number. */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 21);
+ back = DK4_TSP_RES_FATAL;
+ }
+ }
+ switch (dkc_real_output(obj, c, pos, erp)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ } else {
+ back = dkc_real_output(obj, c, pos, erp);
+ } $? "- dkc_after_normalize %d", back
+ return back;
+}
+
+
+
+/** Normalize text if required and pass characters downwards.
+ @param obj Object to modify while processing the character
+ (NULL here).
+ @param c Character to process.
+ @param pos Current position in file or data stream.
+ @param erp Error report, may be NULL.
+ @return Result code:
+ - DK4_TSP_RES_OK if the character was processed successfully,
+ - DK4_TSP_RES_ERROR if there was an error but we can continue,
+ - DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+dkc_after_cr_nl(
+ void *obj,
+ dkChar c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_TSP_RES_OK;
+ $? "+ dkc_after_cr_nl %lx", (unsigned long)c
+ if (0 != normalize_lines) {
+ if ((dkT('\t') == c) || (dkT(' ') == c) || (dkT('\r') == c)) {
+ previous_was_text = 0;
+ } else {
+ if (dkT('\n') == c) {
+ previous_was_text = 0;
+ back = dkc_after_normalize(obj, c, pos, erp);
+ text_in_line = 0;
+ } else {
+ if ((0 == previous_was_text) && (0 != text_in_line)) {
+ back = dkc_after_normalize(obj, dkT(' '), pos, erp);
+ }
+ switch (dkc_after_normalize(obj, c, pos, erp)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ previous_was_text = 1;
+ text_in_line = 1;
+ }
+ }
+ } else {
+ back = dkc_after_normalize(obj, c, pos, erp);
+ } $? "- dkc_after_cr_nl %d", back
+ return back;
+}
+
+
+
+/** Handler function for single characters.
+ @param obj Object to modify while processing the character
+ (NULL here).
+ @param c Character to process.
+ @param pos Current position in file or data stream.
+ @param erp Error report, may be NULL.
+ @return Result code:
+ - DK4_TSP_RES_OK if the character was processed successfully,
+ - DK4_TSP_RES_ERROR if there was an error but we can continue,
+ - DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+dkc_handler(
+ void *obj,
+ dkChar c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_TSP_RES_OK;
+ $? "+ dkc_handler %lx", (unsigned long)c
+ dk4app_set_log_source_line(app, line_number);
+ if (dkT('\r') == c) {
+ if (0 != previous_was_cr) {
+ back = dkc_after_cr_nl(obj, dkT('\r'), pos, erp);
+ }
+ previous_was_cr = 1;
+ } else {
+ if (dkT('\n') == c) {
+ back = dkc_after_cr_nl(obj, c, pos, erp);
+ line_number++;
+ dk4app_set_log_source_line(app, line_number);
+ line_number_printed = 0;
+ text_in_line = 0;
+ } else {
+ if (0 != previous_was_cr) {
+ back = dkc_after_cr_nl(obj, dkT('\r'), pos, erp);
+ }
+ switch (dkc_after_cr_nl(obj, c, pos, erp)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ }
+ previous_was_cr = 0;
+ }
+ $? "- dkc_handler %d", back
+ return back;
+}
+
+
+
+/** Initialize variables like line number and others for one file.
+*/
+static
+void
+initialize_for_one_file(void)
+{
+ $? "+ initialize_for_one_file"
+ line_number = (dk4_um_t)1UL;
+ previous_was_cr = 0;
+ previous_was_nl = 0;
+ previous_was_text = 0;
+ line_number_printed = 0;
+ there_was_text = 0;
+ had_encoding_error = 0;
+ had_decoding_error = 0;
+ had_processing_error = 0;
+ text_in_line = 0;
+ $? "- initialize_for_one_file"
+}
+
+
+
+/** Report errors indicated by text processing.
+ @param er_en Error report for decoding and encoding errors.
+ @param er_pr Error report for processing errors.
+*/
+static
+void
+report_errors(dk4_er_t *er_en, dk4_er_t *er_pr)
+{
+ if (NULL != er_en) {
+ switch (er_en->ec) {
+ case DK4_E_DECODING_FAILED: {
+ switch (had_decoding_error) {
+ case 0: case 1: {
+ report_with_position(
+ ((0 == had_decoding_error) ? 0 : 1), 11,
+ er_en->dt.fpos.byteno,
+ er_en->dt.fpos.lineno,
+ er_en->dt.fpos.charno,
+ er_en->dt.fpos.charinline
+ );
+ } break;
+ case 2: {
+ } break;
+ }
+ if (3 > had_decoding_error) { had_decoding_error++; }
+ } break;
+ case DK4_E_ENCODING_FAILED: {
+ switch (had_encoding_error) {
+ case 0: case 1: {
+ report_with_position(
+ ((0 == had_encoding_error) ? 3 : 4), 12,
+ er_en->dt.fpos.byteno,
+ er_en->dt.fpos.lineno,
+ er_en->dt.fpos.charno,
+ er_en->dt.fpos.charinline
+ );
+ } break;
+ case 2: {
+ } break;
+ }
+ if (3 > had_encoding_error) { had_encoding_error++; }
+ } break;
+ }
+ }
+ if (NULL != er_pr) {
+ if (DK4_E_NONE != er_pr->ec) {
+ switch (had_processing_error) {
+ case 0: case 1: {
+ report_with_position(
+ ((0 == had_processing_error) ? 6 : 7), 13,
+ er_en->dt.fpos.byteno,
+ er_en->dt.fpos.lineno,
+ er_en->dt.fpos.charno,
+ er_en->dt.fpos.charinline
+ );
+ } break;
+ case 2: {
+ } break;
+ }
+ if (3 > had_processing_error) { had_processing_error++; }
+ }
+ }
+}
+
+
+
+/** Process one input file.
+ @param fipo File to process.
+*/
+static
+void
+process_one_file(FILE *fipo)
+{
+ dk4_tsp32_t tsp32;
+ dk4_tspdk_t tspdk;
+ dk4_er_t er;
+ dk4_er_t er_en;
+ dk4_er_t er_pr;
+#if VERSION_1
+ size_t sz;
+#endif
+ int res;
+ int cc;
+ int c;
+ unsigned char ub;
+
+ $? "+ process_one_file"
+ cc = 1;
+ initialize_for_one_file();
+ dk4error_init(&er);
+ if (0 != use_stream) { $? ". stream"
+ res = dk4tsp32_setup_char(
+ &tsp32, NULL, c32_handler, ienc_def, &er
+ );
+ if (0 != res) { $? ". setup ok"
+ do {
+ if (0 != sig_can_continue(0)) {
+ c = fgetc(fipo);
+ if (EOF != c) {
+ ub = (unsigned char)c;
+ switch (dk4tsp32_add_one_byte(&tsp32, ub)) {
+ case DK4_TSP_RES_ERROR: {
+ exval = EXIT_FAILURE;
+ dk4tsp32_get_errors(&er_en, &er_pr, &tsp32);
+ report_errors(&er_en, &er_pr);
+ } break;
+ case DK4_TSP_RES_FATAL: {
+ cc = -1;
+ exval = EXIT_FAILURE;
+ dk4tsp32_get_errors(&er_en, &er_pr, &tsp32);
+ report_errors(&er_en, &er_pr);
+ } break;
+ default: {
+ } break;
+ }
+ } else {
+ cc = 0;
+ }
+ if (0 != feof(fipo)) { if (1 == cc) { cc = 0; } }
+ } else {
+ cc = -1;
+ }
+ } while (1 == cc);
+ if (0 == cc) { $? ". normal loop exit"
+ res = dk4tsp32_finish(&tsp32);
+ switch (res) {
+ case DK4_TSP_RES_ERROR: { $? "! tsp finish error"
+ exval = EXIT_FAILURE;
+ dk4tsp32_get_errors(&er_en, &er_pr, &tsp32);
+ report_errors(&er_en, &er_pr);
+ } break;
+ case DK4_TSP_RES_FATAL: { $? "! tsp finish fatal"
+ exval = EXIT_FAILURE;
+ dk4tsp32_get_errors(&er_en, &er_pr, &tsp32);
+ report_errors(&er_en, &er_pr);
+ } break;
+ }
+ }
+ if (0 != sig_can_continue(0)) {
+ if ((0 != there_was_text) && (0 == previous_was_nl)) {
+ res = c32_real_output(NULL, dkC32(0x0A), NULL, NULL);
+ switch (res) {
+ case DK4_TSP_RES_ERROR: { $? "! newline finalizer error"
+ exval = EXIT_FAILURE;
+ } break;
+ case DK4_TSP_RES_FATAL: { $? "! newline finalizer fatal"
+ exval = EXIT_FAILURE;
+ } break;
+ }
+ }
+ }
+ } else { $? "! setup failed (bug, should not happen)"
+ /* BUG, Should not happen */
+ exval = EXIT_FAILURE;
+ }
+ } else { $? ". stdout"
+ res = dk4tspdk_setup_char(
+ &tspdk, NULL, dkc_handler, oenc_sys, ienc_def, &er
+ );
+ if (0 != res) {
+ if (0 != dk4app_opt_is_set_short(app, dkT('p'), NULL)) {
+ $? ". pass through UTF-8 data"
+ dk4tspdk_enable_utf8_pass_through(&tspdk, 1);
+ }
+ do {
+ c = fgetc(fipo);
+ if (EOF != c) {
+ ub = (unsigned char)c;
+ switch (dk4tspdk_add_one_byte(&tspdk, ub)) {
+ case DK4_TSP_RES_FATAL: {
+ cc = -1;
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tspdk);
+ report_errors(&er_en, &er_pr);
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tspdk);
+ report_errors(&er_en, &er_pr);
+ } break;
+ default: {
+ } break;
+ }
+ } else {
+ cc = 0;
+ }
+ if (0 != feof(fipo)) { if (1 == cc) { cc = 0; } }
+ } while (1 == cc);
+ if (0 == cc) {
+ res = dk4tspdk_finish(&tspdk);
+ switch (res) {
+ case DK4_TSP_RES_ERROR: {
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tspdk);
+ report_errors(&er_en, &er_pr);
+ } break;
+ case DK4_TSP_RES_FATAL: {
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tspdk);
+ report_errors(&er_en, &er_pr);
+ } break;
+ }
+ }
+ if ((0 != there_was_text) && (0 == previous_was_nl)) {
+ res = dkc_real_output(NULL, dkT('\n'), NULL, NULL);
+ switch (res) {
+ case DK4_TSP_RES_ERROR: {
+ exval = EXIT_FAILURE;
+ } break;
+ case DK4_TSP_RES_FATAL: {
+ exval = EXIT_FAILURE;
+ } break;
+ }
+ }
+ }
+ }
+ $? "- process_one_file"
+}
+
+
+
+/** Process one input file specified by name.
+ @param filename Name of input file to process.
+*/
+static
+void
+process_one_file_name(const dkChar *filename)
+{
+ dk4_er_t er;
+ FILE *fipo = NULL;
+ const dkChar *oldsourcefile;
+ dk4_um_t oldsourceline;
+ int tests = DK4_FOPEN_SC_USER;
+ $? "+ process_one_file_name"
+ dk4error_init(&er);
+ oldsourcefile = dk4app_get_log_source_file(app);
+ oldsourceline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_file(app, filename);
+ dk4app_set_log_source_line(app, (dk4_um_t)0UL);
+#if 0
+ /* File is opened for reading only.
+ */
+ if (1 == dk4isadmin()) { tests = DK4_FOPEN_SC_PRIVILEGED; }
+#endif
+ if (0 != sig_can_continue(1)) {
+ fipo = dk4fopen_app(filename, dkT("rb"), tests, app);
+ if (NULL != fipo) {
+ input_file_name = filename;
+ process_one_file(fipo);
+ fclose(fipo);
+ } else {
+ /* ERROR: Failed to open file (already reported) */
+ exval = EXIT_FAILURE;
+ }
+ }
+ dk4app_set_log_source_file(app, oldsourcefile);
+ dk4app_set_log_source_line(app, oldsourceline);
+ $? "- process_one_file_name"
+}
+
+
+
+#if DK4_ON_WINDOWS
+
+static
+void
+expand_and_process(const dkChar *pattern)
+{
+ dkChar buf[DK4_MAX_PATH];
+ dk4_dir_t *fne;
+ const dkChar *shf; /* Short file name */
+ const dkChar *pth; /* Path */
+ int any_file_found = 0; /* Flag: Any file found */
+ int can_continue;
+
+ fne = dk4app_fne_open(pattern, app);
+ if (NULL != fne) {
+ can_continue = 1;
+ while ((0 != can_continue) && (NULL != (shf = dk4dir_next_file(fne)))) {
+ any_file_found = 1;
+ pth = dk4dir_get_path(fne);
+ if (NULL != pth) {
+ if (0 != dk4str_cpy_s(buf, DK4_SIZEOF(buf,dkChar), pth, NULL)) {
+ if(0 != dk4str_cat_s(buf,DK4_SIZEOF(buf,dkChar),dk_cat_kwnl[5],NULL))
+ {
+ if(0 != dk4str_cat_s(buf, DK4_SIZEOF(buf,dkChar), shf, NULL)) {
+ process_one_file_name(buf);
+ } else {
+ exval = EXIT_FAILURE;
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 105, pattern);
+ }
+ }
+ else
+ {
+ exval = EXIT_FAILURE;
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 105, pattern);
+ }
+ } else {
+ exval = EXIT_FAILURE;
+ /* ERROR: Path too long! */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 105, pattern);
+ }
+ } else {
+ process_one_file_name(shf);
+ }
+ can_continue = sig_can_continue(1);
+ }
+ dk4dir_close(fne);
+ if (0 == any_file_found) {
+ /* ERROR: No such file */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 107, pattern);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Failed to open file name expander (already reported) */
+ exval = EXIT_FAILURE;
+ }
+}
+
+#endif
+
+
+
+/** Process all input files specified on command line or standard
+ input if no file name is found.
+*/
+static
+void
+process_files(void)
+{
+ int argc;
+ int i;
+ const dkChar *fn;
+#if DK4_ON_WINDOWS
+ int oldmode;
+#endif
+ $? "+ process_files"
+ argc = dk4app_get_argc(app);
+ if (0 < argc) { $? ". have arguments"
+ for (i = 0; ((i < argc) && (0 != sig_can_continue(1))); i++) {
+ fn = dk4app_get_argv(app, i);
+ if (NULL != fn) {
+#if DK4_ON_WINDOWS
+ if (0 != dk4path_must_expand(fn)) {
+ expand_and_process(fn);
+ } else {
+#endif
+ process_one_file_name(fn);
+#if DK4_ON_WINDOWS
+ }
+#endif
+ }
+ }
+ } else { $? ". no arguments, process stdin"
+#if DK4_ON_WINDOWS
+ $? ". _setmode stdin _O_BINARY"
+ oldmode = _setmode(_fileno(stdin), _O_BINARY);
+#endif
+ input_file_name = dk_cat_kwnl[4];
+ process_one_file(stdin);
+#if DK4_ON_WINDOWS
+ $? ". _setmode stdin oldmode"
+ _setmode(_fileno(stdin), oldmode);
+#endif
+ }
+ $? "- process_files"
+}
+
+
+
+static
+void
+run_the_functions(void)
+{
+ process_files();
+ fflush(stdout);
+ cleanup_output();
+}
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+run_with_signals(void)
+{
+#ifdef SIGPIPE
+ struct sigaction opipe;
+#endif
+ struct sigaction oint;
+ struct sigaction oterm;
+#ifdef SIGPIPE
+ struct sigaction npipe;
+#endif
+ struct sigaction nint;
+ struct sigaction nterm;
+ int success = 0;
+
+#ifdef SIGPIPE
+ /* Set up signal handling for SIGPIPE.
+ */
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 22);
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 22);
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 22);
+ goto finished;
+ }
+#endif
+
+ /* Set up signal handling for SIGINT.
+ */
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 22);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 22);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 22);
+ goto restore_old_pipe;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 22);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 22);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 22);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ run_the_functions();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 23);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 23);
+ success = 0;
+ }
+
+#ifdef SIGPIPE
+ /* Restore signal handling for SIGPIPE.
+ */
+ restore_old_pipe:
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 23);
+ success = 0;
+ }
+#endif
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+run_with_signals(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ run_the_functions();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+#ifdef SIGPIPE
+ sigset(SIGPIPE, oldpipe);
+#endif
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+run_with_signals(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+#ifdef SIGPIPE
+ oldpipe = signal(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ run_the_functions();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+#ifdef SIGPIPE
+ signal(SIGPIPE, oldpipe);
+#endif
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+run_with_signals(void)
+{
+ run_the_functions();
+}
+#endif
+#endif
+#endif
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ dk4_sig_atomic_t shp;
+ $!trace-init dk-cat.deb
+ $? "+ main"
+ app = dk4app_open_cmd(
+ argc, argv, dk_cat_options, dk_cat_sz_options,
+ dk_cat_kwnl[0], DKT_VERSION_DK,
+ dk_cat_kwnl[1], dk_cat_help_text, dk_cat_license_text
+ );
+ if (NULL != app) {
+ sz_msg = dk4app_string_table_size(dk_cat_kw_def);
+ msg = dk4app_string_table(app, dk_cat_kwnl[2], dk_cat_kw_def);
+ if (0 != dk4app_can_run_normally(app)) {
+ if (0 != initialize_from_app()) {
+ decide_for_output_type();
+ exval = EXIT_SUCCESS;
+ run_with_signals();
+#ifdef SIGPIPE
+ shp = sig_read_atomic(&sig_had_pipe);
+#else
+ shp = 0;
+#endif
+ if (0 != shp) {
+ if (0 != verbose) {
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 24);
+ }
+ exval = EXIT_FAILURE;
+ } else {
+ if (0 != had_write_error) {
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 20);
+ exval = EXIT_FAILURE;
+ }
+ }
+ if (0 != sig_read_atomic(&sig_had_int)) {
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 25);
+ }
+ }
+ } else {
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ dk4app_close(app);
+ }
+ $? "- main %d", exval
+ $!trace-end
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/dk-cat.rc b/support/dktools/dk-cat.rc
new file mode 100644
index 0000000000..3750eecb1a
--- /dev/null
+++ b/support/dktools/dk-cat.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "A cat clone, shows text file contents\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "A cat clone, shows text file contents\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "dk-cat\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/dk-db2t.c b/support/dktools/dk-db2t.c
new file mode 100644
index 0000000000..faa556471d
--- /dev/null
+++ b/support/dktools/dk-db2t.c
@@ -0,0 +1,1189 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk-db2t.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk-db2t.c The dk-db2t module.
+*/
+
+
+#line 10 "dk-db2t.ctr"
+
+/*
+ Convert database to text, write to standard output.
+
+ See help_text below.
+*/
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4const.h"
+#include "dk4mem.h"
+#include "dk4mema.h"
+#include "dk4dbi.h"
+#include "dk4dbit8.h"
+#include "dk4dbitw.h"
+#include "dk4dbit.h"
+#include "dk4fput.h"
+#include "dk4vers.h"
+#include "dk4app.h"
+#include "dk4aopt.h"
+#include "dk4dbi.h"
+#include "dk4dbit.h"
+#include "dk4dbia.h"
+#include "dk4maasz.h"
+
+
+
+
+
+#line 89 "dk-db2t.ctr"
+
+
+
+/** Options.
+*/
+static const dk4_option_specification_t dk_db2t_options[] = {
+ { dkT('k'), dkT("key-buffer-size"), DK4_OPT_ARG_SIZE },
+ { dkT('v'), dkT("value-buffer-size"), DK4_OPT_ARG_SIZE },
+ { dkT('R'), dkT("reset"), DK4_OPT_ARG_NONE },
+ { dkT('\0'), dkT("verbose"), DK4_OPT_ARG_NONE }
+};
+
+
+
+/** Constant texts used by the program, not localized.
+*/
+const dkChar * const dk_db2t_kwnl[] = {
+/* 0 */
+dkT("dktools"),
+
+/* 1 */
+dkT("dk-db2t.txt"),
+
+/* 2 */
+dkT("dk-db2t.str"),
+
+/* 3 */
+dkT("ERROR: Application startup failed!\n"),
+
+/* 4 */
+dkT("text-db.key.max-size"),
+
+/* 5 */
+dkT("text-db.value.max-size"),
+
+/* 6 */
+dkT("verbose"),
+
+NULL
+
+
+#line 133 "dk-db2t.ctr"
+};
+
+
+
+static const dkChar * const dk_db2t_type_names[] = {
+/* 0 */
+dkT("bdb"),
+
+/* 1 */
+dkT("ndbm"),
+
+/* 2 */
+dkT("mem"),
+
+NULL
+
+
+#line 143 "dk-db2t.ctr"
+};
+
+
+static const dkChar * const dk_db2t_kw_def[] = {
+/* 0 */
+dkT("Failed to set up signal handlers!"),
+
+/* 1 */
+dkT("Failed to restore previous signal handlers!"),
+
+/* 2 */
+dkT("Failed to traverse database!"),
+
+/* 3 */
+dkT("At least one database name required!"),
+
+/* 4 */
+dkT("Write attempt to closed pipe!"),
+
+/* 5 */
+dkT("Interrupted by SIGINT signal!"),
+
+/* 6 */
+dkT("Failed to write text to standard output!"),
+
+NULL
+
+
+#line 177 "dk-db2t.ctr"
+};
+
+
+
+/** Version text.
+*/
+static const dkChar version_text[] = {
+ DKT_VERSION_DK
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+ dkT(" bdb")
+#endif
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+ dkT(" ndbm")
+#endif
+ dkT(" mem")
+};
+
+
+
+/** Short help text.
+*/
+static const dkChar * const help_text[] = {
+dkT(""),
+dkT("dk-db2t - Show database as text"),
+dkT("-------------------------------"),
+dkT(""),
+dkT("dk-db2t [<options>] <database>"),
+dkT(""),
+dkT("Options:"),
+dkT(""),
+dkT("-k <size>\t--key-size=<size>\t\tKey buffer size."),
+dkT("-v <size>\t--value-buffer-size=<size>\tValue buffer size."),
+dkT("\t\t\t\t\t\tDefault for both: 256."),
+dkT("\t\t--verbose\t\t\tShow error message on SIGPIPE."),
+dkT(""),
+dkT("--help\t\t\t\t\t\tShow short help text."),
+dkT("--manual\t\t\t\t\t*** SHOW FULL MANUAL ***"),
+dkT("--version\t\t\t\t\tShow version information."),
+dkT("--license\t\t\t\t\tShow license information."),
+dkT(""),
+NULL
+
+
+#line 219 "dk-db2t.ctr"
+};
+
+
+
+/** License conditions.
+*/
+static const dkChar * const license_text[] = {
+dkT(""),
+dkT("This software uses code from the following projects, either directly or as"),
+dkT("a library:"),
+dkT(""),
+dkT("dktools\t\tDirk Krause's tools and libraries."),
+dkT("\t\tSee http://dktools.sourceforge.net/ for more information."),
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+dkT(""),
+dkT("Berkeley DB\tDatabase library."),
+#endif
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT("zlib\t\tData compression library."),
+dkT("\t\tSee http://www.zlib.net/ for more information."),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT("bzip2\t\tData compression program and library."),
+dkT("\t\tSee http://www.bzip.org/ for more information."),
+#endif
+dkT(""),
+dkT("All the licenses below apply to the program."),
+dkT("Licenses for used libraries are shown as found on my Scientific Linux 6.x"),
+dkT("computer in the /usr/share/doc directory on 2015-04-01. Check the project"),
+dkT("homepages of the used libraries for additional information and/or updated"),
+dkT("license terms."),
+dkT(""),
+dkT(""),
+dkT("DK tools and libraries license"),
+dkT("=============================="),
+dkT("Copyright (c) 2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above copyright notice,"),
+dkT(" this list of conditions and the following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("* Neither the name of the Dirk Krause nor the names of contributors may be"),
+dkT(" used to endorse or promote products derived from this software without"),
+dkT(" specific prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\""),
+dkT("AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED."),
+dkT(""),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,"),
+dkT("INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,"),
+dkT("BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,"),
+dkT("DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY"),
+dkT("OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,"),
+dkT("EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+dkT(""),
+dkT(""),
+dkT("Berkeley DB license"),
+dkT("==================="),
+dkT("This package was debianized by Clint Adams <schizo@debian.org> on"),
+dkT("Wed, 25 Jul 2007 20:37:51 +0700"),
+dkT(""),
+dkT("It was downloaded from"),
+dkT("http://www.oracle.com/technology/software/products/berkeley-db/db/index.html"),
+dkT(""),
+dkT("Copyright and license:"),
+dkT(""),
+dkT("The following is the license that applies to this copy of the Berkeley DB"),
+dkT("software. For a license to use the Berkeley DB software under conditions"),
+dkT("other than those described here, or to purchase support for this software,"),
+dkT("please contact Oracle at berkeleydb-info_us@oracle.com."),
+dkT(""),
+dkT("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="),
+dkT("/*"),
+dkT(" * Copyright (c) 1990, 2010 Oracle and/or its affiliates. All rights reserved."),
+dkT(" *"),
+dkT(" * Redistribution and use in source and binary forms, with or without"),
+dkT(" * modification, are permitted provided that the following conditions"),
+dkT(" * are met:"),
+dkT(" * 1. Redistributions of source code must retain the above copyright"),
+dkT(" * notice, this list of conditions and the following disclaimer."),
+dkT(" * 2. Redistributions in binary form must reproduce the above copyright"),
+dkT(" * notice, this list of conditions and the following disclaimer in the"),
+dkT(" * documentation and/or other materials provided with the distribution."),
+dkT(" * 3. Redistributions in any form must be accompanied by information on"),
+dkT(" * how to obtain complete source code for the DB software and any"),
+dkT(" * accompanying software that uses the DB software. The source code"),
+dkT(" * must either be included in the distribution or be available for no"),
+dkT(" * more than the cost of distribution plus a nominal fee, and must be"),
+dkT(" * freely redistributable under reasonable conditions. For an"),
+dkT(" * executable file, complete source code means the source code for all"),
+dkT(" * modules it contains. It does not include source code for modules or"),
+dkT(" * files that typically accompany the major components of the operating"),
+dkT(" * system on which the executable file runs."),
+dkT(" *"),
+dkT(" * THIS SOFTWARE IS PROVIDED BY ORACLE ``AS IS'' AND ANY EXPRESS OR"),
+dkT(" * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED"),
+dkT(" * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR"),
+dkT(" * NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL ORACLE BE LIABLE"),
+dkT(" * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR"),
+dkT(" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF"),
+dkT(" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR"),
+dkT(" * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,"),
+dkT(" * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE"),
+dkT(" * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN"),
+dkT(" * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+dkT(" */"),
+dkT("/*"),
+dkT(" * Copyright (c) 1990, 1993, 1994, 1995"),
+dkT(" *\tThe Regents of the University of California. All rights reserved."),
+dkT(" *"),
+dkT(" * Redistribution and use in source and binary forms, with or without"),
+dkT(" * modification, are permitted provided that the following conditions"),
+dkT(" * are met:"),
+dkT(" * 1. Redistributions of source code must retain the above copyright"),
+dkT(" * notice, this list of conditions and the following disclaimer."),
+dkT(" * 2. Redistributions in binary form must reproduce the above copyright"),
+dkT(" * notice, this list of conditions and the following disclaimer in the"),
+dkT(" * documentation and/or other materials provided with the distribution."),
+dkT(" * 3. Neither the name of the University nor the names of its contributors"),
+dkT(" * may be used to endorse or promote products derived from this software"),
+dkT(" * without specific prior written permission."),
+dkT(" *"),
+dkT(" * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND"),
+dkT(" * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT(" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT(" * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE"),
+dkT(" * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT(" * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS"),
+dkT(" * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)"),
+dkT(" * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT"),
+dkT(" * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY"),
+dkT(" * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF"),
+dkT(" * SUCH DAMAGE."),
+dkT(" */"),
+dkT("/*"),
+dkT(" * Copyright (c) 1995, 1996"),
+dkT(" *\tThe President and Fellows of Harvard University. All rights reserved."),
+dkT(" *"),
+dkT(" * Redistribution and use in source and binary forms, with or without"),
+dkT(" * modification, are permitted provided that the following conditions"),
+dkT(" * are met:"),
+dkT(" * 1. Redistributions of source code must retain the above copyright"),
+dkT(" * notice, this list of conditions and the following disclaimer."),
+dkT(" * 2. Redistributions in binary form must reproduce the above copyright"),
+dkT(" * notice, this list of conditions and the following disclaimer in the"),
+dkT(" * documentation and/or other materials provided with the distribution."),
+dkT(" * 3. Neither the name of the University nor the names of its contributors"),
+dkT(" * may be used to endorse or promote products derived from this software"),
+dkT(" * without specific prior written permission."),
+dkT(" *"),
+dkT(" * THIS SOFTWARE IS PROVIDED BY HARVARD AND ITS CONTRIBUTORS ``AS IS'' AND"),
+dkT(" * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT(" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT(" * ARE DISCLAIMED. IN NO EVENT SHALL HARVARD OR ITS CONTRIBUTORS BE LIABLE"),
+dkT(" * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT(" * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS"),
+dkT(" * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)"),
+dkT(" * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT"),
+dkT(" * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY"),
+dkT(" * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF"),
+dkT(" * SUCH DAMAGE."),
+dkT(" */"),
+dkT("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="),
+dkT("/***"),
+dkT(" * ASM: a very small and fast Java bytecode manipulation framework"),
+dkT(" * Copyright (c) 2000-2005 INRIA, France Telecom"),
+dkT(" * All rights reserved."),
+dkT(" *"),
+dkT(" * Redistribution and use in source and binary forms, with or without"),
+dkT(" * modification, are permitted provided that the following conditions"),
+dkT(" * are met:"),
+dkT(" * 1. Redistributions of source code must retain the above copyright"),
+dkT(" * notice, this list of conditions and the following disclaimer."),
+dkT(" * 2. Redistributions in binary form must reproduce the above copyright"),
+dkT(" * notice, this list of conditions and the following disclaimer in the"),
+dkT(" * documentation and/or other materials provided with the distribution."),
+dkT(" * 3. Neither the name of the copyright holders nor the names of its"),
+dkT(" * contributors may be used to endorse or promote products derived from"),
+dkT(" * this software without specific prior written permission."),
+dkT(" *"),
+dkT(" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\""),
+dkT(" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT(" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT(" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE"),
+dkT(" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR"),
+dkT(" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF"),
+dkT(" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS"),
+dkT(" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN"),
+dkT(" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)"),
+dkT(" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF"),
+dkT(" * THE POSSIBILITY OF SUCH DAMAGE."),
+dkT(" */"),
+#endif
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT(""),
+dkT("Zlib license"),
+dkT("============"),
+dkT("(C) 1995-2004 Jean-loup Gailly and Mark Adler"),
+dkT(""),
+dkT("This software is provided 'as-is', without any express or implied"),
+dkT("warranty. In no event will the authors be held liable for any damages"),
+dkT("arising from the use of this software."),
+dkT(""),
+dkT("Permission is granted to anyone to use this software for any purpose,"),
+dkT("including commercial applications, and to alter it and redistribute it"),
+dkT("freely, subject to the following restrictions:"),
+dkT(""),
+dkT("1. The origin of this software must not be misrepresented; you must not"),
+dkT(" claim that you wrote the original software. If you use this software"),
+dkT(" in a product, an acknowledgment in the product documentation would be"),
+dkT(" appreciated but is not required."),
+dkT("2. Altered source versions must be plainly marked as such, and must not be"),
+dkT(" misrepresented as being the original software."),
+dkT("3. This notice may not be removed or altered from any source distribution."),
+dkT(""),
+dkT("Jean-loup Gailly Mark Adler"),
+dkT("jloup@gzip.org madler@alumni.caltech.edu"),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT(""),
+dkT("Bzip2 and libbzip2 library license"),
+dkT("=================================="),
+dkT("This program, \"bzip2\", the associated library \"libbzip2\", and all"),
+dkT("documentation, are copyright (C) 1996-2007 Julian R Seward. All"),
+dkT("rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions"),
+dkT("are met:"),
+dkT(""),
+dkT("1. Redistributions of source code must retain the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer."),
+dkT(""),
+dkT("2. The origin of this software must not be misrepresented; you must "),
+dkT(" not claim that you wrote the original software. If you use this "),
+dkT(" software in a product, an acknowledgment in the product "),
+dkT(" documentation would be appreciated but is not required."),
+dkT(""),
+dkT("3. Altered source versions must be plainly marked as such, and must"),
+dkT(" not be misrepresented as being the original software."),
+dkT(""),
+dkT("4. The name of the author may not be used to endorse or promote "),
+dkT(" products derived from this software without specific prior written "),
+dkT(" permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS"),
+dkT("OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED"),
+dkT("WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE"),
+dkT("GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS"),
+dkT("INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,"),
+dkT("WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS"),
+dkT("SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+dkT(""),
+dkT("Julian Seward, jseward@bzip.org"),
+dkT("bzip2/libbzip2 version 1.0.5 of 10 December 2007"),
+#endif
+NULL
+
+
+#line 494 "dk-db2t.ctr"
+};
+
+
+
+/** Buffer for key text.
+*/
+static dkChar keybuffer[1024];
+
+
+
+/** Buffer for value text.
+*/
+static dkChar valuebuffer[1024];
+
+
+
+/** Localized keywords.
+*/
+static const dkChar * const *dk_db2t_msg = dk_db2t_kw_def;
+
+
+
+/** Number of options in the dk_db2t_options array.
+*/
+static const size_t dk_db2t_sz_options =
+sizeof(dk_db2t_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Number of keywords in the dk_db2t_msg array.
+*/
+static size_t dk_db2t_sz_msg =
+(sizeof(dk_db2t_kw_def)/sizeof(DK4_PDKCHAR) - 1);
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Allocated buffer for key.
+*/
+static dkChar *akey = NULL;
+
+
+
+/** Allocated buffer for value.
+*/
+static dkChar *avalue = NULL;
+
+
+
+/** Pointer to key buffer to use.
+*/
+static dkChar *pkey = keybuffer;
+
+
+
+/** Pointer to value buffer to use.
+*/
+static dkChar *pvalue = valuebuffer;
+
+
+
+/** Key buffer size (number of dkChar).
+*/
+static size_t keysz = DK4_SIZEOF(keybuffer,dkChar);
+
+
+
+/** Value buffer size (number of dkChar).
+*/
+static size_t valsz = DK4_SIZEOF(valuebuffer,dkChar);
+
+
+
+/** Exit status code.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+/** Flag: Write error occured.
+*/
+static int we = 0;
+
+
+
+/** Flag: Report SIGPIPE.
+*/
+static int verbose = 0;
+
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+
+
+/** Check whether we can continue or if a signal was received.
+ @param check_pipe Flag: Check for occured SIGPIPE signal too.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(int check_pipe)
+{
+ int back = 1;
+#ifdef SIGPIPE
+ if (0 != check_pipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_int )) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+/** Traverse simple database containing text.
+ @param obj Object to modify during traversal.
+ @param k Key text.
+ @param v Value text.
+ @return 1 on success, 0 on error (continue traversal),
+ -1 on error (abort).
+*/
+static
+int
+dk_db2t_traverse(
+ void *obj,
+ const dkChar *k,
+ const dkChar *v
+)
+{
+ int back = 1;
+ if (NULL != k) {
+ if (NULL != v) {
+ if (0 == dk4fputs(k, stdout, NULL)) {
+ back = 0; we = 1;
+ }
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ back = 0; we = 1;
+ }
+ if (0 == dk4fputs(v, stdout, NULL)) {
+ back = 0; we = 1;
+ }
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) {
+ back = 0; we = 1;
+ }
+ } else {
+ back = 0;
+ }
+ } else {
+ back = 0;
+ }
+ return back;
+}
+
+
+
+/** Run with allocated buffers.
+*/
+static
+void
+dk_db2t_run_with_buffers(void)
+{
+ dk4_er_t er; /* Error report for size calculation */
+ const dkChar *fn; /* File name */
+ dk4_dbi_t *dbiptr; /* Database */
+ size_t szbk; /* Maximum key size in bytes */
+ size_t szbv; /* Maximum value size in bytes */
+ int obj; /* Dummy object for traversal */
+ int xargc; /* Number of command line arguments */
+ int i; /* Current command line arg index */
+ int res; /* Operation result */
+
+ obj = 0;
+ xargc = dk4app_get_argc(app);
+ if (0 < xargc) {
+ exval = EXIT_SUCCESS;
+ for (i = 0; ((i < xargc) && (0 != sig_can_continue(1))); i++) {
+ fn = dk4app_get_argv(app, i);
+ if (NULL != fn) {
+ dk4error_init(&er);
+ szbk = dk4ma_size_t_mul(keysz, sizeof(dkChar), &er);
+ szbv = dk4ma_size_t_mul(valsz, sizeof(dkChar), &er);
+ if (DK4_E_NONE == er.ec) {
+ dbiptr = dk4dbi_open_sizes_app(fn, 0, 0, szbk, szbv, NULL, app);
+ if (NULL != dbiptr) {
+ res = dk4dbi_text_traverse(dbiptr, &obj, dk_db2t_traverse);
+ switch (res) {
+ case 1: {
+ } break;
+ case 0: {
+ exval = EXIT_FAILURE;
+ } break;
+ default: {
+ dk4app_log_1(app, dk_db2t_msg, dk_db2t_sz_msg, DK4_LL_ERROR, 2);
+ exval = EXIT_FAILURE;
+ } break;
+ }
+ dk4dbi_close(dbiptr, NULL);
+ } else {
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Size calculation overflow */
+ dk4app_log_base1(app, DK4_LL_ERROR, 82);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* BUG: No such file name */
+ exval = EXIT_FAILURE;
+ }
+ }
+ } else {
+ /* ERROR: Too few database names */
+ dk4app_log_1(app, dk_db2t_msg, dk_db2t_sz_msg, DK4_LL_ERROR, 3);
+
+ }
+}
+
+
+
+/** Run normally.
+*/
+static
+void
+dk_db2t_normal_run(void)
+{
+ size_t ks = 0;
+ size_t vs = 0;
+ size_t i = 0;
+
+ /* Check for verbose mode.
+ */
+ if (0 != dk4app_opt_is_set_long(app, dk_db2t_kwnl[6], NULL)) {
+ verbose = 1;
+ }
+ /* Retrieve buffer sizes, allocate larger buffers if necessary.
+ */
+ if (0 != dk4app_opt_is_set_short(app, dkT('R'), NULL)) {
+ if (0 != dk4app_pref_get_size(&i, app, dk_db2t_kwnl[4], 0)) {
+ ks = i;
+ }
+ if (0 != dk4app_pref_get_size(&i, app, dk_db2t_kwnl[5], 0)) {
+ vs = i;
+ }
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('k'), NULL)) {
+ if (0 != dk4app_opt_get_size_short(&i, app, dkT('k'), NULL)) {
+ ks = i;
+ }
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('v'), NULL)) {
+ if (0 != dk4app_opt_get_size_short(&i, app, dkT('v'), NULL)) {
+ vs = i;
+ }
+ }
+ if (ks > keysz) {
+ akey = dk4mem_new_app(dkChar,ks,app) ;
+ if (NULL != akey) {
+ pkey = akey;
+ keysz = ks;
+ } else {
+ goto finished;
+ }
+ } else {
+ if (0 < ks) {
+ keysz = ks;
+ }
+ }
+ if (vs > valsz) {
+ avalue = dk4mem_new_app(dkChar,vs,app) ;
+ if (NULL != avalue) {
+ pvalue = avalue;
+ valsz = vs;
+ } else {
+ goto finished;
+ }
+ } else {
+ if (0 < vs) {
+ valsz = vs;
+ }
+ }
+
+ /* Run either with static or allocated buffers.
+ */
+ dk_db2t_run_with_buffers();
+
+ /* Clean up, release larger buffers if allocated.
+ */
+ finished:
+ dk4mem_release(akey) ;
+ dk4mem_release(avalue) ;
+}
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+dk_db2t_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ struct sigaction opipe;
+#endif
+ struct sigaction oint;
+#ifdef SIGPIPE
+ struct sigaction npipe;
+#endif
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+ int success = 0;
+
+#ifdef SIGPIPE
+ /* Set up signal handling for SIGPIPE.
+ */
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_db2t_msg, dk_db2t_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_db2t_msg, dk_db2t_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ dk4app_log_1(app, dk_db2t_msg, dk_db2t_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+#endif
+
+ /* Set up signal handling for SIGINT.
+ */
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_db2t_msg, dk_db2t_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_db2t_msg, dk_db2t_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, dk_db2t_msg, dk_db2t_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_db2t_msg, dk_db2t_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_db2t_msg, dk_db2t_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, dk_db2t_msg, dk_db2t_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ dk_db2t_normal_run();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, dk_db2t_msg, dk_db2t_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_db2t_msg, dk_db2t_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+#ifdef SIGPIPE
+ /* Restore signal handling for SIGPIPE.
+ */
+ restore_old_pipe:
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_db2t_msg, dk_db2t_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+#endif
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+dk_db2t_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ dk_db2t_normal_run();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+#ifdef SIGPIPE
+ sigset(SIGPIPE, oldpipe);
+#endif
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+dk_db2t_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = signal(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ dk_db2t_normal_run();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+#ifdef SIGPIPE
+ signal(SIGPIPE, oldpipe);
+#endif
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+dk_db2t_run_with_signal_handlers(void)
+{
+ dk_db2t_normal_run();
+}
+#endif
+#endif
+#endif
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ dk4_sig_atomic_t shp = 0; /* Flag: Had SIGPIPE */
+
+
+#line 1076 "dk-db2t.ctr"
+
+
+#line 1077 "dk-db2t.ctr"
+ dk4fput_initialize_stdout();
+ dk4fput_initialize_stderr();
+ app = dk4app_open_cmd(
+ argc, argv,
+ dk_db2t_options, dk_db2t_sz_options,
+ dk_db2t_kwnl[0], version_text,
+ dk_db2t_kwnl[1], help_text, license_text
+ );
+ if (NULL != app) {
+
+
+#line 1087 "dk-db2t.ctr"
+ dk_db2t_sz_msg = dk4app_string_table_size(dk_db2t_kw_def);
+ dk_db2t_msg = dk4app_string_table(app, dk_db2t_kwnl[2], dk_db2t_kw_def);
+ if (0 != dk4app_can_run_normally(app)) {
+
+
+#line 1091 "dk-db2t.ctr"
+ dk_db2t_run_with_signal_handlers();
+#ifdef SIGPIPE
+ shp = sig_read_atomic(&sig_had_pipe);
+#endif
+ if (0 != shp) {
+ if (0 != verbose) {
+ /* ERROR: Write attempt to closed pip */
+ dk4app_log_1(app, dk_db2t_msg, dk_db2t_sz_msg, DK4_LL_ERROR, 4);
+ }
+ exval = EXIT_FAILURE;
+ } else {
+ if (0 != we) {
+ /* ERROR: Failed writing output */
+ dk4app_log_1(app, dk_db2t_msg, dk_db2t_sz_msg, DK4_LL_ERROR, 6);
+ exval = EXIT_FAILURE;
+ }
+ }
+ if (0 != sig_read_atomic(&sig_had_int)) {
+ /* ERROR: Aborted by SIGINT */
+ dk4app_log_1(app, dk_db2t_msg, dk_db2t_sz_msg, DK4_LL_ERROR, 5);
+ exval = EXIT_FAILURE;
+ }
+ if (0 != sig_read_atomic(&sig_had_term)) {
+ exval = EXIT_FAILURE;
+ }
+ } else {
+
+
+#line 1118 "dk-db2t.ctr"
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ dk4app_close(app);
+ } else {
+
+
+#line 1125 "dk-db2t.ctr"
+ dk4fputs(dk_db2t_kwnl[3], stderr, NULL);
+ }
+ fflush(stdout);
+ fflush(stderr);
+ dk4fput_cleanup_stderr();
+ dk4fput_cleanup_stdout();
+
+
+#line 1132 "dk-db2t.ctr"
+
+
+#line 1133 "dk-db2t.ctr"
+ return (exval); exit(exval);
+}
+
diff --git a/support/dktools/dk-db2t.ctr b/support/dktools/dk-db2t.ctr
new file mode 100644
index 0000000000..b5dc522dad
--- /dev/null
+++ b/support/dktools/dk-db2t.ctr
@@ -0,0 +1,1135 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+
+
+%% module
+
+/*
+ Convert database to text, write to standard output.
+
+ See help_text below.
+*/
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4const.h"
+#include "dk4mem.h"
+#include "dk4mema.h"
+#include "dk4dbi.h"
+#include "dk4dbit8.h"
+#include "dk4dbitw.h"
+#include "dk4dbit.h"
+#include "dk4fput.h"
+#include "dk4vers.h"
+#include "dk4app.h"
+#include "dk4aopt.h"
+#include "dk4dbi.h"
+#include "dk4dbit.h"
+#include "dk4dbia.h"
+#include "dk4maasz.h"
+
+
+
+$!trace-include
+
+
+
+/** Options.
+*/
+static const dk4_option_specification_t dk_db2t_options[] = {
+ { dkT('k'), dkT("key-buffer-size"), DK4_OPT_ARG_SIZE },
+ { dkT('v'), dkT("value-buffer-size"), DK4_OPT_ARG_SIZE },
+ { dkT('R'), dkT("reset"), DK4_OPT_ARG_NONE },
+ { dkT('\0'), dkT("verbose"), DK4_OPT_ARG_NONE }
+};
+
+
+
+/** Constant texts used by the program, not localized.
+*/
+const dkChar * const dk_db2t_kwnl[] = {
+$!string-table macro=dkT
+#
+# 0 Program group name
+#
+dktools
+#
+# 1 Help text file name
+#
+dk-db2t.txt
+#
+# 2 String table file name
+#
+dk-db2t.str
+#
+# 3 ERROR: Application startup failed!
+#
+ERROR: Application startup failed!\n
+#
+# 4 5 Preference names for key and value size.
+#
+text-db.key.max-size
+text-db.value.max-size
+#
+# 6 Long option for verbose mode.
+#
+verbose
+$!end
+};
+
+
+
+static const dkChar * const dk_db2t_type_names[] = {
+$!string-table macro=dkT
+bdb
+ndbm
+mem
+$!end
+};
+
+
+static const dkChar * const dk_db2t_kw_def[] = {
+$!string-table macro=dkT
+#
+# 0 Error: Failed to set up signal handlers!
+#
+Failed to set up signal handlers!
+#
+# 1 Error: Failed to restore previous signal handlers!
+#
+Failed to restore previous signal handlers!
+#
+# 2 Error: Failed to traverse database!
+#
+Failed to traverse database!
+#
+# 3 Error: At least one database name required!
+#
+At least one database name required!
+#
+# 4 Error: Write attempt to closed pipe!
+#
+Write attempt to closed pipe!
+#
+# 5 Error: Interrupted by SIGINT signal!
+#
+Interrupted by SIGINT signal!
+#
+# 6 Error: Failed to write text to standard output!
+#
+Failed to write text to standard output!
+$!end
+};
+
+
+
+/** Version text.
+*/
+static const dkChar version_text[] = {
+ DKT_VERSION_DK
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+ dkT(" bdb")
+#endif
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+ dkT(" ndbm")
+#endif
+ dkT(" mem")
+};
+
+
+
+/** Short help text.
+*/
+static const dkChar * const help_text[] = {
+$!text macro=dkT
+
+dk-db2t - Show database as text
+-------------------------------
+
+dk-db2t [<options>] <database>
+
+Options:
+
+-k <size> --key-size=<size> Key buffer size.
+-v <size> --value-buffer-size=<size> Value buffer size.
+ Default for both: 256.
+ --verbose Show error message on SIGPIPE.
+
+--help Show short help text.
+--manual *** SHOW FULL MANUAL ***
+--version Show version information.
+--license Show license information.
+
+$!end
+};
+
+
+
+/** License conditions.
+*/
+static const dkChar * const license_text[] = {
+$!text macro=dkT,preprocessor
+
+This software uses code from the following projects, either directly or as
+a library:
+
+dktools Dirk Krause's tools and libraries.
+ See http://dktools.sourceforge.net/ for more information.
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+
+Berkeley DB Database library.
+#endif
+#if DK4_HAVE_ZLIB_H
+
+zlib Data compression library.
+ See http://www.zlib.net/ for more information.
+#endif
+#if DK4_HAVE_BZLIB_H
+
+bzip2 Data compression program and library.
+ See http://www.bzip.org/ for more information.
+#endif
+
+All the licenses below apply to the program.
+Licenses for used libraries are shown as found on my Scientific Linux 6.x
+computer in the /usr/share/doc directory on 2015-04-01. Check the project
+homepages of the used libraries for additional information and/or updated
+license terms.
+
+
+DK tools and libraries license
+==============================
+Copyright (c) 2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+
+
+Berkeley DB license
+===================
+This package was debianized by Clint Adams <schizo@debian.org> on
+Wed, 25 Jul 2007 20:37:51 +0700
+
+It was downloaded from
+http://www.oracle.com/technology/software/products/berkeley-db/db/index.html
+
+Copyright and license:
+
+The following is the license that applies to this copy of the Berkeley DB
+software. For a license to use the Berkeley DB software under conditions
+other than those described here, or to purchase support for this software,
+please contact Oracle at berkeleydb-info_us@oracle.com.
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+/*
+ * Copyright (c) 1990, 2010 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Redistributions in any form must be accompanied by information on
+ * how to obtain complete source code for the DB software and any
+ * accompanying software that uses the DB software. The source code
+ * must either be included in the distribution or be available for no
+ * more than the cost of distribution plus a nominal fee, and must be
+ * freely redistributable under reasonable conditions. For an
+ * executable file, complete source code means the source code for all
+ * modules it contains. It does not include source code for modules or
+ * files that typically accompany the major components of the operating
+ * system on which the executable file runs.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ORACLE ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ * NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL ORACLE BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * Copyright (c) 1990, 1993, 1994, 1995
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * Copyright (c) 1995, 1996
+ * The President and Fellows of Harvard University. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY HARVARD AND ITS CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HARVARD OR ITS CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#endif
+#if DK4_HAVE_ZLIB_H
+
+
+Zlib license
+============
+(C) 1995-2004 Jean-loup Gailly and Mark Adler
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+
+Jean-loup Gailly Mark Adler
+jloup@gzip.org madler@alumni.caltech.edu
+#endif
+#if DK4_HAVE_BZLIB_H
+
+
+Bzip2 and libbzip2 library license
+==================================
+This program, "bzip2", the associated library "libbzip2", and all
+documentation, are copyright (C) 1996-2007 Julian R Seward. All
+rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+3. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Julian Seward, jseward@bzip.org
+bzip2/libbzip2 version 1.0.5 of 10 December 2007
+#endif
+$!end
+};
+
+
+
+/** Buffer for key text.
+*/
+static dkChar keybuffer[1024];
+
+
+
+/** Buffer for value text.
+*/
+static dkChar valuebuffer[1024];
+
+
+
+/** Localized keywords.
+*/
+static const dkChar * const *dk_db2t_msg = dk_db2t_kw_def;
+
+
+
+/** Number of options in the dk_db2t_options array.
+*/
+static const size_t dk_db2t_sz_options =
+sizeof(dk_db2t_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Number of keywords in the dk_db2t_msg array.
+*/
+static size_t dk_db2t_sz_msg =
+(sizeof(dk_db2t_kw_def)/sizeof(DK4_PDKCHAR) - 1);
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Allocated buffer for key.
+*/
+static dkChar *akey = NULL;
+
+
+
+/** Allocated buffer for value.
+*/
+static dkChar *avalue = NULL;
+
+
+
+/** Pointer to key buffer to use.
+*/
+static dkChar *pkey = keybuffer;
+
+
+
+/** Pointer to value buffer to use.
+*/
+static dkChar *pvalue = valuebuffer;
+
+
+
+/** Key buffer size (number of dkChar).
+*/
+static size_t keysz = DK4_SIZEOF(keybuffer,dkChar);
+
+
+
+/** Value buffer size (number of dkChar).
+*/
+static size_t valsz = DK4_SIZEOF(valuebuffer,dkChar);
+
+
+
+/** Exit status code.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+/** Flag: Write error occured.
+*/
+static int we = 0;
+
+
+
+/** Flag: Report SIGPIPE.
+*/
+static int verbose = 0;
+
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+
+
+/** Check whether we can continue or if a signal was received.
+ @param check_pipe Flag: Check for occured SIGPIPE signal too.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(int check_pipe)
+{
+ int back = 1;
+#ifdef SIGPIPE
+ if (0 != check_pipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_int )) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+/** Traverse simple database containing text.
+ @param obj Object to modify during traversal.
+ @param k Key text.
+ @param v Value text.
+ @return 1 on success, 0 on error (continue traversal),
+ -1 on error (abort).
+*/
+static
+int
+dk_db2t_traverse(
+ void *obj,
+ const dkChar *k,
+ const dkChar *v
+)
+{
+ int back = 1;
+ if (NULL != k) {
+ if (NULL != v) {
+ if (0 == dk4fputs(k, stdout, NULL)) {
+ back = 0; we = 1;
+ }
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ back = 0; we = 1;
+ }
+ if (0 == dk4fputs(v, stdout, NULL)) {
+ back = 0; we = 1;
+ }
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) {
+ back = 0; we = 1;
+ }
+ } else {
+ back = 0;
+ }
+ } else {
+ back = 0;
+ }
+ return back;
+}
+
+
+
+/** Run with allocated buffers.
+*/
+static
+void
+dk_db2t_run_with_buffers(void)
+{
+ dk4_er_t er; /* Error report for size calculation */
+ const dkChar *fn; /* File name */
+ dk4_dbi_t *dbiptr; /* Database */
+ size_t szbk; /* Maximum key size in bytes */
+ size_t szbv; /* Maximum value size in bytes */
+ int obj; /* Dummy object for traversal */
+ int xargc; /* Number of command line arguments */
+ int i; /* Current command line arg index */
+ int res; /* Operation result */
+
+ obj = 0;
+ xargc = dk4app_get_argc(app);
+ if (0 < xargc) {
+ exval = EXIT_SUCCESS;
+ for (i = 0; ((i < xargc) && (0 != sig_can_continue(1))); i++) {
+ fn = dk4app_get_argv(app, i);
+ if (NULL != fn) {
+ dk4error_init(&er);
+ szbk = dk4ma_size_t_mul(keysz, sizeof(dkChar), &er);
+ szbv = dk4ma_size_t_mul(valsz, sizeof(dkChar), &er);
+ if (DK4_E_NONE == er.ec) {
+ dbiptr = dk4dbi_open_sizes_app(fn, 0, 0, szbk, szbv, NULL, app);
+ if (NULL != dbiptr) {
+ res = dk4dbi_text_traverse(dbiptr, &obj, dk_db2t_traverse);
+ switch (res) {
+ case 1: {
+ } break;
+ case 0: {
+ exval = EXIT_FAILURE;
+ } break;
+ default: {
+ dk4app_log_1(app, dk_db2t_msg, dk_db2t_sz_msg, DK4_LL_ERROR, 2);
+ exval = EXIT_FAILURE;
+ } break;
+ }
+ dk4dbi_close(dbiptr, NULL);
+ } else {
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Size calculation overflow */
+ dk4app_log_base1(app, DK4_LL_ERROR, 82);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* BUG: No such file name */
+ exval = EXIT_FAILURE;
+ }
+ }
+ } else {
+ /* ERROR: Too few database names */
+ dk4app_log_1(app, dk_db2t_msg, dk_db2t_sz_msg, DK4_LL_ERROR, 3);
+
+ }
+}
+
+
+
+/** Run normally.
+*/
+static
+void
+dk_db2t_normal_run(void)
+{
+ size_t ks = 0;
+ size_t vs = 0;
+ size_t i = 0;
+
+ /* Check for verbose mode.
+ */
+ if (0 != dk4app_opt_is_set_long(app, dk_db2t_kwnl[6], NULL)) {
+ verbose = 1;
+ }
+ /* Retrieve buffer sizes, allocate larger buffers if necessary.
+ */
+ if (0 != dk4app_opt_is_set_short(app, dkT('R'), NULL)) {
+ if (0 != dk4app_pref_get_size(&i, app, dk_db2t_kwnl[4], 0)) {
+ ks = i;
+ }
+ if (0 != dk4app_pref_get_size(&i, app, dk_db2t_kwnl[5], 0)) {
+ vs = i;
+ }
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('k'), NULL)) {
+ if (0 != dk4app_opt_get_size_short(&i, app, dkT('k'), NULL)) {
+ ks = i;
+ }
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('v'), NULL)) {
+ if (0 != dk4app_opt_get_size_short(&i, app, dkT('v'), NULL)) {
+ vs = i;
+ }
+ }
+ if (ks > keysz) {
+ akey = dk4mem_new_app(dkChar,ks,app) ;
+ if (NULL != akey) {
+ pkey = akey;
+ keysz = ks;
+ } else {
+ goto finished;
+ }
+ } else {
+ if (0 < ks) {
+ keysz = ks;
+ }
+ }
+ if (vs > valsz) {
+ avalue = dk4mem_new_app(dkChar,vs,app) ;
+ if (NULL != avalue) {
+ pvalue = avalue;
+ valsz = vs;
+ } else {
+ goto finished;
+ }
+ } else {
+ if (0 < vs) {
+ valsz = vs;
+ }
+ }
+
+ /* Run either with static or allocated buffers.
+ */
+ dk_db2t_run_with_buffers();
+
+ /* Clean up, release larger buffers if allocated.
+ */
+ finished:
+ dk4mem_release(akey) ;
+ dk4mem_release(avalue) ;
+}
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+dk_db2t_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ struct sigaction opipe;
+#endif
+ struct sigaction oint;
+#ifdef SIGPIPE
+ struct sigaction npipe;
+#endif
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+ int success = 0;
+
+#ifdef SIGPIPE
+ /* Set up signal handling for SIGPIPE.
+ */
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_db2t_msg, dk_db2t_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_db2t_msg, dk_db2t_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ dk4app_log_1(app, dk_db2t_msg, dk_db2t_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+#endif
+
+ /* Set up signal handling for SIGINT.
+ */
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_db2t_msg, dk_db2t_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_db2t_msg, dk_db2t_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, dk_db2t_msg, dk_db2t_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_db2t_msg, dk_db2t_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_db2t_msg, dk_db2t_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, dk_db2t_msg, dk_db2t_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ dk_db2t_normal_run();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, dk_db2t_msg, dk_db2t_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_db2t_msg, dk_db2t_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+#ifdef SIGPIPE
+ /* Restore signal handling for SIGPIPE.
+ */
+ restore_old_pipe:
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_db2t_msg, dk_db2t_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+#endif
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+dk_db2t_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ dk_db2t_normal_run();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+#ifdef SIGPIPE
+ sigset(SIGPIPE, oldpipe);
+#endif
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+dk_db2t_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = signal(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ dk_db2t_normal_run();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+#ifdef SIGPIPE
+ signal(SIGPIPE, oldpipe);
+#endif
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+dk_db2t_run_with_signal_handlers(void)
+{
+ dk_db2t_normal_run();
+}
+#endif
+#endif
+#endif
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ dk4_sig_atomic_t shp = 0; /* Flag: Had SIGPIPE */
+ $!trace-init dk-db2t.deb
+ $? "+ main"
+ dk4fput_initialize_stdout();
+ dk4fput_initialize_stderr();
+ app = dk4app_open_cmd(
+ argc, argv,
+ dk_db2t_options, dk_db2t_sz_options,
+ dk_db2t_kwnl[0], version_text,
+ dk_db2t_kwnl[1], help_text, license_text
+ );
+ if (NULL != app) {
+ $? ". app"
+ dk_db2t_sz_msg = dk4app_string_table_size(dk_db2t_kw_def);
+ dk_db2t_msg = dk4app_string_table(app, dk_db2t_kwnl[2], dk_db2t_kw_def);
+ if (0 != dk4app_can_run_normally(app)) {
+ $? ". can run normally"
+ dk_db2t_run_with_signal_handlers();
+#ifdef SIGPIPE
+ shp = sig_read_atomic(&sig_had_pipe);
+#endif
+ if (0 != shp) {
+ if (0 != verbose) {
+ /* ERROR: Write attempt to closed pip */
+ dk4app_log_1(app, dk_db2t_msg, dk_db2t_sz_msg, DK4_LL_ERROR, 4);
+ }
+ exval = EXIT_FAILURE;
+ } else {
+ if (0 != we) {
+ /* ERROR: Failed writing output */
+ dk4app_log_1(app, dk_db2t_msg, dk_db2t_sz_msg, DK4_LL_ERROR, 6);
+ exval = EXIT_FAILURE;
+ }
+ }
+ if (0 != sig_read_atomic(&sig_had_int)) {
+ /* ERROR: Aborted by SIGINT */
+ dk4app_log_1(app, dk_db2t_msg, dk_db2t_sz_msg, DK4_LL_ERROR, 5);
+ exval = EXIT_FAILURE;
+ }
+ if (0 != sig_read_atomic(&sig_had_term)) {
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ $? ". can not run normally"
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ dk4app_close(app);
+ } else {
+ $? "! app"
+ dk4fputs(dk_db2t_kwnl[3], stderr, NULL);
+ }
+ fflush(stdout);
+ fflush(stderr);
+ dk4fput_cleanup_stderr();
+ dk4fput_cleanup_stdout();
+ $? "- main %d", exval
+ $!trace-end
+ return (exval); exit(exval);
+}
+
diff --git a/support/dktools/dk-db2t.rc b/support/dktools/dk-db2t.rc
new file mode 100644
index 0000000000..4bf2d29ec6
--- /dev/null
+++ b/support/dktools/dk-db2t.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Write simple text database to standard output\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "Write simple text database to standard output\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "dk-db2t\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/dk-dbco.c b/support/dktools/dk-dbco.c
new file mode 100644
index 0000000000..c5111d01e9
--- /dev/null
+++ b/support/dktools/dk-dbco.c
@@ -0,0 +1,1097 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk-dbco.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk-dbco.c The dk-dbco module.
+*/
+
+
+#line 10 "dk-dbco.ctr"
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4const.h"
+#include "dk4numco.h"
+#include "dk4vers.h"
+#include "dk4mem.h"
+#include "dk4opt.h"
+#include "dk4aopt.h"
+#include "dk4app.h"
+#include "dk4mema.h"
+#include "dk4dbi.h"
+#include "dk4dbia.h"
+#include "dk4fput.h"
+
+
+
+
+
+#line 79 "dk-dbco.ctr"
+
+
+
+/** License conditions.
+*/
+static const dkChar * const license_text[] = {
+dkT(""),
+dkT("This software uses code from the following projects, either directly or as"),
+dkT("a library:"),
+dkT(""),
+dkT("dktools\t\tDirk Krause's tools and libraries."),
+dkT("\t\tSee http://dktools.sourceforge.net/ for more information."),
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+dkT(""),
+dkT("Berkeley DB\tDatabase library."),
+#endif
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT("zlib\t\tData compression library."),
+dkT("\t\tSee http://www.zlib.net/ for more information."),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT("bzip2\t\tData compression program and library."),
+dkT("\t\tSee http://www.bzip.org/ for more information."),
+#endif
+dkT(""),
+dkT("All the licenses below apply to the program."),
+dkT("Licenses for used libraries are shown as found on my Scientific Linux 6.x"),
+dkT("computer in the /usr/share/doc directory on 2015-04-01. Check the project"),
+dkT("homepages of the used libraries for additional information and/or updated"),
+dkT("license terms."),
+dkT(""),
+dkT(""),
+dkT("DK tools and libraries license"),
+dkT("=============================="),
+dkT("Copyright (c) 2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above copyright notice,"),
+dkT(" this list of conditions and the following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("* Neither the name of the Dirk Krause nor the names of contributors may be"),
+dkT(" used to endorse or promote products derived from this software without"),
+dkT(" specific prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\""),
+dkT("AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED."),
+dkT(""),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,"),
+dkT("INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,"),
+dkT("BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,"),
+dkT("DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY"),
+dkT("OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,"),
+dkT("EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+dkT(""),
+dkT(""),
+dkT("Berkeley DB license"),
+dkT("==================="),
+dkT("This package was debianized by Clint Adams <schizo@debian.org> on"),
+dkT("Wed, 25 Jul 2007 20:37:51 +0700"),
+dkT(""),
+dkT("It was downloaded from"),
+dkT("http://www.oracle.com/technology/software/products/berkeley-db/db/index.html"),
+dkT(""),
+dkT("Copyright and license:"),
+dkT(""),
+dkT("The following is the license that applies to this copy of the Berkeley DB"),
+dkT("software. For a license to use the Berkeley DB software under conditions"),
+dkT("other than those described here, or to purchase support for this software,"),
+dkT("please contact Oracle at berkeleydb-info_us@oracle.com."),
+dkT(""),
+dkT("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="),
+dkT("/*"),
+dkT(" * Copyright (c) 1990, 2010 Oracle and/or its affiliates. All rights reserved."),
+dkT(" *"),
+dkT(" * Redistribution and use in source and binary forms, with or without"),
+dkT(" * modification, are permitted provided that the following conditions"),
+dkT(" * are met:"),
+dkT(" * 1. Redistributions of source code must retain the above copyright"),
+dkT(" * notice, this list of conditions and the following disclaimer."),
+dkT(" * 2. Redistributions in binary form must reproduce the above copyright"),
+dkT(" * notice, this list of conditions and the following disclaimer in the"),
+dkT(" * documentation and/or other materials provided with the distribution."),
+dkT(" * 3. Redistributions in any form must be accompanied by information on"),
+dkT(" * how to obtain complete source code for the DB software and any"),
+dkT(" * accompanying software that uses the DB software. The source code"),
+dkT(" * must either be included in the distribution or be available for no"),
+dkT(" * more than the cost of distribution plus a nominal fee, and must be"),
+dkT(" * freely redistributable under reasonable conditions. For an"),
+dkT(" * executable file, complete source code means the source code for all"),
+dkT(" * modules it contains. It does not include source code for modules or"),
+dkT(" * files that typically accompany the major components of the operating"),
+dkT(" * system on which the executable file runs."),
+dkT(" *"),
+dkT(" * THIS SOFTWARE IS PROVIDED BY ORACLE ``AS IS'' AND ANY EXPRESS OR"),
+dkT(" * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED"),
+dkT(" * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR"),
+dkT(" * NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL ORACLE BE LIABLE"),
+dkT(" * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR"),
+dkT(" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF"),
+dkT(" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR"),
+dkT(" * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,"),
+dkT(" * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE"),
+dkT(" * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN"),
+dkT(" * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+dkT(" */"),
+dkT("/*"),
+dkT(" * Copyright (c) 1990, 1993, 1994, 1995"),
+dkT(" *\tThe Regents of the University of California. All rights reserved."),
+dkT(" *"),
+dkT(" * Redistribution and use in source and binary forms, with or without"),
+dkT(" * modification, are permitted provided that the following conditions"),
+dkT(" * are met:"),
+dkT(" * 1. Redistributions of source code must retain the above copyright"),
+dkT(" * notice, this list of conditions and the following disclaimer."),
+dkT(" * 2. Redistributions in binary form must reproduce the above copyright"),
+dkT(" * notice, this list of conditions and the following disclaimer in the"),
+dkT(" * documentation and/or other materials provided with the distribution."),
+dkT(" * 3. Neither the name of the University nor the names of its contributors"),
+dkT(" * may be used to endorse or promote products derived from this software"),
+dkT(" * without specific prior written permission."),
+dkT(" *"),
+dkT(" * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND"),
+dkT(" * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT(" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT(" * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE"),
+dkT(" * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT(" * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS"),
+dkT(" * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)"),
+dkT(" * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT"),
+dkT(" * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY"),
+dkT(" * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF"),
+dkT(" * SUCH DAMAGE."),
+dkT(" */"),
+dkT("/*"),
+dkT(" * Copyright (c) 1995, 1996"),
+dkT(" *\tThe President and Fellows of Harvard University. All rights reserved."),
+dkT(" *"),
+dkT(" * Redistribution and use in source and binary forms, with or without"),
+dkT(" * modification, are permitted provided that the following conditions"),
+dkT(" * are met:"),
+dkT(" * 1. Redistributions of source code must retain the above copyright"),
+dkT(" * notice, this list of conditions and the following disclaimer."),
+dkT(" * 2. Redistributions in binary form must reproduce the above copyright"),
+dkT(" * notice, this list of conditions and the following disclaimer in the"),
+dkT(" * documentation and/or other materials provided with the distribution."),
+dkT(" * 3. Neither the name of the University nor the names of its contributors"),
+dkT(" * may be used to endorse or promote products derived from this software"),
+dkT(" * without specific prior written permission."),
+dkT(" *"),
+dkT(" * THIS SOFTWARE IS PROVIDED BY HARVARD AND ITS CONTRIBUTORS ``AS IS'' AND"),
+dkT(" * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT(" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT(" * ARE DISCLAIMED. IN NO EVENT SHALL HARVARD OR ITS CONTRIBUTORS BE LIABLE"),
+dkT(" * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT(" * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS"),
+dkT(" * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)"),
+dkT(" * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT"),
+dkT(" * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY"),
+dkT(" * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF"),
+dkT(" * SUCH DAMAGE."),
+dkT(" */"),
+dkT("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="),
+dkT("/***"),
+dkT(" * ASM: a very small and fast Java bytecode manipulation framework"),
+dkT(" * Copyright (c) 2000-2005 INRIA, France Telecom"),
+dkT(" * All rights reserved."),
+dkT(" *"),
+dkT(" * Redistribution and use in source and binary forms, with or without"),
+dkT(" * modification, are permitted provided that the following conditions"),
+dkT(" * are met:"),
+dkT(" * 1. Redistributions of source code must retain the above copyright"),
+dkT(" * notice, this list of conditions and the following disclaimer."),
+dkT(" * 2. Redistributions in binary form must reproduce the above copyright"),
+dkT(" * notice, this list of conditions and the following disclaimer in the"),
+dkT(" * documentation and/or other materials provided with the distribution."),
+dkT(" * 3. Neither the name of the copyright holders nor the names of its"),
+dkT(" * contributors may be used to endorse or promote products derived from"),
+dkT(" * this software without specific prior written permission."),
+dkT(" *"),
+dkT(" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\""),
+dkT(" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT(" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT(" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE"),
+dkT(" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR"),
+dkT(" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF"),
+dkT(" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS"),
+dkT(" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN"),
+dkT(" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)"),
+dkT(" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF"),
+dkT(" * THE POSSIBILITY OF SUCH DAMAGE."),
+dkT(" */"),
+#endif
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT(""),
+dkT("Zlib license"),
+dkT("============"),
+dkT("(C) 1995-2004 Jean-loup Gailly and Mark Adler"),
+dkT(""),
+dkT("This software is provided 'as-is', without any express or implied"),
+dkT("warranty. In no event will the authors be held liable for any damages"),
+dkT("arising from the use of this software."),
+dkT(""),
+dkT("Permission is granted to anyone to use this software for any purpose,"),
+dkT("including commercial applications, and to alter it and redistribute it"),
+dkT("freely, subject to the following restrictions:"),
+dkT(""),
+dkT("1. The origin of this software must not be misrepresented; you must not"),
+dkT(" claim that you wrote the original software. If you use this software"),
+dkT(" in a product, an acknowledgment in the product documentation would be"),
+dkT(" appreciated but is not required."),
+dkT("2. Altered source versions must be plainly marked as such, and must not be"),
+dkT(" misrepresented as being the original software."),
+dkT("3. This notice may not be removed or altered from any source distribution."),
+dkT(""),
+dkT("Jean-loup Gailly Mark Adler"),
+dkT("jloup@gzip.org madler@alumni.caltech.edu"),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT(""),
+dkT("Bzip2 and libbzip2 library license"),
+dkT("=================================="),
+dkT("This program, \"bzip2\", the associated library \"libbzip2\", and all"),
+dkT("documentation, are copyright (C) 1996-2007 Julian R Seward. All"),
+dkT("rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions"),
+dkT("are met:"),
+dkT(""),
+dkT("1. Redistributions of source code must retain the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer."),
+dkT(""),
+dkT("2. The origin of this software must not be misrepresented; you must "),
+dkT(" not claim that you wrote the original software. If you use this "),
+dkT(" software in a product, an acknowledgment in the product "),
+dkT(" documentation would be appreciated but is not required."),
+dkT(""),
+dkT("3. Altered source versions must be plainly marked as such, and must"),
+dkT(" not be misrepresented as being the original software."),
+dkT(""),
+dkT("4. The name of the author may not be used to endorse or promote "),
+dkT(" products derived from this software without specific prior written "),
+dkT(" permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS"),
+dkT("OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED"),
+dkT("WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE"),
+dkT("GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS"),
+dkT("INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,"),
+dkT("WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS"),
+dkT("SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+dkT(""),
+dkT("Julian Seward, jseward@bzip.org"),
+dkT("bzip2/libbzip2 version 1.0.5 of 10 December 2007"),
+#endif
+NULL
+
+
+#line 353 "dk-dbco.ctr"
+};
+
+
+
+/** Short help text.
+*/
+static const dkChar * const help_text[] = {
+dkT(""),
+dkT("dk-dbco - Copy and convert simple databases"),
+dkT("-------------------------------------------"),
+dkT(""),
+dkT("dk-dbco <source> <destination>"),
+dkT(""),
+dkT("Options:"),
+dkT(""),
+dkT("-a\t\t--add\t\t\t\tModify existing database."),
+dkT("-k <size>\t--key-size=<size>\t\tKey buffer size."),
+dkT("-v <size>\t--value-buffer-size=<size>\tValue buffer size."),
+dkT("\t\t\t\t\t\tDefault for both: 256."),
+dkT(""),
+dkT("--help\t\t\t\t\t\tShow short help text."),
+dkT("--manual\t\t\t\t\t*** SHOW FULL MANUAL ***"),
+dkT("--version\t\t\t\t\tShow version information."),
+dkT("--license\t\t\t\t\tShow license information."),
+dkT(""),
+NULL
+
+
+#line 380 "dk-dbco.ctr"
+};
+
+
+
+/** Version text.
+*/
+static const dkChar version_text[] = {
+ DKT_VERSION_DK
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+ dkT(" bdb")
+#endif
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+ dkT(" ndbm")
+#endif
+ dkT(" mem")
+};
+
+
+
+static const dkChar * const dk_dbco_kwnl[] = {
+/* 0 */
+dkT("dktools"),
+
+/* 1 */
+dkT("dk-dbco.txt"),
+
+/* 2 */
+dkT("dk-dbco.str"),
+
+/* 3 */
+dkT("ERROR: Application startup failed!\n"),
+
+/* 4 */
+dkT("db.key.max-size"),
+
+/* 5 */
+dkT("db.value.max-size"),
+
+NULL
+
+
+#line 423 "dk-dbco.ctr"
+};
+
+
+
+/** Constant texts used by the module, replaced by localized
+ versions if available.
+*/
+static const dkChar * const dk_dbco_kw_def[] = {
+/* 0 */
+dkT("Failed to set up signal handlers!"),
+
+/* 1 */
+dkT("Failed to restore previous signal handlers!"),
+
+/* 2 */
+dkT("Failed to write record!"),
+
+/* 3 */
+dkT("Missing source database name!"),
+
+/* 4 */
+dkT("Missing destination database name!"),
+
+/* 5 */
+dkT("Failed to close database (synchronizing to disk failed)!"),
+
+/* 6 */
+dkT("Source and destination database are required!"),
+
+/* 7 */
+dkT("Aborted by signal!"),
+
+NULL
+
+
+#line 465 "dk-dbco.ctr"
+};
+
+
+
+/** Options.
+*/
+static const dk4_option_specification_t dk_dbco_options[] = {
+ { dkT('a'), dkT("add"), DK4_OPT_ARG_NONE } ,
+ { dkT('k'), dkT("key-buffer-size"), DK4_OPT_ARG_SIZE } ,
+ { dkT('v'), dkT("value-buffer-size"), DK4_OPT_ARG_SIZE } ,
+ { dkT('R'), dkT("reset"), DK4_OPT_ARG_NONE }
+};
+
+
+
+/** Buffer for key.
+*/
+char kb[4096];
+
+
+/** Buffer for value.
+*/
+char vb[4096];
+
+
+
+/** Key buffer to use.
+*/
+static char *pkb = kb;
+
+
+
+/** Value buffer to use.
+*/
+static char *pvb = vb;
+
+
+
+/** Allocated key buffer for large sizes.
+*/
+static char *akb = NULL;
+
+
+
+/** Allocated value buffer for large sizes.
+*/
+static char *avb = NULL;
+
+/** Array of constant text strings, use localized version if
+ available.
+*/
+static const dkChar * const * dk_dbco_msg = dk_dbco_kw_def;
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Number of options in the dk_dbco_options array.
+*/
+static const size_t dk_dbco_sz_options =
+sizeof(dk_dbco_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Number of keywords in the dk_dbco_msg array.
+*/
+static size_t dk_dbco_sz_msg =
+(sizeof(dk_dbco_kw_def)/sizeof(DK4_PDKCHAR) - 1);
+
+
+
+/** Size of key buffer to use.
+*/
+static size_t ks = sizeof(kb);
+
+
+
+/** Size of value buffer to use.
+*/
+static size_t vs = sizeof(vb);
+
+
+
+/** Exit status code.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+/** Flag: Truncate existing destination database.
+*/
+static int trunc = 1;
+
+
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+/** Pass a volatile pointer to an atomic integer.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ptr Address of atomic integer variable.
+ @return The unmodified pointer.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+
+
+/** Check whether we can continue or if a signal was received.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(void)
+{
+ int back = 1;
+ if (0 != sig_read_atomic(&sig_had_int )) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+/** Function to traverse a simple database.
+ The function must check the kb, ks, vb and vs arguments
+ for validity, they are passed as found by the backend
+ functions (this means pointers may be NULL, sizes may be 0).
+ @param Object modified during traversal, may be NULL.
+ @param kb Key data.
+ @param ks Key size.
+ @param vb Value data.
+ @param vs Value size.
+ @return 1 on success, 0 on error (can continue), -1 on error (abort).
+*/
+static
+int
+dk_dbco_traverse_fct(
+ void *obj,
+ const void *mykb,
+ size_t myks,
+ const void *myvb,
+ size_t myvs
+)
+{
+ dk4_dbi_t *dbidst;
+ int back = 0;
+
+
+
+#line 677 "dk-dbco.ctr"
+ dbidst = (dk4_dbi_t *)obj;
+ if (0 != sig_can_continue()) {
+ if ((NULL != mykb) && (NULL != myvb) && (0 < myks) && (0 < myvs)) {
+
+
+#line 681 "dk-dbco.ctr"
+ back = dk4dbi_set(dbidst, mykb, myks, myvb, myvs, NULL);
+ if (1 != back) {
+
+#line 683 "dk-dbco.ctr"
+ /* ERROR: Failed to set entry */
+ dk4app_log_1(app, dk_dbco_msg, dk_dbco_sz_msg, DK4_LL_ERROR, 2);
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 688 "dk-dbco.ctr"
+ }
+#endif
+ }
+ } else {
+ back = -1;
+
+#line 693 "dk-dbco.ctr"
+ }
+
+
+#line 695 "dk-dbco.ctr"
+ return back;
+}
+
+
+
+static
+void
+dk_dbco_copy_all_entries(dk4_dbi_t *dbisrc, dk4_dbi_t *dbidst)
+{
+ int res;
+
+
+#line 706 "dk-dbco.ctr"
+ res = dk4dbi_traverse(dbisrc, (void *)dbidst, dk_dbco_traverse_fct);
+ if (1 == res) {
+ exval = EXIT_SUCCESS;
+
+#line 709 "dk-dbco.ctr"
+ }
+
+#line 710 "dk-dbco.ctr"
+}
+
+
+
+static
+void
+dk_dbco_run_with_filenames(void)
+{
+ dk4_er_t er;
+ dk4_dbi_t *dbisrc = NULL;
+ dk4_dbi_t *dbidst = NULL;
+ const dkChar *fnsrc = NULL;
+ const dkChar *fndst = NULL;
+ size_t i;
+
+
+#line 725 "dk-dbco.ctr"
+ /* Process preferences and options
+ */
+ if (0 != dk4app_opt_is_set_short(app, dkT('R'), NULL)) {
+ if (0 != dk4app_pref_get_size(&i, app, dk_dbco_kwnl[4], 0)) {
+ ks = i;
+ }
+ if (0 != dk4app_pref_get_size(&i, app, dk_dbco_kwnl[5], 0)) {
+ vs = i;
+ }
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('k'), NULL)) {
+ if (0 != dk4app_opt_get_size_short(&i, app, dkT('k'), NULL)) {
+ ks = i;
+ }
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('v'), NULL)) {
+ if (0 != dk4app_opt_get_size_short(&i, app, dkT('v'), NULL)) {
+ vs = i;
+ }
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('a'), NULL)) {
+ trunc = 0;
+ }
+
+
+#line 749 "dk-dbco.ctr"
+
+ /* Allocate memory if necessary
+ */
+ if (sizeof(kb) < ks) {
+ akb = dk4mem_new_app(char,ks,app);
+ if (NULL != akb) {
+ pkb = akb;
+ } else {
+ goto finished;
+ }
+ }
+ if (sizeof(vb) < vs) {
+ avb = dk4mem_new_app(char,vs,app);
+ if (NULL != avb) {
+ pvb = avb;
+ } else {
+ goto finished;
+ }
+ }
+
+
+#line 769 "dk-dbco.ctr"
+
+ /* Open databases
+ */
+ fnsrc = dk4app_get_argv(app, 0);
+ if (NULL == fnsrc) {
+ /* ERROR: Missing source file name */
+ dk4app_log_1(app, dk_dbco_msg, dk_dbco_sz_msg, DK4_LL_ERROR, 3);
+ goto finished;
+ }
+ fndst = dk4app_get_argv(app, 1);
+ if (NULL == fndst) {
+ /* ERROR: Missing destination file name */
+ dk4app_log_1(app, dk_dbco_msg, dk_dbco_sz_msg, DK4_LL_ERROR, 4);
+ goto finished;
+ }
+
+
+#line 785 "dk-dbco.ctr"
+ dbisrc = dk4dbi_open_sizes_app(fnsrc, 0, 0, ks, vs, NULL, app);
+ if (NULL == dbisrc) {
+ goto finished;
+ }
+ if (0 == sig_can_continue()) {
+ goto finished;
+ }
+ dbidst = dk4dbi_open_sizes_app(fndst, 1, trunc, ks, vs, NULL, app);
+ if (NULL == dbidst) {
+ goto finished;
+ }
+
+
+#line 797 "dk-dbco.ctr"
+
+ /* Run processing
+ */
+ dk_dbco_copy_all_entries(dbisrc, dbidst);
+
+ finished:
+ /* Cleanup
+ */
+ if (NULL != dbidst) {
+ dk4error_init(&er);
+ if (0 == dk4dbi_close(dbidst, &er)) {
+ /* ERROR: Failed to close database */
+ dk4app_log_1(app, dk_dbco_msg, dk_dbco_sz_msg, DK4_LL_ERROR, 5);
+ exval = EXIT_FAILURE;
+ }
+ }
+ if (NULL != dbisrc) {
+ dk4dbi_close(dbisrc, NULL);
+ }
+ dk4mem_release(avb) ;
+ dk4mem_release(akb) ;
+
+
+#line 819 "dk-dbco.ctr"
+}
+
+
+
+static
+void
+dk_dbco_normal_run(void)
+{
+
+
+#line 828 "dk-dbco.ctr"
+ if (2 == dk4app_get_argc(app)) {
+ dk_dbco_run_with_filenames();
+ } else {
+ /* ERROR: Must have source and destination database! */
+ dk4app_log_1(app, dk_dbco_msg, dk_dbco_sz_msg, DK4_LL_ERROR, 6);
+ }
+
+
+#line 835 "dk-dbco.ctr"
+}
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+dk_dbco_run_with_signal_handlers(void)
+{
+ struct sigaction oint;
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+ int success = 0;
+
+ /* Set up signal handling for SIGINT.
+ */
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_dbco_msg, dk_dbco_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_dbco_msg, dk_dbco_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, dk_dbco_msg, dk_dbco_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_dbco_msg, dk_dbco_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_dbco_msg, dk_dbco_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, dk_dbco_msg, dk_dbco_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ dk_dbco_normal_run();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, dk_dbco_msg, dk_dbco_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_dbco_msg, dk_dbco_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+dk_dbco_run_with_signal_handlers(void)
+{
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ dk_dbco_normal_run();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+dk_dbco_run_with_signal_handlers(void)
+{
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ dk_dbco_normal_run();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+dk_dbco_run_with_signal_handlers(void)
+{
+ dk_dbco_normal_run();
+}
+#endif
+#endif
+#endif
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ int hvl = 0; /* Flag: Help, version, license */
+
+
+#line 981 "dk-dbco.ctr"
+
+
+#line 982 "dk-dbco.ctr"
+ dk4fput_initialize_stderr();
+ app = dk4app_open_cmd(
+ argc, argv,
+ dk_dbco_options, dk_dbco_sz_options,
+ dk_dbco_kwnl[0], version_text,
+ dk_dbco_kwnl[1], help_text, license_text
+ );
+ if (NULL != app) {
+ dk_dbco_sz_msg = dk4app_string_table_size(dk_dbco_kw_def);
+ dk_dbco_msg = dk4app_string_table(app, dk_dbco_kwnl[2], dk_dbco_kw_def);
+ if (0 != dk4app_can_run_normally(app)) {
+ dk_dbco_run_with_signal_handlers();
+ if (0 != sig_read_atomic(&sig_had_int )) {
+ /* ERROR: Aborted by signal! */
+ dk4app_log_1(app, dk_dbco_msg, dk_dbco_sz_msg, DK4_LL_ERROR, 7);
+ exval = EXIT_FAILURE;
+ }
+ if (0 != sig_read_atomic(&sig_had_term)) {
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ hvl = 1;
+ dk4fput_initialize_stdout();
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ dk4app_close(app);
+ } else {
+ dk4fputs(dk_dbco_kwnl[3], stderr, NULL);
+ }
+ if (0 != hvl) {
+ fflush(stdout);
+ }
+ fflush(stderr);
+ if (0 != hvl) {
+ dk4fput_cleanup_stdout();
+ }
+ dk4fput_cleanup_stderr();
+
+
+#line 1022 "dk-dbco.ctr"
+
+
+#line 1023 "dk-dbco.ctr"
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/dk-dbco.ctr b/support/dktools/dk-dbco.ctr
new file mode 100644
index 0000000000..6bca35ec5b
--- /dev/null
+++ b/support/dktools/dk-dbco.ctr
@@ -0,0 +1,1025 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4const.h"
+#include "dk4numco.h"
+#include "dk4vers.h"
+#include "dk4mem.h"
+#include "dk4opt.h"
+#include "dk4aopt.h"
+#include "dk4app.h"
+#include "dk4mema.h"
+#include "dk4dbi.h"
+#include "dk4dbia.h"
+#include "dk4fput.h"
+
+
+
+$!trace-include
+
+
+
+/** License conditions.
+*/
+static const dkChar * const license_text[] = {
+$!text macro=dkT,preprocessor
+
+This software uses code from the following projects, either directly or as
+a library:
+
+dktools Dirk Krause's tools and libraries.
+ See http://dktools.sourceforge.net/ for more information.
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+
+Berkeley DB Database library.
+#endif
+#if DK4_HAVE_ZLIB_H
+
+zlib Data compression library.
+ See http://www.zlib.net/ for more information.
+#endif
+#if DK4_HAVE_BZLIB_H
+
+bzip2 Data compression program and library.
+ See http://www.bzip.org/ for more information.
+#endif
+
+All the licenses below apply to the program.
+Licenses for used libraries are shown as found on my Scientific Linux 6.x
+computer in the /usr/share/doc directory on 2015-04-01. Check the project
+homepages of the used libraries for additional information and/or updated
+license terms.
+
+
+DK tools and libraries license
+==============================
+Copyright (c) 2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+
+
+Berkeley DB license
+===================
+This package was debianized by Clint Adams <schizo@debian.org> on
+Wed, 25 Jul 2007 20:37:51 +0700
+
+It was downloaded from
+http://www.oracle.com/technology/software/products/berkeley-db/db/index.html
+
+Copyright and license:
+
+The following is the license that applies to this copy of the Berkeley DB
+software. For a license to use the Berkeley DB software under conditions
+other than those described here, or to purchase support for this software,
+please contact Oracle at berkeleydb-info_us@oracle.com.
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+/*
+ * Copyright (c) 1990, 2010 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Redistributions in any form must be accompanied by information on
+ * how to obtain complete source code for the DB software and any
+ * accompanying software that uses the DB software. The source code
+ * must either be included in the distribution or be available for no
+ * more than the cost of distribution plus a nominal fee, and must be
+ * freely redistributable under reasonable conditions. For an
+ * executable file, complete source code means the source code for all
+ * modules it contains. It does not include source code for modules or
+ * files that typically accompany the major components of the operating
+ * system on which the executable file runs.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ORACLE ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ * NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL ORACLE BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * Copyright (c) 1990, 1993, 1994, 1995
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * Copyright (c) 1995, 1996
+ * The President and Fellows of Harvard University. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY HARVARD AND ITS CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HARVARD OR ITS CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#endif
+#if DK4_HAVE_ZLIB_H
+
+
+Zlib license
+============
+(C) 1995-2004 Jean-loup Gailly and Mark Adler
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+
+Jean-loup Gailly Mark Adler
+jloup@gzip.org madler@alumni.caltech.edu
+#endif
+#if DK4_HAVE_BZLIB_H
+
+
+Bzip2 and libbzip2 library license
+==================================
+This program, "bzip2", the associated library "libbzip2", and all
+documentation, are copyright (C) 1996-2007 Julian R Seward. All
+rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+3. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Julian Seward, jseward@bzip.org
+bzip2/libbzip2 version 1.0.5 of 10 December 2007
+#endif
+$!end
+};
+
+
+
+/** Short help text.
+*/
+static const dkChar * const help_text[] = {
+$!text macro=dkT
+
+dk-dbco - Copy and convert simple databases
+-------------------------------------------
+
+dk-dbco <source> <destination>
+
+Options:
+
+-a --add Modify existing database.
+-k <size> --key-size=<size> Key buffer size.
+-v <size> --value-buffer-size=<size> Value buffer size.
+ Default for both: 256.
+
+--help Show short help text.
+--manual *** SHOW FULL MANUAL ***
+--version Show version information.
+--license Show license information.
+
+$!end
+};
+
+
+
+/** Version text.
+*/
+static const dkChar version_text[] = {
+ DKT_VERSION_DK
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+ dkT(" bdb")
+#endif
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+ dkT(" ndbm")
+#endif
+ dkT(" mem")
+};
+
+
+
+static const dkChar * const dk_dbco_kwnl[] = {
+$!string-table macro=dkT
+#
+# 0 Program group name
+#
+dktools
+#
+# 1 Help text file name
+#
+dk-dbco.txt
+#
+# 2 String table file name
+#
+dk-dbco.str
+#
+# 3 ERROR: Application startup failed!
+#
+ERROR: Application startup failed!\n
+#
+# 4 5 Preference names for key and value size
+#
+db.key.max-size
+db.value.max-size
+$!end
+};
+
+
+
+/** Constant texts used by the module, replaced by localized
+ versions if available.
+*/
+static const dkChar * const dk_dbco_kw_def[] = {
+$!string-table macro=dkT
+#
+# 0 Error: Failed to set up signal handlers!
+#
+Failed to set up signal handlers!
+#
+# 1 Error: Failed to restore previous signal handlers!
+#
+Failed to restore previous signal handlers!
+#
+# 2 Error: Failed to write record!
+#
+Failed to write record!
+#
+# 3 Error: Missing source database name!
+#
+Missing source database name!
+#
+# 4 Error: Missing destination database name!
+#
+Missing destination database name!
+#
+# 5 Error: Failed to close database (final write attempt failed)!
+#
+Failed to close database (synchronizing to disk failed)!
+#
+# 6 Error: Source and destination database are required!
+#
+Source and destination database are required!
+#
+# 7 Error: Aborted by signal!
+#
+Aborted by signal!
+$!end
+};
+
+
+
+/** Options.
+*/
+static const dk4_option_specification_t dk_dbco_options[] = {
+ { dkT('a'), dkT("add"), DK4_OPT_ARG_NONE } ,
+ { dkT('k'), dkT("key-buffer-size"), DK4_OPT_ARG_SIZE } ,
+ { dkT('v'), dkT("value-buffer-size"), DK4_OPT_ARG_SIZE } ,
+ { dkT('R'), dkT("reset"), DK4_OPT_ARG_NONE }
+};
+
+
+
+/** Buffer for key.
+*/
+char kb[4096];
+
+
+/** Buffer for value.
+*/
+char vb[4096];
+
+
+
+/** Key buffer to use.
+*/
+static char *pkb = kb;
+
+
+
+/** Value buffer to use.
+*/
+static char *pvb = vb;
+
+
+
+/** Allocated key buffer for large sizes.
+*/
+static char *akb = NULL;
+
+
+
+/** Allocated value buffer for large sizes.
+*/
+static char *avb = NULL;
+
+/** Array of constant text strings, use localized version if
+ available.
+*/
+static const dkChar * const * dk_dbco_msg = dk_dbco_kw_def;
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Number of options in the dk_dbco_options array.
+*/
+static const size_t dk_dbco_sz_options =
+sizeof(dk_dbco_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Number of keywords in the dk_dbco_msg array.
+*/
+static size_t dk_dbco_sz_msg =
+(sizeof(dk_dbco_kw_def)/sizeof(DK4_PDKCHAR) - 1);
+
+
+
+/** Size of key buffer to use.
+*/
+static size_t ks = sizeof(kb);
+
+
+
+/** Size of value buffer to use.
+*/
+static size_t vs = sizeof(vb);
+
+
+
+/** Exit status code.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+/** Flag: Truncate existing destination database.
+*/
+static int trunc = 1;
+
+
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+/** Pass a volatile pointer to an atomic integer.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ptr Address of atomic integer variable.
+ @return The unmodified pointer.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+
+
+/** Check whether we can continue or if a signal was received.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(void)
+{
+ int back = 1;
+ if (0 != sig_read_atomic(&sig_had_int )) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+/** Function to traverse a simple database.
+ The function must check the kb, ks, vb and vs arguments
+ for validity, they are passed as found by the backend
+ functions (this means pointers may be NULL, sizes may be 0).
+ @param Object modified during traversal, may be NULL.
+ @param kb Key data.
+ @param ks Key size.
+ @param vb Value data.
+ @param vs Value size.
+ @return 1 on success, 0 on error (can continue), -1 on error (abort).
+*/
+static
+int
+dk_dbco_traverse_fct(
+ void *obj,
+ const void *mykb,
+ size_t myks,
+ const void *myvb,
+ size_t myvs
+)
+{
+ dk4_dbi_t *dbidst;
+ int back = 0;
+
+ $? "+ dk_dbco_traverse_fct"
+ dbidst = (dk4_dbi_t *)obj;
+ if (0 != sig_can_continue()) {
+ if ((NULL != mykb) && (NULL != myvb) && (0 < myks) && (0 < myvs)) {
+ $? ". buffers and sizes ok"
+ back = dk4dbi_set(dbidst, mykb, myks, myvb, myvs, NULL);
+ if (1 != back) { $? "! failed to write record"
+ /* ERROR: Failed to set entry */
+ dk4app_log_1(app, dk_dbco_msg, dk_dbco_sz_msg, DK4_LL_ERROR, 2);
+ }
+#if TRACE_DEBUG
+ else { $? ". record written successfully"
+ }
+#endif
+ }
+ } else {
+ back = -1; $? "! aborted by signal"
+ }
+ $? "- dk_dbco_traverse_fct %d", back
+ return back;
+}
+
+
+
+static
+void
+dk_dbco_copy_all_entries(dk4_dbi_t *dbisrc, dk4_dbi_t *dbidst)
+{
+ int res;
+ $? "+ dk_dbco_copy_all_entries"
+ res = dk4dbi_traverse(dbisrc, (void *)dbidst, dk_dbco_traverse_fct);
+ if (1 == res) {
+ exval = EXIT_SUCCESS; $? ". success"
+ } $? "- dk_dbco_copy_all_entries"
+}
+
+
+
+static
+void
+dk_dbco_run_with_filenames(void)
+{
+ dk4_er_t er;
+ dk4_dbi_t *dbisrc = NULL;
+ dk4_dbi_t *dbidst = NULL;
+ const dkChar *fnsrc = NULL;
+ const dkChar *fndst = NULL;
+ size_t i;
+ $? "+ dk_dbco_run_with_filenames"
+ /* Process preferences and options
+ */
+ if (0 != dk4app_opt_is_set_short(app, dkT('R'), NULL)) {
+ if (0 != dk4app_pref_get_size(&i, app, dk_dbco_kwnl[4], 0)) {
+ ks = i;
+ }
+ if (0 != dk4app_pref_get_size(&i, app, dk_dbco_kwnl[5], 0)) {
+ vs = i;
+ }
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('k'), NULL)) {
+ if (0 != dk4app_opt_get_size_short(&i, app, dkT('k'), NULL)) {
+ ks = i;
+ }
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('v'), NULL)) {
+ if (0 != dk4app_opt_get_size_short(&i, app, dkT('v'), NULL)) {
+ vs = i;
+ }
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('a'), NULL)) {
+ trunc = 0;
+ }
+ $? ". preferences and options processed"
+
+ /* Allocate memory if necessary
+ */
+ if (sizeof(kb) < ks) {
+ akb = dk4mem_new_app(char,ks,app);
+ if (NULL != akb) {
+ pkb = akb;
+ } else {
+ goto finished;
+ }
+ }
+ if (sizeof(vb) < vs) {
+ avb = dk4mem_new_app(char,vs,app);
+ if (NULL != avb) {
+ pvb = avb;
+ } else {
+ goto finished;
+ }
+ }
+ $? ". buffers available"
+
+ /* Open databases
+ */
+ fnsrc = dk4app_get_argv(app, 0);
+ if (NULL == fnsrc) {
+ /* ERROR: Missing source file name */
+ dk4app_log_1(app, dk_dbco_msg, dk_dbco_sz_msg, DK4_LL_ERROR, 3);
+ goto finished;
+ }
+ fndst = dk4app_get_argv(app, 1);
+ if (NULL == fndst) {
+ /* ERROR: Missing destination file name */
+ dk4app_log_1(app, dk_dbco_msg, dk_dbco_sz_msg, DK4_LL_ERROR, 4);
+ goto finished;
+ }
+ $? ". database names found"
+ dbisrc = dk4dbi_open_sizes_app(fnsrc, 0, 0, ks, vs, NULL, app);
+ if (NULL == dbisrc) {
+ goto finished;
+ }
+ if (0 == sig_can_continue()) {
+ goto finished;
+ }
+ dbidst = dk4dbi_open_sizes_app(fndst, 1, trunc, ks, vs, NULL, app);
+ if (NULL == dbidst) {
+ goto finished;
+ }
+ $? ". databases opened"
+
+ /* Run processing
+ */
+ dk_dbco_copy_all_entries(dbisrc, dbidst);
+
+ finished:
+ /* Cleanup
+ */
+ if (NULL != dbidst) {
+ dk4error_init(&er);
+ if (0 == dk4dbi_close(dbidst, &er)) {
+ /* ERROR: Failed to close database */
+ dk4app_log_1(app, dk_dbco_msg, dk_dbco_sz_msg, DK4_LL_ERROR, 5);
+ exval = EXIT_FAILURE;
+ }
+ }
+ if (NULL != dbisrc) {
+ dk4dbi_close(dbisrc, NULL);
+ }
+ dk4mem_release(avb) ;
+ dk4mem_release(akb) ;
+ $? "- dk_dbco_run_with_filenames"
+}
+
+
+
+static
+void
+dk_dbco_normal_run(void)
+{
+ $? "+ dk_dbco_normal_run"
+ if (2 == dk4app_get_argc(app)) {
+ dk_dbco_run_with_filenames();
+ } else {
+ /* ERROR: Must have source and destination database! */
+ dk4app_log_1(app, dk_dbco_msg, dk_dbco_sz_msg, DK4_LL_ERROR, 6);
+ }
+ $? "- dk_dbco_normal_run"
+}
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+dk_dbco_run_with_signal_handlers(void)
+{
+ struct sigaction oint;
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+ int success = 0;
+
+ /* Set up signal handling for SIGINT.
+ */
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_dbco_msg, dk_dbco_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_dbco_msg, dk_dbco_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, dk_dbco_msg, dk_dbco_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_dbco_msg, dk_dbco_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_dbco_msg, dk_dbco_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, dk_dbco_msg, dk_dbco_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ dk_dbco_normal_run();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, dk_dbco_msg, dk_dbco_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_dbco_msg, dk_dbco_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+dk_dbco_run_with_signal_handlers(void)
+{
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ dk_dbco_normal_run();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+dk_dbco_run_with_signal_handlers(void)
+{
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ dk_dbco_normal_run();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+dk_dbco_run_with_signal_handlers(void)
+{
+ dk_dbco_normal_run();
+}
+#endif
+#endif
+#endif
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ int hvl = 0; /* Flag: Help, version, license */
+ $!trace-init dk-dbco.deb
+ $? "+ main"
+ dk4fput_initialize_stderr();
+ app = dk4app_open_cmd(
+ argc, argv,
+ dk_dbco_options, dk_dbco_sz_options,
+ dk_dbco_kwnl[0], version_text,
+ dk_dbco_kwnl[1], help_text, license_text
+ );
+ if (NULL != app) {
+ dk_dbco_sz_msg = dk4app_string_table_size(dk_dbco_kw_def);
+ dk_dbco_msg = dk4app_string_table(app, dk_dbco_kwnl[2], dk_dbco_kw_def);
+ if (0 != dk4app_can_run_normally(app)) {
+ dk_dbco_run_with_signal_handlers();
+ if (0 != sig_read_atomic(&sig_had_int )) {
+ /* ERROR: Aborted by signal! */
+ dk4app_log_1(app, dk_dbco_msg, dk_dbco_sz_msg, DK4_LL_ERROR, 7);
+ exval = EXIT_FAILURE;
+ }
+ if (0 != sig_read_atomic(&sig_had_term)) {
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ hvl = 1;
+ dk4fput_initialize_stdout();
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ dk4app_close(app);
+ } else {
+ dk4fputs(dk_dbco_kwnl[3], stderr, NULL);
+ }
+ if (0 != hvl) {
+ fflush(stdout);
+ }
+ fflush(stderr);
+ if (0 != hvl) {
+ dk4fput_cleanup_stdout();
+ }
+ dk4fput_cleanup_stderr();
+ $? "- main %d", exval
+ $!trace-end
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/dk-dbco.rc b/support/dktools/dk-dbco.rc
new file mode 100644
index 0000000000..6c85246c51
--- /dev/null
+++ b/support/dktools/dk-dbco.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Copy and convert simple databases\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "Copy and convert simple databases\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "dk-dbco\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/dk-eradisk.c b/support/dktools/dk-eradisk.c
new file mode 100644
index 0000000000..4fd431a1d0
--- /dev/null
+++ b/support/dktools/dk-eradisk.c
@@ -0,0 +1,959 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk-eradisk.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk-eradisk.c The dk-eradisk module.
+*/
+
+
+#line 9 "dk-eradisk.ctr"
+
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4vers.h"
+#include "dk4app.h"
+#include "dk4aopt.h"
+#include "dk4mem.h"
+#include "dk4numco.h"
+#include "dk4fdwre.h"
+
+
+
+
+
+#line 89 "dk-eradisk.ctr"
+
+
+
+/** Constant texts used by program, not localized.
+*/
+static const dkChar * const dk_eradisk_kwnl[] = {
+/* 0 */
+dkT("dktools"),
+
+/* 1 */
+dkT("dk-eradisk.txt"),
+
+/* 2 */
+dkT("dk-eradisk.str"),
+
+NULL
+
+
+#line 109 "dk-eradisk.ctr"
+};
+
+
+
+/** Constant texts used by program, replaced by localized texts
+ if available.
+*/
+static const dkChar * const dk_eradisk_kw_def[] = {
+/* 0 */
+dkT("Failed to set up signal handlers!"),
+
+/* 1 */
+dkT("Failed to restore signal handlers!"),
+
+/* 2 */
+dkT("Aborted by SIGPIPE signal!"),
+
+/* 3 */
+dkT("Aborted by SIGINT signal!"),
+
+/* 4 */
+dkT("Aborted by SIGTERM signal!"),
+
+/* 5 */
+dkT("Block size too large!"),
+
+/* 6 */
+dkT("Pass number out of range!"),
+
+/* 7 */
+dkT("Block size must not be 0!"),
+
+NULL
+
+
+#line 151 "dk-eradisk.ctr"
+};
+
+
+
+/** Default text, used if help text file is not found.
+*/
+static const dkChar * const dk_eradisk_help_text[] = {
+dkT(""),
+dkT("NAME"),
+dkT(""),
+dkT(" dk-eradisk - Generate patterns to erase disk before retiring it"),
+dkT(""),
+dkT("SYNOPSIS"),
+dkT(""),
+dkT(" dk-eradisk [<options>]"),
+dkT(""),
+dkT("DESCRIPTION"),
+dkT(""),
+dkT("The program generates a data stream to erase a disk."),
+dkT("Before retiring a disk or handing a disk over to another user one"),
+dkT("should remove all contents."),
+dkT("The output from dk-eradisk can be used as input for the ``dd'' program"),
+dkT("to savely clean a disk."),
+dkT(""),
+dkT("OPTIONS"),
+dkT(""),
+dkT("-p <number>, --pass=<number>"),
+dkT("\tPass number. Pass 0 (should be used as last pass)"),
+dkT("\tcan be used to write 0 bytes, so operating systems recognize"),
+dkT("\tthe disk as new from manufacturer."),
+dkT("\tThe pass number chooses the bit pattern, one from 0x00, 0xFF,"),
+dkT("\t0x0F, 0xF0, 0x33, 0xCC, 0x55, or 0xAA."),
+dkT("\tWhen doing multiple passes, start with the highest pass number,"),
+dkT("\tuse pass number 0 for the final pass."),
+dkT(""),
+dkT("-b <size>, --blocksize=<size>"),
+dkT("\tBlock size (default: 4096)."),
+dkT("\tThe default is suitable for traditional hard disks."),
+dkT("\tFor flash memory (i.e. SSD) you should increase the value to 1m."),
+dkT(""),
+dkT("-c <size>, --count=<size>"),
+dkT("\tNumber of blocks to write."),
+dkT("\tThe default 0 creates an endless sequence of blocks"),
+dkT("\tuntil the program is finished by signal."),
+dkT(""),
+dkT("EXIT STATUS"),
+dkT(""),
+dkT("0 on success, all other exit status codes indicate an error."),
+dkT(""),
+dkT("AUTHOR"),
+dkT(""),
+dkT("Dirk Krause"),
+dkT(""),
+dkT("COPYRIGHT AND LICENSE"),
+dkT(""),
+dkT("Run"),
+dkT(" dk-eradisk --license"),
+dkT("to see license information."),
+dkT(""),
+dkT("SEE ALSO"),
+dkT(""),
+dkT("http://dktools.sourceforge.net"),
+dkT(""),
+NULL
+
+
+#line 216 "dk-eradisk.ctr"
+};
+
+
+
+/** License conditions.
+*/
+static const dkChar * const dk_eradisk_license_text[] = {
+dkT("This software uses code from the following projects, either directly or as"),
+dkT("a library:"),
+dkT(""),
+dkT("dktools\t\tDirk Krause's tools and libraries."),
+dkT("\t\tSee http://dktools.sourceforge.net/ for more information."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT("zlib\t\tData compression library."),
+dkT("\t\tSee http://www.zlib.net/ for more information."),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT("bzip2\t\tData compression program and library."),
+dkT("\t\tSee http://www.bzip.org/ for more information."),
+#endif
+dkT(""),
+dkT("All the licenses below apply to the program."),
+dkT("Licenses for used libraries are shown as found on my Scientific Linux 6.x"),
+dkT("computer in the /usr/share/doc directory on 2015-04-01. Check the project"),
+dkT("homepages of the used libraries for additional information and/or updated"),
+dkT("license terms."),
+dkT(""),
+dkT(""),
+dkT("DK tools and libraries license"),
+dkT("=============================="),
+dkT("Copyright (c) 2015-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above copyright notice,"),
+dkT(" this list of conditions and the following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("* Neither the name of the Dirk Krause nor the names of contributors may be"),
+dkT(" used to endorse or promote products derived from this software without"),
+dkT(" specific prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\""),
+dkT("AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED."),
+dkT(""),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,"),
+dkT("INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,"),
+dkT("BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,"),
+dkT("DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY"),
+dkT("OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,"),
+dkT("EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT(""),
+dkT("Zlib license"),
+dkT("============"),
+dkT("(C) 1995-2004 Jean-loup Gailly and Mark Adler"),
+dkT(""),
+dkT("This software is provided 'as-is', without any express or implied"),
+dkT("warranty. In no event will the authors be held liable for any damages"),
+dkT("arising from the use of this software."),
+dkT(""),
+dkT("Permission is granted to anyone to use this software for any purpose,"),
+dkT("including commercial applications, and to alter it and redistribute it"),
+dkT("freely, subject to the following restrictions:"),
+dkT(""),
+dkT("1. The origin of this software must not be misrepresented; you must not"),
+dkT(" claim that you wrote the original software. If you use this software"),
+dkT(" in a product, an acknowledgment in the product documentation would be"),
+dkT(" appreciated but is not required."),
+dkT("2. Altered source versions must be plainly marked as such, and must not be"),
+dkT(" misrepresented as being the original software."),
+dkT("3. This notice may not be removed or altered from any source distribution."),
+dkT(""),
+dkT("Jean-loup Gailly Mark Adler"),
+dkT("jloup@gzip.org madler@alumni.caltech.edu"),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT(""),
+dkT("Bzip2 and libbzip2 library license"),
+dkT("=================================="),
+dkT("This program, \"bzip2\", the associated library \"libbzip2\", and all"),
+dkT("documentation, are copyright (C) 1996-2007 Julian R Seward. All"),
+dkT("rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions"),
+dkT("are met:"),
+dkT(""),
+dkT("1. Redistributions of source code must retain the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer."),
+dkT(""),
+dkT("2. The origin of this software must not be misrepresented; you must "),
+dkT(" not claim that you wrote the original software. If you use this "),
+dkT(" software in a product, an acknowledgment in the product "),
+dkT(" documentation would be appreciated but is not required."),
+dkT(""),
+dkT("3. Altered source versions must be plainly marked as such, and must"),
+dkT(" not be misrepresented as being the original software."),
+dkT(""),
+dkT("4. The name of the author may not be used to endorse or promote "),
+dkT(" products derived from this software without specific prior written "),
+dkT(" permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS"),
+dkT("OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED"),
+dkT("WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE"),
+dkT("GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS"),
+dkT("INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,"),
+dkT("WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS"),
+dkT("SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+dkT(""),
+dkT("Julian Seward, jseward@bzip.org"),
+dkT("bzip2/libbzip2 version 1.0.5 of 10 December 2007"),
+#endif
+dkT(""),
+NULL
+
+
+#line 347 "dk-eradisk.ctr"
+};
+
+
+
+/** Options used by program.
+*/
+static const dk4_option_specification_t dk_eradisk_options[] = {
+
+ /* Flag: Line end consists of carriage return and newline.
+ */
+ { dkT('p'), dkT("pass"), DK4_OPT_ARG_INT },
+
+ /* Show line numbers.
+ */
+ { dkT('b'), dkT("blocksize"), DK4_OPT_ARG_SIZE },
+
+ /* Number of digits for line numbers.
+ */
+ { dkT('c'), dkT("count"), DK4_OPT_ARG_SIZE }
+};
+
+/** Number of elements in the dk_cat_options array.
+*/
+static const size_t dk_eradisk_sz_options =
+sizeof(dk_eradisk_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Localized texts used by the program.
+*/
+static const dkChar * const *msg = dk_eradisk_kw_def;
+
+/** Number of elements in dk_blks_msg array.
+*/
+static size_t sz_msg =
+sizeof(dk_eradisk_kw_def)/sizeof(DK4_PCDKCHAR) - 1;
+
+
+
+/** Number of blocks (0 for unlimited).
+*/
+static size_t count = 0;
+
+
+
+/** Block size.
+*/
+static size_t blks = 4096;
+
+
+
+/** Pass number.
+*/
+static int passno = 0;
+
+
+
+/** Small static buffer.
+*/
+static char default_buffer[4096];
+
+
+
+/** A buffer is allocated dynamically if the size is larger
+ than default_buffer size.
+*/
+static char *allocated_buffer = NULL;
+
+
+
+/** The buffer used by the program.
+*/
+static char *buffer = NULL;
+
+
+
+/** Exit status code.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+/** Pass a volatile pointer to an atomic integer.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ptr Address of atomic integer variable.
+ @return The unmodified pointer.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+/** Check whether we can continue or if a signal was received.
+ @param check_pipe Flag: Check for occured SIGPIPE signal too.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(int check_pipe)
+{
+ int back = 1;
+#ifdef SIGPIPE
+ if (0 != check_pipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_int )) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+static
+void
+dk_eradisk_memset(char *ptr, size_t sz, char patbyte)
+{
+#if DK4_HAVE_MEMSET
+ memset((void *)ptr, (int)patbyte, sz);
+#else
+ while(sz--) { *(ptr++) = patbyte; }
+#endif
+}
+
+
+
+static
+void
+produce_output(void)
+{
+ size_t nb;
+#if DK4_ON_WINDOWS
+ int oldmode;
+ int wres;
+#else
+ ssize_t wres;
+#endif
+ int cc;
+ char patbyte;
+
+ /* Check whether to use static or dynamic buffer, allocate
+ buffer if necessary.
+ */
+ if (sizeof(default_buffer) >= blks) {
+ buffer = default_buffer;
+ } else {
+ allocated_buffer = dk4mem_malloc_bytes(blks, NULL);
+ if (NULL != allocated_buffer) {
+ buffer = allocated_buffer;
+ } else {
+ /* ERROR: Failed to obtain memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ }
+ }
+
+ if (NULL != buffer) {
+#if VERSION_BEFORE_20150821
+ cc = 1;
+#endif
+ nb = 0;
+ exval = EXIT_SUCCESS;
+ /* Set buffer to pattern depending on pass number.
+ */
+ switch (passno) {
+ case 7 : { patbyte = 0xAA; } break;
+ case 6 : { patbyte = 0x55; } break;
+ case 5 : { patbyte = 0xCC; } break;
+ case 4 : { patbyte = 0x33; } break;
+ case 3 : { patbyte = 0xF0; } break;
+ case 2 : { patbyte = 0x0F; } break;
+ case 1 : { patbyte = 0xFF; } break;
+ default: { patbyte = 0x00; } break;
+ }
+ dk_eradisk_memset(buffer, blks, patbyte);
+ /* Write output buffer.
+ */
+ cc = sig_can_continue(1);
+#if DK4_ON_WINDOWS
+ oldmode = _setmode(1, _O_BINARY);
+ if ((dk4_um_t)UINT_MAX < blks) {
+ /* ERROR: Block size too large! */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 5);
+ cc = -1;
+ }
+#else
+ if ((dk4_um_t)(SIZE_MAX / 2) < blks) {
+ /* ERROR: Block size too large! */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 5);
+ cc = -1;
+ }
+#endif
+ while(1 == cc) {
+ errno = 0;
+#if DK4_ON_WINDOWS
+ wres = _write(1, buffer, (unsigned)blks);
+#else
+ wres = write(1, buffer, blks);
+#endif
+ if (-1 == wres) {
+ cc = -1;
+ dk4fd_write_error_msg(app, NULL, errno);
+ }
+ if (1 != sig_can_continue(1)) {
+ if (1 == cc) { cc = -1; }
+ }
+ if (0 < count) {
+ if (++nb >= count) {
+ if (1 == cc) { cc = 0; }
+ }
+ }
+ }
+#if DK4_ON_WINDOWS
+ _setmode(1, oldmode);
+#endif
+ }
+
+ /* Release buffer if dynamically allocated.
+ */
+ if (NULL != allocated_buffer) {
+ dk4mem_free(allocated_buffer);
+ }
+}
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+run_with_signals(void)
+{
+#ifdef SIGPIPE
+ struct sigaction opipe;
+#endif
+ struct sigaction oint;
+#ifdef SIGPIPE
+ struct sigaction npipe;
+#endif
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+ int success = 0;
+
+#ifdef SIGPIPE
+ /* Set up signal handling for SIGPIPE.
+ */
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+#endif
+
+ /* Set up signal handling for SIGINT.
+ */
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ produce_output();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+#ifdef SIGPIPE
+ /* Restore signal handling for SIGPIPE.
+ */
+ restore_old_pipe:
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+#endif
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+run_with_signals(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ produce_output();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+#ifdef SIGPIPE
+ sigset(SIGPIPE, oldpipe);
+#endif
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+run_with_signals(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+#ifdef SIGPIPE
+ oldpipe = signal(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ produce_output();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+#ifdef SIGPIPE
+ signal(SIGPIPE, oldpipe);
+#endif
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+run_with_signals(void)
+{
+ produce_output();
+}
+#endif
+#endif
+#endif
+
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ dk4_im_t i;
+ size_t sz;
+
+
+#line 856 "dk-eradisk.ctr"
+
+
+#line 857 "dk-eradisk.ctr"
+
+ app = dk4app_open_cmd(
+ argc, argv, dk_eradisk_options, dk_eradisk_sz_options,
+ dk_eradisk_kwnl[0], DKT_VERSION_DK,
+ dk_eradisk_kwnl[1], dk_eradisk_help_text, dk_eradisk_license_text
+ );
+ if (NULL != app) {
+ sz_msg = dk4app_string_table_size(dk_eradisk_kw_def);
+ msg = dk4app_string_table(app, dk_eradisk_kwnl[2], dk_eradisk_kw_def);
+ if (0 != dk4app_can_run_normally(app)) {
+ if (0 != dk4app_opt_is_set_short(app, dkT('p'), NULL)) {
+ if (0 != dk4app_opt_get_int_short(&i, app, dkT('p'), NULL)) {
+ if ((INT_MIN <= i) && (INT_MAX >= i)) {
+ passno = (int)i;
+ } else {
+ /* ERROR: Out of range */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 6);
+ if (0 < i) { passno = INT_MAX; }
+ else { passno = INT_MIN; }
+ }
+ }
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('b'), NULL)) {
+ if (0 != dk4app_opt_get_size_short(&sz, app, dkT('b'), NULL)) {
+ if (0 < sz) {
+ blks = sz;
+ } else {
+ /* ERROR: Out of range */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 7);
+ }
+ }
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('c'), NULL)) {
+ if (0 != dk4app_opt_get_size_short(&sz, app, dkT('c'), NULL)) {
+ count = sz;
+ }
+ }
+ run_with_signals();
+#ifdef SIGPIPE
+ if ((0 < count) && (0 != sig_read_atomic(&sig_had_pipe))) {
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 2);
+ exval = EXIT_FAILURE;
+ }
+#endif
+ if ((0 < count) && (0 != sig_read_atomic(&sig_had_int))) {
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 3);
+ exval = EXIT_FAILURE;
+ }
+ if (0 != sig_read_atomic(&sig_had_term)) {
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 4);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ dk4app_close(app);
+ }
+
+
+#line 917 "dk-eradisk.ctr"
+
+
+#line 918 "dk-eradisk.ctr"
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/dk-eradisk.ctr b/support/dktools/dk-eradisk.ctr
new file mode 100644
index 0000000000..da4069a92f
--- /dev/null
+++ b/support/dktools/dk-eradisk.ctr
@@ -0,0 +1,920 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% module
+
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4vers.h"
+#include "dk4app.h"
+#include "dk4aopt.h"
+#include "dk4mem.h"
+#include "dk4numco.h"
+#include "dk4fdwre.h"
+
+
+
+$!trace-include
+
+
+
+/** Constant texts used by program, not localized.
+*/
+static const dkChar * const dk_eradisk_kwnl[] = {
+$!string-table macro=dkT
+#
+# 0 Program group name
+#
+dktools
+#
+# 1 Help text file name
+#
+dk-eradisk.txt
+#
+# 2 String table file
+#
+dk-eradisk.str
+$!end
+};
+
+
+
+/** Constant texts used by program, replaced by localized texts
+ if available.
+*/
+static const dkChar * const dk_eradisk_kw_def[] = {
+$!string-table macro=dkT
+#
+# 0 Error message: Failed to set up signal handlers!
+#
+Failed to set up signal handlers!
+#
+# 1 Error message: Failed to restore signal handlers!
+#
+Failed to restore signal handlers!
+#
+# 2 Error message: Signal SIGPIPE received
+#
+Aborted by SIGPIPE signal!
+#
+# 3 Error message: Signal SIGINT received!
+#
+Aborted by SIGINT signal!
+#
+# 4 Error message: Aborted by SIGTERM signal!
+#
+Aborted by SIGTERM signal!
+#
+# 5 Error message: Block size too large.
+#
+Block size too large!
+#
+# 6 Error message: Pass number out of range!
+#
+Pass number out of range!
+#
+# 7 Error message: Block size must not be 0!
+#
+Block size must not be 0!
+$!end
+};
+
+
+
+/** Default text, used if help text file is not found.
+*/
+static const dkChar * const dk_eradisk_help_text[] = {
+$!text macro=dkT,preprocessor
+
+NAME
+
+ dk-eradisk - Generate patterns to erase disk before retiring it
+
+SYNOPSIS
+
+ dk-eradisk [<options>]
+
+DESCRIPTION
+
+The program generates a data stream to erase a disk.
+Before retiring a disk or handing a disk over to another user one
+should remove all contents.
+The output from dk-eradisk can be used as input for the ``dd'' program
+to savely clean a disk.
+
+OPTIONS
+
+-p <number>, --pass=<number>
+ Pass number. Pass 0 (should be used as last pass)
+ can be used to write 0 bytes, so operating systems recognize
+ the disk as new from manufacturer.
+ The pass number chooses the bit pattern, one from 0x00, 0xFF,
+ 0x0F, 0xF0, 0x33, 0xCC, 0x55, or 0xAA.
+ When doing multiple passes, start with the highest pass number,
+ use pass number 0 for the final pass.
+
+-b <size>, --blocksize=<size>
+ Block size (default: 4096).
+ The default is suitable for traditional hard disks.
+ For flash memory (i.e. SSD) you should increase the value to 1m.
+
+-c <size>, --count=<size>
+ Number of blocks to write.
+ The default 0 creates an endless sequence of blocks
+ until the program is finished by signal.
+
+EXIT STATUS
+
+0 on success, all other exit status codes indicate an error.
+
+AUTHOR
+
+Dirk Krause
+
+COPYRIGHT AND LICENSE
+
+Run
+ dk-eradisk --license
+to see license information.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
+$!end
+};
+
+
+
+/** License conditions.
+*/
+static const dkChar * const dk_eradisk_license_text[] = {
+$!text macro=dkT,preprocessor
+This software uses code from the following projects, either directly or as
+a library:
+
+dktools Dirk Krause's tools and libraries.
+ See http://dktools.sourceforge.net/ for more information.
+#if DK4_HAVE_ZLIB_H
+
+zlib Data compression library.
+ See http://www.zlib.net/ for more information.
+#endif
+#if DK4_HAVE_BZLIB_H
+
+bzip2 Data compression program and library.
+ See http://www.bzip.org/ for more information.
+#endif
+
+All the licenses below apply to the program.
+Licenses for used libraries are shown as found on my Scientific Linux 6.x
+computer in the /usr/share/doc directory on 2015-04-01. Check the project
+homepages of the used libraries for additional information and/or updated
+license terms.
+
+
+DK tools and libraries license
+==============================
+Copyright (c) 2015-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#if DK4_HAVE_ZLIB_H
+
+
+Zlib license
+============
+(C) 1995-2004 Jean-loup Gailly and Mark Adler
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+
+Jean-loup Gailly Mark Adler
+jloup@gzip.org madler@alumni.caltech.edu
+#endif
+#if DK4_HAVE_BZLIB_H
+
+
+Bzip2 and libbzip2 library license
+==================================
+This program, "bzip2", the associated library "libbzip2", and all
+documentation, are copyright (C) 1996-2007 Julian R Seward. All
+rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+3. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Julian Seward, jseward@bzip.org
+bzip2/libbzip2 version 1.0.5 of 10 December 2007
+#endif
+
+$!end
+};
+
+
+
+/** Options used by program.
+*/
+static const dk4_option_specification_t dk_eradisk_options[] = {
+
+ /* Flag: Line end consists of carriage return and newline.
+ */
+ { dkT('p'), dkT("pass"), DK4_OPT_ARG_INT },
+
+ /* Show line numbers.
+ */
+ { dkT('b'), dkT("blocksize"), DK4_OPT_ARG_SIZE },
+
+ /* Number of digits for line numbers.
+ */
+ { dkT('c'), dkT("count"), DK4_OPT_ARG_SIZE }
+};
+
+/** Number of elements in the dk_cat_options array.
+*/
+static const size_t dk_eradisk_sz_options =
+sizeof(dk_eradisk_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Localized texts used by the program.
+*/
+static const dkChar * const *msg = dk_eradisk_kw_def;
+
+/** Number of elements in dk_blks_msg array.
+*/
+static size_t sz_msg =
+sizeof(dk_eradisk_kw_def)/sizeof(DK4_PCDKCHAR) - 1;
+
+
+
+/** Number of blocks (0 for unlimited).
+*/
+static size_t count = 0;
+
+
+
+/** Block size.
+*/
+static size_t blks = 4096;
+
+
+
+/** Pass number.
+*/
+static int passno = 0;
+
+
+
+/** Small static buffer.
+*/
+static char default_buffer[4096];
+
+
+
+/** A buffer is allocated dynamically if the size is larger
+ than default_buffer size.
+*/
+static char *allocated_buffer = NULL;
+
+
+
+/** The buffer used by the program.
+*/
+static char *buffer = NULL;
+
+
+
+/** Exit status code.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+/** Pass a volatile pointer to an atomic integer.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ptr Address of atomic integer variable.
+ @return The unmodified pointer.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+/** Check whether we can continue or if a signal was received.
+ @param check_pipe Flag: Check for occured SIGPIPE signal too.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(int check_pipe)
+{
+ int back = 1;
+#ifdef SIGPIPE
+ if (0 != check_pipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_int )) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+static
+void
+dk_eradisk_memset(char *ptr, size_t sz, char patbyte)
+{
+#if DK4_HAVE_MEMSET
+ memset((void *)ptr, (int)patbyte, sz);
+#else
+ while(sz--) { *(ptr++) = patbyte; }
+#endif
+}
+
+
+
+static
+void
+produce_output(void)
+{
+ size_t nb;
+#if DK4_ON_WINDOWS
+ int oldmode;
+ int wres;
+#else
+ ssize_t wres;
+#endif
+ int cc;
+ char patbyte;
+
+ /* Check whether to use static or dynamic buffer, allocate
+ buffer if necessary.
+ */
+ if (sizeof(default_buffer) >= blks) {
+ buffer = default_buffer;
+ } else {
+ allocated_buffer = dk4mem_malloc_bytes(blks, NULL);
+ if (NULL != allocated_buffer) {
+ buffer = allocated_buffer;
+ } else {
+ /* ERROR: Failed to obtain memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ }
+ }
+
+ if (NULL != buffer) {
+#if VERSION_BEFORE_20150821
+ cc = 1;
+#endif
+ nb = 0;
+ exval = EXIT_SUCCESS;
+ /* Set buffer to pattern depending on pass number.
+ */
+ switch (passno) {
+ case 7 : { patbyte = 0xAA; } break;
+ case 6 : { patbyte = 0x55; } break;
+ case 5 : { patbyte = 0xCC; } break;
+ case 4 : { patbyte = 0x33; } break;
+ case 3 : { patbyte = 0xF0; } break;
+ case 2 : { patbyte = 0x0F; } break;
+ case 1 : { patbyte = 0xFF; } break;
+ default: { patbyte = 0x00; } break;
+ }
+ dk_eradisk_memset(buffer, blks, patbyte);
+ /* Write output buffer.
+ */
+ cc = sig_can_continue(1);
+#if DK4_ON_WINDOWS
+ oldmode = _setmode(1, _O_BINARY);
+ if ((dk4_um_t)UINT_MAX < blks) {
+ /* ERROR: Block size too large! */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 5);
+ cc = -1;
+ }
+#else
+ if ((dk4_um_t)(SIZE_MAX / 2) < blks) {
+ /* ERROR: Block size too large! */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 5);
+ cc = -1;
+ }
+#endif
+ while(1 == cc) {
+ errno = 0;
+#if DK4_ON_WINDOWS
+ wres = _write(1, buffer, (unsigned)blks);
+#else
+ wres = write(1, buffer, blks);
+#endif
+ if (-1 == wres) {
+ cc = -1;
+ dk4fd_write_error_msg(app, NULL, errno);
+ }
+ if (1 != sig_can_continue(1)) {
+ if (1 == cc) { cc = -1; }
+ }
+ if (0 < count) {
+ if (++nb >= count) {
+ if (1 == cc) { cc = 0; }
+ }
+ }
+ }
+#if DK4_ON_WINDOWS
+ _setmode(1, oldmode);
+#endif
+ }
+
+ /* Release buffer if dynamically allocated.
+ */
+ if (NULL != allocated_buffer) {
+ dk4mem_free(allocated_buffer);
+ }
+}
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+run_with_signals(void)
+{
+#ifdef SIGPIPE
+ struct sigaction opipe;
+#endif
+ struct sigaction oint;
+#ifdef SIGPIPE
+ struct sigaction npipe;
+#endif
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+ int success = 0;
+
+#ifdef SIGPIPE
+ /* Set up signal handling for SIGPIPE.
+ */
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+#endif
+
+ /* Set up signal handling for SIGINT.
+ */
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ produce_output();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+#ifdef SIGPIPE
+ /* Restore signal handling for SIGPIPE.
+ */
+ restore_old_pipe:
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+#endif
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+run_with_signals(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ produce_output();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+#ifdef SIGPIPE
+ sigset(SIGPIPE, oldpipe);
+#endif
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+run_with_signals(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+#ifdef SIGPIPE
+ oldpipe = signal(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ produce_output();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+#ifdef SIGPIPE
+ signal(SIGPIPE, oldpipe);
+#endif
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+run_with_signals(void)
+{
+ produce_output();
+}
+#endif
+#endif
+#endif
+
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ dk4_im_t i;
+ size_t sz;
+ $!trace-init dk-eradisk.deb
+ $? "+ main"
+
+ app = dk4app_open_cmd(
+ argc, argv, dk_eradisk_options, dk_eradisk_sz_options,
+ dk_eradisk_kwnl[0], DKT_VERSION_DK,
+ dk_eradisk_kwnl[1], dk_eradisk_help_text, dk_eradisk_license_text
+ );
+ if (NULL != app) {
+ sz_msg = dk4app_string_table_size(dk_eradisk_kw_def);
+ msg = dk4app_string_table(app, dk_eradisk_kwnl[2], dk_eradisk_kw_def);
+ if (0 != dk4app_can_run_normally(app)) {
+ if (0 != dk4app_opt_is_set_short(app, dkT('p'), NULL)) {
+ if (0 != dk4app_opt_get_int_short(&i, app, dkT('p'), NULL)) {
+ if ((INT_MIN <= i) && (INT_MAX >= i)) {
+ passno = (int)i;
+ } else {
+ /* ERROR: Out of range */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 6);
+ if (0 < i) { passno = INT_MAX; }
+ else { passno = INT_MIN; }
+ }
+ }
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('b'), NULL)) {
+ if (0 != dk4app_opt_get_size_short(&sz, app, dkT('b'), NULL)) {
+ if (0 < sz) {
+ blks = sz;
+ } else {
+ /* ERROR: Out of range */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 7);
+ }
+ }
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('c'), NULL)) {
+ if (0 != dk4app_opt_get_size_short(&sz, app, dkT('c'), NULL)) {
+ count = sz;
+ }
+ }
+ run_with_signals();
+#ifdef SIGPIPE
+ if ((0 < count) && (0 != sig_read_atomic(&sig_had_pipe))) {
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 2);
+ exval = EXIT_FAILURE;
+ }
+#endif
+ if ((0 < count) && (0 != sig_read_atomic(&sig_had_int))) {
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 3);
+ exval = EXIT_FAILURE;
+ }
+ if (0 != sig_read_atomic(&sig_had_term)) {
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 4);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ dk4app_close(app);
+ }
+ $? "- main %d", exval
+ $!trace-end
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/dk-eradisk.rc b/support/dktools/dk-eradisk.rc
new file mode 100644
index 0000000000..d1d466fe56
--- /dev/null
+++ b/support/dktools/dk-eradisk.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Create data stream to erase a disk\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "Create data stream to erase a disk\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "dk-eradisk\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/dk-fic.c b/support/dktools/dk-fic.c
new file mode 100644
index 0000000000..9d51298960
--- /dev/null
+++ b/support/dktools/dk-fic.c
@@ -0,0 +1,2210 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk-fic.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#line 8 "dk-fic.ctr"
+
+/** @file dk-fic.c File integrity checker.
+*/
+
+
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4vers.h"
+#include "dk4app.h"
+#include "dk4aopt.h"
+#include "dk4mem.h"
+#include "dk4mema.h"
+#include "dk4fput.h"
+#include "dk4mpl.h"
+#include "dk4enc.h"
+#include "dk4tspdk.h"
+#include "dk4fopda.h"
+#include "dk4pathd.h"
+#include "dk4md.h"
+#include "dk4maodd.h"
+#include "dk4filed.h"
+#include "dk4fileid.h"
+#include "dk4filei.h"
+#include "dk4fileia.h"
+#include "dk4strd.h"
+#include "dk4numl.h"
+#include "dk4maidddu.h"
+
+
+
+
+
+#line 84 "dk-fic.ctr"
+
+
+
+/** Default help text, shown if help text file is not found.
+*/
+static const dkChar * const dk_fic_help_text[] = {
+dkT(""),
+dkT("File integrity checker"),
+dkT(""),
+dkT("Create checksum lists for files or verify files against a checksum list."),
+dkT(""),
+dkT("dk-fic [<options>] [<file(s)>]"),
+dkT(""),
+dkT("Options:"),
+dkT("-c\t\t--check\t\t\tCheck (verify a checksum list)."),
+dkT("-v\t\t--verbose\t\tMessages for succeeded tests."),
+dkT("-q\t\t--quiet\t\t\tNo messages for failed tests."),
+dkT("-l <size>\t--line-size=<size>\tSize for input line buffer."),
+dkT(""),
+dkT("--help\t\t\t\t\tShow this short help text."),
+dkT("--manual\t\t\t\t*** SHOW FULL MANUAL. ***"),
+dkT("--version\t\t\t\tShow version information."),
+dkT("--license\t\t\t\tShow license information."),
+dkT(""),
+dkT("Typical operations:"),
+dkT("find <directory> -type f | dk-fic > checklist.txt\t\tCreate check-"),
+dkT("dk-ls -r -tf -pn <directory> | dk-fic > checklist.txt\t\tsum list."),
+dkT("dk-fic -c < checklist.txt\t\t\t\t\tVerify files."),
+dkT(""),
+dkT("http://dktools.sourceforge.net"),
+dkT(""),
+NULL
+
+
+#line 117 "dk-fic.ctr"
+};
+
+
+
+/** License conditions.
+*/
+static const dkChar * const dk_fic_license_text[] = {
+dkT(""),
+dkT("This software uses code from the following projects, either directly or as"),
+dkT("a library:"),
+dkT(""),
+dkT("dktools\t\tDirk Krause's tools and libraries."),
+dkT("\t\tSee http://dktools.sourceforge.net/ for more information."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT("zlib\t\tData compression library."),
+dkT("\t\tSee http://www.zlib.net/ for more information."),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT("bzip2\t\tData compression program and library."),
+dkT("\t\tSee http://www.bzip.org/ for more information."),
+#endif
+dkT(""),
+dkT("All the licenses below apply to the program."),
+dkT("Licenses for used libraries are shown as found on my Scientific Linux 6.x"),
+dkT("computer in the /usr/share/doc directory on 2015-04-01. Check the project"),
+dkT("homepages of the used libraries for additional information and/or updated"),
+dkT("license terms."),
+dkT(""),
+dkT(""),
+dkT("DK tools and libraries license"),
+dkT("=============================="),
+dkT("Copyright (c) 2015-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above copyright notice,"),
+dkT(" this list of conditions and the following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("* Neither the name of the Dirk Krause nor the names of contributors may be"),
+dkT(" used to endorse or promote products derived from this software without"),
+dkT(" specific prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\""),
+dkT("AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED."),
+dkT(""),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,"),
+dkT("INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,"),
+dkT("BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,"),
+dkT("DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY"),
+dkT("OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,"),
+dkT("EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT(""),
+dkT("Zlib license"),
+dkT("============"),
+dkT("(C) 1995-2004 Jean-loup Gailly and Mark Adler"),
+dkT(""),
+dkT("This software is provided 'as-is', without any express or implied"),
+dkT("warranty. In no event will the authors be held liable for any damages"),
+dkT("arising from the use of this software."),
+dkT(""),
+dkT("Permission is granted to anyone to use this software for any purpose,"),
+dkT("including commercial applications, and to alter it and redistribute it"),
+dkT("freely, subject to the following restrictions:"),
+dkT(""),
+dkT("1. The origin of this software must not be misrepresented; you must not"),
+dkT(" claim that you wrote the original software. If you use this software"),
+dkT(" in a product, an acknowledgment in the product documentation would be"),
+dkT(" appreciated but is not required."),
+dkT("2. Altered source versions must be plainly marked as such, and must not be"),
+dkT(" misrepresented as being the original software."),
+dkT("3. This notice may not be removed or altered from any source distribution."),
+dkT(""),
+dkT("Jean-loup Gailly Mark Adler"),
+dkT("jloup@gzip.org madler@alumni.caltech.edu"),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT(""),
+dkT("Bzip2 and libbzip2 library license"),
+dkT("=================================="),
+dkT("This program, \"bzip2\", the associated library \"libbzip2\", and all"),
+dkT("documentation, are copyright (C) 1996-2007 Julian R Seward. All"),
+dkT("rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions"),
+dkT("are met:"),
+dkT(""),
+dkT("1. Redistributions of source code must retain the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer."),
+dkT(""),
+dkT("2. The origin of this software must not be misrepresented; you must "),
+dkT(" not claim that you wrote the original software. If you use this "),
+dkT(" software in a product, an acknowledgment in the product "),
+dkT(" documentation would be appreciated but is not required."),
+dkT(""),
+dkT("3. Altered source versions must be plainly marked as such, and must"),
+dkT(" not be misrepresented as being the original software."),
+dkT(""),
+dkT("4. The name of the author may not be used to endorse or promote "),
+dkT(" products derived from this software without specific prior written "),
+dkT(" permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS"),
+dkT("OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED"),
+dkT("WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE"),
+dkT("GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS"),
+dkT("INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,"),
+dkT("WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS"),
+dkT("SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+dkT(""),
+dkT("Julian Seward, jseward@bzip.org"),
+dkT("bzip2/libbzip2 version 1.0.5 of 10 December 2007"),
+#endif
+dkT(""),
+NULL
+
+
+#line 249 "dk-fic.ctr"
+};
+
+
+
+/** Keywords used by the program, not localized.
+*/
+static const dkChar * const dk_fic_kwnl[] = {
+/* 0 */
+dkT("dktools"),
+
+/* 1 */
+dkT("dk-fic.txt"),
+
+/* 2 */
+dkT("dk-fic.str"),
+
+/* 3 */
+dkT("line.size"),
+
+/* 4 */
+dkT("stdin"),
+
+/* 5 */
+dkT("rb"),
+
+/* 6 */
+dkT("\\"),
+
+/* 7 */
+dkT("# dk-fic 3\n"),
+
+/* 8 */
+dkT("# dk-fic 4\n"),
+
+/* 9 */
+dkT("dk-fic"),
+
+NULL
+
+
+#line 298 "dk-fic.ctr"
+};
+
+
+
+/** Default keywords, localized.
+*/
+static const dkChar * const dk_fic_kw_def[] = {
+/* 0 */
+dkT("Failed to set up signal handlers!"),
+
+/* 1 */
+dkT("Failed to restore signal handlers!"),
+
+/* 2 */
+dkT("PASSED "),
+
+/* 3 */
+dkT("FAILED "),
+
+/* 4 */
+dkT("Failed to read data from file!"),
+
+/* 5 */
+dkT("Failed to convert file size to text for file:\n\t\""),
+
+/* 6 */
+dkT("\"!"),
+
+/* 7 */
+dkT("Failed to finish at least one message digest for file:\n\t\""),
+
+/* 8 */
+dkT("\"!"),
+
+/* 9 */
+dkT("Failed to add data to message digest for file:\n\t\""),
+
+/* 10 */
+dkT("\"!"),
+
+/* 11 */
+dkT("Failed to initialize at least one message digest for file:\n\t\""),
+
+/* 12 */
+dkT("\"!"),
+
+/* 13 */
+dkT("Not a regular file:\n\t\""),
+
+/* 14 */
+dkT("\"!"),
+
+/* 15 */
+dkT("Failed to obtain file size:\n\t\""),
+
+/* 16 */
+dkT("\"!"),
+
+/* 17 */
+dkT("SHA-512 message digest not supported, SHA-512 checksums ignored."),
+
+/* 18 */
+dkT("Syntax error, first line must be \"# dk-fic 3\" or \"# dk-fic 4\"!"),
+
+/* 19 */
+dkT("Syntax error, expected:\n\tmd5 sha-1 ripemd-160 sha-512 size name"),
+
+/* 20 */
+dkT("Syntax error, expected:\n\tmd5 sha-1 ripemd-160 size name"),
+
+/* 21 */
+dkT("Syntax error, invalid file size: \""),
+
+/* 22 */
+dkT("\"!"),
+
+/* 23 */
+dkT("Failed to set up text line processing!"),
+
+/* 24 */
+dkT("Build problem: At least one required message digest type is not supported!"),
+
+/* 25 */
+dkT("Options -q and -v are mutually exclusive!"),
+
+/* 26 */
+dkT("Encoding not found: \""),
+
+/* 27 */
+dkT("\"!"),
+
+/* 28 */
+dkT("Problems while writing output!"),
+
+/* 29 */
+dkT("Signal SIGPIPE received!"),
+
+/* 30 */
+dkT("Aborted by SIGINT signal!"),
+
+/* 31 */
+dkT("Aborted by SIGTERM signal!"),
+
+/* 32 */
+dkT("Decoding error!"),
+
+/* 33 */
+dkT("Encoding error!"),
+
+/* 34 */
+dkT("Processing error!"),
+
+/* 35 */
+dkT("Decoding error!\n\tByte: "),
+
+/* 36 */
+dkT("Encoding error!\n\tByte: "),
+
+/* 37 */
+dkT("Processing error!\n\tByte: "),
+
+/* 38 */
+dkT(",\n\tCharacter: "),
+
+/* 39 */
+dkT(",\n\tPosition in line: "),
+
+/* 40 */
+dkT("."),
+
+NULL
+
+
+#line 423 "dk-fic.ctr"
+};
+
+/* VARIABLES */
+
+/** Options for the program.
+*/
+static const dk4_option_specification_t dk_fic_options[] = {
+
+ /* Check (input is a previously generated checksum list.
+ */
+ { dkT('c'), dkT("check"), DK4_OPT_ARG_NONE },
+
+ /* Input line size.
+ */
+ { dkT('l'), dkT("line-size"), DK4_OPT_ARG_SIZE },
+
+ /* Quite when checking (only set exit status code).
+ */
+ { dkT('q'), dkT("quiet"), DK4_OPT_ARG_NONE },
+
+ /* Verbose (write report line for succeeded test too).
+ */
+ { dkT('v'), dkT("verbose"), DK4_OPT_ARG_NONE },
+
+ /* Expected input encoding.
+ */
+ { dkT('i'), dkT("input-encoding"), DK4_OPT_ARG_STRING },
+
+};
+
+
+
+/** Data buffer for reading the file.
+*/
+static char data_buf[4096];
+
+
+
+/** Default input line buffer.
+*/
+static dkChar ibuf_def[256 + DK4_MAX_PATH];
+
+
+#if DK4_HAVE_OPENSSL_MD5_H && DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_OPENSSL_RIPEMD_H
+
+static dk4_md_ctx_t ctx_md5;
+
+static dk4_md_ctx_t ctx_sha1;
+
+static dk4_md_ctx_t ctx_ripemd160;
+
+#if DK4_HAVE_SHA512
+
+static dk4_md_ctx_t ctx_sha512;
+
+#endif
+
+#endif
+
+
+/** Allocated input buffer for larger line size.
+*/
+static dkChar *ibuf_all = NULL;
+
+
+
+/** Pointer to real input buffer to use.
+*/
+static dkChar *ibuf_ptr = ibuf_def;
+
+
+
+/** Input line buffer size.
+*/
+static size_t ibuf_sz = DK4_SIZEOF(ibuf_def,dkChar);
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Message array, localized messages or default texts.
+*/
+static const dkChar * const *dk_fic_msg = dk_fic_kw_def;
+
+
+
+/** Number of elements in the dk_fic_msg array.
+*/
+static size_t dk_fic_sz_msg =
+sizeof(dk_fic_kw_def)/sizeof(DK4_PCDKCHAR) - 1;
+
+
+/** Number of elements in the dk_fic_options array.
+*/
+static const size_t dk_fic_sz_options =
+sizeof(dk_fic_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Length of file size to print.
+*/
+static size_t dk_fic_num_len = 2 * sizeof(dk4_um_t);
+
+
+
+/** Number of message digests (3 or 4).
+*/
+static size_t dk_fic_num_mds = 4;
+
+
+
+/** Flag: Write error occured while writing output.
+*/
+static int dk_fic_write_error = 0;
+
+
+
+/** Exit status code.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+/** Flag: Verify checksums instead of creating them.
+*/
+static int dk_fic_verify = 0;
+
+
+
+/** Verbosity level (0=silent, 1=errors, 2=errors+success).
+*/
+static int dk_fic_verbosity = 1;
+
+
+
+/** Input encoding expected on standard input.
+*/
+static int dk_fic_ie_stdin = DK4_FILE_ENCODING_ASCII;
+
+
+
+/** Input encoding expected on files.
+*/
+static int dk_fic_ie_file = DK4_FILE_ENCODING_ASCII;
+
+
+
+/** Flag: Current line to process is first line of data stream.
+*/
+static int dk_fic_first_line = 0;
+
+
+
+/* SIGNAL HANDLING VARIABLES AND HANDLER FUNCTIONS */
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+/** Pass a volatile pointer to an atomic integer.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ptr Address of atomic integer variable.
+ @return The unmodified pointer.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+/** Check whether we can continue or if a signal was received.
+ @param check_pipe Flag: Check for occured SIGPIPE signal too.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(int check_pipe)
+{
+ int back = 1;
+#ifdef SIGPIPE
+ if (0 != check_pipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_int )) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+/* FUNCTIONS */
+
+
+static
+int
+dk_fic_can_continue(void)
+{
+ int back;
+ back = sig_can_continue(1);
+ if (0 != back) {
+ if (0 != dk_fic_write_error) {
+ back = 0;
+ }
+ }
+ return back;
+}
+
+
+#if DK4_HAVE_OPENSSL_MD5_H && DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_OPENSSL_RIPEMD_H
+
+
+
+/** Report an error with position.
+ @param i1 Index of first message part in array.
+ @param i2 Index of alternative first message part.
+ @param bno Current byte number.
+ @param lno Current line number.
+ @param cno Current character number.
+ @param cil Current character number within line.
+ @param fn File name processed.
+*/
+static
+void
+dk_fic_report_with_position(
+ size_t i1,
+ size_t i2,
+ dk4_um_t bno,
+ dk4_um_t lno,
+ dk4_um_t cno,
+ dk4_um_t cil,
+ const dkChar *fn
+)
+{
+ dkChar b1[8*(1+sizeof(dk4_um_t))+16];
+ dkChar b2[8*(1+sizeof(dk4_um_t))+16];
+ dkChar b3[8*(1+sizeof(dk4_um_t))+16];
+ const dkChar *oldlogname = NULL;
+ dk4_um_t oldlogline = (dk4_um_t)0UL;
+ int allbuffersok = 0;
+
+ oldlogname = dk4app_get_log_source_file(app);
+ oldlogline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_file(app, fn);
+ dk4app_set_log_source_line(app, lno);
+ if (0 != dk4ma_write_decimal_unsigned(b3,DK4_SIZEOF(b3,dkChar),cil,0,NULL)) {
+ if (0 != dk4ma_write_decimal_unsigned(b2,DK4_SIZEOF(b2,dkChar),cno,0,NULL)) {
+ if (0 != dk4ma_write_decimal_unsigned(b1,DK4_SIZEOF(b1,dkChar),bno,0,NULL)) {
+ allbuffersok = 1;
+ }
+ }
+ }
+ if (0 != allbuffersok) {
+ dk4app_log_7(
+ app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, i1, 38, 39, 40, b1, b2, b3
+ );
+ } else {
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, i2);
+ }
+ dk4app_set_log_source_line(app, oldlogline);
+ dk4app_set_log_source_file(app, oldlogname);
+}
+
+
+
+/** Report decoding/encoding and processing errors.
+ @param er_en Error report for decoding/encoding errors.
+ @param er_pr Error report for processing errors.
+ @param fn File name.
+*/
+static
+void
+dk_fic_report_errors(
+ dk4_er_t *er_en,
+ dk4_er_t *er_pr,
+ const dkChar *fn
+)
+{
+ static int had_decoding_errors = 0;
+ static int had_encoding_errors = 0;
+ static int had_processing_errors = 0;
+
+ if (NULL != er_en) {
+ switch (er_en->ec) {
+ case DK4_E_DECODING_FAILED : {
+ if (3 > had_decoding_errors) {
+ dk_fic_report_with_position(
+ 35, 32,
+ er_en->dt.fpos.byteno, er_en->dt.fpos.lineno,
+ er_en->dt.fpos.charno, er_en->dt.fpos.charinline,
+ fn
+ );
+ }
+ if (2 <= had_decoding_errors) { had_decoding_errors++; }
+ } break;
+ case DK4_E_ENCODING_FAILED : {
+ if (3 > had_encoding_errors) {
+ dk_fic_report_with_position(
+ 36, 33,
+ er_en->dt.fpos.byteno, er_en->dt.fpos.lineno,
+ er_en->dt.fpos.charno, er_en->dt.fpos.charinline,
+ fn
+ );
+ }
+ if (2 <= had_encoding_errors) { had_encoding_errors++; }
+ } break;
+ }
+ }
+ if (NULL != er_pr) {
+ if (DK4_E_NONE != er_pr->ec) {
+ if (3 > had_processing_errors) {
+ dk_fic_report_with_position(
+ 37, 34,
+ er_pr->dt.fpos.byteno, er_pr->dt.fpos.lineno,
+ er_pr->dt.fpos.charno, er_pr->dt.fpos.charinline,
+ fn
+ );
+ }
+ if (2 <= had_processing_errors) { had_processing_errors++; }
+ }
+ }
+}
+
+
+
+/** Write one ASCII-Hex encoded message digest to stdout.
+ @param digptr Start address of text buffer.
+ @param sz Digest size.
+*/
+static
+void
+dk_fic_output_digest(const char *digptr, size_t sz)
+{
+ while (0 < sz--) {
+ if (0 == dk4fputc((dkChar)(*(digptr++)), stdout, NULL)) {
+ dk_fic_write_error = 1;
+ }
+ }
+}
+
+
+
+/** Create checksum line for one file.
+ @param filename File name.
+ @param filesize File size.
+*/
+static
+void
+dk_fic_checksum_file(const dkChar *filename, dk4_um_t filesize)
+{
+ dkChar fszbuf[8*sizeof(dk4_um_t)+16];
+ const dkChar *oldsourcename;
+ const char *md5ptr;
+ const char *sha1ptr;
+ const char *ripemd160ptr;
+#if DK4_HAVE_SHA512
+ const char *sha512ptr;
+#endif
+ FILE *fipo;
+ dk4_um_t oldsourceline;
+ size_t rdb;
+ size_t md5sz;
+ size_t sha1sz;
+ size_t ripemd160sz;
+ size_t sl;
+#if DK4_HAVE_SHA512
+ size_t sha512sz;
+#endif
+ int tests = DK4_FOPEN_SC_IS_REGULAR;
+ int ok = 1;
+ int res;
+ int cc;
+
+ res = dk4md_ctx_init(
+ &ctx_md5, DK4_MD_MD5, DK4_BINARY_TO_TEXT_ENCODING_A85, NULL
+ );
+ if (0 == res) { ok = 0; }
+ res = dk4md_ctx_init(
+ &ctx_sha1, DK4_MD_SHA1, DK4_BINARY_TO_TEXT_ENCODING_A85, NULL
+ );
+ if (0 == res) { ok = 0; }
+ res = dk4md_ctx_init(
+ &ctx_ripemd160, DK4_MD_RIPEMD_160, DK4_BINARY_TO_TEXT_ENCODING_A85, NULL
+ );
+ if (0 == res) { ok = 0; }
+#if DK4_HAVE_SHA512
+ res = dk4md_ctx_init(
+ &ctx_sha512, DK4_MD_SHA512, DK4_BINARY_TO_TEXT_ENCODING_A85, NULL
+ );
+ if (0 == res) { ok = 0; }
+#endif
+ if (0 != ok) {
+ fipo = dk4fopen_app(filename, dk_fic_kwnl[5], tests, app);
+ if (NULL != fipo) {
+ cc = 1;
+ while (1 == cc) {
+ if (dk_fic_can_continue()) {
+ rdb = fread(data_buf, 1, sizeof(data_buf), fipo);
+ if (0 < rdb) {
+ res = dk4md_ctx_add(&ctx_md5, data_buf, rdb, NULL);
+ if (0 == res) { cc = -1; }
+ res = dk4md_ctx_add(&ctx_sha1, data_buf, rdb, NULL);
+ if (0 == res) { cc = -1; }
+ res = dk4md_ctx_add(&ctx_ripemd160, data_buf, rdb, NULL);
+ if (0 == res) { cc = -1; }
+#if DK4_HAVE_SHA512
+ res = dk4md_ctx_add(&ctx_sha512, data_buf, rdb, NULL);
+ if (0 == res) { cc = -1; }
+#endif
+ } else {
+ cc = 0;
+ if (0 != ferror(fipo)) {
+ cc = -1;
+ /* ERROR Read attempt failed */
+ oldsourcename = dk4app_get_log_source_file(app);
+ oldsourceline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_file(app, filename);
+ dk4app_set_log_source_line(app, (dk4_um_t)0UL);
+ dk4app_log_1(
+ app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 4
+ );
+ dk4app_set_log_source_file(app, oldsourcename);
+ dk4app_set_log_source_line(app, oldsourceline);
+ exval = EXIT_FAILURE;
+ }
+ }
+ } else {
+ cc = -1;
+ }
+ }
+ fclose(fipo);
+ if (0 == cc) {
+ md5ptr = NULL; sha1ptr = NULL; ripemd160ptr = NULL;
+ md5sz = 0; sha1sz = 0; ripemd160sz = 0;
+#if DK4_HAVE_SHA512
+ sha512ptr = NULL;
+ sha512sz = 0;
+#endif
+ res = dk4md_ctx_finish(&md5ptr, &md5sz, &ctx_md5, NULL);
+ if (0 == res) { cc = -1; }
+ res = dk4md_ctx_finish(&sha1ptr, &sha1sz, &ctx_sha1, NULL);
+ if (0 == res) { cc = -1; }
+ res = dk4md_ctx_finish(&ripemd160ptr,&ripemd160sz,&ctx_ripemd160,NULL);
+ if (0 == res) { cc = -1; }
+#if DK4_HAVE_SHA512
+ res = dk4md_ctx_finish(&sha512ptr, &sha512sz, &ctx_sha512, NULL);
+ if (0 == res) { cc = -1; }
+#endif
+ if (0 == cc) {
+ res = dk4ma_write_decimal_unsigned(
+ fszbuf, DK4_SIZEOF(fszbuf,dkChar), filesize, 0, NULL
+ );
+ if (0 != res) {
+ dk_fic_output_digest(md5ptr, md5sz);
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ dk_fic_write_error = 1;
+ }
+ dk_fic_output_digest(sha1ptr, sha1sz);
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ dk_fic_write_error = 1;
+ }
+ dk_fic_output_digest(ripemd160ptr, ripemd160sz);
+#if DK4_HAVE_SHA512
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ dk_fic_write_error = 1;
+ }
+ dk_fic_output_digest(sha512ptr, sha512sz);
+#endif
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ dk_fic_write_error = 1;
+ }
+ sl = dk4str_len(fszbuf);
+ while (sl++ < dk_fic_num_len) {
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ dk_fic_write_error = 1;
+ }
+ }
+ if (0 == dk4fputs(fszbuf, stdout, NULL)) {
+ dk_fic_write_error = 1;
+ }
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ dk_fic_write_error = 1;
+ }
+ if (0 == dk4fputs(filename, stdout, NULL)) {
+ dk_fic_write_error = 1;
+ }
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) {
+ dk_fic_write_error = 1;
+ }
+ } else {
+ /* ERROR: Failed to convert file size to text */
+ dk4app_log_3(
+ app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 5, 6, filename
+ );
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Failed to finish at least one message digest */
+ dk4app_log_3(
+ app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 7, 8, filename
+ );
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ if (-1 == cc) {
+ /* ERROR: Failed to add data to message digest context */
+ dk4app_log_3(
+ app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 9, 10, filename
+ );
+ exval = EXIT_FAILURE;
+ }
+ }
+ } else {
+ /* ERROR: Failed to open file, already reported */
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Failed to initialize at least one ctx */
+ dk4app_log_3(
+ app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 11, 12, filename
+ );
+ exval = EXIT_FAILURE;
+ }
+}
+
+
+
+/** Line handler when creating a checksum list.
+ @param obj Object to modify.
+ @param line Text line to process.
+ @param lineno Current line number.
+ @param erp Error report, may be NULL.
+ @return DK4_TSP_RES_OK, DK4_TSP_RES_ERROR, or DK4_TSP_RES_FATAL.
+*/
+static
+int
+dk_fic_create_line_handler(
+ void *obj,
+ dkChar *line,
+ dk4_um_t lineno,
+ dk4_er_t *erp
+)
+{
+ dk4_file_info_t fi;
+ dk4_er_t er;
+ dk4_um_t filesize;
+ int res;
+ int back = DK4_TSP_RES_OK;
+ dk4str_delnl(line);
+ dk4path_correct_sep(line);
+ filesize = (dk4_um_t)0UL;
+ dk4error_init(&er);
+ dk4fileinfo_init(&fi);
+ if (0 != dk4fileinfo_app(&fi, line, app)) {
+ res = dk4fileinfo_size(
+ &filesize, &fi, DK4_FILE_INFO_CONTENTS_DATA_TARGET, &er
+ );
+ if (0 != res) {
+ if (0 != dk4fileinfo_exists_and_is_regular(&fi, &er)) {
+ dk_fic_checksum_file(line, filesize);
+ } else {
+ /* ERROR: Not a regular file */
+ dk4app_log_3(
+ app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 13, 14, line
+ );
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Failed to obtain file size */
+ dk4app_log_3(
+ app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 15, 16, line
+ );
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Failed to information about file, already reported */
+ exval = EXIT_FAILURE;
+ }
+ return back;
+}
+
+
+
+/** Compare current checksum against checksum from file.
+ @param curcs Current checksum.
+ @param orics Original checksum from file.
+ @param curlen Current checksum length.
+ @return 1 if both checksums are equal, 0 otherwise.
+*/
+static
+int
+dk_fic_compare_checksums(
+ const char *curcs,
+ const dkChar *orics,
+ size_t curlen
+)
+{
+ int back = 0;
+
+
+#line 1097 "dk-fic.ctr"
+ if ((NULL != curcs) && (NULL != orics) && (0 < curlen)) {
+ back = 1;
+ while ((1 == back) && (0 < curlen--)) {
+ if ((dkChar)(*(curcs++)) != *(orics++)) {
+ back = 0;
+ }
+ }
+ }
+
+#line 1105 "dk-fic.ctr"
+ return back;
+}
+
+
+
+/** Line handler when verifying a checksum list.
+ @param obj Object to modify.
+ @param line Text line to process.
+ @param lineno Current line number.
+ @param erp Error report, may be NULL.
+ @return DK4_TSP_RES_OK, DK4_TSP_RES_ERROR, or DK4_TSP_RES_FATAL.
+*/
+static
+int
+dk_fic_verify_line_handler(
+ void *obj,
+ dkChar *line,
+ dk4_um_t lineno,
+ dk4_er_t *erp
+)
+{
+ dk4_file_info_t fi; /* File information */
+ dk4_er_t er; /* Error report */
+ FILE *fipo; /* File to read */
+ const dkChar *oldsourcename; /* Source file */
+ const dkChar *endptr; /* Text after size */
+ dkChar *tok[16]; /* Tokens in input line */
+ const char *md5ptr; /* Encoded message digest */
+ const char *sha1ptr; /* Encoded message digest */
+ const char *ripemd160ptr; /* Encoded message digest */
+#if DK4_HAVE_SHA512
+ const char *sha512ptr; /* Encoded message digest */
+#endif
+ dk4_um_t oldsourceline; /* Source line number */
+ dk4_um_t filesize; /* Current file size */
+ dk4_um_t um; /* File size from input line */
+ size_t ntok; /* Number of tokens in input line */
+ size_t i; /* Index to initialize tokens */
+ size_t rdb; /* Number of bytes read */
+ size_t md5sz; /* Encoded digest length */
+ size_t sha1sz; /* Encoded digest length */
+ size_t ripemd160sz; /* Encoded digest length */
+#if DK4_HAVE_SHA512
+ size_t sha512sz; /* Encoded digest length */
+#endif
+ int res; /* Operations result */
+ int cc; /* Flag: Can continue */
+ int tests = DK4_FOPEN_SC_IS_REGULAR;
+ int back = DK4_TSP_RES_ERROR;
+ int ok = 0; /* Flag: Check passed */
+ dk4str_delnl(line);
+
+
+#line 1157 "dk-fic.ctr"
+ /* dk4path_correct_sep(line); Correct file name only! */
+ for (i = 0; i < 16; i++) { tok[i] = NULL; }
+ if (0 != dk_fic_first_line) {
+
+#line 1160 "dk-fic.ctr"
+ dk_fic_first_line = 0;
+ ntok = dk4str_tokenize(tok, 16, line, NULL, NULL);
+ if (3 == ntok) {
+
+#line 1163 "dk-fic.ctr"
+ if (dkT('#') == *(tok[0])) {
+ if (0 == dk4str_cmp(dk_fic_kwnl[9], tok[1])) {
+ endptr = NULL;
+ if (0 != dk4ma_input_dk_dec_dk4_um_t(&um, tok[2], &endptr, 1, NULL)) {
+ if ((dk4_um_t)3UL == um) {
+
+#line 1168 "dk-fic.ctr"
+ dk_fic_num_mds = 3;
+ back = DK4_TSP_RES_OK;
+ } else {
+ if ((dk4_um_t)4UL == um) {
+
+#line 1172 "dk-fic.ctr"
+ dk_fic_num_mds = 4;
+ back = DK4_TSP_RES_OK;
+#if !DK4_HAVE_SHA512
+ /* Warning SHA-512 checksum ignored, not supported */
+ dk4app_log_1(
+ app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_WARNING, 17
+ );
+#endif
+ } else {
+
+#line 1181 "dk-fic.ctr"
+ }
+ }
+ } else {
+
+#line 1184 "dk-fic.ctr"
+ }
+ } else {
+
+#line 1186 "dk-fic.ctr"
+ }
+ } else {
+
+#line 1188 "dk-fic.ctr"
+ }
+ } else {
+
+#line 1190 "dk-fic.ctr"
+ }
+ if (DK4_TSP_RES_ERROR == back) {
+ /* ERROR: Syntax error */
+ dk4app_log_1(
+ app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 18
+ );
+ exval = EXIT_FAILURE;
+ }
+ } else {
+
+#line 1199 "dk-fic.ctr"
+ ntok = dk4str_tokenize(tok, 16, line, NULL, NULL);
+
+
+#line 1201 "dk-fic.ctr"
+ if ((5 == ntok) && (3 == dk_fic_num_mds)) {
+
+#line 1202 "dk-fic.ctr"
+ back = DK4_TSP_RES_OK;
+ } else {
+ if ((6 == ntok) && (4 == dk_fic_num_mds)) {
+
+#line 1205 "dk-fic.ctr"
+ back = DK4_TSP_RES_OK;
+ }
+ }
+ if (DK4_TSP_RES_OK == back) {
+
+#line 1209 "dk-fic.ctr"
+#if VERSION_BEFORE_20150821
+ back = DK4_TSP_RES_ERROR;
+#endif
+ dk4path_correct_sep(tok[ntok - 1]);
+ dk4error_init(&er);
+ dk4fileinfo_init(&fi);
+ if (0 != dk4fileinfo_app(&fi, tok[ntok - 1], app)) {
+
+#line 1216 "dk-fic.ctr"
+ filesize = (dk4_um_t)0UL;
+ res = dk4fileinfo_size(
+ &filesize, &fi, DK4_FILE_INFO_CONTENTS_DATA_TARGET, &er
+ );
+ if (0 != res) {
+
+#line 1221 "dk-fic.ctr"
+ res = dk4ma_input_dk_dec_dk4_um_t(&um, tok[ntok-2], &endptr, 1, NULL);
+ if (0 != res) {
+
+#line 1223 "dk-fic.ctr"
+ if (um == filesize) {
+
+#line 1224 "dk-fic.ctr"
+ ok = 1;
+ /* Initialize message digest contexts.
+ */
+ res = dk4md_ctx_init(
+ &ctx_md5, DK4_MD_MD5, DK4_BINARY_TO_TEXT_ENCODING_A85, NULL
+ ); if (0 == res) { ok = 0; }
+ res = dk4md_ctx_init(
+ &ctx_sha1, DK4_MD_SHA1, DK4_BINARY_TO_TEXT_ENCODING_A85, NULL
+ ); if (0 == res) { ok = 0; }
+ res = dk4md_ctx_init(
+ &ctx_ripemd160,DK4_MD_RIPEMD_160,
+ DK4_BINARY_TO_TEXT_ENCODING_A85, NULL
+ ); if (0 == res) { ok = 0; }
+#if DK4_HAVE_SHA512
+ if (6 == ntok) {
+
+#line 1239 "dk-fic.ctr"
+ res = dk4md_ctx_init(
+ &ctx_sha512,DK4_MD_SHA512,DK4_BINARY_TO_TEXT_ENCODING_A85,NULL
+ );
+ if (0 == res) {
+
+#line 1243 "dk-fic.ctr"
+ ok = 0;
+ }
+ }
+#endif
+ if (0 != ok) {
+
+#line 1248 "dk-fic.ctr"
+ ok = 0;
+ fipo = dk4fopen_app(tok[ntok-1], dk_fic_kwnl[5], tests, app);
+ if (NULL != fipo) {
+
+#line 1251 "dk-fic.ctr"
+ ok = 1;
+ cc = 1;
+ while (1 == cc) {
+
+#line 1254 "dk-fic.ctr"
+ if (dk_fic_can_continue()) {
+
+#line 1255 "dk-fic.ctr"
+ rdb = fread(data_buf, 1, sizeof(data_buf), fipo);
+ if (0 < rdb) {
+
+#line 1257 "dk-fic.ctr"
+ /* Add data from file to message digest contexts.
+ */
+ res = dk4md_ctx_add(&ctx_md5, data_buf, rdb, NULL);
+ if (0 == res) { ok = 0; cc = -1; }
+ res = dk4md_ctx_add(&ctx_sha1, data_buf, rdb, NULL);
+ if (0 == res) { ok = 0; cc = -1; }
+ res = dk4md_ctx_add(&ctx_ripemd160,data_buf,rdb,NULL);
+ if (0 == res) { ok = 0; cc = -1; }
+#if DK4_HAVE_SHA512
+ if (6 == ntok) {
+ res = dk4md_ctx_add(&ctx_sha512, data_buf, rdb, NULL);
+ if (0 == res) { ok = 0; cc = -1; }
+ }
+#endif
+ if (0 == ok) {
+ dk4app_log_3(
+ app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR,
+ 9, 10, tok[ntok-1]
+ );
+ }
+ } else {
+
+#line 1278 "dk-fic.ctr"
+ cc = 0;
+ if (0 != ferror(fipo)) {
+
+#line 1280 "dk-fic.ctr"
+ cc = -1;
+ /* ERROR Read attempt failed */
+ oldsourcename = dk4app_get_log_source_file(app);
+ oldsourceline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_file(app, tok[ntok-1]);
+ dk4app_set_log_source_line(app, (dk4_um_t)0UL);
+ dk4app_log_1(
+ app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 4
+ );
+ dk4app_set_log_source_file(app, oldsourcename);
+ dk4app_set_log_source_line(app, oldsourceline);
+ exval = EXIT_FAILURE;
+ }
+ }
+ } else {
+
+#line 1295 "dk-fic.ctr"
+ cc = -1;
+ }
+ }
+ fclose(fipo);
+ if (0 == cc) {
+
+#line 1300 "dk-fic.ctr"
+ /* Retrieve results from message digest contexts.
+ */
+ md5ptr = NULL; sha1ptr = NULL; ripemd160ptr = NULL;
+ md5sz = 0; sha1sz = 0; ripemd160sz = 0;
+#if DK4_HAVE_SHA512
+ sha512ptr = NULL;
+
+#line 1306 "dk-fic.ctr"
+ sha512sz = 0;
+#endif
+ res = dk4md_ctx_finish(&md5ptr, &md5sz, &ctx_md5, NULL);
+ if (0 == res) {
+ ok = 0;
+#if VERSION_BEFORE_20150821
+ cc = -1;
+#endif
+ }
+ res = dk4md_ctx_finish(&sha1ptr, &sha1sz, &ctx_sha1, NULL);
+ if (0 == res) {
+ ok = 0;
+#if VERSION_BEFORE_20150821
+ cc = -1;
+#endif
+ }
+ res = dk4md_ctx_finish(
+ &ripemd160ptr,&ripemd160sz,&ctx_ripemd160,NULL
+ );
+ if (0 == res) {
+ ok = 0;
+#if VERSION_BEFORE_20150821
+ cc = -1;
+#endif
+ }
+#if DK4_HAVE_SHA512
+ if (6 == ntok) {
+
+#line 1333 "dk-fic.ctr"
+ res = dk4md_ctx_finish(
+ &sha512ptr, &sha512sz, &ctx_sha512, NULL
+ );
+
+#line 1336 "dk-fic.ctr"
+ if (0 == res) {
+ ok = 0;
+#if VERSION_BEFORE_20150821
+ cc = -1;
+#endif
+ }
+ }
+#endif
+ if (0 == ok) {
+ dk4app_log_3(
+ app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR,
+ 7, 8, tok[ntok-1]
+ );
+ }
+ /* Compare current results against input contents.
+ */
+ if (0 != ok) {
+
+#line 1353 "dk-fic.ctr"
+ res = dk_fic_compare_checksums(md5ptr, tok[0], md5sz);
+ if (0 == res) {
+
+#line 1355 "dk-fic.ctr"
+ ok = 0;
+ }
+ }
+ if (0 != ok) {
+
+#line 1359 "dk-fic.ctr"
+ res = dk_fic_compare_checksums(sha1ptr, tok[1], sha1sz);
+ if (0 == res) {
+
+#line 1361 "dk-fic.ctr"
+ ok = 0;
+ }
+ }
+ if (0 != ok) {
+
+#line 1365 "dk-fic.ctr"
+ res = dk_fic_compare_checksums(
+ ripemd160ptr, tok[2], ripemd160sz
+ );
+ if (0 == res) {
+
+#line 1369 "dk-fic.ctr"
+ ok = 0;
+ }
+ }
+
+#if DK4_HAVE_SHA512
+ if (6 == ntok) {
+
+#line 1375 "dk-fic.ctr"
+ if (0 != ok) {
+
+#line 1376 "dk-fic.ctr"
+ res = dk_fic_compare_checksums(
+ sha512ptr, tok[3], sha512sz
+ );
+ if (0 == res) {
+
+#line 1380 "dk-fic.ctr"
+ ok = 0;
+ }
+ }
+ }
+#endif
+ } else {
+
+#line 1386 "dk-fic.ctr"
+ ok = 0;
+ }
+ } else {
+
+#line 1389 "dk-fic.ctr"
+ }
+ } else {
+
+#line 1391 "dk-fic.ctr"
+ /* ERROR Failed to initialize MD contexts */
+ dk4app_log_3(
+ app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 11, 12,
+ tok[ntok-1]
+ );
+ }
+ } else {
+
+#line 1398 "dk-fic.ctr"
+ }
+ if (0 != ok) {
+
+#line 1400 "dk-fic.ctr"
+ if (2 <= dk_fic_verbosity) {
+ if (0 == dk4fputs(dk_fic_msg[2], stdout, NULL)) {
+ exval = EXIT_FAILURE; dk_fic_write_error = 1;
+ }
+ if (0 == dk4fputs(tok[ntok-1], stdout, NULL)) {
+ exval = EXIT_FAILURE; dk_fic_write_error = 1;
+ }
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) {
+ exval = EXIT_FAILURE; dk_fic_write_error = 1;
+ }
+ }
+ } else {
+
+#line 1412 "dk-fic.ctr"
+ exval = EXIT_FAILURE;
+ if (1 <= dk_fic_verbosity) {
+ if (0 == dk4fputs(dk_fic_msg[3], stdout, NULL)) {
+ exval = EXIT_FAILURE; dk_fic_write_error = 1;
+ }
+ if (0 == dk4fputs(tok[ntok-1], stdout, NULL)) {
+ exval = EXIT_FAILURE; dk_fic_write_error = 1;
+ }
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) {
+ exval = EXIT_FAILURE; dk_fic_write_error = 1;
+ }
+ }
+ }
+ } else {
+
+#line 1426 "dk-fic.ctr"
+ /* Syntax error */
+ dk4app_log_3(
+ app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 21, 22, tok[ntok-2]
+ );
+ exval = EXIT_FAILURE;
+ }
+ } else {
+
+#line 1433 "dk-fic.ctr"
+ /* ERROR: Failed to retrieve file size */
+ dk4app_log_3(
+ app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 15, 16, line
+ );
+ exval = EXIT_FAILURE;
+ }
+ } else {
+
+#line 1440 "dk-fic.ctr"
+ /* ERROR: Failed to information about file, already reported */
+ exval = EXIT_FAILURE;
+ }
+#if VERSION_BEFORE_20150821
+ back = DK4_TSP_RES_OK;
+#endif
+ } else {
+
+#line 1447 "dk-fic.ctr"
+ /* Syntax error */
+ if (3 == dk_fic_num_mds) {
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 20);
+ } else {
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 19);
+ }
+ exval = EXIT_FAILURE;
+ }
+ }
+
+
+#line 1457 "dk-fic.ctr"
+ return back;
+}
+
+
+
+/** Process one file.
+ @param fipo Opened file.
+ @param fn File name.
+ @param ie Expected input encoding.
+*/
+static
+void
+dk_fic_process_file(FILE *fipo, const dkChar *fn, int ie)
+{
+ dk4_tspdk_t tsp;
+ dk4_er_t er_en;
+ dk4_er_t er_pr;
+ dk4_er_t er;
+ int res;
+ int cc;
+ int c;
+ unsigned char ub;
+
+
+#line 1480 "dk-fic.ctr"
+ dk4error_init(&er_en);
+ dk4error_init(&er_pr);
+ dk4error_init(&er);
+ res = dk4tspdk_setup_line(
+ &tsp, NULL,
+ (
+ (0 != dk_fic_verify)
+ ? dk_fic_verify_line_handler
+ : dk_fic_create_line_handler
+ ),
+ ibuf_ptr, ibuf_sz,
+ dk4app_get_encoding(app), ie,
+ &er
+ );
+ if (0 != res) {
+ cc = 1;
+ dk_fic_first_line = 1;
+ dk_fic_num_mds = 4;
+ do {
+ if (dk_fic_can_continue()) {
+ c = fgetc(fipo);
+ if (EOF != c) {
+ ub = (unsigned char)c;
+ switch (dk4tspdk_add_one_byte(&tsp, ub)) {
+ case DK4_TSP_RES_FATAL : {
+ cc = -1;
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tsp);
+ dk_fic_report_errors(&er_en, &er_pr, fn);
+ } break;
+ case DK4_TSP_RES_ERROR : {
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tsp);
+ dk_fic_report_errors(&er_en, &er_pr, fn);
+ } break;
+ }
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = -1;
+ }
+ } while (1 == cc);
+ if (0 == cc) {
+ switch (dk4tspdk_finish(&tsp)) {
+ case DK4_TSP_RES_FATAL : {
+#if VERSION_BEFORE_20150821
+ cc = -1;
+#endif
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tsp);
+ dk_fic_report_errors(&er_en, &er_pr, fn);
+ } break;
+ case DK4_TSP_RES_ERROR : {
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tsp);
+ dk_fic_report_errors(&er_en, &er_pr, fn);
+ } break;
+ }
+ }
+ } else {
+ /* ERROR: Failed to initialize text stream processor */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 23);
+ exval = EXIT_FAILURE;
+ }
+
+
+#line 1546 "dk-fic.ctr"
+}
+
+
+
+static
+void
+dk_fic_process_filename(const dkChar *filename)
+{
+ FILE *fipo;
+ int tests = DK4_FOPEN_SC_IS_REGULAR;
+ fipo = dk4fopen_app(filename, dk_fic_kwnl[5], tests, app);
+ if (NULL != fipo) {
+ dk_fic_process_file(fipo, filename, dk_fic_ie_file);
+ fclose(fipo);
+ } else {
+ exval = EXIT_FAILURE;
+ }
+}
+
+
+
+#if DK4_ON_WINDOWS
+static
+void
+dk_fic_expand_path_and_file(
+ dkChar *bptr,
+ size_t bsz,
+ const dkChar *pth,
+ const dkChar *shf
+)
+{
+ if (0 != dk4str_cpy_s(bptr, bsz, pth, NULL)) {
+ if (0 != dk4str_cat_s(bptr, bsz, dk_fic_kwnl[6], NULL)) {
+ if (0 != dk4str_cat_s(bptr, bsz, shf, NULL)) {
+ dk_fic_process_filename(bptr);
+ } else {
+ /* ERROR: Name too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, shf);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Name too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Name too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ exval = EXIT_FAILURE;
+ }
+}
+
+
+
+static
+void
+dk_fic_expand_filename(const dkChar *pattern)
+{
+ dkChar buf[DK4_MAX_PATH];
+ dk4_dir_t *fne;
+ const dkChar *shf;
+ const dkChar *pth;
+ int any_file_found = 0;
+ int can_continue;
+
+
+#line 1611 "dk-fic.ctr"
+ fne = dk4app_fne_open(pattern, app);
+ if (NULL != fne) {
+ do {
+ shf = dk4dir_next_file(fne);
+ if (NULL != shf) {
+ any_file_found = 1;
+ can_continue = dk_fic_can_continue();
+ if (0 != can_continue) {
+ pth = dk4dir_get_path(fne);
+ if (NULL != pth) {
+ dk_fic_expand_path_and_file(buf, DK4_SIZEOF(buf,dkChar), pth, shf);
+ } else {
+ dk_fic_process_filename(shf);
+ }
+ }
+ } else {
+ can_continue = 0;
+ }
+ } while (1 == can_continue);
+ dk4dir_close(fne);
+ if (0 == any_file_found) {
+ /* ERROR: No matching file found */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 107, pattern);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ exval = EXIT_FAILURE;
+ }
+
+
+#line 1640 "dk-fic.ctr"
+}
+#endif
+
+#endif
+/* if DK4_HAVE_... */
+
+
+
+/** Process the command line arguments.
+*/
+static
+void
+dk_fic_run_for_command_line_args(void)
+{
+ const dkChar *filename;
+ int xargc;
+ int i;
+#if DK4_HAVE_OPENSSL_MD5_H && DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_OPENSSL_RIPEMD_H
+#if DK4_ON_WINDOWS
+ int oldmode;
+#endif
+ if (0 == dk_fic_verify) {
+#if DK4_HAVE_SHA512
+ dk4fputs(dk_fic_kwnl[8], stdout, NULL);
+#else
+ dk4fputs(dk_fic_kwnl[7], stdout, NULL);
+#endif
+ }
+ xargc = dk4app_get_argc(app);
+ if (0 < xargc) {
+ for (i = 0; ((0 != dk_fic_can_continue()) && (i < xargc)); i++) {
+ filename = dk4app_get_argv(app, i);
+ if (NULL != filename) {
+#if DK4_ON_WINDOWS
+ if (0 != dk4path_must_expand(filename)) {
+ dk_fic_expand_filename(filename);
+ } else {
+#endif
+ dk_fic_process_filename(filename);
+#if DK4_ON_WINDOWS
+ }
+#endif
+ } else {
+ /* ERROR: Failed to obtain command line argument, bug! */
+ exval = EXIT_FAILURE;
+ }
+ }
+ } else {
+#if DK4_ON_WINDOWS
+ oldmode = _setmode(_fileno(stdin), _O_BINARY);
+#endif
+ dk_fic_process_file(stdin, dk_fic_kwnl[4], dk_fic_ie_stdin);
+#if DK4_ON_WINDOWS
+ _setmode(_fileno(stdin), oldmode);
+#endif
+ }
+#else
+ /* ERROR: At least one unsupported message digest type */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 24);
+ exval = EXIT_FAILURE;
+#endif
+}
+
+
+
+/** Process options and preferences.
+*/
+static
+void
+dk_fic_normal_run(void)
+{
+ dkChar encbuf[64];
+ size_t myll = 0;
+ int res;
+
+ /* Assume success.
+ */
+ exval = EXIT_SUCCESS;
+
+ /* Process command line options.
+ */
+ if (0 != dk4app_opt_is_set_short(app, dkT('c'), NULL)) {
+ dk_fic_verify = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('q'), NULL)) {
+ dk_fic_verbosity = 0;
+ if (0 != dk4app_opt_is_set_short(app, dkT('v'), NULL)) {
+ /* ERROR: Options -q an -v are mutually exclusve */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 25);
+ exval = EXIT_FAILURE;
+ goto finished;
+ }
+ } else {
+ if (0 != dk4app_opt_is_set_short(app, dkT('v'), NULL)) {
+ dk_fic_verbosity = 2;
+ }
+ }
+#if VERSION_BEFORE_20150821
+ res = 0;
+#endif
+ if (0 != dk4app_opt_is_set_short(app, dkT('i'), NULL)) {
+ res = dk4app_opt_get_string_short(
+ encbuf, DK4_SIZEOF(encbuf,dkChar), app, dkT('i'), NULL
+ );
+ if (0 != res) {
+ res = dk4enc_find(&dk_fic_ie_stdin, NULL, encbuf, NULL);
+ if (0 != res) {
+ dk_fic_ie_file = dk_fic_ie_stdin;
+ } else {
+ /* ERROR: Encoding not found! */
+ dk4app_log_3(
+ app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 26, 27, encbuf
+ );
+ exval = EXIT_FAILURE;
+ goto finished;
+ }
+ }
+ }
+ res = 0;
+ if (0 != dk4app_opt_is_set_short(app, dkT('l'), NULL)) {
+ res = dk4app_opt_get_size_short(&myll, app, dkT('l'), NULL);
+ }
+ if ((0 == res) && (0 == dk4app_opt_is_set_short(app, dkT('R'), NULL))) {
+ res = dk4app_pref_get_size(&myll, app, dk_fic_kwnl[3], 0);
+ }
+ if ((0 != res) && (DK4_SIZEOF(ibuf_def,dkChar) < myll)) {
+ ibuf_all = dk4mem_new_app(dkChar, myll, app);
+ if (NULL != ibuf_all) {
+ ibuf_ptr = ibuf_all;
+ ibuf_sz = myll;
+ } else {
+ goto finished;
+ }
+ }
+
+ /* If no errors yet, process input.
+ */
+ if (EXIT_SUCCESS == exval) {
+ dk_fic_run_for_command_line_args();
+ }
+
+ /* Clean up dynamic buffers, if any.
+ */
+ finished:
+ if (NULL != ibuf_all) {
+ dk4mem_release(ibuf_all);
+ }
+}
+
+
+
+/* SIGNAL HANDLING */
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+dk_fic_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ struct sigaction opipe;
+#endif
+ struct sigaction oint;
+#ifdef SIGPIPE
+ struct sigaction npipe;
+#endif
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+ int success = 0;
+
+#ifdef SIGPIPE
+ /* Set up signal handling for SIGPIPE.
+ */
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+#endif
+
+ /* Set up signal handling for SIGINT.
+ */
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ dk_fic_normal_run();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+#ifdef SIGPIPE
+ /* Restore signal handling for SIGPIPE.
+ */
+ restore_old_pipe:
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+#endif
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+dk_fic_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ dk_fic_normal_run();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+#ifdef SIGPIPE
+ sigset(SIGPIPE, oldpipe);
+#endif
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+dk_fic_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = signal(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ dk_fic_normal_run();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+#ifdef SIGPIPE
+ signal(SIGPIPE, oldpipe);
+#endif
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+dk_fic_run_with_signal_handlers(void)
+{
+ dk_fic_normal_run();
+}
+#endif
+#endif
+#endif
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+
+
+#line 1993 "dk-fic.ctr"
+
+
+#line 1994 "dk-fic.ctr"
+ dk_fic_num_len = dk4numlength(sizeof(dk4_um_t), 0);
+ dk4fput_initialize_stdout();
+ dk4fput_initialize_stderr();
+ app = dk4app_open_cmd(
+ argc, argv, dk_fic_options, dk_fic_sz_options,
+ dk_fic_kwnl[0], DKT_VERSION_DK,
+ dk_fic_kwnl[1], dk_fic_help_text, dk_fic_license_text
+ );
+ if (NULL != app) {
+ dk_fic_sz_msg = dk4app_string_table_size(dk_fic_kw_def);
+ dk_fic_msg = dk4app_string_table(app, dk_fic_kwnl[2], dk_fic_kw_def);
+ dk_fic_ie_stdin = dk4app_get_stdin_encoding(app);
+ dk_fic_ie_file = dk4app_get_file_in_encoding(app);
+ if (0 != dk4app_can_run_normally(app)) {
+ dk_fic_run_with_signal_handlers();
+ } else {
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ if (0 != dk_fic_write_error) {
+ /* ERROR While writing output */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 28);
+ exval = EXIT_FAILURE;
+ }
+#ifdef SIGPIPE
+ if (0 != sig_read_atomic(&sig_had_int)) {
+ /* Signal PIPE */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 29);
+ exval = EXIT_FAILURE;
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_int)) {
+ /* Signal INT */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 30);
+ exval = EXIT_FAILURE;
+ }
+ if (0 != sig_read_atomic(&sig_had_term)) {
+ /* Signal TERM */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 31);
+ exval = EXIT_FAILURE;
+ }
+ dk4app_close(app);
+ }
+ fflush(stdout);
+ fflush(stderr);
+ dk4fput_cleanup_stderr();
+ dk4fput_cleanup_stdout();
+
+
+#line 2043 "dk-fic.ctr"
+
+
+#line 2044 "dk-fic.ctr"
+ exit (exval); return exval;
+}
+
+
diff --git a/support/dktools/dk-fic.ctr b/support/dktools/dk-fic.ctr
new file mode 100644
index 0000000000..bb9251480f
--- /dev/null
+++ b/support/dktools/dk-fic.ctr
@@ -0,0 +1,2047 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+%% module
+
+/** @file dk-fic.c File integrity checker.
+*/
+
+
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4vers.h"
+#include "dk4app.h"
+#include "dk4aopt.h"
+#include "dk4mem.h"
+#include "dk4mema.h"
+#include "dk4fput.h"
+#include "dk4mpl.h"
+#include "dk4enc.h"
+#include "dk4tspdk.h"
+#include "dk4fopda.h"
+#include "dk4pathd.h"
+#include "dk4md.h"
+#include "dk4maodd.h"
+#include "dk4filed.h"
+#include "dk4fileid.h"
+#include "dk4filei.h"
+#include "dk4fileia.h"
+#include "dk4strd.h"
+#include "dk4numl.h"
+#include "dk4maidddu.h"
+
+
+
+$!trace-include
+
+
+
+/** Default help text, shown if help text file is not found.
+*/
+static const dkChar * const dk_fic_help_text[] = {
+$!text macro=dkT
+
+File integrity checker
+
+Create checksum lists for files or verify files against a checksum list.
+
+dk-fic [<options>] [<file(s)>]
+
+Options:
+-c --check Check (verify a checksum list).
+-v --verbose Messages for succeeded tests.
+-q --quiet No messages for failed tests.
+-l <size> --line-size=<size> Size for input line buffer.
+
+--help Show this short help text.
+--manual *** SHOW FULL MANUAL. ***
+--version Show version information.
+--license Show license information.
+
+Typical operations:
+find <directory> -type f | dk-fic > checklist.txt Create check-
+dk-ls -r -tf -pn <directory> | dk-fic > checklist.txt sum list.
+dk-fic -c < checklist.txt Verify files.
+
+http://dktools.sourceforge.net
+
+$!end
+};
+
+
+
+/** License conditions.
+*/
+static const dkChar * const dk_fic_license_text[] = {
+$!text macro=dkT,preprocessor
+
+This software uses code from the following projects, either directly or as
+a library:
+
+dktools Dirk Krause's tools and libraries.
+ See http://dktools.sourceforge.net/ for more information.
+#if DK4_HAVE_ZLIB_H
+
+zlib Data compression library.
+ See http://www.zlib.net/ for more information.
+#endif
+#if DK4_HAVE_BZLIB_H
+
+bzip2 Data compression program and library.
+ See http://www.bzip.org/ for more information.
+#endif
+
+All the licenses below apply to the program.
+Licenses for used libraries are shown as found on my Scientific Linux 6.x
+computer in the /usr/share/doc directory on 2015-04-01. Check the project
+homepages of the used libraries for additional information and/or updated
+license terms.
+
+
+DK tools and libraries license
+==============================
+Copyright (c) 2015-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#if DK4_HAVE_ZLIB_H
+
+
+Zlib license
+============
+(C) 1995-2004 Jean-loup Gailly and Mark Adler
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+
+Jean-loup Gailly Mark Adler
+jloup@gzip.org madler@alumni.caltech.edu
+#endif
+#if DK4_HAVE_BZLIB_H
+
+
+Bzip2 and libbzip2 library license
+==================================
+This program, "bzip2", the associated library "libbzip2", and all
+documentation, are copyright (C) 1996-2007 Julian R Seward. All
+rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+3. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Julian Seward, jseward@bzip.org
+bzip2/libbzip2 version 1.0.5 of 10 December 2007
+#endif
+
+$!end
+};
+
+
+
+/** Keywords used by the program, not localized.
+*/
+static const dkChar * const dk_fic_kwnl[] = {
+$!string-table macro=dkT
+#
+# 0 Application group name
+#
+dktools
+#
+# 1 Help file text name
+#
+dk-fic.txt
+#
+# 2 String table file
+#
+dk-fic.str
+#
+# 3 Preference name for line buffer size.
+#
+line.size
+#
+# 4 File name for standard input
+#
+stdin
+#
+# 5 File opening mode for binary reading
+#
+rb
+#
+# 6 Path separator for Windows
+#
+\\
+#
+# 7 First output line if SHA-512 not available
+#
+\# dk-fic 3\n
+#
+# 8 First output line if SHA-512 is available
+#
+\# dk-fic 4\n
+#
+# 9 Keyword dk-fic must appear in line 1
+#
+dk-fic
+$!end
+};
+
+
+
+/** Default keywords, localized.
+*/
+static const dkChar * const dk_fic_kw_def[] = {
+$!string-table macro=dkT
+#
+# 0 Error message: Failed to set up signal handlers
+#
+Failed to set up signal handlers!
+#
+# 1 Error message: Failed to restore signal handlers
+#
+Failed to restore signal handlers!
+#
+# 2 Test passed
+#
+PASSED
+#
+# 3 Test failed
+#
+FAILED
+#
+# 4 Error message: Failed to read data from file!
+#
+Failed to read data from file!
+#
+# 5 6 Error message: Failed to convert file size to text!
+#
+Failed to convert file size to text for file:\n\t"
+"!
+#
+# 7 8 Error message: Failed to finish at least one message digest!
+#
+Failed to finish at least one message digest for file:\n\t"
+"!
+#
+# 9 10 Error message: Failed to add data to message digest!
+#
+Failed to add data to message digest for file:\n\t"
+"!
+#
+# 11 12 Error message: Failed to initialize message digest!
+#
+Failed to initialize at least one message digest for file:\n\t"
+"!
+#
+# 13 14 Error message: not a regular file!
+#
+Not a regular file:\n\t"
+"!
+#
+# 15 16 Error message: Failed to obtain file size
+#
+Failed to obtain file size:\n\t"
+"!
+#
+# 17 Warning: SHA-512 not supported
+#
+SHA-512 message digest not supported, SHA-512 checksums ignored.
+#
+# 18 Syntax error
+#
+Syntax error, first line must be "# dk-fic 3" or "# dk-fic 4"!
+#
+# 19 20 Syntax error, data line expected:
+#
+Syntax error, expected:\n\tmd5 sha-1 ripemd-160 sha-512 size name
+Syntax error, expected:\n\tmd5 sha-1 ripemd-160 size name
+#
+# 21 22 Syntax, error, invalid file size:
+#
+Syntax error, invalid file size: "
+"!
+#
+# 23 Error message: Failed to set up text line processing!
+#
+Failed to set up text line processing!
+#
+# 24 Error message: Missing support for a message digest!
+#
+Build problem: At least one required message digest type is not supported!
+#
+# 25 Error message: Options -q and -v are mutually exclusive!
+#
+Options -q and -v are mutually exclusive!
+#
+# 26 27 Error message: Encoding not found!
+#
+Encoding not found: "
+"!
+#
+# 28 Error message: Problems while writing output!
+#
+Problems while writing output!
+#
+# 29 Error message: Signal SIGPIPE received!
+#
+Signal SIGPIPE received!
+#
+# 30 Error message: Aborted by SIGINT signal!
+#
+Aborted by SIGINT signal!
+#
+# 31 Error message: Aborted by SIGTERM signal!
+#
+Aborted by SIGTERM signal!
+#
+# 32 33 34 Decoding/encoding/processing error
+#
+Decoding error!
+Encoding error!
+Processing error!
+#
+# 35 36 37 38 39 40 Decoding/encoding/processing error!
+#
+Decoding error!\n\tByte:
+Encoding error!\n\tByte:
+Processing error!\n\tByte:
+,\n\tCharacter:
+,\n\tPosition in line:
+.
+$!end
+};
+
+/* VARIABLES */
+
+/** Options for the program.
+*/
+static const dk4_option_specification_t dk_fic_options[] = {
+
+ /* Check (input is a previously generated checksum list.
+ */
+ { dkT('c'), dkT("check"), DK4_OPT_ARG_NONE },
+
+ /* Input line size.
+ */
+ { dkT('l'), dkT("line-size"), DK4_OPT_ARG_SIZE },
+
+ /* Quite when checking (only set exit status code).
+ */
+ { dkT('q'), dkT("quiet"), DK4_OPT_ARG_NONE },
+
+ /* Verbose (write report line for succeeded test too).
+ */
+ { dkT('v'), dkT("verbose"), DK4_OPT_ARG_NONE },
+
+ /* Expected input encoding.
+ */
+ { dkT('i'), dkT("input-encoding"), DK4_OPT_ARG_STRING },
+
+};
+
+
+
+/** Data buffer for reading the file.
+*/
+static char data_buf[4096];
+
+
+
+/** Default input line buffer.
+*/
+static dkChar ibuf_def[256 + DK4_MAX_PATH];
+
+
+#if DK4_HAVE_OPENSSL_MD5_H && DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_OPENSSL_RIPEMD_H
+
+static dk4_md_ctx_t ctx_md5;
+
+static dk4_md_ctx_t ctx_sha1;
+
+static dk4_md_ctx_t ctx_ripemd160;
+
+#if DK4_HAVE_SHA512
+
+static dk4_md_ctx_t ctx_sha512;
+
+#endif
+
+#endif
+
+
+/** Allocated input buffer for larger line size.
+*/
+static dkChar *ibuf_all = NULL;
+
+
+
+/** Pointer to real input buffer to use.
+*/
+static dkChar *ibuf_ptr = ibuf_def;
+
+
+
+/** Input line buffer size.
+*/
+static size_t ibuf_sz = DK4_SIZEOF(ibuf_def,dkChar);
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Message array, localized messages or default texts.
+*/
+static const dkChar * const *dk_fic_msg = dk_fic_kw_def;
+
+
+
+/** Number of elements in the dk_fic_msg array.
+*/
+static size_t dk_fic_sz_msg =
+sizeof(dk_fic_kw_def)/sizeof(DK4_PCDKCHAR) - 1;
+
+
+/** Number of elements in the dk_fic_options array.
+*/
+static const size_t dk_fic_sz_options =
+sizeof(dk_fic_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Length of file size to print.
+*/
+static size_t dk_fic_num_len = 2 * sizeof(dk4_um_t);
+
+
+
+/** Number of message digests (3 or 4).
+*/
+static size_t dk_fic_num_mds = 4;
+
+
+
+/** Flag: Write error occured while writing output.
+*/
+static int dk_fic_write_error = 0;
+
+
+
+/** Exit status code.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+/** Flag: Verify checksums instead of creating them.
+*/
+static int dk_fic_verify = 0;
+
+
+
+/** Verbosity level (0=silent, 1=errors, 2=errors+success).
+*/
+static int dk_fic_verbosity = 1;
+
+
+
+/** Input encoding expected on standard input.
+*/
+static int dk_fic_ie_stdin = DK4_FILE_ENCODING_ASCII;
+
+
+
+/** Input encoding expected on files.
+*/
+static int dk_fic_ie_file = DK4_FILE_ENCODING_ASCII;
+
+
+
+/** Flag: Current line to process is first line of data stream.
+*/
+static int dk_fic_first_line = 0;
+
+
+
+/* SIGNAL HANDLING VARIABLES AND HANDLER FUNCTIONS */
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+/** Pass a volatile pointer to an atomic integer.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ptr Address of atomic integer variable.
+ @return The unmodified pointer.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+/** Check whether we can continue or if a signal was received.
+ @param check_pipe Flag: Check for occured SIGPIPE signal too.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(int check_pipe)
+{
+ int back = 1;
+#ifdef SIGPIPE
+ if (0 != check_pipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_int )) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+/* FUNCTIONS */
+
+
+static
+int
+dk_fic_can_continue(void)
+{
+ int back;
+ back = sig_can_continue(1);
+ if (0 != back) {
+ if (0 != dk_fic_write_error) {
+ back = 0;
+ }
+ }
+ return back;
+}
+
+
+#if DK4_HAVE_OPENSSL_MD5_H && DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_OPENSSL_RIPEMD_H
+
+
+
+/** Report an error with position.
+ @param i1 Index of first message part in array.
+ @param i2 Index of alternative first message part.
+ @param bno Current byte number.
+ @param lno Current line number.
+ @param cno Current character number.
+ @param cil Current character number within line.
+ @param fn File name processed.
+*/
+static
+void
+dk_fic_report_with_position(
+ size_t i1,
+ size_t i2,
+ dk4_um_t bno,
+ dk4_um_t lno,
+ dk4_um_t cno,
+ dk4_um_t cil,
+ const dkChar *fn
+)
+{
+ dkChar b1[8*(1+sizeof(dk4_um_t))+16];
+ dkChar b2[8*(1+sizeof(dk4_um_t))+16];
+ dkChar b3[8*(1+sizeof(dk4_um_t))+16];
+ const dkChar *oldlogname = NULL;
+ dk4_um_t oldlogline = (dk4_um_t)0UL;
+ int allbuffersok = 0;
+
+ oldlogname = dk4app_get_log_source_file(app);
+ oldlogline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_file(app, fn);
+ dk4app_set_log_source_line(app, lno);
+ if (0 != dk4ma_write_decimal_unsigned(b3,DK4_SIZEOF(b3,dkChar),cil,0,NULL)) {
+ if (0 != dk4ma_write_decimal_unsigned(b2,DK4_SIZEOF(b2,dkChar),cno,0,NULL)) {
+ if (0 != dk4ma_write_decimal_unsigned(b1,DK4_SIZEOF(b1,dkChar),bno,0,NULL)) {
+ allbuffersok = 1;
+ }
+ }
+ }
+ if (0 != allbuffersok) {
+ dk4app_log_7(
+ app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, i1, 38, 39, 40, b1, b2, b3
+ );
+ } else {
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, i2);
+ }
+ dk4app_set_log_source_line(app, oldlogline);
+ dk4app_set_log_source_file(app, oldlogname);
+}
+
+
+
+/** Report decoding/encoding and processing errors.
+ @param er_en Error report for decoding/encoding errors.
+ @param er_pr Error report for processing errors.
+ @param fn File name.
+*/
+static
+void
+dk_fic_report_errors(
+ dk4_er_t *er_en,
+ dk4_er_t *er_pr,
+ const dkChar *fn
+)
+{
+ static int had_decoding_errors = 0;
+ static int had_encoding_errors = 0;
+ static int had_processing_errors = 0;
+
+ if (NULL != er_en) {
+ switch (er_en->ec) {
+ case DK4_E_DECODING_FAILED : {
+ if (3 > had_decoding_errors) {
+ dk_fic_report_with_position(
+ 35, 32,
+ er_en->dt.fpos.byteno, er_en->dt.fpos.lineno,
+ er_en->dt.fpos.charno, er_en->dt.fpos.charinline,
+ fn
+ );
+ }
+ if (2 <= had_decoding_errors) { had_decoding_errors++; }
+ } break;
+ case DK4_E_ENCODING_FAILED : {
+ if (3 > had_encoding_errors) {
+ dk_fic_report_with_position(
+ 36, 33,
+ er_en->dt.fpos.byteno, er_en->dt.fpos.lineno,
+ er_en->dt.fpos.charno, er_en->dt.fpos.charinline,
+ fn
+ );
+ }
+ if (2 <= had_encoding_errors) { had_encoding_errors++; }
+ } break;
+ }
+ }
+ if (NULL != er_pr) {
+ if (DK4_E_NONE != er_pr->ec) {
+ if (3 > had_processing_errors) {
+ dk_fic_report_with_position(
+ 37, 34,
+ er_pr->dt.fpos.byteno, er_pr->dt.fpos.lineno,
+ er_pr->dt.fpos.charno, er_pr->dt.fpos.charinline,
+ fn
+ );
+ }
+ if (2 <= had_processing_errors) { had_processing_errors++; }
+ }
+ }
+}
+
+
+
+/** Write one ASCII-Hex encoded message digest to stdout.
+ @param digptr Start address of text buffer.
+ @param sz Digest size.
+*/
+static
+void
+dk_fic_output_digest(const char *digptr, size_t sz)
+{
+ while (0 < sz--) {
+ if (0 == dk4fputc((dkChar)(*(digptr++)), stdout, NULL)) {
+ dk_fic_write_error = 1;
+ }
+ }
+}
+
+
+
+/** Create checksum line for one file.
+ @param filename File name.
+ @param filesize File size.
+*/
+static
+void
+dk_fic_checksum_file(const dkChar *filename, dk4_um_t filesize)
+{
+ dkChar fszbuf[8*sizeof(dk4_um_t)+16];
+ const dkChar *oldsourcename;
+ const char *md5ptr;
+ const char *sha1ptr;
+ const char *ripemd160ptr;
+#if DK4_HAVE_SHA512
+ const char *sha512ptr;
+#endif
+ FILE *fipo;
+ dk4_um_t oldsourceline;
+ size_t rdb;
+ size_t md5sz;
+ size_t sha1sz;
+ size_t ripemd160sz;
+ size_t sl;
+#if DK4_HAVE_SHA512
+ size_t sha512sz;
+#endif
+ int tests = DK4_FOPEN_SC_IS_REGULAR;
+ int ok = 1;
+ int res;
+ int cc;
+
+ res = dk4md_ctx_init(
+ &ctx_md5, DK4_MD_MD5, DK4_BINARY_TO_TEXT_ENCODING_A85, NULL
+ );
+ if (0 == res) { ok = 0; }
+ res = dk4md_ctx_init(
+ &ctx_sha1, DK4_MD_SHA1, DK4_BINARY_TO_TEXT_ENCODING_A85, NULL
+ );
+ if (0 == res) { ok = 0; }
+ res = dk4md_ctx_init(
+ &ctx_ripemd160, DK4_MD_RIPEMD_160, DK4_BINARY_TO_TEXT_ENCODING_A85, NULL
+ );
+ if (0 == res) { ok = 0; }
+#if DK4_HAVE_SHA512
+ res = dk4md_ctx_init(
+ &ctx_sha512, DK4_MD_SHA512, DK4_BINARY_TO_TEXT_ENCODING_A85, NULL
+ );
+ if (0 == res) { ok = 0; }
+#endif
+ if (0 != ok) {
+ fipo = dk4fopen_app(filename, dk_fic_kwnl[5], tests, app);
+ if (NULL != fipo) {
+ cc = 1;
+ while (1 == cc) {
+ if (dk_fic_can_continue()) {
+ rdb = fread(data_buf, 1, sizeof(data_buf), fipo);
+ if (0 < rdb) {
+ res = dk4md_ctx_add(&ctx_md5, data_buf, rdb, NULL);
+ if (0 == res) { cc = -1; }
+ res = dk4md_ctx_add(&ctx_sha1, data_buf, rdb, NULL);
+ if (0 == res) { cc = -1; }
+ res = dk4md_ctx_add(&ctx_ripemd160, data_buf, rdb, NULL);
+ if (0 == res) { cc = -1; }
+#if DK4_HAVE_SHA512
+ res = dk4md_ctx_add(&ctx_sha512, data_buf, rdb, NULL);
+ if (0 == res) { cc = -1; }
+#endif
+ } else {
+ cc = 0;
+ if (0 != ferror(fipo)) {
+ cc = -1;
+ /* ERROR Read attempt failed */
+ oldsourcename = dk4app_get_log_source_file(app);
+ oldsourceline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_file(app, filename);
+ dk4app_set_log_source_line(app, (dk4_um_t)0UL);
+ dk4app_log_1(
+ app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 4
+ );
+ dk4app_set_log_source_file(app, oldsourcename);
+ dk4app_set_log_source_line(app, oldsourceline);
+ exval = EXIT_FAILURE;
+ }
+ }
+ } else {
+ cc = -1;
+ }
+ }
+ fclose(fipo);
+ if (0 == cc) {
+ md5ptr = NULL; sha1ptr = NULL; ripemd160ptr = NULL;
+ md5sz = 0; sha1sz = 0; ripemd160sz = 0;
+#if DK4_HAVE_SHA512
+ sha512ptr = NULL;
+ sha512sz = 0;
+#endif
+ res = dk4md_ctx_finish(&md5ptr, &md5sz, &ctx_md5, NULL);
+ if (0 == res) { cc = -1; }
+ res = dk4md_ctx_finish(&sha1ptr, &sha1sz, &ctx_sha1, NULL);
+ if (0 == res) { cc = -1; }
+ res = dk4md_ctx_finish(&ripemd160ptr,&ripemd160sz,&ctx_ripemd160,NULL);
+ if (0 == res) { cc = -1; }
+#if DK4_HAVE_SHA512
+ res = dk4md_ctx_finish(&sha512ptr, &sha512sz, &ctx_sha512, NULL);
+ if (0 == res) { cc = -1; }
+#endif
+ if (0 == cc) {
+ res = dk4ma_write_decimal_unsigned(
+ fszbuf, DK4_SIZEOF(fszbuf,dkChar), filesize, 0, NULL
+ );
+ if (0 != res) {
+ dk_fic_output_digest(md5ptr, md5sz);
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ dk_fic_write_error = 1;
+ }
+ dk_fic_output_digest(sha1ptr, sha1sz);
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ dk_fic_write_error = 1;
+ }
+ dk_fic_output_digest(ripemd160ptr, ripemd160sz);
+#if DK4_HAVE_SHA512
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ dk_fic_write_error = 1;
+ }
+ dk_fic_output_digest(sha512ptr, sha512sz);
+#endif
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ dk_fic_write_error = 1;
+ }
+ sl = dk4str_len(fszbuf);
+ while (sl++ < dk_fic_num_len) {
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ dk_fic_write_error = 1;
+ }
+ }
+ if (0 == dk4fputs(fszbuf, stdout, NULL)) {
+ dk_fic_write_error = 1;
+ }
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ dk_fic_write_error = 1;
+ }
+ if (0 == dk4fputs(filename, stdout, NULL)) {
+ dk_fic_write_error = 1;
+ }
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) {
+ dk_fic_write_error = 1;
+ }
+ } else {
+ /* ERROR: Failed to convert file size to text */
+ dk4app_log_3(
+ app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 5, 6, filename
+ );
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Failed to finish at least one message digest */
+ dk4app_log_3(
+ app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 7, 8, filename
+ );
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ if (-1 == cc) {
+ /* ERROR: Failed to add data to message digest context */
+ dk4app_log_3(
+ app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 9, 10, filename
+ );
+ exval = EXIT_FAILURE;
+ }
+ }
+ } else {
+ /* ERROR: Failed to open file, already reported */
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Failed to initialize at least one ctx */
+ dk4app_log_3(
+ app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 11, 12, filename
+ );
+ exval = EXIT_FAILURE;
+ }
+}
+
+
+
+/** Line handler when creating a checksum list.
+ @param obj Object to modify.
+ @param line Text line to process.
+ @param lineno Current line number.
+ @param erp Error report, may be NULL.
+ @return DK4_TSP_RES_OK, DK4_TSP_RES_ERROR, or DK4_TSP_RES_FATAL.
+*/
+static
+int
+dk_fic_create_line_handler(
+ void *obj,
+ dkChar *line,
+ dk4_um_t lineno,
+ dk4_er_t *erp
+)
+{
+ dk4_file_info_t fi;
+ dk4_er_t er;
+ dk4_um_t filesize;
+ int res;
+ int back = DK4_TSP_RES_OK;
+ dk4str_delnl(line);
+ dk4path_correct_sep(line);
+ filesize = (dk4_um_t)0UL;
+ dk4error_init(&er);
+ dk4fileinfo_init(&fi);
+ if (0 != dk4fileinfo_app(&fi, line, app)) {
+ res = dk4fileinfo_size(
+ &filesize, &fi, DK4_FILE_INFO_CONTENTS_DATA_TARGET, &er
+ );
+ if (0 != res) {
+ if (0 != dk4fileinfo_exists_and_is_regular(&fi, &er)) {
+ dk_fic_checksum_file(line, filesize);
+ } else {
+ /* ERROR: Not a regular file */
+ dk4app_log_3(
+ app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 13, 14, line
+ );
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Failed to obtain file size */
+ dk4app_log_3(
+ app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 15, 16, line
+ );
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Failed to information about file, already reported */
+ exval = EXIT_FAILURE;
+ }
+ return back;
+}
+
+
+
+/** Compare current checksum against checksum from file.
+ @param curcs Current checksum.
+ @param orics Original checksum from file.
+ @param curlen Current checksum length.
+ @return 1 if both checksums are equal, 0 otherwise.
+*/
+static
+int
+dk_fic_compare_checksums(
+ const char *curcs,
+ const dkChar *orics,
+ size_t curlen
+)
+{
+ int back = 0;
+ $? "+ dk_fic_compare_checksums \"%!8s\"", curcs
+ if ((NULL != curcs) && (NULL != orics) && (0 < curlen)) {
+ back = 1;
+ while ((1 == back) && (0 < curlen--)) {
+ if ((dkChar)(*(curcs++)) != *(orics++)) {
+ back = 0;
+ }
+ }
+ } $? "- dk_fic_compare_checksums %d", back
+ return back;
+}
+
+
+
+/** Line handler when verifying a checksum list.
+ @param obj Object to modify.
+ @param line Text line to process.
+ @param lineno Current line number.
+ @param erp Error report, may be NULL.
+ @return DK4_TSP_RES_OK, DK4_TSP_RES_ERROR, or DK4_TSP_RES_FATAL.
+*/
+static
+int
+dk_fic_verify_line_handler(
+ void *obj,
+ dkChar *line,
+ dk4_um_t lineno,
+ dk4_er_t *erp
+)
+{
+ dk4_file_info_t fi; /* File information */
+ dk4_er_t er; /* Error report */
+ FILE *fipo; /* File to read */
+ const dkChar *oldsourcename; /* Source file */
+ const dkChar *endptr; /* Text after size */
+ dkChar *tok[16]; /* Tokens in input line */
+ const char *md5ptr; /* Encoded message digest */
+ const char *sha1ptr; /* Encoded message digest */
+ const char *ripemd160ptr; /* Encoded message digest */
+#if DK4_HAVE_SHA512
+ const char *sha512ptr; /* Encoded message digest */
+#endif
+ dk4_um_t oldsourceline; /* Source line number */
+ dk4_um_t filesize; /* Current file size */
+ dk4_um_t um; /* File size from input line */
+ size_t ntok; /* Number of tokens in input line */
+ size_t i; /* Index to initialize tokens */
+ size_t rdb; /* Number of bytes read */
+ size_t md5sz; /* Encoded digest length */
+ size_t sha1sz; /* Encoded digest length */
+ size_t ripemd160sz; /* Encoded digest length */
+#if DK4_HAVE_SHA512
+ size_t sha512sz; /* Encoded digest length */
+#endif
+ int res; /* Operations result */
+ int cc; /* Flag: Can continue */
+ int tests = DK4_FOPEN_SC_IS_REGULAR;
+ int back = DK4_TSP_RES_ERROR;
+ int ok = 0; /* Flag: Check passed */
+ dk4str_delnl(line);
+ $? "+ verify_line_handler \"%!ds\"", line
+ /* dk4path_correct_sep(line); Correct file name only! */
+ for (i = 0; i < 16; i++) { tok[i] = NULL; }
+ if (0 != dk_fic_first_line) { $? ". first line"
+ dk_fic_first_line = 0;
+ ntok = dk4str_tokenize(tok, 16, line, NULL, NULL);
+ if (3 == ntok) { $? ". 3 tokens"
+ if (dkT('#') == *(tok[0])) {
+ if (0 == dk4str_cmp(dk_fic_kwnl[9], tok[1])) {
+ endptr = NULL;
+ if (0 != dk4ma_input_dk_dec_dk4_um_t(&um, tok[2], &endptr, 1, NULL)) {
+ if ((dk4_um_t)3UL == um) { $? ". 3 checksums"
+ dk_fic_num_mds = 3;
+ back = DK4_TSP_RES_OK;
+ } else {
+ if ((dk4_um_t)4UL == um) { $? ". 4 checksums"
+ dk_fic_num_mds = 4;
+ back = DK4_TSP_RES_OK;
+#if !DK4_HAVE_SHA512
+ /* Warning SHA-512 checksum ignored, not supported */
+ dk4app_log_1(
+ app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_WARNING, 17
+ );
+#endif
+ } else { $? "! not 3 or 4"
+ }
+ }
+ } else { $? "! not a number"
+ }
+ } else { $? "! not dk-fic"
+ }
+ } else { $? "! not comment"
+ }
+ } else { $? "! wrong no tokens"
+ }
+ if (DK4_TSP_RES_ERROR == back) {
+ /* ERROR: Syntax error */
+ dk4app_log_1(
+ app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 18
+ );
+ exval = EXIT_FAILURE;
+ }
+ } else { $? ". data line"
+ ntok = dk4str_tokenize(tok, 16, line, NULL, NULL);
+ $? ". ntok = %u", (unsigned)ntok
+ if ((5 == ntok) && (3 == dk_fic_num_mds)) { $? ". ntok 5 ok"
+ back = DK4_TSP_RES_OK;
+ } else {
+ if ((6 == ntok) && (4 == dk_fic_num_mds)) { $? ". ntok 6 ok"
+ back = DK4_TSP_RES_OK;
+ }
+ }
+ if (DK4_TSP_RES_OK == back) { $? ". ntok ok"
+#if VERSION_BEFORE_20150821
+ back = DK4_TSP_RES_ERROR;
+#endif
+ dk4path_correct_sep(tok[ntok - 1]);
+ dk4error_init(&er);
+ dk4fileinfo_init(&fi);
+ if (0 != dk4fileinfo_app(&fi, tok[ntok - 1], app)) { $? ". fileinfo"
+ filesize = (dk4_um_t)0UL;
+ res = dk4fileinfo_size(
+ &filesize, &fi, DK4_FILE_INFO_CONTENTS_DATA_TARGET, &er
+ );
+ if (0 != res) { $? ". file size"
+ res = dk4ma_input_dk_dec_dk4_um_t(&um, tok[ntok-2], &endptr, 1, NULL);
+ if (0 != res) { $? ". um"
+ if (um == filesize) { $? ". um = fs"
+ ok = 1;
+ /* Initialize message digest contexts.
+ */
+ res = dk4md_ctx_init(
+ &ctx_md5, DK4_MD_MD5, DK4_BINARY_TO_TEXT_ENCODING_A85, NULL
+ ); if (0 == res) { ok = 0; }
+ res = dk4md_ctx_init(
+ &ctx_sha1, DK4_MD_SHA1, DK4_BINARY_TO_TEXT_ENCODING_A85, NULL
+ ); if (0 == res) { ok = 0; }
+ res = dk4md_ctx_init(
+ &ctx_ripemd160,DK4_MD_RIPEMD_160,
+ DK4_BINARY_TO_TEXT_ENCODING_A85, NULL
+ ); if (0 == res) { ok = 0; }
+#if DK4_HAVE_SHA512
+ if (6 == ntok) { $? ". init sha512"
+ res = dk4md_ctx_init(
+ &ctx_sha512,DK4_MD_SHA512,DK4_BINARY_TO_TEXT_ENCODING_A85,NULL
+ );
+ if (0 == res) { $? "! init sha512"
+ ok = 0;
+ }
+ }
+#endif
+ if (0 != ok) { $? ". ctx init"
+ ok = 0;
+ fipo = dk4fopen_app(tok[ntok-1], dk_fic_kwnl[5], tests, app);
+ if (NULL != fipo) { $? ". fopen"
+ ok = 1;
+ cc = 1;
+ while (1 == cc) { $? ". loop start"
+ if (dk_fic_can_continue()) { $? ". can continue"
+ rdb = fread(data_buf, 1, sizeof(data_buf), fipo);
+ if (0 < rdb) { $? ". bytes found"
+ /* Add data from file to message digest contexts.
+ */
+ res = dk4md_ctx_add(&ctx_md5, data_buf, rdb, NULL);
+ if (0 == res) { ok = 0; cc = -1; }
+ res = dk4md_ctx_add(&ctx_sha1, data_buf, rdb, NULL);
+ if (0 == res) { ok = 0; cc = -1; }
+ res = dk4md_ctx_add(&ctx_ripemd160,data_buf,rdb,NULL);
+ if (0 == res) { ok = 0; cc = -1; }
+#if DK4_HAVE_SHA512
+ if (6 == ntok) {
+ res = dk4md_ctx_add(&ctx_sha512, data_buf, rdb, NULL);
+ if (0 == res) { ok = 0; cc = -1; }
+ }
+#endif
+ if (0 == ok) {
+ dk4app_log_3(
+ app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR,
+ 9, 10, tok[ntok-1]
+ );
+ }
+ } else { $? ". no bytes read"
+ cc = 0;
+ if (0 != ferror(fipo)) { $? "! read error"
+ cc = -1;
+ /* ERROR Read attempt failed */
+ oldsourcename = dk4app_get_log_source_file(app);
+ oldsourceline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_file(app, tok[ntok-1]);
+ dk4app_set_log_source_line(app, (dk4_um_t)0UL);
+ dk4app_log_1(
+ app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 4
+ );
+ dk4app_set_log_source_file(app, oldsourcename);
+ dk4app_set_log_source_line(app, oldsourceline);
+ exval = EXIT_FAILURE;
+ }
+ }
+ } else { $? "! signal"
+ cc = -1;
+ }
+ }
+ fclose(fipo);
+ if (0 == cc) { $? ". end of loop ok"
+ /* Retrieve results from message digest contexts.
+ */
+ md5ptr = NULL; sha1ptr = NULL; ripemd160ptr = NULL;
+ md5sz = 0; sha1sz = 0; ripemd160sz = 0;
+#if DK4_HAVE_SHA512
+ sha512ptr = NULL; $? ". sha512ptr NULL"
+ sha512sz = 0;
+#endif
+ res = dk4md_ctx_finish(&md5ptr, &md5sz, &ctx_md5, NULL);
+ if (0 == res) {
+ ok = 0;
+#if VERSION_BEFORE_20150821
+ cc = -1;
+#endif
+ }
+ res = dk4md_ctx_finish(&sha1ptr, &sha1sz, &ctx_sha1, NULL);
+ if (0 == res) {
+ ok = 0;
+#if VERSION_BEFORE_20150821
+ cc = -1;
+#endif
+ }
+ res = dk4md_ctx_finish(
+ &ripemd160ptr,&ripemd160sz,&ctx_ripemd160,NULL
+ );
+ if (0 == res) {
+ ok = 0;
+#if VERSION_BEFORE_20150821
+ cc = -1;
+#endif
+ }
+#if DK4_HAVE_SHA512
+ if (6 == ntok) { $? ". ntok=6"
+ res = dk4md_ctx_finish(
+ &sha512ptr, &sha512sz, &ctx_sha512, NULL
+ ); $? ". sha512ptr %!8s", TR_8PTR(sha512ptr)
+ if (0 == res) {
+ ok = 0;
+#if VERSION_BEFORE_20150821
+ cc = -1;
+#endif
+ }
+ }
+#endif
+ if (0 == ok) {
+ dk4app_log_3(
+ app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR,
+ 7, 8, tok[ntok-1]
+ );
+ }
+ /* Compare current results against input contents.
+ */
+ if (0 != ok) { $? ". here"
+ res = dk_fic_compare_checksums(md5ptr, tok[0], md5sz);
+ if (0 == res) { $? "! md5 failed"
+ ok = 0;
+ }
+ }
+ if (0 != ok) { $? ". here"
+ res = dk_fic_compare_checksums(sha1ptr, tok[1], sha1sz);
+ if (0 == res) { $? "! sha-1 failed"
+ ok = 0;
+ }
+ }
+ if (0 != ok) { $? ". here"
+ res = dk_fic_compare_checksums(
+ ripemd160ptr, tok[2], ripemd160sz
+ );
+ if (0 == res) { $? "! ripe failed"
+ ok = 0;
+ }
+ }
+
+#if DK4_HAVE_SHA512
+ if (6 == ntok) { $? ". sha512"
+ if (0 != ok) { $? ". here"
+ res = dk_fic_compare_checksums(
+ sha512ptr, tok[3], sha512sz
+ );
+ if (0 == res) { $? "! sha512 failed"
+ ok = 0;
+ }
+ }
+ }
+#endif
+ } else { $? "! loop end by error"
+ ok = 0;
+ }
+ } else { $? "! fopen"
+ }
+ } else { $? "! ctx init"
+ /* ERROR Failed to initialize MD contexts */
+ dk4app_log_3(
+ app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 11, 12,
+ tok[ntok-1]
+ );
+ }
+ } else { $? "! files differ in size"
+ }
+ if (0 != ok) { $? ". PASSED"
+ if (2 <= dk_fic_verbosity) {
+ if (0 == dk4fputs(dk_fic_msg[2], stdout, NULL)) {
+ exval = EXIT_FAILURE; dk_fic_write_error = 1;
+ }
+ if (0 == dk4fputs(tok[ntok-1], stdout, NULL)) {
+ exval = EXIT_FAILURE; dk_fic_write_error = 1;
+ }
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) {
+ exval = EXIT_FAILURE; dk_fic_write_error = 1;
+ }
+ }
+ } else { $? ". FAILED"
+ exval = EXIT_FAILURE;
+ if (1 <= dk_fic_verbosity) {
+ if (0 == dk4fputs(dk_fic_msg[3], stdout, NULL)) {
+ exval = EXIT_FAILURE; dk_fic_write_error = 1;
+ }
+ if (0 == dk4fputs(tok[ntok-1], stdout, NULL)) {
+ exval = EXIT_FAILURE; dk_fic_write_error = 1;
+ }
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) {
+ exval = EXIT_FAILURE; dk_fic_write_error = 1;
+ }
+ }
+ }
+ } else { $? "! um"
+ /* Syntax error */
+ dk4app_log_3(
+ app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 21, 22, tok[ntok-2]
+ );
+ exval = EXIT_FAILURE;
+ }
+ } else { $? "! file size"
+ /* ERROR: Failed to retrieve file size */
+ dk4app_log_3(
+ app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 15, 16, line
+ );
+ exval = EXIT_FAILURE;
+ }
+ } else { $? "! fileinfo"
+ /* ERROR: Failed to information about file, already reported */
+ exval = EXIT_FAILURE;
+ }
+#if VERSION_BEFORE_20150821
+ back = DK4_TSP_RES_OK;
+#endif
+ } else { $? "! ntok"
+ /* Syntax error */
+ if (3 == dk_fic_num_mds) {
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 20);
+ } else {
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 19);
+ }
+ exval = EXIT_FAILURE;
+ }
+ }
+ $? "- verify_line_handler %d", back
+ return back;
+}
+
+
+
+/** Process one file.
+ @param fipo Opened file.
+ @param fn File name.
+ @param ie Expected input encoding.
+*/
+static
+void
+dk_fic_process_file(FILE *fipo, const dkChar *fn, int ie)
+{
+ dk4_tspdk_t tsp;
+ dk4_er_t er_en;
+ dk4_er_t er_pr;
+ dk4_er_t er;
+ int res;
+ int cc;
+ int c;
+ unsigned char ub;
+ $? "+ dk_fic_process_file"
+ dk4error_init(&er_en);
+ dk4error_init(&er_pr);
+ dk4error_init(&er);
+ res = dk4tspdk_setup_line(
+ &tsp, NULL,
+ (
+ (0 != dk_fic_verify)
+ ? dk_fic_verify_line_handler
+ : dk_fic_create_line_handler
+ ),
+ ibuf_ptr, ibuf_sz,
+ dk4app_get_encoding(app), ie,
+ &er
+ );
+ if (0 != res) {
+ cc = 1;
+ dk_fic_first_line = 1;
+ dk_fic_num_mds = 4;
+ do {
+ if (dk_fic_can_continue()) {
+ c = fgetc(fipo);
+ if (EOF != c) {
+ ub = (unsigned char)c;
+ switch (dk4tspdk_add_one_byte(&tsp, ub)) {
+ case DK4_TSP_RES_FATAL : {
+ cc = -1;
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tsp);
+ dk_fic_report_errors(&er_en, &er_pr, fn);
+ } break;
+ case DK4_TSP_RES_ERROR : {
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tsp);
+ dk_fic_report_errors(&er_en, &er_pr, fn);
+ } break;
+ }
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = -1;
+ }
+ } while (1 == cc);
+ if (0 == cc) {
+ switch (dk4tspdk_finish(&tsp)) {
+ case DK4_TSP_RES_FATAL : {
+#if VERSION_BEFORE_20150821
+ cc = -1;
+#endif
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tsp);
+ dk_fic_report_errors(&er_en, &er_pr, fn);
+ } break;
+ case DK4_TSP_RES_ERROR : {
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tsp);
+ dk_fic_report_errors(&er_en, &er_pr, fn);
+ } break;
+ }
+ }
+ } else {
+ /* ERROR: Failed to initialize text stream processor */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 23);
+ exval = EXIT_FAILURE;
+ }
+ $? "- dk_fic_process_file"
+}
+
+
+
+static
+void
+dk_fic_process_filename(const dkChar *filename)
+{
+ FILE *fipo;
+ int tests = DK4_FOPEN_SC_IS_REGULAR;
+ fipo = dk4fopen_app(filename, dk_fic_kwnl[5], tests, app);
+ if (NULL != fipo) {
+ dk_fic_process_file(fipo, filename, dk_fic_ie_file);
+ fclose(fipo);
+ } else {
+ exval = EXIT_FAILURE;
+ }
+}
+
+
+
+#if DK4_ON_WINDOWS
+static
+void
+dk_fic_expand_path_and_file(
+ dkChar *bptr,
+ size_t bsz,
+ const dkChar *pth,
+ const dkChar *shf
+)
+{
+ if (0 != dk4str_cpy_s(bptr, bsz, pth, NULL)) {
+ if (0 != dk4str_cat_s(bptr, bsz, dk_fic_kwnl[6], NULL)) {
+ if (0 != dk4str_cat_s(bptr, bsz, shf, NULL)) {
+ dk_fic_process_filename(bptr);
+ } else {
+ /* ERROR: Name too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, shf);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Name too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Name too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ exval = EXIT_FAILURE;
+ }
+}
+
+
+
+static
+void
+dk_fic_expand_filename(const dkChar *pattern)
+{
+ dkChar buf[DK4_MAX_PATH];
+ dk4_dir_t *fne;
+ const dkChar *shf;
+ const dkChar *pth;
+ int any_file_found = 0;
+ int can_continue;
+ $? "+ dk_fic_expand_filename"
+ fne = dk4app_fne_open(pattern, app);
+ if (NULL != fne) {
+ do {
+ shf = dk4dir_next_file(fne);
+ if (NULL != shf) {
+ any_file_found = 1;
+ can_continue = dk_fic_can_continue();
+ if (0 != can_continue) {
+ pth = dk4dir_get_path(fne);
+ if (NULL != pth) {
+ dk_fic_expand_path_and_file(buf, DK4_SIZEOF(buf,dkChar), pth, shf);
+ } else {
+ dk_fic_process_filename(shf);
+ }
+ }
+ } else {
+ can_continue = 0;
+ }
+ } while (1 == can_continue);
+ dk4dir_close(fne);
+ if (0 == any_file_found) {
+ /* ERROR: No matching file found */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 107, pattern);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ exval = EXIT_FAILURE;
+ }
+ $? "- dk_fic_expand_filename"
+}
+#endif
+
+#endif
+/* if DK4_HAVE_... */
+
+
+
+/** Process the command line arguments.
+*/
+static
+void
+dk_fic_run_for_command_line_args(void)
+{
+ const dkChar *filename;
+ int xargc;
+ int i;
+#if DK4_HAVE_OPENSSL_MD5_H && DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_OPENSSL_RIPEMD_H
+#if DK4_ON_WINDOWS
+ int oldmode;
+#endif
+ if (0 == dk_fic_verify) {
+#if DK4_HAVE_SHA512
+ dk4fputs(dk_fic_kwnl[8], stdout, NULL);
+#else
+ dk4fputs(dk_fic_kwnl[7], stdout, NULL);
+#endif
+ }
+ xargc = dk4app_get_argc(app);
+ if (0 < xargc) {
+ for (i = 0; ((0 != dk_fic_can_continue()) && (i < xargc)); i++) {
+ filename = dk4app_get_argv(app, i);
+ if (NULL != filename) {
+#if DK4_ON_WINDOWS
+ if (0 != dk4path_must_expand(filename)) {
+ dk_fic_expand_filename(filename);
+ } else {
+#endif
+ dk_fic_process_filename(filename);
+#if DK4_ON_WINDOWS
+ }
+#endif
+ } else {
+ /* ERROR: Failed to obtain command line argument, bug! */
+ exval = EXIT_FAILURE;
+ }
+ }
+ } else {
+#if DK4_ON_WINDOWS
+ oldmode = _setmode(_fileno(stdin), _O_BINARY);
+#endif
+ dk_fic_process_file(stdin, dk_fic_kwnl[4], dk_fic_ie_stdin);
+#if DK4_ON_WINDOWS
+ _setmode(_fileno(stdin), oldmode);
+#endif
+ }
+#else
+ /* ERROR: At least one unsupported message digest type */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 24);
+ exval = EXIT_FAILURE;
+#endif
+}
+
+
+
+/** Process options and preferences.
+*/
+static
+void
+dk_fic_normal_run(void)
+{
+ dkChar encbuf[64];
+ size_t myll = 0;
+ int res;
+
+ /* Assume success.
+ */
+ exval = EXIT_SUCCESS;
+
+ /* Process command line options.
+ */
+ if (0 != dk4app_opt_is_set_short(app, dkT('c'), NULL)) {
+ dk_fic_verify = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('q'), NULL)) {
+ dk_fic_verbosity = 0;
+ if (0 != dk4app_opt_is_set_short(app, dkT('v'), NULL)) {
+ /* ERROR: Options -q an -v are mutually exclusve */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 25);
+ exval = EXIT_FAILURE;
+ goto finished;
+ }
+ } else {
+ if (0 != dk4app_opt_is_set_short(app, dkT('v'), NULL)) {
+ dk_fic_verbosity = 2;
+ }
+ }
+#if VERSION_BEFORE_20150821
+ res = 0;
+#endif
+ if (0 != dk4app_opt_is_set_short(app, dkT('i'), NULL)) {
+ res = dk4app_opt_get_string_short(
+ encbuf, DK4_SIZEOF(encbuf,dkChar), app, dkT('i'), NULL
+ );
+ if (0 != res) {
+ res = dk4enc_find(&dk_fic_ie_stdin, NULL, encbuf, NULL);
+ if (0 != res) {
+ dk_fic_ie_file = dk_fic_ie_stdin;
+ } else {
+ /* ERROR: Encoding not found! */
+ dk4app_log_3(
+ app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 26, 27, encbuf
+ );
+ exval = EXIT_FAILURE;
+ goto finished;
+ }
+ }
+ }
+ res = 0;
+ if (0 != dk4app_opt_is_set_short(app, dkT('l'), NULL)) {
+ res = dk4app_opt_get_size_short(&myll, app, dkT('l'), NULL);
+ }
+ if ((0 == res) && (0 == dk4app_opt_is_set_short(app, dkT('R'), NULL))) {
+ res = dk4app_pref_get_size(&myll, app, dk_fic_kwnl[3], 0);
+ }
+ if ((0 != res) && (DK4_SIZEOF(ibuf_def,dkChar) < myll)) {
+ ibuf_all = dk4mem_new_app(dkChar, myll, app);
+ if (NULL != ibuf_all) {
+ ibuf_ptr = ibuf_all;
+ ibuf_sz = myll;
+ } else {
+ goto finished;
+ }
+ }
+
+ /* If no errors yet, process input.
+ */
+ if (EXIT_SUCCESS == exval) {
+ dk_fic_run_for_command_line_args();
+ }
+
+ /* Clean up dynamic buffers, if any.
+ */
+ finished:
+ if (NULL != ibuf_all) {
+ dk4mem_release(ibuf_all);
+ }
+}
+
+
+
+/* SIGNAL HANDLING */
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+dk_fic_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ struct sigaction opipe;
+#endif
+ struct sigaction oint;
+#ifdef SIGPIPE
+ struct sigaction npipe;
+#endif
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+ int success = 0;
+
+#ifdef SIGPIPE
+ /* Set up signal handling for SIGPIPE.
+ */
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+#endif
+
+ /* Set up signal handling for SIGINT.
+ */
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ dk_fic_normal_run();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+#ifdef SIGPIPE
+ /* Restore signal handling for SIGPIPE.
+ */
+ restore_old_pipe:
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+#endif
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+dk_fic_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ dk_fic_normal_run();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+#ifdef SIGPIPE
+ sigset(SIGPIPE, oldpipe);
+#endif
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+dk_fic_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = signal(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ dk_fic_normal_run();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+#ifdef SIGPIPE
+ signal(SIGPIPE, oldpipe);
+#endif
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+dk_fic_run_with_signal_handlers(void)
+{
+ dk_fic_normal_run();
+}
+#endif
+#endif
+#endif
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ $!trace-init dk-fic.deb
+ $? "+ main"
+ dk_fic_num_len = dk4numlength(sizeof(dk4_um_t), 0);
+ dk4fput_initialize_stdout();
+ dk4fput_initialize_stderr();
+ app = dk4app_open_cmd(
+ argc, argv, dk_fic_options, dk_fic_sz_options,
+ dk_fic_kwnl[0], DKT_VERSION_DK,
+ dk_fic_kwnl[1], dk_fic_help_text, dk_fic_license_text
+ );
+ if (NULL != app) {
+ dk_fic_sz_msg = dk4app_string_table_size(dk_fic_kw_def);
+ dk_fic_msg = dk4app_string_table(app, dk_fic_kwnl[2], dk_fic_kw_def);
+ dk_fic_ie_stdin = dk4app_get_stdin_encoding(app);
+ dk_fic_ie_file = dk4app_get_file_in_encoding(app);
+ if (0 != dk4app_can_run_normally(app)) {
+ dk_fic_run_with_signal_handlers();
+ } else {
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ if (0 != dk_fic_write_error) {
+ /* ERROR While writing output */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 28);
+ exval = EXIT_FAILURE;
+ }
+#ifdef SIGPIPE
+ if (0 != sig_read_atomic(&sig_had_int)) {
+ /* Signal PIPE */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 29);
+ exval = EXIT_FAILURE;
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_int)) {
+ /* Signal INT */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 30);
+ exval = EXIT_FAILURE;
+ }
+ if (0 != sig_read_atomic(&sig_had_term)) {
+ /* Signal TERM */
+ dk4app_log_1(app, dk_fic_msg, dk_fic_sz_msg, DK4_LL_ERROR, 31);
+ exval = EXIT_FAILURE;
+ }
+ dk4app_close(app);
+ }
+ fflush(stdout);
+ fflush(stderr);
+ dk4fput_cleanup_stderr();
+ dk4fput_cleanup_stdout();
+ $? "- main %d", exval
+ $!trace-end
+ exit (exval); return exval;
+}
+
+
diff --git a/support/dktools/dk-fic.rc b/support/dktools/dk-fic.rc
new file mode 100644
index 0000000000..e286a64b49
--- /dev/null
+++ b/support/dktools/dk-fic.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "File integrity check\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "File integrity check\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "dk-fic\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/dk-hex.c b/support/dktools/dk-hex.c
new file mode 100644
index 0000000000..5773acc675
--- /dev/null
+++ b/support/dktools/dk-hex.c
@@ -0,0 +1,1201 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk-hex.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#line 10 "dk-hex.ctr"
+
+/** @file dk-hex.c Show file contents in hexadecimal notation.
+
+See dk_hex_help_text for details.
+
+*/
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_CTYPE_H
+#ifndef CTYPE_H_INCLUDED
+#include <ctype.h>
+#define CTYPE_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4mem.h"
+#include "dk4app.h"
+#include "dk4aopt.h"
+#include "dk4mem.h"
+#include "dk4fput.h"
+#include "dk4vers.h"
+#include "dk4maodd.h"
+#include "dk4maodh.h"
+#include "dk4maodo.h"
+#include "dk4fopda.h"
+#include "dk4mpl.h"
+#include "dk4strd.h"
+#include "dk4pathd.h"
+
+
+
+
+
+#line 103 "dk-hex.ctr"
+
+
+
+/** Constant text keywords used by the module, not localized.
+*/
+static const dkChar * const dk_hex_kwnl[] = {
+/* 0 */
+dkT("dktools"),
+
+/* 1 */
+dkT("dk-hex.txt"),
+
+/* 2 */
+dkT("dk-hex.str"),
+
+/* 3 */
+dkT("stdin"),
+
+/* 4 */
+dkT("rb"),
+
+/* 5 */
+dkT("\\"),
+
+/* 6 */
+dkT("verbose"),
+
+NULL
+
+
+#line 139 "dk-hex.ctr"
+};
+
+
+
+/** Help text shown if no localized help file is found.
+*/
+static const dkChar * const dk_hex_help_text[] = {
+dkT(""),
+dkT("Show file contents in hexadecimal notation"),
+dkT(""),
+dkT("dk-hex [<options>] [<file(s)>]"),
+dkT(""),
+dkT("Options:"),
+dkT("-a\t--addresses\tShow addresses."),
+dkT("-t\t--text\t\tShow printable characters as text."),
+dkT("-o\t--octal\t\tUse octal notation instead of hexadecimal notation."),
+dkT("\t--verbose\tShow error message on SIGPIPE."),
+dkT(""),
+dkT("--help\t\t\tShow this short help text."),
+dkT("--manual\t\t*** SHOW FULL MANUAL. ***"),
+dkT("--version\t\tShow version information."),
+dkT("--license\t\tShow license information."),
+dkT(""),
+dkT("http://dktools.sourceforge.net"),
+dkT(""),
+NULL
+
+
+#line 166 "dk-hex.ctr"
+};
+
+
+
+/** License conditions.
+*/
+static const dkChar * const dk_hex_license_text[] = {
+dkT("This software uses code from the following projects, either directly or as"),
+dkT("a library:"),
+dkT(""),
+dkT("dktools\t\tDirk Krause's tools and libraries."),
+dkT("\t\tSee http://dktools.sourceforge.net/ for more information."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT("zlib\t\tData compression library."),
+dkT("\t\tSee http://www.zlib.net/ for more information."),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT("bzip2\t\tData compression program and library."),
+dkT("\t\tSee http://www.bzip.org/ for more information."),
+#endif
+dkT(""),
+dkT("All the licenses below apply to the program."),
+dkT("Licenses for used libraries are shown as found on my Scientific Linux 6.x"),
+dkT("computer in the /usr/share/doc directory on 2015-04-01. Check the project"),
+dkT("homepages of the used libraries for additional information and/or updated"),
+dkT("license terms."),
+dkT(""),
+dkT(""),
+dkT("DK tools and libraries license"),
+dkT("=============================="),
+dkT("Copyright (c) 2015-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above copyright notice,"),
+dkT(" this list of conditions and the following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("* Neither the name of the Dirk Krause nor the names of contributors may be"),
+dkT(" used to endorse or promote products derived from this software without"),
+dkT(" specific prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\""),
+dkT("AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED."),
+dkT(""),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,"),
+dkT("INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,"),
+dkT("BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,"),
+dkT("DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY"),
+dkT("OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,"),
+dkT("EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT(""),
+dkT("Zlib license"),
+dkT("============"),
+dkT("(C) 1995-2004 Jean-loup Gailly and Mark Adler"),
+dkT(""),
+dkT("This software is provided 'as-is', without any express or implied"),
+dkT("warranty. In no event will the authors be held liable for any damages"),
+dkT("arising from the use of this software."),
+dkT(""),
+dkT("Permission is granted to anyone to use this software for any purpose,"),
+dkT("including commercial applications, and to alter it and redistribute it"),
+dkT("freely, subject to the following restrictions:"),
+dkT(""),
+dkT("1. The origin of this software must not be misrepresented; you must not"),
+dkT(" claim that you wrote the original software. If you use this software"),
+dkT(" in a product, an acknowledgment in the product documentation would be"),
+dkT(" appreciated but is not required."),
+dkT("2. Altered source versions must be plainly marked as such, and must not be"),
+dkT(" misrepresented as being the original software."),
+dkT("3. This notice may not be removed or altered from any source distribution."),
+dkT(""),
+dkT("Jean-loup Gailly Mark Adler"),
+dkT("jloup@gzip.org madler@alumni.caltech.edu"),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT(""),
+dkT("Bzip2 and libbzip2 library license"),
+dkT("=================================="),
+dkT("This program, \"bzip2\", the associated library \"libbzip2\", and all"),
+dkT("documentation, are copyright (C) 1996-2007 Julian R Seward. All"),
+dkT("rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions"),
+dkT("are met:"),
+dkT(""),
+dkT("1. Redistributions of source code must retain the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer."),
+dkT(""),
+dkT("2. The origin of this software must not be misrepresented; you must "),
+dkT(" not claim that you wrote the original software. If you use this "),
+dkT(" software in a product, an acknowledgment in the product "),
+dkT(" documentation would be appreciated but is not required."),
+dkT(""),
+dkT("3. Altered source versions must be plainly marked as such, and must"),
+dkT(" not be misrepresented as being the original software."),
+dkT(""),
+dkT("4. The name of the author may not be used to endorse or promote "),
+dkT(" products derived from this software without specific prior written "),
+dkT(" permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS"),
+dkT("OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED"),
+dkT("WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE"),
+dkT("GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS"),
+dkT("INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,"),
+dkT("WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS"),
+dkT("SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+dkT(""),
+dkT("Julian Seward, jseward@bzip.org"),
+dkT("bzip2/libbzip2 version 1.0.5 of 10 December 2007"),
+#endif
+dkT(""),
+NULL
+
+
+#line 297 "dk-hex.ctr"
+};
+
+
+
+/** Constant text keywords, localized.
+*/
+static const dkChar * const dk_hex_kw_def[] = {
+/* 0 */
+dkT("Failed to set up signal handlers!"),
+
+/* 1 */
+dkT("Failed to restore signal handlers!"),
+
+/* 2 */
+dkT("Signal SIGPIPE received!"),
+
+/* 3 */
+dkT("Aborted by SIGINT signal!"),
+
+/* 4 */
+dkT("Aborted by SIGTERM signal!"),
+
+/* 5 */
+dkT("Write attempts to standard output failed!"),
+
+NULL
+
+
+#line 330 "dk-hex.ctr"
+};
+
+
+
+/** Line output buffer.
+*/
+static dkChar lbuf[128];
+
+
+
+/** Command line options.
+*/
+static const dk4_option_specification_t dk_hex_options[] = {
+ /* Show addresses.
+ */
+ { dkT('a'), dkT("addresses"), DK4_OPT_ARG_NONE },
+
+ /* Show text characters.
+ */
+ { dkT('t'), dkT("text"), DK4_OPT_ARG_NONE },
+
+ /* Show values in octal notation.
+ */
+ { dkT('o'), dkT("octal"), DK4_OPT_ARG_NONE },
+
+ /* Verbose mode (report SIGPIPE).
+ */
+ { dkT('\0'), dkT("verbose"), DK4_OPT_ARG_NONE }
+};
+
+
+
+/** Text keyword array, either localized or not localized.
+*/
+static const dkChar * const *dk_hex_msg = dk_hex_kw_def;
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Number of elements in the dk_hex_options array.
+*/
+static const size_t dk_hex_sz_options =
+sizeof(dk_hex_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Number of elements in dk_hex_kw_def, set at start of main() function.
+*/
+static size_t dk_hex_sz_msg =
+sizeof(dk_hex_kw_def)/sizeof(DK4_PCDKCHAR) - 1;
+
+
+
+/** Start of contents in buffer.
+*/
+static size_t st_co = 0;
+
+
+
+/** Start of printable text in buffer.
+*/
+static size_t st_tx = 0;
+
+
+
+/** Line size in buffer.
+*/
+static size_t sz_line = 0;
+
+
+
+/** Bytes to show per line.
+*/
+static size_t el_per_line = 16;
+
+
+
+/** Start address of current line.
+*/
+static dk4_um_t st_addr = (dk4_um_t)0UL;
+
+
+
+/** Number of elements currently in line.
+*/
+static size_t el_in_line = 0;
+
+
+
+/** Flag: Show addresses.
+*/
+static int sh_addr = 0;
+
+
+
+/** Flag: Show printable characters.
+*/
+static int sh_text = 0;
+
+
+
+/** Flag: Show contents in octal notation.
+*/
+static int sh_octal = 0;
+
+
+
+/** Exit status code.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+/** Flag: Errors occured while writing to standard output.
+*/
+static int output_error = 0;
+
+
+
+/** Flag: Verbose mode (report SIGPIPE).
+*/
+static int verbose = 0;
+
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t dk_hex_sig_had_pipe = 0;
+#endif
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t dk_hex_sig_had_int = 0;
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t dk_hex_sig_had_term = 0;
+
+
+
+/** Pass a volatile pointer to an atomic integer.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ptr Address of atomic integer variable.
+ @return The unmodified pointer.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+dk_hex_sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&dk_hex_sig_had_pipe) = 1;
+}
+#endif
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+dk_hex_sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&dk_hex_sig_had_int) = 1;
+}
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+dk_hex_sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&dk_hex_sig_had_term) = 1;
+}
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+dk_hex_sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+/** Check whether we can continue or if a signal was received.
+ @param check_pipe Flag: Check for occured SIGPIPE signal too.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(int check_pipe)
+{
+ int back = 1;
+#ifdef SIGPIPE
+ if (0 != check_pipe) {
+ if (0 != dk_hex_sig_read_atomic(&dk_hex_sig_had_pipe)) { back = 0; }
+ }
+#endif
+ if (0 != dk_hex_sig_read_atomic(&dk_hex_sig_had_int )) { back = 0; }
+ if (0 != dk_hex_sig_read_atomic(&dk_hex_sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+static
+void
+dk_hex_cpy(dkChar *dptr, const dkChar *sptr)
+{
+ while(dkT('\0') != *sptr) { *(dptr++) = *(sptr++); }
+}
+
+
+/** Check whether we can continue.
+ @return 1 if we can continue, 0 otherwise.
+*/
+static
+int
+dk_hex_can_continue(void)
+{
+ return (sig_can_continue(1));
+}
+
+
+
+/** Prepare output line buffer (fill with spaces, set finalizer byte).
+*/
+static
+void
+dk_hex_prepare_line(void)
+{
+ dkChar abuf[16*sizeof(dk4_um_t)];
+ dkChar *ptr;
+ size_t llgt;
+ int res;
+
+ ptr = lbuf;
+ llgt = sz_line;
+ while (llgt--) {
+ *(ptr++) = dkT(' ');
+ }
+ lbuf[sz_line] = dkT('\0');
+ if (0 != sh_addr) {
+ res = dk4ma_write_hex_unsigned(
+ abuf, DK4_SIZEOF(abuf,dkChar), st_addr, 2*sizeof(dk4_um_t), NULL
+ );
+ if (0 != res) {
+ dk_hex_cpy(lbuf, abuf);
+ }
+ }
+}
+
+
+
+static
+void
+dk_hex_flush_line(void)
+{
+ if (0 == dk4fputs(lbuf, stdout, NULL)) {
+ output_error = 1;
+ }
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) {
+ output_error = 1;
+ }
+ el_in_line = 0;
+ st_addr += el_per_line;
+ dk_hex_prepare_line();
+}
+
+
+
+static
+void
+dk_hex_add_byte(unsigned char uc)
+{
+ dkChar mybuf[16 * sizeof(dk4_um_t)];
+ int res;
+ if (0 != sh_octal) {
+ res = dk4ma_write_octal_unsigned(
+ mybuf, DK4_SIZEOF(mybuf,dkChar),
+ ( (dk4_um_t)0xFFUL & (dk4_um_t)uc ),
+ 3, NULL
+ );
+ } else {
+ res = dk4ma_write_hex_unsigned(
+ mybuf, DK4_SIZEOF(mybuf,dkChar),
+ ( (dk4_um_t)0xFFUL & (dk4_um_t)uc ),
+ 2, NULL
+ );
+ }
+ if (0 != res) {
+ dk_hex_cpy(
+ &(lbuf[st_co + el_in_line * ((0 != sh_octal) ? 4 : 3)]),
+ mybuf
+ );
+ }
+ if (0 != sh_text) {
+ if (!((isascii(uc)) && (isprint(uc)))) { uc = '.'; }
+ lbuf[st_tx + el_in_line] = (dkChar)uc;
+ }
+ if (++el_in_line >= el_per_line) {
+ dk_hex_flush_line();
+ }
+}
+
+
+
+/** Process one file.
+ @param fipo Opened file.
+ @param filename File name, (NULL for stdin).
+*/
+static
+void
+dk_hex_process_file(FILE *fipo, const dkChar *filename)
+{
+ const dkChar *oldsourcefile = NULL;
+ dk4_um_t oldsourceline = (dk4_um_t)0UL;
+ int cc = 1; /* Flag: Continue */
+ int c = 0; /* Current char */
+
+ oldsourcefile = dk4app_get_log_source_file(app);
+ oldsourceline = dk4app_get_log_source_line(app);
+
+ dk4app_set_log_source_file(
+ app, ((NULL != filename) ? filename: dk_hex_kwnl[3])
+ );
+ dk4app_set_log_source_line(app, (dk4_um_t)0UL);
+ if (NULL != filename) {
+ if (0 == dk4fputs(filename, stdout, NULL)) { output_error = 1; }
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) { output_error = 1; }
+ }
+ el_in_line = 0;
+ dk_hex_prepare_line();
+ while (1 == cc) {
+ if (0 != dk_hex_can_continue()) {
+ c = fgetc(fipo);
+ if (EOF != c) {
+ if (0 != feof(fipo)) { cc = 0; }
+ dk_hex_add_byte((unsigned char)c);
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = -1;
+ }
+ }
+ if (0 == cc) {
+ if (0 < el_in_line) {
+ dk_hex_flush_line();
+ }
+ }
+ dk4app_set_log_source_file(app, oldsourcefile);
+ dk4app_set_log_source_line(app, oldsourceline);
+}
+
+
+
+/** Open one named file and process it.
+ @param filename File name.
+*/
+static
+void
+dk_hex_process_one_name(const dkChar *filename)
+{
+ FILE *fipo = NULL;
+ fipo = dk4fopen_app(
+ filename, dk_hex_kwnl[4], DK4_FOPEN_SC_IS_REGULAR, app
+ );
+ if (NULL != fipo) {
+ dk_hex_process_file(fipo, filename);
+ fclose(fipo);
+ }
+}
+
+
+
+#if DK4_ON_WINDOWS
+
+/** Expand file name pattern, process file names.
+ @param pattern File name pattern.
+ @return 1 if files were found, 0 otherwise.
+*/
+static
+int
+dk_hex_expand_filename(const dkChar *pattern)
+{
+ dkChar buf[DK4_MAX_PATH];
+ dk4_dir_t *fne;
+ const dkChar *shf;
+ const dkChar *pth;
+ int cc;
+ int back = 0;
+ fne = dk4app_fne_open(pattern, app);
+ if (NULL != fne) {
+ cc = 1;
+ while (1 == cc) {
+ if (0 != dk_hex_can_continue()) {
+ shf = dk4dir_next_file(fne);
+ if (NULL != shf) {
+ back = 1;
+ pth = dk4dir_get_path(fne);
+ if (NULL != pth) {
+ if (0 != dk4str_cpy_s(buf, DK4_SIZEOF(buf,dkChar), pth, NULL)) {
+ if(0!=dk4str_cat_s(buf,DK4_SIZEOF(buf,dkChar),dk_hex_kwnl[5],NULL))
+ {
+ if(0 != dk4str_cat_s(buf, DK4_SIZEOF(buf,dkChar), shf, NULL)) {
+ dk_hex_process_one_name(buf);
+ } else {
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ exval = EXIT_FAILURE;
+ }
+ }
+ else
+ {
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ dk_hex_process_one_name(shf);
+ }
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = -1;
+ }
+ }
+ dk4dir_close(fne);
+ } else {
+ exval = EXIT_FAILURE;
+ }
+ return back;
+}
+
+#endif
+
+
+
+/** Run normal functionality after setting up signal handlers.
+*/
+static
+void
+dk_hex_run_the_functions(void)
+{
+ const dkChar *xargv; /* Current file name to process */
+#if DK4_ON_WINDOWS
+ int oldmode; /* File mode for windows */
+#endif
+ int xargc; /* Number of file names to process */
+ int i; /* Index of current file name processed */
+ /*
+ Check options
+ */
+ if (0 != dk4app_opt_is_set_long(app, dk_hex_kwnl[6], NULL)) { verbose = 1; }
+ if (0 != dk4app_opt_is_set_short(app, dkT('o'), NULL)) { sh_octal = 1; }
+ if (0 != dk4app_opt_is_set_short(app, dkT('a'), NULL)) { sh_addr = 1; }
+ if (0 != dk4app_opt_is_set_short(app, dkT('t'), NULL)) { sh_text = 1; }
+ /*
+ Calculate sizes and indices
+ */
+ if (0 != sh_octal) {
+ if (0 != sh_addr) {
+ st_co = 3 + 2 * sizeof(dk4_um_t);
+ el_per_line = 8;
+ sz_line = st_co + el_per_line * 4 - 1;
+ if (0 != sh_text) { /* octal, addresses, text */
+ st_tx = sz_line + 3;
+ sz_line += (3 + el_per_line);
+ }
+ } else {
+ st_co = 0;
+ if (0 != sh_text) { /* octal, no addresses, text */
+ el_per_line = 8;
+ sz_line = st_co + el_per_line * 4 - 1;
+ st_tx = sz_line + 3;
+ sz_line += (3 + el_per_line);
+ } else { /* octal, no addresses, no text */
+ el_per_line = 16;
+ sz_line = st_co + el_per_line * 4 - 1;
+ }
+ }
+ } else {
+ if (0 != sh_addr) {
+ st_co = 3 + 2 * sizeof(dk4_um_t);
+ if (0 != sh_text) { /* hexadecimal, addresses, text */
+ el_per_line = 8;
+ sz_line = st_co + el_per_line * 3 - 1;
+ st_tx = sz_line + 3;
+ sz_line += (3 + el_per_line);
+ } else { /* hexadecimal, addresses, no text */
+ el_per_line = 16;
+ sz_line = st_co + el_per_line * 3 - 1;
+ }
+ } else {
+ st_co = 0;
+ el_per_line = 16;
+ sz_line = st_co + el_per_line * 3 - 1;
+ if (0 != sh_text) { /* hexadecimal, no addresses, text */
+ st_tx = sz_line + 3;
+ sz_line += (3 + el_per_line);
+ }
+ }
+ }
+
+
+#line 872 "dk-hex.ctr"
+
+
+#line 873 "dk-hex.ctr"
+
+
+#line 874 "dk-hex.ctr"
+ /*
+ Process input files or standard input
+ */
+ exval = EXIT_SUCCESS;
+ xargc = dk4app_get_argc(app);
+ if (0 < xargc) {
+ for (i = 0; ((0 != dk_hex_can_continue()) && (i < xargc)); i++) {
+ xargv = dk4app_get_argv(app, i);
+ if (NULL != xargv) {
+#if DK4_ON_WINDOWS
+ if (0 != dk4path_must_expand(xargv)) {
+ if (0 == dk_hex_expand_filename(xargv)) {
+ /* ERROR: No file found */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 107, xargv);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+#endif
+ dk_hex_process_one_name(xargv);
+#if DK4_ON_WINDOWS
+ }
+#endif
+ }
+ }
+ } else {
+#if DK4_ON_WINDOWS
+ oldmode = _setmode(_fileno(stdin), _O_BINARY);
+#endif
+ dk_hex_process_file(stdin, NULL);
+#if DK4_ON_WINDOWS
+ _setmode(_fileno(stdin), oldmode);
+#endif
+ }
+}
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+dk_hex_run_with_signals(void)
+{
+#ifdef SIGPIPE
+ struct sigaction opipe;
+#endif
+ struct sigaction oint;
+ struct sigaction oterm;
+#ifdef SIGPIPE
+ struct sigaction npipe;
+#endif
+ struct sigaction nint;
+ struct sigaction nterm;
+ int success = 0;
+
+#ifdef SIGPIPE
+ /* Set up signal handling for SIGPIPE.
+ */
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = dk_hex_sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+#endif
+
+ /* Set up signal handling for SIGINT.
+ */
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = dk_hex_sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = dk_hex_sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ dk_hex_run_the_functions();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+#ifdef SIGPIPE
+ /* Restore signal handling for SIGPIPE.
+ */
+ restore_old_pipe:
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+#endif
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+dk_hex_run_with_signals(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = sigset(SIGPIPE, dk_hex_sig_handler_pipe);
+#endif
+ oldint = sigset(SIGINT, dk_hex_sig_handler_int);
+ oldterm = sigset(SIGTERM, dk_hex_sig_handler_term);
+ dk_hex_run_the_functions();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+#ifdef SIGPIPE
+ sigset(SIGPIPE, oldpipe);
+#endif
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+dk_hex_run_with_signals(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+#ifdef SIGPIPE
+ oldpipe = signal(SIGPIPE, dk_hex_sig_handler_pipe);
+#endif
+ oldint = signal(SIGINT, dk_hex_sig_handler_int);
+ oldterm = signal(SIGTERM, dk_hex_sig_handler_term);
+ dk_hex_run_the_functions();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+#ifdef SIGPIPE
+ signal(SIGPIPE, oldpipe);
+#endif
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+dk_hex_run_with_signals(void)
+{
+ dk_hex_run_the_functions();
+}
+#endif
+#endif
+#endif
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ int shp;
+
+
+#line 1109 "dk-hex.ctr"
+
+
+#line 1110 "dk-hex.ctr"
+ dk4fput_initialize_stdout();
+ dk4fput_initialize_stderr();
+ app = dk4app_open_cmd(
+ argc, argv, dk_hex_options, dk_hex_sz_options,
+ dk_hex_kwnl[0], DKT_VERSION_DK,
+ dk_hex_kwnl[1], dk_hex_help_text, dk_hex_license_text
+ );
+ if (NULL != app) {
+ dk_hex_sz_msg = dk4app_string_table_size(dk_hex_kw_def);
+ dk_hex_msg = dk4app_string_table(app, dk_hex_kwnl[2], dk_hex_kw_def);
+ if (0 != dk4app_can_run_normally(app)) {
+ dk_hex_run_with_signals();
+#ifdef SIGPIPE
+ if (0 != dk_hex_sig_read_atomic(&dk_hex_sig_had_pipe)) {
+ if (0 != verbose) {
+ dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 2);
+ }
+ exval = EXIT_FAILURE;
+ shp = 1;
+ } else {
+ shp = 0;
+ }
+#else
+ shp = 0;
+#endif
+ if (0 != dk_hex_sig_read_atomic(&dk_hex_sig_had_int )) {
+ dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 3);
+ exval = EXIT_FAILURE;
+ }
+ if (0 != dk_hex_sig_read_atomic(&dk_hex_sig_had_term)) {
+ dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 4);
+ exval = EXIT_FAILURE;
+ }
+ if ((0 == shp) && (0 != output_error)) {
+ dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 5);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ dk4app_close(app);
+ }
+ fflush(stdout);
+ fflush(stderr);
+ dk4fput_cleanup_stderr();
+ dk4fput_cleanup_stdout();
+
+
+#line 1159 "dk-hex.ctr"
+
+
+#line 1160 "dk-hex.ctr"
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/dk-hex.ctr b/support/dktools/dk-hex.ctr
new file mode 100644
index 0000000000..441d3bfcc1
--- /dev/null
+++ b/support/dktools/dk-hex.ctr
@@ -0,0 +1,1162 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+/** @file dk-hex.c Show file contents in hexadecimal notation.
+
+See dk_hex_help_text for details.
+
+*/
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_CTYPE_H
+#ifndef CTYPE_H_INCLUDED
+#include <ctype.h>
+#define CTYPE_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4mem.h"
+#include "dk4app.h"
+#include "dk4aopt.h"
+#include "dk4mem.h"
+#include "dk4fput.h"
+#include "dk4vers.h"
+#include "dk4maodd.h"
+#include "dk4maodh.h"
+#include "dk4maodo.h"
+#include "dk4fopda.h"
+#include "dk4mpl.h"
+#include "dk4strd.h"
+#include "dk4pathd.h"
+
+
+
+$!trace-include
+
+
+
+/** Constant text keywords used by the module, not localized.
+*/
+static const dkChar * const dk_hex_kwnl[] = {
+$!string-table macro=dkT
+#
+# 0 Program group name
+#
+dktools
+#
+# 1 Help file name
+#
+dk-hex.txt
+#
+# 2 String table file name
+#
+dk-hex.str
+#
+# 3 File name: stdin
+#
+stdin
+#
+# 4 File mode to read binary
+#
+rb
+#
+# 5 Separator for path name components on Windows
+#
+\\
+#
+# 6 Long option name.
+#
+verbose
+$!end
+};
+
+
+
+/** Help text shown if no localized help file is found.
+*/
+static const dkChar * const dk_hex_help_text[] = {
+$!text macro=dkT
+
+Show file contents in hexadecimal notation
+
+dk-hex [<options>] [<file(s)>]
+
+Options:
+-a --addresses Show addresses.
+-t --text Show printable characters as text.
+-o --octal Use octal notation instead of hexadecimal notation.
+ --verbose Show error message on SIGPIPE.
+
+--help Show this short help text.
+--manual *** SHOW FULL MANUAL. ***
+--version Show version information.
+--license Show license information.
+
+http://dktools.sourceforge.net
+
+$!end
+};
+
+
+
+/** License conditions.
+*/
+static const dkChar * const dk_hex_license_text[] = {
+$!text macro=dkT,preprocessor
+This software uses code from the following projects, either directly or as
+a library:
+
+dktools Dirk Krause's tools and libraries.
+ See http://dktools.sourceforge.net/ for more information.
+#if DK4_HAVE_ZLIB_H
+
+zlib Data compression library.
+ See http://www.zlib.net/ for more information.
+#endif
+#if DK4_HAVE_BZLIB_H
+
+bzip2 Data compression program and library.
+ See http://www.bzip.org/ for more information.
+#endif
+
+All the licenses below apply to the program.
+Licenses for used libraries are shown as found on my Scientific Linux 6.x
+computer in the /usr/share/doc directory on 2015-04-01. Check the project
+homepages of the used libraries for additional information and/or updated
+license terms.
+
+
+DK tools and libraries license
+==============================
+Copyright (c) 2015-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#if DK4_HAVE_ZLIB_H
+
+
+Zlib license
+============
+(C) 1995-2004 Jean-loup Gailly and Mark Adler
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+
+Jean-loup Gailly Mark Adler
+jloup@gzip.org madler@alumni.caltech.edu
+#endif
+#if DK4_HAVE_BZLIB_H
+
+
+Bzip2 and libbzip2 library license
+==================================
+This program, "bzip2", the associated library "libbzip2", and all
+documentation, are copyright (C) 1996-2007 Julian R Seward. All
+rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+3. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Julian Seward, jseward@bzip.org
+bzip2/libbzip2 version 1.0.5 of 10 December 2007
+#endif
+
+$!end
+};
+
+
+
+/** Constant text keywords, localized.
+*/
+static const dkChar * const dk_hex_kw_def[] = {
+$!string-table macro=dkT
+#
+# 0 Error: Failed to set up signal handlers!
+#
+Failed to set up signal handlers!
+#
+# 1 Error: Failed to restore signal handlers!
+#
+Failed to restore signal handlers!
+#
+# 2 Error: Signal SIGPIPE received!
+#
+Signal SIGPIPE received!
+#
+# 3 Error: Aborted by SIGINT signal!
+#
+Aborted by SIGINT signal!
+#
+# 4 Error: Aborted by SIGTERM signal!
+#
+Aborted by SIGTERM signal!
+#
+# 5 Error: Write attempts to standard output failed!
+#
+Write attempts to standard output failed!
+$!end
+};
+
+
+
+/** Line output buffer.
+*/
+static dkChar lbuf[128];
+
+
+
+/** Command line options.
+*/
+static const dk4_option_specification_t dk_hex_options[] = {
+ /* Show addresses.
+ */
+ { dkT('a'), dkT("addresses"), DK4_OPT_ARG_NONE },
+
+ /* Show text characters.
+ */
+ { dkT('t'), dkT("text"), DK4_OPT_ARG_NONE },
+
+ /* Show values in octal notation.
+ */
+ { dkT('o'), dkT("octal"), DK4_OPT_ARG_NONE },
+
+ /* Verbose mode (report SIGPIPE).
+ */
+ { dkT('\0'), dkT("verbose"), DK4_OPT_ARG_NONE }
+};
+
+
+
+/** Text keyword array, either localized or not localized.
+*/
+static const dkChar * const *dk_hex_msg = dk_hex_kw_def;
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Number of elements in the dk_hex_options array.
+*/
+static const size_t dk_hex_sz_options =
+sizeof(dk_hex_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Number of elements in dk_hex_kw_def, set at start of main() function.
+*/
+static size_t dk_hex_sz_msg =
+sizeof(dk_hex_kw_def)/sizeof(DK4_PCDKCHAR) - 1;
+
+
+
+/** Start of contents in buffer.
+*/
+static size_t st_co = 0;
+
+
+
+/** Start of printable text in buffer.
+*/
+static size_t st_tx = 0;
+
+
+
+/** Line size in buffer.
+*/
+static size_t sz_line = 0;
+
+
+
+/** Bytes to show per line.
+*/
+static size_t el_per_line = 16;
+
+
+
+/** Start address of current line.
+*/
+static dk4_um_t st_addr = (dk4_um_t)0UL;
+
+
+
+/** Number of elements currently in line.
+*/
+static size_t el_in_line = 0;
+
+
+
+/** Flag: Show addresses.
+*/
+static int sh_addr = 0;
+
+
+
+/** Flag: Show printable characters.
+*/
+static int sh_text = 0;
+
+
+
+/** Flag: Show contents in octal notation.
+*/
+static int sh_octal = 0;
+
+
+
+/** Exit status code.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+/** Flag: Errors occured while writing to standard output.
+*/
+static int output_error = 0;
+
+
+
+/** Flag: Verbose mode (report SIGPIPE).
+*/
+static int verbose = 0;
+
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t dk_hex_sig_had_pipe = 0;
+#endif
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t dk_hex_sig_had_int = 0;
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t dk_hex_sig_had_term = 0;
+
+
+
+/** Pass a volatile pointer to an atomic integer.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ptr Address of atomic integer variable.
+ @return The unmodified pointer.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+dk_hex_sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&dk_hex_sig_had_pipe) = 1;
+}
+#endif
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+dk_hex_sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&dk_hex_sig_had_int) = 1;
+}
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+dk_hex_sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&dk_hex_sig_had_term) = 1;
+}
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+dk_hex_sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+/** Check whether we can continue or if a signal was received.
+ @param check_pipe Flag: Check for occured SIGPIPE signal too.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(int check_pipe)
+{
+ int back = 1;
+#ifdef SIGPIPE
+ if (0 != check_pipe) {
+ if (0 != dk_hex_sig_read_atomic(&dk_hex_sig_had_pipe)) { back = 0; }
+ }
+#endif
+ if (0 != dk_hex_sig_read_atomic(&dk_hex_sig_had_int )) { back = 0; }
+ if (0 != dk_hex_sig_read_atomic(&dk_hex_sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+static
+void
+dk_hex_cpy(dkChar *dptr, const dkChar *sptr)
+{
+ while(dkT('\0') != *sptr) { *(dptr++) = *(sptr++); }
+}
+
+
+/** Check whether we can continue.
+ @return 1 if we can continue, 0 otherwise.
+*/
+static
+int
+dk_hex_can_continue(void)
+{
+ return (sig_can_continue(1));
+}
+
+
+
+/** Prepare output line buffer (fill with spaces, set finalizer byte).
+*/
+static
+void
+dk_hex_prepare_line(void)
+{
+ dkChar abuf[16*sizeof(dk4_um_t)];
+ dkChar *ptr;
+ size_t llgt;
+ int res;
+
+ ptr = lbuf;
+ llgt = sz_line;
+ while (llgt--) {
+ *(ptr++) = dkT(' ');
+ }
+ lbuf[sz_line] = dkT('\0');
+ if (0 != sh_addr) {
+ res = dk4ma_write_hex_unsigned(
+ abuf, DK4_SIZEOF(abuf,dkChar), st_addr, 2*sizeof(dk4_um_t), NULL
+ );
+ if (0 != res) {
+ dk_hex_cpy(lbuf, abuf);
+ }
+ }
+}
+
+
+
+static
+void
+dk_hex_flush_line(void)
+{
+ if (0 == dk4fputs(lbuf, stdout, NULL)) {
+ output_error = 1;
+ }
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) {
+ output_error = 1;
+ }
+ el_in_line = 0;
+ st_addr += el_per_line;
+ dk_hex_prepare_line();
+}
+
+
+
+static
+void
+dk_hex_add_byte(unsigned char uc)
+{
+ dkChar mybuf[16 * sizeof(dk4_um_t)];
+ int res;
+ if (0 != sh_octal) {
+ res = dk4ma_write_octal_unsigned(
+ mybuf, DK4_SIZEOF(mybuf,dkChar),
+ ( (dk4_um_t)0xFFUL & (dk4_um_t)uc ),
+ 3, NULL
+ );
+ } else {
+ res = dk4ma_write_hex_unsigned(
+ mybuf, DK4_SIZEOF(mybuf,dkChar),
+ ( (dk4_um_t)0xFFUL & (dk4_um_t)uc ),
+ 2, NULL
+ );
+ }
+ if (0 != res) {
+ dk_hex_cpy(
+ &(lbuf[st_co + el_in_line * ((0 != sh_octal) ? 4 : 3)]),
+ mybuf
+ );
+ }
+ if (0 != sh_text) {
+ if (!((isascii(uc)) && (isprint(uc)))) { uc = '.'; }
+ lbuf[st_tx + el_in_line] = (dkChar)uc;
+ }
+ if (++el_in_line >= el_per_line) {
+ dk_hex_flush_line();
+ }
+}
+
+
+
+/** Process one file.
+ @param fipo Opened file.
+ @param filename File name, (NULL for stdin).
+*/
+static
+void
+dk_hex_process_file(FILE *fipo, const dkChar *filename)
+{
+ const dkChar *oldsourcefile = NULL;
+ dk4_um_t oldsourceline = (dk4_um_t)0UL;
+ int cc = 1; /* Flag: Continue */
+ int c = 0; /* Current char */
+
+ oldsourcefile = dk4app_get_log_source_file(app);
+ oldsourceline = dk4app_get_log_source_line(app);
+
+ dk4app_set_log_source_file(
+ app, ((NULL != filename) ? filename: dk_hex_kwnl[3])
+ );
+ dk4app_set_log_source_line(app, (dk4_um_t)0UL);
+ if (NULL != filename) {
+ if (0 == dk4fputs(filename, stdout, NULL)) { output_error = 1; }
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) { output_error = 1; }
+ }
+ el_in_line = 0;
+ dk_hex_prepare_line();
+ while (1 == cc) {
+ if (0 != dk_hex_can_continue()) {
+ c = fgetc(fipo);
+ if (EOF != c) {
+ if (0 != feof(fipo)) { cc = 0; }
+ dk_hex_add_byte((unsigned char)c);
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = -1;
+ }
+ }
+ if (0 == cc) {
+ if (0 < el_in_line) {
+ dk_hex_flush_line();
+ }
+ }
+ dk4app_set_log_source_file(app, oldsourcefile);
+ dk4app_set_log_source_line(app, oldsourceline);
+}
+
+
+
+/** Open one named file and process it.
+ @param filename File name.
+*/
+static
+void
+dk_hex_process_one_name(const dkChar *filename)
+{
+ FILE *fipo = NULL;
+ fipo = dk4fopen_app(
+ filename, dk_hex_kwnl[4], DK4_FOPEN_SC_IS_REGULAR, app
+ );
+ if (NULL != fipo) {
+ dk_hex_process_file(fipo, filename);
+ fclose(fipo);
+ }
+}
+
+
+
+#if DK4_ON_WINDOWS
+
+/** Expand file name pattern, process file names.
+ @param pattern File name pattern.
+ @return 1 if files were found, 0 otherwise.
+*/
+static
+int
+dk_hex_expand_filename(const dkChar *pattern)
+{
+ dkChar buf[DK4_MAX_PATH];
+ dk4_dir_t *fne;
+ const dkChar *shf;
+ const dkChar *pth;
+ int cc;
+ int back = 0;
+ fne = dk4app_fne_open(pattern, app);
+ if (NULL != fne) {
+ cc = 1;
+ while (1 == cc) {
+ if (0 != dk_hex_can_continue()) {
+ shf = dk4dir_next_file(fne);
+ if (NULL != shf) {
+ back = 1;
+ pth = dk4dir_get_path(fne);
+ if (NULL != pth) {
+ if (0 != dk4str_cpy_s(buf, DK4_SIZEOF(buf,dkChar), pth, NULL)) {
+ if(0!=dk4str_cat_s(buf,DK4_SIZEOF(buf,dkChar),dk_hex_kwnl[5],NULL))
+ {
+ if(0 != dk4str_cat_s(buf, DK4_SIZEOF(buf,dkChar), shf, NULL)) {
+ dk_hex_process_one_name(buf);
+ } else {
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ exval = EXIT_FAILURE;
+ }
+ }
+ else
+ {
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ dk_hex_process_one_name(shf);
+ }
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = -1;
+ }
+ }
+ dk4dir_close(fne);
+ } else {
+ exval = EXIT_FAILURE;
+ }
+ return back;
+}
+
+#endif
+
+
+
+/** Run normal functionality after setting up signal handlers.
+*/
+static
+void
+dk_hex_run_the_functions(void)
+{
+ const dkChar *xargv; /* Current file name to process */
+#if DK4_ON_WINDOWS
+ int oldmode; /* File mode for windows */
+#endif
+ int xargc; /* Number of file names to process */
+ int i; /* Index of current file name processed */
+ /*
+ Check options
+ */
+ if (0 != dk4app_opt_is_set_long(app, dk_hex_kwnl[6], NULL)) { verbose = 1; }
+ if (0 != dk4app_opt_is_set_short(app, dkT('o'), NULL)) { sh_octal = 1; }
+ if (0 != dk4app_opt_is_set_short(app, dkT('a'), NULL)) { sh_addr = 1; }
+ if (0 != dk4app_opt_is_set_short(app, dkT('t'), NULL)) { sh_text = 1; }
+ /*
+ Calculate sizes and indices
+ */
+ if (0 != sh_octal) {
+ if (0 != sh_addr) {
+ st_co = 3 + 2 * sizeof(dk4_um_t);
+ el_per_line = 8;
+ sz_line = st_co + el_per_line * 4 - 1;
+ if (0 != sh_text) { /* octal, addresses, text */
+ st_tx = sz_line + 3;
+ sz_line += (3 + el_per_line);
+ }
+ } else {
+ st_co = 0;
+ if (0 != sh_text) { /* octal, no addresses, text */
+ el_per_line = 8;
+ sz_line = st_co + el_per_line * 4 - 1;
+ st_tx = sz_line + 3;
+ sz_line += (3 + el_per_line);
+ } else { /* octal, no addresses, no text */
+ el_per_line = 16;
+ sz_line = st_co + el_per_line * 4 - 1;
+ }
+ }
+ } else {
+ if (0 != sh_addr) {
+ st_co = 3 + 2 * sizeof(dk4_um_t);
+ if (0 != sh_text) { /* hexadecimal, addresses, text */
+ el_per_line = 8;
+ sz_line = st_co + el_per_line * 3 - 1;
+ st_tx = sz_line + 3;
+ sz_line += (3 + el_per_line);
+ } else { /* hexadecimal, addresses, no text */
+ el_per_line = 16;
+ sz_line = st_co + el_per_line * 3 - 1;
+ }
+ } else {
+ st_co = 0;
+ el_per_line = 16;
+ sz_line = st_co + el_per_line * 3 - 1;
+ if (0 != sh_text) { /* hexadecimal, no addresses, text */
+ st_tx = sz_line + 3;
+ sz_line += (3 + el_per_line);
+ }
+ }
+ }
+ $? ". st_co= %u", (unsigned)st_co
+ $? ". st_tx= %u", (unsigned)st_tx
+ $? ". sz_line=%u", (unsigned)sz_line
+ /*
+ Process input files or standard input
+ */
+ exval = EXIT_SUCCESS;
+ xargc = dk4app_get_argc(app);
+ if (0 < xargc) {
+ for (i = 0; ((0 != dk_hex_can_continue()) && (i < xargc)); i++) {
+ xargv = dk4app_get_argv(app, i);
+ if (NULL != xargv) {
+#if DK4_ON_WINDOWS
+ if (0 != dk4path_must_expand(xargv)) {
+ if (0 == dk_hex_expand_filename(xargv)) {
+ /* ERROR: No file found */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 107, xargv);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+#endif
+ dk_hex_process_one_name(xargv);
+#if DK4_ON_WINDOWS
+ }
+#endif
+ }
+ }
+ } else {
+#if DK4_ON_WINDOWS
+ oldmode = _setmode(_fileno(stdin), _O_BINARY);
+#endif
+ dk_hex_process_file(stdin, NULL);
+#if DK4_ON_WINDOWS
+ _setmode(_fileno(stdin), oldmode);
+#endif
+ }
+}
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+dk_hex_run_with_signals(void)
+{
+#ifdef SIGPIPE
+ struct sigaction opipe;
+#endif
+ struct sigaction oint;
+ struct sigaction oterm;
+#ifdef SIGPIPE
+ struct sigaction npipe;
+#endif
+ struct sigaction nint;
+ struct sigaction nterm;
+ int success = 0;
+
+#ifdef SIGPIPE
+ /* Set up signal handling for SIGPIPE.
+ */
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = dk_hex_sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+#endif
+
+ /* Set up signal handling for SIGINT.
+ */
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = dk_hex_sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = dk_hex_sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ dk_hex_run_the_functions();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+#ifdef SIGPIPE
+ /* Restore signal handling for SIGPIPE.
+ */
+ restore_old_pipe:
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+#endif
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+dk_hex_run_with_signals(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = sigset(SIGPIPE, dk_hex_sig_handler_pipe);
+#endif
+ oldint = sigset(SIGINT, dk_hex_sig_handler_int);
+ oldterm = sigset(SIGTERM, dk_hex_sig_handler_term);
+ dk_hex_run_the_functions();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+#ifdef SIGPIPE
+ sigset(SIGPIPE, oldpipe);
+#endif
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+dk_hex_run_with_signals(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+#ifdef SIGPIPE
+ oldpipe = signal(SIGPIPE, dk_hex_sig_handler_pipe);
+#endif
+ oldint = signal(SIGINT, dk_hex_sig_handler_int);
+ oldterm = signal(SIGTERM, dk_hex_sig_handler_term);
+ dk_hex_run_the_functions();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+#ifdef SIGPIPE
+ signal(SIGPIPE, oldpipe);
+#endif
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+dk_hex_run_with_signals(void)
+{
+ dk_hex_run_the_functions();
+}
+#endif
+#endif
+#endif
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ int shp;
+ $!trace-init dk-hex.deb
+ $? "+ main"
+ dk4fput_initialize_stdout();
+ dk4fput_initialize_stderr();
+ app = dk4app_open_cmd(
+ argc, argv, dk_hex_options, dk_hex_sz_options,
+ dk_hex_kwnl[0], DKT_VERSION_DK,
+ dk_hex_kwnl[1], dk_hex_help_text, dk_hex_license_text
+ );
+ if (NULL != app) {
+ dk_hex_sz_msg = dk4app_string_table_size(dk_hex_kw_def);
+ dk_hex_msg = dk4app_string_table(app, dk_hex_kwnl[2], dk_hex_kw_def);
+ if (0 != dk4app_can_run_normally(app)) {
+ dk_hex_run_with_signals();
+#ifdef SIGPIPE
+ if (0 != dk_hex_sig_read_atomic(&dk_hex_sig_had_pipe)) {
+ if (0 != verbose) {
+ dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 2);
+ }
+ exval = EXIT_FAILURE;
+ shp = 1;
+ } else {
+ shp = 0;
+ }
+#else
+ shp = 0;
+#endif
+ if (0 != dk_hex_sig_read_atomic(&dk_hex_sig_had_int )) {
+ dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 3);
+ exval = EXIT_FAILURE;
+ }
+ if (0 != dk_hex_sig_read_atomic(&dk_hex_sig_had_term)) {
+ dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 4);
+ exval = EXIT_FAILURE;
+ }
+ if ((0 == shp) && (0 != output_error)) {
+ dk4app_log_1(app, dk_hex_msg, dk_hex_sz_msg, DK4_LL_ERROR, 5);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ dk4app_close(app);
+ }
+ fflush(stdout);
+ fflush(stderr);
+ dk4fput_cleanup_stderr();
+ dk4fput_cleanup_stdout();
+ $? "- main %d", exval
+ $!trace-end
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/dk-hex.rc b/support/dktools/dk-hex.rc
new file mode 100644
index 0000000000..37c2aef850
--- /dev/null
+++ b/support/dktools/dk-hex.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Show file contents in hexadecimal notation\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "Show file contents in hexadecimal notation\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "dk-hex\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/dk-ls-to.c b/support/dktools/dk-ls-to.c
new file mode 100644
index 0000000000..1edfecfc45
--- /dev/null
+++ b/support/dktools/dk-ls-to.c
@@ -0,0 +1,270 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk-ls-to.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk-ls-to.c The dk-ls-to module.
+*/
+
+
+#line 10 "dk-ls-to.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4const.h"
+#include "dk4app.h"
+#include "dk-ls.h"
+#include "dk4strd.h"
+#include "dk4filei.h"
+#include "dk4md.h"
+#include "dk4binenc.h"
+#include "dk4fopda.h"
+#include "dk4fput.h"
+
+
+
+
+
+#line 40 "dk-ls-to.ctr"
+
+
+
+void dk_ls_set_md(
+ int *mdtype,
+ int *mdenc,
+ dkChar *buffer,
+ dk4_app_t *app,
+ const dkChar * const *msg,
+ size_t szmsg
+)
+{
+ dkChar *mdptr; /* Start of text in buffer */
+ dkChar *encptr; /* Encoding within the buffer */
+ int mdt; /* Message digest type */
+ int mde; /* Message digest encoding */
+ mdptr = dk4str_start(buffer, NULL);
+ if (NULL != mdptr) {
+ encptr = dk4str_chr(mdptr, dkT('.'));
+ if (NULL == encptr) {
+ encptr = dk4str_chr(mdptr, dkT(','));
+ }
+ if (NULL != encptr) {
+ *(encptr++) = dkT('\0');
+ encptr = dk4str_start(encptr, NULL);
+ }
+ mdt = dk4md_choose_type(mdptr, NULL);
+ if (NULL != encptr) {
+ mde = dk4binenc_choose_encoding(encptr, NULL);
+ } else {
+ mde = DK4_BINARY_TO_TEXT_ENCODING_HEX;
+ }
+ if ((0 <= mdt) && (0 < mde)) {
+ if (0 != dk4md_check_type(mdt)) {
+ *mdtype = mdt;
+ *mdenc = mde;
+ } else {
+ /* ERROR: No support for digest type */
+ dk4app_log_3(app, msg, szmsg, DK4_LL_ERROR, 20, 21, mdptr);
+ }
+ } else {
+ if (0 > mdt) {
+ /* ERROR: No such message digest type */
+ dk4app_log_3(app, msg, szmsg, DK4_LL_ERROR, 22, 23, mdptr);
+ } else {
+ *mdtype = mdt;
+ }
+ if (1 > mde) {
+ /* ERROR: Illegal encoding */
+ dk4app_log_3(app, msg, szmsg, DK4_LL_ERROR, 24,25, encptr);
+ }
+ }
+ } else {
+ /* ERROR: No contents in buffer, should not happen */
+ }
+}
+
+
+
+#if 0
+/* Now in dk4symlink.c as dk4symlink_target() function.
+*/
+int
+dk_ls_readlink(dkChar *bptr, size_t szb, const dkChar *fn)
+{
+#if DK4_ON_WINDOWS
+ HANDLE fh;
+ DWORD dwres;
+#else
+ ssize_t res;
+#endif
+ int back = 0;
+
+
+#line 113 "dk-ls-to.ctr"
+#if DK4_ON_WINDOWS
+#if DK4_CHAR_SIZE > 1
+ fh = CreateFileW(
+ fn,
+ FILE_READ_ATTRIBUTES,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ NULL
+ );
+ if (INVALID_HANDLE_VALUE != fh) {
+ dwres = GetFinalPathNameByHandleW(fh, bptr, (DWORD)szb, 0);
+ if (0 < dwres) {
+ if (dwres < (DWORD)szb) {
+ back = 1;
+ }
+ }
+ CloseHandle(fh);
+ }
+#else
+ fh = CreateFileA(
+ fn,
+ FILE_READ_ATTRIBUTES,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ NULL
+ );
+ if (INVALID_HANDLE_VALUE != fh) {
+ dwres = GetFinalPathNameByHandleA(fh, bptr, (DWORD)szb, 0);
+ if (0 < dwres) {
+ if (dwres < (DWORD)szb) {
+ back = 1;
+ }
+ }
+ CloseHandle(fh);
+ }
+#endif
+ if (0 < back) {
+ if (dkT('\\') == bptr[0]) {
+ if (dkT('\\') == bptr[1]) {
+ if (dkT('?') == bptr[2]) {
+ if (dkT('\\') == bptr[3]) {
+ if (260 > dk4str_len(&(bptr[4]))) {
+ dk4str_cpy_to_left(bptr, &(bptr[4]));
+ }
+ }
+ }
+ }
+ }
+ }
+#else
+#if DK4_CHAR_SIZE > 1
+
+#else
+ res = readlink(fn, bptr, szb);
+ if (0 < res) {
+ if (res < szb) {
+ bptr[res] = dkT('\0');
+ back = 1;
+ } else {
+
+#line 176 "dk-ls-to.ctr"
+ bptr[0] = dkT('\0');
+ }
+ } else {
+
+#line 179 "dk-ls-to.ctr"
+ bptr[0] = dkT('\0');
+ }
+#endif
+#endif
+ if (0 == back) {
+ bptr[0] = dkT('\0');
+ }
+
+
+#line 187 "dk-ls-to.ctr"
+ return back;
+}
+
+#endif
+
+
+
+void
+dk_ls_report_fileinfo_size_error(
+ dk4_app_t *app,
+ const dkChar *fn,
+ int ch,
+ const dkChar * const *msg,
+ size_t szmsg
+)
+{
+ dk4app_log_3(
+ app, msg, szmsg, DK4_LL_ERROR,
+ ((DK4_FILE_INFO_CONTENTS_DATA_TARGET == ch) ? 4 : 3),
+ 5, fn
+ );
+}
+
+
+
+void
+dk_ls_report_fileinfo_timestamp_error(
+ dk4_app_t *app,
+ const dkChar *fn,
+ int ch,
+ const dkChar * const *msg,
+ size_t szmsg
+)
+{
+ dk4app_log_3(
+ app, msg, szmsg, DK4_LL_ERROR,
+ ((DK4_FILE_INFO_CONTENTS_DATA_TARGET == ch) ? 8 : 7),
+ 9, fn
+ );
+}
+
+
+
diff --git a/support/dktools/dk-ls-to.ctr b/support/dktools/dk-ls-to.ctr
new file mode 100644
index 0000000000..2caf8925a9
--- /dev/null
+++ b/support/dktools/dk-ls-to.ctr
@@ -0,0 +1,229 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4const.h"
+#include "dk4app.h"
+#include "dk-ls.h"
+#include "dk4strd.h"
+#include "dk4filei.h"
+#include "dk4md.h"
+#include "dk4binenc.h"
+#include "dk4fopda.h"
+#include "dk4fput.h"
+
+
+
+$!trace-include
+
+
+
+void dk_ls_set_md(
+ int *mdtype,
+ int *mdenc,
+ dkChar *buffer,
+ dk4_app_t *app,
+ const dkChar * const *msg,
+ size_t szmsg
+)
+{
+ dkChar *mdptr; /* Start of text in buffer */
+ dkChar *encptr; /* Encoding within the buffer */
+ int mdt; /* Message digest type */
+ int mde; /* Message digest encoding */
+ mdptr = dk4str_start(buffer, NULL);
+ if (NULL != mdptr) {
+ encptr = dk4str_chr(mdptr, dkT('.'));
+ if (NULL == encptr) {
+ encptr = dk4str_chr(mdptr, dkT(','));
+ }
+ if (NULL != encptr) {
+ *(encptr++) = dkT('\0');
+ encptr = dk4str_start(encptr, NULL);
+ }
+ mdt = dk4md_choose_type(mdptr, NULL);
+ if (NULL != encptr) {
+ mde = dk4binenc_choose_encoding(encptr, NULL);
+ } else {
+ mde = DK4_BINARY_TO_TEXT_ENCODING_HEX;
+ }
+ if ((0 <= mdt) && (0 < mde)) {
+ if (0 != dk4md_check_type(mdt)) {
+ *mdtype = mdt;
+ *mdenc = mde;
+ } else {
+ /* ERROR: No support for digest type */
+ dk4app_log_3(app, msg, szmsg, DK4_LL_ERROR, 20, 21, mdptr);
+ }
+ } else {
+ if (0 > mdt) {
+ /* ERROR: No such message digest type */
+ dk4app_log_3(app, msg, szmsg, DK4_LL_ERROR, 22, 23, mdptr);
+ } else {
+ *mdtype = mdt;
+ }
+ if (1 > mde) {
+ /* ERROR: Illegal encoding */
+ dk4app_log_3(app, msg, szmsg, DK4_LL_ERROR, 24,25, encptr);
+ }
+ }
+ } else {
+ /* ERROR: No contents in buffer, should not happen */
+ }
+}
+
+
+
+#if 0
+/* Now in dk4symlink.c as dk4symlink_target() function.
+*/
+int
+dk_ls_readlink(dkChar *bptr, size_t szb, const dkChar *fn)
+{
+#if DK4_ON_WINDOWS
+ HANDLE fh;
+ DWORD dwres;
+#else
+ ssize_t res;
+#endif
+ int back = 0;
+ $? "+ dk_ls_readlink \"%!ds\"", TR_STR(fn)
+#if DK4_ON_WINDOWS
+#if DK4_CHAR_SIZE > 1
+ fh = CreateFileW(
+ fn,
+ FILE_READ_ATTRIBUTES,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ NULL
+ );
+ if (INVALID_HANDLE_VALUE != fh) {
+ dwres = GetFinalPathNameByHandleW(fh, bptr, (DWORD)szb, 0);
+ if (0 < dwres) {
+ if (dwres < (DWORD)szb) {
+ back = 1;
+ }
+ }
+ CloseHandle(fh);
+ }
+#else
+ fh = CreateFileA(
+ fn,
+ FILE_READ_ATTRIBUTES,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ NULL
+ );
+ if (INVALID_HANDLE_VALUE != fh) {
+ dwres = GetFinalPathNameByHandleA(fh, bptr, (DWORD)szb, 0);
+ if (0 < dwres) {
+ if (dwres < (DWORD)szb) {
+ back = 1;
+ }
+ }
+ CloseHandle(fh);
+ }
+#endif
+ if (0 < back) {
+ if (dkT('\\') == bptr[0]) {
+ if (dkT('\\') == bptr[1]) {
+ if (dkT('?') == bptr[2]) {
+ if (dkT('\\') == bptr[3]) {
+ if (260 > dk4str_len(&(bptr[4]))) {
+ dk4str_cpy_to_left(bptr, &(bptr[4]));
+ }
+ }
+ }
+ }
+ }
+ }
+#else
+#if DK4_CHAR_SIZE > 1
+
+#else
+ res = readlink(fn, bptr, szb);
+ if (0 < res) {
+ if (res < szb) {
+ bptr[res] = dkT('\0');
+ back = 1;
+ } else { $? "! readlink requires larger buffer"
+ bptr[0] = dkT('\0');
+ }
+ } else { $? "! readlink <= 0"
+ bptr[0] = dkT('\0');
+ }
+#endif
+#endif
+ if (0 == back) {
+ bptr[0] = dkT('\0');
+ }
+ $? "- dk_ls_readlink %d", back
+ return back;
+}
+
+#endif
+
+
+
+void
+dk_ls_report_fileinfo_size_error(
+ dk4_app_t *app,
+ const dkChar *fn,
+ int ch,
+ const dkChar * const *msg,
+ size_t szmsg
+)
+{
+ dk4app_log_3(
+ app, msg, szmsg, DK4_LL_ERROR,
+ ((DK4_FILE_INFO_CONTENTS_DATA_TARGET == ch) ? 4 : 3),
+ 5, fn
+ );
+}
+
+
+
+void
+dk_ls_report_fileinfo_timestamp_error(
+ dk4_app_t *app,
+ const dkChar *fn,
+ int ch,
+ const dkChar * const *msg,
+ size_t szmsg
+)
+{
+ dk4app_log_3(
+ app, msg, szmsg, DK4_LL_ERROR,
+ ((DK4_FILE_INFO_CONTENTS_DATA_TARGET == ch) ? 8 : 7),
+ 9, fn
+ );
+}
+
+
+
diff --git a/support/dktools/dk-ls.c b/support/dktools/dk-ls.c
new file mode 100644
index 0000000000..6ec01d987c
--- /dev/null
+++ b/support/dktools/dk-ls.c
@@ -0,0 +1,3242 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk-ls.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk-ls.c The dk-ls module.
+*/
+
+
+#line 87 "dk-ls.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4vers.h"
+#include "dk4app.h"
+#include "dk4aopt.h"
+#include "dk4mem.h"
+#include "dk4mema.h"
+#include "dk4fput.h"
+#include "dk-ls.h"
+#include "dk4mpl.h"
+#include "dk4stat.h"
+#include "dk4statd.h"
+#include "dk4strd.h"
+#include "dk4fileit.h"
+#include "dk4filei.h"
+#include "dk4fileia.h"
+#include "dk4masz.h"
+#include "dk4maadu.h"
+#include "dk4maodd.h"
+#include "dk4maodh.h"
+#include "dk4numl.h"
+#include "dk4dira.h"
+#include "dk4pathd.h"
+#include "dk4fopda.h"
+#include "dk4symlink.h"
+
+
+
+
+
+#line 168 "dk-ls.ctr"
+
+
+
+/** Default help text, used if help text file is not found.
+*/
+static const dkChar * const dk_ls_help_text[] = {
+dkT(""),
+dkT("List files"),
+dkT(""),
+dkT("dk-ls [<options>] [<file(s)>]"),
+dkT(""),
+dkT("Options:"),
+dkT("-p ... Output column order, see below. -r Recursive listing."),
+dkT("-t ... File types to list. -m ... Message digest type."),
+dkT("-f Stay on current file system. -s Show summary at end."),
+dkT("--help Show this short help text. --manual *** SHOW FULL MANUAL. ***"),
+dkT("--version Show version information. --license Show license information. "),
+dkT(""),
+dkT("Column order characters: n=name, s=size, t=type, p=permissions/attributes,"),
+dkT("c=creation, m=modification, a=access, l=links, u=UID, g=GID, d=device,"),
+dkT("i=inode, r=relative device, w=reparse tag (Widnows), x=message digest."),
+dkT("Default: ``mtpn'' (``mtn'' on Windows)."),
+dkT(""),
+dkT("File type characters: d=directories, f=non-directory entries."),
+dkT(""),
+dkT("Message digest types: md5, sha-1, sha-224, sha-256, sha-384, sha-512,"),
+dkT("ripemd-160. Optionally add encoding hex or a85, i.e. ``sha-1.hex''."),
+dkT(""),
+dkT("http://dktools.sourceforge.net"),
+dkT(""),
+NULL
+
+
+#line 200 "dk-ls.ctr"
+};
+
+
+
+/** License conditions.
+*/
+static const dkChar * const dk_ls_license_text[] = {
+dkT("This software uses code from the following projects, either directly or as"),
+dkT("a library:"),
+dkT(""),
+dkT("dktools\t\tDirk Krause's tools and libraries."),
+dkT("\t\tSee http://dktools.sourceforge.net/ for more information."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT("zlib\t\tData compression library."),
+dkT("\t\tSee http://www.zlib.net/ for more information."),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT("bzip2\t\tData compression program and library."),
+dkT("\t\tSee http://www.bzip.org/ for more information."),
+#endif
+#if DK4_HAVE_OPENSSL_MD5_H && DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_OPENSSL_RIPEMD_H
+dkT(""),
+dkT("OpenSSL\t\tCryptographic toolkit, used to build file checksums here."),
+dkT("\t\tSee http://www.openssl.org/ for more information."),
+dkT(""),
+dkT("This product includes software developed by the OpenSSL Project for use in"),
+dkT("the OpenSSL Toolkit (http://www.openssl.org/)."),
+dkT("This product includes cryptographic software written by"),
+dkT("Eric Young (eay@cryptsoft.com)."),
+dkT("This product includes software written by Tim Hudson (tjh@cryptsoft.com)."),
+#endif
+dkT(""),
+dkT("All the licenses below apply to the program."),
+dkT("Licenses for used libraries are shown as found on my Scientific Linux 6.x"),
+dkT("computer in the /usr/share/doc directory on 2015-04-01. Check the project"),
+dkT("homepages of the used libraries for additional information and/or updated"),
+dkT("license terms."),
+dkT(""),
+dkT(""),
+dkT("DK tools and libraries license"),
+dkT("=============================="),
+dkT("Copyright (c) 2015-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above copyright notice,"),
+dkT(" this list of conditions and the following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("* Neither the name of the Dirk Krause nor the names of contributors may be"),
+dkT(" used to endorse or promote products derived from this software without"),
+dkT(" specific prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\""),
+dkT("AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED."),
+dkT(""),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,"),
+dkT("INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,"),
+dkT("BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,"),
+dkT("DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY"),
+dkT("OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,"),
+dkT("EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT(""),
+dkT("Zlib license"),
+dkT("============"),
+dkT("(C) 1995-2004 Jean-loup Gailly and Mark Adler"),
+dkT(""),
+dkT("This software is provided 'as-is', without any express or implied"),
+dkT("warranty. In no event will the authors be held liable for any damages"),
+dkT("arising from the use of this software."),
+dkT(""),
+dkT("Permission is granted to anyone to use this software for any purpose,"),
+dkT("including commercial applications, and to alter it and redistribute it"),
+dkT("freely, subject to the following restrictions:"),
+dkT(""),
+dkT("1. The origin of this software must not be misrepresented; you must not"),
+dkT(" claim that you wrote the original software. If you use this software"),
+dkT(" in a product, an acknowledgment in the product documentation would be"),
+dkT(" appreciated but is not required."),
+dkT("2. Altered source versions must be plainly marked as such, and must not be"),
+dkT(" misrepresented as being the original software."),
+dkT("3. This notice may not be removed or altered from any source distribution."),
+dkT(""),
+dkT("Jean-loup Gailly Mark Adler"),
+dkT("jloup@gzip.org madler@alumni.caltech.edu"),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT(""),
+dkT("Bzip2 and libbzip2 library license"),
+dkT("=================================="),
+dkT("This program, \"bzip2\", the associated library \"libbzip2\", and all"),
+dkT("documentation, are copyright (C) 1996-2007 Julian R Seward. All"),
+dkT("rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions"),
+dkT("are met:"),
+dkT(""),
+dkT("1. Redistributions of source code must retain the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer."),
+dkT(""),
+dkT("2. The origin of this software must not be misrepresented; you must "),
+dkT(" not claim that you wrote the original software. If you use this "),
+dkT(" software in a product, an acknowledgment in the product "),
+dkT(" documentation would be appreciated but is not required."),
+dkT(""),
+dkT("3. Altered source versions must be plainly marked as such, and must"),
+dkT(" not be misrepresented as being the original software."),
+dkT(""),
+dkT("4. The name of the author may not be used to endorse or promote "),
+dkT(" products derived from this software without specific prior written "),
+dkT(" permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS"),
+dkT("OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED"),
+dkT("WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE"),
+dkT("GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS"),
+dkT("INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,"),
+dkT("WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS"),
+dkT("SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+dkT(""),
+dkT("Julian Seward, jseward@bzip.org"),
+dkT("bzip2/libbzip2 version 1.0.5 of 10 December 2007"),
+#endif
+#if DK4_HAVE_OPENSSL_MD5_H && DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_OPENSSL_RIPEMD_H
+dkT(""),
+dkT(""),
+dkT("OpenSSL license"),
+dkT("==============="),
+dkT(""),
+dkT("LICENSE ISSUES"),
+dkT("--------------"),
+dkT(""),
+dkT("The OpenSSL toolkit stays under a dual license, i.e. both the conditions of"),
+dkT("the OpenSSL License and the original SSLeay license apply to the toolkit."),
+dkT("See below for the actual license texts. Actually both licenses are BSD-style"),
+dkT("Open Source licenses. In case of any license issues related to OpenSSL"),
+dkT("please contact openssl-core@openssl.org."),
+dkT(""),
+dkT("OpenSSL License"),
+dkT("---------------"),
+dkT(""),
+dkT("Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions"),
+dkT("are met:"),
+dkT(""),
+dkT("1. Redistributions of source code must retain the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer. "),
+dkT(""),
+dkT("2. Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in"),
+dkT(" the documentation and/or other materials provided with the"),
+dkT(" distribution."),
+dkT(""),
+dkT("3. All advertising materials mentioning features or use of this"),
+dkT(" software must display the following acknowledgment:"),
+dkT(" \"This product includes software developed by the OpenSSL Project"),
+dkT(" for use in the OpenSSL Toolkit. (http://www.openssl.org/)\""),
+dkT(""),
+dkT("4. The names \"OpenSSL Toolkit\" and \"OpenSSL Project\" must not be used to"),
+dkT(" endorse or promote products derived from this software without"),
+dkT(" prior written permission. For written permission, please contact"),
+dkT(" openssl-core@openssl.org."),
+dkT(""),
+dkT("5. Products derived from this software may not be called \"OpenSSL\""),
+dkT(" nor may \"OpenSSL\" appear in their names without prior written"),
+dkT(" permission of the OpenSSL Project."),
+dkT(""),
+dkT("6. Redistributions of any form whatsoever must retain the following"),
+dkT(" acknowledgment:"),
+dkT(" \"This product includes software developed by the OpenSSL Project"),
+dkT(" for use in the OpenSSL Toolkit (http://www.openssl.org/)\""),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY"),
+dkT("EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR"),
+dkT("PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR"),
+dkT("ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,"),
+dkT("SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT"),
+dkT("NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;"),
+dkT("LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)"),
+dkT("HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,"),
+dkT("STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)"),
+dkT("ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED"),
+dkT("OF THE POSSIBILITY OF SUCH DAMAGE."),
+dkT(""),
+dkT("This product includes cryptographic software written by Eric Young"),
+dkT("(eay@cryptsoft.com). This product includes software written by Tim"),
+dkT("Hudson (tjh@cryptsoft.com)."),
+dkT(""),
+dkT(""),
+dkT("Original SSLeay License"),
+dkT("-----------------------"),
+dkT(""),
+dkT("Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("This package is an SSL implementation written"),
+dkT("by Eric Young (eay@cryptsoft.com)."),
+dkT("The implementation was written so as to conform with Netscapes SSL."),
+dkT(""),
+dkT("This library is free for commercial and non-commercial use as long as"),
+dkT("the following conditions are aheared to. The following conditions"),
+dkT("apply to all code found in this distribution, be it the RC4, RSA,"),
+dkT("lhash, DES, etc., code; not just the SSL code. The SSL documentation"),
+dkT("included with this distribution is covered by the same copyright terms"),
+dkT("except that the holder is Tim Hudson (tjh@cryptsoft.com)."),
+dkT(""),
+dkT("Copyright remains Eric Young's, and as such any Copyright notices in"),
+dkT("the code are not to be removed."),
+dkT("If this package is used in a product, Eric Young should be given attribution"),
+dkT("as the author of the parts of the library used."),
+dkT("This can be in the form of a textual message at program startup or"),
+dkT("in documentation (online or textual) provided with the package."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions"),
+dkT("are met:"),
+dkT("1. Redistributions of source code must retain the copyright"),
+dkT(" notice, this list of conditions and the following disclaimer."),
+dkT("2. Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("3. All advertising materials mentioning features or use of this software"),
+dkT(" must display the following acknowledgement:"),
+dkT(" \"This product includes cryptographic software written by"),
+dkT(" Eric Young (eay@cryptsoft.com)\""),
+dkT(" The word 'cryptographic' can be left out if the rouines from the library"),
+dkT(" being used are not cryptographic related :-)."),
+dkT("4. If you include any Windows specific code (or a derivative thereof) from "),
+dkT(" the apps directory (application code) you must include an acknowledgement:"),
+dkT(" \"This product includes software written by Tim Hudson (tjh@cryptsoft.com)\""),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND"),
+dkT("ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE"),
+dkT("FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS"),
+dkT("OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)"),
+dkT("HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT"),
+dkT("LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY"),
+dkT("OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF"),
+dkT("SUCH DAMAGE."),
+dkT(""),
+dkT("The licence and distribution terms for any publically available version or"),
+dkT("derivative of this code cannot be changed. i.e. this code cannot simply be"),
+dkT("copied and put under another distribution licence"),
+dkT("[including the GNU Public Licence.]"),
+dkT(""),
+#endif
+dkT(""),
+NULL
+
+
+#line 471 "dk-ls.ctr"
+};
+
+
+
+/** Constant texts used by program, not localized.
+*/
+static const dkChar * const dk_ls_kwnl[] = {
+/* 0 */
+dkT("dktools"),
+
+/* 1 */
+dkT("dk-ls.txt"),
+
+/* 2 */
+dkT("dk-ls.str"),
+
+/* 3 */
+dkT("mtpn"),
+
+/* 4 */
+dkT("."),
+
+/* 5 */
+dkT("\\"),
+
+/* 6 */
+dkT("/"),
+
+/* 7 */
+dkT(" -> "),
+
+/* 8 */
+dkT("mtn"),
+
+/* 9 */
+dkT("message.digest"),
+
+/* 10 */
+dkT("print.order"),
+
+/* 11 */
+dkT("ERROR: Application startup failed!\n"),
+
+NULL
+
+
+#line 529 "dk-ls.ctr"
+};
+
+
+
+/** Constant texts used by program, replaced by localized texts
+ if available.
+*/
+static const dkChar * const dk_ls_kw_def[] = {
+/* 0 */
+dkT("Failed to set up signal handlers!"),
+
+/* 1 */
+dkT("Failed to restore previous signal handlers!"),
+
+/* 2 */
+dkT("OVERFLOW"),
+
+/* 3 */
+dkT("Failed to obtain file size for symbolic link:\n\t\""),
+
+/* 4 */
+dkT("Failed to obtain file size for target:\n\t\""),
+
+/* 5 */
+dkT("\"!\n\tInformation not available!"),
+
+/* 6 */
+dkT("Path grows too long while recursing directory!"),
+
+/* 7 */
+dkT("Failed to obtain timestamp for symbolic link:\n\t\""),
+
+/* 8 */
+dkT("Failed to obtain timestamp for target:\n\t\""),
+
+/* 9 */
+dkT("\"!\nInformation not available!"),
+
+/* 10 */
+dkT("Failed to obtain file type and attributes (bug)!"),
+
+/* 11 */
+dkT("Invalid text in print order!"),
+
+/* 12 */
+dkT("Failed to find target for symbolic link:\n\t\""),
+
+/* 13 */
+dkT("\"!"),
+
+/* 14 */
+dkT("Failed to obtain unique file identifier:\n\t\""),
+
+/* 15 */
+dkT("\"!"),
+
+/* 16 */
+dkT("File names too long for expansion:\n\t\""),
+
+/* 17 */
+dkT("\",\n\t\""),
+
+/* 18 */
+dkT("\"!"),
+
+/* 19 */
+dkT("Message digest type not supported!"),
+
+/* 20 */
+dkT("Message digest type not supported: \""),
+
+/* 21 */
+dkT("\"!"),
+
+/* 22 */
+dkT("Not a message digest type name: \""),
+
+/* 23 */
+dkT("\"!"),
+
+/* 24 */
+dkT("Invalid encoding for message digest: \""),
+
+/* 25 */
+dkT("\"!"),
+
+/* 26 */
+dkT("Failed to initialize digest context (error from library function)!"),
+
+/* 27 */
+dkT("Failed to initialize message digest context!"),
+
+/* 28 */
+dkT("Failed to add data to message digest!"),
+
+/* 29 */
+dkT("Failed to finish message digest!"),
+
+/* 30 */
+dkT("# Number of directories: "),
+
+/* 31 */
+dkT("# Number of files: "),
+
+/* 32 */
+dkT("# Total number of bytes: "),
+
+NULL
+
+
+#line 632 "dk-ls.ctr"
+};
+
+
+
+#if DK4_ON_WINDOWS
+/** Buffer to store symbolic link destination.
+*/
+static dkChar dk_ls_sl_target[32784];
+#else
+/** Buffer to store symbolic link destination.
+*/
+static dkChar dk_ls_sl_target[DK4_MAX_PATH];
+#endif
+
+
+
+/** Options used by program.
+*/
+static const dk4_option_specification_t dk_ls_options[] = {
+
+ /* Reset (ignore preferences).
+ */
+ { dkT('R'), dkT("reset"), DK4_OPT_ARG_NONE },
+
+ /* Print order.
+ */
+ { dkT('p'), dkT("print-order"), DK4_OPT_ARG_STRING },
+
+ /* Recursive listing.
+ */
+ { dkT('r'), dkT("recursive"), DK4_OPT_ARG_NONE },
+
+ /* For recursive listings, stay on the current file system.
+ */
+ { dkT('f'), dkT("stay-on-filesystem"), DK4_OPT_ARG_NONE },
+
+ /* File types to show (all others are ignored).
+ */
+ { dkT('t'), dkT("types"), DK4_OPT_ARG_STRING },
+
+ { dkT('s'), dkT("summary"), DK4_OPT_ARG_NONE },
+
+#if DK4_HAVE_OPENSSL_MD5_H && DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_OPENSSL_RIPEMD_H
+ { dkT('m'), dkT("message-digest"), DK4_OPT_ARG_STRING },
+#endif
+};
+
+
+
+/** Buffer for print order from command line.
+*/
+static dkChar po_buf[32];
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Print order.
+*/
+static const dkChar *print_order = NULL;
+
+
+/** Message texts, uses localized texts if possible.
+*/
+static const dkChar * const *dk_ls_msg = dk_ls_kw_def;
+
+
+/** Error report for bytes counting.
+*/
+static dk4_er_t er_bytes;
+
+
+/** Error report for files counting.
+*/
+static dk4_er_t er_files;
+
+
+/** Error report for directory counting.
+*/
+static dk4_er_t er_dirs;
+
+
+
+/** Size found so far.
+*/
+static dk4_um_t size_bytes = (dk4_um_t)0UL;
+
+
+
+/** Number of files shown.
+*/
+static dk4_um_t num_files = (dk4_um_t)0UL;
+
+
+
+/** Number of directories shown.
+*/
+static dk4_um_t num_dirs = (dk4_um_t)0UL;
+
+
+
+
+/** Number of elements in the dk_ls_kw_def array and in dk_ls_msg.
+*/
+static size_t dk_ls_sz_msg =
+(sizeof(dk_ls_kw_def)/sizeof(DK4_PDKCHAR) - 1);
+
+
+
+#if DK4_ON_WINDOWS
+/** Limit for incrementing path construction buffer.
+ On Windows systems a special notation allows very long path names
+ up to 32767 characters.
+*/
+static const size_t dk_ls_max_path = 32784U;
+#else
+/** Limit for incrementing path construction buffer.
+ On non-Windows systems the path is restricted to DK4_MAX_PATH.
+*/
+static const size_t dk_ls_max_path = 2 * DK4_MAX_PATH;
+#endif
+
+
+
+/** Number of elements in the dk_ls_options array.
+*/
+static const size_t dk_ls_sz_options =
+sizeof(dk_ls_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Flag: Size output wanted.
+*/
+static int size_wanted = 0;
+
+
+
+/** Flag: Name output wanted.
+*/
+static int name_wanted = 0;
+
+
+
+/** Flag: Show non-directories.
+*/
+static int show_files = 1;
+
+
+
+/** Flag: Show directories.
+*/
+static int show_dirs = 1;
+
+
+
+/** Flag: Recursive listing.
+*/
+static int recursive = 0;
+
+
+
+/** Flag: Show summary.
+*/
+static int show_summary = 0;
+
+
+
+/** Flag: Stay on file system when recursing directories.
+*/
+static int stay_on_fs = 0;
+
+
+
+/** Message digest type.
+*/
+static int digest_type = DK4_MD_SHA1;
+
+
+
+/** Message digest encoding.
+*/
+static int digest_enco = DK4_BINARY_TO_TEXT_ENCODING_HEX;
+
+
+
+/** Flag: Unsupported digest type already reported.
+*/
+static int digest_erep = 0;
+
+
+
+/** Flag: Write error occured while writing to standard output.
+*/
+static int write_error = 0;
+
+
+
+/** Exit status code.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+/** Flag: Illegal characters in print order reported.
+*/
+static int print_order_error_reported = 0;
+
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+/** Pass a volatile pointer to an atomic integer.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ptr Address of atomic integer variable.
+ @return The unmodified pointer.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+/** Check whether we can continue or if a signal was received.
+ @param check_pipe Flag: Check for occured SIGPIPE signal too.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(int check_pipe)
+{
+ int back = 1;
+#ifdef SIGPIPE
+ if (0 != check_pipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_int )) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+/** Check whether we can continue.
+ @return 1 for yes, 0 for no.
+*/
+static
+int
+dk_ls_can_continue(void)
+{
+ int back = 1;
+ if (0 == sig_can_continue(1)) {
+ back = 0;
+ }
+ return back;
+}
+
+
+
+/** Node type for a directory.
+*/
+typedef struct _dk_ls_node_t_ {
+ struct _dk_ls_node_t_ *parent; /**< Pointer to parent node. */
+ struct _dk_ls_node_t_ *child; /**< Pointer to current child. */
+ dk4_dir_t *dirptr; /**< Directory. */
+ dk4_file_info_t fi; /**< File information. */
+ dk4_um_t size; /**< Directory size. */
+ int level; /**< Processing level. */
+ int ovsize; /**< Flag: Overflow in size calc. */
+} dk_ls_node_t;
+
+
+
+/** Destroy node object, release memory.
+ @param cn Node to destroy.
+*/
+static
+void
+dk_ls_delete_node(dk_ls_node_t *cn)
+{
+
+
+#line 989 "dk-ls.ctr"
+ if (NULL != cn) {
+ cn->parent = NULL;
+ cn->child = NULL;
+ if (NULL != cn->dirptr) {
+ dk4dir_close(cn->dirptr);
+ }
+ cn->dirptr = NULL;
+ dk4mem_free(cn);
+ }
+
+#line 998 "dk-ls.ctr"
+}
+
+
+
+/** Create new new directory node.
+ @param dn Directory name for node.
+ @param pa Parent node.
+ @param level Processing level.
+ @return Pointer to new node on success, NULL on error.
+*/
+static
+dk_ls_node_t *
+dk_ls_new_node(const dkChar *dn, dk_ls_node_t *pa, int level)
+{
+ dk4_er_t er;
+ dk_ls_node_t *back = NULL;
+ int om = DK4_DIR_OPEN_SORTED;
+ int ch = DK4_FILE_INFO_CONTENTS_DATA_TARGET;
+
+
+#line 1017 "dk-ls.ctr"
+ back = dk4mem_new_app(dk_ls_node_t,1,app);
+ if (NULL != back) {
+ DK4_MEMRES(back, sizeof(dk_ls_node_t));
+ back->parent = pa;
+ back->child = NULL;
+ back->dirptr = NULL;
+ back->level = level;
+ back->size = (dk4_um_t)0UL;
+ back->ovsize = 0;
+ if (3 < back->level) { back->level = 3; }
+ om |= DK4_DIR_SYMLINK_DIR_AS_FILE;
+ dk4error_init(&er);
+ back->dirptr = dk4dir_open_app(dn, om, app);
+ if (NULL == back->dirptr) {
+
+#line 1031 "dk-ls.ctr"
+ exval = EXIT_FAILURE;
+ dk_ls_delete_node(back);
+ back = NULL;
+ }
+ if (NULL != back) {
+
+#line 1036 "dk-ls.ctr"
+ dk4fileinfo_init(&(back->fi));
+ if (0 != dk4fileinfo_app(&(back->fi), dn, app)) {
+ if (0 == dk4fileinfo_size(&(back->size), &(back->fi), ch, NULL)) {
+ back->size = (dk4_um_t)0UL;
+
+#line 1040 "dk-ls.ctr"
+ /* ERROR: Failed to retrieve directory size */
+ dk_ls_report_fileinfo_size_error(app,dn,ch,dk_ls_msg,dk_ls_sz_msg);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+
+#line 1045 "dk-ls.ctr"
+ /* ERROR: Failed to retrieve file information, already reported */
+ exval = EXIT_FAILURE;
+ }
+ } else {
+
+#line 1049 "dk-ls.ctr"
+ /* ERROR: Failed to open directory, already reported */
+ exval = EXIT_FAILURE;
+ }
+ } else {
+
+#line 1053 "dk-ls.ctr"
+ /* ERROR: Allocation failed, already reported */
+ exval = EXIT_FAILURE;
+ }
+
+
+#line 1057 "dk-ls.ctr"
+ return back;
+}
+
+
+
+/** Construct a path name consisting of directory and
+ file or subdirectory name into an existing buffer.
+ @param bufptr Buffer address.
+ @param szbuf Size of buffer.
+ @param dirname Leading part of path name.
+ @param filename Trailing part of path name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error (buffer too short).
+*/
+static
+int
+dk_ls_dir_and_file(
+ dkChar *bufptr,
+ size_t szbuf,
+ const dkChar *dirname,
+ const dkChar *filename
+)
+{
+ int back = 0;
+ int nsep = 1; /* Flag: Separator needed */
+
+
+#line 1083 "dk-ls.ctr"
+ if (NULL != dirname) {
+ if (0 != dk4str_cpy_s(bufptr, szbuf, dirname, NULL)) {
+ while(dkT('\0') != *dirname) {
+#if DK4_ON_WINDOWS
+ if (dkT('\\') == *dirname)
+#else
+ if (dkT('/') == *dirname)
+#endif
+ {
+ nsep = 0;
+ } else {
+ nsep = 1;
+ }
+ dirname++;
+ }
+ if (0 != nsep) {
+#if DK4_ON_WINDOWS
+ if (0 != dk4str_cat_s(bufptr, szbuf, dk_ls_kwnl[5], NULL))
+#else
+ if (0 != dk4str_cat_s(bufptr, szbuf, dk_ls_kwnl[6], NULL))
+#endif
+ {
+ back = 1;
+ }
+ } else {
+ back = 1;
+ }
+ if (0 != back) {
+ back = 0;
+ if (0 != dk4str_cat_s(bufptr, szbuf, filename, NULL)) {
+ back = 1;
+ } else {
+
+#line 1115 "dk-ls.ctr"
+ /* BUG: Buffer too small */
+ exval = EXIT_FAILURE;
+ }
+ } else {
+
+#line 1119 "dk-ls.ctr"
+ /* BUG: Buffer too small */
+ exval = EXIT_FAILURE;
+ }
+ } else {
+
+#line 1123 "dk-ls.ctr"
+ /* BUG: Buffer too small */
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ back = dk4str_cpy_s(bufptr, szbuf, filename, NULL);
+ if (0 == back) {
+
+#line 1129 "dk-ls.ctr"
+ /* BUG: Buffer too small */
+ exval = EXIT_FAILURE;
+ }
+ }
+
+#line 1133 "dk-ls.ctr"
+ return back;
+}
+
+
+
+/** Construct a file or directory name, resize buffer if
+ necessary.
+ @param bufptr Address of pointer to buffer.
+ @param szbufptr Address of buffer size variable.
+ @param dirname Directory part of path to construct.
+ @param filename File name part of path to construct.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk_ls_construct_path(
+ dkChar **bufptr,
+ size_t *szbufptr,
+ const dkChar *dirname,
+ const dkChar *filename
+)
+{
+ dk4_er_t er; /* Error code */
+ dkChar *nb; /* New buffer */
+ size_t lgt; /* Required buffer size */
+ int back = 0;
+
+
+#line 1160 "dk-ls.ctr"
+ dk4error_init(&er);
+ lgt = dk4str_len(filename);
+ if (NULL != dirname) {
+ lgt = dk4ma_size_t_add(lgt, dk4str_len(dirname), &er);
+ lgt = dk4ma_size_t_add(lgt, 2, &er);
+ }
+ if (DK4_E_NONE == er.ec) {
+ if (lgt <= *szbufptr) {
+ /*
+ Keep current buffer.
+ */
+
+
+#line 1172 "dk-ls.ctr"
+ back = dk_ls_dir_and_file(*bufptr, *szbufptr, dirname, filename);
+ } else {
+ if (dk_ls_max_path > lgt) {
+ /*
+ Allocate new larger buffer.
+ */
+
+
+#line 1179 "dk-ls.ctr"
+ nb = dk4mem_new_app(dkChar, lgt, app);
+ if (NULL != nb) {
+
+#line 1181 "dk-ls.ctr"
+ dk4mem_release(*bufptr);
+ *bufptr = nb;
+ *szbufptr = lgt;
+ back = dk_ls_dir_and_file(*bufptr, *szbufptr, dirname, filename);
+ } else {
+
+#line 1186 "dk-ls.ctr"
+ /* ERROR: Memory allocation failed, already reported */
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Path size too long */
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 6);
+ exval = EXIT_FAILURE;
+ }
+ }
+ } else {
+ /* ERROR: Overflow in size calculation */
+ dk4app_log_base1(app, DK4_LL_ERROR, 82);
+ exval = EXIT_FAILURE;
+ }
+
+
+#line 1201 "dk-ls.ctr"
+ return back;
+}
+
+
+
+static
+void
+dk_ls_write_decimal_number(dk4_um_t value, size_t width)
+{
+ dkChar buf[16 + 8 * sizeof(dk4_um_t)];
+ dk4_er_t er;
+ size_t sl;
+ int res;
+ dk4error_init(&er);
+ res = dk4ma_write_decimal_unsigned(
+ buf, DK4_SIZEOF(buf,dkChar), value, 0, &er
+ );
+ if (0 != res) {
+ sl = dk4str_len(buf);
+ while (sl++ < width) {
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ if (0 == dk4fputs(buf, stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ } else {
+
+#line 1229 "dk-ls.ctr"
+ /* ERROR: Failed to write decimal number to buffer (bug) */
+ exval = EXIT_FAILURE;
+ }
+}
+
+
+
+static
+void
+dk_ls_write_hexadecimal_number(dk4_um_t value, size_t width)
+{
+ dkChar buf[16 + 8 * sizeof(dk4_um_t)];
+ dk4_er_t er;
+ size_t sl;
+ int res;
+
+
+#line 1245 "dk-ls.ctr"
+ dk4error_init(&er);
+ res = dk4ma_write_hex_unsigned(
+ buf, DK4_SIZEOF(buf,dkChar), value, width, &er
+ );
+ if (0 != res) {
+
+#line 1250 "dk-ls.ctr"
+ sl = dk4str_len(buf);
+ while (sl++ < width) {
+
+#line 1252 "dk-ls.ctr"
+ if (0 == dk4fputc(dkT('0'), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ if (0 == dk4fputs(buf, stdout, NULL)) {
+
+#line 1257 "dk-ls.ctr"
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ } else {
+
+#line 1260 "dk-ls.ctr"
+ /* BUG: Failed to write hexadecimal number to buffer */
+ exval = EXIT_FAILURE;
+ }
+
+
+#line 1264 "dk-ls.ctr"
+}
+
+
+
+/** Write file timestamp.
+ @param fiptr File information.
+ @param fn File name.
+ @param what Choose the timestamp.
+ @param issl Flag: Object is symbolic link.
+*/
+static
+void
+dk_ls_write_timestamp(
+ dk4_file_info_t *fiptr, const dkChar *fn, int what, int issl
+)
+{
+ dk4_er_t er;
+ dkChar buf[64];
+ int ch;
+ int res;
+
+ dk4error_init(&er);
+ ch = (
+ (0 != issl)
+ ? DK4_FILE_INFO_CONTENTS_DATA_LINK
+ : DK4_FILE_INFO_CONTENTS_DATA_TARGET
+ );
+ res = dk4fileinfo_timestamp(buf,DK4_SIZEOF(buf,dkChar),fiptr,ch,what,&er);
+ if (0 != res) {
+ if (0 == dk4fputs(buf, stdout, &er)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERRROR: Failed to obtain time */
+ dk_ls_report_fileinfo_timestamp_error(
+ app, fn, ch, dk_ls_msg, dk_ls_sz_msg
+ );
+ exval = EXIT_FAILURE;
+ }
+}
+
+
+
+/** Write indicator for unkown data.
+ @param width Field width.
+ @param compl Fill complete field.
+*/
+static
+void
+dk_ls_write_unknown(size_t width, int compl)
+{
+ if (0 != compl) {
+ while (0 < width--) {
+ if (0 == dk4fputc(dkT('?'), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ } else {
+ while (1 < width--) {
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ if (0 == dk4fputc(dkT('?'), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+}
+
+
+
+static
+int
+dk_ls_can_create_md(const dkChar *fn, dk4_file_info_t *fiptr)
+{
+ int back = 0;
+ if (0 == dk4fileinfo_is_symlink(fiptr)) {
+#if DK4_ON_WINDOWS
+ if (0 == (FILE_ATTRIBUTE_REPARSE_POINT & (fiptr->fattr))) {
+ if (0 == (FILE_ATTRIBUTE_DIRECTORY & (fiptr->fattr))) {
+ if (0 == (FILE_ATTRIBUTE_DEVICE & (fiptr->fattr))) {
+ back = 1;
+ }
+ }
+ }
+#else
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & (fiptr->contents))) {
+ if (S_IFREG == (S_IFMT & ((fiptr->tstb).st_mode))) {
+ back = 1;
+ }
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+/** Write message digest.
+ @param fn File name.
+ @param fiptr File information pointer.
+ @param digest_type Message digest type.
+ @param digest_enco Message digest encoding.
+ @param app Application structure for diagnostics.
+ @param dk_ls_msg Message texts array.
+ @param dk_ls_sz_msg Size of message texts error.
+*/
+static
+void
+dk_ls_write_md(
+ const dkChar *fn,
+ dk4_file_info_t *fiptr,
+ int digest_type,
+ int digest_enco,
+ dk4_app_t *app,
+ const dkChar * const *dk_ls_msg,
+ size_t dk_ls_sz_msg
+)
+{
+ char buf[4096]; /* Buffer to read file */
+ dk4_md_ctx_t ctx; /* Message digest context */
+ dk4_er_t er; /* Error report */
+ FILE *fipo; /* Input file to process */
+ const char *resptr; /* Pointer to encoded digest buffer */
+ size_t rdbytes; /* Number of bytes read */
+ int mdok = 0; /* Flag: Digesting ok so far */
+ if (0 != dk_ls_can_create_md(fn, fiptr)) {
+
+#line 1391 "dk-ls.ctr"
+ dk4error_init(&er);
+ if (0 != dk4md_ctx_init(&ctx, digest_type, digest_enco, &er)) {
+
+
+#line 1394 "dk-ls.ctr"
+ fipo = dk4fopen_app(fn, dkT("rb"), DK4_FOPEN_SC_IS_REGULAR, app);
+ if (NULL != fipo) {
+
+#line 1396 "dk-ls.ctr"
+ mdok = 1;
+ do {
+ if (0 != dk_ls_can_continue()) {
+ rdbytes = fread(buf, 1, sizeof(buf), fipo);
+ if (0 < rdbytes) {
+
+#line 1401 "dk-ls.ctr"
+ dk4error_init(&er);
+ if (1 != dk4md_ctx_add(&ctx, buf, rdbytes, &er)) {
+ mdok = 0;
+
+#line 1404 "dk-ls.ctr"
+ /* ERROR: Digest failed */
+ switch (er.ec) {
+ case DK4_E_NOT_SUPPORTED : {
+ dk4app_log_1(app,dk_ls_msg,dk_ls_sz_msg,DK4_LL_ERROR,19);
+ } break;
+ default : {
+ dk4app_log_1(app,dk_ls_msg,dk_ls_sz_msg,DK4_LL_ERROR,28);
+ } break;
+ }
+ }
+ }
+ } else {
+ mdok = 0;
+ rdbytes = 0;
+ }
+ } while((0 < rdbytes) && (1 == mdok));
+ fclose(fipo);
+ if (1 == mdok) {
+
+#line 1422 "dk-ls.ctr"
+ resptr = NULL; rdbytes = 0;
+ dk4error_init(&er);
+ if (1 == dk4md_ctx_finish(&resptr, &rdbytes, &ctx, &er)) {
+
+
+#line 1426 "dk-ls.ctr"
+ if ((NULL != resptr) && (0 < rdbytes)) {
+
+#line 1427 "dk-ls.ctr"
+ while(rdbytes--) {
+ if (0 == dk4fputc((dkChar)(*(resptr++)), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+
+#line 1430 "dk-ls.ctr"
+ }
+ }
+ } else {
+
+#line 1433 "dk-ls.ctr"
+ mdok = 0;
+ /* ERROR: No digest obtained */
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 29);
+ }
+ } else {
+
+#line 1438 "dk-ls.ctr"
+ mdok = 0;
+ /* ERROR: Failed to obtain digest */
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 29);
+ }
+ } else {
+
+#line 1443 "dk-ls.ctr"
+ }
+ } else {
+
+#line 1445 "dk-ls.ctr"
+ /* ERROR: Failed to open file, already reported */
+ }
+ } else {
+
+#line 1448 "dk-ls.ctr"
+ /* ERROR: Failed to initialize digest ctx */
+ switch (er.ec) {
+ case DK4_E_NOT_SUPPORTED : {
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 19);
+ } break;
+ case DK4_E_SYSTEM : {
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 26);
+ } break;
+ default : {
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 27);
+ } break;
+ }
+ }
+ } else {
+
+#line 1462 "dk-ls.ctr"
+ }
+ if (0 == mdok) {
+ rdbytes = dk4md_size(digest_type, digest_enco, NULL);
+ while (rdbytes--) {
+ if (0 == dk4fputc(dkT('x'), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ }
+}
+
+
+/** Write information about file to standard output.
+ @param fn File name.
+ @param fiptr File information.
+ @param use_size Flag: Use specified size.
+ @param size Size to use.
+ @param ovsize Flag: Numeric overflow in size calculation.
+*/
+static
+void
+dk_ls_process_item_information(
+ const dkChar *fn,
+ dk4_file_info_t *fiptr,
+ int use_size,
+ dk4_um_t size,
+ int ovsize
+)
+{
+ dkChar abuf[8*sizeof(dk4_um_t) + 16]; /* Attributes */
+ dkChar buf[8*sizeof(dk4_um_t) + 16]; /* Numbers */
+ dk4_er_t er; /* Error report */
+ const dkChar *piptr; /* Print order */
+ dk4_um_t fs; /* File size */
+ size_t numl; /* Number length */
+ size_t slen; /* String length */
+ size_t tlen; /* First part length */
+ size_t i; /* Index variable */
+ int issl; /* Flag: Is symbolic link */
+ int res; /* Result from information retrieval */
+ int showi; /* Flag: Show this item */
+ int habuf; /* Flag: Data in abuf */
+ int last_was_n; /* Flag: n was last character */
+ dkChar lasti; /* Last information printed */
+
+
+#line 1507 "dk-ls.ctr"
+ last_was_n = habuf = 0;
+ if ((NULL != fn) && (NULL != fiptr)) {
+
+#line 1509 "dk-ls.ctr"
+ showi = 1;
+ res = dk4fileinfo_type_attributes(
+ buf, DK4_SIZEOF(buf,dkChar), fiptr, &er
+ );
+ if (0 != res) {
+ showi = 0;
+ if (dkT('d') == buf[1]) {
+ if (0 != show_dirs) {
+ showi = 1;
+ if (0 != show_summary) {
+ num_dirs = dk4ma_um_add(num_dirs, 1, &er_dirs);
+ }
+ }
+ } else {
+ if (0 != show_files) {
+ showi = 1;
+ if (0 != show_summary) {
+ num_files = dk4ma_um_add(num_files, 1, &er_files);
+ }
+ }
+ }
+ } else {
+
+#line 1531 "dk-ls.ctr"
+ /* BUG: Failed to write file attributes to buffer */
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 10);
+ exval = EXIT_FAILURE;
+ }
+ if (0 != showi) {
+
+#line 1536 "dk-ls.ctr"
+ issl = dk4fileinfo_is_symlink(fiptr);
+ lasti = dkT('\0');
+ piptr = print_order;
+ while (dkT('\0') != *piptr) {
+
+#line 1540 "dk-ls.ctr"
+ last_was_n = 0;
+ if ((int)(*piptr) <= 255) {
+
+#line 1542 "dk-ls.ctr"
+ switch ((char)(*piptr)) {
+ case 'n' : {
+
+#line 1544 "dk-ls.ctr"
+ if (dkT('\0') != lasti) {
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ if (0 == dk4fputs(fn, stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ last_was_n = 1;
+ } break;
+ case 'N' : {
+
+#line 1555 "dk-ls.ctr"
+ if (dkT('\0') != lasti) {
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ if (0 == dk4fputs(fn, stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ } break;
+ case 's' : {
+
+#line 1565 "dk-ls.ctr"
+ if (dkT('\0') != lasti) {
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ res = 0;
+ if (0 != use_size) {
+ if (0 != ovsize) {
+ /* Show Overflow */
+ dk4error_set_simple_error_code(&er_bytes, DK4_E_MATH_OVERFLOW);
+ slen = dk4str_len(dk_ls_msg[2]);
+ numl = dk4numlength(sizeof(dk4_um_t), 0);
+ tlen = (numl - slen) / 2;
+ for (i = 0; i < tlen; i++) {
+ if (0 == dk4fputc(dkT('-'), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ if (0 == dk4fputs(dk_ls_msg[2], stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ for (i = (tlen + slen); i < numl; i++) {
+ if (0 == dk4fputc(dkT('-'), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ } else {
+ /* Show size */
+ fs = size;
+ res = 1;
+ }
+ } else {
+ dk4error_init(&er);
+ res = dk4fileinfo_size(
+ &fs, fiptr,
+ (
+ (0 != issl)
+ ? (DK4_FILE_INFO_CONTENTS_DATA_LINK)
+ : (DK4_FILE_INFO_CONTENTS_DATA_TARGET)
+ ),
+ &er
+ );
+ if (0 == res) {
+ /* ERROR: Failed to obtain size */
+
+
+#line 1610 "dk-ls.ctr"
+ dk_ls_report_fileinfo_size_error(
+ app, fn,
+ (
+ (0 != issl)
+ ? (DK4_FILE_INFO_CONTENTS_DATA_LINK)
+ : (DK4_FILE_INFO_CONTENTS_DATA_TARGET)
+ ),
+ dk_ls_msg, dk_ls_sz_msg
+ );
+ }
+ }
+ if (0 != res) {
+ numl = dk4numlength(sizeof(dk4_um_t), 0);
+ dk_ls_write_decimal_number(fs, numl);
+ if (0 != show_summary) {
+ size_bytes = dk4ma_um_add(size_bytes, fs, &er_bytes);
+ }
+ }
+ } break;
+ case 't' : {
+
+#line 1630 "dk-ls.ctr"
+ dk4error_init(&er);
+ if (0 == habuf) {
+ habuf = dk4fileinfo_type_attributes(
+ abuf, DK4_SIZEOF(abuf,dkChar), fiptr, &er
+ );
+ }
+ if (0 != habuf) {
+ if (dkT('\0') != lasti) {
+ if (0 == dk4fputc(dkT(' '), stdout, &er)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ if (0 == dk4fputc(abuf[0], stdout, &er)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ if (0 == dk4fputc(abuf[1], stdout, &er)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Failed to obtain file type */
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 10);
+ }
+ } break;
+ case 'p' : {
+ if (0 == habuf) {
+ habuf = dk4fileinfo_type_attributes(
+ abuf, DK4_SIZEOF(abuf,dkChar), fiptr, &er
+ );
+ }
+ if (0 != habuf) {
+ if ((dkT('\0') != lasti) && (dkT('t') != lasti)) {
+ if (0 == dk4fputc(dkT(' '), stdout, &er)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ if (0 == dk4fputs(&(abuf[2]), stdout, &er)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Failed to obtain file type */
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 10);
+ }
+ } break;
+ case 'l' : {
+
+#line 1674 "dk-ls.ctr"
+ fs = (dk4_um_t)1UL;
+ if (0 != issl) {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & fiptr->contents))
+ {
+#if DK4_ON_WINDOWS
+ fs = (dk4_um_t)((fiptr->linfo).nNumberOfLinks);
+#else
+ fs = (dk4_um_t)((fiptr->lstb).st_nlink);
+#endif
+ }
+ } else {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & fiptr->contents))
+ {
+#if DK4_ON_WINDOWS
+ fs = (dk4_um_t)((fiptr->tinfo).nNumberOfLinks);
+#else
+ fs = (dk4_um_t)((fiptr->tstb).st_nlink);
+#endif
+ }
+ }
+#if DK4_ON_WINDOWS
+ if ((DWORD)0UL == fiptr->resio) {
+#endif
+ dk_ls_write_decimal_number(
+ fs,
+#if DK4_ON_WINDOWS
+ dk4numlength(sizeof(DWORD), 0)
+#else
+ dk4numlength(sizeof(nlink_t), 0)
+#endif
+ );
+#if DK4_ON_WINDOWS
+ } else {
+ slen = dk4numlength(sizeof(DWORD), 0);
+ for (i = 1; i < slen; i++) {
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ if (0 == dk4fputc(dkT('?'), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+#endif
+ } break;
+ case 'c' : {
+
+#line 1720 "dk-ls.ctr"
+ if (dkT('\0') != lasti) {
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ dk_ls_write_timestamp(fiptr, fn, DK4_FILE_INFO_TIME_CREATE, issl);
+ } break;
+ case 'm' : {
+
+#line 1728 "dk-ls.ctr"
+ if (dkT('\0') != lasti) {
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ dk_ls_write_timestamp(fiptr, fn, DK4_FILE_INFO_TIME_MODIFY, issl);
+ } break;
+ case 'a' : {
+
+#line 1736 "dk-ls.ctr"
+ if (dkT('\0') != lasti) {
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ dk_ls_write_timestamp(fiptr, fn, DK4_FILE_INFO_TIME_ACCESS, issl);
+ } break;
+#if !DK4_ON_WINDOWS
+ case 'u' : {
+
+#line 1745 "dk-ls.ctr"
+ if (dkT('\0') != lasti) {
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ if (0 != issl) {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & fiptr->contents))
+ {
+ dk_ls_write_decimal_number(
+ (fiptr->lstb).st_uid,
+ dk4numlength(sizeof(uid_t), 0)
+ );
+ }
+ else
+ {
+ dk_ls_write_unknown(dk4numlength(sizeof(uid_t), 0), 0);
+ }
+ } else {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & fiptr->contents))
+ {
+ dk_ls_write_decimal_number(
+ (fiptr->tstb).st_uid,
+ dk4numlength(sizeof(uid_t), 0)
+ );
+ }
+ else
+ {
+ dk_ls_write_unknown(dk4numlength(sizeof(uid_t), 0), 0);
+ }
+ }
+ } break;
+#endif
+#if !DK4_ON_WINDOWS
+ case 'g' : {
+
+#line 1779 "dk-ls.ctr"
+ if (dkT('\0') != lasti) {
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ if (0 != issl) {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & fiptr->contents))
+ {
+ dk_ls_write_decimal_number(
+ (fiptr->lstb).st_gid,
+ dk4numlength(sizeof(gid_t), 0)
+ );
+ }
+ else
+ {
+ dk_ls_write_unknown(dk4numlength(sizeof(gid_t), 0), 0);
+ }
+ } else {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & fiptr->contents))
+ {
+ dk_ls_write_decimal_number(
+ (fiptr->tstb).st_gid,
+ dk4numlength(sizeof(gid_t), 0)
+ );
+ }
+ else
+ {
+ dk_ls_write_unknown(dk4numlength(sizeof(gid_t), 0), 0);
+ }
+ }
+ } break;
+#endif
+ case 'd' : {
+
+#line 1812 "dk-ls.ctr"
+ if (dkT('\0') != lasti) {
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+#if DK4_ON_WINDOWS
+ if (0 != issl) {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & fiptr->contents))
+ {
+ if ((DWORD)0UL == fiptr->resio) {
+ dk_ls_write_hexadecimal_number(
+ (fiptr->linfo).dwVolumeSerialNumber, 2*sizeof(DWORD)
+ );
+ } else {
+ dk_ls_write_unknown(2*sizeof(DWORD), 1);
+ }
+ }
+ else
+ {
+ dk_ls_write_unknown(2*sizeof(DWORD), 1);
+ }
+ } else {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & fiptr->contents))
+ {
+ if ((DWORD)0UL == fiptr->resio) {
+ dk_ls_write_hexadecimal_number(
+ (fiptr->tinfo).dwVolumeSerialNumber, 2*sizeof(DWORD)
+ );
+ } else {
+ dk_ls_write_unknown(2*sizeof(DWORD), 1);
+ }
+ }
+ else
+ {
+ dk_ls_write_unknown(2*sizeof(DWORD), 1);
+ }
+ }
+#else
+ if (0 != issl) {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & fiptr->contents))
+ {
+ dk_ls_write_hexadecimal_number(
+ (fiptr->lstb).st_dev, 2*sizeof(dev_t)
+ );
+ }
+ else
+ {
+ dk_ls_write_unknown(2*sizeof(dev_t), 1);
+ }
+ } else {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & fiptr->contents))
+ {
+ dk_ls_write_hexadecimal_number(
+ (fiptr->tstb).st_dev, 2*sizeof(dev_t)
+ );
+ }
+ else
+ {
+ dk_ls_write_unknown(2*sizeof(dev_t), 1);
+ }
+ }
+#endif
+ } break;
+ case 'r' : {
+
+#line 1876 "dk-ls.ctr"
+#if DK4_ON_WINDOWS
+ if (0 != issl) {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & fiptr->contents))
+ {
+ if ((DWORD)0UL == fiptr->resio) {
+ dk_ls_write_hexadecimal_number(
+ (fiptr->linfo).dwVolumeSerialNumber, 2*sizeof(DWORD)
+ );
+ } else {
+ dk_ls_write_unknown(2*sizeof(DWORD), 1);
+ }
+ }
+ else
+ {
+ dk_ls_write_unknown(2*sizeof(DWORD), 1);
+ }
+ } else {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & fiptr->contents))
+ {
+ if ((DWORD)0UL == fiptr->resio) {
+ dk_ls_write_hexadecimal_number(
+ (fiptr->tinfo).dwVolumeSerialNumber, 2*sizeof(DWORD)
+ );
+ } else {
+ dk_ls_write_unknown(2*sizeof(DWORD), 1);
+ }
+ }
+ else
+ {
+ dk_ls_write_unknown(2*sizeof(DWORD), 1);
+ }
+ }
+#else
+ if (0 != issl) {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & fiptr->contents))
+ {
+ dk_ls_write_hexadecimal_number(
+ (fiptr->lstb).st_rdev, 2*sizeof(dev_t)
+ );
+ }
+ else
+ {
+ dk_ls_write_unknown(2*sizeof(dev_t), 1);
+ }
+ } else {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & fiptr->contents))
+ {
+ dk_ls_write_hexadecimal_number(
+ (fiptr->tstb).st_rdev, 2*sizeof(dev_t)
+ );
+ }
+ else
+ {
+ dk_ls_write_unknown(2*sizeof(dev_t), 1);
+ }
+ }
+#endif
+ } break;
+ case 'i' : {
+
+#line 1935 "dk-ls.ctr"
+ if (dkT('\0') != lasti) {
+ if (dkT('d') != lasti) {
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ } else {
+ if (0 == dk4fputc(dkT(':'), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ }
+#if DK4_ON_WINDOWS
+ if (0 != issl) {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & fiptr->contents))
+ {
+ if ((DWORD)0UL == fiptr->resio) {
+ dk_ls_write_hexadecimal_number(
+ (fiptr->linfo).nFileIndexHigh, 2*sizeof(DWORD)
+ );
+ dk_ls_write_hexadecimal_number(
+ (fiptr->linfo).nFileIndexLow, 2*sizeof(DWORD)
+ );
+ } else {
+ dk_ls_write_unknown(4*sizeof(DWORD), 1);
+ }
+ }
+ else
+ {
+ dk_ls_write_unknown(4*sizeof(DWORD), 1);
+ }
+ } else {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & fiptr->contents))
+ {
+ if ((DWORD)0UL == fiptr->resio) {
+ dk_ls_write_hexadecimal_number(
+ (fiptr->tinfo).nFileIndexHigh, 2*sizeof(DWORD)
+ );
+ dk_ls_write_hexadecimal_number(
+ (fiptr->tinfo).nFileIndexLow, 2*sizeof(DWORD)
+ );
+ } else {
+ dk_ls_write_unknown(4*sizeof(DWORD), 1);
+ }
+ }
+ else
+ {
+ dk_ls_write_unknown(4*sizeof(DWORD), 1);
+ }
+ }
+#else
+ if (0 != issl) {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & fiptr->contents))
+ {
+ dk_ls_write_hexadecimal_number(
+ (fiptr->lstb).st_ino, 2*sizeof(ino_t)
+ );
+ }
+ else
+ {
+ dk_ls_write_unknown(2*sizeof(ino_t), 1);
+ }
+ } else {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & fiptr->contents))
+ {
+ dk_ls_write_hexadecimal_number(
+ (fiptr->tstb).st_ino, 2*sizeof(ino_t)
+ );
+ }
+ else
+ {
+ dk_ls_write_unknown(2*sizeof(ino_t), 1);
+ }
+ }
+#endif
+ } break;
+#if DK4_ON_WINDOWS
+ case 'w' : {
+
+#line 2012 "dk-ls.ctr"
+ if (dkT('\0') != lasti) {
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ dk_ls_write_hexadecimal_number(
+ fiptr->rppnt, 2*sizeof(DWORD)
+ );
+ } break;
+#endif
+ case 'x' : {
+ if (0 != dk4md_check_type(digest_type)) {
+ if (dkT('\0') != lasti) {
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ dk_ls_write_md(
+ fn, fiptr, digest_type, digest_enco, app,
+ dk_ls_msg, dk_ls_sz_msg
+ );
+ } else {
+ /* ERROR (once) Message digest type not supported */
+ if (0 == digest_erep) {
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 19);
+ digest_erep = 1;
+ }
+ }
+ } break;
+ default : {
+ /* ERROR (once): Invalid text in -p argument */
+ if (0 == print_order_error_reported) {
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 11);
+ print_order_error_reported = 1;
+ }
+ exval = EXIT_FAILURE;
+ } break;
+ }
+ } else {
+ /* ERROR (once): Invalid text in -p argument */
+ if (0 == print_order_error_reported) {
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 11);
+ print_order_error_reported = 1;
+ }
+ exval = EXIT_FAILURE;
+ }
+ lasti = *(piptr++);
+ }
+ if (0 != last_was_n) {
+ if (0 != dk4fileinfo_is_symlink(fiptr)) {
+ res = dk4symlink_target(
+ dk_ls_sl_target, DK4_SIZEOF(dk_ls_sl_target,dkChar), fn, NULL
+ );
+ if (0 != res) {
+ if (0 == dk4fputs(dk_ls_kwnl[7], stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ if (0 == dk4fputs(dk_ls_sl_target, stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Failed to find symlink target */
+ dk4app_log_3(app,dk_ls_msg,dk_ls_sz_msg,DK4_LL_ERROR,12,13,fn);
+ exval = EXIT_FAILURE;
+ }
+ }
+ }
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ } else {
+
+#line 2083 "dk-ls.ctr"
+ }
+ } else {
+
+#line 2085 "dk-ls.ctr"
+ }
+
+
+#line 2087 "dk-ls.ctr"
+}
+
+
+
+/** Process non-directory file.
+ @param fn File name.
+ @param level Processing level (0=cmd line arg, 1=direct child,
+ 2 and above=further indicrect siblings).
+*/
+static
+void
+dk_ls_process_non_directory(const dkChar *fn, int level)
+{
+ dk4_file_info_t fili;
+
+ dk4fileinfo_init(&fili);
+ if (0 != dk4fileinfo_app(&fili, fn, app)) {
+ dk_ls_process_item_information(fn, &fili, 0, (dk4_um_t)0UL, 0);
+ } else {
+ /* ERROR: Failed to obtain information about file, already reported */
+ exval = EXIT_FAILURE;
+ }
+}
+
+
+
+/** Process one directory item.
+ @param dirnode Node for the items parent directory.
+ @param filename Path name for item.
+*/
+static
+void
+dk_ls_process_item_for_node(
+ dk_ls_node_t *dirnode,
+ const dkChar *filename
+)
+{
+ dk4_file_info_t fili;
+ dk4_er_t er;
+ dk4_um_t fs;
+ int ch = DK4_FILE_INFO_CONTENTS_DATA_TARGET;
+
+
+#line 2129 "dk-ls.ctr"
+ if ((0 >= dirnode->level) || (0 != recursive) || (0 != size_wanted))
+ {
+ dk4error_init(&er);
+ dk4fileinfo_init(&fili);
+ if (0 != dk4fileinfo_app(&fili, filename, app)) {
+ if (0 != dk4fileinfo_is_symlink(&fili)) {
+ ch = DK4_FILE_INFO_CONTENTS_DATA_LINK ;
+ }
+ if (0 != dk4fileinfo_size(&fs, &fili, ch, &er)) {
+ dirnode->size = dk4ma_um_add(dirnode->size, fs, &er);
+ if (DK4_E_MATH_OVERFLOW == er.ec) {
+ dirnode->ovsize = 1;
+ }
+ } else {
+ /* ERROR: Failed to retrieve size */
+
+
+#line 2145 "dk-ls.ctr"
+ dk_ls_report_fileinfo_size_error(
+ app, filename, ch, dk_ls_msg, dk_ls_sz_msg
+ );
+ fs = (dk4_um_t)0UL;
+ exval = EXIT_FAILURE;
+ }
+ if ((0 >= dirnode->level ) || (0 != recursive)) {
+ /* Show file information */
+ dk_ls_process_item_information(
+ filename, &fili, 0, (dk4_um_t)0UL, 0
+ );
+ }
+ } else {
+ /* ERROR: Failed to obtain file information, already reported */
+ exval = EXIT_FAILURE;
+ }
+ }
+
+
+#line 2163 "dk-ls.ctr"
+}
+
+
+
+/** Process directory. Unless required otherwise by a non-zero
+ value for recursive, show contents and directory for level=0,
+ directory itself for level=1.
+ @param dn Directory name.
+ @param level Processing level (0=cmd line arg, 1=direct child,
+ 2 and above=further siblings).
+*/
+static
+void
+dk_ls_process_directory(const dkChar *dn, int level)
+{
+ dk4_ufi_t pdufi; /* UFI for parent directory */
+ dk4_ufi_t sdufi; /* UFI for sub directory */
+ dk4_er_t er; /* Error report for size addition */
+ dkChar *mybu; /* Buffer for path name construction */
+#if VERSION_BEFORE_20150821
+ dk_ls_node_t *rn; /* Root node */
+#endif
+ dk_ls_node_t *cn; /* Current node */
+ dk_ls_node_t *on; /* Other node */
+ const dkChar *pa; /* Directory path */
+ const dkChar *ndn; /* Next directory name */
+ size_t szmb; /* Size of mybu (number of dkChar) */
+ int gosub; /* Flag: Go into sub directory */
+ int ufich; /* Channel to retrieve UFI */
+
+
+#line 2193 "dk-ls.ctr"
+ /*
+ Allocate path name construction buffer.
+ */
+ ufich = DK4_FILE_INFO_CONTENTS_DATA_TARGET;
+ szmb = DK4_MAX_PATH;
+ mybu = dk4mem_new_app(dkChar,szmb,app);
+ /*
+ If path name construction buffer available, run normally.
+ */
+ if (NULL != mybu) {
+#if VERSION_BEFORE_20150821
+ rn = cn = dk_ls_new_node(dn, NULL, level);
+#else
+ cn = dk_ls_new_node(dn, NULL, level);
+#endif
+ while (NULL != cn) {
+
+#line 2209 "dk-ls.ctr"
+ if (0 != dk_ls_can_continue()) {
+
+#line 2210 "dk-ls.ctr"
+ ndn = dk4dir_next_dir(cn->dirptr);
+ if (NULL != ndn) {
+ /*
+ Handle sub directory.
+ */
+ pa = dk4dir_get_path(cn->dirptr);
+ if (0 != dk_ls_construct_path(&mybu, &szmb, pa, ndn)) {
+ /*
+ Decide whether or not to go into subdirectory
+ */
+ gosub = 0;
+#if 0
+ /* 2015-04-14
+ There is no reason to open a node for the subdirectory
+ unless recursive output or size calculation is wanted.
+ */
+ if (0 == cn->level) { /* Processing cmd line argument */
+ gosub = 1;
+ }
+#endif
+ if (0 != recursive) { /* Recursive output wanted */
+ gosub = 1;
+ }
+ if (0 != size_wanted) { /* Size calculation required */
+ if (0 != show_dirs) { /* ... and directory information wanted */
+ gosub = 1;
+ }
+ }
+ if (0 != gosub) {
+ if (0 != dk4ufi_get(&sdufi, mybu, NULL)) {
+ if (0 != stay_on_fs) { /* Check for same filesystem */
+ if (0 != dk4fileinfo_ufi(&pdufi, &(cn->fi), ufich, NULL)) {
+#if DK4_ON_WINDOWS
+ if (pdufi.ser != sdufi.ser) {
+ gosub = 0;
+ }
+#else
+ if (pdufi.dev != sdufi.dev) {
+ gosub = 0;
+ }
+#endif
+ } else {
+ /* ERROR: Failed to obtain file identifier */
+ dk4app_log_3(
+ app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 14, 15,
+ dk4dir_get_path(cn->dirptr)
+ );
+ gosub = 0;
+ exval = EXIT_FAILURE;
+ }
+ }
+ if (0 != gosub) { /* Check for symlink loop */
+ on = cn;
+ while ((0 != gosub) && (NULL != on)) {
+ if (0 != dk4fileinfo_ufi(&pdufi, &(on->fi), ufich, NULL)) {
+#if DK4_ON_WINDOWS
+ if (pdufi.ser == sdufi.ser) {
+ if (pdufi.inh == sdufi.inh) {
+ if (pdufi.inl == sdufi.inl) {
+ gosub = 0;
+ }
+ }
+ }
+#else
+ if (pdufi.dev == sdufi.dev) {
+ if (pdufi.ino == sdufi.ino) {
+ gosub = 0;
+ }
+ }
+#endif
+ } else {
+ /* ERROR: Failed to retrieve UFI for directory */
+ dk4app_log_3(
+ app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 14, 15,
+ dk4dir_get_path(on->dirptr)
+ );
+ exval = EXIT_FAILURE;
+ gosub = 0;
+ }
+ on = on->parent;
+ }
+ }
+ } else {
+ /* ERROR: Failed to retrieve unique file identifier */
+ dk4app_log_3(
+ app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 14, 15,
+ mybu
+ );
+ exval = EXIT_FAILURE;
+ gosub = 0;
+ }
+ }
+ if (0 != gosub) {
+ /*
+ Go into subdirectory.
+ */
+ on = dk_ls_new_node(
+ mybu, cn, ((3 >= cn->level) ? (1 + cn->level) : 3)
+ );
+ if (NULL != on) {
+ cn->child = on;
+ cn = on;
+ } else {
+ /* ERROR: Failed to create node, already reported */
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /*
+ Do not go into subdirectory, probably show directory details.
+ */
+ dk_ls_process_item_for_node(cn, mybu);
+ }
+ } else {
+ /* ERROR: Failed to construct path, already reported */
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /*
+ Finalize node, report non-directory entries and the
+ directories, finally move to parent node.
+ */
+ if ((0 != size_wanted) || (0 != show_files)) {
+ if (0 != dk_ls_can_continue()) {
+ do {
+ ndn = dk4dir_next_file(cn->dirptr);
+ if (NULL != ndn) {
+
+#line 2336 "dk-ls.ctr"
+ pa = dk4dir_get_path(cn->dirptr);
+ if (0 != dk_ls_construct_path(&mybu, &szmb, pa, ndn)) {
+ dk_ls_process_item_for_node(cn, mybu);
+ } else {
+ /* ERROR: Failed to construct path, already reported */
+ exval = EXIT_FAILURE;
+ }
+ }
+ } while((0 != dk_ls_can_continue()) && (NULL != ndn)) ;
+ }
+ }
+ if (0 != dk_ls_can_continue()) {
+
+#line 2348 "dk-ls.ctr"
+ if ((0 != size_wanted) || (0 != show_dirs)) {
+ if ((1 >= cn->level) || (0 != recursive)) {
+ dk_ls_process_item_information(
+ dk4dir_get_path(cn->dirptr), &(cn->fi),
+ 1, cn->size, cn->ovsize
+ );
+ }
+ }
+ }
+ on = cn->parent;
+ if (NULL != on) {
+ on->child = NULL;
+ dk4error_init(&er);
+ on->size = dk4ma_size_t_add(on->size, cn->size, &er);
+ if (DK4_E_NONE != er.ec) {
+ on->ovsize = 1;
+ }
+ if (0 != cn->ovsize) {
+ on->ovsize = 1;
+ }
+ }
+ dk_ls_delete_node(cn);
+ cn = on;
+ }
+ } else {
+ /*
+ Abort: Close current node and move to parent. No output.
+ */
+
+
+#line 2377 "dk-ls.ctr"
+ on = cn->parent;
+ if (NULL != on) { on->child = NULL; }
+ dk_ls_delete_node(cn);
+ cn = on;
+ }
+ }
+ } else {
+
+#line 2384 "dk-ls.ctr"
+ /* ERROR: Allocation failed, already reported */
+ exval = EXIT_FAILURE;
+ }
+ /*
+ Release path name construction buffer.
+ */
+ if (NULL != mybu) {
+ dk4mem_release(mybu);
+ }
+
+
+#line 2394 "dk-ls.ctr"
+}
+
+
+
+/** Check whether the specified file name is a directory.
+ @param fn File name.
+ @return 1 for directories, 0 for non-directory entries,
+ -1 on errors.
+*/
+static
+int
+dk_ls_is_directory(const dkChar *fn)
+{
+#if DK4_ON_WINDOWS
+ DWORD dwattr;
+ HANDLE ha;
+ LONG lasterror;
+#if DK4_CHAR_SIZE > 1
+ WIN32_FIND_DATAW finddata;
+#else
+ WIN32_FIND_DATAA finddata;
+#endif
+#else
+ dk4_stat_t stb;
+ dk4_er_t er;
+#endif
+ int back = -1;
+
+
+#line 2422 "dk-ls.ctr"
+ if (NULL != fn) {
+#if DK4_ON_WINDOWS
+#if DK4_CHAR_SIZE > 1
+ dwattr = GetFileAttributesW(fn);
+#else
+ dwattr = GetFileAttributesA(fn);
+#endif
+ if (INVALID_FILE_ATTRIBUTES != dwattr) {
+ if (0 != (FILE_ATTRIBUTE_DIRECTORY & dwattr)) {
+ back = 1;
+ } else {
+ back = 0;
+ }
+ } else {
+ lasterror = GetLastError();
+#if DK4_CHAR_SIZE > 1
+ ha = FindFirstFileW(fn, &finddata);
+#else
+ ha = FindFirstFileA(fn, &finddata);
+#endif
+ if (INVALID_HANDLE_VALUE != ha) {
+ if (0 != (FILE_ATTRIBUTE_DIRECTORY & (finddata.dwFileAttributes))) {
+ back = 1;
+ } else {
+ back = 0;
+ }
+ FindClose(ha);
+ } else {
+ /* ERROR: Failed to retrieve file attributes */
+ dk4fileinfo_report_win_failed(app, fn, lasterror);
+ exval = EXIT_FAILURE;
+ }
+ }
+#else
+ dk4error_init(&er);
+ if (0 != dk4stat(&stb, fn, &er)) {
+ if (0 != dk4stat_is_directory(&stb, &er)) {
+ back = 1;
+ } else {
+ back = 0;
+ }
+ } else {
+ /* ERROR: Failed to retrieve file information */
+ dk4fileinfo_report_stat_failed(app, fn, er.dt.iDetails1);
+ exval = EXIT_FAILURE;
+ }
+#endif
+ }
+
+#line 2470 "dk-ls.ctr"
+ return back;
+}
+
+
+
+/* !!!!!
+ For files explicitly mentioned on the command line
+ processing starts here, probably after name expansion.
+*/
+
+/** Run for one file or directory directly named on the command line.
+ @param arg Path name.
+*/
+static
+void
+run_for_one_name(const dkChar *arg)
+{
+
+
+#line 2488 "dk-ls.ctr"
+ switch (dk_ls_is_directory(arg)) {
+ case 1 : {
+
+#line 2490 "dk-ls.ctr"
+ dk_ls_process_directory(arg, 0);
+ } break;
+ case 0 : {
+
+#line 2493 "dk-ls.ctr"
+ if (0 != show_files) {
+ dk_ls_process_non_directory(arg, 0);
+ }
+ } break;
+ default : {
+
+#line 2498 "dk-ls.ctr"
+ /* ERROR: Failed to obtain information about file, already reported */
+ exval = EXIT_FAILURE;
+ } break;
+ }
+
+
+#line 2503 "dk-ls.ctr"
+}
+
+
+
+/** Process command line arguments.
+ @param xargc Number of command line arguments.
+*/
+static
+void
+run_for_command_line_arguments(int xargc)
+{
+#if DK4_ON_WINDOWS
+ dkChar buf[DK4_MAX_PATH];
+ dk4_dir_t *fne;
+ const dkChar *pth;
+ const dkChar *fn;
+ int cc2;
+#endif
+ const dkChar *xargv;
+ int i;
+ int cc = 1;
+
+
+#line 2525 "dk-ls.ctr"
+ for (i = 0; ((i < xargc) && (1 == cc)); i++) {
+
+#line 2526 "dk-ls.ctr"
+ if (0 != dk_ls_can_continue()) {
+
+#line 2527 "dk-ls.ctr"
+ xargv = dk4app_get_argv(app, i);
+
+#line 2528 "dk-ls.ctr"
+#if DK4_ON_WINDOWS
+ if (0 != dk4path_must_expand(xargv)) {
+ /* !!!!!
+ For file names we need to expand
+ processing starts here.
+ */
+ fne = dk4app_fne_open(xargv, app);
+ if (NULL != fne) {
+ cc2 = 1;
+ while (1 == cc2) {
+ if (0 != dk_ls_can_continue()) {
+ fn = dk4dir_next_dir(fne);
+ if (NULL != fn) {
+ pth = dk4dir_get_path(fne);
+ if (NULL != pth) {
+ if (0 != dk4str_cpy_s(buf,DK4_SIZEOF(buf,dkChar),pth,NULL)) {
+ if (0!=dk4str_cat_s(buf,DK4_SIZEOF(buf,dkChar),dk_ls_kwnl[5],NULL))
+ {
+ if (0 != dk4str_cat_s(buf,DK4_SIZEOF(buf,dkChar),fn,NULL)) {
+ dk_ls_process_directory(buf, 0);
+ } else {
+ /* ERROR: File name too long! */
+ dk4app_log_5(
+ app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 16, 17, 18,
+ pth, fn
+ );
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: File name too long! */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: File name too long! */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ run_for_one_name(fn);
+ }
+ } else {
+ cc2 = 0;
+ }
+ } else {
+ cc2 = 0;
+ }
+ }
+ cc2 = 1;
+ while (1 == cc2) {
+ if (0 != dk_ls_can_continue()) {
+ fn = dk4dir_next_file(fne);
+ if (NULL != fn) {
+ pth = dk4dir_get_path(fne);
+ if (NULL != pth) {
+ if (0 != dk4str_cpy_s(buf,DK4_SIZEOF(buf,dkChar),pth,NULL)) {
+ if (0!=dk4str_cat_s(buf,DK4_SIZEOF(buf,dkChar),dk_ls_kwnl[5],NULL))
+ {
+ if (0 != dk4str_cat_s(buf,DK4_SIZEOF(buf,dkChar),fn,NULL)) {
+ dk_ls_process_non_directory(buf, 0);
+ } else {
+ /* ERROR: File name too long! */
+ dk4app_log_5(
+ app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 16, 17, 18,
+ pth, fn
+ );
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: File name too long! */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: File name too long! */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ run_for_one_name(fn);
+ }
+ } else {
+ cc2 = 0;
+ }
+ } else {
+ cc2 = 0;
+ }
+ }
+ dk4dir_close(fne);
+ } else {
+ /* ERROR: Failed to expand file name, already reported */
+ exval = EXIT_FAILURE;
+ }
+ } else {
+#endif
+
+
+#line 2624 "dk-ls.ctr"
+ run_for_one_name(xargv);
+#if DK4_ON_WINDOWS
+ }
+#endif
+ } else {
+ cc = 0;
+ }
+ }
+
+
+#line 2633 "dk-ls.ctr"
+}
+
+
+
+/* !!!!!
+ If no file names was given on the command line processing
+ starts here.
+*/
+
+/** Show contents of current directory.
+*/
+static
+void
+run_for_current_dir_contents(void)
+{
+ dk4_er_t er;
+ dk4_dir_t *dirptr;
+ const dkChar *fn;
+ int cc;
+ int om;
+
+
+#line 2654 "dk-ls.ctr"
+ dk4error_init(&er);
+ om = DK4_DIR_OPEN_SORTED | DK4_DIR_SYMLINK_DIR_AS_FILE;
+ dirptr = dk4dir_open_app(dk_ls_kwnl[4], om, app);
+ if (NULL != dirptr) {
+ if ((0 != recursive) || (0 != show_dirs)) {
+ cc = 1;
+ while(1 == cc) {
+ if (0 != dk_ls_can_continue()) {
+ fn = dk4dir_next_dir(dirptr);
+ if (NULL != fn) {
+ if ((0 != recursive) || (0 != size_wanted)) {
+ dk_ls_process_directory(fn, 1);
+ } else {
+ dk_ls_process_non_directory(fn, 1);
+ }
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = 0;
+ }
+ }
+ }
+ if (0 != show_files) {
+ cc = 1;
+ while (1 == cc) {
+ if (0 != dk_ls_can_continue()) {
+ fn = dk4dir_next_file(dirptr);
+ if (NULL != fn) {
+ dk_ls_process_non_directory(fn, 1);
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = 0;
+ }
+ }
+ }
+ dk4dir_close(dirptr);
+ } else {
+ /* ERROR: Failed to open current directory, already reported */
+ exval = EXIT_FAILURE;
+ }
+
+
+#line 2698 "dk-ls.ctr"
+}
+
+
+
+/** Process command line arguments (if any).
+*/
+static
+void
+dk_ls_normal_run(void)
+{
+ dkChar mdbuf[32];
+ dkChar *bptr;
+ int res;
+ int xargc;
+ int mdset;
+
+
+#line 2714 "dk-ls.ctr"
+ exval = EXIT_SUCCESS;
+
+ /* Process options.
+ */
+ if (0 != dk4app_opt_is_set_short(app, dkT('p'), NULL)) {
+ res = dk4app_opt_get_string_short(
+ po_buf, DK4_SIZEOF(po_buf,dkChar), app, dkT('p'), NULL
+ );
+ if (0 != res) {
+ print_order = po_buf;
+ }
+ }
+ if (NULL == print_order) {
+ if (0 == dk4app_opt_is_set_short(app, dkT('R'), NULL)) {
+ res = dk4app_pref_get(
+ po_buf, DK4_SIZEOF(po_buf,dkChar), app, dk_ls_kwnl[10], 0
+ );
+ if (0 != res) {
+ dk4str_rtwh(po_buf, NULL);
+ print_order = dk4str_start(po_buf, NULL);
+ }
+ }
+ }
+ if (NULL == print_order) {
+#if DK4_ON_WINDOWS
+ print_order = dk_ls_kwnl[8];
+#else
+ print_order = dk_ls_kwnl[3];
+#endif
+ }
+ if (NULL != dk4str_chr(print_order, dkT('s'))) {
+ size_wanted = 1;
+ }
+ if (NULL != dk4str_chr(print_order, dkT('n'))) {
+ name_wanted = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('r'), NULL)) {
+ recursive = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('f'), NULL)) {
+ stay_on_fs = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('t'), NULL)) {
+ res = dk4app_opt_get_string_short(
+ mdbuf, DK4_SIZEOF(mdbuf,dkChar), app, dkT('t'), NULL
+ );
+ if (0 != res) {
+ bptr = mdbuf;
+ show_files = 0; show_dirs = 0;
+ while (dkT('\0') != *bptr) {
+ if (dkT('d') == *bptr) { show_dirs = 1; }
+ if (dkT('f') == *bptr) { show_files = 1; }
+ bptr++;
+ }
+ }
+ }
+ mdset = 0;
+ if (0 != dk4app_opt_is_set_short(app, dkT('m'), NULL)) {
+ res = dk4app_opt_get_string_short(
+ mdbuf, DK4_SIZEOF(mdbuf,dkChar), app, dkT('m'), NULL
+ );
+ if (0 != res) {
+ /* Process string, find digest and encoding */
+ mdset = 1;
+ dk_ls_set_md(
+ &digest_type, &digest_enco, mdbuf, app, dk_ls_msg, dk_ls_sz_msg
+ );
+ }
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('s'), NULL)) {
+ show_summary = 1;
+ }
+ if ((0 == mdset) && (0 == dk4app_opt_is_set_short(app, dkT('R'), NULL))) {
+ res = dk4app_pref_get(
+ mdbuf, DK4_SIZEOF(mdbuf,dkChar), app, dk_ls_kwnl[9], 0
+ );
+ if (0 != res) {
+ dk_ls_set_md(
+ &digest_type, &digest_enco, mdbuf, app, dk_ls_msg, dk_ls_sz_msg
+ );
+ }
+ }
+
+ /* Process command line arguments or current directory contents.
+ */
+ xargc = dk4app_get_argc(app);
+ if (0 < xargc) {
+
+#line 2801 "dk-ls.ctr"
+ run_for_command_line_arguments(xargc);
+ } else {
+
+#line 2803 "dk-ls.ctr"
+ run_for_current_dir_contents();
+ }
+ if (0 != show_summary) {
+ if (((dk4_um_t)0UL != num_dirs) && (DK4_E_NONE == er_dirs.ec)) {
+ if (0 == dk4fputs(dk_ls_msg[30], stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ dk_ls_write_decimal_number(num_dirs,dk4numlength(sizeof(dk4_um_t),0));
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ if (((dk4_um_t)0UL != num_files) && (DK4_E_NONE == er_files.ec)) {
+ if (0 == dk4fputs(dk_ls_msg[31], stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ dk_ls_write_decimal_number(num_files,dk4numlength(sizeof(dk4_um_t),0));
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ if (((dk4_um_t)0UL != size_bytes) && (DK4_E_NONE == er_bytes.ec)) {
+ if (0 == dk4fputs(dk_ls_msg[32], stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ dk_ls_write_decimal_number(size_bytes,dk4numlength(sizeof(dk4_um_t),0));
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ }
+
+
+#line 2835 "dk-ls.ctr"
+}
+
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+dk_ls_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ struct sigaction opipe;
+#endif
+ struct sigaction oint;
+#ifdef SIGPIPE
+ struct sigaction npipe;
+#endif
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+ int success = 0;
+
+#ifdef SIGPIPE
+ /* Set up signal handling for SIGPIPE.
+ */
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+#endif
+
+ /* Set up signal handling for SIGINT.
+ */
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ dk_ls_normal_run();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+#ifdef SIGPIPE
+ /* Restore signal handling for SIGPIPE.
+ */
+ restore_old_pipe:
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+#endif
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+dk_ls_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ dk_ls_normal_run();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+#ifdef SIGPIPE
+ sigset(SIGPIPE, oldpipe);
+#endif
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+dk_ls_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = signal(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ dk_ls_normal_run();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+#ifdef SIGPIPE
+ signal(SIGPIPE, oldpipe);
+#endif
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+dk_ls_run_with_signal_handlers(void)
+{
+ dk_ls_normal_run();
+}
+#endif
+#endif
+#endif
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+
+
+#line 3039 "dk-ls.ctr"
+
+
+#line 3040 "dk-ls.ctr"
+ dk4fput_initialize_stdout();
+ dk4fput_initialize_stderr();
+ dk4error_init(&er_dirs);
+ dk4error_init(&er_files);
+ dk4error_init(&er_bytes);
+ app = dk4app_open_cmd(
+ argc, argv, dk_ls_options, dk_ls_sz_options,
+ dk_ls_kwnl[0], DKT_VERSION_DK,
+ dk_ls_kwnl[1], dk_ls_help_text, dk_ls_license_text
+ );
+ if (NULL != app) {
+
+#line 3051 "dk-ls.ctr"
+ dk_ls_sz_msg = dk4app_string_table_size(dk_ls_kw_def);
+ dk_ls_msg = dk4app_string_table(app, dk_ls_kwnl[2], dk_ls_kw_def);
+ if (0 != dk4app_can_run_normally(app)) {
+
+#line 3054 "dk-ls.ctr"
+ dk_ls_run_with_signal_handlers();
+ } else {
+ if (0 != dk4app_help_version_license(app)) {
+
+#line 3057 "dk-ls.ctr"
+ exval = EXIT_SUCCESS;
+ }
+ }
+ dk4app_close(app);
+ } else {
+
+#line 3062 "dk-ls.ctr"
+ dk4fputs(dk_ls_kwnl[11], stdout, NULL);
+ fflush(stdout);
+ }
+ fflush(stdout);
+ fflush(stderr);
+ dk4fput_cleanup_stderr();
+ dk4fput_cleanup_stdout();
+
+
+#line 3070 "dk-ls.ctr"
+
+
+#line 3071 "dk-ls.ctr"
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/dk-ls.ctr b/support/dktools/dk-ls.ctr
new file mode 100644
index 0000000000..57786e6fa9
--- /dev/null
+++ b/support/dktools/dk-ls.ctr
@@ -0,0 +1,3073 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk-ls.h Header file for dk-ls program.
+*/
+
+#include "dk4md.h"
+#include "dk4fileit.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Set message digest type and message digest encoding.
+ @param mdtype Address of message digest type variable.
+ @param mdenc Address of message digest encoding variable.
+ @param buffer Buffer containing textual description.
+ @param app Application structure for diagnostics, may be NULL.
+ @param msg Message string array.
+ @param szmsg Size of message string array.
+*/
+void dk_ls_set_md(
+ int *mdtype,
+ int *mdenc,
+ dkChar *buffer,
+ dk4_app_t *app,
+ const dkChar * const *msg,
+ size_t szmsg
+);
+
+/** Read information about symbolic link target.
+ @param bptr Buffer for path name.
+ @param szb Size of buffer (number of dkChar).
+ @param fn Link filename.
+ @return 1 on success, 0 on error.
+*/
+int
+dk_ls_readlink(dkChar *bptr, size_t szb, const dkChar *fn);
+
+/** Report error while attempting to read size.
+ @param app Application structure for diagnostics.
+ @param fn File name.
+ @param ch Data chooser.
+ @param msg Constant message texts.
+ @param szmsg Size of msg array.
+*/
+void
+dk_ls_report_fileinfo_size_error(
+ dk4_app_t *app,
+ const dkChar *fn,
+ int ch,
+ const dkChar * const *msg,
+ size_t szmsg
+);
+
+/** Report error while attempting to read timestamp.
+ @param app Application structure for diagnostics.
+ @param fn File name.
+ @param ch Data chooser.
+ @param msg Constant message texts.
+ @param szmsg Size of msg array.
+*/
+void
+dk_ls_report_fileinfo_timestamp_error(
+ dk4_app_t *app,
+ const dkChar *fn,
+ int ch,
+ const dkChar * const *msg,
+ size_t szmsg
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4vers.h"
+#include "dk4app.h"
+#include "dk4aopt.h"
+#include "dk4mem.h"
+#include "dk4mema.h"
+#include "dk4fput.h"
+#include "dk-ls.h"
+#include "dk4mpl.h"
+#include "dk4stat.h"
+#include "dk4statd.h"
+#include "dk4strd.h"
+#include "dk4fileit.h"
+#include "dk4filei.h"
+#include "dk4fileia.h"
+#include "dk4masz.h"
+#include "dk4maadu.h"
+#include "dk4maodd.h"
+#include "dk4maodh.h"
+#include "dk4numl.h"
+#include "dk4dira.h"
+#include "dk4pathd.h"
+#include "dk4fopda.h"
+#include "dk4symlink.h"
+
+
+
+$!trace-include
+
+
+
+/** Default help text, used if help text file is not found.
+*/
+static const dkChar * const dk_ls_help_text[] = {
+$!text macro=dkT,preprocessor
+
+List files
+
+dk-ls [<options>] [<file(s)>]
+
+Options:
+-p ... Output column order, see below. -r Recursive listing.
+-t ... File types to list. -m ... Message digest type.
+-f Stay on current file system. -s Show summary at end.
+--help Show this short help text. --manual *** SHOW FULL MANUAL. ***
+--version Show version information. --license Show license information.
+
+Column order characters: n=name, s=size, t=type, p=permissions/attributes,
+c=creation, m=modification, a=access, l=links, u=UID, g=GID, d=device,
+i=inode, r=relative device, w=reparse tag (Widnows), x=message digest.
+Default: ``mtpn'' (``mtn'' on Windows).
+
+File type characters: d=directories, f=non-directory entries.
+
+Message digest types: md5, sha-1, sha-224, sha-256, sha-384, sha-512,
+ripemd-160. Optionally add encoding hex or a85, i.e. ``sha-1.hex''.
+
+http://dktools.sourceforge.net
+
+$!end
+};
+
+
+
+/** License conditions.
+*/
+static const dkChar * const dk_ls_license_text[] = {
+$!text macro=dkT,preprocessor
+This software uses code from the following projects, either directly or as
+a library:
+
+dktools Dirk Krause's tools and libraries.
+ See http://dktools.sourceforge.net/ for more information.
+#if DK4_HAVE_ZLIB_H
+
+zlib Data compression library.
+ See http://www.zlib.net/ for more information.
+#endif
+#if DK4_HAVE_BZLIB_H
+
+bzip2 Data compression program and library.
+ See http://www.bzip.org/ for more information.
+#endif
+#if DK4_HAVE_OPENSSL_MD5_H && DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_OPENSSL_RIPEMD_H
+
+OpenSSL Cryptographic toolkit, used to build file checksums here.
+ See http://www.openssl.org/ for more information.
+
+This product includes software developed by the OpenSSL Project for use in
+the OpenSSL Toolkit (http://www.openssl.org/).
+This product includes cryptographic software written by
+Eric Young (eay@cryptsoft.com).
+This product includes software written by Tim Hudson (tjh@cryptsoft.com).
+#endif
+
+All the licenses below apply to the program.
+Licenses for used libraries are shown as found on my Scientific Linux 6.x
+computer in the /usr/share/doc directory on 2015-04-01. Check the project
+homepages of the used libraries for additional information and/or updated
+license terms.
+
+
+DK tools and libraries license
+==============================
+Copyright (c) 2015-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#if DK4_HAVE_ZLIB_H
+
+
+Zlib license
+============
+(C) 1995-2004 Jean-loup Gailly and Mark Adler
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+
+Jean-loup Gailly Mark Adler
+jloup@gzip.org madler@alumni.caltech.edu
+#endif
+#if DK4_HAVE_BZLIB_H
+
+
+Bzip2 and libbzip2 library license
+==================================
+This program, "bzip2", the associated library "libbzip2", and all
+documentation, are copyright (C) 1996-2007 Julian R Seward. All
+rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+3. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Julian Seward, jseward@bzip.org
+bzip2/libbzip2 version 1.0.5 of 10 December 2007
+#endif
+#if DK4_HAVE_OPENSSL_MD5_H && DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_OPENSSL_RIPEMD_H
+
+
+OpenSSL license
+===============
+
+LICENSE ISSUES
+--------------
+
+The OpenSSL toolkit stays under a dual license, i.e. both the conditions of
+the OpenSSL License and the original SSLeay license apply to the toolkit.
+See below for the actual license texts. Actually both licenses are BSD-style
+Open Source licenses. In case of any license issues related to OpenSSL
+please contact openssl-core@openssl.org.
+
+OpenSSL License
+---------------
+
+Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+3. All advertising materials mentioning features or use of this
+ software must display the following acknowledgment:
+ "This product includes software developed by the OpenSSL Project
+ for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+
+4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ endorse or promote products derived from this software without
+ prior written permission. For written permission, please contact
+ openssl-core@openssl.org.
+
+5. Products derived from this software may not be called "OpenSSL"
+ nor may "OpenSSL" appear in their names without prior written
+ permission of the OpenSSL Project.
+
+6. Redistributions of any form whatsoever must retain the following
+ acknowledgment:
+ "This product includes software developed by the OpenSSL Project
+ for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+
+THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+OF THE POSSIBILITY OF SUCH DAMAGE.
+
+This product includes cryptographic software written by Eric Young
+(eay@cryptsoft.com). This product includes software written by Tim
+Hudson (tjh@cryptsoft.com).
+
+
+Original SSLeay License
+-----------------------
+
+Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+All rights reserved.
+
+This package is an SSL implementation written
+by Eric Young (eay@cryptsoft.com).
+The implementation was written so as to conform with Netscapes SSL.
+
+This library is free for commercial and non-commercial use as long as
+the following conditions are aheared to. The following conditions
+apply to all code found in this distribution, be it the RC4, RSA,
+lhash, DES, etc., code; not just the SSL code. The SSL documentation
+included with this distribution is covered by the same copyright terms
+except that the holder is Tim Hudson (tjh@cryptsoft.com).
+
+Copyright remains Eric Young's, and as such any Copyright notices in
+the code are not to be removed.
+If this package is used in a product, Eric Young should be given attribution
+as the author of the parts of the library used.
+This can be in the form of a textual message at program startup or
+in documentation (online or textual) provided with the package.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. All advertising materials mentioning features or use of this software
+ must display the following acknowledgement:
+ "This product includes cryptographic software written by
+ Eric Young (eay@cryptsoft.com)"
+ The word 'cryptographic' can be left out if the rouines from the library
+ being used are not cryptographic related :-).
+4. If you include any Windows specific code (or a derivative thereof) from
+ the apps directory (application code) you must include an acknowledgement:
+ "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+
+THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+The licence and distribution terms for any publically available version or
+derivative of this code cannot be changed. i.e. this code cannot simply be
+copied and put under another distribution licence
+[including the GNU Public Licence.]
+
+#endif
+
+$!end
+};
+
+
+
+/** Constant texts used by program, not localized.
+*/
+static const dkChar * const dk_ls_kwnl[] = {
+$!string-table macro=dkT
+#
+# 0 Program group name
+#
+dktools
+#
+# 1 Help text file name
+#
+dk-ls.txt
+#
+# 2 String table file
+#
+dk-ls.str
+#
+# 3 Default set of information to show
+# (type, permissions, modification time, size, name)
+#
+mtpn
+#
+# 4 Current directory
+#
+.
+#
+# 5 Path component separator on Windows
+#
+\\
+#
+# 6 Path component separator on non-Windows
+#
+/
+#
+# 7 String between link and target
+#
+ ->
+#
+# 8 Default print order for Windows
+#
+mtn
+#
+# 9 Preference name for message digest
+#
+message.digest
+#
+# 10 Preference name for print order
+#
+print.order
+#
+# 11 Error message: Application startup failed!
+#
+ERROR: Application startup failed!\n
+$!end
+};
+
+
+
+/** Constant texts used by program, replaced by localized texts
+ if available.
+*/
+static const dkChar * const dk_ls_kw_def[] = {
+$!string-table macro=dkT
+#
+# 0 Error message: Failed to set up signal handlers!
+#
+Failed to set up signal handlers!
+#
+# 1 Error message: Failed to restore previous signal handlers!
+#
+Failed to restore previous signal handlers!
+#
+# 2 Text "OVERFLOW" to show instead of the size
+#
+OVERFLOW
+#
+# 3 4 5 Failed to retrieve file size information.
+#
+Failed to obtain file size for symbolic link:\n\t"
+Failed to obtain file size for target:\n\t"
+"!\n\tInformation not available!
+#
+# 6 Path grows too long
+#
+Path grows too long while recursing directory!
+#
+# 7 8 9 Failed to obtain timestamp!
+#
+Failed to obtain timestamp for symbolic link:\n\t"
+Failed to obtain timestamp for target:\n\t"
+"!\nInformation not available!
+#
+# 10
+#
+Failed to obtain file type and attributes (bug)!
+#
+# 11
+#
+Invalid text in print order!
+#
+# 12 13 Failed to find target for symbolic link!
+#
+Failed to find target for symbolic link:\n\t"
+"!
+#
+# 14 15 Failed to find unique file identifier
+#
+Failed to obtain unique file identifier:\n\t"
+"!
+#
+# 16 17 18 File names too long in summary.
+#
+File names too long for expansion:\n\t"
+",\n\t"
+"!
+#
+# 19 Message digest type not supported!
+#
+Message digest type not supported!
+#
+# 20 21 Message digest type not supported!
+#
+Message digest type not supported: "
+"!
+#
+# 22 23 Not a message digest type name!
+#
+Not a message digest type name: "
+"!
+#
+# 24 25 Invalid encoding for message digest!
+#
+Invalid encoding for message digest: "
+"!
+#
+# 26 Error message: Failed to init digest ctx
+#
+Failed to initialize digest context (error from library function)!
+#
+# 27 Error message: Failed to init message digest ctx
+#
+Failed to initialize message digest context!
+#
+# 28 Error message: Failed to add bytes to ctx
+#
+Failed to add data to message digest!
+#
+# 29 Error message: Failed to finish message digest
+#
+Failed to finish message digest!
+#
+# 30, 31, 32
+#
+\# Number of directories:
+\# Number of files:
+\# Total number of bytes:
+$!end
+};
+
+
+
+#if DK4_ON_WINDOWS
+/** Buffer to store symbolic link destination.
+*/
+static dkChar dk_ls_sl_target[32784];
+#else
+/** Buffer to store symbolic link destination.
+*/
+static dkChar dk_ls_sl_target[DK4_MAX_PATH];
+#endif
+
+
+
+/** Options used by program.
+*/
+static const dk4_option_specification_t dk_ls_options[] = {
+
+ /* Reset (ignore preferences).
+ */
+ { dkT('R'), dkT("reset"), DK4_OPT_ARG_NONE },
+
+ /* Print order.
+ */
+ { dkT('p'), dkT("print-order"), DK4_OPT_ARG_STRING },
+
+ /* Recursive listing.
+ */
+ { dkT('r'), dkT("recursive"), DK4_OPT_ARG_NONE },
+
+ /* For recursive listings, stay on the current file system.
+ */
+ { dkT('f'), dkT("stay-on-filesystem"), DK4_OPT_ARG_NONE },
+
+ /* File types to show (all others are ignored).
+ */
+ { dkT('t'), dkT("types"), DK4_OPT_ARG_STRING },
+
+ { dkT('s'), dkT("summary"), DK4_OPT_ARG_NONE },
+
+#if DK4_HAVE_OPENSSL_MD5_H && DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_OPENSSL_RIPEMD_H
+ { dkT('m'), dkT("message-digest"), DK4_OPT_ARG_STRING },
+#endif
+};
+
+
+
+/** Buffer for print order from command line.
+*/
+static dkChar po_buf[32];
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Print order.
+*/
+static const dkChar *print_order = NULL;
+
+
+/** Message texts, uses localized texts if possible.
+*/
+static const dkChar * const *dk_ls_msg = dk_ls_kw_def;
+
+
+/** Error report for bytes counting.
+*/
+static dk4_er_t er_bytes;
+
+
+/** Error report for files counting.
+*/
+static dk4_er_t er_files;
+
+
+/** Error report for directory counting.
+*/
+static dk4_er_t er_dirs;
+
+
+
+/** Size found so far.
+*/
+static dk4_um_t size_bytes = (dk4_um_t)0UL;
+
+
+
+/** Number of files shown.
+*/
+static dk4_um_t num_files = (dk4_um_t)0UL;
+
+
+
+/** Number of directories shown.
+*/
+static dk4_um_t num_dirs = (dk4_um_t)0UL;
+
+
+
+
+/** Number of elements in the dk_ls_kw_def array and in dk_ls_msg.
+*/
+static size_t dk_ls_sz_msg =
+(sizeof(dk_ls_kw_def)/sizeof(DK4_PDKCHAR) - 1);
+
+
+
+#if DK4_ON_WINDOWS
+/** Limit for incrementing path construction buffer.
+ On Windows systems a special notation allows very long path names
+ up to 32767 characters.
+*/
+static const size_t dk_ls_max_path = 32784U;
+#else
+/** Limit for incrementing path construction buffer.
+ On non-Windows systems the path is restricted to DK4_MAX_PATH.
+*/
+static const size_t dk_ls_max_path = 2 * DK4_MAX_PATH;
+#endif
+
+
+
+/** Number of elements in the dk_ls_options array.
+*/
+static const size_t dk_ls_sz_options =
+sizeof(dk_ls_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Flag: Size output wanted.
+*/
+static int size_wanted = 0;
+
+
+
+/** Flag: Name output wanted.
+*/
+static int name_wanted = 0;
+
+
+
+/** Flag: Show non-directories.
+*/
+static int show_files = 1;
+
+
+
+/** Flag: Show directories.
+*/
+static int show_dirs = 1;
+
+
+
+/** Flag: Recursive listing.
+*/
+static int recursive = 0;
+
+
+
+/** Flag: Show summary.
+*/
+static int show_summary = 0;
+
+
+
+/** Flag: Stay on file system when recursing directories.
+*/
+static int stay_on_fs = 0;
+
+
+
+/** Message digest type.
+*/
+static int digest_type = DK4_MD_SHA1;
+
+
+
+/** Message digest encoding.
+*/
+static int digest_enco = DK4_BINARY_TO_TEXT_ENCODING_HEX;
+
+
+
+/** Flag: Unsupported digest type already reported.
+*/
+static int digest_erep = 0;
+
+
+
+/** Flag: Write error occured while writing to standard output.
+*/
+static int write_error = 0;
+
+
+
+/** Exit status code.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+/** Flag: Illegal characters in print order reported.
+*/
+static int print_order_error_reported = 0;
+
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+/** Pass a volatile pointer to an atomic integer.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ptr Address of atomic integer variable.
+ @return The unmodified pointer.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+/** Check whether we can continue or if a signal was received.
+ @param check_pipe Flag: Check for occured SIGPIPE signal too.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(int check_pipe)
+{
+ int back = 1;
+#ifdef SIGPIPE
+ if (0 != check_pipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_int )) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+/** Check whether we can continue.
+ @return 1 for yes, 0 for no.
+*/
+static
+int
+dk_ls_can_continue(void)
+{
+ int back = 1;
+ if (0 == sig_can_continue(1)) {
+ back = 0;
+ }
+ return back;
+}
+
+
+
+/** Node type for a directory.
+*/
+typedef struct _dk_ls_node_t_ {
+ struct _dk_ls_node_t_ *parent; /**< Pointer to parent node. */
+ struct _dk_ls_node_t_ *child; /**< Pointer to current child. */
+ dk4_dir_t *dirptr; /**< Directory. */
+ dk4_file_info_t fi; /**< File information. */
+ dk4_um_t size; /**< Directory size. */
+ int level; /**< Processing level. */
+ int ovsize; /**< Flag: Overflow in size calc. */
+} dk_ls_node_t;
+
+
+
+/** Destroy node object, release memory.
+ @param cn Node to destroy.
+*/
+static
+void
+dk_ls_delete_node(dk_ls_node_t *cn)
+{
+ $? "+ dk_ls_delete_node"
+ if (NULL != cn) {
+ cn->parent = NULL;
+ cn->child = NULL;
+ if (NULL != cn->dirptr) {
+ dk4dir_close(cn->dirptr);
+ }
+ cn->dirptr = NULL;
+ dk4mem_free(cn);
+ } $? "- dk_ls_delete_node"
+}
+
+
+
+/** Create new new directory node.
+ @param dn Directory name for node.
+ @param pa Parent node.
+ @param level Processing level.
+ @return Pointer to new node on success, NULL on error.
+*/
+static
+dk_ls_node_t *
+dk_ls_new_node(const dkChar *dn, dk_ls_node_t *pa, int level)
+{
+ dk4_er_t er;
+ dk_ls_node_t *back = NULL;
+ int om = DK4_DIR_OPEN_SORTED;
+ int ch = DK4_FILE_INFO_CONTENTS_DATA_TARGET;
+ $? "+ dk_ls_new_node \"%!ds\" PTR=%d", TR_STR(dn), TR_IPTR(pa)
+ back = dk4mem_new_app(dk_ls_node_t,1,app);
+ if (NULL != back) {
+ DK4_MEMRES(back, sizeof(dk_ls_node_t));
+ back->parent = pa;
+ back->child = NULL;
+ back->dirptr = NULL;
+ back->level = level;
+ back->size = (dk4_um_t)0UL;
+ back->ovsize = 0;
+ if (3 < back->level) { back->level = 3; }
+ om |= DK4_DIR_SYMLINK_DIR_AS_FILE;
+ dk4error_init(&er);
+ back->dirptr = dk4dir_open_app(dn, om, app);
+ if (NULL == back->dirptr) { $? "! back->dirptr"
+ exval = EXIT_FAILURE;
+ dk_ls_delete_node(back);
+ back = NULL;
+ }
+ if (NULL != back) { $? ". node ok, retrieve file info"
+ dk4fileinfo_init(&(back->fi));
+ if (0 != dk4fileinfo_app(&(back->fi), dn, app)) {
+ if (0 == dk4fileinfo_size(&(back->size), &(back->fi), ch, NULL)) {
+ back->size = (dk4_um_t)0UL; $? "! file size"
+ /* ERROR: Failed to retrieve directory size */
+ dk_ls_report_fileinfo_size_error(app,dn,ch,dk_ls_msg,dk_ls_sz_msg);
+ exval = EXIT_FAILURE;
+ }
+ } else { $? "! fileinfo"
+ /* ERROR: Failed to retrieve file information, already reported */
+ exval = EXIT_FAILURE;
+ }
+ } else { $? "! directory"
+ /* ERROR: Failed to open directory, already reported */
+ exval = EXIT_FAILURE;
+ }
+ } else { $? "! allocation"
+ /* ERROR: Allocation failed, already reported */
+ exval = EXIT_FAILURE;
+ }
+ $? "- dk_ls_new_node PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/** Construct a path name consisting of directory and
+ file or subdirectory name into an existing buffer.
+ @param bufptr Buffer address.
+ @param szbuf Size of buffer.
+ @param dirname Leading part of path name.
+ @param filename Trailing part of path name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error (buffer too short).
+*/
+static
+int
+dk_ls_dir_and_file(
+ dkChar *bufptr,
+ size_t szbuf,
+ const dkChar *dirname,
+ const dkChar *filename
+)
+{
+ int back = 0;
+ int nsep = 1; /* Flag: Separator needed */
+ $? "+ dk_ls_dir_and_file \"%!ds\" \"%!ds\"", TR_STR(dirname), TR_STR(filename)
+ if (NULL != dirname) {
+ if (0 != dk4str_cpy_s(bufptr, szbuf, dirname, NULL)) {
+ while(dkT('\0') != *dirname) {
+#if DK4_ON_WINDOWS
+ if (dkT('\\') == *dirname)
+#else
+ if (dkT('/') == *dirname)
+#endif
+ {
+ nsep = 0;
+ } else {
+ nsep = 1;
+ }
+ dirname++;
+ }
+ if (0 != nsep) {
+#if DK4_ON_WINDOWS
+ if (0 != dk4str_cat_s(bufptr, szbuf, dk_ls_kwnl[5], NULL))
+#else
+ if (0 != dk4str_cat_s(bufptr, szbuf, dk_ls_kwnl[6], NULL))
+#endif
+ {
+ back = 1;
+ }
+ } else {
+ back = 1;
+ }
+ if (0 != back) {
+ back = 0;
+ if (0 != dk4str_cat_s(bufptr, szbuf, filename, NULL)) {
+ back = 1;
+ } else { $? "! BUG: Buffer too small"
+ /* BUG: Buffer too small */
+ exval = EXIT_FAILURE;
+ }
+ } else { $? "! BUG: Buffer too small"
+ /* BUG: Buffer too small */
+ exval = EXIT_FAILURE;
+ }
+ } else { $? "! BUG: Buffer too small"
+ /* BUG: Buffer too small */
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ back = dk4str_cpy_s(bufptr, szbuf, filename, NULL);
+ if (0 == back) { $? "! BUG: Buffer too small"
+ /* BUG: Buffer too small */
+ exval = EXIT_FAILURE;
+ }
+ } $? "- dk_ls_dir_and_file %d", back
+ return back;
+}
+
+
+
+/** Construct a file or directory name, resize buffer if
+ necessary.
+ @param bufptr Address of pointer to buffer.
+ @param szbufptr Address of buffer size variable.
+ @param dirname Directory part of path to construct.
+ @param filename File name part of path to construct.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk_ls_construct_path(
+ dkChar **bufptr,
+ size_t *szbufptr,
+ const dkChar *dirname,
+ const dkChar *filename
+)
+{
+ dk4_er_t er; /* Error code */
+ dkChar *nb; /* New buffer */
+ size_t lgt; /* Required buffer size */
+ int back = 0;
+ $? "+ dk_ls_construct_path \"%!ds\" \"%!ds\"",TR_STR(dirname),TR_STR(filename)
+ dk4error_init(&er);
+ lgt = dk4str_len(filename);
+ if (NULL != dirname) {
+ lgt = dk4ma_size_t_add(lgt, dk4str_len(dirname), &er);
+ lgt = dk4ma_size_t_add(lgt, 2, &er);
+ }
+ if (DK4_E_NONE == er.ec) {
+ if (lgt <= *szbufptr) {
+ /*
+ Keep current buffer.
+ */
+ $? ". can keep current buffer"
+ back = dk_ls_dir_and_file(*bufptr, *szbufptr, dirname, filename);
+ } else {
+ if (dk_ls_max_path > lgt) {
+ /*
+ Allocate new larger buffer.
+ */
+ $? ". need new buffer"
+ nb = dk4mem_new_app(dkChar, lgt, app);
+ if (NULL != nb) { $? ". allocation"
+ dk4mem_release(*bufptr);
+ *bufptr = nb;
+ *szbufptr = lgt;
+ back = dk_ls_dir_and_file(*bufptr, *szbufptr, dirname, filename);
+ } else { $? "! allocation"
+ /* ERROR: Memory allocation failed, already reported */
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Path size too long */
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 6);
+ exval = EXIT_FAILURE;
+ }
+ }
+ } else {
+ /* ERROR: Overflow in size calculation */
+ dk4app_log_base1(app, DK4_LL_ERROR, 82);
+ exval = EXIT_FAILURE;
+ }
+ $? "- dk_ls_construct_path %d", back
+ return back;
+}
+
+
+
+static
+void
+dk_ls_write_decimal_number(dk4_um_t value, size_t width)
+{
+ dkChar buf[16 + 8 * sizeof(dk4_um_t)];
+ dk4_er_t er;
+ size_t sl;
+ int res;
+ dk4error_init(&er);
+ res = dk4ma_write_decimal_unsigned(
+ buf, DK4_SIZEOF(buf,dkChar), value, 0, &er
+ );
+ if (0 != res) {
+ sl = dk4str_len(buf);
+ while (sl++ < width) {
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ if (0 == dk4fputs(buf, stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ } else { $? "! BUG: Failed to write decimal to buffer"
+ /* ERROR: Failed to write decimal number to buffer (bug) */
+ exval = EXIT_FAILURE;
+ }
+}
+
+
+
+static
+void
+dk_ls_write_hexadecimal_number(dk4_um_t value, size_t width)
+{
+ dkChar buf[16 + 8 * sizeof(dk4_um_t)];
+ dk4_er_t er;
+ size_t sl;
+ int res;
+ $? "+ dk_ls_write_hexadecimal_number"
+ dk4error_init(&er);
+ res = dk4ma_write_hex_unsigned(
+ buf, DK4_SIZEOF(buf,dkChar), value, width, &er
+ );
+ if (0 != res) { $? ". string created"
+ sl = dk4str_len(buf);
+ while (sl++ < width) { $? ". fill text"
+ if (0 == dk4fputc(dkT('0'), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ if (0 == dk4fputs(buf, stdout, NULL)) { $? "! dk4fputs"
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ } else { $? "! dk4ma_write_hex_unsigned"
+ /* BUG: Failed to write hexadecimal number to buffer */
+ exval = EXIT_FAILURE;
+ }
+ $? "- dk_ls_write_hexadecimal_number"
+}
+
+
+
+/** Write file timestamp.
+ @param fiptr File information.
+ @param fn File name.
+ @param what Choose the timestamp.
+ @param issl Flag: Object is symbolic link.
+*/
+static
+void
+dk_ls_write_timestamp(
+ dk4_file_info_t *fiptr, const dkChar *fn, int what, int issl
+)
+{
+ dk4_er_t er;
+ dkChar buf[64];
+ int ch;
+ int res;
+
+ dk4error_init(&er);
+ ch = (
+ (0 != issl)
+ ? DK4_FILE_INFO_CONTENTS_DATA_LINK
+ : DK4_FILE_INFO_CONTENTS_DATA_TARGET
+ );
+ res = dk4fileinfo_timestamp(buf,DK4_SIZEOF(buf,dkChar),fiptr,ch,what,&er);
+ if (0 != res) {
+ if (0 == dk4fputs(buf, stdout, &er)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERRROR: Failed to obtain time */
+ dk_ls_report_fileinfo_timestamp_error(
+ app, fn, ch, dk_ls_msg, dk_ls_sz_msg
+ );
+ exval = EXIT_FAILURE;
+ }
+}
+
+
+
+/** Write indicator for unkown data.
+ @param width Field width.
+ @param compl Fill complete field.
+*/
+static
+void
+dk_ls_write_unknown(size_t width, int compl)
+{
+ if (0 != compl) {
+ while (0 < width--) {
+ if (0 == dk4fputc(dkT('?'), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ } else {
+ while (1 < width--) {
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ if (0 == dk4fputc(dkT('?'), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+}
+
+
+
+static
+int
+dk_ls_can_create_md(const dkChar *fn, dk4_file_info_t *fiptr)
+{
+ int back = 0;
+ if (0 == dk4fileinfo_is_symlink(fiptr)) {
+#if DK4_ON_WINDOWS
+ if (0 == (FILE_ATTRIBUTE_REPARSE_POINT & (fiptr->fattr))) {
+ if (0 == (FILE_ATTRIBUTE_DIRECTORY & (fiptr->fattr))) {
+ if (0 == (FILE_ATTRIBUTE_DEVICE & (fiptr->fattr))) {
+ back = 1;
+ }
+ }
+ }
+#else
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & (fiptr->contents))) {
+ if (S_IFREG == (S_IFMT & ((fiptr->tstb).st_mode))) {
+ back = 1;
+ }
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+/** Write message digest.
+ @param fn File name.
+ @param fiptr File information pointer.
+ @param digest_type Message digest type.
+ @param digest_enco Message digest encoding.
+ @param app Application structure for diagnostics.
+ @param dk_ls_msg Message texts array.
+ @param dk_ls_sz_msg Size of message texts error.
+*/
+static
+void
+dk_ls_write_md(
+ const dkChar *fn,
+ dk4_file_info_t *fiptr,
+ int digest_type,
+ int digest_enco,
+ dk4_app_t *app,
+ const dkChar * const *dk_ls_msg,
+ size_t dk_ls_sz_msg
+)
+{
+ char buf[4096]; /* Buffer to read file */
+ dk4_md_ctx_t ctx; /* Message digest context */
+ dk4_er_t er; /* Error report */
+ FILE *fipo; /* Input file to process */
+ const char *resptr; /* Pointer to encoded digest buffer */
+ size_t rdbytes; /* Number of bytes read */
+ int mdok = 0; /* Flag: Digesting ok so far */
+ if (0 != dk_ls_can_create_md(fn, fiptr)) { $? ". can create md"
+ dk4error_init(&er);
+ if (0 != dk4md_ctx_init(&ctx, digest_type, digest_enco, &er)) {
+ $? ". ctx initialized"
+ fipo = dk4fopen_app(fn, dkT("rb"), DK4_FOPEN_SC_IS_REGULAR, app);
+ if (NULL != fipo) { $? ". file opened"
+ mdok = 1;
+ do {
+ if (0 != dk_ls_can_continue()) {
+ rdbytes = fread(buf, 1, sizeof(buf), fipo);
+ if (0 < rdbytes) { $? ". bytes found"
+ dk4error_init(&er);
+ if (1 != dk4md_ctx_add(&ctx, buf, rdbytes, &er)) {
+ mdok = 0; $? "! ctx add"
+ /* ERROR: Digest failed */
+ switch (er.ec) {
+ case DK4_E_NOT_SUPPORTED : {
+ dk4app_log_1(app,dk_ls_msg,dk_ls_sz_msg,DK4_LL_ERROR,19);
+ } break;
+ default : {
+ dk4app_log_1(app,dk_ls_msg,dk_ls_sz_msg,DK4_LL_ERROR,28);
+ } break;
+ }
+ }
+ }
+ } else {
+ mdok = 0;
+ rdbytes = 0;
+ }
+ } while((0 < rdbytes) && (1 == mdok));
+ fclose(fipo);
+ if (1 == mdok) { $? ". mdok"
+ resptr = NULL; rdbytes = 0;
+ dk4error_init(&er);
+ if (1 == dk4md_ctx_finish(&resptr, &rdbytes, &ctx, &er)) {
+ $? ". ctx finished"
+ if ((NULL != resptr) && (0 < rdbytes)) { $? ". results"
+ while(rdbytes--) {
+ if (0 == dk4fputc((dkChar)(*(resptr++)), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE; $? "! write error"
+ }
+ }
+ } else { $? "! results"
+ mdok = 0;
+ /* ERROR: No digest obtained */
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 29);
+ }
+ } else { $? "! ctx finish"
+ mdok = 0;
+ /* ERROR: Failed to obtain digest */
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 29);
+ }
+ } else { $? "! mdok"
+ }
+ } else { $? "! fopen"
+ /* ERROR: Failed to open file, already reported */
+ }
+ } else { $? "! ctx init"
+ /* ERROR: Failed to initialize digest ctx */
+ switch (er.ec) {
+ case DK4_E_NOT_SUPPORTED : {
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 19);
+ } break;
+ case DK4_E_SYSTEM : {
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 26);
+ } break;
+ default : {
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 27);
+ } break;
+ }
+ }
+ } else { $? ". do not create md"
+ }
+ if (0 == mdok) {
+ rdbytes = dk4md_size(digest_type, digest_enco, NULL);
+ while (rdbytes--) {
+ if (0 == dk4fputc(dkT('x'), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ }
+}
+
+
+/** Write information about file to standard output.
+ @param fn File name.
+ @param fiptr File information.
+ @param use_size Flag: Use specified size.
+ @param size Size to use.
+ @param ovsize Flag: Numeric overflow in size calculation.
+*/
+static
+void
+dk_ls_process_item_information(
+ const dkChar *fn,
+ dk4_file_info_t *fiptr,
+ int use_size,
+ dk4_um_t size,
+ int ovsize
+)
+{
+ dkChar abuf[8*sizeof(dk4_um_t) + 16]; /* Attributes */
+ dkChar buf[8*sizeof(dk4_um_t) + 16]; /* Numbers */
+ dk4_er_t er; /* Error report */
+ const dkChar *piptr; /* Print order */
+ dk4_um_t fs; /* File size */
+ size_t numl; /* Number length */
+ size_t slen; /* String length */
+ size_t tlen; /* First part length */
+ size_t i; /* Index variable */
+ int issl; /* Flag: Is symbolic link */
+ int res; /* Result from information retrieval */
+ int showi; /* Flag: Show this item */
+ int habuf; /* Flag: Data in abuf */
+ int last_was_n; /* Flag: n was last character */
+ dkChar lasti; /* Last information printed */
+ $? "+ dk_ls_process_item_information \"%!ds\" PTR=%d", TR_STR(fn), TR_IPTR(fiptr)
+ last_was_n = habuf = 0;
+ if ((NULL != fn) && (NULL != fiptr)) { $? ". args ok"
+ showi = 1;
+ res = dk4fileinfo_type_attributes(
+ buf, DK4_SIZEOF(buf,dkChar), fiptr, &er
+ );
+ if (0 != res) {
+ showi = 0;
+ if (dkT('d') == buf[1]) {
+ if (0 != show_dirs) {
+ showi = 1;
+ if (0 != show_summary) {
+ num_dirs = dk4ma_um_add(num_dirs, 1, &er_dirs);
+ }
+ }
+ } else {
+ if (0 != show_files) {
+ showi = 1;
+ if (0 != show_summary) {
+ num_files = dk4ma_um_add(num_files, 1, &er_files);
+ }
+ }
+ }
+ } else { $? "! BUG: Failed to write attributes to buffer"
+ /* BUG: Failed to write file attributes to buffer */
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 10);
+ exval = EXIT_FAILURE;
+ }
+ if (0 != showi) { $? ". show file details"
+ issl = dk4fileinfo_is_symlink(fiptr);
+ lasti = dkT('\0');
+ piptr = print_order;
+ while (dkT('\0') != *piptr) { $? ". piptr %!dc", *piptr
+ last_was_n = 0;
+ if ((int)(*piptr) <= 255) { $? ". ok"
+ switch ((char)(*piptr)) {
+ case 'n' : { $? ". name"
+ if (dkT('\0') != lasti) {
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ if (0 == dk4fputs(fn, stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ last_was_n = 1;
+ } break;
+ case 'N' : { $? ". name"
+ if (dkT('\0') != lasti) {
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ if (0 == dk4fputs(fn, stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ } break;
+ case 's' : { $? ". size"
+ if (dkT('\0') != lasti) {
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ res = 0;
+ if (0 != use_size) {
+ if (0 != ovsize) {
+ /* Show Overflow */
+ dk4error_set_simple_error_code(&er_bytes, DK4_E_MATH_OVERFLOW);
+ slen = dk4str_len(dk_ls_msg[2]);
+ numl = dk4numlength(sizeof(dk4_um_t), 0);
+ tlen = (numl - slen) / 2;
+ for (i = 0; i < tlen; i++) {
+ if (0 == dk4fputc(dkT('-'), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ if (0 == dk4fputs(dk_ls_msg[2], stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ for (i = (tlen + slen); i < numl; i++) {
+ if (0 == dk4fputc(dkT('-'), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ } else {
+ /* Show size */
+ fs = size;
+ res = 1;
+ }
+ } else {
+ dk4error_init(&er);
+ res = dk4fileinfo_size(
+ &fs, fiptr,
+ (
+ (0 != issl)
+ ? (DK4_FILE_INFO_CONTENTS_DATA_LINK)
+ : (DK4_FILE_INFO_CONTENTS_DATA_TARGET)
+ ),
+ &er
+ );
+ if (0 == res) {
+ /* ERROR: Failed to obtain size */
+ $? "! file size"
+ dk_ls_report_fileinfo_size_error(
+ app, fn,
+ (
+ (0 != issl)
+ ? (DK4_FILE_INFO_CONTENTS_DATA_LINK)
+ : (DK4_FILE_INFO_CONTENTS_DATA_TARGET)
+ ),
+ dk_ls_msg, dk_ls_sz_msg
+ );
+ }
+ }
+ if (0 != res) {
+ numl = dk4numlength(sizeof(dk4_um_t), 0);
+ dk_ls_write_decimal_number(fs, numl);
+ if (0 != show_summary) {
+ size_bytes = dk4ma_um_add(size_bytes, fs, &er_bytes);
+ }
+ }
+ } break;
+ case 't' : { $? ". type, permissions"
+ dk4error_init(&er);
+ if (0 == habuf) {
+ habuf = dk4fileinfo_type_attributes(
+ abuf, DK4_SIZEOF(abuf,dkChar), fiptr, &er
+ );
+ }
+ if (0 != habuf) {
+ if (dkT('\0') != lasti) {
+ if (0 == dk4fputc(dkT(' '), stdout, &er)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ if (0 == dk4fputc(abuf[0], stdout, &er)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ if (0 == dk4fputc(abuf[1], stdout, &er)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Failed to obtain file type */
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 10);
+ }
+ } break;
+ case 'p' : {
+ if (0 == habuf) {
+ habuf = dk4fileinfo_type_attributes(
+ abuf, DK4_SIZEOF(abuf,dkChar), fiptr, &er
+ );
+ }
+ if (0 != habuf) {
+ if ((dkT('\0') != lasti) && (dkT('t') != lasti)) {
+ if (0 == dk4fputc(dkT(' '), stdout, &er)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ if (0 == dk4fputs(&(abuf[2]), stdout, &er)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Failed to obtain file type */
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 10);
+ }
+ } break;
+ case 'l' : { $? ". number of links"
+ fs = (dk4_um_t)1UL;
+ if (0 != issl) {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & fiptr->contents))
+ {
+#if DK4_ON_WINDOWS
+ fs = (dk4_um_t)((fiptr->linfo).nNumberOfLinks);
+#else
+ fs = (dk4_um_t)((fiptr->lstb).st_nlink);
+#endif
+ }
+ } else {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & fiptr->contents))
+ {
+#if DK4_ON_WINDOWS
+ fs = (dk4_um_t)((fiptr->tinfo).nNumberOfLinks);
+#else
+ fs = (dk4_um_t)((fiptr->tstb).st_nlink);
+#endif
+ }
+ }
+#if DK4_ON_WINDOWS
+ if ((DWORD)0UL == fiptr->resio) {
+#endif
+ dk_ls_write_decimal_number(
+ fs,
+#if DK4_ON_WINDOWS
+ dk4numlength(sizeof(DWORD), 0)
+#else
+ dk4numlength(sizeof(nlink_t), 0)
+#endif
+ );
+#if DK4_ON_WINDOWS
+ } else {
+ slen = dk4numlength(sizeof(DWORD), 0);
+ for (i = 1; i < slen; i++) {
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ if (0 == dk4fputc(dkT('?'), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+#endif
+ } break;
+ case 'c' : { $? ". creation timestamp"
+ if (dkT('\0') != lasti) {
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ dk_ls_write_timestamp(fiptr, fn, DK4_FILE_INFO_TIME_CREATE, issl);
+ } break;
+ case 'm' : { $? ". modification timestamp"
+ if (dkT('\0') != lasti) {
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ dk_ls_write_timestamp(fiptr, fn, DK4_FILE_INFO_TIME_MODIFY, issl);
+ } break;
+ case 'a' : { $? ". access timestamp"
+ if (dkT('\0') != lasti) {
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ dk_ls_write_timestamp(fiptr, fn, DK4_FILE_INFO_TIME_ACCESS, issl);
+ } break;
+#if !DK4_ON_WINDOWS
+ case 'u' : { $? ". owner UID"
+ if (dkT('\0') != lasti) {
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ if (0 != issl) {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & fiptr->contents))
+ {
+ dk_ls_write_decimal_number(
+ (fiptr->lstb).st_uid,
+ dk4numlength(sizeof(uid_t), 0)
+ );
+ }
+ else
+ {
+ dk_ls_write_unknown(dk4numlength(sizeof(uid_t), 0), 0);
+ }
+ } else {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & fiptr->contents))
+ {
+ dk_ls_write_decimal_number(
+ (fiptr->tstb).st_uid,
+ dk4numlength(sizeof(uid_t), 0)
+ );
+ }
+ else
+ {
+ dk_ls_write_unknown(dk4numlength(sizeof(uid_t), 0), 0);
+ }
+ }
+ } break;
+#endif
+#if !DK4_ON_WINDOWS
+ case 'g' : { $? ". owner GID"
+ if (dkT('\0') != lasti) {
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ if (0 != issl) {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & fiptr->contents))
+ {
+ dk_ls_write_decimal_number(
+ (fiptr->lstb).st_gid,
+ dk4numlength(sizeof(gid_t), 0)
+ );
+ }
+ else
+ {
+ dk_ls_write_unknown(dk4numlength(sizeof(gid_t), 0), 0);
+ }
+ } else {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & fiptr->contents))
+ {
+ dk_ls_write_decimal_number(
+ (fiptr->tstb).st_gid,
+ dk4numlength(sizeof(gid_t), 0)
+ );
+ }
+ else
+ {
+ dk_ls_write_unknown(dk4numlength(sizeof(gid_t), 0), 0);
+ }
+ }
+ } break;
+#endif
+ case 'd' : { $? ". device number"
+ if (dkT('\0') != lasti) {
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+#if DK4_ON_WINDOWS
+ if (0 != issl) {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & fiptr->contents))
+ {
+ if ((DWORD)0UL == fiptr->resio) {
+ dk_ls_write_hexadecimal_number(
+ (fiptr->linfo).dwVolumeSerialNumber, 2*sizeof(DWORD)
+ );
+ } else {
+ dk_ls_write_unknown(2*sizeof(DWORD), 1);
+ }
+ }
+ else
+ {
+ dk_ls_write_unknown(2*sizeof(DWORD), 1);
+ }
+ } else {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & fiptr->contents))
+ {
+ if ((DWORD)0UL == fiptr->resio) {
+ dk_ls_write_hexadecimal_number(
+ (fiptr->tinfo).dwVolumeSerialNumber, 2*sizeof(DWORD)
+ );
+ } else {
+ dk_ls_write_unknown(2*sizeof(DWORD), 1);
+ }
+ }
+ else
+ {
+ dk_ls_write_unknown(2*sizeof(DWORD), 1);
+ }
+ }
+#else
+ if (0 != issl) {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & fiptr->contents))
+ {
+ dk_ls_write_hexadecimal_number(
+ (fiptr->lstb).st_dev, 2*sizeof(dev_t)
+ );
+ }
+ else
+ {
+ dk_ls_write_unknown(2*sizeof(dev_t), 1);
+ }
+ } else {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & fiptr->contents))
+ {
+ dk_ls_write_hexadecimal_number(
+ (fiptr->tstb).st_dev, 2*sizeof(dev_t)
+ );
+ }
+ else
+ {
+ dk_ls_write_unknown(2*sizeof(dev_t), 1);
+ }
+ }
+#endif
+ } break;
+ case 'r' : { $? ". relative device number"
+#if DK4_ON_WINDOWS
+ if (0 != issl) {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & fiptr->contents))
+ {
+ if ((DWORD)0UL == fiptr->resio) {
+ dk_ls_write_hexadecimal_number(
+ (fiptr->linfo).dwVolumeSerialNumber, 2*sizeof(DWORD)
+ );
+ } else {
+ dk_ls_write_unknown(2*sizeof(DWORD), 1);
+ }
+ }
+ else
+ {
+ dk_ls_write_unknown(2*sizeof(DWORD), 1);
+ }
+ } else {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & fiptr->contents))
+ {
+ if ((DWORD)0UL == fiptr->resio) {
+ dk_ls_write_hexadecimal_number(
+ (fiptr->tinfo).dwVolumeSerialNumber, 2*sizeof(DWORD)
+ );
+ } else {
+ dk_ls_write_unknown(2*sizeof(DWORD), 1);
+ }
+ }
+ else
+ {
+ dk_ls_write_unknown(2*sizeof(DWORD), 1);
+ }
+ }
+#else
+ if (0 != issl) {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & fiptr->contents))
+ {
+ dk_ls_write_hexadecimal_number(
+ (fiptr->lstb).st_rdev, 2*sizeof(dev_t)
+ );
+ }
+ else
+ {
+ dk_ls_write_unknown(2*sizeof(dev_t), 1);
+ }
+ } else {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & fiptr->contents))
+ {
+ dk_ls_write_hexadecimal_number(
+ (fiptr->tstb).st_rdev, 2*sizeof(dev_t)
+ );
+ }
+ else
+ {
+ dk_ls_write_unknown(2*sizeof(dev_t), 1);
+ }
+ }
+#endif
+ } break;
+ case 'i' : { $? ". inode number"
+ if (dkT('\0') != lasti) {
+ if (dkT('d') != lasti) {
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ } else {
+ if (0 == dk4fputc(dkT(':'), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ }
+#if DK4_ON_WINDOWS
+ if (0 != issl) {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & fiptr->contents))
+ {
+ if ((DWORD)0UL == fiptr->resio) {
+ dk_ls_write_hexadecimal_number(
+ (fiptr->linfo).nFileIndexHigh, 2*sizeof(DWORD)
+ );
+ dk_ls_write_hexadecimal_number(
+ (fiptr->linfo).nFileIndexLow, 2*sizeof(DWORD)
+ );
+ } else {
+ dk_ls_write_unknown(4*sizeof(DWORD), 1);
+ }
+ }
+ else
+ {
+ dk_ls_write_unknown(4*sizeof(DWORD), 1);
+ }
+ } else {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & fiptr->contents))
+ {
+ if ((DWORD)0UL == fiptr->resio) {
+ dk_ls_write_hexadecimal_number(
+ (fiptr->tinfo).nFileIndexHigh, 2*sizeof(DWORD)
+ );
+ dk_ls_write_hexadecimal_number(
+ (fiptr->tinfo).nFileIndexLow, 2*sizeof(DWORD)
+ );
+ } else {
+ dk_ls_write_unknown(4*sizeof(DWORD), 1);
+ }
+ }
+ else
+ {
+ dk_ls_write_unknown(4*sizeof(DWORD), 1);
+ }
+ }
+#else
+ if (0 != issl) {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & fiptr->contents))
+ {
+ dk_ls_write_hexadecimal_number(
+ (fiptr->lstb).st_ino, 2*sizeof(ino_t)
+ );
+ }
+ else
+ {
+ dk_ls_write_unknown(2*sizeof(ino_t), 1);
+ }
+ } else {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & fiptr->contents))
+ {
+ dk_ls_write_hexadecimal_number(
+ (fiptr->tstb).st_ino, 2*sizeof(ino_t)
+ );
+ }
+ else
+ {
+ dk_ls_write_unknown(2*sizeof(ino_t), 1);
+ }
+ }
+#endif
+ } break;
+#if DK4_ON_WINDOWS
+ case 'w' : { $? ". windows reparse point tag"
+ if (dkT('\0') != lasti) {
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ dk_ls_write_hexadecimal_number(
+ fiptr->rppnt, 2*sizeof(DWORD)
+ );
+ } break;
+#endif
+ case 'x' : {
+ if (0 != dk4md_check_type(digest_type)) {
+ if (dkT('\0') != lasti) {
+ if (0 == dk4fputc(dkT(' '), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ dk_ls_write_md(
+ fn, fiptr, digest_type, digest_enco, app,
+ dk_ls_msg, dk_ls_sz_msg
+ );
+ } else {
+ /* ERROR (once) Message digest type not supported */
+ if (0 == digest_erep) {
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 19);
+ digest_erep = 1;
+ }
+ }
+ } break;
+ default : {
+ /* ERROR (once): Invalid text in -p argument */
+ if (0 == print_order_error_reported) {
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 11);
+ print_order_error_reported = 1;
+ }
+ exval = EXIT_FAILURE;
+ } break;
+ }
+ } else {
+ /* ERROR (once): Invalid text in -p argument */
+ if (0 == print_order_error_reported) {
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 11);
+ print_order_error_reported = 1;
+ }
+ exval = EXIT_FAILURE;
+ }
+ lasti = *(piptr++);
+ }
+ if (0 != last_was_n) {
+ if (0 != dk4fileinfo_is_symlink(fiptr)) {
+ res = dk4symlink_target(
+ dk_ls_sl_target, DK4_SIZEOF(dk_ls_sl_target,dkChar), fn, NULL
+ );
+ if (0 != res) {
+ if (0 == dk4fputs(dk_ls_kwnl[7], stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ if (0 == dk4fputs(dk_ls_sl_target, stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Failed to find symlink target */
+ dk4app_log_3(app,dk_ls_msg,dk_ls_sz_msg,DK4_LL_ERROR,12,13,fn);
+ exval = EXIT_FAILURE;
+ }
+ }
+ }
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ } else { $? ". skipping file"
+ }
+ } else { $? "! args"
+ }
+ $? "- dk_ls_process_item_information"
+}
+
+
+
+/** Process non-directory file.
+ @param fn File name.
+ @param level Processing level (0=cmd line arg, 1=direct child,
+ 2 and above=further indicrect siblings).
+*/
+static
+void
+dk_ls_process_non_directory(const dkChar *fn, int level)
+{
+ dk4_file_info_t fili;
+
+ dk4fileinfo_init(&fili);
+ if (0 != dk4fileinfo_app(&fili, fn, app)) {
+ dk_ls_process_item_information(fn, &fili, 0, (dk4_um_t)0UL, 0);
+ } else {
+ /* ERROR: Failed to obtain information about file, already reported */
+ exval = EXIT_FAILURE;
+ }
+}
+
+
+
+/** Process one directory item.
+ @param dirnode Node for the items parent directory.
+ @param filename Path name for item.
+*/
+static
+void
+dk_ls_process_item_for_node(
+ dk_ls_node_t *dirnode,
+ const dkChar *filename
+)
+{
+ dk4_file_info_t fili;
+ dk4_er_t er;
+ dk4_um_t fs;
+ int ch = DK4_FILE_INFO_CONTENTS_DATA_TARGET;
+ $? "+ dk_ls_process_item_for_node PTR=%d \"%!ds\"", TR_IPTR(dirnode), filename
+ if ((0 >= dirnode->level) || (0 != recursive) || (0 != size_wanted))
+ {
+ dk4error_init(&er);
+ dk4fileinfo_init(&fili);
+ if (0 != dk4fileinfo_app(&fili, filename, app)) {
+ if (0 != dk4fileinfo_is_symlink(&fili)) {
+ ch = DK4_FILE_INFO_CONTENTS_DATA_LINK ;
+ }
+ if (0 != dk4fileinfo_size(&fs, &fili, ch, &er)) {
+ dirnode->size = dk4ma_um_add(dirnode->size, fs, &er);
+ if (DK4_E_MATH_OVERFLOW == er.ec) {
+ dirnode->ovsize = 1;
+ }
+ } else {
+ /* ERROR: Failed to retrieve size */
+ $? "! file size"
+ dk_ls_report_fileinfo_size_error(
+ app, filename, ch, dk_ls_msg, dk_ls_sz_msg
+ );
+ fs = (dk4_um_t)0UL;
+ exval = EXIT_FAILURE;
+ }
+ if ((0 >= dirnode->level ) || (0 != recursive)) {
+ /* Show file information */
+ dk_ls_process_item_information(
+ filename, &fili, 0, (dk4_um_t)0UL, 0
+ );
+ }
+ } else {
+ /* ERROR: Failed to obtain file information, already reported */
+ exval = EXIT_FAILURE;
+ }
+ }
+ $? "- dk_ls_process_item_for_node"
+}
+
+
+
+/** Process directory. Unless required otherwise by a non-zero
+ value for recursive, show contents and directory for level=0,
+ directory itself for level=1.
+ @param dn Directory name.
+ @param level Processing level (0=cmd line arg, 1=direct child,
+ 2 and above=further siblings).
+*/
+static
+void
+dk_ls_process_directory(const dkChar *dn, int level)
+{
+ dk4_ufi_t pdufi; /* UFI for parent directory */
+ dk4_ufi_t sdufi; /* UFI for sub directory */
+ dk4_er_t er; /* Error report for size addition */
+ dkChar *mybu; /* Buffer for path name construction */
+#if VERSION_BEFORE_20150821
+ dk_ls_node_t *rn; /* Root node */
+#endif
+ dk_ls_node_t *cn; /* Current node */
+ dk_ls_node_t *on; /* Other node */
+ const dkChar *pa; /* Directory path */
+ const dkChar *ndn; /* Next directory name */
+ size_t szmb; /* Size of mybu (number of dkChar) */
+ int gosub; /* Flag: Go into sub directory */
+ int ufich; /* Channel to retrieve UFI */
+ $? "+ dk_ls_process_directory \"%!ds\" %d", dn, level
+ /*
+ Allocate path name construction buffer.
+ */
+ ufich = DK4_FILE_INFO_CONTENTS_DATA_TARGET;
+ szmb = DK4_MAX_PATH;
+ mybu = dk4mem_new_app(dkChar,szmb,app);
+ /*
+ If path name construction buffer available, run normally.
+ */
+ if (NULL != mybu) {
+#if VERSION_BEFORE_20150821
+ rn = cn = dk_ls_new_node(dn, NULL, level);
+#else
+ cn = dk_ls_new_node(dn, NULL, level);
+#endif
+ while (NULL != cn) { $? ". still dir to process"
+ if (0 != dk_ls_can_continue()) { $? ". can continue"
+ ndn = dk4dir_next_dir(cn->dirptr);
+ if (NULL != ndn) {
+ /*
+ Handle sub directory.
+ */
+ pa = dk4dir_get_path(cn->dirptr);
+ if (0 != dk_ls_construct_path(&mybu, &szmb, pa, ndn)) {
+ /*
+ Decide whether or not to go into subdirectory
+ */
+ gosub = 0;
+#if 0
+ /* 2015-04-14
+ There is no reason to open a node for the subdirectory
+ unless recursive output or size calculation is wanted.
+ */
+ if (0 == cn->level) { /* Processing cmd line argument */
+ gosub = 1;
+ }
+#endif
+ if (0 != recursive) { /* Recursive output wanted */
+ gosub = 1;
+ }
+ if (0 != size_wanted) { /* Size calculation required */
+ if (0 != show_dirs) { /* ... and directory information wanted */
+ gosub = 1;
+ }
+ }
+ if (0 != gosub) {
+ if (0 != dk4ufi_get(&sdufi, mybu, NULL)) {
+ if (0 != stay_on_fs) { /* Check for same filesystem */
+ if (0 != dk4fileinfo_ufi(&pdufi, &(cn->fi), ufich, NULL)) {
+#if DK4_ON_WINDOWS
+ if (pdufi.ser != sdufi.ser) {
+ gosub = 0;
+ }
+#else
+ if (pdufi.dev != sdufi.dev) {
+ gosub = 0;
+ }
+#endif
+ } else {
+ /* ERROR: Failed to obtain file identifier */
+ dk4app_log_3(
+ app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 14, 15,
+ dk4dir_get_path(cn->dirptr)
+ );
+ gosub = 0;
+ exval = EXIT_FAILURE;
+ }
+ }
+ if (0 != gosub) { /* Check for symlink loop */
+ on = cn;
+ while ((0 != gosub) && (NULL != on)) {
+ if (0 != dk4fileinfo_ufi(&pdufi, &(on->fi), ufich, NULL)) {
+#if DK4_ON_WINDOWS
+ if (pdufi.ser == sdufi.ser) {
+ if (pdufi.inh == sdufi.inh) {
+ if (pdufi.inl == sdufi.inl) {
+ gosub = 0;
+ }
+ }
+ }
+#else
+ if (pdufi.dev == sdufi.dev) {
+ if (pdufi.ino == sdufi.ino) {
+ gosub = 0;
+ }
+ }
+#endif
+ } else {
+ /* ERROR: Failed to retrieve UFI for directory */
+ dk4app_log_3(
+ app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 14, 15,
+ dk4dir_get_path(on->dirptr)
+ );
+ exval = EXIT_FAILURE;
+ gosub = 0;
+ }
+ on = on->parent;
+ }
+ }
+ } else {
+ /* ERROR: Failed to retrieve unique file identifier */
+ dk4app_log_3(
+ app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 14, 15,
+ mybu
+ );
+ exval = EXIT_FAILURE;
+ gosub = 0;
+ }
+ }
+ if (0 != gosub) {
+ /*
+ Go into subdirectory.
+ */
+ on = dk_ls_new_node(
+ mybu, cn, ((3 >= cn->level) ? (1 + cn->level) : 3)
+ );
+ if (NULL != on) {
+ cn->child = on;
+ cn = on;
+ } else {
+ /* ERROR: Failed to create node, already reported */
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /*
+ Do not go into subdirectory, probably show directory details.
+ */
+ dk_ls_process_item_for_node(cn, mybu);
+ }
+ } else {
+ /* ERROR: Failed to construct path, already reported */
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /*
+ Finalize node, report non-directory entries and the
+ directories, finally move to parent node.
+ */
+ if ((0 != size_wanted) || (0 != show_files)) {
+ if (0 != dk_ls_can_continue()) {
+ do {
+ ndn = dk4dir_next_file(cn->dirptr);
+ if (NULL != ndn) { $? ". file \"%!ds\"", ndn
+ pa = dk4dir_get_path(cn->dirptr);
+ if (0 != dk_ls_construct_path(&mybu, &szmb, pa, ndn)) {
+ dk_ls_process_item_for_node(cn, mybu);
+ } else {
+ /* ERROR: Failed to construct path, already reported */
+ exval = EXIT_FAILURE;
+ }
+ }
+ } while((0 != dk_ls_can_continue()) && (NULL != ndn)) ;
+ }
+ }
+ if (0 != dk_ls_can_continue()) { $? ". can continue"
+ if ((0 != size_wanted) || (0 != show_dirs)) {
+ if ((1 >= cn->level) || (0 != recursive)) {
+ dk_ls_process_item_information(
+ dk4dir_get_path(cn->dirptr), &(cn->fi),
+ 1, cn->size, cn->ovsize
+ );
+ }
+ }
+ }
+ on = cn->parent;
+ if (NULL != on) {
+ on->child = NULL;
+ dk4error_init(&er);
+ on->size = dk4ma_size_t_add(on->size, cn->size, &er);
+ if (DK4_E_NONE != er.ec) {
+ on->ovsize = 1;
+ }
+ if (0 != cn->ovsize) {
+ on->ovsize = 1;
+ }
+ }
+ dk_ls_delete_node(cn);
+ cn = on;
+ }
+ } else {
+ /*
+ Abort: Close current node and move to parent. No output.
+ */
+ $? ". abort processing"
+ on = cn->parent;
+ if (NULL != on) { on->child = NULL; }
+ dk_ls_delete_node(cn);
+ cn = on;
+ }
+ }
+ } else { $? "! mybu"
+ /* ERROR: Allocation failed, already reported */
+ exval = EXIT_FAILURE;
+ }
+ /*
+ Release path name construction buffer.
+ */
+ if (NULL != mybu) {
+ dk4mem_release(mybu);
+ }
+ $? "- dk_ls_process_directory"
+}
+
+
+
+/** Check whether the specified file name is a directory.
+ @param fn File name.
+ @return 1 for directories, 0 for non-directory entries,
+ -1 on errors.
+*/
+static
+int
+dk_ls_is_directory(const dkChar *fn)
+{
+#if DK4_ON_WINDOWS
+ DWORD dwattr;
+ HANDLE ha;
+ LONG lasterror;
+#if DK4_CHAR_SIZE > 1
+ WIN32_FIND_DATAW finddata;
+#else
+ WIN32_FIND_DATAA finddata;
+#endif
+#else
+ dk4_stat_t stb;
+ dk4_er_t er;
+#endif
+ int back = -1;
+ $? "+ dk_ls_is_directory \"%!ds\"", fn
+ if (NULL != fn) {
+#if DK4_ON_WINDOWS
+#if DK4_CHAR_SIZE > 1
+ dwattr = GetFileAttributesW(fn);
+#else
+ dwattr = GetFileAttributesA(fn);
+#endif
+ if (INVALID_FILE_ATTRIBUTES != dwattr) {
+ if (0 != (FILE_ATTRIBUTE_DIRECTORY & dwattr)) {
+ back = 1;
+ } else {
+ back = 0;
+ }
+ } else {
+ lasterror = GetLastError();
+#if DK4_CHAR_SIZE > 1
+ ha = FindFirstFileW(fn, &finddata);
+#else
+ ha = FindFirstFileA(fn, &finddata);
+#endif
+ if (INVALID_HANDLE_VALUE != ha) {
+ if (0 != (FILE_ATTRIBUTE_DIRECTORY & (finddata.dwFileAttributes))) {
+ back = 1;
+ } else {
+ back = 0;
+ }
+ FindClose(ha);
+ } else {
+ /* ERROR: Failed to retrieve file attributes */
+ dk4fileinfo_report_win_failed(app, fn, lasterror);
+ exval = EXIT_FAILURE;
+ }
+ }
+#else
+ dk4error_init(&er);
+ if (0 != dk4stat(&stb, fn, &er)) {
+ if (0 != dk4stat_is_directory(&stb, &er)) {
+ back = 1;
+ } else {
+ back = 0;
+ }
+ } else {
+ /* ERROR: Failed to retrieve file information */
+ dk4fileinfo_report_stat_failed(app, fn, er.dt.iDetails1);
+ exval = EXIT_FAILURE;
+ }
+#endif
+ } $? "- dk_ls_is_directory %d", back
+ return back;
+}
+
+
+
+/* !!!!!
+ For files explicitly mentioned on the command line
+ processing starts here, probably after name expansion.
+*/
+
+/** Run for one file or directory directly named on the command line.
+ @param arg Path name.
+*/
+static
+void
+run_for_one_name(const dkChar *arg)
+{
+ $? "+ run_for_one_name \"%!ds\"", arg
+ switch (dk_ls_is_directory(arg)) {
+ case 1 : { $? ". directory"
+ dk_ls_process_directory(arg, 0);
+ } break;
+ case 0 : { $? ". not a directory"
+ if (0 != show_files) {
+ dk_ls_process_non_directory(arg, 0);
+ }
+ } break;
+ default : { $? "! no information"
+ /* ERROR: Failed to obtain information about file, already reported */
+ exval = EXIT_FAILURE;
+ } break;
+ }
+ $? "- run_for_one_name"
+}
+
+
+
+/** Process command line arguments.
+ @param xargc Number of command line arguments.
+*/
+static
+void
+run_for_command_line_arguments(int xargc)
+{
+#if DK4_ON_WINDOWS
+ dkChar buf[DK4_MAX_PATH];
+ dk4_dir_t *fne;
+ const dkChar *pth;
+ const dkChar *fn;
+ int cc2;
+#endif
+ const dkChar *xargv;
+ int i;
+ int cc = 1;
+ $? "+ run_for_command_line_arguments %d", xargc
+ for (i = 0; ((i < xargc) && (1 == cc)); i++) { $? ". loop start"
+ if (0 != dk_ls_can_continue()) { $? ". can continue"
+ xargv = dk4app_get_argv(app, i); $? ". xargv \"%!ds\"", xargv
+#if DK4_ON_WINDOWS
+ if (0 != dk4path_must_expand(xargv)) {
+ /* !!!!!
+ For file names we need to expand
+ processing starts here.
+ */
+ fne = dk4app_fne_open(xargv, app);
+ if (NULL != fne) {
+ cc2 = 1;
+ while (1 == cc2) {
+ if (0 != dk_ls_can_continue()) {
+ fn = dk4dir_next_dir(fne);
+ if (NULL != fn) {
+ pth = dk4dir_get_path(fne);
+ if (NULL != pth) {
+ if (0 != dk4str_cpy_s(buf,DK4_SIZEOF(buf,dkChar),pth,NULL)) {
+ if (0!=dk4str_cat_s(buf,DK4_SIZEOF(buf,dkChar),dk_ls_kwnl[5],NULL))
+ {
+ if (0 != dk4str_cat_s(buf,DK4_SIZEOF(buf,dkChar),fn,NULL)) {
+ dk_ls_process_directory(buf, 0);
+ } else {
+ /* ERROR: File name too long! */
+ dk4app_log_5(
+ app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 16, 17, 18,
+ pth, fn
+ );
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: File name too long! */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: File name too long! */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ run_for_one_name(fn);
+ }
+ } else {
+ cc2 = 0;
+ }
+ } else {
+ cc2 = 0;
+ }
+ }
+ cc2 = 1;
+ while (1 == cc2) {
+ if (0 != dk_ls_can_continue()) {
+ fn = dk4dir_next_file(fne);
+ if (NULL != fn) {
+ pth = dk4dir_get_path(fne);
+ if (NULL != pth) {
+ if (0 != dk4str_cpy_s(buf,DK4_SIZEOF(buf,dkChar),pth,NULL)) {
+ if (0!=dk4str_cat_s(buf,DK4_SIZEOF(buf,dkChar),dk_ls_kwnl[5],NULL))
+ {
+ if (0 != dk4str_cat_s(buf,DK4_SIZEOF(buf,dkChar),fn,NULL)) {
+ dk_ls_process_non_directory(buf, 0);
+ } else {
+ /* ERROR: File name too long! */
+ dk4app_log_5(
+ app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 16, 17, 18,
+ pth, fn
+ );
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: File name too long! */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: File name too long! */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ run_for_one_name(fn);
+ }
+ } else {
+ cc2 = 0;
+ }
+ } else {
+ cc2 = 0;
+ }
+ }
+ dk4dir_close(fne);
+ } else {
+ /* ERROR: Failed to expand file name, already reported */
+ exval = EXIT_FAILURE;
+ }
+ } else {
+#endif
+ $? ". UNIX/Linux"
+ run_for_one_name(xargv);
+#if DK4_ON_WINDOWS
+ }
+#endif
+ } else {
+ cc = 0;
+ }
+ }
+ $? "- run_for_command_line_arguments"
+}
+
+
+
+/* !!!!!
+ If no file names was given on the command line processing
+ starts here.
+*/
+
+/** Show contents of current directory.
+*/
+static
+void
+run_for_current_dir_contents(void)
+{
+ dk4_er_t er;
+ dk4_dir_t *dirptr;
+ const dkChar *fn;
+ int cc;
+ int om;
+ $? "+ run_for_current_dir_contents"
+ dk4error_init(&er);
+ om = DK4_DIR_OPEN_SORTED | DK4_DIR_SYMLINK_DIR_AS_FILE;
+ dirptr = dk4dir_open_app(dk_ls_kwnl[4], om, app);
+ if (NULL != dirptr) {
+ if ((0 != recursive) || (0 != show_dirs)) {
+ cc = 1;
+ while(1 == cc) {
+ if (0 != dk_ls_can_continue()) {
+ fn = dk4dir_next_dir(dirptr);
+ if (NULL != fn) {
+ if ((0 != recursive) || (0 != size_wanted)) {
+ dk_ls_process_directory(fn, 1);
+ } else {
+ dk_ls_process_non_directory(fn, 1);
+ }
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = 0;
+ }
+ }
+ }
+ if (0 != show_files) {
+ cc = 1;
+ while (1 == cc) {
+ if (0 != dk_ls_can_continue()) {
+ fn = dk4dir_next_file(dirptr);
+ if (NULL != fn) {
+ dk_ls_process_non_directory(fn, 1);
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = 0;
+ }
+ }
+ }
+ dk4dir_close(dirptr);
+ } else {
+ /* ERROR: Failed to open current directory, already reported */
+ exval = EXIT_FAILURE;
+ }
+ $? "- run_for_current_dir_contents"
+}
+
+
+
+/** Process command line arguments (if any).
+*/
+static
+void
+dk_ls_normal_run(void)
+{
+ dkChar mdbuf[32];
+ dkChar *bptr;
+ int res;
+ int xargc;
+ int mdset;
+ $? "+ dk_ls_normal_run"
+ exval = EXIT_SUCCESS;
+
+ /* Process options.
+ */
+ if (0 != dk4app_opt_is_set_short(app, dkT('p'), NULL)) {
+ res = dk4app_opt_get_string_short(
+ po_buf, DK4_SIZEOF(po_buf,dkChar), app, dkT('p'), NULL
+ );
+ if (0 != res) {
+ print_order = po_buf;
+ }
+ }
+ if (NULL == print_order) {
+ if (0 == dk4app_opt_is_set_short(app, dkT('R'), NULL)) {
+ res = dk4app_pref_get(
+ po_buf, DK4_SIZEOF(po_buf,dkChar), app, dk_ls_kwnl[10], 0
+ );
+ if (0 != res) {
+ dk4str_rtwh(po_buf, NULL);
+ print_order = dk4str_start(po_buf, NULL);
+ }
+ }
+ }
+ if (NULL == print_order) {
+#if DK4_ON_WINDOWS
+ print_order = dk_ls_kwnl[8];
+#else
+ print_order = dk_ls_kwnl[3];
+#endif
+ }
+ if (NULL != dk4str_chr(print_order, dkT('s'))) {
+ size_wanted = 1;
+ }
+ if (NULL != dk4str_chr(print_order, dkT('n'))) {
+ name_wanted = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('r'), NULL)) {
+ recursive = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('f'), NULL)) {
+ stay_on_fs = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('t'), NULL)) {
+ res = dk4app_opt_get_string_short(
+ mdbuf, DK4_SIZEOF(mdbuf,dkChar), app, dkT('t'), NULL
+ );
+ if (0 != res) {
+ bptr = mdbuf;
+ show_files = 0; show_dirs = 0;
+ while (dkT('\0') != *bptr) {
+ if (dkT('d') == *bptr) { show_dirs = 1; }
+ if (dkT('f') == *bptr) { show_files = 1; }
+ bptr++;
+ }
+ }
+ }
+ mdset = 0;
+ if (0 != dk4app_opt_is_set_short(app, dkT('m'), NULL)) {
+ res = dk4app_opt_get_string_short(
+ mdbuf, DK4_SIZEOF(mdbuf,dkChar), app, dkT('m'), NULL
+ );
+ if (0 != res) {
+ /* Process string, find digest and encoding */
+ mdset = 1;
+ dk_ls_set_md(
+ &digest_type, &digest_enco, mdbuf, app, dk_ls_msg, dk_ls_sz_msg
+ );
+ }
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('s'), NULL)) {
+ show_summary = 1;
+ }
+ if ((0 == mdset) && (0 == dk4app_opt_is_set_short(app, dkT('R'), NULL))) {
+ res = dk4app_pref_get(
+ mdbuf, DK4_SIZEOF(mdbuf,dkChar), app, dk_ls_kwnl[9], 0
+ );
+ if (0 != res) {
+ dk_ls_set_md(
+ &digest_type, &digest_enco, mdbuf, app, dk_ls_msg, dk_ls_sz_msg
+ );
+ }
+ }
+
+ /* Process command line arguments or current directory contents.
+ */
+ xargc = dk4app_get_argc(app);
+ if (0 < xargc) { $? ". process command line arguments"
+ run_for_command_line_arguments(xargc);
+ } else { $? ". no command line args, use current dir"
+ run_for_current_dir_contents();
+ }
+ if (0 != show_summary) {
+ if (((dk4_um_t)0UL != num_dirs) && (DK4_E_NONE == er_dirs.ec)) {
+ if (0 == dk4fputs(dk_ls_msg[30], stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ dk_ls_write_decimal_number(num_dirs,dk4numlength(sizeof(dk4_um_t),0));
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ if (((dk4_um_t)0UL != num_files) && (DK4_E_NONE == er_files.ec)) {
+ if (0 == dk4fputs(dk_ls_msg[31], stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ dk_ls_write_decimal_number(num_files,dk4numlength(sizeof(dk4_um_t),0));
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ if (((dk4_um_t)0UL != size_bytes) && (DK4_E_NONE == er_bytes.ec)) {
+ if (0 == dk4fputs(dk_ls_msg[32], stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ dk_ls_write_decimal_number(size_bytes,dk4numlength(sizeof(dk4_um_t),0));
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) {
+ write_error = 1; exval = EXIT_FAILURE;
+ }
+ }
+ }
+ $? "- dk_ls_normal_run"
+}
+
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+dk_ls_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ struct sigaction opipe;
+#endif
+ struct sigaction oint;
+#ifdef SIGPIPE
+ struct sigaction npipe;
+#endif
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+ int success = 0;
+
+#ifdef SIGPIPE
+ /* Set up signal handling for SIGPIPE.
+ */
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+#endif
+
+ /* Set up signal handling for SIGINT.
+ */
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ dk_ls_normal_run();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+#ifdef SIGPIPE
+ /* Restore signal handling for SIGPIPE.
+ */
+ restore_old_pipe:
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_ls_msg, dk_ls_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+#endif
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+dk_ls_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ dk_ls_normal_run();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+#ifdef SIGPIPE
+ sigset(SIGPIPE, oldpipe);
+#endif
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+dk_ls_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = signal(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ dk_ls_normal_run();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+#ifdef SIGPIPE
+ signal(SIGPIPE, oldpipe);
+#endif
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+dk_ls_run_with_signal_handlers(void)
+{
+ dk_ls_normal_run();
+}
+#endif
+#endif
+#endif
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ $!trace-init /tmp/dk-ls.deb
+ $? "+ main"
+ dk4fput_initialize_stdout();
+ dk4fput_initialize_stderr();
+ dk4error_init(&er_dirs);
+ dk4error_init(&er_files);
+ dk4error_init(&er_bytes);
+ app = dk4app_open_cmd(
+ argc, argv, dk_ls_options, dk_ls_sz_options,
+ dk_ls_kwnl[0], DKT_VERSION_DK,
+ dk_ls_kwnl[1], dk_ls_help_text, dk_ls_license_text
+ );
+ if (NULL != app) { $? ". app"
+ dk_ls_sz_msg = dk4app_string_table_size(dk_ls_kw_def);
+ dk_ls_msg = dk4app_string_table(app, dk_ls_kwnl[2], dk_ls_kw_def);
+ if (0 != dk4app_can_run_normally(app)) { $? ". normal"
+ dk_ls_run_with_signal_handlers();
+ } else {
+ if (0 != dk4app_help_version_license(app)) { $? ". help/vers/lic"
+ exval = EXIT_SUCCESS;
+ }
+ }
+ dk4app_close(app);
+ } else { $? "! app"
+ dk4fputs(dk_ls_kwnl[11], stdout, NULL);
+ fflush(stdout);
+ }
+ fflush(stdout);
+ fflush(stderr);
+ dk4fput_cleanup_stderr();
+ dk4fput_cleanup_stdout();
+ $? "- main %d", exval
+ $!trace-end
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/dk-ls.h b/support/dktools/dk-ls.h
new file mode 100644
index 0000000000..36e2509625
--- /dev/null
+++ b/support/dktools/dk-ls.h
@@ -0,0 +1,119 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk-ls.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK_LS_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK_LS_H_INCLUDED 1
+
+
+#line 10 "dk-ls.ctr"
+
+/** @file dk-ls.h Header file for dk-ls program.
+*/
+
+#include "dk4md.h"
+#include "dk4fileit.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Set message digest type and message digest encoding.
+ @param mdtype Address of message digest type variable.
+ @param mdenc Address of message digest encoding variable.
+ @param buffer Buffer containing textual description.
+ @param app Application structure for diagnostics, may be NULL.
+ @param msg Message string array.
+ @param szmsg Size of message string array.
+*/
+void dk_ls_set_md(
+ int *mdtype,
+ int *mdenc,
+ dkChar *buffer,
+ dk4_app_t *app,
+ const dkChar * const *msg,
+ size_t szmsg
+);
+
+/** Read information about symbolic link target.
+ @param bptr Buffer for path name.
+ @param szb Size of buffer (number of dkChar).
+ @param fn Link filename.
+ @return 1 on success, 0 on error.
+*/
+int
+dk_ls_readlink(dkChar *bptr, size_t szb, const dkChar *fn);
+
+/** Report error while attempting to read size.
+ @param app Application structure for diagnostics.
+ @param fn File name.
+ @param ch Data chooser.
+ @param msg Constant message texts.
+ @param szmsg Size of msg array.
+*/
+void
+dk_ls_report_fileinfo_size_error(
+ dk4_app_t *app,
+ const dkChar *fn,
+ int ch,
+ const dkChar * const *msg,
+ size_t szmsg
+);
+
+/** Report error while attempting to read timestamp.
+ @param app Application structure for diagnostics.
+ @param fn File name.
+ @param ch Data chooser.
+ @param msg Constant message texts.
+ @param szmsg Size of msg array.
+*/
+void
+dk_ls_report_fileinfo_timestamp_error(
+ dk4_app_t *app,
+ const dkChar *fn,
+ int ch,
+ const dkChar * const *msg,
+ size_t szmsg
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk-ls.rc b/support/dktools/dk-ls.rc
new file mode 100644
index 0000000000..8d6e4497c5
--- /dev/null
+++ b/support/dktools/dk-ls.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "An ls clone, configurable output column order\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "An ls clone, configurable output column order\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "dk-ls\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/dk-pwd.c b/support/dktools/dk-pwd.c
new file mode 100644
index 0000000000..a98df244f7
--- /dev/null
+++ b/support/dktools/dk-pwd.c
@@ -0,0 +1,432 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk-pwd.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk-pwd.c The dk-pwd module.
+*/
+
+
+#line 10 "dk-pwd.ctr"
+
+
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4app.h"
+#include "dk4aopt.h"
+#include "dk4vers.h"
+#include "dk4mpl.h"
+#include "dk4getcwdd.h"
+#include "dk4mem.h"
+#include "dk4fput.h"
+
+
+
+
+
+#line 27 "dk-pwd.ctr"
+
+
+/** Default help text, used if help text file is not found.
+*/
+static const dkChar * const dk_pwd_help_text[] = {
+dkT(""),
+dkT("Show current directory"),
+dkT(""),
+dkT("dk-pwd [<options>]"),
+dkT(""),
+dkT("Options:"),
+dkT(""),
+dkT("-l\t\tShow last part of path only."),
+dkT("-b\t\tBeautify (replace backslashes by slashes)."),
+dkT(""),
+dkT("--help\t\tShow this short help text."),
+dkT("--manual\t*** SHOW FULL MANUAL. ***"),
+dkT("--version\tShow version information."),
+dkT("--license\tShow license information."),
+dkT(""),
+NULL
+
+
+#line 49 "dk-pwd.ctr"
+};
+
+
+
+/** License conditions.
+*/
+static const dkChar * const dk_pwd_license_text[] = {
+dkT("This software uses code from the following projects, either directly or as"),
+dkT("a library:"),
+dkT(""),
+dkT("dktools\t\tDirk Krause's tools and libraries."),
+dkT("\t\tSee http://dktools.sourceforge.net/ for more information."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT("zlib\t\tData compression library."),
+dkT("\t\tSee http://www.zlib.net/ for more information."),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT("bzip2\t\tData compression program and library."),
+dkT("\t\tSee http://www.bzip.org/ for more information."),
+#endif
+dkT(""),
+dkT("All the licenses below apply to the program."),
+dkT("Licenses for used libraries are shown as found on my Scientific Linux 6.x"),
+dkT("computer in the /usr/share/doc directory on 2015-04-01. Check the project"),
+dkT("homepages of the used libraries for additional information and/or updated"),
+dkT("license terms."),
+dkT(""),
+dkT(""),
+dkT("DK tools and libraries license"),
+dkT("=============================="),
+dkT("Copyright (c) 2015-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above copyright notice,"),
+dkT(" this list of conditions and the following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("* Neither the name of the Dirk Krause nor the names of contributors may be"),
+dkT(" used to endorse or promote products derived from this software without"),
+dkT(" specific prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\""),
+dkT("AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED."),
+dkT(""),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,"),
+dkT("INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,"),
+dkT("BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,"),
+dkT("DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY"),
+dkT("OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,"),
+dkT("EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT(""),
+dkT("Zlib license"),
+dkT("============"),
+dkT("(C) 1995-2004 Jean-loup Gailly and Mark Adler"),
+dkT(""),
+dkT("This software is provided 'as-is', without any express or implied"),
+dkT("warranty. In no event will the authors be held liable for any damages"),
+dkT("arising from the use of this software."),
+dkT(""),
+dkT("Permission is granted to anyone to use this software for any purpose,"),
+dkT("including commercial applications, and to alter it and redistribute it"),
+dkT("freely, subject to the following restrictions:"),
+dkT(""),
+dkT("1. The origin of this software must not be misrepresented; you must not"),
+dkT(" claim that you wrote the original software. If you use this software"),
+dkT(" in a product, an acknowledgment in the product documentation would be"),
+dkT(" appreciated but is not required."),
+dkT("2. Altered source versions must be plainly marked as such, and must not be"),
+dkT(" misrepresented as being the original software."),
+dkT("3. This notice may not be removed or altered from any source distribution."),
+dkT(""),
+dkT("Jean-loup Gailly Mark Adler"),
+dkT("jloup@gzip.org madler@alumni.caltech.edu"),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT(""),
+dkT("Bzip2 and libbzip2 library license"),
+dkT("=================================="),
+dkT("This program, \"bzip2\", the associated library \"libbzip2\", and all"),
+dkT("documentation, are copyright (C) 1996-2007 Julian R Seward. All"),
+dkT("rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions"),
+dkT("are met:"),
+dkT(""),
+dkT("1. Redistributions of source code must retain the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer."),
+dkT(""),
+dkT("2. The origin of this software must not be misrepresented; you must "),
+dkT(" not claim that you wrote the original software. If you use this "),
+dkT(" software in a product, an acknowledgment in the product "),
+dkT(" documentation would be appreciated but is not required."),
+dkT(""),
+dkT("3. Altered source versions must be plainly marked as such, and must"),
+dkT(" not be misrepresented as being the original software."),
+dkT(""),
+dkT("4. The name of the author may not be used to endorse or promote "),
+dkT(" products derived from this software without specific prior written "),
+dkT(" permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS"),
+dkT("OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED"),
+dkT("WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE"),
+dkT("GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS"),
+dkT("INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,"),
+dkT("WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS"),
+dkT("SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+dkT(""),
+dkT("Julian Seward, jseward@bzip.org"),
+dkT("bzip2/libbzip2 version 1.0.5 of 10 December 2007"),
+#endif
+dkT(""),
+NULL
+
+
+#line 180 "dk-pwd.ctr"
+};
+
+
+
+/** Buffer to store the directory.
+*/
+static dkChar cwdbuf[DK4_MAX_PATH];
+
+
+
+/** Constant texts used by the module, not localized.
+*/
+static const dkChar * const dk_pwd_kwnl[] = {
+/* 0 */
+dkT("dktools"),
+
+/* 1 */
+dkT("dk-pwd.txt"),
+
+/* 2 */
+dkT("dk-pwd.str"),
+
+NULL
+
+
+#line 207 "dk-pwd.ctr"
+};
+
+
+
+/** Constant texts used by the program, replaced by localized texts.
+*/
+static const dkChar * const dk_pwd_kw_def[] = {
+/* 0 */
+dkT("Failed to find current directory!"),
+
+NULL
+
+
+#line 220 "dk-pwd.ctr"
+};
+
+
+/** Options used by program.
+*/
+static const dk4_option_specification_t dk_pwd_options[] = {
+
+ /* Show final part of directory name only.
+ */
+ { dkT('l'), dkT("last"), DK4_OPT_ARG_NONE },
+
+ /* Replace backslashes by slashes.
+ */
+ { dkT('b'), dkT("beautify"), DK4_OPT_ARG_NONE }
+};
+
+
+
+/** Localized texts.
+*/
+static const dkChar * const *dk_pwd_msg = dk_pwd_kw_def;
+
+
+
+/** Application structure for diagnostics.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Number of options in the dk_pwd_options array.
+*/
+static const size_t dk_pwd_sz_options =
+sizeof(dk_pwd_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Number of entries in the message texts array.
+*/
+static size_t dk_pwd_sz_msg =
+sizeof(dk_pwd_kw_def)/sizeof(DK4_PDKCHAR) - 1;
+
+
+
+/** Exit status code returned by the program.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+static
+void
+dk_pwd_beautify(dkChar *buf)
+{
+ while(dkT('\0') != *buf) {
+ if (dkT('\\') == *buf) { *buf = dkT('/'); }
+ buf++;
+ }
+}
+
+
+
+static
+dkChar *
+dk_pwd_last_part(dkChar *buf)
+{
+ dkChar *back = NULL;
+ dkChar *orbuf;
+
+ orbuf = buf;
+ while (dkT('\0') != *buf) {
+ if ((dkT('\\') == *buf) || (dkT('/') == *buf)) { back = buf; }
+ buf++;
+ }
+ if (NULL != back) { back++; } else { back = orbuf; }
+ return back;
+}
+
+
+
+static
+void
+dk_pwd_show_current_directory(void)
+{
+ dk4_er_t er;
+ dkChar *ptr;
+
+ dk4error_init(&er);
+ if (0 != dk4getcwd(cwdbuf, DK4_SIZEOF(cwdbuf,dkChar), &er)) {
+ if (0 != dk4app_opt_is_set_short(app, dkT('b'), NULL)) {
+ dk_pwd_beautify(cwdbuf);
+ }
+ ptr = cwdbuf;
+ if (0 != dk4app_opt_is_set_short(app, dkT('l'), NULL)) {
+ ptr = dk_pwd_last_part(cwdbuf);
+ }
+ exval = EXIT_SUCCESS;
+ if (0 == dk4fputs(ptr, stdout, NULL)) {
+ exval = EXIT_FAILURE;
+ }
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) {
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ dk4app_log_1(app, dk_pwd_msg, dk_pwd_sz_msg, DK4_LL_ERROR, 0);
+ }
+}
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ /*
+ Initialize stdout and stderr for dkChar output.
+ */
+ dk4fput_initialize_stdout();
+ dk4fput_initialize_stderr();
+ /*
+ Create dk4_app_t structure.
+ */
+ app = dk4app_open_cmd(
+ argc, argv, dk_pwd_options, dk_pwd_sz_options,
+ dk_pwd_kwnl[0], DKT_VERSION_DK,
+ dk_pwd_kwnl[1], dk_pwd_help_text, dk_pwd_license_text
+ );
+ if (NULL != app) {
+ /*
+ Obtain string table (array of localized strings).
+ Memory is managed in the dk4_app_t structure.
+ */
+ dk_pwd_sz_msg = dk4app_string_table_size(dk_pwd_kw_def);
+ dk_pwd_msg = dk4app_string_table(app, dk_pwd_kwnl[2], dk_pwd_kw_def);
+ /*
+ Check how to run.
+ */
+ if (0 != dk4app_can_run_normally(app)) {
+ /*
+ Run normally.
+ */
+ dk_pwd_show_current_directory();
+ } else {
+ /*
+ --help, --version, --license, --manual was used. Show information.
+ */
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ /*
+ Destroy dk4_app_t structure, release memory.
+ Memory for the string tables is released here too.
+ */
+ dk4app_close(app);
+ }
+ /*
+ Flush stdout and stderr, restore settings from program start.
+ */
+ fflush(stdout);
+ fflush(stderr);
+ dk4fput_cleanup_stderr();
+ dk4fput_cleanup_stdout();
+ /*
+ Return exit status code.
+ */
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/dk-pwd.ctr b/support/dktools/dk-pwd.ctr
new file mode 100644
index 0000000000..3c74fb1cd3
--- /dev/null
+++ b/support/dktools/dk-pwd.ctr
@@ -0,0 +1,395 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4app.h"
+#include "dk4aopt.h"
+#include "dk4vers.h"
+#include "dk4mpl.h"
+#include "dk4getcwdd.h"
+#include "dk4mem.h"
+#include "dk4fput.h"
+
+
+
+$!trace-include
+
+
+/** Default help text, used if help text file is not found.
+*/
+static const dkChar * const dk_pwd_help_text[] = {
+$!text macro=dkT,preprocessor
+
+Show current directory
+
+dk-pwd [<options>]
+
+Options:
+
+-l Show last part of path only.
+-b Beautify (replace backslashes by slashes).
+
+--help Show this short help text.
+--manual *** SHOW FULL MANUAL. ***
+--version Show version information.
+--license Show license information.
+
+$!end
+};
+
+
+
+/** License conditions.
+*/
+static const dkChar * const dk_pwd_license_text[] = {
+$!text macro=dkT,preprocessor
+This software uses code from the following projects, either directly or as
+a library:
+
+dktools Dirk Krause's tools and libraries.
+ See http://dktools.sourceforge.net/ for more information.
+#if DK4_HAVE_ZLIB_H
+
+zlib Data compression library.
+ See http://www.zlib.net/ for more information.
+#endif
+#if DK4_HAVE_BZLIB_H
+
+bzip2 Data compression program and library.
+ See http://www.bzip.org/ for more information.
+#endif
+
+All the licenses below apply to the program.
+Licenses for used libraries are shown as found on my Scientific Linux 6.x
+computer in the /usr/share/doc directory on 2015-04-01. Check the project
+homepages of the used libraries for additional information and/or updated
+license terms.
+
+
+DK tools and libraries license
+==============================
+Copyright (c) 2015-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#if DK4_HAVE_ZLIB_H
+
+
+Zlib license
+============
+(C) 1995-2004 Jean-loup Gailly and Mark Adler
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+
+Jean-loup Gailly Mark Adler
+jloup@gzip.org madler@alumni.caltech.edu
+#endif
+#if DK4_HAVE_BZLIB_H
+
+
+Bzip2 and libbzip2 library license
+==================================
+This program, "bzip2", the associated library "libbzip2", and all
+documentation, are copyright (C) 1996-2007 Julian R Seward. All
+rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+3. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Julian Seward, jseward@bzip.org
+bzip2/libbzip2 version 1.0.5 of 10 December 2007
+#endif
+
+$!end
+};
+
+
+
+/** Buffer to store the directory.
+*/
+static dkChar cwdbuf[DK4_MAX_PATH];
+
+
+
+/** Constant texts used by the module, not localized.
+*/
+static const dkChar * const dk_pwd_kwnl[] = {
+$!string-table macro=dkT
+#
+# 0 Program group name
+#
+dktools
+#
+# 1 Help file (manual)
+#
+dk-pwd.txt
+#
+# 2 String table file name
+#
+dk-pwd.str
+$!end
+};
+
+
+
+/** Constant texts used by the program, replaced by localized texts.
+*/
+static const dkChar * const dk_pwd_kw_def[] = {
+$!string-table macro=dkT
+#
+# 0 Error: Failed to find current directory!
+#
+Failed to find current directory!
+$!end
+};
+
+
+/** Options used by program.
+*/
+static const dk4_option_specification_t dk_pwd_options[] = {
+
+ /* Show final part of directory name only.
+ */
+ { dkT('l'), dkT("last"), DK4_OPT_ARG_NONE },
+
+ /* Replace backslashes by slashes.
+ */
+ { dkT('b'), dkT("beautify"), DK4_OPT_ARG_NONE }
+};
+
+
+
+/** Localized texts.
+*/
+static const dkChar * const *dk_pwd_msg = dk_pwd_kw_def;
+
+
+
+/** Application structure for diagnostics.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Number of options in the dk_pwd_options array.
+*/
+static const size_t dk_pwd_sz_options =
+sizeof(dk_pwd_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Number of entries in the message texts array.
+*/
+static size_t dk_pwd_sz_msg =
+sizeof(dk_pwd_kw_def)/sizeof(DK4_PDKCHAR) - 1;
+
+
+
+/** Exit status code returned by the program.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+static
+void
+dk_pwd_beautify(dkChar *buf)
+{
+ while(dkT('\0') != *buf) {
+ if (dkT('\\') == *buf) { *buf = dkT('/'); }
+ buf++;
+ }
+}
+
+
+
+static
+dkChar *
+dk_pwd_last_part(dkChar *buf)
+{
+ dkChar *back = NULL;
+ dkChar *orbuf;
+
+ orbuf = buf;
+ while (dkT('\0') != *buf) {
+ if ((dkT('\\') == *buf) || (dkT('/') == *buf)) { back = buf; }
+ buf++;
+ }
+ if (NULL != back) { back++; } else { back = orbuf; }
+ return back;
+}
+
+
+
+static
+void
+dk_pwd_show_current_directory(void)
+{
+ dk4_er_t er;
+ dkChar *ptr;
+
+ dk4error_init(&er);
+ if (0 != dk4getcwd(cwdbuf, DK4_SIZEOF(cwdbuf,dkChar), &er)) {
+ if (0 != dk4app_opt_is_set_short(app, dkT('b'), NULL)) {
+ dk_pwd_beautify(cwdbuf);
+ }
+ ptr = cwdbuf;
+ if (0 != dk4app_opt_is_set_short(app, dkT('l'), NULL)) {
+ ptr = dk_pwd_last_part(cwdbuf);
+ }
+ exval = EXIT_SUCCESS;
+ if (0 == dk4fputs(ptr, stdout, NULL)) {
+ exval = EXIT_FAILURE;
+ }
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) {
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ dk4app_log_1(app, dk_pwd_msg, dk_pwd_sz_msg, DK4_LL_ERROR, 0);
+ }
+}
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ /*
+ Initialize stdout and stderr for dkChar output.
+ */
+ dk4fput_initialize_stdout();
+ dk4fput_initialize_stderr();
+ /*
+ Create dk4_app_t structure.
+ */
+ app = dk4app_open_cmd(
+ argc, argv, dk_pwd_options, dk_pwd_sz_options,
+ dk_pwd_kwnl[0], DKT_VERSION_DK,
+ dk_pwd_kwnl[1], dk_pwd_help_text, dk_pwd_license_text
+ );
+ if (NULL != app) {
+ /*
+ Obtain string table (array of localized strings).
+ Memory is managed in the dk4_app_t structure.
+ */
+ dk_pwd_sz_msg = dk4app_string_table_size(dk_pwd_kw_def);
+ dk_pwd_msg = dk4app_string_table(app, dk_pwd_kwnl[2], dk_pwd_kw_def);
+ /*
+ Check how to run.
+ */
+ if (0 != dk4app_can_run_normally(app)) {
+ /*
+ Run normally.
+ */
+ dk_pwd_show_current_directory();
+ } else {
+ /*
+ --help, --version, --license, --manual was used. Show information.
+ */
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ /*
+ Destroy dk4_app_t structure, release memory.
+ Memory for the string tables is released here too.
+ */
+ dk4app_close(app);
+ }
+ /*
+ Flush stdout and stderr, restore settings from program start.
+ */
+ fflush(stdout);
+ fflush(stderr);
+ dk4fput_cleanup_stderr();
+ dk4fput_cleanup_stdout();
+ /*
+ Return exit status code.
+ */
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/dk-pwg-rnd.c b/support/dktools/dk-pwg-rnd.c
new file mode 100644
index 0000000000..d60117937b
--- /dev/null
+++ b/support/dktools/dk-pwg-rnd.c
@@ -0,0 +1,510 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk-pwg-rnd.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk-pwg-rnd.c The dk-pwg-rnd module.
+*/
+
+
+#line 97 "dk-pwg-rnd.ctr"
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_OPENSSL_RAND_H
+#ifndef OPENSSL_RAND_H_INCLUDED
+#include <openssl/rand.h>
+#define OPENSSL_RAND_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4rnd.h"
+
+
+
+
+
+#line 127 "dk-pwg-rnd.ctr"
+
+
+
+static const int dk4rnd_used_type =
+#if DK4_HAVE_OPENSSL_RAND_H
+ DK4_PRNG_OPENSSL
+#else
+#if DK4_HAVE_RANDOM
+ DK4_PRNG_STATE
+#else
+#if DK4_HAVE_LRAND48
+ DK4_PRNG_RAND48
+#else
+#if DK4_HAVE_RAND
+ DK4_PRNG_SIMPLE
+#else
+ 0
+#endif
+#endif
+#endif
+#endif
+;
+
+
+
+/** Static keywords used by the module, not localized.
+*/
+static const char * const dk4rnd_kwnl[] = {
+/* 0 */
+"EGDSOCKET",
+
+/* 1 */
+"/dev/random",
+
+/* 2 */
+"/dev/urandom",
+
+NULL
+
+
+#line 169 "dk-pwg-rnd.ctr"
+};
+
+
+
+/** Flag: Already seeded.
+*/
+static int dk4rnd_seeded = 0;
+
+
+
+#if !DK4_HAVE_OPENSSL_RAND_H
+#if DK4_HAVE_RANDOM || DK4_HAVE_LRAND48 || DK4_HAVE_RAND
+
+/** Attempt to obtain seed data.
+ @param bptr Buffer pointer.
+ @param sz Buffer size.
+ @return 1 on success, 0 on error.
+
+*/
+static
+int
+dk4rnd_find_seed_data(void *bptr, size_t sz)
+{
+#if DK4_ON_WINDOWS
+ HCRYPTPROV hcp; /* Crypto provider */
+ BOOL res; /* Operation result */
+#else
+#if DK4_HAVE_SOCKET
+ struct sockaddr_un soun; /* Unix domain socket addr */
+ socklen_t szs; /* Socket length */
+ ssize_t sobytes; /* Bytes obtained */
+ int udsock; /* Unix domain socket */
+#endif
+ char *egdsn = NULL;
+#endif
+ FILE *fipo;
+ size_t rdb;
+ int back = 0;
+
+ /* EGD socket
+ */
+#if !DK4_ON_WINDOWS
+ egdsn = getenv(dk4rnd_kwnl[0]);
+ if (NULL != egdsn) {
+ if (108 > strlen(egdsn)) {
+ udsock = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (-1 < udsock) {
+ soun.sun_family = AF_UNIX;
+ strcpy(soun.sun_path, egdsn);
+ szs = sizeof(struct sockaddr_un) - sizeof(soun.sun_path)
+ + strlen(soun.sun_path);
+ if (0 == connect(udsock, (const struct sockaddr *)(&soun), szs)) {
+ sobytes = recv(udsock, bptr, sz, 0);
+ if (0 < sobytes) {
+ if ((size_t)sobytes == sz) {
+ back = 1;
+ }
+ } else {
+
+#line 227 "dk-pwg-rnd.ctr"
+ }
+ } else {
+
+#line 229 "dk-pwg-rnd.ctr"
+ }
+ close(udsock);
+ } else {
+
+#line 232 "dk-pwg-rnd.ctr"
+ }
+ } else {
+
+#line 234 "dk-pwg-rnd.ctr"
+ }
+ } else {
+
+#line 236 "dk-pwg-rnd.ctr"
+ }
+ if (1 == back) { goto finished; }
+#endif
+
+ /* System mechanisms.
+ */
+#if DK4_ON_WINDOWS
+ res = CryptAcquireContext(
+ &hcp, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT
+ );
+ if (res) {
+ res = CryptGenRandom(hcp, (DWORD)sz, bptr);
+ if (res) {
+ back = 1;
+ }
+ CryptReleaseContext(hcp, (DWORD)0L);
+ }
+#else
+ fipo = fopen(dk4rnd_kwnl[1], "rb");
+ if (NULL != fipo) {
+ rdb = fread(bptr, 1, sz, fipo);
+ fclose(fipo);
+ if ((0 < rdb) && (sz == rdb)) {
+ back = 1;
+ }
+ } else {
+ fipo = fopen(dk4rnd_kwnl[2], "rb");
+ if (NULL != fipo) {
+ rdb = fread(bptr, 1, sz, fipo);
+ fclose(fipo);
+ if ((0 < rdb) && (sz == rdb)) {
+ back = 1;
+ }
+ }
+ }
+#endif
+ finished:
+ return back;
+}
+
+#endif
+#endif
+
+
+#if DK4_HAVE_OPENSSL_RAND_H
+ /* +++++ OpenSSL available */
+
+int
+dk4rnd_init(dk4_er_t *erp)
+{
+ char sbuf[256]; /* Buffer for seed data */
+#if DK4_ON_WINDOWS
+ HCRYPTPROV hcp;
+#endif
+ FILE *fipo = NULL; /* Input file */
+ size_t rdb = 0; /* Number of bytes read */
+ char *egdsn = NULL; /* EGD socket name */
+ int back = 0;
+#if DK4_ON_WINDOWS
+ BOOL res = FALSE;
+#endif
+
+ /* Let OpenSSL initialize itself.
+ */
+ if (1 == RAND_status()) {
+ back = 1; goto finished;
+ }
+
+ /* Attempt EGD socket.
+ */
+#if DK4_HAVE_RAND_EGD && DK4_HAVE_STRUCT_SOCKADDR_UN
+ egdsn = getenv(dk4rnd_kwnl[0]);
+ if (NULL != egdsn) {
+ RAND_egd(egdsn);
+ if (1 == RAND_status()) {
+ back = 1; goto finished;
+ }
+ }
+#endif
+
+ /* Attempt native mechanisms.
+ */
+#if DK4_ON_WINDOWS
+ res = CryptAcquireContext(
+ &hcp, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT
+ );
+ if (res) {
+ res = CryptGenRandom(hcp, (DWORD)sizeof(sbuf), sbuf);
+ if (res) {
+ RAND_seed(sbuf, sizeof(sbuf));
+ if (1 == RAND_status()) {
+ back = 1;
+ }
+ }
+ CryptReleaseContext(hcp, (DWORD)0L);
+ }
+ if (1 == back) { goto finished; }
+#else
+ fipo = fopen(dk4rnd_kwnl[1], "rb");
+ if (NULL != fipo) {
+ rdb = fread(sbuf, 1, sizeof(sbuf), fipo);
+ fclose(fipo);
+ if (rdb > 0) {
+ RAND_seed(sbuf, rdb);
+ if (1 == RAND_status()) {
+ back = 1; goto finished;
+ }
+ }
+ } else {
+ fipo = fopen(dk4rnd_kwnl[2], "rb");
+ if (NULL != fipo) {
+ rdb = fread(sbuf, 1, sizeof(sbuf), fipo);
+ fclose(fipo);
+ if (rdb > 0) {
+ RAND_seed(sbuf, rdb);
+ if (1 == RAND_status()) {
+ back = 1; goto finished;
+ }
+ }
+ }
+ }
+#endif
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+finished:
+ if (1 == back) {
+ dk4rnd_seeded = 1;
+ }
+ return back;
+}
+
+int
+dk4rnd_get_data(void *bptr, size_t bs, dk4_er_t *erp)
+{
+ int back = 0;
+ if ((NULL != bptr) && (0 < bs)) {
+ if ((dk4_um_t)bs <= (dk4_um_t)INT_MAX) {
+ if (0 != dk4rnd_seeded) {
+ back = RAND_bytes(bptr, (int)bs);
+ if (1 > back) {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+void
+dk4rnd_cleanup(void)
+{
+ RAND_cleanup();
+ dk4rnd_seeded = 0;
+}
+
+ /* ----- OpenSSL available */
+#else
+#if DK4_HAVE_RANDOM
+ /* +++++ initstate(), setstate() and random() available */
+
+/** State array.
+*/
+static char dk4rnd_random_state[256];
+
+/** The initial state array.
+*/
+static char *dk4rnd_old_state = NULL;
+
+int
+dk4rnd_init(dk4_er_t *erp)
+{
+ unsigned int sv; /* Seed value */
+ int back = 0;
+
+ if (0 != dk4rnd_find_seed_data(&sv, sizeof(sv))) {
+ DK4_MEMRES(dk4rnd_random_state, sizeof(dk4rnd_random_state));
+ if (NULL == dk4rnd_old_state) {
+ dk4rnd_old_state = initstate(sv, dk4rnd_random_state, 256);
+ } else {
+ (void)initstate(sv, dk4rnd_random_state, 256);
+ }
+ back = 1;
+ }
+ if (1 == back) { dk4rnd_seeded = 1; }
+ return back;
+}
+
+int
+dk4rnd_get_data(void *bptr, size_t bs, dk4_er_t *erp)
+{
+ int back = 0;
+ if ((NULL != bptr) && (0 < bs)) {
+ if (0 != dk4rnd_seeded) {
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+void
+dk4rnd_cleanup(void)
+{
+}
+
+ /* ----- initstate(), setstate() and random() available */
+#else
+#if DK4_HAVE_LRAND48
+ /* +++++ lrand48(), nrand48() and seed48() available */
+
+int
+dk4rnd_init(dk4_er_t *erp)
+{
+ int back = 0;
+finished:
+ if (1 == back) { dk4rnd_seeded = 1; }
+ return back;
+}
+
+int
+dk4rnd_get_data(void *bptr, size_t bs, dk4_er_t *erp)
+{
+ int back = 0;
+ if ((NULL != bptr) && (0 < bs)) {
+ if (0 != dk4rnd_seeded) {
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+void
+dk4rnd_cleanup(void)
+{
+}
+
+ /* ----- lrand48(), nrand48() and seed48() available */
+#else
+#if DK4_HAVE_RAND
+ /* +++++ rand() and srand() available */
+
+int
+dk4rnd_init(dk4_er_t *erp)
+{
+ int back = 0;
+
+finished:
+ if (1 == back) { dk4rnd_seeded = 1; }
+ return back;
+}
+
+int
+dk4rnd_get_data(void *bptr, size_t bs, dk4_er_t *erp)
+{
+ int back = 0;
+ if ((NULL != bptr) && (0 < bs)) {
+ if (0 != dk4rnd_seeded) {
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+void
+dk4rnd_cleanup(void)
+{
+}
+
+ /* ----- rand() and srand() available */
+#else
+ /* +++++ no PRNG available */
+
+int
+dk4rnd_init(dk4_er_t *erp)
+{
+ int back = 0;
+ return back;
+}
+
+int
+dk4rnd_get_data(void *bptr, size_t bs, dk4_er_t *erp)
+{
+ int back = 0;
+ if ((NULL != bptr) && (0 < bs)) {
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+void
+dk4rnd_cleanup(void)
+{
+}
+
+ /* ----- no PRNG available */
+#endif
+#endif
+#endif
+#endif
+
+int
+dk4rnd_get_prng_type(void)
+{
+ return dk4rnd_used_type;
+}
+
diff --git a/support/dktools/dk-pwg-rnd.ctr b/support/dktools/dk-pwg-rnd.ctr
new file mode 100644
index 0000000000..114b9042e1
--- /dev/null
+++ b/support/dktools/dk-pwg-rnd.ctr
@@ -0,0 +1,555 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk4rnd.h Random number generation.
+
+NOT A GOOD IDEA: WE EITHER NEED CRYPTOGRAPHICALLY STRONG RANDOM DATA
+OR LIGHTWEIGHT RANDOM DATA FOR GAMES OR SIMULATIONS.
+ONE SIZE DOESN'T FIT ALL!
+*/
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve PRNG type.
+ @return PRNG type.
+*/
+int
+dk4rnd_get_prng_type(void);
+
+/** Initialize (seed) PRNG.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_NOT_FOUND<br>
+ if the function failed to obtain seed data.
+*/
+int
+dk4rnd_init(dk4_er_t *erp);
+
+/** Retrieve random bytes.
+ @param bptr Pointer to destination buffer.
+ @param bs Destination buffer size.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if bptr is NULL or bs is either 0 or too large,
+ - DK4_E_SYNTAX<br>
+ if the PRNG was not yet initialized successfully,
+ - DK4_E_NOT_FOUND<br>
+ if the function failed to obtain random data.
+*/
+int
+dk4rnd_get_data(void *bptr, size_t bs, dk4_er_t *erp);
+
+/** Clean up PRNG.
+*/
+void
+dk4rnd_cleanup(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** Random number generators.
+*/
+enum {
+ /** Use rand() function.
+ */
+ DK4_PRNG_SIMPLE = 1,
+
+ /** Use nrand48() function.
+ */
+ DK4_PRNG_RAND48 = 2,
+
+ /** Use initstate()/setstate() functions.
+ */
+ DK4_PRNG_STATE = 4,
+
+ /** Use OpenSSL PRNG.
+ */
+ DK4_PRNG_OPENSSL = 8,
+
+ /** All the PRNGs above.
+ */
+ DK4_PRNG_ALL = (
+ DK4_PRNG_SIMPLE
+ | DK4_PRNG_RAND48
+ | DK4_PRNG_STATE
+ | DK4_PRNG_OPENSSL
+ )
+
+};
+
+%% module
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_OPENSSL_RAND_H
+#ifndef OPENSSL_RAND_H_INCLUDED
+#include <openssl/rand.h>
+#define OPENSSL_RAND_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4rnd.h"
+
+
+
+$!trace-include
+
+
+
+static const int dk4rnd_used_type =
+#if DK4_HAVE_OPENSSL_RAND_H
+ DK4_PRNG_OPENSSL
+#else
+#if DK4_HAVE_RANDOM
+ DK4_PRNG_STATE
+#else
+#if DK4_HAVE_LRAND48
+ DK4_PRNG_RAND48
+#else
+#if DK4_HAVE_RAND
+ DK4_PRNG_SIMPLE
+#else
+ 0
+#endif
+#endif
+#endif
+#endif
+;
+
+
+
+/** Static keywords used by the module, not localized.
+*/
+static const char * const dk4rnd_kwnl[] = {
+$!string-table
+#
+# 0 Environment variable name, pointing to EGD socket
+#
+EGDSOCKET
+#
+# 1 The /dev/random device
+#
+/dev/random
+#
+# 2 The /dev/urandom device
+#
+/dev/urandom
+$!end
+};
+
+
+
+/** Flag: Already seeded.
+*/
+static int dk4rnd_seeded = 0;
+
+
+
+#if !DK4_HAVE_OPENSSL_RAND_H
+#if DK4_HAVE_RANDOM || DK4_HAVE_LRAND48 || DK4_HAVE_RAND
+
+/** Attempt to obtain seed data.
+ @param bptr Buffer pointer.
+ @param sz Buffer size.
+ @return 1 on success, 0 on error.
+
+*/
+static
+int
+dk4rnd_find_seed_data(void *bptr, size_t sz)
+{
+#if DK4_ON_WINDOWS
+ HCRYPTPROV hcp; /* Crypto provider */
+ BOOL res; /* Operation result */
+#else
+#if DK4_HAVE_SOCKET
+ struct sockaddr_un soun; /* Unix domain socket addr */
+ socklen_t szs; /* Socket length */
+ ssize_t sobytes; /* Bytes obtained */
+ int udsock; /* Unix domain socket */
+#endif
+ char *egdsn = NULL;
+#endif
+ FILE *fipo;
+ size_t rdb;
+ int back = 0;
+
+ /* EGD socket
+ */
+#if !DK4_ON_WINDOWS
+ egdsn = getenv(dk4rnd_kwnl[0]);
+ if (NULL != egdsn) {
+ if (108 > strlen(egdsn)) {
+ udsock = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (-1 < udsock) {
+ soun.sun_family = AF_UNIX;
+ strcpy(soun.sun_path, egdsn);
+ szs = sizeof(struct sockaddr_un) - sizeof(soun.sun_path)
+ + strlen(soun.sun_path);
+ if (0 == connect(udsock, (const struct sockaddr *)(&soun), szs)) {
+ sobytes = recv(udsock, bptr, sz, 0);
+ if (0 < sobytes) {
+ if ((size_t)sobytes == sz) {
+ back = 1;
+ }
+ } else { $? "! recv"
+ }
+ } else { $? "! connect"
+ }
+ close(udsock);
+ } else { $? "! socket"
+ }
+ } else { $? "! name too long"
+ }
+ } else { $? "! not env var"
+ }
+ if (1 == back) { goto finished; }
+#endif
+
+ /* System mechanisms.
+ */
+#if DK4_ON_WINDOWS
+ res = CryptAcquireContext(
+ &hcp, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT
+ );
+ if (res) {
+ res = CryptGenRandom(hcp, (DWORD)sz, bptr);
+ if (res) {
+ back = 1;
+ }
+ CryptReleaseContext(hcp, (DWORD)0L);
+ }
+#else
+ fipo = fopen(dk4rnd_kwnl[1], "rb");
+ if (NULL != fipo) {
+ rdb = fread(bptr, 1, sz, fipo);
+ fclose(fipo);
+ if ((0 < rdb) && (sz == rdb)) {
+ back = 1;
+ }
+ } else {
+ fipo = fopen(dk4rnd_kwnl[2], "rb");
+ if (NULL != fipo) {
+ rdb = fread(bptr, 1, sz, fipo);
+ fclose(fipo);
+ if ((0 < rdb) && (sz == rdb)) {
+ back = 1;
+ }
+ }
+ }
+#endif
+ finished:
+ return back;
+}
+
+#endif
+#endif
+
+
+#if DK4_HAVE_OPENSSL_RAND_H
+ /* +++++ OpenSSL available */
+
+int
+dk4rnd_init(dk4_er_t *erp)
+{
+ char sbuf[256]; /* Buffer for seed data */
+#if DK4_ON_WINDOWS
+ HCRYPTPROV hcp;
+#endif
+ FILE *fipo = NULL; /* Input file */
+ size_t rdb = 0; /* Number of bytes read */
+ char *egdsn = NULL; /* EGD socket name */
+ int back = 0;
+#if DK4_ON_WINDOWS
+ BOOL res = FALSE;
+#endif
+
+ /* Let OpenSSL initialize itself.
+ */
+ if (1 == RAND_status()) {
+ back = 1; goto finished;
+ }
+
+ /* Attempt EGD socket.
+ */
+#if DK4_HAVE_RAND_EGD && DK4_HAVE_STRUCT_SOCKADDR_UN
+ egdsn = getenv(dk4rnd_kwnl[0]);
+ if (NULL != egdsn) {
+ RAND_egd(egdsn);
+ if (1 == RAND_status()) {
+ back = 1; goto finished;
+ }
+ }
+#endif
+
+ /* Attempt native mechanisms.
+ */
+#if DK4_ON_WINDOWS
+ res = CryptAcquireContext(
+ &hcp, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT
+ );
+ if (res) {
+ res = CryptGenRandom(hcp, (DWORD)sizeof(sbuf), sbuf);
+ if (res) {
+ RAND_seed(sbuf, sizeof(sbuf));
+ if (1 == RAND_status()) {
+ back = 1;
+ }
+ }
+ CryptReleaseContext(hcp, (DWORD)0L);
+ }
+ if (1 == back) { goto finished; }
+#else
+ fipo = fopen(dk4rnd_kwnl[1], "rb");
+ if (NULL != fipo) {
+ rdb = fread(sbuf, 1, sizeof(sbuf), fipo);
+ fclose(fipo);
+ if (rdb > 0) {
+ RAND_seed(sbuf, rdb);
+ if (1 == RAND_status()) {
+ back = 1; goto finished;
+ }
+ }
+ } else {
+ fipo = fopen(dk4rnd_kwnl[2], "rb");
+ if (NULL != fipo) {
+ rdb = fread(sbuf, 1, sizeof(sbuf), fipo);
+ fclose(fipo);
+ if (rdb > 0) {
+ RAND_seed(sbuf, rdb);
+ if (1 == RAND_status()) {
+ back = 1; goto finished;
+ }
+ }
+ }
+ }
+#endif
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+finished:
+ if (1 == back) {
+ dk4rnd_seeded = 1;
+ }
+ return back;
+}
+
+int
+dk4rnd_get_data(void *bptr, size_t bs, dk4_er_t *erp)
+{
+ int back = 0;
+ if ((NULL != bptr) && (0 < bs)) {
+ if ((dk4_um_t)bs <= (dk4_um_t)INT_MAX) {
+ if (0 != dk4rnd_seeded) {
+ back = RAND_bytes(bptr, (int)bs);
+ if (1 > back) {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+void
+dk4rnd_cleanup(void)
+{
+ RAND_cleanup();
+ dk4rnd_seeded = 0;
+}
+
+ /* ----- OpenSSL available */
+#else
+#if DK4_HAVE_RANDOM
+ /* +++++ initstate(), setstate() and random() available */
+
+/** State array.
+*/
+static char dk4rnd_random_state[256];
+
+/** The initial state array.
+*/
+static char *dk4rnd_old_state = NULL;
+
+int
+dk4rnd_init(dk4_er_t *erp)
+{
+ unsigned int sv; /* Seed value */
+ int back = 0;
+
+ if (0 != dk4rnd_find_seed_data(&sv, sizeof(sv))) {
+ DK4_MEMRES(dk4rnd_random_state, sizeof(dk4rnd_random_state));
+ if (NULL == dk4rnd_old_state) {
+ dk4rnd_old_state = initstate(sv, dk4rnd_random_state, 256);
+ } else {
+ (void)initstate(sv, dk4rnd_random_state, 256);
+ }
+ back = 1;
+ }
+ if (1 == back) { dk4rnd_seeded = 1; }
+ return back;
+}
+
+int
+dk4rnd_get_data(void *bptr, size_t bs, dk4_er_t *erp)
+{
+ int back = 0;
+ if ((NULL != bptr) && (0 < bs)) {
+ if (0 != dk4rnd_seeded) {
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+void
+dk4rnd_cleanup(void)
+{
+}
+
+ /* ----- initstate(), setstate() and random() available */
+#else
+#if DK4_HAVE_LRAND48
+ /* +++++ lrand48(), nrand48() and seed48() available */
+
+int
+dk4rnd_init(dk4_er_t *erp)
+{
+ int back = 0;
+finished:
+ if (1 == back) { dk4rnd_seeded = 1; }
+ return back;
+}
+
+int
+dk4rnd_get_data(void *bptr, size_t bs, dk4_er_t *erp)
+{
+ int back = 0;
+ if ((NULL != bptr) && (0 < bs)) {
+ if (0 != dk4rnd_seeded) {
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+void
+dk4rnd_cleanup(void)
+{
+}
+
+ /* ----- lrand48(), nrand48() and seed48() available */
+#else
+#if DK4_HAVE_RAND
+ /* +++++ rand() and srand() available */
+
+int
+dk4rnd_init(dk4_er_t *erp)
+{
+ int back = 0;
+
+finished:
+ if (1 == back) { dk4rnd_seeded = 1; }
+ return back;
+}
+
+int
+dk4rnd_get_data(void *bptr, size_t bs, dk4_er_t *erp)
+{
+ int back = 0;
+ if ((NULL != bptr) && (0 < bs)) {
+ if (0 != dk4rnd_seeded) {
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+void
+dk4rnd_cleanup(void)
+{
+}
+
+ /* ----- rand() and srand() available */
+#else
+ /* +++++ no PRNG available */
+
+int
+dk4rnd_init(dk4_er_t *erp)
+{
+ int back = 0;
+ return back;
+}
+
+int
+dk4rnd_get_data(void *bptr, size_t bs, dk4_er_t *erp)
+{
+ int back = 0;
+ if ((NULL != bptr) && (0 < bs)) {
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+void
+dk4rnd_cleanup(void)
+{
+}
+
+ /* ----- no PRNG available */
+#endif
+#endif
+#endif
+#endif
+
+int
+dk4rnd_get_prng_type(void)
+{
+ return dk4rnd_used_type;
+}
+
diff --git a/support/dktools/dk-pwg-rnd.h b/support/dktools/dk-pwg-rnd.h
new file mode 100644
index 0000000000..4140297103
--- /dev/null
+++ b/support/dktools/dk-pwg-rnd.h
@@ -0,0 +1,129 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk-pwg-rnd.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK_PWG_RND_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK_PWG_RND_H_INCLUDED 1
+
+
+#line 10 "dk-pwg-rnd.ctr"
+
+/** @file dk4rnd.h Random number generation.
+
+NOT A GOOD IDEA: WE EITHER NEED CRYPTOGRAPHICALLY STRONG RANDOM DATA
+OR LIGHTWEIGHT RANDOM DATA FOR GAMES OR SIMULATIONS.
+ONE SIZE DOESN'T FIT ALL!
+*/
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve PRNG type.
+ @return PRNG type.
+*/
+int
+dk4rnd_get_prng_type(void);
+
+/** Initialize (seed) PRNG.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_NOT_FOUND<br>
+ if the function failed to obtain seed data.
+*/
+int
+dk4rnd_init(dk4_er_t *erp);
+
+/** Retrieve random bytes.
+ @param bptr Pointer to destination buffer.
+ @param bs Destination buffer size.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if bptr is NULL or bs is either 0 or too large,
+ - DK4_E_SYNTAX<br>
+ if the PRNG was not yet initialized successfully,
+ - DK4_E_NOT_FOUND<br>
+ if the function failed to obtain random data.
+*/
+int
+dk4rnd_get_data(void *bptr, size_t bs, dk4_er_t *erp);
+
+/** Clean up PRNG.
+*/
+void
+dk4rnd_cleanup(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** Random number generators.
+*/
+enum {
+ /** Use rand() function.
+ */
+ DK4_PRNG_SIMPLE = 1,
+
+ /** Use nrand48() function.
+ */
+ DK4_PRNG_RAND48 = 2,
+
+ /** Use initstate()/setstate() functions.
+ */
+ DK4_PRNG_STATE = 4,
+
+ /** Use OpenSSL PRNG.
+ */
+ DK4_PRNG_OPENSSL = 8,
+
+ /** All the PRNGs above.
+ */
+ DK4_PRNG_ALL = (
+ DK4_PRNG_SIMPLE
+ | DK4_PRNG_RAND48
+ | DK4_PRNG_STATE
+ | DK4_PRNG_OPENSSL
+ )
+
+};
+
+
+#endif
diff --git a/support/dktools/dk-pwgen.c b/support/dktools/dk-pwgen.c
new file mode 100644
index 0000000000..b5ef2d4f14
--- /dev/null
+++ b/support/dktools/dk-pwgen.c
@@ -0,0 +1,2179 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk-pwgen.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk-pwgen.c The dk-pwgen module.
+*/
+
+
+#line 10 "dk-pwgen.ctr"
+
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+/** Allow use of the getenv() function. */
+#define _CRT_SECURE_NO_WARNINGS 1
+#endif
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#ifndef WINCRYPT_H_INCLUDED
+#include <wincrypt.h>
+#define WINCRYPT_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_OPENSSL_RAND_H
+#ifndef OPENSSL_RAND_H_INCLUDED
+#include <openssl/rand.h>
+#define OPENSSL_RAND_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4mem.h"
+#include "dk4mema.h"
+#include "dk4memrs.h"
+#include "dk4strd.h"
+#include "dk4app.h"
+#include "dk4aopt.h"
+#include "dk4fput.h"
+#include "dk4vers.h"
+#include "dk4maiddsz.h"
+#include "dk4maasz.h"
+#include "dk4mpl.h"
+#include "dk4svbufa.h"
+
+
+
+
+
+#line 97 "dk-pwgen.ctr"
+
+
+
+/** Output mode.
+*/
+enum {
+ /** Create normal user password.
+ */
+ DK_PWGEN_MODE_NORMAL = 0 ,
+
+ /** Create hard password.
+ */
+ DK_PWGEN_MODE_HARD ,
+
+ /** Create binary data.
+ */
+ DK_PWGEN_MODE_BINARY ,
+
+ /** Create hexadecimal key, use
+ lower case a to f.
+ */
+ DK_PWGEN_MODE_HEX_LOWER ,
+
+ /** Create hexadecimal key, use
+ upper case A to F.
+ */
+ DK_PWGEN_MODE_HEX_UPPER ,
+
+ /** Create numeric PIN.
+ */
+ DK_PWGEN_MODE_PIN
+};
+
+
+/** Constant texts used by program, not localized.
+*/
+static const dkChar * const dk_pwgen_kwnl[] = {
+/* 0 */
+dkT("dktools"),
+
+/* 1 */
+dkT("dk-pwgen.txt"),
+
+/* 2 */
+dkT("dk-pwgen.str"),
+
+/* 3 */
+dkT("0123456789abcdef"),
+
+/* 4 */
+dkT("0123456789ABCDEF"),
+
+/* 5 */
+dkT("0123456789"),
+
+/* 6 */
+dkT("-_.:,;<>|#'+*~@^!\"$%&/()=?`{[]}"),
+
+/* 7 */
+dkT("rand.egd.name"),
+
+/* 8 */
+dkT("verbose"),
+
+NULL
+
+
+#line 167 "dk-pwgen.ctr"
+};
+
+
+
+static const dkChar * const dk_pwgen_help_text[] = {
+dkT(""),
+dkT("Generate passwords, PINs and hexadecimal keys"),
+dkT(""),
+dkT("dk-pwgen [<options>]"),
+dkT(""),
+dkT("Options:"),
+dkT("-h\t\t--hard\t\t\tCreate hard password instead of normal."),
+dkT("-b\t\t--binary\t\tCreate binary random data"),
+dkT("\t\t\t\t\t(not on Windows)."),
+dkT("-p\t\t--pin\t\t\tCreate PIN number."),
+dkT("-x\t\t--hex\t\t\tCreate hexadecimal key, use `a'...`f'."),
+dkT("-X\t\t--Hex\t\t\tCreate hexadecimal key, use `A'...`F'."),
+dkT("-l <range>\t--length=<range>\tLength, i.e. ``8-10''."),
+dkT("-u <range>\t--upper-case=<range>\tNumber of uppercase chars in passwords."),
+dkT("-d <range>\t--digits=<range>\tNumber of digits in passwords."),
+dkT("-s <range>\t--special=<range>\tNumber of special chars in passwords."),
+dkT("-n\t\t--no-newline\t\tSuppress newline after output."),
+dkT("\t\t--verbose\t\tShow error message on SIGPIPE."),
+dkT(""),
+dkT("\t\t--help\t\t\tShow this short help text."),
+dkT("\t\t--manual\t\t*** SHOW FULL MANUAL. ***"),
+dkT("\t\t--version\t\tShow version information."),
+dkT("\t\t--license\t\tShow license information."),
+dkT(""),
+dkT("http://dktools.sourceforge.net"),
+dkT(""),
+NULL
+
+
+#line 200 "dk-pwgen.ctr"
+};
+
+
+
+static const dkChar * const dk_pwgen_license_text[] = {
+dkT("This software uses code from the following projects, either directly or as"),
+dkT("a library:"),
+dkT(""),
+dkT("dktools\t\tDirk Krause's tools and libraries."),
+dkT("\t\tSee http://dktools.sourceforge.net/ for more information."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT("zlib\t\tData compression library."),
+dkT("\t\tSee http://www.zlib.net/ for more information."),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT("bzip2\t\tData compression program and library."),
+dkT("\t\tSee http://www.bzip.org/ for more information."),
+#endif
+#if DK4_HAVE_OPENSSL_RAND_H
+dkT(""),
+dkT("OpenSSL\t\tCryptographic toolkit, used to build file checksums here."),
+dkT("\t\tSee http://www.openssl.org/ for more information."),
+dkT(""),
+dkT("This product includes software developed by the OpenSSL Project for use in"),
+dkT("the OpenSSL Toolkit (http://www.openssl.org/)."),
+dkT("This product includes cryptographic software written by"),
+dkT("Eric Young (eay@cryptsoft.com)."),
+dkT("This product includes software written by Tim Hudson (tjh@cryptsoft.com)."),
+#endif
+dkT(""),
+dkT("All the licenses below apply to the program."),
+dkT("Licenses for used libraries are shown as found on my Scientific Linux 6.x"),
+dkT("computer in the /usr/share/doc directory on 2015-04-01. Check the project"),
+dkT("homepages of the used libraries for additional information and/or updated"),
+dkT("license terms."),
+dkT(""),
+dkT(""),
+dkT("DK tools and libraries license"),
+dkT("=============================="),
+dkT("Copyright (c) 2015-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above copyright notice,"),
+dkT(" this list of conditions and the following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("* Neither the name of the Dirk Krause nor the names of contributors may be"),
+dkT(" used to endorse or promote products derived from this software without"),
+dkT(" specific prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\""),
+dkT("AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED."),
+dkT(""),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,"),
+dkT("INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,"),
+dkT("BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,"),
+dkT("DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY"),
+dkT("OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,"),
+dkT("EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT(""),
+dkT("Zlib license"),
+dkT("============"),
+dkT("(C) 1995-2004 Jean-loup Gailly and Mark Adler"),
+dkT(""),
+dkT("This software is provided 'as-is', without any express or implied"),
+dkT("warranty. In no event will the authors be held liable for any damages"),
+dkT("arising from the use of this software."),
+dkT(""),
+dkT("Permission is granted to anyone to use this software for any purpose,"),
+dkT("including commercial applications, and to alter it and redistribute it"),
+dkT("freely, subject to the following restrictions:"),
+dkT(""),
+dkT("1. The origin of this software must not be misrepresented; you must not"),
+dkT(" claim that you wrote the original software. If you use this software"),
+dkT(" in a product, an acknowledgment in the product documentation would be"),
+dkT(" appreciated but is not required."),
+dkT("2. Altered source versions must be plainly marked as such, and must not be"),
+dkT(" misrepresented as being the original software."),
+dkT("3. This notice may not be removed or altered from any source distribution."),
+dkT(""),
+dkT("Jean-loup Gailly Mark Adler"),
+dkT("jloup@gzip.org madler@alumni.caltech.edu"),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT(""),
+dkT("Bzip2 and libbzip2 library license"),
+dkT("=================================="),
+dkT("This program, \"bzip2\", the associated library \"libbzip2\", and all"),
+dkT("documentation, are copyright (C) 1996-2007 Julian R Seward. All"),
+dkT("rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions"),
+dkT("are met:"),
+dkT(""),
+dkT("1. Redistributions of source code must retain the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer."),
+dkT(""),
+dkT("2. The origin of this software must not be misrepresented; you must "),
+dkT(" not claim that you wrote the original software. If you use this "),
+dkT(" software in a product, an acknowledgment in the product "),
+dkT(" documentation would be appreciated but is not required."),
+dkT(""),
+dkT("3. Altered source versions must be plainly marked as such, and must"),
+dkT(" not be misrepresented as being the original software."),
+dkT(""),
+dkT("4. The name of the author may not be used to endorse or promote "),
+dkT(" products derived from this software without specific prior written "),
+dkT(" permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS"),
+dkT("OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED"),
+dkT("WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE"),
+dkT("GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS"),
+dkT("INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,"),
+dkT("WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS"),
+dkT("SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+dkT(""),
+dkT("Julian Seward, jseward@bzip.org"),
+dkT("bzip2/libbzip2 version 1.0.5 of 10 December 2007"),
+#endif
+#if DK4_HAVE_OPENSSL_RAND_H
+dkT(""),
+dkT(""),
+dkT("OpenSSL license"),
+dkT("==============="),
+dkT(""),
+dkT("LICENSE ISSUES"),
+dkT("--------------"),
+dkT(""),
+dkT("The OpenSSL toolkit stays under a dual license, i.e. both the conditions of"),
+dkT("the OpenSSL License and the original SSLeay license apply to the toolkit."),
+dkT("See below for the actual license texts. Actually both licenses are BSD-style"),
+dkT("Open Source licenses. In case of any license issues related to OpenSSL"),
+dkT("please contact openssl-core@openssl.org."),
+dkT(""),
+dkT("OpenSSL License"),
+dkT("---------------"),
+dkT(""),
+dkT("Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions"),
+dkT("are met:"),
+dkT(""),
+dkT("1. Redistributions of source code must retain the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer. "),
+dkT(""),
+dkT("2. Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in"),
+dkT(" the documentation and/or other materials provided with the"),
+dkT(" distribution."),
+dkT(""),
+dkT("3. All advertising materials mentioning features or use of this"),
+dkT(" software must display the following acknowledgment:"),
+dkT(" \"This product includes software developed by the OpenSSL Project"),
+dkT(" for use in the OpenSSL Toolkit. (http://www.openssl.org/)\""),
+dkT(""),
+dkT("4. The names \"OpenSSL Toolkit\" and \"OpenSSL Project\" must not be used to"),
+dkT(" endorse or promote products derived from this software without"),
+dkT(" prior written permission. For written permission, please contact"),
+dkT(" openssl-core@openssl.org."),
+dkT(""),
+dkT("5. Products derived from this software may not be called \"OpenSSL\""),
+dkT(" nor may \"OpenSSL\" appear in their names without prior written"),
+dkT(" permission of the OpenSSL Project."),
+dkT(""),
+dkT("6. Redistributions of any form whatsoever must retain the following"),
+dkT(" acknowledgment:"),
+dkT(" \"This product includes software developed by the OpenSSL Project"),
+dkT(" for use in the OpenSSL Toolkit (http://www.openssl.org/)\""),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY"),
+dkT("EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR"),
+dkT("PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR"),
+dkT("ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,"),
+dkT("SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT"),
+dkT("NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;"),
+dkT("LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)"),
+dkT("HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,"),
+dkT("STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)"),
+dkT("ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED"),
+dkT("OF THE POSSIBILITY OF SUCH DAMAGE."),
+dkT(""),
+dkT("This product includes cryptographic software written by Eric Young"),
+dkT("(eay@cryptsoft.com). This product includes software written by Tim"),
+dkT("Hudson (tjh@cryptsoft.com)."),
+dkT(""),
+dkT(""),
+dkT("Original SSLeay License"),
+dkT("-----------------------"),
+dkT(""),
+dkT("Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("This package is an SSL implementation written"),
+dkT("by Eric Young (eay@cryptsoft.com)."),
+dkT("The implementation was written so as to conform with Netscapes SSL."),
+dkT(""),
+dkT("This library is free for commercial and non-commercial use as long as"),
+dkT("the following conditions are aheared to. The following conditions"),
+dkT("apply to all code found in this distribution, be it the RC4, RSA,"),
+dkT("lhash, DES, etc., code; not just the SSL code. The SSL documentation"),
+dkT("included with this distribution is covered by the same copyright terms"),
+dkT("except that the holder is Tim Hudson (tjh@cryptsoft.com)."),
+dkT(""),
+dkT("Copyright remains Eric Young's, and as such any Copyright notices in"),
+dkT("the code are not to be removed."),
+dkT("If this package is used in a product, Eric Young should be given attribution"),
+dkT("as the author of the parts of the library used."),
+dkT("This can be in the form of a textual message at program startup or"),
+dkT("in documentation (online or textual) provided with the package."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions"),
+dkT("are met:"),
+dkT("1. Redistributions of source code must retain the copyright"),
+dkT(" notice, this list of conditions and the following disclaimer."),
+dkT("2. Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("3. All advertising materials mentioning features or use of this software"),
+dkT(" must display the following acknowledgement:"),
+dkT(" \"This product includes cryptographic software written by"),
+dkT(" Eric Young (eay@cryptsoft.com)\""),
+dkT(" The word 'cryptographic' can be left out if the rouines from the library"),
+dkT(" being used are not cryptographic related :-)."),
+dkT("4. If you include any Windows specific code (or a derivative thereof) from "),
+dkT(" the apps directory (application code) you must include an acknowledgement:"),
+dkT(" \"This product includes software written by Tim Hudson (tjh@cryptsoft.com)\""),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND"),
+dkT("ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE"),
+dkT("FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS"),
+dkT("OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)"),
+dkT("HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT"),
+dkT("LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY"),
+dkT("OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF"),
+dkT("SUCH DAMAGE."),
+dkT(""),
+dkT("The licence and distribution terms for any publically available version or"),
+dkT("derivative of this code cannot be changed. i.e. this code cannot simply be"),
+dkT("copied and put under another distribution licence"),
+dkT("[including the GNU Public Licence.]"),
+dkT(""),
+#endif
+dkT(""),
+NULL
+
+
+#line 469 "dk-pwgen.ctr"
+};
+
+
+
+static const dkChar * const dk_pwgen_kw_def[] = {
+/* 0 */
+dkT("OpenSSL PRNG not available!"),
+
+/* 1 */
+dkT("Failed to set up signal handlers!"),
+
+/* 2 */
+dkT("Failed to restore signal handlers!"),
+
+/* 3 */
+dkT("Numeric overflow while reading a size number!"),
+
+/* 4 */
+dkT("Not a size specification: \""),
+
+/* 5 */
+dkT("\"!"),
+
+/* 6 */
+dkT("Failed to retrieve size from text: \""),
+
+/* 7 */
+dkT("\"!"),
+
+/* 8 */
+dkT("Options -h, -x, -X, and -p are mutually exclusive!"),
+
+/* 9 */
+dkT("Option -u ignored for this output type!"),
+
+/* 10 */
+dkT("Option -d ignored for this output type!"),
+
+/* 11 */
+dkT("Option -s ignored for this output type!"),
+
+/* 12 */
+dkT("Conflicting ranges for -l and -u/-d/-s!"),
+
+/* 13 */
+dkT("Numeric overflow in password length calculation!"),
+
+/* 14 */
+dkT("Failed to obtain random data from cryptographic context!"),
+
+/* 15 */
+dkT("Failed to acquire cryptographic context!"),
+
+/* 16 */
+dkT("Failed to open /dev/random and /dev/urandom devices!"),
+
+/* 17 */
+dkT("Failed to obtain random data!"),
+
+/* 18 */
+dkT("Failed to seed OpenSSL PRNG!"),
+
+/* 19 */
+dkT("Aborted by SIGTERM signal!"),
+
+/* 20 */
+dkT("Aborted by SIGINT signal!"),
+
+/* 21 */
+dkT("Aborted by SIGPIPE signal!"),
+
+/* 22 */
+dkT("Write attempt to standard output failed!"),
+
+/* 23 */
+dkT("Seeding PRNG using OpenSSL builtin functions."),
+
+/* 24 */
+dkT("Seeding PRNG from EGD socket."),
+
+/* 25 */
+dkT("Seeding PRNG from Windows cryptographic context."),
+
+/* 26 */
+dkT("Seeding PRNG from screen contents."),
+
+/* 27 */
+dkT("Seeding PRNG from /dev/random or /dev/urandom device."),
+
+/* 28 */
+dkT("Seeding PRNG from EGD socket specified by preference."),
+
+/* 29 */
+dkT("Options -b, -h, -x, -X, and -p are mutually exclusive!"),
+
+/* 30 */
+dkT("Failed to reset used memory!"),
+
+/* 31 */
+dkT("The -b option is not supported on Windows!"),
+
+NULL
+
+
+#line 586 "dk-pwgen.ctr"
+};
+
+
+
+/** Options understood by program.
+*/
+static const dk4_option_specification_t dk_pwgen_options[] = {
+ { dkT('h'), dkT("hard"), DK4_OPT_ARG_NONE },
+ { dkT('b'), dkT("binary"), DK4_OPT_ARG_NONE },
+ { dkT('x'), dkT("hex"), DK4_OPT_ARG_NONE },
+ { dkT('X'), dkT("Hex"), DK4_OPT_ARG_NONE },
+ { dkT('p'), dkT("pin"), DK4_OPT_ARG_NONE },
+ { dkT('l'), dkT("length"), DK4_OPT_ARG_STRING },
+ { dkT('u'), dkT("upper-case"), DK4_OPT_ARG_STRING },
+ { dkT('d'), dkT("digits"), DK4_OPT_ARG_STRING },
+ { dkT('s'), dkT("special"), DK4_OPT_ARG_STRING },
+ { dkT('n'), dkT("no-newline"), DK4_OPT_ARG_NONE },
+ { dkT('\0'), dkT("verbose"), DK4_OPT_ARG_NONE }
+};
+
+
+
+#ifndef BUFSIZ
+#define BUFSIZ 8192
+#endif
+
+
+/** Use an explicitly specified buffer for stdout operations
+ so we can securely reset the memory before exiting.
+*/
+static char stdout_buffer[BUFSIZ];
+
+
+
+/** Use an explicitly specified buffer when reading seed file
+ so we can securely reset the memory before exiting.
+*/
+static char seed_file_buf[BUFSIZ];
+
+
+
+/** Localized version if available, otherwise default texts.
+*/
+static const dkChar * const *dk_pwgen_msg = dk_pwgen_kw_def;
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Number of elements in dk_pwgen_msg array.
+*/
+static size_t dk_pwgen_sz_msg =
+sizeof(dk_pwgen_kw_def)/sizeof(DK4_PCDKCHAR) - 1;
+
+
+/** Number of elements in dk_pwgen_options array.
+*/
+static const size_t dk_pwgen_sz_options =
+sizeof(dk_pwgen_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Minimum output length.
+*/
+static size_t length_min = 8;
+
+
+
+/** Maximum output length.
+*/
+static size_t length_max = 10;
+
+
+
+/** Output length to produce.
+*/
+static size_t length = 8;
+
+
+
+/** Minimum number of upper case characters.
+*/
+static size_t upper_min = 1;
+
+
+
+/** Maximum number of upper case characters.
+*/
+static size_t upper_max = 2;
+
+
+
+/** Number of upper case characters to produce.
+*/
+static size_t upper = 1;
+
+
+
+/** Minimum number of digits.
+*/
+static size_t digit_min = 1;
+
+
+
+/** Maximum number of digits.
+*/
+static size_t digit_max = 2;
+
+
+
+/** Number of digits to produce.
+*/
+static size_t digits = 1;
+
+
+
+/** Minimum number of special characters.
+*/
+static size_t special_min = 1;
+
+
+
+/** Maximum number of special characters.
+*/
+static size_t special_max = 2;
+
+
+
+/** Number of special characters to produce.
+*/
+static size_t specials = 1;
+
+
+
+/** Flag: Errors occured while writing to stdout.
+*/
+static int output_error = 0;
+
+
+
+/** Flag: Verbose output (report SIGPIPE).
+*/
+static int verbose = 1;
+
+
+
+/** Exit status code.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+/** Output type to produce.
+*/
+static int output_type = DK_PWGEN_MODE_NORMAL;
+
+
+
+#if DK4_HAVE_OPENSSL_RAND_H
+
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+/** Pass a volatile pointer to an atomic integer.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ptr Address of atomic integer variable.
+ @return The unmodified pointer.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+/** Check whether we can continue or if a signal was received.
+ @param check_pipe Flag: Check for occured SIGPIPE signal too.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(int check_pipe)
+{
+ int back = 1;
+#ifdef SIGPIPE
+ if (0 != check_pipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_int )) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+/** Check whether we can continue.
+ @return 1 for yes, 0 for no.
+*/
+static
+int
+dk_pwgen_can_continue(void)
+{
+ int back = 1;
+ if (0 == sig_can_continue(1)) {
+ back = 0;
+ }
+ return back;
+}
+
+
+
+/** Read range from text to size_t variables.
+ @param minptr Address of minimum variable.
+ @param maxptr Address of maximum variable.
+ @param buf Buffer containing the text.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk_pwgen_opt_range(size_t *minptr, size_t *maxptr, dkChar option)
+{
+ dkChar buf[32*sizeof(dk4_um_t)];
+ dk4_er_t er;
+ const dkChar *endptr;
+ dkChar *p1;
+ size_t val;
+ int res;
+ int rdf = 0;
+ int back = 0;
+ int passno = 0;
+
+
+#line 894 "dk-pwgen.ctr"
+ if (0 != dk4app_opt_is_set_long(app, dk_pwgen_kwnl[8], NULL)) {
+ verbose = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, option, NULL)) {
+ res = dk4app_opt_get_string_short(
+ buf, DK4_SIZEOF(buf,dkChar), app, option, NULL
+ );
+ if (0 != res) {
+
+#line 902 "dk-pwgen.ctr"
+ p1 = dk4str_chr(buf, dkT('-'));
+ if (NULL != p1) {
+
+#line 904 "dk-pwgen.ctr"
+ *(p1++) = dkT('\0');
+ p1 = dk4str_start(p1, NULL);
+ } else {
+
+#line 907 "dk-pwgen.ctr"
+ }
+ val = 0;
+ endptr = NULL;
+ dk4error_init(&er);
+ if (0 != dk4ma_input_dk_dec_size_t(&val, buf, &endptr, 1, &er)) {
+ *minptr = val;
+ *maxptr = val;
+ back = 1;
+ if (NULL != p1) {
+
+#line 916 "dk-pwgen.ctr"
+ passno = 1;
+ back = 0;
+ val = 0;
+ endptr = NULL;
+ if (0 != dk4ma_input_dk_dec_size_t(&val, p1, &endptr, 1, &er)) {
+ *maxptr = val;
+ back = 1;
+ if (*maxptr < *minptr) {
+ val = *maxptr;
+ *maxptr = *minptr;
+ *minptr = val;
+ }
+ } else {
+
+#line 929 "dk-pwgen.ctr"
+ /* ERROR: Failed to read size */
+ rdf = 1;
+ }
+ }
+ } else {
+
+#line 934 "dk-pwgen.ctr"
+ /* ERROR: Failed to read size */
+ rdf = 1;
+ }
+ } else {
+
+#line 938 "dk-pwgen.ctr"
+ /* ERROR: Failed to obtain option argument, probably bug */
+ }
+ } else {
+
+#line 941 "dk-pwgen.ctr"
+ back = 1;
+ }
+ if ((0 == back) && (0 != rdf)) {
+ switch (er.ec) {
+ case DK4_E_MATH_OVERFLOW : {
+
+#line 946 "dk-pwgen.ctr"
+ /* ERROR: Numeric overflow while reading number */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 3);
+ } break;
+ case DK4_E_SYNTAX : {
+
+#line 950 "dk-pwgen.ctr"
+ /* ERROR: Not a size specification */
+ dk4app_log_3(
+ app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 4, 5,
+ ((0 == passno) ? buf : p1)
+ );
+ } break;
+ default: {
+
+#line 957 "dk-pwgen.ctr"
+ /* ERROR: Failed to read size */
+ dk4app_log_3(
+ app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 6, 7,
+ ((0 == passno) ? buf : p1)
+ );
+ } break;
+ }
+ }
+
+#line 965 "dk-pwgen.ctr"
+ return back;
+}
+
+
+
+/** Process command line options.
+ @return 1 on success, 0 on error (invalid option combination).
+*/
+static
+int
+dk_pwgen_check_options(void)
+{
+ dk4_er_t er;
+ size_t val;
+ int back = 0;
+
+
+#line 981 "dk-pwgen.ctr"
+
+ if (0 != dk4app_opt_is_set_short(app, dkT('b'), NULL)) {
+ output_type = DK_PWGEN_MODE_BINARY;
+ if (
+ (0 != dk4app_opt_is_set_short(app, dkT('h'), NULL))
+ || (0 != dk4app_opt_is_set_short(app, dkT('x'), NULL))
+ || (0 != dk4app_opt_is_set_short(app, dkT('X'), NULL))
+ || (0 != dk4app_opt_is_set_short(app, dkT('p'), NULL))
+ )
+ {
+ /* ERROR: Options -b, -h, -x, -X and -p are mutually exclusive! */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 29);
+ goto finished;
+ }
+ else
+ {
+ back = 1;
+ }
+ } else {
+ if (0 != dk4app_opt_is_set_short(app, dkT('h'), NULL)) {
+ output_type = DK_PWGEN_MODE_HARD;
+ if (
+ (0 != dk4app_opt_is_set_short(app, dkT('x'), NULL))
+ || (0 != dk4app_opt_is_set_short(app, dkT('X'), NULL))
+ || (0 != dk4app_opt_is_set_short(app, dkT('p'), NULL))
+ )
+ {
+ /* ERROR: Options -h, -x, -X and -p are mutually exclusive! */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 8);
+ goto finished;
+ }
+ else
+ {
+ back = 1;
+ }
+ } else {
+ if (0 != dk4app_opt_is_set_short(app, dkT('x'), NULL)) {
+ output_type = DK_PWGEN_MODE_HEX_LOWER;
+ if (
+ (0 != dk4app_opt_is_set_short(app, dkT('X'), NULL))
+ || (0 != dk4app_opt_is_set_short(app, dkT('p'), NULL))
+ )
+ {
+ /* ERROR: Options -h, -x, -X and -p are mutually exclusive! */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 8);
+ goto finished;
+ }
+ else
+ {
+ back = 1;
+ }
+ } else {
+ if (0 != dk4app_opt_is_set_short(app, dkT('X'), NULL)) {
+ output_type = DK_PWGEN_MODE_HEX_UPPER;
+ if (0 != dk4app_opt_is_set_short(app, dkT('p'), NULL)) {
+ /* ERROR: Options -h, -x, -X and -p are mutually exclusive! */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 8);
+ goto finished;
+ } else {
+ back = 1;
+ }
+ } else {
+ if (0 != dk4app_opt_is_set_short(app, dkT('p'), NULL)) {
+ output_type = DK_PWGEN_MODE_PIN;
+ }
+ back = 1;
+ }
+ }
+ }
+ }
+ if (1 == back) {
+ if (0 == dk_pwgen_opt_range(&length_min, &length_max, dkT('l'))) {
+ back = 0;
+ }
+ if (1 == back) {
+ switch (output_type) {
+ case DK_PWGEN_MODE_HARD :
+ case DK_PWGEN_MODE_HEX_LOWER :
+ case DK_PWGEN_MODE_HEX_UPPER :
+ case DK_PWGEN_MODE_PIN :
+ {
+ if (0 != dk4app_opt_is_set_short(app, dkT('u'), NULL)) {
+ /* WARNING: Option ignored */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 9);
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('d'), NULL)) {
+ /* WARNING: Option ignored */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 10);
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('s'), NULL)) {
+ /* WARNING: Option ignored */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 11);
+ }
+ } break;
+ default : {
+ if (0 != dk_pwgen_opt_range(&upper_min, &upper_max, dkT('u'))) {
+ if (0 != dk_pwgen_opt_range(&digit_min, &digit_max, dkT('d'))) {
+ if (0 != dk_pwgen_opt_range(&special_min, &special_max, dkT('s')))
+ {
+ dk4error_init(&er);
+ val = dk4ma_size_t_add(upper_max, digit_max, &er);
+ val = dk4ma_size_t_add(val, special_max, &er);
+ if (DK4_E_NONE == er.ec) {
+ if (val > length_min) {
+ back = 0;
+ /* ERROR: Illegal range combination */
+ dk4app_log_1(
+ app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 12
+ );
+ }
+ } else {
+ /* ERROR: Numeric overflow in size calculation */
+ dk4app_log_1(
+ app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 13
+ );
+ }
+ } else {
+ back = 0;
+ }
+ } else {
+ back = 0;
+ }
+ } else {
+ back = 0;
+ }
+ } break;
+ }
+ }
+ }
+ finished:
+
+
+#line 1112 "dk-pwgen.ctr"
+ return back;
+}
+
+
+
+/** Seed PRNG.
+ @return 1 on success, 0 on error (not enough seed data).
+*/
+static
+int
+dk_pwgen_seed_prng(void)
+{
+#if DK4_CHAR_SIZE == 1
+ dkChar snb[DK4_MAX_PATH];
+#endif
+ char buffer[64];
+ char *envptr;
+#if DK4_ON_WINDOWS
+ HCRYPTPROV hcp;
+ BOOL res;
+#else
+ FILE *fipo;
+ size_t rdb;
+#endif
+ int cc;
+ int rounds = 0;
+ int back = 0;
+ int svbres = 0;
+
+
+#line 1141 "dk-pwgen.ctr"
+
+ /* Let OpenSSL library functions try to initialize.
+ */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_DEBUG, 23);
+ if (1 == RAND_status()) {
+ back = 1;
+ goto finished;
+ }
+
+#if DK4_HAVE_RAND_EGD && DK4_HAVE_STRUCT_SOCKADDR_UN
+ /* Attempt EGD socket if specified in environment.
+ */
+ envptr = getenv("EGDSOCKET");
+ if (NULL != envptr) {
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_DEBUG, 24);
+ if (0 < RAND_egd(envptr)) {
+ if (1 == RAND_status()) {
+ back = 1;
+ goto finished;
+ }
+ }
+ }
+
+ /* Attempt EGD socket defined by preference.
+ The RAND_egd() function accepts char, not dkChar.
+ */
+#if DK4_CHAR_SIZE == 1
+ if (0 != dk4app_pref_get(snb,DK4_SIZEOF(snb,dkChar),app,dk_pwgen_kwnl[7],0)) {
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_DEBUG, 28);
+ if (0 < RAND_egd(snb)) {
+ if (1 == RAND_status()) {
+ back = 1;
+ goto finished;
+ }
+ }
+ }
+#endif
+#endif
+
+ /* Use platform specific mechanisms if available.
+ */
+#if DK4_ON_WINDOWS
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_DEBUG, 25);
+ res = CryptAcquireContext(
+ &hcp, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT
+ );
+ if (res) {
+ cc = 1;
+ do {
+ if (0 != dk_pwgen_can_continue()) {
+ res = CryptGenRandom(hcp, (DWORD)sizeof(buffer), buffer);
+ if (res) {
+ RAND_seed(buffer, sizeof(buffer));
+ if (1 == RAND_status()) {
+ cc = 0;
+ back = 1;
+ } else {
+ rounds++;
+ }
+ } else {
+ cc = -1;
+ /* ERROR: Failed to obtain random bytes from crypto context */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 14);
+ }
+ } else {
+ cc = -1;
+ }
+ } while ((1 == cc) && (128 > rounds));
+ CryptReleaseContext(hcp, (DWORD)0UL);
+ dk4mem_reset_secure(buffer, sizeof(buffer), NULL);
+ if (0 == back) {
+ if (0 != dk_pwgen_can_continue()) {
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_DEBUG, 25);
+ RAND_screen();
+ if (1 == RAND_status()) {
+ back = 1;
+ }
+ }
+ }
+ } else {
+ /* ERROR: Failed to acquire crypto context */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 15);
+ }
+#else
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_DEBUG, 27);
+ fipo = fopen("/dev/random", "rb");
+ if (NULL == fipo) {
+ fipo = fopen("/dev/urandom", "rb");
+ }
+ if (NULL != fipo) {
+ dk4mem_reset(seed_file_buf, sizeof(seed_file_buf), NULL);
+ svbres = dk4setvbuf(
+ fipo, DK4_FILE_FULL_BUFFERING, seed_file_buf, sizeof(seed_file_buf), NULL
+ );
+ if (0 != svbres) {
+ cc = 1;
+ do {
+ if (0 != dk_pwgen_can_continue()) {
+ rdb = fread(buffer, 1, sizeof(buffer), fipo);
+ if (0 < rdb) {
+ RAND_seed(buffer, rdb);
+ if (1 == RAND_status()) {
+ cc = 0;
+ back = 1;
+ } else {
+ rounds++;
+ }
+ } else {
+ cc = -1;
+ }
+ } else {
+ cc = -1;
+ }
+ } while ((1 == cc) && (128 > rounds));
+ } else {
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 16);
+ }
+ fclose(fipo);
+ dk4mem_reset_secure(seed_file_buf, sizeof(seed_file_buf), NULL);
+ dk4mem_reset_secure(buffer, sizeof(buffer), NULL);
+ } else {
+ /* ERROR: Failed to open both /dev/random and /dev/urandom */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 16);
+ }
+#endif
+
+ finished:
+
+
+#line 1269 "dk-pwgen.ctr"
+ return back;
+}
+
+
+
+/** Find a random number in a given range.
+ @param dptr Address of destination variable.
+ @param min Minimum value.
+ @param max Maximum value.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk_pwgen_value_in_range(size_t *dptr, size_t min, size_t max)
+{
+ size_t width;
+ size_t rval;
+ int back = 0;
+
+
+#line 1288 "dk-pwgen.ctr"
+ if (max > min) {
+ width = max - min;
+ if (0 != (width + 1)) { width++ ; }
+ if (0 < RAND_bytes((unsigned char *)(&rval), (int)sizeof(rval))) {
+
+
+#line 1293 "dk-pwgen.ctr"
+ *dptr = min + (rval % width);
+ back = 1;
+ } else {
+ /* ERROR: Failed to obtain random bytes */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 17);
+ }
+ } else {
+ *dptr = min;
+ back = 1;
+ }
+
+
+#line 1304 "dk-pwgen.ctr"
+ return back;
+}
+
+
+
+/** Create hexadecimal key and write to standard output.
+ @param upper Flag: Use upper case `a' to `f'.
+*/
+static
+void
+dk_pwgen_output_hex(int upper)
+{
+ unsigned char buf[8]; /* Buffer for 8 random bytes */
+ size_t i; /* Index of current output character */
+ size_t bi; /* Index in buffer 0 to 7 */
+ size_t j; /* Index in hexademical digits string */
+ int cc; /* Flag: Can continue 1=yes,0=no,-1=abort */
+ dkChar dc; /* Current character to write */
+
+
+#line 1323 "dk-pwgen.ctr"
+ cc = 1;
+ i = 0;
+ bi = 0;
+ do {
+ if (0 != dk_pwgen_can_continue()) {
+ if (i < length) {
+
+
+
+ if (0 == (i % 16)) {
+ bi = 0;
+ if (0 < RAND_bytes(buf, (int)sizeof(buf))) {
+ cc = 1;
+ } else {
+ cc = -1;
+ exval = EXIT_FAILURE;
+ /* ERROR: Random */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 17);
+ }
+ }
+ if (1 == cc) {
+ j = (size_t)(buf[bi / 2]);
+ j = 0x00FFU & j;
+ if (0 == (i % 2)) {
+ j = j >> 4;
+ }
+ j &= 0x000FU;
+ dc = (dk_pwgen_kwnl[(0 != upper) ? 4 : 3])[j];
+ if (0 == dk4fputc(dc, stdout, NULL)) { output_error = 1; cc = -1; }
+ }
+ i++; bi++;
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = -1;
+ }
+ } while (1 == cc);
+ if (0 == dk4mem_reset_secure(buf, sizeof(buf), NULL)) {
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 30);
+ exval = EXIT_FAILURE;
+ }
+ dc = dkT('\0'); j = 0;
+ if ((0 != j) || (dkT('\0') != dc)) {
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 30);
+ exval = EXIT_FAILURE;
+ }
+
+
+#line 1371 "dk-pwgen.ctr"
+}
+
+
+
+/** Create hard password and write to standard output.
+*/
+static
+void
+dk_pwgen_output_hard(void)
+{
+ dk4_um_t val;
+ size_t i;
+ int cc;
+ dkChar dc;
+
+ i = 0; cc = 1;
+ do {
+ if (0 != dk_pwgen_can_continue()) {
+ if (i < length) {
+ if (0 < RAND_bytes((unsigned char *)(&val), (int)sizeof(dk4_um_t))) {
+ dc = (dkChar)33 + (dkChar)(val % (dk4_um_t)90U);
+ if (0 == dk4fputc(dc, stdout, NULL)) {
+ output_error = 1;
+ cc = -1;
+ }
+ } else {
+ cc = -1;
+ exval = EXIT_FAILURE;
+ /* ERROR: Random */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 17);
+ }
+ i++;
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = -1;
+ }
+ } while (1 == cc);
+ val = (dk4_um_t)0UL; dc = dkT('\0');
+ if ((val != (dk4_um_t)0UL) || (dc != dkT('\0'))) {
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 30);
+ exval = EXIT_FAILURE;
+ }
+}
+
+
+
+/** Create binary password and write to standard output.
+*/
+static
+void
+dk_pwgen_output_binary(void)
+{
+#if !DK4_ON_WINDOWS
+ char buf[256];
+ size_t i;
+ size_t remaining;
+ size_t wrb;
+ int cc;
+#endif
+
+#if DK4_ON_WINDOWS
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 31);
+ exval = EXIT_FAILURE;
+#else
+ remaining = length;
+ cc = 1;
+ do {
+ if (0 != dk_pwgen_can_continue()) {
+ i = sizeof(buf);
+ if (remaining < i) { i = remaining; }
+ if (0 == i) {
+ cc = 0;
+ } else {
+ if (0 < RAND_bytes((unsigned char *)buf, (int)i)) {
+ wrb = fwrite(buf, 1, i, stdout);
+ if (i == wrb) {
+ if (i >= remaining) {
+ cc = 0;
+ } else {
+ remaining = remaining - i;
+ }
+ } else {
+ cc = -1;
+ exval = EXIT_FAILURE;
+ output_error = 1;
+ }
+ } else {
+ cc = -1;
+ exval = EXIT_FAILURE;
+ /* ERROR: Random */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 17);
+ }
+ }
+ } else {
+ cc = -1;
+ }
+ } while ((1 == cc) && (0 < remaining));
+ if (0 != fflush(stdout)) {
+ exval = EXIT_FAILURE;
+ output_error = 1;
+ }
+ if (0 == dk4mem_reset_secure(buf, sizeof(buf), NULL)) {
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 30);
+ exval = EXIT_FAILURE;
+ }
+#endif
+}
+
+
+/** Create numeric PIN and write to standard output.
+*/
+static
+void
+dk_pwgen_output_pin(void)
+{
+ dk4_um_t val;
+ size_t i;
+ int cc;
+ dkChar dc;
+
+ i = 0; cc = 1;
+ do {
+ if (0 != dk_pwgen_can_continue()) {
+ if (i < length) {
+ if (0 < RAND_bytes((unsigned char *)(&val), (int)sizeof(dk4_um_t))) {
+ dc = dkT('0') + (dkChar)(val % (dk4_um_t)10U);
+ if (0 == dk4fputc(dc, stdout, NULL)) {
+ output_error = 1;
+ cc = -1;
+ }
+ } else {
+ cc = -1;
+ exval = EXIT_FAILURE;
+ /* ERROR: Random */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 17);
+ }
+ i++;
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = -1;
+ }
+ } while (1 == cc);
+ dc = dkT('\0');
+ if (dc != dkT('\0')) {
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 30);
+ exval = EXIT_FAILURE;
+ }
+}
+
+
+
+/** Create normal password and write to standard output.
+*/
+static
+void
+dk_pwgen_output_normal(void)
+{
+ char *ti = NULL; /* Cells */
+ dk4_um_t val; /* Value */
+ size_t avail; /* Number of unused cells */
+ size_t curel; /* Current element within group */
+ size_t ind_to_set; /* Index of unused cell to set */
+ size_t i; /* Traverse all cells */
+ size_t max; /* Number of elements within pass */
+ size_t speclen; /* Length of string containing special */
+ int passno; /* Current pass */
+ int cc; /* Flag: No error yet, can continue */
+ int res; /* Operation result */
+ dkChar dc; /* Character to write */
+ char ic; /* Indicator character */
+
+ ti = dk4mem_new_app(char,length,app);
+ if (NULL != ti) {
+
+#line 1548 "dk-pwgen.ctr"
+ DK4_MEMRES(ti, length);
+ cc = 1;
+ if (0 == dk_pwgen_value_in_range(&upper, upper_min, upper_max)) {
+ cc = 0;
+ }
+ if (0 == dk_pwgen_value_in_range(&digits, digit_min, digit_max)) {
+ cc = 0;
+ }
+ if (0 == dk_pwgen_value_in_range(&specials, special_min, special_max)) {
+ cc = 0;
+ }
+ if (1 == cc) {
+ passno = 0;
+ avail = length;
+ while (3 > passno) {
+
+#line 1563 "dk-pwgen.ctr"
+ switch (passno) {
+ case 2 : {
+ max = specials;
+ ic = 's';
+ } break;
+ case 1 : {
+ max = digits;
+ ic = 'd';
+ } break;
+ default : {
+ max = upper;
+ ic = 'u';
+ } break;
+ }
+ curel = 0;
+ while (curel < max) {
+
+
+#line 1580 "dk-pwgen.ctr"
+ if (0 != dk_pwgen_can_continue()) {
+ res = RAND_bytes(
+ (unsigned char *)(&ind_to_set), (int)sizeof(size_t)
+ );
+ if (0 < res) {
+ if (0 < avail) {
+ ind_to_set = ind_to_set % avail;
+
+
+#line 1588 "dk-pwgen.ctr"
+ res = 0;
+ i = 0;
+ while (i < length) {
+
+
+#line 1592 "dk-pwgen.ctr"
+ if ('\0' == ti[i]) {
+ if (0 == ind_to_set) {
+
+
+#line 1595 "dk-pwgen.ctr"
+ res = 1;
+ ti[i] = ic;
+ i = length - 1;
+ avail--;
+ } else {
+ ind_to_set--;
+ }
+ } else {
+
+#line 1603 "dk-pwgen.ctr"
+ }
+ i++;
+ }
+ curel++;
+ if (0 == res) {
+
+#line 1608 "dk-pwgen.ctr"
+ /* No free cell found */
+ curel = max; passno = 3; cc = 0;
+ dk4app_log_1(
+ app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 12
+ );
+ }
+ } else {
+ /* No more cells available */
+ curel = max; passno = 3; cc = 0;
+ dk4app_log_1(
+ app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 12
+ );
+ }
+ } else {
+ /* ERROR: Random data */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 17);
+ curel = max; passno = 3; cc = 0;
+ }
+ } else {
+ curel = max; passno = 3; cc = 0;
+ }
+ }
+ passno++;
+ if (0 == dk_pwgen_can_continue()) { passno = 3; }
+ }
+ if ((1 == cc) && (0 != dk_pwgen_can_continue())) {
+
+#line 1634 "dk-pwgen.ctr"
+ i = 0;
+ speclen = dk4str_len(dk_pwgen_kwnl[6]);
+
+
+#line 1637 "dk-pwgen.ctr"
+ while (i < length) {
+
+
+#line 1639 "dk-pwgen.ctr"
+ if (0 != dk_pwgen_can_continue()) {
+ res = RAND_bytes(
+ (unsigned char *)(&val), (int)sizeof(dk4_um_t)
+ );
+ if (0 < res) {
+
+
+#line 1645 "dk-pwgen.ctr"
+ switch (ti[i]) {
+ case 's': {
+ val = val % (dk4_um_t)speclen;
+
+
+#line 1649 "dk-pwgen.ctr"
+ dc = (dk_pwgen_kwnl[6])[(size_t)val];
+ } break;
+ case 'd': {
+ val = val % (dk4_um_t)10UL;
+ dc = dkT('0') + (dkChar)val;
+ } break;
+ case 'u': {
+ val = val % (dk4_um_t)26UL;
+ dc = dkT('A') + (dkChar)val;
+ } break;
+ default: {
+ val = val % (dk4_um_t)26UL;
+ dc = dkT('a') + (dkChar)val;
+ } break;
+ }
+ if (0 == dk4fputc(dc, stdout, NULL)) {
+ output_error = 1;
+ }
+ i++;
+ } else {
+ i = length;
+ exval = EXIT_FAILURE;
+ /* ERROR: Random */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 17);
+ }
+ } else {
+ i = length;
+ }
+ }
+ } else {
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ exval = EXIT_FAILURE;
+ /* Failed to obtain random */
+ }
+ if (0 == dk4mem_reset_secure(ti, length, NULL)) {
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 30);
+ exval = EXIT_FAILURE;
+ }
+ dk4mem_free(ti);
+ dc = dkT('\0');
+ if (dc != dkT('\0')) {
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 30);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+
+#line 1696 "dk-pwgen.ctr"
+ exval = EXIT_FAILURE;
+ /* ERROR: Memory, already reported */
+ }
+}
+
+
+
+/** Create password, PIN or key and write to output.
+*/
+static
+void
+dk_pwgen_produce_output(void)
+{
+
+
+#line 1710 "dk-pwgen.ctr"
+ if (0 != dk_pwgen_value_in_range(&length, length_min, length_max)) {
+ exval = EXIT_SUCCESS;
+ switch (output_type) {
+ case DK_PWGEN_MODE_BINARY : {
+
+#line 1714 "dk-pwgen.ctr"
+ dk_pwgen_output_binary();
+ } break;
+ case DK_PWGEN_MODE_HARD : {
+
+#line 1717 "dk-pwgen.ctr"
+ dk_pwgen_output_hard();
+ } break;
+ case DK_PWGEN_MODE_HEX_LOWER : {
+
+#line 1720 "dk-pwgen.ctr"
+ dk_pwgen_output_hex(0);
+ } break;
+ case DK_PWGEN_MODE_HEX_UPPER : {
+
+#line 1723 "dk-pwgen.ctr"
+ dk_pwgen_output_hex(1);
+ } break;
+ case DK_PWGEN_MODE_PIN : {
+
+#line 1726 "dk-pwgen.ctr"
+ dk_pwgen_output_pin();
+ } break;
+ default : {
+
+#line 1729 "dk-pwgen.ctr"
+ dk_pwgen_output_normal();
+ } break;
+ }
+ if (0 == dk4app_opt_is_set_short(app, dkT('n'), NULL)) {
+ if (DK_PWGEN_MODE_BINARY != output_type) {
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) {
+ output_error = 1;
+ }
+ }
+ }
+ }
+
+
+#line 1741 "dk-pwgen.ctr"
+}
+
+
+
+/** Run normally with signal handlers installed.
+*/
+static
+void
+dk_pwgen_normal_run(void)
+{
+
+
+#line 1752 "dk-pwgen.ctr"
+ if (0 < dk_pwgen_check_options()) {
+ if (0 < dk_pwgen_seed_prng()) {
+ dk_pwgen_produce_output();
+ } else {
+ /* ERROR: Failed to seed PRNG */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 18);
+ }
+ RAND_cleanup();
+ }
+
+
+#line 1762 "dk-pwgen.ctr"
+}
+
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+dk_pwgen_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ struct sigaction opipe;
+#endif
+ struct sigaction oint;
+#ifdef SIGPIPE
+ struct sigaction npipe;
+#endif
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+ int success = 0;
+
+#ifdef SIGPIPE
+ /* Set up signal handling for SIGPIPE.
+ */
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 1);
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 1);
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 1);
+ goto finished;
+ }
+#endif
+
+ /* Set up signal handling for SIGINT.
+ */
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 1);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 1);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 1);
+ goto restore_old_pipe;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 1);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 1);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 1);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ dk_pwgen_normal_run();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 2);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 2);
+ success = 0;
+ }
+
+#ifdef SIGPIPE
+ /* Restore signal handling for SIGPIPE.
+ */
+ restore_old_pipe:
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 2);
+ success = 0;
+ }
+#endif
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+dk_pwgen_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ dk_pwgen_normal_run();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+#ifdef SIGPIPE
+ sigset(SIGPIPE, oldpipe);
+#endif
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+dk_pwgen_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = signal(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ dk_pwgen_normal_run();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+#ifdef SIGPIPE
+ signal(SIGPIPE, oldpipe);
+#endif
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+dk_pwgen_run_with_signal_handlers(void)
+{
+ dk_pwgen_normal_run();
+}
+#endif
+#endif
+#endif
+
+#endif
+/* if DK4_HAVE_OPENSSL_RAND_H */
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ int shp;
+ int pbso; /* Flag: Private buffer used for stdout */
+
+ pbso = dk4setvbuf(
+ stdout, DK4_FILE_LINE_BUFFERING, stdout_buffer, sizeof(stdout_buffer), NULL
+ );
+
+
+#line 1975 "dk-pwgen.ctr"
+
+
+#line 1976 "dk-pwgen.ctr"
+ dk4fput_initialize_stdout();
+ dk4fput_initialize_stderr();
+ app = dk4app_open_cmd(
+ argc, argv, dk_pwgen_options, dk_pwgen_sz_options,
+ dk_pwgen_kwnl[0], DKT_VERSION_DK,
+ dk_pwgen_kwnl[1], dk_pwgen_help_text, dk_pwgen_license_text
+ );
+ if (NULL != app) {
+ dk_pwgen_sz_msg = dk4app_string_table_size(dk_pwgen_kw_def);
+ dk_pwgen_msg = dk4app_string_table(app,dk_pwgen_kwnl[2],dk_pwgen_kw_def);
+ if (0 != dk4app_can_run_normally(app)) {
+#if DK4_HAVE_OPENSSL_RAND_H
+ /*
+ Run.
+ */
+ dk_pwgen_run_with_signal_handlers();
+ /*
+ Report signals and output errors, if any.
+ */
+ if (0 != sig_read_atomic(&sig_had_term)) {
+ /* ERROR: SIGTERM signal received */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 19);
+ exval = EXIT_FAILURE;
+ }
+ if (0 != sig_read_atomic(&sig_had_int )) {
+ /* ERROR: SIGINT signal received */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 20);
+ exval = EXIT_FAILURE;
+ }
+#ifdef SIGPIPE
+ if (0 != sig_read_atomic(&sig_had_pipe)) {
+ /* ERROR: SIGPIPE signal received */
+ if (0 != verbose) {
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 21);
+ }
+ exval = EXIT_FAILURE;
+ shp = 1;
+ } else {
+ shp = 0;
+ }
+#else
+ shp = 0;
+#endif
+ if ((0 == shp) && (0 != output_error)) {
+ /* ERROR: Failed to write to stdout */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 22);
+ exval = EXIT_FAILURE;
+ }
+#else
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 0);
+#endif
+ if (0 == pbso) {
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 30);
+ exval = EXIT_FAILURE;
+ } else {
+#ifdef BUFSIZ
+ fflush(stdout);
+ if (0 == dk4mem_reset_secure(stdout_buffer,sizeof(stdout_buffer),NULL))
+ {
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 30);
+ exval = EXIT_FAILURE;
+ }
+#endif
+ }
+ } else {
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ dk4app_close(app);
+ } else {
+ }
+ fflush(stdout);
+ fflush(stderr);
+ dk4fput_cleanup_stderr();
+ dk4fput_cleanup_stdout();
+
+
+#line 2053 "dk-pwgen.ctr"
+
+
+#line 2054 "dk-pwgen.ctr"
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/dk-pwgen.ctr b/support/dktools/dk-pwgen.ctr
new file mode 100644
index 0000000000..c9e1e0dc7a
--- /dev/null
+++ b/support/dktools/dk-pwgen.ctr
@@ -0,0 +1,2056 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+/** Allow use of the getenv() function. */
+#define _CRT_SECURE_NO_WARNINGS 1
+#endif
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#ifndef WINCRYPT_H_INCLUDED
+#include <wincrypt.h>
+#define WINCRYPT_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_OPENSSL_RAND_H
+#ifndef OPENSSL_RAND_H_INCLUDED
+#include <openssl/rand.h>
+#define OPENSSL_RAND_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4mem.h"
+#include "dk4mema.h"
+#include "dk4memrs.h"
+#include "dk4strd.h"
+#include "dk4app.h"
+#include "dk4aopt.h"
+#include "dk4fput.h"
+#include "dk4vers.h"
+#include "dk4maiddsz.h"
+#include "dk4maasz.h"
+#include "dk4mpl.h"
+#include "dk4svbufa.h"
+
+
+
+$!trace-include
+
+
+
+/** Output mode.
+*/
+enum {
+ /** Create normal user password.
+ */
+ DK_PWGEN_MODE_NORMAL = 0 ,
+
+ /** Create hard password.
+ */
+ DK_PWGEN_MODE_HARD ,
+
+ /** Create binary data.
+ */
+ DK_PWGEN_MODE_BINARY ,
+
+ /** Create hexadecimal key, use
+ lower case a to f.
+ */
+ DK_PWGEN_MODE_HEX_LOWER ,
+
+ /** Create hexadecimal key, use
+ upper case A to F.
+ */
+ DK_PWGEN_MODE_HEX_UPPER ,
+
+ /** Create numeric PIN.
+ */
+ DK_PWGEN_MODE_PIN
+};
+
+
+/** Constant texts used by program, not localized.
+*/
+static const dkChar * const dk_pwgen_kwnl[] = {
+$!string-table macro=dkT
+#
+# 0 Program group name
+#
+dktools
+#
+# 1 Help text name
+#
+dk-pwgen.txt
+#
+# 2 String table name
+#
+dk-pwgen.str
+#
+# 3 4 5 Characters for hexadecimal output and PIN output
+#
+0123456789abcdef
+0123456789ABCDEF
+0123456789
+#
+# 6 Special characters
+#
+# -_.:,;<>|#'+*~@^°!"§$%&/()=?`{[]}
+-_.:,;<>|#'+*~@^!"$%&/()=?`{[]}
+#
+# 7 EGD socket preference name
+#
+rand.egd.name
+#
+# 8 Long option name for verbose mode.
+#
+verbose
+$!end
+};
+
+
+
+static const dkChar * const dk_pwgen_help_text[] = {
+$!text macro=dkT,preprocessor
+
+Generate passwords, PINs and hexadecimal keys
+
+dk-pwgen [<options>]
+
+Options:
+-h --hard Create hard password instead of normal.
+-b --binary Create binary random data
+ (not on Windows).
+-p --pin Create PIN number.
+-x --hex Create hexadecimal key, use `a'...`f'.
+-X --Hex Create hexadecimal key, use `A'...`F'.
+-l <range> --length=<range> Length, i.e. ``8-10''.
+-u <range> --upper-case=<range> Number of uppercase chars in passwords.
+-d <range> --digits=<range> Number of digits in passwords.
+-s <range> --special=<range> Number of special chars in passwords.
+-n --no-newline Suppress newline after output.
+ --verbose Show error message on SIGPIPE.
+
+ --help Show this short help text.
+ --manual *** SHOW FULL MANUAL. ***
+ --version Show version information.
+ --license Show license information.
+
+http://dktools.sourceforge.net
+
+$!end
+};
+
+
+
+static const dkChar * const dk_pwgen_license_text[] = {
+$!text macro=dkT,preprocessor
+This software uses code from the following projects, either directly or as
+a library:
+
+dktools Dirk Krause's tools and libraries.
+ See http://dktools.sourceforge.net/ for more information.
+#if DK4_HAVE_ZLIB_H
+
+zlib Data compression library.
+ See http://www.zlib.net/ for more information.
+#endif
+#if DK4_HAVE_BZLIB_H
+
+bzip2 Data compression program and library.
+ See http://www.bzip.org/ for more information.
+#endif
+#if DK4_HAVE_OPENSSL_RAND_H
+
+OpenSSL Cryptographic toolkit, used to build file checksums here.
+ See http://www.openssl.org/ for more information.
+
+This product includes software developed by the OpenSSL Project for use in
+the OpenSSL Toolkit (http://www.openssl.org/).
+This product includes cryptographic software written by
+Eric Young (eay@cryptsoft.com).
+This product includes software written by Tim Hudson (tjh@cryptsoft.com).
+#endif
+
+All the licenses below apply to the program.
+Licenses for used libraries are shown as found on my Scientific Linux 6.x
+computer in the /usr/share/doc directory on 2015-04-01. Check the project
+homepages of the used libraries for additional information and/or updated
+license terms.
+
+
+DK tools and libraries license
+==============================
+Copyright (c) 2015-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#if DK4_HAVE_ZLIB_H
+
+
+Zlib license
+============
+(C) 1995-2004 Jean-loup Gailly and Mark Adler
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+
+Jean-loup Gailly Mark Adler
+jloup@gzip.org madler@alumni.caltech.edu
+#endif
+#if DK4_HAVE_BZLIB_H
+
+
+Bzip2 and libbzip2 library license
+==================================
+This program, "bzip2", the associated library "libbzip2", and all
+documentation, are copyright (C) 1996-2007 Julian R Seward. All
+rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+3. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Julian Seward, jseward@bzip.org
+bzip2/libbzip2 version 1.0.5 of 10 December 2007
+#endif
+#if DK4_HAVE_OPENSSL_RAND_H
+
+
+OpenSSL license
+===============
+
+LICENSE ISSUES
+--------------
+
+The OpenSSL toolkit stays under a dual license, i.e. both the conditions of
+the OpenSSL License and the original SSLeay license apply to the toolkit.
+See below for the actual license texts. Actually both licenses are BSD-style
+Open Source licenses. In case of any license issues related to OpenSSL
+please contact openssl-core@openssl.org.
+
+OpenSSL License
+---------------
+
+Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+3. All advertising materials mentioning features or use of this
+ software must display the following acknowledgment:
+ "This product includes software developed by the OpenSSL Project
+ for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+
+4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ endorse or promote products derived from this software without
+ prior written permission. For written permission, please contact
+ openssl-core@openssl.org.
+
+5. Products derived from this software may not be called "OpenSSL"
+ nor may "OpenSSL" appear in their names without prior written
+ permission of the OpenSSL Project.
+
+6. Redistributions of any form whatsoever must retain the following
+ acknowledgment:
+ "This product includes software developed by the OpenSSL Project
+ for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+
+THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+OF THE POSSIBILITY OF SUCH DAMAGE.
+
+This product includes cryptographic software written by Eric Young
+(eay@cryptsoft.com). This product includes software written by Tim
+Hudson (tjh@cryptsoft.com).
+
+
+Original SSLeay License
+-----------------------
+
+Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+All rights reserved.
+
+This package is an SSL implementation written
+by Eric Young (eay@cryptsoft.com).
+The implementation was written so as to conform with Netscapes SSL.
+
+This library is free for commercial and non-commercial use as long as
+the following conditions are aheared to. The following conditions
+apply to all code found in this distribution, be it the RC4, RSA,
+lhash, DES, etc., code; not just the SSL code. The SSL documentation
+included with this distribution is covered by the same copyright terms
+except that the holder is Tim Hudson (tjh@cryptsoft.com).
+
+Copyright remains Eric Young's, and as such any Copyright notices in
+the code are not to be removed.
+If this package is used in a product, Eric Young should be given attribution
+as the author of the parts of the library used.
+This can be in the form of a textual message at program startup or
+in documentation (online or textual) provided with the package.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. All advertising materials mentioning features or use of this software
+ must display the following acknowledgement:
+ "This product includes cryptographic software written by
+ Eric Young (eay@cryptsoft.com)"
+ The word 'cryptographic' can be left out if the rouines from the library
+ being used are not cryptographic related :-).
+4. If you include any Windows specific code (or a derivative thereof) from
+ the apps directory (application code) you must include an acknowledgement:
+ "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+
+THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+The licence and distribution terms for any publically available version or
+derivative of this code cannot be changed. i.e. this code cannot simply be
+copied and put under another distribution licence
+[including the GNU Public Licence.]
+
+#endif
+
+$!end
+};
+
+
+
+static const dkChar * const dk_pwgen_kw_def[] = {
+$!string-table macro=dkT
+#
+# 0 Error: OpenSSL PRNG not available!
+#
+OpenSSL PRNG not available!
+#
+# 1 Error: Failed to set up signal handlers!
+#
+Failed to set up signal handlers!
+#
+# 2 Error: Failed to restore signal handlers!
+#
+Failed to restore signal handlers!
+#
+# 3 Error: Numeric overflow while reading a size number!
+#
+Numeric overflow while reading a size number!
+#
+# 4 5 Error: Not a size specification: "..."!
+#
+Not a size specification: "
+"!
+#
+# 6 7 Error: Failed to retrieve size from text: "..."!
+#
+Failed to retrieve size from text: "
+"!
+#
+# 8 Error: Options -h, -x, -X, and -p are mutually exclusive!
+#
+Options -h, -x, -X, and -p are mutually exclusive!
+#
+# 9 10 11 Error: Option -u ignored for this output type!
+#
+Option -u ignored for this output type!
+Option -d ignored for this output type!
+Option -s ignored for this output type!
+#
+# 12 Error: Illegal range combination for -l, -u, -d, -s!
+#
+Conflicting ranges for -l and -u/-d/-s!
+#
+# 13 Error: Numeric overflow in password length calculation!
+#
+Numeric overflow in password length calculation!
+#
+# 14 Error: Failed to obtain random data from cryptographic context!
+#
+Failed to obtain random data from cryptographic context!
+#
+# 15 Error: Failed to acquire cryptographic context!
+#
+Failed to acquire cryptographic context!
+#
+# 16 Error: Failed to open /dev/random and /dev/urandom devices!
+#
+Failed to open /dev/random and /dev/urandom devices!
+#
+# 17 Error: Failed to obtain random data!
+#
+Failed to obtain random data!
+#
+# 18 Error: Failed to seed OpenSSL PRNG!
+#
+Failed to seed OpenSSL PRNG!
+#
+# 19 20 21 Error: Aborted by SIGTERM signal!
+#
+Aborted by SIGTERM signal!
+Aborted by SIGINT signal!
+Aborted by SIGPIPE signal!
+#
+# 22 Error: Write attempt to standard output failed!
+#
+Write attempt to standard output failed!
+#
+# 23 Debug: Seeding PRNG using OpenSSL builtin functions.
+#
+Seeding PRNG using OpenSSL builtin functions.
+#
+# 24 Debug: Seeding PRNG from EGD socket.
+#
+Seeding PRNG from EGD socket.
+#
+# 25 Debug: Seeding PRNG from Windows cryptographic context.
+#
+Seeding PRNG from Windows cryptographic context.
+#
+# 26 Debug: Seeding PRNG from screen contents.
+#
+Seeding PRNG from screen contents.
+#
+# 27 Debug: Seeding PRNG from /dev/random or /dev/urandom device.
+#
+Seeding PRNG from /dev/random or /dev/urandom device.
+#
+# 28 Debug: Seeding PRNG from EGD socket specified by preference.
+#
+Seeding PRNG from EGD socket specified by preference.
+#
+# 29 ERROR: Options -b, -h, -x, -X, and -p are mutually exclusive!
+#
+Options -b, -h, -x, -X, and -p are mutually exclusive!
+#
+# 30 ERROR: Failed to reset used memory!
+#
+Failed to reset used memory!
+#
+# 31 ERROR: The -b option is not supported on Windows!
+#
+The -b option is not supported on Windows!
+$!end
+};
+
+
+
+/** Options understood by program.
+*/
+static const dk4_option_specification_t dk_pwgen_options[] = {
+ { dkT('h'), dkT("hard"), DK4_OPT_ARG_NONE },
+ { dkT('b'), dkT("binary"), DK4_OPT_ARG_NONE },
+ { dkT('x'), dkT("hex"), DK4_OPT_ARG_NONE },
+ { dkT('X'), dkT("Hex"), DK4_OPT_ARG_NONE },
+ { dkT('p'), dkT("pin"), DK4_OPT_ARG_NONE },
+ { dkT('l'), dkT("length"), DK4_OPT_ARG_STRING },
+ { dkT('u'), dkT("upper-case"), DK4_OPT_ARG_STRING },
+ { dkT('d'), dkT("digits"), DK4_OPT_ARG_STRING },
+ { dkT('s'), dkT("special"), DK4_OPT_ARG_STRING },
+ { dkT('n'), dkT("no-newline"), DK4_OPT_ARG_NONE },
+ { dkT('\0'), dkT("verbose"), DK4_OPT_ARG_NONE }
+};
+
+
+
+#ifndef BUFSIZ
+#define BUFSIZ 8192
+#endif
+
+
+/** Use an explicitly specified buffer for stdout operations
+ so we can securely reset the memory before exiting.
+*/
+static char stdout_buffer[BUFSIZ];
+
+
+
+/** Use an explicitly specified buffer when reading seed file
+ so we can securely reset the memory before exiting.
+*/
+static char seed_file_buf[BUFSIZ];
+
+
+
+/** Localized version if available, otherwise default texts.
+*/
+static const dkChar * const *dk_pwgen_msg = dk_pwgen_kw_def;
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Number of elements in dk_pwgen_msg array.
+*/
+static size_t dk_pwgen_sz_msg =
+sizeof(dk_pwgen_kw_def)/sizeof(DK4_PCDKCHAR) - 1;
+
+
+/** Number of elements in dk_pwgen_options array.
+*/
+static const size_t dk_pwgen_sz_options =
+sizeof(dk_pwgen_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Minimum output length.
+*/
+static size_t length_min = 8;
+
+
+
+/** Maximum output length.
+*/
+static size_t length_max = 10;
+
+
+
+/** Output length to produce.
+*/
+static size_t length = 8;
+
+
+
+/** Minimum number of upper case characters.
+*/
+static size_t upper_min = 1;
+
+
+
+/** Maximum number of upper case characters.
+*/
+static size_t upper_max = 2;
+
+
+
+/** Number of upper case characters to produce.
+*/
+static size_t upper = 1;
+
+
+
+/** Minimum number of digits.
+*/
+static size_t digit_min = 1;
+
+
+
+/** Maximum number of digits.
+*/
+static size_t digit_max = 2;
+
+
+
+/** Number of digits to produce.
+*/
+static size_t digits = 1;
+
+
+
+/** Minimum number of special characters.
+*/
+static size_t special_min = 1;
+
+
+
+/** Maximum number of special characters.
+*/
+static size_t special_max = 2;
+
+
+
+/** Number of special characters to produce.
+*/
+static size_t specials = 1;
+
+
+
+/** Flag: Errors occured while writing to stdout.
+*/
+static int output_error = 0;
+
+
+
+/** Flag: Verbose output (report SIGPIPE).
+*/
+static int verbose = 1;
+
+
+
+/** Exit status code.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+/** Output type to produce.
+*/
+static int output_type = DK_PWGEN_MODE_NORMAL;
+
+
+
+#if DK4_HAVE_OPENSSL_RAND_H
+
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+/** Pass a volatile pointer to an atomic integer.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ptr Address of atomic integer variable.
+ @return The unmodified pointer.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+/** Check whether we can continue or if a signal was received.
+ @param check_pipe Flag: Check for occured SIGPIPE signal too.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(int check_pipe)
+{
+ int back = 1;
+#ifdef SIGPIPE
+ if (0 != check_pipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_int )) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+/** Check whether we can continue.
+ @return 1 for yes, 0 for no.
+*/
+static
+int
+dk_pwgen_can_continue(void)
+{
+ int back = 1;
+ if (0 == sig_can_continue(1)) {
+ back = 0;
+ }
+ return back;
+}
+
+
+
+/** Read range from text to size_t variables.
+ @param minptr Address of minimum variable.
+ @param maxptr Address of maximum variable.
+ @param buf Buffer containing the text.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk_pwgen_opt_range(size_t *minptr, size_t *maxptr, dkChar option)
+{
+ dkChar buf[32*sizeof(dk4_um_t)];
+ dk4_er_t er;
+ const dkChar *endptr;
+ dkChar *p1;
+ size_t val;
+ int res;
+ int rdf = 0;
+ int back = 0;
+ int passno = 0;
+ $? "+ dk_pwgen_opt_range"
+ if (0 != dk4app_opt_is_set_long(app, dk_pwgen_kwnl[8], NULL)) {
+ verbose = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, option, NULL)) {
+ res = dk4app_opt_get_string_short(
+ buf, DK4_SIZEOF(buf,dkChar), app, option, NULL
+ );
+ if (0 != res) { $? ". opt args ok"
+ p1 = dk4str_chr(buf, dkT('-'));
+ if (NULL != p1) { $? ". minimum and maximum"
+ *(p1++) = dkT('\0');
+ p1 = dk4str_start(p1, NULL);
+ } else { $? ". just value"
+ }
+ val = 0;
+ endptr = NULL;
+ dk4error_init(&er);
+ if (0 != dk4ma_input_dk_dec_size_t(&val, buf, &endptr, 1, &er)) {
+ *minptr = val;
+ *maxptr = val;
+ back = 1;
+ if (NULL != p1) { $? ". retrieve maximum"
+ passno = 1;
+ back = 0;
+ val = 0;
+ endptr = NULL;
+ if (0 != dk4ma_input_dk_dec_size_t(&val, p1, &endptr, 1, &er)) {
+ *maxptr = val;
+ back = 1;
+ if (*maxptr < *minptr) {
+ val = *maxptr;
+ *maxptr = *minptr;
+ *minptr = val;
+ }
+ } else { $? "! failed to retrieve value"
+ /* ERROR: Failed to read size */
+ rdf = 1;
+ }
+ }
+ } else { $? "! failed to read value"
+ /* ERROR: Failed to read size */
+ rdf = 1;
+ }
+ } else { $? "! bug, failed to retrieve opt args"
+ /* ERROR: Failed to obtain option argument, probably bug */
+ }
+ } else { $? ". option not set"
+ back = 1;
+ }
+ if ((0 == back) && (0 != rdf)) {
+ switch (er.ec) {
+ case DK4_E_MATH_OVERFLOW : { $? "! overflow"
+ /* ERROR: Numeric overflow while reading number */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 3);
+ } break;
+ case DK4_E_SYNTAX : { $? "! syntax"
+ /* ERROR: Not a size specification */
+ dk4app_log_3(
+ app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 4, 5,
+ ((0 == passno) ? buf : p1)
+ );
+ } break;
+ default: { $? "! other problem"
+ /* ERROR: Failed to read size */
+ dk4app_log_3(
+ app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 6, 7,
+ ((0 == passno) ? buf : p1)
+ );
+ } break;
+ }
+ } $? "- dk_pwgen_opt_range %u %u %d", (unsigned)(*minptr), (unsigned)(*maxptr), back
+ return back;
+}
+
+
+
+/** Process command line options.
+ @return 1 on success, 0 on error (invalid option combination).
+*/
+static
+int
+dk_pwgen_check_options(void)
+{
+ dk4_er_t er;
+ size_t val;
+ int back = 0;
+ $? "+ dk_pwgen_check_options"
+
+ if (0 != dk4app_opt_is_set_short(app, dkT('b'), NULL)) {
+ output_type = DK_PWGEN_MODE_BINARY;
+ if (
+ (0 != dk4app_opt_is_set_short(app, dkT('h'), NULL))
+ || (0 != dk4app_opt_is_set_short(app, dkT('x'), NULL))
+ || (0 != dk4app_opt_is_set_short(app, dkT('X'), NULL))
+ || (0 != dk4app_opt_is_set_short(app, dkT('p'), NULL))
+ )
+ {
+ /* ERROR: Options -b, -h, -x, -X and -p are mutually exclusive! */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 29);
+ goto finished;
+ }
+ else
+ {
+ back = 1;
+ }
+ } else {
+ if (0 != dk4app_opt_is_set_short(app, dkT('h'), NULL)) {
+ output_type = DK_PWGEN_MODE_HARD;
+ if (
+ (0 != dk4app_opt_is_set_short(app, dkT('x'), NULL))
+ || (0 != dk4app_opt_is_set_short(app, dkT('X'), NULL))
+ || (0 != dk4app_opt_is_set_short(app, dkT('p'), NULL))
+ )
+ {
+ /* ERROR: Options -h, -x, -X and -p are mutually exclusive! */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 8);
+ goto finished;
+ }
+ else
+ {
+ back = 1;
+ }
+ } else {
+ if (0 != dk4app_opt_is_set_short(app, dkT('x'), NULL)) {
+ output_type = DK_PWGEN_MODE_HEX_LOWER;
+ if (
+ (0 != dk4app_opt_is_set_short(app, dkT('X'), NULL))
+ || (0 != dk4app_opt_is_set_short(app, dkT('p'), NULL))
+ )
+ {
+ /* ERROR: Options -h, -x, -X and -p are mutually exclusive! */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 8);
+ goto finished;
+ }
+ else
+ {
+ back = 1;
+ }
+ } else {
+ if (0 != dk4app_opt_is_set_short(app, dkT('X'), NULL)) {
+ output_type = DK_PWGEN_MODE_HEX_UPPER;
+ if (0 != dk4app_opt_is_set_short(app, dkT('p'), NULL)) {
+ /* ERROR: Options -h, -x, -X and -p are mutually exclusive! */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 8);
+ goto finished;
+ } else {
+ back = 1;
+ }
+ } else {
+ if (0 != dk4app_opt_is_set_short(app, dkT('p'), NULL)) {
+ output_type = DK_PWGEN_MODE_PIN;
+ }
+ back = 1;
+ }
+ }
+ }
+ }
+ if (1 == back) {
+ if (0 == dk_pwgen_opt_range(&length_min, &length_max, dkT('l'))) {
+ back = 0;
+ }
+ if (1 == back) {
+ switch (output_type) {
+ case DK_PWGEN_MODE_HARD :
+ case DK_PWGEN_MODE_HEX_LOWER :
+ case DK_PWGEN_MODE_HEX_UPPER :
+ case DK_PWGEN_MODE_PIN :
+ {
+ if (0 != dk4app_opt_is_set_short(app, dkT('u'), NULL)) {
+ /* WARNING: Option ignored */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 9);
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('d'), NULL)) {
+ /* WARNING: Option ignored */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 10);
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('s'), NULL)) {
+ /* WARNING: Option ignored */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 11);
+ }
+ } break;
+ default : {
+ if (0 != dk_pwgen_opt_range(&upper_min, &upper_max, dkT('u'))) {
+ if (0 != dk_pwgen_opt_range(&digit_min, &digit_max, dkT('d'))) {
+ if (0 != dk_pwgen_opt_range(&special_min, &special_max, dkT('s')))
+ {
+ dk4error_init(&er);
+ val = dk4ma_size_t_add(upper_max, digit_max, &er);
+ val = dk4ma_size_t_add(val, special_max, &er);
+ if (DK4_E_NONE == er.ec) {
+ if (val > length_min) {
+ back = 0;
+ /* ERROR: Illegal range combination */
+ dk4app_log_1(
+ app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 12
+ );
+ }
+ } else {
+ /* ERROR: Numeric overflow in size calculation */
+ dk4app_log_1(
+ app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 13
+ );
+ }
+ } else {
+ back = 0;
+ }
+ } else {
+ back = 0;
+ }
+ } else {
+ back = 0;
+ }
+ } break;
+ }
+ }
+ }
+ finished:
+ $? "- dk_pwgen_check_options %d", back
+ return back;
+}
+
+
+
+/** Seed PRNG.
+ @return 1 on success, 0 on error (not enough seed data).
+*/
+static
+int
+dk_pwgen_seed_prng(void)
+{
+#if DK4_CHAR_SIZE == 1
+ dkChar snb[DK4_MAX_PATH];
+#endif
+ char buffer[64];
+ char *envptr;
+#if DK4_ON_WINDOWS
+ HCRYPTPROV hcp;
+ BOOL res;
+#else
+ FILE *fipo;
+ size_t rdb;
+#endif
+ int cc;
+ int rounds = 0;
+ int back = 0;
+ int svbres = 0;
+ $? "+ dk_pwgen_seed_prng"
+
+ /* Let OpenSSL library functions try to initialize.
+ */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_DEBUG, 23);
+ if (1 == RAND_status()) {
+ back = 1;
+ goto finished;
+ }
+
+#if DK4_HAVE_RAND_EGD && DK4_HAVE_STRUCT_SOCKADDR_UN
+ /* Attempt EGD socket if specified in environment.
+ */
+ envptr = getenv("EGDSOCKET");
+ if (NULL != envptr) {
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_DEBUG, 24);
+ if (0 < RAND_egd(envptr)) {
+ if (1 == RAND_status()) {
+ back = 1;
+ goto finished;
+ }
+ }
+ }
+
+ /* Attempt EGD socket defined by preference.
+ The RAND_egd() function accepts char, not dkChar.
+ */
+#if DK4_CHAR_SIZE == 1
+ if (0 != dk4app_pref_get(snb,DK4_SIZEOF(snb,dkChar),app,dk_pwgen_kwnl[7],0)) {
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_DEBUG, 28);
+ if (0 < RAND_egd(snb)) {
+ if (1 == RAND_status()) {
+ back = 1;
+ goto finished;
+ }
+ }
+ }
+#endif
+#endif
+
+ /* Use platform specific mechanisms if available.
+ */
+#if DK4_ON_WINDOWS
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_DEBUG, 25);
+ res = CryptAcquireContext(
+ &hcp, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT
+ );
+ if (res) {
+ cc = 1;
+ do {
+ if (0 != dk_pwgen_can_continue()) {
+ res = CryptGenRandom(hcp, (DWORD)sizeof(buffer), buffer);
+ if (res) {
+ RAND_seed(buffer, sizeof(buffer));
+ if (1 == RAND_status()) {
+ cc = 0;
+ back = 1;
+ } else {
+ rounds++;
+ }
+ } else {
+ cc = -1;
+ /* ERROR: Failed to obtain random bytes from crypto context */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 14);
+ }
+ } else {
+ cc = -1;
+ }
+ } while ((1 == cc) && (128 > rounds));
+ CryptReleaseContext(hcp, (DWORD)0UL);
+ dk4mem_reset_secure(buffer, sizeof(buffer), NULL);
+ if (0 == back) {
+ if (0 != dk_pwgen_can_continue()) {
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_DEBUG, 25);
+ RAND_screen();
+ if (1 == RAND_status()) {
+ back = 1;
+ }
+ }
+ }
+ } else {
+ /* ERROR: Failed to acquire crypto context */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 15);
+ }
+#else
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_DEBUG, 27);
+ fipo = fopen("/dev/random", "rb");
+ if (NULL == fipo) {
+ fipo = fopen("/dev/urandom", "rb");
+ }
+ if (NULL != fipo) {
+ dk4mem_reset(seed_file_buf, sizeof(seed_file_buf), NULL);
+ svbres = dk4setvbuf(
+ fipo, DK4_FILE_FULL_BUFFERING, seed_file_buf, sizeof(seed_file_buf), NULL
+ );
+ if (0 != svbres) {
+ cc = 1;
+ do {
+ if (0 != dk_pwgen_can_continue()) {
+ rdb = fread(buffer, 1, sizeof(buffer), fipo);
+ if (0 < rdb) {
+ RAND_seed(buffer, rdb);
+ if (1 == RAND_status()) {
+ cc = 0;
+ back = 1;
+ } else {
+ rounds++;
+ }
+ } else {
+ cc = -1;
+ }
+ } else {
+ cc = -1;
+ }
+ } while ((1 == cc) && (128 > rounds));
+ } else {
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 16);
+ }
+ fclose(fipo);
+ dk4mem_reset_secure(seed_file_buf, sizeof(seed_file_buf), NULL);
+ dk4mem_reset_secure(buffer, sizeof(buffer), NULL);
+ } else {
+ /* ERROR: Failed to open both /dev/random and /dev/urandom */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 16);
+ }
+#endif
+
+ finished:
+ $? "- dk_pwgen_seed_prng %d", back
+ return back;
+}
+
+
+
+/** Find a random number in a given range.
+ @param dptr Address of destination variable.
+ @param min Minimum value.
+ @param max Maximum value.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk_pwgen_value_in_range(size_t *dptr, size_t min, size_t max)
+{
+ size_t width;
+ size_t rval;
+ int back = 0;
+ $? "+ dk_pwgen_value_in_range %u %u", (unsigned)min, (unsigned)max
+ if (max > min) {
+ width = max - min;
+ if (0 != (width + 1)) { width++ ; }
+ if (0 < RAND_bytes((unsigned char *)(&rval), (int)sizeof(rval))) {
+ $? ". rval = %u width = %u", (unsigned)rval, (unsigned)width
+ *dptr = min + (rval % width);
+ back = 1;
+ } else {
+ /* ERROR: Failed to obtain random bytes */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 17);
+ }
+ } else {
+ *dptr = min;
+ back = 1;
+ }
+ $? "- dk_pwgen_value_in_range %d %u", back, (unsigned)(*dptr)
+ return back;
+}
+
+
+
+/** Create hexadecimal key and write to standard output.
+ @param upper Flag: Use upper case `a' to `f'.
+*/
+static
+void
+dk_pwgen_output_hex(int upper)
+{
+ unsigned char buf[8]; /* Buffer for 8 random bytes */
+ size_t i; /* Index of current output character */
+ size_t bi; /* Index in buffer 0 to 7 */
+ size_t j; /* Index in hexademical digits string */
+ int cc; /* Flag: Can continue 1=yes,0=no,-1=abort */
+ dkChar dc; /* Current character to write */
+ $? "+ dk_pwgen_output_hex upper=%d", upper
+ cc = 1;
+ i = 0;
+ bi = 0;
+ do {
+ if (0 != dk_pwgen_can_continue()) {
+ if (i < length) {
+
+
+
+ if (0 == (i % 16)) {
+ bi = 0;
+ if (0 < RAND_bytes(buf, (int)sizeof(buf))) {
+ cc = 1;
+ } else {
+ cc = -1;
+ exval = EXIT_FAILURE;
+ /* ERROR: Random */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 17);
+ }
+ }
+ if (1 == cc) {
+ j = (size_t)(buf[bi / 2]);
+ j = 0x00FFU & j;
+ if (0 == (i % 2)) {
+ j = j >> 4;
+ }
+ j &= 0x000FU;
+ dc = (dk_pwgen_kwnl[(0 != upper) ? 4 : 3])[j];
+ if (0 == dk4fputc(dc, stdout, NULL)) { output_error = 1; cc = -1; }
+ }
+ i++; bi++;
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = -1;
+ }
+ } while (1 == cc);
+ if (0 == dk4mem_reset_secure(buf, sizeof(buf), NULL)) {
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 30);
+ exval = EXIT_FAILURE;
+ }
+ dc = dkT('\0'); j = 0;
+ if ((0 != j) || (dkT('\0') != dc)) {
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 30);
+ exval = EXIT_FAILURE;
+ }
+ $? "- dk_pwgen_output_hex"
+}
+
+
+
+/** Create hard password and write to standard output.
+*/
+static
+void
+dk_pwgen_output_hard(void)
+{
+ dk4_um_t val;
+ size_t i;
+ int cc;
+ dkChar dc;
+
+ i = 0; cc = 1;
+ do {
+ if (0 != dk_pwgen_can_continue()) {
+ if (i < length) {
+ if (0 < RAND_bytes((unsigned char *)(&val), (int)sizeof(dk4_um_t))) {
+ dc = (dkChar)33 + (dkChar)(val % (dk4_um_t)90U);
+ if (0 == dk4fputc(dc, stdout, NULL)) {
+ output_error = 1;
+ cc = -1;
+ }
+ } else {
+ cc = -1;
+ exval = EXIT_FAILURE;
+ /* ERROR: Random */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 17);
+ }
+ i++;
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = -1;
+ }
+ } while (1 == cc);
+ val = (dk4_um_t)0UL; dc = dkT('\0');
+ if ((val != (dk4_um_t)0UL) || (dc != dkT('\0'))) {
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 30);
+ exval = EXIT_FAILURE;
+ }
+}
+
+
+
+/** Create binary password and write to standard output.
+*/
+static
+void
+dk_pwgen_output_binary(void)
+{
+#if !DK4_ON_WINDOWS
+ char buf[256];
+ size_t i;
+ size_t remaining;
+ size_t wrb;
+ int cc;
+#endif
+
+#if DK4_ON_WINDOWS
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 31);
+ exval = EXIT_FAILURE;
+#else
+ remaining = length;
+ cc = 1;
+ do {
+ if (0 != dk_pwgen_can_continue()) {
+ i = sizeof(buf);
+ if (remaining < i) { i = remaining; }
+ if (0 == i) {
+ cc = 0;
+ } else {
+ if (0 < RAND_bytes((unsigned char *)buf, (int)i)) {
+ wrb = fwrite(buf, 1, i, stdout);
+ if (i == wrb) {
+ if (i >= remaining) {
+ cc = 0;
+ } else {
+ remaining = remaining - i;
+ }
+ } else {
+ cc = -1;
+ exval = EXIT_FAILURE;
+ output_error = 1;
+ }
+ } else {
+ cc = -1;
+ exval = EXIT_FAILURE;
+ /* ERROR: Random */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 17);
+ }
+ }
+ } else {
+ cc = -1;
+ }
+ } while ((1 == cc) && (0 < remaining));
+ if (0 != fflush(stdout)) {
+ exval = EXIT_FAILURE;
+ output_error = 1;
+ }
+ if (0 == dk4mem_reset_secure(buf, sizeof(buf), NULL)) {
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 30);
+ exval = EXIT_FAILURE;
+ }
+#endif
+}
+
+
+/** Create numeric PIN and write to standard output.
+*/
+static
+void
+dk_pwgen_output_pin(void)
+{
+ dk4_um_t val;
+ size_t i;
+ int cc;
+ dkChar dc;
+
+ i = 0; cc = 1;
+ do {
+ if (0 != dk_pwgen_can_continue()) {
+ if (i < length) {
+ if (0 < RAND_bytes((unsigned char *)(&val), (int)sizeof(dk4_um_t))) {
+ dc = dkT('0') + (dkChar)(val % (dk4_um_t)10U);
+ if (0 == dk4fputc(dc, stdout, NULL)) {
+ output_error = 1;
+ cc = -1;
+ }
+ } else {
+ cc = -1;
+ exval = EXIT_FAILURE;
+ /* ERROR: Random */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 17);
+ }
+ i++;
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = -1;
+ }
+ } while (1 == cc);
+ dc = dkT('\0');
+ if (dc != dkT('\0')) {
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 30);
+ exval = EXIT_FAILURE;
+ }
+}
+
+
+
+/** Create normal password and write to standard output.
+*/
+static
+void
+dk_pwgen_output_normal(void)
+{
+ char *ti = NULL; /* Cells */
+ dk4_um_t val; /* Value */
+ size_t avail; /* Number of unused cells */
+ size_t curel; /* Current element within group */
+ size_t ind_to_set; /* Index of unused cell to set */
+ size_t i; /* Traverse all cells */
+ size_t max; /* Number of elements within pass */
+ size_t speclen; /* Length of string containing special */
+ int passno; /* Current pass */
+ int cc; /* Flag: No error yet, can continue */
+ int res; /* Operation result */
+ dkChar dc; /* Character to write */
+ char ic; /* Indicator character */
+
+ ti = dk4mem_new_app(char,length,app);
+ if (NULL != ti) { $? ". ti"
+ DK4_MEMRES(ti, length);
+ cc = 1;
+ if (0 == dk_pwgen_value_in_range(&upper, upper_min, upper_max)) {
+ cc = 0;
+ }
+ if (0 == dk_pwgen_value_in_range(&digits, digit_min, digit_max)) {
+ cc = 0;
+ }
+ if (0 == dk_pwgen_value_in_range(&specials, special_min, special_max)) {
+ cc = 0;
+ }
+ if (1 == cc) {
+ passno = 0;
+ avail = length;
+ while (3 > passno) { $? ". pass %d", passno
+ switch (passno) {
+ case 2 : {
+ max = specials;
+ ic = 's';
+ } break;
+ case 1 : {
+ max = digits;
+ ic = 'd';
+ } break;
+ default : {
+ max = upper;
+ ic = 'u';
+ } break;
+ }
+ curel = 0;
+ while (curel < max) {
+ $? ". element %u / %u", (unsigned)curel, (unsigned)max
+ if (0 != dk_pwgen_can_continue()) {
+ res = RAND_bytes(
+ (unsigned char *)(&ind_to_set), (int)sizeof(size_t)
+ );
+ if (0 < res) {
+ if (0 < avail) {
+ ind_to_set = ind_to_set % avail;
+ $? ". use free cell %u", (unsigned)ind_to_set
+ res = 0;
+ i = 0;
+ while (i < length) {
+ $? ". check cell %u", (unsigned)i
+ if ('\0' == ti[i]) {
+ if (0 == ind_to_set) {
+ $? ". use cell %u", (unsigned)i
+ res = 1;
+ ti[i] = ic;
+ i = length - 1;
+ avail--;
+ } else {
+ ind_to_set--;
+ }
+ } else { $? ". cell %u = %!8c", (unsigned)i, ti[i]
+ }
+ i++;
+ }
+ curel++;
+ if (0 == res) { $? "! no free cell found"
+ /* No free cell found */
+ curel = max; passno = 3; cc = 0;
+ dk4app_log_1(
+ app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 12
+ );
+ }
+ } else {
+ /* No more cells available */
+ curel = max; passno = 3; cc = 0;
+ dk4app_log_1(
+ app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 12
+ );
+ }
+ } else {
+ /* ERROR: Random data */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 17);
+ curel = max; passno = 3; cc = 0;
+ }
+ } else {
+ curel = max; passno = 3; cc = 0;
+ }
+ }
+ passno++;
+ if (0 == dk_pwgen_can_continue()) { passno = 3; }
+ }
+ if ((1 == cc) && (0 != dk_pwgen_can_continue())) { $? ". create output"
+ i = 0;
+ speclen = dk4str_len(dk_pwgen_kwnl[6]);
+ $? ". kw = \"%!ds\" speclen = %u", dk_pwgen_kwnl[6], (unsigned)speclen
+ while (i < length) {
+ $? ". i = %u", (unsigned)i
+ if (0 != dk_pwgen_can_continue()) {
+ res = RAND_bytes(
+ (unsigned char *)(&val), (int)sizeof(dk4_um_t)
+ );
+ if (0 < res) {
+ $? ". val = %ju", val
+ switch (ti[i]) {
+ case 's': {
+ val = val % (dk4_um_t)speclen;
+ $? ". val = %ju", val
+ dc = (dk_pwgen_kwnl[6])[(size_t)val];
+ } break;
+ case 'd': {
+ val = val % (dk4_um_t)10UL;
+ dc = dkT('0') + (dkChar)val;
+ } break;
+ case 'u': {
+ val = val % (dk4_um_t)26UL;
+ dc = dkT('A') + (dkChar)val;
+ } break;
+ default: {
+ val = val % (dk4_um_t)26UL;
+ dc = dkT('a') + (dkChar)val;
+ } break;
+ }
+ if (0 == dk4fputc(dc, stdout, NULL)) {
+ output_error = 1;
+ }
+ i++;
+ } else {
+ i = length;
+ exval = EXIT_FAILURE;
+ /* ERROR: Random */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 17);
+ }
+ } else {
+ i = length;
+ }
+ }
+ } else {
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ exval = EXIT_FAILURE;
+ /* Failed to obtain random */
+ }
+ if (0 == dk4mem_reset_secure(ti, length, NULL)) {
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 30);
+ exval = EXIT_FAILURE;
+ }
+ dk4mem_free(ti);
+ dc = dkT('\0');
+ if (dc != dkT('\0')) {
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 30);
+ exval = EXIT_FAILURE;
+ }
+ } else { $? "! ti"
+ exval = EXIT_FAILURE;
+ /* ERROR: Memory, already reported */
+ }
+}
+
+
+
+/** Create password, PIN or key and write to output.
+*/
+static
+void
+dk_pwgen_produce_output(void)
+{
+ $? "+ dk_pwgen_produce_output"
+ if (0 != dk_pwgen_value_in_range(&length, length_min, length_max)) {
+ exval = EXIT_SUCCESS;
+ switch (output_type) {
+ case DK_PWGEN_MODE_BINARY : { $? ". binary"
+ dk_pwgen_output_binary();
+ } break;
+ case DK_PWGEN_MODE_HARD : { $? ". hard"
+ dk_pwgen_output_hard();
+ } break;
+ case DK_PWGEN_MODE_HEX_LOWER : { $? ". hex lower"
+ dk_pwgen_output_hex(0);
+ } break;
+ case DK_PWGEN_MODE_HEX_UPPER : { $? ". hex upper"
+ dk_pwgen_output_hex(1);
+ } break;
+ case DK_PWGEN_MODE_PIN : { $? ". pin"
+ dk_pwgen_output_pin();
+ } break;
+ default : { $? ". normal"
+ dk_pwgen_output_normal();
+ } break;
+ }
+ if (0 == dk4app_opt_is_set_short(app, dkT('n'), NULL)) {
+ if (DK_PWGEN_MODE_BINARY != output_type) {
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) {
+ output_error = 1;
+ }
+ }
+ }
+ }
+ $? "- dk_pwgen_produce_output"
+}
+
+
+
+/** Run normally with signal handlers installed.
+*/
+static
+void
+dk_pwgen_normal_run(void)
+{
+ $? "+ dk_pwgen_normal_run"
+ if (0 < dk_pwgen_check_options()) {
+ if (0 < dk_pwgen_seed_prng()) {
+ dk_pwgen_produce_output();
+ } else {
+ /* ERROR: Failed to seed PRNG */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 18);
+ }
+ RAND_cleanup();
+ }
+ $? "- dk_pwgen_normal_run"
+}
+
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+dk_pwgen_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ struct sigaction opipe;
+#endif
+ struct sigaction oint;
+#ifdef SIGPIPE
+ struct sigaction npipe;
+#endif
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+ int success = 0;
+
+#ifdef SIGPIPE
+ /* Set up signal handling for SIGPIPE.
+ */
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 1);
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 1);
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 1);
+ goto finished;
+ }
+#endif
+
+ /* Set up signal handling for SIGINT.
+ */
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 1);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 1);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 1);
+ goto restore_old_pipe;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 1);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 1);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 1);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ dk_pwgen_normal_run();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 2);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 2);
+ success = 0;
+ }
+
+#ifdef SIGPIPE
+ /* Restore signal handling for SIGPIPE.
+ */
+ restore_old_pipe:
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 2);
+ success = 0;
+ }
+#endif
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+dk_pwgen_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ dk_pwgen_normal_run();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+#ifdef SIGPIPE
+ sigset(SIGPIPE, oldpipe);
+#endif
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+dk_pwgen_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = signal(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ dk_pwgen_normal_run();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+#ifdef SIGPIPE
+ signal(SIGPIPE, oldpipe);
+#endif
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+dk_pwgen_run_with_signal_handlers(void)
+{
+ dk_pwgen_normal_run();
+}
+#endif
+#endif
+#endif
+
+#endif
+/* if DK4_HAVE_OPENSSL_RAND_H */
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ int shp;
+ int pbso; /* Flag: Private buffer used for stdout */
+
+ pbso = dk4setvbuf(
+ stdout, DK4_FILE_LINE_BUFFERING, stdout_buffer, sizeof(stdout_buffer), NULL
+ );
+ $!trace-init dk-pwgen.deb
+ $? "+ main"
+ dk4fput_initialize_stdout();
+ dk4fput_initialize_stderr();
+ app = dk4app_open_cmd(
+ argc, argv, dk_pwgen_options, dk_pwgen_sz_options,
+ dk_pwgen_kwnl[0], DKT_VERSION_DK,
+ dk_pwgen_kwnl[1], dk_pwgen_help_text, dk_pwgen_license_text
+ );
+ if (NULL != app) {
+ dk_pwgen_sz_msg = dk4app_string_table_size(dk_pwgen_kw_def);
+ dk_pwgen_msg = dk4app_string_table(app,dk_pwgen_kwnl[2],dk_pwgen_kw_def);
+ if (0 != dk4app_can_run_normally(app)) {
+#if DK4_HAVE_OPENSSL_RAND_H
+ /*
+ Run.
+ */
+ dk_pwgen_run_with_signal_handlers();
+ /*
+ Report signals and output errors, if any.
+ */
+ if (0 != sig_read_atomic(&sig_had_term)) {
+ /* ERROR: SIGTERM signal received */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 19);
+ exval = EXIT_FAILURE;
+ }
+ if (0 != sig_read_atomic(&sig_had_int )) {
+ /* ERROR: SIGINT signal received */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 20);
+ exval = EXIT_FAILURE;
+ }
+#ifdef SIGPIPE
+ if (0 != sig_read_atomic(&sig_had_pipe)) {
+ /* ERROR: SIGPIPE signal received */
+ if (0 != verbose) {
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 21);
+ }
+ exval = EXIT_FAILURE;
+ shp = 1;
+ } else {
+ shp = 0;
+ }
+#else
+ shp = 0;
+#endif
+ if ((0 == shp) && (0 != output_error)) {
+ /* ERROR: Failed to write to stdout */
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 22);
+ exval = EXIT_FAILURE;
+ }
+#else
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 0);
+#endif
+ if (0 == pbso) {
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 30);
+ exval = EXIT_FAILURE;
+ } else {
+#ifdef BUFSIZ
+ fflush(stdout);
+ if (0 == dk4mem_reset_secure(stdout_buffer,sizeof(stdout_buffer),NULL))
+ {
+ dk4app_log_1(app, dk_pwgen_msg, dk_pwgen_sz_msg, DK4_LL_ERROR, 30);
+ exval = EXIT_FAILURE;
+ }
+#endif
+ }
+ } else {
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ dk4app_close(app);
+ } else {
+ }
+ fflush(stdout);
+ fflush(stderr);
+ dk4fput_cleanup_stderr();
+ dk4fput_cleanup_stdout();
+ $? "- main %d", exval
+ $!trace-end
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/dk-pwgen.rc b/support/dktools/dk-pwgen.rc
new file mode 100644
index 0000000000..36b551c4ab
--- /dev/null
+++ b/support/dktools/dk-pwgen.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Generator for passwords, PINs and hexadecimal keys\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "Generator for passwords, PINs and hexadecimal keys\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "dk-pwgen\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/dk-rand.c b/support/dktools/dk-rand.c
new file mode 100644
index 0000000000..1eecf01f42
--- /dev/null
+++ b/support/dktools/dk-rand.c
@@ -0,0 +1,1034 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk-rand.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk-rand.c The dk-rand module.
+*/
+
+
+#line 9 "dk-rand.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+#include <stdio.h>
+
+#if DK4_ON_WINDOWS
+/** Allow use of the getenv() function. */
+#define _CRT_SECURE_NO_WARNINGS 1
+#endif
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#ifndef WINCRYPT_H_INCLUDED
+#include <wincrypt.h>
+#define WINCRYPT_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_OPENSSL_RAND_H
+
+#ifndef OPENSSL_RAND_H_INCLUDED
+#include <openssl/rand.h>
+#define OPENSSL_RAND_H_INCLUDED 1
+#endif
+
+#include "dk4const.h"
+#include "dk4mem.h"
+#include "dk4mema.h"
+#include "dk4memrs.h"
+#include "dk4strd.h"
+#include "dk4fput.h"
+#include "dk4vers.h"
+#include "dk4maiddsz.h"
+#include "dk4maasz.h"
+#include "dk4mpl.h"
+#include "dk4svbuf.h"
+
+
+
+
+
+#line 95 "dk-rand.ctr"
+
+
+
+
+/** Buffer for random data.
+*/
+static char dk_rand_buf[16384];
+
+
+
+#ifndef BUFSIZ
+#define BUFSIZ 8192
+#endif
+
+/** Use an explicitly specified buffer for stdout operations
+ so we can securely reset the memory before exiting.
+*/
+static char stdout_buffer[BUFSIZ];
+
+
+/** Buffer to read seed file.
+*/
+static char seed_file_buffer[BUFSIZ];
+
+
+
+/** Help text to show for --help option.
+*/
+static const char * const help_text[] = {
+"",
+"Generate binary random data",
+"",
+"dk-rand [-b bytes]",
+"",
+"-b bytes\tNumber of bytes to generate.",
+"",
+"--help\t\tShow this short help text.",
+"--version\tShow version information.",
+"--license\tShow license information.",
+"",
+"http://dktools.sourceforge.net",
+"",
+NULL
+
+
+#line 139 "dk-rand.ctr"
+};
+
+
+
+/** License information to show for --license option.
+*/
+static const char * const license_text[] = {
+"This software uses code from the following projects, either directly or as",
+"a library:",
+"",
+"dktools\t\tDirk Krause's tools and libraries.",
+"\t\tSee http://dktools.sourceforge.net/ for more information.",
+#if DK4_HAVE_OPENSSL_RAND_H
+"",
+"OpenSSL\t\tCryptographic toolkit, used to build file checksums here.",
+"\t\tSee http://www.openssl.org/ for more information.",
+"",
+"This product includes software developed by the OpenSSL Project for use in",
+"the OpenSSL Toolkit (http://www.openssl.org/).",
+"This product includes cryptographic software written by",
+"Eric Young (eay@cryptsoft.com).",
+"This product includes software written by Tim Hudson (tjh@cryptsoft.com).",
+#endif
+"",
+"All the licenses below apply to the program.",
+"Licenses for used libraries are shown as found on my Scientific Linux 6.x",
+"computer in the /usr/share/doc directory on 2015-04-01. Check the project",
+"homepages of the used libraries for additional information and/or updated",
+"license terms.",
+"",
+"",
+"DK tools and libraries license",
+"==============================",
+"Copyright (c) 2015-2016, Dirk Krause",
+"All rights reserved.",
+"",
+"Redistribution and use in source and binary forms, with or without",
+"modification, are permitted provided that the following conditions are met:",
+"",
+"* Redistributions of source code must retain the above copyright notice,",
+" this list of conditions and the following disclaimer.",
+"* Redistributions in binary form must reproduce the above copyright",
+" notice, this list of conditions and the following disclaimer in the",
+" documentation and/or other materials provided with the distribution.",
+"* Neither the name of the Dirk Krause nor the names of contributors may be",
+" used to endorse or promote products derived from this software without",
+" specific prior written permission.",
+"",
+"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"",
+"AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE",
+"IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE",
+"ARE DISCLAIMED.",
+"",
+"IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,",
+"INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,",
+"BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,",
+"DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY",
+"OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING",
+"NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,",
+"EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.",
+#if DK4_HAVE_OPENSSL_RAND_H
+"",
+"",
+"OpenSSL license",
+"===============",
+"",
+"LICENSE ISSUES",
+"--------------",
+"",
+"The OpenSSL toolkit stays under a dual license, i.e. both the conditions of",
+"the OpenSSL License and the original SSLeay license apply to the toolkit.",
+"See below for the actual license texts. Actually both licenses are BSD-style",
+"Open Source licenses. In case of any license issues related to OpenSSL",
+"please contact openssl-core@openssl.org.",
+"",
+"OpenSSL License",
+"---------------",
+"",
+"Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved.",
+"",
+"Redistribution and use in source and binary forms, with or without",
+"modification, are permitted provided that the following conditions",
+"are met:",
+"",
+"1. Redistributions of source code must retain the above copyright",
+" notice, this list of conditions and the following disclaimer. ",
+"",
+"2. Redistributions in binary form must reproduce the above copyright",
+" notice, this list of conditions and the following disclaimer in",
+" the documentation and/or other materials provided with the",
+" distribution.",
+"",
+"3. All advertising materials mentioning features or use of this",
+" software must display the following acknowledgment:",
+" \"This product includes software developed by the OpenSSL Project",
+" for use in the OpenSSL Toolkit. (http://www.openssl.org/)\"",
+"",
+"4. The names \"OpenSSL Toolkit\" and \"OpenSSL Project\" must not be used to",
+" endorse or promote products derived from this software without",
+" prior written permission. For written permission, please contact",
+" openssl-core@openssl.org.",
+"",
+"5. Products derived from this software may not be called \"OpenSSL\"",
+" nor may \"OpenSSL\" appear in their names without prior written",
+" permission of the OpenSSL Project.",
+"",
+"6. Redistributions of any form whatsoever must retain the following",
+" acknowledgment:",
+" \"This product includes software developed by the OpenSSL Project",
+" for use in the OpenSSL Toolkit (http://www.openssl.org/)\"",
+"",
+"THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY",
+"EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE",
+"IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR",
+"PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR",
+"ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,",
+"SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT",
+"NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;",
+"LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)",
+"HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,",
+"STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)",
+"ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED",
+"OF THE POSSIBILITY OF SUCH DAMAGE.",
+"",
+"This product includes cryptographic software written by Eric Young",
+"(eay@cryptsoft.com). This product includes software written by Tim",
+"Hudson (tjh@cryptsoft.com).",
+"",
+"",
+"Original SSLeay License",
+"-----------------------",
+"",
+"Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)",
+"All rights reserved.",
+"",
+"This package is an SSL implementation written",
+"by Eric Young (eay@cryptsoft.com).",
+"The implementation was written so as to conform with Netscapes SSL.",
+"",
+"This library is free for commercial and non-commercial use as long as",
+"the following conditions are aheared to. The following conditions",
+"apply to all code found in this distribution, be it the RC4, RSA,",
+"lhash, DES, etc., code; not just the SSL code. The SSL documentation",
+"included with this distribution is covered by the same copyright terms",
+"except that the holder is Tim Hudson (tjh@cryptsoft.com).",
+"",
+"Copyright remains Eric Young's, and as such any Copyright notices in",
+"the code are not to be removed.",
+"If this package is used in a product, Eric Young should be given attribution",
+"as the author of the parts of the library used.",
+"This can be in the form of a textual message at program startup or",
+"in documentation (online or textual) provided with the package.",
+"",
+"Redistribution and use in source and binary forms, with or without",
+"modification, are permitted provided that the following conditions",
+"are met:",
+"1. Redistributions of source code must retain the copyright",
+" notice, this list of conditions and the following disclaimer.",
+"2. Redistributions in binary form must reproduce the above copyright",
+" notice, this list of conditions and the following disclaimer in the",
+" documentation and/or other materials provided with the distribution.",
+"3. All advertising materials mentioning features or use of this software",
+" must display the following acknowledgement:",
+" \"This product includes cryptographic software written by",
+" Eric Young (eay@cryptsoft.com)\"",
+" The word 'cryptographic' can be left out if the rouines from the library",
+" being used are not cryptographic related :-).",
+"4. If you include any Windows specific code (or a derivative thereof) from ",
+" the apps directory (application code) you must include an acknowledgement:",
+" \"This product includes software written by Tim Hudson (tjh@cryptsoft.com)\"",
+"",
+"THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND",
+"ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE",
+"IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE",
+"ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE",
+"FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL",
+"DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS",
+"OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)",
+"HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT",
+"LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY",
+"OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF",
+"SUCH DAMAGE.",
+"",
+"The licence and distribution terms for any publically available version or",
+"derivative of this code cannot be changed. i.e. this code cannot simply be",
+"copied and put under another distribution licence",
+"[including the GNU Public Licence.]",
+"",
+#endif
+"",
+NULL
+
+
+#line 331 "dk-rand.ctr"
+};
+
+
+
+/** Version information.
+*/
+static const char version_text[] = { DKT_VERSION_C8 };
+
+
+
+/** Options used by the program.
+*/
+static dk4_option_t options[] = {
+
+ /* Configuration file.
+ */
+ { { dkT('b'), dkT("bytes"), DK4_OPT_ARG_SIZE }, { NULL }, 0 },
+
+ /* 1 Help.
+ */
+ { { dkT('\0'),dkT("help"), DK4_OPT_ARG_NONE}, { NULL }, 0},
+
+ /* 2 Version.
+ */
+ { { dkT('\0'),dkT("version"), DK4_OPT_ARG_NONE}, { NULL }, 0},
+
+ /* 3 License
+ */
+ { { dkT('\0'),dkT("license"), DK4_OPT_ARG_NONE}, { NULL }, 0}
+
+};
+
+
+/** Constant texts used by the program, not localized.
+*/
+static const char * dk_rand_kw[] = {
+/* 0 */
+"dk-rand: ",
+
+/* 1 */
+"ERROR: Failed to write to standard output!\n",
+
+/* 2 */
+"ERROR: Failed to obtain random data!\n",
+
+/* 3 */
+"ERROR: Aborted by signal!\n",
+
+/* 4 */
+"ERROR: Failed to reset used buffers!\n",
+
+/* 5 */
+"ERROR: Failed to seed OpenSSL PRNG!\n",
+
+/* 6 */
+"ERROR: Failed to set up signal handlers!\n",
+
+/* 7 */
+"ERROR: Failed to restore signal handlers!\n",
+
+/* 8 */
+"ERROR: Numeric overflow in size calculation!\n",
+
+NULL
+
+
+#line 405 "dk-rand.ctr"
+};
+
+
+
+/** Number of options in the options array.
+*/
+static const size_t szoptions = sizeof(options)/sizeof(dk4_option_t);
+
+
+
+/** Exit status code.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+/** Options: Help (1), version (2), license (4).
+*/
+static int hvl = 0;
+
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+/** Pass volatile pointer through to caller.
+ The CERT C coding standard recommends to set signal indicator
+ variables through pointers to avoid
+ compilers from optimizing too hard (they might attempt
+ to keep the value in a register although properly marked
+ as volatile).
+ @param ptr Address of volatile indicator variable.
+ @return Same pointer as ptr.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+
+/** Check whether we can continue or must abort due to signal.
+ @param dopipe Flag: Check for SIGPIPE too.
+ @return 1 if we can continue, 0 otherwise.
+*/
+static
+int
+can_continue(int dopipe)
+{
+ int back = 1;
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_int)) { back = 0; }
+#ifdef SIGPIPE
+ if (0 != dopipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ return back;
+}
+
+
+
+/** Write a log message to stderr.
+ @param i Message index in dk_rand_kw.
+*/
+static
+void
+log_1(size_t i)
+{
+ fputs(dk_rand_kw[0], stderr);
+ fputs(dk_rand_kw[i], stderr);
+ fflush(stderr);
+}
+
+
+
+/** Seed pseudo random number generator.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+seed_prng(void)
+{
+ char buffer[64];
+ char *envptr;
+#if DK4_ON_WINDOWS
+ HCRYPTPROV hcp;
+ BOOL res;
+#else
+ FILE *fipo;
+ size_t rdb;
+#endif
+ int cc;
+ int rounds = 0;
+ int back = 0;
+ int svbres = 0;
+
+
+#line 574 "dk-rand.ctr"
+
+ /* Let OpenSSL library functions try to initialize.
+ */
+ if (1 == RAND_status()) {
+ back = 1;
+ goto finished;
+ }
+
+ /* Attempt EGD socket if specified in environment.
+ */
+#if DK4_HAVE_RAND_EGD && DK4_HAVE_STRUCT_SOCKADDR_UN
+ envptr = getenv("EGDSOCKET");
+ if (NULL != envptr) {
+ if (0 < RAND_egd(envptr)) {
+ if (1 == RAND_status()) {
+ back = 1;
+ goto finished;
+ }
+ }
+ }
+#endif
+
+ /* Use platform specific mechanisms if available.
+ */
+#if DK4_ON_WINDOWS
+ res = CryptAcquireContext(
+ &hcp, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT
+ );
+ if (res) {
+ cc = 1;
+ do {
+ if (0 != can_continue(0)) {
+ res = CryptGenRandom(hcp, (DWORD)sizeof(buffer), buffer);
+ if (res) {
+ RAND_seed(buffer, sizeof(buffer));
+ if (1 == RAND_status()) {
+ cc = 0;
+ back = 1;
+ } else {
+ rounds++;
+ }
+ } else {
+ cc = -1;
+ /* ERROR: Failed to obtain random bytes from crypto context */
+ }
+ } else {
+ cc = -1;
+ }
+ } while ((1 == cc) && (128 > rounds));
+ CryptReleaseContext(hcp, (DWORD)0UL);
+ (void)dk4mem_reset_secure(buffer, sizeof(buffer), NULL);
+ if (0 == back) {
+ if (0 != can_continue(0)) {
+ RAND_screen();
+ if (1 == RAND_status()) {
+ back = 1;
+ }
+ }
+ }
+ } else {
+ /* ERROR: Failed to acquire crypto context */
+ }
+#else
+ fipo = fopen("/dev/random", "rb");
+ if (NULL == fipo) {
+ fipo = fopen("/dev/urandom", "rb");
+ }
+ if (NULL != fipo) {
+ dk4mem_reset(seed_file_buffer, sizeof(seed_file_buffer), NULL);
+ svbres = dk4setvbuf(
+ fipo, DK4_FILE_FULL_BUFFERING,
+ seed_file_buffer, sizeof(seed_file_buffer), NULL
+ );
+ if (0 != svbres) {
+ cc = 1;
+ do {
+ if (0 != can_continue(0)) {
+ rdb = fread(buffer, 1, sizeof(buffer), fipo);
+ if (0 < rdb) {
+ RAND_seed(buffer, rdb);
+ if (1 == RAND_status()) {
+ cc = 0;
+ back = 1;
+ } else {
+ rounds++;
+ }
+ } else {
+ cc = -1;
+ }
+ } else {
+ cc = -1;
+ }
+ } while ((1 == cc) && (128 > rounds));
+ } else {
+ /* ERROR: Failed to set file buffer */
+ }
+ fclose(fipo);
+ (void)dk4mem_reset_secure(seed_file_buffer, sizeof(seed_file_buffer), NULL);
+ (void)dk4mem_reset_secure(buffer, sizeof(buffer), NULL);
+ } else {
+ /* ERROR: Failed to open both /dev/random and /dev/urandom */
+ }
+#endif
+
+ finished:
+
+
+#line 680 "dk-rand.ctr"
+ return back;
+}
+
+
+
+/** Create random data, write to standard output.
+*/
+static
+void
+create_random_data(int pbso)
+{
+ size_t sz = 512; /* Amount of data to produce */
+ size_t by; /* Bytes to process */
+ size_t wrb; /* Bytes written */
+#if DK4_ON_WINDOWS
+ int oldmode = _O_TEXT; /* Previous stdout mode */
+#endif
+ int cc = 1; /* Flag: Can continue */
+
+#if DK4_ON_WINDOWS
+ oldmode = _setmode(_fileno(stdout), _O_BINARY);
+#endif
+ if (0 != seed_prng()) {
+ if (0 != options[0].found) {
+ if (0 < options[0].val.s) {
+ sz = options[0].val.s;
+ }
+ }
+ if (0 == sz) { sz = 512; }
+ exval = EXIT_SUCCESS;
+ do {
+ if (0 != can_continue(1)) {
+ by = sizeof(dk_rand_buf);
+ if (by > sz) { by = sz; }
+ if (0 == sz) {
+ cc = 0;
+ } else {
+ if ((dk4_um_t)(INT_MAX) >= (dk4_um_t)by) {
+ if (0 < RAND_bytes((unsigned char *)dk_rand_buf, (int)by)) {
+ if (0 != can_continue(1)) {
+ wrb = fwrite(dk_rand_buf, 1, by, stdout);
+ if (wrb == by) {
+ if (by >= sz) {
+ sz = 0;
+ cc = 0;
+ } else {
+ sz -= by;
+ }
+ } else {
+ /* ERROR: Failed to write bytes to standard output */
+ log_1(1);
+ exval = EXIT_FAILURE;
+ cc = 0;
+ }
+ } else {
+ cc = -1;
+ }
+ } else {
+ /* ERROR: Failed to obtain random data */
+ log_1(2);
+ exval = EXIT_FAILURE;
+ cc = 0;
+ }
+ } else {
+ /* ERROR: Numeric overflow */
+ cc = 0;
+ exval = EXIT_FAILURE;
+ log_1(8);
+ }
+ }
+ } else {
+ cc = -1;
+ }
+ } while (1 == cc);
+ if (-1 == cc) {
+ /* ERROR: Aborted by signal */
+ log_1(3);
+ exval = EXIT_FAILURE;
+ }
+
+ /* Securely reset buffers.
+ */
+ RAND_cleanup();
+ fflush(stdout);
+ if (0 == pbso) {
+ /* ERROR: Failed to reset buffer */
+ log_1(4);
+ exval = EXIT_FAILURE;
+ } else {
+ if (0 == dk4mem_reset_secure(stdout_buffer,sizeof(stdout_buffer),NULL)) {
+ /* ERROR: Failed to reset buffer */
+ log_1(4);
+ exval = EXIT_FAILURE;
+ }
+ }
+ if (0 == dk4mem_reset_secure(dk_rand_buf, sizeof(dk_rand_buf), NULL)) {
+ /* ERROR: Failed to reset buffer */
+ log_1(4);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Failed to seed PRNG */
+ log_1(5);
+ }
+#if DK4_ON_WINDOWS
+ _setmode(_fileno(stdout), oldmode);
+#endif
+}
+
+
+
+/** Show a text paragraph on standard output.
+ @param txt Text to show.
+*/
+static
+void
+show_text(const char * const *txt)
+{
+ if (NULL != txt) {
+ while (NULL != *txt) {
+ fputs(*(txt++), stdout);
+ fputc('\n', stdout);
+ }
+ fflush(stdout);
+ }
+}
+
+
+
+/** Handle --help, --version, --license options.
+*/
+static
+void
+run_hvl(void)
+{
+ if (0 != (1 & hvl)) {
+ show_text(help_text);
+ }
+ if (0 != (2 & hvl)) {
+ fputs(version_text, stdout);
+ fputc('\n', stdout);
+ fflush(stdout);
+ }
+ if (0 != (4 & hvl)) {
+ show_text(license_text);
+ }
+ exval = EXIT_SUCCESS;
+}
+
+
+
+#endif
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+#if DK4_HAVE_OPENSSL_RAND_H
+
+#if DK4_HAVE_SIGACTION
+#ifdef SIGPIPE
+ struct sigaction opipe; /* Old disposition for SIGPIPE */
+ struct sigaction npipe; /* New disposition for SIGPIPE */
+#endif
+ struct sigaction oint; /* Old disposition for SIGINT */
+ struct sigaction nint; /* New disposition for SIGINT */
+ struct sigaction oterm; /* Old disposition for SIGTERM */
+ struct sigaction nterm; /* New disposition for SIGTERM */
+#else
+#ifdef SIGPIPE
+ dk4_sig_handler_t *opipe = NULL; /* Old disposition for SIGPIPE */
+#endif
+ dk4_sig_handler_t *oterm = NULL; /* Old disposition for SIGTERM */
+ dk4_sig_handler_t *oint = NULL; /* Old disposition for SIGINT */
+#endif
+#if DK4_HAVE_SIGACTION
+#ifdef SIGPIPE
+ int set_pipe = 0; /* Flag: Disposition SIGPIPE changed */
+#endif
+ int set_int = 0; /* Flag: Disposition SIGINT changed */
+ int set_term = 0; /* Flag: Disposition SIGTERM changed */
+ int sig_i_f = 0; /* Flag: Handler installation failed */
+ int sig_r_f = 0; /* Flag: Handler restoration failed */
+#endif
+ int pbso = 0; /* Flag: Private buffer for stdout */
+ int res;
+
+ /* Use private buffer for standard output.
+ */
+ pbso = dk4setvbuf(
+ stdout, DK4_FILE_LINE_BUFFERING, stdout_buffer, sizeof(stdout_buffer), NULL
+ );
+
+ /* Process command line arguments.
+ */
+ res = dk4opt_process_argv(
+ options, szoptions, argc, argv, NULL, NULL, 1, 1, NULL
+ );
+ if (0 == res) {
+ goto finished;
+ }
+
+ /* Set up signal handlers.
+ */
+#if DK4_HAVE_SIGACTION
+#ifdef SIGPIPE
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) { sig_i_f = 1; goto finished; }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) { sig_i_f = 1; goto finished; }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) { sig_i_f = 1; goto finished; }
+ set_pipe = 1;
+#endif
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) { sig_i_f = 1; goto finished; }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) { sig_i_f = 1; goto finished; }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) { sig_i_f = 1; goto finished; }
+ set_term = 1;
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) { sig_i_f = 1; goto finished; }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) { sig_i_f = 1; goto finished; }
+ if (0 != sigaction(SIGINT, &nint, &oint)) { sig_i_f = 1; goto finished; }
+ set_int = 1;
+#else
+#if DK4_HAVE_SIGSET
+#ifdef SIGPIPE
+ opipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oint = sigset(SIGINT, sig_handler_int);
+ oterm = sigset(SIGTERM, sig_handler_term);
+#else
+#ifdef SIGPIPE
+ opipe = signal(SIGPIPE, sig_handler_pipe);
+#endif
+ oint = signal(SIGINT, sig_handler_int);
+ oterm = signal(SIGTERM, sig_handler_term);
+#endif
+#endif
+
+ /* Check help, version, license.
+ */
+ if (0 != options[1].found) { hvl |= 1; }
+ if (0 != options[2].found) { hvl |= 2; }
+ if (0 != options[3].found) { hvl |= 4; }
+ if (0 != hvl) {
+ run_hvl();
+ goto finished;
+ }
+
+ /* Create random data.
+ */
+ create_random_data(pbso);
+
+ /* Clean up at end of program.
+ */
+ finished:
+
+ /* Restore signal handlers
+ */
+#if DK4_HAVE_SIGACTION
+ if (0 != sig_i_f) {
+ /* ERROR: Failed to set up signal handlers */
+ log_1(6);
+ }
+ if (0 != set_int) {
+ if (0 != sigaction(SIGINT, &oint, NULL)) { sig_r_f = 1; }
+ }
+ if (0 != set_term) {
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) { sig_r_f = 1; }
+ }
+#ifdef SIGPIPE
+ if (0 != set_pipe) {
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) { sig_r_f = 1; }
+ }
+#endif
+ if (0 != sig_r_f) {
+ /* ERROR: Failed to restore signal handlers */
+ log_1(7);
+ }
+#else
+#if DK4_HAVE_SIGSET
+ if (NULL != oterm) { sigset(SIGTERM, oterm); }
+ if (NULL != oint ) { sigset(SIGINT, oint ); }
+#ifdef SIGPIPE
+ if (NULL != opipe) { sigset(SIGPIPE, opipe); }
+#endif
+#else
+ if (NULL != oterm) { signal(SIGTERM, oterm); }
+ if (NULL != oint ) { signal(SIGINT, oint ); }
+#ifdef SIGPIPE
+ if (NULL != opipe) { signal(SIGPIPE, opipe); }
+#endif
+#endif
+#endif
+
+#else
+ fputs(
+ "dk-rand: ERROR: OpenSSL support was not available during build!\n",
+ stderr
+ );
+ fflush(stderr);
+#endif
+ exit(exval); return exval;
+}
+
+
diff --git a/support/dktools/dk-rand.ctr b/support/dktools/dk-rand.ctr
new file mode 100644
index 0000000000..b308de5f9c
--- /dev/null
+++ b/support/dktools/dk-rand.ctr
@@ -0,0 +1,999 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+#include <stdio.h>
+
+#if DK4_ON_WINDOWS
+/** Allow use of the getenv() function. */
+#define _CRT_SECURE_NO_WARNINGS 1
+#endif
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#ifndef WINCRYPT_H_INCLUDED
+#include <wincrypt.h>
+#define WINCRYPT_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_OPENSSL_RAND_H
+
+#ifndef OPENSSL_RAND_H_INCLUDED
+#include <openssl/rand.h>
+#define OPENSSL_RAND_H_INCLUDED 1
+#endif
+
+#include "dk4const.h"
+#include "dk4mem.h"
+#include "dk4mema.h"
+#include "dk4memrs.h"
+#include "dk4strd.h"
+#include "dk4fput.h"
+#include "dk4vers.h"
+#include "dk4maiddsz.h"
+#include "dk4maasz.h"
+#include "dk4mpl.h"
+#include "dk4svbuf.h"
+
+
+
+$!trace-include
+
+
+
+
+/** Buffer for random data.
+*/
+static char dk_rand_buf[16384];
+
+
+
+#ifndef BUFSIZ
+#define BUFSIZ 8192
+#endif
+
+/** Use an explicitly specified buffer for stdout operations
+ so we can securely reset the memory before exiting.
+*/
+static char stdout_buffer[BUFSIZ];
+
+
+/** Buffer to read seed file.
+*/
+static char seed_file_buffer[BUFSIZ];
+
+
+
+/** Help text to show for --help option.
+*/
+static const char * const help_text[] = {
+$!text
+
+Generate binary random data
+
+dk-rand [-b bytes]
+
+-b bytes Number of bytes to generate.
+
+--help Show this short help text.
+--version Show version information.
+--license Show license information.
+
+http://dktools.sourceforge.net
+
+$!end
+};
+
+
+
+/** License information to show for --license option.
+*/
+static const char * const license_text[] = {
+$!text preprocessor
+This software uses code from the following projects, either directly or as
+a library:
+
+dktools Dirk Krause's tools and libraries.
+ See http://dktools.sourceforge.net/ for more information.
+#if DK4_HAVE_OPENSSL_RAND_H
+
+OpenSSL Cryptographic toolkit, used to build file checksums here.
+ See http://www.openssl.org/ for more information.
+
+This product includes software developed by the OpenSSL Project for use in
+the OpenSSL Toolkit (http://www.openssl.org/).
+This product includes cryptographic software written by
+Eric Young (eay@cryptsoft.com).
+This product includes software written by Tim Hudson (tjh@cryptsoft.com).
+#endif
+
+All the licenses below apply to the program.
+Licenses for used libraries are shown as found on my Scientific Linux 6.x
+computer in the /usr/share/doc directory on 2015-04-01. Check the project
+homepages of the used libraries for additional information and/or updated
+license terms.
+
+
+DK tools and libraries license
+==============================
+Copyright (c) 2015-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#if DK4_HAVE_OPENSSL_RAND_H
+
+
+OpenSSL license
+===============
+
+LICENSE ISSUES
+--------------
+
+The OpenSSL toolkit stays under a dual license, i.e. both the conditions of
+the OpenSSL License and the original SSLeay license apply to the toolkit.
+See below for the actual license texts. Actually both licenses are BSD-style
+Open Source licenses. In case of any license issues related to OpenSSL
+please contact openssl-core@openssl.org.
+
+OpenSSL License
+---------------
+
+Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+3. All advertising materials mentioning features or use of this
+ software must display the following acknowledgment:
+ "This product includes software developed by the OpenSSL Project
+ for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+
+4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ endorse or promote products derived from this software without
+ prior written permission. For written permission, please contact
+ openssl-core@openssl.org.
+
+5. Products derived from this software may not be called "OpenSSL"
+ nor may "OpenSSL" appear in their names without prior written
+ permission of the OpenSSL Project.
+
+6. Redistributions of any form whatsoever must retain the following
+ acknowledgment:
+ "This product includes software developed by the OpenSSL Project
+ for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+
+THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+OF THE POSSIBILITY OF SUCH DAMAGE.
+
+This product includes cryptographic software written by Eric Young
+(eay@cryptsoft.com). This product includes software written by Tim
+Hudson (tjh@cryptsoft.com).
+
+
+Original SSLeay License
+-----------------------
+
+Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+All rights reserved.
+
+This package is an SSL implementation written
+by Eric Young (eay@cryptsoft.com).
+The implementation was written so as to conform with Netscapes SSL.
+
+This library is free for commercial and non-commercial use as long as
+the following conditions are aheared to. The following conditions
+apply to all code found in this distribution, be it the RC4, RSA,
+lhash, DES, etc., code; not just the SSL code. The SSL documentation
+included with this distribution is covered by the same copyright terms
+except that the holder is Tim Hudson (tjh@cryptsoft.com).
+
+Copyright remains Eric Young's, and as such any Copyright notices in
+the code are not to be removed.
+If this package is used in a product, Eric Young should be given attribution
+as the author of the parts of the library used.
+This can be in the form of a textual message at program startup or
+in documentation (online or textual) provided with the package.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. All advertising materials mentioning features or use of this software
+ must display the following acknowledgement:
+ "This product includes cryptographic software written by
+ Eric Young (eay@cryptsoft.com)"
+ The word 'cryptographic' can be left out if the rouines from the library
+ being used are not cryptographic related :-).
+4. If you include any Windows specific code (or a derivative thereof) from
+ the apps directory (application code) you must include an acknowledgement:
+ "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+
+THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+The licence and distribution terms for any publically available version or
+derivative of this code cannot be changed. i.e. this code cannot simply be
+copied and put under another distribution licence
+[including the GNU Public Licence.]
+
+#endif
+
+$!end
+};
+
+
+
+/** Version information.
+*/
+static const char version_text[] = { DKT_VERSION_C8 };
+
+
+
+/** Options used by the program.
+*/
+static dk4_option_t options[] = {
+
+ /* Configuration file.
+ */
+ { { dkT('b'), dkT("bytes"), DK4_OPT_ARG_SIZE }, { NULL }, 0 },
+
+ /* 1 Help.
+ */
+ { { dkT('\0'),dkT("help"), DK4_OPT_ARG_NONE}, { NULL }, 0},
+
+ /* 2 Version.
+ */
+ { { dkT('\0'),dkT("version"), DK4_OPT_ARG_NONE}, { NULL }, 0},
+
+ /* 3 License
+ */
+ { { dkT('\0'),dkT("license"), DK4_OPT_ARG_NONE}, { NULL }, 0}
+
+};
+
+
+/** Constant texts used by the program, not localized.
+*/
+static const char * dk_rand_kw[] = {
+$!string-table
+#
+# Program name
+#
+dk-rand:
+#
+# 1 ERROR: Failed to write to standard output!
+#
+ERROR: Failed to write to standard output!\n
+#
+# 2 ERROR: Failed to obtain random data!
+#
+ERROR: Failed to obtain random data!\n
+#
+# 3 ERROR: Aborted by signal!
+#
+ERROR: Aborted by signal!\n
+#
+# 4 ERROR: Failed to reset used buffers!
+#
+ERROR: Failed to reset used buffers!\n
+#
+# 5 ERROR: Failed to seed OpenSSL PRNG!
+#
+ERROR: Failed to seed OpenSSL PRNG!\n
+#
+# 6 ERROR: Failed to set up signal handlers!
+#
+ERROR: Failed to set up signal handlers!\n
+#
+# 7 ERROR: Failed to restore signal handlers!
+#
+ERROR: Failed to restore signal handlers!\n
+#
+# 8 ERROR: Numeric overflow in size calculation!
+#
+ERROR: Numeric overflow in size calculation!\n
+$!end
+};
+
+
+
+/** Number of options in the options array.
+*/
+static const size_t szoptions = sizeof(options)/sizeof(dk4_option_t);
+
+
+
+/** Exit status code.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+/** Options: Help (1), version (2), license (4).
+*/
+static int hvl = 0;
+
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+/** Pass volatile pointer through to caller.
+ The CERT C coding standard recommends to set signal indicator
+ variables through pointers to avoid
+ compilers from optimizing too hard (they might attempt
+ to keep the value in a register although properly marked
+ as volatile).
+ @param ptr Address of volatile indicator variable.
+ @return Same pointer as ptr.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+
+/** Check whether we can continue or must abort due to signal.
+ @param dopipe Flag: Check for SIGPIPE too.
+ @return 1 if we can continue, 0 otherwise.
+*/
+static
+int
+can_continue(int dopipe)
+{
+ int back = 1;
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_int)) { back = 0; }
+#ifdef SIGPIPE
+ if (0 != dopipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ return back;
+}
+
+
+
+/** Write a log message to stderr.
+ @param i Message index in dk_rand_kw.
+*/
+static
+void
+log_1(size_t i)
+{
+ fputs(dk_rand_kw[0], stderr);
+ fputs(dk_rand_kw[i], stderr);
+ fflush(stderr);
+}
+
+
+
+/** Seed pseudo random number generator.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+seed_prng(void)
+{
+ char buffer[64];
+ char *envptr;
+#if DK4_ON_WINDOWS
+ HCRYPTPROV hcp;
+ BOOL res;
+#else
+ FILE *fipo;
+ size_t rdb;
+#endif
+ int cc;
+ int rounds = 0;
+ int back = 0;
+ int svbres = 0;
+ $? "+ dk_pwgen_seed_prng"
+
+ /* Let OpenSSL library functions try to initialize.
+ */
+ if (1 == RAND_status()) {
+ back = 1;
+ goto finished;
+ }
+
+ /* Attempt EGD socket if specified in environment.
+ */
+#if DK4_HAVE_RAND_EGD && DK4_HAVE_STRUCT_SOCKADDR_UN
+ envptr = getenv("EGDSOCKET");
+ if (NULL != envptr) {
+ if (0 < RAND_egd(envptr)) {
+ if (1 == RAND_status()) {
+ back = 1;
+ goto finished;
+ }
+ }
+ }
+#endif
+
+ /* Use platform specific mechanisms if available.
+ */
+#if DK4_ON_WINDOWS
+ res = CryptAcquireContext(
+ &hcp, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT
+ );
+ if (res) {
+ cc = 1;
+ do {
+ if (0 != can_continue(0)) {
+ res = CryptGenRandom(hcp, (DWORD)sizeof(buffer), buffer);
+ if (res) {
+ RAND_seed(buffer, sizeof(buffer));
+ if (1 == RAND_status()) {
+ cc = 0;
+ back = 1;
+ } else {
+ rounds++;
+ }
+ } else {
+ cc = -1;
+ /* ERROR: Failed to obtain random bytes from crypto context */
+ }
+ } else {
+ cc = -1;
+ }
+ } while ((1 == cc) && (128 > rounds));
+ CryptReleaseContext(hcp, (DWORD)0UL);
+ (void)dk4mem_reset_secure(buffer, sizeof(buffer), NULL);
+ if (0 == back) {
+ if (0 != can_continue(0)) {
+ RAND_screen();
+ if (1 == RAND_status()) {
+ back = 1;
+ }
+ }
+ }
+ } else {
+ /* ERROR: Failed to acquire crypto context */
+ }
+#else
+ fipo = fopen("/dev/random", "rb");
+ if (NULL == fipo) {
+ fipo = fopen("/dev/urandom", "rb");
+ }
+ if (NULL != fipo) {
+ dk4mem_reset(seed_file_buffer, sizeof(seed_file_buffer), NULL);
+ svbres = dk4setvbuf(
+ fipo, DK4_FILE_FULL_BUFFERING,
+ seed_file_buffer, sizeof(seed_file_buffer), NULL
+ );
+ if (0 != svbres) {
+ cc = 1;
+ do {
+ if (0 != can_continue(0)) {
+ rdb = fread(buffer, 1, sizeof(buffer), fipo);
+ if (0 < rdb) {
+ RAND_seed(buffer, rdb);
+ if (1 == RAND_status()) {
+ cc = 0;
+ back = 1;
+ } else {
+ rounds++;
+ }
+ } else {
+ cc = -1;
+ }
+ } else {
+ cc = -1;
+ }
+ } while ((1 == cc) && (128 > rounds));
+ } else {
+ /* ERROR: Failed to set file buffer */
+ }
+ fclose(fipo);
+ (void)dk4mem_reset_secure(seed_file_buffer, sizeof(seed_file_buffer), NULL);
+ (void)dk4mem_reset_secure(buffer, sizeof(buffer), NULL);
+ } else {
+ /* ERROR: Failed to open both /dev/random and /dev/urandom */
+ }
+#endif
+
+ finished:
+ $? "- dk_pwgen_seed_prng %d", back
+ return back;
+}
+
+
+
+/** Create random data, write to standard output.
+*/
+static
+void
+create_random_data(int pbso)
+{
+ size_t sz = 512; /* Amount of data to produce */
+ size_t by; /* Bytes to process */
+ size_t wrb; /* Bytes written */
+#if DK4_ON_WINDOWS
+ int oldmode = _O_TEXT; /* Previous stdout mode */
+#endif
+ int cc = 1; /* Flag: Can continue */
+
+#if DK4_ON_WINDOWS
+ oldmode = _setmode(_fileno(stdout), _O_BINARY);
+#endif
+ if (0 != seed_prng()) {
+ if (0 != options[0].found) {
+ if (0 < options[0].val.s) {
+ sz = options[0].val.s;
+ }
+ }
+ if (0 == sz) { sz = 512; }
+ exval = EXIT_SUCCESS;
+ do {
+ if (0 != can_continue(1)) {
+ by = sizeof(dk_rand_buf);
+ if (by > sz) { by = sz; }
+ if (0 == sz) {
+ cc = 0;
+ } else {
+ if ((dk4_um_t)(INT_MAX) >= (dk4_um_t)by) {
+ if (0 < RAND_bytes((unsigned char *)dk_rand_buf, (int)by)) {
+ if (0 != can_continue(1)) {
+ wrb = fwrite(dk_rand_buf, 1, by, stdout);
+ if (wrb == by) {
+ if (by >= sz) {
+ sz = 0;
+ cc = 0;
+ } else {
+ sz -= by;
+ }
+ } else {
+ /* ERROR: Failed to write bytes to standard output */
+ log_1(1);
+ exval = EXIT_FAILURE;
+ cc = 0;
+ }
+ } else {
+ cc = -1;
+ }
+ } else {
+ /* ERROR: Failed to obtain random data */
+ log_1(2);
+ exval = EXIT_FAILURE;
+ cc = 0;
+ }
+ } else {
+ /* ERROR: Numeric overflow */
+ cc = 0;
+ exval = EXIT_FAILURE;
+ log_1(8);
+ }
+ }
+ } else {
+ cc = -1;
+ }
+ } while (1 == cc);
+ if (-1 == cc) {
+ /* ERROR: Aborted by signal */
+ log_1(3);
+ exval = EXIT_FAILURE;
+ }
+
+ /* Securely reset buffers.
+ */
+ RAND_cleanup();
+ fflush(stdout);
+ if (0 == pbso) {
+ /* ERROR: Failed to reset buffer */
+ log_1(4);
+ exval = EXIT_FAILURE;
+ } else {
+ if (0 == dk4mem_reset_secure(stdout_buffer,sizeof(stdout_buffer),NULL)) {
+ /* ERROR: Failed to reset buffer */
+ log_1(4);
+ exval = EXIT_FAILURE;
+ }
+ }
+ if (0 == dk4mem_reset_secure(dk_rand_buf, sizeof(dk_rand_buf), NULL)) {
+ /* ERROR: Failed to reset buffer */
+ log_1(4);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Failed to seed PRNG */
+ log_1(5);
+ }
+#if DK4_ON_WINDOWS
+ _setmode(_fileno(stdout), oldmode);
+#endif
+}
+
+
+
+/** Show a text paragraph on standard output.
+ @param txt Text to show.
+*/
+static
+void
+show_text(const char * const *txt)
+{
+ if (NULL != txt) {
+ while (NULL != *txt) {
+ fputs(*(txt++), stdout);
+ fputc('\n', stdout);
+ }
+ fflush(stdout);
+ }
+}
+
+
+
+/** Handle --help, --version, --license options.
+*/
+static
+void
+run_hvl(void)
+{
+ if (0 != (1 & hvl)) {
+ show_text(help_text);
+ }
+ if (0 != (2 & hvl)) {
+ fputs(version_text, stdout);
+ fputc('\n', stdout);
+ fflush(stdout);
+ }
+ if (0 != (4 & hvl)) {
+ show_text(license_text);
+ }
+ exval = EXIT_SUCCESS;
+}
+
+
+
+#endif
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+#if DK4_HAVE_OPENSSL_RAND_H
+
+#if DK4_HAVE_SIGACTION
+#ifdef SIGPIPE
+ struct sigaction opipe; /* Old disposition for SIGPIPE */
+ struct sigaction npipe; /* New disposition for SIGPIPE */
+#endif
+ struct sigaction oint; /* Old disposition for SIGINT */
+ struct sigaction nint; /* New disposition for SIGINT */
+ struct sigaction oterm; /* Old disposition for SIGTERM */
+ struct sigaction nterm; /* New disposition for SIGTERM */
+#else
+#ifdef SIGPIPE
+ dk4_sig_handler_t *opipe = NULL; /* Old disposition for SIGPIPE */
+#endif
+ dk4_sig_handler_t *oterm = NULL; /* Old disposition for SIGTERM */
+ dk4_sig_handler_t *oint = NULL; /* Old disposition for SIGINT */
+#endif
+#if DK4_HAVE_SIGACTION
+#ifdef SIGPIPE
+ int set_pipe = 0; /* Flag: Disposition SIGPIPE changed */
+#endif
+ int set_int = 0; /* Flag: Disposition SIGINT changed */
+ int set_term = 0; /* Flag: Disposition SIGTERM changed */
+ int sig_i_f = 0; /* Flag: Handler installation failed */
+ int sig_r_f = 0; /* Flag: Handler restoration failed */
+#endif
+ int pbso = 0; /* Flag: Private buffer for stdout */
+ int res;
+
+ /* Use private buffer for standard output.
+ */
+ pbso = dk4setvbuf(
+ stdout, DK4_FILE_LINE_BUFFERING, stdout_buffer, sizeof(stdout_buffer), NULL
+ );
+
+ /* Process command line arguments.
+ */
+ res = dk4opt_process_argv(
+ options, szoptions, argc, argv, NULL, NULL, 1, 1, NULL
+ );
+ if (0 == res) {
+ goto finished;
+ }
+
+ /* Set up signal handlers.
+ */
+#if DK4_HAVE_SIGACTION
+#ifdef SIGPIPE
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) { sig_i_f = 1; goto finished; }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) { sig_i_f = 1; goto finished; }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) { sig_i_f = 1; goto finished; }
+ set_pipe = 1;
+#endif
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) { sig_i_f = 1; goto finished; }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) { sig_i_f = 1; goto finished; }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) { sig_i_f = 1; goto finished; }
+ set_term = 1;
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) { sig_i_f = 1; goto finished; }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) { sig_i_f = 1; goto finished; }
+ if (0 != sigaction(SIGINT, &nint, &oint)) { sig_i_f = 1; goto finished; }
+ set_int = 1;
+#else
+#if DK4_HAVE_SIGSET
+#ifdef SIGPIPE
+ opipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oint = sigset(SIGINT, sig_handler_int);
+ oterm = sigset(SIGTERM, sig_handler_term);
+#else
+#ifdef SIGPIPE
+ opipe = signal(SIGPIPE, sig_handler_pipe);
+#endif
+ oint = signal(SIGINT, sig_handler_int);
+ oterm = signal(SIGTERM, sig_handler_term);
+#endif
+#endif
+
+ /* Check help, version, license.
+ */
+ if (0 != options[1].found) { hvl |= 1; }
+ if (0 != options[2].found) { hvl |= 2; }
+ if (0 != options[3].found) { hvl |= 4; }
+ if (0 != hvl) {
+ run_hvl();
+ goto finished;
+ }
+
+ /* Create random data.
+ */
+ create_random_data(pbso);
+
+ /* Clean up at end of program.
+ */
+ finished:
+
+ /* Restore signal handlers
+ */
+#if DK4_HAVE_SIGACTION
+ if (0 != sig_i_f) {
+ /* ERROR: Failed to set up signal handlers */
+ log_1(6);
+ }
+ if (0 != set_int) {
+ if (0 != sigaction(SIGINT, &oint, NULL)) { sig_r_f = 1; }
+ }
+ if (0 != set_term) {
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) { sig_r_f = 1; }
+ }
+#ifdef SIGPIPE
+ if (0 != set_pipe) {
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) { sig_r_f = 1; }
+ }
+#endif
+ if (0 != sig_r_f) {
+ /* ERROR: Failed to restore signal handlers */
+ log_1(7);
+ }
+#else
+#if DK4_HAVE_SIGSET
+ if (NULL != oterm) { sigset(SIGTERM, oterm); }
+ if (NULL != oint ) { sigset(SIGINT, oint ); }
+#ifdef SIGPIPE
+ if (NULL != opipe) { sigset(SIGPIPE, opipe); }
+#endif
+#else
+ if (NULL != oterm) { signal(SIGTERM, oterm); }
+ if (NULL != oint ) { signal(SIGINT, oint ); }
+#ifdef SIGPIPE
+ if (NULL != opipe) { signal(SIGPIPE, opipe); }
+#endif
+#endif
+#endif
+
+#else
+ fputs(
+ "dk-rand: ERROR: OpenSSL support was not available during build!\n",
+ stderr
+ );
+ fflush(stderr);
+#endif
+ exit(exval); return exval;
+}
+
+
diff --git a/support/dktools/dk-rand.rc b/support/dktools/dk-rand.rc
new file mode 100644
index 0000000000..b6d392121a
--- /dev/null
+++ b/support/dktools/dk-rand.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Random data generator\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "Random data generator\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "dk-rand\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/dk-recv.c b/support/dktools/dk-recv.c
new file mode 100644
index 0000000000..6ff288b381
--- /dev/null
+++ b/support/dktools/dk-recv.c
@@ -0,0 +1,1226 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk-recv.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk-recv.c The dk-recv module.
+*/
+
+
+#line 10 "dk-recv.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_MATH_H
+#ifndef MATH_H_INCLUDED
+#include <math.h>
+#define MATH_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4sock.h"
+#include "dk4socka.h"
+#include "dk4fput.h"
+#include "dk4vers.h"
+#include "dk4aopt.h"
+#include "dk4numco.h"
+#include "dk4fopda.h"
+#include "dk4isadm.h"
+#include "dk4fdwre.h"
+#include "dk4mpl.h"
+#include "dk4mem.h"
+#include "dk4mema.h"
+#include "dk4strd.h"
+#include "dk4pathd.h"
+
+
+
+
+
+#line 59 "dk-recv.ctr"
+
+
+
+/** Default help text, shown if no localized help text is found.
+*/
+static const dkChar * const dk_recv_help_text[] = {
+dkT(""),
+dkT("Receive data from a dk-send process."),
+dkT(""),
+dkT("dk-recv [<options>] <host> <port> [<file>]"),
+dkT(""),
+dkT("Arguments:"),
+dkT("host\t\tSender host to connect to (name or IP)."),
+dkT("port\t\tPort number to connect to."),
+dkT("file\t\tOutput file to create. Default: Write to standard output."),
+dkT(""),
+dkT("Options:"),
+dkT("-t\t\tTell peer to start transmission."),
+dkT("-l <port>\tLocal port number to bind."),
+dkT("-c <int>\tTimeout for connect attempt."),
+dkT(""),
+dkT("--help\t\tShow this short help text."),
+dkT("--manual\t*** SHOW FULL MANUAL. ***"),
+dkT("--version\tShow version information."),
+dkT("--license\tShow license information."),
+dkT(""),
+NULL
+
+
+#line 87 "dk-recv.ctr"
+};
+
+
+
+/** License text.
+*/
+static const dkChar * const dk_recv_license_text[] = {
+dkT("This software uses code from the following projects, either directly or as"),
+dkT("a library:"),
+dkT(""),
+dkT("dktools\t\tDirk Krause's tools and libraries."),
+dkT("\t\tSee http://dktools.sourceforge.net/ for more information."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT("zlib\t\tData compression library."),
+dkT("\t\tSee http://www.zlib.net/ for more information."),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT("bzip2\t\tData compression program and library."),
+dkT("\t\tSee http://www.bzip.org/ for more information."),
+#endif
+dkT(""),
+dkT("All the licenses below apply to the program."),
+dkT("Licenses for used libraries are shown as found on my Scientific Linux 6.x"),
+dkT("computer in the /usr/share/doc directory on 2015-04-01. Check the project"),
+dkT("homepages of the used libraries for additional information and/or updated"),
+dkT("license terms."),
+dkT(""),
+dkT(""),
+dkT("DK tools and libraries license"),
+dkT("=============================="),
+dkT("Copyright (c) 2015-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above copyright notice,"),
+dkT(" this list of conditions and the following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("* Neither the name of the Dirk Krause nor the names of contributors may be"),
+dkT(" used to endorse or promote products derived from this software without"),
+dkT(" specific prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\""),
+dkT("AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED."),
+dkT(""),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,"),
+dkT("INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,"),
+dkT("BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,"),
+dkT("DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY"),
+dkT("OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,"),
+dkT("EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT(""),
+dkT("Zlib license"),
+dkT("============"),
+dkT("(C) 1995-2004 Jean-loup Gailly and Mark Adler"),
+dkT(""),
+dkT("This software is provided 'as-is', without any express or implied"),
+dkT("warranty. In no event will the authors be held liable for any damages"),
+dkT("arising from the use of this software."),
+dkT(""),
+dkT("Permission is granted to anyone to use this software for any purpose,"),
+dkT("including commercial applications, and to alter it and redistribute it"),
+dkT("freely, subject to the following restrictions:"),
+dkT(""),
+dkT("1. The origin of this software must not be misrepresented; you must not"),
+dkT(" claim that you wrote the original software. If you use this software"),
+dkT(" in a product, an acknowledgment in the product documentation would be"),
+dkT(" appreciated but is not required."),
+dkT("2. Altered source versions must be plainly marked as such, and must not be"),
+dkT(" misrepresented as being the original software."),
+dkT("3. This notice may not be removed or altered from any source distribution."),
+dkT(""),
+dkT("Jean-loup Gailly Mark Adler"),
+dkT("jloup@gzip.org madler@alumni.caltech.edu"),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT(""),
+dkT("Bzip2 and libbzip2 library license"),
+dkT("=================================="),
+dkT("This program, \"bzip2\", the associated library \"libbzip2\", and all"),
+dkT("documentation, are copyright (C) 1996-2007 Julian R Seward. All"),
+dkT("rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions"),
+dkT("are met:"),
+dkT(""),
+dkT("1. Redistributions of source code must retain the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer."),
+dkT(""),
+dkT("2. The origin of this software must not be misrepresented; you must "),
+dkT(" not claim that you wrote the original software. If you use this "),
+dkT(" software in a product, an acknowledgment in the product "),
+dkT(" documentation would be appreciated but is not required."),
+dkT(""),
+dkT("3. Altered source versions must be plainly marked as such, and must"),
+dkT(" not be misrepresented as being the original software."),
+dkT(""),
+dkT("4. The name of the author may not be used to endorse or promote "),
+dkT(" products derived from this software without specific prior written "),
+dkT(" permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS"),
+dkT("OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED"),
+dkT("WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE"),
+dkT("GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS"),
+dkT("INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,"),
+dkT("WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS"),
+dkT("SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+dkT(""),
+dkT("Julian Seward, jseward@bzip.org"),
+dkT("bzip2/libbzip2 version 1.0.5 of 10 December 2007"),
+#endif
+dkT(""),
+NULL
+
+
+#line 218 "dk-recv.ctr"
+};
+
+
+
+/** Constant texts used by the program, not localized.
+*/
+static const dkChar * const dk_recv_kwnl[] = {
+/* 0 */
+dkT("dktools"),
+
+/* 1 */
+dkT("dk-recv.txt"),
+
+/* 2 */
+dkT("dk-recv.str"),
+
+/* 3 */
+dkT("\\"),
+
+/* 4 */
+dkT("wb"),
+
+NULL
+
+
+#line 247 "dk-recv.ctr"
+};
+
+
+
+/** Constant texts used by the program, replaced by localized
+ versions if found.
+*/
+static const dkChar * const dk_recv_kw_def[] = {
+/* 0 */
+dkT("Failed to set up signal handlers!"),
+
+/* 1 */
+dkT("Failed to restore signal handlers!"),
+
+/* 2 */
+dkT("stdin"),
+
+/* 3 */
+dkT("Failed to close file!"),
+
+/* 4 */
+dkT("Timeout too large!"),
+
+/* 5 */
+dkT("Timeout must not be negative!"),
+
+/* 6 */
+dkT("Timeout value not found!"),
+
+/* 7 */
+dkT("Wrong number of arguments!\n\thost port [filename]"),
+
+/* 8 */
+dkT("Interrupted by SIGINT signal!"),
+
+/* 9 */
+dkT("Interrupted by SIGTERM signal!"),
+
+/* 10 */
+dkT("Interrupted by SIGPIPE signal!"),
+
+NULL
+
+
+#line 292 "dk-recv.ctr"
+};
+
+
+
+/** Options used by the program.
+*/
+static const dk4_option_specification_t dk_recv_options[] = {
+
+ /* I am the last client, server can start transmissin now.
+ */
+ { dkT('t'), dkT("transmission"), DK4_OPT_ARG_NONE },
+
+ /* Bind a certain local port number.
+ */
+ { dkT('l'), dkT("local-port"), DK4_OPT_ARG_STRING },
+
+ /* Use a timeout when connecting to the server.
+ */
+ { dkT('c'), dkT("connect-timeout"), DK4_OPT_ARG_DOUBLE }
+};
+
+
+
+/** Array of localized texts, loaded in the main() function.
+ Usable as long as the app pointer below is usable.
+*/
+static const dkChar * const *dk_recv_kw_loc = NULL;
+
+
+
+/** Local port number to use.
+*/
+static const dkChar *dk_recv_portno = NULL;
+
+
+
+/** Application structure for diagnostics.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Number of elements in the dk_recv_options array.
+*/
+static const size_t dk_recv_sz_options =
+sizeof(dk_recv_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Number of elements in the dk_recv_kw_def array.
+*/
+static const size_t dk_recv_sz_def =
+sizeof(dk_recv_kw_def)/sizeof(DK4_PCDKCHAR) - 1;
+
+
+
+/** Number of elements in the dk_recv_kw_def array.
+*/
+static size_t dk_recv_sz_loc =
+sizeof(dk_recv_kw_def)/sizeof(DK4_PCDKCHAR) - 1;
+
+
+
+/** Seconds for timeout.
+*/
+static long dk_recv_timeout_secs = 0L;
+
+
+
+/** Microseconds for timeout.
+*/
+static long dk_recv_timeout_usecs = 0L;
+
+
+
+/** Exit status code.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+/** Flag send to server: Start transmission immediately.
+*/
+static unsigned char start_transmission = 0x00;
+
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+/** Pass a volatile pointer to an atomic integer.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ptr Address of atomic integer variable.
+ @return The unmodified pointer.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+/** Check whether we can continue or if a signal was received.
+ @param check_pipe Flag: Check for occured SIGPIPE signal too.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(int check_pipe)
+{
+ int back = 1;
+#ifdef SIGPIPE
+ if (0 != check_pipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_int )) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+#if 0
+
+/*
+ 2016-01-02:
+ Removed - replaced by sig_can_continue(1) - after profiling.
+*/
+
+/** Check whether we can continue.
+ @return 1 for yes, 0 for no.
+*/
+static
+int
+dk_recv_can_continue(void)
+{
+ int back = 1;
+ if (0 == sig_can_continue(1)) {
+ back = 0;
+ }
+ return back;
+}
+
+#endif
+/* if 0 */
+
+
+
+/** Data buffer
+*/
+#if DK4_SIZEOF_SIZE_T > 2
+static char bu[1048576];
+#else
+static char bu[16384];
+#endif
+
+/** Run for hostname, port specification and real file name
+ (wildcards * and ? resolved on Windows).
+ @param hostname Host to connect to (name or address).
+ @param portspec Port to connect to (number or service name).
+ @param filename File name to write, may be NULL (stdout).
+*/
+static
+void
+dk_recv_run_with_real_file_name(
+ const dkChar *hostname,
+ const dkChar *portspec,
+ const dkChar *filename
+)
+{
+#if 0
+ /* 2016-01-06:
+ Buffer size increased, do not use stack.
+ */
+ char bu[1460]; /* Data buffer */
+#endif
+ FILE *fipo = NULL; /* Output file */
+ size_t sz = 0; /* Buffer sizes */
+ size_t wrb = 0; /* Bytes written */
+ dk4_socket_t sock = INVALID_SOCKET; /* Client socket */
+#if DK4_ON_WINDOWS
+ int oldmode= _O_TEXT; /* File mode stdout */
+#endif
+ int cc = 1; /* Flag: Can continue */
+ int first = 1; /* Flag: First pass */
+ int res = 0; /* Operation result */
+ int we = 0; /* Flag: Write error */
+ int tests = 0;
+
+
+
+#line 553 "dk-recv.ctr"
+ /* Check for signals.
+ */
+ if (0 == sig_can_continue(1)) {
+ goto finished;
+ }
+
+#line 558 "dk-recv.ctr"
+
+ /* Bring socket subsystem up (Windows).
+ */
+ if (DK4_SOCKET_RESULT_SUCCESS != dk4socket_up_app(app)) {
+ /* ERROR: Failed to bring socket subsystem up, already reported */
+ goto finished;
+ }
+
+#line 565 "dk-recv.ctr"
+
+ /* Open TCP client socket.
+ */
+ sock = dk4socket_tcp_client_for_host_service_app(
+ hostname, portspec, dk_recv_portno,
+ dk_recv_timeout_secs, dk_recv_timeout_usecs, app
+ );
+ if (INVALID_SOCKET == sock) {
+ /* ERROR: Failed to create socket, already reported */
+ goto tcpip_down;
+ }
+
+#line 576 "dk-recv.ctr"
+ if (0 == sig_can_continue(1)) {
+ goto close_socket;
+ }
+
+#line 579 "dk-recv.ctr"
+
+ /* Send start-of-transmission byte and shutdown socket for writing.
+ */
+ sz = 1;
+ res = dk4socket_send_app(sock, &start_transmission, &sz, 0, 0L, 0L, app);
+ if (DK4_SOCKET_RESULT_SUCCESS != res) {
+ goto close_socket;
+ }
+
+#line 587 "dk-recv.ctr"
+ if (0 == sig_can_continue(1)) {
+ goto close_socket;
+ }
+
+#line 590 "dk-recv.ctr"
+ res = dk4socket_shutdown_app(sock, DK4_SOCKET_SHUT_WRITE, app);
+ if (DK4_SOCKET_RESULT_SUCCESS != res) {
+ goto close_socket;
+ }
+
+#line 594 "dk-recv.ctr"
+ if (0 == sig_can_continue(1)) {
+ goto close_socket;
+ }
+
+#line 597 "dk-recv.ctr"
+
+ /* Indicate success so far.
+ */
+ exval = EXIT_SUCCESS;
+
+ /* Now receive data.
+ */
+ do {
+ if (0 != sig_can_continue(1)) {
+
+#line 606 "dk-recv.ctr"
+ sz = sizeof(bu);
+ res = dk4socket_recv_app(sock, bu, &sz, 0, 0L, 0L, app);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ if (0 < sz) {
+
+#line 610 "dk-recv.ctr"
+ if (0 != sig_can_continue(1)) {
+ if (0 != first) {
+
+#line 612 "dk-recv.ctr"
+ first = 0;
+ if (NULL != filename) {
+
+#line 614 "dk-recv.ctr"
+ tests = DK4_FOPEN_SC_USER;
+ if (0 != dk4isadmin()) { tests = DK4_FOPEN_SC_PRIVILEGED; }
+ fipo = dk4fopen_app(filename, dk_recv_kwnl[4], tests, app);
+ if (NULL == fipo) {
+
+#line 618 "dk-recv.ctr"
+ exval = EXIT_FAILURE;
+ }
+ } else {
+
+#line 621 "dk-recv.ctr"
+ /* MODE FOR WINDOWS */
+#if DK4_ON_WINDOWS
+ oldmode = _setmode(_fileno(stdout), _O_BINARY);
+#endif
+ fipo = stdout;
+ }
+ }
+ if (NULL != fipo) {
+
+#line 629 "dk-recv.ctr"
+ if (0 == we) {
+
+#line 630 "dk-recv.ctr"
+ errno = 0;
+
+#line 631 "dk-recv.ctr"
+ wrb = fwrite(bu, 1, sz, fipo);
+ if (wrb != sz) {
+
+#line 633 "dk-recv.ctr"
+ we = 1;
+ exval = EXIT_FAILURE;
+ /* ERROR: Write attempt failed */
+ dk4fd_write_error_msg(
+ app,
+ ((filename) ? (filename) : (dk_recv_kw_def[2])),
+ errno
+ );
+ }
+ }
+ }
+ } else {
+
+#line 645 "dk-recv.ctr"
+ cc = -1;
+ }
+ } else {
+
+#line 648 "dk-recv.ctr"
+ cc = 0;
+ }
+ } else {
+
+#line 651 "dk-recv.ctr"
+ cc = -1;
+ }
+ } else {
+
+#line 654 "dk-recv.ctr"
+ cc = -1;
+ }
+ } while (1 == cc);
+
+ /* Cleanup
+ */
+ if (0 == first) {
+
+#line 661 "dk-recv.ctr"
+ if (NULL != filename) {
+
+#line 662 "dk-recv.ctr"
+ if (NULL != fipo) {
+
+#line 663 "dk-recv.ctr"
+ if (0 != fclose(fipo)) {
+
+#line 664 "dk-recv.ctr"
+ /* ERROR: Failed to close file */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 3);
+ exval = EXIT_FAILURE;
+ }
+ }
+ } else {
+
+#line 670 "dk-recv.ctr"
+ if (0 != fflush(stdout)) {
+
+#line 671 "dk-recv.ctr"
+ exval = EXIT_FAILURE;
+ }
+#if DK4_ON_WINDOWS
+ _setmode(_fileno(stdout), oldmode);
+#endif
+ }
+ }
+
+ /* Close socket if open.
+ */
+ close_socket:
+ if (INVALID_SOCKET != sock) {
+
+#line 683 "dk-recv.ctr"
+ dk4socket_close_app(sock, app);
+ }
+
+ /* Shut socket subsystem down (Windows).
+ */
+ tcpip_down:
+ dk4socket_down_app(app);
+
+#line 690 "dk-recv.ctr"
+
+ finished: ;
+
+
+#line 693 "dk-recv.ctr"
+}
+
+
+
+#if DK4_ON_WINDOWS
+/** Expand file name and run for host, port and file name.
+ @param hostname Host name or address to connect to.
+ @param portspec Remote port to connect to.
+ @param filename File name pattern to expand.
+*/
+static
+void
+dk_recv_expand_file_name(
+ const dkChar *hostname,
+ const dkChar *portspec,
+ const dkChar *filename
+)
+{
+ dkChar buf[DK4_MAX_PATH];
+ dk4_dir_t *fne;
+ const dkChar *pt;
+ const dkChar *fn;
+ size_t szbuf;
+ int copied;
+
+ fne = dk4app_fne_open(filename, app);
+ if (NULL != fne) {
+ fn = dk4dir_next_file(fne);
+ if (NULL != fn) {
+ pt = dk4dir_get_path(fne);
+ if (NULL == dk4dir_next_file(fne)) {
+ if (NULL != pt) {
+ szbuf = DK4_SIZEOF(buf, dkChar);
+ copied = 0;
+ if (0 != dk4str_cpy_s(buf, szbuf, pt, NULL)) {
+ if (0 != dk4str_cat_s(buf, szbuf, dk_recv_kwnl[3], NULL)) {
+ if (0 != dk4str_cat_s(buf, szbuf, fn, NULL)) {
+ copied = 1;
+ dk_recv_run_with_real_file_name(hostname, portspec, buf);
+ }
+ }
+ }
+ if (0 == copied) {
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 105, filename);
+ }
+ } else {
+ dk_recv_run_with_real_file_name(hostname, portspec, fn);
+ }
+ } else {
+ /* ERROR: Not a unique file name */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 106, filename);
+ }
+ } else {
+ /* ERROR: No such file */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 107, filename);
+ }
+ dk4dir_close(fne);
+ }
+}
+#endif
+
+
+
+/** Run for given host, port and file name.
+ @param hostname Host name or address to connect to.
+ @param portspec Remote port to connect to.
+ @param filename File name to write to, may be NULL (stdout).
+*/
+static
+void
+dk_recv_run_for_arguments(
+ const dkChar *hostname,
+ const dkChar *portspec,
+ const dkChar *filename
+)
+{
+#if DK4_ON_WINDOWS
+ if (0 != dk4path_must_expand(filename)) {
+ dk_recv_expand_file_name(hostname, portspec, filename);
+ } else {
+#endif
+ dk_recv_run_with_real_file_name(hostname, portspec, filename);
+#if DK4_ON_WINDOWS
+ }
+#endif
+}
+
+
+
+/** Process options, retrieve command line arguments and run
+ for given host, port and optionally file name.
+*/
+static
+void
+dk_recv_normal_run(void)
+{
+ double timeout;
+ double d1;
+ double d2;
+ int xargc;
+ int canrun;
+
+
+#line 796 "dk-recv.ctr"
+ canrun = 1;
+ /* Timeout specified?
+ */
+ if (0 != dk4app_opt_is_set_short(app, dkT('t'), NULL)) {
+ start_transmission = 0x01;
+ }
+ /* Local port number specified?
+ */
+ if (0 != dk4app_opt_is_set_short(app, dkT('l'), NULL)) {
+ dk_recv_portno = dk4app_opt_get_string_ptr_short(app, dkT('l'), NULL);
+ }
+ /* Connection timeout specified?
+ */
+ if (0 != dk4app_opt_is_set_short(app, dkT('c'), NULL)) {
+ if (0 != dk4app_opt_get_double_short(&timeout, app, dkT('c'), NULL)) {
+ if (0.0 <= timeout) {
+ d1 = floor(timeout);
+ d2 = timeout - d1;
+ d2 = 1000000.0 * d2;
+ if ((double)(LONG_MAX) >= d1) {
+ dk_recv_timeout_secs = (long)d1;
+ dk_recv_timeout_usecs = (long)d2;
+ } else {
+ canrun = 0;
+ /* ERROR: Timeout too large */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 4);
+ }
+ } else {
+ /* Warning: Can not use a negative timeout */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_WARNING, 5);
+ }
+ } else {
+ canrun = 0;
+ /* No timeout value found ! */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 6);
+ }
+ }
+ if (0 != canrun) {
+ xargc = dk4app_get_argc(app);
+ switch (xargc) {
+ case 2: {
+ dk_recv_run_for_arguments(
+ dk4app_get_argv(app, 0),
+ dk4app_get_argv(app, 1),
+ NULL
+ );
+ } break;
+ case 3: {
+ dk_recv_run_for_arguments(
+ dk4app_get_argv(app, 0),
+ dk4app_get_argv(app, 1),
+ dk4app_get_argv(app, 2)
+ );
+ } break;
+ default : {
+ /* ERROR: Wrong number of arguments */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 7);
+ } break;
+ }
+ }
+
+
+#line 857 "dk-recv.ctr"
+}
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+dk_recv_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ struct sigaction opipe;
+#endif
+ struct sigaction oint;
+#ifdef SIGPIPE
+ struct sigaction npipe;
+#endif
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+ int success = 0;
+
+#ifdef SIGPIPE
+ /* Set up signal handling for SIGPIPE.
+ */
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+#endif
+
+ /* Set up signal handling for SIGINT.
+ */
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ dk_recv_normal_run();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+#ifdef SIGPIPE
+ /* Restore signal handling for SIGPIPE.
+ */
+ restore_old_pipe:
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+#endif
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+dk_recv_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ dk_recv_normal_run();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+#ifdef SIGPIPE
+ sigset(SIGPIPE, oldpipe);
+#endif
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+dk_recv_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = signal(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ dk_recv_normal_run();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+#ifdef SIGPIPE
+ signal(SIGPIPE, oldpipe);
+#endif
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+dk_recv_run_with_signal_handlers(void)
+{
+ dk_recv_normal_run();
+}
+#endif
+#endif
+#endif
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+
+
+#line 1060 "dk-recv.ctr"
+
+
+#line 1061 "dk-recv.ctr"
+ dk4fput_initialize_stderr();
+ app = dk4app_open_cmd(
+ argc, argv, dk_recv_options, dk_recv_sz_options,
+ dk_recv_kwnl[0], DKT_VERSION_DK,
+ dk_recv_kwnl[1], dk_recv_help_text, dk_recv_license_text
+ );
+ if (NULL != app) {
+
+#line 1068 "dk-recv.ctr"
+ dk_recv_sz_loc = dk4app_string_table_size(dk_recv_kw_def);
+ dk_recv_kw_loc = dk4app_string_table(app, dk_recv_kwnl[2], dk_recv_kw_def);
+ dk_recv_sz_loc = dk4app_string_table_size(dk_recv_kw_loc);
+ if (0 != dk4app_can_run_normally(app)) {
+ dk_recv_run_with_signal_handlers();
+ } else {
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ if (0 != sig_read_atomic(&sig_had_int )) {
+ /* Interrupted by SIGINT */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 8);
+ }
+ if (0 != sig_read_atomic(&sig_had_term)) {
+ /* Interrupted by SIGTERM */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 9);
+ }
+#if defined(SIGPIPE)
+ if (0 != sig_read_atomic(&sig_had_pipe)) {
+ /* Interrupted by SIGPIPE */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 10);
+ }
+#endif
+ dk4app_close(app); app = NULL;
+ } else {
+
+#line 1094 "dk-recv.ctr"
+ }
+ fflush(stderr);
+ dk4fput_cleanup_stderr();
+ if (0 != sig_read_atomic(&sig_had_int )) {
+ exval = EXIT_FAILURE;
+ }
+ if (0 != sig_read_atomic(&sig_had_term)) {
+ exval = EXIT_FAILURE;
+ }
+#if defined(SIGPIPE)
+ if (0 != sig_read_atomic(&sig_had_pipe)) {
+ exval = EXIT_FAILURE;
+ }
+#endif
+
+
+#line 1109 "dk-recv.ctr"
+
+
+#line 1110 "dk-recv.ctr"
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/dk-recv.ctr b/support/dktools/dk-recv.ctr
new file mode 100644
index 0000000000..c00d3c458c
--- /dev/null
+++ b/support/dktools/dk-recv.ctr
@@ -0,0 +1,1112 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_MATH_H
+#ifndef MATH_H_INCLUDED
+#include <math.h>
+#define MATH_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4sock.h"
+#include "dk4socka.h"
+#include "dk4fput.h"
+#include "dk4vers.h"
+#include "dk4aopt.h"
+#include "dk4numco.h"
+#include "dk4fopda.h"
+#include "dk4isadm.h"
+#include "dk4fdwre.h"
+#include "dk4mpl.h"
+#include "dk4mem.h"
+#include "dk4mema.h"
+#include "dk4strd.h"
+#include "dk4pathd.h"
+
+
+
+$!trace-include
+
+
+
+/** Default help text, shown if no localized help text is found.
+*/
+static const dkChar * const dk_recv_help_text[] = {
+$!text macro=dkT
+
+Receive data from a dk-send process.
+
+dk-recv [<options>] <host> <port> [<file>]
+
+Arguments:
+host Sender host to connect to (name or IP).
+port Port number to connect to.
+file Output file to create. Default: Write to standard output.
+
+Options:
+-t Tell peer to start transmission.
+-l <port> Local port number to bind.
+-c <int> Timeout for connect attempt.
+
+--help Show this short help text.
+--manual *** SHOW FULL MANUAL. ***
+--version Show version information.
+--license Show license information.
+
+$!end
+};
+
+
+
+/** License text.
+*/
+static const dkChar * const dk_recv_license_text[] = {
+$!text macro=dkT,preprocessor
+This software uses code from the following projects, either directly or as
+a library:
+
+dktools Dirk Krause's tools and libraries.
+ See http://dktools.sourceforge.net/ for more information.
+#if DK4_HAVE_ZLIB_H
+
+zlib Data compression library.
+ See http://www.zlib.net/ for more information.
+#endif
+#if DK4_HAVE_BZLIB_H
+
+bzip2 Data compression program and library.
+ See http://www.bzip.org/ for more information.
+#endif
+
+All the licenses below apply to the program.
+Licenses for used libraries are shown as found on my Scientific Linux 6.x
+computer in the /usr/share/doc directory on 2015-04-01. Check the project
+homepages of the used libraries for additional information and/or updated
+license terms.
+
+
+DK tools and libraries license
+==============================
+Copyright (c) 2015-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#if DK4_HAVE_ZLIB_H
+
+
+Zlib license
+============
+(C) 1995-2004 Jean-loup Gailly and Mark Adler
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+
+Jean-loup Gailly Mark Adler
+jloup@gzip.org madler@alumni.caltech.edu
+#endif
+#if DK4_HAVE_BZLIB_H
+
+
+Bzip2 and libbzip2 library license
+==================================
+This program, "bzip2", the associated library "libbzip2", and all
+documentation, are copyright (C) 1996-2007 Julian R Seward. All
+rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+3. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Julian Seward, jseward@bzip.org
+bzip2/libbzip2 version 1.0.5 of 10 December 2007
+#endif
+
+$!end
+};
+
+
+
+/** Constant texts used by the program, not localized.
+*/
+static const dkChar * const dk_recv_kwnl[] = {
+$!string-table macro=dkT
+#
+# 0 Program group name
+#
+dktools
+#
+# 1 Help file name
+#
+dk-recv.txt
+#
+# 2 String table file name
+#
+dk-recv.str
+#
+# 3 Path component separator for windows
+#
+\\
+#
+# 4 File open mode for binary writing
+#
+wb
+$!end
+};
+
+
+
+/** Constant texts used by the program, replaced by localized
+ versions if found.
+*/
+static const dkChar * const dk_recv_kw_def[] = {
+$!string-table macro=dkT
+#
+# 0 1 Error: Failed to set up / restore signal handlers!
+#
+Failed to set up signal handlers!
+Failed to restore signal handlers!
+#
+# 2 File name "stdin" for error message
+#
+stdin
+#
+# 3 Error: Failed to close file!
+#
+Failed to close file!
+#
+# 4 Error: Timeout too large!
+#
+Timeout too large!
+#
+# 5 Error: Timeout must not be negative!
+#
+Timeout must not be negative!
+#
+# 6 Error: Timeout value not found!
+#
+Timeout value not found!
+#
+# 7 Error: Wrong number of arguments!
+#
+Wrong number of arguments!\n\thost port [filename]
+#
+# 8 9 10 Error: Interrupted by ... signal!
+#
+Interrupted by SIGINT signal!
+Interrupted by SIGTERM signal!
+Interrupted by SIGPIPE signal!
+$!end
+};
+
+
+
+/** Options used by the program.
+*/
+static const dk4_option_specification_t dk_recv_options[] = {
+
+ /* I am the last client, server can start transmissin now.
+ */
+ { dkT('t'), dkT("transmission"), DK4_OPT_ARG_NONE },
+
+ /* Bind a certain local port number.
+ */
+ { dkT('l'), dkT("local-port"), DK4_OPT_ARG_STRING },
+
+ /* Use a timeout when connecting to the server.
+ */
+ { dkT('c'), dkT("connect-timeout"), DK4_OPT_ARG_DOUBLE }
+};
+
+
+
+/** Array of localized texts, loaded in the main() function.
+ Usable as long as the app pointer below is usable.
+*/
+static const dkChar * const *dk_recv_kw_loc = NULL;
+
+
+
+/** Local port number to use.
+*/
+static const dkChar *dk_recv_portno = NULL;
+
+
+
+/** Application structure for diagnostics.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Number of elements in the dk_recv_options array.
+*/
+static const size_t dk_recv_sz_options =
+sizeof(dk_recv_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Number of elements in the dk_recv_kw_def array.
+*/
+static const size_t dk_recv_sz_def =
+sizeof(dk_recv_kw_def)/sizeof(DK4_PCDKCHAR) - 1;
+
+
+
+/** Number of elements in the dk_recv_kw_def array.
+*/
+static size_t dk_recv_sz_loc =
+sizeof(dk_recv_kw_def)/sizeof(DK4_PCDKCHAR) - 1;
+
+
+
+/** Seconds for timeout.
+*/
+static long dk_recv_timeout_secs = 0L;
+
+
+
+/** Microseconds for timeout.
+*/
+static long dk_recv_timeout_usecs = 0L;
+
+
+
+/** Exit status code.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+/** Flag send to server: Start transmission immediately.
+*/
+static unsigned char start_transmission = 0x00;
+
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+/** Pass a volatile pointer to an atomic integer.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ptr Address of atomic integer variable.
+ @return The unmodified pointer.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+/** Check whether we can continue or if a signal was received.
+ @param check_pipe Flag: Check for occured SIGPIPE signal too.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(int check_pipe)
+{
+ int back = 1;
+#ifdef SIGPIPE
+ if (0 != check_pipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_int )) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+#if 0
+
+/*
+ 2016-01-02:
+ Removed - replaced by sig_can_continue(1) - after profiling.
+*/
+
+/** Check whether we can continue.
+ @return 1 for yes, 0 for no.
+*/
+static
+int
+dk_recv_can_continue(void)
+{
+ int back = 1;
+ if (0 == sig_can_continue(1)) {
+ back = 0;
+ }
+ return back;
+}
+
+#endif
+/* if 0 */
+
+
+
+/** Data buffer
+*/
+#if DK4_SIZEOF_SIZE_T > 2
+static char bu[1048576];
+#else
+static char bu[16384];
+#endif
+
+/** Run for hostname, port specification and real file name
+ (wildcards * and ? resolved on Windows).
+ @param hostname Host to connect to (name or address).
+ @param portspec Port to connect to (number or service name).
+ @param filename File name to write, may be NULL (stdout).
+*/
+static
+void
+dk_recv_run_with_real_file_name(
+ const dkChar *hostname,
+ const dkChar *portspec,
+ const dkChar *filename
+)
+{
+#if 0
+ /* 2016-01-06:
+ Buffer size increased, do not use stack.
+ */
+ char bu[1460]; /* Data buffer */
+#endif
+ FILE *fipo = NULL; /* Output file */
+ size_t sz = 0; /* Buffer sizes */
+ size_t wrb = 0; /* Bytes written */
+ dk4_socket_t sock = INVALID_SOCKET; /* Client socket */
+#if DK4_ON_WINDOWS
+ int oldmode= _O_TEXT; /* File mode stdout */
+#endif
+ int cc = 1; /* Flag: Can continue */
+ int first = 1; /* Flag: First pass */
+ int res = 0; /* Operation result */
+ int we = 0; /* Flag: Write error */
+ int tests = 0;
+
+ $? "+ dk_recv_run_with_real_file_name"
+ /* Check for signals.
+ */
+ if (0 == sig_can_continue(1)) {
+ goto finished;
+ } $? ". no signals received yet"
+
+ /* Bring socket subsystem up (Windows).
+ */
+ if (DK4_SOCKET_RESULT_SUCCESS != dk4socket_up_app(app)) {
+ /* ERROR: Failed to bring socket subsystem up, already reported */
+ goto finished;
+ } $? ". socket subsystem up"
+
+ /* Open TCP client socket.
+ */
+ sock = dk4socket_tcp_client_for_host_service_app(
+ hostname, portspec, dk_recv_portno,
+ dk_recv_timeout_secs, dk_recv_timeout_usecs, app
+ );
+ if (INVALID_SOCKET == sock) {
+ /* ERROR: Failed to create socket, already reported */
+ goto tcpip_down;
+ } $? ". socket created"
+ if (0 == sig_can_continue(1)) {
+ goto close_socket;
+ } $? ". no signal yet"
+
+ /* Send start-of-transmission byte and shutdown socket for writing.
+ */
+ sz = 1;
+ res = dk4socket_send_app(sock, &start_transmission, &sz, 0, 0L, 0L, app);
+ if (DK4_SOCKET_RESULT_SUCCESS != res) {
+ goto close_socket;
+ } $? ". initial byte sent"
+ if (0 == sig_can_continue(1)) {
+ goto close_socket;
+ } $? ". no signal yet"
+ res = dk4socket_shutdown_app(sock, DK4_SOCKET_SHUT_WRITE, app);
+ if (DK4_SOCKET_RESULT_SUCCESS != res) {
+ goto close_socket;
+ } $? ". shut down for writing"
+ if (0 == sig_can_continue(1)) {
+ goto close_socket;
+ } $? ". no signal yet"
+
+ /* Indicate success so far.
+ */
+ exval = EXIT_SUCCESS;
+
+ /* Now receive data.
+ */
+ do {
+ if (0 != sig_can_continue(1)) { $? ". can continue"
+ sz = sizeof(bu);
+ res = dk4socket_recv_app(sock, bu, &sz, 0, 0L, 0L, app);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ if (0 < sz) { $? ". %u bytes found", (unsigned)sz
+ if (0 != sig_can_continue(1)) {
+ if (0 != first) { $? ". first data packet"
+ first = 0;
+ if (NULL != filename) { $? ". have file name"
+ tests = DK4_FOPEN_SC_USER;
+ if (0 != dk4isadmin()) { tests = DK4_FOPEN_SC_PRIVILEGED; }
+ fipo = dk4fopen_app(filename, dk_recv_kwnl[4], tests, app);
+ if (NULL == fipo) { $? "! failed to open file"
+ exval = EXIT_FAILURE;
+ }
+ } else { $? ". no file name, use stdout"
+ /* MODE FOR WINDOWS */
+#if DK4_ON_WINDOWS
+ oldmode = _setmode(_fileno(stdout), _O_BINARY);
+#endif
+ fipo = stdout;
+ }
+ }
+ if (NULL != fipo) { $? ". have output file"
+ if (0 == we) { $? ". no write error yet"
+ errno = 0; $? ". size %u", (unsigned)sz
+ wrb = fwrite(bu, 1, sz, fipo);
+ if (wrb != sz) { $? "! write error"
+ we = 1;
+ exval = EXIT_FAILURE;
+ /* ERROR: Write attempt failed */
+ dk4fd_write_error_msg(
+ app,
+ ((filename) ? (filename) : (dk_recv_kw_def[2])),
+ errno
+ );
+ }
+ }
+ }
+ } else { $? "! signal"
+ cc = -1;
+ }
+ } else { $? ". no more data available"
+ cc = 0;
+ }
+ } else { $? "! failed to receive data"
+ cc = -1;
+ }
+ } else { $? "! signal"
+ cc = -1;
+ }
+ } while (1 == cc);
+
+ /* Cleanup
+ */
+ if (0 == first) { $? ". must clean up"
+ if (NULL != filename) { $? ". have file name"
+ if (NULL != fipo) { $? ". have file"
+ if (0 != fclose(fipo)) { $? "! failed to close file"
+ /* ERROR: Failed to close file */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 3);
+ exval = EXIT_FAILURE;
+ }
+ }
+ } else { $? ". no file name"
+ if (0 != fflush(stdout)) { $? "! failed to flush stdout"
+ exval = EXIT_FAILURE;
+ }
+#if DK4_ON_WINDOWS
+ _setmode(_fileno(stdout), oldmode);
+#endif
+ }
+ }
+
+ /* Close socket if open.
+ */
+ close_socket:
+ if (INVALID_SOCKET != sock) { $? ". close socket"
+ dk4socket_close_app(sock, app);
+ }
+
+ /* Shut socket subsystem down (Windows).
+ */
+ tcpip_down:
+ dk4socket_down_app(app); $? ". TCP/IP subsystem down"
+
+ finished: ;
+ $? "- dk_recv_run_with_real_file_name"
+}
+
+
+
+#if DK4_ON_WINDOWS
+/** Expand file name and run for host, port and file name.
+ @param hostname Host name or address to connect to.
+ @param portspec Remote port to connect to.
+ @param filename File name pattern to expand.
+*/
+static
+void
+dk_recv_expand_file_name(
+ const dkChar *hostname,
+ const dkChar *portspec,
+ const dkChar *filename
+)
+{
+ dkChar buf[DK4_MAX_PATH];
+ dk4_dir_t *fne;
+ const dkChar *pt;
+ const dkChar *fn;
+ size_t szbuf;
+ int copied;
+
+ fne = dk4app_fne_open(filename, app);
+ if (NULL != fne) {
+ fn = dk4dir_next_file(fne);
+ if (NULL != fn) {
+ pt = dk4dir_get_path(fne);
+ if (NULL == dk4dir_next_file(fne)) {
+ if (NULL != pt) {
+ szbuf = DK4_SIZEOF(buf, dkChar);
+ copied = 0;
+ if (0 != dk4str_cpy_s(buf, szbuf, pt, NULL)) {
+ if (0 != dk4str_cat_s(buf, szbuf, dk_recv_kwnl[3], NULL)) {
+ if (0 != dk4str_cat_s(buf, szbuf, fn, NULL)) {
+ copied = 1;
+ dk_recv_run_with_real_file_name(hostname, portspec, buf);
+ }
+ }
+ }
+ if (0 == copied) {
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 105, filename);
+ }
+ } else {
+ dk_recv_run_with_real_file_name(hostname, portspec, fn);
+ }
+ } else {
+ /* ERROR: Not a unique file name */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 106, filename);
+ }
+ } else {
+ /* ERROR: No such file */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 107, filename);
+ }
+ dk4dir_close(fne);
+ }
+}
+#endif
+
+
+
+/** Run for given host, port and file name.
+ @param hostname Host name or address to connect to.
+ @param portspec Remote port to connect to.
+ @param filename File name to write to, may be NULL (stdout).
+*/
+static
+void
+dk_recv_run_for_arguments(
+ const dkChar *hostname,
+ const dkChar *portspec,
+ const dkChar *filename
+)
+{
+#if DK4_ON_WINDOWS
+ if (0 != dk4path_must_expand(filename)) {
+ dk_recv_expand_file_name(hostname, portspec, filename);
+ } else {
+#endif
+ dk_recv_run_with_real_file_name(hostname, portspec, filename);
+#if DK4_ON_WINDOWS
+ }
+#endif
+}
+
+
+
+/** Process options, retrieve command line arguments and run
+ for given host, port and optionally file name.
+*/
+static
+void
+dk_recv_normal_run(void)
+{
+ double timeout;
+ double d1;
+ double d2;
+ int xargc;
+ int canrun;
+ $? "+ dk_recv_normal_run"
+ canrun = 1;
+ /* Timeout specified?
+ */
+ if (0 != dk4app_opt_is_set_short(app, dkT('t'), NULL)) {
+ start_transmission = 0x01;
+ }
+ /* Local port number specified?
+ */
+ if (0 != dk4app_opt_is_set_short(app, dkT('l'), NULL)) {
+ dk_recv_portno = dk4app_opt_get_string_ptr_short(app, dkT('l'), NULL);
+ }
+ /* Connection timeout specified?
+ */
+ if (0 != dk4app_opt_is_set_short(app, dkT('c'), NULL)) {
+ if (0 != dk4app_opt_get_double_short(&timeout, app, dkT('c'), NULL)) {
+ if (0.0 <= timeout) {
+ d1 = floor(timeout);
+ d2 = timeout - d1;
+ d2 = 1000000.0 * d2;
+ if ((double)(LONG_MAX) >= d1) {
+ dk_recv_timeout_secs = (long)d1;
+ dk_recv_timeout_usecs = (long)d2;
+ } else {
+ canrun = 0;
+ /* ERROR: Timeout too large */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 4);
+ }
+ } else {
+ /* Warning: Can not use a negative timeout */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_WARNING, 5);
+ }
+ } else {
+ canrun = 0;
+ /* No timeout value found ! */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 6);
+ }
+ }
+ if (0 != canrun) {
+ xargc = dk4app_get_argc(app);
+ switch (xargc) {
+ case 2: {
+ dk_recv_run_for_arguments(
+ dk4app_get_argv(app, 0),
+ dk4app_get_argv(app, 1),
+ NULL
+ );
+ } break;
+ case 3: {
+ dk_recv_run_for_arguments(
+ dk4app_get_argv(app, 0),
+ dk4app_get_argv(app, 1),
+ dk4app_get_argv(app, 2)
+ );
+ } break;
+ default : {
+ /* ERROR: Wrong number of arguments */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 7);
+ } break;
+ }
+ }
+ $? "- dk_recv_normal_run"
+}
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+dk_recv_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ struct sigaction opipe;
+#endif
+ struct sigaction oint;
+#ifdef SIGPIPE
+ struct sigaction npipe;
+#endif
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+ int success = 0;
+
+#ifdef SIGPIPE
+ /* Set up signal handling for SIGPIPE.
+ */
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+#endif
+
+ /* Set up signal handling for SIGINT.
+ */
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ dk_recv_normal_run();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+#ifdef SIGPIPE
+ /* Restore signal handling for SIGPIPE.
+ */
+ restore_old_pipe:
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+#endif
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+dk_recv_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ dk_recv_normal_run();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+#ifdef SIGPIPE
+ sigset(SIGPIPE, oldpipe);
+#endif
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+dk_recv_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = signal(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ dk_recv_normal_run();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+#ifdef SIGPIPE
+ signal(SIGPIPE, oldpipe);
+#endif
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+dk_recv_run_with_signal_handlers(void)
+{
+ dk_recv_normal_run();
+}
+#endif
+#endif
+#endif
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ $!trace-init dk-recv.deb
+ $? "+ main"
+ dk4fput_initialize_stderr();
+ app = dk4app_open_cmd(
+ argc, argv, dk_recv_options, dk_recv_sz_options,
+ dk_recv_kwnl[0], DKT_VERSION_DK,
+ dk_recv_kwnl[1], dk_recv_help_text, dk_recv_license_text
+ );
+ if (NULL != app) { $? ". app"
+ dk_recv_sz_loc = dk4app_string_table_size(dk_recv_kw_def);
+ dk_recv_kw_loc = dk4app_string_table(app, dk_recv_kwnl[2], dk_recv_kw_def);
+ dk_recv_sz_loc = dk4app_string_table_size(dk_recv_kw_loc);
+ if (0 != dk4app_can_run_normally(app)) {
+ dk_recv_run_with_signal_handlers();
+ } else {
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ if (0 != sig_read_atomic(&sig_had_int )) {
+ /* Interrupted by SIGINT */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 8);
+ }
+ if (0 != sig_read_atomic(&sig_had_term)) {
+ /* Interrupted by SIGTERM */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 9);
+ }
+#if defined(SIGPIPE)
+ if (0 != sig_read_atomic(&sig_had_pipe)) {
+ /* Interrupted by SIGPIPE */
+ dk4app_log_1(app, dk_recv_kw_loc, dk_recv_sz_loc, DK4_LL_ERROR, 10);
+ }
+#endif
+ dk4app_close(app); app = NULL;
+ } else { $? "! app"
+ }
+ fflush(stderr);
+ dk4fput_cleanup_stderr();
+ if (0 != sig_read_atomic(&sig_had_int )) {
+ exval = EXIT_FAILURE;
+ }
+ if (0 != sig_read_atomic(&sig_had_term)) {
+ exval = EXIT_FAILURE;
+ }
+#if defined(SIGPIPE)
+ if (0 != sig_read_atomic(&sig_had_pipe)) {
+ exval = EXIT_FAILURE;
+ }
+#endif
+ $? "- main %d", exval
+ $!trace-end
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/dk-recv.rc b/support/dktools/dk-recv.rc
new file mode 100644
index 0000000000..e63ed5e247
--- /dev/null
+++ b/support/dktools/dk-recv.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Receive data transmission\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "Receive data transmission\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "dk-recv\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/dk-send.c b/support/dktools/dk-send.c
new file mode 100644
index 0000000000..07dc0ed6e8
--- /dev/null
+++ b/support/dktools/dk-send.c
@@ -0,0 +1,1901 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk-send.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk-send.c The dk-send module.
+*/
+
+
+#line 10 "dk-send.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_MATH_H
+#ifndef MATH_H_INCLUDED
+#include <math.h>
+#define MATH_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4app.h"
+#include "dk4aopt.h"
+#include "dk4socka.h"
+#include "dk4maidddu.h"
+#include "dk4mpl.h"
+#include "dk4vers.h"
+#include "dk4isadm.h"
+#include "dk4strd.h"
+#include "dk4strda.h"
+#include "dk4mem.h"
+#include "dk4mema.h"
+#include "dk4fopda.h"
+#include "dk4pathd.h"
+
+
+
+
+
+#line 58 "dk-send.ctr"
+
+
+
+/** Connected peer.
+*/
+typedef struct {
+ dk4_sockaddr_storage_t peeraddr; /**< Peer address. */
+ dk4_um_t num; /**< Number of client. */
+ size_t peerlen; /**< Length of peer address. */
+ dk4_socket_t sock; /**< Socket for transfer. */
+} dk_send_client_t;
+
+
+
+/** Constant texts used by the program, not localized.
+*/
+static const dkChar * const dk_send_kwnl[] = {
+/* 0 */
+dkT("dktools"),
+
+/* 1 */
+dkT("dk-send.txt"),
+
+/* 2 */
+dkT("dk-send.str"),
+
+/* 3 */
+dkT("unlimited"),
+
+/* 4 */
+dkT("\\"),
+
+/* 5 */
+dkT("rb"),
+
+NULL
+
+
+#line 101 "dk-send.ctr"
+};
+
+
+
+/** Text used by the program, replaced by localized texts if found.
+*/
+static const dkChar * const dk_send_kw_def[] = {
+/* 0 */
+dkT("Failed to set up signal handlers!"),
+
+/* 1 */
+dkT("Failed to restore signal handlers!"),
+
+/* 2 */
+dkT("stdin"),
+
+/* 3 */
+dkT("Accepting incoming connection requests."),
+
+/* 4 */
+dkT("Problem with peer address length!"),
+
+/* 5 */
+dkT("Connected: "),
+
+/* 6 */
+dkT("Rejected: "),
+
+/* 7 */
+dkT("Starting data transfer."),
+
+/* 8 */
+dkT("Finished data transfer."),
+
+/* 9 */
+dkT("Disconnected: "),
+
+/* 10 */
+dkT("Invalid number of clients \""),
+
+/* 11 */
+dkT("\"!"),
+
+/* 12 */
+dkT("Wrong number of command line arguments!"),
+
+/* 13 */
+dkT("Aborted by INT signal!"),
+
+/* 14 */
+dkT("Aborted by TERM signal!"),
+
+/* 15 */
+dkT("Not a dk-send client: "),
+
+/* 16 */
+dkT("Timeout too large!"),
+
+/* 17 */
+dkT("Timeout must not be negative!"),
+
+/* 18 */
+dkT("Timeout value not found!"),
+
+/* 19 */
+dkT("Stop processing as all clients are disconnected!"),
+
+NULL
+
+
+#line 181 "dk-send.ctr"
+};
+
+
+
+/** Short help text.
+*/
+static const dkChar * const dk_send_help_text[] = {
+dkT(""),
+dkT("Send file to one or multiple recipients (dk-recv processes)."),
+dkT(""),
+dkT("dk-send [<options>] <port> [<file>]"),
+dkT(""),
+dkT("Options:"),
+dkT("-n <int>\t\t\tNumber of clients, ``unlimited'' or 0"),
+dkT("\t\t\t\tfor no limit."),
+dkT("-a <address>[/<mask>][,...]\tAllowed clients."),
+dkT("-l\t\t\t\tListen on local host ports only."),
+dkT("-b <unsigned>\t\t\tListen backlog (number of connection attempts"),
+dkT("\t\t\t\tto queue)."),
+dkT("-c <timeout>\t\t\tTimeout for read attempt after establishing"),
+dkT("\t\t\t\ta new connection."),
+dkT("-p\t\t\t\tRunning as sink in a pipe (do not abort reading"),
+dkT("\t\t\t\tinput if all clients disconnected unexpectedly)."),
+dkT("--help\t\t\t\tShow this short help text."),
+dkT("--manual\t\t\t*** SHOW FULL MANUAL. ***"),
+dkT("--version\t\t\tShow version information."),
+dkT("--license\t\t\tShow license information."),
+dkT(""),
+NULL
+
+
+#line 211 "dk-send.ctr"
+};
+
+
+
+/** License text.
+*/
+static const dkChar * const dk_send_license_text[] = {
+dkT("This software uses code from the following projects, either directly or as"),
+dkT("a library:"),
+dkT(""),
+dkT("dktools\t\tDirk Krause's tools and libraries."),
+dkT("\t\tSee http://dktools.sourceforge.net/ for more information."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT("zlib\t\tData compression library."),
+dkT("\t\tSee http://www.zlib.net/ for more information."),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT("bzip2\t\tData compression program and library."),
+dkT("\t\tSee http://www.bzip.org/ for more information."),
+#endif
+#if DK4_HAVE_OPENSSL_MD5_H && DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_OPENSSL_RIPEMD_H
+dkT(""),
+dkT("OpenSSL\t\tCryptographic toolkit, used to build file checksums here."),
+dkT("\t\tSee http://www.openssl.org/ for more information."),
+dkT(""),
+dkT("This product includes software developed by the OpenSSL Project for use in"),
+dkT("the OpenSSL Toolkit (http://www.openssl.org/)."),
+dkT("This product includes cryptographic software written by"),
+dkT("Eric Young (eay@cryptsoft.com)."),
+dkT("This product includes software written by Tim Hudson (tjh@cryptsoft.com)."),
+#endif
+dkT(""),
+dkT("All the licenses below apply to the program."),
+dkT("Licenses for used libraries are shown as found on my Scientific Linux 6.x"),
+dkT("computer in the /usr/share/doc directory on 2015-04-01. Check the project"),
+dkT("homepages of the used libraries for additional information and/or updated"),
+dkT("license terms."),
+dkT(""),
+dkT(""),
+dkT("DK tools and libraries license"),
+dkT("=============================="),
+dkT("Copyright (c) 2015-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above copyright notice,"),
+dkT(" this list of conditions and the following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("* Neither the name of the Dirk Krause nor the names of contributors may be"),
+dkT(" used to endorse or promote products derived from this software without"),
+dkT(" specific prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\""),
+dkT("AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED."),
+dkT(""),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,"),
+dkT("INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,"),
+dkT("BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,"),
+dkT("DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY"),
+dkT("OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,"),
+dkT("EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT(""),
+dkT("Zlib license"),
+dkT("============"),
+dkT("(C) 1995-2004 Jean-loup Gailly and Mark Adler"),
+dkT(""),
+dkT("This software is provided 'as-is', without any express or implied"),
+dkT("warranty. In no event will the authors be held liable for any damages"),
+dkT("arising from the use of this software."),
+dkT(""),
+dkT("Permission is granted to anyone to use this software for any purpose,"),
+dkT("including commercial applications, and to alter it and redistribute it"),
+dkT("freely, subject to the following restrictions:"),
+dkT(""),
+dkT("1. The origin of this software must not be misrepresented; you must not"),
+dkT(" claim that you wrote the original software. If you use this software"),
+dkT(" in a product, an acknowledgment in the product documentation would be"),
+dkT(" appreciated but is not required."),
+dkT("2. Altered source versions must be plainly marked as such, and must not be"),
+dkT(" misrepresented as being the original software."),
+dkT("3. This notice may not be removed or altered from any source distribution."),
+dkT(""),
+dkT("Jean-loup Gailly Mark Adler"),
+dkT("jloup@gzip.org madler@alumni.caltech.edu"),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT(""),
+dkT("Bzip2 and libbzip2 library license"),
+dkT("=================================="),
+dkT("This program, \"bzip2\", the associated library \"libbzip2\", and all"),
+dkT("documentation, are copyright (C) 1996-2007 Julian R Seward. All"),
+dkT("rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions"),
+dkT("are met:"),
+dkT(""),
+dkT("1. Redistributions of source code must retain the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer."),
+dkT(""),
+dkT("2. The origin of this software must not be misrepresented; you must "),
+dkT(" not claim that you wrote the original software. If you use this "),
+dkT(" software in a product, an acknowledgment in the product "),
+dkT(" documentation would be appreciated but is not required."),
+dkT(""),
+dkT("3. Altered source versions must be plainly marked as such, and must"),
+dkT(" not be misrepresented as being the original software."),
+dkT(""),
+dkT("4. The name of the author may not be used to endorse or promote "),
+dkT(" products derived from this software without specific prior written "),
+dkT(" permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS"),
+dkT("OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED"),
+dkT("WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE"),
+dkT("GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS"),
+dkT("INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,"),
+dkT("WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS"),
+dkT("SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+dkT(""),
+dkT("Julian Seward, jseward@bzip.org"),
+dkT("bzip2/libbzip2 version 1.0.5 of 10 December 2007"),
+#endif
+#if DK4_HAVE_OPENSSL_MD5_H && DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_OPENSSL_RIPEMD_H
+dkT(""),
+dkT(""),
+dkT("OpenSSL license"),
+dkT("==============="),
+dkT(""),
+dkT("LICENSE ISSUES"),
+dkT("--------------"),
+dkT(""),
+dkT("The OpenSSL toolkit stays under a dual license, i.e. both the conditions of"),
+dkT("the OpenSSL License and the original SSLeay license apply to the toolkit."),
+dkT("See below for the actual license texts. Actually both licenses are BSD-style"),
+dkT("Open Source licenses. In case of any license issues related to OpenSSL"),
+dkT("please contact openssl-core@openssl.org."),
+dkT(""),
+dkT("OpenSSL License"),
+dkT("---------------"),
+dkT(""),
+dkT("Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions"),
+dkT("are met:"),
+dkT(""),
+dkT("1. Redistributions of source code must retain the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer. "),
+dkT(""),
+dkT("2. Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in"),
+dkT(" the documentation and/or other materials provided with the"),
+dkT(" distribution."),
+dkT(""),
+dkT("3. All advertising materials mentioning features or use of this"),
+dkT(" software must display the following acknowledgment:"),
+dkT(" \"This product includes software developed by the OpenSSL Project"),
+dkT(" for use in the OpenSSL Toolkit. (http://www.openssl.org/)\""),
+dkT(""),
+dkT("4. The names \"OpenSSL Toolkit\" and \"OpenSSL Project\" must not be used to"),
+dkT(" endorse or promote products derived from this software without"),
+dkT(" prior written permission. For written permission, please contact"),
+dkT(" openssl-core@openssl.org."),
+dkT(""),
+dkT("5. Products derived from this software may not be called \"OpenSSL\""),
+dkT(" nor may \"OpenSSL\" appear in their names without prior written"),
+dkT(" permission of the OpenSSL Project."),
+dkT(""),
+dkT("6. Redistributions of any form whatsoever must retain the following"),
+dkT(" acknowledgment:"),
+dkT(" \"This product includes software developed by the OpenSSL Project"),
+dkT(" for use in the OpenSSL Toolkit (http://www.openssl.org/)\""),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY"),
+dkT("EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR"),
+dkT("PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR"),
+dkT("ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,"),
+dkT("SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT"),
+dkT("NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;"),
+dkT("LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)"),
+dkT("HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,"),
+dkT("STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)"),
+dkT("ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED"),
+dkT("OF THE POSSIBILITY OF SUCH DAMAGE."),
+dkT(""),
+dkT("This product includes cryptographic software written by Eric Young"),
+dkT("(eay@cryptsoft.com). This product includes software written by Tim"),
+dkT("Hudson (tjh@cryptsoft.com)."),
+dkT(""),
+dkT(""),
+dkT("Original SSLeay License"),
+dkT("-----------------------"),
+dkT(""),
+dkT("Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("This package is an SSL implementation written"),
+dkT("by Eric Young (eay@cryptsoft.com)."),
+dkT("The implementation was written so as to conform with Netscapes SSL."),
+dkT(""),
+dkT("This library is free for commercial and non-commercial use as long as"),
+dkT("the following conditions are aheared to. The following conditions"),
+dkT("apply to all code found in this distribution, be it the RC4, RSA,"),
+dkT("lhash, DES, etc., code; not just the SSL code. The SSL documentation"),
+dkT("included with this distribution is covered by the same copyright terms"),
+dkT("except that the holder is Tim Hudson (tjh@cryptsoft.com)."),
+dkT(""),
+dkT("Copyright remains Eric Young's, and as such any Copyright notices in"),
+dkT("the code are not to be removed."),
+dkT("If this package is used in a product, Eric Young should be given attribution"),
+dkT("as the author of the parts of the library used."),
+dkT("This can be in the form of a textual message at program startup or"),
+dkT("in documentation (online or textual) provided with the package."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions"),
+dkT("are met:"),
+dkT("1. Redistributions of source code must retain the copyright"),
+dkT(" notice, this list of conditions and the following disclaimer."),
+dkT("2. Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("3. All advertising materials mentioning features or use of this software"),
+dkT(" must display the following acknowledgement:"),
+dkT(" \"This product includes cryptographic software written by"),
+dkT(" Eric Young (eay@cryptsoft.com)\""),
+dkT(" The word 'cryptographic' can be left out if the rouines from the library"),
+dkT(" being used are not cryptographic related :-)."),
+dkT("4. If you include any Windows specific code (or a derivative thereof) from "),
+dkT(" the apps directory (application code) you must include an acknowledgement:"),
+dkT(" \"This product includes software written by Tim Hudson (tjh@cryptsoft.com)\""),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND"),
+dkT("ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE"),
+dkT("FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS"),
+dkT("OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)"),
+dkT("HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT"),
+dkT("LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY"),
+dkT("OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF"),
+dkT("SUCH DAMAGE."),
+dkT(""),
+dkT("The licence and distribution terms for any publically available version or"),
+dkT("derivative of this code cannot be changed. i.e. this code cannot simply be"),
+dkT("copied and put under another distribution licence"),
+dkT("[including the GNU Public Licence.]"),
+dkT(""),
+#endif
+dkT(""),
+NULL
+
+
+#line 482 "dk-send.ctr"
+};
+
+
+
+/** Options for this program.
+*/
+static const dk4_option_specification_t dk_send_options[] = {
+ { dkT('n'), dkT("number-of-clients"), DK4_OPT_ARG_STRING },
+ { dkT('a'), dkT("allow"), DK4_OPT_ARG_STRING },
+ { dkT('l'), dkT("local-only"), DK4_OPT_ARG_NONE },
+ { dkT('p'), dkT("pipe"), DK4_OPT_ARG_NONE },
+ { dkT('b'), dkT("backlog"), DK4_OPT_ARG_UNSIGNED },
+ { dkT('c'), dkT("connect-timeout"), DK4_OPT_ARG_DOUBLE }
+};
+
+
+
+/** Buffer for sending.
+ Initial value: 1460
+*/
+#if DK4_SIZEOF_SIZE_T > 2
+static char dk_send_buf[1048576];
+#else
+static char dk_send_buf[16384];
+#endif
+
+
+/** Application structure for diagnostics.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Localized texts or default texts.
+*/
+static const dkChar * const *dk_send_msg = dk_send_kw_def;
+
+
+
+/** Collection of allowed clients.
+*/
+static dk4_sto_t *s_allowed = NULL;
+
+
+
+/** Iterator through allowed clients collection.
+*/
+static dk4_sto_it_t *i_allowed = NULL;
+
+
+
+/** Number of expected clients.
+*/
+static dk4_um_t numclients = (dk4_um_t)1UL;
+
+
+
+/** Number of elements in the dk_send_msg array.
+*/
+static size_t dk_send_sz_msg =
+sizeof(dk_send_kw_def)/sizeof(DK4_PDKCHAR) - 1;
+
+
+
+/** Number of elements in the dk_send_options array.
+*/
+static size_t dk_send_sz_options =
+sizeof(dk_send_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Seconds for read timeout.
+*/
+static long dk_send_timeout_secs = 0L;
+
+
+
+/** Microseconds for read timeout.
+*/
+static long dk_send_timeout_usecs = 0L;
+
+
+
+/** Exit status code returned by the program.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+/** Flag: Running as pipe, avoid SIGPIPE.
+*/
+static int is_pipe = 0;
+
+
+
+/** Flag: Allow only connections from localhost.
+*/
+static int local_only = 0;
+
+
+
+/** Number of outstanding connection requests to queue.
+*/
+static int backlog = 10;
+
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+/** Pass a volatile pointer to an atomic integer.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ptr Address of atomic integer variable.
+ @return The unmodified pointer.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+/** Check whether we can continue or if a signal was received.
+ @param check_pipe Flag: Check for occured SIGPIPE signal too.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(int check_pipe)
+{
+ int back = 1;
+#ifdef SIGPIPE
+ if (0 != check_pipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_int )) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+/** Check whether we can continue.
+ @return 1 for yes, 0 for no.
+*/
+static
+int
+dk_send_can_continue(void)
+{
+ int back = 1;
+
+
+#line 704 "dk-send.ctr"
+ if (0 == sig_can_continue(0)) {
+ back = 0;
+ }
+
+
+#line 708 "dk-send.ctr"
+ return back;
+}
+
+
+
+/** Compare two connected clients.
+ @param l Left client.
+ @param r Right client.
+ @param cr Comparison criteria (ignored).
+ @return 1 if l>r, 0 if l=r, -1 if l<r.
+*/
+static
+int
+dk_send_compare_clients(const void *l, const void *r, int cr)
+{
+ const dk_send_client_t *pl;
+ const dk_send_client_t *pr;
+ int back = 0;
+ if (NULL != l) {
+ if (NULL != r) {
+ pl = (const dk_send_client_t *)l;
+ pr = (const dk_send_client_t *)r;
+ if (pl->num > pr->num) {
+ back = 1;
+ } else {
+ if (pl->num < pr->num) {
+ back = -1;
+ } else {
+ if (pl->sock > pr->sock) {
+ back = 1;
+ } else {
+ if (pl->sock < pr->sock) {
+ back = -1;
+ }
+ }
+ }
+ }
+ } else { back = 1; }
+ } else {
+ if (NULL != r) { back= -1; }
+ }
+ return back;
+}
+
+
+
+/** Obtain information about allowed clients from string.
+ @param argcpy Copy of string, can be modified.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk_send_get_allowed_clients(dkChar *argcpy)
+{
+ dk4_allowed_peer_t peer;
+ dk4_er_t er;
+ dk4_allowed_peer_t *npeer = NULL;
+ dkChar *pc = NULL;
+ dkChar *pn = NULL;
+ int back = 0;
+ int res = 0;
+
+
+#line 770 "dk-send.ctr"
+ s_allowed = dk4sto_open(NULL);
+ if (NULL != s_allowed) {
+ dk4sto_set_comp(s_allowed, dk4socket_allowed_peer_compare, 0);
+ i_allowed = dk4sto_it_open(s_allowed, NULL);
+ if (NULL != i_allowed) {
+ back = 1;
+ pc = argcpy;
+ do {
+ pn = dk4str_chr(pc, dkT(','));
+ if (NULL != pn) { *(pn++) = dkT('\0'); }
+ DK4_MEMRES(&peer, sizeof(peer));
+ dk4error_init(&er);
+ res = dk4socket_get_allowed_peer(&peer, pc, &er);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ npeer = dk4mem_new_app(dk4_allowed_peer_t,1,app);
+ if (NULL != npeer) {
+ DK4_MEMCPY(npeer, &peer, sizeof(peer));
+ if (0 == dk4sto_add(s_allowed, npeer, NULL)) {
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ dk4mem_free(npeer);
+ npeer = NULL;
+ back = 0;
+ }
+ } else {
+ /* ERROR: Memory, already reported */
+ back = 0;
+ }
+ } else {
+ /* ERROR: Failed to obtain peer information from string */
+ dk4socket_log_simple_3(
+ app, DK4_LL_ERROR, 141, 142, pc, &er
+ );
+ back = 0;
+ }
+ pc = pn;
+ } while ((NULL != pc) && (1 == back));
+ } else {
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ }
+ } else {
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ }
+
+
+#line 816 "dk-send.ctr"
+ return back;
+}
+
+
+
+static
+int
+dk_send_check_peer_address(dk4_sockaddr_storage_t *sasto, size_t soalen)
+{
+ struct sockaddr *psoa;
+ int back = 0;
+ if (NULL != sasto) {
+ psoa = (struct sockaddr *)sasto;
+ switch (psoa->sa_family) {
+ case AF_INET : {
+ if (sizeof(struct sockaddr_in) == soalen) {
+ back = 1;
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6 && defined(AF_INET6)
+ case AF_INET6 : {
+ if (sizeof(struct sockaddr_in6) == soalen) {
+ back = 1;
+ }
+ } break;
+#endif
+ }
+ }
+ return back;
+}
+
+
+
+/** Accept incoming connections and transfer data.
+ @param portname Port name to listen.
+ @param infile Input file to read data from.
+ @param filename Input file name.
+*/
+static
+void
+dk_send_do_networking(
+ const dkChar *portname,
+ FILE *infile,
+ const dkChar *filename
+)
+{
+ dkChar peerbuf[1072];
+ const dkChar *msgparts[4];
+ fd_set rfds;
+ dk4_sockaddr_storage_t sasto;
+ struct sockaddr *psoa = NULL;
+ dk4_socket_set_t *listeners = NULL;
+ dk4_sto_t *s_clients = NULL;
+ dk4_sto_it_t *i_clients = NULL;
+ dk_send_client_t *pcl = NULL;
+ char *bufstart; /* Start of remaining buf */
+ dk4_um_t numcl = (dk4_um_t)0UL;
+ dk4_socket_t max = 0; /* Maximum socket number */
+ dk4_socket_t ncsock; /* New client socket */
+ size_t i; /* Traverse socket set */
+ size_t soalen; /* Socket address length */
+ size_t rdbytes; /* Bytes read from file */
+ size_t wrbytes; /* Bytes written to socket */
+ size_t wrpart; /* Bytes written in this part */
+ int cc; /* Flag: Can continue in loop */
+ int ccwr; /* Flag: Continue send loop */
+ int res; /* Operation result */
+ int allowed; /* Client from allowed peer */
+ int anya; /* Flag: Recipients alive */
+ unsigned char tra;
+
+
+
+#line 888 "dk-send.ctr"
+ /* Create storage and iterator for connected clients.
+ */
+ s_clients = dk4sto_open(NULL);
+ if (NULL == s_clients) {
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ goto finished;
+ }
+ dk4sto_set_comp(s_clients, dk_send_compare_clients, 0);
+ i_clients = dk4sto_it_open(s_clients, NULL);
+ if (NULL == i_clients) {
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ goto finished;
+ }
+
+ /* Create listener socket set.
+ */
+ listeners = dk4socket_set_service_app(portname, backlog, local_only, app);
+ if (NULL == listeners) { goto finished; }
+
+ /* Accept connection requests.
+ */
+ /* PROGRESS: Accepting incoming connection requests */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_PROGRESS, 3);
+ cc = 1;
+ for (i = 0; i < listeners->szUsed; i++) {
+ if (0 == i) {
+ max = (listeners->pSockets)[i];
+ } else {
+ if (max < (listeners->pSockets)[i]) { max = (listeners->pSockets)[i]; }
+ }
+ }
+ while (1 == cc) {
+ if (0 != dk_send_can_continue()) {
+ /* Prepare read file descriptor set */
+ FD_ZERO(&rfds);
+ for (i = 0; i < listeners->szUsed; i++) {
+ FD_SET( (listeners->pSockets)[i], &rfds );
+ }
+ res = select( (int)(max+1), &rfds, NULL, NULL, NULL );
+ if (0 < res) {
+ for (i = 0; i < listeners->szUsed; i++) {
+ if (FD_ISSET((listeners->pSockets)[i], &rfds)) {
+ /* Accept connection request */
+ soalen = sizeof(sasto);
+ ncsock = dk4socket_accept_app(
+ (listeners->pSockets)[i],(struct sockaddr *)(&sasto),&soalen,app
+ );
+ if (INVALID_SOCKET != ncsock) {
+ allowed = 1;
+ if ((NULL != s_allowed) && (NULL != i_allowed)) {
+
+#line 940 "dk-send.ctr"
+ /* Check peer address */
+ if (0 != dk_send_check_peer_address(&sasto, soalen)) {
+ if (NULL == dk4sto_it_find_like(i_allowed, &sasto, 1)) {
+ allowed = 0;
+
+#line 944 "dk-send.ctr"
+ } else {
+
+#line 945 "dk-send.ctr"
+ }
+ } else {
+
+#line 947 "dk-send.ctr"
+ /* ERROR: Peer address length problem */
+ dk4app_log_1(app,dk_send_msg,dk_send_sz_msg,DK4_LL_ERROR,4);
+ allowed = 0;
+ }
+ } else {
+
+#line 952 "dk-send.ctr"
+ }
+ if (1 == allowed) {
+ pcl = dk4mem_new_app(dk_send_client_t,1,app);
+ if (NULL != pcl) {
+ pcl->num = numcl;
+ pcl->sock = ncsock;
+ DK4_MEMCPY( &(pcl->peeraddr), &sasto, sizeof(dk4_sockaddr_storage_t) );
+ pcl->peerlen = soalen;
+ if (0 != dk4sto_add(s_clients, pcl, NULL)) {
+ tra = 0x00;
+ soalen = sizeof(tra);
+ res = dk4socket_recv_app(
+ ncsock, &tra, &soalen, 0,
+ dk_send_timeout_secs, dk_send_timeout_usecs,
+ app
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ if (0 < soalen) {
+ numcl++;
+ if (0x00 != tra) {
+ cc = 0;
+ i = listeners->szUsed;
+ }
+ if ((dk4_um_t)0UL < numclients) {
+ if (numcl >= numclients) {
+ cc = 0;
+ i = listeners->szUsed;
+ }
+ }
+ /* Simple message to stdout - accepted
+ */
+ if (0 != dk4app_log_do(app, DK4_LL_PROGRESS)) {
+
+#line 984 "dk-send.ctr"
+ psoa = (struct sockaddr *)(&sasto);
+ res = dk4socket_addr_port_to_text(
+ peerbuf, DK4_SIZEOF(peerbuf,dkChar),
+ psoa->sa_family,
+ (const struct sockaddr *)(&sasto), pcl->peerlen,
+ NULL
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+
+#line 992 "dk-send.ctr"
+ msgparts[0] = dk_send_msg[5];
+ msgparts[1] = peerbuf;
+ dk4app_log_msg(
+ app, DK4_LL_PROGRESS, msgparts, 2
+ );
+
+#line 997 "dk-send.ctr"
+ } else {
+
+#line 998 "dk-send.ctr"
+ }
+ } else {
+
+#line 1000 "dk-send.ctr"
+ }
+ } else {
+ /* ERROR: Nothing was read from socket */
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ psoa = (struct sockaddr *)(&sasto);
+ res = dk4socket_addr_port_to_text(
+ peerbuf, DK4_SIZEOF(peerbuf,dkChar),
+ psoa->sa_family,
+ (const struct sockaddr *)(&sasto), pcl->peerlen,
+ NULL
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ msgparts[0] = dk_send_msg[15];
+ msgparts[1] = peerbuf;
+ dk4app_log_msg(
+ app, DK4_LL_DEBUG, msgparts, 2
+ );
+ }
+ }
+ dk4socket_close(pcl->sock, NULL);
+ if (0 != dk4sto_remove(s_clients, pcl, NULL)) {
+ dk4mem_free(pcl);
+ }
+ }
+ } else {
+ /* ERROR: Failed to read from socket */
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ psoa = (struct sockaddr *)(&sasto);
+ res = dk4socket_addr_port_to_text(
+ peerbuf, DK4_SIZEOF(peerbuf,dkChar),
+ psoa->sa_family,
+ (const struct sockaddr *)(&sasto), pcl->peerlen,
+ NULL
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ msgparts[0] = dk_send_msg[15];
+ msgparts[1] = peerbuf;
+ dk4app_log_msg(
+ app, DK4_LL_DEBUG, msgparts, 2
+ );
+ }
+ }
+ dk4socket_close(pcl->sock, NULL);
+ if (0 != dk4sto_remove(s_clients, pcl, NULL)) {
+ dk4mem_free(pcl);
+ }
+ }
+ } else {
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ cc = -1;
+ i = listeners->szUsed;
+ dk4socket_close(ncsock, NULL);
+ dk4mem_free(pcl);
+ }
+ } else {
+ cc = -1;
+ i = listeners->szUsed;
+ dk4socket_close(ncsock, NULL);
+ }
+ } else {
+ /* ERROR: Denied - Simple message to stdout */
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ psoa = (struct sockaddr *)(&sasto);
+ res = dk4socket_addr_port_to_text(
+ peerbuf, DK4_SIZEOF(peerbuf,dkChar),
+ psoa->sa_family,
+ (const struct sockaddr *)(&sasto), soalen,
+ NULL
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ msgparts[0] = dk_send_msg[6];
+ msgparts[1] = peerbuf;
+ dk4app_log_msg(
+ app, DK4_LL_DEBUG, msgparts, 2
+ );
+ }
+ }
+ dk4socket_close(ncsock, NULL);
+ }
+ } else {
+ /* Accept failed */
+ if (0 == dk_send_can_continue()) { cc = -1; }
+ }
+ }
+ }
+ } else {
+ if (0 == dk_send_can_continue()) { cc = -1; }
+ }
+ } else {
+ cc = -1;
+ }
+ }
+ if (0 != cc) { goto finished; }
+
+ /* All preparations succeeded.
+ */
+ exval = EXIT_SUCCESS;
+
+ /* Transfer data.
+ */
+ dk4socket_set_close(listeners, NULL);
+ listeners = NULL;
+ /* PROGRESS: Starting data transfer */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_PROGRESS, 7);
+ cc = 1;
+ anya = 1;
+ while ((1 == cc) && ((0 != anya) || (0 != is_pipe))) {
+ if (0 != dk_send_can_continue()) {
+ rdbytes = fread(dk_send_buf, 1, sizeof(dk_send_buf), infile);
+ if (0 < rdbytes) {
+
+#line 1111 "dk-send.ctr"
+ anya = 0;
+ dk4sto_it_reset(i_clients);
+ do {
+ pcl = (dk_send_client_t *)dk4sto_it_next(i_clients);
+ if (NULL != pcl) {
+ if (INVALID_SOCKET != pcl->sock) {
+
+#line 1117 "dk-send.ctr"
+ bufstart = dk_send_buf;
+ wrbytes = 0;
+ ccwr = 1;
+ do {
+ if (0 != dk_send_can_continue()) {
+ wrpart = rdbytes - wrbytes;
+
+
+#line 1124 "dk-send.ctr"
+ res = dk4socket_send_app(
+ pcl->sock, bufstart, &wrpart, 0, 0L, 0L, app
+ );
+ switch (res) {
+ case DK4_SOCKET_RESULT_SUCCESS :
+ case DK4_SOCKET_RESULT_IN_PROGRESS : {
+
+
+#line 1131 "dk-send.ctr"
+ wrbytes += wrpart;
+
+
+#line 1133 "dk-send.ctr"
+ if (wrbytes >= rdbytes) {
+ ccwr = 0;
+
+#line 1135 "dk-send.ctr"
+ } else {
+
+#line 1136 "dk-send.ctr"
+ bufstart = &(bufstart[wrpart]);
+ }
+ } break;
+ default : {
+
+#line 1140 "dk-send.ctr"
+ /* ERROR: Failure on socket */
+ ccwr = -1;
+ exval = EXIT_FAILURE;
+ dk4socket_close(pcl->sock, NULL);
+ pcl->sock = INVALID_SOCKET;
+ if (0 != dk4app_log_do(app, DK4_LL_ERROR)) {
+ psoa = (struct sockaddr *)(&(pcl->peeraddr));
+ res = dk4socket_addr_port_to_text(
+ peerbuf, DK4_SIZEOF(peerbuf,dkChar),
+ psoa->sa_family,
+ (const struct sockaddr *)(&(pcl->peeraddr)),
+ pcl->peerlen,
+ NULL
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ msgparts[0] = dk_send_msg[9];
+ msgparts[1] = peerbuf;
+ dk4app_log_msg(
+ app, DK4_LL_ERROR, msgparts, 2
+ );
+ }
+ }
+ } break;
+ }
+ } else {
+ ccwr = -1;
+ }
+ } while (1 == ccwr);
+ if (0 == ccwr) {
+ anya = 1;
+ }
+
+
+#line 1172 "dk-send.ctr"
+ }
+ }
+ if (0 == dk_send_can_continue()) {
+ cc = -1;
+ pcl = NULL;
+ }
+ } while (NULL != pcl);
+ if (0 != feof(infile)) {
+ cc = 0;
+ }
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = -1;
+ }
+ }
+ if ((1 == cc) && (0 == anya)) {
+ /* Warning: All clients disconnected */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_WARNING, 19);
+ }
+ /* PROGRESS: Finished data transfer */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_PROGRESS, 8);
+ if (0 != cc) {
+ exval = EXIT_FAILURE;
+ goto finished;
+ }
+
+ /* Shut down all sockets.
+ */
+ cc = 1;
+ dk4sto_it_reset(i_clients);
+ while (1 == cc) {
+ if (0 != dk_send_can_continue()) {
+ pcl = (dk_send_client_t *)dk4sto_it_next(i_clients);
+ if (NULL != pcl) {
+ if (INVALID_SOCKET != pcl->sock) {
+ res = dk4socket_shutdown_app(pcl->sock, DK4_SOCKET_SHUT_WRITE, app);
+ if (DK4_SOCKET_RESULT_SUCCESS != res) {
+ exval = EXIT_FAILURE;
+ dk4socket_close(pcl->sock, NULL);
+ pcl->sock = INVALID_SOCKET;
+ }
+ }
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = -1;
+ }
+ }
+
+ /* For orderly release read from sockets until we have 0 bytes input.
+ */
+ dk4sto_it_reset(i_clients);
+ do {
+ if (0 != dk_send_can_continue()) {
+ pcl = (dk_send_client_t *)dk4sto_it_next(i_clients);
+ if (NULL != pcl) {
+ cc = 1;
+ while (1 == cc) {
+ rdbytes = sizeof(dk_send_buf);
+ res = dk4socket_recv(
+ pcl->sock, dk_send_buf, &rdbytes, 0, 0L, 0L, NULL
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ if (0 == rdbytes) {
+ cc = 0;
+ }
+ } else {
+ cc = 0;
+ }
+ if (0 == dk_send_can_continue()) {
+ cc = 0;
+ pcl = NULL;
+ }
+ }
+ }
+ } else {
+ pcl = NULL;
+ }
+ } while (NULL != pcl);
+
+ /* Finally clean up.
+ */
+ finished:
+ /* Close the connection sockets */
+ if ((NULL != i_clients) && (NULL != s_clients)) {
+ dk4sto_it_reset(i_clients);
+ do {
+ pcl = (dk_send_client_t *)dk4sto_it_next(i_clients);
+ if (NULL != pcl) {
+ if (INVALID_SOCKET != pcl->sock) {
+ dk4socket_close(pcl->sock, NULL);
+ }
+ }
+ } while (NULL != pcl);
+ }
+ /* Close listener socket set */
+ if (NULL != listeners) {
+ dk4socket_set_close(listeners, NULL);
+ }
+ /* Clean up connection container and iterator */
+ if (NULL != i_clients) {
+ dk4sto_it_reset(i_clients);
+ do {
+ pcl = (dk_send_client_t *)dk4sto_it_next(i_clients);
+ if (NULL != pcl) {
+ dk4mem_free(pcl);
+ }
+ } while (NULL != pcl);
+ dk4sto_it_close(i_clients);
+ }
+ if (NULL != s_clients) {
+ dk4sto_close(s_clients);
+ }
+
+
+#line 1289 "dk-send.ctr"
+}
+
+
+
+/** Process command line arguments, and continue.
+ @param portname Port name to listen.
+ @param infile Input file to read data from.
+ @param filename Input file name.
+*/
+static
+void
+dk_send_process_cmdline_args(
+ const dkChar *portname,
+ FILE *infile,
+ const dkChar *filename
+)
+{
+ const dkChar *argptr = NULL;
+ const dkChar *endptr = NULL;
+ const dkChar *argval = NULL;
+ dkChar *argcpy = NULL;
+ dk4_allowed_peer_t *ppeer;
+ double timeout = 0.0;
+ double td1 = 0.0;
+ double td2 = 0.0;
+ dk4_um_t um = (dk4_um_t)0UL;
+ int res = 0;
+
+
+#line 1317 "dk-send.ctr"
+ /* Check whether to allow local connections only.
+ */
+ if (0 != dk4app_opt_is_set_short(app, dkT('l'), NULL)) {
+ local_only = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('p'), NULL)) {
+ is_pipe = 1;
+ }
+ /* Set up backlog
+ */
+ if (0 != dk4app_opt_is_set_short(app, dkT('b'), NULL)) {
+ if (0 != dk4app_opt_get_unsigned_short(&um, app, dkT('b'), NULL)) {
+ if ((dk4_um_t)(INT_MAX) >= um) {
+ if ((dk4_um_t)0UL < um) {
+ backlog = (int)um;
+ } else {
+ backlog = 1;
+ }
+ } else {
+ backlog = INT_MAX;
+ }
+ } else {
+ /* ERROR: Not an unsigned number, must not happen */
+ goto finished;
+ }
+ }
+ /* Find timeout settings.
+ */
+ if (0 != dk4app_opt_is_set_short(app, dkT('c'), NULL)) {
+ if (0 != dk4app_opt_get_double_short(&timeout, app, dkT('c'), NULL)) {
+ if (0.0 <= timeout) {
+ td1 = floor(timeout);
+ td2 = timeout - td1;
+ td2 = td2 * 1000000.0;
+ if ((double)(LONG_MAX) >= td1) {
+ dk_send_timeout_secs = (long)td1;
+ dk_send_timeout_usecs = (long)td2;
+ } else {
+ /* ERROR: Timeout value too large! */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 16);
+ goto finished;
+ }
+ } else {
+ /* ERROR: Can not use negative timeout */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 17);
+ goto finished;
+ }
+ } else {
+ /* ERROR: Not timeout value found */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 18);
+ goto finished;
+ }
+ }
+ /* Find number of clients.
+ */
+ if (0 != dk4app_opt_is_set_short(app, dkT('n'), NULL)) {
+ argval = dk4app_opt_get_string_ptr_short(app, dkT('n'), NULL);
+ if (dk4str_cmp(dk_send_kwnl[3], argval) == 0) {
+ numclients = (dk4_um_t)0UL;
+ } else {
+ res = dk4ma_input_dk_dec_dk4_um_t(
+ &numclients, argval, &endptr, 1, NULL
+ );
+ if (0 == res) {
+ /* ERROR: Invalid option argument */
+ dk4app_log_3(
+ app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 10, 11, argval
+ );
+ goto finished;
+ }
+ }
+ }
+
+#line 1389 "dk-send.ctr"
+ /* Find allowed client addresses.
+ */
+ if (0 != dk4app_opt_is_set_short(app, dkT('a'), NULL)) {
+ argptr = dk4app_opt_get_string_ptr_short(app, dkT('a'), NULL);
+ if (NULL == argptr) {
+ /* ERROR: Failed to obtain Argument */
+
+
+#line 1396 "dk-send.ctr"
+ goto finished;
+ }
+ argcpy = dk4str_dup_app(argptr, app);
+ if (NULL == argcpy) { goto finished; }
+ if (0 == dk_send_get_allowed_clients(argcpy)) { goto finished; }
+ }
+
+#line 1402 "dk-send.ctr"
+ /* Do the network transmission.
+ */
+ dk_send_do_networking(portname, infile, filename);
+
+
+#line 1406 "dk-send.ctr"
+ /* Finally release resources.
+ */
+ finished:
+ if (NULL != argcpy) {
+ dk4mem_free(argcpy);
+ }
+ if (NULL != s_allowed) {
+ if (NULL != i_allowed) {
+ dk4sto_it_reset(i_allowed);
+ do {
+ ppeer = (dk4_allowed_peer_t *)dk4sto_it_next(i_allowed);
+ if (NULL != ppeer) {
+ dk4mem_free(ppeer);
+ }
+ } while(NULL != ppeer);
+ dk4sto_it_close(i_allowed);
+ i_allowed = NULL;
+ }
+ dk4sto_close(s_allowed);
+ s_allowed = NULL;
+ }
+
+
+#line 1428 "dk-send.ctr"
+}
+
+
+
+/** Bring Winsock up before performing other steps.
+ @param portname Port name to listen.
+ @param infile Input file to read data from.
+ @param filename Input file name.
+*/
+static
+void
+dk_send_run_for_file(
+ const dkChar *portname,
+ FILE *infile,
+ const dkChar *filename
+)
+{
+ if (dk4socket_up_app(app)) {
+ dk_send_process_cmdline_args(portname, infile, filename);
+ dk4socket_down_app(app);
+ }
+}
+
+
+
+/** Run for real file name.
+ @param portname Port name.
+ @param filename File name, no further expansion required.
+*/
+static
+void
+dk_send_run_for_real_file_name(const dkChar *portname, const dkChar *filename)
+{
+ FILE *inf;
+ int tests = DK4_FOPEN_SC_USER;
+ if (dk4isadmin()) { tests = DK4_FOPEN_SC_PRIVILEGED; }
+ inf = dk4fopen_app(filename, dk_send_kwnl[5], tests, app);
+ if (NULL != inf) {
+ dk_send_run_for_file(portname, inf, filename);
+ fclose(inf);
+ }
+}
+
+
+
+#if DK4_ON_WINDOWS
+
+/** Expand file name and run for file.
+ @param portname Port name (first command line argument).
+ @param filename File name pattern.
+*/
+static
+void
+dk_send_expand_filename(const dkChar *portname, const dkChar *filename)
+{
+ dkChar buf[DK4_MAX_PATH];
+ dk4_dir_t *fne;
+ const dkChar *fn;
+ const dkChar *pt;
+ size_t szbuf = DK4_SIZEOF(buf,dkChar);
+ int copied = 0;
+
+ fne = dk4app_fne_open(filename, app);
+ if (NULL != fne) {
+ fn = dk4dir_next_file(fne);
+ if (NULL != fn) {
+ pt = dk4dir_get_path(fne);
+ if (NULL == dk4dir_next_file(fne)) {
+ if (NULL != pt) {
+ copied = 0;
+ if (0 != dk4str_cpy_s(buf, szbuf, pt, NULL)) {
+ if (0 != dk4str_cat_s(buf, szbuf, dk_send_kwnl[4], NULL)) {
+ if (0 != dk4str_cat_s(buf, szbuf, fn, NULL)) {
+ copied = 1;
+ dk_send_run_for_real_file_name(portname, buf);
+ }
+ }
+ }
+ if (0 == copied) {
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pt);
+ }
+ } else {
+ dk_send_run_for_real_file_name(portname, fn);
+ }
+ } else {
+ /* ERROR: Multiple matching files */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 106, filename);
+ }
+ } else {
+ /* ERROR: No such file */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 107, filename);
+ }
+ dk4dir_close(fne);
+ }
+}
+
+#endif
+
+
+
+static
+void
+dk_send_normal_run()
+{
+ const dkChar *filename = NULL;
+ int xargc = 0;
+#if DK4_ON_WINDOWS
+ int oldmode = 0;
+#endif
+ xargc = dk4app_get_argc(app);
+ switch (xargc) {
+ case 1: {
+#if DK4_ON_WINDOWS
+ oldmode = _setmode(_fileno(stdin), _O_BINARY);
+#endif
+ dk_send_run_for_file(dk4app_get_argv(app, 0), stdin, dk_send_msg[2]);
+#if DK4_ON_WINDOWS
+ _setmode(_fileno(stdin), oldmode);
+#endif
+ } break;
+ case 2: {
+ filename = dk4app_get_argv(app, 1);
+#if DK4_ON_WINDOWS
+ if (dk4path_must_expand(filename)) {
+ dk_send_expand_filename(dk4app_get_argv(app, 0), filename);
+ } else {
+#endif
+ dk_send_run_for_real_file_name(dk4app_get_argv(app, 0), filename);
+#if DK4_ON_WINDOWS
+ }
+#endif
+ } break;
+ default : {
+ /* ERROR: Wrong number of command line arguments */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 12);
+ } break;
+ }
+}
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+dk_send_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ struct sigaction opipe;
+#endif
+ struct sigaction oint;
+#ifdef SIGPIPE
+ struct sigaction npipe;
+#endif
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+ int success = 0;
+
+#ifdef SIGPIPE
+ /* Set up signal handling for SIGPIPE.
+ */
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+#endif
+
+ /* Set up signal handling for SIGINT.
+ */
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ dk_send_normal_run();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+#ifdef SIGPIPE
+ /* Restore signal handling for SIGPIPE.
+ */
+ restore_old_pipe:
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+#endif
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+dk_send_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ dk_send_normal_run();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+#ifdef SIGPIPE
+ sigset(SIGPIPE, oldpipe);
+#endif
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+dk_send_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = signal(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ dk_send_normal_run();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+#ifdef SIGPIPE
+ signal(SIGPIPE, oldpipe);
+#endif
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+dk_send_run_with_signal_handlers(void)
+{
+ dk_send_normal_run();
+}
+#endif
+#endif
+#endif
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+
+
+#line 1769 "dk-send.ctr"
+
+
+#line 1770 "dk-send.ctr"
+ app = dk4app_open_cmd(
+ argc, argv, dk_send_options, dk_send_sz_options,
+ dk_send_kwnl[0], DKT_VERSION_DK,
+ dk_send_kwnl[1], dk_send_help_text, dk_send_license_text
+ );
+ if (NULL != app) {
+ dk_send_sz_msg = dk4app_string_table_size(dk_send_kw_def);
+ dk_send_msg = dk4app_string_table(app, dk_send_kwnl[2], dk_send_kw_def);
+ if (0 != dk4app_can_run_normally(app)) {
+ dk_send_run_with_signal_handlers();
+ } else {
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ if (0 != sig_read_atomic(&sig_had_int)) {
+ /* ERROR: INT signal */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 13);
+ exval = EXIT_FAILURE;
+ }
+ if (0 != sig_read_atomic(&sig_had_term)) {
+ /* ERROR: TERM signal */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 14);
+ exval = EXIT_FAILURE;
+ }
+#ifdef SIGPIPE
+ if (0 != sig_read_atomic(&sig_had_pipe)) {
+ exval = EXIT_FAILURE;
+ }
+#endif
+ dk4app_close(app);
+ }
+
+
+#line 1803 "dk-send.ctr"
+
+
+#line 1804 "dk-send.ctr"
+ exit(exval);
+ return exval;
+}
+
diff --git a/support/dktools/dk-send.ctr b/support/dktools/dk-send.ctr
new file mode 100644
index 0000000000..adf0cf6532
--- /dev/null
+++ b/support/dktools/dk-send.ctr
@@ -0,0 +1,1807 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_MATH_H
+#ifndef MATH_H_INCLUDED
+#include <math.h>
+#define MATH_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4app.h"
+#include "dk4aopt.h"
+#include "dk4socka.h"
+#include "dk4maidddu.h"
+#include "dk4mpl.h"
+#include "dk4vers.h"
+#include "dk4isadm.h"
+#include "dk4strd.h"
+#include "dk4strda.h"
+#include "dk4mem.h"
+#include "dk4mema.h"
+#include "dk4fopda.h"
+#include "dk4pathd.h"
+
+
+
+$!trace-include
+
+
+
+/** Connected peer.
+*/
+typedef struct {
+ dk4_sockaddr_storage_t peeraddr; /**< Peer address. */
+ dk4_um_t num; /**< Number of client. */
+ size_t peerlen; /**< Length of peer address. */
+ dk4_socket_t sock; /**< Socket for transfer. */
+} dk_send_client_t;
+
+
+
+/** Constant texts used by the program, not localized.
+*/
+static const dkChar * const dk_send_kwnl[] = {
+$!string-table macro=dkT
+#
+# 0 Program group name
+#
+dktools
+#
+# 1 Help text file name
+#
+dk-send.txt
+#
+# 2 String table file name
+#
+dk-send.str
+#
+# 3 Keyword unlimited for number of clients
+#
+unlimited
+#
+# 4 Path separator for Windows
+#
+\\
+#
+# 5 File open mode: Read binary.
+#
+rb
+$!end
+};
+
+
+
+/** Text used by the program, replaced by localized texts if found.
+*/
+static const dkChar * const dk_send_kw_def[] = {
+$!string-table macro=dkT
+#
+# 0 Error: Failed to set up signal handlers!
+#
+Failed to set up signal handlers!
+#
+# 1 Error: Failed to restore signal handlers!
+#
+Failed to restore signal handlers!
+#
+# 2 Name of input file just processed (default).
+#
+stdin
+#
+# 3 Progress: Accepting incoming connection requests.
+#
+Accepting incoming connection requests.
+#
+# 4 Error: Problem with peer address length!
+#
+Problem with peer address length!
+#
+# 5 Progress: Connected ...
+#
+Connected:
+#
+# 6 Debug: Rejected ...
+#
+Rejected:
+#
+# 7 Progress: Starting data transfer.
+#
+Starting data transfer.
+#
+# 8 Progress: Finished data transfer.
+#
+Finished data transfer.
+#
+# 9 ERROR: Disconnected ...
+#
+Disconnected:
+#
+# 10 11 ERROR: Invalid number of clients ...!
+#
+Invalid number of clients "
+"!
+#
+# 12 ERROR: Wrong number of command line arguments!
+#
+Wrong number of command line arguments!
+#
+# 13 ERROR: Aborted by INT signal!
+#
+Aborted by INT signal!
+#
+# 14 ERROR: Aborted by TERM signal!
+#
+Aborted by TERM signal!
+#
+# 15 Debug: Not a dk-send client ...
+#
+Not a dk-send client:
+#
+# 16 17 18
+#
+Timeout too large!
+Timeout must not be negative!
+Timeout value not found!
+#
+# 19
+#
+Stop processing as all clients are disconnected!
+$!end
+};
+
+
+
+/** Short help text.
+*/
+static const dkChar * const dk_send_help_text[] = {
+$!text macro=dkT
+
+Send file to one or multiple recipients (dk-recv processes).
+
+dk-send [<options>] <port> [<file>]
+
+Options:
+-n <int> Number of clients, ``unlimited'' or 0
+ for no limit.
+-a <address>[/<mask>][,...] Allowed clients.
+-l Listen on local host ports only.
+-b <unsigned> Listen backlog (number of connection attempts
+ to queue).
+-c <timeout> Timeout for read attempt after establishing
+ a new connection.
+-p Running as sink in a pipe (do not abort reading
+ input if all clients disconnected unexpectedly).
+--help Show this short help text.
+--manual *** SHOW FULL MANUAL. ***
+--version Show version information.
+--license Show license information.
+
+$!end
+};
+
+
+
+/** License text.
+*/
+static const dkChar * const dk_send_license_text[] = {
+$!text macro=dkT,preprocessor
+This software uses code from the following projects, either directly or as
+a library:
+
+dktools Dirk Krause's tools and libraries.
+ See http://dktools.sourceforge.net/ for more information.
+#if DK4_HAVE_ZLIB_H
+
+zlib Data compression library.
+ See http://www.zlib.net/ for more information.
+#endif
+#if DK4_HAVE_BZLIB_H
+
+bzip2 Data compression program and library.
+ See http://www.bzip.org/ for more information.
+#endif
+#if DK4_HAVE_OPENSSL_MD5_H && DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_OPENSSL_RIPEMD_H
+
+OpenSSL Cryptographic toolkit, used to build file checksums here.
+ See http://www.openssl.org/ for more information.
+
+This product includes software developed by the OpenSSL Project for use in
+the OpenSSL Toolkit (http://www.openssl.org/).
+This product includes cryptographic software written by
+Eric Young (eay@cryptsoft.com).
+This product includes software written by Tim Hudson (tjh@cryptsoft.com).
+#endif
+
+All the licenses below apply to the program.
+Licenses for used libraries are shown as found on my Scientific Linux 6.x
+computer in the /usr/share/doc directory on 2015-04-01. Check the project
+homepages of the used libraries for additional information and/or updated
+license terms.
+
+
+DK tools and libraries license
+==============================
+Copyright (c) 2015-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#if DK4_HAVE_ZLIB_H
+
+
+Zlib license
+============
+(C) 1995-2004 Jean-loup Gailly and Mark Adler
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+
+Jean-loup Gailly Mark Adler
+jloup@gzip.org madler@alumni.caltech.edu
+#endif
+#if DK4_HAVE_BZLIB_H
+
+
+Bzip2 and libbzip2 library license
+==================================
+This program, "bzip2", the associated library "libbzip2", and all
+documentation, are copyright (C) 1996-2007 Julian R Seward. All
+rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+3. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Julian Seward, jseward@bzip.org
+bzip2/libbzip2 version 1.0.5 of 10 December 2007
+#endif
+#if DK4_HAVE_OPENSSL_MD5_H && DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_OPENSSL_RIPEMD_H
+
+
+OpenSSL license
+===============
+
+LICENSE ISSUES
+--------------
+
+The OpenSSL toolkit stays under a dual license, i.e. both the conditions of
+the OpenSSL License and the original SSLeay license apply to the toolkit.
+See below for the actual license texts. Actually both licenses are BSD-style
+Open Source licenses. In case of any license issues related to OpenSSL
+please contact openssl-core@openssl.org.
+
+OpenSSL License
+---------------
+
+Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+3. All advertising materials mentioning features or use of this
+ software must display the following acknowledgment:
+ "This product includes software developed by the OpenSSL Project
+ for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+
+4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ endorse or promote products derived from this software without
+ prior written permission. For written permission, please contact
+ openssl-core@openssl.org.
+
+5. Products derived from this software may not be called "OpenSSL"
+ nor may "OpenSSL" appear in their names without prior written
+ permission of the OpenSSL Project.
+
+6. Redistributions of any form whatsoever must retain the following
+ acknowledgment:
+ "This product includes software developed by the OpenSSL Project
+ for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+
+THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+OF THE POSSIBILITY OF SUCH DAMAGE.
+
+This product includes cryptographic software written by Eric Young
+(eay@cryptsoft.com). This product includes software written by Tim
+Hudson (tjh@cryptsoft.com).
+
+
+Original SSLeay License
+-----------------------
+
+Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+All rights reserved.
+
+This package is an SSL implementation written
+by Eric Young (eay@cryptsoft.com).
+The implementation was written so as to conform with Netscapes SSL.
+
+This library is free for commercial and non-commercial use as long as
+the following conditions are aheared to. The following conditions
+apply to all code found in this distribution, be it the RC4, RSA,
+lhash, DES, etc., code; not just the SSL code. The SSL documentation
+included with this distribution is covered by the same copyright terms
+except that the holder is Tim Hudson (tjh@cryptsoft.com).
+
+Copyright remains Eric Young's, and as such any Copyright notices in
+the code are not to be removed.
+If this package is used in a product, Eric Young should be given attribution
+as the author of the parts of the library used.
+This can be in the form of a textual message at program startup or
+in documentation (online or textual) provided with the package.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. All advertising materials mentioning features or use of this software
+ must display the following acknowledgement:
+ "This product includes cryptographic software written by
+ Eric Young (eay@cryptsoft.com)"
+ The word 'cryptographic' can be left out if the rouines from the library
+ being used are not cryptographic related :-).
+4. If you include any Windows specific code (or a derivative thereof) from
+ the apps directory (application code) you must include an acknowledgement:
+ "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+
+THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+The licence and distribution terms for any publically available version or
+derivative of this code cannot be changed. i.e. this code cannot simply be
+copied and put under another distribution licence
+[including the GNU Public Licence.]
+
+#endif
+
+$!end
+};
+
+
+
+/** Options for this program.
+*/
+static const dk4_option_specification_t dk_send_options[] = {
+ { dkT('n'), dkT("number-of-clients"), DK4_OPT_ARG_STRING },
+ { dkT('a'), dkT("allow"), DK4_OPT_ARG_STRING },
+ { dkT('l'), dkT("local-only"), DK4_OPT_ARG_NONE },
+ { dkT('p'), dkT("pipe"), DK4_OPT_ARG_NONE },
+ { dkT('b'), dkT("backlog"), DK4_OPT_ARG_UNSIGNED },
+ { dkT('c'), dkT("connect-timeout"), DK4_OPT_ARG_DOUBLE }
+};
+
+
+
+/** Buffer for sending.
+ Initial value: 1460
+*/
+#if DK4_SIZEOF_SIZE_T > 2
+static char dk_send_buf[1048576];
+#else
+static char dk_send_buf[16384];
+#endif
+
+
+/** Application structure for diagnostics.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Localized texts or default texts.
+*/
+static const dkChar * const *dk_send_msg = dk_send_kw_def;
+
+
+
+/** Collection of allowed clients.
+*/
+static dk4_sto_t *s_allowed = NULL;
+
+
+
+/** Iterator through allowed clients collection.
+*/
+static dk4_sto_it_t *i_allowed = NULL;
+
+
+
+/** Number of expected clients.
+*/
+static dk4_um_t numclients = (dk4_um_t)1UL;
+
+
+
+/** Number of elements in the dk_send_msg array.
+*/
+static size_t dk_send_sz_msg =
+sizeof(dk_send_kw_def)/sizeof(DK4_PDKCHAR) - 1;
+
+
+
+/** Number of elements in the dk_send_options array.
+*/
+static size_t dk_send_sz_options =
+sizeof(dk_send_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Seconds for read timeout.
+*/
+static long dk_send_timeout_secs = 0L;
+
+
+
+/** Microseconds for read timeout.
+*/
+static long dk_send_timeout_usecs = 0L;
+
+
+
+/** Exit status code returned by the program.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+/** Flag: Running as pipe, avoid SIGPIPE.
+*/
+static int is_pipe = 0;
+
+
+
+/** Flag: Allow only connections from localhost.
+*/
+static int local_only = 0;
+
+
+
+/** Number of outstanding connection requests to queue.
+*/
+static int backlog = 10;
+
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+/** Pass a volatile pointer to an atomic integer.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ptr Address of atomic integer variable.
+ @return The unmodified pointer.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+/** Check whether we can continue or if a signal was received.
+ @param check_pipe Flag: Check for occured SIGPIPE signal too.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(int check_pipe)
+{
+ int back = 1;
+#ifdef SIGPIPE
+ if (0 != check_pipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_int )) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+/** Check whether we can continue.
+ @return 1 for yes, 0 for no.
+*/
+static
+int
+dk_send_can_continue(void)
+{
+ int back = 1;
+ $? "+ dk_send_can_continue"
+ if (0 == sig_can_continue(0)) {
+ back = 0;
+ }
+ $? "- dk_send_can_continue %d", back
+ return back;
+}
+
+
+
+/** Compare two connected clients.
+ @param l Left client.
+ @param r Right client.
+ @param cr Comparison criteria (ignored).
+ @return 1 if l>r, 0 if l=r, -1 if l<r.
+*/
+static
+int
+dk_send_compare_clients(const void *l, const void *r, int cr)
+{
+ const dk_send_client_t *pl;
+ const dk_send_client_t *pr;
+ int back = 0;
+ if (NULL != l) {
+ if (NULL != r) {
+ pl = (const dk_send_client_t *)l;
+ pr = (const dk_send_client_t *)r;
+ if (pl->num > pr->num) {
+ back = 1;
+ } else {
+ if (pl->num < pr->num) {
+ back = -1;
+ } else {
+ if (pl->sock > pr->sock) {
+ back = 1;
+ } else {
+ if (pl->sock < pr->sock) {
+ back = -1;
+ }
+ }
+ }
+ }
+ } else { back = 1; }
+ } else {
+ if (NULL != r) { back= -1; }
+ }
+ return back;
+}
+
+
+
+/** Obtain information about allowed clients from string.
+ @param argcpy Copy of string, can be modified.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk_send_get_allowed_clients(dkChar *argcpy)
+{
+ dk4_allowed_peer_t peer;
+ dk4_er_t er;
+ dk4_allowed_peer_t *npeer = NULL;
+ dkChar *pc = NULL;
+ dkChar *pn = NULL;
+ int back = 0;
+ int res = 0;
+ $? "+ dk_send_get_allowed_clients \"%!ds\"", TR_STR(argcpy)
+ s_allowed = dk4sto_open(NULL);
+ if (NULL != s_allowed) {
+ dk4sto_set_comp(s_allowed, dk4socket_allowed_peer_compare, 0);
+ i_allowed = dk4sto_it_open(s_allowed, NULL);
+ if (NULL != i_allowed) {
+ back = 1;
+ pc = argcpy;
+ do {
+ pn = dk4str_chr(pc, dkT(','));
+ if (NULL != pn) { *(pn++) = dkT('\0'); }
+ DK4_MEMRES(&peer, sizeof(peer));
+ dk4error_init(&er);
+ res = dk4socket_get_allowed_peer(&peer, pc, &er);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ npeer = dk4mem_new_app(dk4_allowed_peer_t,1,app);
+ if (NULL != npeer) {
+ DK4_MEMCPY(npeer, &peer, sizeof(peer));
+ if (0 == dk4sto_add(s_allowed, npeer, NULL)) {
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ dk4mem_free(npeer);
+ npeer = NULL;
+ back = 0;
+ }
+ } else {
+ /* ERROR: Memory, already reported */
+ back = 0;
+ }
+ } else {
+ /* ERROR: Failed to obtain peer information from string */
+ dk4socket_log_simple_3(
+ app, DK4_LL_ERROR, 141, 142, pc, &er
+ );
+ back = 0;
+ }
+ pc = pn;
+ } while ((NULL != pc) && (1 == back));
+ } else {
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ }
+ } else {
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ }
+ $? "- dk_send_get_allowed_clients %d", back
+ return back;
+}
+
+
+
+static
+int
+dk_send_check_peer_address(dk4_sockaddr_storage_t *sasto, size_t soalen)
+{
+ struct sockaddr *psoa;
+ int back = 0;
+ if (NULL != sasto) {
+ psoa = (struct sockaddr *)sasto;
+ switch (psoa->sa_family) {
+ case AF_INET : {
+ if (sizeof(struct sockaddr_in) == soalen) {
+ back = 1;
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6 && defined(AF_INET6)
+ case AF_INET6 : {
+ if (sizeof(struct sockaddr_in6) == soalen) {
+ back = 1;
+ }
+ } break;
+#endif
+ }
+ }
+ return back;
+}
+
+
+
+/** Accept incoming connections and transfer data.
+ @param portname Port name to listen.
+ @param infile Input file to read data from.
+ @param filename Input file name.
+*/
+static
+void
+dk_send_do_networking(
+ const dkChar *portname,
+ FILE *infile,
+ const dkChar *filename
+)
+{
+ dkChar peerbuf[1072];
+ const dkChar *msgparts[4];
+ fd_set rfds;
+ dk4_sockaddr_storage_t sasto;
+ struct sockaddr *psoa = NULL;
+ dk4_socket_set_t *listeners = NULL;
+ dk4_sto_t *s_clients = NULL;
+ dk4_sto_it_t *i_clients = NULL;
+ dk_send_client_t *pcl = NULL;
+ char *bufstart; /* Start of remaining buf */
+ dk4_um_t numcl = (dk4_um_t)0UL;
+ dk4_socket_t max = 0; /* Maximum socket number */
+ dk4_socket_t ncsock; /* New client socket */
+ size_t i; /* Traverse socket set */
+ size_t soalen; /* Socket address length */
+ size_t rdbytes; /* Bytes read from file */
+ size_t wrbytes; /* Bytes written to socket */
+ size_t wrpart; /* Bytes written in this part */
+ int cc; /* Flag: Can continue in loop */
+ int ccwr; /* Flag: Continue send loop */
+ int res; /* Operation result */
+ int allowed; /* Client from allowed peer */
+ int anya; /* Flag: Recipients alive */
+ unsigned char tra;
+
+ $? "+ dk_send_do_networking"
+ /* Create storage and iterator for connected clients.
+ */
+ s_clients = dk4sto_open(NULL);
+ if (NULL == s_clients) {
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ goto finished;
+ }
+ dk4sto_set_comp(s_clients, dk_send_compare_clients, 0);
+ i_clients = dk4sto_it_open(s_clients, NULL);
+ if (NULL == i_clients) {
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ goto finished;
+ }
+
+ /* Create listener socket set.
+ */
+ listeners = dk4socket_set_service_app(portname, backlog, local_only, app);
+ if (NULL == listeners) { goto finished; }
+
+ /* Accept connection requests.
+ */
+ /* PROGRESS: Accepting incoming connection requests */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_PROGRESS, 3);
+ cc = 1;
+ for (i = 0; i < listeners->szUsed; i++) {
+ if (0 == i) {
+ max = (listeners->pSockets)[i];
+ } else {
+ if (max < (listeners->pSockets)[i]) { max = (listeners->pSockets)[i]; }
+ }
+ }
+ while (1 == cc) {
+ if (0 != dk_send_can_continue()) {
+ /* Prepare read file descriptor set */
+ FD_ZERO(&rfds);
+ for (i = 0; i < listeners->szUsed; i++) {
+ FD_SET( (listeners->pSockets)[i], &rfds );
+ }
+ res = select( (int)(max+1), &rfds, NULL, NULL, NULL );
+ if (0 < res) {
+ for (i = 0; i < listeners->szUsed; i++) {
+ if (FD_ISSET((listeners->pSockets)[i], &rfds)) {
+ /* Accept connection request */
+ soalen = sizeof(sasto);
+ ncsock = dk4socket_accept_app(
+ (listeners->pSockets)[i],(struct sockaddr *)(&sasto),&soalen,app
+ );
+ if (INVALID_SOCKET != ncsock) {
+ allowed = 1;
+ if ((NULL != s_allowed) && (NULL != i_allowed)) { $? ". check"
+ /* Check peer address */
+ if (0 != dk_send_check_peer_address(&sasto, soalen)) {
+ if (NULL == dk4sto_it_find_like(i_allowed, &sasto, 1)) {
+ allowed = 0; $? "! not found"
+ } else { $? ". found"
+ }
+ } else { $? "! address length"
+ /* ERROR: Peer address length problem */
+ dk4app_log_1(app,dk_send_msg,dk_send_sz_msg,DK4_LL_ERROR,4);
+ allowed = 0;
+ }
+ } else { $? ". no check"
+ }
+ if (1 == allowed) {
+ pcl = dk4mem_new_app(dk_send_client_t,1,app);
+ if (NULL != pcl) {
+ pcl->num = numcl;
+ pcl->sock = ncsock;
+ DK4_MEMCPY( &(pcl->peeraddr), &sasto, sizeof(dk4_sockaddr_storage_t) );
+ pcl->peerlen = soalen;
+ if (0 != dk4sto_add(s_clients, pcl, NULL)) {
+ tra = 0x00;
+ soalen = sizeof(tra);
+ res = dk4socket_recv_app(
+ ncsock, &tra, &soalen, 0,
+ dk_send_timeout_secs, dk_send_timeout_usecs,
+ app
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ if (0 < soalen) {
+ numcl++;
+ if (0x00 != tra) {
+ cc = 0;
+ i = listeners->szUsed;
+ }
+ if ((dk4_um_t)0UL < numclients) {
+ if (numcl >= numclients) {
+ cc = 0;
+ i = listeners->szUsed;
+ }
+ }
+ /* Simple message to stdout - accepted
+ */
+ if (0 != dk4app_log_do(app, DK4_LL_PROGRESS)) { $? ". p"
+ psoa = (struct sockaddr *)(&sasto);
+ res = dk4socket_addr_port_to_text(
+ peerbuf, DK4_SIZEOF(peerbuf,dkChar),
+ psoa->sa_family,
+ (const struct sockaddr *)(&sasto), pcl->peerlen,
+ NULL
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) { $? ". r"
+ msgparts[0] = dk_send_msg[5];
+ msgparts[1] = peerbuf;
+ dk4app_log_msg(
+ app, DK4_LL_PROGRESS, msgparts, 2
+ ); $? ". dk4socket_addr_port_to_text"
+ } else { $? "! dk4socket_addr_port_to_text"
+ }
+ } else { $? ". no progress"
+ }
+ } else {
+ /* ERROR: Nothing was read from socket */
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ psoa = (struct sockaddr *)(&sasto);
+ res = dk4socket_addr_port_to_text(
+ peerbuf, DK4_SIZEOF(peerbuf,dkChar),
+ psoa->sa_family,
+ (const struct sockaddr *)(&sasto), pcl->peerlen,
+ NULL
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ msgparts[0] = dk_send_msg[15];
+ msgparts[1] = peerbuf;
+ dk4app_log_msg(
+ app, DK4_LL_DEBUG, msgparts, 2
+ );
+ }
+ }
+ dk4socket_close(pcl->sock, NULL);
+ if (0 != dk4sto_remove(s_clients, pcl, NULL)) {
+ dk4mem_free(pcl);
+ }
+ }
+ } else {
+ /* ERROR: Failed to read from socket */
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ psoa = (struct sockaddr *)(&sasto);
+ res = dk4socket_addr_port_to_text(
+ peerbuf, DK4_SIZEOF(peerbuf,dkChar),
+ psoa->sa_family,
+ (const struct sockaddr *)(&sasto), pcl->peerlen,
+ NULL
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ msgparts[0] = dk_send_msg[15];
+ msgparts[1] = peerbuf;
+ dk4app_log_msg(
+ app, DK4_LL_DEBUG, msgparts, 2
+ );
+ }
+ }
+ dk4socket_close(pcl->sock, NULL);
+ if (0 != dk4sto_remove(s_clients, pcl, NULL)) {
+ dk4mem_free(pcl);
+ }
+ }
+ } else {
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ cc = -1;
+ i = listeners->szUsed;
+ dk4socket_close(ncsock, NULL);
+ dk4mem_free(pcl);
+ }
+ } else {
+ cc = -1;
+ i = listeners->szUsed;
+ dk4socket_close(ncsock, NULL);
+ }
+ } else {
+ /* ERROR: Denied - Simple message to stdout */
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ psoa = (struct sockaddr *)(&sasto);
+ res = dk4socket_addr_port_to_text(
+ peerbuf, DK4_SIZEOF(peerbuf,dkChar),
+ psoa->sa_family,
+ (const struct sockaddr *)(&sasto), soalen,
+ NULL
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ msgparts[0] = dk_send_msg[6];
+ msgparts[1] = peerbuf;
+ dk4app_log_msg(
+ app, DK4_LL_DEBUG, msgparts, 2
+ );
+ }
+ }
+ dk4socket_close(ncsock, NULL);
+ }
+ } else {
+ /* Accept failed */
+ if (0 == dk_send_can_continue()) { cc = -1; }
+ }
+ }
+ }
+ } else {
+ if (0 == dk_send_can_continue()) { cc = -1; }
+ }
+ } else {
+ cc = -1;
+ }
+ }
+ if (0 != cc) { goto finished; }
+
+ /* All preparations succeeded.
+ */
+ exval = EXIT_SUCCESS;
+
+ /* Transfer data.
+ */
+ dk4socket_set_close(listeners, NULL);
+ listeners = NULL;
+ /* PROGRESS: Starting data transfer */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_PROGRESS, 7);
+ cc = 1;
+ anya = 1;
+ while ((1 == cc) && ((0 != anya) || (0 != is_pipe))) {
+ if (0 != dk_send_can_continue()) {
+ rdbytes = fread(dk_send_buf, 1, sizeof(dk_send_buf), infile);
+ if (0 < rdbytes) { $? ". fread -> %u bytes", (unsigned)rdbytes
+ anya = 0;
+ dk4sto_it_reset(i_clients);
+ do {
+ pcl = (dk_send_client_t *)dk4sto_it_next(i_clients);
+ if (NULL != pcl) {
+ if (INVALID_SOCKET != pcl->sock) { $? ". client connection"
+ bufstart = dk_send_buf;
+ wrbytes = 0;
+ ccwr = 1;
+ do {
+ if (0 != dk_send_can_continue()) {
+ wrpart = rdbytes - wrbytes;
+ $? ". wrpart=%u", (unsigned)wrpart
+ res = dk4socket_send_app(
+ pcl->sock, bufstart, &wrpart, 0, 0L, 0L, app
+ );
+ switch (res) {
+ case DK4_SOCKET_RESULT_SUCCESS :
+ case DK4_SOCKET_RESULT_IN_PROGRESS : {
+ $? ". success or partial success"
+ wrbytes += wrpart;
+ $? ". bytes written %u", (unsigned)wrbytes
+ if (wrbytes >= rdbytes) {
+ ccwr = 0; $? ". finished"
+ } else { $? ". must continue"
+ bufstart = &(bufstart[wrpart]);
+ }
+ } break;
+ default : { $? "! failed to send"
+ /* ERROR: Failure on socket */
+ ccwr = -1;
+ exval = EXIT_FAILURE;
+ dk4socket_close(pcl->sock, NULL);
+ pcl->sock = INVALID_SOCKET;
+ if (0 != dk4app_log_do(app, DK4_LL_ERROR)) {
+ psoa = (struct sockaddr *)(&(pcl->peeraddr));
+ res = dk4socket_addr_port_to_text(
+ peerbuf, DK4_SIZEOF(peerbuf,dkChar),
+ psoa->sa_family,
+ (const struct sockaddr *)(&(pcl->peeraddr)),
+ pcl->peerlen,
+ NULL
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ msgparts[0] = dk_send_msg[9];
+ msgparts[1] = peerbuf;
+ dk4app_log_msg(
+ app, DK4_LL_ERROR, msgparts, 2
+ );
+ }
+ }
+ } break;
+ }
+ } else {
+ ccwr = -1;
+ }
+ } while (1 == ccwr);
+ if (0 == ccwr) {
+ anya = 1;
+ }
+ $? ". ccwr = %d", ccwr
+ }
+ }
+ if (0 == dk_send_can_continue()) {
+ cc = -1;
+ pcl = NULL;
+ }
+ } while (NULL != pcl);
+ if (0 != feof(infile)) {
+ cc = 0;
+ }
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = -1;
+ }
+ }
+ if ((1 == cc) && (0 == anya)) {
+ /* Warning: All clients disconnected */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_WARNING, 19);
+ }
+ /* PROGRESS: Finished data transfer */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_PROGRESS, 8);
+ if (0 != cc) {
+ exval = EXIT_FAILURE;
+ goto finished;
+ }
+
+ /* Shut down all sockets.
+ */
+ cc = 1;
+ dk4sto_it_reset(i_clients);
+ while (1 == cc) {
+ if (0 != dk_send_can_continue()) {
+ pcl = (dk_send_client_t *)dk4sto_it_next(i_clients);
+ if (NULL != pcl) {
+ if (INVALID_SOCKET != pcl->sock) {
+ res = dk4socket_shutdown_app(pcl->sock, DK4_SOCKET_SHUT_WRITE, app);
+ if (DK4_SOCKET_RESULT_SUCCESS != res) {
+ exval = EXIT_FAILURE;
+ dk4socket_close(pcl->sock, NULL);
+ pcl->sock = INVALID_SOCKET;
+ }
+ }
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = -1;
+ }
+ }
+
+ /* For orderly release read from sockets until we have 0 bytes input.
+ */
+ dk4sto_it_reset(i_clients);
+ do {
+ if (0 != dk_send_can_continue()) {
+ pcl = (dk_send_client_t *)dk4sto_it_next(i_clients);
+ if (NULL != pcl) {
+ cc = 1;
+ while (1 == cc) {
+ rdbytes = sizeof(dk_send_buf);
+ res = dk4socket_recv(
+ pcl->sock, dk_send_buf, &rdbytes, 0, 0L, 0L, NULL
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ if (0 == rdbytes) {
+ cc = 0;
+ }
+ } else {
+ cc = 0;
+ }
+ if (0 == dk_send_can_continue()) {
+ cc = 0;
+ pcl = NULL;
+ }
+ }
+ }
+ } else {
+ pcl = NULL;
+ }
+ } while (NULL != pcl);
+
+ /* Finally clean up.
+ */
+ finished:
+ /* Close the connection sockets */
+ if ((NULL != i_clients) && (NULL != s_clients)) {
+ dk4sto_it_reset(i_clients);
+ do {
+ pcl = (dk_send_client_t *)dk4sto_it_next(i_clients);
+ if (NULL != pcl) {
+ if (INVALID_SOCKET != pcl->sock) {
+ dk4socket_close(pcl->sock, NULL);
+ }
+ }
+ } while (NULL != pcl);
+ }
+ /* Close listener socket set */
+ if (NULL != listeners) {
+ dk4socket_set_close(listeners, NULL);
+ }
+ /* Clean up connection container and iterator */
+ if (NULL != i_clients) {
+ dk4sto_it_reset(i_clients);
+ do {
+ pcl = (dk_send_client_t *)dk4sto_it_next(i_clients);
+ if (NULL != pcl) {
+ dk4mem_free(pcl);
+ }
+ } while (NULL != pcl);
+ dk4sto_it_close(i_clients);
+ }
+ if (NULL != s_clients) {
+ dk4sto_close(s_clients);
+ }
+ $? "- dk_send_do_networking"
+}
+
+
+
+/** Process command line arguments, and continue.
+ @param portname Port name to listen.
+ @param infile Input file to read data from.
+ @param filename Input file name.
+*/
+static
+void
+dk_send_process_cmdline_args(
+ const dkChar *portname,
+ FILE *infile,
+ const dkChar *filename
+)
+{
+ const dkChar *argptr = NULL;
+ const dkChar *endptr = NULL;
+ const dkChar *argval = NULL;
+ dkChar *argcpy = NULL;
+ dk4_allowed_peer_t *ppeer;
+ double timeout = 0.0;
+ double td1 = 0.0;
+ double td2 = 0.0;
+ dk4_um_t um = (dk4_um_t)0UL;
+ int res = 0;
+ $? "+ dk_send_process_cmdline_args"
+ /* Check whether to allow local connections only.
+ */
+ if (0 != dk4app_opt_is_set_short(app, dkT('l'), NULL)) {
+ local_only = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('p'), NULL)) {
+ is_pipe = 1;
+ }
+ /* Set up backlog
+ */
+ if (0 != dk4app_opt_is_set_short(app, dkT('b'), NULL)) {
+ if (0 != dk4app_opt_get_unsigned_short(&um, app, dkT('b'), NULL)) {
+ if ((dk4_um_t)(INT_MAX) >= um) {
+ if ((dk4_um_t)0UL < um) {
+ backlog = (int)um;
+ } else {
+ backlog = 1;
+ }
+ } else {
+ backlog = INT_MAX;
+ }
+ } else {
+ /* ERROR: Not an unsigned number, must not happen */
+ goto finished;
+ }
+ }
+ /* Find timeout settings.
+ */
+ if (0 != dk4app_opt_is_set_short(app, dkT('c'), NULL)) {
+ if (0 != dk4app_opt_get_double_short(&timeout, app, dkT('c'), NULL)) {
+ if (0.0 <= timeout) {
+ td1 = floor(timeout);
+ td2 = timeout - td1;
+ td2 = td2 * 1000000.0;
+ if ((double)(LONG_MAX) >= td1) {
+ dk_send_timeout_secs = (long)td1;
+ dk_send_timeout_usecs = (long)td2;
+ } else {
+ /* ERROR: Timeout value too large! */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 16);
+ goto finished;
+ }
+ } else {
+ /* ERROR: Can not use negative timeout */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 17);
+ goto finished;
+ }
+ } else {
+ /* ERROR: Not timeout value found */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 18);
+ goto finished;
+ }
+ }
+ /* Find number of clients.
+ */
+ if (0 != dk4app_opt_is_set_short(app, dkT('n'), NULL)) {
+ argval = dk4app_opt_get_string_ptr_short(app, dkT('n'), NULL);
+ if (dk4str_cmp(dk_send_kwnl[3], argval) == 0) {
+ numclients = (dk4_um_t)0UL;
+ } else {
+ res = dk4ma_input_dk_dec_dk4_um_t(
+ &numclients, argval, &endptr, 1, NULL
+ );
+ if (0 == res) {
+ /* ERROR: Invalid option argument */
+ dk4app_log_3(
+ app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 10, 11, argval
+ );
+ goto finished;
+ }
+ }
+ } $? ". number of clients ok"
+ /* Find allowed client addresses.
+ */
+ if (0 != dk4app_opt_is_set_short(app, dkT('a'), NULL)) {
+ argptr = dk4app_opt_get_string_ptr_short(app, dkT('a'), NULL);
+ if (NULL == argptr) {
+ /* ERROR: Failed to obtain Argument */
+ $? "! BUG, Failed to obtain option argument"
+ goto finished;
+ }
+ argcpy = dk4str_dup_app(argptr, app);
+ if (NULL == argcpy) { goto finished; }
+ if (0 == dk_send_get_allowed_clients(argcpy)) { goto finished; }
+ } $? ". remote address ok"
+ /* Do the network transmission.
+ */
+ dk_send_do_networking(portname, infile, filename);
+ $? ". going to release resources"
+ /* Finally release resources.
+ */
+ finished:
+ if (NULL != argcpy) {
+ dk4mem_free(argcpy);
+ }
+ if (NULL != s_allowed) {
+ if (NULL != i_allowed) {
+ dk4sto_it_reset(i_allowed);
+ do {
+ ppeer = (dk4_allowed_peer_t *)dk4sto_it_next(i_allowed);
+ if (NULL != ppeer) {
+ dk4mem_free(ppeer);
+ }
+ } while(NULL != ppeer);
+ dk4sto_it_close(i_allowed);
+ i_allowed = NULL;
+ }
+ dk4sto_close(s_allowed);
+ s_allowed = NULL;
+ }
+ $? "- dk_send_process_cmdline_args"
+}
+
+
+
+/** Bring Winsock up before performing other steps.
+ @param portname Port name to listen.
+ @param infile Input file to read data from.
+ @param filename Input file name.
+*/
+static
+void
+dk_send_run_for_file(
+ const dkChar *portname,
+ FILE *infile,
+ const dkChar *filename
+)
+{
+ if (dk4socket_up_app(app)) {
+ dk_send_process_cmdline_args(portname, infile, filename);
+ dk4socket_down_app(app);
+ }
+}
+
+
+
+/** Run for real file name.
+ @param portname Port name.
+ @param filename File name, no further expansion required.
+*/
+static
+void
+dk_send_run_for_real_file_name(const dkChar *portname, const dkChar *filename)
+{
+ FILE *inf;
+ int tests = DK4_FOPEN_SC_USER;
+ if (dk4isadmin()) { tests = DK4_FOPEN_SC_PRIVILEGED; }
+ inf = dk4fopen_app(filename, dk_send_kwnl[5], tests, app);
+ if (NULL != inf) {
+ dk_send_run_for_file(portname, inf, filename);
+ fclose(inf);
+ }
+}
+
+
+
+#if DK4_ON_WINDOWS
+
+/** Expand file name and run for file.
+ @param portname Port name (first command line argument).
+ @param filename File name pattern.
+*/
+static
+void
+dk_send_expand_filename(const dkChar *portname, const dkChar *filename)
+{
+ dkChar buf[DK4_MAX_PATH];
+ dk4_dir_t *fne;
+ const dkChar *fn;
+ const dkChar *pt;
+ size_t szbuf = DK4_SIZEOF(buf,dkChar);
+ int copied = 0;
+
+ fne = dk4app_fne_open(filename, app);
+ if (NULL != fne) {
+ fn = dk4dir_next_file(fne);
+ if (NULL != fn) {
+ pt = dk4dir_get_path(fne);
+ if (NULL == dk4dir_next_file(fne)) {
+ if (NULL != pt) {
+ copied = 0;
+ if (0 != dk4str_cpy_s(buf, szbuf, pt, NULL)) {
+ if (0 != dk4str_cat_s(buf, szbuf, dk_send_kwnl[4], NULL)) {
+ if (0 != dk4str_cat_s(buf, szbuf, fn, NULL)) {
+ copied = 1;
+ dk_send_run_for_real_file_name(portname, buf);
+ }
+ }
+ }
+ if (0 == copied) {
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pt);
+ }
+ } else {
+ dk_send_run_for_real_file_name(portname, fn);
+ }
+ } else {
+ /* ERROR: Multiple matching files */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 106, filename);
+ }
+ } else {
+ /* ERROR: No such file */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 107, filename);
+ }
+ dk4dir_close(fne);
+ }
+}
+
+#endif
+
+
+
+static
+void
+dk_send_normal_run()
+{
+ const dkChar *filename = NULL;
+ int xargc = 0;
+#if DK4_ON_WINDOWS
+ int oldmode = 0;
+#endif
+ xargc = dk4app_get_argc(app);
+ switch (xargc) {
+ case 1: {
+#if DK4_ON_WINDOWS
+ oldmode = _setmode(_fileno(stdin), _O_BINARY);
+#endif
+ dk_send_run_for_file(dk4app_get_argv(app, 0), stdin, dk_send_msg[2]);
+#if DK4_ON_WINDOWS
+ _setmode(_fileno(stdin), oldmode);
+#endif
+ } break;
+ case 2: {
+ filename = dk4app_get_argv(app, 1);
+#if DK4_ON_WINDOWS
+ if (dk4path_must_expand(filename)) {
+ dk_send_expand_filename(dk4app_get_argv(app, 0), filename);
+ } else {
+#endif
+ dk_send_run_for_real_file_name(dk4app_get_argv(app, 0), filename);
+#if DK4_ON_WINDOWS
+ }
+#endif
+ } break;
+ default : {
+ /* ERROR: Wrong number of command line arguments */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 12);
+ } break;
+ }
+}
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+dk_send_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ struct sigaction opipe;
+#endif
+ struct sigaction oint;
+#ifdef SIGPIPE
+ struct sigaction npipe;
+#endif
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+ int success = 0;
+
+#ifdef SIGPIPE
+ /* Set up signal handling for SIGPIPE.
+ */
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+#endif
+
+ /* Set up signal handling for SIGINT.
+ */
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ dk_send_normal_run();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+#ifdef SIGPIPE
+ /* Restore signal handling for SIGPIPE.
+ */
+ restore_old_pipe:
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+#endif
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+dk_send_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ dk_send_normal_run();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+#ifdef SIGPIPE
+ sigset(SIGPIPE, oldpipe);
+#endif
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+dk_send_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = signal(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ dk_send_normal_run();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+#ifdef SIGPIPE
+ signal(SIGPIPE, oldpipe);
+#endif
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+dk_send_run_with_signal_handlers(void)
+{
+ dk_send_normal_run();
+}
+#endif
+#endif
+#endif
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ $!trace-init dk-send.deb
+ $? "+ main"
+ app = dk4app_open_cmd(
+ argc, argv, dk_send_options, dk_send_sz_options,
+ dk_send_kwnl[0], DKT_VERSION_DK,
+ dk_send_kwnl[1], dk_send_help_text, dk_send_license_text
+ );
+ if (NULL != app) {
+ dk_send_sz_msg = dk4app_string_table_size(dk_send_kw_def);
+ dk_send_msg = dk4app_string_table(app, dk_send_kwnl[2], dk_send_kw_def);
+ if (0 != dk4app_can_run_normally(app)) {
+ dk_send_run_with_signal_handlers();
+ } else {
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ if (0 != sig_read_atomic(&sig_had_int)) {
+ /* ERROR: INT signal */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 13);
+ exval = EXIT_FAILURE;
+ }
+ if (0 != sig_read_atomic(&sig_had_term)) {
+ /* ERROR: TERM signal */
+ dk4app_log_1(app, dk_send_msg, dk_send_sz_msg, DK4_LL_ERROR, 14);
+ exval = EXIT_FAILURE;
+ }
+#ifdef SIGPIPE
+ if (0 != sig_read_atomic(&sig_had_pipe)) {
+ exval = EXIT_FAILURE;
+ }
+#endif
+ dk4app_close(app);
+ }
+ $? "- main %d", exval
+ $!trace-end
+ exit(exval);
+ return exval;
+}
+
diff --git a/support/dktools/dk-send.rc b/support/dktools/dk-send.rc
new file mode 100644
index 0000000000..2699f0f80c
--- /dev/null
+++ b/support/dktools/dk-send.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Send data transmission\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "Send data transmission\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "dk-send\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/dk-sort.c b/support/dktools/dk-sort.c
new file mode 100644
index 0000000000..87a55cda5c
--- /dev/null
+++ b/support/dktools/dk-sort.c
@@ -0,0 +1,1855 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk-sort.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk-sort.c The dk-sort module.
+*/
+
+
+#line 8 "dk-sort.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4vers.h"
+#include "dk4app.h"
+#include "dk4aopt.h"
+#include "dk4mem.h"
+#include "dk4mema.h"
+#include "dk4fput.h"
+#include "dk4mpl.h"
+#include "dk4maiddbl.h"
+#if 0
+#include "dk4maidhmu.h"
+#include "dk4maiddmu.h"
+#include "dk4maiddmi.h"
+#endif
+#include "dk4maidddu.h"
+#include "dk4maidhdu.h"
+#include "dk4maidddi.h"
+#include "dk4maodd.h"
+#include "dk4enc.h"
+#include "dk4strd.h"
+#include "dk4strda.h"
+#include "dk4tspdk.h"
+#include "dk4fopda.h"
+#include "dk4pathd.h"
+#include "dk4filed.h"
+
+
+
+
+
+#line 69 "dk-sort.ctr"
+
+
+
+/** Structure to store one line, optionally with evaluation result.
+*/
+typedef struct {
+ dkChar *line; /**< Text line. */
+ dkChar *fts; /**< File type suffix. */
+ union {
+ dk4_um_t u; /**< Unsigned number at start of line. */
+ dk4_im_t i; /**< Signed number at start of line. */
+ double d; /**< Floating point number at start of line. */
+ } value; /**< Value at start of line. */
+ char h; /**< Flag: Have value. */
+} dk_sort_line_t;
+
+
+/** Default help text, shown if help file is not found.
+*/
+static const dkChar * const dk_sort_help_text[] = {
+dkT(""),
+dkT("Sort text line by line"),
+dkT(""),
+dkT("dk-sort [<options>] [<file(s)>]"),
+dkT(""),
+dkT("Options:"),
+dkT("-i <encoding>\t--input-encoding=<encoding>\tExpected input encoding."),
+dkT("-c\t\t--case-insensitive\t\tCase-insensitive comparisons."),
+dkT("-b\t\t--ignore-leading-blanks\t\tIgnore leading whitespaces."),
+dkT("-w\t\t--normalize\t\t\tNormalize text lines."),
+dkT("-e\t\t--suppress-empty-lines\t\tSuppress output for empty lines."),
+dkT("-t\t\t--file-type\t\t\tSort by file type."),
+dkT("-s <size>\t--skip-words=<size>\t\tNumber of words to skip."),
+dkT("-n\t\t--number\t\t\tLeading signed integer values."),
+dkT("-u\t\t--unsigned\t\t\tLeading unsigned integer values."),
+dkT("-x\t\t--hex\t\t\t\tLeading hexadecimal numbers."),
+dkT("-f\t\t--float\t\t\t\tLeading floating point numbers."),
+dkT("-v\t\t--value-lines-first\t\tLines containing numbers first."),
+dkT("-m\t\t--merge-equal-lines\t\tMerge equal lines."),
+dkT("-r\t\t--reverse\t\t\tReverse output order."),
+dkT("-l <size>\t--line-size=<size>\t\tLine buffer sizes."),
+dkT("-R\t\t--reset\t\t\t\tIgnore preferences values."),
+dkT(""),
+dkT("--help\t\t\t\t\t\tShow this short help text."),
+dkT("--manual\t\t\t\t\t*** SHOW FULL MANUAL. ***"),
+dkT("--version\t\t\t\t\tShow version information."),
+dkT("--license\t\t\t\t\tShow license information."),
+dkT(""),
+dkT("http://dktools.sourceforge.net"),
+dkT(""),
+NULL
+
+
+#line 121 "dk-sort.ctr"
+};
+
+
+
+/** License text.
+*/
+static const dkChar * const dk_sort_license_text[] = {
+dkT("This software uses code from the following projects, either directly or as"),
+dkT("a library:"),
+dkT(""),
+dkT("dktools\t\tDirk Krause's tools and libraries."),
+dkT("\t\tSee http://dktools.sourceforge.net/ for more information."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT("zlib\t\tData compression library."),
+dkT("\t\tSee http://www.zlib.net/ for more information."),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT("bzip2\t\tData compression program and library."),
+dkT("\t\tSee http://www.bzip.org/ for more information."),
+#endif
+dkT(""),
+dkT("All the licenses below apply to the program."),
+dkT("Licenses for used libraries are shown as found on my Scientific Linux 6.x"),
+dkT("computer in the /usr/share/doc directory on 2015-04-01. Check the project"),
+dkT("homepages of the used libraries for additional information and/or updated"),
+dkT("license terms."),
+dkT(""),
+dkT(""),
+dkT("DK tools and libraries license"),
+dkT("=============================="),
+dkT("Copyright (c) 2015-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above copyright notice,"),
+dkT(" this list of conditions and the following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("* Neither the name of the Dirk Krause nor the names of contributors may be"),
+dkT(" used to endorse or promote products derived from this software without"),
+dkT(" specific prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\""),
+dkT("AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED."),
+dkT(""),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,"),
+dkT("INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,"),
+dkT("BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,"),
+dkT("DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY"),
+dkT("OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,"),
+dkT("EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT(""),
+dkT("Zlib license"),
+dkT("============"),
+dkT("(C) 1995-2004 Jean-loup Gailly and Mark Adler"),
+dkT(""),
+dkT("This software is provided 'as-is', without any express or implied"),
+dkT("warranty. In no event will the authors be held liable for any damages"),
+dkT("arising from the use of this software."),
+dkT(""),
+dkT("Permission is granted to anyone to use this software for any purpose,"),
+dkT("including commercial applications, and to alter it and redistribute it"),
+dkT("freely, subject to the following restrictions:"),
+dkT(""),
+dkT("1. The origin of this software must not be misrepresented; you must not"),
+dkT(" claim that you wrote the original software. If you use this software"),
+dkT(" in a product, an acknowledgment in the product documentation would be"),
+dkT(" appreciated but is not required."),
+dkT("2. Altered source versions must be plainly marked as such, and must not be"),
+dkT(" misrepresented as being the original software."),
+dkT("3. This notice may not be removed or altered from any source distribution."),
+dkT(""),
+dkT("Jean-loup Gailly Mark Adler"),
+dkT("jloup@gzip.org madler@alumni.caltech.edu"),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT(""),
+dkT("Bzip2 and libbzip2 library license"),
+dkT("=================================="),
+dkT("This program, \"bzip2\", the associated library \"libbzip2\", and all"),
+dkT("documentation, are copyright (C) 1996-2007 Julian R Seward. All"),
+dkT("rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions"),
+dkT("are met:"),
+dkT(""),
+dkT("1. Redistributions of source code must retain the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer."),
+dkT(""),
+dkT("2. The origin of this software must not be misrepresented; you must "),
+dkT(" not claim that you wrote the original software. If you use this "),
+dkT(" software in a product, an acknowledgment in the product "),
+dkT(" documentation would be appreciated but is not required."),
+dkT(""),
+dkT("3. Altered source versions must be plainly marked as such, and must"),
+dkT(" not be misrepresented as being the original software."),
+dkT(""),
+dkT("4. The name of the author may not be used to endorse or promote "),
+dkT(" products derived from this software without specific prior written "),
+dkT(" permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS"),
+dkT("OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED"),
+dkT("WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE"),
+dkT("GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS"),
+dkT("INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,"),
+dkT("WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS"),
+dkT("SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+dkT(""),
+dkT("Julian Seward, jseward@bzip.org"),
+dkT("bzip2/libbzip2 version 1.0.5 of 10 December 2007"),
+#endif
+dkT(""),
+NULL
+
+
+#line 252 "dk-sort.ctr"
+};
+
+
+
+/** Command line options.
+*/
+static const dk4_option_specification_t dk_sort_options[] = {
+ { dkT('R'), dkT("reset"), DK4_OPT_ARG_NONE },
+ { dkT('i'), dkT("input-encoding"), DK4_OPT_ARG_STRING },
+ { dkT('c'), dkT("case-insensitive"), DK4_OPT_ARG_NONE },
+ { dkT('b'), dkT("ignore-leading-blanks"), DK4_OPT_ARG_NONE },
+ { dkT('w'), dkT("normalize"), DK4_OPT_ARG_NONE },
+ { dkT('t'), dkT("file-type"), DK4_OPT_ARG_NONE },
+ { dkT('s'), dkT("skip-words"), DK4_OPT_ARG_SIZE },
+ { dkT('n'), dkT("number"), DK4_OPT_ARG_NONE },
+ { dkT('u'), dkT("unsigned"), DK4_OPT_ARG_NONE },
+ { dkT('x'), dkT("hex"), DK4_OPT_ARG_NONE },
+ { dkT('f'), dkT("float"), DK4_OPT_ARG_NONE },
+ { dkT('v'), dkT("value-lines-first"), DK4_OPT_ARG_NONE },
+ { dkT('m'), dkT("merge-equal-lines"), DK4_OPT_ARG_NONE },
+ { dkT('r'), dkT("reverse"), DK4_OPT_ARG_NONE },
+ { dkT('l'), dkT("line-size"), DK4_OPT_ARG_SIZE },
+ { dkT('e'), dkT("suppress-empty-lines"), DK4_OPT_ARG_NONE }
+};
+
+
+
+/** Number of elements in the dk_sort_options array.
+*/
+static const size_t dk_sort_sz_options =
+sizeof(dk_sort_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Constant text strings used by the module, not localized.
+*/
+static const dkChar * const dk_sort_kwnl[] = {
+/* 0 */
+dkT("dktools"),
+
+/* 1 */
+dkT("dk-sort.txt"),
+
+/* 2 */
+dkT("dk-sort.str"),
+
+/* 3 */
+dkT("stdin"),
+
+/* 4 */
+dkT("rb"),
+
+/* 5 */
+dkT("\\"),
+
+/* 6 */
+dkT("line.size"),
+
+NULL
+
+
+#line 319 "dk-sort.ctr"
+};
+
+
+
+/** Text strings used by program, localized versions used if found.
+*/
+static const dkChar * const dk_sort_kw_def[] = {
+/* 0 */
+dkT("Failed to set up signal handlers!"),
+
+/* 1 */
+dkT("Failed to restore previous signal handlers!"),
+
+/* 2 */
+dkT("Encoding error!"),
+
+/* 3 */
+dkT("Decoding error!"),
+
+/* 4 */
+dkT("Processing error!"),
+
+/* 5 */
+dkT("Encoding error!\n\tByte: "),
+
+/* 6 */
+dkT("Decoding error!\n\tByte: "),
+
+/* 7 */
+dkT("Processing error!\n\tByte: "),
+
+/* 8 */
+dkT(",\n\tCharacter: "),
+
+/* 9 */
+dkT(",\n\tPosition in line: "),
+
+/* 10 */
+dkT("."),
+
+/* 11 */
+dkT("Options -u, -x, and -f are mutually exclusive!"),
+
+/* 12 */
+dkT("Illegal input encoding: \""),
+
+/* 13 */
+dkT("\"!"),
+
+/* 14 */
+dkT("Failed to initialize text stream processing!"),
+
+NULL
+
+
+#line 364 "dk-sort.ctr"
+};
+
+
+
+/** Default buffer to use if sizes up to 1024 are specified.
+*/
+static dkChar input_line_buffer[1024];
+
+
+
+/** Input buffer really to use.
+*/
+static dkChar *ibptr = input_line_buffer;
+
+
+
+/** Allocated input buffer address for line sizes larger than 1024.
+*/
+static dkChar *allocated_buffer = NULL;
+
+
+
+/** Localized message texts.
+*/
+static const dkChar * const *dk_sort_msg = dk_sort_kw_def;
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Line storage.
+*/
+static dk4_sto_t *lsto = NULL;
+
+
+
+/** Iterator to traverse line storage.
+*/
+static dk4_sto_it_t *lsti = NULL;
+
+
+
+/** Number of strings in dk_sort_msg array.
+*/
+static size_t dk_sort_sz_msg =
+sizeof(dk_sort_kw_def)/sizeof(DK4_PCDKCHAR) - 1;
+
+
+/** Size of ibptr buffer.
+*/
+static size_t ibsz = DK4_SIZEOF(input_line_buffer,dkChar);
+
+
+
+/** Number of words to skip when processing file names.
+*/
+static size_t skip_words = 0;
+
+
+
+/** Flag: Case-insensitive comparison.
+*/
+static int case_insensitive = 0;
+
+
+
+/** How to handle blanks:
+ 0 leave as is,
+ 1 remove leading and trailing blanks,
+ 2 normalize lines.
+*/
+static int handle_blanks = 0;
+
+
+
+/** How to handle leading values:
+ 0 do not use numeric values,
+ 1 use signed integers
+ 2 use unsigned integers
+ 3 use unsigned integers, specified in hexadecimal notation
+ 4 use floating point numbers.
+*/
+static int handle_values = 0;
+
+
+
+/** Flag: Sort files type file type suffix.
+*/
+static int handle_file_type = 0;
+
+
+
+/** Flag: Show lines containing values before lines not containing
+ a value. Default is to show lines without a value first.
+*/
+static int value_first = 0;
+
+
+
+/** Flag: Merge equal lines.
+*/
+static int merge = 0;
+
+
+
+/** Flag: Reverse search order.
+*/
+static int reversed = 0;
+
+
+
+/** Flag: Suppress empty lines.
+*/
+static int suppress_empty = 0;
+
+
+/** Expected input encoding.
+*/
+static int input_encoding = DK4_FILE_ENCODING_ASCII;
+
+
+
+/** Flag: Already reported decoding errors.
+*/
+static int dk_sort_had_decoding_errors = 0;
+
+
+
+/** Flag: Already reported encoding errors.
+*/
+static int dk_sort_had_encoding_errors = 0;
+
+
+
+/** Flag: Already reported processing errors.
+*/
+static int dk_sort_had_proc_errors = 0;
+
+
+
+/** Exit status code returned by the main function.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+/** Pass a volatile pointer to an atomic integer.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ptr Address of atomic integer variable.
+ @return The unmodified pointer.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+/** Check whether we can continue or if a signal was received.
+ @param check_pipe Flag: Check for occured SIGPIPE signal too.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(int check_pipe)
+{
+ int back = 1;
+#ifdef SIGPIPE
+ if (0 != check_pipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_int )) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+/** Check whether we can continue.
+ @return 1 for yes, 0 for no.
+*/
+static
+int
+dk_sort_can_continue(void)
+{
+ int back = 1;
+ if (0 == sig_can_continue(1)) {
+ back = 0;
+ }
+ return back;
+}
+
+
+
+/** Delete a storage node.
+ @param ptr Node to delete.
+*/
+static
+void
+dk_sort_delete_node(dk_sort_line_t *ptr)
+{
+
+
+#line 644 "dk-sort.ctr"
+ if (NULL != ptr) {
+ dk4mem_release(ptr->line);
+ dk4mem_free(ptr);
+ }
+
+
+#line 649 "dk-sort.ctr"
+}
+
+
+
+/** Create storage node for a text line.
+ @param line Text line to store.
+ @return Pointer to new node on success, NULL on error.
+*/
+static
+dk_sort_line_t *
+dk_sort_new_node(dkChar *line)
+{
+ dk_sort_line_t *back = NULL;
+ dkChar *lines = NULL; /* Start of line */
+ const dkChar *endptr = NULL; /* First text after value */
+ double d; /* Evaluation double */
+ dk4_um_t u; /* Evaluation unsigned */
+ dk4_im_t i; /* Evaluation integer */
+
+
+#line 668 "dk-sort.ctr"
+ /* Normalize or remove leading and trailing whitespace if required.
+ */
+ if (NULL != line) {
+ dk4str_delnl(line);
+ if (0 < handle_blanks) {
+ lines = dk4str_start(line, NULL);
+ if (NULL != lines) {
+ line = lines;
+ switch (handle_blanks) {
+ case 1: {
+ dk4str_rtwh(line, NULL);
+ } break;
+ case 2: {
+ dk4str_normalize(line, NULL);
+ } break;
+ }
+ } else {
+ *line = dkT('\0');
+ }
+ }
+ }
+ if ((0 != suppress_empty) && (NULL != line)) {
+ lines = dk4str_start(line, NULL);
+ if (NULL == lines) {
+ line = NULL;
+ }
+ }
+
+ /* Create node.
+ */
+ if (NULL != line) {
+ back = dk4mem_new_app(dk_sort_line_t,1,app);
+ if (NULL != back) {
+ back->fts = NULL;
+ back->h = 0x00;
+ back->line = dk4str_dup_app(line, app);
+ if (NULL != back->line) {
+ if (0 != handle_file_type) {
+ back->fts = dk4path_get_suffix(back->line, NULL);
+ }
+ } else {
+ dk_sort_delete_node(back);
+ back = NULL;
+ exval = EXIT_FAILURE;
+ /* ERROR: Memory, already reported */
+ }
+ } else {
+ exval = EXIT_FAILURE;
+ /* ERROR: Memory, already reported */
+ }
+ }
+
+ /* Evaluate node if necessary.
+ */
+ if (NULL != back) {
+ switch (handle_values) {
+ case 4: {
+ d = 0.0;
+ if (0 != dk4ma_input_dk_double(&d, line, &endptr, 2, NULL)) {
+ (back->value).d = d;
+ back->h = 0x01;
+ }
+ } break;
+ case 3: {
+ u = (dk4_um_t)0UL;
+ if (0 != dk4ma_input_dk_hex_dk4_um_t(&u, line, &endptr, 2, NULL)) {
+ (back->value).u = u;
+ back->h = 0x01;
+ }
+ } break;
+ case 2: {
+ u = (dk4_um_t)0UL;
+ if (0 != dk4ma_input_dk_dec_dk4_um_t(&u, line, &endptr, 2, NULL)) {
+ (back->value).u = u;
+ back->h = 0x01;
+ }
+ } break;
+ case 1: {
+ i = (dk4_im_t)0L;
+ if (0 != dk4ma_input_dk_dec_dk4_im_t(&i, line, &endptr, 2, NULL)) {
+ (back->value).i = i;
+ back->h = 0x01;
+ }
+ } break;
+ }
+ }
+
+
+#line 755 "dk-sort.ctr"
+ return back;
+}
+
+
+
+static
+int
+dk_sort_is_dot_file(const dkChar *fn)
+{
+ const dkChar *fns = NULL;
+ const dkChar *ptr = NULL;
+ int back = 0;
+
+
+#line 768 "dk-sort.ctr"
+ ptr = fn;
+ while (dkT('\0') != *ptr) {
+#if DK4_HAVE_BACKSLASH_AS_SEP
+ if (dkT('\\') == *ptr) { fns = ptr; }
+#else
+ if (dkT('/') == *ptr) { fns = ptr; }
+#endif
+ ptr++;
+ }
+ if (NULL == fns) { fns = fn; }
+ else { fns++; }
+
+
+#line 780 "dk-sort.ctr"
+ if (dkT('.') == *fns) {
+ back = 1;
+ }
+#if DK4_ON_WINDOWS
+ if (dkT('_') == *fns) {
+ back = 1;
+ }
+#endif
+
+
+#line 789 "dk-sort.ctr"
+ return back;
+}
+
+
+
+/** Compare two storage nodes.
+ @param l Left node.
+ @param r Right node.
+ @param cr Comparison criteria, ignored here.
+ @return Comparison result.
+*/
+static
+int
+dk_sort_compare_nodes(const void *l, const void *r, int cr)
+{
+ int back = 0;
+ dk_sort_line_t *pl;
+ dk_sort_line_t *pr;
+ const dkChar *fnleft;
+ const dkChar *fnright;
+
+
+#line 810 "dk-sort.ctr"
+ if (NULL != l) {
+ if (NULL != r) {
+ pl = (dk_sort_line_t *)l;
+ pr = (dk_sort_line_t *)r;
+
+ /* Check file type suffix if required.
+ */
+ if (0 != handle_file_type) {
+ fnleft = dk4str_skip(pl->line, skip_words);
+ fnright = dk4str_skip(pr->line, skip_words);
+ if (NULL != fnleft) {
+
+#line 821 "dk-sort.ctr"
+ if (NULL != fnright) {
+
+#line 822 "dk-sort.ctr"
+ if (0 != dk4file_is_directory(fnleft, NULL)) {
+ if (0 == dk4file_is_directory(fnright, NULL)) {
+ back = -1;
+ }
+ } else {
+ if (0 != dk4file_is_directory(fnright, NULL)) {
+ back = 1;
+ }
+ }
+ if (0 == back) {
+ if (0 != dk_sort_is_dot_file(fnleft)) {
+ if (0 == dk_sort_is_dot_file(fnright)) {
+ back = -1;
+ }
+ } else {
+ if (0 != dk_sort_is_dot_file(fnright)) {
+ back = 1;
+ }
+ }
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != fnright) {
+ back = -1;
+ }
+ }
+ if (0 == back) {
+ if (NULL != pl->fts) {
+ if (NULL != pr->fts) {
+ back = dk4str_pathcmp(pl->fts, pr->fts);
+#if DK4_HAVE_CASE_INSENSITIVE_PATHNAMES
+ if (0 == back) {
+ back = dk4str_cmp(pl->fts, pr->fts);
+ }
+#endif
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != pr->fts) {
+ back = -1;
+ }
+ }
+ }
+ }
+
+ /* Check evaluation if required.
+ */
+ if (0 == back) {
+ if (0 != handle_values) {
+ if (0x00 != pl->h) {
+ if (0x00 != pr->h) { /* both values */
+ switch (handle_values) {
+ case 4: {
+ if ((pl->value).d < (pr->value).d) {
+ back = -1;
+ } else {
+ if ((pl->value).d > (pr->value).d) {
+ back = 1;
+ }
+ }
+ } break;
+ case 2: case 3: {
+ if ((pl->value).u < (pr->value).u) {
+ back = -1;
+ } else {
+ if ((pl->value).u > (pr->value).u) {
+ back = 1;
+ }
+ }
+ } break;
+ case 1: {
+ if ((pl->value).i < (pr->value).i) {
+ back = -1;
+ } else {
+ if ((pl->value).i > (pr->value).i) {
+ back = 1;
+ }
+ }
+ } break;
+ }
+ } else { /* only left value */
+ back = ((0 != value_first) ? -1 : 1);
+ }
+ } else {
+ if (0x00 != pr->h) { /* only right value */
+ back = ((0 != value_first) ? 1 : -1);
+ }
+ }
+ }
+ }
+
+ /* String comparison
+ */
+ if (0 == back) {
+ if (0 != case_insensitive) {
+ back = dk4str_casecmp(pl->line, pr->line);
+ if (0 == back) {
+ back = dk4str_cmp(pl->line, pr->line);
+ }
+ } else {
+ back = dk4str_cmp(pl->line, pr->line);
+ }
+ }
+
+ /* Reverse order if necessary.
+ */
+ if (0 != reversed) { back = -1 * back; }
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != r) {
+ back = -1;
+ }
+ }
+
+#line 940 "dk-sort.ctr"
+ return back;
+}
+
+
+
+static
+int
+dk_sort_line_handler(
+ void *obj,
+ dkChar *line,
+ dk4_um_t lineno,
+ dk4_er_t *erp
+)
+{
+ dk_sort_line_t *nptr;
+ int back = DK4_TSP_RES_OK;
+
+
+#line 957 "dk-sort.ctr"
+ nptr = dk_sort_new_node(line);
+ if (NULL != nptr) {
+ if (0 == dk4sto_add(lsto, nptr, NULL)) {
+ dk_sort_delete_node(nptr);
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ back = DK4_TSP_RES_FATAL;
+ exval = EXIT_FAILURE;
+ }
+ }
+
+#line 966 "dk-sort.ctr"
+ return back;
+}
+
+
+
+/** Report an error with position.
+ @param i1 Index of first message part in array.
+ @param i2 Index of alternative first message part.
+ @param bno Current byte number.
+ @param lno Current line number.
+ @param cno Current character number.
+ @param cil Current character number within line.
+ @param fn File name processed.
+*/
+static
+void
+dk_sort_report_with_position(
+ size_t i1,
+ size_t i2,
+ dk4_um_t bno,
+ dk4_um_t lno,
+ dk4_um_t cno,
+ dk4_um_t cil,
+ const dkChar *fn
+)
+{
+ dkChar b1[8*(1+sizeof(dk4_um_t))+16];
+ dkChar b2[8*(1+sizeof(dk4_um_t))+16];
+ dkChar b3[8*(1+sizeof(dk4_um_t))+16];
+ const dkChar *oldlogname = NULL;
+ dk4_um_t oldlogline = (dk4_um_t)0UL;
+ int allbuffersok = 0;
+
+ oldlogname = dk4app_get_log_source_file(app);
+ oldlogline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_file(app, fn);
+ dk4app_set_log_source_line(app, lno);
+ if (0 != dk4ma_write_decimal_unsigned(b3,DK4_SIZEOF(b3,dkChar),cil,0,NULL)) {
+ if (0 != dk4ma_write_decimal_unsigned(b2,DK4_SIZEOF(b2,dkChar),cno,0,NULL)) {
+ if (0 != dk4ma_write_decimal_unsigned(b1,DK4_SIZEOF(b1,dkChar),bno,0,NULL)) {
+ allbuffersok = 1;
+ }
+ }
+ }
+ if (0 != allbuffersok) {
+ dk4app_log_7(
+ app, dk_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, i1, 8, 9, 10, b1, b2, b3
+ );
+ } else {
+ dk4app_log_1(app, dk_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, i2);
+ }
+ dk4app_set_log_source_line(app, oldlogline);
+ dk4app_set_log_source_file(app, oldlogname);
+}
+
+
+
+/** Report errors from line processing.
+ @param er_en Error report for encoding/decoding errors.
+ @param en_pr Error report for processing errors.
+ @param fn File name for error message.
+*/
+static
+void
+dk_sort_report_errors(
+ dk4_er_t *er_en,
+ dk4_er_t *er_pr,
+ const dkChar *fn
+)
+{
+
+
+#line 1037 "dk-sort.ctr"
+ if (NULL != er_en) {
+ switch (er_en->ec) {
+ case DK4_E_DECODING_FAILED : {
+ switch (dk_sort_had_decoding_errors) {
+ case 0: case 1: case 2: {
+ dk_sort_report_with_position(
+ 6, 3,
+ er_en->dt.fpos.byteno, er_en->dt.fpos.lineno,
+ er_en->dt.fpos.charno, er_en->dt.fpos.charinline,
+ fn
+ );
+ } break;
+ }
+ if (3 > dk_sort_had_decoding_errors) { dk_sort_had_decoding_errors++; }
+ } break;
+ case DK4_E_ENCODING_FAILED : {
+ switch (dk_sort_had_encoding_errors) {
+ case 0: case 1: case 2: {
+ dk_sort_report_with_position(
+ 5, 2,
+ er_en->dt.fpos.byteno, er_en->dt.fpos.lineno,
+ er_en->dt.fpos.charno, er_en->dt.fpos.charinline,
+ fn
+ );
+ } break;
+ }
+ if (3 > dk_sort_had_encoding_errors) { dk_sort_had_encoding_errors++; }
+ } break;
+ }
+ }
+ if (NULL != er_pr) {
+ if (DK4_E_NONE != er_pr->ec) {
+ switch (dk_sort_had_proc_errors) {
+ case 0: case 1: case 2: {
+ dk_sort_report_with_position(
+ 7, 4,
+ er_pr->dt.fpos.byteno, er_pr->dt.fpos.lineno,
+ er_pr->dt.fpos.charno, er_pr->dt.fpos.charinline,
+ fn
+ );
+ } break;
+ }
+ if (3 > dk_sort_had_proc_errors) { dk_sort_had_proc_errors++; }
+ }
+ }
+
+
+#line 1083 "dk-sort.ctr"
+}
+
+
+
+/** Process one input file opened in binary mode.
+ @param fipo File to process.
+ @param filename File name.
+*/
+static
+void
+dk_sort_process_file(FILE *fipo, const dkChar *filename)
+{
+ dk4_tspdk_t tsp;
+ dk4_er_t er_en;
+ dk4_er_t er_pr;
+ dk4_er_t er;
+ int res;
+ int cc;
+ int c;
+ unsigned char ub;
+
+
+#line 1104 "dk-sort.ctr"
+ dk4error_init(&er_en);
+ dk4error_init(&er_pr);
+ dk4error_init(&er);
+ res = dk4tspdk_setup_line(
+ &tsp, NULL,
+ dk_sort_line_handler,
+ ibptr, ibsz,
+ dk4app_get_encoding(app), input_encoding,
+ &er
+ );
+ if (0 != res) {
+ cc = 1;
+ do {
+ if (dk_sort_can_continue()) {
+ c = fgetc(fipo);
+ if (EOF != c) {
+ ub = (unsigned char)c;
+ switch (dk4tspdk_add_one_byte(&tsp, ub)) {
+ case DK4_TSP_RES_FATAL : {
+ cc = -1;
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tsp);
+ dk_sort_report_errors(&er_en, &er_pr, filename);
+ } break;
+ case DK4_TSP_RES_ERROR : {
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tsp);
+ dk_sort_report_errors(&er_en, &er_pr, filename);
+ } break;
+ }
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = -1;
+ }
+ } while (1 == cc);
+ if (0 == cc) {
+ switch (dk4tspdk_finish(&tsp)) {
+ case DK4_TSP_RES_FATAL : {
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tsp);
+ dk_sort_report_errors(&er_en, &er_pr, filename);
+ } break;
+ case DK4_TSP_RES_ERROR : {
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tsp);
+ dk_sort_report_errors(&er_en, &er_pr, filename);
+ } break;
+ }
+ }
+ } else {
+ /* ERROR: Failed to initialize text stream processor */
+ dk4app_log_1(app, dk_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, 14);
+ exval = EXIT_FAILURE;
+ }
+
+
+#line 1161 "dk-sort.ctr"
+}
+
+
+
+/** Process standard input.
+*/
+static
+void
+dk_sort_process_stdin(void)
+{
+#if DK4_ON_WINDOWS
+ int oldmode;
+#endif
+
+
+#line 1175 "dk-sort.ctr"
+#if DK4_ON_WINDOWS
+ oldmode = _setmode(_fileno(stdin), _O_BINARY);
+#endif
+ dk_sort_process_file(stdin, dk_sort_kwnl[3]);
+#if DK4_ON_WINDOWS
+ _setmode(_fileno(stdin), oldmode);
+#endif
+
+
+#line 1183 "dk-sort.ctr"
+}
+
+
+
+static
+void
+dk_sort_process_one_file_name(const dkChar *fn)
+{
+ FILE *fipo;
+ int tests = DK4_FOPEN_SC_IS_REGULAR;
+
+
+#line 1194 "dk-sort.ctr"
+ fipo = dk4fopen_app(fn, dk_sort_kwnl[4], tests, app);
+ if (NULL != fipo) {
+ dk_sort_process_file(fipo, fn);
+ fclose(fipo);
+ } else {
+ /* ERROR: Failed to open file, already reported */
+ exval = EXIT_FAILURE;
+ }
+
+
+#line 1203 "dk-sort.ctr"
+}
+
+
+
+#if DK4_ON_WINDOWS
+static
+void
+dk_sort_expand_one_file_name(const dkChar *pattern)
+{
+ dkChar buf[DK4_MAX_PATH];
+ dk4_dir_t *fne;
+ const dkChar *shf; /* Short file name */
+ const dkChar *pth; /* Path */
+ int any_file_found = 0; /* Flag: Any file found */
+ int can_continue;
+
+
+#line 1219 "dk-sort.ctr"
+ fne = dk4app_fne_open(pattern, app);
+ if (NULL != fne) {
+ can_continue = 1;
+ while ((0 != can_continue) && (NULL != (shf = dk4dir_next_file(fne)))) {
+ any_file_found = 1;
+ pth = dk4dir_get_path(fne);
+ if (NULL != pth) {
+ if (0 != dk4str_cpy_s(buf, DK4_SIZEOF(buf,dkChar), pth, NULL)) {
+ if(0 != dk4str_cat_s(buf,DK4_SIZEOF(buf,dkChar),dk_sort_kwnl[5],NULL))
+ {
+ if(0 != dk4str_cat_s(buf, DK4_SIZEOF(buf,dkChar), shf, NULL)) {
+ dk_sort_process_one_file_name(buf);
+ } else {
+ exval = EXIT_FAILURE;
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 105, pattern);
+ }
+ }
+ else
+ {
+ exval = EXIT_FAILURE;
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 105, pattern);
+ }
+ } else {
+ exval = EXIT_FAILURE;
+ /* ERROR: Path too long! */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 105, pattern);
+ }
+ } else {
+ dk_sort_process_one_file_name(shf);
+ }
+ can_continue = dk_sort_can_continue();
+ if (EXIT_FAILURE == exval) { can_continue = 0; }
+ }
+ dk4dir_close(fne);
+ if (0 == any_file_found) {
+ /* ERROR: No such file */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 107, pattern);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Failed to open file name expander (already reported) */
+ exval = EXIT_FAILURE;
+ }
+
+
+#line 1265 "dk-sort.ctr"
+}
+#endif
+
+
+
+/** Process either the files specified on the command line
+ or standard input otherwise.
+*/
+static
+void
+dk_sort_process_files(void)
+{
+ const dkChar *fn; /* Current file to process */
+ int xargc; /* Number of command line arguments */
+ int i; /* Current file index */
+
+
+#line 1281 "dk-sort.ctr"
+ xargc = dk4app_get_argc(app);
+ if (0 < xargc) {
+ for (
+ i = 0;
+ ((i < xargc) && (0 != dk_sort_can_continue()) && (EXIT_SUCCESS == exval));
+ i++
+ )
+ {
+ fn = dk4app_get_argv(app, i);
+ if (NULL != fn) {
+#if DK4_ON_WINDOWS
+ if (0 != dk4path_must_expand(fn)) {
+ dk_sort_expand_one_file_name(fn);
+ } else {
+#endif
+ dk_sort_process_one_file_name(fn);
+#if DK4_ON_WINDOWS
+ }
+#endif
+ }
+ }
+ } else {
+ dk_sort_process_stdin();
+ }
+
+
+#line 1306 "dk-sort.ctr"
+}
+
+
+
+/** Write stored text lines to standard output.
+*/
+static
+void
+dk_sort_write_output(void)
+{
+ dk_sort_line_t *nptr;
+ const dkChar *prevtext;
+ int printthis;
+
+
+#line 1320 "dk-sort.ctr"
+ if ((0 != dk_sort_can_continue()) && (EXIT_SUCCESS == exval)) {
+ dk4sto_it_reset(lsti);
+ prevtext = NULL;
+ do {
+ if ((0 != dk_sort_can_continue()) && (EXIT_SUCCESS == exval)) {
+ nptr = (dk_sort_line_t *)dk4sto_it_next(lsti);
+ if (NULL != nptr) {
+ printthis = 1;
+ if (0 != merge) {
+ if (NULL != prevtext) {
+ if (0 == dk4str_cmp(prevtext, nptr->line)) {
+ printthis = 0;
+ }
+ }
+ prevtext = nptr->line;
+ }
+ if (0 != printthis) {
+ if (0 == dk4fputs(nptr->line, stdout, NULL)) {
+ exval = EXIT_FAILURE;
+ nptr = NULL;
+ }
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) {
+ exval = EXIT_FAILURE;
+ nptr = NULL;
+ }
+ }
+ }
+ } else {
+ nptr = NULL;
+ }
+ } while (NULL != nptr);
+ }
+
+
+#line 1353 "dk-sort.ctr"
+}
+
+
+
+/** Run after setting signal handlers.
+*/
+static
+void
+dk_sort_normal_run(void)
+{
+ dkChar buf[32]; /* Input encoding name */
+ dk4_er_t er; /* Error report */
+ dk_sort_line_t *nopt; /* Current node */
+ size_t myll = 1024; /* Line length */
+ size_t nskip = 0;
+ int options_error = 0; /* Flag: Error in options */
+ int res = 0; /* Operations result */
+
+
+#line 1371 "dk-sort.ctr"
+ /* Process command line options
+ */
+ if (0 != dk4app_opt_is_set_short(app, dkT('c'), NULL)) {
+ case_insensitive = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('b'), NULL)) {
+ handle_blanks = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('w'), NULL)) {
+ handle_blanks = 2;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('t'), NULL)) {
+ handle_file_type = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('s'), NULL)) {
+ if (0 != dk4app_opt_get_size_short(&nskip, app, dkT('s'), NULL)) {
+ skip_words = nskip;
+ }
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('n'), NULL)) {
+ handle_values = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('u'), NULL)) {
+ handle_values = 2;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('x'), NULL)) {
+ handle_values = 3;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('f'), NULL)) {
+ if ((2 != handle_values) && (3 != handle_values)) {
+ handle_values = 4;
+ } else {
+ dk4app_log_1(app, dk_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, 11);
+ options_error = 1;
+ }
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('v'), NULL)) {
+ value_first = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('m'), NULL)) {
+ merge = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('r'), NULL)) {
+ reversed = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('e'), NULL)) {
+ suppress_empty = 1;
+ }
+ if (0 < dk4app_get_argc(app)) {
+ input_encoding = dk4app_get_file_in_encoding(app);
+ } else {
+ input_encoding = dk4app_get_stdin_encoding(app);
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('i'), NULL)) {
+ res = dk4app_opt_get_string_short(
+ buf, DK4_SIZEOF(buf,dkChar), app, dkT('i'), NULL
+ );
+ if (0 != res) {
+ res = dk4enc_find(&input_encoding, NULL, buf, NULL);
+ if (0 == res) {
+ dk4app_log_3(app,dk_sort_msg,dk_sort_sz_msg,DK4_LL_ERROR,12,13,buf);
+ options_error = 1;
+ }
+ }
+ }
+ res = 0;
+ if (0 != dk4app_opt_is_set_short(app, dkT('l'), NULL)) {
+ res = dk4app_opt_get_size_short(&myll, app, dkT('l'), NULL);
+ }
+ if (0 == res) {
+ if (0 == dk4app_opt_is_set_short(app, dkT('R'), NULL)) {
+ res = dk4app_pref_get_size(&myll, app, dk_sort_kwnl[6], 0);
+ }
+ }
+ if ((0 != res) && (DK4_SIZEOF(input_line_buffer,dkChar) < myll)) {
+ allocated_buffer = dk4mem_new_app(dkChar,myll,app);
+ if (NULL != allocated_buffer) {
+ ibptr = allocated_buffer;
+ ibsz = myll;
+ } else {
+ /* ERROR: Memory allocation failed, already reported */
+ options_error = 1;
+ }
+ }
+
+ /* Processing part.
+ */
+ if (0 == options_error) {
+ dk4error_init(&er);
+ lsto = dk4sto_open(&er);
+ if (NULL != lsto) {
+ dk4sto_set_comp(lsto, dk_sort_compare_nodes, 0);
+ lsti = dk4sto_it_open(lsto, &er);
+ if (NULL != lsti) {
+ exval = EXIT_SUCCESS;
+ dk_sort_process_files();
+ dk_sort_write_output();
+ dk4sto_it_reset(lsti);
+ do {
+ nopt = (dk_sort_line_t *)dk4sto_it_next(lsti);
+ if (NULL != nopt) {
+ dk_sort_delete_node(nopt);
+ }
+ } while (NULL != nopt);
+ dk4sto_it_close(lsti);
+ } else {
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ }
+ dk4sto_close(lsto);
+ } else {
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ }
+ }
+
+ /* Cleanup: release dynamically allocated memory for input line buffer.
+ */
+ if (NULL != allocated_buffer) {
+ dk4mem_free(allocated_buffer); allocated_buffer = NULL; ibsz = 1024;
+ }
+
+
+#line 1491 "dk-sort.ctr"
+}
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+dk_sort_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ struct sigaction opipe;
+#endif
+ struct sigaction oint;
+#ifdef SIGPIPE
+ struct sigaction npipe;
+#endif
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+ int success = 0;
+
+
+#line 1514 "dk-sort.ctr"
+#ifdef SIGPIPE
+ /* Set up signal handling for SIGPIPE.
+ */
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ dk4app_log_1(app, dk_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+#endif
+
+ /* Set up signal handling for SIGINT.
+ */
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, dk_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, dk_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ dk_sort_normal_run();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, dk_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+#ifdef SIGPIPE
+ /* Restore signal handling for SIGPIPE.
+ */
+ restore_old_pipe:
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+#endif
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+
+
+#line 1615 "dk-sort.ctr"
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+dk_sort_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+
+#line 1630 "dk-sort.ctr"
+#ifdef SIGPIPE
+ oldpipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ dk_sort_normal_run();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+#ifdef SIGPIPE
+ sigset(SIGPIPE, oldpipe);
+#endif
+
+
+#line 1642 "dk-sort.ctr"
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+dk_sort_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+
+#line 1657 "dk-sort.ctr"
+#ifdef SIGPIPE
+ oldpipe = signal(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ dk_sort_normal_run();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+#ifdef SIGPIPE
+ signal(SIGPIPE, oldpipe);
+#endif
+
+
+#line 1669 "dk-sort.ctr"
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+dk_sort_run_with_signal_handlers(void)
+{
+ dk_sort_normal_run();
+}
+#endif
+#endif
+#endif
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+
+
+#line 1697 "dk-sort.ctr"
+
+
+#line 1698 "dk-sort.ctr"
+ dk4fput_initialize_stdout();
+ dk4fput_initialize_stderr();
+ app = dk4app_open_cmd(
+ argc, argv, dk_sort_options, dk_sort_sz_options,
+ dk_sort_kwnl[0], DKT_VERSION_DK,
+ dk_sort_kwnl[1], dk_sort_help_text, dk_sort_license_text
+ );
+ if (NULL != app) {
+ dk_sort_sz_msg = dk4app_string_table_size(dk_sort_kw_def);
+ dk_sort_msg = dk4app_string_table(app, dk_sort_kwnl[2], dk_sort_kw_def);
+ if (0 != dk4app_can_run_normally(app)) {
+
+
+#line 1710 "dk-sort.ctr"
+ dk_sort_run_with_signal_handlers();
+ } else {
+
+
+#line 1713 "dk-sort.ctr"
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ dk4app_close(app);
+ } else {
+ }
+ fflush(stdout);
+ fflush(stderr);
+ dk4fput_cleanup_stderr();
+ dk4fput_cleanup_stdout();
+
+
+#line 1725 "dk-sort.ctr"
+
+
+#line 1726 "dk-sort.ctr"
+ return exval;
+}
+
diff --git a/support/dktools/dk-sort.ctr b/support/dktools/dk-sort.ctr
new file mode 100644
index 0000000000..68c89a40e9
--- /dev/null
+++ b/support/dktools/dk-sort.ctr
@@ -0,0 +1,1728 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4vers.h"
+#include "dk4app.h"
+#include "dk4aopt.h"
+#include "dk4mem.h"
+#include "dk4mema.h"
+#include "dk4fput.h"
+#include "dk4mpl.h"
+#include "dk4maiddbl.h"
+#if 0
+#include "dk4maidhmu.h"
+#include "dk4maiddmu.h"
+#include "dk4maiddmi.h"
+#endif
+#include "dk4maidddu.h"
+#include "dk4maidhdu.h"
+#include "dk4maidddi.h"
+#include "dk4maodd.h"
+#include "dk4enc.h"
+#include "dk4strd.h"
+#include "dk4strda.h"
+#include "dk4tspdk.h"
+#include "dk4fopda.h"
+#include "dk4pathd.h"
+#include "dk4filed.h"
+
+
+
+$!trace-include
+
+
+
+/** Structure to store one line, optionally with evaluation result.
+*/
+typedef struct {
+ dkChar *line; /**< Text line. */
+ dkChar *fts; /**< File type suffix. */
+ union {
+ dk4_um_t u; /**< Unsigned number at start of line. */
+ dk4_im_t i; /**< Signed number at start of line. */
+ double d; /**< Floating point number at start of line. */
+ } value; /**< Value at start of line. */
+ char h; /**< Flag: Have value. */
+} dk_sort_line_t;
+
+
+/** Default help text, shown if help file is not found.
+*/
+static const dkChar * const dk_sort_help_text[] = {
+$!text macro=dkT
+
+Sort text line by line
+
+dk-sort [<options>] [<file(s)>]
+
+Options:
+-i <encoding> --input-encoding=<encoding> Expected input encoding.
+-c --case-insensitive Case-insensitive comparisons.
+-b --ignore-leading-blanks Ignore leading whitespaces.
+-w --normalize Normalize text lines.
+-e --suppress-empty-lines Suppress output for empty lines.
+-t --file-type Sort by file type.
+-s <size> --skip-words=<size> Number of words to skip.
+-n --number Leading signed integer values.
+-u --unsigned Leading unsigned integer values.
+-x --hex Leading hexadecimal numbers.
+-f --float Leading floating point numbers.
+-v --value-lines-first Lines containing numbers first.
+-m --merge-equal-lines Merge equal lines.
+-r --reverse Reverse output order.
+-l <size> --line-size=<size> Line buffer sizes.
+-R --reset Ignore preferences values.
+
+--help Show this short help text.
+--manual *** SHOW FULL MANUAL. ***
+--version Show version information.
+--license Show license information.
+
+http://dktools.sourceforge.net
+
+$!end
+};
+
+
+
+/** License text.
+*/
+static const dkChar * const dk_sort_license_text[] = {
+$!text macro=dkT,preprocessor
+This software uses code from the following projects, either directly or as
+a library:
+
+dktools Dirk Krause's tools and libraries.
+ See http://dktools.sourceforge.net/ for more information.
+#if DK4_HAVE_ZLIB_H
+
+zlib Data compression library.
+ See http://www.zlib.net/ for more information.
+#endif
+#if DK4_HAVE_BZLIB_H
+
+bzip2 Data compression program and library.
+ See http://www.bzip.org/ for more information.
+#endif
+
+All the licenses below apply to the program.
+Licenses for used libraries are shown as found on my Scientific Linux 6.x
+computer in the /usr/share/doc directory on 2015-04-01. Check the project
+homepages of the used libraries for additional information and/or updated
+license terms.
+
+
+DK tools and libraries license
+==============================
+Copyright (c) 2015-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#if DK4_HAVE_ZLIB_H
+
+
+Zlib license
+============
+(C) 1995-2004 Jean-loup Gailly and Mark Adler
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+
+Jean-loup Gailly Mark Adler
+jloup@gzip.org madler@alumni.caltech.edu
+#endif
+#if DK4_HAVE_BZLIB_H
+
+
+Bzip2 and libbzip2 library license
+==================================
+This program, "bzip2", the associated library "libbzip2", and all
+documentation, are copyright (C) 1996-2007 Julian R Seward. All
+rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+3. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Julian Seward, jseward@bzip.org
+bzip2/libbzip2 version 1.0.5 of 10 December 2007
+#endif
+
+$!end
+};
+
+
+
+/** Command line options.
+*/
+static const dk4_option_specification_t dk_sort_options[] = {
+ { dkT('R'), dkT("reset"), DK4_OPT_ARG_NONE },
+ { dkT('i'), dkT("input-encoding"), DK4_OPT_ARG_STRING },
+ { dkT('c'), dkT("case-insensitive"), DK4_OPT_ARG_NONE },
+ { dkT('b'), dkT("ignore-leading-blanks"), DK4_OPT_ARG_NONE },
+ { dkT('w'), dkT("normalize"), DK4_OPT_ARG_NONE },
+ { dkT('t'), dkT("file-type"), DK4_OPT_ARG_NONE },
+ { dkT('s'), dkT("skip-words"), DK4_OPT_ARG_SIZE },
+ { dkT('n'), dkT("number"), DK4_OPT_ARG_NONE },
+ { dkT('u'), dkT("unsigned"), DK4_OPT_ARG_NONE },
+ { dkT('x'), dkT("hex"), DK4_OPT_ARG_NONE },
+ { dkT('f'), dkT("float"), DK4_OPT_ARG_NONE },
+ { dkT('v'), dkT("value-lines-first"), DK4_OPT_ARG_NONE },
+ { dkT('m'), dkT("merge-equal-lines"), DK4_OPT_ARG_NONE },
+ { dkT('r'), dkT("reverse"), DK4_OPT_ARG_NONE },
+ { dkT('l'), dkT("line-size"), DK4_OPT_ARG_SIZE },
+ { dkT('e'), dkT("suppress-empty-lines"), DK4_OPT_ARG_NONE }
+};
+
+
+
+/** Number of elements in the dk_sort_options array.
+*/
+static const size_t dk_sort_sz_options =
+sizeof(dk_sort_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Constant text strings used by the module, not localized.
+*/
+static const dkChar * const dk_sort_kwnl[] = {
+$!string-table macro=dkT
+#
+# 0 Program group name
+#
+dktools
+#
+# 1 Help text file name
+#
+dk-sort.txt
+#
+# 2 String table file name
+#
+dk-sort.str
+#
+# 3 File name when processing standard input.
+#
+stdin
+#
+# 4 File open mode to read a file
+#
+rb
+#
+# 5 Backslash for file name expansion
+#
+\\
+#
+# 6 Preference name for line size
+#
+line.size
+$!end
+};
+
+
+
+/** Text strings used by program, localized versions used if found.
+*/
+static const dkChar * const dk_sort_kw_def[] = {
+$!string-table macro=dkT
+#
+# 0 Error message: Failed to set up signal handlers!
+#
+Failed to set up signal handlers!
+#
+# 1 Error message: Failed to restore previous signal handlers!
+#
+Failed to restore previous signal handlers!
+#
+# 2 3 4 Error messages for encoding/decoding/processing errors
+#
+Encoding error!
+Decoding error!
+Processing error!
+#
+# 5 6 7 8 9 10 Error messages with detailed position
+#
+Encoding error!\n\tByte:
+Decoding error!\n\tByte:
+Processing error!\n\tByte:
+,\n\tCharacter:
+,\n\tPosition in line:
+.
+#
+# 11 Options -u, -x, -f mutually exclusive!
+#
+Options -u, -x, and -f are mutually exclusive!
+#
+# 12 13 Error: Illegal input encoding!
+#
+Illegal input encoding: "
+"!
+#
+# 14 Error: Failed to initialize text stream processing!
+#
+Failed to initialize text stream processing!
+$!end
+};
+
+
+
+/** Default buffer to use if sizes up to 1024 are specified.
+*/
+static dkChar input_line_buffer[1024];
+
+
+
+/** Input buffer really to use.
+*/
+static dkChar *ibptr = input_line_buffer;
+
+
+
+/** Allocated input buffer address for line sizes larger than 1024.
+*/
+static dkChar *allocated_buffer = NULL;
+
+
+
+/** Localized message texts.
+*/
+static const dkChar * const *dk_sort_msg = dk_sort_kw_def;
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Line storage.
+*/
+static dk4_sto_t *lsto = NULL;
+
+
+
+/** Iterator to traverse line storage.
+*/
+static dk4_sto_it_t *lsti = NULL;
+
+
+
+/** Number of strings in dk_sort_msg array.
+*/
+static size_t dk_sort_sz_msg =
+sizeof(dk_sort_kw_def)/sizeof(DK4_PCDKCHAR) - 1;
+
+
+/** Size of ibptr buffer.
+*/
+static size_t ibsz = DK4_SIZEOF(input_line_buffer,dkChar);
+
+
+
+/** Number of words to skip when processing file names.
+*/
+static size_t skip_words = 0;
+
+
+
+/** Flag: Case-insensitive comparison.
+*/
+static int case_insensitive = 0;
+
+
+
+/** How to handle blanks:
+ 0 leave as is,
+ 1 remove leading and trailing blanks,
+ 2 normalize lines.
+*/
+static int handle_blanks = 0;
+
+
+
+/** How to handle leading values:
+ 0 do not use numeric values,
+ 1 use signed integers
+ 2 use unsigned integers
+ 3 use unsigned integers, specified in hexadecimal notation
+ 4 use floating point numbers.
+*/
+static int handle_values = 0;
+
+
+
+/** Flag: Sort files type file type suffix.
+*/
+static int handle_file_type = 0;
+
+
+
+/** Flag: Show lines containing values before lines not containing
+ a value. Default is to show lines without a value first.
+*/
+static int value_first = 0;
+
+
+
+/** Flag: Merge equal lines.
+*/
+static int merge = 0;
+
+
+
+/** Flag: Reverse search order.
+*/
+static int reversed = 0;
+
+
+
+/** Flag: Suppress empty lines.
+*/
+static int suppress_empty = 0;
+
+
+/** Expected input encoding.
+*/
+static int input_encoding = DK4_FILE_ENCODING_ASCII;
+
+
+
+/** Flag: Already reported decoding errors.
+*/
+static int dk_sort_had_decoding_errors = 0;
+
+
+
+/** Flag: Already reported encoding errors.
+*/
+static int dk_sort_had_encoding_errors = 0;
+
+
+
+/** Flag: Already reported processing errors.
+*/
+static int dk_sort_had_proc_errors = 0;
+
+
+
+/** Exit status code returned by the main function.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+/** Pass a volatile pointer to an atomic integer.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ptr Address of atomic integer variable.
+ @return The unmodified pointer.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+/** Check whether we can continue or if a signal was received.
+ @param check_pipe Flag: Check for occured SIGPIPE signal too.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(int check_pipe)
+{
+ int back = 1;
+#ifdef SIGPIPE
+ if (0 != check_pipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_int )) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+/** Check whether we can continue.
+ @return 1 for yes, 0 for no.
+*/
+static
+int
+dk_sort_can_continue(void)
+{
+ int back = 1;
+ if (0 == sig_can_continue(1)) {
+ back = 0;
+ }
+ return back;
+}
+
+
+
+/** Delete a storage node.
+ @param ptr Node to delete.
+*/
+static
+void
+dk_sort_delete_node(dk_sort_line_t *ptr)
+{
+ $? "+ dk_sort_delete_node"
+ if (NULL != ptr) {
+ dk4mem_release(ptr->line);
+ dk4mem_free(ptr);
+ }
+ $? "- dk_sort_delete_node"
+}
+
+
+
+/** Create storage node for a text line.
+ @param line Text line to store.
+ @return Pointer to new node on success, NULL on error.
+*/
+static
+dk_sort_line_t *
+dk_sort_new_node(dkChar *line)
+{
+ dk_sort_line_t *back = NULL;
+ dkChar *lines = NULL; /* Start of line */
+ const dkChar *endptr = NULL; /* First text after value */
+ double d; /* Evaluation double */
+ dk4_um_t u; /* Evaluation unsigned */
+ dk4_im_t i; /* Evaluation integer */
+ $? "+ dk_sort_new_node"
+ /* Normalize or remove leading and trailing whitespace if required.
+ */
+ if (NULL != line) {
+ dk4str_delnl(line);
+ if (0 < handle_blanks) {
+ lines = dk4str_start(line, NULL);
+ if (NULL != lines) {
+ line = lines;
+ switch (handle_blanks) {
+ case 1: {
+ dk4str_rtwh(line, NULL);
+ } break;
+ case 2: {
+ dk4str_normalize(line, NULL);
+ } break;
+ }
+ } else {
+ *line = dkT('\0');
+ }
+ }
+ }
+ if ((0 != suppress_empty) && (NULL != line)) {
+ lines = dk4str_start(line, NULL);
+ if (NULL == lines) {
+ line = NULL;
+ }
+ }
+
+ /* Create node.
+ */
+ if (NULL != line) {
+ back = dk4mem_new_app(dk_sort_line_t,1,app);
+ if (NULL != back) {
+ back->fts = NULL;
+ back->h = 0x00;
+ back->line = dk4str_dup_app(line, app);
+ if (NULL != back->line) {
+ if (0 != handle_file_type) {
+ back->fts = dk4path_get_suffix(back->line, NULL);
+ }
+ } else {
+ dk_sort_delete_node(back);
+ back = NULL;
+ exval = EXIT_FAILURE;
+ /* ERROR: Memory, already reported */
+ }
+ } else {
+ exval = EXIT_FAILURE;
+ /* ERROR: Memory, already reported */
+ }
+ }
+
+ /* Evaluate node if necessary.
+ */
+ if (NULL != back) {
+ switch (handle_values) {
+ case 4: {
+ d = 0.0;
+ if (0 != dk4ma_input_dk_double(&d, line, &endptr, 2, NULL)) {
+ (back->value).d = d;
+ back->h = 0x01;
+ }
+ } break;
+ case 3: {
+ u = (dk4_um_t)0UL;
+ if (0 != dk4ma_input_dk_hex_dk4_um_t(&u, line, &endptr, 2, NULL)) {
+ (back->value).u = u;
+ back->h = 0x01;
+ }
+ } break;
+ case 2: {
+ u = (dk4_um_t)0UL;
+ if (0 != dk4ma_input_dk_dec_dk4_um_t(&u, line, &endptr, 2, NULL)) {
+ (back->value).u = u;
+ back->h = 0x01;
+ }
+ } break;
+ case 1: {
+ i = (dk4_im_t)0L;
+ if (0 != dk4ma_input_dk_dec_dk4_im_t(&i, line, &endptr, 2, NULL)) {
+ (back->value).i = i;
+ back->h = 0x01;
+ }
+ } break;
+ }
+ }
+ $? "- dk_sort_new_node PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+static
+int
+dk_sort_is_dot_file(const dkChar *fn)
+{
+ const dkChar *fns = NULL;
+ const dkChar *ptr = NULL;
+ int back = 0;
+ $? "+ dk_sort_is_dot_file \"%s\"", fn
+ ptr = fn;
+ while (dkT('\0') != *ptr) {
+#if DK4_HAVE_BACKSLASH_AS_SEP
+ if (dkT('\\') == *ptr) { fns = ptr; }
+#else
+ if (dkT('/') == *ptr) { fns = ptr; }
+#endif
+ ptr++;
+ }
+ if (NULL == fns) { fns = fn; }
+ else { fns++; }
+ $? ". fns = \"%s\"", fns
+ if (dkT('.') == *fns) {
+ back = 1;
+ }
+#if DK4_ON_WINDOWS
+ if (dkT('_') == *fns) {
+ back = 1;
+ }
+#endif
+ $? "- dk_sort_is_dot_file %d", back
+ return back;
+}
+
+
+
+/** Compare two storage nodes.
+ @param l Left node.
+ @param r Right node.
+ @param cr Comparison criteria, ignored here.
+ @return Comparison result.
+*/
+static
+int
+dk_sort_compare_nodes(const void *l, const void *r, int cr)
+{
+ int back = 0;
+ dk_sort_line_t *pl;
+ dk_sort_line_t *pr;
+ const dkChar *fnleft;
+ const dkChar *fnright;
+ $? "+ dk_sort_compare_nodes"
+ if (NULL != l) {
+ if (NULL != r) {
+ pl = (dk_sort_line_t *)l;
+ pr = (dk_sort_line_t *)r;
+
+ /* Check file type suffix if required.
+ */
+ if (0 != handle_file_type) {
+ fnleft = dk4str_skip(pl->line, skip_words);
+ fnright = dk4str_skip(pr->line, skip_words);
+ if (NULL != fnleft) { $? ". fnleft = \"%s\"", fnleft
+ if (NULL != fnright) { $? ". fnright = \"%s\"", fnright
+ if (0 != dk4file_is_directory(fnleft, NULL)) {
+ if (0 == dk4file_is_directory(fnright, NULL)) {
+ back = -1;
+ }
+ } else {
+ if (0 != dk4file_is_directory(fnright, NULL)) {
+ back = 1;
+ }
+ }
+ if (0 == back) {
+ if (0 != dk_sort_is_dot_file(fnleft)) {
+ if (0 == dk_sort_is_dot_file(fnright)) {
+ back = -1;
+ }
+ } else {
+ if (0 != dk_sort_is_dot_file(fnright)) {
+ back = 1;
+ }
+ }
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != fnright) {
+ back = -1;
+ }
+ }
+ if (0 == back) {
+ if (NULL != pl->fts) {
+ if (NULL != pr->fts) {
+ back = dk4str_pathcmp(pl->fts, pr->fts);
+#if DK4_HAVE_CASE_INSENSITIVE_PATHNAMES
+ if (0 == back) {
+ back = dk4str_cmp(pl->fts, pr->fts);
+ }
+#endif
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != pr->fts) {
+ back = -1;
+ }
+ }
+ }
+ }
+
+ /* Check evaluation if required.
+ */
+ if (0 == back) {
+ if (0 != handle_values) {
+ if (0x00 != pl->h) {
+ if (0x00 != pr->h) { /* both values */
+ switch (handle_values) {
+ case 4: {
+ if ((pl->value).d < (pr->value).d) {
+ back = -1;
+ } else {
+ if ((pl->value).d > (pr->value).d) {
+ back = 1;
+ }
+ }
+ } break;
+ case 2: case 3: {
+ if ((pl->value).u < (pr->value).u) {
+ back = -1;
+ } else {
+ if ((pl->value).u > (pr->value).u) {
+ back = 1;
+ }
+ }
+ } break;
+ case 1: {
+ if ((pl->value).i < (pr->value).i) {
+ back = -1;
+ } else {
+ if ((pl->value).i > (pr->value).i) {
+ back = 1;
+ }
+ }
+ } break;
+ }
+ } else { /* only left value */
+ back = ((0 != value_first) ? -1 : 1);
+ }
+ } else {
+ if (0x00 != pr->h) { /* only right value */
+ back = ((0 != value_first) ? 1 : -1);
+ }
+ }
+ }
+ }
+
+ /* String comparison
+ */
+ if (0 == back) {
+ if (0 != case_insensitive) {
+ back = dk4str_casecmp(pl->line, pr->line);
+ if (0 == back) {
+ back = dk4str_cmp(pl->line, pr->line);
+ }
+ } else {
+ back = dk4str_cmp(pl->line, pr->line);
+ }
+ }
+
+ /* Reverse order if necessary.
+ */
+ if (0 != reversed) { back = -1 * back; }
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != r) {
+ back = -1;
+ }
+ } $? "- dk_sort_compare_nodes %d", back
+ return back;
+}
+
+
+
+static
+int
+dk_sort_line_handler(
+ void *obj,
+ dkChar *line,
+ dk4_um_t lineno,
+ dk4_er_t *erp
+)
+{
+ dk_sort_line_t *nptr;
+ int back = DK4_TSP_RES_OK;
+ $? "+ dk_sort_line_handler"
+ nptr = dk_sort_new_node(line);
+ if (NULL != nptr) {
+ if (0 == dk4sto_add(lsto, nptr, NULL)) {
+ dk_sort_delete_node(nptr);
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ back = DK4_TSP_RES_FATAL;
+ exval = EXIT_FAILURE;
+ }
+ } $? "- dk_sort_line_handler %d", back
+ return back;
+}
+
+
+
+/** Report an error with position.
+ @param i1 Index of first message part in array.
+ @param i2 Index of alternative first message part.
+ @param bno Current byte number.
+ @param lno Current line number.
+ @param cno Current character number.
+ @param cil Current character number within line.
+ @param fn File name processed.
+*/
+static
+void
+dk_sort_report_with_position(
+ size_t i1,
+ size_t i2,
+ dk4_um_t bno,
+ dk4_um_t lno,
+ dk4_um_t cno,
+ dk4_um_t cil,
+ const dkChar *fn
+)
+{
+ dkChar b1[8*(1+sizeof(dk4_um_t))+16];
+ dkChar b2[8*(1+sizeof(dk4_um_t))+16];
+ dkChar b3[8*(1+sizeof(dk4_um_t))+16];
+ const dkChar *oldlogname = NULL;
+ dk4_um_t oldlogline = (dk4_um_t)0UL;
+ int allbuffersok = 0;
+
+ oldlogname = dk4app_get_log_source_file(app);
+ oldlogline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_file(app, fn);
+ dk4app_set_log_source_line(app, lno);
+ if (0 != dk4ma_write_decimal_unsigned(b3,DK4_SIZEOF(b3,dkChar),cil,0,NULL)) {
+ if (0 != dk4ma_write_decimal_unsigned(b2,DK4_SIZEOF(b2,dkChar),cno,0,NULL)) {
+ if (0 != dk4ma_write_decimal_unsigned(b1,DK4_SIZEOF(b1,dkChar),bno,0,NULL)) {
+ allbuffersok = 1;
+ }
+ }
+ }
+ if (0 != allbuffersok) {
+ dk4app_log_7(
+ app, dk_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, i1, 8, 9, 10, b1, b2, b3
+ );
+ } else {
+ dk4app_log_1(app, dk_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, i2);
+ }
+ dk4app_set_log_source_line(app, oldlogline);
+ dk4app_set_log_source_file(app, oldlogname);
+}
+
+
+
+/** Report errors from line processing.
+ @param er_en Error report for encoding/decoding errors.
+ @param en_pr Error report for processing errors.
+ @param fn File name for error message.
+*/
+static
+void
+dk_sort_report_errors(
+ dk4_er_t *er_en,
+ dk4_er_t *er_pr,
+ const dkChar *fn
+)
+{
+ $? "+ dk_sort_report_errors"
+ if (NULL != er_en) {
+ switch (er_en->ec) {
+ case DK4_E_DECODING_FAILED : {
+ switch (dk_sort_had_decoding_errors) {
+ case 0: case 1: case 2: {
+ dk_sort_report_with_position(
+ 6, 3,
+ er_en->dt.fpos.byteno, er_en->dt.fpos.lineno,
+ er_en->dt.fpos.charno, er_en->dt.fpos.charinline,
+ fn
+ );
+ } break;
+ }
+ if (3 > dk_sort_had_decoding_errors) { dk_sort_had_decoding_errors++; }
+ } break;
+ case DK4_E_ENCODING_FAILED : {
+ switch (dk_sort_had_encoding_errors) {
+ case 0: case 1: case 2: {
+ dk_sort_report_with_position(
+ 5, 2,
+ er_en->dt.fpos.byteno, er_en->dt.fpos.lineno,
+ er_en->dt.fpos.charno, er_en->dt.fpos.charinline,
+ fn
+ );
+ } break;
+ }
+ if (3 > dk_sort_had_encoding_errors) { dk_sort_had_encoding_errors++; }
+ } break;
+ }
+ }
+ if (NULL != er_pr) {
+ if (DK4_E_NONE != er_pr->ec) {
+ switch (dk_sort_had_proc_errors) {
+ case 0: case 1: case 2: {
+ dk_sort_report_with_position(
+ 7, 4,
+ er_pr->dt.fpos.byteno, er_pr->dt.fpos.lineno,
+ er_pr->dt.fpos.charno, er_pr->dt.fpos.charinline,
+ fn
+ );
+ } break;
+ }
+ if (3 > dk_sort_had_proc_errors) { dk_sort_had_proc_errors++; }
+ }
+ }
+ $? "- dk_sort_report_errors"
+}
+
+
+
+/** Process one input file opened in binary mode.
+ @param fipo File to process.
+ @param filename File name.
+*/
+static
+void
+dk_sort_process_file(FILE *fipo, const dkChar *filename)
+{
+ dk4_tspdk_t tsp;
+ dk4_er_t er_en;
+ dk4_er_t er_pr;
+ dk4_er_t er;
+ int res;
+ int cc;
+ int c;
+ unsigned char ub;
+ $? "+ dk_sort_process_file"
+ dk4error_init(&er_en);
+ dk4error_init(&er_pr);
+ dk4error_init(&er);
+ res = dk4tspdk_setup_line(
+ &tsp, NULL,
+ dk_sort_line_handler,
+ ibptr, ibsz,
+ dk4app_get_encoding(app), input_encoding,
+ &er
+ );
+ if (0 != res) {
+ cc = 1;
+ do {
+ if (dk_sort_can_continue()) {
+ c = fgetc(fipo);
+ if (EOF != c) {
+ ub = (unsigned char)c;
+ switch (dk4tspdk_add_one_byte(&tsp, ub)) {
+ case DK4_TSP_RES_FATAL : {
+ cc = -1;
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tsp);
+ dk_sort_report_errors(&er_en, &er_pr, filename);
+ } break;
+ case DK4_TSP_RES_ERROR : {
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tsp);
+ dk_sort_report_errors(&er_en, &er_pr, filename);
+ } break;
+ }
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = -1;
+ }
+ } while (1 == cc);
+ if (0 == cc) {
+ switch (dk4tspdk_finish(&tsp)) {
+ case DK4_TSP_RES_FATAL : {
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tsp);
+ dk_sort_report_errors(&er_en, &er_pr, filename);
+ } break;
+ case DK4_TSP_RES_ERROR : {
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tsp);
+ dk_sort_report_errors(&er_en, &er_pr, filename);
+ } break;
+ }
+ }
+ } else {
+ /* ERROR: Failed to initialize text stream processor */
+ dk4app_log_1(app, dk_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, 14);
+ exval = EXIT_FAILURE;
+ }
+ $? "- dk_sort_process_file"
+}
+
+
+
+/** Process standard input.
+*/
+static
+void
+dk_sort_process_stdin(void)
+{
+#if DK4_ON_WINDOWS
+ int oldmode;
+#endif
+ $? "+ dk_sort_process_stdin"
+#if DK4_ON_WINDOWS
+ oldmode = _setmode(_fileno(stdin), _O_BINARY);
+#endif
+ dk_sort_process_file(stdin, dk_sort_kwnl[3]);
+#if DK4_ON_WINDOWS
+ _setmode(_fileno(stdin), oldmode);
+#endif
+ $? "- dk_sort_process_stdin"
+}
+
+
+
+static
+void
+dk_sort_process_one_file_name(const dkChar *fn)
+{
+ FILE *fipo;
+ int tests = DK4_FOPEN_SC_IS_REGULAR;
+ $? "+ dk_sort_process_one_file_name"
+ fipo = dk4fopen_app(fn, dk_sort_kwnl[4], tests, app);
+ if (NULL != fipo) {
+ dk_sort_process_file(fipo, fn);
+ fclose(fipo);
+ } else {
+ /* ERROR: Failed to open file, already reported */
+ exval = EXIT_FAILURE;
+ }
+ $? "- dk_sort_process_one_file_name"
+}
+
+
+
+#if DK4_ON_WINDOWS
+static
+void
+dk_sort_expand_one_file_name(const dkChar *pattern)
+{
+ dkChar buf[DK4_MAX_PATH];
+ dk4_dir_t *fne;
+ const dkChar *shf; /* Short file name */
+ const dkChar *pth; /* Path */
+ int any_file_found = 0; /* Flag: Any file found */
+ int can_continue;
+ $? "+ dk_sort_expand_one_file_name"
+ fne = dk4app_fne_open(pattern, app);
+ if (NULL != fne) {
+ can_continue = 1;
+ while ((0 != can_continue) && (NULL != (shf = dk4dir_next_file(fne)))) {
+ any_file_found = 1;
+ pth = dk4dir_get_path(fne);
+ if (NULL != pth) {
+ if (0 != dk4str_cpy_s(buf, DK4_SIZEOF(buf,dkChar), pth, NULL)) {
+ if(0 != dk4str_cat_s(buf,DK4_SIZEOF(buf,dkChar),dk_sort_kwnl[5],NULL))
+ {
+ if(0 != dk4str_cat_s(buf, DK4_SIZEOF(buf,dkChar), shf, NULL)) {
+ dk_sort_process_one_file_name(buf);
+ } else {
+ exval = EXIT_FAILURE;
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 105, pattern);
+ }
+ }
+ else
+ {
+ exval = EXIT_FAILURE;
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 105, pattern);
+ }
+ } else {
+ exval = EXIT_FAILURE;
+ /* ERROR: Path too long! */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 105, pattern);
+ }
+ } else {
+ dk_sort_process_one_file_name(shf);
+ }
+ can_continue = dk_sort_can_continue();
+ if (EXIT_FAILURE == exval) { can_continue = 0; }
+ }
+ dk4dir_close(fne);
+ if (0 == any_file_found) {
+ /* ERROR: No such file */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 107, pattern);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Failed to open file name expander (already reported) */
+ exval = EXIT_FAILURE;
+ }
+ $? "- dk_sort_expand_one_file_name"
+}
+#endif
+
+
+
+/** Process either the files specified on the command line
+ or standard input otherwise.
+*/
+static
+void
+dk_sort_process_files(void)
+{
+ const dkChar *fn; /* Current file to process */
+ int xargc; /* Number of command line arguments */
+ int i; /* Current file index */
+ $? "+ dk_sort_process_files"
+ xargc = dk4app_get_argc(app);
+ if (0 < xargc) {
+ for (
+ i = 0;
+ ((i < xargc) && (0 != dk_sort_can_continue()) && (EXIT_SUCCESS == exval));
+ i++
+ )
+ {
+ fn = dk4app_get_argv(app, i);
+ if (NULL != fn) {
+#if DK4_ON_WINDOWS
+ if (0 != dk4path_must_expand(fn)) {
+ dk_sort_expand_one_file_name(fn);
+ } else {
+#endif
+ dk_sort_process_one_file_name(fn);
+#if DK4_ON_WINDOWS
+ }
+#endif
+ }
+ }
+ } else {
+ dk_sort_process_stdin();
+ }
+ $? "- dk_sort_process_files"
+}
+
+
+
+/** Write stored text lines to standard output.
+*/
+static
+void
+dk_sort_write_output(void)
+{
+ dk_sort_line_t *nptr;
+ const dkChar *prevtext;
+ int printthis;
+ $? "+ dk_sort_write_output"
+ if ((0 != dk_sort_can_continue()) && (EXIT_SUCCESS == exval)) {
+ dk4sto_it_reset(lsti);
+ prevtext = NULL;
+ do {
+ if ((0 != dk_sort_can_continue()) && (EXIT_SUCCESS == exval)) {
+ nptr = (dk_sort_line_t *)dk4sto_it_next(lsti);
+ if (NULL != nptr) {
+ printthis = 1;
+ if (0 != merge) {
+ if (NULL != prevtext) {
+ if (0 == dk4str_cmp(prevtext, nptr->line)) {
+ printthis = 0;
+ }
+ }
+ prevtext = nptr->line;
+ }
+ if (0 != printthis) {
+ if (0 == dk4fputs(nptr->line, stdout, NULL)) {
+ exval = EXIT_FAILURE;
+ nptr = NULL;
+ }
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) {
+ exval = EXIT_FAILURE;
+ nptr = NULL;
+ }
+ }
+ }
+ } else {
+ nptr = NULL;
+ }
+ } while (NULL != nptr);
+ }
+ $? "- dk_sort_write_output"
+}
+
+
+
+/** Run after setting signal handlers.
+*/
+static
+void
+dk_sort_normal_run(void)
+{
+ dkChar buf[32]; /* Input encoding name */
+ dk4_er_t er; /* Error report */
+ dk_sort_line_t *nopt; /* Current node */
+ size_t myll = 1024; /* Line length */
+ size_t nskip = 0;
+ int options_error = 0; /* Flag: Error in options */
+ int res = 0; /* Operations result */
+ $? "+ dk_sort_normal_run"
+ /* Process command line options
+ */
+ if (0 != dk4app_opt_is_set_short(app, dkT('c'), NULL)) {
+ case_insensitive = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('b'), NULL)) {
+ handle_blanks = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('w'), NULL)) {
+ handle_blanks = 2;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('t'), NULL)) {
+ handle_file_type = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('s'), NULL)) {
+ if (0 != dk4app_opt_get_size_short(&nskip, app, dkT('s'), NULL)) {
+ skip_words = nskip;
+ }
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('n'), NULL)) {
+ handle_values = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('u'), NULL)) {
+ handle_values = 2;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('x'), NULL)) {
+ handle_values = 3;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('f'), NULL)) {
+ if ((2 != handle_values) && (3 != handle_values)) {
+ handle_values = 4;
+ } else {
+ dk4app_log_1(app, dk_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, 11);
+ options_error = 1;
+ }
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('v'), NULL)) {
+ value_first = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('m'), NULL)) {
+ merge = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('r'), NULL)) {
+ reversed = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('e'), NULL)) {
+ suppress_empty = 1;
+ }
+ if (0 < dk4app_get_argc(app)) {
+ input_encoding = dk4app_get_file_in_encoding(app);
+ } else {
+ input_encoding = dk4app_get_stdin_encoding(app);
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('i'), NULL)) {
+ res = dk4app_opt_get_string_short(
+ buf, DK4_SIZEOF(buf,dkChar), app, dkT('i'), NULL
+ );
+ if (0 != res) {
+ res = dk4enc_find(&input_encoding, NULL, buf, NULL);
+ if (0 == res) {
+ dk4app_log_3(app,dk_sort_msg,dk_sort_sz_msg,DK4_LL_ERROR,12,13,buf);
+ options_error = 1;
+ }
+ }
+ }
+ res = 0;
+ if (0 != dk4app_opt_is_set_short(app, dkT('l'), NULL)) {
+ res = dk4app_opt_get_size_short(&myll, app, dkT('l'), NULL);
+ }
+ if (0 == res) {
+ if (0 == dk4app_opt_is_set_short(app, dkT('R'), NULL)) {
+ res = dk4app_pref_get_size(&myll, app, dk_sort_kwnl[6], 0);
+ }
+ }
+ if ((0 != res) && (DK4_SIZEOF(input_line_buffer,dkChar) < myll)) {
+ allocated_buffer = dk4mem_new_app(dkChar,myll,app);
+ if (NULL != allocated_buffer) {
+ ibptr = allocated_buffer;
+ ibsz = myll;
+ } else {
+ /* ERROR: Memory allocation failed, already reported */
+ options_error = 1;
+ }
+ }
+
+ /* Processing part.
+ */
+ if (0 == options_error) {
+ dk4error_init(&er);
+ lsto = dk4sto_open(&er);
+ if (NULL != lsto) {
+ dk4sto_set_comp(lsto, dk_sort_compare_nodes, 0);
+ lsti = dk4sto_it_open(lsto, &er);
+ if (NULL != lsti) {
+ exval = EXIT_SUCCESS;
+ dk_sort_process_files();
+ dk_sort_write_output();
+ dk4sto_it_reset(lsti);
+ do {
+ nopt = (dk_sort_line_t *)dk4sto_it_next(lsti);
+ if (NULL != nopt) {
+ dk_sort_delete_node(nopt);
+ }
+ } while (NULL != nopt);
+ dk4sto_it_close(lsti);
+ } else {
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ }
+ dk4sto_close(lsto);
+ } else {
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ }
+ }
+
+ /* Cleanup: release dynamically allocated memory for input line buffer.
+ */
+ if (NULL != allocated_buffer) {
+ dk4mem_free(allocated_buffer); allocated_buffer = NULL; ibsz = 1024;
+ }
+ $? "- dk_sort_normal_run"
+}
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+dk_sort_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ struct sigaction opipe;
+#endif
+ struct sigaction oint;
+#ifdef SIGPIPE
+ struct sigaction npipe;
+#endif
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+ int success = 0;
+ $? "+ dk_sort_run_with_signal_handlers (sigaction)"
+#ifdef SIGPIPE
+ /* Set up signal handling for SIGPIPE.
+ */
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ dk4app_log_1(app, dk_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+#endif
+
+ /* Set up signal handling for SIGINT.
+ */
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, dk_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, dk_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ dk_sort_normal_run();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, dk_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+#ifdef SIGPIPE
+ /* Restore signal handling for SIGPIPE.
+ */
+ restore_old_pipe:
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_sort_msg, dk_sort_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+#endif
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+ $? "- dk_sort_run_with_signal_handlers (sigaction)"
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+dk_sort_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+ $? "+ dk_sort_run_with_signal_handlers (sigset)"
+#ifdef SIGPIPE
+ oldpipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ dk_sort_normal_run();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+#ifdef SIGPIPE
+ sigset(SIGPIPE, oldpipe);
+#endif
+ $? "- dk_sort_run_with_signal_handlers (sigset)"
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+dk_sort_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+ $? "+ dk_sort_run_with_signal_handlers (signal)"
+#ifdef SIGPIPE
+ oldpipe = signal(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ dk_sort_normal_run();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+#ifdef SIGPIPE
+ signal(SIGPIPE, oldpipe);
+#endif
+ $? "- dk_sort_run_with_signal_handlers (signal)"
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+dk_sort_run_with_signal_handlers(void)
+{
+ dk_sort_normal_run();
+}
+#endif
+#endif
+#endif
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ $!trace-init dk-sort.deb
+ $? "+ main"
+ dk4fput_initialize_stdout();
+ dk4fput_initialize_stderr();
+ app = dk4app_open_cmd(
+ argc, argv, dk_sort_options, dk_sort_sz_options,
+ dk_sort_kwnl[0], DKT_VERSION_DK,
+ dk_sort_kwnl[1], dk_sort_help_text, dk_sort_license_text
+ );
+ if (NULL != app) {
+ dk_sort_sz_msg = dk4app_string_table_size(dk_sort_kw_def);
+ dk_sort_msg = dk4app_string_table(app, dk_sort_kwnl[2], dk_sort_kw_def);
+ if (0 != dk4app_can_run_normally(app)) {
+ $? ". normal processing"
+ dk_sort_run_with_signal_handlers();
+ } else {
+ $? ". help/version/license"
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ dk4app_close(app);
+ } else {
+ }
+ fflush(stdout);
+ fflush(stderr);
+ dk4fput_cleanup_stderr();
+ dk4fput_cleanup_stdout();
+ $? "- main %d", exval
+ $!trace-end
+ return exval;
+}
+
diff --git a/support/dktools/dk-sort.rc b/support/dktools/dk-sort.rc
new file mode 100644
index 0000000000..7ec023feff
--- /dev/null
+++ b/support/dktools/dk-sort.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "A sort clone, mainly intended for Windows\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "A sort clone, mainly intended for Windows\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "dk-sort\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/dk-sqlsplit.c b/support/dktools/dk-sqlsplit.c
new file mode 100644
index 0000000000..c24f0246c6
--- /dev/null
+++ b/support/dktools/dk-sqlsplit.c
@@ -0,0 +1,982 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk-sqlsplit.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @defgroup dkct_state_machine_find_line_end The find_line_end state machine. */
+/**@{*/
+
+#ifndef ST_BQ
+/** State: In back-tick quoted string */
+#line 22 "dk-sqlsplit.ctr"
+#define ST_BQ 0
+#else
+#line 22 "dk-sqlsplit.ctr"
+#error "Redefinition of ST_BQ"
+#endif
+
+#ifndef ST_BQ_BS
+/** State: In back-tick quoted string after backslash */
+#line 23 "dk-sqlsplit.ctr"
+#define ST_BQ_BS 1
+#else
+#line 23 "dk-sqlsplit.ctr"
+#error "Redefinition of ST_BQ_BS"
+#endif
+
+#ifndef ST_CLBR
+/** State: In normal state after closing bracket */
+#line 28 "dk-sqlsplit.ctr"
+#define ST_CLBR 2
+#else
+#line 28 "dk-sqlsplit.ctr"
+#error "Redefinition of ST_CLBR"
+#endif
+
+#ifndef ST_CLBRCO
+/** State: In normal state after closing bracket and comma */
+#line 29 "dk-sqlsplit.ctr"
+#define ST_CLBRCO 3
+#else
+#line 29 "dk-sqlsplit.ctr"
+#error "Redefinition of ST_CLBRCO"
+#endif
+
+#ifndef ST_CO
+/** State: In normal comment */
+#line 26 "dk-sqlsplit.ctr"
+#define ST_CO 4
+#else
+#line 26 "dk-sqlsplit.ctr"
+#error "Redefinition of ST_CO"
+#endif
+
+#ifndef ST_CO_AST
+/** State: In normal comment after asterisk */
+#line 27 "dk-sqlsplit.ctr"
+#define ST_CO_AST 5
+#else
+#line 27 "dk-sqlsplit.ctr"
+#error "Redefinition of ST_CO_AST"
+#endif
+
+#ifndef ST_DQ
+/** State: In double quotes string */
+#line 20 "dk-sqlsplit.ctr"
+#define ST_DQ 6
+#else
+#line 20 "dk-sqlsplit.ctr"
+#error "Redefinition of ST_DQ"
+#endif
+
+#ifndef ST_DQ_BS
+/** State: In double quotes string after back */
+#line 21 "dk-sqlsplit.ctr"
+#define ST_DQ_BS 7
+#else
+#line 21 "dk-sqlsplit.ctr"
+#error "Redefinition of ST_DQ_BS"
+#endif
+
+#ifndef ST_ERROR
+/** State: Undefined state */
+#line 30 "dk-sqlsplit.ctr"
+#define ST_ERROR 8
+#else
+#line 30 "dk-sqlsplit.ctr"
+#error "Redefinition of ST_ERROR"
+#endif
+
+#ifndef ST_SL
+/** State: Normal state after slash */
+#line 24 "dk-sqlsplit.ctr"
+#define ST_SL 9
+#else
+#line 24 "dk-sqlsplit.ctr"
+#error "Redefinition of ST_SL"
+#endif
+
+#ifndef ST_SL_CO
+/** State: In double slash comment */
+#line 25 "dk-sqlsplit.ctr"
+#define ST_SL_CO 10
+#else
+#line 25 "dk-sqlsplit.ctr"
+#error "Redefinition of ST_SL_CO"
+#endif
+
+#ifndef ST_SQ
+/** State: In single quotes string */
+#line 18 "dk-sqlsplit.ctr"
+#define ST_SQ 11
+#else
+#line 18 "dk-sqlsplit.ctr"
+#error "Redefinition of ST_SQ"
+#endif
+
+#ifndef ST_SQ_BS
+/** State: In single quotes string after backslash */
+#line 19 "dk-sqlsplit.ctr"
+#define ST_SQ_BS 12
+#else
+#line 19 "dk-sqlsplit.ctr"
+#error "Redefinition of ST_SQ_BS"
+#endif
+
+#ifndef ST_START
+/** State: Normal state */
+#line 16 "dk-sqlsplit.ctr"
+#define ST_START 13
+#else
+#line 16 "dk-sqlsplit.ctr"
+#error "Redefinition of ST_START"
+#endif
+
+#ifndef ST_START_BS
+/** State: Backslash found in normal state */
+#line 17 "dk-sqlsplit.ctr"
+#define ST_START_BS 14
+#else
+#line 17 "dk-sqlsplit.ctr"
+#error "Redefinition of ST_START_BS"
+#endif
+
+#ifndef I_ANY
+/** State machine input: Anything else */
+#line 43 "dk-sqlsplit.ctr"
+#define I_ANY 0
+#else
+#line 43 "dk-sqlsplit.ctr"
+#error "Redefinition of I_ANY"
+#endif
+
+#ifndef I_AST
+/** State machine input: Asterisk */
+#line 38 "dk-sqlsplit.ctr"
+#define I_AST 1
+#else
+#line 38 "dk-sqlsplit.ctr"
+#error "Redefinition of I_AST"
+#endif
+
+#ifndef I_BS
+/** State machine input: Backslash */
+#line 36 "dk-sqlsplit.ctr"
+#define I_BS 2
+#else
+#line 36 "dk-sqlsplit.ctr"
+#error "Redefinition of I_BS"
+#endif
+
+#ifndef I_BT
+/** State machine input: Backtick */
+#line 41 "dk-sqlsplit.ctr"
+#define I_BT 3
+#else
+#line 41 "dk-sqlsplit.ctr"
+#error "Redefinition of I_BT"
+#endif
+
+#ifndef I_CLBR
+/** State machine input: Closing bracket */
+#line 35 "dk-sqlsplit.ctr"
+#define I_CLBR 4
+#else
+#line 35 "dk-sqlsplit.ctr"
+#error "Redefinition of I_CLBR"
+#endif
+
+#ifndef I_COMMA
+/** State machine input: Comma */
+#line 42 "dk-sqlsplit.ctr"
+#define I_COMMA 5
+#else
+#line 42 "dk-sqlsplit.ctr"
+#error "Redefinition of I_COMMA"
+#endif
+
+#ifndef I_DQ
+/** State machine input: Double quote */
+#line 40 "dk-sqlsplit.ctr"
+#define I_DQ 6
+#else
+#line 40 "dk-sqlsplit.ctr"
+#error "Redefinition of I_DQ"
+#endif
+
+#ifndef I_NL
+/** State machine input: Newline */
+#line 33 "dk-sqlsplit.ctr"
+#define I_NL 7
+#else
+#line 33 "dk-sqlsplit.ctr"
+#error "Redefinition of I_NL"
+#endif
+
+#ifndef I_OPBR
+/** State machine input: Opening bracket */
+#line 34 "dk-sqlsplit.ctr"
+#define I_OPBR 8
+#else
+#line 34 "dk-sqlsplit.ctr"
+#error "Redefinition of I_OPBR"
+#endif
+
+#ifndef I_SL
+/** State machine input: Slash */
+#line 37 "dk-sqlsplit.ctr"
+#define I_SL 9
+#else
+#line 37 "dk-sqlsplit.ctr"
+#error "Redefinition of I_SL"
+#endif
+
+#ifndef I_SQ
+/** State machine input: Single quote */
+#line 39 "dk-sqlsplit.ctr"
+#define I_SQ 10
+#else
+#line 39 "dk-sqlsplit.ctr"
+#error "Redefinition of I_SQ"
+#endif
+
+#ifndef O_NL
+/** State machine output: Print newline and character */
+#line 47 "dk-sqlsplit.ctr"
+#define O_NL 0
+#else
+#line 47 "dk-sqlsplit.ctr"
+#error "Redefinition of O_NL"
+#endif
+
+#ifndef O_NORMAL
+/** State machine output: Print character */
+#line 46 "dk-sqlsplit.ctr"
+#define O_NORMAL 1
+#else
+#line 46 "dk-sqlsplit.ctr"
+#error "Redefinition of O_NORMAL"
+#endif
+
+/**@}*/
+
+/** Reset find_line_end state machine.
+ @param st Pointer to state variable.
+*/
+static
+void
+find_line_end_reset(int *st)
+{
+ if(st) { *st = ST_START; }
+}
+
+/** State machine find_line_end step.
+ @param st Pointer to state variable.
+ @param in Input.
+ @return Transition output.
+*/
+static
+int
+find_line_end_step(int *st, int in)
+{
+ int back = O_NORMAL;
+ if(st) {
+ int os;
+ int nf = 1;
+ int ns = ST_ERROR;
+ os = *st;
+ switch(os) {
+ case ST_BQ: {
+ switch(in) {
+ case I_BS: {
+ ns = ST_BQ_BS; back = O_NORMAL; nf = 0;
+ } break;
+ case I_BT: {
+ ns = ST_START; back = O_NORMAL; nf = 0;
+ } break;
+ }
+ } break;
+ case ST_CLBR: {
+ switch(in) {
+ case I_CLBR: {
+ ns = ST_CLBR; back = O_NORMAL; nf = 0;
+ } break;
+ case I_COMMA: {
+ ns = ST_CLBRCO; back = O_NORMAL; nf = 0;
+ } break;
+ }
+ } break;
+ case ST_CLBRCO: {
+ switch(in) {
+ case I_OPBR: {
+ ns = ST_START; back = O_NL; nf = 0;
+ } break;
+ }
+ } break;
+ case ST_CO: {
+ switch(in) {
+ case I_AST: {
+ ns = ST_CO_AST; back = O_NORMAL; nf = 0;
+ } break;
+ }
+ } break;
+ case ST_CO_AST: {
+ switch(in) {
+ case I_AST: {
+ ns = ST_CO_AST; back = O_NORMAL; nf = 0;
+ } break;
+ case I_SL: {
+ ns = ST_START; back = O_NORMAL; nf = 0;
+ } break;
+ }
+ } break;
+ case ST_DQ: {
+ switch(in) {
+ case I_BS: {
+ ns = ST_DQ_BS; back = O_NORMAL; nf = 0;
+ } break;
+ case I_DQ: {
+ ns = ST_START; back = O_NORMAL; nf = 0;
+ } break;
+ }
+ } break;
+ case ST_SL: {
+ switch(in) {
+ case I_AST: {
+ ns = ST_CO; back = O_NORMAL; nf = 0;
+ } break;
+ case I_SL: {
+ ns = ST_SL_CO; back = O_NORMAL; nf = 0;
+ } break;
+ }
+ } break;
+ case ST_SL_CO: {
+ switch(in) {
+ case I_NL: {
+ ns = ST_START; back = O_NORMAL; nf = 0;
+ } break;
+ }
+ } break;
+ case ST_SQ: {
+ switch(in) {
+ case I_BS: {
+ ns = ST_SQ_BS; back = O_NORMAL; nf = 0;
+ } break;
+ case I_SQ: {
+ ns = ST_START; back = O_NORMAL; nf = 0;
+ } break;
+ }
+ } break;
+ case ST_START: {
+ switch(in) {
+ case I_BS: {
+ ns = ST_START_BS; back = O_NORMAL; nf = 0;
+ } break;
+ case I_BT: {
+ ns = ST_BQ; back = O_NORMAL; nf = 0;
+ } break;
+ case I_CLBR: {
+ ns = ST_CLBR; back = O_NORMAL; nf = 0;
+ } break;
+ case I_DQ: {
+ ns = ST_DQ; back = O_NORMAL; nf = 0;
+ } break;
+ case I_SL: {
+ ns = ST_SL; back = O_NORMAL; nf = 0;
+ } break;
+ case I_SQ: {
+ ns = ST_SQ; back = O_NORMAL; nf = 0;
+ } break;
+ }
+ } break;
+ }
+ if(nf) {
+ if(os == ST_START) {
+ ns = ST_START; back = O_NORMAL;
+ } else {
+ if(os == ST_START_BS) {
+ ns = ST_START; back = O_NORMAL;
+ } else {
+ if(os == ST_SQ) {
+ ns = ST_SQ; back = O_NORMAL;
+ } else {
+ if(os == ST_SQ_BS) {
+ ns = ST_SQ; back = O_NORMAL;
+ } else {
+ if(os == ST_DQ) {
+ ns = ST_DQ; back = O_NORMAL;
+ } else {
+ if(os == ST_DQ_BS) {
+ ns = ST_DQ; back = O_NORMAL;
+ } else {
+ if(os == ST_BQ) {
+ ns = ST_BQ; back = O_NORMAL;
+ } else {
+ if(os == ST_BQ_BS) {
+ ns = ST_BQ; back = O_NORMAL;
+ } else {
+ if(os == ST_SL) {
+ ns = ST_START; back = O_NORMAL;
+ } else {
+ if(os == ST_SL_CO) {
+ ns = ST_SL_CO; back = O_NORMAL;
+ } else {
+ if(os == ST_CO) {
+ ns = ST_CO; back = O_NORMAL;
+ } else {
+ if(os == ST_CO_AST) {
+ ns = ST_CO; back = O_NORMAL;
+ } else {
+ if(os == ST_CLBR) {
+ ns = ST_START; back = O_NORMAL;
+ } else {
+ if(os == ST_CLBRCO) {
+ ns = ST_START; back = O_NORMAL;
+ } else {
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ *st = ns;
+ } else {
+ }
+ return back;
+}
+
+
+#line 101 "dk-sqlsplit.ctr"
+
+/** @file dk-sqlsplit Program to split SQL lines.
+*/
+
+/* The help_text array below shows details.
+*/
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4vers.h"
+#include "dk4app.h"
+#include "dk4fopda.h"
+#include "dk4isadm.h"
+#if DK4_ON_WINDOWS
+#include "dk4mem.h"
+#include "dk4strd.h"
+#include "dk4mpl.h"
+#include "dk4pathd.h"
+#endif
+
+
+/** Default help text, shown if help file is not found.
+*/
+static const dkChar * const help_text[] = {
+dkT(""),
+dkT("Split overlong SQL lines"),
+dkT(""),
+dkT("dk-sqlsplit [<file(s)>]"),
+dkT(""),
+dkT("Options:"),
+dkT("--help\t\tShow this short help text."),
+dkT("--manual\t*** SHOW FULL MANUAL. ***"),
+dkT("--version\tShow version information."),
+dkT("--license\tShow license information."),
+dkT(""),
+dkT("http://dktools.sourceforge.net"),
+dkT(""),
+NULL
+
+
+#line 178 "dk-sqlsplit.ctr"
+};
+
+
+
+/** License conditions.
+*/
+static const dkChar * const license_text[] = {
+dkT("This software uses code from the following projects, either directly or as"),
+dkT("a library:"),
+dkT(""),
+dkT("dktools\t\tDirk Krause's tools and libraries."),
+dkT("\t\tSee http://dktools.sourceforge.net/ for more information."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT("zlib\t\tData compression library."),
+dkT("\t\tSee http://www.zlib.net/ for more information."),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT("bzip2\t\tData compression program and library."),
+dkT("\t\tSee http://www.bzip.org/ for more information."),
+#endif
+dkT(""),
+dkT("All the licenses below apply to the program."),
+dkT("Licenses for used libraries are shown as found on my Scientific Linux 6.x"),
+dkT("computer in the /usr/share/doc directory on 2015-04-01. Check the project"),
+dkT("homepages of the used libraries for additional information and/or updated"),
+dkT("license terms."),
+dkT(""),
+dkT(""),
+dkT("DK tools and libraries license"),
+dkT("=============================="),
+dkT("Copyright (c) 2015-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above copyright notice,"),
+dkT(" this list of conditions and the following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("* Neither the name of the Dirk Krause nor the names of contributors may be"),
+dkT(" used to endorse or promote products derived from this software without"),
+dkT(" specific prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\""),
+dkT("AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED."),
+dkT(""),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,"),
+dkT("INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,"),
+dkT("BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,"),
+dkT("DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY"),
+dkT("OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,"),
+dkT("EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT(""),
+dkT("Zlib license"),
+dkT("============"),
+dkT("(C) 1995-2004 Jean-loup Gailly and Mark Adler"),
+dkT(""),
+dkT("This software is provided 'as-is', without any express or implied"),
+dkT("warranty. In no event will the authors be held liable for any damages"),
+dkT("arising from the use of this software."),
+dkT(""),
+dkT("Permission is granted to anyone to use this software for any purpose,"),
+dkT("including commercial applications, and to alter it and redistribute it"),
+dkT("freely, subject to the following restrictions:"),
+dkT(""),
+dkT("1. The origin of this software must not be misrepresented; you must not"),
+dkT(" claim that you wrote the original software. If you use this software"),
+dkT(" in a product, an acknowledgment in the product documentation would be"),
+dkT(" appreciated but is not required."),
+dkT("2. Altered source versions must be plainly marked as such, and must not be"),
+dkT(" misrepresented as being the original software."),
+dkT("3. This notice may not be removed or altered from any source distribution."),
+dkT(""),
+dkT("Jean-loup Gailly Mark Adler"),
+dkT("jloup@gzip.org madler@alumni.caltech.edu"),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT(""),
+dkT("Bzip2 and libbzip2 library license"),
+dkT("=================================="),
+dkT("This program, \"bzip2\", the associated library \"libbzip2\", and all"),
+dkT("documentation, are copyright (C) 1996-2007 Julian R Seward. All"),
+dkT("rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions"),
+dkT("are met:"),
+dkT(""),
+dkT("1. Redistributions of source code must retain the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer."),
+dkT(""),
+dkT("2. The origin of this software must not be misrepresented; you must "),
+dkT(" not claim that you wrote the original software. If you use this "),
+dkT(" software in a product, an acknowledgment in the product "),
+dkT(" documentation would be appreciated but is not required."),
+dkT(""),
+dkT("3. Altered source versions must be plainly marked as such, and must"),
+dkT(" not be misrepresented as being the original software."),
+dkT(""),
+dkT("4. The name of the author may not be used to endorse or promote "),
+dkT(" products derived from this software without specific prior written "),
+dkT(" permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS"),
+dkT("OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED"),
+dkT("WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE"),
+dkT("GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS"),
+dkT("INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,"),
+dkT("WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS"),
+dkT("SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+dkT(""),
+dkT("Julian Seward, jseward@bzip.org"),
+dkT("bzip2/libbzip2 version 1.0.5 of 10 December 2007"),
+#endif
+dkT(""),
+NULL
+
+
+#line 309 "dk-sqlsplit.ctr"
+};
+
+
+
+/** Constant texts used by the program, not localized.
+*/
+static const dkChar * const kwnl[] = {
+/* 0 */
+dkT("dktools"),
+
+/* 1 */
+dkT("dk-sqlsplit.txt"),
+
+/* 2 */
+dkT("stdin"),
+
+/* 3 */
+dkT("\\"),
+
+NULL
+
+
+#line 334 "dk-sqlsplit.ctr"
+};
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Exit status code.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+static
+void
+process_file_with_name(FILE *fp, const dkChar *fn)
+{
+ const dkChar *oldsourcefile; /* Previous source file name setting */
+ dk4_um_t oldsourceline; /* Previous source line setting */
+ dk4_um_t lineno; /* Current line number */
+ int inc; /* Input character from fgetc() */
+ int ccl; /* Character class, input to STM */
+ int st; /* State */
+ int lnl; /* Flag: Last char was newline */
+ char c; /* Current character to process */
+
+ /* Save current log settings
+ */
+ oldsourcefile = dk4app_get_log_source_file(app);
+ oldsourceline = dk4app_get_log_source_line(app);
+
+ /* Set logging too file name
+ */
+ dk4app_set_log_source_file(app, fn);
+ dk4app_set_log_source_line(app, (dk4_um_t)1UL);
+ lineno = (dk4_um_t)1UL;
+
+ /* Process all input bytes
+ */
+ lnl = 0;
+ find_line_end_reset(&st);
+ while (EOF != (inc = fgetc(fp))) {
+ c = (char)inc;
+ if ('\r' != c) {
+ /* Classify input character
+ */
+ ccl = I_ANY;
+ switch (c) {
+ case '\n': ccl = I_NL; break;
+ case '(': ccl = I_OPBR; break;
+ case ')': ccl = I_CLBR; break;
+ case '\\': ccl = I_BS; break;
+ case '/': ccl = I_SL; break;
+ case '*': ccl = I_AST; break;
+ case '\'': ccl = I_SQ; break;
+ case '"': ccl = I_DQ; break;
+ case '`': ccl = I_BT; break;
+ case ',': ccl = I_COMMA; break;
+ }
+ /* Get state machine reaction and go to appropriate brach
+ */
+ switch (find_line_end_step(&st, ccl)) {
+ case O_NL : {
+ if (EOF == fputc('\n', stdout)) {
+ exval = EXIT_FAILURE;
+ /* ERROR: Write operation failed */
+ dk4app_log_base1(app, DK4_LL_ERROR, 128);
+ }
+ if (EOF == fputc(c, stdout)) {
+ exval = EXIT_FAILURE;
+ /* ERROR: Write operation failed */
+ dk4app_log_base1(app, DK4_LL_ERROR, 128);
+ }
+ } break;
+ default : {
+ if (EOF == fputc(c, stdout)) {
+ exval = EXIT_FAILURE;
+ /* ERROR: Write operation failed */
+ dk4app_log_base1(app, DK4_LL_ERROR, 128);
+ }
+ } break;
+ }
+ if ('\n' == c) {
+ lnl = 1;
+ lineno++;
+ dk4app_set_log_source_line(app, lineno);
+ } else {
+ lnl = 0;
+ }
+ }
+ }
+ if (0 == lnl) {
+ if (EOF == fputc('\n', stdout)) {
+ exval = EXIT_FAILURE;
+ /* ERROR: Write operation failed */
+ dk4app_log_base1(app, DK4_LL_ERROR, 128);
+ }
+ }
+
+ /* Restore log settings
+ */
+ dk4app_set_log_source_file(app, oldsourcefile);
+ dk4app_set_log_source_line(app, oldsourceline);
+}
+
+
+
+static
+void
+process_named_file(const dkChar *filename)
+{
+ FILE *fipo = NULL;
+ int tests = DK4_FOPEN_SC_USER;
+
+#if 0
+ /* File is opened for reading only.
+ */
+ if (1 == dk4isadmin()) { tests = DK4_FOPEN_SC_PRIVILEGED; }
+#endif
+ fipo = dk4fopen_app(filename, dkT("rb"), tests, app);
+ if (NULL != fipo) {
+ process_file_with_name(fipo, filename);
+ fclose(fipo);
+ } else {
+ exval = EXIT_FAILURE;
+ }
+}
+
+
+
+#if DK4_ON_WINDOWS
+static
+void
+expand_and_process(const dkChar *pattern)
+{
+ dkChar buf[DK4_MAX_PATH];
+ dk4_dir_t *fne;
+ const dkChar *shf;
+ const dkChar *pth;
+ int any_file_found = 0;
+
+ fne = dk4app_fne_open(pattern, app);
+ if (NULL != fne) {
+ while (NULL != (shf = dk4dir_next_file(fne))) {
+ any_file_found = 1;
+ pth = dk4dir_get_path(fne);
+ if (0 != dk4str_cpy_s(buf, DK4_SIZEOF(buf,dkChar), pth, NULL)) {
+ if(0 != dk4str_cat_s(buf, DK4_SIZEOF(buf,dkChar), kwnl[3], NULL)) {
+ if(0 != dk4str_cat_s(buf, DK4_SIZEOF(buf,dkChar), shf, NULL)) {
+ process_named_file(buf);
+ } else {
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 105, pattern);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 105, pattern);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 105, pattern);
+ exval = EXIT_FAILURE;
+ }
+ if (NULL != pth) {
+ } else {
+ process_named_file(shf);
+ }
+ }
+ dk4dir_close(fne);
+ if (0 == any_file_found) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 107, pattern);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ exval = EXIT_FAILURE;
+ }
+}
+#endif
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ const dkChar *argptr = NULL;
+#if DK4_ON_WINDOWS
+ int oldmode = _O_TEXT;
+#endif
+ int xargc = 0;
+ int i;
+
+
+#line 535 "dk-sqlsplit.ctr"
+
+
+#line 536 "dk-sqlsplit.ctr"
+
+ app = dk4app_open_cmd(
+ argc, argv, NULL, 0, kwnl[0], DKT_VERSION_DK,
+ kwnl[1], help_text, license_text
+ );
+ if (NULL != app) {
+ if (0 != dk4app_can_run_normally(app)) {
+ exval = EXIT_SUCCESS;
+ if (0 < (xargc = dk4app_get_argc(app))) {
+ for (i = 0; i < xargc; i++) {
+ argptr = dk4app_get_argv(app, i);
+ if (NULL != argptr) {
+#if DK4_ON_WINDOWS
+ if (0 != dk4path_must_expand(argptr)) {
+ expand_and_process(argptr);
+ } else {
+#endif
+ process_named_file(argptr);
+#if DK4_ON_WINDOWS
+ }
+#endif
+ } else {
+
+#line 558 "dk-sqlsplit.ctr"
+ /* BUG: Should not happen */
+ }
+ }
+ } else {
+#if DK4_ON_WINDOWS
+ oldmode = _setmode(_fileno(stdin), _O_BINARY);
+#endif
+ process_file_with_name(stdin, kwnl[2]);
+#if DK4_ON_WINDOWS
+ _setmode(_fileno(stdin), oldmode);
+#endif
+ }
+ } else {
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ dk4app_close(app);
+ } else {
+ }
+
+
+#line 579 "dk-sqlsplit.ctr"
+
+
+#line 580 "dk-sqlsplit.ctr"
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/dk-sqlsplit.ctr b/support/dktools/dk-sqlsplit.ctr
new file mode 100644
index 0000000000..81463eea94
--- /dev/null
+++ b/support/dktools/dk-sqlsplit.ctr
@@ -0,0 +1,582 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% state machine
+
+[options]
+name = find_line_end
+write header = no
+
+[states]
+ST_START # Normal state
+ST_START_BS # Backslash found in normal state
+ST_SQ # In single quotes string
+ST_SQ_BS # In single quotes string after backslash
+ST_DQ # In double quotes string
+ST_DQ_BS # In double quotes string after back
+ST_BQ # In back-tick quoted string
+ST_BQ_BS # In back-tick quoted string after backslash
+ST_SL # Normal state after slash
+ST_SL_CO # In double slash comment
+ST_CO # In normal comment
+ST_CO_AST # In normal comment after asterisk
+ST_CLBR # In normal state after closing bracket
+ST_CLBRCO # In normal state after closing bracket and comma
+ST_ERROR # Undefined state
+
+[inputs]
+I_NL # Newline
+I_OPBR # Opening bracket
+I_CLBR # Closing bracket
+I_BS # Backslash
+I_SL # Slash
+I_AST # Asterisk
+I_SQ # Single quote
+I_DQ # Double quote
+I_BT # Backtick
+I_COMMA # Comma
+I_ANY # Anything else
+
+[outputs]
+O_NORMAL # Print character
+O_NL # Print newline and character
+
+[rules]
+* * ST_ERROR O_NORMAL
+ST_START I_SQ ST_SQ O_NORMAL
+ST_START I_DQ ST_DQ O_NORMAL
+ST_START I_BT ST_BQ O_NORMAL
+ST_START I_SL ST_SL O_NORMAL
+ST_START I_CLBR ST_CLBR O_NORMAL
+ST_START I_BS ST_START_BS O_NORMAL
+ST_START * ST_START O_NORMAL
+
+ST_START_BS * ST_START O_NORMAL
+
+ST_SQ I_SQ ST_START O_NORMAL
+ST_SQ I_BS ST_SQ_BS O_NORMAL
+ST_SQ * ST_SQ O_NORMAL
+
+ST_SQ_BS * ST_SQ O_NORMAL
+
+ST_DQ I_DQ ST_START O_NORMAL
+ST_DQ I_BS ST_DQ_BS O_NORMAL
+ST_DQ * ST_DQ O_NORMAL
+
+ST_DQ_BS * ST_DQ O_NORMAL
+
+ST_BQ I_BT ST_START O_NORMAL
+ST_BQ I_BS ST_BQ_BS O_NORMAL
+ST_BQ * ST_BQ O_NORMAL
+
+ST_BQ_BS * ST_BQ O_NORMAL
+
+ST_SL I_SL ST_SL_CO O_NORMAL
+ST_SL I_AST ST_CO O_NORMAL
+ST_SL * ST_START O_NORMAL
+
+ST_SL_CO I_NL ST_START O_NORMAL
+ST_SL_CO * ST_SL_CO O_NORMAL
+
+ST_CO I_AST ST_CO_AST O_NORMAL
+ST_CO * ST_CO O_NORMAL
+
+ST_CO_AST I_SL ST_START O_NORMAL
+ST_CO_AST I_AST ST_CO_AST O_NORMAL
+ST_CO_AST * ST_CO O_NORMAL
+
+ST_CLBR I_COMMA ST_CLBRCO O_NORMAL
+ST_CLBR I_CLBR ST_CLBR O_NORMAL
+ST_CLBR * ST_START O_NORMAL
+
+ST_CLBRCO I_OPBR ST_START O_NL
+ST_CLBRCO * ST_START O_NORMAL
+
+%% module
+
+/** @file dk-sqlsplit Program to split SQL lines.
+*/
+
+/* The help_text array below shows details.
+*/
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4vers.h"
+#include "dk4app.h"
+#include "dk4fopda.h"
+#include "dk4isadm.h"
+#if DK4_ON_WINDOWS
+#include "dk4mem.h"
+#include "dk4strd.h"
+#include "dk4mpl.h"
+#include "dk4pathd.h"
+#endif
+
+
+/** Default help text, shown if help file is not found.
+*/
+static const dkChar * const help_text[] = {
+$!text macro=dkT,preprocessor
+
+Split overlong SQL lines
+
+dk-sqlsplit [<file(s)>]
+
+Options:
+--help Show this short help text.
+--manual *** SHOW FULL MANUAL. ***
+--version Show version information.
+--license Show license information.
+
+http://dktools.sourceforge.net
+
+$!end
+};
+
+
+
+/** License conditions.
+*/
+static const dkChar * const license_text[] = {
+$!text macro=dkT,preprocessor
+This software uses code from the following projects, either directly or as
+a library:
+
+dktools Dirk Krause's tools and libraries.
+ See http://dktools.sourceforge.net/ for more information.
+#if DK4_HAVE_ZLIB_H
+
+zlib Data compression library.
+ See http://www.zlib.net/ for more information.
+#endif
+#if DK4_HAVE_BZLIB_H
+
+bzip2 Data compression program and library.
+ See http://www.bzip.org/ for more information.
+#endif
+
+All the licenses below apply to the program.
+Licenses for used libraries are shown as found on my Scientific Linux 6.x
+computer in the /usr/share/doc directory on 2015-04-01. Check the project
+homepages of the used libraries for additional information and/or updated
+license terms.
+
+
+DK tools and libraries license
+==============================
+Copyright (c) 2015-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#if DK4_HAVE_ZLIB_H
+
+
+Zlib license
+============
+(C) 1995-2004 Jean-loup Gailly and Mark Adler
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+
+Jean-loup Gailly Mark Adler
+jloup@gzip.org madler@alumni.caltech.edu
+#endif
+#if DK4_HAVE_BZLIB_H
+
+
+Bzip2 and libbzip2 library license
+==================================
+This program, "bzip2", the associated library "libbzip2", and all
+documentation, are copyright (C) 1996-2007 Julian R Seward. All
+rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+3. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Julian Seward, jseward@bzip.org
+bzip2/libbzip2 version 1.0.5 of 10 December 2007
+#endif
+
+$!end
+};
+
+
+
+/** Constant texts used by the program, not localized.
+*/
+static const dkChar * const kwnl[] = {
+$!string-table macro=dkT
+#
+# 0 Program group name
+#
+dktools
+#
+# 1 Help file name
+#
+dk-sqlsplit.txt
+#
+# 2 File name: stdin
+#
+stdin
+#
+# 3 File name separator for Windows
+#
+\\
+$!end
+};
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Exit status code.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+static
+void
+process_file_with_name(FILE *fp, const dkChar *fn)
+{
+ const dkChar *oldsourcefile; /* Previous source file name setting */
+ dk4_um_t oldsourceline; /* Previous source line setting */
+ dk4_um_t lineno; /* Current line number */
+ int inc; /* Input character from fgetc() */
+ int ccl; /* Character class, input to STM */
+ int st; /* State */
+ int lnl; /* Flag: Last char was newline */
+ char c; /* Current character to process */
+
+ /* Save current log settings
+ */
+ oldsourcefile = dk4app_get_log_source_file(app);
+ oldsourceline = dk4app_get_log_source_line(app);
+
+ /* Set logging too file name
+ */
+ dk4app_set_log_source_file(app, fn);
+ dk4app_set_log_source_line(app, (dk4_um_t)1UL);
+ lineno = (dk4_um_t)1UL;
+
+ /* Process all input bytes
+ */
+ lnl = 0;
+ find_line_end_reset(&st);
+ while (EOF != (inc = fgetc(fp))) {
+ c = (char)inc;
+ if ('\r' != c) {
+ /* Classify input character
+ */
+ ccl = I_ANY;
+ switch (c) {
+ case '\n': ccl = I_NL; break;
+ case '(': ccl = I_OPBR; break;
+ case ')': ccl = I_CLBR; break;
+ case '\\': ccl = I_BS; break;
+ case '/': ccl = I_SL; break;
+ case '*': ccl = I_AST; break;
+ case '\'': ccl = I_SQ; break;
+ case '"': ccl = I_DQ; break;
+ case '`': ccl = I_BT; break;
+ case ',': ccl = I_COMMA; break;
+ }
+ /* Get state machine reaction and go to appropriate brach
+ */
+ switch (find_line_end_step(&st, ccl)) {
+ case O_NL : {
+ if (EOF == fputc('\n', stdout)) {
+ exval = EXIT_FAILURE;
+ /* ERROR: Write operation failed */
+ dk4app_log_base1(app, DK4_LL_ERROR, 128);
+ }
+ if (EOF == fputc(c, stdout)) {
+ exval = EXIT_FAILURE;
+ /* ERROR: Write operation failed */
+ dk4app_log_base1(app, DK4_LL_ERROR, 128);
+ }
+ } break;
+ default : {
+ if (EOF == fputc(c, stdout)) {
+ exval = EXIT_FAILURE;
+ /* ERROR: Write operation failed */
+ dk4app_log_base1(app, DK4_LL_ERROR, 128);
+ }
+ } break;
+ }
+ if ('\n' == c) {
+ lnl = 1;
+ lineno++;
+ dk4app_set_log_source_line(app, lineno);
+ } else {
+ lnl = 0;
+ }
+ }
+ }
+ if (0 == lnl) {
+ if (EOF == fputc('\n', stdout)) {
+ exval = EXIT_FAILURE;
+ /* ERROR: Write operation failed */
+ dk4app_log_base1(app, DK4_LL_ERROR, 128);
+ }
+ }
+
+ /* Restore log settings
+ */
+ dk4app_set_log_source_file(app, oldsourcefile);
+ dk4app_set_log_source_line(app, oldsourceline);
+}
+
+
+
+static
+void
+process_named_file(const dkChar *filename)
+{
+ FILE *fipo = NULL;
+ int tests = DK4_FOPEN_SC_USER;
+
+#if 0
+ /* File is opened for reading only.
+ */
+ if (1 == dk4isadmin()) { tests = DK4_FOPEN_SC_PRIVILEGED; }
+#endif
+ fipo = dk4fopen_app(filename, dkT("rb"), tests, app);
+ if (NULL != fipo) {
+ process_file_with_name(fipo, filename);
+ fclose(fipo);
+ } else {
+ exval = EXIT_FAILURE;
+ }
+}
+
+
+
+#if DK4_ON_WINDOWS
+static
+void
+expand_and_process(const dkChar *pattern)
+{
+ dkChar buf[DK4_MAX_PATH];
+ dk4_dir_t *fne;
+ const dkChar *shf;
+ const dkChar *pth;
+ int any_file_found = 0;
+
+ fne = dk4app_fne_open(pattern, app);
+ if (NULL != fne) {
+ while (NULL != (shf = dk4dir_next_file(fne))) {
+ any_file_found = 1;
+ pth = dk4dir_get_path(fne);
+ if (0 != dk4str_cpy_s(buf, DK4_SIZEOF(buf,dkChar), pth, NULL)) {
+ if(0 != dk4str_cat_s(buf, DK4_SIZEOF(buf,dkChar), kwnl[3], NULL)) {
+ if(0 != dk4str_cat_s(buf, DK4_SIZEOF(buf,dkChar), shf, NULL)) {
+ process_named_file(buf);
+ } else {
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 105, pattern);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 105, pattern);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 105, pattern);
+ exval = EXIT_FAILURE;
+ }
+ if (NULL != pth) {
+ } else {
+ process_named_file(shf);
+ }
+ }
+ dk4dir_close(fne);
+ if (0 == any_file_found) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 107, pattern);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ exval = EXIT_FAILURE;
+ }
+}
+#endif
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ const dkChar *argptr = NULL;
+#if DK4_ON_WINDOWS
+ int oldmode = _O_TEXT;
+#endif
+ int xargc = 0;
+ int i;
+ $!trace-init dk-sqlsplit.deb
+ $? "+ main"
+
+ app = dk4app_open_cmd(
+ argc, argv, NULL, 0, kwnl[0], DKT_VERSION_DK,
+ kwnl[1], help_text, license_text
+ );
+ if (NULL != app) {
+ if (0 != dk4app_can_run_normally(app)) {
+ exval = EXIT_SUCCESS;
+ if (0 < (xargc = dk4app_get_argc(app))) {
+ for (i = 0; i < xargc; i++) {
+ argptr = dk4app_get_argv(app, i);
+ if (NULL != argptr) {
+#if DK4_ON_WINDOWS
+ if (0 != dk4path_must_expand(argptr)) {
+ expand_and_process(argptr);
+ } else {
+#endif
+ process_named_file(argptr);
+#if DK4_ON_WINDOWS
+ }
+#endif
+ } else { $? "! BUG, empty argptr"
+ /* BUG: Should not happen */
+ }
+ }
+ } else {
+#if DK4_ON_WINDOWS
+ oldmode = _setmode(_fileno(stdin), _O_BINARY);
+#endif
+ process_file_with_name(stdin, kwnl[2]);
+#if DK4_ON_WINDOWS
+ _setmode(_fileno(stdin), oldmode);
+#endif
+ }
+ } else {
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ dk4app_close(app);
+ } else {
+ }
+ $? "- main %d", exval
+ $!trace-end
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/dk-sqlsplit.rc b/support/dktools/dk-sqlsplit.rc
new file mode 100644
index 0000000000..955c266208
--- /dev/null
+++ b/support/dktools/dk-sqlsplit.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Split overlong SQL lines\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "Split overlong SQL lines\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "dk-sqlsplit\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/dk-t2db.c b/support/dktools/dk-t2db.c
new file mode 100644
index 0000000000..8f8d6b66c8
--- /dev/null
+++ b/support/dktools/dk-t2db.c
@@ -0,0 +1,1629 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk-t2db.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk-t2db.c The dk-t2db module.
+*/
+
+
+#line 10 "dk-t2db.ctr"
+
+/*
+ Convert text to database.
+
+ See help_text below.
+*/
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4const.h"
+#include "dk4mem.h"
+#include "dk4mema.h"
+#include "dk4error.h"
+#include "dk4dbi.h"
+#include "dk4dbit8.h"
+#include "dk4dbitw.h"
+#include "dk4dbit.h"
+#include "dk4dbia.h"
+#include "dk4fput.h"
+#include "dk4vers.h"
+#include "dk4app.h"
+#include "dk4aopt.h"
+#include "dk4maasz.h"
+#include "dk4enc.h"
+#include "dk4fopt.h"
+#include "dk4fopda.h"
+#include "dk4tspdk.h"
+#include "dk4strd.h"
+#include "dk4maodd.h"
+#include "dk4mpl.h"
+#include "dk4pathd.h"
+
+
+
+
+
+#line 96 "dk-t2db.ctr"
+
+
+
+static const dkChar * const help_text[] = {
+dkT(""),
+dkT("dk-t2db - Convert text to simple database"),
+dkT("-----------------------------------------"),
+dkT(""),
+dkT("dk-t2db [<option>] [<file>...] <database>"),
+dkT(""),
+dkT("Options:"),
+dkT(""),
+dkT("-a\t\t--add\t\t\t\tAppend to existing database."),
+dkT("-l <size>\t--line-size=<size>\t\tLine buffer size."),
+dkT("-k <size>\t--key-buffer-size=<size>\tKey buffer size."),
+dkT("-v <size>\t--value-buffer-size=<size>\tValue buffer size."),
+dkT("-i <string>\t--input-encoding=<string>\tExpected input encoding."),
+dkT(""),
+dkT("--help\t\t\t\t\t\tShow short help text."),
+dkT("--manual\t\t\t\t\t*** SHOW FULL MANUAL ***"),
+dkT("--version\t\t\t\t\tShow version information."),
+dkT("--license\t\t\t\t\tShow license information."),
+dkT(""),
+NULL
+
+
+#line 121 "dk-t2db.ctr"
+};
+
+
+/** License conditions.
+*/
+static const dkChar * const license_text[] = {
+dkT(""),
+dkT("This software uses code from the following projects, either directly or as"),
+dkT("a library:"),
+dkT(""),
+dkT("dktools\t\tDirk Krause's tools and libraries."),
+dkT("\t\tSee http://dktools.sourceforge.net/ for more information."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT("zlib\t\tData compression library."),
+dkT("\t\tSee http://www.zlib.net/ for more information."),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT("bzip2\t\tData compression program and library."),
+dkT("\t\tSee http://www.bzip.org/ for more information."),
+#endif
+dkT(""),
+dkT("All the licenses below apply to the program."),
+dkT("Licenses for used libraries are shown as found on my Scientific Linux 6.x"),
+dkT("computer in the /usr/share/doc directory on 2015-04-01. Check the project"),
+dkT("homepages of the used libraries for additional information and/or updated"),
+dkT("license terms."),
+dkT(""),
+dkT(""),
+dkT("DK tools and libraries license"),
+dkT("=============================="),
+dkT("Copyright (c) 2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above copyright notice,"),
+dkT(" this list of conditions and the following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("* Neither the name of the Dirk Krause nor the names of contributors may be"),
+dkT(" used to endorse or promote products derived from this software without"),
+dkT(" specific prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\""),
+dkT("AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED."),
+dkT(""),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,"),
+dkT("INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,"),
+dkT("BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,"),
+dkT("DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY"),
+dkT("OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,"),
+dkT("EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+dkT(""),
+dkT(""),
+dkT("Berkeley DB license"),
+dkT("==================="),
+dkT("This package was debianized by Clint Adams <schizo@debian.org> on"),
+dkT("Wed, 25 Jul 2007 20:37:51 +0700"),
+dkT(""),
+dkT("It was downloaded from"),
+dkT("http://www.oracle.com/technology/software/products/berkeley-db/db/index.html"),
+dkT(""),
+dkT("Copyright and license:"),
+dkT(""),
+dkT("The following is the license that applies to this copy of the Berkeley DB"),
+dkT("software. For a license to use the Berkeley DB software under conditions"),
+dkT("other than those described here, or to purchase support for this software,"),
+dkT("please contact Oracle at berkeleydb-info_us@oracle.com."),
+dkT(""),
+dkT("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="),
+dkT("/*"),
+dkT(" * Copyright (c) 1990, 2010 Oracle and/or its affiliates. All rights reserved."),
+dkT(" *"),
+dkT(" * Redistribution and use in source and binary forms, with or without"),
+dkT(" * modification, are permitted provided that the following conditions"),
+dkT(" * are met:"),
+dkT(" * 1. Redistributions of source code must retain the above copyright"),
+dkT(" * notice, this list of conditions and the following disclaimer."),
+dkT(" * 2. Redistributions in binary form must reproduce the above copyright"),
+dkT(" * notice, this list of conditions and the following disclaimer in the"),
+dkT(" * documentation and/or other materials provided with the distribution."),
+dkT(" * 3. Redistributions in any form must be accompanied by information on"),
+dkT(" * how to obtain complete source code for the DB software and any"),
+dkT(" * accompanying software that uses the DB software. The source code"),
+dkT(" * must either be included in the distribution or be available for no"),
+dkT(" * more than the cost of distribution plus a nominal fee, and must be"),
+dkT(" * freely redistributable under reasonable conditions. For an"),
+dkT(" * executable file, complete source code means the source code for all"),
+dkT(" * modules it contains. It does not include source code for modules or"),
+dkT(" * files that typically accompany the major components of the operating"),
+dkT(" * system on which the executable file runs."),
+dkT(" *"),
+dkT(" * THIS SOFTWARE IS PROVIDED BY ORACLE ``AS IS'' AND ANY EXPRESS OR"),
+dkT(" * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED"),
+dkT(" * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR"),
+dkT(" * NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL ORACLE BE LIABLE"),
+dkT(" * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR"),
+dkT(" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF"),
+dkT(" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR"),
+dkT(" * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,"),
+dkT(" * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE"),
+dkT(" * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN"),
+dkT(" * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+dkT(" */"),
+dkT("/*"),
+dkT(" * Copyright (c) 1990, 1993, 1994, 1995"),
+dkT(" *\tThe Regents of the University of California. All rights reserved."),
+dkT(" *"),
+dkT(" * Redistribution and use in source and binary forms, with or without"),
+dkT(" * modification, are permitted provided that the following conditions"),
+dkT(" * are met:"),
+dkT(" * 1. Redistributions of source code must retain the above copyright"),
+dkT(" * notice, this list of conditions and the following disclaimer."),
+dkT(" * 2. Redistributions in binary form must reproduce the above copyright"),
+dkT(" * notice, this list of conditions and the following disclaimer in the"),
+dkT(" * documentation and/or other materials provided with the distribution."),
+dkT(" * 3. Neither the name of the University nor the names of its contributors"),
+dkT(" * may be used to endorse or promote products derived from this software"),
+dkT(" * without specific prior written permission."),
+dkT(" *"),
+dkT(" * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND"),
+dkT(" * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT(" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT(" * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE"),
+dkT(" * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT(" * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS"),
+dkT(" * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)"),
+dkT(" * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT"),
+dkT(" * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY"),
+dkT(" * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF"),
+dkT(" * SUCH DAMAGE."),
+dkT(" */"),
+dkT("/*"),
+dkT(" * Copyright (c) 1995, 1996"),
+dkT(" *\tThe President and Fellows of Harvard University. All rights reserved."),
+dkT(" *"),
+dkT(" * Redistribution and use in source and binary forms, with or without"),
+dkT(" * modification, are permitted provided that the following conditions"),
+dkT(" * are met:"),
+dkT(" * 1. Redistributions of source code must retain the above copyright"),
+dkT(" * notice, this list of conditions and the following disclaimer."),
+dkT(" * 2. Redistributions in binary form must reproduce the above copyright"),
+dkT(" * notice, this list of conditions and the following disclaimer in the"),
+dkT(" * documentation and/or other materials provided with the distribution."),
+dkT(" * 3. Neither the name of the University nor the names of its contributors"),
+dkT(" * may be used to endorse or promote products derived from this software"),
+dkT(" * without specific prior written permission."),
+dkT(" *"),
+dkT(" * THIS SOFTWARE IS PROVIDED BY HARVARD AND ITS CONTRIBUTORS ``AS IS'' AND"),
+dkT(" * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT(" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT(" * ARE DISCLAIMED. IN NO EVENT SHALL HARVARD OR ITS CONTRIBUTORS BE LIABLE"),
+dkT(" * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT(" * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS"),
+dkT(" * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)"),
+dkT(" * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT"),
+dkT(" * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY"),
+dkT(" * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF"),
+dkT(" * SUCH DAMAGE."),
+dkT(" */"),
+dkT("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="),
+dkT("/***"),
+dkT(" * ASM: a very small and fast Java bytecode manipulation framework"),
+dkT(" * Copyright (c) 2000-2005 INRIA, France Telecom"),
+dkT(" * All rights reserved."),
+dkT(" *"),
+dkT(" * Redistribution and use in source and binary forms, with or without"),
+dkT(" * modification, are permitted provided that the following conditions"),
+dkT(" * are met:"),
+dkT(" * 1. Redistributions of source code must retain the above copyright"),
+dkT(" * notice, this list of conditions and the following disclaimer."),
+dkT(" * 2. Redistributions in binary form must reproduce the above copyright"),
+dkT(" * notice, this list of conditions and the following disclaimer in the"),
+dkT(" * documentation and/or other materials provided with the distribution."),
+dkT(" * 3. Neither the name of the copyright holders nor the names of its"),
+dkT(" * contributors may be used to endorse or promote products derived from"),
+dkT(" * this software without specific prior written permission."),
+dkT(" *"),
+dkT(" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\""),
+dkT(" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT(" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT(" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE"),
+dkT(" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR"),
+dkT(" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF"),
+dkT(" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS"),
+dkT(" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN"),
+dkT(" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)"),
+dkT(" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF"),
+dkT(" * THE POSSIBILITY OF SUCH DAMAGE."),
+dkT(" */"),
+#endif
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT(""),
+dkT("Zlib license"),
+dkT("============"),
+dkT("(C) 1995-2004 Jean-loup Gailly and Mark Adler"),
+dkT(""),
+dkT("This software is provided 'as-is', without any express or implied"),
+dkT("warranty. In no event will the authors be held liable for any damages"),
+dkT("arising from the use of this software."),
+dkT(""),
+dkT("Permission is granted to anyone to use this software for any purpose,"),
+dkT("including commercial applications, and to alter it and redistribute it"),
+dkT("freely, subject to the following restrictions:"),
+dkT(""),
+dkT("1. The origin of this software must not be misrepresented; you must not"),
+dkT(" claim that you wrote the original software. If you use this software"),
+dkT(" in a product, an acknowledgment in the product documentation would be"),
+dkT(" appreciated but is not required."),
+dkT("2. Altered source versions must be plainly marked as such, and must not be"),
+dkT(" misrepresented as being the original software."),
+dkT("3. This notice may not be removed or altered from any source distribution."),
+dkT(""),
+dkT("Jean-loup Gailly Mark Adler"),
+dkT("jloup@gzip.org madler@alumni.caltech.edu"),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT(""),
+dkT("Bzip2 and libbzip2 library license"),
+dkT("=================================="),
+dkT("This program, \"bzip2\", the associated library \"libbzip2\", and all"),
+dkT("documentation, are copyright (C) 1996-2007 Julian R Seward. All"),
+dkT("rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions"),
+dkT("are met:"),
+dkT(""),
+dkT("1. Redistributions of source code must retain the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer."),
+dkT(""),
+dkT("2. The origin of this software must not be misrepresented; you must "),
+dkT(" not claim that you wrote the original software. If you use this "),
+dkT(" software in a product, an acknowledgment in the product "),
+dkT(" documentation would be appreciated but is not required."),
+dkT(""),
+dkT("3. Altered source versions must be plainly marked as such, and must"),
+dkT(" not be misrepresented as being the original software."),
+dkT(""),
+dkT("4. The name of the author may not be used to endorse or promote "),
+dkT(" products derived from this software without specific prior written "),
+dkT(" permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS"),
+dkT("OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED"),
+dkT("WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE"),
+dkT("GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS"),
+dkT("INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,"),
+dkT("WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS"),
+dkT("SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+dkT(""),
+dkT("Julian Seward, jseward@bzip.org"),
+dkT("bzip2/libbzip2 version 1.0.5 of 10 December 2007"),
+#endif
+NULL
+
+
+#line 391 "dk-t2db.ctr"
+};
+
+
+
+/** Version text.
+*/
+static const dkChar version_text[] = {
+ DKT_VERSION_DK
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+ dkT(" bdb")
+#endif
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+ dkT(" ndbm")
+#endif
+ dkT(" mem")
+};
+
+
+
+/** Constant texts used by the module, not localized.
+*/
+const dkChar * const dk_t2db_kwnl[] = {
+/* 0 */
+dkT("dktools"),
+
+/* 1 */
+dkT("dk-t2db.txt"),
+
+/* 2 */
+dkT("ERROR: Application startup failed!\n"),
+
+/* 3 */
+dkT("dk-t2db.str"),
+
+/* 4 */
+dkT("line.size"),
+
+/* 5 */
+dkT("text-db.key.max-size"),
+
+/* 6 */
+dkT("text-db.value.max-size"),
+
+/* 7 */
+dkT("rb"),
+
+/* 8 */
+dkT("\\"),
+
+NULL
+
+
+#line 445 "dk-t2db.ctr"
+};
+
+
+
+/** Constant string used by the module, replaced by localized
+ texts if available.
+*/
+const dkChar * const dk_t2db_kw_def[] = {
+/* 0 */
+dkT("Failed to set up signal handlers!"),
+
+/* 1 */
+dkT("Failed to restore previous signal handlers!"),
+
+/* 2 */
+dkT("<standard input>"),
+
+/* 3 */
+dkT("Failed to set database entry\n\""),
+
+/* 4 */
+dkT("\"=\""),
+
+/* 5 */
+dkT("\"!"),
+
+/* 6 */
+dkT("Failed to delete database entry\n\""),
+
+/* 7 */
+dkT("\"!"),
+
+/* 8 */
+dkT("Decoding failed!"),
+
+/* 9 */
+dkT("Encoding failed!"),
+
+/* 10 */
+dkT("Processing failed!"),
+
+/* 11 */
+dkT("Further decoding failures!"),
+
+/* 12 */
+dkT("Further encoding failures!"),
+
+/* 13 */
+dkT("Further processing failures!"),
+
+/* 14 */
+dkT("Decoding failed!\n\tByte:"),
+
+/* 15 */
+dkT("Encoding failed!\n\tByte:"),
+
+/* 16 */
+dkT("Processing failed!\n\tByte:"),
+
+/* 17 */
+dkT(",\n\tCharacter:"),
+
+/* 18 */
+dkT(",\n\tPosition in line:"),
+
+/* 19 */
+dkT("."),
+
+/* 20 */
+dkT("Failed to read from file!"),
+
+/* 21 */
+dkT("Failed to set up text stream processor!"),
+
+/* 22 */
+dkT("Path too long for pattern\n\""),
+
+/* 23 */
+dkT("\"!"),
+
+/* 24 */
+dkT("No such file:\n\""),
+
+/* 25 */
+dkT("\"!"),
+
+/* 26 */
+dkT("Failed to close database!"),
+
+/* 27 */
+dkT("Database name is required!"),
+
+/* 28 */
+dkT("Illegal text encoding: \""),
+
+/* 29 */
+dkT("\"!"),
+
+/* 30 */
+dkT("Aborted by signal!"),
+
+NULL
+
+
+#line 531 "dk-t2db.ctr"
+};
+
+
+
+/** Options.
+*/
+static const dk4_option_specification_t dk_t2db_options[] = {
+ { dkT('a'), dkT("add"), DK4_OPT_ARG_NONE } ,
+ { dkT('R'), dkT("reset"), DK4_OPT_ARG_NONE } ,
+ { dkT('l'), dkT("line-size"), DK4_OPT_ARG_SIZE } ,
+ { dkT('k'), dkT("key-buffer-size"), DK4_OPT_ARG_SIZE } ,
+ { dkT('v'), dkT("value-buffer-size"), DK4_OPT_ARG_SIZE } ,
+ { dkT('i'), dkT("input-encoding"), DK4_OPT_ARG_STRING } ,
+ { dkT('c'), dkT("comment"), DK4_OPT_ARG_STRING }
+};
+
+
+
+/** Input line buffer.
+*/
+static dkChar linebuf[1024];
+
+
+
+/** Localized or default messages.
+*/
+static const dkChar * const * dk_t2db_msg = dk_t2db_kw_def;
+
+
+
+/** Pointer to input buffer to use.
+*/
+static dkChar *pibuf = linebuf;
+
+
+
+/** Allocated input buffer, if necessary.
+*/
+static dkChar *abuf = NULL;
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** String containing the comment character.
+*/
+static const dkChar *comment = NULL;
+
+
+
+
+/** Number of elements in the dk_t2db_options array.
+*/
+static const size_t dk_t2db_sz_options =
+sizeof(dk_t2db_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Input buffer size.
+*/
+static size_t szpibuf = DK4_SIZEOF(linebuf,dkChar);
+
+
+
+/** Database key size.
+*/
+static size_t szkey = DK4_SIZEOF(linebuf,dkChar) / 2;
+
+
+
+/** Database value size.
+*/
+static size_t szval = DK4_SIZEOF(linebuf,dkChar) / 2;
+
+
+
+/** Number of elements in the dk_t2db_msg array.
+*/
+static size_t dk_t2db_sz_msg =
+(sizeof(dk_t2db_kw_def)/sizeof(DK4_PDKCHAR) - 1);
+
+
+
+/** Exit status code.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+/** Flag: Truncate existing database.
+*/
+static int trunc = 1;
+
+
+
+/** Expected encoding when processing an input file.
+*/
+static int efe = DK4_FILE_ENCODING_ASCII;
+
+
+
+/** Expected encoding when processing standard input.
+*/
+static int ese = DK4_FILE_ENCODING_ASCII;
+
+
+
+/** Number of decoding errors already occured.
+*/
+static int dk_t2db_dec_err = 0;
+
+
+
+/** Number of encoding errors already occured.
+*/
+static int dk_t2db_enc_err = 0;
+
+
+
+/** Number of processing errors already occured.
+*/
+static int dk_t2db_pro_err = 0;
+
+
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+/** Pass a volatile pointer to an atomic integer.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ptr Address of atomic integer variable.
+ @return The unmodified pointer.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+
+
+/** Check whether we can continue or if a signal was received.
+ @param check_pipe Flag: Check for occured SIGPIPE signal too.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(void)
+{
+ int back = 1;
+ if (0 != sig_read_atomic(&sig_had_int )) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+static
+void
+dk_t2db_remove_crnl(dkChar *lptr)
+{
+ while (dkT('\0') != *lptr) {
+ if (dkT('\n') == *lptr) {
+ *lptr = dkT('\0');
+ } else {
+ if (dkT('\r') == *lptr) {
+ *lptr = dkT('\0');
+ } else {
+ lptr++;
+ }
+ }
+ }
+}
+
+
+
+/** Handler function to process one text line.
+ @param obj Object to modify.
+ @param line Text line to process.
+ @param lineno Line number of text line.
+ @param erp Error report, may be NULL.
+ @return One from:
+ - DK4_TSP_RES_OK for successful processing,
+ - DK4_TSP_RES_ERROR on errors we can recover from,
+ - DK4_TSP_RES_FATAL on errors requiring to abort processing.
+*/
+int
+dk_t2db_line_handler(
+ void *obj,
+ dkChar *line,
+ dk4_um_t lineno,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er;
+ dk4_dbi_t *dbiptr;
+ dkChar *p1;
+ dkChar *p2;
+ int back = DK4_TSP_RES_OK;
+ int must = 1; /* Must process line */
+
+
+#line 793 "dk-t2db.ctr"
+ p1 = dk4str_start(line, NULL);
+ if (NULL != p1) {
+
+#line 795 "dk-t2db.ctr"
+ if (NULL != comment) {
+
+#line 796 "dk-t2db.ctr"
+ if (*comment == *p1) {
+ must = 0;
+
+#line 798 "dk-t2db.ctr"
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 801 "dk-t2db.ctr"
+ }
+#endif
+ }
+ if (0 != must) {
+ /* Not a comment line */
+ dk_t2db_remove_crnl(p1);
+ dbiptr = (dk4_dbi_t *)obj;
+ dk4error_init(&er);
+ p2 = dk4str_next(p1, NULL);
+ if (NULL != p2) {
+
+#line 811 "dk-t2db.ctr"
+ /* Add or change entry */
+ if (0 == dk4dbi_text_set(dbiptr, p1, p2, &er)) {
+ dk4error_copy(erp, &er);
+
+#line 814 "dk-t2db.ctr"
+ back = DK4_TSP_RES_ERROR;
+ exval = EXIT_FAILURE;
+ dk4app_log_5(
+ app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 3, 4, 5, p1, p2
+ );
+ }
+ } else {
+
+#line 821 "dk-t2db.ctr"
+ /* Delete entry */
+ if (0 == dk4dbi_text_del(dbiptr, p1, &er)) {
+ dk4error_copy(erp, &er);
+
+#line 824 "dk-t2db.ctr"
+ back = DK4_TSP_RES_ERROR;
+ exval = EXIT_FAILURE;
+ dk4app_log_3(
+ app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 6, 7, p1
+ );
+ }
+ }
+ }
+ }
+
+
+#line 834 "dk-t2db.ctr"
+ return back;
+}
+
+
+/** Report an error with position in source line.
+ @param i1 Index of first message part in array.
+ @param i2 Index of alternative first message part.
+ @param bno Byte processed.
+ @param lno Current line number.
+ @param cno Current character number.
+ @param cil Current character number in line.
+*/
+static
+void
+dk_t2db_report_with_position(
+ size_t i1,
+ size_t i2,
+ dk4_um_t bno,
+ dk4_um_t lno,
+ dk4_um_t cno,
+ dk4_um_t cil
+)
+{
+ dkChar b1[8*(1+sizeof(dk4_um_t))];
+ dkChar b2[8*(1+sizeof(dk4_um_t))];
+ dkChar b3[8*(1+sizeof(dk4_um_t))];
+ dk4_um_t oldlogline = (dk4_um_t)0UL;
+ int allbuffersok = 0;
+
+ oldlogline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_line(app, lno);
+ if (0 != dk4ma_write_decimal_unsigned(b3,DK4_SIZEOF(b3,dkChar),cil,0,NULL)) {
+ if (0 != dk4ma_write_decimal_unsigned(b2,DK4_SIZEOF(b2,dkChar),cno,0,NULL)) {
+ if (0 != dk4ma_write_decimal_unsigned(b1,DK4_SIZEOF(b1,dkChar),bno,0,NULL)) {
+ allbuffersok = 1;
+ }
+ }
+ }
+ if (0 != allbuffersok) {
+ dk4app_log_7(
+ app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR,
+ i1, 17, 18, 19, b1, b2, b3
+ );
+ } else {
+ dk4app_log_1(
+ app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, i2
+ );
+ }
+ dk4app_set_log_source_line(app, oldlogline);
+}
+
+
+/** Report errors from encoding/decoding or processing.
+*/
+static
+void
+dk_t2db_report_errors(dk4_er_t *er_en, dk4_er_t *er_pr)
+{
+
+ if (NULL != er_en) {
+ switch (er_en->ec) {
+ case DK4_E_DECODING_FAILED: {
+ switch (dk_t2db_dec_err) {
+ case 0: case 1: {
+ dk_t2db_report_with_position(
+ 14, 8,
+ er_en->dt.fpos.byteno,
+ er_en->dt.fpos.lineno,
+ er_en->dt.fpos.charno,
+ er_en->dt.fpos.charinline
+ );
+ } break;
+ case 2: {
+ dk4app_log_1(
+ app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 11
+ );
+ } break;
+ }
+ if (3 > dk_t2db_dec_err) { dk_t2db_dec_err++; }
+ } break;
+ case DK4_E_ENCODING_FAILED: {
+ switch (dk_t2db_enc_err) {
+ case 0: case 1: {
+ dk_t2db_report_with_position(
+ 15, 9,
+ er_en->dt.fpos.byteno,
+ er_en->dt.fpos.lineno,
+ er_en->dt.fpos.charno,
+ er_en->dt.fpos.charinline
+ );
+ } break;
+ case 2: {
+ dk4app_log_1(
+ app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 12
+ );
+ } break;
+ }
+ if (3 > dk_t2db_enc_err) { dk_t2db_enc_err++; }
+ } break;
+ }
+ }
+ if (NULL != er_pr) {
+ if (DK4_E_NONE != er_pr->ec) {
+ switch (dk_t2db_pro_err) {
+ case 0: case 1: {
+ dk_t2db_report_with_position(
+ 16, 10,
+ er_pr->dt.fpos.byteno,
+ er_pr->dt.fpos.lineno,
+ er_pr->dt.fpos.charno,
+ er_pr->dt.fpos.charinline
+ );
+ } break;
+ case 2: {
+ dk4app_log_1(
+ app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 13
+ );
+ } break;
+ }
+ if (3 > dk_t2db_pro_err) { dk_t2db_pro_err++; }
+ }
+ }
+
+
+}
+
+
+
+/** Process one input file.
+ @param dbiptr Database to modify.
+ @param infile Input file to process, must be in binary mode.
+ @param filename File name of input file.
+ @param eie Expected input encoding.
+*/
+static
+void
+dk_t2db_run_for_file(
+ dk4_dbi_t *dbiptr,
+ FILE *infile,
+ const dkChar *filename,
+ int eie
+)
+{
+ dk4_tspdk_t tspdk;
+ dk4_er_t er_en;
+ dk4_er_t er_pr;
+ const dkChar *oldsourcefile;
+ int res;
+ int cc;
+ int c;
+ unsigned char ub;
+
+ dk_t2db_dec_err = 0;
+ dk_t2db_enc_err = 0;
+ dk_t2db_pro_err = 0;
+ oldsourcefile = dk4app_get_log_source_file(app);
+ res = dk4tspdk_setup_line(
+ &tspdk, dbiptr, dk_t2db_line_handler, pibuf, szpibuf,
+ dk4app_get_encoding(app), eie, NULL
+ );
+ if (0 != res) {
+ if (DK4_ENCODING_UTF8 == dk4app_get_encoding(app)) {
+ dk4tspdk_enable_utf8_pass_through(&tspdk, 1);
+ }
+ dk4error_init(&er_en);
+ dk4error_init(&er_pr);
+ cc = 1;
+ do {
+ if (0 != sig_can_continue()) {
+ c = fgetc(infile);
+ if (EOF != c) {
+ ub = (unsigned char)c;
+ switch (dk4tspdk_add_one_byte(&tspdk, ub)) {
+ case DK4_TSP_RES_FATAL : {
+ cc = -1;
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tspdk);
+ dk_t2db_report_errors(&er_en, &er_pr);
+ } break;
+ case DK4_TSP_RES_ERROR : {
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tspdk);
+ dk_t2db_report_errors(&er_en, &er_pr);
+ } break;
+ }
+ } else {
+ cc = 0;
+ if (0 != ferror(infile)) {
+ cc = -1;
+ /* ERROR: Failed to read from file */
+ dk4app_log_1(
+ app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 20
+ );
+ exval = EXIT_FAILURE;
+ }
+ }
+ } else {
+ cc = -1;
+ }
+ } while (1 == cc);
+ if (0 == cc) {
+ switch (dk4tspdk_finish(&tspdk)) {
+ case DK4_TSP_RES_FATAL : {
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tspdk);
+ dk_t2db_report_errors(&er_en, &er_pr);
+ } break;
+ case DK4_TSP_RES_ERROR : {
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tspdk);
+ dk_t2db_report_errors(&er_en, &er_pr);
+ } break;
+ }
+ }
+ } else {
+ /* ERROR: Failed to set up text stream processor */
+ dk4app_log_1(
+ app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 21
+ );
+ exval = EXIT_FAILURE;
+ }
+ dk4app_set_log_source_file(app, oldsourcefile);
+}
+
+
+
+/** Process one input file specified by file name.
+ @param dbiptr Database to modify.
+ @param filename Name of file to process.
+*/
+static
+void
+dk_t2db_process_name(dk4_dbi_t *dbiptr, const dkChar *filename)
+{
+#if DK4_ON_WINDOWS
+ dkChar buf[DK4_MAX_PATH];
+#endif
+ FILE *fipo;
+#if DK4_ON_WINDOWS
+ dk4_dir_t *fne;
+ const dkChar *expfn;
+ const dkChar *expth;
+ size_t szbuf = DK4_SIZEOF(buf,dkChar);
+ int any_file_found = 0;
+ int cc;
+#endif
+
+ if (NULL != filename) {
+#if DK4_ON_WINDOWS
+ if (0 != dk4path_must_expand(filename)) {
+ fne = dk4app_fne_open(filename, app);
+ if (NULL != fne) {
+ cc = 1;
+ do {
+ if (0 != sig_can_continue()) {
+ expfn = dk4dir_next_file(fne);
+ if (NULL != expfn) {
+ any_file_found = 1;
+ expth = dk4dir_get_path(fne);
+ if (NULL != expth) {
+ if (0 != dk4str_cpy_s(buf, szbuf, expth, NULL)) {
+ if (0 != dk4str_cat_s(buf, szbuf, dk_t2db_kwnl[8], NULL)) {
+ if (0 != dk4str_cat_s(buf, szbuf, expfn, NULL)) {
+ fipo = dk4fopen_app(
+ buf, dk_t2db_kwnl[7], DK4_FOPEN_SC_IS_REGULAR, app
+ );
+ if (NULL != fipo) {
+ dk_t2db_run_for_file(dbiptr, fipo, buf, efe);
+ fclose(fipo);
+ } else {
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Path too long */
+ dk4app_log_3(
+ app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR,
+ 22, 23, filename
+ );
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Path too long */
+ dk4app_log_3(
+ app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR,
+ 22, 23, filename
+ );
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Path too long */
+ dk4app_log_3(
+ app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR,
+ 22, 23, filename
+ );
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ fipo = dk4fopen_app(
+ expfn, dk_t2db_kwnl[7], DK4_FOPEN_SC_IS_REGULAR, app
+ );
+ if (NULL != fipo) {
+ dk_t2db_run_for_file(dbiptr, fipo, expfn, efe);
+ fclose(fipo);
+ } else {
+ exval = EXIT_FAILURE;
+ }
+ }
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = -1;
+ }
+ } while (1 == cc);
+ dk4dir_close(fne);
+ if (0 == any_file_found) {
+ /* ERROR: No such file */
+ dk4app_log_3(
+ app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR,
+ 24, 25, filename
+ );
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ exval = EXIT_FAILURE;
+ }
+ } else {
+#endif
+ fipo = dk4fopen_app(
+ filename, dk_t2db_kwnl[7], DK4_FOPEN_SC_IS_REGULAR, app
+ );
+ if (NULL != fipo) {
+ dk_t2db_run_for_file(dbiptr, fipo, filename, efe);
+ fclose(fipo);
+ } else {
+ exval = EXIT_FAILURE;
+ }
+#if DK4_ON_WINDOWS
+ }
+#endif
+ }
+}
+
+
+
+/** Run for opened database.
+ @param dbiptr Database to modify.
+*/
+static
+void
+dk_t2db_run_with_dbi(dk4_dbi_t *dbiptr)
+{
+ int xargc;
+ int i;
+#if DK4_ON_WINDOWS
+ int oldmode;
+#endif
+
+ xargc = dk4app_get_argc(app);
+ if (1 < xargc) {
+ for (i = 0; ((i < (xargc - 1)) && (0 != sig_can_continue())); i++) {
+ dk_t2db_process_name(dbiptr, dk4app_get_argv(app, i));
+ }
+ } else {
+#if DK4_ON_WINDOWS
+ oldmode = _setmode(_fileno(stdin), _O_BINARY);
+#endif
+ dk_t2db_run_for_file(dbiptr, stdin, dk_t2db_msg[2], ese);
+#if DK4_ON_WINDOWS
+ _setmode(_fileno(stdin), oldmode);
+#endif
+ }
+}
+
+
+
+/** Open database and do processing.
+*/
+static
+void
+dk_t2db_run_with_buffers(void)
+{
+ dk4_er_t er;
+ dk4_dbi_t *dbiptr;
+ const dkChar *fn;
+
+ fn = dk4app_get_argv(app, (dk4app_get_argc(app)-1));
+ if ((0 != sig_can_continue()) && (NULL != fn)) {
+ dbiptr = dk4dbi_open_sizes_app(fn, 1, trunc, szkey, szval, NULL, app);
+ if (NULL != dbiptr) {
+ exval = EXIT_SUCCESS;
+ dk_t2db_run_with_dbi(dbiptr);
+ dk4error_init(&er);
+ if (0 == dk4dbi_close(dbiptr, &er)) {
+ /* ERROR: Failed to close database */
+ dk4app_log_1(
+ app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 26
+ );
+ exval = EXIT_FAILURE;
+ }
+ }
+ }
+}
+
+
+
+/** Process preferences and command line options,
+ allocate buffer if necessary and do processing.
+*/
+static
+void
+dk_t2db_normal_run(void)
+{
+ dk4_er_t er;
+ const dkChar *oaptr;
+ size_t i;
+ int enc = DK4_FILE_ENCODING_ASCII;
+ int bom = 0;
+
+ /* Check cmd line arguments, must have at least a database name.
+ */
+ if (0 == dk4app_get_argc(app)) {
+ /* ERROR: Database name required. */
+ dk4app_log_1(
+ app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 27
+ );
+ goto finished;
+ }
+
+ /* Process preferences and options.
+ */
+ if (0 == dk4app_opt_is_set_short(app, dkT('R'), NULL)) {
+ if (0 != dk4app_pref_get_size(&i, app, dk_t2db_kwnl[4], 0)) {
+ szpibuf = i;
+ }
+ if (0 != dk4app_pref_get_size(&i, app, dk_t2db_kwnl[5], 0)) {
+ szkey = i;
+ }
+ if (0 != dk4app_pref_get_size(&i, app, dk_t2db_kwnl[6], 0)) {
+ szval = i;
+ }
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('a'), NULL)) {
+ trunc = 0;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('l'), NULL)) {
+ if (0 != dk4app_opt_get_size_short(&i, app, dkT('l'), NULL)) {
+ szpibuf = i;
+ }
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('k'), NULL)) {
+ if (0 != dk4app_opt_get_size_short(&i, app, dkT('k'), NULL)) {
+ szkey = i;
+ }
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('v'), NULL)) {
+ if (0 != dk4app_opt_get_size_short(&i, app, dkT('v'), NULL)) {
+ szval = i;
+ }
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('i'), NULL)) {
+ oaptr = dk4app_opt_get_string_ptr_short(app, dkT('i'), NULL);
+ if (NULL != oaptr) {
+ if (0 != dk4enc_find(&enc, &bom, oaptr, NULL)) {
+ efe = ese = enc;
+ } else {
+ /* ERROR: Encoding not found */
+ dk4app_log_3(
+ app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 28, 29, oaptr
+ );
+ goto finished;
+ }
+ }
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('c'), NULL)) {
+
+
+#line 1310 "dk-t2db.ctr"
+ oaptr = dk4app_opt_get_string_ptr_short(app, dkT('c'), NULL);
+ if (NULL != oaptr) {
+
+#line 1312 "dk-t2db.ctr"
+ comment = oaptr;
+
+#line 1313 "dk-t2db.ctr"
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 1316 "dk-t2db.ctr"
+ }
+#endif
+ }
+ if (0 == szpibuf) { szpibuf = DK4_SIZEOF(linebuf,dkChar); }
+ if (0 == szkey) { szkey = DK4_SIZEOF(linebuf,dkChar) / 2; }
+ if (0 == szval) { szval = DK4_SIZEOF(linebuf,dkChar) / 2; }
+
+ /* Calculate key and value buffer size in bytes.
+ */
+ dk4error_init(&er);
+ szkey = dk4ma_size_t_mul(szkey, sizeof(dkChar), &er);
+ szval = dk4ma_size_t_mul(szval, sizeof(dkChar), &er);
+ if (DK4_E_NONE != er.ec) {
+ /* ERROR: Mathematical overflow in size calculation */
+ dk4app_log_base1(app, DK4_LL_ERROR, 82);
+ goto finished;
+ }
+
+ /* Allocate larger buffer if necessary.
+ */
+ if (DK4_SIZEOF(linebuf,dkChar) < szpibuf) {
+ abuf = dk4mem_new_app(dkChar,szpibuf,app);
+ if (NULL != abuf) {
+ pibuf = abuf;
+ } else {
+ goto finished;
+ }
+ }
+
+ /* Now do the processing.
+ */
+ dk_t2db_run_with_buffers();
+
+ /* Clean up.
+ */
+ finished:
+ dk4mem_release(abuf) ;
+}
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+dk_t2db_run_with_signal_handlers(void)
+{
+ struct sigaction oint;
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+ int success = 0;
+
+ /* Set up signal handling for SIGINT.
+ */
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ dk_t2db_normal_run();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+dk_t2db_run_with_signal_handlers(void)
+{
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ dk_t2db_normal_run();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+dk_t2db_run_with_signal_handlers(void)
+{
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ dk_t2db_normal_run();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+dk_t2db_run_with_signal_handlers(void)
+{
+ dk_t2db_normal_run();
+}
+#endif
+#endif
+#endif
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+
+
+#line 1498 "dk-t2db.ctr"
+
+
+#line 1499 "dk-t2db.ctr"
+ dk4fput_initialize_stderr();
+ app = dk4app_open_cmd(
+ argc, argv,
+ dk_t2db_options, dk_t2db_sz_options,
+ dk_t2db_kwnl[0], version_text,
+ dk_t2db_kwnl[1], help_text, license_text
+ );
+ if (NULL != app) {
+ ese = dk4app_get_stdin_encoding(app);
+ efe = dk4app_get_file_in_encoding(app);
+ dk_t2db_sz_msg = dk4app_string_table_size(dk_t2db_kw_def);
+ dk_t2db_msg = dk4app_string_table(app, dk_t2db_kwnl[3], dk_t2db_kw_def);
+ if (0 != dk4app_can_run_normally(app)) {
+ dk_t2db_run_with_signal_handlers();
+ if (0 != sig_read_atomic(&sig_had_int)) {
+ /* ERROR: Aborted by SIGINT */
+ dk4app_log_1(
+ app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 30
+ );
+ exval = EXIT_FAILURE;
+ }
+ if (0 != sig_read_atomic(&sig_had_term)) {
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ dk4app_close(app);
+ } else {
+ dk4fputs(dk_t2db_kwnl[2], stderr, NULL);
+ }
+ fflush(stderr);
+ dk4fput_cleanup_stderr();
+
+
+#line 1535 "dk-t2db.ctr"
+
+
+#line 1536 "dk-t2db.ctr"
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/dk-t2db.ctr b/support/dktools/dk-t2db.ctr
new file mode 100644
index 0000000000..ab13c0e9e5
--- /dev/null
+++ b/support/dktools/dk-t2db.ctr
@@ -0,0 +1,1538 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+
+
+%% module
+
+/*
+ Convert text to database.
+
+ See help_text below.
+*/
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4const.h"
+#include "dk4mem.h"
+#include "dk4mema.h"
+#include "dk4error.h"
+#include "dk4dbi.h"
+#include "dk4dbit8.h"
+#include "dk4dbitw.h"
+#include "dk4dbit.h"
+#include "dk4dbia.h"
+#include "dk4fput.h"
+#include "dk4vers.h"
+#include "dk4app.h"
+#include "dk4aopt.h"
+#include "dk4maasz.h"
+#include "dk4enc.h"
+#include "dk4fopt.h"
+#include "dk4fopda.h"
+#include "dk4tspdk.h"
+#include "dk4strd.h"
+#include "dk4maodd.h"
+#include "dk4mpl.h"
+#include "dk4pathd.h"
+
+
+
+$!trace-include
+
+
+
+static const dkChar * const help_text[] = {
+$!text macro=dkT
+
+dk-t2db - Convert text to simple database
+-----------------------------------------
+
+dk-t2db [<option>] [<file>...] <database>
+
+Options:
+
+-a --add Append to existing database.
+-l <size> --line-size=<size> Line buffer size.
+-k <size> --key-buffer-size=<size> Key buffer size.
+-v <size> --value-buffer-size=<size> Value buffer size.
+-i <string> --input-encoding=<string> Expected input encoding.
+
+--help Show short help text.
+--manual *** SHOW FULL MANUAL ***
+--version Show version information.
+--license Show license information.
+
+$!end
+};
+
+
+/** License conditions.
+*/
+static const dkChar * const license_text[] = {
+$!text macro=dkT,preprocessor
+
+This software uses code from the following projects, either directly or as
+a library:
+
+dktools Dirk Krause's tools and libraries.
+ See http://dktools.sourceforge.net/ for more information.
+#if DK4_HAVE_ZLIB_H
+
+zlib Data compression library.
+ See http://www.zlib.net/ for more information.
+#endif
+#if DK4_HAVE_BZLIB_H
+
+bzip2 Data compression program and library.
+ See http://www.bzip.org/ for more information.
+#endif
+
+All the licenses below apply to the program.
+Licenses for used libraries are shown as found on my Scientific Linux 6.x
+computer in the /usr/share/doc directory on 2015-04-01. Check the project
+homepages of the used libraries for additional information and/or updated
+license terms.
+
+
+DK tools and libraries license
+==============================
+Copyright (c) 2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+
+
+Berkeley DB license
+===================
+This package was debianized by Clint Adams <schizo@debian.org> on
+Wed, 25 Jul 2007 20:37:51 +0700
+
+It was downloaded from
+http://www.oracle.com/technology/software/products/berkeley-db/db/index.html
+
+Copyright and license:
+
+The following is the license that applies to this copy of the Berkeley DB
+software. For a license to use the Berkeley DB software under conditions
+other than those described here, or to purchase support for this software,
+please contact Oracle at berkeleydb-info_us@oracle.com.
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+/*
+ * Copyright (c) 1990, 2010 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Redistributions in any form must be accompanied by information on
+ * how to obtain complete source code for the DB software and any
+ * accompanying software that uses the DB software. The source code
+ * must either be included in the distribution or be available for no
+ * more than the cost of distribution plus a nominal fee, and must be
+ * freely redistributable under reasonable conditions. For an
+ * executable file, complete source code means the source code for all
+ * modules it contains. It does not include source code for modules or
+ * files that typically accompany the major components of the operating
+ * system on which the executable file runs.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ORACLE ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ * NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL ORACLE BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * Copyright (c) 1990, 1993, 1994, 1995
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * Copyright (c) 1995, 1996
+ * The President and Fellows of Harvard University. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY HARVARD AND ITS CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HARVARD OR ITS CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#endif
+#if DK4_HAVE_ZLIB_H
+
+
+Zlib license
+============
+(C) 1995-2004 Jean-loup Gailly and Mark Adler
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+
+Jean-loup Gailly Mark Adler
+jloup@gzip.org madler@alumni.caltech.edu
+#endif
+#if DK4_HAVE_BZLIB_H
+
+
+Bzip2 and libbzip2 library license
+==================================
+This program, "bzip2", the associated library "libbzip2", and all
+documentation, are copyright (C) 1996-2007 Julian R Seward. All
+rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+3. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Julian Seward, jseward@bzip.org
+bzip2/libbzip2 version 1.0.5 of 10 December 2007
+#endif
+$!end
+};
+
+
+
+/** Version text.
+*/
+static const dkChar version_text[] = {
+ DKT_VERSION_DK
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+ dkT(" bdb")
+#endif
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+ dkT(" ndbm")
+#endif
+ dkT(" mem")
+};
+
+
+
+/** Constant texts used by the module, not localized.
+*/
+const dkChar * const dk_t2db_kwnl[] = {
+$!string-table macro=dkT
+#
+# 0 Program group name
+#
+dktools
+#
+# 1 Help text file name
+#
+dk-t2db.txt
+#
+# 2 Error message: Application startup failed!
+#
+ERROR: Application startup failed!\n
+#
+# 3 String table file name
+#
+dk-t2db.str
+#
+# 4 5 6 Preference names for buffer sizes
+#
+line.size
+text-db.key.max-size
+text-db.value.max-size
+#
+# 7 File open mode for binary reading
+#
+rb
+#
+# 8 Path component separator
+#
+\\
+$!end
+};
+
+
+
+/** Constant string used by the module, replaced by localized
+ texts if available.
+*/
+const dkChar * const dk_t2db_kw_def[] = {
+$!string-table macro=dkT
+#
+# 0 Error: Failed to set up signal handlers!
+#
+Failed to set up signal handlers!
+#
+# 1 Error: Failed to restore previous signal handlers!
+#
+Failed to restore previous signal handlers!
+#
+# 2 Default file name to be used for standard input.
+#
+<standard input>
+#
+# 3 4 5 Error: Failed to set database entry "key"="value"!
+#
+Failed to set database entry\n"
+"="
+"!
+#
+# 6 7 Error: Failed to delete database entry "key"!
+#
+Failed to delete database entry\n"
+"!
+#
+# 8 9 10 11 12 13
+#
+Decoding failed!
+Encoding failed!
+Processing failed!
+Further decoding failures!
+Further encoding failures!
+Further processing failures!
+#
+# 14 15 16 17 18 19
+#
+Decoding failed!\n\tByte:
+Encoding failed!\n\tByte:
+Processing failed!\n\tByte:
+,\n\tCharacter:
+,\n\tPosition in line:
+.
+#
+# 20 ERROR: Failed to read from file!
+#
+Failed to read from file!
+#
+# 21 ERROR: Failed to set up text stream processor!
+#
+Failed to set up text stream processor!
+#
+# 22 23 ERROR: Path too long for pattern "..."!
+#
+Path too long for pattern\n"
+"!
+#
+# 24 25 ERROR: No such file "..."!
+#
+No such file:\n"
+"!
+#
+# 26 ERROR: Failed to close database!
+#
+Failed to close database!
+#
+# 27 ERROR: Database name is required!
+#
+Database name is required!
+#
+# 28 29 ERROR: Illegal text encoding "..."!
+#
+Illegal text encoding: "
+"!
+#
+# 30 ERROR: Aborted by signal
+#
+Aborted by signal!
+$!end
+};
+
+
+
+/** Options.
+*/
+static const dk4_option_specification_t dk_t2db_options[] = {
+ { dkT('a'), dkT("add"), DK4_OPT_ARG_NONE } ,
+ { dkT('R'), dkT("reset"), DK4_OPT_ARG_NONE } ,
+ { dkT('l'), dkT("line-size"), DK4_OPT_ARG_SIZE } ,
+ { dkT('k'), dkT("key-buffer-size"), DK4_OPT_ARG_SIZE } ,
+ { dkT('v'), dkT("value-buffer-size"), DK4_OPT_ARG_SIZE } ,
+ { dkT('i'), dkT("input-encoding"), DK4_OPT_ARG_STRING } ,
+ { dkT('c'), dkT("comment"), DK4_OPT_ARG_STRING }
+};
+
+
+
+/** Input line buffer.
+*/
+static dkChar linebuf[1024];
+
+
+
+/** Localized or default messages.
+*/
+static const dkChar * const * dk_t2db_msg = dk_t2db_kw_def;
+
+
+
+/** Pointer to input buffer to use.
+*/
+static dkChar *pibuf = linebuf;
+
+
+
+/** Allocated input buffer, if necessary.
+*/
+static dkChar *abuf = NULL;
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** String containing the comment character.
+*/
+static const dkChar *comment = NULL;
+
+
+
+
+/** Number of elements in the dk_t2db_options array.
+*/
+static const size_t dk_t2db_sz_options =
+sizeof(dk_t2db_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Input buffer size.
+*/
+static size_t szpibuf = DK4_SIZEOF(linebuf,dkChar);
+
+
+
+/** Database key size.
+*/
+static size_t szkey = DK4_SIZEOF(linebuf,dkChar) / 2;
+
+
+
+/** Database value size.
+*/
+static size_t szval = DK4_SIZEOF(linebuf,dkChar) / 2;
+
+
+
+/** Number of elements in the dk_t2db_msg array.
+*/
+static size_t dk_t2db_sz_msg =
+(sizeof(dk_t2db_kw_def)/sizeof(DK4_PDKCHAR) - 1);
+
+
+
+/** Exit status code.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+/** Flag: Truncate existing database.
+*/
+static int trunc = 1;
+
+
+
+/** Expected encoding when processing an input file.
+*/
+static int efe = DK4_FILE_ENCODING_ASCII;
+
+
+
+/** Expected encoding when processing standard input.
+*/
+static int ese = DK4_FILE_ENCODING_ASCII;
+
+
+
+/** Number of decoding errors already occured.
+*/
+static int dk_t2db_dec_err = 0;
+
+
+
+/** Number of encoding errors already occured.
+*/
+static int dk_t2db_enc_err = 0;
+
+
+
+/** Number of processing errors already occured.
+*/
+static int dk_t2db_pro_err = 0;
+
+
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+/** Pass a volatile pointer to an atomic integer.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ptr Address of atomic integer variable.
+ @return The unmodified pointer.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+
+
+/** Check whether we can continue or if a signal was received.
+ @param check_pipe Flag: Check for occured SIGPIPE signal too.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(void)
+{
+ int back = 1;
+ if (0 != sig_read_atomic(&sig_had_int )) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+static
+void
+dk_t2db_remove_crnl(dkChar *lptr)
+{
+ while (dkT('\0') != *lptr) {
+ if (dkT('\n') == *lptr) {
+ *lptr = dkT('\0');
+ } else {
+ if (dkT('\r') == *lptr) {
+ *lptr = dkT('\0');
+ } else {
+ lptr++;
+ }
+ }
+ }
+}
+
+
+
+/** Handler function to process one text line.
+ @param obj Object to modify.
+ @param line Text line to process.
+ @param lineno Line number of text line.
+ @param erp Error report, may be NULL.
+ @return One from:
+ - DK4_TSP_RES_OK for successful processing,
+ - DK4_TSP_RES_ERROR on errors we can recover from,
+ - DK4_TSP_RES_FATAL on errors requiring to abort processing.
+*/
+int
+dk_t2db_line_handler(
+ void *obj,
+ dkChar *line,
+ dk4_um_t lineno,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er;
+ dk4_dbi_t *dbiptr;
+ dkChar *p1;
+ dkChar *p2;
+ int back = DK4_TSP_RES_OK;
+ int must = 1; /* Must process line */
+ $? "+ dk_t2db_line_handler \"%!ds\"", line
+ p1 = dk4str_start(line, NULL);
+ if (NULL != p1) { $? ". have text"
+ if (NULL != comment) { $? ". have comment \"%!ds\"", comment
+ if (*comment == *p1) {
+ must = 0; $? ". comment line"
+ }
+#if TRACE_DEBUG
+ else { $? ". not a comment line"
+ }
+#endif
+ }
+ if (0 != must) {
+ /* Not a comment line */
+ dk_t2db_remove_crnl(p1);
+ dbiptr = (dk4_dbi_t *)obj;
+ dk4error_init(&er);
+ p2 = dk4str_next(p1, NULL);
+ if (NULL != p2) { $? ". set \"%!ds\"=\"%!ds\"", p1, p2
+ /* Add or change entry */
+ if (0 == dk4dbi_text_set(dbiptr, p1, p2, &er)) {
+ dk4error_copy(erp, &er); $? "! failed"
+ back = DK4_TSP_RES_ERROR;
+ exval = EXIT_FAILURE;
+ dk4app_log_5(
+ app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 3, 4, 5, p1, p2
+ );
+ }
+ } else { $? ". delete \"%!ds\"", p1
+ /* Delete entry */
+ if (0 == dk4dbi_text_del(dbiptr, p1, &er)) {
+ dk4error_copy(erp, &er); $? "! failed"
+ back = DK4_TSP_RES_ERROR;
+ exval = EXIT_FAILURE;
+ dk4app_log_3(
+ app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 6, 7, p1
+ );
+ }
+ }
+ }
+ }
+ $? "- dk_t2db_line_handler %d", back
+ return back;
+}
+
+
+/** Report an error with position in source line.
+ @param i1 Index of first message part in array.
+ @param i2 Index of alternative first message part.
+ @param bno Byte processed.
+ @param lno Current line number.
+ @param cno Current character number.
+ @param cil Current character number in line.
+*/
+static
+void
+dk_t2db_report_with_position(
+ size_t i1,
+ size_t i2,
+ dk4_um_t bno,
+ dk4_um_t lno,
+ dk4_um_t cno,
+ dk4_um_t cil
+)
+{
+ dkChar b1[8*(1+sizeof(dk4_um_t))];
+ dkChar b2[8*(1+sizeof(dk4_um_t))];
+ dkChar b3[8*(1+sizeof(dk4_um_t))];
+ dk4_um_t oldlogline = (dk4_um_t)0UL;
+ int allbuffersok = 0;
+
+ oldlogline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_line(app, lno);
+ if (0 != dk4ma_write_decimal_unsigned(b3,DK4_SIZEOF(b3,dkChar),cil,0,NULL)) {
+ if (0 != dk4ma_write_decimal_unsigned(b2,DK4_SIZEOF(b2,dkChar),cno,0,NULL)) {
+ if (0 != dk4ma_write_decimal_unsigned(b1,DK4_SIZEOF(b1,dkChar),bno,0,NULL)) {
+ allbuffersok = 1;
+ }
+ }
+ }
+ if (0 != allbuffersok) {
+ dk4app_log_7(
+ app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR,
+ i1, 17, 18, 19, b1, b2, b3
+ );
+ } else {
+ dk4app_log_1(
+ app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, i2
+ );
+ }
+ dk4app_set_log_source_line(app, oldlogline);
+}
+
+
+/** Report errors from encoding/decoding or processing.
+*/
+static
+void
+dk_t2db_report_errors(dk4_er_t *er_en, dk4_er_t *er_pr)
+{
+
+ if (NULL != er_en) {
+ switch (er_en->ec) {
+ case DK4_E_DECODING_FAILED: {
+ switch (dk_t2db_dec_err) {
+ case 0: case 1: {
+ dk_t2db_report_with_position(
+ 14, 8,
+ er_en->dt.fpos.byteno,
+ er_en->dt.fpos.lineno,
+ er_en->dt.fpos.charno,
+ er_en->dt.fpos.charinline
+ );
+ } break;
+ case 2: {
+ dk4app_log_1(
+ app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 11
+ );
+ } break;
+ }
+ if (3 > dk_t2db_dec_err) { dk_t2db_dec_err++; }
+ } break;
+ case DK4_E_ENCODING_FAILED: {
+ switch (dk_t2db_enc_err) {
+ case 0: case 1: {
+ dk_t2db_report_with_position(
+ 15, 9,
+ er_en->dt.fpos.byteno,
+ er_en->dt.fpos.lineno,
+ er_en->dt.fpos.charno,
+ er_en->dt.fpos.charinline
+ );
+ } break;
+ case 2: {
+ dk4app_log_1(
+ app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 12
+ );
+ } break;
+ }
+ if (3 > dk_t2db_enc_err) { dk_t2db_enc_err++; }
+ } break;
+ }
+ }
+ if (NULL != er_pr) {
+ if (DK4_E_NONE != er_pr->ec) {
+ switch (dk_t2db_pro_err) {
+ case 0: case 1: {
+ dk_t2db_report_with_position(
+ 16, 10,
+ er_pr->dt.fpos.byteno,
+ er_pr->dt.fpos.lineno,
+ er_pr->dt.fpos.charno,
+ er_pr->dt.fpos.charinline
+ );
+ } break;
+ case 2: {
+ dk4app_log_1(
+ app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 13
+ );
+ } break;
+ }
+ if (3 > dk_t2db_pro_err) { dk_t2db_pro_err++; }
+ }
+ }
+
+
+}
+
+
+
+/** Process one input file.
+ @param dbiptr Database to modify.
+ @param infile Input file to process, must be in binary mode.
+ @param filename File name of input file.
+ @param eie Expected input encoding.
+*/
+static
+void
+dk_t2db_run_for_file(
+ dk4_dbi_t *dbiptr,
+ FILE *infile,
+ const dkChar *filename,
+ int eie
+)
+{
+ dk4_tspdk_t tspdk;
+ dk4_er_t er_en;
+ dk4_er_t er_pr;
+ const dkChar *oldsourcefile;
+ int res;
+ int cc;
+ int c;
+ unsigned char ub;
+
+ dk_t2db_dec_err = 0;
+ dk_t2db_enc_err = 0;
+ dk_t2db_pro_err = 0;
+ oldsourcefile = dk4app_get_log_source_file(app);
+ res = dk4tspdk_setup_line(
+ &tspdk, dbiptr, dk_t2db_line_handler, pibuf, szpibuf,
+ dk4app_get_encoding(app), eie, NULL
+ );
+ if (0 != res) {
+ if (DK4_ENCODING_UTF8 == dk4app_get_encoding(app)) {
+ dk4tspdk_enable_utf8_pass_through(&tspdk, 1);
+ }
+ dk4error_init(&er_en);
+ dk4error_init(&er_pr);
+ cc = 1;
+ do {
+ if (0 != sig_can_continue()) {
+ c = fgetc(infile);
+ if (EOF != c) {
+ ub = (unsigned char)c;
+ switch (dk4tspdk_add_one_byte(&tspdk, ub)) {
+ case DK4_TSP_RES_FATAL : {
+ cc = -1;
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tspdk);
+ dk_t2db_report_errors(&er_en, &er_pr);
+ } break;
+ case DK4_TSP_RES_ERROR : {
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tspdk);
+ dk_t2db_report_errors(&er_en, &er_pr);
+ } break;
+ }
+ } else {
+ cc = 0;
+ if (0 != ferror(infile)) {
+ cc = -1;
+ /* ERROR: Failed to read from file */
+ dk4app_log_1(
+ app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 20
+ );
+ exval = EXIT_FAILURE;
+ }
+ }
+ } else {
+ cc = -1;
+ }
+ } while (1 == cc);
+ if (0 == cc) {
+ switch (dk4tspdk_finish(&tspdk)) {
+ case DK4_TSP_RES_FATAL : {
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tspdk);
+ dk_t2db_report_errors(&er_en, &er_pr);
+ } break;
+ case DK4_TSP_RES_ERROR : {
+ exval = EXIT_FAILURE;
+ dk4tspdk_get_errors(&er_en, &er_pr, &tspdk);
+ dk_t2db_report_errors(&er_en, &er_pr);
+ } break;
+ }
+ }
+ } else {
+ /* ERROR: Failed to set up text stream processor */
+ dk4app_log_1(
+ app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 21
+ );
+ exval = EXIT_FAILURE;
+ }
+ dk4app_set_log_source_file(app, oldsourcefile);
+}
+
+
+
+/** Process one input file specified by file name.
+ @param dbiptr Database to modify.
+ @param filename Name of file to process.
+*/
+static
+void
+dk_t2db_process_name(dk4_dbi_t *dbiptr, const dkChar *filename)
+{
+#if DK4_ON_WINDOWS
+ dkChar buf[DK4_MAX_PATH];
+#endif
+ FILE *fipo;
+#if DK4_ON_WINDOWS
+ dk4_dir_t *fne;
+ const dkChar *expfn;
+ const dkChar *expth;
+ size_t szbuf = DK4_SIZEOF(buf,dkChar);
+ int any_file_found = 0;
+ int cc;
+#endif
+
+ if (NULL != filename) {
+#if DK4_ON_WINDOWS
+ if (0 != dk4path_must_expand(filename)) {
+ fne = dk4app_fne_open(filename, app);
+ if (NULL != fne) {
+ cc = 1;
+ do {
+ if (0 != sig_can_continue()) {
+ expfn = dk4dir_next_file(fne);
+ if (NULL != expfn) {
+ any_file_found = 1;
+ expth = dk4dir_get_path(fne);
+ if (NULL != expth) {
+ if (0 != dk4str_cpy_s(buf, szbuf, expth, NULL)) {
+ if (0 != dk4str_cat_s(buf, szbuf, dk_t2db_kwnl[8], NULL)) {
+ if (0 != dk4str_cat_s(buf, szbuf, expfn, NULL)) {
+ fipo = dk4fopen_app(
+ buf, dk_t2db_kwnl[7], DK4_FOPEN_SC_IS_REGULAR, app
+ );
+ if (NULL != fipo) {
+ dk_t2db_run_for_file(dbiptr, fipo, buf, efe);
+ fclose(fipo);
+ } else {
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Path too long */
+ dk4app_log_3(
+ app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR,
+ 22, 23, filename
+ );
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Path too long */
+ dk4app_log_3(
+ app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR,
+ 22, 23, filename
+ );
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Path too long */
+ dk4app_log_3(
+ app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR,
+ 22, 23, filename
+ );
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ fipo = dk4fopen_app(
+ expfn, dk_t2db_kwnl[7], DK4_FOPEN_SC_IS_REGULAR, app
+ );
+ if (NULL != fipo) {
+ dk_t2db_run_for_file(dbiptr, fipo, expfn, efe);
+ fclose(fipo);
+ } else {
+ exval = EXIT_FAILURE;
+ }
+ }
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = -1;
+ }
+ } while (1 == cc);
+ dk4dir_close(fne);
+ if (0 == any_file_found) {
+ /* ERROR: No such file */
+ dk4app_log_3(
+ app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR,
+ 24, 25, filename
+ );
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ exval = EXIT_FAILURE;
+ }
+ } else {
+#endif
+ fipo = dk4fopen_app(
+ filename, dk_t2db_kwnl[7], DK4_FOPEN_SC_IS_REGULAR, app
+ );
+ if (NULL != fipo) {
+ dk_t2db_run_for_file(dbiptr, fipo, filename, efe);
+ fclose(fipo);
+ } else {
+ exval = EXIT_FAILURE;
+ }
+#if DK4_ON_WINDOWS
+ }
+#endif
+ }
+}
+
+
+
+/** Run for opened database.
+ @param dbiptr Database to modify.
+*/
+static
+void
+dk_t2db_run_with_dbi(dk4_dbi_t *dbiptr)
+{
+ int xargc;
+ int i;
+#if DK4_ON_WINDOWS
+ int oldmode;
+#endif
+
+ xargc = dk4app_get_argc(app);
+ if (1 < xargc) {
+ for (i = 0; ((i < (xargc - 1)) && (0 != sig_can_continue())); i++) {
+ dk_t2db_process_name(dbiptr, dk4app_get_argv(app, i));
+ }
+ } else {
+#if DK4_ON_WINDOWS
+ oldmode = _setmode(_fileno(stdin), _O_BINARY);
+#endif
+ dk_t2db_run_for_file(dbiptr, stdin, dk_t2db_msg[2], ese);
+#if DK4_ON_WINDOWS
+ _setmode(_fileno(stdin), oldmode);
+#endif
+ }
+}
+
+
+
+/** Open database and do processing.
+*/
+static
+void
+dk_t2db_run_with_buffers(void)
+{
+ dk4_er_t er;
+ dk4_dbi_t *dbiptr;
+ const dkChar *fn;
+
+ fn = dk4app_get_argv(app, (dk4app_get_argc(app)-1));
+ if ((0 != sig_can_continue()) && (NULL != fn)) {
+ dbiptr = dk4dbi_open_sizes_app(fn, 1, trunc, szkey, szval, NULL, app);
+ if (NULL != dbiptr) {
+ exval = EXIT_SUCCESS;
+ dk_t2db_run_with_dbi(dbiptr);
+ dk4error_init(&er);
+ if (0 == dk4dbi_close(dbiptr, &er)) {
+ /* ERROR: Failed to close database */
+ dk4app_log_1(
+ app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 26
+ );
+ exval = EXIT_FAILURE;
+ }
+ }
+ }
+}
+
+
+
+/** Process preferences and command line options,
+ allocate buffer if necessary and do processing.
+*/
+static
+void
+dk_t2db_normal_run(void)
+{
+ dk4_er_t er;
+ const dkChar *oaptr;
+ size_t i;
+ int enc = DK4_FILE_ENCODING_ASCII;
+ int bom = 0;
+
+ /* Check cmd line arguments, must have at least a database name.
+ */
+ if (0 == dk4app_get_argc(app)) {
+ /* ERROR: Database name required. */
+ dk4app_log_1(
+ app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 27
+ );
+ goto finished;
+ }
+
+ /* Process preferences and options.
+ */
+ if (0 == dk4app_opt_is_set_short(app, dkT('R'), NULL)) {
+ if (0 != dk4app_pref_get_size(&i, app, dk_t2db_kwnl[4], 0)) {
+ szpibuf = i;
+ }
+ if (0 != dk4app_pref_get_size(&i, app, dk_t2db_kwnl[5], 0)) {
+ szkey = i;
+ }
+ if (0 != dk4app_pref_get_size(&i, app, dk_t2db_kwnl[6], 0)) {
+ szval = i;
+ }
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('a'), NULL)) {
+ trunc = 0;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('l'), NULL)) {
+ if (0 != dk4app_opt_get_size_short(&i, app, dkT('l'), NULL)) {
+ szpibuf = i;
+ }
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('k'), NULL)) {
+ if (0 != dk4app_opt_get_size_short(&i, app, dkT('k'), NULL)) {
+ szkey = i;
+ }
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('v'), NULL)) {
+ if (0 != dk4app_opt_get_size_short(&i, app, dkT('v'), NULL)) {
+ szval = i;
+ }
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('i'), NULL)) {
+ oaptr = dk4app_opt_get_string_ptr_short(app, dkT('i'), NULL);
+ if (NULL != oaptr) {
+ if (0 != dk4enc_find(&enc, &bom, oaptr, NULL)) {
+ efe = ese = enc;
+ } else {
+ /* ERROR: Encoding not found */
+ dk4app_log_3(
+ app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 28, 29, oaptr
+ );
+ goto finished;
+ }
+ }
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('c'), NULL)) {
+ $? ". option -c used"
+ oaptr = dk4app_opt_get_string_ptr_short(app, dkT('c'), NULL);
+ if (NULL != oaptr) { $? ". argument found"
+ comment = oaptr; $? ". comment=\"%!ds\"", comment
+ }
+#if TRACE_DEBUG
+ else { $? "! no argument"
+ }
+#endif
+ }
+ if (0 == szpibuf) { szpibuf = DK4_SIZEOF(linebuf,dkChar); }
+ if (0 == szkey) { szkey = DK4_SIZEOF(linebuf,dkChar) / 2; }
+ if (0 == szval) { szval = DK4_SIZEOF(linebuf,dkChar) / 2; }
+
+ /* Calculate key and value buffer size in bytes.
+ */
+ dk4error_init(&er);
+ szkey = dk4ma_size_t_mul(szkey, sizeof(dkChar), &er);
+ szval = dk4ma_size_t_mul(szval, sizeof(dkChar), &er);
+ if (DK4_E_NONE != er.ec) {
+ /* ERROR: Mathematical overflow in size calculation */
+ dk4app_log_base1(app, DK4_LL_ERROR, 82);
+ goto finished;
+ }
+
+ /* Allocate larger buffer if necessary.
+ */
+ if (DK4_SIZEOF(linebuf,dkChar) < szpibuf) {
+ abuf = dk4mem_new_app(dkChar,szpibuf,app);
+ if (NULL != abuf) {
+ pibuf = abuf;
+ } else {
+ goto finished;
+ }
+ }
+
+ /* Now do the processing.
+ */
+ dk_t2db_run_with_buffers();
+
+ /* Clean up.
+ */
+ finished:
+ dk4mem_release(abuf) ;
+}
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+dk_t2db_run_with_signal_handlers(void)
+{
+ struct sigaction oint;
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+ int success = 0;
+
+ /* Set up signal handling for SIGINT.
+ */
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ dk_t2db_normal_run();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+dk_t2db_run_with_signal_handlers(void)
+{
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ dk_t2db_normal_run();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+dk_t2db_run_with_signal_handlers(void)
+{
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ dk_t2db_normal_run();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+dk_t2db_run_with_signal_handlers(void)
+{
+ dk_t2db_normal_run();
+}
+#endif
+#endif
+#endif
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ $!trace-init dk-t2db.deb
+ $? "+ main"
+ dk4fput_initialize_stderr();
+ app = dk4app_open_cmd(
+ argc, argv,
+ dk_t2db_options, dk_t2db_sz_options,
+ dk_t2db_kwnl[0], version_text,
+ dk_t2db_kwnl[1], help_text, license_text
+ );
+ if (NULL != app) {
+ ese = dk4app_get_stdin_encoding(app);
+ efe = dk4app_get_file_in_encoding(app);
+ dk_t2db_sz_msg = dk4app_string_table_size(dk_t2db_kw_def);
+ dk_t2db_msg = dk4app_string_table(app, dk_t2db_kwnl[3], dk_t2db_kw_def);
+ if (0 != dk4app_can_run_normally(app)) {
+ dk_t2db_run_with_signal_handlers();
+ if (0 != sig_read_atomic(&sig_had_int)) {
+ /* ERROR: Aborted by SIGINT */
+ dk4app_log_1(
+ app, dk_t2db_msg, dk_t2db_sz_msg, DK4_LL_ERROR, 30
+ );
+ exval = EXIT_FAILURE;
+ }
+ if (0 != sig_read_atomic(&sig_had_term)) {
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ dk4app_close(app);
+ } else {
+ dk4fputs(dk_t2db_kwnl[2], stderr, NULL);
+ }
+ fflush(stderr);
+ dk4fput_cleanup_stderr();
+ $? "- main %d", exval
+ $!trace-end
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/dk-t2db.rc b/support/dktools/dk-t2db.rc
new file mode 100644
index 0000000000..e865f1a107
--- /dev/null
+++ b/support/dktools/dk-t2db.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Convert text to simple text database\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "Convert text to simple text database\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "dk-t2db\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/dk-t2h.c b/support/dktools/dk-t2h.c
new file mode 100644
index 0000000000..89c0b64e03
--- /dev/null
+++ b/support/dktools/dk-t2h.c
@@ -0,0 +1,2342 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk-t2h.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#line 9 "dk-t2h.ctr"
+
+/** @file dk-th2.c The dk-t2h program.
+ See dk_t2h_help_text for details.
+*/
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4enc.h"
+#include "dk4mem.h"
+#include "dk4app.h"
+#include "dk4aopt.h"
+#include "dk4fopda.h"
+#include "dk4fput.h"
+#include "dk4vers.h"
+#include "dk4tsp32.h"
+#include "dk4maodd.h"
+#include "dk4mao8d.h"
+#include "dk4mao8h.h"
+#include "dk4utf8.h"
+#include "dk4utf16.h"
+#include "dk4ansi.h"
+#include "dk4mpl.h"
+#include "dk4strd.h"
+#include "dk4pathd.h"
+
+
+
+
+
+#line 102 "dk-t2h.ctr"
+
+
+
+/** Default help text, shown if no help text file is found.
+*/
+static const dkChar * const dk_t2h_help_text[] = {
+dkT(""),
+dkT("Text to HTML converter"),
+dkT(""),
+dkT("dk-t2h [<options>] [<file(s)>]"),
+dkT(""),
+dkT("Options:"),
+dkT("-i <encoding>\t--input-encoding=<encoding>\tExpected input encoding."),
+dkT("-l\t\t--code-lines\t\t\tInput lines are code lines."),
+dkT("-e\t\t--echo\t\t\t\tProcess command line arguments."),
+dkT("-f\t\t--full\t\t\t\tWrite full HTML file."),
+dkT("-t <string>\t--title=<string>\t\tTitle for full HTML file."),
+dkT("\t\t--verbose\t\t\tShow error message on SIGPIPE."),
+dkT(""),
+dkT("--help\t\t\t\t\t\tShow this short help text."),
+dkT("--manual\t\t\t\t\t*** SHOW FULL MANUAL. ***"),
+dkT("--version\t\t\t\t\tShow version information."),
+dkT("--license\t\t\t\t\tShow license information."),
+dkT(""),
+dkT("http://dktools.sourceforge.net"),
+dkT(""),
+NULL
+
+
+#line 130 "dk-t2h.ctr"
+};
+
+
+
+/** License text.
+*/
+static const dkChar * const dk_t2h_license_text[] = {
+dkT(""),
+dkT("This software uses code from the following projects, either directly or as"),
+dkT("a library:"),
+dkT(""),
+dkT("dktools\t\tDirk Krause's tools and libraries."),
+dkT("\t\tSee http://dktools.sourceforge.net/ for more information."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT("zlib\t\tData compression library."),
+dkT("\t\tSee http://www.zlib.net/ for more information."),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT("bzip2\t\tData compression program and library."),
+dkT("\t\tSee http://www.bzip.org/ for more information."),
+#endif
+dkT(""),
+dkT("All the licenses below apply to the program."),
+dkT("Licenses for used libraries are shown as found on my Scientific Linux 6.x"),
+dkT("computer in the /usr/share/doc directory on 2015-04-01. Check the project"),
+dkT("homepages of the used libraries for additional information and/or updated"),
+dkT("license terms."),
+dkT(""),
+dkT(""),
+dkT("DK tools and libraries license"),
+dkT("=============================="),
+dkT("Copyright (c) 2015-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above copyright notice,"),
+dkT(" this list of conditions and the following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("* Neither the name of the Dirk Krause nor the names of contributors may be"),
+dkT(" used to endorse or promote products derived from this software without"),
+dkT(" specific prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\""),
+dkT("AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED."),
+dkT(""),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,"),
+dkT("INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,"),
+dkT("BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,"),
+dkT("DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY"),
+dkT("OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,"),
+dkT("EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT(""),
+dkT("Zlib license"),
+dkT("============"),
+dkT("(C) 1995-2004 Jean-loup Gailly and Mark Adler"),
+dkT(""),
+dkT("This software is provided 'as-is', without any express or implied"),
+dkT("warranty. In no event will the authors be held liable for any damages"),
+dkT("arising from the use of this software."),
+dkT(""),
+dkT("Permission is granted to anyone to use this software for any purpose,"),
+dkT("including commercial applications, and to alter it and redistribute it"),
+dkT("freely, subject to the following restrictions:"),
+dkT(""),
+dkT("1. The origin of this software must not be misrepresented; you must not"),
+dkT(" claim that you wrote the original software. If you use this software"),
+dkT(" in a product, an acknowledgment in the product documentation would be"),
+dkT(" appreciated but is not required."),
+dkT("2. Altered source versions must be plainly marked as such, and must not be"),
+dkT(" misrepresented as being the original software."),
+dkT("3. This notice may not be removed or altered from any source distribution."),
+dkT(""),
+dkT("Jean-loup Gailly Mark Adler"),
+dkT("jloup@gzip.org madler@alumni.caltech.edu"),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT(""),
+dkT("Bzip2 and libbzip2 library license"),
+dkT("=================================="),
+dkT("This program, \"bzip2\", the associated library \"libbzip2\", and all"),
+dkT("documentation, are copyright (C) 1996-2007 Julian R Seward. All"),
+dkT("rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions"),
+dkT("are met:"),
+dkT(""),
+dkT("1. Redistributions of source code must retain the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer."),
+dkT(""),
+dkT("2. The origin of this software must not be misrepresented; you must "),
+dkT(" not claim that you wrote the original software. If you use this "),
+dkT(" software in a product, an acknowledgment in the product "),
+dkT(" documentation would be appreciated but is not required."),
+dkT(""),
+dkT("3. Altered source versions must be plainly marked as such, and must"),
+dkT(" not be misrepresented as being the original software."),
+dkT(""),
+dkT("4. The name of the author may not be used to endorse or promote "),
+dkT(" products derived from this software without specific prior written "),
+dkT(" permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS"),
+dkT("OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED"),
+dkT("WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE"),
+dkT("GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS"),
+dkT("INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,"),
+dkT("WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS"),
+dkT("SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+dkT(""),
+dkT("Julian Seward, jseward@bzip.org"),
+dkT("bzip2/libbzip2 version 1.0.5 of 10 December 2007"),
+#endif
+dkT(""),
+NULL
+
+
+#line 262 "dk-t2h.ctr"
+};
+
+
+
+/** Constant text keywords used by the program, not localized.
+*/
+static const dkChar * const dk_t2h_kwnl[] = {
+/* 0 */
+dkT("dktools"),
+
+/* 1 */
+dkT("dk-t2h.txt"),
+
+/* 2 */
+dkT("dk-t2h.str"),
+
+/* 3 */
+dkT("rb"),
+
+/* 4 */
+dkT("stdin"),
+
+/* 5 */
+dkT("\\"),
+
+/* 6 */
+dkT("verbose"),
+
+NULL
+
+
+#line 299 "dk-t2h.ctr"
+};
+
+
+
+/** Constant keywords used by the program, replaced by localized texts.
+*/
+static const dkChar * const dk_t2h_kw_def[] = {
+/* 0 */
+dkT("Failed to set up signal handlers!"),
+
+/* 1 */
+dkT("Failed to restore signal handlers!"),
+
+/* 2 */
+dkT("Illegal encoding: \""),
+
+/* 3 */
+dkT("\"!"),
+
+/* 4 */
+dkT("Conversion from number to text failed, probably bug!"),
+
+/* 5 */
+dkT("Failed to decode string from UTF-16!"),
+
+/* 6 */
+dkT("Failed to decode string from ANSI!"),
+
+/* 7 */
+dkT("Failed to decode string from UTF-8!"),
+
+/* 8 */
+dkT("Too many input lines, line number overflow!"),
+
+/* 9 */
+dkT("No command line arguments specified!"),
+
+/* 10 */
+dkT("Aborted by SIGINT signal!"),
+
+/* 11 */
+dkT("Aborted by SIGTERM signal!"),
+
+/* 12 */
+dkT("Aborted by SIGPIPE signal!"),
+
+/* 13 */
+dkT("Failed to write to standard output!"),
+
+/* 14 */
+dkT("Option -t ignored, only full pages can have a title!"),
+
+/* 15 */
+dkT("Decoding failed!\n\tByte: "),
+
+/* 16 */
+dkT("Encoding failed!\n\tByte: "),
+
+/* 17 */
+dkT("Processing failed!\n\tByte: "),
+
+/* 18 */
+dkT(",\n\tCharacter: "),
+
+/* 19 */
+dkT(",\n\tPosition in line: "),
+
+/* 20 */
+dkT("."),
+
+/* 21 */
+dkT("Decoding failed!"),
+
+/* 22 */
+dkT("Encoding failed!"),
+
+/* 23 */
+dkT("Processing failed!"),
+
+/* 24 */
+dkT("Further decoding failures!"),
+
+/* 25 */
+dkT("Further encoding failures!"),
+
+/* 26 */
+dkT("Further processing failures!"),
+
+NULL
+
+
+#line 374 "dk-t2h.ctr"
+};
+
+
+
+/** Constant 8 bit text keywords used by the program, not localized.
+*/
+static const char * const dk_t2h_kw8[] = {
+/* 0 */
+"<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n",
+
+/* 1 */
+"<html>\n",
+
+/* 2 */
+"<head>\n",
+
+/* 3 */
+"<meta name=\"generator\" content=\"dk-t2h, see http://dktools.sourceforge.net\">\n",
+
+/* 4 */
+"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=us-ascii\">\n",
+
+/* 5 */
+"<title>__TITLE__</title>\n",
+
+/* 6 */
+"<!--\tstyle sheet\t-->\n",
+
+/* 7 */
+"<!-- link rel=\"StyleSheet\" type=\"text/css\" href=\"__URL__\" -->\n",
+
+/* 8 */
+"<!--\tParent node of current document node\t-->\n",
+
+/* 9 */
+"<!-- link rel=\"Parent\" title=\"\" rev=\"\" href=\"__URL__\" -->\n",
+
+/* 10 */
+"<!--\tDocument author\t-->\n",
+
+/* 11 */
+"<!-- link rel=\"Made\" title=\"\" rev=\"\" href=\"mailto:__MAIL__\" -->\n",
+
+/* 12 */
+"<!--\tLink to homepage\t-->\n",
+
+/* 13 */
+"<!-- link rel=\"Home\" title=\"\" rev=\"\" href=\"__URL__\" -->\n",
+
+/* 14 */
+"<!--\tLink to table of contents\t-->\n",
+
+/* 15 */
+"<!-- link rel=\"ToC\" title=\"\" rev=\"\" href=\"__URL__\" -->\n",
+
+/* 16 */
+"<!--\tLink to index\t-->\n",
+
+/* 17 */
+"<!-- link rel=\"Index\" title=\"\" rev=\"\" href=\"__URL__\" -->\n",
+
+/* 18 */
+"<!--\tLink to glossary\t-->\n",
+
+/* 19 */
+"<!-- link rel=\"Glossary\" title=\"\" rev=\"\" href=\"__URL__\" -->\n",
+
+/* 20 */
+"<!--\tLink to copyright\t-->\n",
+
+/* 21 */
+"<!-- link rel=\"Copyright\" title=\"\" rev=\"\" href=\"__URL__\" -->\n",
+
+/* 22 */
+"<!--\tLink to upper document node (same as parent?)\t-->\n",
+
+/* 23 */
+"<!-- link rel=\"Up\" title=\"\" rev=\"\" href=\"__URL__\" -->\n",
+
+/* 24 */
+"<!--\tLink to next document\t-->\n",
+
+/* 25 */
+"<!-- link rel=\"Next\" title=\"\" rev=\"\" href=\"__URL__\" -->\n",
+
+/* 26 */
+"<!--\tLink to previous document\t-->\n",
+
+/* 27 */
+"<!-- link rel=\"Previous\" title=\"\" rev=\"\" href=\"__URL__\" -->\n",
+
+/* 28 */
+"<!--\tLink to help page\t-->\n",
+
+/* 29 */
+"<!-- link rel=\"Help\" title=\"\" rev=\"\" href=\"__URL__\" -->\n",
+
+/* 30 */
+"<!--\tLink to a document node serving as bookmark\t-->\n",
+
+/* 31 */
+"<!-- link rel=\"Bookmark\" title=\"\" rev=\"\" href=\"\" -->\n",
+
+/* 32 */
+"</head>\n",
+
+/* 33 */
+"<body>\n",
+
+/* 34 */
+"</body>\n",
+
+/* 35 */
+"</html>\n",
+
+/* 36 */
+"<title>",
+
+/* 37 */
+"</title>\n",
+
+/* 38 */
+"<p>\n",
+
+/* 39 */
+"</p>\n",
+
+/* 40 */
+"<pre>\n",
+
+/* 41 */
+"</pre>\n",
+
+/* 42 */
+"<code title=\"",
+
+/* 43 */
+"\">",
+
+/* 44 */
+"</code>",
+
+/* 45 */
+"&#x",
+
+/* 46 */
+";",
+
+NULL
+
+
+#line 457 "dk-t2h.ctr"
+};
+
+
+
+/** Options for the program.
+*/
+static const dk4_option_specification_t dk_t2h_options[] = {
+ { dkT('i'), dkT("input-encoding"), DK4_OPT_ARG_STRING },
+ { dkT('l'), dkT("code-lines"), DK4_OPT_ARG_NONE },
+ { dkT('e'), dkT("echo"), DK4_OPT_ARG_NONE },
+ { dkT('f'), dkT("full"), DK4_OPT_ARG_NONE },
+ { dkT('t'), dkT("title"), DK4_OPT_ARG_STRING },
+ { dkT('\0'), dkT("verbose"), DK4_OPT_ARG_STRING }
+};
+
+
+
+/** Translation table for ASCII characters.
+*/
+static char const * const dk_t2h_translation_table[] = {
+/* 0 00 */ NULL,
+/* 1 01 */ NULL,
+/* 2 02 */ NULL,
+/* 3 03 */ NULL,
+/* 4 04 */ NULL,
+/* 5 05 */ NULL,
+/* 6 06 */ NULL,
+/* 7 07 */ NULL,
+/* 8 08 */ NULL,
+/* 9 09 */ "\t",
+/* 10 0a */ NULL,
+/* 11 0b */ NULL,
+/* 12 0c */ NULL,
+/* 13 0d */ NULL,
+/* 14 0e */ NULL,
+/* 15 0f */ NULL,
+/* 16 10 */ NULL,
+/* 17 11 */ NULL,
+/* 18 12 */ NULL,
+/* 19 13 */ NULL,
+/* 20 14 */ NULL,
+/* 21 15 */ NULL,
+/* 22 16 */ NULL,
+/* 23 17 */ NULL,
+/* 24 18 */ NULL,
+/* 25 19 */ NULL,
+/* 26 1a */ NULL,
+/* 27 1b */ NULL,
+/* 28 1c */ NULL,
+/* 29 1d */ NULL,
+/* 30 1e */ NULL,
+/* 31 1f */ NULL,
+/* 32 20 */ " ",
+/* 33 21 */ "!",
+/* 34 22 */ "&quot;",
+/* 35 23 */ "#",
+/* 36 24 */ "$",
+/* 37 25 */ "%",
+/* 38 26 */ "&amp;",
+/* 39 27 */ "'",
+/* 40 28 */ "(",
+/* 41 29 */ ")",
+/* 42 2a */ "*",
+/* 43 2b */ "+",
+/* 44 2c */ ",",
+/* 45 2d */ "-",
+/* 46 2e */ ".",
+/* 47 2f */ "/",
+/* 48 30 */ "0",
+/* 49 31 */ "1",
+/* 50 32 */ "2",
+/* 51 33 */ "3",
+/* 52 34 */ "4",
+/* 53 35 */ "5",
+/* 54 36 */ "6",
+/* 55 37 */ "7",
+/* 56 38 */ "8",
+/* 57 39 */ "9",
+/* 58 3a */ ":",
+/* 59 3b */ ";",
+/* 60 3c */ "&lt;",
+/* 61 3d */ "=",
+/* 62 3e */ "&gt;",
+/* 63 3f */ "?",
+/* 64 40 */ "@",
+/* 65 41 */ "A",
+/* 66 42 */ "B",
+/* 67 43 */ "C",
+/* 68 44 */ "D",
+/* 69 45 */ "E",
+/* 70 46 */ "F",
+/* 71 47 */ "G",
+/* 72 48 */ "H",
+/* 73 49 */ "I",
+/* 74 4a */ "J",
+/* 75 4b */ "K",
+/* 76 4c */ "L",
+/* 77 4d */ "M",
+/* 78 4e */ "N",
+/* 79 4f */ "O",
+/* 80 50 */ "P",
+/* 81 51 */ "Q",
+/* 82 52 */ "R",
+/* 83 53 */ "S",
+/* 84 54 */ "T",
+/* 85 55 */ "U",
+/* 86 56 */ "V",
+/* 87 57 */ "W",
+/* 88 58 */ "X",
+/* 89 59 */ "Y",
+/* 90 5a */ "Z",
+/* 91 5b */ "[",
+/* 92 5c */ "\\",
+/* 93 5d */ "]",
+/* 94 5e */ "^",
+/* 95 5f */ "_",
+/* 96 60 */ "`",
+/* 97 61 */ "a",
+/* 98 62 */ "b",
+/* 99 63 */ "c",
+/* 100 64 */ "d",
+/* 101 65 */ "e",
+/* 102 66 */ "f",
+/* 103 67 */ "g",
+/* 104 68 */ "h",
+/* 105 69 */ "i",
+/* 106 6a */ "j",
+/* 107 6b */ "k",
+/* 108 6c */ "l",
+/* 109 6d */ "m",
+/* 110 6e */ "n",
+/* 111 6f */ "o",
+/* 112 70 */ "p",
+/* 113 71 */ "q",
+/* 114 72 */ "r",
+/* 115 73 */ "s",
+/* 116 74 */ "t",
+/* 117 75 */ "u",
+/* 118 76 */ "v",
+/* 119 77 */ "w",
+/* 120 78 */ "x",
+/* 121 79 */ "y",
+/* 122 7a */ "z",
+/* 123 7b */ "{",
+/* 124 7c */ "|",
+/* 125 7d */ "}",
+/* 126 7e */ "~",
+/* 127 7f */ NULL,
+/* 128 80 */ NULL,
+/* 129 81 */ NULL,
+/* 130 82 */ NULL,
+/* 131 83 */ NULL,
+/* 132 84 */ NULL,
+/* 133 85 */ NULL,
+/* 134 86 */ NULL,
+/* 135 87 */ NULL,
+/* 136 88 */ NULL,
+/* 137 89 */ NULL,
+/* 138 8a */ NULL,
+/* 139 8b */ NULL,
+/* 140 8c */ NULL,
+/* 141 8d */ NULL,
+/* 142 8e */ NULL,
+/* 143 8f */ NULL,
+/* 144 90 */ NULL,
+/* 145 91 */ NULL,
+/* 146 92 */ NULL,
+/* 147 93 */ NULL,
+/* 148 94 */ NULL,
+/* 149 95 */ NULL,
+/* 150 96 */ NULL,
+/* 151 97 */ NULL,
+/* 152 98 */ NULL,
+/* 153 99 */ NULL,
+/* 154 9a */ NULL,
+/* 155 9b */ NULL,
+/* 156 9c */ NULL,
+/* 157 9d */ NULL,
+/* 158 9e */ NULL,
+/* 159 9f */ NULL,
+/* 160 a0 */ "&nbsp;",
+/* 161 a1 */ "&iexcl;",
+/* 162 a2 */ "&cent;",
+/* 163 a3 */ "&pound;",
+/* 164 a4 */ "&curren;",
+/* 165 a5 */ "&yen;",
+/* 166 a6 */ "&brvbar;",
+/* 167 a7 */ "&sect;",
+/* 168 a8 */ "&uml;",
+/* 169 a9 */ "&copy;",
+/* 170 aa */ "&ordf;",
+/* 171 ab */ "&laquo;",
+/* 172 ac */ "&not;",
+/* 173 ad */ "&shy;",
+/* 174 ae */ "&reg;",
+/* 175 af */ "&macr;",
+/* 176 b0 */ "&deg;",
+/* 177 b1 */ "&plusmn;",
+/* 178 b2 */ "&sup2;",
+/* 179 b3 */ "&sup3;",
+/* 180 b4 */ "&acute;",
+/* 181 b5 */ "&micro;",
+/* 182 b6 */ "&para;",
+/* 183 b7 */ "&middot;",
+/* 184 b8 */ "&cedil;",
+/* 185 b9 */ "&sup1;",
+/* 186 ba */ "&ordm;",
+/* 187 bb */ "&raquo;",
+/* 188 bc */ "&frac14;",
+/* 189 bd */ "&frac12;",
+/* 190 be */ "&frac34;",
+/* 191 bf */ "&iquest;",
+/* 192 c0 */ "&Agrave;",
+/* 193 c1 */ "&Aacute;",
+/* 194 c2 */ "&Acirc;",
+/* 195 c3 */ "&Atilde;",
+/* 196 c4 */ "&Auml;",
+/* 197 c5 */ "&Aring;",
+/* 198 c6 */ "&AElig;",
+/* 199 c7 */ "&Ccedil;",
+/* 200 c8 */ "&Egrave;",
+/* 201 c9 */ "&Eacute;",
+/* 202 ca */ "&Ecirc;",
+/* 203 cb */ "&Euml;",
+/* 204 cc */ "/Igrave;",
+/* 205 cd */ "&Iacute;",
+/* 206 ce */ "&Icirc;",
+/* 207 cf */ "&Iuml;",
+/* 208 d0 */ "&ETH;",
+/* 209 d1 */ "&Ntilde;",
+/* 210 d2 */ "&Ograve;",
+/* 211 d3 */ "&Oacute;",
+/* 212 d4 */ "&Ocirc;",
+/* 213 d5 */ "&Otilde;",
+/* 214 d6 */ "&Ouml;",
+/* 215 d7 */ "&times;",
+/* 216 d8 */ "&Oslash;",
+/* 217 d9 */ "&Ugrave;",
+/* 218 da */ "&Uacute;",
+/* 219 db */ "&Ucirc;",
+/* 220 dc */ "&Uuml;",
+/* 221 dd */ "&Yacute;",
+/* 222 de */ "&THORN;",
+/* 223 df */ "&szlig;",
+/* 224 e0 */ "&agrave;",
+/* 225 e1 */ "&aacute;",
+/* 226 e2 */ "&acirc;",
+/* 227 e3 */ "&atilde;",
+/* 228 e4 */ "&auml;",
+/* 229 e5 */ "&aring;",
+/* 230 e6 */ "&aelig;",
+/* 231 e7 */ "&ccedil;",
+/* 232 e8 */ "&egrave;",
+/* 233 e9 */ "&eacute;",
+/* 234 ea */ "&ecirc;",
+/* 235 eb */ "&euml;",
+/* 236 ec */ "&igrave;",
+/* 237 ed */ "&iacute;",
+/* 238 ee */ "&icirc;",
+/* 239 ef */ "&iuml;",
+/* 240 f0 */ "&eth;",
+/* 241 f1 */ "&ntilde;",
+/* 242 f2 */ "&ograve;",
+/* 243 f3 */ "&oacute;",
+/* 244 f4 */ "&ocirc;",
+/* 245 f5 */ "&otilde;",
+/* 246 f6 */ "&ouml;",
+/* 247 f7 */ "&divide;",
+/* 248 f8 */ "&oslash;",
+/* 249 f9 */ "&ugrave;",
+/* 250 fa */ "&uacute;",
+/* 251 fb */ "&ucirc;",
+/* 252 fc */ "&uuml;",
+/* 253 fd */ "&yacute;",
+/* 254 fe */ "&thorn;",
+/* 255 ff */ "&yuml;"
+};
+
+
+/** Pointer to localized or not localized texts.
+*/
+static const dkChar * const *dk_t2h_msg = dk_t2h_kw_def;
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Page title for full HTML page, if specified on command line.
+*/
+static const dkChar *dk_t2h_title = NULL;
+
+
+
+/** Current line number.
+*/
+static dk4_um_t dk_t2h_lineno = (dk4_um_t)1UL;
+
+
+
+/** Number of elements in the dk_t2h_options array.
+*/
+static const size_t dk_t2h_sz_options =
+sizeof(dk_t2h_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Number of elements in dk_t2h_msg array.
+*/
+static size_t dk_t2h_sz_msg =
+sizeof(dk_t2h_kw_def)/sizeof(DK4_PCDKCHAR) - 1;
+
+
+/** Program exit status.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+/** Flag: Error occured while writing to stdout.
+*/
+static int output_error = 0;
+
+
+
+/** Flag: Verbose output (report SIGPIPE).
+*/
+static int verbose = 0;
+
+
+
+/** Flag: Echo command line arguments instead of processing files.
+*/
+static int dk_t2h_echo = 0;
+
+
+
+/** Flag: Produce full HTML page, not just a fragment.
+*/
+static int dk_t2h_full = 0;
+
+
+
+/** Flag: Wrap all lines in code environments.
+*/
+static int dk_t2h_code = 0;
+
+
+
+/** Input encoding expected when processing stdin.
+*/
+static int dk_t2h_i_std = DK4_FILE_ENCODING_ASCII;
+
+
+
+/** Input encoding expected when processing files.
+*/
+static int dk_t2h_i_file = DK4_FILE_ENCODING_ASCII;
+
+
+
+/** Number of decoding errors in current file.
+*/
+static int dk_t2h_dec_err = 0;
+
+
+
+/** Number of encoding errors in current file.
+*/
+static int dk_t2h_enc_err = 0;
+
+
+
+/** Number of processing errors in current file.
+*/
+static int dk_t2h_pro_err = 0;
+
+
+
+/** Flag: Previous character was carriage return.
+*/
+static int dk_t2h_last_cr = 0;
+
+
+
+/** Flag: Previous character was newline.
+*/
+static int dk_t2h_last_nl = 0;
+
+
+
+/** Flag: Have text in line, newline needed.
+*/
+static int dk_t2h_lhtx = 0;
+
+
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+/** Pass a volatile pointer to an atomic integer.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ptr Address of atomic integer variable.
+ @return The unmodified pointer.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+/** Check whether we can continue or if a signal was received.
+ @param check_pipe Flag: Check for occured SIGPIPE signal too.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(int check_pipe)
+{
+ int back = 1;
+#ifdef SIGPIPE
+ if (0 != check_pipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_int )) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+/** Check whether we can continue.
+ @return 1 for yes, 0 for no.
+*/
+static
+int
+dk_t2h_can_continue(void)
+{
+ int back = 1;
+ if (0 == sig_can_continue(1)) {
+ back = 0;
+ }
+ return back;
+}
+
+
+
+/** Process command line options.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk_t2h_process_options(void)
+{
+ const dkChar *oaptr;
+ int encval = 0;
+ int bomval = 0;
+ int back = 1;
+ if (0 != dk4app_opt_is_set_long(app, dk_t2h_kwnl[6], NULL)) {
+ verbose = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('i'), NULL)) {
+ oaptr = dk4app_opt_get_string_ptr_short(app, dkT('i'), NULL);
+ if (NULL != oaptr) {
+ if (0 != dk4enc_find(&encval, &bomval, oaptr, NULL)) {
+ dk_t2h_i_std = dk_t2h_i_file = encval;
+ } else {
+ /* ERROR: Illegal encoding */
+ back = 0;
+ dk4app_log_3(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 2, 3, oaptr);
+ }
+ } else {
+
+#line 1005 "dk-t2h.ctr"
+ /* ERROR: Failed to obtain option argument, bug! */
+ }
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('e'), NULL)) {
+ dk_t2h_echo = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('l'), NULL)) {
+ dk_t2h_code = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('f'), NULL)) {
+ dk_t2h_full = 1;
+ if (0 != dk4app_opt_is_set_short(app, dkT('t'), NULL)) {
+ dk_t2h_title = dk4app_opt_get_string_ptr_short(app, dkT('t'), NULL);
+ }
+ } else {
+ if (0 != dk4app_opt_is_set_short(app, dkT('t'), NULL)) {
+ back = 0;
+ /* ERROR: Title only for full pages */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 14);
+ }
+ }
+ return back;
+}
+
+
+
+/** Handler function after processing CR/NL sequences.
+ Here we do the real output.
+ @param c Character to process.
+ @return Result code:
+ - DK4_TSP_RES_OK if the character was processed successfully,
+ - DK4_TSP_RES_ERROR if there was an error but we can continue,
+ - DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+dk_t2h_c32_after_cr_nl_check(
+ dk4_c32_t c
+)
+{
+ char buf[16*sizeof(dk4_um_t)];
+ size_t i;
+ int back = DK4_TSP_RES_OK;
+ int res = 0;
+ int done = 0;
+
+
+#line 1052 "dk-t2h.ctr"
+ if (dkC32(0x0A) == c) {
+
+#line 1053 "dk-t2h.ctr"
+ /*
+ Newline, finish line and write newline to output.
+ */
+ if (0 != dk_t2h_code) {
+
+#line 1057 "dk-t2h.ctr"
+ if (0 == dk_t2h_lhtx) {
+ if (EOF == fputs(dk_t2h_kw8[42], stdout)) { output_error = 1; }
+ res = dk4ma_write_c8_decimal_unsigned(
+ buf, sizeof(buf), dk_t2h_lineno, 0, NULL
+ );
+ if (0 != res) {
+ i = strlen(buf);
+ while (3 > i++) {
+ if (EOF == fputc('0', stdout)) { output_error = 1; }
+ }
+ if (EOF == fputs(buf, stdout)) { output_error = 1; }
+ }
+ if (EOF == fputs(dk_t2h_kw8[43], stdout)) { output_error = 1; }
+ dk_t2h_lhtx = 1;
+ }
+ if (0 != dk_t2h_lhtx) {
+
+#line 1073 "dk-t2h.ctr"
+ if (EOF == fputs(dk_t2h_kw8[44], stdout)) { output_error = 1; }
+ } else {
+
+#line 1075 "dk-t2h.ctr"
+ }
+ } else {
+
+#line 1077 "dk-t2h.ctr"
+ }
+ if (EOF == fputc('\n', stdout)) { output_error = 1; }
+ } else {
+
+#line 1080 "dk-t2h.ctr"
+ if (0 != dk_t2h_code) {
+
+#line 1081 "dk-t2h.ctr"
+ if (0 == dk_t2h_lhtx) {
+
+#line 1082 "dk-t2h.ctr"
+ /*
+ Start new line.
+ */
+ if (EOF == fputs(dk_t2h_kw8[42], stdout)) { output_error = 1; }
+ res = dk4ma_write_c8_decimal_unsigned(
+ buf, sizeof(buf), dk_t2h_lineno, 0, NULL
+ );
+ if (0 != res) {
+ i = strlen(buf);
+ while (3 > i++) {
+ if (EOF == fputc('0', stdout)) { output_error = 1; }
+ }
+ if (EOF == fputs(buf, stdout)) { output_error = 1; }
+ }
+ if (EOF == fputs(dk_t2h_kw8[43], stdout)) { output_error = 1; }
+ dk_t2h_lhtx = 1;
+ } else {
+
+#line 1099 "dk-t2h.ctr"
+ }
+ } else {
+
+#line 1101 "dk-t2h.ctr"
+ }
+ /*
+ Write character to output.
+ */
+ if (dkC32(0x00000100) > c) {
+ i = (size_t)c;
+ i &= 0x0000FFU;
+ if (NULL != dk_t2h_translation_table[i]) {
+ if (EOF == fputs(dk_t2h_translation_table[i], stdout)) {
+ output_error = 1;
+ }
+ done = 1;
+ }
+ }
+ if (0 == done) {
+ res = dk4ma_write_c8_hex_unsigned(
+ buf, sizeof(buf), (dk4_um_t)c, 0, NULL
+ );
+ if (0 != res) {
+ i = strlen(buf);
+ if (EOF == fputs(dk_t2h_kw8[45], stdout)) { output_error = 1; }
+ if (0 != (i % 2)) {
+ if (EOF == fputc('0', stdout)) { output_error = 1; }
+ }
+ if (EOF == fputs(buf, stdout)) { output_error = 1; }
+ if (EOF == fputs(dk_t2h_kw8[46], stdout)) { output_error = 1; }
+ } else {
+ exval = EXIT_FAILURE;
+ /* ERROR: Conversion */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 4);
+ }
+ }
+ }
+
+#line 1134 "dk-t2h.ctr"
+ return back;
+}
+
+
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+/* +++++ 4 +++++ */
+
+/** Write 32 bit character string.
+ @param str String to write.
+*/
+static
+void
+dk_t2h_output_c32(const dk4_c32_t *str)
+{
+ while (dkC32(0x00) != *str) {
+ switch (dk_t2h_c32_after_cr_nl_check(*(str++))) {
+ case DK4_TSP_RES_ERROR : case DK4_TSP_RES_FATAL : {
+ exval = EXIT_FAILURE;
+ } break;
+ }
+ }
+}
+
+/* ----- 4 ----- */
+#else
+/* +++++ 2 +++++ */
+
+/** Write UTF-16 encoded text string.
+ @param str String to write.
+*/
+static
+void
+dk_t2h_output_utf16(const dk4_c16_t *str)
+{
+ dk4_utf16_decoder_t dec;
+ int cc;
+
+ dk4utf16_init(&dec);
+ cc = 1;
+ while (1 == cc) {
+ if (dkC16(0) != *str) {
+ switch (dk4utf16_add(&dec, *(str++))) {
+ case DK4_EDSTM_ERROR : {
+ cc = -1;
+ /* ERROR: Decoding error */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 5);
+ } break;
+ case DK4_EDSTM_FINISHED : {
+ switch (dk_t2h_c32_after_cr_nl_check(dk4utf16_get(&dec))) {
+ case DK4_TSP_RES_ERROR : case DK4_TSP_RES_FATAL : {
+ exval = EXIT_FAILURE;
+ } break;
+ }
+ } break;
+ }
+ } else {
+ cc = 0;
+ }
+ }
+ if (0 == cc) {
+ if (0 == dk4utf16_is_empty(&dec)) {
+ /* Decoding error */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 5);
+ exval = EXIT_FAILURE;
+ }
+ }
+}
+
+/* ----- 2 ----- */
+#endif
+#else
+/* +++++ 1 +++++ */
+
+/** Write ASCII encoded text string.
+ @param str String to write.
+*/
+static
+void
+dk_t2h_output_ascii(const char *str)
+{
+ dk4_c32_t c32;
+ while ('\0' != *str) {
+ c32 = dkC32(0xFF) & ((dk4_c32_t)((unsigned char)(*(str++))));
+ switch (dk_t2h_c32_after_cr_nl_check(c32)) {
+ case DK4_TSP_RES_ERROR : case DK4_TSP_RES_FATAL : {
+ exval = EXIT_FAILURE;
+ } break;
+ }
+ }
+}
+
+
+
+/** Write ANSI encoded text string.
+ @param str String to write.
+*/
+static
+void
+dk_t2h_output_ansi(const char *str)
+{
+ dk4_c32_t c32;
+ char c;
+ while ('\0' != *str) {
+ c = *(str++);
+ if (0 != dk4ansi_decode(&c32, (unsigned char)c)) {
+ switch (dk_t2h_c32_after_cr_nl_check(c32)) {
+ case DK4_TSP_RES_ERROR : case DK4_TSP_RES_FATAL : {
+ exval = EXIT_FAILURE;
+ }
+ }
+ } else {
+ exval = EXIT_FAILURE;
+ /* ERROR: Decoding error */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 6);
+ }
+ }
+}
+
+
+
+/** Write UTF-8 encoded string.
+ @param str String to write.
+*/
+static
+void
+dk_t2h_output_utf8(const char *str)
+{
+ dk4_utf8_decoder_t dec;
+ int cc;
+
+ cc = 1;
+ dk4utf8_init(&dec);
+ while (1 == cc) {
+ if ('\0' != *str) {
+ switch (dk4utf8_add(&dec, *(str++))) {
+ case DK4_EDSTM_ERROR : {
+ cc = -1;
+ exval = EXIT_FAILURE;
+ /* Decoding error */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 7);
+ } break;
+ case DK4_EDSTM_FINISHED : {
+ switch (dk_t2h_c32_after_cr_nl_check(dk4utf8_get(&dec))) {
+ case DK4_TSP_RES_ERROR : case DK4_TSP_RES_FATAL : {
+ exval = EXIT_FAILURE;
+ }
+ }
+ } break;
+ }
+ } else {
+ cc = 0;
+ }
+ }
+ if (0 == cc) {
+ if (0 == dk4utf8_is_empty(&dec)) {
+ exval = EXIT_FAILURE;
+ /* ERROR: Decoding error */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 7);
+ }
+ }
+}
+
+/* ----- 1 ----- */
+#endif
+
+
+
+static
+void
+dk_t2h_output_dkstring(const dkChar *str)
+{
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ dk_t2h_output_c32(str);
+#else
+ dk_t2h_output_utf16(str);
+#endif
+#else
+ switch (dk4app_get_encoding(app)) {
+ case DK4_FILE_ENCODING_UTF8 : {
+ dk_t2h_output_utf8(str);
+ } break;
+ case DK4_FILE_ENCODING_ANSI : {
+ dk_t2h_output_ansi(str);
+ } break;
+ default : {
+ dk_t2h_output_ascii(str);
+ } break;
+ }
+#endif
+}
+
+
+
+/** Start output page.
+*/
+static
+void
+dk_t2h_output_start_page(void)
+{
+ size_t i;
+ if (0 != dk_t2h_full) {
+ if (NULL != dk_t2h_title) {
+ for (i = 0; i < 5; i++) {
+ if (EOF == fputs(dk_t2h_kw8[i], stdout)) { output_error = 1; }
+ }
+ if (EOF == fputs(dk_t2h_kw8[36], stdout)) { output_error = 1; }
+ dk_t2h_output_dkstring(dk_t2h_title);
+ if (EOF == fputs(dk_t2h_kw8[37], stdout)) { output_error = 1; }
+ for (i = 6; i < 34; i++) {
+ if (EOF == fputs(dk_t2h_kw8[i], stdout)) { output_error = 1; }
+ }
+ } else {
+ for (i = 0; i < 34; i++) {
+ if (EOF == fputs(dk_t2h_kw8[i], stdout)) { output_error = 1; }
+ }
+ }
+ }
+}
+
+
+
+/** Finish output page.
+*/
+static
+void
+dk_t2h_output_finish_page(void)
+{
+ size_t i;
+
+ if (0 != dk_t2h_full) {
+ for (i = 34; i < 36; i++) {
+ if (EOF == fputs(dk_t2h_kw8[i], stdout)) { output_error = 1; }
+ }
+ }
+}
+
+
+
+/** Start processing of one file.
+*/
+static
+void
+dk_t2h_output_start_file(void)
+{
+
+
+#line 1382 "dk-t2h.ctr"
+ /* No errors in this file yet.
+ */
+ dk_t2h_dec_err = 0;
+ dk_t2h_enc_err = 0;
+ dk_t2h_pro_err = 0;
+ dk_t2h_last_cr = 0;
+ dk_t2h_last_nl = 0;
+ dk_t2h_lhtx = 0;
+ dk_t2h_lineno = (dk4_um_t)1UL;
+ dk4app_set_log_source_line(app, dk_t2h_lineno);
+ if (0 != dk_t2h_full) {
+
+#line 1393 "dk-t2h.ctr"
+ if (0 != dk_t2h_code) {
+
+#line 1394 "dk-t2h.ctr"
+ if (EOF == fputs(dk_t2h_kw8[40], stdout)) { output_error = 1; }
+ } else {
+
+#line 1396 "dk-t2h.ctr"
+ if (EOF == fputs(dk_t2h_kw8[38], stdout)) { output_error = 1; }
+ }
+ }
+
+
+#line 1400 "dk-t2h.ctr"
+}
+
+
+
+/** Finish processing of one file.
+*/
+static
+void
+dk_t2h_output_finish_file(void)
+{
+
+
+#line 1411 "dk-t2h.ctr"
+ if (0 != dk_t2h_full) {
+
+#line 1412 "dk-t2h.ctr"
+ if (0 != dk_t2h_code) {
+
+#line 1413 "dk-t2h.ctr"
+ if (EOF == fputs(dk_t2h_kw8[41], stdout)) { output_error = 1; }
+ } else {
+
+#line 1415 "dk-t2h.ctr"
+ if (EOF == fputs(dk_t2h_kw8[39], stdout)) { output_error = 1; }
+ }
+ }
+
+
+#line 1419 "dk-t2h.ctr"
+}
+
+
+
+/** Handler function for single characters.
+ @param obj Object to modify while processing the character.
+ @param c Character to process.
+ @param pos Current position in file or data stream.
+ @param erp Error report, may be NULL.
+ @return Result code:
+ - DK4_TSP_RES_OK if the character was processed successfully,
+ - DK4_TSP_RES_ERROR if there was an error but we can continue,
+ - DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+dk_t2h_c32_handler(
+ void *obj,
+ dk4_c32_t c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_TSP_RES_OK;
+ if (dkC32(0x0A) == c) {
+ /*
+ For a newline clear CR and TXT flag, set NL flag.
+ */
+ back = dk_t2h_c32_after_cr_nl_check(c);
+ dk_t2h_lineno++;
+ if ((dk4_um_t)0UL == dk_t2h_lineno) {
+ /* ERROR: Overflow in line number counting */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 8);
+ exval = EXIT_FAILURE;
+ }
+ dk4app_set_log_source_line(app, dk_t2h_lineno);
+ dk_t2h_last_cr = 0;
+ dk_t2h_last_nl = 1;
+ dk_t2h_lhtx = 0;
+ } else {
+ if (dkC32(0x0D) == c) {
+ /*
+ For a cr if CR flag is set, pass the cr and set TXT flag, clear nl flag.
+ Otherwise simply set CR flag.
+ */
+ if (0 != dk_t2h_last_cr) {
+ back = dk_t2h_c32_after_cr_nl_check(dkC32(0x0D));
+ dk_t2h_lhtx = 1;
+ dk_t2h_last_nl = 0;
+ } else {
+ dk_t2h_last_cr = 1;
+ }
+ } else {
+ /*
+ For any other character:
+ If the CR flag is set, pass cr and current character.
+ Otherwise pass the current character.
+ Reset NL and CR flag, set TXT flag.
+ */
+ if (0 != dk_t2h_last_cr) {
+ back = dk_t2h_c32_after_cr_nl_check(dkC32(0x0D));
+ switch (dk_t2h_c32_after_cr_nl_check(c)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ } else {
+ back = dk_t2h_c32_after_cr_nl_check(c);
+ }
+ dk_t2h_lhtx = 1;
+ dk_t2h_last_nl = 0;
+ dk_t2h_last_cr = 0;
+ }
+ }
+ return back;
+}
+
+
+
+/** Process command line arguments.
+*/
+static
+void
+dk_t2h_process_cmdline(void)
+{
+ const dkChar *xargv;
+ int xargc;
+ int i;
+ xargc = dk4app_get_argc(app);
+ if (0 < xargc) {
+ dk_t2h_output_start_file();
+ for (i = 0; i < xargc; i++) {
+ xargv = dk4app_get_argv(app, i);
+ if (0 != i) {
+ if (EOF == fputc(' ', stdout)) { output_error = 1; }
+ }
+ if (NULL != xargv) {
+ dk_t2h_output_dkstring(xargv);
+ }
+ }
+ dk_t2h_c32_after_cr_nl_check(dkC32(0x0A));
+ dk_t2h_output_finish_file();
+ } else {
+ exval = EXIT_FAILURE;
+ /* ERROR: No command line arguments */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 9);
+ }
+}
+
+
+
+/** Report an error with position in source line.
+ @param i1 Index of first message part in array.
+ @param i2 Index of alternative first message part.
+ @param bno Byte processed.
+ @param lno Current line number.
+ @param cno Current character number.
+ @param cil Current character number in line.
+*/
+static
+void
+dk_t2h_report_with_position(
+ size_t i1,
+ size_t i2,
+ dk4_um_t bno,
+ dk4_um_t lno,
+ dk4_um_t cno,
+ dk4_um_t cil
+)
+{
+ dkChar b1[8*(1+sizeof(dk4_um_t))];
+ dkChar b2[8*(1+sizeof(dk4_um_t))];
+ dkChar b3[8*(1+sizeof(dk4_um_t))];
+ dk4_um_t oldlogline = (dk4_um_t)0UL;
+ int allbuffersok = 0;
+
+ oldlogline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_line(app, lno);
+ if (0 != dk4ma_write_decimal_unsigned(b3,DK4_SIZEOF(b3,dkChar),cil,0,NULL)) {
+ if (0 != dk4ma_write_decimal_unsigned(b2,DK4_SIZEOF(b2,dkChar),cno,0,NULL)) {
+ if (0 != dk4ma_write_decimal_unsigned(b1,DK4_SIZEOF(b1,dkChar),bno,0,NULL)) {
+ allbuffersok = 1;
+ }
+ }
+ }
+ if (0 != allbuffersok) {
+ dk4app_log_7(
+ app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, i1, 18, 19, 20, b1, b2, b3
+ );
+ } else {
+ dk4app_log_1(
+ app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, i2
+ );
+ }
+ dk4app_set_log_source_line(app, oldlogline);
+}
+
+
+
+static
+void
+dk_t2h_report_errors(dk4_er_t *er_en, dk4_er_t *er_pr)
+{
+ if (NULL != er_en) {
+ switch (er_en->ec) {
+ case DK4_E_DECODING_FAILED: {
+ switch (dk_t2h_dec_err) {
+ case 0: case 1: {
+ /* ERROR: Decoding failed */
+ dk_t2h_report_with_position(
+ 15, 21,
+ er_en->dt.fpos.byteno,
+ er_en->dt.fpos.lineno,
+ er_en->dt.fpos.charno,
+ er_en->dt.fpos.charinline
+ );
+ } break;
+ case 2: {
+ /* ERROR: Further decoding errors */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 24);
+ } break;
+ }
+ if (3 > dk_t2h_dec_err) { dk_t2h_dec_err++; }
+ } break;
+ case DK4_E_ENCODING_FAILED: {
+ switch (dk_t2h_enc_err) {
+ case 0: case 1: {
+ /* ERROR: Encoding failed */
+ dk_t2h_report_with_position(
+ 16, 22,
+ er_en->dt.fpos.byteno,
+ er_en->dt.fpos.lineno,
+ er_en->dt.fpos.charno,
+ er_en->dt.fpos.charinline
+ );
+ } break;
+ case 2: {
+ /* ERROR: Further encoding erros */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 25);
+ } break;
+ }
+ if (3 > dk_t2h_enc_err) { dk_t2h_enc_err++; }
+ } break;
+ }
+ }
+ if (NULL != er_pr) {
+ if (DK4_E_NONE != er_pr->ec) {
+ switch (dk_t2h_pro_err) {
+ case 0: case 1: {
+ /* ERROR: Processing error */
+ dk_t2h_report_with_position(
+ 17, 23,
+ er_pr->dt.fpos.byteno,
+ er_pr->dt.fpos.lineno,
+ er_pr->dt.fpos.charno,
+ er_pr->dt.fpos.charinline
+ );
+ } break;
+ case 2: {
+ /* ERROR: Further processing errors */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 26);
+ } break;
+ }
+ if (3 > dk_t2h_pro_err) { dk_t2h_pro_err++; }
+ }
+ }
+}
+
+
+
+/** Process an opened file with file name.
+ @param fipo Opened file.
+ @param fn File name.
+ @param ienc_def Expected input encoding.
+*/
+static
+void
+dk_t2h_process_named_file(FILE *fipo, const dkChar *fn, int ienc_def)
+{
+ dk4_tsp32_t tsp32;
+ dk4_er_t er;
+ dk4_er_t er_en;
+ dk4_er_t er_pr;
+ const dkChar *oldsourcefile;
+ dk4_um_t oldsourceline;
+ int c;
+ int cc;
+ int res;
+ unsigned char ub;
+
+ oldsourcefile = dk4app_get_log_source_file(app);
+ oldsourceline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_file(app, fn);
+ dk4app_set_log_source_line(app, (dk4_um_t)0UL);
+ dk_t2h_output_start_file();
+ dk4error_init(&er);
+ res = dk4tsp32_setup_char(
+ &tsp32, NULL, dk_t2h_c32_handler, ienc_def, &er
+ );
+ if (0 != res) {
+ cc = 1;
+ while (1 == cc) {
+ if (0 != dk_t2h_can_continue()) {
+ c = fgetc(fipo);
+ if (EOF != c) {
+ ub = (unsigned char)c;
+ res = dk4tsp32_add_one_byte(&tsp32, ub);
+ switch (res) {
+ case DK4_TSP_RES_ERROR: {
+ exval = EXIT_FAILURE;
+ dk4tsp32_get_errors(&er_en, &er_pr, &tsp32);
+ dk_t2h_report_errors(&er_en, &er_pr);
+ } break;
+ case DK4_TSP_RES_FATAL: {
+ cc = -1;
+ exval = EXIT_FAILURE;
+ dk4tsp32_get_errors(&er_en, &er_pr, &tsp32);
+ dk_t2h_report_errors(&er_en, &er_pr);
+ } break;
+ default: {
+ } break;
+ }
+ } else {
+ cc = 0;
+ }
+ if (0 != feof(fipo)) { if (1 == cc) { cc = 0; } }
+ } else {
+ cc = -1;
+ }
+ }
+ if (0 == cc) {
+ res = dk4tsp32_finish(&tsp32);
+ switch (res) {
+ case DK4_TSP_RES_ERROR: case DK4_TSP_RES_FATAL: {
+ exval = EXIT_FAILURE;
+ dk4tsp32_get_errors(&er_en, &er_pr, &tsp32);
+ dk_t2h_report_errors(&er_en, &er_pr);
+ } break;
+ }
+ }
+ if (0 != dk_t2h_can_continue()) {
+ if ((0 == dk_t2h_last_nl) && (0 != dk_t2h_lhtx)) {
+ (void)dk_t2h_c32_after_cr_nl_check(dkC32(0x0A));
+ }
+ }
+ } else {
+ exval = EXIT_FAILURE;
+ /* ERROR: Setup failed, should not happen, bug */
+ }
+ dk_t2h_output_finish_file();
+ dk4app_set_log_source_file(app, oldsourcefile);
+ dk4app_set_log_source_line(app, oldsourceline);
+}
+
+
+
+/** Process standard input.
+*/
+static
+void
+dk_t2h_process_stdin(void)
+{
+#if DK4_ON_WINDOWS
+ int oldmode;
+
+ oldmode = _setmode(_fileno(stdin), _O_BINARY);
+#endif
+ dk_t2h_process_named_file(stdin, dk_t2h_kwnl[4], dk_t2h_i_std);
+#if DK4_ON_WINDOWS
+ _setmode(_fileno(stdin), oldmode);
+#endif
+}
+
+
+
+/** Process one real file name.
+ @param infname File name to process.
+*/
+static
+void
+dk_t2h_process_one_file_name(const dkChar *infname)
+{
+ FILE *fipo = NULL;
+ int tests = DK4_FOPEN_SC_IS_REGULAR;
+ fipo = dk4fopen_app(infname, dk_t2h_kwnl[3], tests, app);
+ if (NULL != fipo) {
+ dk_t2h_process_named_file(fipo, infname, dk_t2h_i_file);
+ fclose(fipo);
+ } else {
+ exval = EXIT_FAILURE;
+ }
+}
+
+
+
+#if DK4_ON_WINDOWS
+
+/** Expand file name pattern and process the files.
+ @pattern File name pattern to expand.
+ @return 1 if files were found, 0 otherwise.
+*/
+static
+int
+dk_t2h_expand_and_process(const dkChar *pattern)
+{
+ dkChar buf[DK4_MAX_PATH];
+ dk4_dir_t *fne;
+ const dkChar *shf;
+ const dkChar *pth;
+ int cc;
+ int back = 0;
+ fne = dk4app_fne_open(pattern, app);
+ if (NULL != fne) {
+ cc = 1;
+ while (1 == cc) {
+ if (0 != dk_t2h_can_continue()) {
+ shf = dk4dir_next_file(fne);
+ if (NULL != shf) {
+ back = 1;
+ pth = dk4dir_get_path(fne);
+ if (NULL != pth) {
+ if (0 != dk4str_cpy_s(buf, DK4_SIZEOF(buf,dkChar), pth, NULL)) {
+ if(0!=dk4str_cat_s(buf,DK4_SIZEOF(buf,dkChar),dk_t2h_kwnl[5],NULL))
+ {
+ if(0 != dk4str_cat_s(buf, DK4_SIZEOF(buf,dkChar), shf, NULL)) {
+ dk_t2h_process_one_file_name(buf);
+ } else {
+ exval = EXIT_FAILURE;
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ }
+ }
+ else
+ {
+ exval = EXIT_FAILURE;
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ }
+ } else {
+ exval = EXIT_FAILURE;
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ }
+ } else {
+ dk_t2h_process_one_file_name(shf);
+ }
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = -1;
+ }
+ }
+ dk4dir_close(fne);
+ } else {
+ exval = EXIT_FAILURE;
+ }
+ return back;
+}
+
+#endif
+
+
+
+/** Process one file name, check whether expansion is necessary.
+ @param infname Input file name to process, may be NULL.
+*/
+static
+void
+dk_t2h_process_filename(const dkChar *infname)
+{
+ if (NULL != infname) {
+#if DK4_ON_WINDOWS
+ if (0 != dk4path_must_expand(infname)) {
+ if (0 == dk_t2h_expand_and_process(infname)) {
+ exval = EXIT_FAILURE;
+ /* ERROR: No such file */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 107, infname);
+ }
+ } else {
+#endif
+ dk_t2h_process_one_file_name(infname);
+#if DK4_ON_WINDOWS
+ }
+#endif
+ }
+}
+
+
+
+/** Run after installing the signal handlers.
+*/
+static
+void
+dk_t2h_normal_run(void)
+{
+ int argc;
+ int i;
+ if (0 != dk_t2h_process_options()) {
+ exval = EXIT_SUCCESS;
+ dk_t2h_output_start_page();
+ if (0 != dk_t2h_echo) {
+ dk_t2h_process_cmdline();
+ } else {
+ argc = dk4app_get_argc(app);
+ if (0 < argc) {
+ for (i = 0; ((0 != dk_t2h_can_continue()) && (i < argc)); i++) {
+ dk_t2h_process_filename(dk4app_get_argv(app, i));
+ }
+ } else {
+ dk_t2h_process_stdin();
+ }
+ }
+ dk_t2h_output_finish_page();
+ }
+}
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+dk_t2h_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ struct sigaction opipe;
+#endif
+ struct sigaction oint;
+#ifdef SIGPIPE
+ struct sigaction npipe;
+#endif
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+ int success = 0;
+
+#ifdef SIGPIPE
+ /* Set up signal handling for SIGPIPE.
+ */
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+#endif
+
+ /* Set up signal handling for SIGINT.
+ */
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ dk_t2h_normal_run();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+#ifdef SIGPIPE
+ /* Restore signal handling for SIGPIPE.
+ */
+ restore_old_pipe:
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+#endif
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+dk_t2h_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ dk_t2h_normal_run();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+#ifdef SIGPIPE
+ sigset(SIGPIPE, oldpipe);
+#endif
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+dk_t2h_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = signal(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ dk_t2h_normal_run();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+#ifdef SIGPIPE
+ signal(SIGPIPE, oldpipe);
+#endif
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+dk_t2h_run_with_signal_handlers(void)
+{
+ dk_t2h_normal_run();
+}
+#endif
+#endif
+#endif
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ int shp;
+
+
+#line 2104 "dk-t2h.ctr"
+
+
+#line 2105 "dk-t2h.ctr"
+ dk4fput_initialize_stderr();
+ app = dk4app_open_cmd(
+ argc, argv, dk_t2h_options, dk_t2h_sz_options,
+ dk_t2h_kwnl[0], DKT_VERSION_DK,
+ dk_t2h_kwnl[1], dk_t2h_help_text, dk_t2h_license_text
+ );
+ if (NULL != app) {
+ dk_t2h_i_std = dk4app_get_stdin_encoding(app);
+ dk_t2h_i_file = dk4app_get_file_in_encoding(app);
+ dk_t2h_sz_msg = dk4app_string_table_size(dk_t2h_kw_def);
+ dk_t2h_msg = dk4app_string_table(app, dk_t2h_kwnl[2], dk_t2h_kw_def);
+ if (0 != dk4app_can_run_normally(app)) {
+ dk_t2h_run_with_signal_handlers();
+ } else {
+ dk4fput_initialize_stdout();
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ fflush(stdout);
+ fflush(stderr);
+ dk4fput_cleanup_stdout();
+ }
+ if (0 != sig_read_atomic(&sig_had_int )) {
+ exval = EXIT_FAILURE;
+ /* ERROR: Interrupted by SIGINT */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 10);
+ }
+ if (0 != sig_read_atomic(&sig_had_term)) {
+ exval = EXIT_FAILURE;
+ /* ERROR: Interrupted by SIGTERM */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 11);
+ }
+#ifdef SIGPIPE
+ if (0 != sig_read_atomic(&sig_had_pipe)) {
+ exval = EXIT_FAILURE;
+ shp = 1;
+ /* ERROR: Interrupted by SIGPIPE */
+ if (0 != verbose) {
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 12);
+ }
+ } else {
+ shp = 0;
+ }
+#else
+ shp = 0;
+#endif
+ if ((0 == shp) && (0 != output_error)) {
+ exval = EXIT_FAILURE;
+ /* ERROR: Output to stdout failed */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 13);
+ }
+ dk4app_close(app);
+ }
+ fflush(stdout);
+ if (0 != sig_read_atomic(&sig_had_int )) { exval = EXIT_FAILURE; }
+ if (0 != sig_read_atomic(&sig_had_term)) { exval = EXIT_FAILURE; }
+#ifdef SIGPIPE
+ if (0 != sig_read_atomic(&sig_had_pipe)) { exval = EXIT_FAILURE; }
+#endif
+ if (0 != output_error) { exval = EXIT_FAILURE; }
+ fflush(stderr);
+ dk4fput_cleanup_stderr();
+
+
+#line 2168 "dk-t2h.ctr"
+
+
+#line 2169 "dk-t2h.ctr"
+ exit(exval); return exval;
+}
+
+
diff --git a/support/dktools/dk-t2h.ctr b/support/dktools/dk-t2h.ctr
new file mode 100644
index 0000000000..e49df93963
--- /dev/null
+++ b/support/dktools/dk-t2h.ctr
@@ -0,0 +1,2172 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% module
+
+/** @file dk-th2.c The dk-t2h program.
+ See dk_t2h_help_text for details.
+*/
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4enc.h"
+#include "dk4mem.h"
+#include "dk4app.h"
+#include "dk4aopt.h"
+#include "dk4fopda.h"
+#include "dk4fput.h"
+#include "dk4vers.h"
+#include "dk4tsp32.h"
+#include "dk4maodd.h"
+#include "dk4mao8d.h"
+#include "dk4mao8h.h"
+#include "dk4utf8.h"
+#include "dk4utf16.h"
+#include "dk4ansi.h"
+#include "dk4mpl.h"
+#include "dk4strd.h"
+#include "dk4pathd.h"
+
+
+
+$!trace-include
+
+
+
+/** Default help text, shown if no help text file is found.
+*/
+static const dkChar * const dk_t2h_help_text[] = {
+$!text macro=dkT,preprocessor
+
+Text to HTML converter
+
+dk-t2h [<options>] [<file(s)>]
+
+Options:
+-i <encoding> --input-encoding=<encoding> Expected input encoding.
+-l --code-lines Input lines are code lines.
+-e --echo Process command line arguments.
+-f --full Write full HTML file.
+-t <string> --title=<string> Title for full HTML file.
+ --verbose Show error message on SIGPIPE.
+
+--help Show this short help text.
+--manual *** SHOW FULL MANUAL. ***
+--version Show version information.
+--license Show license information.
+
+http://dktools.sourceforge.net
+
+$!end
+};
+
+
+
+/** License text.
+*/
+static const dkChar * const dk_t2h_license_text[] = {
+$!text macro=dkT,preprocessor
+
+This software uses code from the following projects, either directly or as
+a library:
+
+dktools Dirk Krause's tools and libraries.
+ See http://dktools.sourceforge.net/ for more information.
+#if DK4_HAVE_ZLIB_H
+
+zlib Data compression library.
+ See http://www.zlib.net/ for more information.
+#endif
+#if DK4_HAVE_BZLIB_H
+
+bzip2 Data compression program and library.
+ See http://www.bzip.org/ for more information.
+#endif
+
+All the licenses below apply to the program.
+Licenses for used libraries are shown as found on my Scientific Linux 6.x
+computer in the /usr/share/doc directory on 2015-04-01. Check the project
+homepages of the used libraries for additional information and/or updated
+license terms.
+
+
+DK tools and libraries license
+==============================
+Copyright (c) 2015-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#if DK4_HAVE_ZLIB_H
+
+
+Zlib license
+============
+(C) 1995-2004 Jean-loup Gailly and Mark Adler
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+
+Jean-loup Gailly Mark Adler
+jloup@gzip.org madler@alumni.caltech.edu
+#endif
+#if DK4_HAVE_BZLIB_H
+
+
+Bzip2 and libbzip2 library license
+==================================
+This program, "bzip2", the associated library "libbzip2", and all
+documentation, are copyright (C) 1996-2007 Julian R Seward. All
+rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+3. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Julian Seward, jseward@bzip.org
+bzip2/libbzip2 version 1.0.5 of 10 December 2007
+#endif
+
+$!end
+};
+
+
+
+/** Constant text keywords used by the program, not localized.
+*/
+static const dkChar * const dk_t2h_kwnl[] = {
+$!string-table macro=dkT
+#
+# 0 Program group name
+#
+dktools
+#
+# 1 Help text file name
+#
+dk-t2h.txt
+#
+# 2 String table file name
+#
+dk-t2h.str
+#
+# 3 File opening mode, read binary
+#
+rb
+#
+# 4 Pseudo file name for standard input
+#
+stdin
+#
+# 5 Path separator for Windows
+#
+\\
+#
+# 6 Long option for verbose mode
+#
+verbose
+$!end
+};
+
+
+
+/** Constant keywords used by the program, replaced by localized texts.
+*/
+static const dkChar * const dk_t2h_kw_def[] = {
+$!string-table macro=dkT
+#
+# 0 Error: Failed to set up signal handlers!
+#
+Failed to set up signal handlers!
+#
+# 1 Error: Failed to restore signal handlers!
+#
+Failed to restore signal handlers!
+#
+# 2 3 Error: Illegal encoding!
+#
+Illegal encoding: "
+"!
+#
+# 4 Error: Conversion from number to text failed, probably bug!
+#
+Conversion from number to text failed, probably bug!
+#
+# 5 Error: Failed to decode string from UTF-16!
+#
+Failed to decode string from UTF-16!
+#
+# 6 Error: Failed to decode string from ANSI!
+#
+Failed to decode string from ANSI!
+#
+# 7 Error: Failed to decode string from UTF-8!
+#
+Failed to decode string from UTF-8!
+#
+# 8 Error: Too many input lines, line number overflow!
+#
+Too many input lines, line number overflow!
+#
+# 9 Error: No command line arguments specified!
+#
+No command line arguments specified!
+#
+# 10 11 12 13 Errors.
+#
+Aborted by SIGINT signal!
+Aborted by SIGTERM signal!
+Aborted by SIGPIPE signal!
+Failed to write to standard output!
+#
+# 14
+#
+Option -t ignored, only full pages can have a title!
+#
+# 15 ... 20 Error messages
+#
+Decoding failed!\n\tByte:
+Encoding failed!\n\tByte:
+Processing failed!\n\tByte:
+,\n\tCharacter:
+,\n\tPosition in line:
+.
+#
+# 21 ... 26 Error messages
+#
+Decoding failed!
+Encoding failed!
+Processing failed!
+Further decoding failures!
+Further encoding failures!
+Further processing failures!
+$!end
+};
+
+
+
+/** Constant 8 bit text keywords used by the program, not localized.
+*/
+static const char * const dk_t2h_kw8[] = {
+$!string-table
+#
+# 0 ... 4 Start of page
+#
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">\n
+<html>\n
+<head>\n
+<meta name="generator" content="dk-t2h, see http://dktools.sourceforge.net">\n
+<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">\n
+#
+# 5 Title line
+#
+<title>__TITLE__</title>\n
+#
+# 6 ... 33 Remaining start of file
+#
+<!-- style sheet -->\n
+<!-- link rel="StyleSheet" type="text/css" href="__URL__" -->\n
+<!-- Parent node of current document node -->\n
+<!-- link rel="Parent" title="" rev="" href="__URL__" -->\n
+<!-- Document author -->\n
+<!-- link rel="Made" title="" rev="" href="mailto:__MAIL__" -->\n
+<!-- Link to homepage -->\n
+<!-- link rel="Home" title="" rev="" href="__URL__" -->\n
+<!-- Link to table of contents -->\n
+<!-- link rel="ToC" title="" rev="" href="__URL__" -->\n
+<!-- Link to index -->\n
+<!-- link rel="Index" title="" rev="" href="__URL__" -->\n
+<!-- Link to glossary -->\n
+<!-- link rel="Glossary" title="" rev="" href="__URL__" -->\n
+<!-- Link to copyright -->\n
+<!-- link rel="Copyright" title="" rev="" href="__URL__" -->\n
+<!-- Link to upper document node (same as parent?) -->\n
+<!-- link rel="Up" title="" rev="" href="__URL__" -->\n
+<!-- Link to next document -->\n
+<!-- link rel="Next" title="" rev="" href="__URL__" -->\n
+<!-- Link to previous document -->\n
+<!-- link rel="Previous" title="" rev="" href="__URL__" -->\n
+<!-- Link to help page -->\n
+<!-- link rel="Help" title="" rev="" href="__URL__" -->\n
+<!-- Link to a document node serving as bookmark -->\n
+<!-- link rel="Bookmark" title="" rev="" href="" -->\n
+</head>\n
+<body>\n
+#
+# 34 35 End of file
+#
+</body>\n
+</html>\n
+#
+# 36 37 Title line when title specified
+#
+<title>
+</title>\n
+#
+# 38 39 Start and end of paragraph
+#
+<p>\n
+</p>\n
+#
+# 40 41 Start and end of pre-formatted text
+#
+<pre>\n
+</pre>\n
+#
+# 42 43 44 Code environment
+#
+<code title="
+">
+</code>
+#
+# 45 46 Code for hexadecimal characters
+#
+&#x
+;
+$!end
+};
+
+
+
+/** Options for the program.
+*/
+static const dk4_option_specification_t dk_t2h_options[] = {
+ { dkT('i'), dkT("input-encoding"), DK4_OPT_ARG_STRING },
+ { dkT('l'), dkT("code-lines"), DK4_OPT_ARG_NONE },
+ { dkT('e'), dkT("echo"), DK4_OPT_ARG_NONE },
+ { dkT('f'), dkT("full"), DK4_OPT_ARG_NONE },
+ { dkT('t'), dkT("title"), DK4_OPT_ARG_STRING },
+ { dkT('\0'), dkT("verbose"), DK4_OPT_ARG_STRING }
+};
+
+
+
+/** Translation table for ASCII characters.
+*/
+static char const * const dk_t2h_translation_table[] = {
+/* 0 00 */ NULL,
+/* 1 01 */ NULL,
+/* 2 02 */ NULL,
+/* 3 03 */ NULL,
+/* 4 04 */ NULL,
+/* 5 05 */ NULL,
+/* 6 06 */ NULL,
+/* 7 07 */ NULL,
+/* 8 08 */ NULL,
+/* 9 09 */ "\t",
+/* 10 0a */ NULL,
+/* 11 0b */ NULL,
+/* 12 0c */ NULL,
+/* 13 0d */ NULL,
+/* 14 0e */ NULL,
+/* 15 0f */ NULL,
+/* 16 10 */ NULL,
+/* 17 11 */ NULL,
+/* 18 12 */ NULL,
+/* 19 13 */ NULL,
+/* 20 14 */ NULL,
+/* 21 15 */ NULL,
+/* 22 16 */ NULL,
+/* 23 17 */ NULL,
+/* 24 18 */ NULL,
+/* 25 19 */ NULL,
+/* 26 1a */ NULL,
+/* 27 1b */ NULL,
+/* 28 1c */ NULL,
+/* 29 1d */ NULL,
+/* 30 1e */ NULL,
+/* 31 1f */ NULL,
+/* 32 20 */ " ",
+/* 33 21 */ "!",
+/* 34 22 */ "&quot;",
+/* 35 23 */ "#",
+/* 36 24 */ "$",
+/* 37 25 */ "%",
+/* 38 26 */ "&amp;",
+/* 39 27 */ "'",
+/* 40 28 */ "(",
+/* 41 29 */ ")",
+/* 42 2a */ "*",
+/* 43 2b */ "+",
+/* 44 2c */ ",",
+/* 45 2d */ "-",
+/* 46 2e */ ".",
+/* 47 2f */ "/",
+/* 48 30 */ "0",
+/* 49 31 */ "1",
+/* 50 32 */ "2",
+/* 51 33 */ "3",
+/* 52 34 */ "4",
+/* 53 35 */ "5",
+/* 54 36 */ "6",
+/* 55 37 */ "7",
+/* 56 38 */ "8",
+/* 57 39 */ "9",
+/* 58 3a */ ":",
+/* 59 3b */ ";",
+/* 60 3c */ "&lt;",
+/* 61 3d */ "=",
+/* 62 3e */ "&gt;",
+/* 63 3f */ "?",
+/* 64 40 */ "@",
+/* 65 41 */ "A",
+/* 66 42 */ "B",
+/* 67 43 */ "C",
+/* 68 44 */ "D",
+/* 69 45 */ "E",
+/* 70 46 */ "F",
+/* 71 47 */ "G",
+/* 72 48 */ "H",
+/* 73 49 */ "I",
+/* 74 4a */ "J",
+/* 75 4b */ "K",
+/* 76 4c */ "L",
+/* 77 4d */ "M",
+/* 78 4e */ "N",
+/* 79 4f */ "O",
+/* 80 50 */ "P",
+/* 81 51 */ "Q",
+/* 82 52 */ "R",
+/* 83 53 */ "S",
+/* 84 54 */ "T",
+/* 85 55 */ "U",
+/* 86 56 */ "V",
+/* 87 57 */ "W",
+/* 88 58 */ "X",
+/* 89 59 */ "Y",
+/* 90 5a */ "Z",
+/* 91 5b */ "[",
+/* 92 5c */ "\\",
+/* 93 5d */ "]",
+/* 94 5e */ "^",
+/* 95 5f */ "_",
+/* 96 60 */ "`",
+/* 97 61 */ "a",
+/* 98 62 */ "b",
+/* 99 63 */ "c",
+/* 100 64 */ "d",
+/* 101 65 */ "e",
+/* 102 66 */ "f",
+/* 103 67 */ "g",
+/* 104 68 */ "h",
+/* 105 69 */ "i",
+/* 106 6a */ "j",
+/* 107 6b */ "k",
+/* 108 6c */ "l",
+/* 109 6d */ "m",
+/* 110 6e */ "n",
+/* 111 6f */ "o",
+/* 112 70 */ "p",
+/* 113 71 */ "q",
+/* 114 72 */ "r",
+/* 115 73 */ "s",
+/* 116 74 */ "t",
+/* 117 75 */ "u",
+/* 118 76 */ "v",
+/* 119 77 */ "w",
+/* 120 78 */ "x",
+/* 121 79 */ "y",
+/* 122 7a */ "z",
+/* 123 7b */ "{",
+/* 124 7c */ "|",
+/* 125 7d */ "}",
+/* 126 7e */ "~",
+/* 127 7f */ NULL,
+/* 128 80 */ NULL,
+/* 129 81 */ NULL,
+/* 130 82 */ NULL,
+/* 131 83 */ NULL,
+/* 132 84 */ NULL,
+/* 133 85 */ NULL,
+/* 134 86 */ NULL,
+/* 135 87 */ NULL,
+/* 136 88 */ NULL,
+/* 137 89 */ NULL,
+/* 138 8a */ NULL,
+/* 139 8b */ NULL,
+/* 140 8c */ NULL,
+/* 141 8d */ NULL,
+/* 142 8e */ NULL,
+/* 143 8f */ NULL,
+/* 144 90 */ NULL,
+/* 145 91 */ NULL,
+/* 146 92 */ NULL,
+/* 147 93 */ NULL,
+/* 148 94 */ NULL,
+/* 149 95 */ NULL,
+/* 150 96 */ NULL,
+/* 151 97 */ NULL,
+/* 152 98 */ NULL,
+/* 153 99 */ NULL,
+/* 154 9a */ NULL,
+/* 155 9b */ NULL,
+/* 156 9c */ NULL,
+/* 157 9d */ NULL,
+/* 158 9e */ NULL,
+/* 159 9f */ NULL,
+/* 160 a0 */ "&nbsp;",
+/* 161 a1 */ "&iexcl;",
+/* 162 a2 */ "&cent;",
+/* 163 a3 */ "&pound;",
+/* 164 a4 */ "&curren;",
+/* 165 a5 */ "&yen;",
+/* 166 a6 */ "&brvbar;",
+/* 167 a7 */ "&sect;",
+/* 168 a8 */ "&uml;",
+/* 169 a9 */ "&copy;",
+/* 170 aa */ "&ordf;",
+/* 171 ab */ "&laquo;",
+/* 172 ac */ "&not;",
+/* 173 ad */ "&shy;",
+/* 174 ae */ "&reg;",
+/* 175 af */ "&macr;",
+/* 176 b0 */ "&deg;",
+/* 177 b1 */ "&plusmn;",
+/* 178 b2 */ "&sup2;",
+/* 179 b3 */ "&sup3;",
+/* 180 b4 */ "&acute;",
+/* 181 b5 */ "&micro;",
+/* 182 b6 */ "&para;",
+/* 183 b7 */ "&middot;",
+/* 184 b8 */ "&cedil;",
+/* 185 b9 */ "&sup1;",
+/* 186 ba */ "&ordm;",
+/* 187 bb */ "&raquo;",
+/* 188 bc */ "&frac14;",
+/* 189 bd */ "&frac12;",
+/* 190 be */ "&frac34;",
+/* 191 bf */ "&iquest;",
+/* 192 c0 */ "&Agrave;",
+/* 193 c1 */ "&Aacute;",
+/* 194 c2 */ "&Acirc;",
+/* 195 c3 */ "&Atilde;",
+/* 196 c4 */ "&Auml;",
+/* 197 c5 */ "&Aring;",
+/* 198 c6 */ "&AElig;",
+/* 199 c7 */ "&Ccedil;",
+/* 200 c8 */ "&Egrave;",
+/* 201 c9 */ "&Eacute;",
+/* 202 ca */ "&Ecirc;",
+/* 203 cb */ "&Euml;",
+/* 204 cc */ "/Igrave;",
+/* 205 cd */ "&Iacute;",
+/* 206 ce */ "&Icirc;",
+/* 207 cf */ "&Iuml;",
+/* 208 d0 */ "&ETH;",
+/* 209 d1 */ "&Ntilde;",
+/* 210 d2 */ "&Ograve;",
+/* 211 d3 */ "&Oacute;",
+/* 212 d4 */ "&Ocirc;",
+/* 213 d5 */ "&Otilde;",
+/* 214 d6 */ "&Ouml;",
+/* 215 d7 */ "&times;",
+/* 216 d8 */ "&Oslash;",
+/* 217 d9 */ "&Ugrave;",
+/* 218 da */ "&Uacute;",
+/* 219 db */ "&Ucirc;",
+/* 220 dc */ "&Uuml;",
+/* 221 dd */ "&Yacute;",
+/* 222 de */ "&THORN;",
+/* 223 df */ "&szlig;",
+/* 224 e0 */ "&agrave;",
+/* 225 e1 */ "&aacute;",
+/* 226 e2 */ "&acirc;",
+/* 227 e3 */ "&atilde;",
+/* 228 e4 */ "&auml;",
+/* 229 e5 */ "&aring;",
+/* 230 e6 */ "&aelig;",
+/* 231 e7 */ "&ccedil;",
+/* 232 e8 */ "&egrave;",
+/* 233 e9 */ "&eacute;",
+/* 234 ea */ "&ecirc;",
+/* 235 eb */ "&euml;",
+/* 236 ec */ "&igrave;",
+/* 237 ed */ "&iacute;",
+/* 238 ee */ "&icirc;",
+/* 239 ef */ "&iuml;",
+/* 240 f0 */ "&eth;",
+/* 241 f1 */ "&ntilde;",
+/* 242 f2 */ "&ograve;",
+/* 243 f3 */ "&oacute;",
+/* 244 f4 */ "&ocirc;",
+/* 245 f5 */ "&otilde;",
+/* 246 f6 */ "&ouml;",
+/* 247 f7 */ "&divide;",
+/* 248 f8 */ "&oslash;",
+/* 249 f9 */ "&ugrave;",
+/* 250 fa */ "&uacute;",
+/* 251 fb */ "&ucirc;",
+/* 252 fc */ "&uuml;",
+/* 253 fd */ "&yacute;",
+/* 254 fe */ "&thorn;",
+/* 255 ff */ "&yuml;"
+};
+
+
+/** Pointer to localized or not localized texts.
+*/
+static const dkChar * const *dk_t2h_msg = dk_t2h_kw_def;
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Page title for full HTML page, if specified on command line.
+*/
+static const dkChar *dk_t2h_title = NULL;
+
+
+
+/** Current line number.
+*/
+static dk4_um_t dk_t2h_lineno = (dk4_um_t)1UL;
+
+
+
+/** Number of elements in the dk_t2h_options array.
+*/
+static const size_t dk_t2h_sz_options =
+sizeof(dk_t2h_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Number of elements in dk_t2h_msg array.
+*/
+static size_t dk_t2h_sz_msg =
+sizeof(dk_t2h_kw_def)/sizeof(DK4_PCDKCHAR) - 1;
+
+
+/** Program exit status.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+/** Flag: Error occured while writing to stdout.
+*/
+static int output_error = 0;
+
+
+
+/** Flag: Verbose output (report SIGPIPE).
+*/
+static int verbose = 0;
+
+
+
+/** Flag: Echo command line arguments instead of processing files.
+*/
+static int dk_t2h_echo = 0;
+
+
+
+/** Flag: Produce full HTML page, not just a fragment.
+*/
+static int dk_t2h_full = 0;
+
+
+
+/** Flag: Wrap all lines in code environments.
+*/
+static int dk_t2h_code = 0;
+
+
+
+/** Input encoding expected when processing stdin.
+*/
+static int dk_t2h_i_std = DK4_FILE_ENCODING_ASCII;
+
+
+
+/** Input encoding expected when processing files.
+*/
+static int dk_t2h_i_file = DK4_FILE_ENCODING_ASCII;
+
+
+
+/** Number of decoding errors in current file.
+*/
+static int dk_t2h_dec_err = 0;
+
+
+
+/** Number of encoding errors in current file.
+*/
+static int dk_t2h_enc_err = 0;
+
+
+
+/** Number of processing errors in current file.
+*/
+static int dk_t2h_pro_err = 0;
+
+
+
+/** Flag: Previous character was carriage return.
+*/
+static int dk_t2h_last_cr = 0;
+
+
+
+/** Flag: Previous character was newline.
+*/
+static int dk_t2h_last_nl = 0;
+
+
+
+/** Flag: Have text in line, newline needed.
+*/
+static int dk_t2h_lhtx = 0;
+
+
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+/** Pass a volatile pointer to an atomic integer.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ptr Address of atomic integer variable.
+ @return The unmodified pointer.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+/** Check whether we can continue or if a signal was received.
+ @param check_pipe Flag: Check for occured SIGPIPE signal too.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(int check_pipe)
+{
+ int back = 1;
+#ifdef SIGPIPE
+ if (0 != check_pipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_int )) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+/** Check whether we can continue.
+ @return 1 for yes, 0 for no.
+*/
+static
+int
+dk_t2h_can_continue(void)
+{
+ int back = 1;
+ if (0 == sig_can_continue(1)) {
+ back = 0;
+ }
+ return back;
+}
+
+
+
+/** Process command line options.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk_t2h_process_options(void)
+{
+ const dkChar *oaptr;
+ int encval = 0;
+ int bomval = 0;
+ int back = 1;
+ if (0 != dk4app_opt_is_set_long(app, dk_t2h_kwnl[6], NULL)) {
+ verbose = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('i'), NULL)) {
+ oaptr = dk4app_opt_get_string_ptr_short(app, dkT('i'), NULL);
+ if (NULL != oaptr) {
+ if (0 != dk4enc_find(&encval, &bomval, oaptr, NULL)) {
+ dk_t2h_i_std = dk_t2h_i_file = encval;
+ } else {
+ /* ERROR: Illegal encoding */
+ back = 0;
+ dk4app_log_3(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 2, 3, oaptr);
+ }
+ } else { $? "! bug"
+ /* ERROR: Failed to obtain option argument, bug! */
+ }
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('e'), NULL)) {
+ dk_t2h_echo = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('l'), NULL)) {
+ dk_t2h_code = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('f'), NULL)) {
+ dk_t2h_full = 1;
+ if (0 != dk4app_opt_is_set_short(app, dkT('t'), NULL)) {
+ dk_t2h_title = dk4app_opt_get_string_ptr_short(app, dkT('t'), NULL);
+ }
+ } else {
+ if (0 != dk4app_opt_is_set_short(app, dkT('t'), NULL)) {
+ back = 0;
+ /* ERROR: Title only for full pages */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 14);
+ }
+ }
+ return back;
+}
+
+
+
+/** Handler function after processing CR/NL sequences.
+ Here we do the real output.
+ @param c Character to process.
+ @return Result code:
+ - DK4_TSP_RES_OK if the character was processed successfully,
+ - DK4_TSP_RES_ERROR if there was an error but we can continue,
+ - DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+dk_t2h_c32_after_cr_nl_check(
+ dk4_c32_t c
+)
+{
+ char buf[16*sizeof(dk4_um_t)];
+ size_t i;
+ int back = DK4_TSP_RES_OK;
+ int res = 0;
+ int done = 0;
+ $? "+ dk_t2h_c32_after_cr_nl_check"
+ if (dkC32(0x0A) == c) { $? ". newline"
+ /*
+ Newline, finish line and write newline to output.
+ */
+ if (0 != dk_t2h_code) { $? ". code"
+ if (0 == dk_t2h_lhtx) {
+ if (EOF == fputs(dk_t2h_kw8[42], stdout)) { output_error = 1; }
+ res = dk4ma_write_c8_decimal_unsigned(
+ buf, sizeof(buf), dk_t2h_lineno, 0, NULL
+ );
+ if (0 != res) {
+ i = strlen(buf);
+ while (3 > i++) {
+ if (EOF == fputc('0', stdout)) { output_error = 1; }
+ }
+ if (EOF == fputs(buf, stdout)) { output_error = 1; }
+ }
+ if (EOF == fputs(dk_t2h_kw8[43], stdout)) { output_error = 1; }
+ dk_t2h_lhtx = 1;
+ }
+ if (0 != dk_t2h_lhtx) { $? ". already text in line"
+ if (EOF == fputs(dk_t2h_kw8[44], stdout)) { output_error = 1; }
+ } else { $? ". no text in line yet"
+ }
+ } else { $? ". not code"
+ }
+ if (EOF == fputc('\n', stdout)) { output_error = 1; }
+ } else { $? ". not newline"
+ if (0 != dk_t2h_code) { $? ". code"
+ if (0 == dk_t2h_lhtx) { $? ". no text in line yet"
+ /*
+ Start new line.
+ */
+ if (EOF == fputs(dk_t2h_kw8[42], stdout)) { output_error = 1; }
+ res = dk4ma_write_c8_decimal_unsigned(
+ buf, sizeof(buf), dk_t2h_lineno, 0, NULL
+ );
+ if (0 != res) {
+ i = strlen(buf);
+ while (3 > i++) {
+ if (EOF == fputc('0', stdout)) { output_error = 1; }
+ }
+ if (EOF == fputs(buf, stdout)) { output_error = 1; }
+ }
+ if (EOF == fputs(dk_t2h_kw8[43], stdout)) { output_error = 1; }
+ dk_t2h_lhtx = 1;
+ } else { $? ". already text in line"
+ }
+ } else { $? ". not code"
+ }
+ /*
+ Write character to output.
+ */
+ if (dkC32(0x00000100) > c) {
+ i = (size_t)c;
+ i &= 0x0000FFU;
+ if (NULL != dk_t2h_translation_table[i]) {
+ if (EOF == fputs(dk_t2h_translation_table[i], stdout)) {
+ output_error = 1;
+ }
+ done = 1;
+ }
+ }
+ if (0 == done) {
+ res = dk4ma_write_c8_hex_unsigned(
+ buf, sizeof(buf), (dk4_um_t)c, 0, NULL
+ );
+ if (0 != res) {
+ i = strlen(buf);
+ if (EOF == fputs(dk_t2h_kw8[45], stdout)) { output_error = 1; }
+ if (0 != (i % 2)) {
+ if (EOF == fputc('0', stdout)) { output_error = 1; }
+ }
+ if (EOF == fputs(buf, stdout)) { output_error = 1; }
+ if (EOF == fputs(dk_t2h_kw8[46], stdout)) { output_error = 1; }
+ } else {
+ exval = EXIT_FAILURE;
+ /* ERROR: Conversion */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 4);
+ }
+ }
+ } $? "- dk_t2h_c32_after_cr_nl_check %d", back
+ return back;
+}
+
+
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+/* +++++ 4 +++++ */
+
+/** Write 32 bit character string.
+ @param str String to write.
+*/
+static
+void
+dk_t2h_output_c32(const dk4_c32_t *str)
+{
+ while (dkC32(0x00) != *str) {
+ switch (dk_t2h_c32_after_cr_nl_check(*(str++))) {
+ case DK4_TSP_RES_ERROR : case DK4_TSP_RES_FATAL : {
+ exval = EXIT_FAILURE;
+ } break;
+ }
+ }
+}
+
+/* ----- 4 ----- */
+#else
+/* +++++ 2 +++++ */
+
+/** Write UTF-16 encoded text string.
+ @param str String to write.
+*/
+static
+void
+dk_t2h_output_utf16(const dk4_c16_t *str)
+{
+ dk4_utf16_decoder_t dec;
+ int cc;
+
+ dk4utf16_init(&dec);
+ cc = 1;
+ while (1 == cc) {
+ if (dkC16(0) != *str) {
+ switch (dk4utf16_add(&dec, *(str++))) {
+ case DK4_EDSTM_ERROR : {
+ cc = -1;
+ /* ERROR: Decoding error */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 5);
+ } break;
+ case DK4_EDSTM_FINISHED : {
+ switch (dk_t2h_c32_after_cr_nl_check(dk4utf16_get(&dec))) {
+ case DK4_TSP_RES_ERROR : case DK4_TSP_RES_FATAL : {
+ exval = EXIT_FAILURE;
+ } break;
+ }
+ } break;
+ }
+ } else {
+ cc = 0;
+ }
+ }
+ if (0 == cc) {
+ if (0 == dk4utf16_is_empty(&dec)) {
+ /* Decoding error */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 5);
+ exval = EXIT_FAILURE;
+ }
+ }
+}
+
+/* ----- 2 ----- */
+#endif
+#else
+/* +++++ 1 +++++ */
+
+/** Write ASCII encoded text string.
+ @param str String to write.
+*/
+static
+void
+dk_t2h_output_ascii(const char *str)
+{
+ dk4_c32_t c32;
+ while ('\0' != *str) {
+ c32 = dkC32(0xFF) & ((dk4_c32_t)((unsigned char)(*(str++))));
+ switch (dk_t2h_c32_after_cr_nl_check(c32)) {
+ case DK4_TSP_RES_ERROR : case DK4_TSP_RES_FATAL : {
+ exval = EXIT_FAILURE;
+ } break;
+ }
+ }
+}
+
+
+
+/** Write ANSI encoded text string.
+ @param str String to write.
+*/
+static
+void
+dk_t2h_output_ansi(const char *str)
+{
+ dk4_c32_t c32;
+ char c;
+ while ('\0' != *str) {
+ c = *(str++);
+ if (0 != dk4ansi_decode(&c32, (unsigned char)c)) {
+ switch (dk_t2h_c32_after_cr_nl_check(c32)) {
+ case DK4_TSP_RES_ERROR : case DK4_TSP_RES_FATAL : {
+ exval = EXIT_FAILURE;
+ }
+ }
+ } else {
+ exval = EXIT_FAILURE;
+ /* ERROR: Decoding error */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 6);
+ }
+ }
+}
+
+
+
+/** Write UTF-8 encoded string.
+ @param str String to write.
+*/
+static
+void
+dk_t2h_output_utf8(const char *str)
+{
+ dk4_utf8_decoder_t dec;
+ int cc;
+
+ cc = 1;
+ dk4utf8_init(&dec);
+ while (1 == cc) {
+ if ('\0' != *str) {
+ switch (dk4utf8_add(&dec, *(str++))) {
+ case DK4_EDSTM_ERROR : {
+ cc = -1;
+ exval = EXIT_FAILURE;
+ /* Decoding error */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 7);
+ } break;
+ case DK4_EDSTM_FINISHED : {
+ switch (dk_t2h_c32_after_cr_nl_check(dk4utf8_get(&dec))) {
+ case DK4_TSP_RES_ERROR : case DK4_TSP_RES_FATAL : {
+ exval = EXIT_FAILURE;
+ }
+ }
+ } break;
+ }
+ } else {
+ cc = 0;
+ }
+ }
+ if (0 == cc) {
+ if (0 == dk4utf8_is_empty(&dec)) {
+ exval = EXIT_FAILURE;
+ /* ERROR: Decoding error */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 7);
+ }
+ }
+}
+
+/* ----- 1 ----- */
+#endif
+
+
+
+static
+void
+dk_t2h_output_dkstring(const dkChar *str)
+{
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ dk_t2h_output_c32(str);
+#else
+ dk_t2h_output_utf16(str);
+#endif
+#else
+ switch (dk4app_get_encoding(app)) {
+ case DK4_FILE_ENCODING_UTF8 : {
+ dk_t2h_output_utf8(str);
+ } break;
+ case DK4_FILE_ENCODING_ANSI : {
+ dk_t2h_output_ansi(str);
+ } break;
+ default : {
+ dk_t2h_output_ascii(str);
+ } break;
+ }
+#endif
+}
+
+
+
+/** Start output page.
+*/
+static
+void
+dk_t2h_output_start_page(void)
+{
+ size_t i;
+ if (0 != dk_t2h_full) {
+ if (NULL != dk_t2h_title) {
+ for (i = 0; i < 5; i++) {
+ if (EOF == fputs(dk_t2h_kw8[i], stdout)) { output_error = 1; }
+ }
+ if (EOF == fputs(dk_t2h_kw8[36], stdout)) { output_error = 1; }
+ dk_t2h_output_dkstring(dk_t2h_title);
+ if (EOF == fputs(dk_t2h_kw8[37], stdout)) { output_error = 1; }
+ for (i = 6; i < 34; i++) {
+ if (EOF == fputs(dk_t2h_kw8[i], stdout)) { output_error = 1; }
+ }
+ } else {
+ for (i = 0; i < 34; i++) {
+ if (EOF == fputs(dk_t2h_kw8[i], stdout)) { output_error = 1; }
+ }
+ }
+ }
+}
+
+
+
+/** Finish output page.
+*/
+static
+void
+dk_t2h_output_finish_page(void)
+{
+ size_t i;
+
+ if (0 != dk_t2h_full) {
+ for (i = 34; i < 36; i++) {
+ if (EOF == fputs(dk_t2h_kw8[i], stdout)) { output_error = 1; }
+ }
+ }
+}
+
+
+
+/** Start processing of one file.
+*/
+static
+void
+dk_t2h_output_start_file(void)
+{
+ $? "+ dk_t2h_output_start_file"
+ /* No errors in this file yet.
+ */
+ dk_t2h_dec_err = 0;
+ dk_t2h_enc_err = 0;
+ dk_t2h_pro_err = 0;
+ dk_t2h_last_cr = 0;
+ dk_t2h_last_nl = 0;
+ dk_t2h_lhtx = 0;
+ dk_t2h_lineno = (dk4_um_t)1UL;
+ dk4app_set_log_source_line(app, dk_t2h_lineno);
+ if (0 != dk_t2h_full) { $? ". full"
+ if (0 != dk_t2h_code) { $? ". code"
+ if (EOF == fputs(dk_t2h_kw8[40], stdout)) { output_error = 1; }
+ } else { $? ". not code"
+ if (EOF == fputs(dk_t2h_kw8[38], stdout)) { output_error = 1; }
+ }
+ }
+ $? "- dk_t2h_output_start_file"
+}
+
+
+
+/** Finish processing of one file.
+*/
+static
+void
+dk_t2h_output_finish_file(void)
+{
+ $? "+ dk_t2h_output_finish_file"
+ if (0 != dk_t2h_full) { $? ". full"
+ if (0 != dk_t2h_code) { $? ". code"
+ if (EOF == fputs(dk_t2h_kw8[41], stdout)) { output_error = 1; }
+ } else { $? ". not code"
+ if (EOF == fputs(dk_t2h_kw8[39], stdout)) { output_error = 1; }
+ }
+ }
+ $? "- dk_t2h_output_finish_file"
+}
+
+
+
+/** Handler function for single characters.
+ @param obj Object to modify while processing the character.
+ @param c Character to process.
+ @param pos Current position in file or data stream.
+ @param erp Error report, may be NULL.
+ @return Result code:
+ - DK4_TSP_RES_OK if the character was processed successfully,
+ - DK4_TSP_RES_ERROR if there was an error but we can continue,
+ - DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+dk_t2h_c32_handler(
+ void *obj,
+ dk4_c32_t c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_TSP_RES_OK;
+ if (dkC32(0x0A) == c) {
+ /*
+ For a newline clear CR and TXT flag, set NL flag.
+ */
+ back = dk_t2h_c32_after_cr_nl_check(c);
+ dk_t2h_lineno++;
+ if ((dk4_um_t)0UL == dk_t2h_lineno) {
+ /* ERROR: Overflow in line number counting */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 8);
+ exval = EXIT_FAILURE;
+ }
+ dk4app_set_log_source_line(app, dk_t2h_lineno);
+ dk_t2h_last_cr = 0;
+ dk_t2h_last_nl = 1;
+ dk_t2h_lhtx = 0;
+ } else {
+ if (dkC32(0x0D) == c) {
+ /*
+ For a cr if CR flag is set, pass the cr and set TXT flag, clear nl flag.
+ Otherwise simply set CR flag.
+ */
+ if (0 != dk_t2h_last_cr) {
+ back = dk_t2h_c32_after_cr_nl_check(dkC32(0x0D));
+ dk_t2h_lhtx = 1;
+ dk_t2h_last_nl = 0;
+ } else {
+ dk_t2h_last_cr = 1;
+ }
+ } else {
+ /*
+ For any other character:
+ If the CR flag is set, pass cr and current character.
+ Otherwise pass the current character.
+ Reset NL and CR flag, set TXT flag.
+ */
+ if (0 != dk_t2h_last_cr) {
+ back = dk_t2h_c32_after_cr_nl_check(dkC32(0x0D));
+ switch (dk_t2h_c32_after_cr_nl_check(c)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ } else {
+ back = dk_t2h_c32_after_cr_nl_check(c);
+ }
+ dk_t2h_lhtx = 1;
+ dk_t2h_last_nl = 0;
+ dk_t2h_last_cr = 0;
+ }
+ }
+ return back;
+}
+
+
+
+/** Process command line arguments.
+*/
+static
+void
+dk_t2h_process_cmdline(void)
+{
+ const dkChar *xargv;
+ int xargc;
+ int i;
+ xargc = dk4app_get_argc(app);
+ if (0 < xargc) {
+ dk_t2h_output_start_file();
+ for (i = 0; i < xargc; i++) {
+ xargv = dk4app_get_argv(app, i);
+ if (0 != i) {
+ if (EOF == fputc(' ', stdout)) { output_error = 1; }
+ }
+ if (NULL != xargv) {
+ dk_t2h_output_dkstring(xargv);
+ }
+ }
+ dk_t2h_c32_after_cr_nl_check(dkC32(0x0A));
+ dk_t2h_output_finish_file();
+ } else {
+ exval = EXIT_FAILURE;
+ /* ERROR: No command line arguments */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 9);
+ }
+}
+
+
+
+/** Report an error with position in source line.
+ @param i1 Index of first message part in array.
+ @param i2 Index of alternative first message part.
+ @param bno Byte processed.
+ @param lno Current line number.
+ @param cno Current character number.
+ @param cil Current character number in line.
+*/
+static
+void
+dk_t2h_report_with_position(
+ size_t i1,
+ size_t i2,
+ dk4_um_t bno,
+ dk4_um_t lno,
+ dk4_um_t cno,
+ dk4_um_t cil
+)
+{
+ dkChar b1[8*(1+sizeof(dk4_um_t))];
+ dkChar b2[8*(1+sizeof(dk4_um_t))];
+ dkChar b3[8*(1+sizeof(dk4_um_t))];
+ dk4_um_t oldlogline = (dk4_um_t)0UL;
+ int allbuffersok = 0;
+
+ oldlogline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_line(app, lno);
+ if (0 != dk4ma_write_decimal_unsigned(b3,DK4_SIZEOF(b3,dkChar),cil,0,NULL)) {
+ if (0 != dk4ma_write_decimal_unsigned(b2,DK4_SIZEOF(b2,dkChar),cno,0,NULL)) {
+ if (0 != dk4ma_write_decimal_unsigned(b1,DK4_SIZEOF(b1,dkChar),bno,0,NULL)) {
+ allbuffersok = 1;
+ }
+ }
+ }
+ if (0 != allbuffersok) {
+ dk4app_log_7(
+ app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, i1, 18, 19, 20, b1, b2, b3
+ );
+ } else {
+ dk4app_log_1(
+ app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, i2
+ );
+ }
+ dk4app_set_log_source_line(app, oldlogline);
+}
+
+
+
+static
+void
+dk_t2h_report_errors(dk4_er_t *er_en, dk4_er_t *er_pr)
+{
+ if (NULL != er_en) {
+ switch (er_en->ec) {
+ case DK4_E_DECODING_FAILED: {
+ switch (dk_t2h_dec_err) {
+ case 0: case 1: {
+ /* ERROR: Decoding failed */
+ dk_t2h_report_with_position(
+ 15, 21,
+ er_en->dt.fpos.byteno,
+ er_en->dt.fpos.lineno,
+ er_en->dt.fpos.charno,
+ er_en->dt.fpos.charinline
+ );
+ } break;
+ case 2: {
+ /* ERROR: Further decoding errors */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 24);
+ } break;
+ }
+ if (3 > dk_t2h_dec_err) { dk_t2h_dec_err++; }
+ } break;
+ case DK4_E_ENCODING_FAILED: {
+ switch (dk_t2h_enc_err) {
+ case 0: case 1: {
+ /* ERROR: Encoding failed */
+ dk_t2h_report_with_position(
+ 16, 22,
+ er_en->dt.fpos.byteno,
+ er_en->dt.fpos.lineno,
+ er_en->dt.fpos.charno,
+ er_en->dt.fpos.charinline
+ );
+ } break;
+ case 2: {
+ /* ERROR: Further encoding erros */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 25);
+ } break;
+ }
+ if (3 > dk_t2h_enc_err) { dk_t2h_enc_err++; }
+ } break;
+ }
+ }
+ if (NULL != er_pr) {
+ if (DK4_E_NONE != er_pr->ec) {
+ switch (dk_t2h_pro_err) {
+ case 0: case 1: {
+ /* ERROR: Processing error */
+ dk_t2h_report_with_position(
+ 17, 23,
+ er_pr->dt.fpos.byteno,
+ er_pr->dt.fpos.lineno,
+ er_pr->dt.fpos.charno,
+ er_pr->dt.fpos.charinline
+ );
+ } break;
+ case 2: {
+ /* ERROR: Further processing errors */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 26);
+ } break;
+ }
+ if (3 > dk_t2h_pro_err) { dk_t2h_pro_err++; }
+ }
+ }
+}
+
+
+
+/** Process an opened file with file name.
+ @param fipo Opened file.
+ @param fn File name.
+ @param ienc_def Expected input encoding.
+*/
+static
+void
+dk_t2h_process_named_file(FILE *fipo, const dkChar *fn, int ienc_def)
+{
+ dk4_tsp32_t tsp32;
+ dk4_er_t er;
+ dk4_er_t er_en;
+ dk4_er_t er_pr;
+ const dkChar *oldsourcefile;
+ dk4_um_t oldsourceline;
+ int c;
+ int cc;
+ int res;
+ unsigned char ub;
+
+ oldsourcefile = dk4app_get_log_source_file(app);
+ oldsourceline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_file(app, fn);
+ dk4app_set_log_source_line(app, (dk4_um_t)0UL);
+ dk_t2h_output_start_file();
+ dk4error_init(&er);
+ res = dk4tsp32_setup_char(
+ &tsp32, NULL, dk_t2h_c32_handler, ienc_def, &er
+ );
+ if (0 != res) {
+ cc = 1;
+ while (1 == cc) {
+ if (0 != dk_t2h_can_continue()) {
+ c = fgetc(fipo);
+ if (EOF != c) {
+ ub = (unsigned char)c;
+ res = dk4tsp32_add_one_byte(&tsp32, ub);
+ switch (res) {
+ case DK4_TSP_RES_ERROR: {
+ exval = EXIT_FAILURE;
+ dk4tsp32_get_errors(&er_en, &er_pr, &tsp32);
+ dk_t2h_report_errors(&er_en, &er_pr);
+ } break;
+ case DK4_TSP_RES_FATAL: {
+ cc = -1;
+ exval = EXIT_FAILURE;
+ dk4tsp32_get_errors(&er_en, &er_pr, &tsp32);
+ dk_t2h_report_errors(&er_en, &er_pr);
+ } break;
+ default: {
+ } break;
+ }
+ } else {
+ cc = 0;
+ }
+ if (0 != feof(fipo)) { if (1 == cc) { cc = 0; } }
+ } else {
+ cc = -1;
+ }
+ }
+ if (0 == cc) {
+ res = dk4tsp32_finish(&tsp32);
+ switch (res) {
+ case DK4_TSP_RES_ERROR: case DK4_TSP_RES_FATAL: {
+ exval = EXIT_FAILURE;
+ dk4tsp32_get_errors(&er_en, &er_pr, &tsp32);
+ dk_t2h_report_errors(&er_en, &er_pr);
+ } break;
+ }
+ }
+ if (0 != dk_t2h_can_continue()) {
+ if ((0 == dk_t2h_last_nl) && (0 != dk_t2h_lhtx)) {
+ (void)dk_t2h_c32_after_cr_nl_check(dkC32(0x0A));
+ }
+ }
+ } else {
+ exval = EXIT_FAILURE;
+ /* ERROR: Setup failed, should not happen, bug */
+ }
+ dk_t2h_output_finish_file();
+ dk4app_set_log_source_file(app, oldsourcefile);
+ dk4app_set_log_source_line(app, oldsourceline);
+}
+
+
+
+/** Process standard input.
+*/
+static
+void
+dk_t2h_process_stdin(void)
+{
+#if DK4_ON_WINDOWS
+ int oldmode;
+
+ oldmode = _setmode(_fileno(stdin), _O_BINARY);
+#endif
+ dk_t2h_process_named_file(stdin, dk_t2h_kwnl[4], dk_t2h_i_std);
+#if DK4_ON_WINDOWS
+ _setmode(_fileno(stdin), oldmode);
+#endif
+}
+
+
+
+/** Process one real file name.
+ @param infname File name to process.
+*/
+static
+void
+dk_t2h_process_one_file_name(const dkChar *infname)
+{
+ FILE *fipo = NULL;
+ int tests = DK4_FOPEN_SC_IS_REGULAR;
+ fipo = dk4fopen_app(infname, dk_t2h_kwnl[3], tests, app);
+ if (NULL != fipo) {
+ dk_t2h_process_named_file(fipo, infname, dk_t2h_i_file);
+ fclose(fipo);
+ } else {
+ exval = EXIT_FAILURE;
+ }
+}
+
+
+
+#if DK4_ON_WINDOWS
+
+/** Expand file name pattern and process the files.
+ @pattern File name pattern to expand.
+ @return 1 if files were found, 0 otherwise.
+*/
+static
+int
+dk_t2h_expand_and_process(const dkChar *pattern)
+{
+ dkChar buf[DK4_MAX_PATH];
+ dk4_dir_t *fne;
+ const dkChar *shf;
+ const dkChar *pth;
+ int cc;
+ int back = 0;
+ fne = dk4app_fne_open(pattern, app);
+ if (NULL != fne) {
+ cc = 1;
+ while (1 == cc) {
+ if (0 != dk_t2h_can_continue()) {
+ shf = dk4dir_next_file(fne);
+ if (NULL != shf) {
+ back = 1;
+ pth = dk4dir_get_path(fne);
+ if (NULL != pth) {
+ if (0 != dk4str_cpy_s(buf, DK4_SIZEOF(buf,dkChar), pth, NULL)) {
+ if(0!=dk4str_cat_s(buf,DK4_SIZEOF(buf,dkChar),dk_t2h_kwnl[5],NULL))
+ {
+ if(0 != dk4str_cat_s(buf, DK4_SIZEOF(buf,dkChar), shf, NULL)) {
+ dk_t2h_process_one_file_name(buf);
+ } else {
+ exval = EXIT_FAILURE;
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ }
+ }
+ else
+ {
+ exval = EXIT_FAILURE;
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ }
+ } else {
+ exval = EXIT_FAILURE;
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ }
+ } else {
+ dk_t2h_process_one_file_name(shf);
+ }
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = -1;
+ }
+ }
+ dk4dir_close(fne);
+ } else {
+ exval = EXIT_FAILURE;
+ }
+ return back;
+}
+
+#endif
+
+
+
+/** Process one file name, check whether expansion is necessary.
+ @param infname Input file name to process, may be NULL.
+*/
+static
+void
+dk_t2h_process_filename(const dkChar *infname)
+{
+ if (NULL != infname) {
+#if DK4_ON_WINDOWS
+ if (0 != dk4path_must_expand(infname)) {
+ if (0 == dk_t2h_expand_and_process(infname)) {
+ exval = EXIT_FAILURE;
+ /* ERROR: No such file */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 107, infname);
+ }
+ } else {
+#endif
+ dk_t2h_process_one_file_name(infname);
+#if DK4_ON_WINDOWS
+ }
+#endif
+ }
+}
+
+
+
+/** Run after installing the signal handlers.
+*/
+static
+void
+dk_t2h_normal_run(void)
+{
+ int argc;
+ int i;
+ if (0 != dk_t2h_process_options()) {
+ exval = EXIT_SUCCESS;
+ dk_t2h_output_start_page();
+ if (0 != dk_t2h_echo) {
+ dk_t2h_process_cmdline();
+ } else {
+ argc = dk4app_get_argc(app);
+ if (0 < argc) {
+ for (i = 0; ((0 != dk_t2h_can_continue()) && (i < argc)); i++) {
+ dk_t2h_process_filename(dk4app_get_argv(app, i));
+ }
+ } else {
+ dk_t2h_process_stdin();
+ }
+ }
+ dk_t2h_output_finish_page();
+ }
+}
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+dk_t2h_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ struct sigaction opipe;
+#endif
+ struct sigaction oint;
+#ifdef SIGPIPE
+ struct sigaction npipe;
+#endif
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+ int success = 0;
+
+#ifdef SIGPIPE
+ /* Set up signal handling for SIGPIPE.
+ */
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+#endif
+
+ /* Set up signal handling for SIGINT.
+ */
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ dk_t2h_normal_run();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+#ifdef SIGPIPE
+ /* Restore signal handling for SIGPIPE.
+ */
+ restore_old_pipe:
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+#endif
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+dk_t2h_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ dk_t2h_normal_run();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+#ifdef SIGPIPE
+ sigset(SIGPIPE, oldpipe);
+#endif
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+dk_t2h_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = signal(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ dk_t2h_normal_run();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+#ifdef SIGPIPE
+ signal(SIGPIPE, oldpipe);
+#endif
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+dk_t2h_run_with_signal_handlers(void)
+{
+ dk_t2h_normal_run();
+}
+#endif
+#endif
+#endif
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ int shp;
+ $!trace-init dk-t2h.deb
+ $? "+ main"
+ dk4fput_initialize_stderr();
+ app = dk4app_open_cmd(
+ argc, argv, dk_t2h_options, dk_t2h_sz_options,
+ dk_t2h_kwnl[0], DKT_VERSION_DK,
+ dk_t2h_kwnl[1], dk_t2h_help_text, dk_t2h_license_text
+ );
+ if (NULL != app) {
+ dk_t2h_i_std = dk4app_get_stdin_encoding(app);
+ dk_t2h_i_file = dk4app_get_file_in_encoding(app);
+ dk_t2h_sz_msg = dk4app_string_table_size(dk_t2h_kw_def);
+ dk_t2h_msg = dk4app_string_table(app, dk_t2h_kwnl[2], dk_t2h_kw_def);
+ if (0 != dk4app_can_run_normally(app)) {
+ dk_t2h_run_with_signal_handlers();
+ } else {
+ dk4fput_initialize_stdout();
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ fflush(stdout);
+ fflush(stderr);
+ dk4fput_cleanup_stdout();
+ }
+ if (0 != sig_read_atomic(&sig_had_int )) {
+ exval = EXIT_FAILURE;
+ /* ERROR: Interrupted by SIGINT */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 10);
+ }
+ if (0 != sig_read_atomic(&sig_had_term)) {
+ exval = EXIT_FAILURE;
+ /* ERROR: Interrupted by SIGTERM */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 11);
+ }
+#ifdef SIGPIPE
+ if (0 != sig_read_atomic(&sig_had_pipe)) {
+ exval = EXIT_FAILURE;
+ shp = 1;
+ /* ERROR: Interrupted by SIGPIPE */
+ if (0 != verbose) {
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 12);
+ }
+ } else {
+ shp = 0;
+ }
+#else
+ shp = 0;
+#endif
+ if ((0 == shp) && (0 != output_error)) {
+ exval = EXIT_FAILURE;
+ /* ERROR: Output to stdout failed */
+ dk4app_log_1(app, dk_t2h_msg, dk_t2h_sz_msg, DK4_LL_ERROR, 13);
+ }
+ dk4app_close(app);
+ }
+ fflush(stdout);
+ if (0 != sig_read_atomic(&sig_had_int )) { exval = EXIT_FAILURE; }
+ if (0 != sig_read_atomic(&sig_had_term)) { exval = EXIT_FAILURE; }
+#ifdef SIGPIPE
+ if (0 != sig_read_atomic(&sig_had_pipe)) { exval = EXIT_FAILURE; }
+#endif
+ if (0 != output_error) { exval = EXIT_FAILURE; }
+ fflush(stderr);
+ dk4fput_cleanup_stderr();
+ $? "- main %d", exval
+ $!trace-end
+ exit(exval); return exval;
+}
+
+
diff --git a/support/dktools/dk-t2h.rc b/support/dktools/dk-t2h.rc
new file mode 100644
index 0000000000..e95fbd358a
--- /dev/null
+++ b/support/dktools/dk-t2h.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Text to HTML converter\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "Text to HTML converter\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "dk-t2h\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/dk-t2l.c b/support/dktools/dk-t2l.c
new file mode 100644
index 0000000000..52ae36a00e
--- /dev/null
+++ b/support/dktools/dk-t2l.c
@@ -0,0 +1,2026 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk-t2l.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#line 9 "dk-t2l.ctr"
+
+/** @file dk-th2.c The dk-t2l program.
+ See dk_t2l_help_text for details.
+*/
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4mem.h"
+#include "dk4enc.h"
+#include "dk4app.h"
+#include "dk4aopt.h"
+#include "dk4fopda.h"
+#include "dk4fput.h"
+#include "dk4vers.h"
+#include "dk4tsp32.h"
+#include "dk4uc2l.h"
+#include "dk4maidhdu.h"
+#include "dk4maidddu.h"
+#include "dk4maodh.h"
+#include "dk4maodd.h"
+#include "dk4mpl.h"
+#include "dk4strd.h"
+#include "dk4pathd.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == 2
+#include "dk4utf16.h"
+#endif
+#else
+#include "dk4ansi.h"
+#include "dk4utf8.h"
+#endif
+
+
+
+
+
+#line 105 "dk-t2l.ctr"
+
+
+
+/** Default help text, shown if no help text file is found.
+*/
+static const dkChar * const dk_t2l_help_text[] = {
+dkT(""),
+dkT("dk-t2l - Text to LaTeX converter"),
+dkT(""),
+dkT("dk-t2l [<options>] [<file(s)>]"),
+dkT(""),
+dkT("Options:"),
+dkT("-i <encoding>\t--input-encoding=<encoding>\tExpected input encoding."),
+dkT("-e\t\t--echo\t\t\t\tProcess command line arguments."),
+dkT("-n\t\t--numeric\t\t\tNumeric values on command line."),
+dkT("-h\t\t--hex\t\t\t\tHexadecimal values on cmd line."),
+dkT("-r\t\t--recommendations\t\tWrite recommendations for"),
+dkT("\t\t\t\t\t\tpackages and font encodings"),
+dkT("\t\t\t\t\t\tto use."),
+dkT("-l\t\t--line-feed\t\t\tWrite \\\\ sequence for newline."),
+dkT("-t\t\t--tabulator\t\t\tWrite LaTeX sequence for"),
+dkT("\t\t\t\t\t\ttabulators"),
+dkT("\t\t--verbose\t\t\tShow error message on SIGPIPE."),
+dkT(""),
+dkT("--help\t\t\t\t\t\tShow this short help text."),
+dkT("--manual\t\t\t\t\t*** SHOW FULL MANUAL. ***"),
+dkT("--version\t\t\t\t\tShow version information."),
+dkT("--license\t\t\t\t\tShow license information."),
+dkT(""),
+dkT("http://dktools.sourceforge.net"),
+dkT(""),
+NULL
+
+
+#line 138 "dk-t2l.ctr"
+};
+
+
+
+/** License text.
+*/
+static const dkChar * const dk_t2l_license_text[] = {
+dkT(""),
+dkT("This software uses code from the following projects, either directly or as"),
+dkT("a library:"),
+dkT(""),
+dkT("dktools\t\tDirk Krause's tools and libraries."),
+dkT("\t\tSee http://dktools.sourceforge.net/ for more information."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT("zlib\t\tData compression library."),
+dkT("\t\tSee http://www.zlib.net/ for more information."),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT("bzip2\t\tData compression program and library."),
+dkT("\t\tSee http://www.bzip.org/ for more information."),
+#endif
+dkT(""),
+dkT("All the licenses below apply to the program."),
+dkT("Licenses for used libraries are shown as found on my Scientific Linux 6.x"),
+dkT("computer in the /usr/share/doc directory on 2015-04-01. Check the project"),
+dkT("homepages of the used libraries for additional information and/or updated"),
+dkT("license terms."),
+dkT(""),
+dkT(""),
+dkT("DK tools and libraries license"),
+dkT("=============================="),
+dkT("Copyright (c) 2015-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above copyright notice,"),
+dkT(" this list of conditions and the following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("* Neither the name of the Dirk Krause nor the names of contributors may be"),
+dkT(" used to endorse or promote products derived from this software without"),
+dkT(" specific prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\""),
+dkT("AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED."),
+dkT(""),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,"),
+dkT("INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,"),
+dkT("BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,"),
+dkT("DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY"),
+dkT("OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,"),
+dkT("EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT(""),
+dkT("Zlib license"),
+dkT("============"),
+dkT("(C) 1995-2004 Jean-loup Gailly and Mark Adler"),
+dkT(""),
+dkT("This software is provided 'as-is', without any express or implied"),
+dkT("warranty. In no event will the authors be held liable for any damages"),
+dkT("arising from the use of this software."),
+dkT(""),
+dkT("Permission is granted to anyone to use this software for any purpose,"),
+dkT("including commercial applications, and to alter it and redistribute it"),
+dkT("freely, subject to the following restrictions:"),
+dkT(""),
+dkT("1. The origin of this software must not be misrepresented; you must not"),
+dkT(" claim that you wrote the original software. If you use this software"),
+dkT(" in a product, an acknowledgment in the product documentation would be"),
+dkT(" appreciated but is not required."),
+dkT("2. Altered source versions must be plainly marked as such, and must not be"),
+dkT(" misrepresented as being the original software."),
+dkT("3. This notice may not be removed or altered from any source distribution."),
+dkT(""),
+dkT("Jean-loup Gailly Mark Adler"),
+dkT("jloup@gzip.org madler@alumni.caltech.edu"),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT(""),
+dkT("Bzip2 and libbzip2 library license"),
+dkT("=================================="),
+dkT("This program, \"bzip2\", the associated library \"libbzip2\", and all"),
+dkT("documentation, are copyright (C) 1996-2007 Julian R Seward. All"),
+dkT("rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions"),
+dkT("are met:"),
+dkT(""),
+dkT("1. Redistributions of source code must retain the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer."),
+dkT(""),
+dkT("2. The origin of this software must not be misrepresented; you must "),
+dkT(" not claim that you wrote the original software. If you use this "),
+dkT(" software in a product, an acknowledgment in the product "),
+dkT(" documentation would be appreciated but is not required."),
+dkT(""),
+dkT("3. Altered source versions must be plainly marked as such, and must"),
+dkT(" not be misrepresented as being the original software."),
+dkT(""),
+dkT("4. The name of the author may not be used to endorse or promote "),
+dkT(" products derived from this software without specific prior written "),
+dkT(" permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS"),
+dkT("OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED"),
+dkT("WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE"),
+dkT("GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS"),
+dkT("INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,"),
+dkT("WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS"),
+dkT("SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+dkT(""),
+dkT("Julian Seward, jseward@bzip.org"),
+dkT("bzip2/libbzip2 version 1.0.5 of 10 December 2007"),
+#endif
+dkT(""),
+NULL
+
+
+#line 270 "dk-t2l.ctr"
+};
+
+
+
+/** Constant 8 bit character texts, not localized.
+*/
+static const char * const dk_t2l_kw8[] = {
+/* 0 */
+"\\(",
+
+/* 1 */
+"\\)",
+
+/* 2 */
+"\\\\",
+
+NULL
+
+
+#line 288 "dk-t2l.ctr"
+};
+
+
+
+/** Constant text keywords used by the program, not localized.
+*/
+static const dkChar * const dk_t2l_kwnl[] = {
+/* 0 */
+dkT("dktools"),
+
+/* 1 */
+dkT("dk-t2l.txt"),
+
+/* 2 */
+dkT("dk-t2l.str"),
+
+/* 3 */
+dkT("rb"),
+
+/* 4 */
+dkT("stdin"),
+
+/* 5 */
+dkT("\\"),
+
+/* 6 */
+dkT("verbose"),
+
+NULL
+
+
+#line 325 "dk-t2l.ctr"
+};
+
+
+
+/** Constant keywords used by the program, replaced by localized texts.
+*/
+static const dkChar * const dk_t2l_kw_def[] = {
+/* 0 */
+dkT("Failed to set up signal handlers!"),
+
+/* 1 */
+dkT("Failed to restore signal handlers!"),
+
+/* 2 */
+dkT("Illegal input encoding name: \""),
+
+/* 3 */
+dkT("\"!"),
+
+/* 4 */
+dkT("Not a hexadecimal number: \""),
+
+/* 5 */
+dkT("\"!"),
+
+/* 6 */
+dkT("No data found for character 0x"),
+
+/* 7 */
+dkT("!"),
+
+/* 8 */
+dkT("No data found for character!"),
+
+/* 9 */
+dkT("Overflow in line number count!"),
+
+/* 10 */
+dkT("Failed to setup character by character processing!"),
+
+/* 11 */
+dkT("Probably incorrect output due to problems with the data files!"),
+
+/* 12 */
+dkT("Aborted by SIGINT signal!"),
+
+/* 13 */
+dkT("Aborted by SIGTERM signal!"),
+
+/* 14 */
+dkT("Received SIGPIPE signal!"),
+
+/* 15 */
+dkT("Write attempt to standard output failed."),
+
+/* 16 */
+dkT("Decoding failed!\n\tByte:"),
+
+/* 17 */
+dkT("Encoding failed!\n\tByte:"),
+
+/* 18 */
+dkT("Processing failed!\n\tByte:"),
+
+/* 19 */
+dkT(",\n\tCharacter:"),
+
+/* 20 */
+dkT(",\n\tPosition in line:"),
+
+/* 21 */
+dkT("."),
+
+/* 22 */
+dkT("Decoding failed!"),
+
+/* 23 */
+dkT("Encoding failed!"),
+
+/* 24 */
+dkT("Processing failed!"),
+
+/* 25 */
+dkT("Further decoding failures!"),
+
+/* 26 */
+dkT("Further encoding failures!"),
+
+/* 27 */
+dkT("Further processing failures!"),
+
+/* 28 */
+dkT("Out of range: \""),
+
+/* 29 */
+dkT("\"!"),
+
+/* 30 */
+dkT("Not a decimal number: \""),
+
+/* 31 */
+dkT("\"!"),
+
+NULL
+
+
+#line 405 "dk-t2l.ctr"
+};
+
+
+
+/** Options for the program.
+*/
+static const dk4_option_specification_t dk_t2l_options[] = {
+
+ /* Expected input encoding.
+ */
+ { dkT('i'), dkT("input-encoding"), DK4_OPT_ARG_STRING },
+
+ /* Process command line arguments.
+ */
+ { dkT('e'), dkT("echo"), DK4_OPT_ARG_NONE },
+
+ /* Command line arguments are decimal character numbers.
+ */
+ { dkT('n'), dkT("numeric"), DK4_OPT_ARG_NONE },
+
+ /* Command line arguments are hexadecimal character numbers.
+ */
+ { dkT('x'), dkT("hex"), DK4_OPT_ARG_NONE },
+
+ /* Write recommendations about font encodings and packages.
+ */
+ { dkT('r'), dkT("recommendations"), DK4_OPT_ARG_NONE },
+
+ /* Convert tabulators.
+ */
+ { dkT('t'), dkT("tabulator"), DK4_OPT_ARG_NONE },
+
+ /* Convert line feeds.
+ */
+ { dkT('l'), dkT("line-feed"), DK4_OPT_ARG_NONE },
+
+ /* Verbose output.
+ */
+ { dkT('\0'), dkT("verbose"), DK4_OPT_ARG_NONE }
+};
+
+
+
+/** Pointer to localized or not localized texts.
+*/
+static const dkChar * const *dk_t2l_msg = dk_t2l_kw_def;
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Conversion data structure.
+*/
+static dk4_uc2l_t *uc2l = NULL;
+
+
+
+/** Current line number.
+*/
+static dk4_um_t dk_t2l_lineno = (dk4_um_t)1UL;
+
+
+
+/** Number of elements in the dk_t2l_options array.
+*/
+static const size_t dk_t2l_sz_options =
+sizeof(dk_t2l_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Number of elements in dk_t2l_msg array.
+*/
+static size_t dk_t2l_sz_msg =
+sizeof(dk_t2l_kw_def)/sizeof(DK4_PCDKCHAR) - 1;
+
+
+/** Program exit status.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+/** Flag: Error occured while writing to stdout.
+*/
+static int output_error = 0;
+
+
+
+/** Flag: Verbose output (report SIGPIPE).
+*/
+static int verbose = 0;
+
+
+
+/** Flag: Echo command line arguments instead of processing files.
+*/
+static int dk_t2l_echo = 0;
+
+
+
+/** Command line arguments are numeric:
+ 0 = text,
+ 1 = decimal,
+ 2 = hexadecimal.
+*/
+static int dk_t2l_numeric = 0;
+
+
+
+/** Input encoding expected when processing stdin.
+*/
+static int dk_t2l_i_std = DK4_FILE_ENCODING_ASCII;
+
+
+
+/** Input encoding expected when processing files.
+*/
+static int dk_t2l_i_file = DK4_FILE_ENCODING_ASCII;
+
+
+
+/** Number of decoding errors in current file.
+*/
+static int dk_t2l_dec_err = 0;
+
+
+
+/** Number of encoding errors in current file.
+*/
+static int dk_t2l_enc_err = 0;
+
+
+
+/** Number of processing errors in current file.
+*/
+static int dk_t2l_pro_err = 0;
+
+
+
+/** Flag: Previous character was carriage return.
+*/
+static int dk_t2l_last_cr = 0;
+
+
+
+/** Flag: Previous character was newline.
+*/
+static int dk_t2l_last_nl = 0;
+
+
+
+/** Flag: Have text in line, newline needed.
+*/
+static int dk_t2l_lhtx = 0;
+
+
+
+/** Flag: In math mode.
+*/
+static int dk_t2l_in_mm = 0;
+
+
+
+/** Flag: Find LaTeX sequence also for tabulators.
+*/
+static int dk_t2l_tabs = 0;
+
+
+
+/** Flag: Write sequence for line feeds.
+*/
+static int dk_t2l_linef = 0;
+
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+/** Pass a volatile pointer to an atomic integer.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ptr Address of atomic integer variable.
+ @return The unmodified pointer.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+/** Check whether we can continue or if a signal was received.
+ @param check_pipe Flag: Check for occured SIGPIPE signal too.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(int check_pipe)
+{
+ int back = 1;
+#ifdef SIGPIPE
+ if (0 != check_pipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_int )) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+/** Check whether we can continue.
+ @return 1 for yes, 0 for no.
+*/
+static
+int
+dk_t2l_can_continue(void)
+{
+ int back = 1;
+ if (0 == sig_can_continue(1)) {
+ back = 0;
+ }
+ return back;
+}
+
+
+
+/** Process command line options.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk_t2l_process_options(void)
+{
+ const dkChar *oaptr;
+ int encval = 0;
+ int bomval = 0;
+ int back = 1;
+
+ if (0 != dk4app_opt_is_set_long(app, dk_t2l_kwnl[6], NULL)) {
+ verbose = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('t'), NULL)) {
+ dk_t2l_tabs = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('l'), NULL)) {
+ dk_t2l_linef = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('i'), NULL)) {
+ oaptr = dk4app_opt_get_string_ptr_short(app, dkT('i'), NULL);
+ if (NULL != oaptr) {
+ if (0 != dk4enc_find(&encval, &bomval, oaptr, NULL)) {
+ dk_t2l_i_std = dk_t2l_i_file = encval;
+ } else {
+ /* ERROR: Illegal encoding */
+ dk4app_log_3(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 2, 3, oaptr);
+ back = 0;
+ }
+ } else {
+
+#line 738 "dk-t2l.ctr"
+ /* ERROR: Failed to obtain option argument, bug! */
+ }
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('e'), NULL)) {
+ dk_t2l_echo = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('n'), NULL)) {
+ dk_t2l_echo = 1;
+ dk_t2l_numeric = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('x'), NULL)) {
+ dk_t2l_echo = 1;
+ dk_t2l_numeric = 2;
+ }
+ uc2l = dk4uc2l_open_from_app(app);
+ if (NULL == uc2l) {
+ back = 0;
+ }
+ return back;
+}
+
+
+
+/** Start output page.
+*/
+static
+void
+dk_t2l_output_start_page(void)
+{
+ /* Hook */
+}
+
+
+
+/** Finish output page.
+*/
+static
+void
+dk_t2l_output_finish_page(void)
+{
+ /* Hook */
+}
+
+
+
+/** Start processing of one file.
+*/
+static
+void
+dk_t2l_output_start_file(void)
+{
+ /* No errors in this file yet.
+ */
+ dk_t2l_dec_err = 0;
+ dk_t2l_enc_err = 0;
+ dk_t2l_pro_err = 0;
+ dk_t2l_last_cr = 0;
+ dk_t2l_last_nl = 0;
+ dk_t2l_lhtx = 0;
+ dk_t2l_lineno = (dk4_um_t)1UL;
+ dk4app_set_log_source_line(app, dk_t2l_lineno);
+}
+
+
+
+/** Finish processing of one file.
+*/
+static
+void
+dk_t2l_output_finish_file(void)
+{
+
+}
+
+
+
+static
+void
+dk_t2l_begin_math_mode(void)
+{
+ if (0 == dk_t2l_in_mm) {
+ dk_t2l_in_mm = 1;
+ if (EOF == fputs(dk_t2l_kw8[0], stdout)) {
+ output_error = 1;
+ }
+ }
+}
+
+
+
+static
+void
+dk_t2l_end_math_mode(void)
+{
+ if (0 != dk_t2l_in_mm) {
+ dk_t2l_in_mm = 0;
+ if (EOF == fputs(dk_t2l_kw8[1], stdout)) {
+ output_error = 1;
+ }
+ }
+}
+
+
+
+/** Handler function after processing CR/NL sequences.
+ Here we do the real output.
+ @param c Character to process.
+ @param pos Current position in file or data stream, may be NULL.
+ @param erp Error report, may be NULL.
+ @return Result code:
+ - DK4_TSP_RES_OK if the character was processed successfully,
+ - DK4_TSP_RES_ERROR if there was an error but we can continue,
+ - DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+dk_t2l_c32_after_cr_nl_check(
+ dk4_c32_t c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+)
+{
+ dkChar buf[16*sizeof(dk4_um_t)];
+ const char *lseq;
+ size_t szbuf;
+ int back = DK4_TSP_RES_OK;
+
+ if (dkC32(0x0A) == c) {
+ /*
+ Newline, finish line and write newline to output.
+ */
+ dk_t2l_end_math_mode();
+ if (0 != dk_t2l_linef) {
+ if (EOF == fputs(dk_t2l_kw8[2], stdout)) { output_error = 1; }
+ }
+ if (EOF == fputc('\n', stdout)) { output_error = 1; }
+ } else {
+ if (0 == dk_t2l_lhtx) {
+ /*
+ Start new line.
+ */
+ }
+ /*
+ Write character to output.
+ */
+ if ((dkC32(0x09) == c) && (0 == dk_t2l_tabs)) {
+ dk_t2l_end_math_mode();
+ if (EOF == fputc(' ', stdout)) { output_error = 1; }
+ } else {
+ lseq = dk4uc2l_find(uc2l, c, 0, app);
+ if (NULL != lseq) {
+ dk_t2l_end_math_mode();
+ if (EOF == fputs(lseq, stdout)) { output_error = 1; }
+ } else {
+ lseq = dk4uc2l_find(uc2l, c, 1, app);
+ if (NULL != lseq) {
+ dk_t2l_begin_math_mode();
+ if (EOF == fputs(lseq, stdout)) { output_error = 1; }
+ } else {
+ /* ERROR, no encoding found */
+ szbuf = DK4_SIZEOF(buf,dkChar);
+ if (0 != dk4ma_write_hex_unsigned(buf, szbuf, (dk4_um_t)c, 8, NULL)) {
+ dk4app_log_3(app,dk_t2l_msg,dk_t2l_sz_msg,DK4_LL_ERROR,6,7,buf);
+ } else {
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 8);
+ }
+ exval = EXIT_FAILURE;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Handler function for single characters.
+ @param obj Object to modify while processing the character.
+ @param c Character to process.
+ @param pos Current position in file or data stream.
+ @param erp Error report, may be NULL.
+ @return Result code:
+ - DK4_TSP_RES_OK if the character was processed successfully,
+ - DK4_TSP_RES_ERROR if there was an error but we can continue,
+ - DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+dk_t2l_c32_handler(
+ void *obj,
+ dk4_c32_t c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_TSP_RES_OK;
+ if (dkC32(0x0A) == c) {
+ /*
+ For a newline clear CR and TXT flag, set NL flag.
+ */
+ back = dk_t2l_c32_after_cr_nl_check(c, pos, erp);
+ dk_t2l_lineno++;
+ if ((dk4_um_t)0UL == dk_t2l_lineno) {
+ /* ERROR: Overflow in line number counting */
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 9);
+ exval = EXIT_FAILURE;
+ }
+ dk4app_set_log_source_line(app, dk_t2l_lineno);
+ dk_t2l_last_cr = 0;
+ dk_t2l_last_nl = 1;
+ dk_t2l_lhtx = 0;
+ } else {
+ if (dkC32(0x0D) == c) {
+ /*
+ For a cr if CR flag is set, pass the cr and set TXT flag, clear nl flag.
+ Otherwise simply set CR flag.
+ */
+ if (0 != dk_t2l_last_cr) {
+ back = dk_t2l_c32_after_cr_nl_check(dkC32(0x0D), pos, erp);
+ dk_t2l_lhtx = 1;
+ dk_t2l_last_nl = 0;
+ } else {
+ dk_t2l_last_cr = 1;
+ }
+ } else {
+ /*
+ For any other character:
+ If the CR flag is set, pass cr and current character.
+ Otherwise pass the current character.
+ Reset NL and CR flag, set TXT flag.
+ */
+ if (0 != dk_t2l_last_cr) {
+ back = dk_t2l_c32_after_cr_nl_check(dkC32(0x0D), pos, erp);
+ switch (dk_t2l_c32_after_cr_nl_check(c, pos, erp)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ } else {
+ back = dk_t2l_c32_after_cr_nl_check(c, pos, erp);
+ }
+ dk_t2l_lhtx = 1;
+ dk_t2l_last_nl = 0;
+ dk_t2l_last_cr = 0;
+ }
+ }
+ return back;
+}
+
+
+
+/** Report an error with position in source line.
+ @param i1 Index of first message part in array.
+ @param i2 Index of alternative first message part.
+ @param bno Byte processed.
+ @param lno Current line number.
+ @param cno Current character number.
+ @param cil Current character number in line.
+*/
+static
+void
+dk_t2l_report_with_position(
+ size_t i1,
+ size_t i2,
+ dk4_um_t bno,
+ dk4_um_t lno,
+ dk4_um_t cno,
+ dk4_um_t cil
+)
+{
+ dkChar b1[8*(1+sizeof(dk4_um_t))];
+ dkChar b2[8*(1+sizeof(dk4_um_t))];
+ dkChar b3[8*(1+sizeof(dk4_um_t))];
+ dk4_um_t oldlogline = (dk4_um_t)0UL;
+ int allbuffersok = 0;
+
+ oldlogline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_line(app, lno);
+ if (0 != dk4ma_write_decimal_unsigned(b3,DK4_SIZEOF(b3,dkChar),cil,0,NULL)) {
+ if (0 != dk4ma_write_decimal_unsigned(b2,DK4_SIZEOF(b2,dkChar),cno,0,NULL)) {
+ if (0 != dk4ma_write_decimal_unsigned(b1,DK4_SIZEOF(b1,dkChar),bno,0,NULL)) {
+ allbuffersok = 1;
+ }
+ }
+ }
+ if (0 != allbuffersok) {
+ dk4app_log_7(
+ app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, i1, 19, 20, 21, b1, b2, b3
+ );
+ } else {
+ dk4app_log_1(
+ app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, i2
+ );
+ }
+ dk4app_set_log_source_line(app, oldlogline);
+}
+
+
+
+static
+void
+dk_t2l_report_errors(dk4_er_t *er_en, dk4_er_t *er_pr)
+{
+ if (NULL != er_en) {
+ switch (er_en->ec) {
+ case DK4_E_DECODING_FAILED: {
+ switch (dk_t2l_dec_err) {
+ case 0: case 1: {
+ dk_t2l_report_with_position(
+ 16, 22,
+ er_en->dt.fpos.byteno,
+ er_en->dt.fpos.lineno,
+ er_en->dt.fpos.charno,
+ er_en->dt.fpos.charinline
+ );
+ } break;
+ case 2: {
+ dk4app_log_1(
+ app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 25
+ );
+ } break;
+ }
+ if (3 > dk_t2l_dec_err) { dk_t2l_dec_err++; }
+ } break;
+ case DK4_E_ENCODING_FAILED: {
+ switch (dk_t2l_enc_err) {
+ case 0: case 1: {
+ dk_t2l_report_with_position(
+ 17, 23,
+ er_en->dt.fpos.byteno,
+ er_en->dt.fpos.lineno,
+ er_en->dt.fpos.charno,
+ er_en->dt.fpos.charinline
+ );
+ } break;
+ case 2: {
+ dk4app_log_1(
+ app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 26
+ );
+ } break;
+ }
+ if (3 > dk_t2l_enc_err) { dk_t2l_enc_err++; }
+ } break;
+ }
+ }
+ if (NULL != er_pr) {
+ if (DK4_E_NONE != er_pr->ec) {
+ switch (dk_t2l_pro_err) {
+ case 0: case 1: {
+ dk_t2l_report_with_position(
+ 18, 24,
+ er_pr->dt.fpos.byteno,
+ er_pr->dt.fpos.lineno,
+ er_pr->dt.fpos.charno,
+ er_pr->dt.fpos.charinline
+ );
+ } break;
+ case 2: {
+ dk4app_log_1(
+ app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 27
+ );
+ } break;
+ }
+ if (3 > dk_t2l_pro_err) { dk_t2l_pro_err++; }
+ }
+ }
+}
+
+
+
+static
+void
+dk_t2l_echo_hex(const dkChar *txt, int argno)
+{
+ const dkChar *endptr = NULL;
+ dk4_um_t um = (dk4_um_t)0UL;
+ int res = 0;
+ if (dkT('0') == txt[0]) {
+ if ((dkT('x') == txt[1]) || (dkT('X') == txt[1])) {
+ txt++; txt++;
+ }
+ }
+ res = dk4ma_input_dk_hex_dk4_um_t(
+ &um, txt, &endptr, 1, NULL
+ );
+ if (0 != res) {
+ if ((dk4_um_t)0xFFFFFFFFUL >= um) {
+ (void)dk_t2l_c32_after_cr_nl_check((dk4_c32_t)um, NULL, NULL);
+ } else {
+ dk4app_log_3(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 28, 29, txt);
+ }
+ } else {
+ /* ERROR: Not a hexadecimal number */
+ dk4app_log_3(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 4, 5, txt);
+ }
+}
+
+
+
+static
+void
+dk_t2l_echo_numeric(const dkChar *txt, int argno)
+{
+ const dkChar *endptr = NULL;
+ dk4_um_t um = (dk4_um_t)0UL;
+ int res = 0;
+ int ishex = 0;
+
+ if (dkT('0') == txt[0]) {
+ if ((dkT('x') == txt[1]) || (dkT('X') == txt[1])) {
+ ishex = 1;
+ }
+ }
+ if (0 == ishex) {
+ res = dk4ma_input_dk_dec_dk4_um_t(
+ &um, txt, &endptr, 1, NULL
+ );
+ if (0 != res) {
+ if ((dk4_um_t)0xFFFFFFFFUL >= um) {
+ (void)dk_t2l_c32_after_cr_nl_check((dk4_c32_t)um, NULL, NULL);
+ } else {
+ dk4app_log_3(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 28, 29, txt);
+ }
+ } else {
+ /* ERROR: Not a decimal number */
+ dk4app_log_3(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 30, 31, txt);
+ }
+ } else {
+ dk_t2l_echo_hex(&(txt[2]), argno);
+ }
+}
+
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+
+/** Process one text word from command line, UNICODE character.
+ @param txt Text word.
+ @param argno Number of current word.
+*/
+static
+void
+dk_t2l_echo_c32(const dkChar *txt, int argno)
+{
+ int isfirst = 1;
+ while (dkC32(0) != *txt) {
+ if ((1 == isfirst) && (0 != argno)) {
+ if (EOF == fputc(' ', stdout)) { output_error = 1; }
+ }
+ isfirst = 0;
+ (void)dk_t2l_c32_after_cr_nl_check(*(txt++), NULL, NULL);
+ }
+}
+
+#else
+
+/** Process one text word from command line, UTF-16 encoded.
+ @param txt Text word.
+ @param argno Number of current word.
+*/
+static
+void
+dk_t2l_echo_utf16(const dkChar *txt, int argno)
+{
+ dk4_utf16_decoder_t dec;
+ int cc = 1;
+ int isfirst = 1;
+ dk4utf16_init(&dec);
+ while (1 == cc) {
+ if (dkC16(0) != *txt) {
+ switch (dk4utf16_add(&dec, *(txt++))) {
+ case DK4_EDSTM_ERROR : {
+ cc = -1;
+ /* !!!!! ERROR: Decoding */
+ exval = EXIT_FAILURE;
+ } break;
+ case DK4_EDSTM_FINISHED : {
+ if ((1 == isfirst) && (0 != argno)) {
+ if (EOF == fputc(' ', stdout)) { output_error = 1; }
+ }
+ isfirst = 0;
+ (void)dk_t2l_c32_after_cr_nl_check(dk4utf16_get(&dec), NULL, NULL);
+ } break;
+ }
+ } else {
+ cc = 0;
+ }
+ }
+ if (0 == cc) {
+ if (0 == dk4utf16_is_empty(&dec)) {
+ /* !!!!! ERROR: Decoding */
+ exval = EXIT_FAILURE;
+ }
+ }
+ /* !!!!! TODO: Implementation */
+}
+
+#endif
+#else
+
+/** Process one text word from command line, ASCII encoded.
+ @param txt Text word.
+ @param argno Number of current word.
+*/
+static
+void
+dk_t2l_echo_ascii(const dkChar *txt, int argno)
+{
+ dk4_c32_t c32;
+ int isfirst = 1;
+ while ('\0' != *txt) {
+ if ((1 == isfirst) && (0 != argno)) {
+ if (EOF == fputc(' ', stdout)) { output_error = 1; }
+ }
+ isfirst = 0;
+ c32 = dkC32(0xFF) & ((dk4_c32_t)((unsigned char)(*(txt++))));
+ (void)dk_t2l_c32_after_cr_nl_check(c32, NULL, NULL);
+ }
+}
+
+/** Process one text word from command line, UTF-8 encoded.
+ @param txt Text word.
+ @param argno Number of current word.
+*/
+static
+void
+dk_t2l_echo_utf8(const dkChar *txt, int argno)
+{
+ dk4_utf8_decoder_t dec;
+ int cc = 1;
+ int isfirst = 1;
+
+ dk4utf8_init(&dec);
+ while (1 == cc) {
+ if ('\0' != *txt) {
+ switch (dk4utf8_add(&dec, *(txt++))) {
+ case DK4_EDSTM_ERROR : {
+ cc = -1;
+ exval = EXIT_FAILURE;
+ /* !!!!! ERROR: Decoding */
+ } break;
+ case DK4_EDSTM_FINISHED : {
+ if ((1 == isfirst) && (0 != argno)) {
+ if (EOF == fputc(' ', stdout)) { output_error = 1; }
+ }
+ isfirst = 0;
+ (void)dk_t2l_c32_after_cr_nl_check(dk4utf8_get(&dec), NULL, NULL);
+ } break;
+ }
+ } else {
+ cc = 0;
+ }
+ }
+ if (0 == cc) {
+ if (0 == dk4utf8_is_empty(&dec)) {
+ exval = EXIT_FAILURE;
+ /* !!!!! ERROR: Decoding */
+ }
+ }
+}
+
+/** Process one text word from command line, ANSI encoded.
+ @param txt Text word.
+ @param argno Number of current word.
+*/
+static
+void
+dk_t2l_echo_ansi(const dkChar *txt, int argno)
+{
+ dk4_c32_t c32;
+ int isfirst = 1;
+ char c;
+ while ('\0' != *txt) {
+ c = *(txt++);
+ if (0 != dk4ansi_decode(&c32, (unsigned char)c)) {
+ if ((1 == isfirst) && (0 != argno)) {
+ if (EOF == fputc(' ', stdout)) { output_error = 1; }
+ }
+ isfirst = 0;
+ (void)dk_t2l_c32_after_cr_nl_check(c32, NULL, NULL);
+ } else {
+ /* !!!!! ERROR: Decoding */
+ exval = EXIT_FAILURE;
+ }
+ }
+}
+
+#endif
+
+
+
+/** Process one text word from command line.
+ @param txt Text word.
+ @param argno Number of current word.
+*/
+static
+void
+dk_t2l_echo_text(const dkChar *txt, int argno)
+{
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ dk_t2l_echo_c32(txt, argno);
+#else
+ dk_t2l_echo_utf16(txt, argno);
+#endif
+#else
+ switch (dk4app_get_encoding(app)) {
+ case DK4_ENCODING_UTF8 : {
+ dk_t2l_echo_utf8(txt, argno);
+ } break;
+ case DK4_ENCODING_ANSI : {
+ dk_t2l_echo_ansi(txt, argno);
+ } break;
+ default : {
+ dk_t2l_echo_ascii(txt, argno);
+ } break;
+ }
+#endif
+ dk_t2l_end_math_mode();
+}
+
+
+
+/** Process command line arguments.
+*/
+static
+void
+dk_t2l_process_cmdline(void)
+{
+ const dkChar *xargv;
+ int argc;
+ int i;
+ /* !!!!! TODO: Implementation */
+ dk_t2l_output_start_file();
+ argc = dk4app_get_argc(app);
+ if (0 < argc) {
+ switch (dk_t2l_numeric) {
+ case 2: {
+ for (i = 0; i < argc; i++) {
+ xargv = dk4app_get_argv(app, i);
+ if (NULL != xargv) {
+ dk_t2l_echo_hex(xargv, i);
+ }
+ }
+ dk_t2l_end_math_mode();
+ } break;
+ case 1: {
+ for (i = 0; i < argc; i++) {
+ xargv = dk4app_get_argv(app, i);
+ if (NULL != xargv) {
+ dk_t2l_echo_numeric(xargv, i);
+ }
+ }
+ dk_t2l_end_math_mode();
+ } break;
+ default: {
+ for (i = 0; i < argc; i++) {
+ xargv = dk4app_get_argv(app, i);
+ if (NULL != xargv) {
+ dk_t2l_echo_text(xargv, i);
+ }
+ }
+ } break;
+ }
+ if (EOF == fputc('\n', stdout)) { output_error = 1; }
+ } else {
+ /* !!!!! ERROR: No command line arguments specified */
+ }
+ dk_t2l_output_finish_file();
+}
+
+
+
+/** Process an opened file with file name.
+ @param fipo Opened file.
+ @param fn File name.
+ @param ienc_def Expected input encoding.
+*/
+static
+void
+dk_t2l_process_named_file(FILE *fipo, const dkChar *fn, int ienc_def)
+{
+ dk4_tsp32_t tsp32;
+ dk4_er_t er;
+ dk4_er_t er_en;
+ dk4_er_t er_pr;
+ const dkChar *oldsourcefile;
+ dk4_um_t oldsourceline;
+ int c;
+ int cc;
+ int res;
+ unsigned char ub;
+
+ dk_t2l_in_mm = 0;
+ oldsourcefile = dk4app_get_log_source_file(app);
+ oldsourceline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_file(app, fn);
+ dk4app_set_log_source_line(app, (dk4_um_t)0UL);
+ dk_t2l_output_start_file();
+ dk4error_init(&er);
+ res = dk4tsp32_setup_char(
+ &tsp32, NULL, dk_t2l_c32_handler, ienc_def, &er
+ );
+ if (0 != res) {
+ cc = 1;
+ while (1 == cc) {
+ if (0 != dk_t2l_can_continue()) {
+ c = fgetc(fipo);
+ if (EOF != c) {
+ ub = (unsigned char)c;
+ res = dk4tsp32_add_one_byte(&tsp32, ub);
+ switch (res) {
+ case DK4_TSP_RES_ERROR: {
+ exval = EXIT_FAILURE;
+ dk4tsp32_get_errors(&er_en, &er_pr, &tsp32);
+ dk_t2l_report_errors(&er_en, &er_pr);
+ } break;
+ case DK4_TSP_RES_FATAL: {
+ cc = -1;
+ exval = EXIT_FAILURE;
+ dk4tsp32_get_errors(&er_en, &er_pr, &tsp32);
+ dk_t2l_report_errors(&er_en, &er_pr);
+ } break;
+ default: {
+ } break;
+ }
+ } else {
+ cc = 0;
+ }
+ if (0 != feof(fipo)) { if (1 == cc) { cc = 0; } }
+ } else {
+ cc = -1;
+ }
+ }
+ if (0 == cc) {
+ res = dk4tsp32_finish(&tsp32);
+ switch (res) {
+ case DK4_TSP_RES_ERROR: case DK4_TSP_RES_FATAL: {
+ exval = EXIT_FAILURE;
+ dk4tsp32_get_errors(&er_en, &er_pr, &tsp32);
+ dk_t2l_report_errors(&er_en, &er_pr);
+ } break;
+ }
+ }
+ if (0 != dk_t2l_can_continue()) {
+ /* TODO: Finish current line */
+ if (0 != dk_t2l_in_mm) {
+ dk_t2l_end_math_mode();
+ if (EOF == fputc('\n', stdout)) { output_error = 1; }
+ } else {
+ if (0 == dk_t2l_last_nl) {
+ if (EOF == fputc('\n', stdout)) { output_error = 1; }
+ }
+ }
+ }
+ } else {
+ /* ERROR: Setup failed, should not happen, bug */
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 10);
+ exval = EXIT_FAILURE;
+ }
+ dk_t2l_output_finish_file();
+ dk4app_set_log_source_file(app, oldsourcefile);
+ dk4app_set_log_source_line(app, oldsourceline);
+}
+
+
+
+/** Process standard input.
+*/
+static
+void
+dk_t2l_process_stdin(void)
+{
+#if DK4_ON_WINDOWS
+ int oldmode;
+
+ oldmode = _setmode(_fileno(stdin), _O_BINARY);
+#endif
+ dk_t2l_process_named_file(stdin, dk_t2l_kwnl[4], dk_t2l_i_std);
+#if DK4_ON_WINDOWS
+ _setmode(_fileno(stdin), oldmode);
+#endif
+}
+
+
+
+/** Process one real file name.
+ @param infname File name to process.
+*/
+static
+void
+dk_t2l_process_one_file_name(const dkChar *infname)
+{
+ FILE *fipo = NULL;
+ int tests = DK4_FOPEN_SC_IS_REGULAR;
+ fipo = dk4fopen_app(infname, dk_t2l_kwnl[3], tests, app);
+ if (NULL != fipo) {
+ dk_t2l_process_named_file(fipo, infname, dk_t2l_i_file);
+ fclose(fipo);
+ } else {
+ exval = EXIT_FAILURE;
+ }
+}
+
+
+
+#if DK4_ON_WINDOWS
+
+/** Expand file name pattern and process the files.
+ @pattern File name pattern to expand.
+ @return 1 if files were found, 0 otherwise.
+*/
+static
+int
+dk_t2l_expand_and_process(const dkChar *pattern)
+{
+ dkChar buf[DK4_MAX_PATH];
+ dk4_dir_t *fne;
+ const dkChar *shf;
+ const dkChar *pth;
+ int cc;
+ int back = 0;
+ fne = dk4app_fne_open(pattern, app);
+ if (NULL != fne) {
+ cc = 1;
+ while (1 == cc) {
+ if (0 != dk_t2l_can_continue()) {
+ shf = dk4dir_next_file(fne);
+ if (NULL != shf) {
+ back = 1;
+ pth = dk4dir_get_path(fne);
+ if (NULL != pth) {
+ if (0 != dk4str_cpy_s(buf, DK4_SIZEOF(buf,dkChar), pth, NULL)) {
+ if(0!=dk4str_cat_s(buf,DK4_SIZEOF(buf,dkChar),dk_t2l_kwnl[5],NULL))
+ {
+ if(0 != dk4str_cat_s(buf, DK4_SIZEOF(buf,dkChar), shf, NULL)) {
+ dk_t2l_process_one_file_name(buf);
+ } else {
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ exval = EXIT_FAILURE;
+ }
+ }
+ else
+ {
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ dk_t2l_process_one_file_name(shf);
+ }
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = -1;
+ }
+ }
+ dk4dir_close(fne);
+ } else {
+ exval = EXIT_FAILURE;
+ }
+ return back;
+}
+
+#endif
+
+
+
+/** Process one file name, check whether expansion is necessary.
+ @param infname Input file name to process, may be NULL.
+*/
+static
+void
+dk_t2l_process_filename(const dkChar *infname)
+{
+ if (NULL != infname) {
+#if DK4_ON_WINDOWS
+ if (0 != dk4path_must_expand(infname)) {
+ if (0 == dk_t2l_expand_and_process(infname)) {
+ exval = EXIT_FAILURE;
+ /* ERROR: No such file */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 107, infname);
+ }
+ } else {
+#endif
+ dk_t2l_process_one_file_name(infname);
+#if DK4_ON_WINDOWS
+ }
+#endif
+ }
+}
+
+
+
+/** Run after installing the signal handlers.
+*/
+static
+void
+dk_t2l_normal_run(void)
+{
+ int argc;
+ int i;
+ if (0 != dk_t2l_process_options()) {
+ exval = EXIT_SUCCESS;
+ dk_t2l_output_start_page();
+ if (0 != dk_t2l_echo) {
+ dk_t2l_process_cmdline();
+ } else {
+ argc = dk4app_get_argc(app);
+ if (0 < argc) {
+ for (i = 0; ((0 != dk_t2l_can_continue()) && (i < argc)); i++) {
+ dk_t2l_process_filename(dk4app_get_argv(app, i));
+ }
+ } else {
+ dk_t2l_process_stdin();
+ }
+ }
+ dk_t2l_output_finish_page();
+ if (0 != dk4app_opt_is_set_short(app, dkT('r'), NULL)) {
+ dk4uc2l_recommendations(uc2l, stdout);
+ }
+ if (0 != dk4uc2l_retrieve_errors(uc2l)) {
+
+#line 1674 "dk-t2l.ctr"
+ /* ERROR: Probably incorrect output due to problems */
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 11);
+ exval = EXIT_FAILURE;
+ }
+ }
+ if (NULL != uc2l) {
+ dk4uc2l_close(uc2l);
+ uc2l = NULL;
+ }
+}
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+dk_t2l_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ struct sigaction opipe;
+#endif
+ struct sigaction oint;
+#ifdef SIGPIPE
+ struct sigaction npipe;
+#endif
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+ int success = 0;
+
+#ifdef SIGPIPE
+ /* Set up signal handling for SIGPIPE.
+ */
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+#endif
+
+ /* Set up signal handling for SIGINT.
+ */
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ dk_t2l_normal_run();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+#ifdef SIGPIPE
+ /* Restore signal handling for SIGPIPE.
+ */
+ restore_old_pipe:
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+#endif
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+dk_t2l_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ dk_t2l_normal_run();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+#ifdef SIGPIPE
+ sigset(SIGPIPE, oldpipe);
+#endif
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+dk_t2l_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = signal(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ dk_t2l_normal_run();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+#ifdef SIGPIPE
+ signal(SIGPIPE, oldpipe);
+#endif
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+dk_t2l_run_with_signal_handlers(void)
+{
+ dk_t2l_normal_run();
+}
+#endif
+#endif
+#endif
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ int shp;
+
+
+#line 1887 "dk-t2l.ctr"
+
+
+#line 1888 "dk-t2l.ctr"
+ dk4fput_initialize_stderr();
+ app = dk4app_open_cmd(
+ argc, argv, dk_t2l_options, dk_t2l_sz_options,
+ dk_t2l_kwnl[0], DKT_VERSION_DK,
+ dk_t2l_kwnl[1], dk_t2l_help_text, dk_t2l_license_text
+ );
+ if (NULL != app) {
+ dk_t2l_i_std = dk4app_get_stdin_encoding(app);
+ dk_t2l_i_file = dk4app_get_file_in_encoding(app);
+ dk_t2l_sz_msg = dk4app_string_table_size(dk_t2l_kw_def);
+ dk_t2l_msg = dk4app_string_table(app, dk_t2l_kwnl[2], dk_t2l_kw_def);
+ if (0 != dk4app_can_run_normally(app)) {
+ dk_t2l_run_with_signal_handlers();
+ } else {
+ dk4fput_initialize_stdout();
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ fflush(stdout);
+ fflush(stderr);
+ dk4fput_cleanup_stdout();
+ }
+ if (0 != sig_read_atomic(&sig_had_int )) {
+ exval = EXIT_FAILURE;
+ /* ERROR: Interrupted by SIGINT */
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 12);
+ }
+ if (0 != sig_read_atomic(&sig_had_term)) {
+ exval = EXIT_FAILURE;
+ /* ERROR: Interrupted by SIGTERM */
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 13);
+ }
+#ifdef SIGPIPE
+ if (0 != sig_read_atomic(&sig_had_pipe)) {
+ exval = EXIT_FAILURE;
+ shp = 1;
+ /* ERROR: Interrupted by SIGPIPE */
+ if (0 != verbose) {
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 14);
+ }
+ } else {
+ shp = 0;
+ }
+#else
+ shp = 0;
+#endif
+ if ((0 == shp) && (0 != output_error)) {
+ exval = EXIT_FAILURE;
+ /* ERROR: Output to stdout failed */
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 15);
+ }
+ dk4app_close(app);
+ }
+ fflush(stdout);
+ if (0 != sig_read_atomic(&sig_had_int )) { exval = EXIT_FAILURE; }
+ if (0 != sig_read_atomic(&sig_had_term)) { exval = EXIT_FAILURE; }
+#ifdef SIGPIPE
+ if (0 != sig_read_atomic(&sig_had_pipe)) { exval = EXIT_FAILURE; }
+#endif
+ if (0 != output_error) { exval = EXIT_FAILURE; }
+ fflush(stderr);
+ dk4fput_cleanup_stderr();
+
+
+#line 1951 "dk-t2l.ctr"
+
+
+#line 1952 "dk-t2l.ctr"
+ exit(exval); return exval;
+}
+
+
diff --git a/support/dktools/dk-t2l.ctr b/support/dktools/dk-t2l.ctr
new file mode 100644
index 0000000000..8a1bcbeb9b
--- /dev/null
+++ b/support/dktools/dk-t2l.ctr
@@ -0,0 +1,1955 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% module
+
+/** @file dk-th2.c The dk-t2l program.
+ See dk_t2l_help_text for details.
+*/
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4mem.h"
+#include "dk4enc.h"
+#include "dk4app.h"
+#include "dk4aopt.h"
+#include "dk4fopda.h"
+#include "dk4fput.h"
+#include "dk4vers.h"
+#include "dk4tsp32.h"
+#include "dk4uc2l.h"
+#include "dk4maidhdu.h"
+#include "dk4maidddu.h"
+#include "dk4maodh.h"
+#include "dk4maodd.h"
+#include "dk4mpl.h"
+#include "dk4strd.h"
+#include "dk4pathd.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == 2
+#include "dk4utf16.h"
+#endif
+#else
+#include "dk4ansi.h"
+#include "dk4utf8.h"
+#endif
+
+
+
+$!trace-include
+
+
+
+/** Default help text, shown if no help text file is found.
+*/
+static const dkChar * const dk_t2l_help_text[] = {
+$!text macro=dkT,preprocessor
+
+dk-t2l - Text to LaTeX converter
+
+dk-t2l [<options>] [<file(s)>]
+
+Options:
+-i <encoding> --input-encoding=<encoding> Expected input encoding.
+-e --echo Process command line arguments.
+-n --numeric Numeric values on command line.
+-h --hex Hexadecimal values on cmd line.
+-r --recommendations Write recommendations for
+ packages and font encodings
+ to use.
+-l --line-feed Write \\ sequence for newline.
+-t --tabulator Write LaTeX sequence for
+ tabulators
+ --verbose Show error message on SIGPIPE.
+
+--help Show this short help text.
+--manual *** SHOW FULL MANUAL. ***
+--version Show version information.
+--license Show license information.
+
+http://dktools.sourceforge.net
+
+$!end
+};
+
+
+
+/** License text.
+*/
+static const dkChar * const dk_t2l_license_text[] = {
+$!text macro=dkT,preprocessor
+
+This software uses code from the following projects, either directly or as
+a library:
+
+dktools Dirk Krause's tools and libraries.
+ See http://dktools.sourceforge.net/ for more information.
+#if DK4_HAVE_ZLIB_H
+
+zlib Data compression library.
+ See http://www.zlib.net/ for more information.
+#endif
+#if DK4_HAVE_BZLIB_H
+
+bzip2 Data compression program and library.
+ See http://www.bzip.org/ for more information.
+#endif
+
+All the licenses below apply to the program.
+Licenses for used libraries are shown as found on my Scientific Linux 6.x
+computer in the /usr/share/doc directory on 2015-04-01. Check the project
+homepages of the used libraries for additional information and/or updated
+license terms.
+
+
+DK tools and libraries license
+==============================
+Copyright (c) 2015-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#if DK4_HAVE_ZLIB_H
+
+
+Zlib license
+============
+(C) 1995-2004 Jean-loup Gailly and Mark Adler
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+
+Jean-loup Gailly Mark Adler
+jloup@gzip.org madler@alumni.caltech.edu
+#endif
+#if DK4_HAVE_BZLIB_H
+
+
+Bzip2 and libbzip2 library license
+==================================
+This program, "bzip2", the associated library "libbzip2", and all
+documentation, are copyright (C) 1996-2007 Julian R Seward. All
+rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+3. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Julian Seward, jseward@bzip.org
+bzip2/libbzip2 version 1.0.5 of 10 December 2007
+#endif
+
+$!end
+};
+
+
+
+/** Constant 8 bit character texts, not localized.
+*/
+static const char * const dk_t2l_kw8[] = {
+$!string-table
+#
+# 0 1 Open and close math mode.
+#
+\\(
+\\)
+#
+# 2
+#
+\\\\
+$!end
+};
+
+
+
+/** Constant text keywords used by the program, not localized.
+*/
+static const dkChar * const dk_t2l_kwnl[] = {
+$!string-table macro=dkT
+#
+# 0 Program group name
+#
+dktools
+#
+# 1 Help text file name
+#
+dk-t2l.txt
+#
+# 2 String table file name
+#
+dk-t2l.str
+#
+# 3 File opening mode, read binary
+#
+rb
+#
+# 4 Pseudo file name for standard input
+#
+stdin
+#
+# 5 Path separator for Windows
+#
+\\
+#
+# 6 Long option for verbose mode
+#
+verbose
+$!end
+};
+
+
+
+/** Constant keywords used by the program, replaced by localized texts.
+*/
+static const dkChar * const dk_t2l_kw_def[] = {
+$!string-table macro=dkT
+#
+# 0 Error: Failed to set up signal handlers!
+#
+Failed to set up signal handlers!
+#
+# 1 Error: Failed to restore signal handlers!
+#
+Failed to restore signal handlers!
+#
+# 2 3 Error: Illegal input encoding name: "..."!
+#
+Illegal input encoding name: "
+"!
+#
+# 4 5 Temporarily unused.
+#
+Not a hexadecimal number: "
+"!
+#
+# 6 7 8 Error: No data found for character 0x...!
+#
+No data found for character 0x
+!
+No data found for character!
+#
+# 9 Error: Overflow in line number count!
+#
+Overflow in line number count!
+#
+# 10 Error: Failed to setup character by character processing!
+#
+Failed to setup character by character processing!
+#
+# 11 Error: Probably incorrect output due to problems ...
+#
+Probably incorrect output due to problems with the data files!
+#
+# 12 .. 15 Error: Aborted by SIGINT signal!
+#
+Aborted by SIGINT signal!
+Aborted by SIGTERM signal!
+Received SIGPIPE signal!
+Write attempt to standard output failed.
+#
+# 16 ... 21 Error messages.
+#
+Decoding failed!\n\tByte:
+Encoding failed!\n\tByte:
+Processing failed!\n\tByte:
+,\n\tCharacter:
+,\n\tPosition in line:
+.
+#
+# 22 ... 27 Error messages.
+#
+Decoding failed!
+Encoding failed!
+Processing failed!
+Further decoding failures!
+Further encoding failures!
+Further processing failures!
+#
+# 28 29 Error: Out of range!
+#
+Out of range: "
+"!
+#
+# 30 31 Error: Not a decimal number!
+#
+Not a decimal number: "
+"!
+$!end
+};
+
+
+
+/** Options for the program.
+*/
+static const dk4_option_specification_t dk_t2l_options[] = {
+
+ /* Expected input encoding.
+ */
+ { dkT('i'), dkT("input-encoding"), DK4_OPT_ARG_STRING },
+
+ /* Process command line arguments.
+ */
+ { dkT('e'), dkT("echo"), DK4_OPT_ARG_NONE },
+
+ /* Command line arguments are decimal character numbers.
+ */
+ { dkT('n'), dkT("numeric"), DK4_OPT_ARG_NONE },
+
+ /* Command line arguments are hexadecimal character numbers.
+ */
+ { dkT('x'), dkT("hex"), DK4_OPT_ARG_NONE },
+
+ /* Write recommendations about font encodings and packages.
+ */
+ { dkT('r'), dkT("recommendations"), DK4_OPT_ARG_NONE },
+
+ /* Convert tabulators.
+ */
+ { dkT('t'), dkT("tabulator"), DK4_OPT_ARG_NONE },
+
+ /* Convert line feeds.
+ */
+ { dkT('l'), dkT("line-feed"), DK4_OPT_ARG_NONE },
+
+ /* Verbose output.
+ */
+ { dkT('\0'), dkT("verbose"), DK4_OPT_ARG_NONE }
+};
+
+
+
+/** Pointer to localized or not localized texts.
+*/
+static const dkChar * const *dk_t2l_msg = dk_t2l_kw_def;
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Conversion data structure.
+*/
+static dk4_uc2l_t *uc2l = NULL;
+
+
+
+/** Current line number.
+*/
+static dk4_um_t dk_t2l_lineno = (dk4_um_t)1UL;
+
+
+
+/** Number of elements in the dk_t2l_options array.
+*/
+static const size_t dk_t2l_sz_options =
+sizeof(dk_t2l_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Number of elements in dk_t2l_msg array.
+*/
+static size_t dk_t2l_sz_msg =
+sizeof(dk_t2l_kw_def)/sizeof(DK4_PCDKCHAR) - 1;
+
+
+/** Program exit status.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+/** Flag: Error occured while writing to stdout.
+*/
+static int output_error = 0;
+
+
+
+/** Flag: Verbose output (report SIGPIPE).
+*/
+static int verbose = 0;
+
+
+
+/** Flag: Echo command line arguments instead of processing files.
+*/
+static int dk_t2l_echo = 0;
+
+
+
+/** Command line arguments are numeric:
+ 0 = text,
+ 1 = decimal,
+ 2 = hexadecimal.
+*/
+static int dk_t2l_numeric = 0;
+
+
+
+/** Input encoding expected when processing stdin.
+*/
+static int dk_t2l_i_std = DK4_FILE_ENCODING_ASCII;
+
+
+
+/** Input encoding expected when processing files.
+*/
+static int dk_t2l_i_file = DK4_FILE_ENCODING_ASCII;
+
+
+
+/** Number of decoding errors in current file.
+*/
+static int dk_t2l_dec_err = 0;
+
+
+
+/** Number of encoding errors in current file.
+*/
+static int dk_t2l_enc_err = 0;
+
+
+
+/** Number of processing errors in current file.
+*/
+static int dk_t2l_pro_err = 0;
+
+
+
+/** Flag: Previous character was carriage return.
+*/
+static int dk_t2l_last_cr = 0;
+
+
+
+/** Flag: Previous character was newline.
+*/
+static int dk_t2l_last_nl = 0;
+
+
+
+/** Flag: Have text in line, newline needed.
+*/
+static int dk_t2l_lhtx = 0;
+
+
+
+/** Flag: In math mode.
+*/
+static int dk_t2l_in_mm = 0;
+
+
+
+/** Flag: Find LaTeX sequence also for tabulators.
+*/
+static int dk_t2l_tabs = 0;
+
+
+
+/** Flag: Write sequence for line feeds.
+*/
+static int dk_t2l_linef = 0;
+
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+/** Pass a volatile pointer to an atomic integer.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ptr Address of atomic integer variable.
+ @return The unmodified pointer.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+/** Check whether we can continue or if a signal was received.
+ @param check_pipe Flag: Check for occured SIGPIPE signal too.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(int check_pipe)
+{
+ int back = 1;
+#ifdef SIGPIPE
+ if (0 != check_pipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_int )) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+/** Check whether we can continue.
+ @return 1 for yes, 0 for no.
+*/
+static
+int
+dk_t2l_can_continue(void)
+{
+ int back = 1;
+ if (0 == sig_can_continue(1)) {
+ back = 0;
+ }
+ return back;
+}
+
+
+
+/** Process command line options.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk_t2l_process_options(void)
+{
+ const dkChar *oaptr;
+ int encval = 0;
+ int bomval = 0;
+ int back = 1;
+
+ if (0 != dk4app_opt_is_set_long(app, dk_t2l_kwnl[6], NULL)) {
+ verbose = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('t'), NULL)) {
+ dk_t2l_tabs = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('l'), NULL)) {
+ dk_t2l_linef = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('i'), NULL)) {
+ oaptr = dk4app_opt_get_string_ptr_short(app, dkT('i'), NULL);
+ if (NULL != oaptr) {
+ if (0 != dk4enc_find(&encval, &bomval, oaptr, NULL)) {
+ dk_t2l_i_std = dk_t2l_i_file = encval;
+ } else {
+ /* ERROR: Illegal encoding */
+ dk4app_log_3(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 2, 3, oaptr);
+ back = 0;
+ }
+ } else { $? "! bug"
+ /* ERROR: Failed to obtain option argument, bug! */
+ }
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('e'), NULL)) {
+ dk_t2l_echo = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('n'), NULL)) {
+ dk_t2l_echo = 1;
+ dk_t2l_numeric = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('x'), NULL)) {
+ dk_t2l_echo = 1;
+ dk_t2l_numeric = 2;
+ }
+ uc2l = dk4uc2l_open_from_app(app);
+ if (NULL == uc2l) {
+ back = 0;
+ }
+ return back;
+}
+
+
+
+/** Start output page.
+*/
+static
+void
+dk_t2l_output_start_page(void)
+{
+ /* Hook */
+}
+
+
+
+/** Finish output page.
+*/
+static
+void
+dk_t2l_output_finish_page(void)
+{
+ /* Hook */
+}
+
+
+
+/** Start processing of one file.
+*/
+static
+void
+dk_t2l_output_start_file(void)
+{
+ /* No errors in this file yet.
+ */
+ dk_t2l_dec_err = 0;
+ dk_t2l_enc_err = 0;
+ dk_t2l_pro_err = 0;
+ dk_t2l_last_cr = 0;
+ dk_t2l_last_nl = 0;
+ dk_t2l_lhtx = 0;
+ dk_t2l_lineno = (dk4_um_t)1UL;
+ dk4app_set_log_source_line(app, dk_t2l_lineno);
+}
+
+
+
+/** Finish processing of one file.
+*/
+static
+void
+dk_t2l_output_finish_file(void)
+{
+
+}
+
+
+
+static
+void
+dk_t2l_begin_math_mode(void)
+{
+ if (0 == dk_t2l_in_mm) {
+ dk_t2l_in_mm = 1;
+ if (EOF == fputs(dk_t2l_kw8[0], stdout)) {
+ output_error = 1;
+ }
+ }
+}
+
+
+
+static
+void
+dk_t2l_end_math_mode(void)
+{
+ if (0 != dk_t2l_in_mm) {
+ dk_t2l_in_mm = 0;
+ if (EOF == fputs(dk_t2l_kw8[1], stdout)) {
+ output_error = 1;
+ }
+ }
+}
+
+
+
+/** Handler function after processing CR/NL sequences.
+ Here we do the real output.
+ @param c Character to process.
+ @param pos Current position in file or data stream, may be NULL.
+ @param erp Error report, may be NULL.
+ @return Result code:
+ - DK4_TSP_RES_OK if the character was processed successfully,
+ - DK4_TSP_RES_ERROR if there was an error but we can continue,
+ - DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+dk_t2l_c32_after_cr_nl_check(
+ dk4_c32_t c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+)
+{
+ dkChar buf[16*sizeof(dk4_um_t)];
+ const char *lseq;
+ size_t szbuf;
+ int back = DK4_TSP_RES_OK;
+
+ if (dkC32(0x0A) == c) {
+ /*
+ Newline, finish line and write newline to output.
+ */
+ dk_t2l_end_math_mode();
+ if (0 != dk_t2l_linef) {
+ if (EOF == fputs(dk_t2l_kw8[2], stdout)) { output_error = 1; }
+ }
+ if (EOF == fputc('\n', stdout)) { output_error = 1; }
+ } else {
+ if (0 == dk_t2l_lhtx) {
+ /*
+ Start new line.
+ */
+ }
+ /*
+ Write character to output.
+ */
+ if ((dkC32(0x09) == c) && (0 == dk_t2l_tabs)) {
+ dk_t2l_end_math_mode();
+ if (EOF == fputc(' ', stdout)) { output_error = 1; }
+ } else {
+ lseq = dk4uc2l_find(uc2l, c, 0, app);
+ if (NULL != lseq) {
+ dk_t2l_end_math_mode();
+ if (EOF == fputs(lseq, stdout)) { output_error = 1; }
+ } else {
+ lseq = dk4uc2l_find(uc2l, c, 1, app);
+ if (NULL != lseq) {
+ dk_t2l_begin_math_mode();
+ if (EOF == fputs(lseq, stdout)) { output_error = 1; }
+ } else {
+ /* ERROR, no encoding found */
+ szbuf = DK4_SIZEOF(buf,dkChar);
+ if (0 != dk4ma_write_hex_unsigned(buf, szbuf, (dk4_um_t)c, 8, NULL)) {
+ dk4app_log_3(app,dk_t2l_msg,dk_t2l_sz_msg,DK4_LL_ERROR,6,7,buf);
+ } else {
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 8);
+ }
+ exval = EXIT_FAILURE;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Handler function for single characters.
+ @param obj Object to modify while processing the character.
+ @param c Character to process.
+ @param pos Current position in file or data stream.
+ @param erp Error report, may be NULL.
+ @return Result code:
+ - DK4_TSP_RES_OK if the character was processed successfully,
+ - DK4_TSP_RES_ERROR if there was an error but we can continue,
+ - DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+dk_t2l_c32_handler(
+ void *obj,
+ dk4_c32_t c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_TSP_RES_OK;
+ if (dkC32(0x0A) == c) {
+ /*
+ For a newline clear CR and TXT flag, set NL flag.
+ */
+ back = dk_t2l_c32_after_cr_nl_check(c, pos, erp);
+ dk_t2l_lineno++;
+ if ((dk4_um_t)0UL == dk_t2l_lineno) {
+ /* ERROR: Overflow in line number counting */
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 9);
+ exval = EXIT_FAILURE;
+ }
+ dk4app_set_log_source_line(app, dk_t2l_lineno);
+ dk_t2l_last_cr = 0;
+ dk_t2l_last_nl = 1;
+ dk_t2l_lhtx = 0;
+ } else {
+ if (dkC32(0x0D) == c) {
+ /*
+ For a cr if CR flag is set, pass the cr and set TXT flag, clear nl flag.
+ Otherwise simply set CR flag.
+ */
+ if (0 != dk_t2l_last_cr) {
+ back = dk_t2l_c32_after_cr_nl_check(dkC32(0x0D), pos, erp);
+ dk_t2l_lhtx = 1;
+ dk_t2l_last_nl = 0;
+ } else {
+ dk_t2l_last_cr = 1;
+ }
+ } else {
+ /*
+ For any other character:
+ If the CR flag is set, pass cr and current character.
+ Otherwise pass the current character.
+ Reset NL and CR flag, set TXT flag.
+ */
+ if (0 != dk_t2l_last_cr) {
+ back = dk_t2l_c32_after_cr_nl_check(dkC32(0x0D), pos, erp);
+ switch (dk_t2l_c32_after_cr_nl_check(c, pos, erp)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ } else {
+ back = dk_t2l_c32_after_cr_nl_check(c, pos, erp);
+ }
+ dk_t2l_lhtx = 1;
+ dk_t2l_last_nl = 0;
+ dk_t2l_last_cr = 0;
+ }
+ }
+ return back;
+}
+
+
+
+/** Report an error with position in source line.
+ @param i1 Index of first message part in array.
+ @param i2 Index of alternative first message part.
+ @param bno Byte processed.
+ @param lno Current line number.
+ @param cno Current character number.
+ @param cil Current character number in line.
+*/
+static
+void
+dk_t2l_report_with_position(
+ size_t i1,
+ size_t i2,
+ dk4_um_t bno,
+ dk4_um_t lno,
+ dk4_um_t cno,
+ dk4_um_t cil
+)
+{
+ dkChar b1[8*(1+sizeof(dk4_um_t))];
+ dkChar b2[8*(1+sizeof(dk4_um_t))];
+ dkChar b3[8*(1+sizeof(dk4_um_t))];
+ dk4_um_t oldlogline = (dk4_um_t)0UL;
+ int allbuffersok = 0;
+
+ oldlogline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_line(app, lno);
+ if (0 != dk4ma_write_decimal_unsigned(b3,DK4_SIZEOF(b3,dkChar),cil,0,NULL)) {
+ if (0 != dk4ma_write_decimal_unsigned(b2,DK4_SIZEOF(b2,dkChar),cno,0,NULL)) {
+ if (0 != dk4ma_write_decimal_unsigned(b1,DK4_SIZEOF(b1,dkChar),bno,0,NULL)) {
+ allbuffersok = 1;
+ }
+ }
+ }
+ if (0 != allbuffersok) {
+ dk4app_log_7(
+ app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, i1, 19, 20, 21, b1, b2, b3
+ );
+ } else {
+ dk4app_log_1(
+ app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, i2
+ );
+ }
+ dk4app_set_log_source_line(app, oldlogline);
+}
+
+
+
+static
+void
+dk_t2l_report_errors(dk4_er_t *er_en, dk4_er_t *er_pr)
+{
+ if (NULL != er_en) {
+ switch (er_en->ec) {
+ case DK4_E_DECODING_FAILED: {
+ switch (dk_t2l_dec_err) {
+ case 0: case 1: {
+ dk_t2l_report_with_position(
+ 16, 22,
+ er_en->dt.fpos.byteno,
+ er_en->dt.fpos.lineno,
+ er_en->dt.fpos.charno,
+ er_en->dt.fpos.charinline
+ );
+ } break;
+ case 2: {
+ dk4app_log_1(
+ app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 25
+ );
+ } break;
+ }
+ if (3 > dk_t2l_dec_err) { dk_t2l_dec_err++; }
+ } break;
+ case DK4_E_ENCODING_FAILED: {
+ switch (dk_t2l_enc_err) {
+ case 0: case 1: {
+ dk_t2l_report_with_position(
+ 17, 23,
+ er_en->dt.fpos.byteno,
+ er_en->dt.fpos.lineno,
+ er_en->dt.fpos.charno,
+ er_en->dt.fpos.charinline
+ );
+ } break;
+ case 2: {
+ dk4app_log_1(
+ app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 26
+ );
+ } break;
+ }
+ if (3 > dk_t2l_enc_err) { dk_t2l_enc_err++; }
+ } break;
+ }
+ }
+ if (NULL != er_pr) {
+ if (DK4_E_NONE != er_pr->ec) {
+ switch (dk_t2l_pro_err) {
+ case 0: case 1: {
+ dk_t2l_report_with_position(
+ 18, 24,
+ er_pr->dt.fpos.byteno,
+ er_pr->dt.fpos.lineno,
+ er_pr->dt.fpos.charno,
+ er_pr->dt.fpos.charinline
+ );
+ } break;
+ case 2: {
+ dk4app_log_1(
+ app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 27
+ );
+ } break;
+ }
+ if (3 > dk_t2l_pro_err) { dk_t2l_pro_err++; }
+ }
+ }
+}
+
+
+
+static
+void
+dk_t2l_echo_hex(const dkChar *txt, int argno)
+{
+ const dkChar *endptr = NULL;
+ dk4_um_t um = (dk4_um_t)0UL;
+ int res = 0;
+ if (dkT('0') == txt[0]) {
+ if ((dkT('x') == txt[1]) || (dkT('X') == txt[1])) {
+ txt++; txt++;
+ }
+ }
+ res = dk4ma_input_dk_hex_dk4_um_t(
+ &um, txt, &endptr, 1, NULL
+ );
+ if (0 != res) {
+ if ((dk4_um_t)0xFFFFFFFFUL >= um) {
+ (void)dk_t2l_c32_after_cr_nl_check((dk4_c32_t)um, NULL, NULL);
+ } else {
+ dk4app_log_3(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 28, 29, txt);
+ }
+ } else {
+ /* ERROR: Not a hexadecimal number */
+ dk4app_log_3(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 4, 5, txt);
+ }
+}
+
+
+
+static
+void
+dk_t2l_echo_numeric(const dkChar *txt, int argno)
+{
+ const dkChar *endptr = NULL;
+ dk4_um_t um = (dk4_um_t)0UL;
+ int res = 0;
+ int ishex = 0;
+
+ if (dkT('0') == txt[0]) {
+ if ((dkT('x') == txt[1]) || (dkT('X') == txt[1])) {
+ ishex = 1;
+ }
+ }
+ if (0 == ishex) {
+ res = dk4ma_input_dk_dec_dk4_um_t(
+ &um, txt, &endptr, 1, NULL
+ );
+ if (0 != res) {
+ if ((dk4_um_t)0xFFFFFFFFUL >= um) {
+ (void)dk_t2l_c32_after_cr_nl_check((dk4_c32_t)um, NULL, NULL);
+ } else {
+ dk4app_log_3(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 28, 29, txt);
+ }
+ } else {
+ /* ERROR: Not a decimal number */
+ dk4app_log_3(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 30, 31, txt);
+ }
+ } else {
+ dk_t2l_echo_hex(&(txt[2]), argno);
+ }
+}
+
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+
+/** Process one text word from command line, UNICODE character.
+ @param txt Text word.
+ @param argno Number of current word.
+*/
+static
+void
+dk_t2l_echo_c32(const dkChar *txt, int argno)
+{
+ int isfirst = 1;
+ while (dkC32(0) != *txt) {
+ if ((1 == isfirst) && (0 != argno)) {
+ if (EOF == fputc(' ', stdout)) { output_error = 1; }
+ }
+ isfirst = 0;
+ (void)dk_t2l_c32_after_cr_nl_check(*(txt++), NULL, NULL);
+ }
+}
+
+#else
+
+/** Process one text word from command line, UTF-16 encoded.
+ @param txt Text word.
+ @param argno Number of current word.
+*/
+static
+void
+dk_t2l_echo_utf16(const dkChar *txt, int argno)
+{
+ dk4_utf16_decoder_t dec;
+ int cc = 1;
+ int isfirst = 1;
+ dk4utf16_init(&dec);
+ while (1 == cc) {
+ if (dkC16(0) != *txt) {
+ switch (dk4utf16_add(&dec, *(txt++))) {
+ case DK4_EDSTM_ERROR : {
+ cc = -1;
+ /* !!!!! ERROR: Decoding */
+ exval = EXIT_FAILURE;
+ } break;
+ case DK4_EDSTM_FINISHED : {
+ if ((1 == isfirst) && (0 != argno)) {
+ if (EOF == fputc(' ', stdout)) { output_error = 1; }
+ }
+ isfirst = 0;
+ (void)dk_t2l_c32_after_cr_nl_check(dk4utf16_get(&dec), NULL, NULL);
+ } break;
+ }
+ } else {
+ cc = 0;
+ }
+ }
+ if (0 == cc) {
+ if (0 == dk4utf16_is_empty(&dec)) {
+ /* !!!!! ERROR: Decoding */
+ exval = EXIT_FAILURE;
+ }
+ }
+ /* !!!!! TODO: Implementation */
+}
+
+#endif
+#else
+
+/** Process one text word from command line, ASCII encoded.
+ @param txt Text word.
+ @param argno Number of current word.
+*/
+static
+void
+dk_t2l_echo_ascii(const dkChar *txt, int argno)
+{
+ dk4_c32_t c32;
+ int isfirst = 1;
+ while ('\0' != *txt) {
+ if ((1 == isfirst) && (0 != argno)) {
+ if (EOF == fputc(' ', stdout)) { output_error = 1; }
+ }
+ isfirst = 0;
+ c32 = dkC32(0xFF) & ((dk4_c32_t)((unsigned char)(*(txt++))));
+ (void)dk_t2l_c32_after_cr_nl_check(c32, NULL, NULL);
+ }
+}
+
+/** Process one text word from command line, UTF-8 encoded.
+ @param txt Text word.
+ @param argno Number of current word.
+*/
+static
+void
+dk_t2l_echo_utf8(const dkChar *txt, int argno)
+{
+ dk4_utf8_decoder_t dec;
+ int cc = 1;
+ int isfirst = 1;
+
+ dk4utf8_init(&dec);
+ while (1 == cc) {
+ if ('\0' != *txt) {
+ switch (dk4utf8_add(&dec, *(txt++))) {
+ case DK4_EDSTM_ERROR : {
+ cc = -1;
+ exval = EXIT_FAILURE;
+ /* !!!!! ERROR: Decoding */
+ } break;
+ case DK4_EDSTM_FINISHED : {
+ if ((1 == isfirst) && (0 != argno)) {
+ if (EOF == fputc(' ', stdout)) { output_error = 1; }
+ }
+ isfirst = 0;
+ (void)dk_t2l_c32_after_cr_nl_check(dk4utf8_get(&dec), NULL, NULL);
+ } break;
+ }
+ } else {
+ cc = 0;
+ }
+ }
+ if (0 == cc) {
+ if (0 == dk4utf8_is_empty(&dec)) {
+ exval = EXIT_FAILURE;
+ /* !!!!! ERROR: Decoding */
+ }
+ }
+}
+
+/** Process one text word from command line, ANSI encoded.
+ @param txt Text word.
+ @param argno Number of current word.
+*/
+static
+void
+dk_t2l_echo_ansi(const dkChar *txt, int argno)
+{
+ dk4_c32_t c32;
+ int isfirst = 1;
+ char c;
+ while ('\0' != *txt) {
+ c = *(txt++);
+ if (0 != dk4ansi_decode(&c32, (unsigned char)c)) {
+ if ((1 == isfirst) && (0 != argno)) {
+ if (EOF == fputc(' ', stdout)) { output_error = 1; }
+ }
+ isfirst = 0;
+ (void)dk_t2l_c32_after_cr_nl_check(c32, NULL, NULL);
+ } else {
+ /* !!!!! ERROR: Decoding */
+ exval = EXIT_FAILURE;
+ }
+ }
+}
+
+#endif
+
+
+
+/** Process one text word from command line.
+ @param txt Text word.
+ @param argno Number of current word.
+*/
+static
+void
+dk_t2l_echo_text(const dkChar *txt, int argno)
+{
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ dk_t2l_echo_c32(txt, argno);
+#else
+ dk_t2l_echo_utf16(txt, argno);
+#endif
+#else
+ switch (dk4app_get_encoding(app)) {
+ case DK4_ENCODING_UTF8 : {
+ dk_t2l_echo_utf8(txt, argno);
+ } break;
+ case DK4_ENCODING_ANSI : {
+ dk_t2l_echo_ansi(txt, argno);
+ } break;
+ default : {
+ dk_t2l_echo_ascii(txt, argno);
+ } break;
+ }
+#endif
+ dk_t2l_end_math_mode();
+}
+
+
+
+/** Process command line arguments.
+*/
+static
+void
+dk_t2l_process_cmdline(void)
+{
+ const dkChar *xargv;
+ int argc;
+ int i;
+ /* !!!!! TODO: Implementation */
+ dk_t2l_output_start_file();
+ argc = dk4app_get_argc(app);
+ if (0 < argc) {
+ switch (dk_t2l_numeric) {
+ case 2: {
+ for (i = 0; i < argc; i++) {
+ xargv = dk4app_get_argv(app, i);
+ if (NULL != xargv) {
+ dk_t2l_echo_hex(xargv, i);
+ }
+ }
+ dk_t2l_end_math_mode();
+ } break;
+ case 1: {
+ for (i = 0; i < argc; i++) {
+ xargv = dk4app_get_argv(app, i);
+ if (NULL != xargv) {
+ dk_t2l_echo_numeric(xargv, i);
+ }
+ }
+ dk_t2l_end_math_mode();
+ } break;
+ default: {
+ for (i = 0; i < argc; i++) {
+ xargv = dk4app_get_argv(app, i);
+ if (NULL != xargv) {
+ dk_t2l_echo_text(xargv, i);
+ }
+ }
+ } break;
+ }
+ if (EOF == fputc('\n', stdout)) { output_error = 1; }
+ } else {
+ /* !!!!! ERROR: No command line arguments specified */
+ }
+ dk_t2l_output_finish_file();
+}
+
+
+
+/** Process an opened file with file name.
+ @param fipo Opened file.
+ @param fn File name.
+ @param ienc_def Expected input encoding.
+*/
+static
+void
+dk_t2l_process_named_file(FILE *fipo, const dkChar *fn, int ienc_def)
+{
+ dk4_tsp32_t tsp32;
+ dk4_er_t er;
+ dk4_er_t er_en;
+ dk4_er_t er_pr;
+ const dkChar *oldsourcefile;
+ dk4_um_t oldsourceline;
+ int c;
+ int cc;
+ int res;
+ unsigned char ub;
+
+ dk_t2l_in_mm = 0;
+ oldsourcefile = dk4app_get_log_source_file(app);
+ oldsourceline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_file(app, fn);
+ dk4app_set_log_source_line(app, (dk4_um_t)0UL);
+ dk_t2l_output_start_file();
+ dk4error_init(&er);
+ res = dk4tsp32_setup_char(
+ &tsp32, NULL, dk_t2l_c32_handler, ienc_def, &er
+ );
+ if (0 != res) {
+ cc = 1;
+ while (1 == cc) {
+ if (0 != dk_t2l_can_continue()) {
+ c = fgetc(fipo);
+ if (EOF != c) {
+ ub = (unsigned char)c;
+ res = dk4tsp32_add_one_byte(&tsp32, ub);
+ switch (res) {
+ case DK4_TSP_RES_ERROR: {
+ exval = EXIT_FAILURE;
+ dk4tsp32_get_errors(&er_en, &er_pr, &tsp32);
+ dk_t2l_report_errors(&er_en, &er_pr);
+ } break;
+ case DK4_TSP_RES_FATAL: {
+ cc = -1;
+ exval = EXIT_FAILURE;
+ dk4tsp32_get_errors(&er_en, &er_pr, &tsp32);
+ dk_t2l_report_errors(&er_en, &er_pr);
+ } break;
+ default: {
+ } break;
+ }
+ } else {
+ cc = 0;
+ }
+ if (0 != feof(fipo)) { if (1 == cc) { cc = 0; } }
+ } else {
+ cc = -1;
+ }
+ }
+ if (0 == cc) {
+ res = dk4tsp32_finish(&tsp32);
+ switch (res) {
+ case DK4_TSP_RES_ERROR: case DK4_TSP_RES_FATAL: {
+ exval = EXIT_FAILURE;
+ dk4tsp32_get_errors(&er_en, &er_pr, &tsp32);
+ dk_t2l_report_errors(&er_en, &er_pr);
+ } break;
+ }
+ }
+ if (0 != dk_t2l_can_continue()) {
+ /* TODO: Finish current line */
+ if (0 != dk_t2l_in_mm) {
+ dk_t2l_end_math_mode();
+ if (EOF == fputc('\n', stdout)) { output_error = 1; }
+ } else {
+ if (0 == dk_t2l_last_nl) {
+ if (EOF == fputc('\n', stdout)) { output_error = 1; }
+ }
+ }
+ }
+ } else {
+ /* ERROR: Setup failed, should not happen, bug */
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 10);
+ exval = EXIT_FAILURE;
+ }
+ dk_t2l_output_finish_file();
+ dk4app_set_log_source_file(app, oldsourcefile);
+ dk4app_set_log_source_line(app, oldsourceline);
+}
+
+
+
+/** Process standard input.
+*/
+static
+void
+dk_t2l_process_stdin(void)
+{
+#if DK4_ON_WINDOWS
+ int oldmode;
+
+ oldmode = _setmode(_fileno(stdin), _O_BINARY);
+#endif
+ dk_t2l_process_named_file(stdin, dk_t2l_kwnl[4], dk_t2l_i_std);
+#if DK4_ON_WINDOWS
+ _setmode(_fileno(stdin), oldmode);
+#endif
+}
+
+
+
+/** Process one real file name.
+ @param infname File name to process.
+*/
+static
+void
+dk_t2l_process_one_file_name(const dkChar *infname)
+{
+ FILE *fipo = NULL;
+ int tests = DK4_FOPEN_SC_IS_REGULAR;
+ fipo = dk4fopen_app(infname, dk_t2l_kwnl[3], tests, app);
+ if (NULL != fipo) {
+ dk_t2l_process_named_file(fipo, infname, dk_t2l_i_file);
+ fclose(fipo);
+ } else {
+ exval = EXIT_FAILURE;
+ }
+}
+
+
+
+#if DK4_ON_WINDOWS
+
+/** Expand file name pattern and process the files.
+ @pattern File name pattern to expand.
+ @return 1 if files were found, 0 otherwise.
+*/
+static
+int
+dk_t2l_expand_and_process(const dkChar *pattern)
+{
+ dkChar buf[DK4_MAX_PATH];
+ dk4_dir_t *fne;
+ const dkChar *shf;
+ const dkChar *pth;
+ int cc;
+ int back = 0;
+ fne = dk4app_fne_open(pattern, app);
+ if (NULL != fne) {
+ cc = 1;
+ while (1 == cc) {
+ if (0 != dk_t2l_can_continue()) {
+ shf = dk4dir_next_file(fne);
+ if (NULL != shf) {
+ back = 1;
+ pth = dk4dir_get_path(fne);
+ if (NULL != pth) {
+ if (0 != dk4str_cpy_s(buf, DK4_SIZEOF(buf,dkChar), pth, NULL)) {
+ if(0!=dk4str_cat_s(buf,DK4_SIZEOF(buf,dkChar),dk_t2l_kwnl[5],NULL))
+ {
+ if(0 != dk4str_cat_s(buf, DK4_SIZEOF(buf,dkChar), shf, NULL)) {
+ dk_t2l_process_one_file_name(buf);
+ } else {
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ exval = EXIT_FAILURE;
+ }
+ }
+ else
+ {
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ dk_t2l_process_one_file_name(shf);
+ }
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = -1;
+ }
+ }
+ dk4dir_close(fne);
+ } else {
+ exval = EXIT_FAILURE;
+ }
+ return back;
+}
+
+#endif
+
+
+
+/** Process one file name, check whether expansion is necessary.
+ @param infname Input file name to process, may be NULL.
+*/
+static
+void
+dk_t2l_process_filename(const dkChar *infname)
+{
+ if (NULL != infname) {
+#if DK4_ON_WINDOWS
+ if (0 != dk4path_must_expand(infname)) {
+ if (0 == dk_t2l_expand_and_process(infname)) {
+ exval = EXIT_FAILURE;
+ /* ERROR: No such file */
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 107, infname);
+ }
+ } else {
+#endif
+ dk_t2l_process_one_file_name(infname);
+#if DK4_ON_WINDOWS
+ }
+#endif
+ }
+}
+
+
+
+/** Run after installing the signal handlers.
+*/
+static
+void
+dk_t2l_normal_run(void)
+{
+ int argc;
+ int i;
+ if (0 != dk_t2l_process_options()) {
+ exval = EXIT_SUCCESS;
+ dk_t2l_output_start_page();
+ if (0 != dk_t2l_echo) {
+ dk_t2l_process_cmdline();
+ } else {
+ argc = dk4app_get_argc(app);
+ if (0 < argc) {
+ for (i = 0; ((0 != dk_t2l_can_continue()) && (i < argc)); i++) {
+ dk_t2l_process_filename(dk4app_get_argv(app, i));
+ }
+ } else {
+ dk_t2l_process_stdin();
+ }
+ }
+ dk_t2l_output_finish_page();
+ if (0 != dk4app_opt_is_set_short(app, dkT('r'), NULL)) {
+ dk4uc2l_recommendations(uc2l, stdout);
+ }
+ if (0 != dk4uc2l_retrieve_errors(uc2l)) { $? "! ERROR"
+ /* ERROR: Probably incorrect output due to problems */
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 11);
+ exval = EXIT_FAILURE;
+ }
+ }
+ if (NULL != uc2l) {
+ dk4uc2l_close(uc2l);
+ uc2l = NULL;
+ }
+}
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+dk_t2l_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ struct sigaction opipe;
+#endif
+ struct sigaction oint;
+#ifdef SIGPIPE
+ struct sigaction npipe;
+#endif
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+ int success = 0;
+
+#ifdef SIGPIPE
+ /* Set up signal handling for SIGPIPE.
+ */
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+#endif
+
+ /* Set up signal handling for SIGINT.
+ */
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ dk_t2l_normal_run();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+#ifdef SIGPIPE
+ /* Restore signal handling for SIGPIPE.
+ */
+ restore_old_pipe:
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+#endif
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+dk_t2l_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ dk_t2l_normal_run();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+#ifdef SIGPIPE
+ sigset(SIGPIPE, oldpipe);
+#endif
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+dk_t2l_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = signal(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ dk_t2l_normal_run();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+#ifdef SIGPIPE
+ signal(SIGPIPE, oldpipe);
+#endif
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+dk_t2l_run_with_signal_handlers(void)
+{
+ dk_t2l_normal_run();
+}
+#endif
+#endif
+#endif
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ int shp;
+ $!trace-init dk-t2l.deb
+ $? "+ main"
+ dk4fput_initialize_stderr();
+ app = dk4app_open_cmd(
+ argc, argv, dk_t2l_options, dk_t2l_sz_options,
+ dk_t2l_kwnl[0], DKT_VERSION_DK,
+ dk_t2l_kwnl[1], dk_t2l_help_text, dk_t2l_license_text
+ );
+ if (NULL != app) {
+ dk_t2l_i_std = dk4app_get_stdin_encoding(app);
+ dk_t2l_i_file = dk4app_get_file_in_encoding(app);
+ dk_t2l_sz_msg = dk4app_string_table_size(dk_t2l_kw_def);
+ dk_t2l_msg = dk4app_string_table(app, dk_t2l_kwnl[2], dk_t2l_kw_def);
+ if (0 != dk4app_can_run_normally(app)) {
+ dk_t2l_run_with_signal_handlers();
+ } else {
+ dk4fput_initialize_stdout();
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ fflush(stdout);
+ fflush(stderr);
+ dk4fput_cleanup_stdout();
+ }
+ if (0 != sig_read_atomic(&sig_had_int )) {
+ exval = EXIT_FAILURE;
+ /* ERROR: Interrupted by SIGINT */
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 12);
+ }
+ if (0 != sig_read_atomic(&sig_had_term)) {
+ exval = EXIT_FAILURE;
+ /* ERROR: Interrupted by SIGTERM */
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 13);
+ }
+#ifdef SIGPIPE
+ if (0 != sig_read_atomic(&sig_had_pipe)) {
+ exval = EXIT_FAILURE;
+ shp = 1;
+ /* ERROR: Interrupted by SIGPIPE */
+ if (0 != verbose) {
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 14);
+ }
+ } else {
+ shp = 0;
+ }
+#else
+ shp = 0;
+#endif
+ if ((0 == shp) && (0 != output_error)) {
+ exval = EXIT_FAILURE;
+ /* ERROR: Output to stdout failed */
+ dk4app_log_1(app, dk_t2l_msg, dk_t2l_sz_msg, DK4_LL_ERROR, 15);
+ }
+ dk4app_close(app);
+ }
+ fflush(stdout);
+ if (0 != sig_read_atomic(&sig_had_int )) { exval = EXIT_FAILURE; }
+ if (0 != sig_read_atomic(&sig_had_term)) { exval = EXIT_FAILURE; }
+#ifdef SIGPIPE
+ if (0 != sig_read_atomic(&sig_had_pipe)) { exval = EXIT_FAILURE; }
+#endif
+ if (0 != output_error) { exval = EXIT_FAILURE; }
+ fflush(stderr);
+ dk4fput_cleanup_stderr();
+ $? "- main %d", exval
+ $!trace-end
+ exit(exval); return exval;
+}
+
+
diff --git a/support/dktools/dk-t2l.rc b/support/dktools/dk-t2l.rc
new file mode 100644
index 0000000000..0f4571cece
--- /dev/null
+++ b/support/dktools/dk-t2l.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Text to LaTeX converter\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "Text to LaTeX converter\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "dk-t2l\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/dk-uid.c b/support/dktools/dk-uid.c
new file mode 100644
index 0000000000..2263382aa5
--- /dev/null
+++ b/support/dktools/dk-uid.c
@@ -0,0 +1,937 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk-uid.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#line 9 "dk-uid.ctr"
+
+/** @file dk-uid.c Search for free user ID in a given range.
+ See dk_uid_help_text below.
+*/
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PWD_H
+#ifndef PWD_H_INCLUDED
+#include <pwd.h>
+#define PWD_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4mem.h"
+#include "dk4numco.h"
+#include "dk4fput.h"
+#include "dk4vers.h"
+#include "dk4app.h"
+#include "dk4maidddu.h"
+#include "dk4maadu.h"
+#include "dk4maodd.h"
+#include "dk4bf.h"
+
+
+
+
+
+#line 61 "dk-uid.ctr"
+
+
+
+/** Constant keywords used by the module, not localized.
+*/
+static const dkChar * const dk_uid_kwnl[] = {
+/* 0 */
+dkT("dktools"),
+
+/* 1 */
+dkT("dk-uid.txt"),
+
+/* 2 */
+dkT("dk-uid.str"),
+
+NULL
+
+
+#line 81 "dk-uid.ctr"
+};
+
+
+
+/** Help text used if localized help file is not found.
+*/
+static const dkChar * const dk_uid_help_text[] = {
+dkT(""),
+dkT("Find free user ID"),
+dkT(""),
+dkT("dk-uid <min> <max>"),
+dkT(""),
+dkT("The program finds to attempt a free user ID (UID) value in the specified"),
+dkT("range."),
+dkT(""),
+dkT("Options:"),
+dkT("--help\t\tShow this short help text."),
+dkT("--manual\t*** SHOW FULL MANUAL. ***"),
+dkT("--version\tShow version information."),
+dkT("--license\tShow license information."),
+dkT(""),
+dkT("http://dktools.sourceforge.net"),
+dkT(""),
+NULL
+
+
+#line 106 "dk-uid.ctr"
+};
+
+
+
+/** License conditions.
+*/
+static const dkChar * const dk_uid_license_text[] = {
+dkT("This software uses code from the following projects, either directly or as"),
+dkT("a library:"),
+dkT(""),
+dkT("dktools\t\tDirk Krause's tools and libraries."),
+dkT("\t\tSee http://dktools.sourceforge.net/ for more information."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT("zlib\t\tData compression library."),
+dkT("\t\tSee http://www.zlib.net/ for more information."),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT("bzip2\t\tData compression program and library."),
+dkT("\t\tSee http://www.bzip.org/ for more information."),
+#endif
+dkT(""),
+dkT("All the licenses below apply to the program."),
+dkT("Licenses for used libraries are shown as found on my Scientific Linux 6.x"),
+dkT("computer in the /usr/share/doc directory on 2015-04-01. Check the project"),
+dkT("homepages of the used libraries for additional information and/or updated"),
+dkT("license terms."),
+dkT(""),
+dkT(""),
+dkT("DK tools and libraries license"),
+dkT("=============================="),
+dkT("Copyright (c) 2015-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above copyright notice,"),
+dkT(" this list of conditions and the following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("* Neither the name of the Dirk Krause nor the names of contributors may be"),
+dkT(" used to endorse or promote products derived from this software without"),
+dkT(" specific prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\""),
+dkT("AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED."),
+dkT(""),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,"),
+dkT("INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,"),
+dkT("BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,"),
+dkT("DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY"),
+dkT("OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,"),
+dkT("EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT(""),
+dkT("Zlib license"),
+dkT("============"),
+dkT("(C) 1995-2004 Jean-loup Gailly and Mark Adler"),
+dkT(""),
+dkT("This software is provided 'as-is', without any express or implied"),
+dkT("warranty. In no event will the authors be held liable for any damages"),
+dkT("arising from the use of this software."),
+dkT(""),
+dkT("Permission is granted to anyone to use this software for any purpose,"),
+dkT("including commercial applications, and to alter it and redistribute it"),
+dkT("freely, subject to the following restrictions:"),
+dkT(""),
+dkT("1. The origin of this software must not be misrepresented; you must not"),
+dkT(" claim that you wrote the original software. If you use this software"),
+dkT(" in a product, an acknowledgment in the product documentation would be"),
+dkT(" appreciated but is not required."),
+dkT("2. Altered source versions must be plainly marked as such, and must not be"),
+dkT(" misrepresented as being the original software."),
+dkT("3. This notice may not be removed or altered from any source distribution."),
+dkT(""),
+dkT("Jean-loup Gailly Mark Adler"),
+dkT("jloup@gzip.org madler@alumni.caltech.edu"),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT(""),
+dkT("Bzip2 and libbzip2 library license"),
+dkT("=================================="),
+dkT("This program, \"bzip2\", the associated library \"libbzip2\", and all"),
+dkT("documentation, are copyright (C) 1996-2007 Julian R Seward. All"),
+dkT("rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions"),
+dkT("are met:"),
+dkT(""),
+dkT("1. Redistributions of source code must retain the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer."),
+dkT(""),
+dkT("2. The origin of this software must not be misrepresented; you must "),
+dkT(" not claim that you wrote the original software. If you use this "),
+dkT(" software in a product, an acknowledgment in the product "),
+dkT(" documentation would be appreciated but is not required."),
+dkT(""),
+dkT("3. Altered source versions must be plainly marked as such, and must"),
+dkT(" not be misrepresented as being the original software."),
+dkT(""),
+dkT("4. The name of the author may not be used to endorse or promote "),
+dkT(" products derived from this software without specific prior written "),
+dkT(" permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS"),
+dkT("OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED"),
+dkT("WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE"),
+dkT("GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS"),
+dkT("INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,"),
+dkT("WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS"),
+dkT("SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+dkT(""),
+dkT("Julian Seward, jseward@bzip.org"),
+dkT("bzip2/libbzip2 version 1.0.5 of 10 December 2007"),
+#endif
+dkT(""),
+NULL
+
+
+#line 237 "dk-uid.ctr"
+};
+
+
+
+/** Constant texts used by the program.
+*/
+static const dkChar * const dk_uid_kw_def[] = {
+/* 0 */
+dkT("Failed to install signal handlers!"),
+
+/* 1 */
+dkT("Failed to restore signal handlers!"),
+
+/* 2 */
+dkT("Illegal number of command line arguments!\n\tMinimum and maximum UID required!"),
+
+/* 3 */
+dkT("The getpwent() function is not available on this platform!"),
+
+/* 4 */
+dkT("Failed to write text to standard output!"),
+
+/* 5 */
+dkT("Failed to convert numeric value to string, probably bug!"),
+
+/* 6 */
+dkT("No unused UID in specified range!"),
+
+/* 7 */
+dkT("Failed to retrieve bit from bit field, probably bug!"),
+
+/* 8 */
+dkT("Aborted by signal!"),
+
+/* 9 */
+dkT("Failed to obtain command line arguments, probably bug!"),
+
+/* 10 */
+dkT("Command line argument \""),
+
+/* 11 */
+dkT("\" is not a number!"),
+
+/* 12 */
+dkT("UID range too large!"),
+
+NULL
+
+
+#line 295 "dk-uid.ctr"
+};
+
+
+
+/** Application structure for diagnostics.
+*/
+dk4_app_t *app = NULL;
+
+
+
+/** Constant texts used by the program, localized.
+*/
+static const dkChar * const *dk_uid_msg = dk_uid_kw_def;
+
+
+
+/** Minimum UID value.
+*/
+static dk4_um_t dk_uid_min = (dk4_um_t)500UL;
+
+
+
+
+/** Maximum UID value.
+*/
+static dk4_um_t dk_uid_max = (dk4_um_t)59997UL;
+
+
+
+
+/** Number of elements in dk_uid_msg array.
+*/
+static size_t dk_uid_sz_msg =
+sizeof(dk_uid_kw_def)/sizeof(DK4_PCDKCHAR) - 1;
+
+
+
+/** Exit status code.
+*/
+int exval = EXIT_FAILURE;
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+/** Pass a volatile pointer to an atomic integer.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ptr Address of atomic integer variable.
+ @return The unmodified pointer.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+/** Check whether we can continue or if a signal was received.
+ @param check_pipe Flag: Check for occured SIGPIPE signal too.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(int check_pipe)
+{
+ int back = 1;
+#ifdef SIGPIPE
+ if (0 != check_pipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_int )) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+/** Check whether we can continue.
+ @return 1 for yes, 0 for no.
+*/
+static
+int
+dk_uid_can_continue(void)
+{
+ int back = 1;
+ if (0 == sig_can_continue(1)) {
+ back = 0;
+ }
+ return back;
+}
+
+
+
+
+/** Traverse existing user accounts to search for a free UID.
+ @param rs Range size.
+*/
+static
+void
+dk_uid_run_with_range_size(dk4_um_t rs)
+{
+#if DK4_HAVE_GETPWENT
+ dkChar buf[16+8*sizeof(dk4_um_t)];
+ dk4_bit_field_t *bf = NULL;
+ struct passwd *pwptr;
+ dk4_um_t cuid;
+ int cc;
+ int bval;
+ bf = dk4bf_open(rs, NULL);
+ if (NULL != bf) {
+#if DK4_HAVE_SETPWENT
+ setpwent();
+#endif
+ cc = 1;
+ while (1 == cc) {
+ if (0 != dk_uid_can_continue()) {
+ pwptr = getpwent();
+ if (NULL != pwptr) {
+ cuid = (dk4_um_t)(pwptr->pw_uid);
+ if (dk_uid_min <= cuid) {
+ if (dk_uid_max >= cuid) {
+ dk4bf_set(bf, (size_t)(cuid - dk_uid_min), 1, NULL);
+ }
+ }
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = -1;
+ }
+ }
+ if (0 == cc) {
+ cuid = (dk4_um_t)0UL;
+ cc = 1;
+ while (1 == cc) {
+ if (0 != dk_uid_can_continue()) {
+ if (cuid < rs) {
+ bval = 0;
+ if (0 != dk4bf_get(&bval, bf, (size_t)cuid, NULL)) {
+ if (0 == bval) {
+ cc = 0;
+ bval = dk4ma_write_decimal_unsigned(
+ buf, DK4_SIZEOF(buf,dkChar), (cuid + dk_uid_min), 0, NULL
+ );
+ if (0 != bval) {
+ if (0 != dk4fputs(buf, stdout, NULL)) {
+ if (0 != dk4fputc(dkT('\n'), stdout, NULL)) {
+ exval = EXIT_SUCCESS;
+ } else {
+ cc = -1;
+ /* ERROR: Write failed */
+ dk4app_log_1(
+ app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 4
+ );
+ }
+ } else {
+ cc = -1;
+ /* ERROR: Write failed */
+ dk4app_log_1(
+ app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 4
+ );
+ }
+ } else {
+
+#line 529 "dk-uid.ctr"
+ cc = -1;
+ /* ERROR: Failed to convert value to string, bug */
+ dk4app_log_1(
+ app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 5
+ );
+ }
+ } else {
+ cuid++;
+ if (rs <= cuid) {
+ cc = -1;
+ /* ERROR: No free UID found */
+ dk4app_log_1(
+ app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 6
+ );
+ }
+ }
+ } else {
+
+#line 546 "dk-uid.ctr"
+ cc = -1;
+ /* ERROR: Failed to retrieve bit, bug */
+ dk4app_log_1(
+ app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 7
+ );
+ }
+ } else {
+ cc = -1;
+ /* ERROR: No free UID found */
+ dk4app_log_1(
+ app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 6
+ );
+ }
+ } else {
+ cc = -1;
+ /* ERROR: Aborted by signal */
+ dk4app_log_1(
+ app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 8
+ );
+ }
+ }
+ } else {
+ /* ERROR: Aborted by signal */
+ dk4app_log_1(
+ app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 8
+ );
+ }
+#if DK4_HAVE_ENDPWENT
+ endpwent();
+#endif
+ dk4bf_close(bf);
+ } else {
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ }
+#endif
+}
+
+
+
+/** After installing the signal handlers, process the command line
+ arguments.
+*/
+static
+void
+dk_uid_normal_run(void)
+{
+ dk4_er_t er;
+ const dkChar *str1;
+ const dkChar *str2;
+ const dkChar *ep1 = NULL;
+ const dkChar *ep2 = NULL;
+ dk4_um_t tmpval;
+ int numargs;
+ int res;
+
+
+#line 602 "dk-uid.ctr"
+ numargs = dk4app_get_argc(app);
+ if (2 == numargs) {
+ str1 = dk4app_get_argv(app, 0);
+ str2 = dk4app_get_argv(app, 1);
+ if ((NULL != str1) && (NULL != str2)) {
+
+#line 607 "dk-uid.ctr"
+ res = dk4ma_input_dk_dec_dk4_um_t(&dk_uid_min, str1, &ep1, 1, NULL);
+ if (0 != res) {
+ res = dk4ma_input_dk_dec_dk4_um_t(&dk_uid_max, str2, &ep2, 1, NULL);
+ if (0 != res) {
+ if (dk_uid_max < dk_uid_min) {
+ tmpval = dk_uid_max;
+ dk_uid_max = dk_uid_min;
+ dk_uid_min = tmpval;
+ }
+ tmpval = dk_uid_max - dk_uid_min;
+ dk4error_init(&er);
+ tmpval = dk4ma_um_add(tmpval, (dk4_um_t)1UL, &er);
+ if (DK4_E_NONE == er.ec) {
+ if ((dk4_um_t)SIZE_MAX >= tmpval) {
+ dk_uid_run_with_range_size(tmpval);
+ } else {
+ /* ERROR: Numeric overflow in range calculation */
+ dk4app_log_1(
+ app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 12
+ );
+ }
+ } else {
+ /* ERROR: Numeric overflow in range calculation */
+ dk4app_log_1(
+ app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 12
+ );
+ }
+ } else {
+ /* ERROR: Argument is not a number */
+ dk4app_log_3(
+ app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 10, 11, str2
+ );
+ }
+ } else {
+ /* ERROR: Argument is not a number */
+ dk4app_log_3(
+ app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 10, 11, str1
+ );
+ }
+ } else {
+
+#line 647 "dk-uid.ctr"
+ /* ERROR: Failed to obtain command line arguments, bug! */
+ dk4app_log_1(
+ app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 9
+ );
+ }
+ } else {
+ dk4app_log_1(app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 2);
+ }
+
+#line 655 "dk-uid.ctr"
+}
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+dk_uid_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ struct sigaction opipe;
+#endif
+ struct sigaction oint;
+#ifdef SIGPIPE
+ struct sigaction npipe;
+#endif
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+ int success = 0;
+
+#ifdef SIGPIPE
+ /* Set up signal handling for SIGPIPE.
+ */
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ dk4app_log_1(app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+#endif
+
+ /* Set up signal handling for SIGINT.
+ */
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ dk_uid_normal_run();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+#ifdef SIGPIPE
+ /* Restore signal handling for SIGPIPE.
+ */
+ restore_old_pipe:
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+#endif
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+dk_uid_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ dk_uid_normal_run();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+#ifdef SIGPIPE
+ sigset(SIGPIPE, oldpipe);
+#endif
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+dk_uid_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = signal(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ dk_uid_normal_run();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+#ifdef SIGPIPE
+ signal(SIGPIPE, oldpipe);
+#endif
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+dk_uid_run_with_signal_handlers(void)
+{
+ dk_uid_normal_run();
+}
+#endif
+#endif
+#endif
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+
+
+#line 858 "dk-uid.ctr"
+
+
+#line 859 "dk-uid.ctr"
+ dk4fput_initialize_stdout();
+ dk4fput_initialize_stderr();
+ app = dk4app_open_cmd(
+ argc, argv, NULL, 0,
+ dk_uid_kwnl[0], DKT_VERSION_DK,
+ dk_uid_kwnl[1], dk_uid_help_text, dk_uid_license_text
+ );
+ if (NULL != app) {
+ dk_uid_sz_msg = dk4app_string_table_size(dk_uid_kw_def);
+ dk_uid_msg = dk4app_string_table(app, dk_uid_kwnl[2], dk_uid_kw_def);
+#if DK4_HAVE_GETPWENT
+ if (0 != dk4app_can_run_normally(app)) {
+ dk_uid_run_with_signal_handlers();
+ } else {
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+#else
+ dk4app_log_1(app, dk_uid_msg, dk_uid_sz_msg, DK_LL_ERROR, 3);
+#endif
+ dk4app_close(app);
+ } else {
+ }
+ fflush(stdout);
+ fflush(stderr);
+ dk4fput_cleanup_stderr();
+ dk4fput_cleanup_stdout();
+
+
+#line 888 "dk-uid.ctr"
+
+
+#line 889 "dk-uid.ctr"
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/dk-uid.ctr b/support/dktools/dk-uid.ctr
new file mode 100644
index 0000000000..18dc14d287
--- /dev/null
+++ b/support/dktools/dk-uid.ctr
@@ -0,0 +1,891 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% module
+
+/** @file dk-uid.c Search for free user ID in a given range.
+ See dk_uid_help_text below.
+*/
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PWD_H
+#ifndef PWD_H_INCLUDED
+#include <pwd.h>
+#define PWD_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4mem.h"
+#include "dk4numco.h"
+#include "dk4fput.h"
+#include "dk4vers.h"
+#include "dk4app.h"
+#include "dk4maidddu.h"
+#include "dk4maadu.h"
+#include "dk4maodd.h"
+#include "dk4bf.h"
+
+
+
+$!trace-include
+
+
+
+/** Constant keywords used by the module, not localized.
+*/
+static const dkChar * const dk_uid_kwnl[] = {
+$!string-table macro=dkT
+#
+# 0 Program group name
+#
+dktools
+#
+# 1 Help file name
+#
+dk-uid.txt
+#
+# 2 String table file
+#
+dk-uid.str
+$!end
+};
+
+
+
+/** Help text used if localized help file is not found.
+*/
+static const dkChar * const dk_uid_help_text[] = {
+$!text macro=dkT
+
+Find free user ID
+
+dk-uid <min> <max>
+
+The program finds to attempt a free user ID (UID) value in the specified
+range.
+
+Options:
+--help Show this short help text.
+--manual *** SHOW FULL MANUAL. ***
+--version Show version information.
+--license Show license information.
+
+http://dktools.sourceforge.net
+
+$!end
+};
+
+
+
+/** License conditions.
+*/
+static const dkChar * const dk_uid_license_text[] = {
+$!text macro=dkT,preprocessor
+This software uses code from the following projects, either directly or as
+a library:
+
+dktools Dirk Krause's tools and libraries.
+ See http://dktools.sourceforge.net/ for more information.
+#if DK4_HAVE_ZLIB_H
+
+zlib Data compression library.
+ See http://www.zlib.net/ for more information.
+#endif
+#if DK4_HAVE_BZLIB_H
+
+bzip2 Data compression program and library.
+ See http://www.bzip.org/ for more information.
+#endif
+
+All the licenses below apply to the program.
+Licenses for used libraries are shown as found on my Scientific Linux 6.x
+computer in the /usr/share/doc directory on 2015-04-01. Check the project
+homepages of the used libraries for additional information and/or updated
+license terms.
+
+
+DK tools and libraries license
+==============================
+Copyright (c) 2015-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#if DK4_HAVE_ZLIB_H
+
+
+Zlib license
+============
+(C) 1995-2004 Jean-loup Gailly and Mark Adler
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+
+Jean-loup Gailly Mark Adler
+jloup@gzip.org madler@alumni.caltech.edu
+#endif
+#if DK4_HAVE_BZLIB_H
+
+
+Bzip2 and libbzip2 library license
+==================================
+This program, "bzip2", the associated library "libbzip2", and all
+documentation, are copyright (C) 1996-2007 Julian R Seward. All
+rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+3. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Julian Seward, jseward@bzip.org
+bzip2/libbzip2 version 1.0.5 of 10 December 2007
+#endif
+
+$!end
+};
+
+
+
+/** Constant texts used by the program.
+*/
+static const dkChar * const dk_uid_kw_def[] = {
+$!string-table macro=dkT
+#
+# 0 Error: Failed to install signal handlers!
+#
+Failed to install signal handlers!
+#
+# 1 Error: Failed to restore signal handlers!
+#
+Failed to restore signal handlers!
+#
+# 2 Error: Illegal number of command line arguments!
+#
+Illegal number of command line arguments!\n\tMinimum and maximum UID required!
+#
+# 3 Error: getpwent() function is not available on this platform!
+#
+The getpwent() function is not available on this platform!
+#
+# 4 Error: Failed to write text to standard output!
+#
+Failed to write text to standard output!
+#
+# 5 Error: Failed to convert numeric value to string!
+#
+Failed to convert numeric value to string, probably bug!
+#
+# 6 Error: No unused UID in specified range!
+#
+No unused UID in specified range!
+#
+# 7 Error: Failed to retrieve bit from bit field, probably bug!
+#
+Failed to retrieve bit from bit field, probably bug!
+#
+# 8 Error: Aborted by signal!
+#
+Aborted by signal!
+#
+# 9 Error: Failed to obtain command line arguments, probably bug!
+#
+Failed to obtain command line arguments, probably bug!
+#
+# 10 11 Error: Command line argument "" is not a number!
+#
+Command line argument "
+" is not a number!
+#
+# 12 Error: UID range too large!
+#
+UID range too large!
+$!end
+};
+
+
+
+/** Application structure for diagnostics.
+*/
+dk4_app_t *app = NULL;
+
+
+
+/** Constant texts used by the program, localized.
+*/
+static const dkChar * const *dk_uid_msg = dk_uid_kw_def;
+
+
+
+/** Minimum UID value.
+*/
+static dk4_um_t dk_uid_min = (dk4_um_t)500UL;
+
+
+
+
+/** Maximum UID value.
+*/
+static dk4_um_t dk_uid_max = (dk4_um_t)59997UL;
+
+
+
+
+/** Number of elements in dk_uid_msg array.
+*/
+static size_t dk_uid_sz_msg =
+sizeof(dk_uid_kw_def)/sizeof(DK4_PCDKCHAR) - 1;
+
+
+
+/** Exit status code.
+*/
+int exval = EXIT_FAILURE;
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+/** Pass a volatile pointer to an atomic integer.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ptr Address of atomic integer variable.
+ @return The unmodified pointer.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+/** Check whether we can continue or if a signal was received.
+ @param check_pipe Flag: Check for occured SIGPIPE signal too.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(int check_pipe)
+{
+ int back = 1;
+#ifdef SIGPIPE
+ if (0 != check_pipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_int )) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+/** Check whether we can continue.
+ @return 1 for yes, 0 for no.
+*/
+static
+int
+dk_uid_can_continue(void)
+{
+ int back = 1;
+ if (0 == sig_can_continue(1)) {
+ back = 0;
+ }
+ return back;
+}
+
+
+
+
+/** Traverse existing user accounts to search for a free UID.
+ @param rs Range size.
+*/
+static
+void
+dk_uid_run_with_range_size(dk4_um_t rs)
+{
+#if DK4_HAVE_GETPWENT
+ dkChar buf[16+8*sizeof(dk4_um_t)];
+ dk4_bit_field_t *bf = NULL;
+ struct passwd *pwptr;
+ dk4_um_t cuid;
+ int cc;
+ int bval;
+ bf = dk4bf_open(rs, NULL);
+ if (NULL != bf) {
+#if DK4_HAVE_SETPWENT
+ setpwent();
+#endif
+ cc = 1;
+ while (1 == cc) {
+ if (0 != dk_uid_can_continue()) {
+ pwptr = getpwent();
+ if (NULL != pwptr) {
+ cuid = (dk4_um_t)(pwptr->pw_uid);
+ if (dk_uid_min <= cuid) {
+ if (dk_uid_max >= cuid) {
+ dk4bf_set(bf, (size_t)(cuid - dk_uid_min), 1, NULL);
+ }
+ }
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = -1;
+ }
+ }
+ if (0 == cc) {
+ cuid = (dk4_um_t)0UL;
+ cc = 1;
+ while (1 == cc) {
+ if (0 != dk_uid_can_continue()) {
+ if (cuid < rs) {
+ bval = 0;
+ if (0 != dk4bf_get(&bval, bf, (size_t)cuid, NULL)) {
+ if (0 == bval) {
+ cc = 0;
+ bval = dk4ma_write_decimal_unsigned(
+ buf, DK4_SIZEOF(buf,dkChar), (cuid + dk_uid_min), 0, NULL
+ );
+ if (0 != bval) {
+ if (0 != dk4fputs(buf, stdout, NULL)) {
+ if (0 != dk4fputc(dkT('\n'), stdout, NULL)) {
+ exval = EXIT_SUCCESS;
+ } else {
+ cc = -1;
+ /* ERROR: Write failed */
+ dk4app_log_1(
+ app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 4
+ );
+ }
+ } else {
+ cc = -1;
+ /* ERROR: Write failed */
+ dk4app_log_1(
+ app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 4
+ );
+ }
+ } else { $? "! bug"
+ cc = -1;
+ /* ERROR: Failed to convert value to string, bug */
+ dk4app_log_1(
+ app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 5
+ );
+ }
+ } else {
+ cuid++;
+ if (rs <= cuid) {
+ cc = -1;
+ /* ERROR: No free UID found */
+ dk4app_log_1(
+ app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 6
+ );
+ }
+ }
+ } else { $? "! bug"
+ cc = -1;
+ /* ERROR: Failed to retrieve bit, bug */
+ dk4app_log_1(
+ app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 7
+ );
+ }
+ } else {
+ cc = -1;
+ /* ERROR: No free UID found */
+ dk4app_log_1(
+ app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 6
+ );
+ }
+ } else {
+ cc = -1;
+ /* ERROR: Aborted by signal */
+ dk4app_log_1(
+ app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 8
+ );
+ }
+ }
+ } else {
+ /* ERROR: Aborted by signal */
+ dk4app_log_1(
+ app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 8
+ );
+ }
+#if DK4_HAVE_ENDPWENT
+ endpwent();
+#endif
+ dk4bf_close(bf);
+ } else {
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ }
+#endif
+}
+
+
+
+/** After installing the signal handlers, process the command line
+ arguments.
+*/
+static
+void
+dk_uid_normal_run(void)
+{
+ dk4_er_t er;
+ const dkChar *str1;
+ const dkChar *str2;
+ const dkChar *ep1 = NULL;
+ const dkChar *ep2 = NULL;
+ dk4_um_t tmpval;
+ int numargs;
+ int res;
+ $? "+ dk_uid_normal_run"
+ numargs = dk4app_get_argc(app);
+ if (2 == numargs) {
+ str1 = dk4app_get_argv(app, 0);
+ str2 = dk4app_get_argv(app, 1);
+ if ((NULL != str1) && (NULL != str2)) { $? ". args ok"
+ res = dk4ma_input_dk_dec_dk4_um_t(&dk_uid_min, str1, &ep1, 1, NULL);
+ if (0 != res) {
+ res = dk4ma_input_dk_dec_dk4_um_t(&dk_uid_max, str2, &ep2, 1, NULL);
+ if (0 != res) {
+ if (dk_uid_max < dk_uid_min) {
+ tmpval = dk_uid_max;
+ dk_uid_max = dk_uid_min;
+ dk_uid_min = tmpval;
+ }
+ tmpval = dk_uid_max - dk_uid_min;
+ dk4error_init(&er);
+ tmpval = dk4ma_um_add(tmpval, (dk4_um_t)1UL, &er);
+ if (DK4_E_NONE == er.ec) {
+ if ((dk4_um_t)SIZE_MAX >= tmpval) {
+ dk_uid_run_with_range_size(tmpval);
+ } else {
+ /* ERROR: Numeric overflow in range calculation */
+ dk4app_log_1(
+ app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 12
+ );
+ }
+ } else {
+ /* ERROR: Numeric overflow in range calculation */
+ dk4app_log_1(
+ app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 12
+ );
+ }
+ } else {
+ /* ERROR: Argument is not a number */
+ dk4app_log_3(
+ app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 10, 11, str2
+ );
+ }
+ } else {
+ /* ERROR: Argument is not a number */
+ dk4app_log_3(
+ app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 10, 11, str1
+ );
+ }
+ } else { $? "! BUG"
+ /* ERROR: Failed to obtain command line arguments, bug! */
+ dk4app_log_1(
+ app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 9
+ );
+ }
+ } else {
+ dk4app_log_1(app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 2);
+ } $? "- dk_uid_normal_run"
+}
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+dk_uid_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ struct sigaction opipe;
+#endif
+ struct sigaction oint;
+#ifdef SIGPIPE
+ struct sigaction npipe;
+#endif
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+ int success = 0;
+
+#ifdef SIGPIPE
+ /* Set up signal handling for SIGPIPE.
+ */
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ dk4app_log_1(app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+#endif
+
+ /* Set up signal handling for SIGINT.
+ */
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ dk_uid_normal_run();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+#ifdef SIGPIPE
+ /* Restore signal handling for SIGPIPE.
+ */
+ restore_old_pipe:
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dk_uid_msg, dk_uid_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+#endif
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+dk_uid_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ dk_uid_normal_run();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+#ifdef SIGPIPE
+ sigset(SIGPIPE, oldpipe);
+#endif
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+dk_uid_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = signal(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ dk_uid_normal_run();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+#ifdef SIGPIPE
+ signal(SIGPIPE, oldpipe);
+#endif
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+dk_uid_run_with_signal_handlers(void)
+{
+ dk_uid_normal_run();
+}
+#endif
+#endif
+#endif
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ $!trace-init dk-uid.deb
+ $? "+ main"
+ dk4fput_initialize_stdout();
+ dk4fput_initialize_stderr();
+ app = dk4app_open_cmd(
+ argc, argv, NULL, 0,
+ dk_uid_kwnl[0], DKT_VERSION_DK,
+ dk_uid_kwnl[1], dk_uid_help_text, dk_uid_license_text
+ );
+ if (NULL != app) {
+ dk_uid_sz_msg = dk4app_string_table_size(dk_uid_kw_def);
+ dk_uid_msg = dk4app_string_table(app, dk_uid_kwnl[2], dk_uid_kw_def);
+#if DK4_HAVE_GETPWENT
+ if (0 != dk4app_can_run_normally(app)) {
+ dk_uid_run_with_signal_handlers();
+ } else {
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+#else
+ dk4app_log_1(app, dk_uid_msg, dk_uid_sz_msg, DK_LL_ERROR, 3);
+#endif
+ dk4app_close(app);
+ } else {
+ }
+ fflush(stdout);
+ fflush(stderr);
+ dk4fput_cleanup_stderr();
+ dk4fput_cleanup_stdout();
+ $? "- main %d", exval
+ $!trace-end
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/dk3.h b/support/dktools/dk3.h
new file mode 100644
index 0000000000..bb49ac3c71
--- /dev/null
+++ b/support/dktools/dk3.h
@@ -0,0 +1,13 @@
+
+/** @file dk3.h Include minimum headers for dk3 library.
+ */
+
+#ifndef DK3_H_INCLUDED
+#define DK3_H_INCLUDED 1
+
+#include <dk3conf.h>
+#include <dk3types.h>
+#include <dk3const.h>
+
+#endif
+
diff --git a/support/dktools/dk3all.h b/support/dktools/dk3all.h
new file mode 100644
index 0000000000..517c63a091
--- /dev/null
+++ b/support/dktools/dk3all.h
@@ -0,0 +1,267 @@
+
+/** @file dk3all.h Main include file for the dk3 libraries.
+Applications using the dk3 libraries should include this file.
+*/
+
+#ifndef DK3_ALL_H_INCLUDED
+#define DK3_ALL_H_INCLUDED 1
+
+#include <dk3conf.h>
+
+#if DK3_HAVE_WINSOCK2_H
+#if !DK3_WINSOCK2_H_INCLUDED
+#define DK3_WINSOCK2_H_INCLUDED 1
+#include <winsock2.h>
+#endif
+#endif
+#if DK3_HAVE_WS2TCPIP_H
+#include <ws2tcpip.h>
+#endif
+#if DK3_HAVE_WINDOWS_H
+#if !DK3_WINDOWS_H_INCLUDED
+#define DK3_WINDOWS_H_INCLUDED 1
+#include <windows.h>
+#endif
+#endif
+#if DK3_HAVE_WINBASE_H
+#if !DK3_WINBASE_H_INCLUDED
+#define DK3_WINBASE_H_INCLUDED 1
+#include <winbase.h>
+#endif
+#endif
+#if DK3_HAVE_WINREG_H
+#if !DK3_WINREG_H_INCLUDED
+#define DK3_WINREG_H_INCLUDED 1
+#include <winreg.h>
+#endif
+#endif
+#if DK3_HAVE_WINCON_H
+#if !DK3_WINCON_H_INCLUDED
+#define DK3_WINCON_H_INCLUDED 1
+#include <wincon.h>
+#endif
+#endif
+#if DK3_HAVE_STDIO_H
+#include <stdio.h>
+#endif
+#if DK3_HAVE_ERR_H
+#include <err.h>
+#endif
+#if DK3_HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if DK3_HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if DK3_HAVE_STDDEF_H
+#include <stddef.h>
+#endif
+#if DK3_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if DK3_HAVE_PROCESS_H
+#include <process.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#if DK3_HAVE_SYS_SYSCTL_H
+#include <sys/sysctl.h>
+#endif
+#if DK3_HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+#if DK3_HAVE_SYS_STATVFS_H
+#include <sys/statvfs.h>
+#endif
+#if DK3_HAVE_SYS_STROPTS_H
+#include <sys/stropts.h>
+#endif
+#if DK3_HAVE_SYS_FILE_H
+#include <sys/file.h>
+#endif
+#if DK3_HAVE_SYS_UIO_H
+#include <sys/uio.h>
+#endif
+#if DK3_HAVE_SYS_UN_H
+#include <sys/un.h>
+#endif
+#if DK3_HAVE_SYS_SUNDDI_H
+#include <sys/sunddi.h>
+#endif
+#if DK3_HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+#if DK3_HAVE_SYS_SYSTEMINFO_H
+#include <sys/systeminfo.h>
+#endif
+#if DK3_HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if DK3_TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else
+#if DK3_HAVE_TIME_H
+#include <time.h>
+#else
+#if DK3_HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#endif
+#endif
+#if DK3_HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#if DK3_HAVE_ALLOC_H
+#include <alloc.h>
+#endif
+#if DK3_HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+#if DK3_HAVE_CTYPE_H
+#include <ctype.h>
+#endif
+#if DK3_HAVE_STRING_H
+#include <string.h>
+#endif
+#if DK3_HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#if DK3_HAVE_WCHAR_H
+#include <wchar.h>
+#endif
+#if DK3_HAVE_STROPTS_H
+#include <stropts.h>
+#endif
+#if DK3_HAVE_IO_H
+#include <io.h>
+#endif
+#if DK3_HAVE_DOS_H
+#include <dos.h>
+#endif
+#if DK3_HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#if DK3_HAVE_DIR_H
+#include <dir.h>
+#endif
+#if DK3_HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+#if DK3_HAVE_DIRECT_H
+#include <direct.h>
+#endif
+#if DK3_HAVE_SYSRES_H
+#include <sysres.h>
+#endif
+#if DK3_HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#if DK3_HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#if DK3_HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if DK3_HAVE_GRP_H
+#include <grp.h>
+#endif
+#if DK3_HAVE_PWD_H
+#include <pwd.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+#if DK3_HAVE_SYSLOG_H
+#include <syslog.h>
+#endif
+#if DK3_HAVE_CONIO_H
+#include <conio.h>
+#endif
+#if DK3_HAVE_STDARG_H
+#include <stdarg.h>
+#else
+#if DK3_HAVE_VARARG_H
+#include <vararg.h>
+#else
+#if DK3_HAVE_VARARGS_H
+#include <varargs.h>
+#else
+#endif
+#endif
+#endif
+#if DK3_HAVE_VARARG_H
+#include <vararg.h>
+#endif
+#if DK3_HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_TERMIOS_H
+#include <termios.h>
+#endif
+#if DK3_HAVE_SHADOW_H
+#include <shadow.h>
+#endif
+#if DK3_HAVE_LOCALE_H
+#include <locale.h>
+#endif
+#if DK3_HAVE_SYS_TERMIOS_H
+#include <sys/termios.h>
+#endif
+#if DK3_HAVE_SYS_TTOLD_H
+#include <sys/ttold.h>
+#endif
+#if DK3_HAVE_SETJMP_H
+#include <setjmp.h>
+#endif
+#if DK3_HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
+#if DK3_HAVE_ZLIB_H
+#include <zlib.h>
+#endif
+#if DK3_HAVE_BZLIB_H
+#include <bzlib.h>
+#endif
+
+#include <dk3types.h>
+#include <dk3const.h>
+#include <dk3inst.h>
+#include <dk3mem.h>
+#include <dk3bits.h>
+#include <dk3ct.h>
+#include <dk3ma.h>
+#include <dk3dir.h>
+#include <dk3str.h>
+#include <dk3signl.h>
+#include <dk3sf.h>
+#include <dk3sto.h>
+#include <dk3chks.h>
+#include <dk3enc.h>
+#include <dk3strm.h>
+#include <dk3of.h>
+#include <dk3app.h>
+#include <dk3wreg.h>
+#include <dk3srch.h>
+#include <dk3paper.h>
+#include <dk3bf.h>
+#include <dk3uc2l.h>
+#include <dk3opt.h>
+#include <dk3dbi.h>
+#include <dk3ufi.h>
+#include <dk3range.h>
+#include <dk3numco.h>
+
+#endif
+/* ifndef DK3_ALL_H_INCLUDED */
+
diff --git a/support/dktools/dk3app.c b/support/dktools/dk3app.c
new file mode 100644
index 0000000000..df9806462a
--- /dev/null
+++ b/support/dktools/dk3app.c
@@ -0,0 +1,6979 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3app.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3app.c The dk3app module.
+*/
+
+
+#line 701 "dk3app.ctr"
+
+#include "dk3all.h"
+
+#if DK3_HAVE_OPENSSL_RAND_H
+#include <openssl/rand.h>
+#endif
+
+
+
+
+
+#line 710 "dk3app.ctr"
+
+
+
+/** Names of preference scope attributes.
+*/
+static dkChar const * const dk3app_scope_attributes[] = {
+/* 0 */ dkT("user"),
+/* 1 */ dkT("application"),
+/* 2 */ dkT("application-group"),
+/* 3 */ dkT("host"),
+/* 4 */ dkT("language"),
+/* 5 */ dkT("region"),
+NULL
+};
+
+
+
+/** Text strings, not localized.
+*/
+static dkChar const * const dk3app_no_loc[] = {
+/* 0 */ dkT("bin"), /* Used to build bindir. */
+/* 1 */ dkT("etc"), /* Used to build etcdir. */
+/* 2 */ dkT("share"), /* Used to build sharedir. */
+/* 3 */ dkT("var"), /* Used to build vardir. */
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+/* 4 */ dkT("\\log"), /* Used to build log directory. */
+#else
+/* 4 */ dkT("/log"), /* Used to build log directory. */
+#endif
+/* 5 */ dkT("-"), /* Used to build log file name. */
+/* 6 */ dkT(".log"), /* Used to build log file name. */
+/* 7 */ dkT("/"), /* Used to build log directory. */
+/* 8 */ dkT("a"), /* Open mode for log file. */
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+/* 9 */ dkT("\\tmp"), /* Subdirectory for temporary files. */
+#else
+/* 9 */ dkT("/tmp"), /* Subdirectory for temporary files. */
+#endif
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+/* 10 */ dkT("\\run"), /* Subdirectory for temporary files. */
+#else
+/* 10 */ dkT("/run"), /* Subdirectory for temporary files. */
+#endif
+/* 11 */ dkT("LANG"), /* Environment variable for language. */
+/* 12 */ dkT("Control Panel\\International"), /* Reg key for language. */
+/* 13 */ dkT("LocaleName"), /* Reg entry name for language. */
+/* 14 */ dkT("sLanguage"), /* Alternative reg entry name for language. */
+/* 15 */ dkT("utf8"), /* Encoding UTF-8 (modern variant). */
+/* 16 */ dkT("UTF-8"), /* Encoding UTF-8 (older variant). */
+/* 17 */ dkT("dk3app"), /* Subdirectory in system configuration. */
+/* 18 */ dkT(".dk3app"), /* Subdirectory in home directory. */
+/* 19 */ dkT("."), /* Current directory. */
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+/* 20 */ dkT("\\"), /* File name separator. */
+#else
+/* 20 */ dkT("/"), /* File name separator. */
+#endif
+/* 21 */ dkT("dk3pref.conf"), /* Configuration file name. */
+/* 22 */ dkT("r"), /* File open mode for reading. */
+/* 23 */ dkT("dk3app.str"), /* String table name. */
+/* 24 */ dkT("w"), /* File open mode. */
+/* 25 */ dkT("="), /* Used when writing preferences. */
+/* 26 */ dkT("\n"), /* Used when writing preferences. */
+/* 27 */ dkT("/ui/lang"), /* User interface, language. */
+/* 28 */ dkT("/log/file/level"), /* Required log level for file. */
+/* 29 */ dkT("/log/file/keep"), /* Required level to keep file. */
+/* 30 */ dkT("/log/stderr/level"), /* Required log level for stderr. */
+/* 31 */ dkT("/temp/dir/keep"), /* Required to keep temp dir. */
+/* 32 */ dkT("-site"), /* Check for site-specific config files. */
+/* 33 */ dkT("*"), /* Wildcard for all users ... */
+/* 34 */ dkT("dk3conf.conf"), /* Configuration file name. */
+/* 35 */ dkT("%lu"), /* scanf/printf format. */
+/* 36 */ dkT("rb"), /* File open mode: Read binary. */
+/* 37 */ dkT("/rand/types"), /* Preference name for allowed PRNG types. */
+/* 38 */ dkT(".rnd-simple"), /* Preference name for simple seed file. */
+/* 39 */ dkT(".rnd-lrand48"), /* Preference name for lrand48() seed file. */
+/* 40 */ dkT(".rnd-random"), /* Preference name for random() seed file. */
+/* 41 */ dkT(".rnd-openssl"), /* Preference name for OpenSSL seed file. */
+/* 42 */ dkT("/rand/egd/name"), /* Preference name for EGD socket. */
+/* 43 */ dkT("EGDSOCKET"), /* Environment variable name for EGD socket. */
+/* 44 */ dkT("/dev/urandom"), /* Device name for seed data. */
+/* 45 */ dkT("/dev/random"), /* Device name for seed data. */
+/* 46 */ dkT("/rand/file/allowed"), /* Preference name. */
+/* 47 */ dkT("en"), /* Default language name. */
+#if 0
+/* 48 */ dkT("/dir/uc2lat-t"), /* Preference name for LaTeX encoding. */
+#else
+/* 48 */ dkT("/dir/charmap"), /* Preference name for LaTeX encoding. */
+#endif
+/* 49 */
+#if 0
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+dkT("\\uc2lat-t"),
+#else
+dkT("/uc2lat-t"),
+#endif
+#else
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+dkT("\\dktools\\charmap"), /* Character map subdirectory of share. */
+#else
+dkT("/dktools/charmap"), /* Character map subdirectory of share. */
+#endif
+#endif
+/* 50 */ dkT("/silent"), /* Preference name for silent work. */
+/* 51 */ dkT("/input/encoding/file"), /* Preference name. */
+/* 52 */ dkT("/input/encoding/stdin"), /* Preference name. */
+/* 53 */ dkT("wb"), /* File open mode: Read binary. */
+/* 54 */ dkT(".dir"), /* Suffix for uc2lat *.dir files. */
+/* 55 */ dkT(".lat"), /* Suffix for uc2lat *.lat files. */
+/* 56 */ dkT("sbin"), /* sbin dirctory. */
+};
+
+
+
+/** Directories where binary executable can reside.
+*/
+static dkChar const * const dk3app_bindir_candidates[] = {
+/* 0 */
+dkT("bin"),
+
+/* 1 */
+dkT("sbin"),
+
+/* 2 */
+dkT("lib"),
+
+/* 3 */
+dkT("libexec"),
+
+NULL
+
+
+#line 833 "dk3app.ctr"
+};
+
+
+
+/** Keywords for users configuration files.
+ These keywords can be used in the $HOME/.dk3app/dk3conf.conf file.
+*/
+dkChar const * const dk3app_conf_file[] = {
+/* 0 */ dkT("use-system-config-files"),
+/* 1 */ dkT("ignore-system-config-files"),
+NULL
+};
+
+
+/** Log level names.
+*/
+static dkChar const * const dk3app_log_levels[] = {
+dkT("n$one"),
+dkT("pa$nic"),
+dkT("f$atal"),
+dkT("e$rror"),
+dkT("w$arning"),
+dkT("in$fo"),
+dkT("pr$ogress"),
+dkT("d$ebug"),
+dkT("ig$nore"),
+NULL
+};
+
+#if 0
+static dkChar const * const dk3app_prng_type_names[] = {
+/* 0 */ dkT("openssl"), /* OpenSSL PRNG. */
+/* 1 */ dkT("random"), /* initstate()/setstate()/random() */
+/* 2 */ dkT("rand48"), /* lrand48(). */
+/* 3 */ dkT("simple"), /* srand()/rand(). */
+NULL
+};
+#endif
+
+
+
+/** Text strings, localization needed.
+The texts strings are used as parts of diagnostic messages.
+*/
+static dkChar const * const dk3app_kw[] = {
+/* 0 */
+dkT("\n"),
+
+/* 1 */
+dkT("PANIC"),
+
+/* 2 */
+dkT("FATAL"),
+
+/* 3 */
+dkT("ERROR"),
+
+/* 4 */
+dkT("Warning"),
+
+/* 5 */
+dkT("Information"),
+
+/* 6 */
+dkT("Progress"),
+
+/* 7 */
+dkT("Debug"),
+
+/* 8 */
+dkT(" "),
+
+/* 9 */
+dkT("Not enough memory (RAM/swap space)!"),
+
+/* 10 */
+dkT("# "),
+
+/* 11 */
+dkT(":"),
+
+/* 12 */
+dkT("Memory allocation ("),
+
+/* 13 */
+dkT(" bytes) failed!"),
+
+/* 14 */
+dkT("Memory allocation failed!"),
+
+/* 15 */
+dkT("Numeric overflow in size calculation!"),
+
+/* 16 */
+dkT("Numeric overflow in size calculation ("),
+
+/* 17 */
+dkT(" x "),
+
+/* 18 */
+dkT(" bytes)!"),
+
+/* 19 */
+dkT("Application \""),
+
+/* 20 */
+dkT("\" started."),
+
+/* 21 */
+dkT("Application \""),
+
+/* 22 */
+dkT("\" finished."),
+
+/* 23 */
+dkT("Application name: "),
+
+/* 24 */
+dkT("Application group: "),
+
+/* 25 */
+dkT("Executable file: "),
+
+/* 26 */
+dkT("Directory \"bin\": "),
+
+/* 27 */
+dkT("Directory \"etc\": "),
+
+/* 28 */
+dkT("Directory \"share\": "),
+
+/* 29 */
+dkT("Directory \"var\": "),
+
+/* 30 */
+dkT("Directory \"home\": "),
+
+/* 31 */
+dkT("Directory \"temp\": "),
+
+/* 32 */
+dkT("User: "),
+
+/* 33 */
+dkT("Log file: "),
+
+/* 34 */
+dkT("Language: "),
+
+/* 35 */
+dkT("Region: "),
+
+/* 36 */
+dkT("<unknown>"),
+
+/* 37 */
+dkT("The name of the temporary directory is too long!"),
+
+/* 38 */
+dkT("Destination buffer too small!"),
+
+/* 39 */
+dkT("The LANG environment variable is too long!"),
+
+/* 40 */
+dkT("Failed to find name of executable file!"),
+
+/* 41 */
+dkT("Too few directories in hierarchy!\nExecutable files should not reside in the root directory!"),
+
+/* 42 */
+dkT("File name of executable file too long!"),
+
+/* 43 */
+dkT("Failed to obtain the users login name!"),
+
+/* 44 */
+dkT("Failed to find the users home directory!"),
+
+/* 45 */
+dkT("File name for log file gets too long!"),
+
+/* 46 */
+dkT("Failed to create directory for log file!"),
+
+/* 47 */
+dkT("Failed to convert process ID to text!"),
+
+/* 48 */
+dkT("Failed to find application name!"),
+
+/* 49 */
+dkT("The name of the temporary directory is too long!"),
+
+/* 50 */
+dkT("Failed to find local state (var) directory!"),
+
+/* 51 */
+dkT("Preference name too long!"),
+
+/* 52 */
+dkT("Malformed preference entry on command line!"),
+
+/* 53 */
+dkT("Failed to find current working directory!"),
+
+/* 54 */
+dkT("Too many requests for temporary file names!"),
+
+/* 55 */
+dkT("Internal error (bug): Missing a file or directory name!"),
+
+/* 56 */
+dkT("Failed to save preference entry \""),
+
+/* 57 */
+dkT("\"=\""),
+
+/* 58 */
+dkT("\"!"),
+
+/* 59 */
+dkT("Directory name \""),
+
+/* 60 */
+dkT("\" too long!"),
+
+/* 61 */
+dkT("Failed to obtain information about \""),
+
+/* 62 */
+dkT("\"!\nThe stat() function failed!"),
+
+/* 63 */
+dkT("Failed to read directory \""),
+
+/* 64 */
+dkT("\"!"),
+
+/* 65 */
+dkT("File name \""),
+
+/* 66 */
+dkT("\" too long!"),
+
+/* 67 */
+dkT("Illegal characters in source string, conversion failed!"),
+
+/* 68 */
+dkT("Failed to remove directory!"),
+
+/* 69 */
+dkT("Failed to remove directory \""),
+
+/* 70 */
+dkT("\"!"),
+
+/* 71 */
+dkT("The HOMEDRIVE environment variable is not set!"),
+
+/* 72 */
+dkT("The HOMEPATH environment variable is not set!"),
+
+/* 73 */
+dkT("Failed to obtain information about a file!"),
+
+/* 74 */
+dkT("\""),
+
+/* 75 */
+dkT("\" is a directory!"),
+
+/* 76 */
+dkT("Can not open file, name refers to a directory!"),
+
+/* 77 */
+dkT("Failed to open file \""),
+
+/* 78 */
+dkT("\" for write access!"),
+
+/* 79 */
+dkT("Failed to open file for write access!"),
+
+/* 80 */
+dkT("Failed to obtain current time!"),
+
+/* 81 */
+dkT("File \""),
+
+/* 82 */
+dkT("\" exists but is not a directory!"),
+
+/* 83 */
+dkT("File exists but is not a directory!"),
+
+/* 84 */
+dkT("Failed to create directory \""),
+
+/* 85 */
+dkT("\"!"),
+
+/* 86 */
+dkT("Failed to create directory!"),
+
+/* 87 */
+dkT("Directory name too long!"),
+
+/* 88 */
+dkT("Failed to remove file \""),
+
+/* 89 */
+dkT("\"!"),
+
+/* 90 */
+dkT("Failed to remove file!"),
+
+/* 91 */
+dkT("No user name entry in user record!"),
+
+/* 92 */
+dkT("No user record for \""),
+
+/* 93 */
+dkT("\"!"),
+
+/* 94 */
+dkT("No matching user record found!"),
+
+/* 95 */
+dkT("No home directory entry in user record!"),
+
+/* 96 */
+dkT("Failed to obtain information about \""),
+
+/* 97 */
+dkT("\"!\nThe lstat() function failed!"),
+
+/* 98 */
+dkT("No information about a file, lstat() failed!"),
+
+/* 99 */
+dkT("No information about a file, lstat() failed!"),
+
+/* 100 */
+dkT("Owner of symlink \""),
+
+/* 101 */
+dkT("\" is not owner of file!"),
+
+/* 102 */
+dkT("Symlink owner is not file owner!"),
+
+/* 103 */
+dkT("Command \""),
+
+/* 104 */
+dkT("\" is too long!"),
+
+/* 105 */
+dkT("Command is too long!"),
+
+/* 106 */
+dkT("The PATH environment variable is not defined!"),
+
+/* 107 */
+dkT("No mkdir() function available!"),
+
+/* 108 */
+dkT("String too long!"),
+
+/* 109 */
+dkT("Command name too long!"),
+
+/* 110 */
+dkT("Too many \"..\" entries in file name \""),
+
+/* 111 */
+dkT("\"!"),
+
+/* 112 */
+dkT("Illegal character(s) in source string!"),
+
+/* 113 */
+dkT("Illegal character(s) in source buffer!"),
+
+/* 114 */
+dkT("Illegal destination encoding!"),
+
+/* 115 */
+dkT("Conversion to UTF-8 failed!"),
+
+/* 116 */
+dkT("Conversion to UTF-16 failed!"),
+
+/* 117 */
+dkT("Result character(s) not available for destination encoding!"),
+
+/* 118 */
+dkT("UTF-8 decoding failed!"),
+
+/* 119 */
+dkT("UTF-16 decoding failed!"),
+
+/* 120 */
+dkT("Failed to write data!"),
+
+/* 121 */
+dkT("Failed to flush output!"),
+
+/* 122 */
+dkT("Failed to close data stream object!"),
+
+/* 123 */
+dkT("Stream not opened for write operations!"),
+
+/* 124 */
+dkT("Failed to read data!"),
+
+/* 125 */
+dkT("Mismatch between encoding and character size!"),
+
+/* 126 */
+dkT("Too many \"..\" entries in file name!"),
+
+/* 127 */
+dkT("Unknown message digest type: \""),
+
+/* 128 */
+dkT("\"!"),
+
+/* 129 */
+dkT("Unknown encoding: \""),
+
+/* 130 */
+dkT("\"!"),
+
+/* 131 */
+dkT("Failed to find current host name!"),
+
+/* 132 */
+dkT("Host: "),
+
+/* 133 */
+dkT("Option \""),
+
+/* 134 */
+dkT("\" requires an argument!"),
+
+/* 135 */
+dkT("Option \""),
+
+/* 136 */
+dkT("\" too long for processing"),
+
+/* 137 */
+dkT("Ignoring irrelevant argument in \""),
+
+/* 138 */
+dkT("\"!"),
+
+/* 139 */
+dkT("Unknown option \""),
+
+/* 140 */
+dkT("\"!"),
+
+/* 141 */
+dkT("Not a numeric value: \""),
+
+/* 142 */
+dkT("\"!"),
+
+/* 143 */
+dkT("Failed to open file \""),
+
+/* 144 */
+dkT("\"!"),
+
+/* 145 */
+dkT("Failed to open file!"),
+
+/* 146 */
+dkT("Not a boolean value: \""),
+
+/* 147 */
+dkT("\"!"),
+
+/* 148 */
+dkT("Resource file \""),
+
+/* 149 */
+dkT("\" found."),
+
+/* 150 */
+dkT("Resource file \""),
+
+/* 151 */
+dkT("\" not found."),
+
+/* 152 */
+dkT("Configuration file \""),
+
+/* 153 */
+dkT("\" found."),
+
+/* 154 */
+dkT("Configuration file \""),
+
+/* 155 */
+dkT("\" not found."),
+
+/* 156 */
+dkT("No support for message digest \""),
+
+/* 157 */
+dkT("\"!"),
+
+/* 158 */
+dkT("Illegal message digest or encoding number!"),
+
+/* 159 */
+dkT("Checksumming is available for regular files only!"),
+
+/* 160 */
+dkT("Option name missing in long option: \""),
+
+/* 161 */
+dkT("\"!"),
+
+/* 162 */
+dkT("Failed to convert a numeric value to text!"),
+
+/* 163 */
+dkT("\"!"),
+
+/* 164 */
+dkT("Too many command line arguments! Ignoring \""),
+
+/* 165 */
+dkT("\"...!"),
+
+/* 166 */
+dkT("Internal error (bug) "),
+
+/* 167 */
+dkT("."),
+
+/* 168 */
+dkT("Too many file names match pattern \""),
+
+/* 169 */
+dkT("\", just one allowed!"),
+
+/* 170 */
+dkT("Write operation failed, "),
+
+/* 171 */
+dkT(" of "),
+
+/* 172 */
+dkT(" bytes written!"),
+
+/* 173 */
+dkT("Write operation failed!"),
+
+/* 174 */
+dkT("Write operation failed, "),
+
+/* 175 */
+dkT(" of "),
+
+/* 176 */
+dkT(" elements written!"),
+
+/* 177 */
+dkT("Failed to create random data!"),
+
+/* 178 */
+dkT("No usable PRNG found!"),
+
+/* 179 */
+dkT("Failed to seed simple PRNG!"),
+
+/* 180 */
+dkT("Failed to seed lrand48() PRNG!"),
+
+/* 181 */
+dkT("Failed to seed random() PRNG!"),
+
+/* 182 */
+dkT("Failed to seed OpenSSL PRNG!"),
+
+/* 183 */
+dkT("Seed file \""),
+
+/* 184 */
+dkT("\" not used (permissions)!"),
+
+/* 185 */
+dkT("Seed file \""),
+
+/* 186 */
+dkT("\" not used (symlink owner)!"),
+
+/* 187 */
+dkT("Unknown PRNG type: \""),
+
+/* 188 */
+dkT("\"!"),
+
+/* 189 */
+dkT("The srand()/rand() PRNG is not available!"),
+
+/* 190 */
+dkT("The srand48()/lrand48() PRNG is not available!"),
+
+/* 191 */
+dkT("The random() PRNG is not available!"),
+
+/* 192 */
+dkT("The OpenSSL PRNG is not available!"),
+
+/* 193 */
+dkT("Failed to save random seed data!"),
+
+/* 194 */
+dkT("HOME directory name too long!"),
+
+/* 195 */
+dkT("System configuration files skipped by user."),
+
+/* 196 */
+dkT("Attempt to obtain seed data from \""),
+
+/* 197 */
+dkT("\"."),
+
+/* 198 */
+dkT("Seed data: "),
+
+/* 199 */
+dkT(" bytes found."),
+
+/* 200 */
+dkT("Index out of range!"),
+
+/* 201 */
+dkT("Matrix expansion requires a square matrix!"),
+
+/* 202 */
+dkT("Not a directory: \""),
+
+/* 203 */
+dkT("\"!"),
+
+/* 204 */
+dkT("Encoding not supported by C runtime library!"),
+
+/* 205 */
+dkT("No directory containing LaTeX encoding tables found!"),
+
+/* 206 */
+dkT("Redefinition,\noverwriting \""),
+
+/* 207 */
+dkT("\" by \""),
+
+/* 208 */
+dkT("\"."),
+
+/* 209 */
+dkT("Syntax error,\nindex "),
+
+/* 210 */
+dkT(" is out of range 0...255."),
+
+/* 211 */
+dkT("Syntax error\nnear \""),
+
+/* 212 */
+dkT("\"!"),
+
+/* 213 */
+dkT("Syntax error,\nmissing LaTeX encoding!"),
+
+/* 214 */
+dkT("Syntax error,\nmissing index!"),
+
+/* 215 */
+dkT("No file name matches pattern \""),
+
+/* 216 */
+dkT("\"!"),
+
+/* 217 */
+dkT("Missing name of long option!"),
+
+/* 218 */
+dkT("Incomplete input sequence."),
+
+/* 219 */
+dkT("String contains non-ISO-LATIN-1 characters!"),
+
+/* 220 */
+dkT("Misconfigured start/end for range!"),
+
+/* 221 */
+dkT("New range conflicts with existing one!"),
+
+/* 222 */
+dkT("Not a hex number!"),
+
+/* 223 */
+dkT("Syntax error!"),
+
+/* 224 */
+dkT("Character redefinition!"),
+
+/* 225 */
+dkT("Range not declared in character directory!"),
+
+/* 226 */
+dkT("Package name conflicts with previous definition!"),
+
+/* 227 */
+dkT("Attempt to obtain seed data from CryptoAPI."),
+
+/* 228 */
+dkT("Attempt to obtain seed data from screen."),
+
+/* 229 */
+dkT("OpenSSL PRNG seeded successfully."),
+
+/* 230 */
+dkT("Attempt to read preferences file \""),
+
+/* 231 */
+dkT("\"."),
+
+/* 232 */
+dkT("LaTeX table directory: \""),
+
+/* 233 */
+dkT("\"."),
+
+/* 234 */
+dkT("Attempting LaTeX table directory: \""),
+
+/* 235 */
+dkT("\"."),
+
+/* 236 */
+dkT("Reading LaTeX table dir: \""),
+
+/* 237 */
+dkT("\"."),
+
+/* 238 */
+dkT("Registering LaTeX conversion range "),
+
+/* 239 */
+dkT("."),
+
+/* 240 */
+dkT("Loading LaTeX conversion data file \""),
+
+/* 241 */
+dkT("\"."),
+
+/* 242 */
+dkT("Failed to change into directory: \""),
+
+/* 243 */
+dkT("\"!"),
+
+/* 244 */
+dkT("Failed to enumerate printers!"),
+
+/* 245 */
+dkT("Record too large!"),
+
+/* 246 */
+dkT("File damaged or not a database file!"),
+
+/* 247 */
+dkT("No support for database type \""),
+
+/* 248 */
+dkT("\" available!"),
+
+/* 249 */
+dkT("Key not found in database!"),
+
+/* 250 */
+dkT("DB entry probably damaged - not a multibyte char string!"),
+
+/* 251 */
+dkT("Database opened for read access only!"),
+
+/* 252 */
+dkT("Error(s) occured while processing command line options!"),
+
+/* 253 */
+dkT("Failed to retrieve current locale!"),
+
+/* 254 */
+dkT("Current locale too long!"),
+
+/* 255 */
+dkT("Not a regular file: \""),
+
+/* 256 */
+dkT("\"!"),
+
+/* 257 */
+dkT("Image file type unknown or not supported!"),
+
+/* 258 */
+dkT("Bits per component restricted to 16!"),
+
+/* 259 */
+dkT("Incorrect page setup, no usable space between borders!"),
+
+/* 260 */
+dkT("Mathematical error in graphics calculations!"),
+
+/* 261 */
+dkT("Failed to set bitmap image frame!"),
+
+/* 262 */
+dkT("Flate compression not supported!"),
+
+/* 263 */
+dkT("Illegal compression cell type used!"),
+
+/* 264 */
+dkT("Error during previous compression operations!"),
+
+/* 265 */
+dkT("Failed to retrieve console settings!"),
+
+/* 266 */
+dkT("Failed to restore console settings!"),
+
+/* 267 */
+dkT("Failed to modify console settings!"),
+
+/* 268 */
+dkT("Failed to convert timestamp to local time!"),
+
+/* 269 */
+dkT("No file name available for database!"),
+
+/* 270 */
+dkT("Failed to change ownership for file:\n\""),
+
+/* 271 */
+dkT("\"!"),
+
+/* 272 */
+dkT("Failed to change permissions for file:\n\""),
+
+/* 273 */
+dkT("\"!"),
+
+/* 274 */
+dkT("Insufficient permissions to open network connection!"),
+
+/* 275 */
+dkT("Unknown or illegal address family!"),
+
+/* 276 */
+dkT("Process table overflow!"),
+
+/* 277 */
+dkT("Too many open files!"),
+
+/* 278 */
+dkT("Protocol not supported!"),
+
+/* 279 */
+dkT("Failed to open network socket!"),
+
+/* 280 */
+dkT("Failed to close socket!"),
+
+/* 281 */
+dkT("Interrupted by signal or explicitly cancelled!"),
+
+/* 282 */
+dkT("Failed to connect!"),
+
+/* 283 */
+dkT("Failed to listen for incoming requests!"),
+
+/* 284 */
+dkT("Failed to find IP address for:\n\""),
+
+/* 285 */
+dkT("\"!"),
+
+/* 286 */
+dkT("Host not found!"),
+
+/* 287 */
+dkT("Host exists, but no IP address assigned!"),
+
+/* 288 */
+dkT("Problem on DNS server!"),
+
+/* 289 */
+dkT("Temporary problem on DNS server, try again later!"),
+
+/* 290 */
+dkT("No gethostbyname() function available!"),
+
+/* 291 */
+dkT("Can not connect to remote port 0!"),
+
+/* 292 */
+dkT("Access denied by firewall or due to insufficient permissions!"),
+
+/* 293 */
+dkT("Local address already in use!"),
+
+/* 294 */
+dkT("Resources shortage, network operation failed!"),
+
+/* 295 */
+dkT("Previous connection attempt not yet completed!"),
+
+/* 296 */
+dkT("Connection refused, port not open on peer!"),
+
+/* 297 */
+dkT("Socket already connected!"),
+
+/* 298 */
+dkT("Network unreachable!"),
+
+/* 299 */
+dkT("Timeout occured."),
+
+/* 300 */
+dkT("No select() function available, timeout settings ignored!"),
+
+/* 301 */
+dkT("Failed to retrieve socket state!"),
+
+/* 302 */
+dkT("Failed to bind local address!"),
+
+/* 303 */
+dkT(""),
+
+/* 304 */
+dkT("Socket already bound to local address!"),
+
+/* 305 */
+dkT("Failed to write data to socket!"),
+
+/* 306 */
+dkT("Operation would block!"),
+
+/* 307 */
+dkT("Connection reset by peer!"),
+
+/* 308 */
+dkT("Peer address is required to send data via connectionless socket!"),
+
+/* 309 */
+dkT("Peer address specification is not allowed for connected sockets!"),
+
+/* 310 */
+dkT("Message too large to be sent atomically!"),
+
+/* 311 */
+dkT("Sending queue full for socket!"),
+
+/* 312 */
+dkT("Writing to a pipe without a reader!"),
+
+/* 313 */
+dkT("Less bytes were written than required!"),
+
+/* 314 */
+dkT("Failed to read data from socket!"),
+
+/* 315 */
+dkT("Failed to shut down socket!"),
+
+/* 316 */
+dkT("Socket not connected!"),
+
+/* 317 */
+dkT("Failed to accept incoming connection request!"),
+
+/* 318 */
+dkT("Connection aborted!"),
+
+/* 319 */
+dkT("Network protocol error!"),
+
+/* 320 */
+dkT("Network subsystem not available!"),
+
+/* 321 */
+dkT("Windows sockets not initialized!"),
+
+/* 322 */
+dkT("A blocking Winsock 1.1 operation is in progress!"),
+
+/* 323 */
+dkT("Socket type doesn't correspond to address family!"),
+
+/* 324 */
+dkT("Socket not configured for broadcasts!"),
+
+/* 325 */
+dkT("Requested address is not available!"),
+
+/* 326 */
+dkT("Host unreachable!"),
+
+/* 327 */
+dkT("Windows sockets version not available!"),
+
+/* 328 */
+dkT("Too many processes use Windows sockets at this time!"),
+
+/* 329 */
+dkT("I/O error occured!"),
+
+/* 330 */
+dkT("Too many symbolic links in path!"),
+
+/* 331 */
+dkT("Illegal pathname (missing a parent directory)!"),
+
+/* 332 */
+dkT("File system is mounted read-only!"),
+
+/* 333 */
+dkT("Stale NFS file handle!"),
+
+/* 334 */
+dkT("Server for remote file not available!"),
+
+/* 335 */
+dkT("No space left on device!"),
+
+/* 336 */
+dkT("Failed to wait for sockets to become ready!"),
+
+/* 337 */
+dkT("Failed to convert text address to address!"),
+
+/* 338 */
+dkT("Failed to find address for host!"),
+
+/* 339 */
+dkT("Failed to set socket options!"),
+
+/* 340 */
+dkT("Error while closing file!"),
+
+/* 341 */
+dkT("Error while closing file\n\""),
+
+/* 342 */
+dkT("\"!"),
+
+/* 343 */
+dkT("Failed to write data to file:\n\""),
+
+/* 344 */
+dkT("\"!"),
+
+/* 345 */
+dkT("Failed to read data from file!"),
+
+/* 346 */
+dkT("Failed to read data from file:\n\""),
+
+/* 347 */
+dkT("\"!"),
+
+/* 348 */
+dkT("Not an IP address: \""),
+
+/* 349 */
+dkT("\"!"),
+
+/* 350 */
+dkT("Not an IP address!"),
+
+/* 351 */
+dkT("Failed to connect to: \""),
+
+/* 352 */
+dkT("\"!"),
+
+/* 353 */
+dkT("No function available to check blocking/non-blocking state!"),
+
+/* 354 */
+dkT("Netmask is not a dotted IP address!"),
+
+/* 355 */
+dkT("Netmask is not a bit number!"),
+
+/* 356 */
+dkT("Netmask is not an IPv6 address!"),
+
+/* 357 */
+dkT("No name resolution available, please specify IP address!"),
+
+/* 358 */
+dkT("No select() function available!"),
+
+/* 359 */
+dkT("No valid socket found in set!"),
+
+/* 360 */
+dkT("Socket "),
+
+/* 361 */
+dkT(" connected to client: "),
+
+/* 362 */
+dkT("Connection from \""),
+
+/* 363 */
+dkT("\" rejected!"),
+
+/* 364 */
+dkT("Failed to create any listener socket for socket set!"),
+
+/* 365 */
+dkT("Preference value of /threads/max higher than number of cores!"),
+
+/* 366 */
+dkT("Failed to find unique file identifier for file\n\""),
+
+/* 367 */
+dkT("\"!"),
+
+/* 368 */
+dkT("Failed to find unique file identifier for a file!"),
+
+/* 369 */
+dkT("Preference \""),
+
+/* 370 */
+dkT("\" does not point to a directory!"),
+
+/* 371 */
+dkT(""),
+
+/* 372 */
+dkT("Socket "),
+
+/* 373 */
+dkT(" listening: "),
+
+/* 374 */
+dkT(""),
+
+/* 375 */
+dkT("Socket "),
+
+/* 376 */
+dkT(" connected:"),
+
+/* 377 */
+dkT(""),
+
+/* 378 */
+dkT("Multiple different font encodings required!"),
+
+/* 379 */
+dkT("Font encoding both required and denied: `"),
+
+/* 380 */
+dkT("'!"),
+
+/* 381 */
+dkT("Font encoding can be used: `"),
+
+/* 382 */
+dkT("'!"),
+
+/* 383 */
+dkT("The following font encoding can not be used: `"),
+
+/* 384 */
+dkT("'."),
+
+/* 385 */
+dkT("All font encodings denied!"),
+
+/* 386 */
+dkT("Too many entries on position "),
+
+/* 387 */
+dkT(" in text line:\n\""),
+
+/* 388 */
+dkT("\""),
+
+/* 389 */
+dkT("Unexpected end of text after backslash in text:\n\""),
+
+/* 390 */
+dkT("\""),
+
+/* 391 */
+dkT("UTF-8 decoding failed for string:\n\""),
+
+/* 392 */
+dkT("UTF-16 decoding failed for string:\n\""),
+
+/* 393 */
+dkT("Non-ANSI characters in string:\n\""),
+
+/* 394 */
+dkT("Non-URL characters in string:\n\""),
+
+/* 395 */
+dkT("Character 0x"),
+
+/* 396 */
+dkT("already defined!"),
+
+/* 397 */
+dkT("Character redefinition!"),
+
+/* 398 */
+dkT("First word is not a hexadecimal number!"),
+
+/* 399 */
+dkT("_UNUSED_"),
+
+/* 400 */
+dkT("No configuration data found for character!"),
+
+/* 401 */
+dkT("No support for zlib compression!"),
+
+/* 402 */
+dkT("No support for bzip2 compression!"),
+
+/* 403 */
+dkT("No data files found to process!"),
+
+/* 404 */
+dkT("Syntax error, unknown encoding!"),
+
+/* 405 */
+dkT("Syntax error, no package names found!"),
+
+/* 406 */
+dkT("Syntax error, missing value for attribute!"),
+
+/* 407 */
+dkT("Missing \"share\" directory!"),
+
+/* 408 */
+dkT("No data found for character!"),
+
+/* 409 */
+dkT("No data found for character 0x"),
+
+/* 410 */
+dkT("!"),
+
+/* 411 */
+dkT("Conflicting font encoding requirements!"),
+
+/* 412 */
+dkT("Failed to set buffer for file\n\""),
+
+/* 413 */
+dkT("\"!"),
+
+NULL
+
+
+#line 2444 "dk3app.ctr"
+};
+
+
+
+/** Preferences entry.
+*/
+typedef struct _dk3app_pref_t {
+ dkChar const *k; /**< Key (name). */
+ dkChar const *v; /**< Value. */
+} dk3app_pref_t;
+
+
+
+/** Message catalog.
+*/
+typedef struct _dk3app_mc_t_ {
+ dkChar const *n; /**< Name (always dynamically allocated). */
+ dkChar const **msg; /**< Message texts. */
+ int f; /**< Flag: Messages dynamically allocated. */
+ size_t nmsg; /**< Number of messages. */
+} dk3app_mc_t;
+
+
+
+/** Delete preferences entry, release memory.
+ @param p Preference entry to delete.
+*/
+static
+void
+dk3app_pref_delete(dk3app_pref_t *p)
+{
+ if(p) {
+
+#line 2476 "dk3app.ctr"
+ dk3_release(p->k);
+ dk3_release(p->v);
+ dk3_delete(p);
+ }
+}
+
+
+
+/** Create new preferences entry, allocate memory.
+ @param k Key (preference name).
+ @param v Value.
+ @return Pointer to new entry on success, NULL on error.
+*/
+static
+dk3app_pref_t *
+dk3app_pref_new(dkChar const *k, dkChar const *v)
+{
+ dk3app_pref_t *back = NULL;
+
+
+#line 2495 "dk3app.ctr"
+ if((k) && (v)) {
+ back = dk3_new(dk3app_pref_t,1);
+ if(back) {
+ back->k = dk3str_dup_app(k, NULL);
+ back->v = dk3str_dup_app(v, NULL);
+ if(!((back->k) && (back->v))) {
+ dk3app_pref_delete(back); back = NULL;
+ }
+ }
+ }
+
+#line 2505 "dk3app.ctr"
+ return back;
+}
+
+
+
+/** Compare two preference entries by name.
+ @param l Left entry.
+ @param r Right entry.
+ @param crit Comparison criteria (ignored).
+ @return Comparison result l <=> r.
+*/
+static
+int
+dk3app_compare_pref(void const *l, void const *r, int crit)
+{
+ int back = 0;
+ dk3app_pref_t const *pl = NULL; /* Left object. */
+ dk3app_pref_t const *pr = NULL; /* Right object. */
+ if(l) {
+ if(r) {
+ pl = (dk3app_pref_t const *)l; pr = (dk3app_pref_t const *)r;
+ if(pl->k) {
+ if(pr->k) {
+ back = dk3str_cmp(pl->k, pr->k);
+ } else { back = 1; }
+ } else {
+ if(pr->k) { back = -1; }
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+/** Delete string table.
+ @param ta Table to delete.
+ @param n Number of entries in the table.
+*/
+static
+void
+dk3app_mc_table_delete(dkChar const **ta, size_t n)
+{
+ dkChar const **ptr = NULL; /* Start of string table. */
+ size_t i = 0; /* Index of current element to process. */
+
+
+#line 2553 "dk3app.ctr"
+ ptr = ta;
+ for(i = 0; i < n; i++) {
+
+#line 2555 "dk3app.ctr"
+ if(*ptr) {
+
+#line 2556 "dk3app.ctr"
+ dk3_delete(*ptr);
+ }
+ *(ptr++) = NULL;
+ }
+ dk3_delete(ta);
+
+#line 2561 "dk3app.ctr"
+}
+
+
+
+/** Delete message catalog entry.
+ @param mc Message catalog entry to delete.
+*/
+static
+void
+dk3app_mc_delete(dk3app_mc_t *mc)
+{
+
+
+#line 2573 "dk3app.ctr"
+ if(mc) {
+
+#line 2574 "dk3app.ctr"
+ dk3_release(mc->n);
+ if(mc->f) {
+ if(mc->msg) {
+ dk3app_mc_table_delete(mc->msg, mc->nmsg);
+ }
+ } mc->f = 0; mc->msg = NULL;
+ dk3_delete(mc);
+ }
+
+#line 2582 "dk3app.ctr"
+}
+
+
+
+/** Create message catalog entry.
+ @param n Short file name of string table file.
+ @param msg String table.
+ @param nmsg Number of entries in \a msg.
+ @param f Flag: The memory for \a msg was dynamically allocated.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to message catalog entry on success, NULL on error.
+*/
+static
+dk3app_mc_t *
+dk3app_mc_new(
+ dkChar const *n, dkChar const **msg, size_t nmsg, int f, dk3_app_t *app
+)
+{
+ dk3app_mc_t *back = NULL;
+
+
+#line 2602 "dk3app.ctr"
+ back = dk3_new_app(dk3app_mc_t,1,app);
+ if(back) {
+ back->n = NULL; back->msg = NULL; back->f = f; back->nmsg = nmsg;
+ back->n = dk3str_dup_app(n, app);
+ if(back->n) {
+ back->msg = msg;
+ } else {
+ dk3app_mc_delete(back); back = NULL;
+ }
+ }
+
+#line 2612 "dk3app.ctr"
+ return back;
+}
+
+
+
+/** Compare two message catalog entries.
+ @param l Left entry.
+ @param r Right entry.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+static
+int
+dk3app_mc_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3app_mc_t const *pl = NULL; /* Left message catalog. */
+ dk3app_mc_t const *pr = NULL; /* Right message catalog. */
+ if(l) {
+ if(r) {
+ pl = (dk3app_mc_t const *)l; pr = (dk3app_mc_t const *)r;
+ if(pl->n) {
+ if(pr->n) {
+ back = dk3str_cmp(pl->n, pr->n);
+ } else { back = 1; }
+ } else {
+ if(pr->n) { back = -1; }
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+/** Write log message to a file.
+ If the time has changed since the last message written to that
+ file we write a new timestamp before writing the message.
+ @param app Application structure.
+ @param ll Log level, DK3_LL_xxx.
+ @param msg Array of message parts.
+ @param nmsg Number of elements in \a msg.
+ @param fipo File to write to.
+ @param last_time Timestamp of last message written to that file.
+*/
+static
+void
+dk3app_log_to_file(
+ dk3_app_t *app, int ll, dkChar const * const * msg, size_t nmsg,
+ FILE *fipo, dk3_time_t *last_time
+)
+{
+ dk3_time_t time_now; /* Current time. */
+ dkChar tb[64]; /* Buffer to store current time as text. */
+ char ulb[64]; /* Buffer for current time as char text. */
+ char *sp = NULL; /* Source pointer used in conversion. */
+ size_t i = 0; /* Index of current string to process. */
+
+
+#line 2672 "dk3app.ctr"
+ if(dk3sf_time(&time_now)) {
+ if(time_now != *last_time) {
+ if(dk3sf_time_convert_app(tb, DK3_SIZEOF(tb,dkChar), &time_now, NULL)) {
+ *last_time = time_now;
+ dk3sf_fputs(((app->msg) ? app->msg : dk3app_kw)[10], fipo);
+ dk3sf_fputs(tb, fipo);
+ dk3sf_fputs(((app->msg) ? app->msg : dk3app_kw)[0], fipo);
+ }
+ }
+ }
+ if(app->n_sourcefile) {
+ dk3sf_fputs(app->n_sourcefile, fipo);
+ dk3sf_fputs(((app->msg) ? app->msg : dk3app_kw)[11], fipo);
+ if(app->sourceline) {
+ sprintf(ulb, "%lu", app->sourceline);
+ sp = ulb;
+ while(*sp) { dk3sf_fputc( (dkChar)(*(sp++)), fipo); }
+ dk3sf_fputs(((app->msg) ? app->msg : dk3app_kw)[11], fipo);
+ }
+ dk3sf_fputs(((app->msg) ? app->msg : dk3app_kw)[8], fipo);
+ }
+ if((ll >= DK3_LL_PANIC) && (ll <= DK3_LL_WARNING)) {
+ dk3sf_fputs(((app->msg) ? app->msg : dk3app_kw)[ll], fipo);
+ dk3sf_fputs(((app->msg) ? app->msg : dk3app_kw)[11], fipo);
+ dk3sf_fputs(((app->msg) ? app->msg : dk3app_kw)[8], fipo);
+ }
+ for(i = 0; i < nmsg; i++) {
+ if(msg[i]) {
+ dk3sf_fputs(msg[i], fipo);
+ }
+ }
+ dk3sf_fputs(((app->msg) ? app->msg : dk3app_kw)[0], fipo);
+
+#line 2704 "dk3app.ctr"
+}
+
+
+
+static
+void
+dk3app_create_parent_directory(const dkChar *fn)
+{
+ dkChar fnb[DK3_MAX_PATH];
+ dkChar *ptr;
+ dkChar *lptr;
+
+ if (dk3str_len(fn) < DK3_SIZEOF(fnb,dkChar)) {
+ dk3str_cpy_not_overlapped(fnb, fn);
+ ptr= fnb; lptr = NULL;
+ while (dkT('\0') != *ptr) {
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+ if (dkT('\\') == *ptr) { lptr = ptr; }
+#else
+ if (dkT('/') == *ptr) { lptr = ptr; }
+#endif
+ ptr++;
+ }
+ if (NULL != lptr) {
+ *lptr = dkT('\0');
+ (void)dk3sf_mkdir_app(fnb, 0700, NULL);
+ }
+ }
+}
+
+
+
+/** Create ${HOME}/log directory for known log file name.
+ @param app Application structure containing log file
+ name in n_logfilename.
+*/
+static
+void
+dk3app_create_log_directory(dk3_app_t *app)
+{
+ dk3app_create_parent_directory(app->n_logfilename);
+}
+
+
+
+/** Create ${HOME}/tmp directory for known log file name.
+ @param app Application structure containing log file
+ name in n_logfilename.
+*/
+static
+void
+dk3app_create_tmp_directory(dk3_app_t *app)
+{
+ dk3app_create_parent_directory(app->n_tmpdir);
+}
+
+
+
+/** Write log message to log file.
+ If the time has changed since the last message written to that
+ file we write a new timestamp before writing the message.
+ @param app Application structure.
+ @param ll Log level, DK3_LL_xxx.
+ @param msg Array of message parts.
+ @param nmsg Number of elements in \a msg.
+*/
+static
+void
+dk3app_log_file(dk3_app_t *app, int ll, dkChar const * const * msg, size_t nmsg)
+{
+ FILE *fipo; /* Output file. */
+ dk3_stat_t stb; /* File stat buffer. */
+
+
+#line 2777 "dk3app.ctr"
+ if(app->n_logfilename) {
+
+#line 2778 "dk3app.ctr"
+ if (0 == app->cr_log) {
+ /*
+ Create ${HOME}/log directory if not yet done.
+ */
+ dk3app_create_log_directory(app);
+ app->cr_log = 1;
+ }
+ if(app->f_first_file_log) {
+ /*
+ Daemons always attempt to append after existing log.
+ */
+ if(app->app_type == DK3_APP_TYPE_DAEMON) {
+ app->f_first_file_log = 0;
+ if(!dk3sf_stat_app(&stb, app->n_logfilename, NULL)) {
+ app->f_first_file_log = 1;
+ }
+ }
+ }
+ fipo = dk3sf_fopen_app(app->n_logfilename, dk3app_no_loc[8], NULL);
+ /* WRITE */
+ if(fipo) {
+
+#line 2799 "dk3app.ctr"
+#if DK3_ON_WINDOWS && (DK3_CHAR_SIZE > 1)
+ /* Switch to 16 bit characters. */
+ (void)_setmode(_fileno(fipo), _O_U16TEXT);
+ /* Write byte order marker. */
+ if(app->f_first_file_log) {
+ fputwc(0xFEFF, fipo);
+ }
+#endif
+ app->f_first_file_log = 0;
+ dk3app_log_to_file(
+ app, ll, msg, nmsg, fipo, &(app->t_last_log_file)
+ );
+ fclose(fipo);
+ } else {
+
+#line 2813 "dk3app.ctr"
+ }
+ }
+
+#line 2815 "dk3app.ctr"
+}
+
+
+
+int
+dk3app_max_log_level(dk3_app_t const *app)
+{
+ int back = 0;
+ if(app) {
+ if(app->app_type != DK3_APP_TYPE_SILENT) {
+ back = app->ll_file;
+ if(app->app_type == DK3_APP_TYPE_COMMAND) {
+ if(app->ll_stderr > back) {
+ back = app->ll_stderr;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+void
+dk3app_log_msg(dk3_app_t *app, int ll, dkChar const * const * msg, size_t nmsg)
+{
+
+
+#line 2840 "dk3app.ctr"
+ if((app) && (msg) && (nmsg)) {
+
+#line 2841 "dk3app.ctr"
+ if(app->f_readytolog) {
+
+#line 2842 "dk3app.ctr"
+ if(ll < app->ll_highest) {
+
+#line 2843 "dk3app.ctr"
+ app->ll_highest = ll;
+ }
+ switch(app->app_type) {
+ case DK3_APP_TYPE_COMMAND: {
+
+#line 2847 "dk3app.ctr"
+ if(app->ll_file >= ll) {
+
+#line 2848 "dk3app.ctr"
+ dk3app_log_file(app, ll, msg, nmsg);
+ } else {
+
+#line 2850 "dk3app.ctr"
+ }
+ if(app->ll_stderr >= ll) {
+
+#line 2852 "dk3app.ctr"
+ dk3sf_initialize_stderr();
+ dk3app_log_to_file(
+ app, ll, msg, nmsg, stderr, &(app->t_last_log_stderr)
+ );
+ } else {
+
+#line 2857 "dk3app.ctr"
+ }
+ } break;
+ case DK3_APP_TYPE_GUI:
+ case DK3_APP_TYPE_DAEMON:
+
+#line 2861 "dk3app.ctr"
+ {
+
+#line 2862 "dk3app.ctr"
+ if(app->ll_file >= ll) {
+
+#line 2863 "dk3app.ctr"
+ dk3app_log_file(app, ll, msg, nmsg);
+ }
+ } break;
+ }
+ } else {
+
+#line 2868 "dk3app.ctr"
+ }
+ } else {
+
+#line 2870 "dk3app.ctr"
+ }
+
+#line 2871 "dk3app.ctr"
+}
+
+
+
+void
+dk3app_log_1(dk3_app_t *app, int ll, dkChar const * const * msg, size_t i1)
+{
+ dkChar const *m[2]; /* Message parts. */
+
+
+#line 2880 "dk3app.ctr"
+ if((app) && (msg)) {
+ m[0] = msg[i1];
+ m[1] = NULL;
+ dk3app_log_msg(app, ll, (dkChar const * const *)m, 1);
+ }
+
+#line 2885 "dk3app.ctr"
+}
+
+
+
+void
+dk3app_log_2(
+ dk3_app_t *app, int ll, dkChar const * const * msg,
+ size_t i, dkChar const *st
+)
+{
+ dkChar const *m[3];
+ if((app) && (msg)) {
+ m[0] = msg[i];
+ m[1] = st;
+ m[2] = NULL;
+ dk3app_log_msg(app, ll, (dkChar const * const *)m, 2);
+ }
+}
+
+
+void
+dk3app_log_3(
+ dk3_app_t *app, int ll, dkChar const * const * msg,
+ size_t i1, size_t i2, dkChar const *st
+)
+{
+ dkChar const *m[4]; /* Message parts. */
+
+
+#line 2913 "dk3app.ctr"
+ if((app) && (msg)) {
+ m[0] = msg[i1];
+ m[1] = st;
+ m[2] = msg[i2];
+ m[3] = NULL;
+ dk3app_log_msg(app, ll, (dkChar const * const *)m, 3);
+ }
+
+#line 2920 "dk3app.ctr"
+}
+
+
+
+void
+dk3app_log_5(
+ dk3_app_t *app, int ll, dkChar const * const * msg,
+ size_t i1, size_t i2, size_t i3, dkChar const *st1, dkChar const *st2
+)
+{
+ dkChar const *m[6]; /* Message parts. */
+
+
+#line 2932 "dk3app.ctr"
+ if((app) && (msg)) {
+ m[0] = msg[i1];
+ m[1] = st1;
+ m[2] = msg[i2];
+ m[3] = st2;
+ m[4] = msg[i3];
+ m[5] = NULL;
+ dk3app_log_msg(app, ll, (dkChar const * const *)m, 5);
+ }
+
+#line 2941 "dk3app.ctr"
+}
+
+
+
+void
+dk3app_log_i1(dk3_app_t *app, int ll, size_t i1)
+{
+
+
+#line 2949 "dk3app.ctr"
+ if(app) {
+ dk3app_log_1(app, ll, ((app->msg) ? app->msg : dk3app_kw), i1);
+ }
+
+#line 2952 "dk3app.ctr"
+}
+
+
+
+void
+dk3app_log_i2(dk3_app_t *app, int ll, size_t i, dkChar const * st)
+{
+ dkChar const *msg[3]; /* Message parts. */
+
+ if((app) && (i) && (st)) {
+ if(i < DK3_SIZEOF(dk3app_kw,DK3_PCDKCHAR)) {
+ msg[0] = ((app->msg) ? app->msg : dk3app_kw)[i];
+ msg[1] = st;
+ msg[2] = NULL;
+ dk3app_log_msg(app, ll, (dkChar const * const *)msg, 2);
+ }
+ }
+}
+
+
+
+void
+dk3app_log_i3(
+ dk3_app_t *app, int ll,
+ size_t i1, size_t i2, dkChar const *st
+)
+{
+
+
+#line 2980 "dk3app.ctr"
+ if(app) {
+ dk3app_log_3(app, ll, ((app->msg) ? app->msg : dk3app_kw), i1, i2, st);
+ }
+
+#line 2983 "dk3app.ctr"
+}
+
+
+
+void
+dk3app_log_i5(
+ dk3_app_t *app, int ll,
+ size_t i1, size_t i2, size_t i3, dkChar const *st1, dkChar const *st2
+)
+{
+
+
+#line 2994 "dk3app.ctr"
+ if(app) {
+ dk3app_log_5(
+ app, ll, ((app->msg) ? app->msg : dk3app_kw), i1, i2, i3, st1, st2
+ );
+ }
+
+#line 2999 "dk3app.ctr"
+}
+
+
+
+void
+dk3app_set_source_file(dk3_app_t *app, dkChar const *fn)
+{
+ if(app) {
+
+#line 3007 "dk3app.ctr"
+ app->n_sourcefile = fn;
+ }
+}
+
+
+
+void
+dk3app_set_source_line(dk3_app_t *app, unsigned long li)
+{
+ if(app) {
+
+#line 3017 "dk3app.ctr"
+ app->sourceline = li;
+ }
+}
+
+
+
+dkChar const *
+dk3app_get_source_file(dk3_app_t const *app)
+{
+ dkChar const *back = NULL;
+ if(app) {
+ back = app->n_sourcefile;
+ }
+
+#line 3030 "dk3app.ctr"
+ return back;
+}
+
+
+
+unsigned long
+dk3app_get_source_line(dk3_app_t const *app)
+{
+ unsigned long back = 0UL;
+ if(app) {
+ back = app->sourceline;
+ }
+
+#line 3042 "dk3app.ctr"
+ return back;
+}
+
+
+
+/** Find data (resource) file.
+ String tables are resources too, so we check language and
+ region subdirectories too.
+ @param app Application structure.
+ @param fn File name.
+ @param db Destination buffer.
+ @param sz Size of \a db (number of characters).
+ @param verb Flag: Diagnostic messages enabled.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3app_my_find_data_file(
+ dk3_app_t *app, dkChar const *fn, dkChar *db, size_t sz, int verb
+)
+{
+ int back = 0;
+ dkChar const *p1 = NULL; /* dk3app, group or application name. */
+ dkChar const *p2 = NULL; /* Language. */
+ dkChar const *p3 = NULL; /* Region. */
+ int cc = 1; /* Flag: Can go. */
+ size_t mysz = 0; /* Size for calculation. */
+ size_t sz1 = 0; /* Length of /xxx/share directory name. */
+ size_t sz2 = 0; /* Length of short file name. */
+ dk3_stat_t stb; /* Stat buffer to test existance of files. */
+ int i = 0; /* Pass: 0=lang+region, 1=language, 0=share. */
+ int j = 0; /* Pass: 0=app, 1=appgroup, 2=dk3app, 3=base. */
+
+
+#line 3075 "dk3app.ctr"
+ if((app) && (fn) && (db) && (sz)) {
+ if(app->n_sharedir) {
+ sz1 = dk3str_len(app->n_sharedir);
+ sz2 = dk3str_len(fn);
+ for(i = 0; ((back == 0) && (i < 4)); i++) {
+ for(j = 0; ((back == 0) && (j < 4)); j++) {
+
+#line 3081 "dk3app.ctr"
+ p1 = NULL; p2 = NULL; p3 = NULL; cc = 0;
+ switch(i) {
+ case 1: {
+ if(app->n_language) {
+ p2 = app->n_language; cc = 1;
+ }
+ } break;
+ case 2: {
+ p2 = dk3app_no_loc[47]; cc = 1;
+ } break;
+ case 3: {
+ cc = 1;
+ } break;
+ default: {
+ if(app->n_language) {
+ p2 = app->n_language;
+ if(app->n_region) {
+ p3 = app->n_region; cc = 1;
+ }
+ }
+ } break;
+ }
+ switch(j) {
+ case 1: {
+ if(app->n_appgroup) {
+ p1 = app->n_appgroup;
+ } else {
+ cc = 0;
+ }
+ } break;
+ case 2: {
+ p1 = dk3app_no_loc[17];
+ } break;
+ case 3: {
+ p1 = NULL;
+ } break;
+ default: {
+ if(app->n_app) {
+ p1 = app->n_app;
+ } else {
+ cc = 0;
+ }
+ } break;
+ }
+ if(cc) {
+ mysz = sz1 + sz2 + 1;
+ if(p1) { mysz += dk3str_len(p1); mysz++; }
+ if(p2) { mysz += dk3str_len(p2); mysz++; }
+ if(p3) { mysz += dk3str_len(p3); mysz++; }
+ if(mysz < sz) {
+ dk3str_cpy_not_overlapped(db, app->n_sharedir);
+ if(p1) {
+ dk3str_cat(db, dk3app_no_loc[20]); dk3str_cat(db, p1);
+ }
+ if(p2) {
+ dk3str_cat(db, dk3app_no_loc[20]); dk3str_cat(db, p2);
+ }
+ if(p3) {
+ dk3str_cat(db, dk3app_no_loc[20]); dk3str_cat(db, p3);
+ }
+ dk3str_cat(db, dk3app_no_loc[20]);
+ dk3str_cat(db, fn);
+
+#line 3143 "dk3app.ctr"
+ if(dk3sf_stat_app(&stb, db, NULL)) {
+ switch((stb.ft) & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_REGULAR: {
+ back = 1;
+
+#line 3147 "dk3app.ctr"
+ } break;
+ }
+ }
+ if(back) {
+ /* DEBUG: Resource file ... found. */
+ dk3app_log_i3(app, DK3_LL_DEBUG, 148, 149, db);
+ } else {
+ /* DEBUG: Resource file ... not found. */
+ dk3app_log_i3(app, DK3_LL_DEBUG, 150, 151, db);
+ }
+ }
+ }
+ }
+ }
+ } else {
+ if(verb) {
+ /* Internal error, no /xxx/share directory! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 55);
+ }
+ }
+ }
+
+#line 3168 "dk3app.ctr"
+ return back;
+}
+
+
+
+/** Remove a file.
+ The difference to dk3sf_remove_file_app() is that this function
+ does not complain if the file does not exist.
+ @param n File name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3app_remove_file_app(dkChar *n, dk3_app_t *app)
+{
+ int back = 0;
+ dk3_stat_t stb; /* Stat buffer to test existance of file. */
+
+
+#line 3187 "dk3app.ctr"
+ if(dk3sf_stat_app(&stb,n,app)) {
+
+#line 3188 "dk3app.ctr"
+ back = dk3sf_remove_file_app(n, app);
+ } else {
+
+#line 3190 "dk3app.ctr"
+ back = 1; /* File does not exist. */
+ }
+
+#line 3192 "dk3app.ctr"
+ return back;
+}
+
+
+
+/** Delete one temporaray file.
+ @param app Application structure.
+ @param n Number to build the file name.
+ @param s Number to build the file suffix.
+ @param f Pointer to error code variable.
+*/
+static
+void
+dk3app_delete_one_temp_file(dk3_app_t *app, unsigned long n, unsigned s, int *f)
+{
+ dkChar buffer[DK3_MAX_PATH]; /* Buffer to construct complete file name. */
+ dkChar fnb2[16]; /* Buffer for short file name. */
+ char fnb[16]; /* Buffer for numeric conversion. */
+ dk3_app_t *ra = NULL; /* Application to use for diagnostics. */
+ size_t sz = 0; /* Length needed for complete file name. */
+
+
+#line 3213 "dk3app.ctr"
+ sprintf(fnb, "/%08lx.%03x", n, s);
+ ra = app;
+ if((*f) & 1) { ra = NULL; }
+ if(dk3str_cnv_c8_to_str_app(fnb2, 15, fnb, ra)) {
+ sz = dk3str_len(app->n_tmpdir) + dk3str_len(fnb2);
+ if(sz < DK3_SIZEOF(buffer,dkChar)) {
+ dk3str_cpy_not_overlapped(buffer, app->n_tmpdir);
+ dk3str_cat(buffer, fnb2);
+ dk3str_correct_filename(buffer);
+#if VERSION_BEFORE_20150821
+ ra = app;
+ if((*f) & 4) { ra = NULL; }
+#endif
+ if(!dk3app_remove_file_app(buffer, NULL)) {
+ *f = ((*f) | 4);
+ }
+ } else {
+ if(!((*f) & 2)) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 37);
+ *f = ((*f) | 2);
+ }
+ }
+ } else {
+ *f = ((*f) | 1);
+ }
+
+#line 3238 "dk3app.ctr"
+}
+
+
+
+/** Delete all temporary files of an application for a core name.
+ @param app Application structure.
+ @param n Number to build core file name.
+ @param f Pointer to error code variable.
+*/
+static
+void
+dk3app_delete_all_temp_files_for(dk3_app_t *app, unsigned long n, int *f)
+{
+ unsigned u; /* Used for file name suffix. */
+
+
+#line 3253 "dk3app.ctr"
+ for(u = 0; u < 0x1000U; u++) {
+ dk3app_delete_one_temp_file(app, n, u, f);
+ }
+
+#line 3256 "dk3app.ctr"
+}
+
+
+
+/** Delete all temporary files of an application.
+ @param app Application structure.
+*/
+static
+void
+dk3app_remove_temporary_files(dk3_app_t *app)
+{
+ unsigned long ul = 0UL; /* Used for base file name. */
+ unsigned u = 0; /* Used for suffixes of final base. */
+ int f = 0; /* Error checking variable. */
+
+
+#line 3271 "dk3app.ctr"
+ if(app->n_tmpdir) {
+ f = 0;
+ if(app->i_tmpcarry) {
+ for(ul = 0UL; ul < 0xFFFFFFFFUL; ul++) {
+ dk3app_delete_all_temp_files_for(app, ul, &f);
+ }
+ dk3app_delete_all_temp_files_for(app, 0xFFFFFFFFUL, &f);
+ } else {
+ for(ul = 0UL; ul < app->ul_tmpname; ul++) {
+ dk3app_delete_all_temp_files_for(app, ul, &f);
+ }
+ for(u = 0; u < app->u_tmpsuffix; u++) {
+ dk3app_delete_one_temp_file(app, app->ul_tmpname, u, &f);
+ }
+ dk3app_delete_one_temp_file(app, app->ul_tmpname, app->u_tmpsuffix, &f);
+ }
+ dk3sf_remove_dir_app(app->n_tmpdir, NULL);
+ }
+
+#line 3289 "dk3app.ctr"
+}
+
+
+
+/** Construct configuration file name candidate.
+ When searching for files (configuration or resource files) we
+ specify the sort file name without leading directory.
+ During the search process we do several tests prepending
+ directory names before the short file name.
+ This function is used to construct a file name.
+ @param app Application structure.
+ @param fn File name.
+ @param db Result buffer.
+ @param sz Size of \a db (number of characters).
+ @param passno Pass number (0-15).
+ @param verb Flag: Diagnostic messages enabled.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3app_config_name(
+ dk3_app_t *app, dkChar const *fn, dkChar *db, size_t sz, int passno, int verb
+)
+{
+ int back = 0;
+ dkChar const *ptr1 = NULL; /* Base directory (etc or share). */
+ dkChar const *ptr2 = NULL; /* Subdirectory (app, group, dk3app or none). */
+ dkChar const *ptr3 = NULL; /* Application or group name. */
+ size_t mysz = 0; /* Buffer size needed for all components. */
+
+
+#line 3319 "dk3app.ctr"
+ ptr1 = NULL; ptr2 = NULL; ptr3 = NULL;
+ switch(passno) {
+
+#if VERSION_BEFORE_20110219
+ case 0: { ptr1 = app->n_sharedir; ptr2 = dk3app_no_loc[17]; } break;
+ case 2: { ptr1 = app->n_sharedir; ptr2 = app->n_appgroup; } break;
+ case 3: { ptr1 = app->n_etcdir; ptr2 = app->n_appgroup; } break;
+ case 4: { ptr1 = app->n_sharedir; ptr2 = app->n_app; } break;
+ case 5: { ptr1 = app->n_etcdir; ptr2 = app->n_app; } break;
+ case 6: { ptr1 = app->n_homedir; ptr2 = dk3app_no_loc[18]; } break;
+ case 7: {
+ ptr1 = app->n_homedir; ptr2 = dk3app_no_loc[18]; ptr3 = app->n_appgroup;
+ } break;
+ case 8: {
+ ptr1 = app->n_homedir; ptr2 = dk3app_no_loc[18]; ptr3 = app->n_app;
+ } break;
+ case 9: {
+ ptr1 = dk3app_no_loc[19];
+ } break;
+ default: { /* 1 */
+ ptr1 = app->n_etcdir; ptr2 = dk3app_no_loc[17];
+ } break;
+#else
+ case 0: {
+ ptr1 = app->n_sharedir; ptr2 = dk3app_no_loc[17];
+ } break;
+ case 1: {
+ ptr1 = app->n_etcdir; ptr2 = dk3app_no_loc[17];
+ } break;
+ case 2: {
+ ptr1 = app->n_sharedir; ptr2 = dk3app_no_loc[17];
+ } break;
+ case 3: {
+ ptr1 = app->n_etcdir; ptr2 = dk3app_no_loc[17];
+ } break;
+ case 4: {
+ ptr1 = app->n_sharedir; ptr2 = app->n_appgroup;
+ } break;
+ case 5: {
+ ptr1 = app->n_etcdir; ptr2 = app->n_appgroup;
+ } break;
+ case 6: {
+ ptr1 = app->n_sharedir; ptr2 = app->n_appgroup;
+ } break;
+ case 7: {
+ ptr1 = app->n_etcdir; ptr2 = app->n_appgroup;
+ } break;
+ case 8: {
+ ptr1 = app->n_sharedir; ptr2 = app->n_app;
+ } break;
+ case 9: {
+ ptr1 = app->n_etcdir; ptr2 = app->n_app;
+ } break;
+ case 10: {
+ ptr1 = app->n_sharedir; ptr2 = app->n_app;
+ } break;
+ case 11: {
+ ptr1 = app->n_etcdir; ptr2 = app->n_app;
+ } break;
+ case 12: {
+ ptr1 = app->n_homedir; ptr2 = dk3app_no_loc[18];
+ } break;
+ case 13: {
+ ptr1 = app->n_homedir; ptr2 = dk3app_no_loc[18]; ptr3 = app->n_appgroup;
+ } break;
+ case 14: {
+ ptr1 = app->n_homedir; ptr2 = dk3app_no_loc[18]; ptr3 = app->n_app;
+ } break;
+ case 15: {
+ ptr1 = dk3app_no_loc[19];
+ } break;
+#endif
+ }
+ mysz = dk3str_len(fn);
+ if(ptr1) {
+ mysz += dk3str_len(ptr1);
+ mysz++;
+ }
+ if(ptr2) {
+ mysz += dk3str_len(ptr2);
+ mysz++;
+ }
+ if(ptr3) {
+ mysz += dk3str_len(ptr3);
+ mysz++;
+ }
+ switch(passno) {
+ case 2: case 3: case 6: case 7: case 10: case 11: {
+ mysz += dk3str_len(dk3app_no_loc[32]);
+ } break;
+ }
+ if(mysz < sz) {
+ if(ptr1) {
+ dk3str_cpy_not_overlapped(db, ptr1);
+ if(ptr2) {
+ dk3str_cat(db, dk3app_no_loc[20]);
+ dk3str_cat(db, ptr2);
+ }
+ if(ptr3) {
+ dk3str_cat(db, dk3app_no_loc[20]);
+ dk3str_cat(db, ptr3);
+ }
+ switch(passno) {
+ case 2: case 3: case 6: case 7: case 10: case 11: {
+ dk3str_cat(db, dk3app_no_loc[32]);
+ } break;
+ }
+ dk3str_cat(db, dk3app_no_loc[20]);
+ dk3str_cat(db, fn);
+ back = 1;
+
+#line 3429 "dk3app.ctr"
+ } else {
+ if(verb) {
+ /* Internal error, some directory not set! */
+ }
+ }
+ } else {
+ if(verb) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+
+#line 3439 "dk3app.ctr"
+ return back;
+}
+
+
+
+/** Unconfigure application (delete registry key or config file).
+ @param app Application to unconfigure.
+*/
+static
+void
+dk3app_do_unconfigure(dk3_app_t *app)
+{
+ dkChar fnb[DK3_MAX_PATH]; /* File name buffer for config file. */
+
+ if(dk3app_config_name(app, dk3app_no_loc[21], fnb, DK3_MAX_PATH, 14, 0)) {
+ (void)dk3sf_remove_file_app(fnb, app);
+ }
+}
+
+
+
+/** Save self-set preferences to registry or file.
+ @param app Application structure.
+*/
+static
+void
+dk3app_do_save_config(dk3_app_t *app)
+{
+ dkChar fnb[DK3_MAX_PATH]; /* File name buffer for conf file. */
+ dkChar *ptr = NULL; /* Slash/backslash correction. */
+ FILE *fipo = NULL; /* Used to write file. */
+ dk3app_pref_t *p1 = NULL; /* Preference entry to process. */
+ dk3app_pref_t *p2 = NULL; /* Check in higher priorized storage. */
+
+
+#line 3473 "dk3app.ctr"
+ if(dk3app_config_name(app, dk3app_no_loc[21], fnb, DK3_MAX_PATH, 14, 0)) {
+
+
+#line 3475 "dk3app.ctr"
+ ptr = dk3str_rchr(fnb, DK3_CHAR_SEP);
+ if(ptr) {
+ *ptr = dkT('\0');
+
+
+#line 3479 "dk3app.ctr"
+ dk3sf_mkdir_app(fnb, 0700, NULL);
+ *ptr = DK3_CHAR_SEP;
+ }
+ fipo = dk3sf_fopen_app(fnb, dk3app_no_loc[24], app); /* WRITE */
+ if(fipo) {
+
+#line 3484 "dk3app.ctr"
+#if DK3_ON_WINDOWS && (DK3_CHAR_SIZE > 1)
+ /* Switch to 16 bit characters. */
+ (void)_setmode(_fileno(fipo), _O_U16TEXT);
+ /* Write byte order marker. */
+ fputwc(0xFEFF, fipo);
+#endif
+ if((app->s_varprefs) && (app->i_varprefs)) {
+ dk3sto_it_reset(app->i_varprefs);
+ while((p1 = (dk3app_pref_t *)dk3sto_it_next(app->i_varprefs)) != NULL) {
+ p2 = NULL;
+ if((app->s_selfprefs) && (app->i_selfprefs)) {
+ p2 = (dk3app_pref_t *)dk3sto_it_find_like(app->i_selfprefs, p1, 0);
+ }
+ if(!(p2)) {
+ dk3sf_fputs(p1->k, fipo);
+ dk3sf_fputs(dk3app_no_loc[25], fipo);
+ dk3sf_fputs(p1->v, fipo);
+ dk3sf_fputs(dk3app_no_loc[26], fipo);
+ }
+ }
+ }
+ if((app->s_selfprefs) && (app->i_selfprefs)) {
+ dk3sto_it_reset(app->i_selfprefs);
+ while((p1 = (dk3app_pref_t *)dk3sto_it_next(app->i_selfprefs)) != NULL) {
+ dk3sf_fputs(p1->k, fipo);
+ dk3sf_fputs(dk3app_no_loc[25], fipo);
+ dk3sf_fputs(p1->v, fipo);
+ dk3sf_fputs(dk3app_no_loc[26], fipo);
+ }
+ }
+ fclose(fipo);
+ } else {
+
+#line 3516 "dk3app.ctr"
+ }
+ } else {
+
+#line 3518 "dk3app.ctr"
+ }
+
+#line 3519 "dk3app.ctr"
+}
+
+
+
+
+
+void
+dk3app_close(dk3_app_t *app)
+{
+ int i = 0; /* Used to release argv memory. */
+ dk3app_pref_t *pref = NULL; /* Used to delete preference entries. */
+ dk3app_mc_t *mcptr = NULL; /* Used to delete message catalogs. */
+
+
+#line 3532 "dk3app.ctr"
+
+ if(app) {
+ if(app->f_unconfigure) {
+
+#line 3535 "dk3app.ctr"
+ dk3app_do_unconfigure(app);
+ } else {
+ if(app->f_prefschanged) {
+
+#line 3538 "dk3app.ctr"
+ dk3app_do_save_config(app);
+ }
+ }
+ /* Clean up preferences system. */
+
+#line 3542 "dk3app.ctr"
+ if(app->s_selfprefs) {
+ if(app->i_selfprefs) {
+ dk3sto_it_reset(app->i_selfprefs);
+ while((pref = (dk3app_pref_t *)dk3sto_it_next(app->i_selfprefs)) != NULL) {
+ dk3app_pref_delete(pref);
+ }
+ dk3sto_it_close(app->i_selfprefs);
+ }
+ dk3sto_close(app->s_selfprefs);
+ } app->s_selfprefs = NULL; app->i_selfprefs = NULL;
+ if(app->s_cmdprefs) {
+ if(app->i_cmdprefs) {
+ dk3sto_it_reset(app->i_cmdprefs);
+ while((pref = (dk3app_pref_t *)dk3sto_it_next(app->i_cmdprefs)) != NULL) {
+ dk3app_pref_delete(pref);
+ }
+ dk3sto_it_close(app->i_cmdprefs);
+ }
+ dk3sto_close(app->s_cmdprefs);
+ } app->s_cmdprefs = NULL; app->i_cmdprefs = NULL;
+ if(app->s_sysprefs) {
+ if(app->i_sysprefs) {
+ dk3sto_it_reset(app->i_sysprefs);
+ while((pref = (dk3app_pref_t *)dk3sto_it_next(app->i_sysprefs)) != NULL)
+ {
+ dk3app_pref_delete(pref);
+ }
+ dk3sto_it_close(app->i_sysprefs);
+ }
+ dk3sto_close(app->s_sysprefs);
+ } app->s_sysprefs = NULL; app->i_sysprefs = NULL;
+ if(app->s_constprefs) {
+ if(app->i_constprefs) {
+ dk3sto_it_reset(app->i_constprefs);
+ while((pref = (dk3app_pref_t *)dk3sto_it_next(app->i_constprefs)) != NULL)
+ {
+ dk3app_pref_delete(pref);
+ }
+ dk3sto_it_close(app->i_constprefs);
+ }
+ dk3sto_close(app->s_constprefs);
+ } app->s_constprefs = NULL; app->i_constprefs = NULL;
+ if(app->s_varprefs) {
+ if(app->i_varprefs) {
+ dk3sto_it_reset(app->i_varprefs);
+ while((pref = (dk3app_pref_t *)dk3sto_it_next(app->i_varprefs)) != NULL)
+ {
+ dk3app_pref_delete(pref);
+ }
+ dk3sto_it_close(app->i_varprefs);
+ }
+ dk3sto_close(app->s_varprefs);
+ } app->s_varprefs = NULL; app->i_varprefs = NULL;
+ /* Clean up temporary directory. */
+
+#line 3596 "dk3app.ctr"
+ if(app->ll_highest > app->ll_tmp_keep) {
+ dk3app_remove_temporary_files(app);
+ }
+ /* Remove log file if no longer needed. */
+
+#line 3600 "dk3app.ctr"
+ if(DK3_APP_TYPE_DAEMON != app->app_type) {
+ dk3app_log_i3(app, DK3_LL_DEBUG, 21, 22, app->n_app);
+ if(app->ll_highest > app->ll_file_keep) {
+ dk3sf_remove_file_app(app->n_logfilename, NULL);
+ }
+ }
+ /* Unset resources, release resources. */
+ app->ll_file = app->ll_stderr = app->ll_file_keep = app->ll_highest = 0;
+ app->app_type = 0;
+ app->msg = NULL;
+ app->n_sourcefile = NULL;
+ app->sourceline = 0UL;
+
+#line 3612 "dk3app.ctr"
+ if(app->s_mc) {
+ if(app->i_mc) {
+ dk3sto_it_reset(app->i_mc);
+ while((mcptr = (dk3app_mc_t *)dk3sto_it_next(app->i_mc)) != NULL)
+ {
+ dk3app_mc_delete(mcptr);
+ }
+ dk3sto_it_close(app->i_mc);
+ }
+ dk3sto_close(app->s_mc);
+ } app->s_mc = NULL; app->i_mc = NULL;
+
+#line 3623 "dk3app.ctr"
+ if(app->argv) {
+ dkChar const **ptr;
+ ptr = (dkChar const **)(app->argv);
+ for(i = 0; i < app->argc; i++) {
+ dk3_release(*ptr);
+ ptr++;
+ }
+ }
+
+#line 3631 "dk3app.ctr"
+ dk3_release(app->n_app);
+ dk3_release(app->n_execfile);
+ dk3_release(app->n_bindir);
+ dk3_release(app->n_etcdir);
+ dk3_release(app->n_sharedir);
+ dk3_release(app->n_vardir);
+ dk3_release(app->n_logname);
+ dk3_release(app->n_homedir);
+ dk3_release(app->n_appgroup);
+ dk3_release(app->n_logfilename);
+ dk3_release(app->n_tmpdir);
+ dk3_release(app->n_language);
+ dk3_release(app->n_region);
+ dk3_release(app->n_langstr);
+ dk3_release(app->n_hostname);
+ dk3_delete(app);
+ }
+
+#line 3648 "dk3app.ctr"
+}
+
+
+
+int
+dk3app_get_default_stdin_encoding(dk3_app_t const *app)
+{
+ int back = 0;
+ if(app) {
+ back = app->i_output_encoding;
+#if DK3_CHAR_SIZE > 1
+#if DK3_ON_WINDOWS
+ back = DK3_FILE_ENCODING_ASCII;
+#endif
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3app_get_default_file_encoding(dk3_app_t const *app)
+{
+ int back = 0;
+ if(app) {
+ back = app->i_output_encoding;
+#if DK3_CHAR_SIZE > 1
+#if DK3_ON_WINDOWS
+ back = DK3_FILE_ENCODING_ASCII;
+#endif
+#endif
+ }
+ return back;
+}
+
+
+
+
+/** Initialize application structure.
+ @param app Application to initialize.
+*/
+static
+void
+dk3app_init(dk3_app_t *app)
+{
+
+
+#line 3695 "dk3app.ctr"
+ app->app_type = 0;
+ app->msg = NULL;
+ app->n_sourcefile = NULL;
+ app->sourceline = 0UL;
+ app->ll_file = DK3_LL_NONE;
+ app->ll_stderr = DK3_LL_INFO;
+ app->ll_file_keep = DK3_LL_NONE;
+ app->ll_tmp_keep = DK3_LL_NONE;
+ app->ll_highest = DK3_LL_IGNORE;
+ app->argv = NULL;
+ app->argc = 0;
+ app->n_app = NULL;
+ app->n_execfile = NULL;
+ app->n_bindir = NULL;
+ app->n_etcdir = NULL;
+ app->n_sharedir = NULL;
+ app->n_vardir = NULL;
+ app->n_logname = NULL;
+ app->n_homedir = NULL;
+ app->n_appgroup = NULL;
+ app->n_logfilename = NULL;
+ app->n_tmpdir = NULL;
+ app->n_language = NULL;
+ app->n_region = NULL;
+ app->n_langstr = NULL;
+ app->ul_tmpname = 0UL;
+ app->u_tmpsuffix = 0U;
+ app->i_tmpcarry = 0;
+ app->n_hostname = NULL;
+#if DK3_CHAR_SIZE > 1
+ app->i_encoding = DK3_ENCODING_UTF16;
+#if DK3_BIGENDIAN
+ app->i_output_encoding = DK3_FILE_ENCODING_UTF16_MSB_FIRST;
+#else
+ app->i_output_encoding = DK3_FILE_ENCODING_UTF16_LSB_FIRST;
+#endif
+#else
+ app->i_encoding = DK3_ENCODING_PLAIN;
+ app->i_output_encoding = DK3_FILE_ENCODING_ASCII;
+#endif
+ app->i_stdin_input_encoding = dk3app_get_default_stdin_encoding(app);
+
+
+#line 3737 "dk3app.ctr"
+ app->i_file_input_encoding = dk3app_get_default_file_encoding(app);
+ app->de = 0; /* No error found yet. */
+
+#line 3739 "dk3app.ctr"
+ app->s_mc = NULL;
+ app->i_mc = NULL;
+ app->s_cmdprefs = NULL;
+ app->i_cmdprefs = NULL;
+ app->s_selfprefs = NULL;
+ app->i_selfprefs = NULL;
+ app->f_unconfigure = 0;
+ app->f_prefschanged = 0;
+ app->f_readytolog = 0;
+ app->s_sysprefs = NULL;
+ app->i_sysprefs = NULL;
+ app->s_constprefs = NULL;
+ app->i_constprefs = NULL;
+ app->s_varprefs = NULL;
+ app->i_varprefs = NULL;
+ app->f_first_file_log = 1;
+ app->f_rand_initialized = 0;
+ app->f_rand_success = 0;
+ app->rand_type = 0;
+ app->cr_log = 0;
+ app->cr_tmp = 0;
+ app->t_last_log_stderr = (dk3_time_t)0UL;
+ app->t_last_log_file = (dk3_time_t)0UL;
+}
+
+
+
+/** Copy binary directory name to other directory names.
+ @param app Application structure.
+*/
+static
+void
+dk3app_copy_bin_to_others(dk3_app_t *app)
+{
+
+
+#line 3774 "dk3app.ctr"
+ app->n_etcdir = dk3str_dup_app(app->n_bindir, NULL);
+ if(app->n_etcdir) {
+ app->n_sharedir = dk3str_dup_app(app->n_bindir, NULL);
+ if(app->n_sharedir) {
+ app->n_vardir = dk3str_dup_app(app->n_bindir, NULL);
+ if(!(app->n_vardir)) {
+ app->de = 9;
+ }
+ } else {
+ app->de = 8;
+ }
+ } else {
+ app->de = 7;
+ }
+
+#line 3788 "dk3app.ctr"
+}
+
+
+#if DK3_ON_WINDOWS
+
+#if VERSION_BEFORE_20131022
+
+/** Open a registry key.
+ @param k Parent key (HKLM or HKCU).
+ @param n Key name.
+ @param p Permissions needed.
+ @param kp Pointer to result key variable.
+ @return ERROR_SUCCESS on success, other values indicate an error.
+*/
+static
+long
+dk3app_reg_open_key(HKEY k, dkChar const *n, int p, HKEY *kp)
+{
+ long back = 0L;
+#if DK3_CHAR_SIZE > 1
+ back = RegOpenKeyExW(k, n, (DWORD)0, p, kp);
+#else
+ back = RegOpenKeyExA(k, n, (DWORD)0, p, kp);
+#endif
+ return back;
+}
+
+
+
+/** Retrieve a value from the registry.
+ @param k Registry key.
+ @param n Entry name.
+ @param tp Entry type.
+ @param b Result buffer address.
+ @param len In: size of buffer, out: number of bytes used.
+ @return ERROR_SUCCESS on success, any other value indicates an error.
+*/
+static
+long
+dk3app_reg_query(HKEY k, dkChar const *n, DWORD *tp, LPBYTE b, DWORD *len)
+{
+ long back = 0L;
+#if DK3_CHAR_SIZE > 1
+ back = RegQueryValueExW(k, n, NULL, tp, b, len);
+#else
+ back = RegQueryValueExA(k, n, NULL, tp, b, len);
+#endif
+ return back;
+}
+
+
+
+/** Retrieve string value from registry.
+ @param k Key.
+ @param n Entry name.
+ @param b Result buffer.
+ @param sz Size of \a b (number of characters).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3app_reg_query_str(HKEY k, dkChar const *n, dkChar *b, size_t sz)
+{
+ int back = 0;
+ DWORD tp = REG_SZ; /* Registry entry type. */
+ DWORD len = 0L; /* Length of arguments and results. */
+ LONG res = 0L; /* Registry operation result. */
+ tp = REG_SZ;
+ len = (DWORD)(sz * DK3_CHAR_SIZE);
+ res = dk3app_reg_query(k, n, &tp, (LPBYTE)b, &len);
+ if(ERROR_SUCCESS == res) {
+ if((REG_SZ == tp) || (REG_EXPAND_SZ == tp)) {
+ if(len > 0) {
+#if DK3_CHAR_SIZE > 1
+ len = len / DK3_CHAR_SIZE;
+#endif
+ b[(((size_t)len) < sz) ? len : (sz - 1)] = dkT('\0');
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+
+#endif
+
+#endif
+
+
+
+/** Get users language/region/encoding setting.
+ @param app Application structure.
+ @param db Result buffer.
+ @param sz Size of \a db (number of characters).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3app_get_language_string(dk3_app_t *app, dkChar *db, size_t sz)
+{
+ int back = 0;
+
+
+#line 3890 "dk3app.ctr"
+#if DK3_ON_WINDOWS
+
+#if VERSION_BEFORE_20131022
+ {
+ LONG res = 0L; /* Registry operation result. */
+ HKEY key; /* Registry key. */
+ res = dk3app_reg_open_key(
+ HKEY_CURRENT_USER,
+ dk3app_no_loc[12],
+ KEY_READ,
+ &key
+ );
+ if(ERROR_SUCCESS == res) {
+ back = dk3app_reg_query_str(key, dk3app_no_loc[13], db, sz);
+ if(back == 0) {
+ back = dk3app_reg_query_str(key, dk3app_no_loc[14], db, sz);
+ if(back) {
+ db[2] = dkT('\0');
+ }
+ }
+ RegCloseKey(key);
+ }
+ }
+#else
+ {
+ HKEY hk; /* Registry key. */
+ if(dk3wreg_key_open_read(HKEY_CURRENT_USER, dk3app_no_loc[12], &hk, NULL)) {
+ if(dk3wreg_get_sz(hk, dk3app_no_loc[13],db,sz,NULL)) {
+ back = 1;
+ } else {
+ if(dk3wreg_get_sz(hk, dk3app_no_loc[14],db,sz,NULL)) {
+ back = 1;
+ db[2] = dkT('\0');
+ }
+ }
+ dk3wreg_key_close(hk, dk3app_no_loc[12], NULL);
+ }
+ }
+#endif
+
+#else
+#if DK3_CHAR_SIZE == 1
+ {
+ char *ptr; /* Pointer to environment variable contents. */
+ ptr = getenv(dk3app_no_loc[11]);
+ if(ptr) {
+ if(dk3str_c8_len(ptr) < sz) {
+ dk3str_c8_cpy_not_overlapped(db, ptr);
+ back = 1;
+ } else {
+ dk3app_log_i1(app, DK3_LL_ERROR, 39);
+ }
+ }
+ }
+#endif
+#endif
+
+
+#line 3947 "dk3app.ctr"
+ return back;
+}
+
+
+
+/** Find language, region and encoding.
+ @param app Application structure.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+*/
+static
+void
+dk3app_language_and_region(dk3_app_t *app, int argc, dkChar const * const *argv)
+{
+ dkChar buffer[DK3_MAX_PATH]; /* Buffer to store language/region name. */
+ dkChar *ptr; /* Used to find region. */
+ dkChar *p2; /* Used to convert to lower characters. */
+
+
+#line 3965 "dk3app.ctr"
+ if(dk3app_get_language_string(app, buffer, DK3_SIZEOF(buffer,dkChar))) {
+ app->n_langstr = dk3str_dup_app(buffer, NULL);
+
+#line 3967 "dk3app.ctr"
+ if(app->n_langstr) {
+ ptr = dk3str_chr(buffer, dkT('.'));
+ if(ptr) {
+ *(ptr++) = dkT('\0');
+
+#line 3971 "dk3app.ctr"
+#if DK3_CHAR_SIZE == 1
+ if(dk3str_casecmp(ptr, dk3app_no_loc[15]) == 0) {
+ app->i_encoding = DK3_ENCODING_UTF8;
+ app->i_output_encoding = DK3_FILE_ENCODING_UTF8;
+ }
+ if(dk3str_casecmp(ptr, dk3app_no_loc[16]) == 0) {
+ app->i_encoding = DK3_ENCODING_UTF8;
+ app->i_output_encoding = DK3_FILE_ENCODING_UTF8;
+ }
+#endif
+ }
+ ptr = dk3str_chr(buffer, dkT('_'));
+#if DK3_ON_WINDOWS
+ if(!(ptr)) { ptr = dk3str_chr(buffer, dkT('-')); }
+#endif
+ if(ptr) {
+
+#line 3987 "dk3app.ctr"
+ *(ptr++) = dkT('\0');
+
+#line 3988 "dk3app.ctr"
+ p2 = ptr; while(*p2) { *p2 = dk3str_tolower(*p2); p2++; }
+ app->n_region = dk3str_dup_app(ptr, NULL);
+ if(!(app->n_region)) {
+
+#line 3991 "dk3app.ctr"
+ app->de = 29;
+ }
+ }
+ if(!(app->de)) {
+
+#line 3995 "dk3app.ctr"
+ p2 = buffer; while(*p2) { *p2 = dk3str_tolower(*p2); p2++; }
+ app->n_language = dk3str_dup_app(buffer, NULL);
+ if(!(app->n_language)) {
+
+#line 3998 "dk3app.ctr"
+ app->de = 30;
+ }
+ }
+ } else {
+
+#line 4002 "dk3app.ctr"
+ app->de = 28;
+ }
+ }
+
+#line 4005 "dk3app.ctr"
+}
+
+
+
+/** Check whether a directory name is a root directory.
+ @param dirname Directory name to check.
+ @return 1 for root directory, 0 for others.
+*/
+static
+int
+dk3app_is_root_directory(dkChar const *dirname)
+{
+ int back = 0;
+#if DK3_ON_WINDOWS
+ size_t sz;
+ sz = dk3str_len(dirname);
+ if(1 == sz) {
+ if(dkT('\\') == dirname[0]) {
+ back = 1;
+ }
+ } else {
+ if(3 == sz) {
+ if((dkT('a') <= dirname[0]) && (dkT('z') >= dirname[0])) {
+ back = 1;
+ } else {
+ if((dkT('A') <= dirname[0]) && (dkT('Z') >= dirname[0])) {
+ back = 1;
+ }
+ }
+ if(back) {
+ back = 0;
+ if(dkT(':') == dirname[1]) {
+ if(dkT('\\') == dirname[2]) {
+ back = 1;
+ }
+ }
+ }
+ }
+ }
+#else
+ if(dk3str_len(dirname) == 1) {
+ if(dkT('/') == dirname[0]) {
+ back = 1;
+ }
+ }
+#endif
+ return back;
+}
+
+
+
+/** Reduce a directory name referring to a bin (or sbin or libexec/xxx
+ directory.
+ @param dirname Directory name to modify.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3app_reduce_bindir_name(dkChar *dirname)
+{
+ dkChar buffer[DK3_MAX_PATH];
+ dkChar *pCurrent; /* Current path component. */
+ dkChar *pPrevious; /* Previous path component. */
+ size_t sz;
+ int ai; /* Array index. */
+ int cc; /* Flag: Can continue. */
+ int back = 0;
+
+
+#line 4073 "dk3app.ctr"
+ if(dk3str_len(dirname) < DK3_SIZEOF(buffer,dkChar)) {
+ dk3str_cpy_not_overlapped(buffer, dirname);
+ pCurrent = NULL; pPrevious = NULL;
+ cc = 1;
+ while(cc) {
+
+#line 4078 "dk3app.ctr"
+ cc = 0;
+ if(dk3str_len(buffer) > 1) {
+
+#line 4080 "dk3app.ctr"
+ if(!dk3app_is_root_directory(buffer)) {
+
+#line 4081 "dk3app.ctr"
+ pCurrent = dk3str_rchr(buffer, DK3_CHAR_SEP);
+ if(pCurrent) {
+
+#line 4083 "dk3app.ctr"
+ cc = 1;
+
+#line 4084 "dk3app.ctr"
+#if DK3_ON_WINDOWS
+ ai = dk3str_array_index(dk3app_bindir_candidates,&(pCurrent[1]),0);
+#else
+ ai = dk3str_array_index(dk3app_bindir_candidates,&(pCurrent[1]),1);
+#endif
+ if(-1 < ai) {
+
+#line 4090 "dk3app.ctr"
+ cc = 0;
+ sz = dk3str_len(buffer);
+ dirname[sz] = dkT('\0');
+ back = 1;
+ } else {
+
+#line 4095 "dk3app.ctr"
+ if(pPrevious) { *pPrevious = DK3_CHAR_SEP; }
+ pPrevious = pCurrent;
+ *pCurrent = dkT('\0');
+ }
+ }
+ }
+ }
+ }
+ }
+
+#line 4104 "dk3app.ctr"
+ return back;
+}
+
+
+
+/** Find all the names. Set app->de on errors, don't report directly.
+ @param app Application to configure.
+ @param wd Current working directory.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+*/
+static
+void
+dk3app_find_names(
+ dk3_app_t *app, dkChar const *wd,
+ int argc, dkChar const * const *argv
+)
+{
+ int must_relocate = 0; /* Flag: Must relocate. */
+ int redres; /* Result from reduce directory. */
+#if DK3_HAVE_UMASK
+ mode_t oldumask; /* Umask before mkdir. */
+#endif
+ dkChar *n_app = NULL; /* Application name. */
+ dkChar *p = NULL; /* Modify application name. */
+ dkChar const *q = NULL; /* Installation bin directory. */
+ dkChar *x = NULL; /* Deal with executable name. */
+ dkChar buffer[DK3_MAX_PATH]; /* Used to construct file names. */
+ char pidbuffer[128]; /* Buffer for PID number (8-bit). */
+ dkChar dkpidbuffer[128]; /* Buffer for PID number. */
+ size_t tsl = 0; /* Buffer size needed. */
+
+
+#line 4136 "dk3app.ctr"
+ p = dk3str_rchr(argv[0], DK3_CHAR_SEP);
+ if(p) { p++; } else { p = (dkChar *)(argv[0]); }
+ n_app = dk3str_dup_app(p, NULL);
+
+#line 4139 "dk3app.ctr"
+ if(n_app) {
+
+#line 4140 "dk3app.ctr"
+ app->n_app = (dkChar const *)n_app;
+
+#line 4141 "dk3app.ctr"
+ p = dk3str_chr(n_app, DK3_CHAR_DOT);
+ if(p) { *p = DK3_CHAR_0; }
+ if(dk3sf_find_exec_app(buffer,DK3_SIZEOF(buffer,dkChar),wd,argv[0], NULL)) {
+ x = dk3str_dup_app(buffer, NULL);
+ app->n_execfile = x;
+ if(app->n_execfile) {
+ p = dk3str_rchr(buffer, DK3_CHAR_SEP);
+ if(p) {
+ *p = DK3_CHAR_0;
+ app->n_bindir = dk3str_dup_app(buffer, NULL);
+ if(app->n_bindir) {
+ redres = dk3app_reduce_bindir_name(buffer);
+ q = dk3inst_get_directory(DK3_INST_BIN);
+ if(dk3str_fncmp(buffer, q)) {
+ q = dk3inst_get_directory(DK3_INST_SBIN);
+ if(dk3str_fncmp(buffer, q)) {
+ q = dk3inst_get_directory(DK3_INST_LIB);
+ if(dk3str_fncmp(buffer, q)) {
+ q = dk3inst_get_directory(DK3_INST_LIBEXEC);
+ if(dk3str_fncmp(buffer, q)) {
+ must_relocate = 1;
+ }
+ }
+ }
+ }
+ if(must_relocate) {
+ p = dk3str_rchr(buffer, DK3_CHAR_SEP);
+ if(p) {
+ p++;
+ if(redres) {
+ *p = DK3_CHAR_0;
+ tsl = dk3str_len(buffer);
+ tsl += dk3str_len(dk3app_no_loc[1]);
+ if(tsl < DK3_SIZEOF(buffer,dkChar)) {
+ dk3str_cpy_not_overlapped(p, dk3app_no_loc[1]);
+ app->n_etcdir = dk3str_dup_app(buffer, NULL);
+ if(app->n_etcdir) {
+ *p = DK3_CHAR_0;
+ tsl = dk3str_len(buffer);
+ tsl += dk3str_len(dk3app_no_loc[2]);
+ if(tsl < DK3_SIZEOF(buffer,dkChar)) {
+ dk3str_cpy_not_overlapped(p, dk3app_no_loc[2]);
+ app->n_sharedir = dk3str_dup_app(buffer, NULL);
+ if(app->n_sharedir) {
+ *p = DK3_CHAR_0;
+ tsl = dk3str_len(buffer);
+ tsl += dk3str_len(dk3app_no_loc[3]);
+ if(tsl < DK3_SIZEOF(buffer,dkChar)) {
+ dk3str_cpy_not_overlapped(p, dk3app_no_loc[3]);
+ app->n_vardir = dk3str_dup_app(buffer, NULL);
+ if(!(app->n_vardir)) {
+ app->de = 9;
+ }
+ } else {
+ app->de = 13;
+ }
+ } else {
+ app->de = 8;
+ }
+ } else {
+ app->de = 12;
+ }
+ } else {
+ app->de = 7;
+ }
+ } else {
+ app->de = 11;
+ }
+ } else {
+ dk3app_copy_bin_to_others(app);
+ }
+ } else {
+ dk3app_copy_bin_to_others(app);
+ }
+ } else {
+ q = dk3inst_get_directory(DK3_INST_SYSCONF);
+ app->n_etcdir = dk3str_dup_app(q, NULL);
+ if(app->n_etcdir) {
+ q = dk3inst_get_directory(DK3_INST_DATAROOT);
+ app->n_sharedir = dk3str_dup_app(q, NULL);
+ if(app->n_sharedir) {
+ q = dk3inst_get_directory(DK3_INST_LOCALSTATE);
+ app->n_vardir = dk3str_dup_app(q, NULL);
+ if(!(app->n_vardir)) {
+ app->de = 9;
+ }
+ } else {
+ app->de = 8;
+ }
+ } else {
+ app->de = 7;
+ }
+ }
+ if(!(app->de)) {
+ if(dk3sf_get_logname_app(buffer,DK3_SIZEOF(buffer,dkChar),NULL)) {
+ app->n_logname = dk3str_dup_app(buffer,NULL);
+ if(!(app->n_logname)) {
+ app->de = 15;
+ }
+ } else {
+ app->de = 14;
+ }
+ }
+ if(!(app->de)) {
+ if(dk3sf_get_hostname_app(buffer,DK3_SIZEOF(buffer,dkChar),NULL))
+ {
+ app->n_hostname = dk3str_dup_app(buffer, NULL);
+ if(!(app->n_hostname)) {
+ app->de = 37;
+ }
+ } else {
+ app->de = 38;
+ }
+ }
+ if(!(app->de)) {
+ if(dk3sf_get_home_app(buffer,DK3_SIZEOF(buffer,dkChar), NULL)) {
+ app->n_homedir = dk3str_dup_app(buffer,NULL);
+ if(!(app->n_homedir)) {
+ app->de = 17;
+ }
+ } else {
+ app->de = 16;
+ }
+ }
+ if(!(app->de)) {
+ switch(app->app_type) {
+ case DK3_APP_TYPE_COMMAND:
+ case DK3_APP_TYPE_GUI: {
+ tsl = dk3str_len(app->n_homedir);
+ tsl += dk3str_len(dk3app_no_loc[4]);
+ tsl += dk3str_len(dk3app_no_loc[20]);
+ tsl += dk3str_len(app->n_app);
+ tsl += dk3str_len(dk3app_no_loc[5]);
+ (void)dk3ma_um_to_c8_string(
+ pidbuffer, sizeof(pidbuffer), dk3sf_getpid()
+ );
+ if(dk3str_cnv_c8_to_str_app(
+ dkpidbuffer, DK3_SIZEOF(dkpidbuffer,dkChar),
+ pidbuffer, NULL
+ )
+ )
+ {
+ tsl += dk3str_len(dkpidbuffer);
+ tsl += dk3str_len(dk3app_no_loc[6]);
+ if(tsl < DK3_SIZEOF(buffer,dkChar)) {
+ dk3str_cpy_not_overlapped(buffer, app->n_homedir);
+ dk3str_cat(buffer, dk3app_no_loc[4]);
+ dk3str_correct_filename(buffer);
+
+
+#line 4290 "dk3app.ctr"
+#if VERSION_BEFORE_20160128
+ if(dk3sf_mkdir_app(buffer, 0700, NULL)) {
+ dk3str_cat(buffer, dk3app_no_loc[20]);
+ dk3str_cat(buffer, app->n_app);
+ dk3str_cat(buffer, dk3app_no_loc[5]);
+ dk3str_cat(buffer, dkpidbuffer);
+ dk3str_cat(buffer, dk3app_no_loc[6]);
+ dk3str_correct_filename(buffer);
+ app->n_logfilename = dk3str_dup_app(buffer,NULL);
+ if(!(app->n_logfilename)) {
+ app->de = 21;
+ }
+ } else {
+ app->de = 20;
+ }
+#else
+ /* 2016-01-28
+ Do not immediately create the log directory
+ for non-daemon programs.
+ */
+ dk3str_cat(buffer, dk3app_no_loc[20]);
+ dk3str_cat(buffer, app->n_app);
+ dk3str_cat(buffer, dk3app_no_loc[5]);
+ dk3str_cat(buffer, dkpidbuffer);
+ dk3str_cat(buffer, dk3app_no_loc[6]);
+ dk3str_correct_filename(buffer);
+ app->n_logfilename = dk3str_dup_app(buffer,NULL);
+ if(!(app->n_logfilename)) {
+ app->de = 21;
+ }
+#endif
+ } else {
+ app->de = 19;
+ }
+ } else {
+ app->de = 22;
+ }
+ } break;
+ case DK3_APP_TYPE_DAEMON: {
+ tsl = dk3str_len(app->n_vardir);
+ tsl += dk3str_len(dk3app_no_loc[4]);
+ tsl += dk3str_len(dk3app_no_loc[20]);
+ tsl += dk3str_len(app->n_app);
+ tsl += dk3str_len(dk3app_no_loc[20]);
+ tsl += dk3str_len(app->n_app);
+ tsl += dk3str_len(dk3app_no_loc[6]);
+#if DK3_HAVE_UMASK
+ oldumask = umask(0);
+#endif
+ if(tsl < DK3_SIZEOF(buffer,dkChar)) {
+ dk3str_cpy_not_overlapped(buffer, app->n_vardir);
+ dk3str_cat(buffer, dk3app_no_loc[4]);
+
+
+#line 4343 "dk3app.ctr"
+ if(dk3sf_mkdir_app(buffer, 0755, NULL)) {
+ dk3str_cat(buffer, dk3app_no_loc[20]);
+ dk3str_cat(buffer, app->n_app);
+
+
+#line 4347 "dk3app.ctr"
+ if(dk3sf_mkdir_app(buffer, 0755, NULL)) {
+ app->cr_log = 1;
+ dk3str_cat(buffer, dk3app_no_loc[20]);
+ dk3str_cat(buffer, app->n_app);
+ dk3str_cat(buffer, dk3app_no_loc[6]);
+ app->n_logfilename = dk3str_dup_app(buffer, NULL);
+ if(!(app->n_logfilename)) {
+ app->de = 21;
+ }
+ } else {
+
+#line 4357 "dk3app.ctr"
+ app->de = 20;
+ }
+ } else {
+
+#line 4360 "dk3app.ctr"
+ app->de = 20;
+ }
+ } else {
+ app->de = 19;
+ }
+#if DK3_HAVE_UMASK
+ umask(oldumask);
+#endif
+ } break;
+ }
+ }
+ if(!(app->de)) {
+
+#line 4372 "dk3app.ctr"
+ switch(app->app_type) {
+ case DK3_APP_TYPE_DAEMON: {
+ if(app->n_vardir) {
+ if(app->n_app) {
+
+ (void)dk3ma_um_to_c8_string(
+ pidbuffer, sizeof(pidbuffer), dk3sf_getpid()
+ );
+ if(dk3str_cnv_c8_to_str_app(
+ dkpidbuffer, DK3_SIZEOF(dkpidbuffer,dkChar),
+ pidbuffer, NULL
+ )
+ )
+ {
+ tsl = dk3str_len(app->n_vardir);
+ tsl += dk3str_len(dk3app_no_loc[10]);
+ tsl += dk3str_len(dk3app_no_loc[20]);
+ tsl += dk3str_len(app->n_app);
+ tsl += dk3str_len(dk3app_no_loc[20]);
+ tsl += dk3str_len(dkpidbuffer);
+ if(tsl < DK3_SIZEOF(buffer,dkChar)) {
+ dk3str_cpy_not_overlapped(buffer, app->n_vardir);
+ dk3str_cat(buffer, dk3app_no_loc[10]);
+ dk3str_correct_filename(buffer);
+
+
+#line 4397 "dk3app.ctr"
+ (void)dk3sf_mkdir_app(buffer,0700,NULL);
+ dk3str_cat(buffer, dk3app_no_loc[20]);
+ dk3str_cat(buffer, app->n_app);
+ dk3str_correct_filename(buffer);
+
+
+#line 4402 "dk3app.ctr"
+ (void)dk3sf_mkdir_app(buffer,0700,NULL);
+ dk3str_cat(buffer, dk3app_no_loc[20]);
+ dk3str_cat(buffer, dkpidbuffer);
+
+
+#line 4406 "dk3app.ctr"
+
+
+#line 4407 "dk3app.ctr"
+ if(dk3sf_mkdir_app(buffer,0700,NULL)) {
+ app->cr_tmp = 1;
+ app->n_tmpdir = dk3str_dup_app(buffer, NULL);
+ if(!(app->n_tmpdir)) {
+ app->de = 25;
+ dk3sf_remove_dir_app(buffer, NULL);
+ }
+ } else {
+ app->de = 26;
+ }
+ } else {
+ app->de = 19;
+ }
+ } else {
+ app->de = 22;
+ }
+ } else {
+ app->de = 24;
+ }
+ } else {
+ app->de = 27;
+ }
+ } break;
+ default: {
+ if(app->n_homedir) {
+ if(app->n_app) {
+ (void)dk3ma_um_to_c8_string(
+ pidbuffer, sizeof(pidbuffer), dk3sf_getpid()
+ );
+ if(dk3str_cnv_c8_to_str_app(
+ dkpidbuffer, DK3_SIZEOF(dkpidbuffer,dkChar),
+ pidbuffer, NULL
+ )
+ )
+ {
+ tsl = dk3str_len(app->n_homedir);
+ tsl += dk3str_len(dk3app_no_loc[9]);
+ tsl += dk3str_len(dk3app_no_loc[20]);
+ tsl += dk3str_len(app->n_app);
+ tsl += dk3str_len(dk3app_no_loc[5]);
+ tsl += dk3str_len(dkpidbuffer);
+ if(tsl < DK3_SIZEOF(buffer,dkChar)) {
+ dk3str_cpy_not_overlapped(buffer, app->n_homedir);
+ dk3str_cat(buffer, dk3app_no_loc[9]);
+ dk3str_correct_filename(buffer);
+#if VERSION_BEFORE_20160128
+
+
+#line 4454 "dk3app.ctr"
+ if(dk3sf_mkdir_app(buffer,0700,NULL)) {
+ dk3str_cat(buffer, dk3app_no_loc[20]);
+ dk3str_cat(buffer, app->n_app);
+ dk3str_cat(buffer, dk3app_no_loc[5]);
+ dk3str_cat(buffer, dkpidbuffer);
+ dk3str_correct_filename(buffer);
+#if VERSION_BEFORE_20150318
+
+
+#line 4462 "dk3app.ctr"
+ if(dk3sf_mkdir_app(buffer,0700,NULL)) {
+ app->n_tmpdir = dk3str_dup_app(buffer, NULL);
+ if(!(app->n_tmpdir)) {
+ app->de = 25;
+ dk3sf_remove_dir_app(buffer, NULL);
+ }
+ } else {
+ app->de = 26;
+ }
+#else
+ app->n_tmpdir = dk3str_dup_app(buffer, NULL);
+ if(!(app->n_tmpdir)) {
+ app->de = 25;
+ }
+#endif
+ } else {
+ app->de = 26;
+ }
+#else
+/* if VERSION_BEFORE_20160128 */
+ dk3str_cat(buffer, dk3app_no_loc[20]);
+ dk3str_cat(buffer, app->n_app);
+ dk3str_cat(buffer, dk3app_no_loc[5]);
+ dk3str_cat(buffer, dkpidbuffer);
+ dk3str_correct_filename(buffer);
+ app->n_tmpdir = dk3str_dup_app(buffer, NULL);
+ if(!(app->n_tmpdir)) {
+ app->de = 25;
+ }
+#endif
+/* if VERSION_BEFORE_20160128 */
+ } else {
+ app->de = 19;
+ }
+ } else {
+ app->de = 22;
+ }
+ } else {
+ app->de = 24;
+ }
+ } else {
+ app->de = 23;
+ }
+ } break;
+ }
+ }
+ } else {
+ app->de = 6;
+ }
+ } else {
+ app->de = 5;
+ }
+ } else {
+ app->de = 4;
+ }
+ } else {
+ app->de = 3;
+ }
+ } else {
+ app->de = 2;
+ }
+
+#line 4523 "dk3app.ctr"
+}
+
+
+
+/** Test whether a configuration file name candidate is valid.
+ @param app Application structure.
+ @param fn File name.
+ @param db Destination buffer.
+ @param sz Size of \a db (number of characters).
+ @param passno Pass number.
+ @param verb Flag: Diagnostic messages enabled.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3app_check_config_file(
+ dk3_app_t *app, dkChar const *fn, dkChar *db, size_t sz, int passno, int verb
+)
+{
+ int back = 0;
+ dk3_stat_t stb; /* Stat buffer used to check existance of files. */
+
+
+#line 4545 "dk3app.ctr"
+ if(dk3app_config_name(app, fn, db, sz, passno, verb)) {
+ if(dk3sf_stat_app(&stb, db, NULL)) {
+ switch((stb.ft) & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_REGULAR: { back = 1; } break;
+ }
+ }
+ if(back) {
+ /* DEBUG Config file ... found. */
+ dk3app_log_i3(app, DK3_LL_DEBUG, 152, 153, db);
+ } else {
+ /* DEBUG Config file ... not found. */
+ dk3app_log_i3(app, DK3_LL_DEBUG, 154, 155, db);
+ }
+ }
+
+#line 4559 "dk3app.ctr"
+ return back;
+}
+
+
+
+/** Add preference key/value entry to storage.
+ Check whether an entry for the key already exists.
+ @param app Application structure for diagnostics, may be NULL.
+ @param s Storage.
+ @param i Storage iterator.
+ @param k Preference key.
+ @param v Preference value.
+*/
+static
+int
+dk3app_add_pref(
+ dk3_app_t *app, dk3_sto_t *s, dk3_sto_it_t *i,
+ dkChar const *k, dkChar const *v
+)
+{
+ int back = 0;
+ dk3app_pref_t p; /* Preference search. */
+ dk3app_pref_t *pref = NULL; /* Existing preference for name. */
+ dkChar *nv = NULL; /* New value string for preference. */
+
+
+#line 4584 "dk3app.ctr"
+ p.k = k; p.v = v;
+ pref = (dk3app_pref_t *)dk3sto_it_find_like(i, &p, 0);
+ if(pref) {
+ nv = dk3str_dup_app(v, NULL);
+ if(nv) {
+ dk3_delete(pref->v);
+ pref->v = nv;
+ back = 1;
+ } else {
+ if(app) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 9);
+ }
+ }
+ } else {
+ pref = dk3app_pref_new(k, v);
+ if(pref) {
+ if(dk3sto_add(s, pref)) {
+ back = 1;
+ } else {
+ if(app) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 9);
+ }
+ dk3app_pref_delete(pref); pref = NULL;
+ }
+ } else {
+ if(app) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 9);
+ }
+ }
+ }
+
+#line 4614 "dk3app.ctr"
+ return back;
+}
+
+
+
+/** Save one preference entry.
+ Do not report problems directly, set app->de instead.
+ @param app Application structure.
+ @param pt Preference text.
+*/
+static
+void
+dk3app_save_one_preference(dk3_app_t *app, dkChar const *pt)
+{
+ dkChar b[DK3_MAX_PATH]; /* Buffer for input line. */
+ dkChar *p1 = NULL; /* Value position. */
+
+
+#line 4631 "dk3app.ctr"
+ if(dk3str_len(pt) < DK3_SIZEOF(b,dkChar)) {
+ dk3str_cpy_not_overlapped(b, pt);
+ p1 = dk3str_chr(b, dkT('='));
+ if(p1) {
+ *(p1++) = dkT('\0');
+ p1 = dk3str_start(p1, NULL);
+ if(p1) {
+ dk3str_chomp(b, NULL);
+ dk3str_chomp(p1, NULL);
+ if(!(app->s_cmdprefs)) {
+ app->s_cmdprefs = dk3sto_open_app(NULL);
+ if(app->s_cmdprefs) {
+ dk3sto_set_comp(app->s_cmdprefs, dk3app_compare_pref, 0);
+ } else {
+ app->de = 36;
+
+#line 4646 "dk3app.ctr"
+ }
+ }
+ if(!(app->i_cmdprefs)) {
+ if(app->s_cmdprefs) {
+ app->i_cmdprefs = dk3sto_it_open(app->s_cmdprefs);
+ } else {
+ app->de = 35;
+
+#line 4653 "dk3app.ctr"
+ }
+ }
+ if((app->s_cmdprefs) && (app->i_cmdprefs)) {
+ if(!dk3app_add_pref(NULL,app->s_cmdprefs,app->i_cmdprefs,b,p1)) {
+ app->de = 33;
+
+#line 4658 "dk3app.ctr"
+ }
+ }
+ } else {
+ app->de = 32;
+
+#line 4662 "dk3app.ctr"
+ }
+ } else {
+ app->de = 32;
+
+#line 4665 "dk3app.ctr"
+ }
+ } else {
+ app->de = 31;
+
+#line 4668 "dk3app.ctr"
+ }
+
+#line 4669 "dk3app.ctr"
+}
+
+
+
+/** Set application to silent mode if --/silent=yes was
+ provided as command line argument.
+ @param app Application structure.
+*/
+static
+void
+dk3app_first_set_silent(dk3_app_t *app)
+{
+ app->ll_stderr = DK3_LL_NONE;
+ switch(app->app_type) {
+ case DK3_APP_TYPE_COMMAND: {
+ app->app_type = DK3_APP_TYPE_SILENT;
+ } break;
+ }
+}
+
+
+
+int
+dk3app_first_silence_check(dk3_app_t *app, int argc, dkChar const * const *argv)
+{
+ int back = 0;
+ int i; /* Index of current argument. */
+ dkChar const * const *lfdptr; /* Pointer to traverse arguments. */
+ dkChar const *ptr; /* Current argument. */
+ dkChar buffer[2 * DK3_MAX_PATH]; /* Local copy. */
+ dkChar *p1; /* Option keyword. */
+ dkChar *p2; /* Option argument. */
+
+ lfdptr = argv; lfdptr++; i = 1;
+ while(i < argc) {
+ ptr = *lfdptr;
+ if(*ptr == dkT('-')) {
+ ptr++;
+ if(*ptr == dkT('-')) {
+ ptr++;
+ if(dk3str_len(ptr) < DK3_SIZEOF(buffer,dkChar)) {
+ dk3str_cpy_not_overlapped(buffer, ptr);
+ p1 = dk3str_start(buffer, NULL);
+ if(p1) {
+ p2 = dk3str_chr(p1, dkT('='));
+ if(p2) {
+ *(p2++) = dkT('\0');
+ p2 = dk3str_start(p2, NULL);
+ }
+ if(dk3str_cmp(dk3app_no_loc[50], p1) == 0) {
+ if(p2) {
+ if(dk3str_is_on(p2)) {
+ back = 1;
+ if(app) { dk3app_first_set_silent(app); }
+ }
+ } else {
+ back = 1;
+ if(app) { dk3app_first_set_silent(app); }
+ }
+ }
+ }
+ } else {
+ /* ERROR: Too long! */
+ }
+ }
+ }
+ lfdptr++; i++;
+ }
+ return back;
+}
+
+
+
+/** Save command line arguments for later use.
+ Don't report errors directly, set app->de instead.
+ @param app Application structure.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+*/
+static
+void
+dk3app_save_arguments(dk3_app_t *app, int argc, dkChar const * const *argv)
+{
+ int myargc = 0; /* Number of options used. */
+ dkChar const **myargv = NULL; /* Private copy of options. */
+ dkChar const **ptr = NULL; /* Traverse myargv. */
+ dkChar const * const *sptr = NULL; /* Traverse original argv. */
+ dkChar const *tptr = NULL; /* String tests in sptr. */
+ int ispref = 0; /* Flag: Is a preference. */
+ int i = 0; /* Index of current argv. */
+
+
+#line 4760 "dk3app.ctr"
+ myargv = dk3_new_app(DK3_PCDKCHAR,(argc+1),app);
+ if(myargv) {
+ ptr = myargv;
+ for(i = 0; i < (argc + 1); i++) { *(ptr++) = NULL; }
+ ptr = myargv; myargc = 0; sptr = argv;
+ for(i = 0; i < argc; i++) {
+ tptr = *(sptr++);
+
+#line 4767 "dk3app.ctr"
+ ispref = 0;
+ if(*tptr == DK3_CHAR_MINUS) {
+ if(tptr[1] == DK3_CHAR_MINUS) {
+ if(tptr[2] == DK3_CHAR_SLASH) {
+ ispref = 1;
+
+#line 4772 "dk3app.ctr"
+ }
+ }
+ }
+ if(ispref) {
+ dk3app_save_one_preference(app, &(tptr[2]));
+ } else {
+ *ptr = dk3str_dup_app(tptr, NULL);
+ if(*ptr) {
+ myargc++;
+ ptr++;
+ } else {
+ app->de = 1;
+ }
+ }
+ }
+ app->argc = myargc; app->argv = myargv;
+ }
+
+#line 4789 "dk3app.ctr"
+}
+
+
+
+/** Save application group name.
+ @param app Application structure.
+ @param gn Group name to save.
+*/
+static
+void
+dk3app_save_group_name(dk3_app_t *app, dkChar const *gn)
+{
+
+
+#line 4802 "dk3app.ctr"
+ app->n_appgroup = dk3str_dup_app(gn,NULL);
+ if(!(app->n_appgroup)) {
+ app->de = 18;
+ }
+
+#line 4806 "dk3app.ctr"
+}
+
+
+
+/** Retrieve preferences from a storage.
+ @param app Application structure for diagnostics, may be NULL.
+ @param p Storage iterator.
+ @param k Key (preference name).
+ @param d Destination buffer.
+ @param s Size of \a d (number of characters).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3app_sto_pref(
+ dk3_app_t *app, dk3_sto_it_t *p, dkChar const *k, dkChar *d, size_t s)
+{
+ int back = 0;
+ dk3app_pref_t pr; /* Used for comparisons in search. */
+ dk3app_pref_t *pref = NULL; /* Entry found. */
+
+
+#line 4827 "dk3app.ctr"
+ if(p) {
+ pr.k = k; pr.v = NULL;
+ pref = (dk3app_pref_t *)dk3sto_it_find_like(p, &pr, 0);
+ if(pref) {
+ if(pref->v) {
+ if(dk3str_len(pref->v) < s) {
+ dk3str_cpy_not_overlapped(d, pref->v);
+ back = 1;
+ } else {
+ if(app) {
+ /* Destination buffer too short! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ }
+ }
+
+#line 4844 "dk3app.ctr"
+ return back;
+}
+
+
+
+/** Find number of entries for a string table file.
+ @param dv String table value array.
+ @return Number of entries in array, including final NULL entry.
+*/
+static
+size_t
+dk3app_mc_array_size(dkChar const * const *dv)
+{
+ size_t back = 0;
+ dkChar const * const *ptr = NULL; /* Traverse the dv array. */
+
+
+#line 4860 "dk3app.ctr"
+ if(dv) {
+ ptr = dv;
+ while(*(ptr++)) { back++; }
+ back++;
+ }
+
+#line 4865 "dk3app.ctr"
+ return back;
+}
+
+
+
+void
+dk3app_squeeze_line(char *lb)
+{
+ char *pd = NULL; /* Destination in copy operations. */
+ char *ps = NULL; /* Source in copy operations. */
+ char *px = NULL; /* Position to continue. */
+ ps = lb;
+
+
+#line 4878 "dk3app.ctr"
+ /* Remove trailing newline. */
+ while(*ps) {
+ if((*ps == '\r') || (*ps == '\n')) {
+ *ps = '\0';
+ } else {
+ ps++;
+ }
+ }
+ /* Correct escape sequences */
+ ps = lb;
+ while(*ps) {
+ if(*ps == '\\') {
+ px = pd = ps; ps++;
+ if(*ps) {
+ switch(*ps) {
+ case 't': {
+ *(pd++) = '\t'; ps++;
+ dk3str_c8_cpy(pd, ps);
+ } break;
+ case 'n': {
+ *(pd++) = '\n'; ps++;
+ dk3str_c8_cpy(pd, ps);
+ } break;
+ case 'r': {
+ *(pd++) = '\r'; ps++;
+ dk3str_c8_cpy(pd, ps);
+ } break;
+ default: {
+ dk3str_c8_cpy(pd, ps);
+ } break;
+ }
+ ps = px; ps++;
+ }
+ } else {
+ ps++;
+ }
+ }
+
+#line 4915 "dk3app.ctr"
+}
+
+
+
+/** Get message catalog contents.
+ @param app Application structure.
+ @param fn File name for message catalog.
+ @param dv Default values.
+ @param verb Flag: Diagnostics enabled.
+ @return Pointer to message array.
+*/
+static
+dkChar const * const *
+dk3app_my_messages(
+ dk3_app_t *app, dkChar const *fn, dkChar const * const *dv, int verb
+)
+{
+ dkChar const * const *back = NULL;
+ dkChar const *source_file = NULL; /* File name for source file. */
+ dk3app_mc_t mc; /* Used for comparisons. */
+ dk3app_mc_t *mcptr = NULL; /* Message catalog. */
+ int errors_occured = 0; /* Flag: We had errors. */
+ unsigned long source_line = 0UL; /* Number of source line. */
+ unsigned long line_number = 0UL; /* NUmber of current line. */
+ size_t sz_defaults = 0; /* Number entries in default table. */
+ size_t i = 0; /* Walk through table. */
+ size_t current_index = 0; /* Index of current entry to process. */
+ dkChar fnb[DK3_MAX_PATH]; /* File name buffer. */
+ char lb[4096]; /* Input line (8-bit characters). */
+ dkChar const **rb = NULL; /* Array of strings to return. */
+ FILE *fipo; /* Input file. */
+
+
+#line 4947 "dk3app.ctr"
+ if((app) && (fn) && (dv)) {
+
+#line 4948 "dk3app.ctr"
+ /* Find array size. */
+ sz_defaults = dk3app_mc_array_size(dv);
+ if(sz_defaults) {
+
+#line 4951 "dk3app.ctr"
+ if((app->s_mc) && (app->i_mc)) {
+
+#line 4952 "dk3app.ctr"
+ mc.n = fn; mc.msg = NULL; mc.f = 0; mc.nmsg = sz_defaults;
+ mcptr = (dk3app_mc_t *)dk3sto_it_find_like(app->i_mc, &mc, 0);
+ if(mcptr) {
+
+#line 4955 "dk3app.ctr"
+ if(mcptr->nmsg >= sz_defaults) {
+ back = mcptr->msg;
+
+#line 4957 "dk3app.ctr"
+ } else {
+
+#line 4958 "dk3app.ctr"
+ errors_occured = 1; /* Too short */
+ }
+ } else {
+
+#line 4961 "dk3app.ctr"
+ }
+ } else {
+
+#line 4963 "dk3app.ctr"
+ }
+ if((!(back)) && (errors_occured == 0)) {
+
+#line 4965 "dk3app.ctr"
+ if(dk3app_my_find_data_file(app, fn, fnb, DK3_MAX_PATH, verb)) {
+ source_file = dk3app_get_source_file(app);
+
+#line 4967 "dk3app.ctr"
+ source_line = dk3app_get_source_line(app);
+ dk3app_set_source_file(app, fnb);
+ dk3app_set_source_line(app, 0UL);
+/* UTF8 */ fipo = dk3sf_fopen_app(fnb, dk3app_no_loc[22], (verb ? app : NULL));
+ if(fipo) {
+
+#line 4972 "dk3app.ctr"
+ rb = dk3_new_app(DK3_PCDKCHAR,sz_defaults,(verb ? app : NULL));
+ if(rb) {
+
+#line 4974 "dk3app.ctr"
+ for(i = 0; i < sz_defaults; i++) { rb[i] = NULL; }
+ current_index = 0;
+ /* We explicitly used 8-bit characters, the file is UTF-8 */
+ while(fgets(lb, sizeof(lb), fipo)) {
+ line_number++;
+ dk3app_set_source_line(app, line_number);
+ if(lb[0] != '#') {
+ dk3app_squeeze_line(lb);
+ if(current_index < (sz_defaults - 1)) {
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "Can not handle 4-byte characters here!"
+#else
+ rb[current_index] =
+ (dkChar const *)dk3str_cnvnew_c8u_to_c16_app(
+ lb, (verb ? app : NULL)
+ );
+ if(rb[current_index]) {
+ current_index++;
+ } else {
+ errors_occured = 2;
+ }
+#endif
+#else
+
+ switch(app->i_encoding) {
+ case DK3_ENCODING_PLAIN: {
+ rb[current_index] =
+ dk3str_cnvnew_c8u_to_c8p_app(lb, (verb ? app : NULL));
+ if(rb[current_index]) {
+ current_index++;
+ } else {
+ errors_occured = 2;
+ }
+ } break;
+ default: {
+ rb[current_index] =
+ dk3str_dup_app(lb, (verb ? app : NULL));
+ if(rb[current_index]) {
+ current_index++;
+ } else {
+ errors_occured = 2;
+ }
+ } break;
+ }
+#endif
+ }
+ /* current_index++; */
+ }
+ }
+
+#line 5024 "dk3app.ctr"
+ dk3app_set_source_line(app, 0UL);
+ if((current_index >= (sz_defaults - 1)) && (!(errors_occured))) {
+ if(!(app->s_mc)) {
+
+#line 5027 "dk3app.ctr"
+ app->s_mc = dk3sto_open_app(verb ? app : NULL);
+ if(app->s_mc) {
+
+#line 5029 "dk3app.ctr"
+ dk3sto_set_comp(app->s_mc, dk3app_mc_compare, 0);
+ } else {
+
+#line 5031 "dk3app.ctr"
+ }
+ }
+ if(!(app->i_mc)) {
+
+#line 5034 "dk3app.ctr"
+ if(app->s_mc) {
+
+#line 5035 "dk3app.ctr"
+ app->i_mc = dk3sto_it_open(app->s_mc);
+ } else {
+
+#line 5037 "dk3app.ctr"
+ }
+ }
+ if((app->s_mc) && (app->i_mc)) {
+
+#line 5040 "dk3app.ctr"
+ mcptr =
+ dk3app_mc_new(fn, rb, sz_defaults, 1, (verb ? app: NULL));
+ if(mcptr) {
+
+#line 5043 "dk3app.ctr"
+ if(dk3sto_add(app->s_mc, mcptr)) {
+
+#line 5044 "dk3app.ctr"
+ back = rb;
+ } else {
+ dk3app_mc_table_delete(rb, sz_defaults); rb = NULL;
+ }
+ } else {
+
+#line 5049 "dk3app.ctr"
+ dk3app_mc_table_delete(rb, sz_defaults); rb = NULL;
+ }
+ } else {
+
+#line 5052 "dk3app.ctr"
+ dk3app_mc_table_delete(rb, sz_defaults); rb = NULL;
+ }
+ } else { /* Error occured or not enough strings. */
+ if(errors_occured) {
+
+#line 5056 "dk3app.ctr"
+ if(verb) {
+ /* Errors while reading file! */
+ }
+ } else {
+
+#line 5060 "dk3app.ctr"
+ if(verb) {
+ /* Too few entries in file! */
+ }
+ }
+ dk3app_mc_table_delete(rb, sz_defaults);
+ rb = NULL;
+ }
+ } else {
+
+#line 5068 "dk3app.ctr"
+ }
+ fclose(fipo);
+ } else {
+
+#line 5071 "dk3app.ctr"
+ }
+ dk3app_set_source_file(app, source_file);
+ dk3app_set_source_line(app, source_line);
+ } else {
+
+#line 5075 "dk3app.ctr"
+ }
+ } else {
+
+#line 5077 "dk3app.ctr"
+ }
+ } else {
+
+#line 5079 "dk3app.ctr"
+ }
+ if(!(back)) {
+
+#line 5081 "dk3app.ctr"
+ back = dv;
+ }
+ } else {
+
+#line 5084 "dk3app.ctr"
+ }
+
+#line 5085 "dk3app.ctr"
+ return back;
+}
+
+
+
+/** Read one preferences file.
+ @param app Application structure.
+ @param fn File name to process.
+ @param s Storage to save preference entries.
+ @param i Iterator through storage.
+*/
+static
+void
+dk3app_rd_pref_file(
+ dk3_app_t *app, dkChar const *fn, dk3_sto_t *s, dk3_sto_it_t *i
+)
+{
+ dkChar buffer[4096];
+ char bombuf[4];
+ dkChar *p1 = NULL; /* Preference key (name). */
+ dkChar *p2 = NULL; /* Preference value. */
+ dkChar *p3 = NULL; /* Scope attribute value. */
+ dkChar const *oldsourcename; /* Old source file name. */
+ FILE *fipo = NULL; /* Input file. */
+ unsigned long lineno = 0UL; /* Current line number. */
+ unsigned long oldsourceline; /* Old source line number. */
+ size_t skb; /* Bytes to skip at start. */
+ int scope_valid = 1; /* Flag: In a valid scope. */
+ int last_was_scope = 0; /* Flag: Previous line was scope. */
+ int scope_action = 0; /* 0=yes, 1=no */
+ int conditions_ok; /* Flag: All conditions ok. */
+ int ie = DK3_FILE_ENCODING_ASCII; /* Input encoding. */
+
+ skb = 0;
+ ie = dk3sf_inspect_bom_skip_app(fn, DK3_FILE_ENCODING_ASCII, &skb, NULL);
+ dk3app_log_i3(app, DK3_LL_DEBUG, 230, 231, fn);
+ fipo = dk3sf_fopen_app(fn, dk3app_no_loc[22], NULL); /* READ */
+ if(fipo) {
+ oldsourcename = dk3app_get_source_file(app);
+ oldsourceline = dk3app_get_source_line(app);
+ dk3app_set_source_file(app, fn);
+ dk3app_set_source_line(app, 0UL);
+ (void)dk3sf_apply_bom_to_file_app(fipo, ie, NULL);
+ lineno = 0UL;
+ if((skb > 0) && (skb <= 4)) { dk3sf_fread_app(bombuf, 1, skb, fipo, NULL); }
+ while(dk3sf_fgets(buffer, DK3_SIZEOF(buffer,dkChar), fipo)) {
+ lineno++;
+ dk3app_set_source_line(app, lineno);
+
+#line 5133 "dk3app.ctr"
+ p1 = dk3str_start(buffer, NULL);
+ if(p1) {
+ if(*p1 != dkT('#')) {
+ if(*p1 == dkT('[')) {
+ if(!last_was_scope) { scope_valid = 0; }
+ scope_action = 0;
+ p2 = dk3str_chr(p1, dkT(']'));
+ if(p2) { *p2 = dkT('\0'); }
+ p1++;
+ dk3str_chomp(p1, NULL);
+ if(*p1 == dkT('-')) { scope_action = 1; p1++; }
+ p1 = dk3str_start(p1, NULL);
+ conditions_ok = 1;
+ while(p1) {
+ p2 = dk3str_chr(p1, dkT(','));
+ if(p2) {
+ *(p2++) = dkT('\0');
+ p2 = dk3str_start(p2, NULL);
+ }
+ p3 = dk3str_chr(p1, dkT('='));
+ if(p3) {
+ *(p3++) = dkT('\0');
+ p3 = dk3str_start(p3, NULL);
+ if(p3) {
+ dk3str_chomp(p1, NULL);
+ dk3str_chomp(p3, NULL);
+
+#line 5159 "dk3app.ctr"
+ switch(dk3str_array_index(dk3app_scope_attributes, p1, 0))
+ {
+ case 0: { /* user */
+ if(dk3str_cmp(p3, dk3app_no_loc[33])) {
+ if(app->n_logname) {
+#if DK3_ON_WINDOWS || DK3_HAVE_USER_NAMES_CASE_INSENSITIVE
+ if(dk3str_casecmp(p3, app->n_logname)) {
+ conditions_ok = 0;
+ }
+#else
+ if(dk3str_cmp(p3, app->n_logname)) {
+ conditions_ok = 0;
+ }
+#endif
+ } else {
+ conditions_ok = 0;
+ }
+ }
+ } break;
+ case 1: { /* application */
+ if(dk3str_cmp(p3, dk3app_no_loc[33])) {
+ if(app->n_app) {
+#if DK3_ON_WINDOWS || DK3_HAVE_FNCASEINS
+ if(dk3str_casecmp(p3, app->n_app)) {
+ conditions_ok = 0;
+ }
+#else
+ if(dk3str_cmp(p3, app->n_app)) { conditions_ok = 0; }
+#endif
+ } else { conditions_ok = 0; }
+ }
+ } break;
+ case 2: { /* application-group */
+ if(dk3str_cmp(p3, dk3app_no_loc[33])) {
+ if(app->n_appgroup) {
+
+#if DK3_ON_WINDOWS || DK3_HAVE_FNCASEINS
+ if(dk3str_casecmp(p3, app->n_appgroup)) {
+ conditions_ok = 0;
+ }
+#else
+ if(dk3str_cmp(p3, app->n_appgroup)) {
+ conditions_ok = 0;
+ }
+#endif
+ } else { conditions_ok = 0; }
+ }
+ } break;
+ case 3: { /* host */
+ if(dk3str_cmp(p3, dk3app_no_loc[33])) {
+ if(app->n_hostname) {
+ if(dk3str_casecmp(p3, app->n_hostname)) {
+ conditions_ok = 0;
+ }
+ } else { conditions_ok = 0; }
+ }
+ } break;
+ case 4: { /* language */
+ if(dk3str_cmp(p3, dk3app_no_loc[33])) {
+ if(app->n_language) {
+ if(dk3str_cmp(p3, app->n_language)) {
+ conditions_ok = 0;
+ }
+ } else { conditions_ok = 0; }
+ }
+ } break;
+ case 5: { /* region */
+ if(dk3str_cmp(p3, dk3app_no_loc[33])) {
+ if(app->n_region) {
+ if(dk3str_cmp(p3, app->n_region)) {
+ conditions_ok = 0;
+ }
+ } else { conditions_ok = 0; }
+ }
+ } break;
+ }
+ }
+ }
+ p1 = p2;
+ }
+ last_was_scope = 1;
+ if(conditions_ok) {
+ if(scope_action) {
+ scope_valid = 0;
+ } else {
+ scope_valid = 1;
+ }
+ }
+ } else {
+ last_was_scope = 0;
+ if(scope_valid) {
+ dk3str_chomp(p1, NULL);
+ p2 = dk3str_chr(p1, dkT('='));
+ if(p2) {
+ *(p2++) = dkT('\0');
+ p2 = dk3str_start(p2, NULL);
+ if(p2) {
+ dk3str_chomp(p1, NULL);
+ dk3str_chomp(p2, NULL);
+ if(!dk3app_add_pref(NULL, s, i, p1, p2)) {
+ app->de = 33;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ fclose(fipo);
+ dk3app_set_source_file(app, oldsourcename);
+ dk3app_set_source_line(app, oldsourceline);
+ } else {
+ dk3app_log_i3(app, DK3_LL_DEBUG, 152, 153, fn);
+ }
+}
+
+
+
+/** Read all preference files for an application.
+ @param app Application structure.
+*/
+static
+void
+dk3app_read_preference_files(dk3_app_t *app)
+{
+ dkChar fnb[DK3_MAX_PATH]; /* File name buffer. */
+ int i = 0; /* Pass. */
+
+
+#line 5288 "dk3app.ctr"
+ for(i = 0; i < 16; i++) {
+ if(dk3app_config_name(app, dk3app_no_loc[21], fnb, DK3_MAX_PATH, i, 0)) {
+ switch(i) {
+ case 14: {
+
+#line 5292 "dk3app.ctr"
+ if(!(app->s_varprefs)) {
+ app->s_varprefs = dk3sto_open_app(NULL);
+ if(app->s_varprefs) {
+ dk3sto_set_comp(app->s_varprefs, dk3app_compare_pref, 0);
+ } else {
+ app->de = 36;
+ }
+ }
+ if(!(app->i_varprefs)) {
+ if(app->s_varprefs) {
+ app->i_varprefs = dk3sto_it_open(app->s_varprefs);
+ if(!(app->i_varprefs)) { app->de = 36; }
+ }
+ }
+ if((app->s_varprefs) && (app->i_varprefs)) {
+ dk3app_rd_pref_file(app, fnb, app->s_varprefs, app->i_varprefs);
+ }
+ } break;
+ case 12: case 13: case 15: {
+
+#line 5311 "dk3app.ctr"
+ if(!(app->s_constprefs)) {
+ app->s_constprefs = dk3sto_open_app(NULL);
+ if(app->s_constprefs) {
+ dk3sto_set_comp(app->s_constprefs, dk3app_compare_pref, 0);
+ } else {
+ app->de = 36;
+ }
+ }
+ if(!(app->i_constprefs)) {
+ if(app->s_constprefs) {
+ app->i_constprefs = dk3sto_it_open(app->s_constprefs);
+ if(!(app->i_constprefs)) { app->de = 36; }
+ }
+ }
+ if((app->s_constprefs) && (app->i_constprefs)) {
+ dk3app_rd_pref_file(app,fnb,app->s_constprefs,app->i_constprefs);
+ }
+ } break;
+ default: {
+
+#line 5330 "dk3app.ctr"
+ if(!(app->s_sysprefs)) {
+ app->s_sysprefs = dk3sto_open_app(NULL);
+ if(app->s_sysprefs) {
+ dk3sto_set_comp(app->s_sysprefs, dk3app_compare_pref, 0);
+ } else { app->de = 36; }
+ }
+ if(!(app->i_sysprefs)) {
+ if(app->s_sysprefs) {
+ app->i_sysprefs = dk3sto_it_open(app->s_sysprefs);
+ if(!(app->i_sysprefs)) { app->de = 36; }
+ }
+ }
+ if((app->s_sysprefs) && (app->i_sysprefs)) {
+ dk3app_rd_pref_file(app, fnb, app->s_sysprefs, app->i_sysprefs);
+ }
+ } break;
+ }
+ }
+ }
+
+#line 5349 "dk3app.ctr"
+}
+
+
+
+/** Find log level.
+ @param app Application structure.
+ @param ind Index of preference name in \a dk3app_no_loc.
+ @param buffer Buffer for preference value.
+ @param sz Size of \a buffer (number of characters).
+ @param dv Default value to use if preference is not set.
+ @return Log level found in preference or default value.
+*/
+static
+int
+dk3app_find_ll(dk3_app_t *app, int ind, dkChar *buffer, size_t sz, int dv)
+{
+ int back = 0;
+ dkChar *p1 = NULL; /* Value string. */
+ int i = 0; /* Index search result. */
+ back = dv;
+
+
+#line 5370 "dk3app.ctr"
+ if(dk3app_get_pref(app, dk3app_no_loc[ind], buffer, sz)) {
+
+#line 5371 "dk3app.ctr"
+ p1 = dk3str_start(buffer, NULL);
+ if(p1) {
+
+
+#line 5374 "dk3app.ctr"
+ dk3str_chomp(p1, NULL);
+
+
+#line 5376 "dk3app.ctr"
+ i = dk3str_array_abbr(dk3app_log_levels, p1, dkT('$'), 0);
+ if(i >= 0) {
+
+#line 5378 "dk3app.ctr"
+ if(i <= DK3_LL_IGNORE) {
+ back = i;
+
+#line 5380 "dk3app.ctr"
+ }
+ } else {
+
+#line 5382 "dk3app.ctr"
+ }
+ } else {
+
+#line 5384 "dk3app.ctr"
+ }
+ } else {
+
+#line 5386 "dk3app.ctr"
+ }
+
+#line 5387 "dk3app.ctr"
+ return back;
+}
+
+
+
+/** Preferences processing at application startup.
+ @param app Application structure.
+*/
+static
+void
+dk3app_process_preferences(dk3_app_t *app)
+{
+ dkChar buffer[4096];
+ dkChar *p1 = NULL; /* Start of language/region/encoding string. */
+ dkChar *p2 = NULL; /* Encoding, later region. */
+ dkChar *p3 = NULL; /* Used to convert to lower case. */
+ dkChar *p4 = NULL; /* New string for region. */
+ int i; /* Input encoding. */
+ if(dk3app_get_pref(app,dk3app_no_loc[27],buffer,DK3_SIZEOF(buffer,dkChar)))
+ {
+ p1 = dk3str_start(buffer, NULL);
+ if(p1) {
+ p2 = dk3str_chr(buffer, dkT('.'));
+ if(p2) { *p2 = dkT('\0'); }
+ p2 = dk3str_chr(buffer, dkT('_'));
+ if(p2) {
+ *(p2++) = dkT('\0');
+ p2 = dk3str_start(p2, NULL);
+ if(p2) {
+ dk3str_chomp(p2, NULL);
+ p3 = p2; while(*p3) { *p3 = dk3str_tolower(*p3); p3++; }
+ }
+ }
+ p3 = p1; while(*p3) { *p3 = dk3str_tolower(*p3); p3++; }
+ dk3str_chomp(p1, NULL);
+ p3 = dk3str_dup_app(p1, NULL);
+ p4 = NULL;
+ if(p2) { p4 = dk3str_dup_app(p2, NULL); }
+ if(p3) {
+ dk3_delete(app->n_language);
+ app->n_language = p3;
+ }
+ if(p4) {
+ dk3_delete(app->n_region);
+ app->n_region = p4;
+ }
+ }
+ }
+ app->ll_file = dk3app_find_ll(
+ app, 28, buffer, DK3_SIZEOF(buffer,dkChar), app->ll_file
+ );
+ app->ll_file_keep = dk3app_find_ll(
+ app, 29, buffer, DK3_SIZEOF(buffer,dkChar), app->ll_file_keep
+ );
+ app->ll_stderr = dk3app_find_ll(
+ app, 30, buffer, DK3_SIZEOF(buffer,dkChar), app->ll_stderr
+ );
+ app->ll_tmp_keep = dk3app_find_ll(
+ app, 31, buffer, DK3_SIZEOF(buffer,dkChar), app->ll_tmp_keep
+ );
+ app->i_stdin_input_encoding = dk3app_get_default_stdin_encoding(app);
+
+
+#line 5449 "dk3app.ctr"
+ app->i_file_input_encoding = dk3app_get_default_file_encoding(app);
+ if(dk3app_get_pref(app,dk3app_no_loc[51],buffer,DK3_SIZEOF(buffer,dkChar)))
+ {
+ p1 = dk3str_start(buffer, NULL);
+ if(p1) {
+ dk3str_chomp(p1, NULL);
+ i = dk3enc_get_text_encoding_app(buffer, NULL);
+ if(i >= 0) {
+ app->i_file_input_encoding = i;
+ }
+ }
+ }
+ if(dk3app_get_pref(app,dk3app_no_loc[52],buffer,DK3_SIZEOF(buffer,dkChar)))
+ {
+ p1 = dk3str_start(buffer, NULL);
+ if(p1) {
+ dk3str_chomp(p1, NULL);
+ i = dk3enc_get_text_encoding_app(buffer, NULL);
+ if(i >= 0) {
+ app->i_stdin_input_encoding = i;
+
+
+#line 5470 "dk3app.ctr"
+ }
+ }
+ }
+
+}
+
+
+
+/** Create new application.
+ @param wd Current working directory.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @param gn Application group name.
+ @param tp Application type.
+ @return Pointer to new application on success, NULL on error.
+*/
+static
+dk3_app_t *
+dk3app_open(
+ dkChar const * wd,
+ int argc, dkChar const * const * argv,
+ dkChar const *gn,
+ int tp
+)
+{
+ dk3_app_t *back = NULL;
+
+
+#line 5497 "dk3app.ctr"
+ back = dk3_new(dk3_app_t,1);
+ if(back) {
+ dk3app_init(back);
+ switch(tp) {
+ case DK3_APP_TYPE_DAEMON: {
+ back->ll_file = DK3_LL_INFO;
+ } break;
+ }
+ back->app_type = tp;
+ if(!(back->de)) { dk3app_save_group_name(back, gn); }
+ if(!(back->de)) { dk3app_first_silence_check(back, argc, argv); }
+ if(!(back->de)) { dk3app_language_and_region(back, argc, argv); }
+ if(!(back->de)) { dk3app_find_names(back, wd, argc, argv); }
+ if(!(back->de)) { dk3app_save_arguments(back, argc, argv); }
+ if(!(back->de)) { dk3app_read_preference_files(back); }
+ if(!(back->de)) { dk3app_process_preferences(back); }
+ if(!(back->de)) {
+ back->msg = dk3app_my_messages(back, dk3app_no_loc[23], dk3app_kw, 0);
+ }
+ back->f_readytolog = 1;
+ if(back->de) {
+ /* Delayed error occured. Report error, destroy structure. */
+ switch(back->de) {
+ case 1: /* Error while saving command line arguments. */
+ case 2: /* Error while saving application name. */
+ case 4: /* Error while saving exec file name. */
+ case 6: /* Error while saving bin directory. */
+ case 7: /* Error while saving etc directory. */
+ case 8: /* Error while saving share directory. */
+ case 9: /* Error while saving var directory. */
+ case 15: /* Error while saving logname. */
+ case 17: /* Error while saving home directory. */
+ case 18: /* Error while saving application group name. */
+ case 21: /* Error while saving log file name. */
+ case 25: /* Error while saving temp dir name. */
+ case 28: /* Error while saving language string. */
+ case 29: /* Failed to save region! */
+ case 30: /* Failed to save language! */
+ case 33: /* Pref */
+ case 34: /* Pref storage */
+ case 35: /* Cmd prefs iterator */
+ case 36: /* Cmd prefs storage */
+ case 37: /* Store host name */
+ {
+ dk3app_log_i1(back, DK3_LL_ERROR, 9);
+ } break;
+ case 3: /* Failed to find executable file name. */
+ {
+ /* Failed to find executable file name. */
+ dk3app_log_i1(back, DK3_LL_ERROR, 40);
+ } break;
+ case 5: /* Incomplete exec file name. */
+ {
+ /* No separator in executable file name! */
+ dk3app_log_i1(back, DK3_LL_ERROR, 40);
+ }
+ case 10: /* Program is started from root directory. */
+ {
+ /* Too few directories in hierarchy! */
+ dk3app_log_i1(back, DK3_LL_ERROR, 41);
+ } break;
+ case 11: /* Error while creating etc directory name! */
+ case 12: /* Error while creating share directory name! */
+ case 13: /* Error while creating var directory name! */
+ {
+ /* Name of executable file too long! */
+ dk3app_log_i1(back, DK3_LL_ERROR, 42);
+ } break;
+ case 14: { /* Failed to retrieve log name! */
+ /* Failed to retrieve log name! */
+ dk3app_log_i1(back, DK3_LL_ERROR, 43);
+ } break;
+ case 16: { /* Failed to retrieve home directory! */
+ /* Failed to retrieve home directory! */
+ dk3app_log_i1(back, DK3_LL_ERROR, 44);
+ } break;
+ case 19: { /* Log file name too long. */
+ /* Log file name gets too long! */
+ dk3app_log_i1(back, DK3_LL_ERROR, 45);
+ } break;
+ case 20: {
+ /* Failed to create log directory! */
+ dk3app_log_i1(back, DK3_LL_ERROR, 46);
+ } break;
+ case 22: {
+ /* Failed to convert PID to dkChar! */
+ dk3app_log_i1(back, DK3_LL_ERROR, 47);
+ } break;
+ case 23: {
+ /* Home directory name missing! */
+ dk3app_log_i1(back, DK3_LL_ERROR, 44);
+ } break;
+ case 24: {
+ /* Application name missing! */
+ dk3app_log_i1(back, DK3_LL_ERROR, 48);
+ } break;
+ case 26: {
+ /* Name of tmp dir gets too long! */
+ dk3app_log_i1(back, DK3_LL_ERROR, 49);
+ } break;
+ case 27: {
+ /* var dir name missing! */
+ dk3app_log_i1(back, DK3_LL_ERROR, 50);
+ } break;
+ case 31: {
+ /* Preference name too long! */
+ dk3app_log_i1(back, DK3_LL_ERROR, 51);
+ } break;
+ case 32: {
+ /* Not a preference entry! */
+ dk3app_log_i1(back, DK3_LL_ERROR, 52);
+ } break;
+ case 38: {
+ dk3app_log_i1(back, DK3_LL_ERROR, 131);
+ } break;
+ }
+ dk3app_close(back);
+ back = NULL;
+ } else {
+
+#line 5616 "dk3app.ctr"
+ dk3app_log_i3(back, DK3_LL_DEBUG, 19, 20, back->n_app);
+ dk3app_log_i2(
+ back, DK3_LL_DEBUG, 23,
+ ((back->n_app) ? back->n_app: ((back->msg) ? back->msg : dk3app_kw)[36])
+ );
+ dk3app_log_i2(
+ back, DK3_LL_DEBUG, 24,
+ ((back->n_appgroup) ? back->n_appgroup: ((back->msg) ? back->msg : dk3app_kw)[36])
+ );
+ dk3app_log_i2(
+ back, DK3_LL_DEBUG, 25,
+ ((back->n_execfile) ? back->n_execfile: ((back->msg) ? back->msg : dk3app_kw)[36])
+ );
+ dk3app_log_i2(
+ back, DK3_LL_DEBUG, 26,
+ ((back->n_bindir) ? back->n_bindir: ((back->msg) ? back->msg : dk3app_kw)[36])
+ );
+ dk3app_log_i2(
+ back, DK3_LL_DEBUG, 27,
+ ((back->n_etcdir) ? back->n_etcdir: ((back->msg) ? back->msg : dk3app_kw)[36])
+ );
+ dk3app_log_i2(
+ back, DK3_LL_DEBUG, 28,
+ ((back->n_sharedir) ? back->n_sharedir: ((back->msg) ? back->msg : dk3app_kw)[36])
+ );
+ dk3app_log_i2(
+ back, DK3_LL_DEBUG, 29,
+ ((back->n_vardir) ? back->n_vardir: ((back->msg) ? back->msg : dk3app_kw)[36])
+ );
+ dk3app_log_i2(
+ back, DK3_LL_DEBUG, 30,
+ ((back->n_homedir) ? back->n_homedir: ((back->msg) ? back->msg : dk3app_kw)[36])
+ );
+ dk3app_log_i2(
+ back, DK3_LL_DEBUG, 31,
+ ((back->n_tmpdir) ? back->n_tmpdir: ((back->msg) ? back->msg : dk3app_kw)[36])
+ );
+ dk3app_log_i2(
+ back, DK3_LL_DEBUG, 32,
+ ((back->n_logname) ? back->n_logname: ((back->msg) ? back->msg : dk3app_kw)[36])
+ );
+ dk3app_log_i2(
+ back, DK3_LL_DEBUG, 132,
+ ((back->n_hostname) ? back->n_hostname: ((back->msg) ? back->msg : dk3app_kw)[36])
+ );
+ dk3app_log_i2(
+ back, DK3_LL_DEBUG, 33,
+ ((back->n_logfilename) ? back->n_logfilename: ((back->msg) ? back->msg : dk3app_kw)[36])
+ );
+ dk3app_log_i2(
+ back, DK3_LL_DEBUG, 34,
+ ((back->n_language) ? back->n_language: ((back->msg) ? back->msg : dk3app_kw)[36])
+ );
+ dk3app_log_i2(
+ back, DK3_LL_DEBUG, 35,
+ ((back->n_region) ? back->n_region: ((back->msg) ? back->msg : dk3app_kw)[36])
+ );
+ }
+ } else {
+ if(tp == DK3_APP_TYPE_COMMAND) {
+ /* ERROR: Not enough memory */
+ dk3sf_initialize_stderr();
+ dk3sf_fputs(dk3app_kw[9], stderr);
+ dk3sf_fputs(dk3app_kw[0], stderr);
+ fflush(stderr);
+ }
+ }
+
+#line 5683 "dk3app.ctr"
+ return back;
+}
+
+
+
+dk3_app_t *
+dk3app_open_command(int argc, dkChar const * const * argv, dkChar const *gn)
+{
+ dk3_app_t *back = NULL;
+ dkChar wd[DK3_MAX_PATH]; /* Current working directory. */
+ if((argc) && (argv) && (gn)) {
+ if(dk3sf_getcwd_app(wd, DK3_SIZEOF(wd,dkChar), NULL)) {
+ back = dk3app_open(wd, argc, argv, gn, DK3_APP_TYPE_COMMAND);
+ } else {
+ /* ERROR: Failed to find current working directory. */
+ if(!dk3app_first_silence_check(NULL, argc, argv)) {
+ dk3sf_initialize_stderr();
+ dk3sf_fputs(dk3app_kw[3], stderr);
+ dk3sf_fputs(dk3app_kw[11], stderr);
+ dk3sf_fputs(dk3app_kw[8], stderr);
+ dk3sf_fputs(dk3app_kw[53], stderr);
+ dk3sf_fputs(dk3app_kw[0], stderr);
+ fflush(stderr);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+dk3_app_t *
+dk3app_open_gui(int argc, dkChar const * const * argv, dkChar const *gn)
+{
+ dk3_app_t *back = NULL;
+ dkChar wd[DK3_MAX_PATH]; /* Current working directory. */
+ if((argc) && (argv) && (gn)) {
+ if(dk3sf_getcwd_app(wd, DK3_SIZEOF(wd,dkChar),NULL)) {
+ back = dk3app_open(wd, argc, argv, gn, DK3_APP_TYPE_GUI);
+ } else {
+ /* ERROR: Failed to find current working directory. */
+ }
+ }
+ return back;
+}
+
+
+
+dk3_app_t *
+dk3app_open_daemon(
+ dkChar const *wd, int argc, dkChar const * const * argv, dkChar const *gn
+)
+{
+ dk3_app_t *back = NULL;
+ if((wd) && (argc) && (argv) && (gn)) {
+ back = dk3app_open(wd, argc, argv, gn, DK3_APP_TYPE_DAEMON);
+ }
+ return back;
+}
+
+
+
+dk3_app_t *
+dk3app_open_silent(int argc, dkChar const * const * argv, dkChar const *gn)
+{
+ dk3_app_t *back = NULL;
+ dkChar wd[DK3_MAX_PATH]; /* Current working directory. */
+ if((argc) && (argv) && (gn)) {
+ if(dk3sf_getcwd_app(wd, DK3_SIZEOF(wd,dkChar),NULL)) {
+ back = dk3app_open(wd, argc, argv, gn, DK3_APP_TYPE_SILENT);
+ } else {
+ /* ERROR: Failed to find current working directory. */
+ }
+ }
+ return back;
+}
+
+
+
+dkChar const * const *
+dk3app_get_argv(dk3_app_t const *app)
+{
+ dkChar const * const *back = NULL;
+ if(app) { back = (dkChar const * const *)(app->argv); }
+ return back;
+}
+
+
+
+int
+dk3app_get_argc(dk3_app_t const *app)
+{
+ int back = 0;
+ if(app) { back = app->argc; }
+ return back;
+}
+
+
+
+dkChar const *
+dk3app_get_appname(dk3_app_t const *app)
+{
+ dkChar const *back = NULL;
+ if(app) {
+ back = app->n_app;
+ }
+
+#line 5789 "dk3app.ctr"
+ return back;
+}
+
+
+
+dkChar const *
+dk3app_get_execfilename(dk3_app_t const *app)
+{
+ dkChar const *back = NULL;
+ if(app) {
+ back = app->n_execfile;
+ }
+ return back;
+}
+
+
+
+dkChar const *
+dk3app_get_bindir(dk3_app_t const *app)
+{
+ dkChar const *back = NULL;
+ if(app) {
+ back = app->n_bindir;
+ }
+ return back;
+}
+
+
+
+dkChar const *
+dk3app_get_etcdir(dk3_app_t const *app)
+{
+ dkChar const *back = NULL;
+ if(app) {
+ back = app->n_etcdir;
+ }
+ return back;
+}
+
+
+
+dkChar const *
+dk3app_get_sharedir(dk3_app_t const *app)
+{
+ dkChar const *back = NULL;
+ if(app) {
+ back = app->n_sharedir;
+ }
+ return back;
+}
+
+
+
+dkChar const *
+dk3app_get_vardir(dk3_app_t const *app)
+{
+ dkChar const *back = NULL;
+ if(app) {
+ back = app->n_vardir;
+ }
+ return back;
+}
+
+
+
+dkChar const *
+dk3app_get_logname(dk3_app_t const *app)
+{
+ dkChar const *back = NULL;
+ if(app) {
+ back = app->n_logname;
+ }
+ return back;
+}
+
+
+
+dkChar const *
+dk3app_get_hostname(dk3_app_t const *app)
+{
+ dkChar const *back = NULL;
+ if(app) {
+ back = app->n_hostname;
+ }
+ return back;
+}
+
+
+
+dkChar const *
+dk3app_get_homedir(dk3_app_t const *app)
+{
+ dkChar const *back = NULL;
+ if(app) {
+ back = app->n_homedir;
+ }
+ return back;
+}
+
+
+
+dkChar const *
+dk3app_get_appgroup(dk3_app_t const *app)
+{
+ dkChar const *back = NULL;
+ if(app) {
+ back = app->n_appgroup;
+ }
+ return back;
+}
+
+
+
+int
+dk3app_get_temp_file_name(dk3_app_t *app, dkChar *db, size_t sz)
+{
+ int back = 0;
+ char fn[16]; /* BUffer for sprintf(). */
+ dkChar fn2[16]; /* Short file name buffer. */
+ size_t s = 0; /* Buffer length needed. */
+
+
+#line 5910 "dk3app.ctr"
+ if((app) && (db) && (sz)) {
+ if(app->n_tmpdir) {
+ if ((DK3_APP_TYPE_DAEMON != app->app_type) && (0 == app->cr_tmp)) {
+ dk3app_create_tmp_directory(app);
+ app->cr_tmp = 1;
+ }
+ if(!(app->i_tmpcarry)) {
+ sprintf(fn, "/%08lx.%03x", app->ul_tmpname, app->u_tmpsuffix);
+ back = 1;
+ if ((0UL == app->ul_tmpname) && (0 == app->u_tmpsuffix)) {
+ if (DK3_APP_TYPE_DAEMON != app->app_type) {
+
+
+#line 5922 "dk3app.ctr"
+
+
+#line 5923 "dk3app.ctr"
+ if (0 == dk3sf_mkdir_app(app->n_tmpdir, 0700, NULL)) {
+ back = 0;
+ }
+ }
+ }
+ app->u_tmpsuffix += 1U;
+ if(app->u_tmpsuffix >= 0x1000U) {
+ app->u_tmpsuffix = 0U;
+#if VERSION_BEFORE_20150318
+ app->ul_tmpname += 1UL;
+ if(app->ul_tmpname == 0UL) {
+ app->i_tmpcarry = 1;
+ back = 0;
+ /* Too many temporary file names asked! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 54);
+ }
+#else
+ /* 2015-03-18 We better check the variable before adding 1.
+ Unsigned long may be larger than 32 bits.
+ */
+ if (0xFFFFFFFFUL > app->ul_tmpname) {
+ app->ul_tmpname += 1UL;
+ } else {
+ app->i_tmpcarry = 1;
+ back = 0;
+ /* Too many temporary file names asked! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 54);
+ }
+#endif
+ }
+ if(back) {
+ back = 0;
+ if(dk3str_cnv_c8_to_str_app(fn2, 15, fn, app)) {
+ s = dk3str_len(app->n_tmpdir) + dk3str_len(fn2);
+ if(s < sz) {
+ dk3str_cpy_not_overlapped(db, app->n_tmpdir);
+ dk3str_cat(db, fn2);
+ dk3str_correct_filename(db);
+ back = 1;
+ } else {
+ /* Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ }
+ } else {
+ /* Not directory for temporary files available! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 55);
+ }
+ }
+
+#line 5974 "dk3app.ctr"
+ return back;
+}
+
+
+
+dkChar const *
+dk3app_get_language(dk3_app_t const *app)
+{
+ dkChar const *back = NULL;
+ if(app) { back = app->n_language; }
+ return back;
+}
+
+
+
+dkChar const *
+dk3app_get_region(dk3_app_t const *app)
+{
+ dkChar const *back = NULL;
+ if(app) { back = app->n_region; }
+ return back;
+}
+
+
+
+int
+dk3app_get_encoding(dk3_app_t const *app)
+{
+ int back = 0;
+ if(app) { back = app->i_encoding; }
+ return back;
+}
+
+
+
+int
+dk3app_get_output_encoding(dk3_app_t const *app)
+{
+ int back = 0;
+ if(app) { back = app->i_output_encoding; }
+ return back;
+}
+
+
+
+int
+dk3app_get_input_stdin_encoding(dk3_app_t const *app)
+{
+ int back = 0;
+ if(app) { back = app->i_stdin_input_encoding; }
+ return back;
+}
+
+
+
+int
+dk3app_get_input_file_encoding(dk3_app_t const *app)
+{
+ int back = 0;
+ if(app) { back = app->i_file_input_encoding; }
+ return back;
+}
+
+
+
+int
+dk3app_set_pref(dk3_app_t *app, dkChar const *k, dkChar const *v)
+{
+ int back = 0;
+ if((app) && (k) && (v)) {
+ if(!(app->s_selfprefs)) {
+ app->s_selfprefs = dk3sto_open_app(app);
+ if(app->s_selfprefs) {
+ dk3sto_set_comp(app->s_selfprefs, dk3app_compare_pref, 0);
+ }
+ }
+ if(!(app->i_selfprefs)) {
+ if(app->s_selfprefs) {
+ app->i_selfprefs = dk3sto_it_open(app->s_selfprefs);
+ }
+ }
+ if((app->s_selfprefs) && (app->i_selfprefs)) {
+ back = dk3app_add_pref(app, app->s_selfprefs, app->i_selfprefs, k, v);
+ app->f_prefschanged = 1;
+ }
+ if(!back) {
+ /* Failed to save preference value! */
+ dk3app_log_i5(app, DK3_LL_ERROR, 56, 57, 58, k, v);
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3app_get_pref(dk3_app_t *app, dkChar const *k, dkChar *d, size_t s)
+{
+ int back = 0;
+
+
+#line 6074 "dk3app.ctr"
+ if((app) && (k) && (d) && (s)) {
+
+
+#line 6076 "dk3app.ctr"
+ back = dk3app_sto_pref(app, app->i_selfprefs, k, d, s);
+ if(back == 0) {
+ back = dk3app_sto_pref(app, app->i_cmdprefs, k, d, s);
+ if(back == 0) {
+ back = dk3app_sto_pref(app, app->i_varprefs, k, d, s);
+ if(back == 0) {
+ back = dk3app_sto_pref(app, app->i_constprefs, k, d, s);
+ if(back == 0) {
+ back = dk3app_sto_pref(app, app->i_sysprefs, k, d, s);
+ }
+ }
+ }
+ }
+
+
+#line 6090 "dk3app.ctr"
+
+
+#line 6091 "dk3app.ctr"
+
+
+#line 6092 "dk3app.ctr"
+ }
+
+#line 6093 "dk3app.ctr"
+ return back;
+}
+
+
+
+int
+dk3app_get_sys_pref(dk3_app_t *app, dkChar const *k, dkChar *d, size_t s)
+{
+ int back = 0;
+ if((app) && (k) && (d) && (s)) {
+ back = dk3app_sto_pref(app, app->i_selfprefs, k, d, s);
+ if(back == 0) {
+ back = dk3app_sto_pref(app, app->i_sysprefs, k, d, s);
+ }
+ }
+ return back;
+}
+
+
+
+/** Check whether the use of system configuration files
+ is allowed for a file name.
+ @param app Application structure.
+ @param fn Short file name.
+ @return 1 for system config files allowed, 0 for user files only.
+*/
+static
+int
+dk3app_allow_system_config_files(dk3_app_t *app, dkChar const *fn)
+{
+ int back = 1;
+ dkChar fnb[DK3_MAX_PATH]; /* File name buffer. */
+ dkChar il[1024 + DK3_MAX_PATH]; /* Input line buffer. */
+ char bombuf[4]; /* Buffer to skip BOM. */
+ dkChar *p1 = NULL; /* Key (entry name). */
+ dkChar *p2 = NULL; /* Value. */
+ FILE *fipo = NULL; /* Input file. */
+ int ie = DK3_FILE_ENCODING_ASCII; /* Input encoding for file. */
+ int cc = 1; /* Flag: Can continue. */
+ size_t sz = 0; /* Buffer size needed. */
+ size_t skb; /* Number of bytes to skip. */
+ if(app->n_homedir) {
+ sz = dk3str_len(app->n_homedir);
+ sz += (2 * dk3str_len(dk3app_no_loc[20]));
+ sz += dk3str_len(dk3app_no_loc[18]);
+ sz += dk3str_len(dk3app_no_loc[34]);
+ if(sz < DK3_SIZEOF(fnb,dkChar)) {
+ dk3str_cpy_not_overlapped(fnb, app->n_homedir);
+ dk3str_cat(fnb, dk3app_no_loc[20]);
+ dk3str_cat(fnb, dk3app_no_loc[18]);
+ dk3str_cat(fnb, dk3app_no_loc[20]);
+ dk3str_cat(fnb, dk3app_no_loc[34]);
+ skb = 0;
+ ie = dk3sf_inspect_bom_skip_app(fnb, DK3_FILE_ENCODING_ASCII, &skb, NULL);
+ fipo = dk3sf_fopen_app(fnb, dk3app_no_loc[22], NULL); /* READ */
+ if(fipo) {
+ (void)dk3sf_apply_bom_to_file_app(fipo, ie, NULL);
+ cc = 1;
+ if((skb > 0) && (skb <= 4)) {
+ dk3sf_fread_app(bombuf, 1, skb, fipo, NULL);
+ }
+ while(cc) {
+ if(dk3sf_fgets(il, DK3_SIZEOF(il,dkChar), fipo)) {
+ p1 = dk3str_start(il, NULL);
+ if(p1) {
+ if(*p1 != dkT('#')) {
+ p2 = dk3str_chr(p1, dkT('='));
+ if(p2) {
+ *(p2++) = dkT('\0');
+ p2 = dk3str_start(p2, NULL);
+ if(p2) {
+ dk3str_chomp(p2, NULL);
+ dk3str_normalize(p1, NULL, dkT('-'));
+ switch(dk3str_array_index(dk3app_conf_file, p1, 0)) {
+ case 0: { /* use system config files */
+ if(dk3str_cmp(p2, dk3app_no_loc[33]) == 0) {
+ back = 1; cc = 0;
+ } else {
+ if(dk3str_cmp(p2, fn) == 0) {
+ back = 1; cc = 0;
+ }
+ }
+ } break;
+ case 1: { /* ignore system config files */
+ if(dk3str_cmp(p2, dk3app_no_loc[33]) == 0) {
+ back = 0; cc = 0;
+ } else {
+ if(dk3str_cmp(p2, fn) == 0) {
+ back = 0; cc = 0;
+ }
+ }
+ } break;
+ }
+ }
+ }
+ }
+ }
+ } else { cc = 0;}
+ }
+ fclose(fipo);
+ }
+ } else {
+ /* ERROR: Home directory name too long! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 194);
+ }
+ }
+ return back;
+}
+
+
+
+/** Find configuration files for a given name.
+ @param app Application structure.
+ @param fn File name.
+ @param res Flag: Reverse search order.
+ @param exclu Flag: Exclude user files.
+ @return Pointer to search result collection on success, NULL on error.
+*/
+static
+dk3_search_t *
+dk3app_my_find_config_file(dk3_app_t *app, dkChar const *fn, int res, int exclu)
+{
+ dk3_search_t *back = NULL;
+ unsigned long items_found = 0; /* Number of items found. */
+ int error_occured = 0; /* Flag: Error occured. */
+ int i = 0; /* Current pass number. */
+ int r = 0; /* Result from check for conf file. */
+ int max = 0; /* Maximum pass number. */
+ int min = 0; /* Minimum pass number. */
+ dkChar buffer[DK3_MAX_PATH]; /* File name buffer. */
+ if((app) && (fn)) {
+ back = dk3search_open_app(res, app);
+ if(back) {
+ min = 0; max = 16;
+ if(app->app_type == DK3_APP_TYPE_DAEMON) {
+ max = 6;
+ } else {
+ if(exclu) {
+ max = 12;
+ } else {
+ if(!dk3app_allow_system_config_files(app, fn)) {
+ min = 12;
+ /* DEBUG: System config files skipped by user. */
+ dk3app_log_i1(app, DK3_LL_DEBUG, 195);
+ }
+ }
+ }
+ for(i = min; i < max; i++) {
+ r = dk3app_check_config_file(app, fn, buffer, DK3_MAX_PATH, i, 1);
+ if(r) {
+ if(dk3search_add(back, buffer)) {
+ items_found++;
+ } else {
+ error_occured = 1;
+ }
+ }
+ }
+ if(error_occured) {
+ dk3search_close(back); back = NULL;
+ } else {
+ if(items_found == 0UL) {
+ dk3search_close(back); back = NULL;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+dk3_search_t *
+dk3app_find_config_file(dk3_app_t *app, dkChar const *fn, int exclu)
+{
+ dk3_search_t *back = NULL;
+ if((app) && (fn)) {
+ back = dk3app_my_find_config_file(app, fn, 0, exclu);
+ }
+ return back;
+}
+
+
+
+dk3_search_t *
+dk3app_find_config_file_revers(dk3_app_t *app, dkChar const *fn, int exclu)
+{
+ dk3_search_t *back = NULL;
+ if((app) && (fn)) {
+ back = dk3app_my_find_config_file(app, fn, 1, exclu);
+ }
+ return back;
+}
+
+
+
+int
+dk3app_find_data_file(dk3_app_t *app, dkChar const *fn, dkChar *db, size_t sz)
+{
+ int back = 0;
+ if((app) && (fn) && (db) && (sz)) {
+ back = dk3app_my_find_data_file(app, fn, db, sz, 1);
+ }
+ return back;
+}
+
+
+
+void
+dk3app_unconfigure(dk3_app_t *app)
+{
+ if(app) { app->f_unconfigure = 1; }
+}
+
+
+
+dkChar const * const *
+dk3app_messages(dk3_app_t *app, dkChar const *fn, dkChar const * const *dv)
+{
+ dkChar const * const *back;
+
+
+#line 6313 "dk3app.ctr"
+ back = dk3app_my_messages(app, fn, dv, 0);
+
+
+#line 6315 "dk3app.ctr"
+ return back;
+}
+
+
+
+void
+dk3app_help(dk3_app_t *app, dkChar const *fn, dkChar const * const *dt)
+{
+ int had_success = 0; /* Flag: Success. */
+ dkChar buffer[DK3_MAX_PATH]; /* File name buffer. */
+ char lb[1024]; /* Input line buffer. */
+ dkChar db[1024]; /* Output line buffer. */
+ FILE *fipo = NULL; /* Input file. */
+ dkChar const * const *ptr = NULL; /* Help text line. */
+
+
+#line 6330 "dk3app.ctr"
+ if((app) && (fn) && (dt)) {
+ dk3sf_initialize_stdout();
+ if(dk3app_my_find_data_file(app, fn, buffer, DK3_SIZEOF(buffer,dkChar), 0))
+ {
+ fipo = dk3sf_fopen_app(buffer, dk3app_no_loc[22], app); /* UTF-8 */
+ if(fipo) {
+ had_success = 1;
+ while(fgets(lb, sizeof(lb), fipo)) {
+
+#line 6338 "dk3app.ctr"
+#if DK3_CHAR_SIZE == 2
+ if(dk3str_cnv_c8u_to_c16_app(db, DK3_SIZEOF(db,dkChar), lb, app)) {
+ dk3sf_fputs(db, stdout);
+ }
+#else
+ switch(app->i_encoding) {
+ case DK3_ENCODING_PLAIN: {
+ if(dk3str_cnv_c8u_to_c8p_app(db, DK3_SIZEOF(db,dkChar), lb, app))
+ {
+ fputs(db, stdout);
+ }
+ } break;
+ default: {
+ fputs(lb, stdout);
+ } break;
+ }
+#endif
+ }
+ fclose(fipo);
+ }
+ }
+ if(!had_success) {
+ ptr = dt;
+ while(*ptr) {
+ dk3sf_fputs(*(ptr++), stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ }
+ }
+
+#line 6367 "dk3app.ctr"
+}
+
+
+
+int
+dk3app_get_stderr_log_level(dk3_app_t const *app)
+{
+ int back = DK3_LL_ERROR;
+ if(app) {
+ back = app->ll_stderr;
+ }
+ return back;
+}
+
+
+
+void
+dk3app_set_stderr_log_level(dk3_app_t *app, int ll)
+{
+ if(app) {
+ app->ll_stderr = ll;
+ }
+}
+
+
+
+void
+dk3app_log_write_error(dk3_app_t *app, int ll, size_t wished, size_t written)
+{
+ dkChar b1[128]; /* Number of bytes wished to write. */
+ dkChar b2[128]; /* Number of bytes really written. */
+
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(b1,dk3app_no_loc[35],((unsigned long)wished));
+ dk3sf_sprintf3(b2,dk3app_no_loc[35],((unsigned long)written));
+ dk3app_log_i5(app, ll, 170, 171, 172, b2, b1);
+#else
+ if (dk3ma_um_to_string(b1, DK3_SIZEOF(b1,dkChar), (dk3_um_t)wished)) {
+ if (dk3ma_um_to_string(b2, DK3_SIZEOF(b2,dkChar), (dk3_um_t)written)) {
+ dk3app_log_i5(app, ll, 170, 171, 172, b2, b1);
+ }
+ }
+#endif
+}
+
+
+
+void
+dk3app_log_fwrite_error(dk3_app_t *app, int ll, size_t wished, size_t written)
+{
+ dkChar b1[128]; /* Number of bytes wished to write. */
+ dkChar b2[128]; /* Number of bytes really written. */
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(b1,dk3app_no_loc[35],((unsigned long)wished));
+ dk3sf_sprintf3(b2,dk3app_no_loc[35],((unsigned long)written));
+ dk3app_log_i5(app, ll, 174, 175, 176, b2, b1);
+#else
+ if (dk3ma_um_to_string(b1, DK3_SIZEOF(b1,dkChar), (dk3_um_t)wished)) {
+ if (dk3ma_um_to_string(b2, DK3_SIZEOF(b2,dkChar), (dk3_um_t)written)) {
+ dk3app_log_i5(app, ll, 174, 175, 176, b2, b1);
+ }
+ }
+#endif
+}
+
+
+
+dkChar const *
+dk3app_localized(dk3_app_t const *app, size_t num)
+{
+ dkChar const *back = NULL;
+ if(app) {
+ if(app->msg) {
+ back = (app->msg)[num];
+ } else {
+ back = dk3app_kw[num];
+ }
+ }
+ return back;
+}
+
+
+
+dkChar const *
+dk3app_not_localized(size_t num)
+{
+ dkChar const *back = NULL;
+ back = dk3app_no_loc[num];
+ return back;
+}
+
+
+
+int
+dk3app_get_pref_bool(dk3_app_t *app, dkChar const *name, int dv)
+{
+ int back;
+ dkChar buffer[256]; /* Buffer for preference value. */
+ dkChar *p1; /* Start of text. */
+ back = dv;
+ if(app) {
+ if(dk3app_get_pref(app, name, buffer, DK3_SIZEOF(buffer,dkChar))) {
+ p1 = dk3str_start(buffer, NULL);
+ if(p1) {
+ dk3str_chomp(p1, NULL);
+ if(dk3str_is_bool(p1)) {
+ back = ((dk3str_is_on(p1)) ? 1 : 0);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3app_get_pref_int(dk3_app_t *app, dkChar const * name, int dv)
+{
+ int back;
+ int x;
+ dkChar buffer[256];
+ dkChar *p1;
+
+
+#line 6491 "dk3app.ctr"
+ back = dv;
+ if(app) {
+ if(dk3app_get_pref(app, name, buffer, DK3_SIZEOF(buffer,dkChar))) {
+ p1 = dk3str_start(buffer, NULL);
+ if(p1) {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(p1, dkT("%d"), &x) == 1)
+#else
+ if (0 != dk3ma_i_from_string(&x, p1, NULL))
+#endif
+ {
+ back = x;
+ }
+ }
+ }
+ }
+
+#line 6507 "dk3app.ctr"
+ return back;
+}
+
+
+
+#if 0
+
+
+int
+dk3app_get_allowed_prng_types(dk3_app_t *app, dkChar const *il)
+{
+ int back = 0;
+ dkChar buffer[256];
+ dkChar *p1 = NULL;
+ dkChar *p2 = NULL;
+ int i = 0;
+ if((app) && (il)) {
+ if(dk3str_len(il) < DK3_SIZEOF(buffer,dkChar)) {
+ dk3str_cpy_not_overlapped(buffer, il);
+ p1 = dk3str_start(buffer, NULL);
+ while(p1) {
+ p2 = dk3str_chr(p1, dkT(','));
+ if(p2) {
+ *(p2++) = dkT('\0'); p2 = dk3str_start(p2, NULL);
+ }
+ i = dk3str_array_index(dk3app_prng_type_names, p1, 0);
+ switch(i) {
+ case 0: {
+#if DK3_HAVE_OPENSSL_RAND_H
+ back |= DK3_PRNG_OPENSSL;
+#else
+ /* ERROR: Openssl PRNG not available! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 192);
+#endif
+ } break;
+ case 1: {
+#if DK3_HAVE_INITSTATE && DK3_HAVE_SETSTATE && DK3_HAVE_RANDOM
+ back |= DK3_PRNG_STATE;
+#else
+ /* ERROR: initstate()/setstate()/random() not available. */
+ dk3app_log_i1(app, DK3_LL_ERROR, 191);
+#endif
+ } break;
+ case 2: {
+#if DK3_HAVE_NRAND48 && DK3_HAVE_LRAND48
+ back |= DK3_PRNG_RAND48;
+#else
+ /* ERROR: lrand48()/lrand48() not available. */
+ dk3app_log_i1(app, DK3_LL_ERROR, 190);
+#endif
+ } break;
+ case 3: {
+#if DK3_HAVE_RAND && DK3_HAVE_SRAND
+ back |= DK3_PRNG_SIMPLE;
+#else
+ /* ERROR: srand()/rand() not available! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 189);
+#endif
+ } break;
+ default: {
+ /* Unknown PRNG type name! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 187, 188, p1);
+ } break;
+ }
+ p1 = p2;
+ }
+ } else {
+ /* ERROR: Line too long for buffer! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ return back;
+}
+
+
+
+/** Find allowed PRNG types using preferences.
+ @param app Application structure.
+ @return Or-combination of DK3_PRNG_xxx.
+*/
+static
+int
+dk3app_rand_find_allowed_types(dk3_app_t *app)
+{
+ int back = DK3_PRNG_ALL;
+ dkChar buffer[256];
+
+
+#line 6594 "dk3app.ctr"
+ if(dk3app_get_pref(app,dk3app_no_loc[37],buffer,DK3_SIZEOF(buffer,dkChar)))
+ {
+
+#line 6596 "dk3app.ctr"
+ back = dk3app_get_allowed_prng_types(app, buffer);
+ }
+
+
+#line 6599 "dk3app.ctr"
+ return back;
+}
+
+
+
+/** Get bytes to seed random number generator.
+ @param app Application structure.
+ @param dp Destination buffer pointer.
+ @param sz Number of bytes required.
+ @param fn File name for seed file.
+ @return Number of bytes found.
+*/
+static
+size_t
+dk3app_read_bytes_from_file(
+ dk3_app_t *app,
+ void *dp,
+ size_t sz,
+ dkChar const *fn
+)
+{
+ size_t back = 0;
+ FILE *fipo;
+ fipo = dk3sf_fopen_app(fn, dk3app_no_loc[36], app);
+ if(fipo) {
+ back = dk3sf_fread_app(dp, 1, sz, fipo, app);
+ fclose(fipo);
+ }
+ return back;
+}
+
+
+
+
+/** Get bytes to seed random number generator.
+ @param app Application structure.
+ @param dp Destination buffer pointer.
+ @param sz Number of bytes required.
+ @param fn File name for seed file.
+ @return Number of bytes found.
+*/
+static
+size_t
+dk3app_get_seed_from_source(dk3_app_t *app,void *dp,size_t sz,dkChar const *fn)
+{
+ size_t back = 0;
+ dk3_stat_t stb;
+ int can_use_file = 1;
+ int mode_denied;
+
+
+#line 6649 "dk3app.ctr"
+ /* DEBUG: Attempting to get seed data from ... */
+ dk3app_log_i3(app, DK3_LL_DEBUG, 196, 197, fn);
+ if(dk3sf_stat_app(&stb, fn, NULL)) {
+
+#line 6652 "dk3app.ctr"
+ switch((stb.ft) & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_DIRECTORY: {
+ /* Ignore it. */
+ } break;
+ case DK3_FT_REGULAR: {
+ /* Security checks before using the file. */
+ mode_denied = DK3_FPERM_G_READ
+ | DK3_FPERM_G_WRITE
+ | DK3_FPERM_O_READ
+ | DK3_FPERM_O_WRITE;
+ if((stb.ft) & DK3_FT_SYMLINK) {
+ if((stb.ai) & DK3_STAT_AI_USER_DIFFERS) {
+ can_use_file = 0;
+ /* WARNING: Symlink owner is not file owner. */
+ dk3app_log_i3(app, DK3_LL_ERROR, 185, 186, fn);
+ }
+ if((stb.perm) & mode_denied) {
+ can_use_file = 0;
+ /* WARNING: File not used (permissions). */
+ dk3app_log_i3(app, DK3_LL_ERROR, 183, 184, fn);
+ } else {
+ if((stb.lperm) & mode_denied) {
+ can_use_file = 0;
+ /* WARNING: File not used (permissions). */
+ dk3app_log_i3(app, DK3_LL_ERROR, 183, 184, fn);
+ }
+ }
+ } else {
+ if((stb.perm) & mode_denied) {
+ can_use_file = 0;
+ /* WARNING: File not used (permissions). */
+ dk3app_log_i3(app, DK3_LL_ERROR, 183, 184, fn);
+ }
+ }
+ if(can_use_file) {
+ back = dk3app_read_bytes_from_file(app, dp, sz, fn);
+ }
+ } break;
+ default: {
+ /* Use file. */
+ back = dk3app_read_bytes_from_file(app, dp, sz, fn);
+ } break;
+ }
+ }
+
+#line 6696 "dk3app.ctr"
+ /* DEBUG: Seed data: ... bytes. */
+ {
+ char b1[64];
+ dkChar b2[64];
+ sprintf(b1, "%lu", (unsigned long)back);
+ if(dk3str_cnv_c8_to_str_app(b2, DK3_SIZEOF(b2,dkChar), b1, app)) {
+ dk3app_log_i3(app, DK3_LL_DEBUG, 198, 199, b2);
+ }
+ }
+ return back;
+}
+
+
+
+/** Get bytes to seed random number generator.
+ @param app Application structure.
+ @param dp Destination buffer pointer.
+ @param sz Number of bytes required.
+ @param fn File name for seed file.
+ @param passno Pass number (only 0 uses files).
+ @return Number of bytes found.
+*/
+static
+size_t
+dk3app_get_seed_bytes(
+ dk3_app_t *app,
+ void *dp,
+ size_t sz,
+ dkChar const *fn,
+ int passno
+)
+{
+ size_t back = 0;
+ dkChar const *p1;
+ dkChar const *p2;
+ dkChar const *p3;
+ dkChar const *p4;
+ dkChar const *p5;
+ dkChar *p6;
+ size_t s;
+ dkChar fnb[DK3_MAX_PATH]; /* File name buffer. */
+ if((app) && (dp) && (sz)) {
+ /* $HOME/.rnd-xxx-application */
+ if(passno == 0) {
+ if(dk3app_get_pref_bool(app, dk3app_no_loc[46], 1)) {
+ p1 = dk3app_get_homedir(app);
+ p2 = dk3app_no_loc[20];
+ p3 = fn;
+ p4 = dk3app_no_loc[5];
+ p5 = dk3app_get_appname(app);
+ if((p1) && (p2) && (p3) && (p4) && (p5)) {
+ s = dk3str_len(p1);
+ s += dk3str_len(p2);
+ s += dk3str_len(p3);
+ s += dk3str_len(p4);
+ s += dk3str_len(p5);
+ if(s < DK3_SIZEOF(fnb,dkChar)) {
+ dk3str_cpy_not_overlapped(fnb, p1);
+ dk3str_cat(fnb, p2);
+ dk3str_cat(fnb, p3);
+ dk3str_cat(fnb, p4);
+ dk3str_cat(fnb, p5);
+ back = dk3app_get_seed_from_source(app, dp, sz, fnb);
+ }
+ }
+ }
+ }
+ /* EGD socket from environment. */
+ if(back == 0) {
+ p1 = dk3sf_getenv(dk3app_no_loc[43]);
+ if(p1) {
+ back = dk3app_get_seed_from_source(app, dp, sz, p1);
+ }
+ }
+ /* EGD socket from preferences. */
+ if(back == 0) {
+ if(dk3app_get_pref(app, dk3app_no_loc[42], fnb, DK3_SIZEOF(fnb,dkChar)))
+ {
+ p6 = dk3str_start(fnb, NULL);
+ if(p6) {
+ dk3str_chomp(p6, NULL);
+ back = dk3app_get_seed_from_source(app, dp, sz, p6);
+ }
+ }
+ }
+#if !DK3_ON_WINDOWS
+ /* /dev/urandom */
+ if(back == 0) {
+ back = dk3app_get_seed_from_source(app, dp, sz, dk3app_no_loc[44]);
+ }
+ /* /dev/random */
+ if(back == 0) {
+ back = dk3app_get_seed_from_source(app, dp, sz, dk3app_no_loc[45]);
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+#if DK3_HAVE_OPENSSL_H
+/** Initialize OpenSSL PRNG.
+ @param app Application structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3app_init_prng_openssl(dk3_app_t *app)
+{
+ int back = 0;
+ int cc = 0;
+ int passno = 0;
+ size_t sz;
+ char seedval[DK3_SEED_OPENSSL_BYTES];
+ do {
+ cc = 0;
+ sz =
+ dk3app_get_seed_bytes(app,seedval,sizeof(seedval),dk3app_no_loc[41],passno);
+ if(sz > 0) {
+ cc = 1;
+ RAND_seed(seedval, sz);
+ if(RAND_status() == 1) {
+ cc = 0; back = 1;
+ }
+#if DK3_ON_WINDOWS
+ if(back == 0) {
+ RAND_screen();
+ if(RAND_status() == 1) {
+ cc = 0; back = 1;
+ }
+ }
+#endif
+ passno++;
+ }
+ } while(cc);
+ if(!back) {
+ /* Warning: Failed to seed OpenSSL PRNG! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 182);
+ }
+ return back;
+}
+#endif
+
+#if DK3_HAVE_INITSTATE && DK3_HAVE_SETSTATE && DK3_HAVE_RANDOM
+/** Initialize state PRNG.
+ @param app Application structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3app_init_prng_state(dk3_app_t *app)
+{
+ int back = 0;
+ unsigned int seedval = 0;
+ if(dk3app_get_seed_bytes(
+ app, (void *)(&seedval), sizeof(unsigned int), dk3app_no_loc[40], 0
+ )
+ )
+ {
+ srandom(seedval);
+ back = 1;
+ }
+ if(!back) {
+ /* Warning: Failed to seed random() PRNG! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 181);
+ }
+ return back;
+}
+#endif
+
+#if DK3_HAVE_NRAND48 && DK3_HAVE_LRAND48
+/** Initialize lrand48() PRNG.
+ @param app Application structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3app_init_prng_rand48(dk3_app_t *app)
+{
+ int back = 0;
+ long int seedval = 0L;
+ if(dk3app_get_seed_bytes(
+ app, (void *)(&seedval), sizeof(long int), dk3app_no_loc[39], 0
+ )
+ )
+ {
+ srand48(seedval);
+ back = 1;
+ }
+ if(!back) {
+ /*Warning: Failed to seed lrand48() PRNG! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 180);
+ }
+ return back;
+}
+#endif
+
+#if DK3_HAVE_RAND && DK3_HAVE_SRAND
+/** Initialize simple rand() PRNG.
+ @param app Application structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3app_init_prng_simple(dk3_app_t *app)
+{
+ int back = 0;
+ unsigned int ui;
+ if(
+ dk3app_get_seed_bytes(
+ app, (void *)(&ui), sizeof(unsigned int), dk3app_no_loc[38], 0
+ )
+ )
+ {
+ srand(ui);
+ back = 1;
+ }
+ if(!back) {
+ /* Warning: Failed to seed simple PRNG! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 179);
+ }
+ return back;
+}
+#endif
+
+
+
+/** Attempt to initialize a PRNG.
+ @param app Application structure.
+ @param il Input line listing allowed PRNGs comma-separated.
+ @return 1 on success (at least one PRNG usable), 0 on error.
+*/
+int
+dk3app_rand_init(dk3_app_t *app, dkChar const *il)
+{
+ int back = 0;
+ int allowed_types;
+ if(app) {
+ if(app->f_rand_initialized) {
+ back = app->f_rand_success;
+ } else {
+ app->f_rand_initialized = 1;
+ if(il) {
+ allowed_types = dk3app_get_allowed_prng_types(app, il);
+ } else {
+ allowed_types = dk3app_rand_find_allowed_types(app);
+ }
+ if(!back) {
+ if(allowed_types & DK3_PRNG_OPENSSL) {
+#if DK3_HAVE_OPENSSL_H
+ back = dk3app_init_prng_openssl(app);
+ if(back) {
+ app->rand_type = DK3_PRNG_OPENSSL;
+ }
+#endif
+ }
+ }
+ if(!back) {
+ if(allowed_types & DK3_PRNG_STATE) {
+#if DK3_HAVE_INITSTATE && DK3_HAVE_SETSTATE && DK3_HAVE_RANDOM
+ back = dk3app_init_prng_state(app);
+ if(back) {
+ app->rand_type = DK3_PRNG_STATE;
+ }
+#endif
+ }
+ }
+ if(!back) {
+ if(allowed_types & DK3_PRNG_RAND48) {
+#if DK3_HAVE_NRAND48 && DK3_HAVE_LRAND48
+ back = dk3app_init_prng_rand48(app);
+ if(back) {
+ app->rand_type = DK3_PRNG_RAND48;
+ }
+#endif
+ }
+ }
+ if(!back) {
+ if(allowed_types & DK3_PRNG_SIMPLE) {
+#if DK3_HAVE_RAND && DK3_HAVE_SRAND
+ back = dk3app_init_prng_simple(app);
+ if(back) {
+ app->rand_type = DK3_PRNG_SIMPLE;
+ }
+#endif
+ }
+ }
+ if(back) {
+ app->f_rand_success = 1;
+ }
+ }
+ }
+ if(!back) {
+ /* ERROR: No PRNG usable! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 178);
+ }
+ return back;
+}
+
+
+
+/** Get random bytes.
+ @param app Application structure.
+ @param db Destination buffer.
+ @param sz Size of \a db (number of bytes).
+ @param f_crypto Flag: For cryptographic purposes.
+ @return Number of bytes written to \a db.
+*/
+static
+size_t
+dk3app_rand_bytes_internal(dk3_app_t *app, void *db, size_t sz, int f_crypto)
+{
+ size_t back = 0;
+ unsigned char *ucptr = NULL;
+ size_t i = 0;
+ unsigned u = 0;
+ if((app) && (db) && (sz)) {
+ ucptr = (unsigned char *)db;
+ if(!(app->f_rand_initialized)) {
+ dk3app_rand_init(app, NULL);
+ }
+ if(app->f_rand_success) {
+ switch(app->rand_type) {
+ case DK3_PRNG_OPENSSL: {
+#if DK3_HAVE_OPENSSL_RAND_H
+ if(f_crypto) {
+ if(RAND_bytes(ucptr, (int)sz) == 1) {
+ back = sz;
+ }
+ } else {
+ if(RAND_pseudo_bytes(ucptr, (int)sz) > -1) {
+ back = sz;
+ }
+ }
+#else
+ /* BUG: Not available! */
+#endif
+ } break;
+ case DK3_PRNG_STATE: {
+#if DK3_HAVE_INITSTATE && DK3_HAVE_SETSTATE && DK3_HAVE_RANDOM
+ long lval;
+ size_t position;
+
+ lval = random() >> 8;
+ position = 0;
+ for(i = 0; i < sz; i++) {
+ *(ucptr++) = (unsigned char)(lval & 0x000000FFL);
+ position++;
+ lval = lval >> 8;
+ if(position >= (sizeof(long) - 1)) {
+ lval = random() >> 8;
+ position = 0;
+ }
+ }
+ back = sz;
+#else
+ /* BUG: Not available! */
+#endif
+ } break;
+ case DK3_PRNG_RAND48: {
+#if DK3_HAVE_NRAND48 && DK3_HAVE_LRAND48
+ long lval;
+ size_t position;
+
+ lval = lrand48() >> 8;
+ position = 0;
+ for(i = 0; i < sz; i++) {
+ *(ucptr++) = (unsigned char)(lval & 0x000000FFL);
+ position++;
+ lval = lval >> 8;
+ if(position >= (sizeof(long) - 1)) {
+ lval = lrand48() >> 8;
+ position = 0;
+ }
+ }
+ back = sz;
+#else
+ /* BUG: Not available! */
+#endif
+ } break;
+ default: {
+#if DK3_HAVE_RAND && DK3_HAVE_SRAND
+ for(i = 0; i < sz; i++) {
+ u = rand();
+#if DK3_SIZEOF_INT > 2
+#if DK3_SIZEOF_INT > 4
+ u = u >> 28;
+#else
+ u = u >> 12;
+#endif
+#else
+ u = u >> 4;
+#endif
+ u &= 0x00FFU;
+ *(ucptr++) = (unsigned char)u;
+ }
+ back = sz;
+#else
+ /* BUG: Not available! */
+#endif
+ } break;
+ }
+ }
+ }
+ if(back < sz) {
+ /* ERROR: Failed to obtain enough random bytes! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 177);
+ }
+ return back;
+}
+
+
+size_t
+dk3app_rand_bytes(dk3_app_t *app, void *db, size_t sz)
+{
+ size_t back;
+ back = dk3app_rand_bytes_internal(app, db, sz, 1);
+ return back;
+}
+
+
+size_t
+dk3app_rand_bytes_non_crypto(dk3_app_t *app, void *db, size_t sz)
+{
+ size_t back;
+ back = dk3app_rand_bytes_internal(app, db, sz, 0);
+ return back;
+}
+
+#endif
+
+
+
+int
+dk3app_process_stdin_lines(
+ dk3_app_t *app,
+ void *obj,
+ dk3_line_handler_t *hf,
+ dkChar *buffer,
+ size_t szbuffer,
+ int de
+)
+{
+ int back = 0;
+ int must_run_directly = 0;
+ int ie;
+ FILE *fipo;
+ dkChar tfn[DK3_MAX_PATH];
+ char b[4096];
+ size_t sz;
+#if DK3_ON_WINDOWS
+ int oldmode;
+#endif
+ if((app) && (hf) && (buffer) && (szbuffer)) {
+ ie = de;
+ if(ie < 0) { ie = app->i_stdin_input_encoding; }
+ if(dk3app_get_temp_file_name(app, tfn, DK3_SIZEOF(tfn,dkChar))) {
+ fipo = dk3sf_fopen_app(tfn, dk3app_no_loc[53], app);
+ if(fipo) {
+#if DK3_ON_WINDOWS
+ oldmode = _setmode(_fileno(stdin), _O_BINARY);
+#endif
+ while((sz = dk3sf_fread_app(b, 1, sizeof(b), stdin, app)) > 0) {
+ dk3sf_fwrite_app(b, 1, sz, fipo, app);
+ }
+ fclose(fipo);
+#if DK3_ON_WINDOWS
+ _setmode(_fileno(stdin), oldmode);
+#endif
+/* 2015-08-21
+ Using ie instead of de.
+*/
+ back = dk3stream_process_filename_lines_app(
+ obj,
+ hf,
+ tfn,
+ buffer,
+ szbuffer,
+ dk3app_get_encoding(app),
+ ie,
+ app
+ );
+ dk3sf_remove_file_app(tfn, app);
+ } else {
+ must_run_directly = 1;
+ }
+ } else {
+ must_run_directly = 1;
+ }
+ if(must_run_directly) {
+#if DK3_ON_WINDOWS
+ oldmode = _setmode(_fileno(stdin), _O_BINARY);
+#endif
+ back = dk3stream_process_file_lines_app(
+ obj,
+ hf,
+ stdin,
+ NULL,
+ buffer,
+ szbuffer,
+ dk3app_get_encoding(app),
+ de,
+ app
+ );
+#if DK3_ON_WINDOWS
+ _setmode(_fileno(stdin), oldmode);
+#endif
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3app_process_stdin_chars(
+ dk3_app_t *app,
+ void *obj,
+ dk3_char_handler_t *hf,
+ int de
+)
+{
+ int back = 0;
+ int must_run_directly = 0;
+ int ie;
+ dkChar tfn[DK3_MAX_PATH];
+ char b[4096];
+ FILE *fipo;
+ size_t sz;
+#if DK3_ON_WINDOWS
+ int oldmode;
+#endif
+
+
+#line 7230 "dk3app.ctr"
+ if((app) && (hf)) {
+
+#line 7231 "dk3app.ctr"
+ ie = de;
+ if(ie < 0) {
+ ie = app->i_stdin_input_encoding;
+ }
+
+#line 7235 "dk3app.ctr"
+ if(dk3app_get_temp_file_name(app, tfn, DK3_SIZEOF(tfn,dkChar))) {
+ fipo = dk3sf_fopen_app(tfn, dk3app_no_loc[53], app);
+ if(fipo) {
+#if DK3_ON_WINDOWS
+ oldmode = _setmode(_fileno(stdin), _O_BINARY);
+#endif
+ while((sz = dk3sf_fread_app(b, 1, sizeof(b), stdin, app)) > 0) {
+ dk3sf_fwrite_app(b, 1, sz, fipo, app);
+ }
+ fclose(fipo);
+#if DK3_ON_WINDOWS
+ _setmode(_fileno(stdin), oldmode);
+#endif
+ back = dk3stream_process_filename_chars_app(obj, hf, tfn, ie, app);
+ dk3sf_remove_file_app(tfn, app);
+ } else {
+ must_run_directly = 1;
+ }
+ } else {
+ must_run_directly = 1;
+ }
+ if(must_run_directly) {
+#if DK3_ON_WINDOWS
+ oldmode = _setmode(_fileno(stdin), _O_BINARY);
+#endif
+ back = dk3stream_process_file_chars_app(obj, hf, stdin, NULL, ie, app);
+#if DK3_ON_WINDOWS
+ _setmode(_fileno(stdin), oldmode);
+#endif
+ }
+ }
+
+#line 7266 "dk3app.ctr"
+ return back;
+}
+
+
+
+#if !DK3_ON_WINDOWS
+#if DK3_HAVE_SETUID && DK3_HAVE_SETGID && DK3_HAVE_CHOWN
+#if DK3_CHAR_SIZE == 1
+/** Change owner for one file if the file exists.
+ @param app Application structure.
+ @param ul1 File name.
+ @param ul2 File name suffix.
+ @param uid New user ID for file ownership.
+ @param gid New group ID for file ownership.
+ @return 1 on success (owner modified or file does not exist).
+*/
+static
+int
+dk3app_change_owner_for_file(
+ dk3_app_t *app,
+ unsigned long ul1,
+ unsigned ul2,
+ uid_t uid,
+ gid_t gid
+)
+{
+ dkChar fnb[DK3_MAX_PATH]; /* Full name buffer. */
+ dkChar smb[32]; /* Small buffer. */
+ char tmb[32];
+ dk3_stat_t stb;
+ int back = 1;
+
+
+#line 7298 "dk3app.ctr"
+ sprintf(tmb, "/%08lx.%03x", ul1, ul2);
+ if(dk3str_c8_to_str_simple_app(smb,DK3_SIZEOF(smb,dkChar),tmb,app)) {
+ if(dk3str_len(app->n_tmpdir) < DK3_SIZEOF(fnb,dkChar)) {
+
+#line 7301 "dk3app.ctr"
+ dk3str_cpy_not_overlapped(fnb, app->n_tmpdir);
+ if((dk3str_len(fnb) + dk3str_len(smb)) < DK3_SIZEOF(fnb,dkChar)) {
+ dk3str_cat(fnb, smb);
+ dk3str_correct_filename(fnb);
+ if(dk3sf_stat_app(&stb, fnb, NULL)) {
+
+#line 7306 "dk3app.ctr"
+ if(0 != chown(fnb, uid, gid)) {
+
+#line 7307 "dk3app.ctr"
+ back = 0;
+ } else {
+
+#line 7309 "dk3app.ctr"
+ }
+ } else {
+
+#line 7311 "dk3app.ctr"
+ /* If there is no such file, there is no need to change owner. */
+ }
+ } else {
+
+#line 7314 "dk3app.ctr"
+ back = 0;
+ }
+ } else {
+
+#line 7317 "dk3app.ctr"
+ back = 0;
+ }
+ } else {
+
+#line 7320 "dk3app.ctr"
+ }
+
+
+#line 7322 "dk3app.ctr"
+ return back;
+}
+
+int
+dk3app_change_user(dk3_app_t *app, uid_t uid, gid_t gid)
+{
+ FILE *fipo;
+ unsigned long ul1;
+ unsigned ul2;
+ int back = 1;
+
+
+#line 7333 "dk3app.ctr"
+ if((app) && ((uid) || (gid))) {
+
+#line 7334 "dk3app.ctr"
+ if(app->n_logfilename) {
+
+#line 7335 "dk3app.ctr"
+ if (0 == app->cr_log) {
+ dk3app_create_log_directory(app);
+ app->cr_log = 1;
+ }
+ fipo = dk3sf_fopen_app(app->n_logfilename, dkT("a"), app);
+ if(fipo) {
+ fclose(fipo);
+ }
+ if(0 != chown(app->n_logfilename, uid, gid)) {
+
+#line 7344 "dk3app.ctr"
+ back = 0;
+ } else {
+
+#line 7346 "dk3app.ctr"
+ }
+ } else {
+
+#line 7348 "dk3app.ctr"
+ }
+ if(app->n_tmpdir) {
+
+#line 7350 "dk3app.ctr"
+ if(0 != chown(app->n_tmpdir, uid, gid)) {
+ back = 0;
+ }
+ if(app->i_tmpcarry) {
+
+#line 7354 "dk3app.ctr"
+ for(ul1 = 0UL; ul1 < 0xFFFFFFFFUL; ul1++) {
+ for(ul2 = 0U; ul2 < 0x00001000U; ul2++) {
+ if(!dk3app_change_owner_for_file(app, ul1, ul2, uid, gid)) {
+ back = 0;
+
+#line 7358 "dk3app.ctr"
+ }
+ }
+ }
+ for(ul2 = 0U; ul2 < 0x00001000U; ul2++) {
+ if(!dk3app_change_owner_for_file(app, 0xFFFFFFFFUL, ul2, uid, gid)) {
+ back = 0;
+
+#line 7364 "dk3app.ctr"
+ }
+ }
+ } else {
+ for(ul1 = 0UL; ul1 < app->ul_tmpname; ul1++) {
+ for(ul2 = 0U; ul2 < 0x00001000U; ul2++) {
+ if(!dk3app_change_owner_for_file(app, ul1, ul2, uid, gid)) {
+ back = 0;
+
+#line 7371 "dk3app.ctr"
+ }
+ }
+ }
+ for(ul2 = 0U; ul2 < app->u_tmpsuffix; ul2++) {
+ if(!dk3app_change_owner_for_file(app,app->ul_tmpname,ul2,uid,gid)) {
+ back = 0;
+
+#line 7377 "dk3app.ctr"
+ }
+ }
+ }
+ } else {
+
+#line 7381 "dk3app.ctr"
+ }
+ } else {
+
+#line 7383 "dk3app.ctr"
+ }
+
+#line 7384 "dk3app.ctr"
+ return back;
+}
+#endif
+#endif
+#endif
+
+
+
+int
+dk3app_get_dir_from_pref(
+ dk3_app_t *app,
+ dkChar const *pn,
+ dkChar *buf,
+ size_t bs,
+ int ch
+)
+{
+ int back = 0;
+ if((app) && (pn) && (buf) && (bs)) {
+ if(dk3app_get_pref(app, pn, buf, bs)) {
+ if(ch) {
+ if(dk3sf_is_dir_app(buf, NULL)) {
+ back = 1;
+ } else {
+ /* ERROR: Directory does not exist! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 369, 370, pn);
+ }
+ } else {
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dk3app.ctr b/support/dktools/dk3app.ctr
new file mode 100644
index 0000000000..5af2002ec1
--- /dev/null
+++ b/support/dktools/dk3app.ctr
@@ -0,0 +1,7422 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk3app.h Application support.
+*/
+
+#include "dk3conf.h"
+#include "dk3types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open application structure for command line application.
+ * Diagnostic messages are written to stderr and to the log file.
+ * The log file $HOME/log/<i>application</i>-<i>pid</i>.log
+ * is removed automatically by dk3app_close() unless there was an
+ * error message.
+ * @param argc Number of command line arguments.
+ * @param argv Command line arguments array.
+ * @param gn Application group name.
+ * @return Pointer to new application on success, NULL on error.
+ */
+dk3_app_t *
+dk3app_open_command(int argc, dkChar const * const * argv, dkChar const *gn);
+
+/** Open application structure for GUI application.
+ * Diagnostic messages are written to the log file only.
+ * The log file is removed automatically by dk3app_open() unless
+ * there were error messages.
+ * Typically this function is invoked from a DkWxAppHelper constructor.
+ * @param argc Number of command line arguments.
+ * @param argv Command line arguments array.
+ * @param gn Application group name.
+ * @return Pointer to new application on success, NULL on error.
+ */
+dk3_app_t *
+dk3app_open_gui(int argc, dkChar const * const * argv, dkChar const *gn);
+
+/** First silence check to correct the type if necessary.
+ Do not report errors directly, set app->de instead.
+ @param app Application structure.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+*/
+int
+dk3app_first_silence_check(dk3_app_t *app,int argc,dkChar const * const *argv);
+
+/** Open application structure for a daemon.
+ * Log messages are appended to
+ * ${localstatedir}/log/<i>applicationname</i>/<i>applicationname</i>.log.
+ * @param wd Working directory when starting the program.
+ * @param argc Number of command line arguments.
+ * @param argv Command line arguments array.
+ * @param gn Application group name.
+ * @return Pointer to new application on success, NULL on error.
+ */
+dk3_app_t *
+dk3app_open_daemon(dkChar const *wd, int argc, dkChar const * const * argv, dkChar const *gn);
+
+/** Open application structure for a silent application (no diagnostics).
+ * @param argc Number of command line arguments.
+ * @param argv Command line arguments array.
+ * @param gn Application group name.
+ * @return Pointer to new application on success, NULL on error.
+ */
+dk3_app_t *
+dk3app_open_silent(int argc, dkChar const * const * argv, dkChar const *gn);
+
+/** Close application structure, release dynamic memory and resources
+ * assigned to the object.
+ * @param app Application to close.
+ */
+void
+dk3app_close(dk3_app_t *app);
+
+/** Log a message consisting of multiple parts.
+ * @param app Application structure.
+ * @param ll Log level.
+ * @param msg Message parts array. Pointer to an array
+ * of string pointers, all array elements are concatenated to
+ * create the message text.
+ * @param nmsg Number of elements in the array.
+ */
+void
+dk3app_log_msg(dk3_app_t *app, int ll, dkChar const * const * msg, size_t nmsg);
+
+/** Log message consisting of one part.
+ * @param app Application structure.
+ * @param ll Log level.
+ * @param msg Message texts array, typically localized, obtained
+ * from dk3app_messages().
+ * @param i1 Index of message text in \a msg.
+ */
+void
+dk3app_log_1(dk3_app_t *app, int ll, dkChar const * const * msg, size_t i1);
+
+/** Log message consisting of two parts.
+ * @param app Application structure.
+ * @param ll Log level.
+ * @param msg Message texts array, typically localized, obtained
+ * from dk3app_messages().
+ * @param i Index of message text in \a msg.
+ * @param st String to write as second part.
+ */
+void
+dk3app_log_2(
+ dk3_app_t *app, int ll, dkChar const * const * msg,
+ size_t i, dkChar const *st
+);
+
+/** Log message consisting of three parts.
+ * @param app Application structure.
+ * @param ll Log level.
+ * @param msg Message string array.
+ * @param i1 Index of first message text in \a msg.
+ * @param i2 Index of third message text in \a msg.
+ * @param st Second message text.
+ */
+void
+dk3app_log_3(
+ dk3_app_t *app, int ll, dkChar const * const * msg,
+ size_t i1, size_t i2, dkChar const *st
+);
+
+/** Log message consisting of five parts.
+ * @param app Application structure.
+ * @param ll Log level.
+ * @param msg Message string array.
+ * @param i1 Index of first message text in \a msg.
+ * @param i2 Index of third message text in \a msg.
+ * @param i3 Index of fifth message text in \a msg.
+ * @param st1 Second message text.
+ * @param st2 Fourth message text.
+ */
+void
+dk3app_log_5(
+ dk3_app_t *app, int ll, dkChar const * const * msg,
+ size_t i1, size_t i2, size_t i3, dkChar const *st1, dkChar const *st2
+);
+
+/** Log message consisting of one part.
+ * @param app Application structure.
+ * @param ll Log level.
+ * @param i1 Index of message text in messages array.
+ */
+void
+dk3app_log_i1(dk3_app_t *app, int ll, size_t i1);
+
+/** Log message consisting of two parts.
+ * @param app Application structure.
+ * @param ll Log level.
+ * @param i Index of first message text in messages array.
+ * @param st Second message text.
+ */
+void
+dk3app_log_i2(dk3_app_t *app, int ll, size_t i, dkChar const * st);
+
+/** Log message consisting of three parts.
+ * @param app Application structure.
+ * @param ll Log level.
+ * @param i1 Index of first message text in messages array.
+ * @param i2 Index of third message text in messages array.
+ * @param st Second message text.
+ */
+void
+dk3app_log_i3(
+ dk3_app_t *app, int ll,
+ size_t i1, size_t i2, dkChar const *st
+);
+
+/** Log message consisting of five parts.
+ * @param app Application structure.
+ * @param ll Log level.
+ * @param i1 Index of first message text in messages array.
+ * @param i2 Index of third message text in messages array.
+ * @param i3 Index of fifth message text in messages array.
+ * @param st1 Second message text.
+ * @param st2 Fourth message text.
+ */
+void
+dk3app_log_i5(
+ dk3_app_t *app, int ll,
+ size_t i1, size_t i2, size_t i3, dkChar const *st1, dkChar const *st2
+);
+
+/** Set file name for current source file position.
+ The source file position is used when writing diagnostic messages.
+ @param app Application structure.
+ @param fn Source file name. Use NULL to disable printing
+ the file name.
+*/
+void
+dk3app_set_source_file(dk3_app_t *app, dkChar const *fn);
+
+/** Set source line number for current source file position.
+ The source file position is used when writing diagnostic messages.
+ @param app Application structure.
+ @param li Line number. Use 0UL to disable printing the
+ line number.
+*/
+void
+dk3app_set_source_line(dk3_app_t *app, unsigned long li);
+
+/** Get current source file name.
+ @param app Application structure.
+ @return Current source file name, may be NULL.
+*/
+dkChar const *
+dk3app_get_source_file(dk3_app_t const *app);
+
+/** Get current source line number.
+ @param app Application structure.
+ @return Current source file line number, may be 0UL.
+*/
+unsigned long
+dk3app_get_source_line(dk3_app_t const *app);
+
+
+/** Get number of command line arguments.
+ @param app Application structure.
+ @return Number of command line arguments.
+*/
+int
+dk3app_get_argc(dk3_app_t const *app);
+
+/** Get command line arguments array.
+ @param app Application structure.
+ @return Command line arguments array.
+*/
+dkChar const * const *
+dk3app_get_argv(dk3_app_t const *app);
+
+/** Retrieve application name.
+ @param app Application structure.
+ @return Application name on success, NULL on error.
+*/
+dkChar const *
+dk3app_get_appname(dk3_app_t const *app);
+
+/** Retrieve name of executable file.
+ * @param app Application structure.
+ * @return Executable file name on success, NULL on error.
+*/
+dkChar const *
+dk3app_get_execfilename(dk3_app_t const *app);
+
+/** Retrieve binary directory name.
+ @param app Application structure.
+ @return Name of bin directory on success, NULL on error.
+*/
+dkChar const *
+dk3app_get_bindir(dk3_app_t const *app);
+
+/** Get system configuration directory (/etc or /usr/local/etc).
+ @param app Application structure.
+ @return Directory name on success, NULL on error.
+*/
+dkChar const *
+dk3app_get_etcdir(dk3_app_t const *app);
+
+/** Get data root directory (/usr/share or /usr/local/share).
+ @param app Application structure.
+ @return Directory name on success, NULL on error.
+*/
+dkChar const *
+dk3app_get_sharedir(dk3_app_t const *app);
+
+/** Get local state directory (/var or /usr/local/var).
+ @param app Application structure.
+ @return Directory name on success, NULL on error.
+*/
+dkChar const *
+dk3app_get_vardir(dk3_app_t const *app);
+
+/** Get user login name.
+ @param app Application structure.
+ @return Login name on success, NULL on error.
+*/
+dkChar const *
+dk3app_get_logname(dk3_app_t const *app);
+
+/** Get host name.
+ @param app Application structure.
+ @return Host name on success, NULL on error.
+*/
+dkChar const *
+dk3app_get_hostname(dk3_app_t const *app);
+
+/** Get users home directory.
+ @param app Application structure.
+ @return Home directory on success, NULL on error.
+*/
+dkChar const *
+dk3app_get_homedir(dk3_app_t const *app);
+
+/** Get application group name.
+ @param app Application structure.
+ @return Group name on success, NULL on error.
+*/
+dkChar const *
+dk3app_get_appgroup(dk3_app_t const *app);
+
+/** Retrieve users language.
+ @param app Application structure.
+ @return Pointer to users language or NULL if no language is defined.
+*/
+dkChar const *
+dk3app_get_language(dk3_app_t const *app);
+
+/** Retrieve users region.
+ @param app Application structure.
+ @return Pointer to users region or NULL if no region is defined.
+*/
+dkChar const *
+dk3app_get_region(dk3_app_t const *app);
+
+/** Retrieve internal encoding.
+ @param app Application structure.
+ @return Internal (in-memory) encoding.
+*/
+int
+dk3app_get_encoding(dk3_app_t const *app);
+
+/** Retrieve output file encoding.
+ @param app Application structure.
+ @return Output file encoding.
+*/
+int
+dk3app_get_output_encoding(dk3_app_t const *app);
+
+/** Retrieve default encoding expected on stdin.
+ @param app Application structure.
+ @return Expected input encoding (DK3_FILE_ENCODING_xxx).
+*/
+int
+dk3app_get_input_stdin_encoding(dk3_app_t const *app);
+
+/** Retrieve default encoding expected on files.
+ @param app Application structure.
+ @return Expected input encoding (DK3_FILE_ENCODING_xxx).
+*/
+int
+dk3app_get_input_file_encoding(dk3_app_t const *app);
+
+/** Get file name for temporary file.
+ The file name is stored into the buffer @a db.
+ @param app Application structure.
+ @param db Destination buffer.
+ @param sz Size of \a db (number of characters).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3app_get_temp_file_name(dk3_app_t *app, dkChar *db, size_t sz);
+
+/** Set a preference value.
+ Preferences set by this function are written to the
+ $HOME/.dk3app/<i>application</i>/dk3pref.conf file during
+ dk3app_close().
+ @param app Application structure.
+ @param k Key (preference name).
+ @param v Value.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3app_set_pref(dk3_app_t *app, dkChar const *k, dkChar const *v);
+
+/** Get a preference value.
+ On success the preference value is written to @a d.
+ @param app Application structure.
+ @param k Key (preference name).
+ @param d Destination buffer.
+ @param s Size of \a d (number of characters).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3app_get_pref(dk3_app_t *app, dkChar const *k, dkChar *d, size_t s);
+
+/** Get boolean preference value.
+ @param app Application structure.
+ @param name Preference name.
+ @param dv Default value if preference not found.
+ @return Preference value or default value.
+*/
+int
+dk3app_get_pref_bool(dk3_app_t *app, dkChar const *name, int dv);
+
+/** Get int preference value.
+ @param app Application structure.
+ @param name Preference name.
+ @param dv Default value.
+ @return Preference value or default value.
+*/
+int
+dk3app_get_pref_int(dk3_app_t *app, dkChar const * name, int dv);
+
+/** Get a system preference value.
+ Command line and user-set preferences are ignored.
+ @param app Application structure.
+ @param k Key (preference name).
+ @param d Destination buffer.
+ @param s Size of \a d (number of characters).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3app_get_sys_pref(dk3_app_t *app, dkChar const *k, dkChar *d, size_t s);
+
+/** Unconfigure application.
+ @param app Application structure.
+*/
+void
+dk3app_unconfigure(dk3_app_t *app);
+
+/** Find configuration file.
+ On success the function returns a file name collection.
+ Configuration files with low priority are at the start of the
+ collection, files with higher priority are at the end.
+ This allows higher priorized configuration files to overwrite
+ settings made by the previously processed files.
+ After you are done with the search results set, use
+ dk3search_close() to close the set and release resources assigned
+ to it.
+ @param app Application structure.
+ @param fn File name to search for (short filename
+ without leading path).
+ @param exclu Flag: Exclude users configuration file.
+ @return Collection of file names (full path names including the
+ leading directory), use dk3search_close() after
+ use to destroy it.
+*/
+dk3_search_t *
+dk3app_find_config_file(dk3_app_t *app, dkChar const *fn, int exclu);
+
+
+/** Find configuration file in reverse search order
+ (most significant file first).
+ This function is typically used to process the first file from
+ the set only which is the most significant file.
+ After you are done with the search results set, use
+ dk3search_close() to close the set and release resources assigned
+ to it.
+ @param app Application structure.
+ @param fn File name to search for (short file name without
+ leading directory).
+ @param exclu Flag: Exclude users configuration files.
+ @return Collection of file names (full path names with leading
+ directory), use dk3search_close() after
+ use to destroy it.
+*/
+dk3_search_t *
+dk3app_find_config_file_revers(dk3_app_t *app, dkChar const *fn, int exclu);
+
+/** Find data file.
+ The full path name of the file found is written to @a db on success.
+ @param app Application structure.
+ @param fn File name to search for (short file name without leading
+ directory).
+ @param db Destination buffer.
+ @param sz Size of \a db (number of characters).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3app_find_data_file(dk3_app_t *app, dkChar const *fn, dkChar *db, size_t sz);
+
+/** Get string table.
+ @param app Application structure.
+ @param fn Short file name of string table.
+ @param dv Default value, used if file not found.
+ @return New string table if found or \a dv on problems.
+*/
+dkChar const * const *
+dk3app_messages(dk3_app_t *app, dkChar const *fn, dkChar const * const *dv);
+
+/** Find and print help text.
+ The function searches for a help text file in the users
+ language. If no file is found the default text is printed.
+ @param app Application structure.
+ @param fn Help text file name (short name wih).
+ @param dt Default text to use if file not found.
+*/
+void
+dk3app_help(dk3_app_t *app, dkChar const *fn, dkChar const * const *dt);
+
+/** Get log level used for stderr.
+ @param app Application structure.
+ @return Log level required for logging to stderr.
+*/
+int
+dk3app_get_stderr_log_level(dk3_app_t const *app);
+
+/** Set log level used for stderr.
+ @param app Application structure.
+ @param ll New log level.
+*/
+void
+dk3app_set_stderr_log_level(dk3_app_t *app, int ll);
+
+/** Report write error.
+ @param app Application structure.
+ @param ll Log level.
+ @param wished Number of bytes wished to write.
+ @param written Number of bytes written.
+*/
+void
+dk3app_log_write_error(dk3_app_t *app, int ll, size_t wished, size_t written);
+
+
+/** Report fwrite error.
+ @param app Application structure.
+ @param ll Log level.
+ @param wished Number of elements wished to write.
+ @param written Number of elements written.
+*/
+void
+dk3app_log_fwrite_error(dk3_app_t *app, int ll, size_t wished, size_t written);
+
+/** Get a localized text.
+ @param app Application structure.
+ @param num Index of string in array.
+ @return Pointer to localized string on success, NULL on error.
+*/
+dkChar const *
+dk3app_localized(dk3_app_t const *app, size_t num);
+
+/** Get a non-localized text.
+ @param num Index of string in array.
+ @return Pointer to localized string on success, NULL on error.
+*/
+dkChar const *
+dk3app_not_localized(size_t num);
+
+/** Initialize random number generator.
+ Set up allowed PRNG types and seed best PRNG found.
+ If at least one of the PRNG types specified in @a il is available
+ we attempt to seed this PRNG.
+ The following preferences are used by this function:
+ - /rand/types is used if il is NULL.
+ - /rand/file/allowed configured whether or not usage o
+ seed file in the users home directory is allowed
+ - /rand/egd/name can be used to specify of the EDG socket
+ if an EGD (entropy gathering daemon) is running on the
+ system. By default /dev/urandom and/or /dev/random
+ are used to seed a PRNG if available.
+ @param app Application structure.
+ @param il Text line to process, may be NULL.
+ If this argument is NULL, the /rand/types preference is used
+ to find the allowed PRNG types.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3app_rand_init(dk3_app_t *app, dkChar const *il);
+
+/** Retrieve list of allowed PRNG types from a text line.
+ If the text line \a il pointer is NULL the
+ /rand/types preference value is used.
+ @param app Application structure.
+ @param il Text line to process.
+ @return Combination of DK3_PRNG_xxx.
+*/
+int
+dk3app_get_allowed_prng_types(dk3_app_t *app, dkChar const *il);
+
+/** Retrieve pseudo-random bytes.
+ @param app Application structure.
+ @param db Destination buffer.
+ @param sz Size of \a db (number of bytes).
+ @return Number of bytes found.
+*/
+size_t
+dk3app_rand_bytes(dk3_app_t *app, void *db, size_t sz);
+
+/** Retrieve pseudo-random bytes.
+ The bytes will not be used for cryptographic or authentication
+ purposes, so we can use a less unpredictive (less complicated und
+ thus faster) generation mechanism.
+ @param app Application structure.
+ @param db Destination buffer.
+ @param sz Size of \a db (number of bytes).
+ @return Number of bytes found.
+*/
+size_t
+dk3app_rand_bytes_non_crypto(dk3_app_t *app, void *db, size_t sz);
+
+/** Attempt to save random seed to file when closing an application.
+ @param app Application structure.
+*/
+void
+dk3app_rand_end(dk3_app_t *app);
+
+/** Get default input encoding for stdin ignoring preferences.
+ @param app Application structure.
+ @return Encoding (DK3_FILE_ENCODING_xxx).
+*/
+int
+dk3app_get_default_stdin_encoding(dk3_app_t const *app);
+
+/** Get default input encoding for files ignoring preferences.
+ @param app Application structure.
+ @return Encoding (DK3_FILE_ENCODING_xxx).
+*/
+int
+dk3app_get_default_file_encoding(dk3_app_t const *app);
+
+/** Process standard input character by character.
+ Attempt to save stdin data to file so we can do a BOM check.
+ @param app Application structure.
+ @param obj Object to modify while processing data.
+ @param hf Handler function.
+ @param de Default encoding.
+*/
+int
+dk3app_process_stdin_chars(
+ dk3_app_t *app,
+ void *obj,
+ dk3_char_handler_t *hf,
+ int de
+);
+
+/** Process standard input line by line.
+ Attempt to save stdin data to file so we can do a BOM check.
+ @param app Application structure.
+ @param obj Object to modify while reading data.
+ @param hf Handler function.
+ @param buffer Line buffer.
+ @param szbuffer Size of buffer.
+ @param de Default encoding.
+*/
+int
+dk3app_process_stdin_lines(
+ dk3_app_t *app,
+ void *obj,
+ dk3_line_handler_t *hf,
+ dkChar *buffer,
+ size_t szbuffer,
+ int de
+);
+
+/** Get maximum log level used by the application.
+ @param app Application structure.
+ @return Maximum log level used by the application.
+*/
+int
+dk3app_max_log_level(dk3_app_t const *app);
+
+/** Remove trailing newline and handle backslash escape sequences.
+ This function is run on lines read from string table file.
+ @param lb Line buffer.
+*/
+void
+dk3app_squeeze_line(char *lb);
+
+
+#if !DK3_ON_WINDOWS
+#if DK3_HAVE_SETUID && DK3_HAVE_SETGID && DK3_HAVE_CHOWN
+#if DK3_CHAR_SIZE == 1
+/** Change ownership to writable files.
+ This function is used by daemons before switching to a
+ non-privileged user account.
+ @param app Application structure.
+ @param uid New user ID for process.
+ @param gid New group ID for process.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3app_change_user(dk3_app_t *app, uid_t uid, gid_t gid);
+#endif
+#endif
+#endif
+
+/** Retrieve directory setting from preference.
+ @param app Application structure.
+ @param pn Preference name.
+ @param buf Result buffer.
+ @param bs Size of bs (number of dkChar).
+ @param ch Flag: Check existance of directory.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3app_get_dir_from_pref(
+ dk3_app_t *app,
+ dkChar const *pn,
+ dkChar *buf,
+ size_t bs,
+ int ch
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk3all.h"
+
+#if DK3_HAVE_OPENSSL_RAND_H
+#include <openssl/rand.h>
+#endif
+
+
+$(trace-include)
+
+
+
+/** Names of preference scope attributes.
+*/
+static dkChar const * const dk3app_scope_attributes[] = {
+/* 0 */ dkT("user"),
+/* 1 */ dkT("application"),
+/* 2 */ dkT("application-group"),
+/* 3 */ dkT("host"),
+/* 4 */ dkT("language"),
+/* 5 */ dkT("region"),
+NULL
+};
+
+
+
+/** Text strings, not localized.
+*/
+static dkChar const * const dk3app_no_loc[] = {
+/* 0 */ dkT("bin"), /* Used to build bindir. */
+/* 1 */ dkT("etc"), /* Used to build etcdir. */
+/* 2 */ dkT("share"), /* Used to build sharedir. */
+/* 3 */ dkT("var"), /* Used to build vardir. */
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+/* 4 */ dkT("\\log"), /* Used to build log directory. */
+#else
+/* 4 */ dkT("/log"), /* Used to build log directory. */
+#endif
+/* 5 */ dkT("-"), /* Used to build log file name. */
+/* 6 */ dkT(".log"), /* Used to build log file name. */
+/* 7 */ dkT("/"), /* Used to build log directory. */
+/* 8 */ dkT("a"), /* Open mode for log file. */
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+/* 9 */ dkT("\\tmp"), /* Subdirectory for temporary files. */
+#else
+/* 9 */ dkT("/tmp"), /* Subdirectory for temporary files. */
+#endif
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+/* 10 */ dkT("\\run"), /* Subdirectory for temporary files. */
+#else
+/* 10 */ dkT("/run"), /* Subdirectory for temporary files. */
+#endif
+/* 11 */ dkT("LANG"), /* Environment variable for language. */
+/* 12 */ dkT("Control Panel\\International"), /* Reg key for language. */
+/* 13 */ dkT("LocaleName"), /* Reg entry name for language. */
+/* 14 */ dkT("sLanguage"), /* Alternative reg entry name for language. */
+/* 15 */ dkT("utf8"), /* Encoding UTF-8 (modern variant). */
+/* 16 */ dkT("UTF-8"), /* Encoding UTF-8 (older variant). */
+/* 17 */ dkT("dk3app"), /* Subdirectory in system configuration. */
+/* 18 */ dkT(".dk3app"), /* Subdirectory in home directory. */
+/* 19 */ dkT("."), /* Current directory. */
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+/* 20 */ dkT("\\"), /* File name separator. */
+#else
+/* 20 */ dkT("/"), /* File name separator. */
+#endif
+/* 21 */ dkT("dk3pref.conf"), /* Configuration file name. */
+/* 22 */ dkT("r"), /* File open mode for reading. */
+/* 23 */ dkT("dk3app.str"), /* String table name. */
+/* 24 */ dkT("w"), /* File open mode. */
+/* 25 */ dkT("="), /* Used when writing preferences. */
+/* 26 */ dkT("\n"), /* Used when writing preferences. */
+/* 27 */ dkT("/ui/lang"), /* User interface, language. */
+/* 28 */ dkT("/log/file/level"), /* Required log level for file. */
+/* 29 */ dkT("/log/file/keep"), /* Required level to keep file. */
+/* 30 */ dkT("/log/stderr/level"), /* Required log level for stderr. */
+/* 31 */ dkT("/temp/dir/keep"), /* Required to keep temp dir. */
+/* 32 */ dkT("-site"), /* Check for site-specific config files. */
+/* 33 */ dkT("*"), /* Wildcard for all users ... */
+/* 34 */ dkT("dk3conf.conf"), /* Configuration file name. */
+/* 35 */ dkT("%lu"), /* scanf/printf format. */
+/* 36 */ dkT("rb"), /* File open mode: Read binary. */
+/* 37 */ dkT("/rand/types"), /* Preference name for allowed PRNG types. */
+/* 38 */ dkT(".rnd-simple"), /* Preference name for simple seed file. */
+/* 39 */ dkT(".rnd-lrand48"), /* Preference name for lrand48() seed file. */
+/* 40 */ dkT(".rnd-random"), /* Preference name for random() seed file. */
+/* 41 */ dkT(".rnd-openssl"), /* Preference name for OpenSSL seed file. */
+/* 42 */ dkT("/rand/egd/name"), /* Preference name for EGD socket. */
+/* 43 */ dkT("EGDSOCKET"), /* Environment variable name for EGD socket. */
+/* 44 */ dkT("/dev/urandom"), /* Device name for seed data. */
+/* 45 */ dkT("/dev/random"), /* Device name for seed data. */
+/* 46 */ dkT("/rand/file/allowed"), /* Preference name. */
+/* 47 */ dkT("en"), /* Default language name. */
+#if 0
+/* 48 */ dkT("/dir/uc2lat-t"), /* Preference name for LaTeX encoding. */
+#else
+/* 48 */ dkT("/dir/charmap"), /* Preference name for LaTeX encoding. */
+#endif
+/* 49 */
+#if 0
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+dkT("\\uc2lat-t"),
+#else
+dkT("/uc2lat-t"),
+#endif
+#else
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+dkT("\\dktools\\charmap"), /* Character map subdirectory of share. */
+#else
+dkT("/dktools/charmap"), /* Character map subdirectory of share. */
+#endif
+#endif
+/* 50 */ dkT("/silent"), /* Preference name for silent work. */
+/* 51 */ dkT("/input/encoding/file"), /* Preference name. */
+/* 52 */ dkT("/input/encoding/stdin"), /* Preference name. */
+/* 53 */ dkT("wb"), /* File open mode: Read binary. */
+/* 54 */ dkT(".dir"), /* Suffix for uc2lat *.dir files. */
+/* 55 */ dkT(".lat"), /* Suffix for uc2lat *.lat files. */
+/* 56 */ dkT("sbin"), /* sbin dirctory. */
+};
+
+
+
+/** Directories where binary executable can reside.
+*/
+static dkChar const * const dk3app_bindir_candidates[] = {
+$!string-table macro=dkT
+bin
+sbin
+lib
+libexec
+$!end
+};
+
+
+
+/** Keywords for users configuration files.
+ These keywords can be used in the $HOME/.dk3app/dk3conf.conf file.
+*/
+dkChar const * const dk3app_conf_file[] = {
+/* 0 */ dkT("use-system-config-files"),
+/* 1 */ dkT("ignore-system-config-files"),
+NULL
+};
+
+
+/** Log level names.
+*/
+static dkChar const * const dk3app_log_levels[] = {
+dkT("n$one"),
+dkT("pa$nic"),
+dkT("f$atal"),
+dkT("e$rror"),
+dkT("w$arning"),
+dkT("in$fo"),
+dkT("pr$ogress"),
+dkT("d$ebug"),
+dkT("ig$nore"),
+NULL
+};
+
+#if 0
+static dkChar const * const dk3app_prng_type_names[] = {
+/* 0 */ dkT("openssl"), /* OpenSSL PRNG. */
+/* 1 */ dkT("random"), /* initstate()/setstate()/random() */
+/* 2 */ dkT("rand48"), /* lrand48(). */
+/* 3 */ dkT("simple"), /* srand()/rand(). */
+NULL
+};
+#endif
+
+
+
+/** Text strings, localization needed.
+The texts strings are used as parts of diagnostic messages.
+*/
+static dkChar const * const dk3app_kw[] = {
+$!string-table macro=dkT
+#
+# 000: \n
+#
+\n
+#
+# 001: PANIC
+#
+PANIC
+#
+# 002: FATAL
+#
+FATAL
+#
+# 003: ERROR
+#
+ERROR
+#
+# 004: Warning
+#
+Warning
+#
+# 005: Information
+#
+Information
+#
+# 006: Progress
+#
+Progress
+#
+# 007: Debug
+#
+Debug
+#
+# 008:
+#
+
+#
+# 009: Not enough memory (RAM/swap space)!
+#
+Not enough memory (RAM/swap space)!
+#
+# 010: #
+#
+\#
+#
+# 011: :
+#
+:
+#
+# 012: Memory allocation (
+#
+Memory allocation (
+#
+# 013: bytes) failed!
+#
+ bytes) failed!
+#
+# 014: Memory allocation failed!
+#
+Memory allocation failed!
+#
+# 015: Numeric overflow in size calculation!
+#
+Numeric overflow in size calculation!
+#
+# 016: Numeric overflow in size calculation (
+#
+Numeric overflow in size calculation (
+#
+# 017: x
+#
+ x
+#
+# 018: bytes)!
+#
+ bytes)!
+#
+# 019: Application "
+#
+Application "
+#
+# 020: " started.
+#
+" started.
+#
+# 021: Application "
+#
+Application "
+#
+# 022: " finished.
+#
+" finished.
+#
+# 023: Application name:
+#
+Application name:
+#
+# 024: Application group:
+#
+Application group:
+#
+# 025: Executable file:
+#
+Executable file:
+#
+# 026: Directory "bin":
+#
+Directory "bin":
+#
+# 027: Directory "etc":
+#
+Directory "etc":
+#
+# 028: Directory "share":
+#
+Directory "share":
+#
+# 029: Directory "var":
+#
+Directory "var":
+#
+# 030: Directory "home":
+#
+Directory "home":
+#
+# 031: Directory "temp":
+#
+Directory "temp":
+#
+# 032: User:
+#
+User:
+#
+# 033: Log file:
+#
+Log file:
+#
+# 034: Language:
+#
+Language:
+#
+# 035: Region:
+#
+Region:
+#
+# 036: <unknown>
+#
+<unknown>
+#
+# 037: The name of the temporary directory is too long!
+#
+The name of the temporary directory is too long!
+#
+# 038: Destination buffer too small!
+#
+Destination buffer too small!
+#
+# 039: The LANG environment variable is too long!
+#
+The LANG environment variable is too long!
+#
+# 040: Failed to find name of executable file!
+#
+Failed to find name of executable file!
+#
+# 041: Too few directories in hierarchy!\nExecutable files should not reside in the root directory!
+#
+Too few directories in hierarchy!\nExecutable files should not reside in the root directory!
+#
+# 042: File name of executable file too long!
+#
+File name of executable file too long!
+#
+# 043: Failed to obtain the users login name!
+#
+Failed to obtain the users login name!
+#
+# 044: Failed to find the users home directory!
+#
+Failed to find the users home directory!
+#
+# 045: File name for log file gets too long!
+#
+File name for log file gets too long!
+#
+# 046: Failed to create directory for log file!
+#
+Failed to create directory for log file!
+#
+# 047: Failed to convert process ID to text!
+#
+Failed to convert process ID to text!
+#
+# 048: Failed to find application name!
+#
+Failed to find application name!
+#
+# 049: The name of the temporary directory is too long!
+#
+The name of the temporary directory is too long!
+#
+# 050: Failed to find local state (var) directory!
+#
+Failed to find local state (var) directory!
+#
+# 051: Preference name too long!
+#
+Preference name too long!
+#
+# 052: Malformed preference entry on command line!
+#
+Malformed preference entry on command line!
+#
+# 053: Failed to find current working directory!
+#
+Failed to find current working directory!
+#
+# 054: Too many requests for temporary file names!
+#
+Too many requests for temporary file names!
+#
+# 055: Internal error (bug): Missing a file or directory name!
+#
+Internal error (bug): Missing a file or directory name!
+#
+# 056: Failed to save preference entry "
+#
+Failed to save preference entry "
+#
+# 057: "="
+#
+"="
+#
+# 058: "!
+#
+"!
+#
+# 059: Directory name "
+#
+Directory name "
+#
+# 060: " too long!
+#
+" too long!
+#
+# 061: Failed to obtain information about "
+#
+Failed to obtain information about "
+#
+# 062: "!\nThe stat() function failed!
+#
+"!\nThe stat() function failed!
+#
+# 063: Failed to read directory "
+#
+Failed to read directory "
+#
+# 064: "!
+#
+"!
+#
+# 065: File name "
+#
+File name "
+#
+# 066: " too long!
+#
+" too long!
+#
+# 067: Illegal characters in source string, conversion failed!
+#
+Illegal characters in source string, conversion failed!
+#
+# 068: Failed to remove directory!
+#
+Failed to remove directory!
+#
+# 069: Failed to remove directory "
+#
+Failed to remove directory "
+#
+# 070: "!
+#
+"!
+#
+# 071: The HOMEDRIVE environment variable is not set!
+#
+The HOMEDRIVE environment variable is not set!
+#
+# 072: The HOMEPATH environment variable is not set!
+#
+The HOMEPATH environment variable is not set!
+#
+# 073: Failed to obtain information about a file!
+#
+Failed to obtain information about a file!
+#
+# 074: "
+#
+"
+#
+# 075: " is a directory!
+#
+" is a directory!
+#
+# 076: Can not open file, name refers to a directory!
+#
+Can not open file, name refers to a directory!
+#
+# 077: Failed to open file "
+#
+Failed to open file "
+#
+# 078: " for write access!
+#
+" for write access!
+#
+# 079: Failed to open file for write access!
+#
+Failed to open file for write access!
+#
+# 080: Failed to obtain current time!
+#
+Failed to obtain current time!
+#
+# 081: File "
+#
+File "
+#
+# 082: " exists but is not a directory!
+#
+" exists but is not a directory!
+#
+# 083: File exists but is not a directory!
+#
+File exists but is not a directory!
+#
+# 084: Failed to create directory "
+#
+Failed to create directory "
+#
+# 085: "!
+#
+"!
+#
+# 086: Failed to create directory!
+#
+Failed to create directory!
+#
+# 087: Directory name too long!
+#
+Directory name too long!
+#
+# 088: Failed to remove file "
+#
+Failed to remove file "
+#
+# 089: "!
+#
+"!
+#
+# 090: Failed to remove file!
+#
+Failed to remove file!
+#
+# 091: No user name entry in user record!
+#
+No user name entry in user record!
+#
+# 092: No user record for "
+#
+No user record for "
+#
+# 093: "!
+#
+"!
+#
+# 094: No matching user record found!
+#
+No matching user record found!
+#
+# 095: No home directory entry in user record!
+#
+No home directory entry in user record!
+#
+# 096: Failed to obtain information about "
+#
+Failed to obtain information about "
+#
+# 097: "!\nThe lstat() function failed!
+#
+"!\nThe lstat() function failed!
+#
+# 098: No information about a file, lstat() failed!
+#
+No information about a file, lstat() failed!
+#
+# 099: No information about a file, lstat() failed!
+#
+No information about a file, lstat() failed!
+#
+# 100: Owner of symlink "
+#
+Owner of symlink "
+#
+# 101: " is not owner of file!
+#
+" is not owner of file!
+#
+# 102: Symlink owner is not file owner!
+#
+Symlink owner is not file owner!
+#
+# 103: Command "
+#
+Command "
+#
+# 104: " is too long!
+#
+" is too long!
+#
+# 105: Command is too long!
+#
+Command is too long!
+#
+# 106: The PATH environment variable is not defined!
+#
+The PATH environment variable is not defined!
+#
+# 107: No mkdir() function available!
+#
+No mkdir() function available!
+#
+# 108: String too long!
+#
+String too long!
+#
+# 109: Command name too long!
+#
+Command name too long!
+#
+# 110: Too many ".." entries in file name "
+#
+Too many ".." entries in file name "
+#
+# 111: "!
+#
+"!
+#
+# 112: Illegal character(s) in source string!
+#
+Illegal character(s) in source string!
+#
+# 113: Illegal character(s) in source buffer!
+#
+Illegal character(s) in source buffer!
+#
+# 114: Illegal destination encoding!
+#
+Illegal destination encoding!
+#
+# 115: Conversion to UTF-8 failed!
+#
+Conversion to UTF-8 failed!
+#
+# 116: Conversion to UTF-16 failed!
+#
+Conversion to UTF-16 failed!
+#
+# 117: Result character(s) not available for destination encoding!
+#
+Result character(s) not available for destination encoding!
+#
+# 118: UTF-8 decoding failed!
+#
+UTF-8 decoding failed!
+#
+# 119: UTF-16 decoding failed!
+#
+UTF-16 decoding failed!
+#
+# 120: Failed to write data!
+#
+Failed to write data!
+#
+# 121: Failed to flush output!
+#
+Failed to flush output!
+#
+# 122: Failed to close data stream object!
+#
+Failed to close data stream object!
+#
+# 123: Stream not opened for write operations!
+#
+Stream not opened for write operations!
+#
+# 124: Failed to read data!
+#
+Failed to read data!
+#
+# 125: Mismatch between encoding and character size!
+#
+Mismatch between encoding and character size!
+#
+# 126: Too many ".." entries in file name!
+#
+Too many ".." entries in file name!
+#
+# 127: Unknown message digest type: "
+#
+Unknown message digest type: "
+#
+# 128: "!
+#
+"!
+#
+# 129: Unknown encoding: "
+#
+Unknown encoding: "
+#
+# 130: "!
+#
+"!
+#
+# 131: Failed to find current host name!
+#
+Failed to find current host name!
+#
+# 132: Host:
+#
+Host:
+#
+# 133: Option "
+#
+Option "
+#
+# 134: " requires an argument!
+#
+" requires an argument!
+#
+# 135: Option "
+#
+Option "
+#
+# 136: " too long for processing
+#
+" too long for processing
+#
+# 137: Ignoring irrelevant argument in "
+#
+Ignoring irrelevant argument in "
+#
+# 138: "!
+#
+"!
+#
+# 139: Unknown option "
+#
+Unknown option "
+#
+# 140: "!
+#
+"!
+#
+# 141: Not a numeric value: "
+#
+Not a numeric value: "
+#
+# 142: "!
+#
+"!
+#
+# 143: Failed to open file "
+#
+Failed to open file "
+#
+# 144: "!
+#
+"!
+#
+# 145: Failed to open file!
+#
+Failed to open file!
+#
+# 146: Not a boolean value: "
+#
+Not a boolean value: "
+#
+# 147: "!
+#
+"!
+#
+# 148: Resource file "
+#
+Resource file "
+#
+# 149: " found.
+#
+" found.
+#
+# 150: Resource file "
+#
+Resource file "
+#
+# 151: " not found.
+#
+" not found.
+#
+# 152: Configuration file "
+#
+Configuration file "
+#
+# 153: " found.
+#
+" found.
+#
+# 154: Configuration file "
+#
+Configuration file "
+#
+# 155: " not found.
+#
+" not found.
+#
+# 156: No support for message digest "
+#
+No support for message digest "
+#
+# 157: "!
+#
+"!
+#
+# 158: Illegal message digest or encoding number!
+#
+Illegal message digest or encoding number!
+#
+# 159: Checksumming is available for regular files only!
+#
+Checksumming is available for regular files only!
+#
+# 160: Option name missing in long option: "
+#
+Option name missing in long option: "
+#
+# 161: "!
+#
+"!
+#
+# 162: Failed to convert a numeric value to text!
+#
+Failed to convert a numeric value to text!
+#
+# 163: "!
+#
+"!
+#
+# 164: Too many command line arguments! Ignoring "
+#
+Too many command line arguments! Ignoring "
+#
+# 165: "...!
+#
+"...!
+#
+# 166: Internal error (bug)
+#
+Internal error (bug)
+#
+# 167: .
+#
+.
+#
+# 168: Too many file names match pattern "
+#
+Too many file names match pattern "
+#
+# 169: ", just one allowed!
+#
+", just one allowed!
+#
+# 170: Write operation failed,
+#
+Write operation failed,
+#
+# 171: of
+#
+ of
+#
+# 172: bytes written!
+#
+ bytes written!
+#
+# 173: Write operation failed!
+#
+Write operation failed!
+#
+# 174: Write operation failed,
+#
+Write operation failed,
+#
+# 175: of
+#
+ of
+#
+# 176: elements written!
+#
+ elements written!
+#
+# 177: Failed to create random data!
+#
+Failed to create random data!
+#
+# 178: No usable PRNG found!
+#
+No usable PRNG found!
+#
+# 179: Failed to seed simple PRNG!
+#
+Failed to seed simple PRNG!
+#
+# 180: Failed to seed lrand48() PRNG!
+#
+Failed to seed lrand48() PRNG!
+#
+# 181: Failed to seed random() PRNG!
+#
+Failed to seed random() PRNG!
+#
+# 182: Failed to seed OpenSSL PRNG!
+#
+Failed to seed OpenSSL PRNG!
+#
+# 183: Seed file "
+#
+Seed file "
+#
+# 184: " not used (permissions)!
+#
+" not used (permissions)!
+#
+# 185: Seed file "
+#
+Seed file "
+#
+# 186: " not used (symlink owner)!
+#
+" not used (symlink owner)!
+#
+# 187: Unknown PRNG type: "
+#
+Unknown PRNG type: "
+#
+# 188: "!
+#
+"!
+#
+# 189: The srand()/rand() PRNG is not available!
+#
+The srand()/rand() PRNG is not available!
+#
+# 190: The srand48()/lrand48() PRNG is not available!
+#
+The srand48()/lrand48() PRNG is not available!
+#
+# 191: The random() PRNG is not available!
+#
+The random() PRNG is not available!
+#
+# 192: The OpenSSL PRNG is not available!
+#
+The OpenSSL PRNG is not available!
+#
+# 193: Failed to save random seed data!
+#
+Failed to save random seed data!
+#
+# 194: HOME directory name too long!
+#
+HOME directory name too long!
+#
+# 195: System configuration files skipped by user.
+#
+System configuration files skipped by user.
+#
+# 196: Attempt to obtain seed data from "
+#
+Attempt to obtain seed data from "
+#
+# 197: ".
+#
+".
+#
+# 198: Seed data:
+#
+Seed data:
+#
+# 199: bytes found.
+#
+ bytes found.
+#
+# 200: Index out of range!
+#
+Index out of range!
+#
+# 201: Matrix expansion requires a square matrix!
+#
+Matrix expansion requires a square matrix!
+#
+# 202: Not a directory: "
+#
+Not a directory: "
+#
+# 203: "!
+#
+"!
+#
+# 204: Encoding not supported by C runtime library!
+#
+Encoding not supported by C runtime library!
+#
+# 205: No directory containing LaTeX encoding tables found!
+#
+No directory containing LaTeX encoding tables found!
+#
+# 206: Redefinition,\noverwriting "
+#
+Redefinition,\noverwriting "
+#
+# 207: " by "
+#
+" by "
+#
+# 208: ".
+#
+".
+#
+# 209: Syntax error,\nindex
+#
+Syntax error,\nindex
+#
+# 210: is out of range 0...255.
+#
+ is out of range 0...255.
+#
+# 211: Syntax error\nnear "
+#
+Syntax error\nnear "
+#
+# 212: "!
+#
+"!
+#
+# 213: Syntax error,\nmissing LaTeX encoding!
+#
+Syntax error,\nmissing LaTeX encoding!
+#
+# 214: Syntax error,\nmissing index!
+#
+Syntax error,\nmissing index!
+#
+# 215: No file name matches pattern "
+#
+No file name matches pattern "
+#
+# 216: "!
+#
+"!
+#
+# 217: Missing name of long option!
+#
+Missing name of long option!
+#
+# 218: Incomplete input sequence.
+#
+Incomplete input sequence.
+#
+# 219: String contains non-ISO-LATIN-1 characters!
+#
+String contains non-ISO-LATIN-1 characters!
+#
+# 220: Misconfigured start/end for range!
+#
+Misconfigured start/end for range!
+#
+# 221: New range conflicts with existing one!
+#
+New range conflicts with existing one!
+#
+# 222: Not a hex number!
+#
+Not a hex number!
+#
+# 223: Syntax error!
+#
+Syntax error!
+#
+# 224: Character redefinition!
+#
+Character redefinition!
+#
+# 225: Range not declared in character directory!
+#
+Range not declared in character directory!
+#
+# 226: Package name conflicts with previous definition!
+#
+Package name conflicts with previous definition!
+#
+# 227: Attempt to obtain seed data from CryptoAPI.
+#
+Attempt to obtain seed data from CryptoAPI.
+#
+# 228: Attempt to obtain seed data from screen.
+#
+Attempt to obtain seed data from screen.
+#
+# 229: OpenSSL PRNG seeded successfully.
+#
+OpenSSL PRNG seeded successfully.
+#
+# 230: Attempt to read preferences file "
+#
+Attempt to read preferences file "
+#
+# 231: ".
+#
+".
+#
+# 232: LaTeX table directory: "
+#
+LaTeX table directory: "
+#
+# 233: ".
+#
+".
+#
+# 234: Attempting LaTeX table directory: "
+#
+Attempting LaTeX table directory: "
+#
+# 235: ".
+#
+".
+#
+# 236: Reading LaTeX table dir: "
+#
+Reading LaTeX table dir: "
+#
+# 237: ".
+#
+".
+#
+# 238: Registering LaTeX conversion range
+#
+Registering LaTeX conversion range
+#
+# 239: .
+#
+.
+#
+# 240: Loading LaTeX conversion data file "
+#
+Loading LaTeX conversion data file "
+#
+# 241: ".
+#
+".
+#
+# 242: Failed to change into directory: "
+#
+Failed to change into directory: "
+#
+# 243: "!
+#
+"!
+#
+# 244: Failed to enumerate printers!
+#
+Failed to enumerate printers!
+#
+# 245: Record too large!
+#
+Record too large!
+#
+# 246: File damaged or not a database file!
+#
+File damaged or not a database file!
+#
+# 247: No support for database type "
+#
+No support for database type "
+#
+# 248: " available!
+#
+" available!
+#
+# 249: Key not found in database!
+#
+Key not found in database!
+#
+# 250: DB entry probably damaged - not a multibyte char string!
+#
+DB entry probably damaged - not a multibyte char string!
+#
+# 251: Database opened for read access only!
+#
+Database opened for read access only!
+#
+# 252: Error(s) occured while processing command line options!
+#
+Error(s) occured while processing command line options!
+#
+# 253: Failed to retrieve current locale!
+#
+Failed to retrieve current locale!
+#
+# 254: Current locale too long!
+#
+Current locale too long!
+#
+# 255: Not a regular file: "
+#
+Not a regular file: "
+#
+# 256: "!
+#
+"!
+#
+# 257: Image file type unknown or not supported!
+#
+Image file type unknown or not supported!
+#
+# 258: Bits per component restricted to 16!
+#
+Bits per component restricted to 16!
+#
+# 259: Incorrect page setup, no usable space between borders!
+#
+Incorrect page setup, no usable space between borders!
+#
+# 260: Mathematical error in size calculations!
+#
+Mathematical error in graphics calculations!
+#
+# 261: Failed to set bitmap image frame!
+#
+Failed to set bitmap image frame!
+#
+# 262: Flate compression not supported!
+#
+Flate compression not supported!
+#
+# 263: Illegal compression cell type used!
+#
+Illegal compression cell type used!
+#
+# 264: Error during previous compression operations!
+#
+Error during previous compression operations!
+#
+# 265: Failed to retrieve console settings!
+#
+Failed to retrieve console settings!
+#
+# 266: Failed to restore console settings!
+#
+Failed to restore console settings!
+#
+# 267: Failed to modify console settings!
+#
+Failed to modify console settings!
+#
+# 268: Failed to convert timestamp to local time!
+#
+Failed to convert timestamp to local time!
+#
+# 269: ERROR: No file name available for database!
+#
+No file name available for database!
+#
+# 270/271: ERROR: Failed to change file ownership!
+#
+Failed to change ownership for file:\n"
+"!
+#
+# 272/273: ERROR: Failed to change file permissions!
+#
+Failed to change permissions for file:\n"
+"!
+#
+# 274: ERROR: Failed to open network socket, insufficient permissions!
+#
+Insufficient permissions to open network connection!
+#
+# 275: ERROR: Failed to open network socket, unknown address family!
+#
+Unknown or illegal address family!
+#
+# 276: ERROR: Failed to open network socket, process table overflow!
+#
+Process table overflow!
+#
+# 277: ERROR: Too many open files!
+#
+Too many open files!
+#
+# 278: ERROR: Protocol not supported!
+#
+Protocol not supported!
+#
+# 279: ERROR: Failed to open network socket!
+#
+Failed to open network socket!
+#
+# 280: ERROR: Failed to close socket!
+#
+Failed to close socket!
+#
+# 281: ERROR: Operation interrupted by signal!
+#
+Interrupted by signal or explicitly cancelled!
+#
+# 282: ERROR: Failed to connect!
+#
+Failed to connect!
+#
+# 283: ERROR: Failed to listen for incoming requests!
+#
+Failed to listen for incoming requests!
+#
+# 284/285: ERROR: Failed to find IP address for "..."!
+#
+Failed to find IP address for:\n"
+"!
+#
+# 286
+#
+Host not found!
+#
+# 287
+#
+Host exists, but no IP address assigned!
+#
+# 288
+#
+Problem on DNS server!
+#
+# 289
+#
+Temporary problem on DNS server, try again later!
+#
+# 290
+#
+No gethostbyname() function available!
+#
+# 291
+#
+Can not connect to remote port 0!
+#
+# 292
+#
+Access denied by firewall or due to insufficient permissions!
+#
+# 293
+#
+Local address already in use!
+#
+# 294
+#
+Resources shortage, network operation failed!
+#
+# 295
+#
+Previous connection attempt not yet completed!
+#
+# 296
+#
+Connection refused, port not open on peer!
+#
+# 297
+#
+Socket already connected!
+#
+# 298
+#
+Network unreachable!
+#
+# 299
+#
+Timeout occured.
+#
+# 300
+#
+No select() function available, timeout settings ignored!
+#
+# 301
+#
+Failed to retrieve socket state!
+#
+# 302
+#
+Failed to bind local address!
+# 303 UNUSED
+
+#
+# 304
+#
+Socket already bound to local address!
+#
+# 305
+#
+Failed to write data to socket!
+#
+# 306
+#
+Operation would block!
+#
+# 307
+#
+Connection reset by peer!
+#
+# 308
+#
+Peer address is required to send data via connectionless socket!
+#
+# 309
+#
+Peer address specification is not allowed for connected sockets!
+#
+# 310
+#
+Message too large to be sent atomically!
+#
+# 311
+#
+Sending queue full for socket!
+#
+# 312
+#
+Writing to a pipe without a reader!
+#
+# 313
+#
+Less bytes were written than required!
+#
+# 314
+#
+Failed to read data from socket!
+#
+# 315
+#
+Failed to shut down socket!
+#
+# 316
+#
+Socket not connected!
+#
+# 317
+#
+Failed to accept incoming connection request!
+#
+# 318
+#
+Connection aborted!
+#
+# 319
+#
+Network protocol error!
+#
+# 320
+#
+Network subsystem not available!
+#
+# 321
+#
+Windows sockets not initialized!
+#
+# 322
+#
+A blocking Winsock 1.1 operation is in progress!
+#
+# 323
+#
+Socket type doesn't correspond to address family!
+#
+# 324
+#
+Socket not configured for broadcasts!
+#
+# 325
+#
+Requested address is not available!
+#
+# 326
+#
+Host unreachable!
+#
+# 327
+#
+Windows sockets version not available!
+#
+# 328
+#
+Too many processes use Windows sockets at this time!
+#
+# 329
+#
+I/O error occured!
+#
+# 330
+#
+Too many symbolic links in path!
+#
+# 331
+#
+Illegal pathname (missing a parent directory)!
+#
+# 332
+#
+File system is mounted read-only!
+#
+# 333
+#
+Stale NFS file handle!
+#
+# 334
+#
+Server for remote file not available!
+#
+# 335
+#
+No space left on device!
+#
+# 336
+#
+Failed to wait for sockets to become ready!
+#
+# 337
+#
+Failed to convert text address to address!
+#
+# 338
+#
+Failed to find address for host!
+#
+# 339
+#
+Failed to set socket options!
+#
+# 340
+#
+Error while closing file!
+#
+# 341/342
+#
+Error while closing file\n"
+"!
+#
+# 343/344
+#
+Failed to write data to file:\n"
+"!
+#
+# 345
+#
+Failed to read data from file!
+#
+# 346/347
+#
+Failed to read data from file:\n"
+"!
+#
+# 348/349
+#
+Not an IP address: "
+"!
+#
+# 350
+#
+Not an IP address!
+#
+# 351/352
+#
+Failed to connect to: "
+"!
+#
+# 353
+#
+No function available to check blocking/non-blocking state!
+#
+# 354
+#
+Netmask is not a dotted IP address!
+#
+# 355
+#
+Netmask is not a bit number!
+#
+# 356
+#
+Netmask is not an IPv6 address!
+#
+# 357
+#
+No name resolution available, please specify IP address!
+#
+# 358
+#
+No select() function available!
+#
+# 359
+#
+No valid socket found in set!
+#
+# 360 361
+#
+Socket
+ connected to client:
+#
+# 362 363
+#
+Connection from "
+" rejected!
+#
+# 364
+#
+Failed to create any listener socket for socket set!
+#
+# 365
+#
+Preference value of /threads/max higher than number of cores!
+#
+# 366 + 367
+#
+Failed to find unique file identifier for file\n"
+"!
+#
+# 368
+#
+Failed to find unique file identifier for a file!
+#
+# 369 + 370 Preference ... does not point to a directory!
+#
+Preference "
+" does not point to a directory!
+#
+# 371
+#
+
+#
+# 372 373 374
+#
+Socket
+ listening:
+
+#
+# 375 376 377
+#
+Socket
+ connected:
+
+#
+# 378 379 380
+#
+Multiple different font encodings required!
+Font encoding both required and denied: `
+'!
+#
+# 381 382
+#
+Font encoding can be used: `
+'!
+#
+# 383 384
+#
+The following font encoding can not be used: `
+'.
+#
+# 385
+#
+All font encodings denied!
+#
+# 386 387 388
+#
+Too many entries on position
+ in text line:\n"
+"
+#
+# 389 390
+#
+Unexpected end of text after backslash in text:\n"
+"
+#
+# 391 392
+#
+UTF-8 decoding failed for string:\n"
+UTF-16 decoding failed for string:\n"
+#
+# 393 394
+#
+Non-ANSI characters in string:\n"
+Non-URL characters in string:\n"
+#
+# 395 396
+#
+Character 0x
+already defined!
+#
+# 397
+#
+Character redefinition!
+#
+# 398 399
+#
+First word is not a hexadecimal number!
+_UNUSED_
+#
+# 400
+#
+No configuration data found for character!
+#
+# 401
+#
+No support for zlib compression!
+#
+# 402
+#
+No support for bzip2 compression!
+#
+# 403
+#
+No data files found to process!
+#
+# 404
+#
+Syntax error, unknown encoding!
+#
+# 405
+#
+Syntax error, no package names found!
+#
+# 406
+#
+Syntax error, missing value for attribute!
+#
+# 407
+#
+Missing "share" directory!
+#
+# 408 409 410
+#
+No data found for character!
+No data found for character 0x
+!
+#
+# 411
+#
+Conflicting font encoding requirements!
+#
+# 412 413
+#
+Failed to set buffer for file\n"
+"!
+$!end
+};
+
+
+
+/** Preferences entry.
+*/
+typedef struct _dk3app_pref_t {
+ dkChar const *k; /**< Key (name). */
+ dkChar const *v; /**< Value. */
+} dk3app_pref_t;
+
+
+
+/** Message catalog.
+*/
+typedef struct _dk3app_mc_t_ {
+ dkChar const *n; /**< Name (always dynamically allocated). */
+ dkChar const **msg; /**< Message texts. */
+ int f; /**< Flag: Messages dynamically allocated. */
+ size_t nmsg; /**< Number of messages. */
+} dk3app_mc_t;
+
+
+
+/** Delete preferences entry, release memory.
+ @param p Preference entry to delete.
+*/
+static
+void
+dk3app_pref_delete(dk3app_pref_t *p)
+{
+ if(p) { $? "= dk3app_pref_delete \"%!ds\"=\"%!ds\"",TR_STR(p->k),TR_STR(p->v)
+ dk3_release(p->k);
+ dk3_release(p->v);
+ dk3_delete(p);
+ }
+}
+
+
+
+/** Create new preferences entry, allocate memory.
+ @param k Key (preference name).
+ @param v Value.
+ @return Pointer to new entry on success, NULL on error.
+*/
+static
+dk3app_pref_t *
+dk3app_pref_new(dkChar const *k, dkChar const *v)
+{
+ dk3app_pref_t *back = NULL;
+ $? "+ dk3app_pref_new \"%!ds\"=\"%!ds\"", TR_STR(k), TR_STR(v)
+ if((k) && (v)) {
+ back = dk3_new(dk3app_pref_t,1);
+ if(back) {
+ back->k = dk3str_dup_app(k, NULL);
+ back->v = dk3str_dup_app(v, NULL);
+ if(!((back->k) && (back->v))) {
+ dk3app_pref_delete(back); back = NULL;
+ }
+ }
+ } $? "- dk3app_pref_new %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+/** Compare two preference entries by name.
+ @param l Left entry.
+ @param r Right entry.
+ @param crit Comparison criteria (ignored).
+ @return Comparison result l <=> r.
+*/
+static
+int
+dk3app_compare_pref(void const *l, void const *r, int crit)
+{
+ int back = 0;
+ dk3app_pref_t const *pl = NULL; /* Left object. */
+ dk3app_pref_t const *pr = NULL; /* Right object. */
+ if(l) {
+ if(r) {
+ pl = (dk3app_pref_t const *)l; pr = (dk3app_pref_t const *)r;
+ if(pl->k) {
+ if(pr->k) {
+ back = dk3str_cmp(pl->k, pr->k);
+ } else { back = 1; }
+ } else {
+ if(pr->k) { back = -1; }
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+/** Delete string table.
+ @param ta Table to delete.
+ @param n Number of entries in the table.
+*/
+static
+void
+dk3app_mc_table_delete(dkChar const **ta, size_t n)
+{
+ dkChar const **ptr = NULL; /* Start of string table. */
+ size_t i = 0; /* Index of current element to process. */
+ $? "+ dk3app_mc_table_delete %!ds %u", TR_PTR(ta), (unsigned)n
+ ptr = ta;
+ for(i = 0; i < n; i++) { $? ". entry no %u", (unsigned)i
+ if(*ptr) { $? ". delete \"%!ds\"", TR_STR(*ptr)
+ dk3_delete(*ptr);
+ }
+ *(ptr++) = NULL;
+ }
+ dk3_delete(ta); $? "- dk3app_mc_table_delete"
+}
+
+
+
+/** Delete message catalog entry.
+ @param mc Message catalog entry to delete.
+*/
+static
+void
+dk3app_mc_delete(dk3app_mc_t *mc)
+{
+ $? "+ dk3app_mc_delete %!ds", TR_PTR(mc)
+ if(mc) { $? ". name=\"%!ds\"", TR_STR(mc->n)
+ dk3_release(mc->n);
+ if(mc->f) {
+ if(mc->msg) {
+ dk3app_mc_table_delete(mc->msg, mc->nmsg);
+ }
+ } mc->f = 0; mc->msg = NULL;
+ dk3_delete(mc);
+ } $? "- dk3app_mc_delete"
+}
+
+
+
+/** Create message catalog entry.
+ @param n Short file name of string table file.
+ @param msg String table.
+ @param nmsg Number of entries in \a msg.
+ @param f Flag: The memory for \a msg was dynamically allocated.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to message catalog entry on success, NULL on error.
+*/
+static
+dk3app_mc_t *
+dk3app_mc_new(
+ dkChar const *n, dkChar const **msg, size_t nmsg, int f, dk3_app_t *app
+)
+{
+ dk3app_mc_t *back = NULL;
+ $? "+ dk3app_mc_new \"%!ds\" f=%d nmsg=%u", TR_STR(n), f, (unsigned)nmsg
+ back = dk3_new_app(dk3app_mc_t,1,app);
+ if(back) {
+ back->n = NULL; back->msg = NULL; back->f = f; back->nmsg = nmsg;
+ back->n = dk3str_dup_app(n, app);
+ if(back->n) {
+ back->msg = msg;
+ } else {
+ dk3app_mc_delete(back); back = NULL;
+ }
+ } $? "- dk3app_mc_new %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+/** Compare two message catalog entries.
+ @param l Left entry.
+ @param r Right entry.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+static
+int
+dk3app_mc_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3app_mc_t const *pl = NULL; /* Left message catalog. */
+ dk3app_mc_t const *pr = NULL; /* Right message catalog. */
+ if(l) {
+ if(r) {
+ pl = (dk3app_mc_t const *)l; pr = (dk3app_mc_t const *)r;
+ if(pl->n) {
+ if(pr->n) {
+ back = dk3str_cmp(pl->n, pr->n);
+ } else { back = 1; }
+ } else {
+ if(pr->n) { back = -1; }
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+/** Write log message to a file.
+ If the time has changed since the last message written to that
+ file we write a new timestamp before writing the message.
+ @param app Application structure.
+ @param ll Log level, DK3_LL_xxx.
+ @param msg Array of message parts.
+ @param nmsg Number of elements in \a msg.
+ @param fipo File to write to.
+ @param last_time Timestamp of last message written to that file.
+*/
+static
+void
+dk3app_log_to_file(
+ dk3_app_t *app, int ll, dkChar const * const * msg, size_t nmsg,
+ FILE *fipo, dk3_time_t *last_time
+)
+{
+ dk3_time_t time_now; /* Current time. */
+ dkChar tb[64]; /* Buffer to store current time as text. */
+ char ulb[64]; /* Buffer for current time as char text. */
+ char *sp = NULL; /* Source pointer used in conversion. */
+ size_t i = 0; /* Index of current string to process. */
+ $? "+ dk3app_log_to_file"
+ if(dk3sf_time(&time_now)) {
+ if(time_now != *last_time) {
+ if(dk3sf_time_convert_app(tb, DK3_SIZEOF(tb,dkChar), &time_now, NULL)) {
+ *last_time = time_now;
+ dk3sf_fputs(((app->msg) ? app->msg : dk3app_kw)[10], fipo);
+ dk3sf_fputs(tb, fipo);
+ dk3sf_fputs(((app->msg) ? app->msg : dk3app_kw)[0], fipo);
+ }
+ }
+ }
+ if(app->n_sourcefile) {
+ dk3sf_fputs(app->n_sourcefile, fipo);
+ dk3sf_fputs(((app->msg) ? app->msg : dk3app_kw)[11], fipo);
+ if(app->sourceline) {
+ sprintf(ulb, "%lu", app->sourceline);
+ sp = ulb;
+ while(*sp) { dk3sf_fputc( (dkChar)(*(sp++)), fipo); }
+ dk3sf_fputs(((app->msg) ? app->msg : dk3app_kw)[11], fipo);
+ }
+ dk3sf_fputs(((app->msg) ? app->msg : dk3app_kw)[8], fipo);
+ }
+ if((ll >= DK3_LL_PANIC) && (ll <= DK3_LL_WARNING)) {
+ dk3sf_fputs(((app->msg) ? app->msg : dk3app_kw)[ll], fipo);
+ dk3sf_fputs(((app->msg) ? app->msg : dk3app_kw)[11], fipo);
+ dk3sf_fputs(((app->msg) ? app->msg : dk3app_kw)[8], fipo);
+ }
+ for(i = 0; i < nmsg; i++) {
+ if(msg[i]) {
+ dk3sf_fputs(msg[i], fipo);
+ }
+ }
+ dk3sf_fputs(((app->msg) ? app->msg : dk3app_kw)[0], fipo); $? "- dk3app_log_to_file"
+}
+
+
+
+static
+void
+dk3app_create_parent_directory(const dkChar *fn)
+{
+ dkChar fnb[DK3_MAX_PATH];
+ dkChar *ptr;
+ dkChar *lptr;
+
+ if (dk3str_len(fn) < DK3_SIZEOF(fnb,dkChar)) {
+ dk3str_cpy_not_overlapped(fnb, fn);
+ ptr= fnb; lptr = NULL;
+ while (dkT('\0') != *ptr) {
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+ if (dkT('\\') == *ptr) { lptr = ptr; }
+#else
+ if (dkT('/') == *ptr) { lptr = ptr; }
+#endif
+ ptr++;
+ }
+ if (NULL != lptr) {
+ *lptr = dkT('\0');
+ (void)dk3sf_mkdir_app(fnb, 0700, NULL);
+ }
+ }
+}
+
+
+
+/** Create ${HOME}/log directory for known log file name.
+ @param app Application structure containing log file
+ name in n_logfilename.
+*/
+static
+void
+dk3app_create_log_directory(dk3_app_t *app)
+{
+ dk3app_create_parent_directory(app->n_logfilename);
+}
+
+
+
+/** Create ${HOME}/tmp directory for known log file name.
+ @param app Application structure containing log file
+ name in n_logfilename.
+*/
+static
+void
+dk3app_create_tmp_directory(dk3_app_t *app)
+{
+ dk3app_create_parent_directory(app->n_tmpdir);
+}
+
+
+
+/** Write log message to log file.
+ If the time has changed since the last message written to that
+ file we write a new timestamp before writing the message.
+ @param app Application structure.
+ @param ll Log level, DK3_LL_xxx.
+ @param msg Array of message parts.
+ @param nmsg Number of elements in \a msg.
+*/
+static
+void
+dk3app_log_file(dk3_app_t *app, int ll, dkChar const * const * msg, size_t nmsg)
+{
+ FILE *fipo; /* Output file. */
+ dk3_stat_t stb; /* File stat buffer. */
+ $? "+ dk3app_log_file"
+ if(app->n_logfilename) { $? ". file \"%!ds\"", app->n_logfilename
+ if (0 == app->cr_log) {
+ /*
+ Create ${HOME}/log directory if not yet done.
+ */
+ dk3app_create_log_directory(app);
+ app->cr_log = 1;
+ }
+ if(app->f_first_file_log) {
+ /*
+ Daemons always attempt to append after existing log.
+ */
+ if(app->app_type == DK3_APP_TYPE_DAEMON) {
+ app->f_first_file_log = 0;
+ if(!dk3sf_stat_app(&stb, app->n_logfilename, NULL)) {
+ app->f_first_file_log = 1;
+ }
+ }
+ }
+ fipo = dk3sf_fopen_app(app->n_logfilename, dk3app_no_loc[8], NULL);
+ /* WRITE */
+ if(fipo) { $? ". file opened"
+#if DK3_ON_WINDOWS && (DK3_CHAR_SIZE > 1)
+ /* Switch to 16 bit characters. */
+ (void)_setmode(_fileno(fipo), _O_U16TEXT);
+ /* Write byte order marker. */
+ if(app->f_first_file_log) {
+ fputwc(0xFEFF, fipo);
+ }
+#endif
+ app->f_first_file_log = 0;
+ dk3app_log_to_file(
+ app, ll, msg, nmsg, fipo, &(app->t_last_log_file)
+ );
+ fclose(fipo);
+ } else { $? "! fopen"
+ }
+ } $? "- dk3app_log_file"
+}
+
+
+
+int
+dk3app_max_log_level(dk3_app_t const *app)
+{
+ int back = 0;
+ if(app) {
+ if(app->app_type != DK3_APP_TYPE_SILENT) {
+ back = app->ll_file;
+ if(app->app_type == DK3_APP_TYPE_COMMAND) {
+ if(app->ll_stderr > back) {
+ back = app->ll_stderr;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+void
+dk3app_log_msg(dk3_app_t *app, int ll, dkChar const * const * msg, size_t nmsg)
+{
+ $? "+ dk3app_log_msg %!8s level=%d parts=%u",TR_8PTR(app),ll,(unsigned)nmsg
+ if((app) && (msg) && (nmsg)) { $? ". arguments ok"
+ if(app->f_readytolog) { $? ". ready to log"
+ if(ll < app->ll_highest) { $? ". keep new highest log level"
+ app->ll_highest = ll;
+ }
+ switch(app->app_type) {
+ case DK3_APP_TYPE_COMMAND: { $? ". command line logging"
+ if(app->ll_file >= ll) { $? ". log level sufficient (file)"
+ dk3app_log_file(app, ll, msg, nmsg);
+ } else { $? "! log level insufficient (file %d)", app->ll_file
+ }
+ if(app->ll_stderr >= ll) { $? ". log level sufficient (stderr)"
+ dk3sf_initialize_stderr();
+ dk3app_log_to_file(
+ app, ll, msg, nmsg, stderr, &(app->t_last_log_stderr)
+ );
+ } else { $? "! log level insufficient (stderr %d)", app->ll_stderr
+ }
+ } break;
+ case DK3_APP_TYPE_GUI:
+ case DK3_APP_TYPE_DAEMON: $? ". daemon/GUI logging"
+ { $? ". ll_file=%d ll=%d", app->ll_file, ll
+ if(app->ll_file >= ll) { $? ". log level sufficient"
+ dk3app_log_file(app, ll, msg, nmsg);
+ }
+ } break;
+ }
+ } else { $? "! not yet ready to log"
+ }
+ } else { $? "! arguments problem"
+ } $? "- dk3app_log_msg"
+}
+
+
+
+void
+dk3app_log_1(dk3_app_t *app, int ll, dkChar const * const * msg, size_t i1)
+{
+ dkChar const *m[2]; /* Message parts. */
+ $? "+ dk3app_log_1"
+ if((app) && (msg)) {
+ m[0] = msg[i1];
+ m[1] = NULL;
+ dk3app_log_msg(app, ll, (dkChar const * const *)m, 1);
+ } $? "- dk3app_log_1"
+}
+
+
+
+void
+dk3app_log_2(
+ dk3_app_t *app, int ll, dkChar const * const * msg,
+ size_t i, dkChar const *st
+)
+{
+ dkChar const *m[3];
+ if((app) && (msg)) {
+ m[0] = msg[i];
+ m[1] = st;
+ m[2] = NULL;
+ dk3app_log_msg(app, ll, (dkChar const * const *)m, 2);
+ }
+}
+
+
+void
+dk3app_log_3(
+ dk3_app_t *app, int ll, dkChar const * const * msg,
+ size_t i1, size_t i2, dkChar const *st
+)
+{
+ dkChar const *m[4]; /* Message parts. */
+ $? "+ dk3app_log_3"
+ if((app) && (msg)) {
+ m[0] = msg[i1];
+ m[1] = st;
+ m[2] = msg[i2];
+ m[3] = NULL;
+ dk3app_log_msg(app, ll, (dkChar const * const *)m, 3);
+ } $? "- dk3app_log_3"
+}
+
+
+
+void
+dk3app_log_5(
+ dk3_app_t *app, int ll, dkChar const * const * msg,
+ size_t i1, size_t i2, size_t i3, dkChar const *st1, dkChar const *st2
+)
+{
+ dkChar const *m[6]; /* Message parts. */
+ $? "+ dk3app_log_5"
+ if((app) && (msg)) {
+ m[0] = msg[i1];
+ m[1] = st1;
+ m[2] = msg[i2];
+ m[3] = st2;
+ m[4] = msg[i3];
+ m[5] = NULL;
+ dk3app_log_msg(app, ll, (dkChar const * const *)m, 5);
+ } $? "- dk3app_log_5"
+}
+
+
+
+void
+dk3app_log_i1(dk3_app_t *app, int ll, size_t i1)
+{
+ $? "+ dk3app_log_i1"
+ if(app) {
+ dk3app_log_1(app, ll, ((app->msg) ? app->msg : dk3app_kw), i1);
+ } $? "- dk3app_log_i1"
+}
+
+
+
+void
+dk3app_log_i2(dk3_app_t *app, int ll, size_t i, dkChar const * st)
+{
+ dkChar const *msg[3]; /* Message parts. */
+
+ if((app) && (i) && (st)) {
+ if(i < DK3_SIZEOF(dk3app_kw,DK3_PCDKCHAR)) {
+ msg[0] = ((app->msg) ? app->msg : dk3app_kw)[i];
+ msg[1] = st;
+ msg[2] = NULL;
+ dk3app_log_msg(app, ll, (dkChar const * const *)msg, 2);
+ }
+ }
+}
+
+
+
+void
+dk3app_log_i3(
+ dk3_app_t *app, int ll,
+ size_t i1, size_t i2, dkChar const *st
+)
+{
+ $? "+ dk3app_log_i3"
+ if(app) {
+ dk3app_log_3(app, ll, ((app->msg) ? app->msg : dk3app_kw), i1, i2, st);
+ } $? "- dk3app_log_i3"
+}
+
+
+
+void
+dk3app_log_i5(
+ dk3_app_t *app, int ll,
+ size_t i1, size_t i2, size_t i3, dkChar const *st1, dkChar const *st2
+)
+{
+ $? "+ dk3app_log_i5"
+ if(app) {
+ dk3app_log_5(
+ app, ll, ((app->msg) ? app->msg : dk3app_kw), i1, i2, i3, st1, st2
+ );
+ } $? "- dk3app_log_i5"
+}
+
+
+
+void
+dk3app_set_source_file(dk3_app_t *app, dkChar const *fn)
+{
+ if(app) { $? "= dk3app_set_source_file \"%!ds\"", TR_STR(fn)
+ app->n_sourcefile = fn;
+ }
+}
+
+
+
+void
+dk3app_set_source_line(dk3_app_t *app, unsigned long li)
+{
+ if(app) { $? "= dk3app_set_source_line %lu", li
+ app->sourceline = li;
+ }
+}
+
+
+
+dkChar const *
+dk3app_get_source_file(dk3_app_t const *app)
+{
+ dkChar const *back = NULL;
+ if(app) {
+ back = app->n_sourcefile;
+ } $? "= dk3app_get_source_file \"%!ds\"", TR_STR(back)
+ return back;
+}
+
+
+
+unsigned long
+dk3app_get_source_line(dk3_app_t const *app)
+{
+ unsigned long back = 0UL;
+ if(app) {
+ back = app->sourceline;
+ } $? "= dk3app_get_source_line %lu", back
+ return back;
+}
+
+
+
+/** Find data (resource) file.
+ String tables are resources too, so we check language and
+ region subdirectories too.
+ @param app Application structure.
+ @param fn File name.
+ @param db Destination buffer.
+ @param sz Size of \a db (number of characters).
+ @param verb Flag: Diagnostic messages enabled.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3app_my_find_data_file(
+ dk3_app_t *app, dkChar const *fn, dkChar *db, size_t sz, int verb
+)
+{
+ int back = 0;
+ dkChar const *p1 = NULL; /* dk3app, group or application name. */
+ dkChar const *p2 = NULL; /* Language. */
+ dkChar const *p3 = NULL; /* Region. */
+ int cc = 1; /* Flag: Can go. */
+ size_t mysz = 0; /* Size for calculation. */
+ size_t sz1 = 0; /* Length of /xxx/share directory name. */
+ size_t sz2 = 0; /* Length of short file name. */
+ dk3_stat_t stb; /* Stat buffer to test existance of files. */
+ int i = 0; /* Pass: 0=lang+region, 1=language, 0=share. */
+ int j = 0; /* Pass: 0=app, 1=appgroup, 2=dk3app, 3=base. */
+ $? "+ dk3app_my_find_data_file \"%!ds\"", TR_STR(fn)
+ if((app) && (fn) && (db) && (sz)) {
+ if(app->n_sharedir) {
+ sz1 = dk3str_len(app->n_sharedir);
+ sz2 = dk3str_len(fn);
+ for(i = 0; ((back == 0) && (i < 4)); i++) {
+ for(j = 0; ((back == 0) && (j < 4)); j++) { $? ". i=%d j=%d", i, j
+ p1 = NULL; p2 = NULL; p3 = NULL; cc = 0;
+ switch(i) {
+ case 1: {
+ if(app->n_language) {
+ p2 = app->n_language; cc = 1;
+ }
+ } break;
+ case 2: {
+ p2 = dk3app_no_loc[47]; cc = 1;
+ } break;
+ case 3: {
+ cc = 1;
+ } break;
+ default: {
+ if(app->n_language) {
+ p2 = app->n_language;
+ if(app->n_region) {
+ p3 = app->n_region; cc = 1;
+ }
+ }
+ } break;
+ }
+ switch(j) {
+ case 1: {
+ if(app->n_appgroup) {
+ p1 = app->n_appgroup;
+ } else {
+ cc = 0;
+ }
+ } break;
+ case 2: {
+ p1 = dk3app_no_loc[17];
+ } break;
+ case 3: {
+ p1 = NULL;
+ } break;
+ default: {
+ if(app->n_app) {
+ p1 = app->n_app;
+ } else {
+ cc = 0;
+ }
+ } break;
+ }
+ if(cc) {
+ mysz = sz1 + sz2 + 1;
+ if(p1) { mysz += dk3str_len(p1); mysz++; }
+ if(p2) { mysz += dk3str_len(p2); mysz++; }
+ if(p3) { mysz += dk3str_len(p3); mysz++; }
+ if(mysz < sz) {
+ dk3str_cpy_not_overlapped(db, app->n_sharedir);
+ if(p1) {
+ dk3str_cat(db, dk3app_no_loc[20]); dk3str_cat(db, p1);
+ }
+ if(p2) {
+ dk3str_cat(db, dk3app_no_loc[20]); dk3str_cat(db, p2);
+ }
+ if(p3) {
+ dk3str_cat(db, dk3app_no_loc[20]); dk3str_cat(db, p3);
+ }
+ dk3str_cat(db, dk3app_no_loc[20]);
+ dk3str_cat(db, fn); $? ". i=%d j=%d db=\"%!ds\"", i, j, db
+ if(dk3sf_stat_app(&stb, db, NULL)) {
+ switch((stb.ft) & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_REGULAR: {
+ back = 1; $? ". found \"%!ds\"", db
+ } break;
+ }
+ }
+ if(back) {
+ /* DEBUG: Resource file ... found. */
+ dk3app_log_i3(app, DK3_LL_DEBUG, 148, 149, db);
+ } else {
+ /* DEBUG: Resource file ... not found. */
+ dk3app_log_i3(app, DK3_LL_DEBUG, 150, 151, db);
+ }
+ }
+ }
+ }
+ }
+ } else {
+ if(verb) {
+ /* Internal error, no /xxx/share directory! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 55);
+ }
+ }
+ } $? "- dk3app_my_find_data_file %d", back
+ return back;
+}
+
+
+
+/** Remove a file.
+ The difference to dk3sf_remove_file_app() is that this function
+ does not complain if the file does not exist.
+ @param n File name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3app_remove_file_app(dkChar *n, dk3_app_t *app)
+{
+ int back = 0;
+ dk3_stat_t stb; /* Stat buffer to test existance of file. */
+ $? "+ dk3app_remove_file_app %!ds", TR_STR(n)
+ if(dk3sf_stat_app(&stb,n,app)) { $? ". file exists"
+ back = dk3sf_remove_file_app(n, app);
+ } else { $? ". no such file"
+ back = 1; /* File does not exist. */
+ } $? "- dk3app_remove_file_app %d", back
+ return back;
+}
+
+
+
+/** Delete one temporaray file.
+ @param app Application structure.
+ @param n Number to build the file name.
+ @param s Number to build the file suffix.
+ @param f Pointer to error code variable.
+*/
+static
+void
+dk3app_delete_one_temp_file(dk3_app_t *app, unsigned long n, unsigned s, int *f)
+{
+ dkChar buffer[DK3_MAX_PATH]; /* Buffer to construct complete file name. */
+ dkChar fnb2[16]; /* Buffer for short file name. */
+ char fnb[16]; /* Buffer for numeric conversion. */
+ dk3_app_t *ra = NULL; /* Application to use for diagnostics. */
+ size_t sz = 0; /* Length needed for complete file name. */
+ $? "+ dk3app_delete_one_temp_file %lu %u", n, s
+ sprintf(fnb, "/%08lx.%03x", n, s);
+ ra = app;
+ if((*f) & 1) { ra = NULL; }
+ if(dk3str_cnv_c8_to_str_app(fnb2, 15, fnb, ra)) {
+ sz = dk3str_len(app->n_tmpdir) + dk3str_len(fnb2);
+ if(sz < DK3_SIZEOF(buffer,dkChar)) {
+ dk3str_cpy_not_overlapped(buffer, app->n_tmpdir);
+ dk3str_cat(buffer, fnb2);
+ dk3str_correct_filename(buffer);
+#if VERSION_BEFORE_20150821
+ ra = app;
+ if((*f) & 4) { ra = NULL; }
+#endif
+ if(!dk3app_remove_file_app(buffer, NULL)) {
+ *f = ((*f) | 4);
+ }
+ } else {
+ if(!((*f) & 2)) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 37);
+ *f = ((*f) | 2);
+ }
+ }
+ } else {
+ *f = ((*f) | 1);
+ } $? "- dk3app_delete_one_temp_file"
+}
+
+
+
+/** Delete all temporary files of an application for a core name.
+ @param app Application structure.
+ @param n Number to build core file name.
+ @param f Pointer to error code variable.
+*/
+static
+void
+dk3app_delete_all_temp_files_for(dk3_app_t *app, unsigned long n, int *f)
+{
+ unsigned u; /* Used for file name suffix. */
+ $? "+ dk3app_delete_all_temp_files_for %lu", n
+ for(u = 0; u < 0x1000U; u++) {
+ dk3app_delete_one_temp_file(app, n, u, f);
+ } $? "- dk3app_delete_all_temp_files_for"
+}
+
+
+
+/** Delete all temporary files of an application.
+ @param app Application structure.
+*/
+static
+void
+dk3app_remove_temporary_files(dk3_app_t *app)
+{
+ unsigned long ul = 0UL; /* Used for base file name. */
+ unsigned u = 0; /* Used for suffixes of final base. */
+ int f = 0; /* Error checking variable. */
+ $? "+ dk3app_remove_temporary_files"
+ if(app->n_tmpdir) {
+ f = 0;
+ if(app->i_tmpcarry) {
+ for(ul = 0UL; ul < 0xFFFFFFFFUL; ul++) {
+ dk3app_delete_all_temp_files_for(app, ul, &f);
+ }
+ dk3app_delete_all_temp_files_for(app, 0xFFFFFFFFUL, &f);
+ } else {
+ for(ul = 0UL; ul < app->ul_tmpname; ul++) {
+ dk3app_delete_all_temp_files_for(app, ul, &f);
+ }
+ for(u = 0; u < app->u_tmpsuffix; u++) {
+ dk3app_delete_one_temp_file(app, app->ul_tmpname, u, &f);
+ }
+ dk3app_delete_one_temp_file(app, app->ul_tmpname, app->u_tmpsuffix, &f);
+ }
+ dk3sf_remove_dir_app(app->n_tmpdir, NULL);
+ } $? "- dk3app_remove_temporary_files"
+}
+
+
+
+/** Construct configuration file name candidate.
+ When searching for files (configuration or resource files) we
+ specify the sort file name without leading directory.
+ During the search process we do several tests prepending
+ directory names before the short file name.
+ This function is used to construct a file name.
+ @param app Application structure.
+ @param fn File name.
+ @param db Result buffer.
+ @param sz Size of \a db (number of characters).
+ @param passno Pass number (0-15).
+ @param verb Flag: Diagnostic messages enabled.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3app_config_name(
+ dk3_app_t *app, dkChar const *fn, dkChar *db, size_t sz, int passno, int verb
+)
+{
+ int back = 0;
+ dkChar const *ptr1 = NULL; /* Base directory (etc or share). */
+ dkChar const *ptr2 = NULL; /* Subdirectory (app, group, dk3app or none). */
+ dkChar const *ptr3 = NULL; /* Application or group name. */
+ size_t mysz = 0; /* Buffer size needed for all components. */
+ $? "+ dk3app_config_name \"%!ds\" pass=%d", TR_STR(fn), passno
+ ptr1 = NULL; ptr2 = NULL; ptr3 = NULL;
+ switch(passno) {
+
+#if VERSION_BEFORE_20110219
+ case 0: { ptr1 = app->n_sharedir; ptr2 = dk3app_no_loc[17]; } break;
+ case 2: { ptr1 = app->n_sharedir; ptr2 = app->n_appgroup; } break;
+ case 3: { ptr1 = app->n_etcdir; ptr2 = app->n_appgroup; } break;
+ case 4: { ptr1 = app->n_sharedir; ptr2 = app->n_app; } break;
+ case 5: { ptr1 = app->n_etcdir; ptr2 = app->n_app; } break;
+ case 6: { ptr1 = app->n_homedir; ptr2 = dk3app_no_loc[18]; } break;
+ case 7: {
+ ptr1 = app->n_homedir; ptr2 = dk3app_no_loc[18]; ptr3 = app->n_appgroup;
+ } break;
+ case 8: {
+ ptr1 = app->n_homedir; ptr2 = dk3app_no_loc[18]; ptr3 = app->n_app;
+ } break;
+ case 9: {
+ ptr1 = dk3app_no_loc[19];
+ } break;
+ default: { /* 1 */
+ ptr1 = app->n_etcdir; ptr2 = dk3app_no_loc[17];
+ } break;
+#else
+ case 0: {
+ ptr1 = app->n_sharedir; ptr2 = dk3app_no_loc[17];
+ } break;
+ case 1: {
+ ptr1 = app->n_etcdir; ptr2 = dk3app_no_loc[17];
+ } break;
+ case 2: {
+ ptr1 = app->n_sharedir; ptr2 = dk3app_no_loc[17];
+ } break;
+ case 3: {
+ ptr1 = app->n_etcdir; ptr2 = dk3app_no_loc[17];
+ } break;
+ case 4: {
+ ptr1 = app->n_sharedir; ptr2 = app->n_appgroup;
+ } break;
+ case 5: {
+ ptr1 = app->n_etcdir; ptr2 = app->n_appgroup;
+ } break;
+ case 6: {
+ ptr1 = app->n_sharedir; ptr2 = app->n_appgroup;
+ } break;
+ case 7: {
+ ptr1 = app->n_etcdir; ptr2 = app->n_appgroup;
+ } break;
+ case 8: {
+ ptr1 = app->n_sharedir; ptr2 = app->n_app;
+ } break;
+ case 9: {
+ ptr1 = app->n_etcdir; ptr2 = app->n_app;
+ } break;
+ case 10: {
+ ptr1 = app->n_sharedir; ptr2 = app->n_app;
+ } break;
+ case 11: {
+ ptr1 = app->n_etcdir; ptr2 = app->n_app;
+ } break;
+ case 12: {
+ ptr1 = app->n_homedir; ptr2 = dk3app_no_loc[18];
+ } break;
+ case 13: {
+ ptr1 = app->n_homedir; ptr2 = dk3app_no_loc[18]; ptr3 = app->n_appgroup;
+ } break;
+ case 14: {
+ ptr1 = app->n_homedir; ptr2 = dk3app_no_loc[18]; ptr3 = app->n_app;
+ } break;
+ case 15: {
+ ptr1 = dk3app_no_loc[19];
+ } break;
+#endif
+ }
+ mysz = dk3str_len(fn);
+ if(ptr1) {
+ mysz += dk3str_len(ptr1);
+ mysz++;
+ }
+ if(ptr2) {
+ mysz += dk3str_len(ptr2);
+ mysz++;
+ }
+ if(ptr3) {
+ mysz += dk3str_len(ptr3);
+ mysz++;
+ }
+ switch(passno) {
+ case 2: case 3: case 6: case 7: case 10: case 11: {
+ mysz += dk3str_len(dk3app_no_loc[32]);
+ } break;
+ }
+ if(mysz < sz) {
+ if(ptr1) {
+ dk3str_cpy_not_overlapped(db, ptr1);
+ if(ptr2) {
+ dk3str_cat(db, dk3app_no_loc[20]);
+ dk3str_cat(db, ptr2);
+ }
+ if(ptr3) {
+ dk3str_cat(db, dk3app_no_loc[20]);
+ dk3str_cat(db, ptr3);
+ }
+ switch(passno) {
+ case 2: case 3: case 6: case 7: case 10: case 11: {
+ dk3str_cat(db, dk3app_no_loc[32]);
+ } break;
+ }
+ dk3str_cat(db, dk3app_no_loc[20]);
+ dk3str_cat(db, fn);
+ back = 1; $? ". file name = \"%!ds\"", db
+ } else {
+ if(verb) {
+ /* Internal error, some directory not set! */
+ }
+ }
+ } else {
+ if(verb) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ } $? "- dk3app_config_name %d", back
+ return back;
+}
+
+
+
+/** Unconfigure application (delete registry key or config file).
+ @param app Application to unconfigure.
+*/
+static
+void
+dk3app_do_unconfigure(dk3_app_t *app)
+{
+ dkChar fnb[DK3_MAX_PATH]; /* File name buffer for config file. */
+
+ if(dk3app_config_name(app, dk3app_no_loc[21], fnb, DK3_MAX_PATH, 14, 0)) {
+ (void)dk3sf_remove_file_app(fnb, app);
+ }
+}
+
+
+
+/** Save self-set preferences to registry or file.
+ @param app Application structure.
+*/
+static
+void
+dk3app_do_save_config(dk3_app_t *app)
+{
+ dkChar fnb[DK3_MAX_PATH]; /* File name buffer for conf file. */
+ dkChar *ptr = NULL; /* Slash/backslash correction. */
+ FILE *fipo = NULL; /* Used to write file. */
+ dk3app_pref_t *p1 = NULL; /* Preference entry to process. */
+ dk3app_pref_t *p2 = NULL; /* Check in higher priorized storage. */
+ $? "+ dk3app_do_save_config"
+ if(dk3app_config_name(app, dk3app_no_loc[21], fnb, DK3_MAX_PATH, 14, 0)) {
+ $? ". file name found \"%!ds\"", fnb
+ ptr = dk3str_rchr(fnb, DK3_CHAR_SEP);
+ if(ptr) {
+ *ptr = dkT('\0');
+ $? ". mkdir %!ds", fnb
+ dk3sf_mkdir_app(fnb, 0700, NULL);
+ *ptr = DK3_CHAR_SEP;
+ }
+ fipo = dk3sf_fopen_app(fnb, dk3app_no_loc[24], app); /* WRITE */
+ if(fipo) { $? ". file opened"
+#if DK3_ON_WINDOWS && (DK3_CHAR_SIZE > 1)
+ /* Switch to 16 bit characters. */
+ (void)_setmode(_fileno(fipo), _O_U16TEXT);
+ /* Write byte order marker. */
+ fputwc(0xFEFF, fipo);
+#endif
+ if((app->s_varprefs) && (app->i_varprefs)) {
+ dk3sto_it_reset(app->i_varprefs);
+ while((p1 = (dk3app_pref_t *)dk3sto_it_next(app->i_varprefs)) != NULL) {
+ p2 = NULL;
+ if((app->s_selfprefs) && (app->i_selfprefs)) {
+ p2 = (dk3app_pref_t *)dk3sto_it_find_like(app->i_selfprefs, p1, 0);
+ }
+ if(!(p2)) {
+ dk3sf_fputs(p1->k, fipo);
+ dk3sf_fputs(dk3app_no_loc[25], fipo);
+ dk3sf_fputs(p1->v, fipo);
+ dk3sf_fputs(dk3app_no_loc[26], fipo);
+ }
+ }
+ }
+ if((app->s_selfprefs) && (app->i_selfprefs)) {
+ dk3sto_it_reset(app->i_selfprefs);
+ while((p1 = (dk3app_pref_t *)dk3sto_it_next(app->i_selfprefs)) != NULL) {
+ dk3sf_fputs(p1->k, fipo);
+ dk3sf_fputs(dk3app_no_loc[25], fipo);
+ dk3sf_fputs(p1->v, fipo);
+ dk3sf_fputs(dk3app_no_loc[26], fipo);
+ }
+ }
+ fclose(fipo);
+ } else { $? "! failed to open file"
+ }
+ } else { $? "! file name not found"
+ } $? "- dk3app_do_save_config"
+}
+
+
+
+
+
+void
+dk3app_close(dk3_app_t *app)
+{
+ int i = 0; /* Used to release argv memory. */
+ dk3app_pref_t *pref = NULL; /* Used to delete preference entries. */
+ dk3app_mc_t *mcptr = NULL; /* Used to delete message catalogs. */
+ $? "+ dk3app_close"
+
+ if(app) {
+ if(app->f_unconfigure) { $? ". must unconfigure application"
+ dk3app_do_unconfigure(app);
+ } else {
+ if(app->f_prefschanged) { $? ". must save self-set preferences"
+ dk3app_do_save_config(app);
+ }
+ }
+ /* Clean up preferences system. */ $? ". clean up preferences"
+ if(app->s_selfprefs) {
+ if(app->i_selfprefs) {
+ dk3sto_it_reset(app->i_selfprefs);
+ while((pref = (dk3app_pref_t *)dk3sto_it_next(app->i_selfprefs)) != NULL) {
+ dk3app_pref_delete(pref);
+ }
+ dk3sto_it_close(app->i_selfprefs);
+ }
+ dk3sto_close(app->s_selfprefs);
+ } app->s_selfprefs = NULL; app->i_selfprefs = NULL;
+ if(app->s_cmdprefs) {
+ if(app->i_cmdprefs) {
+ dk3sto_it_reset(app->i_cmdprefs);
+ while((pref = (dk3app_pref_t *)dk3sto_it_next(app->i_cmdprefs)) != NULL) {
+ dk3app_pref_delete(pref);
+ }
+ dk3sto_it_close(app->i_cmdprefs);
+ }
+ dk3sto_close(app->s_cmdprefs);
+ } app->s_cmdprefs = NULL; app->i_cmdprefs = NULL;
+ if(app->s_sysprefs) {
+ if(app->i_sysprefs) {
+ dk3sto_it_reset(app->i_sysprefs);
+ while((pref = (dk3app_pref_t *)dk3sto_it_next(app->i_sysprefs)) != NULL)
+ {
+ dk3app_pref_delete(pref);
+ }
+ dk3sto_it_close(app->i_sysprefs);
+ }
+ dk3sto_close(app->s_sysprefs);
+ } app->s_sysprefs = NULL; app->i_sysprefs = NULL;
+ if(app->s_constprefs) {
+ if(app->i_constprefs) {
+ dk3sto_it_reset(app->i_constprefs);
+ while((pref = (dk3app_pref_t *)dk3sto_it_next(app->i_constprefs)) != NULL)
+ {
+ dk3app_pref_delete(pref);
+ }
+ dk3sto_it_close(app->i_constprefs);
+ }
+ dk3sto_close(app->s_constprefs);
+ } app->s_constprefs = NULL; app->i_constprefs = NULL;
+ if(app->s_varprefs) {
+ if(app->i_varprefs) {
+ dk3sto_it_reset(app->i_varprefs);
+ while((pref = (dk3app_pref_t *)dk3sto_it_next(app->i_varprefs)) != NULL)
+ {
+ dk3app_pref_delete(pref);
+ }
+ dk3sto_it_close(app->i_varprefs);
+ }
+ dk3sto_close(app->s_varprefs);
+ } app->s_varprefs = NULL; app->i_varprefs = NULL;
+ /* Clean up temporary directory. */ $? ". clean up tmp dir"
+ if(app->ll_highest > app->ll_tmp_keep) {
+ dk3app_remove_temporary_files(app);
+ }
+ /* Remove log file if no longer needed. */ $? ". remove log file"
+ if(DK3_APP_TYPE_DAEMON != app->app_type) {
+ dk3app_log_i3(app, DK3_LL_DEBUG, 21, 22, app->n_app);
+ if(app->ll_highest > app->ll_file_keep) {
+ dk3sf_remove_file_app(app->n_logfilename, NULL);
+ }
+ }
+ /* Unset resources, release resources. */
+ app->ll_file = app->ll_stderr = app->ll_file_keep = app->ll_highest = 0;
+ app->app_type = 0;
+ app->msg = NULL;
+ app->n_sourcefile = NULL;
+ app->sourceline = 0UL; $? ". release message catalogs"
+ if(app->s_mc) {
+ if(app->i_mc) {
+ dk3sto_it_reset(app->i_mc);
+ while((mcptr = (dk3app_mc_t *)dk3sto_it_next(app->i_mc)) != NULL)
+ {
+ dk3app_mc_delete(mcptr);
+ }
+ dk3sto_it_close(app->i_mc);
+ }
+ dk3sto_close(app->s_mc);
+ } app->s_mc = NULL; app->i_mc = NULL; $? ". release cmd args"
+ if(app->argv) {
+ dkChar const **ptr;
+ ptr = (dkChar const **)(app->argv);
+ for(i = 0; i < app->argc; i++) {
+ dk3_release(*ptr);
+ ptr++;
+ }
+ } $? ". release other names"
+ dk3_release(app->n_app);
+ dk3_release(app->n_execfile);
+ dk3_release(app->n_bindir);
+ dk3_release(app->n_etcdir);
+ dk3_release(app->n_sharedir);
+ dk3_release(app->n_vardir);
+ dk3_release(app->n_logname);
+ dk3_release(app->n_homedir);
+ dk3_release(app->n_appgroup);
+ dk3_release(app->n_logfilename);
+ dk3_release(app->n_tmpdir);
+ dk3_release(app->n_language);
+ dk3_release(app->n_region);
+ dk3_release(app->n_langstr);
+ dk3_release(app->n_hostname);
+ dk3_delete(app);
+ } $? "- dk3app_close"
+}
+
+
+
+int
+dk3app_get_default_stdin_encoding(dk3_app_t const *app)
+{
+ int back = 0;
+ if(app) {
+ back = app->i_output_encoding;
+#if DK3_CHAR_SIZE > 1
+#if DK3_ON_WINDOWS
+ back = DK3_FILE_ENCODING_ASCII;
+#endif
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3app_get_default_file_encoding(dk3_app_t const *app)
+{
+ int back = 0;
+ if(app) {
+ back = app->i_output_encoding;
+#if DK3_CHAR_SIZE > 1
+#if DK3_ON_WINDOWS
+ back = DK3_FILE_ENCODING_ASCII;
+#endif
+#endif
+ }
+ return back;
+}
+
+
+
+
+/** Initialize application structure.
+ @param app Application to initialize.
+*/
+static
+void
+dk3app_init(dk3_app_t *app)
+{
+ $? "+ dk3app_init"
+ app->app_type = 0;
+ app->msg = NULL;
+ app->n_sourcefile = NULL;
+ app->sourceline = 0UL;
+ app->ll_file = DK3_LL_NONE;
+ app->ll_stderr = DK3_LL_INFO;
+ app->ll_file_keep = DK3_LL_NONE;
+ app->ll_tmp_keep = DK3_LL_NONE;
+ app->ll_highest = DK3_LL_IGNORE;
+ app->argv = NULL;
+ app->argc = 0;
+ app->n_app = NULL;
+ app->n_execfile = NULL;
+ app->n_bindir = NULL;
+ app->n_etcdir = NULL;
+ app->n_sharedir = NULL;
+ app->n_vardir = NULL;
+ app->n_logname = NULL;
+ app->n_homedir = NULL;
+ app->n_appgroup = NULL;
+ app->n_logfilename = NULL;
+ app->n_tmpdir = NULL;
+ app->n_language = NULL;
+ app->n_region = NULL;
+ app->n_langstr = NULL;
+ app->ul_tmpname = 0UL;
+ app->u_tmpsuffix = 0U;
+ app->i_tmpcarry = 0;
+ app->n_hostname = NULL;
+#if DK3_CHAR_SIZE > 1
+ app->i_encoding = DK3_ENCODING_UTF16;
+#if DK3_BIGENDIAN
+ app->i_output_encoding = DK3_FILE_ENCODING_UTF16_MSB_FIRST;
+#else
+ app->i_output_encoding = DK3_FILE_ENCODING_UTF16_LSB_FIRST;
+#endif
+#else
+ app->i_encoding = DK3_ENCODING_PLAIN;
+ app->i_output_encoding = DK3_FILE_ENCODING_ASCII;
+#endif
+ app->i_stdin_input_encoding = dk3app_get_default_stdin_encoding(app);
+ $? "+ i_stdin_input_encoding=%d", app->i_stdin_input_encoding
+ app->i_file_input_encoding = dk3app_get_default_file_encoding(app);
+ app->de = 0; /* No error found yet. */ $? "- dk3app_init"
+ app->s_mc = NULL;
+ app->i_mc = NULL;
+ app->s_cmdprefs = NULL;
+ app->i_cmdprefs = NULL;
+ app->s_selfprefs = NULL;
+ app->i_selfprefs = NULL;
+ app->f_unconfigure = 0;
+ app->f_prefschanged = 0;
+ app->f_readytolog = 0;
+ app->s_sysprefs = NULL;
+ app->i_sysprefs = NULL;
+ app->s_constprefs = NULL;
+ app->i_constprefs = NULL;
+ app->s_varprefs = NULL;
+ app->i_varprefs = NULL;
+ app->f_first_file_log = 1;
+ app->f_rand_initialized = 0;
+ app->f_rand_success = 0;
+ app->rand_type = 0;
+ app->cr_log = 0;
+ app->cr_tmp = 0;
+ app->t_last_log_stderr = (dk3_time_t)0UL;
+ app->t_last_log_file = (dk3_time_t)0UL;
+}
+
+
+
+/** Copy binary directory name to other directory names.
+ @param app Application structure.
+*/
+static
+void
+dk3app_copy_bin_to_others(dk3_app_t *app)
+{
+ $? "+ dk3app_copy_bin_to_others"
+ app->n_etcdir = dk3str_dup_app(app->n_bindir, NULL);
+ if(app->n_etcdir) {
+ app->n_sharedir = dk3str_dup_app(app->n_bindir, NULL);
+ if(app->n_sharedir) {
+ app->n_vardir = dk3str_dup_app(app->n_bindir, NULL);
+ if(!(app->n_vardir)) {
+ app->de = 9;
+ }
+ } else {
+ app->de = 8;
+ }
+ } else {
+ app->de = 7;
+ } $? "- dk3app_copy_bin_to_others"
+}
+
+
+#if DK3_ON_WINDOWS
+
+#if VERSION_BEFORE_20131022
+
+/** Open a registry key.
+ @param k Parent key (HKLM or HKCU).
+ @param n Key name.
+ @param p Permissions needed.
+ @param kp Pointer to result key variable.
+ @return ERROR_SUCCESS on success, other values indicate an error.
+*/
+static
+long
+dk3app_reg_open_key(HKEY k, dkChar const *n, int p, HKEY *kp)
+{
+ long back = 0L;
+#if DK3_CHAR_SIZE > 1
+ back = RegOpenKeyExW(k, n, (DWORD)0, p, kp);
+#else
+ back = RegOpenKeyExA(k, n, (DWORD)0, p, kp);
+#endif
+ return back;
+}
+
+
+
+/** Retrieve a value from the registry.
+ @param k Registry key.
+ @param n Entry name.
+ @param tp Entry type.
+ @param b Result buffer address.
+ @param len In: size of buffer, out: number of bytes used.
+ @return ERROR_SUCCESS on success, any other value indicates an error.
+*/
+static
+long
+dk3app_reg_query(HKEY k, dkChar const *n, DWORD *tp, LPBYTE b, DWORD *len)
+{
+ long back = 0L;
+#if DK3_CHAR_SIZE > 1
+ back = RegQueryValueExW(k, n, NULL, tp, b, len);
+#else
+ back = RegQueryValueExA(k, n, NULL, tp, b, len);
+#endif
+ return back;
+}
+
+
+
+/** Retrieve string value from registry.
+ @param k Key.
+ @param n Entry name.
+ @param b Result buffer.
+ @param sz Size of \a b (number of characters).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3app_reg_query_str(HKEY k, dkChar const *n, dkChar *b, size_t sz)
+{
+ int back = 0;
+ DWORD tp = REG_SZ; /* Registry entry type. */
+ DWORD len = 0L; /* Length of arguments and results. */
+ LONG res = 0L; /* Registry operation result. */
+ tp = REG_SZ;
+ len = (DWORD)(sz * DK3_CHAR_SIZE);
+ res = dk3app_reg_query(k, n, &tp, (LPBYTE)b, &len);
+ if(ERROR_SUCCESS == res) {
+ if((REG_SZ == tp) || (REG_EXPAND_SZ == tp)) {
+ if(len > 0) {
+#if DK3_CHAR_SIZE > 1
+ len = len / DK3_CHAR_SIZE;
+#endif
+ b[(((size_t)len) < sz) ? len : (sz - 1)] = dkT('\0');
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+
+#endif
+
+#endif
+
+
+
+/** Get users language/region/encoding setting.
+ @param app Application structure.
+ @param db Result buffer.
+ @param sz Size of \a db (number of characters).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3app_get_language_string(dk3_app_t *app, dkChar *db, size_t sz)
+{
+ int back = 0;
+ $? "+ dk3app_get_language_string"
+#if DK3_ON_WINDOWS
+
+#if VERSION_BEFORE_20131022
+ {
+ LONG res = 0L; /* Registry operation result. */
+ HKEY key; /* Registry key. */
+ res = dk3app_reg_open_key(
+ HKEY_CURRENT_USER,
+ dk3app_no_loc[12],
+ KEY_READ,
+ &key
+ );
+ if(ERROR_SUCCESS == res) {
+ back = dk3app_reg_query_str(key, dk3app_no_loc[13], db, sz);
+ if(back == 0) {
+ back = dk3app_reg_query_str(key, dk3app_no_loc[14], db, sz);
+ if(back) {
+ db[2] = dkT('\0');
+ }
+ }
+ RegCloseKey(key);
+ }
+ }
+#else
+ {
+ HKEY hk; /* Registry key. */
+ if(dk3wreg_key_open_read(HKEY_CURRENT_USER, dk3app_no_loc[12], &hk, NULL)) {
+ if(dk3wreg_get_sz(hk, dk3app_no_loc[13],db,sz,NULL)) {
+ back = 1;
+ } else {
+ if(dk3wreg_get_sz(hk, dk3app_no_loc[14],db,sz,NULL)) {
+ back = 1;
+ db[2] = dkT('\0');
+ }
+ }
+ dk3wreg_key_close(hk, dk3app_no_loc[12], NULL);
+ }
+ }
+#endif
+
+#else
+#if DK3_CHAR_SIZE == 1
+ {
+ char *ptr; /* Pointer to environment variable contents. */
+ ptr = getenv(dk3app_no_loc[11]);
+ if(ptr) {
+ if(dk3str_c8_len(ptr) < sz) {
+ dk3str_c8_cpy_not_overlapped(db, ptr);
+ back = 1;
+ } else {
+ dk3app_log_i1(app, DK3_LL_ERROR, 39);
+ }
+ }
+ }
+#endif
+#endif
+ $? "- dk3app_get_language_string %d", back
+ return back;
+}
+
+
+
+/** Find language, region and encoding.
+ @param app Application structure.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+*/
+static
+void
+dk3app_language_and_region(dk3_app_t *app, int argc, dkChar const * const *argv)
+{
+ dkChar buffer[DK3_MAX_PATH]; /* Buffer to store language/region name. */
+ dkChar *ptr; /* Used to find region. */
+ dkChar *p2; /* Used to convert to lower characters. */
+ $? "+ dk3app_language_and_region"
+ if(dk3app_get_language_string(app, buffer, DK3_SIZEOF(buffer,dkChar))) {
+ app->n_langstr = dk3str_dup_app(buffer, NULL); $? ". buffer=%!ds", buffer
+ if(app->n_langstr) {
+ ptr = dk3str_chr(buffer, dkT('.'));
+ if(ptr) {
+ *(ptr++) = dkT('\0'); $? ". encoding found"
+#if DK3_CHAR_SIZE == 1
+ if(dk3str_casecmp(ptr, dk3app_no_loc[15]) == 0) {
+ app->i_encoding = DK3_ENCODING_UTF8;
+ app->i_output_encoding = DK3_FILE_ENCODING_UTF8;
+ }
+ if(dk3str_casecmp(ptr, dk3app_no_loc[16]) == 0) {
+ app->i_encoding = DK3_ENCODING_UTF8;
+ app->i_output_encoding = DK3_FILE_ENCODING_UTF8;
+ }
+#endif
+ }
+ ptr = dk3str_chr(buffer, dkT('_'));
+#if DK3_ON_WINDOWS
+ if(!(ptr)) { ptr = dk3str_chr(buffer, dkT('-')); }
+#endif
+ if(ptr) { $? ". region found"
+ *(ptr++) = dkT('\0'); $? ". buffer=%!ds", buffer
+ p2 = ptr; while(*p2) { *p2 = dk3str_tolower(*p2); p2++; }
+ app->n_region = dk3str_dup_app(ptr, NULL);
+ if(!(app->n_region)) { $? "! region"
+ app->de = 29;
+ }
+ }
+ if(!(app->de)) { $? ". buffer=%!ds", buffer
+ p2 = buffer; while(*p2) { *p2 = dk3str_tolower(*p2); p2++; }
+ app->n_language = dk3str_dup_app(buffer, NULL);
+ if(!(app->n_language)) { $? "! language"
+ app->de = 30;
+ }
+ }
+ } else { $? "! language string"
+ app->de = 28;
+ }
+ } $? "- dk3app_language_and_region"
+}
+
+
+
+/** Check whether a directory name is a root directory.
+ @param dirname Directory name to check.
+ @return 1 for root directory, 0 for others.
+*/
+static
+int
+dk3app_is_root_directory(dkChar const *dirname)
+{
+ int back = 0;
+#if DK3_ON_WINDOWS
+ size_t sz;
+ sz = dk3str_len(dirname);
+ if(1 == sz) {
+ if(dkT('\\') == dirname[0]) {
+ back = 1;
+ }
+ } else {
+ if(3 == sz) {
+ if((dkT('a') <= dirname[0]) && (dkT('z') >= dirname[0])) {
+ back = 1;
+ } else {
+ if((dkT('A') <= dirname[0]) && (dkT('Z') >= dirname[0])) {
+ back = 1;
+ }
+ }
+ if(back) {
+ back = 0;
+ if(dkT(':') == dirname[1]) {
+ if(dkT('\\') == dirname[2]) {
+ back = 1;
+ }
+ }
+ }
+ }
+ }
+#else
+ if(dk3str_len(dirname) == 1) {
+ if(dkT('/') == dirname[0]) {
+ back = 1;
+ }
+ }
+#endif
+ return back;
+}
+
+
+
+/** Reduce a directory name referring to a bin (or sbin or libexec/xxx
+ directory.
+ @param dirname Directory name to modify.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3app_reduce_bindir_name(dkChar *dirname)
+{
+ dkChar buffer[DK3_MAX_PATH];
+ dkChar *pCurrent; /* Current path component. */
+ dkChar *pPrevious; /* Previous path component. */
+ size_t sz;
+ int ai; /* Array index. */
+ int cc; /* Flag: Can continue. */
+ int back = 0;
+ $? "+ dk3app_reduce_bindir_name \"%!ds\"", dirname
+ if(dk3str_len(dirname) < DK3_SIZEOF(buffer,dkChar)) {
+ dk3str_cpy_not_overlapped(buffer, dirname);
+ pCurrent = NULL; pPrevious = NULL;
+ cc = 1;
+ while(cc) { $? ". while \"%!ds\"", buffer
+ cc = 0;
+ if(dk3str_len(buffer) > 1) { $? ". length ok"
+ if(!dk3app_is_root_directory(buffer)) { $? ". not root"
+ pCurrent = dk3str_rchr(buffer, DK3_CHAR_SEP);
+ if(pCurrent) { $? ". separator found"
+ cc = 1; $? ". dir \"%!ds\"",&(pCurrent[1])
+#if DK3_ON_WINDOWS
+ ai = dk3str_array_index(dk3app_bindir_candidates,&(pCurrent[1]),0);
+#else
+ ai = dk3str_array_index(dk3app_bindir_candidates,&(pCurrent[1]),1);
+#endif
+ if(-1 < ai) { $? ". this is a final name"
+ cc = 0;
+ sz = dk3str_len(buffer);
+ dirname[sz] = dkT('\0');
+ back = 1;
+ } else { $? ". not a final name"
+ if(pPrevious) { *pPrevious = DK3_CHAR_SEP; }
+ pPrevious = pCurrent;
+ *pCurrent = dkT('\0');
+ }
+ }
+ }
+ }
+ }
+ } $? "- dk3app_reduce_bindir_name %d \"%!ds\"", back, dirname
+ return back;
+}
+
+
+
+/** Find all the names. Set app->de on errors, don't report directly.
+ @param app Application to configure.
+ @param wd Current working directory.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+*/
+static
+void
+dk3app_find_names(
+ dk3_app_t *app, dkChar const *wd,
+ int argc, dkChar const * const *argv
+)
+{
+ int must_relocate = 0; /* Flag: Must relocate. */
+ int redres; /* Result from reduce directory. */
+#if DK3_HAVE_UMASK
+ mode_t oldumask; /* Umask before mkdir. */
+#endif
+ dkChar *n_app = NULL; /* Application name. */
+ dkChar *p = NULL; /* Modify application name. */
+ dkChar const *q = NULL; /* Installation bin directory. */
+ dkChar *x = NULL; /* Deal with executable name. */
+ dkChar buffer[DK3_MAX_PATH]; /* Used to construct file names. */
+ char pidbuffer[128]; /* Buffer for PID number (8-bit). */
+ dkChar dkpidbuffer[128]; /* Buffer for PID number. */
+ size_t tsl = 0; /* Buffer size needed. */
+ $? "+ dk3app_find_names"
+ p = dk3str_rchr(argv[0], DK3_CHAR_SEP);
+ if(p) { p++; } else { p = (dkChar *)(argv[0]); }
+ n_app = dk3str_dup_app(p, NULL); $? ". program name \"%!ds\"", p
+ if(n_app) { $? ". program name \"%!ds\"", n_app
+ app->n_app = (dkChar const *)n_app; $? ". program name \"%!ds\"", app->n_app
+ p = dk3str_chr(n_app, DK3_CHAR_DOT);
+ if(p) { *p = DK3_CHAR_0; }
+ if(dk3sf_find_exec_app(buffer,DK3_SIZEOF(buffer,dkChar),wd,argv[0], NULL)) {
+ x = dk3str_dup_app(buffer, NULL);
+ app->n_execfile = x;
+ if(app->n_execfile) {
+ p = dk3str_rchr(buffer, DK3_CHAR_SEP);
+ if(p) {
+ *p = DK3_CHAR_0;
+ app->n_bindir = dk3str_dup_app(buffer, NULL);
+ if(app->n_bindir) {
+ redres = dk3app_reduce_bindir_name(buffer);
+ q = dk3inst_get_directory(DK3_INST_BIN);
+ if(dk3str_fncmp(buffer, q)) {
+ q = dk3inst_get_directory(DK3_INST_SBIN);
+ if(dk3str_fncmp(buffer, q)) {
+ q = dk3inst_get_directory(DK3_INST_LIB);
+ if(dk3str_fncmp(buffer, q)) {
+ q = dk3inst_get_directory(DK3_INST_LIBEXEC);
+ if(dk3str_fncmp(buffer, q)) {
+ must_relocate = 1;
+ }
+ }
+ }
+ }
+ if(must_relocate) {
+ p = dk3str_rchr(buffer, DK3_CHAR_SEP);
+ if(p) {
+ p++;
+ if(redres) {
+ *p = DK3_CHAR_0;
+ tsl = dk3str_len(buffer);
+ tsl += dk3str_len(dk3app_no_loc[1]);
+ if(tsl < DK3_SIZEOF(buffer,dkChar)) {
+ dk3str_cpy_not_overlapped(p, dk3app_no_loc[1]);
+ app->n_etcdir = dk3str_dup_app(buffer, NULL);
+ if(app->n_etcdir) {
+ *p = DK3_CHAR_0;
+ tsl = dk3str_len(buffer);
+ tsl += dk3str_len(dk3app_no_loc[2]);
+ if(tsl < DK3_SIZEOF(buffer,dkChar)) {
+ dk3str_cpy_not_overlapped(p, dk3app_no_loc[2]);
+ app->n_sharedir = dk3str_dup_app(buffer, NULL);
+ if(app->n_sharedir) {
+ *p = DK3_CHAR_0;
+ tsl = dk3str_len(buffer);
+ tsl += dk3str_len(dk3app_no_loc[3]);
+ if(tsl < DK3_SIZEOF(buffer,dkChar)) {
+ dk3str_cpy_not_overlapped(p, dk3app_no_loc[3]);
+ app->n_vardir = dk3str_dup_app(buffer, NULL);
+ if(!(app->n_vardir)) {
+ app->de = 9;
+ }
+ } else {
+ app->de = 13;
+ }
+ } else {
+ app->de = 8;
+ }
+ } else {
+ app->de = 12;
+ }
+ } else {
+ app->de = 7;
+ }
+ } else {
+ app->de = 11;
+ }
+ } else {
+ dk3app_copy_bin_to_others(app);
+ }
+ } else {
+ dk3app_copy_bin_to_others(app);
+ }
+ } else {
+ q = dk3inst_get_directory(DK3_INST_SYSCONF);
+ app->n_etcdir = dk3str_dup_app(q, NULL);
+ if(app->n_etcdir) {
+ q = dk3inst_get_directory(DK3_INST_DATAROOT);
+ app->n_sharedir = dk3str_dup_app(q, NULL);
+ if(app->n_sharedir) {
+ q = dk3inst_get_directory(DK3_INST_LOCALSTATE);
+ app->n_vardir = dk3str_dup_app(q, NULL);
+ if(!(app->n_vardir)) {
+ app->de = 9;
+ }
+ } else {
+ app->de = 8;
+ }
+ } else {
+ app->de = 7;
+ }
+ }
+ if(!(app->de)) {
+ if(dk3sf_get_logname_app(buffer,DK3_SIZEOF(buffer,dkChar),NULL)) {
+ app->n_logname = dk3str_dup_app(buffer,NULL);
+ if(!(app->n_logname)) {
+ app->de = 15;
+ }
+ } else {
+ app->de = 14;
+ }
+ }
+ if(!(app->de)) {
+ if(dk3sf_get_hostname_app(buffer,DK3_SIZEOF(buffer,dkChar),NULL))
+ {
+ app->n_hostname = dk3str_dup_app(buffer, NULL);
+ if(!(app->n_hostname)) {
+ app->de = 37;
+ }
+ } else {
+ app->de = 38;
+ }
+ }
+ if(!(app->de)) {
+ if(dk3sf_get_home_app(buffer,DK3_SIZEOF(buffer,dkChar), NULL)) {
+ app->n_homedir = dk3str_dup_app(buffer,NULL);
+ if(!(app->n_homedir)) {
+ app->de = 17;
+ }
+ } else {
+ app->de = 16;
+ }
+ }
+ if(!(app->de)) {
+ switch(app->app_type) {
+ case DK3_APP_TYPE_COMMAND:
+ case DK3_APP_TYPE_GUI: {
+ tsl = dk3str_len(app->n_homedir);
+ tsl += dk3str_len(dk3app_no_loc[4]);
+ tsl += dk3str_len(dk3app_no_loc[20]);
+ tsl += dk3str_len(app->n_app);
+ tsl += dk3str_len(dk3app_no_loc[5]);
+ (void)dk3ma_um_to_c8_string(
+ pidbuffer, sizeof(pidbuffer), dk3sf_getpid()
+ );
+ if(dk3str_cnv_c8_to_str_app(
+ dkpidbuffer, DK3_SIZEOF(dkpidbuffer,dkChar),
+ pidbuffer, NULL
+ )
+ )
+ {
+ tsl += dk3str_len(dkpidbuffer);
+ tsl += dk3str_len(dk3app_no_loc[6]);
+ if(tsl < DK3_SIZEOF(buffer,dkChar)) {
+ dk3str_cpy_not_overlapped(buffer, app->n_homedir);
+ dk3str_cat(buffer, dk3app_no_loc[4]);
+ dk3str_correct_filename(buffer);
+ $? ". mkdir ${HOME}/log = %!ds", buffer
+#if VERSION_BEFORE_20160128
+ if(dk3sf_mkdir_app(buffer, 0700, NULL)) {
+ dk3str_cat(buffer, dk3app_no_loc[20]);
+ dk3str_cat(buffer, app->n_app);
+ dk3str_cat(buffer, dk3app_no_loc[5]);
+ dk3str_cat(buffer, dkpidbuffer);
+ dk3str_cat(buffer, dk3app_no_loc[6]);
+ dk3str_correct_filename(buffer);
+ app->n_logfilename = dk3str_dup_app(buffer,NULL);
+ if(!(app->n_logfilename)) {
+ app->de = 21;
+ }
+ } else {
+ app->de = 20;
+ }
+#else
+ /* 2016-01-28
+ Do not immediately create the log directory
+ for non-daemon programs.
+ */
+ dk3str_cat(buffer, dk3app_no_loc[20]);
+ dk3str_cat(buffer, app->n_app);
+ dk3str_cat(buffer, dk3app_no_loc[5]);
+ dk3str_cat(buffer, dkpidbuffer);
+ dk3str_cat(buffer, dk3app_no_loc[6]);
+ dk3str_correct_filename(buffer);
+ app->n_logfilename = dk3str_dup_app(buffer,NULL);
+ if(!(app->n_logfilename)) {
+ app->de = 21;
+ }
+#endif
+ } else {
+ app->de = 19;
+ }
+ } else {
+ app->de = 22;
+ }
+ } break;
+ case DK3_APP_TYPE_DAEMON: {
+ tsl = dk3str_len(app->n_vardir);
+ tsl += dk3str_len(dk3app_no_loc[4]);
+ tsl += dk3str_len(dk3app_no_loc[20]);
+ tsl += dk3str_len(app->n_app);
+ tsl += dk3str_len(dk3app_no_loc[20]);
+ tsl += dk3str_len(app->n_app);
+ tsl += dk3str_len(dk3app_no_loc[6]);
+#if DK3_HAVE_UMASK
+ oldumask = umask(0);
+#endif
+ if(tsl < DK3_SIZEOF(buffer,dkChar)) {
+ dk3str_cpy_not_overlapped(buffer, app->n_vardir);
+ dk3str_cat(buffer, dk3app_no_loc[4]);
+ $? ". mkdir %!ds", buffer
+ if(dk3sf_mkdir_app(buffer, 0755, NULL)) {
+ dk3str_cat(buffer, dk3app_no_loc[20]);
+ dk3str_cat(buffer, app->n_app);
+ $? ". mkdir %!ds", buffer
+ if(dk3sf_mkdir_app(buffer, 0755, NULL)) {
+ app->cr_log = 1;
+ dk3str_cat(buffer, dk3app_no_loc[20]);
+ dk3str_cat(buffer, app->n_app);
+ dk3str_cat(buffer, dk3app_no_loc[6]);
+ app->n_logfilename = dk3str_dup_app(buffer, NULL);
+ if(!(app->n_logfilename)) {
+ app->de = 21;
+ }
+ } else { $? "! mkdir \"%!ds\"", buffer
+ app->de = 20;
+ }
+ } else { $? "! mkdir \"%!ds\"", buffer
+ app->de = 20;
+ }
+ } else {
+ app->de = 19;
+ }
+#if DK3_HAVE_UMASK
+ umask(oldumask);
+#endif
+ } break;
+ }
+ }
+ if(!(app->de)) { $? ". find tmp dir"
+ switch(app->app_type) {
+ case DK3_APP_TYPE_DAEMON: {
+ if(app->n_vardir) {
+ if(app->n_app) {
+
+ (void)dk3ma_um_to_c8_string(
+ pidbuffer, sizeof(pidbuffer), dk3sf_getpid()
+ );
+ if(dk3str_cnv_c8_to_str_app(
+ dkpidbuffer, DK3_SIZEOF(dkpidbuffer,dkChar),
+ pidbuffer, NULL
+ )
+ )
+ {
+ tsl = dk3str_len(app->n_vardir);
+ tsl += dk3str_len(dk3app_no_loc[10]);
+ tsl += dk3str_len(dk3app_no_loc[20]);
+ tsl += dk3str_len(app->n_app);
+ tsl += dk3str_len(dk3app_no_loc[20]);
+ tsl += dk3str_len(dkpidbuffer);
+ if(tsl < DK3_SIZEOF(buffer,dkChar)) {
+ dk3str_cpy_not_overlapped(buffer, app->n_vardir);
+ dk3str_cat(buffer, dk3app_no_loc[10]);
+ dk3str_correct_filename(buffer);
+ $? ". mkdir /var/run = %!ds", buffer
+ (void)dk3sf_mkdir_app(buffer,0700,NULL);
+ dk3str_cat(buffer, dk3app_no_loc[20]);
+ dk3str_cat(buffer, app->n_app);
+ dk3str_correct_filename(buffer);
+ $? ". mkdir /var/run/app %!ds", buffer
+ (void)dk3sf_mkdir_app(buffer,0700,NULL);
+ dk3str_cat(buffer, dk3app_no_loc[20]);
+ dk3str_cat(buffer, dkpidbuffer);
+ $? ". create process temporary directory"
+ $? ". mkdir /var/run/app/pid = %!ds", buffer
+ if(dk3sf_mkdir_app(buffer,0700,NULL)) {
+ app->cr_tmp = 1;
+ app->n_tmpdir = dk3str_dup_app(buffer, NULL);
+ if(!(app->n_tmpdir)) {
+ app->de = 25;
+ dk3sf_remove_dir_app(buffer, NULL);
+ }
+ } else {
+ app->de = 26;
+ }
+ } else {
+ app->de = 19;
+ }
+ } else {
+ app->de = 22;
+ }
+ } else {
+ app->de = 24;
+ }
+ } else {
+ app->de = 27;
+ }
+ } break;
+ default: {
+ if(app->n_homedir) {
+ if(app->n_app) {
+ (void)dk3ma_um_to_c8_string(
+ pidbuffer, sizeof(pidbuffer), dk3sf_getpid()
+ );
+ if(dk3str_cnv_c8_to_str_app(
+ dkpidbuffer, DK3_SIZEOF(dkpidbuffer,dkChar),
+ pidbuffer, NULL
+ )
+ )
+ {
+ tsl = dk3str_len(app->n_homedir);
+ tsl += dk3str_len(dk3app_no_loc[9]);
+ tsl += dk3str_len(dk3app_no_loc[20]);
+ tsl += dk3str_len(app->n_app);
+ tsl += dk3str_len(dk3app_no_loc[5]);
+ tsl += dk3str_len(dkpidbuffer);
+ if(tsl < DK3_SIZEOF(buffer,dkChar)) {
+ dk3str_cpy_not_overlapped(buffer, app->n_homedir);
+ dk3str_cat(buffer, dk3app_no_loc[9]);
+ dk3str_correct_filename(buffer);
+#if VERSION_BEFORE_20160128
+ $? ". mkdir ${HOME}/tmp %!ds", buffer
+ if(dk3sf_mkdir_app(buffer,0700,NULL)) {
+ dk3str_cat(buffer, dk3app_no_loc[20]);
+ dk3str_cat(buffer, app->n_app);
+ dk3str_cat(buffer, dk3app_no_loc[5]);
+ dk3str_cat(buffer, dkpidbuffer);
+ dk3str_correct_filename(buffer);
+#if VERSION_BEFORE_20150318
+ $? ". mkdir ${HOME}/tmp/app-pid = %!ds", buffer
+ if(dk3sf_mkdir_app(buffer,0700,NULL)) {
+ app->n_tmpdir = dk3str_dup_app(buffer, NULL);
+ if(!(app->n_tmpdir)) {
+ app->de = 25;
+ dk3sf_remove_dir_app(buffer, NULL);
+ }
+ } else {
+ app->de = 26;
+ }
+#else
+ app->n_tmpdir = dk3str_dup_app(buffer, NULL);
+ if(!(app->n_tmpdir)) {
+ app->de = 25;
+ }
+#endif
+ } else {
+ app->de = 26;
+ }
+#else
+/* if VERSION_BEFORE_20160128 */
+ dk3str_cat(buffer, dk3app_no_loc[20]);
+ dk3str_cat(buffer, app->n_app);
+ dk3str_cat(buffer, dk3app_no_loc[5]);
+ dk3str_cat(buffer, dkpidbuffer);
+ dk3str_correct_filename(buffer);
+ app->n_tmpdir = dk3str_dup_app(buffer, NULL);
+ if(!(app->n_tmpdir)) {
+ app->de = 25;
+ }
+#endif
+/* if VERSION_BEFORE_20160128 */
+ } else {
+ app->de = 19;
+ }
+ } else {
+ app->de = 22;
+ }
+ } else {
+ app->de = 24;
+ }
+ } else {
+ app->de = 23;
+ }
+ } break;
+ }
+ }
+ } else {
+ app->de = 6;
+ }
+ } else {
+ app->de = 5;
+ }
+ } else {
+ app->de = 4;
+ }
+ } else {
+ app->de = 3;
+ }
+ } else {
+ app->de = 2;
+ } $? "- dk3app_find_names %d", app->de
+}
+
+
+
+/** Test whether a configuration file name candidate is valid.
+ @param app Application structure.
+ @param fn File name.
+ @param db Destination buffer.
+ @param sz Size of \a db (number of characters).
+ @param passno Pass number.
+ @param verb Flag: Diagnostic messages enabled.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3app_check_config_file(
+ dk3_app_t *app, dkChar const *fn, dkChar *db, size_t sz, int passno, int verb
+)
+{
+ int back = 0;
+ dk3_stat_t stb; /* Stat buffer used to check existance of files. */
+ $? "+ dk3app_check_config_file \"%!ds\" passno=%d", TR_STR(fn), passno
+ if(dk3app_config_name(app, fn, db, sz, passno, verb)) {
+ if(dk3sf_stat_app(&stb, db, NULL)) {
+ switch((stb.ft) & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_REGULAR: { back = 1; } break;
+ }
+ }
+ if(back) {
+ /* DEBUG Config file ... found. */
+ dk3app_log_i3(app, DK3_LL_DEBUG, 152, 153, db);
+ } else {
+ /* DEBUG Config file ... not found. */
+ dk3app_log_i3(app, DK3_LL_DEBUG, 154, 155, db);
+ }
+ } $? "- dk3app_check_config_file %d", back
+ return back;
+}
+
+
+
+/** Add preference key/value entry to storage.
+ Check whether an entry for the key already exists.
+ @param app Application structure for diagnostics, may be NULL.
+ @param s Storage.
+ @param i Storage iterator.
+ @param k Preference key.
+ @param v Preference value.
+*/
+static
+int
+dk3app_add_pref(
+ dk3_app_t *app, dk3_sto_t *s, dk3_sto_it_t *i,
+ dkChar const *k, dkChar const *v
+)
+{
+ int back = 0;
+ dk3app_pref_t p; /* Preference search. */
+ dk3app_pref_t *pref = NULL; /* Existing preference for name. */
+ dkChar *nv = NULL; /* New value string for preference. */
+ $? "+ dk3app_add_pref \"%!ds\"=\"%!ds\"", TR_STR(k), TR_STR(v)
+ p.k = k; p.v = v;
+ pref = (dk3app_pref_t *)dk3sto_it_find_like(i, &p, 0);
+ if(pref) {
+ nv = dk3str_dup_app(v, NULL);
+ if(nv) {
+ dk3_delete(pref->v);
+ pref->v = nv;
+ back = 1;
+ } else {
+ if(app) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 9);
+ }
+ }
+ } else {
+ pref = dk3app_pref_new(k, v);
+ if(pref) {
+ if(dk3sto_add(s, pref)) {
+ back = 1;
+ } else {
+ if(app) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 9);
+ }
+ dk3app_pref_delete(pref); pref = NULL;
+ }
+ } else {
+ if(app) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 9);
+ }
+ }
+ } $? "- dk3app_add_pref %d", back
+ return back;
+}
+
+
+
+/** Save one preference entry.
+ Do not report problems directly, set app->de instead.
+ @param app Application structure.
+ @param pt Preference text.
+*/
+static
+void
+dk3app_save_one_preference(dk3_app_t *app, dkChar const *pt)
+{
+ dkChar b[DK3_MAX_PATH]; /* Buffer for input line. */
+ dkChar *p1 = NULL; /* Value position. */
+ $? "+ dk3app_save_one_preference \"%!ds\"", TR_STR(pt)
+ if(dk3str_len(pt) < DK3_SIZEOF(b,dkChar)) {
+ dk3str_cpy_not_overlapped(b, pt);
+ p1 = dk3str_chr(b, dkT('='));
+ if(p1) {
+ *(p1++) = dkT('\0');
+ p1 = dk3str_start(p1, NULL);
+ if(p1) {
+ dk3str_chomp(b, NULL);
+ dk3str_chomp(p1, NULL);
+ if(!(app->s_cmdprefs)) {
+ app->s_cmdprefs = dk3sto_open_app(NULL);
+ if(app->s_cmdprefs) {
+ dk3sto_set_comp(app->s_cmdprefs, dk3app_compare_pref, 0);
+ } else {
+ app->de = 36; $? "! failed to create storage"
+ }
+ }
+ if(!(app->i_cmdprefs)) {
+ if(app->s_cmdprefs) {
+ app->i_cmdprefs = dk3sto_it_open(app->s_cmdprefs);
+ } else {
+ app->de = 35; $? "! failed to create iterator"
+ }
+ }
+ if((app->s_cmdprefs) && (app->i_cmdprefs)) {
+ if(!dk3app_add_pref(NULL,app->s_cmdprefs,app->i_cmdprefs,b,p1)) {
+ app->de = 33; $? "! failed to add to storage"
+ }
+ }
+ } else {
+ app->de = 32; $? "! no value"
+ }
+ } else {
+ app->de = 32; $? "! no \"=\""
+ }
+ } else {
+ app->de = 31; $? "! too long"
+ } $? "- dk3app_save_one_preference"
+}
+
+
+
+/** Set application to silent mode if --/silent=yes was
+ provided as command line argument.
+ @param app Application structure.
+*/
+static
+void
+dk3app_first_set_silent(dk3_app_t *app)
+{
+ app->ll_stderr = DK3_LL_NONE;
+ switch(app->app_type) {
+ case DK3_APP_TYPE_COMMAND: {
+ app->app_type = DK3_APP_TYPE_SILENT;
+ } break;
+ }
+}
+
+
+
+int
+dk3app_first_silence_check(dk3_app_t *app, int argc, dkChar const * const *argv)
+{
+ int back = 0;
+ int i; /* Index of current argument. */
+ dkChar const * const *lfdptr; /* Pointer to traverse arguments. */
+ dkChar const *ptr; /* Current argument. */
+ dkChar buffer[2 * DK3_MAX_PATH]; /* Local copy. */
+ dkChar *p1; /* Option keyword. */
+ dkChar *p2; /* Option argument. */
+
+ lfdptr = argv; lfdptr++; i = 1;
+ while(i < argc) {
+ ptr = *lfdptr;
+ if(*ptr == dkT('-')) {
+ ptr++;
+ if(*ptr == dkT('-')) {
+ ptr++;
+ if(dk3str_len(ptr) < DK3_SIZEOF(buffer,dkChar)) {
+ dk3str_cpy_not_overlapped(buffer, ptr);
+ p1 = dk3str_start(buffer, NULL);
+ if(p1) {
+ p2 = dk3str_chr(p1, dkT('='));
+ if(p2) {
+ *(p2++) = dkT('\0');
+ p2 = dk3str_start(p2, NULL);
+ }
+ if(dk3str_cmp(dk3app_no_loc[50], p1) == 0) {
+ if(p2) {
+ if(dk3str_is_on(p2)) {
+ back = 1;
+ if(app) { dk3app_first_set_silent(app); }
+ }
+ } else {
+ back = 1;
+ if(app) { dk3app_first_set_silent(app); }
+ }
+ }
+ }
+ } else {
+ /* ERROR: Too long! */
+ }
+ }
+ }
+ lfdptr++; i++;
+ }
+ return back;
+}
+
+
+
+/** Save command line arguments for later use.
+ Don't report errors directly, set app->de instead.
+ @param app Application structure.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+*/
+static
+void
+dk3app_save_arguments(dk3_app_t *app, int argc, dkChar const * const *argv)
+{
+ int myargc = 0; /* Number of options used. */
+ dkChar const **myargv = NULL; /* Private copy of options. */
+ dkChar const **ptr = NULL; /* Traverse myargv. */
+ dkChar const * const *sptr = NULL; /* Traverse original argv. */
+ dkChar const *tptr = NULL; /* String tests in sptr. */
+ int ispref = 0; /* Flag: Is a preference. */
+ int i = 0; /* Index of current argv. */
+ $? "+ dk3app_save_arguments"
+ myargv = dk3_new_app(DK3_PCDKCHAR,(argc+1),app);
+ if(myargv) {
+ ptr = myargv;
+ for(i = 0; i < (argc + 1); i++) { *(ptr++) = NULL; }
+ ptr = myargv; myargc = 0; sptr = argv;
+ for(i = 0; i < argc; i++) {
+ tptr = *(sptr++); $? ". tptr=\"%!ds\"", tptr
+ ispref = 0;
+ if(*tptr == DK3_CHAR_MINUS) {
+ if(tptr[1] == DK3_CHAR_MINUS) {
+ if(tptr[2] == DK3_CHAR_SLASH) {
+ ispref = 1; $? ". is preference"
+ }
+ }
+ }
+ if(ispref) {
+ dk3app_save_one_preference(app, &(tptr[2]));
+ } else {
+ *ptr = dk3str_dup_app(tptr, NULL);
+ if(*ptr) {
+ myargc++;
+ ptr++;
+ } else {
+ app->de = 1;
+ }
+ }
+ }
+ app->argc = myargc; app->argv = myargv;
+ } $? "- dk3app_save_arguments de=%d", app->de
+}
+
+
+
+/** Save application group name.
+ @param app Application structure.
+ @param gn Group name to save.
+*/
+static
+void
+dk3app_save_group_name(dk3_app_t *app, dkChar const *gn)
+{
+ $? "+ dk3app_save_group_name \"%!ds\"", TR_STR(gn)
+ app->n_appgroup = dk3str_dup_app(gn,NULL);
+ if(!(app->n_appgroup)) {
+ app->de = 18;
+ } $? "- dk3app_save_group_name de=%d", app->de
+}
+
+
+
+/** Retrieve preferences from a storage.
+ @param app Application structure for diagnostics, may be NULL.
+ @param p Storage iterator.
+ @param k Key (preference name).
+ @param d Destination buffer.
+ @param s Size of \a d (number of characters).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3app_sto_pref(
+ dk3_app_t *app, dk3_sto_it_t *p, dkChar const *k, dkChar *d, size_t s)
+{
+ int back = 0;
+ dk3app_pref_t pr; /* Used for comparisons in search. */
+ dk3app_pref_t *pref = NULL; /* Entry found. */
+ $? "+ dk3app_sto_pref \"%!ds\"", TR_STR(k)
+ if(p) {
+ pr.k = k; pr.v = NULL;
+ pref = (dk3app_pref_t *)dk3sto_it_find_like(p, &pr, 0);
+ if(pref) {
+ if(pref->v) {
+ if(dk3str_len(pref->v) < s) {
+ dk3str_cpy_not_overlapped(d, pref->v);
+ back = 1;
+ } else {
+ if(app) {
+ /* Destination buffer too short! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ }
+ } $? "- dk3app_sto_pref %d", back
+ return back;
+}
+
+
+
+/** Find number of entries for a string table file.
+ @param dv String table value array.
+ @return Number of entries in array, including final NULL entry.
+*/
+static
+size_t
+dk3app_mc_array_size(dkChar const * const *dv)
+{
+ size_t back = 0;
+ dkChar const * const *ptr = NULL; /* Traverse the dv array. */
+ $? "+ dk3app_mc_array_size"
+ if(dv) {
+ ptr = dv;
+ while(*(ptr++)) { back++; }
+ back++;
+ } $? "- dk3app_mc_array_size %u", (unsigned)back
+ return back;
+}
+
+
+
+void
+dk3app_squeeze_line(char *lb)
+{
+ char *pd = NULL; /* Destination in copy operations. */
+ char *ps = NULL; /* Source in copy operations. */
+ char *px = NULL; /* Position to continue. */
+ ps = lb;
+ $? "+ dk3app_squeeze_line \"%!8s\"", lb
+ /* Remove trailing newline. */
+ while(*ps) {
+ if((*ps == '\r') || (*ps == '\n')) {
+ *ps = '\0';
+ } else {
+ ps++;
+ }
+ }
+ /* Correct escape sequences */
+ ps = lb;
+ while(*ps) {
+ if(*ps == '\\') {
+ px = pd = ps; ps++;
+ if(*ps) {
+ switch(*ps) {
+ case 't': {
+ *(pd++) = '\t'; ps++;
+ dk3str_c8_cpy(pd, ps);
+ } break;
+ case 'n': {
+ *(pd++) = '\n'; ps++;
+ dk3str_c8_cpy(pd, ps);
+ } break;
+ case 'r': {
+ *(pd++) = '\r'; ps++;
+ dk3str_c8_cpy(pd, ps);
+ } break;
+ default: {
+ dk3str_c8_cpy(pd, ps);
+ } break;
+ }
+ ps = px; ps++;
+ }
+ } else {
+ ps++;
+ }
+ } $? "- dk3app_squeeze_line \"%!8s\"", lb
+}
+
+
+
+/** Get message catalog contents.
+ @param app Application structure.
+ @param fn File name for message catalog.
+ @param dv Default values.
+ @param verb Flag: Diagnostics enabled.
+ @return Pointer to message array.
+*/
+static
+dkChar const * const *
+dk3app_my_messages(
+ dk3_app_t *app, dkChar const *fn, dkChar const * const *dv, int verb
+)
+{
+ dkChar const * const *back = NULL;
+ dkChar const *source_file = NULL; /* File name for source file. */
+ dk3app_mc_t mc; /* Used for comparisons. */
+ dk3app_mc_t *mcptr = NULL; /* Message catalog. */
+ int errors_occured = 0; /* Flag: We had errors. */
+ unsigned long source_line = 0UL; /* Number of source line. */
+ unsigned long line_number = 0UL; /* NUmber of current line. */
+ size_t sz_defaults = 0; /* Number entries in default table. */
+ size_t i = 0; /* Walk through table. */
+ size_t current_index = 0; /* Index of current entry to process. */
+ dkChar fnb[DK3_MAX_PATH]; /* File name buffer. */
+ char lb[4096]; /* Input line (8-bit characters). */
+ dkChar const **rb = NULL; /* Array of strings to return. */
+ FILE *fipo; /* Input file. */
+ $? "+ dk3app_my_messages"
+ if((app) && (fn) && (dv)) { $? ". args ok"
+ /* Find array size. */
+ sz_defaults = dk3app_mc_array_size(dv);
+ if(sz_defaults) { $? ". sz = %u", (unsigned)sz_defaults
+ if((app->s_mc) && (app->i_mc)) { $? ". have existing tables"
+ mc.n = fn; mc.msg = NULL; mc.f = 0; mc.nmsg = sz_defaults;
+ mcptr = (dk3app_mc_t *)dk3sto_it_find_like(app->i_mc, &mc, 0);
+ if(mcptr) { $? ". message catalog found"
+ if(mcptr->nmsg >= sz_defaults) {
+ back = mcptr->msg; $? ". can re-use loaded catalog."
+ } else { $? "! message catalog loaded but too short"
+ errors_occured = 1; /* Too short */
+ }
+ } else { $? "! message catalog not found"
+ }
+ } else { $? "! no message catalogs loaded so far"
+ }
+ if((!(back)) && (errors_occured == 0)) { $? ". attempt to find file"
+ if(dk3app_my_find_data_file(app, fn, fnb, DK3_MAX_PATH, verb)) {
+ source_file = dk3app_get_source_file(app); $? ". file found"
+ source_line = dk3app_get_source_line(app);
+ dk3app_set_source_file(app, fnb);
+ dk3app_set_source_line(app, 0UL);
+/* UTF8 */ fipo = dk3sf_fopen_app(fnb, dk3app_no_loc[22], (verb ? app : NULL));
+ if(fipo) { $? ". file opened successfully"
+ rb = dk3_new_app(DK3_PCDKCHAR,sz_defaults,(verb ? app : NULL));
+ if(rb) { $? ". memory allocation ok"
+ for(i = 0; i < sz_defaults; i++) { rb[i] = NULL; }
+ current_index = 0;
+ /* We explicitly used 8-bit characters, the file is UTF-8 */
+ while(fgets(lb, sizeof(lb), fipo)) {
+ line_number++;
+ dk3app_set_source_line(app, line_number);
+ if(lb[0] != '#') {
+ dk3app_squeeze_line(lb);
+ if(current_index < (sz_defaults - 1)) {
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "Can not handle 4-byte characters here!"
+#else
+ rb[current_index] =
+ (dkChar const *)dk3str_cnvnew_c8u_to_c16_app(
+ lb, (verb ? app : NULL)
+ );
+ if(rb[current_index]) {
+ current_index++;
+ } else {
+ errors_occured = 2;
+ }
+#endif
+#else
+
+ switch(app->i_encoding) {
+ case DK3_ENCODING_PLAIN: {
+ rb[current_index] =
+ dk3str_cnvnew_c8u_to_c8p_app(lb, (verb ? app : NULL));
+ if(rb[current_index]) {
+ current_index++;
+ } else {
+ errors_occured = 2;
+ }
+ } break;
+ default: {
+ rb[current_index] =
+ dk3str_dup_app(lb, (verb ? app : NULL));
+ if(rb[current_index]) {
+ current_index++;
+ } else {
+ errors_occured = 2;
+ }
+ } break;
+ }
+#endif
+ }
+ /* current_index++; */
+ }
+ } $? ". file handled completely"
+ dk3app_set_source_line(app, 0UL);
+ if((current_index >= (sz_defaults - 1)) && (!(errors_occured))) {
+ if(!(app->s_mc)) { $? ". must create new storage"
+ app->s_mc = dk3sto_open_app(verb ? app : NULL);
+ if(app->s_mc) { $? ". storage ok"
+ dk3sto_set_comp(app->s_mc, dk3app_mc_compare, 0);
+ } else { $? "! failed to create storage"
+ }
+ }
+ if(!(app->i_mc)) { $? ". must create iterator"
+ if(app->s_mc) { $? ". storage available"
+ app->i_mc = dk3sto_it_open(app->s_mc);
+ } else { $? "! no storage, no iterator"
+ }
+ }
+ if((app->s_mc) && (app->i_mc)) { $? ". storage/iterator"
+ mcptr =
+ dk3app_mc_new(fn, rb, sz_defaults, 1, (verb ? app: NULL));
+ if(mcptr) { $? ". new entry ok"
+ if(dk3sto_add(app->s_mc, mcptr)) { $? ". full success"
+ back = rb;
+ } else {
+ dk3app_mc_table_delete(rb, sz_defaults); rb = NULL;
+ }
+ } else { $? "! failed to create new entry"
+ dk3app_mc_table_delete(rb, sz_defaults); rb = NULL;
+ }
+ } else { $? "! storage or iterator not available"
+ dk3app_mc_table_delete(rb, sz_defaults); rb = NULL;
+ }
+ } else { /* Error occured or not enough strings. */
+ if(errors_occured) { $? "! we had an error"
+ if(verb) {
+ /* Errors while reading file! */
+ }
+ } else { $? "! too few entries"
+ if(verb) {
+ /* Too few entries in file! */
+ }
+ }
+ dk3app_mc_table_delete(rb, sz_defaults);
+ rb = NULL;
+ }
+ } else { $? "! failed to allocate memory"
+ }
+ fclose(fipo);
+ } else { $? "! failed to open file"
+ }
+ dk3app_set_source_file(app, source_file);
+ dk3app_set_source_line(app, source_line);
+ } else { $? "! file not found"
+ }
+ } else { $? ". either succeeded yet or errors"
+ }
+ } else { $? "! size of default message array is 0"
+ }
+ if(!(back)) { $? ". Using default values"
+ back = dv;
+ }
+ } else { $? "! invalid arguments"
+ } $? "- dk3app_my_messages %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+/** Read one preferences file.
+ @param app Application structure.
+ @param fn File name to process.
+ @param s Storage to save preference entries.
+ @param i Iterator through storage.
+*/
+static
+void
+dk3app_rd_pref_file(
+ dk3_app_t *app, dkChar const *fn, dk3_sto_t *s, dk3_sto_it_t *i
+)
+{
+ dkChar buffer[4096];
+ char bombuf[4];
+ dkChar *p1 = NULL; /* Preference key (name). */
+ dkChar *p2 = NULL; /* Preference value. */
+ dkChar *p3 = NULL; /* Scope attribute value. */
+ dkChar const *oldsourcename; /* Old source file name. */
+ FILE *fipo = NULL; /* Input file. */
+ unsigned long lineno = 0UL; /* Current line number. */
+ unsigned long oldsourceline; /* Old source line number. */
+ size_t skb; /* Bytes to skip at start. */
+ int scope_valid = 1; /* Flag: In a valid scope. */
+ int last_was_scope = 0; /* Flag: Previous line was scope. */
+ int scope_action = 0; /* 0=yes, 1=no */
+ int conditions_ok; /* Flag: All conditions ok. */
+ int ie = DK3_FILE_ENCODING_ASCII; /* Input encoding. */
+
+ skb = 0;
+ ie = dk3sf_inspect_bom_skip_app(fn, DK3_FILE_ENCODING_ASCII, &skb, NULL);
+ dk3app_log_i3(app, DK3_LL_DEBUG, 230, 231, fn);
+ fipo = dk3sf_fopen_app(fn, dk3app_no_loc[22], NULL); /* READ */
+ if(fipo) {
+ oldsourcename = dk3app_get_source_file(app);
+ oldsourceline = dk3app_get_source_line(app);
+ dk3app_set_source_file(app, fn);
+ dk3app_set_source_line(app, 0UL);
+ (void)dk3sf_apply_bom_to_file_app(fipo, ie, NULL);
+ lineno = 0UL;
+ if((skb > 0) && (skb <= 4)) { dk3sf_fread_app(bombuf, 1, skb, fipo, NULL); }
+ while(dk3sf_fgets(buffer, DK3_SIZEOF(buffer,dkChar), fipo)) {
+ lineno++;
+ dk3app_set_source_line(app, lineno); $? ". MYSTIC set_source_line %lu", lineno
+ p1 = dk3str_start(buffer, NULL);
+ if(p1) {
+ if(*p1 != dkT('#')) {
+ if(*p1 == dkT('[')) {
+ if(!last_was_scope) { scope_valid = 0; }
+ scope_action = 0;
+ p2 = dk3str_chr(p1, dkT(']'));
+ if(p2) { *p2 = dkT('\0'); }
+ p1++;
+ dk3str_chomp(p1, NULL);
+ if(*p1 == dkT('-')) { scope_action = 1; p1++; }
+ p1 = dk3str_start(p1, NULL);
+ conditions_ok = 1;
+ while(p1) {
+ p2 = dk3str_chr(p1, dkT(','));
+ if(p2) {
+ *(p2++) = dkT('\0');
+ p2 = dk3str_start(p2, NULL);
+ }
+ p3 = dk3str_chr(p1, dkT('='));
+ if(p3) {
+ *(p3++) = dkT('\0');
+ p3 = dk3str_start(p3, NULL);
+ if(p3) {
+ dk3str_chomp(p1, NULL);
+ dk3str_chomp(p3, NULL); $? ". p1=\"%!ds\" p3=\"%!ds\"", p1, p3
+ switch(dk3str_array_index(dk3app_scope_attributes, p1, 0))
+ {
+ case 0: { /* user */
+ if(dk3str_cmp(p3, dk3app_no_loc[33])) {
+ if(app->n_logname) {
+#if DK3_ON_WINDOWS || DK3_HAVE_USER_NAMES_CASE_INSENSITIVE
+ if(dk3str_casecmp(p3, app->n_logname)) {
+ conditions_ok = 0;
+ }
+#else
+ if(dk3str_cmp(p3, app->n_logname)) {
+ conditions_ok = 0;
+ }
+#endif
+ } else {
+ conditions_ok = 0;
+ }
+ }
+ } break;
+ case 1: { /* application */
+ if(dk3str_cmp(p3, dk3app_no_loc[33])) {
+ if(app->n_app) {
+#if DK3_ON_WINDOWS || DK3_HAVE_FNCASEINS
+ if(dk3str_casecmp(p3, app->n_app)) {
+ conditions_ok = 0;
+ }
+#else
+ if(dk3str_cmp(p3, app->n_app)) { conditions_ok = 0; }
+#endif
+ } else { conditions_ok = 0; }
+ }
+ } break;
+ case 2: { /* application-group */
+ if(dk3str_cmp(p3, dk3app_no_loc[33])) {
+ if(app->n_appgroup) {
+
+#if DK3_ON_WINDOWS || DK3_HAVE_FNCASEINS
+ if(dk3str_casecmp(p3, app->n_appgroup)) {
+ conditions_ok = 0;
+ }
+#else
+ if(dk3str_cmp(p3, app->n_appgroup)) {
+ conditions_ok = 0;
+ }
+#endif
+ } else { conditions_ok = 0; }
+ }
+ } break;
+ case 3: { /* host */
+ if(dk3str_cmp(p3, dk3app_no_loc[33])) {
+ if(app->n_hostname) {
+ if(dk3str_casecmp(p3, app->n_hostname)) {
+ conditions_ok = 0;
+ }
+ } else { conditions_ok = 0; }
+ }
+ } break;
+ case 4: { /* language */
+ if(dk3str_cmp(p3, dk3app_no_loc[33])) {
+ if(app->n_language) {
+ if(dk3str_cmp(p3, app->n_language)) {
+ conditions_ok = 0;
+ }
+ } else { conditions_ok = 0; }
+ }
+ } break;
+ case 5: { /* region */
+ if(dk3str_cmp(p3, dk3app_no_loc[33])) {
+ if(app->n_region) {
+ if(dk3str_cmp(p3, app->n_region)) {
+ conditions_ok = 0;
+ }
+ } else { conditions_ok = 0; }
+ }
+ } break;
+ }
+ }
+ }
+ p1 = p2;
+ }
+ last_was_scope = 1;
+ if(conditions_ok) {
+ if(scope_action) {
+ scope_valid = 0;
+ } else {
+ scope_valid = 1;
+ }
+ }
+ } else {
+ last_was_scope = 0;
+ if(scope_valid) {
+ dk3str_chomp(p1, NULL);
+ p2 = dk3str_chr(p1, dkT('='));
+ if(p2) {
+ *(p2++) = dkT('\0');
+ p2 = dk3str_start(p2, NULL);
+ if(p2) {
+ dk3str_chomp(p1, NULL);
+ dk3str_chomp(p2, NULL);
+ if(!dk3app_add_pref(NULL, s, i, p1, p2)) {
+ app->de = 33;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ fclose(fipo);
+ dk3app_set_source_file(app, oldsourcename);
+ dk3app_set_source_line(app, oldsourceline);
+ } else {
+ dk3app_log_i3(app, DK3_LL_DEBUG, 152, 153, fn);
+ }
+}
+
+
+
+/** Read all preference files for an application.
+ @param app Application structure.
+*/
+static
+void
+dk3app_read_preference_files(dk3_app_t *app)
+{
+ dkChar fnb[DK3_MAX_PATH]; /* File name buffer. */
+ int i = 0; /* Pass. */
+ $? "+ dk3app_read_preference_files"
+ for(i = 0; i < 16; i++) {
+ if(dk3app_config_name(app, dk3app_no_loc[21], fnb, DK3_MAX_PATH, i, 0)) {
+ switch(i) {
+ case 14: { $? ". varprefs %d \"%!ds\"", i, fnb
+ if(!(app->s_varprefs)) {
+ app->s_varprefs = dk3sto_open_app(NULL);
+ if(app->s_varprefs) {
+ dk3sto_set_comp(app->s_varprefs, dk3app_compare_pref, 0);
+ } else {
+ app->de = 36;
+ }
+ }
+ if(!(app->i_varprefs)) {
+ if(app->s_varprefs) {
+ app->i_varprefs = dk3sto_it_open(app->s_varprefs);
+ if(!(app->i_varprefs)) { app->de = 36; }
+ }
+ }
+ if((app->s_varprefs) && (app->i_varprefs)) {
+ dk3app_rd_pref_file(app, fnb, app->s_varprefs, app->i_varprefs);
+ }
+ } break;
+ case 12: case 13: case 15: { $? ". constprefs %d \"%!ds\"", i, fnb
+ if(!(app->s_constprefs)) {
+ app->s_constprefs = dk3sto_open_app(NULL);
+ if(app->s_constprefs) {
+ dk3sto_set_comp(app->s_constprefs, dk3app_compare_pref, 0);
+ } else {
+ app->de = 36;
+ }
+ }
+ if(!(app->i_constprefs)) {
+ if(app->s_constprefs) {
+ app->i_constprefs = dk3sto_it_open(app->s_constprefs);
+ if(!(app->i_constprefs)) { app->de = 36; }
+ }
+ }
+ if((app->s_constprefs) && (app->i_constprefs)) {
+ dk3app_rd_pref_file(app,fnb,app->s_constprefs,app->i_constprefs);
+ }
+ } break;
+ default: { $? ". sysprefs %d \"%!ds\"", i, fnb
+ if(!(app->s_sysprefs)) {
+ app->s_sysprefs = dk3sto_open_app(NULL);
+ if(app->s_sysprefs) {
+ dk3sto_set_comp(app->s_sysprefs, dk3app_compare_pref, 0);
+ } else { app->de = 36; }
+ }
+ if(!(app->i_sysprefs)) {
+ if(app->s_sysprefs) {
+ app->i_sysprefs = dk3sto_it_open(app->s_sysprefs);
+ if(!(app->i_sysprefs)) { app->de = 36; }
+ }
+ }
+ if((app->s_sysprefs) && (app->i_sysprefs)) {
+ dk3app_rd_pref_file(app, fnb, app->s_sysprefs, app->i_sysprefs);
+ }
+ } break;
+ }
+ }
+ } $? "- dk3app_read_preference_files"
+}
+
+
+
+/** Find log level.
+ @param app Application structure.
+ @param ind Index of preference name in \a dk3app_no_loc.
+ @param buffer Buffer for preference value.
+ @param sz Size of \a buffer (number of characters).
+ @param dv Default value to use if preference is not set.
+ @return Log level found in preference or default value.
+*/
+static
+int
+dk3app_find_ll(dk3_app_t *app, int ind, dkChar *buffer, size_t sz, int dv)
+{
+ int back = 0;
+ dkChar *p1 = NULL; /* Value string. */
+ int i = 0; /* Index search result. */
+ back = dv;
+ $? "+ dk3app_find_ll %d", dv
+ if(dk3app_get_pref(app, dk3app_no_loc[ind], buffer, sz)) { $? ". pref ok"
+ p1 = dk3str_start(buffer, NULL);
+ if(p1) {
+ $? ". p1 = \"%!ds\"", p1
+ dk3str_chomp(p1, NULL);
+ $? ". p1 = \"%!ds\"", p1
+ i = dk3str_array_abbr(dk3app_log_levels, p1, dkT('$'), 0);
+ if(i >= 0) { $? ". index ok"
+ if(i <= DK3_LL_IGNORE) {
+ back = i; $? ". new ll ok"
+ }
+ } else { $? "! index -1"
+ }
+ } else { $? "! no contents"
+ }
+ } else { $? "! pref not found"
+ } $? "- dk3app_find_ll %d", back
+ return back;
+}
+
+
+
+/** Preferences processing at application startup.
+ @param app Application structure.
+*/
+static
+void
+dk3app_process_preferences(dk3_app_t *app)
+{
+ dkChar buffer[4096];
+ dkChar *p1 = NULL; /* Start of language/region/encoding string. */
+ dkChar *p2 = NULL; /* Encoding, later region. */
+ dkChar *p3 = NULL; /* Used to convert to lower case. */
+ dkChar *p4 = NULL; /* New string for region. */
+ int i; /* Input encoding. */
+ if(dk3app_get_pref(app,dk3app_no_loc[27],buffer,DK3_SIZEOF(buffer,dkChar)))
+ {
+ p1 = dk3str_start(buffer, NULL);
+ if(p1) {
+ p2 = dk3str_chr(buffer, dkT('.'));
+ if(p2) { *p2 = dkT('\0'); }
+ p2 = dk3str_chr(buffer, dkT('_'));
+ if(p2) {
+ *(p2++) = dkT('\0');
+ p2 = dk3str_start(p2, NULL);
+ if(p2) {
+ dk3str_chomp(p2, NULL);
+ p3 = p2; while(*p3) { *p3 = dk3str_tolower(*p3); p3++; }
+ }
+ }
+ p3 = p1; while(*p3) { *p3 = dk3str_tolower(*p3); p3++; }
+ dk3str_chomp(p1, NULL);
+ p3 = dk3str_dup_app(p1, NULL);
+ p4 = NULL;
+ if(p2) { p4 = dk3str_dup_app(p2, NULL); }
+ if(p3) {
+ dk3_delete(app->n_language);
+ app->n_language = p3;
+ }
+ if(p4) {
+ dk3_delete(app->n_region);
+ app->n_region = p4;
+ }
+ }
+ }
+ app->ll_file = dk3app_find_ll(
+ app, 28, buffer, DK3_SIZEOF(buffer,dkChar), app->ll_file
+ );
+ app->ll_file_keep = dk3app_find_ll(
+ app, 29, buffer, DK3_SIZEOF(buffer,dkChar), app->ll_file_keep
+ );
+ app->ll_stderr = dk3app_find_ll(
+ app, 30, buffer, DK3_SIZEOF(buffer,dkChar), app->ll_stderr
+ );
+ app->ll_tmp_keep = dk3app_find_ll(
+ app, 31, buffer, DK3_SIZEOF(buffer,dkChar), app->ll_tmp_keep
+ );
+ app->i_stdin_input_encoding = dk3app_get_default_stdin_encoding(app);
+ $? "+ i_stdin_input_encoding=%d", app->i_stdin_input_encoding
+ app->i_file_input_encoding = dk3app_get_default_file_encoding(app);
+ if(dk3app_get_pref(app,dk3app_no_loc[51],buffer,DK3_SIZEOF(buffer,dkChar)))
+ {
+ p1 = dk3str_start(buffer, NULL);
+ if(p1) {
+ dk3str_chomp(p1, NULL);
+ i = dk3enc_get_text_encoding_app(buffer, NULL);
+ if(i >= 0) {
+ app->i_file_input_encoding = i;
+ }
+ }
+ }
+ if(dk3app_get_pref(app,dk3app_no_loc[52],buffer,DK3_SIZEOF(buffer,dkChar)))
+ {
+ p1 = dk3str_start(buffer, NULL);
+ if(p1) {
+ dk3str_chomp(p1, NULL);
+ i = dk3enc_get_text_encoding_app(buffer, NULL);
+ if(i >= 0) {
+ app->i_stdin_input_encoding = i;
+ $? ". i_stdin_input_encoding=%d", app->i_stdin_input_encoding
+ }
+ }
+ }
+
+}
+
+
+
+/** Create new application.
+ @param wd Current working directory.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @param gn Application group name.
+ @param tp Application type.
+ @return Pointer to new application on success, NULL on error.
+*/
+static
+dk3_app_t *
+dk3app_open(
+ dkChar const * wd,
+ int argc, dkChar const * const * argv,
+ dkChar const *gn,
+ int tp
+)
+{
+ dk3_app_t *back = NULL;
+ $? "+ dk3app_open"
+ back = dk3_new(dk3_app_t,1);
+ if(back) {
+ dk3app_init(back);
+ switch(tp) {
+ case DK3_APP_TYPE_DAEMON: {
+ back->ll_file = DK3_LL_INFO;
+ } break;
+ }
+ back->app_type = tp;
+ if(!(back->de)) { dk3app_save_group_name(back, gn); }
+ if(!(back->de)) { dk3app_first_silence_check(back, argc, argv); }
+ if(!(back->de)) { dk3app_language_and_region(back, argc, argv); }
+ if(!(back->de)) { dk3app_find_names(back, wd, argc, argv); }
+ if(!(back->de)) { dk3app_save_arguments(back, argc, argv); }
+ if(!(back->de)) { dk3app_read_preference_files(back); }
+ if(!(back->de)) { dk3app_process_preferences(back); }
+ if(!(back->de)) {
+ back->msg = dk3app_my_messages(back, dk3app_no_loc[23], dk3app_kw, 0);
+ }
+ back->f_readytolog = 1;
+ if(back->de) {
+ /* Delayed error occured. Report error, destroy structure. */
+ switch(back->de) {
+ case 1: /* Error while saving command line arguments. */
+ case 2: /* Error while saving application name. */
+ case 4: /* Error while saving exec file name. */
+ case 6: /* Error while saving bin directory. */
+ case 7: /* Error while saving etc directory. */
+ case 8: /* Error while saving share directory. */
+ case 9: /* Error while saving var directory. */
+ case 15: /* Error while saving logname. */
+ case 17: /* Error while saving home directory. */
+ case 18: /* Error while saving application group name. */
+ case 21: /* Error while saving log file name. */
+ case 25: /* Error while saving temp dir name. */
+ case 28: /* Error while saving language string. */
+ case 29: /* Failed to save region! */
+ case 30: /* Failed to save language! */
+ case 33: /* Pref */
+ case 34: /* Pref storage */
+ case 35: /* Cmd prefs iterator */
+ case 36: /* Cmd prefs storage */
+ case 37: /* Store host name */
+ {
+ dk3app_log_i1(back, DK3_LL_ERROR, 9);
+ } break;
+ case 3: /* Failed to find executable file name. */
+ {
+ /* Failed to find executable file name. */
+ dk3app_log_i1(back, DK3_LL_ERROR, 40);
+ } break;
+ case 5: /* Incomplete exec file name. */
+ {
+ /* No separator in executable file name! */
+ dk3app_log_i1(back, DK3_LL_ERROR, 40);
+ }
+ case 10: /* Program is started from root directory. */
+ {
+ /* Too few directories in hierarchy! */
+ dk3app_log_i1(back, DK3_LL_ERROR, 41);
+ } break;
+ case 11: /* Error while creating etc directory name! */
+ case 12: /* Error while creating share directory name! */
+ case 13: /* Error while creating var directory name! */
+ {
+ /* Name of executable file too long! */
+ dk3app_log_i1(back, DK3_LL_ERROR, 42);
+ } break;
+ case 14: { /* Failed to retrieve log name! */
+ /* Failed to retrieve log name! */
+ dk3app_log_i1(back, DK3_LL_ERROR, 43);
+ } break;
+ case 16: { /* Failed to retrieve home directory! */
+ /* Failed to retrieve home directory! */
+ dk3app_log_i1(back, DK3_LL_ERROR, 44);
+ } break;
+ case 19: { /* Log file name too long. */
+ /* Log file name gets too long! */
+ dk3app_log_i1(back, DK3_LL_ERROR, 45);
+ } break;
+ case 20: {
+ /* Failed to create log directory! */
+ dk3app_log_i1(back, DK3_LL_ERROR, 46);
+ } break;
+ case 22: {
+ /* Failed to convert PID to dkChar! */
+ dk3app_log_i1(back, DK3_LL_ERROR, 47);
+ } break;
+ case 23: {
+ /* Home directory name missing! */
+ dk3app_log_i1(back, DK3_LL_ERROR, 44);
+ } break;
+ case 24: {
+ /* Application name missing! */
+ dk3app_log_i1(back, DK3_LL_ERROR, 48);
+ } break;
+ case 26: {
+ /* Name of tmp dir gets too long! */
+ dk3app_log_i1(back, DK3_LL_ERROR, 49);
+ } break;
+ case 27: {
+ /* var dir name missing! */
+ dk3app_log_i1(back, DK3_LL_ERROR, 50);
+ } break;
+ case 31: {
+ /* Preference name too long! */
+ dk3app_log_i1(back, DK3_LL_ERROR, 51);
+ } break;
+ case 32: {
+ /* Not a preference entry! */
+ dk3app_log_i1(back, DK3_LL_ERROR, 52);
+ } break;
+ case 38: {
+ dk3app_log_i1(back, DK3_LL_ERROR, 131);
+ } break;
+ }
+ dk3app_close(back);
+ back = NULL;
+ } else { $? ". now write debug log messages"
+ dk3app_log_i3(back, DK3_LL_DEBUG, 19, 20, back->n_app);
+ dk3app_log_i2(
+ back, DK3_LL_DEBUG, 23,
+ ((back->n_app) ? back->n_app: ((back->msg) ? back->msg : dk3app_kw)[36])
+ );
+ dk3app_log_i2(
+ back, DK3_LL_DEBUG, 24,
+ ((back->n_appgroup) ? back->n_appgroup: ((back->msg) ? back->msg : dk3app_kw)[36])
+ );
+ dk3app_log_i2(
+ back, DK3_LL_DEBUG, 25,
+ ((back->n_execfile) ? back->n_execfile: ((back->msg) ? back->msg : dk3app_kw)[36])
+ );
+ dk3app_log_i2(
+ back, DK3_LL_DEBUG, 26,
+ ((back->n_bindir) ? back->n_bindir: ((back->msg) ? back->msg : dk3app_kw)[36])
+ );
+ dk3app_log_i2(
+ back, DK3_LL_DEBUG, 27,
+ ((back->n_etcdir) ? back->n_etcdir: ((back->msg) ? back->msg : dk3app_kw)[36])
+ );
+ dk3app_log_i2(
+ back, DK3_LL_DEBUG, 28,
+ ((back->n_sharedir) ? back->n_sharedir: ((back->msg) ? back->msg : dk3app_kw)[36])
+ );
+ dk3app_log_i2(
+ back, DK3_LL_DEBUG, 29,
+ ((back->n_vardir) ? back->n_vardir: ((back->msg) ? back->msg : dk3app_kw)[36])
+ );
+ dk3app_log_i2(
+ back, DK3_LL_DEBUG, 30,
+ ((back->n_homedir) ? back->n_homedir: ((back->msg) ? back->msg : dk3app_kw)[36])
+ );
+ dk3app_log_i2(
+ back, DK3_LL_DEBUG, 31,
+ ((back->n_tmpdir) ? back->n_tmpdir: ((back->msg) ? back->msg : dk3app_kw)[36])
+ );
+ dk3app_log_i2(
+ back, DK3_LL_DEBUG, 32,
+ ((back->n_logname) ? back->n_logname: ((back->msg) ? back->msg : dk3app_kw)[36])
+ );
+ dk3app_log_i2(
+ back, DK3_LL_DEBUG, 132,
+ ((back->n_hostname) ? back->n_hostname: ((back->msg) ? back->msg : dk3app_kw)[36])
+ );
+ dk3app_log_i2(
+ back, DK3_LL_DEBUG, 33,
+ ((back->n_logfilename) ? back->n_logfilename: ((back->msg) ? back->msg : dk3app_kw)[36])
+ );
+ dk3app_log_i2(
+ back, DK3_LL_DEBUG, 34,
+ ((back->n_language) ? back->n_language: ((back->msg) ? back->msg : dk3app_kw)[36])
+ );
+ dk3app_log_i2(
+ back, DK3_LL_DEBUG, 35,
+ ((back->n_region) ? back->n_region: ((back->msg) ? back->msg : dk3app_kw)[36])
+ );
+ }
+ } else {
+ if(tp == DK3_APP_TYPE_COMMAND) {
+ /* ERROR: Not enough memory */
+ dk3sf_initialize_stderr();
+ dk3sf_fputs(dk3app_kw[9], stderr);
+ dk3sf_fputs(dk3app_kw[0], stderr);
+ fflush(stderr);
+ }
+ } $? "- dk3app_open %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+dk3_app_t *
+dk3app_open_command(int argc, dkChar const * const * argv, dkChar const *gn)
+{
+ dk3_app_t *back = NULL;
+ dkChar wd[DK3_MAX_PATH]; /* Current working directory. */
+ if((argc) && (argv) && (gn)) {
+ if(dk3sf_getcwd_app(wd, DK3_SIZEOF(wd,dkChar), NULL)) {
+ back = dk3app_open(wd, argc, argv, gn, DK3_APP_TYPE_COMMAND);
+ } else {
+ /* ERROR: Failed to find current working directory. */
+ if(!dk3app_first_silence_check(NULL, argc, argv)) {
+ dk3sf_initialize_stderr();
+ dk3sf_fputs(dk3app_kw[3], stderr);
+ dk3sf_fputs(dk3app_kw[11], stderr);
+ dk3sf_fputs(dk3app_kw[8], stderr);
+ dk3sf_fputs(dk3app_kw[53], stderr);
+ dk3sf_fputs(dk3app_kw[0], stderr);
+ fflush(stderr);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+dk3_app_t *
+dk3app_open_gui(int argc, dkChar const * const * argv, dkChar const *gn)
+{
+ dk3_app_t *back = NULL;
+ dkChar wd[DK3_MAX_PATH]; /* Current working directory. */
+ if((argc) && (argv) && (gn)) {
+ if(dk3sf_getcwd_app(wd, DK3_SIZEOF(wd,dkChar),NULL)) {
+ back = dk3app_open(wd, argc, argv, gn, DK3_APP_TYPE_GUI);
+ } else {
+ /* ERROR: Failed to find current working directory. */
+ }
+ }
+ return back;
+}
+
+
+
+dk3_app_t *
+dk3app_open_daemon(
+ dkChar const *wd, int argc, dkChar const * const * argv, dkChar const *gn
+)
+{
+ dk3_app_t *back = NULL;
+ if((wd) && (argc) && (argv) && (gn)) {
+ back = dk3app_open(wd, argc, argv, gn, DK3_APP_TYPE_DAEMON);
+ }
+ return back;
+}
+
+
+
+dk3_app_t *
+dk3app_open_silent(int argc, dkChar const * const * argv, dkChar const *gn)
+{
+ dk3_app_t *back = NULL;
+ dkChar wd[DK3_MAX_PATH]; /* Current working directory. */
+ if((argc) && (argv) && (gn)) {
+ if(dk3sf_getcwd_app(wd, DK3_SIZEOF(wd,dkChar),NULL)) {
+ back = dk3app_open(wd, argc, argv, gn, DK3_APP_TYPE_SILENT);
+ } else {
+ /* ERROR: Failed to find current working directory. */
+ }
+ }
+ return back;
+}
+
+
+
+dkChar const * const *
+dk3app_get_argv(dk3_app_t const *app)
+{
+ dkChar const * const *back = NULL;
+ if(app) { back = (dkChar const * const *)(app->argv); }
+ return back;
+}
+
+
+
+int
+dk3app_get_argc(dk3_app_t const *app)
+{
+ int back = 0;
+ if(app) { back = app->argc; }
+ return back;
+}
+
+
+
+dkChar const *
+dk3app_get_appname(dk3_app_t const *app)
+{
+ dkChar const *back = NULL;
+ if(app) {
+ back = app->n_app;
+ } $? "= dk3app_get_appname %!ds", TR_STR(back)
+ return back;
+}
+
+
+
+dkChar const *
+dk3app_get_execfilename(dk3_app_t const *app)
+{
+ dkChar const *back = NULL;
+ if(app) {
+ back = app->n_execfile;
+ }
+ return back;
+}
+
+
+
+dkChar const *
+dk3app_get_bindir(dk3_app_t const *app)
+{
+ dkChar const *back = NULL;
+ if(app) {
+ back = app->n_bindir;
+ }
+ return back;
+}
+
+
+
+dkChar const *
+dk3app_get_etcdir(dk3_app_t const *app)
+{
+ dkChar const *back = NULL;
+ if(app) {
+ back = app->n_etcdir;
+ }
+ return back;
+}
+
+
+
+dkChar const *
+dk3app_get_sharedir(dk3_app_t const *app)
+{
+ dkChar const *back = NULL;
+ if(app) {
+ back = app->n_sharedir;
+ }
+ return back;
+}
+
+
+
+dkChar const *
+dk3app_get_vardir(dk3_app_t const *app)
+{
+ dkChar const *back = NULL;
+ if(app) {
+ back = app->n_vardir;
+ }
+ return back;
+}
+
+
+
+dkChar const *
+dk3app_get_logname(dk3_app_t const *app)
+{
+ dkChar const *back = NULL;
+ if(app) {
+ back = app->n_logname;
+ }
+ return back;
+}
+
+
+
+dkChar const *
+dk3app_get_hostname(dk3_app_t const *app)
+{
+ dkChar const *back = NULL;
+ if(app) {
+ back = app->n_hostname;
+ }
+ return back;
+}
+
+
+
+dkChar const *
+dk3app_get_homedir(dk3_app_t const *app)
+{
+ dkChar const *back = NULL;
+ if(app) {
+ back = app->n_homedir;
+ }
+ return back;
+}
+
+
+
+dkChar const *
+dk3app_get_appgroup(dk3_app_t const *app)
+{
+ dkChar const *back = NULL;
+ if(app) {
+ back = app->n_appgroup;
+ }
+ return back;
+}
+
+
+
+int
+dk3app_get_temp_file_name(dk3_app_t *app, dkChar *db, size_t sz)
+{
+ int back = 0;
+ char fn[16]; /* BUffer for sprintf(). */
+ dkChar fn2[16]; /* Short file name buffer. */
+ size_t s = 0; /* Buffer length needed. */
+ $? "+ dk3app_get_temp_file_name"
+ if((app) && (db) && (sz)) {
+ if(app->n_tmpdir) {
+ if ((DK3_APP_TYPE_DAEMON != app->app_type) && (0 == app->cr_tmp)) {
+ dk3app_create_tmp_directory(app);
+ app->cr_tmp = 1;
+ }
+ if(!(app->i_tmpcarry)) {
+ sprintf(fn, "/%08lx.%03x", app->ul_tmpname, app->u_tmpsuffix);
+ back = 1;
+ if ((0UL == app->ul_tmpname) && (0 == app->u_tmpsuffix)) {
+ if (DK3_APP_TYPE_DAEMON != app->app_type) {
+ $? ". create temporary directory"
+ $? ". mkdir %!ds", app->n_tmpdir
+ if (0 == dk3sf_mkdir_app(app->n_tmpdir, 0700, NULL)) {
+ back = 0;
+ }
+ }
+ }
+ app->u_tmpsuffix += 1U;
+ if(app->u_tmpsuffix >= 0x1000U) {
+ app->u_tmpsuffix = 0U;
+#if VERSION_BEFORE_20150318
+ app->ul_tmpname += 1UL;
+ if(app->ul_tmpname == 0UL) {
+ app->i_tmpcarry = 1;
+ back = 0;
+ /* Too many temporary file names asked! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 54);
+ }
+#else
+ /* 2015-03-18 We better check the variable before adding 1.
+ Unsigned long may be larger than 32 bits.
+ */
+ if (0xFFFFFFFFUL > app->ul_tmpname) {
+ app->ul_tmpname += 1UL;
+ } else {
+ app->i_tmpcarry = 1;
+ back = 0;
+ /* Too many temporary file names asked! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 54);
+ }
+#endif
+ }
+ if(back) {
+ back = 0;
+ if(dk3str_cnv_c8_to_str_app(fn2, 15, fn, app)) {
+ s = dk3str_len(app->n_tmpdir) + dk3str_len(fn2);
+ if(s < sz) {
+ dk3str_cpy_not_overlapped(db, app->n_tmpdir);
+ dk3str_cat(db, fn2);
+ dk3str_correct_filename(db);
+ back = 1;
+ } else {
+ /* Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ }
+ } else {
+ /* Not directory for temporary files available! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 55);
+ }
+ } $? "- dk3app_get_temp_file_name %d", back
+ return back;
+}
+
+
+
+dkChar const *
+dk3app_get_language(dk3_app_t const *app)
+{
+ dkChar const *back = NULL;
+ if(app) { back = app->n_language; }
+ return back;
+}
+
+
+
+dkChar const *
+dk3app_get_region(dk3_app_t const *app)
+{
+ dkChar const *back = NULL;
+ if(app) { back = app->n_region; }
+ return back;
+}
+
+
+
+int
+dk3app_get_encoding(dk3_app_t const *app)
+{
+ int back = 0;
+ if(app) { back = app->i_encoding; }
+ return back;
+}
+
+
+
+int
+dk3app_get_output_encoding(dk3_app_t const *app)
+{
+ int back = 0;
+ if(app) { back = app->i_output_encoding; }
+ return back;
+}
+
+
+
+int
+dk3app_get_input_stdin_encoding(dk3_app_t const *app)
+{
+ int back = 0;
+ if(app) { back = app->i_stdin_input_encoding; }
+ return back;
+}
+
+
+
+int
+dk3app_get_input_file_encoding(dk3_app_t const *app)
+{
+ int back = 0;
+ if(app) { back = app->i_file_input_encoding; }
+ return back;
+}
+
+
+
+int
+dk3app_set_pref(dk3_app_t *app, dkChar const *k, dkChar const *v)
+{
+ int back = 0;
+ if((app) && (k) && (v)) {
+ if(!(app->s_selfprefs)) {
+ app->s_selfprefs = dk3sto_open_app(app);
+ if(app->s_selfprefs) {
+ dk3sto_set_comp(app->s_selfprefs, dk3app_compare_pref, 0);
+ }
+ }
+ if(!(app->i_selfprefs)) {
+ if(app->s_selfprefs) {
+ app->i_selfprefs = dk3sto_it_open(app->s_selfprefs);
+ }
+ }
+ if((app->s_selfprefs) && (app->i_selfprefs)) {
+ back = dk3app_add_pref(app, app->s_selfprefs, app->i_selfprefs, k, v);
+ app->f_prefschanged = 1;
+ }
+ if(!back) {
+ /* Failed to save preference value! */
+ dk3app_log_i5(app, DK3_LL_ERROR, 56, 57, 58, k, v);
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3app_get_pref(dk3_app_t *app, dkChar const *k, dkChar *d, size_t s)
+{
+ int back = 0;
+ $? "+ dk3app_get_pref"
+ if((app) && (k) && (d) && (s)) {
+ $? ". k=\"%!ds\"", k
+ back = dk3app_sto_pref(app, app->i_selfprefs, k, d, s);
+ if(back == 0) {
+ back = dk3app_sto_pref(app, app->i_cmdprefs, k, d, s);
+ if(back == 0) {
+ back = dk3app_sto_pref(app, app->i_varprefs, k, d, s);
+ if(back == 0) {
+ back = dk3app_sto_pref(app, app->i_constprefs, k, d, s);
+ if(back == 0) {
+ back = dk3app_sto_pref(app, app->i_sysprefs, k, d, s);
+ }
+ }
+ }
+ }
+ $!trace-code if(back) {
+ $? ". v=\"%!ds\"", d
+ $!trace-code }
+ } $? "- dk3app_get_pref %d", back
+ return back;
+}
+
+
+
+int
+dk3app_get_sys_pref(dk3_app_t *app, dkChar const *k, dkChar *d, size_t s)
+{
+ int back = 0;
+ if((app) && (k) && (d) && (s)) {
+ back = dk3app_sto_pref(app, app->i_selfprefs, k, d, s);
+ if(back == 0) {
+ back = dk3app_sto_pref(app, app->i_sysprefs, k, d, s);
+ }
+ }
+ return back;
+}
+
+
+
+/** Check whether the use of system configuration files
+ is allowed for a file name.
+ @param app Application structure.
+ @param fn Short file name.
+ @return 1 for system config files allowed, 0 for user files only.
+*/
+static
+int
+dk3app_allow_system_config_files(dk3_app_t *app, dkChar const *fn)
+{
+ int back = 1;
+ dkChar fnb[DK3_MAX_PATH]; /* File name buffer. */
+ dkChar il[1024 + DK3_MAX_PATH]; /* Input line buffer. */
+ char bombuf[4]; /* Buffer to skip BOM. */
+ dkChar *p1 = NULL; /* Key (entry name). */
+ dkChar *p2 = NULL; /* Value. */
+ FILE *fipo = NULL; /* Input file. */
+ int ie = DK3_FILE_ENCODING_ASCII; /* Input encoding for file. */
+ int cc = 1; /* Flag: Can continue. */
+ size_t sz = 0; /* Buffer size needed. */
+ size_t skb; /* Number of bytes to skip. */
+ if(app->n_homedir) {
+ sz = dk3str_len(app->n_homedir);
+ sz += (2 * dk3str_len(dk3app_no_loc[20]));
+ sz += dk3str_len(dk3app_no_loc[18]);
+ sz += dk3str_len(dk3app_no_loc[34]);
+ if(sz < DK3_SIZEOF(fnb,dkChar)) {
+ dk3str_cpy_not_overlapped(fnb, app->n_homedir);
+ dk3str_cat(fnb, dk3app_no_loc[20]);
+ dk3str_cat(fnb, dk3app_no_loc[18]);
+ dk3str_cat(fnb, dk3app_no_loc[20]);
+ dk3str_cat(fnb, dk3app_no_loc[34]);
+ skb = 0;
+ ie = dk3sf_inspect_bom_skip_app(fnb, DK3_FILE_ENCODING_ASCII, &skb, NULL);
+ fipo = dk3sf_fopen_app(fnb, dk3app_no_loc[22], NULL); /* READ */
+ if(fipo) {
+ (void)dk3sf_apply_bom_to_file_app(fipo, ie, NULL);
+ cc = 1;
+ if((skb > 0) && (skb <= 4)) {
+ dk3sf_fread_app(bombuf, 1, skb, fipo, NULL);
+ }
+ while(cc) {
+ if(dk3sf_fgets(il, DK3_SIZEOF(il,dkChar), fipo)) {
+ p1 = dk3str_start(il, NULL);
+ if(p1) {
+ if(*p1 != dkT('#')) {
+ p2 = dk3str_chr(p1, dkT('='));
+ if(p2) {
+ *(p2++) = dkT('\0');
+ p2 = dk3str_start(p2, NULL);
+ if(p2) {
+ dk3str_chomp(p2, NULL);
+ dk3str_normalize(p1, NULL, dkT('-'));
+ switch(dk3str_array_index(dk3app_conf_file, p1, 0)) {
+ case 0: { /* use system config files */
+ if(dk3str_cmp(p2, dk3app_no_loc[33]) == 0) {
+ back = 1; cc = 0;
+ } else {
+ if(dk3str_cmp(p2, fn) == 0) {
+ back = 1; cc = 0;
+ }
+ }
+ } break;
+ case 1: { /* ignore system config files */
+ if(dk3str_cmp(p2, dk3app_no_loc[33]) == 0) {
+ back = 0; cc = 0;
+ } else {
+ if(dk3str_cmp(p2, fn) == 0) {
+ back = 0; cc = 0;
+ }
+ }
+ } break;
+ }
+ }
+ }
+ }
+ }
+ } else { cc = 0;}
+ }
+ fclose(fipo);
+ }
+ } else {
+ /* ERROR: Home directory name too long! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 194);
+ }
+ }
+ return back;
+}
+
+
+
+/** Find configuration files for a given name.
+ @param app Application structure.
+ @param fn File name.
+ @param res Flag: Reverse search order.
+ @param exclu Flag: Exclude user files.
+ @return Pointer to search result collection on success, NULL on error.
+*/
+static
+dk3_search_t *
+dk3app_my_find_config_file(dk3_app_t *app, dkChar const *fn, int res, int exclu)
+{
+ dk3_search_t *back = NULL;
+ unsigned long items_found = 0; /* Number of items found. */
+ int error_occured = 0; /* Flag: Error occured. */
+ int i = 0; /* Current pass number. */
+ int r = 0; /* Result from check for conf file. */
+ int max = 0; /* Maximum pass number. */
+ int min = 0; /* Minimum pass number. */
+ dkChar buffer[DK3_MAX_PATH]; /* File name buffer. */
+ if((app) && (fn)) {
+ back = dk3search_open_app(res, app);
+ if(back) {
+ min = 0; max = 16;
+ if(app->app_type == DK3_APP_TYPE_DAEMON) {
+ max = 6;
+ } else {
+ if(exclu) {
+ max = 12;
+ } else {
+ if(!dk3app_allow_system_config_files(app, fn)) {
+ min = 12;
+ /* DEBUG: System config files skipped by user. */
+ dk3app_log_i1(app, DK3_LL_DEBUG, 195);
+ }
+ }
+ }
+ for(i = min; i < max; i++) {
+ r = dk3app_check_config_file(app, fn, buffer, DK3_MAX_PATH, i, 1);
+ if(r) {
+ if(dk3search_add(back, buffer)) {
+ items_found++;
+ } else {
+ error_occured = 1;
+ }
+ }
+ }
+ if(error_occured) {
+ dk3search_close(back); back = NULL;
+ } else {
+ if(items_found == 0UL) {
+ dk3search_close(back); back = NULL;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+dk3_search_t *
+dk3app_find_config_file(dk3_app_t *app, dkChar const *fn, int exclu)
+{
+ dk3_search_t *back = NULL;
+ if((app) && (fn)) {
+ back = dk3app_my_find_config_file(app, fn, 0, exclu);
+ }
+ return back;
+}
+
+
+
+dk3_search_t *
+dk3app_find_config_file_revers(dk3_app_t *app, dkChar const *fn, int exclu)
+{
+ dk3_search_t *back = NULL;
+ if((app) && (fn)) {
+ back = dk3app_my_find_config_file(app, fn, 1, exclu);
+ }
+ return back;
+}
+
+
+
+int
+dk3app_find_data_file(dk3_app_t *app, dkChar const *fn, dkChar *db, size_t sz)
+{
+ int back = 0;
+ if((app) && (fn) && (db) && (sz)) {
+ back = dk3app_my_find_data_file(app, fn, db, sz, 1);
+ }
+ return back;
+}
+
+
+
+void
+dk3app_unconfigure(dk3_app_t *app)
+{
+ if(app) { app->f_unconfigure = 1; }
+}
+
+
+
+dkChar const * const *
+dk3app_messages(dk3_app_t *app, dkChar const *fn, dkChar const * const *dv)
+{
+ dkChar const * const *back;
+ $? "+ dk3app_messages"
+ back = dk3app_my_messages(app, fn, dv, 0);
+ $? "- dk3app_messages %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+void
+dk3app_help(dk3_app_t *app, dkChar const *fn, dkChar const * const *dt)
+{
+ int had_success = 0; /* Flag: Success. */
+ dkChar buffer[DK3_MAX_PATH]; /* File name buffer. */
+ char lb[1024]; /* Input line buffer. */
+ dkChar db[1024]; /* Output line buffer. */
+ FILE *fipo = NULL; /* Input file. */
+ dkChar const * const *ptr = NULL; /* Help text line. */
+ $? "+ dk3app_help"
+ if((app) && (fn) && (dt)) {
+ dk3sf_initialize_stdout();
+ if(dk3app_my_find_data_file(app, fn, buffer, DK3_SIZEOF(buffer,dkChar), 0))
+ {
+ fipo = dk3sf_fopen_app(buffer, dk3app_no_loc[22], app); /* UTF-8 */
+ if(fipo) {
+ had_success = 1;
+ while(fgets(lb, sizeof(lb), fipo)) { $? ". \"%!8s\"", lb
+#if DK3_CHAR_SIZE == 2
+ if(dk3str_cnv_c8u_to_c16_app(db, DK3_SIZEOF(db,dkChar), lb, app)) {
+ dk3sf_fputs(db, stdout);
+ }
+#else
+ switch(app->i_encoding) {
+ case DK3_ENCODING_PLAIN: {
+ if(dk3str_cnv_c8u_to_c8p_app(db, DK3_SIZEOF(db,dkChar), lb, app))
+ {
+ fputs(db, stdout);
+ }
+ } break;
+ default: {
+ fputs(lb, stdout);
+ } break;
+ }
+#endif
+ }
+ fclose(fipo);
+ }
+ }
+ if(!had_success) {
+ ptr = dt;
+ while(*ptr) {
+ dk3sf_fputs(*(ptr++), stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ }
+ } $? "- dk3app_help"
+}
+
+
+
+int
+dk3app_get_stderr_log_level(dk3_app_t const *app)
+{
+ int back = DK3_LL_ERROR;
+ if(app) {
+ back = app->ll_stderr;
+ }
+ return back;
+}
+
+
+
+void
+dk3app_set_stderr_log_level(dk3_app_t *app, int ll)
+{
+ if(app) {
+ app->ll_stderr = ll;
+ }
+}
+
+
+
+void
+dk3app_log_write_error(dk3_app_t *app, int ll, size_t wished, size_t written)
+{
+ dkChar b1[128]; /* Number of bytes wished to write. */
+ dkChar b2[128]; /* Number of bytes really written. */
+
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(b1,dk3app_no_loc[35],((unsigned long)wished));
+ dk3sf_sprintf3(b2,dk3app_no_loc[35],((unsigned long)written));
+ dk3app_log_i5(app, ll, 170, 171, 172, b2, b1);
+#else
+ if (dk3ma_um_to_string(b1, DK3_SIZEOF(b1,dkChar), (dk3_um_t)wished)) {
+ if (dk3ma_um_to_string(b2, DK3_SIZEOF(b2,dkChar), (dk3_um_t)written)) {
+ dk3app_log_i5(app, ll, 170, 171, 172, b2, b1);
+ }
+ }
+#endif
+}
+
+
+
+void
+dk3app_log_fwrite_error(dk3_app_t *app, int ll, size_t wished, size_t written)
+{
+ dkChar b1[128]; /* Number of bytes wished to write. */
+ dkChar b2[128]; /* Number of bytes really written. */
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(b1,dk3app_no_loc[35],((unsigned long)wished));
+ dk3sf_sprintf3(b2,dk3app_no_loc[35],((unsigned long)written));
+ dk3app_log_i5(app, ll, 174, 175, 176, b2, b1);
+#else
+ if (dk3ma_um_to_string(b1, DK3_SIZEOF(b1,dkChar), (dk3_um_t)wished)) {
+ if (dk3ma_um_to_string(b2, DK3_SIZEOF(b2,dkChar), (dk3_um_t)written)) {
+ dk3app_log_i5(app, ll, 174, 175, 176, b2, b1);
+ }
+ }
+#endif
+}
+
+
+
+dkChar const *
+dk3app_localized(dk3_app_t const *app, size_t num)
+{
+ dkChar const *back = NULL;
+ if(app) {
+ if(app->msg) {
+ back = (app->msg)[num];
+ } else {
+ back = dk3app_kw[num];
+ }
+ }
+ return back;
+}
+
+
+
+dkChar const *
+dk3app_not_localized(size_t num)
+{
+ dkChar const *back = NULL;
+ back = dk3app_no_loc[num];
+ return back;
+}
+
+
+
+int
+dk3app_get_pref_bool(dk3_app_t *app, dkChar const *name, int dv)
+{
+ int back;
+ dkChar buffer[256]; /* Buffer for preference value. */
+ dkChar *p1; /* Start of text. */
+ back = dv;
+ if(app) {
+ if(dk3app_get_pref(app, name, buffer, DK3_SIZEOF(buffer,dkChar))) {
+ p1 = dk3str_start(buffer, NULL);
+ if(p1) {
+ dk3str_chomp(p1, NULL);
+ if(dk3str_is_bool(p1)) {
+ back = ((dk3str_is_on(p1)) ? 1 : 0);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3app_get_pref_int(dk3_app_t *app, dkChar const * name, int dv)
+{
+ int back;
+ int x;
+ dkChar buffer[256];
+ dkChar *p1;
+ $? "+ dk3app_get_pref_int"
+ back = dv;
+ if(app) {
+ if(dk3app_get_pref(app, name, buffer, DK3_SIZEOF(buffer,dkChar))) {
+ p1 = dk3str_start(buffer, NULL);
+ if(p1) {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(p1, dkT("%d"), &x) == 1)
+#else
+ if (0 != dk3ma_i_from_string(&x, p1, NULL))
+#endif
+ {
+ back = x;
+ }
+ }
+ }
+ } $? "- dk3app_get_pref_int %d", back
+ return back;
+}
+
+
+
+#if 0
+
+
+int
+dk3app_get_allowed_prng_types(dk3_app_t *app, dkChar const *il)
+{
+ int back = 0;
+ dkChar buffer[256];
+ dkChar *p1 = NULL;
+ dkChar *p2 = NULL;
+ int i = 0;
+ if((app) && (il)) {
+ if(dk3str_len(il) < DK3_SIZEOF(buffer,dkChar)) {
+ dk3str_cpy_not_overlapped(buffer, il);
+ p1 = dk3str_start(buffer, NULL);
+ while(p1) {
+ p2 = dk3str_chr(p1, dkT(','));
+ if(p2) {
+ *(p2++) = dkT('\0'); p2 = dk3str_start(p2, NULL);
+ }
+ i = dk3str_array_index(dk3app_prng_type_names, p1, 0);
+ switch(i) {
+ case 0: {
+#if DK3_HAVE_OPENSSL_RAND_H
+ back |= DK3_PRNG_OPENSSL;
+#else
+ /* ERROR: Openssl PRNG not available! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 192);
+#endif
+ } break;
+ case 1: {
+#if DK3_HAVE_INITSTATE && DK3_HAVE_SETSTATE && DK3_HAVE_RANDOM
+ back |= DK3_PRNG_STATE;
+#else
+ /* ERROR: initstate()/setstate()/random() not available. */
+ dk3app_log_i1(app, DK3_LL_ERROR, 191);
+#endif
+ } break;
+ case 2: {
+#if DK3_HAVE_NRAND48 && DK3_HAVE_LRAND48
+ back |= DK3_PRNG_RAND48;
+#else
+ /* ERROR: lrand48()/lrand48() not available. */
+ dk3app_log_i1(app, DK3_LL_ERROR, 190);
+#endif
+ } break;
+ case 3: {
+#if DK3_HAVE_RAND && DK3_HAVE_SRAND
+ back |= DK3_PRNG_SIMPLE;
+#else
+ /* ERROR: srand()/rand() not available! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 189);
+#endif
+ } break;
+ default: {
+ /* Unknown PRNG type name! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 187, 188, p1);
+ } break;
+ }
+ p1 = p2;
+ }
+ } else {
+ /* ERROR: Line too long for buffer! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ return back;
+}
+
+
+
+/** Find allowed PRNG types using preferences.
+ @param app Application structure.
+ @return Or-combination of DK3_PRNG_xxx.
+*/
+static
+int
+dk3app_rand_find_allowed_types(dk3_app_t *app)
+{
+ int back = DK3_PRNG_ALL;
+ dkChar buffer[256];
+ $? "+ dk3app_rand_find_allowed_types"
+ if(dk3app_get_pref(app,dk3app_no_loc[37],buffer,DK3_SIZEOF(buffer,dkChar)))
+ { $? ". preference value \"%!ds\"", buffer
+ back = dk3app_get_allowed_prng_types(app, buffer);
+ }
+ $? "- dk3app_rand_find_allowed_types %d", back
+ return back;
+}
+
+
+
+/** Get bytes to seed random number generator.
+ @param app Application structure.
+ @param dp Destination buffer pointer.
+ @param sz Number of bytes required.
+ @param fn File name for seed file.
+ @return Number of bytes found.
+*/
+static
+size_t
+dk3app_read_bytes_from_file(
+ dk3_app_t *app,
+ void *dp,
+ size_t sz,
+ dkChar const *fn
+)
+{
+ size_t back = 0;
+ FILE *fipo;
+ fipo = dk3sf_fopen_app(fn, dk3app_no_loc[36], app);
+ if(fipo) {
+ back = dk3sf_fread_app(dp, 1, sz, fipo, app);
+ fclose(fipo);
+ }
+ return back;
+}
+
+
+
+
+/** Get bytes to seed random number generator.
+ @param app Application structure.
+ @param dp Destination buffer pointer.
+ @param sz Number of bytes required.
+ @param fn File name for seed file.
+ @return Number of bytes found.
+*/
+static
+size_t
+dk3app_get_seed_from_source(dk3_app_t *app,void *dp,size_t sz,dkChar const *fn)
+{
+ size_t back = 0;
+ dk3_stat_t stb;
+ int can_use_file = 1;
+ int mode_denied;
+ $? "+ dk3app_get_seed_from_source \"%s\"", fn
+ /* DEBUG: Attempting to get seed data from ... */
+ dk3app_log_i3(app, DK3_LL_DEBUG, 196, 197, fn);
+ if(dk3sf_stat_app(&stb, fn, NULL)) { $? ". file exists"
+ switch((stb.ft) & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_DIRECTORY: {
+ /* Ignore it. */
+ } break;
+ case DK3_FT_REGULAR: {
+ /* Security checks before using the file. */
+ mode_denied = DK3_FPERM_G_READ
+ | DK3_FPERM_G_WRITE
+ | DK3_FPERM_O_READ
+ | DK3_FPERM_O_WRITE;
+ if((stb.ft) & DK3_FT_SYMLINK) {
+ if((stb.ai) & DK3_STAT_AI_USER_DIFFERS) {
+ can_use_file = 0;
+ /* WARNING: Symlink owner is not file owner. */
+ dk3app_log_i3(app, DK3_LL_ERROR, 185, 186, fn);
+ }
+ if((stb.perm) & mode_denied) {
+ can_use_file = 0;
+ /* WARNING: File not used (permissions). */
+ dk3app_log_i3(app, DK3_LL_ERROR, 183, 184, fn);
+ } else {
+ if((stb.lperm) & mode_denied) {
+ can_use_file = 0;
+ /* WARNING: File not used (permissions). */
+ dk3app_log_i3(app, DK3_LL_ERROR, 183, 184, fn);
+ }
+ }
+ } else {
+ if((stb.perm) & mode_denied) {
+ can_use_file = 0;
+ /* WARNING: File not used (permissions). */
+ dk3app_log_i3(app, DK3_LL_ERROR, 183, 184, fn);
+ }
+ }
+ if(can_use_file) {
+ back = dk3app_read_bytes_from_file(app, dp, sz, fn);
+ }
+ } break;
+ default: {
+ /* Use file. */
+ back = dk3app_read_bytes_from_file(app, dp, sz, fn);
+ } break;
+ }
+ } $? "- dk3app_get_seed_from_source %u", (unsigned)back
+ /* DEBUG: Seed data: ... bytes. */
+ {
+ char b1[64];
+ dkChar b2[64];
+ sprintf(b1, "%lu", (unsigned long)back);
+ if(dk3str_cnv_c8_to_str_app(b2, DK3_SIZEOF(b2,dkChar), b1, app)) {
+ dk3app_log_i3(app, DK3_LL_DEBUG, 198, 199, b2);
+ }
+ }
+ return back;
+}
+
+
+
+/** Get bytes to seed random number generator.
+ @param app Application structure.
+ @param dp Destination buffer pointer.
+ @param sz Number of bytes required.
+ @param fn File name for seed file.
+ @param passno Pass number (only 0 uses files).
+ @return Number of bytes found.
+*/
+static
+size_t
+dk3app_get_seed_bytes(
+ dk3_app_t *app,
+ void *dp,
+ size_t sz,
+ dkChar const *fn,
+ int passno
+)
+{
+ size_t back = 0;
+ dkChar const *p1;
+ dkChar const *p2;
+ dkChar const *p3;
+ dkChar const *p4;
+ dkChar const *p5;
+ dkChar *p6;
+ size_t s;
+ dkChar fnb[DK3_MAX_PATH]; /* File name buffer. */
+ if((app) && (dp) && (sz)) {
+ /* $HOME/.rnd-xxx-application */
+ if(passno == 0) {
+ if(dk3app_get_pref_bool(app, dk3app_no_loc[46], 1)) {
+ p1 = dk3app_get_homedir(app);
+ p2 = dk3app_no_loc[20];
+ p3 = fn;
+ p4 = dk3app_no_loc[5];
+ p5 = dk3app_get_appname(app);
+ if((p1) && (p2) && (p3) && (p4) && (p5)) {
+ s = dk3str_len(p1);
+ s += dk3str_len(p2);
+ s += dk3str_len(p3);
+ s += dk3str_len(p4);
+ s += dk3str_len(p5);
+ if(s < DK3_SIZEOF(fnb,dkChar)) {
+ dk3str_cpy_not_overlapped(fnb, p1);
+ dk3str_cat(fnb, p2);
+ dk3str_cat(fnb, p3);
+ dk3str_cat(fnb, p4);
+ dk3str_cat(fnb, p5);
+ back = dk3app_get_seed_from_source(app, dp, sz, fnb);
+ }
+ }
+ }
+ }
+ /* EGD socket from environment. */
+ if(back == 0) {
+ p1 = dk3sf_getenv(dk3app_no_loc[43]);
+ if(p1) {
+ back = dk3app_get_seed_from_source(app, dp, sz, p1);
+ }
+ }
+ /* EGD socket from preferences. */
+ if(back == 0) {
+ if(dk3app_get_pref(app, dk3app_no_loc[42], fnb, DK3_SIZEOF(fnb,dkChar)))
+ {
+ p6 = dk3str_start(fnb, NULL);
+ if(p6) {
+ dk3str_chomp(p6, NULL);
+ back = dk3app_get_seed_from_source(app, dp, sz, p6);
+ }
+ }
+ }
+#if !DK3_ON_WINDOWS
+ /* /dev/urandom */
+ if(back == 0) {
+ back = dk3app_get_seed_from_source(app, dp, sz, dk3app_no_loc[44]);
+ }
+ /* /dev/random */
+ if(back == 0) {
+ back = dk3app_get_seed_from_source(app, dp, sz, dk3app_no_loc[45]);
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+#if DK3_HAVE_OPENSSL_H
+/** Initialize OpenSSL PRNG.
+ @param app Application structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3app_init_prng_openssl(dk3_app_t *app)
+{
+ int back = 0;
+ int cc = 0;
+ int passno = 0;
+ size_t sz;
+ char seedval[DK3_SEED_OPENSSL_BYTES];
+ do {
+ cc = 0;
+ sz =
+ dk3app_get_seed_bytes(app,seedval,sizeof(seedval),dk3app_no_loc[41],passno);
+ if(sz > 0) {
+ cc = 1;
+ RAND_seed(seedval, sz);
+ if(RAND_status() == 1) {
+ cc = 0; back = 1;
+ }
+#if DK3_ON_WINDOWS
+ if(back == 0) {
+ RAND_screen();
+ if(RAND_status() == 1) {
+ cc = 0; back = 1;
+ }
+ }
+#endif
+ passno++;
+ }
+ } while(cc);
+ if(!back) {
+ /* Warning: Failed to seed OpenSSL PRNG! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 182);
+ }
+ return back;
+}
+#endif
+
+#if DK3_HAVE_INITSTATE && DK3_HAVE_SETSTATE && DK3_HAVE_RANDOM
+/** Initialize state PRNG.
+ @param app Application structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3app_init_prng_state(dk3_app_t *app)
+{
+ int back = 0;
+ unsigned int seedval = 0;
+ if(dk3app_get_seed_bytes(
+ app, (void *)(&seedval), sizeof(unsigned int), dk3app_no_loc[40], 0
+ )
+ )
+ {
+ srandom(seedval);
+ back = 1;
+ }
+ if(!back) {
+ /* Warning: Failed to seed random() PRNG! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 181);
+ }
+ return back;
+}
+#endif
+
+#if DK3_HAVE_NRAND48 && DK3_HAVE_LRAND48
+/** Initialize lrand48() PRNG.
+ @param app Application structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3app_init_prng_rand48(dk3_app_t *app)
+{
+ int back = 0;
+ long int seedval = 0L;
+ if(dk3app_get_seed_bytes(
+ app, (void *)(&seedval), sizeof(long int), dk3app_no_loc[39], 0
+ )
+ )
+ {
+ srand48(seedval);
+ back = 1;
+ }
+ if(!back) {
+ /*Warning: Failed to seed lrand48() PRNG! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 180);
+ }
+ return back;
+}
+#endif
+
+#if DK3_HAVE_RAND && DK3_HAVE_SRAND
+/** Initialize simple rand() PRNG.
+ @param app Application structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3app_init_prng_simple(dk3_app_t *app)
+{
+ int back = 0;
+ unsigned int ui;
+ if(
+ dk3app_get_seed_bytes(
+ app, (void *)(&ui), sizeof(unsigned int), dk3app_no_loc[38], 0
+ )
+ )
+ {
+ srand(ui);
+ back = 1;
+ }
+ if(!back) {
+ /* Warning: Failed to seed simple PRNG! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 179);
+ }
+ return back;
+}
+#endif
+
+
+
+/** Attempt to initialize a PRNG.
+ @param app Application structure.
+ @param il Input line listing allowed PRNGs comma-separated.
+ @return 1 on success (at least one PRNG usable), 0 on error.
+*/
+int
+dk3app_rand_init(dk3_app_t *app, dkChar const *il)
+{
+ int back = 0;
+ int allowed_types;
+ if(app) {
+ if(app->f_rand_initialized) {
+ back = app->f_rand_success;
+ } else {
+ app->f_rand_initialized = 1;
+ if(il) {
+ allowed_types = dk3app_get_allowed_prng_types(app, il);
+ } else {
+ allowed_types = dk3app_rand_find_allowed_types(app);
+ }
+ if(!back) {
+ if(allowed_types & DK3_PRNG_OPENSSL) {
+#if DK3_HAVE_OPENSSL_H
+ back = dk3app_init_prng_openssl(app);
+ if(back) {
+ app->rand_type = DK3_PRNG_OPENSSL;
+ }
+#endif
+ }
+ }
+ if(!back) {
+ if(allowed_types & DK3_PRNG_STATE) {
+#if DK3_HAVE_INITSTATE && DK3_HAVE_SETSTATE && DK3_HAVE_RANDOM
+ back = dk3app_init_prng_state(app);
+ if(back) {
+ app->rand_type = DK3_PRNG_STATE;
+ }
+#endif
+ }
+ }
+ if(!back) {
+ if(allowed_types & DK3_PRNG_RAND48) {
+#if DK3_HAVE_NRAND48 && DK3_HAVE_LRAND48
+ back = dk3app_init_prng_rand48(app);
+ if(back) {
+ app->rand_type = DK3_PRNG_RAND48;
+ }
+#endif
+ }
+ }
+ if(!back) {
+ if(allowed_types & DK3_PRNG_SIMPLE) {
+#if DK3_HAVE_RAND && DK3_HAVE_SRAND
+ back = dk3app_init_prng_simple(app);
+ if(back) {
+ app->rand_type = DK3_PRNG_SIMPLE;
+ }
+#endif
+ }
+ }
+ if(back) {
+ app->f_rand_success = 1;
+ }
+ }
+ }
+ if(!back) {
+ /* ERROR: No PRNG usable! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 178);
+ }
+ return back;
+}
+
+
+
+/** Get random bytes.
+ @param app Application structure.
+ @param db Destination buffer.
+ @param sz Size of \a db (number of bytes).
+ @param f_crypto Flag: For cryptographic purposes.
+ @return Number of bytes written to \a db.
+*/
+static
+size_t
+dk3app_rand_bytes_internal(dk3_app_t *app, void *db, size_t sz, int f_crypto)
+{
+ size_t back = 0;
+ unsigned char *ucptr = NULL;
+ size_t i = 0;
+ unsigned u = 0;
+ if((app) && (db) && (sz)) {
+ ucptr = (unsigned char *)db;
+ if(!(app->f_rand_initialized)) {
+ dk3app_rand_init(app, NULL);
+ }
+ if(app->f_rand_success) {
+ switch(app->rand_type) {
+ case DK3_PRNG_OPENSSL: {
+#if DK3_HAVE_OPENSSL_RAND_H
+ if(f_crypto) {
+ if(RAND_bytes(ucptr, (int)sz) == 1) {
+ back = sz;
+ }
+ } else {
+ if(RAND_pseudo_bytes(ucptr, (int)sz) > -1) {
+ back = sz;
+ }
+ }
+#else
+ /* BUG: Not available! */
+#endif
+ } break;
+ case DK3_PRNG_STATE: {
+#if DK3_HAVE_INITSTATE && DK3_HAVE_SETSTATE && DK3_HAVE_RANDOM
+ long lval;
+ size_t position;
+
+ lval = random() >> 8;
+ position = 0;
+ for(i = 0; i < sz; i++) {
+ *(ucptr++) = (unsigned char)(lval & 0x000000FFL);
+ position++;
+ lval = lval >> 8;
+ if(position >= (sizeof(long) - 1)) {
+ lval = random() >> 8;
+ position = 0;
+ }
+ }
+ back = sz;
+#else
+ /* BUG: Not available! */
+#endif
+ } break;
+ case DK3_PRNG_RAND48: {
+#if DK3_HAVE_NRAND48 && DK3_HAVE_LRAND48
+ long lval;
+ size_t position;
+
+ lval = lrand48() >> 8;
+ position = 0;
+ for(i = 0; i < sz; i++) {
+ *(ucptr++) = (unsigned char)(lval & 0x000000FFL);
+ position++;
+ lval = lval >> 8;
+ if(position >= (sizeof(long) - 1)) {
+ lval = lrand48() >> 8;
+ position = 0;
+ }
+ }
+ back = sz;
+#else
+ /* BUG: Not available! */
+#endif
+ } break;
+ default: {
+#if DK3_HAVE_RAND && DK3_HAVE_SRAND
+ for(i = 0; i < sz; i++) {
+ u = rand();
+#if DK3_SIZEOF_INT > 2
+#if DK3_SIZEOF_INT > 4
+ u = u >> 28;
+#else
+ u = u >> 12;
+#endif
+#else
+ u = u >> 4;
+#endif
+ u &= 0x00FFU;
+ *(ucptr++) = (unsigned char)u;
+ }
+ back = sz;
+#else
+ /* BUG: Not available! */
+#endif
+ } break;
+ }
+ }
+ }
+ if(back < sz) {
+ /* ERROR: Failed to obtain enough random bytes! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 177);
+ }
+ return back;
+}
+
+
+size_t
+dk3app_rand_bytes(dk3_app_t *app, void *db, size_t sz)
+{
+ size_t back;
+ back = dk3app_rand_bytes_internal(app, db, sz, 1);
+ return back;
+}
+
+
+size_t
+dk3app_rand_bytes_non_crypto(dk3_app_t *app, void *db, size_t sz)
+{
+ size_t back;
+ back = dk3app_rand_bytes_internal(app, db, sz, 0);
+ return back;
+}
+
+#endif
+
+
+
+int
+dk3app_process_stdin_lines(
+ dk3_app_t *app,
+ void *obj,
+ dk3_line_handler_t *hf,
+ dkChar *buffer,
+ size_t szbuffer,
+ int de
+)
+{
+ int back = 0;
+ int must_run_directly = 0;
+ int ie;
+ FILE *fipo;
+ dkChar tfn[DK3_MAX_PATH];
+ char b[4096];
+ size_t sz;
+#if DK3_ON_WINDOWS
+ int oldmode;
+#endif
+ if((app) && (hf) && (buffer) && (szbuffer)) {
+ ie = de;
+ if(ie < 0) { ie = app->i_stdin_input_encoding; }
+ if(dk3app_get_temp_file_name(app, tfn, DK3_SIZEOF(tfn,dkChar))) {
+ fipo = dk3sf_fopen_app(tfn, dk3app_no_loc[53], app);
+ if(fipo) {
+#if DK3_ON_WINDOWS
+ oldmode = _setmode(_fileno(stdin), _O_BINARY);
+#endif
+ while((sz = dk3sf_fread_app(b, 1, sizeof(b), stdin, app)) > 0) {
+ dk3sf_fwrite_app(b, 1, sz, fipo, app);
+ }
+ fclose(fipo);
+#if DK3_ON_WINDOWS
+ _setmode(_fileno(stdin), oldmode);
+#endif
+/* 2015-08-21
+ Using ie instead of de.
+*/
+ back = dk3stream_process_filename_lines_app(
+ obj,
+ hf,
+ tfn,
+ buffer,
+ szbuffer,
+ dk3app_get_encoding(app),
+ ie,
+ app
+ );
+ dk3sf_remove_file_app(tfn, app);
+ } else {
+ must_run_directly = 1;
+ }
+ } else {
+ must_run_directly = 1;
+ }
+ if(must_run_directly) {
+#if DK3_ON_WINDOWS
+ oldmode = _setmode(_fileno(stdin), _O_BINARY);
+#endif
+ back = dk3stream_process_file_lines_app(
+ obj,
+ hf,
+ stdin,
+ NULL,
+ buffer,
+ szbuffer,
+ dk3app_get_encoding(app),
+ de,
+ app
+ );
+#if DK3_ON_WINDOWS
+ _setmode(_fileno(stdin), oldmode);
+#endif
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3app_process_stdin_chars(
+ dk3_app_t *app,
+ void *obj,
+ dk3_char_handler_t *hf,
+ int de
+)
+{
+ int back = 0;
+ int must_run_directly = 0;
+ int ie;
+ dkChar tfn[DK3_MAX_PATH];
+ char b[4096];
+ FILE *fipo;
+ size_t sz;
+#if DK3_ON_WINDOWS
+ int oldmode;
+#endif
+ $? "+ dk3app_process_stdin_chars"
+ if((app) && (hf)) { $? ". default encoding = %d", de
+ ie = de;
+ if(ie < 0) {
+ ie = app->i_stdin_input_encoding;
+ } $? ". input encoding now = %d", ie
+ if(dk3app_get_temp_file_name(app, tfn, DK3_SIZEOF(tfn,dkChar))) {
+ fipo = dk3sf_fopen_app(tfn, dk3app_no_loc[53], app);
+ if(fipo) {
+#if DK3_ON_WINDOWS
+ oldmode = _setmode(_fileno(stdin), _O_BINARY);
+#endif
+ while((sz = dk3sf_fread_app(b, 1, sizeof(b), stdin, app)) > 0) {
+ dk3sf_fwrite_app(b, 1, sz, fipo, app);
+ }
+ fclose(fipo);
+#if DK3_ON_WINDOWS
+ _setmode(_fileno(stdin), oldmode);
+#endif
+ back = dk3stream_process_filename_chars_app(obj, hf, tfn, ie, app);
+ dk3sf_remove_file_app(tfn, app);
+ } else {
+ must_run_directly = 1;
+ }
+ } else {
+ must_run_directly = 1;
+ }
+ if(must_run_directly) {
+#if DK3_ON_WINDOWS
+ oldmode = _setmode(_fileno(stdin), _O_BINARY);
+#endif
+ back = dk3stream_process_file_chars_app(obj, hf, stdin, NULL, ie, app);
+#if DK3_ON_WINDOWS
+ _setmode(_fileno(stdin), oldmode);
+#endif
+ }
+ } $? "- dk3app_process_stdin_chars %d", back
+ return back;
+}
+
+
+
+#if !DK3_ON_WINDOWS
+#if DK3_HAVE_SETUID && DK3_HAVE_SETGID && DK3_HAVE_CHOWN
+#if DK3_CHAR_SIZE == 1
+/** Change owner for one file if the file exists.
+ @param app Application structure.
+ @param ul1 File name.
+ @param ul2 File name suffix.
+ @param uid New user ID for file ownership.
+ @param gid New group ID for file ownership.
+ @return 1 on success (owner modified or file does not exist).
+*/
+static
+int
+dk3app_change_owner_for_file(
+ dk3_app_t *app,
+ unsigned long ul1,
+ unsigned ul2,
+ uid_t uid,
+ gid_t gid
+)
+{
+ dkChar fnb[DK3_MAX_PATH]; /* Full name buffer. */
+ dkChar smb[32]; /* Small buffer. */
+ char tmb[32];
+ dk3_stat_t stb;
+ int back = 1;
+ $? "+ dk3app_change_owner_for_file %08lx.%03x %u %u", ul1, ul2, (unsigned)uid, (unsigned)gid
+ sprintf(tmb, "/%08lx.%03x", ul1, ul2);
+ if(dk3str_c8_to_str_simple_app(smb,DK3_SIZEOF(smb,dkChar),tmb,app)) {
+ if(dk3str_len(app->n_tmpdir) < DK3_SIZEOF(fnb,dkChar)) { $? ". length"
+ dk3str_cpy_not_overlapped(fnb, app->n_tmpdir);
+ if((dk3str_len(fnb) + dk3str_len(smb)) < DK3_SIZEOF(fnb,dkChar)) {
+ dk3str_cat(fnb, smb);
+ dk3str_correct_filename(fnb);
+ if(dk3sf_stat_app(&stb, fnb, NULL)) { $? ". file"
+ if(0 != chown(fnb, uid, gid)) { $? "! chown"
+ back = 0;
+ } else { $? ". chown"
+ }
+ } else { $? ". no file"
+ /* If there is no such file, there is no need to change owner. */
+ }
+ } else { $? "! length"
+ back = 0;
+ }
+ } else { $? "! length"
+ back = 0;
+ }
+ } else { $? "! fn conv"
+ }
+ $? "- dk3app_change_owner_for_file %d", back
+ return back;
+}
+
+int
+dk3app_change_user(dk3_app_t *app, uid_t uid, gid_t gid)
+{
+ FILE *fipo;
+ unsigned long ul1;
+ unsigned ul2;
+ int back = 1;
+ $? "+ dk3app_change_user"
+ if((app) && ((uid) || (gid))) { $? ". args ok"
+ if(app->n_logfilename) { $? ". have logfile"
+ if (0 == app->cr_log) {
+ dk3app_create_log_directory(app);
+ app->cr_log = 1;
+ }
+ fipo = dk3sf_fopen_app(app->n_logfilename, dkT("a"), app);
+ if(fipo) {
+ fclose(fipo);
+ }
+ if(0 != chown(app->n_logfilename, uid, gid)) { $? ". ownership changed"
+ back = 0;
+ } else { $? "! log owner change %d", errno
+ }
+ } else { $? "! no logfile"
+ }
+ if(app->n_tmpdir) { $? ". have tmpdir"
+ if(0 != chown(app->n_tmpdir, uid, gid)) {
+ back = 0;
+ }
+ if(app->i_tmpcarry) { $? "! tmpdir overflow"
+ for(ul1 = 0UL; ul1 < 0xFFFFFFFFUL; ul1++) {
+ for(ul2 = 0U; ul2 < 0x00001000U; ul2++) {
+ if(!dk3app_change_owner_for_file(app, ul1, ul2, uid, gid)) {
+ back = 0; $? "! tmp owner change"
+ }
+ }
+ }
+ for(ul2 = 0U; ul2 < 0x00001000U; ul2++) {
+ if(!dk3app_change_owner_for_file(app, 0xFFFFFFFFUL, ul2, uid, gid)) {
+ back = 0; $? "! tmp owner change"
+ }
+ }
+ } else {
+ for(ul1 = 0UL; ul1 < app->ul_tmpname; ul1++) {
+ for(ul2 = 0U; ul2 < 0x00001000U; ul2++) {
+ if(!dk3app_change_owner_for_file(app, ul1, ul2, uid, gid)) {
+ back = 0; $? "! tmp owner change"
+ }
+ }
+ }
+ for(ul2 = 0U; ul2 < app->u_tmpsuffix; ul2++) {
+ if(!dk3app_change_owner_for_file(app,app->ul_tmpname,ul2,uid,gid)) {
+ back = 0; $? "! tmp owner change"
+ }
+ }
+ }
+ } else { $? "! no tmpdir"
+ }
+ } else { $? "! args"
+ } $? "- dk3app_change_user %d", back
+ return back;
+}
+#endif
+#endif
+#endif
+
+
+
+int
+dk3app_get_dir_from_pref(
+ dk3_app_t *app,
+ dkChar const *pn,
+ dkChar *buf,
+ size_t bs,
+ int ch
+)
+{
+ int back = 0;
+ if((app) && (pn) && (buf) && (bs)) {
+ if(dk3app_get_pref(app, pn, buf, bs)) {
+ if(ch) {
+ if(dk3sf_is_dir_app(buf, NULL)) {
+ back = 1;
+ } else {
+ /* ERROR: Directory does not exist! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 369, 370, pn);
+ }
+ } else {
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dk3app.h b/support/dktools/dk3app.h
new file mode 100644
index 0000000000..e85083fe56
--- /dev/null
+++ b/support/dktools/dk3app.h
@@ -0,0 +1,733 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3app.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK3APP_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3APP_H_INCLUDED 1
+
+
+#line 10 "dk3app.ctr"
+
+/** @file dk3app.h Application support.
+*/
+
+#include "dk3conf.h"
+#include "dk3types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open application structure for command line application.
+ * Diagnostic messages are written to stderr and to the log file.
+ * The log file $HOME/log/<i>application</i>-<i>pid</i>.log
+ * is removed automatically by dk3app_close() unless there was an
+ * error message.
+ * @param argc Number of command line arguments.
+ * @param argv Command line arguments array.
+ * @param gn Application group name.
+ * @return Pointer to new application on success, NULL on error.
+ */
+dk3_app_t *
+dk3app_open_command(int argc, dkChar const * const * argv, dkChar const *gn);
+
+/** Open application structure for GUI application.
+ * Diagnostic messages are written to the log file only.
+ * The log file is removed automatically by dk3app_open() unless
+ * there were error messages.
+ * Typically this function is invoked from a DkWxAppHelper constructor.
+ * @param argc Number of command line arguments.
+ * @param argv Command line arguments array.
+ * @param gn Application group name.
+ * @return Pointer to new application on success, NULL on error.
+ */
+dk3_app_t *
+dk3app_open_gui(int argc, dkChar const * const * argv, dkChar const *gn);
+
+/** First silence check to correct the type if necessary.
+ Do not report errors directly, set app->de instead.
+ @param app Application structure.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+*/
+int
+dk3app_first_silence_check(dk3_app_t *app,int argc,dkChar const * const *argv);
+
+/** Open application structure for a daemon.
+ * Log messages are appended to
+ * ${localstatedir}/log/<i>applicationname</i>/<i>applicationname</i>.log.
+ * @param wd Working directory when starting the program.
+ * @param argc Number of command line arguments.
+ * @param argv Command line arguments array.
+ * @param gn Application group name.
+ * @return Pointer to new application on success, NULL on error.
+ */
+dk3_app_t *
+dk3app_open_daemon(dkChar const *wd, int argc, dkChar const * const * argv, dkChar const *gn);
+
+/** Open application structure for a silent application (no diagnostics).
+ * @param argc Number of command line arguments.
+ * @param argv Command line arguments array.
+ * @param gn Application group name.
+ * @return Pointer to new application on success, NULL on error.
+ */
+dk3_app_t *
+dk3app_open_silent(int argc, dkChar const * const * argv, dkChar const *gn);
+
+/** Close application structure, release dynamic memory and resources
+ * assigned to the object.
+ * @param app Application to close.
+ */
+void
+dk3app_close(dk3_app_t *app);
+
+/** Log a message consisting of multiple parts.
+ * @param app Application structure.
+ * @param ll Log level.
+ * @param msg Message parts array. Pointer to an array
+ * of string pointers, all array elements are concatenated to
+ * create the message text.
+ * @param nmsg Number of elements in the array.
+ */
+void
+dk3app_log_msg(dk3_app_t *app, int ll, dkChar const * const * msg, size_t nmsg);
+
+/** Log message consisting of one part.
+ * @param app Application structure.
+ * @param ll Log level.
+ * @param msg Message texts array, typically localized, obtained
+ * from dk3app_messages().
+ * @param i1 Index of message text in \a msg.
+ */
+void
+dk3app_log_1(dk3_app_t *app, int ll, dkChar const * const * msg, size_t i1);
+
+/** Log message consisting of two parts.
+ * @param app Application structure.
+ * @param ll Log level.
+ * @param msg Message texts array, typically localized, obtained
+ * from dk3app_messages().
+ * @param i Index of message text in \a msg.
+ * @param st String to write as second part.
+ */
+void
+dk3app_log_2(
+ dk3_app_t *app, int ll, dkChar const * const * msg,
+ size_t i, dkChar const *st
+);
+
+/** Log message consisting of three parts.
+ * @param app Application structure.
+ * @param ll Log level.
+ * @param msg Message string array.
+ * @param i1 Index of first message text in \a msg.
+ * @param i2 Index of third message text in \a msg.
+ * @param st Second message text.
+ */
+void
+dk3app_log_3(
+ dk3_app_t *app, int ll, dkChar const * const * msg,
+ size_t i1, size_t i2, dkChar const *st
+);
+
+/** Log message consisting of five parts.
+ * @param app Application structure.
+ * @param ll Log level.
+ * @param msg Message string array.
+ * @param i1 Index of first message text in \a msg.
+ * @param i2 Index of third message text in \a msg.
+ * @param i3 Index of fifth message text in \a msg.
+ * @param st1 Second message text.
+ * @param st2 Fourth message text.
+ */
+void
+dk3app_log_5(
+ dk3_app_t *app, int ll, dkChar const * const * msg,
+ size_t i1, size_t i2, size_t i3, dkChar const *st1, dkChar const *st2
+);
+
+/** Log message consisting of one part.
+ * @param app Application structure.
+ * @param ll Log level.
+ * @param i1 Index of message text in messages array.
+ */
+void
+dk3app_log_i1(dk3_app_t *app, int ll, size_t i1);
+
+/** Log message consisting of two parts.
+ * @param app Application structure.
+ * @param ll Log level.
+ * @param i Index of first message text in messages array.
+ * @param st Second message text.
+ */
+void
+dk3app_log_i2(dk3_app_t *app, int ll, size_t i, dkChar const * st);
+
+/** Log message consisting of three parts.
+ * @param app Application structure.
+ * @param ll Log level.
+ * @param i1 Index of first message text in messages array.
+ * @param i2 Index of third message text in messages array.
+ * @param st Second message text.
+ */
+void
+dk3app_log_i3(
+ dk3_app_t *app, int ll,
+ size_t i1, size_t i2, dkChar const *st
+);
+
+/** Log message consisting of five parts.
+ * @param app Application structure.
+ * @param ll Log level.
+ * @param i1 Index of first message text in messages array.
+ * @param i2 Index of third message text in messages array.
+ * @param i3 Index of fifth message text in messages array.
+ * @param st1 Second message text.
+ * @param st2 Fourth message text.
+ */
+void
+dk3app_log_i5(
+ dk3_app_t *app, int ll,
+ size_t i1, size_t i2, size_t i3, dkChar const *st1, dkChar const *st2
+);
+
+/** Set file name for current source file position.
+ The source file position is used when writing diagnostic messages.
+ @param app Application structure.
+ @param fn Source file name. Use NULL to disable printing
+ the file name.
+*/
+void
+dk3app_set_source_file(dk3_app_t *app, dkChar const *fn);
+
+/** Set source line number for current source file position.
+ The source file position is used when writing diagnostic messages.
+ @param app Application structure.
+ @param li Line number. Use 0UL to disable printing the
+ line number.
+*/
+void
+dk3app_set_source_line(dk3_app_t *app, unsigned long li);
+
+/** Get current source file name.
+ @param app Application structure.
+ @return Current source file name, may be NULL.
+*/
+dkChar const *
+dk3app_get_source_file(dk3_app_t const *app);
+
+/** Get current source line number.
+ @param app Application structure.
+ @return Current source file line number, may be 0UL.
+*/
+unsigned long
+dk3app_get_source_line(dk3_app_t const *app);
+
+
+/** Get number of command line arguments.
+ @param app Application structure.
+ @return Number of command line arguments.
+*/
+int
+dk3app_get_argc(dk3_app_t const *app);
+
+/** Get command line arguments array.
+ @param app Application structure.
+ @return Command line arguments array.
+*/
+dkChar const * const *
+dk3app_get_argv(dk3_app_t const *app);
+
+/** Retrieve application name.
+ @param app Application structure.
+ @return Application name on success, NULL on error.
+*/
+dkChar const *
+dk3app_get_appname(dk3_app_t const *app);
+
+/** Retrieve name of executable file.
+ * @param app Application structure.
+ * @return Executable file name on success, NULL on error.
+*/
+dkChar const *
+dk3app_get_execfilename(dk3_app_t const *app);
+
+/** Retrieve binary directory name.
+ @param app Application structure.
+ @return Name of bin directory on success, NULL on error.
+*/
+dkChar const *
+dk3app_get_bindir(dk3_app_t const *app);
+
+/** Get system configuration directory (/etc or /usr/local/etc).
+ @param app Application structure.
+ @return Directory name on success, NULL on error.
+*/
+dkChar const *
+dk3app_get_etcdir(dk3_app_t const *app);
+
+/** Get data root directory (/usr/share or /usr/local/share).
+ @param app Application structure.
+ @return Directory name on success, NULL on error.
+*/
+dkChar const *
+dk3app_get_sharedir(dk3_app_t const *app);
+
+/** Get local state directory (/var or /usr/local/var).
+ @param app Application structure.
+ @return Directory name on success, NULL on error.
+*/
+dkChar const *
+dk3app_get_vardir(dk3_app_t const *app);
+
+/** Get user login name.
+ @param app Application structure.
+ @return Login name on success, NULL on error.
+*/
+dkChar const *
+dk3app_get_logname(dk3_app_t const *app);
+
+/** Get host name.
+ @param app Application structure.
+ @return Host name on success, NULL on error.
+*/
+dkChar const *
+dk3app_get_hostname(dk3_app_t const *app);
+
+/** Get users home directory.
+ @param app Application structure.
+ @return Home directory on success, NULL on error.
+*/
+dkChar const *
+dk3app_get_homedir(dk3_app_t const *app);
+
+/** Get application group name.
+ @param app Application structure.
+ @return Group name on success, NULL on error.
+*/
+dkChar const *
+dk3app_get_appgroup(dk3_app_t const *app);
+
+/** Retrieve users language.
+ @param app Application structure.
+ @return Pointer to users language or NULL if no language is defined.
+*/
+dkChar const *
+dk3app_get_language(dk3_app_t const *app);
+
+/** Retrieve users region.
+ @param app Application structure.
+ @return Pointer to users region or NULL if no region is defined.
+*/
+dkChar const *
+dk3app_get_region(dk3_app_t const *app);
+
+/** Retrieve internal encoding.
+ @param app Application structure.
+ @return Internal (in-memory) encoding.
+*/
+int
+dk3app_get_encoding(dk3_app_t const *app);
+
+/** Retrieve output file encoding.
+ @param app Application structure.
+ @return Output file encoding.
+*/
+int
+dk3app_get_output_encoding(dk3_app_t const *app);
+
+/** Retrieve default encoding expected on stdin.
+ @param app Application structure.
+ @return Expected input encoding (DK3_FILE_ENCODING_xxx).
+*/
+int
+dk3app_get_input_stdin_encoding(dk3_app_t const *app);
+
+/** Retrieve default encoding expected on files.
+ @param app Application structure.
+ @return Expected input encoding (DK3_FILE_ENCODING_xxx).
+*/
+int
+dk3app_get_input_file_encoding(dk3_app_t const *app);
+
+/** Get file name for temporary file.
+ The file name is stored into the buffer @a db.
+ @param app Application structure.
+ @param db Destination buffer.
+ @param sz Size of \a db (number of characters).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3app_get_temp_file_name(dk3_app_t *app, dkChar *db, size_t sz);
+
+/** Set a preference value.
+ Preferences set by this function are written to the
+ $HOME/.dk3app/<i>application</i>/dk3pref.conf file during
+ dk3app_close().
+ @param app Application structure.
+ @param k Key (preference name).
+ @param v Value.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3app_set_pref(dk3_app_t *app, dkChar const *k, dkChar const *v);
+
+/** Get a preference value.
+ On success the preference value is written to @a d.
+ @param app Application structure.
+ @param k Key (preference name).
+ @param d Destination buffer.
+ @param s Size of \a d (number of characters).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3app_get_pref(dk3_app_t *app, dkChar const *k, dkChar *d, size_t s);
+
+/** Get boolean preference value.
+ @param app Application structure.
+ @param name Preference name.
+ @param dv Default value if preference not found.
+ @return Preference value or default value.
+*/
+int
+dk3app_get_pref_bool(dk3_app_t *app, dkChar const *name, int dv);
+
+/** Get int preference value.
+ @param app Application structure.
+ @param name Preference name.
+ @param dv Default value.
+ @return Preference value or default value.
+*/
+int
+dk3app_get_pref_int(dk3_app_t *app, dkChar const * name, int dv);
+
+/** Get a system preference value.
+ Command line and user-set preferences are ignored.
+ @param app Application structure.
+ @param k Key (preference name).
+ @param d Destination buffer.
+ @param s Size of \a d (number of characters).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3app_get_sys_pref(dk3_app_t *app, dkChar const *k, dkChar *d, size_t s);
+
+/** Unconfigure application.
+ @param app Application structure.
+*/
+void
+dk3app_unconfigure(dk3_app_t *app);
+
+/** Find configuration file.
+ On success the function returns a file name collection.
+ Configuration files with low priority are at the start of the
+ collection, files with higher priority are at the end.
+ This allows higher priorized configuration files to overwrite
+ settings made by the previously processed files.
+ After you are done with the search results set, use
+ dk3search_close() to close the set and release resources assigned
+ to it.
+ @param app Application structure.
+ @param fn File name to search for (short filename
+ without leading path).
+ @param exclu Flag: Exclude users configuration file.
+ @return Collection of file names (full path names including the
+ leading directory), use dk3search_close() after
+ use to destroy it.
+*/
+dk3_search_t *
+dk3app_find_config_file(dk3_app_t *app, dkChar const *fn, int exclu);
+
+
+/** Find configuration file in reverse search order
+ (most significant file first).
+ This function is typically used to process the first file from
+ the set only which is the most significant file.
+ After you are done with the search results set, use
+ dk3search_close() to close the set and release resources assigned
+ to it.
+ @param app Application structure.
+ @param fn File name to search for (short file name without
+ leading directory).
+ @param exclu Flag: Exclude users configuration files.
+ @return Collection of file names (full path names with leading
+ directory), use dk3search_close() after
+ use to destroy it.
+*/
+dk3_search_t *
+dk3app_find_config_file_revers(dk3_app_t *app, dkChar const *fn, int exclu);
+
+/** Find data file.
+ The full path name of the file found is written to @a db on success.
+ @param app Application structure.
+ @param fn File name to search for (short file name without leading
+ directory).
+ @param db Destination buffer.
+ @param sz Size of \a db (number of characters).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3app_find_data_file(dk3_app_t *app, dkChar const *fn, dkChar *db, size_t sz);
+
+/** Get string table.
+ @param app Application structure.
+ @param fn Short file name of string table.
+ @param dv Default value, used if file not found.
+ @return New string table if found or \a dv on problems.
+*/
+dkChar const * const *
+dk3app_messages(dk3_app_t *app, dkChar const *fn, dkChar const * const *dv);
+
+/** Find and print help text.
+ The function searches for a help text file in the users
+ language. If no file is found the default text is printed.
+ @param app Application structure.
+ @param fn Help text file name (short name wih).
+ @param dt Default text to use if file not found.
+*/
+void
+dk3app_help(dk3_app_t *app, dkChar const *fn, dkChar const * const *dt);
+
+/** Get log level used for stderr.
+ @param app Application structure.
+ @return Log level required for logging to stderr.
+*/
+int
+dk3app_get_stderr_log_level(dk3_app_t const *app);
+
+/** Set log level used for stderr.
+ @param app Application structure.
+ @param ll New log level.
+*/
+void
+dk3app_set_stderr_log_level(dk3_app_t *app, int ll);
+
+/** Report write error.
+ @param app Application structure.
+ @param ll Log level.
+ @param wished Number of bytes wished to write.
+ @param written Number of bytes written.
+*/
+void
+dk3app_log_write_error(dk3_app_t *app, int ll, size_t wished, size_t written);
+
+
+/** Report fwrite error.
+ @param app Application structure.
+ @param ll Log level.
+ @param wished Number of elements wished to write.
+ @param written Number of elements written.
+*/
+void
+dk3app_log_fwrite_error(dk3_app_t *app, int ll, size_t wished, size_t written);
+
+/** Get a localized text.
+ @param app Application structure.
+ @param num Index of string in array.
+ @return Pointer to localized string on success, NULL on error.
+*/
+dkChar const *
+dk3app_localized(dk3_app_t const *app, size_t num);
+
+/** Get a non-localized text.
+ @param num Index of string in array.
+ @return Pointer to localized string on success, NULL on error.
+*/
+dkChar const *
+dk3app_not_localized(size_t num);
+
+/** Initialize random number generator.
+ Set up allowed PRNG types and seed best PRNG found.
+ If at least one of the PRNG types specified in @a il is available
+ we attempt to seed this PRNG.
+ The following preferences are used by this function:
+ - /rand/types is used if il is NULL.
+ - /rand/file/allowed configured whether or not usage o
+ seed file in the users home directory is allowed
+ - /rand/egd/name can be used to specify of the EDG socket
+ if an EGD (entropy gathering daemon) is running on the
+ system. By default /dev/urandom and/or /dev/random
+ are used to seed a PRNG if available.
+ @param app Application structure.
+ @param il Text line to process, may be NULL.
+ If this argument is NULL, the /rand/types preference is used
+ to find the allowed PRNG types.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3app_rand_init(dk3_app_t *app, dkChar const *il);
+
+/** Retrieve list of allowed PRNG types from a text line.
+ If the text line \a il pointer is NULL the
+ /rand/types preference value is used.
+ @param app Application structure.
+ @param il Text line to process.
+ @return Combination of DK3_PRNG_xxx.
+*/
+int
+dk3app_get_allowed_prng_types(dk3_app_t *app, dkChar const *il);
+
+/** Retrieve pseudo-random bytes.
+ @param app Application structure.
+ @param db Destination buffer.
+ @param sz Size of \a db (number of bytes).
+ @return Number of bytes found.
+*/
+size_t
+dk3app_rand_bytes(dk3_app_t *app, void *db, size_t sz);
+
+/** Retrieve pseudo-random bytes.
+ The bytes will not be used for cryptographic or authentication
+ purposes, so we can use a less unpredictive (less complicated und
+ thus faster) generation mechanism.
+ @param app Application structure.
+ @param db Destination buffer.
+ @param sz Size of \a db (number of bytes).
+ @return Number of bytes found.
+*/
+size_t
+dk3app_rand_bytes_non_crypto(dk3_app_t *app, void *db, size_t sz);
+
+/** Attempt to save random seed to file when closing an application.
+ @param app Application structure.
+*/
+void
+dk3app_rand_end(dk3_app_t *app);
+
+/** Get default input encoding for stdin ignoring preferences.
+ @param app Application structure.
+ @return Encoding (DK3_FILE_ENCODING_xxx).
+*/
+int
+dk3app_get_default_stdin_encoding(dk3_app_t const *app);
+
+/** Get default input encoding for files ignoring preferences.
+ @param app Application structure.
+ @return Encoding (DK3_FILE_ENCODING_xxx).
+*/
+int
+dk3app_get_default_file_encoding(dk3_app_t const *app);
+
+/** Process standard input character by character.
+ Attempt to save stdin data to file so we can do a BOM check.
+ @param app Application structure.
+ @param obj Object to modify while processing data.
+ @param hf Handler function.
+ @param de Default encoding.
+*/
+int
+dk3app_process_stdin_chars(
+ dk3_app_t *app,
+ void *obj,
+ dk3_char_handler_t *hf,
+ int de
+);
+
+/** Process standard input line by line.
+ Attempt to save stdin data to file so we can do a BOM check.
+ @param app Application structure.
+ @param obj Object to modify while reading data.
+ @param hf Handler function.
+ @param buffer Line buffer.
+ @param szbuffer Size of buffer.
+ @param de Default encoding.
+*/
+int
+dk3app_process_stdin_lines(
+ dk3_app_t *app,
+ void *obj,
+ dk3_line_handler_t *hf,
+ dkChar *buffer,
+ size_t szbuffer,
+ int de
+);
+
+/** Get maximum log level used by the application.
+ @param app Application structure.
+ @return Maximum log level used by the application.
+*/
+int
+dk3app_max_log_level(dk3_app_t const *app);
+
+/** Remove trailing newline and handle backslash escape sequences.
+ This function is run on lines read from string table file.
+ @param lb Line buffer.
+*/
+void
+dk3app_squeeze_line(char *lb);
+
+
+#if !DK3_ON_WINDOWS
+#if DK3_HAVE_SETUID && DK3_HAVE_SETGID && DK3_HAVE_CHOWN
+#if DK3_CHAR_SIZE == 1
+/** Change ownership to writable files.
+ This function is used by daemons before switching to a
+ non-privileged user account.
+ @param app Application structure.
+ @param uid New user ID for process.
+ @param gid New group ID for process.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3app_change_user(dk3_app_t *app, uid_t uid, gid_t gid);
+#endif
+#endif
+#endif
+
+/** Retrieve directory setting from preference.
+ @param app Application structure.
+ @param pn Preference name.
+ @param buf Result buffer.
+ @param bs Size of bs (number of dkChar).
+ @param ch Flag: Check existance of directory.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3app_get_dir_from_pref(
+ dk3_app_t *app,
+ dkChar const *pn,
+ dkChar *buf,
+ size_t bs,
+ int ch
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3appr.c b/support/dktools/dk3appr.c
new file mode 100644
index 0000000000..ae661e85c4
--- /dev/null
+++ b/support/dktools/dk3appr.c
@@ -0,0 +1,857 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3appr.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3appr.c The dk3appr module.
+*/
+
+
+#line 10 "dk3appr.ctr"
+
+#include "dk3all.h"
+
+#if DK3_HAVE_OPENSSL_RAND_H
+#include <openssl/rand.h>
+#endif
+
+#if DK3_ON_WINDOWS
+#include <wincrypt.h>
+#endif
+
+
+
+
+#line 22 "dk3appr.ctr"
+
+
+
+/** Names for the PRNG types.
+*/
+static dkChar const * const dk3app_prng_type_names[] = {
+/* 0 */ dkT("openssl"), /* OpenSSL PRNG. */
+/* 1 */ dkT("random"), /* initstate()/setstate()/random() */
+/* 2 */ dkT("rand48"), /* lrand48(). */
+/* 3 */ dkT("simple"), /* srand()/rand(). */
+NULL
+};
+
+int
+dk3app_get_allowed_prng_types(dk3_app_t *app, dkChar const *il)
+{
+ int back = 0;
+ dkChar buffer[256];
+ dkChar *p1 = NULL;
+ dkChar *p2 = NULL;
+ int i = 0;
+
+
+#line 44 "dk3appr.ctr"
+ if((app) && (il)) {
+ if(dk3str_len(il) < DK3_SIZEOF(buffer,dkChar)) {
+ dk3str_cpy_not_overlapped(buffer, il);
+ p1 = dk3str_start(buffer, NULL);
+ while(p1) {
+ p2 = dk3str_chr(p1, dkT(','));
+ if(p2) {
+ *(p2++) = dkT('\0'); p2 = dk3str_start(p2, NULL);
+ }
+ i = dk3str_array_index(dk3app_prng_type_names, p1, 0);
+ switch(i) {
+ case 0: {
+#if DK3_HAVE_OPENSSL_RAND_H
+ back |= DK3_PRNG_OPENSSL;
+#else
+ /* ERROR: Openssl PRNG not available! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 192);
+#endif
+ } break;
+ case 1: {
+#if DK3_HAVE_INITSTATE && DK3_HAVE_SETSTATE && DK3_HAVE_RANDOM
+ back |= DK3_PRNG_STATE;
+#else
+ /* ERROR: initstate()/setstate()/random() not available. */
+ dk3app_log_i1(app, DK3_LL_ERROR, 191);
+#endif
+ } break;
+ case 2: {
+#if DK3_HAVE_NRAND48 && DK3_HAVE_LRAND48
+ back |= DK3_PRNG_RAND48;
+#else
+ /* ERROR: lrand48()/lrand48() not available. */
+ dk3app_log_i1(app, DK3_LL_ERROR, 190);
+#endif
+ } break;
+ case 3: {
+#if DK3_HAVE_RAND && DK3_HAVE_SRAND
+ back |= DK3_PRNG_SIMPLE;
+#else
+ /* ERROR: srand()/rand() not available! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 189);
+#endif
+ } break;
+ default: {
+ /* Unknown PRNG type name! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 187, 188, p1);
+ } break;
+ }
+ p1 = p2;
+ }
+ } else {
+ /* ERROR: Line too long for buffer! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+
+#line 99 "dk3appr.ctr"
+ return back;
+}
+
+
+
+/** Find allowed PRNG types using preferences.
+ @param app Application structure.
+ @return Or-combination of DK3_PRNG_xxx.
+*/
+static
+int
+dk3app_rand_find_allowed_types(dk3_app_t *app)
+{
+ int back = DK3_PRNG_ALL;
+ dkChar buffer[256];
+
+
+#line 115 "dk3appr.ctr"
+ if(dk3app_get_pref(
+ app,dk3app_not_localized(37),buffer,DK3_SIZEOF(buffer,dkChar))
+ )
+ {
+
+#line 119 "dk3appr.ctr"
+ back = dk3app_get_allowed_prng_types(app, buffer);
+ }
+
+#line 121 "dk3appr.ctr"
+ return back;
+}
+
+
+
+/** Get bytes to seed random number generator.
+ @param app Application structure.
+ @param dp Destination buffer pointer.
+ @param sz Number of bytes required.
+ @param fn File name for seed file.
+ @return Number of bytes found.
+*/
+static
+size_t
+dk3app_read_bytes_from_file(
+ dk3_app_t *app,
+ void *dp,
+ size_t sz,
+ dkChar const *fn
+)
+{
+ size_t back = 0;
+ FILE *fipo;
+
+
+#line 145 "dk3appr.ctr"
+ fipo = dk3sf_fopen_app(fn, dk3app_not_localized(36), app);
+ if(fipo) {
+ back = dk3sf_fread_app(dp, 1, sz, fipo, app);
+ fclose(fipo);
+ }
+
+#line 150 "dk3appr.ctr"
+ return back;
+}
+
+
+
+
+/** Get bytes to seed random number generator.
+ @param app Application structure.
+ @param dp Destination buffer pointer.
+ @param sz Number of bytes required.
+ @param fn File name for seed file.
+ @return Number of bytes found.
+*/
+static
+size_t
+dk3app_get_seed_from_source(dk3_app_t *app,void *dp,size_t sz,dkChar const *fn)
+{
+ size_t back = 0;
+ dk3_stat_t stb;
+ int can_use_file = 1;
+ int mode_denied;
+
+
+#line 172 "dk3appr.ctr"
+ /* DEBUG: Attempting to get seed data from ... */
+ dk3app_log_i3(app, DK3_LL_DEBUG, 196, 197, fn);
+ if(dk3sf_stat_app(&stb, fn, NULL)) {
+
+#line 175 "dk3appr.ctr"
+ switch((stb.ft) & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_DIRECTORY: {
+ /* Ignore it. */
+ } break;
+ case DK3_FT_REGULAR: {
+ /* Security checks before using the file. */
+ mode_denied = DK3_FPERM_G_READ
+ | DK3_FPERM_G_WRITE
+ | DK3_FPERM_O_READ
+ | DK3_FPERM_O_WRITE;
+ if((stb.ft) & DK3_FT_SYMLINK) {
+ if((stb.ai) & DK3_STAT_AI_USER_DIFFERS) {
+ can_use_file = 0;
+ /* WARNING: Symlink owner is not file owner. */
+ dk3app_log_i3(app, DK3_LL_ERROR, 185, 186, fn);
+ }
+ if((stb.perm) & mode_denied) {
+ can_use_file = 0;
+ /* WARNING: File not used (permissions). */
+ dk3app_log_i3(app, DK3_LL_ERROR, 183, 184, fn);
+ } else {
+ if((stb.lperm) & mode_denied) {
+ can_use_file = 0;
+ /* WARNING: File not used (permissions). */
+ dk3app_log_i3(app, DK3_LL_ERROR, 183, 184, fn);
+ }
+ }
+ } else {
+ if((stb.perm) & mode_denied) {
+ can_use_file = 0;
+ /* WARNING: File not used (permissions). */
+ dk3app_log_i3(app, DK3_LL_ERROR, 183, 184, fn);
+ }
+ }
+ if(can_use_file) {
+ back = dk3app_read_bytes_from_file(app, dp, sz, fn);
+ }
+ } break;
+ default: {
+ /* Use file. */
+ back = dk3app_read_bytes_from_file(app, dp, sz, fn);
+ } break;
+ }
+ }
+
+#line 219 "dk3appr.ctr"
+ /* DEBUG: Seed data: ... bytes. */
+ {
+ char b1[64];
+ dkChar b2[64];
+ sprintf(b1, "%lu", (unsigned long)back);
+ if(dk3str_cnv_c8_to_str_app(b2, DK3_SIZEOF(b2,dkChar), b1, app)) {
+ dk3app_log_i3(app, DK3_LL_DEBUG, 198, 199, b2);
+ }
+ }
+ return back;
+}
+
+
+
+/** Get bytes to seed random number generator.
+ @param app Application structure.
+ @param dp Destination buffer pointer.
+ @param sz Number of bytes required.
+ @param fn File name for seed file.
+ @param passno Pass number (only 0 uses files).
+ @return Number of bytes found.
+*/
+static
+size_t
+dk3app_get_seed_bytes(
+ dk3_app_t *app,
+ void *dp,
+ size_t sz,
+ dkChar const *fn,
+ int passno
+)
+{
+ size_t back = 0;
+ dkChar const *p1;
+ dkChar const *p2;
+ dkChar const *p3;
+ dkChar const *p4;
+ dkChar const *p5;
+ dkChar *p6;
+ size_t s;
+ dkChar fnb[DK3_MAX_PATH]; /* File name buffer. */
+ if((app) && (dp) && (sz)) {
+ /* $HOME/.rnd-xxx-application */
+ if(passno == 0) {
+ if(dk3app_get_pref_bool(app, dk3app_not_localized(46), 1)) {
+ p1 = dk3app_get_homedir(app);
+ p2 = dk3app_not_localized(20);
+ p3 = fn;
+ p4 = dk3app_not_localized(5);
+ p5 = dk3app_get_appname(app);
+ if((p1) && (p2) && (p3) && (p4) && (p5)) {
+ s = dk3str_len(p1);
+ s += dk3str_len(p2);
+ s += dk3str_len(p3);
+ s += dk3str_len(p4);
+ s += dk3str_len(p5);
+ if(s < DK3_SIZEOF(fnb,dkChar)) {
+ dk3str_cpy_not_overlapped(fnb, p1);
+ dk3str_cat(fnb, p2);
+ dk3str_cat(fnb, p3);
+ dk3str_cat(fnb, p4);
+ dk3str_cat(fnb, p5);
+ back = dk3app_get_seed_from_source(app, dp, sz, fnb);
+ }
+ }
+ }
+ }
+ /* EGD socket from environment. */
+ if(back == 0) {
+ p1 = dk3sf_getenv(dk3app_not_localized(43));
+ if(p1) {
+ back = dk3app_get_seed_from_source(app, dp, sz, p1);
+ }
+ }
+ /* EGD socket from preferences. */
+ if(back == 0) {
+ if(dk3app_get_pref(
+ app, dk3app_not_localized(42), fnb, DK3_SIZEOF(fnb,dkChar))
+ )
+ {
+ p6 = dk3str_start(fnb, NULL);
+ if(p6) {
+ dk3str_chomp(p6, NULL);
+ back = dk3app_get_seed_from_source(app, dp, sz, p6);
+ }
+ }
+ }
+#if !DK3_ON_WINDOWS
+ /* /dev/urandom */
+ if(back == 0) {
+ back = dk3app_get_seed_from_source(app, dp, sz, dk3app_not_localized(44));
+ }
+ /* /dev/random */
+ if(back == 0) {
+ back = dk3app_get_seed_from_source(app, dp, sz, dk3app_not_localized(45));
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+#if DK3_HAVE_OPENSSL_RAND_H
+/** Initialize OpenSSL PRNG.
+ @param app Application structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3app_init_prng_openssl(dk3_app_t *app)
+{
+ int back = 0;
+ int cc = 0;
+ int passno = 0;
+ size_t sz;
+ char seedval[DK3_SEED_OPENSSL_BYTES];
+#if DK3_ON_WINDOWS
+ BYTE sv[DK3_SEED_OPENSSL_BYTES];
+ HCRYPTPROV hcp;
+ BOOL res;
+ DWORD dwLgt;
+#endif
+
+
+#line 343 "dk3appr.ctr"
+ do {
+ cc = 0;
+ sz =
+ dk3app_get_seed_bytes(
+ app,seedval,sizeof(seedval),dk3app_not_localized(41),passno
+ );
+
+#line 349 "dk3appr.ctr"
+ if(sz > 0) {
+ cc = 1;
+ RAND_seed(seedval, (int)sz);
+ if(RAND_status() == 1) {
+ cc = 0; back = 1;
+ }
+ }
+#if DK3_ON_WINDOWS
+ if(back == 0) {
+
+#line 358 "dk3appr.ctr"
+ dk3app_log_i1(app, DK3_LL_DEBUG, 227);
+ res = CryptAcquireContext(
+ &hcp, /* Pointer to result variable. */
+ NULL, /* Default container (user name). */
+ NULL, /* Users default cryptographic provider. */
+ PROV_RSA_FULL, /* Provider type. */
+ CRYPT_VERIFYCONTEXT
+ );
+ if(res) {
+
+#line 367 "dk3appr.ctr"
+ dwLgt = sizeof(sv);
+ res = CryptGenRandom(hcp, dwLgt, sv);
+ if(res) {
+
+#line 370 "dk3appr.ctr"
+ cc = 1;
+ RAND_seed(sv, sizeof(sv));
+ if(RAND_status() == 1) {
+ cc = 0; back = 1;
+
+#line 374 "dk3appr.ctr"
+ }
+ } else {
+
+#line 376 "dk3appr.ctr"
+ }
+ CryptReleaseContext(hcp, (DWORD)0L);
+ } else {
+
+#line 379 "dk3appr.ctr"
+ }
+ }
+ if(back == 0) {
+
+#line 382 "dk3appr.ctr"
+ dk3app_log_i1(app, DK3_LL_DEBUG, 228);
+ RAND_screen();
+ if(RAND_status() == 1) {
+ cc = 0; back = 1;
+
+#line 386 "dk3appr.ctr"
+ }
+ }
+#endif
+ passno++;
+ } while(cc);
+ if(back) {
+ dk3app_log_i1(app, DK3_LL_DEBUG, 229);
+ } else {
+ /* Warning: Failed to seed OpenSSL PRNG! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 182);
+ }
+
+#line 397 "dk3appr.ctr"
+ return back;
+}
+#endif
+
+#if DK3_HAVE_INITSTATE && DK3_HAVE_SETSTATE && DK3_HAVE_RANDOM
+/** Initialize state PRNG.
+ @param app Application structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3app_init_prng_state(dk3_app_t *app)
+{
+ int back = 0;
+ unsigned int seedval = 0;
+ if(dk3app_get_seed_bytes(
+ app, (void *)(&seedval), sizeof(unsigned int), dk3app_not_localized(40), 0
+ )
+ )
+ {
+ srandom(seedval);
+ back = 1;
+ }
+ if(!back) {
+ /* Warning: Failed to seed random() PRNG! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 181);
+ }
+ return back;
+}
+#endif
+
+#if DK3_HAVE_NRAND48 && DK3_HAVE_LRAND48
+/** Initialize lrand48() PRNG.
+ @param app Application structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3app_init_prng_rand48(dk3_app_t *app)
+{
+ int back = 0;
+ long int seedval = 0L;
+ if(dk3app_get_seed_bytes(
+ app, (void *)(&seedval), sizeof(long int), dk3app_not_localized(39), 0
+ )
+ )
+ {
+ srand48(seedval);
+ back = 1;
+ }
+ if(!back) {
+ /*Warning: Failed to seed lrand48() PRNG! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 180);
+ }
+ return back;
+}
+#endif
+
+#if DK3_HAVE_RAND && DK3_HAVE_SRAND
+/** Initialize simple rand() PRNG.
+ @param app Application structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3app_init_prng_simple(dk3_app_t *app)
+{
+ int back = 0;
+ unsigned int ui;
+ if(
+ dk3app_get_seed_bytes(
+ app, (void *)(&ui), sizeof(unsigned int), dk3app_not_localized(38), 0
+ )
+ )
+ {
+ srand(ui);
+ back = 1;
+ }
+ if(!back) {
+ /* Warning: Failed to seed simple PRNG! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 179);
+ }
+ return back;
+}
+#endif
+
+
+
+/** Attempt to initialize a PRNG.
+ @param app Application structure.
+ @param il Input line listing allowed PRNGs comma-separated.
+ @return 1 on success (at least one PRNG usable), 0 on error.
+*/
+int
+dk3app_rand_init(dk3_app_t *app, dkChar const *il)
+{
+ int back = 0;
+ int allowed_types;
+
+
+#line 496 "dk3appr.ctr"
+ if(app) {
+ if(app->f_rand_initialized) {
+ back = app->f_rand_success;
+ } else {
+ app->f_rand_initialized = 1;
+ if(il) {
+ allowed_types = dk3app_get_allowed_prng_types(app, il);
+ } else {
+ allowed_types = dk3app_rand_find_allowed_types(app);
+ }
+ if(!back) {
+ if(allowed_types & DK3_PRNG_OPENSSL) {
+
+#line 508 "dk3appr.ctr"
+#if DK3_HAVE_OPENSSL_RAND_H
+
+
+#line 510 "dk3appr.ctr"
+ back = dk3app_init_prng_openssl(app);
+ if(back) {
+
+#line 512 "dk3appr.ctr"
+ app->rand_type = DK3_PRNG_OPENSSL;
+ }
+#else
+
+
+#line 516 "dk3appr.ctr"
+#endif
+ }
+ }
+ if(!back) {
+ if(allowed_types & DK3_PRNG_STATE) {
+#if DK3_HAVE_INITSTATE && DK3_HAVE_SETSTATE && DK3_HAVE_RANDOM
+ back = dk3app_init_prng_state(app);
+ if(back) {
+ app->rand_type = DK3_PRNG_STATE;
+ }
+#endif
+ }
+ }
+ if(!back) {
+ if(allowed_types & DK3_PRNG_RAND48) {
+#if DK3_HAVE_NRAND48 && DK3_HAVE_LRAND48
+ back = dk3app_init_prng_rand48(app);
+ if(back) {
+ app->rand_type = DK3_PRNG_RAND48;
+ }
+#endif
+ }
+ }
+ if(!back) {
+ if(allowed_types & DK3_PRNG_SIMPLE) {
+#if DK3_HAVE_RAND && DK3_HAVE_SRAND
+ back = dk3app_init_prng_simple(app);
+ if(back) {
+ app->rand_type = DK3_PRNG_SIMPLE;
+ }
+#endif
+ }
+ }
+ if(back) {
+ app->f_rand_success = 1;
+ }
+ }
+ }
+ if(!back) {
+ /* ERROR: No PRNG usable! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 178);
+ }
+
+#line 558 "dk3appr.ctr"
+ return back;
+}
+
+
+
+/** Get random bytes.
+ @param app Application structure.
+ @param db Destination buffer.
+ @param sz Size of \a db (number of bytes).
+ @param f_crypto Flag: For cryptographic purposes.
+ @return Number of bytes written to \a db.
+*/
+static
+size_t
+dk3app_rand_bytes_internal(dk3_app_t *app, void *db, size_t sz, int f_crypto)
+{
+ size_t back = 0;
+ unsigned char *ucptr = NULL;
+ size_t i = 0;
+ unsigned u = 0;
+ if((app) && (db) && (sz)) {
+ ucptr = (unsigned char *)db;
+ if(!(app->f_rand_initialized)) {
+ dk3app_rand_init(app, NULL);
+ }
+ if(app->f_rand_success) {
+ switch(app->rand_type) {
+ case DK3_PRNG_OPENSSL: {
+#if DK3_HAVE_OPENSSL_RAND_H
+ if(f_crypto) {
+ if(RAND_bytes(ucptr, (int)sz) == 1) {
+ back = sz;
+ }
+ } else {
+ if(RAND_pseudo_bytes(ucptr, (int)sz) > -1) {
+ back = sz;
+ }
+ }
+#else
+ /* BUG: Not available! */
+#endif
+ } break;
+ case DK3_PRNG_STATE: {
+#if DK3_HAVE_INITSTATE && DK3_HAVE_SETSTATE && DK3_HAVE_RANDOM
+ long lval;
+ size_t position;
+
+ lval = random() >> 8;
+ position = 0;
+ for(i = 0; i < sz; i++) {
+ *(ucptr++) = (unsigned char)(lval & 0x000000FFL);
+ position++;
+ lval = lval >> 8;
+ if(position >= (sizeof(long) - 1)) {
+ lval = random() >> 8;
+ position = 0;
+ }
+ }
+ back = sz;
+#else
+ /* BUG: Not available! */
+#endif
+ } break;
+ case DK3_PRNG_RAND48: {
+#if DK3_HAVE_NRAND48 && DK3_HAVE_LRAND48
+ long lval;
+ size_t position;
+
+ lval = lrand48() >> 8;
+ position = 0;
+ for(i = 0; i < sz; i++) {
+ *(ucptr++) = (unsigned char)(lval & 0x000000FFL);
+ position++;
+ lval = lval >> 8;
+ if(position >= (sizeof(long) - 1)) {
+ lval = lrand48() >> 8;
+ position = 0;
+ }
+ }
+ back = sz;
+#else
+ /* BUG: Not available! */
+#endif
+ } break;
+ default: {
+#if DK3_HAVE_RAND && DK3_HAVE_SRAND
+ for(i = 0; i < sz; i++) {
+ u = rand();
+#if DK3_SIZEOF_INT > 2
+#if DK3_SIZEOF_INT > 4
+ u = u >> 28;
+#else
+ u = u >> 12;
+#endif
+#else
+ u = u >> 4;
+#endif
+ u &= 0x00FFU;
+ *(ucptr++) = (unsigned char)u;
+ }
+ back = sz;
+#else
+ /* BUG: Not available! */
+#endif
+ } break;
+ }
+ }
+ }
+ if(back < sz) {
+ /* ERROR: Failed to obtain enough random bytes! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 177);
+ }
+ return back;
+}
+
+
+size_t
+dk3app_rand_bytes(dk3_app_t *app, void *db, size_t sz)
+{
+ size_t back;
+ back = dk3app_rand_bytes_internal(app, db, sz, 1);
+ return back;
+}
+
+
+size_t
+dk3app_rand_bytes_non_crypto(dk3_app_t *app, void *db, size_t sz)
+{
+ size_t back;
+ back = dk3app_rand_bytes_internal(app, db, sz, 0);
+ return back;
+}
+
+
+
+void
+dk3app_rand_end(dk3_app_t *app)
+{
+#if DK3_HAVE_OPENSSL_RAND_H
+#if DK3_CHAR_SIZE == 1
+ dkChar const *p1 = NULL;
+ dkChar const *p2 = NULL;
+ dkChar const *p3 = NULL;
+ dkChar const *p4 = NULL;
+ dkChar const *p5 = NULL;
+ size_t sz = 0;
+ FILE *fipo = NULL;
+ dkChar fnb[DK3_MAX_PATH];
+#endif
+#endif
+
+
+#line 709 "dk3appr.ctr"
+ if((app->f_rand_initialized) && (app->f_rand_success)) {
+
+#line 710 "dk3appr.ctr"
+ switch(app->rand_type) {
+ case DK3_PRNG_OPENSSL: {
+#if DK3_HAVE_OPENSSL_RAND_H
+#if DK3_CHAR_SIZE == 1
+ p1 = dk3app_get_homedir(app);
+ p2 = dk3app_not_localized(20);
+ p3 = dk3app_not_localized(41);
+ p4 = dk3app_not_localized(5);
+ p5 = dk3app_get_appname(app);
+ if((p1) && (p2) && (p3) && (p4) && (p5)) {
+ sz = dk3str_len(p1);
+ sz += dk3str_len(p2);
+ sz += dk3str_len(p3);
+ sz += dk3str_len(p4);
+ sz += dk3str_len(p5);
+ if(sz < DK3_SIZEOF(fnb,dkChar)) {
+ dk3str_cpy_not_overlapped(fnb, p1);
+ dk3str_cat(fnb, p2);
+ dk3str_cat(fnb, p3);
+ dk3str_cat(fnb, p4);
+ dk3str_cat(fnb, p5);
+
+#line 731 "dk3appr.ctr"
+ fipo = dk3sf_fopen_app(fnb, dk3app_not_localized(24), app);
+ if(fipo) {
+ fclose(fipo); fipo = NULL;
+#if DK3_ON_WINDOWS
+ /* chmod(fnb, 0600); */
+#else
+#if DK3_HAVE_CHMOD
+ chmod(fnb, 0600);
+#endif
+#endif
+ if(RAND_write_file(fnb) <= 0) {
+ /* Warning: Failed to save random seed. */
+ dk3app_log_i1(app, DK3_LL_ERROR, 193);
+ }
+ }
+ }
+ }
+#endif
+#endif
+ } break;
+ }
+ } else {
+
+#line 753 "dk3appr.ctr"
+ }
+
+#line 754 "dk3appr.ctr"
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dk3appr.ctr b/support/dktools/dk3appr.ctr
new file mode 100644
index 0000000000..b96268979d
--- /dev/null
+++ b/support/dktools/dk3appr.ctr
@@ -0,0 +1,759 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk3all.h"
+
+#if DK3_HAVE_OPENSSL_RAND_H
+#include <openssl/rand.h>
+#endif
+
+#if DK3_ON_WINDOWS
+#include <wincrypt.h>
+#endif
+
+$(trace-include)
+
+
+
+/** Names for the PRNG types.
+*/
+static dkChar const * const dk3app_prng_type_names[] = {
+/* 0 */ dkT("openssl"), /* OpenSSL PRNG. */
+/* 1 */ dkT("random"), /* initstate()/setstate()/random() */
+/* 2 */ dkT("rand48"), /* lrand48(). */
+/* 3 */ dkT("simple"), /* srand()/rand(). */
+NULL
+};
+
+int
+dk3app_get_allowed_prng_types(dk3_app_t *app, dkChar const *il)
+{
+ int back = 0;
+ dkChar buffer[256];
+ dkChar *p1 = NULL;
+ dkChar *p2 = NULL;
+ int i = 0;
+ $? "+ dk3app_get_allowed_prng_types \"%!ds\"", il
+ if((app) && (il)) {
+ if(dk3str_len(il) < DK3_SIZEOF(buffer,dkChar)) {
+ dk3str_cpy_not_overlapped(buffer, il);
+ p1 = dk3str_start(buffer, NULL);
+ while(p1) {
+ p2 = dk3str_chr(p1, dkT(','));
+ if(p2) {
+ *(p2++) = dkT('\0'); p2 = dk3str_start(p2, NULL);
+ }
+ i = dk3str_array_index(dk3app_prng_type_names, p1, 0);
+ switch(i) {
+ case 0: {
+#if DK3_HAVE_OPENSSL_RAND_H
+ back |= DK3_PRNG_OPENSSL;
+#else
+ /* ERROR: Openssl PRNG not available! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 192);
+#endif
+ } break;
+ case 1: {
+#if DK3_HAVE_INITSTATE && DK3_HAVE_SETSTATE && DK3_HAVE_RANDOM
+ back |= DK3_PRNG_STATE;
+#else
+ /* ERROR: initstate()/setstate()/random() not available. */
+ dk3app_log_i1(app, DK3_LL_ERROR, 191);
+#endif
+ } break;
+ case 2: {
+#if DK3_HAVE_NRAND48 && DK3_HAVE_LRAND48
+ back |= DK3_PRNG_RAND48;
+#else
+ /* ERROR: lrand48()/lrand48() not available. */
+ dk3app_log_i1(app, DK3_LL_ERROR, 190);
+#endif
+ } break;
+ case 3: {
+#if DK3_HAVE_RAND && DK3_HAVE_SRAND
+ back |= DK3_PRNG_SIMPLE;
+#else
+ /* ERROR: srand()/rand() not available! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 189);
+#endif
+ } break;
+ default: {
+ /* Unknown PRNG type name! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 187, 188, p1);
+ } break;
+ }
+ p1 = p2;
+ }
+ } else {
+ /* ERROR: Line too long for buffer! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ } $? "- dk3app_rand_get_allowed_prng_types %d", back
+ return back;
+}
+
+
+
+/** Find allowed PRNG types using preferences.
+ @param app Application structure.
+ @return Or-combination of DK3_PRNG_xxx.
+*/
+static
+int
+dk3app_rand_find_allowed_types(dk3_app_t *app)
+{
+ int back = DK3_PRNG_ALL;
+ dkChar buffer[256];
+ $? "+ dk3app_rand_find_allowed_types"
+ if(dk3app_get_pref(
+ app,dk3app_not_localized(37),buffer,DK3_SIZEOF(buffer,dkChar))
+ )
+ { $? ". buffer = \"%!ds\"", buffer
+ back = dk3app_get_allowed_prng_types(app, buffer);
+ } $? "- dk3app_rand_find_allowed_types %d", back
+ return back;
+}
+
+
+
+/** Get bytes to seed random number generator.
+ @param app Application structure.
+ @param dp Destination buffer pointer.
+ @param sz Number of bytes required.
+ @param fn File name for seed file.
+ @return Number of bytes found.
+*/
+static
+size_t
+dk3app_read_bytes_from_file(
+ dk3_app_t *app,
+ void *dp,
+ size_t sz,
+ dkChar const *fn
+)
+{
+ size_t back = 0;
+ FILE *fipo;
+ $? "+ dk3app_read_bytes_from_file"
+ fipo = dk3sf_fopen_app(fn, dk3app_not_localized(36), app);
+ if(fipo) {
+ back = dk3sf_fread_app(dp, 1, sz, fipo, app);
+ fclose(fipo);
+ } $? "- dk3app_read_bytes_from_file %u", (unsigned)back
+ return back;
+}
+
+
+
+
+/** Get bytes to seed random number generator.
+ @param app Application structure.
+ @param dp Destination buffer pointer.
+ @param sz Number of bytes required.
+ @param fn File name for seed file.
+ @return Number of bytes found.
+*/
+static
+size_t
+dk3app_get_seed_from_source(dk3_app_t *app,void *dp,size_t sz,dkChar const *fn)
+{
+ size_t back = 0;
+ dk3_stat_t stb;
+ int can_use_file = 1;
+ int mode_denied;
+ $? "+ dk3app_get_seed_from_source \"%!ds\"", fn
+ /* DEBUG: Attempting to get seed data from ... */
+ dk3app_log_i3(app, DK3_LL_DEBUG, 196, 197, fn);
+ if(dk3sf_stat_app(&stb, fn, NULL)) { $? ". file exists"
+ switch((stb.ft) & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_DIRECTORY: {
+ /* Ignore it. */
+ } break;
+ case DK3_FT_REGULAR: {
+ /* Security checks before using the file. */
+ mode_denied = DK3_FPERM_G_READ
+ | DK3_FPERM_G_WRITE
+ | DK3_FPERM_O_READ
+ | DK3_FPERM_O_WRITE;
+ if((stb.ft) & DK3_FT_SYMLINK) {
+ if((stb.ai) & DK3_STAT_AI_USER_DIFFERS) {
+ can_use_file = 0;
+ /* WARNING: Symlink owner is not file owner. */
+ dk3app_log_i3(app, DK3_LL_ERROR, 185, 186, fn);
+ }
+ if((stb.perm) & mode_denied) {
+ can_use_file = 0;
+ /* WARNING: File not used (permissions). */
+ dk3app_log_i3(app, DK3_LL_ERROR, 183, 184, fn);
+ } else {
+ if((stb.lperm) & mode_denied) {
+ can_use_file = 0;
+ /* WARNING: File not used (permissions). */
+ dk3app_log_i3(app, DK3_LL_ERROR, 183, 184, fn);
+ }
+ }
+ } else {
+ if((stb.perm) & mode_denied) {
+ can_use_file = 0;
+ /* WARNING: File not used (permissions). */
+ dk3app_log_i3(app, DK3_LL_ERROR, 183, 184, fn);
+ }
+ }
+ if(can_use_file) {
+ back = dk3app_read_bytes_from_file(app, dp, sz, fn);
+ }
+ } break;
+ default: {
+ /* Use file. */
+ back = dk3app_read_bytes_from_file(app, dp, sz, fn);
+ } break;
+ }
+ } $? "- dk3app_get_seed_from_source %u", (unsigned)back
+ /* DEBUG: Seed data: ... bytes. */
+ {
+ char b1[64];
+ dkChar b2[64];
+ sprintf(b1, "%lu", (unsigned long)back);
+ if(dk3str_cnv_c8_to_str_app(b2, DK3_SIZEOF(b2,dkChar), b1, app)) {
+ dk3app_log_i3(app, DK3_LL_DEBUG, 198, 199, b2);
+ }
+ }
+ return back;
+}
+
+
+
+/** Get bytes to seed random number generator.
+ @param app Application structure.
+ @param dp Destination buffer pointer.
+ @param sz Number of bytes required.
+ @param fn File name for seed file.
+ @param passno Pass number (only 0 uses files).
+ @return Number of bytes found.
+*/
+static
+size_t
+dk3app_get_seed_bytes(
+ dk3_app_t *app,
+ void *dp,
+ size_t sz,
+ dkChar const *fn,
+ int passno
+)
+{
+ size_t back = 0;
+ dkChar const *p1;
+ dkChar const *p2;
+ dkChar const *p3;
+ dkChar const *p4;
+ dkChar const *p5;
+ dkChar *p6;
+ size_t s;
+ dkChar fnb[DK3_MAX_PATH]; /* File name buffer. */
+ if((app) && (dp) && (sz)) {
+ /* $HOME/.rnd-xxx-application */
+ if(passno == 0) {
+ if(dk3app_get_pref_bool(app, dk3app_not_localized(46), 1)) {
+ p1 = dk3app_get_homedir(app);
+ p2 = dk3app_not_localized(20);
+ p3 = fn;
+ p4 = dk3app_not_localized(5);
+ p5 = dk3app_get_appname(app);
+ if((p1) && (p2) && (p3) && (p4) && (p5)) {
+ s = dk3str_len(p1);
+ s += dk3str_len(p2);
+ s += dk3str_len(p3);
+ s += dk3str_len(p4);
+ s += dk3str_len(p5);
+ if(s < DK3_SIZEOF(fnb,dkChar)) {
+ dk3str_cpy_not_overlapped(fnb, p1);
+ dk3str_cat(fnb, p2);
+ dk3str_cat(fnb, p3);
+ dk3str_cat(fnb, p4);
+ dk3str_cat(fnb, p5);
+ back = dk3app_get_seed_from_source(app, dp, sz, fnb);
+ }
+ }
+ }
+ }
+ /* EGD socket from environment. */
+ if(back == 0) {
+ p1 = dk3sf_getenv(dk3app_not_localized(43));
+ if(p1) {
+ back = dk3app_get_seed_from_source(app, dp, sz, p1);
+ }
+ }
+ /* EGD socket from preferences. */
+ if(back == 0) {
+ if(dk3app_get_pref(
+ app, dk3app_not_localized(42), fnb, DK3_SIZEOF(fnb,dkChar))
+ )
+ {
+ p6 = dk3str_start(fnb, NULL);
+ if(p6) {
+ dk3str_chomp(p6, NULL);
+ back = dk3app_get_seed_from_source(app, dp, sz, p6);
+ }
+ }
+ }
+#if !DK3_ON_WINDOWS
+ /* /dev/urandom */
+ if(back == 0) {
+ back = dk3app_get_seed_from_source(app, dp, sz, dk3app_not_localized(44));
+ }
+ /* /dev/random */
+ if(back == 0) {
+ back = dk3app_get_seed_from_source(app, dp, sz, dk3app_not_localized(45));
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+#if DK3_HAVE_OPENSSL_RAND_H
+/** Initialize OpenSSL PRNG.
+ @param app Application structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3app_init_prng_openssl(dk3_app_t *app)
+{
+ int back = 0;
+ int cc = 0;
+ int passno = 0;
+ size_t sz;
+ char seedval[DK3_SEED_OPENSSL_BYTES];
+#if DK3_ON_WINDOWS
+ BYTE sv[DK3_SEED_OPENSSL_BYTES];
+ HCRYPTPROV hcp;
+ BOOL res;
+ DWORD dwLgt;
+#endif
+ $? "+ dk3app_init_prng_openssl"
+ do {
+ cc = 0;
+ sz =
+ dk3app_get_seed_bytes(
+ app,seedval,sizeof(seedval),dk3app_not_localized(41),passno
+ ); $? ". Number of seed bytes = %u", (unsigned)sz
+ if(sz > 0) {
+ cc = 1;
+ RAND_seed(seedval, (int)sz);
+ if(RAND_status() == 1) {
+ cc = 0; back = 1;
+ }
+ }
+#if DK3_ON_WINDOWS
+ if(back == 0) { $? ". obtain seed from CryptoAPI"
+ dk3app_log_i1(app, DK3_LL_DEBUG, 227);
+ res = CryptAcquireContext(
+ &hcp, /* Pointer to result variable. */
+ NULL, /* Default container (user name). */
+ NULL, /* Users default cryptographic provider. */
+ PROV_RSA_FULL, /* Provider type. */
+ CRYPT_VERIFYCONTEXT
+ );
+ if(res) { $? ". context ok"
+ dwLgt = sizeof(sv);
+ res = CryptGenRandom(hcp, dwLgt, sv);
+ if(res) { $? ". bytes ok"
+ cc = 1;
+ RAND_seed(sv, sizeof(sv));
+ if(RAND_status() == 1) {
+ cc = 0; back = 1; $? ". successfully seeded from CryptoAPI"
+ }
+ } else { $? "! no bytes"
+ }
+ CryptReleaseContext(hcp, (DWORD)0L);
+ } else { $? "! no context"
+ }
+ }
+ if(back == 0) { $? ". attempt to seed from screen"
+ dk3app_log_i1(app, DK3_LL_DEBUG, 228);
+ RAND_screen();
+ if(RAND_status() == 1) {
+ cc = 0; back = 1; $? ". successfully seeded from screen"
+ }
+ }
+#endif
+ passno++;
+ } while(cc);
+ if(back) {
+ dk3app_log_i1(app, DK3_LL_DEBUG, 229);
+ } else {
+ /* Warning: Failed to seed OpenSSL PRNG! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 182);
+ } $? "- dk3app_init_prng_openssl %d", back
+ return back;
+}
+#endif
+
+#if DK3_HAVE_INITSTATE && DK3_HAVE_SETSTATE && DK3_HAVE_RANDOM
+/** Initialize state PRNG.
+ @param app Application structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3app_init_prng_state(dk3_app_t *app)
+{
+ int back = 0;
+ unsigned int seedval = 0;
+ if(dk3app_get_seed_bytes(
+ app, (void *)(&seedval), sizeof(unsigned int), dk3app_not_localized(40), 0
+ )
+ )
+ {
+ srandom(seedval);
+ back = 1;
+ }
+ if(!back) {
+ /* Warning: Failed to seed random() PRNG! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 181);
+ }
+ return back;
+}
+#endif
+
+#if DK3_HAVE_NRAND48 && DK3_HAVE_LRAND48
+/** Initialize lrand48() PRNG.
+ @param app Application structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3app_init_prng_rand48(dk3_app_t *app)
+{
+ int back = 0;
+ long int seedval = 0L;
+ if(dk3app_get_seed_bytes(
+ app, (void *)(&seedval), sizeof(long int), dk3app_not_localized(39), 0
+ )
+ )
+ {
+ srand48(seedval);
+ back = 1;
+ }
+ if(!back) {
+ /*Warning: Failed to seed lrand48() PRNG! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 180);
+ }
+ return back;
+}
+#endif
+
+#if DK3_HAVE_RAND && DK3_HAVE_SRAND
+/** Initialize simple rand() PRNG.
+ @param app Application structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3app_init_prng_simple(dk3_app_t *app)
+{
+ int back = 0;
+ unsigned int ui;
+ if(
+ dk3app_get_seed_bytes(
+ app, (void *)(&ui), sizeof(unsigned int), dk3app_not_localized(38), 0
+ )
+ )
+ {
+ srand(ui);
+ back = 1;
+ }
+ if(!back) {
+ /* Warning: Failed to seed simple PRNG! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 179);
+ }
+ return back;
+}
+#endif
+
+
+
+/** Attempt to initialize a PRNG.
+ @param app Application structure.
+ @param il Input line listing allowed PRNGs comma-separated.
+ @return 1 on success (at least one PRNG usable), 0 on error.
+*/
+int
+dk3app_rand_init(dk3_app_t *app, dkChar const *il)
+{
+ int back = 0;
+ int allowed_types;
+ $? "+ dk3app_rand_init"
+ if(app) {
+ if(app->f_rand_initialized) {
+ back = app->f_rand_success;
+ } else {
+ app->f_rand_initialized = 1;
+ if(il) {
+ allowed_types = dk3app_get_allowed_prng_types(app, il);
+ } else {
+ allowed_types = dk3app_rand_find_allowed_types(app);
+ }
+ if(!back) {
+ if(allowed_types & DK3_PRNG_OPENSSL) { $? ". check OpenSSL"
+#if DK3_HAVE_OPENSSL_RAND_H
+ $? ". OpenSSL available"
+ back = dk3app_init_prng_openssl(app);
+ if(back) { $? ". OpenSSL initialized"
+ app->rand_type = DK3_PRNG_OPENSSL;
+ }
+#else
+ $? "! OpenSSL not available"
+#endif
+ }
+ }
+ if(!back) {
+ if(allowed_types & DK3_PRNG_STATE) {
+#if DK3_HAVE_INITSTATE && DK3_HAVE_SETSTATE && DK3_HAVE_RANDOM
+ back = dk3app_init_prng_state(app);
+ if(back) {
+ app->rand_type = DK3_PRNG_STATE;
+ }
+#endif
+ }
+ }
+ if(!back) {
+ if(allowed_types & DK3_PRNG_RAND48) {
+#if DK3_HAVE_NRAND48 && DK3_HAVE_LRAND48
+ back = dk3app_init_prng_rand48(app);
+ if(back) {
+ app->rand_type = DK3_PRNG_RAND48;
+ }
+#endif
+ }
+ }
+ if(!back) {
+ if(allowed_types & DK3_PRNG_SIMPLE) {
+#if DK3_HAVE_RAND && DK3_HAVE_SRAND
+ back = dk3app_init_prng_simple(app);
+ if(back) {
+ app->rand_type = DK3_PRNG_SIMPLE;
+ }
+#endif
+ }
+ }
+ if(back) {
+ app->f_rand_success = 1;
+ }
+ }
+ }
+ if(!back) {
+ /* ERROR: No PRNG usable! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 178);
+ } $? "- dk3app_rand_init %d", back
+ return back;
+}
+
+
+
+/** Get random bytes.
+ @param app Application structure.
+ @param db Destination buffer.
+ @param sz Size of \a db (number of bytes).
+ @param f_crypto Flag: For cryptographic purposes.
+ @return Number of bytes written to \a db.
+*/
+static
+size_t
+dk3app_rand_bytes_internal(dk3_app_t *app, void *db, size_t sz, int f_crypto)
+{
+ size_t back = 0;
+ unsigned char *ucptr = NULL;
+ size_t i = 0;
+ unsigned u = 0;
+ if((app) && (db) && (sz)) {
+ ucptr = (unsigned char *)db;
+ if(!(app->f_rand_initialized)) {
+ dk3app_rand_init(app, NULL);
+ }
+ if(app->f_rand_success) {
+ switch(app->rand_type) {
+ case DK3_PRNG_OPENSSL: {
+#if DK3_HAVE_OPENSSL_RAND_H
+ if(f_crypto) {
+ if(RAND_bytes(ucptr, (int)sz) == 1) {
+ back = sz;
+ }
+ } else {
+ if(RAND_pseudo_bytes(ucptr, (int)sz) > -1) {
+ back = sz;
+ }
+ }
+#else
+ /* BUG: Not available! */
+#endif
+ } break;
+ case DK3_PRNG_STATE: {
+#if DK3_HAVE_INITSTATE && DK3_HAVE_SETSTATE && DK3_HAVE_RANDOM
+ long lval;
+ size_t position;
+
+ lval = random() >> 8;
+ position = 0;
+ for(i = 0; i < sz; i++) {
+ *(ucptr++) = (unsigned char)(lval & 0x000000FFL);
+ position++;
+ lval = lval >> 8;
+ if(position >= (sizeof(long) - 1)) {
+ lval = random() >> 8;
+ position = 0;
+ }
+ }
+ back = sz;
+#else
+ /* BUG: Not available! */
+#endif
+ } break;
+ case DK3_PRNG_RAND48: {
+#if DK3_HAVE_NRAND48 && DK3_HAVE_LRAND48
+ long lval;
+ size_t position;
+
+ lval = lrand48() >> 8;
+ position = 0;
+ for(i = 0; i < sz; i++) {
+ *(ucptr++) = (unsigned char)(lval & 0x000000FFL);
+ position++;
+ lval = lval >> 8;
+ if(position >= (sizeof(long) - 1)) {
+ lval = lrand48() >> 8;
+ position = 0;
+ }
+ }
+ back = sz;
+#else
+ /* BUG: Not available! */
+#endif
+ } break;
+ default: {
+#if DK3_HAVE_RAND && DK3_HAVE_SRAND
+ for(i = 0; i < sz; i++) {
+ u = rand();
+#if DK3_SIZEOF_INT > 2
+#if DK3_SIZEOF_INT > 4
+ u = u >> 28;
+#else
+ u = u >> 12;
+#endif
+#else
+ u = u >> 4;
+#endif
+ u &= 0x00FFU;
+ *(ucptr++) = (unsigned char)u;
+ }
+ back = sz;
+#else
+ /* BUG: Not available! */
+#endif
+ } break;
+ }
+ }
+ }
+ if(back < sz) {
+ /* ERROR: Failed to obtain enough random bytes! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 177);
+ }
+ return back;
+}
+
+
+size_t
+dk3app_rand_bytes(dk3_app_t *app, void *db, size_t sz)
+{
+ size_t back;
+ back = dk3app_rand_bytes_internal(app, db, sz, 1);
+ return back;
+}
+
+
+size_t
+dk3app_rand_bytes_non_crypto(dk3_app_t *app, void *db, size_t sz)
+{
+ size_t back;
+ back = dk3app_rand_bytes_internal(app, db, sz, 0);
+ return back;
+}
+
+
+
+void
+dk3app_rand_end(dk3_app_t *app)
+{
+#if DK3_HAVE_OPENSSL_RAND_H
+#if DK3_CHAR_SIZE == 1
+ dkChar const *p1 = NULL;
+ dkChar const *p2 = NULL;
+ dkChar const *p3 = NULL;
+ dkChar const *p4 = NULL;
+ dkChar const *p5 = NULL;
+ size_t sz = 0;
+ FILE *fipo = NULL;
+ dkChar fnb[DK3_MAX_PATH];
+#endif
+#endif
+ $? "+ dk3app_rand_end"
+ if((app->f_rand_initialized) && (app->f_rand_success)) { $? ". init"
+ switch(app->rand_type) {
+ case DK3_PRNG_OPENSSL: {
+#if DK3_HAVE_OPENSSL_RAND_H
+#if DK3_CHAR_SIZE == 1
+ p1 = dk3app_get_homedir(app);
+ p2 = dk3app_not_localized(20);
+ p3 = dk3app_not_localized(41);
+ p4 = dk3app_not_localized(5);
+ p5 = dk3app_get_appname(app);
+ if((p1) && (p2) && (p3) && (p4) && (p5)) {
+ sz = dk3str_len(p1);
+ sz += dk3str_len(p2);
+ sz += dk3str_len(p3);
+ sz += dk3str_len(p4);
+ sz += dk3str_len(p5);
+ if(sz < DK3_SIZEOF(fnb,dkChar)) {
+ dk3str_cpy_not_overlapped(fnb, p1);
+ dk3str_cat(fnb, p2);
+ dk3str_cat(fnb, p3);
+ dk3str_cat(fnb, p4);
+ dk3str_cat(fnb, p5); $? ". rand seed file = \"%!ds\"", fnb
+ fipo = dk3sf_fopen_app(fnb, dk3app_not_localized(24), app);
+ if(fipo) {
+ fclose(fipo); fipo = NULL;
+#if DK3_ON_WINDOWS
+ /* chmod(fnb, 0600); */
+#else
+#if DK3_HAVE_CHMOD
+ chmod(fnb, 0600);
+#endif
+#endif
+ if(RAND_write_file(fnb) <= 0) {
+ /* Warning: Failed to save random seed. */
+ dk3app_log_i1(app, DK3_LL_ERROR, 193);
+ }
+ }
+ }
+ }
+#endif
+#endif
+ } break;
+ }
+ } else { $? "! not initialized"
+ } $? "- dk3app_rand_end"
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dk3bb.c b/support/dktools/dk3bb.c
new file mode 100644
index 0000000000..31ada4f682
--- /dev/null
+++ b/support/dktools/dk3bb.c
@@ -0,0 +1,223 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3bb.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3bb.c The dk3bb module.
+*/
+
+
+#line 81 "dk3bb.ctr"
+
+#include "dk3all.h"
+#include "dk3bb.h"
+
+
+
+
+
+#line 88 "dk3bb.ctr"
+
+
+
+void
+dk3bb_reset(dk3_bb_t *bb)
+{
+
+
+#line 95 "dk3bb.ctr"
+ if(bb) {
+ bb->xmin = bb->xmax = bb->ymin = bb->ymax = 0.0;
+ bb->xused = bb->yused = 0;
+ }
+
+#line 99 "dk3bb.ctr"
+}
+
+
+
+void
+dk3bb_add_x(dk3_bb_t *bb, double x)
+{
+
+
+#line 107 "dk3bb.ctr"
+ if(bb) {
+ if(bb->xused) {
+ if(x < bb->xmin) { bb->xmin = x; }
+ if(x > bb->xmax) { bb->xmax = x; }
+ } else {
+ bb->xmin = x; bb->xmax = x; bb->xused = 1;
+ }
+
+#line 114 "dk3bb.ctr"
+ }
+
+#line 115 "dk3bb.ctr"
+}
+
+
+
+void
+dk3bb_add_y(dk3_bb_t *bb, double y)
+{
+
+
+#line 123 "dk3bb.ctr"
+ if(bb) {
+ if(bb->yused) {
+ if(y < bb->ymin) { bb->ymin = y; }
+ if(y > bb->ymax) { bb->ymax = y; }
+ } else {
+ bb->ymin = y; bb->ymax = y; bb->yused = 1;
+ }
+
+#line 130 "dk3bb.ctr"
+ }
+
+#line 131 "dk3bb.ctr"
+}
+
+
+
+int
+dk3bb_add_x_width(dk3_bb_t *bb, double x, double r)
+{
+ double x1; /* Minimum x value. */
+ double x2; /* Maximum x value. */
+ int ec = 0; /* Error code for mathematical operations. */
+ int back = 0;
+
+
+#line 143 "dk3bb.ctr"
+ if(bb) {
+ x1 = dk3ma_d_sub_ok(x, r, &ec);
+ x2 = dk3ma_d_add_ok(x, r, &ec);
+ if(0 == ec) {
+ back = 1;
+ dk3bb_add_x(bb, x1);
+ dk3bb_add_x(bb, x2);
+ }
+ }
+
+#line 152 "dk3bb.ctr"
+ return back;
+}
+
+
+
+int
+dk3bb_add_y_width(dk3_bb_t *bb, double y, double r)
+{
+ double y1; /* Minimum y value. */
+ double y2; /* Maximum y value. */
+ int ec = 0; /* Error code for mathematical operations. */
+ int back = 0;
+
+
+#line 165 "dk3bb.ctr"
+ y1 = dk3ma_d_sub_ok(y, r, &ec);
+ y2 = dk3ma_d_add_ok(y, r, &ec);
+ if(0 == ec) {
+ back = 1;
+ dk3bb_add_y(bb, y1);
+ dk3bb_add_y(bb, y2);
+ }
+
+#line 172 "dk3bb.ctr"
+ return back;
+}
+
+
+
+void
+dk3bb_point(dk3_bb_t *bb, double x, double y)
+{
+
+
+#line 181 "dk3bb.ctr"
+ if(bb) {
+ dk3bb_add_x(bb, x);
+ dk3bb_add_y(bb, y);
+ }
+
+#line 185 "dk3bb.ctr"
+}
+
+
+
+int
+dk3bb_point_width(dk3_bb_t *bb, double x, double y, double r)
+{
+
+ int back = 0;
+
+
+#line 195 "dk3bb.ctr"
+ if(bb) {
+ if(dk3bb_add_x_width(bb, x, r)) {
+ if(dk3bb_add_y_width(bb, y, r)) {
+ back = 1;
+ }
+ }
+ }
+
+#line 202 "dk3bb.ctr"
+ return back;
+}
+
+
+
+void
+dk3bb_merge(dk3_bb_t *dbb, dk3_bb_t const *sbb)
+{
+
+
+#line 211 "dk3bb.ctr"
+ if((dbb) && (sbb)) {
+ if(sbb->xused) {
+ dk3bb_add_x(dbb, sbb->xmin);
+ dk3bb_add_x(dbb, sbb->xmax);
+ }
+ if(sbb->yused) {
+ dk3bb_add_y(dbb, sbb->ymin);
+ dk3bb_add_y(dbb, sbb->ymax);
+ }
+ }
+
+
+#line 222 "dk3bb.ctr"
+}
+
+
+
diff --git a/support/dktools/dk3bb.ctr b/support/dktools/dk3bb.ctr
new file mode 100644
index 0000000000..9316c415ad
--- /dev/null
+++ b/support/dktools/dk3bb.ctr
@@ -0,0 +1,225 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Reset a bounding box.
+ @param bb Bounding box to reset.
+*/
+void
+dk3bb_reset(dk3_bb_t *bb);
+
+/** Add x value to bounding box.
+ @param bb Bounding box to modify.
+ @param x Value to add.
+*/
+void
+dk3bb_add_x(dk3_bb_t *bb, double x);
+
+/** Add y value to bounding box.
+ @param bb Bounding box to modify.
+ @param y Value to add.
+*/
+void
+dk3bb_add_y(dk3_bb_t *bb, double y);
+
+/** Add x value with radius.
+ @param bb Bounding box to modify.
+ @param x X value to add.
+ @param r Radius.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3bb_add_x_width(dk3_bb_t *bb, double x, double r);
+
+/** Add y value with radius.
+ @param bb Bounding box to modify.
+ @param y Y value to add.
+ @param r Radius.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3bb_add_y_width(dk3_bb_t *bb, double y, double r);
+
+/** Add point.
+ @param bb Bouding box to grow.
+ @param x X value of point.
+ @param y Y value of point.
+*/
+void
+dk3bb_point(dk3_bb_t *bb, double x, double y);
+
+/** Add point with radius.
+ @param bb
+ @param x
+ @param y
+ @param r
+ @return 1 on success, 0 on error (math overflow).
+*/
+int
+dk3bb_point_width(dk3_bb_t *bb, double x, double y, double r);
+
+/** Merge two bounding boxes.
+ @param dbb Destination bounding box.
+ @param sbb Source bounding box to merge into dbb.
+*/
+void
+dk3bb_merge(dk3_bb_t *dbb, dk3_bb_t const *sbb);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk3all.h"
+#include "dk3bb.h"
+
+
+
+$!trace-include
+
+
+
+void
+dk3bb_reset(dk3_bb_t *bb)
+{
+ $? "+ dk3bb_reset"
+ if(bb) {
+ bb->xmin = bb->xmax = bb->ymin = bb->ymax = 0.0;
+ bb->xused = bb->yused = 0;
+ } $? "- dk3bb_reset"
+}
+
+
+
+void
+dk3bb_add_x(dk3_bb_t *bb, double x)
+{
+ $? "+ dk3bb_add_x x=%lg", x
+ if(bb) {
+ if(bb->xused) {
+ if(x < bb->xmin) { bb->xmin = x; }
+ if(x > bb->xmax) { bb->xmax = x; }
+ } else {
+ bb->xmin = x; bb->xmax = x; bb->xused = 1;
+ } $? ". NOW xmin=%lg xmax=%lg", bb->xmin, bb->xmax
+ } $? "- dk3bb_add_x"
+}
+
+
+
+void
+dk3bb_add_y(dk3_bb_t *bb, double y)
+{
+ $? "+ dk3bb_add_y y=%lg", y
+ if(bb) {
+ if(bb->yused) {
+ if(y < bb->ymin) { bb->ymin = y; }
+ if(y > bb->ymax) { bb->ymax = y; }
+ } else {
+ bb->ymin = y; bb->ymax = y; bb->yused = 1;
+ } $? ". NOW ymin=%lg ymax=%lg", bb->ymin, bb->ymax
+ } $? "- dk3bb_add_y"
+}
+
+
+
+int
+dk3bb_add_x_width(dk3_bb_t *bb, double x, double r)
+{
+ double x1; /* Minimum x value. */
+ double x2; /* Maximum x value. */
+ int ec = 0; /* Error code for mathematical operations. */
+ int back = 0;
+ $? "+ dk3bb_add_x_width x=%lg r=%lg", x, r
+ if(bb) {
+ x1 = dk3ma_d_sub_ok(x, r, &ec);
+ x2 = dk3ma_d_add_ok(x, r, &ec);
+ if(0 == ec) {
+ back = 1;
+ dk3bb_add_x(bb, x1);
+ dk3bb_add_x(bb, x2);
+ }
+ } $? "- dk3bb_add_x_width %d", back
+ return back;
+}
+
+
+
+int
+dk3bb_add_y_width(dk3_bb_t *bb, double y, double r)
+{
+ double y1; /* Minimum y value. */
+ double y2; /* Maximum y value. */
+ int ec = 0; /* Error code for mathematical operations. */
+ int back = 0;
+ $? "+ dk3bb_add_y_width y=%lg r=%lg", y, r
+ y1 = dk3ma_d_sub_ok(y, r, &ec);
+ y2 = dk3ma_d_add_ok(y, r, &ec);
+ if(0 == ec) {
+ back = 1;
+ dk3bb_add_y(bb, y1);
+ dk3bb_add_y(bb, y2);
+ } $? "- dk3bb_add_y_width %d", back
+ return back;
+}
+
+
+
+void
+dk3bb_point(dk3_bb_t *bb, double x, double y)
+{
+ $? "+ dk3bb_point x=%lg y=%lg", x ,y
+ if(bb) {
+ dk3bb_add_x(bb, x);
+ dk3bb_add_y(bb, y);
+ } $? "- dk3bb_point"
+}
+
+
+
+int
+dk3bb_point_width(dk3_bb_t *bb, double x, double y, double r)
+{
+
+ int back = 0;
+ $? "+ dk3bb_point_width x=%lg y=%lg r=%lg", x, y, r
+ if(bb) {
+ if(dk3bb_add_x_width(bb, x, r)) {
+ if(dk3bb_add_y_width(bb, y, r)) {
+ back = 1;
+ }
+ }
+ } $? "- dk3bb_point_width %d", back
+ return back;
+}
+
+
+
+void
+dk3bb_merge(dk3_bb_t *dbb, dk3_bb_t const *sbb)
+{
+ $? "+ dk3bb_merge"
+ if((dbb) && (sbb)) {
+ if(sbb->xused) {
+ dk3bb_add_x(dbb, sbb->xmin);
+ dk3bb_add_x(dbb, sbb->xmax);
+ }
+ if(sbb->yused) {
+ dk3bb_add_y(dbb, sbb->ymin);
+ dk3bb_add_y(dbb, sbb->ymax);
+ }
+ }
+ $? "- dk3bb_merge"
+}
+
+
+
diff --git a/support/dktools/dk3bb.h b/support/dktools/dk3bb.h
new file mode 100644
index 0000000000..bae6f7c485
--- /dev/null
+++ b/support/dktools/dk3bb.h
@@ -0,0 +1,118 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3bb.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3bb.h Header file for the dk3bb module.
+*/
+
+#ifndef DK3BB_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3BB_H_INCLUDED 1
+
+
+#line 8 "dk3bb.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Reset a bounding box.
+ @param bb Bounding box to reset.
+*/
+void
+dk3bb_reset(dk3_bb_t *bb);
+
+/** Add x value to bounding box.
+ @param bb Bounding box to modify.
+ @param x Value to add.
+*/
+void
+dk3bb_add_x(dk3_bb_t *bb, double x);
+
+/** Add y value to bounding box.
+ @param bb Bounding box to modify.
+ @param y Value to add.
+*/
+void
+dk3bb_add_y(dk3_bb_t *bb, double y);
+
+/** Add x value with radius.
+ @param bb Bounding box to modify.
+ @param x X value to add.
+ @param r Radius.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3bb_add_x_width(dk3_bb_t *bb, double x, double r);
+
+/** Add y value with radius.
+ @param bb Bounding box to modify.
+ @param y Y value to add.
+ @param r Radius.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3bb_add_y_width(dk3_bb_t *bb, double y, double r);
+
+/** Add point.
+ @param bb Bouding box to grow.
+ @param x X value of point.
+ @param y Y value of point.
+*/
+void
+dk3bb_point(dk3_bb_t *bb, double x, double y);
+
+/** Add point with radius.
+ @param bb
+ @param x
+ @param y
+ @param r
+ @return 1 on success, 0 on error (math overflow).
+*/
+int
+dk3bb_point_width(dk3_bb_t *bb, double x, double y, double r);
+
+/** Merge two bounding boxes.
+ @param dbb Destination bounding box.
+ @param sbb Source bounding box to merge into dbb.
+*/
+void
+dk3bb_merge(dk3_bb_t *dbb, dk3_bb_t const *sbb);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk3bezcu.c b/support/dktools/dk3bezcu.c
new file mode 100644
index 0000000000..ecd25a27a9
--- /dev/null
+++ b/support/dktools/dk3bezcu.c
@@ -0,0 +1,455 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3bezcu.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3bezcu.c The dk3bezcu module.
+*/
+
+
+#line 62 "dk3bezcu.ctr"
+
+#include "dk3all.h"
+#include "dk3bb.h"
+#include "dk3bezcu.h"
+
+
+
+
+
+#line 70 "dk3bezcu.ctr"
+
+
+
+double
+dk3bezier_value(
+ double x0, double xp, double xm, double x1, double t, int *ec
+)
+{
+ int mec = 0;
+ double back;
+
+
+#line 81 "dk3bezcu.ctr"
+ back = dk3ma_d_add_ok(
+ x0,
+ dk3ma_d_mul_ok(
+ t,
+ dk3ma_d_add_ok(
+ dk3ma_d_sub_ok(
+ dk3ma_d_mul_ok(3.0, xp, &mec),
+ dk3ma_d_mul_ok(3.0, x0, &mec),
+ &mec
+ ),
+ dk3ma_d_mul_ok(
+ t,
+ dk3ma_d_add_ok(
+ dk3ma_d_add_ok(
+ dk3ma_d_sub_ok(
+ dk3ma_d_mul_ok(3.0, xm, &mec),
+ dk3ma_d_mul_ok(6.0, xp, &mec),
+ &mec
+ ),
+ dk3ma_d_mul_ok(3.0, x0, &mec),
+ &mec
+ ),
+ dk3ma_d_mul_ok(
+ t,
+ dk3ma_d_add_ok(
+ dk3ma_d_sub_ok(
+ dk3ma_d_mul_ok(3.0, xp, &mec),
+ dk3ma_d_mul_ok(3.0, xm, &mec),
+ &mec
+ ),
+ dk3ma_d_sub_ok(x1, x0, &mec),
+ &mec
+ ),
+ &mec
+ ),
+ &mec
+ ),
+ &mec
+ ),
+ &mec
+ ),
+ &mec
+ ),
+ &mec
+ );
+
+#line 126 "dk3bezcu.ctr"
+ if(mec) {
+ if(ec) { *ec = mec; }
+ }
+
+
+#line 130 "dk3bezcu.ctr"
+ return back;
+}
+
+
+
+/** Apply one t value to a bounding box.
+ @param bb Bounding box to modify.
+ @param x0 Start value.
+ @param xp Control value for start.
+ @param xm Control value for end.
+ @param x1 End value.
+ @param ra Point radius (half line width).
+ @param tv The t value.
+ @param isy Flag: Y direction.
+ @param ec Pointer to error code variable, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bezier_t_dimension(
+ dk3_bb_t *bb,
+ double x0,
+ double xp,
+ double xm,
+ double x1,
+ double ra,
+ double tv,
+ int isy,
+ int *ec
+)
+{
+ double val;
+ int back = 1;
+ int mec = 0;
+
+
+#line 165 "dk3bezcu.ctr"
+ if(tv > 0.0) {
+ if(tv < 1.0) {
+ val = dk3bezier_value(x0, xp, xm, x1, tv, &mec);
+
+#line 168 "dk3bezcu.ctr"
+ if(isy) {
+ if(!dk3bb_add_y_width(bb, val, ra)) { back = 0; }
+ } else {
+ if(!dk3bb_add_x_width(bb, val, ra)) { back = 0; }
+ }
+ }
+ }
+ if(mec) {
+
+#line 176 "dk3bezcu.ctr"
+ back = 0;
+ if(ec) { *ec = mec; }
+ }
+
+#line 179 "dk3bezcu.ctr"
+ return back;
+}
+
+
+
+#if VERSION_BEFORE_20121218
+/** Apply one dimension to a bounding box.
+ @param bb Bounding box to modify.
+ @param x0 Start value.
+ @param xp Control value for start.
+ @param xm Control value for end.
+ @param x1 End value.
+ @param ra Point radius (half line width).
+ @param isy Flag: Y direction.
+ @param ec Pointer to error code variable, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bezier_bb_dimension(
+ dk3_bb_t *bb,
+ double x0,
+ double xp,
+ double xm,
+ double x1,
+ double ra,
+ int isy,
+ int *ec
+)
+{
+ double n;
+ double z1;
+ double z2;
+ double t;
+ int back = 1;
+ int mec = 0;
+
+
+#line 216 "dk3bezcu.ctr"
+ n = dk3ma_d_add_ok(
+ dk3ma_d_sub_ok(x1, x0, &mec),
+ dk3ma_d_mul_ok(3.0, dk3ma_d_sub_ok(xp, xm, &mec), &mec),
+ &mec
+ );
+
+#line 221 "dk3bezcu.ctr"
+ z1 = dk3ma_d_sub_ok(
+ dk3ma_d_sub_ok(dk3ma_d_mul_ok(2.0, xp, &mec), xm, &mec),
+ x0,
+ &mec
+ );
+
+#line 226 "dk3bezcu.ctr"
+ z2 = dk3ma_d_add_ok(
+ dk3ma_d_sub_ok(
+ xm,
+ dk3ma_d_mul_ok(2.0, xp, &mec),
+ &mec
+ ),
+ x0,
+ &mec
+ );
+
+#line 235 "dk3bezcu.ctr"
+ z2 = dk3ma_d_mul_ok(z2, z2, &mec);
+ z2 = dk3ma_d_sub_ok(
+ z2,
+ dk3ma_d_mul_ok(
+ dk3ma_d_sub_ok(xp, x0, &mec),
+ n,
+ &mec
+ ),
+ &mec
+ );
+
+#line 245 "dk3bezcu.ctr"
+ if(z2 >= 0.0) {
+ z2 = sqrt(z2);
+
+#line 247 "dk3bezcu.ctr"
+ t = dk3ma_d_div_ok(
+ dk3ma_d_add_ok(z1, z2, &mec),
+ n,
+ &mec
+ );
+
+#line 252 "dk3bezcu.ctr"
+ if(!dk3bezier_t_dimension(bb, x0, xp, xm, x1, ra, t, isy, &mec)) {
+ back = 0;
+ }
+
+#line 255 "dk3bezcu.ctr"
+ t = dk3ma_d_div_ok(
+ dk3ma_d_sub_ok(z1, z2, &mec),
+ n,
+ &mec
+ );
+
+#line 260 "dk3bezcu.ctr"
+ if(!dk3bezier_t_dimension(bb, x0, xp, xm, x1, ra, t, isy, &mec)) {
+ back = 0;
+ }
+
+#line 263 "dk3bezcu.ctr"
+ }
+ if(mec) {
+
+#line 265 "dk3bezcu.ctr"
+ back = 0;
+ if(ec) { *ec = mec; }
+ }
+
+#line 268 "dk3bezcu.ctr"
+ return back;
+}
+#else
+/** Apply one dimension to a bounding box.
+ @param bb Bounding box to modify.
+ @param x0 Start value.
+ @param xp Control value for start.
+ @param xm Control value for end.
+ @param x1 End value.
+ @param ra Point radius (half line width).
+ @param isy Flag: Y direction.
+ @param ec Pointer to error code variable, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bezier_bb_dimension(
+ dk3_bb_t *bb,
+ double x0,
+ double xp,
+ double xm,
+ double x1,
+ double ra,
+ int isy,
+ int *ec
+)
+{
+ double n;
+ double z1;
+ double z2;
+ double t;
+ int back = 1;
+ int mec = 0;
+ int testmec;
+
+
+#line 303 "dk3bezcu.ctr"
+ n = dk3ma_d_add_ok(
+ dk3ma_d_sub_ok(x1, x0, &mec),
+ dk3ma_d_mul_ok(3.0, dk3ma_d_sub_ok(xp, xm, &mec), &mec),
+ &mec
+ );
+
+#line 308 "dk3bezcu.ctr"
+ z1 = dk3ma_d_sub_ok(
+ dk3ma_d_sub_ok(dk3ma_d_mul_ok(2.0, xp, &mec), xm, &mec),
+ x0,
+ &mec
+ );
+
+#line 313 "dk3bezcu.ctr"
+ z2 = dk3ma_d_add_ok(
+ dk3ma_d_sub_ok(
+ xm,
+ dk3ma_d_mul_ok(2.0, xp, &mec),
+ &mec
+ ),
+ x0,
+ &mec
+ );
+
+#line 322 "dk3bezcu.ctr"
+ z2 = dk3ma_d_mul_ok(z2, z2, &mec);
+ z2 = dk3ma_d_sub_ok(
+ z2,
+ dk3ma_d_mul_ok(
+ dk3ma_d_sub_ok(xp, x0, &mec),
+ n,
+ &mec
+ ),
+ &mec
+ );
+
+#line 332 "dk3bezcu.ctr"
+ if(z2 >= 0.0) {
+ z2 = sqrt(z2);
+
+#line 334 "dk3bezcu.ctr"
+ testmec = 0;
+ t = dk3ma_d_div_ok(
+ dk3ma_d_add_ok(z1, z2, &mec),
+ n,
+ &testmec
+ );
+
+#line 340 "dk3bezcu.ctr"
+ if(0 == testmec) {
+ if(!dk3bezier_t_dimension(bb, x0, xp, xm, x1, ra, t, isy, &mec)) {
+ back = 0;
+ }
+
+#line 344 "dk3bezcu.ctr"
+ }
+ testmec = 0;
+ t = dk3ma_d_div_ok(
+ dk3ma_d_sub_ok(z1, z2, &mec),
+ n,
+ &testmec
+ );
+
+#line 351 "dk3bezcu.ctr"
+ if(0 == testmec) {
+ if(!dk3bezier_t_dimension(bb, x0, xp, xm, x1, ra, t, isy, &mec)) {
+ back = 0;
+ }
+
+#line 355 "dk3bezcu.ctr"
+ }
+ }
+ if(mec) {
+
+#line 358 "dk3bezcu.ctr"
+ back = 0;
+ if(ec) { *ec = mec; }
+ }
+
+#line 361 "dk3bezcu.ctr"
+ return back;
+}
+#endif
+
+
+int
+dk3bezier_bb(
+ dk3_bb_t *bb,
+ double x0,
+ double y0,
+ double xp,
+ double yp,
+ double xm,
+ double ym,
+ double x1,
+ double y1,
+ double ra,
+ int *ec
+)
+{
+ int back = 0;
+ int mec = 0;
+
+
+#line 384 "dk3bezcu.ctr"
+ if(bb) {
+ back = 1;
+ if(!dk3bb_point_width(bb, x0, y0, ra)) {
+ back = 0;
+ }
+ if(!dk3bb_point_width(bb, x1, y1, ra)) {
+ back = 0;
+ }
+ if(!dk3bezier_bb_dimension(bb, x0, xp, xm, x1, ra, 0, &mec)) {
+ back = 0;
+ }
+ if(!dk3bezier_bb_dimension(bb, y0, yp, ym, y1, ra, 1, &mec)) {
+ back = 0;
+ }
+ if(mec) {
+ back = 0;
+ if(ec) { *ec = mec; }
+ }
+ } else {
+ if(ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+
+#line 405 "dk3bezcu.ctr"
+ return back;
+}
+
+
diff --git a/support/dktools/dk3bezcu.ctr b/support/dktools/dk3bezcu.ctr
new file mode 100644
index 0000000000..f5ff1b6955
--- /dev/null
+++ b/support/dktools/dk3bezcu.ctr
@@ -0,0 +1,408 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Bezier curve value calculation.
+ @param x0 Start point value.
+ @param xp Value in control point near start.
+ @param xm Value in control point near end.
+ @param x1 End point.
+ @param t The t parameter.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Calculation result.
+*/
+double
+dk3bezier_value(
+ double x0, double xp, double xm, double x1, double t, int *ec
+);
+
+/** Add Bezier curve segment to bounding box.
+ @param bb Bounding box to modify.
+ @param x0 Start point x coordinate.
+ @param y0 Start point y coordinate.
+ @param xp Control point near start x coordinate.
+ @param yp Control point near start y coordinate.
+ @param xm Control point near end x coordinate.
+ @param ym Control point near end y coordinate.
+ @param x1 End point x coordinate.
+ @param y1 End point y coordinate.
+ @param ra Half line width.
+ @param ec Pointer to error code variable, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3bezier_bb(
+ dk3_bb_t *bb,
+ double x0,
+ double y0,
+ double xp,
+ double yp,
+ double xm,
+ double ym,
+ double x1,
+ double y1,
+ double ra,
+ int *ec
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk3all.h"
+#include "dk3bb.h"
+#include "dk3bezcu.h"
+
+
+
+$!trace-include
+
+
+
+double
+dk3bezier_value(
+ double x0, double xp, double xm, double x1, double t, int *ec
+)
+{
+ int mec = 0;
+ double back;
+ $? "+ dk3bezier_value %lg %lg %lg %lg %lg", x0, xp, xm, x1, t
+ back = dk3ma_d_add_ok(
+ x0,
+ dk3ma_d_mul_ok(
+ t,
+ dk3ma_d_add_ok(
+ dk3ma_d_sub_ok(
+ dk3ma_d_mul_ok(3.0, xp, &mec),
+ dk3ma_d_mul_ok(3.0, x0, &mec),
+ &mec
+ ),
+ dk3ma_d_mul_ok(
+ t,
+ dk3ma_d_add_ok(
+ dk3ma_d_add_ok(
+ dk3ma_d_sub_ok(
+ dk3ma_d_mul_ok(3.0, xm, &mec),
+ dk3ma_d_mul_ok(6.0, xp, &mec),
+ &mec
+ ),
+ dk3ma_d_mul_ok(3.0, x0, &mec),
+ &mec
+ ),
+ dk3ma_d_mul_ok(
+ t,
+ dk3ma_d_add_ok(
+ dk3ma_d_sub_ok(
+ dk3ma_d_mul_ok(3.0, xp, &mec),
+ dk3ma_d_mul_ok(3.0, xm, &mec),
+ &mec
+ ),
+ dk3ma_d_sub_ok(x1, x0, &mec),
+ &mec
+ ),
+ &mec
+ ),
+ &mec
+ ),
+ &mec
+ ),
+ &mec
+ ),
+ &mec
+ ),
+ &mec
+ ); $? ". mec = %d", mec
+ if(mec) {
+ if(ec) { *ec = mec; }
+ }
+ $? "- dk3bezier_value %lg", back
+ return back;
+}
+
+
+
+/** Apply one t value to a bounding box.
+ @param bb Bounding box to modify.
+ @param x0 Start value.
+ @param xp Control value for start.
+ @param xm Control value for end.
+ @param x1 End value.
+ @param ra Point radius (half line width).
+ @param tv The t value.
+ @param isy Flag: Y direction.
+ @param ec Pointer to error code variable, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bezier_t_dimension(
+ dk3_bb_t *bb,
+ double x0,
+ double xp,
+ double xm,
+ double x1,
+ double ra,
+ double tv,
+ int isy,
+ int *ec
+)
+{
+ double val;
+ int back = 1;
+ int mec = 0;
+ $? "+ dk3bezier_t_dimension %lg %lg %lg %lg y=%d", x0, xp, xm, x1, isy
+ if(tv > 0.0) {
+ if(tv < 1.0) {
+ val = dk3bezier_value(x0, xp, xm, x1, tv, &mec); $? ". mec = %d", mec
+ if(isy) {
+ if(!dk3bb_add_y_width(bb, val, ra)) { back = 0; }
+ } else {
+ if(!dk3bb_add_x_width(bb, val, ra)) { back = 0; }
+ }
+ }
+ }
+ if(mec) { $? "! mec"
+ back = 0;
+ if(ec) { *ec = mec; }
+ } $? "- dk3bezier_t_dimension %d", back
+ return back;
+}
+
+
+
+#if VERSION_BEFORE_20121218
+/** Apply one dimension to a bounding box.
+ @param bb Bounding box to modify.
+ @param x0 Start value.
+ @param xp Control value for start.
+ @param xm Control value for end.
+ @param x1 End value.
+ @param ra Point radius (half line width).
+ @param isy Flag: Y direction.
+ @param ec Pointer to error code variable, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bezier_bb_dimension(
+ dk3_bb_t *bb,
+ double x0,
+ double xp,
+ double xm,
+ double x1,
+ double ra,
+ int isy,
+ int *ec
+)
+{
+ double n;
+ double z1;
+ double z2;
+ double t;
+ int back = 1;
+ int mec = 0;
+ $? "+ dk3bezier_bb_dimension %lg %lg %lg %lg y=%d", x0, xp, xm, x1, isy
+ n = dk3ma_d_add_ok(
+ dk3ma_d_sub_ok(x1, x0, &mec),
+ dk3ma_d_mul_ok(3.0, dk3ma_d_sub_ok(xp, xm, &mec), &mec),
+ &mec
+ ); $? ". mec = %d", mec
+ z1 = dk3ma_d_sub_ok(
+ dk3ma_d_sub_ok(dk3ma_d_mul_ok(2.0, xp, &mec), xm, &mec),
+ x0,
+ &mec
+ ); $? ". mec = %d", mec
+ z2 = dk3ma_d_add_ok(
+ dk3ma_d_sub_ok(
+ xm,
+ dk3ma_d_mul_ok(2.0, xp, &mec),
+ &mec
+ ),
+ x0,
+ &mec
+ ); $? ". mec = %d", mec
+ z2 = dk3ma_d_mul_ok(z2, z2, &mec);
+ z2 = dk3ma_d_sub_ok(
+ z2,
+ dk3ma_d_mul_ok(
+ dk3ma_d_sub_ok(xp, x0, &mec),
+ n,
+ &mec
+ ),
+ &mec
+ ); $? ". mec = %d", mec
+ if(z2 >= 0.0) {
+ z2 = sqrt(z2); $? ". z1 = %lg z2 = %lg", z1, z2
+ t = dk3ma_d_div_ok(
+ dk3ma_d_add_ok(z1, z2, &mec),
+ n,
+ &mec
+ ); $? ". mec = %d", mec
+ if(!dk3bezier_t_dimension(bb, x0, xp, xm, x1, ra, t, isy, &mec)) {
+ back = 0;
+ } $? ". mec = %d", mec
+ t = dk3ma_d_div_ok(
+ dk3ma_d_sub_ok(z1, z2, &mec),
+ n,
+ &mec
+ ); $? ". mec = %d", mec
+ if(!dk3bezier_t_dimension(bb, x0, xp, xm, x1, ra, t, isy, &mec)) {
+ back = 0;
+ } $? ". mec = %d", mec
+ }
+ if(mec) { $? "! math error"
+ back = 0;
+ if(ec) { *ec = mec; }
+ } $? "- dk3bezier_bb_dimension %d", back
+ return back;
+}
+#else
+/** Apply one dimension to a bounding box.
+ @param bb Bounding box to modify.
+ @param x0 Start value.
+ @param xp Control value for start.
+ @param xm Control value for end.
+ @param x1 End value.
+ @param ra Point radius (half line width).
+ @param isy Flag: Y direction.
+ @param ec Pointer to error code variable, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bezier_bb_dimension(
+ dk3_bb_t *bb,
+ double x0,
+ double xp,
+ double xm,
+ double x1,
+ double ra,
+ int isy,
+ int *ec
+)
+{
+ double n;
+ double z1;
+ double z2;
+ double t;
+ int back = 1;
+ int mec = 0;
+ int testmec;
+ $? "+ dk3bezier_bb_dimension %lg %lg %lg %lg y=%d", x0, xp, xm, x1, isy
+ n = dk3ma_d_add_ok(
+ dk3ma_d_sub_ok(x1, x0, &mec),
+ dk3ma_d_mul_ok(3.0, dk3ma_d_sub_ok(xp, xm, &mec), &mec),
+ &mec
+ ); $? ". mec = %d", mec
+ z1 = dk3ma_d_sub_ok(
+ dk3ma_d_sub_ok(dk3ma_d_mul_ok(2.0, xp, &mec), xm, &mec),
+ x0,
+ &mec
+ ); $? ". mec = %d", mec
+ z2 = dk3ma_d_add_ok(
+ dk3ma_d_sub_ok(
+ xm,
+ dk3ma_d_mul_ok(2.0, xp, &mec),
+ &mec
+ ),
+ x0,
+ &mec
+ ); $? ". mec = %d", mec
+ z2 = dk3ma_d_mul_ok(z2, z2, &mec);
+ z2 = dk3ma_d_sub_ok(
+ z2,
+ dk3ma_d_mul_ok(
+ dk3ma_d_sub_ok(xp, x0, &mec),
+ n,
+ &mec
+ ),
+ &mec
+ ); $? ". mec = %d", mec
+ if(z2 >= 0.0) {
+ z2 = sqrt(z2); $? ". z1 = %lg z2 = %lg", z1, z2
+ testmec = 0;
+ t = dk3ma_d_div_ok(
+ dk3ma_d_add_ok(z1, z2, &mec),
+ n,
+ &testmec
+ ); $? ". mec = %d", mec
+ if(0 == testmec) {
+ if(!dk3bezier_t_dimension(bb, x0, xp, xm, x1, ra, t, isy, &mec)) {
+ back = 0;
+ } $? ". mec = %d", mec
+ }
+ testmec = 0;
+ t = dk3ma_d_div_ok(
+ dk3ma_d_sub_ok(z1, z2, &mec),
+ n,
+ &testmec
+ ); $? ". mec = %d", mec
+ if(0 == testmec) {
+ if(!dk3bezier_t_dimension(bb, x0, xp, xm, x1, ra, t, isy, &mec)) {
+ back = 0;
+ } $? ". mec = %d", mec
+ }
+ }
+ if(mec) { $? "! math error"
+ back = 0;
+ if(ec) { *ec = mec; }
+ } $? "- dk3bezier_bb_dimension %d", back
+ return back;
+}
+#endif
+
+
+int
+dk3bezier_bb(
+ dk3_bb_t *bb,
+ double x0,
+ double y0,
+ double xp,
+ double yp,
+ double xm,
+ double ym,
+ double x1,
+ double y1,
+ double ra,
+ int *ec
+)
+{
+ int back = 0;
+ int mec = 0;
+ $? "+ dk3bezier_bb %lg %lg %lg %lg %lg %lg %lg %lg", x0, y0, xp, yp, xm, ym, x1, y1
+ if(bb) {
+ back = 1;
+ if(!dk3bb_point_width(bb, x0, y0, ra)) {
+ back = 0;
+ }
+ if(!dk3bb_point_width(bb, x1, y1, ra)) {
+ back = 0;
+ }
+ if(!dk3bezier_bb_dimension(bb, x0, xp, xm, x1, ra, 0, &mec)) {
+ back = 0;
+ }
+ if(!dk3bezier_bb_dimension(bb, y0, yp, ym, y1, ra, 1, &mec)) {
+ back = 0;
+ }
+ if(mec) {
+ back = 0;
+ if(ec) { *ec = mec; }
+ }
+ } else {
+ if(ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ } $? "- dk3bezier_bb %d", back
+ return back;
+}
+
+
diff --git a/support/dktools/dk3bezcu.h b/support/dktools/dk3bezcu.h
new file mode 100644
index 0000000000..cc8ebdb8eb
--- /dev/null
+++ b/support/dktools/dk3bezcu.h
@@ -0,0 +1,98 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3bezcu.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3bezcu.h Header file for the dk3bezcu module.
+*/
+
+#ifndef DK3BEZCU_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3BEZCU_H_INCLUDED 1
+
+
+#line 9 "dk3bezcu.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Bezier curve value calculation.
+ @param x0 Start point value.
+ @param xp Value in control point near start.
+ @param xm Value in control point near end.
+ @param x1 End point.
+ @param t The t parameter.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Calculation result.
+*/
+double
+dk3bezier_value(
+ double x0, double xp, double xm, double x1, double t, int *ec
+);
+
+/** Add Bezier curve segment to bounding box.
+ @param bb Bounding box to modify.
+ @param x0 Start point x coordinate.
+ @param y0 Start point y coordinate.
+ @param xp Control point near start x coordinate.
+ @param yp Control point near start y coordinate.
+ @param xm Control point near end x coordinate.
+ @param ym Control point near end y coordinate.
+ @param x1 End point x coordinate.
+ @param y1 End point y coordinate.
+ @param ra Half line width.
+ @param ec Pointer to error code variable, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3bezier_bb(
+ dk3_bb_t *bb,
+ double x0,
+ double y0,
+ double xp,
+ double yp,
+ double xm,
+ double ym,
+ double x1,
+ double y1,
+ double ra,
+ int *ec
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk3bf.c b/support/dktools/dk3bf.c
new file mode 100644
index 0000000000..409200533e
--- /dev/null
+++ b/support/dktools/dk3bf.c
@@ -0,0 +1,760 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3bf.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3bf.c The dk3bf module.
+*/
+
+
+#line 102 "dk3bf.ctr"
+
+#include "dk3all.h"
+#include "dk3cores.h"
+
+
+
+
+#line 108 "dk3bf.ctr"
+
+
+/** Bit mask to set/retrieve single bits in a byte.
+*/
+static unsigned char const dk3bf_bits_in_byte[] = {
+0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
+};
+
+
+
+/** Bit masks to reset a single bit in a byte
+*/
+static unsigned char const dk3bf_not_in_byte[] = {
+0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0xFE
+};
+
+
+
+/** Keywords used by the module, not localized.
+*/
+static dkChar const * const dk3bf_kw[] = {
+/* 0 */
+dkT("/bitmatrix/expand/cache-friendly"),
+
+/* 1 */
+dkT("/proc/cache/available"),
+
+/* 2 */
+dkT("/proc/cache/percent"),
+
+NULL
+
+
+#line 143 "dk3bf.ctr"
+};
+
+void
+dk3bf_close(dk3_bf_t *b)
+{
+ if(b) {
+ dk3_release(b->data);
+ b->nbits = 0; b->app = NULL;
+ dk3_delete(b);
+ }
+}
+
+
+
+dk3_bf_t *
+dk3bf_open_app(size_t nbits, dk3_app_t *app)
+{
+ dk3_bf_t *back = NULL;
+ size_t sz = 0; /* Number of bytes needed. */
+ if(nbits) {
+ sz = nbits / 8;
+ if(nbits % 8) { sz++; }
+ back = dk3_new_app(dk3_bf_t,1,app);
+ if(back) {
+ back->nbits = nbits; back->data = NULL; back->app = app;
+ back->data = dk3_new_app(unsigned char,sz,app);
+ if(back->data) {
+ dk3mem_res((void *)(back->data), sz);
+ } else {
+ dk3bf_close(back); back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void
+dk3bf_set(dk3_bf_t *b, size_t n, int v)
+{
+ size_t byteno = 0; /* Byte index in data. */
+ size_t inbyte = 0; /* Number of bit within the byte. */
+ if(b) {
+ if(n < b->nbits) {
+ byteno = n / 8; inbyte = n % 8;
+ if(v) {
+ (b->data)[byteno] |= dk3bf_bits_in_byte[inbyte];
+ } else {
+ (b->data)[byteno] &= (~(dk3bf_bits_in_byte[inbyte]));
+ }
+ } else {
+ if(b->app) {
+ /* ERROR: Index out of range. */
+ dk3app_log_i1(b->app, DK3_LL_ERROR, 200);
+ }
+ }
+ }
+}
+
+
+
+int
+dk3bf_get(dk3_bf_t const *b, size_t n)
+{
+ int back = 0;
+ size_t byteno = 0; /* Byte index in data. */
+ size_t inbyte = 0; /* Number of bit within the byte. */
+ if(b) {
+ if(n < b->nbits) {
+ byteno = n / 8; inbyte = n % 8;
+ if(((b->data)[byteno]) & (dk3bf_bits_in_byte[inbyte])) {
+ back = 1;
+ }
+ } else {
+ if(b->app) {
+ /* ERROR: Index out of range. */
+ dk3app_log_i1(b->app, DK3_LL_ERROR, 200);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+#if VERSION_BEFORE_20140605
+
+void
+dk3bm_close(dk3_bm_t *b)
+{
+ size_t i = 0; /* Index of current row to delete. */
+ if(b) {
+ if(b->data) {
+ for(i = 0; i < b->rows; i++) {
+ dk3_release((b->data)[i]);
+ }
+ dk3_delete(b->data);
+ }
+ b->data = NULL; b->app = NULL; b->columns = 0; b->rows = 0;
+ dk3_delete(b);
+ }
+}
+
+
+
+dk3_bm_t *
+dk3bm_open(size_t x, size_t y, dk3_app_t *app)
+{
+ size_t bytes_per_row = 0; /* Number of bytes per row. */
+ size_t i = 0; /* Current row to initialize. */
+ int ok = 0; /* Flag: Success. */
+ dk3_bm_t *back = NULL;
+ if((x) && (y)) {
+ back = dk3_new_app(dk3_bm_t,1,app);
+ if(back) {
+ back->columns = x; back->rows = y; back->app = app;
+ back->data = NULL;
+ bytes_per_row = x / 8;
+ if(x % 8) { bytes_per_row++; }
+ back->data = dk3_new_app(DK3_PUCHAR,y,app);
+ if(back->data) {
+ ok = 1;
+ for(i = 0; i < y; i++) { (back->data)[i] = NULL; }
+ for(i = 0; i < y; i++) {
+ (back->data)[i] = dk3_new_app(unsigned char,bytes_per_row,app);
+ if((back->data)[i]) {
+ dk3mem_res((void *)((back->data)[i]), bytes_per_row);
+ } else {
+ ok = 0;
+ }
+ }
+ if(ok == 0) {
+ dk3bm_close(back); back = NULL;
+ }
+ } else {
+ dk3_delete(back); back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void
+dk3bm_set(dk3_bm_t *b, size_t x, size_t y, int v)
+{
+ unsigned char *pu = NULL; /* Row pointer. */
+ size_t byteno = 0; /* Index of byte in row. */
+ size_t bitno = 0; /* Index of bit within the byte. */
+ if(b) {
+ if((x < b->columns) && (y < b->rows)) {
+ pu = (b->data)[y];
+ byteno = x / 8; bitno = x % 8;
+ if(v) {
+ pu[byteno] |= dk3bf_bits_in_byte[bitno];
+ } else {
+ pu[byteno] &= (~(dk3bf_bits_in_byte[bitno]));
+ }
+ }
+ }
+}
+
+
+
+int
+dk3bm_get(dk3_bm_t const *b, size_t x, size_t y)
+{
+ int back = 0;
+ unsigned char *pu = NULL; /* Row pointer. */
+ size_t byteno = 0; /* Index of byte within the row. */
+ size_t bitno = 0; /* Index of bit within the byte. */
+ if(b) {
+ if((x < b->columns) && (y < b->rows)) {
+ pu = (b->data)[y];
+ byteno = x / 8; bitno = x % 8;
+ if((pu[byteno]) & (dk3bf_bits_in_byte[bitno])) {
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void
+dk3bm_expand(dk3_bm_t *b)
+{
+ int f_change_found = 0; /* Flag: Change found in this pass. */
+ size_t i = 0; /* Source node number. */
+ size_t j = 0; /* Destination node number. */
+ size_t k = 0; /* Intermediate node number. */
+ size_t p = 0; /* Number of current pass. */
+ if(b) {
+ if(b->columns == b->rows) {
+ p = 0;
+ do {
+ f_change_found = 0;
+ for(i = 0; i < b->columns; i++) {
+ for(j = 0; j < b->rows; j++) {
+ if(!dk3bm_get(b, i, j)) {
+ for(k = 0; k < b->columns; k++) {
+ if(dk3bm_get(b, i, k)) {
+ if(dk3bm_get(b, k, j)) {
+ dk3bm_set(b, i, j, 1);
+ f_change_found = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ p++;
+ } while((f_change_found) && (p < b->columns));
+ } else {
+ if(b->app) {
+ /* ERROR: Matrix must be a square! */
+ dk3app_log_i1(b->app, DK3_LL_ERROR, 201);
+ }
+ }
+ }
+}
+
+
+#else
+
+
+
+void
+dk3bm_close(dk3_bm_t *b)
+{
+ size_t i;
+ if (b) {
+ if (b->data) {
+ if (b->columns < b->rows) {
+ for (i = 0; i < b->columns; i++) {
+ dk3_release((b->data)[i]);
+ }
+ } else {
+ for (i = 0; i < b->rows; i++) {
+ dk3_release((b->data)[i]);
+ }
+ }
+ dk3_delete(b->data);
+ }
+ b->data = NULL;
+ b->app = NULL;
+ b->columns = 0;
+ b->rows = 0;
+ b->cachesize = 0;
+ dk3_delete(b);
+ }
+}
+
+
+
+#if VERSION_BEFORE_20140809
+
+/** Find cache size available to this bit matrix expansion.
+ @param app Application structure.
+ @return Cache size if preferences found, 0 otherwise.
+*/
+static
+size_t
+dk3bf_get_cache_size(dk3_app_t *app)
+{
+ dkChar buf[128];
+ unsigned long ul = 0UL;
+ size_t back = 0;
+ int found = 0;
+ int ec = 0;
+
+
+#line 417 "dk3bf.ctr"
+ if (dk3app_get_pref(app, dk3bf_kw[0], buf, DK3_SIZEOF(buf,dkChar))) {
+#if VERSION_BEFORE_20140716
+ if (1 == dk3sf_sscanf3(buf, dkT("%lu"), &ul))
+#else
+ if (0 != dk3ma_ul_from_string(&ul, buf, NULL))
+#endif
+ {
+ back = (size_t)ul;
+ found = 1;
+ if ((unsigned long)back != ul) {
+ back = 0;
+ found = 0;
+ }
+ }
+ }
+ if (!(found)) {
+ if (dk3app_get_pref(app, dk3bf_kw[1], buf, DK3_SIZEOF(buf,dkChar))) {
+#if VERSION_BEFORE_20140716
+ if (1 == dk3sf_sscanf3(buf, dkT("%lu"), &ul))
+#else
+ if (0 != dk3ma_ul_from_string(&ul, buf, NULL))
+#endif
+ {
+ back = (size_t)ul;
+ found = 1;
+ if ((unsigned long)back != ul) {
+ back = 0;
+ found = 0;
+ }
+ if (found) {
+ found = 0;
+ if (dk3app_get_pref(app, dk3bf_kw[2], buf, DK3_SIZEOF(buf,dkChar))) {
+#if VERSION_BEFORE_20140716
+ if (1 == dk3sf_sscanf3(buf, dkT("%lu"), &ul))
+#else
+ if (0 != dk3ma_ul_from_string(&ul, buf, NULL))
+#endif
+ {
+ back = dk3mem_mul_size_t(back, (size_t)ul, &ec) / 100;
+ if (ec) {
+ back = 0;
+ } else {
+ found = 1;
+ }
+ }
+ }
+ if ((back) && (!(found))) {
+ back = back / 4;
+ if (0 < back) { back = 1; }
+ }
+ }
+ }
+ }
+ }
+
+#line 471 "dk3bf.ctr"
+ return back;
+}
+
+#else
+
+/** Find cache size available to this bit matrix expansion.
+ @param app Application structure.
+ @return Cache size if preferences found, 0 otherwise.
+*/
+static
+size_t
+dk3bf_get_cache_size(dk3_app_t *app)
+{
+
+ dkChar buf[128]; /* Preference value text */
+ dk3_um_t um1; /* From preferences */
+ dk3_um_t um2; /* From preferences */
+ size_t back = 0;
+ int ec = 0; /* Error code */
+
+
+#line 491 "dk3bf.ctr"
+ if (dk3app_get_pref(app, dk3bf_kw[0], buf, DK3_SIZEOF(buf,dkChar))) {
+#if VERSION_BEFORE_20140716
+ if (dk3ma_string_to_um(&um1, buf))
+#else
+ if (0 != dk3ma_um_from_string(&um1, buf, NULL))
+#endif
+ {
+#if VERSION_BEFORE_20140716
+ back = dk3ma_um_to_sz(um1, NULL);
+#else
+#if DK3_SIZEOF_SIZE_T >= DK3_SIZEOF_UM
+ back = (size_t)um1;
+#else
+ if ((dk3_um_t)DK3_SIZE_T_MAX >= um1) {
+ back = (size_t)um1;
+ }
+#endif
+#endif
+ }
+ }
+ if (0 == back) {
+ if (dk3app_get_pref(app, dk3bf_kw[1], buf, DK3_SIZEOF(buf,dkChar))) {
+#if VERSION_BEFORE_20140716
+ if (dk3ma_string_to_um(&um1, buf))
+#else
+ if (0 != dk3ma_um_from_string(&um1, buf, NULL))
+#endif
+ {
+ if (dk3app_get_pref(app, dk3bf_kw[2], buf, DK3_SIZEOF(buf,dkChar))) {
+#if VERSION_BEFORE_20140716
+ if (dk3ma_string_to_um(&um2, buf))
+#else
+ if (0 != dk3ma_um_from_string(&um2, buf, NULL))
+#endif
+ {
+ if (DK3_UM_0 < um2) {
+ if ((dk3_um_t)100U >= um2) {
+ back = dk3ma_um_to_sz(
+ (dk3ma_um_mul_ok(um1, um2, &ec) / ((dk3_um_t)100U)),
+ &ec
+ );
+ if (0 != ec) { back = 0; }
+ }
+ }
+ }
+ }
+ if (0 == back) {
+ ec = 0;
+ back = dk3ma_um_to_sz((um1 / ((dk3_um_t)4U)), &ec);
+ if (0 != ec) { back = 0; }
+ }
+ }
+ }
+ }
+
+
+#line 546 "dk3bf.ctr"
+ return back;
+}
+
+#endif
+
+
+
+dk3_bm_t *
+dk3bm_open(size_t x, size_t y, dk3_app_t *app)
+{
+ dk3_bm_t *back = NULL;
+ size_t bpstr = 0; /* Bytes per strip */
+ size_t i = 0; /* Current strip index */
+ int ok = 0; /* Flag: Successfully */
+
+
+#line 561 "dk3bf.ctr"
+ if ((x) && (y)) {
+ back = dk3_new_app(dk3_bm_t,1,app);
+ if (back) {
+ back->columns = x;
+ back->rows = y;
+ back->app = app;
+ back->cachesize = 0;
+ back->data = NULL;
+ if (x < y) {
+
+#line 570 "dk3bf.ctr"
+ bpstr = y / 8;
+ if (y % 8) { bpstr++; }
+ back->data = dk3_new_app(DK3_PUCHAR,x,app);
+ if (back->data) {
+
+#line 574 "dk3bf.ctr"
+ ok = 1;
+ for (i = 0; i < x; i++) { (back->data)[i] = NULL; }
+ for (i = 0; i < x; i++) {
+ (back->data)[i] = dk3_new_app(unsigned char,bpstr,app);
+ if ((back->data)[i]) {
+ dk3mem_res((void *)((back->data)[i]), bpstr);
+ } else {
+ ok = 0;
+ }
+ }
+ if (!(ok)) {
+
+#line 585 "dk3bf.ctr"
+ dk3bm_close(back); back = NULL;
+ }
+ } else {
+
+#line 588 "dk3bf.ctr"
+ dk3_release(back);
+ }
+ } else {
+
+#line 591 "dk3bf.ctr"
+ bpstr = x / 8;
+ if (x % 8) { bpstr++; }
+ back->data = dk3_new_app(DK3_PUCHAR,y,app);
+ if (back->data) {
+
+#line 595 "dk3bf.ctr"
+ ok = 1;
+ for (i = 0; i < y; i++) { (back->data)[i] = NULL; }
+ for (i = 0; i < y; i++) {
+ (back->data)[i] = dk3_new_app(unsigned char,bpstr,app);
+ if ((back->data)[i]) {
+ dk3mem_res((void *)((back->data)[i]), bpstr);
+ } else {
+ ok = 0;
+ }
+ }
+ if (!(ok)) {
+
+#line 606 "dk3bf.ctr"
+ dk3bm_close(back); back = NULL;
+ }
+ } else {
+
+#line 609 "dk3bf.ctr"
+ dk3_release(back);
+ }
+ }
+ if (back) {
+ if (app) {
+ back->cachesize = dk3bf_get_cache_size(app);
+ }
+ }
+ } else {
+
+#line 618 "dk3bf.ctr"
+ }
+ } else {
+
+#line 620 "dk3bf.ctr"
+ }
+
+
+#line 622 "dk3bf.ctr"
+ return back;
+}
+
+
+
+void
+dk3bm_set_cache_size(dk3_bm_t *b, size_t cs)
+{
+ if (b) { b->cachesize = cs; }
+}
+
+
+
+void
+dk3bm_set(dk3_bm_t *b, size_t x, size_t y, int v)
+{
+ unsigned char *pu = NULL; /* Stripe pointer */
+ size_t byteno = 0; /* Index of byte in stripe */
+ size_t bitno = 0; /* Index of bit within the byte */
+
+
+#line 642 "dk3bf.ctr"
+ if (b) {
+ if ((x < b->columns) && (y < b->rows)) {
+ if (b->columns < b->rows) {
+ pu = (b->data)[x];
+ byteno = y / 8;
+ bitno = y % 8;
+ } else {
+ pu = (b->data)[y];
+ byteno = x / 8;
+ bitno = x % 8;
+ }
+ if (v) {
+ pu[byteno] |= dk3bf_bits_in_byte[bitno];
+ } else {
+ pu[byteno] &= dk3bf_not_in_byte[bitno];
+ }
+ }
+ }
+
+
+#line 661 "dk3bf.ctr"
+}
+
+
+
+int
+dk3bm_get(dk3_bm_t const *b, size_t x, size_t y)
+{
+ unsigned char *pu = NULL; /* Stripe pointer */
+ size_t byteno = 0; /* Index of byte within stripe */
+ size_t bitno = 0; /* Index of bit within byte */
+ int back = 0;
+
+
+
+#line 674 "dk3bf.ctr"
+ if (b) {
+ if ((x < b->columns) && (y < b->rows)) {
+ if (b->columns < b->rows) {
+ pu = (b->data)[x];
+ byteno = y / 8;
+ bitno = y % 8;
+ } else {
+ pu = (b->data)[y];
+ byteno = x / 8;
+ bitno = x % 8;
+ }
+ if((pu[byteno]) & (dk3bf_bits_in_byte[bitno])) {
+ back = 1;
+ }
+ }
+ }
+
+
+#line 691 "dk3bf.ctr"
+ return back;
+}
+
+
+
+void
+dk3bm_expand(dk3_bm_t *b)
+{
+ int f_cache_fr = 1; /* Flag: Cache friendly */
+ int f_change_found = 0; /* Flag: Change found */
+ size_t i = 0; /* Source node number */
+ size_t j = 0; /* Destination node number */
+ size_t k = 0; /* Intermediate node */
+ size_t mxs = 0; /* Matrix size */
+ int ec = 0; /* Math error code */
+
+
+#line 707 "dk3bf.ctr"
+ if (b) {
+
+#line 708 "dk3bf.ctr"
+ if (b->columns == b->rows) {
+
+#line 709 "dk3bf.ctr"
+ if (b->cachesize) {
+ mxs = dk3mem_mul_size_t(b->rows, b->columns, &ec);
+ if (mxs % 8) { mxs = mxs / 8 + 1; } else { mxs = mxs / 8; }
+ if (0 == ec) { if (mxs <= b->cachesize) { f_cache_fr = 0; } }
+ } else {
+ f_cache_fr = 0;
+ }
+ if (f_cache_fr) {
+
+#line 717 "dk3bf.ctr"
+ do {
+ f_change_found = 0;
+ for (j = 0; j < b->rows; j++) {
+ for (k = 0; k < b->columns; k++) {
+ for (i = 0; i < b->columns; i++) {
+ if (!(dk3bm_get(b, i, j))) {
+ if (dk3bm_get(b, k, j)) {
+ if (dk3bm_get(b, i, k)) {
+ dk3bm_set(b, i, j, 1);
+ f_change_found = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ } while(f_change_found);
+ } else {
+
+#line 735 "dk3bf.ctr"
+ do {
+ f_change_found = 0;
+ for (i = 0; i < b->columns; i++) {
+ for (j = 0; j < b->rows; j++) {
+ if (!(dk3bm_get(b, i, j))) {
+ for (k = 0; k < b->columns; k++) {
+ if (dk3bm_get(b, i, k)) {
+ if (dk3bm_get(b, k, j)) {
+ dk3bm_set(b, i, j, 1);
+ f_change_found = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ } while(f_change_found);
+ }
+ } else {
+
+#line 754 "dk3bf.ctr"
+ if (b->app) {
+ /* ERROR: Matrix must be a square! */
+ dk3app_log_i1(b->app, DK3_LL_ERROR, 201);
+ }
+ }
+ }
+
+#line 760 "dk3bf.ctr"
+}
+
+
+#endif
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dk3bf.ctr b/support/dktools/dk3bf.ctr
new file mode 100644
index 0000000000..5f85ecfdb7
--- /dev/null
+++ b/support/dktools/dk3bf.ctr
@@ -0,0 +1,766 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+%% header
+
+#include "dk3conf.h"
+#include "dk3types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** Open a bit field (bit array).
+ @param nbits Number of bits.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new bit field on success, NULL on error.
+*/
+dk3_bf_t *
+dk3bf_open_app(size_t nbits, dk3_app_t *app);
+
+/** Close bit field.
+ @param b Bit field to close.
+*/
+void
+dk3bf_close(dk3_bf_t *b);
+
+/** Set or reset one bit.
+ @param b Bit field.
+ @param n Index of bit to set.
+ @param v New bit value (1 or 0).
+*/
+void
+dk3bf_set(dk3_bf_t *b, size_t n, int v);
+
+/** Get one bit value.
+ @param b Bit field.
+ @param n Index of bit.
+ @return 1 or 0 depending on the bit value.
+*/
+int
+dk3bf_get(dk3_bf_t const *b, size_t n);
+
+/** Open a bit matrix.
+ @param x Number of columns.
+ @param y Number of rows.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new bit matrix on success, NULL on error.
+*/
+dk3_bm_t *
+dk3bm_open(size_t x, size_t y, dk3_app_t *app);
+
+/** Close bit matrix.
+ @param b Bit matrix to close.
+*/
+void
+dk3bm_close(dk3_bm_t *b);
+
+/** Set cache size (threshold to switch between traditional
+ algorithm for dk3bm_expand and cache friendly algorithm).
+ @param b Bit matrix.
+ @param cs Maximum matrix size for traditional algorithm.
+*/
+void
+dk3bm_set_cache_size(dk3_bm_t *b, size_t cs);
+
+/** Set or reset one bit.
+ @param b Bit matrix.
+ @param x Column number.
+ @param y Row number.
+ @param v New value for bit.
+*/
+void
+dk3bm_set(dk3_bm_t *b, size_t x, size_t y, int v);
+
+/** Get one bit.
+ @param b Bit matrix.
+ @param x Column number.
+ @param y Row number.
+ @return 1 or 0 depending on the bit value.
+*/
+int
+dk3bm_get(dk3_bm_t const *b, size_t x, size_t y);
+
+/** Expand bit matrix. The matrix must be square.
+ @param b Bit matrix.
+*/
+void
+dk3bm_expand(dk3_bm_t *b);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk3all.h"
+#include "dk3cores.h"
+
+
+$!trace-include
+
+
+/** Bit mask to set/retrieve single bits in a byte.
+*/
+static unsigned char const dk3bf_bits_in_byte[] = {
+0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
+};
+
+
+
+/** Bit masks to reset a single bit in a byte
+*/
+static unsigned char const dk3bf_not_in_byte[] = {
+0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0xFE
+};
+
+
+
+/** Keywords used by the module, not localized.
+*/
+static dkChar const * const dk3bf_kw[] = {
+$!string-table macro=dkT
+#
+# 0 Threshold to switch from traditional to cache friendly
+#
+/bitmatrix/expand/cache-friendly
+#
+# 1 Amount of cache available
+#
+/proc/cache/available
+#
+# 2 Percents of entire cache available to this program
+#
+/proc/cache/percent
+$!end
+};
+
+void
+dk3bf_close(dk3_bf_t *b)
+{
+ if(b) {
+ dk3_release(b->data);
+ b->nbits = 0; b->app = NULL;
+ dk3_delete(b);
+ }
+}
+
+
+
+dk3_bf_t *
+dk3bf_open_app(size_t nbits, dk3_app_t *app)
+{
+ dk3_bf_t *back = NULL;
+ size_t sz = 0; /* Number of bytes needed. */
+ if(nbits) {
+ sz = nbits / 8;
+ if(nbits % 8) { sz++; }
+ back = dk3_new_app(dk3_bf_t,1,app);
+ if(back) {
+ back->nbits = nbits; back->data = NULL; back->app = app;
+ back->data = dk3_new_app(unsigned char,sz,app);
+ if(back->data) {
+ dk3mem_res((void *)(back->data), sz);
+ } else {
+ dk3bf_close(back); back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void
+dk3bf_set(dk3_bf_t *b, size_t n, int v)
+{
+ size_t byteno = 0; /* Byte index in data. */
+ size_t inbyte = 0; /* Number of bit within the byte. */
+ if(b) {
+ if(n < b->nbits) {
+ byteno = n / 8; inbyte = n % 8;
+ if(v) {
+ (b->data)[byteno] |= dk3bf_bits_in_byte[inbyte];
+ } else {
+ (b->data)[byteno] &= (~(dk3bf_bits_in_byte[inbyte]));
+ }
+ } else {
+ if(b->app) {
+ /* ERROR: Index out of range. */
+ dk3app_log_i1(b->app, DK3_LL_ERROR, 200);
+ }
+ }
+ }
+}
+
+
+
+int
+dk3bf_get(dk3_bf_t const *b, size_t n)
+{
+ int back = 0;
+ size_t byteno = 0; /* Byte index in data. */
+ size_t inbyte = 0; /* Number of bit within the byte. */
+ if(b) {
+ if(n < b->nbits) {
+ byteno = n / 8; inbyte = n % 8;
+ if(((b->data)[byteno]) & (dk3bf_bits_in_byte[inbyte])) {
+ back = 1;
+ }
+ } else {
+ if(b->app) {
+ /* ERROR: Index out of range. */
+ dk3app_log_i1(b->app, DK3_LL_ERROR, 200);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+#if VERSION_BEFORE_20140605
+
+void
+dk3bm_close(dk3_bm_t *b)
+{
+ size_t i = 0; /* Index of current row to delete. */
+ if(b) {
+ if(b->data) {
+ for(i = 0; i < b->rows; i++) {
+ dk3_release((b->data)[i]);
+ }
+ dk3_delete(b->data);
+ }
+ b->data = NULL; b->app = NULL; b->columns = 0; b->rows = 0;
+ dk3_delete(b);
+ }
+}
+
+
+
+dk3_bm_t *
+dk3bm_open(size_t x, size_t y, dk3_app_t *app)
+{
+ size_t bytes_per_row = 0; /* Number of bytes per row. */
+ size_t i = 0; /* Current row to initialize. */
+ int ok = 0; /* Flag: Success. */
+ dk3_bm_t *back = NULL;
+ if((x) && (y)) {
+ back = dk3_new_app(dk3_bm_t,1,app);
+ if(back) {
+ back->columns = x; back->rows = y; back->app = app;
+ back->data = NULL;
+ bytes_per_row = x / 8;
+ if(x % 8) { bytes_per_row++; }
+ back->data = dk3_new_app(DK3_PUCHAR,y,app);
+ if(back->data) {
+ ok = 1;
+ for(i = 0; i < y; i++) { (back->data)[i] = NULL; }
+ for(i = 0; i < y; i++) {
+ (back->data)[i] = dk3_new_app(unsigned char,bytes_per_row,app);
+ if((back->data)[i]) {
+ dk3mem_res((void *)((back->data)[i]), bytes_per_row);
+ } else {
+ ok = 0;
+ }
+ }
+ if(ok == 0) {
+ dk3bm_close(back); back = NULL;
+ }
+ } else {
+ dk3_delete(back); back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void
+dk3bm_set(dk3_bm_t *b, size_t x, size_t y, int v)
+{
+ unsigned char *pu = NULL; /* Row pointer. */
+ size_t byteno = 0; /* Index of byte in row. */
+ size_t bitno = 0; /* Index of bit within the byte. */
+ if(b) {
+ if((x < b->columns) && (y < b->rows)) {
+ pu = (b->data)[y];
+ byteno = x / 8; bitno = x % 8;
+ if(v) {
+ pu[byteno] |= dk3bf_bits_in_byte[bitno];
+ } else {
+ pu[byteno] &= (~(dk3bf_bits_in_byte[bitno]));
+ }
+ }
+ }
+}
+
+
+
+int
+dk3bm_get(dk3_bm_t const *b, size_t x, size_t y)
+{
+ int back = 0;
+ unsigned char *pu = NULL; /* Row pointer. */
+ size_t byteno = 0; /* Index of byte within the row. */
+ size_t bitno = 0; /* Index of bit within the byte. */
+ if(b) {
+ if((x < b->columns) && (y < b->rows)) {
+ pu = (b->data)[y];
+ byteno = x / 8; bitno = x % 8;
+ if((pu[byteno]) & (dk3bf_bits_in_byte[bitno])) {
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void
+dk3bm_expand(dk3_bm_t *b)
+{
+ int f_change_found = 0; /* Flag: Change found in this pass. */
+ size_t i = 0; /* Source node number. */
+ size_t j = 0; /* Destination node number. */
+ size_t k = 0; /* Intermediate node number. */
+ size_t p = 0; /* Number of current pass. */
+ if(b) {
+ if(b->columns == b->rows) {
+ p = 0;
+ do {
+ f_change_found = 0;
+ for(i = 0; i < b->columns; i++) {
+ for(j = 0; j < b->rows; j++) {
+ if(!dk3bm_get(b, i, j)) {
+ for(k = 0; k < b->columns; k++) {
+ if(dk3bm_get(b, i, k)) {
+ if(dk3bm_get(b, k, j)) {
+ dk3bm_set(b, i, j, 1);
+ f_change_found = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ p++;
+ } while((f_change_found) && (p < b->columns));
+ } else {
+ if(b->app) {
+ /* ERROR: Matrix must be a square! */
+ dk3app_log_i1(b->app, DK3_LL_ERROR, 201);
+ }
+ }
+ }
+}
+
+
+#else
+
+
+
+void
+dk3bm_close(dk3_bm_t *b)
+{
+ size_t i;
+ if (b) {
+ if (b->data) {
+ if (b->columns < b->rows) {
+ for (i = 0; i < b->columns; i++) {
+ dk3_release((b->data)[i]);
+ }
+ } else {
+ for (i = 0; i < b->rows; i++) {
+ dk3_release((b->data)[i]);
+ }
+ }
+ dk3_delete(b->data);
+ }
+ b->data = NULL;
+ b->app = NULL;
+ b->columns = 0;
+ b->rows = 0;
+ b->cachesize = 0;
+ dk3_delete(b);
+ }
+}
+
+
+
+#if VERSION_BEFORE_20140809
+
+/** Find cache size available to this bit matrix expansion.
+ @param app Application structure.
+ @return Cache size if preferences found, 0 otherwise.
+*/
+static
+size_t
+dk3bf_get_cache_size(dk3_app_t *app)
+{
+ dkChar buf[128];
+ unsigned long ul = 0UL;
+ size_t back = 0;
+ int found = 0;
+ int ec = 0;
+ $? "+ dk3bf_get_cache_size"
+ if (dk3app_get_pref(app, dk3bf_kw[0], buf, DK3_SIZEOF(buf,dkChar))) {
+#if VERSION_BEFORE_20140716
+ if (1 == dk3sf_sscanf3(buf, dkT("%lu"), &ul))
+#else
+ if (0 != dk3ma_ul_from_string(&ul, buf, NULL))
+#endif
+ {
+ back = (size_t)ul;
+ found = 1;
+ if ((unsigned long)back != ul) {
+ back = 0;
+ found = 0;
+ }
+ }
+ }
+ if (!(found)) {
+ if (dk3app_get_pref(app, dk3bf_kw[1], buf, DK3_SIZEOF(buf,dkChar))) {
+#if VERSION_BEFORE_20140716
+ if (1 == dk3sf_sscanf3(buf, dkT("%lu"), &ul))
+#else
+ if (0 != dk3ma_ul_from_string(&ul, buf, NULL))
+#endif
+ {
+ back = (size_t)ul;
+ found = 1;
+ if ((unsigned long)back != ul) {
+ back = 0;
+ found = 0;
+ }
+ if (found) {
+ found = 0;
+ if (dk3app_get_pref(app, dk3bf_kw[2], buf, DK3_SIZEOF(buf,dkChar))) {
+#if VERSION_BEFORE_20140716
+ if (1 == dk3sf_sscanf3(buf, dkT("%lu"), &ul))
+#else
+ if (0 != dk3ma_ul_from_string(&ul, buf, NULL))
+#endif
+ {
+ back = dk3mem_mul_size_t(back, (size_t)ul, &ec) / 100;
+ if (ec) {
+ back = 0;
+ } else {
+ found = 1;
+ }
+ }
+ }
+ if ((back) && (!(found))) {
+ back = back / 4;
+ if (0 < back) { back = 1; }
+ }
+ }
+ }
+ }
+ } $? "- dk3bf_get_cache_size %lu", (unsigned long)back
+ return back;
+}
+
+#else
+
+/** Find cache size available to this bit matrix expansion.
+ @param app Application structure.
+ @return Cache size if preferences found, 0 otherwise.
+*/
+static
+size_t
+dk3bf_get_cache_size(dk3_app_t *app)
+{
+
+ dkChar buf[128]; /* Preference value text */
+ dk3_um_t um1; /* From preferences */
+ dk3_um_t um2; /* From preferences */
+ size_t back = 0;
+ int ec = 0; /* Error code */
+ $? "+ dk3bf_get_cache_size"
+ if (dk3app_get_pref(app, dk3bf_kw[0], buf, DK3_SIZEOF(buf,dkChar))) {
+#if VERSION_BEFORE_20140716
+ if (dk3ma_string_to_um(&um1, buf))
+#else
+ if (0 != dk3ma_um_from_string(&um1, buf, NULL))
+#endif
+ {
+#if VERSION_BEFORE_20140716
+ back = dk3ma_um_to_sz(um1, NULL);
+#else
+#if DK3_SIZEOF_SIZE_T >= DK3_SIZEOF_UM
+ back = (size_t)um1;
+#else
+ if ((dk3_um_t)DK3_SIZE_T_MAX >= um1) {
+ back = (size_t)um1;
+ }
+#endif
+#endif
+ }
+ }
+ if (0 == back) {
+ if (dk3app_get_pref(app, dk3bf_kw[1], buf, DK3_SIZEOF(buf,dkChar))) {
+#if VERSION_BEFORE_20140716
+ if (dk3ma_string_to_um(&um1, buf))
+#else
+ if (0 != dk3ma_um_from_string(&um1, buf, NULL))
+#endif
+ {
+ if (dk3app_get_pref(app, dk3bf_kw[2], buf, DK3_SIZEOF(buf,dkChar))) {
+#if VERSION_BEFORE_20140716
+ if (dk3ma_string_to_um(&um2, buf))
+#else
+ if (0 != dk3ma_um_from_string(&um2, buf, NULL))
+#endif
+ {
+ if (DK3_UM_0 < um2) {
+ if ((dk3_um_t)100U >= um2) {
+ back = dk3ma_um_to_sz(
+ (dk3ma_um_mul_ok(um1, um2, &ec) / ((dk3_um_t)100U)),
+ &ec
+ );
+ if (0 != ec) { back = 0; }
+ }
+ }
+ }
+ }
+ if (0 == back) {
+ ec = 0;
+ back = dk3ma_um_to_sz((um1 / ((dk3_um_t)4U)), &ec);
+ if (0 != ec) { back = 0; }
+ }
+ }
+ }
+ }
+ $? "- dk3bf_get_cache_size"
+ return back;
+}
+
+#endif
+
+
+
+dk3_bm_t *
+dk3bm_open(size_t x, size_t y, dk3_app_t *app)
+{
+ dk3_bm_t *back = NULL;
+ size_t bpstr = 0; /* Bytes per strip */
+ size_t i = 0; /* Current strip index */
+ int ok = 0; /* Flag: Successfully */
+ $? "+ dk3bm_open %lu %lu", (unsigned long)x, (unsigned long)y
+ if ((x) && (y)) {
+ back = dk3_new_app(dk3_bm_t,1,app);
+ if (back) {
+ back->columns = x;
+ back->rows = y;
+ back->app = app;
+ back->cachesize = 0;
+ back->data = NULL;
+ if (x < y) { $? ". saving column by column"
+ bpstr = y / 8;
+ if (y % 8) { bpstr++; }
+ back->data = dk3_new_app(DK3_PUCHAR,x,app);
+ if (back->data) { $? ". array allocation ok"
+ ok = 1;
+ for (i = 0; i < x; i++) { (back->data)[i] = NULL; }
+ for (i = 0; i < x; i++) {
+ (back->data)[i] = dk3_new_app(unsigned char,bpstr,app);
+ if ((back->data)[i]) {
+ dk3mem_res((void *)((back->data)[i]), bpstr);
+ } else {
+ ok = 0;
+ }
+ }
+ if (!(ok)) { $? "! stripe(s) allocation failed"
+ dk3bm_close(back); back = NULL;
+ }
+ } else { $? "! array allocation failed"
+ dk3_release(back);
+ }
+ } else { $? ". saving row by row"
+ bpstr = x / 8;
+ if (x % 8) { bpstr++; }
+ back->data = dk3_new_app(DK3_PUCHAR,y,app);
+ if (back->data) { $? ". array allocation ok"
+ ok = 1;
+ for (i = 0; i < y; i++) { (back->data)[i] = NULL; }
+ for (i = 0; i < y; i++) {
+ (back->data)[i] = dk3_new_app(unsigned char,bpstr,app);
+ if ((back->data)[i]) {
+ dk3mem_res((void *)((back->data)[i]), bpstr);
+ } else {
+ ok = 0;
+ }
+ }
+ if (!(ok)) { $? "! failure(s) in stripe allocation"
+ dk3bm_close(back); back = NULL;
+ }
+ } else { $? "! array allocation failed"
+ dk3_release(back);
+ }
+ }
+ if (back) {
+ if (app) {
+ back->cachesize = dk3bf_get_cache_size(app);
+ }
+ }
+ } else { $? "! allocation failed"
+ }
+ } else { $? "! wrong arguments"
+ }
+ $? "- dk3bm_open %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+void
+dk3bm_set_cache_size(dk3_bm_t *b, size_t cs)
+{
+ if (b) { b->cachesize = cs; }
+}
+
+
+
+void
+dk3bm_set(dk3_bm_t *b, size_t x, size_t y, int v)
+{
+ unsigned char *pu = NULL; /* Stripe pointer */
+ size_t byteno = 0; /* Index of byte in stripe */
+ size_t bitno = 0; /* Index of bit within the byte */
+ $? "+ dk3bm_set %lu %lu %d", (unsigned long)x, (unsigned long)y, v
+ if (b) {
+ if ((x < b->columns) && (y < b->rows)) {
+ if (b->columns < b->rows) {
+ pu = (b->data)[x];
+ byteno = y / 8;
+ bitno = y % 8;
+ } else {
+ pu = (b->data)[y];
+ byteno = x / 8;
+ bitno = x % 8;
+ }
+ if (v) {
+ pu[byteno] |= dk3bf_bits_in_byte[bitno];
+ } else {
+ pu[byteno] &= dk3bf_not_in_byte[bitno];
+ }
+ }
+ }
+ $? "- dk3bm_set"
+}
+
+
+
+int
+dk3bm_get(dk3_bm_t const *b, size_t x, size_t y)
+{
+ unsigned char *pu = NULL; /* Stripe pointer */
+ size_t byteno = 0; /* Index of byte within stripe */
+ size_t bitno = 0; /* Index of bit within byte */
+ int back = 0;
+
+ $? "+ dk3bm_get %lu %lu", (unsigned long)x, (unsigned long)y
+ if (b) {
+ if ((x < b->columns) && (y < b->rows)) {
+ if (b->columns < b->rows) {
+ pu = (b->data)[x];
+ byteno = y / 8;
+ bitno = y % 8;
+ } else {
+ pu = (b->data)[y];
+ byteno = x / 8;
+ bitno = x % 8;
+ }
+ if((pu[byteno]) & (dk3bf_bits_in_byte[bitno])) {
+ back = 1;
+ }
+ }
+ }
+ $? "- dk3bm_get %d", back
+ return back;
+}
+
+
+
+void
+dk3bm_expand(dk3_bm_t *b)
+{
+ int f_cache_fr = 1; /* Flag: Cache friendly */
+ int f_change_found = 0; /* Flag: Change found */
+ size_t i = 0; /* Source node number */
+ size_t j = 0; /* Destination node number */
+ size_t k = 0; /* Intermediate node */
+ size_t mxs = 0; /* Matrix size */
+ int ec = 0; /* Math error code */
+ $? "+ dk3bm_expand"
+ if (b) { $? ". b ok"
+ if (b->columns == b->rows) { $? ". square"
+ if (b->cachesize) {
+ mxs = dk3mem_mul_size_t(b->rows, b->columns, &ec);
+ if (mxs % 8) { mxs = mxs / 8 + 1; } else { mxs = mxs / 8; }
+ if (0 == ec) { if (mxs <= b->cachesize) { f_cache_fr = 0; } }
+ } else {
+ f_cache_fr = 0;
+ }
+ if (f_cache_fr) { $? ". cache friendly"
+ do {
+ f_change_found = 0;
+ for (j = 0; j < b->rows; j++) {
+ for (k = 0; k < b->columns; k++) {
+ for (i = 0; i < b->columns; i++) {
+ if (!(dk3bm_get(b, i, j))) {
+ if (dk3bm_get(b, k, j)) {
+ if (dk3bm_get(b, i, k)) {
+ dk3bm_set(b, i, j, 1);
+ f_change_found = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ } while(f_change_found);
+ } else { $? ". traditional"
+ do {
+ f_change_found = 0;
+ for (i = 0; i < b->columns; i++) {
+ for (j = 0; j < b->rows; j++) {
+ if (!(dk3bm_get(b, i, j))) {
+ for (k = 0; k < b->columns; k++) {
+ if (dk3bm_get(b, i, k)) {
+ if (dk3bm_get(b, k, j)) {
+ dk3bm_set(b, i, j, 1);
+ f_change_found = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ } while(f_change_found);
+ }
+ } else { $? "! not square"
+ if (b->app) {
+ /* ERROR: Matrix must be a square! */
+ dk3app_log_i1(b->app, DK3_LL_ERROR, 201);
+ }
+ }
+ } $? "- dk3bm_expand"
+}
+
+
+#endif
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dk3bf.h b/support/dktools/dk3bf.h
new file mode 100644
index 0000000000..2d81db7d80
--- /dev/null
+++ b/support/dktools/dk3bf.h
@@ -0,0 +1,139 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3bf.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3bf.h Header file for the dk3bf module.
+*/
+
+#ifndef DK3BF_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3BF_H_INCLUDED 1
+
+
+#line 8 "dk3bf.ctr"
+
+#include "dk3conf.h"
+#include "dk3types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** Open a bit field (bit array).
+ @param nbits Number of bits.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new bit field on success, NULL on error.
+*/
+dk3_bf_t *
+dk3bf_open_app(size_t nbits, dk3_app_t *app);
+
+/** Close bit field.
+ @param b Bit field to close.
+*/
+void
+dk3bf_close(dk3_bf_t *b);
+
+/** Set or reset one bit.
+ @param b Bit field.
+ @param n Index of bit to set.
+ @param v New bit value (1 or 0).
+*/
+void
+dk3bf_set(dk3_bf_t *b, size_t n, int v);
+
+/** Get one bit value.
+ @param b Bit field.
+ @param n Index of bit.
+ @return 1 or 0 depending on the bit value.
+*/
+int
+dk3bf_get(dk3_bf_t const *b, size_t n);
+
+/** Open a bit matrix.
+ @param x Number of columns.
+ @param y Number of rows.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new bit matrix on success, NULL on error.
+*/
+dk3_bm_t *
+dk3bm_open(size_t x, size_t y, dk3_app_t *app);
+
+/** Close bit matrix.
+ @param b Bit matrix to close.
+*/
+void
+dk3bm_close(dk3_bm_t *b);
+
+/** Set cache size (threshold to switch between traditional
+ algorithm for dk3bm_expand and cache friendly algorithm).
+ @param b Bit matrix.
+ @param cs Maximum matrix size for traditional algorithm.
+*/
+void
+dk3bm_set_cache_size(dk3_bm_t *b, size_t cs);
+
+/** Set or reset one bit.
+ @param b Bit matrix.
+ @param x Column number.
+ @param y Row number.
+ @param v New value for bit.
+*/
+void
+dk3bm_set(dk3_bm_t *b, size_t x, size_t y, int v);
+
+/** Get one bit.
+ @param b Bit matrix.
+ @param x Column number.
+ @param y Row number.
+ @return 1 or 0 depending on the bit value.
+*/
+int
+dk3bm_get(dk3_bm_t const *b, size_t x, size_t y);
+
+/** Expand bit matrix. The matrix must be square.
+ @param b Bit matrix.
+*/
+void
+dk3bm_expand(dk3_bm_t *b);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3bif.c b/support/dktools/dk3bif.c
new file mode 100644
index 0000000000..35a8df4b17
--- /dev/null
+++ b/support/dktools/dk3bif.c
@@ -0,0 +1,3171 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3bif.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3bif.c The dk3bif module.
+*/
+
+
+#line 393 "dk3bif.ctr"
+
+#include "dk3conf.h"
+
+#include <stdio.h>
+
+#if DK3_HAVE_PNG_H
+#include <png.h>
+#else
+#if DK3_HAVE_SETJMP_H
+#include <setjmp.h>
+#endif
+#endif
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if DK3_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if DK3_HAVE_PROCESS_H
+#include <process.h>
+#endif
+#if DK3_HAVE_JPEGLIB_H
+#include <jpeglib.h>
+#endif
+
+#if DK3_HAVE_TIFF_H
+#include <tiff.h>
+#include <tiffio.h>
+#endif
+
+#if DK3_HAVE_STRING_H
+#include <string.h>
+#endif
+#if DK3_HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
+#if 0
+#include "dk3all.h"
+#endif
+
+#include "dk3const.h"
+#include "dk3mem.h"
+#include "dk3str.h"
+#include "dk3sf.h"
+#include "dk3sto.h"
+#include "dk3bif.h"
+#include "dk3bifa.h"
+#include "dk3pixre.h"
+#include "dk3ma.h"
+#include "dk3numco.h"
+#include "dk3bits.h"
+#include "dk3app.h"
+
+
+
+
+
+#line 453 "dk3bif.ctr"
+
+
+
+
+#line 456 "dk3bif.ctr"
+
+
+/** File suffixes for images.
+*/
+static dkChar const * const dk3bif_dk_type_names[] = {
+dkT("png"),
+dkT("jpeg"),
+dkT("jpg"),
+dkT("tiff"),
+dkT("tif"),
+NULL
+
+
+#line 468 "dk3bif.ctr"
+};
+
+
+
+/** File suffixes for images.
+ Note: Order must correpsond to the order of dk3bif_dk_type_names.
+*/
+static char const * const dk3bif_c8_type_names[] = {
+"png",
+"jpeg",
+"jpg",
+"tiff",
+"tif",
+NULL
+
+
+#line 483 "dk3bif.ctr"
+};
+
+
+
+/** Keywords used by the module (dkChar).
+*/
+static dkChar const * const dk3bif_kw_dk[] = {
+/* 0 */ dkT("rb"),
+NULL
+};
+
+
+
+/** Keywords and texts used by the module (8-bit).
+*/
+static char const * const dk3bif_kw_c8[] = {
+/* 0 */ "dk3bif-%lu-%lu.tmp", /* PID, index */
+/* 1 */ "dk3bif-%d-%lu.tmp", /* PID, index */
+NULL
+};
+
+
+
+/** Number of current temporary file within this process.
+*/
+static unsigned long dk3bif_temp_number = 0UL;
+
+
+
+static
+dk3_bif_frame_t *
+dk3bif_frame_new(dk3_bif_t *bp);
+
+
+
+#if DK3_HAVE_PNG_H
+/** Per frame data, PNG-specific.
+*/
+typedef struct {
+ png_bytep *rows;
+ png_colorp palp;
+ png_size_t rowbytes;
+ dk3_bif_coord_t h;
+ dk3_bif_pixel_t bgred;
+ dk3_bif_pixel_t bggreen;
+ dk3_bif_pixel_t bgblue;
+ int paln;
+} dk3_bif_frame_png_t;
+
+/** Per file data, PNG-specific.
+*/
+typedef struct {
+ png_structp pp; /* Read structure. */
+ png_infop pi; /* PNG information. */
+ int ct; /* Color type. */
+ int im; /* Interlace method. */
+ int cm; /* Compression method. */
+ int fm; /* Filter method. */
+ int ch; /* Number of channels. */
+ int np; /* Number of interlace passes. */
+} dk3_bif_png_t;
+
+/** Release type-specific information for PNG file.
+ @param is Bitmap-type specific data.
+*/
+static
+void
+dk3bif_frame_release_implspec_png(void *is)
+{
+ dk3_bif_frame_png_t *fdis;
+ dk3_bif_coord_t i;
+
+
+#line 555 "dk3bif.ctr"
+ fdis = (dk3_bif_frame_png_t *)is;
+ if(fdis->rows) {
+
+#line 557 "dk3bif.ctr"
+ for(i = 0L; i < fdis->h; i++) {
+
+#line 558 "dk3bif.ctr"
+ dk3_delete((fdis->rows)[i]);
+ }
+ dk3_delete(fdis->rows);
+ }
+ dk3_release(fdis);
+
+
+#line 564 "dk3bif.ctr"
+}
+
+/** Release type specific information for PNG file (image).
+ @param is Bitmap-type specific data.
+*/
+static
+void
+dk3bif_release_implspec_png(void *is)
+{
+ dk3_bif_png_t *dis;
+
+
+#line 575 "dk3bif.ctr"
+ dis = (dk3_bif_png_t *)is;
+ if(dis->pp) {
+ if(dis->pi) {
+
+#line 578 "dk3bif.ctr"
+ png_destroy_info_struct(dis->pp, &(dis->pi));
+ }
+
+#line 580 "dk3bif.ctr"
+ png_destroy_read_struct(&(dis->pp), (png_infopp)NULL, (png_infopp)NULL);
+ }
+ dis->pp = NULL; dis->pi = NULL;
+ dk3_release(dis);
+
+
+#line 585 "dk3bif.ctr"
+}
+
+/** Read header for PNG image.
+ @param bp Bitmap image file.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bif_read_png_header(dk3_bif_t *bp)
+{
+ unsigned char header[9]; /* Test for PNG file header. */
+ dk3_bif_png_t *dis;
+ dk3_bif_frame_png_t *fdis;
+#if 0
+ double gamma; /* Gamma value. */
+#endif
+ double dbldpi = 0.0;
+ double dblxdpi = 0.0;
+ double dblydpi = 0.0;
+ png_uint_32 w; /* Image width. */
+ png_uint_32 h; /* Image height. */
+ png_uint_32 xdpi; /* X resolution. */
+ png_uint_32 ydpi; /* Y resolution. */
+ png_uint_32 dpi; /* Resolution. */
+ int bd; /* Bit depth. */
+ int ct; /* Color type. */
+ int im; /* Interlace method. */
+ int cm; /* Compression method. */
+ int fm; /* Filter method. */
+ int ch; /* Number of channels. */
+ int np = 1; /* Number of interlace passes. */
+ size_t szh; /* Number of header bytes read. */
+ int back = 0;
+
+
+#line 619 "dk3bif.ctr"
+ szh = fread(header, 1, 8, bp->tmpfipo);
+ if(szh > 0) {
+
+#line 621 "dk3bif.ctr"
+ if(png_sig_cmp(header, 0, szh) == 0) {
+ dis = dk3_new_app(dk3_bif_png_t,1,bp->app);
+ if(dis) {
+
+#line 624 "dk3bif.ctr"
+ bp->implspec = (void *)dis;
+ dis->pp = NULL; dis->pi = NULL; dis->ct = 0;
+ dis->pp = png_create_read_struct(
+ PNG_LIBPNG_VER_STRING,
+ NULL, /* user error data */
+ NULL, /* user error function */
+ NULL /* user warning function */
+ );
+ if(dis->pp) {
+
+#line 633 "dk3bif.ctr"
+#if DK3_HAVE_SETJMP_H
+ if(setjmp(png_jmpbuf(dis->pp)) == 0) {
+#endif
+ dis->pi = png_create_info_struct(dis->pp);
+ if(dis->pi) {
+
+#line 638 "dk3bif.ctr"
+ bp->cf = dk3bif_frame_new(bp);
+ if(bp->cf) {
+
+#line 640 "dk3bif.ctr"
+ fdis = dk3_new_app(dk3_bif_frame_png_t,1,bp->app);
+ if(fdis) {
+
+#line 642 "dk3bif.ctr"
+ fdis->rows = NULL;
+ fdis->rowbytes = 0;
+ fdis->palp = NULL;
+ fdis->paln = 0;
+ fdis->bgred = 255; fdis->bggreen = 255; fdis->bgblue = 255;
+ fdis->h = 0L;
+ (bp->cf)->implspec = (void *)fdis;
+ /*
+ Prepare reading.
+ */
+ png_init_io(dis->pp, bp->tmpfipo);
+ png_set_sig_bytes(dis->pp, (int)szh);
+ /*
+ Read file information.
+ */
+ png_read_info(dis->pp, dis->pi);
+ /*
+ Read information about the image.
+ */
+ png_get_IHDR(dis->pp,dis->pi,&w,&h,&bd,&ct,&im,&cm,&fm);
+ /* Static code analysis: Dead assignement. */
+ /* Needed for traceing, not for normal build. */
+#if TRACE_DEBUG || VERSION_BEFORE_20150821
+ ch = png_get_channels(dis->pp, dis->pi);
+
+
+#line 667 "dk3bif.ctr"
+#endif
+ if(png_get_valid(dis->pp, dis->pi, PNG_INFO_pHYs)) {
+#if VERSION_BEFORE_20150821
+ dbldpi = dblxdpi = dblydpi = 0.0;
+#endif
+#if DK3_HAVE_PNG_GET_PIXELS_PER_INCH
+ dpi = png_get_pixels_per_inch(dis->pp, dis->pi);
+ xdpi = png_get_x_pixels_per_inch(dis->pp, dis->pi);
+ ydpi = png_get_y_pixels_per_inch(dis->pp, dis->pi);
+ dbldpi = (double)dpi;
+ dblxdpi = (double)xdpi;
+ dblydpi = (double)ydpi;
+#else
+ /* 0.0254 = 254 / 10000 */
+ dpi = png_get_pixels_per_meter(dis->pp, dis->pi);
+ xdpi = png_get_x_pixels_per_meter(dis->pp, dis->pi);
+ ydpi = png_get_y_pixels_per_meter(dis->pp, dis->pi);
+ dbldpi = 0.0254 * (double)dpi;
+ dblxdpi = 0.0254 * (double)xdpi;
+ dblydpi = 0.0254 * (double)ydpi;
+ dpi = (png_uint_32)dbldpi;
+ xdpi = (png_uint_32)dblxdpi;
+ ydpi = (png_uint_32)dblydpi;
+#endif
+ if(!(xdpi)) {
+ if(dpi) { xdpi = dpi; dblxdpi = dbldpi; }
+ else { if(ydpi) { xdpi = ydpi; dblxdpi = dblydpi; } }
+ }
+ if(!(ydpi)) {
+ if(dpi) { ydpi = dpi; dblydpi = dbldpi; }
+ else { if(xdpi) { ydpi = xdpi; dblydpi = dblxdpi; } }
+ }
+ if((xdpi) && (ydpi)) {
+ (bp->cf)->xres = dblxdpi;
+ (bp->cf)->yres = dblydpi;
+ if((xdpi == 72UL) && (ydpi == 72UL)) {
+ (bp->cf)->xres = (bp->cf)->yres = -1.0;
+ }
+ }
+
+
+#line 707 "dk3bif.ctr"
+ }
+ /*
+ Establish transformations.
+ */
+ if(ct == PNG_COLOR_TYPE_PALETTE) {
+ /* Convert palette image to RGB */
+ png_set_palette_to_rgb(dis->pp);
+ }
+ if(png_get_valid(dis->pp, dis->pi, PNG_INFO_tRNS)) {
+ /* Get alpha values if available */
+ png_set_tRNS_to_alpha(dis->pp);
+ }
+#if !DK3_WORDS_BIGENDIAN
+ if(bd == 16) {
+ /* Change network byte order to host byte order on x86. */
+ png_set_swap(dis->pp);
+ }
+#endif
+#if 0
+/*
+ I need to find out some more about gamma correction.
+*/
+ if(png_get_gAMA(dis->pp, dis->pi, &gamma)) {
+ png_set_gamma(dis->pp, scg, gamma);
+ } else {
+ png_set_gamma(dis->pp, scg, 0.45455);
+ }
+#endif
+ switch(im) {
+ case PNG_INTERLACE_ADAM7: {
+ np = png_set_interlace_handling(dis->pp);
+ } break;
+ }
+ /*
+ Re-read information.
+ */
+ png_read_update_info(dis->pp, dis->pi);
+ png_get_IHDR(dis->pp,dis->pi,&w,&h,&bd,&ct,&im,&cm,&fm);
+ ch = png_get_channels(dis->pp, dis->pi);
+
+
+#line 747 "dk3bif.ctr"
+ (bp->cf)->w = (dk3_bif_coord_t)w;
+ (bp->cf)->h = (dk3_bif_coord_t)h;
+ (bp->cf)->realbits = (bp->cf)->bits = (size_t)bd;
+ dis->ct = ct;
+ dis->im = im;
+ dis->cm = cm;
+ dis->fm = fm;
+ dis->ch = ch;
+ dis->np = np;
+ fdis->h = h;
+ switch(ct) {
+ case PNG_COLOR_TYPE_GRAY: { /* 1,2,4,8,16 */
+ (bp->cf)->cs = DK3_COLOR_SPACE_GRAY;
+ back = 1;
+ } break;
+ case PNG_COLOR_TYPE_GRAY_ALPHA: { /* 8,16 */
+ (bp->cf)->cs = DK3_COLOR_SPACE_GRAY_ALPHA;
+ back = 1;
+ } break;
+ case PNG_COLOR_TYPE_PALETTE: { /* 1,2,4,8 */
+ (bp->cf)->cs = DK3_COLOR_SPACE_RGB;
+ back = 1;
+ } break;
+ case PNG_COLOR_TYPE_RGB: { /* 8,16 */
+ (bp->cf)->cs = DK3_COLOR_SPACE_RGB;
+ back = 1;
+ } break;
+ case PNG_COLOR_TYPE_RGB_ALPHA: { /* 8,16 */
+ (bp->cf)->cs = DK3_COLOR_SPACE_RGBA;
+ back = 1;
+ } break;
+ }
+ } else {
+
+#line 780 "dk3bif.ctr"
+ }
+ } else {
+
+#line 782 "dk3bif.ctr"
+ }
+ } else {
+
+#line 784 "dk3bif.ctr"
+ }
+#if DK3_HAVE_SETJMP_H
+ } else {
+ back = 0;
+ }
+#endif
+ } else {
+
+#line 791 "dk3bif.ctr"
+ }
+ } else {
+
+#line 793 "dk3bif.ctr"
+ }
+ } else {
+
+#line 795 "dk3bif.ctr"
+ }
+ } else {
+
+#line 797 "dk3bif.ctr"
+ }
+
+
+#line 799 "dk3bif.ctr"
+ return back;
+}
+
+/** Read data for PNG image.
+ @param bp Bitmap image file.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bif_read_png_data(dk3_bif_t *bp)
+{
+#if 0
+ png_color_16 bg;
+#endif
+ png_color_16p bgp = NULL;
+ dk3_bif_png_t *dis;
+ dk3_bif_frame_png_t *fdis;
+ png_bytep *rp;
+ dk3_bif_coord_t i;
+ int back = 0;
+ dis = (dk3_bif_png_t *)(bp->implspec);
+ fdis = (dk3_bif_frame_png_t *)((bp->cf)->implspec);
+#if DK3_HAVE_SETJMP_H
+ if(setjmp(png_jmpbuf(dis->pp)) == 0) {
+#endif
+ fdis->rowbytes = png_get_rowbytes(dis->pp, dis->pi);
+ fdis->rows = dk3_new_app(png_bytep,(size_t)((bp->cf)->h),bp->app);
+ if(fdis->rows) {
+ rp = fdis->rows;
+ for(i = 0L; i < (bp->cf)->h; i++) { *(rp++) = NULL; }
+ back = 1;
+ rp = fdis->rows;
+ for(i = 0L; (i < (bp->cf)->h) && (back == 1); i++) {
+ *rp = dk3_new_app(png_byte, fdis->rowbytes, bp->app);
+ if(!(*rp)) {
+ back = 0;
+ }
+ rp++;
+ }
+ if(back) {
+ png_read_image(dis->pp, fdis->rows);
+ if(png_get_bKGD(dis->pp, dis->pi, &bgp)) {
+ fdis->bgred = bgp->red;
+ fdis->bggreen = bgp->green;
+ fdis->bgblue = bgp->blue;
+
+#line 844 "dk3bif.ctr"
+ }
+ if(dis->ct == PNG_COLOR_TYPE_PALETTE) {
+ back = 0;
+ png_get_PLTE(dis->pp, dis->pi, &(fdis->palp), &(fdis->paln));
+ if((fdis->palp) && (fdis->paln)) {
+ back = 1;
+ }
+ }
+ }
+ } else {
+
+#line 854 "dk3bif.ctr"
+ }
+#if DK3_HAVE_SETJMP_H
+ } else {
+ back = 0;
+ }
+#endif
+ return back;
+}
+
+/** Retrieve one pixel component from PNG.
+ @param bp Bitmap image.
+ @param x X coordinate.
+ @param y Y coordinate.
+ @param c Choose component: 0=red/gray, 1=green, 2=blue, 3=alpha.
+ @return Pixel component.
+*/
+static
+dk3_bif_pixel_t
+dk3bif_get_png_pixel_component(
+ dk3_bif_t *bp,
+ dk3_bif_coord_t x,
+ dk3_bif_coord_t y,
+ int c
+)
+{
+ png_bytep row;
+ dk3_bif_png_t *dis;
+ dk3_bif_frame_png_t *fdis;
+ dk3_bif_pixel_t back = (dk3_bif_pixel_t)0;
+ dk3_bif_coord_t vi;
+
+ if(bp) {
+ if(bp->cf) {
+ if(bp->implspec) {
+ if((bp->cf)->implspec) {
+ dis = (dk3_bif_png_t *)(bp->implspec);
+ fdis = (dk3_bif_frame_png_t *)((bp->cf)->implspec);
+ if(fdis->rows) {
+ row = (fdis->rows)[y];
+ vi = 0L;
+ switch(dis->ct) {
+ case PNG_COLOR_TYPE_GRAY: {
+ vi = x;
+ } break;
+ case PNG_COLOR_TYPE_GRAY_ALPHA: {
+ vi = 2L * x;
+ if(c == 3) { vi = vi + 1; }
+ } break;
+ case PNG_COLOR_TYPE_RGB: {
+ vi = 3L * x;
+ if((c >= 0) && (c < 3)) {
+ vi = vi + (dk3_bif_coord_t)c;
+ }
+ } break;
+ case PNG_COLOR_TYPE_RGB_ALPHA: {
+ vi = 4L * x;
+ if((c >= 0) && (c < 4)) {
+ vi = vi + (dk3_bif_coord_t)c;
+ }
+ } break;
+ default: {
+ /*
+ Must not happen, we requested conversion from
+ palette to RGB.
+ */
+ } break;
+ }
+ back = dk3pixre_get_value_from_packed_bytes(
+ (unsigned char const *)row,
+ vi,
+ (bp->cf)->bits
+ );
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+#endif
+/* if DK3_HAVE_PNG_H */
+
+
+
+#if DK3_HAVE_JPEGLIB_H
+/*
+ JPEGLIB error management.
+*/
+/** JPEGLIB error manager.
+*/
+typedef struct {
+ struct jpeg_error_mgr pub; /**< Default error manager. */
+#if DK3_HAVE_SETJMP_H
+ jmp_buf setjmp_buffer; /**< Buffer for setjmp. */
+#endif
+} dk3_bif_jpg_error_mgr;
+
+/** Per frame data, JPEG-specific.
+*/
+typedef struct {
+ JSAMPLE **rows; /**< Sample buffer. */
+ JDIMENSION w; /**< Image width. */
+ JDIMENSION h; /**< Image height. */
+ int is_adobe; /**< Flag: Adobe marker found. */
+ int num_comp; /**< Number of components found. */
+} dk3_bif_frame_jpeg_t;
+
+/** Per file data, JPEG-specific.
+*/
+typedef struct {
+ int st;
+ struct jpeg_decompress_struct cinfo; /**< Decompression struct. */
+ dk3_bif_jpg_error_mgr errmgr; /**< Error manager. */
+} dk3_bif_jpeg_t;
+
+/** Error exit replacement function.
+ @param cinfo JPEG decompression structure.
+*/
+static
+void
+dk3bif_jpeg_error_exit(j_common_ptr cinfo)
+{
+ dk3_bif_jpg_error_mgr *myerr = (dk3_bif_jpg_error_mgr *)(cinfo->err);
+ if(myerr) {
+ longjmp(myerr->setjmp_buffer, 1);
+ }
+}
+
+/** Release type-specific information for JPEG file (frame).
+ @param is Bitmap-type specific data.
+*/
+static
+void
+dk3bif_frame_release_implspec_jpeg(void *is)
+{
+ dk3_bif_frame_jpeg_t *fdis;
+ JSAMPLE **ptr;
+ JDIMENSION i;
+ fdis = (dk3_bif_frame_jpeg_t *)is;
+ if(fdis->rows) {
+ ptr = fdis->rows;
+ for(i = 0; i < fdis->h; i++) {
+ dk3_release(*ptr);
+ ptr++;
+ }
+ dk3_delete(fdis->rows);
+ }
+ dk3_delete(is);
+}
+
+/** Release type specific information for JPEG file (image).
+ @param is Bitmap-type specific data.
+*/
+static
+void
+dk3bif_release_implspec_jpeg(void *is)
+{
+ dk3_bif_jpeg_t *dis;
+ dis = (dk3_bif_jpeg_t *)is;
+ if(dis->st >= 1) {
+#if DK3_HAVE_SETJMP_H
+ if(setjmp((dis->errmgr).setjmp_buffer) == 0) {
+#endif
+ jpeg_destroy_decompress(&(dis->cinfo));
+#if DK3_HAVE_SETJMP_H
+ }
+#endif
+ }
+ dk3_delete(dis);
+}
+
+/** Read header for JPEG image.
+ @param bp Bitmap image file.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bif_read_jpeg_header(dk3_bif_t *bp)
+{
+ dk3_bif_jpeg_t *dis = NULL;
+ dk3_bif_frame_jpeg_t *fdis = NULL;
+ int back = 0;
+
+
+#line 1037 "dk3bif.ctr"
+ bp->cf = dk3bif_frame_new(bp);
+ if(bp->cf) {
+ dis = dk3_new_app(dk3_bif_jpeg_t,1,bp->app);
+ if(dis) {
+ bp->implspec = (void *)dis;
+ dis->st = 0; /* Initial state. */
+ (dis->errmgr).pub.error_exit = dk3bif_jpeg_error_exit;
+ (dis->cinfo).err = jpeg_std_error(&((dis->errmgr).pub));
+ (dis->errmgr).pub.error_exit = dk3bif_jpeg_error_exit;
+#if DK3_HAVE_SETJMP_H
+ if(setjmp((dis->errmgr).setjmp_buffer) == 0) {
+#endif
+ jpeg_create_decompress(&(dis->cinfo));
+ dis->st = 1; /* Decompress created. */
+ if(bp->tmpfipo) {
+ jpeg_stdio_src(&(dis->cinfo), bp->tmpfipo);
+ dis->st = 2;
+ jpeg_read_header(&(dis->cinfo), TRUE);
+ dis->st = 3;
+ fdis = dk3_new_app(dk3_bif_frame_jpeg_t,1,bp->app);
+ if(fdis) {
+ (bp->cf)->implspec = (void *)fdis;
+ fdis->is_adobe = 0;
+ fdis->num_comp = (dis->cinfo).num_components;
+
+
+#line 1062 "dk3bif.ctr"
+ fdis->rows = NULL;
+ fdis->w = (dis->cinfo).image_width;
+ fdis->h = (dis->cinfo).image_height;
+ (bp->cf)->w = (dk3_bif_coord_t)(fdis->w);
+ (bp->cf)->h = (dk3_bif_coord_t)(fdis->h);
+ (bp->cf)->realbits = (bp->cf)->bits = 8;
+ switch((dis->cinfo).jpeg_color_space) {
+ case JCS_GRAYSCALE: {
+
+#line 1070 "dk3bif.ctr"
+ (bp->cf)->cs = DK3_COLOR_SPACE_GRAY;
+ } break;
+ case JCS_RGB: {
+
+#line 1073 "dk3bif.ctr"
+ (bp->cf)->cs = DK3_COLOR_SPACE_RGB;
+ } break;
+ case JCS_CMYK: {
+
+#line 1076 "dk3bif.ctr"
+ (bp->cf)->cs = DK3_COLOR_SPACE_CMYK;
+ } break;
+ case JCS_YCCK: {
+
+#line 1079 "dk3bif.ctr"
+ (bp->cf)->cs = DK3_COLOR_SPACE_CMYK;
+ } break;
+ case JCS_YCbCr: {
+
+#line 1082 "dk3bif.ctr"
+ (bp->cf)->cs = DK3_COLOR_SPACE_YCbCr;
+ } break;
+ default: {
+ /* No setting available (yet). */
+ } break;
+ }
+ if((dis->cinfo).saw_JFIF_marker) {
+ switch((dis->cinfo).density_unit) {
+ case 0x01: { /* per inch */
+ if(((dis->cinfo).X_density) && ((dis->cinfo).Y_density)) {
+ (bp->cf)->xres = (double)((dis->cinfo).X_density);
+ (bp->cf)->yres = (double)((dis->cinfo).Y_density);
+ }
+ } break;
+ case 0x02: { /* per cm */
+ if(((dis->cinfo).X_density) && ((dis->cinfo).Y_density)) {
+ (bp->cf)->xres = 2.54 * (double)((dis->cinfo).X_density);
+ (bp->cf)->yres = 2.54 * (double)((dis->cinfo).Y_density);
+ }
+ } break;
+ }
+ }
+ back = 1;
+ if((dis->cinfo).saw_Adobe_marker) {
+ fdis->is_adobe = 1;
+ }
+ }
+ }
+#if DK3_HAVE_SETJMP_H
+ } else {
+ }
+#endif
+ }
+ }
+
+
+#line 1117 "dk3bif.ctr"
+ return back;
+}
+
+/** Read data for JPEG image.
+ @param bp Bitmap image file.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bif_read_jpeg_data(dk3_bif_t *bp)
+{
+ dk3_bif_jpeg_t *dis = NULL;
+ dk3_bif_frame_jpeg_t *fdis = NULL;
+ JSAMPROW *rp = NULL;
+ JDIMENSION y;
+ int back = 0;
+ int ok;
+ int occ;
+
+
+#line 1136 "dk3bif.ctr"
+ if(bp->implspec) {
+
+#line 1137 "dk3bif.ctr"
+ if(bp->cf) {
+
+#line 1138 "dk3bif.ctr"
+ if((bp->cf)->implspec) {
+
+#line 1139 "dk3bif.ctr"
+ dis = (dk3_bif_jpeg_t *)(bp->implspec);
+ fdis = (dk3_bif_frame_jpeg_t *)((bp->cf)->implspec);
+
+#line 1141 "dk3bif.ctr"
+ if(dis->st == 3) {
+
+#line 1142 "dk3bif.ctr"
+#if DK3_HAVE_SETJMP_H
+ if(setjmp((dis->errmgr).setjmp_buffer) == 0) {
+
+#line 1144 "dk3bif.ctr"
+#endif
+ dis->st = 4; /* We attempted to continue. */
+ jpeg_start_decompress(&(dis->cinfo));
+ dis->st = 5; /* Decompression started. */
+ fdis->rows = dk3_new_app(JSAMPROW,fdis->h,bp->app);
+ if(fdis->rows) {
+
+#line 1150 "dk3bif.ctr"
+ occ = (dis->cinfo).out_color_components;
+ ok = 1;
+
+#line 1152 "dk3bif.ctr"
+ rp = fdis->rows;
+
+#line 1153 "dk3bif.ctr"
+ for(y = 0; y < fdis->h; y++) { *(rp++) = NULL; }
+ occ = occ * fdis->w;
+
+#line 1155 "dk3bif.ctr"
+ rp = fdis->rows;
+ for(y = 0; y < fdis->h; y++) {
+
+#line 1157 "dk3bif.ctr"
+ *rp = dk3_new_app(JSAMPLE,occ,bp->app);
+ if(!(*rp)) {
+ ok = 0;
+
+#line 1160 "dk3bif.ctr"
+ }
+ rp++;
+ }
+ if(ok) {
+
+#line 1164 "dk3bif.ctr"
+ dis->st = 6; /* Decompression started. */
+ rp = fdis->rows;
+
+#line 1166 "dk3bif.ctr"
+ for(y = 0; y < fdis->h; y++) {
+
+#line 1167 "dk3bif.ctr"
+ jpeg_read_scanlines(&(dis->cinfo), rp, 1);
+ rp++;
+
+#line 1169 "dk3bif.ctr"
+ }
+
+#line 1170 "dk3bif.ctr"
+ dis->st = 7; /* Data was read successfully. */
+ jpeg_finish_decompress(&(dis->cinfo));
+
+#line 1172 "dk3bif.ctr"
+ dis->st = 8; /* Decompression finished. */
+ switch((dis->cinfo).out_color_space) {
+ case JCS_GRAYSCALE: {
+
+#line 1175 "dk3bif.ctr"
+ (bp->cf)->cs = DK3_COLOR_SPACE_GRAY;
+ back = 1;
+ } break;
+ case JCS_RGB: {
+
+#line 1179 "dk3bif.ctr"
+ (bp->cf)->cs = DK3_COLOR_SPACE_RGB;
+ back = 1;
+ } break;
+ default: {
+ (bp->cf)->cs = 0;
+ } break;
+ }
+ } else {
+ }
+ } else {
+
+#line 1189 "dk3bif.ctr"
+ }
+#if DK3_HAVE_SETJMP_H
+ } else {
+ }
+#endif
+ } else {
+
+#line 1195 "dk3bif.ctr"
+ }
+ } else {
+
+#line 1197 "dk3bif.ctr"
+ }
+ } else {
+
+#line 1199 "dk3bif.ctr"
+ }
+ }
+
+#line 1201 "dk3bif.ctr"
+ return back;
+}
+
+/** Retrieve one pixel component from JPEG.
+ @param bp Bitmap image.
+ @param x X coordinate.
+ @param y Y coordinate.
+ @param c Choose component: 0=red/gray, 1=green, 2=blue, 3=alpha.
+ @return Pixel component.
+*/
+static
+dk3_bif_pixel_t
+dk3bif_get_jpeg_pixel_component(
+ dk3_bif_t *bp,
+ dk3_bif_coord_t x,
+ dk3_bif_coord_t y,
+ int c
+)
+{
+#if VERSION_BEFORE_20150821
+ dk3_bif_jpeg_t *dis = NULL;
+#endif
+ dk3_bif_frame_jpeg_t *fdis = NULL;
+ dk3_bif_pixel_t back = (dk3_bif_pixel_t)0;
+ JSAMPLE value;
+ JSAMPLE *row;
+ if(bp) {
+ if(bp->cf) {
+ if(bp->implspec) {
+ if((bp->cf)->implspec) {
+#if VERSION_BEFORE_20150821
+ dis = (dk3_bif_jpeg_t *)(bp->implspec);
+#endif
+ fdis = (dk3_bif_frame_jpeg_t *)((bp->cf)->implspec);
+ if(c == 3) {
+ back = 255;
+ } else {
+ switch((bp->cf)->cs) {
+ case DK3_COLOR_SPACE_GRAY: {
+ if((c >= 0) && (c < 3)) {
+ if(fdis->rows) {
+ row = (fdis->rows)[y];
+ if(row) {
+ value = row[x];
+ back = (dk3_bif_pixel_t)value;
+ back &= 0x00FFU;
+ }
+ }
+ }
+ } break;
+ case DK3_COLOR_SPACE_RGB: {
+ if((c >= 0) && (c < 3)) {
+ if(fdis->rows) {
+ row = (fdis->rows)[y];
+ if(row) {
+ value = row[3 * x + c];
+ back = (dk3_bif_pixel_t)value;
+ back &= 0x00FFU;
+ }
+ }
+ }
+ } break;
+ }
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+#endif
+/* if DK3_HAVE_JPEGLIB_H */
+
+
+
+#if DK3_HAVE_TIFF_H
+/** Per frame data, TIFF-specific.
+*/
+typedef struct {
+ uint32 *r; /**< Raster image data. */
+ uint32 w; /**< Image width. */
+ uint32 h; /**< Image height. */
+ uint16 cps;
+ uint16 spp;
+ uint16 ori; /**< Orientation. */
+} dk3_bif_frame_tiff_t;
+
+/** Per file data, TIFF-specific.
+*/
+typedef struct {
+ TIFF *tiff;
+} dk3_bif_tiff_t;
+
+/** Release type-specific information for TIFF file.
+ @param is Bitmap-type specific data.
+*/
+static
+void
+dk3bif_frame_release_implspec_tiff(void *is)
+{
+ dk3_bif_frame_tiff_t *fdis;
+ fdis = (dk3_bif_frame_tiff_t *)is;
+ if(fdis->r) {
+ _TIFFfree(fdis->r);
+ fdis->r = NULL;
+ }
+ fdis->w = fdis->h = 0UL; fdis->spp = fdis->cps = 0U;
+ dk3_delete(fdis);
+}
+
+/** Release type specific information for TIFF file (image).
+ @param is Bitmap-type specific data.
+*/
+static
+void
+dk3bif_release_implspec_tiff(void *is)
+{
+ dk3_bif_tiff_t *dis;
+ dis = (dk3_bif_tiff_t *)is;
+ if(dis->tiff) {
+ TIFFClose(dis->tiff); dis->tiff = NULL;
+ }
+ dk3_delete(dis);
+}
+
+
+
+
+/** Read header for TIFF image.
+ @param bp Bitmap image file.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bif_read_tiff_header(dk3_bif_t *bp)
+{
+ dk3_bif_frame_tiff_t *fdis;
+ dk3_bif_tiff_t *dis;
+ float rv;
+#if VERSION_BEFORE_20140809
+ unsigned long wh = 0UL;
+#else
+ dk3_um_t wh = DK3_UM_0;
+#endif
+ uint32 w;
+ uint32 h;
+ int back = 0;
+ int me = 0;
+ size_t sz;
+#if VERSION_BEFORE_20150821
+ uint16 cps;
+ uint16 spp;
+#endif
+ uint16 ru;
+ uint16 orient;
+
+
+#line 1357 "dk3bif.ctr"
+ if(bp->tmpfn) {
+
+#line 1358 "dk3bif.ctr"
+ dis = dk3_new_app(dk3_bif_tiff_t,1,bp->app);
+ if(dis) {
+
+#line 1360 "dk3bif.ctr"
+ /*
+ Initialization of TIFF per file.
+ */
+ bp->implspec = (void *)dis;
+ dis->tiff = NULL;
+ dis->tiff = TIFFOpen(bp->tmpfn, "rb");
+ if(dis->tiff) {
+
+#line 1367 "dk3bif.ctr"
+ back = 1;
+ do {
+
+#line 1369 "dk3bif.ctr"
+ w = h = 0UL; rv = 0.0; ru = 0;
+#if VERSION_BEFORE_20150821
+ cps = spp = 0U;
+#endif
+ bp->cf = dk3bif_frame_new(bp);
+ if(bp->cf) {
+
+#line 1375 "dk3bif.ctr"
+ (bp->cf)->realbits = (bp->cf)->bits = 8;
+ (bp->cf)->cs = DK3_COLOR_SPACE_RGBA;
+ fdis = dk3_new_app(dk3_bif_frame_tiff_t,1,bp->app);
+ if(fdis) {
+
+#line 1379 "dk3bif.ctr"
+ /*
+ Initialize TIFF per frame.
+ */
+ fdis->w = fdis->h = 0UL; fdis->cps = fdis->spp = 0U;
+ fdis->r = NULL;
+ fdis->ori = ORIENTATION_BOTLEFT;
+ (bp->cf)->implspec = (void *)fdis;
+ if(TIFFGetField(dis->tiff, TIFFTAG_IMAGEWIDTH, &w) == 1) {
+ fdis->w = w;
+
+#line 1388 "dk3bif.ctr"
+ (bp->cf)->w = (dk3_bif_coord_t)w;
+ if(TIFFGetField(dis->tiff, TIFFTAG_IMAGELENGTH, &h) == 1) {
+ fdis->h = h;
+
+#line 1391 "dk3bif.ctr"
+ (bp->cf)->h = (dk3_bif_coord_t)h;
+ rv = 0.0;
+ if(TIFFGetField(dis->tiff, TIFFTAG_XRESOLUTION, &rv) == 1) {
+ (bp->cf)->xres = (double)rv;
+
+#line 1395 "dk3bif.ctr"
+ }
+ rv = 0.0;
+ if(TIFFGetField(dis->tiff, TIFFTAG_YRESOLUTION, &rv) == 1) {
+ (bp->cf)->yres = (double)rv;
+
+#line 1399 "dk3bif.ctr"
+ }
+ ru = 0;
+ if(TIFFGetField(dis->tiff, TIFFTAG_RESOLUTIONUNIT, &ru) == 1)
+ {
+
+#line 1403 "dk3bif.ctr"
+ switch(ru) {
+ case RESUNIT_CENTIMETER: {
+
+#line 1405 "dk3bif.ctr"
+ (bp->cf)->xres = 2.54 * (bp->cf)->xres;
+ (bp->cf)->yres = 2.54 * (bp->cf)->yres;
+ } break;
+ case RESUNIT_NONE: {
+
+#line 1409 "dk3bif.ctr"
+ (bp->cf)->xres = (bp->cf)->yres = -1.0;
+ } break;
+ }
+ }
+ orient = ORIENTATION_TOPLEFT;
+ if(TIFFGetFieldDefaulted(
+ dis->tiff, TIFFTAG_ORIENTATION, &orient
+ ) == 1
+ )
+ {
+
+#line 1419 "dk3bif.ctr"
+ fdis->ori = orient;
+ switch(orient) {
+ case 5: case 6: case 7: case 8: {
+
+#line 1422 "dk3bif.ctr"
+ fdis->h = w;
+ (bp->cf)->h = w;
+ fdis->w = h;
+ (bp->cf)->w = h;
+ rv = (float)((bp->cf)->xres);
+ (bp->cf)->xres = (bp->cf)->yres;
+ (bp->cf)->yres = rv;
+ } break;
+ }
+ } else {
+ orient = ORIENTATION_TOPLEFT;
+ }
+#if VERSION_BEFORE_20140809
+ wh = dk3ma_ul_mul_ok(w, h, &me);
+ wh = dk3ma_ul_mul_ok(4UL, wh, &me);
+#else
+ wh = dk3ma_um_mul_ok((dk3_um_t)w, (dk3_um_t)h, &me);
+ wh = dk3ma_um_mul_ok((dk3_um_t)4U, wh, &me);
+#endif
+ if(me) {
+ back = 0;
+
+#line 1443 "dk3bif.ctr"
+ } else {
+
+#line 1444 "dk3bif.ctr"
+#if VERSION_BEFORE_20140809
+ sz = (size_t)wh;
+ if(wh == (unsigned long)sz)
+#else
+ sz = dk3ma_um_to_sz(wh, &me);
+ if (0 != sz)
+#endif
+ {
+
+#line 1452 "dk3bif.ctr"
+ fdis->r = (uint32 *)_TIFFmalloc(sz);
+ if(fdis->r) {
+
+#line 1454 "dk3bif.ctr"
+ if(TIFFReadRGBAImageOriented(
+ dis->tiff, w, h, fdis->r, orient, 0
+ )
+ )
+ {
+#if TRACE_DEBUG || VERSION_BEFORE_20150821
+ back = 1;
+
+#line 1461 "dk3bif.ctr"
+#endif
+ } else {
+
+#line 1463 "dk3bif.ctr"
+ back = 0;
+ }
+ } else {
+
+#line 1466 "dk3bif.ctr"
+ back = 0;
+ }
+ } else {
+ back = 0;
+
+#line 1470 "dk3bif.ctr"
+ }
+ }
+ } else {
+
+#line 1473 "dk3bif.ctr"
+ back = 0;
+ }
+ } else {
+
+#line 1476 "dk3bif.ctr"
+ back = 0;
+ }
+ } else {
+ back = 0;
+
+#line 1480 "dk3bif.ctr"
+ }
+ } else {
+ back = 0;
+
+#line 1483 "dk3bif.ctr"
+ }
+ w = h = 0UL;
+#if VERSION_BEFORE_20150821
+ cps = spp = 0U;
+#endif
+
+
+#line 1489 "dk3bif.ctr"
+ } while((back == 1) && TIFFReadDirectory(dis->tiff));
+ TIFFClose(dis->tiff); dis->tiff = NULL;
+
+#line 1491 "dk3bif.ctr"
+ if(bp->i_frames) {
+
+#line 1492 "dk3bif.ctr"
+ dk3sto_it_reset(bp->i_frames);
+ bp->cf = (dk3_bif_frame_t *)dk3sto_it_next(bp->i_frames);
+ if(!(bp->cf)) {
+
+#line 1495 "dk3bif.ctr"
+ back = 0;
+ }
+ } else {
+
+#line 1498 "dk3bif.ctr"
+ }
+ } else {
+
+#line 1500 "dk3bif.ctr"
+ }
+ } else {
+
+#line 1502 "dk3bif.ctr"
+ }
+ } else {
+
+#line 1504 "dk3bif.ctr"
+ }
+
+#line 1505 "dk3bif.ctr"
+ return back;
+}
+
+
+
+
+/** Read data for TIFF image.
+ @param bp Bitmap image file.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bif_read_tiff_data(dk3_bif_t *bp)
+{
+ int back = 0;
+ if(bp->i_frames) {
+ dk3sto_it_reset(bp->i_frames);
+ bp->cf = (dk3_bif_frame_t *)dk3sto_it_next(bp->i_frames);
+ if(bp->cf) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+/** Retrieve one pixel component from TIFF.
+ @param bp Bitmap image.
+ @param x X coordinate.
+ @param y Y coordinate.
+ @param c Choose component: 0=red/gray, 1=green, 2=blue, 3=alpha.
+ @return Pixel component.
+*/
+static
+dk3_bif_pixel_t
+dk3bif_get_tiff_pixel_component(
+ dk3_bif_t *bp,
+ dk3_bif_coord_t x,
+ dk3_bif_coord_t y,
+ int c
+)
+{
+ dk3_bif_frame_tiff_t *fdis;
+ dk3_bif_pixel_t back = (dk3_bif_pixel_t)0;
+ uint32 uv;
+ if(bp) {
+ if(bp->cf) {
+ if(bp->implspec) {
+ if((bp->cf)->implspec) {
+ fdis = (dk3_bif_frame_tiff_t *)((bp->cf)->implspec);
+ if(fdis->r) {
+ uv = (fdis->r)[y * (bp->cf)->w + x];
+ /*
+ uv = (fdis->r)[((bp->cf)->h - y - 1) * (bp->cf)->w + x];
+ */
+ switch(c) {
+ case 3: {
+ uv = ((uv >> 24) & 0x000000FFUL);
+ } break;
+ case 2: {
+ uv = ((uv >> 16) & 0x000000FFUL);
+ } break;
+ case 1: {
+ uv = ((uv >> 8) & 0x000000FFUL);
+ } break;
+ default: {
+ uv = (uv & 0x000000FFUL);
+ } break;
+ }
+ back = (dk3_bif_pixel_t)uv;
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+#endif
+/* if DK3_HAVE_TIFF_H */
+
+
+
+/** Calculate gray value from red, green, blue.
+ @param r Red value.
+ @param g Green value.
+ @param b Blue value.
+ @return Gray value.
+*/
+static
+dk3_bif_pixel_t
+dk3bif_ntsc(dk3_bif_pixel_t r, dk3_bif_pixel_t g, dk3_bif_pixel_t b)
+{
+ dk3_bif_pixel_t back;
+ back = (dk3_bif_pixel_t)(
+ (
+ 30UL * (unsigned long)r
+ + 59UL * (unsigned long)g
+ + 11UL * (unsigned long)b
+ ) / 100UL
+ );
+ return back;
+}
+
+
+
+/** Delete BIF frame, release memory.
+ @param tp Image type.
+ @param fp Frame to delete.
+*/
+static
+void
+dk3bif_frame_delete(dk3_bif_frame_t *fp, int tp)
+{
+
+
+#line 1618 "dk3bif.ctr"
+ if(fp) {
+ /*
+ Release type-depending components.
+ */
+ if(fp->implspec) {
+ switch(tp) {
+ case DK3_BIF_IMAGE_TYPE_PNG: {
+#if DK3_HAVE_PNG_H
+ dk3bif_frame_release_implspec_png(fp->implspec);
+#endif
+ } break;
+ case DK3_BIF_IMAGE_TYPE_JPEG: {
+#if DK3_HAVE_JPEGLIB_H
+ dk3bif_frame_release_implspec_jpeg(fp->implspec);
+#endif
+ } break;
+ case DK3_BIF_IMAGE_TYPE_TIFF: {
+#if DK3_HAVE_TIFF_H
+ dk3bif_frame_release_implspec_tiff(fp->implspec);
+#endif
+ } break;
+ }
+ }
+ fp->implspec = NULL;
+ /*
+ Release type-independent components.
+ */
+ fp->w = fp->h = 0L; fp->realbits = fp->bits = fp->n = 0; fp->cs = 0;
+ /*
+ Release frame itself.
+ */
+ dk3_delete(fp);
+ }
+
+#line 1651 "dk3bif.ctr"
+}
+
+
+
+/** Allocate memory for new frame.
+ @param bp Bitmap image file.
+ @return Pointer to new frame on success, NULL on error.
+*/
+static
+dk3_bif_frame_t *
+dk3bif_frame_new(dk3_bif_t *bp)
+{
+ dk3_bif_frame_t *back = NULL;
+ back = dk3_new_app(dk3_bif_frame_t,1,bp->app);
+ if(back) {
+ back->implspec = NULL;
+ back->xres = -1.0;
+ back->yres = -1.0;
+ back->w = 0L;
+ back->h = 0L;
+ back->realbits = back->bits = 0;
+ back->realcolor = 1;
+ back->realalpha = 1;
+ back->n = bp->n_frames;
+ back->cs = 0;
+ back->bg = 0; back->bgr = back->bgg = back->bgb = back->bggr = 0U;
+ if(dk3sto_add(bp->s_frames, (void *)back)) {
+ bp->n_frames += 1;
+ } else {
+ dk3bif_frame_delete(back, bp->bt); back = NULL;
+ }
+ }
+ return back;
+}
+
+
+
+dk3_bif_pixel_t
+dk3bif_get_pixel_component_not_resampled(
+ dk3_bif_t *bp,
+ dk3_bif_coord_t x,
+ dk3_bif_coord_t y,
+ int c
+)
+{
+ dk3_bif_pixel_t back = (dk3_bif_pixel_t)0;
+
+
+#line 1698 "dk3bif.ctr"
+ if(c == 3) {
+
+#line 1699 "dk3bif.ctr"
+ back = dk3pixre_get_max_value(&(bp->pr));
+ }
+ if((x >= 0L) && (x < (bp->cf)->w)) {
+ if((y >= 0L) && (y < (bp->cf)->h)) {
+ switch(bp->bt) {
+ case DK3_BIF_IMAGE_TYPE_PNG: {
+#if DK3_HAVE_PNG_H
+ back = dk3bif_get_png_pixel_component(bp, x, y, c);
+#endif
+ } break;
+ case DK3_BIF_IMAGE_TYPE_JPEG: {
+#if DK3_HAVE_JPEGLIB_H
+ back = dk3bif_get_jpeg_pixel_component(bp, x, y, c);
+#endif
+ } break;
+ case DK3_BIF_IMAGE_TYPE_TIFF: {
+#if DK3_HAVE_TIFF_H
+ back = dk3bif_get_tiff_pixel_component(bp, x, y, c);
+#endif
+ } break;
+ }
+ }
+ }
+
+
+#line 1723 "dk3bif.ctr"
+ return back;
+}
+
+
+
+/** Retrieve one pixel component resampled to output bit size.
+ @param bp Bitmap image.
+ @param x X coordinate.
+ @param y Y coordinate.
+ @param c Choose component: 0=red/gray, 1=green, 2=blue, 3=alpha.
+ @return Pixel component.
+*/
+static
+dk3_bif_pixel_t
+dk3bif_get_pixel_component(
+ dk3_bif_t *bp,
+ dk3_bif_coord_t x,
+ dk3_bif_coord_t y,
+ int c
+)
+{
+ dk3_bif_pixel_t back;
+
+
+#line 1746 "dk3bif.ctr"
+ /*
+ Get unresampled value.
+ */
+ back = dk3bif_get_pixel_component_not_resampled(bp, x, y, c);
+ /*
+ Resample value to requested output bit size.
+ */
+
+
+#line 1754 "dk3bif.ctr"
+ back = dk3pixre_convert(&(bp->pr), back);
+ return back;
+}
+
+
+/** Compare two frames by number.
+ @param l Left frame.
+ @param r Right frame or number.
+ @param cr Comparison criteria: 0=frame/frame, 1=frame/number.
+ @return Comparison result.
+*/
+static
+int
+dk3bif_frame_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3_bif_frame_t const *pl;
+ dk3_bif_frame_t const *pr;
+ size_t *psz;
+ if(l) {
+ if(r) {
+ pl = (dk3_bif_frame_t const *)l; pr = (dk3_bif_frame_t const *)r;
+ psz = (size_t *)r;
+ switch(cr) {
+ case 1: {
+ if(pl->n > *psz) {
+ back = 1;
+ } else {
+ if(pl->n < *psz) {
+ back = -1;
+ }
+ }
+ } break;
+ default: {
+ if(pl->n > pr->n) {
+ back = 1;
+ } else {
+ if(pl->n < pr->n) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Set up upsampling/downsampling after changing frame or
+ output bit number.
+ @param bp Bitmap image file.
+*/
+static
+void
+dk3bif_set_pixel_sampling(dk3_bif_t *bp)
+{
+
+
+#line 1819 "dk3bif.ctr"
+ if(bp) {
+ if(bp->cf) {
+ if(bp->bits) {
+
+#line 1822 "dk3bif.ctr"
+ dk3pixre_set(&(bp->pr), (bp->cf)->bits, bp->bits);
+ } else {
+
+#line 1824 "dk3bif.ctr"
+ dk3pixre_set(&(bp->pr), (bp->cf)->bits, (bp->cf)->bits);
+ }
+ }
+ }
+
+
+#line 1829 "dk3bif.ctr"
+}
+
+
+
+/** Allocate memory for bitmap image file.
+ @param tp Image type.
+ @param app Application structure for diagnostics, may not be NULL.
+ @return Pointer to new structure on success, NULL on error.
+*/
+static
+dk3_bif_t *
+dk3bif_allocate_app(int tp, dk3_app_t *app)
+{
+ dk3_bif_t *back = NULL;
+ int ok = 0;
+
+
+#line 1845 "dk3bif.ctr"
+ if(app) {
+ back = dk3_new_app(dk3_bif_t,1,app);
+ if(back) {
+ dk3pixre_set(&(back->pr), 8, 8);
+ back->app = app;
+ back->tmpfn = NULL;
+ back->tmpfipo = NULL;
+ back->s_frames = NULL;
+ back->i_frames = NULL;
+ back->cf = NULL;
+ back->implspec = NULL;
+ back->n = dk3bif_temp_number++;
+ back->n_frames = 0;
+ back->bits = 0;
+ back->bt = tp;
+ back->bg = 0;
+ back->remtmpf = 0;
+ back->bgr = back->bgg = back->bgb = 255U;
+ back->s_frames = dk3sto_open_app(app);
+ if(back->s_frames) {
+ dk3sto_set_comp(back->s_frames, dk3bif_frame_compare, 0);
+ back->i_frames = dk3sto_it_open(back->s_frames);
+ if(back->i_frames) {
+ ok = 1;
+ }
+ }
+ if(!(ok)) {
+ dk3bif_close(back);
+ back = NULL;
+ }
+ }
+ }
+
+#line 1877 "dk3bif.ctr"
+ return back;
+}
+
+
+
+/** Read image header information.
+ Create the frames, fill implspec for bif and frame.
+ @param bp Bitmap image file.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bif_read_header(dk3_bif_t *bp)
+{
+ int back = 0;
+
+
+#line 1893 "dk3bif.ctr"
+ switch(bp->bt) {
+ case DK3_BIF_IMAGE_TYPE_PNG: {
+#if DK3_HAVE_PNG_H
+ back = dk3bif_read_png_header(bp);
+#endif
+ } break;
+ case DK3_BIF_IMAGE_TYPE_JPEG: {
+#if DK3_HAVE_JPEGLIB_H
+ back = dk3bif_read_jpeg_header(bp);
+#endif
+ } break;
+ case DK3_BIF_IMAGE_TYPE_TIFF: {
+#if DK3_HAVE_TIFF_H
+ back = dk3bif_read_tiff_header(bp);
+#endif
+ } break;
+ }
+ dk3bif_set_pixel_sampling(bp);
+
+
+#line 1912 "dk3bif.ctr"
+ return back;
+}
+
+
+
+/** Create a temporary file name (8 bit characters).
+ @param fnb File name buffer.
+ @param bp Bitmap image file pointer.
+*/
+static
+void
+dk3bif_create_tmpfilename(char *fnb, dk3_bif_t *bp)
+{
+
+
+#line 1926 "dk3bif.ctr"
+#if DK3_ON_WINDOWS
+ sprintf(fnb, dk3bif_kw_c8[1], _getpid(), bp->n);
+#else
+#if DK3_HAVE_GETPID
+ sprintf(fnb, dk3bif_kw_c8[0], (unsigned long)getpid(), bp->n);
+#else
+ time_t timer;
+ time(&timer);
+ sprintf(fnb, dk3bif_kw_c8[0], (unsigned long)timer, bp->n);
+#endif
+#endif
+
+
+#line 1938 "dk3bif.ctr"
+}
+
+
+
+/** Copy input file to temporary file.
+ This function relies on tmpfn set.
+ @param bp Bitmap image file.
+ @param fipos Source file, must be opened "rb".
+ @param app Application structure for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bif_copy_to_temp(dk3_bif_t *bp, FILE *fipos, dk3_app_t *app)
+{
+ char bu[4096]; /* Buffer. */
+ FILE *fipod; /* Destination file. */
+ int back = 0;
+ int cc = 1; /* Flag: Can continue copying. */
+ size_t rdb; /* Bytes read. */
+
+
+#line 1959 "dk3bif.ctr"
+ fipod = dk3sf_c8_fopen_app(bp->tmpfn, "wb", app);
+ if(fipod) {
+ back = 1;
+ while(cc) {
+ cc = 0;
+ rdb = dk3sf_fread_app(bu, 1, sizeof(bu), fipos, app);
+ if(rdb > 0) {
+ if(dk3sf_fwrite_app(bu, 1, rdb, fipod, app)) {
+ cc = 1;
+ } else {
+ back = 0;
+ }
+ }
+ }
+#if DK3_CHAR_SIZE == 1
+ if(!dk3sf_fclose_fn_app(fipod, bp->tmpfn, app)) {
+ back = 0;
+ }
+#else
+ if(!dk3sf_fclose_fn_app(fipod, NULL, app)) {
+ back = 0;
+ }
+#endif
+ }
+
+#line 1983 "dk3bif.ctr"
+ return back;
+}
+
+
+
+/** Correct image type.
+ @param tp Original image type, may need correction.
+ @return Corrected value (set to DK3_BIF_IMAGE_TYPE_UNKNOWN
+ if necessary).
+*/
+static
+int
+dk3bif_correct_type(int tp)
+{
+ int back;
+ back = tp;
+
+
+#line 2000 "dk3bif.ctr"
+ if(tp != DK3_BIF_IMAGE_TYPE_PNG) {
+ if(tp != DK3_BIF_IMAGE_TYPE_JPEG) {
+ if(tp != DK3_BIF_IMAGE_TYPE_TIFF) {
+ /* +++ further file types here +++ */
+ back = DK3_BIF_IMAGE_TYPE_UNKNOWN;
+ }
+ }
+ }
+
+#line 2008 "dk3bif.ctr"
+ return back;
+}
+
+
+
+dk3_bif_t *
+dk3bif_open_filename_app(dkChar const *fn, int tp, dk3_app_t *app)
+{
+ char fnb[128]; /* File name buffer for temp file. */
+ dk3_bif_t *back = NULL;
+ FILE *fipos;
+ int mytp; /* Type, corrected if necessary. */
+ int ok = 0; /* Flag: Success. */
+
+
+#line 2022 "dk3bif.ctr"
+ mytp = dk3bif_correct_type(tp);
+ if((fn) && (app)) {
+ if(mytp == DK3_BIF_IMAGE_TYPE_UNKNOWN) {
+ mytp = dk3bif_check_file_name(fn);
+ }
+ if(dk3bif_type_supported(mytp)) {
+ back = dk3bif_allocate_app(mytp, app);
+ if(back) {
+ switch(back->bt) {
+ case DK3_BIF_IMAGE_TYPE_TIFF: {
+ dk3bif_create_tmpfilename(fnb, back);
+ back->tmpfn = dk3str_c8_dup_app(fnb, NULL);
+ if(back->tmpfn) {
+ back->remtmpf = 1;
+ fipos = dk3sf_fopen_app(fn, dk3bif_kw_dk[0], app);
+ if(fipos) {
+ ok = dk3bif_copy_to_temp(back, fipos, app);
+ fclose(fipos);
+ if(ok) {
+ ok = dk3bif_read_header(back);
+ }
+ }
+ }
+ } break;
+ default: {
+ back->tmpfipo = dk3sf_fopen_app(fn, dk3bif_kw_dk[0], app);
+ if(back->tmpfipo) {
+ ok = dk3bif_read_header(back);
+ }
+ } break;
+ }
+ if(!(ok)) {
+ dk3bif_close(back); back = NULL;
+ }
+ }
+ } else {
+ if(app) {
+ /* ERROR: File type unknown or unsupported! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 257);
+ }
+ }
+ }
+
+#line 2064 "dk3bif.ctr"
+ return back;
+}
+
+
+dk3_bif_t *
+dk3bif_open_c8_filename_app(char const *fn, int tp, dk3_app_t *app)
+{
+ dk3_bif_t *back = NULL;
+ int mytp; /* Type, corrected if necessary. */
+ int ok = 0; /* Flag: Success. */
+
+
+#line 2075 "dk3bif.ctr"
+ mytp = dk3bif_correct_type(tp);
+ if((fn) && (app)) {
+ if(mytp == DK3_BIF_IMAGE_TYPE_UNKNOWN) {
+ mytp = dk3bif_check_c8_file_name(fn);
+ }
+ if(dk3bif_type_supported(mytp)) {
+ back = dk3bif_allocate_app(mytp, app);
+ if(back) {
+ switch(back->bt) {
+ case DK3_BIF_IMAGE_TYPE_TIFF: {
+ back->tmpfn = dk3str_c8_dup_app(fn, NULL);
+ if(back->tmpfn) {
+ ok = dk3bif_read_header(back);
+ }
+ } break;
+ default: {
+ back->tmpfipo = dk3sf_c8_fopen_app(fn, "rb", app);
+ if(back->tmpfipo) {
+ ok = dk3bif_read_header(back);
+ }
+ } break;
+ }
+ if(!(ok)) {
+ dk3bif_close(back); back = NULL;
+ }
+ }
+ } else {
+ if(app) {
+ /* ERROR: File type unknown or unsupported! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 257);
+ }
+ }
+ }
+
+#line 2108 "dk3bif.ctr"
+ return back;
+}
+
+
+
+dk3_bif_t *
+dk3bif_open_file_app(FILE *fipo, int tp, dk3_app_t *app)
+{
+ char fnb[128];
+ dk3_bif_t *back = NULL;
+ int ok = 0;
+ int mytp;
+
+
+#line 2121 "dk3bif.ctr"
+ mytp = dk3bif_correct_type(tp);
+ if((fipo) && (app) && (mytp != DK3_BIF_IMAGE_TYPE_UNKNOWN)) {
+ if(dk3bif_type_supported(mytp)) {
+ back = dk3bif_allocate_app(mytp, app);
+ if(back) {
+ dk3bif_create_tmpfilename(fnb, back);
+ back->tmpfn = dk3str_c8_dup_app(fnb, NULL);
+ if(back->tmpfn) {
+ back->remtmpf = 1;
+ if(dk3bif_copy_to_temp(back, fipo, app)) {
+ ok = dk3bif_read_header(back);
+ }
+ }
+ if(!(ok)) {
+ dk3bif_close(back); back = NULL;
+ }
+ }
+ } else {
+ /* ERROR: Unknown/unsupported file type! */
+ if(app) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 257);
+ }
+ }
+ }
+
+#line 2145 "dk3bif.ctr"
+ return back;
+}
+
+
+
+void
+dk3bif_close(dk3_bif_t *bp)
+{
+ dk3_bif_frame_t *fp;
+
+
+#line 2155 "dk3bif.ctr"
+ if(bp) {
+ /*
+ Release image type specific data per frame.
+ */
+ if(bp->s_frames) {
+ if(bp->i_frames) {
+ dk3sto_it_reset(bp->i_frames);
+ while((fp = (dk3_bif_frame_t *)dk3sto_it_next(bp->i_frames)) != NULL) {
+ /* Close and delete frame. */
+ dk3bif_frame_delete(fp, bp->bt);
+ }
+ dk3sto_it_close(bp->i_frames);
+ }
+ dk3sto_close(bp->s_frames);
+ }
+ bp->s_frames = NULL; bp->i_frames = NULL; bp->cf = NULL;
+ /*
+ Release image type specific data for file.
+ */
+ if(bp->implspec) {
+ switch(bp->bt) {
+ case DK3_BIF_IMAGE_TYPE_PNG: {
+#if DK3_HAVE_PNG_H
+ dk3bif_release_implspec_png(bp->implspec);
+#endif
+ } break;
+ case DK3_BIF_IMAGE_TYPE_JPEG: {
+#if DK3_HAVE_JPEGLIB_H
+ dk3bif_release_implspec_jpeg(bp->implspec);
+#endif
+ } break;
+ case DK3_BIF_IMAGE_TYPE_TIFF: {
+#if DK3_HAVE_TIFF_H
+ dk3bif_release_implspec_tiff(bp->implspec);
+#endif
+ } break;
+ }
+ }
+ bp->implspec = NULL;
+ bp->n = 0UL;
+ bp->n_frames = 0;
+ bp->bits = 0;
+ bp->bt = DK3_BIF_IMAGE_TYPE_UNKNOWN;
+ /*
+ Close file if open.
+ */
+ if(bp->tmpfipo) {
+
+#line 2202 "dk3bif.ctr"
+ fclose(bp->tmpfipo); bp->tmpfipo = NULL;
+ }
+ /*
+ Delete file and release file name memory.
+ */
+ if(bp->tmpfn) {
+
+#line 2208 "dk3bif.ctr"
+ if(bp->remtmpf) {
+ dk3sf_c8_remove_file_app(bp->tmpfn, bp->app);
+ }
+ dk3_release(bp->tmpfn);
+ }
+ bp->app = NULL;
+ dk3_delete(bp);
+ }
+
+#line 2216 "dk3bif.ctr"
+}
+
+
+
+int
+dk3bif_check_suffix_without_dot(dkChar const *sn)
+{
+ int back = DK3_BIF_IMAGE_TYPE_UNKNOWN;
+ int tp = -1;
+
+
+#line 2226 "dk3bif.ctr"
+ if(sn) {
+ tp = dk3str_array_index(dk3bif_dk_type_names, sn, 0);
+
+#line 2228 "dk3bif.ctr"
+ switch(tp) {
+ case 0: {
+
+#line 2230 "dk3bif.ctr"
+ back = DK3_BIF_IMAGE_TYPE_PNG;
+ } break;
+ case 1: case 2: {
+
+#line 2233 "dk3bif.ctr"
+ back = DK3_BIF_IMAGE_TYPE_JPEG;
+ } break;
+ case 3: case 4: {
+
+#line 2236 "dk3bif.ctr"
+ back = DK3_BIF_IMAGE_TYPE_TIFF;
+ } break;
+ }
+ }
+
+#line 2240 "dk3bif.ctr"
+ return back;
+}
+
+
+
+int
+dk3bif_check_c8_suffix_without_dot(char const *sn)
+{
+ int back = DK3_BIF_IMAGE_TYPE_UNKNOWN;
+ int tp = -1;
+ if(sn) {
+ tp = dk3str_c8_array_index(dk3bif_c8_type_names, sn, 0);
+ switch(tp) {
+ case 0: { back = DK3_BIF_IMAGE_TYPE_PNG; } break;
+ case 1: case 2: { back = DK3_BIF_IMAGE_TYPE_JPEG; } break;
+ case 3: case 4: { back = DK3_BIF_IMAGE_TYPE_TIFF; } break;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3bif_check_file_name(dkChar const *fn)
+{
+ int back = DK3_BIF_IMAGE_TYPE_UNKNOWN;
+ dkChar const *sp;
+
+
+#line 2269 "dk3bif.ctr"
+ if(fn) {
+ sp = dk3str_get_suffix(fn);
+ if(sp) {
+ sp++;
+ back = dk3bif_check_suffix_without_dot(sp);
+ }
+ }
+
+#line 2276 "dk3bif.ctr"
+ return back;
+}
+
+
+
+int
+dk3bif_check_c8_file_name(char const *fn)
+{
+ int back = DK3_BIF_IMAGE_TYPE_UNKNOWN;
+ char const *sp;
+ if(fn) {
+ sp = dk3str_c8_get_suffix(fn);
+ if(sp) {
+ sp++;
+ back = dk3bif_check_c8_suffix_without_dot(sp);
+ }
+ }
+ return back;
+}
+
+
+
+
+/** Transfer background color from image to frame.
+ @param bp Bitmap image file (source).
+ @param fr Frame (destination).
+*/
+void
+dk3_bif_transfer_background(dk3_bif_t *bp, dk3_bif_frame_t *fr)
+{
+ dk3_pixel_resample_t pixre;
+ dk3pixre_set(&pixre, 8, fr->bits);
+ fr->bgr = dk3pixre_convert(&pixre, bp->bgr);
+ fr->bgg = dk3pixre_convert(&pixre, bp->bgg);
+ fr->bgb = dk3pixre_convert(&pixre, bp->bgb);
+}
+
+
+
+int
+dk3bif_read_data(dk3_bif_t *bp)
+{
+ int back = 0;
+ dk3_bif_frame_t *fr = NULL;
+
+
+#line 2321 "dk3bif.ctr"
+ if(bp) {
+ switch(bp->bt) {
+ case DK3_BIF_IMAGE_TYPE_PNG: {
+#if DK3_HAVE_PNG_H
+ back = dk3bif_read_png_data(bp);
+#endif
+ } break;
+ case DK3_BIF_IMAGE_TYPE_JPEG: {
+#if DK3_HAVE_JPEGLIB_H
+
+
+#line 2331 "dk3bif.ctr"
+ back = dk3bif_read_jpeg_data(bp);
+
+
+#line 2333 "dk3bif.ctr"
+#endif
+ } break;
+ case DK3_BIF_IMAGE_TYPE_TIFF: {
+#if DK3_HAVE_TIFF_H
+ back = dk3bif_read_tiff_data(bp);
+#endif
+ } break;
+ }
+ }
+ if(back) {
+ dk3sto_it_reset(bp->i_frames);
+ while((fr = (dk3_bif_frame_t *)dk3sto_it_next(bp->i_frames)) != NULL) {
+ /*
+ The following settings are overwritten by dk3bif_analyze().
+ */
+ switch(fr->cs) {
+ case DK3_COLOR_SPACE_GRAY:
+ case DK3_COLOR_SPACE_GRAY_ALPHA:
+ {
+ fr->realcolor = 0;
+ }
+ break;
+ default:
+ {
+ fr->realcolor = 1;
+ }
+ break;
+ }
+ switch(fr->cs) {
+ case DK3_COLOR_SPACE_GRAY_ALPHA:
+ case DK3_COLOR_SPACE_RGBA: {
+ fr->realalpha = 1;
+ } break;
+ default: {
+ fr->realalpha = 0;
+ } break;
+ }
+ fr->realbits = fr->bits;
+ /*
+ Obtain background color from per-file settings.
+ */
+ if((!(fr->bg)) || (bp->bg)) {
+ dk3_bif_transfer_background(bp, fr);
+ }
+ fr->bggr = dk3bif_ntsc(fr->bgr, fr->bgg, fr->bgb);
+ }
+ dk3sto_it_reset(bp->i_frames);
+ bp->cf = (dk3_bif_frame_t *)dk3sto_it_next(bp->i_frames);
+ if(!(bp->cf)) { back = 0; }
+ }
+ dk3bif_set_pixel_sampling(bp);
+
+
+#line 2385 "dk3bif.ctr"
+ return back;
+}
+
+
+
+size_t
+dk3bif_number_of_frames(dk3_bif_t *bp)
+{
+ size_t back = 0;
+
+
+#line 2395 "dk3bif.ctr"
+ if(bp) {
+ back = bp->n_frames;
+ }
+
+#line 2398 "dk3bif.ctr"
+ return back;
+}
+
+
+
+int
+dk3bif_set_frame(dk3_bif_t *bp, size_t fn)
+{
+ int back = 0;
+
+
+#line 2408 "dk3bif.ctr"
+ if(bp) {
+ bp->cf =
+ (dk3_bif_frame_t *)dk3sto_it_find_like(bp->i_frames, (void *)(&fn), 1);
+ if(bp->cf) {
+ back = 1;
+ dk3bif_set_pixel_sampling(bp);
+ } else {
+ dk3sto_it_reset(bp->i_frames);
+ }
+ }
+
+#line 2418 "dk3bif.ctr"
+ return back;
+}
+
+
+
+size_t
+dk3bif_get_bits_per_pixel(dk3_bif_t *bp)
+{
+ size_t back = 0;
+
+
+#line 2428 "dk3bif.ctr"
+ if(bp) {
+ if(bp->cf) {
+ back = (bp->cf)->bits;
+ }
+ }
+
+#line 2433 "dk3bif.ctr"
+ return back;
+}
+
+
+
+size_t
+dk3bif_real_bits_per_pixel(dk3_bif_t *bp)
+{
+ size_t back = 0;
+
+
+#line 2443 "dk3bif.ctr"
+ if(bp) {
+ if(bp->cf) {
+ back = (bp->cf)->realbits;
+ }
+ }
+
+#line 2448 "dk3bif.ctr"
+ return back;
+}
+
+
+
+int
+dk3bif_real_color(dk3_bif_t *bp)
+{
+ int back = 0;
+ if(bp) {
+ if(bp->cf) {
+ back = (bp->cf)->realcolor;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3bif_real_alpha(dk3_bif_t *bp)
+{
+ int back = 0;
+ if(bp) {
+ if(bp->cf) {
+ back = (bp->cf)->realalpha;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3bif_set_bits_per_pixel(dk3_bif_t *bp, size_t sz)
+{
+ int back = 0;
+
+
+#line 2486 "dk3bif.ctr"
+ if((bp) && (sz)) {
+ if(sz < 17) {
+ bp->bits = sz;
+ dk3bif_set_pixel_sampling(bp);
+ back = 1;
+ } else {
+ bp->bits = 16;
+ dk3bif_set_pixel_sampling(bp);
+ /* Maximum number of bits exceeded! */
+ if(bp->app) {
+ dk3app_log_i1(bp->app, DK3_LL_WARNING, 258);
+ }
+ }
+ }
+
+#line 2500 "dk3bif.ctr"
+ return back;
+}
+
+
+
+dk3_bif_coord_t
+dk3bif_get_width(dk3_bif_t *bp)
+{
+ dk3_bif_coord_t back = 0L;
+
+
+#line 2510 "dk3bif.ctr"
+ if(bp) {
+ if(bp->cf) {
+ back = (bp->cf)->w;
+ }
+ }
+
+#line 2515 "dk3bif.ctr"
+ return back;
+}
+
+
+
+dk3_bif_coord_t
+dk3bif_get_height(dk3_bif_t *bp)
+{
+ dk3_bif_coord_t back = 0L;
+
+
+#line 2525 "dk3bif.ctr"
+ if(bp) {
+ if(bp->cf) {
+ back = (bp->cf)->h;
+ }
+ }
+
+#line 2530 "dk3bif.ctr"
+ return back;
+}
+
+
+
+dk3_bif_coord_t
+dk3bif_get_largest_width(dk3_bif_t *bp)
+{
+ dk3_bif_frame_t *fp;
+ dk3_bif_coord_t back = 0L;
+
+
+#line 2541 "dk3bif.ctr"
+ if(bp) {
+ dk3sto_it_reset(bp->i_frames);
+ while((fp = (dk3_bif_frame_t *)dk3sto_it_next(bp->i_frames)) != NULL) {
+ if(fp->w > back) { back = fp->w; }
+ }
+ }
+
+#line 2547 "dk3bif.ctr"
+ return back;
+}
+
+
+
+dk3_bif_coord_t
+dk3bif_get_largest_height(dk3_bif_t *bp)
+{
+ dk3_bif_frame_t *fp;
+ dk3_bif_coord_t back = 0L;
+
+
+#line 2558 "dk3bif.ctr"
+ if(bp) {
+ dk3sto_it_reset(bp->i_frames);
+ while((fp = (dk3_bif_frame_t *)dk3sto_it_next(bp->i_frames)) != NULL) {
+ if(fp->h > back) { back = fp->h; }
+ }
+ }
+
+
+#line 2565 "dk3bif.ctr"
+ return back;
+}
+
+
+
+dk3_bif_pixel_t
+dk3bif_get_red(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y)
+{
+ dk3_bif_pixel_t back = (dk3_bif_pixel_t)0;
+
+
+#line 2575 "dk3bif.ctr"
+ if(bp) {
+ if(bp->cf) {
+ switch((bp->cf)->cs) {
+ case DK3_COLOR_SPACE_GRAY:
+ case DK3_COLOR_SPACE_GRAY_ALPHA:
+ {
+ back = dk3bif_get_pixel_component(bp, x, y, 0);
+ } break;
+ case DK3_COLOR_SPACE_RGB:
+ case DK3_COLOR_SPACE_RGBA:
+ {
+ back = dk3bif_get_pixel_component(bp, x, y, 0);
+ } break;
+ }
+ }
+ }
+
+#line 2591 "dk3bif.ctr"
+ return back;
+}
+
+
+
+dk3_bif_pixel_t
+dk3bif_get_green(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y)
+{
+ dk3_bif_pixel_t back = (dk3_bif_pixel_t)0;
+
+
+#line 2601 "dk3bif.ctr"
+ if(bp) {
+ if(bp->cf) {
+ switch((bp->cf)->cs) {
+ case DK3_COLOR_SPACE_GRAY:
+ case DK3_COLOR_SPACE_GRAY_ALPHA:
+ {
+ back = dk3bif_get_pixel_component(bp, x, y, 0);
+ } break;
+ case DK3_COLOR_SPACE_RGB:
+ case DK3_COLOR_SPACE_RGBA:
+ {
+ back = dk3bif_get_pixel_component(bp, x, y, 1);
+ } break;
+ }
+ }
+ }
+
+#line 2617 "dk3bif.ctr"
+ return back;
+}
+
+
+
+dk3_bif_pixel_t
+dk3bif_get_blue(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y)
+{
+ dk3_bif_pixel_t back = (dk3_bif_pixel_t)0;
+
+
+#line 2627 "dk3bif.ctr"
+ if(bp) {
+ if(bp->cf) {
+ switch((bp->cf)->cs) {
+ case DK3_COLOR_SPACE_GRAY:
+ case DK3_COLOR_SPACE_GRAY_ALPHA:
+ {
+ back = dk3bif_get_pixel_component(bp, x, y, 0);
+ } break;
+ case DK3_COLOR_SPACE_RGB:
+ case DK3_COLOR_SPACE_RGBA:
+ {
+ back = dk3bif_get_pixel_component(bp, x, y, 2);
+ } break;
+ }
+ }
+ }
+
+#line 2643 "dk3bif.ctr"
+ return back;
+}
+
+
+
+dk3_bif_pixel_t
+dk3bif_get_gray(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y)
+{
+ dk3_bif_pixel_t back = (dk3_bif_pixel_t)0;
+
+
+#line 2653 "dk3bif.ctr"
+ if(bp) {
+ if(bp->cf) {
+ switch((bp->cf)->cs) {
+ case DK3_COLOR_SPACE_GRAY:
+ case DK3_COLOR_SPACE_GRAY_ALPHA:
+ {
+ back = dk3bif_get_pixel_component(bp, x, y, 0);
+ } break;
+ case DK3_COLOR_SPACE_RGB:
+ case DK3_COLOR_SPACE_RGBA:
+ {
+ back = dk3bif_ntsc(
+ dk3bif_get_pixel_component(bp, x, y, 0),
+ dk3bif_get_pixel_component(bp, x, y, 1),
+ dk3bif_get_pixel_component(bp, x, y, 2)
+ );
+ back &= dk3pixre_get_max_value(&(bp->pr));
+
+
+#line 2671 "dk3bif.ctr"
+ } break;
+ }
+ }
+ }
+
+#line 2675 "dk3bif.ctr"
+ return back;
+}
+
+
+
+dk3_bif_pixel_t
+dk3bif_get_alpha(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y)
+{
+ dk3_bif_pixel_t back = (dk3_bif_pixel_t)0;
+
+
+#line 2685 "dk3bif.ctr"
+ if(bp) {
+ back = dk3pixre_get_max_value(&(bp->pr));
+ if(bp->cf) {
+ switch((bp->cf)->cs) {
+ case DK3_COLOR_SPACE_GRAY_ALPHA:
+ case DK3_COLOR_SPACE_RGBA:
+ {
+ back = dk3bif_get_pixel_component(bp, x, y, 3);
+ } break;
+ default: {
+ if((x >= 0L) && (x < (bp->cf)->w)) {
+ if((y >= 0L) && (y < (bp->cf)->h)) {
+ back = dk3pixre_get_max_value(&(bp->pr));
+ }
+ }
+ } break;
+ }
+ }
+ }
+
+#line 2704 "dk3bif.ctr"
+ return back;
+}
+
+
+
+/** Mix pixel value against background value.
+ @param v Pixel value.
+ @param w Background value.
+ @param a Alpha channel value (opacity).
+ @param m Maximum alpha value.
+ @return Mixing result.
+*/
+static
+dk3_bif_pixel_t
+dk3bif_mix(
+ dk3_bif_pixel_t v,
+ dk3_bif_pixel_t w,
+ dk3_bif_pixel_t a,
+ dk3_bif_pixel_t m
+)
+{
+ unsigned long l1, l2, l3, l4, l5, l6;
+ dk3_bif_pixel_t back;
+ dk3_bif_pixel_t b;
+ int me = 0;
+
+ back = v;
+ b = m - a;
+ l1 = (unsigned long)v;
+ l2 = (unsigned long)a;
+ l3 = (unsigned long)w;
+ l4 = (unsigned long)b;
+ l5 = (unsigned long)m;
+ l6 = dk3ma_ul_div_ok(
+ dk3ma_ul_add_ok(
+ dk3ma_ul_mul_ok(l1, l2, &me),
+ dk3ma_ul_mul_ok(l3, l4, &me),
+ &me
+ ),
+ l5,
+ &me
+ );
+ if(me == 0) {
+ back = (((dk3_bif_pixel_t)l6) & m);
+ }
+ return back;
+}
+
+
+
+dk3_bif_pixel_t
+dk3bif_get_mixed_red(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y)
+{
+ dk3_bif_pixel_t back = 0U;
+
+
+#line 2759 "dk3bif.ctr"
+ back = dk3bif_get_red(bp, x, y);
+ if(bp->cf) {
+ switch((bp->cf)->cs) {
+ case DK3_COLOR_SPACE_GRAY_ALPHA: case DK3_COLOR_SPACE_RGBA: {
+ back = dk3bif_mix(
+ back,
+ (bp->cf)->bgr,
+ dk3bif_get_alpha(bp, x, y),
+ dk3pixre_get_max_value(&(bp->pr))
+ );
+ } break;
+ }
+ }
+
+#line 2772 "dk3bif.ctr"
+ return back;
+}
+
+
+
+dk3_bif_pixel_t
+dk3bif_get_mixed_green(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y)
+{
+ dk3_bif_pixel_t back = 0U;
+
+
+#line 2782 "dk3bif.ctr"
+ back = dk3bif_get_green(bp, x, y);
+ if(bp->cf) {
+ switch((bp->cf)->cs) {
+ case DK3_COLOR_SPACE_GRAY_ALPHA: case DK3_COLOR_SPACE_RGBA: {
+ back = dk3bif_mix(
+ back,
+ (bp->cf)->bgg,
+ dk3bif_get_alpha(bp, x, y),
+ dk3pixre_get_max_value(&(bp->pr))
+ );
+ } break;
+ }
+ }
+
+#line 2795 "dk3bif.ctr"
+ return back;
+}
+
+
+
+dk3_bif_pixel_t
+dk3bif_get_mixed_blue(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y)
+{
+ dk3_bif_pixel_t back = 0U;
+
+
+#line 2805 "dk3bif.ctr"
+ back = dk3bif_get_blue(bp, x, y);
+ if(bp->cf) {
+ switch((bp->cf)->cs) {
+ case DK3_COLOR_SPACE_GRAY_ALPHA: case DK3_COLOR_SPACE_RGBA: {
+ back = dk3bif_mix(
+ back,
+ (bp->cf)->bgb,
+ dk3bif_get_alpha(bp, x, y),
+ dk3pixre_get_max_value(&(bp->pr))
+ );
+ } break;
+ }
+ }
+
+#line 2818 "dk3bif.ctr"
+ return back;
+}
+
+
+
+dk3_bif_pixel_t
+dk3bif_get_mixed_gray(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y)
+{
+ dk3_bif_pixel_t back = 0U;
+
+
+#line 2828 "dk3bif.ctr"
+ back = dk3bif_get_gray(bp, x, y);
+ if(bp->cf) {
+ switch((bp->cf)->cs) {
+ case DK3_COLOR_SPACE_GRAY_ALPHA: case DK3_COLOR_SPACE_RGBA: {
+
+#line 2832 "dk3bif.ctr"
+ back = dk3bif_mix(
+ back,
+ (bp->cf)->bggr,
+ dk3bif_get_alpha(bp, x, y),
+ dk3pixre_get_max_value(&(bp->pr))
+ );
+ } break;
+ }
+ }
+
+#line 2841 "dk3bif.ctr"
+ return back;
+}
+
+
+
+int
+dk3bif_type_supported(int tp)
+{
+ int back = 0;
+
+
+#line 2851 "dk3bif.ctr"
+ switch(tp) {
+ case DK3_BIF_IMAGE_TYPE_PNG: {
+#if DK3_HAVE_PNG_H
+ back = 1;
+#endif
+ } break;
+ case DK3_BIF_IMAGE_TYPE_JPEG: {
+#if DK3_HAVE_JPEGLIB_H
+ back = 1;
+#endif
+ } break;
+ case DK3_BIF_IMAGE_TYPE_TIFF: {
+#if DK3_HAVE_TIFF_H
+ back = 1;
+#endif
+ } break;
+ }
+
+#line 2868 "dk3bif.ctr"
+ return back;
+}
+
+
+
+FILE *
+dk3bif_get_file(dk3_bif_t *bp)
+{
+ FILE *back = NULL;
+
+
+#line 2878 "dk3bif.ctr"
+ if(bp) {
+ back = bp->tmpfipo;
+ }
+
+#line 2881 "dk3bif.ctr"
+ return back;
+}
+
+
+
+int
+dk3bif_is_colored(dk3_bif_t *bp)
+{
+ int back = 0;
+ dk3_bif_coord_t x;
+ dk3_bif_coord_t y;
+ dk3_bif_pixel_t r;
+ dk3_bif_pixel_t g;
+ dk3_bif_pixel_t b;
+
+ if(bp) {
+ if(bp->cf) {
+ switch((bp->cf)->cs) {
+ case DK3_COLOR_SPACE_RGB:
+ case DK3_COLOR_SPACE_RGBA: {
+ for(y = 0L; (y < (bp->cf)->h) && (back == 0); y++) {
+ for(x = 0L; (x < (bp->cf)->w) && (back == 0); x++) {
+ r = dk3bif_get_red(bp, x, y);
+ g = dk3bif_get_green(bp, x, y);
+ b = dk3bif_get_blue(bp, x, y);
+ if(r != g) { back = 1; }
+ if(r != b) { back = 1; }
+ }
+ }
+ } break;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+double
+dk3bif_get_xres(dk3_bif_t *bp)
+{
+ double back = -1.0;
+
+
+#line 2924 "dk3bif.ctr"
+ if(bp) {
+ if(bp->cf) {
+ back = (bp->cf)->xres;
+ }
+ }
+
+#line 2929 "dk3bif.ctr"
+ return back;
+}
+
+
+
+double
+dk3bif_get_yres(dk3_bif_t *bp)
+{
+ double back = -1.0;
+
+
+#line 2939 "dk3bif.ctr"
+ if(bp) {
+ if(bp->cf) {
+ back = (bp->cf)->yres;
+ }
+ }
+
+#line 2944 "dk3bif.ctr"
+ return back;
+}
+
+
+
+
+int
+dk3bif_next_frame(dk3_bif_t *bp)
+{
+ int back = 0;
+ if(bp) {
+ if(bp->i_frames) {
+ bp->cf = (dk3_bif_frame_t *)dk3sto_it_next(bp->i_frames);
+ if(bp->cf) {
+ back = 1;
+ dk3bif_set_pixel_sampling(bp);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void
+dk3bif_reset_frames(dk3_bif_t *bp)
+{
+ if(bp) {
+ bp->cf = NULL;
+ dk3sto_it_reset(bp->i_frames);
+ }
+}
+
+
+
+void
+dk3bif_set_background(
+ dk3_bif_t *bp,
+ dk3_bif_pixel_t r,
+ dk3_bif_pixel_t g,
+ dk3_bif_pixel_t b,
+ int f
+)
+{
+ if(bp) {
+ bp->bgr = r; bp->bgg = g; bp->bgb = b; bp->bg = (f ? 1 : 0);
+ }
+}
+
+
+
+int
+dk3bif_get_color_space(dk3_bif_t *bp)
+{
+ int back = 0;
+ if(bp) {
+ if(bp->cf) {
+ back = (bp->cf)->cs;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3bif_get_type(dk3_bif_t *bp)
+{
+ int back = DK3_BIF_IMAGE_TYPE_UNKNOWN;
+ if(bp) {
+ back = bp->bt;
+ }
+ return back;
+}
+
+
+
+
+#line 3021 "dk3bif.ctr"
+
+int
+dk3bif_jpeg_get_num_components(dk3_bif_t *bif)
+{
+ int back = 0;
+#if DK3_HAVE_JPEGLIB_H
+ dk3_bif_frame_jpeg_t *jpf;
+
+
+#line 3029 "dk3bif.ctr"
+ if(bif) {
+
+#line 3030 "dk3bif.ctr"
+ if(bif->cf) {
+
+#line 3031 "dk3bif.ctr"
+ if(bif->bt == DK3_BIF_IMAGE_TYPE_JPEG) {
+
+#line 3032 "dk3bif.ctr"
+ jpf = (dk3_bif_frame_jpeg_t *)((bif->cf)->implspec);
+ if(jpf) {
+
+#line 3034 "dk3bif.ctr"
+ back = jpf->num_comp;
+ } else {
+
+#line 3036 "dk3bif.ctr"
+ }
+ } else {
+
+#line 3038 "dk3bif.ctr"
+ }
+ } else {
+
+#line 3040 "dk3bif.ctr"
+ }
+ } else {
+
+#line 3042 "dk3bif.ctr"
+ }
+
+#line 3043 "dk3bif.ctr"
+#endif
+ return back;
+}
+
+
+
+#line 3048 "dk3bif.ctr"
+
+
+int
+dk3bif_jpeg_get_found_adobe_marker(dk3_bif_t *bif)
+{
+ int back = 0;
+#if DK3_HAVE_JPEGLIB_H
+ dk3_bif_frame_jpeg_t *jpf;
+ if(bif) {
+ if(bif->cf) {
+ if(bif->bt == DK3_BIF_IMAGE_TYPE_JPEG) {
+ jpf = (dk3_bif_frame_jpeg_t *)((bif->cf)->implspec);
+ if(jpf) {
+ back = jpf->is_adobe;
+ }
+ }
+ }
+ }
+#endif
+ return back;
+}
+
+
+
+dk3_bif_pixel_t
+dk3bif_average(dk3_bif_pixel_t left, dk3_bif_pixel_t upper)
+{
+ dk3_bif_pixel_t back;
+ long x;
+ x = (long)left + (long)upper;
+ x = x / 2;
+ back = (dk3_bif_pixel_t)x;
+ return back;
+}
+
+
+
+dk3_bif_pixel_t
+dk3bif_paeth(
+ dk3_bif_pixel_t v1,
+ dk3_bif_pixel_t v2,
+ dk3_bif_pixel_t v3
+)
+{
+ dk3_bif_pixel_t back;
+ long p, pa, pb, pc;
+ p = (long)v1 + (long)v2 - (long)v3;
+ pa = p - (long)v1;
+ pb = p - (long)v2;
+ pc = p - (long)v3;
+ if(pa < 0) { pa = 0L - pa; }
+ if(pb < 0) { pb = 0L - pb; }
+ if(pc < 0) { pc = 0L - pc; }
+ if((pa <= pb) && (pa <= pc)) {
+ back = v1;
+ } else {
+ if(pb <= pc) {
+ back = v2;
+ } else {
+ back = v3;
+ }
+ }
+ return back;
+}
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dk3bif.ctr b/support/dktools/dk3bif.ctr
new file mode 100644
index 0000000000..afc5e90634
--- /dev/null
+++ b/support/dktools/dk3bif.ctr
@@ -0,0 +1,3115 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% header
+
+#include "dk3conf.h"
+#include "dk3types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Check whether a bitmap image file type is supported.
+ @param tp File type to check.
+ @return 1 for supported types, 0 otherwise.
+*/
+int
+dk3bif_type_supported(int tp);
+
+/** Check file name suffix (dkChar).
+ @param sn File name suffix without the dot.
+ @return Bitmap image file type.
+*/
+int
+dk3bif_check_suffix_without_dot(dkChar const *sn);
+
+/** Check file name suffix (char).
+ @param sn File name suffix without the dot.
+ @return Bitmap image file type.
+*/
+int
+dk3bif_check_c8_suffix_without_dot(char const *sn);
+
+/** Check file name suffix (dkChar).
+ @param fn File name to check.
+ @return Bitmap image file type.
+*/
+int
+dk3bif_check_file_name(dkChar const *fn);
+
+/** Check file name suffix (char).
+ @param fn File name to check.
+ @return Bitmap image file type.
+*/
+int
+dk3bif_check_c8_file_name(char const *fn);
+
+/** Open bitmap image file (dkChar).
+ @param fn File name.
+ @param tp Bitmap type.
+ @param app Application structure for diagnostics, may not be NULL.
+ @return Pointer to BIF on success, NULL on error.
+*/
+dk3_bif_t *
+dk3bif_open_filename_app(dkChar const *fn, int tp, dk3_app_t *app);
+
+/** Open bitmap image file (char).
+ @param fn File name.
+ @param tp Bitmap type.
+ @param app Application structure for diagnostics, may not be NULL.
+ @return Pointer to BIF on success, NULL on error.
+*/
+dk3_bif_t *
+dk3bif_open_c8_filename_app(char const *fn, int tp, dk3_app_t *app);
+
+/** Open bitmap image file.
+ @param fipo File, opened for binary reading.
+ @param tp Bitmap type.
+ @param app Application structure for diagnostics, may not be NULL.
+ @return Pointer to BIF on success, NULL on error.
+*/
+dk3_bif_t *
+dk3bif_open_file_app(FILE *fipo, int tp, dk3_app_t *app);
+
+/** Retrieve image type.
+ @param bp Bitmap image file.
+ @return Image type, DK3_BIF_IMAGE_TYPE_xxx, see @ref bifimagetypes.
+*/
+int
+dk3bif_get_type(dk3_bif_t *bp);
+
+/** Get width of current frame.
+ @param bp Bitmap image file.
+ @return Image width.
+*/
+dk3_bif_coord_t
+dk3bif_get_width(dk3_bif_t *bp);
+
+/** Get height of current frame.
+ @param bp Bitmap image file.
+ @return Image height.
+*/
+dk3_bif_coord_t
+dk3bif_get_height(dk3_bif_t *bp);
+
+/** Get width of widest frame.
+ @param bp Bitmap image file.
+ @return Image width.
+*/
+dk3_bif_coord_t
+dk3bif_get_largest_width(dk3_bif_t *bp);
+
+/** Get height of highest frame.
+ @param bp Bitmap image file.
+ @return Image height.
+*/
+dk3_bif_coord_t
+dk3bif_get_largest_height(dk3_bif_t *bp);
+
+/** Set background color on per-file base.
+ Use this function after opening the bitmap image file
+ but before dk3bif_read_data().
+ @param bp Bitmap image file.
+ @param r Red.
+ @param g Green.
+ @param b Blue.
+ @param f Force flag: 0=use background color chunk
+ from file if available, 1=always use the color specified here.
+*/
+void
+dk3bif_set_background(
+ dk3_bif_t *bp,
+ dk3_bif_pixel_t r,
+ dk3_bif_pixel_t g,
+ dk3_bif_pixel_t b,
+ int f
+);
+
+/** Read image data.
+ @param bp Bitmap image file.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3bif_read_data(dk3_bif_t *bp);
+
+/** Find number of frames in image file.
+ @param bp Bitmap image file.
+ @return Number of frames in the file.
+*/
+size_t
+dk3bif_number_of_frames(dk3_bif_t *bp);
+
+/** Set current frame number.
+ @param bp Bitmap image file.
+ @param fn Number of frame to process.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3bif_set_frame(dk3_bif_t *bp, size_t fn);
+
+/** Reset internal current frame pointer, so the next
+ dk3bif_next_frame() call returns the first frame.
+ @param bp Bitmap image file.
+*/
+void
+dk3bif_reset_frames(dk3_bif_t *bp);
+
+/** Switch to the next frame.
+ @param bp Bitmap image file.
+ @return 1 on success, 0 on error (no more frames).
+*/
+int
+dk3bif_next_frame(dk3_bif_t *bp);
+
+/** Check whether a bitmap image is really colored.
+ @param bp Bitmap image file.
+ @return 1 for colored image, 0 for grey.
+*/
+int
+dk3bif_is_colored(dk3_bif_t *bp);
+
+/** Retrieve number of bits per pixel for current frame.
+ @param bp Bitmap image file.
+ @return Number of bits per pixel used in the file.
+*/
+size_t
+dk3bif_get_bits_per_pixel(dk3_bif_t *bp);
+
+/** Retrieve number of bits per pixel for current frame
+ really containing information.
+ This function returns a useful result only if
+ dk3bif_analyze() was run with DK3_ANALYSIS_BITS before.
+ @param bp Bitmap image file.
+ @return Number of non-redundant bits per pixel.
+*/
+size_t
+dk3bif_real_bits_per_pixel(dk3_bif_t *bp);
+
+/** Retrieve information whether colors are really used.
+ This function returns a useful result only if
+ dk3bif_analyze() was run with DK3_BIF_ANALYSIS_COLOR before.
+ @param bp Bitmap image file.
+ @return 1 for colors, 0 for gray.
+*/
+int
+dk3bif_real_color(dk3_bif_t *bp);
+
+/** Retrieve information whether alpha channel is really used.
+ This function returns a useful result only if
+ dk3bif_analyze() was run with DK3_BIF_ANALYSIS_ALPHA before.
+ @param bp Bitmap image file.
+ @return 1 for alpha channel used, 0 for unused.
+*/
+int
+dk3bif_real_alpha(dk3_bif_t *bp);
+
+/** Set number of bits per pixel when retrieving data.
+ @param bp Bitmap image file.
+ @param sz Number of bits per pixel.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3bif_set_bits_per_pixel(dk3_bif_t *bp, size_t sz);
+
+/** Get color space.
+ @param bp Bitmap image file.
+ @return The color space used by the image.
+*/
+int
+dk3bif_get_color_space(dk3_bif_t *bp);
+
+/** Get red component of pixel.
+ @param bp Bitmap image file.
+ @param x X coordinate.
+ @param y Y coordinate.
+ @return Value corrected to requested bits per component.
+*/
+dk3_bif_pixel_t
+dk3bif_get_red(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y);
+
+/** Get green component of pixel.
+ @param bp Bitmap image file.
+ @param x X coordinate.
+ @param y Y coordinate.
+ @return Value corrected to requested bits per component.
+*/
+dk3_bif_pixel_t
+dk3bif_get_green(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y);
+
+/** Get blue component of pixel.
+ @param bp Bitmap image file.
+ @param x X coordinate.
+ @param y Y coordinate.
+ @return Value corrected to requested bits per component.
+*/
+dk3_bif_pixel_t
+dk3bif_get_blue(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y);
+
+/** Get gray component of pixel.
+ @param bp Bitmap image file.
+ @param x X coordinate.
+ @param y Y coordinate.
+ @return Value corrected to requested bits per component.
+*/
+dk3_bif_pixel_t
+dk3bif_get_gray(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y);
+
+/** Get alpha component of pixel.
+ @param bp Bitmap image file.
+ @param x X coordinate.
+ @param y Y coordinate.
+ @return Value corrected to requested bits per component.
+*/
+dk3_bif_pixel_t
+dk3bif_get_alpha(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y);
+
+/** Get red component of pixel mixed against background.
+ @param bp Bitmap image file.
+ @param x X coordinate.
+ @param y Y coordinate.
+ @return Value corrected to requested bits per component.
+*/
+dk3_bif_pixel_t
+dk3bif_get_mixed_red(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y);
+
+/** Get green component of pixel mixed against background.
+ @param bp Bitmap image file.
+ @param x X coordinate.
+ @param y Y coordinate.
+ @return Value corrected to requested bits per component.
+*/
+dk3_bif_pixel_t
+dk3bif_get_mixed_green(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y);
+
+/** Get blue component of pixel mixed against background.
+ @param bp Bitmap image file.
+ @param x X coordinate.
+ @param y Y coordinate.
+ @return Value corrected to requested bits per component.
+*/
+dk3_bif_pixel_t
+dk3bif_get_mixed_blue(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y);
+
+/** Get gray component of pixel mixed against background.
+ @param bp Bitmap image file.
+ @param x X coordinate.
+ @param y Y coordinate.
+ @return Value corrected to requested bits per component.
+*/
+dk3_bif_pixel_t
+dk3bif_get_mixed_gray(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y);
+
+/** Get file to access raw data.
+ This function is primary intended to access JPEG data.
+ @param bp Bitmap image file.
+ @return FILE pointer if available, NULL otherwise.
+*/
+FILE *
+dk3bif_get_file(dk3_bif_t *bp);
+
+/** Retrieve X resolution.
+ @param bp Bitmap image file.
+ @return X resolution in dpi.
+*/
+double
+dk3bif_get_xres(dk3_bif_t *bp);
+
+/** Retrieve Y resolution.
+ @param bp Bitmap image file.
+ @return Y resolution in dpi.
+*/
+double
+dk3bif_get_yres(dk3_bif_t *bp);
+
+/** Close bitmap image file, release memory.
+ @param bp Bitmap image file to close.
+*/
+void
+dk3bif_close(dk3_bif_t *bp);
+
+/** Get original number of components for JPEG file.
+ @param bif Bitmap image file.
+ @return Number of components found in file on success, 0 on error.
+*/
+int
+dk3bif_jpeg_get_num_components(dk3_bif_t *bif);
+
+/** Check whether Adobe marker was found in JPEG input file.
+ @param bif Bitmap image file.
+ @return 1 if marker was found, 0 otherwise.
+*/
+int
+dk3bif_jpeg_get_found_adobe_marker(dk3_bif_t *bif);
+
+/** Calculate average predictor value from left and upper value.
+ @param left Value left to the pixel.
+ @param upper Value upper to the pixel.
+ @return Predictor value.
+*/
+dk3_bif_pixel_t
+dk3bif_average(dk3_bif_pixel_t left, dk3_bif_pixel_t upper);
+
+/** Paeth prediction function.
+ @param v1 Left value.
+ @param v2 Upper value.
+ @param v3 Upper left value.
+ @return Predicted value.
+*/
+dk3_bif_pixel_t
+dk3bif_paeth(
+ dk3_bif_pixel_t v1,
+ dk3_bif_pixel_t v2,
+ dk3_bif_pixel_t v3
+);
+
+/** Retrieve one pixel component not yet resampled.
+ @param bp Bitmap image.
+ @param x X coordinate.
+ @param y Y coordinate.
+ @param c Choose component: 0=red/gray, 1=green, 2=blue, 3=alpha.
+ @return Pixel component.
+*/
+dk3_bif_pixel_t
+dk3bif_get_pixel_component_not_resampled(
+ dk3_bif_t *bp,
+ dk3_bif_coord_t x,
+ dk3_bif_coord_t y,
+ int c
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk3conf.h"
+
+#include <stdio.h>
+
+#if DK3_HAVE_PNG_H
+#include <png.h>
+#else
+#if DK3_HAVE_SETJMP_H
+#include <setjmp.h>
+#endif
+#endif
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if DK3_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if DK3_HAVE_PROCESS_H
+#include <process.h>
+#endif
+#if DK3_HAVE_JPEGLIB_H
+#include <jpeglib.h>
+#endif
+
+#if DK3_HAVE_TIFF_H
+#include <tiff.h>
+#include <tiffio.h>
+#endif
+
+#if DK3_HAVE_STRING_H
+#include <string.h>
+#endif
+#if DK3_HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
+#if 0
+#include "dk3all.h"
+#endif
+
+#include "dk3const.h"
+#include "dk3mem.h"
+#include "dk3str.h"
+#include "dk3sf.h"
+#include "dk3sto.h"
+#include "dk3bif.h"
+#include "dk3bifa.h"
+#include "dk3pixre.h"
+#include "dk3ma.h"
+#include "dk3numco.h"
+#include "dk3bits.h"
+#include "dk3app.h"
+
+
+
+$!trace-include
+
+
+$!trace-off
+
+
+/** File suffixes for images.
+*/
+static dkChar const * const dk3bif_dk_type_names[] = {
+$!text macro=dkT
+png
+jpeg
+jpg
+tiff
+tif
+$!end
+};
+
+
+
+/** File suffixes for images.
+ Note: Order must correpsond to the order of dk3bif_dk_type_names.
+*/
+static char const * const dk3bif_c8_type_names[] = {
+$!text
+png
+jpeg
+jpg
+tiff
+tif
+$!end
+};
+
+
+
+/** Keywords used by the module (dkChar).
+*/
+static dkChar const * const dk3bif_kw_dk[] = {
+/* 0 */ dkT("rb"),
+NULL
+};
+
+
+
+/** Keywords and texts used by the module (8-bit).
+*/
+static char const * const dk3bif_kw_c8[] = {
+/* 0 */ "dk3bif-%lu-%lu.tmp", /* PID, index */
+/* 1 */ "dk3bif-%d-%lu.tmp", /* PID, index */
+NULL
+};
+
+
+
+/** Number of current temporary file within this process.
+*/
+static unsigned long dk3bif_temp_number = 0UL;
+
+
+
+static
+dk3_bif_frame_t *
+dk3bif_frame_new(dk3_bif_t *bp);
+
+
+
+#if DK3_HAVE_PNG_H
+/** Per frame data, PNG-specific.
+*/
+typedef struct {
+ png_bytep *rows;
+ png_colorp palp;
+ png_size_t rowbytes;
+ dk3_bif_coord_t h;
+ dk3_bif_pixel_t bgred;
+ dk3_bif_pixel_t bggreen;
+ dk3_bif_pixel_t bgblue;
+ int paln;
+} dk3_bif_frame_png_t;
+
+/** Per file data, PNG-specific.
+*/
+typedef struct {
+ png_structp pp; /* Read structure. */
+ png_infop pi; /* PNG information. */
+ int ct; /* Color type. */
+ int im; /* Interlace method. */
+ int cm; /* Compression method. */
+ int fm; /* Filter method. */
+ int ch; /* Number of channels. */
+ int np; /* Number of interlace passes. */
+} dk3_bif_png_t;
+
+/** Release type-specific information for PNG file.
+ @param is Bitmap-type specific data.
+*/
+static
+void
+dk3bif_frame_release_implspec_png(void *is)
+{
+ dk3_bif_frame_png_t *fdis;
+ dk3_bif_coord_t i;
+ $? "+ dk3bif_frame_release_implspec_png"
+ fdis = (dk3_bif_frame_png_t *)is;
+ if(fdis->rows) { $? ". delete rows"
+ for(i = 0L; i < fdis->h; i++) { $? ". delete row %ld", i
+ dk3_delete((fdis->rows)[i]);
+ }
+ dk3_delete(fdis->rows);
+ }
+ dk3_release(fdis);
+ $? "- dk3bif_frame_release_implspec_png"
+}
+
+/** Release type specific information for PNG file (image).
+ @param is Bitmap-type specific data.
+*/
+static
+void
+dk3bif_release_implspec_png(void *is)
+{
+ dk3_bif_png_t *dis;
+ $? "+ dk3bif_release_implspec_png"
+ dis = (dk3_bif_png_t *)is;
+ if(dis->pp) {
+ if(dis->pi) { $? ". destroy info struct"
+ png_destroy_info_struct(dis->pp, &(dis->pi));
+ } $? ". destroy read struct"
+ png_destroy_read_struct(&(dis->pp), (png_infopp)NULL, (png_infopp)NULL);
+ }
+ dis->pp = NULL; dis->pi = NULL;
+ dk3_release(dis);
+ $? "- dk3bif_release_implspec_png"
+}
+
+/** Read header for PNG image.
+ @param bp Bitmap image file.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bif_read_png_header(dk3_bif_t *bp)
+{
+ unsigned char header[9]; /* Test for PNG file header. */
+ dk3_bif_png_t *dis;
+ dk3_bif_frame_png_t *fdis;
+#if 0
+ double gamma; /* Gamma value. */
+#endif
+ double dbldpi = 0.0;
+ double dblxdpi = 0.0;
+ double dblydpi = 0.0;
+ png_uint_32 w; /* Image width. */
+ png_uint_32 h; /* Image height. */
+ png_uint_32 xdpi; /* X resolution. */
+ png_uint_32 ydpi; /* Y resolution. */
+ png_uint_32 dpi; /* Resolution. */
+ int bd; /* Bit depth. */
+ int ct; /* Color type. */
+ int im; /* Interlace method. */
+ int cm; /* Compression method. */
+ int fm; /* Filter method. */
+ int ch; /* Number of channels. */
+ int np = 1; /* Number of interlace passes. */
+ size_t szh; /* Number of header bytes read. */
+ int back = 0;
+ $? "+ dk3bif_read_png_header"
+ szh = fread(header, 1, 8, bp->tmpfipo);
+ if(szh > 0) { $? ". szh ok"
+ if(png_sig_cmp(header, 0, szh) == 0) {
+ dis = dk3_new_app(dk3_bif_png_t,1,bp->app);
+ if(dis) { $? ". dis ok"
+ bp->implspec = (void *)dis;
+ dis->pp = NULL; dis->pi = NULL; dis->ct = 0;
+ dis->pp = png_create_read_struct(
+ PNG_LIBPNG_VER_STRING,
+ NULL, /* user error data */
+ NULL, /* user error function */
+ NULL /* user warning function */
+ );
+ if(dis->pp) { $? ". pp ok"
+#if DK3_HAVE_SETJMP_H
+ if(setjmp(png_jmpbuf(dis->pp)) == 0) {
+#endif
+ dis->pi = png_create_info_struct(dis->pp);
+ if(dis->pi) { $? ". piok"
+ bp->cf = dk3bif_frame_new(bp);
+ if(bp->cf) { $? ". cf ok"
+ fdis = dk3_new_app(dk3_bif_frame_png_t,1,bp->app);
+ if(fdis) { $? ". fdis ok"
+ fdis->rows = NULL;
+ fdis->rowbytes = 0;
+ fdis->palp = NULL;
+ fdis->paln = 0;
+ fdis->bgred = 255; fdis->bggreen = 255; fdis->bgblue = 255;
+ fdis->h = 0L;
+ (bp->cf)->implspec = (void *)fdis;
+ /*
+ Prepare reading.
+ */
+ png_init_io(dis->pp, bp->tmpfipo);
+ png_set_sig_bytes(dis->pp, (int)szh);
+ /*
+ Read file information.
+ */
+ png_read_info(dis->pp, dis->pi);
+ /*
+ Read information about the image.
+ */
+ png_get_IHDR(dis->pp,dis->pi,&w,&h,&bd,&ct,&im,&cm,&fm);
+ /* Static code analysis: Dead assignement. */
+ /* Needed for traceing, not for normal build. */
+#if TRACE_DEBUG || VERSION_BEFORE_20150821
+ ch = png_get_channels(dis->pp, dis->pi);
+ $? ". w=%lu h=%lu ct=%d ch=%d bd=%d im=%d",w,h,ct,ch,bd,im
+#endif
+ if(png_get_valid(dis->pp, dis->pi, PNG_INFO_pHYs)) {
+#if VERSION_BEFORE_20150821
+ dbldpi = dblxdpi = dblydpi = 0.0;
+#endif
+#if DK3_HAVE_PNG_GET_PIXELS_PER_INCH
+ dpi = png_get_pixels_per_inch(dis->pp, dis->pi);
+ xdpi = png_get_x_pixels_per_inch(dis->pp, dis->pi);
+ ydpi = png_get_y_pixels_per_inch(dis->pp, dis->pi);
+ dbldpi = (double)dpi;
+ dblxdpi = (double)xdpi;
+ dblydpi = (double)ydpi;
+#else
+ /* 0.0254 = 254 / 10000 */
+ dpi = png_get_pixels_per_meter(dis->pp, dis->pi);
+ xdpi = png_get_x_pixels_per_meter(dis->pp, dis->pi);
+ ydpi = png_get_y_pixels_per_meter(dis->pp, dis->pi);
+ dbldpi = 0.0254 * (double)dpi;
+ dblxdpi = 0.0254 * (double)xdpi;
+ dblydpi = 0.0254 * (double)ydpi;
+ dpi = (png_uint_32)dbldpi;
+ xdpi = (png_uint_32)dblxdpi;
+ ydpi = (png_uint_32)dblydpi;
+#endif
+ if(!(xdpi)) {
+ if(dpi) { xdpi = dpi; dblxdpi = dbldpi; }
+ else { if(ydpi) { xdpi = ydpi; dblxdpi = dblydpi; } }
+ }
+ if(!(ydpi)) {
+ if(dpi) { ydpi = dpi; dblydpi = dbldpi; }
+ else { if(xdpi) { ydpi = xdpi; dblydpi = dblxdpi; } }
+ }
+ if((xdpi) && (ydpi)) {
+ (bp->cf)->xres = dblxdpi;
+ (bp->cf)->yres = dblydpi;
+ if((xdpi == 72UL) && (ydpi == 72UL)) {
+ (bp->cf)->xres = (bp->cf)->yres = -1.0;
+ }
+ }
+ $? ". resolution %lg %lg", (bp->cf)->xres, (bp->cf)->yres
+ }
+ /*
+ Establish transformations.
+ */
+ if(ct == PNG_COLOR_TYPE_PALETTE) {
+ /* Convert palette image to RGB */
+ png_set_palette_to_rgb(dis->pp);
+ }
+ if(png_get_valid(dis->pp, dis->pi, PNG_INFO_tRNS)) {
+ /* Get alpha values if available */
+ png_set_tRNS_to_alpha(dis->pp);
+ }
+#if !DK3_WORDS_BIGENDIAN
+ if(bd == 16) {
+ /* Change network byte order to host byte order on x86. */
+ png_set_swap(dis->pp);
+ }
+#endif
+#if 0
+/*
+ I need to find out some more about gamma correction.
+*/
+ if(png_get_gAMA(dis->pp, dis->pi, &gamma)) {
+ png_set_gamma(dis->pp, scg, gamma);
+ } else {
+ png_set_gamma(dis->pp, scg, 0.45455);
+ }
+#endif
+ switch(im) {
+ case PNG_INTERLACE_ADAM7: {
+ np = png_set_interlace_handling(dis->pp);
+ } break;
+ }
+ /*
+ Re-read information.
+ */
+ png_read_update_info(dis->pp, dis->pi);
+ png_get_IHDR(dis->pp,dis->pi,&w,&h,&bd,&ct,&im,&cm,&fm);
+ ch = png_get_channels(dis->pp, dis->pi);
+ $? ". w=%lu h=%lu ct=%d ch=%d bd=%d im=%d",w,h,ct,ch,bd,im
+ (bp->cf)->w = (dk3_bif_coord_t)w;
+ (bp->cf)->h = (dk3_bif_coord_t)h;
+ (bp->cf)->realbits = (bp->cf)->bits = (size_t)bd;
+ dis->ct = ct;
+ dis->im = im;
+ dis->cm = cm;
+ dis->fm = fm;
+ dis->ch = ch;
+ dis->np = np;
+ fdis->h = h;
+ switch(ct) {
+ case PNG_COLOR_TYPE_GRAY: { /* 1,2,4,8,16 */
+ (bp->cf)->cs = DK3_COLOR_SPACE_GRAY;
+ back = 1;
+ } break;
+ case PNG_COLOR_TYPE_GRAY_ALPHA: { /* 8,16 */
+ (bp->cf)->cs = DK3_COLOR_SPACE_GRAY_ALPHA;
+ back = 1;
+ } break;
+ case PNG_COLOR_TYPE_PALETTE: { /* 1,2,4,8 */
+ (bp->cf)->cs = DK3_COLOR_SPACE_RGB;
+ back = 1;
+ } break;
+ case PNG_COLOR_TYPE_RGB: { /* 8,16 */
+ (bp->cf)->cs = DK3_COLOR_SPACE_RGB;
+ back = 1;
+ } break;
+ case PNG_COLOR_TYPE_RGB_ALPHA: { /* 8,16 */
+ (bp->cf)->cs = DK3_COLOR_SPACE_RGBA;
+ back = 1;
+ } break;
+ }
+ } else { $? "! memory"
+ }
+ } else { $? "! memory"
+ }
+ } else { $? "! memory"
+ }
+#if DK3_HAVE_SETJMP_H
+ } else {
+ back = 0;
+ }
+#endif
+ } else { $? "! memory"
+ }
+ } else { $? "! memory"
+ }
+ } else { $? "! not a png file"
+ }
+ } else { $? "! failed to read any header data"
+ }
+ $? "- dk3bif_read_png_header %d", back
+ return back;
+}
+
+/** Read data for PNG image.
+ @param bp Bitmap image file.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bif_read_png_data(dk3_bif_t *bp)
+{
+#if 0
+ png_color_16 bg;
+#endif
+ png_color_16p bgp = NULL;
+ dk3_bif_png_t *dis;
+ dk3_bif_frame_png_t *fdis;
+ png_bytep *rp;
+ dk3_bif_coord_t i;
+ int back = 0;
+ dis = (dk3_bif_png_t *)(bp->implspec);
+ fdis = (dk3_bif_frame_png_t *)((bp->cf)->implspec);
+#if DK3_HAVE_SETJMP_H
+ if(setjmp(png_jmpbuf(dis->pp)) == 0) {
+#endif
+ fdis->rowbytes = png_get_rowbytes(dis->pp, dis->pi);
+ fdis->rows = dk3_new_app(png_bytep,(size_t)((bp->cf)->h),bp->app);
+ if(fdis->rows) {
+ rp = fdis->rows;
+ for(i = 0L; i < (bp->cf)->h; i++) { *(rp++) = NULL; }
+ back = 1;
+ rp = fdis->rows;
+ for(i = 0L; (i < (bp->cf)->h) && (back == 1); i++) {
+ *rp = dk3_new_app(png_byte, fdis->rowbytes, bp->app);
+ if(!(*rp)) {
+ back = 0;
+ }
+ rp++;
+ }
+ if(back) {
+ png_read_image(dis->pp, fdis->rows);
+ if(png_get_bKGD(dis->pp, dis->pi, &bgp)) {
+ fdis->bgred = bgp->red;
+ fdis->bggreen = bgp->green;
+ fdis->bgblue = bgp->blue; $? ". bg chunk %lu %lu %lu", (unsigned long)(bgp->red), (unsigned long)(bgp->green), (unsigned long)(bgp->blue)
+ }
+ if(dis->ct == PNG_COLOR_TYPE_PALETTE) {
+ back = 0;
+ png_get_PLTE(dis->pp, dis->pi, &(fdis->palp), &(fdis->paln));
+ if((fdis->palp) && (fdis->paln)) {
+ back = 1;
+ }
+ }
+ }
+ } else { $? "! memory"
+ }
+#if DK3_HAVE_SETJMP_H
+ } else {
+ back = 0;
+ }
+#endif
+ return back;
+}
+
+/** Retrieve one pixel component from PNG.
+ @param bp Bitmap image.
+ @param x X coordinate.
+ @param y Y coordinate.
+ @param c Choose component: 0=red/gray, 1=green, 2=blue, 3=alpha.
+ @return Pixel component.
+*/
+static
+dk3_bif_pixel_t
+dk3bif_get_png_pixel_component(
+ dk3_bif_t *bp,
+ dk3_bif_coord_t x,
+ dk3_bif_coord_t y,
+ int c
+)
+{
+ png_bytep row;
+ dk3_bif_png_t *dis;
+ dk3_bif_frame_png_t *fdis;
+ dk3_bif_pixel_t back = (dk3_bif_pixel_t)0;
+ dk3_bif_coord_t vi;
+
+ if(bp) {
+ if(bp->cf) {
+ if(bp->implspec) {
+ if((bp->cf)->implspec) {
+ dis = (dk3_bif_png_t *)(bp->implspec);
+ fdis = (dk3_bif_frame_png_t *)((bp->cf)->implspec);
+ if(fdis->rows) {
+ row = (fdis->rows)[y];
+ vi = 0L;
+ switch(dis->ct) {
+ case PNG_COLOR_TYPE_GRAY: {
+ vi = x;
+ } break;
+ case PNG_COLOR_TYPE_GRAY_ALPHA: {
+ vi = 2L * x;
+ if(c == 3) { vi = vi + 1; }
+ } break;
+ case PNG_COLOR_TYPE_RGB: {
+ vi = 3L * x;
+ if((c >= 0) && (c < 3)) {
+ vi = vi + (dk3_bif_coord_t)c;
+ }
+ } break;
+ case PNG_COLOR_TYPE_RGB_ALPHA: {
+ vi = 4L * x;
+ if((c >= 0) && (c < 4)) {
+ vi = vi + (dk3_bif_coord_t)c;
+ }
+ } break;
+ default: {
+ /*
+ Must not happen, we requested conversion from
+ palette to RGB.
+ */
+ } break;
+ }
+ back = dk3pixre_get_value_from_packed_bytes(
+ (unsigned char const *)row,
+ vi,
+ (bp->cf)->bits
+ );
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+#endif
+/* if DK3_HAVE_PNG_H */
+
+
+
+#if DK3_HAVE_JPEGLIB_H
+/*
+ JPEGLIB error management.
+*/
+/** JPEGLIB error manager.
+*/
+typedef struct {
+ struct jpeg_error_mgr pub; /**< Default error manager. */
+#if DK3_HAVE_SETJMP_H
+ jmp_buf setjmp_buffer; /**< Buffer for setjmp. */
+#endif
+} dk3_bif_jpg_error_mgr;
+
+/** Per frame data, JPEG-specific.
+*/
+typedef struct {
+ JSAMPLE **rows; /**< Sample buffer. */
+ JDIMENSION w; /**< Image width. */
+ JDIMENSION h; /**< Image height. */
+ int is_adobe; /**< Flag: Adobe marker found. */
+ int num_comp; /**< Number of components found. */
+} dk3_bif_frame_jpeg_t;
+
+/** Per file data, JPEG-specific.
+*/
+typedef struct {
+ int st;
+ struct jpeg_decompress_struct cinfo; /**< Decompression struct. */
+ dk3_bif_jpg_error_mgr errmgr; /**< Error manager. */
+} dk3_bif_jpeg_t;
+
+/** Error exit replacement function.
+ @param cinfo JPEG decompression structure.
+*/
+static
+void
+dk3bif_jpeg_error_exit(j_common_ptr cinfo)
+{
+ dk3_bif_jpg_error_mgr *myerr = (dk3_bif_jpg_error_mgr *)(cinfo->err);
+ if(myerr) {
+ longjmp(myerr->setjmp_buffer, 1);
+ }
+}
+
+/** Release type-specific information for JPEG file (frame).
+ @param is Bitmap-type specific data.
+*/
+static
+void
+dk3bif_frame_release_implspec_jpeg(void *is)
+{
+ dk3_bif_frame_jpeg_t *fdis;
+ JSAMPLE **ptr;
+ JDIMENSION i;
+ fdis = (dk3_bif_frame_jpeg_t *)is;
+ if(fdis->rows) {
+ ptr = fdis->rows;
+ for(i = 0; i < fdis->h; i++) {
+ dk3_release(*ptr);
+ ptr++;
+ }
+ dk3_delete(fdis->rows);
+ }
+ dk3_delete(is);
+}
+
+/** Release type specific information for JPEG file (image).
+ @param is Bitmap-type specific data.
+*/
+static
+void
+dk3bif_release_implspec_jpeg(void *is)
+{
+ dk3_bif_jpeg_t *dis;
+ dis = (dk3_bif_jpeg_t *)is;
+ if(dis->st >= 1) {
+#if DK3_HAVE_SETJMP_H
+ if(setjmp((dis->errmgr).setjmp_buffer) == 0) {
+#endif
+ jpeg_destroy_decompress(&(dis->cinfo));
+#if DK3_HAVE_SETJMP_H
+ }
+#endif
+ }
+ dk3_delete(dis);
+}
+
+/** Read header for JPEG image.
+ @param bp Bitmap image file.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bif_read_jpeg_header(dk3_bif_t *bp)
+{
+ dk3_bif_jpeg_t *dis = NULL;
+ dk3_bif_frame_jpeg_t *fdis = NULL;
+ int back = 0;
+ $? "+ dk3bif_read_jpeg_header"
+ bp->cf = dk3bif_frame_new(bp);
+ if(bp->cf) {
+ dis = dk3_new_app(dk3_bif_jpeg_t,1,bp->app);
+ if(dis) {
+ bp->implspec = (void *)dis;
+ dis->st = 0; /* Initial state. */
+ (dis->errmgr).pub.error_exit = dk3bif_jpeg_error_exit;
+ (dis->cinfo).err = jpeg_std_error(&((dis->errmgr).pub));
+ (dis->errmgr).pub.error_exit = dk3bif_jpeg_error_exit;
+#if DK3_HAVE_SETJMP_H
+ if(setjmp((dis->errmgr).setjmp_buffer) == 0) {
+#endif
+ jpeg_create_decompress(&(dis->cinfo));
+ dis->st = 1; /* Decompress created. */
+ if(bp->tmpfipo) {
+ jpeg_stdio_src(&(dis->cinfo), bp->tmpfipo);
+ dis->st = 2;
+ jpeg_read_header(&(dis->cinfo), TRUE);
+ dis->st = 3;
+ fdis = dk3_new_app(dk3_bif_frame_jpeg_t,1,bp->app);
+ if(fdis) {
+ (bp->cf)->implspec = (void *)fdis;
+ fdis->is_adobe = 0;
+ fdis->num_comp = (dis->cinfo).num_components;
+ $? ". fdis->num_comp = %d", (int)(fdis->num_comp)
+ fdis->rows = NULL;
+ fdis->w = (dis->cinfo).image_width;
+ fdis->h = (dis->cinfo).image_height;
+ (bp->cf)->w = (dk3_bif_coord_t)(fdis->w);
+ (bp->cf)->h = (dk3_bif_coord_t)(fdis->h);
+ (bp->cf)->realbits = (bp->cf)->bits = 8;
+ switch((dis->cinfo).jpeg_color_space) {
+ case JCS_GRAYSCALE: { $? ". gray"
+ (bp->cf)->cs = DK3_COLOR_SPACE_GRAY;
+ } break;
+ case JCS_RGB: { $? ". rgb"
+ (bp->cf)->cs = DK3_COLOR_SPACE_RGB;
+ } break;
+ case JCS_CMYK: { $? ". cmyk"
+ (bp->cf)->cs = DK3_COLOR_SPACE_CMYK;
+ } break;
+ case JCS_YCCK: { $? ". ycck"
+ (bp->cf)->cs = DK3_COLOR_SPACE_CMYK;
+ } break;
+ case JCS_YCbCr: { $? ". ycbcr"
+ (bp->cf)->cs = DK3_COLOR_SPACE_YCbCr;
+ } break;
+ default: {
+ /* No setting available (yet). */
+ } break;
+ }
+ if((dis->cinfo).saw_JFIF_marker) {
+ switch((dis->cinfo).density_unit) {
+ case 0x01: { /* per inch */
+ if(((dis->cinfo).X_density) && ((dis->cinfo).Y_density)) {
+ (bp->cf)->xres = (double)((dis->cinfo).X_density);
+ (bp->cf)->yres = (double)((dis->cinfo).Y_density);
+ }
+ } break;
+ case 0x02: { /* per cm */
+ if(((dis->cinfo).X_density) && ((dis->cinfo).Y_density)) {
+ (bp->cf)->xres = 2.54 * (double)((dis->cinfo).X_density);
+ (bp->cf)->yres = 2.54 * (double)((dis->cinfo).Y_density);
+ }
+ } break;
+ }
+ }
+ back = 1;
+ if((dis->cinfo).saw_Adobe_marker) {
+ fdis->is_adobe = 1;
+ }
+ }
+ }
+#if DK3_HAVE_SETJMP_H
+ } else {
+ }
+#endif
+ }
+ }
+ $? "- dk3bif_read_jpeg_header %d", back
+ return back;
+}
+
+/** Read data for JPEG image.
+ @param bp Bitmap image file.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bif_read_jpeg_data(dk3_bif_t *bp)
+{
+ dk3_bif_jpeg_t *dis = NULL;
+ dk3_bif_frame_jpeg_t *fdis = NULL;
+ JSAMPROW *rp = NULL;
+ JDIMENSION y;
+ int back = 0;
+ int ok;
+ int occ;
+ $? "+ dk3bif_read_jpeg_data"
+ if(bp->implspec) { $? ". implspec ok"
+ if(bp->cf) { $? ". cf ok"
+ if((bp->cf)->implspec) { $? ". cf->implspec ok"
+ dis = (dk3_bif_jpeg_t *)(bp->implspec);
+ fdis = (dk3_bif_frame_jpeg_t *)((bp->cf)->implspec); $? ". dis/fdis"
+ if(dis->st == 3) { $? ". state ok"
+#if DK3_HAVE_SETJMP_H
+ if(setjmp((dis->errmgr).setjmp_buffer) == 0) { $? ". setjmp"
+#endif
+ dis->st = 4; /* We attempted to continue. */
+ jpeg_start_decompress(&(dis->cinfo));
+ dis->st = 5; /* Decompression started. */
+ fdis->rows = dk3_new_app(JSAMPROW,fdis->h,bp->app);
+ if(fdis->rows) { $? ". alloc ok"
+ occ = (dis->cinfo).out_color_components;
+ ok = 1; $? ". occ = %d", occ
+ rp = fdis->rows; $? ". fdis->w=%lu", (unsigned long)(fdis->w)
+ for(y = 0; y < fdis->h; y++) { *(rp++) = NULL; }
+ occ = occ * fdis->w; $? ". occ = %d", occ
+ rp = fdis->rows;
+ for(y = 0; y < fdis->h; y++) { $? ". alloc %lu", (unsigned long)y
+ *rp = dk3_new_app(JSAMPLE,occ,bp->app);
+ if(!(*rp)) {
+ ok = 0; $? "! memory"
+ }
+ rp++;
+ }
+ if(ok) { $? ". memory allocated"
+ dis->st = 6; /* Decompression started. */
+ rp = fdis->rows; $? ". decompression started"
+ for(y = 0; y < fdis->h; y++) { $? ". now %lu", (unsigned long)y
+ jpeg_read_scanlines(&(dis->cinfo), rp, 1);
+ rp++; $? ". line scanned"
+ } $? ". image data read"
+ dis->st = 7; /* Data was read successfully. */
+ jpeg_finish_decompress(&(dis->cinfo)); $? ". finished"
+ dis->st = 8; /* Decompression finished. */
+ switch((dis->cinfo).out_color_space) {
+ case JCS_GRAYSCALE: { $? ". now grey"
+ (bp->cf)->cs = DK3_COLOR_SPACE_GRAY;
+ back = 1;
+ } break;
+ case JCS_RGB: { $? ". now rgb"
+ (bp->cf)->cs = DK3_COLOR_SPACE_RGB;
+ back = 1;
+ } break;
+ default: {
+ (bp->cf)->cs = 0;
+ } break;
+ }
+ } else {
+ }
+ } else { $? "! memory"
+ }
+#if DK3_HAVE_SETJMP_H
+ } else {
+ }
+#endif
+ } else { $? "! st"
+ }
+ } else { $? "! cf->implspec"
+ }
+ } else { $? "! cf"
+ }
+ } $? "- dk3bif_read_jpeg_data %d", back
+ return back;
+}
+
+/** Retrieve one pixel component from JPEG.
+ @param bp Bitmap image.
+ @param x X coordinate.
+ @param y Y coordinate.
+ @param c Choose component: 0=red/gray, 1=green, 2=blue, 3=alpha.
+ @return Pixel component.
+*/
+static
+dk3_bif_pixel_t
+dk3bif_get_jpeg_pixel_component(
+ dk3_bif_t *bp,
+ dk3_bif_coord_t x,
+ dk3_bif_coord_t y,
+ int c
+)
+{
+#if VERSION_BEFORE_20150821
+ dk3_bif_jpeg_t *dis = NULL;
+#endif
+ dk3_bif_frame_jpeg_t *fdis = NULL;
+ dk3_bif_pixel_t back = (dk3_bif_pixel_t)0;
+ JSAMPLE value;
+ JSAMPLE *row;
+ if(bp) {
+ if(bp->cf) {
+ if(bp->implspec) {
+ if((bp->cf)->implspec) {
+#if VERSION_BEFORE_20150821
+ dis = (dk3_bif_jpeg_t *)(bp->implspec);
+#endif
+ fdis = (dk3_bif_frame_jpeg_t *)((bp->cf)->implspec);
+ if(c == 3) {
+ back = 255;
+ } else {
+ switch((bp->cf)->cs) {
+ case DK3_COLOR_SPACE_GRAY: {
+ if((c >= 0) && (c < 3)) {
+ if(fdis->rows) {
+ row = (fdis->rows)[y];
+ if(row) {
+ value = row[x];
+ back = (dk3_bif_pixel_t)value;
+ back &= 0x00FFU;
+ }
+ }
+ }
+ } break;
+ case DK3_COLOR_SPACE_RGB: {
+ if((c >= 0) && (c < 3)) {
+ if(fdis->rows) {
+ row = (fdis->rows)[y];
+ if(row) {
+ value = row[3 * x + c];
+ back = (dk3_bif_pixel_t)value;
+ back &= 0x00FFU;
+ }
+ }
+ }
+ } break;
+ }
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+#endif
+/* if DK3_HAVE_JPEGLIB_H */
+
+
+
+#if DK3_HAVE_TIFF_H
+/** Per frame data, TIFF-specific.
+*/
+typedef struct {
+ uint32 *r; /**< Raster image data. */
+ uint32 w; /**< Image width. */
+ uint32 h; /**< Image height. */
+ uint16 cps;
+ uint16 spp;
+ uint16 ori; /**< Orientation. */
+} dk3_bif_frame_tiff_t;
+
+/** Per file data, TIFF-specific.
+*/
+typedef struct {
+ TIFF *tiff;
+} dk3_bif_tiff_t;
+
+/** Release type-specific information for TIFF file.
+ @param is Bitmap-type specific data.
+*/
+static
+void
+dk3bif_frame_release_implspec_tiff(void *is)
+{
+ dk3_bif_frame_tiff_t *fdis;
+ fdis = (dk3_bif_frame_tiff_t *)is;
+ if(fdis->r) {
+ _TIFFfree(fdis->r);
+ fdis->r = NULL;
+ }
+ fdis->w = fdis->h = 0UL; fdis->spp = fdis->cps = 0U;
+ dk3_delete(fdis);
+}
+
+/** Release type specific information for TIFF file (image).
+ @param is Bitmap-type specific data.
+*/
+static
+void
+dk3bif_release_implspec_tiff(void *is)
+{
+ dk3_bif_tiff_t *dis;
+ dis = (dk3_bif_tiff_t *)is;
+ if(dis->tiff) {
+ TIFFClose(dis->tiff); dis->tiff = NULL;
+ }
+ dk3_delete(dis);
+}
+
+
+
+
+/** Read header for TIFF image.
+ @param bp Bitmap image file.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bif_read_tiff_header(dk3_bif_t *bp)
+{
+ dk3_bif_frame_tiff_t *fdis;
+ dk3_bif_tiff_t *dis;
+ float rv;
+#if VERSION_BEFORE_20140809
+ unsigned long wh = 0UL;
+#else
+ dk3_um_t wh = DK3_UM_0;
+#endif
+ uint32 w;
+ uint32 h;
+ int back = 0;
+ int me = 0;
+ size_t sz;
+#if VERSION_BEFORE_20150821
+ uint16 cps;
+ uint16 spp;
+#endif
+ uint16 ru;
+ uint16 orient;
+ $? "+ dk3bif_read_tiff_header"
+ if(bp->tmpfn) { $? ". have tmpfn"
+ dis = dk3_new_app(dk3_bif_tiff_t,1,bp->app);
+ if(dis) { $? ". dis"
+ /*
+ Initialization of TIFF per file.
+ */
+ bp->implspec = (void *)dis;
+ dis->tiff = NULL;
+ dis->tiff = TIFFOpen(bp->tmpfn, "rb");
+ if(dis->tiff) { $? ". TIFFOpen"
+ back = 1;
+ do { $? ". loop start"
+ w = h = 0UL; rv = 0.0; ru = 0;
+#if VERSION_BEFORE_20150821
+ cps = spp = 0U;
+#endif
+ bp->cf = dk3bif_frame_new(bp);
+ if(bp->cf) { $? ". frame ok"
+ (bp->cf)->realbits = (bp->cf)->bits = 8;
+ (bp->cf)->cs = DK3_COLOR_SPACE_RGBA;
+ fdis = dk3_new_app(dk3_bif_frame_tiff_t,1,bp->app);
+ if(fdis) { $? ". fdis ok"
+ /*
+ Initialize TIFF per frame.
+ */
+ fdis->w = fdis->h = 0UL; fdis->cps = fdis->spp = 0U;
+ fdis->r = NULL;
+ fdis->ori = ORIENTATION_BOTLEFT;
+ (bp->cf)->implspec = (void *)fdis;
+ if(TIFFGetField(dis->tiff, TIFFTAG_IMAGEWIDTH, &w) == 1) {
+ fdis->w = w; $? ". width ok"
+ (bp->cf)->w = (dk3_bif_coord_t)w;
+ if(TIFFGetField(dis->tiff, TIFFTAG_IMAGELENGTH, &h) == 1) {
+ fdis->h = h; $? ". height ok"
+ (bp->cf)->h = (dk3_bif_coord_t)h;
+ rv = 0.0;
+ if(TIFFGetField(dis->tiff, TIFFTAG_XRESOLUTION, &rv) == 1) {
+ (bp->cf)->xres = (double)rv; $? ". x resolution found"
+ }
+ rv = 0.0;
+ if(TIFFGetField(dis->tiff, TIFFTAG_YRESOLUTION, &rv) == 1) {
+ (bp->cf)->yres = (double)rv; $? ". y resolution found"
+ }
+ ru = 0;
+ if(TIFFGetField(dis->tiff, TIFFTAG_RESOLUTIONUNIT, &ru) == 1)
+ { $? ". resolution unit found"
+ switch(ru) {
+ case RESUNIT_CENTIMETER: { $? ". unit cm"
+ (bp->cf)->xres = 2.54 * (bp->cf)->xres;
+ (bp->cf)->yres = 2.54 * (bp->cf)->yres;
+ } break;
+ case RESUNIT_NONE: { $? ". other unit"
+ (bp->cf)->xres = (bp->cf)->yres = -1.0;
+ } break;
+ }
+ }
+ orient = ORIENTATION_TOPLEFT;
+ if(TIFFGetFieldDefaulted(
+ dis->tiff, TIFFTAG_ORIENTATION, &orient
+ ) == 1
+ )
+ { $? ". orientation = %u", (unsigned)orient
+ fdis->ori = orient;
+ switch(orient) {
+ case 5: case 6: case 7: case 8: { $? ". swap w/h"
+ fdis->h = w;
+ (bp->cf)->h = w;
+ fdis->w = h;
+ (bp->cf)->w = h;
+ rv = (float)((bp->cf)->xres);
+ (bp->cf)->xres = (bp->cf)->yres;
+ (bp->cf)->yres = rv;
+ } break;
+ }
+ } else {
+ orient = ORIENTATION_TOPLEFT;
+ }
+#if VERSION_BEFORE_20140809
+ wh = dk3ma_ul_mul_ok(w, h, &me);
+ wh = dk3ma_ul_mul_ok(4UL, wh, &me);
+#else
+ wh = dk3ma_um_mul_ok((dk3_um_t)w, (dk3_um_t)h, &me);
+ wh = dk3ma_um_mul_ok((dk3_um_t)4U, wh, &me);
+#endif
+ if(me) {
+ back = 0; $? "! math error"
+ } else { $? ". wh product ok"
+#if VERSION_BEFORE_20140809
+ sz = (size_t)wh;
+ if(wh == (unsigned long)sz)
+#else
+ sz = dk3ma_um_to_sz(wh, &me);
+ if (0 != sz)
+#endif
+ { $? ". wh ok"
+ fdis->r = (uint32 *)_TIFFmalloc(sz);
+ if(fdis->r) { $? ". allocation ok"
+ if(TIFFReadRGBAImageOriented(
+ dis->tiff, w, h, fdis->r, orient, 0
+ )
+ )
+ {
+#if TRACE_DEBUG || VERSION_BEFORE_20150821
+ back = 1; $? ". image was read"
+#endif
+ } else { $? "! read image failed"
+ back = 0;
+ }
+ } else { $? "! memory"
+ back = 0;
+ }
+ } else {
+ back = 0; $? "! numeric overflow"
+ }
+ }
+ } else { $? "! height not found"
+ back = 0;
+ }
+ } else { $? "! width not found"
+ back = 0;
+ }
+ } else {
+ back = 0; $? "! memory fdis"
+ }
+ } else {
+ back = 0; $? "! memory bp->cf"
+ }
+ w = h = 0UL;
+#if VERSION_BEFORE_20150821
+ cps = spp = 0U;
+#endif
+ $? ". loop end"
+ } while((back == 1) && TIFFReadDirectory(dis->tiff));
+ TIFFClose(dis->tiff); dis->tiff = NULL; $? ". tiff file closed"
+ if(bp->i_frames) { $? ". i_frames"
+ dk3sto_it_reset(bp->i_frames);
+ bp->cf = (dk3_bif_frame_t *)dk3sto_it_next(bp->i_frames);
+ if(!(bp->cf)) { $? "! no frame"
+ back = 0;
+ }
+ } else { $? "! i_frames"
+ }
+ } else { $? "! TIFFOpen"
+ }
+ } else { $? "! dis"
+ }
+ } else { $? "! no file name"
+ } $? "- dk3bif_read_tiff_header %d", back
+ return back;
+}
+
+
+
+
+/** Read data for TIFF image.
+ @param bp Bitmap image file.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bif_read_tiff_data(dk3_bif_t *bp)
+{
+ int back = 0;
+ if(bp->i_frames) {
+ dk3sto_it_reset(bp->i_frames);
+ bp->cf = (dk3_bif_frame_t *)dk3sto_it_next(bp->i_frames);
+ if(bp->cf) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+/** Retrieve one pixel component from TIFF.
+ @param bp Bitmap image.
+ @param x X coordinate.
+ @param y Y coordinate.
+ @param c Choose component: 0=red/gray, 1=green, 2=blue, 3=alpha.
+ @return Pixel component.
+*/
+static
+dk3_bif_pixel_t
+dk3bif_get_tiff_pixel_component(
+ dk3_bif_t *bp,
+ dk3_bif_coord_t x,
+ dk3_bif_coord_t y,
+ int c
+)
+{
+ dk3_bif_frame_tiff_t *fdis;
+ dk3_bif_pixel_t back = (dk3_bif_pixel_t)0;
+ uint32 uv;
+ if(bp) {
+ if(bp->cf) {
+ if(bp->implspec) {
+ if((bp->cf)->implspec) {
+ fdis = (dk3_bif_frame_tiff_t *)((bp->cf)->implspec);
+ if(fdis->r) {
+ uv = (fdis->r)[y * (bp->cf)->w + x];
+ /*
+ uv = (fdis->r)[((bp->cf)->h - y - 1) * (bp->cf)->w + x];
+ */
+ switch(c) {
+ case 3: {
+ uv = ((uv >> 24) & 0x000000FFUL);
+ } break;
+ case 2: {
+ uv = ((uv >> 16) & 0x000000FFUL);
+ } break;
+ case 1: {
+ uv = ((uv >> 8) & 0x000000FFUL);
+ } break;
+ default: {
+ uv = (uv & 0x000000FFUL);
+ } break;
+ }
+ back = (dk3_bif_pixel_t)uv;
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+#endif
+/* if DK3_HAVE_TIFF_H */
+
+
+
+/** Calculate gray value from red, green, blue.
+ @param r Red value.
+ @param g Green value.
+ @param b Blue value.
+ @return Gray value.
+*/
+static
+dk3_bif_pixel_t
+dk3bif_ntsc(dk3_bif_pixel_t r, dk3_bif_pixel_t g, dk3_bif_pixel_t b)
+{
+ dk3_bif_pixel_t back;
+ back = (dk3_bif_pixel_t)(
+ (
+ 30UL * (unsigned long)r
+ + 59UL * (unsigned long)g
+ + 11UL * (unsigned long)b
+ ) / 100UL
+ );
+ return back;
+}
+
+
+
+/** Delete BIF frame, release memory.
+ @param tp Image type.
+ @param fp Frame to delete.
+*/
+static
+void
+dk3bif_frame_delete(dk3_bif_frame_t *fp, int tp)
+{
+ $? "+ dk3bif_frame_delete %!8s", TR_8PTR(fp)
+ if(fp) {
+ /*
+ Release type-depending components.
+ */
+ if(fp->implspec) {
+ switch(tp) {
+ case DK3_BIF_IMAGE_TYPE_PNG: {
+#if DK3_HAVE_PNG_H
+ dk3bif_frame_release_implspec_png(fp->implspec);
+#endif
+ } break;
+ case DK3_BIF_IMAGE_TYPE_JPEG: {
+#if DK3_HAVE_JPEGLIB_H
+ dk3bif_frame_release_implspec_jpeg(fp->implspec);
+#endif
+ } break;
+ case DK3_BIF_IMAGE_TYPE_TIFF: {
+#if DK3_HAVE_TIFF_H
+ dk3bif_frame_release_implspec_tiff(fp->implspec);
+#endif
+ } break;
+ }
+ }
+ fp->implspec = NULL;
+ /*
+ Release type-independent components.
+ */
+ fp->w = fp->h = 0L; fp->realbits = fp->bits = fp->n = 0; fp->cs = 0;
+ /*
+ Release frame itself.
+ */
+ dk3_delete(fp);
+ } $? "- dk3bif_frame_delete"
+}
+
+
+
+/** Allocate memory for new frame.
+ @param bp Bitmap image file.
+ @return Pointer to new frame on success, NULL on error.
+*/
+static
+dk3_bif_frame_t *
+dk3bif_frame_new(dk3_bif_t *bp)
+{
+ dk3_bif_frame_t *back = NULL;
+ back = dk3_new_app(dk3_bif_frame_t,1,bp->app);
+ if(back) {
+ back->implspec = NULL;
+ back->xres = -1.0;
+ back->yres = -1.0;
+ back->w = 0L;
+ back->h = 0L;
+ back->realbits = back->bits = 0;
+ back->realcolor = 1;
+ back->realalpha = 1;
+ back->n = bp->n_frames;
+ back->cs = 0;
+ back->bg = 0; back->bgr = back->bgg = back->bgb = back->bggr = 0U;
+ if(dk3sto_add(bp->s_frames, (void *)back)) {
+ bp->n_frames += 1;
+ } else {
+ dk3bif_frame_delete(back, bp->bt); back = NULL;
+ }
+ }
+ return back;
+}
+
+
+
+dk3_bif_pixel_t
+dk3bif_get_pixel_component_not_resampled(
+ dk3_bif_t *bp,
+ dk3_bif_coord_t x,
+ dk3_bif_coord_t y,
+ int c
+)
+{
+ dk3_bif_pixel_t back = (dk3_bif_pixel_t)0;
+ $? "+ dk3bif_get_pixel_component_not_resampled %lu %lu %d", (unsigned long)x, (unsigned long)y, c
+ if(c == 3) { $? ". alpha component asked, default is full"
+ back = dk3pixre_get_max_value(&(bp->pr));
+ }
+ if((x >= 0L) && (x < (bp->cf)->w)) {
+ if((y >= 0L) && (y < (bp->cf)->h)) {
+ switch(bp->bt) {
+ case DK3_BIF_IMAGE_TYPE_PNG: {
+#if DK3_HAVE_PNG_H
+ back = dk3bif_get_png_pixel_component(bp, x, y, c);
+#endif
+ } break;
+ case DK3_BIF_IMAGE_TYPE_JPEG: {
+#if DK3_HAVE_JPEGLIB_H
+ back = dk3bif_get_jpeg_pixel_component(bp, x, y, c);
+#endif
+ } break;
+ case DK3_BIF_IMAGE_TYPE_TIFF: {
+#if DK3_HAVE_TIFF_H
+ back = dk3bif_get_tiff_pixel_component(bp, x, y, c);
+#endif
+ } break;
+ }
+ }
+ }
+ $? "- dk3bif_get_pixel_component_not_resampled %u", (unsigned)back
+ return back;
+}
+
+
+
+/** Retrieve one pixel component resampled to output bit size.
+ @param bp Bitmap image.
+ @param x X coordinate.
+ @param y Y coordinate.
+ @param c Choose component: 0=red/gray, 1=green, 2=blue, 3=alpha.
+ @return Pixel component.
+*/
+static
+dk3_bif_pixel_t
+dk3bif_get_pixel_component(
+ dk3_bif_t *bp,
+ dk3_bif_coord_t x,
+ dk3_bif_coord_t y,
+ int c
+)
+{
+ dk3_bif_pixel_t back;
+ $? "+ dk3bif_get_pixel_component %lu %lu %d", (unsigned long)x, (unsigned long)y, c
+ /*
+ Get unresampled value.
+ */
+ back = dk3bif_get_pixel_component_not_resampled(bp, x, y, c);
+ /*
+ Resample value to requested output bit size.
+ */
+ $? "- dk3bif_get_pixel_component %u", (unsigned)back
+ back = dk3pixre_convert(&(bp->pr), back);
+ return back;
+}
+
+
+/** Compare two frames by number.
+ @param l Left frame.
+ @param r Right frame or number.
+ @param cr Comparison criteria: 0=frame/frame, 1=frame/number.
+ @return Comparison result.
+*/
+static
+int
+dk3bif_frame_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3_bif_frame_t const *pl;
+ dk3_bif_frame_t const *pr;
+ size_t *psz;
+ if(l) {
+ if(r) {
+ pl = (dk3_bif_frame_t const *)l; pr = (dk3_bif_frame_t const *)r;
+ psz = (size_t *)r;
+ switch(cr) {
+ case 1: {
+ if(pl->n > *psz) {
+ back = 1;
+ } else {
+ if(pl->n < *psz) {
+ back = -1;
+ }
+ }
+ } break;
+ default: {
+ if(pl->n > pr->n) {
+ back = 1;
+ } else {
+ if(pl->n < pr->n) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Set up upsampling/downsampling after changing frame or
+ output bit number.
+ @param bp Bitmap image file.
+*/
+static
+void
+dk3bif_set_pixel_sampling(dk3_bif_t *bp)
+{
+ $? "+ dk3bif_set_pixel_sampling"
+ if(bp) {
+ if(bp->cf) {
+ if(bp->bits) { $? ". resampling probably needed"
+ dk3pixre_set(&(bp->pr), (bp->cf)->bits, bp->bits);
+ } else { $? ". no resampling required"
+ dk3pixre_set(&(bp->pr), (bp->cf)->bits, (bp->cf)->bits);
+ }
+ }
+ }
+ $? "- dk3bif_set_pixel_sampling"
+}
+
+
+
+/** Allocate memory for bitmap image file.
+ @param tp Image type.
+ @param app Application structure for diagnostics, may not be NULL.
+ @return Pointer to new structure on success, NULL on error.
+*/
+static
+dk3_bif_t *
+dk3bif_allocate_app(int tp, dk3_app_t *app)
+{
+ dk3_bif_t *back = NULL;
+ int ok = 0;
+ $? "+ dk3bif_allocate_app"
+ if(app) {
+ back = dk3_new_app(dk3_bif_t,1,app);
+ if(back) {
+ dk3pixre_set(&(back->pr), 8, 8);
+ back->app = app;
+ back->tmpfn = NULL;
+ back->tmpfipo = NULL;
+ back->s_frames = NULL;
+ back->i_frames = NULL;
+ back->cf = NULL;
+ back->implspec = NULL;
+ back->n = dk3bif_temp_number++;
+ back->n_frames = 0;
+ back->bits = 0;
+ back->bt = tp;
+ back->bg = 0;
+ back->remtmpf = 0;
+ back->bgr = back->bgg = back->bgb = 255U;
+ back->s_frames = dk3sto_open_app(app);
+ if(back->s_frames) {
+ dk3sto_set_comp(back->s_frames, dk3bif_frame_compare, 0);
+ back->i_frames = dk3sto_it_open(back->s_frames);
+ if(back->i_frames) {
+ ok = 1;
+ }
+ }
+ if(!(ok)) {
+ dk3bif_close(back);
+ back = NULL;
+ }
+ }
+ } $? "- dk3bif_allocate_app %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+/** Read image header information.
+ Create the frames, fill implspec for bif and frame.
+ @param bp Bitmap image file.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bif_read_header(dk3_bif_t *bp)
+{
+ int back = 0;
+ $? "+ dk3bif_read_header"
+ switch(bp->bt) {
+ case DK3_BIF_IMAGE_TYPE_PNG: {
+#if DK3_HAVE_PNG_H
+ back = dk3bif_read_png_header(bp);
+#endif
+ } break;
+ case DK3_BIF_IMAGE_TYPE_JPEG: {
+#if DK3_HAVE_JPEGLIB_H
+ back = dk3bif_read_jpeg_header(bp);
+#endif
+ } break;
+ case DK3_BIF_IMAGE_TYPE_TIFF: {
+#if DK3_HAVE_TIFF_H
+ back = dk3bif_read_tiff_header(bp);
+#endif
+ } break;
+ }
+ dk3bif_set_pixel_sampling(bp);
+ $? "- dk3bif_read_header %d", back
+ return back;
+}
+
+
+
+/** Create a temporary file name (8 bit characters).
+ @param fnb File name buffer.
+ @param bp Bitmap image file pointer.
+*/
+static
+void
+dk3bif_create_tmpfilename(char *fnb, dk3_bif_t *bp)
+{
+ $? "+ dk3bif_create_tmpfilename"
+#if DK3_ON_WINDOWS
+ sprintf(fnb, dk3bif_kw_c8[1], _getpid(), bp->n);
+#else
+#if DK3_HAVE_GETPID
+ sprintf(fnb, dk3bif_kw_c8[0], (unsigned long)getpid(), bp->n);
+#else
+ time_t timer;
+ time(&timer);
+ sprintf(fnb, dk3bif_kw_c8[0], (unsigned long)timer, bp->n);
+#endif
+#endif
+ $? "- dk3bif_create_tmpfilename"
+}
+
+
+
+/** Copy input file to temporary file.
+ This function relies on tmpfn set.
+ @param bp Bitmap image file.
+ @param fipos Source file, must be opened "rb".
+ @param app Application structure for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bif_copy_to_temp(dk3_bif_t *bp, FILE *fipos, dk3_app_t *app)
+{
+ char bu[4096]; /* Buffer. */
+ FILE *fipod; /* Destination file. */
+ int back = 0;
+ int cc = 1; /* Flag: Can continue copying. */
+ size_t rdb; /* Bytes read. */
+ $? "+ dk3bif_copy_to_temp"
+ fipod = dk3sf_c8_fopen_app(bp->tmpfn, "wb", app);
+ if(fipod) {
+ back = 1;
+ while(cc) {
+ cc = 0;
+ rdb = dk3sf_fread_app(bu, 1, sizeof(bu), fipos, app);
+ if(rdb > 0) {
+ if(dk3sf_fwrite_app(bu, 1, rdb, fipod, app)) {
+ cc = 1;
+ } else {
+ back = 0;
+ }
+ }
+ }
+#if DK3_CHAR_SIZE == 1
+ if(!dk3sf_fclose_fn_app(fipod, bp->tmpfn, app)) {
+ back = 0;
+ }
+#else
+ if(!dk3sf_fclose_fn_app(fipod, NULL, app)) {
+ back = 0;
+ }
+#endif
+ } $? "- dk3bif_copy_to_temp %d", back
+ return back;
+}
+
+
+
+/** Correct image type.
+ @param tp Original image type, may need correction.
+ @return Corrected value (set to DK3_BIF_IMAGE_TYPE_UNKNOWN
+ if necessary).
+*/
+static
+int
+dk3bif_correct_type(int tp)
+{
+ int back;
+ back = tp;
+ $? "+ dk3bif_correct_type %d", tp
+ if(tp != DK3_BIF_IMAGE_TYPE_PNG) {
+ if(tp != DK3_BIF_IMAGE_TYPE_JPEG) {
+ if(tp != DK3_BIF_IMAGE_TYPE_TIFF) {
+ /* +++ further file types here +++ */
+ back = DK3_BIF_IMAGE_TYPE_UNKNOWN;
+ }
+ }
+ } $? "- dk3bif_correct_type %d", back
+ return back;
+}
+
+
+
+dk3_bif_t *
+dk3bif_open_filename_app(dkChar const *fn, int tp, dk3_app_t *app)
+{
+ char fnb[128]; /* File name buffer for temp file. */
+ dk3_bif_t *back = NULL;
+ FILE *fipos;
+ int mytp; /* Type, corrected if necessary. */
+ int ok = 0; /* Flag: Success. */
+ $? "+ dk3bif_open_filename_app"
+ mytp = dk3bif_correct_type(tp);
+ if((fn) && (app)) {
+ if(mytp == DK3_BIF_IMAGE_TYPE_UNKNOWN) {
+ mytp = dk3bif_check_file_name(fn);
+ }
+ if(dk3bif_type_supported(mytp)) {
+ back = dk3bif_allocate_app(mytp, app);
+ if(back) {
+ switch(back->bt) {
+ case DK3_BIF_IMAGE_TYPE_TIFF: {
+ dk3bif_create_tmpfilename(fnb, back);
+ back->tmpfn = dk3str_c8_dup_app(fnb, NULL);
+ if(back->tmpfn) {
+ back->remtmpf = 1;
+ fipos = dk3sf_fopen_app(fn, dk3bif_kw_dk[0], app);
+ if(fipos) {
+ ok = dk3bif_copy_to_temp(back, fipos, app);
+ fclose(fipos);
+ if(ok) {
+ ok = dk3bif_read_header(back);
+ }
+ }
+ }
+ } break;
+ default: {
+ back->tmpfipo = dk3sf_fopen_app(fn, dk3bif_kw_dk[0], app);
+ if(back->tmpfipo) {
+ ok = dk3bif_read_header(back);
+ }
+ } break;
+ }
+ if(!(ok)) {
+ dk3bif_close(back); back = NULL;
+ }
+ }
+ } else {
+ if(app) {
+ /* ERROR: File type unknown or unsupported! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 257);
+ }
+ }
+ } $? "- dk3bif_open_filename_app %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+dk3_bif_t *
+dk3bif_open_c8_filename_app(char const *fn, int tp, dk3_app_t *app)
+{
+ dk3_bif_t *back = NULL;
+ int mytp; /* Type, corrected if necessary. */
+ int ok = 0; /* Flag: Success. */
+ $? "+ dk3bif_open_c8_filename_app"
+ mytp = dk3bif_correct_type(tp);
+ if((fn) && (app)) {
+ if(mytp == DK3_BIF_IMAGE_TYPE_UNKNOWN) {
+ mytp = dk3bif_check_c8_file_name(fn);
+ }
+ if(dk3bif_type_supported(mytp)) {
+ back = dk3bif_allocate_app(mytp, app);
+ if(back) {
+ switch(back->bt) {
+ case DK3_BIF_IMAGE_TYPE_TIFF: {
+ back->tmpfn = dk3str_c8_dup_app(fn, NULL);
+ if(back->tmpfn) {
+ ok = dk3bif_read_header(back);
+ }
+ } break;
+ default: {
+ back->tmpfipo = dk3sf_c8_fopen_app(fn, "rb", app);
+ if(back->tmpfipo) {
+ ok = dk3bif_read_header(back);
+ }
+ } break;
+ }
+ if(!(ok)) {
+ dk3bif_close(back); back = NULL;
+ }
+ }
+ } else {
+ if(app) {
+ /* ERROR: File type unknown or unsupported! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 257);
+ }
+ }
+ } $? "- dk3bif_open_c8_filename_app %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+dk3_bif_t *
+dk3bif_open_file_app(FILE *fipo, int tp, dk3_app_t *app)
+{
+ char fnb[128];
+ dk3_bif_t *back = NULL;
+ int ok = 0;
+ int mytp;
+ $? "+ dk3bif_open_file_app"
+ mytp = dk3bif_correct_type(tp);
+ if((fipo) && (app) && (mytp != DK3_BIF_IMAGE_TYPE_UNKNOWN)) {
+ if(dk3bif_type_supported(mytp)) {
+ back = dk3bif_allocate_app(mytp, app);
+ if(back) {
+ dk3bif_create_tmpfilename(fnb, back);
+ back->tmpfn = dk3str_c8_dup_app(fnb, NULL);
+ if(back->tmpfn) {
+ back->remtmpf = 1;
+ if(dk3bif_copy_to_temp(back, fipo, app)) {
+ ok = dk3bif_read_header(back);
+ }
+ }
+ if(!(ok)) {
+ dk3bif_close(back); back = NULL;
+ }
+ }
+ } else {
+ /* ERROR: Unknown/unsupported file type! */
+ if(app) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 257);
+ }
+ }
+ } $? "- dk3bif_open_file_app %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+void
+dk3bif_close(dk3_bif_t *bp)
+{
+ dk3_bif_frame_t *fp;
+ $? "+ dk3bif_close"
+ if(bp) {
+ /*
+ Release image type specific data per frame.
+ */
+ if(bp->s_frames) {
+ if(bp->i_frames) {
+ dk3sto_it_reset(bp->i_frames);
+ while((fp = (dk3_bif_frame_t *)dk3sto_it_next(bp->i_frames)) != NULL) {
+ /* Close and delete frame. */
+ dk3bif_frame_delete(fp, bp->bt);
+ }
+ dk3sto_it_close(bp->i_frames);
+ }
+ dk3sto_close(bp->s_frames);
+ }
+ bp->s_frames = NULL; bp->i_frames = NULL; bp->cf = NULL;
+ /*
+ Release image type specific data for file.
+ */
+ if(bp->implspec) {
+ switch(bp->bt) {
+ case DK3_BIF_IMAGE_TYPE_PNG: {
+#if DK3_HAVE_PNG_H
+ dk3bif_release_implspec_png(bp->implspec);
+#endif
+ } break;
+ case DK3_BIF_IMAGE_TYPE_JPEG: {
+#if DK3_HAVE_JPEGLIB_H
+ dk3bif_release_implspec_jpeg(bp->implspec);
+#endif
+ } break;
+ case DK3_BIF_IMAGE_TYPE_TIFF: {
+#if DK3_HAVE_TIFF_H
+ dk3bif_release_implspec_tiff(bp->implspec);
+#endif
+ } break;
+ }
+ }
+ bp->implspec = NULL;
+ bp->n = 0UL;
+ bp->n_frames = 0;
+ bp->bits = 0;
+ bp->bt = DK3_BIF_IMAGE_TYPE_UNKNOWN;
+ /*
+ Close file if open.
+ */
+ if(bp->tmpfipo) { $? ". close file"
+ fclose(bp->tmpfipo); bp->tmpfipo = NULL;
+ }
+ /*
+ Delete file and release file name memory.
+ */
+ if(bp->tmpfn) { $? ". delete temp file name and remove file"
+ if(bp->remtmpf) {
+ dk3sf_c8_remove_file_app(bp->tmpfn, bp->app);
+ }
+ dk3_release(bp->tmpfn);
+ }
+ bp->app = NULL;
+ dk3_delete(bp);
+ } $? "- dk3bif_close"
+}
+
+
+
+int
+dk3bif_check_suffix_without_dot(dkChar const *sn)
+{
+ int back = DK3_BIF_IMAGE_TYPE_UNKNOWN;
+ int tp = -1;
+ $? "+ dk3bif_check_suffix_without_dot"
+ if(sn) {
+ tp = dk3str_array_index(dk3bif_dk_type_names, sn, 0); $? ". tp=%d", tp
+ switch(tp) {
+ case 0: { $? ". png"
+ back = DK3_BIF_IMAGE_TYPE_PNG;
+ } break;
+ case 1: case 2: { $? ". jpeg"
+ back = DK3_BIF_IMAGE_TYPE_JPEG;
+ } break;
+ case 3: case 4: { $? ". tiff"
+ back = DK3_BIF_IMAGE_TYPE_TIFF;
+ } break;
+ }
+ } $? "- dk3bif_check_suffix_without_dot %d", back
+ return back;
+}
+
+
+
+int
+dk3bif_check_c8_suffix_without_dot(char const *sn)
+{
+ int back = DK3_BIF_IMAGE_TYPE_UNKNOWN;
+ int tp = -1;
+ if(sn) {
+ tp = dk3str_c8_array_index(dk3bif_c8_type_names, sn, 0);
+ switch(tp) {
+ case 0: { back = DK3_BIF_IMAGE_TYPE_PNG; } break;
+ case 1: case 2: { back = DK3_BIF_IMAGE_TYPE_JPEG; } break;
+ case 3: case 4: { back = DK3_BIF_IMAGE_TYPE_TIFF; } break;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3bif_check_file_name(dkChar const *fn)
+{
+ int back = DK3_BIF_IMAGE_TYPE_UNKNOWN;
+ dkChar const *sp;
+ $? "+ dk3bif_check_file_name"
+ if(fn) {
+ sp = dk3str_get_suffix(fn);
+ if(sp) {
+ sp++;
+ back = dk3bif_check_suffix_without_dot(sp);
+ }
+ } $? "- dk3bif_check_file_name %d", back
+ return back;
+}
+
+
+
+int
+dk3bif_check_c8_file_name(char const *fn)
+{
+ int back = DK3_BIF_IMAGE_TYPE_UNKNOWN;
+ char const *sp;
+ if(fn) {
+ sp = dk3str_c8_get_suffix(fn);
+ if(sp) {
+ sp++;
+ back = dk3bif_check_c8_suffix_without_dot(sp);
+ }
+ }
+ return back;
+}
+
+
+
+
+/** Transfer background color from image to frame.
+ @param bp Bitmap image file (source).
+ @param fr Frame (destination).
+*/
+void
+dk3_bif_transfer_background(dk3_bif_t *bp, dk3_bif_frame_t *fr)
+{
+ dk3_pixel_resample_t pixre;
+ dk3pixre_set(&pixre, 8, fr->bits);
+ fr->bgr = dk3pixre_convert(&pixre, bp->bgr);
+ fr->bgg = dk3pixre_convert(&pixre, bp->bgg);
+ fr->bgb = dk3pixre_convert(&pixre, bp->bgb);
+}
+
+
+
+int
+dk3bif_read_data(dk3_bif_t *bp)
+{
+ int back = 0;
+ dk3_bif_frame_t *fr = NULL;
+ $? "+ dk3bif_read_data"
+ if(bp) {
+ switch(bp->bt) {
+ case DK3_BIF_IMAGE_TYPE_PNG: {
+#if DK3_HAVE_PNG_H
+ back = dk3bif_read_png_data(bp);
+#endif
+ } break;
+ case DK3_BIF_IMAGE_TYPE_JPEG: {
+#if DK3_HAVE_JPEGLIB_H
+ $? ". read jpeg"
+ back = dk3bif_read_jpeg_data(bp);
+ $? ". jpeg read successfully"
+#endif
+ } break;
+ case DK3_BIF_IMAGE_TYPE_TIFF: {
+#if DK3_HAVE_TIFF_H
+ back = dk3bif_read_tiff_data(bp);
+#endif
+ } break;
+ }
+ }
+ if(back) {
+ dk3sto_it_reset(bp->i_frames);
+ while((fr = (dk3_bif_frame_t *)dk3sto_it_next(bp->i_frames)) != NULL) {
+ /*
+ The following settings are overwritten by dk3bif_analyze().
+ */
+ switch(fr->cs) {
+ case DK3_COLOR_SPACE_GRAY:
+ case DK3_COLOR_SPACE_GRAY_ALPHA:
+ {
+ fr->realcolor = 0;
+ }
+ break;
+ default:
+ {
+ fr->realcolor = 1;
+ }
+ break;
+ }
+ switch(fr->cs) {
+ case DK3_COLOR_SPACE_GRAY_ALPHA:
+ case DK3_COLOR_SPACE_RGBA: {
+ fr->realalpha = 1;
+ } break;
+ default: {
+ fr->realalpha = 0;
+ } break;
+ }
+ fr->realbits = fr->bits;
+ /*
+ Obtain background color from per-file settings.
+ */
+ if((!(fr->bg)) || (bp->bg)) {
+ dk3_bif_transfer_background(bp, fr);
+ }
+ fr->bggr = dk3bif_ntsc(fr->bgr, fr->bgg, fr->bgb);
+ }
+ dk3sto_it_reset(bp->i_frames);
+ bp->cf = (dk3_bif_frame_t *)dk3sto_it_next(bp->i_frames);
+ if(!(bp->cf)) { back = 0; }
+ }
+ dk3bif_set_pixel_sampling(bp);
+ $? "- dk3bif_read_data %d", back
+ return back;
+}
+
+
+
+size_t
+dk3bif_number_of_frames(dk3_bif_t *bp)
+{
+ size_t back = 0;
+ $? "+ dk3bif_number_of_frames"
+ if(bp) {
+ back = bp->n_frames;
+ } $? "- dk3bif_number_of_frames %u", (unsigned)back
+ return back;
+}
+
+
+
+int
+dk3bif_set_frame(dk3_bif_t *bp, size_t fn)
+{
+ int back = 0;
+ $? "+ dk3bif_set_frame %u", (unsigned)fn
+ if(bp) {
+ bp->cf =
+ (dk3_bif_frame_t *)dk3sto_it_find_like(bp->i_frames, (void *)(&fn), 1);
+ if(bp->cf) {
+ back = 1;
+ dk3bif_set_pixel_sampling(bp);
+ } else {
+ dk3sto_it_reset(bp->i_frames);
+ }
+ } $? "- dk3bif_set_frame %d", back
+ return back;
+}
+
+
+
+size_t
+dk3bif_get_bits_per_pixel(dk3_bif_t *bp)
+{
+ size_t back = 0;
+ $? "+ dk3bif_get_bits_per_pixel"
+ if(bp) {
+ if(bp->cf) {
+ back = (bp->cf)->bits;
+ }
+ } $? "- dk3bif_get_bits_per_pixel %u", (unsigned)back
+ return back;
+}
+
+
+
+size_t
+dk3bif_real_bits_per_pixel(dk3_bif_t *bp)
+{
+ size_t back = 0;
+ $? "+ dk3bif_real_bits_per_pixel"
+ if(bp) {
+ if(bp->cf) {
+ back = (bp->cf)->realbits;
+ }
+ } $? "- dk3bif_real_bits_per_pixel %u", (unsigned)back
+ return back;
+}
+
+
+
+int
+dk3bif_real_color(dk3_bif_t *bp)
+{
+ int back = 0;
+ if(bp) {
+ if(bp->cf) {
+ back = (bp->cf)->realcolor;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3bif_real_alpha(dk3_bif_t *bp)
+{
+ int back = 0;
+ if(bp) {
+ if(bp->cf) {
+ back = (bp->cf)->realalpha;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3bif_set_bits_per_pixel(dk3_bif_t *bp, size_t sz)
+{
+ int back = 0;
+ $? "+ dk3bif_set_bits_per_pixel"
+ if((bp) && (sz)) {
+ if(sz < 17) {
+ bp->bits = sz;
+ dk3bif_set_pixel_sampling(bp);
+ back = 1;
+ } else {
+ bp->bits = 16;
+ dk3bif_set_pixel_sampling(bp);
+ /* Maximum number of bits exceeded! */
+ if(bp->app) {
+ dk3app_log_i1(bp->app, DK3_LL_WARNING, 258);
+ }
+ }
+ } $? "- dk3bif_set_bits_per_pixel %d", back
+ return back;
+}
+
+
+
+dk3_bif_coord_t
+dk3bif_get_width(dk3_bif_t *bp)
+{
+ dk3_bif_coord_t back = 0L;
+ $? "+ dk3bif_get_width"
+ if(bp) {
+ if(bp->cf) {
+ back = (bp->cf)->w;
+ }
+ } $? "- dk3bif_get_width %ld", (long)back
+ return back;
+}
+
+
+
+dk3_bif_coord_t
+dk3bif_get_height(dk3_bif_t *bp)
+{
+ dk3_bif_coord_t back = 0L;
+ $? "+ dk3bif_get_height"
+ if(bp) {
+ if(bp->cf) {
+ back = (bp->cf)->h;
+ }
+ } $? "- dk3bif_get_height %ld", (long)back
+ return back;
+}
+
+
+
+dk3_bif_coord_t
+dk3bif_get_largest_width(dk3_bif_t *bp)
+{
+ dk3_bif_frame_t *fp;
+ dk3_bif_coord_t back = 0L;
+ $? "+ dk3bif_get_largest_width"
+ if(bp) {
+ dk3sto_it_reset(bp->i_frames);
+ while((fp = (dk3_bif_frame_t *)dk3sto_it_next(bp->i_frames)) != NULL) {
+ if(fp->w > back) { back = fp->w; }
+ }
+ } $? "- dk3bif_get_largest_width %ld", (long)back
+ return back;
+}
+
+
+
+dk3_bif_coord_t
+dk3bif_get_largest_height(dk3_bif_t *bp)
+{
+ dk3_bif_frame_t *fp;
+ dk3_bif_coord_t back = 0L;
+ $? "+ dk3bif_get_largest_height"
+ if(bp) {
+ dk3sto_it_reset(bp->i_frames);
+ while((fp = (dk3_bif_frame_t *)dk3sto_it_next(bp->i_frames)) != NULL) {
+ if(fp->h > back) { back = fp->h; }
+ }
+ }
+ $? "- dk3bif_get_largest_height %ld", (long)back
+ return back;
+}
+
+
+
+dk3_bif_pixel_t
+dk3bif_get_red(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y)
+{
+ dk3_bif_pixel_t back = (dk3_bif_pixel_t)0;
+ $? "+ dk3bif_get_red"
+ if(bp) {
+ if(bp->cf) {
+ switch((bp->cf)->cs) {
+ case DK3_COLOR_SPACE_GRAY:
+ case DK3_COLOR_SPACE_GRAY_ALPHA:
+ {
+ back = dk3bif_get_pixel_component(bp, x, y, 0);
+ } break;
+ case DK3_COLOR_SPACE_RGB:
+ case DK3_COLOR_SPACE_RGBA:
+ {
+ back = dk3bif_get_pixel_component(bp, x, y, 0);
+ } break;
+ }
+ }
+ } $? "- dk3bif_get_red %ld %ld %u", (long)x, (long)y, (unsigned)back
+ return back;
+}
+
+
+
+dk3_bif_pixel_t
+dk3bif_get_green(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y)
+{
+ dk3_bif_pixel_t back = (dk3_bif_pixel_t)0;
+ $? "+ dk3bif_get_green"
+ if(bp) {
+ if(bp->cf) {
+ switch((bp->cf)->cs) {
+ case DK3_COLOR_SPACE_GRAY:
+ case DK3_COLOR_SPACE_GRAY_ALPHA:
+ {
+ back = dk3bif_get_pixel_component(bp, x, y, 0);
+ } break;
+ case DK3_COLOR_SPACE_RGB:
+ case DK3_COLOR_SPACE_RGBA:
+ {
+ back = dk3bif_get_pixel_component(bp, x, y, 1);
+ } break;
+ }
+ }
+ } $? "- dk3bif_get_green %ld %ld %u", (long)x, (long)y, (unsigned)back
+ return back;
+}
+
+
+
+dk3_bif_pixel_t
+dk3bif_get_blue(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y)
+{
+ dk3_bif_pixel_t back = (dk3_bif_pixel_t)0;
+ $? "+ dk3bif_get_blue"
+ if(bp) {
+ if(bp->cf) {
+ switch((bp->cf)->cs) {
+ case DK3_COLOR_SPACE_GRAY:
+ case DK3_COLOR_SPACE_GRAY_ALPHA:
+ {
+ back = dk3bif_get_pixel_component(bp, x, y, 0);
+ } break;
+ case DK3_COLOR_SPACE_RGB:
+ case DK3_COLOR_SPACE_RGBA:
+ {
+ back = dk3bif_get_pixel_component(bp, x, y, 2);
+ } break;
+ }
+ }
+ } $? "- dk3bif_get_blue %ld %ld %u", (long)x, (long)y, (unsigned)back
+ return back;
+}
+
+
+
+dk3_bif_pixel_t
+dk3bif_get_gray(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y)
+{
+ dk3_bif_pixel_t back = (dk3_bif_pixel_t)0;
+ $? "+ dk3bif_get_gray"
+ if(bp) {
+ if(bp->cf) {
+ switch((bp->cf)->cs) {
+ case DK3_COLOR_SPACE_GRAY:
+ case DK3_COLOR_SPACE_GRAY_ALPHA:
+ {
+ back = dk3bif_get_pixel_component(bp, x, y, 0);
+ } break;
+ case DK3_COLOR_SPACE_RGB:
+ case DK3_COLOR_SPACE_RGBA:
+ {
+ back = dk3bif_ntsc(
+ dk3bif_get_pixel_component(bp, x, y, 0),
+ dk3bif_get_pixel_component(bp, x, y, 1),
+ dk3bif_get_pixel_component(bp, x, y, 2)
+ );
+ back &= dk3pixre_get_max_value(&(bp->pr));
+ $? ". r=%u g=%u b=%u gray=%u", dk3bif_get_pixel_component(bp, x, y, 0), dk3bif_get_pixel_component(bp, x, y, 1), dk3bif_get_pixel_component(bp, x, y, 2), back
+ } break;
+ }
+ }
+ } $? "- dk3bif_get_gray %u", (unsigned)back
+ return back;
+}
+
+
+
+dk3_bif_pixel_t
+dk3bif_get_alpha(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y)
+{
+ dk3_bif_pixel_t back = (dk3_bif_pixel_t)0;
+ $? "+ dk3bif_get_alpha"
+ if(bp) {
+ back = dk3pixre_get_max_value(&(bp->pr));
+ if(bp->cf) {
+ switch((bp->cf)->cs) {
+ case DK3_COLOR_SPACE_GRAY_ALPHA:
+ case DK3_COLOR_SPACE_RGBA:
+ {
+ back = dk3bif_get_pixel_component(bp, x, y, 3);
+ } break;
+ default: {
+ if((x >= 0L) && (x < (bp->cf)->w)) {
+ if((y >= 0L) && (y < (bp->cf)->h)) {
+ back = dk3pixre_get_max_value(&(bp->pr));
+ }
+ }
+ } break;
+ }
+ }
+ } $? "- dk3bif_get_alpha %u", (unsigned)back
+ return back;
+}
+
+
+
+/** Mix pixel value against background value.
+ @param v Pixel value.
+ @param w Background value.
+ @param a Alpha channel value (opacity).
+ @param m Maximum alpha value.
+ @return Mixing result.
+*/
+static
+dk3_bif_pixel_t
+dk3bif_mix(
+ dk3_bif_pixel_t v,
+ dk3_bif_pixel_t w,
+ dk3_bif_pixel_t a,
+ dk3_bif_pixel_t m
+)
+{
+ unsigned long l1, l2, l3, l4, l5, l6;
+ dk3_bif_pixel_t back;
+ dk3_bif_pixel_t b;
+ int me = 0;
+
+ back = v;
+ b = m - a;
+ l1 = (unsigned long)v;
+ l2 = (unsigned long)a;
+ l3 = (unsigned long)w;
+ l4 = (unsigned long)b;
+ l5 = (unsigned long)m;
+ l6 = dk3ma_ul_div_ok(
+ dk3ma_ul_add_ok(
+ dk3ma_ul_mul_ok(l1, l2, &me),
+ dk3ma_ul_mul_ok(l3, l4, &me),
+ &me
+ ),
+ l5,
+ &me
+ );
+ if(me == 0) {
+ back = (((dk3_bif_pixel_t)l6) & m);
+ }
+ return back;
+}
+
+
+
+dk3_bif_pixel_t
+dk3bif_get_mixed_red(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y)
+{
+ dk3_bif_pixel_t back = 0U;
+ $? "+ dk3bif_get_mixed_red"
+ back = dk3bif_get_red(bp, x, y);
+ if(bp->cf) {
+ switch((bp->cf)->cs) {
+ case DK3_COLOR_SPACE_GRAY_ALPHA: case DK3_COLOR_SPACE_RGBA: {
+ back = dk3bif_mix(
+ back,
+ (bp->cf)->bgr,
+ dk3bif_get_alpha(bp, x, y),
+ dk3pixre_get_max_value(&(bp->pr))
+ );
+ } break;
+ }
+ } $? "- dk3bif_get_mixed_red %ld %ld %u", (long)x, (long)y, (unsigned)back
+ return back;
+}
+
+
+
+dk3_bif_pixel_t
+dk3bif_get_mixed_green(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y)
+{
+ dk3_bif_pixel_t back = 0U;
+ $? "+ dk3bif_get_mixed_green"
+ back = dk3bif_get_green(bp, x, y);
+ if(bp->cf) {
+ switch((bp->cf)->cs) {
+ case DK3_COLOR_SPACE_GRAY_ALPHA: case DK3_COLOR_SPACE_RGBA: {
+ back = dk3bif_mix(
+ back,
+ (bp->cf)->bgg,
+ dk3bif_get_alpha(bp, x, y),
+ dk3pixre_get_max_value(&(bp->pr))
+ );
+ } break;
+ }
+ } $? "- dk3bif_get_mixed_green %ld %ld %u", (long)x, (long)y, (unsigned)back
+ return back;
+}
+
+
+
+dk3_bif_pixel_t
+dk3bif_get_mixed_blue(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y)
+{
+ dk3_bif_pixel_t back = 0U;
+ $? "+ dk3bif_get_mixed_blue"
+ back = dk3bif_get_blue(bp, x, y);
+ if(bp->cf) {
+ switch((bp->cf)->cs) {
+ case DK3_COLOR_SPACE_GRAY_ALPHA: case DK3_COLOR_SPACE_RGBA: {
+ back = dk3bif_mix(
+ back,
+ (bp->cf)->bgb,
+ dk3bif_get_alpha(bp, x, y),
+ dk3pixre_get_max_value(&(bp->pr))
+ );
+ } break;
+ }
+ } $? "- dk3bif_get_mixed_blue %ld %ld %u", (long)x, (long)y, (unsigned)back
+ return back;
+}
+
+
+
+dk3_bif_pixel_t
+dk3bif_get_mixed_gray(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y)
+{
+ dk3_bif_pixel_t back = 0U;
+ $? "+ dk3bif_get_mixed_gray %ld %ld", x, y
+ back = dk3bif_get_gray(bp, x, y);
+ if(bp->cf) {
+ switch((bp->cf)->cs) {
+ case DK3_COLOR_SPACE_GRAY_ALPHA: case DK3_COLOR_SPACE_RGBA: { $? ". mix"
+ back = dk3bif_mix(
+ back,
+ (bp->cf)->bggr,
+ dk3bif_get_alpha(bp, x, y),
+ dk3pixre_get_max_value(&(bp->pr))
+ );
+ } break;
+ }
+ } $? "- dk3bif_get_mixed_gray %u", (unsigned)back
+ return back;
+}
+
+
+
+int
+dk3bif_type_supported(int tp)
+{
+ int back = 0;
+ $? "+ dk3bif_type_supported %d", tp
+ switch(tp) {
+ case DK3_BIF_IMAGE_TYPE_PNG: {
+#if DK3_HAVE_PNG_H
+ back = 1;
+#endif
+ } break;
+ case DK3_BIF_IMAGE_TYPE_JPEG: {
+#if DK3_HAVE_JPEGLIB_H
+ back = 1;
+#endif
+ } break;
+ case DK3_BIF_IMAGE_TYPE_TIFF: {
+#if DK3_HAVE_TIFF_H
+ back = 1;
+#endif
+ } break;
+ } $? "- dk3bif_type_supported %d", back
+ return back;
+}
+
+
+
+FILE *
+dk3bif_get_file(dk3_bif_t *bp)
+{
+ FILE *back = NULL;
+ $? "+ dk3bif_get_file"
+ if(bp) {
+ back = bp->tmpfipo;
+ } $? "- dk3bif_get_file %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+int
+dk3bif_is_colored(dk3_bif_t *bp)
+{
+ int back = 0;
+ dk3_bif_coord_t x;
+ dk3_bif_coord_t y;
+ dk3_bif_pixel_t r;
+ dk3_bif_pixel_t g;
+ dk3_bif_pixel_t b;
+
+ if(bp) {
+ if(bp->cf) {
+ switch((bp->cf)->cs) {
+ case DK3_COLOR_SPACE_RGB:
+ case DK3_COLOR_SPACE_RGBA: {
+ for(y = 0L; (y < (bp->cf)->h) && (back == 0); y++) {
+ for(x = 0L; (x < (bp->cf)->w) && (back == 0); x++) {
+ r = dk3bif_get_red(bp, x, y);
+ g = dk3bif_get_green(bp, x, y);
+ b = dk3bif_get_blue(bp, x, y);
+ if(r != g) { back = 1; }
+ if(r != b) { back = 1; }
+ }
+ }
+ } break;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+double
+dk3bif_get_xres(dk3_bif_t *bp)
+{
+ double back = -1.0;
+ $? "+ dk3bif_get_xres"
+ if(bp) {
+ if(bp->cf) {
+ back = (bp->cf)->xres;
+ }
+ } $? "- dk3bif_get_xres %lg", back
+ return back;
+}
+
+
+
+double
+dk3bif_get_yres(dk3_bif_t *bp)
+{
+ double back = -1.0;
+ $? "+ dk3bif_get_yres"
+ if(bp) {
+ if(bp->cf) {
+ back = (bp->cf)->yres;
+ }
+ } $? "- dk3bif_get_yres %lg", back
+ return back;
+}
+
+
+
+
+int
+dk3bif_next_frame(dk3_bif_t *bp)
+{
+ int back = 0;
+ if(bp) {
+ if(bp->i_frames) {
+ bp->cf = (dk3_bif_frame_t *)dk3sto_it_next(bp->i_frames);
+ if(bp->cf) {
+ back = 1;
+ dk3bif_set_pixel_sampling(bp);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void
+dk3bif_reset_frames(dk3_bif_t *bp)
+{
+ if(bp) {
+ bp->cf = NULL;
+ dk3sto_it_reset(bp->i_frames);
+ }
+}
+
+
+
+void
+dk3bif_set_background(
+ dk3_bif_t *bp,
+ dk3_bif_pixel_t r,
+ dk3_bif_pixel_t g,
+ dk3_bif_pixel_t b,
+ int f
+)
+{
+ if(bp) {
+ bp->bgr = r; bp->bgg = g; bp->bgb = b; bp->bg = (f ? 1 : 0);
+ }
+}
+
+
+
+int
+dk3bif_get_color_space(dk3_bif_t *bp)
+{
+ int back = 0;
+ if(bp) {
+ if(bp->cf) {
+ back = (bp->cf)->cs;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3bif_get_type(dk3_bif_t *bp)
+{
+ int back = DK3_BIF_IMAGE_TYPE_UNKNOWN;
+ if(bp) {
+ back = bp->bt;
+ }
+ return back;
+}
+
+
+$!trace-on
+
+int
+dk3bif_jpeg_get_num_components(dk3_bif_t *bif)
+{
+ int back = 0;
+#if DK3_HAVE_JPEGLIB_H
+ dk3_bif_frame_jpeg_t *jpf;
+ $? "+ dk3bif_jpeg_get_num_components"
+ if(bif) { $? ". bif"
+ if(bif->cf) { $? ". cf"
+ if(bif->bt == DK3_BIF_IMAGE_TYPE_JPEG) { $? ". cs ok"
+ jpf = (dk3_bif_frame_jpeg_t *)((bif->cf)->implspec);
+ if(jpf) { $? ". jpf"
+ back = jpf->num_comp;
+ } else { $? "! jpf"
+ }
+ } else { $? "! cs"
+ }
+ } else { $? "! cf"
+ }
+ } else { $? "! bif"
+ } $? "- dk3bif_jpeg_get_num_components %d", back
+#endif
+ return back;
+}
+
+$!trace-off
+
+
+int
+dk3bif_jpeg_get_found_adobe_marker(dk3_bif_t *bif)
+{
+ int back = 0;
+#if DK3_HAVE_JPEGLIB_H
+ dk3_bif_frame_jpeg_t *jpf;
+ if(bif) {
+ if(bif->cf) {
+ if(bif->bt == DK3_BIF_IMAGE_TYPE_JPEG) {
+ jpf = (dk3_bif_frame_jpeg_t *)((bif->cf)->implspec);
+ if(jpf) {
+ back = jpf->is_adobe;
+ }
+ }
+ }
+ }
+#endif
+ return back;
+}
+
+
+
+dk3_bif_pixel_t
+dk3bif_average(dk3_bif_pixel_t left, dk3_bif_pixel_t upper)
+{
+ dk3_bif_pixel_t back;
+ long x;
+ x = (long)left + (long)upper;
+ x = x / 2;
+ back = (dk3_bif_pixel_t)x;
+ return back;
+}
+
+
+
+dk3_bif_pixel_t
+dk3bif_paeth(
+ dk3_bif_pixel_t v1,
+ dk3_bif_pixel_t v2,
+ dk3_bif_pixel_t v3
+)
+{
+ dk3_bif_pixel_t back;
+ long p, pa, pb, pc;
+ p = (long)v1 + (long)v2 - (long)v3;
+ pa = p - (long)v1;
+ pb = p - (long)v2;
+ pc = p - (long)v3;
+ if(pa < 0) { pa = 0L - pa; }
+ if(pb < 0) { pb = 0L - pb; }
+ if(pc < 0) { pc = 0L - pc; }
+ if((pa <= pb) && (pa <= pc)) {
+ back = v1;
+ } else {
+ if(pb <= pc) {
+ back = v2;
+ } else {
+ back = v3;
+ }
+ }
+ return back;
+}
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dk3bif.h b/support/dktools/dk3bif.h
new file mode 100644
index 0000000000..000c0df05a
--- /dev/null
+++ b/support/dktools/dk3bif.h
@@ -0,0 +1,428 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3bif.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3bif.h Header file for the dk3bif module.
+*/
+
+#ifndef DK3BIF_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3BIF_H_INCLUDED 1
+
+
+#line 10 "dk3bif.ctr"
+
+#include "dk3conf.h"
+#include "dk3types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Check whether a bitmap image file type is supported.
+ @param tp File type to check.
+ @return 1 for supported types, 0 otherwise.
+*/
+int
+dk3bif_type_supported(int tp);
+
+/** Check file name suffix (dkChar).
+ @param sn File name suffix without the dot.
+ @return Bitmap image file type.
+*/
+int
+dk3bif_check_suffix_without_dot(dkChar const *sn);
+
+/** Check file name suffix (char).
+ @param sn File name suffix without the dot.
+ @return Bitmap image file type.
+*/
+int
+dk3bif_check_c8_suffix_without_dot(char const *sn);
+
+/** Check file name suffix (dkChar).
+ @param fn File name to check.
+ @return Bitmap image file type.
+*/
+int
+dk3bif_check_file_name(dkChar const *fn);
+
+/** Check file name suffix (char).
+ @param fn File name to check.
+ @return Bitmap image file type.
+*/
+int
+dk3bif_check_c8_file_name(char const *fn);
+
+/** Open bitmap image file (dkChar).
+ @param fn File name.
+ @param tp Bitmap type.
+ @param app Application structure for diagnostics, may not be NULL.
+ @return Pointer to BIF on success, NULL on error.
+*/
+dk3_bif_t *
+dk3bif_open_filename_app(dkChar const *fn, int tp, dk3_app_t *app);
+
+/** Open bitmap image file (char).
+ @param fn File name.
+ @param tp Bitmap type.
+ @param app Application structure for diagnostics, may not be NULL.
+ @return Pointer to BIF on success, NULL on error.
+*/
+dk3_bif_t *
+dk3bif_open_c8_filename_app(char const *fn, int tp, dk3_app_t *app);
+
+/** Open bitmap image file.
+ @param fipo File, opened for binary reading.
+ @param tp Bitmap type.
+ @param app Application structure for diagnostics, may not be NULL.
+ @return Pointer to BIF on success, NULL on error.
+*/
+dk3_bif_t *
+dk3bif_open_file_app(FILE *fipo, int tp, dk3_app_t *app);
+
+/** Retrieve image type.
+ @param bp Bitmap image file.
+ @return Image type, DK3_BIF_IMAGE_TYPE_xxx, see @ref bifimagetypes.
+*/
+int
+dk3bif_get_type(dk3_bif_t *bp);
+
+/** Get width of current frame.
+ @param bp Bitmap image file.
+ @return Image width.
+*/
+dk3_bif_coord_t
+dk3bif_get_width(dk3_bif_t *bp);
+
+/** Get height of current frame.
+ @param bp Bitmap image file.
+ @return Image height.
+*/
+dk3_bif_coord_t
+dk3bif_get_height(dk3_bif_t *bp);
+
+/** Get width of widest frame.
+ @param bp Bitmap image file.
+ @return Image width.
+*/
+dk3_bif_coord_t
+dk3bif_get_largest_width(dk3_bif_t *bp);
+
+/** Get height of highest frame.
+ @param bp Bitmap image file.
+ @return Image height.
+*/
+dk3_bif_coord_t
+dk3bif_get_largest_height(dk3_bif_t *bp);
+
+/** Set background color on per-file base.
+ Use this function after opening the bitmap image file
+ but before dk3bif_read_data().
+ @param bp Bitmap image file.
+ @param r Red.
+ @param g Green.
+ @param b Blue.
+ @param f Force flag: 0=use background color chunk
+ from file if available, 1=always use the color specified here.
+*/
+void
+dk3bif_set_background(
+ dk3_bif_t *bp,
+ dk3_bif_pixel_t r,
+ dk3_bif_pixel_t g,
+ dk3_bif_pixel_t b,
+ int f
+);
+
+/** Read image data.
+ @param bp Bitmap image file.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3bif_read_data(dk3_bif_t *bp);
+
+/** Find number of frames in image file.
+ @param bp Bitmap image file.
+ @return Number of frames in the file.
+*/
+size_t
+dk3bif_number_of_frames(dk3_bif_t *bp);
+
+/** Set current frame number.
+ @param bp Bitmap image file.
+ @param fn Number of frame to process.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3bif_set_frame(dk3_bif_t *bp, size_t fn);
+
+/** Reset internal current frame pointer, so the next
+ dk3bif_next_frame() call returns the first frame.
+ @param bp Bitmap image file.
+*/
+void
+dk3bif_reset_frames(dk3_bif_t *bp);
+
+/** Switch to the next frame.
+ @param bp Bitmap image file.
+ @return 1 on success, 0 on error (no more frames).
+*/
+int
+dk3bif_next_frame(dk3_bif_t *bp);
+
+/** Check whether a bitmap image is really colored.
+ @param bp Bitmap image file.
+ @return 1 for colored image, 0 for grey.
+*/
+int
+dk3bif_is_colored(dk3_bif_t *bp);
+
+/** Retrieve number of bits per pixel for current frame.
+ @param bp Bitmap image file.
+ @return Number of bits per pixel used in the file.
+*/
+size_t
+dk3bif_get_bits_per_pixel(dk3_bif_t *bp);
+
+/** Retrieve number of bits per pixel for current frame
+ really containing information.
+ This function returns a useful result only if
+ dk3bif_analyze() was run with DK3_ANALYSIS_BITS before.
+ @param bp Bitmap image file.
+ @return Number of non-redundant bits per pixel.
+*/
+size_t
+dk3bif_real_bits_per_pixel(dk3_bif_t *bp);
+
+/** Retrieve information whether colors are really used.
+ This function returns a useful result only if
+ dk3bif_analyze() was run with DK3_BIF_ANALYSIS_COLOR before.
+ @param bp Bitmap image file.
+ @return 1 for colors, 0 for gray.
+*/
+int
+dk3bif_real_color(dk3_bif_t *bp);
+
+/** Retrieve information whether alpha channel is really used.
+ This function returns a useful result only if
+ dk3bif_analyze() was run with DK3_BIF_ANALYSIS_ALPHA before.
+ @param bp Bitmap image file.
+ @return 1 for alpha channel used, 0 for unused.
+*/
+int
+dk3bif_real_alpha(dk3_bif_t *bp);
+
+/** Set number of bits per pixel when retrieving data.
+ @param bp Bitmap image file.
+ @param sz Number of bits per pixel.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3bif_set_bits_per_pixel(dk3_bif_t *bp, size_t sz);
+
+/** Get color space.
+ @param bp Bitmap image file.
+ @return The color space used by the image.
+*/
+int
+dk3bif_get_color_space(dk3_bif_t *bp);
+
+/** Get red component of pixel.
+ @param bp Bitmap image file.
+ @param x X coordinate.
+ @param y Y coordinate.
+ @return Value corrected to requested bits per component.
+*/
+dk3_bif_pixel_t
+dk3bif_get_red(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y);
+
+/** Get green component of pixel.
+ @param bp Bitmap image file.
+ @param x X coordinate.
+ @param y Y coordinate.
+ @return Value corrected to requested bits per component.
+*/
+dk3_bif_pixel_t
+dk3bif_get_green(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y);
+
+/** Get blue component of pixel.
+ @param bp Bitmap image file.
+ @param x X coordinate.
+ @param y Y coordinate.
+ @return Value corrected to requested bits per component.
+*/
+dk3_bif_pixel_t
+dk3bif_get_blue(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y);
+
+/** Get gray component of pixel.
+ @param bp Bitmap image file.
+ @param x X coordinate.
+ @param y Y coordinate.
+ @return Value corrected to requested bits per component.
+*/
+dk3_bif_pixel_t
+dk3bif_get_gray(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y);
+
+/** Get alpha component of pixel.
+ @param bp Bitmap image file.
+ @param x X coordinate.
+ @param y Y coordinate.
+ @return Value corrected to requested bits per component.
+*/
+dk3_bif_pixel_t
+dk3bif_get_alpha(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y);
+
+/** Get red component of pixel mixed against background.
+ @param bp Bitmap image file.
+ @param x X coordinate.
+ @param y Y coordinate.
+ @return Value corrected to requested bits per component.
+*/
+dk3_bif_pixel_t
+dk3bif_get_mixed_red(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y);
+
+/** Get green component of pixel mixed against background.
+ @param bp Bitmap image file.
+ @param x X coordinate.
+ @param y Y coordinate.
+ @return Value corrected to requested bits per component.
+*/
+dk3_bif_pixel_t
+dk3bif_get_mixed_green(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y);
+
+/** Get blue component of pixel mixed against background.
+ @param bp Bitmap image file.
+ @param x X coordinate.
+ @param y Y coordinate.
+ @return Value corrected to requested bits per component.
+*/
+dk3_bif_pixel_t
+dk3bif_get_mixed_blue(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y);
+
+/** Get gray component of pixel mixed against background.
+ @param bp Bitmap image file.
+ @param x X coordinate.
+ @param y Y coordinate.
+ @return Value corrected to requested bits per component.
+*/
+dk3_bif_pixel_t
+dk3bif_get_mixed_gray(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y);
+
+/** Get file to access raw data.
+ This function is primary intended to access JPEG data.
+ @param bp Bitmap image file.
+ @return FILE pointer if available, NULL otherwise.
+*/
+FILE *
+dk3bif_get_file(dk3_bif_t *bp);
+
+/** Retrieve X resolution.
+ @param bp Bitmap image file.
+ @return X resolution in dpi.
+*/
+double
+dk3bif_get_xres(dk3_bif_t *bp);
+
+/** Retrieve Y resolution.
+ @param bp Bitmap image file.
+ @return Y resolution in dpi.
+*/
+double
+dk3bif_get_yres(dk3_bif_t *bp);
+
+/** Close bitmap image file, release memory.
+ @param bp Bitmap image file to close.
+*/
+void
+dk3bif_close(dk3_bif_t *bp);
+
+/** Get original number of components for JPEG file.
+ @param bif Bitmap image file.
+ @return Number of components found in file on success, 0 on error.
+*/
+int
+dk3bif_jpeg_get_num_components(dk3_bif_t *bif);
+
+/** Check whether Adobe marker was found in JPEG input file.
+ @param bif Bitmap image file.
+ @return 1 if marker was found, 0 otherwise.
+*/
+int
+dk3bif_jpeg_get_found_adobe_marker(dk3_bif_t *bif);
+
+/** Calculate average predictor value from left and upper value.
+ @param left Value left to the pixel.
+ @param upper Value upper to the pixel.
+ @return Predictor value.
+*/
+dk3_bif_pixel_t
+dk3bif_average(dk3_bif_pixel_t left, dk3_bif_pixel_t upper);
+
+/** Paeth prediction function.
+ @param v1 Left value.
+ @param v2 Upper value.
+ @param v3 Upper left value.
+ @return Predicted value.
+*/
+dk3_bif_pixel_t
+dk3bif_paeth(
+ dk3_bif_pixel_t v1,
+ dk3_bif_pixel_t v2,
+ dk3_bif_pixel_t v3
+);
+
+/** Retrieve one pixel component not yet resampled.
+ @param bp Bitmap image.
+ @param x X coordinate.
+ @param y Y coordinate.
+ @param c Choose component: 0=red/gray, 1=green, 2=blue, 3=alpha.
+ @return Pixel component.
+*/
+dk3_bif_pixel_t
+dk3bif_get_pixel_component_not_resampled(
+ dk3_bif_t *bp,
+ dk3_bif_coord_t x,
+ dk3_bif_coord_t y,
+ int c
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3bifa.c b/support/dktools/dk3bifa.c
new file mode 100644
index 0000000000..859e385c54
--- /dev/null
+++ b/support/dktools/dk3bifa.c
@@ -0,0 +1,602 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3bifa.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3bifa.c The dk3bifa module.
+*/
+
+
+#line 49 "dk3bifa.ctr"
+
+#include "dk3const.h"
+#include "dk3mem.h"
+#include "dk3str.h"
+#include "dk3sf.h"
+#include "dk3sto.h"
+#include "dk3bif.h"
+#include "dk3bifa.h"
+#include "dk3pixre.h"
+#include "dk3ma.h"
+#include "dk3bits.h"
+#include "dk3app.h"
+
+#include <stdio.h>
+
+#if DK3_USE_WX
+#include <wx/wx.h>
+#include <wx/thread.h>
+#include "DkWxCommunicator.h"
+#endif
+
+
+
+
+
+#line 73 "dk3bifa.ctr"
+
+
+
+/** Default texts for debug messages in bit depth analysis.
+*/
+static dkChar const * const dk3bif_analysis_msg[] = {
+/* 0 */
+dkT("Image analysis: Original image is color image."),
+
+/* 1 */
+dkT("Image analysis: Original image is greyscaled image."),
+
+/* 2 */
+dkT("Image analysis: Can reduce image to greyscaled image."),
+
+/* 3 */
+dkT("Image analysis: Really a color image."),
+
+/* 4 */
+dkT("Image analysis: Original image contains alpha channel."),
+
+/* 5 */
+dkT("Image analysis: No alpha channel in original image."),
+
+/* 6 */
+dkT("Image analysis: Alpha channel is used."),
+
+/* 7 */
+dkT("Image analysis: Alpha channel is not used."),
+
+/* 8 */
+dkT("Image analysis: Original image contains "),
+
+/* 9 */
+dkT(" bits per component."),
+
+/* 10 */
+dkT("Image analysis: Output image contains "),
+
+/* 11 */
+dkT(" bits per component."),
+
+NULL
+
+
+#line 123 "dk3bifa.ctr"
+};
+
+
+
+#if 0
+/** Find number of significant bits in pixel value.
+ @param v Pixel value to inspect.
+ @param nbits Bits per component information from image.
+ @return Number of significant bits in @a v.
+*/
+static
+size_t
+dk3bif_real_bits(dk3_bif_pixel_t v, size_t nbits)
+{
+ size_t back = 1;
+ int st = 0;
+ size_t i;
+ size_t j;
+
+
+#line 142 "dk3bifa.ctr"
+ for(i = 0; i < nbits; i++) {
+ j = nbits - i - 1;
+ if(i == 0) {
+ if(v & dk3bits_get(j)) {
+ st = 1;
+ } else {
+ st = 0;
+ }
+ back = 1;
+ } else {
+ if(v & dk3bits_get(j)) {
+ if(st == 0) {
+ back = i + 1;
+ }
+ st = 1;
+ } else {
+ if(st == 1) {
+ back = i + 1;
+ }
+ st = 0;
+ }
+ }
+ }
+
+#line 165 "dk3bifa.ctr"
+ return back;
+}
+#endif
+
+
+
+#if DK3_USE_WX
+/** Show progress during image analysis.
+ Progress is only shown when the module is compiled with
+ DK3_USE_WX defined unequal zero.
+ @param pc Communicator object.
+ @param minpb Minimum progress bar value (0-1000).
+ @param maxpb Maximum progress bar value (0-1000).
+ @param h Image height (number of lines).
+ @param y Current line completed.
+*/
+static
+void
+dk3bif_show_lines_progress(
+ void *pc,
+ int minpb,
+ int maxpb,
+ dk3_bif_coord_t h,
+ dk3_bif_coord_t y
+)
+{
+ DkWxCommunicator *pComm;
+ unsigned long umax;
+ unsigned long umin;
+ unsigned long uh;
+ unsigned long uy;
+ int ec = 0;
+ if((pc) && (maxpb > minpb) && (h)) {
+ pComm = (DkWxCommunicator *)pc;
+ umax = (unsigned long)maxpb;
+ umin = (unsigned long)minpb;
+ uh = (unsigned long)h;
+ uy = (unsigned long)y;
+ /* umax = umin + (uy + 1UL) * (umax - umin) / (uh); */
+ umax = dk3ma_ul_add_ok(
+ umin,
+ dk3ma_ul_div_ok(
+ dk3ma_ul_mul_ok(
+ dk3ma_ul_add_ok(uy, 1UL, &ec),
+ dk3ma_ul_sub_ok(umax, umin, &ec),
+ &ec
+ ),
+ uh,
+ &ec
+ ),
+ &ec
+ );
+ if(ec == 0) {
+ ec = (int)umax;
+ if((minpb <= ec) && (ec <= maxpb)) {
+ pComm->updateGauge(ec);
+ }
+ }
+ }
+}
+#endif
+
+
+
+/** Structure to analyze bit depth of an image frame.
+*/
+typedef struct {
+ dk3_pixel_resample_t r01; /**< Pixel resampling to 1 bit. */
+ dk3_pixel_resample_t r02; /**< Pixel resampling to 2 bit. */
+ dk3_pixel_resample_t r04; /**< Pixel resampling to 4 bit. */
+ dk3_pixel_resample_t r08; /**< Pixel resampling to 8 bit. */
+ dk3_pixel_resample_t r12; /**< Pixel resampling to 12 bit. */
+ int finished; /**< Flag: Analysis finished. */
+ int f01; /**< Flag: Can resample to 1 bit. */
+ int f02; /**< Flag: Can resample to 2 bit. */
+ int f04; /**< Flag: Can resample to 4 bit. */
+ int f08; /**< Flag: Can resample to 8 bit. */
+ int f12; /**< Flag: Can resample to 12 bit. */
+} dk3_bif_analyze_bitdepth_t;
+
+
+
+/** Set up analysis structure.
+ @param p Bitdepth analysis structure.
+ @param at Analysis type.
+ @param srcw Source bit width.
+*/
+static
+void
+dk3bif_analyze_setup_structure(
+ dk3_bif_analyze_bitdepth_t *p,
+ int at,
+ size_t srcw
+)
+{
+ p->f01 = 0; p->f02 = 0; p->f04 = 0; p->f08 = 0; p->f12 = 0;
+ dk3pixre_set(&(p->r01), srcw, 1);
+ dk3pixre_set(&(p->r02), srcw, 2);
+ dk3pixre_set(&(p->r04), srcw, 4);
+ dk3pixre_set(&(p->r08), srcw, 8);
+ dk3pixre_set(&(p->r12), srcw, 12);
+ p->finished = 1;
+ if ( 1 < srcw) { p->f01 = 1; p->finished = 0; }
+ if ( 2 < srcw) { p->f02 = 1; }
+ if ( 4 < srcw) { p->f04 = 1; }
+ if ( 8 < srcw) { p->f08 = 1; }
+ if (12 < srcw) { p->f12 = 1; }
+}
+
+
+
+/** Analyse one pixel value.
+ @param p Bit depth analysis structure.
+ @param v Value to analyze.
+*/
+static
+void
+dk3bif_analyze_check_bitvalue(
+ dk3_bif_analyze_bitdepth_t *p,
+ dk3_bif_pixel_t v
+)
+{
+ int changed = 0;
+ if (p->f01) {
+ if (!(dk3pixre_can_convert(&(p->r01), v))) {
+ p->f01 = 0;
+ changed = 1;
+ }
+ }
+ if (p->f02) {
+ if (!(dk3pixre_can_convert(&(p->r02), v))) {
+ p->f02 = 0;
+ changed = 1;
+ }
+ }
+ if (p->f04) {
+ if (!(dk3pixre_can_convert(&(p->r04), v))) {
+ p->f04 = 0;
+ changed = 1;
+ }
+ }
+ if (p->f08) {
+ if (!(dk3pixre_can_convert(&(p->r08), v))) {
+ p->f08 = 0;
+ changed = 1;
+ }
+ }
+ if (p->f12) {
+ if (!(dk3pixre_can_convert(&(p->r12), v))) {
+ p->f12 = 0;
+ changed = 1;
+ }
+ }
+ if (changed) {
+ if (!((p->f01) || (p->f02) || (p->f04) || (p->f08) || (p->f12))) {
+ p->finished = 1;
+ }
+ }
+}
+
+
+
+void
+dk3bif_analyze_progress(
+ dk3_bif_t *bp,
+ int at,
+ void *pcomm,
+ int minpb,
+ int maxpb
+)
+{
+ dk3_bif_analyze_bitdepth_t ana;
+ dk3_bif_coord_t x;
+ dk3_bif_coord_t y;
+ int cc;
+ int found_color;
+ int found_alpha;
+ int search_color;
+ int search_alpha;
+ dk3_bif_pixel_t maxval;
+ dk3_bif_pixel_t r;
+ dk3_bif_pixel_t g;
+ dk3_bif_pixel_t b;
+ dk3_bif_pixel_t a;
+ if (bp) {
+ if (bp->cf) {
+ /* Default values for all color space types.
+ */
+ (bp->cf)->realbits = (bp->cf)->bits;
+ (bp->cf)->realcolor = 0;
+ (bp->cf)->realalpha = 0;
+
+ switch ((bp->cf)->cs) {
+
+ /* For some color space we can not do the analysis.
+ */
+ case DK3_COLOR_SPACE_HSB:
+ case DK3_COLOR_SPACE_YCCK:
+ case DK3_COLOR_SPACE_YCbCr:
+ case DK3_COLOR_SPACE_CMYK:
+ {
+ (bp->cf)->realcolor = 1;
+ (bp->cf)->realalpha = 1;
+ }
+ break;
+
+ /* Do analysis.
+ */
+ default: {
+ /* Default values.
+ */
+ (bp->cf)->realcolor = 0;
+ (bp->cf)->realalpha = 0;
+ search_alpha = 0;
+ search_color = 0;
+ switch ((bp->cf)->cs) {
+ case DK3_COLOR_SPACE_GRAY_ALPHA:
+ case DK3_COLOR_SPACE_RGBA: {
+ if (DK3_BIF_ANALYSIS_ALPHA & at) {
+ search_alpha = 1;
+ } else {
+ (bp->cf)->realalpha = 1;
+ }
+ } break;
+ }
+ switch ((bp->cf)->cs) {
+ case DK3_COLOR_SPACE_RGB:
+ case DK3_COLOR_SPACE_RGBA: {
+ if (DK3_BIF_ANALYSIS_COLOR & at) {
+ search_color = 1;
+ } else {
+ (bp->cf)->realcolor = 1;
+ }
+ } break;
+ }
+
+ /* Do analysis
+ */
+ dk3bif_analyze_setup_structure(&ana, at, (bp->cf)->bits);
+ maxval = dk3pixre_maximum_for_width((bp->cf)->bits);
+ found_color = 0;
+ found_alpha = 0;
+ switch ((bp->cf)->cs) {
+ case DK3_COLOR_SPACE_GRAY_ALPHA:
+ case DK3_COLOR_SPACE_RGBA:
+ {
+ if((bp->cf)->bgr != (bp->cf)->bgg) { found_color = 1; }
+ if((bp->cf)->bgr != (bp->cf)->bgb) { found_color = 1; }
+ if (DK3_BIF_ANALYSIS_BITS & at) {
+ dk3bif_analyze_check_bitvalue(&ana, (bp->cf)->bgr);
+ dk3bif_analyze_check_bitvalue(&ana, (bp->cf)->bgg);
+ dk3bif_analyze_check_bitvalue(&ana, (bp->cf)->bgb);
+ }
+ } break;
+ }
+ cc = 1;
+ for (y = 0; ((y < (bp->cf)->h) && (cc)); y++) {
+ for (x = 0; ((x < (bp->cf)->w) && (cc)); x++) {
+ switch ((bp->cf)->cs) {
+ case DK3_COLOR_SPACE_GRAY: {
+ r = dk3bif_get_pixel_component_not_resampled(bp, x, y, 0);
+ if (DK3_BIF_ANALYSIS_BITS & at) {
+ dk3bif_analyze_check_bitvalue(&ana, r);
+ }
+ } break;
+ case DK3_COLOR_SPACE_GRAY_ALPHA: {
+ r = dk3bif_get_pixel_component_not_resampled(bp, x, y, 0);
+ a = dk3bif_get_pixel_component_not_resampled(bp, x, y, 3);
+ if (DK3_BIF_ANALYSIS_BITS & at) {
+ dk3bif_analyze_check_bitvalue(&ana, r);
+ dk3bif_analyze_check_bitvalue(&ana, a);
+ }
+ if (search_alpha) {
+ if (maxval != a) { found_alpha = 1; }
+ }
+ } break;
+ case DK3_COLOR_SPACE_RGB: {
+ r = dk3bif_get_pixel_component_not_resampled(bp, x, y, 0);
+ g = dk3bif_get_pixel_component_not_resampled(bp, x, y, 1);
+ b = dk3bif_get_pixel_component_not_resampled(bp, x, y, 2);
+ if (DK3_BIF_ANALYSIS_BITS & at) {
+ dk3bif_analyze_check_bitvalue(&ana, r);
+ dk3bif_analyze_check_bitvalue(&ana, g);
+ dk3bif_analyze_check_bitvalue(&ana, b);
+ }
+ if (search_color) {
+ if((r != g) || (r != b)) { found_color = 1; }
+ }
+ } break;
+ case DK3_COLOR_SPACE_RGBA: {
+ r = dk3bif_get_pixel_component_not_resampled(bp, x, y, 0);
+ g = dk3bif_get_pixel_component_not_resampled(bp, x, y, 1);
+ b = dk3bif_get_pixel_component_not_resampled(bp, x, y, 2);
+ a = dk3bif_get_pixel_component_not_resampled(bp, x, y, 3);
+ if (DK3_BIF_ANALYSIS_BITS & at) {
+ dk3bif_analyze_check_bitvalue(&ana, r);
+ dk3bif_analyze_check_bitvalue(&ana, g);
+ dk3bif_analyze_check_bitvalue(&ana, b);
+ dk3bif_analyze_check_bitvalue(&ana, a);
+ }
+ if (search_color) {
+ if((r != g) || (r != b)) { found_color = 1; }
+ }
+ if (search_alpha) {
+ if (maxval != a) { found_alpha = 1; }
+ }
+ } break;
+ }
+ cc = 0;
+ if (DK3_BIF_ANALYSIS_BITS & at) {
+ if(!(ana.finished)) { cc = 1; }
+ }
+ if (search_color) {
+ if(!(found_color)) { cc = 1; }
+ }
+ if (search_alpha) {
+ if(!(found_alpha)) { cc = 1; }
+ }
+ }
+#if DK3_USE_WX
+ dk3bif_show_lines_progress(pcomm, minpb, maxpb, (bp->cf)->h, y);
+#endif
+ }
+
+ /* After analysis apply results.
+ */
+ if (DK3_BIF_ANALYSIS_BITS & at) {
+ if (ana.f01) {
+ (bp->cf)->realbits = 1;
+ } else {
+ if (ana.f02) {
+ (bp->cf)->realbits = 2;
+ } else {
+ if (ana.f04) {
+ (bp->cf)->realbits = 4;
+ } else {
+ if (ana.f08) {
+ (bp->cf)->realbits = 8;
+ } else {
+ if (ana.f12) {
+ (bp->cf)->realbits = 12;
+ }
+ }
+ }
+ }
+ }
+ }
+ if (search_color) {
+ (bp->cf)->realcolor = found_color;
+ }
+ if (search_alpha) {
+ (bp->cf)->realalpha = found_alpha;
+ }
+ if (bp->app) {
+ if (DK3_LL_DEBUG <= dk3app_max_log_level(bp->app)) {
+ dkChar buffer[128];
+ dkChar const * const *msg;
+ msg = dk3app_messages(
+ bp->app, dkT("dk3bifa.str"), dk3bif_analysis_msg
+ );
+ if (DK3_BIF_ANALYSIS_COLOR & at) {
+ switch ((bp->cf)->cs) {
+ case DK3_COLOR_SPACE_RGB:
+ case DK3_COLOR_SPACE_RGBA: {
+ /* Original image: color */
+ dk3app_log_1(bp->app, DK3_LL_DEBUG, msg, 0);
+ if (found_color) {
+ dk3app_log_1(bp->app, DK3_LL_DEBUG, msg, 3);
+ } else {
+ /* Grayscale image */
+ dk3app_log_1(bp->app, DK3_LL_DEBUG, msg, 2);
+ }
+ } break;
+ default: {
+ /* Gray image */
+ dk3app_log_1(bp->app, DK3_LL_DEBUG, msg, 1);
+ } break;
+ }
+ }
+ if (DK3_BIF_ANALYSIS_ALPHA & at) {
+ switch ((bp->cf)->cs) {
+ case DK3_COLOR_SPACE_GRAY_ALPHA:
+ case DK3_COLOR_SPACE_RGBA: {
+ dk3app_log_1(bp->app, DK3_LL_DEBUG, msg, 4);
+ if (found_alpha) {
+ /* Alpha data found */
+ dk3app_log_1(bp->app, DK3_LL_DEBUG, msg, 6);
+ } else {
+ /* No real alpha data */
+ dk3app_log_1(bp->app, DK3_LL_DEBUG, msg, 7);
+ }
+ } break;
+ default: {
+ /* No alpha channel in image */
+ dk3app_log_1(bp->app, DK3_LL_DEBUG, msg, 5);
+ } break;
+ }
+ }
+ if (DK3_BIF_ANALYSIS_BITS & at) {
+#if VERSION_BEFORE_20140716
+ /* Original bits per component */
+ dk3sf_sprintf3(buffer, dkT("%u"), (unsigned)((bp->cf)->bits));
+ dk3app_log_3(bp->app, DK3_LL_DEBUG, msg, 8, 9, buffer);
+ /* Output bits per component */
+ dk3sf_sprintf3(buffer,dkT("%u"),(unsigned)((bp->cf)->realbits));
+ dk3app_log_3(bp->app, DK3_LL_DEBUG, msg, 10, 11, buffer);
+#else
+ int res;
+ res = dk3ma_um_to_string(
+ buffer, DK3_SIZEOF(buffer,dkChar),
+ (dk3_um_t)((bp->cf)->bits)
+ );
+ if (0 != res) {
+ dk3app_log_3(bp->app, DK3_LL_DEBUG, msg, 8, 9, buffer);
+ }
+ res = dk3ma_um_to_string(
+ buffer, DK3_SIZEOF(buffer,dkChar),
+ (dk3_um_t)((bp->cf)->realbits)
+ );
+ if (0 != res) {
+ dk3app_log_3(bp->app, DK3_LL_DEBUG, msg, 10, 11, buffer);
+ }
+#endif
+ }
+ }
+ }
+ } break;
+ }
+ }
+ }
+#if DK3_USE_WX
+ dk3bif_show_lines_progress(pcomm, minpb, maxpb, 1UL, 0UL);
+#endif
+}
+
+
+
+void
+dk3bif_analyze(dk3_bif_t *bp, int at)
+{
+ dk3bif_analyze_progress(bp, at, NULL, 0, 1000);
+}
+
+
diff --git a/support/dktools/dk3bifa.ctr b/support/dktools/dk3bifa.ctr
new file mode 100644
index 0000000000..018fcfb68a
--- /dev/null
+++ b/support/dktools/dk3bifa.ctr
@@ -0,0 +1,608 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Check bits per component really used and alpha and color usage.
+ As a result of this function (bp->cf)->realbits,
+ (bp->cf)->realcolor, and (bp->cf)->realalpha is set.
+ @param bp Bitmap image file to check.
+ @param at Analysis type, DK3_BIF_ANALYSIS_xxx,
+ @param pcomm Communicator object.
+ @param minpb Minimum progress bar value (0-1000).
+ @param maxpb Maximum progress bar value (0-1000).
+ see @ref bifanalysis.
+*/
+void
+dk3bif_analyze_progress(
+ dk3_bif_t *bp,
+ int at,
+ void *pcomm,
+ int minpb,
+ int maxpb
+);
+
+/** Check bits per component really used and alpha and color usage.
+ As a result of this function (bp->cf)->realbits,
+ (bp->cf)->realcolor, and (bp->cf)->realalpha is set.
+ @param bp Bitmap image file to check.
+ @param at Analysis type, DK3_BIF_ANALYSIS_xxx,
+ see @ref bifanalysis.
+*/
+void
+dk3bif_analyze(dk3_bif_t *bp, int at);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk3const.h"
+#include "dk3mem.h"
+#include "dk3str.h"
+#include "dk3sf.h"
+#include "dk3sto.h"
+#include "dk3bif.h"
+#include "dk3bifa.h"
+#include "dk3pixre.h"
+#include "dk3ma.h"
+#include "dk3bits.h"
+#include "dk3app.h"
+
+#include <stdio.h>
+
+#if DK3_USE_WX
+#include <wx/wx.h>
+#include <wx/thread.h>
+#include "DkWxCommunicator.h"
+#endif
+
+
+
+$!trace-include
+
+
+
+/** Default texts for debug messages in bit depth analysis.
+*/
+static dkChar const * const dk3bif_analysis_msg[] = {
+$!string-table macro=dkT
+#
+# 0
+#
+Image analysis: Original image is color image.
+#
+# 1
+#
+Image analysis: Original image is greyscaled image.
+#
+# 2
+#
+Image analysis: Can reduce image to greyscaled image.
+#
+# 3
+#
+Image analysis: Really a color image.
+#
+# 4
+#
+Image analysis: Original image contains alpha channel.
+#
+# 5
+#
+Image analysis: No alpha channel in original image.
+#
+# 6
+#
+Image analysis: Alpha channel is used.
+#
+# 7
+#
+Image analysis: Alpha channel is not used.
+#
+# 8 9
+#
+Image analysis: Original image contains
+ bits per component.
+#
+# 10 11
+#
+Image analysis: Output image contains
+ bits per component.
+$!end
+};
+
+
+
+#if 0
+/** Find number of significant bits in pixel value.
+ @param v Pixel value to inspect.
+ @param nbits Bits per component information from image.
+ @return Number of significant bits in @a v.
+*/
+static
+size_t
+dk3bif_real_bits(dk3_bif_pixel_t v, size_t nbits)
+{
+ size_t back = 1;
+ int st = 0;
+ size_t i;
+ size_t j;
+ $? "+ dk3bif_real_bits %u %u", (unsigned)v, (unsigned)nbits
+ for(i = 0; i < nbits; i++) {
+ j = nbits - i - 1;
+ if(i == 0) {
+ if(v & dk3bits_get(j)) {
+ st = 1;
+ } else {
+ st = 0;
+ }
+ back = 1;
+ } else {
+ if(v & dk3bits_get(j)) {
+ if(st == 0) {
+ back = i + 1;
+ }
+ st = 1;
+ } else {
+ if(st == 1) {
+ back = i + 1;
+ }
+ st = 0;
+ }
+ }
+ } $? "- dk3bif_real_bits %u", (unsigned)back
+ return back;
+}
+#endif
+
+
+
+#if DK3_USE_WX
+/** Show progress during image analysis.
+ Progress is only shown when the module is compiled with
+ DK3_USE_WX defined unequal zero.
+ @param pc Communicator object.
+ @param minpb Minimum progress bar value (0-1000).
+ @param maxpb Maximum progress bar value (0-1000).
+ @param h Image height (number of lines).
+ @param y Current line completed.
+*/
+static
+void
+dk3bif_show_lines_progress(
+ void *pc,
+ int minpb,
+ int maxpb,
+ dk3_bif_coord_t h,
+ dk3_bif_coord_t y
+)
+{
+ DkWxCommunicator *pComm;
+ unsigned long umax;
+ unsigned long umin;
+ unsigned long uh;
+ unsigned long uy;
+ int ec = 0;
+ if((pc) && (maxpb > minpb) && (h)) {
+ pComm = (DkWxCommunicator *)pc;
+ umax = (unsigned long)maxpb;
+ umin = (unsigned long)minpb;
+ uh = (unsigned long)h;
+ uy = (unsigned long)y;
+ /* umax = umin + (uy + 1UL) * (umax - umin) / (uh); */
+ umax = dk3ma_ul_add_ok(
+ umin,
+ dk3ma_ul_div_ok(
+ dk3ma_ul_mul_ok(
+ dk3ma_ul_add_ok(uy, 1UL, &ec),
+ dk3ma_ul_sub_ok(umax, umin, &ec),
+ &ec
+ ),
+ uh,
+ &ec
+ ),
+ &ec
+ );
+ if(ec == 0) {
+ ec = (int)umax;
+ if((minpb <= ec) && (ec <= maxpb)) {
+ pComm->updateGauge(ec);
+ }
+ }
+ }
+}
+#endif
+
+
+
+/** Structure to analyze bit depth of an image frame.
+*/
+typedef struct {
+ dk3_pixel_resample_t r01; /**< Pixel resampling to 1 bit. */
+ dk3_pixel_resample_t r02; /**< Pixel resampling to 2 bit. */
+ dk3_pixel_resample_t r04; /**< Pixel resampling to 4 bit. */
+ dk3_pixel_resample_t r08; /**< Pixel resampling to 8 bit. */
+ dk3_pixel_resample_t r12; /**< Pixel resampling to 12 bit. */
+ int finished; /**< Flag: Analysis finished. */
+ int f01; /**< Flag: Can resample to 1 bit. */
+ int f02; /**< Flag: Can resample to 2 bit. */
+ int f04; /**< Flag: Can resample to 4 bit. */
+ int f08; /**< Flag: Can resample to 8 bit. */
+ int f12; /**< Flag: Can resample to 12 bit. */
+} dk3_bif_analyze_bitdepth_t;
+
+
+
+/** Set up analysis structure.
+ @param p Bitdepth analysis structure.
+ @param at Analysis type.
+ @param srcw Source bit width.
+*/
+static
+void
+dk3bif_analyze_setup_structure(
+ dk3_bif_analyze_bitdepth_t *p,
+ int at,
+ size_t srcw
+)
+{
+ p->f01 = 0; p->f02 = 0; p->f04 = 0; p->f08 = 0; p->f12 = 0;
+ dk3pixre_set(&(p->r01), srcw, 1);
+ dk3pixre_set(&(p->r02), srcw, 2);
+ dk3pixre_set(&(p->r04), srcw, 4);
+ dk3pixre_set(&(p->r08), srcw, 8);
+ dk3pixre_set(&(p->r12), srcw, 12);
+ p->finished = 1;
+ if ( 1 < srcw) { p->f01 = 1; p->finished = 0; }
+ if ( 2 < srcw) { p->f02 = 1; }
+ if ( 4 < srcw) { p->f04 = 1; }
+ if ( 8 < srcw) { p->f08 = 1; }
+ if (12 < srcw) { p->f12 = 1; }
+}
+
+
+
+/** Analyse one pixel value.
+ @param p Bit depth analysis structure.
+ @param v Value to analyze.
+*/
+static
+void
+dk3bif_analyze_check_bitvalue(
+ dk3_bif_analyze_bitdepth_t *p,
+ dk3_bif_pixel_t v
+)
+{
+ int changed = 0;
+ if (p->f01) {
+ if (!(dk3pixre_can_convert(&(p->r01), v))) {
+ p->f01 = 0;
+ changed = 1;
+ }
+ }
+ if (p->f02) {
+ if (!(dk3pixre_can_convert(&(p->r02), v))) {
+ p->f02 = 0;
+ changed = 1;
+ }
+ }
+ if (p->f04) {
+ if (!(dk3pixre_can_convert(&(p->r04), v))) {
+ p->f04 = 0;
+ changed = 1;
+ }
+ }
+ if (p->f08) {
+ if (!(dk3pixre_can_convert(&(p->r08), v))) {
+ p->f08 = 0;
+ changed = 1;
+ }
+ }
+ if (p->f12) {
+ if (!(dk3pixre_can_convert(&(p->r12), v))) {
+ p->f12 = 0;
+ changed = 1;
+ }
+ }
+ if (changed) {
+ if (!((p->f01) || (p->f02) || (p->f04) || (p->f08) || (p->f12))) {
+ p->finished = 1;
+ }
+ }
+}
+
+
+
+void
+dk3bif_analyze_progress(
+ dk3_bif_t *bp,
+ int at,
+ void *pcomm,
+ int minpb,
+ int maxpb
+)
+{
+ dk3_bif_analyze_bitdepth_t ana;
+ dk3_bif_coord_t x;
+ dk3_bif_coord_t y;
+ int cc;
+ int found_color;
+ int found_alpha;
+ int search_color;
+ int search_alpha;
+ dk3_bif_pixel_t maxval;
+ dk3_bif_pixel_t r;
+ dk3_bif_pixel_t g;
+ dk3_bif_pixel_t b;
+ dk3_bif_pixel_t a;
+ if (bp) {
+ if (bp->cf) {
+ /* Default values for all color space types.
+ */
+ (bp->cf)->realbits = (bp->cf)->bits;
+ (bp->cf)->realcolor = 0;
+ (bp->cf)->realalpha = 0;
+
+ switch ((bp->cf)->cs) {
+
+ /* For some color space we can not do the analysis.
+ */
+ case DK3_COLOR_SPACE_HSB:
+ case DK3_COLOR_SPACE_YCCK:
+ case DK3_COLOR_SPACE_YCbCr:
+ case DK3_COLOR_SPACE_CMYK:
+ {
+ (bp->cf)->realcolor = 1;
+ (bp->cf)->realalpha = 1;
+ }
+ break;
+
+ /* Do analysis.
+ */
+ default: {
+ /* Default values.
+ */
+ (bp->cf)->realcolor = 0;
+ (bp->cf)->realalpha = 0;
+ search_alpha = 0;
+ search_color = 0;
+ switch ((bp->cf)->cs) {
+ case DK3_COLOR_SPACE_GRAY_ALPHA:
+ case DK3_COLOR_SPACE_RGBA: {
+ if (DK3_BIF_ANALYSIS_ALPHA & at) {
+ search_alpha = 1;
+ } else {
+ (bp->cf)->realalpha = 1;
+ }
+ } break;
+ }
+ switch ((bp->cf)->cs) {
+ case DK3_COLOR_SPACE_RGB:
+ case DK3_COLOR_SPACE_RGBA: {
+ if (DK3_BIF_ANALYSIS_COLOR & at) {
+ search_color = 1;
+ } else {
+ (bp->cf)->realcolor = 1;
+ }
+ } break;
+ }
+
+ /* Do analysis
+ */
+ dk3bif_analyze_setup_structure(&ana, at, (bp->cf)->bits);
+ maxval = dk3pixre_maximum_for_width((bp->cf)->bits);
+ found_color = 0;
+ found_alpha = 0;
+ switch ((bp->cf)->cs) {
+ case DK3_COLOR_SPACE_GRAY_ALPHA:
+ case DK3_COLOR_SPACE_RGBA:
+ {
+ if((bp->cf)->bgr != (bp->cf)->bgg) { found_color = 1; }
+ if((bp->cf)->bgr != (bp->cf)->bgb) { found_color = 1; }
+ if (DK3_BIF_ANALYSIS_BITS & at) {
+ dk3bif_analyze_check_bitvalue(&ana, (bp->cf)->bgr);
+ dk3bif_analyze_check_bitvalue(&ana, (bp->cf)->bgg);
+ dk3bif_analyze_check_bitvalue(&ana, (bp->cf)->bgb);
+ }
+ } break;
+ }
+ cc = 1;
+ for (y = 0; ((y < (bp->cf)->h) && (cc)); y++) {
+ for (x = 0; ((x < (bp->cf)->w) && (cc)); x++) {
+ switch ((bp->cf)->cs) {
+ case DK3_COLOR_SPACE_GRAY: {
+ r = dk3bif_get_pixel_component_not_resampled(bp, x, y, 0);
+ if (DK3_BIF_ANALYSIS_BITS & at) {
+ dk3bif_analyze_check_bitvalue(&ana, r);
+ }
+ } break;
+ case DK3_COLOR_SPACE_GRAY_ALPHA: {
+ r = dk3bif_get_pixel_component_not_resampled(bp, x, y, 0);
+ a = dk3bif_get_pixel_component_not_resampled(bp, x, y, 3);
+ if (DK3_BIF_ANALYSIS_BITS & at) {
+ dk3bif_analyze_check_bitvalue(&ana, r);
+ dk3bif_analyze_check_bitvalue(&ana, a);
+ }
+ if (search_alpha) {
+ if (maxval != a) { found_alpha = 1; }
+ }
+ } break;
+ case DK3_COLOR_SPACE_RGB: {
+ r = dk3bif_get_pixel_component_not_resampled(bp, x, y, 0);
+ g = dk3bif_get_pixel_component_not_resampled(bp, x, y, 1);
+ b = dk3bif_get_pixel_component_not_resampled(bp, x, y, 2);
+ if (DK3_BIF_ANALYSIS_BITS & at) {
+ dk3bif_analyze_check_bitvalue(&ana, r);
+ dk3bif_analyze_check_bitvalue(&ana, g);
+ dk3bif_analyze_check_bitvalue(&ana, b);
+ }
+ if (search_color) {
+ if((r != g) || (r != b)) { found_color = 1; }
+ }
+ } break;
+ case DK3_COLOR_SPACE_RGBA: {
+ r = dk3bif_get_pixel_component_not_resampled(bp, x, y, 0);
+ g = dk3bif_get_pixel_component_not_resampled(bp, x, y, 1);
+ b = dk3bif_get_pixel_component_not_resampled(bp, x, y, 2);
+ a = dk3bif_get_pixel_component_not_resampled(bp, x, y, 3);
+ if (DK3_BIF_ANALYSIS_BITS & at) {
+ dk3bif_analyze_check_bitvalue(&ana, r);
+ dk3bif_analyze_check_bitvalue(&ana, g);
+ dk3bif_analyze_check_bitvalue(&ana, b);
+ dk3bif_analyze_check_bitvalue(&ana, a);
+ }
+ if (search_color) {
+ if((r != g) || (r != b)) { found_color = 1; }
+ }
+ if (search_alpha) {
+ if (maxval != a) { found_alpha = 1; }
+ }
+ } break;
+ }
+ cc = 0;
+ if (DK3_BIF_ANALYSIS_BITS & at) {
+ if(!(ana.finished)) { cc = 1; }
+ }
+ if (search_color) {
+ if(!(found_color)) { cc = 1; }
+ }
+ if (search_alpha) {
+ if(!(found_alpha)) { cc = 1; }
+ }
+ }
+#if DK3_USE_WX
+ dk3bif_show_lines_progress(pcomm, minpb, maxpb, (bp->cf)->h, y);
+#endif
+ }
+
+ /* After analysis apply results.
+ */
+ if (DK3_BIF_ANALYSIS_BITS & at) {
+ if (ana.f01) {
+ (bp->cf)->realbits = 1;
+ } else {
+ if (ana.f02) {
+ (bp->cf)->realbits = 2;
+ } else {
+ if (ana.f04) {
+ (bp->cf)->realbits = 4;
+ } else {
+ if (ana.f08) {
+ (bp->cf)->realbits = 8;
+ } else {
+ if (ana.f12) {
+ (bp->cf)->realbits = 12;
+ }
+ }
+ }
+ }
+ }
+ }
+ if (search_color) {
+ (bp->cf)->realcolor = found_color;
+ }
+ if (search_alpha) {
+ (bp->cf)->realalpha = found_alpha;
+ }
+ if (bp->app) {
+ if (DK3_LL_DEBUG <= dk3app_max_log_level(bp->app)) {
+ dkChar buffer[128];
+ dkChar const * const *msg;
+ msg = dk3app_messages(
+ bp->app, dkT("dk3bifa.str"), dk3bif_analysis_msg
+ );
+ if (DK3_BIF_ANALYSIS_COLOR & at) {
+ switch ((bp->cf)->cs) {
+ case DK3_COLOR_SPACE_RGB:
+ case DK3_COLOR_SPACE_RGBA: {
+ /* Original image: color */
+ dk3app_log_1(bp->app, DK3_LL_DEBUG, msg, 0);
+ if (found_color) {
+ dk3app_log_1(bp->app, DK3_LL_DEBUG, msg, 3);
+ } else {
+ /* Grayscale image */
+ dk3app_log_1(bp->app, DK3_LL_DEBUG, msg, 2);
+ }
+ } break;
+ default: {
+ /* Gray image */
+ dk3app_log_1(bp->app, DK3_LL_DEBUG, msg, 1);
+ } break;
+ }
+ }
+ if (DK3_BIF_ANALYSIS_ALPHA & at) {
+ switch ((bp->cf)->cs) {
+ case DK3_COLOR_SPACE_GRAY_ALPHA:
+ case DK3_COLOR_SPACE_RGBA: {
+ dk3app_log_1(bp->app, DK3_LL_DEBUG, msg, 4);
+ if (found_alpha) {
+ /* Alpha data found */
+ dk3app_log_1(bp->app, DK3_LL_DEBUG, msg, 6);
+ } else {
+ /* No real alpha data */
+ dk3app_log_1(bp->app, DK3_LL_DEBUG, msg, 7);
+ }
+ } break;
+ default: {
+ /* No alpha channel in image */
+ dk3app_log_1(bp->app, DK3_LL_DEBUG, msg, 5);
+ } break;
+ }
+ }
+ if (DK3_BIF_ANALYSIS_BITS & at) {
+#if VERSION_BEFORE_20140716
+ /* Original bits per component */
+ dk3sf_sprintf3(buffer, dkT("%u"), (unsigned)((bp->cf)->bits));
+ dk3app_log_3(bp->app, DK3_LL_DEBUG, msg, 8, 9, buffer);
+ /* Output bits per component */
+ dk3sf_sprintf3(buffer,dkT("%u"),(unsigned)((bp->cf)->realbits));
+ dk3app_log_3(bp->app, DK3_LL_DEBUG, msg, 10, 11, buffer);
+#else
+ int res;
+ res = dk3ma_um_to_string(
+ buffer, DK3_SIZEOF(buffer,dkChar),
+ (dk3_um_t)((bp->cf)->bits)
+ );
+ if (0 != res) {
+ dk3app_log_3(bp->app, DK3_LL_DEBUG, msg, 8, 9, buffer);
+ }
+ res = dk3ma_um_to_string(
+ buffer, DK3_SIZEOF(buffer,dkChar),
+ (dk3_um_t)((bp->cf)->realbits)
+ );
+ if (0 != res) {
+ dk3app_log_3(bp->app, DK3_LL_DEBUG, msg, 10, 11, buffer);
+ }
+#endif
+ }
+ }
+ }
+ } break;
+ }
+ }
+ }
+#if DK3_USE_WX
+ dk3bif_show_lines_progress(pcomm, minpb, maxpb, 1UL, 0UL);
+#endif
+}
+
+
+
+void
+dk3bif_analyze(dk3_bif_t *bp, int at)
+{
+ dk3bif_analyze_progress(bp, at, NULL, 0, 1000);
+}
+
+
diff --git a/support/dktools/dk3bifa.h b/support/dktools/dk3bifa.h
new file mode 100644
index 0000000000..290887a5dd
--- /dev/null
+++ b/support/dktools/dk3bifa.h
@@ -0,0 +1,86 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3bifa.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3bifa.h Header file for the dk3bifa module.
+*/
+
+#ifndef DK3BIFA_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3BIFA_H_INCLUDED 1
+
+
+#line 8 "dk3bifa.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Check bits per component really used and alpha and color usage.
+ As a result of this function (bp->cf)->realbits,
+ (bp->cf)->realcolor, and (bp->cf)->realalpha is set.
+ @param bp Bitmap image file to check.
+ @param at Analysis type, DK3_BIF_ANALYSIS_xxx,
+ @param pcomm Communicator object.
+ @param minpb Minimum progress bar value (0-1000).
+ @param maxpb Maximum progress bar value (0-1000).
+ see @ref bifanalysis.
+*/
+void
+dk3bif_analyze_progress(
+ dk3_bif_t *bp,
+ int at,
+ void *pcomm,
+ int minpb,
+ int maxpb
+);
+
+/** Check bits per component really used and alpha and color usage.
+ As a result of this function (bp->cf)->realbits,
+ (bp->cf)->realcolor, and (bp->cf)->realalpha is set.
+ @param bp Bitmap image file to check.
+ @param at Analysis type, DK3_BIF_ANALYSIS_xxx,
+ see @ref bifanalysis.
+*/
+void
+dk3bif_analyze(dk3_bif_t *bp, int at);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3bits.c b/support/dktools/dk3bits.c
new file mode 100644
index 0000000000..26158ecc40
--- /dev/null
+++ b/support/dktools/dk3bits.c
@@ -0,0 +1,81 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3bits.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3bits.c The dk3bits module.
+*/
+
+
+#line 29 "dk3bits.ctr"
+
+#include "dk3conf.h"
+#include "dk3types.h"
+#include "dk3bits.h"
+
+
+
+/** Masks to set and retrieve single bits.
+*/
+static unsigned short const dk3bits_values[] = {
+0x0001U,
+0x0002U,
+0x0004U,
+0x0008U,
+0x0010U,
+0x0020U,
+0x0040U,
+0x0080U,
+0x0100U,
+0x0200U,
+0x0400U,
+0x0800U,
+0x1000U,
+0x2000U,
+0x4000U,
+0x8000U
+};
+
+
+
+unsigned short
+dk3bits_get(size_t i)
+{
+ unsigned short back = 0U;
+ if(i < 16) {
+ back = dk3bits_values[i];
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk3bits.ctr b/support/dktools/dk3bits.ctr
new file mode 100644
index 0000000000..85cac7a012
--- /dev/null
+++ b/support/dktools/dk3bits.ctr
@@ -0,0 +1,69 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve one bit.
+ @param i Index of bit (0=lsb, 15=msb).
+ @return The requested bit.
+*/
+unsigned short
+dk3bits_get(size_t i);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk3conf.h"
+#include "dk3types.h"
+#include "dk3bits.h"
+
+
+
+/** Masks to set and retrieve single bits.
+*/
+static unsigned short const dk3bits_values[] = {
+0x0001U,
+0x0002U,
+0x0004U,
+0x0008U,
+0x0010U,
+0x0020U,
+0x0040U,
+0x0080U,
+0x0100U,
+0x0200U,
+0x0400U,
+0x0800U,
+0x1000U,
+0x2000U,
+0x4000U,
+0x8000U
+};
+
+
+
+unsigned short
+dk3bits_get(size_t i)
+{
+ unsigned short back = 0U;
+ if(i < 16) {
+ back = dk3bits_values[i];
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk3bits.h b/support/dktools/dk3bits.h
new file mode 100644
index 0000000000..a38fd7c75d
--- /dev/null
+++ b/support/dktools/dk3bits.h
@@ -0,0 +1,64 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3bits.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3bits.h Header file for the dk3bits module.
+*/
+
+#ifndef DK3BITS_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3BITS_H_INCLUDED 1
+
+
+#line 10 "dk3bits.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve one bit.
+ @param i Index of bit (0=lsb, 15=msb).
+ @return The requested bit.
+*/
+unsigned short
+dk3bits_get(size_t i);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3bm.c b/support/dktools/dk3bm.c
new file mode 100644
index 0000000000..09fffa6699
--- /dev/null
+++ b/support/dktools/dk3bm.c
@@ -0,0 +1,4365 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3bm.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3bm.c The dk3bm module.
+*/
+
+
+#line 106 "dk3bm.ctr"
+
+#include "dk3all.h"
+#include "dk3bif.h"
+#include "dk3bifa.h"
+#include "dk3bmeps.h"
+#include "dk3bmeo.h"
+#include "dk3bmj.h"
+#include "dk3pdf.h"
+#include "dk3bm.h"
+
+
+
+#if DK3_USE_WX
+#include <wxbmeps.h>
+#endif
+
+
+
+
+#line 124 "dk3bm.ctr"
+
+
+
+/** Don't debug the module.
+*/
+#define DK3BM_DEBUG 0
+
+
+
+/** File name suffixes for output files.
+*/
+dkChar const * const dk3bm_output_suffixes[] = {
+dkT(".ps"),
+dkT(".eps"),
+dkT(".pdf"),
+dkT(".bb")
+};
+
+
+
+/** Everything between 72-epsilon and 72+epsilon is seen as 72 dpi.
+ Some file formats store the resolution in pixels per meter as
+ integer numbers.
+ If 72.0 is scaled from one inch to a meter and rounded to
+ integer, the rounding error maximum is one. If one dot per meter
+ (the probable rounding error) is converted back to dot per inch
+ the result is 0.254.
+*/
+static double const dk3bm_epsilon = 0.254;
+
+
+
+/** Keywords used by the module.
+*/
+static char const * const dk3bm_c8_kw[] = {
+/* 0 */ "\n",
+/* 1 */ " ",
+/* 2 */ "{\n",
+/* 3 */ "} exec\n",
+/* 4 */ "gsave\n",
+/* 5 */ "grestore\n",
+/* 6 */ "showpage\n",
+/* 7 */ "13 dict begin\n",
+/* 8 */ "end\n",
+/* 9 */ "%lg %lg translate\n",
+/* 10 */ "%d rotate\n",
+/* 11 */ "%lg %lg scale\n",
+/* 12 */ "%ld %ld scale\n",
+/* 13 */ "%!PS-Adobe-2.0",
+/* 14 */ "%!PS-Adobe-3.0",
+/* 15 */ " EPSF-2.0",
+/* 16 */ " EPSF-3.0",
+/* 17 */ "<<\n",
+/* 18 */ ">>\nimage\n",
+/* 19 */ "/ImageType 1\n",
+/* 20 */ "/DeviceRGB setcolorspace\n",
+/* 21 */ "/DeviceGray setcolorspace\n",
+/* 22 */ "/fa currentfile /ASCII85Decode filter def\n",
+/* 23 */ "fa flushfile fa closefile\n",
+/* 24 */ "/fb fa /RunLengthDecode filter def\n",
+/* 25 */ "fb closefile\n",
+/* 26 */ "/fb fa /FlateDecode filter def\n",
+/* 27 */ "/fb fa << >> /DCTDecode filter def\n",
+/* 28 */ "/Width %ld\n",
+/* 29 */ "/Height %ld\n",
+/* 30 */ "/ImageMatrix [%ld 0 0 -%ld 0 %ld]\n",
+/* 31 */ "%%%%BoundingBox: 0 0 %ld %ld\n",
+/* 32 */ "%%LanguageLevel: 2\n",
+/* 33 */ "%%LanguageLevel: 3\n",
+/* 34 */ "/BitsPerComponent %u\n",
+/* 35 */ "/MultipleDataSources true\n",
+/* 36 */ "/MultipleDataSources false\n",
+/* 37 */ "/DataSource fb\n",
+/* 38 */ "/DataSource fa\n",
+/* 39 */ "/DataSource [\n",
+/* 40 */ "{ fb sr readstring pop }\n",
+/* 41 */ "{ fb sg readstring pop }\n",
+/* 42 */ "{ fb sb readstring pop }\n",
+/* 43 */ "]\n",
+/* 44 */ "/Decode [0 1]\n",
+/* 45 */ "/Decode [0 1 0 1 0 1]\n",
+/* 46 */ "/Interpolate true\n",
+/* 47 */ "/Interpolate false\n",
+/* 48 */ "/sr %ld string def\n",
+/* 49 */ "/sg %ld string def\n",
+/* 50 */ "/sb %ld string def\n",
+/* 51 */ "%%Creator: bmeps3\n",
+/* 52 */ "%%Title: ",
+/* 53 */ "%%%%Pages: %u\n",
+/* 54 */ "%%PageOrder: Ascend\n",
+/* 55 */ "%%DocumentData: Clean7Bit\n",
+/* 56 */ "%%EndComments\n",
+/* 57 */ "%%BeginProlog\n",
+/* 58 */ "%%EndProlog\n",
+/* 59 */ "%%BeginSetup\n",
+/* 60 */ "%%EndSetup\n",
+/* 61 */ "%%Trailer\n",
+/* 62 */ "%%EOF\n",
+/* 63 */ "%%%%Page: %u %u\n",
+/* 64 */ "%%BeginFeature: *PageSize BmepsPage\n",
+/* 65 */ "%%EndFeature\n",
+/* 66 */ "<< /PageSize [%ld %ld] /ImagingBBox null >> setpagedevice\n",
+/* 67 */ "%%BeginFeature: *Duplex DuplexNoTumble\n",
+/* 68 */ "<< /Duplex true /Tumble false >> setpagedevice\n",
+/* 69 */ "%%BeginFeature: *Duplex DuplexTumble\n",
+/* 70 */ "<< /Duplex true /Tumble true >> setpagedevice\n",
+/* 71 */ "0 setgray\nnewpath\n",
+/* 72 */ "%lg %lg moveto\n",
+/* 73 */ "%lg %lg lineto\n",
+/* 74 */ "closepath\nfill\n",
+/* 75 */ "0.8 setgray\nnewpath\n",
+/* 76 */ "1 setgray\nnewpath\n",
+/* 77 */ "%lg setlinewidth\n",
+/* 78 */ "newpath\n",
+/* 79 */ "stroke\n",
+/* 80 */ "/fb fa <<\n",
+/* 81 */ ">> /FlateDecode filter def\n",
+/* 82 */ "/Predictor %d\n",
+/* 83 */ "/Columns %ld\n",
+/* 84 */ "/Colors 3\n",
+/* 85 */ "/Colors 1\n",
+/* 86 */ "/DeviceCMYK setcolorspace\n",
+/* 87 */ "/Decode [0 1 0 1 0 1 0 1]\n",
+/* 88 */ "/Decode [1 0 1 0 1 0 1 0]\n",
+};
+
+
+
+/** Convert long to double.
+ @param l Long value to convert.
+ @return Conversion result.
+*/
+static
+double
+dk3bm_l_to_d(long l)
+{
+ return ((double)l);
+}
+
+
+
+/** Correct output buffer.
+ If LC_NUMERIC has a wrong setting it might produce
+ a comma instead of a decimal dot for floating point numbers.
+ The PS and PDF language specification always requires a dot,
+ independent of the users language setting.
+ @param s Buffer start address.
+*/
+static
+void
+dk3bm_correct_output_buffer(char *s)
+{
+ char *ptr; /* Temporary pointer to traverse string. */
+
+
+#line 278 "dk3bm.ctr"
+ if(s) {
+ ptr = s;
+ while(*ptr) {
+ if(*ptr == ',') { *ptr = '.'; }
+ ptr++;
+ }
+ }
+
+#line 285 "dk3bm.ctr"
+}
+
+
+
+/** Write PS header for document.
+ @param job Conversion job.
+ @param pages Number of pages in the print job.
+*/
+static
+void
+dk3bm_ps_document_header(dk3_bm_conversion_job_t *job, size_t pages)
+{
+ char fnb[DK3_MAX_PATH]; /* Buffer used to construct output. */
+ char outputbuffer[256]; /* Another buffer for output. */
+ dkChar const *ptr; /* Used to traverse file name. */
+ dkChar const *nb; /* Short file name. */
+ int ie; /* Input encoding. */
+
+
+#line 303 "dk3bm.ctr"
+ fputs(dk3bm_c8_kw[((job->opt)->psl == 3) ? 14 : 13], job->dfile);
+ if((job->opt)->dr == DK3_BMEPS_DRIVER_EPS) {
+ fputs(dk3bm_c8_kw[((job->opt)->psl == 3) ? 16 : 15], job->dfile);
+ }
+ fputs(dk3bm_c8_kw[0], job->dfile);
+
+#line 308 "dk3bm.ctr"
+ fprintf(job->dfile, dk3bm_c8_kw[31], job->x_size, job->y_size);
+ fputs(dk3bm_c8_kw[((job->opt)->psl == 3) ? 33 : 32], job->dfile);
+ if((job->opt)->dsc) {
+ fputs(dk3bm_c8_kw[51], job->dfile);
+ ptr = job->sfn;
+ if(ptr) {
+ nb = NULL;
+ while(*ptr) {
+ if((*ptr == dkT('\\')) || (*ptr == dkT('/'))) {
+ nb = ptr;
+ }
+ ptr++;
+ }
+ if(nb) {
+ nb++;
+ } else {
+ nb = job->sfn;
+ }
+ ie = dk3app_get_encoding((job->opt)->app);
+ if(dk3str_to_c8p_app(fnb,sizeof(fnb),nb,ie,(job->opt)->app)) {
+ fputs(dk3bm_c8_kw[52], job->dfile);
+ fputc('(', job->dfile);
+ fputs(fnb, job->dfile);
+ fputc(')', job->dfile);
+ fputs(dk3bm_c8_kw[0], job->dfile);
+ }
+ }
+ sprintf(fnb, dk3bm_c8_kw[53], (unsigned)pages);
+ fputs(fnb, job->dfile);
+ for(ie = 54; ie <= 59; ie++) {
+ fputs(dk3bm_c8_kw[ie], job->dfile);
+ }
+ switch((job->opt)->dr) {
+ case DK3_BMEPS_DRIVER_PS: {
+ switch((job->opt)->mode) {
+ case DK3_BMEPS_MODE_DOCUMENT: {
+ fputs(dk3bm_c8_kw[64], job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[66], job->x_size, job->y_size);
+ fputs(outputbuffer, job->dfile);
+ fputs(dk3bm_c8_kw[65], job->dfile);
+ if((job->opt)->duplex) {
+ if((job->opt)->tumble) {
+ fputs(dk3bm_c8_kw[69], job->dfile);
+ fputs(dk3bm_c8_kw[70], job->dfile);
+ fputs(dk3bm_c8_kw[65], job->dfile);
+ } else {
+ fputs(dk3bm_c8_kw[67], job->dfile);
+ fputs(dk3bm_c8_kw[68], job->dfile);
+ fputs(dk3bm_c8_kw[65], job->dfile);
+ }
+ }
+ } break;
+ }
+ } break;
+ }
+ fputs(dk3bm_c8_kw[60], job->dfile);
+ } else {
+ if((job->opt)->duplex) {
+ if((job->opt)->tumble) {
+ fputs(dk3bm_c8_kw[70], job->dfile);
+ } else {
+ fputs(dk3bm_c8_kw[68], job->dfile);
+ }
+ }
+ }
+
+#line 373 "dk3bm.ctr"
+}
+
+
+
+/** Produce footer for PS print job.
+ @param job Conversion job.
+*/
+static
+void
+dk3bm_ps_document_footer(dk3_bm_conversion_job_t *job)
+{
+
+
+#line 385 "dk3bm.ctr"
+ if((job->opt)->dsc) {
+ fputs(dk3bm_c8_kw[61], job->dfile);
+ fputs(dk3bm_c8_kw[62], job->dfile);
+ }
+ switch((job->opt)->dr) {
+ case DK3_BMEPS_DRIVER_PS: {
+ switch((job->opt)->mode) {
+ case DK3_BMEPS_MODE_DOCUMENT: {
+ fputc(0x04, job->dfile);
+ } break;
+ }
+ } break;
+ }
+
+#line 398 "dk3bm.ctr"
+}
+
+
+
+/** Copy DCT encoded data directly from input to output.
+ @param of Output filter.
+ @param dctin Input file containing DCT-encoded data.
+ @param job Conversion job.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bm_copy_dct_data(
+ dk3_of_t *of,
+ FILE *dctin,
+ dk3_bm_conversion_job_t *job
+)
+{
+ char bu[4096]; /* Buffer for data read from file. */
+ size_t rb; /* Number of bytes read. */
+ int back = 1;
+ int cc; /* Flag: Can continue. */
+
+
+#line 421 "dk3bm.ctr"
+ cc = 1;
+ while(cc) {
+ cc = 0;
+ rb = dk3sf_fread_app((void *)bu, 1, sizeof(bu), dctin, (job->opt)->app);
+ if(rb > 0) {
+ cc = 1;
+ if(!dk3of_write_bytes(of, (unsigned char *)bu, rb)) {
+ back = 0;
+ cc = 0;
+ /* ERROR: Failed to write data! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 58, DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ }
+ }
+
+#line 437 "dk3bm.ctr"
+ return back;
+}
+
+
+
+/** Write flate filter definition with predictor.
+ @param job Conversion job.
+*/
+static
+void
+dk3bm_define_flate_with_predictor(dk3_bm_conversion_job_t *job)
+{
+ char outputbuffer[256]; /* Buffer to construct output. */
+ int i = 0; /* Predictor ID in PS and PDF. */
+
+
+#line 452 "dk3bm.ctr"
+ fputs(dk3bm_c8_kw[80], job->dfile);
+ /* Predictor Columns Colors BitsPerComponent */
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ i = 2;
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_SUB: {
+ i = 11;
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_UP: {
+ i = 12;
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_AVERAGE: {
+ i = 13;
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_PAETH: {
+ i = 14;
+ } break;
+ }
+ sprintf(outputbuffer, dk3bm_c8_kw[82], i);
+ fputs(outputbuffer, job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[83], dk3bif_get_width(job->bif));
+ fputs(outputbuffer, job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[34], job->bpc);
+ fputs(outputbuffer, job->dfile);
+ if(job->procedure == DK3_BMEPS_RGB_FLATE) {
+ fputs(dk3bm_c8_kw[84], job->dfile);
+ } else {
+ fputs(dk3bm_c8_kw[85], job->dfile);
+ }
+ fputs(dk3bm_c8_kw[81], job->dfile);
+
+#line 483 "dk3bm.ctr"
+}
+
+
+
+/** Write one unsigned character.
+ @param of Output filter.
+ @param v Value to write to output.
+*/
+static
+void
+dk3bm_write_uc(dk3_of_t *of, dk3_bif_pixel_t v)
+{
+ unsigned char ucv; /* Byte to write. */
+
+
+#line 497 "dk3bm.ctr"
+ ucv = (unsigned char)v;
+ dk3of_write_bytes(of, &ucv, 1);
+
+#line 499 "dk3bm.ctr"
+}
+
+
+
+/** Produce PS for image or object.
+ The following components of job must be set:
+ x_size, y_size, x_translate, y_translate, x_0, x_1, y_0, y_1,
+ x_scale, y_scale, do_translate, do_rotate, do_float_scale.
+ @param job Conversion job.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bm_job_produce_img_job_real_ps(dk3_bm_conversion_job_t *job)
+{
+ char outputbuffer[256]; /* Buffer to prepare output. */
+ FILE *dctin; /* Input file containing DCT data. */
+ dk3_stream_t *os; /* Output stream. */
+ dk3_of_t *of; /* Output filter. */
+ long bitsperline; /* Bits per line. */
+ long bytesperline; /* Bytes per line. */
+ dk3_bif_coord_t w; /* Image width. */
+ dk3_bif_coord_t h; /* Image height. */
+ dk3_bif_coord_t x; /* Current x. */
+ dk3_bif_coord_t y; /* Current y. */
+ dk3_bif_pixel_t v; /* Current point value. */
+ dk3_bif_pixel_t pl; /* Left pixel. */
+ dk3_bif_pixel_t pu; /* Upper pixel. */
+ dk3_bif_pixel_t plu; /* Left upper pixel. */
+ size_t nbits; /* Number of bits per component. */
+ int back = 0;
+ int analysis_type = 0; /* Analysis to perform. */
+ int use_dct = 0; /* Flag: DCT used. */
+ int me = 0; /* Flag: Math error. */
+ int alphain = 0; /* Flag: Alpha channel. */
+#if TRACE_DEBUG || VERSION_BEFORE_20150821
+ int colorin = 0; /* Flag: Color image. */
+#endif
+#if DK3_USE_WX
+ int minpb; /* Original min progress bar value. */
+ int maxpb; /* Original max progress bar value. */
+ int pbmin; /* Min progress bar value. */
+ int pbmax; /* Max progress bar value. */
+#endif
+
+
+#line 544 "dk3bm.ctr"
+#if DK3_USE_WX
+ minpb = job->minpb;
+ maxpb = job->maxpb;
+#endif
+ if(job->dfile) {
+
+#line 549 "dk3bm.ctr"
+ alphain = 0;
+ switch(dk3bif_get_color_space(job->bif)) {
+ case DK3_COLOR_SPACE_GRAY_ALPHA:
+ case DK3_COLOR_SPACE_RGBA:
+ {
+ alphain = 1;
+
+#line 555 "dk3bm.ctr"
+ } break;
+ }
+#if VERSION_BEFORE_20150821
+ /* Already initialized to 0 */
+ colorin = 0;
+#endif
+ switch(dk3bif_get_color_space(job->bif)) {
+ case DK3_COLOR_SPACE_GRAY:
+ case DK3_COLOR_SPACE_GRAY_ALPHA: {
+ } break;
+ default: {
+ /* Static code analysis: Dead assignment */
+ /* Variable used when tracing, not in normaly build */
+#if VERSION_BEFORE_20150821
+ colorin = 1;
+
+#line 570 "dk3bm.ctr"
+#endif
+ } break;
+ }
+ /*
+ Conversion defaults.
+ */
+ w = dk3bif_get_width(job->bif);
+ h = dk3bif_get_height(job->bif);
+ job->procedure = DK3_BMEPS_GRAY_UNCOMPRESSED;
+ job->bpc = 8;
+ /*
+ Decisions about compression, bpc, colors.
+ */
+ analysis_type = 0;
+ switch(dk3bif_get_type(job->bif)) {
+ case DK3_BIF_IMAGE_TYPE_JPEG: {
+
+#line 586 "dk3bm.ctr"
+ if((job->opt)->dct) {
+
+#line 587 "dk3bm.ctr"
+ switch(dk3bif_get_bits_per_pixel(job->bif)) {
+ case 8: case 4: case 2: case 1: {
+
+#line 589 "dk3bm.ctr"
+ switch(dk3bif_jpeg_get_num_components(job->bif)) {
+ case 1: {
+
+#line 591 "dk3bm.ctr"
+ job->procedure = DK3_BMEPS_GRAY_DCT;
+ job->bpc = dk3bif_get_bits_per_pixel(job->bif);
+ use_dct = 1;
+ } break;
+ case 3: {
+
+#line 596 "dk3bm.ctr"
+ job->procedure = DK3_BMEPS_RGB_DCT;
+ job->bpc = dk3bif_get_bits_per_pixel(job->bif);
+ use_dct = 1;
+ } break;
+ case 4: {
+
+#line 601 "dk3bm.ctr"
+ job->procedure = DK3_BMEPS_CMYK_DCT;
+ job->bpc = dk3bif_get_bits_per_pixel(job->bif);
+ use_dct = 1;
+ } break;
+ default: {
+
+#line 606 "dk3bm.ctr"
+ } break;
+ }
+ } break;
+ }
+ }
+ } break;
+ }
+ if(!(use_dct)) {
+ if((job->opt)->color) {
+ switch(dk3bif_get_color_space(job->bif)) {
+ case DK3_COLOR_SPACE_GRAY:
+ case DK3_COLOR_SPACE_GRAY_ALPHA: {
+ } break;
+ default: {
+ analysis_type |= DK3_BIF_ANALYSIS_COLOR;
+ } break;
+ }
+ }
+ if((job->opt)->rbpc) {
+ analysis_type |= DK3_BIF_ANALYSIS_BITS;
+ }
+ if(alphain) {
+ analysis_type |= DK3_BIF_ANALYSIS_ALPHA;
+ }
+ /* PROGRESS: Analyzing image. */
+ dk3app_log_1((job->opt)->app, DK3_LL_PROGRESS, job->msg, 48);
+ if(analysis_type) {
+#if DK3_USE_WX
+ dk3bif_analyze_progress(
+ job->bif, analysis_type, job->pComm, minpb, ((maxpb + minpb)/2)
+ );
+#else
+ dk3bif_analyze(job->bif, analysis_type);
+#endif
+ }
+ nbits = dk3bif_get_bits_per_pixel(job->bif);
+ if((job->opt)->rbpc) { nbits = dk3bif_real_bits_per_pixel(job->bif); }
+#if 0
+ /* 2014-03-22
+ New algorithms for bits per component detection and reduction.
+ */
+ job->bpc = 1;
+ if(nbits > 1) {
+ job->bpc = 2;
+ if(nbits > 2) {
+ job->bpc = 4;
+ if(nbits > 4) {
+ job->bpc = 8;
+ if(nbits > 8) {
+ job->bpc = 12;
+ }
+ }
+ }
+ }
+#else
+ switch (nbits) {
+ case 1: { job->bpc = 1; } break;
+ case 2: { job->bpc = 2; } break;
+ case 4: { job->bpc = 4; } break;
+ case 12: { job->bpc = 12; } break;
+ default: { job->bpc = 8; } break;
+ }
+#endif
+
+/* 2014-03-23
+ The dk3bifa module generate debug output.
+*/
+#if 0
+ /* DEBUG: Analysis results. */
+ {
+ dkChar numbuf[128];
+ dkChar const *msgpart[3];
+ int convres;
+ msgpart[0] = (job->msg)[51];
+ msgpart[1] = (job->msg)[(colorin) ? 49 : 50];
+ dk3app_log_msg((job->opt)->app, DK3_LL_DEBUG, msgpart, 2);
+ msgpart[0] = (job->msg)[52];
+ msgpart[1] = (job->msg)[(dk3bif_real_color(job->bif)) ? 49 : 50];
+ dk3app_log_msg((job->opt)->app, DK3_LL_DEBUG, msgpart, 2);
+ msgpart[0] = (job->msg)[53];
+ msgpart[1] = (job->msg)[(alphain) ? 49 : 50];
+ dk3app_log_msg((job->opt)->app, DK3_LL_DEBUG, msgpart, 2);
+ msgpart[0] = (job->msg)[54];
+ msgpart[1] = (job->msg)[(dk3bif_real_alpha(job->bif)) ? 49 : 50];
+ dk3app_log_msg((job->opt)->app, DK3_LL_DEBUG, msgpart, 2);
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(numbuf,dkT("%u"),(unsigned)dk3bif_get_bits_per_pixel(job->bif));
+ msgpart[0] = (job->msg)[55];
+ msgpart[1] = numbuf;
+ dk3app_log_msg((job->opt)->app, DK3_LL_DEBUG, msgpart, 2);
+ dk3sf_sprintf3(numbuf,dkT("%u"),(unsigned)dk3bif_real_bits_per_pixel(job->bif));
+ msgpart[0] = (job->msg)[56];
+ msgpart[1] = numbuf;
+ dk3app_log_msg((job->opt)->app, DK3_LL_DEBUG, msgpart, 2);
+ dk3sf_sprintf3(numbuf,dkT("%u"),(unsigned)(job->bpc));
+ msgpart[0] = (job->msg)[57];
+ msgpart[1] = numbuf;
+ dk3app_log_msg((job->opt)->app, DK3_LL_DEBUG, msgpart, 2);
+#else
+ convres = dk3ma_um_to_string(
+ numbuf, DK3_SIZEOF(numbuf,dkChar),
+ (dk3_um_t)dk3bif_get_bits_per_pixel(job->bif)
+ );
+ if (0 != convres) {
+ msgpart[0] = (job->msg)[55];
+ msgpart[1] = numbuf;
+ dk3app_log_msg((job->opt)->app, DK3_LL_DEBUG, msgpart, 2);
+ }
+ convres = dk3ma_um_to_string(
+ numbuf, DK3_SIZEOF(numbuf,dkChar),
+ (dk3_um_t)dk3bif_real_bits_per_pixel(job->bif)
+ );
+ if (0 != convres) {
+ msgpart[0] = (job->msg)[56];
+ msgpart[1] = numbuf;
+ dk3app_log_msg((job->opt)->app, DK3_LL_DEBUG, msgpart, 2);
+ }
+ convres = dk3ma_um_to_string(
+ numbuf, DK3_SIZEOF(numbuf,dkChar), (dk3_um_t)(job->bpc)
+ );
+ if (0 != convres) {
+ msgpart[0] = (job->msg)[57];
+ msgpart[1] = numbuf;
+ dk3app_log_msg((job->opt)->app, DK3_LL_DEBUG, msgpart, 2);
+ }
+#endif
+ }
+#endif
+#if VERSION_BEFORE_20150821
+ if(analysis_type & DK3_BIF_ANALYSIS_COLOR) {
+ colorin = dk3bif_real_color(job->bif);
+ }
+#endif
+ if(analysis_type & DK3_BIF_ANALYSIS_ALPHA) {
+ alphain = dk3bif_real_alpha(job->bif);
+ }
+ switch(dk3bif_get_color_space(job->bif)) {
+ case DK3_COLOR_SPACE_GRAY:
+ case DK3_COLOR_SPACE_GRAY_ALPHA: {
+ job->procedure = DK3_BMEPS_GRAY_RUNLENGTH;
+ if((job->opt)->psl >= 3) {
+ job->procedure = DK3_BMEPS_GRAY_FLATE;
+ if((job->opt)->pred > DK3_COMPRESSION_PREDICTOR_TIFF) {
+ job->bpc = 8;
+ }
+ }
+ } break;
+ default: {
+ if(dk3bif_real_color(job->bif)) {
+ job->procedure = DK3_BMEPS_RGB_UNCOMPRESSED;
+ if((job->opt)->psl >= 3) {
+ job->procedure = DK3_BMEPS_RGB_FLATE;
+ if((job->opt)->pred > DK3_COMPRESSION_PREDICTOR_TIFF) {
+ job->bpc = 8;
+ }
+ } else {
+ bitsperline = dk3ma_l_mul_ok((long)(job->bpc), w, &me);
+ if(me == 0) {
+ bytesperline = bitsperline / 8L;
+ if(bitsperline % 8L) { bytesperline++; }
+ if(bytesperline < 16384L) {
+ job->procedure = DK3_BMEPS_RGB_RUNLENGTH;
+ }
+ }
+ }
+ } else {
+ job->procedure = DK3_BMEPS_GRAY_RUNLENGTH;
+ if((job->opt)->psl >= 3) {
+ job->procedure = DK3_BMEPS_GRAY_FLATE;
+ if((job->opt)->pred > DK3_COMPRESSION_PREDICTOR_TIFF) {
+ job->bpc = 8;
+ }
+ }
+ }
+ } break;
+ }
+ }
+ dk3app_log_1((job->opt)->app, DK3_LL_PROGRESS, job->msg, 76);
+#if DK3BM_DEBUG
+ job->procedure = DK3_BMEPS_RGB_UNCOMPRESSED;
+#endif
+#if DK3_USE_WX
+
+
+#line 789 "dk3bm.ctr"
+ dk3bmj_progress(job->pComm, ((maxpb + minpb)/2));
+ job->minpb = ((maxpb + minpb) / 2);
+ pbmin = job->minpb;
+ pbmax = job->maxpb;
+#endif
+ /*
+ File header.
+ */
+ if(job->do_header_footer) {
+ dk3bm_ps_document_header(job, 1);
+ }
+ /*
+ Image.
+ */
+ if((job->opt)->dsc) {
+ sprintf(
+ outputbuffer, dk3bm_c8_kw[63],
+ (unsigned)(job->currentPage),
+ (unsigned)(job->currentPage)
+ );
+ fputs(outputbuffer, job->dfile);
+ }
+ fputs(dk3bm_c8_kw[2], job->dfile); /* { */
+ fputs(dk3bm_c8_kw[4], job->dfile); /* gsave */
+ /*
+ Translate, rotate, scale.
+ */
+ if(job->do_translate) {
+ sprintf(
+ outputbuffer, dk3bm_c8_kw[9], job->x_translate, job->y_translate
+ );
+ dk3bm_correct_output_buffer(outputbuffer);
+ fputs(outputbuffer, job->dfile);
+ }
+ if(job->do_rotate) {
+ sprintf(outputbuffer, dk3bm_c8_kw[10], (90 * job->do_rotate));
+ fputs(outputbuffer, job->dfile);
+ }
+ if(job->do_float_scale) {
+ sprintf(
+ outputbuffer,
+ dk3bm_c8_kw[11],
+ job->x_scale, job->y_scale
+ );
+ dk3bm_correct_output_buffer(outputbuffer);
+ } else {
+ sprintf(outputbuffer, dk3bm_c8_kw[12], w, h);
+ }
+ fputs(outputbuffer, job->dfile);
+ fputs(dk3bm_c8_kw[7], job->dfile); /* 13 dict begin */
+ /*
+ Color space, definitions for data source(s).
+ */
+ switch(job->procedure) {
+ case DK3_BMEPS_GRAY_UNCOMPRESSED: {
+ fputs(dk3bm_c8_kw[21], job->dfile);
+ fputs(dk3bm_c8_kw[22], job->dfile);
+ } break;
+ case DK3_BMEPS_RGB_UNCOMPRESSED: {
+ fputs(dk3bm_c8_kw[20], job->dfile);
+ fputs(dk3bm_c8_kw[22], job->dfile);
+ } break;
+ case DK3_BMEPS_GRAY_RUNLENGTH: {
+ fputs(dk3bm_c8_kw[21], job->dfile);
+ fputs(dk3bm_c8_kw[22], job->dfile);
+ fputs(dk3bm_c8_kw[24], job->dfile);
+ } break;
+ case DK3_BMEPS_RGB_RUNLENGTH: {
+ fputs(dk3bm_c8_kw[20], job->dfile);
+ fputs(dk3bm_c8_kw[22], job->dfile);
+ fputs(dk3bm_c8_kw[24], job->dfile);
+ bitsperline = w * (long)(job->bpc);
+ bytesperline = bitsperline / 8L;
+ if(bitsperline % 8L) { bytesperline++; }
+ fprintf(job->dfile, dk3bm_c8_kw[48], bytesperline);
+ fprintf(job->dfile, dk3bm_c8_kw[49], bytesperline);
+ fprintf(job->dfile, dk3bm_c8_kw[50], bytesperline);
+ } break;
+ case DK3_BMEPS_GRAY_DCT: {
+ fputs(dk3bm_c8_kw[21], job->dfile);
+ fputs(dk3bm_c8_kw[22], job->dfile);
+ fputs(dk3bm_c8_kw[27], job->dfile);
+ } break;
+ case DK3_BMEPS_RGB_DCT: {
+ fputs(dk3bm_c8_kw[20], job->dfile);
+ fputs(dk3bm_c8_kw[22], job->dfile);
+ fputs(dk3bm_c8_kw[27], job->dfile);
+ } break;
+ case DK3_BMEPS_CMYK_DCT: {
+ fputs(dk3bm_c8_kw[86], job->dfile);
+ fputs(dk3bm_c8_kw[22], job->dfile);
+ fputs(dk3bm_c8_kw[27], job->dfile);
+ } break;
+ case DK3_BMEPS_GRAY_FLATE: {
+ fputs(dk3bm_c8_kw[21], job->dfile);
+ fputs(dk3bm_c8_kw[22], job->dfile);
+ if((job->opt)->pred) {
+ dk3bm_define_flate_with_predictor(job);
+ } else {
+ fputs(dk3bm_c8_kw[26], job->dfile);
+ }
+ } break;
+ case DK3_BMEPS_RGB_FLATE: {
+ fputs(dk3bm_c8_kw[20], job->dfile);
+ fputs(dk3bm_c8_kw[22], job->dfile);
+ if((job->opt)->pred) {
+ dk3bm_define_flate_with_predictor(job);
+ } else {
+ fputs(dk3bm_c8_kw[26], job->dfile);
+ }
+ } break;
+ }
+ fputs(dk3bm_c8_kw[17], job->dfile); /* << */
+ /*
+ Image dictionary contents.
+ */
+ fputs(dk3bm_c8_kw[19], job->dfile); /* /ImageType 1 */
+ sprintf(outputbuffer, dk3bm_c8_kw[28], w);
+ fputs(outputbuffer, job->dfile); /* /Width ... */
+ sprintf(outputbuffer, dk3bm_c8_kw[29], h);
+ fputs(outputbuffer, job->dfile); /* /Height ... */
+ sprintf(outputbuffer, dk3bm_c8_kw[30], w, h, h);
+ fputs(outputbuffer, job->dfile); /* /ImageMatrix ... */
+ sprintf(outputbuffer, dk3bm_c8_kw[34], (unsigned)(job->bpc));
+ fputs(outputbuffer, job->dfile); /* /BitsPerComponent ... */
+ /* /Interpolate ... */
+ switch(job->procedure) {
+ case DK3_BMEPS_GRAY_UNCOMPRESSED: {
+ fputs(dk3bm_c8_kw[38], job->dfile);
+ fputs(dk3bm_c8_kw[44], job->dfile);
+ fputs(dk3bm_c8_kw[((job->opt)->ip) ? 46 : 47], job->dfile);
+ } break;
+ case DK3_BMEPS_RGB_UNCOMPRESSED: {
+ fputs(dk3bm_c8_kw[36], job->dfile);
+ fputs(dk3bm_c8_kw[38], job->dfile);
+ fputs(dk3bm_c8_kw[45], job->dfile);
+ fputs(dk3bm_c8_kw[((job->opt)->ip) ? 46 : 47], job->dfile);
+ } break;
+ case DK3_BMEPS_GRAY_RUNLENGTH: {
+ fputs(dk3bm_c8_kw[37], job->dfile);
+ fputs(dk3bm_c8_kw[44], job->dfile);
+ fputs(dk3bm_c8_kw[((job->opt)->ip) ? 46 : 47], job->dfile);
+ } break;
+ case DK3_BMEPS_RGB_RUNLENGTH: {
+ fputs(dk3bm_c8_kw[35], job->dfile);
+ fputs(dk3bm_c8_kw[39], job->dfile);
+ fputs(dk3bm_c8_kw[40], job->dfile);
+ fputs(dk3bm_c8_kw[41], job->dfile);
+ fputs(dk3bm_c8_kw[42], job->dfile);
+ fputs(dk3bm_c8_kw[43], job->dfile);
+ fputs(dk3bm_c8_kw[45], job->dfile);
+ fputs(dk3bm_c8_kw[((job->opt)->ip) ? 46 : 47], job->dfile);
+ } break;
+ case DK3_BMEPS_GRAY_DCT: {
+ fputs(dk3bm_c8_kw[37], job->dfile);
+ fputs(dk3bm_c8_kw[44], job->dfile);
+ if((job->opt)->ip) {
+ if((job->opt)->jip) {
+ fputs(dk3bm_c8_kw[46], job->dfile);
+ }
+ }
+ } break;
+ case DK3_BMEPS_RGB_DCT: {
+ fputs(dk3bm_c8_kw[36], job->dfile);
+ fputs(dk3bm_c8_kw[37], job->dfile);
+ fputs(dk3bm_c8_kw[45], job->dfile);
+ if((job->opt)->ip) {
+ if((job->opt)->jip) {
+ fputs(dk3bm_c8_kw[46], job->dfile);
+ }
+ }
+ } break;
+ case DK3_BMEPS_CMYK_DCT: {
+ fputs(dk3bm_c8_kw[36], job->dfile);
+ fputs(dk3bm_c8_kw[37], job->dfile);
+ if(dk3bif_jpeg_get_found_adobe_marker(job->bif)) {
+ fputs(dk3bm_c8_kw[88], job->dfile);
+ } else {
+ fputs(dk3bm_c8_kw[87], job->dfile);
+ }
+ if((job->opt)->ip) {
+ if((job->opt)->jip) {
+ fputs(dk3bm_c8_kw[46], job->dfile);
+ }
+ }
+ } break;
+ case DK3_BMEPS_GRAY_FLATE: {
+ fputs(dk3bm_c8_kw[37], job->dfile);
+ fputs(dk3bm_c8_kw[44], job->dfile);
+ fputs(dk3bm_c8_kw[((job->opt)->ip) ? 46 : 47], job->dfile);
+ } break;
+ case DK3_BMEPS_RGB_FLATE: {
+ fputs(dk3bm_c8_kw[36], job->dfile);
+ fputs(dk3bm_c8_kw[37], job->dfile);
+ fputs(dk3bm_c8_kw[45], job->dfile);
+ fputs(dk3bm_c8_kw[((job->opt)->ip) ? 46 : 47], job->dfile);
+ } break;
+ }
+ fputs(dk3bm_c8_kw[18], job->dfile); /* >> image */
+ /*
+ Close data streams.
+ */
+ switch(job->procedure) {
+ case DK3_BMEPS_GRAY_UNCOMPRESSED: {
+ fputs(dk3bm_c8_kw[23], job->dfile);
+ } break;
+ case DK3_BMEPS_RGB_UNCOMPRESSED: {
+ fputs(dk3bm_c8_kw[23], job->dfile);
+ } break;
+ case DK3_BMEPS_GRAY_RUNLENGTH: {
+ fputs(dk3bm_c8_kw[25], job->dfile);
+ fputs(dk3bm_c8_kw[23], job->dfile);
+ } break;
+ case DK3_BMEPS_RGB_RUNLENGTH: {
+ fputs(dk3bm_c8_kw[25], job->dfile);
+ fputs(dk3bm_c8_kw[23], job->dfile);
+ } break;
+ case DK3_BMEPS_GRAY_DCT: {
+ fputs(dk3bm_c8_kw[25], job->dfile);
+ fputs(dk3bm_c8_kw[23], job->dfile);
+ } break;
+ case DK3_BMEPS_RGB_DCT: {
+ fputs(dk3bm_c8_kw[25], job->dfile);
+ fputs(dk3bm_c8_kw[23], job->dfile);
+ } break;
+ case DK3_BMEPS_CMYK_DCT: {
+ fputs(dk3bm_c8_kw[25], job->dfile);
+ fputs(dk3bm_c8_kw[23], job->dfile);
+ } break;
+ case DK3_BMEPS_GRAY_FLATE: {
+ fputs(dk3bm_c8_kw[25], job->dfile);
+ fputs(dk3bm_c8_kw[23], job->dfile);
+ } break;
+ case DK3_BMEPS_RGB_FLATE: {
+ fputs(dk3bm_c8_kw[25], job->dfile);
+ fputs(dk3bm_c8_kw[23], job->dfile);
+ } break;
+ }
+ fputs(dk3bm_c8_kw[8], job->dfile); /* end */
+ fputs(dk3bm_c8_kw[5], job->dfile); /* grestore */
+ switch((job->opt)->mode) {
+ case DK3_BMEPS_MODE_IMAGE:
+ case DK3_BMEPS_MODE_DOCUMENT: {
+ if((job->opt)->dr == DK3_BMEPS_DRIVER_PS) {
+ fputs(dk3bm_c8_kw[6], job->dfile); /* showpage */
+ }
+ } break;
+ }
+ fputs(dk3bm_c8_kw[3], job->dfile); /* } exec */
+ /*
+ Write compress/encoded image data.
+ */
+ os = dk3stream_open_file_app(
+ job->dfile, DK3_STREAM_FLAG_WRITE, (job->opt)->app
+ );
+ if(os) {
+ of = dk3of_open_app(os, (job->opt)->app);
+ if(of) {
+ dk3of_set_finalize(of, 1);
+ if(dk3of_add_cell(of, DK3_OF_CELL_TYPE_A85)) {
+ switch(job->procedure) {
+ case DK3_BMEPS_GRAY_UNCOMPRESSED: {
+ dk3bif_set_bits_per_pixel(job->bif, job->bpc);
+ if(dk3of_start_chunk(of)) {
+ if(job->bpc == 8) {
+ if(alphain) {
+ for(y = 0L; y < h; y++) {
+ for(x = 0L; x < w; x++) {
+ v = dk3bif_get_mixed_gray(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } else {
+ for(y = 0L; y < h; y++) {
+ for(x = 0L; x < w; x++) {
+ v = dk3bif_get_gray(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ }
+ } else {
+ if(alphain) {
+ for(y = 0L; y < h; y++) {
+ for(x = 0L; x < w; x++) {
+ v = dk3bif_get_mixed_gray(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ }
+ dk3of_flush_bits(of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } else {
+ for(y = 0L; y < h; y++) {
+ for(x = 0L; x < w; x++) {
+ v = dk3bif_get_gray(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ }
+ dk3of_flush_bits(of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ }
+ }
+ back = dk3of_end_chunk(of);
+ } else {
+ /* ERROR: Failed to start encoded chunk! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 59,
+ DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ } break;
+ case DK3_BMEPS_RGB_UNCOMPRESSED: {
+ dk3bif_set_bits_per_pixel(job->bif, job->bpc);
+ if(dk3of_start_chunk(of)) {
+ if(job->bpc == 8) {
+ if(alphain) {
+ for(y = 0L; y < h; y++) {
+ for(x = 0L; x < w; x++) {
+ v = dk3bif_get_mixed_red(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ v = dk3bif_get_mixed_green(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ v = dk3bif_get_mixed_blue(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } else {
+ for(y = 0L; y < h; y++) {
+ for(x = 0L; x < w; x++) {
+ v = dk3bif_get_red(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ v = dk3bif_get_green(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ v = dk3bif_get_blue(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ }
+ } else {
+ if(alphain) {
+ for(y = 0L; y < h; y++) {
+ for(x = 0L; x < w; x++) {
+ v = dk3bif_get_mixed_red(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ v = dk3bif_get_mixed_green(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ v = dk3bif_get_mixed_blue(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ }
+ dk3of_flush_bits(of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } else {
+ for(y = 0L; y < h; y++) {
+ for(x = 0L; x < w; x++) {
+ v = dk3bif_get_red(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ v = dk3bif_get_green(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ v = dk3bif_get_blue(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ }
+ dk3of_flush_bits(of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ }
+ }
+ back = dk3of_end_chunk(of);
+ } else {
+ /* ERROR: Failed to start encoded chunk! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 59,
+ DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ } break;
+ case DK3_BMEPS_GRAY_RUNLENGTH: {
+ dk3bif_set_bits_per_pixel(job->bif, job->bpc);
+ if(dk3of_add_cell(of, DK3_OF_CELL_TYPE_RUN_LENGTH)) {
+ if(dk3of_start_chunk(of)) {
+ if(job->bpc == 8) {
+ if(alphain) {
+ for(y = 0UL; y < h; y++) {
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_gray(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } else {
+ for(y = 0UL; y < h; y++) {
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_gray(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ }
+ } else {
+ if(alphain) {
+ for(y = 0UL; y < h; y++) {
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_gray(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ }
+ dk3of_flush_bits(of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } else {
+ for(y = 0UL; y < h; y++) {
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_gray(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ }
+ dk3of_flush_bits(of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ }
+ }
+ back = dk3of_end_chunk(of);
+ } else {
+ /* ERROR: Failed to start encoded chunk! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 59,
+ DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ } else {
+ /* ERROR: Failed to add run-length cell! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 59,
+ DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ } break;
+ case DK3_BMEPS_RGB_RUNLENGTH: {
+ dk3bif_set_bits_per_pixel(job->bif, job->bpc);
+ if(dk3of_add_cell(of, DK3_OF_CELL_TYPE_RUN_LENGTH)) {
+ if(dk3of_start_chunk(of)) {
+ if(job->bpc == 8) {
+ if(alphain) {
+ for(y = 0UL; y < h; y++) {
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_red(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ }
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_green(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ }
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_blue(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } else {
+ for(y = 0UL; y < h; y++) {
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_red(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ }
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_green(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ }
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_blue(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ }
+ } else {
+ if(alphain) {
+ for(y = 0UL; y < h; y++) {
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_red(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ }
+ dk3of_flush_bits(of);
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_green(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ }
+ dk3of_flush_bits(of);
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_blue(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ }
+ dk3of_flush_bits(of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } else {
+ for(y = 0UL; y < h; y++) {
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_red(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ }
+ dk3of_flush_bits(of);
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_green(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ }
+ dk3of_flush_bits(of);
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_blue(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ }
+ dk3of_flush_bits(of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ }
+ }
+ back = dk3of_end_chunk(of);
+ } else {
+ /* ERROR: Failed to start encoded chunk! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 59,
+ DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ } else {
+ /* ERROR: Failed to add run-length cell! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 59,
+ DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ } break;
+ case DK3_BMEPS_GRAY_DCT:
+ case DK3_BMEPS_RGB_DCT:
+ case DK3_BMEPS_CMYK_DCT: {
+ dctin = dk3bif_get_file(job->bif);
+ if(dctin) {
+ rewind(dctin);
+ if(dk3of_start_chunk(of)) {
+ back = dk3bm_copy_dct_data(of, dctin, job);
+ if(back) {
+ back = dk3of_end_chunk(of);
+ } else {
+ (void)dk3of_end_chunk(of);
+ }
+ } else {
+ /* ERROR: Failed to start encoded chunk! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 59,
+ DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ } else {
+ /* BUG: No input file! */
+ }
+ } break;
+ case DK3_BMEPS_GRAY_FLATE: {
+ dk3bif_set_bits_per_pixel(job->bif, job->bpc);
+ if(dk3of_add_cell(of, DK3_OF_CELL_TYPE_FLATE)) {
+ if(dk3of_start_chunk(of)) {
+ if(job->bpc == 8) {
+ if(alphain) {
+
+#line 1384 "dk3bm.ctr"
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ for(y = 0UL; y < h; y++) {
+ pl = 0;
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_gray(job->bif, x, y);
+ dk3bm_write_uc(of, (v - pl));
+ pl = v;
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_SUB: {
+ for(y = 0UL; y < h; y++) {
+ pl = 0;
+ dk3bm_write_uc(of, 1);
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_gray(job->bif, x, y);
+ dk3bm_write_uc(of, (v - pl));
+ pl = v;
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_UP: {
+ for(y = 0UL; y < h; y++) {
+ dk3bm_write_uc(of, 2);
+ for(x = 0UL; x < w; x++) {
+
+#line 1416 "dk3bm.ctr"
+ v = dk3bif_get_mixed_gray(job->bif, x, y);
+ pu = dk3bif_get_mixed_gray(job->bif, x, (y - 1L));
+
+
+#line 1419 "dk3bm.ctr"
+ v = v - pu;
+
+#line 1420 "dk3bm.ctr"
+ dk3bm_write_uc(of, v);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_AVERAGE: {
+ for(y = 0UL; y < h; y++) {
+ dk3bm_write_uc(of, 3);
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_gray(job->bif, x, y);
+ pl = dk3bif_get_mixed_gray(job->bif, (x - 1L), y);
+ pu = dk3bif_get_mixed_gray(job->bif, x, (y - 1L));
+ pl = dk3bif_average(pl, pu);
+ pl &= 0x00FFU;
+ v = v - pl;
+ dk3bm_write_uc(of, v);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_PAETH: {
+ for(y = 0UL; y < h; y++) {
+ dk3bm_write_uc(of, 4);
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_gray(job->bif, x, y);
+ pl = dk3bif_get_mixed_gray(job->bif, (x - 1L), y);
+ pu = dk3bif_get_mixed_gray(job->bif, x, (y - 1L));
+ plu = dk3bif_get_mixed_gray(
+ job->bif, (x - 1L), (y - 1L)
+ );
+ pl = dk3bif_paeth(pl, pu, plu);
+ v = v - pl;
+ dk3bm_write_uc(of, v);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ default: {
+ for(y = 0UL; y < h; y++) {
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_gray(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ }
+ } else {
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ for(y = 0UL; y < h; y++) {
+ pl = 0;
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_gray(job->bif, x, y);
+ dk3bm_write_uc(of, (v - pl));
+ pl = v;
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_SUB: {
+ for(y = 0UL; y < h; y++) {
+ dk3bm_write_uc(of, 1);
+ pl = 0;
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_gray(job->bif, x, y);
+ dk3bm_write_uc(of, (v - pl));
+ pl = v;
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_UP: {
+ for(y = 0UL; y < h; y++) {
+ dk3bm_write_uc(of, 2);
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_gray(job->bif, x, y);
+ pu = dk3bif_get_gray(job->bif, x, (y - 1L));
+ dk3bm_write_uc(of, (v - pu));
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_AVERAGE: {
+ for(y = 0UL; y < h; y++) {
+ dk3bm_write_uc(of, 3);
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_gray(job->bif, x, y);
+ pl = dk3bif_get_gray(job->bif, (x - 1L), y);
+ pu = dk3bif_get_gray(job->bif, x, (y - 1L));
+ pl = dk3bif_average(pl, pu);
+ pl &= 0x00FFU;
+ v = v - pl;
+ dk3bm_write_uc(of, v);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_PAETH: {
+ for(y = 0UL; y < h; y++) {
+ dk3bm_write_uc(of, 4);
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_gray(job->bif, x, y);
+ pl = dk3bif_get_gray(job->bif, (x - 1L), y);
+ pu = dk3bif_get_gray(job->bif, x, (y - 1L));
+ plu = dk3bif_get_gray(
+ job->bif, (x - 1L), (y - 1L)
+ );
+ pl = dk3bif_paeth(pl, pu, plu);
+ v = v - pl;
+ dk3bm_write_uc(of, v);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ default: {
+ for(y = 0UL; y < h; y++) {
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_gray(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ }
+ }
+ } else {
+ if(alphain) {
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ for(y = 0UL; y < h; y++) {
+ pl = 0;
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_gray(job->bif, x, y);
+ dk3of_write_bits(of, (v - pl), job->bpc);
+ pl = v;
+ }
+ dk3of_flush_bits(of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ default: {
+ for(y = 0UL; y < h; y++) {
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_gray(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ }
+ dk3of_flush_bits(of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ }
+ } else {
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ for(y = 0UL; y < h; y++) {
+ pl = 0;
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_gray(job->bif, x, y);
+ dk3of_write_bits(of, (v - pl), job->bpc);
+ pl = v;
+ }
+ dk3of_flush_bits(of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ default: {
+ for(y = 0UL; y < h; y++) {
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_gray(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ }
+ dk3of_flush_bits(of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ }
+ }
+ }
+ back = dk3of_end_chunk(of);
+ } else {
+ /* ERROR: Failed to start encoded chunk! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 59,
+ DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ } else {
+ /* ERROR: Failed to add run-length cell! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 59,
+ DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ } break;
+ case DK3_BMEPS_RGB_FLATE: {
+ dk3bif_set_bits_per_pixel(job->bif, job->bpc);
+ if(dk3of_add_cell(of, DK3_OF_CELL_TYPE_FLATE)) {
+ if(dk3of_start_chunk(of)) {
+ if(job->bpc == 8) {
+ if(alphain) {
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ for(y = 0UL; y < h; y++) {
+ pl = 0; /* r */
+ pu = 0; /* g */
+ plu = 0; /* b */
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_red(job->bif, x, y);
+ dk3bm_write_uc(of, (v - pl));
+ pl = v;
+ v = dk3bif_get_mixed_green(job->bif, x, y);
+ dk3bm_write_uc(of, (v - pu));
+ pu = v;
+ v = dk3bif_get_mixed_blue(job->bif, x, y);
+ dk3bm_write_uc(of, (v - plu));
+ plu = v;
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_SUB: {
+ for(y = 0UL; y < h; y++) {
+ pl = 0; /* r */
+ pu = 0; /* g */
+ plu = 0; /* b */
+ dk3bm_write_uc(of, 1);
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_red(job->bif, x, y);
+ dk3bm_write_uc(of, (v - pl));
+ pl = v;
+ v = dk3bif_get_mixed_green(job->bif, x, y);
+ dk3bm_write_uc(of, (v - pu));
+ pu = v;
+ v = dk3bif_get_mixed_blue(job->bif, x, y);
+ dk3bm_write_uc(of, (v - plu));
+ plu = v;
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_UP: {
+ for(y = 0UL; y < h; y++) {
+ dk3bm_write_uc(of, 2);
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_red(job->bif, x, y);
+ pu = dk3bif_get_mixed_red(job->bif, x, (y - 1L));
+ dk3bm_write_uc(of, (v - pu));
+ v = dk3bif_get_mixed_green(job->bif, x, y);
+ pu = dk3bif_get_mixed_green(job->bif, x, (y - 1L));
+ dk3bm_write_uc(of, (v - pu));
+ v = dk3bif_get_mixed_blue(job->bif, x, y);
+ pu = dk3bif_get_mixed_blue(job->bif, x, (y - 1L));
+ dk3bm_write_uc(of, (v - pu));
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_AVERAGE: {
+ for(y = 0UL; y < h; y++) {
+ dk3bm_write_uc(of, 3);
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_red(job->bif, x, y);
+ pl = dk3bif_get_mixed_red(job->bif, (x - 1L), y);
+ pu = dk3bif_get_mixed_red(job->bif, x, (y - 1L));
+ pu = dk3bif_average(pl, pu);
+ dk3bm_write_uc(of, (v - pu));
+ v = dk3bif_get_mixed_green(job->bif, x, y);
+ pl = dk3bif_get_mixed_green(job->bif, (x - 1L), y);
+ pu = dk3bif_get_mixed_green(job->bif, x, (y - 1L));
+ pu = dk3bif_average(pl, pu);
+ dk3bm_write_uc(of, (v - pu));
+ v = dk3bif_get_mixed_blue(job->bif, x, y);
+ pl = dk3bif_get_mixed_blue(job->bif, (x - 1L), y);
+ pu = dk3bif_get_mixed_blue(job->bif, x, (y - 1L));
+ pu = dk3bif_average(pl, pu);
+ dk3bm_write_uc(of, (v - pu));
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_PAETH: {
+ for(y = 0UL; y < h; y++) {
+ dk3bm_write_uc(of, 3);
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_red(job->bif, x, y);
+ pl = dk3bif_get_mixed_red(job->bif, (x - 1L), y);
+ pu = dk3bif_get_mixed_red(job->bif, x, (y - 1L));
+ plu = dk3bif_get_mixed_red(job->bif, (x - 1L), (y - 1L));
+ pu = dk3bif_paeth(pl, pu, plu);
+ dk3bm_write_uc(of, (v - pu));
+ v = dk3bif_get_mixed_green(job->bif, x, y);
+ pl = dk3bif_get_mixed_green(job->bif, (x - 1L), y);
+ pu = dk3bif_get_mixed_green(job->bif, x, (y - 1L));
+ plu = dk3bif_get_mixed_green(job->bif, (x - 1L), (y - 1L));
+ pu = dk3bif_paeth(pl, pu, plu);
+ dk3bm_write_uc(of, (v - pu));
+ v = dk3bif_get_mixed_blue(job->bif, x, y);
+ pl = dk3bif_get_mixed_blue(job->bif, (x - 1L), y);
+ pu = dk3bif_get_mixed_blue(job->bif, x, (y - 1L));
+ plu = dk3bif_get_mixed_blue(job->bif, (x - 1L), (y - 1L));
+ pu = dk3bif_paeth(pl, pu, plu);
+ dk3bm_write_uc(of, (v - pu));
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ default: {
+ for(y = 0UL; y < h; y++) {
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_red(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ v = dk3bif_get_mixed_green(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ v = dk3bif_get_mixed_blue(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ }
+ } else {
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ for(y = 0UL; y < h; y++) {
+ pl = 0; /* r */
+ pu = 0; /* g */
+ plu = 0; /* b */
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_red(job->bif, x, y);
+ dk3bm_write_uc(of, (v - pl));
+ pl = v;
+ v = dk3bif_get_green(job->bif, x, y);
+ dk3bm_write_uc(of, (v - pu));
+ pu = v;
+ v = dk3bif_get_blue(job->bif, x, y);
+ dk3bm_write_uc(of, (v - plu));
+ plu = v;
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_SUB: {
+ for(y = 0UL; y < h; y++) {
+ pl = 0; /* r */
+ pu = 0; /* g */
+ plu = 0; /* b */
+ dk3bm_write_uc(of, 1);
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_red(job->bif, x, y);
+ dk3bm_write_uc(of, (v - pl));
+ pl = v;
+ v = dk3bif_get_green(job->bif, x, y);
+ dk3bm_write_uc(of, (v - pu));
+ pu = v;
+ v = dk3bif_get_blue(job->bif, x, y);
+ dk3bm_write_uc(of, (v - plu));
+ plu = v;
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_UP: {
+ for(y = 0UL; y < h; y++) {
+ dk3bm_write_uc(of, 2);
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_red(job->bif, x, y);
+ pu = dk3bif_get_red(job->bif, x, (y - 1L));
+ dk3bm_write_uc(of, (v - pu));
+ v = dk3bif_get_green(job->bif, x, y);
+ pu = dk3bif_get_green(job->bif, x, (y - 1L));
+ dk3bm_write_uc(of, (v - pu));
+ v = dk3bif_get_blue(job->bif, x, y);
+ pu = dk3bif_get_blue(job->bif, x, (y - 1L));
+ dk3bm_write_uc(of, (v - pu));
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_AVERAGE: {
+ for(y = 0UL; y < h; y++) {
+ dk3bm_write_uc(of, 3);
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_red(job->bif, x, y);
+ pl = dk3bif_get_red(job->bif, (x - 1L), y);
+ pu = dk3bif_get_red(job->bif, x, (y - 1L));
+ pu = dk3bif_average(pl, pu);
+ dk3bm_write_uc(of, (v - pu));
+ v = dk3bif_get_green(job->bif, x, y);
+ pl = dk3bif_get_green(job->bif, (x - 1L), y);
+ pu = dk3bif_get_green(job->bif, x, (y - 1L));
+ pu = dk3bif_average(pl, pu);
+ dk3bm_write_uc(of, (v - pu));
+ v = dk3bif_get_blue(job->bif, x, y);
+ pl = dk3bif_get_blue(job->bif, (x - 1L), y);
+ pu = dk3bif_get_blue(job->bif, x, (y - 1L));
+ pu = dk3bif_average(pl, pu);
+ dk3bm_write_uc(of, (v - pu));
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_PAETH: {
+ for(y = 0UL; y < h; y++) {
+ dk3bm_write_uc(of, 3);
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_red(job->bif, x, y);
+ pl = dk3bif_get_red(job->bif, (x - 1L), y);
+ pu = dk3bif_get_red(job->bif, x, (y - 1L));
+ plu = dk3bif_get_red(job->bif, (x - 1L), (y - 1L));
+ pu = dk3bif_paeth(pl, pu, plu);
+ dk3bm_write_uc(of, (v - pu));
+ v = dk3bif_get_green(job->bif, x, y);
+ pl = dk3bif_get_green(job->bif, (x - 1L), y);
+ pu = dk3bif_get_green(job->bif, x, (y - 1L));
+ plu = dk3bif_get_green(job->bif, (x - 1L), (y - 1L));
+ pu = dk3bif_paeth(pl, pu, plu);
+ dk3bm_write_uc(of, (v - pu));
+ v = dk3bif_get_blue(job->bif, x, y);
+ pl = dk3bif_get_blue(job->bif, (x - 1L), y);
+ pu = dk3bif_get_blue(job->bif, x, (y - 1L));
+ plu = dk3bif_get_blue(job->bif, (x - 1L), (y - 1L));
+ pu = dk3bif_paeth(pl, pu, plu);
+ dk3bm_write_uc(of, (v - pu));
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ default : {
+ for(y = 0UL; y < h; y++) {
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_red(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ v = dk3bif_get_green(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ v = dk3bif_get_blue(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ }
+ }
+ } else {
+ if(alphain) {
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ for(y = 0UL; y < h; y++) {
+ pl = 0; pu = 0; plu = 0;
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_red(job->bif, x, y);
+ dk3of_write_bits(of, (v - pl), job->bpc);
+ pl = v;
+ v = dk3bif_get_mixed_green(job->bif, x, y);
+ dk3of_write_bits(of, (v - pu), job->bpc);
+ pu = v;
+ v = dk3bif_get_mixed_blue(job->bif, x, y);
+ dk3of_write_bits(of, (v - plu), job->bpc);
+ plu = v;
+ }
+ dk3of_flush_bits(of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ default: {
+ for(y = 0UL; y < h; y++) {
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_red(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ v = dk3bif_get_mixed_green(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ v = dk3bif_get_mixed_blue(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ }
+ dk3of_flush_bits(of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ }
+ } else {
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ for(y = 0UL; y < h; y++) {
+ pl = 0; pu = 0; plu = 0;
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_red(job->bif, x, y);
+ dk3of_write_bits(of, (v - pl), job->bpc);
+ pl = v;
+ v = dk3bif_get_green(job->bif, x, y);
+ dk3of_write_bits(of, (v - pu), job->bpc);
+ pu = v;
+ v = dk3bif_get_blue(job->bif, x, y);
+ dk3of_write_bits(of, (v - plu), job->bpc);
+ plu = v;
+ }
+ dk3of_flush_bits(of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ default: {
+ for(y = 0UL; y < h; y++) {
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_red(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ v = dk3bif_get_green(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ v = dk3bif_get_blue(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ }
+ dk3of_flush_bits(of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ }
+ }
+ }
+ back = dk3of_end_chunk(of);
+ } else {
+ /* ERROR: Failed to start encoded chunk! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 59,
+ DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ } else {
+ /* ERROR: Failed to add run-length cell! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 59,
+ DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ } break;
+ }
+ } else {
+ /* ERROR: Failed to add filter cell! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 59,
+ DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ dk3of_close(of);
+ } else {
+ /* ERROR: Failed to create output filter! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 59, DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ dk3stream_close(os);
+ } else {
+ /* ERROR: Failed to create output stream! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 59, DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ /*
+ File footer.
+ */
+ if(job->do_header_footer) {
+ dk3bm_ps_document_footer(job);
+ }
+ } else {
+
+#line 2041 "dk3bm.ctr"
+ /* BUG: No output file! */
+ }
+#if DK3_USE_WX
+ job->minpb = minpb;
+ job->maxpb = maxpb;
+#endif
+
+
+#line 2048 "dk3bm.ctr"
+ return back;
+}
+
+
+
+int
+dk3bm_find_transformation(
+ dk3_coordinates_transformation_t *dst,
+ dk3_bb_t *outbb,
+ int drawdir,
+ double imw,
+ double imh,
+ double xres,
+ double yres,
+ int *ec
+)
+{
+ double w = 0.0; /* Image width. */
+ double h = 0.0; /* Image height. */
+ double sx = 0.0; /* X scale factor. */
+ double sy = 0.0; /* Y scale factor. */
+#if VERSION_BEFORE_20150821
+ double sf = 0.0; /* Scale factor. */
+#endif
+ double xmin = 0.0; /* Minimum X. */
+ double xmax = 0.0; /* Maximum X. */
+ double ymin = 0.0; /* Minimum Y. */
+ double ymax = 0.0; /* Maximum Y. */
+ double xused = 0.0; /* Used X range. */
+ double yused = 0.0; /* Used Y range. */
+ double xborder = 0.0; /* X border. */
+ double yborder = 0.0; /* Y border. */
+ int mec = 0; /* Mathematical error code. */
+ int back = 0;
+
+
+#line 2083 "dk3bm.ctr"
+ if((dst) && (outbb)) {
+ back = 1;
+ w = imw;
+
+#line 2086 "dk3bm.ctr"
+ h = imh;
+
+#line 2087 "dk3bm.ctr"
+ if((xres > 0.0) && (yres > 0.0)) {
+ w = dk3ma_d_div_ok(w, xres, &mec);
+
+#line 2089 "dk3bm.ctr"
+ h = dk3ma_d_div_ok(h, yres, &mec);
+
+#line 2090 "dk3bm.ctr"
+ }
+#if VERSION_BEFORE_20150821
+ sx = sy = sf = 0.0;
+#endif
+ switch(drawdir) {
+ case DK3_IMAGE_ORIGIN_LEFT_BOTTOM:
+ case DK3_IMAGE_ORIGIN_RIGHT_TOP:
+ case DK3_IMAGE_ORIGIN_LEFT_TOP_FLIPPED:
+ case DK3_IMAGE_ORIGIN_RIGHT_BOTTOM_FLIPPED:
+ {
+ sx = dk3ma_d_div_ok(
+ dk3ma_d_sub_ok(outbb->xmax, outbb->xmin, ec),
+ h,
+ ec
+ );
+ sy = dk3ma_d_div_ok(
+ dk3ma_d_sub_ok(outbb->ymax, outbb->ymin, ec),
+ w,
+ ec
+ );
+ if(sx < sy) { /* Entire X range used. */
+ xmin = outbb->xmin;
+ xmax = outbb->xmax;
+ xused = dk3ma_d_sub_ok(xmax, xmin, ec);
+#if VERSION_BEFORE_20150821
+ xborder = 0.0;
+#endif
+ yused = dk3ma_d_mul_ok(sx, w, ec);
+ yborder = 0.5 * dk3ma_d_sub_ok(
+ dk3ma_d_sub_ok(outbb->ymax, outbb->ymin, ec),
+ yused,
+ ec
+ );
+ if(yborder < 0.0) { yborder = 0.0; }
+ ymin = dk3ma_d_add_ok(outbb->ymin, yborder, ec);
+ ymax = dk3ma_d_add_ok(ymin, yused, ec);
+ } else { /* Entire Y range used. */
+ ymin = outbb->ymin;
+ ymax = outbb->ymax;
+ yused = dk3ma_d_sub_ok(ymax, ymin, ec);
+#if VERSION_BEFORE_20150821
+ yborder = 0.0;
+#endif
+ xused = dk3ma_d_mul_ok(sy, h, ec);
+ xborder = 0.5 * dk3ma_d_sub_ok(
+ dk3ma_d_sub_ok(outbb->xmax, outbb->xmin, ec),
+ xused,
+ ec
+ );
+ if(xborder < 0.0) { xborder = 0.0; }
+ xmin = dk3ma_d_add_ok(outbb->xmin, xborder, ec);
+ xmax = dk3ma_d_add_ok(xmin, xused, ec);
+ }
+ } break;
+ default: {
+ sx = dk3ma_d_div_ok(
+ dk3ma_d_sub_ok(outbb->xmax, outbb->xmin, ec),
+ w,
+ ec
+ );
+ sy = dk3ma_d_div_ok(
+ dk3ma_d_sub_ok(outbb->ymax, outbb->ymin, ec),
+ h,
+ ec
+ );
+ if(sx < sy) { /* Entire X range used. */
+ xmin = outbb->xmin;
+ xmax = outbb->xmax;
+ xused = dk3ma_d_sub_ok(xmax, xmin, ec);
+#if VERSION_BEFORE_20150821
+ xborder = 0.0;
+#endif
+ yused = dk3ma_d_mul_ok(sx, h, ec);
+ yborder = 0.5 * dk3ma_d_sub_ok(
+ dk3ma_d_sub_ok(outbb->ymax, outbb->ymin, ec),
+ yused,
+ ec
+ );
+ if(yborder < 0.0) { yborder = 0.0; }
+ ymin = dk3ma_d_add_ok(outbb->ymin, yborder, ec);
+ ymax = dk3ma_d_add_ok(ymin, yused, ec);
+ } else { /* Entire Y range used. */
+ ymin = outbb->ymin;
+ ymax = outbb->ymax;
+ yused = dk3ma_d_sub_ok(ymax, ymin, ec);
+#if VERSION_BEFORE_20150821
+ yborder = 0.0;
+#endif
+ xused = dk3ma_d_mul_ok(sy, w, ec);
+ xborder = 0.5 * dk3ma_d_sub_ok(
+ dk3ma_d_sub_ok(outbb->xmax, outbb->xmin, ec),
+ xused,
+ ec
+ );
+ if(xborder < 0.0) { xborder = 0.0; }
+ xmin = dk3ma_d_add_ok(outbb->xmin, xborder, ec);
+ xmax = dk3ma_d_add_ok(xmin, xused, ec);
+ }
+ } break;
+ }
+ dst->x_scale = xused;
+ dst->y_scale = yused;
+
+
+#line 2193 "dk3bm.ctr"
+
+
+#line 2194 "dk3bm.ctr"
+
+
+#line 2195 "dk3bm.ctr"
+
+
+#line 2196 "dk3bm.ctr"
+
+
+#line 2197 "dk3bm.ctr"
+
+
+#line 2198 "dk3bm.ctr"
+ dst->rot = 0;
+ switch(drawdir) {
+ case DK3_IMAGE_ORIGIN_LEFT_BOTTOM: { /* 1 */
+ dst->x_translate = xmax;
+ dst->y_translate = ymin;
+ dst->rot = 1;
+ dst->x_scale = yused;
+ dst->y_scale = xused;
+ } break;
+ case DK3_IMAGE_ORIGIN_RIGHT_TOP: { /* 2 */
+ dst->x_translate = xmin;
+ dst->y_translate = ymax;
+ dst->rot = 3;
+ dst->x_scale = yused;
+ dst->y_scale = xused;
+ } break;
+ case DK3_IMAGE_ORIGIN_RIGHT_BOTTOM: { /* 3 */
+ dst->x_translate = xmax;
+ dst->y_translate = ymax;
+ dst->rot = 2;
+ } break;
+ case DK3_IMAGE_ORIGIN_LEFT_TOP_FLIPPED: { /* 4 */
+ dst->x_translate = xmax;
+ dst->y_translate = ymax;
+ dst->rot = 1;
+ dst->x_scale = yused;
+ dst->y_scale = xused;
+ dst->x_scale = -1.0 * (dst->x_scale);
+ } break;
+ case DK3_IMAGE_ORIGIN_LEFT_BOTTOM_FLIPPED: { /* 5 */
+ dst->x_translate = xmin;
+ dst->y_translate = ymax;
+ dst->y_scale = -1.0 * (dst->y_scale);
+ } break;
+ case DK3_IMAGE_ORIGIN_RIGHT_TOP_FLIPPED: { /* 6 */
+ dst->x_translate = xmax;
+ dst->y_translate = ymin;
+ dst->x_scale = -1.0 * (dst->x_scale);
+ } break;
+ case DK3_IMAGE_ORIGIN_RIGHT_BOTTOM_FLIPPED: { /* 7 */
+ dst->x_translate = xmin;
+ dst->y_translate = ymin;
+ dst->rot = 3;
+ dst->x_scale = yused;
+ dst->y_scale = xused;
+ dst->x_scale = -1.0 * (dst->x_scale);
+ } break;
+ default: { /* left top */
+ dst->x_translate = xmin;
+ dst->y_translate = ymin;
+ dst->rot = 0;
+ } break;
+ }
+
+
+#line 2252 "dk3bm.ctr"
+
+
+#line 2253 "dk3bm.ctr"
+
+
+#line 2254 "dk3bm.ctr"
+
+
+#line 2255 "dk3bm.ctr"
+
+
+#line 2256 "dk3bm.ctr"
+ }
+ if(mec) {
+ if(ec) { *ec = mec; }
+ }
+
+#line 2260 "dk3bm.ctr"
+ return back;
+}
+
+
+
+int
+dk3bm_find_bif_transformation(
+ dk3_coordinates_transformation_t *dst,
+ dk3_bif_t *bif,
+ dk3_bb_t *outbb,
+ int drawdir,
+ int *ec
+)
+{
+ double w;
+ double h;
+ double xres;
+ double yres;
+ dk3_bif_coord_t imw;
+ dk3_bif_coord_t imh;
+ int back = 0;
+
+
+#line 2282 "dk3bm.ctr"
+ if((dst) && (bif) && (outbb)) {
+ imw = dk3bif_get_width(bif);
+ imh = dk3bif_get_height(bif);
+ w = (double)imw;
+ h = (double)imh;
+ xres = dk3bif_get_xres(bif);
+ yres = dk3bif_get_yres(bif);
+ back = dk3bm_find_transformation(dst, outbb, drawdir, w, h, xres, yres, ec);
+ }
+
+#line 2291 "dk3bm.ctr"
+ return back;
+}
+
+
+
+int
+dk3bm_ps_place_object(
+ FILE *dfile,
+ dk3_bb_t *outbb,
+ int drawdir,
+ char const *sfn,
+ dk3_app_t *app,
+ int pslevel,
+ int *ec
+)
+{
+ dk3_coordinates_transformation_t trans;
+ dk3_bm_eps_options_t bmeo;
+ dk3_bm_conversion_job_t job;
+ int back = 0;
+
+
+#line 2312 "dk3bm.ctr"
+ if((dfile) && (outbb) && (sfn) && (app)) {
+ dk3bmj_init(&job, app);
+ dk3bmeo_init(&bmeo);
+
+#line 2315 "dk3bm.ctr"
+ job.opt = &bmeo;
+ job.sfn = NULL;
+ job.dfile = dfile;
+ job.do_header_footer = 0;
+ bmeo.app = app;
+ bmeo.ima.ia.xl = outbb->xmin;
+ bmeo.ima.ia.xr = outbb->xmax;
+ bmeo.ima.ia.yb = outbb->ymin;
+ bmeo.ima.ia.yt = outbb->ymax;
+#if VERSION_BEFORE_20140902
+ bmeo.mode =
+ bmeo.szmode =
+ bmeo.dr = DK3_BMEPS_DRIVER_EPS;
+#else
+ bmeo.mode = DK3_BMEPS_MODE_OBJECT;
+ bmeo.szmode = DK3_BMEPS_SIZE_1_1;
+
+#line 2331 "dk3bm.ctr"
+ bmeo.dr = DK3_BMEPS_DRIVER_EPS;
+#endif
+ bmeo.io = drawdir;
+ bmeo.psl = pslevel;
+ job.bif = dk3bif_open_c8_filename_app(sfn,DK3_BIF_IMAGE_TYPE_UNKNOWN,app);
+ if(job.bif) {
+
+#line 2337 "dk3bm.ctr"
+ job.biftype = dk3bif_get_type(job.bif);
+ /* job.procedure = */
+
+#line 2339 "dk3bm.ctr"
+ /* job->x_size */
+ /* job->y_size */
+ /* job->x_0 */
+ /* job->x_1 */
+ /* job->y_0 */
+ /* job->y_1 */
+ /* job->procedure */
+ /* job->bpc */
+ /* job->nPages */
+ /* job->currentPage */
+ if(dk3bm_find_bif_transformation(&trans, job.bif, outbb, drawdir, ec)) {
+ /* FIG2LAT */
+
+#line 2351 "dk3bm.ctr"
+ job.x_translate = trans.x_translate;
+ job.y_translate = trans.y_translate;
+ job.x_scale = trans.x_scale;
+ job.y_scale = trans.y_scale;
+ job.do_rotate = trans.rot;
+ job.do_translate = 1;
+ job.do_float_scale = 1;
+
+#line 2358 "dk3bm.ctr"
+ if(dk3bif_read_data(job.bif)) {
+ back = dk3bm_job_produce_img_job_real_ps(&job);
+ } else {
+ /* ##### ERROR: Failed to read image data! */
+ }
+ } else {
+ /* ##### ERROR: Failed to calculate transformation data */
+ }
+ dk3bif_close(job.bif);
+ } else {
+
+#line 2368 "dk3bm.ctr"
+ /* ##### ERROR: Failed to open image */
+ }
+ } else {
+
+#line 2371 "dk3bm.ctr"
+ }
+
+#line 2372 "dk3bm.ctr"
+ return back;
+}
+
+
+
+/** Paper size check function.
+ @param ps Paper size to check.
+ @return 1 on success, 0 on error (borders larger than paper).
+*/
+static
+int
+dk3bm_check_paper_size(dk3_paper_size_t *ps)
+{
+ int back = 0;
+
+
+#line 2387 "dk3bm.ctr"
+ if(ps->w > (ps->i + ps->o)) {
+ if(ps->h > (ps->t + ps->b)) {
+ back = 1;
+ }
+ }
+
+#line 2392 "dk3bm.ctr"
+ return back;
+}
+
+
+
+/** Produce PS draft for image or object.
+ The x_0, x_1, y_0 and y_1 values must be set.
+ @param job Conversion job.
+ @return 1 on succes, 0 on error.
+*/
+static
+int
+dk3bm_job_produce_img_job_draft_ps(dk3_bm_conversion_job_t *job)
+{
+ char outputbuffer[256]; /* Conversion buffer for numbers. */
+ double dx; /* Stripe width. */
+ double dy; /* Stripe width backup. */
+ int back = 0;
+
+
+#line 2411 "dk3bm.ctr"
+ dk3bm_ps_document_header(job, job->nPages);
+ fputs(dk3bm_c8_kw[4], job->dfile);
+ fputs(dk3bm_c8_kw[21], job->dfile);
+ fputs(dk3bm_c8_kw[71], job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[72], job->x_0, job->y_0);
+ dk3bm_correct_output_buffer(outputbuffer);
+ fputs(outputbuffer, job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[73], job->x_1, job->y_0);
+ dk3bm_correct_output_buffer(outputbuffer);
+ fputs(outputbuffer, job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[73], job->x_1, job->y_1);
+ dk3bm_correct_output_buffer(outputbuffer);
+ fputs(outputbuffer, job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[73], job->x_0, job->y_1);
+ dk3bm_correct_output_buffer(outputbuffer);
+ fputs(outputbuffer, job->dfile);
+ fputs(dk3bm_c8_kw[74], job->dfile);
+ dx = 0.01 * (job->x_1 - job->x_0);
+ dy = 0.01 * (job->y_1 - job->y_0);
+ if(dy < dx) dx = dy;
+ if(dx > 2.8) dx = 2.8;
+ fputs(dk3bm_c8_kw[75], job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[72], job->x_0+dx, job->y_0+dx);
+ dk3bm_correct_output_buffer(outputbuffer);
+ fputs(outputbuffer, job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[73], job->x_1-dx, job->y_0+dx);
+ dk3bm_correct_output_buffer(outputbuffer);
+ fputs(outputbuffer, job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[73], job->x_1-dx, job->y_1-dx);
+ dk3bm_correct_output_buffer(outputbuffer);
+ fputs(outputbuffer, job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[73], job->x_0+dx, job->y_1-dx);
+ dk3bm_correct_output_buffer(outputbuffer);
+ fputs(outputbuffer, job->dfile);
+ fputs(dk3bm_c8_kw[74], job->dfile);
+ dx = 10.0 * dx;
+ fputs(dk3bm_c8_kw[76], job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[72], job->x_0+dx, job->y_0+dx);
+ dk3bm_correct_output_buffer(outputbuffer);
+ fputs(outputbuffer, job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[73], job->x_1-dx, job->y_0+dx);
+ dk3bm_correct_output_buffer(outputbuffer);
+ fputs(outputbuffer, job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[73], job->x_1-dx, job->y_1-dx);
+ dk3bm_correct_output_buffer(outputbuffer);
+ fputs(outputbuffer, job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[73], job->x_0+dx, job->y_1-dx);
+ dk3bm_correct_output_buffer(outputbuffer);
+ fputs(outputbuffer, job->dfile);
+ fputs(dk3bm_c8_kw[74], job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[77], 0.9 * dx);
+ dk3bm_correct_output_buffer(outputbuffer);
+ fputs(outputbuffer, job->dfile);
+ fputs(dk3bm_c8_kw[75], job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[72], job->x_0+dx, job->y_0+dx);
+ dk3bm_correct_output_buffer(outputbuffer);
+ fputs(outputbuffer, job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[73], job->x_1-dx, job->y_1-dx);
+ dk3bm_correct_output_buffer(outputbuffer);
+ fputs(outputbuffer, job->dfile);
+ fputs(dk3bm_c8_kw[79], job->dfile);
+ fputs(dk3bm_c8_kw[78], job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[72], job->x_0+dx, job->y_1-dx);
+ dk3bm_correct_output_buffer(outputbuffer);
+ fputs(outputbuffer, job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[73], job->x_1-dx, job->y_0+dx);
+ dk3bm_correct_output_buffer(outputbuffer);
+ fputs(outputbuffer, job->dfile);
+ fputs(dk3bm_c8_kw[79], job->dfile);
+ fputs(dk3bm_c8_kw[5], job->dfile);
+ switch((job->opt)->mode) {
+ case DK3_BMEPS_MODE_IMAGE:
+ case DK3_BMEPS_MODE_DOCUMENT: {
+ if((job->opt)->dr == DK3_BMEPS_DRIVER_PS) {
+ fputs(dk3bm_c8_kw[6], job->dfile); /* showpage */
+ }
+ } break;
+ }
+ dk3bm_ps_document_footer(job);
+
+
+#line 2491 "dk3bm.ctr"
+ return back;
+}
+
+
+
+/** Do the real work when producing a PS document.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bm_job_produce_doc_real_ps(dk3_bm_conversion_job_t *job)
+{
+ double dmaxwidth = 0.0; /* Max width PS points. */
+ double dmaxheight = 0.0; /* Max height PS points. */
+ double xres; /* X res current frame. */
+ double yres; /* Y res current frame. */
+ double deltax; /* Real x width. */
+ double deltay; /* Real y width. */
+ double sx; /* Scale factor x. */
+ double sy; /* Scale factor y. */
+ dk3_bif_coord_t maxwidth = 0L; /* Max width pixels. */
+ dk3_bif_coord_t maxheight = 0L; /* Max height pixels. */
+ dk3_bif_coord_t w; /* Current frame width. */
+ dk3_bif_coord_t h; /* Current frame height. */
+ size_t nFrames; /* Number of frames. */
+ size_t cf; /* Current frame. */
+ int me = 0; /* Math error. */
+ int workmode = 0; /* Transformation mode. */
+ int back = 1;
+ int must_rotate = 0; /* Flag: Must rotate. */
+#if DK3_USE_WX
+ int minpb; /* Original min progress bar value. */
+ int maxpb; /* Original max progress bar value. */
+#endif
+
+
+#line 2527 "dk3bm.ctr"
+#if DK3_USE_WX
+ minpb = job->minpb;
+ maxpb = job->maxpb;
+#endif
+ switch((job->opt)->szmode) {
+ case DK3_BMEPS_SIZE_1_1: {
+
+#line 2533 "dk3bm.ctr"
+ workmode = 0;
+ } break;
+ case DK3_BMEPS_SIZE_CHUNK: case DK3_BMEPS_SIZE_SPECIFIED: {
+ workmode = 1;
+
+#line 2537 "dk3bm.ctr"
+ } break;
+ case DK3_BMEPS_SIZE_PAPER: {
+
+#line 2539 "dk3bm.ctr"
+ workmode = 2;
+ if(!dk3bm_check_paper_size(&(((job->opt)->ima).ps))) {
+ back = 0;
+ /* ERROR: Incorrect paper size setup! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 62, DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ } break;
+ }
+ if(back) {
+ nFrames = dk3bif_number_of_frames(job->bif);
+ for(cf = 0; cf < nFrames; cf++) {
+ dk3bif_set_frame(job->bif, cf);
+ job->currentPage = cf + 1;
+ w = dk3bif_get_width(job->bif);
+ h = dk3bif_get_height(job->bif);
+ if(w > maxwidth) { maxwidth = w; }
+ if(h > maxheight) { maxheight = h; }
+ if(workmode == 1) {
+ switch((job->opt)->szmode) {
+ case DK3_BMEPS_SIZE_SPECIFIED: {
+
+#line 2561 "dk3bm.ctr"
+ xres = yres = (job->opt)->resolution;
+ } break;
+ default: {
+
+#line 2564 "dk3bm.ctr"
+ xres = dk3bif_get_xres(job->bif);
+ yres = dk3bif_get_yres(job->bif);
+ } break;
+ }
+ if(xres <= 0.0) { xres = 72.0; }
+ if(yres <= 0.0) { yres = 72.0; }
+ if(fabs(xres - 72.0) > dk3bm_epsilon) {
+ deltax = dk3ma_d_mul_ok(
+ 72.0,
+ dk3ma_d_div_ok(dk3bm_l_to_d(w), xres, &me),
+ &me
+ );
+ } else {
+ deltax = dk3bm_l_to_d(w);
+ }
+ if(fabs(yres - 72.0) > dk3bm_epsilon) {
+ deltay = dk3ma_d_mul_ok(
+ 72.0,
+ dk3ma_d_div_ok(dk3bm_l_to_d(h), yres, &me),
+ &me
+ );
+ } else {
+ deltay = dk3bm_l_to_d(h);
+ }
+ if(deltax > dmaxwidth) { dmaxwidth = deltax; }
+ if(deltay > dmaxheight) { dmaxheight = deltay; }
+ }
+ }
+ switch(workmode) {
+ case 0: {
+ job->x_size = maxwidth;
+ job->y_size = maxheight;
+ } break;
+ case 1: {
+ dmaxwidth = ceil(dmaxwidth);
+ dmaxheight = ceil(dmaxheight);
+ job->x_size = dk3ma_d_to_l_ok(dmaxwidth, &me);
+ job->y_size = dk3ma_d_to_l_ok(dmaxheight, &me);
+ } break;
+ case 2: {
+ job->x_size = dk3ma_d_to_l_ok(floor(((job->opt)->ima).ps.w), &me);
+ job->y_size = dk3ma_d_to_l_ok(floor(((job->opt)->ima).ps.h), &me);
+ } break;
+ }
+ /*
+ Produce output.
+ */
+ if(back) {
+ job->nPages = nFrames;
+ dk3bm_ps_document_header(job, job->nPages);
+ job->do_header_footer = 0;
+ for(cf = 0; cf < nFrames; cf++) {
+#if DK3_USE_WX
+ job->minpb = minpb + (int)cf * (maxpb - minpb) / (int)nFrames;
+ job->maxpb = minpb + (1 + (int)cf) * (maxpb - minpb) / (int)nFrames;
+ if(job->minpb < minpb) { job->minpb = minpb; }
+ if(job->maxpb > maxpb) { job->maxpb = maxpb; }
+#endif
+ dk3bif_set_frame(job->bif, cf);
+ w = dk3bif_get_width(job->bif);
+ h = dk3bif_get_height(job->bif);
+ job->currentPage = cf + 1;
+ job->x_translate = 0.0;
+ job->y_translate = 0.0;
+ job->x_0 = 0.0;
+ job->y_0 = 0.0;
+ job->x_1 = 0.0;
+ job->y_1 = 0.0;
+ job->x_scale = 1.0;
+ job->y_scale = 1.0;
+ job->do_translate = 0;
+ job->do_float_scale = 0;
+ job->do_rotate = 0;
+ must_rotate = 0;
+ switch(workmode) {
+ case 0: {
+ if(w < maxwidth) {
+ job->x_translate = 0.5 * dk3bm_l_to_d(maxwidth - w);
+ job->do_translate = 1;
+ }
+ if(h < maxheight) {
+ job->y_translate = 0.5 * dk3bm_l_to_d(maxheight - h);
+ job->do_translate = 1;
+ }
+ if(job->do_translate) {
+ job->x_scale = dk3bm_l_to_d(w);
+ job->y_scale = dk3bm_l_to_d(h);
+ job->do_float_scale = 1;
+ }
+ } break;
+ case 1: {
+ job->do_float_scale = 1;
+ job->do_translate = 1;
+ switch((job->opt)->szmode) {
+ case DK3_BMEPS_SIZE_SPECIFIED: {
+
+#line 2659 "dk3bm.ctr"
+ xres = yres = (job->opt)->resolution;
+ } break;
+ default: {
+
+#line 2662 "dk3bm.ctr"
+ xres = dk3bif_get_xres(job->bif);
+ yres = dk3bif_get_yres(job->bif);
+ } break;
+ }
+ if(xres <= 0.0) { xres = 72.0; }
+ if(yres <= 0.0) { yres = 72.0; }
+ if(fabs(xres - 72.0) > dk3bm_epsilon) {
+ deltax = dk3ma_d_mul_ok(
+ 72.0,
+ dk3ma_d_div_ok(dk3bm_l_to_d(w), xres, &me),
+ &me
+ );
+ } else {
+ deltax = dk3bm_l_to_d(w);
+ }
+ if(fabs(yres - 72.0) > dk3bm_epsilon) {
+ deltay = dk3ma_d_mul_ok(
+ 72.0,
+ dk3ma_d_div_ok(dk3bm_l_to_d(h), yres, &me),
+ &me
+ );
+ } else {
+ deltay = dk3bm_l_to_d(h);
+ }
+ job->x_scale = deltax;
+ job->y_scale = deltay;
+ job->x_translate = 0.5 * (dmaxwidth - deltax);
+ job->y_translate = 0.5 * (dmaxheight - deltay);
+ } break;
+ case 2: {
+ job->do_float_scale = 1;
+ job->do_translate = 1;
+ if((job->opt)->duplex) {
+ if((job->opt)->tumble) {
+ if((job->currentPage) % 2) {
+ job->y_0 = ((job->opt)->ima).ps.b;
+ job->y_1 = ((job->opt)->ima).ps.h - ((job->opt)->ima).ps.t;
+ } else {
+ job->y_0 = ((job->opt)->ima).ps.t;
+ job->y_1 = ((job->opt)->ima).ps.h - ((job->opt)->ima).ps.b;
+ }
+ job->x_0 = ((job->opt)->ima).ps.i;
+ job->x_1 = ((job->opt)->ima).ps.w - ((job->opt)->ima).ps.o;
+ } else {
+ if((job->currentPage) % 2) {
+ job->x_0 = ((job->opt)->ima).ps.i;
+ job->x_1 = ((job->opt)->ima).ps.w - ((job->opt)->ima).ps.o;
+ } else {
+ job->x_0 = ((job->opt)->ima).ps.o;
+ job->x_1 = ((job->opt)->ima).ps.w - ((job->opt)->ima).ps.i;
+ }
+ job->y_0 = ((job->opt)->ima).ps.b;
+ job->y_1 = ((job->opt)->ima).ps.h - ((job->opt)->ima).ps.t;
+ }
+ } else {
+ job->x_0 = ((job->opt)->ima).ps.i;
+ job->x_1 = ((job->opt)->ima).ps.w - ((job->opt)->ima).ps.o;
+ job->y_0 = ((job->opt)->ima).ps.b;
+ job->y_1 = ((job->opt)->ima).ps.h - ((job->opt)->ima).ps.t;
+ }
+ xres = dk3bif_get_xres(job->bif);
+ yres = dk3bif_get_yres(job->bif);
+ if(xres <= 0.0) xres = 72.0;
+ if(yres <= 0.0) yres = 72.0;
+ if(fabs(xres - 72.0) > dk3bm_epsilon) {
+ deltax = dk3ma_d_mul_ok(
+ 72.0,
+ dk3ma_d_div_ok(dk3bm_l_to_d(w), xres, &me),
+ &me
+ );
+ } else {
+ deltax = dk3bm_l_to_d(w);
+ }
+ if(fabs(yres - 72.0) > dk3bm_epsilon) {
+ deltay = dk3ma_d_mul_ok(
+ 72.0,
+ dk3ma_d_div_ok(dk3bm_l_to_d(h), yres, &me),
+ &me
+ );
+ } else {
+ deltay = dk3bm_l_to_d(h);
+ }
+ if((job->y_1 - job->y_0) > (job->x_1 - job->x_0)) {
+ if(deltax > deltay) {
+ must_rotate = 1;
+ }
+ } else {
+ if((job->y_1 - job->y_0) < (job->x_1 - job->x_0)) {
+ if(deltax > deltay) {
+ must_rotate = 1;
+ }
+ }
+ }
+ if(must_rotate) {
+ job->do_rotate = 1;
+ sx = dk3ma_d_div_ok((job->y_1 - job->y_0), deltax, &me);
+ sy = dk3ma_d_div_ok((job->x_1 - job->x_0), deltay, &me);
+ if(sx < sy) {
+ job->x_scale = job->y_1 - job->y_0;
+ job->y_scale = dk3ma_d_mul_ok(sx, deltay, &me);
+ job->x_translate = job->x_1 - 0.5 * (job->x_1 - job->x_0 - job->y_scale);
+ job->y_translate = job->y_0;
+ } else {
+ job->y_scale = job->x_1 - job->x_0;
+ job->x_scale = dk3ma_d_mul_ok(sy, deltax, &me);
+ job->x_translate = job->x_1;
+ job->y_translate = job->y_0 + 0.5 * (job->y_1 - job->y_0 - job->x_scale);
+ }
+ } else {
+ sx = dk3ma_d_div_ok((job->x_1 - job->x_0), deltax, &me);
+ sy = dk3ma_d_div_ok((job->y_1 - job->y_0), deltay, &me);
+ if(sx < sy) {
+ job->x_scale = job->x_1 - job->x_0;
+ job->y_scale = dk3ma_d_mul_ok(sx, deltay, &me);
+ job->x_translate = job->x_0;
+ job->y_translate = job->y_0 + 0.5 * (job->y_1 - job->y_0 - job->y_scale);
+ } else {
+ job->y_scale = job->y_1 - job->y_0;
+ job->x_scale = dk3ma_d_mul_ok(sy, deltax, &me);
+ job->y_translate = job->y_0;
+ job->x_translate = job->x_0 + 0.5 * (job->x_1 - job->x_0 - job->x_scale);
+ }
+ }
+
+
+#line 2786 "dk3bm.ctr"
+
+
+#line 2787 "dk3bm.ctr"
+
+
+#line 2788 "dk3bm.ctr"
+
+
+#line 2789 "dk3bm.ctr"
+
+
+#line 2790 "dk3bm.ctr"
+ } break;
+ }
+ /*
+ Output current frame.
+ */
+ if(back) {
+ if(!dk3bm_job_produce_img_job_real_ps(job)) {
+ back = 0;
+ }
+ }
+#if DK3_USE_WX
+ dk3bmj_progress(job->pComm, job->maxpb);
+#endif
+ }
+ dk3bm_ps_document_footer(job);
+ }
+ }
+#if DK3_USE_WX
+ job->minpb = minpb;
+ job->maxpb = maxpb;
+#endif
+
+
+#line 2812 "dk3bm.ctr"
+ return back;
+}
+
+
+
+/** Produce PS document.
+ @param job Conversion job.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bm_job_produce_doc_ps(dk3_bm_conversion_job_t *job)
+{
+ int back = 0;
+#if DK3_USE_WX
+ int min; /* Original min progress bar value. */
+ int max; /* Original max progress bar value. */
+#endif
+ /* PROGRESS: Reading image. */
+
+
+#line 2832 "dk3bm.ctr"
+ dk3app_log_1((job->opt)->app, DK3_LL_PROGRESS, job->msg, 47);
+#if DK3_USE_WX
+ min = job->minpb;
+ max = job->maxpb;
+#endif
+ if(dk3bif_read_data(job->bif)) {
+
+#line 2838 "dk3bm.ctr"
+#if DK3_USE_WX
+
+
+#line 2840 "dk3bm.ctr"
+ dk3bmj_progress(job->pComm, job->minpb + (job->maxpb - job->minpb)/3);
+ job->minpb = job->minpb + ((job->maxpb - job->minpb)/3);
+#endif
+ if(job->dfile) {
+ back = dk3bm_job_produce_doc_real_ps(job);
+ } else {
+ job->dfile = dk3sf_fopen_app(
+ job->dfn,
+ dk3app_not_localized(24),
+ (job->opt)->app
+ );
+ if(job->dfile) {
+ back = dk3bm_job_produce_doc_real_ps(job);
+ if(!dk3sf_fclose_fn_app(job->dfile, job->dfn, (job->opt)->app)) {
+ back = 0;
+ }
+ job->dfile = NULL;
+ } else {
+ /* ERROR: Failed to open output file! */
+ dk3bmj_log_i3(
+ (job->opt)->app, DK3_LL_ERROR, 77, 78, job->dfn, DK3_BMJ_LOG_JOB, job
+ );
+ }
+ }
+ } else {
+
+#line 2865 "dk3bm.ctr"
+ /* ERROR: Failed to read image data! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 61, DK3_BMJ_LOG_BOTH, job
+ );
+ }
+#if DK3_USE_WX
+ job->minpb = min;
+ job->maxpb = max;
+#endif
+
+
+#line 2875 "dk3bm.ctr"
+ return back;
+}
+
+
+
+/** Produce PS image or object.
+ @param job Conversion job.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bm_job_produce_img_obj_ps(dk3_bm_conversion_job_t *job)
+{
+ double w; /* Image width used. */
+ double h; /* Image height used. */
+ double xr = 0.0; /* X resolution. */
+ double yr = 0.0; /* Y resolution. */
+ int back = 1;
+ int ur = 0; /* Flag: Use resolution. */
+ int ec = 0; /* Math error code. */
+
+
+#line 2896 "dk3bm.ctr"
+ /*
+ Prepare for size 1:1.
+ */
+ job->x_size = dk3bif_get_width(job->bif);
+ job->y_size = dk3bif_get_height(job->bif);
+ job->x_1 = dk3bm_l_to_d(job->x_size);
+ job->y_1 = dk3bm_l_to_d(job->y_size);
+
+
+#line 2904 "dk3bm.ctr"
+ /*
+ Attempt to use other size/resolution if required.
+ */
+ switch((job->opt)->szmode) {
+ case DK3_BMEPS_SIZE_CHUNK: {
+
+#line 2909 "dk3bm.ctr"
+ xr = dk3bif_get_xres(job->bif);
+ yr = dk3bif_get_yres(job->bif);
+
+#line 2911 "dk3bm.ctr"
+ if((xr > 0.0) && (yr > 0.0)) {
+
+
+#line 2913 "dk3bm.ctr"
+ if(fabs(xr - 72.0) > dk3bm_epsilon) {
+ ur = 1;
+ }
+
+
+#line 2917 "dk3bm.ctr"
+ if(fabs(yr - 72.0) > dk3bm_epsilon) {
+ ur = 1;
+ }
+ }
+ } break;
+ case DK3_BMEPS_SIZE_SPECIFIED: {
+
+#line 2923 "dk3bm.ctr"
+ if((job->opt)->resolution > 0.0) {
+
+
+#line 2925 "dk3bm.ctr"
+ if(fabs((job->opt)->resolution - 72.0) > dk3bm_epsilon) {
+ xr = yr = (job->opt)->resolution;
+
+#line 2927 "dk3bm.ctr"
+ ur = 1;
+ }
+ }
+ } break;
+ }
+ /*
+ If we have to use a resolution, calculate dimensions.
+ */
+ if(ur) {
+
+#line 2936 "dk3bm.ctr"
+ w = dk3bm_l_to_d(job->x_size);
+
+#line 2937 "dk3bm.ctr"
+ h = dk3bm_l_to_d(job->y_size);
+
+#line 2938 "dk3bm.ctr"
+ w = dk3ma_d_mul_ok(72.0, dk3ma_d_div_ok(w, xr, &ec), &ec);
+ h = dk3ma_d_mul_ok(72.0, dk3ma_d_div_ok(h, yr, &ec), &ec);
+ job->x_1 = ceil(w);
+
+#line 2941 "dk3bm.ctr"
+ job->y_1 = ceil(h);
+ job->x_size = dk3ma_d_to_l_ok(job->x_1, &ec);
+ job->y_size = dk3ma_d_to_l_ok(job->y_1, &ec);
+
+
+#line 2945 "dk3bm.ctr"
+ job->x_translate = 0.5 * (job->x_1 - w);
+ job->y_translate = 0.5 * (job->y_1 - h);
+ if(job->x_translate < 0.0) { job->x_translate = 0.0; }
+ if(job->y_translate < 0.0) { job->y_translate = 0.0; }
+ job->do_translate = 1;
+ job->x_0 = job->x_translate;
+ job->y_0 = job->y_translate;
+ job->x_1 = job->x_0 + w;
+ job->y_1 = job->y_0 + h;
+ if(job->x_1 > dk3bm_l_to_d(job->x_size)) {
+ job->x_1 = dk3bm_l_to_d(job->x_size);
+ }
+ if(job->y_1 > dk3bm_l_to_d(job->y_size)) {
+ job->y_1 = dk3bm_l_to_d(job->y_size);
+ }
+ job->x_scale = w;
+ job->y_scale = h;
+ job->do_float_scale = 1;
+
+
+#line 2964 "dk3bm.ctr"
+
+
+#line 2965 "dk3bm.ctr"
+
+
+#line 2966 "dk3bm.ctr"
+
+
+#line 2967 "dk3bm.ctr"
+
+
+#line 2968 "dk3bm.ctr"
+
+
+#line 2969 "dk3bm.ctr"
+
+
+#line 2970 "dk3bm.ctr"
+
+
+#line 2971 "dk3bm.ctr"
+
+
+#line 2972 "dk3bm.ctr"
+
+
+#line 2973 "dk3bm.ctr"
+ if(ec) {
+
+#line 2974 "dk3bm.ctr"
+ back = 0;
+ dk3bmj_log_i1(
+ (job->opt)->app, DK3_LL_ERROR, 260, DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ }
+ /*
+ If no error yet, go on.
+ */
+ if(back) {
+ if((job->opt)->draft) {
+
+#line 2985 "dk3bm.ctr"
+ if(job->dfile) {
+
+#line 2986 "dk3bm.ctr"
+ back = dk3bm_job_produce_img_job_draft_ps(job);
+ } else {
+
+#line 2988 "dk3bm.ctr"
+ job->dfile = dk3sf_fopen_app(
+ job->dfn,
+ dk3app_not_localized(24),
+ (job->opt)->app
+ );
+ if(job->dfile) {
+
+#line 2994 "dk3bm.ctr"
+ back = dk3bm_job_produce_img_job_draft_ps(job);
+ if(!dk3sf_fclose_fn_app(job->dfile, job->dfn, (job->opt)->app)) {
+ back = 0;
+ }
+ job->dfile = NULL;
+ } else {
+
+#line 3000 "dk3bm.ctr"
+ back = 0;
+ /* ERROR: Failed to open output file! */
+ dk3bmj_log_i3(
+ (job->opt)->app, DK3_LL_ERROR, 77, 78, job->dfn,
+ DK3_BMJ_LOG_JOB, job
+ );
+ }
+ }
+ } else {
+
+#line 3009 "dk3bm.ctr"
+ /* PROGRESS: Reading image. */
+ dk3app_log_1((job->opt)->app, DK3_LL_PROGRESS, job->msg, 47);
+ if(dk3bif_read_data(job->bif)) {
+
+#line 3012 "dk3bm.ctr"
+#if DK3_USE_WX
+
+
+#line 3014 "dk3bm.ctr"
+ dk3bmj_progress(job->pComm, job->minpb + (job->maxpb - job->minpb)/3);
+ job->minpb = job->minpb + ((job->maxpb - job->minpb)/3);
+#endif
+ if(job->dfile) {
+
+#line 3018 "dk3bm.ctr"
+ back = dk3bm_job_produce_img_job_real_ps(job);
+ } else {
+
+#line 3020 "dk3bm.ctr"
+ job->dfile = dk3sf_fopen_app(
+ job->dfn,
+ dk3app_not_localized(24),
+ (job->opt)->app
+ );
+ if(job->dfile) {
+
+#line 3026 "dk3bm.ctr"
+ back = dk3bm_job_produce_img_job_real_ps(job);
+ if(!dk3sf_fclose_fn_app(job->dfile, job->dfn, (job->opt)->app)) {
+ back = 0;
+ }
+ job->dfile = NULL;
+ } else {
+
+#line 3032 "dk3bm.ctr"
+ back = 0;
+ /* ERROR: Failed to open output file! */
+ dk3bmj_log_i3(
+ (job->opt)->app, DK3_LL_ERROR, 77, 78, job->dfn,
+ DK3_BMJ_LOG_JOB, job
+ );
+ }
+ }
+ } else {
+
+#line 3041 "dk3bm.ctr"
+ back = 0;
+ /* ERROR: Failed to read image data! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 61, DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ }
+ }
+
+#line 3049 "dk3bm.ctr"
+ return back;
+}
+
+
+
+/** Produce PS/EPS output.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bm_job_produce_ps(dk3_bm_conversion_job_t *job)
+{
+ int back = 0;
+
+
+#line 3064 "dk3bm.ctr"
+ switch((job->opt)->mode) {
+ case DK3_BMEPS_MODE_DOCUMENT: {
+
+#line 3066 "dk3bm.ctr"
+ back = dk3bm_job_produce_doc_ps(job);
+ } break;
+ default: {
+
+#line 3069 "dk3bm.ctr"
+ back = dk3bm_job_produce_img_obj_ps(job);
+ } break;
+ }
+
+#line 3072 "dk3bm.ctr"
+ return back;
+}
+
+
+
+/** Add one image frame as output page.
+ @param job Conversion job.
+ @param pageno Page number of frame to add.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bm_job_add_pdf_frame(dk3_bm_conversion_job_t *job, size_t pageno)
+{
+ dk3_bif_coord_t w; /* Image width. */
+ dk3_bif_coord_t h; /* Image height. */
+ double xres = 0.0; /* X resolution. */
+ double yres = 0.0; /* Y resolution. */
+ double dw; /* Image width on paper. */
+ double dh; /* Image height on paper. */
+ double px0; /* Left x (paper). */
+ double px1; /* Right x (paper). */
+ double py0; /* Lower y (paper). */
+ double py1; /* Upper y (paper). */
+ double width; /* Paper width. */
+ double height; /* Paper height. */
+ double sx; /* Scale factor for x direction. */
+ double sy; /* Scale factor for y direction. */
+ long mbx0; /* Left x (media box). */
+ long mbx1; /* Right x (media box). */
+ long mby0; /* Lower y (media box). */
+ long mby1; /* Upper y (media box). */
+ int workmode; /* Transformation mode. */
+ int back = 1;
+ int me = 0; /* Flag: Math error. */
+
+
+#line 3108 "dk3bm.ctr"
+ /*
+ Re-initialize (we probably have to handle multiple frames in one job.
+ */
+ job->x_translate = 0.0;
+ job->y_translate = 0.0;
+ job->x_scale = 1.0;
+ job->y_scale = 1.0;
+ job->x_0 = 0.0;
+ job->x_1 = 0.0;
+ job->y_0 = 0.0;
+ job->y_1 = 0.0;
+ job->x_size = 0L;
+ job->y_size = 0L;
+ job->bpc = 8;
+ job->do_translate = 0;
+ job->do_rotate = 0;
+ job->do_float_scale = 0;
+ job->procedure = 0;
+ workmode = 0;
+ mbx0 = mbx1 = mby0 = mby1 = 0L;
+ /*
+ Process image width, height and resolution.
+ */
+ w = dk3bif_get_width(job->bif);
+ h = dk3bif_get_height(job->bif);
+ switch((job->opt)->szmode) {
+ case DK3_BMEPS_SIZE_CHUNK: {
+
+#line 3135 "dk3bm.ctr"
+ xres = dk3bif_get_xres(job->bif);
+ yres = dk3bif_get_yres(job->bif);
+ if(xres > 0.0) {
+ if(yres > 0.0) {
+ if((fabs(xres - 72.0) > dk3bm_epsilon)
+ || (fabs(yres - 72.0) > dk3bm_epsilon))
+ {
+ workmode = 1;
+ }
+ }
+ }
+ } break;
+ case DK3_BMEPS_SIZE_SPECIFIED: {
+
+#line 3148 "dk3bm.ctr"
+ xres = yres = (job->opt)->resolution;
+ if(xres > 0.0) {
+ if(fabs(xres - 72.0) > dk3bm_epsilon) {
+ workmode = 1;
+ }
+ }
+ } break;
+ case DK3_BMEPS_SIZE_PAPER: {
+
+#line 3156 "dk3bm.ctr"
+ workmode = 2;
+ xres = dk3bif_get_xres(job->bif);
+ yres = dk3bif_get_yres(job->bif);
+ if(xres <= 0.0) { xres = 72.0; }
+ if(yres <= 0.0) { yres = 72.0; }
+ if(fabs(xres - 72.0) <= dk3bm_epsilon) {
+ xres = 72.0;
+ }
+ if(fabs(yres - 72.0) <= dk3bm_epsilon) {
+ yres = 72.0;
+ }
+ } break;
+ default: {
+
+#line 3169 "dk3bm.ctr"
+ workmode = 0;
+ } break;
+ }
+ switch(workmode) {
+ case 2: {
+ dw = dk3ma_d_mul_ok(
+ 72.0,
+ dk3ma_d_div_ok(dk3bm_l_to_d(w), xres, &me),
+ &me
+ );
+ dh = dk3ma_d_mul_ok(
+ 72.0,
+ dk3ma_d_div_ok(dk3bm_l_to_d(h), yres, &me),
+ &me
+ );
+
+#line 3184 "dk3bm.ctr"
+ if(dk3bm_check_paper_size(&(((job->opt)->ima).ps))) {
+ width = floor(((job->opt)->ima).ps.w);
+ height = floor(((job->opt)->ima).ps.h);
+
+
+#line 3188 "dk3bm.ctr"
+
+
+#line 3189 "dk3bm.ctr"
+ mbx1 = dk3ma_d_to_l_ok(width, &me);
+ mby1 = dk3ma_d_to_l_ok(height, &me);
+ if((job->opt)->duplex) {
+ if((job->opt)->tumble) {
+ if(pageno % 2) { /* Rueckseite */
+ px0 = ((job->opt)->ima).ps.i;
+ px1 = width - ((job->opt)->ima).ps.o;
+ py0 = ((job->opt)->ima).ps.t;
+ py1 = height - ((job->opt)->ima).ps.b;
+ } else { /* Vorderseite */
+ px0 = ((job->opt)->ima).ps.i;
+ px1 = width - ((job->opt)->ima).ps.o;
+ py0 = ((job->opt)->ima).ps.b;
+ py1 = height - ((job->opt)->ima).ps.t;
+ }
+ } else {
+ if(pageno % 2) { /* Rueckseite */
+ px0 = ((job->opt)->ima).ps.o;
+ px1 = width - ((job->opt)->ima).ps.i;
+ py0 = ((job->opt)->ima).ps.b;
+ py1 = height - ((job->opt)->ima).ps.t;
+ } else { /* Vorderseite */
+ px0 = ((job->opt)->ima).ps.i;
+ px1 = width - ((job->opt)->ima).ps.o;
+ py0 = ((job->opt)->ima).ps.b;
+ py1 = height - ((job->opt)->ima).ps.t;
+ }
+ }
+ } else {
+ px0 = ((job->opt)->ima).ps.i;
+ px1 = width - ((job->opt)->ima).ps.o;
+ py0 = ((job->opt)->ima).ps.b;
+ py1 = height - ((job->opt)->ima).ps.t;
+ }
+ if((px1 > px0) && (py1 > py0)) {
+ if((py1 - py0) > (px1 - px0)) {
+
+#line 3225 "dk3bm.ctr"
+ if(dw > dh) {
+
+#line 3226 "dk3bm.ctr"
+ job->do_rotate = 1;
+ } else {
+
+#line 3228 "dk3bm.ctr"
+ }
+ } else {
+
+#line 3230 "dk3bm.ctr"
+ if((py1 - py0) < (px1 - px0)) {
+
+#line 3231 "dk3bm.ctr"
+ if(dh > dw) {
+
+#line 3232 "dk3bm.ctr"
+ job->do_rotate = 1;
+ } else {
+ }
+ }
+ }
+
+
+#line 3238 "dk3bm.ctr"
+
+
+#line 3239 "dk3bm.ctr"
+
+
+#line 3240 "dk3bm.ctr"
+
+
+#line 3241 "dk3bm.ctr"
+ if(job->do_rotate) {
+
+#line 3242 "dk3bm.ctr"
+ sx = dk3ma_d_div_ok((py1 - py0), dw, &me);
+ sy = dk3ma_d_div_ok((px1 - px0), dh, &me);
+ if(sx > sy) {
+
+#line 3245 "dk3bm.ctr"
+ job->y_scale = (px1 - px0);
+ job->x_scale = sy * dw;
+ job->x_translate = px1;
+ job->y_translate = py0 + 0.5 * (py1 - py0 - job->x_scale);
+ if(job->y_translate < py0) { job->y_translate = py0; }
+ } else {
+
+#line 3251 "dk3bm.ctr"
+ job->x_scale = (py1 - py0);
+ job->y_scale = sx * dh;
+ job->x_translate = px1 - 0.5 * (px1 - px0 - job->y_scale);
+ if(job->x_translate > px1) { job->x_translate = px1; }
+ job->y_translate = py0;
+ }
+ } else {
+
+#line 3258 "dk3bm.ctr"
+ sx = dk3ma_d_div_ok((px1 - px0), dw, &me);
+ sy = dk3ma_d_div_ok((py1 - py0), dh, &me);
+ if(sx > sy) {
+
+#line 3261 "dk3bm.ctr"
+ job->y_scale = py1 - py0;
+ job->x_scale = sy * dw;
+ job->x_translate = px0 + 0.5 * (px1 - px0 - job->x_scale);
+ if(job->x_translate < px0) { job->x_translate = px0; }
+ job->y_translate = py0;
+ } else {
+
+#line 3267 "dk3bm.ctr"
+ job->x_scale = px1 - px0;
+ job->y_scale = sx * dh;
+ job->y_translate = py0 + 0.5 * (py1 - py0 - job->y_scale);
+ if(job->y_translate < py0) { job->y_translate = py0; }
+ job->x_translate = px0;
+ }
+ }
+ job->do_translate = 1;
+ job->do_float_scale = 1;
+ } else {
+
+#line 3277 "dk3bm.ctr"
+ back = 0;
+ /* ERROR Page setup incorrect */
+ dk3bmj_log_i1(
+ (job->opt)->app, DK3_LL_ERROR, 259,
+ DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ } else {
+ back = 0;
+ }
+
+
+#line 3288 "dk3bm.ctr"
+
+
+#line 3289 "dk3bm.ctr"
+
+
+#line 3290 "dk3bm.ctr"
+
+
+#line 3291 "dk3bm.ctr"
+
+
+#line 3292 "dk3bm.ctr"
+ } break;
+ case 1: {
+ dw = dk3ma_d_mul_ok(
+ 72.0,
+ dk3ma_d_div_ok(dk3bm_l_to_d(w), xres, &me),
+ &me
+ );
+ dh = dk3ma_d_mul_ok(
+ 72.0,
+ dk3ma_d_div_ok(dk3bm_l_to_d(h), yres, &me),
+ &me
+ );
+ job->x_scale = dw;
+ job->y_scale = dh;
+ job->x_size = dk3ma_d_to_l_ok(ceil(dw), &me);
+ job->y_size = dk3ma_d_to_l_ok(ceil(dh), &me);
+ job->do_float_scale = 1;
+ job->x_translate = 0.5 * dk3ma_d_sub_ok(job->x_size, dw, &me);
+ job->y_translate = 0.5 * dk3ma_d_sub_ok(job->y_size, dh, &me);
+ if(job->x_translate < 0.0) { job->x_translate = 0.0; }
+ if(job->y_translate < 0.0) { job->y_translate = 0.0; }
+ job->do_translate = 1;
+ mbx1 = dk3ma_d_to_l_ok(job->x_size, &me);
+ mby1 = dk3ma_d_to_l_ok(job->y_size, &me);
+ } break;
+ default: {
+
+#line 3318 "dk3bm.ctr"
+ mbx0 = 0L; mby0 = 0L; mbx1 = w; mby1 = h;
+ job->x_size = w; job->y_size = h;
+ } break;
+ }
+ dk3pdf_set_next_mediabox(job->pdf, mbx0, mbx1, mby0, mby1);
+ if(me) {
+
+#line 3324 "dk3bm.ctr"
+ back = 0;
+ }
+ if(back == 1) {
+
+#line 3327 "dk3bm.ctr"
+ if(dk3pdf_open_page(job->pdf)) {
+
+#line 3328 "dk3bm.ctr"
+ if(job->do_translate) {
+ dk3pdf_translate_double(job->pdf, job->x_translate, job->y_translate);
+ }
+ if(job->do_rotate) {
+ dk3pdf_rotate_int(job->pdf, 90);
+ }
+ if(job->do_float_scale) {
+ dk3pdf_scale_double(job->pdf, job->x_scale, job->y_scale);
+ } else {
+ dk3pdf_scale_long(job->pdf, mbx1, mby1);
+ }
+ if(dk3pdf_add_image_progress(
+ job->pdf, job->bif, job->opt, job->pComm, job->minpb, job->maxpb
+ )
+ )
+ {
+ back = 1;
+
+#line 3345 "dk3bm.ctr"
+ } else {
+ back = 0;
+
+#line 3347 "dk3bm.ctr"
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 73,
+ DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ dk3pdf_close_page(job->pdf);
+ } else {
+
+#line 3354 "dk3bm.ctr"
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 71,
+ DK3_BMJ_LOG_JOB, job
+ );
+ }
+ } else {
+ back = 0;
+ /* ERROR: Math error! */
+ dk3bmj_log_i1(
+ (job->opt)->app, DK3_LL_ERROR, 260,
+ DK3_BMJ_LOG_BOTH, job
+ );
+ }
+
+#line 3367 "dk3bm.ctr"
+ return back;
+}
+
+
+
+/** Produce PDF output.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bm_job_produce_file_pdf(dk3_bm_conversion_job_t *job)
+{
+ size_t nFrames; /* Number of frames. */
+ size_t i; /* Current frame index. */
+ int back = 0;
+#if DK3_USE_WX
+ int min; /* Original min progress bar value. */
+ int max; /* Original max progress bar value. */
+ int xmax; /* Intermediate progress bar value. */
+#endif
+
+
+#line 3389 "dk3bm.ctr"
+#if DK3_USE_WX
+ min = job->minpb;
+ max = job->maxpb;
+ job->maxpb = xmax = min + ((14 * (max - min)) / 15);
+#endif
+ job->pdf = dk3pdf_open_app((job->opt)->app);
+ if(job->pdf) {
+ back = 1;
+
+
+#line 3398 "dk3bm.ctr"
+ switch((job->opt)->mode) {
+ case DK3_BMEPS_MODE_DOCUMENT: {
+
+#line 3400 "dk3bm.ctr"
+ nFrames = dk3bif_number_of_frames(job->bif);
+ for(i = 0; i < nFrames; i++) {
+#if DK3_USE_WX
+ job->minpb = min + ((((int)i) * (xmax - min)) / (int)nFrames);
+ job->maxpb = min + (((((int)i) + 1) * (xmax - min)) / (int)nFrames);
+#endif
+ if(dk3bif_set_frame(job->bif, i)) {
+ if(!dk3bm_job_add_pdf_frame(job, i)) {
+ back = 0;
+ }
+ } else {
+ back = 0;
+ /* ERROR: Failed to set frame! */
+ dk3bmj_log_i1(
+ (job->opt)->app, DK3_LL_ERROR, 261, DK3_BMJ_LOG_BOTH, job
+ );
+ }
+#if DK3_USE_WX
+
+
+#line 3419 "dk3bm.ctr"
+ dk3bmj_progress(job->pComm, job->maxpb);
+#endif
+ }
+ } break;
+ default: {
+
+#line 3424 "dk3bm.ctr"
+ if(!dk3bm_job_add_pdf_frame(job, 0)) {
+ back = 0;
+ }
+ } break;
+ }
+#if DK3_USE_WX
+
+
+#line 3431 "dk3bm.ctr"
+ dk3bmj_progress(job->pComm, job->maxpb);
+ job->minpb = job->maxpb;
+ job->maxpb = max;
+#endif
+ if(!dk3pdf_write_file_progress(
+ job->pdf, job->dfile, job->pComm, job->minpb, job->maxpb)
+ )
+ {
+ back = 0;
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 72,
+ DK3_BMJ_LOG_JOB, job
+ );
+ }
+ dk3pdf_close(job->pdf); job->pdf = NULL;
+ } else {
+ /* ERROR: Failed to create PDF job! */
+ dk3bmj_log_i1(
+ (job->opt)->app, DK3_LL_ERROR, 9,
+ DK3_BMJ_LOG_JOB, job
+ );
+ }
+#if DK3_USE_WX
+ job->minpb = min;
+ job->maxpb = max;
+#endif
+
+
+#line 3458 "dk3bm.ctr"
+ return back;
+}
+
+
+
+/** Produce draft PDF output.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bm_job_draft_pdf(dk3_bm_conversion_job_t *job)
+{
+ dk3_pdf_t *pdf; /* PDF writer structure. */
+ double x0; /* Left border. */
+ double x1; /* Right border. */
+ double y0; /* Lower border. */
+ double y1; /* Upper border. */
+ double xres = -1.0; /* X resolution. */
+ double yres = -1.0; /* Y resolution. */
+ double w; /* Width, using resolution. */
+ double h; /* Height, using resolution. */
+ double dx; /* X delta. */
+ double dy; /* Y delta. */
+ long mbx0; /* Media box x0. */
+ long mbx1; /* Media box x1. */
+ long mby0; /* Media box y0. */
+ long mby1; /* Media box y1. */
+ int me = 0; /* Flag: Math error. */
+ int workmode = 0; /* Work mode. */
+ int do_rotate = 0; /* Flag: Rotate. */
+ int back = 1;
+
+
+#line 3491 "dk3bm.ctr"
+ mbx0 = mby0 = 0L;
+ mbx1 = dk3bif_get_width(job->bif);
+ mby1 = dk3bif_get_height(job->bif);
+ x0 = 0.0;
+ y0 = 0.0;
+ x1 = dk3bm_l_to_d(mbx1);
+ y1 = dk3bm_l_to_d(mby1);
+ switch((job->opt)->szmode) {
+ case DK3_BMEPS_SIZE_CHUNK: {
+
+#line 3500 "dk3bm.ctr"
+ xres = dk3bif_get_xres(job->bif);
+ yres = dk3bif_get_yres(job->bif);
+ if((xres > 0.0) || (yres > 0.0)) {
+ if(xres <= 0.0) { xres = 72.0; }
+ if(yres <= 0.0) { yres = 72.0; }
+ if(fabs(xres - 72.0) > dk3bm_epsilon) {
+ workmode = 1;
+ }
+ if(fabs(yres - 72.0) > dk3bm_epsilon) {
+ workmode = 1;
+ }
+ }
+ } break;
+ case DK3_BMEPS_SIZE_SPECIFIED: {
+
+#line 3514 "dk3bm.ctr"
+ xres = yres = (job->opt)->resolution;
+ if(xres > 0.0) {
+ if(fabs(xres - 72.0) > dk3bm_epsilon) {
+ workmode = 1;
+ }
+ }
+ } break;
+ case DK3_BMEPS_SIZE_PAPER: {
+
+#line 3522 "dk3bm.ctr"
+ workmode = 2;
+ xres = dk3bif_get_xres(job->bif);
+ yres = dk3bif_get_yres(job->bif);
+ if(xres <= 0.0) { xres = 72.0; }
+ if(yres <= 0.0) { yres = 72.0; }
+ if(fabs(xres - 72.0) <= dk3bm_epsilon) { xres = 72.0; }
+ if(fabs(yres - 72.0) <= dk3bm_epsilon) { yres = 72.0; }
+ } break;
+ }
+ switch(workmode) {
+ case 2: { /* Fit to page */
+ w = dk3ma_d_div_ok(dk3bm_l_to_d(mbx1), xres, &me);
+
+#line 3534 "dk3bm.ctr"
+ h = dk3ma_d_div_ok(dk3bm_l_to_d(mby1), yres, &me);
+
+#line 3535 "dk3bm.ctr"
+ mbx1 = dk3ma_d_to_l_ok(floor(((job->opt)->ima).ps.w), &me);
+ mby1 = dk3ma_d_to_l_ok(floor(((job->opt)->ima).ps.h), &me);
+
+
+#line 3538 "dk3bm.ctr"
+ x0 = ((job->opt)->ima).ps.i;
+ y0 = ((job->opt)->ima).ps.b;
+ x1 = dk3ma_d_sub_ok(((job->opt)->ima).ps.w, ((job->opt)->ima).ps.o, &me);
+ y1 = dk3ma_d_sub_ok(((job->opt)->ima).ps.h, ((job->opt)->ima).ps.t, &me);
+
+
+#line 3543 "dk3bm.ctr"
+ if((x1 > x0) && (y1 > y0)) {
+
+#line 3544 "dk3bm.ctr"
+ if((x1 - x0) > (y1 - y0)) {
+ if(h > w) {
+
+#line 3546 "dk3bm.ctr"
+ do_rotate = 1;
+ }
+ } else {
+ if((x1 - x0) < (y1 - y0)) {
+ if(h < w) {
+
+#line 3551 "dk3bm.ctr"
+ do_rotate = 1;
+ }
+ }
+ }
+ if(do_rotate) {
+
+#line 3556 "dk3bm.ctr"
+ dx = dk3ma_d_div_ok((x1 - x0), h, &me);
+ dy = dk3ma_d_div_ok((y1 - y0), w, &me);
+ if(dx > dy) {
+ w = dk3ma_d_mul_ok(dy, h, &me);
+ dx = dk3ma_d_add_ok(
+ x0,
+ 0.5 * dk3ma_d_sub_ok((x1 - x0), w, &me),
+ &me
+ );
+ dy = dk3ma_d_add_ok(dx, w, &me);
+ if(dx >= x0) { x0 = dx; }
+ if(dy <= x1) { x1 = dy; }
+ } else {
+ h = dk3ma_d_mul_ok(dx, w, &me);
+ dx = dk3ma_d_add_ok(
+ y0,
+ 0.5 * dk3ma_d_sub_ok((y1 - y0), h, &me),
+ &me
+ );
+ dy = dk3ma_d_add_ok(dx, h, &me);
+ if(dx >= y0) { y0 = dx; }
+ if(dy <= y1) { y1 = dy; }
+ }
+ } else {
+
+#line 3580 "dk3bm.ctr"
+ dx = dk3ma_d_div_ok((x1 - x0), w, &me);
+ dy = dk3ma_d_div_ok((y1 - y0), h, &me);
+ if(dx > dy) {
+
+#line 3583 "dk3bm.ctr"
+ w = dk3ma_d_mul_ok(dy, w, &me);
+ dx = dk3ma_d_add_ok(
+ x0,
+ 0.5 * dk3ma_d_sub_ok((x1 - x0), w, &me),
+ &me
+ );
+ dy = dk3ma_d_add_ok(dx, w, &me);
+ if(dx >= x0) { x0 = dx; }
+ if(dy <= x1) { x1 = dy; }
+ } else {
+
+#line 3593 "dk3bm.ctr"
+ h = dk3ma_d_mul_ok(dx, h, &me);
+ dx = dk3ma_d_add_ok(
+ y0,
+ 0.5 * dk3ma_d_sub_ok((y1 - y0), h, &me),
+ &me
+ );
+ dy = dk3ma_d_add_ok(dx, h, &me);
+ if(dx >= y0) { y0 = dx; }
+ if(dy <= y1) { y1 = dy; }
+ }
+ }
+
+#line 3604 "dk3bm.ctr"
+ } else {
+ back = 0;
+ /* ERROR: Incorrect page setup. */
+ dk3bmj_log_i1(
+ (job->opt)->app, DK3_LL_ERROR, 259, DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ } break;
+ case 1: { /* Use resolution */
+ w = dk3ma_d_div_ok(dk3bm_l_to_d(mbx1), xres, &me);
+ h = dk3ma_d_div_ok(dk3bm_l_to_d(mby1), yres, &me);
+ w = dk3ma_d_mul_ok(72.0, w, &me);
+ h = dk3ma_d_mul_ok(72.0, h, &me);
+ x1 = ceil(w);
+ y1 = ceil(h);
+ mbx1 = dk3ma_d_to_l_ok(x1, &me);
+ mby1 = dk3ma_d_to_l_ok(y1, &me);
+ x0 = 0.5 * dk3ma_d_sub_ok(x1, w, &me);
+ y0 = 0.5 * dk3ma_d_sub_ok(y1, h, &me);
+ x1 = dk3ma_d_add_ok(x0, w, &me);
+ y1 = dk3ma_d_add_ok(y0, h, &me);
+ if(x0 < 0.0) { x0 = 0.0; }
+ if(y0 < 0.0) { y0 = 0.0; }
+ if(x1 > dk3bm_l_to_d(mbx1)) { x1 = dk3bm_l_to_d(mbx1); }
+ if(y1 > dk3bm_l_to_d(mby1)) { y1 = dk3bm_l_to_d(mby1); }
+ } break;
+ default: { /* 1:1 */
+ /* Nothing to do, everything is initialized. */
+ } break;
+ }
+ if(me) {
+ back = 0;
+ /* ERROR: Math error occured! */
+ dk3bmj_log_i1(
+ (job->opt)->app, DK3_LL_ERROR, 260, DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ if(back) {
+ back = 0;
+ /* Here we have all information prepared to produce the draft. */
+ pdf = dk3pdf_open_app((job->opt)->app);
+ if(pdf) {
+ dk3pdf_set_next_mediabox(pdf, mbx0, mbx1, mby0, mby1);
+ if(dk3pdf_open_page(pdf)) {
+ back = 1;
+ dx = 0.01 * (x1 - x0);
+ dy = 0.01 * (y1 - y0);
+ if(dy < dx) dx = dy;
+ if(dx > 2.8) dx = 2.8;
+ dk3pdf_set_nonstroking_gray(pdf, 0.0);
+ dk3pdf_newpath_moveto(pdf, x0, y0);
+ dk3pdf_lineto(pdf, x1, y0);
+ dk3pdf_lineto(pdf, x1, y1);
+ dk3pdf_lineto(pdf, x0, y1);
+ dk3pdf_closepath(pdf);
+ dk3pdf_fill_nz(pdf);
+ dk3pdf_set_nonstroking_gray(pdf, 0.8);
+ dk3pdf_newpath_moveto(pdf, (x0 + dx), (y0 + dx));
+ dk3pdf_lineto(pdf, (x1 - dx), (y0 + dx));
+ dk3pdf_lineto(pdf, (x1 - dx), (y1 - dx));
+ dk3pdf_lineto(pdf, (x0 + dx), (y1 - dx));
+ dk3pdf_closepath(pdf);
+ dk3pdf_fill_nz(pdf);
+ dk3pdf_set_nonstroking_gray(pdf, 1.0);
+#if VERSION_BEFORE_20150821
+ dy = dx;
+#endif
+ dx = 10.0 * dx;
+ dk3pdf_newpath_moveto(pdf, (x0 + dx), (y0 + dx));
+ dk3pdf_lineto(pdf, (x1 - dx), (y0 + dx));
+ dk3pdf_lineto(pdf, (x1 - dx), (y1 - dx));
+ dk3pdf_lineto(pdf, (x0 + dx), (y1 - dx));
+ dk3pdf_closepath(pdf);
+ dk3pdf_fill_nz(pdf);
+ dk3pdf_set_linewidth(pdf, dx);
+ dk3pdf_set_linecap(pdf, DK3_LINECAP_ROUND);
+ dk3pdf_set_stroking_gray(pdf, 0.8);
+ dk3pdf_newpath_moveto(pdf, (x0 + dx), (y0 + dx));
+ dk3pdf_lineto(pdf, (x1 - dx), (y1 - dx));
+ dk3pdf_stroke(pdf);
+ dk3pdf_newpath_moveto(pdf, (x0 + dx), (y1 - dx));
+ dk3pdf_lineto(pdf, (x1 - dx), (y0 + dx));
+ dk3pdf_stroke(pdf);
+ dk3pdf_close_page(pdf);
+ } else {
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 71,
+ DK3_BMJ_LOG_JOB, job
+ );
+ }
+ dk3pdf_write_file(pdf, job->dfile);
+ dk3pdf_close(pdf);
+ } else {
+ /* ERROR: Failed to create PDF writer */
+ dk3bmj_log_i1(
+ (job->opt)->app, DK3_LL_ERROR, 9,
+ DK3_BMJ_LOG_JOB, job
+ );
+ }
+ }
+
+
+#line 3705 "dk3bm.ctr"
+ return back;
+}
+
+
+
+/** Produce PDF output.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bm_job_produce_pdf(dk3_bm_conversion_job_t *job)
+{
+ int back = 0;
+#if DK3_USE_WX
+ int min; /* Original min progress bar value. */
+ int max; /* Original max progress bar value. */
+#endif
+
+
+#line 3724 "dk3bm.ctr"
+#if DK3_USE_WX
+ min = job->minpb;
+ max = job->maxpb;
+ job->minpb = min + ((max - min) / 4);
+#endif
+ if((job->opt)->draft) {
+ if(job->dfile) {
+ back = dk3bm_job_draft_pdf(job);
+ } else {
+ job->dfile = dk3sf_fopen_app(
+ job->dfn,
+ dk3app_not_localized(53),
+ (job->opt)->app
+ );
+ if(job->dfile) {
+ back = dk3bm_job_draft_pdf(job);
+ if(!dk3sf_fclose_fn_app(job->dfile, job->dfn, (job->opt)->app)) {
+ back = 0;
+ }
+ job->dfile = NULL;
+ } else {
+ /* ERROR: Failed to open output file! */
+ dk3bmj_log_i3(
+ (job->opt)->app, DK3_LL_ERROR, 77, 78, job->dfn,
+ DK3_BMJ_LOG_JOB, job
+ );
+ }
+ }
+ } else {
+ if(dk3bif_read_data(job->bif)) {
+#if DK3_USE_WX
+ if((job->pComm) && (job->maxpb > job->minpb)) {
+
+
+#line 3757 "dk3bm.ctr"
+ dk3bmj_progress(job->pComm, job->minpb);
+ }
+#endif
+ if(job->dfile) {
+ back = dk3bm_job_produce_file_pdf(job);
+ } else {
+ job->dfile = dk3sf_fopen_app(
+ job->dfn,
+ dk3app_not_localized(53),
+ (job->opt)->app
+ );
+ if(job->dfile) {
+ back = dk3bm_job_produce_file_pdf(job);
+ if(!dk3sf_fclose_fn_app(job->dfile, job->dfn, (job->opt)->app)) {
+ back = 0;
+ }
+ job->dfile = NULL;
+ } else {
+ /* ERROR: Failed to open output file! */
+ dk3bmj_log_i3(
+ (job->opt)->app, DK3_LL_ERROR, 77, 78, job->dfn,
+ DK3_BMJ_LOG_JOB, job
+ );
+ }
+ }
+ } else {
+ /* ERROR: Failed to read image data! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 61, DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ }
+#if DK3_USE_WX
+ job->minpb = min;
+ job->maxpb = max;
+#endif
+
+
+#line 3794 "dk3bm.ctr"
+ return back;
+}
+
+
+
+/** Produce bounding box output.
+ @param job Job structure.
+*/
+static
+void
+dk3bm_produce_bb(dk3_bm_conversion_job_t *job)
+{
+ dk3_bif_coord_t w; /* Image width. */
+ dk3_bif_coord_t h; /* Image height. */
+
+
+#line 3809 "dk3bm.ctr"
+ w = dk3bif_get_width(job->bif);
+ h = dk3bif_get_height(job->bif);
+ fprintf(job->dfile, dk3bm_c8_kw[31], w, h);
+
+
+#line 3813 "dk3bm.ctr"
+}
+
+
+
+/** Produce bounding box output.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bm_job_produce_bb(dk3_bm_conversion_job_t *job)
+{
+ int back = 0;
+ if(job->dfile) {
+ dk3bm_produce_bb(job);
+ back = 1;
+ } else {
+ job->dfile = dk3sf_fopen_app(
+ job->dfn,
+ dk3app_not_localized(24),
+ (job->opt)->app
+ );
+ if(job->dfile) {
+ dk3bm_produce_bb(job);
+ back = 1;
+ if(!dk3sf_fclose_fn_app(job->dfile, job->dfn, (job->opt)->app)) {
+ back = 0;
+ }
+ job->dfile = NULL;
+ } else {
+ dk3bmj_log_i3(
+ (job->opt)->app, DK3_LL_ERROR, 77, 78, job->dfn,
+ DK3_BMJ_LOG_JOB, job
+ );
+ }
+ }
+ return back;
+}
+
+
+
+/** Run a conversion job for either the opened file or the named file.
+ @param job Conversion job.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bm_job_from_program_with_output(dk3_bm_conversion_job_t *job)
+{
+ int back = 0;
+
+
+#line 3864 "dk3bm.ctr"
+ job->bif = dk3bif_open_filename_app(job->sfn, job->biftype, (job->opt)->app);
+ if(job->bif) {
+ switch((job->opt)->dr) {
+ case DK3_BMEPS_DRIVER_PS: {
+ back = dk3bm_job_produce_ps(job);
+ } break;
+ case DK3_BMEPS_DRIVER_EPS: {
+ back = dk3bm_job_produce_ps(job);
+ } break;
+ case DK3_BMEPS_DRIVER_PDF: {
+ back = dk3bm_job_produce_pdf(job);
+ } break;
+ default: {
+ back = dk3bm_job_produce_bb(job);
+ } break;
+ }
+ dk3bif_close(job->bif);
+ } else {
+ dk3bmj_log_3(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 69, 70, job->sfn, DK3_BMJ_LOG_BOTH, job
+ );
+ }
+
+
+#line 3887 "dk3bm.ctr"
+ return back;
+}
+
+
+
+
+/** Construct an output file name and run.
+ @param job Conversion job.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bm_job_from_program_construct_name(dk3_bm_conversion_job_t *job)
+{
+ dkChar fno[DK3_MAX_PATH]; /* Output file name buffer. */
+ dkChar *sptr; /* Pointer to file name suffix. */
+ dkChar const *ns; /* New suffix. */
+ int back = 0;
+
+
+#line 3906 "dk3bm.ctr"
+ dk3str_cpy_not_overlapped(fno, job->sfn);
+ sptr = dk3str_get_suffix(fno);
+ if(sptr) { *sptr = dkT('\0'); }
+ ns = dk3bm_output_suffixes[0];
+ switch((job->opt)->dr) {
+ case DK3_BMEPS_DRIVER_EPS: {
+ ns = dk3bm_output_suffixes[1];
+ } break;
+ case DK3_BMEPS_DRIVER_PDF: {
+ ns = dk3bm_output_suffixes[2];
+ } break;
+ case DK3_BMEPS_DRIVER_BB: {
+ ns = dk3bm_output_suffixes[3];
+ } break;
+ }
+ if((dk3str_len(ns) + dk3str_len(fno)) < DK3_SIZEOF(fno,dkChar)) {
+ dk3str_cat(fno, ns);
+
+#line 3923 "dk3bm.ctr"
+ job->dfn = fno;
+ back = dk3bm_job_from_program_with_output(job);
+ } else {
+ /* ERROR: File name too long! */
+ dk3bmj_log_i3(
+ (job->opt)->app, DK3_LL_ERROR, 65, 66, job->sfn, DK3_BMJ_LOG_BOTH, job
+ );
+ }
+
+#line 3931 "dk3bm.ctr"
+ return back;
+}
+
+
+
+int
+dk3bm_process_file_name(
+ dk3_bm_eps_options_t *opt,
+ dkChar const *sfn,
+ int biftype,
+ int min,
+ int max,
+ void *comm
+)
+{
+ dk3_bm_eps_options_t bmeo; /* Conversion options. */
+ dk3_bm_conversion_job_t job; /* Conversion job. */
+#if DK3_ON_WINDOWS
+ int oldmode; /* Original stdout file mode. */
+#endif
+ int back = 0;
+
+
+#line 3953 "dk3bm.ctr"
+ if((opt) && (sfn)) {
+
+#line 3954 "dk3bm.ctr"
+ if(opt->app) {
+
+#line 3955 "dk3bm.ctr"
+ dk3bmj_init(&job, opt->app);
+ dk3mem_cpy((void *)(&bmeo), (void *)opt, sizeof(dk3_bm_eps_options_t));
+ job.opt = &bmeo;
+
+#line 3958 "dk3bm.ctr"
+ job.sfn = sfn;
+ job.biftype = biftype;
+#if DK3_USE_WX
+ job.pComm = comm;
+ job.minpb = min;
+ job.maxpb = max;
+#endif
+ if(dk3bmeo_check(&bmeo, 0, opt->app, &job)) {
+
+#line 3966 "dk3bm.ctr"
+ if(opt->to_stdout) {
+
+#line 3967 "dk3bm.ctr"
+ job.dfile = stdout;
+ switch(opt->dr) {
+ case DK3_BMEPS_DRIVER_PDF: {
+
+#line 3970 "dk3bm.ctr"
+#if DK3_ON_WINDOWS
+ oldmode = _setmode(_fileno(stdout), _O_BINARY);
+#endif
+ back = dk3bm_job_from_program_with_output(&job);
+#if DK3_ON_WINDOWS
+ _setmode(_fileno(stdout), oldmode);
+#endif
+ } break;
+ default: {
+
+#line 3979 "dk3bm.ctr"
+ back = dk3bm_job_from_program_with_output(&job);
+ } break;
+ }
+ } else {
+
+#line 3983 "dk3bm.ctr"
+ job.dfile = NULL;
+ back = dk3bm_job_from_program_construct_name(&job);
+ }
+ } else {
+
+#line 3987 "dk3bm.ctr"
+ /* ERROR: Inconsistent options, reported by dk3bmeo_check(). */
+ dk3bmj_log_1(
+ opt->app, DK3_LL_ERROR, job.msg, 68, DK3_BMJ_LOG_JOB, &job
+ );
+ }
+ } else {
+
+#line 3993 "dk3bm.ctr"
+ /* ERROR: Application structure not set! */
+ }
+ }
+#if DK3_USE_WX
+ if((comm) && (max > min)) {
+
+
+#line 3999 "dk3bm.ctr"
+ dk3bmj_progress(comm, max);
+ }
+#endif
+
+
+#line 4003 "dk3bm.ctr"
+ return back;
+}
+
+
diff --git a/support/dktools/dk3bm.ctr b/support/dktools/dk3bm.ctr
new file mode 100644
index 0000000000..93baeb6e7c
--- /dev/null
+++ b/support/dktools/dk3bm.ctr
@@ -0,0 +1,4006 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Process one file name.
+ This function is the entry point used by bmeps3 and wxbmeps.
+ The opt->app component must be set.
+ @param opt Option set for conversion.
+ @param sfn Source file name.
+ @param biftype Bitmap image file type.
+ @param min Progress bar value at start of processing.
+ @param max Progress bar value at end of processing.
+ @param comm Communicator object from wxbmeps.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3bm_process_file_name(
+ dk3_bm_eps_options_t *opt,
+ dkChar const *sfn,
+ int biftype,
+ int min,
+ int max,
+ void *comm
+);
+
+
+/** Place a PS object in a given range.
+ This is the entry point used by Fig to PS/EPS conversion.
+ @param dfile Destination file.
+ @param outbb Image area.
+ @param drawdir Draw direction / coordinates origin.
+ @param sfn Source file name.
+ @param app Application structure.
+ @param pslevel PS level.
+ @param ec Pointer to error code variable, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3bm_ps_place_object(
+ FILE *dfile,
+ dk3_bb_t *outbb,
+ int drawdir,
+ char const *sfn,
+ dk3_app_t *app,
+ int pslevel,
+ int *ec
+);
+
+/** Find graphics state transformations to place an object.
+ @param dst Graphics state transformation structure.
+ @param outbb Reserved range for image.
+ @param drawdir Drawing directory / coordinates origin.
+ @param imw Image width in pixels.
+ @param imh Image height in pixels.
+ @param xres X resolution.
+ @param yres Y resolution.
+ @param ec Pointer to error code variable.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3bm_find_transformation(
+ dk3_coordinates_transformation_t *dst,
+ dk3_bb_t *outbb,
+ int drawdir,
+ double imw,
+ double imh,
+ double xres,
+ double yres,
+ int *ec
+);
+
+/** Find graphics state transformations to place an object.
+ @param dst Graphics state transformation structure.
+ @param bif Image to place.
+ @param outbb Reserved range for image.
+ @param drawdir Drawing directory / coordinates origin.
+ @param ec Pointer to error code variable.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3bm_find_bif_transformation(
+ dk3_coordinates_transformation_t *dst,
+ dk3_bif_t *bif,
+ dk3_bb_t *outbb,
+ int drawdir,
+ int *ec
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk3all.h"
+#include "dk3bif.h"
+#include "dk3bifa.h"
+#include "dk3bmeps.h"
+#include "dk3bmeo.h"
+#include "dk3bmj.h"
+#include "dk3pdf.h"
+#include "dk3bm.h"
+
+
+
+#if DK3_USE_WX
+#include <wxbmeps.h>
+#endif
+
+
+$!trace-include
+
+
+
+/** Don't debug the module.
+*/
+#define DK3BM_DEBUG 0
+
+
+
+/** File name suffixes for output files.
+*/
+dkChar const * const dk3bm_output_suffixes[] = {
+dkT(".ps"),
+dkT(".eps"),
+dkT(".pdf"),
+dkT(".bb")
+};
+
+
+
+/** Everything between 72-epsilon and 72+epsilon is seen as 72 dpi.
+ Some file formats store the resolution in pixels per meter as
+ integer numbers.
+ If 72.0 is scaled from one inch to a meter and rounded to
+ integer, the rounding error maximum is one. If one dot per meter
+ (the probable rounding error) is converted back to dot per inch
+ the result is 0.254.
+*/
+static double const dk3bm_epsilon = 0.254;
+
+
+
+/** Keywords used by the module.
+*/
+static char const * const dk3bm_c8_kw[] = {
+/* 0 */ "\n",
+/* 1 */ " ",
+/* 2 */ "{\n",
+/* 3 */ "} exec\n",
+/* 4 */ "gsave\n",
+/* 5 */ "grestore\n",
+/* 6 */ "showpage\n",
+/* 7 */ "13 dict begin\n",
+/* 8 */ "end\n",
+/* 9 */ "%lg %lg translate\n",
+/* 10 */ "%d rotate\n",
+/* 11 */ "%lg %lg scale\n",
+/* 12 */ "%ld %ld scale\n",
+/* 13 */ "%!PS-Adobe-2.0",
+/* 14 */ "%!PS-Adobe-3.0",
+/* 15 */ " EPSF-2.0",
+/* 16 */ " EPSF-3.0",
+/* 17 */ "<<\n",
+/* 18 */ ">>\nimage\n",
+/* 19 */ "/ImageType 1\n",
+/* 20 */ "/DeviceRGB setcolorspace\n",
+/* 21 */ "/DeviceGray setcolorspace\n",
+/* 22 */ "/fa currentfile /ASCII85Decode filter def\n",
+/* 23 */ "fa flushfile fa closefile\n",
+/* 24 */ "/fb fa /RunLengthDecode filter def\n",
+/* 25 */ "fb closefile\n",
+/* 26 */ "/fb fa /FlateDecode filter def\n",
+/* 27 */ "/fb fa << >> /DCTDecode filter def\n",
+/* 28 */ "/Width %ld\n",
+/* 29 */ "/Height %ld\n",
+/* 30 */ "/ImageMatrix [%ld 0 0 -%ld 0 %ld]\n",
+/* 31 */ "%%%%BoundingBox: 0 0 %ld %ld\n",
+/* 32 */ "%%LanguageLevel: 2\n",
+/* 33 */ "%%LanguageLevel: 3\n",
+/* 34 */ "/BitsPerComponent %u\n",
+/* 35 */ "/MultipleDataSources true\n",
+/* 36 */ "/MultipleDataSources false\n",
+/* 37 */ "/DataSource fb\n",
+/* 38 */ "/DataSource fa\n",
+/* 39 */ "/DataSource [\n",
+/* 40 */ "{ fb sr readstring pop }\n",
+/* 41 */ "{ fb sg readstring pop }\n",
+/* 42 */ "{ fb sb readstring pop }\n",
+/* 43 */ "]\n",
+/* 44 */ "/Decode [0 1]\n",
+/* 45 */ "/Decode [0 1 0 1 0 1]\n",
+/* 46 */ "/Interpolate true\n",
+/* 47 */ "/Interpolate false\n",
+/* 48 */ "/sr %ld string def\n",
+/* 49 */ "/sg %ld string def\n",
+/* 50 */ "/sb %ld string def\n",
+/* 51 */ "%%Creator: bmeps3\n",
+/* 52 */ "%%Title: ",
+/* 53 */ "%%%%Pages: %u\n",
+/* 54 */ "%%PageOrder: Ascend\n",
+/* 55 */ "%%DocumentData: Clean7Bit\n",
+/* 56 */ "%%EndComments\n",
+/* 57 */ "%%BeginProlog\n",
+/* 58 */ "%%EndProlog\n",
+/* 59 */ "%%BeginSetup\n",
+/* 60 */ "%%EndSetup\n",
+/* 61 */ "%%Trailer\n",
+/* 62 */ "%%EOF\n",
+/* 63 */ "%%%%Page: %u %u\n",
+/* 64 */ "%%BeginFeature: *PageSize BmepsPage\n",
+/* 65 */ "%%EndFeature\n",
+/* 66 */ "<< /PageSize [%ld %ld] /ImagingBBox null >> setpagedevice\n",
+/* 67 */ "%%BeginFeature: *Duplex DuplexNoTumble\n",
+/* 68 */ "<< /Duplex true /Tumble false >> setpagedevice\n",
+/* 69 */ "%%BeginFeature: *Duplex DuplexTumble\n",
+/* 70 */ "<< /Duplex true /Tumble true >> setpagedevice\n",
+/* 71 */ "0 setgray\nnewpath\n",
+/* 72 */ "%lg %lg moveto\n",
+/* 73 */ "%lg %lg lineto\n",
+/* 74 */ "closepath\nfill\n",
+/* 75 */ "0.8 setgray\nnewpath\n",
+/* 76 */ "1 setgray\nnewpath\n",
+/* 77 */ "%lg setlinewidth\n",
+/* 78 */ "newpath\n",
+/* 79 */ "stroke\n",
+/* 80 */ "/fb fa <<\n",
+/* 81 */ ">> /FlateDecode filter def\n",
+/* 82 */ "/Predictor %d\n",
+/* 83 */ "/Columns %ld\n",
+/* 84 */ "/Colors 3\n",
+/* 85 */ "/Colors 1\n",
+/* 86 */ "/DeviceCMYK setcolorspace\n",
+/* 87 */ "/Decode [0 1 0 1 0 1 0 1]\n",
+/* 88 */ "/Decode [1 0 1 0 1 0 1 0]\n",
+};
+
+
+
+/** Convert long to double.
+ @param l Long value to convert.
+ @return Conversion result.
+*/
+static
+double
+dk3bm_l_to_d(long l)
+{
+ return ((double)l);
+}
+
+
+
+/** Correct output buffer.
+ If LC_NUMERIC has a wrong setting it might produce
+ a comma instead of a decimal dot for floating point numbers.
+ The PS and PDF language specification always requires a dot,
+ independent of the users language setting.
+ @param s Buffer start address.
+*/
+static
+void
+dk3bm_correct_output_buffer(char *s)
+{
+ char *ptr; /* Temporary pointer to traverse string. */
+ $? "+ dk3bm_correct_output_buffer"
+ if(s) {
+ ptr = s;
+ while(*ptr) {
+ if(*ptr == ',') { *ptr = '.'; }
+ ptr++;
+ }
+ } $? "- dk3bm_correct_output_buffer"
+}
+
+
+
+/** Write PS header for document.
+ @param job Conversion job.
+ @param pages Number of pages in the print job.
+*/
+static
+void
+dk3bm_ps_document_header(dk3_bm_conversion_job_t *job, size_t pages)
+{
+ char fnb[DK3_MAX_PATH]; /* Buffer used to construct output. */
+ char outputbuffer[256]; /* Another buffer for output. */
+ dkChar const *ptr; /* Used to traverse file name. */
+ dkChar const *nb; /* Short file name. */
+ int ie; /* Input encoding. */
+ $? "+ dk3bm_ps_document_header"
+ fputs(dk3bm_c8_kw[((job->opt)->psl == 3) ? 14 : 13], job->dfile);
+ if((job->opt)->dr == DK3_BMEPS_DRIVER_EPS) {
+ fputs(dk3bm_c8_kw[((job->opt)->psl == 3) ? 16 : 15], job->dfile);
+ }
+ fputs(dk3bm_c8_kw[0], job->dfile); $? ". w=%ld h=%ld", job->x_size, job->y_size
+ fprintf(job->dfile, dk3bm_c8_kw[31], job->x_size, job->y_size);
+ fputs(dk3bm_c8_kw[((job->opt)->psl == 3) ? 33 : 32], job->dfile);
+ if((job->opt)->dsc) {
+ fputs(dk3bm_c8_kw[51], job->dfile);
+ ptr = job->sfn;
+ if(ptr) {
+ nb = NULL;
+ while(*ptr) {
+ if((*ptr == dkT('\\')) || (*ptr == dkT('/'))) {
+ nb = ptr;
+ }
+ ptr++;
+ }
+ if(nb) {
+ nb++;
+ } else {
+ nb = job->sfn;
+ }
+ ie = dk3app_get_encoding((job->opt)->app);
+ if(dk3str_to_c8p_app(fnb,sizeof(fnb),nb,ie,(job->opt)->app)) {
+ fputs(dk3bm_c8_kw[52], job->dfile);
+ fputc('(', job->dfile);
+ fputs(fnb, job->dfile);
+ fputc(')', job->dfile);
+ fputs(dk3bm_c8_kw[0], job->dfile);
+ }
+ }
+ sprintf(fnb, dk3bm_c8_kw[53], (unsigned)pages);
+ fputs(fnb, job->dfile);
+ for(ie = 54; ie <= 59; ie++) {
+ fputs(dk3bm_c8_kw[ie], job->dfile);
+ }
+ switch((job->opt)->dr) {
+ case DK3_BMEPS_DRIVER_PS: {
+ switch((job->opt)->mode) {
+ case DK3_BMEPS_MODE_DOCUMENT: {
+ fputs(dk3bm_c8_kw[64], job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[66], job->x_size, job->y_size);
+ fputs(outputbuffer, job->dfile);
+ fputs(dk3bm_c8_kw[65], job->dfile);
+ if((job->opt)->duplex) {
+ if((job->opt)->tumble) {
+ fputs(dk3bm_c8_kw[69], job->dfile);
+ fputs(dk3bm_c8_kw[70], job->dfile);
+ fputs(dk3bm_c8_kw[65], job->dfile);
+ } else {
+ fputs(dk3bm_c8_kw[67], job->dfile);
+ fputs(dk3bm_c8_kw[68], job->dfile);
+ fputs(dk3bm_c8_kw[65], job->dfile);
+ }
+ }
+ } break;
+ }
+ } break;
+ }
+ fputs(dk3bm_c8_kw[60], job->dfile);
+ } else {
+ if((job->opt)->duplex) {
+ if((job->opt)->tumble) {
+ fputs(dk3bm_c8_kw[70], job->dfile);
+ } else {
+ fputs(dk3bm_c8_kw[68], job->dfile);
+ }
+ }
+ } $? "- dk3bm_ps_document_header"
+}
+
+
+
+/** Produce footer for PS print job.
+ @param job Conversion job.
+*/
+static
+void
+dk3bm_ps_document_footer(dk3_bm_conversion_job_t *job)
+{
+ $? "+ dk3bm_ps_document_footer"
+ if((job->opt)->dsc) {
+ fputs(dk3bm_c8_kw[61], job->dfile);
+ fputs(dk3bm_c8_kw[62], job->dfile);
+ }
+ switch((job->opt)->dr) {
+ case DK3_BMEPS_DRIVER_PS: {
+ switch((job->opt)->mode) {
+ case DK3_BMEPS_MODE_DOCUMENT: {
+ fputc(0x04, job->dfile);
+ } break;
+ }
+ } break;
+ } $? "- dk3bm_ps_document_footer"
+}
+
+
+
+/** Copy DCT encoded data directly from input to output.
+ @param of Output filter.
+ @param dctin Input file containing DCT-encoded data.
+ @param job Conversion job.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bm_copy_dct_data(
+ dk3_of_t *of,
+ FILE *dctin,
+ dk3_bm_conversion_job_t *job
+)
+{
+ char bu[4096]; /* Buffer for data read from file. */
+ size_t rb; /* Number of bytes read. */
+ int back = 1;
+ int cc; /* Flag: Can continue. */
+ $? "+ dk3bm_copy_dct_data"
+ cc = 1;
+ while(cc) {
+ cc = 0;
+ rb = dk3sf_fread_app((void *)bu, 1, sizeof(bu), dctin, (job->opt)->app);
+ if(rb > 0) {
+ cc = 1;
+ if(!dk3of_write_bytes(of, (unsigned char *)bu, rb)) {
+ back = 0;
+ cc = 0;
+ /* ERROR: Failed to write data! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 58, DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ }
+ } $? "- dk3bm_copy_dct_data %d", back
+ return back;
+}
+
+
+
+/** Write flate filter definition with predictor.
+ @param job Conversion job.
+*/
+static
+void
+dk3bm_define_flate_with_predictor(dk3_bm_conversion_job_t *job)
+{
+ char outputbuffer[256]; /* Buffer to construct output. */
+ int i = 0; /* Predictor ID in PS and PDF. */
+ $? "+ dk3bm_define_flate_with_predictor"
+ fputs(dk3bm_c8_kw[80], job->dfile);
+ /* Predictor Columns Colors BitsPerComponent */
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ i = 2;
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_SUB: {
+ i = 11;
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_UP: {
+ i = 12;
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_AVERAGE: {
+ i = 13;
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_PAETH: {
+ i = 14;
+ } break;
+ }
+ sprintf(outputbuffer, dk3bm_c8_kw[82], i);
+ fputs(outputbuffer, job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[83], dk3bif_get_width(job->bif));
+ fputs(outputbuffer, job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[34], job->bpc);
+ fputs(outputbuffer, job->dfile);
+ if(job->procedure == DK3_BMEPS_RGB_FLATE) {
+ fputs(dk3bm_c8_kw[84], job->dfile);
+ } else {
+ fputs(dk3bm_c8_kw[85], job->dfile);
+ }
+ fputs(dk3bm_c8_kw[81], job->dfile); $? "- dk3bm_define_flate_with_predictor"
+}
+
+
+
+/** Write one unsigned character.
+ @param of Output filter.
+ @param v Value to write to output.
+*/
+static
+void
+dk3bm_write_uc(dk3_of_t *of, dk3_bif_pixel_t v)
+{
+ unsigned char ucv; /* Byte to write. */
+ $? "+ dk3bm_write_uc"
+ ucv = (unsigned char)v;
+ dk3of_write_bytes(of, &ucv, 1); $? "- dk3bm_write_uc"
+}
+
+
+
+/** Produce PS for image or object.
+ The following components of job must be set:
+ x_size, y_size, x_translate, y_translate, x_0, x_1, y_0, y_1,
+ x_scale, y_scale, do_translate, do_rotate, do_float_scale.
+ @param job Conversion job.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bm_job_produce_img_job_real_ps(dk3_bm_conversion_job_t *job)
+{
+ char outputbuffer[256]; /* Buffer to prepare output. */
+ FILE *dctin; /* Input file containing DCT data. */
+ dk3_stream_t *os; /* Output stream. */
+ dk3_of_t *of; /* Output filter. */
+ long bitsperline; /* Bits per line. */
+ long bytesperline; /* Bytes per line. */
+ dk3_bif_coord_t w; /* Image width. */
+ dk3_bif_coord_t h; /* Image height. */
+ dk3_bif_coord_t x; /* Current x. */
+ dk3_bif_coord_t y; /* Current y. */
+ dk3_bif_pixel_t v; /* Current point value. */
+ dk3_bif_pixel_t pl; /* Left pixel. */
+ dk3_bif_pixel_t pu; /* Upper pixel. */
+ dk3_bif_pixel_t plu; /* Left upper pixel. */
+ size_t nbits; /* Number of bits per component. */
+ int back = 0;
+ int analysis_type = 0; /* Analysis to perform. */
+ int use_dct = 0; /* Flag: DCT used. */
+ int me = 0; /* Flag: Math error. */
+ int alphain = 0; /* Flag: Alpha channel. */
+#if TRACE_DEBUG || VERSION_BEFORE_20150821
+ int colorin = 0; /* Flag: Color image. */
+#endif
+#if DK3_USE_WX
+ int minpb; /* Original min progress bar value. */
+ int maxpb; /* Original max progress bar value. */
+ int pbmin; /* Min progress bar value. */
+ int pbmax; /* Max progress bar value. */
+#endif
+ $? "+ dk3bm_job_produce_img_job_real_ps"
+#if DK3_USE_WX
+ minpb = job->minpb;
+ maxpb = job->maxpb;
+#endif
+ if(job->dfile) { $? ". destination file ok"
+ alphain = 0;
+ switch(dk3bif_get_color_space(job->bif)) {
+ case DK3_COLOR_SPACE_GRAY_ALPHA:
+ case DK3_COLOR_SPACE_RGBA:
+ {
+ alphain = 1; $? ". alpha inspection necessary"
+ } break;
+ }
+#if VERSION_BEFORE_20150821
+ /* Already initialized to 0 */
+ colorin = 0;
+#endif
+ switch(dk3bif_get_color_space(job->bif)) {
+ case DK3_COLOR_SPACE_GRAY:
+ case DK3_COLOR_SPACE_GRAY_ALPHA: {
+ } break;
+ default: {
+ /* Static code analysis: Dead assignment */
+ /* Variable used when tracing, not in normaly build */
+#if VERSION_BEFORE_20150821
+ colorin = 1; $? ". color inspection necessary"
+#endif
+ } break;
+ }
+ /*
+ Conversion defaults.
+ */
+ w = dk3bif_get_width(job->bif);
+ h = dk3bif_get_height(job->bif);
+ job->procedure = DK3_BMEPS_GRAY_UNCOMPRESSED;
+ job->bpc = 8;
+ /*
+ Decisions about compression, bpc, colors.
+ */
+ analysis_type = 0;
+ switch(dk3bif_get_type(job->bif)) {
+ case DK3_BIF_IMAGE_TYPE_JPEG: { $? ". is jpeg"
+ if((job->opt)->dct) { $? ". dct allowed"
+ switch(dk3bif_get_bits_per_pixel(job->bif)) {
+ case 8: case 4: case 2: case 1: { $? ". bpc ok"
+ switch(dk3bif_jpeg_get_num_components(job->bif)) {
+ case 1: { $? ". dct gray"
+ job->procedure = DK3_BMEPS_GRAY_DCT;
+ job->bpc = dk3bif_get_bits_per_pixel(job->bif);
+ use_dct = 1;
+ } break;
+ case 3: { $? ". dct rgb"
+ job->procedure = DK3_BMEPS_RGB_DCT;
+ job->bpc = dk3bif_get_bits_per_pixel(job->bif);
+ use_dct = 1;
+ } break;
+ case 4: { $? ". dct cmyk"
+ job->procedure = DK3_BMEPS_CMYK_DCT;
+ job->bpc = dk3bif_get_bits_per_pixel(job->bif);
+ use_dct = 1;
+ } break;
+ default: { $? ". comp %u", (unsigned)dk3bif_jpeg_get_num_components(job->bif)
+ } break;
+ }
+ } break;
+ }
+ }
+ } break;
+ }
+ if(!(use_dct)) {
+ if((job->opt)->color) {
+ switch(dk3bif_get_color_space(job->bif)) {
+ case DK3_COLOR_SPACE_GRAY:
+ case DK3_COLOR_SPACE_GRAY_ALPHA: {
+ } break;
+ default: {
+ analysis_type |= DK3_BIF_ANALYSIS_COLOR;
+ } break;
+ }
+ }
+ if((job->opt)->rbpc) {
+ analysis_type |= DK3_BIF_ANALYSIS_BITS;
+ }
+ if(alphain) {
+ analysis_type |= DK3_BIF_ANALYSIS_ALPHA;
+ }
+ /* PROGRESS: Analyzing image. */
+ dk3app_log_1((job->opt)->app, DK3_LL_PROGRESS, job->msg, 48);
+ if(analysis_type) {
+#if DK3_USE_WX
+ dk3bif_analyze_progress(
+ job->bif, analysis_type, job->pComm, minpb, ((maxpb + minpb)/2)
+ );
+#else
+ dk3bif_analyze(job->bif, analysis_type);
+#endif
+ }
+ nbits = dk3bif_get_bits_per_pixel(job->bif);
+ if((job->opt)->rbpc) { nbits = dk3bif_real_bits_per_pixel(job->bif); }
+#if 0
+ /* 2014-03-22
+ New algorithms for bits per component detection and reduction.
+ */
+ job->bpc = 1;
+ if(nbits > 1) {
+ job->bpc = 2;
+ if(nbits > 2) {
+ job->bpc = 4;
+ if(nbits > 4) {
+ job->bpc = 8;
+ if(nbits > 8) {
+ job->bpc = 12;
+ }
+ }
+ }
+ }
+#else
+ switch (nbits) {
+ case 1: { job->bpc = 1; } break;
+ case 2: { job->bpc = 2; } break;
+ case 4: { job->bpc = 4; } break;
+ case 12: { job->bpc = 12; } break;
+ default: { job->bpc = 8; } break;
+ }
+#endif
+
+/* 2014-03-23
+ The dk3bifa module generate debug output.
+*/
+#if 0
+ /* DEBUG: Analysis results. */
+ {
+ dkChar numbuf[128];
+ dkChar const *msgpart[3];
+ int convres;
+ msgpart[0] = (job->msg)[51];
+ msgpart[1] = (job->msg)[(colorin) ? 49 : 50];
+ dk3app_log_msg((job->opt)->app, DK3_LL_DEBUG, msgpart, 2);
+ msgpart[0] = (job->msg)[52];
+ msgpart[1] = (job->msg)[(dk3bif_real_color(job->bif)) ? 49 : 50];
+ dk3app_log_msg((job->opt)->app, DK3_LL_DEBUG, msgpart, 2);
+ msgpart[0] = (job->msg)[53];
+ msgpart[1] = (job->msg)[(alphain) ? 49 : 50];
+ dk3app_log_msg((job->opt)->app, DK3_LL_DEBUG, msgpart, 2);
+ msgpart[0] = (job->msg)[54];
+ msgpart[1] = (job->msg)[(dk3bif_real_alpha(job->bif)) ? 49 : 50];
+ dk3app_log_msg((job->opt)->app, DK3_LL_DEBUG, msgpart, 2);
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(numbuf,dkT("%u"),(unsigned)dk3bif_get_bits_per_pixel(job->bif));
+ msgpart[0] = (job->msg)[55];
+ msgpart[1] = numbuf;
+ dk3app_log_msg((job->opt)->app, DK3_LL_DEBUG, msgpart, 2);
+ dk3sf_sprintf3(numbuf,dkT("%u"),(unsigned)dk3bif_real_bits_per_pixel(job->bif));
+ msgpart[0] = (job->msg)[56];
+ msgpart[1] = numbuf;
+ dk3app_log_msg((job->opt)->app, DK3_LL_DEBUG, msgpart, 2);
+ dk3sf_sprintf3(numbuf,dkT("%u"),(unsigned)(job->bpc));
+ msgpart[0] = (job->msg)[57];
+ msgpart[1] = numbuf;
+ dk3app_log_msg((job->opt)->app, DK3_LL_DEBUG, msgpart, 2);
+#else
+ convres = dk3ma_um_to_string(
+ numbuf, DK3_SIZEOF(numbuf,dkChar),
+ (dk3_um_t)dk3bif_get_bits_per_pixel(job->bif)
+ );
+ if (0 != convres) {
+ msgpart[0] = (job->msg)[55];
+ msgpart[1] = numbuf;
+ dk3app_log_msg((job->opt)->app, DK3_LL_DEBUG, msgpart, 2);
+ }
+ convres = dk3ma_um_to_string(
+ numbuf, DK3_SIZEOF(numbuf,dkChar),
+ (dk3_um_t)dk3bif_real_bits_per_pixel(job->bif)
+ );
+ if (0 != convres) {
+ msgpart[0] = (job->msg)[56];
+ msgpart[1] = numbuf;
+ dk3app_log_msg((job->opt)->app, DK3_LL_DEBUG, msgpart, 2);
+ }
+ convres = dk3ma_um_to_string(
+ numbuf, DK3_SIZEOF(numbuf,dkChar), (dk3_um_t)(job->bpc)
+ );
+ if (0 != convres) {
+ msgpart[0] = (job->msg)[57];
+ msgpart[1] = numbuf;
+ dk3app_log_msg((job->opt)->app, DK3_LL_DEBUG, msgpart, 2);
+ }
+#endif
+ }
+#endif
+#if VERSION_BEFORE_20150821
+ if(analysis_type & DK3_BIF_ANALYSIS_COLOR) {
+ colorin = dk3bif_real_color(job->bif);
+ }
+#endif
+ if(analysis_type & DK3_BIF_ANALYSIS_ALPHA) {
+ alphain = dk3bif_real_alpha(job->bif);
+ }
+ switch(dk3bif_get_color_space(job->bif)) {
+ case DK3_COLOR_SPACE_GRAY:
+ case DK3_COLOR_SPACE_GRAY_ALPHA: {
+ job->procedure = DK3_BMEPS_GRAY_RUNLENGTH;
+ if((job->opt)->psl >= 3) {
+ job->procedure = DK3_BMEPS_GRAY_FLATE;
+ if((job->opt)->pred > DK3_COMPRESSION_PREDICTOR_TIFF) {
+ job->bpc = 8;
+ }
+ }
+ } break;
+ default: {
+ if(dk3bif_real_color(job->bif)) {
+ job->procedure = DK3_BMEPS_RGB_UNCOMPRESSED;
+ if((job->opt)->psl >= 3) {
+ job->procedure = DK3_BMEPS_RGB_FLATE;
+ if((job->opt)->pred > DK3_COMPRESSION_PREDICTOR_TIFF) {
+ job->bpc = 8;
+ }
+ } else {
+ bitsperline = dk3ma_l_mul_ok((long)(job->bpc), w, &me);
+ if(me == 0) {
+ bytesperline = bitsperline / 8L;
+ if(bitsperline % 8L) { bytesperline++; }
+ if(bytesperline < 16384L) {
+ job->procedure = DK3_BMEPS_RGB_RUNLENGTH;
+ }
+ }
+ }
+ } else {
+ job->procedure = DK3_BMEPS_GRAY_RUNLENGTH;
+ if((job->opt)->psl >= 3) {
+ job->procedure = DK3_BMEPS_GRAY_FLATE;
+ if((job->opt)->pred > DK3_COMPRESSION_PREDICTOR_TIFF) {
+ job->bpc = 8;
+ }
+ }
+ }
+ } break;
+ }
+ }
+ dk3app_log_1((job->opt)->app, DK3_LL_PROGRESS, job->msg, 76);
+#if DK3BM_DEBUG
+ job->procedure = DK3_BMEPS_RGB_UNCOMPRESSED;
+#endif
+#if DK3_USE_WX
+ $? ". 1/2"
+ dk3bmj_progress(job->pComm, ((maxpb + minpb)/2));
+ job->minpb = ((maxpb + minpb) / 2);
+ pbmin = job->minpb;
+ pbmax = job->maxpb;
+#endif
+ /*
+ File header.
+ */
+ if(job->do_header_footer) {
+ dk3bm_ps_document_header(job, 1);
+ }
+ /*
+ Image.
+ */
+ if((job->opt)->dsc) {
+ sprintf(
+ outputbuffer, dk3bm_c8_kw[63],
+ (unsigned)(job->currentPage),
+ (unsigned)(job->currentPage)
+ );
+ fputs(outputbuffer, job->dfile);
+ }
+ fputs(dk3bm_c8_kw[2], job->dfile); /* { */
+ fputs(dk3bm_c8_kw[4], job->dfile); /* gsave */
+ /*
+ Translate, rotate, scale.
+ */
+ if(job->do_translate) {
+ sprintf(
+ outputbuffer, dk3bm_c8_kw[9], job->x_translate, job->y_translate
+ );
+ dk3bm_correct_output_buffer(outputbuffer);
+ fputs(outputbuffer, job->dfile);
+ }
+ if(job->do_rotate) {
+ sprintf(outputbuffer, dk3bm_c8_kw[10], (90 * job->do_rotate));
+ fputs(outputbuffer, job->dfile);
+ }
+ if(job->do_float_scale) {
+ sprintf(
+ outputbuffer,
+ dk3bm_c8_kw[11],
+ job->x_scale, job->y_scale
+ );
+ dk3bm_correct_output_buffer(outputbuffer);
+ } else {
+ sprintf(outputbuffer, dk3bm_c8_kw[12], w, h);
+ }
+ fputs(outputbuffer, job->dfile);
+ fputs(dk3bm_c8_kw[7], job->dfile); /* 13 dict begin */
+ /*
+ Color space, definitions for data source(s).
+ */
+ switch(job->procedure) {
+ case DK3_BMEPS_GRAY_UNCOMPRESSED: {
+ fputs(dk3bm_c8_kw[21], job->dfile);
+ fputs(dk3bm_c8_kw[22], job->dfile);
+ } break;
+ case DK3_BMEPS_RGB_UNCOMPRESSED: {
+ fputs(dk3bm_c8_kw[20], job->dfile);
+ fputs(dk3bm_c8_kw[22], job->dfile);
+ } break;
+ case DK3_BMEPS_GRAY_RUNLENGTH: {
+ fputs(dk3bm_c8_kw[21], job->dfile);
+ fputs(dk3bm_c8_kw[22], job->dfile);
+ fputs(dk3bm_c8_kw[24], job->dfile);
+ } break;
+ case DK3_BMEPS_RGB_RUNLENGTH: {
+ fputs(dk3bm_c8_kw[20], job->dfile);
+ fputs(dk3bm_c8_kw[22], job->dfile);
+ fputs(dk3bm_c8_kw[24], job->dfile);
+ bitsperline = w * (long)(job->bpc);
+ bytesperline = bitsperline / 8L;
+ if(bitsperline % 8L) { bytesperline++; }
+ fprintf(job->dfile, dk3bm_c8_kw[48], bytesperline);
+ fprintf(job->dfile, dk3bm_c8_kw[49], bytesperline);
+ fprintf(job->dfile, dk3bm_c8_kw[50], bytesperline);
+ } break;
+ case DK3_BMEPS_GRAY_DCT: {
+ fputs(dk3bm_c8_kw[21], job->dfile);
+ fputs(dk3bm_c8_kw[22], job->dfile);
+ fputs(dk3bm_c8_kw[27], job->dfile);
+ } break;
+ case DK3_BMEPS_RGB_DCT: {
+ fputs(dk3bm_c8_kw[20], job->dfile);
+ fputs(dk3bm_c8_kw[22], job->dfile);
+ fputs(dk3bm_c8_kw[27], job->dfile);
+ } break;
+ case DK3_BMEPS_CMYK_DCT: {
+ fputs(dk3bm_c8_kw[86], job->dfile);
+ fputs(dk3bm_c8_kw[22], job->dfile);
+ fputs(dk3bm_c8_kw[27], job->dfile);
+ } break;
+ case DK3_BMEPS_GRAY_FLATE: {
+ fputs(dk3bm_c8_kw[21], job->dfile);
+ fputs(dk3bm_c8_kw[22], job->dfile);
+ if((job->opt)->pred) {
+ dk3bm_define_flate_with_predictor(job);
+ } else {
+ fputs(dk3bm_c8_kw[26], job->dfile);
+ }
+ } break;
+ case DK3_BMEPS_RGB_FLATE: {
+ fputs(dk3bm_c8_kw[20], job->dfile);
+ fputs(dk3bm_c8_kw[22], job->dfile);
+ if((job->opt)->pred) {
+ dk3bm_define_flate_with_predictor(job);
+ } else {
+ fputs(dk3bm_c8_kw[26], job->dfile);
+ }
+ } break;
+ }
+ fputs(dk3bm_c8_kw[17], job->dfile); /* << */
+ /*
+ Image dictionary contents.
+ */
+ fputs(dk3bm_c8_kw[19], job->dfile); /* /ImageType 1 */
+ sprintf(outputbuffer, dk3bm_c8_kw[28], w);
+ fputs(outputbuffer, job->dfile); /* /Width ... */
+ sprintf(outputbuffer, dk3bm_c8_kw[29], h);
+ fputs(outputbuffer, job->dfile); /* /Height ... */
+ sprintf(outputbuffer, dk3bm_c8_kw[30], w, h, h);
+ fputs(outputbuffer, job->dfile); /* /ImageMatrix ... */
+ sprintf(outputbuffer, dk3bm_c8_kw[34], (unsigned)(job->bpc));
+ fputs(outputbuffer, job->dfile); /* /BitsPerComponent ... */
+ /* /Interpolate ... */
+ switch(job->procedure) {
+ case DK3_BMEPS_GRAY_UNCOMPRESSED: {
+ fputs(dk3bm_c8_kw[38], job->dfile);
+ fputs(dk3bm_c8_kw[44], job->dfile);
+ fputs(dk3bm_c8_kw[((job->opt)->ip) ? 46 : 47], job->dfile);
+ } break;
+ case DK3_BMEPS_RGB_UNCOMPRESSED: {
+ fputs(dk3bm_c8_kw[36], job->dfile);
+ fputs(dk3bm_c8_kw[38], job->dfile);
+ fputs(dk3bm_c8_kw[45], job->dfile);
+ fputs(dk3bm_c8_kw[((job->opt)->ip) ? 46 : 47], job->dfile);
+ } break;
+ case DK3_BMEPS_GRAY_RUNLENGTH: {
+ fputs(dk3bm_c8_kw[37], job->dfile);
+ fputs(dk3bm_c8_kw[44], job->dfile);
+ fputs(dk3bm_c8_kw[((job->opt)->ip) ? 46 : 47], job->dfile);
+ } break;
+ case DK3_BMEPS_RGB_RUNLENGTH: {
+ fputs(dk3bm_c8_kw[35], job->dfile);
+ fputs(dk3bm_c8_kw[39], job->dfile);
+ fputs(dk3bm_c8_kw[40], job->dfile);
+ fputs(dk3bm_c8_kw[41], job->dfile);
+ fputs(dk3bm_c8_kw[42], job->dfile);
+ fputs(dk3bm_c8_kw[43], job->dfile);
+ fputs(dk3bm_c8_kw[45], job->dfile);
+ fputs(dk3bm_c8_kw[((job->opt)->ip) ? 46 : 47], job->dfile);
+ } break;
+ case DK3_BMEPS_GRAY_DCT: {
+ fputs(dk3bm_c8_kw[37], job->dfile);
+ fputs(dk3bm_c8_kw[44], job->dfile);
+ if((job->opt)->ip) {
+ if((job->opt)->jip) {
+ fputs(dk3bm_c8_kw[46], job->dfile);
+ }
+ }
+ } break;
+ case DK3_BMEPS_RGB_DCT: {
+ fputs(dk3bm_c8_kw[36], job->dfile);
+ fputs(dk3bm_c8_kw[37], job->dfile);
+ fputs(dk3bm_c8_kw[45], job->dfile);
+ if((job->opt)->ip) {
+ if((job->opt)->jip) {
+ fputs(dk3bm_c8_kw[46], job->dfile);
+ }
+ }
+ } break;
+ case DK3_BMEPS_CMYK_DCT: {
+ fputs(dk3bm_c8_kw[36], job->dfile);
+ fputs(dk3bm_c8_kw[37], job->dfile);
+ if(dk3bif_jpeg_get_found_adobe_marker(job->bif)) {
+ fputs(dk3bm_c8_kw[88], job->dfile);
+ } else {
+ fputs(dk3bm_c8_kw[87], job->dfile);
+ }
+ if((job->opt)->ip) {
+ if((job->opt)->jip) {
+ fputs(dk3bm_c8_kw[46], job->dfile);
+ }
+ }
+ } break;
+ case DK3_BMEPS_GRAY_FLATE: {
+ fputs(dk3bm_c8_kw[37], job->dfile);
+ fputs(dk3bm_c8_kw[44], job->dfile);
+ fputs(dk3bm_c8_kw[((job->opt)->ip) ? 46 : 47], job->dfile);
+ } break;
+ case DK3_BMEPS_RGB_FLATE: {
+ fputs(dk3bm_c8_kw[36], job->dfile);
+ fputs(dk3bm_c8_kw[37], job->dfile);
+ fputs(dk3bm_c8_kw[45], job->dfile);
+ fputs(dk3bm_c8_kw[((job->opt)->ip) ? 46 : 47], job->dfile);
+ } break;
+ }
+ fputs(dk3bm_c8_kw[18], job->dfile); /* >> image */
+ /*
+ Close data streams.
+ */
+ switch(job->procedure) {
+ case DK3_BMEPS_GRAY_UNCOMPRESSED: {
+ fputs(dk3bm_c8_kw[23], job->dfile);
+ } break;
+ case DK3_BMEPS_RGB_UNCOMPRESSED: {
+ fputs(dk3bm_c8_kw[23], job->dfile);
+ } break;
+ case DK3_BMEPS_GRAY_RUNLENGTH: {
+ fputs(dk3bm_c8_kw[25], job->dfile);
+ fputs(dk3bm_c8_kw[23], job->dfile);
+ } break;
+ case DK3_BMEPS_RGB_RUNLENGTH: {
+ fputs(dk3bm_c8_kw[25], job->dfile);
+ fputs(dk3bm_c8_kw[23], job->dfile);
+ } break;
+ case DK3_BMEPS_GRAY_DCT: {
+ fputs(dk3bm_c8_kw[25], job->dfile);
+ fputs(dk3bm_c8_kw[23], job->dfile);
+ } break;
+ case DK3_BMEPS_RGB_DCT: {
+ fputs(dk3bm_c8_kw[25], job->dfile);
+ fputs(dk3bm_c8_kw[23], job->dfile);
+ } break;
+ case DK3_BMEPS_CMYK_DCT: {
+ fputs(dk3bm_c8_kw[25], job->dfile);
+ fputs(dk3bm_c8_kw[23], job->dfile);
+ } break;
+ case DK3_BMEPS_GRAY_FLATE: {
+ fputs(dk3bm_c8_kw[25], job->dfile);
+ fputs(dk3bm_c8_kw[23], job->dfile);
+ } break;
+ case DK3_BMEPS_RGB_FLATE: {
+ fputs(dk3bm_c8_kw[25], job->dfile);
+ fputs(dk3bm_c8_kw[23], job->dfile);
+ } break;
+ }
+ fputs(dk3bm_c8_kw[8], job->dfile); /* end */
+ fputs(dk3bm_c8_kw[5], job->dfile); /* grestore */
+ switch((job->opt)->mode) {
+ case DK3_BMEPS_MODE_IMAGE:
+ case DK3_BMEPS_MODE_DOCUMENT: {
+ if((job->opt)->dr == DK3_BMEPS_DRIVER_PS) {
+ fputs(dk3bm_c8_kw[6], job->dfile); /* showpage */
+ }
+ } break;
+ }
+ fputs(dk3bm_c8_kw[3], job->dfile); /* } exec */
+ /*
+ Write compress/encoded image data.
+ */
+ os = dk3stream_open_file_app(
+ job->dfile, DK3_STREAM_FLAG_WRITE, (job->opt)->app
+ );
+ if(os) {
+ of = dk3of_open_app(os, (job->opt)->app);
+ if(of) {
+ dk3of_set_finalize(of, 1);
+ if(dk3of_add_cell(of, DK3_OF_CELL_TYPE_A85)) {
+ switch(job->procedure) {
+ case DK3_BMEPS_GRAY_UNCOMPRESSED: {
+ dk3bif_set_bits_per_pixel(job->bif, job->bpc);
+ if(dk3of_start_chunk(of)) {
+ if(job->bpc == 8) {
+ if(alphain) {
+ for(y = 0L; y < h; y++) {
+ for(x = 0L; x < w; x++) {
+ v = dk3bif_get_mixed_gray(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } else {
+ for(y = 0L; y < h; y++) {
+ for(x = 0L; x < w; x++) {
+ v = dk3bif_get_gray(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ }
+ } else {
+ if(alphain) {
+ for(y = 0L; y < h; y++) {
+ for(x = 0L; x < w; x++) {
+ v = dk3bif_get_mixed_gray(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ }
+ dk3of_flush_bits(of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } else {
+ for(y = 0L; y < h; y++) {
+ for(x = 0L; x < w; x++) {
+ v = dk3bif_get_gray(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ }
+ dk3of_flush_bits(of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ }
+ }
+ back = dk3of_end_chunk(of);
+ } else {
+ /* ERROR: Failed to start encoded chunk! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 59,
+ DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ } break;
+ case DK3_BMEPS_RGB_UNCOMPRESSED: {
+ dk3bif_set_bits_per_pixel(job->bif, job->bpc);
+ if(dk3of_start_chunk(of)) {
+ if(job->bpc == 8) {
+ if(alphain) {
+ for(y = 0L; y < h; y++) {
+ for(x = 0L; x < w; x++) {
+ v = dk3bif_get_mixed_red(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ v = dk3bif_get_mixed_green(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ v = dk3bif_get_mixed_blue(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } else {
+ for(y = 0L; y < h; y++) {
+ for(x = 0L; x < w; x++) {
+ v = dk3bif_get_red(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ v = dk3bif_get_green(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ v = dk3bif_get_blue(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ }
+ } else {
+ if(alphain) {
+ for(y = 0L; y < h; y++) {
+ for(x = 0L; x < w; x++) {
+ v = dk3bif_get_mixed_red(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ v = dk3bif_get_mixed_green(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ v = dk3bif_get_mixed_blue(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ }
+ dk3of_flush_bits(of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } else {
+ for(y = 0L; y < h; y++) {
+ for(x = 0L; x < w; x++) {
+ v = dk3bif_get_red(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ v = dk3bif_get_green(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ v = dk3bif_get_blue(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ }
+ dk3of_flush_bits(of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ }
+ }
+ back = dk3of_end_chunk(of);
+ } else {
+ /* ERROR: Failed to start encoded chunk! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 59,
+ DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ } break;
+ case DK3_BMEPS_GRAY_RUNLENGTH: {
+ dk3bif_set_bits_per_pixel(job->bif, job->bpc);
+ if(dk3of_add_cell(of, DK3_OF_CELL_TYPE_RUN_LENGTH)) {
+ if(dk3of_start_chunk(of)) {
+ if(job->bpc == 8) {
+ if(alphain) {
+ for(y = 0UL; y < h; y++) {
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_gray(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } else {
+ for(y = 0UL; y < h; y++) {
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_gray(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ }
+ } else {
+ if(alphain) {
+ for(y = 0UL; y < h; y++) {
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_gray(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ }
+ dk3of_flush_bits(of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } else {
+ for(y = 0UL; y < h; y++) {
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_gray(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ }
+ dk3of_flush_bits(of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ }
+ }
+ back = dk3of_end_chunk(of);
+ } else {
+ /* ERROR: Failed to start encoded chunk! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 59,
+ DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ } else {
+ /* ERROR: Failed to add run-length cell! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 59,
+ DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ } break;
+ case DK3_BMEPS_RGB_RUNLENGTH: {
+ dk3bif_set_bits_per_pixel(job->bif, job->bpc);
+ if(dk3of_add_cell(of, DK3_OF_CELL_TYPE_RUN_LENGTH)) {
+ if(dk3of_start_chunk(of)) {
+ if(job->bpc == 8) {
+ if(alphain) {
+ for(y = 0UL; y < h; y++) {
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_red(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ }
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_green(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ }
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_blue(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } else {
+ for(y = 0UL; y < h; y++) {
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_red(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ }
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_green(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ }
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_blue(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ }
+ } else {
+ if(alphain) {
+ for(y = 0UL; y < h; y++) {
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_red(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ }
+ dk3of_flush_bits(of);
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_green(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ }
+ dk3of_flush_bits(of);
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_blue(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ }
+ dk3of_flush_bits(of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } else {
+ for(y = 0UL; y < h; y++) {
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_red(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ }
+ dk3of_flush_bits(of);
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_green(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ }
+ dk3of_flush_bits(of);
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_blue(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ }
+ dk3of_flush_bits(of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ }
+ }
+ back = dk3of_end_chunk(of);
+ } else {
+ /* ERROR: Failed to start encoded chunk! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 59,
+ DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ } else {
+ /* ERROR: Failed to add run-length cell! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 59,
+ DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ } break;
+ case DK3_BMEPS_GRAY_DCT:
+ case DK3_BMEPS_RGB_DCT:
+ case DK3_BMEPS_CMYK_DCT: {
+ dctin = dk3bif_get_file(job->bif);
+ if(dctin) {
+ rewind(dctin);
+ if(dk3of_start_chunk(of)) {
+ back = dk3bm_copy_dct_data(of, dctin, job);
+ if(back) {
+ back = dk3of_end_chunk(of);
+ } else {
+ (void)dk3of_end_chunk(of);
+ }
+ } else {
+ /* ERROR: Failed to start encoded chunk! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 59,
+ DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ } else {
+ /* BUG: No input file! */
+ }
+ } break;
+ case DK3_BMEPS_GRAY_FLATE: {
+ dk3bif_set_bits_per_pixel(job->bif, job->bpc);
+ if(dk3of_add_cell(of, DK3_OF_CELL_TYPE_FLATE)) {
+ if(dk3of_start_chunk(of)) {
+ if(job->bpc == 8) {
+ if(alphain) { $? ". have alpha"
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ for(y = 0UL; y < h; y++) {
+ pl = 0;
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_gray(job->bif, x, y);
+ dk3bm_write_uc(of, (v - pl));
+ pl = v;
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_SUB: {
+ for(y = 0UL; y < h; y++) {
+ pl = 0;
+ dk3bm_write_uc(of, 1);
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_gray(job->bif, x, y);
+ dk3bm_write_uc(of, (v - pl));
+ pl = v;
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_UP: {
+ for(y = 0UL; y < h; y++) {
+ dk3bm_write_uc(of, 2);
+ for(x = 0UL; x < w; x++) { $? ". x=%ld y=%ld", x, y
+ v = dk3bif_get_mixed_gray(job->bif, x, y);
+ pu = dk3bif_get_mixed_gray(job->bif, x, (y - 1L));
+ $? ". v = %u pu=%u", (unsigned)v, (unsigned)pu
+ v = v - pu; $? ". v-pu=%u", (unsigned)v
+ dk3bm_write_uc(of, v);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_AVERAGE: {
+ for(y = 0UL; y < h; y++) {
+ dk3bm_write_uc(of, 3);
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_gray(job->bif, x, y);
+ pl = dk3bif_get_mixed_gray(job->bif, (x - 1L), y);
+ pu = dk3bif_get_mixed_gray(job->bif, x, (y - 1L));
+ pl = dk3bif_average(pl, pu);
+ pl &= 0x00FFU;
+ v = v - pl;
+ dk3bm_write_uc(of, v);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_PAETH: {
+ for(y = 0UL; y < h; y++) {
+ dk3bm_write_uc(of, 4);
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_gray(job->bif, x, y);
+ pl = dk3bif_get_mixed_gray(job->bif, (x - 1L), y);
+ pu = dk3bif_get_mixed_gray(job->bif, x, (y - 1L));
+ plu = dk3bif_get_mixed_gray(
+ job->bif, (x - 1L), (y - 1L)
+ );
+ pl = dk3bif_paeth(pl, pu, plu);
+ v = v - pl;
+ dk3bm_write_uc(of, v);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ default: {
+ for(y = 0UL; y < h; y++) {
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_gray(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ }
+ } else {
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ for(y = 0UL; y < h; y++) {
+ pl = 0;
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_gray(job->bif, x, y);
+ dk3bm_write_uc(of, (v - pl));
+ pl = v;
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_SUB: {
+ for(y = 0UL; y < h; y++) {
+ dk3bm_write_uc(of, 1);
+ pl = 0;
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_gray(job->bif, x, y);
+ dk3bm_write_uc(of, (v - pl));
+ pl = v;
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_UP: {
+ for(y = 0UL; y < h; y++) {
+ dk3bm_write_uc(of, 2);
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_gray(job->bif, x, y);
+ pu = dk3bif_get_gray(job->bif, x, (y - 1L));
+ dk3bm_write_uc(of, (v - pu));
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_AVERAGE: {
+ for(y = 0UL; y < h; y++) {
+ dk3bm_write_uc(of, 3);
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_gray(job->bif, x, y);
+ pl = dk3bif_get_gray(job->bif, (x - 1L), y);
+ pu = dk3bif_get_gray(job->bif, x, (y - 1L));
+ pl = dk3bif_average(pl, pu);
+ pl &= 0x00FFU;
+ v = v - pl;
+ dk3bm_write_uc(of, v);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_PAETH: {
+ for(y = 0UL; y < h; y++) {
+ dk3bm_write_uc(of, 4);
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_gray(job->bif, x, y);
+ pl = dk3bif_get_gray(job->bif, (x - 1L), y);
+ pu = dk3bif_get_gray(job->bif, x, (y - 1L));
+ plu = dk3bif_get_gray(
+ job->bif, (x - 1L), (y - 1L)
+ );
+ pl = dk3bif_paeth(pl, pu, plu);
+ v = v - pl;
+ dk3bm_write_uc(of, v);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ default: {
+ for(y = 0UL; y < h; y++) {
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_gray(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ }
+ }
+ } else {
+ if(alphain) {
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ for(y = 0UL; y < h; y++) {
+ pl = 0;
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_gray(job->bif, x, y);
+ dk3of_write_bits(of, (v - pl), job->bpc);
+ pl = v;
+ }
+ dk3of_flush_bits(of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ default: {
+ for(y = 0UL; y < h; y++) {
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_gray(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ }
+ dk3of_flush_bits(of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ }
+ } else {
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ for(y = 0UL; y < h; y++) {
+ pl = 0;
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_gray(job->bif, x, y);
+ dk3of_write_bits(of, (v - pl), job->bpc);
+ pl = v;
+ }
+ dk3of_flush_bits(of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ default: {
+ for(y = 0UL; y < h; y++) {
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_gray(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ }
+ dk3of_flush_bits(of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ }
+ }
+ }
+ back = dk3of_end_chunk(of);
+ } else {
+ /* ERROR: Failed to start encoded chunk! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 59,
+ DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ } else {
+ /* ERROR: Failed to add run-length cell! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 59,
+ DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ } break;
+ case DK3_BMEPS_RGB_FLATE: {
+ dk3bif_set_bits_per_pixel(job->bif, job->bpc);
+ if(dk3of_add_cell(of, DK3_OF_CELL_TYPE_FLATE)) {
+ if(dk3of_start_chunk(of)) {
+ if(job->bpc == 8) {
+ if(alphain) {
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ for(y = 0UL; y < h; y++) {
+ pl = 0; /* r */
+ pu = 0; /* g */
+ plu = 0; /* b */
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_red(job->bif, x, y);
+ dk3bm_write_uc(of, (v - pl));
+ pl = v;
+ v = dk3bif_get_mixed_green(job->bif, x, y);
+ dk3bm_write_uc(of, (v - pu));
+ pu = v;
+ v = dk3bif_get_mixed_blue(job->bif, x, y);
+ dk3bm_write_uc(of, (v - plu));
+ plu = v;
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_SUB: {
+ for(y = 0UL; y < h; y++) {
+ pl = 0; /* r */
+ pu = 0; /* g */
+ plu = 0; /* b */
+ dk3bm_write_uc(of, 1);
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_red(job->bif, x, y);
+ dk3bm_write_uc(of, (v - pl));
+ pl = v;
+ v = dk3bif_get_mixed_green(job->bif, x, y);
+ dk3bm_write_uc(of, (v - pu));
+ pu = v;
+ v = dk3bif_get_mixed_blue(job->bif, x, y);
+ dk3bm_write_uc(of, (v - plu));
+ plu = v;
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_UP: {
+ for(y = 0UL; y < h; y++) {
+ dk3bm_write_uc(of, 2);
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_red(job->bif, x, y);
+ pu = dk3bif_get_mixed_red(job->bif, x, (y - 1L));
+ dk3bm_write_uc(of, (v - pu));
+ v = dk3bif_get_mixed_green(job->bif, x, y);
+ pu = dk3bif_get_mixed_green(job->bif, x, (y - 1L));
+ dk3bm_write_uc(of, (v - pu));
+ v = dk3bif_get_mixed_blue(job->bif, x, y);
+ pu = dk3bif_get_mixed_blue(job->bif, x, (y - 1L));
+ dk3bm_write_uc(of, (v - pu));
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_AVERAGE: {
+ for(y = 0UL; y < h; y++) {
+ dk3bm_write_uc(of, 3);
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_red(job->bif, x, y);
+ pl = dk3bif_get_mixed_red(job->bif, (x - 1L), y);
+ pu = dk3bif_get_mixed_red(job->bif, x, (y - 1L));
+ pu = dk3bif_average(pl, pu);
+ dk3bm_write_uc(of, (v - pu));
+ v = dk3bif_get_mixed_green(job->bif, x, y);
+ pl = dk3bif_get_mixed_green(job->bif, (x - 1L), y);
+ pu = dk3bif_get_mixed_green(job->bif, x, (y - 1L));
+ pu = dk3bif_average(pl, pu);
+ dk3bm_write_uc(of, (v - pu));
+ v = dk3bif_get_mixed_blue(job->bif, x, y);
+ pl = dk3bif_get_mixed_blue(job->bif, (x - 1L), y);
+ pu = dk3bif_get_mixed_blue(job->bif, x, (y - 1L));
+ pu = dk3bif_average(pl, pu);
+ dk3bm_write_uc(of, (v - pu));
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_PAETH: {
+ for(y = 0UL; y < h; y++) {
+ dk3bm_write_uc(of, 3);
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_red(job->bif, x, y);
+ pl = dk3bif_get_mixed_red(job->bif, (x - 1L), y);
+ pu = dk3bif_get_mixed_red(job->bif, x, (y - 1L));
+ plu = dk3bif_get_mixed_red(job->bif, (x - 1L), (y - 1L));
+ pu = dk3bif_paeth(pl, pu, plu);
+ dk3bm_write_uc(of, (v - pu));
+ v = dk3bif_get_mixed_green(job->bif, x, y);
+ pl = dk3bif_get_mixed_green(job->bif, (x - 1L), y);
+ pu = dk3bif_get_mixed_green(job->bif, x, (y - 1L));
+ plu = dk3bif_get_mixed_green(job->bif, (x - 1L), (y - 1L));
+ pu = dk3bif_paeth(pl, pu, plu);
+ dk3bm_write_uc(of, (v - pu));
+ v = dk3bif_get_mixed_blue(job->bif, x, y);
+ pl = dk3bif_get_mixed_blue(job->bif, (x - 1L), y);
+ pu = dk3bif_get_mixed_blue(job->bif, x, (y - 1L));
+ plu = dk3bif_get_mixed_blue(job->bif, (x - 1L), (y - 1L));
+ pu = dk3bif_paeth(pl, pu, plu);
+ dk3bm_write_uc(of, (v - pu));
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ default: {
+ for(y = 0UL; y < h; y++) {
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_red(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ v = dk3bif_get_mixed_green(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ v = dk3bif_get_mixed_blue(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ }
+ } else {
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ for(y = 0UL; y < h; y++) {
+ pl = 0; /* r */
+ pu = 0; /* g */
+ plu = 0; /* b */
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_red(job->bif, x, y);
+ dk3bm_write_uc(of, (v - pl));
+ pl = v;
+ v = dk3bif_get_green(job->bif, x, y);
+ dk3bm_write_uc(of, (v - pu));
+ pu = v;
+ v = dk3bif_get_blue(job->bif, x, y);
+ dk3bm_write_uc(of, (v - plu));
+ plu = v;
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_SUB: {
+ for(y = 0UL; y < h; y++) {
+ pl = 0; /* r */
+ pu = 0; /* g */
+ plu = 0; /* b */
+ dk3bm_write_uc(of, 1);
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_red(job->bif, x, y);
+ dk3bm_write_uc(of, (v - pl));
+ pl = v;
+ v = dk3bif_get_green(job->bif, x, y);
+ dk3bm_write_uc(of, (v - pu));
+ pu = v;
+ v = dk3bif_get_blue(job->bif, x, y);
+ dk3bm_write_uc(of, (v - plu));
+ plu = v;
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_UP: {
+ for(y = 0UL; y < h; y++) {
+ dk3bm_write_uc(of, 2);
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_red(job->bif, x, y);
+ pu = dk3bif_get_red(job->bif, x, (y - 1L));
+ dk3bm_write_uc(of, (v - pu));
+ v = dk3bif_get_green(job->bif, x, y);
+ pu = dk3bif_get_green(job->bif, x, (y - 1L));
+ dk3bm_write_uc(of, (v - pu));
+ v = dk3bif_get_blue(job->bif, x, y);
+ pu = dk3bif_get_blue(job->bif, x, (y - 1L));
+ dk3bm_write_uc(of, (v - pu));
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_AVERAGE: {
+ for(y = 0UL; y < h; y++) {
+ dk3bm_write_uc(of, 3);
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_red(job->bif, x, y);
+ pl = dk3bif_get_red(job->bif, (x - 1L), y);
+ pu = dk3bif_get_red(job->bif, x, (y - 1L));
+ pu = dk3bif_average(pl, pu);
+ dk3bm_write_uc(of, (v - pu));
+ v = dk3bif_get_green(job->bif, x, y);
+ pl = dk3bif_get_green(job->bif, (x - 1L), y);
+ pu = dk3bif_get_green(job->bif, x, (y - 1L));
+ pu = dk3bif_average(pl, pu);
+ dk3bm_write_uc(of, (v - pu));
+ v = dk3bif_get_blue(job->bif, x, y);
+ pl = dk3bif_get_blue(job->bif, (x - 1L), y);
+ pu = dk3bif_get_blue(job->bif, x, (y - 1L));
+ pu = dk3bif_average(pl, pu);
+ dk3bm_write_uc(of, (v - pu));
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_PAETH: {
+ for(y = 0UL; y < h; y++) {
+ dk3bm_write_uc(of, 3);
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_red(job->bif, x, y);
+ pl = dk3bif_get_red(job->bif, (x - 1L), y);
+ pu = dk3bif_get_red(job->bif, x, (y - 1L));
+ plu = dk3bif_get_red(job->bif, (x - 1L), (y - 1L));
+ pu = dk3bif_paeth(pl, pu, plu);
+ dk3bm_write_uc(of, (v - pu));
+ v = dk3bif_get_green(job->bif, x, y);
+ pl = dk3bif_get_green(job->bif, (x - 1L), y);
+ pu = dk3bif_get_green(job->bif, x, (y - 1L));
+ plu = dk3bif_get_green(job->bif, (x - 1L), (y - 1L));
+ pu = dk3bif_paeth(pl, pu, plu);
+ dk3bm_write_uc(of, (v - pu));
+ v = dk3bif_get_blue(job->bif, x, y);
+ pl = dk3bif_get_blue(job->bif, (x - 1L), y);
+ pu = dk3bif_get_blue(job->bif, x, (y - 1L));
+ plu = dk3bif_get_blue(job->bif, (x - 1L), (y - 1L));
+ pu = dk3bif_paeth(pl, pu, plu);
+ dk3bm_write_uc(of, (v - pu));
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ default : {
+ for(y = 0UL; y < h; y++) {
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_red(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ v = dk3bif_get_green(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ v = dk3bif_get_blue(job->bif, x, y);
+ dk3bm_write_uc(of, v);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ }
+ }
+ } else {
+ if(alphain) {
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ for(y = 0UL; y < h; y++) {
+ pl = 0; pu = 0; plu = 0;
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_red(job->bif, x, y);
+ dk3of_write_bits(of, (v - pl), job->bpc);
+ pl = v;
+ v = dk3bif_get_mixed_green(job->bif, x, y);
+ dk3of_write_bits(of, (v - pu), job->bpc);
+ pu = v;
+ v = dk3bif_get_mixed_blue(job->bif, x, y);
+ dk3of_write_bits(of, (v - plu), job->bpc);
+ plu = v;
+ }
+ dk3of_flush_bits(of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ default: {
+ for(y = 0UL; y < h; y++) {
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_mixed_red(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ v = dk3bif_get_mixed_green(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ v = dk3bif_get_mixed_blue(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ }
+ dk3of_flush_bits(of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ }
+ } else {
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ for(y = 0UL; y < h; y++) {
+ pl = 0; pu = 0; plu = 0;
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_red(job->bif, x, y);
+ dk3of_write_bits(of, (v - pl), job->bpc);
+ pl = v;
+ v = dk3bif_get_green(job->bif, x, y);
+ dk3of_write_bits(of, (v - pu), job->bpc);
+ pu = v;
+ v = dk3bif_get_blue(job->bif, x, y);
+ dk3of_write_bits(of, (v - plu), job->bpc);
+ plu = v;
+ }
+ dk3of_flush_bits(of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ default: {
+ for(y = 0UL; y < h; y++) {
+ for(x = 0UL; x < w; x++) {
+ v = dk3bif_get_red(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ v = dk3bif_get_green(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ v = dk3bif_get_blue(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ }
+ dk3of_flush_bits(of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(job->pComm,pbmin,pbmax,h,y);
+#endif
+ }
+ } break;
+ }
+ }
+ }
+ back = dk3of_end_chunk(of);
+ } else {
+ /* ERROR: Failed to start encoded chunk! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 59,
+ DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ } else {
+ /* ERROR: Failed to add run-length cell! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 59,
+ DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ } break;
+ }
+ } else {
+ /* ERROR: Failed to add filter cell! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 59,
+ DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ dk3of_close(of);
+ } else {
+ /* ERROR: Failed to create output filter! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 59, DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ dk3stream_close(os);
+ } else {
+ /* ERROR: Failed to create output stream! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 59, DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ /*
+ File footer.
+ */
+ if(job->do_header_footer) {
+ dk3bm_ps_document_footer(job);
+ }
+ } else { $? "! no output file"
+ /* BUG: No output file! */
+ }
+#if DK3_USE_WX
+ job->minpb = minpb;
+ job->maxpb = maxpb;
+#endif
+ $? "- dk3bm_job_produce_img_job_real_ps %d", back
+ return back;
+}
+
+
+
+int
+dk3bm_find_transformation(
+ dk3_coordinates_transformation_t *dst,
+ dk3_bb_t *outbb,
+ int drawdir,
+ double imw,
+ double imh,
+ double xres,
+ double yres,
+ int *ec
+)
+{
+ double w = 0.0; /* Image width. */
+ double h = 0.0; /* Image height. */
+ double sx = 0.0; /* X scale factor. */
+ double sy = 0.0; /* Y scale factor. */
+#if VERSION_BEFORE_20150821
+ double sf = 0.0; /* Scale factor. */
+#endif
+ double xmin = 0.0; /* Minimum X. */
+ double xmax = 0.0; /* Maximum X. */
+ double ymin = 0.0; /* Minimum Y. */
+ double ymax = 0.0; /* Maximum Y. */
+ double xused = 0.0; /* Used X range. */
+ double yused = 0.0; /* Used Y range. */
+ double xborder = 0.0; /* X border. */
+ double yborder = 0.0; /* Y border. */
+ int mec = 0; /* Mathematical error code. */
+ int back = 0;
+ $? "+ dk3bm_find_transformation w=%lg h=%lg xr=%lg yr=%lg",imw,imh,xres,yres
+ if((dst) && (outbb)) {
+ back = 1;
+ w = imw; $? ". w = %lg", w
+ h = imh; $? ". h = %lg", h
+ if((xres > 0.0) && (yres > 0.0)) {
+ w = dk3ma_d_div_ok(w, xres, &mec); $? ". w = %lg", w
+ h = dk3ma_d_div_ok(h, yres, &mec); $? ". h = %lg", h
+ }
+#if VERSION_BEFORE_20150821
+ sx = sy = sf = 0.0;
+#endif
+ switch(drawdir) {
+ case DK3_IMAGE_ORIGIN_LEFT_BOTTOM:
+ case DK3_IMAGE_ORIGIN_RIGHT_TOP:
+ case DK3_IMAGE_ORIGIN_LEFT_TOP_FLIPPED:
+ case DK3_IMAGE_ORIGIN_RIGHT_BOTTOM_FLIPPED:
+ {
+ sx = dk3ma_d_div_ok(
+ dk3ma_d_sub_ok(outbb->xmax, outbb->xmin, ec),
+ h,
+ ec
+ );
+ sy = dk3ma_d_div_ok(
+ dk3ma_d_sub_ok(outbb->ymax, outbb->ymin, ec),
+ w,
+ ec
+ );
+ if(sx < sy) { /* Entire X range used. */
+ xmin = outbb->xmin;
+ xmax = outbb->xmax;
+ xused = dk3ma_d_sub_ok(xmax, xmin, ec);
+#if VERSION_BEFORE_20150821
+ xborder = 0.0;
+#endif
+ yused = dk3ma_d_mul_ok(sx, w, ec);
+ yborder = 0.5 * dk3ma_d_sub_ok(
+ dk3ma_d_sub_ok(outbb->ymax, outbb->ymin, ec),
+ yused,
+ ec
+ );
+ if(yborder < 0.0) { yborder = 0.0; }
+ ymin = dk3ma_d_add_ok(outbb->ymin, yborder, ec);
+ ymax = dk3ma_d_add_ok(ymin, yused, ec);
+ } else { /* Entire Y range used. */
+ ymin = outbb->ymin;
+ ymax = outbb->ymax;
+ yused = dk3ma_d_sub_ok(ymax, ymin, ec);
+#if VERSION_BEFORE_20150821
+ yborder = 0.0;
+#endif
+ xused = dk3ma_d_mul_ok(sy, h, ec);
+ xborder = 0.5 * dk3ma_d_sub_ok(
+ dk3ma_d_sub_ok(outbb->xmax, outbb->xmin, ec),
+ xused,
+ ec
+ );
+ if(xborder < 0.0) { xborder = 0.0; }
+ xmin = dk3ma_d_add_ok(outbb->xmin, xborder, ec);
+ xmax = dk3ma_d_add_ok(xmin, xused, ec);
+ }
+ } break;
+ default: {
+ sx = dk3ma_d_div_ok(
+ dk3ma_d_sub_ok(outbb->xmax, outbb->xmin, ec),
+ w,
+ ec
+ );
+ sy = dk3ma_d_div_ok(
+ dk3ma_d_sub_ok(outbb->ymax, outbb->ymin, ec),
+ h,
+ ec
+ );
+ if(sx < sy) { /* Entire X range used. */
+ xmin = outbb->xmin;
+ xmax = outbb->xmax;
+ xused = dk3ma_d_sub_ok(xmax, xmin, ec);
+#if VERSION_BEFORE_20150821
+ xborder = 0.0;
+#endif
+ yused = dk3ma_d_mul_ok(sx, h, ec);
+ yborder = 0.5 * dk3ma_d_sub_ok(
+ dk3ma_d_sub_ok(outbb->ymax, outbb->ymin, ec),
+ yused,
+ ec
+ );
+ if(yborder < 0.0) { yborder = 0.0; }
+ ymin = dk3ma_d_add_ok(outbb->ymin, yborder, ec);
+ ymax = dk3ma_d_add_ok(ymin, yused, ec);
+ } else { /* Entire Y range used. */
+ ymin = outbb->ymin;
+ ymax = outbb->ymax;
+ yused = dk3ma_d_sub_ok(ymax, ymin, ec);
+#if VERSION_BEFORE_20150821
+ yborder = 0.0;
+#endif
+ xused = dk3ma_d_mul_ok(sy, w, ec);
+ xborder = 0.5 * dk3ma_d_sub_ok(
+ dk3ma_d_sub_ok(outbb->xmax, outbb->xmin, ec),
+ xused,
+ ec
+ );
+ if(xborder < 0.0) { xborder = 0.0; }
+ xmin = dk3ma_d_add_ok(outbb->xmin, xborder, ec);
+ xmax = dk3ma_d_add_ok(xmin, xused, ec);
+ }
+ } break;
+ }
+ dst->x_scale = xused;
+ dst->y_scale = yused;
+ $? ". xused = %lg", xused
+ $? ". yused = %lg", yused
+ $? ". xmin = %lg", xmin
+ $? ". xmax = %lg", xmax
+ $? ". ymin = %lg", ymin
+ $? ". ymax = %lg", ymax
+ dst->rot = 0;
+ switch(drawdir) {
+ case DK3_IMAGE_ORIGIN_LEFT_BOTTOM: { /* 1 */
+ dst->x_translate = xmax;
+ dst->y_translate = ymin;
+ dst->rot = 1;
+ dst->x_scale = yused;
+ dst->y_scale = xused;
+ } break;
+ case DK3_IMAGE_ORIGIN_RIGHT_TOP: { /* 2 */
+ dst->x_translate = xmin;
+ dst->y_translate = ymax;
+ dst->rot = 3;
+ dst->x_scale = yused;
+ dst->y_scale = xused;
+ } break;
+ case DK3_IMAGE_ORIGIN_RIGHT_BOTTOM: { /* 3 */
+ dst->x_translate = xmax;
+ dst->y_translate = ymax;
+ dst->rot = 2;
+ } break;
+ case DK3_IMAGE_ORIGIN_LEFT_TOP_FLIPPED: { /* 4 */
+ dst->x_translate = xmax;
+ dst->y_translate = ymax;
+ dst->rot = 1;
+ dst->x_scale = yused;
+ dst->y_scale = xused;
+ dst->x_scale = -1.0 * (dst->x_scale);
+ } break;
+ case DK3_IMAGE_ORIGIN_LEFT_BOTTOM_FLIPPED: { /* 5 */
+ dst->x_translate = xmin;
+ dst->y_translate = ymax;
+ dst->y_scale = -1.0 * (dst->y_scale);
+ } break;
+ case DK3_IMAGE_ORIGIN_RIGHT_TOP_FLIPPED: { /* 6 */
+ dst->x_translate = xmax;
+ dst->y_translate = ymin;
+ dst->x_scale = -1.0 * (dst->x_scale);
+ } break;
+ case DK3_IMAGE_ORIGIN_RIGHT_BOTTOM_FLIPPED: { /* 7 */
+ dst->x_translate = xmin;
+ dst->y_translate = ymin;
+ dst->rot = 3;
+ dst->x_scale = yused;
+ dst->y_scale = xused;
+ dst->x_scale = -1.0 * (dst->x_scale);
+ } break;
+ default: { /* left top */
+ dst->x_translate = xmin;
+ dst->y_translate = ymin;
+ dst->rot = 0;
+ } break;
+ }
+ $? ". x translate = %lg", dst->x_translate
+ $? ". y translate = %lg", dst->y_translate
+ $? ". rotate = %d", dst->rot
+ $? ". x scale = %lg", dst->x_scale
+ $? ". y_scale = %lg", dst->y_scale
+ }
+ if(mec) {
+ if(ec) { *ec = mec; }
+ } $? "- dk3bm_find_transformation %d", back
+ return back;
+}
+
+
+
+int
+dk3bm_find_bif_transformation(
+ dk3_coordinates_transformation_t *dst,
+ dk3_bif_t *bif,
+ dk3_bb_t *outbb,
+ int drawdir,
+ int *ec
+)
+{
+ double w;
+ double h;
+ double xres;
+ double yres;
+ dk3_bif_coord_t imw;
+ dk3_bif_coord_t imh;
+ int back = 0;
+ $? "+ dk3bm_find_bif_transformation"
+ if((dst) && (bif) && (outbb)) {
+ imw = dk3bif_get_width(bif);
+ imh = dk3bif_get_height(bif);
+ w = (double)imw;
+ h = (double)imh;
+ xres = dk3bif_get_xres(bif);
+ yres = dk3bif_get_yres(bif);
+ back = dk3bm_find_transformation(dst, outbb, drawdir, w, h, xres, yres, ec);
+ } $? "- dk3bm_find_bif_transformation"
+ return back;
+}
+
+
+
+int
+dk3bm_ps_place_object(
+ FILE *dfile,
+ dk3_bb_t *outbb,
+ int drawdir,
+ char const *sfn,
+ dk3_app_t *app,
+ int pslevel,
+ int *ec
+)
+{
+ dk3_coordinates_transformation_t trans;
+ dk3_bm_eps_options_t bmeo;
+ dk3_bm_conversion_job_t job;
+ int back = 0;
+ $? "+ dk3bm_ps_place_object %d", drawdir
+ if((dfile) && (outbb) && (sfn) && (app)) {
+ dk3bmj_init(&job, app);
+ dk3bmeo_init(&bmeo); $? ". job and options initialized"
+ job.opt = &bmeo;
+ job.sfn = NULL;
+ job.dfile = dfile;
+ job.do_header_footer = 0;
+ bmeo.app = app;
+ bmeo.ima.ia.xl = outbb->xmin;
+ bmeo.ima.ia.xr = outbb->xmax;
+ bmeo.ima.ia.yb = outbb->ymin;
+ bmeo.ima.ia.yt = outbb->ymax;
+#if VERSION_BEFORE_20140902
+ bmeo.mode =
+ bmeo.szmode =
+ bmeo.dr = DK3_BMEPS_DRIVER_EPS;
+#else
+ bmeo.mode = DK3_BMEPS_MODE_OBJECT;
+ bmeo.szmode = DK3_BMEPS_SIZE_1_1; $? ". szmode = 1:1"
+ bmeo.dr = DK3_BMEPS_DRIVER_EPS;
+#endif
+ bmeo.io = drawdir;
+ bmeo.psl = pslevel;
+ job.bif = dk3bif_open_c8_filename_app(sfn,DK3_BIF_IMAGE_TYPE_UNKNOWN,app);
+ if(job.bif) { $? ". bif opened"
+ job.biftype = dk3bif_get_type(job.bif);
+ /* job.procedure = */ $? ". bif type = %d", job.biftype
+ /* job->x_size */
+ /* job->y_size */
+ /* job->x_0 */
+ /* job->x_1 */
+ /* job->y_0 */
+ /* job->y_1 */
+ /* job->procedure */
+ /* job->bpc */
+ /* job->nPages */
+ /* job->currentPage */
+ if(dk3bm_find_bif_transformation(&trans, job.bif, outbb, drawdir, ec)) {
+ /* FIG2LAT */ $? ". transformations found"
+ job.x_translate = trans.x_translate;
+ job.y_translate = trans.y_translate;
+ job.x_scale = trans.x_scale;
+ job.y_scale = trans.y_scale;
+ job.do_rotate = trans.rot;
+ job.do_translate = 1;
+ job.do_float_scale = 1; $? ". going to produce image data"
+ if(dk3bif_read_data(job.bif)) {
+ back = dk3bm_job_produce_img_job_real_ps(&job);
+ } else {
+ /* ##### ERROR: Failed to read image data! */
+ }
+ } else {
+ /* ##### ERROR: Failed to calculate transformation data */
+ }
+ dk3bif_close(job.bif);
+ } else { $? "! failed to open image"
+ /* ##### ERROR: Failed to open image */
+ }
+ } else { $? "! arguments"
+ } $? "- dk3bm_ps_place_object %d", back
+ return back;
+}
+
+
+
+/** Paper size check function.
+ @param ps Paper size to check.
+ @return 1 on success, 0 on error (borders larger than paper).
+*/
+static
+int
+dk3bm_check_paper_size(dk3_paper_size_t *ps)
+{
+ int back = 0;
+ $? "+ dk3bm_check_paper_size"
+ if(ps->w > (ps->i + ps->o)) {
+ if(ps->h > (ps->t + ps->b)) {
+ back = 1;
+ }
+ } $? "- dk3bm_check_paper_size %d", back
+ return back;
+}
+
+
+
+/** Produce PS draft for image or object.
+ The x_0, x_1, y_0 and y_1 values must be set.
+ @param job Conversion job.
+ @return 1 on succes, 0 on error.
+*/
+static
+int
+dk3bm_job_produce_img_job_draft_ps(dk3_bm_conversion_job_t *job)
+{
+ char outputbuffer[256]; /* Conversion buffer for numbers. */
+ double dx; /* Stripe width. */
+ double dy; /* Stripe width backup. */
+ int back = 0;
+ $? "+ dk3bm_job_produce_img_job_draft_ps"
+ dk3bm_ps_document_header(job, job->nPages);
+ fputs(dk3bm_c8_kw[4], job->dfile);
+ fputs(dk3bm_c8_kw[21], job->dfile);
+ fputs(dk3bm_c8_kw[71], job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[72], job->x_0, job->y_0);
+ dk3bm_correct_output_buffer(outputbuffer);
+ fputs(outputbuffer, job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[73], job->x_1, job->y_0);
+ dk3bm_correct_output_buffer(outputbuffer);
+ fputs(outputbuffer, job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[73], job->x_1, job->y_1);
+ dk3bm_correct_output_buffer(outputbuffer);
+ fputs(outputbuffer, job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[73], job->x_0, job->y_1);
+ dk3bm_correct_output_buffer(outputbuffer);
+ fputs(outputbuffer, job->dfile);
+ fputs(dk3bm_c8_kw[74], job->dfile);
+ dx = 0.01 * (job->x_1 - job->x_0);
+ dy = 0.01 * (job->y_1 - job->y_0);
+ if(dy < dx) dx = dy;
+ if(dx > 2.8) dx = 2.8;
+ fputs(dk3bm_c8_kw[75], job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[72], job->x_0+dx, job->y_0+dx);
+ dk3bm_correct_output_buffer(outputbuffer);
+ fputs(outputbuffer, job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[73], job->x_1-dx, job->y_0+dx);
+ dk3bm_correct_output_buffer(outputbuffer);
+ fputs(outputbuffer, job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[73], job->x_1-dx, job->y_1-dx);
+ dk3bm_correct_output_buffer(outputbuffer);
+ fputs(outputbuffer, job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[73], job->x_0+dx, job->y_1-dx);
+ dk3bm_correct_output_buffer(outputbuffer);
+ fputs(outputbuffer, job->dfile);
+ fputs(dk3bm_c8_kw[74], job->dfile);
+ dx = 10.0 * dx;
+ fputs(dk3bm_c8_kw[76], job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[72], job->x_0+dx, job->y_0+dx);
+ dk3bm_correct_output_buffer(outputbuffer);
+ fputs(outputbuffer, job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[73], job->x_1-dx, job->y_0+dx);
+ dk3bm_correct_output_buffer(outputbuffer);
+ fputs(outputbuffer, job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[73], job->x_1-dx, job->y_1-dx);
+ dk3bm_correct_output_buffer(outputbuffer);
+ fputs(outputbuffer, job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[73], job->x_0+dx, job->y_1-dx);
+ dk3bm_correct_output_buffer(outputbuffer);
+ fputs(outputbuffer, job->dfile);
+ fputs(dk3bm_c8_kw[74], job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[77], 0.9 * dx);
+ dk3bm_correct_output_buffer(outputbuffer);
+ fputs(outputbuffer, job->dfile);
+ fputs(dk3bm_c8_kw[75], job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[72], job->x_0+dx, job->y_0+dx);
+ dk3bm_correct_output_buffer(outputbuffer);
+ fputs(outputbuffer, job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[73], job->x_1-dx, job->y_1-dx);
+ dk3bm_correct_output_buffer(outputbuffer);
+ fputs(outputbuffer, job->dfile);
+ fputs(dk3bm_c8_kw[79], job->dfile);
+ fputs(dk3bm_c8_kw[78], job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[72], job->x_0+dx, job->y_1-dx);
+ dk3bm_correct_output_buffer(outputbuffer);
+ fputs(outputbuffer, job->dfile);
+ sprintf(outputbuffer, dk3bm_c8_kw[73], job->x_1-dx, job->y_0+dx);
+ dk3bm_correct_output_buffer(outputbuffer);
+ fputs(outputbuffer, job->dfile);
+ fputs(dk3bm_c8_kw[79], job->dfile);
+ fputs(dk3bm_c8_kw[5], job->dfile);
+ switch((job->opt)->mode) {
+ case DK3_BMEPS_MODE_IMAGE:
+ case DK3_BMEPS_MODE_DOCUMENT: {
+ if((job->opt)->dr == DK3_BMEPS_DRIVER_PS) {
+ fputs(dk3bm_c8_kw[6], job->dfile); /* showpage */
+ }
+ } break;
+ }
+ dk3bm_ps_document_footer(job);
+ $? "- dk3bm_job_produce_img_job_draft_ps %d", back
+ return back;
+}
+
+
+
+/** Do the real work when producing a PS document.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bm_job_produce_doc_real_ps(dk3_bm_conversion_job_t *job)
+{
+ double dmaxwidth = 0.0; /* Max width PS points. */
+ double dmaxheight = 0.0; /* Max height PS points. */
+ double xres; /* X res current frame. */
+ double yres; /* Y res current frame. */
+ double deltax; /* Real x width. */
+ double deltay; /* Real y width. */
+ double sx; /* Scale factor x. */
+ double sy; /* Scale factor y. */
+ dk3_bif_coord_t maxwidth = 0L; /* Max width pixels. */
+ dk3_bif_coord_t maxheight = 0L; /* Max height pixels. */
+ dk3_bif_coord_t w; /* Current frame width. */
+ dk3_bif_coord_t h; /* Current frame height. */
+ size_t nFrames; /* Number of frames. */
+ size_t cf; /* Current frame. */
+ int me = 0; /* Math error. */
+ int workmode = 0; /* Transformation mode. */
+ int back = 1;
+ int must_rotate = 0; /* Flag: Must rotate. */
+#if DK3_USE_WX
+ int minpb; /* Original min progress bar value. */
+ int maxpb; /* Original max progress bar value. */
+#endif
+ $? "+ dk3bm_job_produce_doc_real_p2"
+#if DK3_USE_WX
+ minpb = job->minpb;
+ maxpb = job->maxpb;
+#endif
+ switch((job->opt)->szmode) {
+ case DK3_BMEPS_SIZE_1_1: { $? ". szmode: 1:1"
+ workmode = 0;
+ } break;
+ case DK3_BMEPS_SIZE_CHUNK: case DK3_BMEPS_SIZE_SPECIFIED: {
+ workmode = 1; $? ". szmode: chunk/specified"
+ } break;
+ case DK3_BMEPS_SIZE_PAPER: { $? ". szmode: paper size"
+ workmode = 2;
+ if(!dk3bm_check_paper_size(&(((job->opt)->ima).ps))) {
+ back = 0;
+ /* ERROR: Incorrect paper size setup! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 62, DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ } break;
+ }
+ if(back) {
+ nFrames = dk3bif_number_of_frames(job->bif);
+ for(cf = 0; cf < nFrames; cf++) {
+ dk3bif_set_frame(job->bif, cf);
+ job->currentPage = cf + 1;
+ w = dk3bif_get_width(job->bif);
+ h = dk3bif_get_height(job->bif);
+ if(w > maxwidth) { maxwidth = w; }
+ if(h > maxheight) { maxheight = h; }
+ if(workmode == 1) {
+ switch((job->opt)->szmode) {
+ case DK3_BMEPS_SIZE_SPECIFIED: { $? ". szmode: specified"
+ xres = yres = (job->opt)->resolution;
+ } break;
+ default: { $? ". szmode: other"
+ xres = dk3bif_get_xres(job->bif);
+ yres = dk3bif_get_yres(job->bif);
+ } break;
+ }
+ if(xres <= 0.0) { xres = 72.0; }
+ if(yres <= 0.0) { yres = 72.0; }
+ if(fabs(xres - 72.0) > dk3bm_epsilon) {
+ deltax = dk3ma_d_mul_ok(
+ 72.0,
+ dk3ma_d_div_ok(dk3bm_l_to_d(w), xres, &me),
+ &me
+ );
+ } else {
+ deltax = dk3bm_l_to_d(w);
+ }
+ if(fabs(yres - 72.0) > dk3bm_epsilon) {
+ deltay = dk3ma_d_mul_ok(
+ 72.0,
+ dk3ma_d_div_ok(dk3bm_l_to_d(h), yres, &me),
+ &me
+ );
+ } else {
+ deltay = dk3bm_l_to_d(h);
+ }
+ if(deltax > dmaxwidth) { dmaxwidth = deltax; }
+ if(deltay > dmaxheight) { dmaxheight = deltay; }
+ }
+ }
+ switch(workmode) {
+ case 0: {
+ job->x_size = maxwidth;
+ job->y_size = maxheight;
+ } break;
+ case 1: {
+ dmaxwidth = ceil(dmaxwidth);
+ dmaxheight = ceil(dmaxheight);
+ job->x_size = dk3ma_d_to_l_ok(dmaxwidth, &me);
+ job->y_size = dk3ma_d_to_l_ok(dmaxheight, &me);
+ } break;
+ case 2: {
+ job->x_size = dk3ma_d_to_l_ok(floor(((job->opt)->ima).ps.w), &me);
+ job->y_size = dk3ma_d_to_l_ok(floor(((job->opt)->ima).ps.h), &me);
+ } break;
+ }
+ /*
+ Produce output.
+ */
+ if(back) {
+ job->nPages = nFrames;
+ dk3bm_ps_document_header(job, job->nPages);
+ job->do_header_footer = 0;
+ for(cf = 0; cf < nFrames; cf++) {
+#if DK3_USE_WX
+ job->minpb = minpb + (int)cf * (maxpb - minpb) / (int)nFrames;
+ job->maxpb = minpb + (1 + (int)cf) * (maxpb - minpb) / (int)nFrames;
+ if(job->minpb < minpb) { job->minpb = minpb; }
+ if(job->maxpb > maxpb) { job->maxpb = maxpb; }
+#endif
+ dk3bif_set_frame(job->bif, cf);
+ w = dk3bif_get_width(job->bif);
+ h = dk3bif_get_height(job->bif);
+ job->currentPage = cf + 1;
+ job->x_translate = 0.0;
+ job->y_translate = 0.0;
+ job->x_0 = 0.0;
+ job->y_0 = 0.0;
+ job->x_1 = 0.0;
+ job->y_1 = 0.0;
+ job->x_scale = 1.0;
+ job->y_scale = 1.0;
+ job->do_translate = 0;
+ job->do_float_scale = 0;
+ job->do_rotate = 0;
+ must_rotate = 0;
+ switch(workmode) {
+ case 0: {
+ if(w < maxwidth) {
+ job->x_translate = 0.5 * dk3bm_l_to_d(maxwidth - w);
+ job->do_translate = 1;
+ }
+ if(h < maxheight) {
+ job->y_translate = 0.5 * dk3bm_l_to_d(maxheight - h);
+ job->do_translate = 1;
+ }
+ if(job->do_translate) {
+ job->x_scale = dk3bm_l_to_d(w);
+ job->y_scale = dk3bm_l_to_d(h);
+ job->do_float_scale = 1;
+ }
+ } break;
+ case 1: {
+ job->do_float_scale = 1;
+ job->do_translate = 1;
+ switch((job->opt)->szmode) {
+ case DK3_BMEPS_SIZE_SPECIFIED: { $? ". szmode: specified"
+ xres = yres = (job->opt)->resolution;
+ } break;
+ default: { $? ". szmode: other"
+ xres = dk3bif_get_xres(job->bif);
+ yres = dk3bif_get_yres(job->bif);
+ } break;
+ }
+ if(xres <= 0.0) { xres = 72.0; }
+ if(yres <= 0.0) { yres = 72.0; }
+ if(fabs(xres - 72.0) > dk3bm_epsilon) {
+ deltax = dk3ma_d_mul_ok(
+ 72.0,
+ dk3ma_d_div_ok(dk3bm_l_to_d(w), xres, &me),
+ &me
+ );
+ } else {
+ deltax = dk3bm_l_to_d(w);
+ }
+ if(fabs(yres - 72.0) > dk3bm_epsilon) {
+ deltay = dk3ma_d_mul_ok(
+ 72.0,
+ dk3ma_d_div_ok(dk3bm_l_to_d(h), yres, &me),
+ &me
+ );
+ } else {
+ deltay = dk3bm_l_to_d(h);
+ }
+ job->x_scale = deltax;
+ job->y_scale = deltay;
+ job->x_translate = 0.5 * (dmaxwidth - deltax);
+ job->y_translate = 0.5 * (dmaxheight - deltay);
+ } break;
+ case 2: {
+ job->do_float_scale = 1;
+ job->do_translate = 1;
+ if((job->opt)->duplex) {
+ if((job->opt)->tumble) {
+ if((job->currentPage) % 2) {
+ job->y_0 = ((job->opt)->ima).ps.b;
+ job->y_1 = ((job->opt)->ima).ps.h - ((job->opt)->ima).ps.t;
+ } else {
+ job->y_0 = ((job->opt)->ima).ps.t;
+ job->y_1 = ((job->opt)->ima).ps.h - ((job->opt)->ima).ps.b;
+ }
+ job->x_0 = ((job->opt)->ima).ps.i;
+ job->x_1 = ((job->opt)->ima).ps.w - ((job->opt)->ima).ps.o;
+ } else {
+ if((job->currentPage) % 2) {
+ job->x_0 = ((job->opt)->ima).ps.i;
+ job->x_1 = ((job->opt)->ima).ps.w - ((job->opt)->ima).ps.o;
+ } else {
+ job->x_0 = ((job->opt)->ima).ps.o;
+ job->x_1 = ((job->opt)->ima).ps.w - ((job->opt)->ima).ps.i;
+ }
+ job->y_0 = ((job->opt)->ima).ps.b;
+ job->y_1 = ((job->opt)->ima).ps.h - ((job->opt)->ima).ps.t;
+ }
+ } else {
+ job->x_0 = ((job->opt)->ima).ps.i;
+ job->x_1 = ((job->opt)->ima).ps.w - ((job->opt)->ima).ps.o;
+ job->y_0 = ((job->opt)->ima).ps.b;
+ job->y_1 = ((job->opt)->ima).ps.h - ((job->opt)->ima).ps.t;
+ }
+ xres = dk3bif_get_xres(job->bif);
+ yres = dk3bif_get_yres(job->bif);
+ if(xres <= 0.0) xres = 72.0;
+ if(yres <= 0.0) yres = 72.0;
+ if(fabs(xres - 72.0) > dk3bm_epsilon) {
+ deltax = dk3ma_d_mul_ok(
+ 72.0,
+ dk3ma_d_div_ok(dk3bm_l_to_d(w), xres, &me),
+ &me
+ );
+ } else {
+ deltax = dk3bm_l_to_d(w);
+ }
+ if(fabs(yres - 72.0) > dk3bm_epsilon) {
+ deltay = dk3ma_d_mul_ok(
+ 72.0,
+ dk3ma_d_div_ok(dk3bm_l_to_d(h), yres, &me),
+ &me
+ );
+ } else {
+ deltay = dk3bm_l_to_d(h);
+ }
+ if((job->y_1 - job->y_0) > (job->x_1 - job->x_0)) {
+ if(deltax > deltay) {
+ must_rotate = 1;
+ }
+ } else {
+ if((job->y_1 - job->y_0) < (job->x_1 - job->x_0)) {
+ if(deltax > deltay) {
+ must_rotate = 1;
+ }
+ }
+ }
+ if(must_rotate) {
+ job->do_rotate = 1;
+ sx = dk3ma_d_div_ok((job->y_1 - job->y_0), deltax, &me);
+ sy = dk3ma_d_div_ok((job->x_1 - job->x_0), deltay, &me);
+ if(sx < sy) {
+ job->x_scale = job->y_1 - job->y_0;
+ job->y_scale = dk3ma_d_mul_ok(sx, deltay, &me);
+ job->x_translate = job->x_1 - 0.5 * (job->x_1 - job->x_0 - job->y_scale);
+ job->y_translate = job->y_0;
+ } else {
+ job->y_scale = job->x_1 - job->x_0;
+ job->x_scale = dk3ma_d_mul_ok(sy, deltax, &me);
+ job->x_translate = job->x_1;
+ job->y_translate = job->y_0 + 0.5 * (job->y_1 - job->y_0 - job->x_scale);
+ }
+ } else {
+ sx = dk3ma_d_div_ok((job->x_1 - job->x_0), deltax, &me);
+ sy = dk3ma_d_div_ok((job->y_1 - job->y_0), deltay, &me);
+ if(sx < sy) {
+ job->x_scale = job->x_1 - job->x_0;
+ job->y_scale = dk3ma_d_mul_ok(sx, deltay, &me);
+ job->x_translate = job->x_0;
+ job->y_translate = job->y_0 + 0.5 * (job->y_1 - job->y_0 - job->y_scale);
+ } else {
+ job->y_scale = job->y_1 - job->y_0;
+ job->x_scale = dk3ma_d_mul_ok(sy, deltax, &me);
+ job->y_translate = job->y_0;
+ job->x_translate = job->x_0 + 0.5 * (job->x_1 - job->x_0 - job->x_scale);
+ }
+ }
+ $? ". x_scale = %lg", job->x_scale
+ $? ". y_scale = %lg", job->y_scale
+ $? ". x_translate = %lg", job->x_translate
+ $? ". y_translate = %lg", job->y_translate
+ $? ". do_rotate = %d", job->do_rotate
+ } break;
+ }
+ /*
+ Output current frame.
+ */
+ if(back) {
+ if(!dk3bm_job_produce_img_job_real_ps(job)) {
+ back = 0;
+ }
+ }
+#if DK3_USE_WX
+ dk3bmj_progress(job->pComm, job->maxpb);
+#endif
+ }
+ dk3bm_ps_document_footer(job);
+ }
+ }
+#if DK3_USE_WX
+ job->minpb = minpb;
+ job->maxpb = maxpb;
+#endif
+ $? "- dk3bm_job_produce_doc_real_ps %d", back
+ return back;
+}
+
+
+
+/** Produce PS document.
+ @param job Conversion job.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bm_job_produce_doc_ps(dk3_bm_conversion_job_t *job)
+{
+ int back = 0;
+#if DK3_USE_WX
+ int min; /* Original min progress bar value. */
+ int max; /* Original max progress bar value. */
+#endif
+ /* PROGRESS: Reading image. */
+ $? "+ dk3bm_job_produce_doc_ps"
+ dk3app_log_1((job->opt)->app, DK3_LL_PROGRESS, job->msg, 47);
+#if DK3_USE_WX
+ min = job->minpb;
+ max = job->maxpb;
+#endif
+ if(dk3bif_read_data(job->bif)) { $? ". image ok"
+#if DK3_USE_WX
+ $? ". 1/3"
+ dk3bmj_progress(job->pComm, job->minpb + (job->maxpb - job->minpb)/3);
+ job->minpb = job->minpb + ((job->maxpb - job->minpb)/3);
+#endif
+ if(job->dfile) {
+ back = dk3bm_job_produce_doc_real_ps(job);
+ } else {
+ job->dfile = dk3sf_fopen_app(
+ job->dfn,
+ dk3app_not_localized(24),
+ (job->opt)->app
+ );
+ if(job->dfile) {
+ back = dk3bm_job_produce_doc_real_ps(job);
+ if(!dk3sf_fclose_fn_app(job->dfile, job->dfn, (job->opt)->app)) {
+ back = 0;
+ }
+ job->dfile = NULL;
+ } else {
+ /* ERROR: Failed to open output file! */
+ dk3bmj_log_i3(
+ (job->opt)->app, DK3_LL_ERROR, 77, 78, job->dfn, DK3_BMJ_LOG_JOB, job
+ );
+ }
+ }
+ } else { $? "! failed to read image"
+ /* ERROR: Failed to read image data! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 61, DK3_BMJ_LOG_BOTH, job
+ );
+ }
+#if DK3_USE_WX
+ job->minpb = min;
+ job->maxpb = max;
+#endif
+ $? "- dk3bm_job_produce_doc_ps %d", back
+ return back;
+}
+
+
+
+/** Produce PS image or object.
+ @param job Conversion job.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bm_job_produce_img_obj_ps(dk3_bm_conversion_job_t *job)
+{
+ double w; /* Image width used. */
+ double h; /* Image height used. */
+ double xr = 0.0; /* X resolution. */
+ double yr = 0.0; /* Y resolution. */
+ int back = 1;
+ int ur = 0; /* Flag: Use resolution. */
+ int ec = 0; /* Math error code. */
+ $? "+ dk3bm_job_produce_img_obj_ps"
+ /*
+ Prepare for size 1:1.
+ */
+ job->x_size = dk3bif_get_width(job->bif);
+ job->y_size = dk3bif_get_height(job->bif);
+ job->x_1 = dk3bm_l_to_d(job->x_size);
+ job->y_1 = dk3bm_l_to_d(job->y_size);
+ $? ". w=%ld h=%ld", job->x_size, job->y_size
+ /*
+ Attempt to use other size/resolution if required.
+ */
+ switch((job->opt)->szmode) {
+ case DK3_BMEPS_SIZE_CHUNK: { $? ". szmode: chunk"
+ xr = dk3bif_get_xres(job->bif);
+ yr = dk3bif_get_yres(job->bif); $? ". xr=%lg yr=%lg", xr, yr
+ if((xr > 0.0) && (yr > 0.0)) {
+ $? ". rounding error = %lg", fabs(xr - 72.0)
+ if(fabs(xr - 72.0) > dk3bm_epsilon) {
+ ur = 1;
+ }
+ $? ". rounding error = %lg", fabs(yr - 72.0)
+ if(fabs(yr - 72.0) > dk3bm_epsilon) {
+ ur = 1;
+ }
+ }
+ } break;
+ case DK3_BMEPS_SIZE_SPECIFIED: { $? ". szmode: specified"
+ if((job->opt)->resolution > 0.0) {
+ $? ". rounding error = %lg", fabs((job->opt)->resolution - 72.0)
+ if(fabs((job->opt)->resolution - 72.0) > dk3bm_epsilon) {
+ xr = yr = (job->opt)->resolution; $? ". xr=%lg yr=%lg", xr, yr
+ ur = 1;
+ }
+ }
+ } break;
+ }
+ /*
+ If we have to use a resolution, calculate dimensions.
+ */
+ if(ur) { $? ". must use resolution"
+ w = dk3bm_l_to_d(job->x_size); $? ". w=%ld h=%ld", job->x_size, job->y_size
+ h = dk3bm_l_to_d(job->y_size); $? ". w=%lg h=%lg", w, h
+ w = dk3ma_d_mul_ok(72.0, dk3ma_d_div_ok(w, xr, &ec), &ec);
+ h = dk3ma_d_mul_ok(72.0, dk3ma_d_div_ok(h, yr, &ec), &ec);
+ job->x_1 = ceil(w); $? ". w=%lg h=%lg", w, h
+ job->y_1 = ceil(h);
+ job->x_size = dk3ma_d_to_l_ok(job->x_1, &ec);
+ job->y_size = dk3ma_d_to_l_ok(job->y_1, &ec);
+ $? ". w=%ld h=%ld", job->x_size, job->y_size
+ job->x_translate = 0.5 * (job->x_1 - w);
+ job->y_translate = 0.5 * (job->y_1 - h);
+ if(job->x_translate < 0.0) { job->x_translate = 0.0; }
+ if(job->y_translate < 0.0) { job->y_translate = 0.0; }
+ job->do_translate = 1;
+ job->x_0 = job->x_translate;
+ job->y_0 = job->y_translate;
+ job->x_1 = job->x_0 + w;
+ job->y_1 = job->y_0 + h;
+ if(job->x_1 > dk3bm_l_to_d(job->x_size)) {
+ job->x_1 = dk3bm_l_to_d(job->x_size);
+ }
+ if(job->y_1 > dk3bm_l_to_d(job->y_size)) {
+ job->y_1 = dk3bm_l_to_d(job->y_size);
+ }
+ job->x_scale = w;
+ job->y_scale = h;
+ job->do_float_scale = 1;
+ $? ". x0 = %lg", job->x_0
+ $? ". x1 = %lg", job->x_1
+ $? ". y0 = %lg", job->y_0
+ $? ". y1 = %lg", job->y_1
+ $? ". xt = %lg", job->x_translate
+ $? ". yt = %lg", job->y_translate
+ $? ". xs = %lg", job->x_scale
+ $? ". ys = %lg", job->y_scale
+ $? ". w = %ld", job->x_size
+ $? ". h = %ld", job->y_size
+ if(ec) { $? ". math error"
+ back = 0;
+ dk3bmj_log_i1(
+ (job->opt)->app, DK3_LL_ERROR, 260, DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ }
+ /*
+ If no error yet, go on.
+ */
+ if(back) {
+ if((job->opt)->draft) { $? ". draft"
+ if(job->dfile) { $? ". file already set"
+ back = dk3bm_job_produce_img_job_draft_ps(job);
+ } else { $? ". must open output"
+ job->dfile = dk3sf_fopen_app(
+ job->dfn,
+ dk3app_not_localized(24),
+ (job->opt)->app
+ );
+ if(job->dfile) { $? ". output ok"
+ back = dk3bm_job_produce_img_job_draft_ps(job);
+ if(!dk3sf_fclose_fn_app(job->dfile, job->dfn, (job->opt)->app)) {
+ back = 0;
+ }
+ job->dfile = NULL;
+ } else { $? "! failed to open output"
+ back = 0;
+ /* ERROR: Failed to open output file! */
+ dk3bmj_log_i3(
+ (job->opt)->app, DK3_LL_ERROR, 77, 78, job->dfn,
+ DK3_BMJ_LOG_JOB, job
+ );
+ }
+ }
+ } else { $? ". real image"
+ /* PROGRESS: Reading image. */
+ dk3app_log_1((job->opt)->app, DK3_LL_PROGRESS, job->msg, 47);
+ if(dk3bif_read_data(job->bif)) { $? ". image ok"
+#if DK3_USE_WX
+ $? ". 1/3"
+ dk3bmj_progress(job->pComm, job->minpb + (job->maxpb - job->minpb)/3);
+ job->minpb = job->minpb + ((job->maxpb - job->minpb)/3);
+#endif
+ if(job->dfile) { $? ". file already set"
+ back = dk3bm_job_produce_img_job_real_ps(job);
+ } else { $? ". must open output"
+ job->dfile = dk3sf_fopen_app(
+ job->dfn,
+ dk3app_not_localized(24),
+ (job->opt)->app
+ );
+ if(job->dfile) { $? ". output ok"
+ back = dk3bm_job_produce_img_job_real_ps(job);
+ if(!dk3sf_fclose_fn_app(job->dfile, job->dfn, (job->opt)->app)) {
+ back = 0;
+ }
+ job->dfile = NULL;
+ } else { $? "! failed to open output"
+ back = 0;
+ /* ERROR: Failed to open output file! */
+ dk3bmj_log_i3(
+ (job->opt)->app, DK3_LL_ERROR, 77, 78, job->dfn,
+ DK3_BMJ_LOG_JOB, job
+ );
+ }
+ }
+ } else { $? "! failed to read image"
+ back = 0;
+ /* ERROR: Failed to read image data! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 61, DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ }
+ } $? "- dk3bm_job_produce_img_obj_ps %d", back
+ return back;
+}
+
+
+
+/** Produce PS/EPS output.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bm_job_produce_ps(dk3_bm_conversion_job_t *job)
+{
+ int back = 0;
+ $? "+ dk3bm_job_produce_ps"
+ switch((job->opt)->mode) {
+ case DK3_BMEPS_MODE_DOCUMENT: { $? ". document"
+ back = dk3bm_job_produce_doc_ps(job);
+ } break;
+ default: { $? ". image or object"
+ back = dk3bm_job_produce_img_obj_ps(job);
+ } break;
+ } $? "- dk3bm_job_produce_ps %d", back
+ return back;
+}
+
+
+
+/** Add one image frame as output page.
+ @param job Conversion job.
+ @param pageno Page number of frame to add.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bm_job_add_pdf_frame(dk3_bm_conversion_job_t *job, size_t pageno)
+{
+ dk3_bif_coord_t w; /* Image width. */
+ dk3_bif_coord_t h; /* Image height. */
+ double xres = 0.0; /* X resolution. */
+ double yres = 0.0; /* Y resolution. */
+ double dw; /* Image width on paper. */
+ double dh; /* Image height on paper. */
+ double px0; /* Left x (paper). */
+ double px1; /* Right x (paper). */
+ double py0; /* Lower y (paper). */
+ double py1; /* Upper y (paper). */
+ double width; /* Paper width. */
+ double height; /* Paper height. */
+ double sx; /* Scale factor for x direction. */
+ double sy; /* Scale factor for y direction. */
+ long mbx0; /* Left x (media box). */
+ long mbx1; /* Right x (media box). */
+ long mby0; /* Lower y (media box). */
+ long mby1; /* Upper y (media box). */
+ int workmode; /* Transformation mode. */
+ int back = 1;
+ int me = 0; /* Flag: Math error. */
+ $? "+ dk3bm_job_add_pdf_frame %!8s min=%d max=%d", TR_8PTR(job->pComm), job->minpb, job->maxpb
+ /*
+ Re-initialize (we probably have to handle multiple frames in one job.
+ */
+ job->x_translate = 0.0;
+ job->y_translate = 0.0;
+ job->x_scale = 1.0;
+ job->y_scale = 1.0;
+ job->x_0 = 0.0;
+ job->x_1 = 0.0;
+ job->y_0 = 0.0;
+ job->y_1 = 0.0;
+ job->x_size = 0L;
+ job->y_size = 0L;
+ job->bpc = 8;
+ job->do_translate = 0;
+ job->do_rotate = 0;
+ job->do_float_scale = 0;
+ job->procedure = 0;
+ workmode = 0;
+ mbx0 = mbx1 = mby0 = mby1 = 0L;
+ /*
+ Process image width, height and resolution.
+ */
+ w = dk3bif_get_width(job->bif);
+ h = dk3bif_get_height(job->bif);
+ switch((job->opt)->szmode) {
+ case DK3_BMEPS_SIZE_CHUNK: { $? ". szmode: chunk"
+ xres = dk3bif_get_xres(job->bif);
+ yres = dk3bif_get_yres(job->bif);
+ if(xres > 0.0) {
+ if(yres > 0.0) {
+ if((fabs(xres - 72.0) > dk3bm_epsilon)
+ || (fabs(yres - 72.0) > dk3bm_epsilon))
+ {
+ workmode = 1;
+ }
+ }
+ }
+ } break;
+ case DK3_BMEPS_SIZE_SPECIFIED: { $? ". szmode: specified"
+ xres = yres = (job->opt)->resolution;
+ if(xres > 0.0) {
+ if(fabs(xres - 72.0) > dk3bm_epsilon) {
+ workmode = 1;
+ }
+ }
+ } break;
+ case DK3_BMEPS_SIZE_PAPER: { $? ". szmode: paper"
+ workmode = 2;
+ xres = dk3bif_get_xres(job->bif);
+ yres = dk3bif_get_yres(job->bif);
+ if(xres <= 0.0) { xres = 72.0; }
+ if(yres <= 0.0) { yres = 72.0; }
+ if(fabs(xres - 72.0) <= dk3bm_epsilon) {
+ xres = 72.0;
+ }
+ if(fabs(yres - 72.0) <= dk3bm_epsilon) {
+ yres = 72.0;
+ }
+ } break;
+ default: { $? ". szmode: 1:1"
+ workmode = 0;
+ } break;
+ }
+ switch(workmode) {
+ case 2: {
+ dw = dk3ma_d_mul_ok(
+ 72.0,
+ dk3ma_d_div_ok(dk3bm_l_to_d(w), xres, &me),
+ &me
+ );
+ dh = dk3ma_d_mul_ok(
+ 72.0,
+ dk3ma_d_div_ok(dk3bm_l_to_d(h), yres, &me),
+ &me
+ ); $? ". dw=%lg dh=%lg", dw, dh
+ if(dk3bm_check_paper_size(&(((job->opt)->ima).ps))) {
+ width = floor(((job->opt)->ima).ps.w);
+ height = floor(((job->opt)->ima).ps.h);
+ $? ". width=%lg", width
+ $? ". height=%lg", height
+ mbx1 = dk3ma_d_to_l_ok(width, &me);
+ mby1 = dk3ma_d_to_l_ok(height, &me);
+ if((job->opt)->duplex) {
+ if((job->opt)->tumble) {
+ if(pageno % 2) { /* Rueckseite */
+ px0 = ((job->opt)->ima).ps.i;
+ px1 = width - ((job->opt)->ima).ps.o;
+ py0 = ((job->opt)->ima).ps.t;
+ py1 = height - ((job->opt)->ima).ps.b;
+ } else { /* Vorderseite */
+ px0 = ((job->opt)->ima).ps.i;
+ px1 = width - ((job->opt)->ima).ps.o;
+ py0 = ((job->opt)->ima).ps.b;
+ py1 = height - ((job->opt)->ima).ps.t;
+ }
+ } else {
+ if(pageno % 2) { /* Rueckseite */
+ px0 = ((job->opt)->ima).ps.o;
+ px1 = width - ((job->opt)->ima).ps.i;
+ py0 = ((job->opt)->ima).ps.b;
+ py1 = height - ((job->opt)->ima).ps.t;
+ } else { /* Vorderseite */
+ px0 = ((job->opt)->ima).ps.i;
+ px1 = width - ((job->opt)->ima).ps.o;
+ py0 = ((job->opt)->ima).ps.b;
+ py1 = height - ((job->opt)->ima).ps.t;
+ }
+ }
+ } else {
+ px0 = ((job->opt)->ima).ps.i;
+ px1 = width - ((job->opt)->ima).ps.o;
+ py0 = ((job->opt)->ima).ps.b;
+ py1 = height - ((job->opt)->ima).ps.t;
+ }
+ if((px1 > px0) && (py1 > py0)) {
+ if((py1 - py0) > (px1 - px0)) { $? ". paper is portrait"
+ if(dw > dh) { $? ". image is landscape, rot"
+ job->do_rotate = 1;
+ } else { $? ". image is portrait"
+ }
+ } else { $? ". paper is prob landscape"
+ if((py1 - py0) < (px1 - px0)) { $? ". paper is landscape"
+ if(dh > dw) { $? ". image is portrait"
+ job->do_rotate = 1;
+ } else {
+ }
+ }
+ }
+ $? ". px0 = %lg", px0
+ $? ". px1 = %lg", px1
+ $? ". py0 = %lg", py0
+ $? ". py1 = %lg", py1
+ if(job->do_rotate) { $? ". rotate"
+ sx = dk3ma_d_div_ok((py1 - py0), dw, &me);
+ sy = dk3ma_d_div_ok((px1 - px0), dh, &me);
+ if(sx > sy) { $? ". x factor too large"
+ job->y_scale = (px1 - px0);
+ job->x_scale = sy * dw;
+ job->x_translate = px1;
+ job->y_translate = py0 + 0.5 * (py1 - py0 - job->x_scale);
+ if(job->y_translate < py0) { job->y_translate = py0; }
+ } else { $? ". y factor too large"
+ job->x_scale = (py1 - py0);
+ job->y_scale = sx * dh;
+ job->x_translate = px1 - 0.5 * (px1 - px0 - job->y_scale);
+ if(job->x_translate > px1) { job->x_translate = px1; }
+ job->y_translate = py0;
+ }
+ } else { $? ". no rotation"
+ sx = dk3ma_d_div_ok((px1 - px0), dw, &me);
+ sy = dk3ma_d_div_ok((py1 - py0), dh, &me);
+ if(sx > sy) { $? ". x factor too large"
+ job->y_scale = py1 - py0;
+ job->x_scale = sy * dw;
+ job->x_translate = px0 + 0.5 * (px1 - px0 - job->x_scale);
+ if(job->x_translate < px0) { job->x_translate = px0; }
+ job->y_translate = py0;
+ } else { $? ". y factor too large"
+ job->x_scale = px1 - px0;
+ job->y_scale = sx * dh;
+ job->y_translate = py0 + 0.5 * (py1 - py0 - job->y_scale);
+ if(job->y_translate < py0) { job->y_translate = py0; }
+ job->x_translate = px0;
+ }
+ }
+ job->do_translate = 1;
+ job->do_float_scale = 1;
+ } else { $? "! page setup"
+ back = 0;
+ /* ERROR Page setup incorrect */
+ dk3bmj_log_i1(
+ (job->opt)->app, DK3_LL_ERROR, 259,
+ DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ } else {
+ back = 0;
+ }
+ $? ". x_scale = %lg", job->x_scale
+ $? ". y_scale = %lg", job->y_scale
+ $? ". x_translate = %lg", job->x_translate
+ $? ". y_translate = %lg", job->y_translate
+ $? ". do_rotate = %d", job->do_rotate
+ } break;
+ case 1: {
+ dw = dk3ma_d_mul_ok(
+ 72.0,
+ dk3ma_d_div_ok(dk3bm_l_to_d(w), xres, &me),
+ &me
+ );
+ dh = dk3ma_d_mul_ok(
+ 72.0,
+ dk3ma_d_div_ok(dk3bm_l_to_d(h), yres, &me),
+ &me
+ );
+ job->x_scale = dw;
+ job->y_scale = dh;
+ job->x_size = dk3ma_d_to_l_ok(ceil(dw), &me);
+ job->y_size = dk3ma_d_to_l_ok(ceil(dh), &me);
+ job->do_float_scale = 1;
+ job->x_translate = 0.5 * dk3ma_d_sub_ok(job->x_size, dw, &me);
+ job->y_translate = 0.5 * dk3ma_d_sub_ok(job->y_size, dh, &me);
+ if(job->x_translate < 0.0) { job->x_translate = 0.0; }
+ if(job->y_translate < 0.0) { job->y_translate = 0.0; }
+ job->do_translate = 1;
+ mbx1 = dk3ma_d_to_l_ok(job->x_size, &me);
+ mby1 = dk3ma_d_to_l_ok(job->y_size, &me);
+ } break;
+ default: { $? ". workmode = 0"
+ mbx0 = 0L; mby0 = 0L; mbx1 = w; mby1 = h;
+ job->x_size = w; job->y_size = h;
+ } break;
+ }
+ dk3pdf_set_next_mediabox(job->pdf, mbx0, mbx1, mby0, mby1);
+ if(me) { $? ". math error"
+ back = 0;
+ }
+ if(back == 1) { $? ". still ok"
+ if(dk3pdf_open_page(job->pdf)) { $? ". open page"
+ if(job->do_translate) {
+ dk3pdf_translate_double(job->pdf, job->x_translate, job->y_translate);
+ }
+ if(job->do_rotate) {
+ dk3pdf_rotate_int(job->pdf, 90);
+ }
+ if(job->do_float_scale) {
+ dk3pdf_scale_double(job->pdf, job->x_scale, job->y_scale);
+ } else {
+ dk3pdf_scale_long(job->pdf, mbx1, mby1);
+ }
+ if(dk3pdf_add_image_progress(
+ job->pdf, job->bif, job->opt, job->pComm, job->minpb, job->maxpb
+ )
+ )
+ {
+ back = 1; $? ". success"
+ } else {
+ back = 0; $? "! failed to add image"
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 73,
+ DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ dk3pdf_close_page(job->pdf);
+ } else { $? "! dk3pdf_open_page"
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 71,
+ DK3_BMJ_LOG_JOB, job
+ );
+ }
+ } else {
+ back = 0;
+ /* ERROR: Math error! */
+ dk3bmj_log_i1(
+ (job->opt)->app, DK3_LL_ERROR, 260,
+ DK3_BMJ_LOG_BOTH, job
+ );
+ } $? "- dk3bm_job_add_pdf_frame %d", back
+ return back;
+}
+
+
+
+/** Produce PDF output.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bm_job_produce_file_pdf(dk3_bm_conversion_job_t *job)
+{
+ size_t nFrames; /* Number of frames. */
+ size_t i; /* Current frame index. */
+ int back = 0;
+#if DK3_USE_WX
+ int min; /* Original min progress bar value. */
+ int max; /* Original max progress bar value. */
+ int xmax; /* Intermediate progress bar value. */
+#endif
+ $? "+ dk3bm_job_produce_file_pdf"
+#if DK3_USE_WX
+ min = job->minpb;
+ max = job->maxpb;
+ job->maxpb = xmax = min + ((14 * (max - min)) / 15);
+#endif
+ job->pdf = dk3pdf_open_app((job->opt)->app);
+ if(job->pdf) {
+ back = 1;
+ $? ". mode %d", (job->opt)->mode
+ switch((job->opt)->mode) {
+ case DK3_BMEPS_MODE_DOCUMENT: { $? ". mode: document"
+ nFrames = dk3bif_number_of_frames(job->bif);
+ for(i = 0; i < nFrames; i++) {
+#if DK3_USE_WX
+ job->minpb = min + ((((int)i) * (xmax - min)) / (int)nFrames);
+ job->maxpb = min + (((((int)i) + 1) * (xmax - min)) / (int)nFrames);
+#endif
+ if(dk3bif_set_frame(job->bif, i)) {
+ if(!dk3bm_job_add_pdf_frame(job, i)) {
+ back = 0;
+ }
+ } else {
+ back = 0;
+ /* ERROR: Failed to set frame! */
+ dk3bmj_log_i1(
+ (job->opt)->app, DK3_LL_ERROR, 261, DK3_BMJ_LOG_BOTH, job
+ );
+ }
+#if DK3_USE_WX
+ $? ". %d", job->maxpb
+ dk3bmj_progress(job->pComm, job->maxpb);
+#endif
+ }
+ } break;
+ default: { $? ". mode: not a document"
+ if(!dk3bm_job_add_pdf_frame(job, 0)) {
+ back = 0;
+ }
+ } break;
+ }
+#if DK3_USE_WX
+ $? ". %d", job->maxpb
+ dk3bmj_progress(job->pComm, job->maxpb);
+ job->minpb = job->maxpb;
+ job->maxpb = max;
+#endif
+ if(!dk3pdf_write_file_progress(
+ job->pdf, job->dfile, job->pComm, job->minpb, job->maxpb)
+ )
+ {
+ back = 0;
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 72,
+ DK3_BMJ_LOG_JOB, job
+ );
+ }
+ dk3pdf_close(job->pdf); job->pdf = NULL;
+ } else {
+ /* ERROR: Failed to create PDF job! */
+ dk3bmj_log_i1(
+ (job->opt)->app, DK3_LL_ERROR, 9,
+ DK3_BMJ_LOG_JOB, job
+ );
+ }
+#if DK3_USE_WX
+ job->minpb = min;
+ job->maxpb = max;
+#endif
+ $? "- dk3bm_job_produce_file_pdf %d", back
+ return back;
+}
+
+
+
+/** Produce draft PDF output.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bm_job_draft_pdf(dk3_bm_conversion_job_t *job)
+{
+ dk3_pdf_t *pdf; /* PDF writer structure. */
+ double x0; /* Left border. */
+ double x1; /* Right border. */
+ double y0; /* Lower border. */
+ double y1; /* Upper border. */
+ double xres = -1.0; /* X resolution. */
+ double yres = -1.0; /* Y resolution. */
+ double w; /* Width, using resolution. */
+ double h; /* Height, using resolution. */
+ double dx; /* X delta. */
+ double dy; /* Y delta. */
+ long mbx0; /* Media box x0. */
+ long mbx1; /* Media box x1. */
+ long mby0; /* Media box y0. */
+ long mby1; /* Media box y1. */
+ int me = 0; /* Flag: Math error. */
+ int workmode = 0; /* Work mode. */
+ int do_rotate = 0; /* Flag: Rotate. */
+ int back = 1;
+ $? "+ dk3bm_job_draft_pdf"
+ mbx0 = mby0 = 0L;
+ mbx1 = dk3bif_get_width(job->bif);
+ mby1 = dk3bif_get_height(job->bif);
+ x0 = 0.0;
+ y0 = 0.0;
+ x1 = dk3bm_l_to_d(mbx1);
+ y1 = dk3bm_l_to_d(mby1);
+ switch((job->opt)->szmode) {
+ case DK3_BMEPS_SIZE_CHUNK: { $? ". szmode: chunk"
+ xres = dk3bif_get_xres(job->bif);
+ yres = dk3bif_get_yres(job->bif);
+ if((xres > 0.0) || (yres > 0.0)) {
+ if(xres <= 0.0) { xres = 72.0; }
+ if(yres <= 0.0) { yres = 72.0; }
+ if(fabs(xres - 72.0) > dk3bm_epsilon) {
+ workmode = 1;
+ }
+ if(fabs(yres - 72.0) > dk3bm_epsilon) {
+ workmode = 1;
+ }
+ }
+ } break;
+ case DK3_BMEPS_SIZE_SPECIFIED: { $? ". szmode: specified"
+ xres = yres = (job->opt)->resolution;
+ if(xres > 0.0) {
+ if(fabs(xres - 72.0) > dk3bm_epsilon) {
+ workmode = 1;
+ }
+ }
+ } break;
+ case DK3_BMEPS_SIZE_PAPER: { $? ". szmode: paper"
+ workmode = 2;
+ xres = dk3bif_get_xres(job->bif);
+ yres = dk3bif_get_yres(job->bif);
+ if(xres <= 0.0) { xres = 72.0; }
+ if(yres <= 0.0) { yres = 72.0; }
+ if(fabs(xres - 72.0) <= dk3bm_epsilon) { xres = 72.0; }
+ if(fabs(yres - 72.0) <= dk3bm_epsilon) { yres = 72.0; }
+ } break;
+ }
+ switch(workmode) {
+ case 2: { /* Fit to page */
+ w = dk3ma_d_div_ok(dk3bm_l_to_d(mbx1), xres, &me); $? ". w=%lg", w
+ h = dk3ma_d_div_ok(dk3bm_l_to_d(mby1), yres, &me); $? ". h=%lg", h
+ mbx1 = dk3ma_d_to_l_ok(floor(((job->opt)->ima).ps.w), &me);
+ mby1 = dk3ma_d_to_l_ok(floor(((job->opt)->ima).ps.h), &me);
+ $? ". mbx1=%ld mby1=%ld", mbx1, mby1
+ x0 = ((job->opt)->ima).ps.i;
+ y0 = ((job->opt)->ima).ps.b;
+ x1 = dk3ma_d_sub_ok(((job->opt)->ima).ps.w, ((job->opt)->ima).ps.o, &me);
+ y1 = dk3ma_d_sub_ok(((job->opt)->ima).ps.h, ((job->opt)->ima).ps.t, &me);
+ $? ". x0=%lg y0=%lg x1=%lg y1=%lg", x0, y0, x1, y1
+ if((x1 > x0) && (y1 > y0)) { $? ". paper setup ok"
+ if((x1 - x0) > (y1 - y0)) {
+ if(h > w) { $? ". rotate"
+ do_rotate = 1;
+ }
+ } else {
+ if((x1 - x0) < (y1 - y0)) {
+ if(h < w) { $? ". rotate"
+ do_rotate = 1;
+ }
+ }
+ }
+ if(do_rotate) { $? ". do rotate"
+ dx = dk3ma_d_div_ok((x1 - x0), h, &me);
+ dy = dk3ma_d_div_ok((y1 - y0), w, &me);
+ if(dx > dy) {
+ w = dk3ma_d_mul_ok(dy, h, &me);
+ dx = dk3ma_d_add_ok(
+ x0,
+ 0.5 * dk3ma_d_sub_ok((x1 - x0), w, &me),
+ &me
+ );
+ dy = dk3ma_d_add_ok(dx, w, &me);
+ if(dx >= x0) { x0 = dx; }
+ if(dy <= x1) { x1 = dy; }
+ } else {
+ h = dk3ma_d_mul_ok(dx, w, &me);
+ dx = dk3ma_d_add_ok(
+ y0,
+ 0.5 * dk3ma_d_sub_ok((y1 - y0), h, &me),
+ &me
+ );
+ dy = dk3ma_d_add_ok(dx, h, &me);
+ if(dx >= y0) { y0 = dx; }
+ if(dy <= y1) { y1 = dy; }
+ }
+ } else { $? ". do not rotate"
+ dx = dk3ma_d_div_ok((x1 - x0), w, &me);
+ dy = dk3ma_d_div_ok((y1 - y0), h, &me);
+ if(dx > dy) { $? ". restrict x"
+ w = dk3ma_d_mul_ok(dy, w, &me);
+ dx = dk3ma_d_add_ok(
+ x0,
+ 0.5 * dk3ma_d_sub_ok((x1 - x0), w, &me),
+ &me
+ );
+ dy = dk3ma_d_add_ok(dx, w, &me);
+ if(dx >= x0) { x0 = dx; }
+ if(dy <= x1) { x1 = dy; }
+ } else { $? ". restrict y"
+ h = dk3ma_d_mul_ok(dx, h, &me);
+ dx = dk3ma_d_add_ok(
+ y0,
+ 0.5 * dk3ma_d_sub_ok((y1 - y0), h, &me),
+ &me
+ );
+ dy = dk3ma_d_add_ok(dx, h, &me);
+ if(dx >= y0) { y0 = dx; }
+ if(dy <= y1) { y1 = dy; }
+ }
+ } $? ". x0=%lg y0=%lg x1=%lg y1=%lg", x0, y0, x1, y1
+ } else {
+ back = 0;
+ /* ERROR: Incorrect page setup. */
+ dk3bmj_log_i1(
+ (job->opt)->app, DK3_LL_ERROR, 259, DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ } break;
+ case 1: { /* Use resolution */
+ w = dk3ma_d_div_ok(dk3bm_l_to_d(mbx1), xres, &me);
+ h = dk3ma_d_div_ok(dk3bm_l_to_d(mby1), yres, &me);
+ w = dk3ma_d_mul_ok(72.0, w, &me);
+ h = dk3ma_d_mul_ok(72.0, h, &me);
+ x1 = ceil(w);
+ y1 = ceil(h);
+ mbx1 = dk3ma_d_to_l_ok(x1, &me);
+ mby1 = dk3ma_d_to_l_ok(y1, &me);
+ x0 = 0.5 * dk3ma_d_sub_ok(x1, w, &me);
+ y0 = 0.5 * dk3ma_d_sub_ok(y1, h, &me);
+ x1 = dk3ma_d_add_ok(x0, w, &me);
+ y1 = dk3ma_d_add_ok(y0, h, &me);
+ if(x0 < 0.0) { x0 = 0.0; }
+ if(y0 < 0.0) { y0 = 0.0; }
+ if(x1 > dk3bm_l_to_d(mbx1)) { x1 = dk3bm_l_to_d(mbx1); }
+ if(y1 > dk3bm_l_to_d(mby1)) { y1 = dk3bm_l_to_d(mby1); }
+ } break;
+ default: { /* 1:1 */
+ /* Nothing to do, everything is initialized. */
+ } break;
+ }
+ if(me) {
+ back = 0;
+ /* ERROR: Math error occured! */
+ dk3bmj_log_i1(
+ (job->opt)->app, DK3_LL_ERROR, 260, DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ if(back) {
+ back = 0;
+ /* Here we have all information prepared to produce the draft. */
+ pdf = dk3pdf_open_app((job->opt)->app);
+ if(pdf) {
+ dk3pdf_set_next_mediabox(pdf, mbx0, mbx1, mby0, mby1);
+ if(dk3pdf_open_page(pdf)) {
+ back = 1;
+ dx = 0.01 * (x1 - x0);
+ dy = 0.01 * (y1 - y0);
+ if(dy < dx) dx = dy;
+ if(dx > 2.8) dx = 2.8;
+ dk3pdf_set_nonstroking_gray(pdf, 0.0);
+ dk3pdf_newpath_moveto(pdf, x0, y0);
+ dk3pdf_lineto(pdf, x1, y0);
+ dk3pdf_lineto(pdf, x1, y1);
+ dk3pdf_lineto(pdf, x0, y1);
+ dk3pdf_closepath(pdf);
+ dk3pdf_fill_nz(pdf);
+ dk3pdf_set_nonstroking_gray(pdf, 0.8);
+ dk3pdf_newpath_moveto(pdf, (x0 + dx), (y0 + dx));
+ dk3pdf_lineto(pdf, (x1 - dx), (y0 + dx));
+ dk3pdf_lineto(pdf, (x1 - dx), (y1 - dx));
+ dk3pdf_lineto(pdf, (x0 + dx), (y1 - dx));
+ dk3pdf_closepath(pdf);
+ dk3pdf_fill_nz(pdf);
+ dk3pdf_set_nonstroking_gray(pdf, 1.0);
+#if VERSION_BEFORE_20150821
+ dy = dx;
+#endif
+ dx = 10.0 * dx;
+ dk3pdf_newpath_moveto(pdf, (x0 + dx), (y0 + dx));
+ dk3pdf_lineto(pdf, (x1 - dx), (y0 + dx));
+ dk3pdf_lineto(pdf, (x1 - dx), (y1 - dx));
+ dk3pdf_lineto(pdf, (x0 + dx), (y1 - dx));
+ dk3pdf_closepath(pdf);
+ dk3pdf_fill_nz(pdf);
+ dk3pdf_set_linewidth(pdf, dx);
+ dk3pdf_set_linecap(pdf, DK3_LINECAP_ROUND);
+ dk3pdf_set_stroking_gray(pdf, 0.8);
+ dk3pdf_newpath_moveto(pdf, (x0 + dx), (y0 + dx));
+ dk3pdf_lineto(pdf, (x1 - dx), (y1 - dx));
+ dk3pdf_stroke(pdf);
+ dk3pdf_newpath_moveto(pdf, (x0 + dx), (y1 - dx));
+ dk3pdf_lineto(pdf, (x1 - dx), (y0 + dx));
+ dk3pdf_stroke(pdf);
+ dk3pdf_close_page(pdf);
+ } else {
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 71,
+ DK3_BMJ_LOG_JOB, job
+ );
+ }
+ dk3pdf_write_file(pdf, job->dfile);
+ dk3pdf_close(pdf);
+ } else {
+ /* ERROR: Failed to create PDF writer */
+ dk3bmj_log_i1(
+ (job->opt)->app, DK3_LL_ERROR, 9,
+ DK3_BMJ_LOG_JOB, job
+ );
+ }
+ }
+ $? "- dk3bm_job_draft_pdf %d", back
+ return back;
+}
+
+
+
+/** Produce PDF output.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bm_job_produce_pdf(dk3_bm_conversion_job_t *job)
+{
+ int back = 0;
+#if DK3_USE_WX
+ int min; /* Original min progress bar value. */
+ int max; /* Original max progress bar value. */
+#endif
+ $? "+ dk3bm_job_produce_pdf"
+#if DK3_USE_WX
+ min = job->minpb;
+ max = job->maxpb;
+ job->minpb = min + ((max - min) / 4);
+#endif
+ if((job->opt)->draft) {
+ if(job->dfile) {
+ back = dk3bm_job_draft_pdf(job);
+ } else {
+ job->dfile = dk3sf_fopen_app(
+ job->dfn,
+ dk3app_not_localized(53),
+ (job->opt)->app
+ );
+ if(job->dfile) {
+ back = dk3bm_job_draft_pdf(job);
+ if(!dk3sf_fclose_fn_app(job->dfile, job->dfn, (job->opt)->app)) {
+ back = 0;
+ }
+ job->dfile = NULL;
+ } else {
+ /* ERROR: Failed to open output file! */
+ dk3bmj_log_i3(
+ (job->opt)->app, DK3_LL_ERROR, 77, 78, job->dfn,
+ DK3_BMJ_LOG_JOB, job
+ );
+ }
+ }
+ } else {
+ if(dk3bif_read_data(job->bif)) {
+#if DK3_USE_WX
+ if((job->pComm) && (job->maxpb > job->minpb)) {
+ $? ". %d", job->minpb
+ dk3bmj_progress(job->pComm, job->minpb);
+ }
+#endif
+ if(job->dfile) {
+ back = dk3bm_job_produce_file_pdf(job);
+ } else {
+ job->dfile = dk3sf_fopen_app(
+ job->dfn,
+ dk3app_not_localized(53),
+ (job->opt)->app
+ );
+ if(job->dfile) {
+ back = dk3bm_job_produce_file_pdf(job);
+ if(!dk3sf_fclose_fn_app(job->dfile, job->dfn, (job->opt)->app)) {
+ back = 0;
+ }
+ job->dfile = NULL;
+ } else {
+ /* ERROR: Failed to open output file! */
+ dk3bmj_log_i3(
+ (job->opt)->app, DK3_LL_ERROR, 77, 78, job->dfn,
+ DK3_BMJ_LOG_JOB, job
+ );
+ }
+ }
+ } else {
+ /* ERROR: Failed to read image data! */
+ dk3bmj_log_1(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 61, DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ }
+#if DK3_USE_WX
+ job->minpb = min;
+ job->maxpb = max;
+#endif
+ $? "- dk3bm_job_produce_pdf %d", back
+ return back;
+}
+
+
+
+/** Produce bounding box output.
+ @param job Job structure.
+*/
+static
+void
+dk3bm_produce_bb(dk3_bm_conversion_job_t *job)
+{
+ dk3_bif_coord_t w; /* Image width. */
+ dk3_bif_coord_t h; /* Image height. */
+ $? "+ dk3bm_produce_bb"
+ w = dk3bif_get_width(job->bif);
+ h = dk3bif_get_height(job->bif);
+ fprintf(job->dfile, dk3bm_c8_kw[31], w, h);
+ $? "- dk3bm_produce_bb"
+}
+
+
+
+/** Produce bounding box output.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bm_job_produce_bb(dk3_bm_conversion_job_t *job)
+{
+ int back = 0;
+ if(job->dfile) {
+ dk3bm_produce_bb(job);
+ back = 1;
+ } else {
+ job->dfile = dk3sf_fopen_app(
+ job->dfn,
+ dk3app_not_localized(24),
+ (job->opt)->app
+ );
+ if(job->dfile) {
+ dk3bm_produce_bb(job);
+ back = 1;
+ if(!dk3sf_fclose_fn_app(job->dfile, job->dfn, (job->opt)->app)) {
+ back = 0;
+ }
+ job->dfile = NULL;
+ } else {
+ dk3bmj_log_i3(
+ (job->opt)->app, DK3_LL_ERROR, 77, 78, job->dfn,
+ DK3_BMJ_LOG_JOB, job
+ );
+ }
+ }
+ return back;
+}
+
+
+
+/** Run a conversion job for either the opened file or the named file.
+ @param job Conversion job.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bm_job_from_program_with_output(dk3_bm_conversion_job_t *job)
+{
+ int back = 0;
+ $? "+ dk3bm_job_from_program_with_output"
+ job->bif = dk3bif_open_filename_app(job->sfn, job->biftype, (job->opt)->app);
+ if(job->bif) {
+ switch((job->opt)->dr) {
+ case DK3_BMEPS_DRIVER_PS: {
+ back = dk3bm_job_produce_ps(job);
+ } break;
+ case DK3_BMEPS_DRIVER_EPS: {
+ back = dk3bm_job_produce_ps(job);
+ } break;
+ case DK3_BMEPS_DRIVER_PDF: {
+ back = dk3bm_job_produce_pdf(job);
+ } break;
+ default: {
+ back = dk3bm_job_produce_bb(job);
+ } break;
+ }
+ dk3bif_close(job->bif);
+ } else {
+ dk3bmj_log_3(
+ (job->opt)->app, DK3_LL_ERROR, job->msg, 69, 70, job->sfn, DK3_BMJ_LOG_BOTH, job
+ );
+ }
+ $? "- dk3bm_job_from_program_with_output %d", back
+ return back;
+}
+
+
+
+
+/** Construct an output file name and run.
+ @param job Conversion job.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bm_job_from_program_construct_name(dk3_bm_conversion_job_t *job)
+{
+ dkChar fno[DK3_MAX_PATH]; /* Output file name buffer. */
+ dkChar *sptr; /* Pointer to file name suffix. */
+ dkChar const *ns; /* New suffix. */
+ int back = 0;
+ $? "+ dk3bm_job_from_program_construct_name %d", (job->opt)->dr
+ dk3str_cpy_not_overlapped(fno, job->sfn);
+ sptr = dk3str_get_suffix(fno);
+ if(sptr) { *sptr = dkT('\0'); }
+ ns = dk3bm_output_suffixes[0];
+ switch((job->opt)->dr) {
+ case DK3_BMEPS_DRIVER_EPS: {
+ ns = dk3bm_output_suffixes[1];
+ } break;
+ case DK3_BMEPS_DRIVER_PDF: {
+ ns = dk3bm_output_suffixes[2];
+ } break;
+ case DK3_BMEPS_DRIVER_BB: {
+ ns = dk3bm_output_suffixes[3];
+ } break;
+ }
+ if((dk3str_len(ns) + dk3str_len(fno)) < DK3_SIZEOF(fno,dkChar)) {
+ dk3str_cat(fno, ns); $? ". output file \"%!ds\"", fno
+ job->dfn = fno;
+ back = dk3bm_job_from_program_with_output(job);
+ } else {
+ /* ERROR: File name too long! */
+ dk3bmj_log_i3(
+ (job->opt)->app, DK3_LL_ERROR, 65, 66, job->sfn, DK3_BMJ_LOG_BOTH, job
+ );
+ } $? "- dk3bm_job_from_program_construct_name %d", back
+ return back;
+}
+
+
+
+int
+dk3bm_process_file_name(
+ dk3_bm_eps_options_t *opt,
+ dkChar const *sfn,
+ int biftype,
+ int min,
+ int max,
+ void *comm
+)
+{
+ dk3_bm_eps_options_t bmeo; /* Conversion options. */
+ dk3_bm_conversion_job_t job; /* Conversion job. */
+#if DK3_ON_WINDOWS
+ int oldmode; /* Original stdout file mode. */
+#endif
+ int back = 0;
+ $? "+ dk3bm_process_file_name \"%!ds\" dr = %d", TR_STR(sfn), opt->dr
+ if((opt) && (sfn)) { $? ". dr = %d", opt->dr
+ if(opt->app) { $? ". app"
+ dk3bmj_init(&job, opt->app);
+ dk3mem_cpy((void *)(&bmeo), (void *)opt, sizeof(dk3_bm_eps_options_t));
+ job.opt = &bmeo; $? ". dr = %d", bmeo.dr
+ job.sfn = sfn;
+ job.biftype = biftype;
+#if DK3_USE_WX
+ job.pComm = comm;
+ job.minpb = min;
+ job.maxpb = max;
+#endif
+ if(dk3bmeo_check(&bmeo, 0, opt->app, &job)) { $? ". check"
+ if(opt->to_stdout) { $? ". write output to stdout"
+ job.dfile = stdout;
+ switch(opt->dr) {
+ case DK3_BMEPS_DRIVER_PDF: { $? ". PDF"
+#if DK3_ON_WINDOWS
+ oldmode = _setmode(_fileno(stdout), _O_BINARY);
+#endif
+ back = dk3bm_job_from_program_with_output(&job);
+#if DK3_ON_WINDOWS
+ _setmode(_fileno(stdout), oldmode);
+#endif
+ } break;
+ default: { $? ". not PDF"
+ back = dk3bm_job_from_program_with_output(&job);
+ } break;
+ }
+ } else { $? ". write output to file"
+ job.dfile = NULL;
+ back = dk3bm_job_from_program_construct_name(&job);
+ }
+ } else { $? "! Inconsistent options"
+ /* ERROR: Inconsistent options, reported by dk3bmeo_check(). */
+ dk3bmj_log_1(
+ opt->app, DK3_LL_ERROR, job.msg, 68, DK3_BMJ_LOG_JOB, &job
+ );
+ }
+ } else { $? "! opt->app"
+ /* ERROR: Application structure not set! */
+ }
+ }
+#if DK3_USE_WX
+ if((comm) && (max > min)) {
+ $? ". %d", max
+ dk3bmj_progress(comm, max);
+ }
+#endif
+ $? "- dk3bm_process_file_name %d", back
+ return back;
+}
+
+
diff --git a/support/dktools/dk3bm.h b/support/dktools/dk3bm.h
new file mode 100644
index 0000000000..e7d5fe65b6
--- /dev/null
+++ b/support/dktools/dk3bm.h
@@ -0,0 +1,141 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3bm.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3bm.h Header file for the dk3bm module.
+*/
+
+#ifndef DK3BM_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3BM_H_INCLUDED 1
+
+
+#line 10 "dk3bm.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Process one file name.
+ This function is the entry point used by bmeps3 and wxbmeps.
+ The opt->app component must be set.
+ @param opt Option set for conversion.
+ @param sfn Source file name.
+ @param biftype Bitmap image file type.
+ @param min Progress bar value at start of processing.
+ @param max Progress bar value at end of processing.
+ @param comm Communicator object from wxbmeps.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3bm_process_file_name(
+ dk3_bm_eps_options_t *opt,
+ dkChar const *sfn,
+ int biftype,
+ int min,
+ int max,
+ void *comm
+);
+
+
+/** Place a PS object in a given range.
+ This is the entry point used by Fig to PS/EPS conversion.
+ @param dfile Destination file.
+ @param outbb Image area.
+ @param drawdir Draw direction / coordinates origin.
+ @param sfn Source file name.
+ @param app Application structure.
+ @param pslevel PS level.
+ @param ec Pointer to error code variable, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3bm_ps_place_object(
+ FILE *dfile,
+ dk3_bb_t *outbb,
+ int drawdir,
+ char const *sfn,
+ dk3_app_t *app,
+ int pslevel,
+ int *ec
+);
+
+/** Find graphics state transformations to place an object.
+ @param dst Graphics state transformation structure.
+ @param outbb Reserved range for image.
+ @param drawdir Drawing directory / coordinates origin.
+ @param imw Image width in pixels.
+ @param imh Image height in pixels.
+ @param xres X resolution.
+ @param yres Y resolution.
+ @param ec Pointer to error code variable.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3bm_find_transformation(
+ dk3_coordinates_transformation_t *dst,
+ dk3_bb_t *outbb,
+ int drawdir,
+ double imw,
+ double imh,
+ double xres,
+ double yres,
+ int *ec
+);
+
+/** Find graphics state transformations to place an object.
+ @param dst Graphics state transformation structure.
+ @param bif Image to place.
+ @param outbb Reserved range for image.
+ @param drawdir Drawing directory / coordinates origin.
+ @param ec Pointer to error code variable.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3bm_find_bif_transformation(
+ dk3_coordinates_transformation_t *dst,
+ dk3_bif_t *bif,
+ dk3_bb_t *outbb,
+ int drawdir,
+ int *ec
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3bmeo.c b/support/dktools/dk3bmeo.c
new file mode 100644
index 0000000000..f2981f8e3c
--- /dev/null
+++ b/support/dktools/dk3bmeo.c
@@ -0,0 +1,1995 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3bmeo.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3bmeo.c The dk3bmeo module.
+*/
+
+
+#line 321 "dk3bmeo.ctr"
+
+
+#include "dk3all.h"
+#include "dk3bmeo.h"
+#include "dk3bmeps.h"
+#include "dk3bmj.h"
+#include "dk3bm.h"
+
+
+
+
+#line 331 "dk3bmeo.ctr"
+
+
+
+/** Keywords used by the module.
+*/
+static dkChar const * const dk3bmeo_kw[] = {
+/* 0 */
+dkT("/print/paper-size"),
+
+/* 1 */
+dkT("1px1pt"),
+
+/* 2 */
+dkT("chunk"),
+
+/* 3 */
+dkT("1:1"),
+
+/* 4 */
+dkT("/print/ps/level"),
+
+/* 5 */
+dkT("%ld"),
+
+NULL
+
+
+#line 363 "dk3bmeo.ctr"
+};
+
+
+
+/** Names for options.
+*/
+static dkChar const * const dk3bmeo_option_names[] = {
+/* 0 */
+dkT("level"),
+
+/* 1 */
+dkT("color"),
+
+/* 2 */
+dkT("dsc"),
+
+/* 3 */
+dkT("draft"),
+
+/* 4 */
+dkT("predictor"),
+
+/* 5 */
+dkT("duplex"),
+
+/* 6 */
+dkT("tumble"),
+
+/* 7 */
+dkT("dct"),
+
+/* 8 */
+dkT("bg"),
+
+/* 9 */
+dkT("interpolation"),
+
+/* 10 */
+dkT("jpeg-interpolation"),
+
+/* 11 */
+dkT("resolution"),
+
+/* 12 */
+dkT("paper"),
+
+/* 13 */
+dkT("make"),
+
+/* 14 */
+dkT("aspect"),
+
+/* 15 */
+dkT("bpc"),
+
+NULL
+
+
+#line 436 "dk3bmeo.ctr"
+};
+
+
+
+/** Driver names.
+*/
+dkChar const * const dk3bmeo_driver_names[] = {
+/* 0 */
+dkT("ps"),
+
+/* 1 */
+dkT("eps"),
+
+/* 2 */
+dkT("pdf"),
+
+/* 3 */
+dkT("bb"),
+
+NULL
+
+
+#line 449 "dk3bmeo.ctr"
+};
+
+
+
+/** Mode names
+*/
+dkChar const * const dk3bmeo_mode_names[] = {
+/* 0 */
+dkT("i$mage"),
+
+/* 1 */
+dkT("o$bject"),
+
+/* 2 */
+dkT("d$ocument"),
+
+NULL
+
+
+#line 470 "dk3bmeo.ctr"
+};
+
+
+
+/** Names for flate compression predictors.
+ Order must match DK3_COMPRESSION_PREDICTOR_xxx
+ in dk3const.h, see @ref flatepredictors.
+*/
+dkChar const * const dk3bmeo_predictor_names[] = {
+/* 0 */
+dkT("tiff"),
+
+/* 1 */
+dkT("sub"),
+
+/* 2 */
+dkT("up"),
+
+/* 3 */
+dkT("average"),
+
+/* 4 */
+dkT("paeth"),
+
+NULL
+
+
+#line 486 "dk3bmeo.ctr"
+};
+
+
+
+
+void
+dk3bmeo_init(dk3_bm_eps_options_t *opt)
+{
+
+
+#line 495 "dk3bmeo.ctr"
+ if(opt) {
+ (opt->ima).ps.w = 595.0;
+ (opt->ima).ps.h = 842.0;
+ (opt->ima).ps.i = 0.0;
+ (opt->ima).ps.o = 0.0;
+ (opt->ima).ps.t = 0.0;
+ (opt->ima).ps.b = 0.0;
+ opt->resolution = 72.0;
+ opt->app = NULL;
+ opt->mode = DK3_BMEPS_MODE_OBJECT;
+ opt->szmode = DK3_BMEPS_SIZE_1_1;
+
+#line 506 "dk3bmeo.ctr"
+ opt->dr = DK3_BMEPS_DRIVER_PDF;
+ opt->pred = 0;
+ opt->io = 0;
+ opt->draft = 0;
+ opt->duplex = 0;
+ opt->tumble = 0;
+ opt->psl = 3;
+ opt->dsc = 0;
+ opt->dct = 1;
+ opt->kar = 1;
+ opt->bgr = 255; opt->bgg = 255; opt->bgb = 255; opt->fbg = 0;
+ opt->ip = 1; opt->jip = 0;
+ opt->make = 0;
+ opt->color = 1;
+ opt->to_stdout = 0;
+ opt->rbpc = 1;
+ }
+
+#line 523 "dk3bmeo.ctr"
+}
+
+
+
+dk3_bm_eps_options_t *
+dk3bmeo_new_app(dk3_app_t *app)
+{
+ dk3_bm_eps_options_t *back = NULL;
+
+
+#line 532 "dk3bmeo.ctr"
+ back = dk3_new_app(dk3_bm_eps_options_t,1,app);
+ if(back) {
+ dk3bmeo_init(back);
+ back->app = app;
+ }
+
+#line 537 "dk3bmeo.ctr"
+ return back;
+}
+
+
+
+void
+dk3bmeo_delete(dk3_bm_eps_options_t *opt)
+{
+
+
+#line 546 "dk3bmeo.ctr"
+ if(opt) {
+ opt->app = NULL;
+ dk3_delete(opt);
+ }
+
+#line 550 "dk3bmeo.ctr"
+}
+
+
+
+int
+dk3bmeo_get_mode(dk3_bm_eps_options_t *opt)
+{
+ int back = DK3_BMEPS_MODE_IMAGE;
+
+
+#line 559 "dk3bmeo.ctr"
+ if(opt) {
+ back = opt->mode;
+ }
+
+#line 562 "dk3bmeo.ctr"
+ return back;
+}
+
+
+
+/** Set paper size, complain if named size is not found.
+ @param opt Option set to receive size information.
+ @param psn Paper size name.
+ @param cond Flag: Complain (nonzero) or not (0).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bmeo_set_paper_size_complain(
+ dk3_bm_eps_options_t *opt, dkChar const *psn, int cond
+)
+{
+ dk3_paper_size_collection_t *psc; /* Paper size collection. */
+ dk3_paper_size_t const *pap; /* Paper size. */
+ dkChar const * const *msg; /* Localized message texts. */
+ int back = 0;
+
+
+#line 584 "dk3bmeo.ctr"
+ msg = dk3app_messages(
+ opt->app,
+ dk3bmep_str_get_string_table_name(),
+ (dkChar const **)dk3bmep_str_get_message_texts()
+ );
+ if(!(msg)) {
+ msg = dk3bmep_str_get_message_texts();
+ }
+ if((opt) && (psn)) {
+
+#line 593 "dk3bmeo.ctr"
+ if(opt->app) {
+
+#line 594 "dk3bmeo.ctr"
+ psc = dk3paper_open_app(opt->app);
+ if(psc) {
+
+#line 596 "dk3bmeo.ctr"
+ pap = dk3paper_find(psc, psn);
+ if(pap) {
+
+#line 598 "dk3bmeo.ctr"
+ (opt->ima).ps.w = pap->w;
+ (opt->ima).ps.h = pap->h;
+ (opt->ima).ps.i = pap->i;
+ (opt->ima).ps.o = pap->o;
+ (opt->ima).ps.t = pap->t;
+ (opt->ima).ps.b = pap->b;
+ back = 1;
+ } else {
+
+#line 606 "dk3bmeo.ctr"
+ /* ERROR: No such paper size. */
+ dk3bmj_log_3(
+ opt->app, DK3_LL_ERROR,msg,39,40,psn,DK3_BMJ_LOG_BOTH,NULL
+ );
+ }
+ dk3paper_close(psc);
+ } else {
+
+#line 613 "dk3bmeo.ctr"
+ }
+ if(!(opt->mode == DK3_BMEPS_MODE_DOCUMENT)) {
+
+#line 615 "dk3bmeo.ctr"
+ /* ERROR: Not a document */
+ if(cond) {
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR,msg,38,DK3_BMJ_LOG_BOTH,NULL);
+ }
+ }
+ } else {
+
+#line 621 "dk3bmeo.ctr"
+ /* ERROR: No app! */
+ }
+ } else {
+
+#line 624 "dk3bmeo.ctr"
+ }
+
+#line 625 "dk3bmeo.ctr"
+ return back;
+}
+
+
+
+void
+dk3bmeo_apply_preferences(dk3_bm_eps_options_t *opt)
+{
+ dkChar psn[64]; /* Buffer for paper size name. */
+ int psl; /* PS level. */
+
+
+#line 636 "dk3bmeo.ctr"
+ if(opt->app) {
+ if(dk3app_get_pref(opt->app,dk3bmeo_kw[0],psn,DK3_SIZEOF(psn,dkChar)))
+ {
+ (void)dk3bmeo_set_paper_size_complain(opt, psn, 0);
+ }
+ if(dk3app_get_pref(opt->app,dk3bmeo_kw[4],psn,DK3_SIZEOF(psn,dkChar)))
+ {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(psn, dk3bmeo_kw[5], &psl) == 1)
+#else
+ if (0 != dk3ma_i_from_string(&psl, psn, NULL))
+#endif
+ {
+ if(psl > 3) { psl = 3; }
+ if(psl < 2) { psl = 2; }
+ opt->psl = psl;
+ }
+ }
+ }
+
+
+#line 656 "dk3bmeo.ctr"
+}
+
+
+
+/** Initialize for a given driver and mode.
+ @param opt Option set to complete setup.
+*/
+static
+void
+dk3bmeo_initialize_for_driver_and_mode(dk3_bm_eps_options_t *opt)
+{
+ switch(opt->dr) {
+ case DK3_BMEPS_DRIVER_PS: {
+ } break;
+ case DK3_BMEPS_DRIVER_EPS: {
+ } break;
+ case DK3_BMEPS_DRIVER_PDF: {
+ } break;
+ case DK3_BMEPS_DRIVER_BB: {
+ opt->mode = DK3_BMEPS_MODE_OBJECT;
+ } break;
+ }
+ switch(opt->mode) {
+ case DK3_BMEPS_MODE_IMAGE: {
+ opt->szmode = DK3_BMEPS_SIZE_CHUNK;
+
+#line 681 "dk3bmeo.ctr"
+ } break;
+ case DK3_BMEPS_MODE_OBJECT: {
+ opt->szmode = DK3_BMEPS_SIZE_1_1;
+
+#line 684 "dk3bmeo.ctr"
+ } break;
+ case DK3_BMEPS_MODE_DOCUMENT: {
+
+#line 686 "dk3bmeo.ctr"
+ opt->szmode = DK3_BMEPS_SIZE_PAPER;
+ if(opt->dr == DK3_BMEPS_DRIVER_PS) {
+ opt->dsc = 1;
+ }
+ } break;
+ }
+ (opt->ima).ps.w = 595.0;
+ (opt->ima).ps.h = 842.0;
+ if(opt->mode == DK3_BMEPS_MODE_DOCUMENT) {
+ /*
+ The option -l ps.document is typically used for fax TIFF files
+ which already have a border. So we do not need an additional border.
+ */
+ (opt->ima).ps.i = 0.0;
+ (opt->ima).ps.o = 0.0;
+ (opt->ima).ps.t = 0.0;
+ (opt->ima).ps.b = 0.0;
+ opt->szmode = DK3_BMEPS_SIZE_PAPER;
+
+#line 704 "dk3bmeo.ctr"
+ } else {
+ (opt->ima).ps.i = 56.0;
+ (opt->ima).ps.o = 28.0;
+ (opt->ima).ps.t = 14.0;
+ (opt->ima).ps.b = 14.0;
+ }
+ dk3bmeo_apply_preferences(opt);
+}
+
+
+
+
+void
+dk3bmeo_set_driver_and_mode(dk3_bm_eps_options_t *opt, int driver, int mode)
+{
+
+
+#line 720 "dk3bmeo.ctr"
+ if(opt) {
+ opt->dr = driver;
+ opt->mode = mode;
+ dk3bmeo_initialize_for_driver_and_mode(opt);
+ }
+
+#line 725 "dk3bmeo.ctr"
+}
+
+
+
+int
+dk3bmeo_set_paper_size(dk3_bm_eps_options_t *opt, dkChar const *psn)
+{
+ int back;
+ back = dk3bmeo_set_paper_size_complain(opt, psn, 1);
+ return back;
+}
+
+
+
+int
+dk3bmeo_get_driver(dk3_bm_eps_options_t *opt)
+{
+ int back = DK3_BMEPS_DRIVER_PS;
+
+
+#line 744 "dk3bmeo.ctr"
+ if(opt) {
+ back = opt->dr;
+ }
+
+#line 747 "dk3bmeo.ctr"
+ return back;
+}
+
+
+
+void
+dk3bmeo_set_draft(dk3_bm_eps_options_t *opt, int drflag)
+{
+
+
+#line 756 "dk3bmeo.ctr"
+ if(opt) {
+ opt->draft = drflag;
+ }
+
+#line 759 "dk3bmeo.ctr"
+}
+
+
+
+int
+dk3bmeo_get_draft(dk3_bm_eps_options_t *opt)
+{
+ int back = 0;
+
+
+#line 768 "dk3bmeo.ctr"
+ if(opt) {
+ back = ((opt->draft) ? 1 : 0);
+ }
+
+#line 771 "dk3bmeo.ctr"
+ return back;
+}
+
+
+
+void
+dk3bmeo_set_duplex(dk3_bm_eps_options_t *opt, int duplex)
+{
+
+
+#line 780 "dk3bmeo.ctr"
+ if(opt) {
+ opt->duplex = duplex;
+ }
+
+#line 783 "dk3bmeo.ctr"
+}
+
+
+
+int
+dk3bmeo_get_duplex(dk3_bm_eps_options_t *opt)
+{
+ int back = 0;
+
+
+#line 792 "dk3bmeo.ctr"
+ if(opt) {
+ back = ((opt->duplex) ? 1 : 0);
+ }
+
+#line 795 "dk3bmeo.ctr"
+ return back;
+}
+
+
+
+void
+dk3bmeo_set_predictor(dk3_bm_eps_options_t *opt, int pred)
+{
+
+
+#line 804 "dk3bmeo.ctr"
+ if(opt) {
+ opt->pred = pred;
+ }
+
+#line 807 "dk3bmeo.ctr"
+}
+
+
+
+int
+dk3bmeo_get_predictor(dk3_bm_eps_options_t *opt)
+{
+ int back = 0;
+
+
+#line 816 "dk3bmeo.ctr"
+ if(opt) {
+ back = opt->pred;
+ }
+
+#line 819 "dk3bmeo.ctr"
+ return back;
+}
+
+
+
+void
+dk3bmeo_set_origin(dk3_bm_eps_options_t *opt, int io)
+{
+
+
+#line 828 "dk3bmeo.ctr"
+ if(opt) {
+ opt->io = io;
+ }
+
+#line 831 "dk3bmeo.ctr"
+}
+
+
+
+int
+dk3bmeo_get_origin(dk3_bm_eps_options_t *opt)
+{
+ int back = 0;
+
+
+#line 840 "dk3bmeo.ctr"
+ if(opt) {
+ back = opt->io;
+ }
+
+#line 843 "dk3bmeo.ctr"
+ return back;
+}
+
+
+
+void
+dk3bmeo_set_ps_level(dk3_bm_eps_options_t *opt, int psl)
+{
+
+
+#line 852 "dk3bmeo.ctr"
+ if(opt) {
+ opt->psl = psl;
+ if(psl < 2) opt->psl = 2;
+ if(psl > 3) opt->psl = 3;
+ }
+
+#line 857 "dk3bmeo.ctr"
+}
+
+
+
+int
+dk3bmeo_get_ps_level(dk3_bm_eps_options_t *opt)
+{
+ int back = 3;
+
+
+#line 866 "dk3bmeo.ctr"
+ if(opt) {
+ back = opt->psl;
+ }
+
+#line 869 "dk3bmeo.ctr"
+ return back;
+}
+
+
+
+void
+dk3bmeo_set_dct(dk3_bm_eps_options_t *opt, int dct)
+{
+
+
+#line 878 "dk3bmeo.ctr"
+ if(opt) {
+ opt->dct = dct;
+ }
+
+#line 881 "dk3bmeo.ctr"
+}
+
+
+
+int
+dk3bmeo_get_dct(dk3_bm_eps_options_t *opt)
+{
+ int back = 1;
+
+
+#line 890 "dk3bmeo.ctr"
+ if(opt) {
+ back = ((opt->dct) ? 1 : 0);
+ }
+
+#line 893 "dk3bmeo.ctr"
+ return back;
+}
+
+
+void
+dk3bmeo_set_keep_aspect_ratio(dk3_bm_eps_options_t *opt, int kar)
+{
+
+
+#line 901 "dk3bmeo.ctr"
+ if(opt) {
+ opt->kar = kar;
+ }
+
+#line 904 "dk3bmeo.ctr"
+}
+
+
+
+int
+dk3bmeo_get_keep_aspect_ratio(dk3_bm_eps_options_t *opt)
+{
+ int back = 1;
+
+
+#line 913 "dk3bmeo.ctr"
+ if(opt) {
+ back = ((opt->kar) ? 1 : 0);
+ }
+
+#line 916 "dk3bmeo.ctr"
+ return back;
+}
+
+
+
+void
+dk3bmeo_set_background(dk3_bm_eps_options_t *opt, int r, int g, int b, int f)
+{
+
+
+#line 925 "dk3bmeo.ctr"
+ if(opt) {
+ opt->bgr = r; opt->bgg = g; opt->bgb = b; opt->fbg = f;
+ }
+
+#line 928 "dk3bmeo.ctr"
+}
+
+
+
+int
+dk3bmeo_get_background_red(dk3_bm_eps_options_t *opt)
+{
+ int back = 0;
+
+
+#line 937 "dk3bmeo.ctr"
+ if(opt) {
+ back = opt->bgr;
+ }
+
+#line 940 "dk3bmeo.ctr"
+ return back;
+}
+
+
+
+
+int
+dk3bmeo_get_background_green(dk3_bm_eps_options_t *opt)
+{
+ int back = 0;
+
+
+#line 951 "dk3bmeo.ctr"
+ if(opt) {
+ back = opt->bgg;
+ }
+
+#line 954 "dk3bmeo.ctr"
+ return back;
+}
+
+
+
+int
+dk3bmeo_get_background_blue(dk3_bm_eps_options_t *opt)
+{
+ int back = 0;
+
+
+#line 964 "dk3bmeo.ctr"
+ if(opt) {
+ back = opt->bgb;
+ }
+
+#line 967 "dk3bmeo.ctr"
+ return back;
+}
+
+
+
+int
+dk3bmeo_get_background_force(dk3_bm_eps_options_t *opt)
+{
+ int back = 0;
+
+
+#line 977 "dk3bmeo.ctr"
+ if(opt) {
+ back = ((opt->fbg) ? 1 : 0);
+ }
+
+#line 980 "dk3bmeo.ctr"
+ return back;
+}
+
+
+
+void
+dk3bmeo_set_interpolation(dk3_bm_eps_options_t *opt, int iip)
+{
+
+
+#line 989 "dk3bmeo.ctr"
+ if(opt) {
+ opt->ip = iip;
+ }
+
+#line 992 "dk3bmeo.ctr"
+}
+
+
+
+int
+dk3bmeo_get_interpolation(dk3_bm_eps_options_t *opt)
+{
+ int back = 1;
+
+
+#line 1001 "dk3bmeo.ctr"
+ if(opt) {
+ back = ((opt->ip) ? 1 : 0);
+ }
+
+#line 1004 "dk3bmeo.ctr"
+ return back;
+}
+
+
+
+void
+dk3bmeo_set_jpeg_interpolation(dk3_bm_eps_options_t *opt, int iip)
+{
+
+
+#line 1013 "dk3bmeo.ctr"
+ if(opt) {
+ opt->jip = iip;
+ }
+
+#line 1016 "dk3bmeo.ctr"
+}
+
+
+
+int
+dk3bmeo_get_jpeg_interpolation(dk3_bm_eps_options_t *opt)
+{
+ int back = 0;
+
+
+#line 1025 "dk3bmeo.ctr"
+ if(opt) {
+ back = ((opt->jip) ? 1 : 0);
+ }
+
+#line 1028 "dk3bmeo.ctr"
+ return back;
+}
+
+
+
+void
+dk3bmeo_set_szmode(dk3_bm_eps_options_t *opt, int newmode)
+{
+
+
+#line 1037 "dk3bmeo.ctr"
+ if(opt) {
+ if((newmode >= 0) && (newmode <= 2)) {
+ opt->szmode = newmode;
+
+#line 1040 "dk3bmeo.ctr"
+ }
+ }
+
+#line 1042 "dk3bmeo.ctr"
+}
+
+
+
+void
+dk3bmeo_set_resolution(dk3_bm_eps_options_t *opt, double dpi)
+{
+
+
+#line 1050 "dk3bmeo.ctr"
+ if(opt) {
+ opt->resolution = dpi;
+ }
+
+#line 1053 "dk3bmeo.ctr"
+}
+
+
+
+double
+dk3bmeo_get_resolution(dk3_bm_eps_options_t *opt)
+{
+ double back = 72.0;
+
+
+#line 1062 "dk3bmeo.ctr"
+ if(opt) {
+ back = opt->resolution;
+ if(back < 0.0) { back = 0.0; }
+ }
+
+#line 1066 "dk3bmeo.ctr"
+ return back;
+}
+
+
+
+int
+dk3bmeo_get_szmode(dk3_bm_eps_options_t *opt)
+{
+ int back = 0;
+
+
+#line 1076 "dk3bmeo.ctr"
+ if(opt) {
+ back = opt->szmode;
+ }
+
+#line 1079 "dk3bmeo.ctr"
+ return back;
+}
+
+
+
+/** Set PS level.
+ @param opt Option set to modify.
+ @param val Value for option.
+ @param msg Localized message texts.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bmeo_option_pslevel(
+ dk3_bm_eps_options_t *opt,
+ dkChar const *val,
+ dkChar const * const *msg
+)
+{
+ int back = 0;
+ int i; /* Number obtained from val. */
+
+
+#line 1101 "dk3bmeo.ctr"
+ if(val) {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(val, dkT("%d"), &i))
+#else
+ if (0 != dk3ma_i_from_string(&i, val, NULL))
+#endif
+ {
+ if(i >= 2) {
+ if(i <= 3) {
+ opt->psl = i; back = 1;
+ } else {
+ /* ERROR: Must be 2 or 3! */
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR,msg,26,DK3_BMJ_LOG_BOTH,NULL);
+ }
+ } else {
+ /* ERROR: Must be 2 or 3! */
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR,msg,26,DK3_BMJ_LOG_BOTH,NULL);
+ }
+ } else {
+ /* ERROR: Not a number! */
+ dk3bmj_log_3(opt->app, DK3_LL_ERROR,msg,24,25,val,DK3_BMJ_LOG_BOTH,NULL);
+ }
+ } else {
+ /* ERROR: Missing argument! */
+ }
+
+#line 1126 "dk3bmeo.ctr"
+ return back;
+}
+
+
+
+
+/** Set a boolean value.
+ @param opt Option set, used for diagnostics.
+ @param dest Boolean variable.
+ @param val Text containing the value.
+ @param msg Localized message texts.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bmeo_set_boolean(
+ dk3_bm_eps_options_t *opt,
+ int *dest,
+ dkChar const *val,
+ dkChar const * const *msg
+)
+{
+ int back = 0;
+
+
+#line 1150 "dk3bmeo.ctr"
+ if(val) {
+ if(dk3str_is_bool(val)) {
+ back = 1;
+ if(dk3str_is_on(val)) {
+ *dest = 1;
+ } else {
+ *dest = 0;
+ }
+ } else {
+ /* ERROR: Not a boolean! */
+ dk3bmj_log_3(opt->app, DK3_LL_ERROR,msg,27,28,val,DK3_BMJ_LOG_BOTH,NULL);
+ }
+ } else {
+ *dest = 1; back = 1;
+ }
+
+#line 1165 "dk3bmeo.ctr"
+ return back;
+}
+
+
+
+/** Set flate predictor name.
+ @param opt Option set to modify.
+ @param val Value for option.
+ @param msg Localized message texts.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bmeo_option_predictor(
+ dk3_bm_eps_options_t *opt,
+ dkChar const *val,
+ dkChar const * const *msg
+)
+{
+ int back = 0;
+
+
+#line 1186 "dk3bmeo.ctr"
+ if(val) {
+ back = dk3str_array_index(dk3bmeo_predictor_names, val, 0);
+ if(back > -1) {
+ opt->pred = back + 1;
+ back = 1;
+ } else {
+ back = 0;
+ dk3bmj_log_3(opt->app, DK3_LL_ERROR,msg,29,30,val,DK3_BMJ_LOG_BOTH,NULL);
+ }
+ } else {
+ opt->pred = DK3_COMPRESSION_PREDICTOR_TIFF; back = 1;
+ }
+
+#line 1198 "dk3bmeo.ctr"
+ return back;
+}
+
+
+
+/** Set background.
+ @param opt Option set to modify.
+ @param val Value for option.
+ @param msg Localized message texts.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bmeo_option_background(
+ dk3_bm_eps_options_t *opt,
+ dkChar const *val,
+ dkChar const * const *msg
+)
+{
+ int back = 0;
+ int i; /* Temporary conversion result. */
+ dkChar *pc; /* Current word pointer. */
+ dkChar *pn; /* Next word pointer. */
+
+
+#line 1222 "dk3bmeo.ctr"
+ if(val) {
+ pc = dk3str_start(val, NULL);
+ if(pc) {
+ pn = dk3str_chr(pc, dkT(':'));
+ if(pn) {
+ *(pn++) = dkT('\0');
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(pc, dkT("%d"), &i))
+#else
+ if (0 != dk3ma_i_from_string(&i, pc, NULL))
+#endif
+ {
+ opt->bgr = DK3_TO_RANGE(i,0,255);
+ pc = pn;
+ pn = dk3str_chr(pc, dkT(':'));
+ if(pn) {
+ *(pn++) = dkT('\0');
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(pc, dkT("%d"), &i))
+#else
+ if (0 != dk3ma_i_from_string(&i, pc, NULL))
+#endif
+ {
+ opt->bgg = DK3_TO_RANGE(i,0,255);
+ pc = pn;
+ pn = dk3str_chr(pc, dkT(':'));
+ if(pn) { *(pn++) = dkT('\0'); pn = dk3str_start(pn, NULL); }
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(pc, dkT("%d"), &i))
+#else
+ if (0 != dk3ma_i_from_string(&i, pc, NULL))
+#endif
+ {
+ opt->bgb = DK3_TO_RANGE(i,0,255);
+ back = 1;
+ if(pn) {
+ back = 0;
+ if(dk3str_is_bool(pn)) {
+ back = 1;
+ opt->fbg = (dk3str_is_on(pn) ? 1 : 0);
+ } else {
+ /* ERROR: Not a boolean! */
+ dk3bmj_log_3(
+ opt->app, DK3_LL_ERROR,msg,27,28,pn,DK3_BMJ_LOG_BOTH,NULL
+ );
+ }
+ }
+ } else {
+ /* ERROR: Not a number! */
+ dk3bmj_log_3(
+ opt->app, DK3_LL_ERROR,msg,24,25,pc,DK3_BMJ_LOG_BOTH,NULL
+ );
+ }
+ } else {
+ /* ERROR: Not a number! */
+ dk3bmj_log_3(
+ opt->app, DK3_LL_ERROR,msg,24,25,pc,DK3_BMJ_LOG_BOTH,NULL
+ );
+ }
+ } else {
+ /* ERROR: Syntax! */
+ dk3bmj_log_3(
+ opt->app, DK3_LL_ERROR,msg,32,33,pc,DK3_BMJ_LOG_BOTH,NULL
+ );
+ }
+ } else {
+ /* ERROR: Not a number! */
+ dk3bmj_log_3(
+ opt->app, DK3_LL_ERROR,msg,24,25,pc,DK3_BMJ_LOG_BOTH,NULL
+ );
+ }
+ } else {
+ /* ERROR: Syntax! */
+ dk3bmj_log_3(opt->app, DK3_LL_ERROR,msg,32,33,pc,DK3_BMJ_LOG_BOTH,NULL);
+ }
+ } else {
+ /* ERROR: Empty string */
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR,msg,31,DK3_BMJ_LOG_BOTH,NULL);
+ }
+ } else {
+ opt->bgr = 255; opt->bgg = 255; opt->bgb = 255; opt->fbg = 1;
+ }
+
+#line 1304 "dk3bmeo.ctr"
+ return back;
+}
+
+
+
+/** Set resolution, numeric or by name.
+ @param opt Option set to modify.
+ @param val Value for option.
+ @param msg Localized message texts.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bmeo_option_resolution(
+ dk3_bm_eps_options_t *opt,
+ dkChar const *val,
+ dkChar const * const *msg
+)
+{
+ int back = 0;
+ double d; /* Temporary conversion result. */
+
+
+#line 1326 "dk3bmeo.ctr"
+ if(val) {
+ if(dk3str_casecmp(dk3bmeo_kw[1], val) == 0) {
+ opt->szmode = DK3_BMEPS_SIZE_1_1;
+
+#line 1329 "dk3bmeo.ctr"
+ back = 1;
+ } else {
+ if(dk3str_casecmp(dk3bmeo_kw[2], val) == 0) {
+ opt->szmode = DK3_BMEPS_SIZE_CHUNK;
+
+#line 1333 "dk3bmeo.ctr"
+ back = 1;
+ } else {
+ if(dk3str_casecmp(dk3bmeo_kw[3], val) == 0) {
+ opt->szmode = DK3_BMEPS_SIZE_1_1;
+
+#line 1337 "dk3bmeo.ctr"
+ back = 1;
+ } else {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(val, dkT("%lf"), &d))
+#else
+ if (0 != dk3ma_d_from_string(&d, val, NULL))
+#endif
+ {
+ opt->szmode = DK3_BMEPS_SIZE_SPECIFIED;
+
+#line 1346 "dk3bmeo.ctr"
+ opt->resolution = d;
+ back = 1;
+ } else {
+ /* ERROR: Illegal resolution value */
+ dk3bmj_log_3(
+ opt->app, DK3_LL_ERROR,msg,35,36,val,DK3_BMJ_LOG_BOTH,NULL
+ );
+ }
+ }
+ }
+ }
+ } else {
+ /* ERROR: Missing value! */
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR,msg,34,DK3_BMJ_LOG_BOTH,NULL);
+ }
+
+
+#line 1362 "dk3bmeo.ctr"
+ return back;
+}
+
+
+
+/** Set paper size.
+ @param opt Option set to modify.
+ @param val Value for option.
+ @param msg Localized message texts.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bmeo_option_paper(
+ dk3_bm_eps_options_t *opt,
+ dkChar const *val,
+ dkChar const * const *msg
+)
+{
+ int back = 0;
+
+
+#line 1383 "dk3bmeo.ctr"
+ if(val) {
+ back = dk3bmeo_set_paper_size_complain(opt, val, 1);
+ opt->szmode = DK3_BMEPS_SIZE_PAPER;
+
+#line 1386 "dk3bmeo.ctr"
+ } else {
+ /* ERROR: Missing value! */
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR,msg,37,DK3_BMJ_LOG_BOTH,NULL);
+ }
+
+#line 1390 "dk3bmeo.ctr"
+ return back;
+}
+
+
+
+int
+dk3bmeo_apply_option(
+ dk3_bm_eps_options_t *opt,
+ dkChar const *str,
+ dkChar const * const *msg
+)
+{
+ dkChar bu[1024]; /* Private copy of str. */
+ dkChar *p1; /* String start, option value. */
+ int ind; /* Option name index. */
+ int back = 0;
+
+
+#line 1407 "dk3bmeo.ctr"
+ if((opt) && (str)) {
+ p1 = dk3str_start(str, NULL);
+ if(p1) {
+ if(dk3str_len(p1) < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy_not_overlapped(bu, p1);
+ p1 = dk3str_chr(bu, dkT('='));
+ if(p1) {
+ *(p1++) = dkT('\0');
+ p1 = dk3str_start(p1, NULL);
+ }
+ ind = dk3str_array_index(dk3bmeo_option_names, bu, 0);
+ switch(ind) {
+ case 0: { /* PS level */
+ back = dk3bmeo_option_pslevel(opt, p1, msg);
+ } break;
+ case 1: { /* Color flag */
+ back = dk3bmeo_set_boolean(opt, &(opt->color), p1, msg);
+ } break;
+ case 2: { /* DSC flag */
+ back = dk3bmeo_set_boolean(opt, &(opt->dsc), p1, msg);
+ } break;
+ case 3: { /* Draft flag */
+ back = dk3bmeo_set_boolean(opt, &(opt->draft), p1, msg);
+ } break;
+ case 4: { /* Flate predictor name */
+ back = dk3bmeo_option_predictor(opt, p1, msg);
+ } break;
+ case 5: { /* Duplex flag */
+ back = dk3bmeo_set_boolean(opt, &(opt->duplex), p1, msg);
+ } break;
+ case 6: { /* Tumble for duplex flag */
+ back = dk3bmeo_set_boolean(opt, &(opt->tumble), p1, msg);
+ } break;
+ case 7: { /* DCT flag */
+ back = dk3bmeo_set_boolean(opt, &(opt->dct), p1, msg);
+ } break;
+ case 8: { /* Background color and optional force flag */
+ back = dk3bmeo_option_background(opt, p1, msg);
+ } break;
+ case 9: { /* Interpolation flag */
+ back = dk3bmeo_set_boolean(opt, &(opt->ip), p1, msg);
+ } break;
+ case 10: { /* JPEG interpolation flag */
+ back = dk3bmeo_set_boolean(opt, &(opt->jip), p1, msg);
+ } break;
+ case 11: { /* Resolution, dpi number or name */
+ back = dk3bmeo_option_resolution(opt, p1, msg);
+ } break;
+ case 12: { /* Paper size, name or numeric */
+ back = dk3bmeo_option_paper(opt, p1, msg);
+ } break;
+ case 13: { /* Make */
+ back = dk3bmeo_set_boolean(opt, &(opt->make), p1, msg);
+ } break;
+ case 14: { /* Keep aspect ratio. */
+ back = dk3bmeo_set_boolean(opt, &(opt->kar), p1, msg);
+ } break;
+ case 15: { /* Reduce bits per component if possible. */
+
+
+#line 1466 "dk3bmeo.ctr"
+ back = dk3bmeo_set_boolean(opt, &(opt->rbpc), p1, msg);
+ } break;
+ default: {
+ /* ERROR: Unknown option name! */
+ dk3bmj_log_3(
+ opt->app, DK3_LL_ERROR,msg,22,23,bu,DK3_BMJ_LOG_BOTH,NULL
+ );
+ } break;
+ }
+ } else {
+
+#line 1476 "dk3bmeo.ctr"
+ /* ERROR: Configuration string too long! */
+ dk3bmj_log_3(opt->app, DK3_LL_ERROR,msg,20,21,p1,DK3_BMJ_LOG_BOTH,NULL);
+ }
+ } else {
+
+#line 1480 "dk3bmeo.ctr"
+ /* ERROR: Empty configuration string! */
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR,msg,19,DK3_BMJ_LOG_BOTH,NULL);
+ }
+ }
+
+#line 1484 "dk3bmeo.ctr"
+ return back;
+}
+
+
+
+#if 0
+int
+dk3bmeo_set_language(
+ dk3_bm_eps_options_t *opt, dkChar const *str, dk3_app_t *app
+)
+{
+ dkChar bu[1024]; /* Private copy of str. */
+ dkChar const * const *msg; /* Localized messages. */
+ dkChar *pn; /* Next part to process. */
+ dkChar *pc; /* Current part to process. */
+ dkChar *pt; /* Type. */
+ int back = 0;
+ int lang = -1; /* Language. */
+ int mode = -1; /* Mode. */
+
+
+#line 1504 "dk3bmeo.ctr"
+ msg = dk3app_messages(
+ opt->app,
+ dk3bmep_str_get_string_table_name(),
+ (dkChar const **)dk3bmep_str_get_message_texts()
+ );
+ if(!(msg)) {
+ msg = dk3bmep_str_get_message_texts();
+ }
+ if((opt) && (str)) {
+ if(dk3str_len(str) < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy_not_overlapped(bu, str);
+ pn = dk3str_chr(bu, dkT(','));
+ if(pn) { *(pn++) = dkT('\0'); }
+ pc = dk3str_start(bu, NULL);
+ if(pc) {
+ pt = dk3str_chr(pc, dkT('.'));
+ if(pt) { *(pt++) = dkT('\0'); pt = dk3str_start(pt, NULL); }
+ lang = dk3str_array_index(dk3bmeo_driver_names, pc, 0);
+ switch(lang) {
+ case 0: {
+ lang = DK3_BMEPS_DRIVER_PS; back = 1;
+ } break;
+ case 1: {
+ lang = DK3_BMEPS_DRIVER_EPS; back = 1;
+ } break;
+ case 2: {
+ lang = DK3_BMEPS_DRIVER_PDF; back = 1;
+ } break;
+ case 3: {
+ back = DK3_BMEPS_DRIVER_BB; back = 1;
+ } break;
+ default: {
+ /* ERROR: Unknown language! */
+ if(app) {
+ dkChar const * const *msg;
+ msg = dk3app_messages(
+ app,
+ dk3bmep_str_get_string_table_name(),
+ (dkChar const **)dk3bmep_str_get_message_texts()
+ );
+ if(msg) {
+ dk3app_log_3(app, DK3_LL_ERROR, msg, 74, 75, pc);
+ }
+ }
+ } break;
+ }
+ if(back) {
+ mode = DK3_BMEPS_MODE_OBJECT;
+ if(pt) {
+ back = 0;
+ switch(dk3str_array_index(dk3bmeo_mode_names, pt, 0)) {
+ case 0: case 1: {
+ mode = DK3_BMEPS_MODE_IMAGE; back = 1;
+ } break;
+ case 2: case 3: {
+ mode = DK3_BMEPS_MODE_OBJECT; back = 1;
+ } break;
+ case 4: case 5: {
+ mode = DK3_BMEPS_MODE_DOCUMENT; back = 1;
+ } break;
+ }
+ }
+ if(back) {
+ dk3bmeo_set_driver_and_mode(opt, lang, mode);
+ pc = pn;
+ while(pc) {
+ pn = dk3str_chr(pc, dkT(','));
+ if(pn) { *(pn++) = dkT('\0'); pn = dk3str_start(pn, NULL); }
+ if(!dk3bmeo_apply_option(opt, pc, msg)) { back = 0; }
+ pc = pn;
+ }
+ }
+ }
+ } else {
+ /* ##### ERROR: Missing language/mode! */
+ }
+ } else {
+ /* ERROR: String too long! */
+ dk3bmj_log_3(opt->app, DK3_LL_ERROR,msg,12,13,str,DK3_BMJ_LOG_BOTH,job);
+ }
+ }
+
+#line 1585 "dk3bmeo.ctr"
+ return back;
+}
+#else
+int
+dk3bmeo_set_language(
+ dk3_bm_eps_options_t *opt,
+ dkChar const *str,
+ dk3_app_t *app
+)
+{
+ dkChar bu[1024]; /* Private copy of str. */
+ dkChar const * const *msg; /* Localized messages. */
+ dkChar *pn; /* Next part to process. */
+ dkChar *pc; /* Current part to process. */
+ dkChar *pt; /* Type. */
+ int back = 0;
+
+
+#line 1602 "dk3bmeo.ctr"
+ msg = dk3app_messages(
+ opt->app,
+ dk3bmep_str_get_string_table_name(),
+ (dkChar const **)dk3bmep_str_get_message_texts()
+ );
+ if(!(msg)) {
+ msg = dk3bmep_str_get_message_texts();
+ }
+ if((opt) && (str)) {
+
+#line 1611 "dk3bmeo.ctr"
+ dk3bmeo_init(opt);
+ opt->app = app;
+ if(dk3str_len(str) < DK3_SIZEOF(bu,dkChar)) {
+
+#line 1614 "dk3bmeo.ctr"
+ dk3str_cpy_not_overlapped(bu, str);
+ pc = dk3str_start(bu, NULL);
+ if(pc) {
+
+#line 1617 "dk3bmeo.ctr"
+ pn = dk3str_chr(pc, dkT(','));
+ if(pn) { *(pn++) = dkT('\0'); pn = dk3str_start(pn, NULL); }
+ pt = dk3str_chr(pc, dkT('.'));
+ if(pt) { *(pt++) = dkT('\0'); pt = dk3str_start(pt, NULL); }
+ back = 1;
+
+#line 1622 "dk3bmeo.ctr"
+ opt->mode = DK3_BMEPS_MODE_OBJECT;
+ opt->szmode = DK3_BMEPS_SIZE_1_1;
+
+#line 1624 "dk3bmeo.ctr"
+ switch(dk3str_array_index(dk3bmeo_driver_names, pc, 0)) {
+ case 0: {
+ opt->dr = DK3_BMEPS_DRIVER_PS;
+
+#line 1627 "dk3bmeo.ctr"
+ } break;
+ case 1: {
+ opt->dr = DK3_BMEPS_DRIVER_EPS;
+
+#line 1630 "dk3bmeo.ctr"
+ } break;
+ case 2: {
+ opt->dr = DK3_BMEPS_DRIVER_PDF;
+
+#line 1633 "dk3bmeo.ctr"
+ } break;
+ case 3: {
+ opt->dr = DK3_BMEPS_DRIVER_BB;
+
+#line 1636 "dk3bmeo.ctr"
+ opt->mode = DK3_BMEPS_MODE_OBJECT;
+ opt->szmode = DK3_BMEPS_SIZE_1_1;
+
+#line 1638 "dk3bmeo.ctr"
+ } break;
+ default: {
+
+#line 1640 "dk3bmeo.ctr"
+ back = 0;
+ dk3bmj_log_3(
+ opt->app, DK3_LL_ERROR,msg,15,16,pc,DK3_BMJ_LOG_BOTH,NULL
+ );
+ } break;
+ }
+ if(back) {
+
+#line 1647 "dk3bmeo.ctr"
+ if(pt) {
+
+#line 1648 "dk3bmeo.ctr"
+ switch(dk3str_array_abbr(dk3bmeo_mode_names, pt, dkT('$'), 0)) {
+ case 0: {
+
+#line 1650 "dk3bmeo.ctr"
+ opt->mode = DK3_BMEPS_MODE_IMAGE;
+ opt->szmode = DK3_BMEPS_SIZE_CHUNK;
+
+#line 1652 "dk3bmeo.ctr"
+ } break;
+ case 1: {
+
+#line 1654 "dk3bmeo.ctr"
+ opt->mode = DK3_BMEPS_MODE_OBJECT;
+ opt->szmode = DK3_BMEPS_SIZE_1_1;
+
+#line 1656 "dk3bmeo.ctr"
+ } break;
+ case 2: {
+ opt->mode = DK3_BMEPS_MODE_DOCUMENT;
+
+#line 1659 "dk3bmeo.ctr"
+ opt->szmode = DK3_BMEPS_SIZE_PAPER;
+
+#line 1660 "dk3bmeo.ctr"
+ } break;
+ default: {
+
+#line 1662 "dk3bmeo.ctr"
+ back = 0;
+ /* ERROR: Illegal mode! */
+ dk3bmj_log_3(
+ opt->app, DK3_LL_ERROR,msg,17,18,pt,DK3_BMJ_LOG_BOTH,NULL
+ );
+ } break;
+ }
+ if(opt->dr == DK3_BMEPS_DRIVER_BB) {
+
+#line 1670 "dk3bmeo.ctr"
+ if(opt->mode != DK3_BMEPS_MODE_OBJECT) {
+
+#line 1671 "dk3bmeo.ctr"
+ back = 0;
+ /* ERROR: BB driver can only produce objects! */
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR,msg,8,DK3_BMJ_LOG_BOTH,NULL);
+ }
+ }
+ } else {
+
+#line 1677 "dk3bmeo.ctr"
+ }
+ dk3bmeo_initialize_for_driver_and_mode(opt);
+ if(back) {
+
+#line 1680 "dk3bmeo.ctr"
+ pc = pn;
+ while(pc) {
+
+#line 1682 "dk3bmeo.ctr"
+ pn = dk3str_chr(pc, dkT(','));
+ if(pn) { *(pn++) = dkT('\0'); pn = dk3str_start(pn, NULL); }
+ if(!dk3bmeo_apply_option(opt, pc, msg)) { back = 0; }
+ pc = pn;
+ }
+ }
+ }
+ } else {
+
+#line 1690 "dk3bmeo.ctr"
+ /* ERROR: Empty string! */
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR,msg,14,DK3_BMJ_LOG_BOTH,NULL);
+ }
+ } else {
+
+#line 1694 "dk3bmeo.ctr"
+ /* ERROR: String too long! */
+ dk3bmj_log_3(opt->app, DK3_LL_ERROR,msg,12,13,str,DK3_BMJ_LOG_BOTH,NULL);
+ }
+ } else {
+
+#line 1698 "dk3bmeo.ctr"
+ }
+
+#line 1699 "dk3bmeo.ctr"
+ return back;
+}
+#endif
+
+
+
+int
+dk3bmeo_check(
+ dk3_bm_eps_options_t *opt,
+ int type,
+ dk3_app_t *app,
+ dk3_bm_conversion_job_t *job
+)
+{
+ dkChar const * const *msg; /* Localized message texts. */
+ int back = 1; /* No error found (yet). */
+
+
+#line 1716 "dk3bmeo.ctr"
+ /*
+ Check driver.
+ */
+ msg = dk3app_messages(
+ opt->app,
+ dk3bmep_str_get_string_table_name(),
+ (dkChar const **)dk3bmep_str_get_message_texts()
+ );
+ if(!(msg)) {
+ msg = dk3bmep_str_get_message_texts();
+ }
+ if(type) {
+
+#line 1728 "dk3bmeo.ctr"
+ switch(opt->dr) {
+ case DK3_BMEPS_DRIVER_PS:
+ case DK3_BMEPS_DRIVER_PDF:
+ {
+
+#line 1732 "dk3bmeo.ctr"
+ }
+ break;
+ default: {
+
+#line 1735 "dk3bmeo.ctr"
+ back = 0;
+ /* ERROR: Placed objects can use the PS or PDF driver only! */
+ opt->dr = DK3_BMEPS_DRIVER_PS;
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR, msg, 2, DK3_BMJ_LOG_BOTH, job);
+ } break;
+ }
+ } else {
+
+#line 1742 "dk3bmeo.ctr"
+ switch(opt->dr) {
+ case DK3_BMEPS_DRIVER_PS:
+ case DK3_BMEPS_DRIVER_EPS:
+ case DK3_BMEPS_DRIVER_PDF:
+ case DK3_BMEPS_DRIVER_BB:
+ {
+
+#line 1748 "dk3bmeo.ctr"
+ }
+ break;
+ default: {
+
+#line 1751 "dk3bmeo.ctr"
+ back = 0;
+ /* ERROR: Illegal driver, must be PS, EPS, PDF, BB! */
+ opt->dr = DK3_BMEPS_DRIVER_PDF;
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR, msg, 3, DK3_BMJ_LOG_BOTH, job);
+ } break;
+ }
+ }
+ /*
+ Check mode.
+ */
+ if(type) {
+
+#line 1762 "dk3bmeo.ctr"
+ if(opt->mode != DK3_BMEPS_MODE_PLACED_OBJECT) {
+ back = 0;
+
+#line 1764 "dk3bmeo.ctr"
+ /* ERROR: Illegal mode, must be placed object! */
+ opt->mode = DK3_BMEPS_MODE_PLACED_OBJECT;
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR, msg, 4, DK3_BMJ_LOG_BOTH, job);
+ }
+ } else {
+
+#line 1769 "dk3bmeo.ctr"
+ if(opt->mode == DK3_BMEPS_MODE_PLACED_OBJECT) {
+
+#line 1770 "dk3bmeo.ctr"
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR, msg, 5, DK3_BMJ_LOG_BOTH, job);
+ } else {
+ switch(opt->dr) {
+ case DK3_BMEPS_DRIVER_PS: {
+
+#line 1774 "dk3bmeo.ctr"
+ switch(opt->mode) {
+ case DK3_BMEPS_MODE_IMAGE:
+ case DK3_BMEPS_MODE_OBJECT:
+ case DK3_BMEPS_MODE_DOCUMENT:
+ {
+
+#line 1779 "dk3bmeo.ctr"
+ }
+ break;
+ default: {
+
+#line 1782 "dk3bmeo.ctr"
+ back = 0;
+ /* ERROR: Illegal mode, must be image, object, document! */
+ opt->mode = DK3_BMEPS_MODE_IMAGE;
+ dk3bmj_log_1(opt->app,DK3_LL_ERROR,msg,6,DK3_BMJ_LOG_BOTH,job);
+ } break;
+ }
+ } break;
+ case DK3_BMEPS_DRIVER_EPS: {
+
+#line 1790 "dk3bmeo.ctr"
+ switch(opt->mode) {
+ case DK3_BMEPS_MODE_IMAGE:
+ case DK3_BMEPS_MODE_OBJECT:
+ {
+
+#line 1794 "dk3bmeo.ctr"
+ }
+ break;
+ default: {
+
+#line 1797 "dk3bmeo.ctr"
+ back = 0;
+ /* ERROR: Illegal mode, must be image or object! */
+ opt->mode = DK3_BMEPS_MODE_OBJECT;
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR,msg,7,DK3_BMJ_LOG_BOTH,job);
+ } break;
+ }
+ } break;
+ case DK3_BMEPS_DRIVER_PDF: {
+
+#line 1805 "dk3bmeo.ctr"
+ switch(opt->mode) {
+ case DK3_BMEPS_MODE_IMAGE:
+ case DK3_BMEPS_MODE_OBJECT:
+ case DK3_BMEPS_MODE_DOCUMENT:
+ {
+
+#line 1810 "dk3bmeo.ctr"
+ }
+ break;
+ default: {
+
+#line 1813 "dk3bmeo.ctr"
+ back = 0;
+ /* ERROR: Illegal mode, must be image, object, document! */
+ opt->mode = DK3_BMEPS_MODE_OBJECT;
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR,msg,6,DK3_BMJ_LOG_BOTH,job);
+ } break;
+ }
+ } break;
+ case DK3_BMEPS_DRIVER_BB: {
+
+#line 1821 "dk3bmeo.ctr"
+ switch(opt->mode) {
+ case DK3_BMEPS_MODE_OBJECT:
+ {
+
+#line 1824 "dk3bmeo.ctr"
+ }
+ break;
+ default: {
+
+#line 1827 "dk3bmeo.ctr"
+ back = 0;
+ /* ERROR: Illegal mode, BB requires object! */
+ opt->mode = DK3_BMEPS_MODE_OBJECT;
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR,msg,8,DK3_BMJ_LOG_BOTH,job);
+ } break;
+ }
+ if(opt->draft) {
+ opt->draft = 0;
+ /* ERROR: Draft mode can not be used for bounding box! */
+ }
+ } break;
+ }
+ }
+ }
+ /*
+ Check size mode.
+ */
+ if(type) {
+
+#line 1845 "dk3bmeo.ctr"
+ } else {
+
+#line 1846 "dk3bmeo.ctr"
+ switch(opt->mode) {
+ case DK3_BMEPS_MODE_IMAGE: {
+
+#line 1848 "dk3bmeo.ctr"
+ switch(opt->szmode) {
+ case DK3_BMEPS_SIZE_1_1: {
+
+#line 1850 "dk3bmeo.ctr"
+ } break;
+ case DK3_BMEPS_SIZE_CHUNK: {
+
+#line 1852 "dk3bmeo.ctr"
+ } break;
+ case DK3_BMEPS_SIZE_SPECIFIED: {
+
+#line 1854 "dk3bmeo.ctr"
+ } break;
+ case DK3_BMEPS_SIZE_PAPER: {
+
+#line 1856 "dk3bmeo.ctr"
+ } break;
+ default: {
+
+#line 1858 "dk3bmeo.ctr"
+ back = 0;
+ /* ERROR: Illegal size mode! */
+ opt->szmode = DK3_BMEPS_SIZE_1_1;
+
+#line 1861 "dk3bmeo.ctr"
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR,msg,9,DK3_BMJ_LOG_BOTH,job);
+ } break;
+ }
+ } break;
+ case DK3_BMEPS_MODE_OBJECT: {
+
+#line 1866 "dk3bmeo.ctr"
+ switch(opt->szmode) {
+ case DK3_BMEPS_SIZE_1_1: {
+
+#line 1868 "dk3bmeo.ctr"
+ } break;
+ default: {
+
+#line 1870 "dk3bmeo.ctr"
+ back = 0;
+ /* ERROR: Illegal size mode, must be 1:1! */
+ opt->szmode = DK3_BMEPS_SIZE_1_1;
+
+#line 1873 "dk3bmeo.ctr"
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR,msg,10,DK3_BMJ_LOG_BOTH,job);
+ } break;
+ }
+ } break;
+ case DK3_BMEPS_MODE_DOCUMENT: {
+
+#line 1878 "dk3bmeo.ctr"
+ if(opt->draft) {
+ opt->draft = 0;
+ /* ERROR: Draft can not be used with documents! */
+ dk3bmj_log_1(opt->app, DK3_LL_WARNING,msg,11,DK3_BMJ_LOG_BOTH,job);
+ }
+ switch(opt->szmode) {
+ case DK3_BMEPS_SIZE_1_1: {
+
+#line 1885 "dk3bmeo.ctr"
+ } break;
+ case DK3_BMEPS_SIZE_CHUNK: {
+
+#line 1887 "dk3bmeo.ctr"
+ } break;
+ case DK3_BMEPS_SIZE_SPECIFIED: {
+
+#line 1889 "dk3bmeo.ctr"
+ } break;
+ case DK3_BMEPS_SIZE_PAPER: {
+
+#line 1891 "dk3bmeo.ctr"
+ } break;
+ default: {
+
+#line 1893 "dk3bmeo.ctr"
+ back = 0;
+ /* ERROR: Illegal size mode! */
+ opt->szmode = DK3_BMEPS_SIZE_1_1;
+
+#line 1896 "dk3bmeo.ctr"
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR,msg,9,DK3_BMJ_LOG_BOTH,job);
+ } break;
+ }
+ } break;
+ }
+ }
+
+#line 1902 "dk3bmeo.ctr"
+ return back;
+}
+
diff --git a/support/dktools/dk3bmeo.ctr b/support/dktools/dk3bmeo.ctr
new file mode 100644
index 0000000000..785d33cb0e
--- /dev/null
+++ b/support/dktools/dk3bmeo.ctr
@@ -0,0 +1,1904 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Initialize bmeps option set.
+ @param opt Option set to initialize.
+*/
+void
+dk3bmeo_init(dk3_bm_eps_options_t *opt);
+
+/** Allocate and initalize new option set.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new option set on success, NULL on error.
+*/
+dk3_bm_eps_options_t *
+dk3bmeo_new_app(dk3_app_t *app);
+
+/** Get run mode.
+ @param opt Option set.
+ @return Run mode DK3_BMEPS_MODE_xxx, see @ref dkbmmodes.
+*/
+int
+dk3bmeo_get_mode(dk3_bm_eps_options_t *opt);
+
+/** Set output driver and mode.
+ @param opt Option set.
+ @param driver Output driver DK3_BMEPS_DRIVER_xxx,
+ see @ref bmepsdrivers.
+ @param mode Output mode DK3_BMEPS_MODE_xxx,
+ see @ref dkbmmodes.
+*/
+void
+dk3bmeo_set_driver_and_mode(dk3_bm_eps_options_t *opt, int driver, int mode);
+
+/** Set paper size by name.
+ @param opt Option set.
+ @param psn Paper size name.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3bmeo_set_paper_size(dk3_bm_eps_options_t *opt, dkChar const *psn);
+
+/** Get output driver.
+ @param opt Option set.
+ @return Output driver DK3_BMEPS_DRIVER_xxx, see @ref bmepsdrivers.
+*/
+int
+dk3bmeo_get_driver(dk3_bm_eps_options_t *opt);
+
+/** Enable/disable draft mode.
+ @param opt Option set.
+ @param drflag 1=draft, 0=normal.
+*/
+void
+dk3bmeo_set_draft(dk3_bm_eps_options_t *opt, int drflag);
+
+/** Get draft mode setting.
+ @param opt Option set.
+ @return 1 for draft mode, 0 for normal mode.
+*/
+int
+dk3bmeo_get_draft(dk3_bm_eps_options_t *opt);
+
+/** Set duplex printing.
+ @param opt Option set.
+ @param duplex Flag: Enable duplex output.
+*/
+void
+dk3bmeo_set_duplex(dk3_bm_eps_options_t *opt, int duplex);
+
+/** Retrieve duplex setting.
+ @param opt Option set.
+ @return 1 for duplex, 0 for simplex output.
+*/
+int
+dk3bmeo_get_duplex(dk3_bm_eps_options_t *opt);
+
+/** Set flate predictor.
+ @param opt Option set.
+ @param pred Predictor DK3_COMPRESSION_PREDICTOR_xxx, see
+ @ref flatepredictors.
+*/
+void
+dk3bmeo_set_predictor(dk3_bm_eps_options_t *opt, int pred);
+
+/** Get compression predictor.
+ @param opt Option set.
+ @return Predictor DK3_COMPRESSION_PREDICTOR_xxx,
+ see @ref flatepredictors.
+*/
+int
+dk3bmeo_get_predictor(dk3_bm_eps_options_t *opt);
+
+/** Set image origin.
+ @param opt Option set.
+ @param io Image origin DK3_IMAGE_ORIGIN_xxx, se @ref imageorigin.
+*/
+void
+dk3bmeo_set_origin(dk3_bm_eps_options_t *opt, int io);
+
+/** Get image origin.
+ @param opt Option set.
+ @return Image origin DK3_IMAGE_ORIGIN_xxx, se @ref imageorigin.
+*/
+int
+dk3bmeo_get_origin(dk3_bm_eps_options_t *opt);
+
+/** Set PS level.
+ @param opt Option set.
+ @param psl PS level (2 or 3).
+*/
+void
+dk3bmeo_set_ps_level(dk3_bm_eps_options_t *opt, int psl);
+
+/** Get PS level.
+ @param opt Option set.
+ @return PS level (2 or 3).
+*/
+int
+dk3bmeo_get_ps_level(dk3_bm_eps_options_t *opt);
+
+/** Enable/disable direct transfer of DCT data.
+ @param opt Option set.
+ @param dct 1=enable, 0=disable.
+*/
+void
+dk3bmeo_set_dct(dk3_bm_eps_options_t *opt, int dct);
+
+/** Get flag for direct DCT data transfer.
+ @param opt Option set.
+ @return 1=enabled, 0=disabled.
+*/
+int
+dk3bmeo_get_dct(dk3_bm_eps_options_t *opt);
+
+/** Set flag to keep aspect ratio.
+ @param opt Option set.
+ @param kar 1=keep aspect ratio, 0=allow different scales for
+ x and y.
+*/
+void
+dk3bmeo_set_keep_aspect_ratio(dk3_bm_eps_options_t *opt, int kar);
+
+/** Get flag for keeping aspect ratio.
+ @param opt Option set.
+ @return 1 for keep aspect ratio, 0 for allow different
+ scaling for x and y.
+*/
+int
+dk3bmeo_get_keep_aspect_ratio(dk3_bm_eps_options_t *opt);
+
+/** Set background.
+ @param opt Option set.
+ @param r Background red component.
+ @param g Background green component.
+ @param b Background blue component.
+ @param f Flag: Force this background over background chunk
+ from image file.
+*/
+void
+dk3bmeo_set_background(dk3_bm_eps_options_t *opt, int r, int g, int b, int f);
+
+/** Get background red component.
+ @param opt Option set.
+ @return Background red component.
+*/
+int
+dk3bmeo_get_background_red(dk3_bm_eps_options_t *opt);
+
+/** Get background green component.
+ @param opt Option set.
+ @return Background green component.
+*/
+int
+dk3bmeo_get_background_green(dk3_bm_eps_options_t *opt);
+
+/** Get background blue component.
+ @param opt Option set.
+ @return Background blue component.
+*/
+int
+dk3bmeo_get_background_blue(dk3_bm_eps_options_t *opt);
+
+/** Get enforce background flag.
+ @param opt Option set.
+ @return 1 for enforce background over background chunk,
+ 0 for use background chunk if available.
+*/
+int
+dk3bmeo_get_background_force(dk3_bm_eps_options_t *opt);
+
+/** Enable/disable image interpolation.
+ @param opt Option set.
+ @param iip Flag: Image interpolation allowed.
+*/
+void
+dk3bmeo_set_interpolation(dk3_bm_eps_options_t *opt, int iip);
+
+/** Get image interpolation flag.
+ @param opt Option set.
+ @return 1 for image interpolation allowed, 0 for denied.
+*/
+int
+dk3bmeo_get_interpolation(dk3_bm_eps_options_t *opt);
+
+/** Enable/disable image interpolation for JPEG files.
+ @param opt Option set.
+ @param iip Flag: Image interpolation for JPEGs allowed or denied.
+*/
+void
+dk3bmeo_set_jpeg_interpolation(dk3_bm_eps_options_t *opt, int iip);
+
+/** Get image interpolation flag for JPEGs.
+ @param opt Option set.
+ @return 1 for image interpolation allowed, 0 for denied.
+*/
+int
+dk3bmeo_get_jpeg_interpolation(dk3_bm_eps_options_t *opt);
+
+/** Destroy option set, release memory.
+ @param opt Option set to destroy.
+*/
+void
+dk3bmeo_delete(dk3_bm_eps_options_t *opt);
+
+/** Apply one text option (argument to -o) to option set.
+ @param opt Option set to modify.
+ @param str Option text.
+ @param msg Message text array containing localized texts.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3bmeo_apply_option(
+ dk3_bm_eps_options_t *opt,
+ dkChar const *str,
+ dkChar const * const *msg
+);
+
+/** Set language (driver and mode, obtained from -l option).
+ @param opt Option set to modify.
+ @param str String containing configuration data.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3bmeo_set_language(
+ dk3_bm_eps_options_t *opt,
+ dkChar const *str,
+ dk3_app_t *app
+);
+
+/** Check options consistency.
+ On inconsistency, correct the options and return 0 so
+ a second check will return 1.
+ @param opt Option set.
+ @param type Invokation type (0=bmeps/wxbmeps, 1=placed object).
+ @param app Application structure for diagnostics, may be NULL.
+ @param job Conversion job structure.
+ @return 1 on success, 0 on error (corrections applied).
+*/
+int
+dk3bmeo_check(
+ dk3_bm_eps_options_t *opt,
+ int type,
+ dk3_app_t *app,
+ dk3_bm_conversion_job_t *job
+);
+
+/** Attempt to find PS level and page size from preferences.
+ @param opt Conversion option set, app must be initialized.
+*/
+void
+dk3bmeo_apply_preferences(dk3_bm_eps_options_t *opt);
+
+/** Set size mode in option set.
+ @param opt Option set.
+ @param newmode new size mode DK3_BMEPS_SIZE_xxx,
+ see @ref bmepssizehandling.
+*/
+void
+dk3bmeo_set_szmode(dk3_bm_eps_options_t *opt, int newmode);
+
+/** Retrieve image size mode.
+ @param opt Option set.
+ @return Size mode.
+*/
+int
+dk3bmeo_get_szmode(dk3_bm_eps_options_t *opt);
+
+/** Set image resolution.
+ @param opt Option set.
+ @param dpi Resolution in dpi (dots per inch).
+*/
+void
+dk3bmeo_set_resolution(dk3_bm_eps_options_t *opt, double dpi);
+
+/** Retrieve image resolution setting.
+ @param opt Option set.
+ @return Resolution in dpi if set, 72.0 is used as default.
+*/
+double
+dk3bmeo_get_resolution(dk3_bm_eps_options_t *opt);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+
+#include "dk3all.h"
+#include "dk3bmeo.h"
+#include "dk3bmeps.h"
+#include "dk3bmj.h"
+#include "dk3bm.h"
+
+
+$!trace-include
+
+
+
+/** Keywords used by the module.
+*/
+static dkChar const * const dk3bmeo_kw[] = {
+$!string-table macro=dkT
+#
+# 0: Preference name to retrieve default paper size
+#
+/print/paper-size
+#
+# 1: Resolution: 1 pixel = 1 pt
+#
+1px1pt
+#
+# 2: Resolution: Check image resolution chunk
+#
+chunk
+#
+# 3: Resolution: 1 pixel = 1pt
+#
+1:1
+#
+# 4: PS level supported by printer
+#
+/print/ps/level
+#
+# 5: Format string to scan PS level
+#
+%ld
+$!end
+};
+
+
+
+/** Names for options.
+*/
+static dkChar const * const dk3bmeo_option_names[] = {
+$!string-table macro=dkT
+#
+# 0: PS level
+#
+level
+#
+# 1: Flag: color allowed
+#
+color
+#
+# 2: Flag: DSC wanted
+#
+dsc
+#
+# 3: Flag: Draft
+#
+draft
+#
+# 4: Predictor name for flate compression
+#
+predictor
+#
+# 5: Flag: Duplex on
+#
+duplex
+#
+# 6: Flag: Tumble on for duplex
+#
+tumble
+#
+# 7: Flag: DCT pass-through allowed
+#
+dct
+#
+# 8: Background
+#
+bg
+#
+# 9: Flag: Interpolation on
+#
+interpolation
+#
+# 10: Flag: Interpolation allowed for JPEGs too
+#
+jpeg-interpolation
+#
+# 11: Resolution, dpi number or name like 1:1 or chunk
+#
+resolution
+#
+# 12: Paper size, either name or direct size
+#
+paper
+#
+# 13: Make mode
+#
+make
+#
+# 14: Keep aspect ratio
+#
+aspect
+#
+# 15: Reduce bits per component.
+#
+bpc
+$!end
+};
+
+
+
+/** Driver names.
+*/
+dkChar const * const dk3bmeo_driver_names[] = {
+$!string-table macro=dkT
+ps
+eps
+pdf
+bb
+$!end
+};
+
+
+
+/** Mode names
+*/
+dkChar const * const dk3bmeo_mode_names[] = {
+$!string-table macro=dkT
+#
+# 0: Image
+#
+i$mage
+#
+# 1: Object
+#
+o$bject
+#
+# 2: Document
+#
+d$ocument
+$!end
+};
+
+
+
+/** Names for flate compression predictors.
+ Order must match DK3_COMPRESSION_PREDICTOR_xxx
+ in dk3const.h, see @ref flatepredictors.
+*/
+dkChar const * const dk3bmeo_predictor_names[] = {
+$!string-table macro=dkT
+tiff
+sub
+up
+average
+paeth
+$!end
+};
+
+
+
+
+void
+dk3bmeo_init(dk3_bm_eps_options_t *opt)
+{
+ $? "+ dk3bmeo_init"
+ if(opt) {
+ (opt->ima).ps.w = 595.0;
+ (opt->ima).ps.h = 842.0;
+ (opt->ima).ps.i = 0.0;
+ (opt->ima).ps.o = 0.0;
+ (opt->ima).ps.t = 0.0;
+ (opt->ima).ps.b = 0.0;
+ opt->resolution = 72.0;
+ opt->app = NULL;
+ opt->mode = DK3_BMEPS_MODE_OBJECT;
+ opt->szmode = DK3_BMEPS_SIZE_1_1; $? ". szmode = 1:1"
+ opt->dr = DK3_BMEPS_DRIVER_PDF;
+ opt->pred = 0;
+ opt->io = 0;
+ opt->draft = 0;
+ opt->duplex = 0;
+ opt->tumble = 0;
+ opt->psl = 3;
+ opt->dsc = 0;
+ opt->dct = 1;
+ opt->kar = 1;
+ opt->bgr = 255; opt->bgg = 255; opt->bgb = 255; opt->fbg = 0;
+ opt->ip = 1; opt->jip = 0;
+ opt->make = 0;
+ opt->color = 1;
+ opt->to_stdout = 0;
+ opt->rbpc = 1;
+ } $? "- dk3bmeo_init"
+}
+
+
+
+dk3_bm_eps_options_t *
+dk3bmeo_new_app(dk3_app_t *app)
+{
+ dk3_bm_eps_options_t *back = NULL;
+ $? "+ dk3bmeo_new_app"
+ back = dk3_new_app(dk3_bm_eps_options_t,1,app);
+ if(back) {
+ dk3bmeo_init(back);
+ back->app = app;
+ } $? "- dk3bmeo_new_app %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+void
+dk3bmeo_delete(dk3_bm_eps_options_t *opt)
+{
+ $? "+ dk3bmeo_delete"
+ if(opt) {
+ opt->app = NULL;
+ dk3_delete(opt);
+ } $? "- dk3bmeo_delete"
+}
+
+
+
+int
+dk3bmeo_get_mode(dk3_bm_eps_options_t *opt)
+{
+ int back = DK3_BMEPS_MODE_IMAGE;
+ $? "+ dk3bmeo_get_mode"
+ if(opt) {
+ back = opt->mode;
+ } $? "- dk3bmeo_get_mode %d", back
+ return back;
+}
+
+
+
+/** Set paper size, complain if named size is not found.
+ @param opt Option set to receive size information.
+ @param psn Paper size name.
+ @param cond Flag: Complain (nonzero) or not (0).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bmeo_set_paper_size_complain(
+ dk3_bm_eps_options_t *opt, dkChar const *psn, int cond
+)
+{
+ dk3_paper_size_collection_t *psc; /* Paper size collection. */
+ dk3_paper_size_t const *pap; /* Paper size. */
+ dkChar const * const *msg; /* Localized message texts. */
+ int back = 0;
+ $? "+ dk3bmeo_set_paper_size"
+ msg = dk3app_messages(
+ opt->app,
+ dk3bmep_str_get_string_table_name(),
+ (dkChar const **)dk3bmep_str_get_message_texts()
+ );
+ if(!(msg)) {
+ msg = dk3bmep_str_get_message_texts();
+ }
+ if((opt) && (psn)) { $? ". args ok"
+ if(opt->app) { $? ". app ok"
+ psc = dk3paper_open_app(opt->app);
+ if(psc) { $? ". collection ok"
+ pap = dk3paper_find(psc, psn);
+ if(pap) { $? ". found"
+ (opt->ima).ps.w = pap->w;
+ (opt->ima).ps.h = pap->h;
+ (opt->ima).ps.i = pap->i;
+ (opt->ima).ps.o = pap->o;
+ (opt->ima).ps.t = pap->t;
+ (opt->ima).ps.b = pap->b;
+ back = 1;
+ } else { $? "! not found"
+ /* ERROR: No such paper size. */
+ dk3bmj_log_3(
+ opt->app, DK3_LL_ERROR,msg,39,40,psn,DK3_BMJ_LOG_BOTH,NULL
+ );
+ }
+ dk3paper_close(psc);
+ } else { $? "! collection"
+ }
+ if(!(opt->mode == DK3_BMEPS_MODE_DOCUMENT)) { $? "! mode"
+ /* ERROR: Not a document */
+ if(cond) {
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR,msg,38,DK3_BMJ_LOG_BOTH,NULL);
+ }
+ }
+ } else { $? "! app"
+ /* ERROR: No app! */
+ }
+ } else { $? "! args"
+ } $? "- dk3bmeo_set_paper_size %d", back
+ return back;
+}
+
+
+
+void
+dk3bmeo_apply_preferences(dk3_bm_eps_options_t *opt)
+{
+ dkChar psn[64]; /* Buffer for paper size name. */
+ int psl; /* PS level. */
+ $? "+ dk3bmeo_apply_preferences"
+ if(opt->app) {
+ if(dk3app_get_pref(opt->app,dk3bmeo_kw[0],psn,DK3_SIZEOF(psn,dkChar)))
+ {
+ (void)dk3bmeo_set_paper_size_complain(opt, psn, 0);
+ }
+ if(dk3app_get_pref(opt->app,dk3bmeo_kw[4],psn,DK3_SIZEOF(psn,dkChar)))
+ {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(psn, dk3bmeo_kw[5], &psl) == 1)
+#else
+ if (0 != dk3ma_i_from_string(&psl, psn, NULL))
+#endif
+ {
+ if(psl > 3) { psl = 3; }
+ if(psl < 2) { psl = 2; }
+ opt->psl = psl;
+ }
+ }
+ }
+ $? "- dk3bmeo_apply_preferences"
+}
+
+
+
+/** Initialize for a given driver and mode.
+ @param opt Option set to complete setup.
+*/
+static
+void
+dk3bmeo_initialize_for_driver_and_mode(dk3_bm_eps_options_t *opt)
+{
+ switch(opt->dr) {
+ case DK3_BMEPS_DRIVER_PS: {
+ } break;
+ case DK3_BMEPS_DRIVER_EPS: {
+ } break;
+ case DK3_BMEPS_DRIVER_PDF: {
+ } break;
+ case DK3_BMEPS_DRIVER_BB: {
+ opt->mode = DK3_BMEPS_MODE_OBJECT;
+ } break;
+ }
+ switch(opt->mode) {
+ case DK3_BMEPS_MODE_IMAGE: {
+ opt->szmode = DK3_BMEPS_SIZE_CHUNK; $? ". szmode = chunk"
+ } break;
+ case DK3_BMEPS_MODE_OBJECT: {
+ opt->szmode = DK3_BMEPS_SIZE_1_1; $? ". szmode = 1:1"
+ } break;
+ case DK3_BMEPS_MODE_DOCUMENT: { $? ". szmode = paper"
+ opt->szmode = DK3_BMEPS_SIZE_PAPER;
+ if(opt->dr == DK3_BMEPS_DRIVER_PS) {
+ opt->dsc = 1;
+ }
+ } break;
+ }
+ (opt->ima).ps.w = 595.0;
+ (opt->ima).ps.h = 842.0;
+ if(opt->mode == DK3_BMEPS_MODE_DOCUMENT) {
+ /*
+ The option -l ps.document is typically used for fax TIFF files
+ which already have a border. So we do not need an additional border.
+ */
+ (opt->ima).ps.i = 0.0;
+ (opt->ima).ps.o = 0.0;
+ (opt->ima).ps.t = 0.0;
+ (opt->ima).ps.b = 0.0;
+ opt->szmode = DK3_BMEPS_SIZE_PAPER; $? ". szmode = paper"
+ } else {
+ (opt->ima).ps.i = 56.0;
+ (opt->ima).ps.o = 28.0;
+ (opt->ima).ps.t = 14.0;
+ (opt->ima).ps.b = 14.0;
+ }
+ dk3bmeo_apply_preferences(opt);
+}
+
+
+
+
+void
+dk3bmeo_set_driver_and_mode(dk3_bm_eps_options_t *opt, int driver, int mode)
+{
+ $? "+ dk3bmeo_set_driver_and_mode"
+ if(opt) {
+ opt->dr = driver;
+ opt->mode = mode;
+ dk3bmeo_initialize_for_driver_and_mode(opt);
+ } $? "- dk3bmeo_set_driver_and_mode"
+}
+
+
+
+int
+dk3bmeo_set_paper_size(dk3_bm_eps_options_t *opt, dkChar const *psn)
+{
+ int back;
+ back = dk3bmeo_set_paper_size_complain(opt, psn, 1);
+ return back;
+}
+
+
+
+int
+dk3bmeo_get_driver(dk3_bm_eps_options_t *opt)
+{
+ int back = DK3_BMEPS_DRIVER_PS;
+ $? "+ dk3bmeo_get_driver"
+ if(opt) {
+ back = opt->dr;
+ } $? "- dk3bmeo_get_driver %d", back
+ return back;
+}
+
+
+
+void
+dk3bmeo_set_draft(dk3_bm_eps_options_t *opt, int drflag)
+{
+ $? "+ dk3bmeo_set_draft"
+ if(opt) {
+ opt->draft = drflag;
+ } $? "- dk3bmeo_set_draft"
+}
+
+
+
+int
+dk3bmeo_get_draft(dk3_bm_eps_options_t *opt)
+{
+ int back = 0;
+ $? "+ dk3bmeo_get_draft"
+ if(opt) {
+ back = ((opt->draft) ? 1 : 0);
+ } $? "- dk3bmeo_get_draft %d", back
+ return back;
+}
+
+
+
+void
+dk3bmeo_set_duplex(dk3_bm_eps_options_t *opt, int duplex)
+{
+ $? "+ dk3bmeo_set_duplex"
+ if(opt) {
+ opt->duplex = duplex;
+ } $? "- dk3bmeo_set_duplex"
+}
+
+
+
+int
+dk3bmeo_get_duplex(dk3_bm_eps_options_t *opt)
+{
+ int back = 0;
+ $? "+ dk3bmeo_get_duplex"
+ if(opt) {
+ back = ((opt->duplex) ? 1 : 0);
+ } $? "- dk3bmeo_get_duplex %d", back
+ return back;
+}
+
+
+
+void
+dk3bmeo_set_predictor(dk3_bm_eps_options_t *opt, int pred)
+{
+ $? "+ dk3bmeo_set_predictor"
+ if(opt) {
+ opt->pred = pred;
+ } $? "- dk3bmeo_set_predictor"
+}
+
+
+
+int
+dk3bmeo_get_predictor(dk3_bm_eps_options_t *opt)
+{
+ int back = 0;
+ $? "+ dk3bmeo_get_predictor"
+ if(opt) {
+ back = opt->pred;
+ } $? "- dk3bmeo_get_predictor %d", back
+ return back;
+}
+
+
+
+void
+dk3bmeo_set_origin(dk3_bm_eps_options_t *opt, int io)
+{
+ $? "+ dk3bmeo_set_origin"
+ if(opt) {
+ opt->io = io;
+ } $? "- dk3bmeo_set_origin"
+}
+
+
+
+int
+dk3bmeo_get_origin(dk3_bm_eps_options_t *opt)
+{
+ int back = 0;
+ $? "+ dk3bmeo_get_origin"
+ if(opt) {
+ back = opt->io;
+ } $? "- dk3bmeo_get_origin %d", back
+ return back;
+}
+
+
+
+void
+dk3bmeo_set_ps_level(dk3_bm_eps_options_t *opt, int psl)
+{
+ $? "+ dk3bmeo_set_ps_level"
+ if(opt) {
+ opt->psl = psl;
+ if(psl < 2) opt->psl = 2;
+ if(psl > 3) opt->psl = 3;
+ } $? "- dk3bmeo_set_ps_level"
+}
+
+
+
+int
+dk3bmeo_get_ps_level(dk3_bm_eps_options_t *opt)
+{
+ int back = 3;
+ $? "+ dk3bmeo_get_ps_level"
+ if(opt) {
+ back = opt->psl;
+ } $? "- dk3bmeo_get_ps_level %d", back
+ return back;
+}
+
+
+
+void
+dk3bmeo_set_dct(dk3_bm_eps_options_t *opt, int dct)
+{
+ $? "+ dk3bmeo_set_dct"
+ if(opt) {
+ opt->dct = dct;
+ } $? "- dk3bmeo_set_dct"
+}
+
+
+
+int
+dk3bmeo_get_dct(dk3_bm_eps_options_t *opt)
+{
+ int back = 1;
+ $? "+ dk3bmeo_get_dct"
+ if(opt) {
+ back = ((opt->dct) ? 1 : 0);
+ } $? "- dk3bmeo_get_dct %d", back
+ return back;
+}
+
+
+void
+dk3bmeo_set_keep_aspect_ratio(dk3_bm_eps_options_t *opt, int kar)
+{
+ $? "+ dk3bmeo_set_keep_aspect_ratio"
+ if(opt) {
+ opt->kar = kar;
+ } $? "- dk3bmeo_set_keep_aspect_ratio"
+}
+
+
+
+int
+dk3bmeo_get_keep_aspect_ratio(dk3_bm_eps_options_t *opt)
+{
+ int back = 1;
+ $? "+ dk3bmeo_get_keep_aspect_ratio"
+ if(opt) {
+ back = ((opt->kar) ? 1 : 0);
+ } $? "- dk3bmeo_get_keep_aspect_ratio %d", back
+ return back;
+}
+
+
+
+void
+dk3bmeo_set_background(dk3_bm_eps_options_t *opt, int r, int g, int b, int f)
+{
+ $? "+ dk3bmeo_set_background"
+ if(opt) {
+ opt->bgr = r; opt->bgg = g; opt->bgb = b; opt->fbg = f;
+ } $? "- dk3bmeo_set_background"
+}
+
+
+
+int
+dk3bmeo_get_background_red(dk3_bm_eps_options_t *opt)
+{
+ int back = 0;
+ $? "+ dk3bmeo_get_background_red"
+ if(opt) {
+ back = opt->bgr;
+ } $? "- dk3bmeo_get_background_red %d", back
+ return back;
+}
+
+
+
+
+int
+dk3bmeo_get_background_green(dk3_bm_eps_options_t *opt)
+{
+ int back = 0;
+ $? "+ dk3bmeo_get_background_green"
+ if(opt) {
+ back = opt->bgg;
+ } $? "- dk3bmeo_get_background_green %d", back
+ return back;
+}
+
+
+
+int
+dk3bmeo_get_background_blue(dk3_bm_eps_options_t *opt)
+{
+ int back = 0;
+ $? "+ dk3bmeo_get_background_blue"
+ if(opt) {
+ back = opt->bgb;
+ } $? "- dk3bmeo_get_background_blue %d", back
+ return back;
+}
+
+
+
+int
+dk3bmeo_get_background_force(dk3_bm_eps_options_t *opt)
+{
+ int back = 0;
+ $? "+ dk3bmeo_get_background_force"
+ if(opt) {
+ back = ((opt->fbg) ? 1 : 0);
+ } $? "- dk3bmeo_get_background_force %d", back
+ return back;
+}
+
+
+
+void
+dk3bmeo_set_interpolation(dk3_bm_eps_options_t *opt, int iip)
+{
+ $? "+ dk3bmeo_set_interpolation"
+ if(opt) {
+ opt->ip = iip;
+ } $? "- dk3bmeo_set_interpolation"
+}
+
+
+
+int
+dk3bmeo_get_interpolation(dk3_bm_eps_options_t *opt)
+{
+ int back = 1;
+ $? "+ dk3bmeo_get_interpolation"
+ if(opt) {
+ back = ((opt->ip) ? 1 : 0);
+ } $? "- dk3bmeo_get_interpolation %d", back
+ return back;
+}
+
+
+
+void
+dk3bmeo_set_jpeg_interpolation(dk3_bm_eps_options_t *opt, int iip)
+{
+ $? "+ dk3bmeo_set_jpeg_interpolation"
+ if(opt) {
+ opt->jip = iip;
+ } $? "- dk3bmeo_set_jpeg_interpolation"
+}
+
+
+
+int
+dk3bmeo_get_jpeg_interpolation(dk3_bm_eps_options_t *opt)
+{
+ int back = 0;
+ $? "+ dk3bmeo_get_jpeg_interpolation"
+ if(opt) {
+ back = ((opt->jip) ? 1 : 0);
+ } $? "- dk3bmeo_get_jpeg_interpolation %d", back
+ return back;
+}
+
+
+
+void
+dk3bmeo_set_szmode(dk3_bm_eps_options_t *opt, int newmode)
+{
+ $? "+ dk3bmeo_set_szmode %d", newmode
+ if(opt) {
+ if((newmode >= 0) && (newmode <= 2)) {
+ opt->szmode = newmode; $? ". szmode = %d", newmode
+ }
+ } $? "- dk3bmeo_set_szmode"
+}
+
+
+
+void
+dk3bmeo_set_resolution(dk3_bm_eps_options_t *opt, double dpi)
+{
+ $? "+ dk3bmeo_set_resolution"
+ if(opt) {
+ opt->resolution = dpi;
+ } $? "- dk3bmeo_set_resolution"
+}
+
+
+
+double
+dk3bmeo_get_resolution(dk3_bm_eps_options_t *opt)
+{
+ double back = 72.0;
+ $? "+ dk3bmeo_get_resolution"
+ if(opt) {
+ back = opt->resolution;
+ if(back < 0.0) { back = 0.0; }
+ } $? "- dk3bmeo_get_resolution %lg", back
+ return back;
+}
+
+
+
+int
+dk3bmeo_get_szmode(dk3_bm_eps_options_t *opt)
+{
+ int back = 0;
+ $? "+ dk3bmeo_get_szmode"
+ if(opt) {
+ back = opt->szmode;
+ } $? "- dk3bmeo_get_szmode %d", back
+ return back;
+}
+
+
+
+/** Set PS level.
+ @param opt Option set to modify.
+ @param val Value for option.
+ @param msg Localized message texts.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bmeo_option_pslevel(
+ dk3_bm_eps_options_t *opt,
+ dkChar const *val,
+ dkChar const * const *msg
+)
+{
+ int back = 0;
+ int i; /* Number obtained from val. */
+ $? "+ dk3bmeo_option_pslevel"
+ if(val) {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(val, dkT("%d"), &i))
+#else
+ if (0 != dk3ma_i_from_string(&i, val, NULL))
+#endif
+ {
+ if(i >= 2) {
+ if(i <= 3) {
+ opt->psl = i; back = 1;
+ } else {
+ /* ERROR: Must be 2 or 3! */
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR,msg,26,DK3_BMJ_LOG_BOTH,NULL);
+ }
+ } else {
+ /* ERROR: Must be 2 or 3! */
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR,msg,26,DK3_BMJ_LOG_BOTH,NULL);
+ }
+ } else {
+ /* ERROR: Not a number! */
+ dk3bmj_log_3(opt->app, DK3_LL_ERROR,msg,24,25,val,DK3_BMJ_LOG_BOTH,NULL);
+ }
+ } else {
+ /* ERROR: Missing argument! */
+ } $? "- dk3bmeo_option_pslevel %d", back
+ return back;
+}
+
+
+
+
+/** Set a boolean value.
+ @param opt Option set, used for diagnostics.
+ @param dest Boolean variable.
+ @param val Text containing the value.
+ @param msg Localized message texts.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bmeo_set_boolean(
+ dk3_bm_eps_options_t *opt,
+ int *dest,
+ dkChar const *val,
+ dkChar const * const *msg
+)
+{
+ int back = 0;
+ $? "+ dk3bmeo_set_boolean"
+ if(val) {
+ if(dk3str_is_bool(val)) {
+ back = 1;
+ if(dk3str_is_on(val)) {
+ *dest = 1;
+ } else {
+ *dest = 0;
+ }
+ } else {
+ /* ERROR: Not a boolean! */
+ dk3bmj_log_3(opt->app, DK3_LL_ERROR,msg,27,28,val,DK3_BMJ_LOG_BOTH,NULL);
+ }
+ } else {
+ *dest = 1; back = 1;
+ } $? "- dk3bmeo_set_boolean %d", back
+ return back;
+}
+
+
+
+/** Set flate predictor name.
+ @param opt Option set to modify.
+ @param val Value for option.
+ @param msg Localized message texts.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bmeo_option_predictor(
+ dk3_bm_eps_options_t *opt,
+ dkChar const *val,
+ dkChar const * const *msg
+)
+{
+ int back = 0;
+ $? "+ dk3bmeo_option_predictor"
+ if(val) {
+ back = dk3str_array_index(dk3bmeo_predictor_names, val, 0);
+ if(back > -1) {
+ opt->pred = back + 1;
+ back = 1;
+ } else {
+ back = 0;
+ dk3bmj_log_3(opt->app, DK3_LL_ERROR,msg,29,30,val,DK3_BMJ_LOG_BOTH,NULL);
+ }
+ } else {
+ opt->pred = DK3_COMPRESSION_PREDICTOR_TIFF; back = 1;
+ } $? "- dk3bmeo_option_predictor %d", back
+ return back;
+}
+
+
+
+/** Set background.
+ @param opt Option set to modify.
+ @param val Value for option.
+ @param msg Localized message texts.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bmeo_option_background(
+ dk3_bm_eps_options_t *opt,
+ dkChar const *val,
+ dkChar const * const *msg
+)
+{
+ int back = 0;
+ int i; /* Temporary conversion result. */
+ dkChar *pc; /* Current word pointer. */
+ dkChar *pn; /* Next word pointer. */
+ $? "+ dk3bmeo_option_background"
+ if(val) {
+ pc = dk3str_start(val, NULL);
+ if(pc) {
+ pn = dk3str_chr(pc, dkT(':'));
+ if(pn) {
+ *(pn++) = dkT('\0');
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(pc, dkT("%d"), &i))
+#else
+ if (0 != dk3ma_i_from_string(&i, pc, NULL))
+#endif
+ {
+ opt->bgr = DK3_TO_RANGE(i,0,255);
+ pc = pn;
+ pn = dk3str_chr(pc, dkT(':'));
+ if(pn) {
+ *(pn++) = dkT('\0');
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(pc, dkT("%d"), &i))
+#else
+ if (0 != dk3ma_i_from_string(&i, pc, NULL))
+#endif
+ {
+ opt->bgg = DK3_TO_RANGE(i,0,255);
+ pc = pn;
+ pn = dk3str_chr(pc, dkT(':'));
+ if(pn) { *(pn++) = dkT('\0'); pn = dk3str_start(pn, NULL); }
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(pc, dkT("%d"), &i))
+#else
+ if (0 != dk3ma_i_from_string(&i, pc, NULL))
+#endif
+ {
+ opt->bgb = DK3_TO_RANGE(i,0,255);
+ back = 1;
+ if(pn) {
+ back = 0;
+ if(dk3str_is_bool(pn)) {
+ back = 1;
+ opt->fbg = (dk3str_is_on(pn) ? 1 : 0);
+ } else {
+ /* ERROR: Not a boolean! */
+ dk3bmj_log_3(
+ opt->app, DK3_LL_ERROR,msg,27,28,pn,DK3_BMJ_LOG_BOTH,NULL
+ );
+ }
+ }
+ } else {
+ /* ERROR: Not a number! */
+ dk3bmj_log_3(
+ opt->app, DK3_LL_ERROR,msg,24,25,pc,DK3_BMJ_LOG_BOTH,NULL
+ );
+ }
+ } else {
+ /* ERROR: Not a number! */
+ dk3bmj_log_3(
+ opt->app, DK3_LL_ERROR,msg,24,25,pc,DK3_BMJ_LOG_BOTH,NULL
+ );
+ }
+ } else {
+ /* ERROR: Syntax! */
+ dk3bmj_log_3(
+ opt->app, DK3_LL_ERROR,msg,32,33,pc,DK3_BMJ_LOG_BOTH,NULL
+ );
+ }
+ } else {
+ /* ERROR: Not a number! */
+ dk3bmj_log_3(
+ opt->app, DK3_LL_ERROR,msg,24,25,pc,DK3_BMJ_LOG_BOTH,NULL
+ );
+ }
+ } else {
+ /* ERROR: Syntax! */
+ dk3bmj_log_3(opt->app, DK3_LL_ERROR,msg,32,33,pc,DK3_BMJ_LOG_BOTH,NULL);
+ }
+ } else {
+ /* ERROR: Empty string */
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR,msg,31,DK3_BMJ_LOG_BOTH,NULL);
+ }
+ } else {
+ opt->bgr = 255; opt->bgg = 255; opt->bgb = 255; opt->fbg = 1;
+ } $? "- dk3bmeo_option_background %d", back
+ return back;
+}
+
+
+
+/** Set resolution, numeric or by name.
+ @param opt Option set to modify.
+ @param val Value for option.
+ @param msg Localized message texts.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bmeo_option_resolution(
+ dk3_bm_eps_options_t *opt,
+ dkChar const *val,
+ dkChar const * const *msg
+)
+{
+ int back = 0;
+ double d; /* Temporary conversion result. */
+ $? "+ dk3bmeo_option_resolution"
+ if(val) {
+ if(dk3str_casecmp(dk3bmeo_kw[1], val) == 0) {
+ opt->szmode = DK3_BMEPS_SIZE_1_1; $? ". szmode = 1:1"
+ back = 1;
+ } else {
+ if(dk3str_casecmp(dk3bmeo_kw[2], val) == 0) {
+ opt->szmode = DK3_BMEPS_SIZE_CHUNK; $? ". szmode = chunk"
+ back = 1;
+ } else {
+ if(dk3str_casecmp(dk3bmeo_kw[3], val) == 0) {
+ opt->szmode = DK3_BMEPS_SIZE_1_1; $? ". szmode = 1:1"
+ back = 1;
+ } else {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(val, dkT("%lf"), &d))
+#else
+ if (0 != dk3ma_d_from_string(&d, val, NULL))
+#endif
+ {
+ opt->szmode = DK3_BMEPS_SIZE_SPECIFIED; $? ". szmode = spec"
+ opt->resolution = d;
+ back = 1;
+ } else {
+ /* ERROR: Illegal resolution value */
+ dk3bmj_log_3(
+ opt->app, DK3_LL_ERROR,msg,35,36,val,DK3_BMJ_LOG_BOTH,NULL
+ );
+ }
+ }
+ }
+ }
+ } else {
+ /* ERROR: Missing value! */
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR,msg,34,DK3_BMJ_LOG_BOTH,NULL);
+ }
+ $? "- dk3bmeo_option_resolution %d", back
+ return back;
+}
+
+
+
+/** Set paper size.
+ @param opt Option set to modify.
+ @param val Value for option.
+ @param msg Localized message texts.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3bmeo_option_paper(
+ dk3_bm_eps_options_t *opt,
+ dkChar const *val,
+ dkChar const * const *msg
+)
+{
+ int back = 0;
+ $? "+ dk3bmeo_option_paper"
+ if(val) {
+ back = dk3bmeo_set_paper_size_complain(opt, val, 1);
+ opt->szmode = DK3_BMEPS_SIZE_PAPER; $? ". szmode = paper"
+ } else {
+ /* ERROR: Missing value! */
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR,msg,37,DK3_BMJ_LOG_BOTH,NULL);
+ } $? "- dk3bmeo_option_paper %d", back
+ return back;
+}
+
+
+
+int
+dk3bmeo_apply_option(
+ dk3_bm_eps_options_t *opt,
+ dkChar const *str,
+ dkChar const * const *msg
+)
+{
+ dkChar bu[1024]; /* Private copy of str. */
+ dkChar *p1; /* String start, option value. */
+ int ind; /* Option name index. */
+ int back = 0;
+ $? "+ dk3bmeo_apply_option \"%!ds\"", str
+ if((opt) && (str)) {
+ p1 = dk3str_start(str, NULL);
+ if(p1) {
+ if(dk3str_len(p1) < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy_not_overlapped(bu, p1);
+ p1 = dk3str_chr(bu, dkT('='));
+ if(p1) {
+ *(p1++) = dkT('\0');
+ p1 = dk3str_start(p1, NULL);
+ }
+ ind = dk3str_array_index(dk3bmeo_option_names, bu, 0);
+ switch(ind) {
+ case 0: { /* PS level */
+ back = dk3bmeo_option_pslevel(opt, p1, msg);
+ } break;
+ case 1: { /* Color flag */
+ back = dk3bmeo_set_boolean(opt, &(opt->color), p1, msg);
+ } break;
+ case 2: { /* DSC flag */
+ back = dk3bmeo_set_boolean(opt, &(opt->dsc), p1, msg);
+ } break;
+ case 3: { /* Draft flag */
+ back = dk3bmeo_set_boolean(opt, &(opt->draft), p1, msg);
+ } break;
+ case 4: { /* Flate predictor name */
+ back = dk3bmeo_option_predictor(opt, p1, msg);
+ } break;
+ case 5: { /* Duplex flag */
+ back = dk3bmeo_set_boolean(opt, &(opt->duplex), p1, msg);
+ } break;
+ case 6: { /* Tumble for duplex flag */
+ back = dk3bmeo_set_boolean(opt, &(opt->tumble), p1, msg);
+ } break;
+ case 7: { /* DCT flag */
+ back = dk3bmeo_set_boolean(opt, &(opt->dct), p1, msg);
+ } break;
+ case 8: { /* Background color and optional force flag */
+ back = dk3bmeo_option_background(opt, p1, msg);
+ } break;
+ case 9: { /* Interpolation flag */
+ back = dk3bmeo_set_boolean(opt, &(opt->ip), p1, msg);
+ } break;
+ case 10: { /* JPEG interpolation flag */
+ back = dk3bmeo_set_boolean(opt, &(opt->jip), p1, msg);
+ } break;
+ case 11: { /* Resolution, dpi number or name */
+ back = dk3bmeo_option_resolution(opt, p1, msg);
+ } break;
+ case 12: { /* Paper size, name or numeric */
+ back = dk3bmeo_option_paper(opt, p1, msg);
+ } break;
+ case 13: { /* Make */
+ back = dk3bmeo_set_boolean(opt, &(opt->make), p1, msg);
+ } break;
+ case 14: { /* Keep aspect ratio. */
+ back = dk3bmeo_set_boolean(opt, &(opt->kar), p1, msg);
+ } break;
+ case 15: { /* Reduce bits per component if possible. */
+ $? ". reduce bits per component"
+ back = dk3bmeo_set_boolean(opt, &(opt->rbpc), p1, msg);
+ } break;
+ default: {
+ /* ERROR: Unknown option name! */
+ dk3bmj_log_3(
+ opt->app, DK3_LL_ERROR,msg,22,23,bu,DK3_BMJ_LOG_BOTH,NULL
+ );
+ } break;
+ }
+ } else { $? "! string too long"
+ /* ERROR: Configuration string too long! */
+ dk3bmj_log_3(opt->app, DK3_LL_ERROR,msg,20,21,p1,DK3_BMJ_LOG_BOTH,NULL);
+ }
+ } else { $? "! empty string"
+ /* ERROR: Empty configuration string! */
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR,msg,19,DK3_BMJ_LOG_BOTH,NULL);
+ }
+ } $? "- dk3bmeo_apply_option %d", back
+ return back;
+}
+
+
+
+#if 0
+int
+dk3bmeo_set_language(
+ dk3_bm_eps_options_t *opt, dkChar const *str, dk3_app_t *app
+)
+{
+ dkChar bu[1024]; /* Private copy of str. */
+ dkChar const * const *msg; /* Localized messages. */
+ dkChar *pn; /* Next part to process. */
+ dkChar *pc; /* Current part to process. */
+ dkChar *pt; /* Type. */
+ int back = 0;
+ int lang = -1; /* Language. */
+ int mode = -1; /* Mode. */
+ $? "+ dk3bmeo_set_language \"%!ds\"", TR_STR(str)
+ msg = dk3app_messages(
+ opt->app,
+ dk3bmep_str_get_string_table_name(),
+ (dkChar const **)dk3bmep_str_get_message_texts()
+ );
+ if(!(msg)) {
+ msg = dk3bmep_str_get_message_texts();
+ }
+ if((opt) && (str)) {
+ if(dk3str_len(str) < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy_not_overlapped(bu, str);
+ pn = dk3str_chr(bu, dkT(','));
+ if(pn) { *(pn++) = dkT('\0'); }
+ pc = dk3str_start(bu, NULL);
+ if(pc) {
+ pt = dk3str_chr(pc, dkT('.'));
+ if(pt) { *(pt++) = dkT('\0'); pt = dk3str_start(pt, NULL); }
+ lang = dk3str_array_index(dk3bmeo_driver_names, pc, 0);
+ switch(lang) {
+ case 0: {
+ lang = DK3_BMEPS_DRIVER_PS; back = 1;
+ } break;
+ case 1: {
+ lang = DK3_BMEPS_DRIVER_EPS; back = 1;
+ } break;
+ case 2: {
+ lang = DK3_BMEPS_DRIVER_PDF; back = 1;
+ } break;
+ case 3: {
+ back = DK3_BMEPS_DRIVER_BB; back = 1;
+ } break;
+ default: {
+ /* ERROR: Unknown language! */
+ if(app) {
+ dkChar const * const *msg;
+ msg = dk3app_messages(
+ app,
+ dk3bmep_str_get_string_table_name(),
+ (dkChar const **)dk3bmep_str_get_message_texts()
+ );
+ if(msg) {
+ dk3app_log_3(app, DK3_LL_ERROR, msg, 74, 75, pc);
+ }
+ }
+ } break;
+ }
+ if(back) {
+ mode = DK3_BMEPS_MODE_OBJECT;
+ if(pt) {
+ back = 0;
+ switch(dk3str_array_index(dk3bmeo_mode_names, pt, 0)) {
+ case 0: case 1: {
+ mode = DK3_BMEPS_MODE_IMAGE; back = 1;
+ } break;
+ case 2: case 3: {
+ mode = DK3_BMEPS_MODE_OBJECT; back = 1;
+ } break;
+ case 4: case 5: {
+ mode = DK3_BMEPS_MODE_DOCUMENT; back = 1;
+ } break;
+ }
+ }
+ if(back) {
+ dk3bmeo_set_driver_and_mode(opt, lang, mode);
+ pc = pn;
+ while(pc) {
+ pn = dk3str_chr(pc, dkT(','));
+ if(pn) { *(pn++) = dkT('\0'); pn = dk3str_start(pn, NULL); }
+ if(!dk3bmeo_apply_option(opt, pc, msg)) { back = 0; }
+ pc = pn;
+ }
+ }
+ }
+ } else {
+ /* ##### ERROR: Missing language/mode! */
+ }
+ } else {
+ /* ERROR: String too long! */
+ dk3bmj_log_3(opt->app, DK3_LL_ERROR,msg,12,13,str,DK3_BMJ_LOG_BOTH,job);
+ }
+ } $? "- dk3bmeo_set_language %d", back
+ return back;
+}
+#else
+int
+dk3bmeo_set_language(
+ dk3_bm_eps_options_t *opt,
+ dkChar const *str,
+ dk3_app_t *app
+)
+{
+ dkChar bu[1024]; /* Private copy of str. */
+ dkChar const * const *msg; /* Localized messages. */
+ dkChar *pn; /* Next part to process. */
+ dkChar *pc; /* Current part to process. */
+ dkChar *pt; /* Type. */
+ int back = 0;
+ $? "+ dk3bmeo_set_language"
+ msg = dk3app_messages(
+ opt->app,
+ dk3bmep_str_get_string_table_name(),
+ (dkChar const **)dk3bmep_str_get_message_texts()
+ );
+ if(!(msg)) {
+ msg = dk3bmep_str_get_message_texts();
+ }
+ if((opt) && (str)) { $? ". args ok"
+ dk3bmeo_init(opt);
+ opt->app = app;
+ if(dk3str_len(str) < DK3_SIZEOF(bu,dkChar)) { $? ". length ok"
+ dk3str_cpy_not_overlapped(bu, str);
+ pc = dk3str_start(bu, NULL);
+ if(pc) { $? ". contents found"
+ pn = dk3str_chr(pc, dkT(','));
+ if(pn) { *(pn++) = dkT('\0'); pn = dk3str_start(pn, NULL); }
+ pt = dk3str_chr(pc, dkT('.'));
+ if(pt) { *(pt++) = dkT('\0'); pt = dk3str_start(pt, NULL); }
+ back = 1; $? ". ok so far"
+ opt->mode = DK3_BMEPS_MODE_OBJECT;
+ opt->szmode = DK3_BMEPS_SIZE_1_1; $? ". szmode = 1:1"
+ switch(dk3str_array_index(dk3bmeo_driver_names, pc, 0)) {
+ case 0: {
+ opt->dr = DK3_BMEPS_DRIVER_PS; $? ". driver ps"
+ } break;
+ case 1: {
+ opt->dr = DK3_BMEPS_DRIVER_EPS; $? ". driver eps"
+ } break;
+ case 2: {
+ opt->dr = DK3_BMEPS_DRIVER_PDF; $? ". driver pdf"
+ } break;
+ case 3: {
+ opt->dr = DK3_BMEPS_DRIVER_BB; $? ". driver bb"
+ opt->mode = DK3_BMEPS_MODE_OBJECT;
+ opt->szmode = DK3_BMEPS_SIZE_1_1; $? ". szmode = 1:1"
+ } break;
+ default: { $? "! illegal driver"
+ back = 0;
+ dk3bmj_log_3(
+ opt->app, DK3_LL_ERROR,msg,15,16,pc,DK3_BMJ_LOG_BOTH,NULL
+ );
+ } break;
+ }
+ if(back) { $? ". ok so far"
+ if(pt) { $? ". have mode"
+ switch(dk3str_array_abbr(dk3bmeo_mode_names, pt, dkT('$'), 0)) {
+ case 0: { $? ". mode image"
+ opt->mode = DK3_BMEPS_MODE_IMAGE;
+ opt->szmode = DK3_BMEPS_SIZE_CHUNK; $? ". szmode = chunk"
+ } break;
+ case 1: { $? ". mode object"
+ opt->mode = DK3_BMEPS_MODE_OBJECT;
+ opt->szmode = DK3_BMEPS_SIZE_1_1; $? ". szmode = 1:1"
+ } break;
+ case 2: {
+ opt->mode = DK3_BMEPS_MODE_DOCUMENT; $? ". mode document"
+ opt->szmode = DK3_BMEPS_SIZE_PAPER; $? ". szmode = paper"
+ } break;
+ default: { $? "! illegal mode"
+ back = 0;
+ /* ERROR: Illegal mode! */
+ dk3bmj_log_3(
+ opt->app, DK3_LL_ERROR,msg,17,18,pt,DK3_BMJ_LOG_BOTH,NULL
+ );
+ } break;
+ }
+ if(opt->dr == DK3_BMEPS_DRIVER_BB) { $? ". driver bb"
+ if(opt->mode != DK3_BMEPS_MODE_OBJECT) { $? "! bb req object"
+ back = 0;
+ /* ERROR: BB driver can only produce objects! */
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR,msg,8,DK3_BMJ_LOG_BOTH,NULL);
+ }
+ }
+ } else { $? ". no mode"
+ }
+ dk3bmeo_initialize_for_driver_and_mode(opt);
+ if(back) { $? ". ok so far"
+ pc = pn;
+ while(pc) { $? ". add option"
+ pn = dk3str_chr(pc, dkT(','));
+ if(pn) { *(pn++) = dkT('\0'); pn = dk3str_start(pn, NULL); }
+ if(!dk3bmeo_apply_option(opt, pc, msg)) { back = 0; }
+ pc = pn;
+ }
+ }
+ }
+ } else { $? "! empty string"
+ /* ERROR: Empty string! */
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR,msg,14,DK3_BMJ_LOG_BOTH,NULL);
+ }
+ } else { $? "! string too long"
+ /* ERROR: String too long! */
+ dk3bmj_log_3(opt->app, DK3_LL_ERROR,msg,12,13,str,DK3_BMJ_LOG_BOTH,NULL);
+ }
+ } else { $? "! args"
+ } $? "- dk3bmeo_set_language %d", back
+ return back;
+}
+#endif
+
+
+
+int
+dk3bmeo_check(
+ dk3_bm_eps_options_t *opt,
+ int type,
+ dk3_app_t *app,
+ dk3_bm_conversion_job_t *job
+)
+{
+ dkChar const * const *msg; /* Localized message texts. */
+ int back = 1; /* No error found (yet). */
+ $? "+ dk3bmeo_check"
+ /*
+ Check driver.
+ */
+ msg = dk3app_messages(
+ opt->app,
+ dk3bmep_str_get_string_table_name(),
+ (dkChar const **)dk3bmep_str_get_message_texts()
+ );
+ if(!(msg)) {
+ msg = dk3bmep_str_get_message_texts();
+ }
+ if(type) { $? ". placed object"
+ switch(opt->dr) {
+ case DK3_BMEPS_DRIVER_PS:
+ case DK3_BMEPS_DRIVER_PDF:
+ { $? ". PS/PDF"
+ }
+ break;
+ default: { $? "! illegal driver"
+ back = 0;
+ /* ERROR: Placed objects can use the PS or PDF driver only! */
+ opt->dr = DK3_BMEPS_DRIVER_PS;
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR, msg, 2, DK3_BMJ_LOG_BOTH, job);
+ } break;
+ }
+ } else { $? ". file conversion"
+ switch(opt->dr) {
+ case DK3_BMEPS_DRIVER_PS:
+ case DK3_BMEPS_DRIVER_EPS:
+ case DK3_BMEPS_DRIVER_PDF:
+ case DK3_BMEPS_DRIVER_BB:
+ { $? ". driver ok"
+ }
+ break;
+ default: { $? "! illegal driver"
+ back = 0;
+ /* ERROR: Illegal driver, must be PS, EPS, PDF, BB! */
+ opt->dr = DK3_BMEPS_DRIVER_PDF;
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR, msg, 3, DK3_BMJ_LOG_BOTH, job);
+ } break;
+ }
+ }
+ /*
+ Check mode.
+ */
+ if(type) { $? ". placed object"
+ if(opt->mode != DK3_BMEPS_MODE_PLACED_OBJECT) {
+ back = 0; $? "! illegal mode"
+ /* ERROR: Illegal mode, must be placed object! */
+ opt->mode = DK3_BMEPS_MODE_PLACED_OBJECT;
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR, msg, 4, DK3_BMJ_LOG_BOTH, job);
+ }
+ } else { $? ". file conversion"
+ if(opt->mode == DK3_BMEPS_MODE_PLACED_OBJECT) { $? "! illegal mode"
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR, msg, 5, DK3_BMJ_LOG_BOTH, job);
+ } else {
+ switch(opt->dr) {
+ case DK3_BMEPS_DRIVER_PS: { $? ". driver PS"
+ switch(opt->mode) {
+ case DK3_BMEPS_MODE_IMAGE:
+ case DK3_BMEPS_MODE_OBJECT:
+ case DK3_BMEPS_MODE_DOCUMENT:
+ { $? ". mode ok"
+ }
+ break;
+ default: { $? "! illegal mode"
+ back = 0;
+ /* ERROR: Illegal mode, must be image, object, document! */
+ opt->mode = DK3_BMEPS_MODE_IMAGE;
+ dk3bmj_log_1(opt->app,DK3_LL_ERROR,msg,6,DK3_BMJ_LOG_BOTH,job);
+ } break;
+ }
+ } break;
+ case DK3_BMEPS_DRIVER_EPS: { $? ". driver PS"
+ switch(opt->mode) {
+ case DK3_BMEPS_MODE_IMAGE:
+ case DK3_BMEPS_MODE_OBJECT:
+ { $? " . mode ok"
+ }
+ break;
+ default: { $? "! illegal mode"
+ back = 0;
+ /* ERROR: Illegal mode, must be image or object! */
+ opt->mode = DK3_BMEPS_MODE_OBJECT;
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR,msg,7,DK3_BMJ_LOG_BOTH,job);
+ } break;
+ }
+ } break;
+ case DK3_BMEPS_DRIVER_PDF: { $? ". driver PDF"
+ switch(opt->mode) {
+ case DK3_BMEPS_MODE_IMAGE:
+ case DK3_BMEPS_MODE_OBJECT:
+ case DK3_BMEPS_MODE_DOCUMENT:
+ { $? ". mode ok"
+ }
+ break;
+ default: { $? "! illegal mode"
+ back = 0;
+ /* ERROR: Illegal mode, must be image, object, document! */
+ opt->mode = DK3_BMEPS_MODE_OBJECT;
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR,msg,6,DK3_BMJ_LOG_BOTH,job);
+ } break;
+ }
+ } break;
+ case DK3_BMEPS_DRIVER_BB: { $? ". driver bb"
+ switch(opt->mode) {
+ case DK3_BMEPS_MODE_OBJECT:
+ { $? ". mode ok"
+ }
+ break;
+ default: { $? "! illegal mode"
+ back = 0;
+ /* ERROR: Illegal mode, BB requires object! */
+ opt->mode = DK3_BMEPS_MODE_OBJECT;
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR,msg,8,DK3_BMJ_LOG_BOTH,job);
+ } break;
+ }
+ if(opt->draft) {
+ opt->draft = 0;
+ /* ERROR: Draft mode can not be used for bounding box! */
+ }
+ } break;
+ }
+ }
+ }
+ /*
+ Check size mode.
+ */
+ if(type) { $? ". placed object"
+ } else { $? ". file conversion"
+ switch(opt->mode) {
+ case DK3_BMEPS_MODE_IMAGE: { $? ". mode image"
+ switch(opt->szmode) {
+ case DK3_BMEPS_SIZE_1_1: { $? ". szmode ok 1:1"
+ } break;
+ case DK3_BMEPS_SIZE_CHUNK: { $? ". szmode ok chunk"
+ } break;
+ case DK3_BMEPS_SIZE_SPECIFIED: { $? ". szmode ok specified"
+ } break;
+ case DK3_BMEPS_SIZE_PAPER: { $? ". szmode ok paper"
+ } break;
+ default: { $? "! illegal szmode"
+ back = 0;
+ /* ERROR: Illegal size mode! */
+ opt->szmode = DK3_BMEPS_SIZE_1_1; $? ". szmode = 1:1"
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR,msg,9,DK3_BMJ_LOG_BOTH,job);
+ } break;
+ }
+ } break;
+ case DK3_BMEPS_MODE_OBJECT: { $? ". mode object"
+ switch(opt->szmode) {
+ case DK3_BMEPS_SIZE_1_1: { $? ". szmode: 1:1"
+ } break;
+ default: { $? "! illegal szmode"
+ back = 0;
+ /* ERROR: Illegal size mode, must be 1:1! */
+ opt->szmode = DK3_BMEPS_SIZE_1_1; $? ". szmode = 1:1"
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR,msg,10,DK3_BMJ_LOG_BOTH,job);
+ } break;
+ }
+ } break;
+ case DK3_BMEPS_MODE_DOCUMENT: { $? ". mode document"
+ if(opt->draft) {
+ opt->draft = 0;
+ /* ERROR: Draft can not be used with documents! */
+ dk3bmj_log_1(opt->app, DK3_LL_WARNING,msg,11,DK3_BMJ_LOG_BOTH,job);
+ }
+ switch(opt->szmode) {
+ case DK3_BMEPS_SIZE_1_1: { $? ". szmode ok 1:1"
+ } break;
+ case DK3_BMEPS_SIZE_CHUNK: { $? ". szmode ok chunk"
+ } break;
+ case DK3_BMEPS_SIZE_SPECIFIED: { $? ". szmode ok specified"
+ } break;
+ case DK3_BMEPS_SIZE_PAPER: { $? ". szmode ok paper"
+ } break;
+ default: { $? "! illegal szmode"
+ back = 0;
+ /* ERROR: Illegal size mode! */
+ opt->szmode = DK3_BMEPS_SIZE_1_1; $? ". szmode = 1:1"
+ dk3bmj_log_1(opt->app, DK3_LL_ERROR,msg,9,DK3_BMJ_LOG_BOTH,job);
+ } break;
+ }
+ } break;
+ }
+ } $? "- dk3bmeo_check %d", back
+ return back;
+}
+
diff --git a/support/dktools/dk3bmeo.h b/support/dktools/dk3bmeo.h
new file mode 100644
index 0000000000..d506acc00e
--- /dev/null
+++ b/support/dktools/dk3bmeo.h
@@ -0,0 +1,356 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3bmeo.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3bmeo.h Header file for the dk3bmeo module.
+*/
+
+#ifndef DK3BMEO_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3BMEO_H_INCLUDED 1
+
+
+#line 10 "dk3bmeo.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Initialize bmeps option set.
+ @param opt Option set to initialize.
+*/
+void
+dk3bmeo_init(dk3_bm_eps_options_t *opt);
+
+/** Allocate and initalize new option set.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new option set on success, NULL on error.
+*/
+dk3_bm_eps_options_t *
+dk3bmeo_new_app(dk3_app_t *app);
+
+/** Get run mode.
+ @param opt Option set.
+ @return Run mode DK3_BMEPS_MODE_xxx, see @ref dkbmmodes.
+*/
+int
+dk3bmeo_get_mode(dk3_bm_eps_options_t *opt);
+
+/** Set output driver and mode.
+ @param opt Option set.
+ @param driver Output driver DK3_BMEPS_DRIVER_xxx,
+ see @ref bmepsdrivers.
+ @param mode Output mode DK3_BMEPS_MODE_xxx,
+ see @ref dkbmmodes.
+*/
+void
+dk3bmeo_set_driver_and_mode(dk3_bm_eps_options_t *opt, int driver, int mode);
+
+/** Set paper size by name.
+ @param opt Option set.
+ @param psn Paper size name.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3bmeo_set_paper_size(dk3_bm_eps_options_t *opt, dkChar const *psn);
+
+/** Get output driver.
+ @param opt Option set.
+ @return Output driver DK3_BMEPS_DRIVER_xxx, see @ref bmepsdrivers.
+*/
+int
+dk3bmeo_get_driver(dk3_bm_eps_options_t *opt);
+
+/** Enable/disable draft mode.
+ @param opt Option set.
+ @param drflag 1=draft, 0=normal.
+*/
+void
+dk3bmeo_set_draft(dk3_bm_eps_options_t *opt, int drflag);
+
+/** Get draft mode setting.
+ @param opt Option set.
+ @return 1 for draft mode, 0 for normal mode.
+*/
+int
+dk3bmeo_get_draft(dk3_bm_eps_options_t *opt);
+
+/** Set duplex printing.
+ @param opt Option set.
+ @param duplex Flag: Enable duplex output.
+*/
+void
+dk3bmeo_set_duplex(dk3_bm_eps_options_t *opt, int duplex);
+
+/** Retrieve duplex setting.
+ @param opt Option set.
+ @return 1 for duplex, 0 for simplex output.
+*/
+int
+dk3bmeo_get_duplex(dk3_bm_eps_options_t *opt);
+
+/** Set flate predictor.
+ @param opt Option set.
+ @param pred Predictor DK3_COMPRESSION_PREDICTOR_xxx, see
+ @ref flatepredictors.
+*/
+void
+dk3bmeo_set_predictor(dk3_bm_eps_options_t *opt, int pred);
+
+/** Get compression predictor.
+ @param opt Option set.
+ @return Predictor DK3_COMPRESSION_PREDICTOR_xxx,
+ see @ref flatepredictors.
+*/
+int
+dk3bmeo_get_predictor(dk3_bm_eps_options_t *opt);
+
+/** Set image origin.
+ @param opt Option set.
+ @param io Image origin DK3_IMAGE_ORIGIN_xxx, se @ref imageorigin.
+*/
+void
+dk3bmeo_set_origin(dk3_bm_eps_options_t *opt, int io);
+
+/** Get image origin.
+ @param opt Option set.
+ @return Image origin DK3_IMAGE_ORIGIN_xxx, se @ref imageorigin.
+*/
+int
+dk3bmeo_get_origin(dk3_bm_eps_options_t *opt);
+
+/** Set PS level.
+ @param opt Option set.
+ @param psl PS level (2 or 3).
+*/
+void
+dk3bmeo_set_ps_level(dk3_bm_eps_options_t *opt, int psl);
+
+/** Get PS level.
+ @param opt Option set.
+ @return PS level (2 or 3).
+*/
+int
+dk3bmeo_get_ps_level(dk3_bm_eps_options_t *opt);
+
+/** Enable/disable direct transfer of DCT data.
+ @param opt Option set.
+ @param dct 1=enable, 0=disable.
+*/
+void
+dk3bmeo_set_dct(dk3_bm_eps_options_t *opt, int dct);
+
+/** Get flag for direct DCT data transfer.
+ @param opt Option set.
+ @return 1=enabled, 0=disabled.
+*/
+int
+dk3bmeo_get_dct(dk3_bm_eps_options_t *opt);
+
+/** Set flag to keep aspect ratio.
+ @param opt Option set.
+ @param kar 1=keep aspect ratio, 0=allow different scales for
+ x and y.
+*/
+void
+dk3bmeo_set_keep_aspect_ratio(dk3_bm_eps_options_t *opt, int kar);
+
+/** Get flag for keeping aspect ratio.
+ @param opt Option set.
+ @return 1 for keep aspect ratio, 0 for allow different
+ scaling for x and y.
+*/
+int
+dk3bmeo_get_keep_aspect_ratio(dk3_bm_eps_options_t *opt);
+
+/** Set background.
+ @param opt Option set.
+ @param r Background red component.
+ @param g Background green component.
+ @param b Background blue component.
+ @param f Flag: Force this background over background chunk
+ from image file.
+*/
+void
+dk3bmeo_set_background(dk3_bm_eps_options_t *opt, int r, int g, int b, int f);
+
+/** Get background red component.
+ @param opt Option set.
+ @return Background red component.
+*/
+int
+dk3bmeo_get_background_red(dk3_bm_eps_options_t *opt);
+
+/** Get background green component.
+ @param opt Option set.
+ @return Background green component.
+*/
+int
+dk3bmeo_get_background_green(dk3_bm_eps_options_t *opt);
+
+/** Get background blue component.
+ @param opt Option set.
+ @return Background blue component.
+*/
+int
+dk3bmeo_get_background_blue(dk3_bm_eps_options_t *opt);
+
+/** Get enforce background flag.
+ @param opt Option set.
+ @return 1 for enforce background over background chunk,
+ 0 for use background chunk if available.
+*/
+int
+dk3bmeo_get_background_force(dk3_bm_eps_options_t *opt);
+
+/** Enable/disable image interpolation.
+ @param opt Option set.
+ @param iip Flag: Image interpolation allowed.
+*/
+void
+dk3bmeo_set_interpolation(dk3_bm_eps_options_t *opt, int iip);
+
+/** Get image interpolation flag.
+ @param opt Option set.
+ @return 1 for image interpolation allowed, 0 for denied.
+*/
+int
+dk3bmeo_get_interpolation(dk3_bm_eps_options_t *opt);
+
+/** Enable/disable image interpolation for JPEG files.
+ @param opt Option set.
+ @param iip Flag: Image interpolation for JPEGs allowed or denied.
+*/
+void
+dk3bmeo_set_jpeg_interpolation(dk3_bm_eps_options_t *opt, int iip);
+
+/** Get image interpolation flag for JPEGs.
+ @param opt Option set.
+ @return 1 for image interpolation allowed, 0 for denied.
+*/
+int
+dk3bmeo_get_jpeg_interpolation(dk3_bm_eps_options_t *opt);
+
+/** Destroy option set, release memory.
+ @param opt Option set to destroy.
+*/
+void
+dk3bmeo_delete(dk3_bm_eps_options_t *opt);
+
+/** Apply one text option (argument to -o) to option set.
+ @param opt Option set to modify.
+ @param str Option text.
+ @param msg Message text array containing localized texts.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3bmeo_apply_option(
+ dk3_bm_eps_options_t *opt,
+ dkChar const *str,
+ dkChar const * const *msg
+);
+
+/** Set language (driver and mode, obtained from -l option).
+ @param opt Option set to modify.
+ @param str String containing configuration data.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3bmeo_set_language(
+ dk3_bm_eps_options_t *opt,
+ dkChar const *str,
+ dk3_app_t *app
+);
+
+/** Check options consistency.
+ On inconsistency, correct the options and return 0 so
+ a second check will return 1.
+ @param opt Option set.
+ @param type Invokation type (0=bmeps/wxbmeps, 1=placed object).
+ @param app Application structure for diagnostics, may be NULL.
+ @param job Conversion job structure.
+ @return 1 on success, 0 on error (corrections applied).
+*/
+int
+dk3bmeo_check(
+ dk3_bm_eps_options_t *opt,
+ int type,
+ dk3_app_t *app,
+ dk3_bm_conversion_job_t *job
+);
+
+/** Attempt to find PS level and page size from preferences.
+ @param opt Conversion option set, app must be initialized.
+*/
+void
+dk3bmeo_apply_preferences(dk3_bm_eps_options_t *opt);
+
+/** Set size mode in option set.
+ @param opt Option set.
+ @param newmode new size mode DK3_BMEPS_SIZE_xxx,
+ see @ref bmepssizehandling.
+*/
+void
+dk3bmeo_set_szmode(dk3_bm_eps_options_t *opt, int newmode);
+
+/** Retrieve image size mode.
+ @param opt Option set.
+ @return Size mode.
+*/
+int
+dk3bmeo_get_szmode(dk3_bm_eps_options_t *opt);
+
+/** Set image resolution.
+ @param opt Option set.
+ @param dpi Resolution in dpi (dots per inch).
+*/
+void
+dk3bmeo_set_resolution(dk3_bm_eps_options_t *opt, double dpi);
+
+/** Retrieve image resolution setting.
+ @param opt Option set.
+ @return Resolution in dpi if set, 72.0 is used as default.
+*/
+double
+dk3bmeo_get_resolution(dk3_bm_eps_options_t *opt);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3bmep.c b/support/dktools/dk3bmep.c
new file mode 100644
index 0000000000..4e816ef94f
--- /dev/null
+++ b/support/dktools/dk3bmep.c
@@ -0,0 +1,41 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3bmep.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3bmep.c The dk3bmep module.
+*/
+
+
+#line 25 "dk3bmep.ctr"
+
diff --git a/support/dktools/dk3bmep.ctr b/support/dktools/dk3bmep.ctr
new file mode 100644
index 0000000000..ff195e3967
--- /dev/null
+++ b/support/dktools/dk3bmep.ctr
@@ -0,0 +1,25 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert bitmap image to PS/EPS/PDF
+*/
+int
+dk3bmep_run(
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
diff --git a/support/dktools/dk3bmep.h b/support/dktools/dk3bmep.h
new file mode 100644
index 0000000000..f7ae4eccb9
--- /dev/null
+++ b/support/dktools/dk3bmep.h
@@ -0,0 +1,61 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3bmep.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3bmep.h Header file for the dk3bmep module.
+*/
+
+#ifndef DK3BMEP_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3BMEP_H_INCLUDED 1
+
+
+#line 9 "dk3bmep.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert bitmap image to PS/EPS/PDF
+*/
+int
+dk3bmep_run(
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk3bmeps.c b/support/dktools/dk3bmeps.c
new file mode 100644
index 0000000000..71905ebdbe
--- /dev/null
+++ b/support/dktools/dk3bmeps.c
@@ -0,0 +1,308 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3bmeps.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3bmeps.c The dk3bmeps module.
+*/
+
+
+#line 34 "dk3bmeps.ctr"
+
+#include "dk3all.h"
+#include "dk3bmeps.h"
+
+
+
+
+#line 40 "dk3bmeps.ctr"
+
+
+
+/** Message texts used by bmpp and wxbmpp.
+*/
+dkChar const * const dk3bmep_str_default_texts[] = {
+/* 0 */
+dkT("\n"),
+
+/* 1 */
+dkT(" "),
+
+/* 2 */
+dkT("Inconsistent options!\nOutput mode \"object\" can be used for \"ps\" and \"pdf\" output only!"),
+
+/* 3 */
+dkT("Illegal driver number!"),
+
+/* 4 */
+dkT("Illegal mode, must be a placed object!"),
+
+/* 5 */
+dkT("Illegal mode, must not be a placed object!"),
+
+/* 6 */
+dkT("Inconsistent options!\nMode must be image, object, or document!"),
+
+/* 7 */
+dkT("Inconsistent options!\nMode must be image or object!"),
+
+/* 8 */
+dkT("Inconsistent options!\nDriver bb can produce objects only!"),
+
+/* 9 */
+dkT("Illegal size mode specified!"),
+
+/* 10 */
+dkT("Inconsistent options!\nSize mode must be 1px=1pt for objects!"),
+
+/* 11 */
+dkT("Draft can not be used when producing document!"),
+
+/* 12 */
+dkT("Option string too long:\n\""),
+
+/* 13 */
+dkT("\""),
+
+/* 14 */
+dkT("Empty language and options string!"),
+
+/* 15 */
+dkT("Illegal driver: \""),
+
+/* 16 */
+dkT("\"!"),
+
+/* 17 */
+dkT("Illegal mode: \""),
+
+/* 18 */
+dkT("\"!"),
+
+/* 19 */
+dkT("Empty configuration string!"),
+
+/* 20 */
+dkT("Configuration string too long:\n\""),
+
+/* 21 */
+dkT("\"!"),
+
+/* 22 */
+dkT("Unknown configuration option name: \""),
+
+/* 23 */
+dkT("\"!"),
+
+/* 24 */
+dkT("Not a number: \""),
+
+/* 25 */
+dkT("\"!"),
+
+/* 26 */
+dkT("PS level must be 2 or 3!"),
+
+/* 27 */
+dkT("Not a boolean value: \""),
+
+/* 28 */
+dkT("\"!"),
+
+/* 29 */
+dkT("Unknown predictor: \""),
+
+/* 30 */
+dkT("\"!"),
+
+/* 31 */
+dkT("Empty background specification string!"),
+
+/* 32 */
+dkT("Syntax error in background specification: \""),
+
+/* 33 */
+dkT("\"!"),
+
+/* 34 */
+dkT("Option \"size\" needs an argument!"),
+
+/* 35 */
+dkT("Illegal size argument: \""),
+
+/* 36 */
+dkT("\"!"),
+
+/* 37 */
+dkT("Option \"paper\" needs an argument!"),
+
+/* 38 */
+dkT("Inconsistent options!\nSetting a paper size is only allowed when producing a document!"),
+
+/* 39 */
+dkT("Paper size not found: \""),
+
+/* 40 */
+dkT("\"!"),
+
+/* 41 */
+dkT("Processing file \""),
+
+/* 42 */
+dkT("\"."),
+
+/* 43 */
+dkT("Finished file \""),
+
+/* 44 */
+dkT("\"."),
+
+/* 45 */
+dkT("Conversion not necessary for \""),
+
+/* 46 */
+dkT("\"."),
+
+/* 47 */
+dkT("Reading image data."),
+
+/* 48 */
+dkT("Analyzing image."),
+
+/* 49 */
+dkT("yes"),
+
+/* 50 */
+dkT("no"),
+
+/* 51 */
+dkT("Color usage indicated: "),
+
+/* 52 */
+dkT("Color usage found: "),
+
+/* 53 */
+dkT("Alpha usage indicated: "),
+
+/* 54 */
+dkT("Alpha usage found: "),
+
+/* 55 */
+dkT("Bits per component indicated: "),
+
+/* 56 */
+dkT("Bits per component found: "),
+
+/* 57 */
+dkT("Bits per component used: "),
+
+/* 58 */
+dkT("Error while writing data!"),
+
+/* 59 */
+dkT("Failed to set up output compression!"),
+
+/* 60 */
+dkT("Invalid paper setup!"),
+
+/* 61 */
+dkT("Failed to read image data!"),
+
+/* 62 */
+dkT("Incorrect page setup, borders larger than page!"),
+
+/* 63 */
+dkT("File type \""),
+
+/* 64 */
+dkT("\" unknown!"),
+
+/* 65 */
+dkT("Illegal file type: \""),
+
+/* 66 */
+dkT("\"!"),
+
+/* 67 */
+dkT("No file type specified for standard input!"),
+
+/* 68 */
+dkT("Inconsistent options found in option check!"),
+
+/* 69 */
+dkT("Failed to read image file:\n\""),
+
+/* 70 */
+dkT("\"!"),
+
+/* 71 */
+dkT("PDF writer failed to open a new page!"),
+
+/* 72 */
+dkT("Failed to write PDF output to file!"),
+
+/* 73 */
+dkT("Failed to add image to PDF page!"),
+
+/* 74 */
+dkT("Illegal output language \""),
+
+/* 75 */
+dkT("\"!"),
+
+/* 76 */
+dkT("Writing output."),
+
+NULL
+
+
+#line 302 "dk3bmeps.ctr"
+};
+
+/** Size of the dk3bmep_str_default_texts array.
+*/
+dkChar const dk3bmep_str_string_table_name[] = { dkT("dk3bmeps.str") };
+
+dkChar const * const *
+dk3bmep_str_get_message_texts(void)
+{
+ return dk3bmep_str_default_texts;
+}
+
+
+dkChar const *
+dk3bmep_str_get_string_table_name(void)
+{
+ return dk3bmep_str_string_table_name;
+}
+
diff --git a/support/dktools/dk3bmeps.ctr b/support/dktools/dk3bmeps.ctr
new file mode 100644
index 0000000000..f2dc9759e9
--- /dev/null
+++ b/support/dktools/dk3bmeps.ctr
@@ -0,0 +1,320 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Get default message texts.
+ @return Pointer to message texts array.
+*/
+dkChar const * const *
+dk3bmep_str_get_message_texts(void);
+
+/** Get short file name of string table file.
+ @return File name.
+*/
+dkChar const *
+dk3bmep_str_get_string_table_name(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk3all.h"
+#include "dk3bmeps.h"
+
+
+$!trace-include
+
+
+
+/** Message texts used by bmpp and wxbmpp.
+*/
+dkChar const * const dk3bmep_str_default_texts[] = {
+$!string-table macro=dkT
+#
+# 0: Simple newline.
+#
+\n
+#
+# 1: Space.
+#
+
+#
+# 2: Error: Output mode object requires ps or pdf output!
+#
+Inconsistent options!\nOutput mode "object" can be used for "ps" and "pdf" output only!
+#
+# 3: Error: Illegal driver number!
+#
+Illegal driver number!
+#
+# 4: Error: Illegal mode, must be a placed object!
+#
+Illegal mode, must be a placed object!
+#
+# 5: Error: Illegal mode, must not be a placed object!
+#
+Illegal mode, must not be a placed object!
+#
+# 6: Error: Illegal mode, must be image, object or document!
+#
+Inconsistent options!\nMode must be image, object, or document!
+#
+# 7: Error: Illegal mode, must be image or object!
+#
+Inconsistent options!\nMode must be image or object!
+#
+# 8: Error: Driver bb can produce objects only!
+#
+Inconsistent options!\nDriver bb can produce objects only!
+#
+# 9: Error: Illegal size mode specified!
+#
+Illegal size mode specified!
+#
+# 10: Error: Size mode must be 1px=1pt for objects!
+#
+Inconsistent options!\nSize mode must be 1px=1pt for objects!
+#
+# 11: Warning: Draft can not be used when producing document!
+#
+Draft can not be used when producing document!
+#
+# 12/13: Error: Option string "..." too long!
+#
+Option string too long:\n"
+"
+#
+# 14: Error: Empty language and options string!
+#
+Empty language and options string!
+#
+# 15/16: Error: Illegal driver!
+#
+Illegal driver: "
+"!
+#
+# 17/18: Error: Illegal mode!
+#
+Illegal mode: "
+"!
+#
+# 19: Error: Empty configuration string!
+#
+Empty configuration string!
+#
+# 20/21: Error: Configuration string "..." too long!
+#
+Configuration string too long:\n"
+"!
+#
+# 22/23: Error: Unknown configuration option name!
+#
+Unknown configuration option name: "
+"!
+#
+# 24/25: Error: Not a number!
+#
+Not a number: "
+"!
+#
+# 26: Error: PS level must be 2 or 3!
+#
+PS level must be 2 or 3!
+#
+# 27/28: Error: Not a boolean value!
+#
+Not a boolean value: "
+"!
+#
+# 29/30: Error: Unknown predictor!
+#
+Unknown predictor: "
+"!
+#
+# 31: Error: Empty background specification string!
+#
+Empty background specification string!
+#
+# 32/33: Error: Syntax error in background specification!
+#
+Syntax error in background specification: "
+"!
+#
+# 34: Error: Option needs an argument!
+#
+Option "size" needs an argument!
+#
+# 35/36: Error: Illegal size argument!
+#
+Illegal size argument: "
+"!
+#
+# 37: Error: Option needs an argument!
+#
+Option "paper" needs an argument!
+#
+# 38: Error: Setting a paper size is only allowed for document!
+#
+Inconsistent options!\nSetting a paper size is only allowed when producing a document!
+#
+# 39/40: Error: Paper size not found!
+#
+Paper size not found: "
+"!
+#
+# 41/42: Progress: Processing file "...".
+#
+Processing file "
+".
+#
+# 43/44: Progress: Finished file "...".
+#
+Finished file "
+".
+#
+# 45/46: Progress: Destination file is up to date.
+#
+Conversion not necessary for "
+".
+#
+# 47: Progress: Reading image data.
+#
+Reading image data.
+#
+# 48: Progress: Analyzing image.
+#
+Analyzing image.
+#
+# 49: Answer yes
+#
+yes
+#
+# 50: Answer no
+#
+no
+#
+# 51: Color usage indicated:
+#
+Color usage indicated:
+#
+# 52: Color usage found:
+#
+Color usage found:
+#
+# 53: Alpha usage indicated:
+#
+Alpha usage indicated:
+#
+# 54: Alpha usage found:
+#
+Alpha usage found:
+#
+# 55: Bits per component indicated:
+#
+Bits per component indicated:
+#
+# 56: Bits per component found:
+#
+Bits per component found:
+#
+# 57: Bits per component used:
+#
+Bits per component used:
+#
+# 58: ERROR: Error while writing data!
+#
+Error while writing data!
+#
+# 59: ERROR: Failed to start encoded chunk!
+#
+Failed to set up output compression!
+#
+# 60: ERROR: Invalid paper setup!
+#
+Invalid paper setup!
+#
+# 61: ERROR: Failed to read image data!
+#
+Failed to read image data!
+#
+# 62: ERROR: Incorrect page setup, borders larger than page!
+#
+Incorrect page setup, borders larger than page!
+#
+# 63/64: ERROR: File type "..." unknown!
+#
+File type "
+" unknown!
+#
+# 65/66: ERROR: Illegal file type: "..."!
+#
+Illegal file type: "
+"!
+#
+# 67: ERROR: No file type specified for standard input!
+#
+No file type specified for standard input!
+#
+# 68: ERROR: Inconsistent options found in option check!
+#
+Inconsistent options found in option check!
+#
+# 69/70: ERROR: Failed to read image file: ....!
+#
+Failed to read image file:\n"
+"!
+#
+# 71: ERROR: PDF Writer failed to open a new page!
+#
+PDF writer failed to open a new page!
+#
+# 72: ERROR: Failed to write PDF output to file!
+#
+Failed to write PDF output to file!
+#
+# 73: ERROR: Failed to add image to PDF page!
+#
+Failed to add image to PDF page!
+#
+# 74/75 ERROR: Unknown output language "..."!
+#
+Illegal output language "
+"!
+#
+# 76: PROGRESS: Writing output.
+#
+Writing output.
+$!end
+};
+
+/** Size of the dk3bmep_str_default_texts array.
+*/
+dkChar const dk3bmep_str_string_table_name[] = { dkT("dk3bmeps.str") };
+
+dkChar const * const *
+dk3bmep_str_get_message_texts(void)
+{
+ return dk3bmep_str_default_texts;
+}
+
+
+dkChar const *
+dk3bmep_str_get_string_table_name(void)
+{
+ return dk3bmep_str_string_table_name;
+}
+
diff --git a/support/dktools/dk3bmeps.h b/support/dktools/dk3bmeps.h
new file mode 100644
index 0000000000..522e7da682
--- /dev/null
+++ b/support/dktools/dk3bmeps.h
@@ -0,0 +1,69 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3bmeps.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3bmeps.h Header file for the dk3bmeps module.
+*/
+
+#ifndef DK3BMEPS_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3BMEPS_H_INCLUDED 1
+
+
+#line 10 "dk3bmeps.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Get default message texts.
+ @return Pointer to message texts array.
+*/
+dkChar const * const *
+dk3bmep_str_get_message_texts(void);
+
+/** Get short file name of string table file.
+ @return File name.
+*/
+dkChar const *
+dk3bmep_str_get_string_table_name(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3bmj.c b/support/dktools/dk3bmj.c
new file mode 100644
index 0000000000..ee0ef2ccf3
--- /dev/null
+++ b/support/dktools/dk3bmj.c
@@ -0,0 +1,584 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3bmj.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3bmj.c The dk3bmj module.
+*/
+
+
+#line 303 "dk3bmj.ctr"
+
+#if DK3_USE_WX
+#include "wxbmeps.h"
+#else
+#include "dk3all.h"
+#include "dk3bmj.h"
+#include "dk3bmeps.h"
+#endif
+
+
+
+
+
+#line 315 "dk3bmj.ctr"
+
+
+
+/** Log level required for writing to the log text field in wxbmeps.
+*/
+static int const dk3bmj_required_log_level = DK3_LL_PROGRESS;
+
+
+
+void
+dk3bmj_init(dk3_bm_conversion_job_t *job, dk3_app_t *app)
+{
+
+
+#line 328 "dk3bmj.ctr"
+ job->opt = NULL;
+ if(app) {
+ job->msg = dk3app_messages(
+ app,
+ dk3bmep_str_get_string_table_name(),
+ (dkChar const **)dk3bmep_str_get_message_texts()
+ );
+ if(!(job->msg)) {
+ job->msg = dk3bmep_str_get_message_texts();
+ }
+ } else {
+ job->msg = dk3bmep_str_get_message_texts();
+ }
+ job->sfn = NULL;
+ job->dfn = NULL;
+ job->dfile = NULL;
+ job->biftype = 0;
+ job->bif = NULL;
+ job->pComm = NULL;
+ job->minpb = 0;
+ job->maxpb = 0;
+ job->do_translate = 0;
+ job->x_translate = 0.0;
+ job->y_translate = 0.0;
+ job->do_rotate = 0;
+ job->do_float_scale = 0;
+ job->x_scale = 1.0;
+ job->y_scale = 1.0;
+ job->x_size = 0L;
+ job->y_size = 0L;
+ job->x_0 = 0.0;
+ job->x_1 = 0.0;
+ job->y_0 = 0.0;
+ job->y_1 = 0.0;
+ job->do_header_footer = 1;
+ job->procedure = DK3_BMEPS_GRAY_UNCOMPRESSED;
+ job->bpc = 8;
+ job->nPages = 1;
+ job->currentPage = 1;
+ job->pdf = NULL;
+
+#line 368 "dk3bmj.ctr"
+}
+
+
+
+void
+dk3bmj_progress(void *pc, int val)
+{
+
+
+#line 376 "dk3bmj.ctr"
+#if DK3_USE_WX
+ DkWxCommunicator *pComm;
+ if(pc) {
+
+#line 379 "dk3bmj.ctr"
+ pComm = (DkWxCommunicator *)pc;
+ pComm->updateGauge(val);
+ }
+#endif
+
+
+#line 384 "dk3bmj.ctr"
+}
+
+
+
+void
+dk3bmj_lines_do_progress(
+ void *pc,
+ int min,
+ int max,
+ dk3_bif_coord_t h,
+ dk3_bif_coord_t y
+)
+{
+
+
+#line 398 "dk3bmj.ctr"
+#if DK3_USE_WX
+ {
+ unsigned long ul;
+ int i;
+
+
+#line 403 "dk3bmj.ctr"
+ if((pc) && (max > min)) {
+
+#line 404 "dk3bmj.ctr"
+ ul = (unsigned long)min
+ + (((unsigned long)y + 1UL) * ((unsigned long)(max - min)))
+ /(unsigned long)h;
+ i = (int)ul;
+ if(i < min) i = min;
+ if(i > max) i = max;
+ dk3bmj_progress(pc, i);
+ } else {
+
+#line 412 "dk3bmj.ctr"
+ }
+ }
+#endif
+
+
+#line 416 "dk3bmj.ctr"
+}
+
+
+
+void
+dk3bmj_lines_progress(
+ void *pc,
+ int min,
+ int max,
+ dk3_bif_coord_t h,
+ dk3_bif_coord_t y
+)
+{
+#if DK3_USE_WX
+ dk3bmj_lines_do_progress(pc, min, max, h, y);
+#endif
+}
+
+
+
+void
+dk3bmj_objects_do_progress(
+ void *pc,
+ int min,
+ int max,
+ unsigned long nObjects,
+ unsigned long co
+)
+{
+
+
+#line 446 "dk3bmj.ctr"
+#if DK3_USE_WX
+ unsigned long ul; /* Temporary value. */
+ int i; /* New progress bar value. */
+
+ if((pc) && (max > min)) {
+
+#line 451 "dk3bmj.ctr"
+ ul = (unsigned long)min
+ + ((co + 1UL) * ((unsigned long)(max - min))) / nObjects;
+ i = (int)ul;
+ if(i < min) i = min;
+ if(i > max) i = max;
+ dk3bmj_progress(pc, i);
+ } else {
+
+#line 458 "dk3bmj.ctr"
+ }
+#endif
+
+
+#line 461 "dk3bmj.ctr"
+}
+
+
+void
+dk3bmj_obj_progress(
+ void *pc,
+ int min,
+ int max,
+ unsigned long nObjects,
+ unsigned long co
+)
+{
+#if DK3_USE_WX
+ dk3bmj_objects_do_progress(pc, min, max, nObjects, co);
+#endif
+}
+
+
+
+void
+dk3bmj_log_i1(
+ dk3_app_t *app,
+ int ll,
+ size_t i,
+ int dest,
+ dk3_bm_conversion_job_t *job
+)
+{
+#if DK3_USE_WX
+ dkChar const *p1; /* Log text. */
+ DkWxCommunicator *pComm; /* Communicator object. */
+#endif
+ if(dest & DK3_BMJ_LOG_APP) {
+ if(app) {
+ dk3app_log_i1(app, ll, i);
+ }
+ }
+#if DK3_USE_WX
+ if((dest & DK3_BMJ_LOG_JOB) && (ll <= dk3bmj_required_log_level)) {
+ if(job) {
+ if(app) {
+ pComm = (DkWxCommunicator *)(job->pComm);
+ if(pComm) {
+ pComm->setLogLevel(ll);
+ p1 = dk3app_localized(app, i);
+ if(p1) {
+ pComm->addDkText(p1);
+ pComm->nl();
+ }
+ }
+ }
+ }
+ }
+#endif
+}
+
+
+
+void
+dk3bmj_log_i3(
+ dk3_app_t *app,
+ int ll,
+ size_t i1,
+ size_t i2,
+ dkChar const *txt,
+ int dest,
+ dk3_bm_conversion_job_t *job
+)
+{
+#if DK3_USE_WX
+ dkChar const *p1; /* First message part. */
+ dkChar const *p2; /* Last message part. */
+ DkWxCommunicator *pComm; /* Communicator object. */
+#endif
+ if(dest & DK3_BMJ_LOG_APP) {
+ if(app) {
+ dk3app_log_i3(app, ll, i1, i2, txt);
+ }
+ }
+#if DK3_USE_WX
+ if((dest & DK3_BMJ_LOG_JOB) && (ll <= dk3bmj_required_log_level)) {
+ if(job) {
+ if(app) {
+ pComm = (DkWxCommunicator *)(job->pComm);
+ if(pComm) {
+ pComm->setLogLevel(ll);
+ p1 = dk3app_localized(app, i1);
+ p2 = dk3app_localized(app, i2);
+ if((p1) && (p2)) {
+ pComm->addDkText(p1);
+ if(txt) {
+ pComm->addDkText(txt);
+ }
+ pComm->addDkText(p2);
+ pComm->nl();
+ }
+ }
+ }
+ }
+ }
+#endif
+}
+
+
+
+
+void
+dk3bmj_log_i5(
+ dk3_app_t *app,
+ int ll,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ dkChar const *txt1,
+ dkChar const *txt2,
+ int dest,
+ dk3_bm_conversion_job_t *job
+)
+{
+#if DK3_USE_WX
+ dkChar const *p1; /* First message part. */
+ dkChar const *p2; /* Centered message part. */
+ dkChar const *p3; /* Last message part. */
+ DkWxCommunicator *pComm; /* Communicator object. */
+#endif
+ if(dest & DK3_BMJ_LOG_APP) {
+ if(app) {
+ dk3app_log_i5(app, ll, i1, i2, i3, txt1, txt2);
+ }
+ }
+#if DK3_USE_WX
+ if((dest & DK3_BMJ_LOG_JOB) && (ll <= dk3bmj_required_log_level)) {
+ if(job) {
+ if(app) {
+ pComm = (DkWxCommunicator *)(job->pComm);
+ if(pComm) {
+ pComm->setLogLevel(ll);
+ p1 = dk3app_localized(app, i1);
+ p2 = dk3app_localized(app, i2);
+ p3 = dk3app_localized(app, i3);
+ if((p1) && (p2) && (p3)) {
+ pComm->addDkText(p1);
+ if(txt1) {
+ pComm->addDkText(txt1);
+ }
+ pComm->addDkText(p2);
+ if(txt2) {
+ pComm->addDkText(txt2);
+ }
+ pComm->addDkText(p3);
+ pComm->nl();
+ }
+ }
+ }
+ }
+ }
+#endif
+}
+
+
+
+void
+dk3bmj_log_1(
+ dk3_app_t *app,
+ int ll,
+ dkChar const * const *txta,
+ size_t i,
+ int dest,
+ dk3_bm_conversion_job_t *job
+)
+{
+#if DK3_USE_WX
+ dkChar const *p1; /* Message text. */
+ DkWxCommunicator *pComm; /* Communicator object. */
+#endif
+
+
+#line 637 "dk3bmj.ctr"
+ if(txta) {
+
+#line 638 "dk3bmj.ctr"
+ if(dest & DK3_BMJ_LOG_APP) {
+
+#line 639 "dk3bmj.ctr"
+ if(app) {
+
+#line 640 "dk3bmj.ctr"
+ dk3app_log_1(app, ll, txta, i);
+ } else {
+
+#line 642 "dk3bmj.ctr"
+ }
+ } else {
+
+#line 644 "dk3bmj.ctr"
+ }
+#if DK3_USE_WX
+ if((dest & DK3_BMJ_LOG_JOB) && (ll <= dk3bmj_required_log_level)) {
+
+#line 647 "dk3bmj.ctr"
+ if(job) {
+
+#line 648 "dk3bmj.ctr"
+ if(app) {
+
+#line 649 "dk3bmj.ctr"
+ pComm = (DkWxCommunicator *)(job->pComm);
+ if(pComm) {
+
+#line 651 "dk3bmj.ctr"
+ pComm->setLogLevel(ll);
+ p1 = txta[i];
+ if(p1) {
+
+#line 654 "dk3bmj.ctr"
+ pComm->addDkText(p1);
+ pComm->nl();
+ } else {
+
+#line 657 "dk3bmj.ctr"
+ }
+ } else {
+
+#line 659 "dk3bmj.ctr"
+ }
+ } else {
+
+#line 661 "dk3bmj.ctr"
+ }
+ } else {
+
+#line 663 "dk3bmj.ctr"
+ }
+ } else {
+
+#line 665 "dk3bmj.ctr"
+ }
+#endif
+ } else {
+
+#line 668 "dk3bmj.ctr"
+ }
+
+#line 669 "dk3bmj.ctr"
+}
+
+
+
+void
+dk3bmj_log_3(
+ dk3_app_t *app,
+ int ll,
+ dkChar const * const *txta,
+ size_t i1,
+ size_t i2,
+ dkChar const *txt,
+ int dest,
+ dk3_bm_conversion_job_t *job
+)
+{
+#if DK3_USE_WX
+ dkChar const *p1; /* First message part. */
+ dkChar const *p2; /* Last message part. */
+ DkWxCommunicator *pComm; /* Communicator object. */
+#endif
+ if(txta) {
+ if(dest & DK3_BMJ_LOG_APP) {
+ if(app) {
+ dk3app_log_3(app, ll, txta, i1, i2, txt);
+ }
+ }
+#if DK3_USE_WX
+ if((dest & DK3_BMJ_LOG_JOB) && (ll <= dk3bmj_required_log_level)) {
+ if(job) {
+ if(app) {
+ pComm = (DkWxCommunicator *)(job->pComm);
+ if(pComm) {
+ pComm->setLogLevel(ll);
+ p1 = txta[i1];
+ p2 = txta[i2];
+ if((p1) && (p2)) {
+ pComm->addDkText(p1);
+ if(txt) {
+ pComm->addDkText(txt);
+ }
+ pComm->addDkText(p2);
+ pComm->nl();
+ }
+ }
+ }
+ }
+ }
+#endif
+ }
+}
+
+
+
+
+void
+dk3bmj_log_5(
+ dk3_app_t *app,
+ int ll,
+ dkChar const * const *txta,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ dkChar const *txt1,
+ dkChar const *txt2,
+ int dest,
+ dk3_bm_conversion_job_t *job
+)
+{
+#if DK3_USE_WX
+ dkChar const *p1; /* First message part. */
+ dkChar const *p2; /* Centered message part. */
+ dkChar const *p3; /* Last message part. */
+ DkWxCommunicator *pComm; /* Communicator object. */
+#endif
+ if(txta) {
+ if(dest & DK3_BMJ_LOG_APP) {
+ if(app) {
+ dk3app_log_5(app, ll, txta, i1, i2, i3, txt1, txt2);
+ }
+ }
+#if DK3_USE_WX
+ if((dest & DK3_BMJ_LOG_JOB) && (ll <= dk3bmj_required_log_level)) {
+ if(job) {
+ if(app) {
+ pComm = (DkWxCommunicator *)(job->pComm);
+ if(pComm) {
+ pComm->setLogLevel(ll);
+ p1 = txta[i1];
+ p2 = txta[i2];
+ p3 = txta[i3];
+ if((p1) && (p2) && (p3)) {
+ pComm->addDkText(p1);
+ if(txt1) {
+ pComm->addDkText(txt1);
+ }
+ pComm->addDkText(p2);
+ if(txt2) {
+ pComm->addDkText(txt2);
+ }
+ pComm->addDkText(p3);
+ pComm->nl();
+ }
+ }
+ }
+ }
+ }
+#endif
+ }
+}
+
+
diff --git a/support/dktools/dk3bmj.ctr b/support/dktools/dk3bmj.ctr
new file mode 100644
index 0000000000..84f8f182c9
--- /dev/null
+++ b/support/dktools/dk3bmj.ctr
@@ -0,0 +1,780 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Initialize job structure.
+ @param job Structure to initialize.
+ @param app Application structure for diagnostics.
+*/
+void
+dk3bmj_init(dk3_bm_conversion_job_t *job, dk3_app_t *app);
+
+/** Write a log message.
+ @param app Application structure.
+ @param ll Log level.
+ @param i Index of message text in internal array.
+ @param dest Destination, combination of DK3_BMJ_LOG_xxx,
+ see @ref bmepslogtargets.
+ @param job Job structure.
+*/
+void
+dk3bmj_log_i1(
+ dk3_app_t *app,
+ int ll,
+ size_t i,
+ int dest,
+ dk3_bm_conversion_job_t *job
+);
+
+/** Write a log message.
+ @param app Application structure.
+ @param ll Log level.
+ @param i1 Index of first message text in internal array.
+ @param i2 Index of third message text in internal array.
+ @param txt Second message text.
+ @param dest Destination, combination of DK3_BMJ_LOG_xxx,
+ see @ref bmepslogtargets.
+ @param job Job structure.
+*/
+void
+dk3bmj_log_i3(
+ dk3_app_t *app,
+ int ll,
+ size_t i1,
+ size_t i2,
+ dkChar const *txt,
+ int dest,
+ dk3_bm_conversion_job_t *job
+);
+
+/** Write a log message.
+ @param app Application structure.
+ @param ll Log level.
+ @param i1 Index of first message text in internal array.
+ @param i2 Index of third message text in internal array.
+ @param i3 Index of fifth message text in internal array.
+ @param txt1 Second message text.
+ @param txt2 Fourth message text.
+ @param dest Destination, combination of DK3_BMJ_LOG_xxx,
+ see @ref bmepslogtargets.
+ @param job Job structure.
+*/
+void
+dk3bmj_log_i5(
+ dk3_app_t *app,
+ int ll,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ dkChar const *txt1,
+ dkChar const *txt2,
+ int dest,
+ dk3_bm_conversion_job_t *job
+);
+
+/** Write a log message.
+ @param app Application structure.
+ @param ll Log level.
+ @param txta Localized message texts.
+ @param i Index of message text in @a txta.
+ @param dest Destination, combination of DK3_BMJ_LOG_xxx,
+ see @ref bmepslogtargets.
+ @param job Job structure.
+*/
+void
+dk3bmj_log_1(
+ dk3_app_t *app,
+ int ll,
+ dkChar const * const *txta,
+ size_t i,
+ int dest,
+ dk3_bm_conversion_job_t *job
+);
+
+/** Write a log message.
+ @param app Application structure.
+ @param ll Log level.
+ @param txta Localized message texts.
+ @param i1 Index of first message text in @a txta.
+ @param i2 Index of third message text in @a txta.
+ @param txt Second message text.
+ @param dest Destination, combination of DK3_BMJ_LOG_xxx,
+ see @ref bmepslogtargets.
+ @param job Job structure.
+*/
+void
+dk3bmj_log_3(
+ dk3_app_t *app,
+ int ll,
+ dkChar const * const *txta,
+ size_t i1,
+ size_t i2,
+ dkChar const *txt,
+ int dest,
+ dk3_bm_conversion_job_t *job
+);
+
+/** Write a log message.
+ @param app Application structure.
+ @param ll Log level.
+ @param txta Localized message texts.
+ @param i1 Index of first message text in @a txta.
+ @param i2 Index of third message text in @a txta.
+ @param i3 Index of fifth message text in @a txta.
+ @param txt1 Second message text.
+ @param txt2 Fourth message text.
+ @param dest Destination, combination of DK3_BMJ_LOG_xxx,
+ see @ref bmepslogtargets.
+ @param job Job structure.
+*/
+void
+dk3bmj_log_5(
+ dk3_app_t *app,
+ int ll,
+ dkChar const * const *txta,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ dkChar const *txt1,
+ dkChar const *txt2,
+ int dest,
+ dk3_bm_conversion_job_t *job
+);
+
+/** Set new value for progress bar.
+ @param pc Communicator object pointer.
+ @param val New value (0-1000).
+*/
+void
+dk3bmj_progress(void *pc, int val);
+
+/** Show progress for completed image scanlines.
+ @param pc Communicator object.
+ @param min Minimum progress bar value.
+ @param max Maximum progress bar value.
+ @param h Image height (number of lines).
+ @param y Current line completed.
+*/
+void
+dk3bmj_lines_do_progress(
+ void *pc,
+ int min,
+ int max,
+ dk3_bif_coord_t h,
+ dk3_bif_coord_t y
+);
+
+/** Show progress for completed image scanlines.
+ Calls dk3bmj_lines_do_progress() if DK3_USE_WX is on,
+ does nothing otherwise.
+ @param pc Communicator object.
+ @param min Minimum progress bar value.
+ @param max Maximum progress bar value.
+ @param h Image height (number of lines).
+ @param y Current line completed.
+*/
+void
+dk3bmj_lines_progress(
+ void *pc,
+ int min,
+ int max,
+ dk3_bif_coord_t h,
+ dk3_bif_coord_t y
+);
+
+/** Show progress for completed image scanlines.
+ @param pc Communicator object.
+ @param min Minimum progress bar value.
+ @param max Maximum progress bar value.
+ @param nObjects Number of objects.
+ @param co Current object number.
+*/
+void
+dk3bmj_objects_do_progress(
+ void *pc,
+ int min,
+ int max,
+ unsigned long nObjects,
+ unsigned long co
+);
+
+/** Show progress for completed image scanlines.
+ Call dk3bmj_objects_do_progress() if DK3_USE_WX is on,
+ do nothing otherwise.
+ @param pc Communicator object.
+ @param min Minimum progress bar value.
+ @param max Maximum progress bar value.
+ @param nObjects Number of objects.
+ @param co Current object number.
+*/
+void
+dk3bmj_obj_progress(
+ void *pc,
+ int min,
+ int max,
+ unsigned long nObjects,
+ unsigned long co
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/** @defgroup bmepslogtargets Log targets for bmeps3 and wxbmeps . */
+/**@{*/
+/** Log destination: Application structure.
+*/
+#define DK3_BMJ_LOG_APP 1
+
+/** Log destination: Job structure.
+*/
+#define DK3_BMJ_LOG_JOB 2
+
+/** Log destination: Application structure and job structure.
+*/
+#define DK3_BMJ_LOG_BOTH (DK3_BMJ_LOG_APP | DK3_BMJ_LOG_JOB)
+/**@}*/
+
+
+
+/** @defgroup bmepscompression Compression type used by bmeps.
+*/
+/**@{*/
+/** Output procedure: Uncompressed RGB.
+*/
+#define DK3_BMEPS_RGB_UNCOMPRESSED 0
+
+/** Output procedure: Uncompressed gray.
+*/
+#define DK3_BMEPS_GRAY_UNCOMPRESSED 1
+
+/** Output procedure: Run-length compressed RGB, separated color channels.
+*/
+#define DK3_BMEPS_RGB_RUNLENGTH 2
+
+/** Output procedure: Run-length compressed gray.
+*/
+#define DK3_BMEPS_GRAY_RUNLENGTH 3
+
+/** Output procedure: DCT-compressed RGB.
+*/
+#define DK3_BMEPS_RGB_DCT 4
+
+/** Output procedure: DCT-compressed gray.
+*/
+#define DK3_BMEPS_GRAY_DCT 5
+
+/** Output procedure: DCT-compressed CMYK.
+*/
+#define DK3_BMEPS_CMYK_DCT 6
+
+/** Output procedure: Flate-compressed RGB.
+*/
+#define DK3_BMEPS_RGB_FLATE 7
+
+/** Output procedure: Flate-compressed gray.
+*/
+#define DK3_BMEPS_GRAY_FLATE 8
+
+/** Output procedure: Flate-compressed RGB with alpha (PDF output only).
+*/
+#define DK3_BMEPS_RGB_ALPHA_FLATE 9
+
+/** Output procedure: Flate-compressed gray with alpha (PDF output only).
+*/
+#define DK3_BMEPS_GRAY_ALPHA_FLATE 10
+
+/**@}*/
+
+
+
+%% module
+
+#if DK3_USE_WX
+#include "wxbmeps.h"
+#else
+#include "dk3all.h"
+#include "dk3bmj.h"
+#include "dk3bmeps.h"
+#endif
+
+
+
+$!trace-include
+
+
+
+/** Log level required for writing to the log text field in wxbmeps.
+*/
+static int const dk3bmj_required_log_level = DK3_LL_PROGRESS;
+
+
+
+void
+dk3bmj_init(dk3_bm_conversion_job_t *job, dk3_app_t *app)
+{
+ $? "+ dk3bmj_init"
+ job->opt = NULL;
+ if(app) {
+ job->msg = dk3app_messages(
+ app,
+ dk3bmep_str_get_string_table_name(),
+ (dkChar const **)dk3bmep_str_get_message_texts()
+ );
+ if(!(job->msg)) {
+ job->msg = dk3bmep_str_get_message_texts();
+ }
+ } else {
+ job->msg = dk3bmep_str_get_message_texts();
+ }
+ job->sfn = NULL;
+ job->dfn = NULL;
+ job->dfile = NULL;
+ job->biftype = 0;
+ job->bif = NULL;
+ job->pComm = NULL;
+ job->minpb = 0;
+ job->maxpb = 0;
+ job->do_translate = 0;
+ job->x_translate = 0.0;
+ job->y_translate = 0.0;
+ job->do_rotate = 0;
+ job->do_float_scale = 0;
+ job->x_scale = 1.0;
+ job->y_scale = 1.0;
+ job->x_size = 0L;
+ job->y_size = 0L;
+ job->x_0 = 0.0;
+ job->x_1 = 0.0;
+ job->y_0 = 0.0;
+ job->y_1 = 0.0;
+ job->do_header_footer = 1;
+ job->procedure = DK3_BMEPS_GRAY_UNCOMPRESSED;
+ job->bpc = 8;
+ job->nPages = 1;
+ job->currentPage = 1;
+ job->pdf = NULL; $? "- dk3bmj_init"
+}
+
+
+
+void
+dk3bmj_progress(void *pc, int val)
+{
+ $? "+ dk3bmj_progress %d", val
+#if DK3_USE_WX
+ DkWxCommunicator *pComm;
+ if(pc) { $? ". update progress bar"
+ pComm = (DkWxCommunicator *)pc;
+ pComm->updateGauge(val);
+ }
+#endif
+ $? "- dk3bmj_progress"
+}
+
+
+
+void
+dk3bmj_lines_do_progress(
+ void *pc,
+ int min,
+ int max,
+ dk3_bif_coord_t h,
+ dk3_bif_coord_t y
+)
+{
+ $? "+ dk3bmj_lines_do_progress %d %d %lu %lu", min, max, (unsigned long)h, (unsigned long)y
+#if DK3_USE_WX
+ {
+ unsigned long ul;
+ int i;
+ $? ". use wx"
+ if((pc) && (max > min)) { $? ". args ok"
+ ul = (unsigned long)min
+ + (((unsigned long)y + 1UL) * ((unsigned long)(max - min)))
+ /(unsigned long)h;
+ i = (int)ul;
+ if(i < min) i = min;
+ if(i > max) i = max;
+ dk3bmj_progress(pc, i);
+ } else { $? "! args"
+ }
+ }
+#endif
+ $? "- dk3bmj_lines_do_progress"
+}
+
+
+
+void
+dk3bmj_lines_progress(
+ void *pc,
+ int min,
+ int max,
+ dk3_bif_coord_t h,
+ dk3_bif_coord_t y
+)
+{
+#if DK3_USE_WX
+ dk3bmj_lines_do_progress(pc, min, max, h, y);
+#endif
+}
+
+
+
+void
+dk3bmj_objects_do_progress(
+ void *pc,
+ int min,
+ int max,
+ unsigned long nObjects,
+ unsigned long co
+)
+{
+ $? "+ dk3bmj_objects_do_progress %d %d %lu %lu", min, max, nObjects, co
+#if DK3_USE_WX
+ unsigned long ul; /* Temporary value. */
+ int i; /* New progress bar value. */
+
+ if((pc) && (max > min)) { $? ". args ok"
+ ul = (unsigned long)min
+ + ((co + 1UL) * ((unsigned long)(max - min))) / nObjects;
+ i = (int)ul;
+ if(i < min) i = min;
+ if(i > max) i = max;
+ dk3bmj_progress(pc, i);
+ } else { $? "! args"
+ }
+#endif
+ $? "- dk3bmj_objects_do_progress"
+}
+
+
+void
+dk3bmj_obj_progress(
+ void *pc,
+ int min,
+ int max,
+ unsigned long nObjects,
+ unsigned long co
+)
+{
+#if DK3_USE_WX
+ dk3bmj_objects_do_progress(pc, min, max, nObjects, co);
+#endif
+}
+
+
+
+void
+dk3bmj_log_i1(
+ dk3_app_t *app,
+ int ll,
+ size_t i,
+ int dest,
+ dk3_bm_conversion_job_t *job
+)
+{
+#if DK3_USE_WX
+ dkChar const *p1; /* Log text. */
+ DkWxCommunicator *pComm; /* Communicator object. */
+#endif
+ if(dest & DK3_BMJ_LOG_APP) {
+ if(app) {
+ dk3app_log_i1(app, ll, i);
+ }
+ }
+#if DK3_USE_WX
+ if((dest & DK3_BMJ_LOG_JOB) && (ll <= dk3bmj_required_log_level)) {
+ if(job) {
+ if(app) {
+ pComm = (DkWxCommunicator *)(job->pComm);
+ if(pComm) {
+ pComm->setLogLevel(ll);
+ p1 = dk3app_localized(app, i);
+ if(p1) {
+ pComm->addDkText(p1);
+ pComm->nl();
+ }
+ }
+ }
+ }
+ }
+#endif
+}
+
+
+
+void
+dk3bmj_log_i3(
+ dk3_app_t *app,
+ int ll,
+ size_t i1,
+ size_t i2,
+ dkChar const *txt,
+ int dest,
+ dk3_bm_conversion_job_t *job
+)
+{
+#if DK3_USE_WX
+ dkChar const *p1; /* First message part. */
+ dkChar const *p2; /* Last message part. */
+ DkWxCommunicator *pComm; /* Communicator object. */
+#endif
+ if(dest & DK3_BMJ_LOG_APP) {
+ if(app) {
+ dk3app_log_i3(app, ll, i1, i2, txt);
+ }
+ }
+#if DK3_USE_WX
+ if((dest & DK3_BMJ_LOG_JOB) && (ll <= dk3bmj_required_log_level)) {
+ if(job) {
+ if(app) {
+ pComm = (DkWxCommunicator *)(job->pComm);
+ if(pComm) {
+ pComm->setLogLevel(ll);
+ p1 = dk3app_localized(app, i1);
+ p2 = dk3app_localized(app, i2);
+ if((p1) && (p2)) {
+ pComm->addDkText(p1);
+ if(txt) {
+ pComm->addDkText(txt);
+ }
+ pComm->addDkText(p2);
+ pComm->nl();
+ }
+ }
+ }
+ }
+ }
+#endif
+}
+
+
+
+
+void
+dk3bmj_log_i5(
+ dk3_app_t *app,
+ int ll,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ dkChar const *txt1,
+ dkChar const *txt2,
+ int dest,
+ dk3_bm_conversion_job_t *job
+)
+{
+#if DK3_USE_WX
+ dkChar const *p1; /* First message part. */
+ dkChar const *p2; /* Centered message part. */
+ dkChar const *p3; /* Last message part. */
+ DkWxCommunicator *pComm; /* Communicator object. */
+#endif
+ if(dest & DK3_BMJ_LOG_APP) {
+ if(app) {
+ dk3app_log_i5(app, ll, i1, i2, i3, txt1, txt2);
+ }
+ }
+#if DK3_USE_WX
+ if((dest & DK3_BMJ_LOG_JOB) && (ll <= dk3bmj_required_log_level)) {
+ if(job) {
+ if(app) {
+ pComm = (DkWxCommunicator *)(job->pComm);
+ if(pComm) {
+ pComm->setLogLevel(ll);
+ p1 = dk3app_localized(app, i1);
+ p2 = dk3app_localized(app, i2);
+ p3 = dk3app_localized(app, i3);
+ if((p1) && (p2) && (p3)) {
+ pComm->addDkText(p1);
+ if(txt1) {
+ pComm->addDkText(txt1);
+ }
+ pComm->addDkText(p2);
+ if(txt2) {
+ pComm->addDkText(txt2);
+ }
+ pComm->addDkText(p3);
+ pComm->nl();
+ }
+ }
+ }
+ }
+ }
+#endif
+}
+
+
+
+void
+dk3bmj_log_1(
+ dk3_app_t *app,
+ int ll,
+ dkChar const * const *txta,
+ size_t i,
+ int dest,
+ dk3_bm_conversion_job_t *job
+)
+{
+#if DK3_USE_WX
+ dkChar const *p1; /* Message text. */
+ DkWxCommunicator *pComm; /* Communicator object. */
+#endif
+ $? "+ dk3bmj_log_1"
+ if(txta) { $? ". txta"
+ if(dest & DK3_BMJ_LOG_APP) { $? ". write to app"
+ if(app) { $? ". app ok"
+ dk3app_log_1(app, ll, txta, i);
+ } else { $? "! app"
+ }
+ } else { $? ". no need to write to app"
+ }
+#if DK3_USE_WX
+ if((dest & DK3_BMJ_LOG_JOB) && (ll <= dk3bmj_required_log_level)) { $? ". x"
+ if(job) { $? ". job"
+ if(app) { $? ". app"
+ pComm = (DkWxCommunicator *)(job->pComm);
+ if(pComm) { $? ". pComm"
+ pComm->setLogLevel(ll);
+ p1 = txta[i];
+ if(p1) { $? ". p1"
+ pComm->addDkText(p1);
+ pComm->nl();
+ } else { $? "! p1"
+ }
+ } else { $? "! pComm"
+ }
+ } else { $? "! app"
+ }
+ } else { $? "! job"
+ }
+ } else { $? ". no need to write to wx"
+ }
+#endif
+ } else { $? "! txta"
+ } $? "- dk3bmj_log_1"
+}
+
+
+
+void
+dk3bmj_log_3(
+ dk3_app_t *app,
+ int ll,
+ dkChar const * const *txta,
+ size_t i1,
+ size_t i2,
+ dkChar const *txt,
+ int dest,
+ dk3_bm_conversion_job_t *job
+)
+{
+#if DK3_USE_WX
+ dkChar const *p1; /* First message part. */
+ dkChar const *p2; /* Last message part. */
+ DkWxCommunicator *pComm; /* Communicator object. */
+#endif
+ if(txta) {
+ if(dest & DK3_BMJ_LOG_APP) {
+ if(app) {
+ dk3app_log_3(app, ll, txta, i1, i2, txt);
+ }
+ }
+#if DK3_USE_WX
+ if((dest & DK3_BMJ_LOG_JOB) && (ll <= dk3bmj_required_log_level)) {
+ if(job) {
+ if(app) {
+ pComm = (DkWxCommunicator *)(job->pComm);
+ if(pComm) {
+ pComm->setLogLevel(ll);
+ p1 = txta[i1];
+ p2 = txta[i2];
+ if((p1) && (p2)) {
+ pComm->addDkText(p1);
+ if(txt) {
+ pComm->addDkText(txt);
+ }
+ pComm->addDkText(p2);
+ pComm->nl();
+ }
+ }
+ }
+ }
+ }
+#endif
+ }
+}
+
+
+
+
+void
+dk3bmj_log_5(
+ dk3_app_t *app,
+ int ll,
+ dkChar const * const *txta,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ dkChar const *txt1,
+ dkChar const *txt2,
+ int dest,
+ dk3_bm_conversion_job_t *job
+)
+{
+#if DK3_USE_WX
+ dkChar const *p1; /* First message part. */
+ dkChar const *p2; /* Centered message part. */
+ dkChar const *p3; /* Last message part. */
+ DkWxCommunicator *pComm; /* Communicator object. */
+#endif
+ if(txta) {
+ if(dest & DK3_BMJ_LOG_APP) {
+ if(app) {
+ dk3app_log_5(app, ll, txta, i1, i2, i3, txt1, txt2);
+ }
+ }
+#if DK3_USE_WX
+ if((dest & DK3_BMJ_LOG_JOB) && (ll <= dk3bmj_required_log_level)) {
+ if(job) {
+ if(app) {
+ pComm = (DkWxCommunicator *)(job->pComm);
+ if(pComm) {
+ pComm->setLogLevel(ll);
+ p1 = txta[i1];
+ p2 = txta[i2];
+ p3 = txta[i3];
+ if((p1) && (p2) && (p3)) {
+ pComm->addDkText(p1);
+ if(txt1) {
+ pComm->addDkText(txt1);
+ }
+ pComm->addDkText(p2);
+ if(txt2) {
+ pComm->addDkText(txt2);
+ }
+ pComm->addDkText(p3);
+ pComm->nl();
+ }
+ }
+ }
+ }
+ }
+#endif
+ }
+}
+
+
diff --git a/support/dktools/dk3bmj.h b/support/dktools/dk3bmj.h
new file mode 100644
index 0000000000..8b5e9f7c94
--- /dev/null
+++ b/support/dktools/dk3bmj.h
@@ -0,0 +1,338 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3bmj.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3bmj.h Header file for the dk3bmj module.
+*/
+
+#ifndef DK3BMJ_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3BMJ_H_INCLUDED 1
+
+
+#line 10 "dk3bmj.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Initialize job structure.
+ @param job Structure to initialize.
+ @param app Application structure for diagnostics.
+*/
+void
+dk3bmj_init(dk3_bm_conversion_job_t *job, dk3_app_t *app);
+
+/** Write a log message.
+ @param app Application structure.
+ @param ll Log level.
+ @param i Index of message text in internal array.
+ @param dest Destination, combination of DK3_BMJ_LOG_xxx,
+ see @ref bmepslogtargets.
+ @param job Job structure.
+*/
+void
+dk3bmj_log_i1(
+ dk3_app_t *app,
+ int ll,
+ size_t i,
+ int dest,
+ dk3_bm_conversion_job_t *job
+);
+
+/** Write a log message.
+ @param app Application structure.
+ @param ll Log level.
+ @param i1 Index of first message text in internal array.
+ @param i2 Index of third message text in internal array.
+ @param txt Second message text.
+ @param dest Destination, combination of DK3_BMJ_LOG_xxx,
+ see @ref bmepslogtargets.
+ @param job Job structure.
+*/
+void
+dk3bmj_log_i3(
+ dk3_app_t *app,
+ int ll,
+ size_t i1,
+ size_t i2,
+ dkChar const *txt,
+ int dest,
+ dk3_bm_conversion_job_t *job
+);
+
+/** Write a log message.
+ @param app Application structure.
+ @param ll Log level.
+ @param i1 Index of first message text in internal array.
+ @param i2 Index of third message text in internal array.
+ @param i3 Index of fifth message text in internal array.
+ @param txt1 Second message text.
+ @param txt2 Fourth message text.
+ @param dest Destination, combination of DK3_BMJ_LOG_xxx,
+ see @ref bmepslogtargets.
+ @param job Job structure.
+*/
+void
+dk3bmj_log_i5(
+ dk3_app_t *app,
+ int ll,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ dkChar const *txt1,
+ dkChar const *txt2,
+ int dest,
+ dk3_bm_conversion_job_t *job
+);
+
+/** Write a log message.
+ @param app Application structure.
+ @param ll Log level.
+ @param txta Localized message texts.
+ @param i Index of message text in @a txta.
+ @param dest Destination, combination of DK3_BMJ_LOG_xxx,
+ see @ref bmepslogtargets.
+ @param job Job structure.
+*/
+void
+dk3bmj_log_1(
+ dk3_app_t *app,
+ int ll,
+ dkChar const * const *txta,
+ size_t i,
+ int dest,
+ dk3_bm_conversion_job_t *job
+);
+
+/** Write a log message.
+ @param app Application structure.
+ @param ll Log level.
+ @param txta Localized message texts.
+ @param i1 Index of first message text in @a txta.
+ @param i2 Index of third message text in @a txta.
+ @param txt Second message text.
+ @param dest Destination, combination of DK3_BMJ_LOG_xxx,
+ see @ref bmepslogtargets.
+ @param job Job structure.
+*/
+void
+dk3bmj_log_3(
+ dk3_app_t *app,
+ int ll,
+ dkChar const * const *txta,
+ size_t i1,
+ size_t i2,
+ dkChar const *txt,
+ int dest,
+ dk3_bm_conversion_job_t *job
+);
+
+/** Write a log message.
+ @param app Application structure.
+ @param ll Log level.
+ @param txta Localized message texts.
+ @param i1 Index of first message text in @a txta.
+ @param i2 Index of third message text in @a txta.
+ @param i3 Index of fifth message text in @a txta.
+ @param txt1 Second message text.
+ @param txt2 Fourth message text.
+ @param dest Destination, combination of DK3_BMJ_LOG_xxx,
+ see @ref bmepslogtargets.
+ @param job Job structure.
+*/
+void
+dk3bmj_log_5(
+ dk3_app_t *app,
+ int ll,
+ dkChar const * const *txta,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ dkChar const *txt1,
+ dkChar const *txt2,
+ int dest,
+ dk3_bm_conversion_job_t *job
+);
+
+/** Set new value for progress bar.
+ @param pc Communicator object pointer.
+ @param val New value (0-1000).
+*/
+void
+dk3bmj_progress(void *pc, int val);
+
+/** Show progress for completed image scanlines.
+ @param pc Communicator object.
+ @param min Minimum progress bar value.
+ @param max Maximum progress bar value.
+ @param h Image height (number of lines).
+ @param y Current line completed.
+*/
+void
+dk3bmj_lines_do_progress(
+ void *pc,
+ int min,
+ int max,
+ dk3_bif_coord_t h,
+ dk3_bif_coord_t y
+);
+
+/** Show progress for completed image scanlines.
+ Calls dk3bmj_lines_do_progress() if DK3_USE_WX is on,
+ does nothing otherwise.
+ @param pc Communicator object.
+ @param min Minimum progress bar value.
+ @param max Maximum progress bar value.
+ @param h Image height (number of lines).
+ @param y Current line completed.
+*/
+void
+dk3bmj_lines_progress(
+ void *pc,
+ int min,
+ int max,
+ dk3_bif_coord_t h,
+ dk3_bif_coord_t y
+);
+
+/** Show progress for completed image scanlines.
+ @param pc Communicator object.
+ @param min Minimum progress bar value.
+ @param max Maximum progress bar value.
+ @param nObjects Number of objects.
+ @param co Current object number.
+*/
+void
+dk3bmj_objects_do_progress(
+ void *pc,
+ int min,
+ int max,
+ unsigned long nObjects,
+ unsigned long co
+);
+
+/** Show progress for completed image scanlines.
+ Call dk3bmj_objects_do_progress() if DK3_USE_WX is on,
+ do nothing otherwise.
+ @param pc Communicator object.
+ @param min Minimum progress bar value.
+ @param max Maximum progress bar value.
+ @param nObjects Number of objects.
+ @param co Current object number.
+*/
+void
+dk3bmj_obj_progress(
+ void *pc,
+ int min,
+ int max,
+ unsigned long nObjects,
+ unsigned long co
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/** @defgroup bmepslogtargets Log targets for bmeps3 and wxbmeps . */
+/**@{*/
+/** Log destination: Application structure.
+*/
+#define DK3_BMJ_LOG_APP 1
+
+/** Log destination: Job structure.
+*/
+#define DK3_BMJ_LOG_JOB 2
+
+/** Log destination: Application structure and job structure.
+*/
+#define DK3_BMJ_LOG_BOTH (DK3_BMJ_LOG_APP | DK3_BMJ_LOG_JOB)
+/**@}*/
+
+
+
+/** @defgroup bmepscompression Compression type used by bmeps.
+*/
+/**@{*/
+/** Output procedure: Uncompressed RGB.
+*/
+#define DK3_BMEPS_RGB_UNCOMPRESSED 0
+
+/** Output procedure: Uncompressed gray.
+*/
+#define DK3_BMEPS_GRAY_UNCOMPRESSED 1
+
+/** Output procedure: Run-length compressed RGB, separated color channels.
+*/
+#define DK3_BMEPS_RGB_RUNLENGTH 2
+
+/** Output procedure: Run-length compressed gray.
+*/
+#define DK3_BMEPS_GRAY_RUNLENGTH 3
+
+/** Output procedure: DCT-compressed RGB.
+*/
+#define DK3_BMEPS_RGB_DCT 4
+
+/** Output procedure: DCT-compressed gray.
+*/
+#define DK3_BMEPS_GRAY_DCT 5
+
+/** Output procedure: DCT-compressed CMYK.
+*/
+#define DK3_BMEPS_CMYK_DCT 6
+
+/** Output procedure: Flate-compressed RGB.
+*/
+#define DK3_BMEPS_RGB_FLATE 7
+
+/** Output procedure: Flate-compressed gray.
+*/
+#define DK3_BMEPS_GRAY_FLATE 8
+
+/** Output procedure: Flate-compressed RGB with alpha (PDF output only).
+*/
+#define DK3_BMEPS_RGB_ALPHA_FLATE 9
+
+/** Output procedure: Flate-compressed gray with alpha (PDF output only).
+*/
+#define DK3_BMEPS_GRAY_ALPHA_FLATE 10
+
+/**@}*/
+
+
+
+
+#endif
diff --git a/support/dktools/dk3bom.c b/support/dktools/dk3bom.c
new file mode 100644
index 0000000000..1927989b3c
--- /dev/null
+++ b/support/dktools/dk3bom.c
@@ -0,0 +1,223 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3bom.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3bom.c The dk3bom module.
+*/
+
+
+#line 76 "dk3bom.ctr"
+
+#include "dk3const.h"
+#include "dk3stm.h"
+#include "dk3bom.h"
+
+/** Initialize detector structure.
+ @param ptr Detector structure to initialize.
+*/
+void
+dk3bom_detect_init(dk3_bom_detector_t *ptr, int de)
+{
+ if (NULL != ptr) {
+ ptr->defenc = de;
+ ptr->found = de;
+ ptr->state = 0;
+ ptr->rjb = 0;
+ ptr->rj[0] = 0x00;
+ ptr->rj[1] = 0x00;
+ ptr->rj[2] = 0x00;
+ ptr->rj[3] = 0x00;
+ }
+}
+
+/*
+ BOMS and states
+ ---------------
+ UTF-32 LSB: 0xFF (1) 0xFE (2) 0x00 (3) 0x00
+ UTF-32 MSB: 0x00 (4) 0x00 (5) 0xFE (6) 0xFF
+ UTF-16 LSB: 0xFF (1) 0xFE (2)
+ UTF-16 MSB: 0xFE (7) 0xFF
+ UTF-8: 0xEF (8) 0xBB (9) 0xBF
+*/
+
+
+int
+dk3bom_detect_add(dk3_bom_detector_t *ptr, unsigned char b)
+{
+ int back = DK3_STM_ERROR;
+ if (NULL != ptr) {
+ switch (ptr->state) {
+ case 0: {
+ ptr->rj[0] = b;
+ ptr->rjb = 1;
+ switch ((int)(b)) {
+ case 0x00: {
+ ptr->state = 4; back = DK3_STM_ACCEPT;
+ } break;
+ case 0xFF: {
+ ptr->state = 1; back = DK3_STM_ACCEPT;
+ } break;
+ case 0xFE: {
+ ptr->state = 7; back = DK3_STM_ACCEPT;
+ } break;
+ case 0xEF: {
+ ptr->state = 8; back = DK3_STM_ACCEPT;
+ } break;
+ default: {
+ ptr->state = -1; back = DK3_STM_FINISHED;
+ } break;
+ }
+ } break;
+ case 1: {
+ ptr->rj[1] = b;
+ ptr->rjb = 2;
+ if (0xFE == b) {
+ ptr->state = 2;
+ back = DK3_STM_ACCEPT;
+ ptr->found = DK3_FILE_ENCODING_UTF16_LSB_FIRST;
+ ptr->rjb = 0;
+ } else {
+ ptr->state = -1; back = DK3_STM_FINISHED;
+ }
+ } break;
+ case 2: {
+ ptr->rj[0] = b;
+ ptr->rjb = 1;
+ if (0x00 == b) {
+ ptr->state = 3; back = DK3_STM_ACCEPT;
+ } else {
+ ptr->state = -1; back = DK3_STM_FINISHED;
+ ptr->found = DK3_FILE_ENCODING_UTF16_LSB_FIRST;
+ }
+ } break;
+ case 3: {
+ ptr->rj[1] = b;
+ ptr->rjb = 2;
+ if (0x00 == b) {
+ ptr->state = -1; back = DK3_STM_FINISHED;
+ ptr->found = DK3_FILE_ENCODING_UNICODE_LSB_FIRST;
+ ptr->rjb = 0;
+ } else {
+ ptr->state = -1; back = DK3_STM_FINISHED;
+ ptr->found = DK3_FILE_ENCODING_UTF16_LSB_FIRST;
+ }
+ } break;
+ case 4: {
+ ptr->rj[1] = b;
+ ptr->rjb = 2;
+ if (0x00 == b) {
+ ptr->state = 5; back = DK3_STM_ACCEPT;
+ } else {
+ ptr->state = -1; back = DK3_STM_FINISHED;
+ }
+ } break;
+ case 5: {
+ ptr->rj[2] = b;
+ ptr->rjb = 3;
+ if (0xFE == b) {
+ ptr->state = 6; back = DK3_STM_ACCEPT;
+ } else {
+ ptr->state = -1; back = DK3_STM_FINISHED;
+ }
+ } break;
+ case 6: {
+ ptr->rj[3] = b;
+ ptr->rjb = 4;
+ if (0xFF == b) {
+ ptr->state = -1; back = DK3_STM_FINISHED;
+ ptr->found = DK3_FILE_ENCODING_UNICODE_MSB_FIRST;
+ ptr->rjb = 0;
+ } else {
+ ptr->state = -1; back = DK3_STM_FINISHED;
+ }
+ } break;
+ case 7: {
+ ptr->rj[1] = b;
+ ptr->rjb = 2;
+ if (0xFF == b) {
+ ptr->state= -1; back = DK3_STM_FINISHED;
+ ptr->found = DK3_FILE_ENCODING_UTF16_MSB_FIRST;
+ ptr->rjb = 0;
+ } else {
+ ptr->state = -1; back = DK3_STM_FINISHED;
+ }
+ } break;
+ case 8: {
+ ptr->rj[1] = b;
+ ptr->rjb = 2;
+ if (0xBB == b) {
+ ptr->state = 9; back = DK3_STM_ACCEPT;
+ } else {
+ ptr->state = -1; back = DK3_STM_FINISHED;
+ }
+ } break;
+ case 9: {
+ ptr->rj[2] = b;
+ ptr->rjb = 3;
+ if (0xBF == b) {
+ ptr->state = -1; back = DK3_STM_FINISHED;
+ ptr->found = DK3_FILE_ENCODING_UTF8;
+ ptr->rjb = 0;
+ } else {
+ ptr->state = -1; back = DK3_STM_FINISHED;
+ }
+ } break;
+ /*
+ Default not necessary due to initialization of return variable.
+ */
+ }
+ }
+ return back;
+}
+
+
+
+void
+dk3bom_detect_results(
+ int *enc, const unsigned char **rjptr, size_t *rjsz, dk3_bom_detector_t *ptr
+)
+{
+ if (NULL != ptr) {
+ if (NULL != enc) { *enc = ptr->found; }
+ if ((NULL != rjptr) && (NULL != rjsz)) {
+ *rjptr = ptr->rj;
+ *rjsz = ptr->rjb;
+ } else {
+ if (NULL != rjptr) { *rjptr = NULL; }
+ if (NULL != rjsz ) { *rjsz = 0; }
+ }
+ }
+}
+
+
diff --git a/support/dktools/dk3bom.ctr b/support/dktools/dk3bom.ctr
new file mode 100644
index 0000000000..83a7517a90
--- /dev/null
+++ b/support/dktools/dk3bom.ctr
@@ -0,0 +1,258 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+#include "dk3conf.h"
+#include "dk3types.h"
+
+/** @file dk3bom.h Byte order marker detection.
+ The functions in this module check for a byte order marker at the
+ start of a data stream.
+ First use dk3bom_detect_init() to initialize a detector structure.
+ Use dk3bom_detect_add() to add the first byte to the dectector.
+ As long as the result is DK3_STM_ACCEPT, continue adding bytes.
+ On DK3_STM_FINISHED use dk3bom_detect_results() to retrieve the
+ detected encoding and the array of rejected bytes.
+ Process the rejected bytes before processing the remaining bytes
+ from the data stream.
+*/
+
+/** State machine to detect a BOM (byte order marker) at
+ the start of a data stream.
+*/
+typedef struct {
+ int defenc;
+ int found;
+ int state;
+ size_t rjb;
+ unsigned char rj[4];
+} dk3_bom_detector_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Initialize detector structure.
+ @param ptr Detector structure to initialize.
+*/
+void
+dk3bom_detect_init(dk3_bom_detector_t *ptr, int de);
+
+/** Add one byte to detector.
+ @param ptr Detector structure.
+ @param b Byte to add.
+ @return
+ DK3_STM_ACCEPT if there is no result yet,
+ DK3_STM_FINISHED if a result was found or
+ DK3_STM_ERROR on attempts to add further bytes
+ after a result was found.
+*/
+int
+dk3bom_detect_add(dk3_bom_detector_t *ptr, unsigned char b);
+
+/** Retrieve results from detector structure.
+ @param enc Pointer to variable receiving encoding.
+ @param rjptr Address of pointer receiving address of rejected bytes
+ array.
+ @param rjsz Pointer to variable receiving size of rejected bytes
+ array.
+ @param ptr Detector structure (data source).
+*/
+void
+dk3bom_detect_results(
+ int *enc, const unsigned char **rjptr, size_t *rjsz, dk3_bom_detector_t *ptr
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk3const.h"
+#include "dk3stm.h"
+#include "dk3bom.h"
+
+/** Initialize detector structure.
+ @param ptr Detector structure to initialize.
+*/
+void
+dk3bom_detect_init(dk3_bom_detector_t *ptr, int de)
+{
+ if (NULL != ptr) {
+ ptr->defenc = de;
+ ptr->found = de;
+ ptr->state = 0;
+ ptr->rjb = 0;
+ ptr->rj[0] = 0x00;
+ ptr->rj[1] = 0x00;
+ ptr->rj[2] = 0x00;
+ ptr->rj[3] = 0x00;
+ }
+}
+
+/*
+ BOMS and states
+ ---------------
+ UTF-32 LSB: 0xFF (1) 0xFE (2) 0x00 (3) 0x00
+ UTF-32 MSB: 0x00 (4) 0x00 (5) 0xFE (6) 0xFF
+ UTF-16 LSB: 0xFF (1) 0xFE (2)
+ UTF-16 MSB: 0xFE (7) 0xFF
+ UTF-8: 0xEF (8) 0xBB (9) 0xBF
+*/
+
+
+int
+dk3bom_detect_add(dk3_bom_detector_t *ptr, unsigned char b)
+{
+ int back = DK3_STM_ERROR;
+ if (NULL != ptr) {
+ switch (ptr->state) {
+ case 0: {
+ ptr->rj[0] = b;
+ ptr->rjb = 1;
+ switch ((int)(b)) {
+ case 0x00: {
+ ptr->state = 4; back = DK3_STM_ACCEPT;
+ } break;
+ case 0xFF: {
+ ptr->state = 1; back = DK3_STM_ACCEPT;
+ } break;
+ case 0xFE: {
+ ptr->state = 7; back = DK3_STM_ACCEPT;
+ } break;
+ case 0xEF: {
+ ptr->state = 8; back = DK3_STM_ACCEPT;
+ } break;
+ default: {
+ ptr->state = -1; back = DK3_STM_FINISHED;
+ } break;
+ }
+ } break;
+ case 1: {
+ ptr->rj[1] = b;
+ ptr->rjb = 2;
+ if (0xFE == b) {
+ ptr->state = 2;
+ back = DK3_STM_ACCEPT;
+ ptr->found = DK3_FILE_ENCODING_UTF16_LSB_FIRST;
+ ptr->rjb = 0;
+ } else {
+ ptr->state = -1; back = DK3_STM_FINISHED;
+ }
+ } break;
+ case 2: {
+ ptr->rj[0] = b;
+ ptr->rjb = 1;
+ if (0x00 == b) {
+ ptr->state = 3; back = DK3_STM_ACCEPT;
+ } else {
+ ptr->state = -1; back = DK3_STM_FINISHED;
+ ptr->found = DK3_FILE_ENCODING_UTF16_LSB_FIRST;
+ }
+ } break;
+ case 3: {
+ ptr->rj[1] = b;
+ ptr->rjb = 2;
+ if (0x00 == b) {
+ ptr->state = -1; back = DK3_STM_FINISHED;
+ ptr->found = DK3_FILE_ENCODING_UNICODE_LSB_FIRST;
+ ptr->rjb = 0;
+ } else {
+ ptr->state = -1; back = DK3_STM_FINISHED;
+ ptr->found = DK3_FILE_ENCODING_UTF16_LSB_FIRST;
+ }
+ } break;
+ case 4: {
+ ptr->rj[1] = b;
+ ptr->rjb = 2;
+ if (0x00 == b) {
+ ptr->state = 5; back = DK3_STM_ACCEPT;
+ } else {
+ ptr->state = -1; back = DK3_STM_FINISHED;
+ }
+ } break;
+ case 5: {
+ ptr->rj[2] = b;
+ ptr->rjb = 3;
+ if (0xFE == b) {
+ ptr->state = 6; back = DK3_STM_ACCEPT;
+ } else {
+ ptr->state = -1; back = DK3_STM_FINISHED;
+ }
+ } break;
+ case 6: {
+ ptr->rj[3] = b;
+ ptr->rjb = 4;
+ if (0xFF == b) {
+ ptr->state = -1; back = DK3_STM_FINISHED;
+ ptr->found = DK3_FILE_ENCODING_UNICODE_MSB_FIRST;
+ ptr->rjb = 0;
+ } else {
+ ptr->state = -1; back = DK3_STM_FINISHED;
+ }
+ } break;
+ case 7: {
+ ptr->rj[1] = b;
+ ptr->rjb = 2;
+ if (0xFF == b) {
+ ptr->state= -1; back = DK3_STM_FINISHED;
+ ptr->found = DK3_FILE_ENCODING_UTF16_MSB_FIRST;
+ ptr->rjb = 0;
+ } else {
+ ptr->state = -1; back = DK3_STM_FINISHED;
+ }
+ } break;
+ case 8: {
+ ptr->rj[1] = b;
+ ptr->rjb = 2;
+ if (0xBB == b) {
+ ptr->state = 9; back = DK3_STM_ACCEPT;
+ } else {
+ ptr->state = -1; back = DK3_STM_FINISHED;
+ }
+ } break;
+ case 9: {
+ ptr->rj[2] = b;
+ ptr->rjb = 3;
+ if (0xBF == b) {
+ ptr->state = -1; back = DK3_STM_FINISHED;
+ ptr->found = DK3_FILE_ENCODING_UTF8;
+ ptr->rjb = 0;
+ } else {
+ ptr->state = -1; back = DK3_STM_FINISHED;
+ }
+ } break;
+ /*
+ Default not necessary due to initialization of return variable.
+ */
+ }
+ }
+ return back;
+}
+
+
+
+void
+dk3bom_detect_results(
+ int *enc, const unsigned char **rjptr, size_t *rjsz, dk3_bom_detector_t *ptr
+)
+{
+ if (NULL != ptr) {
+ if (NULL != enc) { *enc = ptr->found; }
+ if ((NULL != rjptr) && (NULL != rjsz)) {
+ *rjptr = ptr->rj;
+ *rjsz = ptr->rjb;
+ } else {
+ if (NULL != rjptr) { *rjptr = NULL; }
+ if (NULL != rjsz ) { *rjsz = 0; }
+ }
+ }
+}
+
+
diff --git a/support/dktools/dk3bom.h b/support/dktools/dk3bom.h
new file mode 100644
index 0000000000..316b6d356c
--- /dev/null
+++ b/support/dktools/dk3bom.h
@@ -0,0 +1,109 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3bom.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK3BOM_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3BOM_H_INCLUDED 1
+
+
+#line 9 "dk3bom.ctr"
+
+#include "dk3conf.h"
+#include "dk3types.h"
+
+/** @file dk3bom.h Byte order marker detection.
+ The functions in this module check for a byte order marker at the
+ start of a data stream.
+ First use dk3bom_detect_init() to initialize a detector structure.
+ Use dk3bom_detect_add() to add the first byte to the dectector.
+ As long as the result is DK3_STM_ACCEPT, continue adding bytes.
+ On DK3_STM_FINISHED use dk3bom_detect_results() to retrieve the
+ detected encoding and the array of rejected bytes.
+ Process the rejected bytes before processing the remaining bytes
+ from the data stream.
+*/
+
+/** State machine to detect a BOM (byte order marker) at
+ the start of a data stream.
+*/
+typedef struct {
+ int defenc;
+ int found;
+ int state;
+ size_t rjb;
+ unsigned char rj[4];
+} dk3_bom_detector_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Initialize detector structure.
+ @param ptr Detector structure to initialize.
+*/
+void
+dk3bom_detect_init(dk3_bom_detector_t *ptr, int de);
+
+/** Add one byte to detector.
+ @param ptr Detector structure.
+ @param b Byte to add.
+ @return
+ DK3_STM_ACCEPT if there is no result yet,
+ DK3_STM_FINISHED if a result was found or
+ DK3_STM_ERROR on attempts to add further bytes
+ after a result was found.
+*/
+int
+dk3bom_detect_add(dk3_bom_detector_t *ptr, unsigned char b);
+
+/** Retrieve results from detector structure.
+ @param enc Pointer to variable receiving encoding.
+ @param rjptr Address of pointer receiving address of rejected bytes
+ array.
+ @param rjsz Pointer to variable receiving size of rejected bytes
+ array.
+ @param ptr Detector structure (data source).
+*/
+void
+dk3bom_detect_results(
+ int *enc, const unsigned char **rjptr, size_t *rjsz, dk3_bom_detector_t *ptr
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk3chks.c b/support/dktools/dk3chks.c
new file mode 100644
index 0000000000..28dcf30bd2
--- /dev/null
+++ b/support/dktools/dk3chks.c
@@ -0,0 +1,397 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3chks.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3chks.c The dk3chks module.
+*/
+
+
+#line 66 "dk3chks.ctr"
+
+#include "dk3all.h"
+
+#if DK3_HAVE_OPENSSL_MD5_H
+#include <openssl/md5.h>
+#endif
+#if DK3_HAVE_OPENSSL_SHA_H
+#include <openssl/sha.h>
+#endif
+#if DK3_HAVE_OPENSSL_RIPEMD_H
+#include <openssl/ripemd.h>
+#endif
+
+
+
+
+#line 81 "dk3chks.ctr"
+
+
+
+/** Names of message digest algorithms.
+ Order here must match order of DK3_MD_TYPE_xxx in dk3const.h.
+*/
+static dkChar const * const dk3_checksum_type_names[] = {
+/* 0 */ dkT("MD5"),
+/* 1 */ dkT("SHA-1"),
+/* 2 */ dkT("SHA-224"),
+/* 3 */ dkT("SHA-256"),
+/* 4 */ dkT("SHA-384"),
+/* 5 */ dkT("SHA-512"),
+/* 6 */ dkT("RIPEMD-160"),
+NULL
+};
+
+
+
+/** String constants.
+*/
+static dkChar const * const kw[] = {
+#if DK3_ON_WINDOWS
+/* 0 */ dkT("rb"), /* File mode, read binary. */
+#else
+/* 0 */ dkT("r"), /* no difference on non-Windows. */
+#endif
+};
+
+
+
+int
+dk3checksum_get_type_app(dkChar const *n, dk3_app_t *app)
+{
+ int back = -1;
+ if(n) {
+ back = dk3str_array_index(dk3_checksum_type_names, n, 0);
+ if(back == -1) {
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 127, 128, n);
+ }
+ } else {
+ back++;
+ }
+ }
+ return back;
+}
+
+
+
+/** Convert length of binary message digest to length of encoded string.
+ @param l Number of binary bytes to encode.
+ @param cse Message digest encoding.
+ @return Number of text characters produced by encoding.
+*/
+static
+size_t
+dk3chksum_conv_length(size_t l, int cse)
+{
+ size_t back = 0;
+
+
+#line 142 "dk3chks.ctr"
+ switch(cse) {
+ case DK3_DATA_ENCODING_HEX: {
+ back = dk3enc_size_bin_to_hex(l);
+ } break;
+ default: {
+ back = dk3enc_size_bin_to_a85(l);
+ } break;
+ }
+
+#line 150 "dk3chks.ctr"
+ return back;
+}
+
+
+
+/** Get length of binary message digest.
+ @param cst Message digest type.
+ @return Number of binary bytes produced.
+*/
+static
+size_t
+dk3chksum_min_length(int cst)
+{
+ size_t back = 0;
+ switch(cst) {
+ case DK3_MD_TYPE_MD5: back = 16; break;
+ case DK3_MD_TYPE_SHA_1: back = 20; break;
+ case DK3_MD_TYPE_SHA_224: back = 28; break;
+ case DK3_MD_TYPE_SHA_256: back = 32; break;
+ case DK3_MD_TYPE_SHA_384: back = 48; break;
+ case DK3_MD_TYPE_SHA_512: back = 64; break;
+ case DK3_MD_TYPE_RIPEMD_160: back = 20; break;
+ }
+ return back;
+}
+
+
+
+/** Build binary checksum from file.
+ @param db Destination buffer.
+ @param sz Size of \a db.
+ @param fipo File pointer for read access.
+ @param cst Checksum type.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3checksum_binary(char *db, size_t sz, FILE *fipo, int cst, dk3_app_t *app)
+{
+ int back = 0;
+#if DK3_HAVE_OPENSSL_SHA_H
+ SHA_CTX sha_ctx; /* SHA-1 context. */
+#if DK3_HAVE_SHA224 || DK3_HAVE_SHA256
+ SHA256_CTX sha256_ctx; /* SHA-256 context. */
+#endif
+#if DK3_HAVE_SHA384 || DK3_HAVE_SHA512
+ SHA512_CTX sha512_ctx; /* SHA-512 context. */
+#endif
+#endif
+#if DK3_HAVE_OPENSSL_MD5_H
+ MD5_CTX md5_ctx; /* MD5 context. */
+#endif
+#if DK3_HAVE_OPENSSL_RIPEMD_H
+ RIPEMD160_CTX ripemd160_ctx; /* RIPEMD-160 context. */
+#endif
+ char buffer[4096]; /* Buffer for input. */
+ size_t rb = 0; /* Number of bytes read. */
+ switch(cst) {
+ case DK3_MD_TYPE_MD5: {
+#if DK3_HAVE_OPENSSL_MD5_H
+ MD5_Init(&md5_ctx);
+ while((rb = dk3sf_fread_app(buffer,1,sizeof(buffer),fipo,app)) > 0) {
+ MD5_Update(&md5_ctx, buffer, rb);
+ }
+ MD5_Final((unsigned char *)db, &md5_ctx);
+ back = 1;
+#else
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 156, 157, dk3_checksum_type_names[0]);
+ }
+#endif
+ } break;
+ case DK3_MD_TYPE_SHA_1: {
+#if DK3_HAVE_OPENSSL_SHA_H
+ SHA1_Init(&sha_ctx);
+ while((rb = dk3sf_fread_app(buffer,1,sizeof(buffer),fipo,app)) > 0) {
+ SHA1_Update(&sha_ctx, buffer, rb);
+ }
+ SHA1_Final((unsigned char *)db, &sha_ctx);
+ back = 1;
+#else
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 156, 157, dk3_checksum_type_names[1]);
+ }
+#endif
+ } break;
+ case DK3_MD_TYPE_SHA_224: {
+#if DK3_HAVE_OPENSSL_SHA_H && DK3_HAVE_SHA224
+ SHA224_Init(&sha256_ctx);
+ while((rb = dk3sf_fread_app(buffer,1,sizeof(buffer),fipo,app)) > 0) {
+ SHA224_Update(&sha256_ctx, buffer, rb);
+ }
+ SHA224_Final((unsigned char *)db, &sha256_ctx);
+ back = 1;
+#else
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 156, 157, dk3_checksum_type_names[2]);
+ }
+#endif
+ } break;
+ case DK3_MD_TYPE_SHA_256: {
+#if DK3_HAVE_OPENSSL_SHA_H && DK3_HAVE_SHA256
+ SHA256_Init(&sha256_ctx);
+ while((rb = dk3sf_fread_app(buffer,1,sizeof(buffer),fipo,app)) > 0) {
+ SHA256_Update(&sha256_ctx, buffer, rb);
+ }
+ SHA256_Final((unsigned char *)db, &sha256_ctx);
+ back = 1;
+#else
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 156, 157, dk3_checksum_type_names[3]);
+ }
+#endif
+ } break;
+ case DK3_MD_TYPE_SHA_384: {
+#if DK3_HAVE_OPENSSL_SHA_H && DK3_HAVE_SHA384
+ SHA384_Init(&sha512_ctx);
+ while((rb = dk3sf_fread_app(buffer,1,sizeof(buffer),fipo,app)) > 0) {
+ SHA384_Update(&sha512_ctx, buffer, rb);
+ }
+ SHA384_Final((unsigned char *)db, &sha512_ctx);
+ back = 1;
+#else
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 156, 157, dk3_checksum_type_names[4]);
+ }
+#endif
+ } break;
+ case DK3_MD_TYPE_SHA_512: {
+#if DK3_HAVE_OPENSSL_SHA_H && DK3_HAVE_SHA512
+ SHA512_Init(&sha512_ctx);
+ while((rb = dk3sf_fread_app(buffer,1,sizeof(buffer),fipo,app)) > 0) {
+ SHA512_Update(&sha512_ctx, buffer, rb);
+ }
+ SHA512_Final((unsigned char *)db, &sha512_ctx);
+ back = 1;
+#else
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 156, 157, dk3_checksum_type_names[5]);
+ }
+#endif
+ } break;
+ case DK3_MD_TYPE_RIPEMD_160 : {
+#if DK3_HAVE_OPENSSL_RIPEMD_H
+ RIPEMD160_Init(&ripemd160_ctx);
+ while((rb = dk3sf_fread_app(buffer,1,sizeof(buffer),fipo,app)) > 0) {
+ RIPEMD160_Update(&ripemd160_ctx, buffer, rb);
+ }
+ RIPEMD160_Final((unsigned char *)db, &ripemd160_ctx);
+ back = 1;
+#else
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 156, 157, dk3_checksum_type_names[6]);
+ }
+#endif
+ } break;
+ default: {
+ if(app) {
+ /* ERROR: Unknown message digest type. */
+ dk3app_log_i1(app, DK3_LL_ERROR, 158);
+ }
+ } break;
+ }
+ return back;
+}
+
+
+
+size_t
+dk3checksum_length(int cst, int cse)
+{
+ size_t back;
+ back = dk3chksum_conv_length(dk3chksum_min_length(cst), cse);
+ return back;
+}
+
+
+
+int
+dk3checksum_build_app(
+ char *db, size_t sz, dkChar const *fn, int cst, int cse, dk3_app_t *app
+)
+{
+ int back = 0;
+ size_t minlgt = 0; /* Length of binary message digest. */
+ size_t convlgt = 0; /* Length of digest converted to text. */
+ size_t i = 0; /* Used to write zeroes. */
+ dk3_stat_t stb; /* Test for existance. */
+ char mybuffer[256]; /* ASCII text version of digest. */
+ FILE *fipo = NULL; /* Input file. */
+ if(db) { *db = '\0'; }
+ if((db) && (sz) && (fn)) {
+ if((cst > 0) && (cst <= DK3_MD_TYPE_MAX)) {
+ if((cse >= 0) && (cse <= DK3_DATA_ENCODING_MAX)) {
+ minlgt = dk3chksum_min_length(cst);
+ convlgt = dk3chksum_conv_length(minlgt, cse);
+ if(sz > convlgt) {
+ for(i = 0; i < convlgt; i++) { db[i] = '-'; } db[convlgt] = '\0';
+ if(dk3sf_stat_app(&stb, fn, app)) {
+ if(((stb.ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_REGULAR) {
+ fipo = dk3sf_fopen_app(fn, kw[0], app);
+ if(fipo) {
+ if(dk3checksum_binary(mybuffer,sizeof(mybuffer),fipo, cst,app))
+ {
+ switch(cse) {
+ case DK3_DATA_ENCODING_HEX: {
+ back = dk3enc_bin_to_hex_app(db,sz,mybuffer,minlgt,app);
+ } break;
+ case DK3_DATA_ENCODING_ASCII85: {
+ back = dk3enc_bin_to_a85_app(db,sz,mybuffer,minlgt,app);
+ } break;
+ case DK3_DATA_ENCODING_REVERSE_ASCII85: {
+ back = dk3enc_bin_to_ra85_app(db,sz,mybuffer,minlgt,app);
+ } break;
+ default: {
+ /* Illegal encoding type! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 158);
+ } break;
+ }
+ }
+ fclose(fipo);
+ }
+ } else {
+ if(app) {
+ /* ERROR: Checksumming for regular files only .*/
+ dk3app_log_i1(app, DK3_LL_ERROR, 159);
+ }
+ }
+ }
+ } else {
+ if(app) {
+ /* ERROR: Destination buffer too small */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ } else {
+ if(app) {
+ /* ERROR: Illegal encoding number. */
+ dk3app_log_i1(app, DK3_LL_ERROR, 158);
+ }
+ }
+ } else {
+ if(app) {
+ /* ERROR: Illegal digest type. */
+ dk3app_log_i1(app, DK3_LL_ERROR, 158);
+ }
+ }
+ }
+ return back;
+}
+
+
+dkChar const *
+dk3checksum_get_type_name(int tp)
+{
+ dkChar const *back = NULL;
+ if((tp > 0) && (tp <= DK3_MD_TYPE_MAX)) {
+ back = dk3_checksum_type_names[tp - 1];
+ }
+ return back;
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dk3chks.ctr b/support/dktools/dk3chks.ctr
new file mode 100644
index 0000000000..5d1c48c477
--- /dev/null
+++ b/support/dktools/dk3chks.ctr
@@ -0,0 +1,416 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% header
+
+#include "dk3conf.h"
+#include "dk3types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Get checksum type for a given name.
+ @param n Message digest name ("MD5", "SHA-1", "SHA-224",
+ "SHA-256", "SHA-384", "SHA-512", or "RIPEMD-160").
+ @param app Application structure for diagnostics, may be NULL.
+ @return Integer representation (see @ref mdtypes) on success,
+ -1 on error.
+*/
+int
+dk3checksum_get_type_app(dkChar const *n, dk3_app_t *app);
+
+/** Build checksum for a file.
+ @param db Destination buffer.
+ @param sz Size of destination buffer.
+ @param fn File name to process.
+ @param cst Checksum type (message digest type,
+ see @ref mdtypes).
+ @param cse Binary to text encoding for message digest
+ (see @ref dataencoding).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3checksum_build_app(
+ char *db, size_t sz, dkChar const *fn, int cst, int cse, dk3_app_t *app
+);
+
+/** Get string length produced for a message digest and encoding type.
+ @param cst Message digest type, see @ref mdtypes.
+ @param cse Binary to text encoding, see @ref dataencoding.
+ @return Number of characters produced.
+*/
+size_t
+dk3checksum_length(int cst, int cse);
+
+/** Get name for message digest type.
+ @param tp Digest type, see @ref mdtypes.
+ @return Name for digest type.
+*/
+dkChar const *
+dk3checksum_get_type_name(int tp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk3all.h"
+
+#if DK3_HAVE_OPENSSL_MD5_H
+#include <openssl/md5.h>
+#endif
+#if DK3_HAVE_OPENSSL_SHA_H
+#include <openssl/sha.h>
+#endif
+#if DK3_HAVE_OPENSSL_RIPEMD_H
+#include <openssl/ripemd.h>
+#endif
+
+
+$!trace-include
+
+
+
+/** Names of message digest algorithms.
+ Order here must match order of DK3_MD_TYPE_xxx in dk3const.h.
+*/
+static dkChar const * const dk3_checksum_type_names[] = {
+/* 0 */ dkT("MD5"),
+/* 1 */ dkT("SHA-1"),
+/* 2 */ dkT("SHA-224"),
+/* 3 */ dkT("SHA-256"),
+/* 4 */ dkT("SHA-384"),
+/* 5 */ dkT("SHA-512"),
+/* 6 */ dkT("RIPEMD-160"),
+NULL
+};
+
+
+
+/** String constants.
+*/
+static dkChar const * const kw[] = {
+#if DK3_ON_WINDOWS
+/* 0 */ dkT("rb"), /* File mode, read binary. */
+#else
+/* 0 */ dkT("r"), /* no difference on non-Windows. */
+#endif
+};
+
+
+
+int
+dk3checksum_get_type_app(dkChar const *n, dk3_app_t *app)
+{
+ int back = -1;
+ if(n) {
+ back = dk3str_array_index(dk3_checksum_type_names, n, 0);
+ if(back == -1) {
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 127, 128, n);
+ }
+ } else {
+ back++;
+ }
+ }
+ return back;
+}
+
+
+
+/** Convert length of binary message digest to length of encoded string.
+ @param l Number of binary bytes to encode.
+ @param cse Message digest encoding.
+ @return Number of text characters produced by encoding.
+*/
+static
+size_t
+dk3chksum_conv_length(size_t l, int cse)
+{
+ size_t back = 0;
+ $? "+ dk3chksum_conv_length %lu %d", (unsigned long)l, cse
+ switch(cse) {
+ case DK3_DATA_ENCODING_HEX: {
+ back = dk3enc_size_bin_to_hex(l);
+ } break;
+ default: {
+ back = dk3enc_size_bin_to_a85(l);
+ } break;
+ } $? "- dk3chksum_conv_length %lu", (unsigned long)back
+ return back;
+}
+
+
+
+/** Get length of binary message digest.
+ @param cst Message digest type.
+ @return Number of binary bytes produced.
+*/
+static
+size_t
+dk3chksum_min_length(int cst)
+{
+ size_t back = 0;
+ switch(cst) {
+ case DK3_MD_TYPE_MD5: back = 16; break;
+ case DK3_MD_TYPE_SHA_1: back = 20; break;
+ case DK3_MD_TYPE_SHA_224: back = 28; break;
+ case DK3_MD_TYPE_SHA_256: back = 32; break;
+ case DK3_MD_TYPE_SHA_384: back = 48; break;
+ case DK3_MD_TYPE_SHA_512: back = 64; break;
+ case DK3_MD_TYPE_RIPEMD_160: back = 20; break;
+ }
+ return back;
+}
+
+
+
+/** Build binary checksum from file.
+ @param db Destination buffer.
+ @param sz Size of \a db.
+ @param fipo File pointer for read access.
+ @param cst Checksum type.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3checksum_binary(char *db, size_t sz, FILE *fipo, int cst, dk3_app_t *app)
+{
+ int back = 0;
+#if DK3_HAVE_OPENSSL_SHA_H
+ SHA_CTX sha_ctx; /* SHA-1 context. */
+#if DK3_HAVE_SHA224 || DK3_HAVE_SHA256
+ SHA256_CTX sha256_ctx; /* SHA-256 context. */
+#endif
+#if DK3_HAVE_SHA384 || DK3_HAVE_SHA512
+ SHA512_CTX sha512_ctx; /* SHA-512 context. */
+#endif
+#endif
+#if DK3_HAVE_OPENSSL_MD5_H
+ MD5_CTX md5_ctx; /* MD5 context. */
+#endif
+#if DK3_HAVE_OPENSSL_RIPEMD_H
+ RIPEMD160_CTX ripemd160_ctx; /* RIPEMD-160 context. */
+#endif
+ char buffer[4096]; /* Buffer for input. */
+ size_t rb = 0; /* Number of bytes read. */
+ switch(cst) {
+ case DK3_MD_TYPE_MD5: {
+#if DK3_HAVE_OPENSSL_MD5_H
+ MD5_Init(&md5_ctx);
+ while((rb = dk3sf_fread_app(buffer,1,sizeof(buffer),fipo,app)) > 0) {
+ MD5_Update(&md5_ctx, buffer, rb);
+ }
+ MD5_Final((unsigned char *)db, &md5_ctx);
+ back = 1;
+#else
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 156, 157, dk3_checksum_type_names[0]);
+ }
+#endif
+ } break;
+ case DK3_MD_TYPE_SHA_1: {
+#if DK3_HAVE_OPENSSL_SHA_H
+ SHA1_Init(&sha_ctx);
+ while((rb = dk3sf_fread_app(buffer,1,sizeof(buffer),fipo,app)) > 0) {
+ SHA1_Update(&sha_ctx, buffer, rb);
+ }
+ SHA1_Final((unsigned char *)db, &sha_ctx);
+ back = 1;
+#else
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 156, 157, dk3_checksum_type_names[1]);
+ }
+#endif
+ } break;
+ case DK3_MD_TYPE_SHA_224: {
+#if DK3_HAVE_OPENSSL_SHA_H && DK3_HAVE_SHA224
+ SHA224_Init(&sha256_ctx);
+ while((rb = dk3sf_fread_app(buffer,1,sizeof(buffer),fipo,app)) > 0) {
+ SHA224_Update(&sha256_ctx, buffer, rb);
+ }
+ SHA224_Final((unsigned char *)db, &sha256_ctx);
+ back = 1;
+#else
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 156, 157, dk3_checksum_type_names[2]);
+ }
+#endif
+ } break;
+ case DK3_MD_TYPE_SHA_256: {
+#if DK3_HAVE_OPENSSL_SHA_H && DK3_HAVE_SHA256
+ SHA256_Init(&sha256_ctx);
+ while((rb = dk3sf_fread_app(buffer,1,sizeof(buffer),fipo,app)) > 0) {
+ SHA256_Update(&sha256_ctx, buffer, rb);
+ }
+ SHA256_Final((unsigned char *)db, &sha256_ctx);
+ back = 1;
+#else
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 156, 157, dk3_checksum_type_names[3]);
+ }
+#endif
+ } break;
+ case DK3_MD_TYPE_SHA_384: {
+#if DK3_HAVE_OPENSSL_SHA_H && DK3_HAVE_SHA384
+ SHA384_Init(&sha512_ctx);
+ while((rb = dk3sf_fread_app(buffer,1,sizeof(buffer),fipo,app)) > 0) {
+ SHA384_Update(&sha512_ctx, buffer, rb);
+ }
+ SHA384_Final((unsigned char *)db, &sha512_ctx);
+ back = 1;
+#else
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 156, 157, dk3_checksum_type_names[4]);
+ }
+#endif
+ } break;
+ case DK3_MD_TYPE_SHA_512: {
+#if DK3_HAVE_OPENSSL_SHA_H && DK3_HAVE_SHA512
+ SHA512_Init(&sha512_ctx);
+ while((rb = dk3sf_fread_app(buffer,1,sizeof(buffer),fipo,app)) > 0) {
+ SHA512_Update(&sha512_ctx, buffer, rb);
+ }
+ SHA512_Final((unsigned char *)db, &sha512_ctx);
+ back = 1;
+#else
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 156, 157, dk3_checksum_type_names[5]);
+ }
+#endif
+ } break;
+ case DK3_MD_TYPE_RIPEMD_160 : {
+#if DK3_HAVE_OPENSSL_RIPEMD_H
+ RIPEMD160_Init(&ripemd160_ctx);
+ while((rb = dk3sf_fread_app(buffer,1,sizeof(buffer),fipo,app)) > 0) {
+ RIPEMD160_Update(&ripemd160_ctx, buffer, rb);
+ }
+ RIPEMD160_Final((unsigned char *)db, &ripemd160_ctx);
+ back = 1;
+#else
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 156, 157, dk3_checksum_type_names[6]);
+ }
+#endif
+ } break;
+ default: {
+ if(app) {
+ /* ERROR: Unknown message digest type. */
+ dk3app_log_i1(app, DK3_LL_ERROR, 158);
+ }
+ } break;
+ }
+ return back;
+}
+
+
+
+size_t
+dk3checksum_length(int cst, int cse)
+{
+ size_t back;
+ back = dk3chksum_conv_length(dk3chksum_min_length(cst), cse);
+ return back;
+}
+
+
+
+int
+dk3checksum_build_app(
+ char *db, size_t sz, dkChar const *fn, int cst, int cse, dk3_app_t *app
+)
+{
+ int back = 0;
+ size_t minlgt = 0; /* Length of binary message digest. */
+ size_t convlgt = 0; /* Length of digest converted to text. */
+ size_t i = 0; /* Used to write zeroes. */
+ dk3_stat_t stb; /* Test for existance. */
+ char mybuffer[256]; /* ASCII text version of digest. */
+ FILE *fipo = NULL; /* Input file. */
+ if(db) { *db = '\0'; }
+ if((db) && (sz) && (fn)) {
+ if((cst > 0) && (cst <= DK3_MD_TYPE_MAX)) {
+ if((cse >= 0) && (cse <= DK3_DATA_ENCODING_MAX)) {
+ minlgt = dk3chksum_min_length(cst);
+ convlgt = dk3chksum_conv_length(minlgt, cse);
+ if(sz > convlgt) {
+ for(i = 0; i < convlgt; i++) { db[i] = '-'; } db[convlgt] = '\0';
+ if(dk3sf_stat_app(&stb, fn, app)) {
+ if(((stb.ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_REGULAR) {
+ fipo = dk3sf_fopen_app(fn, kw[0], app);
+ if(fipo) {
+ if(dk3checksum_binary(mybuffer,sizeof(mybuffer),fipo, cst,app))
+ {
+ switch(cse) {
+ case DK3_DATA_ENCODING_HEX: {
+ back = dk3enc_bin_to_hex_app(db,sz,mybuffer,minlgt,app);
+ } break;
+ case DK3_DATA_ENCODING_ASCII85: {
+ back = dk3enc_bin_to_a85_app(db,sz,mybuffer,minlgt,app);
+ } break;
+ case DK3_DATA_ENCODING_REVERSE_ASCII85: {
+ back = dk3enc_bin_to_ra85_app(db,sz,mybuffer,minlgt,app);
+ } break;
+ default: {
+ /* Illegal encoding type! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 158);
+ } break;
+ }
+ }
+ fclose(fipo);
+ }
+ } else {
+ if(app) {
+ /* ERROR: Checksumming for regular files only .*/
+ dk3app_log_i1(app, DK3_LL_ERROR, 159);
+ }
+ }
+ }
+ } else {
+ if(app) {
+ /* ERROR: Destination buffer too small */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ } else {
+ if(app) {
+ /* ERROR: Illegal encoding number. */
+ dk3app_log_i1(app, DK3_LL_ERROR, 158);
+ }
+ }
+ } else {
+ if(app) {
+ /* ERROR: Illegal digest type. */
+ dk3app_log_i1(app, DK3_LL_ERROR, 158);
+ }
+ }
+ }
+ return back;
+}
+
+
+dkChar const *
+dk3checksum_get_type_name(int tp)
+{
+ dkChar const *back = NULL;
+ if((tp > 0) && (tp <= DK3_MD_TYPE_MAX)) {
+ back = dk3_checksum_type_names[tp - 1];
+ }
+ return back;
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dk3chks.h b/support/dktools/dk3chks.h
new file mode 100644
index 0000000000..50cc0ab853
--- /dev/null
+++ b/support/dktools/dk3chks.h
@@ -0,0 +1,101 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3chks.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3chks.h Header file for the dk3chks module.
+*/
+
+#ifndef DK3CHKS_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3CHKS_H_INCLUDED 1
+
+
+#line 10 "dk3chks.ctr"
+
+#include "dk3conf.h"
+#include "dk3types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Get checksum type for a given name.
+ @param n Message digest name ("MD5", "SHA-1", "SHA-224",
+ "SHA-256", "SHA-384", "SHA-512", or "RIPEMD-160").
+ @param app Application structure for diagnostics, may be NULL.
+ @return Integer representation (see @ref mdtypes) on success,
+ -1 on error.
+*/
+int
+dk3checksum_get_type_app(dkChar const *n, dk3_app_t *app);
+
+/** Build checksum for a file.
+ @param db Destination buffer.
+ @param sz Size of destination buffer.
+ @param fn File name to process.
+ @param cst Checksum type (message digest type,
+ see @ref mdtypes).
+ @param cse Binary to text encoding for message digest
+ (see @ref dataencoding).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3checksum_build_app(
+ char *db, size_t sz, dkChar const *fn, int cst, int cse, dk3_app_t *app
+);
+
+/** Get string length produced for a message digest and encoding type.
+ @param cst Message digest type, see @ref mdtypes.
+ @param cse Binary to text encoding, see @ref dataencoding.
+ @return Number of characters produced.
+*/
+size_t
+dk3checksum_length(int cst, int cse);
+
+/** Get name for message digest type.
+ @param tp Digest type, see @ref mdtypes.
+ @return Name for digest type.
+*/
+dkChar const *
+dk3checksum_get_type_name(int tp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3conf.cross b/support/dktools/dk3conf.cross
new file mode 100644
index 0000000000..62727a718a
--- /dev/null
+++ b/support/dktools/dk3conf.cross
@@ -0,0 +1,2795 @@
+/** @file dk3conf.h Configuration for DK3 libraries.
+ This is the default file for use in cross compilation.
+ Features: Include files, functions, sizes,
+ and endianness.
+*/
+
+#ifndef DK3_CONF_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3_CONF_H_INCLUDED 1
+
+#include "config.h"
+
+#ifndef DK3_ON_WINDOWS
+#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
+/** On a Windows system. */
+#define DK3_ON_WINDOWS 1
+#else
+/** Not on a Windows system. */
+#define DK3_ON_WINDOWS 0
+#endif
+#endif
+/** ifndef DK3_ON_WINDOWS */
+
+
+#ifndef DK3_HAVE_ACOSH
+#if HAVE_ACOSH
+/** DK3 version of HAVE_ACOSH.
+*/
+#define DK3_HAVE_ACOSH 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_ACOSHL
+#if HAVE_ACOSHL
+/** DK3 version of HAVE_ACOSHL.
+*/
+#define DK3_HAVE_ACOSHL 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_ACOSL
+#if HAVE_ACOSL
+/** DK3 version of HAVE_ACOSL.
+*/
+#define DK3_HAVE_ACOSL 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_ALLOC_H
+#if HAVE_ALLOC_H
+/** DK3 version of HAVE_ALLOC_H.
+*/
+#define DK3_HAVE_ALLOC_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_ARPA_INET_H
+#if HAVE_ARPA_INET_H
+/** DK3 version of HAVE_ARPA_INET_H.
+*/
+#define DK3_HAVE_ARPA_INET_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_ASINH
+#if HAVE_ASINH
+/** DK3 version of HAVE_ASINH.
+*/
+#define DK3_HAVE_ASINH 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_ASINHL
+#if HAVE_ASINHL
+/** DK3 version of HAVE_ASINHL.
+*/
+#define DK3_HAVE_ASINHL 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_ASINL
+#if HAVE_ASINL
+/** DK3 version of HAVE_ASINL.
+*/
+#define DK3_HAVE_ASINL 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_ATAN2
+#if HAVE_ATAN2
+/** DK3 version of HAVE_ATAN2.
+*/
+#define DK3_HAVE_ATAN2 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_ATAN2L
+#if HAVE_ATAN2L
+/** DK3 version of HAVE_ATAN2L.
+*/
+#define DK3_HAVE_ATAN2L 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_ATANH
+#if HAVE_ATANH
+/** DK3 version of HAVE_ATANH.
+*/
+#define DK3_HAVE_ATANH 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_ATANHL
+#if HAVE_ATANHL
+/** DK3 version of HAVE_ATANHL.
+*/
+#define DK3_HAVE_ATANHL 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_ATANL
+#if HAVE_ATANL
+/** DK3 version of HAVE_ATANL.
+*/
+#define DK3_HAVE_ATANL 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_BACKSLASH
+#if HAVE_BACKSLASH
+/** DK3 version of HAVE_BACKSLASH.
+*/
+#define DK3_HAVE_BACKSLASH 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_BCMP
+#if HAVE_BCMP
+/** DK3 version of HAVE_BCMP.
+*/
+#define DK3_HAVE_BCMP 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_BCOPY
+#if HAVE_BCOPY
+/** DK3 version of HAVE_BCOPY.
+*/
+#define DK3_HAVE_BCOPY 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_BZERO
+#if HAVE_BZERO
+/** DK3 version of HAVE_BZERO.
+*/
+#define DK3_HAVE_BZERO 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_BZLIB_H
+#if HAVE_BZLIB_H
+/** DK3 version of HAVE_BZLIB_H.
+*/
+#define DK3_HAVE_BZLIB_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_CEIL
+#if HAVE_CEIL
+/** DK3 version of HAVE_CEIL.
+*/
+#define DK3_HAVE_CEIL 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_CEILL
+#if HAVE_CEILL
+/** DK3 version of HAVE_CEILL.
+*/
+#define DK3_HAVE_CEILL 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_CHDIR
+#if HAVE_CHDIR
+/** DK3 version of HAVE_CHDIR.
+*/
+#define DK3_HAVE_CHDIR 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_CHMOD
+#if HAVE_CHMOD
+/** DK3 version of HAVE_CHMOD.
+*/
+#define DK3_HAVE_CHMOD 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_CHOWN
+#if HAVE_CHOWN
+/** DK3 version of HAVE_CHOWN.
+*/
+#define DK3_HAVE_CHOWN 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_CLOSEDIR
+#if HAVE_CLOSEDIR
+/** DK3 version of HAVE_CLOSEDIR.
+*/
+#define DK3_HAVE_CLOSEDIR 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_CONIO_H
+#if HAVE_CONIO_H
+/** DK3 version of HAVE_CONIO_H.
+*/
+#define DK3_HAVE_CONIO_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_CONST
+#if HAVE_CONST
+/** DK3 version of HAVE_CONST.
+*/
+#define DK3_HAVE_CONST 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_COSHL
+#if HAVE_COSHL
+/** DK3 version of HAVE_COSHL.
+*/
+#define DK3_HAVE_COSHL 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_COSL
+#if HAVE_COSL
+/** DK3 version of HAVE_COSL.
+*/
+#define DK3_HAVE_COSL 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_CTYPE_H
+#if HAVE_CTYPE_H
+/** DK3 version of HAVE_CTYPE_H.
+*/
+#define DK3_HAVE_CTYPE_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_DB_CURSOR_C_GET
+#if HAVE_DB_CURSOR_C_GET
+/** DK3 version of HAVE_DB_CURSOR_C_GET.
+*/
+#define DK3_HAVE_DB_CURSOR_C_GET 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_DB_H
+#if HAVE_DB_H
+/** DK3 version of HAVE_DB_H.
+*/
+#define DK3_HAVE_DB_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_DEV_RANDOM
+#if HAVE_DEV_RANDOM
+/** DK3 version of HAVE_DEV_RANDOM.
+*/
+#define DK3_HAVE_DEV_RANDOM 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_DEV_URANDOM
+#if HAVE_DEV_URANDOM
+/** DK3 version of HAVE_DEV_URANDOM.
+*/
+#define DK3_HAVE_DEV_URANDOM 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_DIRECT_H
+#if HAVE_DIRECT_H
+/** DK3 version of HAVE_DIRECT_H.
+*/
+#define DK3_HAVE_DIRECT_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_DIRENT_H
+#if HAVE_DIRENT_H
+/** DK3 version of HAVE_DIRENT_H.
+*/
+#define DK3_HAVE_DIRENT_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_DIR_H
+#if HAVE_DIR_H
+/** DK3 version of HAVE_DIR_H.
+*/
+#define DK3_HAVE_DIR_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_DOS_H
+#if HAVE_DOS_H
+/** DK3 version of HAVE_DOS_H.
+*/
+#define DK3_HAVE_DOS_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_ENDGRENT
+#if HAVE_ENDGRENT
+/** DK3 version of HAVE_ENDGRENT.
+*/
+#define DK3_HAVE_ENDGRENT 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_ENDPWENT
+#if HAVE_ENDPWENT
+/** DK3 version of HAVE_ENDPWENT.
+*/
+#define DK3_HAVE_ENDPWENT 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_ERRNO_H
+#if HAVE_ERRNO_H
+/** DK3 version of HAVE_ERRNO_H.
+*/
+#define DK3_HAVE_ERRNO_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_ERR_H
+#if HAVE_ERR_H
+/** DK3 version of HAVE_ERR_H.
+*/
+#define DK3_HAVE_ERR_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_EXPL
+#if HAVE_EXPL
+/** DK3 version of HAVE_EXPL.
+*/
+#define DK3_HAVE_EXPL 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_FABS
+#if HAVE_FABS
+/** DK3 version of HAVE_FABS.
+*/
+#define DK3_HAVE_FABS 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_FABSL
+#if HAVE_FABSL
+/** DK3 version of HAVE_FABSL.
+*/
+#define DK3_HAVE_FABSL 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_FCLOSE
+#if HAVE_FCLOSE
+/** DK3 version of HAVE_FCLOSE.
+*/
+#define DK3_HAVE_FCLOSE 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_FCNTL_H
+#if HAVE_FCNTL_H
+/** DK3 version of HAVE_FCNTL_H.
+*/
+#define DK3_HAVE_FCNTL_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_FENV_H
+#if HAVE_FENV_H
+/** DK3 version of HAVE_FENV_H.
+*/
+#define DK3_HAVE_FENV_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_FEOF
+#if HAVE_FEOF
+/** DK3 version of HAVE_FEOF.
+*/
+#define DK3_HAVE_FEOF 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_FERROR
+#if HAVE_FERROR
+/** DK3 version of HAVE_FERROR.
+*/
+#define DK3_HAVE_FERROR 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_FETESTEXCEPT
+#if HAVE_FETESTEXCEPT
+/** DK3 version of HAVE_FETESTEXCEPT.
+*/
+#define DK3_HAVE_FETESTEXCEPT 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_FFLUSH
+#if HAVE_FFLUSH
+/** DK3 version of HAVE_FFLUSH.
+*/
+#define DK3_HAVE_FFLUSH 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_FLOAT_H
+#if HAVE_FLOAT_H
+/** DK3 version of HAVE_FLOAT_H.
+*/
+#define DK3_HAVE_FLOAT_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_FLOOR
+#if HAVE_FLOOR
+/** DK3 version of HAVE_FLOOR.
+*/
+#define DK3_HAVE_FLOOR 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_FLOORL
+#if HAVE_FLOORL
+/** DK3 version of HAVE_FLOORL.
+*/
+#define DK3_HAVE_FLOORL 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_FNCASEINS
+#if HAVE_FNCASEINS
+/** DK3 version of HAVE_FNCASEINS.
+*/
+#define DK3_HAVE_FNCASEINS 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_FOPEN
+#if HAVE_FOPEN
+/** DK3 version of HAVE_FOPEN.
+*/
+#define DK3_HAVE_FOPEN 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_FOPEN64
+#if HAVE_FOPEN64
+/** DK3 version of HAVE_FOPEN64.
+*/
+#define DK3_HAVE_FOPEN64 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_FOPEN_S
+#if HAVE_FOPEN_S
+/** DK3 version of HAVE_FOPEN_S.
+*/
+#define DK3_HAVE_FOPEN_S 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_FORK
+#if HAVE_FORK
+/** DK3 version of HAVE_FORK.
+*/
+#define DK3_HAVE_FORK 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_WORKING_FORK
+#if HAVE_WORKING_FORK
+/** DK3 version of HAVE_WORKING_FORK.
+*/
+#define DK3_HAVE_WORKING_FORK 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_FPCLASSIFY
+#if HAVE_FPCLASSIFY
+/** DK3 version of HAVE_FPCLASSIFY.
+*/
+#define DK3_HAVE_FPCLASSIFY 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_FREAD
+#if HAVE_FREAD
+/** DK3 version of HAVE_FREAD.
+*/
+#define DK3_HAVE_FREAD 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_FREE
+#if HAVE_FREE
+/** DK3 version of HAVE_FREE.
+*/
+#define DK3_HAVE_FREE 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_FWRITE
+#if HAVE_FWRITE
+/** DK3 version of HAVE_FWRITE.
+*/
+#define DK3_HAVE_FWRITE 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_GDBM_H
+#if HAVE_GDBM_H
+/** DK3 version of HAVE_GDBM_H.
+*/
+#define DK3_HAVE_GDBM_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_GETADDRINFO
+#if HAVE_GETADDRINFO
+/** DK3 version of HAVE_GETADDRINFO.
+*/
+#define DK3_HAVE_GETADDRINFO 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_GETCWD
+#if HAVE_GETCWD
+/** DK3 version of HAVE_GETCWD.
+*/
+#define DK3_HAVE_GETCWD 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_GETENV
+#if HAVE_GETENV
+/** DK3 version of HAVE_GETENV.
+*/
+#define DK3_HAVE_GETENV 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_GETEUID
+#if HAVE_GETEUID
+/** DK3 version of HAVE_GETEUID.
+*/
+#define DK3_HAVE_GETEUID 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_GETGRENT
+#if HAVE_GETGRENT
+/** DK3 version of HAVE_GETGRENT.
+*/
+#define DK3_HAVE_GETGRENT 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_GETGRGID
+#if HAVE_GETGRGID
+/** DK3 version of HAVE_GETGRGID.
+*/
+#define DK3_HAVE_GETGRGID 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_GETGRNAM
+#if HAVE_GETGRNAM
+/** DK3 version of HAVE_GETGRNAM.
+*/
+#define DK3_HAVE_GETGRNAM 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_GETHOSTBYNAME
+#if HAVE_GETHOSTBYNAME
+/** DK3 version of HAVE_GETHOSTBYNAME.
+*/
+#define DK3_HAVE_GETHOSTBYNAME 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_GETHOSTNAME
+#if HAVE_GETHOSTNAME
+/** DK3 version of HAVE_GETHOSTNAME.
+*/
+#define DK3_HAVE_GETHOSTNAME 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_GETPEERNAME
+#if HAVE_GETPEERNAME
+/** DK3 version of HAVE_GETPEERNAME.
+*/
+#define DK3_HAVE_GETPEERNAME 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_GETPID
+#if HAVE_GETPID
+/** DK3 version of HAVE_GETPID.
+*/
+#define DK3_HAVE_GETPID 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_GETPWENT
+#if HAVE_GETPWENT
+/** DK3 version of HAVE_GETPWENT.
+*/
+#define DK3_HAVE_GETPWENT 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_GETPWNAM
+#if HAVE_GETPWNAM
+/** DK3 version of HAVE_GETPWNAM.
+*/
+#define DK3_HAVE_GETPWNAM 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_GETPWUID
+#if HAVE_GETPWUID
+/** DK3 version of HAVE_GETPWUID.
+*/
+#define DK3_HAVE_GETPWUID 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_GETRLIMIT
+#if HAVE_GETRLIMIT
+/** DK3 version of HAVE_GETRLIMIT.
+*/
+#define DK3_HAVE_GETRLIMIT 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_GETSOCKNAME
+#if HAVE_GETSOCKNAME
+/** DK3 version of HAVE_GETSOCKNAME.
+*/
+#define DK3_HAVE_GETSOCKNAME 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_GETUID
+#if HAVE_GETUID
+/** DK3 version of HAVE_GETUID.
+*/
+#define DK3_HAVE_GETUID 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_GRP_H
+#if HAVE_GRP_H
+/** DK3 version of HAVE_GRP_H.
+*/
+#define DK3_HAVE_GRP_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_HTONL
+#if HAVE_HTONL
+/** DK3 version of HAVE_HTONL.
+*/
+#define DK3_HAVE_HTONL 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_IEEE_754_DOUBLE
+#if HAVE_IEEE_754_DOUBLE
+/** DK3 version of HAVE_IEEE_754_DOUBLE.
+*/
+#define DK3_HAVE_IEEE_754_DOUBLE 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_IN6_ADDR
+#if HAVE_IN6_ADDR
+/** DK3 version of HAVE_IN6_ADDR.
+*/
+#define DK3_HAVE_IN6_ADDR 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_INET_ADDR
+#if HAVE_INET_ADDR
+/** DK3 version of HAVE_INET_ADDR.
+*/
+#define DK3_HAVE_INET_ADDR 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_INET_ATON
+#if HAVE_INET_ATON
+/** DK3 version of HAVE_INET_ATON.
+*/
+#define DK3_HAVE_INET_ATON 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_INET_PTON
+#if HAVE_INET_PTON
+/** DK3 version of HAVE_INET_PTON.
+*/
+#define DK3_HAVE_INET_PTON 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_INITSTATE
+#if HAVE_INITSTATE
+/** DK3 version of HAVE_INITSTATE.
+*/
+#define DK3_HAVE_INITSTATE 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_INODES
+#if HAVE_INODES
+/** DK3 version of HAVE_INODES.
+*/
+#define DK3_HAVE_INODES 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_INTMAX_T
+#if HAVE_INTMAX_T
+/** DK3 version of HAVE_INTMAX_T.
+*/
+#define DK3_HAVE_INTMAX_T 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_INTTYPES_H
+#if HAVE_INTTYPES_H
+/** DK3 version of HAVE_INTTYPES_H.
+*/
+#define DK3_HAVE_INTTYPES_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_IN_ADDR
+#if HAVE_IN_ADDR
+/** DK3 version of HAVE_IN_ADDR.
+*/
+#define DK3_HAVE_IN_ADDR 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_IO_H
+#if HAVE_IO_H
+/** DK3 version of HAVE_IO_H.
+*/
+#define DK3_HAVE_IO_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_ISATTY
+#if HAVE_ISATTY
+/** DK3 version of HAVE_ISATTY.
+*/
+#define DK3_HAVE_ISATTY 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_ISFINITE
+#if HAVE_ISFINITE
+/** DK3 version of HAVE_ISFINITE.
+*/
+#define DK3_HAVE_ISFINITE 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_ISNORMAL
+#if HAVE_ISNORMAL
+/** DK3 version of HAVE_ISNORMAL.
+*/
+#define DK3_HAVE_ISNORMAL 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_JPEGLIB_H
+#if HAVE_JPEGLIB_H
+/** DK3 version of HAVE_JPEGLIB_H.
+*/
+#define DK3_HAVE_JPEGLIB_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_LABS
+#if HAVE_LABS
+/** DK3 version of HAVE_LABS.
+*/
+#define DK3_HAVE_LABS 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_LARGEFILE64_SOURCE
+#if HAVE_LARGEFILE64_SOURCE
+/** DK3 version of HAVE_LARGEFILE64_SOURCE.
+*/
+#define DK3_HAVE_LARGEFILE64_SOURCE 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_LIBNETSNMP
+#if HAVE_LIBNETSNMP
+/** DK3 version of HAVE_LIBNETSNMP.
+*/
+#define DK3_HAVE_LIBNETSNMP 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_LIMITS_H
+#if HAVE_LIMITS_H
+/** DK3 version of HAVE_LIMITS_H.
+*/
+#define DK3_HAVE_LIMITS_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_LOCALE_H
+#if HAVE_LOCALE_H
+/** DK3 version of HAVE_LOCALE_H.
+*/
+#define DK3_HAVE_LOCALE_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_LOCALTIME
+#if HAVE_LOCALTIME
+/** DK3 version of HAVE_LOCALTIME.
+*/
+#define DK3_HAVE_LOCALTIME 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_LOCALTIME
+#if HAVE_LOCALTIME
+/** DK3 version of HAVE_LOCALTIME.
+*/
+#define DK3_HAVE_LOCALTIME 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_LOCALTIME_R
+#if HAVE_LOCALTIME_R
+/** DK3 version of HAVE_LOCALTIME_R.
+*/
+#define DK3_HAVE_LOCALTIME_R 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_LOCALTIME_S
+#if HAVE_LOCALTIME_S
+/** DK3 version of HAVE_LOCALTIME_S.
+*/
+#define DK3_HAVE_LOCALTIME_S 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_LOGL
+#if HAVE_LOGL
+/** DK3 version of HAVE_LOGL.
+*/
+#define DK3_HAVE_LOGL 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_LONG_DOUBLE
+#if HAVE_LONG_DOUBLE
+/** DK3 version of HAVE_LONG_DOUBLE.
+*/
+#define DK3_HAVE_LONG_DOUBLE 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_LONG_LONG
+#if HAVE_LONG_LONG
+/** DK3 version of HAVE_LONG_LONG.
+*/
+#define DK3_HAVE_LONG_LONG 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_LPRNG_H
+#if HAVE_LPRNG_H
+/** DK3 version of HAVE_LPRNG_H.
+*/
+#define DK3_HAVE_LPRNG_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_LRAND48
+#if HAVE_LRAND48
+/** DK3 version of HAVE_LRAND48.
+*/
+#define DK3_HAVE_LRAND48 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_LSTAT
+#if HAVE_LSTAT
+/** DK3 version of HAVE_LSTAT.
+*/
+#define DK3_HAVE_LSTAT 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_LSTAT32
+#if HAVE_LSTAT32
+/** DK3 version of HAVE_LSTAT32.
+*/
+#define DK3_HAVE_LSTAT32 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_LSTAT64
+#if HAVE_LSTAT64
+/** DK3 version of HAVE_LSTAT64.
+*/
+#define DK3_HAVE_LSTAT64 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_MALLOC
+#if HAVE_MALLOC
+/** DK3 version of HAVE_MALLOC.
+*/
+#define DK3_HAVE_MALLOC 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_MALLOC_H
+#if HAVE_MALLOC_H
+/** DK3 version of HAVE_MALLOC_H.
+*/
+#define DK3_HAVE_MALLOC_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_MATH_H
+#if HAVE_MATH_H
+/** DK3 version of HAVE_MATH_H.
+*/
+#define DK3_HAVE_MATH_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_MEMCMP
+#if HAVE_MEMCMP
+/** DK3 version of HAVE_MEMCMP.
+*/
+#define DK3_HAVE_MEMCMP 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_MEMCPY
+#if HAVE_MEMCPY
+/** DK3 version of HAVE_MEMCPY.
+*/
+#define DK3_HAVE_MEMCPY 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_MEMSET
+#if HAVE_MEMSET
+/** DK3 version of HAVE_MEMSET.
+*/
+#define DK3_HAVE_MEMSET 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_MKDIR
+#if HAVE_MKDIR
+/** DK3 version of HAVE_MKDIR.
+*/
+#define DK3_HAVE_MKDIR 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_MKDIR2
+#if HAVE_MKDIR2
+/** DK3 version of HAVE_MKDIR2.
+*/
+#define DK3_HAVE_MKDIR2 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_MPCTL
+#if HAVE_MPCTL
+/** DK3 version of HAVE_MPCTL.
+*/
+#define DK3_HAVE_MPCTL 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_MYSQL_LIBRARY_END
+#if HAVE_MYSQL_LIBRARY_END
+/** DK3 version of HAVE_MYSQL_LIBRARY_END.
+*/
+#define DK3_HAVE_MYSQL_LIBRARY_END 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_MYSQL_LIBRARY_INIT
+#if HAVE_MYSQL_LIBRARY_INIT
+/** DK3 version of HAVE_MYSQL_LIBRARY_INIT.
+*/
+#define DK3_HAVE_MYSQL_LIBRARY_INIT 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_MYSQL_MYSQL_H
+#if HAVE_MYSQL_MYSQL_H
+/** DK3 version of HAVE_MYSQL_MYSQL_H.
+*/
+#define DK3_HAVE_MYSQL_MYSQL_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_MYSQL_SET_CHARACTER_SET
+#if HAVE_MYSQL_SET_CHARACTER_SET
+/** DK3 version of HAVE_MYSQL_SET_CHARACTER_SET.
+*/
+#define DK3_HAVE_MYSQL_SET_CHARACTER_SET 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_NDBM_H
+#if HAVE_NDBM_H
+/** DK3 version of HAVE_NDBM_H.
+*/
+#define DK3_HAVE_NDBM_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_NETDB_H
+#if HAVE_NETDB_H
+/** DK3 version of HAVE_NETDB_H.
+*/
+#define DK3_HAVE_NETDB_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_NETINET_IN_H
+#if HAVE_NETINET_IN_H
+/** DK3 version of HAVE_NETINET_IN_H.
+*/
+#define DK3_HAVE_NETINET_IN_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_NETSNMP_ENABLE_FILELOG
+#if HAVE_NETSNMP_ENABLE_FILELOG
+/** DK3 version of HAVE_NETSNMP_ENABLE_FILELOG.
+*/
+#define DK3_HAVE_NETSNMP_ENABLE_FILELOG 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_NRAND48
+#if HAVE_NRAND48
+/** DK3 version of HAVE_NRAND48.
+*/
+#define DK3_HAVE_NRAND48 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_OPENDIR
+#if HAVE_OPENDIR
+/** DK3 version of HAVE_OPENDIR.
+*/
+#define DK3_HAVE_OPENDIR 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_OPENSSL_MD5_H
+#if HAVE_OPENSSL_MD5_H
+/** DK3 version of HAVE_OPENSSL_MD5_H.
+*/
+#define DK3_HAVE_OPENSSL_MD5_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_OPENSSL_RAND_H
+#if HAVE_OPENSSL_RAND_H
+/** DK3 version of HAVE_OPENSSL_RAND_H.
+*/
+#define DK3_HAVE_OPENSSL_RAND_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_OPENSSL_RIPEMD_H
+#if HAVE_OPENSSL_RIPEMD_H
+/** DK3 version of HAVE_OPENSSL_RIPEMD_H.
+*/
+#define DK3_HAVE_OPENSSL_RIPEMD_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_OPENSSL_SHA_H
+#if HAVE_OPENSSL_SHA_H
+/** DK3 version of HAVE_OPENSSL_SHA_H.
+*/
+#define DK3_HAVE_OPENSSL_SHA_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_PNG_GET_PIXELS_PER_INCH
+#if HAVE_PNG_GET_PIXELS_PER_INCH
+/** DK3 version of HAVE_PNG_GET_PIXELS_PER_INCH.
+*/
+#define DK3_HAVE_PNG_GET_PIXELS_PER_INCH 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_PNG_H
+#if HAVE_PNG_H
+/** DK3 version of HAVE_PNG_H.
+*/
+#define DK3_HAVE_PNG_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_POPEN
+#if HAVE_POPEN
+/** DK3 version of HAVE_POPEN.
+*/
+#define DK3_HAVE_POPEN 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_PROCESS_H
+#if HAVE_PROCESS_H
+/** DK3 version of HAVE_PROCESS_H.
+*/
+#define DK3_HAVE_PROCESS_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_PTHREAD_H
+#if HAVE_PTHREAD_H
+/** DK3 version of HAVE_PTHREAD_H.
+*/
+#define DK3_HAVE_PTHREAD_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_PWD_H
+#if HAVE_PWD_H
+/** DK3 version of HAVE_PWD_H.
+*/
+#define DK3_HAVE_PWD_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_RAND
+#if HAVE_RAND
+/** DK3 version of HAVE_RAND.
+*/
+#define DK3_HAVE_RAND 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_RANDOM
+#if HAVE_RANDOM
+/** DK3 version of HAVE_RANDOM.
+*/
+#define DK3_HAVE_RANDOM 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_READ
+#if HAVE_READ
+/** DK3 version of HAVE_READ.
+*/
+#define DK3_HAVE_READ 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_READDIR
+#if HAVE_READDIR
+/** DK3 version of HAVE_READDIR.
+*/
+#define DK3_HAVE_READDIR 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_RFC_2249
+#if HAVE_RFC_2249
+/** DK3 version of HAVE_RFC_2249.
+*/
+#define DK3_HAVE_RFC_2249 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_RINT
+#if HAVE_RINT
+/** DK3 version of HAVE_RINT.
+*/
+#define DK3_HAVE_RINT 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_RINTL
+#if HAVE_RINTL
+/** DK3 version of HAVE_RINTL.
+*/
+#define DK3_HAVE_RINTL 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_RMDIR
+#if HAVE_RMDIR
+/** DK3 version of HAVE_RMDIR.
+*/
+#define DK3_HAVE_RMDIR 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SEED48
+#if HAVE_SEED48
+/** DK3 version of HAVE_SEED48.
+*/
+#define DK3_HAVE_SEED48 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SELECT
+#if HAVE_SELECT
+/** DK3 version of HAVE_SELECT.
+*/
+#define DK3_HAVE_SELECT 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SETGID
+#if HAVE_SETGID
+/** DK3 version of HAVE_SETGID.
+*/
+#define DK3_HAVE_SETGID 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SETGRENT
+#if HAVE_SETGRENT
+/** DK3 version of HAVE_SETGRENT.
+*/
+#define DK3_HAVE_SETGRENT 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SETJMP_H
+#if HAVE_SETJMP_H
+/** DK3 version of HAVE_SETJMP_H.
+*/
+#define DK3_HAVE_SETJMP_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SETLOCALE
+#if HAVE_SETLOCALE
+/** DK3 version of HAVE_SETLOCALE.
+*/
+#define DK3_HAVE_SETLOCALE 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SETPGRP
+#if HAVE_SETPGRP
+/** DK3 version of HAVE_SETPGRP.
+*/
+#define DK3_HAVE_SETPGRP 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SETPWENT
+#if HAVE_SETPWENT
+/** DK3 version of HAVE_SETPWENT.
+*/
+#define DK3_HAVE_SETPWENT 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SETSID
+#if HAVE_SETSID
+/** DK3 version of HAVE_SETSID.
+*/
+#define DK3_HAVE_SETSID 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SETSOCKOPT
+#if HAVE_SETSOCKOPT
+/** DK3 version of HAVE_SETSOCKOPT.
+*/
+#define DK3_HAVE_SETSOCKOPT 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SETSTATE
+#if HAVE_SETSTATE
+/** DK3 version of HAVE_SETSTATE.
+*/
+#define DK3_HAVE_SETSTATE 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SETUID
+#if HAVE_SETUID
+/** DK3 version of HAVE_SETUID.
+*/
+#define DK3_HAVE_SETUID 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SHA224
+#if HAVE_SHA224
+/** DK3 version of HAVE_SHA224.
+*/
+#define DK3_HAVE_SHA224 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SHA256
+#if HAVE_SHA256
+/** DK3 version of HAVE_SHA256.
+*/
+#define DK3_HAVE_SHA256 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SHA384
+#if HAVE_SHA384
+/** DK3 version of HAVE_SHA384.
+*/
+#define DK3_HAVE_SHA384 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SHA512
+#if HAVE_SHA512
+/** DK3 version of HAVE_SHA512.
+*/
+#define DK3_HAVE_SHA512 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SHADOW_H
+#if HAVE_SHADOW_H
+/** DK3 version of HAVE_SHADOW_H.
+*/
+#define DK3_HAVE_SHADOW_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SIGACTION
+#if HAVE_SIGACTION
+/** DK3 version of HAVE_SIGACTION.
+*/
+#define DK3_HAVE_SIGACTION 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SIGNAL
+#if HAVE_SIGNAL
+/** DK3 version of HAVE_SIGNAL.
+*/
+#define DK3_HAVE_SIGNAL 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SIGNAL_H
+#if HAVE_SIGNAL_H
+/** DK3 version of HAVE_SIGNAL_H.
+*/
+#define DK3_HAVE_SIGNAL_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SIGSET
+#if HAVE_SIGSET
+/** DK3 version of HAVE_SIGSET.
+*/
+#define DK3_HAVE_SIGSET 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SIG_ATOMIC_T
+#if HAVE_SIG_ATOMIC_T
+/** DK3 version of HAVE_SIG_ATOMIC_T.
+*/
+#define DK3_HAVE_SIG_ATOMIC_T 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SINHL
+#if HAVE_SINHL
+/** DK3 version of HAVE_SINHL.
+*/
+#define DK3_HAVE_SINHL 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SINL
+#if HAVE_SINL
+/** DK3 version of HAVE_SINL.
+*/
+#define DK3_HAVE_SINL 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SNPRINTF
+#if HAVE_SNPRINTF
+/** DK3 version of HAVE_SNPRINTF.
+*/
+#define DK3_HAVE_SNPRINTF 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SNWPRINTF
+#if HAVE_SNWPRINTF
+/** DK3 version of HAVE_SNWPRINTF.
+*/
+#define DK3_HAVE_SNWPRINTF 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SOCKET
+#if HAVE_SOCKET
+/** DK3 version of HAVE_SOCKET.
+*/
+#define DK3_HAVE_SOCKET 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SOCKLEN_T
+#if HAVE_SOCKLEN_T
+/** DK3 version of HAVE_SOCKLEN_T.
+*/
+#define DK3_HAVE_SOCKLEN_T 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SPRINTF_S
+#if HAVE_SPRINTF_S
+/** DK3 version of HAVE_SPRINTF_S.
+*/
+#define DK3_HAVE_SPRINTF_S 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SQRTL
+#if HAVE_SQRTL
+/** DK3 version of HAVE_SQRTL.
+*/
+#define DK3_HAVE_SQRTL 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SRAND
+#if HAVE_SRAND
+/** DK3 version of HAVE_SRAND.
+*/
+#define DK3_HAVE_SRAND 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SSCANF_S
+#if HAVE_SSCANF_S
+/** DK3 version of HAVE_SSCANF_S.
+*/
+#define DK3_HAVE_SSCANF_S 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SSIZE_T
+#if HAVE_SSIZE_T
+/** DK3 version of HAVE_SSIZE_T.
+*/
+#define DK3_HAVE_SSIZE_T 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STAT
+#if HAVE_STAT
+/** DK3 version of HAVE_STAT.
+*/
+#define DK3_HAVE_STAT 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STAT32
+#if HAVE_STAT32
+/** DK3 version of HAVE_STAT32.
+*/
+#define DK3_HAVE_STAT32 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STAT64
+#if HAVE_STAT64
+/** DK3 version of HAVE_STAT64.
+*/
+#define DK3_HAVE_STAT64 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STDARG_H
+#if HAVE_STDARG_H
+/** DK3 version of HAVE_STDARG_H.
+*/
+#define DK3_HAVE_STDARG_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STDDEF_H
+#if HAVE_STDDEF_H
+/** DK3 version of HAVE_STDDEF_H.
+*/
+#define DK3_HAVE_STDDEF_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STDINT_H
+#if HAVE_STDINT_H
+/** DK3 version of HAVE_STDINT_H.
+*/
+#define DK3_HAVE_STDINT_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STDIO_H
+#if HAVE_STDIO_H
+/** DK3 version of HAVE_STDIO_H.
+*/
+#define DK3_HAVE_STDIO_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STDLIB_H
+#if HAVE_STDLIB_H
+/** DK3 version of HAVE_STDLIB_H.
+*/
+#define DK3_HAVE_STDLIB_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRCASECMP
+#if HAVE_STRCASECMP
+/** DK3 version of HAVE_STRCASECMP.
+*/
+#define DK3_HAVE_STRCASECMP 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRCAT
+#if HAVE_STRCAT
+/** DK3 version of HAVE_STRCAT.
+*/
+#define DK3_HAVE_STRCAT 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRCAT_S
+#if HAVE_STRCAT_S
+/** DK3 version of HAVE_STRCAT_S.
+*/
+#define DK3_HAVE_STRCAT_S 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRCHR
+#if HAVE_STRCHR
+/** DK3 version of HAVE_STRCHR.
+*/
+#define DK3_HAVE_STRCHR 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRCMP
+#if HAVE_STRCMP
+/** DK3 version of HAVE_STRCMP.
+*/
+#define DK3_HAVE_STRCMP 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRCPY
+#if HAVE_STRCPY
+/** DK3 version of HAVE_STRCPY.
+*/
+#define DK3_HAVE_STRCPY 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRCPY_S
+#if HAVE_STRCPY_S
+/** DK3 version of HAVE_STRCPY_S.
+*/
+#define DK3_HAVE_STRCPY_S 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRDUP
+#if HAVE_STRDUP
+/** DK3 version of HAVE_STRDUP.
+*/
+#define DK3_HAVE_STRDUP 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRERROR
+#if HAVE_STRERROR
+/** DK3 version of HAVE_STRERROR.
+*/
+#define DK3_HAVE_STRERROR 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRICMP
+#if HAVE_STRICMP
+/** DK3 version of HAVE_STRICMP.
+*/
+#define DK3_HAVE_STRICMP 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRINGS_H
+#if HAVE_STRINGS_H
+/** DK3 version of HAVE_STRINGS_H.
+*/
+#define DK3_HAVE_STRINGS_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRING_H
+#if HAVE_STRING_H
+/** DK3 version of HAVE_STRING_H.
+*/
+#define DK3_HAVE_STRING_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRLEN
+#if HAVE_STRLEN
+/** DK3 version of HAVE_STRLEN.
+*/
+#define DK3_HAVE_STRLEN 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRNCMP
+#if HAVE_STRNCMP
+/** DK3 version of HAVE_STRNCMP.
+*/
+#define DK3_HAVE_STRNCMP 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRNCPY
+#if HAVE_STRNCPY
+/** DK3 version of HAVE_STRNCPY.
+*/
+#define DK3_HAVE_STRNCPY 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRNCPY_S
+#if HAVE_STRNCPY_S
+/** DK3 version of HAVE_STRNCPY_S.
+*/
+#define DK3_HAVE_STRNCPY_S 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STROPTS_H
+#if HAVE_STROPTS_H
+/** DK3 version of HAVE_STROPTS_H.
+*/
+#define DK3_HAVE_STROPTS_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRRCHR
+#if HAVE_STRRCHR
+/** DK3 version of HAVE_STRRCHR.
+*/
+#define DK3_HAVE_STRRCHR 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRTOD
+#if HAVE_STRTOD
+/** DK3 version of HAVE_STRTOD.
+*/
+#define DK3_HAVE_STRTOD 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRTOIMAX
+#if HAVE_STRTOIMAX
+/** DK3 version of HAVE_STRTOIMAX.
+*/
+#define DK3_HAVE_STRTOIMAX 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRTOL
+#if HAVE_STRTOL
+/** DK3 version of HAVE_STRTOL.
+*/
+#define DK3_HAVE_STRTOL 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRTOLL
+#if HAVE_STRTOLL
+/** DK3 version of HAVE_STRTOLL.
+*/
+#define DK3_HAVE_STRTOLL 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRTOUL
+#if HAVE_STRTOUL
+/** DK3 version of HAVE_STRTOUL.
+*/
+#define DK3_HAVE_STRTOUL 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRTOULL
+#if HAVE_STRTOULL
+/** DK3 version of HAVE_STRTOULL.
+*/
+#define DK3_HAVE_STRTOULL 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRTOUMAX
+#if HAVE_STRTOUMAX
+/** DK3 version of HAVE_STRTOUMAX.
+*/
+#define DK3_HAVE_STRTOUMAX 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRUCT_ADDRINFO
+#if HAVE_STRUCT_ADDRINFO
+/** DK3 version of HAVE_STRUCT_ADDRINFO.
+*/
+#define DK3_HAVE_STRUCT_ADDRINFO 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRUCT_SOCKADDR_IN
+#if HAVE_STRUCT_SOCKADDR_IN
+/** DK3 version of HAVE_STRUCT_SOCKADDR_IN.
+*/
+#define DK3_HAVE_STRUCT_SOCKADDR_IN 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRUCT_SOCKADDR_IN6
+#if HAVE_STRUCT_SOCKADDR_IN6
+/** DK3 version of HAVE_STRUCT_SOCKADDR_IN6.
+*/
+#define DK3_HAVE_STRUCT_SOCKADDR_IN6 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRUCT_SOCKADDR_STORAGE
+#if HAVE_STRUCT_SOCKADDR_STORAGE
+/** DK3 version of HAVE_STRUCT_SOCKADDR_STORAGE.
+*/
+#define DK3_HAVE_STRUCT_SOCKADDR_STORAGE 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRUCT_SOCKADDR_UN
+#if HAVE_STRUCT_SOCKADDR_UN
+/** DK3 version of HAVE_STRUCT_SOCKADDR_UN.
+*/
+#define DK3_HAVE_STRUCT_SOCKADDR_UN 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SWSCANF_S
+#if HAVE_SWSCANF_S
+/** DK3 version of HAVE_SWSCANF_S.
+*/
+#define DK3_HAVE_SWSCANF_S 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SYSCONF
+#if HAVE_SYSCONF
+/** DK3 version of HAVE_SYSCONF.
+*/
+#define DK3_HAVE_SYSCONF 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SYSCTL
+#if HAVE_SYSCTL
+/** DK3 version of HAVE_SYSCTL.
+*/
+#define DK3_HAVE_SYSCTL 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SYSLOG
+#if HAVE_SYSLOG
+/** DK3 version of HAVE_SYSLOG.
+*/
+#define DK3_HAVE_SYSLOG 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SYSLOG_H
+#if HAVE_SYSLOG_H
+/** DK3 version of HAVE_SYSLOG_H.
+*/
+#define DK3_HAVE_SYSLOG_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SYSRES_H
+#if HAVE_SYSRES_H
+/** DK3 version of HAVE_SYSRES_H.
+*/
+#define DK3_HAVE_SYSRES_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SYS_FILE_H
+#if HAVE_SYS_FILE_H
+/** DK3 version of HAVE_SYS_FILE_H.
+*/
+#define DK3_HAVE_SYS_FILE_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SYS_PARAM_H
+#if HAVE_SYS_PARAM_H
+/** DK3 version of HAVE_SYS_PARAM_H.
+*/
+#define DK3_HAVE_SYS_PARAM_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SYS_RESOURCE_H
+#if HAVE_SYS_RESOURCE_H
+/** DK3 version of HAVE_SYS_RESOURCE_H.
+*/
+#define DK3_HAVE_SYS_RESOURCE_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SYS_SOCKET_H
+#if HAVE_SYS_SOCKET_H
+/** DK3 version of HAVE_SYS_SOCKET_H.
+*/
+#define DK3_HAVE_SYS_SOCKET_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SYS_STATVFS_H
+#if HAVE_SYS_STATVFS_H
+/** DK3 version of HAVE_SYS_STATVFS_H.
+*/
+#define DK3_HAVE_SYS_STATVFS_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SYS_STAT_H
+#if HAVE_SYS_STAT_H
+/** DK3 version of HAVE_SYS_STAT_H.
+*/
+#define DK3_HAVE_SYS_STAT_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SYS_STROPTS_H
+#if HAVE_SYS_STROPTS_H
+/** DK3 version of HAVE_SYS_STROPTS_H.
+*/
+#define DK3_HAVE_SYS_STROPTS_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SYS_SUNDDI_H
+#if HAVE_SYS_SUNDDI_H
+/** DK3 version of HAVE_SYS_SUNDDI_H.
+*/
+#define DK3_HAVE_SYS_SUNDDI_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SYS_SYSCTL_H
+#if HAVE_SYS_SYSCTL_H
+/** DK3 version of HAVE_SYS_SYSCTL_H.
+*/
+#define DK3_HAVE_SYS_SYSCTL_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SYS_SYSTEMINFO_H
+#if HAVE_SYS_SYSTEMINFO_H
+/** DK3 version of HAVE_SYS_SYSTEMINFO_H.
+*/
+#define DK3_HAVE_SYS_SYSTEMINFO_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SYS_TERMIOS_H
+#if HAVE_SYS_TERMIOS_H
+/** DK3 version of HAVE_SYS_TERMIOS_H.
+*/
+#define DK3_HAVE_SYS_TERMIOS_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SYS_TIME_H
+#if HAVE_SYS_TIME_H
+/** DK3 version of HAVE_SYS_TIME_H.
+*/
+#define DK3_HAVE_SYS_TIME_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SYS_TTOLD_H
+#if HAVE_SYS_TTOLD_H
+/** DK3 version of HAVE_SYS_TTOLD_H.
+*/
+#define DK3_HAVE_SYS_TTOLD_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SYS_TYPES_H
+#if HAVE_SYS_TYPES_H
+/** DK3 version of HAVE_SYS_TYPES_H.
+*/
+#define DK3_HAVE_SYS_TYPES_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SYS_UIO_H
+#if HAVE_SYS_UIO_H
+/** DK3 version of HAVE_SYS_UIO_H.
+*/
+#define DK3_HAVE_SYS_UIO_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SYS_UN_H
+#if HAVE_SYS_UN_H
+/** DK3 version of HAVE_SYS_UN_H.
+*/
+#define DK3_HAVE_SYS_UN_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_SYS_WAIT_H
+#if HAVE_SYS_WAIT_H
+/** DK3 version of HAVE_SYS_WAIT_H.
+*/
+#define DK3_HAVE_SYS_WAIT_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_TANHL
+#if HAVE_TANHL
+/** DK3 version of HAVE_TANHL.
+*/
+#define DK3_HAVE_TANHL 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_TANL
+#if HAVE_TANL
+/** DK3 version of HAVE_TANL.
+*/
+#define DK3_HAVE_TANL 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_TCFLUSH
+#if HAVE_TCFLUSH
+/** DK3 version of HAVE_TCFLUSH.
+*/
+#define DK3_HAVE_TCFLUSH 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_TCGETATTR
+#if HAVE_TCGETATTR
+/** DK3 version of HAVE_TCGETATTR.
+*/
+#define DK3_HAVE_TCGETATTR 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_TERMIOS_H
+#if HAVE_TERMIOS_H
+/** DK3 version of HAVE_TERMIOS_H.
+*/
+#define DK3_HAVE_TERMIOS_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_TIFF_H
+#if HAVE_TIFF_H
+/** DK3 version of HAVE_TIFF_H.
+*/
+#define DK3_HAVE_TIFF_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_TIME
+#if HAVE_TIME
+/** DK3 version of HAVE_TIME.
+*/
+#define DK3_HAVE_TIME 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_TIME_H
+#if HAVE_TIME_H
+/** DK3 version of HAVE_TIME_H.
+*/
+#define DK3_HAVE_TIME_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_TWOS_COMPLEMENT
+#if HAVE_TWOS_COMPLEMENT
+/** DK3 version of HAVE_TWOS_COMPLEMENT.
+*/
+#define DK3_HAVE_TWOS_COMPLEMENT 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_UMASK
+#if HAVE_UMASK
+/** DK3 version of HAVE_UMASK.
+*/
+#define DK3_HAVE_UMASK 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_UNISTD_H
+#if HAVE_UNISTD_H
+/** DK3 version of HAVE_UNISTD_H.
+*/
+#define DK3_HAVE_UNISTD_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_UNLINK
+#if HAVE_UNLINK
+/** DK3 version of HAVE_UNLINK.
+*/
+#define DK3_HAVE_UNLINK 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_USER_NAMES_CASE_INSENSITIVE
+#if HAVE_USER_NAMES_CASE_INSENSITIVE
+/** DK3 version of HAVE_USER_NAMES_CASE_INSENSITIVE.
+*/
+#define DK3_HAVE_USER_NAMES_CASE_INSENSITIVE 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_VARARGS_H
+#if HAVE_VARARGS_H
+/** DK3 version of HAVE_VARARGS_H.
+*/
+#define DK3_HAVE_VARARGS_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_VARARG_H
+#if HAVE_VARARG_H
+/** DK3 version of HAVE_VARARG_H.
+*/
+#define DK3_HAVE_VARARG_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_VOLATILE
+#if HAVE_VOLATILE
+/** DK3 version of HAVE_VOLATILE.
+*/
+#define DK3_HAVE_VOLATILE 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCHAR_H
+#if HAVE_WCHAR_H
+/** DK3 version of HAVE_WCHAR_H.
+*/
+#define DK3_HAVE_WCHAR_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCHAR_T
+#if HAVE_WCHAR_T
+/** DK3 version of HAVE_WCHAR_T.
+*/
+#define DK3_HAVE_WCHAR_T 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCSCAT
+#if HAVE_WCSCAT
+/** DK3 version of HAVE_WCSCAT.
+*/
+#define DK3_HAVE_WCSCAT 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCSCAT_S
+#if HAVE_WCSCAT_S
+/** DK3 version of HAVE_WCSCAT_S.
+*/
+#define DK3_HAVE_WCSCAT_S 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCSCHR
+#if HAVE_WCSCHR
+/** DK3 version of HAVE_WCSCHR.
+*/
+#define DK3_HAVE_WCSCHR 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCSCMP
+#if HAVE_WCSCMP
+/** DK3 version of HAVE_WCSCMP.
+*/
+#define DK3_HAVE_WCSCMP 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCSCPY
+#if HAVE_WCSCPY
+/** DK3 version of HAVE_WCSCPY.
+*/
+#define DK3_HAVE_WCSCPY 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCSCPY_S
+#if HAVE_WCSCPY_S
+/** DK3 version of HAVE_WCSCPY_S.
+*/
+#define DK3_HAVE_WCSCPY_S 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCSDUP
+#if HAVE_WCSDUP
+/** DK3 version of HAVE_WCSDUP.
+*/
+#define DK3_HAVE_WCSDUP 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCSICMP
+#if HAVE_WCSICMP
+/** DK3 version of HAVE_WCSICMP.
+*/
+#define DK3_HAVE_WCSICMP 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCSLEN
+#if HAVE_WCSLEN
+/** DK3 version of HAVE_WCSLEN.
+*/
+#define DK3_HAVE_WCSLEN 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCSNCMP
+#if HAVE_WCSNCMP
+/** DK3 version of HAVE_WCSNCMP.
+*/
+#define DK3_HAVE_WCSNCMP 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCSNCPY
+#if HAVE_WCSNCPY
+/** DK3 version of HAVE_WCSNCPY.
+*/
+#define DK3_HAVE_WCSNCPY 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCSNCPY_S
+#if HAVE_WCSNCPY_S
+/** DK3 version of HAVE_WCSNCPY_S.
+*/
+#define DK3_HAVE_WCSNCPY_S 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCSRCHR
+#if HAVE_WCSRCHR
+/** DK3 version of HAVE_WCSRCHR.
+*/
+#define DK3_HAVE_WCSRCHR 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCSTOD
+#if HAVE_WCSTOD
+/** DK3 version of HAVE_WCSTOD.
+*/
+#define DK3_HAVE_WCSTOD 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCSTOIMAX
+#if HAVE_WCSTOIMAX
+/** DK3 version of HAVE_WCSTOIMAX.
+*/
+#define DK3_HAVE_WCSTOIMAX 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCSTOL
+#if HAVE_WCSTOL
+/** DK3 version of HAVE_WCSTOL.
+*/
+#define DK3_HAVE_WCSTOL 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCSTOLL
+#if HAVE_WCSTOLL
+/** DK3 version of HAVE_WCSTOLL.
+*/
+#define DK3_HAVE_WCSTOLL 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCSTOUL
+#if HAVE_WCSTOUL
+/** DK3 version of HAVE_WCSTOUL.
+*/
+#define DK3_HAVE_WCSTOUL 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCSTOULL
+#if HAVE_WCSTOULL
+/** DK3 version of HAVE_WCSTOULL.
+*/
+#define DK3_HAVE_WCSTOULL 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCSTOUMAX
+#if HAVE_WCSTOUMAX
+/** DK3 version of HAVE_WCSTOUMAX.
+*/
+#define DK3_HAVE_WCSTOUMAX 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_WINBASE_H
+#if HAVE_WINBASE_H
+/** DK3 version of HAVE_WINBASE_H.
+*/
+#define DK3_HAVE_WINBASE_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_WINCON_H
+#if HAVE_WINCON_H
+/** DK3 version of HAVE_WINCON_H.
+*/
+#define DK3_HAVE_WINCON_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_WINDOWS_H
+#if HAVE_WINDOWS_H
+/** DK3 version of HAVE_WINDOWS_H.
+*/
+#define DK3_HAVE_WINDOWS_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_WINREG_H
+#if HAVE_WINREG_H
+/** DK3 version of HAVE_WINREG_H.
+*/
+#define DK3_HAVE_WINREG_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_WINSOCK2_H
+#if HAVE_WINSOCK2_H
+/** DK3 version of HAVE_WINSOCK2_H.
+*/
+#define DK3_HAVE_WINSOCK2_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_WRITE
+#if HAVE_WRITE
+/** DK3 version of HAVE_WRITE.
+*/
+#define DK3_HAVE_WRITE 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_WS2TCPIP_H
+#if HAVE_WS2TCPIP_H
+/** DK3 version of HAVE_WS2TCPIP_H.
+*/
+#define DK3_HAVE_WS2TCPIP_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE_ZLIB_H
+#if HAVE_ZLIB_H
+/** DK3 version of HAVE_ZLIB_H.
+*/
+#define DK3_HAVE_ZLIB_H 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__CLEARFP
+#if HAVE__CLEARFP
+/** DK3 version of HAVE__CLEARFP.
+*/
+#define DK3_HAVE__CLEARFP 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__FCLOSE
+#if HAVE__FCLOSE
+/** DK3 version of HAVE__FCLOSE.
+*/
+#define DK3_HAVE__FCLOSE 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__FEOF
+#if HAVE__FEOF
+/** DK3 version of HAVE__FEOF.
+*/
+#define DK3_HAVE__FEOF 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__FERROR
+#if HAVE__FERROR
+/** DK3 version of HAVE__FERROR.
+*/
+#define DK3_HAVE__FERROR 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__FFLUSH
+#if HAVE__FFLUSH
+/** DK3 version of HAVE__FFLUSH.
+*/
+#define DK3_HAVE__FFLUSH 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__FOPEN
+#if HAVE__FOPEN
+/** DK3 version of HAVE__FOPEN.
+*/
+#define DK3_HAVE__FOPEN 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__FREAD
+#if HAVE__FREAD
+/** DK3 version of HAVE__FREAD.
+*/
+#define DK3_HAVE__FREAD 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__FWRITE
+#if HAVE__FWRITE
+/** DK3 version of HAVE__FWRITE.
+*/
+#define DK3_HAVE__FWRITE 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__GETCWD
+#if HAVE__GETCWD
+/** DK3 version of HAVE__GETCWD.
+*/
+#define DK3_HAVE__GETCWD 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__GETENV_S
+#if HAVE__GETENV_S
+/** DK3 version of HAVE__GETENV_S.
+*/
+#define DK3_HAVE__GETENV_S 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__GETPID
+#if HAVE__GETPID
+/** DK3 version of HAVE__GETPID.
+*/
+#define DK3_HAVE__GETPID 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__LSTAT
+#if HAVE__LSTAT
+/** DK3 version of HAVE__LSTAT.
+*/
+#define DK3_HAVE__LSTAT 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__LSTAT32
+#if HAVE__LSTAT32
+/** DK3 version of HAVE__LSTAT32.
+*/
+#define DK3_HAVE__LSTAT32 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__LSTAT64
+#if HAVE__LSTAT64
+/** DK3 version of HAVE__LSTAT64.
+*/
+#define DK3_HAVE__LSTAT64 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__MKDIR
+#if HAVE__MKDIR
+/** DK3 version of HAVE__MKDIR.
+*/
+#define DK3_HAVE__MKDIR 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__POPEN
+#if HAVE__POPEN
+/** DK3 version of HAVE__POPEN.
+*/
+#define DK3_HAVE__POPEN 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__READ
+#if HAVE__READ
+/** DK3 version of HAVE__READ.
+*/
+#define DK3_HAVE__READ 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__RMDIR
+#if HAVE__RMDIR
+/** DK3 version of HAVE__RMDIR.
+*/
+#define DK3_HAVE__RMDIR 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__SNPRINTF
+#if HAVE__SNPRINTF
+/** DK3 version of HAVE__SNPRINTF.
+*/
+#define DK3_HAVE__SNPRINTF 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__SNPRINTF_S
+#if HAVE__SNPRINTF_S
+/** DK3 version of HAVE__SNPRINTF_S.
+*/
+#define DK3_HAVE__SNPRINTF_S 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__SNWPRINTF
+#if HAVE__SNWPRINTF
+/** DK3 version of HAVE__SNWPRINTF.
+*/
+#define DK3_HAVE__SNWPRINTF 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__SNWPRINTF_S
+#if HAVE__SNWPRINTF_S
+/** DK3 version of HAVE__SNWPRINTF_S.
+*/
+#define DK3_HAVE__SNWPRINTF_S 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__STAT
+#if HAVE__STAT
+/** DK3 version of HAVE__STAT.
+*/
+#define DK3_HAVE__STAT 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__STAT32
+#if HAVE__STAT32
+/** DK3 version of HAVE__STAT32.
+*/
+#define DK3_HAVE__STAT32 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__STAT64
+#if HAVE__STAT64
+/** DK3 version of HAVE__STAT64.
+*/
+#define DK3_HAVE__STAT64 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__STRDUP
+#if HAVE__STRDUP
+/** DK3 version of HAVE__STRDUP.
+*/
+#define DK3_HAVE__STRDUP 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__STRICMP
+#if HAVE__STRICMP
+/** DK3 version of HAVE__STRICMP.
+*/
+#define DK3_HAVE__STRICMP 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__UNLINK
+#if HAVE__UNLINK
+/** DK3 version of HAVE__UNLINK.
+*/
+#define DK3_HAVE__UNLINK 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__WCSCAT
+#if HAVE__WCSCAT
+/** DK3 version of HAVE__WCSCAT.
+*/
+#define DK3_HAVE__WCSCAT 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__WCSCHR
+#if HAVE__WCSCHR
+/** DK3 version of HAVE__WCSCHR.
+*/
+#define DK3_HAVE__WCSCHR 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__WCSCMP
+#if HAVE__WCSCMP
+/** DK3 version of HAVE__WCSCMP.
+*/
+#define DK3_HAVE__WCSCMP 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__WCSCPY
+#if HAVE__WCSCPY
+/** DK3 version of HAVE__WCSCPY.
+*/
+#define DK3_HAVE__WCSCPY 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__WCSDUP
+#if HAVE__WCSDUP
+/** DK3 version of HAVE__WCSDUP.
+*/
+#define DK3_HAVE__WCSDUP 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__WCSICMP
+#if HAVE__WCSICMP
+/** DK3 version of HAVE__WCSICMP.
+*/
+#define DK3_HAVE__WCSICMP 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__WCSLEN
+#if HAVE__WCSLEN
+/** DK3 version of HAVE__WCSLEN.
+*/
+#define DK3_HAVE__WCSLEN 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__WCSNCMP
+#if HAVE__WCSNCMP
+/** DK3 version of HAVE__WCSNCMP.
+*/
+#define DK3_HAVE__WCSNCMP 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__WCSNCPY
+#if HAVE__WCSNCPY
+/** DK3 version of HAVE__WCSNCPY.
+*/
+#define DK3_HAVE__WCSNCPY 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__WCSRCHR
+#if HAVE__WCSRCHR
+/** DK3 version of HAVE__WCSRCHR.
+*/
+#define DK3_HAVE__WCSRCHR 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__WFOPEN_S
+#if HAVE__WFOPEN_S
+/** DK3 version of HAVE__WFOPEN_S.
+*/
+#define DK3_HAVE__WFOPEN_S 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__WGETENV
+#if HAVE__WGETENV
+/** DK3 version of HAVE__WGETENV.
+*/
+#define DK3_HAVE__WGETENV 1
+#endif
+#endif
+
+#ifndef DK3_HAVE__WRITE
+#if HAVE__WRITE
+/** DK3 version of HAVE__WRITE.
+*/
+#define DK3_HAVE__WRITE 1
+#endif
+#endif
+
+#ifndef DK3_TIME_WITH_SYS_TIME
+#if TIME_WITH_SYS_TIME
+/** DK3 version of TIME_WITH_SYS_TIME.
+*/
+#define DK3_TIME_WITH_SYS_TIME 1
+#endif
+#endif
+
+#ifndef DK3_SIZEOF_DOUBLE
+#if SIZEOF_DOUBLE
+/** DK3 version of SIZEOF_DOUBLE.
+*/
+#define DK3_SIZEOF_DOUBLE SIZEOF_DOUBLE
+#endif
+#endif
+
+#ifndef DK3_SIZEOF_INT
+#if SIZEOF_INT
+/** DK3 version of SIZEOF_INT.
+*/
+#define DK3_SIZEOF_INT SIZEOF_INT
+#endif
+#endif
+
+#ifndef DK3_SIZEOF_INTMAX_T
+#if SIZEOF_INTMAX_T
+/** DK3 version of SIZEOF_INTMAX_T.
+*/
+#define DK3_SIZEOF_INTMAX_T SIZEOF_INTMAX_T
+#endif
+#endif
+
+#ifndef DK3_SIZEOF_LONG
+#if SIZEOF_LONG
+/** DK3 version of SIZEOF_LONG.
+*/
+#define DK3_SIZEOF_LONG SIZEOF_LONG
+#endif
+#endif
+
+#ifndef DK3_SIZEOF_LONG_DOUBLE
+#if SIZEOF_LONG_DOUBLE
+/** DK3 version of SIZEOF_LONG_DOUBLE.
+*/
+#define DK3_SIZEOF_LONG_DOUBLE SIZEOF_LONG_DOUBLE
+#endif
+#endif
+
+#ifndef DK3_SIZEOF_LONG_LONG
+#if SIZEOF_LONG_LONG
+/** DK3 version of SIZEOF_LONG_LONG.
+*/
+#define DK3_SIZEOF_LONG_LONG SIZEOF_LONG_LONG
+#endif
+#endif
+
+#ifndef DK3_SIZEOF_SHORT
+#if SIZEOF_SHORT
+/** DK3 version of SIZEOF_SHORT.
+*/
+#define DK3_SIZEOF_SHORT SIZEOF_SHORT
+#endif
+#endif
+
+#ifndef DK3_SIZEOF_SIZE_T
+#if SIZEOF_SIZE_T
+/** DK3 version of SIZEOF_SIZE_T.
+*/
+#define DK3_SIZEOF_SIZE_T SIZEOF_SIZE_T
+#endif
+#endif
+
+#ifndef DK3_SIZEOF_WCHAR_T
+#if SIZEOF_WCHAR_T
+/** DK3 version of SIZEOF_WCHAR_T.
+*/
+#define DK3_SIZEOF_WCHAR_T SIZEOF_WCHAR_T
+#endif
+#endif
+
+#ifndef DK3_WORDS_BIGENDIAN
+#if WORDS_BIGENDIAN
+/** Little-endian.
+*/
+#define DK3_WORDS_BIGENDIAN 1
+#else
+#define DK3_WORDS_BIGENDIAN 0
+#endif
+#endif
+
+#ifndef DK3_MAX_PATH
+/** Maximum path length.
+*/
+#define DK3_MAX_PATH 4097
+#endif
+
+#endif
+/* ifndef DK3_CONF_H_INCLUDED */
+
diff --git a/support/dktools/dk3conf.cross.in b/support/dktools/dk3conf.cross.in
new file mode 100644
index 0000000000..400f1d8124
--- /dev/null
+++ b/support/dktools/dk3conf.cross.in
@@ -0,0 +1,2094 @@
+/** @file dk3conf.h Configuration for DK3 libraries.
+ Features: Include files, functions, sizes,
+ and endianness.
+*/
+
+#ifndef DK3_CONF_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3_CONF_H_INCLUDED 1
+
+#ifndef DK3_ON_WINDOWS
+#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
+/** On a Windows system. */
+#define DK3_ON_WINDOWS 1
+#else
+/** Not on a Windows system. */
+#define DK3_ON_WINDOWS 0
+#endif
+#endif
+/** ifndef DK3_ON_WINDOWS */
+
+
+#ifndef DK3_HAVE_ACOSH
+/** DK3 version of HAVE_ACOSH.
+*/
+#define DK3_HAVE_ACOSH 1
+#endif
+
+#ifndef DK3_HAVE_ACOSHL
+/** DK3 version of HAVE_ACOSHL.
+*/
+#define DK3_HAVE_ACOSHL 1
+#endif
+
+#ifndef DK3_HAVE_ACOSL
+/** DK3 version of HAVE_ACOSL.
+*/
+#define DK3_HAVE_ACOSL 1
+#endif
+
+#ifndef DK3_HAVE_ALLOC_H
+/** DK3 version of HAVE_ALLOC_H.
+*/
+#define DK3_HAVE_ALLOC_H 0
+#endif
+
+#ifndef DK3_HAVE_ARPA_INET_H
+/** DK3 version of HAVE_ARPA_INET_H.
+*/
+#define DK3_HAVE_ARPA_INET_H 1
+#endif
+
+#ifndef DK3_HAVE_ASINH
+/** DK3 version of HAVE_ASINH.
+*/
+#define DK3_HAVE_ASINH 1
+#endif
+
+#ifndef DK3_HAVE_ASINHL
+/** DK3 version of HAVE_ASINHL.
+*/
+#define DK3_HAVE_ASINHL 1
+#endif
+
+#ifndef DK3_HAVE_ASINL
+/** DK3 version of HAVE_ASINL.
+*/
+#define DK3_HAVE_ASINL 1
+#endif
+
+#ifndef DK3_HAVE_ATAN2
+/** DK3 version of HAVE_ATAN2.
+*/
+#define DK3_HAVE_ATAN2 1
+#endif
+
+#ifndef DK3_HAVE_ATAN2L
+/** DK3 version of HAVE_ATAN2L.
+*/
+#define DK3_HAVE_ATAN2L 1
+#endif
+
+#ifndef DK3_HAVE_ATANH
+/** DK3 version of HAVE_ATANH.
+*/
+#define DK3_HAVE_ATANH 1
+#endif
+
+#ifndef DK3_HAVE_ATANHL
+/** DK3 version of HAVE_ATANHL.
+*/
+#define DK3_HAVE_ATANHL 1
+#endif
+
+#ifndef DK3_HAVE_ATANL
+/** DK3 version of HAVE_ATANL.
+*/
+#define DK3_HAVE_ATANL 1
+#endif
+
+#ifndef DK3_HAVE_BACKSLASH
+/** DK3 version of HAVE_BACKSLASH.
+*/
+#define DK3_HAVE_BACKSLASH 0
+#endif
+
+#ifndef DK3_HAVE_BCMP
+/** DK3 version of HAVE_BCMP.
+*/
+#define DK3_HAVE_BCMP 1
+#endif
+
+#ifndef DK3_HAVE_BCOPY
+/** DK3 version of HAVE_BCOPY.
+*/
+#define DK3_HAVE_BCOPY 1
+#endif
+
+#ifndef DK3_HAVE_BZERO
+/** DK3 version of HAVE_BZERO.
+*/
+#define DK3_HAVE_BZERO 1
+#endif
+
+#ifndef DK3_HAVE_BZLIB_H
+/** DK3 version of HAVE_BZLIB_H.
+*/
+#define DK3_HAVE_BZLIB_H 1
+#endif
+
+#ifndef DK3_HAVE_CEIL
+/** DK3 version of HAVE_CEIL.
+*/
+#define DK3_HAVE_CEIL 1
+#endif
+
+#ifndef DK3_HAVE_CEILL
+/** DK3 version of HAVE_CEILL.
+*/
+#define DK3_HAVE_CEILL 1
+#endif
+
+#ifndef DK3_HAVE_CHDIR
+/** DK3 version of HAVE_CHDIR.
+*/
+#define DK3_HAVE_CHDIR 1
+#endif
+
+#ifndef DK3_HAVE_CHMOD
+/** DK3 version of HAVE_CHMOD.
+*/
+#define DK3_HAVE_CHMOD 1
+#endif
+
+#ifndef DK3_HAVE_CHOWN
+/** DK3 version of HAVE_CHOWN.
+*/
+#define DK3_HAVE_CHOWN 1
+#endif
+
+#ifndef DK3_HAVE_CLOSEDIR
+/** DK3 version of HAVE_CLOSEDIR.
+*/
+#define DK3_HAVE_CLOSEDIR 1
+#endif
+
+#ifndef DK3_HAVE_CONIO_H
+/** DK3 version of HAVE_CONIO_H.
+*/
+#define DK3_HAVE_CONIO_H 0
+#endif
+
+#ifndef DK3_HAVE_CONST
+/** DK3 version of HAVE_CONST.
+*/
+#define DK3_HAVE_CONST 1
+#endif
+
+#ifndef DK3_HAVE_COSHL
+/** DK3 version of HAVE_COSHL.
+*/
+#define DK3_HAVE_COSHL 1
+#endif
+
+#ifndef DK3_HAVE_COSL
+/** DK3 version of HAVE_COSL.
+*/
+#define DK3_HAVE_COSL 1
+#endif
+
+#ifndef DK3_HAVE_CTYPE_H
+/** DK3 version of HAVE_CTYPE_H.
+*/
+#define DK3_HAVE_CTYPE_H 1
+#endif
+
+#ifndef DK3_HAVE_DB_CURSOR_C_GET
+/** DK3 version of HAVE_DB_CURSOR_C_GET.
+*/
+#define DK3_HAVE_DB_CURSOR_C_GET 1
+#endif
+
+#ifndef DK3_HAVE_DB_H
+/** DK3 version of HAVE_DB_H.
+*/
+#define DK3_HAVE_DB_H 1
+#endif
+
+#ifndef DK3_HAVE_DEV_RANDOM
+/** DK3 version of HAVE_DEV_RANDOM.
+*/
+#define DK3_HAVE_DEV_RANDOM 1
+#endif
+
+#ifndef DK3_HAVE_DEV_URANDOM
+/** DK3 version of HAVE_DEV_URANDOM.
+*/
+#define DK3_HAVE_DEV_URANDOM 1
+#endif
+
+#ifndef DK3_HAVE_DIRECT_H
+/** DK3 version of HAVE_DIRECT_H.
+*/
+#define DK3_HAVE_DIRECT_H 0
+#endif
+
+#ifndef DK3_HAVE_DIRENT_H
+/** DK3 version of HAVE_DIRENT_H.
+*/
+#define DK3_HAVE_DIRENT_H 1
+#endif
+
+#ifndef DK3_HAVE_DIR_H
+/** DK3 version of HAVE_DIR_H.
+*/
+#define DK3_HAVE_DIR_H 0
+#endif
+
+#ifndef DK3_HAVE_DOS_H
+/** DK3 version of HAVE_DOS_H.
+*/
+#define DK3_HAVE_DOS_H 0
+#endif
+
+#ifndef DK3_HAVE_ENDGRENT
+/** DK3 version of HAVE_ENDGRENT.
+*/
+#define DK3_HAVE_ENDGRENT 1
+#endif
+
+#ifndef DK3_HAVE_ENDPWENT
+/** DK3 version of HAVE_ENDPWENT.
+*/
+#define DK3_HAVE_ENDPWENT 1
+#endif
+
+#ifndef DK3_HAVE_ERRNO_H
+/** DK3 version of HAVE_ERRNO_H.
+*/
+#define DK3_HAVE_ERRNO_H 1
+#endif
+
+#ifndef DK3_HAVE_ERR_H
+/** DK3 version of HAVE_ERR_H.
+*/
+#define DK3_HAVE_ERR_H 1
+#endif
+
+#ifndef DK3_HAVE_EXPL
+/** DK3 version of HAVE_EXPL.
+*/
+#define DK3_HAVE_EXPL 1
+#endif
+
+#ifndef DK3_HAVE_FABS
+/** DK3 version of HAVE_FABS.
+*/
+#define DK3_HAVE_FABS 1
+#endif
+
+#ifndef DK3_HAVE_FABSL
+/** DK3 version of HAVE_FABSL.
+*/
+#define DK3_HAVE_FABSL 1
+#endif
+
+#ifndef DK3_HAVE_FCLOSE
+/** DK3 version of HAVE_FCLOSE.
+*/
+#define DK3_HAVE_FCLOSE 1
+#endif
+
+#ifndef DK3_HAVE_FCNTL_H
+/** DK3 version of HAVE_FCNTL_H.
+*/
+#define DK3_HAVE_FCNTL_H 1
+#endif
+
+#ifndef DK3_HAVE_FENV_H
+/** DK3 version of HAVE_FENV_H.
+*/
+#define DK3_HAVE_FENV_H 1
+#endif
+
+#ifndef DK3_HAVE_FEOF
+/** DK3 version of HAVE_FEOF.
+*/
+#define DK3_HAVE_FEOF 1
+#endif
+
+#ifndef DK3_HAVE_FERROR
+/** DK3 version of HAVE_FERROR.
+*/
+#define DK3_HAVE_FERROR 1
+#endif
+
+#ifndef DK3_HAVE_FETESTEXCEPT
+/** DK3 version of HAVE_FETESTEXCEPT.
+*/
+#define DK3_HAVE_FETESTEXCEPT 0
+#endif
+
+#ifndef DK3_HAVE_FFLUSH
+/** DK3 version of HAVE_FFLUSH.
+*/
+#define DK3_HAVE_FFLUSH 1
+#endif
+
+#ifndef DK3_HAVE_FLOAT_H
+/** DK3 version of HAVE_FLOAT_H.
+*/
+#define DK3_HAVE_FLOAT_H 1
+#endif
+
+#ifndef DK3_HAVE_FLOOR
+/** DK3 version of HAVE_FLOOR.
+*/
+#define DK3_HAVE_FLOOR 1
+#endif
+
+#ifndef DK3_HAVE_FLOORL
+/** DK3 version of HAVE_FLOORL.
+*/
+#define DK3_HAVE_FLOORL 1
+#endif
+
+#ifndef DK3_HAVE_FNCASEINS
+/** DK3 version of HAVE_FNCASEINS.
+*/
+#define DK3_HAVE_FNCASEINS 0
+#endif
+
+#ifndef DK3_HAVE_FOPEN
+/** DK3 version of HAVE_FOPEN.
+*/
+#define DK3_HAVE_FOPEN 1
+#endif
+
+#ifndef DK3_HAVE_FOPEN64
+/** DK3 version of HAVE_FOPEN64.
+*/
+#define DK3_HAVE_FOPEN64 1
+#endif
+
+#ifndef DK3_HAVE_FOPEN_S
+/** DK3 version of HAVE_FOPEN_S.
+*/
+#define DK3_HAVE_FOPEN_S 0
+#endif
+
+#ifndef DK3_HAVE_FORK
+/** DK3 version of HAVE_FORK.
+*/
+#define DK3_HAVE_FORK 1
+#endif
+
+#ifndef DK3_HAVE_FPCLASSIFY
+/** DK3 version of HAVE_FPCLASSIFY.
+*/
+#define DK3_HAVE_FPCLASSIFY 1
+#endif
+
+#ifndef DK3_HAVE_FREAD
+/** DK3 version of HAVE_FREAD.
+*/
+#define DK3_HAVE_FREAD 1
+#endif
+
+#ifndef DK3_HAVE_FREE
+/** DK3 version of HAVE_FREE.
+*/
+#define DK3_HAVE_FREE 1
+#endif
+
+#ifndef DK3_HAVE_FWRITE
+/** DK3 version of HAVE_FWRITE.
+*/
+#define DK3_HAVE_FWRITE 1
+#endif
+
+#ifndef DK3_HAVE_GDBM_H
+/** DK3 version of HAVE_GDBM_H.
+*/
+#define DK3_HAVE_GDBM_H 1
+#endif
+
+#ifndef DK3_HAVE_GETADDRINFO
+/** DK3 version of HAVE_GETADDRINFO.
+*/
+#define DK3_HAVE_GETADDRINFO 1
+#endif
+
+#ifndef DK3_HAVE_GETCWD
+/** DK3 version of HAVE_GETCWD.
+*/
+#define DK3_HAVE_GETCWD 1
+#endif
+
+#ifndef DK3_HAVE_GETENV
+/** DK3 version of HAVE_GETENV.
+*/
+#define DK3_HAVE_GETENV 1
+#endif
+
+#ifndef DK3_HAVE_GETEUID
+/** DK3 version of HAVE_GETEUID.
+*/
+#define DK3_HAVE_GETEUID 1
+#endif
+
+#ifndef DK3_HAVE_GETGRENT
+/** DK3 version of HAVE_GETGRENT.
+*/
+#define DK3_HAVE_GETGRENT 1
+#endif
+
+#ifndef DK3_HAVE_GETGRGID
+/** DK3 version of HAVE_GETGRGID.
+*/
+#define DK3_HAVE_GETGRGID 1
+#endif
+
+#ifndef DK3_HAVE_GETGRNAM
+/** DK3 version of HAVE_GETGRNAM.
+*/
+#define DK3_HAVE_GETGRNAM 1
+#endif
+
+#ifndef DK3_HAVE_GETHOSTBYNAME
+/** DK3 version of HAVE_GETHOSTBYNAME.
+*/
+#define DK3_HAVE_GETHOSTBYNAME 1
+#endif
+
+#ifndef DK3_HAVE_GETHOSTNAME
+/** DK3 version of HAVE_GETHOSTNAME.
+*/
+#define DK3_HAVE_GETHOSTNAME 1
+#endif
+
+#ifndef DK3_HAVE_GETPEERNAME
+/** DK3 version of HAVE_GETPEERNAME.
+*/
+#define DK3_HAVE_GETPEERNAME 1
+#endif
+
+#ifndef DK3_HAVE_GETPID
+/** DK3 version of HAVE_GETPID.
+*/
+#define DK3_HAVE_GETPID 1
+#endif
+
+#ifndef DK3_HAVE_GETPWENT
+/** DK3 version of HAVE_GETPWENT.
+*/
+#define DK3_HAVE_GETPWENT 1
+#endif
+
+#ifndef DK3_HAVE_GETPWNAM
+/** DK3 version of HAVE_GETPWNAM.
+*/
+#define DK3_HAVE_GETPWNAM 1
+#endif
+
+#ifndef DK3_HAVE_GETPWUID
+/** DK3 version of HAVE_GETPWUID.
+*/
+#define DK3_HAVE_GETPWUID 1
+#endif
+
+#ifndef DK3_HAVE_GETRLIMIT
+/** DK3 version of HAVE_GETRLIMIT.
+*/
+#define DK3_HAVE_GETRLIMIT 1
+#endif
+
+#ifndef DK3_HAVE_GETSOCKNAME
+/** DK3 version of HAVE_GETSOCKNAME.
+*/
+#define DK3_HAVE_GETSOCKNAME 1
+#endif
+
+#ifndef DK3_HAVE_GETUID
+/** DK3 version of HAVE_GETUID.
+*/
+#define DK3_HAVE_GETUID 1
+#endif
+
+#ifndef DK3_HAVE_GRP_H
+/** DK3 version of HAVE_GRP_H.
+*/
+#define DK3_HAVE_GRP_H 1
+#endif
+
+#ifndef DK3_HAVE_HTONL
+/** DK3 version of HAVE_HTONL.
+*/
+#define DK3_HAVE_HTONL 1
+#endif
+
+#ifndef DK3_HAVE_IEEE_754_DOUBLE
+/** DK3 version of HAVE_IEEE_754_DOUBLE.
+*/
+#define DK3_HAVE_IEEE_754_DOUBLE 1
+#endif
+
+#ifndef DK3_HAVE_IN6_ADDR
+/** DK3 version of HAVE_IN6_ADDR.
+*/
+#define DK3_HAVE_IN6_ADDR 0
+#endif
+
+#ifndef DK3_HAVE_INET_ADDR
+/** DK3 version of HAVE_INET_ADDR.
+*/
+#define DK3_HAVE_INET_ADDR 1
+#endif
+
+#ifndef DK3_HAVE_INET_ATON
+/** DK3 version of HAVE_INET_ATON.
+*/
+#define DK3_HAVE_INET_ATON 1
+#endif
+
+#ifndef DK3_HAVE_INET_PTON
+/** DK3 version of HAVE_INET_PTON.
+*/
+#define DK3_HAVE_INET_PTON 1
+#endif
+
+#ifndef DK3_HAVE_INITSTATE
+/** DK3 version of HAVE_INITSTATE.
+*/
+#define DK3_HAVE_INITSTATE 1
+#endif
+
+#ifndef DK3_HAVE_INODES
+/** DK3 version of HAVE_INODES.
+*/
+#define DK3_HAVE_INODES 1
+#endif
+
+#ifndef DK3_HAVE_INTMAX_T
+/** DK3 version of HAVE_INTMAX_T.
+*/
+#define DK3_HAVE_INTMAX_T 1
+#endif
+
+#ifndef DK3_HAVE_INTTYPES_H
+/** DK3 version of HAVE_INTTYPES_H.
+*/
+#define DK3_HAVE_INTTYPES_H 1
+#endif
+
+#ifndef DK3_HAVE_IN_ADDR
+/** DK3 version of HAVE_IN_ADDR.
+*/
+#define DK3_HAVE_IN_ADDR 0
+#endif
+
+#ifndef DK3_HAVE_IO_H
+/** DK3 version of HAVE_IO_H.
+*/
+#define DK3_HAVE_IO_H 0
+#endif
+
+#ifndef DK3_HAVE_ISATTY
+/** DK3 version of HAVE_ISATTY.
+*/
+#define DK3_HAVE_ISATTY 1
+#endif
+
+#ifndef DK3_HAVE_ISFINITE
+/** DK3 version of HAVE_ISFINITE.
+*/
+#define DK3_HAVE_ISFINITE 1
+#endif
+
+#ifndef DK3_HAVE_ISNORMAL
+/** DK3 version of HAVE_ISNORMAL.
+*/
+#define DK3_HAVE_ISNORMAL 1
+#endif
+
+#ifndef DK3_HAVE_JPEGLIB_H
+/** DK3 version of HAVE_JPEGLIB_H.
+*/
+#define DK3_HAVE_JPEGLIB_H 1
+#endif
+
+#ifndef DK3_HAVE_LABS
+/** DK3 version of HAVE_LABS.
+*/
+#define DK3_HAVE_LABS 1
+#endif
+
+#ifndef DK3_HAVE_LARGEFILE64_SOURCE
+/** DK3 version of HAVE_LARGEFILE64_SOURCE.
+*/
+#define DK3_HAVE_LARGEFILE64_SOURCE 1
+#endif
+
+#ifndef DK3_HAVE_LIBNETSNMP
+/** DK3 version of HAVE_LIBNETSNMP.
+*/
+#define DK3_HAVE_LIBNETSNMP 1
+#endif
+
+#ifndef DK3_HAVE_LIMITS_H
+/** DK3 version of HAVE_LIMITS_H.
+*/
+#define DK3_HAVE_LIMITS_H 1
+#endif
+
+#ifndef DK3_HAVE_LOCALE_H
+/** DK3 version of HAVE_LOCALE_H.
+*/
+#define DK3_HAVE_LOCALE_H 1
+#endif
+
+#ifndef DK3_HAVE_LOCALTIME
+/** DK3 version of HAVE_LOCALTIME.
+*/
+#define DK3_HAVE_LOCALTIME 1
+#endif
+
+#ifndef DK3_HAVE_LOCALTIME
+/** DK3 version of HAVE_LOCALTIME.
+*/
+#define DK3_HAVE_LOCALTIME 1
+#endif
+
+#ifndef DK3_HAVE_LOCALTIME_R
+/** DK3 version of HAVE_LOCALTIME_R.
+*/
+#define DK3_HAVE_LOCALTIME_R 1
+#endif
+
+#ifndef DK3_HAVE_LOCALTIME_S
+/** DK3 version of HAVE_LOCALTIME_S.
+*/
+#define DK3_HAVE_LOCALTIME_S 0
+#endif
+
+#ifndef DK3_HAVE_LOGL
+/** DK3 version of HAVE_LOGL.
+*/
+#define DK3_HAVE_LOGL 1
+#endif
+
+#ifndef DK3_HAVE_LONG_DOUBLE
+/** DK3 version of HAVE_LONG_DOUBLE.
+*/
+#define DK3_HAVE_LONG_DOUBLE 1
+#endif
+
+#ifndef DK3_HAVE_LONG_LONG
+/** DK3 version of HAVE_LONG_LONG.
+*/
+#define DK3_HAVE_LONG_LONG 1
+#endif
+
+#ifndef DK3_HAVE_LPRNG_H
+/** DK3 version of HAVE_LPRNG_H.
+*/
+#define DK3_HAVE_LPRNG_H 0
+#endif
+
+#ifndef DK3_HAVE_LRAND48
+/** DK3 version of HAVE_LRAND48.
+*/
+#define DK3_HAVE_LRAND48 1
+#endif
+
+#ifndef DK3_HAVE_LSTAT
+/** DK3 version of HAVE_LSTAT.
+*/
+#define DK3_HAVE_LSTAT 1
+#endif
+
+#ifndef DK3_HAVE_LSTAT32
+/** DK3 version of HAVE_LSTAT32.
+*/
+#define DK3_HAVE_LSTAT32 0
+#endif
+
+#ifndef DK3_HAVE_LSTAT64
+/** DK3 version of HAVE_LSTAT64.
+*/
+#define DK3_HAVE_LSTAT64 1
+#endif
+
+#ifndef DK3_HAVE_MALLOC
+/** DK3 version of HAVE_MALLOC.
+*/
+#define DK3_HAVE_MALLOC 1
+#endif
+
+#ifndef DK3_HAVE_MALLOC_H
+/** DK3 version of HAVE_MALLOC_H.
+*/
+#define DK3_HAVE_MALLOC_H 1
+#endif
+
+#ifndef DK3_HAVE_MATH_H
+/** DK3 version of HAVE_MATH_H.
+*/
+#define DK3_HAVE_MATH_H 1
+#endif
+
+#ifndef DK3_HAVE_MEMCMP
+/** DK3 version of HAVE_MEMCMP.
+*/
+#define DK3_HAVE_MEMCMP 1
+#endif
+
+#ifndef DK3_HAVE_MEMCPY
+/** DK3 version of HAVE_MEMCPY.
+*/
+#define DK3_HAVE_MEMCPY 1
+#endif
+
+#ifndef DK3_HAVE_MEMSET
+/** DK3 version of HAVE_MEMSET.
+*/
+#define DK3_HAVE_MEMSET 1
+#endif
+
+#ifndef DK3_HAVE_MKDIR
+/** DK3 version of HAVE_MKDIR.
+*/
+#define DK3_HAVE_MKDIR 1
+#endif
+
+#ifndef DK3_HAVE_MKDIR2
+/** DK3 version of HAVE_MKDIR2.
+*/
+#define DK3_HAVE_MKDIR2 1
+#endif
+
+#ifndef DK3_HAVE_MPCTL
+/** DK3 version of HAVE_MPCTL.
+*/
+#define DK3_HAVE_MPCTL 0
+#endif
+
+#ifndef DK3_HAVE_MYSQL_LIBRARY_END
+/** DK3 version of HAVE_MYSQL_LIBRARY_END.
+*/
+#define DK3_HAVE_MYSQL_LIBRARY_END 0
+#endif
+
+#ifndef DK3_HAVE_MYSQL_LIBRARY_INIT
+/** DK3 version of HAVE_MYSQL_LIBRARY_INIT.
+*/
+#define DK3_HAVE_MYSQL_LIBRARY_INIT 0
+#endif
+
+#ifndef DK3_HAVE_MYSQL_MYSQL_H
+/** DK3 version of HAVE_MYSQL_MYSQL_H.
+*/
+#define DK3_HAVE_MYSQL_MYSQL_H 1
+#endif
+
+#ifndef DK3_HAVE_MYSQL_SET_CHARACTER_SET
+/** DK3 version of HAVE_MYSQL_SET_CHARACTER_SET.
+*/
+#define DK3_HAVE_MYSQL_SET_CHARACTER_SET 0
+#endif
+
+#ifndef DK3_HAVE_NDBM_H
+/** DK3 version of HAVE_NDBM_H.
+*/
+#define DK3_HAVE_NDBM_H 0
+#endif
+
+#ifndef DK3_HAVE_NETDB_H
+/** DK3 version of HAVE_NETDB_H.
+*/
+#define DK3_HAVE_NETDB_H 1
+#endif
+
+#ifndef DK3_HAVE_NETINET_IN_H
+/** DK3 version of HAVE_NETINET_IN_H.
+*/
+#define DK3_HAVE_NETINET_IN_H 1
+#endif
+
+#ifndef DK3_HAVE_NETSNMP_ENABLE_FILELOG
+/** DK3 version of HAVE_NETSNMP_ENABLE_FILELOG.
+*/
+#define DK3_HAVE_NETSNMP_ENABLE_FILELOG 1
+#endif
+
+#ifndef DK3_HAVE_NRAND48
+/** DK3 version of HAVE_NRAND48.
+*/
+#define DK3_HAVE_NRAND48 1
+#endif
+
+#ifndef DK3_HAVE_OPENDIR
+/** DK3 version of HAVE_OPENDIR.
+*/
+#define DK3_HAVE_OPENDIR 1
+#endif
+
+#ifndef DK3_HAVE_OPENSSL_MD5_H
+/** DK3 version of HAVE_OPENSSL_MD5_H.
+*/
+#define DK3_HAVE_OPENSSL_MD5_H 1
+#endif
+
+#ifndef DK3_HAVE_OPENSSL_RAND_H
+/** DK3 version of HAVE_OPENSSL_RAND_H.
+*/
+#define DK3_HAVE_OPENSSL_RAND_H 1
+#endif
+
+#ifndef DK3_HAVE_OPENSSL_RIPEMD_H
+/** DK3 version of HAVE_OPENSSL_RIPEMD_H.
+*/
+#define DK3_HAVE_OPENSSL_RIPEMD_H 1
+#endif
+
+#ifndef DK3_HAVE_OPENSSL_SHA_H
+/** DK3 version of HAVE_OPENSSL_SHA_H.
+*/
+#define DK3_HAVE_OPENSSL_SHA_H 1
+#endif
+
+#ifndef DK3_HAVE_PNG_GET_PIXELS_PER_INCH
+/** DK3 version of HAVE_PNG_GET_PIXELS_PER_INCH.
+*/
+#define DK3_HAVE_PNG_GET_PIXELS_PER_INCH 0
+#endif
+
+#ifndef DK3_HAVE_PNG_H
+/** DK3 version of HAVE_PNG_H.
+*/
+#define DK3_HAVE_PNG_H 1
+#endif
+
+#ifndef DK3_HAVE_POPEN
+/** DK3 version of HAVE_POPEN.
+*/
+#define DK3_HAVE_POPEN 1
+#endif
+
+#ifndef DK3_HAVE_PROCESS_H
+/** DK3 version of HAVE_PROCESS_H.
+*/
+#define DK3_HAVE_PROCESS_H 0
+#endif
+
+#ifndef DK3_HAVE_PTHREAD_H
+/** DK3 version of HAVE_PTHREAD_H.
+*/
+#define DK3_HAVE_PTHREAD_H 1
+#endif
+
+#ifndef DK3_HAVE_PWD_H
+/** DK3 version of HAVE_PWD_H.
+*/
+#define DK3_HAVE_PWD_H 1
+#endif
+
+#ifndef DK3_HAVE_RAND
+/** DK3 version of HAVE_RAND.
+*/
+#define DK3_HAVE_RAND 1
+#endif
+
+#ifndef DK3_HAVE_RANDOM
+/** DK3 version of HAVE_RANDOM.
+*/
+#define DK3_HAVE_RANDOM 1
+#endif
+
+#ifndef DK3_HAVE_READ
+/** DK3 version of HAVE_READ.
+*/
+#define DK3_HAVE_READ 1
+#endif
+
+#ifndef DK3_HAVE_READDIR
+/** DK3 version of HAVE_READDIR.
+*/
+#define DK3_HAVE_READDIR 1
+#endif
+
+#ifndef DK3_HAVE_RFC_2249
+/** DK3 version of HAVE_RFC_2249.
+*/
+#define DK3_HAVE_RFC_2249 0
+#endif
+
+#ifndef DK3_HAVE_RINT
+/** DK3 version of HAVE_RINT.
+*/
+#define DK3_HAVE_RINT 1
+#endif
+
+#ifndef DK3_HAVE_RINTL
+/** DK3 version of HAVE_RINTL.
+*/
+#define DK3_HAVE_RINTL 1
+#endif
+
+#ifndef DK3_HAVE_RMDIR
+/** DK3 version of HAVE_RMDIR.
+*/
+#define DK3_HAVE_RMDIR 1
+#endif
+
+#ifndef DK3_HAVE_SEED48
+/** DK3 version of HAVE_SEED48.
+*/
+#define DK3_HAVE_SEED48 1
+#endif
+
+#ifndef DK3_HAVE_SELECT
+/** DK3 version of HAVE_SELECT.
+*/
+#define DK3_HAVE_SELECT 1
+#endif
+
+#ifndef DK3_HAVE_SETGID
+/** DK3 version of HAVE_SETGID.
+*/
+#define DK3_HAVE_SETGID 1
+#endif
+
+#ifndef DK3_HAVE_SETGRENT
+/** DK3 version of HAVE_SETGRENT.
+*/
+#define DK3_HAVE_SETGRENT 1
+#endif
+
+#ifndef DK3_HAVE_SETJMP_H
+/** DK3 version of HAVE_SETJMP_H.
+*/
+#define DK3_HAVE_SETJMP_H 1
+#endif
+
+#ifndef DK3_HAVE_SETLOCALE
+/** DK3 version of HAVE_SETLOCALE.
+*/
+#define DK3_HAVE_SETLOCALE 1
+#endif
+
+#ifndef DK3_HAVE_SETPGRP
+/** DK3 version of HAVE_SETPGRP.
+*/
+#define DK3_HAVE_SETPGRP 1
+#endif
+
+#ifndef DK3_HAVE_SETPWENT
+/** DK3 version of HAVE_SETPWENT.
+*/
+#define DK3_HAVE_SETPWENT 1
+#endif
+
+#ifndef DK3_HAVE_SETSID
+/** DK3 version of HAVE_SETSID.
+*/
+#define DK3_HAVE_SETSID 1
+#endif
+
+#ifndef DK3_HAVE_SETSOCKOPT
+/** DK3 version of HAVE_SETSOCKOPT.
+*/
+#define DK3_HAVE_SETSOCKOPT 1
+#endif
+
+#ifndef DK3_HAVE_SETSTATE
+/** DK3 version of HAVE_SETSTATE.
+*/
+#define DK3_HAVE_SETSTATE 1
+#endif
+
+#ifndef DK3_HAVE_SETUID
+/** DK3 version of HAVE_SETUID.
+*/
+#define DK3_HAVE_SETUID 1
+#endif
+
+#ifndef DK3_HAVE_SHA224
+/** DK3 version of HAVE_SHA224.
+*/
+#define DK3_HAVE_SHA224 1
+#endif
+
+#ifndef DK3_HAVE_SHA256
+/** DK3 version of HAVE_SHA256.
+*/
+#define DK3_HAVE_SHA256 1
+#endif
+
+#ifndef DK3_HAVE_SHA384
+/** DK3 version of HAVE_SHA384.
+*/
+#define DK3_HAVE_SHA384 1
+#endif
+
+#ifndef DK3_HAVE_SHA512
+/** DK3 version of HAVE_SHA512.
+*/
+#define DK3_HAVE_SHA512 1
+#endif
+
+#ifndef DK3_HAVE_SHADOW_H
+/** DK3 version of HAVE_SHADOW_H.
+*/
+#define DK3_HAVE_SHADOW_H 1
+#endif
+
+#ifndef DK3_HAVE_SIGACTION
+/** DK3 version of HAVE_SIGACTION.
+*/
+#define DK3_HAVE_SIGACTION 1
+#endif
+
+#ifndef DK3_HAVE_SIGNAL
+/** DK3 version of HAVE_SIGNAL.
+*/
+#define DK3_HAVE_SIGNAL 1
+#endif
+
+#ifndef DK3_HAVE_SIGNAL_H
+/** DK3 version of HAVE_SIGNAL_H.
+*/
+#define DK3_HAVE_SIGNAL_H 1
+#endif
+
+#ifndef DK3_HAVE_SIGSET
+/** DK3 version of HAVE_SIGSET.
+*/
+#define DK3_HAVE_SIGSET 1
+#endif
+
+#ifndef DK3_HAVE_SIG_ATOMIC_T
+/** DK3 version of HAVE_SIG_ATOMIC_T.
+*/
+#define DK3_HAVE_SIG_ATOMIC_T 1
+#endif
+
+#ifndef DK3_HAVE_SINHL
+/** DK3 version of HAVE_SINHL.
+*/
+#define DK3_HAVE_SINHL 1
+#endif
+
+#ifndef DK3_HAVE_SINL
+/** DK3 version of HAVE_SINL.
+*/
+#define DK3_HAVE_SINL 1
+#endif
+
+#ifndef DK3_HAVE_SNPRINTF
+/** DK3 version of HAVE_SNPRINTF.
+*/
+#define DK3_HAVE_SNPRINTF 1
+#endif
+
+#ifndef DK3_HAVE_SNWPRINTF
+/** DK3 version of HAVE_SNWPRINTF.
+*/
+#define DK3_HAVE_SNWPRINTF 0
+#endif
+
+#ifndef DK3_HAVE_SOCKET
+/** DK3 version of HAVE_SOCKET.
+*/
+#define DK3_HAVE_SOCKET 1
+#endif
+
+#ifndef DK3_HAVE_SOCKLEN_T
+/** DK3 version of HAVE_SOCKLEN_T.
+*/
+#define DK3_HAVE_SOCKLEN_T 1
+#endif
+
+#ifndef DK3_HAVE_SPRINTF_S
+/** DK3 version of HAVE_SPRINTF_S.
+*/
+#define DK3_HAVE_SPRINTF_S 0
+#endif
+
+#ifndef DK3_HAVE_SQRTL
+/** DK3 version of HAVE_SQRTL.
+*/
+#define DK3_HAVE_SQRTL 1
+#endif
+
+#ifndef DK3_HAVE_SRAND
+/** DK3 version of HAVE_SRAND.
+*/
+#define DK3_HAVE_SRAND 1
+#endif
+
+#ifndef DK3_HAVE_SSCANF_S
+/** DK3 version of HAVE_SSCANF_S.
+*/
+#define DK3_HAVE_SSCANF_S 0
+#endif
+
+#ifndef DK3_HAVE_SSIZE_T
+/** DK3 version of HAVE_SSIZE_T.
+*/
+#define DK3_HAVE_SSIZE_T 1
+#endif
+
+#ifndef DK3_HAVE_STAT
+/** DK3 version of HAVE_STAT.
+*/
+#define DK3_HAVE_STAT 1
+#endif
+
+#ifndef DK3_HAVE_STAT32
+/** DK3 version of HAVE_STAT32.
+*/
+#define DK3_HAVE_STAT32 0
+#endif
+
+#ifndef DK3_HAVE_STAT64
+/** DK3 version of HAVE_STAT64.
+*/
+#define DK3_HAVE_STAT64 1
+#endif
+
+#ifndef DK3_HAVE_STDARG_H
+/** DK3 version of HAVE_STDARG_H.
+*/
+#define DK3_HAVE_STDARG_H 1
+#endif
+
+#ifndef DK3_HAVE_STDDEF_H
+/** DK3 version of HAVE_STDDEF_H.
+*/
+#define DK3_HAVE_STDDEF_H 1
+#endif
+
+#ifndef DK3_HAVE_STDINT_H
+/** DK3 version of HAVE_STDINT_H.
+*/
+#define DK3_HAVE_STDINT_H 1
+#endif
+
+#ifndef DK3_HAVE_STDIO_H
+/** DK3 version of HAVE_STDIO_H.
+*/
+#define DK3_HAVE_STDIO_H 1
+#endif
+
+#ifndef DK3_HAVE_STDLIB_H
+/** DK3 version of HAVE_STDLIB_H.
+*/
+#define DK3_HAVE_STDLIB_H 1
+#endif
+
+#ifndef DK3_HAVE_STRCASECMP
+/** DK3 version of HAVE_STRCASECMP.
+*/
+#define DK3_HAVE_STRCASECMP 1
+#endif
+
+#ifndef DK3_HAVE_STRCAT
+/** DK3 version of HAVE_STRCAT.
+*/
+#define DK3_HAVE_STRCAT 1
+#endif
+
+#ifndef DK3_HAVE_STRCAT_S
+/** DK3 version of HAVE_STRCAT_S.
+*/
+#define DK3_HAVE_STRCAT_S 0
+#endif
+
+#ifndef DK3_HAVE_STRCHR
+/** DK3 version of HAVE_STRCHR.
+*/
+#define DK3_HAVE_STRCHR 1
+#endif
+
+#ifndef DK3_HAVE_STRCMP
+/** DK3 version of HAVE_STRCMP.
+*/
+#define DK3_HAVE_STRCMP 1
+#endif
+
+#ifndef DK3_HAVE_STRCPY
+/** DK3 version of HAVE_STRCPY.
+*/
+#define DK3_HAVE_STRCPY 1
+#endif
+
+#ifndef DK3_HAVE_STRCPY_S
+/** DK3 version of HAVE_STRCPY_S.
+*/
+#define DK3_HAVE_STRCPY_S 0
+#endif
+
+#ifndef DK3_HAVE_STRDUP
+/** DK3 version of HAVE_STRDUP.
+*/
+#define DK3_HAVE_STRDUP 1
+#endif
+
+#ifndef DK3_HAVE_STRERROR
+/** DK3 version of HAVE_STRERROR.
+*/
+#define DK3_HAVE_STRERROR 1
+#endif
+
+#ifndef DK3_HAVE_STRICMP
+/** DK3 version of HAVE_STRICMP.
+*/
+#define DK3_HAVE_STRICMP 0
+#endif
+
+#ifndef DK3_HAVE_STRINGS_H
+/** DK3 version of HAVE_STRINGS_H.
+*/
+#define DK3_HAVE_STRINGS_H 1
+#endif
+
+#ifndef DK3_HAVE_STRING_H
+/** DK3 version of HAVE_STRING_H.
+*/
+#define DK3_HAVE_STRING_H 1
+#endif
+
+#ifndef DK3_HAVE_STRLEN
+/** DK3 version of HAVE_STRLEN.
+*/
+#define DK3_HAVE_STRLEN 1
+#endif
+
+#ifndef DK3_HAVE_STRNCMP
+/** DK3 version of HAVE_STRNCMP.
+*/
+#define DK3_HAVE_STRNCMP 1
+#endif
+
+#ifndef DK3_HAVE_STRNCPY
+/** DK3 version of HAVE_STRNCPY.
+*/
+#define DK3_HAVE_STRNCPY 1
+#endif
+
+#ifndef DK3_HAVE_STRNCPY_S
+/** DK3 version of HAVE_STRNCPY_S.
+*/
+#define DK3_HAVE_STRNCPY_S 0
+#endif
+
+#ifndef DK3_HAVE_STROPTS_H
+/** DK3 version of HAVE_STROPTS_H.
+*/
+#define DK3_HAVE_STROPTS_H 0
+#endif
+
+#ifndef DK3_HAVE_STRRCHR
+/** DK3 version of HAVE_STRRCHR.
+*/
+#define DK3_HAVE_STRRCHR 1
+#endif
+
+#ifndef DK3_HAVE_STRTOD
+/** DK3 version of HAVE_STRTOD.
+*/
+#define DK3_HAVE_STRTOD 1
+#endif
+
+#ifndef DK3_HAVE_STRTOIMAX
+/** DK3 version of HAVE_STRTOIMAX.
+*/
+#define DK3_HAVE_STRTOIMAX 1
+#endif
+
+#ifndef DK3_HAVE_STRTOL
+/** DK3 version of HAVE_STRTOL.
+*/
+#define DK3_HAVE_STRTOL 1
+#endif
+
+#ifndef DK3_HAVE_STRTOLL
+/** DK3 version of HAVE_STRTOLL.
+*/
+#define DK3_HAVE_STRTOLL 1
+#endif
+
+#ifndef DK3_HAVE_STRTOUL
+/** DK3 version of HAVE_STRTOUL.
+*/
+#define DK3_HAVE_STRTOUL 1
+#endif
+
+#ifndef DK3_HAVE_STRTOULL
+/** DK3 version of HAVE_STRTOULL.
+*/
+#define DK3_HAVE_STRTOULL 1
+#endif
+
+#ifndef DK3_HAVE_STRTOUMAX
+/** DK3 version of HAVE_STRTOUMAX.
+*/
+#define DK3_HAVE_STRTOUMAX 1
+#endif
+
+#ifndef DK3_HAVE_STRUCT_ADDRINFO
+/** DK3 version of HAVE_STRUCT_ADDRINFO.
+*/
+#define DK3_HAVE_STRUCT_ADDRINFO 1
+#endif
+
+#ifndef DK3_HAVE_STRUCT_SOCKADDR_IN
+/** DK3 version of HAVE_STRUCT_SOCKADDR_IN.
+*/
+#define DK3_HAVE_STRUCT_SOCKADDR_IN 1
+#endif
+
+#ifndef DK3_HAVE_STRUCT_SOCKADDR_IN6
+/** DK3 version of HAVE_STRUCT_SOCKADDR_IN6.
+*/
+#define DK3_HAVE_STRUCT_SOCKADDR_IN6 1
+#endif
+
+#ifndef DK3_HAVE_STRUCT_SOCKADDR_STORAGE
+/** DK3 version of HAVE_STRUCT_SOCKADDR_STORAGE.
+*/
+#define DK3_HAVE_STRUCT_SOCKADDR_STORAGE 1
+#endif
+
+#ifndef DK3_HAVE_STRUCT_SOCKADDR_UN
+/** DK3 version of HAVE_STRUCT_SOCKADDR_UN.
+*/
+#define DK3_HAVE_STRUCT_SOCKADDR_UN 1
+#endif
+
+#ifndef DK3_HAVE_SWSCANF_S
+/** DK3 version of HAVE_SWSCANF_S.
+*/
+#define DK3_HAVE_SWSCANF_S 0
+#endif
+
+#ifndef DK3_HAVE_SYSCONF
+/** DK3 version of HAVE_SYSCONF.
+*/
+#define DK3_HAVE_SYSCONF 1
+#endif
+
+#ifndef DK3_HAVE_SYSCTL
+/** DK3 version of HAVE_SYSCTL.
+*/
+#define DK3_HAVE_SYSCTL 1
+#endif
+
+#ifndef DK3_HAVE_SYSLOG
+/** DK3 version of HAVE_SYSLOG.
+*/
+#define DK3_HAVE_SYSLOG 1
+#endif
+
+#ifndef DK3_HAVE_SYSLOG_H
+/** DK3 version of HAVE_SYSLOG_H.
+*/
+#define DK3_HAVE_SYSLOG_H 1
+#endif
+
+#ifndef DK3_HAVE_SYSRES_H
+/** DK3 version of HAVE_SYSRES_H.
+*/
+#define DK3_HAVE_SYSRES_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_FILE_H
+/** DK3 version of HAVE_SYS_FILE_H.
+*/
+#define DK3_HAVE_SYS_FILE_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_PARAM_H
+/** DK3 version of HAVE_SYS_PARAM_H.
+*/
+#define DK3_HAVE_SYS_PARAM_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_RESOURCE_H
+/** DK3 version of HAVE_SYS_RESOURCE_H.
+*/
+#define DK3_HAVE_SYS_RESOURCE_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_SOCKET_H
+/** DK3 version of HAVE_SYS_SOCKET_H.
+*/
+#define DK3_HAVE_SYS_SOCKET_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_STATVFS_H
+/** DK3 version of HAVE_SYS_STATVFS_H.
+*/
+#define DK3_HAVE_SYS_STATVFS_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_STAT_H
+/** DK3 version of HAVE_SYS_STAT_H.
+*/
+#define DK3_HAVE_SYS_STAT_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_STROPTS_H
+/** DK3 version of HAVE_SYS_STROPTS_H.
+*/
+#define DK3_HAVE_SYS_STROPTS_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_SUNDDI_H
+/** DK3 version of HAVE_SYS_SUNDDI_H.
+*/
+#define DK3_HAVE_SYS_SUNDDI_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_SYSCTL_H
+/** DK3 version of HAVE_SYS_SYSCTL_H.
+*/
+#define DK3_HAVE_SYS_SYSCTL_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_SYSTEMINFO_H
+/** DK3 version of HAVE_SYS_SYSTEMINFO_H.
+*/
+#define DK3_HAVE_SYS_SYSTEMINFO_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_TERMIOS_H
+/** DK3 version of HAVE_SYS_TERMIOS_H.
+*/
+#define DK3_HAVE_SYS_TERMIOS_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_TIME_H
+/** DK3 version of HAVE_SYS_TIME_H.
+*/
+#define DK3_HAVE_SYS_TIME_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_TTOLD_H
+/** DK3 version of HAVE_SYS_TTOLD_H.
+*/
+#define DK3_HAVE_SYS_TTOLD_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_TYPES_H
+/** DK3 version of HAVE_SYS_TYPES_H.
+*/
+#define DK3_HAVE_SYS_TYPES_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_UIO_H
+/** DK3 version of HAVE_SYS_UIO_H.
+*/
+#define DK3_HAVE_SYS_UIO_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_UN_H
+/** DK3 version of HAVE_SYS_UN_H.
+*/
+#define DK3_HAVE_SYS_UN_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_WAIT_H
+/** DK3 version of HAVE_SYS_WAIT_H.
+*/
+#define DK3_HAVE_SYS_WAIT_H 1
+#endif
+
+#ifndef DK3_HAVE_TANHL
+/** DK3 version of HAVE_TANHL.
+*/
+#define DK3_HAVE_TANHL 1
+#endif
+
+#ifndef DK3_HAVE_TANL
+/** DK3 version of HAVE_TANL.
+*/
+#define DK3_HAVE_TANL 1
+#endif
+
+#ifndef DK3_HAVE_TCFLUSH
+/** DK3 version of HAVE_TCFLUSH.
+*/
+#define DK3_HAVE_TCFLUSH 1
+#endif
+
+#ifndef DK3_HAVE_TCGETATTR
+/** DK3 version of HAVE_TCGETATTR.
+*/
+#define DK3_HAVE_TCGETATTR 1
+#endif
+
+#ifndef DK3_HAVE_TERMIOS_H
+/** DK3 version of HAVE_TERMIOS_H.
+*/
+#define DK3_HAVE_TERMIOS_H 1
+#endif
+
+#ifndef DK3_HAVE_TIFF_H
+/** DK3 version of HAVE_TIFF_H.
+*/
+#define DK3_HAVE_TIFF_H 1
+#endif
+
+#ifndef DK3_HAVE_TIME
+/** DK3 version of HAVE_TIME.
+*/
+#define DK3_HAVE_TIME 1
+#endif
+
+#ifndef DK3_HAVE_TIME_H
+/** DK3 version of HAVE_TIME_H.
+*/
+#define DK3_HAVE_TIME_H 1
+#endif
+
+#ifndef DK3_HAVE_TWOS_COMPLEMENT
+/** DK3 version of HAVE_TWOS_COMPLEMENT.
+*/
+#define DK3_HAVE_TWOS_COMPLEMENT 1
+#endif
+
+#ifndef DK3_HAVE_UMASK
+/** DK3 version of HAVE_UMASK.
+*/
+#define DK3_HAVE_UMASK 1
+#endif
+
+#ifndef DK3_HAVE_UNISTD_H
+/** DK3 version of HAVE_UNISTD_H.
+*/
+#define DK3_HAVE_UNISTD_H 1
+#endif
+
+#ifndef DK3_HAVE_UNLINK
+/** DK3 version of HAVE_UNLINK.
+*/
+#define DK3_HAVE_UNLINK 1
+#endif
+
+#ifndef DK3_HAVE_USER_NAMES_CASE_INSENSITIVE
+/** DK3 version of HAVE_USER_NAMES_CASE_INSENSITIVE.
+*/
+#define DK3_HAVE_USER_NAMES_CASE_INSENSITIVE 0
+#endif
+
+#ifndef DK3_HAVE_VARARGS_H
+/** DK3 version of HAVE_VARARGS_H.
+*/
+#define DK3_HAVE_VARARGS_H 0
+#endif
+
+#ifndef DK3_HAVE_VARARG_H
+/** DK3 version of HAVE_VARARG_H.
+*/
+#define DK3_HAVE_VARARG_H 0
+#endif
+
+#ifndef DK3_HAVE_VOLATILE
+/** DK3 version of HAVE_VOLATILE.
+*/
+#define DK3_HAVE_VOLATILE 1
+#endif
+
+#ifndef DK3_HAVE_WCHAR_H
+/** DK3 version of HAVE_WCHAR_H.
+*/
+#define DK3_HAVE_WCHAR_H 1
+#endif
+
+#ifndef DK3_HAVE_WCHAR_T
+/** DK3 version of HAVE_WCHAR_T.
+*/
+#define DK3_HAVE_WCHAR_T 1
+#endif
+
+#ifndef DK3_HAVE_WCSCAT
+/** DK3 version of HAVE_WCSCAT.
+*/
+#define DK3_HAVE_WCSCAT 1
+#endif
+
+#ifndef DK3_HAVE_WCSCAT_S
+/** DK3 version of HAVE_WCSCAT_S.
+*/
+#define DK3_HAVE_WCSCAT_S 0
+#endif
+
+#ifndef DK3_HAVE_WCSCHR
+/** DK3 version of HAVE_WCSCHR.
+*/
+#define DK3_HAVE_WCSCHR 1
+#endif
+
+#ifndef DK3_HAVE_WCSCMP
+/** DK3 version of HAVE_WCSCMP.
+*/
+#define DK3_HAVE_WCSCMP 1
+#endif
+
+#ifndef DK3_HAVE_WCSCPY
+/** DK3 version of HAVE_WCSCPY.
+*/
+#define DK3_HAVE_WCSCPY 1
+#endif
+
+#ifndef DK3_HAVE_WCSCPY_S
+/** DK3 version of HAVE_WCSCPY_S.
+*/
+#define DK3_HAVE_WCSCPY_S 0
+#endif
+
+#ifndef DK3_HAVE_WCSDUP
+/** DK3 version of HAVE_WCSDUP.
+*/
+#define DK3_HAVE_WCSDUP 1
+#endif
+
+#ifndef DK3_HAVE_WCSICMP
+/** DK3 version of HAVE_WCSICMP.
+*/
+#define DK3_HAVE_WCSICMP 0
+#endif
+
+#ifndef DK3_HAVE_WCSLEN
+/** DK3 version of HAVE_WCSLEN.
+*/
+#define DK3_HAVE_WCSLEN 1
+#endif
+
+#ifndef DK3_HAVE_WCSNCMP
+/** DK3 version of HAVE_WCSNCMP.
+*/
+#define DK3_HAVE_WCSNCMP 1
+#endif
+
+#ifndef DK3_HAVE_WCSNCPY
+/** DK3 version of HAVE_WCSNCPY.
+*/
+#define DK3_HAVE_WCSNCPY 1
+#endif
+
+#ifndef DK3_HAVE_WCSNCPY_S
+/** DK3 version of HAVE_WCSNCPY_S.
+*/
+#define DK3_HAVE_WCSNCPY_S 0
+#endif
+
+#ifndef DK3_HAVE_WCSRCHR
+/** DK3 version of HAVE_WCSRCHR.
+*/
+#define DK3_HAVE_WCSRCHR 1
+#endif
+
+#ifndef DK3_HAVE_WCSTOD
+/** DK3 version of HAVE_WCSTOD.
+*/
+#define DK3_HAVE_WCSTOD 1
+#endif
+
+#ifndef DK3_HAVE_WCSTOIMAX
+/** DK3 version of HAVE_WCSTOIMAX.
+*/
+#define DK3_HAVE_WCSTOIMAX 1
+#endif
+
+#ifndef DK3_HAVE_WCSTOL
+/** DK3 version of HAVE_WCSTOL.
+*/
+#define DK3_HAVE_WCSTOL 1
+#endif
+
+#ifndef DK3_HAVE_WCSTOLL
+/** DK3 version of HAVE_WCSTOLL.
+*/
+#define DK3_HAVE_WCSTOLL 1
+#endif
+
+#ifndef DK3_HAVE_WCSTOUL
+/** DK3 version of HAVE_WCSTOUL.
+*/
+#define DK3_HAVE_WCSTOUL 1
+#endif
+
+#ifndef DK3_HAVE_WCSTOULL
+/** DK3 version of HAVE_WCSTOULL.
+*/
+#define DK3_HAVE_WCSTOULL 1
+#endif
+
+#ifndef DK3_HAVE_WCSTOUMAX
+/** DK3 version of HAVE_WCSTOUMAX.
+*/
+#define DK3_HAVE_WCSTOUMAX 1
+#endif
+
+#ifndef DK3_HAVE_WINBASE_H
+/** DK3 version of HAVE_WINBASE_H.
+*/
+#define DK3_HAVE_WINBASE_H 0
+#endif
+
+#ifndef DK3_HAVE_WINCON_H
+/** DK3 version of HAVE_WINCON_H.
+*/
+#define DK3_HAVE_WINCON_H 0
+#endif
+
+#ifndef DK3_HAVE_WINDOWS_H
+/** DK3 version of HAVE_WINDOWS_H.
+*/
+#define DK3_HAVE_WINDOWS_H 0
+#endif
+
+#ifndef DK3_HAVE_WINREG_H
+/** DK3 version of HAVE_WINREG_H.
+*/
+#define DK3_HAVE_WINREG_H 0
+#endif
+
+#ifndef DK3_HAVE_WINSOCK2_H
+/** DK3 version of HAVE_WINSOCK2_H.
+*/
+#define DK3_HAVE_WINSOCK2_H 0
+#endif
+
+#ifndef DK3_HAVE_WRITE
+/** DK3 version of HAVE_WRITE.
+*/
+#define DK3_HAVE_WRITE 1
+#endif
+
+#ifndef DK3_HAVE_WS2TCPIP_H
+/** DK3 version of HAVE_WS2TCPIP_H.
+*/
+#define DK3_HAVE_WS2TCPIP_H 0
+#endif
+
+#ifndef DK3_HAVE_ZLIB_H
+/** DK3 version of HAVE_ZLIB_H.
+*/
+#define DK3_HAVE_ZLIB_H 1
+#endif
+
+#ifndef DK3_HAVE__CLEARFP
+/** DK3 version of HAVE__CLEARFP.
+*/
+#define DK3_HAVE__CLEARFP 0
+#endif
+
+#ifndef DK3_HAVE__FCLOSE
+/** DK3 version of HAVE__FCLOSE.
+*/
+#define DK3_HAVE__FCLOSE 0
+#endif
+
+#ifndef DK3_HAVE__FEOF
+/** DK3 version of HAVE__FEOF.
+*/
+#define DK3_HAVE__FEOF 0
+#endif
+
+#ifndef DK3_HAVE__FERROR
+/** DK3 version of HAVE__FERROR.
+*/
+#define DK3_HAVE__FERROR 0
+#endif
+
+#ifndef DK3_HAVE__FFLUSH
+/** DK3 version of HAVE__FFLUSH.
+*/
+#define DK3_HAVE__FFLUSH 0
+#endif
+
+#ifndef DK3_HAVE__FOPEN
+/** DK3 version of HAVE__FOPEN.
+*/
+#define DK3_HAVE__FOPEN 0
+#endif
+
+#ifndef DK3_HAVE__FREAD
+/** DK3 version of HAVE__FREAD.
+*/
+#define DK3_HAVE__FREAD 0
+#endif
+
+#ifndef DK3_HAVE__FWRITE
+/** DK3 version of HAVE__FWRITE.
+*/
+#define DK3_HAVE__FWRITE 0
+#endif
+
+#ifndef DK3_HAVE__GETCWD
+/** DK3 version of HAVE__GETCWD.
+*/
+#define DK3_HAVE__GETCWD 0
+#endif
+
+#ifndef DK3_HAVE__GETENV_S
+/** DK3 version of HAVE__GETENV_S.
+*/
+#define DK3_HAVE__GETENV_S 0
+#endif
+
+#ifndef DK3_HAVE__GETPID
+/** DK3 version of HAVE__GETPID.
+*/
+#define DK3_HAVE__GETPID 0
+#endif
+
+#ifndef DK3_HAVE__LSTAT
+/** DK3 version of HAVE__LSTAT.
+*/
+#define DK3_HAVE__LSTAT 0
+#endif
+
+#ifndef DK3_HAVE__LSTAT32
+/** DK3 version of HAVE__LSTAT32.
+*/
+#define DK3_HAVE__LSTAT32 0
+#endif
+
+#ifndef DK3_HAVE__LSTAT64
+/** DK3 version of HAVE__LSTAT64.
+*/
+#define DK3_HAVE__LSTAT64 0
+#endif
+
+#ifndef DK3_HAVE__MKDIR
+/** DK3 version of HAVE__MKDIR.
+*/
+#define DK3_HAVE__MKDIR 0
+#endif
+
+#ifndef DK3_HAVE__POPEN
+/** DK3 version of HAVE__POPEN.
+*/
+#define DK3_HAVE__POPEN 0
+#endif
+
+#ifndef DK3_HAVE__READ
+/** DK3 version of HAVE__READ.
+*/
+#define DK3_HAVE__READ 0
+#endif
+
+#ifndef DK3_HAVE__RMDIR
+/** DK3 version of HAVE__RMDIR.
+*/
+#define DK3_HAVE__RMDIR 0
+#endif
+
+#ifndef DK3_HAVE__SNPRINTF
+/** DK3 version of HAVE__SNPRINTF.
+*/
+#define DK3_HAVE__SNPRINTF 0
+#endif
+
+#ifndef DK3_HAVE__SNPRINTF_S
+/** DK3 version of HAVE__SNPRINTF_S.
+*/
+#define DK3_HAVE__SNPRINTF_S 0
+#endif
+
+#ifndef DK3_HAVE__SNWPRINTF
+/** DK3 version of HAVE__SNWPRINTF.
+*/
+#define DK3_HAVE__SNWPRINTF 0
+#endif
+
+#ifndef DK3_HAVE__SNWPRINTF_S
+/** DK3 version of HAVE__SNWPRINTF_S.
+*/
+#define DK3_HAVE__SNWPRINTF_S 0
+#endif
+
+#ifndef DK3_HAVE__STAT
+/** DK3 version of HAVE__STAT.
+*/
+#define DK3_HAVE__STAT 0
+#endif
+
+#ifndef DK3_HAVE__STAT32
+/** DK3 version of HAVE__STAT32.
+*/
+#define DK3_HAVE__STAT32 0
+#endif
+
+#ifndef DK3_HAVE__STAT64
+/** DK3 version of HAVE__STAT64.
+*/
+#define DK3_HAVE__STAT64 0
+#endif
+
+#ifndef DK3_HAVE__STRDUP
+/** DK3 version of HAVE__STRDUP.
+*/
+#define DK3_HAVE__STRDUP 0
+#endif
+
+#ifndef DK3_HAVE__STRICMP
+/** DK3 version of HAVE__STRICMP.
+*/
+#define DK3_HAVE__STRICMP 0
+#endif
+
+#ifndef DK3_HAVE__UNLINK
+/** DK3 version of HAVE__UNLINK.
+*/
+#define DK3_HAVE__UNLINK 0
+#endif
+
+#ifndef DK3_HAVE__WCSCAT
+/** DK3 version of HAVE__WCSCAT.
+*/
+#define DK3_HAVE__WCSCAT 0
+#endif
+
+#ifndef DK3_HAVE__WCSCHR
+/** DK3 version of HAVE__WCSCHR.
+*/
+#define DK3_HAVE__WCSCHR 0
+#endif
+
+#ifndef DK3_HAVE__WCSCMP
+/** DK3 version of HAVE__WCSCMP.
+*/
+#define DK3_HAVE__WCSCMP 0
+#endif
+
+#ifndef DK3_HAVE__WCSCPY
+/** DK3 version of HAVE__WCSCPY.
+*/
+#define DK3_HAVE__WCSCPY 0
+#endif
+
+#ifndef DK3_HAVE__WCSDUP
+/** DK3 version of HAVE__WCSDUP.
+*/
+#define DK3_HAVE__WCSDUP 0
+#endif
+
+#ifndef DK3_HAVE__WCSICMP
+/** DK3 version of HAVE__WCSICMP.
+*/
+#define DK3_HAVE__WCSICMP 0
+#endif
+
+#ifndef DK3_HAVE__WCSLEN
+/** DK3 version of HAVE__WCSLEN.
+*/
+#define DK3_HAVE__WCSLEN 0
+#endif
+
+#ifndef DK3_HAVE__WCSNCMP
+/** DK3 version of HAVE__WCSNCMP.
+*/
+#define DK3_HAVE__WCSNCMP 0
+#endif
+
+#ifndef DK3_HAVE__WCSNCPY
+/** DK3 version of HAVE__WCSNCPY.
+*/
+#define DK3_HAVE__WCSNCPY 0
+#endif
+
+#ifndef DK3_HAVE__WCSRCHR
+/** DK3 version of HAVE__WCSRCHR.
+*/
+#define DK3_HAVE__WCSRCHR 0
+#endif
+
+#ifndef DK3_HAVE__WFOPEN_S
+/** DK3 version of HAVE__WFOPEN_S.
+*/
+#define DK3_HAVE__WFOPEN_S 0
+#endif
+
+#ifndef DK3_HAVE__WGETENV
+/** DK3 version of HAVE__WGETENV.
+*/
+#define DK3_HAVE__WGETENV 0
+#endif
+
+#ifndef DK3_HAVE__WRITE
+/** DK3 version of HAVE__WRITE.
+*/
+#define DK3_HAVE__WRITE 0
+#endif
+
+#ifndef DK3_TIME_WITH_SYS_TIME
+/** DK3 version of TIME_WITH_SYS_TIME.
+*/
+#define DK3_TIME_WITH_SYS_TIME 1
+#endif
+
+#ifndef DK3_SIZEOF_DOUBLE
+/** DK3 version of SIZEOF_DOUBLE.
+*/
+#define DK3_SIZEOF_DOUBLE 8
+#endif
+
+#ifndef DK3_SIZEOF_INT
+/** DK3 version of SIZEOF_INT.
+*/
+#define DK3_SIZEOF_INT 4
+#endif
+
+#ifndef DK3_SIZEOF_INTMAX_T
+/** DK3 version of SIZEOF_INTMAX_T.
+*/
+#define DK3_SIZEOF_INTMAX_T 8
+#endif
+
+#ifndef DK3_SIZEOF_LONG
+/** DK3 version of SIZEOF_LONG.
+*/
+#define DK3_SIZEOF_LONG 4
+#endif
+
+#ifndef DK3_SIZEOF_LONG_DOUBLE
+/** DK3 version of SIZEOF_LONG_DOUBLE.
+*/
+#define DK3_SIZEOF_LONG_DOUBLE 12
+#endif
+
+#ifndef DK3_SIZEOF_LONG_LONG
+/** DK3 version of SIZEOF_LONG_LONG.
+*/
+#define DK3_SIZEOF_LONG_LONG 8
+#endif
+
+#ifndef DK3_SIZEOF_SHORT
+/** DK3 version of SIZEOF_SHORT.
+*/
+#define DK3_SIZEOF_SHORT 2
+#endif
+
+#ifndef DK3_SIZEOF_SIZE_T
+/** DK3 version of SIZEOF_SIZE_T.
+*/
+#define DK3_SIZEOF_SIZE_T 4
+#endif
+
+#ifndef DK3_SIZEOF_WCHAR_T
+/** DK3 version of SIZEOF_WCHAR_T.
+*/
+#define DK3_SIZEOF_WCHAR_T 4
+#endif
+
+#ifndef DK3_WORDS_BIGENDIAN
+/** Little-endian.
+*/
+#define DK3_WORDS_BIGENDIAN 0
+#endif
+
+#ifndef DK3_MAX_PATH
+/** Maximum path length.
+*/
+#define DK3_MAX_PATH 4097
+#endif
+
+#endif
+/* ifndef DK3_CONF_H_INCLUDED */
+
diff --git a/support/dktools/dk3conf.h b/support/dktools/dk3conf.h
new file mode 100644
index 0000000000..660e76fd09
--- /dev/null
+++ b/support/dktools/dk3conf.h
@@ -0,0 +1,4234 @@
+/** @file dk3conf.h Configuration for DK3 libraries.
+ Features: Include files, functions, sizes,
+ and endianness.
+*/
+
+#ifndef DK3_CONF_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3_CONF_H_INCLUDED 1
+
+#ifndef DK3_ON_WINDOWS
+#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
+/** On a Windows system. */
+#define DK3_ON_WINDOWS 1
+#else
+/** Not on a Windows system. */
+#define DK3_ON_WINDOWS 0
+#endif
+#endif
+/** ifndef DK3_ON_WINDOWS */
+
+#if DK3_ON_WINDOWS
+
+#ifndef DK3_HAVE_ACOSH
+/** DK3 version of HAVE_ACOSH.
+*/
+#define DK3_HAVE_ACOSH 0
+#endif
+
+#ifndef DK3_HAVE_ACOSHL
+/** DK3 version of HAVE_ACOSHL.
+*/
+#define DK3_HAVE_ACOSHL 1
+#endif
+
+#ifndef DK3_HAVE_ACOSL
+/** DK3 version of HAVE_ACOSL.
+*/
+#define DK3_HAVE_ACOSL 1
+#endif
+
+#ifndef DK3_HAVE_ALLOC_H
+/** DK3 version of HAVE_ALLOC_H.
+*/
+#define DK3_HAVE_ALLOC_H 0
+#endif
+
+#ifndef DK3_HAVE_ARPA_INET_H
+/** DK3 version of HAVE_ARPA_INET_H.
+*/
+#define DK3_HAVE_ARPA_INET_H 0
+#endif
+
+#ifndef DK3_HAVE_ASINH
+/** DK3 version of HAVE_ASINH.
+*/
+#define DK3_HAVE_ASINH 0
+#endif
+
+#ifndef DK3_HAVE_ASINHL
+/** DK3 version of HAVE_ASINHL.
+*/
+#define DK3_HAVE_ASINHL 1
+#endif
+
+#ifndef DK3_HAVE_ASINL
+/** DK3 version of HAVE_ASINL.
+*/
+#define DK3_HAVE_ASINL 1
+#endif
+
+#ifndef DK3_HAVE_ATAN2
+/** DK3 version of HAVE_ATAN2.
+*/
+#define DK3_HAVE_ATAN2 1
+#endif
+
+#ifndef DK3_HAVE_ATAN2L
+/** DK3 version of HAVE_ATAN2L.
+*/
+#define DK3_HAVE_ATAN2L 1
+#endif
+
+#ifndef DK3_HAVE_ATANH
+/** DK3 version of HAVE_ATANH.
+*/
+#define DK3_HAVE_ATANH 0
+#endif
+
+#ifndef DK3_HAVE_ATANHL
+/** DK3 version of HAVE_ATANHL.
+*/
+#define DK3_HAVE_ATANHL 1
+#endif
+
+#ifndef DK3_HAVE_ATANL
+/** DK3 version of HAVE_ATANL.
+*/
+#define DK3_HAVE_ATANL 1
+#endif
+
+#ifndef DK3_HAVE_BACKSLASH
+/** DK3 version of HAVE_BACKSLASH.
+*/
+#define DK3_HAVE_BACKSLASH 1
+#endif
+
+#ifndef DK3_HAVE_BCMP
+/** DK3 version of HAVE_BCMP.
+*/
+#define DK3_HAVE_BCMP 0
+#endif
+
+#ifndef DK3_HAVE_BCOPY
+/** DK3 version of HAVE_BCOPY.
+*/
+#define DK3_HAVE_BCOPY 0
+#endif
+
+#ifndef DK3_HAVE_BZERO
+/** DK3 version of HAVE_BZERO.
+*/
+#define DK3_HAVE_BZERO 0
+#endif
+
+#ifndef DK3_HAVE_CEIL
+/** DK3 version of HAVE_CEIL.
+*/
+#define DK3_HAVE_CEIL 1
+#endif
+
+#ifndef DK3_HAVE_CEILL
+/** DK3 version of HAVE_CEILL.
+*/
+#define DK3_HAVE_CEILL 1
+#endif
+
+#ifndef DK3_HAVE_CHDIR
+/** DK3 version of HAVE_CHDIR.
+*/
+#define DK3_HAVE_CHDIR 1
+#endif
+
+#ifndef DK3_HAVE_CHMOD
+/** DK3 version of HAVE_CHMOD.
+*/
+#define DK3_HAVE_CHMOD 0
+#endif
+
+#ifndef DK3_HAVE_CHOWN
+/** DK3 version of HAVE_CHOWN.
+*/
+#define DK3_HAVE_CHOWN 0
+#endif
+
+#ifndef DK3_HAVE_CLOSEDIR
+/** DK3 version of HAVE_CLOSEDIR.
+*/
+#define DK3_HAVE_CLOSEDIR 0
+#endif
+
+#ifndef DK3_HAVE_CONIO_H
+/** DK3 version of HAVE_CONIO_H.
+*/
+#define DK3_HAVE_CONIO_H 1
+#endif
+
+#ifndef DK3_HAVE_CONST
+/** DK3 version of HAVE_CONST.
+*/
+#define DK3_HAVE_CONST 1
+#endif
+
+#ifndef DK3_HAVE_COSHL
+/** DK3 version of HAVE_COSHL.
+*/
+#define DK3_HAVE_COSHL 1
+#endif
+
+#ifndef DK3_HAVE_COSL
+/** DK3 version of HAVE_COSL.
+*/
+#define DK3_HAVE_COSL 1
+#endif
+
+#ifndef DK3_HAVE_CTYPE_H
+/** DK3 version of HAVE_CTYPE_H.
+*/
+#define DK3_HAVE_CTYPE_H 1
+#endif
+
+#ifndef DK3_HAVE_DEV_RANDOM
+/** DK3 version of HAVE_DEV_RANDOM.
+*/
+#define DK3_HAVE_DEV_RANDOM 0
+#endif
+
+#ifndef DK3_HAVE_DEV_URANDOM
+/** DK3 version of HAVE_DEV_URANDOM.
+*/
+#define DK3_HAVE_DEV_URANDOM 0
+#endif
+
+#ifndef DK3_HAVE_DIRECT_H
+/** DK3 version of HAVE_DIRECT_H.
+*/
+#define DK3_HAVE_DIRECT_H 1
+#endif
+
+#ifndef DK3_HAVE_DIRENT_H
+/** DK3 version of HAVE_DIRENT_H.
+*/
+#define DK3_HAVE_DIRENT_H 0
+#endif
+
+#ifndef DK3_HAVE_DIR_H
+/** DK3 version of HAVE_DIR_H.
+*/
+#define DK3_HAVE_DIR_H 0
+#endif
+
+#ifndef DK3_HAVE_DOS_H
+/** DK3 version of HAVE_DOS_H.
+*/
+#define DK3_HAVE_DOS_H 1
+#endif
+
+#ifndef DK3_HAVE_ENDGRENT
+/** DK3 version of HAVE_ENDGRENT.
+*/
+#define DK3_HAVE_ENDGRENT 0
+#endif
+
+#ifndef DK3_HAVE_ENDPWENT
+/** DK3 version of HAVE_ENDPWENT.
+*/
+#define DK3_HAVE_ENDPWENT 0
+#endif
+
+#ifndef DK3_HAVE_ERRNO_H
+/** DK3 version of HAVE_ERRNO_H.
+*/
+#define DK3_HAVE_ERRNO_H 1
+#endif
+
+#ifndef DK3_HAVE_ERR_H
+/** DK3 version of HAVE_ERR_H.
+*/
+#define DK3_HAVE_ERR_H 0
+#endif
+
+#ifndef DK3_HAVE_EXPL
+/** DK3 version of HAVE_EXPL.
+*/
+#define DK3_HAVE_EXPL 1
+#endif
+
+#ifndef DK3_HAVE_FABS
+/** DK3 version of HAVE_FABS.
+*/
+#define DK3_HAVE_FABS 1
+#endif
+
+#ifndef DK3_HAVE_FABSL
+/** DK3 version of HAVE_FABSL.
+*/
+#define DK3_HAVE_FABSL 1
+#endif
+
+#ifndef DK3_HAVE_FCLOSE
+/** DK3 version of HAVE_FCLOSE.
+*/
+#define DK3_HAVE_FCLOSE 1
+#endif
+
+#ifndef DK3_HAVE_FCNTL_H
+/** DK3 version of HAVE_FCNTL_H.
+*/
+#define DK3_HAVE_FCNTL_H 1
+#endif
+
+#ifndef DK3_HAVE_FENV_H
+/** DK3 version of HAVE_FENV_H.
+*/
+#define DK3_HAVE_FENV_H 0
+#endif
+
+#ifndef DK3_HAVE_FEOF
+/** DK3 version of HAVE_FEOF.
+*/
+#define DK3_HAVE_FEOF 1
+#endif
+
+#ifndef DK3_HAVE_FERROR
+/** DK3 version of HAVE_FERROR.
+*/
+#define DK3_HAVE_FERROR 1
+#endif
+
+#ifndef DK3_HAVE_FETESTEXCEPT
+/** DK3 version of HAVE_FETESTEXCEPT.
+*/
+#define DK3_HAVE_FETESTEXCEPT 0
+#endif
+
+#ifndef DK3_HAVE_FFLUSH
+/** DK3 version of HAVE_FFLUSH.
+*/
+#define DK3_HAVE_FFLUSH 1
+#endif
+
+#ifndef DK3_HAVE_FLOAT_H
+/** DK3 version of HAVE_FLOAT_H.
+*/
+#define DK3_HAVE_FLOAT_H 1
+#endif
+
+#ifndef DK3_HAVE_FLOOR
+/** DK3 version of HAVE_FLOOR.
+*/
+#define DK3_HAVE_FLOOR 1
+#endif
+
+#ifndef DK3_HAVE_FLOORL
+/** DK3 version of HAVE_FLOORL.
+*/
+#define DK3_HAVE_FLOORL 1
+#endif
+
+#ifndef DK3_HAVE_FNCASEINS
+/** DK3 version of HAVE_FNCASEINS.
+*/
+#define DK3_HAVE_FNCASEINS 1
+#endif
+
+#ifndef DK3_HAVE_FOPEN
+/** DK3 version of HAVE_FOPEN.
+*/
+#define DK3_HAVE_FOPEN 1
+#endif
+
+#ifndef DK3_HAVE_FOPEN64
+/** DK3 version of HAVE_FOPEN64.
+*/
+#define DK3_HAVE_FOPEN64 0
+#endif
+
+#ifndef DK3_HAVE_FOPEN_S
+#if _MSC_VER >= 1700
+/** DK3 version of HAVE_FOPEN_S.
+*/
+#define DK3_HAVE_FOPEN_S 1
+#else
+/** DK3 version of HAVE_FOPEN_S.
+*/
+#define DK3_HAVE_FOPEN_S 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_FORK
+/** DK3 version of HAVE_FORK.
+*/
+#define DK3_HAVE_FORK 0
+#endif
+
+#ifndef DK3_HAVE_FPCLASSIFY
+/** DK3 version of HAVE_FPCLASSIFY.
+*/
+#define DK3_HAVE_FPCLASSIFY 0
+#endif
+
+#ifndef DK3_HAVE_FREAD
+/** DK3 version of HAVE_FREAD.
+*/
+#define DK3_HAVE_FREAD 0
+#endif
+
+#ifndef DK3_HAVE_FREE
+/** DK3 version of HAVE_FREE.
+*/
+#define DK3_HAVE_FREE 1
+#endif
+
+#ifndef DK3_HAVE_FWRITE
+/** DK3 version of HAVE_FWRITE.
+*/
+#define DK3_HAVE_FWRITE 0
+#endif
+
+#ifndef DK3_HAVE_GDBM_H
+/** DK3 version of HAVE_GDBM_H.
+*/
+#define DK3_HAVE_GDBM_H 0
+#endif
+
+#ifndef DK3_HAVE_GETADDRINFO
+/** DK3 version of HAVE_GETADDRINFO.
+*/
+#define DK3_HAVE_GETADDRINFO 1
+#endif
+
+#ifndef DK3_HAVE_GETCWD
+/** DK3 version of HAVE_GETCWD.
+*/
+#define DK3_HAVE_GETCWD 1
+#endif
+
+#ifndef DK3_HAVE_GETENV
+/** DK3 version of HAVE_GETENV.
+*/
+#define DK3_HAVE_GETENV 1
+#endif
+
+#ifndef DK3_HAVE_GETEUID
+/** DK3 version of HAVE_GETEUID.
+*/
+#define DK3_HAVE_GETEUID 0
+#endif
+
+#ifndef DK3_HAVE_GETGRENT
+/** DK3 version of HAVE_GETGRENT.
+*/
+#define DK3_HAVE_GETGRENT 0
+#endif
+
+#ifndef DK3_HAVE_GETGRGID
+/** DK3 version of HAVE_GETGRGID.
+*/
+#define DK3_HAVE_GETGRGID 0
+#endif
+
+#ifndef DK3_HAVE_GETGRNAM
+/** DK3 version of HAVE_GETGRNAM.
+*/
+#define DK3_HAVE_GETGRNAM 0
+#endif
+
+#ifndef DK3_HAVE_GETHOSTBYNAME
+/** DK3 version of HAVE_GETHOSTBYNAME.
+*/
+#define DK3_HAVE_GETHOSTBYNAME 1
+#endif
+
+#ifndef DK3_HAVE_GETHOSTNAME
+/** DK3 version of HAVE_GETHOSTNAME.
+*/
+#define DK3_HAVE_GETHOSTNAME 0
+#endif
+
+#ifndef DK3_HAVE_GETPEERNAME
+/** DK3 version of HAVE_GETPEERNAME.
+*/
+#define DK3_HAVE_GETPEERNAME 1
+#endif
+
+#ifndef DK3_HAVE_GETPID
+/** DK3 version of HAVE_GETPID.
+*/
+#define DK3_HAVE_GETPID 1
+#endif
+
+#ifndef DK3_HAVE_GETPWENT
+/** DK3 version of HAVE_GETPWENT.
+*/
+#define DK3_HAVE_GETPWENT 0
+#endif
+
+#ifndef DK3_HAVE_GETPWNAM
+/** DK3 version of HAVE_GETPWNAM.
+*/
+#define DK3_HAVE_GETPWNAM 0
+#endif
+
+#ifndef DK3_HAVE_GETPWUID
+/** DK3 version of HAVE_GETPWUID.
+*/
+#define DK3_HAVE_GETPWUID 0
+#endif
+
+#ifndef DK3_HAVE_GETRLIMIT
+/** DK3 version of HAVE_GETRLIMIT.
+*/
+#define DK3_HAVE_GETRLIMIT 0
+#endif
+
+#ifndef DK3_HAVE_GETSOCKNAME
+/** DK3 version of HAVE_GETSOCKNAME.
+*/
+#define DK3_HAVE_GETSOCKNAME 1
+#endif
+
+#ifndef DK3_HAVE_GETUID
+/** DK3 version of HAVE_GETUID.
+*/
+#define DK3_HAVE_GETUID 0
+#endif
+
+#ifndef DK3_HAVE_GRP_H
+/** DK3 version of HAVE_GRP_H.
+*/
+#define DK3_HAVE_GRP_H 0
+#endif
+
+#ifndef DK3_HAVE_HTONL
+/** DK3 version of HAVE_HTONL.
+*/
+#define DK3_HAVE_HTONL 1
+#endif
+
+#ifndef DK3_HAVE_IEEE_754_DOUBLE
+/** DK3 version of HAVE_IEEE_754_DOUBLE.
+*/
+#define DK3_HAVE_IEEE_754_DOUBLE 1
+#endif
+
+#ifndef DK3_HAVE_IN6_ADDR
+/** DK3 version of HAVE_IN6_ADDR.
+*/
+#define DK3_HAVE_IN6_ADDR 1
+#endif
+
+#ifndef DK3_HAVE_INET_ADDR
+/** DK3 version of HAVE_INET_ADDR.
+*/
+#define DK3_HAVE_INET_ADDR 0
+#endif
+
+#ifndef DK3_HAVE_INET_ATON
+/** DK3 version of HAVE_INET_ATON.
+*/
+#define DK3_HAVE_INET_ATON 0
+#endif
+
+#ifndef DK3_HAVE_INET_PTON
+/** DK3 version of HAVE_INET_PTON.
+*/
+#define DK3_HAVE_INET_PTON 0
+#endif
+
+#ifndef DK3_HAVE_INITSTATE
+/** DK3 version of HAVE_INITSTATE.
+*/
+#define DK3_HAVE_INITSTATE 0
+#endif
+
+#ifndef DK3_HAVE_INODES
+/** DK3 version of HAVE_INODES.
+*/
+#define DK3_HAVE_INODES 0
+#endif
+
+#ifndef DK3_HAVE_INTMAX_T
+#if _MSC_VER >= 1700
+/** DK3 version of HAVE_INTMAX_T.
+*/
+#define DK3_HAVE_INTMAX_T 1
+#else
+/** DK3 version of HAVE_INTMAX_T.
+*/
+#define DK3_HAVE_INTMAX_T 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_INTTYPES_H
+/** DK3 version of HAVE_INTTYPES_H.
+*/
+#define DK3_HAVE_INTTYPES_H 0
+#endif
+
+#ifndef DK3_HAVE_IN_ADDR
+/** DK3 version of HAVE_IN_ADDR.
+*/
+#define DK3_HAVE_IN_ADDR 1
+#endif
+
+#ifndef DK3_HAVE_IO_H
+/** DK3 version of HAVE_IO_H.
+*/
+#define DK3_HAVE_IO_H 1
+#endif
+
+#ifndef DK3_HAVE_ISATTY
+/** DK3 version of HAVE_ISATTY.
+*/
+#define DK3_HAVE_ISATTY 1
+#endif
+
+#ifndef DK3_HAVE_ISFINITE
+/** DK3 version of HAVE_ISFINITE.
+*/
+#define DK3_HAVE_ISFINITE 0
+#endif
+
+#ifndef DK3_HAVE_ISNORMAL
+/** DK3 version of HAVE_ISNORMAL.
+*/
+#define DK3_HAVE_ISNORMAL 0
+#endif
+
+#ifndef DK3_HAVE_LABS
+/** DK3 version of HAVE_LABS.
+*/
+#define DK3_HAVE_LABS 1
+#endif
+
+#ifndef DK3_HAVE_LARGEFILE64_SOURCE
+/** DK3 version of HAVE_LARGEFILE64_SOURCE.
+*/
+#define DK3_HAVE_LARGEFILE64_SOURCE 0
+#endif
+
+#ifndef DK3_HAVE_LIMITS_H
+/** DK3 version of HAVE_LIMITS_H.
+*/
+#define DK3_HAVE_LIMITS_H 1
+#endif
+
+#ifndef DK3_HAVE_LOCALE_H
+/** DK3 version of HAVE_LOCALE_H.
+*/
+#define DK3_HAVE_LOCALE_H 1
+#endif
+
+#ifndef DK3_HAVE_LOCALTIME
+/** DK3 version of HAVE_LOCALTIME.
+*/
+#define DK3_HAVE_LOCALTIME 1
+#endif
+
+#ifndef DK3_HAVE_LOCALTIME
+/** DK3 version of HAVE_LOCALTIME.
+*/
+#define DK3_HAVE_LOCALTIME 1
+#endif
+
+#ifndef DK3_HAVE_LOCALTIME_R
+/** DK3 version of HAVE_LOCALTIME_R.
+*/
+#define DK3_HAVE_LOCALTIME_R 0
+#endif
+
+#ifndef DK3_HAVE_LOCALTIME_S
+#if _MSC_VER >= 1700
+/** DK3 version of HAVE_LOCALTIME_S.
+*/
+#define DK3_HAVE_LOCALTIME_S 1
+#else
+/** DK3 version of HAVE_LOCALTIME_S.
+*/
+#define DK3_HAVE_LOCALTIME_S 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_LOGL
+/** DK3 version of HAVE_LOGL.
+*/
+#define DK3_HAVE_LOGL 1
+#endif
+
+#ifndef DK3_HAVE_LONG_DOUBLE
+/** DK3 version of HAVE_LONG_DOUBLE.
+*/
+#define DK3_HAVE_LONG_DOUBLE 1
+#endif
+
+#ifndef DK3_HAVE_LONG_LONG
+/** DK3 version of HAVE_LONG_LONG.
+*/
+#define DK3_HAVE_LONG_LONG 1
+#endif
+
+#ifndef DK3_HAVE_LRAND48
+/** DK3 version of HAVE_LRAND48.
+*/
+#define DK3_HAVE_LRAND48 0
+#endif
+
+#ifndef DK3_HAVE_LSTAT
+/** DK3 version of HAVE_LSTAT.
+*/
+#define DK3_HAVE_LSTAT 1
+#endif
+
+#ifndef DK3_HAVE_LSTAT32
+/** DK3 version of HAVE_LSTAT32.
+*/
+#define DK3_HAVE_LSTAT32 1
+#endif
+
+#ifndef DK3_HAVE_LSTAT64
+/** DK3 version of HAVE_LSTAT64.
+*/
+#define DK3_HAVE_LSTAT64 1
+#endif
+
+#ifndef DK3_HAVE_MALLOC
+/** DK3 version of HAVE_MALLOC.
+*/
+#define DK3_HAVE_MALLOC 1
+#endif
+
+#ifndef DK3_HAVE_MALLOC_H
+/** DK3 version of HAVE_MALLOC_H.
+*/
+#define DK3_HAVE_MALLOC_H 1
+#endif
+
+#ifndef DK3_HAVE_MATH_H
+/** DK3 version of HAVE_MATH_H.
+*/
+#define DK3_HAVE_MATH_H 1
+#endif
+
+#ifndef DK3_HAVE_MEMCMP
+/** DK3 version of HAVE_MEMCMP.
+*/
+#define DK3_HAVE_MEMCMP 1
+#endif
+
+#ifndef DK3_HAVE_MEMCPY
+/** DK3 version of HAVE_MEMCPY.
+*/
+#define DK3_HAVE_MEMCPY 1
+#endif
+
+#ifndef DK3_HAVE_MEMSET
+/** DK3 version of HAVE_MEMSET.
+*/
+#define DK3_HAVE_MEMSET 1
+#endif
+
+#ifndef DK3_HAVE_MKDIR
+/** DK3 version of HAVE_MKDIR.
+*/
+#define DK3_HAVE_MKDIR 0
+#endif
+
+#ifndef DK3_HAVE_MKDIR2
+/** DK3 version of HAVE_MKDIR2.
+*/
+#define DK3_HAVE_MKDIR2 0
+#endif
+
+#ifndef DK3_HAVE_MPCTL
+/** DK3 version of HAVE_MPCTL.
+*/
+#define DK3_HAVE_MPCTL 0
+#endif
+
+#ifndef DK3_HAVE_NDBM_H
+/** DK3 version of HAVE_NDBM_H.
+*/
+#define DK3_HAVE_NDBM_H 0
+#endif
+
+#ifndef DK3_HAVE_NETDB_H
+/** DK3 version of HAVE_NETDB_H.
+*/
+#define DK3_HAVE_NETDB_H 0
+#endif
+
+#ifndef DK3_HAVE_NETINET_IN_H
+/** DK3 version of HAVE_NETINET_IN_H.
+*/
+#define DK3_HAVE_NETINET_IN_H 0
+#endif
+
+#ifndef DK3_HAVE_NRAND48
+/** DK3 version of HAVE_NRAND48.
+*/
+#define DK3_HAVE_NRAND48 0
+#endif
+
+#ifndef DK3_HAVE_OPENDIR
+/** DK3 version of HAVE_OPENDIR.
+*/
+#define DK3_HAVE_OPENDIR 0
+#endif
+
+#ifndef DK3_HAVE_PNG_GET_PIXELS_PER_INCH
+/** DK3 version of HAVE_PNG_GET_PIXELS_PER_INCH.
+*/
+#define DK3_HAVE_PNG_GET_PIXELS_PER_INCH 1
+#endif
+
+#ifndef DK3_HAVE_POPEN
+/** DK3 version of HAVE_POPEN.
+*/
+#define DK3_HAVE_POPEN 0
+#endif
+
+#ifndef DK3_HAVE_PROCESS_H
+/** DK3 version of HAVE_PROCESS_H.
+*/
+#define DK3_HAVE_PROCESS_H 1
+#endif
+
+#ifndef DK3_HAVE_PTHREAD_H
+/** DK3 version of HAVE_PTHREAD_H.
+*/
+#define DK3_HAVE_PTHREAD_H 0
+#endif
+
+#ifndef DK3_HAVE_PWD_H
+/** DK3 version of HAVE_PWD_H.
+*/
+#define DK3_HAVE_PWD_H 0
+#endif
+
+#ifndef DK3_HAVE_RAND
+/** DK3 version of HAVE_RAND.
+*/
+#define DK3_HAVE_RAND 0
+#endif
+
+#ifndef DK3_HAVE_RANDOM
+/** DK3 version of HAVE_RANDOM.
+*/
+#define DK3_HAVE_RANDOM 0
+#endif
+
+#ifndef DK3_HAVE_READ
+/** DK3 version of HAVE_READ.
+*/
+#define DK3_HAVE_READ 1
+#endif
+
+#ifndef DK3_HAVE_READDIR
+/** DK3 version of HAVE_READDIR.
+*/
+#define DK3_HAVE_READDIR 0
+#endif
+
+#ifndef DK3_HAVE_RFC_2249
+/** DK3 version of HAVE_RFC_2249.
+*/
+#define DK3_HAVE_RFC_2249 0
+#endif
+
+#ifndef DK3_HAVE_RINT
+/** DK3 version of HAVE_RINT.
+*/
+#define DK3_HAVE_RINT 0
+#endif
+
+#ifndef DK3_HAVE_RINTL
+/** DK3 version of HAVE_RINTL.
+*/
+#define DK3_HAVE_RINTL 1
+#endif
+
+#ifndef DK3_HAVE_RMDIR
+/** DK3 version of HAVE_RMDIR.
+*/
+#define DK3_HAVE_RMDIR 0
+#endif
+
+#ifndef DK3_HAVE_SEED48
+/** DK3 version of HAVE_SEED48.
+*/
+#define DK3_HAVE_SEED48 0
+#endif
+
+#ifndef DK3_HAVE_SELECT
+/** DK3 version of HAVE_SELECT.
+*/
+#define DK3_HAVE_SELECT 1
+#endif
+
+#ifndef DK3_HAVE_SETGID
+/** DK3 version of HAVE_SETGID.
+*/
+#define DK3_HAVE_SETGID 0
+#endif
+
+#ifndef DK3_HAVE_SETGRENT
+/** DK3 version of HAVE_SETGRENT.
+*/
+#define DK3_HAVE_SETGRENT 0
+#endif
+
+#ifndef DK3_HAVE_SETJMP_H
+/** DK3 version of HAVE_SETJMP_H.
+*/
+#define DK3_HAVE_SETJMP_H 1
+#endif
+
+#ifndef DK3_HAVE_SETPGRP
+/** DK3 version of HAVE_SETPGRP.
+*/
+#define DK3_HAVE_SETPGRP 0
+#endif
+
+#ifndef DK3_HAVE_SETPWENT
+/** DK3 version of HAVE_SETPWENT.
+*/
+#define DK3_HAVE_SETPWENT 0
+#endif
+
+#ifndef DK3_HAVE_SETSID
+/** DK3 version of HAVE_SETSID.
+*/
+#define DK3_HAVE_SETSID 0
+#endif
+
+#ifndef DK3_HAVE_SETSOCKOPT
+/** DK3 version of HAVE_SETSOCKOPT.
+*/
+#define DK3_HAVE_SETSOCKOPT 1
+#endif
+
+#ifndef DK3_HAVE_SETSTATE
+/** DK3 version of HAVE_SETSTATE.
+*/
+#define DK3_HAVE_SETSTATE 0
+#endif
+
+#ifndef DK3_HAVE_SETUID
+/** DK3 version of HAVE_SETUID.
+*/
+#define DK3_HAVE_SETUID 0
+#endif
+
+#ifndef DK3_HAVE_SETVBUF
+/** DK3 version of HAVE_SETVBUF.
+*/
+#define DK3_HAVE_SETVBUF 1
+#endif
+
+#ifndef DK3_HAVE_SHADOW_H
+/** DK3 version of HAVE_SHADOW_H.
+*/
+#define DK3_HAVE_SHADOW_H 0
+#endif
+
+#ifndef DK3_HAVE_SIGACTION
+/** DK3 version of HAVE_SIGACTION.
+*/
+#define DK3_HAVE_SIGACTION 0
+#endif
+
+#ifndef DK3_HAVE_SIGNAL
+/** DK3 version of HAVE_SIGNAL.
+*/
+#define DK3_HAVE_SIGNAL 1
+#endif
+
+#ifndef DK3_HAVE_SIGNAL_H
+/** DK3 version of HAVE_SIGNAL_H.
+*/
+#define DK3_HAVE_SIGNAL_H 1
+#endif
+
+#ifndef DK3_HAVE_SIGSET
+/** DK3 version of HAVE_SIGSET.
+*/
+#define DK3_HAVE_SIGSET 0
+#endif
+
+#ifndef DK3_HAVE_SIG_ATOMIC_T
+/** DK3 version of HAVE_SIG_ATOMIC_T.
+*/
+#define DK3_HAVE_SIG_ATOMIC_T 0
+#endif
+
+#ifndef DK3_HAVE_SINHL
+/** DK3 version of HAVE_SINHL.
+*/
+#define DK3_HAVE_SINHL 1
+#endif
+
+#ifndef DK3_HAVE_SINL
+/** DK3 version of HAVE_SINL.
+*/
+#define DK3_HAVE_SINL 1
+#endif
+
+#ifndef DK3_HAVE_SNPRINTF
+/** DK3 version of HAVE_SNPRINTF.
+*/
+#define DK3_HAVE_SNPRINTF 0
+#endif
+
+#ifndef DK3_HAVE_SOCKET
+/** DK3 version of HAVE_SOCKET.
+*/
+#define DK3_HAVE_SOCKET 1
+#endif
+
+#ifndef DK3_HAVE_SOCKLEN_T
+/** DK3 version of HAVE_SOCKLEN_T.
+*/
+#define DK3_HAVE_SOCKLEN_T 0
+#endif
+
+#ifndef DK3_HAVE_SPRINTF_S
+#if _MSC_VER >= 1700
+/** DK3 version of HAVE_SPRINTF_S.
+*/
+#define DK3_HAVE_SPRINTF_S 1
+#else
+/** DK3 version of HAVE_SPRINTF_S.
+*/
+#define DK3_HAVE_SPRINTF_S 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_SQRTL
+/** DK3 version of HAVE_SQRTL.
+*/
+#define DK3_HAVE_SQRTL 1
+#endif
+
+#ifndef DK3_HAVE_SRAND
+/** DK3 version of HAVE_SRAND.
+*/
+#define DK3_HAVE_SRAND 0
+#endif
+
+#ifndef DK3_HAVE_SSCANF_S
+#if _MSC_VER >= 1700
+/** DK3 version of HAVE_SSCANF_S.
+*/
+#define DK3_HAVE_SSCANF_S 1
+#else
+/** DK3 version of HAVE_SSCANF_S.
+*/
+#define DK3_HAVE_SSCANF_S 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_SSIZE_T
+/** DK3 version of HAVE_SSIZE_T.
+*/
+#define DK3_HAVE_SSIZE_T 0
+#endif
+
+#ifndef DK3_HAVE_STAT
+/** DK3 version of HAVE_STAT.
+*/
+#define DK3_HAVE_STAT 1
+#endif
+
+#ifndef DK3_HAVE_STAT32
+/** DK3 version of HAVE_STAT32.
+*/
+#define DK3_HAVE_STAT32 1
+#endif
+
+#ifndef DK3_HAVE_STAT64
+/** DK3 version of HAVE_STAT64.
+*/
+#define DK3_HAVE_STAT64 1
+#endif
+
+#ifndef DK3_HAVE_STDARG_H
+/** DK3 version of HAVE_STDARG_H.
+*/
+#define DK3_HAVE_STDARG_H 1
+#endif
+
+#ifndef DK3_HAVE_STDDEF_H
+/** DK3 version of HAVE_STDDEF_H.
+*/
+#define DK3_HAVE_STDDEF_H 1
+#endif
+
+#ifndef DK3_HAVE_STDINT_H
+#if _MSC_VER >= 1700
+/** DK3 version of HAVE_STDINT_H.
+*/
+#define DK3_HAVE_STDINT_H 1
+#else
+/** DK3 version of HAVE_STDINT_H.
+*/
+#define DK3_HAVE_STDINT_H 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_STDIO_H
+/** DK3 version of HAVE_STDIO_H.
+*/
+#define DK3_HAVE_STDIO_H 1
+#endif
+
+#ifndef DK3_HAVE_STDLIB_H
+/** DK3 version of HAVE_STDLIB_H.
+*/
+#define DK3_HAVE_STDLIB_H 1
+#endif
+
+#ifndef DK3_HAVE_STRCASECMP
+/** DK3 version of HAVE_STRCASECMP.
+*/
+#define DK3_HAVE_STRCASECMP 0
+#endif
+
+#ifndef DK3_HAVE_STRCAT
+/** DK3 version of HAVE_STRCAT.
+*/
+#define DK3_HAVE_STRCAT 1
+#endif
+
+#ifndef DK3_HAVE_STRCAT_S
+#if _MSC_VER >= 1700
+/** DK3 version of HAVE_STRCAT_S.
+*/
+#define DK3_HAVE_STRCAT_S 1
+#else
+/** DK3 version of HAVE_STRCAT_S.
+*/
+#define DK3_HAVE_STRCAT_S 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRCHR
+/** DK3 version of HAVE_STRCHR.
+*/
+#define DK3_HAVE_STRCHR 1
+#endif
+
+#ifndef DK3_HAVE_STRCMP
+/** DK3 version of HAVE_STRCMP.
+*/
+#define DK3_HAVE_STRCMP 1
+#endif
+
+#ifndef DK3_HAVE_STRCPY
+/** DK3 version of HAVE_STRCPY.
+*/
+#define DK3_HAVE_STRCPY 1
+#endif
+
+#ifndef DK3_HAVE_STRCPY_S
+#if _MSC_VER >= 1700
+/** DK3 version of HAVE_STRCPY_S.
+*/
+#define DK3_HAVE_STRCPY_S 1
+#else
+/** DK3 version of HAVE_STRCPY_S.
+*/
+#define DK3_HAVE_STRCPY_S 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRDUP
+/** DK3 version of HAVE_STRDUP.
+*/
+#define DK3_HAVE_STRDUP 0
+#endif
+
+#ifndef DK3_HAVE_STRERROR
+/** DK3 version of HAVE_STRERROR.
+*/
+#define DK3_HAVE_STRERROR 1
+#endif
+
+#ifndef DK3_HAVE_STRICMP
+/** DK3 version of HAVE_STRICMP.
+*/
+#define DK3_HAVE_STRICMP 0
+#endif
+
+#ifndef DK3_HAVE_STRINGS_H
+/** DK3 version of HAVE_STRINGS_H.
+*/
+#define DK3_HAVE_STRINGS_H 0
+#endif
+
+#ifndef DK3_HAVE_STRING_H
+/** DK3 version of HAVE_STRING_H.
+*/
+#define DK3_HAVE_STRING_H 1
+#endif
+
+#ifndef DK3_HAVE_STRLEN
+/** DK3 version of HAVE_STRLEN.
+*/
+#define DK3_HAVE_STRLEN 1
+#endif
+
+#ifndef DK3_HAVE_STRNCMP
+/** DK3 version of HAVE_STRNCMP.
+*/
+#define DK3_HAVE_STRNCMP 1
+#endif
+
+#ifndef DK3_HAVE_STRNCPY
+/** DK3 version of HAVE_STRNCPY.
+*/
+#define DK3_HAVE_STRNCPY 1
+#endif
+
+#ifndef DK3_HAVE_STRNCPY_S
+#if _MSC_VER >= 1700
+/** DK3 version of HAVE_STRNCPY_S.
+*/
+#define DK3_HAVE_STRNCPY_S 1
+#else
+/** DK3 version of HAVE_STRNCPY_S.
+*/
+#define DK3_HAVE_STRNCPY_S 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_STROPTS_H
+/** DK3 version of HAVE_STROPTS_H.
+*/
+#define DK3_HAVE_STROPTS_H 0
+#endif
+
+#ifndef DK3_HAVE_STRRCHR
+/** DK3 version of HAVE_STRRCHR.
+*/
+#define DK3_HAVE_STRRCHR 1
+#endif
+
+#ifndef DK3_HAVE_STRTOD
+/** DK3 version of HAVE_STRTOD.
+*/
+#define DK3_HAVE_STRTOD 1
+#endif
+
+#ifndef DK3_HAVE_STRTOIMAX
+#if _MSC_VER >= 1800
+/** DK3 version of HAVE_STRTOIMAX.
+*/
+#define DK3_HAVE_STRTOIMAX 1
+#else
+/** DK3 version of HAVE_STRTOIMAX.
+*/
+#define DK3_HAVE_STRTOIMAX 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRTOL
+#if _MSC_VER >= 1700
+/** DK3 version of HAVE_STRTOL.
+*/
+#define DK3_HAVE_STRTOL 1
+#else
+/** DK3 version of HAVE_STRTOL.
+*/
+#define DK3_HAVE_STRTOL 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRTOLL
+#if _MSC_VER >= 1700
+/** DK3 version of HAVE_STRTOLL.
+*/
+#define DK3_HAVE_STRTOLL 1
+#else
+/** DK3 version of HAVE_STRTOLL.
+*/
+#define DK3_HAVE_STRTOLL 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRTOUL
+#if _MSC_VER >= 1700
+/** DK3 version of HAVE_STRTOUL.
+*/
+#define DK3_HAVE_STRTOUL 1
+#else
+/** DK3 version of HAVE_STRTOUL.
+*/
+#define DK3_HAVE_STRTOUL 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRTOULL
+#if _MSC_VER >= 1700
+/** DK3 version of HAVE_STRTOULL.
+*/
+#define DK3_HAVE_STRTOULL 1
+#else
+/** DK3 version of HAVE_STRTOULL.
+*/
+#define DK3_HAVE_STRTOULL 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRTOUMAX
+#if _MSC_VER >= 1800
+/** DK3 version of HAVE_STRTOUMAX.
+*/
+#define DK3_HAVE_STRTOUMAX 1
+#else
+/** DK3 version of HAVE_STRTOUMAX.
+*/
+#define DK3_HAVE_STRTOUMAX 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRUCT_ADDRINFO
+/** DK3 version of HAVE_STRUCT_ADDRINFO.
+*/
+#define DK3_HAVE_STRUCT_ADDRINFO 0
+#endif
+
+#ifndef DK3_HAVE_STRUCT_SOCKADDR_IN
+/** DK3 version of HAVE_STRUCT_SOCKADDR_IN.
+*/
+#define DK3_HAVE_STRUCT_SOCKADDR_IN 1
+#endif
+
+#ifndef DK3_HAVE_STRUCT_SOCKADDR_IN6
+/** DK3 version of HAVE_STRUCT_SOCKADDR_IN6.
+*/
+#define DK3_HAVE_STRUCT_SOCKADDR_IN6 1
+#endif
+
+#ifndef DK3_HAVE_STRUCT_SOCKADDR_STORAGE
+/** DK3 version of HAVE_STRUCT_SOCKADDR_STORAGE.
+*/
+#define DK3_HAVE_STRUCT_SOCKADDR_STORAGE 0
+#endif
+
+#ifndef DK3_HAVE_STRUCT_SOCKADDR_UN
+/** DK3 version of HAVE_STRUCT_SOCKADDR_UN.
+*/
+#define DK3_HAVE_STRUCT_SOCKADDR_UN 0
+#endif
+
+#ifndef DK3_HAVE_SWSCANF_S
+#if _MSC_VER >= 1700
+/** DK3 version of HAVE_SWSCANF_S.
+*/
+#define DK3_HAVE_SWSCANF_S 1
+#else
+/** DK3 version of HAVE_SWSCANF_S.
+*/
+#define DK3_HAVE_SWSCANF_S 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_SYSCONF
+/** DK3 version of HAVE_SYSCONF.
+*/
+#define DK3_HAVE_SYSCONF 0
+#endif
+
+#ifndef DK3_HAVE_SYSCTL
+/** DK3 version of HAVE_SYSCTL.
+*/
+#define DK3_HAVE_SYSCTL 0
+#endif
+
+#ifndef DK3_HAVE_SYSLOG
+/** DK3 version of HAVE_SYSLOG.
+*/
+#define DK3_HAVE_SYSLOG 0
+#endif
+
+#ifndef DK3_HAVE_SYSLOG_H
+/** DK3 version of HAVE_SYSLOG_H.
+*/
+#define DK3_HAVE_SYSLOG_H 0
+#endif
+
+#ifndef DK3_HAVE_SYSRES_H
+/** DK3 version of HAVE_SYSRES_H.
+*/
+#define DK3_HAVE_SYSRES_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_FILE_H
+/** DK3 version of HAVE_SYS_FILE_H.
+*/
+#define DK3_HAVE_SYS_FILE_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_PARAM_H
+/** DK3 version of HAVE_SYS_PARAM_H.
+*/
+#define DK3_HAVE_SYS_PARAM_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_RESOURCE_H
+/** DK3 version of HAVE_SYS_RESOURCE_H.
+*/
+#define DK3_HAVE_SYS_RESOURCE_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_SOCKET_H
+/** DK3 version of HAVE_SYS_SOCKET_H.
+*/
+#define DK3_HAVE_SYS_SOCKET_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_STATVFS_H
+/** DK3 version of HAVE_SYS_STATVFS_H.
+*/
+#define DK3_HAVE_SYS_STATVFS_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_STAT_H
+/** DK3 version of HAVE_SYS_STAT_H.
+*/
+#define DK3_HAVE_SYS_STAT_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_STROPTS_H
+/** DK3 version of HAVE_SYS_STROPTS_H.
+*/
+#define DK3_HAVE_SYS_STROPTS_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_SUNDDI_H
+/** DK3 version of HAVE_SYS_SUNDDI_H.
+*/
+#define DK3_HAVE_SYS_SUNDDI_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_SYSCTL_H
+/** DK3 version of HAVE_SYS_SYSCTL_H.
+*/
+#define DK3_HAVE_SYS_SYSCTL_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_SYSTEMINFO_H
+/** DK3 version of HAVE_SYS_SYSTEMINFO_H.
+*/
+#define DK3_HAVE_SYS_SYSTEMINFO_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_TERMIOS_H
+/** DK3 version of HAVE_SYS_TERMIOS_H.
+*/
+#define DK3_HAVE_SYS_TERMIOS_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_TIME_H
+/** DK3 version of HAVE_SYS_TIME_H.
+*/
+#define DK3_HAVE_SYS_TIME_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_TTOLD_H
+/** DK3 version of HAVE_SYS_TTOLD_H.
+*/
+#define DK3_HAVE_SYS_TTOLD_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_TYPES_H
+/** DK3 version of HAVE_SYS_TYPES_H.
+*/
+#define DK3_HAVE_SYS_TYPES_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_UIO_H
+/** DK3 version of HAVE_SYS_UIO_H.
+*/
+#define DK3_HAVE_SYS_UIO_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_UN_H
+/** DK3 version of HAVE_SYS_UN_H.
+*/
+#define DK3_HAVE_SYS_UN_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_WAIT_H
+/** DK3 version of HAVE_SYS_WAIT_H.
+*/
+#define DK3_HAVE_SYS_WAIT_H 0
+#endif
+
+#ifndef DK3_HAVE_TANHL
+/** DK3 version of HAVE_TANHL.
+*/
+#define DK3_HAVE_TANHL 1
+#endif
+
+#ifndef DK3_HAVE_TANL
+/** DK3 version of HAVE_TANL.
+*/
+#define DK3_HAVE_TANL 1
+#endif
+
+#ifndef DK3_HAVE_TCFLUSH
+/** DK3 version of HAVE_TCFLUSH.
+*/
+#define DK3_HAVE_TCFLUSH 0
+#endif
+
+#ifndef DK3_HAVE_TCGETATTR
+/** DK3 version of HAVE_TCGETATTR.
+*/
+#define DK3_HAVE_TCGETATTR 0
+#endif
+
+#ifndef DK3_HAVE_TERMIOS_H
+/** DK3 version of HAVE_TERMIOS_H.
+*/
+#define DK3_HAVE_TERMIOS_H 0
+#endif
+
+#ifndef DK3_HAVE_TIME
+/** DK3 version of HAVE_TIME.
+*/
+#define DK3_HAVE_TIME 1
+#endif
+
+#ifndef DK3_HAVE_TIME_H
+/** DK3 version of HAVE_TIME_H.
+*/
+#define DK3_HAVE_TIME_H 1
+#endif
+
+#ifndef DK3_HAVE_TWOS_COMPLEMENT
+/** DK3 version of HAVE_TWOS_COMPLEMENT.
+*/
+#define DK3_HAVE_TWOS_COMPLEMENT 1
+#endif
+
+#ifndef DK3_HAVE_UMASK
+/** DK3 version of HAVE_UMASK.
+*/
+#define DK3_HAVE_UMASK 0
+#endif
+
+#ifndef DK3_HAVE_UNISTD_H
+/** DK3 version of HAVE_UNISTD_H.
+*/
+#define DK3_HAVE_UNISTD_H 0
+#endif
+
+#ifndef DK3_HAVE_UNLINK
+/** DK3 version of HAVE_UNLINK.
+*/
+#define DK3_HAVE_UNLINK 0
+#endif
+
+#ifndef DK3_HAVE_USER_NAMES_CASE_INSENSITIVE
+/** DK3 version of HAVE_USER_NAMES_CASE_INSENSITIVE.
+*/
+#define DK3_HAVE_USER_NAMES_CASE_INSENSITIVE 1
+#endif
+
+#ifndef DK3_HAVE_VARARGS_H
+/** DK3 version of HAVE_VARARGS_H.
+*/
+#define DK3_HAVE_VARARGS_H 0
+#endif
+
+#ifndef DK3_HAVE_VARARG_H
+/** DK3 version of HAVE_VARARG_H.
+*/
+#define DK3_HAVE_VARARG_H 0
+#endif
+
+#ifndef DK3_HAVE_VOLATILE
+/** DK3 version of HAVE_VOLATILE.
+*/
+#define DK3_HAVE_VOLATILE 1
+#endif
+
+#ifndef DK3_HAVE_WCHAR_H
+/** DK3 version of HAVE_WCHAR_H.
+*/
+#define DK3_HAVE_WCHAR_H 1
+#endif
+
+#ifndef DK3_HAVE_WCHAR_T
+/** DK3 version of HAVE_WCHAR_T.
+*/
+#define DK3_HAVE_WCHAR_T 1
+#endif
+
+#ifndef DK3_HAVE_WCSCAT
+/** DK3 version of HAVE_WCSCAT.
+*/
+#define DK3_HAVE_WCSCAT 1
+#endif
+
+#ifndef DK3_HAVE_WCSCAT_S
+#if _MSC_VER >= 1700
+/** DK3 version of HAVE_WCSCAT_S.
+*/
+#define DK3_HAVE_WCSCAT_S 1
+#else
+/** DK3 version of HAVE_WCSCAT_S.
+*/
+#define DK3_HAVE_WCSCAT_S 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCSCHR
+/** DK3 version of HAVE_WCSCHR.
+*/
+#define DK3_HAVE_WCSCHR 1
+#endif
+
+#ifndef DK3_HAVE_WCSCMP
+/** DK3 version of HAVE_WCSCMP.
+*/
+#define DK3_HAVE_WCSCMP 1
+#endif
+
+#ifndef DK3_HAVE_WCSCPY
+/** DK3 version of HAVE_WCSCPY.
+*/
+#define DK3_HAVE_WCSCPY 1
+#endif
+
+#ifndef DK3_HAVE_WCSCPY_S
+#if _MSC_VER >= 1700
+/** DK3 version of HAVE_WCSCPY_S.
+*/
+#define DK3_HAVE_WCSCPY_S 1
+#else
+/** DK3 version of HAVE_WCSCPY_S.
+*/
+#define DK3_HAVE_WCSCPY_S 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCSDUP
+/** DK3 version of HAVE_WCSDUP.
+*/
+#define DK3_HAVE_WCSDUP 0
+#endif
+
+#ifndef DK3_HAVE_WCSICMP
+/** DK3 version of HAVE_WCSICMP.
+*/
+#define DK3_HAVE_WCSICMP 0
+#endif
+
+#ifndef DK3_HAVE_WCSLEN
+/** DK3 version of HAVE_WCSLEN.
+*/
+#define DK3_HAVE_WCSLEN 1
+#endif
+
+#ifndef DK3_HAVE_WCSNCMP
+/** DK3 version of HAVE_WCSNCMP.
+*/
+#define DK3_HAVE_WCSNCMP 1
+#endif
+
+#ifndef DK3_HAVE_WCSNCPY
+/** DK3 version of HAVE_WCSNCPY.
+*/
+#define DK3_HAVE_WCSNCPY 1
+#endif
+
+#ifndef DK3_HAVE_WCSNCPY_S
+#if _MSC_VER >= 1700
+/** DK3 version of HAVE_WCSNCPY_S.
+*/
+#define DK3_HAVE_WCSNCPY_S 1
+#else
+/** DK3 version of HAVE_WCSNCPY_S.
+*/
+#define DK3_HAVE_WCSNCPY_S 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCSRCHR
+/** DK3 version of HAVE_WCSRCHR.
+*/
+#define DK3_HAVE_WCSRCHR 1
+#endif
+
+#ifndef DK3_HAVE_WCSTOD
+/** DK3 version of HAVE_WCSTOD.
+*/
+#define DK3_HAVE_WCSTOD 1
+#endif
+
+#ifndef DK3_HAVE_WCSTOIMAX
+#if _MSC_VER >= 1800
+/** DK3 version of HAVE_WCSTOIMAX.
+*/
+#define DK3_HAVE_WCSTOIMAX 1
+#else
+/** DK3 version of HAVE_WCSTOIMAX.
+*/
+#define DK3_HAVE_WCSTOIMAX 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCSTOL
+#if _MSC_VER >= 1700
+/** DK3 version of HAVE_WCSTOL.
+*/
+#define DK3_HAVE_WCSTOL 1
+#else
+/** DK3 version of HAVE_WCSTOL.
+*/
+#define DK3_HAVE_WCSTOL 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCSTOLL
+#if _MSC_VER >= 1700
+/** DK3 version of HAVE_WCSTOLL.
+*/
+#define DK3_HAVE_WCSTOLL 1
+#else
+/** DK3 version of HAVE_WCSTOLL.
+*/
+#define DK3_HAVE_WCSTOLL 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCSTOUL
+#if _MSC_VER >= 1700
+/** DK3 version of HAVE_WCSTOUL.
+*/
+#define DK3_HAVE_WCSTOUL 1
+#else
+/** DK3 version of HAVE_WCSTOUL.
+*/
+#define DK3_HAVE_WCSTOUL 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCSTOULL
+#if _MSC_VER >= 1700
+/** DK3 version of HAVE_WCSTOULL.
+*/
+#define DK3_HAVE_WCSTOULL 1
+#else
+/** DK3 version of HAVE_WCSTOULL.
+*/
+#define DK3_HAVE_WCSTOULL 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCSTOUMAX
+#if _MSC_VER >= 1800
+/** DK3 version of HAVE_WCSTOUMAX.
+*/
+#define DK3_HAVE_WCSTOUMAX 1
+#else
+/** DK3 version of HAVE_WCSTOUMAX.
+*/
+#define DK3_HAVE_WCSTOUMAX 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_WINBASE_H
+/** DK3 version of HAVE_WINBASE_H.
+*/
+#define DK3_HAVE_WINBASE_H 1
+#endif
+
+#ifndef DK3_HAVE_WINCON_H
+/** DK3 version of HAVE_WINCON_H.
+*/
+#define DK3_HAVE_WINCON_H 1
+#endif
+
+#ifndef DK3_HAVE_WINDOWS_H
+/** DK3 version of HAVE_WINDOWS_H.
+*/
+#define DK3_HAVE_WINDOWS_H 1
+#endif
+
+#ifndef DK3_HAVE_WINREG_H
+/** DK3 version of HAVE_WINREG_H.
+*/
+#define DK3_HAVE_WINREG_H 1
+#endif
+
+#ifndef DK3_HAVE_WINSOCK2_H
+/** DK3 version of HAVE_WINSOCK2_H.
+*/
+#define DK3_HAVE_WINSOCK2_H 1
+#endif
+
+#ifndef DK3_HAVE_WRITE
+/** DK3 version of HAVE_WRITE.
+*/
+#define DK3_HAVE_WRITE 1
+#endif
+
+#ifndef DK3_HAVE_WS2TCPIP_H
+/** DK3 version of HAVE_WS2TCPIP_H.
+*/
+#define DK3_HAVE_WS2TCPIP_H 1
+#endif
+
+#ifndef DK3_HAVE__CLEARFP
+#if _MSC_VER >= 1700
+/** DK3 version of HAVE__CLEARFP.
+*/
+#define DK3_HAVE__CLEARFP 1
+#else
+/** DK3 version of HAVE__CLEARFP.
+*/
+#define DK3_HAVE__CLEARFP 0
+#endif
+#endif
+
+#ifndef DK3_HAVE__FCLOSE
+/** DK3 version of HAVE__FCLOSE.
+*/
+#define DK3_HAVE__FCLOSE 0
+#endif
+
+#ifndef DK3_HAVE__FEOF
+/** DK3 version of HAVE__FEOF.
+*/
+#define DK3_HAVE__FEOF 0
+#endif
+
+#ifndef DK3_HAVE__FERROR
+/** DK3 version of HAVE__FERROR.
+*/
+#define DK3_HAVE__FERROR 0
+#endif
+
+#ifndef DK3_HAVE__FFLUSH
+/** DK3 version of HAVE__FFLUSH.
+*/
+#define DK3_HAVE__FFLUSH 0
+#endif
+
+#ifndef DK3_HAVE__FOPEN
+/** DK3 version of HAVE__FOPEN.
+*/
+#define DK3_HAVE__FOPEN 0
+#endif
+
+#ifndef DK3_HAVE__FREAD
+/** DK3 version of HAVE__FREAD.
+*/
+#define DK3_HAVE__FREAD 1
+#endif
+
+#ifndef DK3_HAVE__FWRITE
+/** DK3 version of HAVE__FWRITE.
+*/
+#define DK3_HAVE__FWRITE 1
+#endif
+
+#ifndef DK3_HAVE__GETCWD
+/** DK3 version of HAVE__GETCWD.
+*/
+#define DK3_HAVE__GETCWD 0
+#endif
+
+#ifndef DK3_HAVE__GETENV_S
+#if _MSC_VER >= 1700
+/** DK3 version of HAVE__GETENV_S.
+*/
+#define DK3_HAVE__GETENV_S 1
+#else
+/** DK3 version of HAVE__GETENV_S.
+*/
+#define DK3_HAVE__GETENV_S 0
+#endif
+#endif
+
+#ifndef DK3_HAVE__GETPID
+/** DK3 version of HAVE__GETPID.
+*/
+#define DK3_HAVE__GETPID 0
+#endif
+
+#ifndef DK3_HAVE__LSTAT
+/** DK3 version of HAVE__LSTAT.
+*/
+#define DK3_HAVE__LSTAT 0
+#endif
+
+#ifndef DK3_HAVE__LSTAT32
+/** DK3 version of HAVE__LSTAT32.
+*/
+#define DK3_HAVE__LSTAT32 0
+#endif
+
+#ifndef DK3_HAVE__LSTAT64
+/** DK3 version of HAVE__LSTAT64.
+*/
+#define DK3_HAVE__LSTAT64 0
+#endif
+
+#ifndef DK3_HAVE__MKDIR
+/** DK3 version of HAVE__MKDIR.
+*/
+#define DK3_HAVE__MKDIR 1
+#endif
+
+#ifndef DK3_HAVE__POPEN
+/** DK3 version of HAVE__POPEN.
+*/
+#define DK3_HAVE__POPEN 1
+#endif
+
+#ifndef DK3_HAVE__READ
+/** DK3 version of HAVE__READ.
+*/
+#define DK3_HAVE__READ 0
+#endif
+
+#ifndef DK3_HAVE__RMDIR
+/** DK3 version of HAVE__RMDIR.
+*/
+#define DK3_HAVE__RMDIR 1
+#endif
+
+#ifndef DK3_HAVE__SNPRINTF
+/** DK3 version of HAVE__SNPRINTF.
+*/
+#define DK3_HAVE__SNPRINTF 1
+#endif
+
+#ifndef DK3_HAVE__SNPRINTF_S
+#if _MSC_VER >= 1
+/** DK3 version of HAVE__SNPRINTF_S.
+*/
+#define DK3_HAVE__SNPRINTF_S 1
+#else
+/** DK3 version of HAVE__SNPRINTF_S.
+*/
+#define DK3_HAVE__SNPRINTF_S 0
+#endif
+#endif
+
+#ifndef DK3_HAVE__STAT
+/** DK3 version of HAVE__STAT.
+*/
+#define DK3_HAVE__STAT 0
+#endif
+
+#ifndef DK3_HAVE__STAT32
+/** DK3 version of HAVE__STAT32.
+*/
+#define DK3_HAVE__STAT32 0
+#endif
+
+#ifndef DK3_HAVE__STAT64
+/** DK3 version of HAVE__STAT64.
+*/
+#define DK3_HAVE__STAT64 0
+#endif
+
+#ifndef DK3_HAVE__STRDUP
+/** DK3 version of HAVE__STRDUP.
+*/
+#define DK3_HAVE__STRDUP 1
+#endif
+
+#ifndef DK3_HAVE__STRICMP
+/** DK3 version of HAVE__STRICMP.
+*/
+#define DK3_HAVE__STRICMP 1
+#endif
+
+#ifndef DK3_HAVE__UNLINK
+/** DK3 version of HAVE__UNLINK.
+*/
+#define DK3_HAVE__UNLINK 1
+#endif
+
+#ifndef DK3_HAVE__WCSCAT
+/** DK3 version of HAVE__WCSCAT.
+*/
+#define DK3_HAVE__WCSCAT 0
+#endif
+
+#ifndef DK3_HAVE__WCSCHR
+/** DK3 version of HAVE__WCSCHR.
+*/
+#define DK3_HAVE__WCSCHR 0
+#endif
+
+#ifndef DK3_HAVE__WCSCMP
+/** DK3 version of HAVE__WCSCMP.
+*/
+#define DK3_HAVE__WCSCMP 0
+#endif
+
+#ifndef DK3_HAVE__WCSCPY
+/** DK3 version of HAVE__WCSCPY.
+*/
+#define DK3_HAVE__WCSCPY 0
+#endif
+
+#ifndef DK3_HAVE__WCSDUP
+/** DK3 version of HAVE__WCSDUP.
+*/
+#define DK3_HAVE__WCSDUP 1
+#endif
+
+#ifndef DK3_HAVE__WCSICMP
+/** DK3 version of HAVE__WCSICMP.
+*/
+#define DK3_HAVE__WCSICMP 1
+#endif
+
+#ifndef DK3_HAVE__WCSLEN
+/** DK3 version of HAVE__WCSLEN.
+*/
+#define DK3_HAVE__WCSLEN 0
+#endif
+
+#ifndef DK3_HAVE__WCSNCMP
+/** DK3 version of HAVE__WCSNCMP.
+*/
+#define DK3_HAVE__WCSNCMP 0
+#endif
+
+#ifndef DK3_HAVE__WCSNCPY
+/** DK3 version of HAVE__WCSNCPY.
+*/
+#define DK3_HAVE__WCSNCPY 0
+#endif
+
+#ifndef DK3_HAVE__WCSRCHR
+/** DK3 version of HAVE__WCSRCHR.
+*/
+#define DK3_HAVE__WCSRCHR 0
+#endif
+
+#ifndef DK3_HAVE__WFOPEN_S
+#if _MSC_VER >= 1700
+/** DK3 version of HAVE__WFOPEN_S.
+*/
+#define DK3_HAVE__WFOPEN_S 1
+#else
+/** DK3 version of HAVE__WFOPEN_S.
+*/
+#define DK3_HAVE__WFOPEN_S 0
+#endif
+#endif
+
+#ifndef DK3_HAVE__WGETENV
+/** DK3 version of HAVE__WGETENV.
+*/
+#define DK3_HAVE__WGETENV 1
+#endif
+
+#ifndef DK3_HAVE__WRITE
+/** DK3 version of HAVE__WRITE.
+*/
+#define DK3_HAVE__WRITE 0
+#endif
+
+#ifndef DK3_TIME_WITH_SYS_TIME
+/** DK3 version of TIME_WITH_SYS_TIME.
+*/
+#define DK3_TIME_WITH_SYS_TIME 0
+#endif
+
+#ifndef DK3_SIZEOF_DOUBLE
+/** DK3 version of SIZEOF_DOUBLE.
+*/
+#define DK3_SIZEOF_DOUBLE 8
+#endif
+
+#ifndef DK3_SIZEOF_INT
+/** DK3 version of SIZEOF_INT.
+*/
+#define DK3_SIZEOF_INT 4
+#endif
+
+#ifndef DK3_SIZEOF_INTMAX_T
+#if _MSC_VER >= 1700
+/** DK3 version of SIZEOF_INTMAX_T.
+*/
+#define DK3_SIZEOF_INTMAX_T 8
+#else
+/** DK3 version of SIZEOF_INTMAX_T.
+*/
+#define DK3_SIZEOF_INTMAX_T 0
+#endif
+#endif
+
+#ifndef DK3_SIZEOF_LONG
+/** DK3 version of SIZEOF_LONG.
+*/
+#define DK3_SIZEOF_LONG 4
+#endif
+
+#ifndef DK3_SIZEOF_LONG_DOUBLE
+/** DK3 version of SIZEOF_LONG_DOUBLE.
+*/
+#define DK3_SIZEOF_LONG_DOUBLE 8
+#endif
+
+#ifndef DK3_SIZEOF_LONG_LONG
+/** DK3 version of SIZEOF_LONG_LONG.
+*/
+#define DK3_SIZEOF_LONG_LONG 8
+#endif
+
+#ifndef DK3_SIZEOF_SHORT
+/** DK3 version of SIZEOF_SHORT.
+*/
+#define DK3_SIZEOF_SHORT 2
+#endif
+
+#if defined(WIN64) || defined(_WIN64)
+#ifndef DK3_SIZEOF_SIZE_T
+/** DK3 version of SIZEOF_SIZE_T.
+*/
+#define DK3_SIZEOF_SIZE_T 8
+#endif
+#else
+#ifndef DK3_SIZEOF_SIZE_T
+/** DK3 version of SIZEOF_SIZE_T.
+*/
+#define DK3_SIZEOF_SIZE_T 4
+#endif
+#endif
+
+#ifndef DK3_SIZEOF_WCHAR_T
+/** DK3 version of SIZEOF_WCHAR_T.
+*/
+#define DK3_SIZEOF_WCHAR_T 2
+#endif
+
+#ifndef DK3_HAVE_RFC_2279
+/** DK3 version of HAVE_RFC_2279.
+*/
+#define DK3_HAVE_RFC_2279 0
+#endif
+
+#ifndef DK3_WORDS_BIGENDIAN
+/** DK3 version of WORDS_BIGENDIAN.
+*/
+#define DK3_WORDS_BIGENDIAN 0
+#endif
+
+#else
+/* if DK3_ON_WINDOWS */
+
+
+#ifndef DK3_HAVE_ACOSH
+/** DK3 version of HAVE_ACOSH.
+*/
+#define DK3_HAVE_ACOSH 1
+#endif
+
+#ifndef DK3_HAVE_ACOSHL
+/** DK3 version of HAVE_ACOSHL.
+*/
+#define DK3_HAVE_ACOSHL 1
+#endif
+
+#ifndef DK3_HAVE_ACOSL
+/** DK3 version of HAVE_ACOSL.
+*/
+#define DK3_HAVE_ACOSL 1
+#endif
+
+#ifndef DK3_HAVE_ALLOC_H
+/** DK3 version of HAVE_ALLOC_H.
+*/
+#define DK3_HAVE_ALLOC_H 0
+#endif
+
+#ifndef DK3_HAVE_ARPA_INET_H
+/** DK3 version of HAVE_ARPA_INET_H.
+*/
+#define DK3_HAVE_ARPA_INET_H 1
+#endif
+
+#ifndef DK3_HAVE_ASINH
+/** DK3 version of HAVE_ASINH.
+*/
+#define DK3_HAVE_ASINH 1
+#endif
+
+#ifndef DK3_HAVE_ASINHL
+/** DK3 version of HAVE_ASINHL.
+*/
+#define DK3_HAVE_ASINHL 1
+#endif
+
+#ifndef DK3_HAVE_ASINL
+/** DK3 version of HAVE_ASINL.
+*/
+#define DK3_HAVE_ASINL 1
+#endif
+
+#ifndef DK3_HAVE_ATAN2
+/** DK3 version of HAVE_ATAN2.
+*/
+#define DK3_HAVE_ATAN2 1
+#endif
+
+#ifndef DK3_HAVE_ATAN2L
+/** DK3 version of HAVE_ATAN2L.
+*/
+#define DK3_HAVE_ATAN2L 1
+#endif
+
+#ifndef DK3_HAVE_ATANH
+/** DK3 version of HAVE_ATANH.
+*/
+#define DK3_HAVE_ATANH 1
+#endif
+
+#ifndef DK3_HAVE_ATANHL
+/** DK3 version of HAVE_ATANHL.
+*/
+#define DK3_HAVE_ATANHL 1
+#endif
+
+#ifndef DK3_HAVE_ATANL
+/** DK3 version of HAVE_ATANL.
+*/
+#define DK3_HAVE_ATANL 1
+#endif
+
+#ifndef DK3_HAVE_BACKSLASH
+/** DK3 version of HAVE_BACKSLASH.
+*/
+#define DK3_HAVE_BACKSLASH 0
+#endif
+
+#ifndef DK3_HAVE_BCMP
+/** DK3 version of HAVE_BCMP.
+*/
+#define DK3_HAVE_BCMP 1
+#endif
+
+#ifndef DK3_HAVE_BCOPY
+/** DK3 version of HAVE_BCOPY.
+*/
+#define DK3_HAVE_BCOPY 1
+#endif
+
+#ifndef DK3_HAVE_BZERO
+/** DK3 version of HAVE_BZERO.
+*/
+#define DK3_HAVE_BZERO 1
+#endif
+
+#ifndef DK3_HAVE_BZLIB_H
+/** DK3 version of HAVE_BZLIB_H.
+*/
+#define DK3_HAVE_BZLIB_H 1
+#endif
+
+#ifndef DK3_HAVE_CEIL
+/** DK3 version of HAVE_CEIL.
+*/
+#define DK3_HAVE_CEIL 1
+#endif
+
+#ifndef DK3_HAVE_CEILL
+/** DK3 version of HAVE_CEILL.
+*/
+#define DK3_HAVE_CEILL 1
+#endif
+
+#ifndef DK3_HAVE_CHDIR
+/** DK3 version of HAVE_CHDIR.
+*/
+#define DK3_HAVE_CHDIR 1
+#endif
+
+#ifndef DK3_HAVE_CHMOD
+/** DK3 version of HAVE_CHMOD.
+*/
+#define DK3_HAVE_CHMOD 1
+#endif
+
+#ifndef DK3_HAVE_CHOWN
+/** DK3 version of HAVE_CHOWN.
+*/
+#define DK3_HAVE_CHOWN 1
+#endif
+
+#ifndef DK3_HAVE_CLOSEDIR
+/** DK3 version of HAVE_CLOSEDIR.
+*/
+#define DK3_HAVE_CLOSEDIR 1
+#endif
+
+#ifndef DK3_HAVE_CONIO_H
+/** DK3 version of HAVE_CONIO_H.
+*/
+#define DK3_HAVE_CONIO_H 0
+#endif
+
+#ifndef DK3_HAVE_CONST
+/** DK3 version of HAVE_CONST.
+*/
+#define DK3_HAVE_CONST 1
+#endif
+
+#ifndef DK3_HAVE_COSHL
+/** DK3 version of HAVE_COSHL.
+*/
+#define DK3_HAVE_COSHL 1
+#endif
+
+#ifndef DK3_HAVE_COSL
+/** DK3 version of HAVE_COSL.
+*/
+#define DK3_HAVE_COSL 1
+#endif
+
+#ifndef DK3_HAVE_CTYPE_H
+/** DK3 version of HAVE_CTYPE_H.
+*/
+#define DK3_HAVE_CTYPE_H 1
+#endif
+
+#ifndef DK3_HAVE_DB_CURSOR_C_GET
+/** DK3 version of HAVE_DB_CURSOR_C_GET.
+*/
+#define DK3_HAVE_DB_CURSOR_C_GET 1
+#endif
+
+#ifndef DK3_HAVE_DB_H
+/** DK3 version of HAVE_DB_H.
+*/
+#define DK3_HAVE_DB_H 1
+#endif
+
+#ifndef DK3_HAVE_DEV_RANDOM
+/** DK3 version of HAVE_DEV_RANDOM.
+*/
+#define DK3_HAVE_DEV_RANDOM 1
+#endif
+
+#ifndef DK3_HAVE_DEV_URANDOM
+/** DK3 version of HAVE_DEV_URANDOM.
+*/
+#define DK3_HAVE_DEV_URANDOM 1
+#endif
+
+#ifndef DK3_HAVE_DIRECT_H
+/** DK3 version of HAVE_DIRECT_H.
+*/
+#define DK3_HAVE_DIRECT_H 0
+#endif
+
+#ifndef DK3_HAVE_DIRENT_H
+/** DK3 version of HAVE_DIRENT_H.
+*/
+#define DK3_HAVE_DIRENT_H 1
+#endif
+
+#ifndef DK3_HAVE_DIR_H
+/** DK3 version of HAVE_DIR_H.
+*/
+#define DK3_HAVE_DIR_H 0
+#endif
+
+#ifndef DK3_HAVE_DOS_H
+/** DK3 version of HAVE_DOS_H.
+*/
+#define DK3_HAVE_DOS_H 0
+#endif
+
+#ifndef DK3_HAVE_ENDGRENT
+/** DK3 version of HAVE_ENDGRENT.
+*/
+#define DK3_HAVE_ENDGRENT 1
+#endif
+
+#ifndef DK3_HAVE_ENDPWENT
+/** DK3 version of HAVE_ENDPWENT.
+*/
+#define DK3_HAVE_ENDPWENT 1
+#endif
+
+#ifndef DK3_HAVE_ERRNO_H
+/** DK3 version of HAVE_ERRNO_H.
+*/
+#define DK3_HAVE_ERRNO_H 1
+#endif
+
+#ifndef DK3_HAVE_ERR_H
+/** DK3 version of HAVE_ERR_H.
+*/
+#define DK3_HAVE_ERR_H 1
+#endif
+
+#ifndef DK3_HAVE_EXPL
+/** DK3 version of HAVE_EXPL.
+*/
+#define DK3_HAVE_EXPL 1
+#endif
+
+#ifndef DK3_HAVE_FABS
+/** DK3 version of HAVE_FABS.
+*/
+#define DK3_HAVE_FABS 1
+#endif
+
+#ifndef DK3_HAVE_FABSL
+/** DK3 version of HAVE_FABSL.
+*/
+#define DK3_HAVE_FABSL 1
+#endif
+
+#ifndef DK3_HAVE_FCLOSE
+/** DK3 version of HAVE_FCLOSE.
+*/
+#define DK3_HAVE_FCLOSE 1
+#endif
+
+#ifndef DK3_HAVE_FCNTL_H
+/** DK3 version of HAVE_FCNTL_H.
+*/
+#define DK3_HAVE_FCNTL_H 1
+#endif
+
+#ifndef DK3_HAVE_FENV_H
+/** DK3 version of HAVE_FENV_H.
+*/
+#define DK3_HAVE_FENV_H 1
+#endif
+
+#ifndef DK3_HAVE_FEOF
+/** DK3 version of HAVE_FEOF.
+*/
+#define DK3_HAVE_FEOF 1
+#endif
+
+#ifndef DK3_HAVE_FERROR
+/** DK3 version of HAVE_FERROR.
+*/
+#define DK3_HAVE_FERROR 1
+#endif
+
+#ifndef DK3_HAVE_FETESTEXCEPT
+/** DK3 version of HAVE_FETESTEXCEPT.
+*/
+#define DK3_HAVE_FETESTEXCEPT 0
+#endif
+
+#ifndef DK3_HAVE_FFLUSH
+/** DK3 version of HAVE_FFLUSH.
+*/
+#define DK3_HAVE_FFLUSH 1
+#endif
+
+#ifndef DK3_HAVE_FLOAT_H
+/** DK3 version of HAVE_FLOAT_H.
+*/
+#define DK3_HAVE_FLOAT_H 1
+#endif
+
+#ifndef DK3_HAVE_FLOOR
+/** DK3 version of HAVE_FLOOR.
+*/
+#define DK3_HAVE_FLOOR 1
+#endif
+
+#ifndef DK3_HAVE_FLOORL
+/** DK3 version of HAVE_FLOORL.
+*/
+#define DK3_HAVE_FLOORL 1
+#endif
+
+#ifndef DK3_HAVE_FNCASEINS
+/** DK3 version of HAVE_FNCASEINS.
+*/
+#define DK3_HAVE_FNCASEINS 0
+#endif
+
+#ifndef DK3_HAVE_FOPEN
+/** DK3 version of HAVE_FOPEN.
+*/
+#define DK3_HAVE_FOPEN 1
+#endif
+
+#ifndef DK3_HAVE_FOPEN64
+/** DK3 version of HAVE_FOPEN64.
+*/
+#define DK3_HAVE_FOPEN64 1
+#endif
+
+#ifndef DK3_HAVE_FOPEN_S
+/** DK3 version of HAVE_FOPEN_S.
+*/
+#define DK3_HAVE_FOPEN_S 0
+#endif
+
+#ifndef DK3_HAVE_FORK
+/** DK3 version of HAVE_FORK.
+*/
+#define DK3_HAVE_FORK 1
+#endif
+
+#ifndef DK3_HAVE_FPCLASSIFY
+/** DK3 version of HAVE_FPCLASSIFY.
+*/
+#define DK3_HAVE_FPCLASSIFY 1
+#endif
+
+#ifndef DK3_HAVE_FREAD
+/** DK3 version of HAVE_FREAD.
+*/
+#define DK3_HAVE_FREAD 1
+#endif
+
+#ifndef DK3_HAVE_FREE
+/** DK3 version of HAVE_FREE.
+*/
+#define DK3_HAVE_FREE 1
+#endif
+
+#ifndef DK3_HAVE_FWRITE
+/** DK3 version of HAVE_FWRITE.
+*/
+#define DK3_HAVE_FWRITE 1
+#endif
+
+#ifndef DK3_HAVE_GDBM_H
+/** DK3 version of HAVE_GDBM_H.
+*/
+#define DK3_HAVE_GDBM_H 0
+#endif
+
+#ifndef DK3_HAVE_GETADDRINFO
+/** DK3 version of HAVE_GETADDRINFO.
+*/
+#define DK3_HAVE_GETADDRINFO 1
+#endif
+
+#ifndef DK3_HAVE_GETCWD
+/** DK3 version of HAVE_GETCWD.
+*/
+#define DK3_HAVE_GETCWD 1
+#endif
+
+#ifndef DK3_HAVE_GETENV
+/** DK3 version of HAVE_GETENV.
+*/
+#define DK3_HAVE_GETENV 1
+#endif
+
+#ifndef DK3_HAVE_GETEUID
+/** DK3 version of HAVE_GETEUID.
+*/
+#define DK3_HAVE_GETEUID 1
+#endif
+
+#ifndef DK3_HAVE_GETGRENT
+/** DK3 version of HAVE_GETGRENT.
+*/
+#define DK3_HAVE_GETGRENT 1
+#endif
+
+#ifndef DK3_HAVE_GETGRGID
+/** DK3 version of HAVE_GETGRGID.
+*/
+#define DK3_HAVE_GETGRGID 1
+#endif
+
+#ifndef DK3_HAVE_GETGRNAM
+/** DK3 version of HAVE_GETGRNAM.
+*/
+#define DK3_HAVE_GETGRNAM 1
+#endif
+
+#ifndef DK3_HAVE_GETHOSTBYNAME
+/** DK3 version of HAVE_GETHOSTBYNAME.
+*/
+#define DK3_HAVE_GETHOSTBYNAME 1
+#endif
+
+#ifndef DK3_HAVE_GETHOSTNAME
+/** DK3 version of HAVE_GETHOSTNAME.
+*/
+#define DK3_HAVE_GETHOSTNAME 1
+#endif
+
+#ifndef DK3_HAVE_GETPEERNAME
+/** DK3 version of HAVE_GETPEERNAME.
+*/
+#define DK3_HAVE_GETPEERNAME 1
+#endif
+
+#ifndef DK3_HAVE_GETPID
+/** DK3 version of HAVE_GETPID.
+*/
+#define DK3_HAVE_GETPID 1
+#endif
+
+#ifndef DK3_HAVE_GETPWENT
+/** DK3 version of HAVE_GETPWENT.
+*/
+#define DK3_HAVE_GETPWENT 1
+#endif
+
+#ifndef DK3_HAVE_GETPWNAM
+/** DK3 version of HAVE_GETPWNAM.
+*/
+#define DK3_HAVE_GETPWNAM 1
+#endif
+
+#ifndef DK3_HAVE_GETPWUID
+/** DK3 version of HAVE_GETPWUID.
+*/
+#define DK3_HAVE_GETPWUID 1
+#endif
+
+#ifndef DK3_HAVE_GETRLIMIT
+/** DK3 version of HAVE_GETRLIMIT.
+*/
+#define DK3_HAVE_GETRLIMIT 1
+#endif
+
+#ifndef DK3_HAVE_GETSOCKNAME
+/** DK3 version of HAVE_GETSOCKNAME.
+*/
+#define DK3_HAVE_GETSOCKNAME 1
+#endif
+
+#ifndef DK3_HAVE_GETUID
+/** DK3 version of HAVE_GETUID.
+*/
+#define DK3_HAVE_GETUID 1
+#endif
+
+#ifndef DK3_HAVE_GRP_H
+/** DK3 version of HAVE_GRP_H.
+*/
+#define DK3_HAVE_GRP_H 1
+#endif
+
+#ifndef DK3_HAVE_HTONL
+/** DK3 version of HAVE_HTONL.
+*/
+#define DK3_HAVE_HTONL 1
+#endif
+
+#ifndef DK3_HAVE_IEEE_754_DOUBLE
+/** DK3 version of HAVE_IEEE_754_DOUBLE.
+*/
+#define DK3_HAVE_IEEE_754_DOUBLE 1
+#endif
+
+#ifndef DK3_HAVE_IN6_ADDR
+/** DK3 version of HAVE_IN6_ADDR.
+*/
+#define DK3_HAVE_IN6_ADDR 0
+#endif
+
+#ifndef DK3_HAVE_INET_ADDR
+/** DK3 version of HAVE_INET_ADDR.
+*/
+#define DK3_HAVE_INET_ADDR 1
+#endif
+
+#ifndef DK3_HAVE_INET_ATON
+/** DK3 version of HAVE_INET_ATON.
+*/
+#define DK3_HAVE_INET_ATON 1
+#endif
+
+#ifndef DK3_HAVE_INET_PTON
+/** DK3 version of HAVE_INET_PTON.
+*/
+#define DK3_HAVE_INET_PTON 1
+#endif
+
+#ifndef DK3_HAVE_INITSTATE
+/** DK3 version of HAVE_INITSTATE.
+*/
+#define DK3_HAVE_INITSTATE 1
+#endif
+
+#ifndef DK3_HAVE_INODES
+/** DK3 version of HAVE_INODES.
+*/
+#define DK3_HAVE_INODES 1
+#endif
+
+#ifndef DK3_HAVE_INTMAX_T
+/** DK3 version of HAVE_INTMAX_T.
+*/
+#define DK3_HAVE_INTMAX_T 1
+#endif
+
+#ifndef DK3_HAVE_INTTYPES_H
+/** DK3 version of HAVE_INTTYPES_H.
+*/
+#define DK3_HAVE_INTTYPES_H 1
+#endif
+
+#ifndef DK3_HAVE_IN_ADDR
+/** DK3 version of HAVE_IN_ADDR.
+*/
+#define DK3_HAVE_IN_ADDR 0
+#endif
+
+#ifndef DK3_HAVE_IO_H
+/** DK3 version of HAVE_IO_H.
+*/
+#define DK3_HAVE_IO_H 0
+#endif
+
+#ifndef DK3_HAVE_ISATTY
+/** DK3 version of HAVE_ISATTY.
+*/
+#define DK3_HAVE_ISATTY 1
+#endif
+
+#ifndef DK3_HAVE_ISFINITE
+/** DK3 version of HAVE_ISFINITE.
+*/
+#define DK3_HAVE_ISFINITE 1
+#endif
+
+#ifndef DK3_HAVE_ISNORMAL
+/** DK3 version of HAVE_ISNORMAL.
+*/
+#define DK3_HAVE_ISNORMAL 1
+#endif
+
+#ifndef DK3_HAVE_JPEGLIB_H
+/** DK3 version of HAVE_JPEGLIB_H.
+*/
+#define DK3_HAVE_JPEGLIB_H 1
+#endif
+
+#ifndef DK3_HAVE_LABS
+/** DK3 version of HAVE_LABS.
+*/
+#define DK3_HAVE_LABS 1
+#endif
+
+#ifndef DK3_HAVE_LARGEFILE64_SOURCE
+/** DK3 version of HAVE_LARGEFILE64_SOURCE.
+*/
+#define DK3_HAVE_LARGEFILE64_SOURCE 1
+#endif
+
+#ifndef DK3_HAVE_LIBNETSNMP
+/** DK3 version of HAVE_LIBNETSNMP.
+*/
+#define DK3_HAVE_LIBNETSNMP 1
+#endif
+
+#ifndef DK3_HAVE_LIMITS_H
+/** DK3 version of HAVE_LIMITS_H.
+*/
+#define DK3_HAVE_LIMITS_H 1
+#endif
+
+#ifndef DK3_HAVE_LOCALE_H
+/** DK3 version of HAVE_LOCALE_H.
+*/
+#define DK3_HAVE_LOCALE_H 1
+#endif
+
+#ifndef DK3_HAVE_LOCALTIME
+/** DK3 version of HAVE_LOCALTIME.
+*/
+#define DK3_HAVE_LOCALTIME 1
+#endif
+
+#ifndef DK3_HAVE_LOCALTIME
+/** DK3 version of HAVE_LOCALTIME.
+*/
+#define DK3_HAVE_LOCALTIME 1
+#endif
+
+#ifndef DK3_HAVE_LOCALTIME_R
+/** DK3 version of HAVE_LOCALTIME_R.
+*/
+#define DK3_HAVE_LOCALTIME_R 1
+#endif
+
+#ifndef DK3_HAVE_LOCALTIME_S
+/** DK3 version of HAVE_LOCALTIME_S.
+*/
+#define DK3_HAVE_LOCALTIME_S 0
+#endif
+
+#ifndef DK3_HAVE_LOGL
+/** DK3 version of HAVE_LOGL.
+*/
+#define DK3_HAVE_LOGL 1
+#endif
+
+#ifndef DK3_HAVE_LONG_DOUBLE
+/** DK3 version of HAVE_LONG_DOUBLE.
+*/
+#define DK3_HAVE_LONG_DOUBLE 1
+#endif
+
+#ifndef DK3_HAVE_LONG_LONG
+/** DK3 version of HAVE_LONG_LONG.
+*/
+#define DK3_HAVE_LONG_LONG 1
+#endif
+
+#ifndef DK3_HAVE_LPRNG_H
+/** DK3 version of HAVE_LPRNG_H.
+*/
+#define DK3_HAVE_LPRNG_H 0
+#endif
+
+#ifndef DK3_HAVE_LRAND48
+/** DK3 version of HAVE_LRAND48.
+*/
+#define DK3_HAVE_LRAND48 1
+#endif
+
+#ifndef DK3_HAVE_LSTAT
+/** DK3 version of HAVE_LSTAT.
+*/
+#define DK3_HAVE_LSTAT 1
+#endif
+
+#ifndef DK3_HAVE_LSTAT32
+/** DK3 version of HAVE_LSTAT32.
+*/
+#define DK3_HAVE_LSTAT32 0
+#endif
+
+#ifndef DK3_HAVE_LSTAT64
+/** DK3 version of HAVE_LSTAT64.
+*/
+#define DK3_HAVE_LSTAT64 1
+#endif
+
+#ifndef DK3_HAVE_MALLOC
+/** DK3 version of HAVE_MALLOC.
+*/
+#define DK3_HAVE_MALLOC 1
+#endif
+
+#ifndef DK3_HAVE_MALLOC_H
+/** DK3 version of HAVE_MALLOC_H.
+*/
+#define DK3_HAVE_MALLOC_H 1
+#endif
+
+#ifndef DK3_HAVE_MATH_H
+/** DK3 version of HAVE_MATH_H.
+*/
+#define DK3_HAVE_MATH_H 1
+#endif
+
+#ifndef DK3_HAVE_MEMCMP
+/** DK3 version of HAVE_MEMCMP.
+*/
+#define DK3_HAVE_MEMCMP 1
+#endif
+
+#ifndef DK3_HAVE_MEMCPY
+/** DK3 version of HAVE_MEMCPY.
+*/
+#define DK3_HAVE_MEMCPY 1
+#endif
+
+#ifndef DK3_HAVE_MEMSET
+/** DK3 version of HAVE_MEMSET.
+*/
+#define DK3_HAVE_MEMSET 1
+#endif
+
+#ifndef DK3_HAVE_MKDIR
+/** DK3 version of HAVE_MKDIR.
+*/
+#define DK3_HAVE_MKDIR 1
+#endif
+
+#ifndef DK3_HAVE_MKDIR2
+/** DK3 version of HAVE_MKDIR2.
+*/
+#define DK3_HAVE_MKDIR2 1
+#endif
+
+#ifndef DK3_HAVE_MPCTL
+/** DK3 version of HAVE_MPCTL.
+*/
+#define DK3_HAVE_MPCTL 0
+#endif
+
+#ifndef DK3_HAVE_MYSQL_LIBRARY_END
+/** DK3 version of HAVE_MYSQL_LIBRARY_END.
+*/
+#define DK3_HAVE_MYSQL_LIBRARY_END 0
+#endif
+
+#ifndef DK3_HAVE_MYSQL_LIBRARY_INIT
+/** DK3 version of HAVE_MYSQL_LIBRARY_INIT.
+*/
+#define DK3_HAVE_MYSQL_LIBRARY_INIT 0
+#endif
+
+#ifndef DK3_HAVE_MYSQL_MYSQL_H
+/** DK3 version of HAVE_MYSQL_MYSQL_H.
+*/
+#define DK3_HAVE_MYSQL_MYSQL_H 1
+#endif
+
+#ifndef DK3_HAVE_MYSQL_H
+/** DK3 version of HAVE_MYSQL_H.
+*/
+#define DK3_HAVE_MYSQL_H 0
+#endif
+
+#ifndef DK3_HAVE_MYSQL_SET_CHARACTER_SET
+/** DK3 version of HAVE_MYSQL_SET_CHARACTER_SET.
+*/
+#define DK3_HAVE_MYSQL_SET_CHARACTER_SET 0
+#endif
+
+#ifndef DK3_HAVE_NDBM_H
+/** DK3 version of HAVE_NDBM_H.
+*/
+#define DK3_HAVE_NDBM_H 0
+#endif
+
+#ifndef DK3_HAVE_NETDB_H
+/** DK3 version of HAVE_NETDB_H.
+*/
+#define DK3_HAVE_NETDB_H 1
+#endif
+
+#ifndef DK3_HAVE_NETINET_IN_H
+/** DK3 version of HAVE_NETINET_IN_H.
+*/
+#define DK3_HAVE_NETINET_IN_H 1
+#endif
+
+#ifndef DK3_HAVE_NETSNMP_ENABLE_FILELOG
+/** DK3 version of HAVE_NETSNMP_ENABLE_FILELOG.
+*/
+#define DK3_HAVE_NETSNMP_ENABLE_FILELOG 0
+#endif
+
+#ifndef DK3_HAVE_NRAND48
+/** DK3 version of HAVE_NRAND48.
+*/
+#define DK3_HAVE_NRAND48 1
+#endif
+
+#ifndef DK3_HAVE_OPENDIR
+/** DK3 version of HAVE_OPENDIR.
+*/
+#define DK3_HAVE_OPENDIR 1
+#endif
+
+#ifndef DK3_HAVE_OPENSSL_MD5_H
+/** DK3 version of HAVE_OPENSSL_MD5_H.
+*/
+#define DK3_HAVE_OPENSSL_MD5_H 1
+#endif
+
+#ifndef DK3_HAVE_OPENSSL_RAND_H
+/** DK3 version of HAVE_OPENSSL_RAND_H.
+*/
+#define DK3_HAVE_OPENSSL_RAND_H 1
+#endif
+
+#ifndef DK3_HAVE_OPENSSL_RIPEMD_H
+/** DK3 version of HAVE_OPENSSL_RIPEMD_H.
+*/
+#define DK3_HAVE_OPENSSL_RIPEMD_H 1
+#endif
+
+#ifndef DK3_HAVE_OPENSSL_SHA_H
+/** DK3 version of HAVE_OPENSSL_SHA_H.
+*/
+#define DK3_HAVE_OPENSSL_SHA_H 1
+#endif
+
+#ifndef DK3_HAVE_PNG_GET_PIXELS_PER_INCH
+/** DK3 version of HAVE_PNG_GET_PIXELS_PER_INCH.
+*/
+#define DK3_HAVE_PNG_GET_PIXELS_PER_INCH 0
+#endif
+
+#ifndef DK3_HAVE_PNG_H
+/** DK3 version of HAVE_PNG_H.
+*/
+#define DK3_HAVE_PNG_H 1
+#endif
+
+#ifndef DK3_HAVE_POPEN
+/** DK3 version of HAVE_POPEN.
+*/
+#define DK3_HAVE_POPEN 1
+#endif
+
+#ifndef DK3_HAVE_PROCESS_H
+/** DK3 version of HAVE_PROCESS_H.
+*/
+#define DK3_HAVE_PROCESS_H 0
+#endif
+
+#ifndef DK3_HAVE_PTHREAD_H
+/** DK3 version of HAVE_PTHREAD_H.
+*/
+#define DK3_HAVE_PTHREAD_H 1
+#endif
+
+#ifndef DK3_HAVE_PWD_H
+/** DK3 version of HAVE_PWD_H.
+*/
+#define DK3_HAVE_PWD_H 1
+#endif
+
+#ifndef DK3_HAVE_RAND
+/** DK3 version of HAVE_RAND.
+*/
+#define DK3_HAVE_RAND 1
+#endif
+
+#ifndef DK3_HAVE_RANDOM
+/** DK3 version of HAVE_RANDOM.
+*/
+#define DK3_HAVE_RANDOM 1
+#endif
+
+#ifndef DK3_HAVE_READ
+/** DK3 version of HAVE_READ.
+*/
+#define DK3_HAVE_READ 1
+#endif
+
+#ifndef DK3_HAVE_READDIR
+/** DK3 version of HAVE_READDIR.
+*/
+#define DK3_HAVE_READDIR 1
+#endif
+
+#ifndef DK3_HAVE_RFC_2249
+/** DK3 version of HAVE_RFC_2249.
+*/
+#define DK3_HAVE_RFC_2249 0
+#endif
+
+#ifndef DK3_HAVE_RINT
+/** DK3 version of HAVE_RINT.
+*/
+#define DK3_HAVE_RINT 1
+#endif
+
+#ifndef DK3_HAVE_RINTL
+/** DK3 version of HAVE_RINTL.
+*/
+#define DK3_HAVE_RINTL 1
+#endif
+
+#ifndef DK3_HAVE_RMDIR
+/** DK3 version of HAVE_RMDIR.
+*/
+#define DK3_HAVE_RMDIR 1
+#endif
+
+#ifndef DK3_HAVE_SEED48
+/** DK3 version of HAVE_SEED48.
+*/
+#define DK3_HAVE_SEED48 1
+#endif
+
+#ifndef DK3_HAVE_SELECT
+/** DK3 version of HAVE_SELECT.
+*/
+#define DK3_HAVE_SELECT 1
+#endif
+
+#ifndef DK3_HAVE_SETGID
+/** DK3 version of HAVE_SETGID.
+*/
+#define DK3_HAVE_SETGID 1
+#endif
+
+#ifndef DK3_HAVE_SETGRENT
+/** DK3 version of HAVE_SETGRENT.
+*/
+#define DK3_HAVE_SETGRENT 1
+#endif
+
+#ifndef DK3_HAVE_SETJMP_H
+/** DK3 version of HAVE_SETJMP_H.
+*/
+#define DK3_HAVE_SETJMP_H 1
+#endif
+
+#ifndef DK3_HAVE_SETLOCALE
+/** DK3 version of HAVE_SETLOCALE.
+*/
+#define DK3_HAVE_SETLOCALE 1
+#endif
+
+#ifndef DK3_HAVE_SETPGRP
+/** DK3 version of HAVE_SETPGRP.
+*/
+#define DK3_HAVE_SETPGRP 1
+#endif
+
+#ifndef DK3_HAVE_SETPWENT
+/** DK3 version of HAVE_SETPWENT.
+*/
+#define DK3_HAVE_SETPWENT 1
+#endif
+
+#ifndef DK3_HAVE_SETSID
+/** DK3 version of HAVE_SETSID.
+*/
+#define DK3_HAVE_SETSID 1
+#endif
+
+#ifndef DK3_HAVE_SETSOCKOPT
+/** DK3 version of HAVE_SETSOCKOPT.
+*/
+#define DK3_HAVE_SETSOCKOPT 1
+#endif
+
+#ifndef DK3_HAVE_SETSTATE
+/** DK3 version of HAVE_SETSTATE.
+*/
+#define DK3_HAVE_SETSTATE 1
+#endif
+
+#ifndef DK3_HAVE_SETUID
+/** DK3 version of HAVE_SETUID.
+*/
+#define DK3_HAVE_SETUID 1
+#endif
+
+#ifndef DK3_HAVE_SETVBUF
+/** DK3 version of HAVE_SETVBUF.
+*/
+#define DK3_HAVE_SETVBUF 1
+#endif
+
+#ifndef DK3_HAVE_SHA224
+/** DK3 version of HAVE_SHA224.
+*/
+#define DK3_HAVE_SHA224 1
+#endif
+
+#ifndef DK3_HAVE_SHA256
+/** DK3 version of HAVE_SHA256.
+*/
+#define DK3_HAVE_SHA256 1
+#endif
+
+#ifndef DK3_HAVE_SHA384
+/** DK3 version of HAVE_SHA384.
+*/
+#define DK3_HAVE_SHA384 1
+#endif
+
+#ifndef DK3_HAVE_SHA512
+/** DK3 version of HAVE_SHA512.
+*/
+#define DK3_HAVE_SHA512 1
+#endif
+
+#ifndef DK3_HAVE_SHADOW_H
+/** DK3 version of HAVE_SHADOW_H.
+*/
+#define DK3_HAVE_SHADOW_H 1
+#endif
+
+#ifndef DK3_HAVE_SIGACTION
+/** DK3 version of HAVE_SIGACTION.
+*/
+#define DK3_HAVE_SIGACTION 1
+#endif
+
+#ifndef DK3_HAVE_SIGNAL
+/** DK3 version of HAVE_SIGNAL.
+*/
+#define DK3_HAVE_SIGNAL 1
+#endif
+
+#ifndef DK3_HAVE_SIGNAL_H
+/** DK3 version of HAVE_SIGNAL_H.
+*/
+#define DK3_HAVE_SIGNAL_H 1
+#endif
+
+#ifndef DK3_HAVE_SIGSET
+/** DK3 version of HAVE_SIGSET.
+*/
+#define DK3_HAVE_SIGSET 1
+#endif
+
+#ifndef DK3_HAVE_SIG_ATOMIC_T
+/** DK3 version of HAVE_SIG_ATOMIC_T.
+*/
+#define DK3_HAVE_SIG_ATOMIC_T 1
+#endif
+
+#ifndef DK3_HAVE_SINHL
+/** DK3 version of HAVE_SINHL.
+*/
+#define DK3_HAVE_SINHL 1
+#endif
+
+#ifndef DK3_HAVE_SINL
+/** DK3 version of HAVE_SINL.
+*/
+#define DK3_HAVE_SINL 1
+#endif
+
+#ifndef DK3_HAVE_SNPRINTF
+/** DK3 version of HAVE_SNPRINTF.
+*/
+#define DK3_HAVE_SNPRINTF 1
+#endif
+
+#ifndef DK3_HAVE_SNWPRINTF
+/** DK3 version of HAVE_SNWPRINTF.
+*/
+#define DK3_HAVE_SNWPRINTF 0
+#endif
+
+#ifndef DK3_HAVE_SOCKET
+/** DK3 version of HAVE_SOCKET.
+*/
+#define DK3_HAVE_SOCKET 1
+#endif
+
+#ifndef DK3_HAVE_SOCKLEN_T
+/** DK3 version of HAVE_SOCKLEN_T.
+*/
+#define DK3_HAVE_SOCKLEN_T 1
+#endif
+
+#ifndef DK3_HAVE_SPRINTF_S
+/** DK3 version of HAVE_SPRINTF_S.
+*/
+#define DK3_HAVE_SPRINTF_S 0
+#endif
+
+#ifndef DK3_HAVE_SQRTL
+/** DK3 version of HAVE_SQRTL.
+*/
+#define DK3_HAVE_SQRTL 1
+#endif
+
+#ifndef DK3_HAVE_SRAND
+/** DK3 version of HAVE_SRAND.
+*/
+#define DK3_HAVE_SRAND 1
+#endif
+
+#ifndef DK3_HAVE_SSCANF_S
+/** DK3 version of HAVE_SSCANF_S.
+*/
+#define DK3_HAVE_SSCANF_S 0
+#endif
+
+#ifndef DK3_HAVE_SSIZE_T
+/** DK3 version of HAVE_SSIZE_T.
+*/
+#define DK3_HAVE_SSIZE_T 1
+#endif
+
+#ifndef DK3_HAVE_STAT
+/** DK3 version of HAVE_STAT.
+*/
+#define DK3_HAVE_STAT 1
+#endif
+
+#ifndef DK3_HAVE_STAT32
+/** DK3 version of HAVE_STAT32.
+*/
+#define DK3_HAVE_STAT32 0
+#endif
+
+#ifndef DK3_HAVE_STAT64
+/** DK3 version of HAVE_STAT64.
+*/
+#define DK3_HAVE_STAT64 1
+#endif
+
+#ifndef DK3_HAVE_STDARG_H
+/** DK3 version of HAVE_STDARG_H.
+*/
+#define DK3_HAVE_STDARG_H 1
+#endif
+
+#ifndef DK3_HAVE_STDDEF_H
+/** DK3 version of HAVE_STDDEF_H.
+*/
+#define DK3_HAVE_STDDEF_H 1
+#endif
+
+#ifndef DK3_HAVE_STDINT_H
+/** DK3 version of HAVE_STDINT_H.
+*/
+#define DK3_HAVE_STDINT_H 1
+#endif
+
+#ifndef DK3_HAVE_STDIO_H
+/** DK3 version of HAVE_STDIO_H.
+*/
+#define DK3_HAVE_STDIO_H 1
+#endif
+
+#ifndef DK3_HAVE_STDLIB_H
+/** DK3 version of HAVE_STDLIB_H.
+*/
+#define DK3_HAVE_STDLIB_H 1
+#endif
+
+#ifndef DK3_HAVE_STRCASECMP
+/** DK3 version of HAVE_STRCASECMP.
+*/
+#define DK3_HAVE_STRCASECMP 1
+#endif
+
+#ifndef DK3_HAVE_STRCAT
+/** DK3 version of HAVE_STRCAT.
+*/
+#define DK3_HAVE_STRCAT 1
+#endif
+
+#ifndef DK3_HAVE_STRCAT_S
+/** DK3 version of HAVE_STRCAT_S.
+*/
+#define DK3_HAVE_STRCAT_S 0
+#endif
+
+#ifndef DK3_HAVE_STRCHR
+/** DK3 version of HAVE_STRCHR.
+*/
+#define DK3_HAVE_STRCHR 1
+#endif
+
+#ifndef DK3_HAVE_STRCMP
+/** DK3 version of HAVE_STRCMP.
+*/
+#define DK3_HAVE_STRCMP 1
+#endif
+
+#ifndef DK3_HAVE_STRCPY
+/** DK3 version of HAVE_STRCPY.
+*/
+#define DK3_HAVE_STRCPY 1
+#endif
+
+#ifndef DK3_HAVE_STRCPY_S
+/** DK3 version of HAVE_STRCPY_S.
+*/
+#define DK3_HAVE_STRCPY_S 0
+#endif
+
+#ifndef DK3_HAVE_STRDUP
+/** DK3 version of HAVE_STRDUP.
+*/
+#define DK3_HAVE_STRDUP 1
+#endif
+
+#ifndef DK3_HAVE_STRERROR
+/** DK3 version of HAVE_STRERROR.
+*/
+#define DK3_HAVE_STRERROR 1
+#endif
+
+#ifndef DK3_HAVE_STRICMP
+/** DK3 version of HAVE_STRICMP.
+*/
+#define DK3_HAVE_STRICMP 0
+#endif
+
+#ifndef DK3_HAVE_STRINGS_H
+/** DK3 version of HAVE_STRINGS_H.
+*/
+#define DK3_HAVE_STRINGS_H 1
+#endif
+
+#ifndef DK3_HAVE_STRING_H
+/** DK3 version of HAVE_STRING_H.
+*/
+#define DK3_HAVE_STRING_H 1
+#endif
+
+#ifndef DK3_HAVE_STRLEN
+/** DK3 version of HAVE_STRLEN.
+*/
+#define DK3_HAVE_STRLEN 1
+#endif
+
+#ifndef DK3_HAVE_STRNCMP
+/** DK3 version of HAVE_STRNCMP.
+*/
+#define DK3_HAVE_STRNCMP 1
+#endif
+
+#ifndef DK3_HAVE_STRNCPY
+/** DK3 version of HAVE_STRNCPY.
+*/
+#define DK3_HAVE_STRNCPY 1
+#endif
+
+#ifndef DK3_HAVE_STRNCPY_S
+/** DK3 version of HAVE_STRNCPY_S.
+*/
+#define DK3_HAVE_STRNCPY_S 0
+#endif
+
+#ifndef DK3_HAVE_STROPTS_H
+/** DK3 version of HAVE_STROPTS_H.
+*/
+#define DK3_HAVE_STROPTS_H 1
+#endif
+
+#ifndef DK3_HAVE_STRRCHR
+/** DK3 version of HAVE_STRRCHR.
+*/
+#define DK3_HAVE_STRRCHR 1
+#endif
+
+#ifndef DK3_HAVE_STRTOD
+/** DK3 version of HAVE_STRTOD.
+*/
+#define DK3_HAVE_STRTOD 1
+#endif
+
+#ifndef DK3_HAVE_STRTOIMAX
+/** DK3 version of HAVE_STRTOIMAX.
+*/
+#define DK3_HAVE_STRTOIMAX 1
+#endif
+
+#ifndef DK3_HAVE_STRTOL
+/** DK3 version of HAVE_STRTOL.
+*/
+#define DK3_HAVE_STRTOL 1
+#endif
+
+#ifndef DK3_HAVE_STRTOLL
+/** DK3 version of HAVE_STRTOLL.
+*/
+#define DK3_HAVE_STRTOLL 1
+#endif
+
+#ifndef DK3_HAVE_STRTOUL
+/** DK3 version of HAVE_STRTOUL.
+*/
+#define DK3_HAVE_STRTOUL 1
+#endif
+
+#ifndef DK3_HAVE_STRTOULL
+/** DK3 version of HAVE_STRTOULL.
+*/
+#define DK3_HAVE_STRTOULL 1
+#endif
+
+#ifndef DK3_HAVE_STRTOUMAX
+/** DK3 version of HAVE_STRTOUMAX.
+*/
+#define DK3_HAVE_STRTOUMAX 1
+#endif
+
+#ifndef DK3_HAVE_STRUCT_ADDRINFO
+/** DK3 version of HAVE_STRUCT_ADDRINFO.
+*/
+#define DK3_HAVE_STRUCT_ADDRINFO 1
+#endif
+
+#ifndef DK3_HAVE_STRUCT_SOCKADDR_IN
+/** DK3 version of HAVE_STRUCT_SOCKADDR_IN.
+*/
+#define DK3_HAVE_STRUCT_SOCKADDR_IN 1
+#endif
+
+#ifndef DK3_HAVE_STRUCT_SOCKADDR_IN6
+/** DK3 version of HAVE_STRUCT_SOCKADDR_IN6.
+*/
+#define DK3_HAVE_STRUCT_SOCKADDR_IN6 1
+#endif
+
+#ifndef DK3_HAVE_STRUCT_SOCKADDR_STORAGE
+/** DK3 version of HAVE_STRUCT_SOCKADDR_STORAGE.
+*/
+#define DK3_HAVE_STRUCT_SOCKADDR_STORAGE 1
+#endif
+
+#ifndef DK3_HAVE_STRUCT_SOCKADDR_UN
+/** DK3 version of HAVE_STRUCT_SOCKADDR_UN.
+*/
+#define DK3_HAVE_STRUCT_SOCKADDR_UN 1
+#endif
+
+#ifndef DK3_HAVE_SWSCANF_S
+/** DK3 version of HAVE_SWSCANF_S.
+*/
+#define DK3_HAVE_SWSCANF_S 0
+#endif
+
+#ifndef DK3_HAVE_SYSCONF
+/** DK3 version of HAVE_SYSCONF.
+*/
+#define DK3_HAVE_SYSCONF 1
+#endif
+
+#ifndef DK3_HAVE_SYSCTL
+/** DK3 version of HAVE_SYSCTL.
+*/
+#define DK3_HAVE_SYSCTL 1
+#endif
+
+#ifndef DK3_HAVE_SYSLOG
+/** DK3 version of HAVE_SYSLOG.
+*/
+#define DK3_HAVE_SYSLOG 1
+#endif
+
+#ifndef DK3_HAVE_SYSLOG_H
+/** DK3 version of HAVE_SYSLOG_H.
+*/
+#define DK3_HAVE_SYSLOG_H 1
+#endif
+
+#ifndef DK3_HAVE_SYSRES_H
+/** DK3 version of HAVE_SYSRES_H.
+*/
+#define DK3_HAVE_SYSRES_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_FILE_H
+/** DK3 version of HAVE_SYS_FILE_H.
+*/
+#define DK3_HAVE_SYS_FILE_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_PARAM_H
+/** DK3 version of HAVE_SYS_PARAM_H.
+*/
+#define DK3_HAVE_SYS_PARAM_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_RESOURCE_H
+/** DK3 version of HAVE_SYS_RESOURCE_H.
+*/
+#define DK3_HAVE_SYS_RESOURCE_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_SOCKET_H
+/** DK3 version of HAVE_SYS_SOCKET_H.
+*/
+#define DK3_HAVE_SYS_SOCKET_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_STATVFS_H
+/** DK3 version of HAVE_SYS_STATVFS_H.
+*/
+#define DK3_HAVE_SYS_STATVFS_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_STAT_H
+/** DK3 version of HAVE_SYS_STAT_H.
+*/
+#define DK3_HAVE_SYS_STAT_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_STROPTS_H
+/** DK3 version of HAVE_SYS_STROPTS_H.
+*/
+#define DK3_HAVE_SYS_STROPTS_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_SUNDDI_H
+/** DK3 version of HAVE_SYS_SUNDDI_H.
+*/
+#define DK3_HAVE_SYS_SUNDDI_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_SYSCTL_H
+/** DK3 version of HAVE_SYS_SYSCTL_H.
+*/
+#define DK3_HAVE_SYS_SYSCTL_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_SYSTEMINFO_H
+/** DK3 version of HAVE_SYS_SYSTEMINFO_H.
+*/
+#define DK3_HAVE_SYS_SYSTEMINFO_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_TERMIOS_H
+/** DK3 version of HAVE_SYS_TERMIOS_H.
+*/
+#define DK3_HAVE_SYS_TERMIOS_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_TIME_H
+/** DK3 version of HAVE_SYS_TIME_H.
+*/
+#define DK3_HAVE_SYS_TIME_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_TTOLD_H
+/** DK3 version of HAVE_SYS_TTOLD_H.
+*/
+#define DK3_HAVE_SYS_TTOLD_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_TYPES_H
+/** DK3 version of HAVE_SYS_TYPES_H.
+*/
+#define DK3_HAVE_SYS_TYPES_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_UIO_H
+/** DK3 version of HAVE_SYS_UIO_H.
+*/
+#define DK3_HAVE_SYS_UIO_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_UN_H
+/** DK3 version of HAVE_SYS_UN_H.
+*/
+#define DK3_HAVE_SYS_UN_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_WAIT_H
+/** DK3 version of HAVE_SYS_WAIT_H.
+*/
+#define DK3_HAVE_SYS_WAIT_H 1
+#endif
+
+#ifndef DK3_HAVE_TANHL
+/** DK3 version of HAVE_TANHL.
+*/
+#define DK3_HAVE_TANHL 1
+#endif
+
+#ifndef DK3_HAVE_TANL
+/** DK3 version of HAVE_TANL.
+*/
+#define DK3_HAVE_TANL 1
+#endif
+
+#ifndef DK3_HAVE_TCFLUSH
+/** DK3 version of HAVE_TCFLUSH.
+*/
+#define DK3_HAVE_TCFLUSH 1
+#endif
+
+#ifndef DK3_HAVE_TCGETATTR
+/** DK3 version of HAVE_TCGETATTR.
+*/
+#define DK3_HAVE_TCGETATTR 1
+#endif
+
+#ifndef DK3_HAVE_TERMIOS_H
+/** DK3 version of HAVE_TERMIOS_H.
+*/
+#define DK3_HAVE_TERMIOS_H 1
+#endif
+
+#ifndef DK3_HAVE_TIFF_H
+/** DK3 version of HAVE_TIFF_H.
+*/
+#define DK3_HAVE_TIFF_H 1
+#endif
+
+#ifndef DK3_HAVE_TIME
+/** DK3 version of HAVE_TIME.
+*/
+#define DK3_HAVE_TIME 1
+#endif
+
+#ifndef DK3_HAVE_TIME_H
+/** DK3 version of HAVE_TIME_H.
+*/
+#define DK3_HAVE_TIME_H 1
+#endif
+
+#ifndef DK3_HAVE_TWOS_COMPLEMENT
+/** DK3 version of HAVE_TWOS_COMPLEMENT.
+*/
+#define DK3_HAVE_TWOS_COMPLEMENT 1
+#endif
+
+#ifndef DK3_HAVE_UMASK
+/** DK3 version of HAVE_UMASK.
+*/
+#define DK3_HAVE_UMASK 1
+#endif
+
+#ifndef DK3_HAVE_UNISTD_H
+/** DK3 version of HAVE_UNISTD_H.
+*/
+#define DK3_HAVE_UNISTD_H 1
+#endif
+
+#ifndef DK3_HAVE_UNLINK
+/** DK3 version of HAVE_UNLINK.
+*/
+#define DK3_HAVE_UNLINK 1
+#endif
+
+#ifndef DK3_HAVE_USER_NAMES_CASE_INSENSITIVE
+/** DK3 version of HAVE_USER_NAMES_CASE_INSENSITIVE.
+*/
+#define DK3_HAVE_USER_NAMES_CASE_INSENSITIVE 0
+#endif
+
+#ifndef DK3_HAVE_VARARGS_H
+/** DK3 version of HAVE_VARARGS_H.
+*/
+#define DK3_HAVE_VARARGS_H 0
+#endif
+
+#ifndef DK3_HAVE_VARARG_H
+/** DK3 version of HAVE_VARARG_H.
+*/
+#define DK3_HAVE_VARARG_H 0
+#endif
+
+#ifndef DK3_HAVE_VOLATILE
+/** DK3 version of HAVE_VOLATILE.
+*/
+#define DK3_HAVE_VOLATILE 1
+#endif
+
+#ifndef DK3_HAVE_WCHAR_H
+/** DK3 version of HAVE_WCHAR_H.
+*/
+#define DK3_HAVE_WCHAR_H 1
+#endif
+
+#ifndef DK3_HAVE_WCHAR_T
+/** DK3 version of HAVE_WCHAR_T.
+*/
+#define DK3_HAVE_WCHAR_T 1
+#endif
+
+#ifndef DK3_HAVE_WCSCAT
+/** DK3 version of HAVE_WCSCAT.
+*/
+#define DK3_HAVE_WCSCAT 1
+#endif
+
+#ifndef DK3_HAVE_WCSCAT_S
+/** DK3 version of HAVE_WCSCAT_S.
+*/
+#define DK3_HAVE_WCSCAT_S 0
+#endif
+
+#ifndef DK3_HAVE_WCSCHR
+/** DK3 version of HAVE_WCSCHR.
+*/
+#define DK3_HAVE_WCSCHR 1
+#endif
+
+#ifndef DK3_HAVE_WCSCMP
+/** DK3 version of HAVE_WCSCMP.
+*/
+#define DK3_HAVE_WCSCMP 1
+#endif
+
+#ifndef DK3_HAVE_WCSCPY
+/** DK3 version of HAVE_WCSCPY.
+*/
+#define DK3_HAVE_WCSCPY 1
+#endif
+
+#ifndef DK3_HAVE_WCSCPY_S
+/** DK3 version of HAVE_WCSCPY_S.
+*/
+#define DK3_HAVE_WCSCPY_S 0
+#endif
+
+#ifndef DK3_HAVE_WCSDUP
+/** DK3 version of HAVE_WCSDUP.
+*/
+#define DK3_HAVE_WCSDUP 1
+#endif
+
+#ifndef DK3_HAVE_WCSICMP
+/** DK3 version of HAVE_WCSICMP.
+*/
+#define DK3_HAVE_WCSICMP 0
+#endif
+
+#ifndef DK3_HAVE_WCSLEN
+/** DK3 version of HAVE_WCSLEN.
+*/
+#define DK3_HAVE_WCSLEN 1
+#endif
+
+#ifndef DK3_HAVE_WCSNCMP
+/** DK3 version of HAVE_WCSNCMP.
+*/
+#define DK3_HAVE_WCSNCMP 1
+#endif
+
+#ifndef DK3_HAVE_WCSNCPY
+/** DK3 version of HAVE_WCSNCPY.
+*/
+#define DK3_HAVE_WCSNCPY 1
+#endif
+
+#ifndef DK3_HAVE_WCSNCPY_S
+/** DK3 version of HAVE_WCSNCPY_S.
+*/
+#define DK3_HAVE_WCSNCPY_S 0
+#endif
+
+#ifndef DK3_HAVE_WCSRCHR
+/** DK3 version of HAVE_WCSRCHR.
+*/
+#define DK3_HAVE_WCSRCHR 1
+#endif
+
+#ifndef DK3_HAVE_WCSTOD
+/** DK3 version of HAVE_WCSTOD.
+*/
+#define DK3_HAVE_WCSTOD 1
+#endif
+
+#ifndef DK3_HAVE_WCSTOIMAX
+/** DK3 version of HAVE_WCSTOIMAX.
+*/
+#define DK3_HAVE_WCSTOIMAX 1
+#endif
+
+#ifndef DK3_HAVE_WCSTOL
+/** DK3 version of HAVE_WCSTOL.
+*/
+#define DK3_HAVE_WCSTOL 1
+#endif
+
+#ifndef DK3_HAVE_WCSTOLL
+/** DK3 version of HAVE_WCSTOLL.
+*/
+#define DK3_HAVE_WCSTOLL 1
+#endif
+
+#ifndef DK3_HAVE_WCSTOUL
+/** DK3 version of HAVE_WCSTOUL.
+*/
+#define DK3_HAVE_WCSTOUL 1
+#endif
+
+#ifndef DK3_HAVE_WCSTOULL
+/** DK3 version of HAVE_WCSTOULL.
+*/
+#define DK3_HAVE_WCSTOULL 1
+#endif
+
+#ifndef DK3_HAVE_WCSTOUMAX
+/** DK3 version of HAVE_WCSTOUMAX.
+*/
+#define DK3_HAVE_WCSTOUMAX 1
+#endif
+
+#ifndef DK3_HAVE_WINBASE_H
+/** DK3 version of HAVE_WINBASE_H.
+*/
+#define DK3_HAVE_WINBASE_H 0
+#endif
+
+#ifndef DK3_HAVE_WINCON_H
+/** DK3 version of HAVE_WINCON_H.
+*/
+#define DK3_HAVE_WINCON_H 0
+#endif
+
+#ifndef DK3_HAVE_WINDOWS_H
+/** DK3 version of HAVE_WINDOWS_H.
+*/
+#define DK3_HAVE_WINDOWS_H 0
+#endif
+
+#ifndef DK3_HAVE_WINREG_H
+/** DK3 version of HAVE_WINREG_H.
+*/
+#define DK3_HAVE_WINREG_H 0
+#endif
+
+#ifndef DK3_HAVE_WINSOCK2_H
+/** DK3 version of HAVE_WINSOCK2_H.
+*/
+#define DK3_HAVE_WINSOCK2_H 0
+#endif
+
+#ifndef DK3_HAVE_WRITE
+/** DK3 version of HAVE_WRITE.
+*/
+#define DK3_HAVE_WRITE 1
+#endif
+
+#ifndef DK3_HAVE_WS2TCPIP_H
+/** DK3 version of HAVE_WS2TCPIP_H.
+*/
+#define DK3_HAVE_WS2TCPIP_H 0
+#endif
+
+#ifndef DK3_HAVE_ZLIB_H
+/** DK3 version of HAVE_ZLIB_H.
+*/
+#define DK3_HAVE_ZLIB_H 1
+#endif
+
+#ifndef DK3_HAVE__CLEARFP
+/** DK3 version of HAVE__CLEARFP.
+*/
+#define DK3_HAVE__CLEARFP 0
+#endif
+
+#ifndef DK3_HAVE__FCLOSE
+/** DK3 version of HAVE__FCLOSE.
+*/
+#define DK3_HAVE__FCLOSE 0
+#endif
+
+#ifndef DK3_HAVE__FEOF
+/** DK3 version of HAVE__FEOF.
+*/
+#define DK3_HAVE__FEOF 0
+#endif
+
+#ifndef DK3_HAVE__FERROR
+/** DK3 version of HAVE__FERROR.
+*/
+#define DK3_HAVE__FERROR 0
+#endif
+
+#ifndef DK3_HAVE__FFLUSH
+/** DK3 version of HAVE__FFLUSH.
+*/
+#define DK3_HAVE__FFLUSH 0
+#endif
+
+#ifndef DK3_HAVE__FOPEN
+/** DK3 version of HAVE__FOPEN.
+*/
+#define DK3_HAVE__FOPEN 0
+#endif
+
+#ifndef DK3_HAVE__FREAD
+/** DK3 version of HAVE__FREAD.
+*/
+#define DK3_HAVE__FREAD 0
+#endif
+
+#ifndef DK3_HAVE__FWRITE
+/** DK3 version of HAVE__FWRITE.
+*/
+#define DK3_HAVE__FWRITE 0
+#endif
+
+#ifndef DK3_HAVE__GETCWD
+/** DK3 version of HAVE__GETCWD.
+*/
+#define DK3_HAVE__GETCWD 0
+#endif
+
+#ifndef DK3_HAVE__GETENV_S
+/** DK3 version of HAVE__GETENV_S.
+*/
+#define DK3_HAVE__GETENV_S 0
+#endif
+
+#ifndef DK3_HAVE__GETPID
+/** DK3 version of HAVE__GETPID.
+*/
+#define DK3_HAVE__GETPID 0
+#endif
+
+#ifndef DK3_HAVE__LSTAT
+/** DK3 version of HAVE__LSTAT.
+*/
+#define DK3_HAVE__LSTAT 0
+#endif
+
+#ifndef DK3_HAVE__LSTAT32
+/** DK3 version of HAVE__LSTAT32.
+*/
+#define DK3_HAVE__LSTAT32 0
+#endif
+
+#ifndef DK3_HAVE__LSTAT64
+/** DK3 version of HAVE__LSTAT64.
+*/
+#define DK3_HAVE__LSTAT64 0
+#endif
+
+#ifndef DK3_HAVE__MKDIR
+/** DK3 version of HAVE__MKDIR.
+*/
+#define DK3_HAVE__MKDIR 0
+#endif
+
+#ifndef DK3_HAVE__POPEN
+/** DK3 version of HAVE__POPEN.
+*/
+#define DK3_HAVE__POPEN 0
+#endif
+
+#ifndef DK3_HAVE__READ
+/** DK3 version of HAVE__READ.
+*/
+#define DK3_HAVE__READ 0
+#endif
+
+#ifndef DK3_HAVE__RMDIR
+/** DK3 version of HAVE__RMDIR.
+*/
+#define DK3_HAVE__RMDIR 0
+#endif
+
+#ifndef DK3_HAVE__SNPRINTF
+/** DK3 version of HAVE__SNPRINTF.
+*/
+#define DK3_HAVE__SNPRINTF 0
+#endif
+
+#ifndef DK3_HAVE__SNPRINTF_S
+/** DK3 version of HAVE__SNPRINTF_S.
+*/
+#define DK3_HAVE__SNPRINTF_S 0
+#endif
+
+#ifndef DK3_HAVE__SNWPRINTF
+/** DK3 version of HAVE__SNWPRINTF.
+*/
+#define DK3_HAVE__SNWPRINTF 0
+#endif
+
+#ifndef DK3_HAVE__SNWPRINTF_S
+/** DK3 version of HAVE__SNWPRINTF_S.
+*/
+#define DK3_HAVE__SNWPRINTF_S 0
+#endif
+
+#ifndef DK3_HAVE__STAT
+/** DK3 version of HAVE__STAT.
+*/
+#define DK3_HAVE__STAT 0
+#endif
+
+#ifndef DK3_HAVE__STAT32
+/** DK3 version of HAVE__STAT32.
+*/
+#define DK3_HAVE__STAT32 0
+#endif
+
+#ifndef DK3_HAVE__STAT64
+/** DK3 version of HAVE__STAT64.
+*/
+#define DK3_HAVE__STAT64 0
+#endif
+
+#ifndef DK3_HAVE__STRDUP
+/** DK3 version of HAVE__STRDUP.
+*/
+#define DK3_HAVE__STRDUP 0
+#endif
+
+#ifndef DK3_HAVE__STRICMP
+/** DK3 version of HAVE__STRICMP.
+*/
+#define DK3_HAVE__STRICMP 0
+#endif
+
+#ifndef DK3_HAVE__UNLINK
+/** DK3 version of HAVE__UNLINK.
+*/
+#define DK3_HAVE__UNLINK 0
+#endif
+
+#ifndef DK3_HAVE__WCSCAT
+/** DK3 version of HAVE__WCSCAT.
+*/
+#define DK3_HAVE__WCSCAT 0
+#endif
+
+#ifndef DK3_HAVE__WCSCHR
+/** DK3 version of HAVE__WCSCHR.
+*/
+#define DK3_HAVE__WCSCHR 0
+#endif
+
+#ifndef DK3_HAVE__WCSCMP
+/** DK3 version of HAVE__WCSCMP.
+*/
+#define DK3_HAVE__WCSCMP 0
+#endif
+
+#ifndef DK3_HAVE__WCSCPY
+/** DK3 version of HAVE__WCSCPY.
+*/
+#define DK3_HAVE__WCSCPY 0
+#endif
+
+#ifndef DK3_HAVE__WCSDUP
+/** DK3 version of HAVE__WCSDUP.
+*/
+#define DK3_HAVE__WCSDUP 0
+#endif
+
+#ifndef DK3_HAVE__WCSICMP
+/** DK3 version of HAVE__WCSICMP.
+*/
+#define DK3_HAVE__WCSICMP 0
+#endif
+
+#ifndef DK3_HAVE__WCSLEN
+/** DK3 version of HAVE__WCSLEN.
+*/
+#define DK3_HAVE__WCSLEN 0
+#endif
+
+#ifndef DK3_HAVE__WCSNCMP
+/** DK3 version of HAVE__WCSNCMP.
+*/
+#define DK3_HAVE__WCSNCMP 0
+#endif
+
+#ifndef DK3_HAVE__WCSNCPY
+/** DK3 version of HAVE__WCSNCPY.
+*/
+#define DK3_HAVE__WCSNCPY 0
+#endif
+
+#ifndef DK3_HAVE__WCSRCHR
+/** DK3 version of HAVE__WCSRCHR.
+*/
+#define DK3_HAVE__WCSRCHR 0
+#endif
+
+#ifndef DK3_HAVE__WFOPEN_S
+/** DK3 version of HAVE__WFOPEN_S.
+*/
+#define DK3_HAVE__WFOPEN_S 0
+#endif
+
+#ifndef DK3_HAVE__WGETENV
+/** DK3 version of HAVE__WGETENV.
+*/
+#define DK3_HAVE__WGETENV 0
+#endif
+
+#ifndef DK3_HAVE__WRITE
+/** DK3 version of HAVE__WRITE.
+*/
+#define DK3_HAVE__WRITE 0
+#endif
+
+#ifndef DK3_TIME_WITH_SYS_TIME
+/** DK3 version of TIME_WITH_SYS_TIME.
+*/
+#define DK3_TIME_WITH_SYS_TIME 1
+#endif
+
+#ifndef DK3_HAVE_WX_CHARTYPE_H
+/** DK3 version of HAVE_WX_CHARTYPE_H.
+*/
+#define DK3_HAVE_WX_CHARTYPE_H 0
+#endif
+
+#ifndef DK3_HAVE_WX_WXCHAR_H
+/** DK3 version of HAVE_WX_WXCHAR_H.
+*/
+#define DK3_HAVE_WX_WXCHAR_H 0
+#endif
+
+#ifndef DK3_SIZEOF_DOUBLE
+/** DK3 version of SIZEOF_DOUBLE.
+*/
+#define DK3_SIZEOF_DOUBLE 8
+#endif
+
+#ifndef DK3_SIZEOF_INT
+/** DK3 version of SIZEOF_INT.
+*/
+#define DK3_SIZEOF_INT 4
+#endif
+
+#ifndef DK3_SIZEOF_INTMAX_T
+/** DK3 version of SIZEOF_INTMAX_T.
+*/
+#define DK3_SIZEOF_INTMAX_T 8
+#endif
+
+#ifndef DK3_SIZEOF_LONG
+/** DK3 version of SIZEOF_LONG.
+*/
+#define DK3_SIZEOF_LONG 8
+#endif
+
+#ifndef DK3_SIZEOF_LONG_DOUBLE
+/** DK3 version of SIZEOF_LONG_DOUBLE.
+*/
+#define DK3_SIZEOF_LONG_DOUBLE 16
+#endif
+
+#ifndef DK3_SIZEOF_LONG_LONG
+/** DK3 version of SIZEOF_LONG_LONG.
+*/
+#define DK3_SIZEOF_LONG_LONG 8
+#endif
+
+#ifndef DK3_SIZEOF_SHORT
+/** DK3 version of SIZEOF_SHORT.
+*/
+#define DK3_SIZEOF_SHORT 2
+#endif
+
+#ifndef DK3_SIZEOF_SIZE_T
+/** DK3 version of SIZEOF_SIZE_T.
+*/
+#define DK3_SIZEOF_SIZE_T 8
+#endif
+
+#ifndef DK3_SIZEOF_WCHAR_T
+/** DK3 version of SIZEOF_WCHAR_T.
+*/
+#define DK3_SIZEOF_WCHAR_T 4
+#endif
+
+#endif
+/* if DK3_ON_WINDOWS */
+
+#ifndef DK3_WORDS_BIGENDIAN
+/** Little-endian.
+*/
+#define DK3_WORDS_BIGENDIAN 0
+#endif
+
+#ifndef DK3_MAX_PATH
+/** Maximum path length.
+*/
+#define DK3_MAX_PATH 4097
+#endif
+
+#endif
+/* ifndef DK3_CONF_H_INCLUDED */
+
diff --git a/support/dktools/dk3confd.h b/support/dktools/dk3confd.h
new file mode 100644
index 0000000000..afcfa65112
--- /dev/null
+++ b/support/dktools/dk3confd.h
@@ -0,0 +1,194 @@
+
+/** @file dk3confd.h Configuration defaults.
+ * This file contains default settings for systems where the
+ * configure script cannot be run.
+ */
+
+#ifndef DK3_CONFD_H_INCLUDED
+#define DK3_CONFD_H_INCLUDED 1
+
+#ifndef DK3_ON_WINDOWS
+#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
+/** On a Windows system. */
+#define DK3_ON_WINDOWS 1
+#else
+/** Not on a Windows system. */
+#define DK3_ON_WINDOWS 0
+#endif
+#endif
+/** ifndef DK3_ON_WINDOWS */
+
+#if DK3_ON_WINDOWS
+/* +++ Windows */
+
+/* ##### TODO: Create setup entries. */
+
+/* --- Windows */
+#else
+/* if DK3_ON_WINDOWS */
+/* +++ non-Windows */
+
+#define HAVE_WINSOCK2_H 0
+#define HAVE_WINDOWS_H 0
+#define HAVE_WINBASE_H 0
+#define HAVE_WINREG_H 0
+#define HAVE_WINCON_H 0
+#define HAVE_STDIO_H 1
+#define HAVE_SYS_TYPES_H 1
+#define HAVE_SYS_STAT_H 1
+#define HAVE_STDLIB_H 1
+#define HAVE_STDDEF_H 1
+#define HAVE_UNISTD_H 1
+#define HAVE_PROCESS_H 0
+#define HAVE_LIMITS_H 1
+#define HAVE_SYS_PARAM_H 1
+#define HAVE_SYS_WAIT_H 1
+#define HAVE_SYS_STATVFS_H 1
+#define HAVE_SYS_STROPTS_H 0
+#define HAVE_SYS_FILE_H 1
+#define HAVE_SYS_UIO_H 1
+#define HAVE_SYS_UN_H 1
+#define HAVE_SYS_SUNDDI_H 0
+#define HAVE_SYS_RESOURCE_H 1
+#define HAVE_SYS_SYSTEMINFO_H 0
+#define HAVE_SYS_SOCKET_H 1
+#define TIME_WITH_SYS_TIME 1
+#define HAVE_SYS_TIME_H 1
+#define HAVE_TIME_H 1
+#define HAVE_ERRNO_H 1
+#define HAVE_ALLOC_H 0
+#define HAVE_MALLOC_H 1
+#define HAVE_CTYPE_H 1
+#define HAVE_STRING_H 1
+#define HAVE_STRINGS_H 1
+#define HAVE_STROPTS_H 0
+#define HAVE_IO_H 0
+#define HAVE_DOS_H 0
+#define HAVE_FCNTL_H 1
+#define HAVE_DIR_H 0
+#define HAVE_DIREENT_H 0
+#define HAVE_DIRECT_H 0
+#define HAVE_SYSRES_H 0
+#define HAVE_NETINET_IN_H 1
+#define HAVE_ARPA_INET_H 1
+#define HAVE_NETDB_H 1
+#define HAVE_GRP_H 1
+#define HAVE_PWD_H 1
+#define HAVE_MATH_H 1
+#define HAVE_SIGNAL_H 1
+#define HAVE_SYSLOG_H 1
+#define HAVE_CONIO_H 0
+#define HAVE_WCHAR_H 1
+#define HAVE_STDARG_H 1
+#define HAVE_VARARG_H 0
+#define HAVE_VARARGS_H 0
+#define HAVE_TERMIOS_H 1
+#define HAVE_SHADOW_H 1
+#define HAVE_SYS_TERMIOS_H 1
+#define HAVE_SYS_TTOLD_H 0
+#define HAVE_SETJMP_H 1
+#define HAVE_OPENSSL_RAND_H 1
+#define HAVE_OPENSSL_MD5_H 1
+#define HAVE_OPENSSL_SHA_H 1
+#define HAVE_OPENSSL_RIPEMD_H 1
+#define HAVE_PNG_H 1
+#define HAVE_PNM_H 0
+#define HAVE_JPEGLIB_H 1
+#define HAVE_TIFF_H 1
+#define HAVE_NDBM_H 0
+#define HAVE_DB_H 1
+#define WORDS_BIGENDIAN 0
+#define SIZEOF_SHORT 2
+#define SIZEOF_INT 4
+#define SIZEOF_LONG 4
+#define SIZEOF_SIZE_T 4
+#define HAVE_LONG_LONG 1
+#define SIZEOF_LONG_LONG 8
+#define HAVE_WCHAR_T 1
+#define SIZEOF_WCHAR_T 4
+#define HAVE_LARGEFILE64_SOURCE 1
+#define HAVE_CONST 1
+#define HAVE_VOLATILE 1
+#define HAVE_BACKSLASH 0
+#define HAVE_FNCASEINS 0
+#define HAVE_MALLOC 1
+#define HAVE_FREE 1
+#define HAVE_STRLEN 1
+#define HAVE_WCSLEN 0
+#define HAVE__WCSLEN 0
+#define HAVE_STRCMP 1
+#define HAVE_WCSCMP 0
+#define HAVE__WCSCMP 0
+#define HAVE_STRNCMP 1
+#define HAVE_WCSNCMP 0
+#define HAVE__WCSNCMP 0
+#define HAVE_STRICMP 0
+#define HAVE_STRCASECMP 1
+#define HAVE_WCSICMP 0
+#define HAVE__WCSICMP 0
+#define HAVE_STRCPY 1
+#define HAVE_WCSCPY 0
+#define HAVE__WCSCPY 0
+#define HAVE_STRNCPY 1
+#define HAVE_WCSNCPY 0
+#define HAVE__WCSNCPY 0
+#define HAVE_STRCAT 1
+#define HAVE_WCSCAT 0
+#define HAVE__WCSCAT 0
+#define HAVE_STRCHR 1
+#define HAVE_WCSCHR 0
+#define HAVE__WCSCHR 0
+#define HAVE_STRRCHR 1
+#define HAVE_WCSRCHR 0
+#define HAVE__WCSRCHR 0
+#define HAVE_STRDUP 1
+#define HAVE_WCSDUP 0
+#define HAVE__WCSDUP 0
+#define HAVE_RINT 1
+#define HAVE_FLOOR 1
+#define HAVE_CEIL 1
+#define HAVE_FABS 1
+#define HAVE_LABS 1
+#define HAVE_TIME 1
+#define HAVE_LOCALTIME 1
+#define HAVE_FOPEN 1
+#define HAVE__FOPEN 0
+#define HAVE_FCLOSE 1
+#define HAVE__FCLOSE 0
+#define HAVE_FEOF 1
+#define HAVE__FEOF 0
+#define HAVE_FFLUSH 1
+#define HAVE__FFLUSH 0
+#define HAVE_FREAD 1
+#define HAVE__FREAD 0
+#define HAVE_FWRITE 1
+#define HAVE__FWRITE 0
+#define HAVE__WGETENV 0
+#define HAVE_GETPWNAM 1
+#define HAVE_GETPWUID 1
+#define HAVE_GETPWENT 1
+#define HAVE_SETPWENT 1
+#define HAVE_ENDPWENT 1
+#define HAVE_GETUID 1
+#define HAVE_STAT64 1
+#define HAVE__STAT64 0
+#define HAVE_LSTAT64 1
+#define HAVE__LSTAT64 0
+#define HAVE_STAT32 0
+#define HAVE__STAT32 0
+#define HAVE_LSTAT32 0
+#define HAVE__LSTAT32 0
+#define HAVE_STAT 1
+#define HAVE__STAT 0
+#define HAVE_LSTAT 1
+#define HAVE__LSTAT 0
+#define HAVE_GETHOSTNAME 1
+
+/* --- non-Windows */
+#endif
+/* if DK3_ON_WINDOWS */
+
+
+#endif
+/* ifndef DK3_CONFD_H_INCLUDED */
+
diff --git a/support/dktools/dk3config.c b/support/dktools/dk3config.c
new file mode 100644
index 0000000000..e647d7b538
--- /dev/null
+++ b/support/dktools/dk3config.c
@@ -0,0 +1,4486 @@
+#include <stdio.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#else
+#include "dk3confd.h"
+#endif
+
+#if HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
+#if HAVE_WS2TCPIP_H
+#include <ws2tcpip.h>
+#endif
+#if HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+#if HAVE_WINBASE_H
+#include <winbase.h>
+#endif
+#if HAVE_WINREG_H
+#include <winreg.h>
+#endif
+#if HAVE_WINCON_H
+#include <wincon.h>
+#endif
+#if HAVE_STDIO_H
+#include <stdio.h>
+#endif
+#if HAVE_ERR_H
+#include <err.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_STDDEF_H
+#include <stddef.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_PROCESS_H
+#include <process.h>
+#endif
+#if HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#if HAVE_SYS_SYSCTL_H
+#include <sys/sysctl.h>
+#endif
+#if HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+#if HAVE_SYS_STATVFS_H
+#include <sys/statvfs.h>
+#endif
+#if HAVE_SYS_STROPTS_H
+#include <sys/stropts.h>
+#endif
+#if HAVE_SYS_FILE_H
+#include <sys/file.h>
+#endif
+#if HAVE_SYS_UIO_H
+#include <sys/uio.h>
+#endif
+#if HAVE_SYS_UN_H
+#include <sys/un.h>
+#endif
+#if HAVE_SYS_SUNDDI_H
+#include <sys/sunddi.h>
+#endif
+#if HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+#if HAVE_SYS_SYSTEMINFO_H
+#include <sys/systeminfo.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else
+#if HAVE_TIME_H
+#include <time.h>
+#else
+#if HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#endif
+#endif
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#if HAVE_ALLOC_H
+#include <alloc.h>
+#endif
+#if HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+#if HAVE_CTYPE_H
+#include <ctype.h>
+#endif
+#if HAVE_STRING_H
+#include <string.h>
+#endif
+#if HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#if HAVE_WCHAR_H
+#include <wchar.h>
+#endif
+#if HAVE_STROPTS_H
+#include <stropts.h>
+#endif
+#if HAVE_IO_H
+#include <io.h>
+#endif
+#if HAVE_DOS_H
+#include <dos.h>
+#endif
+#if HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#if HAVE_DIR_H
+#include <dir.h>
+#endif
+#if HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+#if HAVE_DIRECT_H
+#include <direct.h>
+#endif
+#if HAVE_SYSRES_H
+#include <sysres.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_GRP_H
+#include <grp.h>
+#endif
+#if HAVE_PWD_H
+#include <pwd.h>
+#endif
+#if HAVE_MATH_H
+#include <math.h>
+#endif
+#if HAVE_FLOAT_H
+#include <float.h>
+#endif
+#if HAVE_FENV_H
+#include <fenv.h>
+#endif
+#if HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+#if HAVE_SYSLOG_H
+#include <syslog.h>
+#endif
+#if HAVE_CONIO_H
+#include <conio.h>
+#endif
+#if HAVE_STDARG_H
+#include <stdarg.h>
+#else
+#if HAVE_VARARG_H
+#include <vararg.h>
+#else
+#if HAVE_VARARGS_H
+#include <varargs.h>
+#else
+#endif
+#endif
+#endif
+#if HAVE_VARARG_H
+#include <vararg.h>
+#endif
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#if HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if HAVE_TERMIOS_H
+#include <termios.h>
+#endif
+#if HAVE_SHADOW_H
+#include <shadow.h>
+#endif
+#if HAVE_LOCALE_H
+#include <locale.h>
+#endif
+#if HAVE_SYS_TERMIOS_H
+#include <sys/termios.h>
+#endif
+#if HAVE_SYS_TTOLD_H
+#include <sys/ttold.h>
+#endif
+#if HAVE_SETJMP_H
+#include <setjmp.h>
+#endif
+#if HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
+#if HAVE_ZLIB_H
+#include <zlib.h>
+#endif
+#if HAVE_BZLIB_H
+#include <bzlib.h>
+#endif
+
+#ifndef MPL
+#ifdef MAXPATHLEN
+/** Maximum path length.
+*/
+#define MPL MAXPATHLEN
+#else
+#ifdef MAX_PATH
+/** Maximum path length.
+*/
+#define MPL MAX_PATH
+#else
+#ifdef PATH_MAX
+/** Maximum path length.
+*/
+#define MPL PATH_MAX
+#else
+/** Maximum path length.
+*/
+#define MPL 1024
+#endif
+#endif
+#endif
+#endif
+
+int main(int argc, char *argv[])
+{
+ printf("/**\t@file dk3conf.h\tConfiguration for DK3 libraries.\n\tFeatures: Include files, functions, sizes,\n\tand endianness.\n*/\n\n");
+ printf("#ifndef DK3_CONF_H_INCLUDED\n");
+ printf("/** Avoid multiple inclusions. */\n");
+ printf("#define DK3_CONF_H_INCLUDED 1\n\n");
+ printf("#ifndef DK3_ON_WINDOWS\n");
+ printf("#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)\n");
+ printf("/** On a Windows system. */\n");
+ printf("#define DK3_ON_WINDOWS\t1\n");
+ printf("#else\n");
+ printf("/** Not on a Windows system. */\n");
+ printf("#define DK3_ON_WINDOWS\t0\n");
+ printf("#endif\n");
+ printf("#endif\n/** ifndef DK3_ON_WINDOWS */\n");
+ printf("\n#if DK3_ON_WINDOWS\n");
+ printf("\n#ifndef DK3_HAVE_ACOSH\n");
+ printf("/**\tDK3 version of HAVE_ACOSH.\n*/\n");
+ printf("#define DK3_HAVE_ACOSH 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ACOSHL\n");
+ printf("/**\tDK3 version of HAVE_ACOSHL.\n*/\n");
+ printf("#define DK3_HAVE_ACOSHL 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ACOSL\n");
+ printf("/**\tDK3 version of HAVE_ACOSL.\n*/\n");
+ printf("#define DK3_HAVE_ACOSL 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ALLOC_H\n");
+ printf("/**\tDK3 version of HAVE_ALLOC_H.\n*/\n");
+ printf("#define DK3_HAVE_ALLOC_H 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ARPA_INET_H\n");
+ printf("/**\tDK3 version of HAVE_ARPA_INET_H.\n*/\n");
+ printf("#define DK3_HAVE_ARPA_INET_H 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ASINH\n");
+ printf("/**\tDK3 version of HAVE_ASINH.\n*/\n");
+ printf("#define DK3_HAVE_ASINH 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ASINHL\n");
+ printf("/**\tDK3 version of HAVE_ASINHL.\n*/\n");
+ printf("#define DK3_HAVE_ASINHL 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ASINL\n");
+ printf("/**\tDK3 version of HAVE_ASINL.\n*/\n");
+ printf("#define DK3_HAVE_ASINL 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ATAN2\n");
+ printf("/**\tDK3 version of HAVE_ATAN2.\n*/\n");
+ printf("#define DK3_HAVE_ATAN2 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ATAN2L\n");
+ printf("/**\tDK3 version of HAVE_ATAN2L.\n*/\n");
+ printf("#define DK3_HAVE_ATAN2L 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ATANH\n");
+ printf("/**\tDK3 version of HAVE_ATANH.\n*/\n");
+ printf("#define DK3_HAVE_ATANH 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ATANHL\n");
+ printf("/**\tDK3 version of HAVE_ATANHL.\n*/\n");
+ printf("#define DK3_HAVE_ATANHL 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ATANL\n");
+ printf("/**\tDK3 version of HAVE_ATANL.\n*/\n");
+ printf("#define DK3_HAVE_ATANL 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_BACKSLASH\n");
+ printf("/**\tDK3 version of HAVE_BACKSLASH.\n*/\n");
+ printf("#define DK3_HAVE_BACKSLASH 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_BCMP\n");
+ printf("/**\tDK3 version of HAVE_BCMP.\n*/\n");
+ printf("#define DK3_HAVE_BCMP 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_BCOPY\n");
+ printf("/**\tDK3 version of HAVE_BCOPY.\n*/\n");
+ printf("#define DK3_HAVE_BCOPY 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_BZERO\n");
+ printf("/**\tDK3 version of HAVE_BZERO.\n*/\n");
+ printf("#define DK3_HAVE_BZERO 0\n");
+ printf("#endif\n");
+/* WARNING: HAVE_BZLIB_H not defined for Windows! */
+ printf("\n#ifndef DK3_HAVE_CEIL\n");
+ printf("/**\tDK3 version of HAVE_CEIL.\n*/\n");
+ printf("#define DK3_HAVE_CEIL 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_CEILL\n");
+ printf("/**\tDK3 version of HAVE_CEILL.\n*/\n");
+ printf("#define DK3_HAVE_CEILL 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_CHDIR\n");
+ printf("/**\tDK3 version of HAVE_CHDIR.\n*/\n");
+ printf("#define DK3_HAVE_CHDIR 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_CHMOD\n");
+ printf("/**\tDK3 version of HAVE_CHMOD.\n*/\n");
+ printf("#define DK3_HAVE_CHMOD 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_CHOWN\n");
+ printf("/**\tDK3 version of HAVE_CHOWN.\n*/\n");
+ printf("#define DK3_HAVE_CHOWN 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_CLOSEDIR\n");
+ printf("/**\tDK3 version of HAVE_CLOSEDIR.\n*/\n");
+ printf("#define DK3_HAVE_CLOSEDIR 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_CONIO_H\n");
+ printf("/**\tDK3 version of HAVE_CONIO_H.\n*/\n");
+ printf("#define DK3_HAVE_CONIO_H 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_CONST\n");
+ printf("/**\tDK3 version of HAVE_CONST.\n*/\n");
+ printf("#define DK3_HAVE_CONST 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_COSHL\n");
+ printf("/**\tDK3 version of HAVE_COSHL.\n*/\n");
+ printf("#define DK3_HAVE_COSHL 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_COSL\n");
+ printf("/**\tDK3 version of HAVE_COSL.\n*/\n");
+ printf("#define DK3_HAVE_COSL 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_CTYPE_H\n");
+ printf("/**\tDK3 version of HAVE_CTYPE_H.\n*/\n");
+ printf("#define DK3_HAVE_CTYPE_H 1\n");
+ printf("#endif\n");
+/* WARNING: HAVE_DB_CURSOR_C_GET not defined for Windows! */
+/* WARNING: HAVE_DB_H not defined for Windows! */
+ printf("\n#ifndef DK3_HAVE_DEV_RANDOM\n");
+ printf("/**\tDK3 version of HAVE_DEV_RANDOM.\n*/\n");
+ printf("#define DK3_HAVE_DEV_RANDOM 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_DEV_URANDOM\n");
+ printf("/**\tDK3 version of HAVE_DEV_URANDOM.\n*/\n");
+ printf("#define DK3_HAVE_DEV_URANDOM 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_DIRECT_H\n");
+ printf("/**\tDK3 version of HAVE_DIRECT_H.\n*/\n");
+ printf("#define DK3_HAVE_DIRECT_H 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_DIRENT_H\n");
+ printf("/**\tDK3 version of HAVE_DIRENT_H.\n*/\n");
+ printf("#define DK3_HAVE_DIRENT_H 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_DIR_H\n");
+ printf("/**\tDK3 version of HAVE_DIR_H.\n*/\n");
+ printf("#define DK3_HAVE_DIR_H 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_DOS_H\n");
+ printf("/**\tDK3 version of HAVE_DOS_H.\n*/\n");
+ printf("#define DK3_HAVE_DOS_H 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ENDGRENT\n");
+ printf("/**\tDK3 version of HAVE_ENDGRENT.\n*/\n");
+ printf("#define DK3_HAVE_ENDGRENT 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ENDPWENT\n");
+ printf("/**\tDK3 version of HAVE_ENDPWENT.\n*/\n");
+ printf("#define DK3_HAVE_ENDPWENT 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ERRNO_H\n");
+ printf("/**\tDK3 version of HAVE_ERRNO_H.\n*/\n");
+ printf("#define DK3_HAVE_ERRNO_H 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ERR_H\n");
+ printf("/**\tDK3 version of HAVE_ERR_H.\n*/\n");
+ printf("#define DK3_HAVE_ERR_H 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_EXPL\n");
+ printf("/**\tDK3 version of HAVE_EXPL.\n*/\n");
+ printf("#define DK3_HAVE_EXPL 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FABS\n");
+ printf("/**\tDK3 version of HAVE_FABS.\n*/\n");
+ printf("#define DK3_HAVE_FABS 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FABSL\n");
+ printf("/**\tDK3 version of HAVE_FABSL.\n*/\n");
+ printf("#define DK3_HAVE_FABSL 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FCLOSE\n");
+ printf("/**\tDK3 version of HAVE_FCLOSE.\n*/\n");
+ printf("#define DK3_HAVE_FCLOSE 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FCNTL_H\n");
+ printf("/**\tDK3 version of HAVE_FCNTL_H.\n*/\n");
+ printf("#define DK3_HAVE_FCNTL_H 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FENV_H\n");
+ printf("/**\tDK3 version of HAVE_FENV_H.\n*/\n");
+ printf("#define DK3_HAVE_FENV_H 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FEOF\n");
+ printf("/**\tDK3 version of HAVE_FEOF.\n*/\n");
+ printf("#define DK3_HAVE_FEOF 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FERROR\n");
+ printf("/**\tDK3 version of HAVE_FERROR.\n*/\n");
+ printf("#define DK3_HAVE_FERROR 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FETESTEXCEPT\n");
+ printf("/**\tDK3 version of HAVE_FETESTEXCEPT.\n*/\n");
+ printf("#define DK3_HAVE_FETESTEXCEPT 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FFLUSH\n");
+ printf("/**\tDK3 version of HAVE_FFLUSH.\n*/\n");
+ printf("#define DK3_HAVE_FFLUSH 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FLOAT_H\n");
+ printf("/**\tDK3 version of HAVE_FLOAT_H.\n*/\n");
+ printf("#define DK3_HAVE_FLOAT_H 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FLOOR\n");
+ printf("/**\tDK3 version of HAVE_FLOOR.\n*/\n");
+ printf("#define DK3_HAVE_FLOOR 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FLOORL\n");
+ printf("/**\tDK3 version of HAVE_FLOORL.\n*/\n");
+ printf("#define DK3_HAVE_FLOORL 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FNCASEINS\n");
+ printf("/**\tDK3 version of HAVE_FNCASEINS.\n*/\n");
+ printf("#define DK3_HAVE_FNCASEINS 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FOPEN\n");
+ printf("/**\tDK3 version of HAVE_FOPEN.\n*/\n");
+ printf("#define DK3_HAVE_FOPEN 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FOPEN64\n");
+ printf("/**\tDK3 version of HAVE_FOPEN64.\n*/\n");
+ printf("#define DK3_HAVE_FOPEN64 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FOPEN_S\n");
+ printf("#if _MSC_VER >= 1700\n");
+ printf("/**\tDK3 version of HAVE_FOPEN_S.\n*/\n");
+ printf("#define DK3_HAVE_FOPEN_S 1\n");
+ printf("#else\n");
+ printf("/**\tDK3 version of HAVE_FOPEN_S.\n*/\n");
+ printf("#define DK3_HAVE_FOPEN_S 0\n");
+ printf("#endif\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FORK\n");
+ printf("/**\tDK3 version of HAVE_FORK.\n*/\n");
+ printf("#define DK3_HAVE_FORK 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FPCLASSIFY\n");
+ printf("/**\tDK3 version of HAVE_FPCLASSIFY.\n*/\n");
+ printf("#define DK3_HAVE_FPCLASSIFY 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FREAD\n");
+ printf("/**\tDK3 version of HAVE_FREAD.\n*/\n");
+ printf("#define DK3_HAVE_FREAD 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FREE\n");
+ printf("/**\tDK3 version of HAVE_FREE.\n*/\n");
+ printf("#define DK3_HAVE_FREE 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FWRITE\n");
+ printf("/**\tDK3 version of HAVE_FWRITE.\n*/\n");
+ printf("#define DK3_HAVE_FWRITE 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GDBM_H\n");
+ printf("/**\tDK3 version of HAVE_GDBM_H.\n*/\n");
+ printf("#define DK3_HAVE_GDBM_H 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GETADDRINFO\n");
+ printf("/**\tDK3 version of HAVE_GETADDRINFO.\n*/\n");
+ printf("#define DK3_HAVE_GETADDRINFO 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GETCWD\n");
+ printf("/**\tDK3 version of HAVE_GETCWD.\n*/\n");
+ printf("#define DK3_HAVE_GETCWD 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GETENV\n");
+ printf("/**\tDK3 version of HAVE_GETENV.\n*/\n");
+ printf("#define DK3_HAVE_GETENV 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GETEUID\n");
+ printf("/**\tDK3 version of HAVE_GETEUID.\n*/\n");
+ printf("#define DK3_HAVE_GETEUID 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GETGRENT\n");
+ printf("/**\tDK3 version of HAVE_GETGRENT.\n*/\n");
+ printf("#define DK3_HAVE_GETGRENT 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GETGRGID\n");
+ printf("/**\tDK3 version of HAVE_GETGRGID.\n*/\n");
+ printf("#define DK3_HAVE_GETGRGID 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GETGRNAM\n");
+ printf("/**\tDK3 version of HAVE_GETGRNAM.\n*/\n");
+ printf("#define DK3_HAVE_GETGRNAM 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GETHOSTBYNAME\n");
+ printf("/**\tDK3 version of HAVE_GETHOSTBYNAME.\n*/\n");
+ printf("#define DK3_HAVE_GETHOSTBYNAME 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GETHOSTNAME\n");
+ printf("/**\tDK3 version of HAVE_GETHOSTNAME.\n*/\n");
+ printf("#define DK3_HAVE_GETHOSTNAME 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GETPEERNAME\n");
+ printf("/**\tDK3 version of HAVE_GETPEERNAME.\n*/\n");
+ printf("#define DK3_HAVE_GETPEERNAME 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GETPID\n");
+ printf("/**\tDK3 version of HAVE_GETPID.\n*/\n");
+ printf("#define DK3_HAVE_GETPID 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GETPWENT\n");
+ printf("/**\tDK3 version of HAVE_GETPWENT.\n*/\n");
+ printf("#define DK3_HAVE_GETPWENT 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GETPWNAM\n");
+ printf("/**\tDK3 version of HAVE_GETPWNAM.\n*/\n");
+ printf("#define DK3_HAVE_GETPWNAM 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GETPWUID\n");
+ printf("/**\tDK3 version of HAVE_GETPWUID.\n*/\n");
+ printf("#define DK3_HAVE_GETPWUID 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GETRLIMIT\n");
+ printf("/**\tDK3 version of HAVE_GETRLIMIT.\n*/\n");
+ printf("#define DK3_HAVE_GETRLIMIT 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GETSOCKNAME\n");
+ printf("/**\tDK3 version of HAVE_GETSOCKNAME.\n*/\n");
+ printf("#define DK3_HAVE_GETSOCKNAME 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GETUID\n");
+ printf("/**\tDK3 version of HAVE_GETUID.\n*/\n");
+ printf("#define DK3_HAVE_GETUID 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GRP_H\n");
+ printf("/**\tDK3 version of HAVE_GRP_H.\n*/\n");
+ printf("#define DK3_HAVE_GRP_H 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_HTONL\n");
+ printf("/**\tDK3 version of HAVE_HTONL.\n*/\n");
+ printf("#define DK3_HAVE_HTONL 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_IEEE_754_DOUBLE\n");
+ printf("/**\tDK3 version of HAVE_IEEE_754_DOUBLE.\n*/\n");
+ printf("#define DK3_HAVE_IEEE_754_DOUBLE 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_IN6_ADDR\n");
+ printf("/**\tDK3 version of HAVE_IN6_ADDR.\n*/\n");
+ printf("#define DK3_HAVE_IN6_ADDR 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_INET_ADDR\n");
+ printf("/**\tDK3 version of HAVE_INET_ADDR.\n*/\n");
+ printf("#define DK3_HAVE_INET_ADDR 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_INET_ATON\n");
+ printf("/**\tDK3 version of HAVE_INET_ATON.\n*/\n");
+ printf("#define DK3_HAVE_INET_ATON 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_INET_PTON\n");
+ printf("/**\tDK3 version of HAVE_INET_PTON.\n*/\n");
+ printf("#define DK3_HAVE_INET_PTON 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_INITSTATE\n");
+ printf("/**\tDK3 version of HAVE_INITSTATE.\n*/\n");
+ printf("#define DK3_HAVE_INITSTATE 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_INODES\n");
+ printf("/**\tDK3 version of HAVE_INODES.\n*/\n");
+ printf("#define DK3_HAVE_INODES 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_INTMAX_T\n");
+ printf("#if _MSC_VER >= 1700\n");
+ printf("/**\tDK3 version of HAVE_INTMAX_T.\n*/\n");
+ printf("#define DK3_HAVE_INTMAX_T 1\n");
+ printf("#else\n");
+ printf("/**\tDK3 version of HAVE_INTMAX_T.\n*/\n");
+ printf("#define DK3_HAVE_INTMAX_T 0\n");
+ printf("#endif\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_INTTYPES_H\n");
+ printf("/**\tDK3 version of HAVE_INTTYPES_H.\n*/\n");
+ printf("#define DK3_HAVE_INTTYPES_H 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_IN_ADDR\n");
+ printf("/**\tDK3 version of HAVE_IN_ADDR.\n*/\n");
+ printf("#define DK3_HAVE_IN_ADDR 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_IO_H\n");
+ printf("/**\tDK3 version of HAVE_IO_H.\n*/\n");
+ printf("#define DK3_HAVE_IO_H 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ISATTY\n");
+ printf("/**\tDK3 version of HAVE_ISATTY.\n*/\n");
+ printf("#define DK3_HAVE_ISATTY 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ISFINITE\n");
+ printf("/**\tDK3 version of HAVE_ISFINITE.\n*/\n");
+ printf("#define DK3_HAVE_ISFINITE 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ISNORMAL\n");
+ printf("/**\tDK3 version of HAVE_ISNORMAL.\n*/\n");
+ printf("#define DK3_HAVE_ISNORMAL 0\n");
+ printf("#endif\n");
+/* WARNING: HAVE_JPEGLIB_H not defined for Windows! */
+ printf("\n#ifndef DK3_HAVE_LABS\n");
+ printf("/**\tDK3 version of HAVE_LABS.\n*/\n");
+ printf("#define DK3_HAVE_LABS 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_LARGEFILE64_SOURCE\n");
+ printf("/**\tDK3 version of HAVE_LARGEFILE64_SOURCE.\n*/\n");
+ printf("#define DK3_HAVE_LARGEFILE64_SOURCE 0\n");
+ printf("#endif\n");
+/* WARNING: HAVE_LIBNETSNMP not defined for Windows! */
+ printf("\n#ifndef DK3_HAVE_LIMITS_H\n");
+ printf("/**\tDK3 version of HAVE_LIMITS_H.\n*/\n");
+ printf("#define DK3_HAVE_LIMITS_H 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_LOCALE_H\n");
+ printf("/**\tDK3 version of HAVE_LOCALE_H.\n*/\n");
+ printf("#define DK3_HAVE_LOCALE_H 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_LOCALTIME\n");
+ printf("/**\tDK3 version of HAVE_LOCALTIME.\n*/\n");
+ printf("#define DK3_HAVE_LOCALTIME 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_LOCALTIME\n");
+ printf("/**\tDK3 version of HAVE_LOCALTIME.\n*/\n");
+ printf("#define DK3_HAVE_LOCALTIME 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_LOCALTIME_R\n");
+ printf("/**\tDK3 version of HAVE_LOCALTIME_R.\n*/\n");
+ printf("#define DK3_HAVE_LOCALTIME_R 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_LOCALTIME_S\n");
+ printf("#if _MSC_VER >= 1700\n");
+ printf("/**\tDK3 version of HAVE_LOCALTIME_S.\n*/\n");
+ printf("#define DK3_HAVE_LOCALTIME_S 1\n");
+ printf("#else\n");
+ printf("/**\tDK3 version of HAVE_LOCALTIME_S.\n*/\n");
+ printf("#define DK3_HAVE_LOCALTIME_S 0\n");
+ printf("#endif\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_LOGL\n");
+ printf("/**\tDK3 version of HAVE_LOGL.\n*/\n");
+ printf("#define DK3_HAVE_LOGL 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_LONG_DOUBLE\n");
+ printf("/**\tDK3 version of HAVE_LONG_DOUBLE.\n*/\n");
+ printf("#define DK3_HAVE_LONG_DOUBLE 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_LONG_LONG\n");
+ printf("/**\tDK3 version of HAVE_LONG_LONG.\n*/\n");
+ printf("#define DK3_HAVE_LONG_LONG 1\n");
+ printf("#endif\n");
+/* WARNING: HAVE_LPRNG_H not defined for Windows! */
+ printf("\n#ifndef DK3_HAVE_LRAND48\n");
+ printf("/**\tDK3 version of HAVE_LRAND48.\n*/\n");
+ printf("#define DK3_HAVE_LRAND48 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_LSTAT\n");
+ printf("/**\tDK3 version of HAVE_LSTAT.\n*/\n");
+ printf("#define DK3_HAVE_LSTAT 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_LSTAT32\n");
+ printf("/**\tDK3 version of HAVE_LSTAT32.\n*/\n");
+ printf("#define DK3_HAVE_LSTAT32 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_LSTAT64\n");
+ printf("/**\tDK3 version of HAVE_LSTAT64.\n*/\n");
+ printf("#define DK3_HAVE_LSTAT64 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_MALLOC\n");
+ printf("/**\tDK3 version of HAVE_MALLOC.\n*/\n");
+ printf("#define DK3_HAVE_MALLOC 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_MALLOC_H\n");
+ printf("/**\tDK3 version of HAVE_MALLOC_H.\n*/\n");
+ printf("#define DK3_HAVE_MALLOC_H 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_MATH_H\n");
+ printf("/**\tDK3 version of HAVE_MATH_H.\n*/\n");
+ printf("#define DK3_HAVE_MATH_H 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_MEMCMP\n");
+ printf("/**\tDK3 version of HAVE_MEMCMP.\n*/\n");
+ printf("#define DK3_HAVE_MEMCMP 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_MEMCPY\n");
+ printf("/**\tDK3 version of HAVE_MEMCPY.\n*/\n");
+ printf("#define DK3_HAVE_MEMCPY 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_MEMSET\n");
+ printf("/**\tDK3 version of HAVE_MEMSET.\n*/\n");
+ printf("#define DK3_HAVE_MEMSET 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_MKDIR\n");
+ printf("/**\tDK3 version of HAVE_MKDIR.\n*/\n");
+ printf("#define DK3_HAVE_MKDIR 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_MKDIR2\n");
+ printf("/**\tDK3 version of HAVE_MKDIR2.\n*/\n");
+ printf("#define DK3_HAVE_MKDIR2 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_MPCTL\n");
+ printf("/**\tDK3 version of HAVE_MPCTL.\n*/\n");
+ printf("#define DK3_HAVE_MPCTL 0\n");
+ printf("#endif\n");
+/* WARNING: HAVE_MYSQL_LIBRARY_END not defined for Windows! */
+/* WARNING: HAVE_MYSQL_LIBRARY_INIT not defined for Windows! */
+/* WARNING: HAVE_MYSQL_MYSQL_H not defined for Windows! */
+/* WARNING: HAVE_MYSQL_SET_CHARACTER_SET not defined for Windows! */
+ printf("\n#ifndef DK3_HAVE_NDBM_H\n");
+ printf("/**\tDK3 version of HAVE_NDBM_H.\n*/\n");
+ printf("#define DK3_HAVE_NDBM_H 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_NETDB_H\n");
+ printf("/**\tDK3 version of HAVE_NETDB_H.\n*/\n");
+ printf("#define DK3_HAVE_NETDB_H 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_NETINET_IN_H\n");
+ printf("/**\tDK3 version of HAVE_NETINET_IN_H.\n*/\n");
+ printf("#define DK3_HAVE_NETINET_IN_H 0\n");
+ printf("#endif\n");
+/* WARNING: HAVE_NETSNMP_ENABLE_FILELOG not defined for Windows! */
+ printf("\n#ifndef DK3_HAVE_NRAND48\n");
+ printf("/**\tDK3 version of HAVE_NRAND48.\n*/\n");
+ printf("#define DK3_HAVE_NRAND48 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_OPENDIR\n");
+ printf("/**\tDK3 version of HAVE_OPENDIR.\n*/\n");
+ printf("#define DK3_HAVE_OPENDIR 0\n");
+ printf("#endif\n");
+/* WARNING: HAVE_OPENSSL_MD5_H not defined for Windows! */
+/* WARNING: HAVE_OPENSSL_RAND_H not defined for Windows! */
+/* WARNING: HAVE_OPENSSL_RIPEMD_H not defined for Windows! */
+/* WARNING: HAVE_OPENSSL_SHA_H not defined for Windows! */
+ printf("\n#ifndef DK3_HAVE_PNG_GET_PIXELS_PER_INCH\n");
+ printf("/**\tDK3 version of HAVE_PNG_GET_PIXELS_PER_INCH.\n*/\n");
+ printf("#define DK3_HAVE_PNG_GET_PIXELS_PER_INCH 1\n");
+ printf("#endif\n");
+/* WARNING: HAVE_PNG_H not defined for Windows! */
+ printf("\n#ifndef DK3_HAVE_POPEN\n");
+ printf("/**\tDK3 version of HAVE_POPEN.\n*/\n");
+ printf("#define DK3_HAVE_POPEN 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_PROCESS_H\n");
+ printf("/**\tDK3 version of HAVE_PROCESS_H.\n*/\n");
+ printf("#define DK3_HAVE_PROCESS_H 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_PTHREAD_H\n");
+ printf("/**\tDK3 version of HAVE_PTHREAD_H.\n*/\n");
+ printf("#define DK3_HAVE_PTHREAD_H 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_PWD_H\n");
+ printf("/**\tDK3 version of HAVE_PWD_H.\n*/\n");
+ printf("#define DK3_HAVE_PWD_H 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_RAND\n");
+ printf("/**\tDK3 version of HAVE_RAND.\n*/\n");
+ printf("#define DK3_HAVE_RAND 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_RANDOM\n");
+ printf("/**\tDK3 version of HAVE_RANDOM.\n*/\n");
+ printf("#define DK3_HAVE_RANDOM 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_READ\n");
+ printf("/**\tDK3 version of HAVE_READ.\n*/\n");
+ printf("#define DK3_HAVE_READ 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_READDIR\n");
+ printf("/**\tDK3 version of HAVE_READDIR.\n*/\n");
+ printf("#define DK3_HAVE_READDIR 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_RFC_2249\n");
+ printf("/**\tDK3 version of HAVE_RFC_2249.\n*/\n");
+ printf("#define DK3_HAVE_RFC_2249 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_RINT\n");
+ printf("/**\tDK3 version of HAVE_RINT.\n*/\n");
+ printf("#define DK3_HAVE_RINT 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_RINTL\n");
+ printf("/**\tDK3 version of HAVE_RINTL.\n*/\n");
+ printf("#define DK3_HAVE_RINTL 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_RMDIR\n");
+ printf("/**\tDK3 version of HAVE_RMDIR.\n*/\n");
+ printf("#define DK3_HAVE_RMDIR 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SEED48\n");
+ printf("/**\tDK3 version of HAVE_SEED48.\n*/\n");
+ printf("#define DK3_HAVE_SEED48 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SELECT\n");
+ printf("/**\tDK3 version of HAVE_SELECT.\n*/\n");
+ printf("#define DK3_HAVE_SELECT 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SETGID\n");
+ printf("/**\tDK3 version of HAVE_SETGID.\n*/\n");
+ printf("#define DK3_HAVE_SETGID 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SETGRENT\n");
+ printf("/**\tDK3 version of HAVE_SETGRENT.\n*/\n");
+ printf("#define DK3_HAVE_SETGRENT 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SETJMP_H\n");
+ printf("/**\tDK3 version of HAVE_SETJMP_H.\n*/\n");
+ printf("#define DK3_HAVE_SETJMP_H 1\n");
+ printf("#endif\n");
+/* WARNING: HAVE_SETLOCALE not defined for Windows! */
+ printf("\n#ifndef DK3_HAVE_SETPGRP\n");
+ printf("/**\tDK3 version of HAVE_SETPGRP.\n*/\n");
+ printf("#define DK3_HAVE_SETPGRP 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SETPWENT\n");
+ printf("/**\tDK3 version of HAVE_SETPWENT.\n*/\n");
+ printf("#define DK3_HAVE_SETPWENT 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SETSID\n");
+ printf("/**\tDK3 version of HAVE_SETSID.\n*/\n");
+ printf("#define DK3_HAVE_SETSID 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SETSOCKOPT\n");
+ printf("/**\tDK3 version of HAVE_SETSOCKOPT.\n*/\n");
+ printf("#define DK3_HAVE_SETSOCKOPT 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SETSTATE\n");
+ printf("/**\tDK3 version of HAVE_SETSTATE.\n*/\n");
+ printf("#define DK3_HAVE_SETSTATE 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SETUID\n");
+ printf("/**\tDK3 version of HAVE_SETUID.\n*/\n");
+ printf("#define DK3_HAVE_SETUID 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SETVBUF\n");
+ printf("/**\tDK3 version of HAVE_SETVBUF.\n*/\n");
+ printf("#define DK3_HAVE_SETVBUF 1\n");
+ printf("#endif\n");
+/* WARNING: HAVE_SHA224 not defined for Windows! */
+/* WARNING: HAVE_SHA256 not defined for Windows! */
+/* WARNING: HAVE_SHA384 not defined for Windows! */
+/* WARNING: HAVE_SHA512 not defined for Windows! */
+ printf("\n#ifndef DK3_HAVE_SHADOW_H\n");
+ printf("/**\tDK3 version of HAVE_SHADOW_H.\n*/\n");
+ printf("#define DK3_HAVE_SHADOW_H 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SIGACTION\n");
+ printf("/**\tDK3 version of HAVE_SIGACTION.\n*/\n");
+ printf("#define DK3_HAVE_SIGACTION 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SIGNAL\n");
+ printf("/**\tDK3 version of HAVE_SIGNAL.\n*/\n");
+ printf("#define DK3_HAVE_SIGNAL 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SIGNAL_H\n");
+ printf("/**\tDK3 version of HAVE_SIGNAL_H.\n*/\n");
+ printf("#define DK3_HAVE_SIGNAL_H 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SIGSET\n");
+ printf("/**\tDK3 version of HAVE_SIGSET.\n*/\n");
+ printf("#define DK3_HAVE_SIGSET 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SIG_ATOMIC_T\n");
+ printf("/**\tDK3 version of HAVE_SIG_ATOMIC_T.\n*/\n");
+ printf("#define DK3_HAVE_SIG_ATOMIC_T 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SINHL\n");
+ printf("/**\tDK3 version of HAVE_SINHL.\n*/\n");
+ printf("#define DK3_HAVE_SINHL 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SINL\n");
+ printf("/**\tDK3 version of HAVE_SINL.\n*/\n");
+ printf("#define DK3_HAVE_SINL 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SNPRINTF\n");
+ printf("/**\tDK3 version of HAVE_SNPRINTF.\n*/\n");
+ printf("#define DK3_HAVE_SNPRINTF 0\n");
+ printf("#endif\n");
+/* WARNING: HAVE_SNWPRINTF not defined for Windows! */
+ printf("\n#ifndef DK3_HAVE_SOCKET\n");
+ printf("/**\tDK3 version of HAVE_SOCKET.\n*/\n");
+ printf("#define DK3_HAVE_SOCKET 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SOCKLEN_T\n");
+ printf("/**\tDK3 version of HAVE_SOCKLEN_T.\n*/\n");
+ printf("#define DK3_HAVE_SOCKLEN_T 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SPRINTF_S\n");
+ printf("#if _MSC_VER >= 1700\n");
+ printf("/**\tDK3 version of HAVE_SPRINTF_S.\n*/\n");
+ printf("#define DK3_HAVE_SPRINTF_S 1\n");
+ printf("#else\n");
+ printf("/**\tDK3 version of HAVE_SPRINTF_S.\n*/\n");
+ printf("#define DK3_HAVE_SPRINTF_S 0\n");
+ printf("#endif\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SQRTL\n");
+ printf("/**\tDK3 version of HAVE_SQRTL.\n*/\n");
+ printf("#define DK3_HAVE_SQRTL 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SRAND\n");
+ printf("/**\tDK3 version of HAVE_SRAND.\n*/\n");
+ printf("#define DK3_HAVE_SRAND 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SSCANF_S\n");
+ printf("#if _MSC_VER >= 1700\n");
+ printf("/**\tDK3 version of HAVE_SSCANF_S.\n*/\n");
+ printf("#define DK3_HAVE_SSCANF_S 1\n");
+ printf("#else\n");
+ printf("/**\tDK3 version of HAVE_SSCANF_S.\n*/\n");
+ printf("#define DK3_HAVE_SSCANF_S 0\n");
+ printf("#endif\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SSIZE_T\n");
+ printf("/**\tDK3 version of HAVE_SSIZE_T.\n*/\n");
+ printf("#define DK3_HAVE_SSIZE_T 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STAT\n");
+ printf("/**\tDK3 version of HAVE_STAT.\n*/\n");
+ printf("#define DK3_HAVE_STAT 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STAT32\n");
+ printf("/**\tDK3 version of HAVE_STAT32.\n*/\n");
+ printf("#define DK3_HAVE_STAT32 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STAT64\n");
+ printf("/**\tDK3 version of HAVE_STAT64.\n*/\n");
+ printf("#define DK3_HAVE_STAT64 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STDARG_H\n");
+ printf("/**\tDK3 version of HAVE_STDARG_H.\n*/\n");
+ printf("#define DK3_HAVE_STDARG_H 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STDDEF_H\n");
+ printf("/**\tDK3 version of HAVE_STDDEF_H.\n*/\n");
+ printf("#define DK3_HAVE_STDDEF_H 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STDINT_H\n");
+ printf("#if _MSC_VER >= 1700\n");
+ printf("/**\tDK3 version of HAVE_STDINT_H.\n*/\n");
+ printf("#define DK3_HAVE_STDINT_H 1\n");
+ printf("#else\n");
+ printf("/**\tDK3 version of HAVE_STDINT_H.\n*/\n");
+ printf("#define DK3_HAVE_STDINT_H 0\n");
+ printf("#endif\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STDIO_H\n");
+ printf("/**\tDK3 version of HAVE_STDIO_H.\n*/\n");
+ printf("#define DK3_HAVE_STDIO_H 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STDLIB_H\n");
+ printf("/**\tDK3 version of HAVE_STDLIB_H.\n*/\n");
+ printf("#define DK3_HAVE_STDLIB_H 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRCASECMP\n");
+ printf("/**\tDK3 version of HAVE_STRCASECMP.\n*/\n");
+ printf("#define DK3_HAVE_STRCASECMP 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRCAT\n");
+ printf("/**\tDK3 version of HAVE_STRCAT.\n*/\n");
+ printf("#define DK3_HAVE_STRCAT 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRCAT_S\n");
+ printf("#if _MSC_VER >= 1700\n");
+ printf("/**\tDK3 version of HAVE_STRCAT_S.\n*/\n");
+ printf("#define DK3_HAVE_STRCAT_S 1\n");
+ printf("#else\n");
+ printf("/**\tDK3 version of HAVE_STRCAT_S.\n*/\n");
+ printf("#define DK3_HAVE_STRCAT_S 0\n");
+ printf("#endif\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRCHR\n");
+ printf("/**\tDK3 version of HAVE_STRCHR.\n*/\n");
+ printf("#define DK3_HAVE_STRCHR 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRCMP\n");
+ printf("/**\tDK3 version of HAVE_STRCMP.\n*/\n");
+ printf("#define DK3_HAVE_STRCMP 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRCPY\n");
+ printf("/**\tDK3 version of HAVE_STRCPY.\n*/\n");
+ printf("#define DK3_HAVE_STRCPY 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRCPY_S\n");
+ printf("#if _MSC_VER >= 1700\n");
+ printf("/**\tDK3 version of HAVE_STRCPY_S.\n*/\n");
+ printf("#define DK3_HAVE_STRCPY_S 1\n");
+ printf("#else\n");
+ printf("/**\tDK3 version of HAVE_STRCPY_S.\n*/\n");
+ printf("#define DK3_HAVE_STRCPY_S 0\n");
+ printf("#endif\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRDUP\n");
+ printf("/**\tDK3 version of HAVE_STRDUP.\n*/\n");
+ printf("#define DK3_HAVE_STRDUP 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRERROR\n");
+ printf("/**\tDK3 version of HAVE_STRERROR.\n*/\n");
+ printf("#define DK3_HAVE_STRERROR 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRICMP\n");
+ printf("/**\tDK3 version of HAVE_STRICMP.\n*/\n");
+ printf("#define DK3_HAVE_STRICMP 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRINGS_H\n");
+ printf("/**\tDK3 version of HAVE_STRINGS_H.\n*/\n");
+ printf("#define DK3_HAVE_STRINGS_H 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRING_H\n");
+ printf("/**\tDK3 version of HAVE_STRING_H.\n*/\n");
+ printf("#define DK3_HAVE_STRING_H 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRLEN\n");
+ printf("/**\tDK3 version of HAVE_STRLEN.\n*/\n");
+ printf("#define DK3_HAVE_STRLEN 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRNCMP\n");
+ printf("/**\tDK3 version of HAVE_STRNCMP.\n*/\n");
+ printf("#define DK3_HAVE_STRNCMP 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRNCPY\n");
+ printf("/**\tDK3 version of HAVE_STRNCPY.\n*/\n");
+ printf("#define DK3_HAVE_STRNCPY 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRNCPY_S\n");
+ printf("#if _MSC_VER >= 1700\n");
+ printf("/**\tDK3 version of HAVE_STRNCPY_S.\n*/\n");
+ printf("#define DK3_HAVE_STRNCPY_S 1\n");
+ printf("#else\n");
+ printf("/**\tDK3 version of HAVE_STRNCPY_S.\n*/\n");
+ printf("#define DK3_HAVE_STRNCPY_S 0\n");
+ printf("#endif\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STROPTS_H\n");
+ printf("/**\tDK3 version of HAVE_STROPTS_H.\n*/\n");
+ printf("#define DK3_HAVE_STROPTS_H 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRRCHR\n");
+ printf("/**\tDK3 version of HAVE_STRRCHR.\n*/\n");
+ printf("#define DK3_HAVE_STRRCHR 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRTOD\n");
+ printf("/**\tDK3 version of HAVE_STRTOD.\n*/\n");
+ printf("#define DK3_HAVE_STRTOD 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRTOIMAX\n");
+ printf("#if _MSC_VER >= 1800\n");
+ printf("/**\tDK3 version of HAVE_STRTOIMAX.\n*/\n");
+ printf("#define DK3_HAVE_STRTOIMAX 1\n");
+ printf("#else\n");
+ printf("/**\tDK3 version of HAVE_STRTOIMAX.\n*/\n");
+ printf("#define DK3_HAVE_STRTOIMAX 0\n");
+ printf("#endif\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRTOL\n");
+ printf("#if _MSC_VER >= 1700\n");
+ printf("/**\tDK3 version of HAVE_STRTOL.\n*/\n");
+ printf("#define DK3_HAVE_STRTOL 1\n");
+ printf("#else\n");
+ printf("/**\tDK3 version of HAVE_STRTOL.\n*/\n");
+ printf("#define DK3_HAVE_STRTOL 0\n");
+ printf("#endif\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRTOLL\n");
+ printf("#if _MSC_VER >= 1700\n");
+ printf("/**\tDK3 version of HAVE_STRTOLL.\n*/\n");
+ printf("#define DK3_HAVE_STRTOLL 1\n");
+ printf("#else\n");
+ printf("/**\tDK3 version of HAVE_STRTOLL.\n*/\n");
+ printf("#define DK3_HAVE_STRTOLL 0\n");
+ printf("#endif\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRTOUL\n");
+ printf("#if _MSC_VER >= 1700\n");
+ printf("/**\tDK3 version of HAVE_STRTOUL.\n*/\n");
+ printf("#define DK3_HAVE_STRTOUL 1\n");
+ printf("#else\n");
+ printf("/**\tDK3 version of HAVE_STRTOUL.\n*/\n");
+ printf("#define DK3_HAVE_STRTOUL 0\n");
+ printf("#endif\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRTOULL\n");
+ printf("#if _MSC_VER >= 1700\n");
+ printf("/**\tDK3 version of HAVE_STRTOULL.\n*/\n");
+ printf("#define DK3_HAVE_STRTOULL 1\n");
+ printf("#else\n");
+ printf("/**\tDK3 version of HAVE_STRTOULL.\n*/\n");
+ printf("#define DK3_HAVE_STRTOULL 0\n");
+ printf("#endif\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRTOUMAX\n");
+ printf("#if _MSC_VER >= 1800\n");
+ printf("/**\tDK3 version of HAVE_STRTOUMAX.\n*/\n");
+ printf("#define DK3_HAVE_STRTOUMAX 1\n");
+ printf("#else\n");
+ printf("/**\tDK3 version of HAVE_STRTOUMAX.\n*/\n");
+ printf("#define DK3_HAVE_STRTOUMAX 0\n");
+ printf("#endif\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRUCT_ADDRINFO\n");
+ printf("/**\tDK3 version of HAVE_STRUCT_ADDRINFO.\n*/\n");
+ printf("#define DK3_HAVE_STRUCT_ADDRINFO 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRUCT_SOCKADDR_IN\n");
+ printf("/**\tDK3 version of HAVE_STRUCT_SOCKADDR_IN.\n*/\n");
+ printf("#define DK3_HAVE_STRUCT_SOCKADDR_IN 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRUCT_SOCKADDR_IN6\n");
+ printf("/**\tDK3 version of HAVE_STRUCT_SOCKADDR_IN6.\n*/\n");
+ printf("#define DK3_HAVE_STRUCT_SOCKADDR_IN6 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRUCT_SOCKADDR_STORAGE\n");
+ printf("/**\tDK3 version of HAVE_STRUCT_SOCKADDR_STORAGE.\n*/\n");
+ printf("#define DK3_HAVE_STRUCT_SOCKADDR_STORAGE 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRUCT_SOCKADDR_UN\n");
+ printf("/**\tDK3 version of HAVE_STRUCT_SOCKADDR_UN.\n*/\n");
+ printf("#define DK3_HAVE_STRUCT_SOCKADDR_UN 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SWSCANF_S\n");
+ printf("#if _MSC_VER >= 1700\n");
+ printf("/**\tDK3 version of HAVE_SWSCANF_S.\n*/\n");
+ printf("#define DK3_HAVE_SWSCANF_S 1\n");
+ printf("#else\n");
+ printf("/**\tDK3 version of HAVE_SWSCANF_S.\n*/\n");
+ printf("#define DK3_HAVE_SWSCANF_S 0\n");
+ printf("#endif\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYSCONF\n");
+ printf("/**\tDK3 version of HAVE_SYSCONF.\n*/\n");
+ printf("#define DK3_HAVE_SYSCONF 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYSCTL\n");
+ printf("/**\tDK3 version of HAVE_SYSCTL.\n*/\n");
+ printf("#define DK3_HAVE_SYSCTL 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYSLOG\n");
+ printf("/**\tDK3 version of HAVE_SYSLOG.\n*/\n");
+ printf("#define DK3_HAVE_SYSLOG 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYSLOG_H\n");
+ printf("/**\tDK3 version of HAVE_SYSLOG_H.\n*/\n");
+ printf("#define DK3_HAVE_SYSLOG_H 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYSRES_H\n");
+ printf("/**\tDK3 version of HAVE_SYSRES_H.\n*/\n");
+ printf("#define DK3_HAVE_SYSRES_H 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYS_FILE_H\n");
+ printf("/**\tDK3 version of HAVE_SYS_FILE_H.\n*/\n");
+ printf("#define DK3_HAVE_SYS_FILE_H 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYS_PARAM_H\n");
+ printf("/**\tDK3 version of HAVE_SYS_PARAM_H.\n*/\n");
+ printf("#define DK3_HAVE_SYS_PARAM_H 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYS_RESOURCE_H\n");
+ printf("/**\tDK3 version of HAVE_SYS_RESOURCE_H.\n*/\n");
+ printf("#define DK3_HAVE_SYS_RESOURCE_H 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYS_SOCKET_H\n");
+ printf("/**\tDK3 version of HAVE_SYS_SOCKET_H.\n*/\n");
+ printf("#define DK3_HAVE_SYS_SOCKET_H 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYS_STATVFS_H\n");
+ printf("/**\tDK3 version of HAVE_SYS_STATVFS_H.\n*/\n");
+ printf("#define DK3_HAVE_SYS_STATVFS_H 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYS_STAT_H\n");
+ printf("/**\tDK3 version of HAVE_SYS_STAT_H.\n*/\n");
+ printf("#define DK3_HAVE_SYS_STAT_H 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYS_STROPTS_H\n");
+ printf("/**\tDK3 version of HAVE_SYS_STROPTS_H.\n*/\n");
+ printf("#define DK3_HAVE_SYS_STROPTS_H 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYS_SUNDDI_H\n");
+ printf("/**\tDK3 version of HAVE_SYS_SUNDDI_H.\n*/\n");
+ printf("#define DK3_HAVE_SYS_SUNDDI_H 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYS_SYSCTL_H\n");
+ printf("/**\tDK3 version of HAVE_SYS_SYSCTL_H.\n*/\n");
+ printf("#define DK3_HAVE_SYS_SYSCTL_H 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYS_SYSTEMINFO_H\n");
+ printf("/**\tDK3 version of HAVE_SYS_SYSTEMINFO_H.\n*/\n");
+ printf("#define DK3_HAVE_SYS_SYSTEMINFO_H 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYS_TERMIOS_H\n");
+ printf("/**\tDK3 version of HAVE_SYS_TERMIOS_H.\n*/\n");
+ printf("#define DK3_HAVE_SYS_TERMIOS_H 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYS_TIME_H\n");
+ printf("/**\tDK3 version of HAVE_SYS_TIME_H.\n*/\n");
+ printf("#define DK3_HAVE_SYS_TIME_H 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYS_TTOLD_H\n");
+ printf("/**\tDK3 version of HAVE_SYS_TTOLD_H.\n*/\n");
+ printf("#define DK3_HAVE_SYS_TTOLD_H 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYS_TYPES_H\n");
+ printf("/**\tDK3 version of HAVE_SYS_TYPES_H.\n*/\n");
+ printf("#define DK3_HAVE_SYS_TYPES_H 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYS_UIO_H\n");
+ printf("/**\tDK3 version of HAVE_SYS_UIO_H.\n*/\n");
+ printf("#define DK3_HAVE_SYS_UIO_H 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYS_UN_H\n");
+ printf("/**\tDK3 version of HAVE_SYS_UN_H.\n*/\n");
+ printf("#define DK3_HAVE_SYS_UN_H 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYS_WAIT_H\n");
+ printf("/**\tDK3 version of HAVE_SYS_WAIT_H.\n*/\n");
+ printf("#define DK3_HAVE_SYS_WAIT_H 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_TANHL\n");
+ printf("/**\tDK3 version of HAVE_TANHL.\n*/\n");
+ printf("#define DK3_HAVE_TANHL 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_TANL\n");
+ printf("/**\tDK3 version of HAVE_TANL.\n*/\n");
+ printf("#define DK3_HAVE_TANL 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_TCFLUSH\n");
+ printf("/**\tDK3 version of HAVE_TCFLUSH.\n*/\n");
+ printf("#define DK3_HAVE_TCFLUSH 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_TCGETATTR\n");
+ printf("/**\tDK3 version of HAVE_TCGETATTR.\n*/\n");
+ printf("#define DK3_HAVE_TCGETATTR 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_TERMIOS_H\n");
+ printf("/**\tDK3 version of HAVE_TERMIOS_H.\n*/\n");
+ printf("#define DK3_HAVE_TERMIOS_H 0\n");
+ printf("#endif\n");
+/* WARNING: HAVE_TIFF_H not defined for Windows! */
+ printf("\n#ifndef DK3_HAVE_TIME\n");
+ printf("/**\tDK3 version of HAVE_TIME.\n*/\n");
+ printf("#define DK3_HAVE_TIME 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_TIME_H\n");
+ printf("/**\tDK3 version of HAVE_TIME_H.\n*/\n");
+ printf("#define DK3_HAVE_TIME_H 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_TWOS_COMPLEMENT\n");
+ printf("/**\tDK3 version of HAVE_TWOS_COMPLEMENT.\n*/\n");
+ printf("#define DK3_HAVE_TWOS_COMPLEMENT 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_UMASK\n");
+ printf("/**\tDK3 version of HAVE_UMASK.\n*/\n");
+ printf("#define DK3_HAVE_UMASK 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_UNISTD_H\n");
+ printf("/**\tDK3 version of HAVE_UNISTD_H.\n*/\n");
+ printf("#define DK3_HAVE_UNISTD_H 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_UNLINK\n");
+ printf("/**\tDK3 version of HAVE_UNLINK.\n*/\n");
+ printf("#define DK3_HAVE_UNLINK 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_USER_NAMES_CASE_INSENSITIVE\n");
+ printf("/**\tDK3 version of HAVE_USER_NAMES_CASE_INSENSITIVE.\n*/\n");
+ printf("#define DK3_HAVE_USER_NAMES_CASE_INSENSITIVE 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_VARARGS_H\n");
+ printf("/**\tDK3 version of HAVE_VARARGS_H.\n*/\n");
+ printf("#define DK3_HAVE_VARARGS_H 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_VARARG_H\n");
+ printf("/**\tDK3 version of HAVE_VARARG_H.\n*/\n");
+ printf("#define DK3_HAVE_VARARG_H 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_VOLATILE\n");
+ printf("/**\tDK3 version of HAVE_VOLATILE.\n*/\n");
+ printf("#define DK3_HAVE_VOLATILE 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCHAR_H\n");
+ printf("/**\tDK3 version of HAVE_WCHAR_H.\n*/\n");
+ printf("#define DK3_HAVE_WCHAR_H 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCHAR_T\n");
+ printf("/**\tDK3 version of HAVE_WCHAR_T.\n*/\n");
+ printf("#define DK3_HAVE_WCHAR_T 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSCAT\n");
+ printf("/**\tDK3 version of HAVE_WCSCAT.\n*/\n");
+ printf("#define DK3_HAVE_WCSCAT 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSCAT_S\n");
+ printf("#if _MSC_VER >= 1700\n");
+ printf("/**\tDK3 version of HAVE_WCSCAT_S.\n*/\n");
+ printf("#define DK3_HAVE_WCSCAT_S 1\n");
+ printf("#else\n");
+ printf("/**\tDK3 version of HAVE_WCSCAT_S.\n*/\n");
+ printf("#define DK3_HAVE_WCSCAT_S 0\n");
+ printf("#endif\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSCHR\n");
+ printf("/**\tDK3 version of HAVE_WCSCHR.\n*/\n");
+ printf("#define DK3_HAVE_WCSCHR 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSCMP\n");
+ printf("/**\tDK3 version of HAVE_WCSCMP.\n*/\n");
+ printf("#define DK3_HAVE_WCSCMP 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSCPY\n");
+ printf("/**\tDK3 version of HAVE_WCSCPY.\n*/\n");
+ printf("#define DK3_HAVE_WCSCPY 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSCPY_S\n");
+ printf("#if _MSC_VER >= 1700\n");
+ printf("/**\tDK3 version of HAVE_WCSCPY_S.\n*/\n");
+ printf("#define DK3_HAVE_WCSCPY_S 1\n");
+ printf("#else\n");
+ printf("/**\tDK3 version of HAVE_WCSCPY_S.\n*/\n");
+ printf("#define DK3_HAVE_WCSCPY_S 0\n");
+ printf("#endif\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSDUP\n");
+ printf("/**\tDK3 version of HAVE_WCSDUP.\n*/\n");
+ printf("#define DK3_HAVE_WCSDUP 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSICMP\n");
+ printf("/**\tDK3 version of HAVE_WCSICMP.\n*/\n");
+ printf("#define DK3_HAVE_WCSICMP 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSLEN\n");
+ printf("/**\tDK3 version of HAVE_WCSLEN.\n*/\n");
+ printf("#define DK3_HAVE_WCSLEN 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSNCMP\n");
+ printf("/**\tDK3 version of HAVE_WCSNCMP.\n*/\n");
+ printf("#define DK3_HAVE_WCSNCMP 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSNCPY\n");
+ printf("/**\tDK3 version of HAVE_WCSNCPY.\n*/\n");
+ printf("#define DK3_HAVE_WCSNCPY 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSNCPY_S\n");
+ printf("#if _MSC_VER >= 1700\n");
+ printf("/**\tDK3 version of HAVE_WCSNCPY_S.\n*/\n");
+ printf("#define DK3_HAVE_WCSNCPY_S 1\n");
+ printf("#else\n");
+ printf("/**\tDK3 version of HAVE_WCSNCPY_S.\n*/\n");
+ printf("#define DK3_HAVE_WCSNCPY_S 0\n");
+ printf("#endif\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSRCHR\n");
+ printf("/**\tDK3 version of HAVE_WCSRCHR.\n*/\n");
+ printf("#define DK3_HAVE_WCSRCHR 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSTOD\n");
+ printf("/**\tDK3 version of HAVE_WCSTOD.\n*/\n");
+ printf("#define DK3_HAVE_WCSTOD 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSTOIMAX\n");
+ printf("#if _MSC_VER >= 1800\n");
+ printf("/**\tDK3 version of HAVE_WCSTOIMAX.\n*/\n");
+ printf("#define DK3_HAVE_WCSTOIMAX 1\n");
+ printf("#else\n");
+ printf("/**\tDK3 version of HAVE_WCSTOIMAX.\n*/\n");
+ printf("#define DK3_HAVE_WCSTOIMAX 0\n");
+ printf("#endif\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSTOL\n");
+ printf("#if _MSC_VER >= 1700\n");
+ printf("/**\tDK3 version of HAVE_WCSTOL.\n*/\n");
+ printf("#define DK3_HAVE_WCSTOL 1\n");
+ printf("#else\n");
+ printf("/**\tDK3 version of HAVE_WCSTOL.\n*/\n");
+ printf("#define DK3_HAVE_WCSTOL 0\n");
+ printf("#endif\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSTOLL\n");
+ printf("#if _MSC_VER >= 1700\n");
+ printf("/**\tDK3 version of HAVE_WCSTOLL.\n*/\n");
+ printf("#define DK3_HAVE_WCSTOLL 1\n");
+ printf("#else\n");
+ printf("/**\tDK3 version of HAVE_WCSTOLL.\n*/\n");
+ printf("#define DK3_HAVE_WCSTOLL 0\n");
+ printf("#endif\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSTOUL\n");
+ printf("#if _MSC_VER >= 1700\n");
+ printf("/**\tDK3 version of HAVE_WCSTOUL.\n*/\n");
+ printf("#define DK3_HAVE_WCSTOUL 1\n");
+ printf("#else\n");
+ printf("/**\tDK3 version of HAVE_WCSTOUL.\n*/\n");
+ printf("#define DK3_HAVE_WCSTOUL 0\n");
+ printf("#endif\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSTOULL\n");
+ printf("#if _MSC_VER >= 1700\n");
+ printf("/**\tDK3 version of HAVE_WCSTOULL.\n*/\n");
+ printf("#define DK3_HAVE_WCSTOULL 1\n");
+ printf("#else\n");
+ printf("/**\tDK3 version of HAVE_WCSTOULL.\n*/\n");
+ printf("#define DK3_HAVE_WCSTOULL 0\n");
+ printf("#endif\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSTOUMAX\n");
+ printf("#if _MSC_VER >= 1800\n");
+ printf("/**\tDK3 version of HAVE_WCSTOUMAX.\n*/\n");
+ printf("#define DK3_HAVE_WCSTOUMAX 1\n");
+ printf("#else\n");
+ printf("/**\tDK3 version of HAVE_WCSTOUMAX.\n*/\n");
+ printf("#define DK3_HAVE_WCSTOUMAX 0\n");
+ printf("#endif\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WINBASE_H\n");
+ printf("/**\tDK3 version of HAVE_WINBASE_H.\n*/\n");
+ printf("#define DK3_HAVE_WINBASE_H 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WINCON_H\n");
+ printf("/**\tDK3 version of HAVE_WINCON_H.\n*/\n");
+ printf("#define DK3_HAVE_WINCON_H 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WINDOWS_H\n");
+ printf("/**\tDK3 version of HAVE_WINDOWS_H.\n*/\n");
+ printf("#define DK3_HAVE_WINDOWS_H 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WINREG_H\n");
+ printf("/**\tDK3 version of HAVE_WINREG_H.\n*/\n");
+ printf("#define DK3_HAVE_WINREG_H 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WINSOCK2_H\n");
+ printf("/**\tDK3 version of HAVE_WINSOCK2_H.\n*/\n");
+ printf("#define DK3_HAVE_WINSOCK2_H 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WRITE\n");
+ printf("/**\tDK3 version of HAVE_WRITE.\n*/\n");
+ printf("#define DK3_HAVE_WRITE 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WS2TCPIP_H\n");
+ printf("/**\tDK3 version of HAVE_WS2TCPIP_H.\n*/\n");
+ printf("#define DK3_HAVE_WS2TCPIP_H 1\n");
+ printf("#endif\n");
+/* WARNING: HAVE_ZLIB_H not defined for Windows! */
+ printf("\n#ifndef DK3_HAVE__CLEARFP\n");
+ printf("#if _MSC_VER >= 1700\n");
+ printf("/**\tDK3 version of HAVE__CLEARFP.\n*/\n");
+ printf("#define DK3_HAVE__CLEARFP 1\n");
+ printf("#else\n");
+ printf("/**\tDK3 version of HAVE__CLEARFP.\n*/\n");
+ printf("#define DK3_HAVE__CLEARFP 0\n");
+ printf("#endif\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__FCLOSE\n");
+ printf("/**\tDK3 version of HAVE__FCLOSE.\n*/\n");
+ printf("#define DK3_HAVE__FCLOSE 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__FEOF\n");
+ printf("/**\tDK3 version of HAVE__FEOF.\n*/\n");
+ printf("#define DK3_HAVE__FEOF 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__FERROR\n");
+ printf("/**\tDK3 version of HAVE__FERROR.\n*/\n");
+ printf("#define DK3_HAVE__FERROR 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__FFLUSH\n");
+ printf("/**\tDK3 version of HAVE__FFLUSH.\n*/\n");
+ printf("#define DK3_HAVE__FFLUSH 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__FOPEN\n");
+ printf("/**\tDK3 version of HAVE__FOPEN.\n*/\n");
+ printf("#define DK3_HAVE__FOPEN 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__FREAD\n");
+ printf("/**\tDK3 version of HAVE__FREAD.\n*/\n");
+ printf("#define DK3_HAVE__FREAD 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__FWRITE\n");
+ printf("/**\tDK3 version of HAVE__FWRITE.\n*/\n");
+ printf("#define DK3_HAVE__FWRITE 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__GETCWD\n");
+ printf("/**\tDK3 version of HAVE__GETCWD.\n*/\n");
+ printf("#define DK3_HAVE__GETCWD 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__GETENV_S\n");
+ printf("#if _MSC_VER >= 1700\n");
+ printf("/**\tDK3 version of HAVE__GETENV_S.\n*/\n");
+ printf("#define DK3_HAVE__GETENV_S 1\n");
+ printf("#else\n");
+ printf("/**\tDK3 version of HAVE__GETENV_S.\n*/\n");
+ printf("#define DK3_HAVE__GETENV_S 0\n");
+ printf("#endif\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__GETPID\n");
+ printf("/**\tDK3 version of HAVE__GETPID.\n*/\n");
+ printf("#define DK3_HAVE__GETPID 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__LSTAT\n");
+ printf("/**\tDK3 version of HAVE__LSTAT.\n*/\n");
+ printf("#define DK3_HAVE__LSTAT 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__LSTAT32\n");
+ printf("/**\tDK3 version of HAVE__LSTAT32.\n*/\n");
+ printf("#define DK3_HAVE__LSTAT32 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__LSTAT64\n");
+ printf("/**\tDK3 version of HAVE__LSTAT64.\n*/\n");
+ printf("#define DK3_HAVE__LSTAT64 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__MKDIR\n");
+ printf("/**\tDK3 version of HAVE__MKDIR.\n*/\n");
+ printf("#define DK3_HAVE__MKDIR 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__POPEN\n");
+ printf("/**\tDK3 version of HAVE__POPEN.\n*/\n");
+ printf("#define DK3_HAVE__POPEN 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__READ\n");
+ printf("/**\tDK3 version of HAVE__READ.\n*/\n");
+ printf("#define DK3_HAVE__READ 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__RMDIR\n");
+ printf("/**\tDK3 version of HAVE__RMDIR.\n*/\n");
+ printf("#define DK3_HAVE__RMDIR 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__SNPRINTF\n");
+ printf("/**\tDK3 version of HAVE__SNPRINTF.\n*/\n");
+ printf("#define DK3_HAVE__SNPRINTF 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__SNPRINTF_S\n");
+ printf("#if _MSC_VER >= 1\n");
+ printf("/**\tDK3 version of HAVE__SNPRINTF_S.\n*/\n");
+ printf("#define DK3_HAVE__SNPRINTF_S 1\n");
+ printf("#else\n");
+ printf("/**\tDK3 version of HAVE__SNPRINTF_S.\n*/\n");
+ printf("#define DK3_HAVE__SNPRINTF_S 0\n");
+ printf("#endif\n");
+ printf("#endif\n");
+/* WARNING: HAVE__SNWPRINTF not defined for Windows! */
+/* WARNING: HAVE__SNWPRINTF_S not defined for Windows! */
+ printf("\n#ifndef DK3_HAVE__STAT\n");
+ printf("/**\tDK3 version of HAVE__STAT.\n*/\n");
+ printf("#define DK3_HAVE__STAT 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__STAT32\n");
+ printf("/**\tDK3 version of HAVE__STAT32.\n*/\n");
+ printf("#define DK3_HAVE__STAT32 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__STAT64\n");
+ printf("/**\tDK3 version of HAVE__STAT64.\n*/\n");
+ printf("#define DK3_HAVE__STAT64 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__STRDUP\n");
+ printf("/**\tDK3 version of HAVE__STRDUP.\n*/\n");
+ printf("#define DK3_HAVE__STRDUP 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__STRICMP\n");
+ printf("/**\tDK3 version of HAVE__STRICMP.\n*/\n");
+ printf("#define DK3_HAVE__STRICMP 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__UNLINK\n");
+ printf("/**\tDK3 version of HAVE__UNLINK.\n*/\n");
+ printf("#define DK3_HAVE__UNLINK 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__WCSCAT\n");
+ printf("/**\tDK3 version of HAVE__WCSCAT.\n*/\n");
+ printf("#define DK3_HAVE__WCSCAT 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__WCSCHR\n");
+ printf("/**\tDK3 version of HAVE__WCSCHR.\n*/\n");
+ printf("#define DK3_HAVE__WCSCHR 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__WCSCMP\n");
+ printf("/**\tDK3 version of HAVE__WCSCMP.\n*/\n");
+ printf("#define DK3_HAVE__WCSCMP 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__WCSCPY\n");
+ printf("/**\tDK3 version of HAVE__WCSCPY.\n*/\n");
+ printf("#define DK3_HAVE__WCSCPY 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__WCSDUP\n");
+ printf("/**\tDK3 version of HAVE__WCSDUP.\n*/\n");
+ printf("#define DK3_HAVE__WCSDUP 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__WCSICMP\n");
+ printf("/**\tDK3 version of HAVE__WCSICMP.\n*/\n");
+ printf("#define DK3_HAVE__WCSICMP 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__WCSLEN\n");
+ printf("/**\tDK3 version of HAVE__WCSLEN.\n*/\n");
+ printf("#define DK3_HAVE__WCSLEN 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__WCSNCMP\n");
+ printf("/**\tDK3 version of HAVE__WCSNCMP.\n*/\n");
+ printf("#define DK3_HAVE__WCSNCMP 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__WCSNCPY\n");
+ printf("/**\tDK3 version of HAVE__WCSNCPY.\n*/\n");
+ printf("#define DK3_HAVE__WCSNCPY 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__WCSRCHR\n");
+ printf("/**\tDK3 version of HAVE__WCSRCHR.\n*/\n");
+ printf("#define DK3_HAVE__WCSRCHR 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__WFOPEN_S\n");
+ printf("#if _MSC_VER >= 1700\n");
+ printf("/**\tDK3 version of HAVE__WFOPEN_S.\n*/\n");
+ printf("#define DK3_HAVE__WFOPEN_S 1\n");
+ printf("#else\n");
+ printf("/**\tDK3 version of HAVE__WFOPEN_S.\n*/\n");
+ printf("#define DK3_HAVE__WFOPEN_S 0\n");
+ printf("#endif\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__WGETENV\n");
+ printf("/**\tDK3 version of HAVE__WGETENV.\n*/\n");
+ printf("#define DK3_HAVE__WGETENV 1\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__WRITE\n");
+ printf("/**\tDK3 version of HAVE__WRITE.\n*/\n");
+ printf("#define DK3_HAVE__WRITE 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_TIME_WITH_SYS_TIME\n");
+ printf("/**\tDK3 version of TIME_WITH_SYS_TIME.\n*/\n");
+ printf("#define DK3_TIME_WITH_SYS_TIME 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_SIZEOF_DOUBLE\n");
+ printf("/**\tDK3 version of SIZEOF_DOUBLE.\n*/\n");
+ printf("#define DK3_SIZEOF_DOUBLE 8\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_SIZEOF_INT\n");
+ printf("/**\tDK3 version of SIZEOF_INT.\n*/\n");
+ printf("#define DK3_SIZEOF_INT 4\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_SIZEOF_INTMAX_T\n");
+ printf("#if _MSC_VER >= 1700\n");
+ printf("/**\tDK3 version of SIZEOF_INTMAX_T.\n*/\n");
+ printf("#define DK3_SIZEOF_INTMAX_T 8\n");
+ printf("#else\n");
+ printf("/**\tDK3 version of SIZEOF_INTMAX_T.\n*/\n");
+ printf("#define DK3_SIZEOF_INTMAX_T 0\n");
+ printf("#endif\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_SIZEOF_LONG\n");
+ printf("/**\tDK3 version of SIZEOF_LONG.\n*/\n");
+ printf("#define DK3_SIZEOF_LONG 4\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_SIZEOF_LONG_DOUBLE\n");
+ printf("/**\tDK3 version of SIZEOF_LONG_DOUBLE.\n*/\n");
+ printf("#define DK3_SIZEOF_LONG_DOUBLE 8\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_SIZEOF_LONG_LONG\n");
+ printf("/**\tDK3 version of SIZEOF_LONG_LONG.\n*/\n");
+ printf("#define DK3_SIZEOF_LONG_LONG 8\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_SIZEOF_SHORT\n");
+ printf("/**\tDK3 version of SIZEOF_SHORT.\n*/\n");
+ printf("#define DK3_SIZEOF_SHORT 2\n");
+ printf("#endif\n");
+ printf("\n#if defined(WIN64) || defined(_WIN64)\n");
+ printf("#ifndef DK3_SIZEOF_SIZE_T\n");
+ printf("/**\tDK3 version of SIZEOF_SIZE_T.\n*/\n");
+ printf("#define DK3_SIZEOF_SIZE_T 8\n");
+ printf("#endif\n");
+ printf("#else\n");
+ printf("#ifndef DK3_SIZEOF_SIZE_T\n");
+ printf("/**\tDK3 version of SIZEOF_SIZE_T.\n*/\n");
+ printf("#define DK3_SIZEOF_SIZE_T 4\n");
+ printf("#endif\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_SIZEOF_WCHAR_T\n");
+ printf("/**\tDK3 version of SIZEOF_WCHAR_T.\n*/\n");
+ printf("#define DK3_SIZEOF_WCHAR_T 2\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_RFC_2279\n");
+ printf("/**\tDK3 version of HAVE_RFC_2279.\n*/\n");
+ printf("#define DK3_HAVE_RFC_2279 0\n");
+ printf("#endif\n");
+ printf("\n#ifndef DK3_WORDS_BIGENDIAN\n");
+ printf("/**\tDK3 version of WORDS_BIGENDIAN.\n*/\n");
+ printf("#define DK3_WORDS_BIGENDIAN 0\n");
+ printf("#endif\n");
+ printf("\n#else\n/* if DK3_ON_WINDOWS */\n\n");
+ printf("\n#ifndef DK3_HAVE_ACOSH\n");
+ printf("/**\tDK3 version of HAVE_ACOSH.\n*/\n");
+#if HAVE_ACOSH
+ printf("#define DK3_HAVE_ACOSH 1\n");
+#else
+ printf("#define DK3_HAVE_ACOSH 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ACOSHL\n");
+ printf("/**\tDK3 version of HAVE_ACOSHL.\n*/\n");
+#if HAVE_ACOSHL
+ printf("#define DK3_HAVE_ACOSHL 1\n");
+#else
+ printf("#define DK3_HAVE_ACOSHL 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ACOSL\n");
+ printf("/**\tDK3 version of HAVE_ACOSL.\n*/\n");
+#if HAVE_ACOSL
+ printf("#define DK3_HAVE_ACOSL 1\n");
+#else
+ printf("#define DK3_HAVE_ACOSL 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ALLOC_H\n");
+ printf("/**\tDK3 version of HAVE_ALLOC_H.\n*/\n");
+#if HAVE_ALLOC_H
+ printf("#define DK3_HAVE_ALLOC_H 1\n");
+#else
+ printf("#define DK3_HAVE_ALLOC_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ARPA_INET_H\n");
+ printf("/**\tDK3 version of HAVE_ARPA_INET_H.\n*/\n");
+#if HAVE_ARPA_INET_H
+ printf("#define DK3_HAVE_ARPA_INET_H 1\n");
+#else
+ printf("#define DK3_HAVE_ARPA_INET_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ASINH\n");
+ printf("/**\tDK3 version of HAVE_ASINH.\n*/\n");
+#if HAVE_ASINH
+ printf("#define DK3_HAVE_ASINH 1\n");
+#else
+ printf("#define DK3_HAVE_ASINH 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ASINHL\n");
+ printf("/**\tDK3 version of HAVE_ASINHL.\n*/\n");
+#if HAVE_ASINHL
+ printf("#define DK3_HAVE_ASINHL 1\n");
+#else
+ printf("#define DK3_HAVE_ASINHL 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ASINL\n");
+ printf("/**\tDK3 version of HAVE_ASINL.\n*/\n");
+#if HAVE_ASINL
+ printf("#define DK3_HAVE_ASINL 1\n");
+#else
+ printf("#define DK3_HAVE_ASINL 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ATAN2\n");
+ printf("/**\tDK3 version of HAVE_ATAN2.\n*/\n");
+#if HAVE_ATAN2
+ printf("#define DK3_HAVE_ATAN2 1\n");
+#else
+ printf("#define DK3_HAVE_ATAN2 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ATAN2L\n");
+ printf("/**\tDK3 version of HAVE_ATAN2L.\n*/\n");
+#if HAVE_ATAN2L
+ printf("#define DK3_HAVE_ATAN2L 1\n");
+#else
+ printf("#define DK3_HAVE_ATAN2L 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ATANH\n");
+ printf("/**\tDK3 version of HAVE_ATANH.\n*/\n");
+#if HAVE_ATANH
+ printf("#define DK3_HAVE_ATANH 1\n");
+#else
+ printf("#define DK3_HAVE_ATANH 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ATANHL\n");
+ printf("/**\tDK3 version of HAVE_ATANHL.\n*/\n");
+#if HAVE_ATANHL
+ printf("#define DK3_HAVE_ATANHL 1\n");
+#else
+ printf("#define DK3_HAVE_ATANHL 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ATANL\n");
+ printf("/**\tDK3 version of HAVE_ATANL.\n*/\n");
+#if HAVE_ATANL
+ printf("#define DK3_HAVE_ATANL 1\n");
+#else
+ printf("#define DK3_HAVE_ATANL 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_BACKSLASH\n");
+ printf("/**\tDK3 version of HAVE_BACKSLASH.\n*/\n");
+#if HAVE_BACKSLASH
+ printf("#define DK3_HAVE_BACKSLASH 1\n");
+#else
+ printf("#define DK3_HAVE_BACKSLASH 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_BCMP\n");
+ printf("/**\tDK3 version of HAVE_BCMP.\n*/\n");
+#if HAVE_BCMP
+ printf("#define DK3_HAVE_BCMP 1\n");
+#else
+ printf("#define DK3_HAVE_BCMP 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_BCOPY\n");
+ printf("/**\tDK3 version of HAVE_BCOPY.\n*/\n");
+#if HAVE_BCOPY
+ printf("#define DK3_HAVE_BCOPY 1\n");
+#else
+ printf("#define DK3_HAVE_BCOPY 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_BZERO\n");
+ printf("/**\tDK3 version of HAVE_BZERO.\n*/\n");
+#if HAVE_BZERO
+ printf("#define DK3_HAVE_BZERO 1\n");
+#else
+ printf("#define DK3_HAVE_BZERO 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_BZLIB_H\n");
+ printf("/**\tDK3 version of HAVE_BZLIB_H.\n*/\n");
+#if HAVE_BZLIB_H
+ printf("#define DK3_HAVE_BZLIB_H 1\n");
+#else
+ printf("#define DK3_HAVE_BZLIB_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_CEIL\n");
+ printf("/**\tDK3 version of HAVE_CEIL.\n*/\n");
+#if HAVE_CEIL
+ printf("#define DK3_HAVE_CEIL 1\n");
+#else
+ printf("#define DK3_HAVE_CEIL 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_CEILL\n");
+ printf("/**\tDK3 version of HAVE_CEILL.\n*/\n");
+#if HAVE_CEILL
+ printf("#define DK3_HAVE_CEILL 1\n");
+#else
+ printf("#define DK3_HAVE_CEILL 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_CHDIR\n");
+ printf("/**\tDK3 version of HAVE_CHDIR.\n*/\n");
+#if HAVE_CHDIR
+ printf("#define DK3_HAVE_CHDIR 1\n");
+#else
+ printf("#define DK3_HAVE_CHDIR 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_CHMOD\n");
+ printf("/**\tDK3 version of HAVE_CHMOD.\n*/\n");
+#if HAVE_CHMOD
+ printf("#define DK3_HAVE_CHMOD 1\n");
+#else
+ printf("#define DK3_HAVE_CHMOD 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_CHOWN\n");
+ printf("/**\tDK3 version of HAVE_CHOWN.\n*/\n");
+#if HAVE_CHOWN
+ printf("#define DK3_HAVE_CHOWN 1\n");
+#else
+ printf("#define DK3_HAVE_CHOWN 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_CLOSEDIR\n");
+ printf("/**\tDK3 version of HAVE_CLOSEDIR.\n*/\n");
+#if HAVE_CLOSEDIR
+ printf("#define DK3_HAVE_CLOSEDIR 1\n");
+#else
+ printf("#define DK3_HAVE_CLOSEDIR 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_CONIO_H\n");
+ printf("/**\tDK3 version of HAVE_CONIO_H.\n*/\n");
+#if HAVE_CONIO_H
+ printf("#define DK3_HAVE_CONIO_H 1\n");
+#else
+ printf("#define DK3_HAVE_CONIO_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_CONST\n");
+ printf("/**\tDK3 version of HAVE_CONST.\n*/\n");
+#if HAVE_CONST
+ printf("#define DK3_HAVE_CONST 1\n");
+#else
+ printf("#define DK3_HAVE_CONST 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_COSHL\n");
+ printf("/**\tDK3 version of HAVE_COSHL.\n*/\n");
+#if HAVE_COSHL
+ printf("#define DK3_HAVE_COSHL 1\n");
+#else
+ printf("#define DK3_HAVE_COSHL 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_COSL\n");
+ printf("/**\tDK3 version of HAVE_COSL.\n*/\n");
+#if HAVE_COSL
+ printf("#define DK3_HAVE_COSL 1\n");
+#else
+ printf("#define DK3_HAVE_COSL 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_CTYPE_H\n");
+ printf("/**\tDK3 version of HAVE_CTYPE_H.\n*/\n");
+#if HAVE_CTYPE_H
+ printf("#define DK3_HAVE_CTYPE_H 1\n");
+#else
+ printf("#define DK3_HAVE_CTYPE_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_DB_CURSOR_C_GET\n");
+ printf("/**\tDK3 version of HAVE_DB_CURSOR_C_GET.\n*/\n");
+#if HAVE_DB_CURSOR_C_GET
+ printf("#define DK3_HAVE_DB_CURSOR_C_GET 1\n");
+#else
+ printf("#define DK3_HAVE_DB_CURSOR_C_GET 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_DB_H\n");
+ printf("/**\tDK3 version of HAVE_DB_H.\n*/\n");
+#if HAVE_DB_H
+ printf("#define DK3_HAVE_DB_H 1\n");
+#else
+ printf("#define DK3_HAVE_DB_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_DEV_RANDOM\n");
+ printf("/**\tDK3 version of HAVE_DEV_RANDOM.\n*/\n");
+#if HAVE_DEV_RANDOM
+ printf("#define DK3_HAVE_DEV_RANDOM 1\n");
+#else
+ printf("#define DK3_HAVE_DEV_RANDOM 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_DEV_URANDOM\n");
+ printf("/**\tDK3 version of HAVE_DEV_URANDOM.\n*/\n");
+#if HAVE_DEV_URANDOM
+ printf("#define DK3_HAVE_DEV_URANDOM 1\n");
+#else
+ printf("#define DK3_HAVE_DEV_URANDOM 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_DIRECT_H\n");
+ printf("/**\tDK3 version of HAVE_DIRECT_H.\n*/\n");
+#if HAVE_DIRECT_H
+ printf("#define DK3_HAVE_DIRECT_H 1\n");
+#else
+ printf("#define DK3_HAVE_DIRECT_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_DIRENT_H\n");
+ printf("/**\tDK3 version of HAVE_DIRENT_H.\n*/\n");
+#if HAVE_DIRENT_H
+ printf("#define DK3_HAVE_DIRENT_H 1\n");
+#else
+ printf("#define DK3_HAVE_DIRENT_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_DIR_H\n");
+ printf("/**\tDK3 version of HAVE_DIR_H.\n*/\n");
+#if HAVE_DIR_H
+ printf("#define DK3_HAVE_DIR_H 1\n");
+#else
+ printf("#define DK3_HAVE_DIR_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_DOS_H\n");
+ printf("/**\tDK3 version of HAVE_DOS_H.\n*/\n");
+#if HAVE_DOS_H
+ printf("#define DK3_HAVE_DOS_H 1\n");
+#else
+ printf("#define DK3_HAVE_DOS_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ENDGRENT\n");
+ printf("/**\tDK3 version of HAVE_ENDGRENT.\n*/\n");
+#if HAVE_ENDGRENT
+ printf("#define DK3_HAVE_ENDGRENT 1\n");
+#else
+ printf("#define DK3_HAVE_ENDGRENT 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ENDPWENT\n");
+ printf("/**\tDK3 version of HAVE_ENDPWENT.\n*/\n");
+#if HAVE_ENDPWENT
+ printf("#define DK3_HAVE_ENDPWENT 1\n");
+#else
+ printf("#define DK3_HAVE_ENDPWENT 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ERRNO_H\n");
+ printf("/**\tDK3 version of HAVE_ERRNO_H.\n*/\n");
+#if HAVE_ERRNO_H
+ printf("#define DK3_HAVE_ERRNO_H 1\n");
+#else
+ printf("#define DK3_HAVE_ERRNO_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ERR_H\n");
+ printf("/**\tDK3 version of HAVE_ERR_H.\n*/\n");
+#if HAVE_ERR_H
+ printf("#define DK3_HAVE_ERR_H 1\n");
+#else
+ printf("#define DK3_HAVE_ERR_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_EXPL\n");
+ printf("/**\tDK3 version of HAVE_EXPL.\n*/\n");
+#if HAVE_EXPL
+ printf("#define DK3_HAVE_EXPL 1\n");
+#else
+ printf("#define DK3_HAVE_EXPL 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FABS\n");
+ printf("/**\tDK3 version of HAVE_FABS.\n*/\n");
+#if HAVE_FABS
+ printf("#define DK3_HAVE_FABS 1\n");
+#else
+ printf("#define DK3_HAVE_FABS 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FABSL\n");
+ printf("/**\tDK3 version of HAVE_FABSL.\n*/\n");
+#if HAVE_FABSL
+ printf("#define DK3_HAVE_FABSL 1\n");
+#else
+ printf("#define DK3_HAVE_FABSL 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FCLOSE\n");
+ printf("/**\tDK3 version of HAVE_FCLOSE.\n*/\n");
+#if HAVE_FCLOSE
+ printf("#define DK3_HAVE_FCLOSE 1\n");
+#else
+ printf("#define DK3_HAVE_FCLOSE 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FCNTL_H\n");
+ printf("/**\tDK3 version of HAVE_FCNTL_H.\n*/\n");
+#if HAVE_FCNTL_H
+ printf("#define DK3_HAVE_FCNTL_H 1\n");
+#else
+ printf("#define DK3_HAVE_FCNTL_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FENV_H\n");
+ printf("/**\tDK3 version of HAVE_FENV_H.\n*/\n");
+#if HAVE_FENV_H
+ printf("#define DK3_HAVE_FENV_H 1\n");
+#else
+ printf("#define DK3_HAVE_FENV_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FEOF\n");
+ printf("/**\tDK3 version of HAVE_FEOF.\n*/\n");
+#if HAVE_FEOF
+ printf("#define DK3_HAVE_FEOF 1\n");
+#else
+ printf("#define DK3_HAVE_FEOF 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FERROR\n");
+ printf("/**\tDK3 version of HAVE_FERROR.\n*/\n");
+#if HAVE_FERROR
+ printf("#define DK3_HAVE_FERROR 1\n");
+#else
+ printf("#define DK3_HAVE_FERROR 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FETESTEXCEPT\n");
+ printf("/**\tDK3 version of HAVE_FETESTEXCEPT.\n*/\n");
+#if HAVE_FETESTEXCEPT
+ printf("#define DK3_HAVE_FETESTEXCEPT 1\n");
+#else
+ printf("#define DK3_HAVE_FETESTEXCEPT 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FFLUSH\n");
+ printf("/**\tDK3 version of HAVE_FFLUSH.\n*/\n");
+#if HAVE_FFLUSH
+ printf("#define DK3_HAVE_FFLUSH 1\n");
+#else
+ printf("#define DK3_HAVE_FFLUSH 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FLOAT_H\n");
+ printf("/**\tDK3 version of HAVE_FLOAT_H.\n*/\n");
+#if HAVE_FLOAT_H
+ printf("#define DK3_HAVE_FLOAT_H 1\n");
+#else
+ printf("#define DK3_HAVE_FLOAT_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FLOOR\n");
+ printf("/**\tDK3 version of HAVE_FLOOR.\n*/\n");
+#if HAVE_FLOOR
+ printf("#define DK3_HAVE_FLOOR 1\n");
+#else
+ printf("#define DK3_HAVE_FLOOR 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FLOORL\n");
+ printf("/**\tDK3 version of HAVE_FLOORL.\n*/\n");
+#if HAVE_FLOORL
+ printf("#define DK3_HAVE_FLOORL 1\n");
+#else
+ printf("#define DK3_HAVE_FLOORL 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FNCASEINS\n");
+ printf("/**\tDK3 version of HAVE_FNCASEINS.\n*/\n");
+#if HAVE_FNCASEINS
+ printf("#define DK3_HAVE_FNCASEINS 1\n");
+#else
+ printf("#define DK3_HAVE_FNCASEINS 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FOPEN\n");
+ printf("/**\tDK3 version of HAVE_FOPEN.\n*/\n");
+#if HAVE_FOPEN
+ printf("#define DK3_HAVE_FOPEN 1\n");
+#else
+ printf("#define DK3_HAVE_FOPEN 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FOPEN64\n");
+ printf("/**\tDK3 version of HAVE_FOPEN64.\n*/\n");
+#if HAVE_FOPEN64
+ printf("#define DK3_HAVE_FOPEN64 1\n");
+#else
+ printf("#define DK3_HAVE_FOPEN64 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FOPEN_S\n");
+ printf("/**\tDK3 version of HAVE_FOPEN_S.\n*/\n");
+#if HAVE_FOPEN_S
+ printf("#define DK3_HAVE_FOPEN_S 1\n");
+#else
+ printf("#define DK3_HAVE_FOPEN_S 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FORK\n");
+ printf("/**\tDK3 version of HAVE_FORK.\n*/\n");
+#if HAVE_FORK
+ printf("#define DK3_HAVE_FORK 1\n");
+#else
+ printf("#define DK3_HAVE_FORK 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FPCLASSIFY\n");
+ printf("/**\tDK3 version of HAVE_FPCLASSIFY.\n*/\n");
+#if HAVE_FPCLASSIFY
+ printf("#define DK3_HAVE_FPCLASSIFY 1\n");
+#else
+ printf("#define DK3_HAVE_FPCLASSIFY 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FREAD\n");
+ printf("/**\tDK3 version of HAVE_FREAD.\n*/\n");
+#if HAVE_FREAD
+ printf("#define DK3_HAVE_FREAD 1\n");
+#else
+ printf("#define DK3_HAVE_FREAD 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FREE\n");
+ printf("/**\tDK3 version of HAVE_FREE.\n*/\n");
+#if HAVE_FREE
+ printf("#define DK3_HAVE_FREE 1\n");
+#else
+ printf("#define DK3_HAVE_FREE 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_FWRITE\n");
+ printf("/**\tDK3 version of HAVE_FWRITE.\n*/\n");
+#if HAVE_FWRITE
+ printf("#define DK3_HAVE_FWRITE 1\n");
+#else
+ printf("#define DK3_HAVE_FWRITE 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GDBM_H\n");
+ printf("/**\tDK3 version of HAVE_GDBM_H.\n*/\n");
+#if HAVE_GDBM_H
+ printf("#define DK3_HAVE_GDBM_H 1\n");
+#else
+ printf("#define DK3_HAVE_GDBM_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GETADDRINFO\n");
+ printf("/**\tDK3 version of HAVE_GETADDRINFO.\n*/\n");
+#if HAVE_GETADDRINFO
+ printf("#define DK3_HAVE_GETADDRINFO 1\n");
+#else
+ printf("#define DK3_HAVE_GETADDRINFO 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GETCWD\n");
+ printf("/**\tDK3 version of HAVE_GETCWD.\n*/\n");
+#if HAVE_GETCWD
+ printf("#define DK3_HAVE_GETCWD 1\n");
+#else
+ printf("#define DK3_HAVE_GETCWD 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GETENV\n");
+ printf("/**\tDK3 version of HAVE_GETENV.\n*/\n");
+#if HAVE_GETENV
+ printf("#define DK3_HAVE_GETENV 1\n");
+#else
+ printf("#define DK3_HAVE_GETENV 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GETEUID\n");
+ printf("/**\tDK3 version of HAVE_GETEUID.\n*/\n");
+#if HAVE_GETEUID
+ printf("#define DK3_HAVE_GETEUID 1\n");
+#else
+ printf("#define DK3_HAVE_GETEUID 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GETGRENT\n");
+ printf("/**\tDK3 version of HAVE_GETGRENT.\n*/\n");
+#if HAVE_GETGRENT
+ printf("#define DK3_HAVE_GETGRENT 1\n");
+#else
+ printf("#define DK3_HAVE_GETGRENT 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GETGRGID\n");
+ printf("/**\tDK3 version of HAVE_GETGRGID.\n*/\n");
+#if HAVE_GETGRGID
+ printf("#define DK3_HAVE_GETGRGID 1\n");
+#else
+ printf("#define DK3_HAVE_GETGRGID 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GETGRNAM\n");
+ printf("/**\tDK3 version of HAVE_GETGRNAM.\n*/\n");
+#if HAVE_GETGRNAM
+ printf("#define DK3_HAVE_GETGRNAM 1\n");
+#else
+ printf("#define DK3_HAVE_GETGRNAM 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GETHOSTBYNAME\n");
+ printf("/**\tDK3 version of HAVE_GETHOSTBYNAME.\n*/\n");
+#if HAVE_GETHOSTBYNAME
+ printf("#define DK3_HAVE_GETHOSTBYNAME 1\n");
+#else
+ printf("#define DK3_HAVE_GETHOSTBYNAME 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GETHOSTNAME\n");
+ printf("/**\tDK3 version of HAVE_GETHOSTNAME.\n*/\n");
+#if HAVE_GETHOSTNAME
+ printf("#define DK3_HAVE_GETHOSTNAME 1\n");
+#else
+ printf("#define DK3_HAVE_GETHOSTNAME 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GETPEERNAME\n");
+ printf("/**\tDK3 version of HAVE_GETPEERNAME.\n*/\n");
+#if HAVE_GETPEERNAME
+ printf("#define DK3_HAVE_GETPEERNAME 1\n");
+#else
+ printf("#define DK3_HAVE_GETPEERNAME 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GETPID\n");
+ printf("/**\tDK3 version of HAVE_GETPID.\n*/\n");
+#if HAVE_GETPID
+ printf("#define DK3_HAVE_GETPID 1\n");
+#else
+ printf("#define DK3_HAVE_GETPID 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GETPWENT\n");
+ printf("/**\tDK3 version of HAVE_GETPWENT.\n*/\n");
+#if HAVE_GETPWENT
+ printf("#define DK3_HAVE_GETPWENT 1\n");
+#else
+ printf("#define DK3_HAVE_GETPWENT 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GETPWNAM\n");
+ printf("/**\tDK3 version of HAVE_GETPWNAM.\n*/\n");
+#if HAVE_GETPWNAM
+ printf("#define DK3_HAVE_GETPWNAM 1\n");
+#else
+ printf("#define DK3_HAVE_GETPWNAM 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GETPWUID\n");
+ printf("/**\tDK3 version of HAVE_GETPWUID.\n*/\n");
+#if HAVE_GETPWUID
+ printf("#define DK3_HAVE_GETPWUID 1\n");
+#else
+ printf("#define DK3_HAVE_GETPWUID 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GETRLIMIT\n");
+ printf("/**\tDK3 version of HAVE_GETRLIMIT.\n*/\n");
+#if HAVE_GETRLIMIT
+ printf("#define DK3_HAVE_GETRLIMIT 1\n");
+#else
+ printf("#define DK3_HAVE_GETRLIMIT 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GETSOCKNAME\n");
+ printf("/**\tDK3 version of HAVE_GETSOCKNAME.\n*/\n");
+#if HAVE_GETSOCKNAME
+ printf("#define DK3_HAVE_GETSOCKNAME 1\n");
+#else
+ printf("#define DK3_HAVE_GETSOCKNAME 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GETUID\n");
+ printf("/**\tDK3 version of HAVE_GETUID.\n*/\n");
+#if HAVE_GETUID
+ printf("#define DK3_HAVE_GETUID 1\n");
+#else
+ printf("#define DK3_HAVE_GETUID 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_GRP_H\n");
+ printf("/**\tDK3 version of HAVE_GRP_H.\n*/\n");
+#if HAVE_GRP_H
+ printf("#define DK3_HAVE_GRP_H 1\n");
+#else
+ printf("#define DK3_HAVE_GRP_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_HTONL\n");
+ printf("/**\tDK3 version of HAVE_HTONL.\n*/\n");
+#if HAVE_HTONL
+ printf("#define DK3_HAVE_HTONL 1\n");
+#else
+ printf("#define DK3_HAVE_HTONL 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_IEEE_754_DOUBLE\n");
+ printf("/**\tDK3 version of HAVE_IEEE_754_DOUBLE.\n*/\n");
+#if HAVE_IEEE_754_DOUBLE
+ printf("#define DK3_HAVE_IEEE_754_DOUBLE 1\n");
+#else
+ printf("#define DK3_HAVE_IEEE_754_DOUBLE 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_IN6_ADDR\n");
+ printf("/**\tDK3 version of HAVE_IN6_ADDR.\n*/\n");
+#if HAVE_IN6_ADDR
+ printf("#define DK3_HAVE_IN6_ADDR 1\n");
+#else
+ printf("#define DK3_HAVE_IN6_ADDR 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_INET_ADDR\n");
+ printf("/**\tDK3 version of HAVE_INET_ADDR.\n*/\n");
+#if HAVE_INET_ADDR
+ printf("#define DK3_HAVE_INET_ADDR 1\n");
+#else
+ printf("#define DK3_HAVE_INET_ADDR 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_INET_ATON\n");
+ printf("/**\tDK3 version of HAVE_INET_ATON.\n*/\n");
+#if HAVE_INET_ATON
+ printf("#define DK3_HAVE_INET_ATON 1\n");
+#else
+ printf("#define DK3_HAVE_INET_ATON 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_INET_PTON\n");
+ printf("/**\tDK3 version of HAVE_INET_PTON.\n*/\n");
+#if HAVE_INET_PTON
+ printf("#define DK3_HAVE_INET_PTON 1\n");
+#else
+ printf("#define DK3_HAVE_INET_PTON 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_INITSTATE\n");
+ printf("/**\tDK3 version of HAVE_INITSTATE.\n*/\n");
+#if HAVE_INITSTATE
+ printf("#define DK3_HAVE_INITSTATE 1\n");
+#else
+ printf("#define DK3_HAVE_INITSTATE 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_INODES\n");
+ printf("/**\tDK3 version of HAVE_INODES.\n*/\n");
+#if HAVE_INODES
+ printf("#define DK3_HAVE_INODES 1\n");
+#else
+ printf("#define DK3_HAVE_INODES 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_INTMAX_T\n");
+ printf("/**\tDK3 version of HAVE_INTMAX_T.\n*/\n");
+#if HAVE_INTMAX_T
+ printf("#define DK3_HAVE_INTMAX_T 1\n");
+#else
+ printf("#define DK3_HAVE_INTMAX_T 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_INTTYPES_H\n");
+ printf("/**\tDK3 version of HAVE_INTTYPES_H.\n*/\n");
+#if HAVE_INTTYPES_H
+ printf("#define DK3_HAVE_INTTYPES_H 1\n");
+#else
+ printf("#define DK3_HAVE_INTTYPES_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_IN_ADDR\n");
+ printf("/**\tDK3 version of HAVE_IN_ADDR.\n*/\n");
+#if HAVE_IN_ADDR
+ printf("#define DK3_HAVE_IN_ADDR 1\n");
+#else
+ printf("#define DK3_HAVE_IN_ADDR 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_IO_H\n");
+ printf("/**\tDK3 version of HAVE_IO_H.\n*/\n");
+#if HAVE_IO_H
+ printf("#define DK3_HAVE_IO_H 1\n");
+#else
+ printf("#define DK3_HAVE_IO_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ISATTY\n");
+ printf("/**\tDK3 version of HAVE_ISATTY.\n*/\n");
+#if HAVE_ISATTY
+ printf("#define DK3_HAVE_ISATTY 1\n");
+#else
+ printf("#define DK3_HAVE_ISATTY 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ISFINITE\n");
+ printf("/**\tDK3 version of HAVE_ISFINITE.\n*/\n");
+#if HAVE_ISFINITE
+ printf("#define DK3_HAVE_ISFINITE 1\n");
+#else
+ printf("#define DK3_HAVE_ISFINITE 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ISNORMAL\n");
+ printf("/**\tDK3 version of HAVE_ISNORMAL.\n*/\n");
+#if HAVE_ISNORMAL
+ printf("#define DK3_HAVE_ISNORMAL 1\n");
+#else
+ printf("#define DK3_HAVE_ISNORMAL 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_JPEGLIB_H\n");
+ printf("/**\tDK3 version of HAVE_JPEGLIB_H.\n*/\n");
+#if HAVE_JPEGLIB_H
+ printf("#define DK3_HAVE_JPEGLIB_H 1\n");
+#else
+ printf("#define DK3_HAVE_JPEGLIB_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_LABS\n");
+ printf("/**\tDK3 version of HAVE_LABS.\n*/\n");
+#if HAVE_LABS
+ printf("#define DK3_HAVE_LABS 1\n");
+#else
+ printf("#define DK3_HAVE_LABS 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_LARGEFILE64_SOURCE\n");
+ printf("/**\tDK3 version of HAVE_LARGEFILE64_SOURCE.\n*/\n");
+#if HAVE_LARGEFILE64_SOURCE
+ printf("#define DK3_HAVE_LARGEFILE64_SOURCE 1\n");
+#else
+ printf("#define DK3_HAVE_LARGEFILE64_SOURCE 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_LIBNETSNMP\n");
+ printf("/**\tDK3 version of HAVE_LIBNETSNMP.\n*/\n");
+#if HAVE_LIBNETSNMP
+ printf("#define DK3_HAVE_LIBNETSNMP 1\n");
+#else
+ printf("#define DK3_HAVE_LIBNETSNMP 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_LIMITS_H\n");
+ printf("/**\tDK3 version of HAVE_LIMITS_H.\n*/\n");
+#if HAVE_LIMITS_H
+ printf("#define DK3_HAVE_LIMITS_H 1\n");
+#else
+ printf("#define DK3_HAVE_LIMITS_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_LOCALE_H\n");
+ printf("/**\tDK3 version of HAVE_LOCALE_H.\n*/\n");
+#if HAVE_LOCALE_H
+ printf("#define DK3_HAVE_LOCALE_H 1\n");
+#else
+ printf("#define DK3_HAVE_LOCALE_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_LOCALTIME\n");
+ printf("/**\tDK3 version of HAVE_LOCALTIME.\n*/\n");
+#if HAVE_LOCALTIME
+ printf("#define DK3_HAVE_LOCALTIME 1\n");
+#else
+ printf("#define DK3_HAVE_LOCALTIME 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_LOCALTIME\n");
+ printf("/**\tDK3 version of HAVE_LOCALTIME.\n*/\n");
+#if HAVE_LOCALTIME
+ printf("#define DK3_HAVE_LOCALTIME 1\n");
+#else
+ printf("#define DK3_HAVE_LOCALTIME 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_LOCALTIME_R\n");
+ printf("/**\tDK3 version of HAVE_LOCALTIME_R.\n*/\n");
+#if HAVE_LOCALTIME_R
+ printf("#define DK3_HAVE_LOCALTIME_R 1\n");
+#else
+ printf("#define DK3_HAVE_LOCALTIME_R 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_LOCALTIME_S\n");
+ printf("/**\tDK3 version of HAVE_LOCALTIME_S.\n*/\n");
+#if HAVE_LOCALTIME_S
+ printf("#define DK3_HAVE_LOCALTIME_S 1\n");
+#else
+ printf("#define DK3_HAVE_LOCALTIME_S 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_LOGL\n");
+ printf("/**\tDK3 version of HAVE_LOGL.\n*/\n");
+#if HAVE_LOGL
+ printf("#define DK3_HAVE_LOGL 1\n");
+#else
+ printf("#define DK3_HAVE_LOGL 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_LONG_DOUBLE\n");
+ printf("/**\tDK3 version of HAVE_LONG_DOUBLE.\n*/\n");
+#if HAVE_LONG_DOUBLE
+ printf("#define DK3_HAVE_LONG_DOUBLE 1\n");
+#else
+ printf("#define DK3_HAVE_LONG_DOUBLE 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_LONG_LONG\n");
+ printf("/**\tDK3 version of HAVE_LONG_LONG.\n*/\n");
+#if HAVE_LONG_LONG
+ printf("#define DK3_HAVE_LONG_LONG 1\n");
+#else
+ printf("#define DK3_HAVE_LONG_LONG 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_LPRNG_H\n");
+ printf("/**\tDK3 version of HAVE_LPRNG_H.\n*/\n");
+#if HAVE_LPRNG_H
+ printf("#define DK3_HAVE_LPRNG_H 1\n");
+#else
+ printf("#define DK3_HAVE_LPRNG_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_LRAND48\n");
+ printf("/**\tDK3 version of HAVE_LRAND48.\n*/\n");
+#if HAVE_LRAND48
+ printf("#define DK3_HAVE_LRAND48 1\n");
+#else
+ printf("#define DK3_HAVE_LRAND48 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_LSTAT\n");
+ printf("/**\tDK3 version of HAVE_LSTAT.\n*/\n");
+#if HAVE_LSTAT
+ printf("#define DK3_HAVE_LSTAT 1\n");
+#else
+ printf("#define DK3_HAVE_LSTAT 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_LSTAT32\n");
+ printf("/**\tDK3 version of HAVE_LSTAT32.\n*/\n");
+#if HAVE_LSTAT32
+ printf("#define DK3_HAVE_LSTAT32 1\n");
+#else
+ printf("#define DK3_HAVE_LSTAT32 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_LSTAT64\n");
+ printf("/**\tDK3 version of HAVE_LSTAT64.\n*/\n");
+#if HAVE_LSTAT64
+ printf("#define DK3_HAVE_LSTAT64 1\n");
+#else
+ printf("#define DK3_HAVE_LSTAT64 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_MALLOC\n");
+ printf("/**\tDK3 version of HAVE_MALLOC.\n*/\n");
+#if HAVE_MALLOC
+ printf("#define DK3_HAVE_MALLOC 1\n");
+#else
+ printf("#define DK3_HAVE_MALLOC 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_MALLOC_H\n");
+ printf("/**\tDK3 version of HAVE_MALLOC_H.\n*/\n");
+#if HAVE_MALLOC_H
+ printf("#define DK3_HAVE_MALLOC_H 1\n");
+#else
+ printf("#define DK3_HAVE_MALLOC_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_MATH_H\n");
+ printf("/**\tDK3 version of HAVE_MATH_H.\n*/\n");
+#if HAVE_MATH_H
+ printf("#define DK3_HAVE_MATH_H 1\n");
+#else
+ printf("#define DK3_HAVE_MATH_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_MEMCMP\n");
+ printf("/**\tDK3 version of HAVE_MEMCMP.\n*/\n");
+#if HAVE_MEMCMP
+ printf("#define DK3_HAVE_MEMCMP 1\n");
+#else
+ printf("#define DK3_HAVE_MEMCMP 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_MEMCPY\n");
+ printf("/**\tDK3 version of HAVE_MEMCPY.\n*/\n");
+#if HAVE_MEMCPY
+ printf("#define DK3_HAVE_MEMCPY 1\n");
+#else
+ printf("#define DK3_HAVE_MEMCPY 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_MEMSET\n");
+ printf("/**\tDK3 version of HAVE_MEMSET.\n*/\n");
+#if HAVE_MEMSET
+ printf("#define DK3_HAVE_MEMSET 1\n");
+#else
+ printf("#define DK3_HAVE_MEMSET 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_MKDIR\n");
+ printf("/**\tDK3 version of HAVE_MKDIR.\n*/\n");
+#if HAVE_MKDIR
+ printf("#define DK3_HAVE_MKDIR 1\n");
+#else
+ printf("#define DK3_HAVE_MKDIR 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_MKDIR2\n");
+ printf("/**\tDK3 version of HAVE_MKDIR2.\n*/\n");
+#if HAVE_MKDIR2
+ printf("#define DK3_HAVE_MKDIR2 1\n");
+#else
+ printf("#define DK3_HAVE_MKDIR2 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_MPCTL\n");
+ printf("/**\tDK3 version of HAVE_MPCTL.\n*/\n");
+#if HAVE_MPCTL
+ printf("#define DK3_HAVE_MPCTL 1\n");
+#else
+ printf("#define DK3_HAVE_MPCTL 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_MYSQL_LIBRARY_END\n");
+ printf("/**\tDK3 version of HAVE_MYSQL_LIBRARY_END.\n*/\n");
+#if HAVE_MYSQL_LIBRARY_END
+ printf("#define DK3_HAVE_MYSQL_LIBRARY_END 1\n");
+#else
+ printf("#define DK3_HAVE_MYSQL_LIBRARY_END 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_MYSQL_LIBRARY_INIT\n");
+ printf("/**\tDK3 version of HAVE_MYSQL_LIBRARY_INIT.\n*/\n");
+#if HAVE_MYSQL_LIBRARY_INIT
+ printf("#define DK3_HAVE_MYSQL_LIBRARY_INIT 1\n");
+#else
+ printf("#define DK3_HAVE_MYSQL_LIBRARY_INIT 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_MYSQL_MYSQL_H\n");
+ printf("/**\tDK3 version of HAVE_MYSQL_MYSQL_H.\n*/\n");
+#if HAVE_MYSQL_MYSQL_H
+ printf("#define DK3_HAVE_MYSQL_MYSQL_H 1\n");
+#else
+ printf("#define DK3_HAVE_MYSQL_MYSQL_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_MYSQL_H\n");
+ printf("/**\tDK3 version of HAVE_MYSQL_H.\n*/\n");
+#if HAVE_MYSQL_H
+ printf("#define DK3_HAVE_MYSQL_H 1\n");
+#else
+ printf("#define DK3_HAVE_MYSQL_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_MYSQL_SET_CHARACTER_SET\n");
+ printf("/**\tDK3 version of HAVE_MYSQL_SET_CHARACTER_SET.\n*/\n");
+#if HAVE_MYSQL_SET_CHARACTER_SET
+ printf("#define DK3_HAVE_MYSQL_SET_CHARACTER_SET 1\n");
+#else
+ printf("#define DK3_HAVE_MYSQL_SET_CHARACTER_SET 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_NDBM_H\n");
+ printf("/**\tDK3 version of HAVE_NDBM_H.\n*/\n");
+#if HAVE_NDBM_H
+ printf("#define DK3_HAVE_NDBM_H 1\n");
+#else
+ printf("#define DK3_HAVE_NDBM_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_NETDB_H\n");
+ printf("/**\tDK3 version of HAVE_NETDB_H.\n*/\n");
+#if HAVE_NETDB_H
+ printf("#define DK3_HAVE_NETDB_H 1\n");
+#else
+ printf("#define DK3_HAVE_NETDB_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_NETINET_IN_H\n");
+ printf("/**\tDK3 version of HAVE_NETINET_IN_H.\n*/\n");
+#if HAVE_NETINET_IN_H
+ printf("#define DK3_HAVE_NETINET_IN_H 1\n");
+#else
+ printf("#define DK3_HAVE_NETINET_IN_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_NETSNMP_ENABLE_FILELOG\n");
+ printf("/**\tDK3 version of HAVE_NETSNMP_ENABLE_FILELOG.\n*/\n");
+#if HAVE_NETSNMP_ENABLE_FILELOG
+ printf("#define DK3_HAVE_NETSNMP_ENABLE_FILELOG 1\n");
+#else
+ printf("#define DK3_HAVE_NETSNMP_ENABLE_FILELOG 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_NRAND48\n");
+ printf("/**\tDK3 version of HAVE_NRAND48.\n*/\n");
+#if HAVE_NRAND48
+ printf("#define DK3_HAVE_NRAND48 1\n");
+#else
+ printf("#define DK3_HAVE_NRAND48 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_OPENDIR\n");
+ printf("/**\tDK3 version of HAVE_OPENDIR.\n*/\n");
+#if HAVE_OPENDIR
+ printf("#define DK3_HAVE_OPENDIR 1\n");
+#else
+ printf("#define DK3_HAVE_OPENDIR 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_OPENSSL_MD5_H\n");
+ printf("/**\tDK3 version of HAVE_OPENSSL_MD5_H.\n*/\n");
+#if HAVE_OPENSSL_MD5_H
+ printf("#define DK3_HAVE_OPENSSL_MD5_H 1\n");
+#else
+ printf("#define DK3_HAVE_OPENSSL_MD5_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_OPENSSL_RAND_H\n");
+ printf("/**\tDK3 version of HAVE_OPENSSL_RAND_H.\n*/\n");
+#if HAVE_OPENSSL_RAND_H
+ printf("#define DK3_HAVE_OPENSSL_RAND_H 1\n");
+#else
+ printf("#define DK3_HAVE_OPENSSL_RAND_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_OPENSSL_RIPEMD_H\n");
+ printf("/**\tDK3 version of HAVE_OPENSSL_RIPEMD_H.\n*/\n");
+#if HAVE_OPENSSL_RIPEMD_H
+ printf("#define DK3_HAVE_OPENSSL_RIPEMD_H 1\n");
+#else
+ printf("#define DK3_HAVE_OPENSSL_RIPEMD_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_OPENSSL_SHA_H\n");
+ printf("/**\tDK3 version of HAVE_OPENSSL_SHA_H.\n*/\n");
+#if HAVE_OPENSSL_SHA_H
+ printf("#define DK3_HAVE_OPENSSL_SHA_H 1\n");
+#else
+ printf("#define DK3_HAVE_OPENSSL_SHA_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_PNG_GET_PIXELS_PER_INCH\n");
+ printf("/**\tDK3 version of HAVE_PNG_GET_PIXELS_PER_INCH.\n*/\n");
+#if HAVE_PNG_GET_PIXELS_PER_INCH
+ printf("#define DK3_HAVE_PNG_GET_PIXELS_PER_INCH 1\n");
+#else
+ printf("#define DK3_HAVE_PNG_GET_PIXELS_PER_INCH 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_PNG_H\n");
+ printf("/**\tDK3 version of HAVE_PNG_H.\n*/\n");
+#if HAVE_PNG_H
+ printf("#define DK3_HAVE_PNG_H 1\n");
+#else
+ printf("#define DK3_HAVE_PNG_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_POPEN\n");
+ printf("/**\tDK3 version of HAVE_POPEN.\n*/\n");
+#if HAVE_POPEN
+ printf("#define DK3_HAVE_POPEN 1\n");
+#else
+ printf("#define DK3_HAVE_POPEN 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_PROCESS_H\n");
+ printf("/**\tDK3 version of HAVE_PROCESS_H.\n*/\n");
+#if HAVE_PROCESS_H
+ printf("#define DK3_HAVE_PROCESS_H 1\n");
+#else
+ printf("#define DK3_HAVE_PROCESS_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_PTHREAD_H\n");
+ printf("/**\tDK3 version of HAVE_PTHREAD_H.\n*/\n");
+#if HAVE_PTHREAD_H
+ printf("#define DK3_HAVE_PTHREAD_H 1\n");
+#else
+ printf("#define DK3_HAVE_PTHREAD_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_PWD_H\n");
+ printf("/**\tDK3 version of HAVE_PWD_H.\n*/\n");
+#if HAVE_PWD_H
+ printf("#define DK3_HAVE_PWD_H 1\n");
+#else
+ printf("#define DK3_HAVE_PWD_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_RAND\n");
+ printf("/**\tDK3 version of HAVE_RAND.\n*/\n");
+#if HAVE_RAND
+ printf("#define DK3_HAVE_RAND 1\n");
+#else
+ printf("#define DK3_HAVE_RAND 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_RANDOM\n");
+ printf("/**\tDK3 version of HAVE_RANDOM.\n*/\n");
+#if HAVE_RANDOM
+ printf("#define DK3_HAVE_RANDOM 1\n");
+#else
+ printf("#define DK3_HAVE_RANDOM 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_READ\n");
+ printf("/**\tDK3 version of HAVE_READ.\n*/\n");
+#if HAVE_READ
+ printf("#define DK3_HAVE_READ 1\n");
+#else
+ printf("#define DK3_HAVE_READ 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_READDIR\n");
+ printf("/**\tDK3 version of HAVE_READDIR.\n*/\n");
+#if HAVE_READDIR
+ printf("#define DK3_HAVE_READDIR 1\n");
+#else
+ printf("#define DK3_HAVE_READDIR 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_RFC_2249\n");
+ printf("/**\tDK3 version of HAVE_RFC_2249.\n*/\n");
+#if HAVE_RFC_2249
+ printf("#define DK3_HAVE_RFC_2249 1\n");
+#else
+ printf("#define DK3_HAVE_RFC_2249 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_RINT\n");
+ printf("/**\tDK3 version of HAVE_RINT.\n*/\n");
+#if HAVE_RINT
+ printf("#define DK3_HAVE_RINT 1\n");
+#else
+ printf("#define DK3_HAVE_RINT 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_RINTL\n");
+ printf("/**\tDK3 version of HAVE_RINTL.\n*/\n");
+#if HAVE_RINTL
+ printf("#define DK3_HAVE_RINTL 1\n");
+#else
+ printf("#define DK3_HAVE_RINTL 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_RMDIR\n");
+ printf("/**\tDK3 version of HAVE_RMDIR.\n*/\n");
+#if HAVE_RMDIR
+ printf("#define DK3_HAVE_RMDIR 1\n");
+#else
+ printf("#define DK3_HAVE_RMDIR 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SEED48\n");
+ printf("/**\tDK3 version of HAVE_SEED48.\n*/\n");
+#if HAVE_SEED48
+ printf("#define DK3_HAVE_SEED48 1\n");
+#else
+ printf("#define DK3_HAVE_SEED48 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SELECT\n");
+ printf("/**\tDK3 version of HAVE_SELECT.\n*/\n");
+#if HAVE_SELECT
+ printf("#define DK3_HAVE_SELECT 1\n");
+#else
+ printf("#define DK3_HAVE_SELECT 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SETGID\n");
+ printf("/**\tDK3 version of HAVE_SETGID.\n*/\n");
+#if HAVE_SETGID
+ printf("#define DK3_HAVE_SETGID 1\n");
+#else
+ printf("#define DK3_HAVE_SETGID 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SETGRENT\n");
+ printf("/**\tDK3 version of HAVE_SETGRENT.\n*/\n");
+#if HAVE_SETGRENT
+ printf("#define DK3_HAVE_SETGRENT 1\n");
+#else
+ printf("#define DK3_HAVE_SETGRENT 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SETJMP_H\n");
+ printf("/**\tDK3 version of HAVE_SETJMP_H.\n*/\n");
+#if HAVE_SETJMP_H
+ printf("#define DK3_HAVE_SETJMP_H 1\n");
+#else
+ printf("#define DK3_HAVE_SETJMP_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SETLOCALE\n");
+ printf("/**\tDK3 version of HAVE_SETLOCALE.\n*/\n");
+#if HAVE_SETLOCALE
+ printf("#define DK3_HAVE_SETLOCALE 1\n");
+#else
+ printf("#define DK3_HAVE_SETLOCALE 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SETPGRP\n");
+ printf("/**\tDK3 version of HAVE_SETPGRP.\n*/\n");
+#if HAVE_SETPGRP
+ printf("#define DK3_HAVE_SETPGRP 1\n");
+#else
+ printf("#define DK3_HAVE_SETPGRP 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SETPWENT\n");
+ printf("/**\tDK3 version of HAVE_SETPWENT.\n*/\n");
+#if HAVE_SETPWENT
+ printf("#define DK3_HAVE_SETPWENT 1\n");
+#else
+ printf("#define DK3_HAVE_SETPWENT 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SETSID\n");
+ printf("/**\tDK3 version of HAVE_SETSID.\n*/\n");
+#if HAVE_SETSID
+ printf("#define DK3_HAVE_SETSID 1\n");
+#else
+ printf("#define DK3_HAVE_SETSID 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SETSOCKOPT\n");
+ printf("/**\tDK3 version of HAVE_SETSOCKOPT.\n*/\n");
+#if HAVE_SETSOCKOPT
+ printf("#define DK3_HAVE_SETSOCKOPT 1\n");
+#else
+ printf("#define DK3_HAVE_SETSOCKOPT 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SETSTATE\n");
+ printf("/**\tDK3 version of HAVE_SETSTATE.\n*/\n");
+#if HAVE_SETSTATE
+ printf("#define DK3_HAVE_SETSTATE 1\n");
+#else
+ printf("#define DK3_HAVE_SETSTATE 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SETUID\n");
+ printf("/**\tDK3 version of HAVE_SETUID.\n*/\n");
+#if HAVE_SETUID
+ printf("#define DK3_HAVE_SETUID 1\n");
+#else
+ printf("#define DK3_HAVE_SETUID 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SETVBUF\n");
+ printf("/**\tDK3 version of HAVE_SETVBUF.\n*/\n");
+#if HAVE_SETVBUF
+ printf("#define DK3_HAVE_SETVBUF 1\n");
+#else
+ printf("#define DK3_HAVE_SETVBUF 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SHA224\n");
+ printf("/**\tDK3 version of HAVE_SHA224.\n*/\n");
+#if HAVE_SHA224
+ printf("#define DK3_HAVE_SHA224 1\n");
+#else
+ printf("#define DK3_HAVE_SHA224 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SHA256\n");
+ printf("/**\tDK3 version of HAVE_SHA256.\n*/\n");
+#if HAVE_SHA256
+ printf("#define DK3_HAVE_SHA256 1\n");
+#else
+ printf("#define DK3_HAVE_SHA256 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SHA384\n");
+ printf("/**\tDK3 version of HAVE_SHA384.\n*/\n");
+#if HAVE_SHA384
+ printf("#define DK3_HAVE_SHA384 1\n");
+#else
+ printf("#define DK3_HAVE_SHA384 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SHA512\n");
+ printf("/**\tDK3 version of HAVE_SHA512.\n*/\n");
+#if HAVE_SHA512
+ printf("#define DK3_HAVE_SHA512 1\n");
+#else
+ printf("#define DK3_HAVE_SHA512 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SHADOW_H\n");
+ printf("/**\tDK3 version of HAVE_SHADOW_H.\n*/\n");
+#if HAVE_SHADOW_H
+ printf("#define DK3_HAVE_SHADOW_H 1\n");
+#else
+ printf("#define DK3_HAVE_SHADOW_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SIGACTION\n");
+ printf("/**\tDK3 version of HAVE_SIGACTION.\n*/\n");
+#if HAVE_SIGACTION
+ printf("#define DK3_HAVE_SIGACTION 1\n");
+#else
+ printf("#define DK3_HAVE_SIGACTION 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SIGNAL\n");
+ printf("/**\tDK3 version of HAVE_SIGNAL.\n*/\n");
+#if HAVE_SIGNAL
+ printf("#define DK3_HAVE_SIGNAL 1\n");
+#else
+ printf("#define DK3_HAVE_SIGNAL 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SIGNAL_H\n");
+ printf("/**\tDK3 version of HAVE_SIGNAL_H.\n*/\n");
+#if HAVE_SIGNAL_H
+ printf("#define DK3_HAVE_SIGNAL_H 1\n");
+#else
+ printf("#define DK3_HAVE_SIGNAL_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SIGSET\n");
+ printf("/**\tDK3 version of HAVE_SIGSET.\n*/\n");
+#if HAVE_SIGSET
+ printf("#define DK3_HAVE_SIGSET 1\n");
+#else
+ printf("#define DK3_HAVE_SIGSET 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SIG_ATOMIC_T\n");
+ printf("/**\tDK3 version of HAVE_SIG_ATOMIC_T.\n*/\n");
+#if HAVE_SIG_ATOMIC_T
+ printf("#define DK3_HAVE_SIG_ATOMIC_T 1\n");
+#else
+ printf("#define DK3_HAVE_SIG_ATOMIC_T 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SINHL\n");
+ printf("/**\tDK3 version of HAVE_SINHL.\n*/\n");
+#if HAVE_SINHL
+ printf("#define DK3_HAVE_SINHL 1\n");
+#else
+ printf("#define DK3_HAVE_SINHL 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SINL\n");
+ printf("/**\tDK3 version of HAVE_SINL.\n*/\n");
+#if HAVE_SINL
+ printf("#define DK3_HAVE_SINL 1\n");
+#else
+ printf("#define DK3_HAVE_SINL 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SNPRINTF\n");
+ printf("/**\tDK3 version of HAVE_SNPRINTF.\n*/\n");
+#if HAVE_SNPRINTF
+ printf("#define DK3_HAVE_SNPRINTF 1\n");
+#else
+ printf("#define DK3_HAVE_SNPRINTF 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SNWPRINTF\n");
+ printf("/**\tDK3 version of HAVE_SNWPRINTF.\n*/\n");
+#if HAVE_SNWPRINTF
+ printf("#define DK3_HAVE_SNWPRINTF 1\n");
+#else
+ printf("#define DK3_HAVE_SNWPRINTF 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SOCKET\n");
+ printf("/**\tDK3 version of HAVE_SOCKET.\n*/\n");
+#if HAVE_SOCKET
+ printf("#define DK3_HAVE_SOCKET 1\n");
+#else
+ printf("#define DK3_HAVE_SOCKET 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SOCKLEN_T\n");
+ printf("/**\tDK3 version of HAVE_SOCKLEN_T.\n*/\n");
+#if HAVE_SOCKLEN_T
+ printf("#define DK3_HAVE_SOCKLEN_T 1\n");
+#else
+ printf("#define DK3_HAVE_SOCKLEN_T 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SPRINTF_S\n");
+ printf("/**\tDK3 version of HAVE_SPRINTF_S.\n*/\n");
+#if HAVE_SPRINTF_S
+ printf("#define DK3_HAVE_SPRINTF_S 1\n");
+#else
+ printf("#define DK3_HAVE_SPRINTF_S 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SQRTL\n");
+ printf("/**\tDK3 version of HAVE_SQRTL.\n*/\n");
+#if HAVE_SQRTL
+ printf("#define DK3_HAVE_SQRTL 1\n");
+#else
+ printf("#define DK3_HAVE_SQRTL 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SRAND\n");
+ printf("/**\tDK3 version of HAVE_SRAND.\n*/\n");
+#if HAVE_SRAND
+ printf("#define DK3_HAVE_SRAND 1\n");
+#else
+ printf("#define DK3_HAVE_SRAND 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SSCANF_S\n");
+ printf("/**\tDK3 version of HAVE_SSCANF_S.\n*/\n");
+#if HAVE_SSCANF_S
+ printf("#define DK3_HAVE_SSCANF_S 1\n");
+#else
+ printf("#define DK3_HAVE_SSCANF_S 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SSIZE_T\n");
+ printf("/**\tDK3 version of HAVE_SSIZE_T.\n*/\n");
+#if HAVE_SSIZE_T
+ printf("#define DK3_HAVE_SSIZE_T 1\n");
+#else
+ printf("#define DK3_HAVE_SSIZE_T 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STAT\n");
+ printf("/**\tDK3 version of HAVE_STAT.\n*/\n");
+#if HAVE_STAT
+ printf("#define DK3_HAVE_STAT 1\n");
+#else
+ printf("#define DK3_HAVE_STAT 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STAT32\n");
+ printf("/**\tDK3 version of HAVE_STAT32.\n*/\n");
+#if HAVE_STAT32
+ printf("#define DK3_HAVE_STAT32 1\n");
+#else
+ printf("#define DK3_HAVE_STAT32 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STAT64\n");
+ printf("/**\tDK3 version of HAVE_STAT64.\n*/\n");
+#if HAVE_STAT64
+ printf("#define DK3_HAVE_STAT64 1\n");
+#else
+ printf("#define DK3_HAVE_STAT64 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STDARG_H\n");
+ printf("/**\tDK3 version of HAVE_STDARG_H.\n*/\n");
+#if HAVE_STDARG_H
+ printf("#define DK3_HAVE_STDARG_H 1\n");
+#else
+ printf("#define DK3_HAVE_STDARG_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STDDEF_H\n");
+ printf("/**\tDK3 version of HAVE_STDDEF_H.\n*/\n");
+#if HAVE_STDDEF_H
+ printf("#define DK3_HAVE_STDDEF_H 1\n");
+#else
+ printf("#define DK3_HAVE_STDDEF_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STDINT_H\n");
+ printf("/**\tDK3 version of HAVE_STDINT_H.\n*/\n");
+#if HAVE_STDINT_H
+ printf("#define DK3_HAVE_STDINT_H 1\n");
+#else
+ printf("#define DK3_HAVE_STDINT_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STDIO_H\n");
+ printf("/**\tDK3 version of HAVE_STDIO_H.\n*/\n");
+#if HAVE_STDIO_H
+ printf("#define DK3_HAVE_STDIO_H 1\n");
+#else
+ printf("#define DK3_HAVE_STDIO_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STDLIB_H\n");
+ printf("/**\tDK3 version of HAVE_STDLIB_H.\n*/\n");
+#if HAVE_STDLIB_H
+ printf("#define DK3_HAVE_STDLIB_H 1\n");
+#else
+ printf("#define DK3_HAVE_STDLIB_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRCASECMP\n");
+ printf("/**\tDK3 version of HAVE_STRCASECMP.\n*/\n");
+#if HAVE_STRCASECMP
+ printf("#define DK3_HAVE_STRCASECMP 1\n");
+#else
+ printf("#define DK3_HAVE_STRCASECMP 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRCAT\n");
+ printf("/**\tDK3 version of HAVE_STRCAT.\n*/\n");
+#if HAVE_STRCAT
+ printf("#define DK3_HAVE_STRCAT 1\n");
+#else
+ printf("#define DK3_HAVE_STRCAT 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRCAT_S\n");
+ printf("/**\tDK3 version of HAVE_STRCAT_S.\n*/\n");
+#if HAVE_STRCAT_S
+ printf("#define DK3_HAVE_STRCAT_S 1\n");
+#else
+ printf("#define DK3_HAVE_STRCAT_S 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRCHR\n");
+ printf("/**\tDK3 version of HAVE_STRCHR.\n*/\n");
+#if HAVE_STRCHR
+ printf("#define DK3_HAVE_STRCHR 1\n");
+#else
+ printf("#define DK3_HAVE_STRCHR 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRCMP\n");
+ printf("/**\tDK3 version of HAVE_STRCMP.\n*/\n");
+#if HAVE_STRCMP
+ printf("#define DK3_HAVE_STRCMP 1\n");
+#else
+ printf("#define DK3_HAVE_STRCMP 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRCPY\n");
+ printf("/**\tDK3 version of HAVE_STRCPY.\n*/\n");
+#if HAVE_STRCPY
+ printf("#define DK3_HAVE_STRCPY 1\n");
+#else
+ printf("#define DK3_HAVE_STRCPY 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRCPY_S\n");
+ printf("/**\tDK3 version of HAVE_STRCPY_S.\n*/\n");
+#if HAVE_STRCPY_S
+ printf("#define DK3_HAVE_STRCPY_S 1\n");
+#else
+ printf("#define DK3_HAVE_STRCPY_S 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRDUP\n");
+ printf("/**\tDK3 version of HAVE_STRDUP.\n*/\n");
+#if HAVE_STRDUP
+ printf("#define DK3_HAVE_STRDUP 1\n");
+#else
+ printf("#define DK3_HAVE_STRDUP 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRERROR\n");
+ printf("/**\tDK3 version of HAVE_STRERROR.\n*/\n");
+#if HAVE_STRERROR
+ printf("#define DK3_HAVE_STRERROR 1\n");
+#else
+ printf("#define DK3_HAVE_STRERROR 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRICMP\n");
+ printf("/**\tDK3 version of HAVE_STRICMP.\n*/\n");
+#if HAVE_STRICMP
+ printf("#define DK3_HAVE_STRICMP 1\n");
+#else
+ printf("#define DK3_HAVE_STRICMP 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRINGS_H\n");
+ printf("/**\tDK3 version of HAVE_STRINGS_H.\n*/\n");
+#if HAVE_STRINGS_H
+ printf("#define DK3_HAVE_STRINGS_H 1\n");
+#else
+ printf("#define DK3_HAVE_STRINGS_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRING_H\n");
+ printf("/**\tDK3 version of HAVE_STRING_H.\n*/\n");
+#if HAVE_STRING_H
+ printf("#define DK3_HAVE_STRING_H 1\n");
+#else
+ printf("#define DK3_HAVE_STRING_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRLEN\n");
+ printf("/**\tDK3 version of HAVE_STRLEN.\n*/\n");
+#if HAVE_STRLEN
+ printf("#define DK3_HAVE_STRLEN 1\n");
+#else
+ printf("#define DK3_HAVE_STRLEN 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRNCMP\n");
+ printf("/**\tDK3 version of HAVE_STRNCMP.\n*/\n");
+#if HAVE_STRNCMP
+ printf("#define DK3_HAVE_STRNCMP 1\n");
+#else
+ printf("#define DK3_HAVE_STRNCMP 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRNCPY\n");
+ printf("/**\tDK3 version of HAVE_STRNCPY.\n*/\n");
+#if HAVE_STRNCPY
+ printf("#define DK3_HAVE_STRNCPY 1\n");
+#else
+ printf("#define DK3_HAVE_STRNCPY 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRNCPY_S\n");
+ printf("/**\tDK3 version of HAVE_STRNCPY_S.\n*/\n");
+#if HAVE_STRNCPY_S
+ printf("#define DK3_HAVE_STRNCPY_S 1\n");
+#else
+ printf("#define DK3_HAVE_STRNCPY_S 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STROPTS_H\n");
+ printf("/**\tDK3 version of HAVE_STROPTS_H.\n*/\n");
+#if HAVE_STROPTS_H
+ printf("#define DK3_HAVE_STROPTS_H 1\n");
+#else
+ printf("#define DK3_HAVE_STROPTS_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRRCHR\n");
+ printf("/**\tDK3 version of HAVE_STRRCHR.\n*/\n");
+#if HAVE_STRRCHR
+ printf("#define DK3_HAVE_STRRCHR 1\n");
+#else
+ printf("#define DK3_HAVE_STRRCHR 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRTOD\n");
+ printf("/**\tDK3 version of HAVE_STRTOD.\n*/\n");
+#if HAVE_STRTOD
+ printf("#define DK3_HAVE_STRTOD 1\n");
+#else
+ printf("#define DK3_HAVE_STRTOD 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRTOIMAX\n");
+ printf("/**\tDK3 version of HAVE_STRTOIMAX.\n*/\n");
+#if HAVE_STRTOIMAX
+ printf("#define DK3_HAVE_STRTOIMAX 1\n");
+#else
+ printf("#define DK3_HAVE_STRTOIMAX 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRTOL\n");
+ printf("/**\tDK3 version of HAVE_STRTOL.\n*/\n");
+#if HAVE_STRTOL
+ printf("#define DK3_HAVE_STRTOL 1\n");
+#else
+ printf("#define DK3_HAVE_STRTOL 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRTOLL\n");
+ printf("/**\tDK3 version of HAVE_STRTOLL.\n*/\n");
+#if HAVE_STRTOLL
+ printf("#define DK3_HAVE_STRTOLL 1\n");
+#else
+ printf("#define DK3_HAVE_STRTOLL 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRTOUL\n");
+ printf("/**\tDK3 version of HAVE_STRTOUL.\n*/\n");
+#if HAVE_STRTOUL
+ printf("#define DK3_HAVE_STRTOUL 1\n");
+#else
+ printf("#define DK3_HAVE_STRTOUL 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRTOULL\n");
+ printf("/**\tDK3 version of HAVE_STRTOULL.\n*/\n");
+#if HAVE_STRTOULL
+ printf("#define DK3_HAVE_STRTOULL 1\n");
+#else
+ printf("#define DK3_HAVE_STRTOULL 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRTOUMAX\n");
+ printf("/**\tDK3 version of HAVE_STRTOUMAX.\n*/\n");
+#if HAVE_STRTOUMAX
+ printf("#define DK3_HAVE_STRTOUMAX 1\n");
+#else
+ printf("#define DK3_HAVE_STRTOUMAX 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRUCT_ADDRINFO\n");
+ printf("/**\tDK3 version of HAVE_STRUCT_ADDRINFO.\n*/\n");
+#if HAVE_STRUCT_ADDRINFO
+ printf("#define DK3_HAVE_STRUCT_ADDRINFO 1\n");
+#else
+ printf("#define DK3_HAVE_STRUCT_ADDRINFO 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRUCT_SOCKADDR_IN\n");
+ printf("/**\tDK3 version of HAVE_STRUCT_SOCKADDR_IN.\n*/\n");
+#if HAVE_STRUCT_SOCKADDR_IN
+ printf("#define DK3_HAVE_STRUCT_SOCKADDR_IN 1\n");
+#else
+ printf("#define DK3_HAVE_STRUCT_SOCKADDR_IN 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRUCT_SOCKADDR_IN6\n");
+ printf("/**\tDK3 version of HAVE_STRUCT_SOCKADDR_IN6.\n*/\n");
+#if HAVE_STRUCT_SOCKADDR_IN6
+ printf("#define DK3_HAVE_STRUCT_SOCKADDR_IN6 1\n");
+#else
+ printf("#define DK3_HAVE_STRUCT_SOCKADDR_IN6 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRUCT_SOCKADDR_STORAGE\n");
+ printf("/**\tDK3 version of HAVE_STRUCT_SOCKADDR_STORAGE.\n*/\n");
+#if HAVE_STRUCT_SOCKADDR_STORAGE
+ printf("#define DK3_HAVE_STRUCT_SOCKADDR_STORAGE 1\n");
+#else
+ printf("#define DK3_HAVE_STRUCT_SOCKADDR_STORAGE 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_STRUCT_SOCKADDR_UN\n");
+ printf("/**\tDK3 version of HAVE_STRUCT_SOCKADDR_UN.\n*/\n");
+#if HAVE_STRUCT_SOCKADDR_UN
+ printf("#define DK3_HAVE_STRUCT_SOCKADDR_UN 1\n");
+#else
+ printf("#define DK3_HAVE_STRUCT_SOCKADDR_UN 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SWSCANF_S\n");
+ printf("/**\tDK3 version of HAVE_SWSCANF_S.\n*/\n");
+#if HAVE_SWSCANF_S
+ printf("#define DK3_HAVE_SWSCANF_S 1\n");
+#else
+ printf("#define DK3_HAVE_SWSCANF_S 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYSCONF\n");
+ printf("/**\tDK3 version of HAVE_SYSCONF.\n*/\n");
+#if HAVE_SYSCONF
+ printf("#define DK3_HAVE_SYSCONF 1\n");
+#else
+ printf("#define DK3_HAVE_SYSCONF 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYSCTL\n");
+ printf("/**\tDK3 version of HAVE_SYSCTL.\n*/\n");
+#if HAVE_SYSCTL
+ printf("#define DK3_HAVE_SYSCTL 1\n");
+#else
+ printf("#define DK3_HAVE_SYSCTL 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYSLOG\n");
+ printf("/**\tDK3 version of HAVE_SYSLOG.\n*/\n");
+#if HAVE_SYSLOG
+ printf("#define DK3_HAVE_SYSLOG 1\n");
+#else
+ printf("#define DK3_HAVE_SYSLOG 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYSLOG_H\n");
+ printf("/**\tDK3 version of HAVE_SYSLOG_H.\n*/\n");
+#if HAVE_SYSLOG_H
+ printf("#define DK3_HAVE_SYSLOG_H 1\n");
+#else
+ printf("#define DK3_HAVE_SYSLOG_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYSRES_H\n");
+ printf("/**\tDK3 version of HAVE_SYSRES_H.\n*/\n");
+#if HAVE_SYSRES_H
+ printf("#define DK3_HAVE_SYSRES_H 1\n");
+#else
+ printf("#define DK3_HAVE_SYSRES_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYS_FILE_H\n");
+ printf("/**\tDK3 version of HAVE_SYS_FILE_H.\n*/\n");
+#if HAVE_SYS_FILE_H
+ printf("#define DK3_HAVE_SYS_FILE_H 1\n");
+#else
+ printf("#define DK3_HAVE_SYS_FILE_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYS_PARAM_H\n");
+ printf("/**\tDK3 version of HAVE_SYS_PARAM_H.\n*/\n");
+#if HAVE_SYS_PARAM_H
+ printf("#define DK3_HAVE_SYS_PARAM_H 1\n");
+#else
+ printf("#define DK3_HAVE_SYS_PARAM_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYS_RESOURCE_H\n");
+ printf("/**\tDK3 version of HAVE_SYS_RESOURCE_H.\n*/\n");
+#if HAVE_SYS_RESOURCE_H
+ printf("#define DK3_HAVE_SYS_RESOURCE_H 1\n");
+#else
+ printf("#define DK3_HAVE_SYS_RESOURCE_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYS_SOCKET_H\n");
+ printf("/**\tDK3 version of HAVE_SYS_SOCKET_H.\n*/\n");
+#if HAVE_SYS_SOCKET_H
+ printf("#define DK3_HAVE_SYS_SOCKET_H 1\n");
+#else
+ printf("#define DK3_HAVE_SYS_SOCKET_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYS_STATVFS_H\n");
+ printf("/**\tDK3 version of HAVE_SYS_STATVFS_H.\n*/\n");
+#if HAVE_SYS_STATVFS_H
+ printf("#define DK3_HAVE_SYS_STATVFS_H 1\n");
+#else
+ printf("#define DK3_HAVE_SYS_STATVFS_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYS_STAT_H\n");
+ printf("/**\tDK3 version of HAVE_SYS_STAT_H.\n*/\n");
+#if HAVE_SYS_STAT_H
+ printf("#define DK3_HAVE_SYS_STAT_H 1\n");
+#else
+ printf("#define DK3_HAVE_SYS_STAT_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYS_STROPTS_H\n");
+ printf("/**\tDK3 version of HAVE_SYS_STROPTS_H.\n*/\n");
+#if HAVE_SYS_STROPTS_H
+ printf("#define DK3_HAVE_SYS_STROPTS_H 1\n");
+#else
+ printf("#define DK3_HAVE_SYS_STROPTS_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYS_SUNDDI_H\n");
+ printf("/**\tDK3 version of HAVE_SYS_SUNDDI_H.\n*/\n");
+#if HAVE_SYS_SUNDDI_H
+ printf("#define DK3_HAVE_SYS_SUNDDI_H 1\n");
+#else
+ printf("#define DK3_HAVE_SYS_SUNDDI_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYS_SYSCTL_H\n");
+ printf("/**\tDK3 version of HAVE_SYS_SYSCTL_H.\n*/\n");
+#if HAVE_SYS_SYSCTL_H
+ printf("#define DK3_HAVE_SYS_SYSCTL_H 1\n");
+#else
+ printf("#define DK3_HAVE_SYS_SYSCTL_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYS_SYSTEMINFO_H\n");
+ printf("/**\tDK3 version of HAVE_SYS_SYSTEMINFO_H.\n*/\n");
+#if HAVE_SYS_SYSTEMINFO_H
+ printf("#define DK3_HAVE_SYS_SYSTEMINFO_H 1\n");
+#else
+ printf("#define DK3_HAVE_SYS_SYSTEMINFO_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYS_TERMIOS_H\n");
+ printf("/**\tDK3 version of HAVE_SYS_TERMIOS_H.\n*/\n");
+#if HAVE_SYS_TERMIOS_H
+ printf("#define DK3_HAVE_SYS_TERMIOS_H 1\n");
+#else
+ printf("#define DK3_HAVE_SYS_TERMIOS_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYS_TIME_H\n");
+ printf("/**\tDK3 version of HAVE_SYS_TIME_H.\n*/\n");
+#if HAVE_SYS_TIME_H
+ printf("#define DK3_HAVE_SYS_TIME_H 1\n");
+#else
+ printf("#define DK3_HAVE_SYS_TIME_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYS_TTOLD_H\n");
+ printf("/**\tDK3 version of HAVE_SYS_TTOLD_H.\n*/\n");
+#if HAVE_SYS_TTOLD_H
+ printf("#define DK3_HAVE_SYS_TTOLD_H 1\n");
+#else
+ printf("#define DK3_HAVE_SYS_TTOLD_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYS_TYPES_H\n");
+ printf("/**\tDK3 version of HAVE_SYS_TYPES_H.\n*/\n");
+#if HAVE_SYS_TYPES_H
+ printf("#define DK3_HAVE_SYS_TYPES_H 1\n");
+#else
+ printf("#define DK3_HAVE_SYS_TYPES_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYS_UIO_H\n");
+ printf("/**\tDK3 version of HAVE_SYS_UIO_H.\n*/\n");
+#if HAVE_SYS_UIO_H
+ printf("#define DK3_HAVE_SYS_UIO_H 1\n");
+#else
+ printf("#define DK3_HAVE_SYS_UIO_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYS_UN_H\n");
+ printf("/**\tDK3 version of HAVE_SYS_UN_H.\n*/\n");
+#if HAVE_SYS_UN_H
+ printf("#define DK3_HAVE_SYS_UN_H 1\n");
+#else
+ printf("#define DK3_HAVE_SYS_UN_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_SYS_WAIT_H\n");
+ printf("/**\tDK3 version of HAVE_SYS_WAIT_H.\n*/\n");
+#if HAVE_SYS_WAIT_H
+ printf("#define DK3_HAVE_SYS_WAIT_H 1\n");
+#else
+ printf("#define DK3_HAVE_SYS_WAIT_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_TANHL\n");
+ printf("/**\tDK3 version of HAVE_TANHL.\n*/\n");
+#if HAVE_TANHL
+ printf("#define DK3_HAVE_TANHL 1\n");
+#else
+ printf("#define DK3_HAVE_TANHL 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_TANL\n");
+ printf("/**\tDK3 version of HAVE_TANL.\n*/\n");
+#if HAVE_TANL
+ printf("#define DK3_HAVE_TANL 1\n");
+#else
+ printf("#define DK3_HAVE_TANL 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_TCFLUSH\n");
+ printf("/**\tDK3 version of HAVE_TCFLUSH.\n*/\n");
+#if HAVE_TCFLUSH
+ printf("#define DK3_HAVE_TCFLUSH 1\n");
+#else
+ printf("#define DK3_HAVE_TCFLUSH 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_TCGETATTR\n");
+ printf("/**\tDK3 version of HAVE_TCGETATTR.\n*/\n");
+#if HAVE_TCGETATTR
+ printf("#define DK3_HAVE_TCGETATTR 1\n");
+#else
+ printf("#define DK3_HAVE_TCGETATTR 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_TERMIOS_H\n");
+ printf("/**\tDK3 version of HAVE_TERMIOS_H.\n*/\n");
+#if HAVE_TERMIOS_H
+ printf("#define DK3_HAVE_TERMIOS_H 1\n");
+#else
+ printf("#define DK3_HAVE_TERMIOS_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_TIFF_H\n");
+ printf("/**\tDK3 version of HAVE_TIFF_H.\n*/\n");
+#if HAVE_TIFF_H
+ printf("#define DK3_HAVE_TIFF_H 1\n");
+#else
+ printf("#define DK3_HAVE_TIFF_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_TIME\n");
+ printf("/**\tDK3 version of HAVE_TIME.\n*/\n");
+#if HAVE_TIME
+ printf("#define DK3_HAVE_TIME 1\n");
+#else
+ printf("#define DK3_HAVE_TIME 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_TIME_H\n");
+ printf("/**\tDK3 version of HAVE_TIME_H.\n*/\n");
+#if HAVE_TIME_H
+ printf("#define DK3_HAVE_TIME_H 1\n");
+#else
+ printf("#define DK3_HAVE_TIME_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_TWOS_COMPLEMENT\n");
+ printf("/**\tDK3 version of HAVE_TWOS_COMPLEMENT.\n*/\n");
+#if HAVE_TWOS_COMPLEMENT
+ printf("#define DK3_HAVE_TWOS_COMPLEMENT 1\n");
+#else
+ printf("#define DK3_HAVE_TWOS_COMPLEMENT 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_UMASK\n");
+ printf("/**\tDK3 version of HAVE_UMASK.\n*/\n");
+#if HAVE_UMASK
+ printf("#define DK3_HAVE_UMASK 1\n");
+#else
+ printf("#define DK3_HAVE_UMASK 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_UNISTD_H\n");
+ printf("/**\tDK3 version of HAVE_UNISTD_H.\n*/\n");
+#if HAVE_UNISTD_H
+ printf("#define DK3_HAVE_UNISTD_H 1\n");
+#else
+ printf("#define DK3_HAVE_UNISTD_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_UNLINK\n");
+ printf("/**\tDK3 version of HAVE_UNLINK.\n*/\n");
+#if HAVE_UNLINK
+ printf("#define DK3_HAVE_UNLINK 1\n");
+#else
+ printf("#define DK3_HAVE_UNLINK 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_USER_NAMES_CASE_INSENSITIVE\n");
+ printf("/**\tDK3 version of HAVE_USER_NAMES_CASE_INSENSITIVE.\n*/\n");
+#if HAVE_USER_NAMES_CASE_INSENSITIVE
+ printf("#define DK3_HAVE_USER_NAMES_CASE_INSENSITIVE 1\n");
+#else
+ printf("#define DK3_HAVE_USER_NAMES_CASE_INSENSITIVE 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_VARARGS_H\n");
+ printf("/**\tDK3 version of HAVE_VARARGS_H.\n*/\n");
+#if HAVE_VARARGS_H
+ printf("#define DK3_HAVE_VARARGS_H 1\n");
+#else
+ printf("#define DK3_HAVE_VARARGS_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_VARARG_H\n");
+ printf("/**\tDK3 version of HAVE_VARARG_H.\n*/\n");
+#if HAVE_VARARG_H
+ printf("#define DK3_HAVE_VARARG_H 1\n");
+#else
+ printf("#define DK3_HAVE_VARARG_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_VOLATILE\n");
+ printf("/**\tDK3 version of HAVE_VOLATILE.\n*/\n");
+#if HAVE_VOLATILE
+ printf("#define DK3_HAVE_VOLATILE 1\n");
+#else
+ printf("#define DK3_HAVE_VOLATILE 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCHAR_H\n");
+ printf("/**\tDK3 version of HAVE_WCHAR_H.\n*/\n");
+#if HAVE_WCHAR_H
+ printf("#define DK3_HAVE_WCHAR_H 1\n");
+#else
+ printf("#define DK3_HAVE_WCHAR_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCHAR_T\n");
+ printf("/**\tDK3 version of HAVE_WCHAR_T.\n*/\n");
+#if HAVE_WCHAR_T
+ printf("#define DK3_HAVE_WCHAR_T 1\n");
+#else
+ printf("#define DK3_HAVE_WCHAR_T 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSCAT\n");
+ printf("/**\tDK3 version of HAVE_WCSCAT.\n*/\n");
+#if HAVE_WCSCAT
+ printf("#define DK3_HAVE_WCSCAT 1\n");
+#else
+ printf("#define DK3_HAVE_WCSCAT 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSCAT_S\n");
+ printf("/**\tDK3 version of HAVE_WCSCAT_S.\n*/\n");
+#if HAVE_WCSCAT_S
+ printf("#define DK3_HAVE_WCSCAT_S 1\n");
+#else
+ printf("#define DK3_HAVE_WCSCAT_S 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSCHR\n");
+ printf("/**\tDK3 version of HAVE_WCSCHR.\n*/\n");
+#if HAVE_WCSCHR
+ printf("#define DK3_HAVE_WCSCHR 1\n");
+#else
+ printf("#define DK3_HAVE_WCSCHR 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSCMP\n");
+ printf("/**\tDK3 version of HAVE_WCSCMP.\n*/\n");
+#if HAVE_WCSCMP
+ printf("#define DK3_HAVE_WCSCMP 1\n");
+#else
+ printf("#define DK3_HAVE_WCSCMP 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSCPY\n");
+ printf("/**\tDK3 version of HAVE_WCSCPY.\n*/\n");
+#if HAVE_WCSCPY
+ printf("#define DK3_HAVE_WCSCPY 1\n");
+#else
+ printf("#define DK3_HAVE_WCSCPY 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSCPY_S\n");
+ printf("/**\tDK3 version of HAVE_WCSCPY_S.\n*/\n");
+#if HAVE_WCSCPY_S
+ printf("#define DK3_HAVE_WCSCPY_S 1\n");
+#else
+ printf("#define DK3_HAVE_WCSCPY_S 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSDUP\n");
+ printf("/**\tDK3 version of HAVE_WCSDUP.\n*/\n");
+#if HAVE_WCSDUP
+ printf("#define DK3_HAVE_WCSDUP 1\n");
+#else
+ printf("#define DK3_HAVE_WCSDUP 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSICMP\n");
+ printf("/**\tDK3 version of HAVE_WCSICMP.\n*/\n");
+#if HAVE_WCSICMP
+ printf("#define DK3_HAVE_WCSICMP 1\n");
+#else
+ printf("#define DK3_HAVE_WCSICMP 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSLEN\n");
+ printf("/**\tDK3 version of HAVE_WCSLEN.\n*/\n");
+#if HAVE_WCSLEN
+ printf("#define DK3_HAVE_WCSLEN 1\n");
+#else
+ printf("#define DK3_HAVE_WCSLEN 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSNCMP\n");
+ printf("/**\tDK3 version of HAVE_WCSNCMP.\n*/\n");
+#if HAVE_WCSNCMP
+ printf("#define DK3_HAVE_WCSNCMP 1\n");
+#else
+ printf("#define DK3_HAVE_WCSNCMP 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSNCPY\n");
+ printf("/**\tDK3 version of HAVE_WCSNCPY.\n*/\n");
+#if HAVE_WCSNCPY
+ printf("#define DK3_HAVE_WCSNCPY 1\n");
+#else
+ printf("#define DK3_HAVE_WCSNCPY 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSNCPY_S\n");
+ printf("/**\tDK3 version of HAVE_WCSNCPY_S.\n*/\n");
+#if HAVE_WCSNCPY_S
+ printf("#define DK3_HAVE_WCSNCPY_S 1\n");
+#else
+ printf("#define DK3_HAVE_WCSNCPY_S 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSRCHR\n");
+ printf("/**\tDK3 version of HAVE_WCSRCHR.\n*/\n");
+#if HAVE_WCSRCHR
+ printf("#define DK3_HAVE_WCSRCHR 1\n");
+#else
+ printf("#define DK3_HAVE_WCSRCHR 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSTOD\n");
+ printf("/**\tDK3 version of HAVE_WCSTOD.\n*/\n");
+#if HAVE_WCSTOD
+ printf("#define DK3_HAVE_WCSTOD 1\n");
+#else
+ printf("#define DK3_HAVE_WCSTOD 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSTOIMAX\n");
+ printf("/**\tDK3 version of HAVE_WCSTOIMAX.\n*/\n");
+#if HAVE_WCSTOIMAX
+ printf("#define DK3_HAVE_WCSTOIMAX 1\n");
+#else
+ printf("#define DK3_HAVE_WCSTOIMAX 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSTOL\n");
+ printf("/**\tDK3 version of HAVE_WCSTOL.\n*/\n");
+#if HAVE_WCSTOL
+ printf("#define DK3_HAVE_WCSTOL 1\n");
+#else
+ printf("#define DK3_HAVE_WCSTOL 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSTOLL\n");
+ printf("/**\tDK3 version of HAVE_WCSTOLL.\n*/\n");
+#if HAVE_WCSTOLL
+ printf("#define DK3_HAVE_WCSTOLL 1\n");
+#else
+ printf("#define DK3_HAVE_WCSTOLL 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSTOUL\n");
+ printf("/**\tDK3 version of HAVE_WCSTOUL.\n*/\n");
+#if HAVE_WCSTOUL
+ printf("#define DK3_HAVE_WCSTOUL 1\n");
+#else
+ printf("#define DK3_HAVE_WCSTOUL 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSTOULL\n");
+ printf("/**\tDK3 version of HAVE_WCSTOULL.\n*/\n");
+#if HAVE_WCSTOULL
+ printf("#define DK3_HAVE_WCSTOULL 1\n");
+#else
+ printf("#define DK3_HAVE_WCSTOULL 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WCSTOUMAX\n");
+ printf("/**\tDK3 version of HAVE_WCSTOUMAX.\n*/\n");
+#if HAVE_WCSTOUMAX
+ printf("#define DK3_HAVE_WCSTOUMAX 1\n");
+#else
+ printf("#define DK3_HAVE_WCSTOUMAX 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WINBASE_H\n");
+ printf("/**\tDK3 version of HAVE_WINBASE_H.\n*/\n");
+#if HAVE_WINBASE_H
+ printf("#define DK3_HAVE_WINBASE_H 1\n");
+#else
+ printf("#define DK3_HAVE_WINBASE_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WINCON_H\n");
+ printf("/**\tDK3 version of HAVE_WINCON_H.\n*/\n");
+#if HAVE_WINCON_H
+ printf("#define DK3_HAVE_WINCON_H 1\n");
+#else
+ printf("#define DK3_HAVE_WINCON_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WINDOWS_H\n");
+ printf("/**\tDK3 version of HAVE_WINDOWS_H.\n*/\n");
+#if HAVE_WINDOWS_H
+ printf("#define DK3_HAVE_WINDOWS_H 1\n");
+#else
+ printf("#define DK3_HAVE_WINDOWS_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WINREG_H\n");
+ printf("/**\tDK3 version of HAVE_WINREG_H.\n*/\n");
+#if HAVE_WINREG_H
+ printf("#define DK3_HAVE_WINREG_H 1\n");
+#else
+ printf("#define DK3_HAVE_WINREG_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WINSOCK2_H\n");
+ printf("/**\tDK3 version of HAVE_WINSOCK2_H.\n*/\n");
+#if HAVE_WINSOCK2_H
+ printf("#define DK3_HAVE_WINSOCK2_H 1\n");
+#else
+ printf("#define DK3_HAVE_WINSOCK2_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WRITE\n");
+ printf("/**\tDK3 version of HAVE_WRITE.\n*/\n");
+#if HAVE_WRITE
+ printf("#define DK3_HAVE_WRITE 1\n");
+#else
+ printf("#define DK3_HAVE_WRITE 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WS2TCPIP_H\n");
+ printf("/**\tDK3 version of HAVE_WS2TCPIP_H.\n*/\n");
+#if HAVE_WS2TCPIP_H
+ printf("#define DK3_HAVE_WS2TCPIP_H 1\n");
+#else
+ printf("#define DK3_HAVE_WS2TCPIP_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_ZLIB_H\n");
+ printf("/**\tDK3 version of HAVE_ZLIB_H.\n*/\n");
+#if HAVE_ZLIB_H
+ printf("#define DK3_HAVE_ZLIB_H 1\n");
+#else
+ printf("#define DK3_HAVE_ZLIB_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__CLEARFP\n");
+ printf("/**\tDK3 version of HAVE__CLEARFP.\n*/\n");
+#if HAVE__CLEARFP
+ printf("#define DK3_HAVE__CLEARFP 1\n");
+#else
+ printf("#define DK3_HAVE__CLEARFP 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__FCLOSE\n");
+ printf("/**\tDK3 version of HAVE__FCLOSE.\n*/\n");
+#if HAVE__FCLOSE
+ printf("#define DK3_HAVE__FCLOSE 1\n");
+#else
+ printf("#define DK3_HAVE__FCLOSE 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__FEOF\n");
+ printf("/**\tDK3 version of HAVE__FEOF.\n*/\n");
+#if HAVE__FEOF
+ printf("#define DK3_HAVE__FEOF 1\n");
+#else
+ printf("#define DK3_HAVE__FEOF 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__FERROR\n");
+ printf("/**\tDK3 version of HAVE__FERROR.\n*/\n");
+#if HAVE__FERROR
+ printf("#define DK3_HAVE__FERROR 1\n");
+#else
+ printf("#define DK3_HAVE__FERROR 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__FFLUSH\n");
+ printf("/**\tDK3 version of HAVE__FFLUSH.\n*/\n");
+#if HAVE__FFLUSH
+ printf("#define DK3_HAVE__FFLUSH 1\n");
+#else
+ printf("#define DK3_HAVE__FFLUSH 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__FOPEN\n");
+ printf("/**\tDK3 version of HAVE__FOPEN.\n*/\n");
+#if HAVE__FOPEN
+ printf("#define DK3_HAVE__FOPEN 1\n");
+#else
+ printf("#define DK3_HAVE__FOPEN 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__FREAD\n");
+ printf("/**\tDK3 version of HAVE__FREAD.\n*/\n");
+#if HAVE__FREAD
+ printf("#define DK3_HAVE__FREAD 1\n");
+#else
+ printf("#define DK3_HAVE__FREAD 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__FWRITE\n");
+ printf("/**\tDK3 version of HAVE__FWRITE.\n*/\n");
+#if HAVE__FWRITE
+ printf("#define DK3_HAVE__FWRITE 1\n");
+#else
+ printf("#define DK3_HAVE__FWRITE 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__GETCWD\n");
+ printf("/**\tDK3 version of HAVE__GETCWD.\n*/\n");
+#if HAVE__GETCWD
+ printf("#define DK3_HAVE__GETCWD 1\n");
+#else
+ printf("#define DK3_HAVE__GETCWD 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__GETENV_S\n");
+ printf("/**\tDK3 version of HAVE__GETENV_S.\n*/\n");
+#if HAVE__GETENV_S
+ printf("#define DK3_HAVE__GETENV_S 1\n");
+#else
+ printf("#define DK3_HAVE__GETENV_S 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__GETPID\n");
+ printf("/**\tDK3 version of HAVE__GETPID.\n*/\n");
+#if HAVE__GETPID
+ printf("#define DK3_HAVE__GETPID 1\n");
+#else
+ printf("#define DK3_HAVE__GETPID 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__LSTAT\n");
+ printf("/**\tDK3 version of HAVE__LSTAT.\n*/\n");
+#if HAVE__LSTAT
+ printf("#define DK3_HAVE__LSTAT 1\n");
+#else
+ printf("#define DK3_HAVE__LSTAT 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__LSTAT32\n");
+ printf("/**\tDK3 version of HAVE__LSTAT32.\n*/\n");
+#if HAVE__LSTAT32
+ printf("#define DK3_HAVE__LSTAT32 1\n");
+#else
+ printf("#define DK3_HAVE__LSTAT32 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__LSTAT64\n");
+ printf("/**\tDK3 version of HAVE__LSTAT64.\n*/\n");
+#if HAVE__LSTAT64
+ printf("#define DK3_HAVE__LSTAT64 1\n");
+#else
+ printf("#define DK3_HAVE__LSTAT64 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__MKDIR\n");
+ printf("/**\tDK3 version of HAVE__MKDIR.\n*/\n");
+#if HAVE__MKDIR
+ printf("#define DK3_HAVE__MKDIR 1\n");
+#else
+ printf("#define DK3_HAVE__MKDIR 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__POPEN\n");
+ printf("/**\tDK3 version of HAVE__POPEN.\n*/\n");
+#if HAVE__POPEN
+ printf("#define DK3_HAVE__POPEN 1\n");
+#else
+ printf("#define DK3_HAVE__POPEN 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__READ\n");
+ printf("/**\tDK3 version of HAVE__READ.\n*/\n");
+#if HAVE__READ
+ printf("#define DK3_HAVE__READ 1\n");
+#else
+ printf("#define DK3_HAVE__READ 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__RMDIR\n");
+ printf("/**\tDK3 version of HAVE__RMDIR.\n*/\n");
+#if HAVE__RMDIR
+ printf("#define DK3_HAVE__RMDIR 1\n");
+#else
+ printf("#define DK3_HAVE__RMDIR 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__SNPRINTF\n");
+ printf("/**\tDK3 version of HAVE__SNPRINTF.\n*/\n");
+#if HAVE__SNPRINTF
+ printf("#define DK3_HAVE__SNPRINTF 1\n");
+#else
+ printf("#define DK3_HAVE__SNPRINTF 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__SNPRINTF_S\n");
+ printf("/**\tDK3 version of HAVE__SNPRINTF_S.\n*/\n");
+#if HAVE__SNPRINTF_S
+ printf("#define DK3_HAVE__SNPRINTF_S 1\n");
+#else
+ printf("#define DK3_HAVE__SNPRINTF_S 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__SNWPRINTF\n");
+ printf("/**\tDK3 version of HAVE__SNWPRINTF.\n*/\n");
+#if HAVE__SNWPRINTF
+ printf("#define DK3_HAVE__SNWPRINTF 1\n");
+#else
+ printf("#define DK3_HAVE__SNWPRINTF 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__SNWPRINTF_S\n");
+ printf("/**\tDK3 version of HAVE__SNWPRINTF_S.\n*/\n");
+#if HAVE__SNWPRINTF_S
+ printf("#define DK3_HAVE__SNWPRINTF_S 1\n");
+#else
+ printf("#define DK3_HAVE__SNWPRINTF_S 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__STAT\n");
+ printf("/**\tDK3 version of HAVE__STAT.\n*/\n");
+#if HAVE__STAT
+ printf("#define DK3_HAVE__STAT 1\n");
+#else
+ printf("#define DK3_HAVE__STAT 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__STAT32\n");
+ printf("/**\tDK3 version of HAVE__STAT32.\n*/\n");
+#if HAVE__STAT32
+ printf("#define DK3_HAVE__STAT32 1\n");
+#else
+ printf("#define DK3_HAVE__STAT32 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__STAT64\n");
+ printf("/**\tDK3 version of HAVE__STAT64.\n*/\n");
+#if HAVE__STAT64
+ printf("#define DK3_HAVE__STAT64 1\n");
+#else
+ printf("#define DK3_HAVE__STAT64 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__STRDUP\n");
+ printf("/**\tDK3 version of HAVE__STRDUP.\n*/\n");
+#if HAVE__STRDUP
+ printf("#define DK3_HAVE__STRDUP 1\n");
+#else
+ printf("#define DK3_HAVE__STRDUP 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__STRICMP\n");
+ printf("/**\tDK3 version of HAVE__STRICMP.\n*/\n");
+#if HAVE__STRICMP
+ printf("#define DK3_HAVE__STRICMP 1\n");
+#else
+ printf("#define DK3_HAVE__STRICMP 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__UNLINK\n");
+ printf("/**\tDK3 version of HAVE__UNLINK.\n*/\n");
+#if HAVE__UNLINK
+ printf("#define DK3_HAVE__UNLINK 1\n");
+#else
+ printf("#define DK3_HAVE__UNLINK 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__WCSCAT\n");
+ printf("/**\tDK3 version of HAVE__WCSCAT.\n*/\n");
+#if HAVE__WCSCAT
+ printf("#define DK3_HAVE__WCSCAT 1\n");
+#else
+ printf("#define DK3_HAVE__WCSCAT 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__WCSCHR\n");
+ printf("/**\tDK3 version of HAVE__WCSCHR.\n*/\n");
+#if HAVE__WCSCHR
+ printf("#define DK3_HAVE__WCSCHR 1\n");
+#else
+ printf("#define DK3_HAVE__WCSCHR 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__WCSCMP\n");
+ printf("/**\tDK3 version of HAVE__WCSCMP.\n*/\n");
+#if HAVE__WCSCMP
+ printf("#define DK3_HAVE__WCSCMP 1\n");
+#else
+ printf("#define DK3_HAVE__WCSCMP 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__WCSCPY\n");
+ printf("/**\tDK3 version of HAVE__WCSCPY.\n*/\n");
+#if HAVE__WCSCPY
+ printf("#define DK3_HAVE__WCSCPY 1\n");
+#else
+ printf("#define DK3_HAVE__WCSCPY 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__WCSDUP\n");
+ printf("/**\tDK3 version of HAVE__WCSDUP.\n*/\n");
+#if HAVE__WCSDUP
+ printf("#define DK3_HAVE__WCSDUP 1\n");
+#else
+ printf("#define DK3_HAVE__WCSDUP 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__WCSICMP\n");
+ printf("/**\tDK3 version of HAVE__WCSICMP.\n*/\n");
+#if HAVE__WCSICMP
+ printf("#define DK3_HAVE__WCSICMP 1\n");
+#else
+ printf("#define DK3_HAVE__WCSICMP 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__WCSLEN\n");
+ printf("/**\tDK3 version of HAVE__WCSLEN.\n*/\n");
+#if HAVE__WCSLEN
+ printf("#define DK3_HAVE__WCSLEN 1\n");
+#else
+ printf("#define DK3_HAVE__WCSLEN 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__WCSNCMP\n");
+ printf("/**\tDK3 version of HAVE__WCSNCMP.\n*/\n");
+#if HAVE__WCSNCMP
+ printf("#define DK3_HAVE__WCSNCMP 1\n");
+#else
+ printf("#define DK3_HAVE__WCSNCMP 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__WCSNCPY\n");
+ printf("/**\tDK3 version of HAVE__WCSNCPY.\n*/\n");
+#if HAVE__WCSNCPY
+ printf("#define DK3_HAVE__WCSNCPY 1\n");
+#else
+ printf("#define DK3_HAVE__WCSNCPY 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__WCSRCHR\n");
+ printf("/**\tDK3 version of HAVE__WCSRCHR.\n*/\n");
+#if HAVE__WCSRCHR
+ printf("#define DK3_HAVE__WCSRCHR 1\n");
+#else
+ printf("#define DK3_HAVE__WCSRCHR 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__WFOPEN_S\n");
+ printf("/**\tDK3 version of HAVE__WFOPEN_S.\n*/\n");
+#if HAVE__WFOPEN_S
+ printf("#define DK3_HAVE__WFOPEN_S 1\n");
+#else
+ printf("#define DK3_HAVE__WFOPEN_S 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__WGETENV\n");
+ printf("/**\tDK3 version of HAVE__WGETENV.\n*/\n");
+#if HAVE__WGETENV
+ printf("#define DK3_HAVE__WGETENV 1\n");
+#else
+ printf("#define DK3_HAVE__WGETENV 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE__WRITE\n");
+ printf("/**\tDK3 version of HAVE__WRITE.\n*/\n");
+#if HAVE__WRITE
+ printf("#define DK3_HAVE__WRITE 1\n");
+#else
+ printf("#define DK3_HAVE__WRITE 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_TIME_WITH_SYS_TIME\n");
+ printf("/**\tDK3 version of TIME_WITH_SYS_TIME.\n*/\n");
+#if TIME_WITH_SYS_TIME
+ printf("#define DK3_TIME_WITH_SYS_TIME 1\n");
+#else
+ printf("#define DK3_TIME_WITH_SYS_TIME 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WX_CHARTYPE_H\n");
+ printf("/**\tDK3 version of HAVE_WX_CHARTYPE_H.\n*/\n");
+#if HAVE_WX_CHARTYPE_H
+ printf("#define DK3_HAVE_WX_CHARTYPE_H 1\n");
+#else
+ printf("#define DK3_HAVE_WX_CHARTYPE_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_HAVE_WX_WXCHAR_H\n");
+ printf("/**\tDK3 version of HAVE_WX_WXCHAR_H.\n*/\n");
+#if HAVE_WX_WXCHAR_H
+ printf("#define DK3_HAVE_WX_WXCHAR_H 1\n");
+#else
+ printf("#define DK3_HAVE_WX_WXCHAR_H 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_SIZEOF_DOUBLE\n");
+ printf("/**\tDK3 version of SIZEOF_DOUBLE.\n*/\n");
+ printf("#define DK3_SIZEOF_DOUBLE %d\n", (int)SIZEOF_DOUBLE);
+ printf("#endif\n");
+ printf("\n#ifndef DK3_SIZEOF_INT\n");
+ printf("/**\tDK3 version of SIZEOF_INT.\n*/\n");
+ printf("#define DK3_SIZEOF_INT %d\n", (int)SIZEOF_INT);
+ printf("#endif\n");
+ printf("\n#ifndef DK3_SIZEOF_INTMAX_T\n");
+ printf("/**\tDK3 version of SIZEOF_INTMAX_T.\n*/\n");
+ printf("#define DK3_SIZEOF_INTMAX_T %d\n", (int)SIZEOF_INTMAX_T);
+ printf("#endif\n");
+ printf("\n#ifndef DK3_SIZEOF_LONG\n");
+ printf("/**\tDK3 version of SIZEOF_LONG.\n*/\n");
+ printf("#define DK3_SIZEOF_LONG %d\n", (int)SIZEOF_LONG);
+ printf("#endif\n");
+ printf("\n#ifndef DK3_SIZEOF_LONG_DOUBLE\n");
+ printf("/**\tDK3 version of SIZEOF_LONG_DOUBLE.\n*/\n");
+ printf("#define DK3_SIZEOF_LONG_DOUBLE %d\n", (int)SIZEOF_LONG_DOUBLE);
+ printf("#endif\n");
+ printf("\n#ifndef DK3_SIZEOF_LONG_LONG\n");
+ printf("/**\tDK3 version of SIZEOF_LONG_LONG.\n*/\n");
+ printf("#define DK3_SIZEOF_LONG_LONG %d\n", (int)SIZEOF_LONG_LONG);
+ printf("#endif\n");
+ printf("\n#ifndef DK3_SIZEOF_SHORT\n");
+ printf("/**\tDK3 version of SIZEOF_SHORT.\n*/\n");
+ printf("#define DK3_SIZEOF_SHORT %d\n", (int)SIZEOF_SHORT);
+ printf("#endif\n");
+ printf("\n#ifndef DK3_SIZEOF_SIZE_T\n");
+ printf("/**\tDK3 version of SIZEOF_SIZE_T.\n*/\n");
+ printf("#define DK3_SIZEOF_SIZE_T %d\n", (int)SIZEOF_SIZE_T);
+ printf("#endif\n");
+ printf("\n#ifndef DK3_SIZEOF_WCHAR_T\n");
+ printf("/**\tDK3 version of SIZEOF_WCHAR_T.\n*/\n");
+ printf("#define DK3_SIZEOF_WCHAR_T %d\n", (int)SIZEOF_WCHAR_T);
+ printf("#endif\n");
+ printf("\n#endif\n/* if DK3_ON_WINDOWS */\n");
+ printf("\n#ifndef DK3_WORDS_BIGENDIAN\n");
+#if WORDS_BIGENDIAN
+ printf("/**\tBig-endian.\n*/\n");
+ printf("#define DK3_WORDS_BIGENDIAN 1\n");
+#else
+ printf("/**\tLittle-endian.\n*/\n");
+ printf("#define DK3_WORDS_BIGENDIAN 0\n");
+#endif
+ printf("#endif\n");
+ printf("\n#ifndef DK3_MAX_PATH\n");
+ printf("/**\tMaximum path length.\n*/\n");
+ printf("#define DK3_MAX_PATH %d\n", (MPL + 1));
+ printf("#endif\n");
+ printf("\n#endif\n/* ifndef DK3_CONF_H_INCLUDED */\n\n");
+ exit(0); return 0;
+}
diff --git a/support/dktools/dk3conft.h b/support/dktools/dk3conft.h
new file mode 100644
index 0000000000..bce4984ab8
--- /dev/null
+++ b/support/dktools/dk3conft.h
@@ -0,0 +1,21 @@
+WARNING: HAVE_ACCEPTED_GPL not defined for Windows!
+WARNING: HAVE_BZLIB_H not defined for Windows!
+WARNING: HAVE_DB_H not defined for Windows!
+WARNING: HAVE_FOPEN64 not defined for Windows!
+WARNING: HAVE_GDBM_H not defined for Windows!
+WARNING: HAVE_JPEGLIB_H not defined for Windows!
+WARNING: HAVE_NETPBM_PNM_H not defined for Windows!
+WARNING: HAVE_OPENSSL_MD5_H not defined for Windows!
+WARNING: HAVE_OPENSSL_RAND_H not defined for Windows!
+WARNING: HAVE_OPENSSL_RIPEMD_H not defined for Windows!
+WARNING: HAVE_OPENSSL_SHA_H not defined for Windows!
+WARNING: HAVE_PNG_GET_PIXELS_PER_INCH not defined for Windows!
+WARNING: HAVE_PNG_H not defined for Windows!
+WARNING: HAVE_PNM_H not defined for Windows!
+WARNING: HAVE_SHA224 not defined for Windows!
+WARNING: HAVE_SHA256 not defined for Windows!
+WARNING: HAVE_SHA384 not defined for Windows!
+WARNING: HAVE_SHA512 not defined for Windows!
+WARNING: HAVE_TIFF_H not defined for Windows!
+WARNING: HAVE_WX_WX_H not defined for Windows!
+WARNING: HAVE_ZLIB_H not defined for Windows!
diff --git a/support/dktools/dk3const.h b/support/dktools/dk3const.h
new file mode 100644
index 0000000000..6ac065cd44
--- /dev/null
+++ b/support/dktools/dk3const.h
@@ -0,0 +1,2013 @@
+
+/** @file dk3const.h Constants for the dk3 libraries.
+*/
+
+#ifndef DK3_CONST_H_INCLUDED
+/** Avoid multiple inclusion. */
+#define DK3_CONST_H_INCLUDED 1
+
+#include <dk3conf.h>
+
+/** @defgroup apptypes Application types.
+*/
+/**@{*/
+enum {
+/** Application type: Not (yet) specified.
+
+No application type was specified.
+*/
+DK3_APP_TYPE_UNKNOWN = 0,
+
+/** Application type: Command line application.
+
+Diagnostics go to a log file and to standard error output.
+The log file is deleted by dk3app_close() unless keeping the
+log file is required by the preference /log/file/keep.
+*/
+DK3_APP_TYPE_COMMAND,
+
+/** Application type: GUI application.
+
+Diagnostics go to a log file.
+The log file is deleted by dk3app_close() unless keeping the
+log file is required by the preference /log/file/keep.
+*/
+DK3_APP_TYPE_GUI,
+
+/** Application type: Daemon.
+
+Diagnostics go to a log file.
+The same log file is used again and again, messages
+are appended. The log file is not deleted automatically.
+*/
+DK3_APP_TYPE_DAEMON,
+
+/** Application type: Silent application.
+
+No diagnostic messages are produced.
+*/
+DK3_APP_TYPE_SILENT
+};
+/**@}*/
+
+
+
+/** @defgroup fileenc Encodings for text files.
+ These encodings can be used when writing texts to file.
+ For multi-byte characters we have to decide whether to write
+ MSB first or LSB first.
+*/
+/**@{*/
+enum {
+/** Plain ascii text.
+*/
+DK3_FILE_ENCODING_ASCII = 0,
+
+/** UTF-8 encoding.
+*/
+DK3_FILE_ENCODING_UTF8,
+
+/** UTF-16 encoding, MSB comes first.
+*/
+DK3_FILE_ENCODING_UTF16_MSB_FIRST,
+
+/** UTF-16 encoding, LSB comes first.
+ */
+DK3_FILE_ENCODING_UTF16_LSB_FIRST,
+
+/** 32-bit UNICODE used directly, MSB comes first.
+ */
+DK3_FILE_ENCODING_UNICODE_MSB_FIRST,
+
+/** 32-bit UNICODE used directly, LSB comes first.
+ */
+DK3_FILE_ENCODING_UNICODE_LSB_FIRST
+};
+/**@}*/
+
+
+
+/** @defgroup stringenc Encodings for text.
+ These encoding are used when keeping text in memory.
+*/
+/**@{*/
+enum {
+/** Plain ascii text.
+*/
+DK3_ENCODING_PLAIN = DK3_FILE_ENCODING_ASCII,
+
+/** UTF-8 encoding.
+*/
+DK3_ENCODING_UTF8 = DK3_FILE_ENCODING_UTF8,
+
+/** UTF-16 encoding, MSB comes first.
+*/
+DK3_ENCODING_UTF16 = DK3_FILE_ENCODING_UTF16_MSB_FIRST,
+
+/** 32-bit UNICODE used directly, MSB comes first.
+ */
+DK3_ENCODING_UNICODE = DK3_FILE_ENCODING_UNICODE_MSB_FIRST
+};
+/**@}*/
+
+
+
+
+/** @defgroup filetypes File types
+ These file types are returned in the ft component of the
+ dk3_stat_t type.
+*/
+/**@{*/
+enum {
+
+/** Regular file.
+*/
+DK3_FT_REGULAR = 1,
+
+/** Directory.
+*/
+DK3_FT_DIRECTORY,
+
+/** FIFO.
+*/
+DK3_FT_FIFO,
+
+/** Character special device.
+*/
+DK3_FT_SPECIAL_CHAR,
+
+/** Block special device.
+*/
+DK3_FT_SPECIAL_BLOCK,
+
+/** Socket.
+*/
+DK3_FT_SOCKET,
+
+/* Next there are some exotic file types. */
+
+/** Door.
+*/
+DK3_FT_DOOR,
+
+/** Event port.
+*/
+DK3_FT_EVENT_PORT,
+
+/** Xenix special file.
+*/
+DK3_FT_XENIX_SPECIAL,
+
+/** Xenix semaphore.
+*/
+DK3_FT_XENIX_SEMAPHORE,
+
+/** Xenix shared data.
+*/
+DK3_FT_XENIX_SHARED_DATA,
+
+/** Multiplexed character device.
+ */
+DK3_FT_MUX_CHAR,
+
+/** Multiplexed block device.
+ */
+DK3_FT_MUX_BLOCK,
+
+/** VxFS compressed file.
+ */
+DK3_FT_VXFS_COMPRESSED,
+
+/** Network special file.
+ */
+DK3_FT_NETWORK_SPECIAL,
+
+/** Whiteout (not used for inode).
+ */
+DK3_FT_WHITEOUT,
+
+/** ACL shadow inode.
+ */
+DK3_FT_ACL_SHADOW,
+
+/** Symlink with non-existing target.
+*/
+DK3_FT_BAD_SYMLINK,
+
+/** Maximum found so far. Applications must use int i[DK3_FT_MAX+1]
+ to store information about all the file types.
+ */
+DK3_FT_MAX = DK3_FT_BAD_SYMLINK,
+
+/** Symbolic link (this flag is or-combined with one of the values below).
+*/
+DK3_FT_SYMLINK = 256,
+
+};
+/**@}*/
+
+
+
+/** @defgroup filepermissions File permissions.
+*/
+/**@{*/
+enum {
+/** Read permission for owner.
+*/
+DK3_FPERM_U_READ = 0400,
+
+/** Write permission for owner.
+*/
+DK3_FPERM_U_WRITE = 0200,
+
+/** Execute permission for owner.
+*/
+DK3_FPERM_U_EXEC = 0100,
+
+/** Read permission for group.
+*/
+DK3_FPERM_G_READ = 0040,
+
+/** Write permission for group.
+*/
+DK3_FPERM_G_WRITE = 0020,
+
+/** Execute permission for group.
+*/
+DK3_FPERM_G_EXEC = 0010,
+
+/** Read permission for others.
+*/
+DK3_FPERM_O_READ = 0004,
+
+/** Write permission for others.
+*/
+DK3_FPERM_O_WRITE = 0002,
+
+/** Execute permission for others.
+*/
+DK3_FPERM_O_EXEC = 0001,
+
+/** Set user ID on execution.
+*/
+DK3_FPERM_SUID = 04000,
+
+/** Set group ID on execution.
+*/
+DK3_FPERM_SGID = 02000,
+
+/** VTX: Save swapped text segment even after use.
+*/
+DK3_FPERM_VTX = 01000,
+
+/** Directory create mode: Only for user.
+*/
+DK3_FPERM_CREATE_PRIVATE = 0700,
+
+/** File create mode: Only for user.
+*/
+DK3_FPERM_CREATE_FILE_PRIVATE = 0600,
+
+/** Directory create mode: Full permissions for owner and group.
+*/
+DK3_FPERM_CREATE_GROUP = 0770,
+
+/** File create mode: Full permissions for owner and group.
+*/
+DK3_FPERM_CREATE_FILE_GROUP = 0660
+};
+/**@}*/
+
+
+
+/** @defgroup streamuseflags Flags how to use a stream.
+ A stream can be opened for reading, writing or both.
+*/
+/**@{*/
+enum {
+/** Allowed to read from stream.
+*/
+DK3_STREAM_FLAG_READ = 1,
+
+/** Allowed to write to stream.
+*/
+DK3_STREAM_FLAG_WRITE
+};
+/**@}*/
+
+
+
+/** @defgroup streamapicommands Stream API commands.
+ These commands are used in the dk3stream.c module for
+ communication between the exported functions and the low-level
+ function dealing with the stream destination.
+*/
+/**@{*/
+enum {
+/** Read into input buffer.
+*/
+DK3_STREAM_API_READ = 1,
+
+/** Write output buffer.
+*/
+DK3_STREAM_API_WRITE,
+
+/** Flush output buffer.
+*/
+DK3_STREAM_API_FLUSH,
+
+/** Check whether we have reached the end of data.
+*/
+DK3_STREAM_API_AT_END,
+
+/** Close the low-level data.
+*/
+DK3_STREAM_API_CLOSE,
+
+/** Check whether a zero read result indicates end of data.
+*/
+DK3_STREAM_API_ZERO_IS_END,
+
+/** Check for error.
+*/
+DK3_STREAM_API_ERROR
+};
+/**@}*/
+
+
+
+/** @defgroup loglevels Log levels.
+ These levels are used to describe the importance of log messages.
+ Log messages are written to a log file, command line applications
+ also write to standard error output (stderr).
+ For both log destinations there is a required level, only messages
+ on that level or higher priorized (lower numeric value) are written
+ to that destination.
+*/
+/**@{*/
+enum {
+/** This message priority never occurs. */
+DK3_LL_NONE = 0,
+
+/** Panic message. */
+DK3_LL_PANIC,
+
+/** Fatal error message. */
+DK3_LL_FATAL,
+
+/** Error message. */
+DK3_LL_ERROR,
+
+/** Warning message. */
+DK3_LL_WARNING,
+
+/** Informational message. */
+DK3_LL_INFO,
+
+/** Progress message. */
+DK3_LL_PROGRESS,
+
+/** Debug message. */
+DK3_LL_DEBUG,
+
+/** Message can be ignored. */
+DK3_LL_IGNORE
+};
+/**@}*/
+
+
+
+/** Preferences priorities.
+*/
+enum {
+/** Mask to retrieve scope value.
+*/
+DK3_PREF_SCOPE = 0x0007,
+
+/** Scope: Host.
+*/
+DK3_PREF_SCOPE_HOST = 0x0001,
+
+/** Scope: Application.
+*/
+DK3_PREF_SCOPE_APPLICATION = 0x0002,
+
+/** Scope: User name.
+*/
+DK3_PREF_SCOPE_USER = 0x0004,
+
+/** Mask to retrieve source.
+*/
+DK3_PREF_SOURCE = 0x0018,
+
+/** Source: System configuration settings.
+*/
+DK3_PREF_SOURCE_SYSTEM = 0x0000,
+
+/** Source: Users general configuration settings.
+*/
+DK3_PREF_SOURCE_USER = 0x0008,
+
+/** Source: Command line arguments.
+*/
+DK3_PREF_SOURCE_COMMANDLINE = 0x0010,
+};
+
+
+
+/** @defgroup errorcodes Error codes. */
+/**@{*/
+enum {
+/** No error occured.
+*/
+DK3_ERROR_NONE = 0,
+
+/** System error, see errno.
+*/
+DK3_ERROR_SYSTEM,
+
+/** Aborted by user (cancel button).
+*/
+DK3_ERROR_ABORTED,
+
+/** Mathematical error (division by zero).
+*/
+DK3_ERROR_MATH_DIVZERO,
+
+/** Mathematical error (result out of range).
+*/
+DK3_ERROR_MATH_OVERFLOW,
+
+/** Mathematical error (at least one argument out of range).
+*/
+DK3_ERROR_MATH_OUT_OF_RANGE,
+
+/** Not enough memory.
+*/
+DK3_ERROR_MEMORY,
+
+/** Invalid arguments passed to function.
+*/
+DK3_ERROR_INVALID_ARGS,
+
+/** Incomplete configuration.
+*/
+DK3_ERROR_INCOMPLETE_CONFIGURATION,
+
+/** Stream not opened for writing.
+*/
+DK3_ERROR_NOT_OPENED_FOR_WRITING,
+
+/** Stream not opened for reading.
+*/
+DK3_ERROR_NOT_OPENED_FOR_READING,
+
+/** An error occured during a write operation.
+*/
+DK3_ERROR_DURING_WRITE,
+
+/** An error occured during a read operation.
+*/
+DK3_ERROR_DURING_READ,
+
+/** No supported (library was not available during build time).
+*/
+DK3_ERROR_NOT_SUPPORTED,
+
+/** Entry not found.
+*/
+DK3_ERROR_NOT_FOUND,
+
+/** Conversion of binary data to text failed.
+*/
+DK3_ERROR_CONVERSION_FAILED,
+
+/** Data too large.
+*/
+DK3_ERROR_TOO_LARGE,
+
+/** Data unusable, probably damaged.
+*/
+DK3_ERROR_DATA_DAMAGED,
+
+/** Syntax error in input file.
+*/
+DK3_ERROR_SYNTAX,
+
+/** Network protocol is not supported.
+*/
+DK3_ERROR_PROTOCOL_NOT_SUPPORTED,
+
+/** Network address family is not supported.
+*/
+DK3_ERROR_ADDRESS_FAMILY_NOT_SUPPORTED,
+
+/** Insufficient permissions.
+*/
+DK3_ERROR_INSUFFICIENT_PERMISSIONS,
+
+/** Illegal network protocol family.
+*/
+DK3_ERROR_ILLEGAL_PROTOCOL_FAMILY,
+
+/** Process table overflow.
+*/
+DK3_ERROR_PROCESS_TABLE_OVERFLOW,
+
+/** Limit reached for number of open filedescriptors.
+*/
+DK3_ERROR_TOO_MANY_OPEN_FILES,
+
+/** Error in I/O operation.
+*/
+DK3_ERROR_IO,
+
+/** Signal was received.
+*/
+DK3_ERROR_INTERRUPTED,
+
+/** IP address not found for host.
+*/
+DK3_ERROR_HOST_NOT_FOUND,
+
+/** Local address already in use.
+*/
+DK3_ERROR_ADDR_IN_USE,
+
+/** Out of resources.
+*/
+DK3_ERROR_RESOURCES,
+
+/** Previous connection request in processing.
+*/
+DK3_ERROR_IN_PROGRESS,
+
+/** Connection refused, no-one listening on the port.
+*/
+DK3_ERROR_CONNECTION_REFUSED,
+
+/** Socket is already connected.
+*/
+DK3_ERROR_ALREADY_CONNECTED,
+
+/** Network is unreachable.
+*/
+DK3_ERROR_NETWORK_UNREACHABLE,
+
+/** Operation timed out.
+*/
+DK3_ERROR_TIMEOUT,
+
+/** Failed to retrieve or set socket options.
+*/
+DK3_ERROR_SOCKET_OPTIONS,
+
+/** Failed to bind local address.
+*/
+DK3_ERROR_BIND_FAILED,
+
+/** The socket is already bound to an address.
+*/
+DK3_ERROR_ALREADY_BOUND,
+
+/** Operation would block.
+*/
+DK3_ERROR_WOULD_BLOCK,
+
+/** Connection reset by peer.
+*/
+DK3_ERROR_CONNECTION_RESET,
+
+/** Peer address is required to send over connectionless socket.
+*/
+DK3_ERROR_ADDRESS_REQUIRED,
+
+/** Writing to a pipe no-one is reading.
+*/
+DK3_ERROR_PIPE,
+
+/** End of input found.
+*/
+DK3_ERROR_END_OF_INPUT,
+
+/** Socket not connected.
+*/
+DK3_ERROR_SOCKET_NOT_CONNECTED,
+
+/** Listen operation failed on socket.
+*/
+DK3_ERROR_LISTEN_FAILED,
+
+/** Failed to accept incoming connection request.
+*/
+DK3_ERROR_ACCEPT_FAILED,
+
+/** Connection attempt aborted.
+*/
+DK3_ERROR_CONNECTION_ABORTED,
+
+/** Error in network protocol.
+*/
+DK3_ERROR_NETWORK_PROTOCOL,
+
+/** Message was not sent completely.
+*/
+DK3_ERROR_MESSAGE_NOT_SENT_COMPLETELY,
+
+/** Network subsystem or Winsock not ready.
+*/
+DK3_ERROR_NETWORK_SUBSYSTEM_NOT_READY,
+
+/** The address is not available!
+*/
+DK3_ERROR_ADDRESS_NOT_AVAILABLE,
+
+/** Host (temporarily) unreachable!
+*/
+DK3_ERROR_HOST_UNREACHABLE,
+
+/** Stale NFS file handle.
+*/
+DK3_ERROR_STALE_NFS_FILE_HANDLE,
+
+/** No select function available.
+*/
+DK3_ERROR_NO_SELECT,
+
+/** Iteration failed (no result after maximum number of passes).
+*/
+DK3_ERROR_ITERATION
+};
+/**@}*/
+
+
+
+/** Installation directories.
+ Order must correspond to order of directories in the dk3inst.c module.
+*/
+enum {
+
+/** Installation prefix (/usr/local).
+*/
+DK3_INST_PREFIX = 0,
+
+/** System configuration directory (/usr/local/etc).
+*/
+DK3_INST_SYSCONF = 1,
+
+/** Data root directory (/usr/local/share).
+*/
+DK3_INST_DATAROOT = 2,
+
+/** Local state directory (/usr/local/var).
+*/
+DK3_INST_LOCALSTATE = 3,
+
+/** bin directory (/usr/local/bin).
+*/
+DK3_INST_BIN = 4,
+
+/** sbin directory (/usr/local/sbin).
+*/
+DK3_INST_SBIN = 5,
+
+/** lib directory (/usr/local/lib).
+*/
+DK3_INST_LIB = 6,
+
+/** include directory (/usr/local/include).
+*/
+DK3_INST_INCLUDE = 7,
+
+/** man directory (/usr/local/share/man).
+*/
+DK3_INST_MAN = 8,
+
+/** Installation prefix again (/usr/local).
+*/
+DK3_INST_PREFIX2 = 9,
+
+/** libexec directory (/usr/local/libexec).
+*/
+DK3_INST_LIBEXEC = 10
+};
+
+
+
+/** @defgroup mdtypes Message digest types.
+ Order here must match order in dk3chks -> dk3_checksum_type_names.
+*/
+/**@{*/
+enum {
+/** RSA Security, Inc. MD5 message digest.
+*/
+DK3_MD_TYPE_MD5 = 1,
+
+/** SHA-1 message digest.
+*/
+DK3_MD_TYPE_SHA_1,
+
+/** SHA-224 message digest.
+*/
+DK3_MD_TYPE_SHA_224,
+
+/** SHA-256 message digest.
+*/
+DK3_MD_TYPE_SHA_256,
+
+/** SHA-384 message digest.
+*/
+DK3_MD_TYPE_SHA_384,
+
+/** SHA-512 message digest.
+*/
+DK3_MD_TYPE_SHA_512,
+
+/** RIPEMD-160 message digest.
+*/
+DK3_MD_TYPE_RIPEMD_160,
+
+/** Maximum number for digest type.
+*/
+DK3_MD_TYPE_MAX = DK3_MD_TYPE_RIPEMD_160
+};
+/**@}*/
+
+
+
+/** @defgroup dataencoding Data encoding.
+ Order here must match order in dk3enc -> dk3_data_encoding_names.
+*/
+/**@{*/
+enum {
+/** Hexadecimal encoding.
+*/
+DK3_DATA_ENCODING_HEX = 0,
+
+/** ASCII-85 encoding.
+*/
+DK3_DATA_ENCODING_ASCII85,
+
+/** Reverse ASCII-85 encoding.
+*/
+DK3_DATA_ENCODING_REVERSE_ASCII85,
+
+/** Maximum number for encoding.
+*/
+DK3_DATA_ENCODING_MAX = DK3_DATA_ENCODING_REVERSE_ASCII85
+};
+/**@}*/
+
+
+
+/** Signal handling types.
+ Different signal handling mechanisms are available for different
+ operating systems.
+*/
+enum {
+/** No signal handling available.
+*/
+DK3_SIGNAL_HANDLING_TYPE_NONE = 0,
+
+/** Use signal() function.
+*/
+DK3_SIGNAL_HANDLING_TYPE_SIGNAL,
+
+/** Use sigset() function.
+*/
+DK3_SIGNAL_HANDLING_TYPE_SIGSET,
+
+/** Use sigaction() function.
+*/
+DK3_SIGNAL_HANDLING_TYPE_SIGACTION
+};
+
+
+/** @defgroup rndtypes Random number generator types.
+ Depending on the OS and the installed libraries there are different
+ PRNGs available.
+*/
+/**@{*/
+enum {
+/** PRNG type: OpenSSL.
+*/
+DK3_PRNG_OPENSSL = 1,
+
+/** PRNG type: initstate()/setstate().
+*/
+DK3_PRNG_STATE = 2,
+
+/** PRNG type: nrand48().
+*/
+DK3_PRNG_RAND48 = 4,
+
+/** PRNG type: rand().
+*/
+DK3_PRNG_SIMPLE = 8,
+
+/** Mask to enable all PRNG types.
+*/
+DK3_PRNG_ALL =
+(DK3_PRNG_OPENSSL + DK3_PRNG_STATE + DK3_PRNG_RAND48 + DK3_PRNG_SIMPLE)
+};
+/**@}*/
+
+
+
+/** Application commands.
+*/
+enum {
+/** Show help.
+*/
+DK3_APP_CMD_HELP = 1,
+
+/** Show version.
+*/
+DK3_APP_CMD_VERSION = 2,
+
+/** Show license conditions.
+*/
+DK3_APP_CMD_LICENSE = 4
+};
+
+
+/** @defgroup outputfiltercelltypes Output filter cell types.
+*/
+/**@{*/
+enum {
+/** Output filter cell type: Binary to hex encoding.
+*/
+DK3_OF_CELL_TYPE_HEX = 0,
+
+/** Output filter cell type: Binary to ASCII85 encoding.
+*/
+DK3_OF_CELL_TYPE_A85,
+
+/** Output filter cell type: Run-length compression.
+*/
+DK3_OF_CELL_TYPE_RUN_LENGTH,
+
+/** Output filter cell type: Flate compression.
+*/
+DK3_OF_CELL_TYPE_FLATE
+};
+/**@}*/
+
+
+
+/** Sizes for flate buffers. */
+enum {
+/** Input buffer size for flate compression.
+*/
+DK3_OF_FLATE_IN_BUFFER_SIZE = 1024,
+
+/** Output buffer size for flate compression
+ (in theory 1057 would suffice).
+*/
+DK3_OF_FLATE_OUT_BUFFER_SIZE = 1536
+};
+
+
+
+/** @defgroup databasetypes Database types. */
+/**@{*/
+enum {
+/** Database type: Not yet set.
+*/
+DK3_DB_TYPE_UNKNOWN = -1,
+/** Database type: In-memory database, synchronize on
+ explicit request and on close only.
+*/
+DK3_DB_TYPE_MEMORY = 0,
+
+/** Database type: Berkeley DB.
+*/
+DK3_DB_TYPE_BDB = 1,
+
+/** Database type: NDBM.
+*/
+DK3_DB_TYPE_NDBM = 2
+};
+/**@}*/
+
+
+
+/** Database type for SQL databases. */
+enum {
+/** SQL database type: Not type configured yet.
+*/
+DK3_SQLDB_TYPE_UNKNOWN = -1,
+
+/** SQL database type: Not type configured yet.
+*/
+DK3_SQLDB_TYPE_MYSQL = 0
+};
+
+
+
+/** @defgroup databaseaccess Access types for databases. */
+/**@{*/
+enum {
+/** Database access: Read only.
+*/
+DK3_DB_ACCESS_READ = 1,
+
+/** Database access: Write entries.
+*/
+DK3_DB_ACCESS_WRITE = 2
+};
+/**@}*/
+
+
+
+/** Text and object alignments.
+*/
+enum {
+/** Align: Horizontally and vertically centered.
+*/
+DK3_ALIGN_CENTER = 0,
+
+/** Align: Horizontally centered.
+*/
+DK3_ALIGN_CENTER_HORIZONTAL = 0,
+
+/** Align: Left.
+*/
+DK3_ALIGN_LEFT = 1,
+
+/** Align: Right.
+*/
+DK3_ALIGN_RIGHT = 2,
+
+/** Align: Mask to retrieve horizontal alignment.
+*/
+DK3_ALIGN_HORIZONTAL = 3,
+
+/** Align: Vertically centered.
+*/
+DK3_ALIGN_CENTER_VERTICAL = 0,
+
+/** Align: Top.
+*/
+DK3_ALIGN_TOP = 4,
+
+/** Align: Bottom.
+*/
+DK3_ALIGN_BOTTOM = 8,
+
+/** Align: Mask to retrieve vertical alignment.
+*/
+DK3_ALIGN_VERTICAL = 12
+};
+
+
+
+/** @defgroup retrieveguialignment Retrieve GUI alignment.
+*/
+/**@{*/
+/** Retrieve horizontal alignment from horizontal/vertical combination.
+*/
+#define DK3_ALIGN_GET_HORIZONTAL(x) ((x) & DK3_ALIGN_HORIZONTAL)
+
+/** Retrieve vertical alignment from horizontal/vertical combination.
+*/
+#define DK3_ALIGN_GET_VERTICAL(x) ((x) & DK3_ALIGN_VERTICAL)
+/**@}*/
+
+
+
+/** @defgroup colorspaces Color spaces for bitmaps.
+*/
+/**@{*/
+enum {
+/** Color space: Not defined yet.
+*/
+DK3_COLOR_SPACE_UNKNOWN = 0,
+
+/** Color space: Grey.
+*/
+DK3_COLOR_SPACE_GRAY,
+
+/** Color space: Grey with alpha channel.
+*/
+DK3_COLOR_SPACE_GRAY_ALPHA,
+
+/** Color space: RGB.
+*/
+DK3_COLOR_SPACE_RGB,
+
+/** Color space: RGB with alpha channel.
+*/
+DK3_COLOR_SPACE_RGBA,
+
+/** Color space: CMYK.
+*/
+DK3_COLOR_SPACE_CMYK,
+
+/** Color space: Y Cb Cr
+*/
+DK3_COLOR_SPACE_YCbCr,
+
+/** Color space: Y Cb Cr K (inverted CMYK?)
+*/
+DK3_COLOR_SPACE_YCCK,
+
+/** Color space: Hue, saturation, brightness.
+*/
+DK3_COLOR_SPACE_HSB,
+};
+/**@}*/
+
+
+
+/** @defgroup linecap Line cap styles. */
+/**@{*/
+enum {
+/** Line cap: Butted.
+*/
+DK3_LINECAP_BUTT = 0,
+
+/** Line cap: Rounded.
+*/
+DK3_LINECAP_ROUND,
+
+/** Line cap: Half linewidt added.
+*/
+DK3_LINECAP_SQUARE
+};
+/**@}*/
+
+
+
+/** Line join styles. */
+enum {
+/** Line join: Mitered.
+*/
+DK3_LINEJOIN_MITER = 0,
+
+/** Line join: Rounded corner.
+*/
+DK3_LINEJOIN_ROUND,
+
+/** Line join: Cut corner.
+*/
+DK3_LINEJOIN_BEVEL
+};
+
+
+
+/** @defgroup bifimagetypes BIF image types.
+*/
+/**@{*/
+enum {
+/** Image type: Unknown.
+*/
+DK3_BIF_IMAGE_TYPE_UNKNOWN = -1,
+
+/** Image type: PNG.
+*/
+DK3_BIF_IMAGE_TYPE_PNG = 0,
+
+/** Image type: JPEG.
+*/
+DK3_BIF_IMAGE_TYPE_JPEG = 1,
+
+/** Image type: TIFF.
+*/
+DK3_BIF_IMAGE_TYPE_TIFF = 4
+};
+/**@}*/
+
+
+
+/** @defgroup bifanalysis Analysis types for bitmap images.
+*/
+/**@{*/
+enum {
+/** Bitmap image analysis: Number of bits necessary.
+*/
+DK3_BIF_ANALYSIS_BITS = 1,
+
+/** Bitmap image analysis: Color really used.
+*/
+DK3_BIF_ANALYSIS_COLOR = 2,
+
+/** Bitmap image analysis: Alpha channel really used.
+*/
+DK3_BIF_ANALYSIS_ALPHA = 4,
+
+/** Bitmap image analysis: Complete analysis
+*/
+DK3_BIF_ANALYSIS_ALL = 7,
+
+/** Bitmap image analysis: Analysis to prepare PS output.
+*/
+DK3_BIF_ANALYSIS_FOR_PS = 3,
+};
+/**@}*/
+
+
+
+/** @defgroup dkbmmodes Run modes for dkbm and wxdkbm.
+*/
+/**@{*/
+enum {
+/** Bitmap to PS/PDF conversion: Create standalone image.
+
+ Alpha channel: The image is mixed against a background color
+ defined in the source file or on the command line or mixed against
+ white if there is no background chunk.
+
+ Frames: If the input contains multiple frames only the first
+ frame is used.
+
+ An optional resolution chunk from the source file is used
+ to scale the image, otherwise each pixel is sized to 1 PS/PDF point.
+ No automatic rotation.
+
+ A showpage instruction is written to PS output, not to EPS
+ output.
+*/
+DK3_BMEPS_MODE_IMAGE = 0,
+
+/** Bitmap to PS/PDF conversion: Create object to embed in a document.
+
+ Alpha channel for EPS output: The image is mixed against
+ a background specified in the file or on the command line or against
+ a white background.
+
+ Alpha channel for PDF output: The alpha channel is transferred
+ to the output so the object can be placed over other objects.
+
+ Frames: If the input file contains multiple frames only the first
+ frame is used.
+
+ Each pixel is sized to 1 PS/PDF point. No automatic rotation.
+ Scaling and rotating is up to the application processing
+ the document in which the object is embedded.
+
+ No showpage instruction is written to PS output.
+*/
+DK3_BMEPS_MODE_OBJECT = 1,
+
+/** Bitmap to PS/PDF conversion: Create print job or standalone PDF file.
+
+ Alpha channel: The image is mixed against a background color
+ defined in the source file or on command line or mixed against
+ white if there is no background chunk.
+
+ Frames: If the input contains multiple frames all frames are
+ used, the output contains multiple pages.
+
+ The image is placed in a given area to fill it optimally.
+ Automatic rotation may occur to best fit the area.
+
+ For PS output a showpage instruction is written at the end
+ of each page.
+*/
+DK3_BMEPS_MODE_DOCUMENT = 2,
+
+/** Bitmap to PS/PDF conversion: Create object to embed in a document
+ in a given area.
+
+ Alpha channel for EPS output: The image is mixed against
+ a background specified in the file or on the command line or against
+ a white background.
+
+ Alpha channel for PDF output: The alpha channel is transferred
+ to the output so the object can be placed over other objects.
+
+ Frames: If the input contains multiple frames only the first
+ frame is used.
+
+ The image is placed in a given area with a specified rotation
+ mode. Rotation depends on a DK3_IMAGE_ORIGIN_xxx value,
+ see @ref imageorigin.
+
+ No showpage instruction is written to PS output.
+*/
+DK3_BMEPS_MODE_PLACED_OBJECT = 3
+};
+/**@}*/
+
+
+
+/** @defgroup bmepsdrivers Output drivers for dkbm/wxdkbm.
+*/
+/**@{*/
+enum {
+/** Bitmap to PS/PDF conversion: Output driver to create PS.
+*/
+DK3_BMEPS_DRIVER_PS = 0,
+
+/** Bitmap to PS/PDF conversion: Output driver to create EPS.
+*/
+DK3_BMEPS_DRIVER_EPS,
+
+/** Bitmap to PS/PDF conversion: Output driver to create PDF.
+*/
+DK3_BMEPS_DRIVER_PDF,
+
+/** Bitmap to PS/PDF conversion: Output driver to create a bounding box.
+*/
+DK3_BMEPS_DRIVER_BB,
+
+/** Bitmap to PS/PDF conversion: Output driver for print using wxWidgets.
+*/
+DK3_BMEPS_DRIVER_WXPRINT
+};
+/**@}*/
+
+
+
+/** @defgroup bmepssizehandling Size handling in bmeps.
+*/
+/**@{*/
+enum {
+/** Bmeps size handling: 1 pixel corresponds to 1 PS point.
+*/
+DK3_BMEPS_SIZE_1_1 = 0,
+
+/** Bmeps size handling: Use resolution chunk from input file.
+*/
+DK3_BMEPS_SIZE_CHUNK,
+
+/** Bmeps size handling: DPI size specified.
+*/
+DK3_BMEPS_SIZE_SPECIFIED,
+
+/** Bmeps size handling: Paper size specified.
+*/
+DK3_BMEPS_SIZE_PAPER
+};
+/**@}*/
+
+
+
+/** @defgroup imageorigin Rotation instructions for images.
+ In XFig and transfig images are rotated depending on the
+ position of the first image rectangle point click and
+ the flipped flag.
+*/
+/**@{*/
+enum {
+/** Image placement: First click in left top point, not flipped.
+*/
+DK3_IMAGE_ORIGIN_LEFT_TOP = 0,
+
+/** Image placement: First click in left bottom point, not flipped.
+*/
+DK3_IMAGE_ORIGIN_LEFT_BOTTOM,
+
+/** Image placement: First click in right top point, not flipped.
+*/
+DK3_IMAGE_ORIGIN_RIGHT_TOP,
+
+/** Image placement: First click in right bottom point, not flipped.
+*/
+DK3_IMAGE_ORIGIN_RIGHT_BOTTOM,
+
+/** Image placement: First click in left top point, flipped.
+*/
+DK3_IMAGE_ORIGIN_LEFT_TOP_FLIPPED,
+
+/** Image placement: First click in left bottom point, flipped.
+*/
+DK3_IMAGE_ORIGIN_LEFT_BOTTOM_FLIPPED,
+
+/** Image placement: First click in right top point, flipped.
+*/
+DK3_IMAGE_ORIGIN_RIGHT_TOP_FLIPPED,
+
+/** Image placement: First click in right bottom point, flipped.
+*/
+DK3_IMAGE_ORIGIN_RIGHT_BOTTOM_FLIPPED
+};
+/**@}*/
+
+
+
+/** @defgroup flatepredictors Predictors for flate compression.
+*/
+/**@{*/
+enum {
+/** Compression predictor: None.
+*/
+DK3_COMPRESSION_PREDICTOR_NONE = 0,
+
+/** Compression predictor: TIFF.
+*/
+DK3_COMPRESSION_PREDICTOR_TIFF,
+
+/** Compression predictor: PNG sub (value left).
+*/
+DK3_COMPRESSION_PREDICTOR_PNG_SUB,
+
+/** Compression predictor: PNG up (value above).
+*/
+DK3_COMPRESSION_PREDICTOR_PNG_UP,
+
+/** Compression predictor: PNG average.
+*/
+DK3_COMPRESSION_PREDICTOR_PNG_AVERAGE,
+
+/** Compression predictor: PNG paeth.
+*/
+DK3_COMPRESSION_PREDICTOR_PNG_PAETH
+};
+/**@}*/
+
+
+
+/** Run state.
+*/
+enum {
+/** Run state: No autorun required.
+*/
+DK3_WX_AUTOSTART_NORMAL = 0,
+
+/** Run state: Waiting for autorun start.
+*/
+DK3_WX_AUTOSTART_START,
+
+/** Run state: Running.
+*/
+DK3_WX_AUTOSTART_RUNNING,
+
+/** Run state: Finished, application can exit.
+*/
+DK3_WX_AUTOSTART_FINISHED,
+
+/** Run state: Application allowed to exit and notified about that.
+*/
+DK3_WX_AUTOSTART_WAIT_FOR_EXIT
+};
+
+
+
+/** OpenSSL PRNG seeding.
+*/
+enum {
+/** Number of bytes required to seed OpenSSL PRNG.
+*/
+DK3_SEED_OPENSSL_BYTES = 1024
+};
+
+
+
+/** Paper size configuration file.
+*/
+enum {
+/** Configuration line size for paper formats.
+*/
+DK3_PAPER_CONFIG_LINE_SIZE = 256
+};
+
+
+
+/** @defgroup pdfxobjecttype XObject types for PDF creation.
+*/
+/**@{*/
+enum {
+/** XObject represents an image.
+*/
+DK3_PDF_XO_TYPE_IMAGE = 1,
+
+/** XObject represents an alpha mask.
+*/
+DK3_PDF_XO_TYPE_ALPHA
+};
+/**@}*/
+
+
+
+/** @defgroup shutdownvalues Values for socket shutdown.
+*/
+/**@{*/
+enum {
+/** Shutdown socket for read access.
+*/
+DK3_TCPIP_SHUTDOWN_READ = 0,
+
+/** Shutdown socket for write access.
+*/
+DK3_TCPIP_SHUTDOWN_WRITE,
+
+/** Shutdown socket for both read and write access.
+*/
+DK3_TCPIP_SHUTDOWN_RW
+};
+/**@}*/
+
+
+
+#if 0
+/** Socket states.
+*/
+enum {
+/** Socket state: Initialized.
+*/
+DK3_SOCKET_STATE_INITIALIZED = 1
+};
+#endif
+
+
+
+/** SNMP versions.
+*/
+enum {
+/** SNMP version not (yet) known.
+*/
+DK3_SNMP_VERSION_UNKNOWN = 0,
+
+/** SNMP version: 1.
+*/
+DK3_SNMP_VERSION_1,
+
+/** SNMP version: 2c.
+*/
+DK3_SNMP_VERSION_2C,
+
+/** SNMP version: 2p.
+*/
+DK3_SNMP_VERSION_2P,
+
+/** SNMP version: 3.
+*/
+DK3_SNMP_VERSION_3
+};
+
+
+
+/** Font features.
+*/
+enum {
+/** Roman font.
+*/
+DK3_FONT_ROMAN = 0,
+
+/** Sans-serif font.
+*/
+DK3_FONT_SANS_SERIF = 1,
+
+/** Typewriter font.
+*/
+DK3_FONT_TYPEWRITER = 2,
+
+/** Mask to retrieve font category.
+*/
+DK3_FONT_FAMILY = 3,
+
+/** Bold font.
+*/
+DK3_FONT_BOLD = 4,
+
+/** Italic font (in german: kursiv).
+*/
+DK3_FONT_ITALIC = 8,
+
+/** Oblique font (in german: schraeggestellt).
+*/
+DK3_FONT_OBLIQUE = 16,
+
+/** Mask value to check if text is either bold or oblique.
+*/
+DK3_FONT_ITOB = 24
+};
+
+
+
+/** PS fonts.
+ We use the same font order as the Fig file standard.
+*/
+enum {
+/** PS font: Default font (Times Roman).
+*/
+DK3_FONT_PS_DEFAULT = -1,
+
+/** PS font: Times Roman.
+*/
+DK3_FONT_PS_TIMES_ROMAN = 0,
+
+/** PS font: Times Roman Italic.
+*/
+DK3_FONT_PS_TIMES_ITALIC,
+
+/** PS font: Times Roman Bold.
+*/
+DK3_FONT_PS_TIMES_BOLD,
+
+/** PS font: Times Roman Bold Italic.
+*/
+DK3_FONT_PS_TIMES_BOLD_ITALIC,
+
+/** PS font: Avantgarde Book.
+*/
+DK3_FONT_PS_AVANTGARDE_BOOK,
+
+/** PS font: Avantgarde Book Oblique.
+*/
+DK3_FONT_PS_AVANTGARDE_BOOK_OBLIQUE,
+
+/** PS font: Avantgarde Demi.
+*/
+DK3_FONT_PS_AVANTGARDE_DEMI,
+
+/** PS font: Avantgarde Demi Oblique.
+*/
+DK3_FONT_PS_AVANTGARDE_DEMI_OBLIQUE,
+
+/** PS font: Bookman Light.
+*/
+DK3_FONT_PS_BOOKMAN_LIGHT,
+
+/** PS font: Bookman Light Italic.
+*/
+DK3_FONT_PS_BOOKMAN_LIGHT_ITALIC,
+
+/** PS font: Bookman Demi.
+*/
+DK3_FONT_PS_BOOKMAN_DEMI,
+
+/** PS font: Bookman Demi Italic.
+*/
+DK3_FONT_PS_BOOKMAN_DEMI_ITALIC,
+
+/** PS font: Courier.
+*/
+DK3_FONT_PS_COURIER,
+
+/** PS font: Courier Oblique.
+*/
+DK3_FONT_PS_COURIER_OBLIQUE,
+
+/** PS font: Courier Bold.
+*/
+DK3_FONT_PS_COURIER_BOLD,
+
+/** PS font: Courier Bold Oblique.
+*/
+DK3_FONT_PS_COURIER_BOLD_OBLIQUE,
+
+/** PS font: Helvetica.
+*/
+DK3_FONT_PS_HELVETICA,
+
+/** PS font: Helvetica Oblique.
+*/
+DK3_FONT_PS_HELVETICA_OBLIQUE,
+
+/** PS font: Helvetica Bold.
+*/
+DK3_FONT_PS_HELVETICA_BOLD,
+
+/** PS font: Helvetica Bold Oblique.
+*/
+DK3_FONT_PS_HELVETICA_BOLD_OBLIQUE,
+
+/** PS font: Helvetica Narrow.
+*/
+DK3_FONT_PS_HELVETICA_NARROW,
+
+/** PS font: Helvetica Narrow Oblique.
+*/
+DK3_FONT_PS_HELVETICA_NARROW_OBLIQUE,
+
+/** PS font: Helvetica Narrow Bold.
+*/
+DK3_FONT_PS_HELVETICA_NARROW_BOLD,
+
+/** PS font: Helvetica Narrow Bold Oblique.
+*/
+DK3_FONT_PS_HELVETICA_NARROW_BOLD_OBLIQUE,
+
+/** PS font: New Century Schoolbook Roman.
+*/
+DK3_FONT_PS_NEW_CENTURY_SCHOOLBOOK_ROMAN,
+
+/** PS font: New Century Schoolbook Italic.
+*/
+DK3_FONT_PS_NEW_CENTURY_SCHOOLBOOK_ITALIC,
+
+/** PS font: New Century Schoolbook Bold.
+*/
+DK3_FONT_PS_NEW_CENTURY_SCHOOLBOOK_BOLD,
+
+/** PS font: New Century Schoolbook Bold Italic.
+*/
+DK3_FONT_PS_NEW_CENTURY_SCHOOLBOOK_BOLD_ITALIC,
+
+/** PS font: Palatino Roman.
+*/
+DK3_FONT_PS_PALATINO_ROMAN,
+
+/** PS font: Palatino Roman Italic.
+*/
+DK3_FONT_PS_PALATINO_ITALIC,
+
+/** PS font: Palatino Roman Bold.
+*/
+DK3_FONT_PS_PALATINO_BOLD,
+
+/** PS font: Palatino Roman Bold Italic.
+*/
+DK3_FONT_PS_PALATINO_BOLD_ITALIC,
+
+/** PS font: Symbol.
+*/
+DK3_FONT_PS_SYMBOL,
+
+/** PS font: Zapf Chancery.
+*/
+DK3_FONT_PS_ZAPF_CHANCERY_MEDIUM_ITALIC,
+
+/** PS font: Zapf Dingbats.
+*/
+DK3_FONT_PS_ZAPF_DINGBATS
+};
+
+
+
+/** @defgroup printertypes Printer types.
+*/
+/**@{*/
+enum {
+/** Printer type: Unspecified/unknown.
+*/
+DK3_PRINTER_TYPE_NONE = 0,
+
+/** Printer type: Windows system printer.
+*/
+DK3_PRINTER_TYPE_WINDOWS,
+
+/** Printer type: Raw socket.
+*/
+DK3_PRINTER_TYPE_SOCKET,
+
+/** Printer type: LPD.
+*/
+DK3_PRINTER_TYPE_LPD,
+
+/** Printer type: LPRng.
+*/
+DK3_PRINTER_TYPE_LPRNG
+};
+/**@}*/
+
+
+
+/* Not an enum:
+ The dkChar data type has different size, can be 8, 16 or
+ 32 bit long. So our constants can not be type int, and thus
+ not enum.
+*/
+/** @defgroup characters Characters. */
+/**@{*/
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+/* +++ 32 bit +++ */
+/** String finalizer.
+*/
+#define DK3_CHAR_0 0UL
+
+/** Byte order marker (BOM)
+*/
+#define DK3_CHAR_BOM 0x0000FEFFUL
+
+/** Backslash.
+*/
+#define DK3_CHAR_BS 0x0000005CUL
+
+/** Slash.
+*/
+#define DK3_CHAR_SLASH 0x0000002FUL
+
+/** Minus.
+*/
+#define DK3_CHAR_MINUS 0x0000002DUL
+
+#if DK3_HAVE_BACKSLASH
+/** File name separator.
+*/
+#define DK3_CHAR_SEP 0x0000005CUL
+/** Not a file name separator.
+*/
+#define DK3_CHAR_NOSEP 0x0000002FUL
+#else
+/** File name separator.
+*/
+#define DK3_CHAR_SEP 0x0000002FUL
+/** Not a file name separator.
+*/
+#define DK3_CHAR_NOSEP 0x0000005CUL
+#endif
+/** Newline.
+*/
+#define DK3_CHAR_NL 0x0000000AUL
+/** Dot.
+*/
+#define DK3_CHAR_DOT 0x0000002EUL
+/* --- 32 bit --- */
+#else
+/* +++ 16 bit +++ */
+/** String finalizer.
+*/
+#define DK3_CHAR_0 0U
+
+/** Byte order marker (BOM).
+*/
+#define DK3_CHAR_BOM 0xFEFFU
+
+/** Backslash.
+*/
+#define DK3_CHAR_BS 0x005CU
+
+/** Slash.
+*/
+#define DK3_CHAR_SLASH 0x002FU
+
+/** Minus.
+*/
+#define DK3_CHAR_MINUS 0x002DU
+
+#if DK3_HAVE_BACKSLASH
+/** File name separator.
+*/
+#define DK3_CHAR_SEP 0x005CU
+/** Not a file name separator.
+*/
+#define DK3_CHAR_NOSEP 0x002FU
+#else
+/** File name separator.
+*/
+#define DK3_CHAR_SEP 0x002FU
+/** Not a file name separator.
+*/
+#define DK3_CHAR_NOSEP 0x005CU
+#endif
+/** Newline.
+*/
+#define DK3_CHAR_NL 0x000AU
+/** Dot.
+*/
+#define DK3_CHAR_DOT 0x002EU
+/* --- 16 bit --- */
+#endif
+#else
+/* +++ 8 bit +++ */
+/** String finalizer.
+*/
+#define DK3_CHAR_0 '\0'
+
+/** Backslash.
+*/
+#define DK3_CHAR_BS '\\'
+
+/** Slash.
+*/
+#define DK3_CHAR_SLASH '/'
+
+/** Minus
+*/
+#define DK3_CHAR_MINUS '-'
+
+#if DK3_HAVE_BACKSLASH
+/** File name separator.
+*/
+#define DK3_CHAR_SEP '\\'
+/** Not a file name separator.
+*/
+#define DK3_CHAR_NOSEP '/'
+#else
+/** File name separator.
+*/
+#define DK3_CHAR_SEP '/'
+/** Not a file name separator.
+*/
+#define DK3_CHAR_NOSEP '\\'
+#endif
+/** Newline.
+*/
+#define DK3_CHAR_NL '\n'
+/** Dot.
+*/
+#define DK3_CHAR_DOT '.'
+/* --- 8 bit --- */
+#endif
+
+/**@}*/
+
+
+
+#ifndef DK3_MAX_PATH
+#if DK3_ON_WINDOWS
+#ifdef _MAX_PATH
+#define DK3_MAX_PATH _MAX_PATH
+#else
+/** Maximum file name (path) length.
+*/
+#define DK3_MAX_PATH 1024
+#endif
+#else
+#ifdef MAX_PATH_LEN
+/** Maximum file name (path) length.
+*/
+#define DK3_MAX_PATH MAX_PATH_LEN
+#else
+/** Maximum file name (path) length.
+*/
+#define DK3_MAX_PATH 1024
+#endif
+#endif
+#endif
+
+
+
+/* Not an enum:
+ As we might have multiple dk3_stat_t in use at same time
+ we used the smallest possible data type -- unsigned char -- for
+ this information.
+*/
+/** @defgroup statadditional Additional information from stat
+The dk3sf_stat() function internally uses both stat() and lstat() to
+retrieve information.
+*/
+/**@{*/
+/** The link owner is not the same user as the link targets owner.
+*/
+#define DK3_STAT_AI_USER_DIFFERS 0x01
+
+/** The link owner group is not the same as the link targets owner group.
+*/
+#define DK3_STAT_AI_GROUP_DIFFERS 0x02
+
+/** Link and link target are on different file systems.
+*/
+#define DK3_STAT_AI_FAR_LINK 0x04
+/**@}*/
+
+
+
+/* Not an enum:
+ As we might have multiple outut streams in use at same
+ time we used the smallest possible data type.
+*/
+/** @defgroup outputfiltertypes Output filter flags.
+*/
+/**@{*/
+/** Flag: Use cr/nl sequence.
+*/
+#define DK3_OF_FLAG_CRNL 0x01
+
+/** Flag: Add finalizer to end of output.
+*/
+#define DK3_OF_FLAG_FINALIZE 0x02
+/**@}*/
+
+
+
+/* Not an enum:
+ As there are a lot of probable error conditions we
+ use an unsigned long here for the bits.
+*/
+/** @defgroup snmpprintererrors SNMP reported printer errors.
+ Note: The unsigned long value is filled beginning from the LSB
+ when reading the SNMP response beginning from the MSB of the
+ first byte.
+*/
+/**@{*/
+
+/** Printer error condition: Paper low.
+*/
+#define DK3_SNMP_PRINTER_ERROR_LOW_PAPER 0x00000001UL
+
+/** Printer error condition: No paper available.
+*/
+#define DK3_SNMP_PRINTER_ERROR_NO_PAPER 0x00000002UL
+
+/** Printer error condition: Toner low.
+*/
+#define DK3_SNMP_PRINTER_ERROR_LOW_TONER 0x00000004UL
+
+/** Printer error condition: Toner empty.
+*/
+#define DK3_SNMP_PRINTER_ERROR_NO_TONER 0x00000008UL
+
+/** Printer error condition: Door is open
+*/
+#define DK3_SNMP_PRINTER_ERROR_DOOR_OPEN 0x00000010UL
+
+/** Printer error condition: Paper jam.
+*/
+#define DK3_SNMP_PRINTER_ERROR_JAMMED 0x00000020UL
+
+/** Printer error condition: Printer offline for whatever reason.
+*/
+#define DK3_SNMP_PRINTER_ERROR_OFFLINE 0x00000040UL
+
+/** Printer error condition: Service needed.
+*/
+#define DK3_SNMP_PRINTER_ERROR_SERVICE_NEEDED 0x00000080UL
+
+/** Printer error condition: Input tray is missing.
+*/
+#define DK3_SNMP_PRINTER_ERROR_INPUT_TRAY 0x00000100UL
+
+/** Printer error condition: Output tray is missing.
+*/
+#define DK3_SNMP_PRINTER_ERROR_OUTPUT_TRAY 0x00000200UL
+
+/** Printer error condition: Marker supply is missing.
+*/
+#define DK3_SNMP_PRINTER_ERROR_MARKER_SUPPLY 0x00000400UL
+
+/** Printer error condition: Output tray nearly full.
+*/
+#define DK3_SNMP_PRINTER_ERROR_OUTPUT_NEAR 0x00000800UL
+
+/** Printer error condition: Output tray full.
+*/
+#define DK3_SNMP_PRINTER_ERROR_OUTPUT_FULL 0x00001000UL
+
+/** Printer error condition: Input tray is empty.
+*/
+#define DK3_SNMP_PRINTER_ERROR_INPUT_EMPTY 0x00002000UL
+
+/** Printer error condition: Overdue preventive maintenance.
+*/
+#define DK3_SNMP_PRINTER_ERROR_MAINTENANCE 0x00004000UL
+/**@}*/
+
+
+
+/* Not an enum:
+ As the font encoding information is stored for each
+ Unicode to LaTeX character conversion we used the smallest
+ possible data type.
+*/
+/** @defgroup fontenc LaTeX font encodings.
+*/
+/**@{*/
+
+/** No specific requirements.
+*/
+#define DK3_FONT_ENCODING_NONE ((dk3_font_encoding_t)0x00)
+
+/** OT1 required.
+*/
+#define DK3_FONT_ENCODING_OT1 ((dk3_font_encoding_t)0x01)
+
+/** Do not use OT1.
+*/
+#define DK3_FONT_ENCODING_NOT_OT1 ((dk3_font_encoding_t)0x02)
+
+/** T1 required.
+*/
+#define DK3_FONT_ENCODING_T1 ((dk3_font_encoding_t)0x04)
+
+/** Do not use T1.
+*/
+#define DK3_FONT_ENCODING_NOT_T1 ((dk3_font_encoding_t)0x08)
+
+/** T4 required.
+*/
+#define DK3_FONT_ENCODING_T4 ((dk3_font_encoding_t)0x10)
+
+/** Do not use T4.
+*/
+#define DK3_FONT_ENCODING_NOT_T4 ((dk3_font_encoding_t)0x20)
+
+/** T5 required.
+*/
+#define DK3_FONT_ENCODING_T5 ((dk3_font_encoding_t)0x40)
+
+/** Do not use T5.
+*/
+#define DK3_FONT_ENCODING_NOT_T5 ((dk3_font_encoding_t)0x80)
+/**@}*/
+
+
+/** @defgroup tspres Results from processing one character or line.
+*/
+/**@{*/
+enum {
+ /** Text processed successfully.
+ */
+ DK3_TSP_RES_OK = 0,
+
+ /** There was an error, but we should attempt
+ to continue.
+ */
+ DK3_TSP_RES_ERROR ,
+
+ /** There was a fatal error, stop processing.
+ */
+ DK3_TSP_RES_FATAL
+};
+/**@}*/
+
+
+
+
+#endif
+
diff --git a/support/dktools/dk3cores.c b/support/dktools/dk3cores.c
new file mode 100644
index 0000000000..2a393830a6
--- /dev/null
+++ b/support/dktools/dk3cores.c
@@ -0,0 +1,460 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3cores.ctr
+*/
+
+/** @file dk3cores.c The dk3cores module.
+*/
+
+
+#line 67 "dk3cores.ctr"
+
+#ifndef _WIN32_WINNT
+/** On Windows use minimum Windows version required for functions
+ in this module.
+*/
+#define _WIN32_WINNT 0x0501
+#endif
+
+#include "dk3all.h"
+#if MACOS || DK3_HAVE_SYS_SYSCTL_H
+#include <sys/sysctl.h>
+#endif
+#include "dk3cores.h"
+
+
+
+
+
+#line 84 "dk3cores.ctr"
+
+
+
+#if DK3_ON_WINDOWS
+typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
+typedef void (WINAPI *LPFN_GETSYSTEMINFO) (LPSYSTEM_INFO);
+#endif
+
+
+
+int
+dk3cores_is_wow64(void)
+{
+ int back = 0;
+#if DK3_ON_WINDOWS
+ LPFN_ISWOW64PROCESS fnIsWow64Process; /* Function address */
+ BOOL bIsWow64 = FALSE; /* Flag: Is Wow64 process. */
+
+#if DK3_CHAR_SIZE > 1
+ fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(
+ GetModuleHandleW( L"kernel32" ), "IsWow64Process"
+ );
+#else
+ fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(
+ GetModuleHandleA("kernel32"), "IsWow64Process"
+ );
+#endif
+ if(NULL != fnIsWow64Process) {
+ if(fnIsWow64Process(GetCurrentProcess(), &bIsWow64)) {
+ if(bIsWow64) { back = 1; }
+ }
+ }
+#endif
+ return back;
+}
+
+
+
+#if !DK3_ON_WINDOWS
+/** Compare two unsigned long numbers.
+ @param l Pointer to left number.
+ @param r Pointer to right number.
+ @param cr Comparison criteria, ignored.
+ @return Comparison result.
+*/
+static
+int
+dk3cores_compare_lu(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ unsigned long const *ull;
+ unsigned long const *ulr;
+ if(l) {
+ if(r) {
+ ull = (unsigned long const *)l;
+ ulr = (unsigned long const *)r;
+ if((*ull) > (*ulr)) {
+ back = 1;
+ } else {
+ if((*ull) < (*ulr)) {
+ back = -1;
+ }
+ }
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ }
+ return back;
+}
+
+/** Retrieve number of cores from /proc/cpuinfo.
+ @param src Pointer to information source indicator variable.
+ @return Number of cores found, 1 for default.
+*/
+static
+size_t
+dk3cores_from_proc_cpuinfo(int *src)
+{
+ char line[1024]; /* Input text line buffer. */
+ FILE *fipo = NULL; /* Input file. */
+ char *pc = NULL; /* Current word pointer. */
+ char *pn = NULL; /* Next text pointer. */
+ dk3_sto_t *scores = NULL; /* Storage for found core numbers. */
+ dk3_sto_it_t *icores = NULL; /* Iterator through core numbers storage. */
+ unsigned long *ulp = NULL; /* New unsigned long memory. */
+ unsigned long ul = 0UL; /* Result variable for sscanf(). */
+ unsigned long maxul = 0UL; /* Maximum core ID found so far. */
+ int memerr = 0; /* Flag: Memory allocation error occured. */
+ size_t back = 0;
+
+
+#line 174 "dk3cores.ctr"
+ scores = dk3sto_open_app(NULL);
+ if(scores) {
+ dk3sto_set_comp(scores, dk3cores_compare_lu, 0);
+ icores = dk3sto_it_open(scores);
+ if(icores) {
+ fipo = fopen("/proc/cpuinfo", "r");
+ if(fipo) {
+ while(fgets(line, sizeof(line), fipo)) {
+ pc = dk3str_c8_start(line, NULL);
+ if(pc) {
+ dk3str_c8_delnl(line);
+
+#line 185 "dk3cores.ctr"
+ pn = dk3str_c8_next(pc, NULL);
+ if(0 == strcmp(pc, "core")) {
+ pc = pn;
+ if(pc) {
+ pn = dk3str_c8_next(pc, NULL);
+ if(0 == strcmp(pc, "id")) {
+ pc = pn;
+ if(pc) {
+ if(':' == *pc) {
+ pc++;
+#if VERSION_BEFORE_20140716
+ if(1 == sscanf(pc, "%lu", &ul))
+#else
+ if(0 != dk3ma_ul_from_c8_string(&ul, pc, NULL))
+#endif
+ {
+
+#line 201 "dk3cores.ctr"
+ if(ul > maxul) { maxul = ul; }
+ if (NULL != src) { *src = DK3_CORES_SRC_CPUINFO; }
+ ulp = (unsigned long *)dk3sto_it_find_like(
+ icores, (void *)(&ul), 0
+ );
+ if(NULL == ulp) {
+ ulp = dk3_new(unsigned long,1);
+ if(ulp) {
+ if(!dk3sto_add(scores, (void *)ulp)) {
+ memerr = 1;
+ }
+ } else {
+ memerr = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ fclose(fipo);
+ } else {
+
+#line 226 "dk3cores.ctr"
+ }
+ dk3sto_it_reset(icores);
+ while(NULL != (ulp = (unsigned long *)dk3sto_it_next(icores))) {
+ back++;
+
+#line 230 "dk3cores.ctr"
+ dk3_delete(ulp);
+ }
+ dk3sto_it_close(icores);
+ } else {
+
+#line 234 "dk3cores.ctr"
+ memerr = 1;
+ }
+ dk3sto_close(scores);
+ } else {
+
+#line 238 "dk3cores.ctr"
+ memerr = 1;
+ }
+ if(memerr) {
+
+#line 241 "dk3cores.ctr"
+ if(back < (size_t)(maxul + 1UL)) {
+
+#line 242 "dk3cores.ctr"
+ back = (size_t)(maxul + 1UL);
+ }
+ }
+ if(back < 1) {
+
+#line 246 "dk3cores.ctr"
+ back = 1;
+ }
+
+#line 248 "dk3cores.ctr"
+ return back;
+}
+#endif
+
+
+
+size_t
+dk3cores_get_num(int *src)
+{
+ size_t back = 1;
+ int found = DK3_CORES_SRC_NONE;
+
+#if DK3_ON_WINDOWS
+ SYSTEM_INFO si; /* System information structure. */
+ LPFN_GETSYSTEMINFO fngetsysteminfo; /* Function address. */
+ char *ptr; /* Environment variable text. */
+ unsigned u; /* Core number from environment. */
+#elif MACOS || (DK3_HAVE_SYSCTL && defined(CTL_HW) && defined(HW_AVAILCPU) && defined(HW_NCPU))
+ uint32_t count = 0; /* Number of cores found. */
+ size_t len = 0; /* Argument length for sysctl(). */
+ int mib[4]; /* Mib for sysctl(). */
+ int scres = 0; /* Result from sysctl(). */
+#endif
+
+
+#line 272 "dk3cores.ctr"
+#if DK3_ON_WINDOWS
+ if(dk3cores_is_wow64()) {
+
+#line 274 "dk3cores.ctr"
+#if DK3_CHAR_SIZE > 1
+ fngetsysteminfo = (LPFN_GETSYSTEMINFO)GetProcAddress(
+ GetModuleHandleW( L"kernel32" ), "GetNativeSystemInfo"
+ );
+#else
+ fngetsysteminfo = (LPFN_GETSYSTEMINFO)GetProcAddress(
+ GetModuleHandleA("kernel32"), "GetNativeSystemInfo"
+ );
+#endif
+ if(NULL != fngetsysteminfo) {
+
+#line 284 "dk3cores.ctr"
+ fngetsysteminfo(&si);
+ found = DK3_CORES_SRC_SYSTEM;
+ back = (size_t)(si.dwNumberOfProcessors);
+ } else {
+
+#line 288 "dk3cores.ctr"
+#if DK3_CHAR_SIZE > 1
+ fngetsysteminfo = (LPFN_GETSYSTEMINFO)GetProcAddress(
+ GetModuleHandleW( L"kernel32" ), "GetSystemInfo"
+ );
+#else
+ fngetsysteminfo = (LPFN_GETSYSTEMINFO)GetProcAddress(
+ GetModuleHandleA("kernel32"), "GetSystemInfo"
+ );
+#endif
+ if(NULL != fngetsysteminfo) {
+
+#line 298 "dk3cores.ctr"
+ fngetsysteminfo(&si);
+ found = DK3_CORES_SRC_SYSTEM;
+ back = (size_t)(si.dwNumberOfProcessors);
+ } else {
+
+#line 302 "dk3cores.ctr"
+ }
+ }
+ } else {
+
+#line 305 "dk3cores.ctr"
+#if DK3_CHAR_SIZE > 1
+ fngetsysteminfo = (LPFN_GETSYSTEMINFO)GetProcAddress(
+ GetModuleHandleW( L"kernel32" ), "GetSystemInfo"
+ );
+#else
+ fngetsysteminfo = (LPFN_GETSYSTEMINFO)GetProcAddress(
+ GetModuleHandleA("kernel32"), "GetSystemInfo"
+ );
+#endif
+ if(NULL != fngetsysteminfo) {
+
+#line 315 "dk3cores.ctr"
+ fngetsysteminfo(&si);
+ found = DK3_CORES_SRC_SYSTEM;
+ back = (size_t)(si.dwNumberOfProcessors);
+ } else {
+
+#line 319 "dk3cores.ctr"
+ }
+ }
+ if((DK3_CORES_SRC_NONE == found) || (back < 1)) {
+
+#line 322 "dk3cores.ctr"
+ ptr = getenv("NUMBER_OF_PROCESSORS");
+ if(ptr) {
+
+#line 324 "dk3cores.ctr"
+#if VERSION_BEFORE_20140716
+ if(1 == sscanf(ptr, "%u", &u))
+#else
+ if (0 != dk3ma_ui_from_c8_string(&u, ptr, NULL))
+#endif
+ {
+
+#line 330 "dk3cores.ctr"
+ back = (size_t)u;
+ found = DK3_CORES_SRC_ENVIRONMENT;
+ } else {
+
+#line 333 "dk3cores.ctr"
+ }
+ } else {
+
+#line 335 "dk3cores.ctr"
+ }
+ }
+#elif DK3_HAVE_SYSCONF && defined(_SC_NPROCESSORS_ONLN)
+
+
+#line 339 "dk3cores.ctr"
+ back = (size_t)sysconf(_SC_NPROCESSORS_ONLN);
+ found = DK3_CORES_SRC_SYSTEM;
+#elif DK3_HAVE_SYSCONF && defined(_SC_NPROC_ONLN)
+
+
+#line 343 "dk3cores.ctr"
+ back = (size_t)sysconf(_SC_NPROC_ONLN);
+ found = DK3_CORES_SRC_SYSTEM;
+#elif DK3_HAVE_MPCTL && defined(MPC_GETNUMSPUS)
+
+
+#line 347 "dk3cores.ctr"
+ back = (size_t)mpctl(MPC_GETNUMSPUS, NULL, NULL);
+ found = DK3_CORES_SRC_SYSTEM;
+#elif DK3_HAVE_MPCTL && defined(MPC_GETNUMCPUS)
+
+
+#line 351 "dk3cores.ctr"
+ back = (size_t)mpctl(MPC_GETNUMCPUS, NULL, NULL);
+ found = DK3_CORES_SRC_SYSTEM;
+#elif MACOS || (DK3_HAVE_SYSCTL && defined(CTL_HW) && defined(HW_AVAILCPU) && defined(HW_NCPU))
+
+
+#line 355 "dk3cores.ctr"
+ mib[0] = CTL_HW; mib[1] = HW_AVAILCPU; len = sizeof(count);
+ scres = sysctl(mib, 2, &count, &len, NULL, 0);
+ if((0 != scres) || (count < 1)) {
+
+#line 358 "dk3cores.ctr"
+ mib[0] = CTL_HW; mib[1] = HW_NCPU; len = sizeof(count);
+ scres = sysctl(mib, 2, &count, &len, NULL, 0);
+ if((0 == scres) && (count > 0)) {
+
+#line 361 "dk3cores.ctr"
+ back = (size_t)count;
+ found = DK3_CORES_SRC_SYSTEM;
+ }
+ } else {
+
+#line 365 "dk3cores.ctr"
+ back = (size_t)count;
+ found = DK3_CORES_SRC_SYSTEM;
+ }
+#endif
+#if !DK3_ON_WINDOWS
+ if((DK3_CORES_SRC_NONE == found)) {
+
+#line 371 "dk3cores.ctr"
+ back = dk3cores_from_proc_cpuinfo(&found);
+ }
+#endif
+ if(back < 1) {
+
+#line 375 "dk3cores.ctr"
+ back = 1;
+ }
+ if (NULL != src) { *src = found; }
+
+
+#line 379 "dk3cores.ctr"
+ return back;
+}
+
+
+
+size_t
+dk3cores_max_threads(dk3_app_t *app, int *src)
+{
+ dkChar line[128]; /* Result buffer for preferences .*/
+ unsigned long ul; /* Result variable for sscanf(). */
+ size_t back = 0;
+ size_t cores = 0; /* Number of cores found. */
+ size_t x; /* Result variable for sscanf(). */
+ int found = DK3_CORES_SRC_NONE; /* Information source. */
+
+
+#line 394 "dk3cores.ctr"
+ /*
+ Derive number of threads from number of cores.
+ */
+ cores = back = dk3cores_get_num(&found);
+ if(back > 2) {
+ back = back - 1;
+ }
+ /*
+ Check /threads/max preference, attempt to use it.
+ */
+ if(app) {
+ if(dk3app_get_pref(app,dkT("/threads/max"),line,DK3_SIZEOF(line,dkChar))) {
+#if VERSION_BEFORE_20140716
+ if(1 == dk3sf_sscanf3(line, dkT("%lu"), &ul))
+#else
+ if (0 != dk3ma_ul_from_string(&ul, line, NULL))
+#endif
+ {
+ x = (size_t)ul;
+ if(x > back) {
+ dk3app_log_i1(app, DK3_LL_DEBUG, 365);
+ }
+ found = DK3_CORES_SRC_PREFERENCE;
+ back = x;
+ } else {
+ if(0 == dk3str_cmp(dkT("cores"), line)) {
+ back = cores;
+ }
+ }
+ }
+ }
+ /*
+ Apply corrections if no value was found.
+ */
+ if(back < 1) {
+ back = 1;
+ }
+ if (NULL != src) { *src = found; }
+
+
+#line 433 "dk3cores.ctr"
+ return back;
+}
+
+
diff --git a/support/dktools/dk3cores.ctr b/support/dktools/dk3cores.ctr
new file mode 100644
index 0000000000..64eb9149fa
--- /dev/null
+++ b/support/dktools/dk3cores.ctr
@@ -0,0 +1,436 @@
+%% options
+
+%% header
+
+/** @defgroup coressrc Source for cores information
+*/
+/**@{*/
+
+/** No information found.
+*/
+#define DK3_CORES_SRC_NONE (-1)
+
+/** System call succeeded.
+*/
+#define DK3_CORES_SRC_SYSTEM 0
+
+/** Environment variable NUMBER_OF_PROCESSORS on Windows.
+*/
+#define DK3_CORES_SRC_ENVIRONMENT 1
+
+/** File /proc/cpuinfo on *x systems.
+*/
+#define DK3_CORES_SRC_CPUINFO 2
+
+/** The /threads/max preference.
+*/
+#define DK3_CORES_SRC_PREFERENCE 3
+
+/**@}*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve number of processor cores on system.
+ @param src Pointer to information source indicator variable,
+ may be NULL.
+ @return Number of processor cores found.
+*/
+size_t
+dk3cores_get_num(int *src);
+
+/** Check whether we run on WOW6432.
+ @return 1 for WOW6432, 0 otherwise.
+*/
+int
+dk3cores_is_wow64(void);
+
+/** Get maximum number of threads.
+ The number is retrieved from the /threads/max preference if
+ available, or derived from the number of cores available
+ (back = (n > 2) ? (n - 1) : 1) to leave one core for
+ GUI or desktop session.
+ @param app Application to use for preferences retrieval.
+ @param src Pointer to information source indicator variable,
+ may be NULL.
+ @return Number of threas to use maximally.
+*/
+size_t
+dk3cores_max_threads(dk3_app_t *app, int *src);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#ifndef _WIN32_WINNT
+/** On Windows use minimum Windows version required for functions
+ in this module.
+*/
+#define _WIN32_WINNT 0x0501
+#endif
+
+#include "dk3all.h"
+#if MACOS || DK3_HAVE_SYS_SYSCTL_H
+#include <sys/sysctl.h>
+#endif
+#include "dk3cores.h"
+
+
+
+$!trace-include
+
+
+
+#if DK3_ON_WINDOWS
+typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
+typedef void (WINAPI *LPFN_GETSYSTEMINFO) (LPSYSTEM_INFO);
+#endif
+
+
+
+int
+dk3cores_is_wow64(void)
+{
+ int back = 0;
+#if DK3_ON_WINDOWS
+ LPFN_ISWOW64PROCESS fnIsWow64Process; /* Function address */
+ BOOL bIsWow64 = FALSE; /* Flag: Is Wow64 process. */
+
+#if DK3_CHAR_SIZE > 1
+ fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(
+ GetModuleHandleW( L"kernel32" ), "IsWow64Process"
+ );
+#else
+ fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(
+ GetModuleHandleA("kernel32"), "IsWow64Process"
+ );
+#endif
+ if(NULL != fnIsWow64Process) {
+ if(fnIsWow64Process(GetCurrentProcess(), &bIsWow64)) {
+ if(bIsWow64) { back = 1; }
+ }
+ }
+#endif
+ return back;
+}
+
+
+
+#if !DK3_ON_WINDOWS
+/** Compare two unsigned long numbers.
+ @param l Pointer to left number.
+ @param r Pointer to right number.
+ @param cr Comparison criteria, ignored.
+ @return Comparison result.
+*/
+static
+int
+dk3cores_compare_lu(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ unsigned long const *ull;
+ unsigned long const *ulr;
+ if(l) {
+ if(r) {
+ ull = (unsigned long const *)l;
+ ulr = (unsigned long const *)r;
+ if((*ull) > (*ulr)) {
+ back = 1;
+ } else {
+ if((*ull) < (*ulr)) {
+ back = -1;
+ }
+ }
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ }
+ return back;
+}
+
+/** Retrieve number of cores from /proc/cpuinfo.
+ @param src Pointer to information source indicator variable.
+ @return Number of cores found, 1 for default.
+*/
+static
+size_t
+dk3cores_from_proc_cpuinfo(int *src)
+{
+ char line[1024]; /* Input text line buffer. */
+ FILE *fipo = NULL; /* Input file. */
+ char *pc = NULL; /* Current word pointer. */
+ char *pn = NULL; /* Next text pointer. */
+ dk3_sto_t *scores = NULL; /* Storage for found core numbers. */
+ dk3_sto_it_t *icores = NULL; /* Iterator through core numbers storage. */
+ unsigned long *ulp = NULL; /* New unsigned long memory. */
+ unsigned long ul = 0UL; /* Result variable for sscanf(). */
+ unsigned long maxul = 0UL; /* Maximum core ID found so far. */
+ int memerr = 0; /* Flag: Memory allocation error occured. */
+ size_t back = 0;
+ $? "+ dk3cores_from_proc_cpuinfo"
+ scores = dk3sto_open_app(NULL);
+ if(scores) {
+ dk3sto_set_comp(scores, dk3cores_compare_lu, 0);
+ icores = dk3sto_it_open(scores);
+ if(icores) {
+ fipo = fopen("/proc/cpuinfo", "r");
+ if(fipo) {
+ while(fgets(line, sizeof(line), fipo)) {
+ pc = dk3str_c8_start(line, NULL);
+ if(pc) {
+ dk3str_c8_delnl(line); $? ". process \"%!8s\"", line
+ pn = dk3str_c8_next(pc, NULL);
+ if(0 == strcmp(pc, "core")) {
+ pc = pn;
+ if(pc) {
+ pn = dk3str_c8_next(pc, NULL);
+ if(0 == strcmp(pc, "id")) {
+ pc = pn;
+ if(pc) {
+ if(':' == *pc) {
+ pc++;
+#if VERSION_BEFORE_20140716
+ if(1 == sscanf(pc, "%lu", &ul))
+#else
+ if(0 != dk3ma_ul_from_c8_string(&ul, pc, NULL))
+#endif
+ { $? ". %lu", ul
+ if(ul > maxul) { maxul = ul; }
+ if (NULL != src) { *src = DK3_CORES_SRC_CPUINFO; }
+ ulp = (unsigned long *)dk3sto_it_find_like(
+ icores, (void *)(&ul), 0
+ );
+ if(NULL == ulp) {
+ ulp = dk3_new(unsigned long,1);
+ if(ulp) {
+ if(!dk3sto_add(scores, (void *)ulp)) {
+ memerr = 1;
+ }
+ } else {
+ memerr = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ fclose(fipo);
+ } else { $? "! fopen"
+ }
+ dk3sto_it_reset(icores);
+ while(NULL != (ulp = (unsigned long *)dk3sto_it_next(icores))) {
+ back++; $? ". yet another core"
+ dk3_delete(ulp);
+ }
+ dk3sto_it_close(icores);
+ } else { $? "! icores"
+ memerr = 1;
+ }
+ dk3sto_close(scores);
+ } else { $? "! scores"
+ memerr = 1;
+ }
+ if(memerr) { $? "! memory error"
+ if(back < (size_t)(maxul + 1UL)) { $? "! use maxul"
+ back = (size_t)(maxul + 1UL);
+ }
+ }
+ if(back < 1) { $? "! correction necessary"
+ back = 1;
+ } $? "- dk3cores_from_proc_cpuinfo %lu", (unsigned long)back
+ return back;
+}
+#endif
+
+
+
+size_t
+dk3cores_get_num(int *src)
+{
+ size_t back = 1;
+ int found = DK3_CORES_SRC_NONE;
+
+#if DK3_ON_WINDOWS
+ SYSTEM_INFO si; /* System information structure. */
+ LPFN_GETSYSTEMINFO fngetsysteminfo; /* Function address. */
+ char *ptr; /* Environment variable text. */
+ unsigned u; /* Core number from environment. */
+#elif MACOS || (DK3_HAVE_SYSCTL && defined(CTL_HW) && defined(HW_AVAILCPU) && defined(HW_NCPU))
+ uint32_t count = 0; /* Number of cores found. */
+ size_t len = 0; /* Argument length for sysctl(). */
+ int mib[4]; /* Mib for sysctl(). */
+ int scres = 0; /* Result from sysctl(). */
+#endif
+ $? "+ dk3cores_get_num"
+#if DK3_ON_WINDOWS
+ if(dk3cores_is_wow64()) { $? ". windows wow6432"
+#if DK3_CHAR_SIZE > 1
+ fngetsysteminfo = (LPFN_GETSYSTEMINFO)GetProcAddress(
+ GetModuleHandleW( L"kernel32" ), "GetNativeSystemInfo"
+ );
+#else
+ fngetsysteminfo = (LPFN_GETSYSTEMINFO)GetProcAddress(
+ GetModuleHandleA("kernel32"), "GetNativeSystemInfo"
+ );
+#endif
+ if(NULL != fngetsysteminfo) { $? ". GetNativeSystemInfo"
+ fngetsysteminfo(&si);
+ found = DK3_CORES_SRC_SYSTEM;
+ back = (size_t)(si.dwNumberOfProcessors);
+ } else { $? "! GetNativeSystemInfo"
+#if DK3_CHAR_SIZE > 1
+ fngetsysteminfo = (LPFN_GETSYSTEMINFO)GetProcAddress(
+ GetModuleHandleW( L"kernel32" ), "GetSystemInfo"
+ );
+#else
+ fngetsysteminfo = (LPFN_GETSYSTEMINFO)GetProcAddress(
+ GetModuleHandleA("kernel32"), "GetSystemInfo"
+ );
+#endif
+ if(NULL != fngetsysteminfo) { $? ". GetSystemInfo"
+ fngetsysteminfo(&si);
+ found = DK3_CORES_SRC_SYSTEM;
+ back = (size_t)(si.dwNumberOfProcessors);
+ } else { $? "! GetSystemInfo"
+ }
+ }
+ } else { $? ". windows native"
+#if DK3_CHAR_SIZE > 1
+ fngetsysteminfo = (LPFN_GETSYSTEMINFO)GetProcAddress(
+ GetModuleHandleW( L"kernel32" ), "GetSystemInfo"
+ );
+#else
+ fngetsysteminfo = (LPFN_GETSYSTEMINFO)GetProcAddress(
+ GetModuleHandleA("kernel32"), "GetSystemInfo"
+ );
+#endif
+ if(NULL != fngetsysteminfo) { $? ". GetSystemInfo"
+ fngetsysteminfo(&si);
+ found = DK3_CORES_SRC_SYSTEM;
+ back = (size_t)(si.dwNumberOfProcessors);
+ } else { $? "! GetSystemInfo"
+ }
+ }
+ if((DK3_CORES_SRC_NONE == found) || (back < 1)) { $? ". check environment"
+ ptr = getenv("NUMBER_OF_PROCESSORS");
+ if(ptr) { $? ". found"
+#if VERSION_BEFORE_20140716
+ if(1 == sscanf(ptr, "%u", &u))
+#else
+ if (0 != dk3ma_ui_from_c8_string(&u, ptr, NULL))
+#endif
+ { $? ". number"
+ back = (size_t)u;
+ found = DK3_CORES_SRC_ENVIRONMENT;
+ } else { $? "! not numeric"
+ }
+ } else { $? "! NUMBER_OF_PROCESSORS"
+ }
+ }
+#elif DK3_HAVE_SYSCONF && defined(_SC_NPROCESSORS_ONLN)
+ $? ". sysconf (1)"
+ back = (size_t)sysconf(_SC_NPROCESSORS_ONLN);
+ found = DK3_CORES_SRC_SYSTEM;
+#elif DK3_HAVE_SYSCONF && defined(_SC_NPROC_ONLN)
+ $? ". sysconf (2)"
+ back = (size_t)sysconf(_SC_NPROC_ONLN);
+ found = DK3_CORES_SRC_SYSTEM;
+#elif DK3_HAVE_MPCTL && defined(MPC_GETNUMSPUS)
+ $? ". mpctl (1)"
+ back = (size_t)mpctl(MPC_GETNUMSPUS, NULL, NULL);
+ found = DK3_CORES_SRC_SYSTEM;
+#elif DK3_HAVE_MPCTL && defined(MPC_GETNUMCPUS)
+ $? ". mpctl (2)"
+ back = (size_t)mpctl(MPC_GETNUMCPUS, NULL, NULL);
+ found = DK3_CORES_SRC_SYSTEM;
+#elif MACOS || (DK3_HAVE_SYSCTL && defined(CTL_HW) && defined(HW_AVAILCPU) && defined(HW_NCPU))
+ $? ". sysctl (hope we are on Mac or BSD here)"
+ mib[0] = CTL_HW; mib[1] = HW_AVAILCPU; len = sizeof(count);
+ scres = sysctl(mib, 2, &count, &len, NULL, 0);
+ if((0 != scres) || (count < 1)) { $? "! HW_AVAILCPU"
+ mib[0] = CTL_HW; mib[1] = HW_NCPU; len = sizeof(count);
+ scres = sysctl(mib, 2, &count, &len, NULL, 0);
+ if((0 == scres) && (count > 0)) { $? ". HW_NCPU"
+ back = (size_t)count;
+ found = DK3_CORES_SRC_SYSTEM;
+ }
+ } else { $? ". HW_AVAILCPU"
+ back = (size_t)count;
+ found = DK3_CORES_SRC_SYSTEM;
+ }
+#endif
+#if !DK3_ON_WINDOWS
+ if((DK3_CORES_SRC_NONE == found)) { $? "! no value found"
+ back = dk3cores_from_proc_cpuinfo(&found);
+ }
+#endif
+ if(back < 1) { $? "! correction necessary"
+ back = 1;
+ }
+ if (NULL != src) { *src = found; }
+ $? "- dk3cores_get_num %lu", (unsigned long)back
+ return back;
+}
+
+
+
+size_t
+dk3cores_max_threads(dk3_app_t *app, int *src)
+{
+ dkChar line[128]; /* Result buffer for preferences .*/
+ unsigned long ul; /* Result variable for sscanf(). */
+ size_t back = 0;
+ size_t cores = 0; /* Number of cores found. */
+ size_t x; /* Result variable for sscanf(). */
+ int found = DK3_CORES_SRC_NONE; /* Information source. */
+ $? "+ dk3cores_max_threads"
+ /*
+ Derive number of threads from number of cores.
+ */
+ cores = back = dk3cores_get_num(&found);
+ if(back > 2) {
+ back = back - 1;
+ }
+ /*
+ Check /threads/max preference, attempt to use it.
+ */
+ if(app) {
+ if(dk3app_get_pref(app,dkT("/threads/max"),line,DK3_SIZEOF(line,dkChar))) {
+#if VERSION_BEFORE_20140716
+ if(1 == dk3sf_sscanf3(line, dkT("%lu"), &ul))
+#else
+ if (0 != dk3ma_ul_from_string(&ul, line, NULL))
+#endif
+ {
+ x = (size_t)ul;
+ if(x > back) {
+ dk3app_log_i1(app, DK3_LL_DEBUG, 365);
+ }
+ found = DK3_CORES_SRC_PREFERENCE;
+ back = x;
+ } else {
+ if(0 == dk3str_cmp(dkT("cores"), line)) {
+ back = cores;
+ }
+ }
+ }
+ }
+ /*
+ Apply corrections if no value was found.
+ */
+ if(back < 1) {
+ back = 1;
+ }
+ if (NULL != src) { *src = found; }
+ $? "- dk3cores_max_threads"
+ return back;
+}
+
+
diff --git a/support/dktools/dk3cores.h b/support/dktools/dk3cores.h
new file mode 100644
index 0000000000..36b0db0c7e
--- /dev/null
+++ b/support/dktools/dk3cores.h
@@ -0,0 +1,80 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3cores.ctr
+*/
+
+/** @file dk3cores.h Header file for the dk3cores module.
+*/
+
+#ifndef DK3CORES_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3CORES_H_INCLUDED 1
+
+
+#line 4 "dk3cores.ctr"
+
+/** @defgroup coressrc Source for cores information
+*/
+/**@{*/
+
+/** No information found.
+*/
+#define DK3_CORES_SRC_NONE (-1)
+
+/** System call succeeded.
+*/
+#define DK3_CORES_SRC_SYSTEM 0
+
+/** Environment variable NUMBER_OF_PROCESSORS on Windows.
+*/
+#define DK3_CORES_SRC_ENVIRONMENT 1
+
+/** File /proc/cpuinfo on *x systems.
+*/
+#define DK3_CORES_SRC_CPUINFO 2
+
+/** The /threads/max preference.
+*/
+#define DK3_CORES_SRC_PREFERENCE 3
+
+/**@}*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve number of processor cores on system.
+ @param src Pointer to information source indicator variable,
+ may be NULL.
+ @return Number of processor cores found.
+*/
+size_t
+dk3cores_get_num(int *src);
+
+/** Check whether we run on WOW6432.
+ @return 1 for WOW6432, 0 otherwise.
+*/
+int
+dk3cores_is_wow64(void);
+
+/** Get maximum number of threads.
+ The number is retrieved from the /threads/max preference if
+ available, or derived from the number of cores available
+ (back = (n > 2) ? (n - 1) : 1) to leave one core for
+ GUI or desktop session.
+ @param app Application to use for preferences retrieval.
+ @param src Pointer to information source indicator variable,
+ may be NULL.
+ @return Number of threas to use maximally.
+*/
+size_t
+dk3cores_max_threads(dk3_app_t *app, int *src);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk3ct.c b/support/dktools/dk3ct.c
new file mode 100644
index 0000000000..9ace2a196f
--- /dev/null
+++ b/support/dktools/dk3ct.c
@@ -0,0 +1,108 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3ct.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3ct.c The dk3ct module.
+*/
+
+
+#line 46 "dk3ct.ctr"
+
+#include "dk3all.h"
+
+
+
+
+
+#line 52 "dk3ct.ctr"
+
+
+double
+dk3ct_2d_x(dk3_ct_2d_t const *ct, double x, int *ec)
+{
+ double back = 0.0;
+
+
+#line 59 "dk3ct.ctr"
+ if(ct) {
+ back = dk3ma_d_add_ok(
+ dk3ma_d_mul_ok(ct->mx, x, ec),
+ ct->nx,
+ ec
+ );
+ }
+
+#line 66 "dk3ct.ctr"
+ return back;
+}
+
+
+
+double
+dk3ct_2d_y(dk3_ct_2d_t const *ct, double y, int *ec)
+{
+ double back = 0.0;
+
+
+#line 76 "dk3ct.ctr"
+ if(ct) {
+ back = dk3ma_d_add_ok(
+ dk3ma_d_mul_ok(ct->my, y, ec),
+ ct->ny,
+ ec
+ );
+ }
+
+#line 83 "dk3ct.ctr"
+ return back;
+}
+
+
+
+double
+dk3ct_2d_r(dk3_ct_2d_t const *ct, double r, int *ec)
+{
+ double back = 0.0;
+
+
+#line 93 "dk3ct.ctr"
+ if(ct) {
+ back = dk3ma_d_mul_ok(fabs(ct->mx), r, ec);
+ }
+
+#line 96 "dk3ct.ctr"
+ return back;
+}
+
+
diff --git a/support/dktools/dk3ct.ctr b/support/dktools/dk3ct.ctr
new file mode 100644
index 0000000000..060f8011f0
--- /dev/null
+++ b/support/dktools/dk3ct.ctr
@@ -0,0 +1,99 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Coordinates transformation: X value.
+ @param ct Transformation data.
+ @param x X value.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Transformation result.
+*/
+double
+dk3ct_2d_x(dk3_ct_2d_t const *ct, double x, int *ec);
+
+/** Coordinates transformation: Y value.
+ @param ct Transformation data.
+ @param y X value.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Transformation result.
+*/
+double
+dk3ct_2d_y(dk3_ct_2d_t const *ct, double y, int *ec);
+
+/** Coordinates transformation: Radius.
+ @param ct Transformation data.
+ @param r X value.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Transformation result.
+*/
+double
+dk3ct_2d_r(dk3_ct_2d_t const *ct, double r, int *ec);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk3all.h"
+
+
+
+$!trace-include
+
+
+double
+dk3ct_2d_x(dk3_ct_2d_t const *ct, double x, int *ec)
+{
+ double back = 0.0;
+ $? "+ dk3ct_2d_x %lg", x
+ if(ct) {
+ back = dk3ma_d_add_ok(
+ dk3ma_d_mul_ok(ct->mx, x, ec),
+ ct->nx,
+ ec
+ );
+ } $? "- dk3ct_2d_x %lg", back
+ return back;
+}
+
+
+
+double
+dk3ct_2d_y(dk3_ct_2d_t const *ct, double y, int *ec)
+{
+ double back = 0.0;
+ $? "+ dk3ct_2d_y %lg", y
+ if(ct) {
+ back = dk3ma_d_add_ok(
+ dk3ma_d_mul_ok(ct->my, y, ec),
+ ct->ny,
+ ec
+ );
+ } $? "- dk3ct_2d_y %lg", back
+ return back;
+}
+
+
+
+double
+dk3ct_2d_r(dk3_ct_2d_t const *ct, double r, int *ec)
+{
+ double back = 0.0;
+ $? "+ dk3ct_2d_r %lg", r
+ if(ct) {
+ back = dk3ma_d_mul_ok(fabs(ct->mx), r, ec);
+ } $? "- dk3ct_2d_r %lg", back
+ return back;
+}
+
+
diff --git a/support/dktools/dk3ct.h b/support/dktools/dk3ct.h
new file mode 100644
index 0000000000..a69bba0390
--- /dev/null
+++ b/support/dktools/dk3ct.h
@@ -0,0 +1,82 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3ct.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3ct.h Header file for the dk3ct module.
+*/
+
+#ifndef DK3CT_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3CT_H_INCLUDED 1
+
+
+#line 9 "dk3ct.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Coordinates transformation: X value.
+ @param ct Transformation data.
+ @param x X value.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Transformation result.
+*/
+double
+dk3ct_2d_x(dk3_ct_2d_t const *ct, double x, int *ec);
+
+/** Coordinates transformation: Y value.
+ @param ct Transformation data.
+ @param y X value.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Transformation result.
+*/
+double
+dk3ct_2d_y(dk3_ct_2d_t const *ct, double y, int *ec);
+
+/** Coordinates transformation: Radius.
+ @param ct Transformation data.
+ @param r X value.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Transformation result.
+*/
+double
+dk3ct_2d_r(dk3_ct_2d_t const *ct, double r, int *ec);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk3dbi.c b/support/dktools/dk3dbi.c
new file mode 100644
index 0000000000..bd84766e4f
--- /dev/null
+++ b/support/dktools/dk3dbi.c
@@ -0,0 +1,2738 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3dbi.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3dbi.c The dk3dbi module.
+*/
+
+
+#line 372 "dk3dbi.ctr"
+
+#include "dk3all.h"
+#include "dk3dbi.h"
+
+#ifdef DK3_USE_DB
+#undef DK3_USE_DB
+#endif
+#ifdef DK3_USE_NDBM
+#undef DK3_USE_NDBM
+#endif
+
+#if DK3_HAVE_DB_H
+#include <db.h>
+/** Use Berkeley DB.
+*/
+#define DK3_USE_DB 1
+#endif
+
+#if DK3_HAVE_NDBM_H
+#include <ndbm.h>
+/** Use NDBM.
+*/
+#define DK3_USE_NDBM 1
+#endif
+
+
+
+
+#line 399 "dk3dbi.ctr"
+
+
+
+/** Data type used in storage.
+*/
+typedef struct {
+ /** Key data.
+ */
+ void *keydata;
+ /** value data.
+ */
+ void *valdata;
+ /** Key size (number of bytes in key data).
+ */
+ size_t keysize;
+ /** Value size (number of bytes in value data).
+ */
+ size_t valsize;
+} dk3_dbi_node_t;
+
+
+
+
+/** Names of database types. Order must match the
+ definitions in @ref databasetypes.
+*/
+static dkChar const * const dk3dbi_type_names[] = {
+/* 0 */
+dkT("mem"),
+
+/* 1 */
+dkT("bdb"),
+
+/* 2 */
+dkT("ndbm"),
+
+NULL
+
+
+#line 440 "dk3dbi.ctr"
+};
+
+
+
+/** Modes to open file.
+*/
+static dkChar const * const dk3dbi_file_open_modes[] = {
+/* 0 */ dkT("rb"),
+/* 1 */ dkT("wb")
+};
+
+
+
+/** File name suffixes for NDBM files.
+*/
+static char const * const dk3dbi_ndbm_suffixes[] = {
+".dir", ".pag"
+};
+
+
+
+/** Delete one storage node, release memory.
+ @param np Node to delete.
+*/
+static
+void
+dk3dbi_node_delete(dk3_dbi_node_t *np)
+{
+ if(np) {
+ dk3_release(np->keydata);
+ dk3_release(np->valdata);
+ np->keydata = NULL; np->valdata = NULL;
+ np->keysize = 0; np->valsize = 0;
+ dk3_delete(np);
+ }
+}
+
+
+
+/** Create a new node with specified buffer sizes.
+ @param ks Keys size.
+ @param vs Value size.
+ @param app Application structure for diagnostics.
+ @return Pointer to new node on success, NULL on error.
+*/
+static
+dk3_dbi_node_t *
+dk3dbi_node_new(size_t ks, size_t vs, dk3_app_t *app)
+{
+ dk3_dbi_node_t *back = NULL;
+ char *cpk = NULL; /* Key buffer pointer. */
+ char *cpv = NULL; /* Value buffer pointer. */
+ int ok = 0; /* Flag: Success. */
+
+
+#line 494 "dk3dbi.ctr"
+ back = dk3_new_app(dk3_dbi_node_t,1,app);
+ if(back) {
+ back->keysize = 0; back->valsize = 0;
+ back->keydata = NULL; back->valdata = NULL;
+ cpk = dk3_new_app(char,ks,app);
+ if(cpk) {
+ cpv = dk3_new_app(char,vs,app);
+ if(cpv) {
+ ok = 1;
+ back->keydata = (void *)cpk;
+ back->valdata = (void *)cpv;
+ back->keysize = ks;
+ back->valsize = vs;
+ }
+ }
+ if(!(ok)) {
+ dk3_delete(cpk);
+ dk3_delete(cpv);
+ dk3dbi_node_delete(back);
+ back = NULL;
+ }
+ }
+
+#line 516 "dk3dbi.ctr"
+ return back;
+}
+
+
+
+/** Comparison of storage nodes.
+ @param l Left node.
+ @param r Right node.
+ @param cr Comparison criteria (0=node/node, 1=node/datum).
+ @return Comparison result.
+*/
+static
+int
+dk3dbi_node_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3_dbi_node_t const *pl; /* Left object pointer. */
+ dk3_dbi_node_t const *pr; /* Right object pointer. */
+ dk3_datum_t const *pd; /* Right object pointer (datum). */
+ if(l) {
+ if(r) {
+ pl = (dk3_dbi_node_t const *)l;
+ switch(cr) {
+ case 1: {
+ pd = (dk3_datum_t const *)r;
+ if(pl->keydata) {
+ if(pd->dt) {
+ if(pl->keysize > pd->sz) {
+ back = 1;
+ } else {
+ if(pl->keysize < pd->sz) {
+ back = -1;
+ } else {
+ back = dk3mem_cmp(pl->keydata, pd->dt, pl->keysize);
+ if(back < -1) back = -1;
+ if(back > 1) back = 1;
+ }
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(pd->dt) {
+ back = -1;
+ }
+ }
+ } break;
+ default: {
+ pr = (dk3_dbi_node_t const *)r;
+ if(pl->keydata) {
+ if(pr->keydata) {
+ if(pl->keysize > pr->keysize) {
+ back = 1;
+ } else {
+ if(pl->keysize < pr->keysize) {
+ back = -1;
+ } else {
+ back = dk3mem_cmp(pl->keydata, pr->keydata, pl->keysize);
+ if(back < -1) back = -1;
+ if(back > 1) back = 1;
+ }
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(pr->keydata) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Read in-memory database from file.
+ @param dbp Database to initialize.
+ @return 1 on success (even if there is not db file yet), 0 on error.
+*/
+static
+int
+dk3dbi_mem_read_file(dk3_dbi_t *dbp)
+{
+ unsigned char uc[8]; /* Buffer for key and value size. */
+ FILE *fipo; /* Input file. */
+ dk3_dbi_node_t *np; /* Node for record just read. */
+ unsigned char *kd; /* Key data buffer pointer. */
+ unsigned char *vd; /* Value data buffer pointer. */
+ dkChar const *oldsourcename; /* Previous source file name. */
+ unsigned long oldsourceline; /* Previous source file line. */
+ unsigned long ul1; /* Key size as unsigned long. */
+ unsigned long ul2; /* Value size as unsigned long. */
+ size_t nread; /* Number of bytes read from file. */
+ size_t ks; /* Key size. */
+ size_t vs; /* Value size. */
+ int ok = 0; /* Flag: Success. */
+ int back = 1;
+ int cc = 1; /* Flag: Can continue. */
+
+
+#line 625 "dk3dbi.ctr"
+ oldsourcename = dk3app_get_source_file(dbp->app);
+ oldsourceline = dk3app_get_source_line(dbp->app);
+ dk3app_set_source_file(dbp->app, dbp->fn);
+ dk3app_set_source_line(dbp->app, 0UL);
+ fipo = dk3sf_fopen_app(dbp->fn, dk3dbi_file_open_modes[0], dbp->app);
+ if(fipo) {
+ while((cc) && (back)) {
+ cc = 0;
+ kd = vd = NULL;
+ nread = dk3sf_fread_app(uc, 1, 8, fipo, dbp->app);
+ if(nread > 0) {
+ if(nread == 8) {
+ ul1 = ((((unsigned long)(uc[0])) << 24) & 0xFF000000UL)
+ | ((((unsigned long)(uc[1])) << 16) & 0x00FF0000UL)
+ | ((((unsigned long)(uc[2])) << 8) & 0x0000FF00UL)
+ | (( (unsigned long)(uc[3]) ) & 0x000000FFUL);
+ ul2 = ((((unsigned long)(uc[4])) << 24) & 0xFF000000UL)
+ | ((((unsigned long)(uc[5])) << 16) & 0x00FF0000UL)
+ | ((((unsigned long)(uc[6])) << 8) & 0x0000FF00UL)
+ | (( (unsigned long)(uc[7]) ) & 0x000000FFUL);
+ ks = (size_t)ul1; vs = (size_t)ul2;
+ if(sizeof(size_t) < 4) {
+ if((ul1 > 0x0000FFFFUL) || (ul2 > 0x0000FFFFUL)) {
+ back = 0;
+ /* ERROR: Entry size too large! */
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 245);
+ }
+ }
+ if(back) {
+ kd = dk3_new_app(unsigned char,ks,dbp->app);
+ vd = dk3_new_app(unsigned char,vs,dbp->app);
+ if((kd) && (vd)) {
+ ok = 0;
+ nread = dk3sf_fread_app(kd, 1, ks, fipo, dbp->app);
+ if(nread == ks) {
+ nread = dk3sf_fread_app(vd, 1, vs, fipo, dbp->app);
+ if(nread == vs) {
+ np = dk3_new_app(dk3_dbi_node_t,1,dbp->app);
+ if(np) {
+ np->keydata = kd; np->valdata = vd;
+ np->keysize = ks; np->valsize = vs;
+ if(dk3sto_add((dbp->details).mem.s_mem, np)) {
+ cc = 1; ok = 1;
+ } else {
+ np->keydata = np->valdata = NULL;
+ np->keysize = np->valsize = 0;
+ dk3_delete(np);
+ np = NULL;
+ back = 0;
+ }
+ }
+ } else {
+ back = 0;
+ /* ERROR: File probably damaged! */
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 246);
+ }
+ } else {
+ back = 0;
+ /* ERROR: File probably damaged! */
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 246);
+ }
+ if(!(ok)) {
+ dk3_delete(kd);
+ dk3_delete(vd);
+ kd = vd = NULL;
+#if VERSION_BEFORE_20150821
+ ks = vs = 0;
+#endif
+ }
+ } else {
+ back = 0;
+ dk3_delete(kd);
+ dk3_delete(vd);
+ }
+ }
+ } else {
+ back = 0;
+ /* ERROR: File probably damaged! */
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 246);
+ }
+ } else {
+ /* End of file reached. */
+ }
+ }
+ fclose(fipo);
+ }
+ dk3app_set_source_file(dbp->app, oldsourcename);
+ dk3app_set_source_line(dbp->app, oldsourceline);
+
+
+#line 714 "dk3dbi.ctr"
+ return back;
+}
+
+
+
+/** Synchronize memory database to file.
+ @param dbp Database.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dbi_mem_sync(dk3_dbi_t *dbp)
+{
+ unsigned char uc[8]; /* Buffer for key and value size. */
+ FILE *fipo; /* Output file. */
+ dk3_dbi_node_t *np; /* Current node to process. */
+ unsigned long ul1; /* Key size as unsigned long. */
+ unsigned long ul2; /* Value size as unsigned long. */
+ size_t nwrite; /* Number of bytes written. */
+ int back = 0;
+
+
+#line 735 "dk3dbi.ctr"
+ if(dbp->fn) {
+
+#line 736 "dk3dbi.ctr"
+ fipo = dk3sf_fopen_app(dbp->fn, dk3dbi_file_open_modes[1], dbp->app);
+ if(fipo) {
+
+#line 738 "dk3dbi.ctr"
+ back = 1;
+ dk3sto_it_reset((dbp->details).mem.i_mem);
+ do {
+ np = (dk3_dbi_node_t *)dk3sto_it_next((dbp->details).mem.i_mem);
+ if(np) {
+
+#line 743 "dk3dbi.ctr"
+ ul1 = (unsigned long)(np->keysize);
+ ul2 = (unsigned long)(np->valsize);
+ uc[0] = (unsigned char)((ul1 >> 24) & 0x000000FFUL);
+ uc[1] = (unsigned char)((ul1 >> 16) & 0x000000FFUL);
+ uc[2] = (unsigned char)((ul1 >> 8) & 0x000000FFUL);
+ uc[3] = (unsigned char)( ul1 & 0x000000FFUL);
+ uc[4] = (unsigned char)((ul2 >> 24) & 0x000000FFUL);
+ uc[5] = (unsigned char)((ul2 >> 16) & 0x000000FFUL);
+ uc[6] = (unsigned char)((ul2 >> 8) & 0x000000FFUL);
+ uc[7] = (unsigned char)( ul2 & 0x000000FFUL);
+ nwrite = dk3sf_fwrite_app(uc, 1, 8, fipo, dbp->app);
+ if(nwrite) {
+
+#line 755 "dk3dbi.ctr"
+ nwrite = dk3sf_fwrite_app(np->keydata,1,np->keysize,fipo,dbp->app);
+ if(nwrite) {
+
+#line 757 "dk3dbi.ctr"
+ nwrite =
+ dk3sf_fwrite_app(np->valdata,1,np->valsize,fipo,dbp->app);
+ if(!(nwrite)) {
+
+#line 760 "dk3dbi.ctr"
+ back = 0;
+ dbp->ec = DK3_ERROR_DURING_WRITE;
+ }
+ } else {
+
+#line 764 "dk3dbi.ctr"
+ back = 0;
+ dbp->ec = DK3_ERROR_DURING_WRITE;
+ }
+ } else {
+
+#line 768 "dk3dbi.ctr"
+ back = 0;
+ dbp->ec = DK3_ERROR_DURING_WRITE;
+ }
+ }
+ } while((np) && (back));
+ if(!dk3sf_fclose_fn_app(fipo, dbp->fn, dbp->app)) {
+ back = 0;
+ }
+ } else {
+
+#line 777 "dk3dbi.ctr"
+ dbp->ec = DK3_ERROR_NOT_OPENED_FOR_WRITING;
+ }
+ } else {
+ /* BUG: No file name, must not happen! */
+ }
+
+#line 782 "dk3dbi.ctr"
+ return back;
+}
+
+
+
+/** Set entry (in-memory database).
+ @param dbp Database.
+ @param key Key data.
+ @param val Value data.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dbi_mem_set(dk3_dbi_t *dbp, dk3_datum_t *key, dk3_datum_t *val)
+{
+ int back = 0;
+ dk3_dbi_node_t *np; /* Current node to process. */
+ unsigned char *nb; /* New value buffer for node. */
+
+
+#line 801 "dk3dbi.ctr"
+ np = (dk3_dbi_node_t *)dk3sto_it_find_like(
+ (dbp->details).mem.i_mem, (void *)key, 1
+ );
+ if(np) {
+
+#line 805 "dk3dbi.ctr"
+ nb = dk3_new_app(unsigned char,val->sz,dbp->app);
+ if(nb) {
+ dk3mem_cpy(nb, val->dt, val->sz);
+ dk3_release(np->valdata);
+ np->valdata = nb;
+ np->valsize = val->sz;
+ back = 1;
+
+#line 812 "dk3dbi.ctr"
+ } else {
+ dbp->ec = DK3_ERROR_MEMORY;
+ }
+ } else {
+
+#line 816 "dk3dbi.ctr"
+ np = dk3dbi_node_new(key->sz, val->sz, dbp->app);
+ if(np) {
+ dk3mem_cpy(np->keydata, key->dt, key->sz);
+ dk3mem_cpy(np->valdata, val->dt, val->sz);
+ np->keysize = key->sz;
+ np->valsize = val->sz;
+ if(dk3sto_add((dbp->details).mem.s_mem, (void *)np)) {
+ back = 1;
+
+#line 824 "dk3dbi.ctr"
+ } else {
+ dk3dbi_node_delete(np);
+ dbp->ec = DK3_ERROR_MEMORY;
+ }
+ } else {
+ dbp->ec = DK3_ERROR_MEMORY;
+ }
+ }
+
+#line 832 "dk3dbi.ctr"
+ return back;
+}
+
+
+
+/** Retrieve entry (in-memory database).
+ @param dbp Database.
+ @param key Key data.
+ @param val Value data (input: result buffer size, output:
+ buffer size used).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dbi_mem_get(dk3_dbi_t *dbp, dk3_datum_t *key, dk3_datum_t *val)
+{
+ int back = 0;
+ dk3_dbi_node_t *np; /* Current node to process. */
+
+
+#line 851 "dk3dbi.ctr"
+ np = (dk3_dbi_node_t *)dk3sto_it_find_like(
+ (dbp->details).mem.i_mem, (void *)key, 1
+ );
+ if(np) {
+
+#line 855 "dk3dbi.ctr"
+ if(val->sz >= np->valsize) {
+ dk3mem_cpy(val->dt, np->valdata, np->valsize);
+ val->sz = np->valsize;
+ back = 1;
+
+#line 859 "dk3dbi.ctr"
+ } else {
+
+#line 860 "dk3dbi.ctr"
+ }
+ } else {
+
+#line 862 "dk3dbi.ctr"
+ if(dbp->rfk) {
+ if(dbp->app) {
+ /* ERROR: Entry not found! */
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 249);
+ }
+ }
+ }
+
+
+#line 870 "dk3dbi.ctr"
+ return back;
+}
+
+
+
+/** Delete entry (in-memory database).
+ @param dbp Database.
+ @param key Key data.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dbi_mem_delete(dk3_dbi_t *dbp, dk3_datum_t *key)
+{
+ dk3_dbi_node_t *np; /* Current node to process .*/
+ int back = 1;
+
+
+#line 887 "dk3dbi.ctr"
+ np = (dk3_dbi_node_t *)dk3sto_it_find_like(
+ (dbp->details).mem.i_mem, (void *)key, 1
+ );
+ if(np) {
+ dk3sto_remove((dbp->details).mem.s_mem, (void *)np);
+ dk3dbi_node_delete(np);
+ }
+
+#line 894 "dk3dbi.ctr"
+ return back;
+}
+
+
+
+/** Traverse database (in-memory database).
+ @param dbp Database.
+ @param obj Object to modify during traversal.
+ @param fct Function to invoke for each key/value pair.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dbi_mem_traverse(dk3_dbi_t *dbp, void *obj, dk3_db_traverse_fct_t *fct)
+{
+ dk3_datum_t key; /* Key data. */
+ dk3_datum_t val; /* Value data. */
+ dk3_dbi_node_t *np; /* Current node to process. */
+ int back = 1;
+ int res = 1; /* Function result for current node. */
+
+
+#line 915 "dk3dbi.ctr"
+ dk3sto_it_reset((dbp->details).mem.i_mem);
+ do {
+ np = (dk3_dbi_node_t *)dk3sto_it_next((dbp->details).mem.i_mem);
+ if(np) {
+ key.sz = np->keysize;
+ key.dt = np->keydata;
+ val.sz = np->valsize;
+ val.dt = np->valdata;
+ res = (*fct)(obj, &key, &val);
+ if(res < 1) {
+
+#line 925 "dk3dbi.ctr"
+ back = 0;
+ }
+ }
+ } while((np) && (res >= 0));
+
+
+#line 930 "dk3dbi.ctr"
+ return back;
+}
+
+
+#if DK3_USE_DB
+/** Open Berkeley DB file.
+ @param dbp Database.
+ @param trunc Flag: Truncate database.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dbi_bdb_open_file(dk3_dbi_t *dbp, int trunc)
+{
+ char fnb[DK3_MAX_PATH]; /* File name buffer, 8-bit chars. */
+ DB *db = NULL; /* BDB. */
+ u_int32_t flags = 0UL; /* Flags to open BDB. */
+ int back = 0;
+ int ret; /* BDB operation result. */
+
+
+#line 950 "dk3dbi.ctr"
+ if(dk3sf_filename_to_c8(fnb, sizeof(fnb), dbp->fn, dbp->app)) {
+ ret = db_create(&db, NULL, 0);
+ if(ret == 0) {
+ db->set_errfile(db, NULL);
+ flags = DB_RDONLY;
+ if(dbp->wr) {
+ flags = DB_CREATE;
+ if(trunc) {
+ flags |= DB_TRUNCATE;
+ }
+ }
+ ret = db->open(db, NULL, fnb, NULL, DB_BTREE, flags, 0600);
+ if(ret == 0) {
+ back = 1;
+ (dbp->details).bdb.dbptr = (void *)db;
+ } else {
+ db->close(db, 0);
+ }
+ } else {
+ /* ERROR: Failed to create database */
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 9);
+ }
+ } else {
+ /* ERROR: File name conversion failed! */
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+
+#line 976 "dk3dbi.ctr"
+ return back;
+}
+
+/** Set entry (Berkeley DB).
+ @param dbp Database.
+ @param key Key data.
+ @param val Value data.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dbi_bdb_set(dk3_dbi_t *dbp, dk3_datum_t *key, dk3_datum_t *val)
+{
+ DBT k; /* Key datum. */
+ DBT v; /* Value datum. */
+ DB *db; /* BDB structure. */
+ int res; /* BDB operation result. */
+ int back = 0;
+
+
+#line 995 "dk3dbi.ctr"
+ db = (DB *)((dbp->details).bdb.dbptr);
+ dk3mem_res((void *)(&k), sizeof(DBT));
+ dk3mem_res((void *)(&v), sizeof(DBT));
+ k.data = key->dt; k.size = key->sz;
+ v.data = val->dt; v.size = val->sz;
+ db->del(db, NULL, &k, 0);
+ dk3mem_res((void *)(&k), sizeof(DBT));
+ k.data = key->dt; k.size = key->sz;
+ res = db->put(db, NULL, &k, &v, 0);
+ if(res == 0) {
+ back = 1;
+ }
+
+#line 1007 "dk3dbi.ctr"
+ return back;
+}
+
+/** Retrieve entry (Berkeley DB).
+ @param dbp Database.
+ @param key Key data.
+ @param val Value data (input: result buffer size, output:
+ buffer size used).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dbi_bdb_get(dk3_dbi_t *dbp, dk3_datum_t *key, dk3_datum_t *val)
+{
+ DBT k; /* Key datum. */
+ DBT v; /* Value datum. */
+ DB *db; /* BDB structure. */
+ int res; /* BDB operation result. */
+ int back = 0;
+
+
+#line 1027 "dk3dbi.ctr"
+ db = (DB *)((dbp->details).bdb.dbptr);
+ dk3mem_res((void *)(&k), sizeof(DBT));
+ dk3mem_res((void *)(&v), sizeof(DBT));
+ k.data = key->dt; k.size = key->sz;
+ v.data = val->dt; v.ulen = val->sz; v.flags = DB_DBT_USERMEM;
+ res = db->get(db, NULL, &k, &v, 0);
+ if(res == 0) {
+ back = 1;
+ val->sz = v.size;
+ } else {
+ if(dbp->rfk) {
+ if(dbp->app) {
+ /* ERROR: Entry not found! */
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 249);
+ }
+ }
+ }
+
+#line 1044 "dk3dbi.ctr"
+ return back;
+}
+
+/** Delete entry (Berkeley DB).
+ @param dbp Database.
+ @param key Key data.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dbi_bdb_delete(dk3_dbi_t *dbp, dk3_datum_t *key)
+{
+ DBT k; /* Key datum. */
+ DB *db; /* BDB structure. */
+ int res; /* BDB operation result. */
+ int back = 0;
+
+
+#line 1061 "dk3dbi.ctr"
+ db = (DB *)((dbp->details).bdb.dbptr);
+ dk3mem_res((void *)(&k), sizeof(DBT));
+ k.data = key->dt; k.size = key->sz;
+ res = db->del(db, NULL, &k, 0);
+ if(res == 0) {
+ back = 1;
+ }
+
+#line 1068 "dk3dbi.ctr"
+ return back;
+}
+
+/** Traverse database (Berkeley DB).
+ @param dbp Database.
+ @param obj Object to modify during traversal.
+ @param fct Function to invoke for each key/value pair.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dbi_bdb_traverse(dk3_dbi_t *dbp, void *obj, dk3_db_traverse_fct_t *fct)
+{
+ DBT k; /* Key datum (BDB). */
+ DBT v; /* Value datum (BDB). */
+ dk3_datum_t key; /* Key datum (dk3dbi). */
+ dk3_datum_t val; /* Vaue datum (dk3dbi). */
+ DB *db; /* BDB structure. */
+ DBC *cp = NULL; /* BDB cursor. */
+ int res; /* BDB operation result. */
+ int cc; /* Flag: Can continue. */
+ int isfirst; /* Flag: No record received yet. */
+ int back = 0;
+
+
+#line 1092 "dk3dbi.ctr"
+ db = (DB *)((dbp->details).bdb.dbptr);
+ res = db->cursor(db, NULL, &cp, 0);
+ if(res == 0) {
+
+#line 1095 "dk3dbi.ctr"
+ if(cp) {
+
+#line 1096 "dk3dbi.ctr"
+#if VERSION_BEFORE_20150821
+ cc = 1;
+#endif
+ back = 1;
+ isfirst = 1;
+ dk3mem_res((void *)(&k), sizeof(DBT));
+ dk3mem_res((void *)(&v), sizeof(DBT));
+ do {
+
+#line 1104 "dk3dbi.ctr"
+ cc = 0;
+#if DK3_HAVE_DB_CURSOR_C_GET
+ /* 2011-10-23: c_get() not in current documentation of BDB. */
+ res = cp->c_get(cp, &k, &v, ((isfirst) ? (DB_FIRST) : (DB_NEXT)));
+#else
+ if(isfirst) {
+
+#line 1110 "dk3dbi.ctr"
+ res = cp->get(cp, &k, &v, DB_FIRST);
+ } else {
+
+#line 1112 "dk3dbi.ctr"
+ res = cp->get(cp, &k, &v, DB_NEXT);
+ }
+#endif
+ isfirst = 0;
+ if(res == 0) {
+
+#line 1117 "dk3dbi.ctr"
+ cc = 1;
+ key.dt = k.data; key.sz = k.size;
+ val.dt = v.data; val.sz = v.size;
+ res = (*fct)(obj, &key, &val);
+ switch(res) {
+ case 0: {
+
+#line 1123 "dk3dbi.ctr"
+ back = 0;
+ } break;
+ case -1: {
+
+#line 1126 "dk3dbi.ctr"
+ back = 0; cc = 0;
+ } break;
+ }
+ } else {
+
+#line 1130 "dk3dbi.ctr"
+#if VERSION_BEFORE_20150821
+ cc = 0;
+#endif
+ if(res != DB_NOTFOUND) {
+
+#line 1134 "dk3dbi.ctr"
+ back = 0;
+ }
+ }
+ } while(cc);
+ cp->c_close(cp);
+ } else {
+
+#line 1140 "dk3dbi.ctr"
+ }
+ } else {
+
+#line 1142 "dk3dbi.ctr"
+ }
+ if(cp) {
+ cp->c_close(cp);
+ }
+
+#line 1146 "dk3dbi.ctr"
+ return back;
+}
+
+#endif
+
+#if DK3_USE_NDBM
+
+/** Open NDBM database file.
+ @param dbp Database.
+ @param trunc Flag: Truncate database.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dbi_ndbm_open_file(dk3_dbi_t *dbp, int trunc)
+{
+ DBM *dbm = NULL; /* NDBM structure. */
+ int back = 0;
+ int omode = 0; /* Output file mode. */
+
+
+#line 1166 "dk3dbi.ctr"
+ omode = O_CREAT;
+ if(dbp->wr) {
+
+#line 1168 "dk3dbi.ctr"
+ omode |= O_RDWR;
+ if(trunc) {
+
+#line 1170 "dk3dbi.ctr"
+ omode |= O_TRUNC;
+ }
+ } else {
+
+#line 1173 "dk3dbi.ctr"
+ omode |= O_RDONLY;
+ }
+
+#line 1175 "dk3dbi.ctr"
+ dbm = dbm_open(dbp->fn, omode, 0600);
+ if(dbm) {
+
+#line 1177 "dk3dbi.ctr"
+ (dbp->details).ndbm.dbptr = (void *)dbm;
+ back = 1;
+ } else {
+
+#line 1180 "dk3dbi.ctr"
+ }
+
+#line 1181 "dk3dbi.ctr"
+ return back;
+}
+
+/** Set entry (NDBM).
+ @param dbp Database.
+ @param key Key data.
+ @param val Value data.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dbi_ndbm_set(dk3_dbi_t *dbp, dk3_datum_t *key, dk3_datum_t *val)
+{
+ datum k; /* Key datum. */
+ datum v; /* Value datum. */
+ DBM *dbm; /* NDBM structure. */
+ int res; /* Operation result. */
+ int back = 0;
+
+
+#line 1200 "dk3dbi.ctr"
+ dbm = (DBM *)((dbp->details).ndbm.dbptr);
+ dk3mem_res((void *)(&k),sizeof(datum));
+ dk3mem_res((void *)(&v),sizeof(datum));
+ k.dptr = key->dt; k.dsize = key->sz; v.dptr = val->dt; v.dsize = val->sz;
+ res = dbm_store(dbm, k, v, DBM_INSERT);
+ if(res == 0) {
+ back = 1;
+ } else {
+ dk3mem_res((void *)(&k),sizeof(datum));
+ dk3mem_res((void *)(&v),sizeof(datum));
+ k.dptr = key->dt; k.dsize = key->sz; v.dptr = val->dt; v.dsize = val->sz;
+ res = dbm_store(dbm, k, v, DBM_REPLACE);
+ if(res == 0) {
+ back = 1;
+ }
+ }
+
+#line 1216 "dk3dbi.ctr"
+ return back;
+}
+
+/** Retrieve entry (NDBM).
+ @param dbp Database.
+ @param key Key data.
+ @param val Value data (input: result buffer size, output:
+ buffer size used).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dbi_ndbm_get(dk3_dbi_t *dbp, dk3_datum_t *key, dk3_datum_t *val)
+{
+ datum k; /* Key datum. */
+ datum v; /* Value datum. */
+ DBM *dbm; /* NDBM structure. */
+ int back = 0;
+
+
+#line 1235 "dk3dbi.ctr"
+ dbm = (DBM *)((dbp->details).ndbm.dbptr);
+ dk3mem_res((void *)(&k), sizeof(datum));
+ k.dptr = key->dt; k.dsize = key->sz;
+ v = dbm_fetch(dbm, k);
+ if((v.dptr) && (v.dsize)) {
+ if(v.dsize <= val->sz) {
+ dk3mem_cpy(val->dt, v.dptr, v.dsize);
+ val->sz = v.dsize;
+ back = 1;
+ }
+ } else {
+ if(dbp->rfk) {
+ if(dbp->app) {
+ /* ERROR: Entry not found! */
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 249);
+ }
+ }
+ }
+
+#line 1253 "dk3dbi.ctr"
+ return back;
+}
+
+/** Delete entry (NDBM).
+ @param dbp Database.
+ @param key Key data.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dbi_ndbm_delete(dk3_dbi_t *dbp, dk3_datum_t *key)
+{
+ datum k; /* Key datum. */
+ DBM *dbm; /* NDBM structure. */
+ int back = 0;
+
+
+#line 1269 "dk3dbi.ctr"
+ dbm = (DBM *)((dbp->details).ndbm.dbptr);
+ dk3mem_res((void *)(&k),sizeof(datum));
+ k.dptr = key->dt; k.dsize = key->sz;
+ if(dbm_delete(dbm, k) == 0) {
+ back = 1;
+ }
+
+#line 1275 "dk3dbi.ctr"
+ return back;
+}
+
+/** Traverse database (NDBM).
+ @param dbp Database.
+ @param obj Object to modify during traversal.
+ @param fct Function to invoke for each key/value pair.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dbi_ndbm_traverse(dk3_dbi_t *dbp, void *obj, dk3_db_traverse_fct_t *fct)
+{
+ datum k; /* Key datum (NDBM). */
+ datum v; /* Value datum (NDBM). */
+ dk3_datum_t key; /* Key datum (dk3dbi). */
+ dk3_datum_t val; /* Value datum (dk3dbi). */
+ DBM *dbm; /* NDBM structure. */
+ int isfirst = 1; /* Flag: No record received yet. */
+ int cc; /* Flag: Can continue. */
+ int res; /* Operation result. */
+ int back = 1;
+
+
+#line 1298 "dk3dbi.ctr"
+ dbm = (DBM *)((dbp->details).ndbm.dbptr);
+ cc = 1;
+ do {
+ cc = 0;
+ if(isfirst) {
+ k = dbm_firstkey(dbm);
+ } else {
+ k = dbm_nextkey(dbm);
+ }
+ isfirst = 0;
+ if((k.dptr) && (k.dsize)) {
+ v = dbm_fetch(dbm, k);
+ if((v.dptr) && (v.dsize)) {
+ cc = 1;
+ key.dt = k.dptr;
+ key.sz = k.dsize;
+ val.dt = v.dptr;
+ val.sz = v.dsize;
+ res = (*fct)(obj, &key, &val);
+ switch(res) {
+ case 0: {
+ back = 0;
+
+#line 1320 "dk3dbi.ctr"
+ } break;
+ case -1: {
+ back = 0; cc = 0;
+
+#line 1323 "dk3dbi.ctr"
+ } break;
+ }
+ }
+ }
+ } while(cc);
+
+
+#line 1329 "dk3dbi.ctr"
+ return back;
+}
+
+#endif
+
+
+
+int
+dk3dbi_type_supported(int tp)
+{
+ int back = 0;
+
+
+#line 1341 "dk3dbi.ctr"
+ switch(tp) {
+ case DK3_DB_TYPE_MEMORY:
+ {
+ back = 1;
+ } break;
+ case DK3_DB_TYPE_BDB: {
+#if DK3_USE_DB
+ back = 1;
+#endif
+ } break;
+ case DK3_DB_TYPE_NDBM: {
+#if DK3_USE_NDBM
+ back = 1;
+#endif
+ } break;
+ }
+
+#line 1357 "dk3dbi.ctr"
+ return back;
+}
+
+
+
+/** If no type is specified use best available database type.
+ @return Best available database type.
+*/
+static
+int
+dk3dbi_choose_best_available_type(void)
+{
+ int back = DK3_DB_TYPE_MEMORY;
+
+
+#line 1371 "dk3dbi.ctr"
+#if DK3_USE_DB
+ back = DK3_DB_TYPE_BDB;
+#else
+#if DK3_USE_NDBM
+ back = DK3_DB_TYPE_NDBM;
+#endif
+#endif
+
+
+#line 1379 "dk3dbi.ctr"
+ return back;
+}
+
+
+
+/** Internal function to close the database.
+ @param dbp Database to close.
+*/
+static
+void
+dk3dbi_close_internal(dk3_dbi_t *dbp)
+{
+ dk3_dbi_node_t *np; /* Current node to process. */
+
+
+#line 1393 "dk3dbi.ctr"
+ if(dbp) {
+ switch(dbp->tp) {
+ case DK3_DB_TYPE_MEMORY: {
+ if((dbp->details).mem.s_mem) {
+ if((dbp->details).mem.i_mem) {
+ dk3sto_it_reset((dbp->details).mem.i_mem);
+ do {
+ np = (dk3_dbi_node_t *)dk3sto_it_next((dbp->details).mem.i_mem);
+ if(np) {
+ dk3dbi_node_delete(np);
+ }
+ } while(np);
+ dk3sto_it_close((dbp->details).mem.i_mem);
+ }
+ dk3sto_close((dbp->details).mem.s_mem);
+ }
+ (dbp->details).mem.s_mem = NULL;
+ } break;
+ case DK3_DB_TYPE_BDB: {
+#if DK3_USE_DB
+ DB *db;
+ if((dbp->details).bdb.dbptr) {
+ db = (DB *)((dbp->details).bdb.dbptr);
+ db->close(db, 0);
+ (dbp->details).bdb.dbptr = NULL;
+ }
+#endif
+ } break;
+ case DK3_DB_TYPE_NDBM: {
+#if DK3_USE_NDBM
+ DBM *dbm;
+ if((dbp->details).ndbm.dbptr) {
+ dbm = (DBM *)((dbp->details).ndbm.dbptr);
+ dbm_close(dbm);
+ (dbp->details).ndbm.dbptr = NULL;
+ }
+#endif
+ } break;
+ }
+ dbp->app = NULL;
+ if(dbp->fn) {
+ dk3_delete(dbp->fn);
+ }
+ dbp->fn = NULL;
+ dk3_delete(dbp);
+ }
+
+#line 1439 "dk3dbi.ctr"
+}
+
+
+
+/** Synchronize database (write all modifications to file).
+ @param dbp Database.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dbi_sync_internal(dk3_dbi_t *dbp)
+{
+ int back = 0;
+
+
+#line 1453 "dk3dbi.ctr"
+ switch(dbp->tp) {
+ case DK3_DB_TYPE_MEMORY: {
+ back = dk3dbi_mem_sync(dbp);
+ } break;
+ case DK3_DB_TYPE_BDB: {
+#if DK3_USE_DB
+ DB *db;
+ db = (DB *)((dbp->details).bdb.dbptr);
+ if(db->sync(db, 0) == 0) {
+ back = 1;
+ }
+#endif
+ } break;
+ case DK3_DB_TYPE_NDBM: {
+#if DK3_USE_NDBM
+ /* There is no sync function! */
+ dbp->ec = DK3_ERROR_NOT_SUPPORTED;
+#endif
+ } break;
+ }
+
+#line 1473 "dk3dbi.ctr"
+ return back;
+}
+
+
+
+/** Open a database if the type is known.
+ This function is invoked with the real file name
+ and a known database type.
+ @param fn File name.
+ @param tp Database type.
+ @param acc Access type DK3_DB_ACCESS_xxx,
+ see @ref databaseaccess.
+ @param pec Pointer to variable for error codes, may be NULL.
+ @param app Application structure for diagnostics, may be NULL.
+ @param trunc Flag: Truncate database.
+ @return Pointer to database structure on success, NULL on error.
+*/
+static
+dk3_dbi_t *
+dk3dbi_open_app_with_tp(
+ dkChar const *fn,
+ int tp,
+ int acc,
+ int *pec,
+ dk3_app_t *app,
+ int trunc
+)
+{
+ dk3_dbi_t *back = NULL;
+ int ok = 0; /* Flag: Success. */
+
+
+#line 1504 "dk3dbi.ctr"
+ back = dk3_new_app(dk3_dbi_t,1,app);
+ if(back) {
+ back->ec = 0;
+ back->rfk = 0;
+ back->wr = ((acc != DK3_DB_ACCESS_READ) ? 1 : 0);
+ back->app = app;
+ back->fn = NULL;
+ back->tp = tp;
+ back->mod = 0;
+ back->fn = dk3str_dup_app(fn, app);
+ if(back->fn) {
+ switch(tp) {
+ case DK3_DB_TYPE_MEMORY: {
+ (back->details).mem.s_mem = NULL;
+ (back->details).mem.i_mem = NULL;
+ (back->details).mem.s_mem = dk3sto_open_app(app);
+ if((back->details).mem.s_mem) {
+ dk3sto_set_comp(
+ (back->details).mem.s_mem,
+ dk3dbi_node_compare,
+ 0
+ );
+ (back->details).mem.i_mem = dk3sto_it_open(
+ (back->details).mem.s_mem
+ );
+ if((back->details).mem.i_mem) {
+ if(!(trunc)) {
+ ok = dk3dbi_mem_read_file(back);
+ } else {
+ ok = 1;
+ }
+ }
+ }
+ } break;
+ case DK3_DB_TYPE_BDB: {
+#if DK3_USE_DB
+ (back->details).bdb.dbptr = NULL;
+
+#line 1541 "dk3dbi.ctr"
+ ok = dk3dbi_bdb_open_file(back, trunc);
+#else
+ if(pec) { *pec = DK3_ERROR_NOT_SUPPORTED; }
+ if(app) {
+ /* ERROR: Database type not supported! */
+ dk3app_log_i3(
+ app, DK3_LL_ERROR, 247, 248, dk3dbi_type_names[1]
+ );
+ }
+#endif
+ } break;
+ case DK3_DB_TYPE_NDBM: {
+#if DK3_USE_NDBM
+ (back->details).ndbm.dbptr = NULL;
+
+#line 1555 "dk3dbi.ctr"
+ ok = dk3dbi_ndbm_open_file(back, trunc);
+#else
+ if(pec) { *pec = DK3_ERROR_NOT_SUPPORTED; }
+
+#line 1558 "dk3dbi.ctr"
+ if(app) {
+ /* ERROR: Database type not supported! */
+ dk3app_log_i3(
+ app, DK3_LL_ERROR, 247, 248, dk3dbi_type_names[2]
+ );
+ }
+#endif
+ } break;
+ }
+ } else {
+ if(pec) { *pec = DK3_ERROR_MEMORY; }
+ }
+ if(!(ok)) {
+ dk3dbi_close_internal(back);
+ back = NULL;
+ }
+ }
+
+#line 1575 "dk3dbi.ctr"
+ return back;
+}
+
+
+
+int
+dk3dbi_find_type_and_name(
+ dkChar const **myfn,
+ int *mytp,
+ dkChar const *fn,
+ int tp,
+ int *pec,
+ dk3_app_t *app
+)
+{
+ dkChar *p1; /* Start of real file name. */
+ int back = 0;
+
+
+#line 1593 "dk3dbi.ctr"
+ *mytp = tp;
+ p1 = dk3str_chr(fn, dkT(':'));
+ if(p1) {
+
+#line 1596 "dk3dbi.ctr"
+ if(p1[1] == dkT(':')) {
+
+#line 1597 "dk3dbi.ctr"
+ *(p1++) = dkT('\0');
+ p1++;
+ *myfn = p1;
+ *mytp = dk3str_array_index(dk3dbi_type_names, fn, 0);
+ if(*mytp >= 0) {
+
+#line 1602 "dk3dbi.ctr"
+ if(dk3dbi_type_supported(*mytp)) {
+ back = 1;
+ } else {
+
+#line 1605 "dk3dbi.ctr"
+ if(app) {
+ /* ERROR: Database type not supported! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 247, 248, fn);
+ }
+ if(pec) {
+ *pec = DK3_ERROR_NOT_SUPPORTED;
+ }
+ }
+ } else {
+
+#line 1614 "dk3dbi.ctr"
+ if(app) {
+ /* ERROR: Database type not found! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 247, 248, fn);
+ }
+ if(pec) {
+ *pec = DK3_ERROR_INVALID_ARGS;
+ }
+ }
+ } else {
+
+#line 1623 "dk3dbi.ctr"
+ /* Single colon */
+ *myfn = fn;
+ if(tp < 0) {
+ *mytp = dk3dbi_choose_best_available_type();
+ }
+ back = 1;
+ }
+ } else {
+
+#line 1631 "dk3dbi.ctr"
+ /* No colon found */
+ *myfn = fn;
+ if(tp < 0) {
+ *mytp = dk3dbi_choose_best_available_type();
+ }
+ back = 1;
+ }
+ if(back) {
+ if(*mytp >= 0) {
+ if(!dk3dbi_type_supported(*mytp)) {
+ back = 0;
+ if(app) {
+ /* ERROR: Database type not supported! */
+ }
+ if(pec) {
+ *pec = DK3_ERROR_NOT_SUPPORTED;
+ }
+ }
+ } else {
+ back = 0;
+ }
+ }
+
+#line 1653 "dk3dbi.ctr"
+ return back;
+}
+
+
+
+/** Open a database.
+ @param fn File name.
+ @param tp Database type.
+ @param acc Access type.
+ @param pec Pointer to error code variable.
+ @param app Application structure for diagnostics, may be NULL.
+ @param trunc Flag: Truncate database.
+ @return Pointer to new database on success, NULL on error.
+*/
+static
+dk3_dbi_t *
+dk3dbi_open_internal(
+ dkChar const *fn,
+ int tp,
+ int acc,
+ int *pec,
+ dk3_app_t *app,
+ int trunc
+)
+{
+ dkChar fnb[DK3_MAX_PATH + 16]; /* File name buffer. */
+ dk3_dbi_t *back = NULL;
+ dkChar const *myfn = NULL; /* Real file name. */
+ int mytp = DK3_DB_TYPE_UNKNOWN; /* Database type. */
+
+
+#line 1683 "dk3dbi.ctr"
+ if(fn) {
+
+#line 1684 "dk3dbi.ctr"
+ if(dk3str_len(fn) < DK3_SIZEOF(fnb,dkChar)) {
+
+#line 1685 "dk3dbi.ctr"
+ dk3str_cpy_not_overlapped(fnb, fn);
+ if(dk3dbi_find_type_and_name(&myfn ,&mytp, fnb, tp, pec, app))
+ {
+
+#line 1688 "dk3dbi.ctr"
+ if((myfn) && (mytp >= 0)) {
+
+#line 1689 "dk3dbi.ctr"
+ back = dk3dbi_open_app_with_tp(myfn, mytp, acc, pec, app, trunc);
+ } else {
+
+#line 1691 "dk3dbi.ctr"
+ /* BUG: Must not happen! */
+ }
+ }
+ } else {
+
+#line 1695 "dk3dbi.ctr"
+ if(app) {
+ /* ERROR: File name too long! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 65, 66, fn);
+ }
+ if(pec) {
+ *pec = DK3_ERROR_INVALID_ARGS;
+ }
+ }
+ } else {
+
+#line 1704 "dk3dbi.ctr"
+ }
+
+#line 1705 "dk3dbi.ctr"
+ return back;
+}
+
+
+
+dk3_dbi_t *
+dk3dbi_open_app(
+ dkChar const *fn,
+ int tp,
+ int acc,
+ int *pec,
+ dk3_app_t *app
+)
+{
+ dk3_dbi_t *back;
+ back = dk3dbi_open_internal(fn, tp, acc, pec, app, 0);
+ return back;
+}
+
+
+
+dk3_dbi_t *
+dk3dbi_open_truncate_app(
+ dkChar const *fn,
+ int tp,
+ int acc,
+ int *pec,
+ dk3_app_t *app
+)
+{
+ dk3_dbi_t *back;
+
+
+#line 1737 "dk3dbi.ctr"
+ back = dk3dbi_open_internal(fn, tp, acc, pec, app, 1);
+
+
+#line 1739 "dk3dbi.ctr"
+ return back;
+}
+
+
+
+dk3_dbi_t *
+dk3dbi_open(dkChar const *fn, int tp, int acc, int *pec)
+{
+ dk3_dbi_t *back = NULL;
+
+
+#line 1749 "dk3dbi.ctr"
+ back = dk3dbi_open_app(fn, tp, acc, pec, NULL);
+
+
+#line 1751 "dk3dbi.ctr"
+ return back;
+}
+
+
+
+dk3_dbi_t *
+dk3dbi_open_truncate(dkChar const *fn, int tp, int acc, int *pec)
+{
+ dk3_dbi_t *back;
+ back = dk3dbi_open_truncate_app(fn, tp, acc, pec, NULL);
+ return back;
+}
+
+
+
+int
+dk3dbi_close(dk3_dbi_t *dbp)
+{
+ int back = 0;
+
+
+#line 1771 "dk3dbi.ctr"
+ if(dbp) {
+ back = 1;
+ if(dbp->mod) {
+
+#line 1774 "dk3dbi.ctr"
+ back = dk3dbi_sync_internal(dbp);
+ }
+ dk3dbi_close_internal(dbp);
+ }
+
+#line 1778 "dk3dbi.ctr"
+ return back;
+}
+
+
+
+int
+dk3dbi_set(dk3_dbi_t *dbp, dk3_datum_t *key, dk3_datum_t *val)
+{
+ int back = 0;
+
+
+#line 1788 "dk3dbi.ctr"
+ if((dbp) && (key) && (val)) {
+ if((key->dt) && (key->sz) && (val->dt) && (val->sz)) {
+ if(dbp->wr) {
+ switch(dbp->tp) {
+ case DK3_DB_TYPE_MEMORY: {
+ back = dk3dbi_mem_set(dbp, key, val);
+ dbp->mod = 1;
+ } break;
+ case DK3_DB_TYPE_BDB: {
+#if DK3_USE_DB
+ back = dk3dbi_bdb_set(dbp, key, val);
+ dbp->mod = 1;
+#endif
+ } break;
+ case DK3_DB_TYPE_NDBM: {
+#if DK3_USE_NDBM
+ back = dk3dbi_ndbm_set(dbp, key, val);
+ dbp->mod = 1;
+#endif
+ } break;
+ }
+ } else {
+ /* ERROR: Write operations denied! */
+ dbp->ec = DK3_ERROR_NOT_OPENED_FOR_WRITING;
+ if(dbp->app) {
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 251);
+ }
+ }
+ } else {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ } else {
+ if(dbp) {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ }
+
+#line 1824 "dk3dbi.ctr"
+ return back;
+}
+
+
+
+int
+dk3dbi_get(dk3_dbi_t *dbp, dk3_datum_t *key, dk3_datum_t *val)
+{
+ int back = 0;
+
+
+#line 1834 "dk3dbi.ctr"
+ if((dbp) && (key) && (val)) {
+ if((key->dt) && (key->sz) && (val->dt) && (val->sz)) {
+ switch(dbp->tp) {
+ case DK3_DB_TYPE_MEMORY: {
+ back = dk3dbi_mem_get(dbp, key, val);
+ } break;
+ case DK3_DB_TYPE_BDB: {
+#if DK3_USE_DB
+ back = dk3dbi_bdb_get(dbp, key, val);
+#endif
+ } break;
+ case DK3_DB_TYPE_NDBM: {
+#if DK3_USE_NDBM
+ back = dk3dbi_ndbm_get(dbp, key, val);
+#endif
+ } break;
+ }
+ } else {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ } else {
+ if(dbp) {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ }
+
+#line 1859 "dk3dbi.ctr"
+ return back;
+}
+
+
+
+int
+dk3dbi_delete(dk3_dbi_t *dbp, dk3_datum_t *key)
+{
+ int back = 0;
+
+
+#line 1869 "dk3dbi.ctr"
+ if((dbp) && (key)) {
+ if((key->dt) && (key->sz)) {
+ switch(dbp->tp) {
+ case DK3_DB_TYPE_MEMORY: {
+ back = dk3dbi_mem_delete(dbp, key);
+ dbp->mod = 1;
+ } break;
+ case DK3_DB_TYPE_BDB: {
+#if DK3_USE_DB
+ back = dk3dbi_bdb_delete(dbp, key);
+ dbp->mod = 1;
+#endif
+ } break;
+ case DK3_DB_TYPE_NDBM: {
+#if DK3_USE_NDBM
+ back = dk3dbi_ndbm_delete(dbp, key);
+ dbp->mod = 1;
+#endif
+ } break;
+ }
+ } else {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ } else {
+ if(dbp) {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ }
+
+#line 1897 "dk3dbi.ctr"
+ return back;
+}
+
+
+
+int
+dk3dbi_traverse(dk3_dbi_t *dbp, void *obj, dk3_db_traverse_fct_t *fct)
+{
+ int back = 0;
+
+
+#line 1907 "dk3dbi.ctr"
+ if((dbp) && (fct)) {
+ switch(dbp->tp) {
+ case DK3_DB_TYPE_MEMORY: {
+ back = dk3dbi_mem_traverse(dbp, obj, fct);
+ } break;
+ case DK3_DB_TYPE_BDB: {
+#if DK3_USE_DB
+ back = dk3dbi_bdb_traverse(dbp, obj, fct);
+#endif
+ } break;
+ case DK3_DB_TYPE_NDBM: {
+#if DK3_USE_NDBM
+ back = dk3dbi_ndbm_traverse(dbp, obj, fct);
+#endif
+ } break;
+ }
+ } else {
+ if(dbp) {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ }
+
+#line 1928 "dk3dbi.ctr"
+ return back;
+}
+
+
+
+int
+dk3dbi_sync(dk3_dbi_t *dbp)
+{
+ int back = 0;
+
+
+#line 1938 "dk3dbi.ctr"
+ if(dbp) {
+ back = 1;
+ if(dbp->mod) {
+ back = dk3dbi_sync_internal(dbp);
+ if(back) { dbp->mod = 0; }
+ }
+ }
+
+#line 1945 "dk3dbi.ctr"
+ return back;
+}
+
+
+
+int
+dk3dbi_get_error(dk3_dbi_t *dbp, int res)
+{
+ int back = 0;
+
+
+#line 1955 "dk3dbi.ctr"
+ if(dbp) {
+ back = dbp->ec;
+ if(res) { dbp->ec = 0; }
+ }
+
+#line 1959 "dk3dbi.ctr"
+ return back;
+}
+
+
+
+int
+dk3dbi_set_c8_string(
+ dk3_dbi_t *dbp,
+ char const *key,
+ char const *val
+)
+{
+ dk3_datum_t k; /* Key datum. */
+ dk3_datum_t v; /* Value datum. */
+ size_t ks; /* Key size (number of bytes). */
+ size_t vs; /* Value size (number of bytes). */
+ int back = 0;
+
+
+#line 1977 "dk3dbi.ctr"
+ if((dbp) && (key) && (val)) {
+ ks = dk3str_c8_len(key);
+ vs = dk3str_c8_len(val);
+ ks++; vs++;
+ if((ks) && (vs)) {
+ k.dt = (void *)key; k.sz = ks;
+ v.dt = (void *)val; v.sz = vs;
+ back = dk3dbi_set(dbp, &k, &v);
+ } else {
+ /* ERROR: At least one numeric overflow. */
+ if(dbp->app) {
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 15);
+ }
+ dbp->ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if(dbp) {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ }
+
+#line 1997 "dk3dbi.ctr"
+ return back;
+}
+
+
+
+int
+dk3dbi_get_c8_string(
+ dk3_dbi_t *dbp,
+ char const *key,
+ char *vb,
+ size_t vbsz
+)
+{
+ dk3_datum_t k; /* Key datum. */
+ dk3_datum_t v; /* Value datum. */
+ size_t ks; /* Key size (number of bytes). */
+ int back = 0;
+ int orfk;
+
+
+#line 2016 "dk3dbi.ctr"
+ if((dbp) && (key) && (vb) && (vbsz)) {
+ ks = dk3str_c8_len(key);
+ ks++;
+ if(ks) {
+ k.dt = (void *)key; k.sz = ks;
+ v.dt = vb; v.sz = vbsz;
+ orfk = dbp->rfk;
+ dbp->rfk = 0;
+ if(dk3dbi_get(dbp, &k, &v)) {
+ back = 1;
+ if(v.sz > 0) {
+ if(v.sz < vbsz) {
+ vb[v.sz] = '\0';
+ } else {
+ vb[vbsz - 1] = '\0';
+ }
+ } else {
+ vb[0] = '\0';
+ }
+ }
+ dbp->rfk = orfk;
+ } else {
+ /* ERROR: Numeric overflow! */
+ if(dbp->app) {
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 15);
+ }
+ dbp->ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if(dbp) {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ }
+
+#line 2049 "dk3dbi.ctr"
+ return back;
+}
+
+
+
+int
+dk3dbi_delete_c8_string(
+ dk3_dbi_t *dbp,
+ char const *key
+)
+{
+ dk3_datum_t k; /* Key datum. */
+ size_t ks; /* Key size in bytes. */
+ int back = 0;
+
+
+#line 2064 "dk3dbi.ctr"
+ if((dbp) && (key)) {
+ ks = dk3str_c8_len(key);
+ ks++;
+ if(ks) {
+ k.dt = (void *)key; k.sz = ks;
+ back = dk3dbi_delete(dbp, &k);
+ } else {
+ /* ERROR: Numeric overflow! */
+ if(dbp->app) {
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 15);
+ }
+ dbp->ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if(dbp) {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ }
+
+#line 2082 "dk3dbi.ctr"
+ return back;
+}
+
+
+
+int
+dk3dbi_set_c16_string(
+ dk3_dbi_t *dbp,
+ dk3_c16_t const *key,
+ dk3_c16_t const *val
+)
+{
+ dk3_datum_t k; /* Key datum. */
+ dk3_datum_t v; /* Value datum. */
+ size_t ks; /* Key size (number of bytes). */
+ size_t vs; /* Value size (number of bytes). */
+ int back = 0;
+
+
+#line 2100 "dk3dbi.ctr"
+ if((dbp) && (key) && (val)) {
+ ks = dk3str_c16_len(key);
+ vs = dk3str_c16_len(val);
+ ks = dk3mem_mul_size_t(dk3mem_add_size_t(ks, 1, NULL), 2, NULL);
+ vs = dk3mem_mul_size_t(dk3mem_add_size_t(vs, 1, NULL), 2, NULL);
+ if((ks) && (vs)) {
+ k.dt = (void *)key; k.sz = ks; v.dt = (void *)val; v.sz = vs;
+ back = dk3dbi_set(dbp, &k, &v);
+ } else {
+ /* ERROR: Size overflow! */
+ if(dbp->app) {
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 15);
+ }
+ dbp->ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if(dbp) {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ }
+
+#line 2120 "dk3dbi.ctr"
+ return back;
+}
+
+
+
+int
+dk3dbi_get_c16_string(
+ dk3_dbi_t *dbp,
+ dk3_c16_t const *key,
+ dk3_c16_t *vb,
+ size_t vbsz
+)
+{
+ dk3_datum_t k; /* Key datum. */
+ dk3_datum_t v; /* Value datum. */
+ size_t ks; /* Key size (number of bytes). */
+ size_t vs; /* Value size (number of bytes). */
+ int back = 0;
+ int orfk;
+
+
+#line 2140 "dk3dbi.ctr"
+ if((dbp) && (key) && (vb) && (vbsz)) {
+ ks = dk3str_c16_len(key);
+ ks = dk3mem_mul_size_t(dk3mem_add_size_t(ks, 1, NULL), 2, NULL);
+ vs = dk3mem_mul_size_t(vbsz, 2, NULL);
+ if((ks) && (vs)) {
+ k.dt = (void *)key; k.sz = ks; v.dt = vb, v.sz = vs;
+ orfk = dbp->rfk;
+ dbp->rfk = 0;
+ if(dk3dbi_get(dbp, &k, &v)) {
+ if(!((v.sz) % 2)) {
+ back = 1;
+ v.sz = v.sz / 2;
+ if(v.sz > 0) {
+ if(v.sz < vbsz) {
+ vb[v.sz] = 0U;
+ } else {
+ vb[vbsz - 1] = 0U;
+ }
+ } else {
+ vb[0] = 0U;
+ }
+ } else {
+ /* ERROR: Damaged entry! */
+ if(dbp->app) {
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 250);
+ }
+ dbp->ec = DK3_ERROR_DATA_DAMAGED;
+ }
+ }
+ dbp->rfk = orfk;
+ } else {
+ /* ERROR: Numeric overflow! */
+ if(dbp->app) {
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 15);
+ }
+ dbp->ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if(dbp) {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ }
+
+#line 2182 "dk3dbi.ctr"
+ return back;
+}
+
+
+
+int
+dk3dbi_delete_c16_string(
+ dk3_dbi_t *dbp,
+ dk3_c16_t const *key
+)
+{
+ dk3_datum_t k; /* Key datum. */
+ size_t ks; /* Key size (number of bytes). */
+ int back = 0;
+
+
+#line 2197 "dk3dbi.ctr"
+ if((dbp) && (key)) {
+ ks = dk3str_c16_len(key);
+ ks = dk3mem_mul_size_t(dk3mem_add_size_t(ks, 1, NULL), 2, NULL);
+ if(ks) {
+ k.dt = (void *)key; k.sz = ks;
+ back = dk3dbi_delete(dbp, &k);
+ } else {
+ /* ERROR: Numeric overflow! */
+ if(dbp->app) {
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 15);
+ }
+ dbp->ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if(dbp) {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ }
+
+#line 2215 "dk3dbi.ctr"
+ return back;
+}
+
+
+
+int
+dk3dbi_set_c32_string(
+ dk3_dbi_t *dbp,
+ dk3_c32_t const *key,
+ dk3_c32_t const *val
+)
+{
+ dk3_datum_t k; /* Key datum. */
+ dk3_datum_t v; /* Value datum. */
+ size_t ks; /* Key size (number of bytes). */
+ size_t vs; /* Value size (number of bytes). */
+ int back = 0;
+
+
+#line 2233 "dk3dbi.ctr"
+ if((dbp) && (key) && (val)) {
+ ks = dk3str_c32_len(key);
+ ks = dk3mem_mul_size_t(dk3mem_add_size_t(ks, 1, NULL), 4, NULL);
+ vs = dk3str_c32_len(val);
+ vs = dk3mem_mul_size_t(dk3mem_add_size_t(vs, 1, NULL), 4, NULL);
+ if((ks) && (vs)) {
+ k.dt = (void *)key; k.sz = ks; v.dt = (void *)val; v.sz = vs;
+ back = dk3dbi_set(dbp, &k, &v);
+ } else {
+ /* ERROR: Numeric overflow! */
+ if(dbp->app) {
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 15);
+ }
+ dbp->ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if(dbp) {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ }
+
+#line 2253 "dk3dbi.ctr"
+ return back;
+}
+
+
+
+int
+dk3dbi_get_c32_string(
+ dk3_dbi_t *dbp,
+ dk3_c32_t const *key,
+ dk3_c32_t *vb,
+ size_t vbsz
+)
+{
+ dk3_datum_t k; /* Key datum. */
+ dk3_datum_t v; /* Value datum. */
+ size_t ks; /* Key size (number of bytes). */
+ size_t vs; /* Value size (number of bytes). */
+ int back = 0;
+ int orfk;
+
+
+#line 2273 "dk3dbi.ctr"
+ if((dbp) && (key) && (vb) && (vbsz)) {
+ ks = dk3str_c32_len(key);
+ ks = dk3mem_mul_size_t(dk3mem_add_size_t(ks, 1, NULL), 4, NULL);
+ vs = dk3mem_mul_size_t(vbsz, 4, NULL);
+ if((ks) && (vs)) {
+ k.dt = (void *)key; k.sz = ks; v.dt = vb; v.sz = vs;
+ orfk = dbp->rfk;
+ dbp->rfk = 0;
+ if(dk3dbi_get(dbp, &k, &v)) {
+ if(!((v.sz) % 4)) {
+ back = 1;
+ v.sz = v.sz / 4;
+ if(v.sz > 0) {
+ if(v.sz < vbsz) {
+ vb[v.sz] = 0UL;
+ } else {
+ vb[vbsz - 1] = 0UL;
+ }
+ } else {
+ vb[0] = 0UL;
+ }
+ } else {
+ /* ERROR: Damaged entry! */
+ if(dbp->app) {
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 250);
+ }
+ dbp->ec = DK3_ERROR_DATA_DAMAGED;
+ }
+ }
+ dbp->rfk = orfk;
+ } else {
+ /* ERROR: Numeric overflow! */
+ if(dbp->app) {
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 15);
+ }
+ dbp->ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if(dbp) {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ }
+
+#line 2315 "dk3dbi.ctr"
+ return back;
+}
+
+
+
+int
+dk3dbi_delete_c32_string(
+ dk3_dbi_t *dbp,
+ dk3_c32_t const *key
+)
+{
+ dk3_datum_t k; /* Key datum. */
+ size_t ks; /* Key size (number of bytes). */
+ int back = 0;
+
+
+#line 2330 "dk3dbi.ctr"
+ if((dbp) && (key)) {
+ ks = dk3str_c32_len(key);
+ ks = dk3mem_mul_size_t(dk3mem_add_size_t(ks, 1, NULL), 4, NULL);
+ if(ks) {
+ k.dt = (void *)key; k.sz = ks;
+ back = dk3dbi_delete(dbp, &k);
+ } else {
+ /* ERROR: Numeric overflow! */
+ if(dbp->app) {
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 15);
+ }
+ dbp->ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if(dbp) {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ }
+
+#line 2348 "dk3dbi.ctr"
+ return back;
+}
+
+
+
+int
+dk3dbi_set_string(
+ dk3_dbi_t *dbp,
+ dkChar const *key,
+ dkChar const *val
+)
+{
+ int back = 0;
+
+
+#line 2362 "dk3dbi.ctr"
+ if((dbp) && (key) && (val)) {
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ back = dk3dbi_set_c32_string(dbp, key, val);
+#else
+ back = dk3dbi_set_c16_string(dbp, key, val);
+#endif
+#else
+ back = dk3dbi_set_c8_string(dbp, key, val);
+#endif
+ } else {
+ if(dbp) {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ }
+
+#line 2377 "dk3dbi.ctr"
+ return back;
+}
+
+
+
+int
+dk3dbi_get_string(
+ dk3_dbi_t *dbp,
+ dkChar const *key,
+ dkChar *vb,
+ size_t vbsz
+)
+{
+ int back = 0;
+
+
+#line 2392 "dk3dbi.ctr"
+ if((dbp) && (key) && (vb) && (vbsz)) {
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ back = dk3dbi_get_c32_string(dbp, key, vb, vbsz);
+#else
+ back = dk3dbi_get_c16_string(dbp, key, vb, vbsz);
+#endif
+#else
+ back = dk3dbi_get_c8_string(dbp, key, vb, vbsz);
+#endif
+ } else {
+ if(dbp) {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ }
+
+#line 2407 "dk3dbi.ctr"
+ return back;
+}
+
+
+int
+dk3dbi_delete_string(
+ dk3_dbi_t *dbp,
+ dkChar const *key
+)
+{
+ int back = 0;
+
+
+#line 2419 "dk3dbi.ctr"
+ if((dbp) && (key)) {
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ back = dk3dbi_delete_c32_string(dbp, key);
+#else
+ back = dk3dbi_delete_c16_string(dbp, key);
+#endif
+#else
+ back = dk3dbi_delete_c8_string(dbp, key);
+#endif
+ } else {
+ if(dbp) {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ }
+
+#line 2434 "dk3dbi.ctr"
+ return back;
+}
+
+
+
+/** Delete or truncate a database file.
+ @param fn File name.
+ @param tp Database type.
+ @param del Flag: Delete (non-zero) or truncate (0).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dbi_dbfile_del_or_trunc(dkChar const *fn, int tp, int del, dk3_app_t *app)
+{
+ dkChar fnb[DK3_MAX_PATH + 16]; /* Copy of file name. */
+ char c8fn[DK3_MAX_PATH]; /* File name as 8-bit. */
+ FILE *fipo; /* File to truncate. */
+ dkChar const *myfn; /* File name. */
+ int ec = 0; /* Error code. */
+ int mytp; /* DB type. */
+ int back = 0;
+
+
+#line 2458 "dk3dbi.ctr"
+ mytp = tp;
+ if(fn) {
+ if(dk3str_len(fn) < DK3_SIZEOF(fnb,dkChar)) {
+ dk3str_cpy_not_overlapped(fnb, fn);
+ if(dk3dbi_find_type_and_name(&myfn, &mytp, fnb, tp, &ec, app)) {
+ if((myfn) && (mytp >= 0)) {
+ switch(mytp) {
+ case DK3_DB_TYPE_MEMORY: {
+
+#line 2466 "dk3dbi.ctr"
+ if(del) {
+ dk3sf_remove_file_app(myfn, app);
+ back = 1;
+ } else {
+ fipo = dk3sf_fopen_app(myfn, dk3dbi_file_open_modes[1], app);
+ if(fipo) {
+
+#line 2472 "dk3dbi.ctr"
+ if(dk3sf_fclose_fn_app(fipo, myfn, app)) {
+ back = 1;
+ }
+ } else {
+
+#line 2476 "dk3dbi.ctr"
+ }
+ }
+ } break;
+ case DK3_DB_TYPE_BDB: {
+
+#line 2480 "dk3dbi.ctr"
+ if(dk3sf_filename_to_c8(c8fn, sizeof(c8fn), myfn, app)) {
+ if(del) {
+ dk3sf_remove_file_app(myfn, app);
+ back = 1;
+ } else {
+#if DK3_USE_DB
+ DB *db = NULL;
+ int ret;
+ u_int32_t flags;
+ ret = db_create(&db, NULL, 0);
+ if(ret == 0) {
+
+#line 2491 "dk3dbi.ctr"
+ flags = DB_CREATE | DB_TRUNCATE;
+ ret = db->open(db, NULL, c8fn, NULL, DB_BTREE, flags, 0600);
+ if(ret == 0) {
+
+#line 2494 "dk3dbi.ctr"
+ back = 1;
+ } else {
+
+#line 2496 "dk3dbi.ctr"
+ }
+ if(db) {
+ db->close(db, 0);
+ }
+ } else {
+
+#line 2501 "dk3dbi.ctr"
+ }
+#endif
+ }
+ } else {
+
+#line 2505 "dk3dbi.ctr"
+ }
+ } break;
+ case DK3_DB_TYPE_NDBM: {
+
+#line 2508 "dk3dbi.ctr"
+ if(dk3sf_filename_to_c8(c8fn, sizeof(c8fn), myfn, app)) {
+ if(del) {
+ if((dk3str_c8_len(c8fn)
+ + dk3str_c8_len(dk3dbi_ndbm_suffixes[0])
+ ) < sizeof(c8fn)
+ )
+ {
+ dk3str_c8_cat(c8fn, dk3dbi_ndbm_suffixes[0]);
+ dk3sf_c8_remove_file_app(c8fn, app);
+ dk3sf_filename_to_c8(c8fn, sizeof(c8fn), myfn, app);
+ if((dk3str_c8_len(c8fn)
+ + dk3str_c8_len(dk3dbi_ndbm_suffixes[1])
+ ) < sizeof(c8fn)
+ )
+ {
+ dk3str_c8_cat(c8fn, dk3dbi_ndbm_suffixes[1]);
+ dk3sf_c8_remove_file_app(c8fn, app);
+ back = 1;
+ }
+ }
+ } else {
+#if DK3_USE_NDBM
+ DBM *dbm = NULL;
+ dbm = dbm_open(c8fn, (O_RDWR | O_CREAT | O_TRUNC), 0600);
+ if(dbm) {
+ dbm_close(dbm);
+ }
+#endif
+ }
+ } else {
+
+#line 2538 "dk3dbi.ctr"
+ }
+ } break;
+ default: {
+ /* BUG: Illegal database type, must not happen! */
+ } break;
+ }
+ } else {
+
+#line 2545 "dk3dbi.ctr"
+ /* BUG: Must not happen! */
+ }
+ } else {
+
+#line 2548 "dk3dbi.ctr"
+ /* Error: Name or type not found, already reported! */
+ }
+ } else {
+
+#line 2551 "dk3dbi.ctr"
+ /* ERROR: File name too long! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 65, 66, fn);
+ }
+ } else {
+
+#line 2555 "dk3dbi.ctr"
+ }
+
+#line 2556 "dk3dbi.ctr"
+ return back;
+}
+
+
+
+int
+dk3dbi_dbfile_delete_app(dkChar const *fn, int tp, dk3_app_t *app)
+{
+ int back;
+
+
+#line 2566 "dk3dbi.ctr"
+ back = dk3dbi_dbfile_del_or_trunc(fn, tp, 1, app);
+
+
+#line 2568 "dk3dbi.ctr"
+ return back;
+}
+
+
+
+int
+dk3dbi_dbfile_truncate_app(dkChar const *fn, int tp, dk3_app_t *app)
+{
+ int back;
+
+
+#line 2578 "dk3dbi.ctr"
+ back = dk3dbi_dbfile_del_or_trunc(fn, tp, 1, app);
+
+
+#line 2580 "dk3dbi.ctr"
+ return back;
+}
+
+
+
+int
+dk3dbi_dbfile_delete(dkChar const *fn, int tp)
+{
+ int back;
+
+
+#line 2590 "dk3dbi.ctr"
+ back = dk3dbi_dbfile_del_or_trunc(fn, tp, 1, NULL);
+
+
+#line 2592 "dk3dbi.ctr"
+ return back;
+}
+
+
+
+int
+dk3dbi_dbfile_truncate(dkChar const *fn, int tp)
+{
+ int back;
+
+
+#line 2602 "dk3dbi.ctr"
+ back = dk3dbi_dbfile_del_or_trunc(fn, tp, 1, NULL);
+
+
+#line 2604 "dk3dbi.ctr"
+ return back;
+}
+
+
+
+#if !DK3_ON_WINDOWS
+#if DK3_CHAR_SIZE == 1
+#if DK3_HAVE_CHOWN && DK3_HAVE_CHMOD
+static
+int
+dk3dbi_change_file_user_and_permissions(
+ dk3_dbi_t *db, char const *fn, uid_t uid, gid_t gid, mode_t mode
+)
+{
+ int back = 0;
+ if(0 == chown(fn, uid, gid)) {
+ if(0 == chmod(fn, mode)) {
+ back = 1;
+ } else {
+ /* ERROR: Failed to change file permissions! */
+ if(db->app) {
+ dk3app_log_i3(db->app, DK3_LL_ERROR, 272, 273, fn);
+ }
+ }
+ } else {
+ /* ERROR: Failed to change file ownership! */
+ if(db->app) {
+ dk3app_log_i3(db->app, DK3_LL_ERROR, 270, 271, fn);
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3dbi_change_user_and_permissions(
+ dk3_dbi_t *db,
+ uid_t uid,
+ gid_t gid,
+ mode_t mode
+)
+{
+ dkChar fnb[DK3_MAX_PATH];
+ int back = 0;
+ if(db) {
+ switch(db->tp) {
+ case DK3_DB_TYPE_MEMORY:
+ case DK3_DB_TYPE_BDB: {
+ if(db->fn) {
+ back = dk3dbi_change_file_user_and_permissions(
+ db, db->fn, uid, gid, mode
+ );
+ } else {
+ /* ERROR: No file name for database! */
+ if(db->app) {
+ dk3app_log_i1(db->app, DK3_LL_ERROR, 269);
+ }
+ }
+ } break;
+ case DK3_DB_TYPE_NDBM: {
+ if(db->fn) {
+ if(dk3str_len(db->fn) < DK3_SIZEOF(fnb,dkChar)) {
+ back = 1;
+ dk3str_cpy_not_overlapped(fnb, db->fn);
+ if((dk3str_len(fnb) + dk3str_len(dk3dbi_ndbm_suffixes[0]))
+ < DK3_SIZEOF(fnb,dkChar)
+ )
+ {
+ dk3str_cat(fnb, dk3dbi_ndbm_suffixes[0]);
+ if(!dk3dbi_change_file_user_and_permissions(db,fnb,uid,gid,mode))
+ {
+ back = 0;
+ }
+ }
+ else
+ {
+ /* ERROR: File name too long! */
+ if(db->app) {
+ dk3app_log_i3(db->app, DK3_LL_ERROR, 66, 67, db->fn);
+ }
+ back = 0;
+ }
+ dk3str_cpy_not_overlapped(fnb, db->fn);
+ if((dk3str_len(fnb) + dk3str_len(dk3dbi_ndbm_suffixes[1]))
+ < DK3_SIZEOF(fnb,dkChar)
+ )
+ {
+ dk3str_cat(fnb, dk3dbi_ndbm_suffixes[1]);
+ if(!dk3dbi_change_file_user_and_permissions(db,fnb,uid,gid,mode))
+ {
+ back = 0;
+ }
+ }
+ else
+ {
+ /* ERROR: File name too long! */
+ if(db->app) {
+ dk3app_log_i3(db->app, DK3_LL_ERROR, 66, 67, db->fn);
+ }
+ back = 0;
+ }
+ } else {
+ /* ERROR: File name too long! */
+ if(db->app) {
+ dk3app_log_i3(db->app, DK3_LL_ERROR, 66, 67, db->fn);
+ }
+ }
+ } else {
+ /* ERROR: No file name for database! */
+ if(db->app) {
+ dk3app_log_i1(db->app, DK3_LL_ERROR, 269);
+ }
+ }
+ } break;
+ }
+ }
+ return back;
+}
+#endif
+#endif
+#endif
+
diff --git a/support/dktools/dk3dbi.ctr b/support/dktools/dk3dbi.ctr
new file mode 100644
index 0000000000..1887ce2522
--- /dev/null
+++ b/support/dktools/dk3dbi.ctr
@@ -0,0 +1,2726 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Check whether a database type is supported.
+ @param tp Database type, see @ref databasetypes.
+ @return 1 on success (type supported), 0 on error (not supported).
+*/
+int
+dk3dbi_type_supported(int tp);
+
+/** Open a database.
+ @param fn Database file name.
+ @param tp Database type, see @ref databasetypes.
+ @param acc Access type, see @ref databaseaccess.
+ @param pec Pointer to error code variable, may be NULL.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to opened database on success, NULL on error.
+*/
+dk3_dbi_t *
+dk3dbi_open_app(dkChar const *fn, int tp, int acc, int *pec, dk3_app_t *app);
+
+/** Open a database.
+ @param fn Database file name.
+ @param tp Database type, see @ref databasetypes.
+ @param acc Access type, see @ref databaseaccess.
+ @param pec Pointer to error code variable, may be NULL.
+ @return Pointer to opened database on success, NULL on error.
+*/
+dk3_dbi_t *
+dk3dbi_open(dkChar const *fn, int tp, int acc, int *pec);
+
+/** Open a database, discard all existing contents.
+ @param fn Database file name.
+ @param tp Database type, see @ref databasetypes.
+ @param acc Access type, see @ref databaseaccess.
+ @param pec Pointer to error code variable, may be NULL.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to opened database on success, NULL on error.
+*/
+dk3_dbi_t *
+dk3dbi_open_truncate_app(
+ dkChar const *fn,
+ int tp,
+ int acc,
+ int *pec,
+ dk3_app_t *app
+);
+
+/** Open a database, discard all existing contents.
+ @param fn Database file name.
+ @param tp Database type, see @ref databasetypes.
+ @param acc Access type, see @ref databaseaccess.
+ @param pec Pointer to error code variable, may be NULL.
+ @return Pointer to opened database on success, NULL on error.
+*/
+dk3_dbi_t *
+dk3dbi_open_truncate(dkChar const *fn, int tp, int acc, int *pec);
+
+/** Set an entry in the database.
+ @param dbp Database.
+ @param key Key data.
+ @param val Value data.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_set(dk3_dbi_t *dbp, dk3_datum_t *key, dk3_datum_t *val);
+
+/** Get an entry from the database.
+ @param dbp Database.
+ @param key Key data.
+ @param val Value data, set up for a result buffer.
+ On input it contains the buffer size, on successful
+ return it contains the number of bytes.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_get(dk3_dbi_t *dbp, dk3_datum_t *key, dk3_datum_t *val);
+
+/** Delete an entry from the database.
+ @param dbp Database.
+ @param key Key data.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_delete(dk3_dbi_t *dbp, dk3_datum_t *key);
+
+/** Save 8-bit character string to database.
+ @param dbp Database.
+ @param key Key string.
+ @param val Value string.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_set_c8_string(
+ dk3_dbi_t *dbp,
+ char const *key,
+ char const *val
+);
+
+/** Retrieve 8-bit character string from database.
+ @param dbp Database.
+ @param key Key string.
+ @param vb Value buffer.
+ @param vbsz Value buffer size in bytes.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_get_c8_string(
+ dk3_dbi_t *dbp,
+ char const *key,
+ char *vb,
+ size_t vbsz
+);
+
+/** Delete 8-bit character string from database.
+ @param dbp Database.
+ @param key Key string.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_delete_c8_string(
+ dk3_dbi_t *dbp,
+ char const *key
+);
+
+/** Save 16-bit character string to database.
+ @param dbp Database.
+ @param key Key string.
+ @param val Value string.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_set_c16_string(
+ dk3_dbi_t *dbp,
+ dk3_c16_t const *key,
+ dk3_c16_t const *val
+);
+
+/** Retrieve 16-bit character string from database.
+ @param dbp Database.
+ @param key Key string.
+ @param vb Value buffer.
+ @param vbsz Value buffer size (number of 16-bit characters).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_get_c16_string(
+ dk3_dbi_t *dbp,
+ dk3_c16_t const *key,
+ dk3_c16_t *vb,
+ size_t vbsz
+);
+
+/** Delete 16-bit character string from database.
+ @param dbp Database.
+ @param key Key string.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_delete_c16_string(
+ dk3_dbi_t *dbp,
+ dk3_c16_t const *key
+);
+
+/** Save 32-bit character string to database.
+ @param dbp Database.
+ @param key Key string.
+ @param val Value string.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_set_c32_string(
+ dk3_dbi_t *dbp,
+ dk3_c32_t const *key,
+ dk3_c32_t const *val
+);
+
+/** Retrieve 32-bit character string from database.
+ @param dbp Database.
+ @param key Key string.
+ @param vb Value buffer.
+ @param vbsz Value buffer size (number of 32-bit characters).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_get_c32_string(
+ dk3_dbi_t *dbp,
+ dk3_c32_t const *key,
+ dk3_c32_t *vb,
+ size_t vbsz
+);
+
+/** Delete 32-bit character string from database.
+ @param dbp Database.
+ @param key Key string.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_delete_c32_string(
+ dk3_dbi_t *dbp,
+ dk3_c32_t const *key
+);
+
+/** Save a dkChar string to the database.
+ @param dbp Database.
+ @param key Key string.
+ @param val Value string.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_set_string(
+ dk3_dbi_t *dbp,
+ dkChar const *key,
+ dkChar const *val
+);
+
+/** Retrieve dkChar string from the database.
+ @param dbp Database.
+ @param key Key string.
+ @param vb Value buffer.
+ @param vbsz Size of value buffer (Number of dkChar).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_get_string(
+ dk3_dbi_t *dbp,
+ dkChar const *key,
+ dkChar *vb,
+ size_t vbsz
+);
+
+/** Delete dkChar string from database.
+ @param dbp Database.
+ @param key Key string.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_delete_string(
+ dk3_dbi_t *dbp,
+ dkChar const *key
+);
+
+/** Synchronize to disk.
+ @param dbp Database.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_sync(dk3_dbi_t *dbp);
+
+/** Traverse database.
+ @param dbp Database.
+ @param obj Object to modify while traversing the database.
+ @param fct Callback function to use for each key/value pair.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_traverse(dk3_dbi_t *dbp, void *obj, dk3_db_traverse_fct_t *fct);
+
+/** Get last error code occured.
+ @param dbp Database.
+ @param res Flag: Reset error code.
+ @return Error code for last error.
+*/
+int
+dk3dbi_get_error(dk3_dbi_t *dbp, int res);
+
+/** Close database.
+ @param dbp Database to close.
+ @return 1 on success (sync ok), 0 on error.
+*/
+int
+dk3dbi_close(dk3_dbi_t *dbp);
+
+/** Delete database file(s).
+ @param fn Database file name.
+ @param tp Database type.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_dbfile_delete_app(dkChar const *fn, int tp, dk3_app_t *app);
+
+/** Truncate database (remove all contents).
+ @param fn Database file name.
+ @param tp Database type.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_dbfile_truncate_app(dkChar const *fn, int tp, dk3_app_t *app);
+
+/** Delete database file(s).
+ @param fn Database file name.
+ @param tp Database type.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_dbfile_delete(dkChar const *fn, int tp);
+
+/** Truncate database (remove all contents).
+ @param fn Database file name.
+ @param tp Database type.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_dbfile_truncate(dkChar const *fn, int tp);
+
+/** Split a given name into database type and real file name.
+ The given name may be either a file name with tp set to a
+ database type or
+ "mem::file", "bdb::file", or "ndbm::file" to specify a file name
+ and database type with tp set to DK3_DB_TYPE_UNKNOWN.
+ @param myfn Pointer to a pointer to receive real file name.
+ @param mytp Pointer to type output variable.
+ @param fn File name or type::filename.
+ @param tp Type as specified.
+ @param pec Pointer to error code variable.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_find_type_and_name(
+ dkChar const **myfn,
+ int *mytp,
+ dkChar const *fn,
+ int tp,
+ int *pec,
+ dk3_app_t *app
+);
+
+
+#if !DK3_ON_WINDOWS
+#if DK3_CHAR_SIZE == 1
+#if DK3_HAVE_CHOWN && DK3_HAVE_CHMOD
+/** Change user name and permissions for a database.
+ This function is intended for daemons on *x systems where the daemon
+ is started by user root but gives up privileges before starting
+ processing.
+ @param db Database to change.
+ @param uid New user ID.
+ @param gid New group ID.
+ @param mode Unix/Linux permissions.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_change_user_and_permissions(
+ dk3_dbi_t *db,
+ uid_t uid,
+ gid_t gid,
+ mode_t mode
+);
+#endif
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk3all.h"
+#include "dk3dbi.h"
+
+#ifdef DK3_USE_DB
+#undef DK3_USE_DB
+#endif
+#ifdef DK3_USE_NDBM
+#undef DK3_USE_NDBM
+#endif
+
+#if DK3_HAVE_DB_H
+#include <db.h>
+/** Use Berkeley DB.
+*/
+#define DK3_USE_DB 1
+#endif
+
+#if DK3_HAVE_NDBM_H
+#include <ndbm.h>
+/** Use NDBM.
+*/
+#define DK3_USE_NDBM 1
+#endif
+
+
+$!trace-include
+
+
+
+/** Data type used in storage.
+*/
+typedef struct {
+ /** Key data.
+ */
+ void *keydata;
+ /** value data.
+ */
+ void *valdata;
+ /** Key size (number of bytes in key data).
+ */
+ size_t keysize;
+ /** Value size (number of bytes in value data).
+ */
+ size_t valsize;
+} dk3_dbi_node_t;
+
+
+
+
+/** Names of database types. Order must match the
+ definitions in @ref databasetypes.
+*/
+static dkChar const * const dk3dbi_type_names[] = {
+$!string-table macro=dkT
+#
+# 0: in-memory database
+#
+mem
+#
+# 1: Berkeley DB
+#
+bdb
+#
+# 2: NDBM
+#
+ndbm
+$!end
+};
+
+
+
+/** Modes to open file.
+*/
+static dkChar const * const dk3dbi_file_open_modes[] = {
+/* 0 */ dkT("rb"),
+/* 1 */ dkT("wb")
+};
+
+
+
+/** File name suffixes for NDBM files.
+*/
+static char const * const dk3dbi_ndbm_suffixes[] = {
+".dir", ".pag"
+};
+
+
+
+/** Delete one storage node, release memory.
+ @param np Node to delete.
+*/
+static
+void
+dk3dbi_node_delete(dk3_dbi_node_t *np)
+{
+ if(np) {
+ dk3_release(np->keydata);
+ dk3_release(np->valdata);
+ np->keydata = NULL; np->valdata = NULL;
+ np->keysize = 0; np->valsize = 0;
+ dk3_delete(np);
+ }
+}
+
+
+
+/** Create a new node with specified buffer sizes.
+ @param ks Keys size.
+ @param vs Value size.
+ @param app Application structure for diagnostics.
+ @return Pointer to new node on success, NULL on error.
+*/
+static
+dk3_dbi_node_t *
+dk3dbi_node_new(size_t ks, size_t vs, dk3_app_t *app)
+{
+ dk3_dbi_node_t *back = NULL;
+ char *cpk = NULL; /* Key buffer pointer. */
+ char *cpv = NULL; /* Value buffer pointer. */
+ int ok = 0; /* Flag: Success. */
+ $? "+ dk3dbi_node_new %u %u", (unsigned)ks, (unsigned)vs
+ back = dk3_new_app(dk3_dbi_node_t,1,app);
+ if(back) {
+ back->keysize = 0; back->valsize = 0;
+ back->keydata = NULL; back->valdata = NULL;
+ cpk = dk3_new_app(char,ks,app);
+ if(cpk) {
+ cpv = dk3_new_app(char,vs,app);
+ if(cpv) {
+ ok = 1;
+ back->keydata = (void *)cpk;
+ back->valdata = (void *)cpv;
+ back->keysize = ks;
+ back->valsize = vs;
+ }
+ }
+ if(!(ok)) {
+ dk3_delete(cpk);
+ dk3_delete(cpv);
+ dk3dbi_node_delete(back);
+ back = NULL;
+ }
+ } $? "- dk3dbi_node_new %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+/** Comparison of storage nodes.
+ @param l Left node.
+ @param r Right node.
+ @param cr Comparison criteria (0=node/node, 1=node/datum).
+ @return Comparison result.
+*/
+static
+int
+dk3dbi_node_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3_dbi_node_t const *pl; /* Left object pointer. */
+ dk3_dbi_node_t const *pr; /* Right object pointer. */
+ dk3_datum_t const *pd; /* Right object pointer (datum). */
+ if(l) {
+ if(r) {
+ pl = (dk3_dbi_node_t const *)l;
+ switch(cr) {
+ case 1: {
+ pd = (dk3_datum_t const *)r;
+ if(pl->keydata) {
+ if(pd->dt) {
+ if(pl->keysize > pd->sz) {
+ back = 1;
+ } else {
+ if(pl->keysize < pd->sz) {
+ back = -1;
+ } else {
+ back = dk3mem_cmp(pl->keydata, pd->dt, pl->keysize);
+ if(back < -1) back = -1;
+ if(back > 1) back = 1;
+ }
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(pd->dt) {
+ back = -1;
+ }
+ }
+ } break;
+ default: {
+ pr = (dk3_dbi_node_t const *)r;
+ if(pl->keydata) {
+ if(pr->keydata) {
+ if(pl->keysize > pr->keysize) {
+ back = 1;
+ } else {
+ if(pl->keysize < pr->keysize) {
+ back = -1;
+ } else {
+ back = dk3mem_cmp(pl->keydata, pr->keydata, pl->keysize);
+ if(back < -1) back = -1;
+ if(back > 1) back = 1;
+ }
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(pr->keydata) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Read in-memory database from file.
+ @param dbp Database to initialize.
+ @return 1 on success (even if there is not db file yet), 0 on error.
+*/
+static
+int
+dk3dbi_mem_read_file(dk3_dbi_t *dbp)
+{
+ unsigned char uc[8]; /* Buffer for key and value size. */
+ FILE *fipo; /* Input file. */
+ dk3_dbi_node_t *np; /* Node for record just read. */
+ unsigned char *kd; /* Key data buffer pointer. */
+ unsigned char *vd; /* Value data buffer pointer. */
+ dkChar const *oldsourcename; /* Previous source file name. */
+ unsigned long oldsourceline; /* Previous source file line. */
+ unsigned long ul1; /* Key size as unsigned long. */
+ unsigned long ul2; /* Value size as unsigned long. */
+ size_t nread; /* Number of bytes read from file. */
+ size_t ks; /* Key size. */
+ size_t vs; /* Value size. */
+ int ok = 0; /* Flag: Success. */
+ int back = 1;
+ int cc = 1; /* Flag: Can continue. */
+ $? "+ dk3dbi_mem_read_file"
+ oldsourcename = dk3app_get_source_file(dbp->app);
+ oldsourceline = dk3app_get_source_line(dbp->app);
+ dk3app_set_source_file(dbp->app, dbp->fn);
+ dk3app_set_source_line(dbp->app, 0UL);
+ fipo = dk3sf_fopen_app(dbp->fn, dk3dbi_file_open_modes[0], dbp->app);
+ if(fipo) {
+ while((cc) && (back)) {
+ cc = 0;
+ kd = vd = NULL;
+ nread = dk3sf_fread_app(uc, 1, 8, fipo, dbp->app);
+ if(nread > 0) {
+ if(nread == 8) {
+ ul1 = ((((unsigned long)(uc[0])) << 24) & 0xFF000000UL)
+ | ((((unsigned long)(uc[1])) << 16) & 0x00FF0000UL)
+ | ((((unsigned long)(uc[2])) << 8) & 0x0000FF00UL)
+ | (( (unsigned long)(uc[3]) ) & 0x000000FFUL);
+ ul2 = ((((unsigned long)(uc[4])) << 24) & 0xFF000000UL)
+ | ((((unsigned long)(uc[5])) << 16) & 0x00FF0000UL)
+ | ((((unsigned long)(uc[6])) << 8) & 0x0000FF00UL)
+ | (( (unsigned long)(uc[7]) ) & 0x000000FFUL);
+ ks = (size_t)ul1; vs = (size_t)ul2;
+ if(sizeof(size_t) < 4) {
+ if((ul1 > 0x0000FFFFUL) || (ul2 > 0x0000FFFFUL)) {
+ back = 0;
+ /* ERROR: Entry size too large! */
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 245);
+ }
+ }
+ if(back) {
+ kd = dk3_new_app(unsigned char,ks,dbp->app);
+ vd = dk3_new_app(unsigned char,vs,dbp->app);
+ if((kd) && (vd)) {
+ ok = 0;
+ nread = dk3sf_fread_app(kd, 1, ks, fipo, dbp->app);
+ if(nread == ks) {
+ nread = dk3sf_fread_app(vd, 1, vs, fipo, dbp->app);
+ if(nread == vs) {
+ np = dk3_new_app(dk3_dbi_node_t,1,dbp->app);
+ if(np) {
+ np->keydata = kd; np->valdata = vd;
+ np->keysize = ks; np->valsize = vs;
+ if(dk3sto_add((dbp->details).mem.s_mem, np)) {
+ cc = 1; ok = 1;
+ } else {
+ np->keydata = np->valdata = NULL;
+ np->keysize = np->valsize = 0;
+ dk3_delete(np);
+ np = NULL;
+ back = 0;
+ }
+ }
+ } else {
+ back = 0;
+ /* ERROR: File probably damaged! */
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 246);
+ }
+ } else {
+ back = 0;
+ /* ERROR: File probably damaged! */
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 246);
+ }
+ if(!(ok)) {
+ dk3_delete(kd);
+ dk3_delete(vd);
+ kd = vd = NULL;
+#if VERSION_BEFORE_20150821
+ ks = vs = 0;
+#endif
+ }
+ } else {
+ back = 0;
+ dk3_delete(kd);
+ dk3_delete(vd);
+ }
+ }
+ } else {
+ back = 0;
+ /* ERROR: File probably damaged! */
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 246);
+ }
+ } else {
+ /* End of file reached. */
+ }
+ }
+ fclose(fipo);
+ }
+ dk3app_set_source_file(dbp->app, oldsourcename);
+ dk3app_set_source_line(dbp->app, oldsourceline);
+ $? "- dk3dbi_mem_read_file %d", back
+ return back;
+}
+
+
+
+/** Synchronize memory database to file.
+ @param dbp Database.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dbi_mem_sync(dk3_dbi_t *dbp)
+{
+ unsigned char uc[8]; /* Buffer for key and value size. */
+ FILE *fipo; /* Output file. */
+ dk3_dbi_node_t *np; /* Current node to process. */
+ unsigned long ul1; /* Key size as unsigned long. */
+ unsigned long ul2; /* Value size as unsigned long. */
+ size_t nwrite; /* Number of bytes written. */
+ int back = 0;
+ $? "+ dk3dbi_mem_sync"
+ if(dbp->fn) { $? ". file name ok"
+ fipo = dk3sf_fopen_app(dbp->fn, dk3dbi_file_open_modes[1], dbp->app);
+ if(fipo) { $? ". file opened"
+ back = 1;
+ dk3sto_it_reset((dbp->details).mem.i_mem);
+ do {
+ np = (dk3_dbi_node_t *)dk3sto_it_next((dbp->details).mem.i_mem);
+ if(np) { $? ". yet another entry to write"
+ ul1 = (unsigned long)(np->keysize);
+ ul2 = (unsigned long)(np->valsize);
+ uc[0] = (unsigned char)((ul1 >> 24) & 0x000000FFUL);
+ uc[1] = (unsigned char)((ul1 >> 16) & 0x000000FFUL);
+ uc[2] = (unsigned char)((ul1 >> 8) & 0x000000FFUL);
+ uc[3] = (unsigned char)( ul1 & 0x000000FFUL);
+ uc[4] = (unsigned char)((ul2 >> 24) & 0x000000FFUL);
+ uc[5] = (unsigned char)((ul2 >> 16) & 0x000000FFUL);
+ uc[6] = (unsigned char)((ul2 >> 8) & 0x000000FFUL);
+ uc[7] = (unsigned char)( ul2 & 0x000000FFUL);
+ nwrite = dk3sf_fwrite_app(uc, 1, 8, fipo, dbp->app);
+ if(nwrite) { $? ". size written successfully"
+ nwrite = dk3sf_fwrite_app(np->keydata,1,np->keysize,fipo,dbp->app);
+ if(nwrite) { $? ". key written successfully"
+ nwrite =
+ dk3sf_fwrite_app(np->valdata,1,np->valsize,fipo,dbp->app);
+ if(!(nwrite)) { $? ". value written"
+ back = 0;
+ dbp->ec = DK3_ERROR_DURING_WRITE;
+ }
+ } else { $? "! failed to write key"
+ back = 0;
+ dbp->ec = DK3_ERROR_DURING_WRITE;
+ }
+ } else { $? "! error while writing sizes"
+ back = 0;
+ dbp->ec = DK3_ERROR_DURING_WRITE;
+ }
+ }
+ } while((np) && (back));
+ if(!dk3sf_fclose_fn_app(fipo, dbp->fn, dbp->app)) {
+ back = 0;
+ }
+ } else { $? "! failed to open file"
+ dbp->ec = DK3_ERROR_NOT_OPENED_FOR_WRITING;
+ }
+ } else {
+ /* BUG: No file name, must not happen! */
+ } $? "- dk3dbi_mem_sync %d", back
+ return back;
+}
+
+
+
+/** Set entry (in-memory database).
+ @param dbp Database.
+ @param key Key data.
+ @param val Value data.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dbi_mem_set(dk3_dbi_t *dbp, dk3_datum_t *key, dk3_datum_t *val)
+{
+ int back = 0;
+ dk3_dbi_node_t *np; /* Current node to process. */
+ unsigned char *nb; /* New value buffer for node. */
+ $? "+ dk3dbi_mem_set"
+ np = (dk3_dbi_node_t *)dk3sto_it_find_like(
+ (dbp->details).mem.i_mem, (void *)key, 1
+ );
+ if(np) { $? ". modify existing entry"
+ nb = dk3_new_app(unsigned char,val->sz,dbp->app);
+ if(nb) {
+ dk3mem_cpy(nb, val->dt, val->sz);
+ dk3_release(np->valdata);
+ np->valdata = nb;
+ np->valsize = val->sz;
+ back = 1; $? ". success"
+ } else {
+ dbp->ec = DK3_ERROR_MEMORY;
+ }
+ } else { $? ". create new entry"
+ np = dk3dbi_node_new(key->sz, val->sz, dbp->app);
+ if(np) {
+ dk3mem_cpy(np->keydata, key->dt, key->sz);
+ dk3mem_cpy(np->valdata, val->dt, val->sz);
+ np->keysize = key->sz;
+ np->valsize = val->sz;
+ if(dk3sto_add((dbp->details).mem.s_mem, (void *)np)) {
+ back = 1; $? ". success"
+ } else {
+ dk3dbi_node_delete(np);
+ dbp->ec = DK3_ERROR_MEMORY;
+ }
+ } else {
+ dbp->ec = DK3_ERROR_MEMORY;
+ }
+ } $? "- dk3dbi_mem_set %d", back
+ return back;
+}
+
+
+
+/** Retrieve entry (in-memory database).
+ @param dbp Database.
+ @param key Key data.
+ @param val Value data (input: result buffer size, output:
+ buffer size used).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dbi_mem_get(dk3_dbi_t *dbp, dk3_datum_t *key, dk3_datum_t *val)
+{
+ int back = 0;
+ dk3_dbi_node_t *np; /* Current node to process. */
+ $? "+ dk3dbi_mem_get"
+ np = (dk3_dbi_node_t *)dk3sto_it_find_like(
+ (dbp->details).mem.i_mem, (void *)key, 1
+ );
+ if(np) { $? ". found"
+ if(val->sz >= np->valsize) {
+ dk3mem_cpy(val->dt, np->valdata, np->valsize);
+ val->sz = np->valsize;
+ back = 1; $? ". success"
+ } else { $? "! result buffer too small"
+ }
+ } else { $? "! not found"
+ if(dbp->rfk) {
+ if(dbp->app) {
+ /* ERROR: Entry not found! */
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 249);
+ }
+ }
+ }
+ $? "- dk3dbi_mem_get %d", back
+ return back;
+}
+
+
+
+/** Delete entry (in-memory database).
+ @param dbp Database.
+ @param key Key data.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dbi_mem_delete(dk3_dbi_t *dbp, dk3_datum_t *key)
+{
+ dk3_dbi_node_t *np; /* Current node to process .*/
+ int back = 1;
+ $? "+ dk3dbi_mem_delete"
+ np = (dk3_dbi_node_t *)dk3sto_it_find_like(
+ (dbp->details).mem.i_mem, (void *)key, 1
+ );
+ if(np) {
+ dk3sto_remove((dbp->details).mem.s_mem, (void *)np);
+ dk3dbi_node_delete(np);
+ } $? "- dk3dbi_mem_delete"
+ return back;
+}
+
+
+
+/** Traverse database (in-memory database).
+ @param dbp Database.
+ @param obj Object to modify during traversal.
+ @param fct Function to invoke for each key/value pair.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dbi_mem_traverse(dk3_dbi_t *dbp, void *obj, dk3_db_traverse_fct_t *fct)
+{
+ dk3_datum_t key; /* Key data. */
+ dk3_datum_t val; /* Value data. */
+ dk3_dbi_node_t *np; /* Current node to process. */
+ int back = 1;
+ int res = 1; /* Function result for current node. */
+ $? "+ dk3dbi_mem_traverse"
+ dk3sto_it_reset((dbp->details).mem.i_mem);
+ do {
+ np = (dk3_dbi_node_t *)dk3sto_it_next((dbp->details).mem.i_mem);
+ if(np) {
+ key.sz = np->keysize;
+ key.dt = np->keydata;
+ val.sz = np->valsize;
+ val.dt = np->valdata;
+ res = (*fct)(obj, &key, &val);
+ if(res < 1) { $? "! problem for record"
+ back = 0;
+ }
+ }
+ } while((np) && (res >= 0));
+ $? "- dk3dbi_mem_traverse %d", back
+ return back;
+}
+
+
+#if DK3_USE_DB
+/** Open Berkeley DB file.
+ @param dbp Database.
+ @param trunc Flag: Truncate database.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dbi_bdb_open_file(dk3_dbi_t *dbp, int trunc)
+{
+ char fnb[DK3_MAX_PATH]; /* File name buffer, 8-bit chars. */
+ DB *db = NULL; /* BDB. */
+ u_int32_t flags = 0UL; /* Flags to open BDB. */
+ int back = 0;
+ int ret; /* BDB operation result. */
+ $? "+ dk3dbi_bdb_open_file"
+ if(dk3sf_filename_to_c8(fnb, sizeof(fnb), dbp->fn, dbp->app)) {
+ ret = db_create(&db, NULL, 0);
+ if(ret == 0) {
+ db->set_errfile(db, NULL);
+ flags = DB_RDONLY;
+ if(dbp->wr) {
+ flags = DB_CREATE;
+ if(trunc) {
+ flags |= DB_TRUNCATE;
+ }
+ }
+ ret = db->open(db, NULL, fnb, NULL, DB_BTREE, flags, 0600);
+ if(ret == 0) {
+ back = 1;
+ (dbp->details).bdb.dbptr = (void *)db;
+ } else {
+ db->close(db, 0);
+ }
+ } else {
+ /* ERROR: Failed to create database */
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 9);
+ }
+ } else {
+ /* ERROR: File name conversion failed! */
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ } $? "- dk3dbi_bdb_open_file %d", back
+ return back;
+}
+
+/** Set entry (Berkeley DB).
+ @param dbp Database.
+ @param key Key data.
+ @param val Value data.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dbi_bdb_set(dk3_dbi_t *dbp, dk3_datum_t *key, dk3_datum_t *val)
+{
+ DBT k; /* Key datum. */
+ DBT v; /* Value datum. */
+ DB *db; /* BDB structure. */
+ int res; /* BDB operation result. */
+ int back = 0;
+ $? "+ dk3dbi_bdb_set"
+ db = (DB *)((dbp->details).bdb.dbptr);
+ dk3mem_res((void *)(&k), sizeof(DBT));
+ dk3mem_res((void *)(&v), sizeof(DBT));
+ k.data = key->dt; k.size = key->sz;
+ v.data = val->dt; v.size = val->sz;
+ db->del(db, NULL, &k, 0);
+ dk3mem_res((void *)(&k), sizeof(DBT));
+ k.data = key->dt; k.size = key->sz;
+ res = db->put(db, NULL, &k, &v, 0);
+ if(res == 0) {
+ back = 1;
+ } $? "- dk3dbi_bdb_set %d", back
+ return back;
+}
+
+/** Retrieve entry (Berkeley DB).
+ @param dbp Database.
+ @param key Key data.
+ @param val Value data (input: result buffer size, output:
+ buffer size used).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dbi_bdb_get(dk3_dbi_t *dbp, dk3_datum_t *key, dk3_datum_t *val)
+{
+ DBT k; /* Key datum. */
+ DBT v; /* Value datum. */
+ DB *db; /* BDB structure. */
+ int res; /* BDB operation result. */
+ int back = 0;
+ $? "+ dk3dbi_bdb_get"
+ db = (DB *)((dbp->details).bdb.dbptr);
+ dk3mem_res((void *)(&k), sizeof(DBT));
+ dk3mem_res((void *)(&v), sizeof(DBT));
+ k.data = key->dt; k.size = key->sz;
+ v.data = val->dt; v.ulen = val->sz; v.flags = DB_DBT_USERMEM;
+ res = db->get(db, NULL, &k, &v, 0);
+ if(res == 0) {
+ back = 1;
+ val->sz = v.size;
+ } else {
+ if(dbp->rfk) {
+ if(dbp->app) {
+ /* ERROR: Entry not found! */
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 249);
+ }
+ }
+ } $? "- dk3dbi_bdb_get %d", back
+ return back;
+}
+
+/** Delete entry (Berkeley DB).
+ @param dbp Database.
+ @param key Key data.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dbi_bdb_delete(dk3_dbi_t *dbp, dk3_datum_t *key)
+{
+ DBT k; /* Key datum. */
+ DB *db; /* BDB structure. */
+ int res; /* BDB operation result. */
+ int back = 0;
+ $? "+ dk3dbi_bdb_delete"
+ db = (DB *)((dbp->details).bdb.dbptr);
+ dk3mem_res((void *)(&k), sizeof(DBT));
+ k.data = key->dt; k.size = key->sz;
+ res = db->del(db, NULL, &k, 0);
+ if(res == 0) {
+ back = 1;
+ } $? "- dk3dbi_bdb_delete %d", back
+ return back;
+}
+
+/** Traverse database (Berkeley DB).
+ @param dbp Database.
+ @param obj Object to modify during traversal.
+ @param fct Function to invoke for each key/value pair.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dbi_bdb_traverse(dk3_dbi_t *dbp, void *obj, dk3_db_traverse_fct_t *fct)
+{
+ DBT k; /* Key datum (BDB). */
+ DBT v; /* Value datum (BDB). */
+ dk3_datum_t key; /* Key datum (dk3dbi). */
+ dk3_datum_t val; /* Vaue datum (dk3dbi). */
+ DB *db; /* BDB structure. */
+ DBC *cp = NULL; /* BDB cursor. */
+ int res; /* BDB operation result. */
+ int cc; /* Flag: Can continue. */
+ int isfirst; /* Flag: No record received yet. */
+ int back = 0;
+ $? "+ dk3dbi_bdb_traverse"
+ db = (DB *)((dbp->details).bdb.dbptr);
+ res = db->cursor(db, NULL, &cp, 0);
+ if(res == 0) { $? ". cursor created"
+ if(cp) { $? ". cursor ok"
+#if VERSION_BEFORE_20150821
+ cc = 1;
+#endif
+ back = 1;
+ isfirst = 1;
+ dk3mem_res((void *)(&k), sizeof(DBT));
+ dk3mem_res((void *)(&v), sizeof(DBT));
+ do { $? ". yet another attempt"
+ cc = 0;
+#if DK3_HAVE_DB_CURSOR_C_GET
+ /* 2011-10-23: c_get() not in current documentation of BDB. */
+ res = cp->c_get(cp, &k, &v, ((isfirst) ? (DB_FIRST) : (DB_NEXT)));
+#else
+ if(isfirst) { $? ". first attempt"
+ res = cp->get(cp, &k, &v, DB_FIRST);
+ } else { $? ". not first"
+ res = cp->get(cp, &k, &v, DB_NEXT);
+ }
+#endif
+ isfirst = 0;
+ if(res == 0) { $? ". record found"
+ cc = 1;
+ key.dt = k.data; key.sz = k.size;
+ val.dt = v.data; val.sz = v.size;
+ res = (*fct)(obj, &key, &val);
+ switch(res) {
+ case 0: { $? ". processing failed, continue"
+ back = 0;
+ } break;
+ case -1: { $? ". processing failed, abort"
+ back = 0; cc = 0;
+ } break;
+ }
+ } else { $? ". no record"
+#if VERSION_BEFORE_20150821
+ cc = 0;
+#endif
+ if(res != DB_NOTFOUND) { $? ". error"
+ back = 0;
+ }
+ }
+ } while(cc);
+ cp->c_close(cp);
+ } else { $? "! failed to create cursor"
+ }
+ } else { $? "! failed to create cursor"
+ }
+ if(cp) {
+ cp->c_close(cp);
+ } $? "- dk3dbi_bdb_traverse %d", back
+ return back;
+}
+
+#endif
+
+#if DK3_USE_NDBM
+
+/** Open NDBM database file.
+ @param dbp Database.
+ @param trunc Flag: Truncate database.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dbi_ndbm_open_file(dk3_dbi_t *dbp, int trunc)
+{
+ DBM *dbm = NULL; /* NDBM structure. */
+ int back = 0;
+ int omode = 0; /* Output file mode. */
+ $? "+ dk3dbi_ndbm_open_file trunc=%d", trunc
+ omode = O_CREAT;
+ if(dbp->wr) { $? ". want to write"
+ omode |= O_RDWR;
+ if(trunc) { $? ". allow truncate"
+ omode |= O_TRUNC;
+ }
+ } else { $? ". read only"
+ omode |= O_RDONLY;
+ } $? ". fn = \"%!ds\"", TR_STR(dbp->fn)
+ dbm = dbm_open(dbp->fn, omode, 0600);
+ if(dbm) { $? ". dbm_open"
+ (dbp->details).ndbm.dbptr = (void *)dbm;
+ back = 1;
+ } else { $? "! dbm_open"
+ } $? "- dk3dbi_ndbm_open_file %d", back
+ return back;
+}
+
+/** Set entry (NDBM).
+ @param dbp Database.
+ @param key Key data.
+ @param val Value data.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dbi_ndbm_set(dk3_dbi_t *dbp, dk3_datum_t *key, dk3_datum_t *val)
+{
+ datum k; /* Key datum. */
+ datum v; /* Value datum. */
+ DBM *dbm; /* NDBM structure. */
+ int res; /* Operation result. */
+ int back = 0;
+ $? "+ dk3dbi_ndbm_set"
+ dbm = (DBM *)((dbp->details).ndbm.dbptr);
+ dk3mem_res((void *)(&k),sizeof(datum));
+ dk3mem_res((void *)(&v),sizeof(datum));
+ k.dptr = key->dt; k.dsize = key->sz; v.dptr = val->dt; v.dsize = val->sz;
+ res = dbm_store(dbm, k, v, DBM_INSERT);
+ if(res == 0) {
+ back = 1;
+ } else {
+ dk3mem_res((void *)(&k),sizeof(datum));
+ dk3mem_res((void *)(&v),sizeof(datum));
+ k.dptr = key->dt; k.dsize = key->sz; v.dptr = val->dt; v.dsize = val->sz;
+ res = dbm_store(dbm, k, v, DBM_REPLACE);
+ if(res == 0) {
+ back = 1;
+ }
+ } $? "- dk3dbi_ndbm_set %d", back
+ return back;
+}
+
+/** Retrieve entry (NDBM).
+ @param dbp Database.
+ @param key Key data.
+ @param val Value data (input: result buffer size, output:
+ buffer size used).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dbi_ndbm_get(dk3_dbi_t *dbp, dk3_datum_t *key, dk3_datum_t *val)
+{
+ datum k; /* Key datum. */
+ datum v; /* Value datum. */
+ DBM *dbm; /* NDBM structure. */
+ int back = 0;
+ $? "+ dk3dbi_ndbm_get"
+ dbm = (DBM *)((dbp->details).ndbm.dbptr);
+ dk3mem_res((void *)(&k), sizeof(datum));
+ k.dptr = key->dt; k.dsize = key->sz;
+ v = dbm_fetch(dbm, k);
+ if((v.dptr) && (v.dsize)) {
+ if(v.dsize <= val->sz) {
+ dk3mem_cpy(val->dt, v.dptr, v.dsize);
+ val->sz = v.dsize;
+ back = 1;
+ }
+ } else {
+ if(dbp->rfk) {
+ if(dbp->app) {
+ /* ERROR: Entry not found! */
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 249);
+ }
+ }
+ } $? "- dk3dbi_ndbm_get %d", back
+ return back;
+}
+
+/** Delete entry (NDBM).
+ @param dbp Database.
+ @param key Key data.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dbi_ndbm_delete(dk3_dbi_t *dbp, dk3_datum_t *key)
+{
+ datum k; /* Key datum. */
+ DBM *dbm; /* NDBM structure. */
+ int back = 0;
+ $? "+ dk3dbi_ndbm_delete"
+ dbm = (DBM *)((dbp->details).ndbm.dbptr);
+ dk3mem_res((void *)(&k),sizeof(datum));
+ k.dptr = key->dt; k.dsize = key->sz;
+ if(dbm_delete(dbm, k) == 0) {
+ back = 1;
+ } $? "- dk3dbi_ndbm_delete %d", back
+ return back;
+}
+
+/** Traverse database (NDBM).
+ @param dbp Database.
+ @param obj Object to modify during traversal.
+ @param fct Function to invoke for each key/value pair.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dbi_ndbm_traverse(dk3_dbi_t *dbp, void *obj, dk3_db_traverse_fct_t *fct)
+{
+ datum k; /* Key datum (NDBM). */
+ datum v; /* Value datum (NDBM). */
+ dk3_datum_t key; /* Key datum (dk3dbi). */
+ dk3_datum_t val; /* Value datum (dk3dbi). */
+ DBM *dbm; /* NDBM structure. */
+ int isfirst = 1; /* Flag: No record received yet. */
+ int cc; /* Flag: Can continue. */
+ int res; /* Operation result. */
+ int back = 1;
+ $? "+ dk3dbi_ndbm_traverse"
+ dbm = (DBM *)((dbp->details).ndbm.dbptr);
+ cc = 1;
+ do {
+ cc = 0;
+ if(isfirst) {
+ k = dbm_firstkey(dbm);
+ } else {
+ k = dbm_nextkey(dbm);
+ }
+ isfirst = 0;
+ if((k.dptr) && (k.dsize)) {
+ v = dbm_fetch(dbm, k);
+ if((v.dptr) && (v.dsize)) {
+ cc = 1;
+ key.dt = k.dptr;
+ key.sz = k.dsize;
+ val.dt = v.dptr;
+ val.sz = v.dsize;
+ res = (*fct)(obj, &key, &val);
+ switch(res) {
+ case 0: {
+ back = 0; $? ". res = 0"
+ } break;
+ case -1: {
+ back = 0; cc = 0; $? ". res = -1"
+ } break;
+ }
+ }
+ }
+ } while(cc);
+ $? "- dk3dbi_ndbm_traverse %d", back
+ return back;
+}
+
+#endif
+
+
+
+int
+dk3dbi_type_supported(int tp)
+{
+ int back = 0;
+ $? "+ dk3dbi_type_supported %d", tp
+ switch(tp) {
+ case DK3_DB_TYPE_MEMORY:
+ {
+ back = 1;
+ } break;
+ case DK3_DB_TYPE_BDB: {
+#if DK3_USE_DB
+ back = 1;
+#endif
+ } break;
+ case DK3_DB_TYPE_NDBM: {
+#if DK3_USE_NDBM
+ back = 1;
+#endif
+ } break;
+ } $? "- dk3dbi_type_supported %d", back
+ return back;
+}
+
+
+
+/** If no type is specified use best available database type.
+ @return Best available database type.
+*/
+static
+int
+dk3dbi_choose_best_available_type(void)
+{
+ int back = DK3_DB_TYPE_MEMORY;
+ $? "+ dk3dbi_choose_best_available_type"
+#if DK3_USE_DB
+ back = DK3_DB_TYPE_BDB;
+#else
+#if DK3_USE_NDBM
+ back = DK3_DB_TYPE_NDBM;
+#endif
+#endif
+ $? "- dk3dbi_choose_best_available_type %d", back
+ return back;
+}
+
+
+
+/** Internal function to close the database.
+ @param dbp Database to close.
+*/
+static
+void
+dk3dbi_close_internal(dk3_dbi_t *dbp)
+{
+ dk3_dbi_node_t *np; /* Current node to process. */
+ $? "+ dk3dbi_close_internal"
+ if(dbp) {
+ switch(dbp->tp) {
+ case DK3_DB_TYPE_MEMORY: {
+ if((dbp->details).mem.s_mem) {
+ if((dbp->details).mem.i_mem) {
+ dk3sto_it_reset((dbp->details).mem.i_mem);
+ do {
+ np = (dk3_dbi_node_t *)dk3sto_it_next((dbp->details).mem.i_mem);
+ if(np) {
+ dk3dbi_node_delete(np);
+ }
+ } while(np);
+ dk3sto_it_close((dbp->details).mem.i_mem);
+ }
+ dk3sto_close((dbp->details).mem.s_mem);
+ }
+ (dbp->details).mem.s_mem = NULL;
+ } break;
+ case DK3_DB_TYPE_BDB: {
+#if DK3_USE_DB
+ DB *db;
+ if((dbp->details).bdb.dbptr) {
+ db = (DB *)((dbp->details).bdb.dbptr);
+ db->close(db, 0);
+ (dbp->details).bdb.dbptr = NULL;
+ }
+#endif
+ } break;
+ case DK3_DB_TYPE_NDBM: {
+#if DK3_USE_NDBM
+ DBM *dbm;
+ if((dbp->details).ndbm.dbptr) {
+ dbm = (DBM *)((dbp->details).ndbm.dbptr);
+ dbm_close(dbm);
+ (dbp->details).ndbm.dbptr = NULL;
+ }
+#endif
+ } break;
+ }
+ dbp->app = NULL;
+ if(dbp->fn) {
+ dk3_delete(dbp->fn);
+ }
+ dbp->fn = NULL;
+ dk3_delete(dbp);
+ } $? "- dk3dbi_close_internal"
+}
+
+
+
+/** Synchronize database (write all modifications to file).
+ @param dbp Database.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dbi_sync_internal(dk3_dbi_t *dbp)
+{
+ int back = 0;
+ $? "+ dk3dbi_sync_internal"
+ switch(dbp->tp) {
+ case DK3_DB_TYPE_MEMORY: {
+ back = dk3dbi_mem_sync(dbp);
+ } break;
+ case DK3_DB_TYPE_BDB: {
+#if DK3_USE_DB
+ DB *db;
+ db = (DB *)((dbp->details).bdb.dbptr);
+ if(db->sync(db, 0) == 0) {
+ back = 1;
+ }
+#endif
+ } break;
+ case DK3_DB_TYPE_NDBM: {
+#if DK3_USE_NDBM
+ /* There is no sync function! */
+ dbp->ec = DK3_ERROR_NOT_SUPPORTED;
+#endif
+ } break;
+ } $? "- dk3dbi_sync_internal %d", back
+ return back;
+}
+
+
+
+/** Open a database if the type is known.
+ This function is invoked with the real file name
+ and a known database type.
+ @param fn File name.
+ @param tp Database type.
+ @param acc Access type DK3_DB_ACCESS_xxx,
+ see @ref databaseaccess.
+ @param pec Pointer to variable for error codes, may be NULL.
+ @param app Application structure for diagnostics, may be NULL.
+ @param trunc Flag: Truncate database.
+ @return Pointer to database structure on success, NULL on error.
+*/
+static
+dk3_dbi_t *
+dk3dbi_open_app_with_tp(
+ dkChar const *fn,
+ int tp,
+ int acc,
+ int *pec,
+ dk3_app_t *app,
+ int trunc
+)
+{
+ dk3_dbi_t *back = NULL;
+ int ok = 0; /* Flag: Success. */
+ $? "+ dk3dbi_open_app_with_tp trunc=%d", trunc
+ back = dk3_new_app(dk3_dbi_t,1,app);
+ if(back) {
+ back->ec = 0;
+ back->rfk = 0;
+ back->wr = ((acc != DK3_DB_ACCESS_READ) ? 1 : 0);
+ back->app = app;
+ back->fn = NULL;
+ back->tp = tp;
+ back->mod = 0;
+ back->fn = dk3str_dup_app(fn, app);
+ if(back->fn) {
+ switch(tp) {
+ case DK3_DB_TYPE_MEMORY: {
+ (back->details).mem.s_mem = NULL;
+ (back->details).mem.i_mem = NULL;
+ (back->details).mem.s_mem = dk3sto_open_app(app);
+ if((back->details).mem.s_mem) {
+ dk3sto_set_comp(
+ (back->details).mem.s_mem,
+ dk3dbi_node_compare,
+ 0
+ );
+ (back->details).mem.i_mem = dk3sto_it_open(
+ (back->details).mem.s_mem
+ );
+ if((back->details).mem.i_mem) {
+ if(!(trunc)) {
+ ok = dk3dbi_mem_read_file(back);
+ } else {
+ ok = 1;
+ }
+ }
+ }
+ } break;
+ case DK3_DB_TYPE_BDB: {
+#if DK3_USE_DB
+ (back->details).bdb.dbptr = NULL; $? ". use bdb"
+ ok = dk3dbi_bdb_open_file(back, trunc);
+#else
+ if(pec) { *pec = DK3_ERROR_NOT_SUPPORTED; }
+ if(app) {
+ /* ERROR: Database type not supported! */
+ dk3app_log_i3(
+ app, DK3_LL_ERROR, 247, 248, dk3dbi_type_names[1]
+ );
+ }
+#endif
+ } break;
+ case DK3_DB_TYPE_NDBM: {
+#if DK3_USE_NDBM
+ (back->details).ndbm.dbptr = NULL; $? ". use ndbm"
+ ok = dk3dbi_ndbm_open_file(back, trunc);
+#else
+ if(pec) { *pec = DK3_ERROR_NOT_SUPPORTED; } $? "! no ndbm support"
+ if(app) {
+ /* ERROR: Database type not supported! */
+ dk3app_log_i3(
+ app, DK3_LL_ERROR, 247, 248, dk3dbi_type_names[2]
+ );
+ }
+#endif
+ } break;
+ }
+ } else {
+ if(pec) { *pec = DK3_ERROR_MEMORY; }
+ }
+ if(!(ok)) {
+ dk3dbi_close_internal(back);
+ back = NULL;
+ }
+ } $? "- dk3dbi_open_app_with_tp %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+int
+dk3dbi_find_type_and_name(
+ dkChar const **myfn,
+ int *mytp,
+ dkChar const *fn,
+ int tp,
+ int *pec,
+ dk3_app_t *app
+)
+{
+ dkChar *p1; /* Start of real file name. */
+ int back = 0;
+ $? "+ dk3dbi_find_type_and_name \"%!ds\"", TR_STR(fn)
+ *mytp = tp;
+ p1 = dk3str_chr(fn, dkT(':'));
+ if(p1) { $? ". one colon in name"
+ if(p1[1] == dkT(':')) { $? ". two colons in name"
+ *(p1++) = dkT('\0');
+ p1++;
+ *myfn = p1;
+ *mytp = dk3str_array_index(dk3dbi_type_names, fn, 0);
+ if(*mytp >= 0) { $? ". database type found"
+ if(dk3dbi_type_supported(*mytp)) {
+ back = 1;
+ } else { $? "! database type not supported"
+ if(app) {
+ /* ERROR: Database type not supported! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 247, 248, fn);
+ }
+ if(pec) {
+ *pec = DK3_ERROR_NOT_SUPPORTED;
+ }
+ }
+ } else { $? "! database type not found"
+ if(app) {
+ /* ERROR: Database type not found! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 247, 248, fn);
+ }
+ if(pec) {
+ *pec = DK3_ERROR_INVALID_ARGS;
+ }
+ }
+ } else { $? ". one colon in name"
+ /* Single colon */
+ *myfn = fn;
+ if(tp < 0) {
+ *mytp = dk3dbi_choose_best_available_type();
+ }
+ back = 1;
+ }
+ } else { $? ". no colon in name"
+ /* No colon found */
+ *myfn = fn;
+ if(tp < 0) {
+ *mytp = dk3dbi_choose_best_available_type();
+ }
+ back = 1;
+ }
+ if(back) {
+ if(*mytp >= 0) {
+ if(!dk3dbi_type_supported(*mytp)) {
+ back = 0;
+ if(app) {
+ /* ERROR: Database type not supported! */
+ }
+ if(pec) {
+ *pec = DK3_ERROR_NOT_SUPPORTED;
+ }
+ }
+ } else {
+ back = 0;
+ }
+ } $? "- dk3dbi_find_type_and_name %d", back
+ return back;
+}
+
+
+
+/** Open a database.
+ @param fn File name.
+ @param tp Database type.
+ @param acc Access type.
+ @param pec Pointer to error code variable.
+ @param app Application structure for diagnostics, may be NULL.
+ @param trunc Flag: Truncate database.
+ @return Pointer to new database on success, NULL on error.
+*/
+static
+dk3_dbi_t *
+dk3dbi_open_internal(
+ dkChar const *fn,
+ int tp,
+ int acc,
+ int *pec,
+ dk3_app_t *app,
+ int trunc
+)
+{
+ dkChar fnb[DK3_MAX_PATH + 16]; /* File name buffer. */
+ dk3_dbi_t *back = NULL;
+ dkChar const *myfn = NULL; /* Real file name. */
+ int mytp = DK3_DB_TYPE_UNKNOWN; /* Database type. */
+ $? "+ dk3dbi_open_internal \"%!ds\"", TR_STR(fn)
+ if(fn) { $? ". fn found"
+ if(dk3str_len(fn) < DK3_SIZEOF(fnb,dkChar)) { $? ". length ok"
+ dk3str_cpy_not_overlapped(fnb, fn);
+ if(dk3dbi_find_type_and_name(&myfn ,&mytp, fnb, tp, pec, app))
+ { $? ". type found"
+ if((myfn) && (mytp >= 0)) { $? ". results ok"
+ back = dk3dbi_open_app_with_tp(myfn, mytp, acc, pec, app, trunc);
+ } else { $? "! results"
+ /* BUG: Must not happen! */
+ }
+ }
+ } else { $? "! fn too long"
+ if(app) {
+ /* ERROR: File name too long! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 65, 66, fn);
+ }
+ if(pec) {
+ *pec = DK3_ERROR_INVALID_ARGS;
+ }
+ }
+ } else { $? "! fn"
+ } $? "- dk3dbi_open_internal %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+dk3_dbi_t *
+dk3dbi_open_app(
+ dkChar const *fn,
+ int tp,
+ int acc,
+ int *pec,
+ dk3_app_t *app
+)
+{
+ dk3_dbi_t *back;
+ back = dk3dbi_open_internal(fn, tp, acc, pec, app, 0);
+ return back;
+}
+
+
+
+dk3_dbi_t *
+dk3dbi_open_truncate_app(
+ dkChar const *fn,
+ int tp,
+ int acc,
+ int *pec,
+ dk3_app_t *app
+)
+{
+ dk3_dbi_t *back;
+ $? "+ dk3dbi_open_truncate_app \"%!ds\"", TR_STR(fn)
+ back = dk3dbi_open_internal(fn, tp, acc, pec, app, 1);
+ $? "- dk3dbi_open_truncate_app %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+dk3_dbi_t *
+dk3dbi_open(dkChar const *fn, int tp, int acc, int *pec)
+{
+ dk3_dbi_t *back = NULL;
+ $? "+ dk3dbi_open"
+ back = dk3dbi_open_app(fn, tp, acc, pec, NULL);
+ $? "- dk3dbi_open"
+ return back;
+}
+
+
+
+dk3_dbi_t *
+dk3dbi_open_truncate(dkChar const *fn, int tp, int acc, int *pec)
+{
+ dk3_dbi_t *back;
+ back = dk3dbi_open_truncate_app(fn, tp, acc, pec, NULL);
+ return back;
+}
+
+
+
+int
+dk3dbi_close(dk3_dbi_t *dbp)
+{
+ int back = 0;
+ $? "+ dk3dbi_close"
+ if(dbp) {
+ back = 1;
+ if(dbp->mod) { $? ". must sync"
+ back = dk3dbi_sync_internal(dbp);
+ }
+ dk3dbi_close_internal(dbp);
+ } $? "- dk3dbi_close %d", back
+ return back;
+}
+
+
+
+int
+dk3dbi_set(dk3_dbi_t *dbp, dk3_datum_t *key, dk3_datum_t *val)
+{
+ int back = 0;
+ $? "+ dk3dbi_set"
+ if((dbp) && (key) && (val)) {
+ if((key->dt) && (key->sz) && (val->dt) && (val->sz)) {
+ if(dbp->wr) {
+ switch(dbp->tp) {
+ case DK3_DB_TYPE_MEMORY: {
+ back = dk3dbi_mem_set(dbp, key, val);
+ dbp->mod = 1;
+ } break;
+ case DK3_DB_TYPE_BDB: {
+#if DK3_USE_DB
+ back = dk3dbi_bdb_set(dbp, key, val);
+ dbp->mod = 1;
+#endif
+ } break;
+ case DK3_DB_TYPE_NDBM: {
+#if DK3_USE_NDBM
+ back = dk3dbi_ndbm_set(dbp, key, val);
+ dbp->mod = 1;
+#endif
+ } break;
+ }
+ } else {
+ /* ERROR: Write operations denied! */
+ dbp->ec = DK3_ERROR_NOT_OPENED_FOR_WRITING;
+ if(dbp->app) {
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 251);
+ }
+ }
+ } else {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ } else {
+ if(dbp) {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ } $? "- dk3dbi_set %d", back
+ return back;
+}
+
+
+
+int
+dk3dbi_get(dk3_dbi_t *dbp, dk3_datum_t *key, dk3_datum_t *val)
+{
+ int back = 0;
+ $? "+ dk3dbi_get"
+ if((dbp) && (key) && (val)) {
+ if((key->dt) && (key->sz) && (val->dt) && (val->sz)) {
+ switch(dbp->tp) {
+ case DK3_DB_TYPE_MEMORY: {
+ back = dk3dbi_mem_get(dbp, key, val);
+ } break;
+ case DK3_DB_TYPE_BDB: {
+#if DK3_USE_DB
+ back = dk3dbi_bdb_get(dbp, key, val);
+#endif
+ } break;
+ case DK3_DB_TYPE_NDBM: {
+#if DK3_USE_NDBM
+ back = dk3dbi_ndbm_get(dbp, key, val);
+#endif
+ } break;
+ }
+ } else {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ } else {
+ if(dbp) {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ } $? "- dk3dbi_get %d", back
+ return back;
+}
+
+
+
+int
+dk3dbi_delete(dk3_dbi_t *dbp, dk3_datum_t *key)
+{
+ int back = 0;
+ $? "+ dk3dbi_delete"
+ if((dbp) && (key)) {
+ if((key->dt) && (key->sz)) {
+ switch(dbp->tp) {
+ case DK3_DB_TYPE_MEMORY: {
+ back = dk3dbi_mem_delete(dbp, key);
+ dbp->mod = 1;
+ } break;
+ case DK3_DB_TYPE_BDB: {
+#if DK3_USE_DB
+ back = dk3dbi_bdb_delete(dbp, key);
+ dbp->mod = 1;
+#endif
+ } break;
+ case DK3_DB_TYPE_NDBM: {
+#if DK3_USE_NDBM
+ back = dk3dbi_ndbm_delete(dbp, key);
+ dbp->mod = 1;
+#endif
+ } break;
+ }
+ } else {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ } else {
+ if(dbp) {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ } $? "- dk3dbi_delete %d", back
+ return back;
+}
+
+
+
+int
+dk3dbi_traverse(dk3_dbi_t *dbp, void *obj, dk3_db_traverse_fct_t *fct)
+{
+ int back = 0;
+ $? "+ dk3dbi_traverse"
+ if((dbp) && (fct)) {
+ switch(dbp->tp) {
+ case DK3_DB_TYPE_MEMORY: {
+ back = dk3dbi_mem_traverse(dbp, obj, fct);
+ } break;
+ case DK3_DB_TYPE_BDB: {
+#if DK3_USE_DB
+ back = dk3dbi_bdb_traverse(dbp, obj, fct);
+#endif
+ } break;
+ case DK3_DB_TYPE_NDBM: {
+#if DK3_USE_NDBM
+ back = dk3dbi_ndbm_traverse(dbp, obj, fct);
+#endif
+ } break;
+ }
+ } else {
+ if(dbp) {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ } $? "- dk3dbi_traverse %d", back
+ return back;
+}
+
+
+
+int
+dk3dbi_sync(dk3_dbi_t *dbp)
+{
+ int back = 0;
+ $? "+ dk3dbi_sync"
+ if(dbp) {
+ back = 1;
+ if(dbp->mod) {
+ back = dk3dbi_sync_internal(dbp);
+ if(back) { dbp->mod = 0; }
+ }
+ } $? "- dk3dbi_sync %d", back
+ return back;
+}
+
+
+
+int
+dk3dbi_get_error(dk3_dbi_t *dbp, int res)
+{
+ int back = 0;
+ $? "+ dk3dbi_get_error"
+ if(dbp) {
+ back = dbp->ec;
+ if(res) { dbp->ec = 0; }
+ } $? "- dk3dbi_get_error %d", back
+ return back;
+}
+
+
+
+int
+dk3dbi_set_c8_string(
+ dk3_dbi_t *dbp,
+ char const *key,
+ char const *val
+)
+{
+ dk3_datum_t k; /* Key datum. */
+ dk3_datum_t v; /* Value datum. */
+ size_t ks; /* Key size (number of bytes). */
+ size_t vs; /* Value size (number of bytes). */
+ int back = 0;
+ $? "+ dk3dbi_set_c8_string \"%!8s\"=\"%!8s\"", TR_8STR(key), TR_8STR(val)
+ if((dbp) && (key) && (val)) {
+ ks = dk3str_c8_len(key);
+ vs = dk3str_c8_len(val);
+ ks++; vs++;
+ if((ks) && (vs)) {
+ k.dt = (void *)key; k.sz = ks;
+ v.dt = (void *)val; v.sz = vs;
+ back = dk3dbi_set(dbp, &k, &v);
+ } else {
+ /* ERROR: At least one numeric overflow. */
+ if(dbp->app) {
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 15);
+ }
+ dbp->ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if(dbp) {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ } $? "- dk3dbi_set_c8_string %d", back
+ return back;
+}
+
+
+
+int
+dk3dbi_get_c8_string(
+ dk3_dbi_t *dbp,
+ char const *key,
+ char *vb,
+ size_t vbsz
+)
+{
+ dk3_datum_t k; /* Key datum. */
+ dk3_datum_t v; /* Value datum. */
+ size_t ks; /* Key size (number of bytes). */
+ int back = 0;
+ int orfk;
+ $? "+ dk3dbi_get_c8_string \"%!8s\"", TR_8STR(key)
+ if((dbp) && (key) && (vb) && (vbsz)) {
+ ks = dk3str_c8_len(key);
+ ks++;
+ if(ks) {
+ k.dt = (void *)key; k.sz = ks;
+ v.dt = vb; v.sz = vbsz;
+ orfk = dbp->rfk;
+ dbp->rfk = 0;
+ if(dk3dbi_get(dbp, &k, &v)) {
+ back = 1;
+ if(v.sz > 0) {
+ if(v.sz < vbsz) {
+ vb[v.sz] = '\0';
+ } else {
+ vb[vbsz - 1] = '\0';
+ }
+ } else {
+ vb[0] = '\0';
+ }
+ }
+ dbp->rfk = orfk;
+ } else {
+ /* ERROR: Numeric overflow! */
+ if(dbp->app) {
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 15);
+ }
+ dbp->ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if(dbp) {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ } $? "- dk3dbi_get_c8_string %d", back
+ return back;
+}
+
+
+
+int
+dk3dbi_delete_c8_string(
+ dk3_dbi_t *dbp,
+ char const *key
+)
+{
+ dk3_datum_t k; /* Key datum. */
+ size_t ks; /* Key size in bytes. */
+ int back = 0;
+ $? "+ dk3dbi_delete_c8_string \"%!8s\"", TR_8STR(key)
+ if((dbp) && (key)) {
+ ks = dk3str_c8_len(key);
+ ks++;
+ if(ks) {
+ k.dt = (void *)key; k.sz = ks;
+ back = dk3dbi_delete(dbp, &k);
+ } else {
+ /* ERROR: Numeric overflow! */
+ if(dbp->app) {
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 15);
+ }
+ dbp->ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if(dbp) {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ } $? "- dk3dbi_delete_c8_string %d", back
+ return back;
+}
+
+
+
+int
+dk3dbi_set_c16_string(
+ dk3_dbi_t *dbp,
+ dk3_c16_t const *key,
+ dk3_c16_t const *val
+)
+{
+ dk3_datum_t k; /* Key datum. */
+ dk3_datum_t v; /* Value datum. */
+ size_t ks; /* Key size (number of bytes). */
+ size_t vs; /* Value size (number of bytes). */
+ int back = 0;
+ $? "+ dk3dbi_set_c16_string"
+ if((dbp) && (key) && (val)) {
+ ks = dk3str_c16_len(key);
+ vs = dk3str_c16_len(val);
+ ks = dk3mem_mul_size_t(dk3mem_add_size_t(ks, 1, NULL), 2, NULL);
+ vs = dk3mem_mul_size_t(dk3mem_add_size_t(vs, 1, NULL), 2, NULL);
+ if((ks) && (vs)) {
+ k.dt = (void *)key; k.sz = ks; v.dt = (void *)val; v.sz = vs;
+ back = dk3dbi_set(dbp, &k, &v);
+ } else {
+ /* ERROR: Size overflow! */
+ if(dbp->app) {
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 15);
+ }
+ dbp->ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if(dbp) {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ } $? "- dk3dbi_set_c16_string %d", back
+ return back;
+}
+
+
+
+int
+dk3dbi_get_c16_string(
+ dk3_dbi_t *dbp,
+ dk3_c16_t const *key,
+ dk3_c16_t *vb,
+ size_t vbsz
+)
+{
+ dk3_datum_t k; /* Key datum. */
+ dk3_datum_t v; /* Value datum. */
+ size_t ks; /* Key size (number of bytes). */
+ size_t vs; /* Value size (number of bytes). */
+ int back = 0;
+ int orfk;
+ $? "+ dk3dbi_get_c16_string"
+ if((dbp) && (key) && (vb) && (vbsz)) {
+ ks = dk3str_c16_len(key);
+ ks = dk3mem_mul_size_t(dk3mem_add_size_t(ks, 1, NULL), 2, NULL);
+ vs = dk3mem_mul_size_t(vbsz, 2, NULL);
+ if((ks) && (vs)) {
+ k.dt = (void *)key; k.sz = ks; v.dt = vb, v.sz = vs;
+ orfk = dbp->rfk;
+ dbp->rfk = 0;
+ if(dk3dbi_get(dbp, &k, &v)) {
+ if(!((v.sz) % 2)) {
+ back = 1;
+ v.sz = v.sz / 2;
+ if(v.sz > 0) {
+ if(v.sz < vbsz) {
+ vb[v.sz] = 0U;
+ } else {
+ vb[vbsz - 1] = 0U;
+ }
+ } else {
+ vb[0] = 0U;
+ }
+ } else {
+ /* ERROR: Damaged entry! */
+ if(dbp->app) {
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 250);
+ }
+ dbp->ec = DK3_ERROR_DATA_DAMAGED;
+ }
+ }
+ dbp->rfk = orfk;
+ } else {
+ /* ERROR: Numeric overflow! */
+ if(dbp->app) {
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 15);
+ }
+ dbp->ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if(dbp) {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ } $? "- dk3dbi_get_c16_string %d", back
+ return back;
+}
+
+
+
+int
+dk3dbi_delete_c16_string(
+ dk3_dbi_t *dbp,
+ dk3_c16_t const *key
+)
+{
+ dk3_datum_t k; /* Key datum. */
+ size_t ks; /* Key size (number of bytes). */
+ int back = 0;
+ $? "+ dk3dbi_delete_c16_string"
+ if((dbp) && (key)) {
+ ks = dk3str_c16_len(key);
+ ks = dk3mem_mul_size_t(dk3mem_add_size_t(ks, 1, NULL), 2, NULL);
+ if(ks) {
+ k.dt = (void *)key; k.sz = ks;
+ back = dk3dbi_delete(dbp, &k);
+ } else {
+ /* ERROR: Numeric overflow! */
+ if(dbp->app) {
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 15);
+ }
+ dbp->ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if(dbp) {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ } $? "- dk3dbi_delete_c16_string %d", back
+ return back;
+}
+
+
+
+int
+dk3dbi_set_c32_string(
+ dk3_dbi_t *dbp,
+ dk3_c32_t const *key,
+ dk3_c32_t const *val
+)
+{
+ dk3_datum_t k; /* Key datum. */
+ dk3_datum_t v; /* Value datum. */
+ size_t ks; /* Key size (number of bytes). */
+ size_t vs; /* Value size (number of bytes). */
+ int back = 0;
+ $? "+ dk3dbi_set_c32_string"
+ if((dbp) && (key) && (val)) {
+ ks = dk3str_c32_len(key);
+ ks = dk3mem_mul_size_t(dk3mem_add_size_t(ks, 1, NULL), 4, NULL);
+ vs = dk3str_c32_len(val);
+ vs = dk3mem_mul_size_t(dk3mem_add_size_t(vs, 1, NULL), 4, NULL);
+ if((ks) && (vs)) {
+ k.dt = (void *)key; k.sz = ks; v.dt = (void *)val; v.sz = vs;
+ back = dk3dbi_set(dbp, &k, &v);
+ } else {
+ /* ERROR: Numeric overflow! */
+ if(dbp->app) {
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 15);
+ }
+ dbp->ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if(dbp) {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ } $? "- dk3dbi_set_c32_string %d", back
+ return back;
+}
+
+
+
+int
+dk3dbi_get_c32_string(
+ dk3_dbi_t *dbp,
+ dk3_c32_t const *key,
+ dk3_c32_t *vb,
+ size_t vbsz
+)
+{
+ dk3_datum_t k; /* Key datum. */
+ dk3_datum_t v; /* Value datum. */
+ size_t ks; /* Key size (number of bytes). */
+ size_t vs; /* Value size (number of bytes). */
+ int back = 0;
+ int orfk;
+ $? "+ dk3dbi_get_c32_string"
+ if((dbp) && (key) && (vb) && (vbsz)) {
+ ks = dk3str_c32_len(key);
+ ks = dk3mem_mul_size_t(dk3mem_add_size_t(ks, 1, NULL), 4, NULL);
+ vs = dk3mem_mul_size_t(vbsz, 4, NULL);
+ if((ks) && (vs)) {
+ k.dt = (void *)key; k.sz = ks; v.dt = vb; v.sz = vs;
+ orfk = dbp->rfk;
+ dbp->rfk = 0;
+ if(dk3dbi_get(dbp, &k, &v)) {
+ if(!((v.sz) % 4)) {
+ back = 1;
+ v.sz = v.sz / 4;
+ if(v.sz > 0) {
+ if(v.sz < vbsz) {
+ vb[v.sz] = 0UL;
+ } else {
+ vb[vbsz - 1] = 0UL;
+ }
+ } else {
+ vb[0] = 0UL;
+ }
+ } else {
+ /* ERROR: Damaged entry! */
+ if(dbp->app) {
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 250);
+ }
+ dbp->ec = DK3_ERROR_DATA_DAMAGED;
+ }
+ }
+ dbp->rfk = orfk;
+ } else {
+ /* ERROR: Numeric overflow! */
+ if(dbp->app) {
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 15);
+ }
+ dbp->ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if(dbp) {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ } $? "- dk3dbi_get_c32_string %d", back
+ return back;
+}
+
+
+
+int
+dk3dbi_delete_c32_string(
+ dk3_dbi_t *dbp,
+ dk3_c32_t const *key
+)
+{
+ dk3_datum_t k; /* Key datum. */
+ size_t ks; /* Key size (number of bytes). */
+ int back = 0;
+ $? "+ dk3dbi_delete_c32_string"
+ if((dbp) && (key)) {
+ ks = dk3str_c32_len(key);
+ ks = dk3mem_mul_size_t(dk3mem_add_size_t(ks, 1, NULL), 4, NULL);
+ if(ks) {
+ k.dt = (void *)key; k.sz = ks;
+ back = dk3dbi_delete(dbp, &k);
+ } else {
+ /* ERROR: Numeric overflow! */
+ if(dbp->app) {
+ dk3app_log_i1(dbp->app, DK3_LL_ERROR, 15);
+ }
+ dbp->ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if(dbp) {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ } $? "- dk3dbi_delete_c32_string %d", back
+ return back;
+}
+
+
+
+int
+dk3dbi_set_string(
+ dk3_dbi_t *dbp,
+ dkChar const *key,
+ dkChar const *val
+)
+{
+ int back = 0;
+ $? "+ dk3dbi_set_string"
+ if((dbp) && (key) && (val)) {
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ back = dk3dbi_set_c32_string(dbp, key, val);
+#else
+ back = dk3dbi_set_c16_string(dbp, key, val);
+#endif
+#else
+ back = dk3dbi_set_c8_string(dbp, key, val);
+#endif
+ } else {
+ if(dbp) {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ } $? "- dk3dbi_set_string %d", back
+ return back;
+}
+
+
+
+int
+dk3dbi_get_string(
+ dk3_dbi_t *dbp,
+ dkChar const *key,
+ dkChar *vb,
+ size_t vbsz
+)
+{
+ int back = 0;
+ $? "+ dk3dbi_get_string"
+ if((dbp) && (key) && (vb) && (vbsz)) {
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ back = dk3dbi_get_c32_string(dbp, key, vb, vbsz);
+#else
+ back = dk3dbi_get_c16_string(dbp, key, vb, vbsz);
+#endif
+#else
+ back = dk3dbi_get_c8_string(dbp, key, vb, vbsz);
+#endif
+ } else {
+ if(dbp) {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ } $? "- dk3dbi_get_string %d", back
+ return back;
+}
+
+
+int
+dk3dbi_delete_string(
+ dk3_dbi_t *dbp,
+ dkChar const *key
+)
+{
+ int back = 0;
+ $? "+ dk3dbi_delete_string"
+ if((dbp) && (key)) {
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ back = dk3dbi_delete_c32_string(dbp, key);
+#else
+ back = dk3dbi_delete_c16_string(dbp, key);
+#endif
+#else
+ back = dk3dbi_delete_c8_string(dbp, key);
+#endif
+ } else {
+ if(dbp) {
+ dbp->ec = DK3_ERROR_INVALID_ARGS;
+ }
+ } $? "- dk3dbi_delete_string %d", back
+ return back;
+}
+
+
+
+/** Delete or truncate a database file.
+ @param fn File name.
+ @param tp Database type.
+ @param del Flag: Delete (non-zero) or truncate (0).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dbi_dbfile_del_or_trunc(dkChar const *fn, int tp, int del, dk3_app_t *app)
+{
+ dkChar fnb[DK3_MAX_PATH + 16]; /* Copy of file name. */
+ char c8fn[DK3_MAX_PATH]; /* File name as 8-bit. */
+ FILE *fipo; /* File to truncate. */
+ dkChar const *myfn; /* File name. */
+ int ec = 0; /* Error code. */
+ int mytp; /* DB type. */
+ int back = 0;
+ $? "+ dk3dbi_dbfile_del_or_trunc"
+ mytp = tp;
+ if(fn) {
+ if(dk3str_len(fn) < DK3_SIZEOF(fnb,dkChar)) {
+ dk3str_cpy_not_overlapped(fnb, fn);
+ if(dk3dbi_find_type_and_name(&myfn, &mytp, fnb, tp, &ec, app)) {
+ if((myfn) && (mytp >= 0)) {
+ switch(mytp) {
+ case DK3_DB_TYPE_MEMORY: { $? ". mem"
+ if(del) {
+ dk3sf_remove_file_app(myfn, app);
+ back = 1;
+ } else {
+ fipo = dk3sf_fopen_app(myfn, dk3dbi_file_open_modes[1], app);
+ if(fipo) { $? ". file opened ok"
+ if(dk3sf_fclose_fn_app(fipo, myfn, app)) {
+ back = 1;
+ }
+ } else { $? "! failed to open file"
+ }
+ }
+ } break;
+ case DK3_DB_TYPE_BDB: { $? ". bdb"
+ if(dk3sf_filename_to_c8(c8fn, sizeof(c8fn), myfn, app)) {
+ if(del) {
+ dk3sf_remove_file_app(myfn, app);
+ back = 1;
+ } else {
+#if DK3_USE_DB
+ DB *db = NULL;
+ int ret;
+ u_int32_t flags;
+ ret = db_create(&db, NULL, 0);
+ if(ret == 0) { $? ". db created"
+ flags = DB_CREATE | DB_TRUNCATE;
+ ret = db->open(db, NULL, c8fn, NULL, DB_BTREE, flags, 0600);
+ if(ret == 0) { $? ". db opend ok"
+ back = 1;
+ } else { $? "! failed to open db"
+ }
+ if(db) {
+ db->close(db, 0);
+ }
+ } else { $? "! failed to create db"
+ }
+#endif
+ }
+ } else { $? "! failed to convert file name to 8 bit"
+ }
+ } break;
+ case DK3_DB_TYPE_NDBM: { $? ". ndbm"
+ if(dk3sf_filename_to_c8(c8fn, sizeof(c8fn), myfn, app)) {
+ if(del) {
+ if((dk3str_c8_len(c8fn)
+ + dk3str_c8_len(dk3dbi_ndbm_suffixes[0])
+ ) < sizeof(c8fn)
+ )
+ {
+ dk3str_c8_cat(c8fn, dk3dbi_ndbm_suffixes[0]);
+ dk3sf_c8_remove_file_app(c8fn, app);
+ dk3sf_filename_to_c8(c8fn, sizeof(c8fn), myfn, app);
+ if((dk3str_c8_len(c8fn)
+ + dk3str_c8_len(dk3dbi_ndbm_suffixes[1])
+ ) < sizeof(c8fn)
+ )
+ {
+ dk3str_c8_cat(c8fn, dk3dbi_ndbm_suffixes[1]);
+ dk3sf_c8_remove_file_app(c8fn, app);
+ back = 1;
+ }
+ }
+ } else {
+#if DK3_USE_NDBM
+ DBM *dbm = NULL;
+ dbm = dbm_open(c8fn, (O_RDWR | O_CREAT | O_TRUNC), 0600);
+ if(dbm) {
+ dbm_close(dbm);
+ }
+#endif
+ }
+ } else { $? "! failed to convert file name to 8 bit"
+ }
+ } break;
+ default: {
+ /* BUG: Illegal database type, must not happen! */
+ } break;
+ }
+ } else { $? "! name or type not found"
+ /* BUG: Must not happen! */
+ }
+ } else { $? "! name or type not found"
+ /* Error: Name or type not found, already reported! */
+ }
+ } else { $? "! file name too long"
+ /* ERROR: File name too long! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 65, 66, fn);
+ }
+ } else { $? "! illegal file name"
+ } $? "- dk3dbi_dbfile_del_or_trunc %d", back
+ return back;
+}
+
+
+
+int
+dk3dbi_dbfile_delete_app(dkChar const *fn, int tp, dk3_app_t *app)
+{
+ int back;
+ $? "+ dk3dbi_dbfile_delete_app \"%!ds\"", TR_STR(fn)
+ back = dk3dbi_dbfile_del_or_trunc(fn, tp, 1, app);
+ $? "- dk3dbi_dbfile_delete_app %d", back
+ return back;
+}
+
+
+
+int
+dk3dbi_dbfile_truncate_app(dkChar const *fn, int tp, dk3_app_t *app)
+{
+ int back;
+ $? "+ dk3dbi_dbfile_truncate_app \"%!ds\"", TR_STR(fn)
+ back = dk3dbi_dbfile_del_or_trunc(fn, tp, 1, app);
+ $? "- dk3dbi_dbfile_truncate_app %d", back
+ return back;
+}
+
+
+
+int
+dk3dbi_dbfile_delete(dkChar const *fn, int tp)
+{
+ int back;
+ $? "+ dk3dbi_dbfile_delete \"%!ds\"", TR_STR(fn)
+ back = dk3dbi_dbfile_del_or_trunc(fn, tp, 1, NULL);
+ $? "- dk3dbi_dbfile_delete %d", back
+ return back;
+}
+
+
+
+int
+dk3dbi_dbfile_truncate(dkChar const *fn, int tp)
+{
+ int back;
+ $? "+ dk3dbi_dbfile_truncate \"%!ds\"", TR_STR(fn)
+ back = dk3dbi_dbfile_del_or_trunc(fn, tp, 1, NULL);
+ $? "- dk3dbi_dbfile_truncate %d", back
+ return back;
+}
+
+
+
+#if !DK3_ON_WINDOWS
+#if DK3_CHAR_SIZE == 1
+#if DK3_HAVE_CHOWN && DK3_HAVE_CHMOD
+static
+int
+dk3dbi_change_file_user_and_permissions(
+ dk3_dbi_t *db, char const *fn, uid_t uid, gid_t gid, mode_t mode
+)
+{
+ int back = 0;
+ if(0 == chown(fn, uid, gid)) {
+ if(0 == chmod(fn, mode)) {
+ back = 1;
+ } else {
+ /* ERROR: Failed to change file permissions! */
+ if(db->app) {
+ dk3app_log_i3(db->app, DK3_LL_ERROR, 272, 273, fn);
+ }
+ }
+ } else {
+ /* ERROR: Failed to change file ownership! */
+ if(db->app) {
+ dk3app_log_i3(db->app, DK3_LL_ERROR, 270, 271, fn);
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3dbi_change_user_and_permissions(
+ dk3_dbi_t *db,
+ uid_t uid,
+ gid_t gid,
+ mode_t mode
+)
+{
+ dkChar fnb[DK3_MAX_PATH];
+ int back = 0;
+ if(db) {
+ switch(db->tp) {
+ case DK3_DB_TYPE_MEMORY:
+ case DK3_DB_TYPE_BDB: {
+ if(db->fn) {
+ back = dk3dbi_change_file_user_and_permissions(
+ db, db->fn, uid, gid, mode
+ );
+ } else {
+ /* ERROR: No file name for database! */
+ if(db->app) {
+ dk3app_log_i1(db->app, DK3_LL_ERROR, 269);
+ }
+ }
+ } break;
+ case DK3_DB_TYPE_NDBM: {
+ if(db->fn) {
+ if(dk3str_len(db->fn) < DK3_SIZEOF(fnb,dkChar)) {
+ back = 1;
+ dk3str_cpy_not_overlapped(fnb, db->fn);
+ if((dk3str_len(fnb) + dk3str_len(dk3dbi_ndbm_suffixes[0]))
+ < DK3_SIZEOF(fnb,dkChar)
+ )
+ {
+ dk3str_cat(fnb, dk3dbi_ndbm_suffixes[0]);
+ if(!dk3dbi_change_file_user_and_permissions(db,fnb,uid,gid,mode))
+ {
+ back = 0;
+ }
+ }
+ else
+ {
+ /* ERROR: File name too long! */
+ if(db->app) {
+ dk3app_log_i3(db->app, DK3_LL_ERROR, 66, 67, db->fn);
+ }
+ back = 0;
+ }
+ dk3str_cpy_not_overlapped(fnb, db->fn);
+ if((dk3str_len(fnb) + dk3str_len(dk3dbi_ndbm_suffixes[1]))
+ < DK3_SIZEOF(fnb,dkChar)
+ )
+ {
+ dk3str_cat(fnb, dk3dbi_ndbm_suffixes[1]);
+ if(!dk3dbi_change_file_user_and_permissions(db,fnb,uid,gid,mode))
+ {
+ back = 0;
+ }
+ }
+ else
+ {
+ /* ERROR: File name too long! */
+ if(db->app) {
+ dk3app_log_i3(db->app, DK3_LL_ERROR, 66, 67, db->fn);
+ }
+ back = 0;
+ }
+ } else {
+ /* ERROR: File name too long! */
+ if(db->app) {
+ dk3app_log_i3(db->app, DK3_LL_ERROR, 66, 67, db->fn);
+ }
+ }
+ } else {
+ /* ERROR: No file name for database! */
+ if(db->app) {
+ dk3app_log_i1(db->app, DK3_LL_ERROR, 269);
+ }
+ }
+ } break;
+ }
+ }
+ return back;
+}
+#endif
+#endif
+#endif
+
diff --git a/support/dktools/dk3dbi.h b/support/dktools/dk3dbi.h
new file mode 100644
index 0000000000..3bbc97c0db
--- /dev/null
+++ b/support/dktools/dk3dbi.h
@@ -0,0 +1,407 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3dbi.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3dbi.h Header file for the dk3dbi module.
+*/
+
+#ifndef DK3DBI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3DBI_H_INCLUDED 1
+
+
+#line 10 "dk3dbi.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Check whether a database type is supported.
+ @param tp Database type, see @ref databasetypes.
+ @return 1 on success (type supported), 0 on error (not supported).
+*/
+int
+dk3dbi_type_supported(int tp);
+
+/** Open a database.
+ @param fn Database file name.
+ @param tp Database type, see @ref databasetypes.
+ @param acc Access type, see @ref databaseaccess.
+ @param pec Pointer to error code variable, may be NULL.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to opened database on success, NULL on error.
+*/
+dk3_dbi_t *
+dk3dbi_open_app(dkChar const *fn, int tp, int acc, int *pec, dk3_app_t *app);
+
+/** Open a database.
+ @param fn Database file name.
+ @param tp Database type, see @ref databasetypes.
+ @param acc Access type, see @ref databaseaccess.
+ @param pec Pointer to error code variable, may be NULL.
+ @return Pointer to opened database on success, NULL on error.
+*/
+dk3_dbi_t *
+dk3dbi_open(dkChar const *fn, int tp, int acc, int *pec);
+
+/** Open a database, discard all existing contents.
+ @param fn Database file name.
+ @param tp Database type, see @ref databasetypes.
+ @param acc Access type, see @ref databaseaccess.
+ @param pec Pointer to error code variable, may be NULL.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to opened database on success, NULL on error.
+*/
+dk3_dbi_t *
+dk3dbi_open_truncate_app(
+ dkChar const *fn,
+ int tp,
+ int acc,
+ int *pec,
+ dk3_app_t *app
+);
+
+/** Open a database, discard all existing contents.
+ @param fn Database file name.
+ @param tp Database type, see @ref databasetypes.
+ @param acc Access type, see @ref databaseaccess.
+ @param pec Pointer to error code variable, may be NULL.
+ @return Pointer to opened database on success, NULL on error.
+*/
+dk3_dbi_t *
+dk3dbi_open_truncate(dkChar const *fn, int tp, int acc, int *pec);
+
+/** Set an entry in the database.
+ @param dbp Database.
+ @param key Key data.
+ @param val Value data.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_set(dk3_dbi_t *dbp, dk3_datum_t *key, dk3_datum_t *val);
+
+/** Get an entry from the database.
+ @param dbp Database.
+ @param key Key data.
+ @param val Value data, set up for a result buffer.
+ On input it contains the buffer size, on successful
+ return it contains the number of bytes.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_get(dk3_dbi_t *dbp, dk3_datum_t *key, dk3_datum_t *val);
+
+/** Delete an entry from the database.
+ @param dbp Database.
+ @param key Key data.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_delete(dk3_dbi_t *dbp, dk3_datum_t *key);
+
+/** Save 8-bit character string to database.
+ @param dbp Database.
+ @param key Key string.
+ @param val Value string.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_set_c8_string(
+ dk3_dbi_t *dbp,
+ char const *key,
+ char const *val
+);
+
+/** Retrieve 8-bit character string from database.
+ @param dbp Database.
+ @param key Key string.
+ @param vb Value buffer.
+ @param vbsz Value buffer size in bytes.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_get_c8_string(
+ dk3_dbi_t *dbp,
+ char const *key,
+ char *vb,
+ size_t vbsz
+);
+
+/** Delete 8-bit character string from database.
+ @param dbp Database.
+ @param key Key string.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_delete_c8_string(
+ dk3_dbi_t *dbp,
+ char const *key
+);
+
+/** Save 16-bit character string to database.
+ @param dbp Database.
+ @param key Key string.
+ @param val Value string.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_set_c16_string(
+ dk3_dbi_t *dbp,
+ dk3_c16_t const *key,
+ dk3_c16_t const *val
+);
+
+/** Retrieve 16-bit character string from database.
+ @param dbp Database.
+ @param key Key string.
+ @param vb Value buffer.
+ @param vbsz Value buffer size (number of 16-bit characters).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_get_c16_string(
+ dk3_dbi_t *dbp,
+ dk3_c16_t const *key,
+ dk3_c16_t *vb,
+ size_t vbsz
+);
+
+/** Delete 16-bit character string from database.
+ @param dbp Database.
+ @param key Key string.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_delete_c16_string(
+ dk3_dbi_t *dbp,
+ dk3_c16_t const *key
+);
+
+/** Save 32-bit character string to database.
+ @param dbp Database.
+ @param key Key string.
+ @param val Value string.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_set_c32_string(
+ dk3_dbi_t *dbp,
+ dk3_c32_t const *key,
+ dk3_c32_t const *val
+);
+
+/** Retrieve 32-bit character string from database.
+ @param dbp Database.
+ @param key Key string.
+ @param vb Value buffer.
+ @param vbsz Value buffer size (number of 32-bit characters).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_get_c32_string(
+ dk3_dbi_t *dbp,
+ dk3_c32_t const *key,
+ dk3_c32_t *vb,
+ size_t vbsz
+);
+
+/** Delete 32-bit character string from database.
+ @param dbp Database.
+ @param key Key string.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_delete_c32_string(
+ dk3_dbi_t *dbp,
+ dk3_c32_t const *key
+);
+
+/** Save a dkChar string to the database.
+ @param dbp Database.
+ @param key Key string.
+ @param val Value string.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_set_string(
+ dk3_dbi_t *dbp,
+ dkChar const *key,
+ dkChar const *val
+);
+
+/** Retrieve dkChar string from the database.
+ @param dbp Database.
+ @param key Key string.
+ @param vb Value buffer.
+ @param vbsz Size of value buffer (Number of dkChar).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_get_string(
+ dk3_dbi_t *dbp,
+ dkChar const *key,
+ dkChar *vb,
+ size_t vbsz
+);
+
+/** Delete dkChar string from database.
+ @param dbp Database.
+ @param key Key string.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_delete_string(
+ dk3_dbi_t *dbp,
+ dkChar const *key
+);
+
+/** Synchronize to disk.
+ @param dbp Database.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_sync(dk3_dbi_t *dbp);
+
+/** Traverse database.
+ @param dbp Database.
+ @param obj Object to modify while traversing the database.
+ @param fct Callback function to use for each key/value pair.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_traverse(dk3_dbi_t *dbp, void *obj, dk3_db_traverse_fct_t *fct);
+
+/** Get last error code occured.
+ @param dbp Database.
+ @param res Flag: Reset error code.
+ @return Error code for last error.
+*/
+int
+dk3dbi_get_error(dk3_dbi_t *dbp, int res);
+
+/** Close database.
+ @param dbp Database to close.
+ @return 1 on success (sync ok), 0 on error.
+*/
+int
+dk3dbi_close(dk3_dbi_t *dbp);
+
+/** Delete database file(s).
+ @param fn Database file name.
+ @param tp Database type.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_dbfile_delete_app(dkChar const *fn, int tp, dk3_app_t *app);
+
+/** Truncate database (remove all contents).
+ @param fn Database file name.
+ @param tp Database type.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_dbfile_truncate_app(dkChar const *fn, int tp, dk3_app_t *app);
+
+/** Delete database file(s).
+ @param fn Database file name.
+ @param tp Database type.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_dbfile_delete(dkChar const *fn, int tp);
+
+/** Truncate database (remove all contents).
+ @param fn Database file name.
+ @param tp Database type.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_dbfile_truncate(dkChar const *fn, int tp);
+
+/** Split a given name into database type and real file name.
+ The given name may be either a file name with tp set to a
+ database type or
+ "mem::file", "bdb::file", or "ndbm::file" to specify a file name
+ and database type with tp set to DK3_DB_TYPE_UNKNOWN.
+ @param myfn Pointer to a pointer to receive real file name.
+ @param mytp Pointer to type output variable.
+ @param fn File name or type::filename.
+ @param tp Type as specified.
+ @param pec Pointer to error code variable.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_find_type_and_name(
+ dkChar const **myfn,
+ int *mytp,
+ dkChar const *fn,
+ int tp,
+ int *pec,
+ dk3_app_t *app
+);
+
+
+#if !DK3_ON_WINDOWS
+#if DK3_CHAR_SIZE == 1
+#if DK3_HAVE_CHOWN && DK3_HAVE_CHMOD
+/** Change user name and permissions for a database.
+ This function is intended for daemons on *x systems where the daemon
+ is started by user root but gives up privileges before starting
+ processing.
+ @param db Database to change.
+ @param uid New user ID.
+ @param gid New group ID.
+ @param mode Unix/Linux permissions.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dbi_change_user_and_permissions(
+ dk3_dbi_t *db,
+ uid_t uid,
+ gid_t gid,
+ mode_t mode
+);
+#endif
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk3dir.c b/support/dktools/dk3dir.c
new file mode 100644
index 0000000000..777dc8540b
--- /dev/null
+++ b/support/dktools/dk3dir.c
@@ -0,0 +1,1484 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3dir.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3dir.c The dk3dir module.
+*/
+
+
+#line 124 "dk3dir.ctr"
+
+#include "dk3all.h"
+
+
+
+
+
+#line 130 "dk3dir.ctr"
+
+
+
+/* Error flags used in ec:
+ 1 Failed to allocate memory for name to save.
+ 2 Failed to save name to storage.
+ 4 Directory name too long.
+ 8 stat() failed for full name.
+ 16 Failed to list directory contents.
+*/
+
+/** Keywords and texts used in this module.
+*/
+static dkChar const * const kw[] = {
+/* 0 */ dkT("."),
+/* 1 */ dkT(".."),
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+/* 2 */ dkT("\\"),
+/* 3 */ dkT("\\*"),
+#else
+/* 2 */ dkT("/"),
+/* 3 */ dkT("/*"),
+#endif
+/* 4 */ dkT("*"),
+NULL
+};
+
+
+
+/** Compare two directory entries by name.
+ @param l Left name.
+ @param r Right name.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+static
+int
+dk3dir_compare_by_name(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ if(l) {
+ if(r) {
+#if DK3_ON_WINDOWS || DK3_HAVE_FNCASEINS
+ back = dk3str_casecmp((dkChar const *)l,(dkChar const *)r);
+#else
+ back = dk3str_cmp((dkChar const *)l,(dkChar const *)r);
+#endif
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+/** Release all directory entries in a storage.
+ @param s Storage to clean up.
+ @param i Iterator for \a s.
+*/
+static
+void
+dk3dir_release_entries(dk3_sto_t *s, dk3_sto_it_t *i)
+{
+ dkChar *p = NULL; /* Current name to release. */
+
+
+#line 196 "dk3dir.ctr"
+ if(s) {
+ if(i) {
+ dk3sto_it_reset(i);
+ while((p = (dkChar *)dk3sto_it_next(i)) != NULL) {
+
+
+#line 201 "dk3dir.ctr"
+ dk3_delete(p);
+ }
+ dk3sto_it_close(i);
+ }
+ dk3sto_close(s);
+ }
+
+#line 207 "dk3dir.ctr"
+}
+
+
+
+/** Close directory.
+ @param dp Directory to close.
+*/
+void
+dk3dir_close(dk3_dir_t *dp)
+{
+
+
+#line 218 "dk3dir.ctr"
+ if(dp) {
+ dk3dir_release_entries(dp->sdi, dp->idi);
+ dk3dir_release_entries(dp->sfi, dp->ifi);
+ dp->sdi = NULL; dp->sfi = NULL; dp->idi = NULL; dp->ifi = NULL;
+ dk3_release(dp->dirname);
+ dk3_release(dp->fullname);
+ dp->app = NULL;
+ dp->ndir = dp->nfi = DK3_UM_0;
+ dk3_delete(dp);
+ }
+
+#line 228 "dk3dir.ctr"
+}
+
+
+
+/** Create new dir structure.
+ @param dn Directory name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new structure on success, NULL on error.
+*/
+static
+dk3_dir_t *
+dk3dir_new(dkChar const *dn, dk3_app_t *app)
+{
+ dk3_dir_t *back = NULL;
+ int ok = 0; /* Flag: Success. */
+
+
+#line 244 "dk3dir.ctr"
+ back = dk3_new_app(dk3_dir_t,1,app);
+ if(back) {
+ back->sdi = NULL; back->sfi = NULL; back->idi = NULL; back->ifi = NULL;
+ back->dirname = NULL; back->fullname = NULL; back->app = app;
+ back->ndir = back->nfi = DK3_UM_0;
+ back->sdi = dk3sto_open_app(app);
+ if(back->sdi) {
+ back->idi = dk3sto_it_open(back->sdi);
+ if(back->idi) {
+ back->sfi = dk3sto_open_app(app);
+ if(back->sfi) {
+ back->ifi = dk3sto_it_open(back->sfi);
+ if(back->ifi) {
+ dk3sto_set_comp(back->sdi,dk3dir_compare_by_name,0);
+ dk3sto_set_comp(back->sfi,dk3dir_compare_by_name,0);
+ back->dirname = dk3str_dup_app(dn, NULL);
+ if(back->dirname) {
+ back->fullname = dk3_new_app(dkChar,DK3_MAX_PATH,app);
+ if(back->fullname) {
+ ok = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ if(!ok) {
+ dk3dir_close(back); back = NULL;
+ }
+ }
+
+#line 274 "dk3dir.ctr"
+ return back;
+}
+
+
+
+dkChar const *
+dk3dir_get_directory_name(dk3_dir_t const *dir)
+{
+ dkChar const *back = NULL;
+
+
+#line 284 "dk3dir.ctr"
+ if(dir) {
+ back = dir->dirname;
+ }
+
+#line 287 "dk3dir.ctr"
+ return back;
+}
+
+
+
+void
+dk3dir_reset(dk3_dir_t *d)
+{
+
+
+#line 296 "dk3dir.ctr"
+ if(d) {
+ dk3sto_it_reset(d->idi);
+ dk3sto_it_reset(d->ifi);
+ d->shortname = NULL;
+ }
+
+#line 301 "dk3dir.ctr"
+}
+
+
+
+dk3_um_t
+dk3dir_get_number_of_directories(dk3_dir_t const *d)
+{
+ dk3_um_t back = DK3_UM_0;
+ if(d) {
+ back = d->ndir;
+ }
+
+#line 312 "dk3dir.ctr"
+ return back;
+}
+
+
+
+dk3_um_t
+dk3dir_get_number_of_files(dk3_dir_t const *d)
+{
+ dk3_um_t back = DK3_UM_0;
+ if(d) {
+ back = d->nfi;
+ }
+
+#line 324 "dk3dir.ctr"
+ return back;
+}
+
+
+
+dkChar const *
+dk3dir_get_fullname(dk3_dir_t const *d)
+{
+ dkChar const *back = NULL;
+
+
+#line 334 "dk3dir.ctr"
+ if(d) {
+ back = (dkChar const *)(d->fullname);
+ }
+
+#line 337 "dk3dir.ctr"
+ return back;
+}
+
+
+
+dk3_stat_t const *
+dk3dir_get_stat(dk3_dir_t *d)
+{
+ dk3_stat_t *back = NULL;
+
+
+#line 347 "dk3dir.ctr"
+ if(d) {
+ back = &(d->stb);
+ }
+
+#line 350 "dk3dir.ctr"
+ return back;
+}
+
+
+
+dkChar const *
+dk3dir_get_shortname(dk3_dir_t const *d)
+{
+ dkChar const *back = NULL;
+
+
+#line 360 "dk3dir.ctr"
+ if(d) {
+ back = (dkChar const *)(d->shortname);
+ }
+
+#line 363 "dk3dir.ctr"
+ return back;
+}
+
+
+
+/** Get next entry.
+ @param d Directory structure.
+ @param s Iterator for the storage.
+ @param isdir Flag: Current entry is a directory.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dir_get_next_entry(dk3_dir_t *d, dk3_sto_it_t *s, int isdir)
+{
+ int back = 0;
+ int cc = 1; /* Flag: Can continue. */
+ size_t sz = 0; /* Directory name length. */
+
+
+#line 382 "dk3dir.ctr"
+ do {
+ cc = 0;
+ d->shortname = (dkChar *)dk3sto_it_next(s);
+ if(d->shortname) {
+
+#line 386 "dk3dir.ctr"
+ cc = 1;
+ if(d->dirname) {
+ if(dk3str_len(d->dirname)) {
+ dk3str_cpy_not_overlapped(d->fullname, d->dirname);
+ sz = dk3str_len(d->dirname);
+ if(sz > 0) {
+ if((d->dirname)[sz - 1] != DK3_CHAR_SEP) {
+ dk3str_cat(d->fullname, kw[2]);
+ }
+ } else {
+ dk3str_cat(d->fullname, kw[2]);
+ }
+ dk3str_cat(d->fullname, d->shortname);
+ } else {
+ dk3str_cpy_not_overlapped(d->fullname, d->shortname);
+ }
+ } else {
+ dk3str_cpy_not_overlapped(d->fullname, d->shortname);
+ }
+ if(dk3sf_stat_app(&(d->stb), d->fullname, (dk3_app_t *)(d->app))) {
+ switch(((d->stb).ft) & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_DIRECTORY: {
+ if(isdir) {
+ back = 1; cc = 0;
+ }
+ } break;
+ default: {
+ if(!isdir) {
+ back = 1; cc = 0;
+ }
+ } break;
+ }
+ }
+ }
+
+#line 420 "dk3dir.ctr"
+ } while(cc);
+
+#line 421 "dk3dir.ctr"
+ return back;
+}
+
+
+
+int
+dk3dir_get_next_directory(dk3_dir_t *d)
+{
+ int back = 0;
+
+
+#line 431 "dk3dir.ctr"
+ if(d) {
+ back = dk3dir_get_next_entry(d, d->idi, 1);
+ }
+
+#line 434 "dk3dir.ctr"
+ return back;
+}
+
+
+
+int
+dk3dir_get_next_file(dk3_dir_t *d)
+{
+ int back = 0;
+
+
+#line 444 "dk3dir.ctr"
+ if(d) {
+ back = dk3dir_get_next_entry(d, d->ifi, 0);
+ }
+
+#line 447 "dk3dir.ctr"
+ return back;
+}
+
+
+
+/** Add a found item to a storage.
+ @param s Storage to add item to.
+ @param n Item name.
+ @param c Pointer to variable to increase to.
+ @param ec Pointer to error code variable.
+ @param app Application structure for diagnostics.
+*/
+static
+void
+dk3dir_add(dk3_sto_t *s, dkChar const *n, dk3_um_t *c, int *ec, dk3_app_t *app)
+{
+ dkChar *newname = NULL; /* New copy of name. */
+ dk3_um_t mu = DK3_UM_0; /* Number of entries. */
+
+
+#line 466 "dk3dir.ctr"
+ newname = dk3str_dup_app(n,(((*ec) & 1) ? NULL : app));
+ if(newname) {
+ if(dk3sto_add(s, newname)) {
+ mu = *c;
+ mu++;
+ *c = mu;
+ } else {
+ dk3_delete(newname);
+ *ec |= 2;
+
+#line 475 "dk3dir.ctr"
+ }
+ } else {
+ *ec |= 1;
+
+#line 478 "dk3dir.ctr"
+ }
+
+#line 479 "dk3dir.ctr"
+}
+
+
+
+#if DK3_ON_WINDOWS
+/* +++ Windows +++ */
+#if DK3_CHAR_SIZE > 1
+/* +++ Windows > 8 bit +++ */
+
+
+#if VERSION_BEFORE_2012_04_13
+
+dk3_dir_t *
+dk3dir_open_app(dkChar const *dn, dk3_app_t *app)
+{
+ dk3_dir_t *back = NULL;
+ int ec = 0; /* Error code. */
+ dkChar buffer[DK3_MAX_PATH]; /* Buffer for entry names. */
+ intptr_t ffres; /* Result of findfirst(). */
+ dkChar *namecopy = NULL; /* New copy of name. */
+ struct _wfinddata64_t ffdata; /* Find data. */
+ if(dn) {
+ if((dk3str_len(kw[3]) + dk3str_len(dn)) < DK3_SIZEOF(buffer,dkChar)) {
+ dk3str_cpy_not_overlapped(buffer, dn);
+ dk3str_cat(buffer, kw[3]);
+ back = dk3dir_new(dn, app);
+ if(back) {
+ ffres = _wfindfirst64(buffer, &ffdata);
+ if(ffres != -1) {
+ do {
+ if(dk3str_cmp(ffdata.name, kw[0])) {
+ if(dk3str_cmp(ffdata.name, kw[1])) {
+ if((ffdata.attrib) & _A_SUBDIR) {
+ dk3dir_add(back->sdi, ffdata.name, &(back->ndir), &ec, app);
+ } else {
+ dk3dir_add(back->sfi, ffdata.name, &(back->nfi), &ec, app);
+ }
+ }
+ }
+ } while(_wfindnext64(ffres, &ffdata) == 0);
+ _findclose(ffres);
+ } else {
+ ec |= 16;
+ if(app) {
+ /* ERROR: Failed to open directory! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 63, 64, dn);
+ }
+ }
+ }
+ if(ec) {
+ if(3 & ec) {
+ if(app) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 9);
+ }
+ }
+ dk3dir_close(back); back = NULL;
+ }
+ } else {
+ if(app) {
+ /* ERROR: Directory name too long! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 59, 60, dn);
+ }
+ }
+ }
+ return back;
+}
+
+
+dk3_dir_t *
+dk3dir_fne_open_app(dkChar const *fn, dk3_app_t *app)
+{
+ dk3_dir_t *back = NULL;
+ int ec = 0; /* Error code. */
+ dkChar mybuffer[DK3_MAX_PATH]; /* Buffer for entry names. */
+ dkChar myb2[2]; /* Search pattern. */
+ dkChar *ptr = NULL; /* Last separator. */
+ dkChar *namecopy = NULL; /* New copy of entry name. */
+ intptr_t ffres; /* Result from findfirst(). */
+ struct _wfinddata64_t ffdata; /* Find data. */
+
+
+#line 559 "dk3dir.ctr"
+ if(fn) {
+ if(dk3str_len(fn) < DK3_MAX_PATH) {
+ dk3str_cpy_not_overlapped(mybuffer, fn);
+ ptr = dk3str_rchr(mybuffer, DK3_CHAR_SEP);
+ if(ptr) {
+ *ptr = DK3_CHAR_0;
+ back = dk3dir_new(mybuffer, app);
+ *ptr = DK3_CHAR_SEP;
+ } else {
+ myb2[0] = DK3_CHAR_0;
+ back = dk3dir_new(myb2, app);
+ }
+ if(back) {
+
+#line 572 "dk3dir.ctr"
+ ffres = _wfindfirst64(mybuffer, &ffdata);
+ if(ffres != -1) {
+ do {
+
+#line 575 "dk3dir.ctr"
+ if(dk3str_cmp(ffdata.name, kw[0])) {
+
+#line 576 "dk3dir.ctr"
+ if(dk3str_cmp(ffdata.name, kw[1])) {
+
+#line 577 "dk3dir.ctr"
+ if((ffdata.attrib) & _A_SUBDIR) {
+
+#line 578 "dk3dir.ctr"
+ dk3dir_add(back->sdi, ffdata.name, &(back->ndir), &ec, app);
+ } else {
+
+#line 580 "dk3dir.ctr"
+ dk3dir_add(back->sfi, ffdata.name, &(back->nfi), &ec, app);
+ }
+ }
+ }
+ } while(_wfindnext64(ffres, &ffdata) == 0);
+ _findclose(ffres);
+ } else {
+ ec |= 16;
+ if(app) {
+ /* ERROR: Failed to open directory! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 215, 216, mybuffer);
+ }
+ }
+ }
+ if(ec) {
+ if(3 & ec) {
+ if(app) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 9);
+ }
+ }
+ dk3dir_close(back); back = NULL;
+ }
+ } else {
+ /* ERROR: Pattern too long! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 65, 66, fn);
+ }
+ }
+
+#line 607 "dk3dir.ctr"
+ return back;
+}
+
+
+#else
+
+
+static
+dk3_dir_t *
+dk3dir_my_open_app(dkChar const *dn, int usefne, dk3_app_t *app)
+{
+ WIN32_FIND_DATAW wfd; /* Details for file. */
+ dkChar b1[DK3_MAX_PATH]; /* Directory base. */
+ dkChar b2[DK3_MAX_PATH]; /* Pattern. */
+ dkChar *p1; /* Separator. */
+ dk3_dir_t *back = NULL;
+ HANDLE hSearch; /* File search handle. */
+ size_t sz; /* String length. */
+ int ok; /* Flag: No error yet. */
+ int ec; /* Error code. */
+ int isDir; /* Flag: Entry is dir. */
+
+
+#line 629 "dk3dir.ctr"
+ ec = 0;
+ if(dn) {
+ ok = 0;
+ if(usefne) {
+ if(dk3str_len(dn) < DK3_SIZEOF(b1,dkChar)) {
+ ok = 1;
+
+#line 635 "dk3dir.ctr"
+ dk3str_cpy_not_overlapped(b1, dn);
+ dk3str_cpy_not_overlapped(b2, dn);
+ p1 = dk3str_rchr(b1, DK3_CHAR_SEP);
+ if(p1) {
+ *p1 = dkT('\0');
+ } else {
+ b1[0] = dkT('\0');
+ }
+ } else {
+
+#line 644 "dk3dir.ctr"
+ /* ERROR: Name too long! */
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 65, 66, dn);
+ }
+ }
+ } else {
+ sz = dk3str_len(dn) + dk3str_len(kw[3]);
+ if(sz < DK3_SIZEOF(b1,dkChar)) {
+ ok = 1;
+
+#line 653 "dk3dir.ctr"
+ dk3str_cpy_not_overlapped(b1, dn);
+ dk3str_cpy_not_overlapped(b2, dn);
+ sz = dk3str_len(b2);
+ if(sz > 1) {
+ dk3str_cat(b2, kw[(DK3_CHAR_SEP == b2[sz - 1]) ? 4 : 3]);
+ } else {
+ dk3str_cat(b2, kw[3]);
+ }
+ } else {
+
+#line 662 "dk3dir.ctr"
+ /* Name too long! */
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 59, 60, dn);
+ }
+ }
+ }
+ if(ok) {
+
+#line 669 "dk3dir.ctr"
+ back = dk3dir_new(b1, app);
+ if(back) {
+
+#line 671 "dk3dir.ctr"
+ hSearch = FindFirstFileW(b2, &wfd);
+ if(INVALID_HANDLE_VALUE != hSearch) {
+
+#line 673 "dk3dir.ctr"
+ do {
+ isDir = 0;
+
+#line 675 "dk3dir.ctr"
+ if(dk3str_cmp(wfd.cFileName, kw[0])) {
+ if(dk3str_cmp(wfd.cFileName, kw[1])) {
+
+#line 677 "dk3dir.ctr"
+ if((wfd.dwFileAttributes) & FILE_ATTRIBUTE_DIRECTORY) {
+ isDir = 1;
+#if 0
+ if((wfd.dwFileAttributes) & FILE_ATTRIBUTE_REPARSE_POINT) {
+ switch(wfd.dwReserved0) {
+ case IO_REPARSE_TAG_MOUNT_POINT: {
+ isDir = 0;
+ } break;
+ }
+ }
+#endif
+ }
+ if(isDir) {
+
+#line 690 "dk3dir.ctr"
+ dk3dir_add(back->sdi, wfd.cFileName, &(back->ndir), &ec, app);
+ } else {
+
+#line 692 "dk3dir.ctr"
+ dk3dir_add(back->sfi, wfd.cFileName, &(back->nfi), &ec, app);
+ }
+ }
+ }
+ } while(FindNextFileW(hSearch, &wfd));
+ FindClose(hSearch);
+ } else {
+
+#line 699 "dk3dir.ctr"
+ /* ERROR: Failed to search for pattern! */
+ ec |= 16;
+ if(app) {
+ if(usefne) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 215, 216, dn);
+ } else {
+ dk3app_log_i3(app, DK3_LL_ERROR, 63, 64, dn);
+ }
+ }
+ }
+ if(ec) {
+ if(3 & ec) {
+ if(app) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 9);
+ }
+ }
+ dk3dir_close(back); back = NULL;
+ }
+ } else {
+
+#line 718 "dk3dir.ctr"
+ }
+ }
+ } else {
+
+#line 721 "dk3dir.ctr"
+ }
+
+#line 722 "dk3dir.ctr"
+ return back;
+}
+
+
+
+dk3_dir_t *
+dk3dir_open_app(dkChar const *dn, dk3_app_t *app)
+{
+ dk3_dir_t *back;
+
+
+#line 732 "dk3dir.ctr"
+ back = dk3dir_my_open_app(dn, 0, app);
+
+
+#line 734 "dk3dir.ctr"
+ return back;
+}
+
+
+dk3_dir_t *
+dk3dir_fne_open_app(dkChar const *fn, dk3_app_t *app)
+{
+ dk3_dir_t *back;
+
+
+#line 743 "dk3dir.ctr"
+ back = dk3dir_my_open_app(fn, 1, app);
+
+
+#line 745 "dk3dir.ctr"
+ return back;
+}
+
+
+#endif
+
+
+/* --- Windows > 8 bit --- */
+#else
+/* +++ Windows, 8 bit +++ */
+
+
+
+#if VERSION_BEFORE_2012_04_13
+
+dk3_dir_t *
+dk3dir_open_app(dkChar const *dn, dk3_app_t *app)
+{
+ dk3_dir_t *back = NULL;
+ int ec = 0; /* Error code. */
+ dkChar buffer[DK3_MAX_PATH]; /* Buffer for entry names. */
+ intptr_t ffres; /* Result from findfirst(). */
+ dkChar *namecopy = NULL; /* New copy of entry name. */
+ struct __finddata64_t ffdata; /* Find data. */
+ if(dn) {
+ if((dk3str_len(kw[3]) + dk3str_len(dn)) < DK3_SIZEOF(buffer,dkChar)) {
+ dk3str_cpy_not_overlapped(buffer, dn);
+ dk3str_cat(buffer, kw[3]);
+ back = dk3dir_new(dn, app);
+ if(back) {
+ ffres = _findfirst64(buffer, &ffdata);
+ if(ffres != -1) {
+ do {
+ if(dk3str_cmp(ffdata.name, kw[0])) {
+ if(dk3str_cmp(ffdata.name, kw[1])) {
+ if((ffdata.attrib) & _A_SUBDIR) {
+ dk3dir_add(back->sdi, ffdata.name, &(back->ndir), &ec, app);
+ } else {
+ dk3dir_add(back->sfi, ffdata.name, &(back->nfi), &ec, app);
+ }
+ }
+ }
+ } while(_findnext64(ffres, &ffdata) == 0);
+ _findclose(ffres);
+ } else {
+ ec |= 16; /* Findfirst failed */
+ if(app) {
+ /* ERROR: Findfirst failed! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 63, 64, dn);
+ }
+ }
+ }
+ if(ec) {
+ if(3 & ec) {
+ if(app) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 9);
+ }
+ }
+ dk3dir_close(back); back = NULL;
+ }
+ } else {
+ if(app) {
+ /* ERROR: Directory name too long! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 59, 60, dn);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+dk3_dir_t *
+dk3dir_fne_open_app(dkChar const *fn, dk3_app_t *app)
+{
+ dk3_dir_t *back = NULL;
+ int ec = 0; /* Error code. */
+ dkChar mybuffer[DK3_MAX_PATH]; /* Buffer for entry name. */
+ dkChar myb2[2]; /* Buffer for pattern. */
+ dkChar *ptr = NULL; /* Last separator. */
+ dkChar *namecopy = NULL; /* New copy of entry name. */
+ intptr_t ffres; /* Result from findfirst(). */
+ struct __finddata64_t ffdata; /* Find data. */
+
+
+#line 829 "dk3dir.ctr"
+ if(fn) {
+ if(dk3str_len(fn) < DK3_MAX_PATH) {
+ dk3str_cpy_not_overlapped(mybuffer, fn);
+ ptr = dk3str_rchr(mybuffer, DK3_CHAR_SEP);
+ if(ptr) {
+ *ptr = DK3_CHAR_0;
+ back = dk3dir_new(mybuffer, app);
+ *ptr = DK3_CHAR_SEP;
+ } else {
+ myb2[0] = DK3_CHAR_0;
+ back = dk3dir_new(myb2, app);
+ }
+ if(back) {
+ ffres = _findfirst64(mybuffer, &ffdata);
+ if(ffres != -1) {
+ do {
+ if(dk3str_cmp(ffdata.name, kw[0])) {
+ if(dk3str_cmp(ffdata.name, kw[1])) {
+ if((ffdata.attrib) & _A_SUBDIR) {
+ dk3dir_add(back->sdi, ffdata.name, &(back->ndir), &ec, app);
+ } else {
+ dk3dir_add(back->sfi, ffdata.name, &(back->nfi), &ec, app);
+ }
+ }
+ }
+ } while(_findnext64(ffres, &ffdata) == 0);
+ _findclose(ffres);
+ } else {
+ ec |= 16;
+ if(app) {
+ /* ERROR: Failed to open directory! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 215, 216, mybuffer);
+ }
+ }
+ }
+ if(ec) {
+ if(3 & ec) {
+ if(app) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 9);
+ }
+ }
+ dk3dir_close(back); back = NULL;
+ }
+ } else {
+ if(app) {
+ /* ERROR: Pattern too long! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 65, 66, fn);
+ }
+ }
+ }
+
+#line 879 "dk3dir.ctr"
+ return back;
+}
+
+
+#else
+
+
+
+static
+dk3_dir_t *
+dk3dir_my_open_app(dkChar const *dn, int usefne, dk3_app_t *app)
+{
+ WIN32_FIND_DATAA wfd; /* Details for file. */
+ dkChar b1[DK3_MAX_PATH]; /* Directory base. */
+ dkChar b2[DK3_MAX_PATH]; /* Pattern. */
+ dkChar *p1; /* Separator. */
+ dk3_dir_t *back = NULL;
+ HANDLE hSearch; /* File search handle. */
+ size_t sz; /* String length. */
+ int ok; /* Flag: No error yet. */
+ int ec; /* Error code. */
+ int isDir; /* Flag: Entry is dir. */
+
+
+#line 902 "dk3dir.ctr"
+ ec = 0;
+ if(dn) {
+ ok = 0;
+ if(usefne) {
+ if(dk3str_len(dn) < DK3_SIZEOF(b1,dkChar)) {
+ ok = 1;
+
+#line 908 "dk3dir.ctr"
+ dk3str_cpy_not_overlapped(b1, dn);
+ dk3str_cpy_not_overlapped(b2, dn);
+ p1 = dk3str_rchr(b1, DK3_CHAR_SEP);
+ if(p1) {
+ *p1 = dkT('\0');
+ } else {
+ b1[0] = dkT('\0');
+ }
+ } else {
+
+#line 917 "dk3dir.ctr"
+ /* ERROR: Name too long! */
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 65, 66, dn);
+ }
+ }
+ } else {
+ sz = dk3str_len(dn) + dk3str_len(kw[3]);
+ if(sz < DK3_SIZEOF(b1,dkChar)) {
+ ok = 1;
+
+#line 926 "dk3dir.ctr"
+ dk3str_cpy_not_overlapped(b1, dn);
+ dk3str_cpy_not_overlapped(b2, dn);
+ sz = dk3str_len(b2);
+ if(sz > 1) {
+ dk3str_cat(b2, kw[(DK3_CHAR_SEP == b2[sz - 1]) ? 4 : 3]);
+ } else {
+ dk3str_cat(b2, kw[3]);
+ }
+ } else {
+
+#line 935 "dk3dir.ctr"
+ /* ERROR: Name too long! */
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 59, 60, dn);
+ }
+ }
+ }
+ if(ok) {
+
+#line 942 "dk3dir.ctr"
+ back = dk3dir_new(b1, app);
+ if(back) {
+
+#line 944 "dk3dir.ctr"
+ hSearch = FindFirstFileA(b2, &wfd);
+ if(INVALID_HANDLE_VALUE != hSearch) {
+
+#line 946 "dk3dir.ctr"
+ do {
+ isDir = 0;
+
+#line 948 "dk3dir.ctr"
+ if(dk3str_cmp(wfd.cFileName, kw[0])) {
+ if(dk3str_cmp(wfd.cFileName, kw[1])) {
+
+#line 950 "dk3dir.ctr"
+ if((wfd.dwFileAttributes) & FILE_ATTRIBUTE_DIRECTORY) {
+ isDir = 1;
+#if 0
+ if((wfd.dwFileAttributes) & FILE_ATTRIBUTE_REPARSE_POINT) {
+ switch(wfd.dwReserved0) {
+ case IO_REPARSE_TAG_MOUNT_POINT: {
+ isDir = 0;
+ } break;
+ }
+ }
+#endif
+ }
+ if(isDir) {
+
+#line 963 "dk3dir.ctr"
+ dk3dir_add(back->sdi, wfd.cFileName, &(back->ndir), &ec, app);
+ } else {
+
+#line 965 "dk3dir.ctr"
+ dk3dir_add(back->sfi, wfd.cFileName, &(back->nfi), &ec, app);
+ }
+ }
+ }
+ } while(FindNextFileA(hSearch, &wfd));
+ FindClose(hSearch);
+ } else {
+
+#line 972 "dk3dir.ctr"
+ /* ERROR: Failed to search for pattern! */
+ ec |= 16;
+ if(app) {
+ if(usefne) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 215, 216, dn);
+ } else {
+ dk3app_log_i3(app, DK3_LL_ERROR, 63, 64, dn);
+ }
+ }
+ }
+ if(ec) {
+ if(3 & ec) {
+ if(app) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 9);
+ }
+ }
+ dk3dir_close(back); back = NULL;
+ }
+ } else {
+
+#line 991 "dk3dir.ctr"
+ }
+ }
+ } else {
+
+#line 994 "dk3dir.ctr"
+ }
+
+#line 995 "dk3dir.ctr"
+ return back;
+}
+
+
+
+dk3_dir_t *
+dk3dir_open_app(dkChar const *dn, dk3_app_t *app)
+{
+ dk3_dir_t *back;
+
+
+#line 1005 "dk3dir.ctr"
+ back = dk3dir_my_open_app(dn, 0, app);
+
+
+#line 1007 "dk3dir.ctr"
+ return back;
+}
+
+
+dk3_dir_t *
+dk3dir_fne_open_app(dkChar const *fn, dk3_app_t *app)
+{
+ dk3_dir_t *back;
+
+
+#line 1016 "dk3dir.ctr"
+ back = dk3dir_my_open_app(fn, 1, app);
+
+
+#line 1018 "dk3dir.ctr"
+ return back;
+}
+
+
+
+#endif
+
+/* --- Windows, 8 bit --- */
+#endif
+/* --- Windows --- */
+#else
+/* +++ non-Windows +++ */
+#if DK3_CHAR_SIZE > 1
+/* +++ non-Windows > 8 bit +++ */
+#error "16/32-bit file names only available on Windows!"
+/* --- non-Windows > 8 bit --- */
+#else
+/* +++ non-Windows, 8 bit +++ */
+
+
+
+/** Function names used in error messages.
+*/
+static dkChar const * const dk3dir_function_names[] = {
+/* 0 */
+dkT("opendir: "),
+
+NULL
+
+
+#line 1048 "dk3dir.ctr"
+};
+
+
+
+#if DK3_HAVE_OPENDIR && DK3_HAVE_READDIR && DK3_HAVE_CLOSEDIR
+
+
+
+dk3_dir_t *
+dk3dir_open_app(dkChar const *dn, dk3_app_t *app)
+{
+ dk3_dir_t *back = NULL;
+ int ec = 0; /* Error code. */
+ struct dirent *de = NULL; /* Directory entry from readdir(). */
+ DIR *d = NULL; /* Directory structure from opendir(). */
+ size_t sz = 0; /* Length of entire file name. */
+ size_t dns = 0; /* Directory name length. */
+ size_t kw2l = 0; /* Length of separator string. */
+ dk3_stat_t stb; /* Buffer for stat() result. */
+
+
+#line 1068 "dk3dir.ctr"
+ if(dn) {
+ back = dk3dir_new(dn, app);
+ if(back) {
+ d = opendir(dn);
+ if(d) {
+ dns = dk3str_len(dn); kw2l = dk3str_len(kw[2]);
+ while((de = readdir(d)) != NULL) {
+ if(dk3str_cmp(de->d_name, kw[0])) {
+ if(dk3str_cmp(de->d_name, kw[1])) {
+ sz = dns + kw2l + dk3str_len(de->d_name);
+ if(sz < DK3_MAX_PATH) {
+ dk3str_cpy_not_overlapped(back->fullname, dn);
+ dk3str_cat(back->fullname, kw[2]);
+ dk3str_cat(back->fullname, de->d_name);
+ if(dk3sf_stat_app(&stb, back->fullname, NULL)) {
+ switch((stb.ft) & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_DIRECTORY: {
+ dk3dir_add(back->sdi,de->d_name,&(back->ndir),&ec,app);
+ } break;
+ default: {
+ dk3dir_add(back->sfi,de->d_name,&(back->nfi),&ec,app);
+ } break;
+ }
+ } else {
+ if(!(ec & 8)) {
+ if(app) {
+ /* Stat failed! */
+ dk3app_log_i3(app,DK3_LL_ERROR,61,62,back->fullname);
+ }
+ } ec |= 8;
+ }
+ } else {
+ if(!(ec & 4)) {
+ if(app) {
+ /* Directory name too long! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 59, 60, dn);
+ }
+ } ec |= 4;
+ }
+ }
+ }
+ }
+ closedir(d);
+ } else {
+ ec |= 16;
+ if(app) {
+ /* Failed to open directory! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 63, 64, dn);
+ dk3sf_report_errno(app, errno, dk3dir_function_names[0]);
+ }
+ }
+ if(ec) {
+ if(3 & ec) {
+ if(app) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 9);
+ }
+ }
+ dk3dir_close(back); back = NULL;
+ }
+ }
+ }
+
+#line 1129 "dk3dir.ctr"
+ return back;
+}
+
+
+
+dk3_dir_t *
+dk3dir_fne_open_app(dkChar const *fn, dk3_app_t *app)
+{
+ dk3_dir_t *back = NULL;
+ int ec = 0; /* Error code. */
+ dk3_stat_t stb; /* Stat buffer. */
+ dkChar mybuffer[DK3_MAX_PATH]; /* Buffer for entire file name. */
+ dkChar myb2[2]; /* Pattern buffer. */
+ dkChar *ptr; /* Last separator in pattern. */
+
+
+#line 1144 "dk3dir.ctr"
+ if(fn) {
+ if(dk3str_len(fn) < DK3_MAX_PATH) {
+ dk3str_cpy_not_overlapped(mybuffer, fn);
+ if(dk3sf_stat_app(&stb, fn, app)) {
+ ptr = dk3str_rchr(mybuffer, DK3_CHAR_SEP);
+ if(ptr) {
+ *(ptr++) = DK3_CHAR_0;
+ back = dk3dir_new(mybuffer, app);
+ } else {
+ myb2[0] = DK3_CHAR_0;
+ back = dk3dir_new(myb2, app);
+ ptr = mybuffer;
+ }
+ if(back) {
+ switch((stb.ft) & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_DIRECTORY: {
+ dk3dir_add(back->sdi, ptr, &(back->ndir), &ec, app);
+ } break;
+ default: {
+ dk3dir_add(back->sfi, ptr, &(back->nfi), &ec, app);
+ } break;
+ }
+ if(ec) {
+ if(3 & ec) {
+ if(app) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 9);
+ }
+ }
+ dk3dir_close(back); back = NULL;
+ }
+ }
+ }
+ } else {
+ if(app) {
+ /* Name too long! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 65, 66, fn);
+ }
+ }
+ }
+
+#line 1183 "dk3dir.ctr"
+ return back;
+}
+
+
+
+#else
+#error "No opendir()/readdir()/closedir() function set!"
+#endif
+
+/* --- non-Windows, 8 bit --- */
+#endif
+/* --- non-Windows --- */
+#endif
+
+
+/** Directory chain cell.
+*/
+struct _dk3_dir_cell_t_ {
+ struct _dk3_dir_cell_t_ *parent; /**< Parent cell. */
+ dk3_dir_t *dir; /**< Directory structure. */
+};
+/** Directory chain cell.
+*/
+typedef struct _dk3_dir_cell_t_ DK3_DIR_CELL;
+
+
+
+/** Destroy chain cell, release memory.
+ @param c Cell to destroy.
+*/
+static
+void
+dk3dir_cell_delete(DK3_DIR_CELL *c)
+{
+ if(c) {
+ if(c->dir) {
+ dk3dir_close(c->dir);
+ }
+ c->dir = NULL;
+ c->parent = NULL;
+ dk3_delete(c);
+ }
+}
+
+
+
+/** Create directory cell, allocate memory.
+ @param n Directory name.
+ @param p Parent cell in chain.
+ @param app Application structure for diagnostics.
+ @return Pointer to new cell on success, NULL on error.
+*/
+static
+DK3_DIR_CELL *
+dk3dir_cell_new(dkChar const *n, DK3_DIR_CELL *p, dk3_app_t *app)
+{
+ DK3_DIR_CELL *back = NULL;
+ back = dk3_new_app(DK3_DIR_CELL,1,app);
+ if(back) {
+ back->parent = p;
+ back->dir = dk3dir_open_app(n, app);
+ if(!(back->dir)) {
+ dk3dir_cell_delete(back); back = NULL;
+ }
+ }
+ return back;
+}
+
+
+
+#if DK3_ON_WINDOWS
+/** Remove a directory reparse point.
+ @param dn Directory to remove.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dir_remove_reparse_point(dkChar const *dn, dk3_app_t *app)
+{
+ int back = 0;
+ if(dk3sf_remove_dir_app(dn, app)) {
+ back = 1;
+ } else {
+ if(dk3sf_remove_file_app(dn, app)) {
+ back = 1;
+ }
+ }
+ return back;
+}
+#endif
+
+
+
+int
+dk3dir_remove_app(dkChar const *dn, dk3_app_t *app)
+{
+ int back = 0;
+ dk3_stat_t stb; /* Stat buffer. */
+ dkChar const *en = NULL; /* Entry name. */
+ dkChar const *xdn; /* Current dir to delete. */
+ dk3_stat_t const *es = NULL; /* Entry stat buffer. */
+ DK3_DIR_CELL *ccell = NULL; /* Current cell. */
+ DK3_DIR_CELL *ncell = NULL; /* New cell or next cell. */
+#if VERSION_BEFORE_20150821
+ int ft; /* File type. */
+#endif
+
+ if(dn) {
+ if(dk3sf_stat_app(&stb, dn, app)) {
+ if((stb.ft) & DK3_FT_SYMLINK) { /* symbolic link */
+ /* Removing symbolic link only, not target! */
+ back = dk3sf_remove_file_app(dn, app);
+ } else {
+ if(stb.ft == DK3_FT_DIRECTORY) {
+
+#if DK3_ON_WINDOWS
+ if(0x00 == stb.cReparse) {
+#endif
+ ccell = dk3dir_cell_new(dn, NULL, app);
+ if(ccell) {
+ back = 1;
+ while(ccell) {
+ if(dk3dir_get_next_directory(ccell->dir)) {
+ en = dk3dir_get_fullname(ccell->dir);
+ if(en) {
+ es = dk3dir_get_stat(ccell->dir);
+ if(es) {
+ if((es->ft) & DK3_FT_SYMLINK) {
+ if(!dk3sf_remove_file_app(en, app)) {
+ back = 0;
+ }
+ } else {
+#if DK3_ON_WINDOWS
+ if(0x00 == es->cReparse) {
+#endif
+ ncell = dk3dir_cell_new(en, ccell, app);
+ if(ncell) {
+ ccell = ncell;
+ } else {
+ back = 0;
+ }
+#if DK3_ON_WINDOWS
+ } else {
+ if(!dk3dir_remove_reparse_point(en, app)) {
+ back = 0;
+ }
+ }
+#endif
+ }
+ } else {
+ back = 0;
+ /* BUG: Internal error. */
+ }
+ } else {
+ back = 0;
+ /* BUG: Internal error. */
+ }
+ } else {
+ while(dk3dir_get_next_file(ccell->dir)) {
+#if VERSION_BEFORE_20150821
+ ft = DK3_FT_REGULAR;
+#endif
+ en = dk3dir_get_fullname(ccell->dir);
+#if VERSION_BEFORE_20150821
+ es = dk3dir_get_stat(ccell->dir);
+ if(es) { ft = es->ft; }
+#endif
+ if(en) {
+ if(!dk3sf_remove_file_app(en, app)) {
+ back = 0;
+ }
+ } else {
+ back = 0;
+ /* BUG: Internal error. */
+ }
+ }
+ ncell = ccell->parent;
+ if(ccell->dir) {
+ xdn = dk3dir_get_directory_name(ccell->dir);
+ if(xdn) {
+ if(!dk3sf_remove_dir_app(xdn, app)) {
+ back = 0;
+ }
+ }
+ }
+ dk3dir_cell_delete(ccell);
+ ccell = ncell;
+ }
+ }
+ }
+#if DK3_ON_WINDOWS
+ } else {
+ if(!dk3dir_remove_reparse_point(dn, app)) {
+ back = 0;
+ }
+ }
+#endif
+ } else {
+ /* ERROR: Not a directory! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 202, 203, dn);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dk3dir.ctr b/support/dktools/dk3dir.ctr
new file mode 100644
index 0000000000..18b2b1d5f3
--- /dev/null
+++ b/support/dktools/dk3dir.ctr
@@ -0,0 +1,1394 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% header
+
+#include "dk3conf.h"
+#include "dk3types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** Open a directory.
+ @param dn Directory name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to directory structure on success, NULL on error.
+*/
+dk3_dir_t *
+dk3dir_open_app(dkChar const *dn, dk3_app_t *app);
+
+/** Open directory structure to expand a file name.
+ @param fn File name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to directory structure on success, NULL on errror.
+*/
+dk3_dir_t *
+dk3dir_fne_open_app(dkChar const *fn, dk3_app_t *app);
+
+/** Close directory.
+ @param dp Directory to close.
+*/
+void
+dk3dir_close(dk3_dir_t *dp);
+
+/** Get number of subdirectories.
+ @param d Directory structure.
+ @return Number of subdirectories.
+*/
+dk3_um_t
+dk3dir_get_number_of_directories(dk3_dir_t const *d);
+
+/** Get number of files.
+ @param d Directory structure.
+ @return Number of non-directory entries in directory.
+*/
+dk3_um_t
+dk3dir_get_number_of_files(dk3_dir_t const *d);
+
+/** Attempt to retrieve information about the next sub-directory.
+ @param d Directory structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dir_get_next_directory(dk3_dir_t *d);
+
+/** Attempt to retrieve information about the next non-sub-directory entry.
+ @param d Directory structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dir_get_next_file(dk3_dir_t *d);
+
+/** Retrieve short file name of entry found.
+ May be used after a successful call to dk3dir_get_next_directory() or
+ dk3dir_get_next_file() only.
+ @param d Directory structure.
+ @return Pointer to file name on success, NULL on error.
+*/
+dkChar const *
+dk3dir_get_shortname(dk3_dir_t const *d);
+
+/** Retrieve full file name of entry found.
+ May be used after a successful call to dk3dir_get_next_directory() or
+ dk3dir_get_next_file() only.
+ @param d Directory structure.
+ @return Pointer to file name on success, NULL on error.
+*/
+dkChar const *
+dk3dir_get_fullname(dk3_dir_t const *d);
+
+/** Retrieve file status information.
+ May be used after a successful call to dk3dir_get_next_directory() or
+ dk3dir_get_next_file() only.
+ @param d Directory structure.
+ @return Pointer to file name on success, NULL on error.
+*/
+dk3_stat_t const *
+dk3dir_get_stat(dk3_dir_t *d);
+
+/** Reset directory for new traversal.
+ @param d Directory structure.
+*/
+void
+dk3dir_reset(dk3_dir_t *d);
+
+/** Retrieve directory name.
+ @param dir Directory structure.
+ @return Directory path name.
+*/
+dkChar const *
+dk3dir_get_directory_name(dk3_dir_t const *dir);
+
+/** Remove directory recursively, including all contents.
+ @param dn Directory name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dir_remove_app(dkChar const *dn, dk3_app_t *app);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk3all.h"
+
+
+
+$!trace-include
+
+
+
+/* Error flags used in ec:
+ 1 Failed to allocate memory for name to save.
+ 2 Failed to save name to storage.
+ 4 Directory name too long.
+ 8 stat() failed for full name.
+ 16 Failed to list directory contents.
+*/
+
+/** Keywords and texts used in this module.
+*/
+static dkChar const * const kw[] = {
+/* 0 */ dkT("."),
+/* 1 */ dkT(".."),
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+/* 2 */ dkT("\\"),
+/* 3 */ dkT("\\*"),
+#else
+/* 2 */ dkT("/"),
+/* 3 */ dkT("/*"),
+#endif
+/* 4 */ dkT("*"),
+NULL
+};
+
+
+
+/** Compare two directory entries by name.
+ @param l Left name.
+ @param r Right name.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+static
+int
+dk3dir_compare_by_name(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ if(l) {
+ if(r) {
+#if DK3_ON_WINDOWS || DK3_HAVE_FNCASEINS
+ back = dk3str_casecmp((dkChar const *)l,(dkChar const *)r);
+#else
+ back = dk3str_cmp((dkChar const *)l,(dkChar const *)r);
+#endif
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+/** Release all directory entries in a storage.
+ @param s Storage to clean up.
+ @param i Iterator for \a s.
+*/
+static
+void
+dk3dir_release_entries(dk3_sto_t *s, dk3_sto_it_t *i)
+{
+ dkChar *p = NULL; /* Current name to release. */
+ $? "+ dk3dir_release_entries"
+ if(s) {
+ if(i) {
+ dk3sto_it_reset(i);
+ while((p = (dkChar *)dk3sto_it_next(i)) != NULL) {
+ $? ". release entry %!ds", p
+ dk3_delete(p);
+ }
+ dk3sto_it_close(i);
+ }
+ dk3sto_close(s);
+ } $? "- dk3dir_release_entries"
+}
+
+
+
+/** Close directory.
+ @param dp Directory to close.
+*/
+void
+dk3dir_close(dk3_dir_t *dp)
+{
+ $? "+ dk3dir_close"
+ if(dp) {
+ dk3dir_release_entries(dp->sdi, dp->idi);
+ dk3dir_release_entries(dp->sfi, dp->ifi);
+ dp->sdi = NULL; dp->sfi = NULL; dp->idi = NULL; dp->ifi = NULL;
+ dk3_release(dp->dirname);
+ dk3_release(dp->fullname);
+ dp->app = NULL;
+ dp->ndir = dp->nfi = DK3_UM_0;
+ dk3_delete(dp);
+ } $? "- dk3dir_close"
+}
+
+
+
+/** Create new dir structure.
+ @param dn Directory name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new structure on success, NULL on error.
+*/
+static
+dk3_dir_t *
+dk3dir_new(dkChar const *dn, dk3_app_t *app)
+{
+ dk3_dir_t *back = NULL;
+ int ok = 0; /* Flag: Success. */
+ $? "+ dk3dir_new \"%!ds\"", TR_STR(dn)
+ back = dk3_new_app(dk3_dir_t,1,app);
+ if(back) {
+ back->sdi = NULL; back->sfi = NULL; back->idi = NULL; back->ifi = NULL;
+ back->dirname = NULL; back->fullname = NULL; back->app = app;
+ back->ndir = back->nfi = DK3_UM_0;
+ back->sdi = dk3sto_open_app(app);
+ if(back->sdi) {
+ back->idi = dk3sto_it_open(back->sdi);
+ if(back->idi) {
+ back->sfi = dk3sto_open_app(app);
+ if(back->sfi) {
+ back->ifi = dk3sto_it_open(back->sfi);
+ if(back->ifi) {
+ dk3sto_set_comp(back->sdi,dk3dir_compare_by_name,0);
+ dk3sto_set_comp(back->sfi,dk3dir_compare_by_name,0);
+ back->dirname = dk3str_dup_app(dn, NULL);
+ if(back->dirname) {
+ back->fullname = dk3_new_app(dkChar,DK3_MAX_PATH,app);
+ if(back->fullname) {
+ ok = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ if(!ok) {
+ dk3dir_close(back); back = NULL;
+ }
+ } $? "- dk3dir_new %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+dkChar const *
+dk3dir_get_directory_name(dk3_dir_t const *dir)
+{
+ dkChar const *back = NULL;
+ $? "+ dk3dir_get_directory_name"
+ if(dir) {
+ back = dir->dirname;
+ } $? "- dk3dir_get_directory_name \"%!ds\"", TR_STR(back)
+ return back;
+}
+
+
+
+void
+dk3dir_reset(dk3_dir_t *d)
+{
+ $? "+ dk3dir_reset"
+ if(d) {
+ dk3sto_it_reset(d->idi);
+ dk3sto_it_reset(d->ifi);
+ d->shortname = NULL;
+ } $? "- dk3dir_reset"
+}
+
+
+
+dk3_um_t
+dk3dir_get_number_of_directories(dk3_dir_t const *d)
+{
+ dk3_um_t back = DK3_UM_0;
+ if(d) {
+ back = d->ndir;
+ } $? "= dk3dir_get_number_of_directories %lu", (unsigned long)back
+ return back;
+}
+
+
+
+dk3_um_t
+dk3dir_get_number_of_files(dk3_dir_t const *d)
+{
+ dk3_um_t back = DK3_UM_0;
+ if(d) {
+ back = d->nfi;
+ } $? "= dk3dir_get_number_of_files %lu", (unsigned long)back
+ return back;
+}
+
+
+
+dkChar const *
+dk3dir_get_fullname(dk3_dir_t const *d)
+{
+ dkChar const *back = NULL;
+ $? "+ dk3dir_get_fullname"
+ if(d) {
+ back = (dkChar const *)(d->fullname);
+ } $? "- dk3dir_get_fullname \"%!ds\"", TR_STR(back)
+ return back;
+}
+
+
+
+dk3_stat_t const *
+dk3dir_get_stat(dk3_dir_t *d)
+{
+ dk3_stat_t *back = NULL;
+ $? "+ dk3dir_get_stat"
+ if(d) {
+ back = &(d->stb);
+ } $? "- dk3dir_get_stat %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+dkChar const *
+dk3dir_get_shortname(dk3_dir_t const *d)
+{
+ dkChar const *back = NULL;
+ $? "+ dk3dir_get_shortname"
+ if(d) {
+ back = (dkChar const *)(d->shortname);
+ } $? "- dk3dir_get_shortname \"%!ds\"", TR_STR(back)
+ return back;
+}
+
+
+
+/** Get next entry.
+ @param d Directory structure.
+ @param s Iterator for the storage.
+ @param isdir Flag: Current entry is a directory.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dir_get_next_entry(dk3_dir_t *d, dk3_sto_it_t *s, int isdir)
+{
+ int back = 0;
+ int cc = 1; /* Flag: Can continue. */
+ size_t sz = 0; /* Directory name length. */
+ $? "+ dk3dir_get_next_entry dir=%d", isdir
+ do {
+ cc = 0;
+ d->shortname = (dkChar *)dk3sto_it_next(s);
+ if(d->shortname) { $? ". shortname = \"%!ds\"", d->shortname
+ cc = 1;
+ if(d->dirname) {
+ if(dk3str_len(d->dirname)) {
+ dk3str_cpy_not_overlapped(d->fullname, d->dirname);
+ sz = dk3str_len(d->dirname);
+ if(sz > 0) {
+ if((d->dirname)[sz - 1] != DK3_CHAR_SEP) {
+ dk3str_cat(d->fullname, kw[2]);
+ }
+ } else {
+ dk3str_cat(d->fullname, kw[2]);
+ }
+ dk3str_cat(d->fullname, d->shortname);
+ } else {
+ dk3str_cpy_not_overlapped(d->fullname, d->shortname);
+ }
+ } else {
+ dk3str_cpy_not_overlapped(d->fullname, d->shortname);
+ }
+ if(dk3sf_stat_app(&(d->stb), d->fullname, (dk3_app_t *)(d->app))) {
+ switch(((d->stb).ft) & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_DIRECTORY: {
+ if(isdir) {
+ back = 1; cc = 0;
+ }
+ } break;
+ default: {
+ if(!isdir) {
+ back = 1; cc = 0;
+ }
+ } break;
+ }
+ }
+ } $? ". cc = %d shortname=\"%!ds\"", cc, TR_STR(d->shortname)
+ } while(cc); $? "- dk3dir_get_next_entry %d", back
+ return back;
+}
+
+
+
+int
+dk3dir_get_next_directory(dk3_dir_t *d)
+{
+ int back = 0;
+ $? "+ dk3dir_get_next_directory"
+ if(d) {
+ back = dk3dir_get_next_entry(d, d->idi, 1);
+ } $? "- dk3dir_get_next_directory %d", back
+ return back;
+}
+
+
+
+int
+dk3dir_get_next_file(dk3_dir_t *d)
+{
+ int back = 0;
+ $? "+ dk3dir_get_next_file"
+ if(d) {
+ back = dk3dir_get_next_entry(d, d->ifi, 0);
+ } $? "- dk3dir_get_next_file %d", back
+ return back;
+}
+
+
+
+/** Add a found item to a storage.
+ @param s Storage to add item to.
+ @param n Item name.
+ @param c Pointer to variable to increase to.
+ @param ec Pointer to error code variable.
+ @param app Application structure for diagnostics.
+*/
+static
+void
+dk3dir_add(dk3_sto_t *s, dkChar const *n, dk3_um_t *c, int *ec, dk3_app_t *app)
+{
+ dkChar *newname = NULL; /* New copy of name. */
+ dk3_um_t mu = DK3_UM_0; /* Number of entries. */
+ $? "+ dk3dir_add \"%!ds\"", TR_STR(n)
+ newname = dk3str_dup_app(n,(((*ec) & 1) ? NULL : app));
+ if(newname) {
+ if(dk3sto_add(s, newname)) {
+ mu = *c;
+ mu++;
+ *c = mu;
+ } else {
+ dk3_delete(newname);
+ *ec |= 2; $? "! failed to store name"
+ }
+ } else {
+ *ec |= 1; $? "! failed to allocate name"
+ } $? "- dk3dir_add"
+}
+
+
+
+#if DK3_ON_WINDOWS
+/* +++ Windows +++ */
+#if DK3_CHAR_SIZE > 1
+/* +++ Windows > 8 bit +++ */
+
+
+#if VERSION_BEFORE_2012_04_13
+
+dk3_dir_t *
+dk3dir_open_app(dkChar const *dn, dk3_app_t *app)
+{
+ dk3_dir_t *back = NULL;
+ int ec = 0; /* Error code. */
+ dkChar buffer[DK3_MAX_PATH]; /* Buffer for entry names. */
+ intptr_t ffres; /* Result of findfirst(). */
+ dkChar *namecopy = NULL; /* New copy of name. */
+ struct _wfinddata64_t ffdata; /* Find data. */
+ if(dn) {
+ if((dk3str_len(kw[3]) + dk3str_len(dn)) < DK3_SIZEOF(buffer,dkChar)) {
+ dk3str_cpy_not_overlapped(buffer, dn);
+ dk3str_cat(buffer, kw[3]);
+ back = dk3dir_new(dn, app);
+ if(back) {
+ ffres = _wfindfirst64(buffer, &ffdata);
+ if(ffres != -1) {
+ do {
+ if(dk3str_cmp(ffdata.name, kw[0])) {
+ if(dk3str_cmp(ffdata.name, kw[1])) {
+ if((ffdata.attrib) & _A_SUBDIR) {
+ dk3dir_add(back->sdi, ffdata.name, &(back->ndir), &ec, app);
+ } else {
+ dk3dir_add(back->sfi, ffdata.name, &(back->nfi), &ec, app);
+ }
+ }
+ }
+ } while(_wfindnext64(ffres, &ffdata) == 0);
+ _findclose(ffres);
+ } else {
+ ec |= 16;
+ if(app) {
+ /* ERROR: Failed to open directory! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 63, 64, dn);
+ }
+ }
+ }
+ if(ec) {
+ if(3 & ec) {
+ if(app) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 9);
+ }
+ }
+ dk3dir_close(back); back = NULL;
+ }
+ } else {
+ if(app) {
+ /* ERROR: Directory name too long! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 59, 60, dn);
+ }
+ }
+ }
+ return back;
+}
+
+
+dk3_dir_t *
+dk3dir_fne_open_app(dkChar const *fn, dk3_app_t *app)
+{
+ dk3_dir_t *back = NULL;
+ int ec = 0; /* Error code. */
+ dkChar mybuffer[DK3_MAX_PATH]; /* Buffer for entry names. */
+ dkChar myb2[2]; /* Search pattern. */
+ dkChar *ptr = NULL; /* Last separator. */
+ dkChar *namecopy = NULL; /* New copy of entry name. */
+ intptr_t ffres; /* Result from findfirst(). */
+ struct _wfinddata64_t ffdata; /* Find data. */
+ $? "+ dk3dir_fne_open_app \"%ls\"", fn
+ if(fn) {
+ if(dk3str_len(fn) < DK3_MAX_PATH) {
+ dk3str_cpy_not_overlapped(mybuffer, fn);
+ ptr = dk3str_rchr(mybuffer, DK3_CHAR_SEP);
+ if(ptr) {
+ *ptr = DK3_CHAR_0;
+ back = dk3dir_new(mybuffer, app);
+ *ptr = DK3_CHAR_SEP;
+ } else {
+ myb2[0] = DK3_CHAR_0;
+ back = dk3dir_new(myb2, app);
+ }
+ if(back) { $? ". mybuffer = \"%ls\"", mybuffer
+ ffres = _wfindfirst64(mybuffer, &ffdata);
+ if(ffres != -1) {
+ do { $? ". entry \"%ls\"", ffdata.name
+ if(dk3str_cmp(ffdata.name, kw[0])) { $? ". comparison ok"
+ if(dk3str_cmp(ffdata.name, kw[1])) { $? ". comparison ok"
+ if((ffdata.attrib) & _A_SUBDIR) { $? ". sub directory"
+ dk3dir_add(back->sdi, ffdata.name, &(back->ndir), &ec, app);
+ } else { $? ". regular file"
+ dk3dir_add(back->sfi, ffdata.name, &(back->nfi), &ec, app);
+ }
+ }
+ }
+ } while(_wfindnext64(ffres, &ffdata) == 0);
+ _findclose(ffres);
+ } else {
+ ec |= 16;
+ if(app) {
+ /* ERROR: Failed to open directory! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 215, 216, mybuffer);
+ }
+ }
+ }
+ if(ec) {
+ if(3 & ec) {
+ if(app) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 9);
+ }
+ }
+ dk3dir_close(back); back = NULL;
+ }
+ } else {
+ /* ERROR: Pattern too long! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 65, 66, fn);
+ }
+ } $? "- dk3dir_fne_open_app %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+#else
+
+
+static
+dk3_dir_t *
+dk3dir_my_open_app(dkChar const *dn, int usefne, dk3_app_t *app)
+{
+ WIN32_FIND_DATAW wfd; /* Details for file. */
+ dkChar b1[DK3_MAX_PATH]; /* Directory base. */
+ dkChar b2[DK3_MAX_PATH]; /* Pattern. */
+ dkChar *p1; /* Separator. */
+ dk3_dir_t *back = NULL;
+ HANDLE hSearch; /* File search handle. */
+ size_t sz; /* String length. */
+ int ok; /* Flag: No error yet. */
+ int ec; /* Error code. */
+ int isDir; /* Flag: Entry is dir. */
+ $? "+ dk3dir_my_open_app \"%!ds\"", dn
+ ec = 0;
+ if(dn) {
+ ok = 0;
+ if(usefne) {
+ if(dk3str_len(dn) < DK3_SIZEOF(b1,dkChar)) {
+ ok = 1; $? ". ok"
+ dk3str_cpy_not_overlapped(b1, dn);
+ dk3str_cpy_not_overlapped(b2, dn);
+ p1 = dk3str_rchr(b1, DK3_CHAR_SEP);
+ if(p1) {
+ *p1 = dkT('\0');
+ } else {
+ b1[0] = dkT('\0');
+ }
+ } else { $? "! name too long"
+ /* ERROR: Name too long! */
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 65, 66, dn);
+ }
+ }
+ } else {
+ sz = dk3str_len(dn) + dk3str_len(kw[3]);
+ if(sz < DK3_SIZEOF(b1,dkChar)) {
+ ok = 1; $? ". ok"
+ dk3str_cpy_not_overlapped(b1, dn);
+ dk3str_cpy_not_overlapped(b2, dn);
+ sz = dk3str_len(b2);
+ if(sz > 1) {
+ dk3str_cat(b2, kw[(DK3_CHAR_SEP == b2[sz - 1]) ? 4 : 3]);
+ } else {
+ dk3str_cat(b2, kw[3]);
+ }
+ } else { $? "! name too long"
+ /* Name too long! */
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 59, 60, dn);
+ }
+ }
+ }
+ if(ok) { $? ". b1=\"%!ds\" b2=\"%!ds\"", b1, b2
+ back = dk3dir_new(b1, app);
+ if(back) { $? ". alloc ok"
+ hSearch = FindFirstFileW(b2, &wfd);
+ if(INVALID_HANDLE_VALUE != hSearch) { $? ". FindFirstFile"
+ do {
+ isDir = 0; $? ". name=\"%ls\"", wfd.cFileName
+ if(dk3str_cmp(wfd.cFileName, kw[0])) {
+ if(dk3str_cmp(wfd.cFileName, kw[1])) { $? ". name ok"
+ if((wfd.dwFileAttributes) & FILE_ATTRIBUTE_DIRECTORY) {
+ isDir = 1;
+#if 0
+ if((wfd.dwFileAttributes) & FILE_ATTRIBUTE_REPARSE_POINT) {
+ switch(wfd.dwReserved0) {
+ case IO_REPARSE_TAG_MOUNT_POINT: {
+ isDir = 0;
+ } break;
+ }
+ }
+#endif
+ }
+ if(isDir) { $? ". dir"
+ dk3dir_add(back->sdi, wfd.cFileName, &(back->ndir), &ec, app);
+ } else { $? ". no dir"
+ dk3dir_add(back->sfi, wfd.cFileName, &(back->nfi), &ec, app);
+ }
+ }
+ }
+ } while(FindNextFileW(hSearch, &wfd));
+ FindClose(hSearch);
+ } else { $? "! FindFirstFileW"
+ /* ERROR: Failed to search for pattern! */
+ ec |= 16;
+ if(app) {
+ if(usefne) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 215, 216, dn);
+ } else {
+ dk3app_log_i3(app, DK3_LL_ERROR, 63, 64, dn);
+ }
+ }
+ }
+ if(ec) {
+ if(3 & ec) {
+ if(app) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 9);
+ }
+ }
+ dk3dir_close(back); back = NULL;
+ }
+ } else { $? "! alloc"
+ }
+ }
+ } else { $? "! no dn"
+ } $? "- dk3dir_my_open_app %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+dk3_dir_t *
+dk3dir_open_app(dkChar const *dn, dk3_app_t *app)
+{
+ dk3_dir_t *back;
+ $? "+ dk3dir_open_app \"%!ds\"", dn
+ back = dk3dir_my_open_app(dn, 0, app);
+ $? "- dk3dir_open_app %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+dk3_dir_t *
+dk3dir_fne_open_app(dkChar const *fn, dk3_app_t *app)
+{
+ dk3_dir_t *back;
+ $? "+ dk3dir_fne_open_app \"%!ds\"", fn
+ back = dk3dir_my_open_app(fn, 1, app);
+ $? "- dk3dir_fne_open_app %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+#endif
+
+
+/* --- Windows > 8 bit --- */
+#else
+/* +++ Windows, 8 bit +++ */
+
+
+
+#if VERSION_BEFORE_2012_04_13
+
+dk3_dir_t *
+dk3dir_open_app(dkChar const *dn, dk3_app_t *app)
+{
+ dk3_dir_t *back = NULL;
+ int ec = 0; /* Error code. */
+ dkChar buffer[DK3_MAX_PATH]; /* Buffer for entry names. */
+ intptr_t ffres; /* Result from findfirst(). */
+ dkChar *namecopy = NULL; /* New copy of entry name. */
+ struct __finddata64_t ffdata; /* Find data. */
+ if(dn) {
+ if((dk3str_len(kw[3]) + dk3str_len(dn)) < DK3_SIZEOF(buffer,dkChar)) {
+ dk3str_cpy_not_overlapped(buffer, dn);
+ dk3str_cat(buffer, kw[3]);
+ back = dk3dir_new(dn, app);
+ if(back) {
+ ffres = _findfirst64(buffer, &ffdata);
+ if(ffres != -1) {
+ do {
+ if(dk3str_cmp(ffdata.name, kw[0])) {
+ if(dk3str_cmp(ffdata.name, kw[1])) {
+ if((ffdata.attrib) & _A_SUBDIR) {
+ dk3dir_add(back->sdi, ffdata.name, &(back->ndir), &ec, app);
+ } else {
+ dk3dir_add(back->sfi, ffdata.name, &(back->nfi), &ec, app);
+ }
+ }
+ }
+ } while(_findnext64(ffres, &ffdata) == 0);
+ _findclose(ffres);
+ } else {
+ ec |= 16; /* Findfirst failed */
+ if(app) {
+ /* ERROR: Findfirst failed! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 63, 64, dn);
+ }
+ }
+ }
+ if(ec) {
+ if(3 & ec) {
+ if(app) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 9);
+ }
+ }
+ dk3dir_close(back); back = NULL;
+ }
+ } else {
+ if(app) {
+ /* ERROR: Directory name too long! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 59, 60, dn);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+dk3_dir_t *
+dk3dir_fne_open_app(dkChar const *fn, dk3_app_t *app)
+{
+ dk3_dir_t *back = NULL;
+ int ec = 0; /* Error code. */
+ dkChar mybuffer[DK3_MAX_PATH]; /* Buffer for entry name. */
+ dkChar myb2[2]; /* Buffer for pattern. */
+ dkChar *ptr = NULL; /* Last separator. */
+ dkChar *namecopy = NULL; /* New copy of entry name. */
+ intptr_t ffres; /* Result from findfirst(). */
+ struct __finddata64_t ffdata; /* Find data. */
+ $? "+ dk3dir_fne_open_app \"%!ds\"", fn
+ if(fn) {
+ if(dk3str_len(fn) < DK3_MAX_PATH) {
+ dk3str_cpy_not_overlapped(mybuffer, fn);
+ ptr = dk3str_rchr(mybuffer, DK3_CHAR_SEP);
+ if(ptr) {
+ *ptr = DK3_CHAR_0;
+ back = dk3dir_new(mybuffer, app);
+ *ptr = DK3_CHAR_SEP;
+ } else {
+ myb2[0] = DK3_CHAR_0;
+ back = dk3dir_new(myb2, app);
+ }
+ if(back) {
+ ffres = _findfirst64(mybuffer, &ffdata);
+ if(ffres != -1) {
+ do {
+ if(dk3str_cmp(ffdata.name, kw[0])) {
+ if(dk3str_cmp(ffdata.name, kw[1])) {
+ if((ffdata.attrib) & _A_SUBDIR) {
+ dk3dir_add(back->sdi, ffdata.name, &(back->ndir), &ec, app);
+ } else {
+ dk3dir_add(back->sfi, ffdata.name, &(back->nfi), &ec, app);
+ }
+ }
+ }
+ } while(_findnext64(ffres, &ffdata) == 0);
+ _findclose(ffres);
+ } else {
+ ec |= 16;
+ if(app) {
+ /* ERROR: Failed to open directory! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 215, 216, mybuffer);
+ }
+ }
+ }
+ if(ec) {
+ if(3 & ec) {
+ if(app) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 9);
+ }
+ }
+ dk3dir_close(back); back = NULL;
+ }
+ } else {
+ if(app) {
+ /* ERROR: Pattern too long! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 65, 66, fn);
+ }
+ }
+ } $? "- dk3dir_fne_open_app %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+#else
+
+
+
+static
+dk3_dir_t *
+dk3dir_my_open_app(dkChar const *dn, int usefne, dk3_app_t *app)
+{
+ WIN32_FIND_DATAA wfd; /* Details for file. */
+ dkChar b1[DK3_MAX_PATH]; /* Directory base. */
+ dkChar b2[DK3_MAX_PATH]; /* Pattern. */
+ dkChar *p1; /* Separator. */
+ dk3_dir_t *back = NULL;
+ HANDLE hSearch; /* File search handle. */
+ size_t sz; /* String length. */
+ int ok; /* Flag: No error yet. */
+ int ec; /* Error code. */
+ int isDir; /* Flag: Entry is dir. */
+ $? "+ dk3dir_my_open_app \"%!ds\"", dn
+ ec = 0;
+ if(dn) {
+ ok = 0;
+ if(usefne) {
+ if(dk3str_len(dn) < DK3_SIZEOF(b1,dkChar)) {
+ ok = 1; $? ". ok"
+ dk3str_cpy_not_overlapped(b1, dn);
+ dk3str_cpy_not_overlapped(b2, dn);
+ p1 = dk3str_rchr(b1, DK3_CHAR_SEP);
+ if(p1) {
+ *p1 = dkT('\0');
+ } else {
+ b1[0] = dkT('\0');
+ }
+ } else { $? "! name too long"
+ /* ERROR: Name too long! */
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 65, 66, dn);
+ }
+ }
+ } else {
+ sz = dk3str_len(dn) + dk3str_len(kw[3]);
+ if(sz < DK3_SIZEOF(b1,dkChar)) {
+ ok = 1; $? ". ok"
+ dk3str_cpy_not_overlapped(b1, dn);
+ dk3str_cpy_not_overlapped(b2, dn);
+ sz = dk3str_len(b2);
+ if(sz > 1) {
+ dk3str_cat(b2, kw[(DK3_CHAR_SEP == b2[sz - 1]) ? 4 : 3]);
+ } else {
+ dk3str_cat(b2, kw[3]);
+ }
+ } else { $? "! name too long"
+ /* ERROR: Name too long! */
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 59, 60, dn);
+ }
+ }
+ }
+ if(ok) { $? ". b1=\"%!ds\" b2=\"%!ds\"", b1, b2
+ back = dk3dir_new(b1, app);
+ if(back) { $? ". alloc ok"
+ hSearch = FindFirstFileA(b2, &wfd);
+ if(INVALID_HANDLE_VALUE != hSearch) { $? ". FIndFirstFile"
+ do {
+ isDir = 0; $? ". name=\"%!8s\"", wfd.cFileName
+ if(dk3str_cmp(wfd.cFileName, kw[0])) {
+ if(dk3str_cmp(wfd.cFileName, kw[1])) { $? ". name ok"
+ if((wfd.dwFileAttributes) & FILE_ATTRIBUTE_DIRECTORY) {
+ isDir = 1;
+#if 0
+ if((wfd.dwFileAttributes) & FILE_ATTRIBUTE_REPARSE_POINT) {
+ switch(wfd.dwReserved0) {
+ case IO_REPARSE_TAG_MOUNT_POINT: {
+ isDir = 0;
+ } break;
+ }
+ }
+#endif
+ }
+ if(isDir) { $? ". dir"
+ dk3dir_add(back->sdi, wfd.cFileName, &(back->ndir), &ec, app);
+ } else { $? ". no dir"
+ dk3dir_add(back->sfi, wfd.cFileName, &(back->nfi), &ec, app);
+ }
+ }
+ }
+ } while(FindNextFileA(hSearch, &wfd));
+ FindClose(hSearch);
+ } else { $? "! FindFirstFileW"
+ /* ERROR: Failed to search for pattern! */
+ ec |= 16;
+ if(app) {
+ if(usefne) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 215, 216, dn);
+ } else {
+ dk3app_log_i3(app, DK3_LL_ERROR, 63, 64, dn);
+ }
+ }
+ }
+ if(ec) {
+ if(3 & ec) {
+ if(app) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 9);
+ }
+ }
+ dk3dir_close(back); back = NULL;
+ }
+ } else { $? "! alloc"
+ }
+ }
+ } else { $? "! no dn"
+ } $? "- dk3dir_my_open_app %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+dk3_dir_t *
+dk3dir_open_app(dkChar const *dn, dk3_app_t *app)
+{
+ dk3_dir_t *back;
+ $? "+ dk3dir_open_app \"%!ds\"", dn
+ back = dk3dir_my_open_app(dn, 0, app);
+ $? "- dk3dir_open_app %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+dk3_dir_t *
+dk3dir_fne_open_app(dkChar const *fn, dk3_app_t *app)
+{
+ dk3_dir_t *back;
+ $? "+ dk3dir_fne_open_app \"%!ds\"", fn
+ back = dk3dir_my_open_app(fn, 1, app);
+ $? "- dk3dir_fne_open_app %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+#endif
+
+/* --- Windows, 8 bit --- */
+#endif
+/* --- Windows --- */
+#else
+/* +++ non-Windows +++ */
+#if DK3_CHAR_SIZE > 1
+/* +++ non-Windows > 8 bit +++ */
+#error "16/32-bit file names only available on Windows!"
+/* --- non-Windows > 8 bit --- */
+#else
+/* +++ non-Windows, 8 bit +++ */
+
+
+
+/** Function names used in error messages.
+*/
+static dkChar const * const dk3dir_function_names[] = {
+$!string-table macro=dkT
+#
+# 0
+#
+opendir:
+$!end
+};
+
+
+
+#if DK3_HAVE_OPENDIR && DK3_HAVE_READDIR && DK3_HAVE_CLOSEDIR
+
+
+
+dk3_dir_t *
+dk3dir_open_app(dkChar const *dn, dk3_app_t *app)
+{
+ dk3_dir_t *back = NULL;
+ int ec = 0; /* Error code. */
+ struct dirent *de = NULL; /* Directory entry from readdir(). */
+ DIR *d = NULL; /* Directory structure from opendir(). */
+ size_t sz = 0; /* Length of entire file name. */
+ size_t dns = 0; /* Directory name length. */
+ size_t kw2l = 0; /* Length of separator string. */
+ dk3_stat_t stb; /* Buffer for stat() result. */
+ $? "+ dk3dir_open_app"
+ if(dn) {
+ back = dk3dir_new(dn, app);
+ if(back) {
+ d = opendir(dn);
+ if(d) {
+ dns = dk3str_len(dn); kw2l = dk3str_len(kw[2]);
+ while((de = readdir(d)) != NULL) {
+ if(dk3str_cmp(de->d_name, kw[0])) {
+ if(dk3str_cmp(de->d_name, kw[1])) {
+ sz = dns + kw2l + dk3str_len(de->d_name);
+ if(sz < DK3_MAX_PATH) {
+ dk3str_cpy_not_overlapped(back->fullname, dn);
+ dk3str_cat(back->fullname, kw[2]);
+ dk3str_cat(back->fullname, de->d_name);
+ if(dk3sf_stat_app(&stb, back->fullname, NULL)) {
+ switch((stb.ft) & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_DIRECTORY: {
+ dk3dir_add(back->sdi,de->d_name,&(back->ndir),&ec,app);
+ } break;
+ default: {
+ dk3dir_add(back->sfi,de->d_name,&(back->nfi),&ec,app);
+ } break;
+ }
+ } else {
+ if(!(ec & 8)) {
+ if(app) {
+ /* Stat failed! */
+ dk3app_log_i3(app,DK3_LL_ERROR,61,62,back->fullname);
+ }
+ } ec |= 8;
+ }
+ } else {
+ if(!(ec & 4)) {
+ if(app) {
+ /* Directory name too long! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 59, 60, dn);
+ }
+ } ec |= 4;
+ }
+ }
+ }
+ }
+ closedir(d);
+ } else {
+ ec |= 16;
+ if(app) {
+ /* Failed to open directory! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 63, 64, dn);
+ dk3sf_report_errno(app, errno, dk3dir_function_names[0]);
+ }
+ }
+ if(ec) {
+ if(3 & ec) {
+ if(app) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 9);
+ }
+ }
+ dk3dir_close(back); back = NULL;
+ }
+ }
+ } $? "- dk3dir_open_app %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+dk3_dir_t *
+dk3dir_fne_open_app(dkChar const *fn, dk3_app_t *app)
+{
+ dk3_dir_t *back = NULL;
+ int ec = 0; /* Error code. */
+ dk3_stat_t stb; /* Stat buffer. */
+ dkChar mybuffer[DK3_MAX_PATH]; /* Buffer for entire file name. */
+ dkChar myb2[2]; /* Pattern buffer. */
+ dkChar *ptr; /* Last separator in pattern. */
+ $? "+ dk3dir_fne_open_app \"%!ds\"", fn
+ if(fn) {
+ if(dk3str_len(fn) < DK3_MAX_PATH) {
+ dk3str_cpy_not_overlapped(mybuffer, fn);
+ if(dk3sf_stat_app(&stb, fn, app)) {
+ ptr = dk3str_rchr(mybuffer, DK3_CHAR_SEP);
+ if(ptr) {
+ *(ptr++) = DK3_CHAR_0;
+ back = dk3dir_new(mybuffer, app);
+ } else {
+ myb2[0] = DK3_CHAR_0;
+ back = dk3dir_new(myb2, app);
+ ptr = mybuffer;
+ }
+ if(back) {
+ switch((stb.ft) & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_DIRECTORY: {
+ dk3dir_add(back->sdi, ptr, &(back->ndir), &ec, app);
+ } break;
+ default: {
+ dk3dir_add(back->sfi, ptr, &(back->nfi), &ec, app);
+ } break;
+ }
+ if(ec) {
+ if(3 & ec) {
+ if(app) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 9);
+ }
+ }
+ dk3dir_close(back); back = NULL;
+ }
+ }
+ }
+ } else {
+ if(app) {
+ /* Name too long! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 65, 66, fn);
+ }
+ }
+ } $? "- dk3dir_fne_open_app %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+#else
+#error "No opendir()/readdir()/closedir() function set!"
+#endif
+
+/* --- non-Windows, 8 bit --- */
+#endif
+/* --- non-Windows --- */
+#endif
+
+
+/** Directory chain cell.
+*/
+struct _dk3_dir_cell_t_ {
+ struct _dk3_dir_cell_t_ *parent; /**< Parent cell. */
+ dk3_dir_t *dir; /**< Directory structure. */
+};
+/** Directory chain cell.
+*/
+typedef struct _dk3_dir_cell_t_ DK3_DIR_CELL;
+
+
+
+/** Destroy chain cell, release memory.
+ @param c Cell to destroy.
+*/
+static
+void
+dk3dir_cell_delete(DK3_DIR_CELL *c)
+{
+ if(c) {
+ if(c->dir) {
+ dk3dir_close(c->dir);
+ }
+ c->dir = NULL;
+ c->parent = NULL;
+ dk3_delete(c);
+ }
+}
+
+
+
+/** Create directory cell, allocate memory.
+ @param n Directory name.
+ @param p Parent cell in chain.
+ @param app Application structure for diagnostics.
+ @return Pointer to new cell on success, NULL on error.
+*/
+static
+DK3_DIR_CELL *
+dk3dir_cell_new(dkChar const *n, DK3_DIR_CELL *p, dk3_app_t *app)
+{
+ DK3_DIR_CELL *back = NULL;
+ back = dk3_new_app(DK3_DIR_CELL,1,app);
+ if(back) {
+ back->parent = p;
+ back->dir = dk3dir_open_app(n, app);
+ if(!(back->dir)) {
+ dk3dir_cell_delete(back); back = NULL;
+ }
+ }
+ return back;
+}
+
+
+
+#if DK3_ON_WINDOWS
+/** Remove a directory reparse point.
+ @param dn Directory to remove.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3dir_remove_reparse_point(dkChar const *dn, dk3_app_t *app)
+{
+ int back = 0;
+ if(dk3sf_remove_dir_app(dn, app)) {
+ back = 1;
+ } else {
+ if(dk3sf_remove_file_app(dn, app)) {
+ back = 1;
+ }
+ }
+ return back;
+}
+#endif
+
+
+
+int
+dk3dir_remove_app(dkChar const *dn, dk3_app_t *app)
+{
+ int back = 0;
+ dk3_stat_t stb; /* Stat buffer. */
+ dkChar const *en = NULL; /* Entry name. */
+ dkChar const *xdn; /* Current dir to delete. */
+ dk3_stat_t const *es = NULL; /* Entry stat buffer. */
+ DK3_DIR_CELL *ccell = NULL; /* Current cell. */
+ DK3_DIR_CELL *ncell = NULL; /* New cell or next cell. */
+#if VERSION_BEFORE_20150821
+ int ft; /* File type. */
+#endif
+
+ if(dn) {
+ if(dk3sf_stat_app(&stb, dn, app)) {
+ if((stb.ft) & DK3_FT_SYMLINK) { /* symbolic link */
+ /* Removing symbolic link only, not target! */
+ back = dk3sf_remove_file_app(dn, app);
+ } else {
+ if(stb.ft == DK3_FT_DIRECTORY) {
+
+#if DK3_ON_WINDOWS
+ if(0x00 == stb.cReparse) {
+#endif
+ ccell = dk3dir_cell_new(dn, NULL, app);
+ if(ccell) {
+ back = 1;
+ while(ccell) {
+ if(dk3dir_get_next_directory(ccell->dir)) {
+ en = dk3dir_get_fullname(ccell->dir);
+ if(en) {
+ es = dk3dir_get_stat(ccell->dir);
+ if(es) {
+ if((es->ft) & DK3_FT_SYMLINK) {
+ if(!dk3sf_remove_file_app(en, app)) {
+ back = 0;
+ }
+ } else {
+#if DK3_ON_WINDOWS
+ if(0x00 == es->cReparse) {
+#endif
+ ncell = dk3dir_cell_new(en, ccell, app);
+ if(ncell) {
+ ccell = ncell;
+ } else {
+ back = 0;
+ }
+#if DK3_ON_WINDOWS
+ } else {
+ if(!dk3dir_remove_reparse_point(en, app)) {
+ back = 0;
+ }
+ }
+#endif
+ }
+ } else {
+ back = 0;
+ /* BUG: Internal error. */
+ }
+ } else {
+ back = 0;
+ /* BUG: Internal error. */
+ }
+ } else {
+ while(dk3dir_get_next_file(ccell->dir)) {
+#if VERSION_BEFORE_20150821
+ ft = DK3_FT_REGULAR;
+#endif
+ en = dk3dir_get_fullname(ccell->dir);
+#if VERSION_BEFORE_20150821
+ es = dk3dir_get_stat(ccell->dir);
+ if(es) { ft = es->ft; }
+#endif
+ if(en) {
+ if(!dk3sf_remove_file_app(en, app)) {
+ back = 0;
+ }
+ } else {
+ back = 0;
+ /* BUG: Internal error. */
+ }
+ }
+ ncell = ccell->parent;
+ if(ccell->dir) {
+ xdn = dk3dir_get_directory_name(ccell->dir);
+ if(xdn) {
+ if(!dk3sf_remove_dir_app(xdn, app)) {
+ back = 0;
+ }
+ }
+ }
+ dk3dir_cell_delete(ccell);
+ ccell = ncell;
+ }
+ }
+ }
+#if DK3_ON_WINDOWS
+ } else {
+ if(!dk3dir_remove_reparse_point(dn, app)) {
+ back = 0;
+ }
+ }
+#endif
+ } else {
+ /* ERROR: Not a directory! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 202, 203, dn);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dk3dir.h b/support/dktools/dk3dir.h
new file mode 100644
index 0000000000..68eb9c7630
--- /dev/null
+++ b/support/dktools/dk3dir.h
@@ -0,0 +1,159 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3dir.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3dir.h Header file for the dk3dir module.
+*/
+
+#ifndef DK3DIR_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3DIR_H_INCLUDED 1
+
+
+#line 10 "dk3dir.ctr"
+
+#include "dk3conf.h"
+#include "dk3types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** Open a directory.
+ @param dn Directory name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to directory structure on success, NULL on error.
+*/
+dk3_dir_t *
+dk3dir_open_app(dkChar const *dn, dk3_app_t *app);
+
+/** Open directory structure to expand a file name.
+ @param fn File name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to directory structure on success, NULL on errror.
+*/
+dk3_dir_t *
+dk3dir_fne_open_app(dkChar const *fn, dk3_app_t *app);
+
+/** Close directory.
+ @param dp Directory to close.
+*/
+void
+dk3dir_close(dk3_dir_t *dp);
+
+/** Get number of subdirectories.
+ @param d Directory structure.
+ @return Number of subdirectories.
+*/
+dk3_um_t
+dk3dir_get_number_of_directories(dk3_dir_t const *d);
+
+/** Get number of files.
+ @param d Directory structure.
+ @return Number of non-directory entries in directory.
+*/
+dk3_um_t
+dk3dir_get_number_of_files(dk3_dir_t const *d);
+
+/** Attempt to retrieve information about the next sub-directory.
+ @param d Directory structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dir_get_next_directory(dk3_dir_t *d);
+
+/** Attempt to retrieve information about the next non-sub-directory entry.
+ @param d Directory structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dir_get_next_file(dk3_dir_t *d);
+
+/** Retrieve short file name of entry found.
+ May be used after a successful call to dk3dir_get_next_directory() or
+ dk3dir_get_next_file() only.
+ @param d Directory structure.
+ @return Pointer to file name on success, NULL on error.
+*/
+dkChar const *
+dk3dir_get_shortname(dk3_dir_t const *d);
+
+/** Retrieve full file name of entry found.
+ May be used after a successful call to dk3dir_get_next_directory() or
+ dk3dir_get_next_file() only.
+ @param d Directory structure.
+ @return Pointer to file name on success, NULL on error.
+*/
+dkChar const *
+dk3dir_get_fullname(dk3_dir_t const *d);
+
+/** Retrieve file status information.
+ May be used after a successful call to dk3dir_get_next_directory() or
+ dk3dir_get_next_file() only.
+ @param d Directory structure.
+ @return Pointer to file name on success, NULL on error.
+*/
+dk3_stat_t const *
+dk3dir_get_stat(dk3_dir_t *d);
+
+/** Reset directory for new traversal.
+ @param d Directory structure.
+*/
+void
+dk3dir_reset(dk3_dir_t *d);
+
+/** Retrieve directory name.
+ @param dir Directory structure.
+ @return Directory path name.
+*/
+dkChar const *
+dk3dir_get_directory_name(dk3_dir_t const *dir);
+
+/** Remove directory recursively, including all contents.
+ @param dn Directory name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3dir_remove_app(dkChar const *dn, dk3_app_t *app);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3echo.c b/support/dktools/dk3echo.c
new file mode 100644
index 0000000000..43f454eebc
--- /dev/null
+++ b/support/dktools/dk3echo.c
@@ -0,0 +1,316 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3echo.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3echo.c The dk3echo module.
+*/
+
+
+#line 168 "dk3echo.ctr"
+
+
+#include "dk3all.h"
+#include "dk3echo.h"
+
+
+
+
+#line 175 "dk3echo.ctr"
+
+
+
+int
+dk3echo_save(dk3_echo_t *ep)
+{
+ int back;
+ back = dk3echo_save_app(ep, NULL);
+ return back;
+}
+
+
+
+int
+dk3echo_save_app(dk3_echo_t *ep, dk3_app_t *app)
+{
+ int back = 0;
+ if(ep) {
+#if DK3_ON_WINDOWS
+ ep->consoleHandle = GetStdHandle(STD_INPUT_HANDLE);
+ if(ep->consoleHandle != INVALID_HANDLE_VALUE) {
+ ep->is_tty = 1;
+ if(GetConsoleMode(ep->consoleHandle, &(ep->ori))) {
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Failed to retrieve console settings! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 265);
+ }
+ }
+ } else {
+ if(app) {
+ /* ERROR: Failed to obtain handle for standard input! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 265);
+ }
+ }
+#else
+#if DK3_HAVE_ISATTY
+ ep->is_tty = isatty(0);
+#else
+ ep->is_tty = 1;
+#endif
+#if DK3_HAVE_TCGETATTR
+ if(tcgetattr(0, &(ep->ori)) == 0) {
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Failed to retrieve console settings! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 265);
+ }
+ }
+#else
+#if defined(TCGETS)
+ if(ioctl(0, TCGETS, &(ep->ori)) == 0) {
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Failed to retrieve console settings! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 265);
+ }
+ }
+#else
+
+#endif
+#endif
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3echo_restore(dk3_echo_t *ep)
+{
+ int back;
+ back = dk3echo_restore_app(ep, NULL);
+ return back;
+}
+
+
+
+int
+dk3echo_restore_app(dk3_echo_t *ep, dk3_app_t *app)
+{
+ int back = 0;
+ if(ep) {
+#if DK3_ON_WINDOWS
+ if(ep->consoleHandle != INVALID_HANDLE_VALUE) {
+ if(SetConsoleMode(ep->consoleHandle, ep->ori)) {
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Failed to restore console settings! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 266);
+ }
+ }
+ }
+#else
+#if DK3_HAVE_TCGETATTR
+ if(tcsetattr(0, TCSANOW, &(ep->ori)) == 0) {
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Failed to restore console settings! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 266);
+ }
+ }
+#else
+#if defined(TCGETS)
+ if(ioctl(0, TCSETS, &(ep->ori)) == 0) {
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Failed to restore console settings! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 266);
+ }
+ }
+#else
+
+#endif
+#endif
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3echo_off(dk3_echo_t *ep)
+{
+ int back;
+ back = dk3echo_off_app(ep, NULL);
+ return back;
+}
+
+
+
+int
+dk3echo_off_app(dk3_echo_t *ep, dk3_app_t *app)
+{
+ int back = 0;
+ if(ep) {
+#if DK3_ON_WINDOWS
+ if(ep->consoleHandle != INVALID_HANDLE_VALUE) {
+ if(SetConsoleMode(ep->consoleHandle,((ep->ori) & (~(ENABLE_ECHO_INPUT)))))
+ {
+ back = 1;
+ }
+ else
+ {
+ if(app) {
+ /* ERROR: Failed to modify console settings! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 267);
+ }
+ }
+ }
+#else
+#if DK3_HAVE_TCGETATTR
+ dk3_termios_t nti;
+ dk3mem_cpy((void *)(&nti), (void *)(&(ep->ori)), sizeof(dk3_termios_t));
+#if defined(ECHO)
+ nti.c_lflag &= (~(ECHO));
+#endif
+#if defined(ECHONL)
+ nti.c_lflag &= (~(ECHONL));
+#endif
+ if(tcsetattr(0, TCSANOW, &nti) == 0) {
+ back = 1;
+#if DK3_HAVE_TCFLUSH
+ tcflush(0, TCIFLUSH);
+#endif
+ } else {
+ if(app) {
+ /* ERROR: Failed to modify terminal settings! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 267);
+ }
+ }
+#else
+#if defined(TCGETS)
+ dk3_termios_t nti;
+ dk3mem_cpy((void *)(&nti), (void *)(&(ep->ori)), sizeof(dk3_termios_t));
+#if defined(ECHO)
+ nti.c_lflag &= (~(ECHO));
+#endif
+#if defined(ECHONL)
+ nti.c_lflag &= (~(ECHONL));
+#endif
+ if(ioctl(0, TCSETS, &nti) == 0) {
+ back = 1;
+ (void)ioctl(0, TCFLSH, 0);
+ } else {
+ if(app) {
+ /* ERROR: Failed to modify terminal settings! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 267);
+ }
+ }
+#else
+
+#endif
+#endif
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3echo_is_tty(dk3_echo_t *ep)
+{
+ int back;
+ back = dk3echo_is_tty_app(ep, NULL);
+ return back;
+}
+
+
+
+int
+dk3echo_is_tty_app(dk3_echo_t const *ep, dk3_app_t *app)
+{
+ int back = 0;
+ if(ep) {
+ back = ep->is_tty;
+ }
+ return back;
+}
+
+
+
+int
+dk3echo_test_tty(dk3_echo_t *ep)
+{
+ int back;
+ back = dk3echo_test_tty_app(ep, NULL);
+ return back;
+}
+
+
+
+int
+dk3echo_test_tty_app(dk3_echo_t *ep, dk3_app_t *app)
+{
+ int back = 0;
+ if(ep) {
+#if DK3_ON_WINDOWS
+ if(GetStdHandle(STD_INPUT_HANDLE) != INVALID_HANDLE_VALUE) {
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Failed to retrieve console settings! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 265);
+ }
+ }
+#else
+#if DK3_HAVE_ISATTY
+ back = isatty(0);
+#endif
+ dk3app_log_i1(app, DK3_LL_ERROR, 265);
+#endif
+ }
+ return back;
+}
+
+
+/* vim: set ai sw=2 : */
diff --git a/support/dktools/dk3echo.ctr b/support/dktools/dk3echo.ctr
new file mode 100644
index 0000000000..709d7cdbc6
--- /dev/null
+++ b/support/dktools/dk3echo.ctr
@@ -0,0 +1,441 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% header
+
+#include "dk3conf.h"
+
+
+
+#if DK3_HAVE_TCGETATTR
+/** Terminal IO structure.
+*/
+typedef struct termios dk3_termios_t;
+#else
+#if defined(TCGETS)
+/** Terminal IO structure.
+*/
+typedef struct termios dk3_termios_t;
+#else
+
+#endif
+#endif
+
+
+
+/** Keyboard echo configuration.
+*/
+typedef struct {
+
+#if DK3_ON_WINDOWS
+
+ /** Handle for console.
+ */
+ HANDLE consoleHandle;
+
+ /** Original console flags.
+ */
+ DWORD ori;
+
+#else
+/* DK3_ON_WINDOWS */
+
+#if DK3_HAVE_TCGETATTR
+
+ /** Original terminal settings.
+ */
+ dk3_termios_t ori;
+
+#else
+/* DK3_HAVE_TCGETATTR */
+
+#if defined(TCGETS)
+
+ /** Original terminal settings.
+ */
+ dk3_termios_t ori;
+#else
+/* defined(TCGETS) */
+
+#endif
+/* defined(TCGETS) */
+
+#endif
+/* DK3_HAVE_TCGETATTR */
+
+#endif
+/* DK3_ON_WINDOWS */
+
+ /** Flag: Standard input is a terminal.
+ */
+ int is_tty;
+
+} dk3_echo_t;
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Save current keyboard echo settings.
+ @param ep Keyboard echo settings structure.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3echo_save_app(dk3_echo_t *ep, dk3_app_t *app);
+
+/** Restore keyboard echo settings.
+ @param ep Keyboard echo settings structure.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3echo_restore_app(dk3_echo_t *ep, dk3_app_t *app);
+
+/** Disable keyboard echo.
+ @param ep Keyboard echo settings structure.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3echo_off_app(dk3_echo_t *ep, dk3_app_t *app);
+
+/** Check whether standard input is from terminal for settings structure.
+ @param ep Keyboard echo settings structure.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3echo_is_tty_app(dk3_echo_t const *ep, dk3_app_t *app);
+
+/** Check whether standard input is from terminal.
+ @param ep Keyboard echo settings structure.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3echo_test_tty_app(dk3_echo_t *ep, dk3_app_t *app);
+
+/** Save current keyboard echo settings.
+ @param ep Keyboard echo settings structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3echo_save(dk3_echo_t *ep);
+
+/** Restore keyboard echo settings.
+ @param ep Keyboard echo settings structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3echo_restore(dk3_echo_t *ep);
+
+/** Disable keyboard echo.
+ @param ep Keyboard echo settings structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3echo_off(dk3_echo_t *ep);
+
+/** Check whether standard input is from terminal for settings structure.
+ @param ep Keyboard echo settings structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3echo_is_tty(dk3_echo_t *ep);
+
+/** Check whether standard input is from terminal.
+ @param ep Keyboard echo settings structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3echo_test_tty(dk3_echo_t *ep);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+
+#include "dk3all.h"
+#include "dk3echo.h"
+
+
+$!trace-include
+
+
+
+int
+dk3echo_save(dk3_echo_t *ep)
+{
+ int back;
+ back = dk3echo_save_app(ep, NULL);
+ return back;
+}
+
+
+
+int
+dk3echo_save_app(dk3_echo_t *ep, dk3_app_t *app)
+{
+ int back = 0;
+ if(ep) {
+#if DK3_ON_WINDOWS
+ ep->consoleHandle = GetStdHandle(STD_INPUT_HANDLE);
+ if(ep->consoleHandle != INVALID_HANDLE_VALUE) {
+ ep->is_tty = 1;
+ if(GetConsoleMode(ep->consoleHandle, &(ep->ori))) {
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Failed to retrieve console settings! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 265);
+ }
+ }
+ } else {
+ if(app) {
+ /* ERROR: Failed to obtain handle for standard input! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 265);
+ }
+ }
+#else
+#if DK3_HAVE_ISATTY
+ ep->is_tty = isatty(0);
+#else
+ ep->is_tty = 1;
+#endif
+#if DK3_HAVE_TCGETATTR
+ if(tcgetattr(0, &(ep->ori)) == 0) {
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Failed to retrieve console settings! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 265);
+ }
+ }
+#else
+#if defined(TCGETS)
+ if(ioctl(0, TCGETS, &(ep->ori)) == 0) {
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Failed to retrieve console settings! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 265);
+ }
+ }
+#else
+
+#endif
+#endif
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3echo_restore(dk3_echo_t *ep)
+{
+ int back;
+ back = dk3echo_restore_app(ep, NULL);
+ return back;
+}
+
+
+
+int
+dk3echo_restore_app(dk3_echo_t *ep, dk3_app_t *app)
+{
+ int back = 0;
+ if(ep) {
+#if DK3_ON_WINDOWS
+ if(ep->consoleHandle != INVALID_HANDLE_VALUE) {
+ if(SetConsoleMode(ep->consoleHandle, ep->ori)) {
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Failed to restore console settings! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 266);
+ }
+ }
+ }
+#else
+#if DK3_HAVE_TCGETATTR
+ if(tcsetattr(0, TCSANOW, &(ep->ori)) == 0) {
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Failed to restore console settings! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 266);
+ }
+ }
+#else
+#if defined(TCGETS)
+ if(ioctl(0, TCSETS, &(ep->ori)) == 0) {
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Failed to restore console settings! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 266);
+ }
+ }
+#else
+
+#endif
+#endif
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3echo_off(dk3_echo_t *ep)
+{
+ int back;
+ back = dk3echo_off_app(ep, NULL);
+ return back;
+}
+
+
+
+int
+dk3echo_off_app(dk3_echo_t *ep, dk3_app_t *app)
+{
+ int back = 0;
+ if(ep) {
+#if DK3_ON_WINDOWS
+ if(ep->consoleHandle != INVALID_HANDLE_VALUE) {
+ if(SetConsoleMode(ep->consoleHandle,((ep->ori) & (~(ENABLE_ECHO_INPUT)))))
+ {
+ back = 1;
+ }
+ else
+ {
+ if(app) {
+ /* ERROR: Failed to modify console settings! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 267);
+ }
+ }
+ }
+#else
+#if DK3_HAVE_TCGETATTR
+ dk3_termios_t nti;
+ dk3mem_cpy((void *)(&nti), (void *)(&(ep->ori)), sizeof(dk3_termios_t));
+#if defined(ECHO)
+ nti.c_lflag &= (~(ECHO));
+#endif
+#if defined(ECHONL)
+ nti.c_lflag &= (~(ECHONL));
+#endif
+ if(tcsetattr(0, TCSANOW, &nti) == 0) {
+ back = 1;
+#if DK3_HAVE_TCFLUSH
+ tcflush(0, TCIFLUSH);
+#endif
+ } else {
+ if(app) {
+ /* ERROR: Failed to modify terminal settings! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 267);
+ }
+ }
+#else
+#if defined(TCGETS)
+ dk3_termios_t nti;
+ dk3mem_cpy((void *)(&nti), (void *)(&(ep->ori)), sizeof(dk3_termios_t));
+#if defined(ECHO)
+ nti.c_lflag &= (~(ECHO));
+#endif
+#if defined(ECHONL)
+ nti.c_lflag &= (~(ECHONL));
+#endif
+ if(ioctl(0, TCSETS, &nti) == 0) {
+ back = 1;
+ (void)ioctl(0, TCFLSH, 0);
+ } else {
+ if(app) {
+ /* ERROR: Failed to modify terminal settings! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 267);
+ }
+ }
+#else
+
+#endif
+#endif
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3echo_is_tty(dk3_echo_t *ep)
+{
+ int back;
+ back = dk3echo_is_tty_app(ep, NULL);
+ return back;
+}
+
+
+
+int
+dk3echo_is_tty_app(dk3_echo_t const *ep, dk3_app_t *app)
+{
+ int back = 0;
+ if(ep) {
+ back = ep->is_tty;
+ }
+ return back;
+}
+
+
+
+int
+dk3echo_test_tty(dk3_echo_t *ep)
+{
+ int back;
+ back = dk3echo_test_tty_app(ep, NULL);
+ return back;
+}
+
+
+
+int
+dk3echo_test_tty_app(dk3_echo_t *ep, dk3_app_t *app)
+{
+ int back = 0;
+ if(ep) {
+#if DK3_ON_WINDOWS
+ if(GetStdHandle(STD_INPUT_HANDLE) != INVALID_HANDLE_VALUE) {
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Failed to retrieve console settings! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 265);
+ }
+ }
+#else
+#if DK3_HAVE_ISATTY
+ back = isatty(0);
+#endif
+ dk3app_log_i1(app, DK3_LL_ERROR, 265);
+#endif
+ }
+ return back;
+}
+
+
+/* vim: set ai sw=2 : */
diff --git a/support/dktools/dk3echo.h b/support/dktools/dk3echo.h
new file mode 100644
index 0000000000..3de87ed4a1
--- /dev/null
+++ b/support/dktools/dk3echo.h
@@ -0,0 +1,203 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3echo.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3echo.h Header file for the dk3echo module.
+*/
+
+#ifndef DK3ECHO_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3ECHO_H_INCLUDED 1
+
+
+#line 10 "dk3echo.ctr"
+
+#include "dk3conf.h"
+
+
+
+#if DK3_HAVE_TCGETATTR
+/** Terminal IO structure.
+*/
+typedef struct termios dk3_termios_t;
+#else
+#if defined(TCGETS)
+/** Terminal IO structure.
+*/
+typedef struct termios dk3_termios_t;
+#else
+
+#endif
+#endif
+
+
+
+/** Keyboard echo configuration.
+*/
+typedef struct {
+
+#if DK3_ON_WINDOWS
+
+ /** Handle for console.
+ */
+ HANDLE consoleHandle;
+
+ /** Original console flags.
+ */
+ DWORD ori;
+
+#else
+/* DK3_ON_WINDOWS */
+
+#if DK3_HAVE_TCGETATTR
+
+ /** Original terminal settings.
+ */
+ dk3_termios_t ori;
+
+#else
+/* DK3_HAVE_TCGETATTR */
+
+#if defined(TCGETS)
+
+ /** Original terminal settings.
+ */
+ dk3_termios_t ori;
+#else
+/* defined(TCGETS) */
+
+#endif
+/* defined(TCGETS) */
+
+#endif
+/* DK3_HAVE_TCGETATTR */
+
+#endif
+/* DK3_ON_WINDOWS */
+
+ /** Flag: Standard input is a terminal.
+ */
+ int is_tty;
+
+} dk3_echo_t;
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Save current keyboard echo settings.
+ @param ep Keyboard echo settings structure.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3echo_save_app(dk3_echo_t *ep, dk3_app_t *app);
+
+/** Restore keyboard echo settings.
+ @param ep Keyboard echo settings structure.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3echo_restore_app(dk3_echo_t *ep, dk3_app_t *app);
+
+/** Disable keyboard echo.
+ @param ep Keyboard echo settings structure.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3echo_off_app(dk3_echo_t *ep, dk3_app_t *app);
+
+/** Check whether standard input is from terminal for settings structure.
+ @param ep Keyboard echo settings structure.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3echo_is_tty_app(dk3_echo_t const *ep, dk3_app_t *app);
+
+/** Check whether standard input is from terminal.
+ @param ep Keyboard echo settings structure.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3echo_test_tty_app(dk3_echo_t *ep, dk3_app_t *app);
+
+/** Save current keyboard echo settings.
+ @param ep Keyboard echo settings structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3echo_save(dk3_echo_t *ep);
+
+/** Restore keyboard echo settings.
+ @param ep Keyboard echo settings structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3echo_restore(dk3_echo_t *ep);
+
+/** Disable keyboard echo.
+ @param ep Keyboard echo settings structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3echo_off(dk3_echo_t *ep);
+
+/** Check whether standard input is from terminal for settings structure.
+ @param ep Keyboard echo settings structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3echo_is_tty(dk3_echo_t *ep);
+
+/** Check whether standard input is from terminal.
+ @param ep Keyboard echo settings structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3echo_test_tty(dk3_echo_t *ep);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3enc.c b/support/dktools/dk3enc.c
new file mode 100644
index 0000000000..384db91bd5
--- /dev/null
+++ b/support/dktools/dk3enc.c
@@ -0,0 +1,1880 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3enc.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3enc.c The dk3enc module.
+*/
+
+
+#line 312 "dk3enc.ctr"
+
+#include "dk3all.h"
+
+
+
+
+
+#line 317 "dk3enc.ctr"
+
+
+
+/** Binary to text encoding names.
+ Order here must match order of DK3_DATA_ENCODING_xxx in dk3const.h.
+*/
+static dkChar const * const dk3enc_data_encoding_names[] = {
+/* 0 */ dkT("HEX"),
+/* 1 */ dkT("ASCII-85"),
+/* 2 */ dkT("R-ASCII-85"),
+/* 3 */ dkT("H"),
+/* 4 */ dkT("A"),
+/* 5 */ dkT("R"),
+/* 6 */ dkT("A85"),
+/* 7 */ dkT("RA85"),
+NULL
+};
+
+
+
+/** Encoding names for file contents encodings.
+*/
+static dkChar const * const dk3enc_text_encoding_names[] = {
+/* 0 */ dkT("PLAIN"),
+/* 1 */ dkT("UTF-8"),
+/* 2 */ dkT("UTF-16"),
+/* 3 */ dkT("UTF-16.MSB"),
+/* 4 */ dkT("UTF-16.LSB"),
+/* 5 */ dkT("UC32"),
+/* 6 */ dkT("UC32.MSB"),
+/* 7 */ dkT("UC32.LSB"),
+/* 8 */ dkT("ASCII"),
+/* 9 */ dkT("ISO-LATIN-1"),
+/* 10 */ dkT("UTF8"),
+/* 11 */ dkT("UTF16"),
+/* 12 */ dkT("UTF-16-LE"),
+/* 13 */ dkT("UTF-16LE"),
+/* 14 */ dkT("UTF16LE"),
+/* 15 */ dkT("UTF-16-LSB"),
+/* 16 */ dkT("UTF-16LSB"),
+/* 17 */ dkT("UTF16LSB"),
+/* 18 */ dkT("UTF-16-BE"),
+/* 19 */ dkT("UTF-16BE"),
+/* 20 */ dkT("UTF16BE"),
+/* 21 */ dkT("UTF-16-MSB"),
+/* 22 */ dkT("UTF-16MSB"),
+/* 23 */ dkT("UTF16MSB"),
+/* 24 */ dkT("C32"),
+/* 25 */ dkT("C32-LE"),
+/* 26 */ dkT("C32LE"),
+/* 27 */ dkT("C32-LSB"),
+/* 28 */ dkT("C32LSB"),
+/* 29 */ dkT("C32-BE"),
+/* 30 */ dkT("C32BE"),
+/* 31 */ dkT("C32-MSB"),
+/* 32 */ dkT("C32MSB"),
+NULL
+};
+
+
+
+/** Encoding names for UTF-8 encoding.
+*/
+static char const * const dk3enc_utf8_names[] = {
+/* 0 */
+"utf-8",
+
+/* 1 */
+"utf8",
+
+NULL
+
+
+#line 385 "dk3enc.ctr"
+};
+
+
+/** Digits used to show hexadecimal characters.
+*/
+static char const dk3enc_hex_digits[] = {
+'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', '\0'
+};
+
+
+/** Bit mask to obtain last byte of a double word.
+*/
+static unsigned long const dk3enc_last_byte = 0x000000FFUL;
+
+
+
+/** Factors for ASCII85 and reverse ASCII85 encoding.
+*/
+static unsigned long const dk3enc_f2[] = {
+ 1UL,
+ 85UL,
+ (85UL * 85UL),
+ (85UL * 85UL * 85UL),
+ (85UL * 85UL * 85UL * 85UL)
+};
+
+
+
+/** Swap byte order for unsigned long.
+ @param ul Original value.
+ @return Value in swapped byte order.
+*/
+static
+unsigned long
+dk3enc_swap_ul(unsigned long ul)
+{
+ unsigned long back = 0UL;
+ back = ((ul >> 24) & 0x000000FFUL);
+ back |= ((ul >> 8) & 0x0000FF00UL);
+ back |= ((ul << 8) & 0x00FF0000UL);
+ back |= ((ul << 24) & 0xFF000000UL);
+ return back;
+}
+
+
+
+/** Swap byte order for unsigned short.
+ @param us Original value.
+ @return Value in swapped byte order.
+*/
+static
+unsigned short
+dk3enc_swap_us(unsigned short us)
+{
+ unsigned short back = 0U;
+ back = ((us >> 8) & 0x00FFU);
+ back |= ((us << 8) & 0xFF00U);
+ return back;
+}
+
+
+unsigned long
+dk3enc_ntohl(unsigned long x)
+{
+ unsigned long back;
+#if DK3_WORDS_BIGENDIAN
+ back = x;
+#else
+ back = dk3enc_swap_ul(x);
+#endif
+ return back;
+}
+
+
+unsigned long
+dk3enc_htonl(unsigned long x)
+{
+ unsigned long back;
+#if DK3_WORDS_BIGENDIAN
+ back = x;
+#else
+ back = dk3enc_swap_ul(x);
+#endif
+ return back;
+}
+
+
+
+unsigned short
+dk3enc_ntohs(unsigned short x)
+{
+ unsigned short back;
+#if DK3_WORDS_BIGENDIAN
+ back = x;
+#else
+ back = dk3enc_swap_us(x);
+#endif
+ return back;
+}
+
+
+
+unsigned short
+dk3enc_htons(unsigned short x)
+{
+ unsigned short back;
+#if DK3_WORDS_BIGENDIAN
+ back = x;
+#else
+ back = dk3enc_swap_us(x);
+#endif
+ return back;
+}
+
+
+
+/** Convert 32-bit character to UTF-8 following RFC2279.
+ @param c 32-bit character to convert.
+ @param u8p Destination buffer.
+ @param u8l Length of @a u8p (number of bytes).
+ @return Number of bytes written to @a u8p.
+*/
+static
+size_t
+dk3enc_uc2utf8_rfc2279(dk3_c32_t c, unsigned char *u8p, size_t u8l)
+{
+ size_t back = 0;
+ dk3_c32_t x = 0UL; /* Variable for temporary results. */
+
+
+#line 514 "dk3enc.ctr"
+ if(u8p) {
+ if(u8l > 0) {
+ if(c > (dk3_c32_t)0x7FUL) {
+ if(c > (dk3_c32_t)0x000007FFUL) {
+ if(c > (dk3_c32_t)0x0000FFFFUL) {
+ if(c > (dk3_c32_t)0x001FFFFFUL) {
+ if(c > (dk3_c32_t)0x03FFFFFFUL) {
+ if(c < (dk3_c32_t)0x80000000UL) { /* 6 Byte */
+ if(u8l >= 6) {
+ back = 6;
+ x = c >> 30;
+ x &= 0x00000001UL;
+ x |= 0x000000FCUL;
+ u8p[0] = (unsigned char)x;
+ x = c >> 24; x &= 0x0000003FUL; x |= 0x00000080UL;
+ u8p[1] = (unsigned char)x;
+ x = c >> 18; x &= 0x0000003FUL; x |= 0x00000080UL;
+ u8p[2] = (unsigned char)x;
+ x = c >> 12; x &= 0x0000003FUL; x |= 0x00000080UL;
+ u8p[3] = (unsigned char)x;
+ x = c >> 6; x &= 0x0000003FUL; x |= 0x00000080UL;
+ u8p[4] = (unsigned char)x;
+ x = c & 0x0000003FUL; x |= 0x00000080UL;
+ u8p[5] = (unsigned char)x;
+ }
+ }
+ } else { /* 5 Byte */
+ if(u8l >= 5) {
+ back = 5;
+ x = c >> 24;
+ x &= 0x00000003UL;
+ x |= 0x000000F8UL;
+ u8p[0] = (unsigned char)x;
+ x = c >> 18; x &= 0x0000003FUL; x |= 0x00000080UL;
+ u8p[1] = (unsigned char)x;
+ x = c >> 12; x &= 0x0000003FUL; x |= 0x00000080UL;
+ u8p[2] = (unsigned char)x;
+ x = c >> 6; x &= 0x0000003FUL; x |= 0x00000080UL;
+ u8p[3] = (unsigned char)x;
+ x = c & 0x0000003FUL; x |= 0x00000080UL;
+ u8p[4] = (unsigned char)x;
+ }
+ }
+ } else { /* 4 Byte */
+ if(u8l >= 4) {
+ back = 4;
+ x = c >> 18;
+ x &= 0x00000007UL;
+ x |= 0x000000F0UL;
+ u8p[0] = (unsigned char)x;
+ x = c >> 12;
+ x &= 0x0000003FUL;
+ x |= 0x00000080UL;
+ u8p[1] = (unsigned char)x;
+ x = c >> 6;
+ x &= 0x0000003FUL;
+ x |= 0x00000080UL;
+ u8p[2] = (unsigned char)x;
+ x = c & 0x0000003FUL;
+ x |= 0x00000080UL;
+ u8p[3] = (unsigned char)x;
+ }
+ }
+ } else { /* 3 Byte */
+ if(u8l >= 3) {
+ back = 3;
+ x = c >> 12;
+ x &= 0x0000000FUL;
+ x |= 0x000000E0UL;
+ u8p[0] = (unsigned char)x;
+ x = c >> 6;
+ x &= 0x0000003FUL;
+ x |= 0x00000080UL;
+ u8p[1] = (unsigned char)x;
+ x = c & 0x0000003FUL;
+ x |= 0x00000080UL;
+ u8p[2] = (unsigned char)x;
+ }
+ }
+ } else { /* 2 Byte */
+ if(u8l >= 2) {
+ back = 2;
+ x = c >> 6;
+ x &= 0x0000001FUL;
+ x |= 0x000000C0UL;
+ u8p[0] = (unsigned char)x;
+ x = c & 0x0000003FUL;
+ x |= 0x00000080UL;
+ u8p[1] = (unsigned char)x;
+ }
+ }
+ } else { /* 1 Byte */
+ if(u8l >= 1) {
+ back = 1;
+ u8p[0] = (unsigned char)(c & 0x0000007FUL);
+ }
+ }
+ }
+ }
+
+#line 613 "dk3enc.ctr"
+ return back;
+}
+
+
+
+/** Get one 32-bit character from UTF-8 encoded string or buffer.
+ @param ucp Pointer to destination variable.
+ @param u8p Buffer containing UTF-8 encoded data.
+ @param u8l Length of @a u8p (number of bytes).
+ @param u8u Pointer to variable for used bytes from @a u8p.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3enc_utf82uc_rfc2279(
+ dk3_c32_t *ucp, unsigned char const *u8p,size_t u8l,size_t *u8u
+)
+{
+ int back = 0;
+ unsigned char u1 = 0x00; /* Character to process. */
+ dk3_c32_t res = 0UL; /* Result. */
+ dk3_c32_t x1 = 0UL; /* Result component from 1st byte. */
+ dk3_c32_t x2 = 0UL; /* Result component from 2nd byte. */
+ dk3_c32_t x3 = 0UL; /* Result component from 3rd byte. */
+ dk3_c32_t x4 = 0UL; /* Result component from 4th byte. */
+ dk3_c32_t x5 = 0UL; /* Result component from 5th byte. */
+ dk3_c32_t x6 = 0UL; /* Result component from 6th byte. */
+ size_t needed_length = 0; /* Number of btes needed. */
+
+
+#line 642 "dk3enc.ctr"
+ needed_length = 0;
+ if(ucp) {
+ if(u8p) {
+ if(u8l) {
+ if(u8u) {
+ if((u8l) > 0) {
+ u1 = *u8p; needed_length = 1;
+ if(u1 > 0x7F) { /* > 1 Byte */
+ if((u1 & 0xE0) == 0xC0) { /* 2 Byte */
+ needed_length = 2;
+ if(u8l >= needed_length) {
+ if((u8p[1] & 0xC0) == 0x80) {
+ x1 = u1;
+ x1 = x1 << 6;
+ x1 = x1 & 0x000007C0UL;
+ x2 = u8p[1];
+ x2 = x2 & 0x0000003FUL;
+ res = (x1 | x2); back = 1;
+ }
+ }
+ } else {
+ if((u1 & 0xF0) == 0xE0) { /* 3 Byte */
+ needed_length = 3;
+ if(u8l >= needed_length) {
+ if((u8p[1] & 0xC0) == 0x80) {
+ if((u8p[2] & 0xC0) == 0x80) {
+ x1 = u1;
+ x1 = x1 << 12;
+ x1 = x1 & 0x0000F000UL;
+ x2 = u8p[1];
+ x2 = x2 << 6;
+ x2 = x2 & 0x00000FC0UL;
+ x3 = u8p[2];
+ x3 = x3 & 0x0000003FUL;
+ res = (x1 | x2 | x3); back = 1;
+ }
+ }
+ }
+ } else {
+ if((u1 & 0xF8) == 0xF0) { /* 4 Byte */
+ needed_length = 4;
+ if(u8l >= needed_length) {
+ if((u8p[1] & 0xC0) == 0x80) {
+ if((u8p[2] & 0xC0) == 0x80) {
+ if((u8p[3] & 0xC0) == 0x80) {
+ x1 = u1;
+ x2 = u8p[1];
+ x3 = u8p[2];
+ x4 = u8p[3];
+ x1 = x1 << 18;
+ x1 = x1 & 0x001C0000UL;
+ x2 = x2 << 12;
+ x2 = x2 & 0x0003F000UL;
+ x3 = x3 << 6;
+ x3 = x3 & 0x00000FC0UL;
+ x4 = x4 & 0x0000003FUL;
+ res = (x1 | x2 | x3 | x4); back = 1;
+ }
+ }
+ }
+ }
+ } else {
+ if((u1 & 0xFC) == 0xF8) { /* 5 Byte */
+ needed_length = 5;
+ if(u8l >= needed_length) {
+ if((u8p[1] & 0xC0) == 0x80) {
+ if((u8p[2] & 0xC0) == 0x80) {
+ if((u8p[3] & 0xC0) == 0x80) {
+ if((u8p[4] & 0xC0) == 0x80) {
+ x1 = u1;
+ x2 = u8p[1];
+ x3 = u8p[2];
+ x4 = u8p[3];
+ x5 = u8p[4];
+ x1 = x1 << 24;
+ x1 = x1 & 0x03000000UL;
+ x2 = x2 << 18;
+ x2 = x2 & 0x00FC0000UL;
+ x3 = x3 << 12;
+ x3 = x3 & 0x0003F000UL;
+ x4 = x4 << 6;
+ x4 = x4 & 0x00000FC0UL;
+ x5 = x5 & 0x0000003FUL;
+ res = (x1 | x2 | x3 | x4 | x5); back = 1;
+ }
+ }
+ }
+ }
+ }
+ } else {
+ if((u1 & 0xFE) == 0xFC) { /* 6 Byte */
+ needed_length = 6;
+ if(u8l >= needed_length) {
+ if((u8p[1] & 0xC0) == 0x80) {
+ if((u8p[2] & 0xC0) == 0x80) {
+ if((u8p[3] & 0xC0) == 0x80) {
+ if((u8p[4] & 0xC0) == 0x80) {
+ if((u8p[5] & 0xC0) == 0x80) {
+ x1 = 0x40000000UL;
+ x2 = u8p[1]; x3 = u8p[2]; x4 = u8p[3];
+ x5 = u8p[4]; x6 = u8p[5];
+ x2 = x2 << 24;
+ x3 = x3 << 18;
+ x4 = x4 << 12;
+ x5 = x5 << 6;
+ x2 = x2 & 0x3F000000UL;
+ x3 = x3 & 0x00FC0000UL;
+ x4 = x4 & 0x0003F000UL;
+ x5 = x5 & 0x00000FC0UL;
+ x6 = x6 & 0x0000003FUL;
+ res = (x1 | x2 | x3 | x4 | x5 | x6);
+ back = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } else { /* 1 Byte */
+ res = u1;
+ back = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ if(back) {
+ *u8u = needed_length;
+ *ucp = res;
+ }
+
+#line 778 "dk3enc.ctr"
+ return back;
+}
+
+
+
+#if DK3_HAVE_RFC_2279
+
+/*
+ RFC 2279 allowed UTF-8 encoding for 32-bit characters in the
+ range 0 ... 0x7FFFFFFF.
+*/
+
+size_t
+dk3enc_uc2utf8(dk3_c32_t c, unsigned char *u8p, size_t u8l)
+{
+ size_t back;
+
+
+#line 795 "dk3enc.ctr"
+ back = dk3enc_uc2utf8_rfc2279(c, u8p, u8l);
+
+
+#line 797 "dk3enc.ctr"
+ return back;
+}
+
+int
+dk3enc_utf82uc(dk3_c32_t *ucp, unsigned char const *u8p,size_t u8l,size_t *u8u)
+{
+ int back;
+ back = dk3enc_utf82uc_rfc2279(ucp, u8p, u8l, u8u);
+ return back;
+}
+
+
+#else
+
+/*
+ RFC 3629 replaces (obsoletes) RFC 2279.
+ 32-bit characters are now allowed in the range
+ 0 ... 0x0010FFFF only.
+*/
+
+size_t
+dk3enc_uc2utf8(dk3_c32_t c, unsigned char *u8p, size_t u8l)
+{
+ size_t back = 0;
+
+
+#line 822 "dk3enc.ctr"
+ if(c <= (dk3_c32_t)0x0010FFFFUL) {
+ back = dk3enc_uc2utf8_rfc2279(c, u8p, u8l);
+ }
+
+#line 825 "dk3enc.ctr"
+ return back;
+}
+
+int
+dk3enc_utf82uc(dk3_c32_t *ucp, unsigned char const *u8p,size_t u8l,size_t *u8u)
+{
+ int back = 0;
+ back = dk3enc_utf82uc_rfc2279(ucp, u8p, u8l, u8u);
+ if(back) {
+ if((*ucp) > (dk3_c32_t)0x0010FFFFUL) {
+ back = 0;
+ }
+ }
+ return back;
+}
+
+#endif
+
+
+
+size_t
+dk3enc_uc2utf16(dk3_c32_t c, dk3_c16_t *u16p, size_t u16l)
+{
+ size_t back = 0;
+ dk3_c32_t ul = 0UL; /* Low surrogate. */
+ dk3_c32_t um = 0UL; /* Hight surrogate. */
+ if((u16p) && (u16l)) {
+ if(c >= (dk3_c32_t)0x00010000UL) {
+ if(c <= (dk3_c32_t)0x0010FFFFUL) {
+ if(u16l >= 2) {
+ ul = c - 0x00010000UL;
+ um = ((ul >> 10) & 0x000003FFUL);
+ um |= 0x0000D800UL;
+ u16p[0] = (dk3_c16_t)um;
+ um = (ul & 0x000003FFUL);
+ um |= 0x0000DC00UL;
+ u16p[1] = (dk3_c16_t)um;
+ back = 2;
+ }
+ }
+ } else {
+#if VERSION_BEFORE_20141125
+ if((c & 0x0000DC00UL) != 0x0000DC00UL) {
+ if((c & 0x0000DC00UL) != 0x0000D800UL) {
+ *u16p = (dk3_c16_t)c; back = 1;
+ }
+ }
+#else
+ if ((0x0000D800UL > c) || (0x0000DFFF < c)) {
+ *u16p = (dk3_c16_t)c; back = 1;
+ }
+#endif
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3enc_utf162uc(dk3_c32_t *ucp, dk3_c16_t const *u16p, size_t u16l, size_t *u16u)
+{
+ int back = 0;
+ dk3_c32_t result = 0UL; /* Result 32-bit character. */
+ dk3_c32_t ul1 = 0UL; /* First UC16 used. */
+ dk3_c32_t ul2 = 0UL; /* Second UC16 used (if any). */
+
+ if((ucp) && (u16p) && (u16l) && (u16u)) {
+ *u16u = 0;
+ ul1 = (((dk3_c32_t)(u16p[0])) & 0x0000FFFFUL);
+ ul2 = 0UL;
+ if(u16l > 1) {
+ ul2 = (((dk3_c32_t)(u16p[1])) & 0x0000FFFFUL);
+ }
+ if((ul1 & 0x0000DC00UL) == 0x0000DC00UL) {
+ if(u16l > 1) {
+ if((ul2 & 0x0000DC00UL) == 0x0000D800UL) {
+ ul2 = ((ul2 << 10) & 0x000FFC00UL);
+ ul1 = (ul1 & 0x000003FFUL);
+ result = ul1 | ul2;
+ result = result + 0x00010000UL;
+ *ucp = result; *u16u = 2; back = 1;
+ }
+ }
+ } else {
+ if((ul1 & 0x0000DC00UL) == 0x0000D800UL) {
+ if(u16l > 1) {
+ if((ul2 & 0x0000DC00UL) == 0x0000DC00UL) {
+ ul1 = ((ul1 << 10) & 0x000FFC00UL);
+ ul2 = (ul2 & 0x000003FFUL);
+ result = ul1 | ul2;
+ result = result + 0x00010000UL;
+ *ucp = result; *u16u = 2; back = 1;
+ }
+ }
+ } else {
+ ul1 &= 0x0000FFFFUL;
+ *ucp = ul1; *u16u = 1; back = 1;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Check whether a character is a digit.
+ @param c Character to check.
+ @return 1 on success, 0 on error.
+*/
+static int
+dk3enc_c8_is_digit(char c)
+{
+ int back = 0;
+ switch(c) {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ {
+ back = 1;
+ }
+ break;
+ }
+ return back;
+}
+
+
+
+/** Convert digit to corresponding unsigned long.
+ @param c Digit.
+ @return Unsigned long for the digit.
+*/
+static
+unsigned long
+dk3enc_c8_to_ul(char c)
+{
+ unsigned long back = 0UL;
+ if(c == '1') back = 1UL;
+ if(c == '2') back = 2UL;
+ if(c == '3') back = 3UL;
+ if(c == '4') back = 4UL;
+ if(c == '5') back = 5UL;
+ if(c == '6') back = 6UL;
+ if(c == '7') back = 7UL;
+ if(c == '8') back = 8UL;
+ if(c == '9') back = 9UL;
+ return back;
+}
+
+
+
+int
+dk3enc_ipaddr_to_ul_app(dkChar const *str, unsigned long *ul, dk3_app_t *app)
+{
+ char bu[512];
+ int back = 0;
+
+
+#line 981 "dk3enc.ctr"
+ if((str) && (ul)) {
+ if(dk3str_string_to_c8_simple_app(bu, sizeof(bu), str, app)) {
+
+#line 983 "dk3enc.ctr"
+ back = dk3enc_c8_ipaddr_to_ul_app(bu, ul, app);
+ } else {
+ /* ERROR: Conversion failed! */
+ }
+ }
+
+#line 988 "dk3enc.ctr"
+ return back;
+}
+
+
+
+int
+dk3enc_c8_ipaddr_to_ul_app(char const *str, unsigned long *ul, dk3_app_t *app)
+{
+ int back = 0;
+ int state = 0; /* Current state. */
+ char const *ptr = NULL; /* Used to traverse string. */
+ unsigned long ul1 = 0UL; /* First part of IP address. */
+ unsigned long ul2 = 0UL; /* Second part of IP address. */
+ unsigned long ul3 = 0UL; /* Third part of IP address. */
+ unsigned long ulval = 0UL; /* Resulting IP address. */
+
+
+#line 1004 "dk3enc.ctr"
+ if(str && ul) {
+ state = 0; ptr = str; back = 1;
+ ul1 = ul2 = ul3 = ulval = 0UL;
+ while(back && (*ptr)) {
+ if(dk3enc_c8_is_digit(*ptr)) {
+ switch(state) {
+ case 0:
+ case 1:
+ case 2:
+ case 4:
+ case 5:
+ case 6:
+ case 8:
+ case 9:
+ case 10:
+ case 12:
+ case 13:
+ case 14: {
+ ulval = 10UL * ulval + dk3enc_c8_to_ul(*ptr); state++;
+ } break;
+ default: {
+ back = 0;
+ } break;
+ }
+ } else {
+ if(*ptr == '.') {
+ switch(state) {
+ case 0:
+ case 1:
+ case 2:
+ case 3: {
+ ul1 = ulval; ulval = 0UL; state = 4;
+ } break;
+ case 4:
+ case 5:
+ case 6:
+ case 7: {
+ ul2 = ulval; ulval = 0UL; state = 8;
+ } break;
+ case 8:
+ case 9:
+ case 10:
+ case 11: {
+ ul3 = ulval; ulval = 0UL; state = 12;
+ } break;
+ }
+ } else {
+ back = 0;
+ }
+ }
+ ptr++;
+ }
+ if((state < 12) || (state > 15)) {
+ back = 0;
+ }
+ if(back) {
+ if(ul1 > 255UL) back = 1;
+ if(ul2 > 255UL) back = 1;
+ if(ul3 > 255UL) back = 1;
+ if(ulval > 255UL) back = 1;
+ }
+ if(back) {
+ ul1 = ul1 << 24;
+ ul1 &= 0xFF000000UL;
+ ul2 = ul2 << 16;
+ ul2 &= 0x00FF0000UL;
+ ul3 = ul3 << 8;
+ ul3 &= 0x0000FF00UL;
+ ulval &= 0x000000FFUL;
+ ulval = ulval | ul1 | ul2 | ul3;
+ *ul = ulval;
+ } else {
+ if(app) {
+ /* Not an IP address! */
+ }
+ }
+ }
+
+
+#line 1082 "dk3enc.ctr"
+ return back;
+}
+
+
+
+size_t
+dk3enc_size_bin_to_a85(size_t s)
+{
+#if VERSION_BEFORE_20140809
+ size_t back = 0;
+ int ec = 0; /* Error code. */
+ unsigned long ul1 = 0UL; /* Original size converted to unsigned long. */
+ unsigned long ul2 = 0UL; /* Remainder of division by 4. */
+ unsigned long ul3 = 0UL; /* Result division by 4. */
+
+
+#line 1097 "dk3enc.ctr"
+ ul1 = (unsigned long)s;
+ ul2 = ul1 % 4UL;
+ ul3 = ul1 / 4UL;
+ if(ul2) ul2++; /* for last incomplete block */
+ ul1 = dk3ma_ul_add_ok(
+ dk3ma_ul_mul_ok(ul3, 5UL, &ec),
+ ul2,
+ &ec
+ ); /* add 25 percent */
+ ul1++; /* final 0x00 byte for string */
+ back = (size_t)ul1;
+ if(ec) back = 0; /* error checking */
+ if((unsigned long)back != ul1) back = 0;
+
+
+#line 1111 "dk3enc.ctr"
+ return back;
+#else
+ size_t back = 0;
+ size_t rem = 0; /* Division remainder */
+ size_t res = 0; /* Division result */
+ int ec = 0; /* Error code */
+
+
+#line 1118 "dk3enc.ctr"
+ rem = s % 4;
+ res = s / 4;
+ if (rem) { rem++; }
+ /* back = 5 * res + rem + 1 */
+ rem++;
+ back = dk3mem_add_size_t(rem, dk3mem_mul_size_t(5, res, &ec), &ec);
+ if (ec) { back = 0; }
+
+
+#line 1126 "dk3enc.ctr"
+ return back;
+#endif
+}
+
+
+
+/** Convert binary data to ASCII-85 encoded string.
+ @param dp Destination pointer.
+ @param ds Destination size.
+ @param sp Source pointer.
+ @param ss Source size.
+*/
+static
+void
+dk3enc_do_bin_to_ra85(char *dp, size_t ds, char const *sp, size_t ss)
+{
+ register char const *mysp = NULL; /* Source pointer. */
+ register unsigned char *mydp = NULL; /* Destination pointer. */
+ register unsigned long v = 0UL; /* Output value. */
+ register size_t i = 0; /* Current byte index. */
+ register short vused = 0; /* Flag: v is used. */
+
+
+#line 1148 "dk3enc.ctr"
+ mydp = (unsigned char *)dp; mysp = sp; v = 0UL; vused = 0;
+ for(i = 0; i < ss; i++) {
+ switch(vused++) {
+ case 3: {
+ v |=
+ ((((unsigned long)((unsigned char)(*(mysp++)))) << 24) & 0xFF000000UL);
+ } break;
+ case 2: {
+ v |=
+ ((((unsigned long)((unsigned char)(*(mysp++)))) << 16) & 0x00FF0000UL);
+ } break;
+ case 1: {
+ v |=
+ ((((unsigned long)((unsigned char)(*(mysp++)))) << 8) & 0x0000FF00UL);
+ } break;
+ default: {
+ v |=
+ ((((unsigned long)((unsigned char)(*(mysp++)))) ) & dk3enc_last_byte);
+ } break;
+ }
+ if(vused >= 4) {
+ *(mydp++) = (unsigned char)((v % 85UL) + 33UL);
+ v = v / 85UL;
+ *(mydp++) = (unsigned char)((v % 85UL) + 33UL);
+ v = v / 85UL;
+ *(mydp++) = (unsigned char)((v % 85UL) + 33UL);
+ v = v / 85UL;
+ *(mydp++) = (unsigned char)((v % 85UL) + 33UL);
+ v = v / 85UL;
+ *(mydp++) = (unsigned char)((v % 85UL) + 33UL);
+ vused = 0; v = 0UL;
+ }
+ }
+ if(vused) {
+ vused++;
+ while(vused--) {
+ *(mydp++) = (unsigned char)((v % 85UL) + 33UL);
+ v = v / 85UL;
+ }
+ }
+ *mydp = '\0';
+
+#line 1189 "dk3enc.ctr"
+}
+
+
+
+int
+dk3enc_bin_to_ra85_app(
+ char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app
+)
+{
+ int back = 0;
+ size_t needed_size = 0; /* Destination buffer minimum size. */
+
+
+#line 1201 "dk3enc.ctr"
+ if((dp) && (sp) && (ds) && (ss)) {
+ needed_size = dk3enc_size_bin_to_a85(ss);
+ if(needed_size) {
+ if(ds >= needed_size) {
+ dk3enc_do_bin_to_ra85(dp, ds, sp, ss);
+ back = 1;
+ } else {
+ if(app) {
+ /* Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ }
+
+#line 1215 "dk3enc.ctr"
+ return back;
+}
+
+
+
+size_t
+dk3enc_size_a85_to_bin(size_t s)
+{
+ size_t back = 0;
+ unsigned long ul1 = 0UL; /* Original size converted to unsigned long. */
+ unsigned long ul2 = 0UL; /* Remainder of division by 5. */
+ unsigned long ul3 = 0UL; /* Result of division by 5. */
+
+
+#line 1228 "dk3enc.ctr"
+ ul1 = (unsigned long)s;
+ ul2 = ul1 % 5UL;
+ ul3 = ul1 / 5UL;
+ ul1 = 4UL * ul3 + ul2;
+ back = (size_t)ul1;
+
+
+#line 1234 "dk3enc.ctr"
+ return back;
+}
+
+
+
+/** Check whether a character is from the ASCII-85 charset.
+ @param c Character to check.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3enc_c8_is_a85(char c)
+{
+ int back = 1;
+ if((int)c < 33) {
+ back = 0;
+ } else {
+ if((int)c > 117) {
+ back = 0;
+ }
+ }
+ return back;
+}
+
+
+
+/** Convert reverse ASCII-85 encoded data to binary data.
+ @param dp Destination pointer.
+ @param ds Destination size.
+ @param sp Source pointer.
+ @param ss Source size.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Number of binary bytes produced.
+*/
+static
+size_t
+dk3enc_do_ra85_to_bin(char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app)
+{
+ size_t back = 0;
+ unsigned char *mydp = NULL; /* Destination pointer. */
+ char const *mysp = NULL; /* Source pointer. */
+ unsigned long v = 0UL; /* Double-word. */
+ short vused = 0; /* Flag: v is used. */
+ size_t i = 0; /* Index of current source byte. */
+ int reported_illegal_char = 0; /* Flag: Error already reported. */
+
+
+#line 1280 "dk3enc.ctr"
+ mydp = (unsigned char *)dp; mysp = sp; v = 0UL; vused = 0;
+ for(i = 0; i < ss; i++) {
+ if(dk3enc_c8_is_a85(*mysp)) {
+ v += dk3enc_f2[vused++] * ((((unsigned long)((unsigned char)(*mysp))) & dk3enc_last_byte) - 33UL);
+ if(vused >= 5) {
+ *(mydp++) = (unsigned char)(v & dk3enc_last_byte);
+ *(mydp++) = (unsigned char)((v >> 8) & dk3enc_last_byte);
+ *(mydp++) = (unsigned char)((v >> 16) & dk3enc_last_byte);
+ *(mydp++) = (unsigned char)((v >> 24) & dk3enc_last_byte);
+ back += 4;
+ v = 0UL; vused = 0;
+ }
+ } else {
+ if(app) {
+ if(!reported_illegal_char) {
+ reported_illegal_char = 1;
+ /* Illegal character(s) in source string! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 67);
+ }
+ }
+ }
+ mysp++;
+ }
+ if(vused) {
+ vused--;
+ while(vused--) {
+ *(mydp++) = (unsigned char)(v & dk3enc_last_byte);
+ back++;
+ v = v >> 8;
+ }
+ }
+
+#line 1311 "dk3enc.ctr"
+ return back;
+}
+
+
+
+size_t
+dk3enc_ra85_to_bin_app(
+ char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app
+)
+{
+ size_t back = 0;
+ size_t needed_size = 0; /* Minimum output buffer size. */
+
+
+#line 1324 "dk3enc.ctr"
+ if((dp) && (sp) && (ds) && (ss)) {
+ needed_size = dk3enc_size_a85_to_bin(ss);
+ if(needed_size) {
+ if(ds >= needed_size) {
+ back = dk3enc_do_ra85_to_bin(dp, ds, sp, ss, app);
+ } else {
+ if(app) {
+ /* Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ }
+
+#line 1337 "dk3enc.ctr"
+ return back;
+}
+
+
+
+size_t
+dk3enc_ra85string_to_bin_app(
+ char *dp, size_t ds, char const *sp, dk3_app_t *app
+)
+{
+ size_t back = 0;
+
+
+#line 1349 "dk3enc.ctr"
+ if(sp) {
+ back = dk3enc_ra85_to_bin_app(dp, ds, sp, dk3str_c8_len(sp), app);
+ }
+ return back;
+}
+
+
+
+/** Convert binary data to ASCII-85 string.
+ @param dp Destination pointer.
+ @param ds Destination size.
+ @param sp Source pointer.
+ @param ss Source size.
+*/
+static
+void
+dk3enc_do_bin_to_a85(char *dp, size_t ds, char const *sp, size_t ss)
+{
+ register unsigned char *mydp = NULL; /* Destination pointer. */
+ register unsigned char *mysp = NULL; /* Source pointer. */
+ register unsigned long v = 0UL; /* Double-word. */
+ register short vused = 0; /* Flag: v used. */
+ register short addval = 0; /* Value to add. */
+ register size_t i = 0; /* Index of current source byte. */
+
+
+#line 1374 "dk3enc.ctr"
+ mydp = (unsigned char *)dp;
+ mysp = (unsigned char *)sp;
+ v = 0UL;
+ vused = 0;
+ for(i = 0; i < ss; i++) {
+ switch(vused) {
+ case 3: {
+ v |= ( ((unsigned long)(*(mysp++))) & 0x000000FFUL);
+ } break;
+ case 2: {
+ v |= ((((unsigned long)(*(mysp++))) << 8) & 0x0000FF00UL);
+ } break;
+ case 1: {
+ v |= ((((unsigned long)(*(mysp++))) << 16) & 0x00FF0000UL);
+ } break;
+ default: {
+ v |= ((((unsigned long)(*(mysp++))) << 24) & 0xFF000000UL);
+ } break;
+ }
+ if(++vused >= 4) {
+ vused = 5;
+ while(vused--) {
+ *(mydp++) = (unsigned char)(33UL + v / dk3enc_f2[vused]);
+ v = v % dk3enc_f2[vused];
+ }
+ v = 0UL; vused = 0;
+ }
+ }
+ if(vused) {
+ vused++; addval = 5 - vused;
+ while(vused--) {
+ *(mydp++) = (unsigned char)(33UL + v / dk3enc_f2[vused + addval]);
+ v = v % dk3enc_f2[vused + addval];
+ }
+ }
+ *mydp = '\0';
+
+#line 1410 "dk3enc.ctr"
+}
+
+
+
+int
+dk3enc_bin_to_a85_app(
+ char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app
+)
+{
+ int back = 0;
+ size_t needed_size = 0; /* Minimum output buffer size. */
+
+
+#line 1422 "dk3enc.ctr"
+ if((dp) && (sp) && (ds) && (ss)) {
+ needed_size = dk3enc_size_bin_to_a85(ss);
+ if(needed_size) {
+ if(ds >= needed_size) {
+ dk3enc_do_bin_to_a85(dp, ds, sp, ss);
+ back = 1;
+ } else {
+ if(app) {
+ /* Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ }
+
+#line 1436 "dk3enc.ctr"
+ return back;
+}
+
+
+
+/** Convert ASCII-85 encoded data to binary data.
+ @param dp Destination pointer.
+ @param ds Destination size.
+ @param sp Source pointer.
+ @param ss Source size.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Number of binary bytes produced.
+*/
+static
+size_t
+dk3enc_do_a85_to_bin(char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app)
+{
+ register size_t back = 0;
+ register unsigned char *mydp = NULL; /* Destination pointer. */
+ register unsigned char const *mysp = NULL; /* Source pointer. */
+ register unsigned long v = 0UL; /* Double-word. */
+ register short vused = 0; /* Flag: v used. */
+ register size_t i = 0; /* Current source byte index. */
+ unsigned long u1 = 0UL; /* Temporary value. */
+ unsigned long u2 = 0UL; /* Temporary value. */
+ unsigned long u3 = 0UL; /* Temporary value. */
+ int reported_illegal_character = 0;
+
+
+#line 1464 "dk3enc.ctr"
+ mydp = (unsigned char *)dp; mysp = (unsigned char *)sp;
+ v = 0UL; vused = 0;
+ for(i = 0; i < ss; i++) {
+ if(*mysp) {
+ if(dk3enc_c8_is_a85(*mysp)) {
+ v += dk3enc_f2[4 - vused] *
+ ((((unsigned long)(*mysp)) & 0x000000FFUL) - 33UL);
+ } else {
+ if(!reported_illegal_character) {
+ reported_illegal_character = 1;
+ if(app) {
+ /* Illegal character in source data! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 67);
+ }
+ }
+ }
+ vused++;
+ if(vused >= 5) {
+ *(mydp++) = (unsigned char)((v >> 24) & 0x000000FFUL); back++;
+ *(mydp++) = (unsigned char)((v >> 16) & 0x000000FFUL); back++;
+ *(mydp++) = (unsigned char)((v >> 8) & 0x000000FFUL); back++;
+ *(mydp++) = (unsigned char)( v & 0x000000FFUL); back++;
+ v = 0UL; vused = 0;
+ }
+ }
+ mysp++;
+ }
+ if(vused) {
+ u1 = (v >> 24) & 0x000000FFUL;
+ u2 = (v >> 16) & 0x000000FFUL;
+ u3 = (v >> 8) & 0x000000FFUL;
+ switch(vused) {
+ case 2: {
+ if(v & 0x00FFFFFFUL) {
+ u1++; if(u1 >= 256UL) u1 = 0UL;
+ }
+ *(mydp++) = (unsigned char)(u1 & 0x000000FFUL); back++;
+ } break;
+ case 3: {
+ if(v & 0x0000FFFFUL) {
+ u2++;
+ if(u2 >= 256UL) {
+ u2 = 0UL;
+ u1++; if(u1 >= 256UL) u1 = 0UL;
+ }
+ }
+ *(mydp++) = (unsigned char)(u1 & 0x000000FFUL); back++;
+ *(mydp++) = (unsigned char)(u2 & 0x000000FFUL); back++;
+ } break;
+ case 4: {
+ if(v & 0x000000FFUL) {
+ u3++;
+ if(u3 >= 256UL) {
+ u3 = 0UL;
+ u2++;
+ if(u2 >= 256UL) {
+ u2 = 0UL;
+ u1++; if(u1 >= 256UL) u1 = 0UL;
+ }
+ }
+ }
+ *(mydp++) = (unsigned char)(u1 & 0x000000FFUL); back++;
+ *(mydp++) = (unsigned char)(u2 & 0x000000FFUL); back++;
+ *(mydp++) = (unsigned char)(u3 & 0x000000FFUL); back++;
+ } break;
+ }
+ }
+
+#line 1531 "dk3enc.ctr"
+ return back;
+}
+
+
+
+size_t
+dk3enc_a85_to_bin_app(
+ char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app
+)
+{
+ size_t back = 0;
+ size_t needed_size = 0; /* Minimum output buffer size. */
+
+
+#line 1544 "dk3enc.ctr"
+ if((dp) && (sp) && (ds) && (ss)) {
+ needed_size = dk3enc_size_a85_to_bin(ss);
+ if(needed_size) {
+ if(ds >= needed_size) {
+ back = dk3enc_do_a85_to_bin(dp, ds, sp, ss, app);
+ } else {
+ if(app) {
+ /* Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ }
+
+#line 1557 "dk3enc.ctr"
+ return back;
+}
+
+
+
+size_t
+dk3enc_a85string_to_bin_app(char *dp, size_t ds, char const *sp, dk3_app_t *app)
+{
+ size_t back = 0;
+
+
+#line 1567 "dk3enc.ctr"
+ if(sp) {
+ back = dk3enc_a85_to_bin_app(dp, ds, sp, dk3str_c8_len(sp), app);
+ }
+
+#line 1570 "dk3enc.ctr"
+ return back;
+}
+
+
+
+size_t
+dk3enc_size_bin_to_hex(size_t s)
+{
+#if VERSION_BEFORE_20140809
+ size_t back = 0;
+ int ec = 0; /* Error code. */
+ unsigned long ul1 = 0UL; /* Temporary value for calculation. */
+
+
+#line 1583 "dk3enc.ctr"
+ ul1 = (unsigned long)s;
+ ul1 = dk3ma_ul_mul_ok(ul1, 2UL, &ec);
+ ul1 = dk3ma_ul_add_ok(ul1, 1UL, &ec);
+ back = (size_t)ul1;
+ if(ec) back = 0;
+ if((unsigned long)back != ul1) back = 0;
+
+
+#line 1590 "dk3enc.ctr"
+ return back;
+#else
+ size_t back = 0;
+ int ec = 0; /* Error code */
+
+
+#line 1595 "dk3enc.ctr"
+ back = dk3mem_add_size_t(1, dk3mem_mul_size_t(2, s, &ec), &ec);
+ if (ec) { back = 0; }
+
+
+#line 1598 "dk3enc.ctr"
+ return back;
+#endif
+}
+
+
+
+size_t
+dk3enc_size_hex_to_bin(size_t s)
+{
+ size_t back;
+
+
+#line 1609 "dk3enc.ctr"
+ back = s / 2;
+ back++;
+
+#line 1611 "dk3enc.ctr"
+ return back;
+}
+
+
+
+/** Get higher half-byte from character.
+ @param c Source character.
+ @return Higher half-byte of \a c.
+*/
+static
+char
+dk3enc_c8_high_nibble_hex(char c)
+{
+ char back;
+ back = dk3enc_hex_digits[ (((unsigned short)c) >> 4) & 0x000FU ];
+ return back;
+}
+
+
+
+/** Get lower half-byte from character.
+ @param c Source character.
+ @return Lower half-byte of \a c.
+*/
+static
+char
+dk3enc_c8_low_nibble_hex(char c)
+{
+ char back;
+ back = dk3enc_hex_digits[ ((unsigned short)c) & 0x000FU ];
+ return back;
+}
+
+
+
+/** Convert binary data to hexadecimal string.
+ @param dp Destination pointer.
+ @param ds Destination size.
+ @param sp Source pointer.
+ @param ss Source size.
+ @param app Application structure for diagnostics, may be NULL.
+*/
+static
+void
+dk3enc_do_bin_to_hex(char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app)
+{
+ register char *mydp = NULL; /* Destination pointer. */
+ register char const *mysp = NULL; /* Source pointer. */
+ register size_t i = 0; /* Current source byte index. */
+
+
+#line 1661 "dk3enc.ctr"
+ mydp = dp; mysp = sp;
+ for(i = 0; i < ss; i++) {
+ *(mydp++) = dk3enc_c8_high_nibble_hex(*mysp);
+ *(mydp++) = dk3enc_c8_low_nibble_hex(*(mysp++));
+ }
+ *mydp = '\0';
+
+#line 1667 "dk3enc.ctr"
+}
+
+
+
+int
+dk3enc_bin_to_hex_app(
+ char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app
+)
+{
+ int back = 0;
+ size_t needed_bytes = 0; /* Minimum output buffer size. */
+
+
+#line 1679 "dk3enc.ctr"
+ if((dp) && (ds) && (sp) && (ss)) {
+ needed_bytes = dk3enc_size_bin_to_hex(ss);
+ if(needed_bytes) {
+ if(ds >= needed_bytes) {
+ dk3enc_do_bin_to_hex(dp, ds, sp, ss, app); back = 1;
+ } else {
+ if(app) {
+ /* Destination buffer too small1 */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ }
+
+#line 1692 "dk3enc.ctr"
+ return back;
+}
+
+
+
+/** Convert hexadecimal data to binary data.
+ @param dp Destination pointer.
+ @param ds Destination size.
+ @param sp Source pointer.
+ @param ss Source size.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Number of bytes created in destination.
+*/
+static
+size_t
+dk3enc_do_hex_to_bin(char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app)
+{
+ register size_t back = 0;
+ register char const *mysp = NULL; /* Source pointer. */
+ register unsigned char *mydp = NULL; /* Destination pointer. */
+ register unsigned char v = 0x00; /* Current byte to process. */
+ register short int vused = 0; /* Flag: v used. */
+ register size_t i = 0; /* Current source byte index. */
+ int reported_illegal_character = 0; /* Flag: Error already reported. */
+
+
+#line 1717 "dk3enc.ctr"
+ mydp = (unsigned char *)dp;
+ mysp = sp; v = 0x00; vused = 0U;
+ for(i = 0; i < ss; i++) {
+ switch(*mysp) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case 'a':
+ case 'A':
+ case 'b':
+ case 'B':
+ case 'c':
+ case 'C':
+ case 'd':
+ case 'D':
+ case 'e':
+ case 'E':
+ case 'f':
+ case 'F':
+ {
+ if(vused) {
+ switch(*mysp) {
+ case '0': { v |= 0x00; } break;
+ case '1': { v |= 0x01; } break;
+ case '2': { v |= 0x02; } break;
+ case '3': { v |= 0x03; } break;
+ case '4': { v |= 0x04; } break;
+ case '5': { v |= 0x05; } break;
+ case '6': { v |= 0x06; } break;
+ case '7': { v |= 0x07; } break;
+ case '8': { v |= 0x08; } break;
+ case '9': { v |= 0x09; } break;
+ case 'a': { v |= 0x0A; } break;
+ case 'A': { v |= 0x0A; } break;
+ case 'b': { v |= 0x0B; } break;
+ case 'B': { v |= 0x0B; } break;
+ case 'c': { v |= 0x0C; } break;
+ case 'C': { v |= 0x0C; } break;
+ case 'd': { v |= 0x0D; } break;
+ case 'D': { v |= 0x0D; } break;
+ case 'e': { v |= 0x0E; } break;
+ case 'E': { v |= 0x0E; } break;
+ case 'f': { v |= 0x0F; } break;
+ case 'F': { v |= 0x0F; } break;
+ }
+ *(mydp++) = v; back++; v = 0; vused = 0U;
+ } else {
+ switch(*mysp) {
+ case '0': { v = 0x00; } break;
+ case '1': { v = 0x10; } break;
+ case '2': { v = 0x20; } break;
+ case '3': { v = 0x30; } break;
+ case '4': { v = 0x40; } break;
+ case '5': { v = 0x50; } break;
+ case '6': { v = 0x60; } break;
+ case '7': { v = 0x70; } break;
+ case '8': { v = 0x80; } break;
+ case '9': { v = 0x90; } break;
+ case 'a': { v = 0xA0; } break;
+ case 'A': { v = 0xA0; } break;
+ case 'b': { v = 0xB0; } break;
+ case 'B': { v = 0xB0; } break;
+ case 'c': { v = 0xC0; } break;
+ case 'C': { v = 0xC0; } break;
+ case 'd': { v = 0xD0; } break;
+ case 'D': { v = 0xD0; } break;
+ case 'e': { v = 0xE0; } break;
+ case 'E': { v = 0xE0; } break;
+ case 'f': { v = 0xF0; } break;
+ case 'F': { v = 0xF0; } break;
+ }
+ vused = 1U;
+ }
+ } break;
+ default: {
+ if(!reported_illegal_character) {
+ reported_illegal_character = 1;
+ if(app) {
+ /* Illegal character(s) in source! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 67);
+ }
+ }
+ } break;
+ }
+ mysp++;
+ }
+ if(vused) {
+ *mydp = v; back++;
+ }
+
+#line 1813 "dk3enc.ctr"
+ return back;
+}
+
+
+
+size_t
+dk3enc_hex_to_bin_app(
+ char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app
+)
+{
+ size_t back = 0;
+ size_t needed_bytes = 0; /* Minimum output buffer size. */
+
+
+#line 1826 "dk3enc.ctr"
+ if((dp) && (ds) && (sp) && (ss)) {
+ needed_bytes = dk3enc_size_hex_to_bin(ss);
+ if(needed_bytes) {
+ if(ds >= needed_bytes) {
+ back = dk3enc_do_hex_to_bin(dp, ds, sp, ss, app);
+ } else {
+ if(app) {
+ /* Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ }
+
+#line 1839 "dk3enc.ctr"
+ return back;
+}
+
+
+
+size_t
+dk3enc_hexstring_to_bin_app(
+ char *dp, size_t ds, char const *sp, dk3_app_t *app
+)
+{
+ size_t back = 0;
+
+
+#line 1851 "dk3enc.ctr"
+ if(sp) {
+ back = dk3enc_hex_to_bin_app(dp, ds, sp, dk3str_c8_len(sp), app);
+ }
+
+#line 1854 "dk3enc.ctr"
+ return back;
+}
+
+
+
+size_t
+dk3enc_size_hexstring_to_bin(char const *s)
+{
+ size_t back = 0;
+
+
+#line 1864 "dk3enc.ctr"
+ if(s) {
+ back = dk3str_c8_len(s);
+ back = dk3enc_size_hex_to_bin(back);
+ }
+
+#line 1868 "dk3enc.ctr"
+ return back;
+}
+
+
+
+size_t
+dk3enc_size_a85string_to_bin(char const *s)
+{
+ size_t back = 0;
+
+
+#line 1878 "dk3enc.ctr"
+ if(s) {
+ back = dk3str_c8_len(s);
+ back = dk3enc_size_a85_to_bin(back);
+ }
+
+#line 1882 "dk3enc.ctr"
+ return back;
+}
+
+
+
+int
+dk3enc_get_type_app(dkChar const *n, dk3_app_t *app)
+{
+ int back = -1;
+ if(n) {
+ back = dk3str_array_index(dk3enc_data_encoding_names, n, 0);
+ if(back >= 0) {
+ switch(back) {
+ case 0: case 3: {
+ back = DK3_DATA_ENCODING_HEX;
+ } break;
+ case 1: case 4: case 6: {
+ back = DK3_DATA_ENCODING_ASCII85;
+ } break;
+ case 2: case 5: case 7: {
+ back = DK3_DATA_ENCODING_REVERSE_ASCII85;
+ } break;
+ }
+ } else {
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 129, 130, n);
+ }
+ }
+ }
+ return back;
+}
+
+
+dkChar const *
+dk3enc_get_data_encoding_name(int t)
+{
+ dkChar const *back = NULL;
+ if((t >= 0) && (t <= 2)) {
+ back = dk3enc_data_encoding_names[t];
+ }
+ return back;
+}
+
+
+
+int
+dk3enc_get_text_encoding_app(dkChar const *en, dk3_app_t *app)
+{
+ int back = -1;
+ int i;
+
+
+#line 1933 "dk3enc.ctr"
+ if(app) { back = dk3app_get_output_encoding(app); }
+ if(en) {
+ i = dk3str_array_index(dk3enc_text_encoding_names, en, 0);
+
+#line 1936 "dk3enc.ctr"
+ switch(i) {
+ case 0: case 8: case 9: {
+ back = DK3_FILE_ENCODING_ASCII;
+ } break;
+ case 1: case 10: {
+ back = DK3_FILE_ENCODING_UTF8;
+ } break;
+ case 2: case 11: {
+#if DK3_HAVE_BIGENDIAN
+ back = DK3_FILE_ENCODING_UTF16_MSB_FIRST;
+#else
+ back = DK3_FILE_ENCODING_UTF16_LSB_FIRST;
+#endif
+ } break;
+ case 3: case 18: case 19: case 20: case 21: case 22: case 23: {
+ back = DK3_FILE_ENCODING_UTF16_MSB_FIRST;
+ } break;
+ case 4: case 12: case 13: case 14: case 15: case 16: case 17: {
+ back = DK3_FILE_ENCODING_UTF16_LSB_FIRST;
+ } break;
+ case 5: case 24: {
+#if DK3_HAVE_BIGENDIAN
+ back = DK3_FILE_ENCODING_UNICODE_MSB_FIRST;
+#else
+ back = DK3_FILE_ENCODING_UNICODE_LSB_FIRST;
+#endif
+ } break;
+ case 6: case 29: case 30: case 31: case 32: {
+ back = DK3_FILE_ENCODING_UNICODE_MSB_FIRST;
+ } break;
+ case 7: case 25: case 26: case 27: case 28: {
+ back = DK3_FILE_ENCODING_UNICODE_LSB_FIRST;
+ } break;
+ default: {
+ if(app) {
+ /* ERROR: Unknown text encoding name! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 129, 130, en);
+ }
+ } break;
+ }
+ }
+
+#line 1977 "dk3enc.ctr"
+ return back;
+}
+
+
+
+int
+dk3enc_get_encoding(dk3_app_t *app)
+{
+ int back = 0;
+#if DK3_CHAR_SIZE == 1
+ char *ptr;
+#endif
+ if(app) {
+ back = dk3app_get_encoding(app);
+ } else {
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ back = DK3_ENCODING_UNICODE;
+#else
+ back = DK3_ENCODING_UTF16;
+#endif
+#else
+ back = DK3_ENCODING_PLAIN;
+ ptr = getenv("LANG");
+ if(ptr) {
+ ptr = dk3str_c8_chr(ptr, '.');
+ if(ptr) {
+ ptr++;
+ switch(dk3str_c8_array_index(dk3enc_utf8_names, ptr, 0)) {
+ case 0: case 1: {
+ back = DK3_ENCODING_UTF8;
+ } break;
+ }
+ }
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dk3enc.ctr b/support/dktools/dk3enc.ctr
new file mode 100644
index 0000000000..0c80cf3bda
--- /dev/null
+++ b/support/dktools/dk3enc.ctr
@@ -0,0 +1,2020 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% header
+
+#include "dk3conf.h"
+#include "dk3types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert long number from net to host representation.
+ @param x Number to convert.
+ @return Conversion result.
+*/
+unsigned long
+dk3enc_ntohl(unsigned long x);
+
+/** Convert long number from host to net representation.
+ @param x Number to convert.
+ @return Conversion result.
+*/
+unsigned long
+dk3enc_htonl(unsigned long x);
+
+/** Convert short number from net to host representation.
+ @param x Number to convert.
+ @return Conversion result.
+*/
+unsigned short
+dk3enc_ntohs(unsigned short x);
+
+/** Convert short number from host to net representation.
+ @param x Number to convert.
+ @return Conversion result.
+*/
+unsigned short
+dk3enc_htons(unsigned short x);
+
+/** Convert 32-bit character to UTF-8.
+ @param c 32-bit character to convert.
+ @param u8p Pointer to result buffer.
+ @param u8l Size of result buffer, should be 8 at least.
+ @return Number of bytes used in result buffer.
+*/
+size_t
+dk3enc_uc2utf8(dk3_c32_t c, unsigned char *u8p, size_t u8l);
+
+/** Convert UTF-8 encoded text to 32-bit character.
+ @param ucp Pointer to variable for result.
+ @param u8p Buffer containing UTF-8 encoded text.
+ @param u8l Number of bytes in buffer.
+ @param u8u Pointer to variable to receive number of bytes used.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3enc_utf82uc(dk3_c32_t *ucp, unsigned char const *u8p,size_t u8l,size_t *u8u);
+
+/** Convert IP address from 8-bit text string to long number
+ in host representation.
+ @param str Text string containing the IP address.
+ @param ul Pointer to result variable.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3enc_c8_ipaddr_to_ul_app(char const *str, unsigned long *ul, dk3_app_t *app);
+
+/** Convert IP address from string to long number
+ in host representation.
+ @param str Text string containing the IP address.
+ @param ul Pointer to result variable.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3enc_ipaddr_to_ul_app(dkChar const *str, unsigned long *ul, dk3_app_t *app);
+
+/** Find size for result buffer needed to convert binary data to
+ text using ASCII-85 encoding.
+ @param s Size of binary data.
+ @return The required buffer length (includeing finalizing 0x00 byte).
+*/
+size_t
+dk3enc_size_bin_to_a85(size_t s);
+
+/** Convert binary data to text using reverse ASCII-85 encoding.
+ @param dp Destination buffer pointer.
+ @param ds Size of \a dp.
+ @param sp Binary (source) data.
+ @param ss Number of bytes in \a sp.
+ @param app Application structure, for diagnostics, may be NULL.
+*/
+int
+dk3enc_bin_to_ra85_app(
+ char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app
+);
+
+/** Find size for result buffer needed to convert ASCII-85 encoded
+ data back to binary data.
+ @param s Number of ASCII-85 text characters.
+ @return Length of resulting binary data.
+*/
+size_t
+dk3enc_size_a85_to_bin(size_t s);
+
+/** Convert reverse ASCII-85 encoded data back to binary.
+ @param dp Destination buffer pointer.
+ @param ds Destination buffer size in bytes.
+ @param sp Source buffer pointer.
+ @param ss Source buffer length.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Number of binary bytes decoded.
+*/
+size_t
+dk3enc_ra85_to_bin_app(
+ char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app
+);
+
+#if 0
+/** Convert reverse ASCII-85 encoded data back to binary.
+ @param dp Destination buffer pointer.
+ @param ds Destination buffer size in bytes.
+ @param sp Source buffer pointer.
+ @param ss Source buffer length.
+ @return Number of binary bytes decoded.
+*/
+size_t
+dk3enc_ra85_to_bin(char *dp, size_t ds, char const *sp, size_t ss);
+#endif
+
+/** Convert reverse ASCII-85 encoded data string back to binary.
+ @param dp Destination buffer pointer.
+ @param ds Destination buffer size in bytes.
+ @param sp Source buffer pointer.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Number of binary bytes decoded.
+*/
+size_t
+dk3enc_ra85string_to_bin_app(
+ char *dp, size_t ds, char const *sp, dk3_app_t *app
+);
+
+/** Apply ASCII-85 encoding to binary data.
+ @param dp Destination buffer pointer.
+ @param ds Destination buffer size.
+ @param sp Source buffer pointer.
+ @param ss Source buffer size.
+ @param app Application structure for diagnostics, may be NULL.
+*/
+int
+dk3enc_bin_to_a85_app(
+ char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app
+);
+
+/** Decode ASCII-85 encoded data back to binary.
+ @param dp Destination buffer pointer.
+ @param ds Destination buffer size.
+ @param sp Source buffer pointer.
+ @param ss Source buffer size.
+ @param app Application structure for diagnostics, may be NULL.
+*/
+size_t
+dk3enc_a85_to_bin_app(
+ char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app
+);
+
+/** Decode ASCII-85 encoded data string back to binary.
+ @param dp Destination buffer pointer.
+ @param ds Destination buffer size.
+ @param sp Source buffer pointer.
+ @param app Application structure for diagnostics, may be NULL.
+*/
+size_t
+dk3enc_a85string_to_bin_app(char *dp, size_t ds, char const *sp, dk3_app_t *app);
+
+/** Calculate size for binary to hexadecimal conversion.
+ @param s Size of binary data.
+ @return Size of hexadecimal encoding.
+*/
+size_t
+dk3enc_size_bin_to_hex(size_t s);
+
+/** Calculate size for hexadecimal to binary conversion.
+ @param s Size of hexadecimal data.
+ @return Size of binary data.
+*/
+size_t
+dk3enc_size_hex_to_bin(size_t s);
+
+/** Apply hexadecimal encoding to binary data.
+ @param dp Destination buffer pointer.
+ @param ds Destination buffer size.
+ @param sp Source buffer pointer.
+ @param ss Source buffer size.
+ @param app Application structure for diagnostics, may be NULL.
+*/
+int
+dk3enc_bin_to_hex_app(
+ char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app
+);
+
+/** Convert hexadecimal encoded data back to binary.
+ @param dp Destination buffer pointer.
+ @param ds Destination buffer size.
+ @param sp Source buffer pointer.
+ @param ss Source buffer size.
+ @param app Application structure for diagnostics, may be NULL.
+*/
+size_t
+dk3enc_hex_to_bin_app(
+ char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app
+);
+
+/** Convert hexadecimal encoded data string back to binary.
+ @param dp Destination buffer pointer.
+ @param ds Destination buffer size.
+ @param sp Source buffer pointer.
+ @param app Application structure for diagnostics, may be NULL.
+*/
+size_t
+dk3enc_hexstring_to_bin_app(
+ char *dp, size_t ds, char const *sp, dk3_app_t *app
+);
+
+/** Calculate size for hex decoding to binary.
+ @param s String containing hexadecimal data.
+ @return Size of binary data.
+*/
+size_t
+dk3enc_size_hexstring_to_bin(char const *s);
+
+/** Find size for conversion from ASCII-85 encoded data to binary.
+ * @param s ASCII-85 encoded string.
+ * @return Size of binary data.
+ */
+size_t
+dk3enc_size_a85string_to_bin(char const *s);
+
+/** Convert 32-bit character to UTF-16.
+ If the value is 0xFFFF and below, the 16 bits are used ``as is''.
+ For values \a c > 0xFFFF we have to build a surrogate pair.
+ We substract 0x00010000, the result is a new character with
+ 20 significant bits. These 20 bits are splitted into two blocks of
+ 10 bits each. The high surrogate is built using the prefix
+ bits 110110 and the higher 10-bits block. The low surrogate is built
+ using the prefix bits 110111 and the lower 10-bits block.
+ Order of surrogates in a surrogate pair is flexible, this function
+ writes the high surrogate first.
+ @param c The 32-bit character.
+ @param u16p Buffer to receive UTF-16 encoded result.
+ @param u16l Length of \a u16l in elements.
+ @return The number of dk3_c16_t characters produced.
+*/
+size_t
+dk3enc_uc2utf16(dk3_c32_t c, dk3_c16_t *u16p, size_t u16l);
+
+/** Convert UTF-16 encoded characters to 32-bit character
+ @param ucp Pointer to result variable.
+ @param u16p Buffer containing UTF-16 encoded text.
+ @param u16l Number of elements available in \a u16p.
+ @param u16u Pointer to variable to receive number of dk3_c16_t used.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3enc_utf162uc(dk3_c32_t *ucp, dk3_c16_t const *u16p, size_t u16l, size_t *u16u);
+
+/** Get data encoding type for name.
+ @param n Data encoding name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Integer representation of data encoding on success, -1 on error.
+*/
+int
+dk3enc_get_type_app(dkChar const *n, dk3_app_t *app);
+
+/** Get name for data encoding type.
+ @param t Numeric type.
+ @return Name for type on success, NULL on error.
+*/
+dkChar const *
+dk3enc_get_data_encoding_name(int t);
+
+/** Get numeric value for text encoding.
+ @param en Encoding name.
+ @param app Application structure, may be NULL.
+ @return Numeric representation of text encoding on success,
+ -1 on error.
+*/
+int
+dk3enc_get_text_encoding_app(dkChar const *en, dk3_app_t *app);
+
+/** Get the used encoding.
+ @param app Application structure, may be NULL.
+ @return The encoding used for characters in memory.
+*/
+int
+dk3enc_get_encoding(dk3_app_t *app);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk3all.h"
+
+
+$(trace-include)
+
+
+
+/** Binary to text encoding names.
+ Order here must match order of DK3_DATA_ENCODING_xxx in dk3const.h.
+*/
+static dkChar const * const dk3enc_data_encoding_names[] = {
+/* 0 */ dkT("HEX"),
+/* 1 */ dkT("ASCII-85"),
+/* 2 */ dkT("R-ASCII-85"),
+/* 3 */ dkT("H"),
+/* 4 */ dkT("A"),
+/* 5 */ dkT("R"),
+/* 6 */ dkT("A85"),
+/* 7 */ dkT("RA85"),
+NULL
+};
+
+
+
+/** Encoding names for file contents encodings.
+*/
+static dkChar const * const dk3enc_text_encoding_names[] = {
+/* 0 */ dkT("PLAIN"),
+/* 1 */ dkT("UTF-8"),
+/* 2 */ dkT("UTF-16"),
+/* 3 */ dkT("UTF-16.MSB"),
+/* 4 */ dkT("UTF-16.LSB"),
+/* 5 */ dkT("UC32"),
+/* 6 */ dkT("UC32.MSB"),
+/* 7 */ dkT("UC32.LSB"),
+/* 8 */ dkT("ASCII"),
+/* 9 */ dkT("ISO-LATIN-1"),
+/* 10 */ dkT("UTF8"),
+/* 11 */ dkT("UTF16"),
+/* 12 */ dkT("UTF-16-LE"),
+/* 13 */ dkT("UTF-16LE"),
+/* 14 */ dkT("UTF16LE"),
+/* 15 */ dkT("UTF-16-LSB"),
+/* 16 */ dkT("UTF-16LSB"),
+/* 17 */ dkT("UTF16LSB"),
+/* 18 */ dkT("UTF-16-BE"),
+/* 19 */ dkT("UTF-16BE"),
+/* 20 */ dkT("UTF16BE"),
+/* 21 */ dkT("UTF-16-MSB"),
+/* 22 */ dkT("UTF-16MSB"),
+/* 23 */ dkT("UTF16MSB"),
+/* 24 */ dkT("C32"),
+/* 25 */ dkT("C32-LE"),
+/* 26 */ dkT("C32LE"),
+/* 27 */ dkT("C32-LSB"),
+/* 28 */ dkT("C32LSB"),
+/* 29 */ dkT("C32-BE"),
+/* 30 */ dkT("C32BE"),
+/* 31 */ dkT("C32-MSB"),
+/* 32 */ dkT("C32MSB"),
+NULL
+};
+
+
+
+/** Encoding names for UTF-8 encoding.
+*/
+static char const * const dk3enc_utf8_names[] = {
+$!string-table
+utf-8
+utf8
+$!end
+};
+
+
+/** Digits used to show hexadecimal characters.
+*/
+static char const dk3enc_hex_digits[] = {
+'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', '\0'
+};
+
+
+/** Bit mask to obtain last byte of a double word.
+*/
+static unsigned long const dk3enc_last_byte = 0x000000FFUL;
+
+
+
+/** Factors for ASCII85 and reverse ASCII85 encoding.
+*/
+static unsigned long const dk3enc_f2[] = {
+ 1UL,
+ 85UL,
+ (85UL * 85UL),
+ (85UL * 85UL * 85UL),
+ (85UL * 85UL * 85UL * 85UL)
+};
+
+
+
+/** Swap byte order for unsigned long.
+ @param ul Original value.
+ @return Value in swapped byte order.
+*/
+static
+unsigned long
+dk3enc_swap_ul(unsigned long ul)
+{
+ unsigned long back = 0UL;
+ back = ((ul >> 24) & 0x000000FFUL);
+ back |= ((ul >> 8) & 0x0000FF00UL);
+ back |= ((ul << 8) & 0x00FF0000UL);
+ back |= ((ul << 24) & 0xFF000000UL);
+ return back;
+}
+
+
+
+/** Swap byte order for unsigned short.
+ @param us Original value.
+ @return Value in swapped byte order.
+*/
+static
+unsigned short
+dk3enc_swap_us(unsigned short us)
+{
+ unsigned short back = 0U;
+ back = ((us >> 8) & 0x00FFU);
+ back |= ((us << 8) & 0xFF00U);
+ return back;
+}
+
+
+unsigned long
+dk3enc_ntohl(unsigned long x)
+{
+ unsigned long back;
+#if DK3_WORDS_BIGENDIAN
+ back = x;
+#else
+ back = dk3enc_swap_ul(x);
+#endif
+ return back;
+}
+
+
+unsigned long
+dk3enc_htonl(unsigned long x)
+{
+ unsigned long back;
+#if DK3_WORDS_BIGENDIAN
+ back = x;
+#else
+ back = dk3enc_swap_ul(x);
+#endif
+ return back;
+}
+
+
+
+unsigned short
+dk3enc_ntohs(unsigned short x)
+{
+ unsigned short back;
+#if DK3_WORDS_BIGENDIAN
+ back = x;
+#else
+ back = dk3enc_swap_us(x);
+#endif
+ return back;
+}
+
+
+
+unsigned short
+dk3enc_htons(unsigned short x)
+{
+ unsigned short back;
+#if DK3_WORDS_BIGENDIAN
+ back = x;
+#else
+ back = dk3enc_swap_us(x);
+#endif
+ return back;
+}
+
+
+
+/** Convert 32-bit character to UTF-8 following RFC2279.
+ @param c 32-bit character to convert.
+ @param u8p Destination buffer.
+ @param u8l Length of @a u8p (number of bytes).
+ @return Number of bytes written to @a u8p.
+*/
+static
+size_t
+dk3enc_uc2utf8_rfc2279(dk3_c32_t c, unsigned char *u8p, size_t u8l)
+{
+ size_t back = 0;
+ dk3_c32_t x = 0UL; /* Variable for temporary results. */
+ $? "+ dk3enc_uc2utf8_rfc2279 0x%lx=%lu %lu", (unsigned long)c, (unsigned long)c, (unsigned long)u8l
+ if(u8p) {
+ if(u8l > 0) {
+ if(c > (dk3_c32_t)0x7FUL) {
+ if(c > (dk3_c32_t)0x000007FFUL) {
+ if(c > (dk3_c32_t)0x0000FFFFUL) {
+ if(c > (dk3_c32_t)0x001FFFFFUL) {
+ if(c > (dk3_c32_t)0x03FFFFFFUL) {
+ if(c < (dk3_c32_t)0x80000000UL) { /* 6 Byte */
+ if(u8l >= 6) {
+ back = 6;
+ x = c >> 30;
+ x &= 0x00000001UL;
+ x |= 0x000000FCUL;
+ u8p[0] = (unsigned char)x;
+ x = c >> 24; x &= 0x0000003FUL; x |= 0x00000080UL;
+ u8p[1] = (unsigned char)x;
+ x = c >> 18; x &= 0x0000003FUL; x |= 0x00000080UL;
+ u8p[2] = (unsigned char)x;
+ x = c >> 12; x &= 0x0000003FUL; x |= 0x00000080UL;
+ u8p[3] = (unsigned char)x;
+ x = c >> 6; x &= 0x0000003FUL; x |= 0x00000080UL;
+ u8p[4] = (unsigned char)x;
+ x = c & 0x0000003FUL; x |= 0x00000080UL;
+ u8p[5] = (unsigned char)x;
+ }
+ }
+ } else { /* 5 Byte */
+ if(u8l >= 5) {
+ back = 5;
+ x = c >> 24;
+ x &= 0x00000003UL;
+ x |= 0x000000F8UL;
+ u8p[0] = (unsigned char)x;
+ x = c >> 18; x &= 0x0000003FUL; x |= 0x00000080UL;
+ u8p[1] = (unsigned char)x;
+ x = c >> 12; x &= 0x0000003FUL; x |= 0x00000080UL;
+ u8p[2] = (unsigned char)x;
+ x = c >> 6; x &= 0x0000003FUL; x |= 0x00000080UL;
+ u8p[3] = (unsigned char)x;
+ x = c & 0x0000003FUL; x |= 0x00000080UL;
+ u8p[4] = (unsigned char)x;
+ }
+ }
+ } else { /* 4 Byte */
+ if(u8l >= 4) {
+ back = 4;
+ x = c >> 18;
+ x &= 0x00000007UL;
+ x |= 0x000000F0UL;
+ u8p[0] = (unsigned char)x;
+ x = c >> 12;
+ x &= 0x0000003FUL;
+ x |= 0x00000080UL;
+ u8p[1] = (unsigned char)x;
+ x = c >> 6;
+ x &= 0x0000003FUL;
+ x |= 0x00000080UL;
+ u8p[2] = (unsigned char)x;
+ x = c & 0x0000003FUL;
+ x |= 0x00000080UL;
+ u8p[3] = (unsigned char)x;
+ }
+ }
+ } else { /* 3 Byte */
+ if(u8l >= 3) {
+ back = 3;
+ x = c >> 12;
+ x &= 0x0000000FUL;
+ x |= 0x000000E0UL;
+ u8p[0] = (unsigned char)x;
+ x = c >> 6;
+ x &= 0x0000003FUL;
+ x |= 0x00000080UL;
+ u8p[1] = (unsigned char)x;
+ x = c & 0x0000003FUL;
+ x |= 0x00000080UL;
+ u8p[2] = (unsigned char)x;
+ }
+ }
+ } else { /* 2 Byte */
+ if(u8l >= 2) {
+ back = 2;
+ x = c >> 6;
+ x &= 0x0000001FUL;
+ x |= 0x000000C0UL;
+ u8p[0] = (unsigned char)x;
+ x = c & 0x0000003FUL;
+ x |= 0x00000080UL;
+ u8p[1] = (unsigned char)x;
+ }
+ }
+ } else { /* 1 Byte */
+ if(u8l >= 1) {
+ back = 1;
+ u8p[0] = (unsigned char)(c & 0x0000007FUL);
+ }
+ }
+ }
+ } $? "- dk3enc_uc2utf8_rfc2279 %lu", (unsigned long)back
+ return back;
+}
+
+
+
+/** Get one 32-bit character from UTF-8 encoded string or buffer.
+ @param ucp Pointer to destination variable.
+ @param u8p Buffer containing UTF-8 encoded data.
+ @param u8l Length of @a u8p (number of bytes).
+ @param u8u Pointer to variable for used bytes from @a u8p.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3enc_utf82uc_rfc2279(
+ dk3_c32_t *ucp, unsigned char const *u8p,size_t u8l,size_t *u8u
+)
+{
+ int back = 0;
+ unsigned char u1 = 0x00; /* Character to process. */
+ dk3_c32_t res = 0UL; /* Result. */
+ dk3_c32_t x1 = 0UL; /* Result component from 1st byte. */
+ dk3_c32_t x2 = 0UL; /* Result component from 2nd byte. */
+ dk3_c32_t x3 = 0UL; /* Result component from 3rd byte. */
+ dk3_c32_t x4 = 0UL; /* Result component from 4th byte. */
+ dk3_c32_t x5 = 0UL; /* Result component from 5th byte. */
+ dk3_c32_t x6 = 0UL; /* Result component from 6th byte. */
+ size_t needed_length = 0; /* Number of btes needed. */
+ $? "+ dk3enc_utf82uc"
+ needed_length = 0;
+ if(ucp) {
+ if(u8p) {
+ if(u8l) {
+ if(u8u) {
+ if((u8l) > 0) {
+ u1 = *u8p; needed_length = 1;
+ if(u1 > 0x7F) { /* > 1 Byte */
+ if((u1 & 0xE0) == 0xC0) { /* 2 Byte */
+ needed_length = 2;
+ if(u8l >= needed_length) {
+ if((u8p[1] & 0xC0) == 0x80) {
+ x1 = u1;
+ x1 = x1 << 6;
+ x1 = x1 & 0x000007C0UL;
+ x2 = u8p[1];
+ x2 = x2 & 0x0000003FUL;
+ res = (x1 | x2); back = 1;
+ }
+ }
+ } else {
+ if((u1 & 0xF0) == 0xE0) { /* 3 Byte */
+ needed_length = 3;
+ if(u8l >= needed_length) {
+ if((u8p[1] & 0xC0) == 0x80) {
+ if((u8p[2] & 0xC0) == 0x80) {
+ x1 = u1;
+ x1 = x1 << 12;
+ x1 = x1 & 0x0000F000UL;
+ x2 = u8p[1];
+ x2 = x2 << 6;
+ x2 = x2 & 0x00000FC0UL;
+ x3 = u8p[2];
+ x3 = x3 & 0x0000003FUL;
+ res = (x1 | x2 | x3); back = 1;
+ }
+ }
+ }
+ } else {
+ if((u1 & 0xF8) == 0xF0) { /* 4 Byte */
+ needed_length = 4;
+ if(u8l >= needed_length) {
+ if((u8p[1] & 0xC0) == 0x80) {
+ if((u8p[2] & 0xC0) == 0x80) {
+ if((u8p[3] & 0xC0) == 0x80) {
+ x1 = u1;
+ x2 = u8p[1];
+ x3 = u8p[2];
+ x4 = u8p[3];
+ x1 = x1 << 18;
+ x1 = x1 & 0x001C0000UL;
+ x2 = x2 << 12;
+ x2 = x2 & 0x0003F000UL;
+ x3 = x3 << 6;
+ x3 = x3 & 0x00000FC0UL;
+ x4 = x4 & 0x0000003FUL;
+ res = (x1 | x2 | x3 | x4); back = 1;
+ }
+ }
+ }
+ }
+ } else {
+ if((u1 & 0xFC) == 0xF8) { /* 5 Byte */
+ needed_length = 5;
+ if(u8l >= needed_length) {
+ if((u8p[1] & 0xC0) == 0x80) {
+ if((u8p[2] & 0xC0) == 0x80) {
+ if((u8p[3] & 0xC0) == 0x80) {
+ if((u8p[4] & 0xC0) == 0x80) {
+ x1 = u1;
+ x2 = u8p[1];
+ x3 = u8p[2];
+ x4 = u8p[3];
+ x5 = u8p[4];
+ x1 = x1 << 24;
+ x1 = x1 & 0x03000000UL;
+ x2 = x2 << 18;
+ x2 = x2 & 0x00FC0000UL;
+ x3 = x3 << 12;
+ x3 = x3 & 0x0003F000UL;
+ x4 = x4 << 6;
+ x4 = x4 & 0x00000FC0UL;
+ x5 = x5 & 0x0000003FUL;
+ res = (x1 | x2 | x3 | x4 | x5); back = 1;
+ }
+ }
+ }
+ }
+ }
+ } else {
+ if((u1 & 0xFE) == 0xFC) { /* 6 Byte */
+ needed_length = 6;
+ if(u8l >= needed_length) {
+ if((u8p[1] & 0xC0) == 0x80) {
+ if((u8p[2] & 0xC0) == 0x80) {
+ if((u8p[3] & 0xC0) == 0x80) {
+ if((u8p[4] & 0xC0) == 0x80) {
+ if((u8p[5] & 0xC0) == 0x80) {
+ x1 = 0x40000000UL;
+ x2 = u8p[1]; x3 = u8p[2]; x4 = u8p[3];
+ x5 = u8p[4]; x6 = u8p[5];
+ x2 = x2 << 24;
+ x3 = x3 << 18;
+ x4 = x4 << 12;
+ x5 = x5 << 6;
+ x2 = x2 & 0x3F000000UL;
+ x3 = x3 & 0x00FC0000UL;
+ x4 = x4 & 0x0003F000UL;
+ x5 = x5 & 0x00000FC0UL;
+ x6 = x6 & 0x0000003FUL;
+ res = (x1 | x2 | x3 | x4 | x5 | x6);
+ back = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } else { /* 1 Byte */
+ res = u1;
+ back = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ if(back) {
+ *u8u = needed_length;
+ *ucp = res;
+ } $? "- dk3enc_utf82uc %d", back
+ return back;
+}
+
+
+
+#if DK3_HAVE_RFC_2279
+
+/*
+ RFC 2279 allowed UTF-8 encoding for 32-bit characters in the
+ range 0 ... 0x7FFFFFFF.
+*/
+
+size_t
+dk3enc_uc2utf8(dk3_c32_t c, unsigned char *u8p, size_t u8l)
+{
+ size_t back;
+ $? "+ dk3enc_uc2utf8 (RFC 2279) 0x%lx=%lu", c, c
+ back = dk3enc_uc2utf8_rfc2279(c, u8p, u8l);
+ $? "- dk3enc_uc2utf8 (RFC 2279) %u", (unsigned)back
+ return back;
+}
+
+int
+dk3enc_utf82uc(dk3_c32_t *ucp, unsigned char const *u8p,size_t u8l,size_t *u8u)
+{
+ int back;
+ back = dk3enc_utf82uc_rfc2279(ucp, u8p, u8l, u8u);
+ return back;
+}
+
+
+#else
+
+/*
+ RFC 3629 replaces (obsoletes) RFC 2279.
+ 32-bit characters are now allowed in the range
+ 0 ... 0x0010FFFF only.
+*/
+
+size_t
+dk3enc_uc2utf8(dk3_c32_t c, unsigned char *u8p, size_t u8l)
+{
+ size_t back = 0;
+ $? "+ dk3enc_uc2utf8 (RFC 3629) %lu=0x%lx",(unsigned long)c,(unsigned long)c
+ if(c <= (dk3_c32_t)0x0010FFFFUL) {
+ back = dk3enc_uc2utf8_rfc2279(c, u8p, u8l);
+ } $? "- dk3enc_uc2utf8 (RFC 3629) %u", (unsigned)back
+ return back;
+}
+
+int
+dk3enc_utf82uc(dk3_c32_t *ucp, unsigned char const *u8p,size_t u8l,size_t *u8u)
+{
+ int back = 0;
+ back = dk3enc_utf82uc_rfc2279(ucp, u8p, u8l, u8u);
+ if(back) {
+ if((*ucp) > (dk3_c32_t)0x0010FFFFUL) {
+ back = 0;
+ }
+ }
+ return back;
+}
+
+#endif
+
+
+
+size_t
+dk3enc_uc2utf16(dk3_c32_t c, dk3_c16_t *u16p, size_t u16l)
+{
+ size_t back = 0;
+ dk3_c32_t ul = 0UL; /* Low surrogate. */
+ dk3_c32_t um = 0UL; /* Hight surrogate. */
+ if((u16p) && (u16l)) {
+ if(c >= (dk3_c32_t)0x00010000UL) {
+ if(c <= (dk3_c32_t)0x0010FFFFUL) {
+ if(u16l >= 2) {
+ ul = c - 0x00010000UL;
+ um = ((ul >> 10) & 0x000003FFUL);
+ um |= 0x0000D800UL;
+ u16p[0] = (dk3_c16_t)um;
+ um = (ul & 0x000003FFUL);
+ um |= 0x0000DC00UL;
+ u16p[1] = (dk3_c16_t)um;
+ back = 2;
+ }
+ }
+ } else {
+#if VERSION_BEFORE_20141125
+ if((c & 0x0000DC00UL) != 0x0000DC00UL) {
+ if((c & 0x0000DC00UL) != 0x0000D800UL) {
+ *u16p = (dk3_c16_t)c; back = 1;
+ }
+ }
+#else
+ if ((0x0000D800UL > c) || (0x0000DFFF < c)) {
+ *u16p = (dk3_c16_t)c; back = 1;
+ }
+#endif
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3enc_utf162uc(dk3_c32_t *ucp, dk3_c16_t const *u16p, size_t u16l, size_t *u16u)
+{
+ int back = 0;
+ dk3_c32_t result = 0UL; /* Result 32-bit character. */
+ dk3_c32_t ul1 = 0UL; /* First UC16 used. */
+ dk3_c32_t ul2 = 0UL; /* Second UC16 used (if any). */
+
+ if((ucp) && (u16p) && (u16l) && (u16u)) {
+ *u16u = 0;
+ ul1 = (((dk3_c32_t)(u16p[0])) & 0x0000FFFFUL);
+ ul2 = 0UL;
+ if(u16l > 1) {
+ ul2 = (((dk3_c32_t)(u16p[1])) & 0x0000FFFFUL);
+ }
+ if((ul1 & 0x0000DC00UL) == 0x0000DC00UL) {
+ if(u16l > 1) {
+ if((ul2 & 0x0000DC00UL) == 0x0000D800UL) {
+ ul2 = ((ul2 << 10) & 0x000FFC00UL);
+ ul1 = (ul1 & 0x000003FFUL);
+ result = ul1 | ul2;
+ result = result + 0x00010000UL;
+ *ucp = result; *u16u = 2; back = 1;
+ }
+ }
+ } else {
+ if((ul1 & 0x0000DC00UL) == 0x0000D800UL) {
+ if(u16l > 1) {
+ if((ul2 & 0x0000DC00UL) == 0x0000DC00UL) {
+ ul1 = ((ul1 << 10) & 0x000FFC00UL);
+ ul2 = (ul2 & 0x000003FFUL);
+ result = ul1 | ul2;
+ result = result + 0x00010000UL;
+ *ucp = result; *u16u = 2; back = 1;
+ }
+ }
+ } else {
+ ul1 &= 0x0000FFFFUL;
+ *ucp = ul1; *u16u = 1; back = 1;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Check whether a character is a digit.
+ @param c Character to check.
+ @return 1 on success, 0 on error.
+*/
+static int
+dk3enc_c8_is_digit(char c)
+{
+ int back = 0;
+ switch(c) {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ {
+ back = 1;
+ }
+ break;
+ }
+ return back;
+}
+
+
+
+/** Convert digit to corresponding unsigned long.
+ @param c Digit.
+ @return Unsigned long for the digit.
+*/
+static
+unsigned long
+dk3enc_c8_to_ul(char c)
+{
+ unsigned long back = 0UL;
+ if(c == '1') back = 1UL;
+ if(c == '2') back = 2UL;
+ if(c == '3') back = 3UL;
+ if(c == '4') back = 4UL;
+ if(c == '5') back = 5UL;
+ if(c == '6') back = 6UL;
+ if(c == '7') back = 7UL;
+ if(c == '8') back = 8UL;
+ if(c == '9') back = 9UL;
+ return back;
+}
+
+
+
+int
+dk3enc_ipaddr_to_ul_app(dkChar const *str, unsigned long *ul, dk3_app_t *app)
+{
+ char bu[512];
+ int back = 0;
+ $? "+ dk3enc_ipaddr_to_ul_app \"%!ds\"", TR_STR(str)
+ if((str) && (ul)) {
+ if(dk3str_string_to_c8_simple_app(bu, sizeof(bu), str, app)) { $? ". bu=\"%!8s\"", bu
+ back = dk3enc_c8_ipaddr_to_ul_app(bu, ul, app);
+ } else {
+ /* ERROR: Conversion failed! */
+ }
+ } $? "- dk3enc_ipaddr_to_ul_app %d %lx", back, ((ul) ? (*ul) : 0UL)
+ return back;
+}
+
+
+
+int
+dk3enc_c8_ipaddr_to_ul_app(char const *str, unsigned long *ul, dk3_app_t *app)
+{
+ int back = 0;
+ int state = 0; /* Current state. */
+ char const *ptr = NULL; /* Used to traverse string. */
+ unsigned long ul1 = 0UL; /* First part of IP address. */
+ unsigned long ul2 = 0UL; /* Second part of IP address. */
+ unsigned long ul3 = 0UL; /* Third part of IP address. */
+ unsigned long ulval = 0UL; /* Resulting IP address. */
+ $? "+ dk3enc_c8_ipaddr_to_ul %!8s", TR_8STR(str)
+ if(str && ul) {
+ state = 0; ptr = str; back = 1;
+ ul1 = ul2 = ul3 = ulval = 0UL;
+ while(back && (*ptr)) {
+ if(dk3enc_c8_is_digit(*ptr)) {
+ switch(state) {
+ case 0:
+ case 1:
+ case 2:
+ case 4:
+ case 5:
+ case 6:
+ case 8:
+ case 9:
+ case 10:
+ case 12:
+ case 13:
+ case 14: {
+ ulval = 10UL * ulval + dk3enc_c8_to_ul(*ptr); state++;
+ } break;
+ default: {
+ back = 0;
+ } break;
+ }
+ } else {
+ if(*ptr == '.') {
+ switch(state) {
+ case 0:
+ case 1:
+ case 2:
+ case 3: {
+ ul1 = ulval; ulval = 0UL; state = 4;
+ } break;
+ case 4:
+ case 5:
+ case 6:
+ case 7: {
+ ul2 = ulval; ulval = 0UL; state = 8;
+ } break;
+ case 8:
+ case 9:
+ case 10:
+ case 11: {
+ ul3 = ulval; ulval = 0UL; state = 12;
+ } break;
+ }
+ } else {
+ back = 0;
+ }
+ }
+ ptr++;
+ }
+ if((state < 12) || (state > 15)) {
+ back = 0;
+ }
+ if(back) {
+ if(ul1 > 255UL) back = 1;
+ if(ul2 > 255UL) back = 1;
+ if(ul3 > 255UL) back = 1;
+ if(ulval > 255UL) back = 1;
+ }
+ if(back) {
+ ul1 = ul1 << 24;
+ ul1 &= 0xFF000000UL;
+ ul2 = ul2 << 16;
+ ul2 &= 0x00FF0000UL;
+ ul3 = ul3 << 8;
+ ul3 &= 0x0000FF00UL;
+ ulval &= 0x000000FFUL;
+ ulval = ulval | ul1 | ul2 | ul3;
+ *ul = ulval;
+ } else {
+ if(app) {
+ /* Not an IP address! */
+ }
+ }
+ }
+ $? "- dk3enc_c8_ipaddr_to_ul %d %lx", back , ((ul) ? (*ul) : 0UL)
+ return back;
+}
+
+
+
+size_t
+dk3enc_size_bin_to_a85(size_t s)
+{
+#if VERSION_BEFORE_20140809
+ size_t back = 0;
+ int ec = 0; /* Error code. */
+ unsigned long ul1 = 0UL; /* Original size converted to unsigned long. */
+ unsigned long ul2 = 0UL; /* Remainder of division by 4. */
+ unsigned long ul3 = 0UL; /* Result division by 4. */
+ $? "+ dk3enc_size_bin_to_a85 %lu", (unsigned long)s
+ ul1 = (unsigned long)s;
+ ul2 = ul1 % 4UL;
+ ul3 = ul1 / 4UL;
+ if(ul2) ul2++; /* for last incomplete block */
+ ul1 = dk3ma_ul_add_ok(
+ dk3ma_ul_mul_ok(ul3, 5UL, &ec),
+ ul2,
+ &ec
+ ); /* add 25 percent */
+ ul1++; /* final 0x00 byte for string */
+ back = (size_t)ul1;
+ if(ec) back = 0; /* error checking */
+ if((unsigned long)back != ul1) back = 0;
+ $? "- dk3enc_size_bin_to_a85 %lu", (unsigned long)back
+ return back;
+#else
+ size_t back = 0;
+ size_t rem = 0; /* Division remainder */
+ size_t res = 0; /* Division result */
+ int ec = 0; /* Error code */
+ $? "+ dk3enc_size_bin_to_a85 %lu", (unsigned long)s
+ rem = s % 4;
+ res = s / 4;
+ if (rem) { rem++; }
+ /* back = 5 * res + rem + 1 */
+ rem++;
+ back = dk3mem_add_size_t(rem, dk3mem_mul_size_t(5, res, &ec), &ec);
+ if (ec) { back = 0; }
+ $? "- dk3enc_size_bin_to_a85 %lu", (unsigned long)back
+ return back;
+#endif
+}
+
+
+
+/** Convert binary data to ASCII-85 encoded string.
+ @param dp Destination pointer.
+ @param ds Destination size.
+ @param sp Source pointer.
+ @param ss Source size.
+*/
+static
+void
+dk3enc_do_bin_to_ra85(char *dp, size_t ds, char const *sp, size_t ss)
+{
+ register char const *mysp = NULL; /* Source pointer. */
+ register unsigned char *mydp = NULL; /* Destination pointer. */
+ register unsigned long v = 0UL; /* Output value. */
+ register size_t i = 0; /* Current byte index. */
+ register short vused = 0; /* Flag: v is used. */
+ $? "+ dk3enc_do_bin_to_ra85"
+ mydp = (unsigned char *)dp; mysp = sp; v = 0UL; vused = 0;
+ for(i = 0; i < ss; i++) {
+ switch(vused++) {
+ case 3: {
+ v |=
+ ((((unsigned long)((unsigned char)(*(mysp++)))) << 24) & 0xFF000000UL);
+ } break;
+ case 2: {
+ v |=
+ ((((unsigned long)((unsigned char)(*(mysp++)))) << 16) & 0x00FF0000UL);
+ } break;
+ case 1: {
+ v |=
+ ((((unsigned long)((unsigned char)(*(mysp++)))) << 8) & 0x0000FF00UL);
+ } break;
+ default: {
+ v |=
+ ((((unsigned long)((unsigned char)(*(mysp++)))) ) & dk3enc_last_byte);
+ } break;
+ }
+ if(vused >= 4) {
+ *(mydp++) = (unsigned char)((v % 85UL) + 33UL);
+ v = v / 85UL;
+ *(mydp++) = (unsigned char)((v % 85UL) + 33UL);
+ v = v / 85UL;
+ *(mydp++) = (unsigned char)((v % 85UL) + 33UL);
+ v = v / 85UL;
+ *(mydp++) = (unsigned char)((v % 85UL) + 33UL);
+ v = v / 85UL;
+ *(mydp++) = (unsigned char)((v % 85UL) + 33UL);
+ vused = 0; v = 0UL;
+ }
+ }
+ if(vused) {
+ vused++;
+ while(vused--) {
+ *(mydp++) = (unsigned char)((v % 85UL) + 33UL);
+ v = v / 85UL;
+ }
+ }
+ *mydp = '\0'; $? "- dk3enc_do_bin_to_ra85"
+}
+
+
+
+int
+dk3enc_bin_to_ra85_app(
+ char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app
+)
+{
+ int back = 0;
+ size_t needed_size = 0; /* Destination buffer minimum size. */
+ $? "+ dk3enc_bin_to_ra85 %lu %lu", (unsigned long)ds, (unsigned long)ss
+ if((dp) && (sp) && (ds) && (ss)) {
+ needed_size = dk3enc_size_bin_to_a85(ss);
+ if(needed_size) {
+ if(ds >= needed_size) {
+ dk3enc_do_bin_to_ra85(dp, ds, sp, ss);
+ back = 1;
+ } else {
+ if(app) {
+ /* Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ } $? "- dk3enc_bin_to_ra85 %d", back
+ return back;
+}
+
+
+
+size_t
+dk3enc_size_a85_to_bin(size_t s)
+{
+ size_t back = 0;
+ unsigned long ul1 = 0UL; /* Original size converted to unsigned long. */
+ unsigned long ul2 = 0UL; /* Remainder of division by 5. */
+ unsigned long ul3 = 0UL; /* Result of division by 5. */
+ $? "+ dk3enc_size_a85_to_bin %lu", (unsigned long)s
+ ul1 = (unsigned long)s;
+ ul2 = ul1 % 5UL;
+ ul3 = ul1 / 5UL;
+ ul1 = 4UL * ul3 + ul2;
+ back = (size_t)ul1;
+ $? "- dk3enc_size_a85_to_bin %lu", (unsigned long)back
+ return back;
+}
+
+
+
+/** Check whether a character is from the ASCII-85 charset.
+ @param c Character to check.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3enc_c8_is_a85(char c)
+{
+ int back = 1;
+ if((int)c < 33) {
+ back = 0;
+ } else {
+ if((int)c > 117) {
+ back = 0;
+ }
+ }
+ return back;
+}
+
+
+
+/** Convert reverse ASCII-85 encoded data to binary data.
+ @param dp Destination pointer.
+ @param ds Destination size.
+ @param sp Source pointer.
+ @param ss Source size.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Number of binary bytes produced.
+*/
+static
+size_t
+dk3enc_do_ra85_to_bin(char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app)
+{
+ size_t back = 0;
+ unsigned char *mydp = NULL; /* Destination pointer. */
+ char const *mysp = NULL; /* Source pointer. */
+ unsigned long v = 0UL; /* Double-word. */
+ short vused = 0; /* Flag: v is used. */
+ size_t i = 0; /* Index of current source byte. */
+ int reported_illegal_char = 0; /* Flag: Error already reported. */
+ $? "+ dk3enc_do_ra85_to_bin %lu %lu", (unsigned long)ds, (unsigned long)ss
+ mydp = (unsigned char *)dp; mysp = sp; v = 0UL; vused = 0;
+ for(i = 0; i < ss; i++) {
+ if(dk3enc_c8_is_a85(*mysp)) {
+ v += dk3enc_f2[vused++] * ((((unsigned long)((unsigned char)(*mysp))) & dk3enc_last_byte) - 33UL);
+ if(vused >= 5) {
+ *(mydp++) = (unsigned char)(v & dk3enc_last_byte);
+ *(mydp++) = (unsigned char)((v >> 8) & dk3enc_last_byte);
+ *(mydp++) = (unsigned char)((v >> 16) & dk3enc_last_byte);
+ *(mydp++) = (unsigned char)((v >> 24) & dk3enc_last_byte);
+ back += 4;
+ v = 0UL; vused = 0;
+ }
+ } else {
+ if(app) {
+ if(!reported_illegal_char) {
+ reported_illegal_char = 1;
+ /* Illegal character(s) in source string! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 67);
+ }
+ }
+ }
+ mysp++;
+ }
+ if(vused) {
+ vused--;
+ while(vused--) {
+ *(mydp++) = (unsigned char)(v & dk3enc_last_byte);
+ back++;
+ v = v >> 8;
+ }
+ } $? "- dk3enc_do_ra85_to_bin %lu", (unsigned long)back
+ return back;
+}
+
+
+
+size_t
+dk3enc_ra85_to_bin_app(
+ char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app
+)
+{
+ size_t back = 0;
+ size_t needed_size = 0; /* Minimum output buffer size. */
+ $? "+ dk3enc_ra85_to_bin %lu %lu", (unsigned long)ds, (unsigned long)ss
+ if((dp) && (sp) && (ds) && (ss)) {
+ needed_size = dk3enc_size_a85_to_bin(ss);
+ if(needed_size) {
+ if(ds >= needed_size) {
+ back = dk3enc_do_ra85_to_bin(dp, ds, sp, ss, app);
+ } else {
+ if(app) {
+ /* Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ } $? "- dk3enc_ra85_to_bin %lu", (unsigned long)back
+ return back;
+}
+
+
+
+size_t
+dk3enc_ra85string_to_bin_app(
+ char *dp, size_t ds, char const *sp, dk3_app_t *app
+)
+{
+ size_t back = 0;
+ $? "+ dk3enc_ra85string_to_bin %lu %!8s", (unsigned long)ds, TR_8STR(sp)
+ if(sp) {
+ back = dk3enc_ra85_to_bin_app(dp, ds, sp, dk3str_c8_len(sp), app);
+ }
+ return back;
+}
+
+
+
+/** Convert binary data to ASCII-85 string.
+ @param dp Destination pointer.
+ @param ds Destination size.
+ @param sp Source pointer.
+ @param ss Source size.
+*/
+static
+void
+dk3enc_do_bin_to_a85(char *dp, size_t ds, char const *sp, size_t ss)
+{
+ register unsigned char *mydp = NULL; /* Destination pointer. */
+ register unsigned char *mysp = NULL; /* Source pointer. */
+ register unsigned long v = 0UL; /* Double-word. */
+ register short vused = 0; /* Flag: v used. */
+ register short addval = 0; /* Value to add. */
+ register size_t i = 0; /* Index of current source byte. */
+ $? "+ dk3enc_do_bin_to_a85 %lu %lu", (unsigned long)ds, (unsigned long)ss
+ mydp = (unsigned char *)dp;
+ mysp = (unsigned char *)sp;
+ v = 0UL;
+ vused = 0;
+ for(i = 0; i < ss; i++) {
+ switch(vused) {
+ case 3: {
+ v |= ( ((unsigned long)(*(mysp++))) & 0x000000FFUL);
+ } break;
+ case 2: {
+ v |= ((((unsigned long)(*(mysp++))) << 8) & 0x0000FF00UL);
+ } break;
+ case 1: {
+ v |= ((((unsigned long)(*(mysp++))) << 16) & 0x00FF0000UL);
+ } break;
+ default: {
+ v |= ((((unsigned long)(*(mysp++))) << 24) & 0xFF000000UL);
+ } break;
+ }
+ if(++vused >= 4) {
+ vused = 5;
+ while(vused--) {
+ *(mydp++) = (unsigned char)(33UL + v / dk3enc_f2[vused]);
+ v = v % dk3enc_f2[vused];
+ }
+ v = 0UL; vused = 0;
+ }
+ }
+ if(vused) {
+ vused++; addval = 5 - vused;
+ while(vused--) {
+ *(mydp++) = (unsigned char)(33UL + v / dk3enc_f2[vused + addval]);
+ v = v % dk3enc_f2[vused + addval];
+ }
+ }
+ *mydp = '\0'; $? "- dk3enc_do_bin_to_a85"
+}
+
+
+
+int
+dk3enc_bin_to_a85_app(
+ char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app
+)
+{
+ int back = 0;
+ size_t needed_size = 0; /* Minimum output buffer size. */
+ $? "+ dk3enc_bin_to_a85 %lu %lu", (unsigned long)ds, (unsigned long)ss
+ if((dp) && (sp) && (ds) && (ss)) {
+ needed_size = dk3enc_size_bin_to_a85(ss);
+ if(needed_size) {
+ if(ds >= needed_size) {
+ dk3enc_do_bin_to_a85(dp, ds, sp, ss);
+ back = 1;
+ } else {
+ if(app) {
+ /* Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ } $? "- dk3enc_bin_to_a85 %d", back
+ return back;
+}
+
+
+
+/** Convert ASCII-85 encoded data to binary data.
+ @param dp Destination pointer.
+ @param ds Destination size.
+ @param sp Source pointer.
+ @param ss Source size.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Number of binary bytes produced.
+*/
+static
+size_t
+dk3enc_do_a85_to_bin(char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app)
+{
+ register size_t back = 0;
+ register unsigned char *mydp = NULL; /* Destination pointer. */
+ register unsigned char const *mysp = NULL; /* Source pointer. */
+ register unsigned long v = 0UL; /* Double-word. */
+ register short vused = 0; /* Flag: v used. */
+ register size_t i = 0; /* Current source byte index. */
+ unsigned long u1 = 0UL; /* Temporary value. */
+ unsigned long u2 = 0UL; /* Temporary value. */
+ unsigned long u3 = 0UL; /* Temporary value. */
+ int reported_illegal_character = 0;
+ $? "+ dk3enc_do_a85_to_bin %lu %lu", (unsigned long)ds, (unsigned long)ss
+ mydp = (unsigned char *)dp; mysp = (unsigned char *)sp;
+ v = 0UL; vused = 0;
+ for(i = 0; i < ss; i++) {
+ if(*mysp) {
+ if(dk3enc_c8_is_a85(*mysp)) {
+ v += dk3enc_f2[4 - vused] *
+ ((((unsigned long)(*mysp)) & 0x000000FFUL) - 33UL);
+ } else {
+ if(!reported_illegal_character) {
+ reported_illegal_character = 1;
+ if(app) {
+ /* Illegal character in source data! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 67);
+ }
+ }
+ }
+ vused++;
+ if(vused >= 5) {
+ *(mydp++) = (unsigned char)((v >> 24) & 0x000000FFUL); back++;
+ *(mydp++) = (unsigned char)((v >> 16) & 0x000000FFUL); back++;
+ *(mydp++) = (unsigned char)((v >> 8) & 0x000000FFUL); back++;
+ *(mydp++) = (unsigned char)( v & 0x000000FFUL); back++;
+ v = 0UL; vused = 0;
+ }
+ }
+ mysp++;
+ }
+ if(vused) {
+ u1 = (v >> 24) & 0x000000FFUL;
+ u2 = (v >> 16) & 0x000000FFUL;
+ u3 = (v >> 8) & 0x000000FFUL;
+ switch(vused) {
+ case 2: {
+ if(v & 0x00FFFFFFUL) {
+ u1++; if(u1 >= 256UL) u1 = 0UL;
+ }
+ *(mydp++) = (unsigned char)(u1 & 0x000000FFUL); back++;
+ } break;
+ case 3: {
+ if(v & 0x0000FFFFUL) {
+ u2++;
+ if(u2 >= 256UL) {
+ u2 = 0UL;
+ u1++; if(u1 >= 256UL) u1 = 0UL;
+ }
+ }
+ *(mydp++) = (unsigned char)(u1 & 0x000000FFUL); back++;
+ *(mydp++) = (unsigned char)(u2 & 0x000000FFUL); back++;
+ } break;
+ case 4: {
+ if(v & 0x000000FFUL) {
+ u3++;
+ if(u3 >= 256UL) {
+ u3 = 0UL;
+ u2++;
+ if(u2 >= 256UL) {
+ u2 = 0UL;
+ u1++; if(u1 >= 256UL) u1 = 0UL;
+ }
+ }
+ }
+ *(mydp++) = (unsigned char)(u1 & 0x000000FFUL); back++;
+ *(mydp++) = (unsigned char)(u2 & 0x000000FFUL); back++;
+ *(mydp++) = (unsigned char)(u3 & 0x000000FFUL); back++;
+ } break;
+ }
+ } $? "- dk3enc_do_a85_to_bin %lu", (unsigned long)back
+ return back;
+}
+
+
+
+size_t
+dk3enc_a85_to_bin_app(
+ char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app
+)
+{
+ size_t back = 0;
+ size_t needed_size = 0; /* Minimum output buffer size. */
+ $? "+ dk3enc_a85_to_bin %lu %lu", (unsigned long)ds, (unsigned long)ss
+ if((dp) && (sp) && (ds) && (ss)) {
+ needed_size = dk3enc_size_a85_to_bin(ss);
+ if(needed_size) {
+ if(ds >= needed_size) {
+ back = dk3enc_do_a85_to_bin(dp, ds, sp, ss, app);
+ } else {
+ if(app) {
+ /* Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ } $? "- dk3enc_a85_to_bin %lu", (unsigned long)back
+ return back;
+}
+
+
+
+size_t
+dk3enc_a85string_to_bin_app(char *dp, size_t ds, char const *sp, dk3_app_t *app)
+{
+ size_t back = 0;
+ $? "+ dk3enc_a85string_to_bin %lu %!8s", (unsigned long)ds, TR_8STR(sp)
+ if(sp) {
+ back = dk3enc_a85_to_bin_app(dp, ds, sp, dk3str_c8_len(sp), app);
+ } $? "- dk3enc_a85string_to_bin %lu", (unsigned long)back
+ return back;
+}
+
+
+
+size_t
+dk3enc_size_bin_to_hex(size_t s)
+{
+#if VERSION_BEFORE_20140809
+ size_t back = 0;
+ int ec = 0; /* Error code. */
+ unsigned long ul1 = 0UL; /* Temporary value for calculation. */
+ $? "+ dk3enc_size_bin_to_hex %lu", (unsigned long)s
+ ul1 = (unsigned long)s;
+ ul1 = dk3ma_ul_mul_ok(ul1, 2UL, &ec);
+ ul1 = dk3ma_ul_add_ok(ul1, 1UL, &ec);
+ back = (size_t)ul1;
+ if(ec) back = 0;
+ if((unsigned long)back != ul1) back = 0;
+ $? "- dk3enc_size_bin_to_hex %lu", (unsigned long)back
+ return back;
+#else
+ size_t back = 0;
+ int ec = 0; /* Error code */
+ $? "+ dk3enc_size_bin_to_hex %lu", (unsigned long)s
+ back = dk3mem_add_size_t(1, dk3mem_mul_size_t(2, s, &ec), &ec);
+ if (ec) { back = 0; }
+ $? "- dk3enc_size_bin_to_hex %lu", (unsigned long)back
+ return back;
+#endif
+}
+
+
+
+size_t
+dk3enc_size_hex_to_bin(size_t s)
+{
+ size_t back;
+ $? "+ dk3enc_size_hex_to_bin %lu", (unsigned long)s
+ back = s / 2;
+ back++; $? "- dk3enc_size_hex_to_bin %lu", (unsigned long)back
+ return back;
+}
+
+
+
+/** Get higher half-byte from character.
+ @param c Source character.
+ @return Higher half-byte of \a c.
+*/
+static
+char
+dk3enc_c8_high_nibble_hex(char c)
+{
+ char back;
+ back = dk3enc_hex_digits[ (((unsigned short)c) >> 4) & 0x000FU ];
+ return back;
+}
+
+
+
+/** Get lower half-byte from character.
+ @param c Source character.
+ @return Lower half-byte of \a c.
+*/
+static
+char
+dk3enc_c8_low_nibble_hex(char c)
+{
+ char back;
+ back = dk3enc_hex_digits[ ((unsigned short)c) & 0x000FU ];
+ return back;
+}
+
+
+
+/** Convert binary data to hexadecimal string.
+ @param dp Destination pointer.
+ @param ds Destination size.
+ @param sp Source pointer.
+ @param ss Source size.
+ @param app Application structure for diagnostics, may be NULL.
+*/
+static
+void
+dk3enc_do_bin_to_hex(char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app)
+{
+ register char *mydp = NULL; /* Destination pointer. */
+ register char const *mysp = NULL; /* Source pointer. */
+ register size_t i = 0; /* Current source byte index. */
+ $? "+ dk3enc_do_bin_to_hex %lu %lu", (unsigned long)ds, (unsigned long)ss
+ mydp = dp; mysp = sp;
+ for(i = 0; i < ss; i++) {
+ *(mydp++) = dk3enc_c8_high_nibble_hex(*mysp);
+ *(mydp++) = dk3enc_c8_low_nibble_hex(*(mysp++));
+ }
+ *mydp = '\0'; $? "- dk3enc_do_bin_to_hex"
+}
+
+
+
+int
+dk3enc_bin_to_hex_app(
+ char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app
+)
+{
+ int back = 0;
+ size_t needed_bytes = 0; /* Minimum output buffer size. */
+ $? "+ dk3enc_bin_to_hex %lu %lu", (unsigned long)ds, (unsigned long)ss
+ if((dp) && (ds) && (sp) && (ss)) {
+ needed_bytes = dk3enc_size_bin_to_hex(ss);
+ if(needed_bytes) {
+ if(ds >= needed_bytes) {
+ dk3enc_do_bin_to_hex(dp, ds, sp, ss, app); back = 1;
+ } else {
+ if(app) {
+ /* Destination buffer too small1 */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ } $? "- dk3enc_bin_to_hex %d", back
+ return back;
+}
+
+
+
+/** Convert hexadecimal data to binary data.
+ @param dp Destination pointer.
+ @param ds Destination size.
+ @param sp Source pointer.
+ @param ss Source size.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Number of bytes created in destination.
+*/
+static
+size_t
+dk3enc_do_hex_to_bin(char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app)
+{
+ register size_t back = 0;
+ register char const *mysp = NULL; /* Source pointer. */
+ register unsigned char *mydp = NULL; /* Destination pointer. */
+ register unsigned char v = 0x00; /* Current byte to process. */
+ register short int vused = 0; /* Flag: v used. */
+ register size_t i = 0; /* Current source byte index. */
+ int reported_illegal_character = 0; /* Flag: Error already reported. */
+ $? "+ dk3enc_do_hex_to_bin %lu %lu", (unsigned long)ds, (unsigned long)ss
+ mydp = (unsigned char *)dp;
+ mysp = sp; v = 0x00; vused = 0U;
+ for(i = 0; i < ss; i++) {
+ switch(*mysp) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case 'a':
+ case 'A':
+ case 'b':
+ case 'B':
+ case 'c':
+ case 'C':
+ case 'd':
+ case 'D':
+ case 'e':
+ case 'E':
+ case 'f':
+ case 'F':
+ {
+ if(vused) {
+ switch(*mysp) {
+ case '0': { v |= 0x00; } break;
+ case '1': { v |= 0x01; } break;
+ case '2': { v |= 0x02; } break;
+ case '3': { v |= 0x03; } break;
+ case '4': { v |= 0x04; } break;
+ case '5': { v |= 0x05; } break;
+ case '6': { v |= 0x06; } break;
+ case '7': { v |= 0x07; } break;
+ case '8': { v |= 0x08; } break;
+ case '9': { v |= 0x09; } break;
+ case 'a': { v |= 0x0A; } break;
+ case 'A': { v |= 0x0A; } break;
+ case 'b': { v |= 0x0B; } break;
+ case 'B': { v |= 0x0B; } break;
+ case 'c': { v |= 0x0C; } break;
+ case 'C': { v |= 0x0C; } break;
+ case 'd': { v |= 0x0D; } break;
+ case 'D': { v |= 0x0D; } break;
+ case 'e': { v |= 0x0E; } break;
+ case 'E': { v |= 0x0E; } break;
+ case 'f': { v |= 0x0F; } break;
+ case 'F': { v |= 0x0F; } break;
+ }
+ *(mydp++) = v; back++; v = 0; vused = 0U;
+ } else {
+ switch(*mysp) {
+ case '0': { v = 0x00; } break;
+ case '1': { v = 0x10; } break;
+ case '2': { v = 0x20; } break;
+ case '3': { v = 0x30; } break;
+ case '4': { v = 0x40; } break;
+ case '5': { v = 0x50; } break;
+ case '6': { v = 0x60; } break;
+ case '7': { v = 0x70; } break;
+ case '8': { v = 0x80; } break;
+ case '9': { v = 0x90; } break;
+ case 'a': { v = 0xA0; } break;
+ case 'A': { v = 0xA0; } break;
+ case 'b': { v = 0xB0; } break;
+ case 'B': { v = 0xB0; } break;
+ case 'c': { v = 0xC0; } break;
+ case 'C': { v = 0xC0; } break;
+ case 'd': { v = 0xD0; } break;
+ case 'D': { v = 0xD0; } break;
+ case 'e': { v = 0xE0; } break;
+ case 'E': { v = 0xE0; } break;
+ case 'f': { v = 0xF0; } break;
+ case 'F': { v = 0xF0; } break;
+ }
+ vused = 1U;
+ }
+ } break;
+ default: {
+ if(!reported_illegal_character) {
+ reported_illegal_character = 1;
+ if(app) {
+ /* Illegal character(s) in source! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 67);
+ }
+ }
+ } break;
+ }
+ mysp++;
+ }
+ if(vused) {
+ *mydp = v; back++;
+ } $? "- dk3enc_do_hex_to_bin %lu", (unsigned long)back
+ return back;
+}
+
+
+
+size_t
+dk3enc_hex_to_bin_app(
+ char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app
+)
+{
+ size_t back = 0;
+ size_t needed_bytes = 0; /* Minimum output buffer size. */
+ $? "+ dk3enc_hex_to_bin %lu %lu", (unsigned long)ds, (unsigned long)ss
+ if((dp) && (ds) && (sp) && (ss)) {
+ needed_bytes = dk3enc_size_hex_to_bin(ss);
+ if(needed_bytes) {
+ if(ds >= needed_bytes) {
+ back = dk3enc_do_hex_to_bin(dp, ds, sp, ss, app);
+ } else {
+ if(app) {
+ /* Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ } $? "- dk3enc_hex_to_bin %lu", (unsigned long)back
+ return back;
+}
+
+
+
+size_t
+dk3enc_hexstring_to_bin_app(
+ char *dp, size_t ds, char const *sp, dk3_app_t *app
+)
+{
+ size_t back = 0;
+ $? "+ dk3enc_hexstring_to_bin %lu %!8s", (unsigned long)ds, TR_8STR(sp)
+ if(sp) {
+ back = dk3enc_hex_to_bin_app(dp, ds, sp, dk3str_c8_len(sp), app);
+ } $? "- dk3enc_hexstring_to_bin %lu", (unsigned long)back
+ return back;
+}
+
+
+
+size_t
+dk3enc_size_hexstring_to_bin(char const *s)
+{
+ size_t back = 0;
+ $? "+ dk3enc_size_hexstring_to_bin %!8s", TR_8STR(s)
+ if(s) {
+ back = dk3str_c8_len(s);
+ back = dk3enc_size_hex_to_bin(back);
+ } $? "- dk3enc_size_hexstring_to_bin %lu", (unsigned long)back
+ return back;
+}
+
+
+
+size_t
+dk3enc_size_a85string_to_bin(char const *s)
+{
+ size_t back = 0;
+ $? "+ dk3enc_size_a85string_to_bin %!8s", TR_8STR(s)
+ if(s) {
+ back = dk3str_c8_len(s);
+ back = dk3enc_size_a85_to_bin(back);
+ } $? "- dk3enc_size_a85string_to_bin %lu", (unsigned long)back
+ return back;
+}
+
+
+
+int
+dk3enc_get_type_app(dkChar const *n, dk3_app_t *app)
+{
+ int back = -1;
+ if(n) {
+ back = dk3str_array_index(dk3enc_data_encoding_names, n, 0);
+ if(back >= 0) {
+ switch(back) {
+ case 0: case 3: {
+ back = DK3_DATA_ENCODING_HEX;
+ } break;
+ case 1: case 4: case 6: {
+ back = DK3_DATA_ENCODING_ASCII85;
+ } break;
+ case 2: case 5: case 7: {
+ back = DK3_DATA_ENCODING_REVERSE_ASCII85;
+ } break;
+ }
+ } else {
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 129, 130, n);
+ }
+ }
+ }
+ return back;
+}
+
+
+dkChar const *
+dk3enc_get_data_encoding_name(int t)
+{
+ dkChar const *back = NULL;
+ if((t >= 0) && (t <= 2)) {
+ back = dk3enc_data_encoding_names[t];
+ }
+ return back;
+}
+
+
+
+int
+dk3enc_get_text_encoding_app(dkChar const *en, dk3_app_t *app)
+{
+ int back = -1;
+ int i;
+ $? "+ dk3enc_get_text_encoding_app \"%!ds\"", TR_STR(en)
+ if(app) { back = dk3app_get_output_encoding(app); }
+ if(en) {
+ i = dk3str_array_index(dk3enc_text_encoding_names, en, 0); $? ". i=%d", i
+ switch(i) {
+ case 0: case 8: case 9: {
+ back = DK3_FILE_ENCODING_ASCII;
+ } break;
+ case 1: case 10: {
+ back = DK3_FILE_ENCODING_UTF8;
+ } break;
+ case 2: case 11: {
+#if DK3_HAVE_BIGENDIAN
+ back = DK3_FILE_ENCODING_UTF16_MSB_FIRST;
+#else
+ back = DK3_FILE_ENCODING_UTF16_LSB_FIRST;
+#endif
+ } break;
+ case 3: case 18: case 19: case 20: case 21: case 22: case 23: {
+ back = DK3_FILE_ENCODING_UTF16_MSB_FIRST;
+ } break;
+ case 4: case 12: case 13: case 14: case 15: case 16: case 17: {
+ back = DK3_FILE_ENCODING_UTF16_LSB_FIRST;
+ } break;
+ case 5: case 24: {
+#if DK3_HAVE_BIGENDIAN
+ back = DK3_FILE_ENCODING_UNICODE_MSB_FIRST;
+#else
+ back = DK3_FILE_ENCODING_UNICODE_LSB_FIRST;
+#endif
+ } break;
+ case 6: case 29: case 30: case 31: case 32: {
+ back = DK3_FILE_ENCODING_UNICODE_MSB_FIRST;
+ } break;
+ case 7: case 25: case 26: case 27: case 28: {
+ back = DK3_FILE_ENCODING_UNICODE_LSB_FIRST;
+ } break;
+ default: {
+ if(app) {
+ /* ERROR: Unknown text encoding name! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 129, 130, en);
+ }
+ } break;
+ }
+ } $? "- dk3enc_get_text_encoding_app %d", back
+ return back;
+}
+
+
+
+int
+dk3enc_get_encoding(dk3_app_t *app)
+{
+ int back = 0;
+#if DK3_CHAR_SIZE == 1
+ char *ptr;
+#endif
+ if(app) {
+ back = dk3app_get_encoding(app);
+ } else {
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ back = DK3_ENCODING_UNICODE;
+#else
+ back = DK3_ENCODING_UTF16;
+#endif
+#else
+ back = DK3_ENCODING_PLAIN;
+ ptr = getenv("LANG");
+ if(ptr) {
+ ptr = dk3str_c8_chr(ptr, '.');
+ if(ptr) {
+ ptr++;
+ switch(dk3str_c8_array_index(dk3enc_utf8_names, ptr, 0)) {
+ case 0: case 1: {
+ back = DK3_ENCODING_UTF8;
+ } break;
+ }
+ }
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dk3enc.h b/support/dktools/dk3enc.h
new file mode 100644
index 0000000000..14aa7514cf
--- /dev/null
+++ b/support/dktools/dk3enc.h
@@ -0,0 +1,347 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3enc.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3enc.h Header file for the dk3enc module.
+*/
+
+#ifndef DK3ENC_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3ENC_H_INCLUDED 1
+
+
+#line 10 "dk3enc.ctr"
+
+#include "dk3conf.h"
+#include "dk3types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert long number from net to host representation.
+ @param x Number to convert.
+ @return Conversion result.
+*/
+unsigned long
+dk3enc_ntohl(unsigned long x);
+
+/** Convert long number from host to net representation.
+ @param x Number to convert.
+ @return Conversion result.
+*/
+unsigned long
+dk3enc_htonl(unsigned long x);
+
+/** Convert short number from net to host representation.
+ @param x Number to convert.
+ @return Conversion result.
+*/
+unsigned short
+dk3enc_ntohs(unsigned short x);
+
+/** Convert short number from host to net representation.
+ @param x Number to convert.
+ @return Conversion result.
+*/
+unsigned short
+dk3enc_htons(unsigned short x);
+
+/** Convert 32-bit character to UTF-8.
+ @param c 32-bit character to convert.
+ @param u8p Pointer to result buffer.
+ @param u8l Size of result buffer, should be 8 at least.
+ @return Number of bytes used in result buffer.
+*/
+size_t
+dk3enc_uc2utf8(dk3_c32_t c, unsigned char *u8p, size_t u8l);
+
+/** Convert UTF-8 encoded text to 32-bit character.
+ @param ucp Pointer to variable for result.
+ @param u8p Buffer containing UTF-8 encoded text.
+ @param u8l Number of bytes in buffer.
+ @param u8u Pointer to variable to receive number of bytes used.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3enc_utf82uc(dk3_c32_t *ucp, unsigned char const *u8p,size_t u8l,size_t *u8u);
+
+/** Convert IP address from 8-bit text string to long number
+ in host representation.
+ @param str Text string containing the IP address.
+ @param ul Pointer to result variable.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3enc_c8_ipaddr_to_ul_app(char const *str, unsigned long *ul, dk3_app_t *app);
+
+/** Convert IP address from string to long number
+ in host representation.
+ @param str Text string containing the IP address.
+ @param ul Pointer to result variable.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3enc_ipaddr_to_ul_app(dkChar const *str, unsigned long *ul, dk3_app_t *app);
+
+/** Find size for result buffer needed to convert binary data to
+ text using ASCII-85 encoding.
+ @param s Size of binary data.
+ @return The required buffer length (includeing finalizing 0x00 byte).
+*/
+size_t
+dk3enc_size_bin_to_a85(size_t s);
+
+/** Convert binary data to text using reverse ASCII-85 encoding.
+ @param dp Destination buffer pointer.
+ @param ds Size of \a dp.
+ @param sp Binary (source) data.
+ @param ss Number of bytes in \a sp.
+ @param app Application structure, for diagnostics, may be NULL.
+*/
+int
+dk3enc_bin_to_ra85_app(
+ char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app
+);
+
+/** Find size for result buffer needed to convert ASCII-85 encoded
+ data back to binary data.
+ @param s Number of ASCII-85 text characters.
+ @return Length of resulting binary data.
+*/
+size_t
+dk3enc_size_a85_to_bin(size_t s);
+
+/** Convert reverse ASCII-85 encoded data back to binary.
+ @param dp Destination buffer pointer.
+ @param ds Destination buffer size in bytes.
+ @param sp Source buffer pointer.
+ @param ss Source buffer length.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Number of binary bytes decoded.
+*/
+size_t
+dk3enc_ra85_to_bin_app(
+ char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app
+);
+
+#if 0
+/** Convert reverse ASCII-85 encoded data back to binary.
+ @param dp Destination buffer pointer.
+ @param ds Destination buffer size in bytes.
+ @param sp Source buffer pointer.
+ @param ss Source buffer length.
+ @return Number of binary bytes decoded.
+*/
+size_t
+dk3enc_ra85_to_bin(char *dp, size_t ds, char const *sp, size_t ss);
+#endif
+
+/** Convert reverse ASCII-85 encoded data string back to binary.
+ @param dp Destination buffer pointer.
+ @param ds Destination buffer size in bytes.
+ @param sp Source buffer pointer.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Number of binary bytes decoded.
+*/
+size_t
+dk3enc_ra85string_to_bin_app(
+ char *dp, size_t ds, char const *sp, dk3_app_t *app
+);
+
+/** Apply ASCII-85 encoding to binary data.
+ @param dp Destination buffer pointer.
+ @param ds Destination buffer size.
+ @param sp Source buffer pointer.
+ @param ss Source buffer size.
+ @param app Application structure for diagnostics, may be NULL.
+*/
+int
+dk3enc_bin_to_a85_app(
+ char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app
+);
+
+/** Decode ASCII-85 encoded data back to binary.
+ @param dp Destination buffer pointer.
+ @param ds Destination buffer size.
+ @param sp Source buffer pointer.
+ @param ss Source buffer size.
+ @param app Application structure for diagnostics, may be NULL.
+*/
+size_t
+dk3enc_a85_to_bin_app(
+ char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app
+);
+
+/** Decode ASCII-85 encoded data string back to binary.
+ @param dp Destination buffer pointer.
+ @param ds Destination buffer size.
+ @param sp Source buffer pointer.
+ @param app Application structure for diagnostics, may be NULL.
+*/
+size_t
+dk3enc_a85string_to_bin_app(char *dp, size_t ds, char const *sp, dk3_app_t *app);
+
+/** Calculate size for binary to hexadecimal conversion.
+ @param s Size of binary data.
+ @return Size of hexadecimal encoding.
+*/
+size_t
+dk3enc_size_bin_to_hex(size_t s);
+
+/** Calculate size for hexadecimal to binary conversion.
+ @param s Size of hexadecimal data.
+ @return Size of binary data.
+*/
+size_t
+dk3enc_size_hex_to_bin(size_t s);
+
+/** Apply hexadecimal encoding to binary data.
+ @param dp Destination buffer pointer.
+ @param ds Destination buffer size.
+ @param sp Source buffer pointer.
+ @param ss Source buffer size.
+ @param app Application structure for diagnostics, may be NULL.
+*/
+int
+dk3enc_bin_to_hex_app(
+ char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app
+);
+
+/** Convert hexadecimal encoded data back to binary.
+ @param dp Destination buffer pointer.
+ @param ds Destination buffer size.
+ @param sp Source buffer pointer.
+ @param ss Source buffer size.
+ @param app Application structure for diagnostics, may be NULL.
+*/
+size_t
+dk3enc_hex_to_bin_app(
+ char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app
+);
+
+/** Convert hexadecimal encoded data string back to binary.
+ @param dp Destination buffer pointer.
+ @param ds Destination buffer size.
+ @param sp Source buffer pointer.
+ @param app Application structure for diagnostics, may be NULL.
+*/
+size_t
+dk3enc_hexstring_to_bin_app(
+ char *dp, size_t ds, char const *sp, dk3_app_t *app
+);
+
+/** Calculate size for hex decoding to binary.
+ @param s String containing hexadecimal data.
+ @return Size of binary data.
+*/
+size_t
+dk3enc_size_hexstring_to_bin(char const *s);
+
+/** Find size for conversion from ASCII-85 encoded data to binary.
+ * @param s ASCII-85 encoded string.
+ * @return Size of binary data.
+ */
+size_t
+dk3enc_size_a85string_to_bin(char const *s);
+
+/** Convert 32-bit character to UTF-16.
+ If the value is 0xFFFF and below, the 16 bits are used ``as is''.
+ For values \a c > 0xFFFF we have to build a surrogate pair.
+ We substract 0x00010000, the result is a new character with
+ 20 significant bits. These 20 bits are splitted into two blocks of
+ 10 bits each. The high surrogate is built using the prefix
+ bits 110110 and the higher 10-bits block. The low surrogate is built
+ using the prefix bits 110111 and the lower 10-bits block.
+ Order of surrogates in a surrogate pair is flexible, this function
+ writes the high surrogate first.
+ @param c The 32-bit character.
+ @param u16p Buffer to receive UTF-16 encoded result.
+ @param u16l Length of \a u16l in elements.
+ @return The number of dk3_c16_t characters produced.
+*/
+size_t
+dk3enc_uc2utf16(dk3_c32_t c, dk3_c16_t *u16p, size_t u16l);
+
+/** Convert UTF-16 encoded characters to 32-bit character
+ @param ucp Pointer to result variable.
+ @param u16p Buffer containing UTF-16 encoded text.
+ @param u16l Number of elements available in \a u16p.
+ @param u16u Pointer to variable to receive number of dk3_c16_t used.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3enc_utf162uc(dk3_c32_t *ucp, dk3_c16_t const *u16p, size_t u16l, size_t *u16u);
+
+/** Get data encoding type for name.
+ @param n Data encoding name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Integer representation of data encoding on success, -1 on error.
+*/
+int
+dk3enc_get_type_app(dkChar const *n, dk3_app_t *app);
+
+/** Get name for data encoding type.
+ @param t Numeric type.
+ @return Name for type on success, NULL on error.
+*/
+dkChar const *
+dk3enc_get_data_encoding_name(int t);
+
+/** Get numeric value for text encoding.
+ @param en Encoding name.
+ @param app Application structure, may be NULL.
+ @return Numeric representation of text encoding on success,
+ -1 on error.
+*/
+int
+dk3enc_get_text_encoding_app(dkChar const *en, dk3_app_t *app);
+
+/** Get the used encoding.
+ @param app Application structure, may be NULL.
+ @return The encoding used for characters in memory.
+*/
+int
+dk3enc_get_encoding(dk3_app_t *app);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3fig.c b/support/dktools/dk3fig.c
new file mode 100644
index 0000000000..e6d57cc080
--- /dev/null
+++ b/support/dktools/dk3fig.c
@@ -0,0 +1,1456 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3fig.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3fig.c The dk3fig module.
+*/
+
+
+#line 1110 "dk3fig.ctr"
+
+
+#include "dk3all.h"
+#include "dk3fig.h"
+
+
+
+
+#line 1117 "dk3fig.ctr"
+
+
+
+/** Localized message texts.
+*/
+static dkChar const * const dk3fig_messages[] = {
+/* 0 */
+dkT("dk3fig.str"),
+
+/* 1 */
+dkT("Syntax error in Fig input!"),
+
+/* 2 */
+dkT("Color redefined!"),
+
+/* 3 */
+dkT("Mathematical problem in arc calculation!"),
+
+/* 4 */
+dkT("Object processing failed!"),
+
+/* 5 */
+dkT("Arrowhead calculation failed!"),
+
+/* 6 */
+dkT("Error while reading input file!"),
+
+/* 7 */
+dkT("Color not found, using black as default color!"),
+
+/* 8 */
+dkT("Unknown object type!"),
+
+/* 9 */
+dkT("Can not fill open graphics path!"),
+
+/* 10 */
+dkT("Converted to closed graphics path for filling."),
+
+NULL
+
+
+#line 1169 "dk3fig.ctr"
+};
+
+
+
+
+dkChar const * const *
+dk3fig_get_localized_messages(dk3_app_t *app)
+{
+ dkChar const * const *back = NULL;
+ if(app) {
+ back = dk3app_messages(
+ app, dk3fig_messages[0], (dkChar const **)dk3fig_messages
+ );
+ }
+ return back;
+}
+
+
+
+/** Compare two text objects.
+ This function is used to sort text objects.
+ @param pl Left text object.
+ @param pr Right text object.
+ @return Comparison result.
+*/
+static
+int
+dk3fig_obj_text_compare(dk3_fig_obj_t const *pl, dk3_fig_obj_t const *pr)
+{
+ int back = 0;
+ /*
+ Non-special texts before special texts.
+ */
+ if(((pl->dt).txt.ff) & DK3_FIG_FONT_FLAG_SPECIAL) {
+ if(!(((pr->dt).txt.ff) & DK3_FIG_FONT_FLAG_SPECIAL)) {
+ back = 1;
+ }
+ } else {
+ if(((pr->dt).txt.ff) & DK3_FIG_FONT_FLAG_SPECIAL) {
+ back = -1;
+ }
+ }
+ /*
+ Font selection type.
+ */
+ if(0 == back) {
+ if(((pl->dt).txt.ff) & DK3_FIG_FONT_FLAG_PS) {
+ if(!(((pr->dt).txt.ff) & DK3_FIG_FONT_FLAG_PS)) {
+ back = 1;
+ }
+ } else {
+ if(((pr->dt).txt.ff) & DK3_FIG_FONT_FLAG_PS) {
+ back = -1;
+ }
+ }
+ }
+ /*
+ Font number.
+ */
+ if(0 == back) {
+ if((pl->dt).txt.fo > (pr->dt).txt.fo) {
+ back = 1;
+ } else {
+ if((pl->dt).txt.fo < (pr->dt).txt.fo) {
+ back = -1;
+ }
+ }
+ }
+ /*
+ Font size.
+ */
+ if(0 == back) {
+ if((pl->dt).txt.fs > (pr->dt).txt.fs) {
+ back = 1;
+ } else {
+ if((pl->dt).txt.fs < (pr->dt).txt.fs) {
+ back = -1;
+ }
+ }
+ }
+ /*
+ Text string.
+ */
+ if(0 == back) {
+ back = dk3str_c8_cmp((pl->dt).txt.st, (pr->dt).txt.st);
+ if(back < -1) back = -1;
+ if(back > 1) back = 1;
+ }
+ return back;
+}
+
+
+
+/** Compare two non-text objects.
+ @param pl Left object.
+ @param pr Right object.
+ @return Comparison result.
+*/
+static
+int
+dk3fig_obj_path_compare(dk3_fig_obj_t const *pl, dk3_fig_obj_t const *pr)
+{
+ int back = 0;
+ /*
+ Line width.
+ */
+ if(0 == back) {
+ if(pl->lw > pr->lw) { back = 1; }
+ else { if(pl->lw < pr->lw) { back = -1; } }
+ }
+ /*
+ Pen color.
+ */
+ if(0 == back) {
+ if(pl->pc > pr->pc) { back = 1; }
+ else { if(pl->pc < pr->pc) { back = -1; } }
+ }
+ /*
+ Line cap.
+ */
+ if(0 == back) {
+ if(pl->cs > pr->cs) { back = 1; }
+ else { if(pl->cs < pr->cs) { back = -1; } }
+ }
+ /*
+ Line join.
+ */
+ if(0 == back) {
+ if(pl->js > pr->js) { back = 1; }
+ else { if(pl->js < pr->js) { back = -1; } }
+ }
+ /*
+ Line style, style value for equal line style.
+ */
+ if(0 == back) {
+ if(pl->ls > pr->ls) { back = 1; }
+ else { if(pl->ls < pr->ls) { back = -1; } }
+ if(0 == back) {
+ if(pl->sv > pr->sv) { back = 1; }
+ else { if(pl->sv < pr->sv) { back = -1; } }
+ }
+ }
+ /*
+ Non-closed before closed.
+ */
+ if(0 == back) {
+ if(pl->cl) {
+ if(pr->cl) {
+ /*
+ Fill color.
+ */
+ if(pl->fc > pr->fc) { back = 1; }
+ else { if(pl->fc < pr->fc) { back = -1; } }
+ /*
+ Fill style.
+ */
+ if(0 == back) {
+ if(pl->fi > pr->fi) { back = 1; }
+ else { if(pl->fi < pr->fi) { back = -1; } }
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(pr->cl) {
+ back = -1;
+ }
+ }
+ }
+ /*
+ Object type.
+ */
+ if(0 == back) {
+ if(pl->ot > pr->ot) { back = 1; }
+ else { if(pl->ot < pr->ot) { back = -1; } }
+ }
+ /*
+ Sub type.
+ */
+ if(0 == back) {
+ if(pl->st > pr->st) { back = 1; }
+ else { if(pl->st < pr->st) { back = -1; } }
+ }
+ return back;
+}
+
+
+
+/** Compare two Fig objects for sorted storing.
+ We must draw the deepest layer elements first (by definition).
+ Additionally we sort elements by multiple attributes
+ (non-text elements before texts, pen color, fill color and type,
+ line style, line width, cap style, join style) to group elements
+ with equal attributes. This is done to minimize instructions
+ for writing colors, line style, line width...
+ @param l Left Fig object.
+ @param r Right Fig object.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+static
+int
+dk3fig_obj_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3_fig_obj_t const *pl;
+ dk3_fig_obj_t const *pr;
+ if(l) {
+ if(r) {
+ pl = (dk3_fig_obj_t const *)l;
+ pr = (dk3_fig_obj_t const *)r;
+ /*
+ Deepest layers first.
+ */
+ if(pl->la > pr->la) { back = -1; }
+ else { if(pl->la < pr->la) { back = 1; } }
+ /*
+ Non-texts before texts.
+ */
+ if(0 == back) {
+ if(DK3_FIG_OBJ_TEXT == pl->ot) {
+ if(!(DK3_FIG_OBJ_TEXT == pr->ot)) {
+ back = 1;
+ } else {
+ back = dk3fig_obj_text_compare(pl, pr);
+ }
+ } else {
+ if(DK3_FIG_OBJ_TEXT == pr->ot) {
+ back = -1;
+ } else {
+ back = dk3fig_obj_path_compare(pl, pr);
+ }
+ }
+ }
+ /*
+ Line number of definition.
+ */
+ if(0 == back) {
+ if(pl->li > pr->li) { back = 1; }
+ else { if(pl->li < pr->li) { back = -1; } }
+ }
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ }
+ return back;
+}
+
+
+
+/** Destroy arrowhead, release memory.
+ @param ah Arrowhead to destroy.
+*/
+static
+void
+dk3fig_ah_delete(dk3_fig_ah_t *ah)
+{
+
+
+#line 1427 "dk3fig.ctr"
+ if(ah) {
+ if(ah->o1) {
+
+#line 1429 "dk3fig.ctr"
+ dk3fig_obj_delete((dk3_fig_obj_t *)(ah->o1));
+ }
+ if(ah->o2) {
+
+#line 1432 "dk3fig.ctr"
+ dk3fig_obj_delete((dk3_fig_obj_t *)(ah->o2));
+ }
+ dk3_delete(ah);
+ }
+
+#line 1436 "dk3fig.ctr"
+}
+
+
+
+/** Create new arrowhead structure.
+ @param app Application structure for diagnostics.
+ @return Pointer to new structure on success, NULL on error.
+*/
+static
+dk3_fig_ah_t *
+dk3fig_ah_new(dk3_app_t *app)
+{
+ dk3_fig_ah_t *back = NULL;
+ back = dk3_new_app(dk3_fig_ah_t,1,app);
+ if(back) {
+ back->o1 = NULL;
+ back->o2 = NULL;
+ back->wi = 0.0;
+ back->he = 0.0;
+ back->as = 0;
+ back->af = 0;
+ }
+ return back;
+}
+
+
+
+void
+dk3fig_obj_delete(dk3_fig_obj_t *obj)
+{
+
+
+#line 1467 "dk3fig.ctr"
+ if(obj) {
+ if(obj->af) {
+
+#line 1469 "dk3fig.ctr"
+ dk3fig_ah_delete(obj->af);
+ }
+ if(obj->ab) {
+
+#line 1472 "dk3fig.ctr"
+ dk3fig_ah_delete(obj->ab);
+ }
+ switch(obj->ot) {
+ case DK3_FIG_OBJ_TEXT: {
+
+#line 1476 "dk3fig.ctr"
+ if((obj->dt).txt.st) {
+ dk3_release((obj->dt).txt.st);
+ }
+ } break;
+ case DK3_FIG_OBJ_SPLINE: {
+
+#line 1481 "dk3fig.ctr"
+ if((obj->dt).spl.po) {
+ dk3_release((obj->dt).spl.po);
+ }
+ if((obj->dt).spl.fslc) {
+ dk3_release((obj->dt).spl.fslc);
+ }
+ } break;
+ case DK3_FIG_OBJ_POLYLINE: {
+
+#line 1489 "dk3fig.ctr"
+ if((obj->dt).pol.po) {
+ dk3_release((obj->dt).pol.po);
+ }
+ if((obj->dt).pol.fn) {
+ dk3_release((obj->dt).pol.fn);
+ }
+ } break;
+ }
+ obj->af = NULL;
+ obj->ab = NULL;
+ dk3_delete(obj);
+ }
+
+#line 1501 "dk3fig.ctr"
+}
+
+
+
+/** Reset all members of a drawing object.
+ @param drw Drawing object to reset.
+*/
+static
+void
+dk3fig_initialize_empty_drawing(dk3_fig_drawing_t *drw)
+{
+
+
+#line 1513 "dk3fig.ctr"
+ dk3bb_reset(&(drw->bb));
+ drw->msg = NULL;
+ drw->app = NULL;
+ drw->sobj = NULL;
+ drw->iobj = NULL;
+ drw->scol = NULL;
+ drw->icol = NULL;
+ drw->cobj = NULL;
+ drw->dsd = NULL;
+ drw->res = 1200.0;
+ drw->lineno = 0UL;
+ drw->lres = 0;
+ drw->cind = 0;
+ drw->cxy = 0;
+ drw->state = 0;
+ drw->ec = 0;
+ drw->srctype = DK3_FIG_SRCTYPE_UNKNOWN;
+ drw->xssbs = 8;
+ drw->qbs = 4;
+ drw->transcol = -2;
+ drw->coah = 0;
+ drw->xsah = 0;
+ drw->cosp = 0;
+ drw->cofop = 1;
+ drw->bbts = 0;
+ drw->arcspp = 8.0;
+ drw->splspp = 8.0;
+ drw->minspp = 4;
+ drw->codi = 3;
+ drw->xsprec = 0.04; /* originally 1200.0 / 25400.0 */
+ drw->lwbp = 0.9; /* 1/80 inch */
+
+
+#line 1545 "dk3fig.ctr"
+}
+
+
+
+/** Compare two Fig colors.
+ @param l Left object.
+ @param r Right color object or number.
+ @param cr Comparison criteria (0=color/color, 1=color/number).
+ @return Comparison result.
+*/
+static
+int
+dk3fig_color_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3_fig_color_t const *pl;
+ dk3_fig_color_t const *pr;
+ int *ip;
+ if(l) {
+ if(r) {
+ pl = (dk3_fig_color_t const *)l;
+ pr = (dk3_fig_color_t const *)r;
+ ip = (int *)r;
+ switch(cr) {
+ case 1: {
+ if(pl->i > (*ip)) {
+ back = 1;
+ } else {
+ if(pl->i < (*ip)) {
+ back = -1;
+ }
+ }
+ } break;
+ default: {
+ if(pl->i > pr->i) {
+ back = 1;
+ } else {
+ if(pl->i < pr->i) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ }
+ return back;
+}
+
+
+dk3_fig_drawing_t *
+dk3fig_drawing_new(dk3_app_t *app, dkChar const * const *msg)
+{
+ dk3_fig_drawing_t *back = NULL;
+
+
+#line 1601 "dk3fig.ctr"
+ if(app) {
+ back = dk3_new_app(dk3_fig_drawing_t,1,app);
+ if(back) {
+ dk3fig_initialize_empty_drawing(back);
+ back->app = app;
+ back->msg = msg;
+ back->sobj = dk3sto_open_app(app);
+ if(back->sobj) {
+ dk3sto_set_comp(back->sobj, dk3fig_obj_compare, 0);
+ back->iobj = dk3sto_it_open(back->sobj);
+ if(back->iobj) {
+ back->scol = dk3sto_open_app(app);
+ if(back->scol) {
+ dk3sto_set_comp(back->scol, dk3fig_color_compare, 0);
+ back->icol = dk3sto_it_open(back->scol);
+ if(back->icol) {
+ /* Place for further initialization here */
+ } else {
+
+#line 1619 "dk3fig.ctr"
+ dk3fig_drawing_delete(back);
+ back = NULL;
+ }
+ } else {
+
+#line 1623 "dk3fig.ctr"
+ dk3fig_drawing_delete(back);
+ back = NULL;
+ }
+ } else {
+
+#line 1627 "dk3fig.ctr"
+ dk3fig_drawing_delete(back);
+ back = NULL;
+ }
+ } else {
+
+#line 1631 "dk3fig.ctr"
+ dk3fig_drawing_delete(back);
+ back = NULL;
+ }
+ } else {
+
+#line 1635 "dk3fig.ctr"
+ }
+ }
+
+#line 1637 "dk3fig.ctr"
+ return back;
+}
+
+
+
+void
+dk3fig_drawing_delete(dk3_fig_drawing_t *drw)
+{
+ dk3_fig_color_t *co; /* Current color to release. */
+ dk3_fig_obj_t *po; /* Current Fig object to release. */
+
+
+#line 1648 "dk3fig.ctr"
+ if(drw) {
+ /*
+ Remove all objects.
+ */
+ if(drw->sobj) {
+ if(drw->iobj) {
+ dk3sto_it_reset(drw->iobj);
+ while(NULL != (po = (dk3_fig_obj_t *)dk3sto_it_next(drw->iobj))) {
+ dk3fig_obj_delete(po);
+ }
+ dk3sto_it_close(drw->iobj);
+ }
+ dk3sto_close(drw->sobj);
+ }
+ /*
+ Remove all colors.
+ */
+ if(drw->scol) {
+ if(drw->icol) {
+ dk3sto_it_reset(drw->icol);
+ while(NULL != (co = (dk3_fig_color_t *)dk3sto_it_next(drw->icol))) {
+
+
+#line 1670 "dk3fig.ctr"
+ dk3_delete(co);
+ }
+ dk3sto_it_close(drw->icol);
+ }
+ dk3sto_close(drw->scol);
+ }
+ /*
+ Reset all members.
+ */
+ dk3fig_initialize_empty_drawing(drw);
+ /*
+ Release memory.
+ */
+ drw->app = NULL;
+ drw->msg = NULL;
+ dk3_delete(drw);
+ }
+
+#line 1687 "dk3fig.ctr"
+}
+
+
+
+/** Internal function to create Fig object and initialize it.
+ @param li Line number of object definition in file.
+ @param la Layer number.
+ @param ot Object type.
+ @param st Object subtype.
+ @param lw Line width.
+ @param pc Pen color.
+ @param fc Fill color.
+ @param fi Fill type.
+ @param cs Cap style.
+ @param js Join style.
+ @param ls Line style.
+ @param sv Style value.
+ @param af Flag: Arrowhead forward.
+ @param ab Flag: Arrowhead backward.
+ @param po Flag: Path object (non-text object).
+ @param cl Flag: Closed path object.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new object on success, NULL on error.
+*/
+static
+dk3_fig_obj_t *
+dk3fig_obj_internal_new(
+ unsigned long li,
+ int la,
+ int ot,
+ int st,
+ int lw,
+ int pc,
+ int fc,
+ int fi,
+ int cs,
+ int js,
+ int ls,
+ double sv,
+ int af,
+ int ab,
+ int po,
+ int cl,
+ dk3_app_t *app
+)
+{
+ dk3_fig_obj_t *back = NULL;
+
+
+#line 1735 "dk3fig.ctr"
+ back = dk3_new_app(dk3_fig_obj_t,1,app);
+ if(back) {
+
+#line 1737 "dk3fig.ctr"
+ back->af = NULL;
+ back->ab = NULL;
+ back->dsd = NULL;
+ back->sv = sv;
+ back->li = li;
+ back->la = la;
+ back->ot = ot;
+ back->st = st;
+ back->lw = lw;
+ back->pc = pc;
+ back->fc = fc;
+ back->fi = fi;
+ back->cs = cs;
+ back->js = js;
+ back->ls = ls;
+ back->cl = ((cl) ? 0x01 : 0x00);
+
+#line 1753 "dk3fig.ctr"
+ if(back->lw < 0) {
+ back->lw = 0;
+ if(po) {
+
+#line 1756 "dk3fig.ctr"
+ /* +++++ Warning: Illegal line width corrected! */
+ }
+ }
+ if(back->pc < -1) {
+
+#line 1760 "dk3fig.ctr"
+ back->pc = -1;
+ /* +++++ Warning: Illegal pen color definition corrected! */
+ }
+ if(back->fc < DK3_FIG_COLOR_DEFAULT) {
+ back->fc = DK3_FIG_COLOR_DEFAULT;
+ if((po) && (cl)) {
+
+#line 1766 "dk3fig.ctr"
+ /* +++++ Warning: Illegal fill color definition corrected! */
+ }
+ }
+ if(back->fi < DK3_FIG_COLOR_DEFAULT) {
+ back->fi = DK3_FIG_COLOR_DEFAULT;
+ if((po) && (cl)) {
+
+#line 1772 "dk3fig.ctr"
+ /* +++++ Warning: Illegal fill style corrected! */
+ }
+ } else {
+ if(back->fi > 62) {
+ back->fi = 62;
+ if((po) && (cl)) {
+
+#line 1778 "dk3fig.ctr"
+ /* +++++ Warning: Illegal fill style corrected! */
+ }
+ } else {
+ if((DK3_FIG_COLOR_BLACK == fc) || (DK3_FIG_COLOR_WHITE == fc)) {
+ if((back->fi >= 21) && (back->fi <= 40)) {
+ back->fi = 20;
+ if((po) && (cl)) {
+
+#line 1785 "dk3fig.ctr"
+ /* +++++ Warning: Illegal fill style corrected! */
+ }
+ }
+ }
+ }
+ }
+ if(DK3_FIG_LC_BUTT != back->cs) {
+ if(DK3_FIG_LC_ROUND != back->cs) {
+ if(DK3_FIG_LC_PROJECTING != back->cs) {
+ back->cs = DK3_FIG_LC_BUTT;
+ if(po) {
+
+#line 1796 "dk3fig.ctr"
+ /* +++++ Warning: Illegal line cap style corrected! */
+ }
+ }
+ }
+ }
+ if(DK3_FIG_LJ_MITER != back->js) {
+ if(DK3_FIG_LJ_ROUND != back->js) {
+ if(DK3_FIG_LJ_BEVEL != back->js) {
+ back->js = DK3_FIG_LJ_MITER;
+ if(po) {
+
+#line 1806 "dk3fig.ctr"
+ /* +++++ Warning: Illegal line join style corrected! */
+ }
+ }
+ }
+ }
+ if(back->ls < DK3_FIG_LS_SOLID) {
+ back->ls = DK3_FIG_LS_SOLID;
+ if(ls < DK3_FIG_LS_DEFAULT) {
+ if(po) {
+
+#line 1815 "dk3fig.ctr"
+ /* +++++ Warning: Illegal line style corrected! */
+ }
+ }
+ } else {
+ if(back->ls > DK3_FIG_LS_DASH_TRIPLE_DOTTED) {
+ back->ls = DK3_FIG_LS_SOLID;
+ if(po) {
+
+#line 1822 "dk3fig.ctr"
+ /* +++++ Warning: Illegal line style corrected! */
+ }
+ }
+ }
+ } else {
+
+#line 1827 "dk3fig.ctr"
+ }
+ if((po) && (!(cl))) {
+
+#line 1829 "dk3fig.ctr"
+ if(NULL != back) {
+ if(af) {
+
+#line 1831 "dk3fig.ctr"
+ back->af = dk3fig_ah_new(app);
+ if(!(back->af)) {
+ dk3fig_obj_delete(back);
+ back = NULL;
+ }
+ }
+ }
+ if (NULL != back) {
+ if(ab) {
+
+#line 1840 "dk3fig.ctr"
+ back->ab = dk3fig_ah_new(app);
+ if(!(back->ab)) {
+ dk3fig_obj_delete(back);
+ back = NULL;
+ }
+ }
+ }
+ } else {
+
+#line 1848 "dk3fig.ctr"
+ if((af) || (ab)) {
+
+#line 1849 "dk3fig.ctr"
+ /* +++++ Warning: Arrowhead ignored for closed path! */
+ }
+ }
+
+#line 1852 "dk3fig.ctr"
+ return back;
+}
+
+
+
+/** Initialize details for arc.
+ @param obj Object to initialize.
+*/
+static
+void
+dk3fig_initialize_arc_details(dk3_fig_obj_t *obj)
+{
+ (obj->dt).arc.xc = 0.0;
+ (obj->dt).arc.yc = 0.0;
+ (obj->dt).arc.ra = 0.0;
+ (obj->dt).arc.x1 = 0.0;
+ (obj->dt).arc.y1 = 0.0;
+ (obj->dt).arc.x2 = 0.0;
+ (obj->dt).arc.y2 = 0.0;
+ (obj->dt).arc.x3 = 0.0;
+ (obj->dt).arc.y3 = 0.0;
+ (obj->dt).arc.as = 0.0;
+ (obj->dt).arc.ae = 0.0;
+ (obj->dt).arc.di = 0x00;
+}
+
+
+
+/** Initialize ellipse details.
+ @param obj Object to initialize.
+*/
+static
+void
+dk3fig_initialize_ellipse_details(dk3_fig_obj_t *obj)
+{
+ (obj->dt).ell.an = 0.0;
+ (obj->dt).ell.cx = 0.0;
+ (obj->dt).ell.cy = 0.0;
+ (obj->dt).ell.rx = 0.0;
+ (obj->dt).ell.ry = 0.0;
+}
+
+
+
+/** Initialize polyline details.
+ @param obj Object to initialize.
+ @param np Number of points.
+ @param app Application structure for diagnostics.
+ @return 1 on success, 0 on error (not enough memory).
+*/
+static
+int
+dk3fig_initialize_polyline_details(dk3_fig_obj_t *obj,size_t np,dk3_app_t *app)
+{
+ int back = 0;
+ (obj->dt).pol.fn = NULL;
+ (obj->dt).pol.po = NULL;
+ (obj->dt).pol.ra = 0.0;
+ (obj->dt).pol.xs = 0.0;
+ (obj->dt).pol.ys = 0.0;
+ (obj->dt).pol.xe = 0.0;
+ (obj->dt).pol.ye = 0.0;
+ (obj->dt).pol.np = np;
+ (obj->dt).pol.flf = 0;
+ (obj->dt).pol.po = dk3_new_app(dk3_fig_poly_point_t,np,app);
+ if((obj->dt).pol.po) {
+ back = 1;
+ }
+ return back;
+}
+
+
+
+/** Initialize spline details.
+ @param obj Object to initialize.
+ @param np Number of spline points.
+ @param app Application structure for diagnostics.
+ @return 1 on success, 0 on error (not enough memory).
+*/
+static
+int
+dk3fig_initialize_spline_details(dk3_fig_obj_t *obj,size_t np,dk3_app_t *app)
+{
+ double *xptr;
+ size_t i;
+ int back = 0;
+ (obj->dt).spl.po = NULL;
+ (obj->dt).spl.fslc = NULL;
+ (obj->dt).spl.ts = -1.0;
+ (obj->dt).spl.te = -1.0;
+ (obj->dt).spl.np = np;
+ (obj->dt).spl.po = dk3_new_app(dk3_fig_spline_point_t, np, app);
+ if((obj->dt).spl.po) {
+ back = 1;
+ switch(obj->st) {
+ case 0: case 2: case 4: {
+ if(((obj->af) || (obj->ab)) && (2 <= np)) {
+ (obj->dt).spl.fslc = dk3_new_app(double, (np-1), app);
+ if((obj->dt).spl.fslc) {
+ /* Initialize cache to -1 */
+ xptr = (obj->dt).spl.fslc;
+ i = np - 1;
+ while(i--) { *(xptr++) = -1.0; }
+ } else {
+ back = 0;
+ }
+ }
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+/** Initialize text details.
+ @param obj Object to initialize.
+ @param tx Text for text object.
+ @param app Application structure for diagnostics.
+ @return 1 on success, 0 on error (not enough memory).
+*/
+static
+int
+dk3fig_initialize_text_details(dk3_fig_obj_t *obj,char const *tx,dk3_app_t *app)
+{
+ int back = 0;
+ (obj->dt).txt.st = NULL;
+ (obj->dt).txt.x = 0.0;
+ (obj->dt).txt.y = 0.0;
+ (obj->dt).txt.an = 0.0;
+ (obj->dt).txt.fs = 0.0;
+ (obj->dt).txt.he = 0.0;
+ (obj->dt).txt.wi = 0.0;
+ (obj->dt).txt.fo = 0;
+ (obj->dt).txt.ff = 0;
+ (obj->dt).txt.st = dk3str_c8_dup_app(tx, app);
+ if((obj->dt).txt.st) {
+ back = 1;
+ }
+ return back;
+}
+
+
+
+dk3_fig_obj_t *
+dk3fig_obj_new(
+ unsigned long li,
+ int la,
+ int ot,
+ int st,
+ int lw,
+ int pc,
+ int fc,
+ int fi,
+ int cs,
+ int js,
+ int ls,
+ double sv,
+ int af,
+ int ab,
+ size_t np,
+ char const *txt,
+ dk3_app_t *app
+)
+{
+ dk3_fig_obj_t *back = NULL;
+
+
+#line 2019 "dk3fig.ctr"
+ if((la < 0) || (la > 999)) {
+ /* +++++ Warning: Illegal layer number! */
+ }
+ switch(ot) {
+ case DK3_FIG_OBJ_ARC: {
+
+#line 2024 "dk3fig.ctr"
+ switch(st) {
+ case DK3_FIG_OBJ_SUB_ARC_OPEN: {
+
+#line 2026 "dk3fig.ctr"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 0, app
+ );
+ } break;
+ case DK3_FIG_OBJ_SUB_ARC_CLOSED: {
+
+#line 2031 "dk3fig.ctr"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app
+ );
+ } break;
+ case 0: {
+
+#line 2036 "dk3fig.ctr"
+ /* +++++ Warning: jFig closed arc bug. */
+ back = dk3fig_obj_internal_new(
+ li, la, ot, DK3_FIG_OBJ_SUB_ARC_CLOSED,
+ lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 0, app
+ );
+ } break;
+ default: {
+
+#line 2043 "dk3fig.ctr"
+ /* +++++ Warning: Illegal sub type corrected! */
+ back = dk3fig_obj_internal_new(
+ li, la, ot, DK3_FIG_OBJ_SUB_ARC_CLOSED,
+ lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 0, app
+ );
+ } break;
+ }
+ if(back) {
+ dk3fig_initialize_arc_details(back);
+ }
+ } break;
+ case DK3_FIG_OBJ_ELLIPSE: {
+
+#line 2055 "dk3fig.ctr"
+ switch(st) {
+ case DK3_FIG_OBJ_SUB_ELL_RADII: {
+
+#line 2057 "dk3fig.ctr"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app
+ );
+ } break;
+ case DK3_FIG_OBJ_SUB_ELL_DIAMETERS: {
+
+#line 2062 "dk3fig.ctr"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app
+ );
+ } break;
+ case DK3_FIG_OBJ_SUB_CIR_RADIUS: {
+
+#line 2067 "dk3fig.ctr"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app
+ );
+ } break;
+ case DK3_FIG_OBJ_SUB_CIR_DIAMETER: {
+
+#line 2072 "dk3fig.ctr"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app
+ );
+ } break;
+ default: {
+
+#line 2077 "dk3fig.ctr"
+ /* +++++ Warning: Illegal sub type corrected! */
+ back = dk3fig_obj_internal_new(
+ li, la, ot, DK3_FIG_OBJ_SUB_ELL_RADII,
+ lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app
+ );
+ } break;
+ }
+ if(back) {
+ dk3fig_initialize_ellipse_details(back);
+ }
+ } break;
+ case DK3_FIG_OBJ_POLYLINE: {
+
+#line 2089 "dk3fig.ctr"
+ switch(st) {
+ case DK3_FIG_OBJ_SUB_POLYLINE: {
+
+#line 2091 "dk3fig.ctr"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 0, app
+ );
+ } break;
+ case DK3_FIG_OBJ_SUB_BOX: {
+
+#line 2096 "dk3fig.ctr"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app
+ );
+ } break;
+ case DK3_FIG_OBJ_SUB_POLYGON: {
+
+#line 2101 "dk3fig.ctr"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app
+ );
+ } break;
+ case DK3_FIG_OBJ_SUB_ARCBOX: {
+
+#line 2106 "dk3fig.ctr"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app
+ );
+ } break;
+ case DK3_FIG_OBJ_SUB_IMAGE: {
+
+#line 2111 "dk3fig.ctr"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app
+ );
+ } break;
+ default: {
+
+#line 2116 "dk3fig.ctr"
+ /* +++++ Warning: Illegal sub type corrected! */
+ back = dk3fig_obj_internal_new(
+ li, la, ot, DK3_FIG_OBJ_SUB_POLYLINE,
+ lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 0, app
+ );
+ } break;
+ }
+ if(back) {
+ if(!dk3fig_initialize_polyline_details(back, np, app)) {
+ dk3fig_obj_delete(back);
+ back = NULL;
+ }
+ }
+ } break;
+ case DK3_FIG_OBJ_SPLINE: {
+
+#line 2131 "dk3fig.ctr"
+ switch(st) {
+ case DK3_FIG_OBJ_SUB_OPEN_APPRO: {
+
+#line 2133 "dk3fig.ctr"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 0, app
+ );
+ } break;
+ case DK3_FIG_OBJ_SUB_CLOSED_APPRO: {
+
+#line 2138 "dk3fig.ctr"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app
+ );
+ } break;
+ case DK3_FIG_OBJ_SUB_OPEN_INT: {
+
+#line 2143 "dk3fig.ctr"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 0, app
+ );
+ } break;
+ case DK3_FIG_OBJ_SUB_CLOSED_INT: {
+
+#line 2148 "dk3fig.ctr"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app
+ );
+ } break;
+ case DK3_FIG_OBJ_SUB_OPEN_X: {
+
+#line 2153 "dk3fig.ctr"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 0, app
+ );
+ } break;
+ case DK3_FIG_OBJ_SUB_CLOSED_X: {
+
+#line 2158 "dk3fig.ctr"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app
+ );
+ } break;
+ default: {
+
+#line 2163 "dk3fig.ctr"
+ /* +++++ Warning: Illegal sub type corrected! */
+ back = dk3fig_obj_internal_new(
+ li, la, ot, DK3_FIG_OBJ_SUB_OPEN_X,
+ lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 0, app
+ );
+ } break;
+ }
+ if(back) {
+ if(!dk3fig_initialize_spline_details(back, np, app)) {
+ dk3fig_obj_delete(back);
+ back = NULL;
+ }
+ }
+ } break;
+ case DK3_FIG_OBJ_TEXT: {
+
+#line 2178 "dk3fig.ctr"
+ if(txt) {
+
+#line 2179 "dk3fig.ctr"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 0, 0, app
+ );
+ if(back) {
+ if(!dk3fig_initialize_text_details(back, txt, app)) {
+ dk3fig_obj_delete(back);
+ back = NULL;
+ }
+ }
+ } else {
+
+#line 2189 "dk3fig.ctr"
+ /* +++++ ERROR: No text specified! */
+ }
+ } break;
+ case DK3_FIG_OBJ_PSEUDO_HALF_CIRCLE: {
+
+#line 2193 "dk3fig.ctr"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, ((st) ? 1 : 0),
+ lw, pc, fc, fi, cs, js, ls, sv, af, ab, 0,
+ ((st) ? 1 : 0),
+ app
+ );
+ } break;
+ default: {
+
+#line 2201 "dk3fig.ctr"
+ /* +++++ ERROR: Can not create object! */
+ } break;
+ }
+
+#line 2204 "dk3fig.ctr"
+ return back;
+}
+
+
+void
+dk3fig_obj_init(dk3_fig_obj_t *obj)
+{
+ if(obj) {
+ dk3mem_res((void *)obj, sizeof(dk3_fig_obj_t));
+ obj->af = NULL;
+ obj->ab = NULL;
+ obj->dsd = NULL;
+ obj->sv = 0.0;
+ }
+}
+
+
+
+void
+dk3fig_set_options_bsegs(dk3_fig_drawing_t *drw, size_t xssbs, size_t qbs)
+{
+ if(drw) {
+ drw->xssbs = xssbs;
+ drw->qbs = qbs;
+ if(xssbs < 2) drw->xssbs = 2;
+ if(qbs < 2) drw->qbs = 2;
+ }
+}
+
+
+
+void
+dk3fig_set_options_lwbp(dk3_fig_drawing_t *drw, double val)
+{
+ if (drw) {
+ drw->lwbp = val;
+ }
+}
+
+
+
+void
+dk3fig_set_options_coah(dk3_fig_drawing_t *drw, int val)
+{
+ if(drw) {
+ drw->coah = ((val) ? 1 : 0);
+ }
+}
+
+
+
+void
+dk3fig_set_options_xsah(dk3_fig_drawing_t *drw, int val)
+{
+ if (drw) {
+ drw->xsah = ((val) ? 1 : 0);
+ }
+}
+
+
+
+void
+dk3fig_set_options_cosp(dk3_fig_drawing_t *drw, int val)
+{
+ if(drw) {
+ drw->cosp = ((val) ? 1 : 0);
+ }
+}
+
+
+
+void
+dk3fig_set_options_bbts(dk3_fig_drawing_t *drw, int val)
+{
+ if(drw) {
+ drw->bbts = ((val) ? 1 : 0);
+ }
+}
+
+
+
+void
+dk3fig_set_options_cofop(dk3_fig_drawing_t *drw, int val)
+{
+ if(drw) {
+ drw->cofop = ((val) ? 1 : 0);
+ }
+}
+
+
+
+void
+dk3fig_set_options_srctype(dk3_fig_drawing_t *drw, int val)
+{
+ if(drw) {
+ drw->srctype = val;
+ }
+}
+
+
+
+void
+dk3fig_set_options_arrows(
+ dk3_fig_drawing_t *drw,
+ double arcspp,
+ double splspp,
+ size_t minspp
+)
+{
+ if(drw) {
+ drw->arcspp = arcspp;
+ if(drw->arcspp < 2.0) { drw->arcspp = 2.0; }
+ drw->splspp = splspp;
+ if(drw->splspp < 2.0) { drw->splspp = 2.0; }
+ drw->minspp = minspp;
+ if(drw->minspp < 2) { drw->minspp = 2; }
+ }
+}
+
+
+
+void
+dk3fig_set_options_iteration_precision(
+ dk3_fig_drawing_t *drw,
+ double prec
+)
+{
+ if(drw) {
+ drw->xsprec = fabs(prec);
+ if(drw->xsprec < 1.0e-24) {
+ drw->xsprec = 1.0e-24;
+ }
+ }
+}
+
+
+void
+dk3fig_gs_init(dk3_graphics_state_t *gs)
+{
+ if(gs) {
+ (gs->c1).r = (gs->c1).g = (gs->c1).b = 0.0;
+ (gs->c2).r = (gs->c2).g = (gs->c2).b = 0.0;
+ gs->lw = -1.0;
+ gs->sv = -1.0;
+ gs->slw = -1.0;
+ gs->lc = gs->lj = gs->ls = 0;
+ gs->hc1 = gs->hc2 = gs->hlc = gs->hlj = gs->hlw = gs->hls = 0;
+ gs->hfn = 0; gs->fs = -1.0; gs->fn = -1;
+ }
+}
+
+
+
+void
+dk3fig_set_options_codi(
+ dk3_fig_drawing_t *drw,
+ size_t codi
+)
+{
+ if(drw) {
+ drw->codi = codi;
+ }
+}
+
+
+
+void
+dk3fig_set_ec(dk3_fig_drawing_t *drw, int ec)
+{
+ if(drw) {
+ if(0 == drw->ec) {
+ drw->ec = ec;
+ }
+ }
+}
+
+
diff --git a/support/dktools/dk3fig.ctr b/support/dktools/dk3fig.ctr
new file mode 100644
index 0000000000..67938e1c6b
--- /dev/null
+++ b/support/dktools/dk3fig.ctr
@@ -0,0 +1,2380 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+%% header
+
+#include <dk3all.h>
+#include <dk3bb.h>
+
+/** Maximum input line size for Fig file.
+ Although the Fig Format 3.2 specification does not set any limit for
+ line sizes in Fig files we want to provide a buffer for input lines,
+ so we must specify a buffer size.
+*/
+#define DK3_FIG_LINE_SIZE 1024
+
+
+/** Maximum difference to treat coordinates as equal.
+*/
+#define DK3_FIG_EPSILON 1.0e-6
+
+
+
+/** @defgroup dk3figoperations Draw operations. */
+/**@{*/
+/** Path operation: stroke.
+*/
+#define DK3_FIG_OP_STROKE 1
+
+/** Path operation: fill.
+*/
+#define DK3_FIG_OP_FILL 2
+
+/** Path operation: draw fill pattern.
+*/
+#define DK3_FIG_OP_PATTERN 4
+
+/**@}*/
+
+
+
+/** @defgroup dk3figcolors Fig colors */
+/**@{*/
+/** Use default color.
+*/
+#define DK3_FIG_COLOR_DEFAULT (-1)
+
+/** Black.
+*/
+#define DK3_FIG_COLOR_BLACK 0
+
+/** Blue.
+*/
+#define DK3_FIG_COLOR_BLUE 1
+
+/** Green.
+*/
+#define DK3_FIG_COLOR_GREEN 2
+
+/** Cyan.
+*/
+#define DK3_FIG_COLOR_CYAN 3
+
+/** Red.
+*/
+#define DK3_FIG_COLOR_RED 4
+
+/** Magenta.
+*/
+#define DK3_FIG_COLOR_MAGENTA 5
+
+/** Yellow.
+*/
+#define DK3_FIG_COLOR_YELLOW 6
+
+/** White.
+*/
+#define DK3_FIG_COLOR_WHITE 7
+
+/** Blue, 20 percent.
+*/
+#define DK3_FIG_COLOR_20_BLUE 8
+
+/** Blue, 40 percent.
+*/
+#define DK3_FIG_COLOR_40_BLUE 9
+
+/** Blue, 60 percent.
+*/
+#define DK3_FIG_COLOR_60_BLUE 10
+
+/** Blue, 80 percent.
+*/
+#define DK3_FIG_COLOR_80_BLUE 11
+
+/** Green, 25 percent.
+*/
+#define DK3_FIG_COLOR_25_GREEN 12
+
+/** Green, 50 percent.
+*/
+#define DK3_FIG_COLOR_50_GREEN 13
+
+/** Green, 75 percent.
+*/
+#define DK3_FIG_COLOR_75_GREEN 14
+
+/** Cyan, 25 percent.
+*/
+#define DK3_FIG_COLOR_25_CYAN 15
+
+/** Cyan, 50 percent.
+*/
+#define DK3_FIG_COLOR_50_CYAN 16
+
+/** Cyan, 75 percent.
+*/
+#define DK3_FIG_COLOR_75_CYAN 17
+
+/** Red, 25 percent.
+*/
+#define DK3_FIG_COLOR_25_RED 18
+
+/** Red, 50 percent.
+*/
+#define DK3_FIG_COLOR_50_RED 19
+
+/** Red, 75 percent.
+*/
+#define DK3_FIG_COLOR_75_RED 20
+
+/** Magenta, 25 percent.
+*/
+#define DK3_FIG_COLOR_25_MAGENTA 21
+
+/** Magenta, 50 percent.
+*/
+#define DK3_FIG_COLOR_50_MAGENTA 22
+
+/** Magenta, 75 percent.
+*/
+#define DK3_FIG_COLOR_75_MAGENTA 23
+
+/** Brown, 33 percent.
+*/
+#define DK3_FIG_COLOR_33_BROWN 24
+
+/** Brown, 66 percent.
+*/
+#define DK3_FIG_COLOR_66_BROWN 25
+
+/** Brown.
+*/
+#define DK3_FIG_COLOR_BROWN 26
+
+/** Pink, 25 percent.
+*/
+#define DK3_FIG_COLOR_25_PINK 27
+
+/** Pink, 50 percent.
+*/
+#define DK3_FIG_COLOR_50_PINK 28
+
+/** Pink, 75 percent.
+*/
+#define DK3_FIG_COLOR_75_PINK 29
+
+/** Pink.
+*/
+#define DK3_FIG_COLOR_PINK 30
+
+/** Gold.
+*/
+#define DK3_FIG_COLOR_GOLD 31
+
+/**@}*/
+
+
+
+/** @defgroup dk3figobjtypes Fig object types */
+/**@{*/
+/** Color definition.
+*/
+#define DK3_FIG_OBJ_COLOR 0
+
+/** Ellipse.
+*/
+#define DK3_FIG_OBJ_ELLIPSE 1
+
+/** Polyline, polygon.
+*/
+#define DK3_FIG_OBJ_POLYLINE 2
+
+/** Spline.
+*/
+#define DK3_FIG_OBJ_SPLINE 3
+
+/** Text.
+*/
+#define DK3_FIG_OBJ_TEXT 4
+
+/** Arc.
+*/
+#define DK3_FIG_OBJ_ARC 5
+
+/** Compound object. Compound objects are resolved while reading
+ the Fig file.
+*/
+#define DK3_FIG_OBJ_COMPOUND 6
+
+/** End of compound object.
+*/
+#define DK3_FIG_OBJ_ENDCOMPOUND (-6)
+
+/** Not in Fig format definition, used for arrowheads
+ 6/0 and 6/1.
+ Subtype 0: stroked only, 1: closed, filled.
+ The cl attribute must be set correctly.
+ This object type can not appear as primary object,
+ only in arrowheads.
+*/
+#define DK3_FIG_OBJ_PSEUDO_HALF_CIRCLE 100
+
+/** Not in Fig format definition, used for arrowheads.
+ Subtype 0: Open spline.
+ Subtype 1: Closed spline.
+ The cl attribute must be set correctly.
+ This object type can not appear as primary object,
+ only in arrowheads.
+*/
+#define DK3_FIG_OBJ_PSEUDO_FAST_SPLINE 101
+
+/**@}*/
+
+
+
+/** @defgroup dk3figsubtypes Fig object subtypes */
+/**@{*/
+
+/** Arc sub type: Open.
+*/
+#define DK3_FIG_OBJ_SUB_ARC_OPEN 1
+
+/** Arc sub type: Closed.
+*/
+#define DK3_FIG_OBJ_SUB_ARC_CLOSED 2
+
+/** Ellipse sub type: Defined by radii.
+*/
+#define DK3_FIG_OBJ_SUB_ELL_RADII 1
+
+/** Ellipse sub type: Defined by diameters.
+*/
+#define DK3_FIG_OBJ_SUB_ELL_DIAMETERS 2
+
+/** Ellipse sub type: Circle defined by radius.
+*/
+#define DK3_FIG_OBJ_SUB_CIR_RADIUS 3
+
+/** Ellipse sub type: Circle defined by diameter.
+*/
+#define DK3_FIG_OBJ_SUB_CIR_DIAMETER 4
+
+/** Polyline sub type: Polyline.
+*/
+#define DK3_FIG_OBJ_SUB_POLYLINE 1
+
+/** Polyline sub type: Box.
+*/
+#define DK3_FIG_OBJ_SUB_BOX 2
+
+/** Polyline sub type: Polygon.
+*/
+#define DK3_FIG_OBJ_SUB_POLYGON 3
+
+/** Polyline sub type: Arc-box.
+*/
+#define DK3_FIG_OBJ_SUB_ARCBOX 4
+
+/** Polyline sub type: Embedded image.
+*/
+#define DK3_FIG_OBJ_SUB_IMAGE 5
+
+/** Spline sub type: Open approximated spline.
+*/
+#define DK3_FIG_OBJ_SUB_OPEN_APPRO 0
+
+/** Spline sub type: Closed approximated spline.
+*/
+#define DK3_FIG_OBJ_SUB_CLOSED_APPRO 1
+
+/** Spline sub type: Open interpolated spline.
+*/
+#define DK3_FIG_OBJ_SUB_OPEN_INT 2
+
+/** Spline sub type: Closed interpolated spline.
+*/
+#define DK3_FIG_OBJ_SUB_CLOSED_INT 3
+
+/** Spline sub type: Open X-spline.
+*/
+#define DK3_FIG_OBJ_SUB_OPEN_X 4
+
+/** Spline sub type: Closed X-spline.
+*/
+#define DK3_FIG_OBJ_SUB_CLOSED_X 5
+
+/**@}*/
+
+
+/** @defgroup dk3figlinestyles Fig line styles */
+/**@{*/
+
+/** Default line style.
+*/
+#define DK3_FIG_LS_DEFAULT (-1)
+
+/** Solid line.
+*/
+#define DK3_FIG_LS_SOLID 0
+
+/** Dashed line.
+*/
+#define DK3_FIG_LS_DASHED 1
+
+/** Dotted line.
+*/
+#define DK3_FIG_LS_DOTTED 2
+
+/** Dash dot line.
+*/
+#define DK3_FIG_LS_DASH_DOTTED 3
+
+/** Dash dot dot line.
+*/
+#define DK3_FIG_LS_DASH_DOUBLE_DOTTED 4
+
+/** Dash dot dot dot line.
+*/
+#define DK3_FIG_LS_DASH_TRIPLE_DOTTED 5
+
+/**@}*/
+
+
+
+/** @defgroup dk3figlinejoin Line join style */
+/**@{*/
+
+/** Mitered line join.
+*/
+#define DK3_FIG_LJ_MITER 0
+
+/** Rounded line join.
+*/
+#define DK3_FIG_LJ_ROUND 1
+
+/** Beveled line join.
+*/
+#define DK3_FIG_LJ_BEVEL 2
+
+/**@}*/
+
+
+
+/** @defgroup dk3figlinecap Fig line cap style */
+/**@{*/
+
+/** Butted line cap.
+*/
+#define DK3_FIG_LC_BUTT 0
+
+/** Rounded line cap.
+*/
+#define DK3_FIG_LC_ROUND 1
+
+/** Projecting line cap.
+*/
+#define DK3_FIG_LC_PROJECTING 2
+
+/**@}*/
+
+
+
+/** @defgroup dk3figarrowstyles Fig arrow styles */
+/**@{*/
+
+/** Polyline arrow head.
+*/
+#define DK3_FIG_AS_STICK 0
+
+/** Polygon arrow head.
+*/
+#define DK3_FIG_AS_CLOSED 1
+
+/** Arrow with indented butt.
+*/
+#define DK3_FIG_AS_INDENTED 2
+
+/** Arrow with pointed butt.
+*/
+#define DK3_FIG_AS_POINTED 3
+
+/** Arrow with rhombus.
+*/
+#define DK3_FIG_AS_RHOMBUS 4
+
+/** Line end with circle.
+*/
+#define DK3_FIG_AS_FULL_CIRCLE_END 5
+
+/** Line end with half circle.
+*/
+#define DK3_FIG_AS_HALF_CIRCLE_END 6
+
+/** Line end with rectangle.
+*/
+#define DK3_FIG_AS_RECTANGLE 7
+
+/** Arrow inverted arrowhead.
+*/
+#define DK3_FIG_AS_INVERSE 8
+
+/** Arrow only one side filled.
+*/
+#define DK3_FIG_AS_INDENTED_FILLED_HALF 9
+
+/** Arrow only one side drawn (and filled).
+*/
+#define DK3_FIG_AS_CLOSED_HALF 10
+
+/** Arrow indented, only one side drawn (and filled).
+*/
+#define DK3_FIG_AS_INDENTED_HALF 11
+
+/** Arrow butted, only one side drawn (and filled).
+*/
+#define DK3_FIG_AS_BUTTED_HALF 12
+
+/** Line end with triangle fork or overstroke.
+*/
+#define DK3_FIG_AS_TRIANGLE_FORK 13
+
+/** Line end with forward or backward rectangle fork.
+*/
+#define DK3_FIG_AS_RECTANGLE_FORK 14
+
+/**@}*/
+
+
+
+/** @defgroup dk3figarrowfill Fig arrow head fill style */
+/**@{*/
+
+/** Hollow arrow head (white filled).
+*/
+#define DK3_FIG_AF_HOLLOW 0
+
+/** Filled arrow head.
+*/
+#define DK3_FIG_AF_FILLED 1
+
+/**@}*/
+
+
+/** @defgroup dk3figfonts Fig fonts */
+/**@{*/
+
+/** LaTeX font: Default font.
+*/
+#define DK3_FIG_FONT_LATEX_DEFAULT 0
+
+/** LaTeX font: Roman font.
+*/
+#define DK3_FIG_FONT_LATEX_ROMAN 1
+
+/** LaTeX font: Bold font (roman).
+*/
+#define DK3_FIG_FONT_LATEX_BOLD 2
+
+/** LaTeX font: Italic font (roman).
+*/
+#define DK3_FIG_FONT_LATEX_ITALIC 3
+
+/** LaTeX font: Sans-serif.
+*/
+#define DK3_FIG_FONT_LATEX_SANS_SERIF 4
+
+/** LaTeX font: Typewriter.
+*/
+#define DK3_FIG_FONT_LATEX_TYPEWRITER 5
+
+/**@}*/
+
+
+
+/** @defgroup dk3figfontflags Fig font flags */
+/**@{*/
+
+/** Rigid text (not scaled when scaling a compound).
+*/
+#define DK3_FIG_FONT_FLAG_RIGID 1
+
+/** LaTeX special text.
+*/
+#define DK3_FIG_FONT_FLAG_SPECIAL 2
+
+/** PS font in use (LaTeX font otherwise).
+*/
+#define DK3_FIG_FONT_FLAG_PS 4
+
+/** Hidden text.
+*/
+#define DK3_FIG_FONT_FLAG_HIDDEN 8
+
+/**@}*/
+
+
+
+/** @defgroup figsrctypes Fig source types */
+/**@{*/
+
+/** Creator software unknown.
+*/
+#define DK3_FIG_SRCTYPE_UNKNOWN (-1)
+
+/** Fig created by XFig.
+*/
+#define DK3_FIG_SRCTYPE_XFIG 0
+
+/** File created by jFig.
+*/
+#define DK3_FIG_SRCTYPE_JFIG 1
+
+/** File created by WinFIG.
+*/
+#define DK3_FIG_SRCTYPE_WINFIG 2
+
+/**@}*/
+
+
+
+/** @defgroup figreaderstates Fig reader states */
+/**@{*/
+
+/** Error occured.
+*/
+#define DK3_FIG_RD_STATE_ERROR (-1)
+
+/** Expecting file type line.
+*/
+#define DK3_FIG_RD_STATE_START 0
+
+/** Waiting for line containing orientation.
+*/
+#define DK3_FIG_RD_STATE_EXPECT_ORIENTATION 1
+
+/** Waiting for line containing justification.
+*/
+#define DK3_FIG_RD_STATE_EXPECT_JUSTIFICATION 2
+
+/** Waiting for line containing units.
+*/
+#define DK3_FIG_RD_STATE_EXPECT_UNITS 3
+
+/** Waiting for line containing paper size.
+*/
+#define DK3_FIG_RD_STATE_EXPECT_PAPERSIZE 4
+
+/** Waiting for line containing magnification.
+*/
+#define DK3_FIG_RD_STATE_EXPECT_MAGNIFICATION 5
+
+/** Waiting for line containing multiplage or singlepage.
+*/
+#define DK3_FIG_RD_STATE_EXPECT_MULTIPAGE 6
+
+/** Waiting for line containing transparent color number.
+*/
+#define DK3_FIG_RD_STATE_EXPECT_TRANSPARENT 7
+
+/** Waiting for line containing resolution and coordinate system.
+*/
+#define DK3_FIG_RD_STATE_EXPECT_RESOLUTION 8
+
+/** Ready to start a new object.
+*/
+#define DK3_FIG_RD_STATE_READY 9
+
+/** Expecting arc arrowhead forward.
+*/
+#define DK3_FIG_RD_STATE_ARC_ARROW_FORWARD 10
+
+/** Expecting arc arrowhead backward.
+*/
+#define DK3_FIG_RD_STATE_ARC_ARROW_BACKWARD 11
+
+/** Expecting polyline arrowhead forward.
+*/
+#define DK3_FIG_RD_STATE_PL_ARROW_FORWARD 12
+
+/** Expecting polyline arrowhead backward.
+*/
+#define DK3_FIG_RD_STATE_PL_ARROW_BACKWARD 13
+
+/** Expecting polyline image file name.
+*/
+#define DK3_FIG_RD_STATE_PL_IMAGE 14
+
+/** Expecting polyline point coordinates.
+*/
+#define DK3_FIG_RD_STATE_PL_POINTS 15
+
+/** Expecting spline arrowhead forward.
+*/
+#define DK3_FIG_RD_STATE_SP_ARROW_FORWARD 16
+
+/** Expecting spline arrowhead backward.
+*/
+#define DK3_FIG_RD_STATE_SP_ARROW_BACKWARD 17
+
+/** Expecting spline point coordinates.
+*/
+#define DK3_FIG_RD_STATE_SP_POINTS 18
+
+/** Expecting spline control values.
+*/
+#define DK3_FIG_RD_STATE_SP_CONTROL 19
+
+/**@}*/
+
+
+/** Fig polygon or polyline point.
+*/
+typedef struct {
+ double x; /**< X coordinate. */
+ double y; /**< Y coordinate. */
+} dk3_fig_poly_point_t;
+
+
+
+/** Fig X-spline point.
+*/
+typedef struct {
+ double x; /**< X coordinate. */
+ double y; /**< Y coordinate. */
+ double s; /**< Shape factor. */
+} dk3_fig_spline_point_t;
+
+
+
+/** One X-spline segment.
+*/
+typedef struct {
+ dk3_fig_spline_point_t a; /**< Left neighbour control point. */
+ dk3_fig_spline_point_t b; /**< Left endpoing of segment. */
+ dk3_fig_spline_point_t c; /**< Right endpoint of segment. */
+ dk3_fig_spline_point_t d; /**< Right neighbour control point. */
+ double pa; /**< Function parameter for A fct. */
+ double pb; /**< Function parameter for B fct. */
+ double pc; /**< Function parameter for C fct. */
+ double pd; /**< Function parameter for D fct. */
+ double qa; /**< Function parameter for A fct. */
+ double qb; /**< Function parameter for B fct. */
+ double qc; /**< Function parameter for C fct. */
+ double qd; /**< Function parameter for D fct. */
+ double duadt; /**< Window fct A du/dt. */
+ double dubdt; /**< Window fct B du/dt. */
+ double ducdt; /**< Window fct C du/dt. */
+ double duddt; /**< Window fct D du/dt. */
+ double x; /**< X result. */
+ double y; /**< Y result. */
+ double dxdt; /**< dx/dt result. */
+ double dydt; /**< dy/dt result. */
+ int cb; /**< Compatibility bug flag. */
+ int ha; /**< Flag: Have point A. */
+ int hd; /**< Flag: Have point D. */
+} dk3_xspline_segment_t;
+
+
+
+/** Fig arc details.
+*/
+typedef struct {
+ double xc; /**< X center. */
+ double yc; /**< Y center. */
+ double ra; /**< Radius. */
+ double x1; /**< First x. */
+ double y1; /**< First y. */
+ double x2; /**< Second x. */
+ double y2; /**< Second y. */
+ double x3; /**< Third x. */
+ double y3; /**< Third y. */
+ double as; /**< Start alpha (if arrowhead back). */
+ double ae; /**< End alpha (if arrowhead forward). */
+ unsigned char di; /**< Direction: 0x00=clockwise, 0x01=counter. */
+} dk3_fig_det_arc_t;
+
+
+
+/** Fig ellipse details.
+*/
+typedef struct {
+ double an; /**< Angle (rotation) in radians. */
+ double cx; /**< Center x position. */
+ double cy; /**< Center y position. */
+ double rx; /**< Radius x. */
+ double ry; /**< Radius y. */
+} dk3_fig_det_ell_t;
+
+
+
+/** Fig polygon/polyline details.
+*/
+typedef struct {
+ char const *fn; /**< File name for embedded image. */
+ dk3_fig_poly_point_t *po; /**< Point data. */
+ double ra; /**< Radius for arc boxes. */
+#if 1
+ double xs; /**< Start x (if arrowhead back). */
+ double ys; /**< Start y (if arrowhead back). */
+ double xe; /**< End x (if arrowhead forward). */
+ double ye; /**< End y (if arrowhead forward). */
+#endif
+ size_t np; /**< Number of points. */
+ int flf; /**< Flip flag. */
+} dk3_fig_det_pol_t;
+
+
+
+/** Fig spline details.
+*/
+typedef struct {
+ dk3_fig_spline_point_t *po; /**< Point data. */
+ double *fslc; /**< Full segment length cache. */
+ double ts; /**< Start t (if arrowhead back). */
+ double te; /**< End t (if arrowhead forward). */
+ size_t np; /**< Number of points. */
+} dk3_fig_det_spl_t;
+
+
+
+/** Fig text details.
+*/
+typedef struct {
+ char const *st; /**< String. */
+ double x; /**< X position. */
+ double y; /**< Y position. */
+ double an; /**< Rotation in radians. */
+ double fs; /**< Font size. */
+ double he; /**< Height. */
+ double wi; /**< Width. */
+ int fo; /**< Font, see @ref dk3figfonts. */
+ int ff; /**< Font flags, see @ref dk3figfontflags. */
+} dk3_fig_det_txt_t;
+
+
+
+/** Half-circle, used for arrowheads.
+*/
+typedef struct {
+ double cx; /**< Center point x. */
+ double cy; /**< Center point y. */
+ double ra; /**< Radius. */
+ double an; /**< Angle in radians, Fig space. */
+} dk3_fig_det_hci_t;
+
+
+
+/** Fig object details.
+*/
+typedef union {
+ dk3_fig_det_arc_t arc; /**< Arc details. */
+ dk3_fig_det_ell_t ell; /**< Ellipse details. */
+ dk3_fig_det_pol_t pol; /**< Polygon or polyline details. */
+ dk3_fig_det_spl_t spl; /**< Spline details. */
+ dk3_fig_det_txt_t txt; /**< Text details. */
+ dk3_fig_det_hci_t hci; /**< Half-circle for arrowhead. */
+} dk3_fig_obj_det_t;
+
+
+
+/** Fig arrow head.
+*/
+typedef struct {
+ void *o1; /**< Object 1 for arrowhead. */
+ void *o2; /**< Object 2 for arrowhead. */
+ double wi; /**< Width. */
+ double he; /**< Height. */
+ int as; /**< Style, see @ref dk3figarrowstyles. */
+ int af; /**< Fill style, see @ref dk3figarrowfill. */
+} dk3_fig_ah_t;
+
+
+
+/** Fig object.
+*/
+typedef struct {
+ dk3_fig_obj_det_t dt; /**< Object details, type-specific. */
+ dk3_fig_ah_t *af; /**< Arrow details forward. */
+ dk3_fig_ah_t *ab; /**< Arrow details backward. */
+ void *dsd; /**< Driver specific details. */
+ double sv; /**< Style value (1/80) inch. */
+ unsigned long li; /**< Line number of object definition. */
+ int la; /**< Layer number. */
+ int ot; /**< Object type, see @ref dk3figobjtypes. */
+ int st; /**< Object subtype, see @ref dk3figsubtypes. */
+ int lw; /**< Line width (1/80 inch). */
+ int pc; /**< Pen+text color, see @ref dk3figcolors. */
+ int fc; /**< Fill color, see @ref dk3figcolors. */
+ int fi; /**< Area fill type. */
+ int cs; /**< Cap style, see @ref dk3figlinecap. */
+ int js; /**< Join style, see @ref dk3figlinejoin. */
+ int ls; /**< Line style, see @ref dk3figlinestyles. */
+ unsigned char cl; /**< Flag: Closed object. */
+} dk3_fig_obj_t;
+
+
+
+/** Fig color.
+*/
+typedef struct {
+ int i; /**< Color number. */
+ int r; /**< Red component. */
+ int g; /**< Green component. */
+ int b; /**< Blue component. */
+} dk3_fig_color_t;
+
+
+
+/** Fig drawing.
+*/
+typedef struct {
+ dk3_bb_t bb; /**< Bounding box in Fig units. */
+ dkChar const * const *msg; /**< Localized Fig messages. */
+ dk3_app_t *app; /**< Application structure. */
+ dk3_sto_t *sobj; /**< Storage for objects. */
+ dk3_sto_it_t *iobj; /**< Iterator for objects storage. */
+ dk3_sto_t *scol; /**< Storage for colors. */
+ dk3_sto_it_t *icol; /**< Iterator for colors storage. */
+ dk3_fig_obj_t *cobj; /**< Current object. */
+ void *dsd; /**< Driver specific details. */
+ double res; /**< Resolution. */
+ double arcspp; /**< Spline points per arc. */
+ double splspp; /**< Spline points per interval. */
+ double xsprec; /**< Precision for iterations. */
+ double lwbp; /**< Base line width in bp. */
+ unsigned long lineno; /**< Line number. */
+ long lres; /**< Resolution as integer value. */
+ size_t cind; /**< Current point index. */
+ size_t xssbs; /**< X-spline segements Bezier segs. */
+ size_t qbs; /**< Quadrant Bezier segments. */
+ size_t minspp; /**< Minimum spline points for arc. */
+ size_t codi; /**< Color digits. */
+ int cxy; /**< Flag: Read x (0) or y (1). */
+ int ec; /**< Error code. */
+ int state; /**< Reader state. */
+ int transcol; /**< Transparent color. */
+ int srctype; /**< Source type. */
+ int coah; /**< Flag: Compatible arrowheads. */
+ int xsah; /**< Flag: X-spline arrowheads. */
+ int cosp; /**< Flag: Compatible splines. */
+ int cofop; /**< Flag: Compat filled open paths. */
+ int bbts; /**< Flag: Use text size for bb. */
+} dk3_fig_drawing_t;
+
+
+
+/** Fig document consisting of multiple pages.
+*/
+typedef struct {
+ dk3_sto_t *sdrw; /**< Storage for Fig drawings. */
+ dk3_sto_it_t *idrw; /**< Iterator through drawing storage. */
+} dk3_fig_writer_t;
+
+
+
+/** Graphics state.
+*/
+typedef struct {
+ dk3_rgb_color_t c1; /**< Current color or stroke color. */
+ dk3_rgb_color_t c2; /**< Non-stroking color if applicable. */
+ double lw; /**< Line width. */
+ double sv; /**< Style value. */
+ double slw; /**< Dash line width. */
+ double fs; /**< Font size. */
+ int lc; /**< Line cap, see @ref dk3figlinecap. */
+ int lj; /**< Line join, see @ref dk3figlinejoin. */
+ int ls; /**< Line style, see @ref dk3figlinestyles. */
+ int fn; /**< PS font number. */
+ int hc1; /**< Flag: c1 is set. */
+ int hc2; /**< Flag: c2 is set. */
+ int hlc; /**< Flag: lc is set. */
+ int hlj; /**< Flag: lj is set. */
+ int hlw; /**< Flag: lw is set. */
+ int hls; /**< Flag: ls is set. */
+ int hfn; /**< Flag: fn and fs set. */
+} dk3_graphics_state_t;
+
+
+
+/** Font as specified in the Fig file.
+*/
+typedef struct {
+ int psfont; /**< Flag: PS font (1) or LaTeX font (0). */
+ int fontno; /**< Font number. */
+ double fontsz; /**< Font size. */
+} dk3_fig_font_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+/*
+ dk3fig module
+ =============
+*/
+
+/** Get localized message texts.
+ @param app Application structure.
+ @return Pointer to localized message texts on success, NULL on error.
+*/
+dkChar const * const *
+dk3fig_get_localized_messages(dk3_app_t *app);
+
+/** Create a new drawing structure.
+ @param app Application structure, must not be NULL.
+ @param msg Localized messages texts from dk3fig module.
+ @return Pointer to new structure on success, NULL on error.
+*/
+dk3_fig_drawing_t *
+dk3fig_drawing_new(dk3_app_t *app, dkChar const * const *msg);
+
+/** Set detail options for drawing.
+ @param drw Drawing to set up.
+ @param xssbs Number of Bezier segments for each X-spline segment.
+ @param qbs Number of Bezier segments for a 90 degree arc.
+*/
+void
+dk3fig_set_options_bsegs(dk3_fig_drawing_t *drw, size_t xssbs, size_t qbs);
+
+/** Set base line width in bp.
+ @param drw Drawing to set up.
+ @param val New value.
+*/
+void
+dk3fig_set_options_lwbp(dk3_fig_drawing_t *drw, double val);
+
+/** Set flag for compatible arrowheads.
+ @param drw Drawing to set up.
+ @param val Flag value.
+*/
+void
+dk3fig_set_options_coah(dk3_fig_drawing_t *drw, int val);
+
+/** Set flag for X-spline arrowheads (only used, when compatible
+ arrowheads not used).
+ @param drw Drawing to set up.
+ @param val Flag value.
+*/
+void
+dk3fig_set_options_xsah(dk3_fig_drawing_t *drw, int val);
+
+/** Set flag for compatible splines (reproduce XFig/fig2dev interpolated
+ spline bug).
+ @param drw Drawing to set up.
+ @param val Flag value.
+*/
+void
+dk3fig_set_options_cosp(dk3_fig_drawing_t *drw, int val);
+
+/** Set flag for bounding box with text sizes.
+ @param drw Drawing to set up.
+ @param val Flag value.
+*/
+void
+dk3fig_set_options_bbts(dk3_fig_drawing_t *drw, int val);
+
+/** Set flag for compatible filled open paths.
+ @param drw Drawing to set up.
+ @param val Flag value.
+*/
+void
+dk3fig_set_options_cofop(dk3_fig_drawing_t *drw, int val);
+
+/** Set source type.
+ @param drw Drawing to set up.
+ @param val New source type value.
+*/
+void
+dk3fig_set_options_srctype(dk3_fig_drawing_t *drw, int val);
+
+/** Destroy drawing structure, release memory.
+ @param drw Structure to destroy.
+*/
+void
+dk3fig_drawing_delete(dk3_fig_drawing_t *drw);
+
+/** Destroy Fig object, release memory.
+ @param obj Object to destroy.
+*/
+void
+dk3fig_obj_delete(dk3_fig_obj_t *obj);
+
+/** Create new Fig object.
+ @param li Line number of object definition.
+ @param la Layer number.
+ @param ot Object type.
+ @param st Object subtype.
+ @param lw Line width.
+ @param pc Pen color.
+ @param fc Fill color.
+ @param fi Fill type.
+ @param cs Cap style.
+ @param js Join style.
+ @param ls Line style.
+ @param sv Style value.
+ @param af Flag: Arrowhead forward.
+ @param ab Flag: Arrowhead backward.
+ @param np Number of spline/polyline points.
+ @param txt Text string (for text objects).
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new object on success, NULL on error.
+*/
+dk3_fig_obj_t *
+dk3fig_obj_new(
+ unsigned long li,
+ int la,
+ int ot,
+ int st,
+ int lw,
+ int pc,
+ int fc,
+ int fi,
+ int cs,
+ int js,
+ int ls,
+ double sv,
+ int af,
+ int ab,
+ size_t np,
+ char const *txt,
+ dk3_app_t *app
+);
+
+/** Initialize Fig object.
+ @param obj Object to initialize.
+*/
+void
+dk3fig_obj_init(dk3_fig_obj_t *obj);
+
+/** Initialize graphics state data.
+ @param gs Graphics state structure to initialize.
+*/
+void
+dk3fig_gs_init(dk3_graphics_state_t *gs);
+
+/** Set arrowhead spline options.
+ @param drw Drawing to set up.
+ @param arcspp Number of X-spline segments per 90 degree arc.
+ @param splspp Number of X-spline segments per X-spline interval.
+ @param minspp Minimum number of X-spline intervals for arrowhead edge.
+*/
+void
+dk3fig_set_options_arrows(
+ dk3_fig_drawing_t *drw,
+ double arcspp,
+ double splspp,
+ size_t minspp
+);
+
+/** Set precision for X-splines iterations.
+ @param drw Drawing to set up.
+ @param prec Precision.
+*/
+void
+dk3fig_set_options_iteration_precision(
+ dk3_fig_drawing_t *drw,
+ double prec
+);
+
+/** Set number of digits for colors.
+ @param drw Drawing to set up.
+ @param codi Number of color digits.
+*/
+void
+dk3fig_set_options_codi(
+ dk3_fig_drawing_t *drw,
+ size_t codi
+);
+
+/** Set error code for drawing.
+ The new error code is set only if the current error code
+ of the drawing is 0 (indicates "no error found").
+ @param drw Drawing to set.
+ @param ec Error code to set.
+*/
+void
+dk3fig_set_ec(dk3_fig_drawing_t *drw, int ec);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+
+#include "dk3all.h"
+#include "dk3fig.h"
+
+
+$!trace-include
+
+
+
+/** Localized message texts.
+*/
+static dkChar const * const dk3fig_messages[] = {
+$!string-table macro=dkT
+#
+# 0: File name.
+#
+dk3fig.str
+#
+# 1: Syntax error in Fig input!
+#
+Syntax error in Fig input!
+#
+# 2: Color redefinition!
+#
+Color redefined!
+#
+# 3: Math problem in arc calculation!
+#
+Mathematical problem in arc calculation!
+#
+# 4: Object processing failed!
+#
+Object processing failed!
+#
+# 5: Arrowhead calculation failed!
+#
+Arrowhead calculation failed!
+#
+# 6: Error while reading input file!
+#
+Error while reading input file!
+#
+# 7: Color not found, using black as default color!
+#
+Color not found, using black as default color!
+#
+# 8: Unknown object type!
+#
+Unknown object type!
+#
+# 9: Can not fill open graphics path!
+#
+Can not fill open graphics path!
+#
+# 10: Converted to closed graphics path for filling.
+#
+Converted to closed graphics path for filling.
+$!end
+};
+
+
+
+
+dkChar const * const *
+dk3fig_get_localized_messages(dk3_app_t *app)
+{
+ dkChar const * const *back = NULL;
+ if(app) {
+ back = dk3app_messages(
+ app, dk3fig_messages[0], (dkChar const **)dk3fig_messages
+ );
+ }
+ return back;
+}
+
+
+
+/** Compare two text objects.
+ This function is used to sort text objects.
+ @param pl Left text object.
+ @param pr Right text object.
+ @return Comparison result.
+*/
+static
+int
+dk3fig_obj_text_compare(dk3_fig_obj_t const *pl, dk3_fig_obj_t const *pr)
+{
+ int back = 0;
+ /*
+ Non-special texts before special texts.
+ */
+ if(((pl->dt).txt.ff) & DK3_FIG_FONT_FLAG_SPECIAL) {
+ if(!(((pr->dt).txt.ff) & DK3_FIG_FONT_FLAG_SPECIAL)) {
+ back = 1;
+ }
+ } else {
+ if(((pr->dt).txt.ff) & DK3_FIG_FONT_FLAG_SPECIAL) {
+ back = -1;
+ }
+ }
+ /*
+ Font selection type.
+ */
+ if(0 == back) {
+ if(((pl->dt).txt.ff) & DK3_FIG_FONT_FLAG_PS) {
+ if(!(((pr->dt).txt.ff) & DK3_FIG_FONT_FLAG_PS)) {
+ back = 1;
+ }
+ } else {
+ if(((pr->dt).txt.ff) & DK3_FIG_FONT_FLAG_PS) {
+ back = -1;
+ }
+ }
+ }
+ /*
+ Font number.
+ */
+ if(0 == back) {
+ if((pl->dt).txt.fo > (pr->dt).txt.fo) {
+ back = 1;
+ } else {
+ if((pl->dt).txt.fo < (pr->dt).txt.fo) {
+ back = -1;
+ }
+ }
+ }
+ /*
+ Font size.
+ */
+ if(0 == back) {
+ if((pl->dt).txt.fs > (pr->dt).txt.fs) {
+ back = 1;
+ } else {
+ if((pl->dt).txt.fs < (pr->dt).txt.fs) {
+ back = -1;
+ }
+ }
+ }
+ /*
+ Text string.
+ */
+ if(0 == back) {
+ back = dk3str_c8_cmp((pl->dt).txt.st, (pr->dt).txt.st);
+ if(back < -1) back = -1;
+ if(back > 1) back = 1;
+ }
+ return back;
+}
+
+
+
+/** Compare two non-text objects.
+ @param pl Left object.
+ @param pr Right object.
+ @return Comparison result.
+*/
+static
+int
+dk3fig_obj_path_compare(dk3_fig_obj_t const *pl, dk3_fig_obj_t const *pr)
+{
+ int back = 0;
+ /*
+ Line width.
+ */
+ if(0 == back) {
+ if(pl->lw > pr->lw) { back = 1; }
+ else { if(pl->lw < pr->lw) { back = -1; } }
+ }
+ /*
+ Pen color.
+ */
+ if(0 == back) {
+ if(pl->pc > pr->pc) { back = 1; }
+ else { if(pl->pc < pr->pc) { back = -1; } }
+ }
+ /*
+ Line cap.
+ */
+ if(0 == back) {
+ if(pl->cs > pr->cs) { back = 1; }
+ else { if(pl->cs < pr->cs) { back = -1; } }
+ }
+ /*
+ Line join.
+ */
+ if(0 == back) {
+ if(pl->js > pr->js) { back = 1; }
+ else { if(pl->js < pr->js) { back = -1; } }
+ }
+ /*
+ Line style, style value for equal line style.
+ */
+ if(0 == back) {
+ if(pl->ls > pr->ls) { back = 1; }
+ else { if(pl->ls < pr->ls) { back = -1; } }
+ if(0 == back) {
+ if(pl->sv > pr->sv) { back = 1; }
+ else { if(pl->sv < pr->sv) { back = -1; } }
+ }
+ }
+ /*
+ Non-closed before closed.
+ */
+ if(0 == back) {
+ if(pl->cl) {
+ if(pr->cl) {
+ /*
+ Fill color.
+ */
+ if(pl->fc > pr->fc) { back = 1; }
+ else { if(pl->fc < pr->fc) { back = -1; } }
+ /*
+ Fill style.
+ */
+ if(0 == back) {
+ if(pl->fi > pr->fi) { back = 1; }
+ else { if(pl->fi < pr->fi) { back = -1; } }
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(pr->cl) {
+ back = -1;
+ }
+ }
+ }
+ /*
+ Object type.
+ */
+ if(0 == back) {
+ if(pl->ot > pr->ot) { back = 1; }
+ else { if(pl->ot < pr->ot) { back = -1; } }
+ }
+ /*
+ Sub type.
+ */
+ if(0 == back) {
+ if(pl->st > pr->st) { back = 1; }
+ else { if(pl->st < pr->st) { back = -1; } }
+ }
+ return back;
+}
+
+
+
+/** Compare two Fig objects for sorted storing.
+ We must draw the deepest layer elements first (by definition).
+ Additionally we sort elements by multiple attributes
+ (non-text elements before texts, pen color, fill color and type,
+ line style, line width, cap style, join style) to group elements
+ with equal attributes. This is done to minimize instructions
+ for writing colors, line style, line width...
+ @param l Left Fig object.
+ @param r Right Fig object.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+static
+int
+dk3fig_obj_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3_fig_obj_t const *pl;
+ dk3_fig_obj_t const *pr;
+ if(l) {
+ if(r) {
+ pl = (dk3_fig_obj_t const *)l;
+ pr = (dk3_fig_obj_t const *)r;
+ /*
+ Deepest layers first.
+ */
+ if(pl->la > pr->la) { back = -1; }
+ else { if(pl->la < pr->la) { back = 1; } }
+ /*
+ Non-texts before texts.
+ */
+ if(0 == back) {
+ if(DK3_FIG_OBJ_TEXT == pl->ot) {
+ if(!(DK3_FIG_OBJ_TEXT == pr->ot)) {
+ back = 1;
+ } else {
+ back = dk3fig_obj_text_compare(pl, pr);
+ }
+ } else {
+ if(DK3_FIG_OBJ_TEXT == pr->ot) {
+ back = -1;
+ } else {
+ back = dk3fig_obj_path_compare(pl, pr);
+ }
+ }
+ }
+ /*
+ Line number of definition.
+ */
+ if(0 == back) {
+ if(pl->li > pr->li) { back = 1; }
+ else { if(pl->li < pr->li) { back = -1; } }
+ }
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ }
+ return back;
+}
+
+
+
+/** Destroy arrowhead, release memory.
+ @param ah Arrowhead to destroy.
+*/
+static
+void
+dk3fig_ah_delete(dk3_fig_ah_t *ah)
+{
+ $? "+ dk3fig_ah_delete %!8s", TR_8PTR(ah)
+ if(ah) {
+ if(ah->o1) { $? ". Fig object 1"
+ dk3fig_obj_delete((dk3_fig_obj_t *)(ah->o1));
+ }
+ if(ah->o2) { $? ". Fig object 2"
+ dk3fig_obj_delete((dk3_fig_obj_t *)(ah->o2));
+ }
+ dk3_delete(ah);
+ } $? "- dk3fig_ah_delete"
+}
+
+
+
+/** Create new arrowhead structure.
+ @param app Application structure for diagnostics.
+ @return Pointer to new structure on success, NULL on error.
+*/
+static
+dk3_fig_ah_t *
+dk3fig_ah_new(dk3_app_t *app)
+{
+ dk3_fig_ah_t *back = NULL;
+ back = dk3_new_app(dk3_fig_ah_t,1,app);
+ if(back) {
+ back->o1 = NULL;
+ back->o2 = NULL;
+ back->wi = 0.0;
+ back->he = 0.0;
+ back->as = 0;
+ back->af = 0;
+ }
+ return back;
+}
+
+
+
+void
+dk3fig_obj_delete(dk3_fig_obj_t *obj)
+{
+ $? "+ dk3fig_obj_delete %!8s", TR_8PTR(obj)
+ if(obj) {
+ if(obj->af) { $? ". arrowhead forward"
+ dk3fig_ah_delete(obj->af);
+ }
+ if(obj->ab) { $? ". arrowhead backward"
+ dk3fig_ah_delete(obj->ab);
+ }
+ switch(obj->ot) {
+ case DK3_FIG_OBJ_TEXT: { $? ". text"
+ if((obj->dt).txt.st) {
+ dk3_release((obj->dt).txt.st);
+ }
+ } break;
+ case DK3_FIG_OBJ_SPLINE: { $? ". spline"
+ if((obj->dt).spl.po) {
+ dk3_release((obj->dt).spl.po);
+ }
+ if((obj->dt).spl.fslc) {
+ dk3_release((obj->dt).spl.fslc);
+ }
+ } break;
+ case DK3_FIG_OBJ_POLYLINE: { $? ". polyline"
+ if((obj->dt).pol.po) {
+ dk3_release((obj->dt).pol.po);
+ }
+ if((obj->dt).pol.fn) {
+ dk3_release((obj->dt).pol.fn);
+ }
+ } break;
+ }
+ obj->af = NULL;
+ obj->ab = NULL;
+ dk3_delete(obj);
+ } $? "- dk3fig_obj_delete"
+}
+
+
+
+/** Reset all members of a drawing object.
+ @param drw Drawing object to reset.
+*/
+static
+void
+dk3fig_initialize_empty_drawing(dk3_fig_drawing_t *drw)
+{
+ $? "+ dk3fig_initialize_empty_drawing %!8s", TR_8PTR(drw)
+ dk3bb_reset(&(drw->bb));
+ drw->msg = NULL;
+ drw->app = NULL;
+ drw->sobj = NULL;
+ drw->iobj = NULL;
+ drw->scol = NULL;
+ drw->icol = NULL;
+ drw->cobj = NULL;
+ drw->dsd = NULL;
+ drw->res = 1200.0;
+ drw->lineno = 0UL;
+ drw->lres = 0;
+ drw->cind = 0;
+ drw->cxy = 0;
+ drw->state = 0;
+ drw->ec = 0;
+ drw->srctype = DK3_FIG_SRCTYPE_UNKNOWN;
+ drw->xssbs = 8;
+ drw->qbs = 4;
+ drw->transcol = -2;
+ drw->coah = 0;
+ drw->xsah = 0;
+ drw->cosp = 0;
+ drw->cofop = 1;
+ drw->bbts = 0;
+ drw->arcspp = 8.0;
+ drw->splspp = 8.0;
+ drw->minspp = 4;
+ drw->codi = 3;
+ drw->xsprec = 0.04; /* originally 1200.0 / 25400.0 */
+ drw->lwbp = 0.9; /* 1/80 inch */
+ $? "- dk3fig_initialize_empty_drawing"
+}
+
+
+
+/** Compare two Fig colors.
+ @param l Left object.
+ @param r Right color object or number.
+ @param cr Comparison criteria (0=color/color, 1=color/number).
+ @return Comparison result.
+*/
+static
+int
+dk3fig_color_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3_fig_color_t const *pl;
+ dk3_fig_color_t const *pr;
+ int *ip;
+ if(l) {
+ if(r) {
+ pl = (dk3_fig_color_t const *)l;
+ pr = (dk3_fig_color_t const *)r;
+ ip = (int *)r;
+ switch(cr) {
+ case 1: {
+ if(pl->i > (*ip)) {
+ back = 1;
+ } else {
+ if(pl->i < (*ip)) {
+ back = -1;
+ }
+ }
+ } break;
+ default: {
+ if(pl->i > pr->i) {
+ back = 1;
+ } else {
+ if(pl->i < pr->i) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ }
+ return back;
+}
+
+
+dk3_fig_drawing_t *
+dk3fig_drawing_new(dk3_app_t *app, dkChar const * const *msg)
+{
+ dk3_fig_drawing_t *back = NULL;
+ $? "+ dk3fig_drawing_new %!8s", TR_8PTR(app)
+ if(app) {
+ back = dk3_new_app(dk3_fig_drawing_t,1,app);
+ if(back) {
+ dk3fig_initialize_empty_drawing(back);
+ back->app = app;
+ back->msg = msg;
+ back->sobj = dk3sto_open_app(app);
+ if(back->sobj) {
+ dk3sto_set_comp(back->sobj, dk3fig_obj_compare, 0);
+ back->iobj = dk3sto_it_open(back->sobj);
+ if(back->iobj) {
+ back->scol = dk3sto_open_app(app);
+ if(back->scol) {
+ dk3sto_set_comp(back->scol, dk3fig_color_compare, 0);
+ back->icol = dk3sto_it_open(back->scol);
+ if(back->icol) {
+ /* Place for further initialization here */
+ } else { $? "! memory color iterator"
+ dk3fig_drawing_delete(back);
+ back = NULL;
+ }
+ } else { $? "! memory color storage"
+ dk3fig_drawing_delete(back);
+ back = NULL;
+ }
+ } else { $? "! memory iterator"
+ dk3fig_drawing_delete(back);
+ back = NULL;
+ }
+ } else { $? "! memory storage"
+ dk3fig_drawing_delete(back);
+ back = NULL;
+ }
+ } else { $? "! memory"
+ }
+ } $? "- dk3fig_drawing_new %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+void
+dk3fig_drawing_delete(dk3_fig_drawing_t *drw)
+{
+ dk3_fig_color_t *co; /* Current color to release. */
+ dk3_fig_obj_t *po; /* Current Fig object to release. */
+ $? "+ dk3fig_drawing_delete %!8s", TR_8PTR(drw)
+ if(drw) {
+ /*
+ Remove all objects.
+ */
+ if(drw->sobj) {
+ if(drw->iobj) {
+ dk3sto_it_reset(drw->iobj);
+ while(NULL != (po = (dk3_fig_obj_t *)dk3sto_it_next(drw->iobj))) {
+ dk3fig_obj_delete(po);
+ }
+ dk3sto_it_close(drw->iobj);
+ }
+ dk3sto_close(drw->sobj);
+ }
+ /*
+ Remove all colors.
+ */
+ if(drw->scol) {
+ if(drw->icol) {
+ dk3sto_it_reset(drw->icol);
+ while(NULL != (co = (dk3_fig_color_t *)dk3sto_it_next(drw->icol))) {
+ $? ". delete color %d = %d %d %d", co->i, co->r, co->g, co->b
+ dk3_delete(co);
+ }
+ dk3sto_it_close(drw->icol);
+ }
+ dk3sto_close(drw->scol);
+ }
+ /*
+ Reset all members.
+ */
+ dk3fig_initialize_empty_drawing(drw);
+ /*
+ Release memory.
+ */
+ drw->app = NULL;
+ drw->msg = NULL;
+ dk3_delete(drw);
+ } $? "- dk3fig_drawing_delete"
+}
+
+
+
+/** Internal function to create Fig object and initialize it.
+ @param li Line number of object definition in file.
+ @param la Layer number.
+ @param ot Object type.
+ @param st Object subtype.
+ @param lw Line width.
+ @param pc Pen color.
+ @param fc Fill color.
+ @param fi Fill type.
+ @param cs Cap style.
+ @param js Join style.
+ @param ls Line style.
+ @param sv Style value.
+ @param af Flag: Arrowhead forward.
+ @param ab Flag: Arrowhead backward.
+ @param po Flag: Path object (non-text object).
+ @param cl Flag: Closed path object.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new object on success, NULL on error.
+*/
+static
+dk3_fig_obj_t *
+dk3fig_obj_internal_new(
+ unsigned long li,
+ int la,
+ int ot,
+ int st,
+ int lw,
+ int pc,
+ int fc,
+ int fi,
+ int cs,
+ int js,
+ int ls,
+ double sv,
+ int af,
+ int ab,
+ int po,
+ int cl,
+ dk3_app_t *app
+)
+{
+ dk3_fig_obj_t *back = NULL;
+ $? "+ dk3fig_obj_internal_new po = %d cl = %d", po, cl
+ back = dk3_new_app(dk3_fig_obj_t,1,app);
+ if(back) { $? ". allocation ok"
+ back->af = NULL;
+ back->ab = NULL;
+ back->dsd = NULL;
+ back->sv = sv;
+ back->li = li;
+ back->la = la;
+ back->ot = ot;
+ back->st = st;
+ back->lw = lw;
+ back->pc = pc;
+ back->fc = fc;
+ back->fi = fi;
+ back->cs = cs;
+ back->js = js;
+ back->ls = ls;
+ back->cl = ((cl) ? 0x01 : 0x00); $? ". here"
+ if(back->lw < 0) {
+ back->lw = 0;
+ if(po) { $? ". warning: illegal line width"
+ /* +++++ Warning: Illegal line width corrected! */
+ }
+ }
+ if(back->pc < -1) { $? ". warning: illegal pen color"
+ back->pc = -1;
+ /* +++++ Warning: Illegal pen color definition corrected! */
+ }
+ if(back->fc < DK3_FIG_COLOR_DEFAULT) {
+ back->fc = DK3_FIG_COLOR_DEFAULT;
+ if((po) && (cl)) { $? ". warning: illegal fill color"
+ /* +++++ Warning: Illegal fill color definition corrected! */
+ }
+ }
+ if(back->fi < DK3_FIG_COLOR_DEFAULT) {
+ back->fi = DK3_FIG_COLOR_DEFAULT;
+ if((po) && (cl)) { $? ". warning: illegal fill style"
+ /* +++++ Warning: Illegal fill style corrected! */
+ }
+ } else {
+ if(back->fi > 62) {
+ back->fi = 62;
+ if((po) && (cl)) { $? ". warning: illegal fill style"
+ /* +++++ Warning: Illegal fill style corrected! */
+ }
+ } else {
+ if((DK3_FIG_COLOR_BLACK == fc) || (DK3_FIG_COLOR_WHITE == fc)) {
+ if((back->fi >= 21) && (back->fi <= 40)) {
+ back->fi = 20;
+ if((po) && (cl)) { $? ". warning: illegal fill style"
+ /* +++++ Warning: Illegal fill style corrected! */
+ }
+ }
+ }
+ }
+ }
+ if(DK3_FIG_LC_BUTT != back->cs) {
+ if(DK3_FIG_LC_ROUND != back->cs) {
+ if(DK3_FIG_LC_PROJECTING != back->cs) {
+ back->cs = DK3_FIG_LC_BUTT;
+ if(po) { $? ". warning: illegal line cap"
+ /* +++++ Warning: Illegal line cap style corrected! */
+ }
+ }
+ }
+ }
+ if(DK3_FIG_LJ_MITER != back->js) {
+ if(DK3_FIG_LJ_ROUND != back->js) {
+ if(DK3_FIG_LJ_BEVEL != back->js) {
+ back->js = DK3_FIG_LJ_MITER;
+ if(po) { $? ". warning: illegal join style"
+ /* +++++ Warning: Illegal line join style corrected! */
+ }
+ }
+ }
+ }
+ if(back->ls < DK3_FIG_LS_SOLID) {
+ back->ls = DK3_FIG_LS_SOLID;
+ if(ls < DK3_FIG_LS_DEFAULT) {
+ if(po) { $? ". warning: illegal line style"
+ /* +++++ Warning: Illegal line style corrected! */
+ }
+ }
+ } else {
+ if(back->ls > DK3_FIG_LS_DASH_TRIPLE_DOTTED) {
+ back->ls = DK3_FIG_LS_SOLID;
+ if(po) { $? ". warning: illegal line style"
+ /* +++++ Warning: Illegal line style corrected! */
+ }
+ }
+ }
+ } else { $? "! allocation failed"
+ }
+ if((po) && (!(cl))) { $? ". open path"
+ if(NULL != back) {
+ if(af) { $? ". have arrowhead forward"
+ back->af = dk3fig_ah_new(app);
+ if(!(back->af)) {
+ dk3fig_obj_delete(back);
+ back = NULL;
+ }
+ }
+ }
+ if (NULL != back) {
+ if(ab) { $? ". have arrowhead backward"
+ back->ab = dk3fig_ah_new(app);
+ if(!(back->ab)) {
+ dk3fig_obj_delete(back);
+ back = NULL;
+ }
+ }
+ }
+ } else { $? ". closed path"
+ if((af) || (ab)) { $? "! arrowhead ignored for closed path"
+ /* +++++ Warning: Arrowhead ignored for closed path! */
+ }
+ } $? "- dk3fig_obj_internal_new %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+/** Initialize details for arc.
+ @param obj Object to initialize.
+*/
+static
+void
+dk3fig_initialize_arc_details(dk3_fig_obj_t *obj)
+{
+ (obj->dt).arc.xc = 0.0;
+ (obj->dt).arc.yc = 0.0;
+ (obj->dt).arc.ra = 0.0;
+ (obj->dt).arc.x1 = 0.0;
+ (obj->dt).arc.y1 = 0.0;
+ (obj->dt).arc.x2 = 0.0;
+ (obj->dt).arc.y2 = 0.0;
+ (obj->dt).arc.x3 = 0.0;
+ (obj->dt).arc.y3 = 0.0;
+ (obj->dt).arc.as = 0.0;
+ (obj->dt).arc.ae = 0.0;
+ (obj->dt).arc.di = 0x00;
+}
+
+
+
+/** Initialize ellipse details.
+ @param obj Object to initialize.
+*/
+static
+void
+dk3fig_initialize_ellipse_details(dk3_fig_obj_t *obj)
+{
+ (obj->dt).ell.an = 0.0;
+ (obj->dt).ell.cx = 0.0;
+ (obj->dt).ell.cy = 0.0;
+ (obj->dt).ell.rx = 0.0;
+ (obj->dt).ell.ry = 0.0;
+}
+
+
+
+/** Initialize polyline details.
+ @param obj Object to initialize.
+ @param np Number of points.
+ @param app Application structure for diagnostics.
+ @return 1 on success, 0 on error (not enough memory).
+*/
+static
+int
+dk3fig_initialize_polyline_details(dk3_fig_obj_t *obj,size_t np,dk3_app_t *app)
+{
+ int back = 0;
+ (obj->dt).pol.fn = NULL;
+ (obj->dt).pol.po = NULL;
+ (obj->dt).pol.ra = 0.0;
+ (obj->dt).pol.xs = 0.0;
+ (obj->dt).pol.ys = 0.0;
+ (obj->dt).pol.xe = 0.0;
+ (obj->dt).pol.ye = 0.0;
+ (obj->dt).pol.np = np;
+ (obj->dt).pol.flf = 0;
+ (obj->dt).pol.po = dk3_new_app(dk3_fig_poly_point_t,np,app);
+ if((obj->dt).pol.po) {
+ back = 1;
+ }
+ return back;
+}
+
+
+
+/** Initialize spline details.
+ @param obj Object to initialize.
+ @param np Number of spline points.
+ @param app Application structure for diagnostics.
+ @return 1 on success, 0 on error (not enough memory).
+*/
+static
+int
+dk3fig_initialize_spline_details(dk3_fig_obj_t *obj,size_t np,dk3_app_t *app)
+{
+ double *xptr;
+ size_t i;
+ int back = 0;
+ (obj->dt).spl.po = NULL;
+ (obj->dt).spl.fslc = NULL;
+ (obj->dt).spl.ts = -1.0;
+ (obj->dt).spl.te = -1.0;
+ (obj->dt).spl.np = np;
+ (obj->dt).spl.po = dk3_new_app(dk3_fig_spline_point_t, np, app);
+ if((obj->dt).spl.po) {
+ back = 1;
+ switch(obj->st) {
+ case 0: case 2: case 4: {
+ if(((obj->af) || (obj->ab)) && (2 <= np)) {
+ (obj->dt).spl.fslc = dk3_new_app(double, (np-1), app);
+ if((obj->dt).spl.fslc) {
+ /* Initialize cache to -1 */
+ xptr = (obj->dt).spl.fslc;
+ i = np - 1;
+ while(i--) { *(xptr++) = -1.0; }
+ } else {
+ back = 0;
+ }
+ }
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+/** Initialize text details.
+ @param obj Object to initialize.
+ @param tx Text for text object.
+ @param app Application structure for diagnostics.
+ @return 1 on success, 0 on error (not enough memory).
+*/
+static
+int
+dk3fig_initialize_text_details(dk3_fig_obj_t *obj,char const *tx,dk3_app_t *app)
+{
+ int back = 0;
+ (obj->dt).txt.st = NULL;
+ (obj->dt).txt.x = 0.0;
+ (obj->dt).txt.y = 0.0;
+ (obj->dt).txt.an = 0.0;
+ (obj->dt).txt.fs = 0.0;
+ (obj->dt).txt.he = 0.0;
+ (obj->dt).txt.wi = 0.0;
+ (obj->dt).txt.fo = 0;
+ (obj->dt).txt.ff = 0;
+ (obj->dt).txt.st = dk3str_c8_dup_app(tx, app);
+ if((obj->dt).txt.st) {
+ back = 1;
+ }
+ return back;
+}
+
+
+
+dk3_fig_obj_t *
+dk3fig_obj_new(
+ unsigned long li,
+ int la,
+ int ot,
+ int st,
+ int lw,
+ int pc,
+ int fc,
+ int fi,
+ int cs,
+ int js,
+ int ls,
+ double sv,
+ int af,
+ int ab,
+ size_t np,
+ char const *txt,
+ dk3_app_t *app
+)
+{
+ dk3_fig_obj_t *back = NULL;
+ $? "+ dk3fig_obj_new ot = %d st = %d", ot, st
+ if((la < 0) || (la > 999)) {
+ /* +++++ Warning: Illegal layer number! */
+ }
+ switch(ot) {
+ case DK3_FIG_OBJ_ARC: { $? ". arc"
+ switch(st) {
+ case DK3_FIG_OBJ_SUB_ARC_OPEN: { $? ". open arc"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 0, app
+ );
+ } break;
+ case DK3_FIG_OBJ_SUB_ARC_CLOSED: { $? ". closed arc"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app
+ );
+ } break;
+ case 0: { $? ". closed arc (jFig)"
+ /* +++++ Warning: jFig closed arc bug. */
+ back = dk3fig_obj_internal_new(
+ li, la, ot, DK3_FIG_OBJ_SUB_ARC_CLOSED,
+ lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 0, app
+ );
+ } break;
+ default: { $? "! unknown arc"
+ /* +++++ Warning: Illegal sub type corrected! */
+ back = dk3fig_obj_internal_new(
+ li, la, ot, DK3_FIG_OBJ_SUB_ARC_CLOSED,
+ lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 0, app
+ );
+ } break;
+ }
+ if(back) {
+ dk3fig_initialize_arc_details(back);
+ }
+ } break;
+ case DK3_FIG_OBJ_ELLIPSE: { $? ". ellipse"
+ switch(st) {
+ case DK3_FIG_OBJ_SUB_ELL_RADII: { $? ". ellipse by radii"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app
+ );
+ } break;
+ case DK3_FIG_OBJ_SUB_ELL_DIAMETERS: { $? ". ellipse by diameters"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app
+ );
+ } break;
+ case DK3_FIG_OBJ_SUB_CIR_RADIUS: { $? ". circle by radii"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app
+ );
+ } break;
+ case DK3_FIG_OBJ_SUB_CIR_DIAMETER: { $? ". circle by diameters"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app
+ );
+ } break;
+ default: { $? "! unknown ellipse type"
+ /* +++++ Warning: Illegal sub type corrected! */
+ back = dk3fig_obj_internal_new(
+ li, la, ot, DK3_FIG_OBJ_SUB_ELL_RADII,
+ lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app
+ );
+ } break;
+ }
+ if(back) {
+ dk3fig_initialize_ellipse_details(back);
+ }
+ } break;
+ case DK3_FIG_OBJ_POLYLINE: { $? ". polyline"
+ switch(st) {
+ case DK3_FIG_OBJ_SUB_POLYLINE: { $? ". polyline"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 0, app
+ );
+ } break;
+ case DK3_FIG_OBJ_SUB_BOX: { $? ". box"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app
+ );
+ } break;
+ case DK3_FIG_OBJ_SUB_POLYGON: { $? ". polygon"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app
+ );
+ } break;
+ case DK3_FIG_OBJ_SUB_ARCBOX: { $? ". arc box"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app
+ );
+ } break;
+ case DK3_FIG_OBJ_SUB_IMAGE: { $? ". image import"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app
+ );
+ } break;
+ default: { $? "! unknown polyline type"
+ /* +++++ Warning: Illegal sub type corrected! */
+ back = dk3fig_obj_internal_new(
+ li, la, ot, DK3_FIG_OBJ_SUB_POLYLINE,
+ lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 0, app
+ );
+ } break;
+ }
+ if(back) {
+ if(!dk3fig_initialize_polyline_details(back, np, app)) {
+ dk3fig_obj_delete(back);
+ back = NULL;
+ }
+ }
+ } break;
+ case DK3_FIG_OBJ_SPLINE: { $? ". spline"
+ switch(st) {
+ case DK3_FIG_OBJ_SUB_OPEN_APPRO: { $? ". open approximated"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 0, app
+ );
+ } break;
+ case DK3_FIG_OBJ_SUB_CLOSED_APPRO: { $? ". closed approximated"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app
+ );
+ } break;
+ case DK3_FIG_OBJ_SUB_OPEN_INT: { $? ". open interpolated"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 0, app
+ );
+ } break;
+ case DK3_FIG_OBJ_SUB_CLOSED_INT: { $? ". closed interpolated"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app
+ );
+ } break;
+ case DK3_FIG_OBJ_SUB_OPEN_X: { $? ". open x-spline"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 0, app
+ );
+ } break;
+ case DK3_FIG_OBJ_SUB_CLOSED_X: { $? ". closed x-spline"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 1, app
+ );
+ } break;
+ default: { $? "! unknown spline type"
+ /* +++++ Warning: Illegal sub type corrected! */
+ back = dk3fig_obj_internal_new(
+ li, la, ot, DK3_FIG_OBJ_SUB_OPEN_X,
+ lw, pc, fc, fi, cs, js, ls, sv, af, ab, 1, 0, app
+ );
+ } break;
+ }
+ if(back) {
+ if(!dk3fig_initialize_spline_details(back, np, app)) {
+ dk3fig_obj_delete(back);
+ back = NULL;
+ }
+ }
+ } break;
+ case DK3_FIG_OBJ_TEXT: { $? ". text"
+ if(txt) { $? ". string available"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, st, lw, pc, fc, fi, cs, js, ls, sv, af, ab, 0, 0, app
+ );
+ if(back) {
+ if(!dk3fig_initialize_text_details(back, txt, app)) {
+ dk3fig_obj_delete(back);
+ back = NULL;
+ }
+ }
+ } else { $? "! no text string available"
+ /* +++++ ERROR: No text specified! */
+ }
+ } break;
+ case DK3_FIG_OBJ_PSEUDO_HALF_CIRCLE: { $? ". half circle as arrowhead"
+ back = dk3fig_obj_internal_new(
+ li, la, ot, ((st) ? 1 : 0),
+ lw, pc, fc, fi, cs, js, ls, sv, af, ab, 0,
+ ((st) ? 1 : 0),
+ app
+ );
+ } break;
+ default: { $? "! unknown"
+ /* +++++ ERROR: Can not create object! */
+ } break;
+ } $? "- dk3fig_obj_new %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+void
+dk3fig_obj_init(dk3_fig_obj_t *obj)
+{
+ if(obj) {
+ dk3mem_res((void *)obj, sizeof(dk3_fig_obj_t));
+ obj->af = NULL;
+ obj->ab = NULL;
+ obj->dsd = NULL;
+ obj->sv = 0.0;
+ }
+}
+
+
+
+void
+dk3fig_set_options_bsegs(dk3_fig_drawing_t *drw, size_t xssbs, size_t qbs)
+{
+ if(drw) {
+ drw->xssbs = xssbs;
+ drw->qbs = qbs;
+ if(xssbs < 2) drw->xssbs = 2;
+ if(qbs < 2) drw->qbs = 2;
+ }
+}
+
+
+
+void
+dk3fig_set_options_lwbp(dk3_fig_drawing_t *drw, double val)
+{
+ if (drw) {
+ drw->lwbp = val;
+ }
+}
+
+
+
+void
+dk3fig_set_options_coah(dk3_fig_drawing_t *drw, int val)
+{
+ if(drw) {
+ drw->coah = ((val) ? 1 : 0);
+ }
+}
+
+
+
+void
+dk3fig_set_options_xsah(dk3_fig_drawing_t *drw, int val)
+{
+ if (drw) {
+ drw->xsah = ((val) ? 1 : 0);
+ }
+}
+
+
+
+void
+dk3fig_set_options_cosp(dk3_fig_drawing_t *drw, int val)
+{
+ if(drw) {
+ drw->cosp = ((val) ? 1 : 0);
+ }
+}
+
+
+
+void
+dk3fig_set_options_bbts(dk3_fig_drawing_t *drw, int val)
+{
+ if(drw) {
+ drw->bbts = ((val) ? 1 : 0);
+ }
+}
+
+
+
+void
+dk3fig_set_options_cofop(dk3_fig_drawing_t *drw, int val)
+{
+ if(drw) {
+ drw->cofop = ((val) ? 1 : 0);
+ }
+}
+
+
+
+void
+dk3fig_set_options_srctype(dk3_fig_drawing_t *drw, int val)
+{
+ if(drw) {
+ drw->srctype = val;
+ }
+}
+
+
+
+void
+dk3fig_set_options_arrows(
+ dk3_fig_drawing_t *drw,
+ double arcspp,
+ double splspp,
+ size_t minspp
+)
+{
+ if(drw) {
+ drw->arcspp = arcspp;
+ if(drw->arcspp < 2.0) { drw->arcspp = 2.0; }
+ drw->splspp = splspp;
+ if(drw->splspp < 2.0) { drw->splspp = 2.0; }
+ drw->minspp = minspp;
+ if(drw->minspp < 2) { drw->minspp = 2; }
+ }
+}
+
+
+
+void
+dk3fig_set_options_iteration_precision(
+ dk3_fig_drawing_t *drw,
+ double prec
+)
+{
+ if(drw) {
+ drw->xsprec = fabs(prec);
+ if(drw->xsprec < 1.0e-24) {
+ drw->xsprec = 1.0e-24;
+ }
+ }
+}
+
+
+void
+dk3fig_gs_init(dk3_graphics_state_t *gs)
+{
+ if(gs) {
+ (gs->c1).r = (gs->c1).g = (gs->c1).b = 0.0;
+ (gs->c2).r = (gs->c2).g = (gs->c2).b = 0.0;
+ gs->lw = -1.0;
+ gs->sv = -1.0;
+ gs->slw = -1.0;
+ gs->lc = gs->lj = gs->ls = 0;
+ gs->hc1 = gs->hc2 = gs->hlc = gs->hlj = gs->hlw = gs->hls = 0;
+ gs->hfn = 0; gs->fs = -1.0; gs->fn = -1;
+ }
+}
+
+
+
+void
+dk3fig_set_options_codi(
+ dk3_fig_drawing_t *drw,
+ size_t codi
+)
+{
+ if(drw) {
+ drw->codi = codi;
+ }
+}
+
+
+
+void
+dk3fig_set_ec(dk3_fig_drawing_t *drw, int ec)
+{
+ if(drw) {
+ if(0 == drw->ec) {
+ drw->ec = ec;
+ }
+ }
+}
+
+
diff --git a/support/dktools/dk3fig.h b/support/dktools/dk3fig.h
new file mode 100644
index 0000000000..62012559e5
--- /dev/null
+++ b/support/dktools/dk3fig.h
@@ -0,0 +1,1146 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3fig.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3fig.h Header file for the dk3fig module.
+*/
+
+#ifndef DK3FIG_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3FIG_H_INCLUDED 1
+
+
+#line 9 "dk3fig.ctr"
+
+#include <dk3all.h>
+#include <dk3bb.h>
+
+/** Maximum input line size for Fig file.
+ Although the Fig Format 3.2 specification does not set any limit for
+ line sizes in Fig files we want to provide a buffer for input lines,
+ so we must specify a buffer size.
+*/
+#define DK3_FIG_LINE_SIZE 1024
+
+
+/** Maximum difference to treat coordinates as equal.
+*/
+#define DK3_FIG_EPSILON 1.0e-6
+
+
+
+/** @defgroup dk3figoperations Draw operations. */
+/**@{*/
+/** Path operation: stroke.
+*/
+#define DK3_FIG_OP_STROKE 1
+
+/** Path operation: fill.
+*/
+#define DK3_FIG_OP_FILL 2
+
+/** Path operation: draw fill pattern.
+*/
+#define DK3_FIG_OP_PATTERN 4
+
+/**@}*/
+
+
+
+/** @defgroup dk3figcolors Fig colors */
+/**@{*/
+/** Use default color.
+*/
+#define DK3_FIG_COLOR_DEFAULT (-1)
+
+/** Black.
+*/
+#define DK3_FIG_COLOR_BLACK 0
+
+/** Blue.
+*/
+#define DK3_FIG_COLOR_BLUE 1
+
+/** Green.
+*/
+#define DK3_FIG_COLOR_GREEN 2
+
+/** Cyan.
+*/
+#define DK3_FIG_COLOR_CYAN 3
+
+/** Red.
+*/
+#define DK3_FIG_COLOR_RED 4
+
+/** Magenta.
+*/
+#define DK3_FIG_COLOR_MAGENTA 5
+
+/** Yellow.
+*/
+#define DK3_FIG_COLOR_YELLOW 6
+
+/** White.
+*/
+#define DK3_FIG_COLOR_WHITE 7
+
+/** Blue, 20 percent.
+*/
+#define DK3_FIG_COLOR_20_BLUE 8
+
+/** Blue, 40 percent.
+*/
+#define DK3_FIG_COLOR_40_BLUE 9
+
+/** Blue, 60 percent.
+*/
+#define DK3_FIG_COLOR_60_BLUE 10
+
+/** Blue, 80 percent.
+*/
+#define DK3_FIG_COLOR_80_BLUE 11
+
+/** Green, 25 percent.
+*/
+#define DK3_FIG_COLOR_25_GREEN 12
+
+/** Green, 50 percent.
+*/
+#define DK3_FIG_COLOR_50_GREEN 13
+
+/** Green, 75 percent.
+*/
+#define DK3_FIG_COLOR_75_GREEN 14
+
+/** Cyan, 25 percent.
+*/
+#define DK3_FIG_COLOR_25_CYAN 15
+
+/** Cyan, 50 percent.
+*/
+#define DK3_FIG_COLOR_50_CYAN 16
+
+/** Cyan, 75 percent.
+*/
+#define DK3_FIG_COLOR_75_CYAN 17
+
+/** Red, 25 percent.
+*/
+#define DK3_FIG_COLOR_25_RED 18
+
+/** Red, 50 percent.
+*/
+#define DK3_FIG_COLOR_50_RED 19
+
+/** Red, 75 percent.
+*/
+#define DK3_FIG_COLOR_75_RED 20
+
+/** Magenta, 25 percent.
+*/
+#define DK3_FIG_COLOR_25_MAGENTA 21
+
+/** Magenta, 50 percent.
+*/
+#define DK3_FIG_COLOR_50_MAGENTA 22
+
+/** Magenta, 75 percent.
+*/
+#define DK3_FIG_COLOR_75_MAGENTA 23
+
+/** Brown, 33 percent.
+*/
+#define DK3_FIG_COLOR_33_BROWN 24
+
+/** Brown, 66 percent.
+*/
+#define DK3_FIG_COLOR_66_BROWN 25
+
+/** Brown.
+*/
+#define DK3_FIG_COLOR_BROWN 26
+
+/** Pink, 25 percent.
+*/
+#define DK3_FIG_COLOR_25_PINK 27
+
+/** Pink, 50 percent.
+*/
+#define DK3_FIG_COLOR_50_PINK 28
+
+/** Pink, 75 percent.
+*/
+#define DK3_FIG_COLOR_75_PINK 29
+
+/** Pink.
+*/
+#define DK3_FIG_COLOR_PINK 30
+
+/** Gold.
+*/
+#define DK3_FIG_COLOR_GOLD 31
+
+/**@}*/
+
+
+
+/** @defgroup dk3figobjtypes Fig object types */
+/**@{*/
+/** Color definition.
+*/
+#define DK3_FIG_OBJ_COLOR 0
+
+/** Ellipse.
+*/
+#define DK3_FIG_OBJ_ELLIPSE 1
+
+/** Polyline, polygon.
+*/
+#define DK3_FIG_OBJ_POLYLINE 2
+
+/** Spline.
+*/
+#define DK3_FIG_OBJ_SPLINE 3
+
+/** Text.
+*/
+#define DK3_FIG_OBJ_TEXT 4
+
+/** Arc.
+*/
+#define DK3_FIG_OBJ_ARC 5
+
+/** Compound object. Compound objects are resolved while reading
+ the Fig file.
+*/
+#define DK3_FIG_OBJ_COMPOUND 6
+
+/** End of compound object.
+*/
+#define DK3_FIG_OBJ_ENDCOMPOUND (-6)
+
+/** Not in Fig format definition, used for arrowheads
+ 6/0 and 6/1.
+ Subtype 0: stroked only, 1: closed, filled.
+ The cl attribute must be set correctly.
+ This object type can not appear as primary object,
+ only in arrowheads.
+*/
+#define DK3_FIG_OBJ_PSEUDO_HALF_CIRCLE 100
+
+/** Not in Fig format definition, used for arrowheads.
+ Subtype 0: Open spline.
+ Subtype 1: Closed spline.
+ The cl attribute must be set correctly.
+ This object type can not appear as primary object,
+ only in arrowheads.
+*/
+#define DK3_FIG_OBJ_PSEUDO_FAST_SPLINE 101
+
+/**@}*/
+
+
+
+/** @defgroup dk3figsubtypes Fig object subtypes */
+/**@{*/
+
+/** Arc sub type: Open.
+*/
+#define DK3_FIG_OBJ_SUB_ARC_OPEN 1
+
+/** Arc sub type: Closed.
+*/
+#define DK3_FIG_OBJ_SUB_ARC_CLOSED 2
+
+/** Ellipse sub type: Defined by radii.
+*/
+#define DK3_FIG_OBJ_SUB_ELL_RADII 1
+
+/** Ellipse sub type: Defined by diameters.
+*/
+#define DK3_FIG_OBJ_SUB_ELL_DIAMETERS 2
+
+/** Ellipse sub type: Circle defined by radius.
+*/
+#define DK3_FIG_OBJ_SUB_CIR_RADIUS 3
+
+/** Ellipse sub type: Circle defined by diameter.
+*/
+#define DK3_FIG_OBJ_SUB_CIR_DIAMETER 4
+
+/** Polyline sub type: Polyline.
+*/
+#define DK3_FIG_OBJ_SUB_POLYLINE 1
+
+/** Polyline sub type: Box.
+*/
+#define DK3_FIG_OBJ_SUB_BOX 2
+
+/** Polyline sub type: Polygon.
+*/
+#define DK3_FIG_OBJ_SUB_POLYGON 3
+
+/** Polyline sub type: Arc-box.
+*/
+#define DK3_FIG_OBJ_SUB_ARCBOX 4
+
+/** Polyline sub type: Embedded image.
+*/
+#define DK3_FIG_OBJ_SUB_IMAGE 5
+
+/** Spline sub type: Open approximated spline.
+*/
+#define DK3_FIG_OBJ_SUB_OPEN_APPRO 0
+
+/** Spline sub type: Closed approximated spline.
+*/
+#define DK3_FIG_OBJ_SUB_CLOSED_APPRO 1
+
+/** Spline sub type: Open interpolated spline.
+*/
+#define DK3_FIG_OBJ_SUB_OPEN_INT 2
+
+/** Spline sub type: Closed interpolated spline.
+*/
+#define DK3_FIG_OBJ_SUB_CLOSED_INT 3
+
+/** Spline sub type: Open X-spline.
+*/
+#define DK3_FIG_OBJ_SUB_OPEN_X 4
+
+/** Spline sub type: Closed X-spline.
+*/
+#define DK3_FIG_OBJ_SUB_CLOSED_X 5
+
+/**@}*/
+
+
+/** @defgroup dk3figlinestyles Fig line styles */
+/**@{*/
+
+/** Default line style.
+*/
+#define DK3_FIG_LS_DEFAULT (-1)
+
+/** Solid line.
+*/
+#define DK3_FIG_LS_SOLID 0
+
+/** Dashed line.
+*/
+#define DK3_FIG_LS_DASHED 1
+
+/** Dotted line.
+*/
+#define DK3_FIG_LS_DOTTED 2
+
+/** Dash dot line.
+*/
+#define DK3_FIG_LS_DASH_DOTTED 3
+
+/** Dash dot dot line.
+*/
+#define DK3_FIG_LS_DASH_DOUBLE_DOTTED 4
+
+/** Dash dot dot dot line.
+*/
+#define DK3_FIG_LS_DASH_TRIPLE_DOTTED 5
+
+/**@}*/
+
+
+
+/** @defgroup dk3figlinejoin Line join style */
+/**@{*/
+
+/** Mitered line join.
+*/
+#define DK3_FIG_LJ_MITER 0
+
+/** Rounded line join.
+*/
+#define DK3_FIG_LJ_ROUND 1
+
+/** Beveled line join.
+*/
+#define DK3_FIG_LJ_BEVEL 2
+
+/**@}*/
+
+
+
+/** @defgroup dk3figlinecap Fig line cap style */
+/**@{*/
+
+/** Butted line cap.
+*/
+#define DK3_FIG_LC_BUTT 0
+
+/** Rounded line cap.
+*/
+#define DK3_FIG_LC_ROUND 1
+
+/** Projecting line cap.
+*/
+#define DK3_FIG_LC_PROJECTING 2
+
+/**@}*/
+
+
+
+/** @defgroup dk3figarrowstyles Fig arrow styles */
+/**@{*/
+
+/** Polyline arrow head.
+*/
+#define DK3_FIG_AS_STICK 0
+
+/** Polygon arrow head.
+*/
+#define DK3_FIG_AS_CLOSED 1
+
+/** Arrow with indented butt.
+*/
+#define DK3_FIG_AS_INDENTED 2
+
+/** Arrow with pointed butt.
+*/
+#define DK3_FIG_AS_POINTED 3
+
+/** Arrow with rhombus.
+*/
+#define DK3_FIG_AS_RHOMBUS 4
+
+/** Line end with circle.
+*/
+#define DK3_FIG_AS_FULL_CIRCLE_END 5
+
+/** Line end with half circle.
+*/
+#define DK3_FIG_AS_HALF_CIRCLE_END 6
+
+/** Line end with rectangle.
+*/
+#define DK3_FIG_AS_RECTANGLE 7
+
+/** Arrow inverted arrowhead.
+*/
+#define DK3_FIG_AS_INVERSE 8
+
+/** Arrow only one side filled.
+*/
+#define DK3_FIG_AS_INDENTED_FILLED_HALF 9
+
+/** Arrow only one side drawn (and filled).
+*/
+#define DK3_FIG_AS_CLOSED_HALF 10
+
+/** Arrow indented, only one side drawn (and filled).
+*/
+#define DK3_FIG_AS_INDENTED_HALF 11
+
+/** Arrow butted, only one side drawn (and filled).
+*/
+#define DK3_FIG_AS_BUTTED_HALF 12
+
+/** Line end with triangle fork or overstroke.
+*/
+#define DK3_FIG_AS_TRIANGLE_FORK 13
+
+/** Line end with forward or backward rectangle fork.
+*/
+#define DK3_FIG_AS_RECTANGLE_FORK 14
+
+/**@}*/
+
+
+
+/** @defgroup dk3figarrowfill Fig arrow head fill style */
+/**@{*/
+
+/** Hollow arrow head (white filled).
+*/
+#define DK3_FIG_AF_HOLLOW 0
+
+/** Filled arrow head.
+*/
+#define DK3_FIG_AF_FILLED 1
+
+/**@}*/
+
+
+/** @defgroup dk3figfonts Fig fonts */
+/**@{*/
+
+/** LaTeX font: Default font.
+*/
+#define DK3_FIG_FONT_LATEX_DEFAULT 0
+
+/** LaTeX font: Roman font.
+*/
+#define DK3_FIG_FONT_LATEX_ROMAN 1
+
+/** LaTeX font: Bold font (roman).
+*/
+#define DK3_FIG_FONT_LATEX_BOLD 2
+
+/** LaTeX font: Italic font (roman).
+*/
+#define DK3_FIG_FONT_LATEX_ITALIC 3
+
+/** LaTeX font: Sans-serif.
+*/
+#define DK3_FIG_FONT_LATEX_SANS_SERIF 4
+
+/** LaTeX font: Typewriter.
+*/
+#define DK3_FIG_FONT_LATEX_TYPEWRITER 5
+
+/**@}*/
+
+
+
+/** @defgroup dk3figfontflags Fig font flags */
+/**@{*/
+
+/** Rigid text (not scaled when scaling a compound).
+*/
+#define DK3_FIG_FONT_FLAG_RIGID 1
+
+/** LaTeX special text.
+*/
+#define DK3_FIG_FONT_FLAG_SPECIAL 2
+
+/** PS font in use (LaTeX font otherwise).
+*/
+#define DK3_FIG_FONT_FLAG_PS 4
+
+/** Hidden text.
+*/
+#define DK3_FIG_FONT_FLAG_HIDDEN 8
+
+/**@}*/
+
+
+
+/** @defgroup figsrctypes Fig source types */
+/**@{*/
+
+/** Creator software unknown.
+*/
+#define DK3_FIG_SRCTYPE_UNKNOWN (-1)
+
+/** Fig created by XFig.
+*/
+#define DK3_FIG_SRCTYPE_XFIG 0
+
+/** File created by jFig.
+*/
+#define DK3_FIG_SRCTYPE_JFIG 1
+
+/** File created by WinFIG.
+*/
+#define DK3_FIG_SRCTYPE_WINFIG 2
+
+/**@}*/
+
+
+
+/** @defgroup figreaderstates Fig reader states */
+/**@{*/
+
+/** Error occured.
+*/
+#define DK3_FIG_RD_STATE_ERROR (-1)
+
+/** Expecting file type line.
+*/
+#define DK3_FIG_RD_STATE_START 0
+
+/** Waiting for line containing orientation.
+*/
+#define DK3_FIG_RD_STATE_EXPECT_ORIENTATION 1
+
+/** Waiting for line containing justification.
+*/
+#define DK3_FIG_RD_STATE_EXPECT_JUSTIFICATION 2
+
+/** Waiting for line containing units.
+*/
+#define DK3_FIG_RD_STATE_EXPECT_UNITS 3
+
+/** Waiting for line containing paper size.
+*/
+#define DK3_FIG_RD_STATE_EXPECT_PAPERSIZE 4
+
+/** Waiting for line containing magnification.
+*/
+#define DK3_FIG_RD_STATE_EXPECT_MAGNIFICATION 5
+
+/** Waiting for line containing multiplage or singlepage.
+*/
+#define DK3_FIG_RD_STATE_EXPECT_MULTIPAGE 6
+
+/** Waiting for line containing transparent color number.
+*/
+#define DK3_FIG_RD_STATE_EXPECT_TRANSPARENT 7
+
+/** Waiting for line containing resolution and coordinate system.
+*/
+#define DK3_FIG_RD_STATE_EXPECT_RESOLUTION 8
+
+/** Ready to start a new object.
+*/
+#define DK3_FIG_RD_STATE_READY 9
+
+/** Expecting arc arrowhead forward.
+*/
+#define DK3_FIG_RD_STATE_ARC_ARROW_FORWARD 10
+
+/** Expecting arc arrowhead backward.
+*/
+#define DK3_FIG_RD_STATE_ARC_ARROW_BACKWARD 11
+
+/** Expecting polyline arrowhead forward.
+*/
+#define DK3_FIG_RD_STATE_PL_ARROW_FORWARD 12
+
+/** Expecting polyline arrowhead backward.
+*/
+#define DK3_FIG_RD_STATE_PL_ARROW_BACKWARD 13
+
+/** Expecting polyline image file name.
+*/
+#define DK3_FIG_RD_STATE_PL_IMAGE 14
+
+/** Expecting polyline point coordinates.
+*/
+#define DK3_FIG_RD_STATE_PL_POINTS 15
+
+/** Expecting spline arrowhead forward.
+*/
+#define DK3_FIG_RD_STATE_SP_ARROW_FORWARD 16
+
+/** Expecting spline arrowhead backward.
+*/
+#define DK3_FIG_RD_STATE_SP_ARROW_BACKWARD 17
+
+/** Expecting spline point coordinates.
+*/
+#define DK3_FIG_RD_STATE_SP_POINTS 18
+
+/** Expecting spline control values.
+*/
+#define DK3_FIG_RD_STATE_SP_CONTROL 19
+
+/**@}*/
+
+
+/** Fig polygon or polyline point.
+*/
+typedef struct {
+ double x; /**< X coordinate. */
+ double y; /**< Y coordinate. */
+} dk3_fig_poly_point_t;
+
+
+
+/** Fig X-spline point.
+*/
+typedef struct {
+ double x; /**< X coordinate. */
+ double y; /**< Y coordinate. */
+ double s; /**< Shape factor. */
+} dk3_fig_spline_point_t;
+
+
+
+/** One X-spline segment.
+*/
+typedef struct {
+ dk3_fig_spline_point_t a; /**< Left neighbour control point. */
+ dk3_fig_spline_point_t b; /**< Left endpoing of segment. */
+ dk3_fig_spline_point_t c; /**< Right endpoint of segment. */
+ dk3_fig_spline_point_t d; /**< Right neighbour control point. */
+ double pa; /**< Function parameter for A fct. */
+ double pb; /**< Function parameter for B fct. */
+ double pc; /**< Function parameter for C fct. */
+ double pd; /**< Function parameter for D fct. */
+ double qa; /**< Function parameter for A fct. */
+ double qb; /**< Function parameter for B fct. */
+ double qc; /**< Function parameter for C fct. */
+ double qd; /**< Function parameter for D fct. */
+ double duadt; /**< Window fct A du/dt. */
+ double dubdt; /**< Window fct B du/dt. */
+ double ducdt; /**< Window fct C du/dt. */
+ double duddt; /**< Window fct D du/dt. */
+ double x; /**< X result. */
+ double y; /**< Y result. */
+ double dxdt; /**< dx/dt result. */
+ double dydt; /**< dy/dt result. */
+ int cb; /**< Compatibility bug flag. */
+ int ha; /**< Flag: Have point A. */
+ int hd; /**< Flag: Have point D. */
+} dk3_xspline_segment_t;
+
+
+
+/** Fig arc details.
+*/
+typedef struct {
+ double xc; /**< X center. */
+ double yc; /**< Y center. */
+ double ra; /**< Radius. */
+ double x1; /**< First x. */
+ double y1; /**< First y. */
+ double x2; /**< Second x. */
+ double y2; /**< Second y. */
+ double x3; /**< Third x. */
+ double y3; /**< Third y. */
+ double as; /**< Start alpha (if arrowhead back). */
+ double ae; /**< End alpha (if arrowhead forward). */
+ unsigned char di; /**< Direction: 0x00=clockwise, 0x01=counter. */
+} dk3_fig_det_arc_t;
+
+
+
+/** Fig ellipse details.
+*/
+typedef struct {
+ double an; /**< Angle (rotation) in radians. */
+ double cx; /**< Center x position. */
+ double cy; /**< Center y position. */
+ double rx; /**< Radius x. */
+ double ry; /**< Radius y. */
+} dk3_fig_det_ell_t;
+
+
+
+/** Fig polygon/polyline details.
+*/
+typedef struct {
+ char const *fn; /**< File name for embedded image. */
+ dk3_fig_poly_point_t *po; /**< Point data. */
+ double ra; /**< Radius for arc boxes. */
+#if 1
+ double xs; /**< Start x (if arrowhead back). */
+ double ys; /**< Start y (if arrowhead back). */
+ double xe; /**< End x (if arrowhead forward). */
+ double ye; /**< End y (if arrowhead forward). */
+#endif
+ size_t np; /**< Number of points. */
+ int flf; /**< Flip flag. */
+} dk3_fig_det_pol_t;
+
+
+
+/** Fig spline details.
+*/
+typedef struct {
+ dk3_fig_spline_point_t *po; /**< Point data. */
+ double *fslc; /**< Full segment length cache. */
+ double ts; /**< Start t (if arrowhead back). */
+ double te; /**< End t (if arrowhead forward). */
+ size_t np; /**< Number of points. */
+} dk3_fig_det_spl_t;
+
+
+
+/** Fig text details.
+*/
+typedef struct {
+ char const *st; /**< String. */
+ double x; /**< X position. */
+ double y; /**< Y position. */
+ double an; /**< Rotation in radians. */
+ double fs; /**< Font size. */
+ double he; /**< Height. */
+ double wi; /**< Width. */
+ int fo; /**< Font, see @ref dk3figfonts. */
+ int ff; /**< Font flags, see @ref dk3figfontflags. */
+} dk3_fig_det_txt_t;
+
+
+
+/** Half-circle, used for arrowheads.
+*/
+typedef struct {
+ double cx; /**< Center point x. */
+ double cy; /**< Center point y. */
+ double ra; /**< Radius. */
+ double an; /**< Angle in radians, Fig space. */
+} dk3_fig_det_hci_t;
+
+
+
+/** Fig object details.
+*/
+typedef union {
+ dk3_fig_det_arc_t arc; /**< Arc details. */
+ dk3_fig_det_ell_t ell; /**< Ellipse details. */
+ dk3_fig_det_pol_t pol; /**< Polygon or polyline details. */
+ dk3_fig_det_spl_t spl; /**< Spline details. */
+ dk3_fig_det_txt_t txt; /**< Text details. */
+ dk3_fig_det_hci_t hci; /**< Half-circle for arrowhead. */
+} dk3_fig_obj_det_t;
+
+
+
+/** Fig arrow head.
+*/
+typedef struct {
+ void *o1; /**< Object 1 for arrowhead. */
+ void *o2; /**< Object 2 for arrowhead. */
+ double wi; /**< Width. */
+ double he; /**< Height. */
+ int as; /**< Style, see @ref dk3figarrowstyles. */
+ int af; /**< Fill style, see @ref dk3figarrowfill. */
+} dk3_fig_ah_t;
+
+
+
+/** Fig object.
+*/
+typedef struct {
+ dk3_fig_obj_det_t dt; /**< Object details, type-specific. */
+ dk3_fig_ah_t *af; /**< Arrow details forward. */
+ dk3_fig_ah_t *ab; /**< Arrow details backward. */
+ void *dsd; /**< Driver specific details. */
+ double sv; /**< Style value (1/80) inch. */
+ unsigned long li; /**< Line number of object definition. */
+ int la; /**< Layer number. */
+ int ot; /**< Object type, see @ref dk3figobjtypes. */
+ int st; /**< Object subtype, see @ref dk3figsubtypes. */
+ int lw; /**< Line width (1/80 inch). */
+ int pc; /**< Pen+text color, see @ref dk3figcolors. */
+ int fc; /**< Fill color, see @ref dk3figcolors. */
+ int fi; /**< Area fill type. */
+ int cs; /**< Cap style, see @ref dk3figlinecap. */
+ int js; /**< Join style, see @ref dk3figlinejoin. */
+ int ls; /**< Line style, see @ref dk3figlinestyles. */
+ unsigned char cl; /**< Flag: Closed object. */
+} dk3_fig_obj_t;
+
+
+
+/** Fig color.
+*/
+typedef struct {
+ int i; /**< Color number. */
+ int r; /**< Red component. */
+ int g; /**< Green component. */
+ int b; /**< Blue component. */
+} dk3_fig_color_t;
+
+
+
+/** Fig drawing.
+*/
+typedef struct {
+ dk3_bb_t bb; /**< Bounding box in Fig units. */
+ dkChar const * const *msg; /**< Localized Fig messages. */
+ dk3_app_t *app; /**< Application structure. */
+ dk3_sto_t *sobj; /**< Storage for objects. */
+ dk3_sto_it_t *iobj; /**< Iterator for objects storage. */
+ dk3_sto_t *scol; /**< Storage for colors. */
+ dk3_sto_it_t *icol; /**< Iterator for colors storage. */
+ dk3_fig_obj_t *cobj; /**< Current object. */
+ void *dsd; /**< Driver specific details. */
+ double res; /**< Resolution. */
+ double arcspp; /**< Spline points per arc. */
+ double splspp; /**< Spline points per interval. */
+ double xsprec; /**< Precision for iterations. */
+ double lwbp; /**< Base line width in bp. */
+ unsigned long lineno; /**< Line number. */
+ long lres; /**< Resolution as integer value. */
+ size_t cind; /**< Current point index. */
+ size_t xssbs; /**< X-spline segements Bezier segs. */
+ size_t qbs; /**< Quadrant Bezier segments. */
+ size_t minspp; /**< Minimum spline points for arc. */
+ size_t codi; /**< Color digits. */
+ int cxy; /**< Flag: Read x (0) or y (1). */
+ int ec; /**< Error code. */
+ int state; /**< Reader state. */
+ int transcol; /**< Transparent color. */
+ int srctype; /**< Source type. */
+ int coah; /**< Flag: Compatible arrowheads. */
+ int xsah; /**< Flag: X-spline arrowheads. */
+ int cosp; /**< Flag: Compatible splines. */
+ int cofop; /**< Flag: Compat filled open paths. */
+ int bbts; /**< Flag: Use text size for bb. */
+} dk3_fig_drawing_t;
+
+
+
+/** Fig document consisting of multiple pages.
+*/
+typedef struct {
+ dk3_sto_t *sdrw; /**< Storage for Fig drawings. */
+ dk3_sto_it_t *idrw; /**< Iterator through drawing storage. */
+} dk3_fig_writer_t;
+
+
+
+/** Graphics state.
+*/
+typedef struct {
+ dk3_rgb_color_t c1; /**< Current color or stroke color. */
+ dk3_rgb_color_t c2; /**< Non-stroking color if applicable. */
+ double lw; /**< Line width. */
+ double sv; /**< Style value. */
+ double slw; /**< Dash line width. */
+ double fs; /**< Font size. */
+ int lc; /**< Line cap, see @ref dk3figlinecap. */
+ int lj; /**< Line join, see @ref dk3figlinejoin. */
+ int ls; /**< Line style, see @ref dk3figlinestyles. */
+ int fn; /**< PS font number. */
+ int hc1; /**< Flag: c1 is set. */
+ int hc2; /**< Flag: c2 is set. */
+ int hlc; /**< Flag: lc is set. */
+ int hlj; /**< Flag: lj is set. */
+ int hlw; /**< Flag: lw is set. */
+ int hls; /**< Flag: ls is set. */
+ int hfn; /**< Flag: fn and fs set. */
+} dk3_graphics_state_t;
+
+
+
+/** Font as specified in the Fig file.
+*/
+typedef struct {
+ int psfont; /**< Flag: PS font (1) or LaTeX font (0). */
+ int fontno; /**< Font number. */
+ double fontsz; /**< Font size. */
+} dk3_fig_font_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+/*
+ dk3fig module
+ =============
+*/
+
+/** Get localized message texts.
+ @param app Application structure.
+ @return Pointer to localized message texts on success, NULL on error.
+*/
+dkChar const * const *
+dk3fig_get_localized_messages(dk3_app_t *app);
+
+/** Create a new drawing structure.
+ @param app Application structure, must not be NULL.
+ @param msg Localized messages texts from dk3fig module.
+ @return Pointer to new structure on success, NULL on error.
+*/
+dk3_fig_drawing_t *
+dk3fig_drawing_new(dk3_app_t *app, dkChar const * const *msg);
+
+/** Set detail options for drawing.
+ @param drw Drawing to set up.
+ @param xssbs Number of Bezier segments for each X-spline segment.
+ @param qbs Number of Bezier segments for a 90 degree arc.
+*/
+void
+dk3fig_set_options_bsegs(dk3_fig_drawing_t *drw, size_t xssbs, size_t qbs);
+
+/** Set base line width in bp.
+ @param drw Drawing to set up.
+ @param val New value.
+*/
+void
+dk3fig_set_options_lwbp(dk3_fig_drawing_t *drw, double val);
+
+/** Set flag for compatible arrowheads.
+ @param drw Drawing to set up.
+ @param val Flag value.
+*/
+void
+dk3fig_set_options_coah(dk3_fig_drawing_t *drw, int val);
+
+/** Set flag for X-spline arrowheads (only used, when compatible
+ arrowheads not used).
+ @param drw Drawing to set up.
+ @param val Flag value.
+*/
+void
+dk3fig_set_options_xsah(dk3_fig_drawing_t *drw, int val);
+
+/** Set flag for compatible splines (reproduce XFig/fig2dev interpolated
+ spline bug).
+ @param drw Drawing to set up.
+ @param val Flag value.
+*/
+void
+dk3fig_set_options_cosp(dk3_fig_drawing_t *drw, int val);
+
+/** Set flag for bounding box with text sizes.
+ @param drw Drawing to set up.
+ @param val Flag value.
+*/
+void
+dk3fig_set_options_bbts(dk3_fig_drawing_t *drw, int val);
+
+/** Set flag for compatible filled open paths.
+ @param drw Drawing to set up.
+ @param val Flag value.
+*/
+void
+dk3fig_set_options_cofop(dk3_fig_drawing_t *drw, int val);
+
+/** Set source type.
+ @param drw Drawing to set up.
+ @param val New source type value.
+*/
+void
+dk3fig_set_options_srctype(dk3_fig_drawing_t *drw, int val);
+
+/** Destroy drawing structure, release memory.
+ @param drw Structure to destroy.
+*/
+void
+dk3fig_drawing_delete(dk3_fig_drawing_t *drw);
+
+/** Destroy Fig object, release memory.
+ @param obj Object to destroy.
+*/
+void
+dk3fig_obj_delete(dk3_fig_obj_t *obj);
+
+/** Create new Fig object.
+ @param li Line number of object definition.
+ @param la Layer number.
+ @param ot Object type.
+ @param st Object subtype.
+ @param lw Line width.
+ @param pc Pen color.
+ @param fc Fill color.
+ @param fi Fill type.
+ @param cs Cap style.
+ @param js Join style.
+ @param ls Line style.
+ @param sv Style value.
+ @param af Flag: Arrowhead forward.
+ @param ab Flag: Arrowhead backward.
+ @param np Number of spline/polyline points.
+ @param txt Text string (for text objects).
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new object on success, NULL on error.
+*/
+dk3_fig_obj_t *
+dk3fig_obj_new(
+ unsigned long li,
+ int la,
+ int ot,
+ int st,
+ int lw,
+ int pc,
+ int fc,
+ int fi,
+ int cs,
+ int js,
+ int ls,
+ double sv,
+ int af,
+ int ab,
+ size_t np,
+ char const *txt,
+ dk3_app_t *app
+);
+
+/** Initialize Fig object.
+ @param obj Object to initialize.
+*/
+void
+dk3fig_obj_init(dk3_fig_obj_t *obj);
+
+/** Initialize graphics state data.
+ @param gs Graphics state structure to initialize.
+*/
+void
+dk3fig_gs_init(dk3_graphics_state_t *gs);
+
+/** Set arrowhead spline options.
+ @param drw Drawing to set up.
+ @param arcspp Number of X-spline segments per 90 degree arc.
+ @param splspp Number of X-spline segments per X-spline interval.
+ @param minspp Minimum number of X-spline intervals for arrowhead edge.
+*/
+void
+dk3fig_set_options_arrows(
+ dk3_fig_drawing_t *drw,
+ double arcspp,
+ double splspp,
+ size_t minspp
+);
+
+/** Set precision for X-splines iterations.
+ @param drw Drawing to set up.
+ @param prec Precision.
+*/
+void
+dk3fig_set_options_iteration_precision(
+ dk3_fig_drawing_t *drw,
+ double prec
+);
+
+/** Set number of digits for colors.
+ @param drw Drawing to set up.
+ @param codi Number of color digits.
+*/
+void
+dk3fig_set_options_codi(
+ dk3_fig_drawing_t *drw,
+ size_t codi
+);
+
+/** Set error code for drawing.
+ The new error code is set only if the current error code
+ of the drawing is 0 (indicates "no error found").
+ @param drw Drawing to set.
+ @param ec Error code to set.
+*/
+void
+dk3fig_set_ec(dk3_fig_drawing_t *drw, int ec);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk3figah.c b/support/dktools/dk3figah.c
new file mode 100644
index 0000000000..8690ba7aca
--- /dev/null
+++ b/support/dktools/dk3figah.c
@@ -0,0 +1,7098 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3figah.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3figah.c The dk3figah module.
+*/
+
+
+#line 40 "dk3figah.ctr"
+
+#include "dk3all.h"
+#include "dk3fig.h"
+#include "dk3figto.h"
+#include "dk3figpr.h"
+#include "dk3figbb.h"
+#include "dk3figah.h"
+#include "dk3xsp.h"
+
+
+
+
+#line 51 "dk3figah.ctr"
+
+
+
+/** Calculate c_min (minimum length to cut).
+ @param drw Drawing.
+ @param obj Object to calculate arrowheads for.
+ @param ah Arrowhead data.
+ @param ec Pointer to error code variable, may be NULL.
+ @return The c_min value.
+*/
+static
+double
+dk3figah_cmin(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec
+)
+{
+ double back;
+ double h;
+ double w;
+ double lw; /* Line width. */
+
+
+#line 75 "dk3figah.ctr"
+ lw = dk3fig_tool_get_lw(drw, obj, ec);
+ h = ah->he;
+ w = ah->wi;
+ switch(ah->as) {
+ case DK3_FIG_AS_INDENTED:
+ case DK3_FIG_AS_INDENTED_FILLED_HALF:
+ {
+ h = dk3ma_d_mul_ok(1.25, h, ec);
+ } break;
+ case DK3_FIG_AS_POINTED: {
+ h = 0.75 * h;
+ } break;
+ case DK3_FIG_AS_RHOMBUS: {
+ h = 0.5 * h;
+ } break;
+ }
+ back = dk3ma_d_div_ok(dk3ma_d_mul_ok(lw, h, ec), w, ec);
+
+
+#line 93 "dk3figah.ctr"
+ return back;
+}
+
+
+
+/** Calculate s value for arrowhead.
+ @param drw Drawing.
+ @param obj Object to calculate arrowheads for.
+ @param ah Arrowhead data.
+ @param ec Pointer to error code variable, may be NULL.
+ @return The s value.
+*/
+static
+double
+dk3figah_s(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec
+)
+{
+ double back;
+ double lw; /* Line width. */
+ double h; /* Arrow height (length). */
+ double w; /* Arrow width. */
+
+
+#line 119 "dk3figah.ctr"
+ lw = dk3fig_tool_get_lw(drw, obj, ec);
+ h = ah->he;
+ w = ah->wi;
+ switch(ah->as) {
+ case DK3_FIG_AS_INDENTED:
+ case DK3_FIG_AS_INDENTED_FILLED_HALF:
+ {
+ h = dk3ma_d_mul_ok(1.25, h, ec);
+
+#line 127 "dk3figah.ctr"
+ } break;
+ case DK3_FIG_AS_POINTED: {
+ h = 0.75 * h;
+
+#line 130 "dk3figah.ctr"
+ } break;
+ case DK3_FIG_AS_RHOMBUS: {
+ h = 0.5 * h;
+
+#line 133 "dk3figah.ctr"
+ } break;
+ }
+ back = dk3ma_d_mul_ok(
+ dk3ma_d_div_ok(lw, w, ec),
+ sqrt(
+ dk3ma_d_add_ok(
+ dk3ma_d_square_ok(h, ec),
+ dk3ma_d_div_ok(
+ dk3ma_d_square_ok(w, ec),
+ 4.0,
+ ec
+ ),
+ ec
+ )
+ ),
+ ec
+ );
+
+#line 150 "dk3figah.ctr"
+ return back;
+}
+
+
+
+/** Calculate s value for half arrowhead.
+ @param drw Drawing.
+ @param obj Object to calculate arrowheads for.
+ @param ah Arrowhead data.
+ @param ec Pointer to error code variable, may be NULL.
+ @return The s value.
+*/
+static
+double
+dk3figah_half_arrow_s(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec
+)
+{
+ double back;
+ double lw; /* Line width. */
+ double h; /* Arrow height (length). */
+ double w; /* Arrow width. */
+
+
+#line 176 "dk3figah.ctr"
+ lw = dk3fig_tool_get_lw(drw, obj, ec);
+ h = ah->he;
+ w = ah->wi;
+ switch(ah->as) {
+ case DK3_FIG_AS_INDENTED_HALF:
+ {
+ h = dk3ma_d_mul_ok(1.25, h, ec);
+
+#line 183 "dk3figah.ctr"
+ } break;
+ case DK3_FIG_AS_BUTTED_HALF: {
+ h = 0.75 * h;
+
+#line 186 "dk3figah.ctr"
+ } break;
+ }
+ back = dk3ma_d_div_ok(
+ dk3ma_d_mul_ok(2.0, dk3ma_d_mul_ok(h, lw, ec), ec), w, ec
+ );
+
+
+#line 192 "dk3figah.ctr"
+ return back;
+}
+
+
+
+#if 0
+/** Calculate c_max value for arrowhead.
+ @param drw Drawing.
+ @param obj Object to calculate arrowheads for.
+ @param ah Arrowhead data.
+ @param ec Pointer to error code variable, may be NULL.
+ @return The c_max value.
+*/
+static
+double
+dk3figah_cmax(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec
+)
+{
+ double back;
+
+
+#line 216 "dk3figah.ctr"
+ back = dk3ma_d_mul_ok(
+ 2.0,
+ dk3figah_s(drw, obj, ah, ec),
+ ec
+ );
+
+#line 221 "dk3figah.ctr"
+ return back;
+}
+#endif
+
+
+
+/** Calculate length correction for normal arrows.
+ @param drw Drawing structure.
+ @param obj Object to modify.
+ @param ah Arrowhead to calculate length correction for.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Length correction value.
+*/
+static
+double
+dk3figah_normal_arrow_length_correction(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec
+)
+{
+ double back = 0.0;
+ double cmin;
+ double s;
+
+
+#line 247 "dk3figah.ctr"
+ cmin = dk3figah_cmin(drw, obj, ah, ec);
+ s = dk3figah_s(drw, obj, ah, ec);
+ switch(obj->cs) {
+ case DK3_FIG_LC_PROJECTING:
+ case DK3_FIG_LC_ROUND: {
+ back = dk3ma_d_add_ok(
+ dk3ma_d_mul_ok(1.5, s, ec),
+ (0.5 * cmin),
+ ec
+ );
+ } break;
+ default: {
+ back = dk3ma_d_add_ok(s, (0.5 * cmin), ec);
+ } break;
+ }
+
+#line 262 "dk3figah.ctr"
+ return back;
+}
+
+
+
+
+/** Calculate length correction tolerance for normal arrows.
+ @param drw Drawing structure.
+ @param obj Object to modify.
+ @param ah Arrowhead to calculate length correction for.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Length correction value.
+*/
+static
+double
+dk3figah_normal_arrow_length_correction_tolerance(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec
+)
+{
+ double back;
+ double cmin;
+ double s;
+
+
+#line 288 "dk3figah.ctr"
+ cmin = dk3figah_cmin(drw, obj, ah, ec);
+ s = dk3figah_s(drw, obj, ah, ec);
+ switch(obj->cs) {
+ case DK3_FIG_LC_PROJECTING:
+ case DK3_FIG_LC_ROUND: {
+ back = 0.25 * dk3ma_d_sub_ok(s, cmin, ec);
+ } break;
+ default: {
+ back = dk3ma_d_sub_ok((0.5 * s), (0.25 * cmin), ec);
+ } break;
+ }
+
+#line 299 "dk3figah.ctr"
+ return back;
+}
+
+
+
+/** Calculate length correction for blocking line arrowhead.
+ @param drw Drawing structure.
+ @param obj Object to modify.
+ @param ah Arrowhead to calculate length correction for.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Length correction value.
+*/
+static
+double
+dk3figah_block_line_length_correction(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec
+)
+{
+ double back = 0.0;
+
+
+#line 322 "dk3figah.ctr"
+ switch(obj->cs) {
+ case DK3_FIG_LC_PROJECTING:
+ case DK3_FIG_LC_ROUND: {
+ back = 0.75 * dk3fig_tool_get_lw(drw, obj, ec);
+ } break;
+ default: {
+ back = 0.5 * dk3fig_tool_get_lw(drw, obj, ec);
+ } break;
+ }
+
+#line 331 "dk3figah.ctr"
+ return back;
+}
+
+
+
+/** Calculate length correction tolerance for blocking line arrowhead.
+ @param drw Drawing structure.
+ @param obj Object to modify.
+ @param ah Arrowhead to calculate length correction for.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Length correction value.
+*/
+static
+double
+dk3figah_block_line_length_correction_tolerance(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec
+)
+{
+ double back = 0.0;
+
+
+#line 354 "dk3figah.ctr"
+ switch(obj->cs) {
+ case DK3_FIG_LC_PROJECTING:
+ case DK3_FIG_LC_ROUND: {
+ back = 0.125 * dk3fig_tool_get_lw(drw, obj, ec);
+ } break;
+ default: {
+ back = 0.25 * dk3fig_tool_get_lw(drw, obj, ec);
+ } break;
+ }
+
+#line 363 "dk3figah.ctr"
+ return back;
+}
+
+
+
+/** Length correction for inverted open arrow.
+ @param drw Drawing structure.
+ @param obj Object to modify.
+ @param ah Arrowhead to calculate length correction for.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Length correction value.
+*/
+static
+double
+dk3figah_anti_arrow_length_correction(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec
+)
+{
+ double back;
+ double sqv;
+ double lw;
+ double cmin;
+ double cmax;
+
+
+#line 390 "dk3figah.ctr"
+ lw = dk3fig_tool_get_lw(drw, obj, ec);
+ sqv = sqrt(
+ dk3ma_d_add_ok(
+ dk3ma_d_square_ok(ah->wi, ec),
+ dk3ma_d_mul_ok(
+ 4.0,
+ dk3ma_d_square_ok(ah->he, ec),
+ ec
+ ),
+ ec
+ )
+ );
+ sqv = dk3ma_d_div_ok(
+ dk3ma_d_mul_ok(lw, sqv, ec),
+ dk3ma_d_mul_ok(2.0, ah->wi, ec),
+ ec
+ );
+ cmin = dk3ma_d_sub_ok(ah->he, sqv, ec);
+ cmax = dk3ma_d_sub_ok(
+ dk3ma_d_add_ok(ah->he, sqv, ec),
+ dk3ma_d_div_ok(
+ dk3ma_d_mul_ok(lw, ah->he, ec),
+ ah->wi,
+ ec
+ ),
+ ec
+ );
+ switch(obj->cs) {
+ case DK3_FIG_LC_PROJECTING: case DK3_FIG_LC_ROUND: {
+ sqv = dk3ma_d_sub_ok(
+ dk3ma_d_sub_ok(cmax, cmin, ec),
+ (0.5 * lw),
+ ec
+ );
+ back = dk3ma_d_sub_ok(
+ cmax,
+ (0.5 * sqv),
+ ec
+ );
+ } break;
+ default: {
+ back = 0.5 * dk3ma_d_add_ok(cmin, cmax, ec);
+ } break;
+ }
+
+#line 434 "dk3figah.ctr"
+ return back;
+}
+
+
+
+/** Length correction tolerance for inverted open arrow.
+ @param drw Drawing structure.
+ @param obj Object to modify.
+ @param ah Arrowhead to calculate length correction for.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Length correction value.
+*/
+static
+double
+dk3figah_anti_arrow_length_correction_tolerance(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec
+)
+{
+ double back;
+ double sqv;
+ double lw;
+ double cmin;
+ double cmax;
+
+
+#line 461 "dk3figah.ctr"
+ lw = dk3fig_tool_get_lw(drw, obj, ec);
+ sqv = sqrt(
+ dk3ma_d_add_ok(
+ dk3ma_d_square_ok(ah->wi, ec),
+ dk3ma_d_mul_ok(
+ 4.0,
+ dk3ma_d_square_ok(ah->he, ec),
+ ec
+ ),
+ ec
+ )
+ );
+ sqv = dk3ma_d_div_ok(
+ dk3ma_d_mul_ok(lw, sqv, ec),
+ dk3ma_d_mul_ok(2.0, ah->wi, ec),
+ ec
+ );
+ cmin = dk3ma_d_sub_ok(ah->he, sqv, ec);
+ cmax = dk3ma_d_sub_ok(
+ dk3ma_d_add_ok(ah->he, sqv, ec),
+ dk3ma_d_div_ok(
+ dk3ma_d_mul_ok(lw, ah->he, ec),
+ ah->wi,
+ ec
+ ),
+ ec
+ );
+ switch(obj->cs) {
+ case DK3_FIG_LC_PROJECTING: case DK3_FIG_LC_ROUND: {
+ back = 0.25 * dk3ma_d_sub_ok(
+ dk3ma_d_sub_ok(cmax, cmin, ec),
+ (0.5 * lw),
+ ec
+ );
+ } break;
+ default: {
+ back = 0.25 * dk3ma_d_sub_ok(cmax, cmin, ec);
+ } break;
+ }
+
+#line 500 "dk3figah.ctr"
+ return back;
+}
+
+
+
+/** Length correction for full circle arrowhead.
+ @param drw Drawing structure.
+ @param obj Object to modify.
+ @param ah Arrowhead to calculate length correction for.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Length correction value.
+*/
+static
+double
+dk3figah_full_circle_length_correction(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec
+)
+{
+ double back;
+ double lw;
+ double cmin;
+ double cmax;
+
+
+#line 526 "dk3figah.ctr"
+ lw = dk3fig_tool_get_lw(drw, obj, ec);
+ cmin = 0.5 * dk3ma_d_mul_ok(
+ dk3ma_d_add_ok(ah->he, lw, ec),
+ dk3ma_d_sub_ok(
+ 1.0,
+ sqrt(
+ dk3ma_d_sub_ok(
+ 1.0,
+ dk3ma_d_square_ok(
+ dk3ma_d_div_ok(
+ lw,
+ dk3ma_d_add_ok(lw, ah->he, ec),
+ ec
+ ),
+ ec
+ ),
+ ec
+ )
+ ),
+ ec
+ ),
+ ec
+ );
+ cmax = lw;
+ switch(obj->cs) {
+ case DK3_FIG_LC_PROJECTING: case DK3_FIG_LC_ROUND: {
+ back = dk3ma_d_sub_ok(
+ cmax,
+ (0.5 * dk3ma_d_sub_ok(dk3ma_d_sub_ok(cmax, cmin, ec), (0.5 * lw), ec)),
+ ec
+ );
+ } break;
+ default: {
+ back = 0.5 * dk3ma_d_add_ok(cmax, cmin, ec);
+ } break;
+ }
+
+#line 562 "dk3figah.ctr"
+ return back;
+}
+
+
+
+/** Length correction tolerance for full circle arrowhead.
+ @param drw Drawing structure.
+ @param obj Object to modify.
+ @param ah Arrowhead to calculate length correction for.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Length correction value.
+*/
+static
+double
+dk3figah_full_circle_length_correction_tolerance(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec
+)
+{
+ double back;
+ double lw;
+ double cmin;
+ double cmax;
+
+
+#line 588 "dk3figah.ctr"
+ lw = dk3fig_tool_get_lw(drw, obj, ec);
+ cmin = 0.5 * dk3ma_d_mul_ok(
+ dk3ma_d_add_ok(ah->he, lw, ec),
+ dk3ma_d_sub_ok(
+ 1.0,
+ sqrt(
+ dk3ma_d_sub_ok(
+ 1.0,
+ dk3ma_d_square_ok(
+ dk3ma_d_div_ok(
+ lw,
+ dk3ma_d_add_ok(lw, ah->he, ec),
+ ec
+ ),
+ ec
+ ),
+ ec
+ )
+ ),
+ ec
+ ),
+ ec
+ );
+ cmax = lw;
+ switch(obj->cs) {
+ case DK3_FIG_LC_PROJECTING: case DK3_FIG_LC_ROUND: {
+ back = 0.25 * dk3ma_d_sub_ok(
+ dk3ma_d_sub_ok(cmax, cmin, ec),
+ (0.5 * lw),
+ ec
+ );
+ } break;
+ default: {
+ back = 0.25 * dk3ma_d_sub_ok(cmax, cmin, ec);
+ } break;
+ }
+
+#line 624 "dk3figah.ctr"
+ return back;
+}
+
+
+
+/** Length correction for half circle arrowhead.
+ @param drw Drawing structure.
+ @param obj Object to modify.
+ @param ah Arrowhead to calculate length correction for.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Length correction value.
+*/
+static
+double
+dk3figah_half_circle_length_correction(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec
+)
+{
+ double back;
+ double lw;
+#if VERSION_BEFORE_20150821
+ double cmin;
+ double cmax;
+#endif
+
+
+#line 652 "dk3figah.ctr"
+ lw = dk3fig_tool_get_lw(drw, obj, ec);
+#if VERSION_BEFORE_20150821
+ cmin = dk3ma_d_sub_ok(
+ (0.5 * ah->he),
+ (0.5 * lw),
+ ec
+ );
+ cmax = dk3ma_d_add_ok(
+ (0.5 * ah->he),
+ (0.5 * lw),
+ ec
+ );
+#endif
+ switch(obj->cs) {
+ case DK3_FIG_LC_PROJECTING: case DK3_FIG_LC_ROUND: {
+ back = dk3ma_d_add_ok(
+ (0.5 * ah->he),
+ (0.25 * lw),
+ ec
+ );
+ } break;
+ default: {
+ back = 0.5 * ah->he;
+ } break;
+ }
+
+#line 677 "dk3figah.ctr"
+ return back;
+}
+
+
+
+
+#if VERSION_BEFORE_20121215
+/** Length correction for half-arrow arrowhead.
+ @param drw Drawing structure.
+ @param obj Object to modify.
+ @param ah Arrowhead to calculate length correction for.
+ @param ec Pointer to error code variable, may be NULL.
+ @param incr Flag: Increase (1=increase, 0=no op, -1=decrease).
+ @return Length correction value.
+*/
+static
+double
+dk3figah_half_arrow_length_correction(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec,
+ int incr
+)
+{
+ double back;
+ double lw;
+ double cmin;
+ double d;
+ double cmax;
+
+
+#line 708 "dk3figah.ctr"
+ lw = dk3fig_tool_get_lw(drw, obj, ec);
+ cmin = dk3ma_d_div_ok(
+ dk3ma_d_mul_ok(
+ dk3ma_d_mul_ok(lw, ah->he, ec),
+ 2.0,
+ ec
+ ),
+ ah->wi,
+ ec
+ );
+ d = dk3ma_d_div_ok(
+ lw,
+ dk3ma_d_mul_ok(
+ 2.0,
+ tan(
+ 0.5 * atan(
+ dk3ma_d_div_ok(
+ ah->wi,
+ dk3ma_d_mul_ok(2.0, ah->he, ec),
+ ec
+ )
+ )
+ ),
+ ec
+ ),
+ ec
+ );
+ cmax = dk3ma_d_add_ok(d, (0.5 * lw), ec);
+ cmax = dk3ma_d_add_ok(
+ cmax,
+ dk3ma_d_mul_ok(
+ ((incr > 0) ? 1.25 : ((incr < 0) ? 0.75 : 1.0)),
+ ah->he,
+ ec
+ ),
+ ec
+ );
+ if(cmax > dk3ma_d_add_ok(cmin, lw, ec)) {
+ cmax = dk3ma_d_add_ok(cmin, lw, ec);
+ }
+ switch(obj->cs) {
+ case DK3_FIG_LC_PROJECTING: case DK3_FIG_LC_ROUND: {
+ back = dk3ma_d_sub_ok(
+ cmax,
+ (0.5 * dk3ma_d_sub_ok(dk3ma_d_sub_ok(cmax, cmin, ec), (0.5*lw), ec)),
+ ec
+ );
+ } break;
+ default: {
+ back = 0.5 * dk3ma_d_add_ok(cmax, cmin, ec);
+ } break;
+ }
+
+#line 760 "dk3figah.ctr"
+ return back;
+}
+#else
+/** Length correction for half-arrow arrowhead.
+ @param drw Drawing structure.
+ @param obj Object to modify.
+ @param ah Arrowhead to calculate length correction for.
+ @param ec Pointer to error code variable, may be NULL.
+ @param incr Flag: Increase (1=increase, 0=no op, -1=decrease).
+ @return Length correction value.
+*/
+static
+double
+dk3figah_half_arrow_length_correction(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec,
+ int incr
+)
+{
+ double back;
+ double lw; /* Line width. */
+ double cmin; /* Minimum correction. */
+ double cmax; /* Maximum correction. */
+ double d; /* Shift value. */
+ double w; /* Arrowhead width. */
+ double h; /* Arrowhead height. */
+
+
+
+#line 790 "dk3figah.ctr"
+ w = ah->wi;
+ h = ah->he;
+ switch(incr) {
+ case -1: { /* indented */
+ h = dk3ma_d_mul_ok(1.25, h, ec);
+ } break;
+ case 1: { /* butted */
+ h = 0.75 * h;
+ } break;
+ }
+ lw = dk3fig_tool_get_lw(drw, obj, ec);
+
+
+#line 802 "dk3figah.ctr"
+ cmin = dk3ma_d_div_ok(
+ dk3ma_d_mul_ok(2.0, dk3ma_d_mul_ok(h, lw, ec), ec), w, ec
+ );
+ d = dk3ma_d_div_ok(
+ lw,
+ dk3ma_d_mul_ok(
+ 2.0,tan(0.5 * atan(dk3ma_d_div_ok(w, dk3ma_d_mul_ok(2.0, h, ec), ec))),ec
+ ),
+ ec
+ );
+ cmax = dk3ma_d_mul_ok(2.0, d, ec);
+
+
+#line 814 "dk3figah.ctr"
+ switch(obj->cs) {
+ case DK3_FIG_LC_PROJECTING: case DK3_FIG_LC_ROUND: {
+ back = dk3ma_d_sub_ok(
+ (0.5 * lw),
+ (0.5 * dk3ma_d_sub_ok(dk3ma_d_sub_ok(cmax, cmin, ec), (0.5*lw), ec)),
+ ec
+ );
+ } break;
+ default: {
+ back = 0.5 * dk3ma_d_add_ok(cmax, cmin, ec);
+ } break;
+ }
+
+#line 826 "dk3figah.ctr"
+ return back;
+}
+#endif
+
+
+#if VERSION_BEFORE_20121215
+/** Length correction tolerance for half-arrow arrowhead.
+ @param drw Drawing structure.
+ @param obj Object to modify.
+ @param ah Arrowhead to calculate length correction for.
+ @param ec Pointer to error code variable, may be NULL.
+ @param incr Flag: Increase (1=increase, 0=no op, -1=decrease).
+ @return Length correction tolerance value.
+*/
+static
+double
+dk3figah_half_arrow_length_correction_tolerance(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec,
+ int incr
+)
+{
+ double back;
+ double lw;
+ double cmin;
+ double d;
+ double cmax;
+
+
+#line 856 "dk3figah.ctr"
+ lw = dk3fig_tool_get_lw(drw, obj, ec);
+ cmin = dk3ma_d_div_ok(
+ dk3ma_d_mul_ok(
+ dk3ma_d_mul_ok(lw, ah->he, ec),
+ 2.0,
+ ec
+ ),
+ ah->wi,
+ ec
+ );
+ d = dk3ma_d_div_ok(
+ lw,
+ dk3ma_d_mul_ok(
+ 2.0,
+ tan(
+ 0.5 * atan(
+ dk3ma_d_div_ok(
+ ah->wi,
+ dk3ma_d_mul_ok(2.0, ah->he, ec),
+ ec
+ )
+ )
+ ),
+ ec
+ ),
+ ec
+ );
+ cmax = dk3ma_d_add_ok(d, (0.5 * lw), ec);
+ cmax = dk3ma_d_add_ok(
+ cmax,
+ dk3ma_d_mul_ok(
+ ((incr > 0) ? 1.25 : ((incr < 0) ? 0.75 : 1.0)),
+ ah->he,
+ ec
+ ),
+ ec
+ );
+ if(cmax > dk3ma_d_add_ok(cmin, lw, ec)) {
+ cmax = dk3ma_d_add_ok(cmin, lw, ec);
+ }
+ switch(obj->cs) {
+ case DK3_FIG_LC_PROJECTING: case DK3_FIG_LC_ROUND: {
+ back = 0.25 * dk3ma_d_sub_ok(dk3ma_d_sub_ok(cmax,cmin,ec),(0.5 * lw),ec);
+ } break;
+ default: {
+ back = 0.25 * dk3ma_d_sub_ok(cmax, cmin, ec);
+ } break;
+ }
+
+#line 904 "dk3figah.ctr"
+ return back;
+}
+#else
+
+/** Length correction tolerance for half-arrow arrowhead.
+ @param drw Drawing structure.
+ @param obj Object to modify.
+ @param ah Arrowhead to calculate length correction for.
+ @param ec Pointer to error code variable, may be NULL.
+ @param incr Flag: Increase (1=increase, 0=no op, -1=decrease).
+ @return Length correction tolerance value.
+*/
+static
+double
+dk3figah_half_arrow_length_correction_tolerance(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec,
+ int incr
+)
+{
+ double back;
+ double lw; /* Line width. */
+ double cmin; /* Minimum correction. */
+ double cmax; /* Maximum correction. */
+ double d; /* Shift value. */
+ double w; /* Arrowhead width. */
+ double h; /* Arrowhead height. */
+
+
+
+#line 935 "dk3figah.ctr"
+ w = ah->wi;
+ h = ah->he;
+ switch(incr) {
+ case -1: { /* indented */
+ h = dk3ma_d_mul_ok(1.25, h, ec);
+ } break;
+ case 1: { /* butted */
+ h = 0.75 * h;
+ } break;
+ }
+ lw = dk3fig_tool_get_lw(drw, obj, ec);
+
+
+#line 947 "dk3figah.ctr"
+ cmin = dk3ma_d_div_ok(
+ dk3ma_d_mul_ok(2.0, dk3ma_d_mul_ok(h, lw, ec), ec), w, ec
+ );
+ d = dk3ma_d_div_ok(
+ lw,
+ dk3ma_d_mul_ok(
+ 2.0,tan(0.5 * atan(dk3ma_d_div_ok(w, dk3ma_d_mul_ok(2.0, h, ec), ec))),ec
+ ),
+ ec
+ );
+ cmax = dk3ma_d_mul_ok(2.0, d, ec);
+
+
+#line 959 "dk3figah.ctr"
+ back = 0.25 * fabs(dk3ma_d_sub_ok(cmax, cmin, ec));
+
+
+#line 961 "dk3figah.ctr"
+ return back;
+}
+#endif
+
+
+
+/** Calculate length correction for arrowhead.
+ Amount to cut the original line.
+ @param drw Drawing.
+ @param obj Object to calculate arrowheads for.
+ @param ah Arrowhead data.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Length to cut from line.
+*/
+static
+double
+dk3figah_length_correction(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec
+)
+{
+ double back = 0.0;
+
+
+#line 986 "dk3figah.ctr"
+ switch(ah->as) {
+ case DK3_FIG_AS_RHOMBUS: { /* 4 */
+ if((1 == ah->af) && (DK3_FIG_SRCTYPE_JFIG == drw->srctype)) {
+ back = 0.0;
+ } else {
+ back = dk3figah_normal_arrow_length_correction(drw, obj, ah, ec);
+ }
+ } break;
+ case DK3_FIG_AS_FULL_CIRCLE_END: { /* 5 */
+ back = dk3figah_full_circle_length_correction(drw, obj, ah, ec);
+ } break;
+ case DK3_FIG_AS_RECTANGLE: /* 7 */
+ case DK3_FIG_AS_INVERSE: /* 8 */
+ {
+ back = dk3figah_block_line_length_correction(drw, obj, ah, ec);
+ } break;
+ case DK3_FIG_AS_HALF_CIRCLE_END: { /* 6 */
+ if(1 == ah->af) {
+ back = dk3figah_block_line_length_correction(drw, obj, ah, ec);
+ } else {
+ back = dk3figah_half_circle_length_correction(drw, obj, ah, ec);
+ }
+ } break;
+ case DK3_FIG_AS_CLOSED_HALF: { /* 10 */
+ back = dk3figah_half_arrow_length_correction(drw, obj, ah, ec, 0);
+ } break;
+ case DK3_FIG_AS_INDENTED_HALF: { /* 11 */
+ back = dk3figah_half_arrow_length_correction(drw, obj, ah, ec, -1);
+ } break;
+ case DK3_FIG_AS_BUTTED_HALF: { /* 12 */
+ back = dk3figah_half_arrow_length_correction(drw, obj, ah, ec, 1);
+ } break;
+ case DK3_FIG_AS_TRIANGLE_FORK: { /* 13 */
+ if(1 == ah->af) {
+ back = dk3figah_block_line_length_correction(drw, obj, ah, ec);
+ } else {
+ back = dk3figah_anti_arrow_length_correction(drw, obj, ah, ec);
+ }
+ } break;
+ case DK3_FIG_AS_RECTANGLE_FORK: { /* 14 */
+ if(1 == ah->af) {
+ back = dk3figah_block_line_length_correction(drw, obj, ah, ec);
+ } else {
+#if 0
+ back = dk3figah_block_line_length_correction(drw, obj, ah, ec);
+#endif
+ back = dk3ma_d_add_ok(back, ah->he, ec);
+
+#line 1033 "dk3figah.ctr"
+ }
+ } break;
+ default: {
+ back = dk3figah_normal_arrow_length_correction(drw, obj, ah, ec);
+ } break;
+ }
+
+#line 1039 "dk3figah.ctr"
+ return back;
+}
+
+
+
+/** Calculate length correction tolerance for arrowhead.
+ @param drw Drawing.
+ @param obj Object to calculate arrowheads for.
+ @param ah Arrowhead data.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Tolerance for length to cut from line.
+*/
+static
+double
+dk3figah_length_correction_tolerance(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec
+)
+{
+ double back;
+
+
+#line 1062 "dk3figah.ctr"
+ switch(ah->as) {
+ case DK3_FIG_AS_RHOMBUS: { /* 4 */
+ if((1 == ah->af) && (DK3_FIG_SRCTYPE_JFIG == drw->srctype)) {
+ back = 0.0;
+ } else {
+ back = dk3figah_normal_arrow_length_correction_tolerance(drw,obj,ah,ec);
+ }
+ } break;
+ case DK3_FIG_AS_FULL_CIRCLE_END: { /* 5 */
+ back = dk3figah_full_circle_length_correction_tolerance(drw,obj,ah,ec);
+ } break;
+ case DK3_FIG_AS_RECTANGLE: /* 7 */
+ case DK3_FIG_AS_INVERSE: /* 8 */
+ {
+ back = dk3figah_block_line_length_correction_tolerance(drw,obj,ah,ec);
+ } break;
+ case DK3_FIG_AS_HALF_CIRCLE_END: { /* 6 */
+ back = dk3figah_block_line_length_correction_tolerance(drw,obj,ah,ec);
+ } break;
+ case DK3_FIG_AS_CLOSED_HALF: { /* 10 */
+ back = dk3figah_half_arrow_length_correction_tolerance(drw,obj,ah,ec,0);
+ } break;
+ case DK3_FIG_AS_INDENTED_HALF: { /* 11 */
+ back = dk3figah_half_arrow_length_correction_tolerance(drw,obj,ah,ec,-1);
+ } break;
+ case DK3_FIG_AS_BUTTED_HALF: { /* 12 */
+ back = dk3figah_half_arrow_length_correction_tolerance(drw,obj,ah,ec,1);
+ } break;
+ case DK3_FIG_AS_TRIANGLE_FORK: { /* 13 */
+ if(1 == ah->af) {
+ back = dk3figah_block_line_length_correction_tolerance(drw,obj,ah,ec);
+ } else {
+ back = dk3figah_anti_arrow_length_correction_tolerance(drw,obj,ah,ec);
+ }
+ } break;
+ case DK3_FIG_AS_RECTANGLE_FORK: { /* 14 */
+ back = dk3figah_block_line_length_correction_tolerance(drw,obj,ah,ec);
+ } break;
+ default: {
+ back = dk3figah_normal_arrow_length_correction_tolerance(drw,obj,ah,ec);
+ } break;
+ }
+
+#line 1104 "dk3figah.ctr"
+ return back;
+}
+
+
+
+int
+dk3figah_candidate(dk3_fig_obj_t *obj)
+{
+ int back = 0;
+
+
+#line 1114 "dk3figah.ctr"
+ if(obj) {
+ switch(obj->ot) {
+ case DK3_FIG_OBJ_POLYLINE: {
+ switch(obj->st) {
+ case 1: { back = 1; } break;
+ }
+ } break;
+ case DK3_FIG_OBJ_SPLINE: {
+ switch(obj->st) {
+ case 0: case 2: case 4: { back = 1; } break;
+ }
+ } break;
+ case DK3_FIG_OBJ_ARC: {
+ switch(obj->st) {
+ case 1: { back = 1; } break;
+ }
+ } break;
+ }
+ if(back) {
+ if(!((obj->af) || (obj->ab))) {
+ back = 0;
+ }
+ }
+ }
+
+#line 1138 "dk3figah.ctr"
+ return back;
+}
+
+
+
+/** Find distance to shift arrowhead polygon point from end point.
+ @param drw Drawing structure.
+ @param obj Object containing the arrowhead.
+ @param ah Arrowhead.
+ @param ec Pointer to error code variable.
+ @return Non-negative distance on success, negative value on error.
+*/
+static
+double
+dk3figah_find_shift_length(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec
+)
+{
+ double back = 0.0;
+
+
+#line 1161 "dk3figah.ctr"
+ switch(ah->as) {
+ case DK3_FIG_AS_TRIANGLE_FORK: {
+ if(ah->af) {
+ back = 0.5 * dk3fig_tool_get_lw(drw, obj, ec);
+ } else {
+ }
+ } break;
+ case DK3_FIG_AS_RECTANGLE_FORK: {
+ if(ah->af) {
+ back = 0.5 * dk3fig_tool_get_lw(drw, obj, ec);
+ }
+ } break;
+ case DK3_FIG_AS_FULL_CIRCLE_END:
+ case DK3_FIG_AS_HALF_CIRCLE_END:
+ case DK3_FIG_AS_RECTANGLE:
+ case DK3_FIG_AS_INVERSE:
+ {
+ back = 0.5 * dk3fig_tool_get_lw(drw, obj, ec);
+ } break;
+ case DK3_FIG_AS_INDENTED_FILLED_HALF:
+ case DK3_FIG_AS_STICK:
+ case DK3_FIG_AS_CLOSED:
+ case DK3_FIG_AS_INDENTED:
+ case DK3_FIG_AS_POINTED:
+ case DK3_FIG_AS_RHOMBUS:
+ {
+ back = dk3figah_s(drw, obj, ah, ec);
+ } break;
+ case DK3_FIG_AS_CLOSED_HALF:
+ case DK3_FIG_AS_INDENTED_HALF:
+ case DK3_FIG_AS_BUTTED_HALF: {
+ back = dk3figah_half_arrow_s(drw, obj, ah, ec);
+ } break;
+ }
+
+#line 1195 "dk3figah.ctr"
+ return back;
+}
+
+
+
+/** Arrowhead for polylines or compatible arrowheads.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param ah Arrowhead to modify.
+ @param ep Endpoint of the arrowhead.
+ @param rotation Arrowhead direction in radians.
+ @param ec Pointer to error code variable.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figah_straight_arrowhead(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ dk3_fig_poly_point_t *ep,
+ double rotation,
+ int *ec
+)
+{
+ dk3_fig_poly_point_t aep;
+ dk3_fig_poly_point_t po[8];
+ double s; /* Shifting the first point */
+ size_t i;
+ int back = 0;
+
+
+#line 1226 "dk3figah.ctr"
+ dk3mem_cpy((void *)(&aep), (void *)ep, sizeof(dk3_fig_poly_point_t));
+ switch(ah->as) {
+ case DK3_FIG_AS_STICK: {
+ if(!(drw->coah)) {
+ s = dk3figah_s(drw, obj, ah, ec);
+ aep.x = dk3ma_d_sub_ok(aep.x, (s * cos(rotation)), ec);
+ aep.y = dk3ma_d_sub_ok(aep.y, (s * sin(rotation)), ec);
+ }
+ po[0].x = -1.0 * ah->he;
+ po[0].y = 0.5 * ah->wi;
+ po[1].x = 0.0;
+ po[1].y = 0.0;
+ po[2].x = po[0].x;
+ po[2].y = -0.5 * ah->wi;
+ for(i = 0; i < 3; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), rotation, ec);
+ dk3fig_tool_shift_point(&(po[i]), aep.x, aep.y, ec);
+ }
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 1, /* Object type, subtype */
+ obj->lw, obj->pc, obj->pc, -1, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 3, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ if(ah->o1) {
+ if((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po) {
+ dk3mem_cpy(
+ (void *)((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po),
+ (void *)po,
+ (3 * sizeof(dk3_fig_poly_point_t))
+ );
+ back = 1;
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } break;
+ case DK3_FIG_AS_CLOSED: {
+ if(!(drw->coah)) {
+ s = dk3figah_s(drw, obj, ah, ec);
+ aep.x = dk3ma_d_sub_ok(aep.x, (s * cos(rotation)), ec);
+ aep.y = dk3ma_d_sub_ok(aep.y, (s * sin(rotation)), ec);
+ }
+ po[0].x = -1.0 * ah->he;
+ po[0].y = 0.5 * ah->wi;
+ po[1].x = 0.0;
+ po[1].y = 0.0;
+ po[2].x = po[0].x;
+ po[2].y = -0.5 * ah->wi;
+ for(i = 0; i < 3; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), rotation, ec);
+ dk3fig_tool_shift_point(&(po[i]), aep.x, aep.y, ec);
+ }
+ if(ah->af) {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, obj->pc, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 3, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ } else {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, 7, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 3, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ }
+ if(ah->o1) {
+ if((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po) {
+ dk3mem_cpy(
+ (void *)((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po),
+ (void *)po,
+ (3 * sizeof(dk3_fig_poly_point_t))
+ );
+ back = 1;
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } break;
+ case DK3_FIG_AS_INDENTED: {
+ if(!(drw->coah)) {
+ s = dk3figah_s(drw, obj, ah, ec);
+ aep.x = dk3ma_d_sub_ok(aep.x, (s * cos(rotation)), ec);
+ aep.y = dk3ma_d_sub_ok(aep.y, (s * sin(rotation)), ec);
+ }
+ po[0].x = dk3ma_d_mul_ok(-1.25, ah->he, ec);
+ po[0].y = 0.5 * ah->wi;
+ po[1].x = 0.0;
+ po[1].y = 0.0;
+ po[2].x = po[0].x;
+ po[2].y = -0.5 * ah->wi;
+ po[3].x = -1.0 * ah->he;
+ po[3].y = 0.0;
+ for(i = 0; i < 4; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), rotation, ec);
+ dk3fig_tool_shift_point(&(po[i]), aep.x, aep.y, ec);
+ }
+ if(ah->af) {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, obj->pc, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 4, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ } else {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, 7, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 4, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ }
+ if(ah->o1) {
+ if((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po) {
+ dk3mem_cpy(
+ (void *)((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po),
+ (void *)po,
+ (4 * sizeof(dk3_fig_poly_point_t))
+ );
+ back = 1;
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } break;
+ case DK3_FIG_AS_POINTED: {
+ if(!(drw->coah)) {
+ s = dk3figah_s(drw, obj, ah, ec);
+ aep.x = dk3ma_d_sub_ok(aep.x, (s * cos(rotation)), ec);
+ aep.y = dk3ma_d_sub_ok(aep.y, (s * sin(rotation)), ec);
+ }
+ po[0].x = -0.75 * ah->he;
+ po[0].y = 0.5 * ah->wi;
+ po[1].x = 0.0;
+ po[1].y = 0.0;
+ po[2].x = po[0].x;
+ po[2].y = -0.5 * ah->wi;
+ po[3].x = -1.0 * ah->he;
+ po[3].y = 0.0;
+ for(i = 0; i < 4; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), rotation, ec);
+ dk3fig_tool_shift_point(&(po[i]), aep.x, aep.y, ec);
+ }
+ if(ah->af) {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, obj->pc, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 4, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ } else {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, 7, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 4, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ }
+ if(ah->o1) {
+ if((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po) {
+ dk3mem_cpy(
+ (void *)((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po),
+ (void *)po,
+ (4 * sizeof(dk3_fig_poly_point_t))
+ );
+ back = 1;
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } break;
+ case DK3_FIG_AS_RHOMBUS: {
+ if((DK3_FIG_SRCTYPE_JFIG == drw->srctype) && (ah->af)) {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_ELLIPSE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, obj->pc, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 0, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ if(ah->o1) {
+ (((dk3_fig_obj_t *)(ah->o1))->dt).ell.an = 0.0;
+ (((dk3_fig_obj_t *)(ah->o1))->dt).ell.cx = aep.x;
+ (((dk3_fig_obj_t *)(ah->o1))->dt).ell.cy = aep.y;
+ (((dk3_fig_obj_t *)(ah->o1))->dt).ell.rx = ah->he;
+ (((dk3_fig_obj_t *)(ah->o1))->dt).ell.ry = ah->he;
+ back = 1;
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } else {
+ if(!(drw->coah)) {
+ s = dk3figah_s(drw, obj, ah, ec);
+ aep.x = dk3ma_d_sub_ok(aep.x, (s * cos(rotation)), ec);
+ aep.y = dk3ma_d_sub_ok(aep.y, (s * sin(rotation)), ec);
+ }
+ po[0].x = -1.0 * ah->he;
+ po[0].y = 0.0;
+ po[1].x = -0.5 * ah->he;
+ po[1].y = 0.5 * ah->wi;
+ po[2].x = 0.0;
+ po[2].y = 0.0;
+ po[3].x = -0.5 * ah->he;
+ po[3].y = -0.5 * ah->wi;
+ for(i = 0; i < 4; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), rotation, ec);
+ dk3fig_tool_shift_point(&(po[i]), aep.x, aep.y, ec);
+ }
+ if(ah->af) {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, obj->pc, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 4, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ } else {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, 7, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 4, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ }
+ if(ah->o1) {
+ if((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po) {
+ dk3mem_cpy(
+ (void *)((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po),
+ (void *)po,
+ (4 * sizeof(dk3_fig_poly_point_t))
+ );
+ back = 1;
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ }
+ } break;
+ case DK3_FIG_AS_FULL_CIRCLE_END: {
+ s = 0.5 * dk3fig_tool_get_lw(drw, obj, ec);
+ aep.x = dk3ma_d_sub_ok(aep.x, (0.5 * ah->he * cos(rotation)), ec);
+ aep.y = dk3ma_d_sub_ok(aep.y, (0.5 * ah->he * sin(rotation)), ec);
+ if(!(drw->coah)) {
+ aep.x = dk3ma_d_sub_ok(aep.x, (s * cos(rotation)), ec);
+ aep.y = dk3ma_d_sub_ok(aep.y, (s * sin(rotation)), ec);
+ }
+ if(ah->af) {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_ELLIPSE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, obj->pc, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 0, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ } else {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_ELLIPSE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, 7, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 0, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ }
+ if(ah->o1) {
+ (((dk3_fig_obj_t *)(ah->o1))->dt).ell.an = 0.0;
+ (((dk3_fig_obj_t *)(ah->o1))->dt).ell.cx = aep.x;
+ (((dk3_fig_obj_t *)(ah->o1))->dt).ell.cy = aep.y;
+ (((dk3_fig_obj_t *)(ah->o1))->dt).ell.rx = 0.5 * ah->he;
+ (((dk3_fig_obj_t *)(ah->o1))->dt).ell.ry = 0.5 * ah->he;
+ back = 1;
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } break;
+ case DK3_FIG_AS_HALF_CIRCLE_END: {
+ if(ah->af) {
+ if(!(drw->coah)) {
+ s = 0.5 * dk3fig_tool_get_lw(drw, obj, ec);
+ aep.x = dk3ma_d_sub_ok(aep.x, (s * cos(rotation)), ec);
+ aep.y = dk3ma_d_sub_ok(aep.y, (s * sin(rotation)), ec);
+ }
+ }
+ if(ah->af) {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_PSEUDO_HALF_CIRCLE, 1, /* Object type, subtype */
+ obj->lw, obj->pc, obj->pc, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 0, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ } else {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_PSEUDO_HALF_CIRCLE, 0, /* Object type, subtype */
+ obj->lw, obj->pc, 7, -1, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 0, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ }
+ if(ah->o1) {
+
+#line 1620 "dk3figah.ctr"
+ (((dk3_fig_obj_t *)(ah->o1))->dt).hci.cx = aep.x;
+ (((dk3_fig_obj_t *)(ah->o1))->dt).hci.cy = aep.y;
+ (((dk3_fig_obj_t *)(ah->o1))->dt).hci.ra = 0.5 * ah->he;
+ (((dk3_fig_obj_t *)(ah->o1))->dt).hci.an = rotation;
+ back = 1;
+ } else {
+
+#line 1626 "dk3figah.ctr"
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } break;
+ case DK3_FIG_AS_RECTANGLE: {
+ if(!(drw->coah)) {
+ s = 0.5 * dk3fig_tool_get_lw(drw, obj, ec);
+ aep.x = dk3ma_d_sub_ok(aep.x, (s * cos(rotation)), ec);
+ aep.y = dk3ma_d_sub_ok(aep.y, (s * sin(rotation)), ec);
+ }
+ po[0].x = -1.0 * ah->he;
+ po[0].y = 0.5 * ah->wi;
+ po[1].x = 0.0;
+ po[1].y = po[0].y;
+ po[2].x = 0.0;
+ po[2].y = -0.5 * ah->wi;
+ po[3].x = po[0].x;
+ po[3].y = po[2].y;
+ for(i = 0; i < 4; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), rotation, ec);
+ dk3fig_tool_shift_point(&(po[i]), aep.x, aep.y, ec);
+ }
+ if(ah->af) {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, obj->pc, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 4, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ } else {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, 7, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 4, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ }
+ if(ah->o1) {
+ if((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po) {
+ dk3mem_cpy(
+ (void *)((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po),
+ po,
+ (4 * sizeof(dk3_fig_poly_point_t))
+ );
+ (((dk3_fig_obj_t *)(ah->o1))->dt).pol.np = 4;
+ back = 1;
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } break;
+ case DK3_FIG_AS_INVERSE: {
+ if(!(drw->coah)) {
+ s = 0.5 * dk3fig_tool_get_lw(drw, obj, ec);
+ aep.x = dk3ma_d_sub_ok(aep.x, (s * cos(rotation)), ec);
+ aep.y = dk3ma_d_sub_ok(aep.y, (s * sin(rotation)), ec);
+ }
+ po[0].x = -1.0 * ah->he;
+ po[0].y = 0.0;
+ po[1].x = 0.0;
+ po[1].y = 0.5 * ah->wi;
+ po[2].x = 0.0;
+ po[2].y = -0.5 * ah->wi;
+ for(i = 0; i < 3; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), rotation, ec);
+ dk3fig_tool_shift_point(&(po[i]), aep.x, aep.y, ec);
+ }
+ if(ah->af) {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, obj->pc, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 3, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ } else {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, 7, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 3, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ }
+ if(ah->o1) {
+ if((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po) {
+ dk3mem_cpy(
+ (void *)((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po),
+ po,
+ (3 * sizeof(dk3_fig_poly_point_t))
+ );
+ (((dk3_fig_obj_t *)(ah->o1))->dt).pol.np = 3;
+ back = 1;
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } break;
+ case DK3_FIG_AS_INDENTED_FILLED_HALF: {
+#if 0
+ s = 0.0;
+ if(!(drw->coah)) {
+ s = dk3figah_s(drw, obj, ah, ec);
+ aep.x = dk3ma_d_sub_ok(aep.x, (s * cos(rotation)), ec);
+ aep.y = dk3ma_d_sub_ok(aep.y, (s * sin(rotation)), ec);
+ }
+ po[0].x = -1.0 * ah->he;
+ po[0].y = 0.0;
+ po[1].x = -1.25 * ah->he;
+ if(ah->af) {
+ po[1].y = 0.5 * ah->wi;
+ } else {
+ po[1].y = -0.5 * ah->wi;
+ }
+ po[2].x = 0.0;
+ po[2].y = 0.0;
+ po[3].x = po[1].x;
+ if(ah->af) {
+ po[3].y = -0.5 * ah->wi;
+ } else {
+ po[3].y = 0.5 * ah->wi;
+ }
+ for(i = 0; i < 4; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), rotation, ec);
+ dk3fig_tool_shift_point(&(po[i]), aep.x, aep.y, ec);
+ }
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, 7, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 4, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ if(ah->o1) {
+ if((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po) {
+ dk3mem_cpy(
+ (void *)((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po),
+ po,
+ (4 * sizeof(dk3_fig_poly_point_t))
+ );
+ (((dk3_fig_obj_t *)(ah->o1))->dt).pol.np = 4;
+ ah->o2 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, obj->pc, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 3, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ if(ah->o2) {
+ if((((dk3_fig_obj_t *)(ah->o2))->dt).pol.po) {
+ dk3mem_cpy(
+ (void *)((((dk3_fig_obj_t *)(ah->o2))->dt).pol.po),
+ po,
+ (3 * sizeof(dk3_fig_poly_point_t))
+ );
+ (((dk3_fig_obj_t *)(ah->o2))->dt).pol.np = 3;
+ back = 1;
+ }
+ }
+ }
+ }
+#else
+ if(!(drw->coah)) {
+ s = dk3figah_s(drw, obj, ah, ec);
+ aep.x = dk3ma_d_sub_ok(aep.x, (s * cos(rotation)), ec);
+ aep.y = dk3ma_d_sub_ok(aep.y, (s * sin(rotation)), ec);
+ }
+ po[0].x = -1.0 * ah->he;
+ po[0].y = 0.0;
+ po[1].x = dk3ma_d_mul_ok(-1.25, ah->he, ec);
+ if(ah->af) {
+ po[1].y = 0.5 * ah->wi;
+ } else {
+ po[1].y = -0.5 * ah->wi;
+ }
+ po[2].x = 0.0;
+ po[2].y = 0.0;
+ po[3].x = dk3ma_d_mul_ok(-1.25, ah->he, ec);
+ if(ah->af) {
+ po[3].y = -0.5 * ah->wi;
+ } else {
+ po[3].y = 0.5 * ah->wi;
+ }
+ for(i = 0; i < 4; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), rotation, ec);
+ dk3fig_tool_shift_point(&(po[i]), aep.x, aep.y, ec);
+ }
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, 7, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 4, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ if(ah->o1) {
+ if((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po) {
+ dk3mem_cpy(
+ (void *)((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po),
+ (void *)po,
+ (4 * sizeof(dk3_fig_poly_point_t))
+ );
+ (((dk3_fig_obj_t *)(ah->o1))->dt).pol.np = 4;
+ ah->o2 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ 0, obj->pc, obj->pc, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 3, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ if(ah->o2) {
+ if((((dk3_fig_obj_t *)(ah->o2))->dt).pol.po) {
+ dk3mem_cpy(
+ (void *)((((dk3_fig_obj_t *)(ah->o2))->dt).pol.po),
+ (void *)po,
+ (3 * sizeof(dk3_fig_poly_point_t))
+ );
+ (((dk3_fig_obj_t *)(ah->o2))->dt).pol.np = 3;
+ back = 1;
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+#endif
+ } break;
+ case DK3_FIG_AS_CLOSED_HALF: {
+ if(!(drw->coah)) {
+ s = dk3figah_s(drw, obj, ah, ec);
+ aep.x = dk3ma_d_sub_ok(aep.x, (s * cos(rotation)), ec);
+ aep.y = dk3ma_d_sub_ok(aep.y, (s * sin(rotation)), ec);
+ }
+ po[0].x = -1.0 * ah->he;
+ po[0].y = 0.0;
+ po[1].x = -1.0 * ah->he;
+ po[1].y = 0.5 * ah->wi;
+ po[2].x = 0.0;
+ po[2].y = 0.0;
+ for(i = 0; i < 3; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), rotation, ec);
+ dk3fig_tool_shift_point(&(po[i]), aep.x, aep.y, ec);
+ }
+ if(ah->af) {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, obj->pc, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 3, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ } else {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, 7, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 3, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ }
+ if(ah->o1) {
+ if((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po) {
+ dk3mem_cpy(
+ (void *)((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po),
+ po,
+ (3 * sizeof(dk3_fig_poly_point_t))
+ );
+ (((dk3_fig_obj_t *)(ah->o1))->dt).pol.np = 3;
+ back = 1;
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } break;
+ case DK3_FIG_AS_INDENTED_HALF: {
+ if(!(drw->coah)) {
+ s = dk3figah_s(drw, obj, ah, ec);
+ aep.x = dk3ma_d_sub_ok(aep.x, (s * cos(rotation)), ec);
+ aep.y = dk3ma_d_sub_ok(aep.y, (s * sin(rotation)), ec);
+ }
+ po[0].x = -1.0 * ah->he;
+ po[0].y = 0.0;
+ po[1].x = -1.25 * ah->he;
+ po[1].y = 0.5 * ah->wi;
+ po[2].x = 0.0;
+ po[2].y = 0.0;
+ for(i = 0; i < 3; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), rotation, ec);
+ dk3fig_tool_shift_point(&(po[i]), aep.x, aep.y, ec);
+ }
+ if(ah->af) {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, obj->pc, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 3, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ } else {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, 7, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 3, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ }
+ if(ah->o1) {
+ if((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po) {
+ dk3mem_cpy(
+ (void *)((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po),
+ po,
+ (3 * sizeof(dk3_fig_poly_point_t))
+ );
+ (((dk3_fig_obj_t *)(ah->o1))->dt).pol.np = 3;
+ back = 1;
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } break;
+ case DK3_FIG_AS_BUTTED_HALF: {
+ if(!(drw->coah)) {
+ s = dk3figah_s(drw, obj, ah, ec);
+ aep.x = dk3ma_d_sub_ok(aep.x, (s * cos(rotation)), ec);
+ aep.y = dk3ma_d_sub_ok(aep.y, (s * sin(rotation)), ec);
+ }
+ po[0].x = -1.0 * ah->he;
+ po[0].y = 0.0;
+ po[1].x = -0.75 * ah->he;
+ po[1].y = 0.5 * ah->wi;
+ po[2].x = 0.0;
+ po[2].y = 0.0;
+ for(i = 0; i < 3; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), rotation, ec);
+ dk3fig_tool_shift_point(&(po[i]), aep.x, aep.y, ec);
+ }
+ if(ah->af) {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, obj->pc, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 3, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ } else {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, 7, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 3, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ }
+ if(ah->o1) {
+ if((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po) {
+ dk3mem_cpy(
+ (void *)((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po),
+ po,
+ (3 * sizeof(dk3_fig_poly_point_t))
+ );
+ (((dk3_fig_obj_t *)(ah->o1))->dt).pol.np = 3;
+ back = 1;
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } break;
+ case DK3_FIG_AS_TRIANGLE_FORK: {
+ if(ah->af) {
+ if(!(drw->coah)) {
+ s = 0.5 * dk3fig_tool_get_lw(drw, obj, ec);
+ aep.x = dk3ma_d_sub_ok(aep.x, (s * cos(rotation)), ec);
+ aep.y = dk3ma_d_sub_ok(aep.y, (s * sin(rotation)), ec);
+ }
+ po[0].x = 0.0;
+ po[0].y = 0.5 * ah->wi;
+ po[1].x = 0.0;
+ po[1].y = -0.5 * ah->wi;
+ for(i = 0; i < 2; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), rotation, ec);
+ dk3fig_tool_shift_point(&(po[i]), aep.x, aep.y, ec);
+ }
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 1, /* Object type, subtype */
+ obj->lw, obj->pc, obj->pc, -1, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 2, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ if(ah->o1) {
+ if((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po) {
+ dk3mem_cpy(
+ (void *)((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po),
+ po,
+ (2 * sizeof(dk3_fig_poly_point_t))
+ );
+ (((dk3_fig_obj_t *)(ah->o1))->dt).pol.np = 2;
+ back = 1;
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } else {
+ po[0].x = 0.0;
+ po[0].y = 0.5 * ah->wi;
+ po[1].x = -1.0 * ah->he;
+ po[1].y = 0.0;
+ po[2].x = 0.0;
+ po[2].y = -0.5 * ah->wi;
+ for(i = 0; i < 3; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), rotation, ec);
+ dk3fig_tool_shift_point(&(po[i]), aep.x, aep.y, ec);
+ }
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 1, /* Object type, subtype */
+ obj->lw, obj->pc, obj->pc, -1, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 3, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ if(ah->o1) {
+ if((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po) {
+ dk3mem_cpy(
+ (void *)((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po),
+ po,
+ (3 * sizeof(dk3_fig_poly_point_t))
+ );
+ (((dk3_fig_obj_t *)(ah->o1))->dt).pol.np = 3;
+ back = 1;
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ }
+ } break;
+ case DK3_FIG_AS_RECTANGLE_FORK: {
+ if(ah->af) {
+ if(!(drw->coah)) {
+ s = 0.5 * dk3fig_tool_get_lw(drw, obj, ec);
+ aep.x = dk3ma_d_sub_ok(aep.x, (s * cos(rotation)), ec);
+ aep.y = dk3ma_d_sub_ok(aep.y, (s * sin(rotation)), ec);
+ }
+ po[0].x = -1.0 * ah->he;
+ po[0].y = 0.5 * ah->wi;
+ po[1].x = 0.0;
+ po[1].y = 0.5 * ah->wi;
+ po[2].x = 0.0;
+ po[2].y = -0.5 * ah->wi;
+ po[3].x = -1.0 * ah->he;
+ po[3].y = -0.5 * ah->wi;
+ } else {
+ po[0].x = 0.0;
+ po[0].y = 0.5 * ah->wi;
+ po[1].x = -1.0 * ah->he;
+ po[1].y = 0.5 * ah->wi;
+ po[2].x = -1.0 * ah->he;
+ po[2].y = -0.5 * ah->wi;
+ po[3].x = 0.0;
+ po[3].y = -0.5 * ah->wi;
+ }
+ for(i = 0; i < 4; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), rotation, ec);
+ dk3fig_tool_shift_point(&(po[i]), aep.x, aep.y, ec);
+ }
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 1, /* Object type, subtype */
+ obj->lw, obj->pc, obj->pc, -1, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 4, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ if(ah->o1) {
+ if((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po) {
+ dk3mem_cpy(
+ (void *)((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po),
+ po,
+ (4 * sizeof(dk3_fig_poly_point_t))
+ );
+ (((dk3_fig_obj_t *)(ah->o1))->dt).pol.np = 4;
+ back = 1;
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } break;
+ }
+
+
+#line 2218 "dk3figah.ctr"
+ return back;
+}
+
+
+
+/** Calculate arrowheads for polyline.
+ @param drw Drawing to modify.
+ @param obj Object to modify.
+ @param objno Object number.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figah_calculate_polyline(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ unsigned long objno
+)
+{
+ dk3_fig_poly_point_t *po; /* Points of the polyline. */
+ double cuts = -1.0; /* Cut at start. */
+ double cute = -1.0; /* Cut at end. */
+ double alphaf = 0.0; /* Direction of forward arrowhead. */
+ double alphab = 0.0; /* Direction of backward arrowhead. */
+ size_t np; /* Number of points in polyline. */
+ int mec = 0; /* Math error code. */
+ int res = 0; /* Arrowhead creation result. */
+ int back = 1;
+
+
+#line 2247 "dk3figah.ctr"
+ np = (obj->dt).pol.np;
+ po = (obj->dt).pol.po;
+ if((1 < np) && (po)) {
+ /*
+ Calculate line cuttings for arrowhead.
+ */
+ if(obj->af) {
+ cute = dk3figah_length_correction(drw, obj, obj->af, &mec);
+ }
+ if(obj->ab) {
+ cuts = dk3figah_length_correction(drw, obj, obj->ab, &mec);
+ }
+
+#line 2259 "dk3figah.ctr"
+ /*
+ Create arrowhead objects.
+ */
+ if(obj->af) {
+ alphaf = dk3ma_d_atan2(
+ dk3ma_d_sub_ok(po[np - 1].y, po[np - 2].y, &mec),
+ dk3ma_d_sub_ok(po[np - 1].x, po[np - 2].x, &mec)
+ );
+ }
+ if(obj->ab) {
+ alphab = dk3ma_d_atan2(
+ dk3ma_d_sub_ok(po[0].y, po[1].y, &mec),
+ dk3ma_d_sub_ok(po[0].x, po[1].x, &mec)
+ );
+ }
+ if(obj->af) {
+ res = dk3figah_straight_arrowhead(
+ drw, obj, obj->af, &(po[np - 1]), alphaf, &mec
+ );
+ if(!(res)) { back = 0; }
+ }
+ if(obj->ab) {
+ res = dk3figah_straight_arrowhead(
+ drw, obj, obj->ab, &(po[0]), alphab, &mec
+ );
+ if(!(res)) { back = 0; }
+ }
+ /*
+ Cut first and last segment if necessary when not using compatible
+ arrowheads.
+ */
+ if(!(drw->coah)) {
+ if(0.0 < cuts) {
+ if(0 == dk3fig_tool_cut_segment(&(po[0]), &(po[1]), cuts, &mec)) {
+ np = (obj->dt).pol.np = np - 1;
+ dk3fig_tool_poly_point_move_left(&(po[0]), &(po[1]), np);
+ }
+ }
+ if((0.0 < cute) && (1 < np)) {
+ if(0 == dk3fig_tool_cut_segment(&(po[np - 1]),&(po[np - 2]),cute,&mec))
+ {
+ (obj->dt).pol.np = np - 1;
+ }
+ }
+ }
+ }
+ if(mec) {
+ back = 0;
+ /* ERROR: Math error in object! */
+ dk3app_log_i1(drw->app, DK3_LL_ERROR, 260);
+ dk3fig_set_ec(drw, DK3_ERROR_MATH_OVERFLOW);
+ }
+
+
+#line 2312 "dk3figah.ctr"
+ return back;
+}
+
+
+
+/** Calculate values for a given t.
+ @param drw Drawing object.
+ @param obj Fig object.
+ @param ah Arrowhead to modify.
+ @param xpos Pointer to x position variable.
+ @param ypos Pointer to y position variable.
+ @param phi Pointer to direction variable.
+ @param ab Flag: Is backward arrowhead (0=forward, 1=backward).
+ @param t The t value.
+ @param ec Pointer to error code variable.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figah_spline_values(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ double *xpos,
+ double *ypos,
+ double *phi,
+ int ab,
+ double t,
+ int *ec
+)
+{
+ double p;
+ int back = 0;
+ int mec = 0;
+ p = dk3xsp_direction_and_position(
+ xpos, ypos, (obj->dt).spl.po, (obj->dt).spl.np, t, drw->cosp, &mec
+ );
+ if(0.0 <= p) {
+ back = 1;
+ if(ab) {
+ p = p + M_PI;
+ while((2.0 * M_PI) < p) { p = p - (2.0 * M_PI);}
+ }
+ *phi = p;
+ if(mec) {
+ back = 0;
+ if(ec) { *ec = mec; }
+ }
+ }
+ return back;
+}
+
+
+
+#if TRACE_DEBUG
+/** Report spline points to debug file.
+ @param sp Spline points to report.
+ @param np Number of points to report.
+*/
+static
+void
+dk3figah_report_spline_points(
+ dk3_fig_spline_point_t *sp,
+ size_t np
+)
+{
+ FILE *fipo;
+ size_t i;
+ if((sp) && (np)) {
+ fipo = dktrace_file();
+ if(fipo) {
+ fputs("Spline points report:\n", fipo);
+ for(i = 0; i < np; i++) {
+ fprintf(
+ fipo,
+ "Point %5u:\tx = %lg \ty = %lg \ts = %lg\n",
+ (unsigned)i, sp[i].x, sp[i].y, sp[i].s
+ );
+ }
+ }
+ }
+}
+#endif
+
+
+
+/** Create arrowhead object on end of open spline.
+ @param drw Drawing object.
+ @param obj Fig object.
+ @param ah Arrowhead to modify.
+ @param ab Flag: Is backward arrowhead (0=forward, 1=backward).
+ @param ec Pointer to error code variable.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figah_one_spline_arrowhead(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int ab,
+ int *ec
+)
+{
+ dk3_xspline_segment_t seg; /* Segment for calculations. */
+ dk3_fig_poly_point_t pp[2]; /* For calculation. */
+ dk3_fig_poly_point_t *po; /* New polyline points. */
+ dk3_fig_obj_t *ao1 = NULL; /* Arrowhead object 1. */
+ dk3_fig_obj_t *ao2 = NULL; /* Arrowhead object 2. */
+ dk3_fig_spline_point_t *osp = NULL; /* Original spline points. */
+ dk3_fig_spline_point_t *sp = NULL; /* New spline points. */
+ dk3_fig_spline_point_t *sp2 = NULL; /* Spline points obj 2. */
+ double t0 = 0.0; /* Front point t. */
+ double t1 = 0.0; /* Current t. */
+ double t2 = 0.0; /* Arrow end point t. */
+ double t; /* Current t. */
+ double s = 0.0; /* Shift for front point. */
+ double l1 = 0.0; /* Segment 1 length. */
+ double l2 = 0.0; /* Segment 2 length. */
+ double xpos = 0.0; /* X position. */
+ double ypos = 0.0; /* Y position. */
+ double phi = 0.0; /* Angle at position. */
+ double lw = 0.0; /* Line width. */
+ double dist = 0.0; /* Distance to end point. */
+ size_t onp = 0; /* Object number of points. */
+ size_t n1 = 0; /* Number of sub-segments 1. */
+ size_t n2 = 0; /* Number of sub-segments 2. */
+ size_t n3 = 0; /* Number of sub-segments 3. */
+ size_t np = 0; /* Number of points. */
+ size_t nq = 0; /* Number of points obj 2. */
+ size_t i;
+ size_t j;
+ int res = 0; /* Operation result. */
+ int mec = 0; /* Mathematical error code. */
+ int back = 0;
+
+
+#line 2448 "dk3figah.ctr"
+ osp = (obj->dt).spl.po;
+ onp = (obj->dt).spl.np;
+ t0 = ((ab) ? 0.0 : (double)(onp - 1));
+ lw = dk3fig_tool_get_lw(drw, obj, &mec);
+ s = dk3figah_find_shift_length(drw, obj, ah, &mec);
+ switch(ah->as) {
+ case DK3_FIG_AS_STICK:
+ case DK3_FIG_AS_CLOSED: {
+
+#line 2456 "dk3figah.ctr"
+ t0 = dk3xsp_get_t_for_distance(
+ osp, onp, s, drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if(0.0 <= t0) {
+ t1 = dk3xsp_get_t_for_distance(
+ osp, onp, dk3ma_d_add_ok(s, ah->he, &mec),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if(0.0 <= t1) {
+
+#line 2465 "dk3figah.ctr"
+ n1 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(fabs(t1 - t0), drw->splspp, &mec)), &mec
+ );
+ if(n1 < drw->minspp) { n1 = drw->minspp; }
+ np = dk3mem_add_size_t(dk3mem_mul_size_t(2, n1, &mec), 1, &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la,
+ DK3_FIG_OBJ_SPLINE,
+ ((DK3_FIG_AS_CLOSED == ah->as) ? 5 : 4),
+ obj->lw, obj->pc, ((ah->af) ? obj->pc : 7),
+ ((DK3_FIG_AS_CLOSED == ah->as) ? 20 : -1),
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1;
+ res = dk3xsp_calculate_position(
+ &seg, osp, onp, t0, drw->cosp, 0, &mec
+ );
+ if(res) {
+
+#line 2489 "dk3figah.ctr"
+ sp[n1].x = dk3xsp_get_x(&seg);
+ sp[n1].y = dk3xsp_get_y(&seg);
+ sp[n1].s = 0.0;
+
+#line 2492 "dk3figah.ctr"
+ for(i = 0; i < n1; i++) {
+ j = i + 1;
+
+#line 2494 "dk3figah.ctr"
+ if(j == n1) {
+ t = t1;
+ } else {
+ dist = dk3ma_d_add_ok(
+ s, (((double)j / (double)n1) * ah->he), &mec
+ );
+
+#line 2500 "dk3figah.ctr"
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+
+#line 2504 "dk3figah.ctr"
+
+
+#line 2505 "dk3figah.ctr"
+ }
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+
+#line 2510 "dk3figah.ctr"
+ if(res) {
+ pp[0].x = pp[1].x = 0.0;
+ if(j == n1) {
+ pp[0].y = 0.5 * ah->wi;
+ } else {
+ pp[0].y = 0.5 * ah->wi * ((double)j / (double)n1);
+ }
+ pp[1].y = -1.0 * pp[0].y;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+ sp[n1 - j].x = pp[0].x;
+
+#line 2523 "dk3figah.ctr"
+ sp[n1 - j].y = pp[0].y;
+
+#line 2524 "dk3figah.ctr"
+ sp[n1 + j].x = pp[1].x;
+ sp[n1 + j].y = pp[1].y;
+ sp[n1 - j].s = sp[n1 + j].s =
+ ((j == n1) ? 0.0 : (-1.0));
+ } else {
+ back = 0; i = n1;
+
+#line 2530 "dk3figah.ctr"
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } else {
+
+#line 2533 "dk3figah.ctr"
+ back = 0; i = n1;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ }
+ } else {
+
+#line 2538 "dk3figah.ctr"
+ back = 0;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+
+#line 2541 "dk3figah.ctr"
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ }
+ }
+ }
+ } break;
+ case DK3_FIG_AS_INDENTED: {
+
+#line 2550 "dk3figah.ctr"
+ l1 = dk3ma_d_mul_ok(1.25, ah->he, &mec);
+ l2 = 0.25 * ah->he;
+ t0 = dk3xsp_get_t_for_distance(
+ osp, onp, s, drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ t1 = dk3xsp_get_t_for_distance(
+ osp, onp, dk3ma_d_add_ok(s, l1, &mec),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ t2 = dk3xsp_get_t_for_distance(
+ osp, onp, dk3ma_d_add_ok(s, ah->he, &mec),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if((0.0 <= t0) && (0.0 <= t1) && (0.0 <= t2)) {
+
+#line 2564 "dk3figah.ctr"
+ n1 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(drw->splspp, fabs(t1 - t0), &mec)), &mec
+ );
+
+#line 2567 "dk3figah.ctr"
+ n2 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(drw->splspp, fabs(t1 - t2), &mec)), &mec
+ );
+ if(n1 < drw->minspp) { n1 = drw->minspp; }
+ if(n2 < drw->minspp) { n2 = drw->minspp; }
+ np = dk3mem_mul_size_t(2, dk3mem_add_size_t(n1, n2, &mec), &mec);
+ if(0 == mec) {
+
+#line 2574 "dk3figah.ctr"
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 5,
+ obj->lw, obj->pc, ((ah->af) ? obj->pc : 7), 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1;
+ res = dk3xsp_calculate_position(
+ &seg, osp, onp, t0, drw->cosp, 0, &mec
+ );
+ if(res) {
+
+#line 2589 "dk3figah.ctr"
+ sp[n1 + n2 - 1].x = dk3xsp_get_x(&seg);
+ sp[n1 + n2 - 1].y = dk3xsp_get_y(&seg);
+ sp[n1 + n2 - 1].s = 0.0;
+
+#line 2592 "dk3figah.ctr"
+ for(i = 0; i < n1; i++) {
+ j = i + 1;
+ if(j == n1) {
+ t = t1;
+ } else {
+ dist = dk3ma_d_add_ok(
+ s, (((double)j / (double)n1) * l1), &mec
+ );
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ }
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+ if(res) {
+ pp[0].x = pp[1].x = 0.0;
+ if(j == n1) {
+ pp[0].y = 0.5 * ah->wi;
+ } else {
+ pp[0].y = 0.5 * ah->wi * ((double)j / (double)n1);
+ }
+ pp[1].y = -1.0 * pp[0].y;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+ sp[n1 + n2 - 1 - j].x = pp[0].x;
+ sp[n1 + n2 - 1 - j].y = pp[0].y;
+
+
+#line 2624 "dk3figah.ctr"
+ sp[n1 + n2 - 1 + j].x = pp[1].x;
+ sp[n1 + n2 - 1 + j].y = pp[1].y;
+
+
+#line 2627 "dk3figah.ctr"
+ sp[n1 + n2 - 1 - j].s = sp[n1 + n2 - 1 + j].s =
+ ((j == n1) ? 0.0 : (-1.0));
+ } else {
+ back = 0; i = n1;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } else {
+ back = 0; i = n1;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ }
+ if(back) {
+ for(i = 0; i < (n2 - 1); i++) {
+ j = i + 1;
+ dist = dk3ma_d_sub_ok(
+ dk3ma_d_add_ok(s, l1, &mec),
+ (l2 * ((double)j / (double)n2)),
+ &mec
+ );
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+ if(res) {
+ pp[0].x = pp[1].x = 0.0;
+ pp[0].y = 0.5 * ah->wi * (1.0 - ((double)j/(double)n2));
+ pp[1].y = -1.0 * pp[0].y;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+ sp[n2 - 1 - j].x = pp[0].x;
+ sp[n2 - 1 - j].y = pp[0].y;
+
+
+#line 2665 "dk3figah.ctr"
+ sp[2 * n1 + n2 - 1 + j].x = pp[1].x;
+ sp[2 * n1 + n2 - 1 + j].y = pp[1].y;
+
+
+#line 2668 "dk3figah.ctr"
+ sp[n2 - 1 - j].s = sp[2 * n1 + n2 - 1 + j].s =
+ ((j == n1) ? 0.0 : (-1.0));
+ } else {
+ back = 0; i = n2;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } else {
+ back = 0; i = n2;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ }
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t2, &mec
+ );
+ if(res) {
+ sp[np - 1].x = xpos;
+ sp[np - 1].y = ypos;
+ sp[np - 1].s = 0.0;
+
+#line 2686 "dk3figah.ctr"
+ } else {
+ back = 0;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ }
+ } else {
+ back = 0;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+
+#line 2695 "dk3figah.ctr"
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } else {
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } else {
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } break;
+ case DK3_FIG_AS_POINTED: {
+
+#line 2707 "dk3figah.ctr"
+ l1 = 0.75 * ah->he;
+ l2 = 0.25 * ah->he;
+ t0 = dk3xsp_get_t_for_distance(
+ osp, onp, s, drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ t1 = dk3xsp_get_t_for_distance(
+ osp, onp, dk3ma_d_add_ok(s, l1, &mec),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ t2 = dk3xsp_get_t_for_distance(
+ osp, onp, dk3ma_d_add_ok(s, ah->he, &mec),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if((0.0 <= t0) && (0.0 <= t1) && (0.0 <= t2)) {
+
+#line 2721 "dk3figah.ctr"
+ n1 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(drw->splspp, fabs(t1 - t0), &mec)), &mec
+ );
+
+#line 2724 "dk3figah.ctr"
+ n2 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(drw->splspp, fabs(t1 - t2), &mec)), &mec
+ );
+ if(n1 < drw->minspp) { n1 = drw->minspp; }
+ if(n2 < drw->minspp) { n2 = drw->minspp; }
+ np = dk3mem_mul_size_t(2, dk3mem_add_size_t(n1, n2, &mec), &mec);
+ if(0 == mec) {
+
+#line 2731 "dk3figah.ctr"
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 5,
+ obj->lw, obj->pc, ((ah->af) ? obj->pc : 7), 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1;
+ res = dk3xsp_calculate_position(
+ &seg, osp, onp, t0, drw->cosp, 0, &mec
+ );
+ if(res) {
+
+#line 2746 "dk3figah.ctr"
+ sp[n1 + n2 - 1].x = dk3xsp_get_x(&seg);
+ sp[n1 + n2 - 1].y = dk3xsp_get_y(&seg);
+ sp[n1 + n2 - 1].s = 0.0;
+
+#line 2749 "dk3figah.ctr"
+ for(i = 0; i < n1; i++) {
+ j = i + 1;
+ if(j == n1) {
+ t = t1;
+ } else {
+ dist = dk3ma_d_add_ok(
+ s, (((double)j / (double)n1) * l1), &mec
+ );
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ }
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+ if(res) {
+ pp[0].x = pp[1].x = 0.0;
+ if(j == n1) {
+ pp[0].y = 0.5 * ah->wi;
+ } else {
+ pp[0].y = 0.5 * ah->wi * ((double)j / (double)n1);
+ }
+ pp[1].y = -1.0 * pp[0].y;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+ sp[n1 + n2 - 1 - j].x = pp[0].x;
+ sp[n1 + n2 - 1 - j].y = pp[0].y;
+
+
+#line 2781 "dk3figah.ctr"
+ sp[n1 + n2 - 1 + j].x = pp[1].x;
+ sp[n1 + n2 - 1 + j].y = pp[1].y;
+
+
+#line 2784 "dk3figah.ctr"
+ sp[n1 + n2 - 1 - j].s = sp[n1 + n2 - 1 + j].s =
+ ((j == n1) ? 0.0 : (-1.0));
+ } else {
+ back = 0; i = n1;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } else {
+ back = 0; i = n1;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ }
+ if(back) {
+ for(i = 0; i < (n2 - 1); i++) {
+ j = i + 1;
+ dist = dk3ma_d_add_ok(
+ dk3ma_d_add_ok(s, l1, &mec),
+ (l2 * ((double)j / (double)n2)),
+ &mec
+ );
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+ if(res) {
+ pp[0].x = pp[1].x = 0.0;
+ pp[0].y = 0.5 * ah->wi * (1.0 - ((double)j/(double)n2));
+ pp[1].y = -1.0 * pp[0].y;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+ sp[n2 - 1 - j].x = pp[0].x;
+ sp[n2 - 1 - j].y = pp[0].y;
+
+
+#line 2822 "dk3figah.ctr"
+ sp[2 * n1 + n2 - 1 + j].x = pp[1].x;
+ sp[2 * n1 + n2 - 1 + j].y = pp[1].y;
+
+
+#line 2825 "dk3figah.ctr"
+ sp[n2 - 1 - j].s = sp[2 * n1 + n2 - 1 + j].s =
+ ((j == n1) ? 0.0 : (-1.0));
+ } else {
+ back = 0; i = n2;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } else {
+ back = 0; i = n2;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ }
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t2, &mec
+ );
+ if(res) {
+ sp[np - 1].x = xpos;
+ sp[np - 1].y = ypos;
+ sp[np - 1].s = 0.0;
+
+#line 2843 "dk3figah.ctr"
+ } else {
+ back = 0;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ }
+ } else {
+ back = 0;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+
+#line 2852 "dk3figah.ctr"
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } else {
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } else {
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } break;
+ case DK3_FIG_AS_RHOMBUS: {
+ if((1 == ah->af) && (DK3_FIG_SRCTYPE_JFIG == drw->srctype)) {
+
+#line 2865 "dk3figah.ctr"
+ if(dk3xsp_calculate_position(&seg, osp, onp, t0, drw->cosp, 0, &mec)) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_ELLIPSE, 3,
+ obj->lw, obj->pc, obj->pc, 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, 0, NULL, drw->app
+ );
+ if(ao1) {
+ back = 1;
+ ah->o1 = (void *)ao1;
+ (ao1->dt).ell.an = 0.0;
+ (ao1->dt).ell.cx = dk3xsp_get_x(&seg);
+ (ao1->dt).ell.cy = dk3xsp_get_y(&seg);
+ (ao1->dt).ell.rx = dk3ma_d_mul_ok(2.0, ah->wi, &mec);
+ (ao1->dt).ell.ry = (ao1->dt).ell.rx;
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } else {
+
+#line 2884 "dk3figah.ctr"
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } else {
+
+#line 2887 "dk3figah.ctr"
+ l1 = 0.5 * ah->he;
+ l2 = l1;
+ t0 = dk3xsp_get_t_for_distance(
+ osp, onp, s, drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ t1 = dk3xsp_get_t_for_distance(
+ osp, onp, dk3ma_d_add_ok(s, l1, &mec),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ t2 = dk3xsp_get_t_for_distance(
+ osp, onp, dk3ma_d_add_ok(s, ah->he, &mec),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if((0.0 <= t0) && (0.0 <= t1) && (0.0 <= t2)) {
+
+#line 2901 "dk3figah.ctr"
+ n1 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(drw->splspp, fabs(t1 - t0), &mec)), &mec
+ );
+
+#line 2904 "dk3figah.ctr"
+ n2 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(drw->splspp, fabs(t1 - t2), &mec)), &mec
+ );
+ if(n1 < drw->minspp) { n1 = drw->minspp; }
+ if(n2 < drw->minspp) { n2 = drw->minspp; }
+ np = dk3mem_mul_size_t(2, dk3mem_add_size_t(n1, n2, &mec), &mec);
+ if(0 == mec) {
+
+#line 2911 "dk3figah.ctr"
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 5,
+ obj->lw, obj->pc, ((ah->af) ? obj->pc : 7), 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1;
+ res = dk3xsp_calculate_position(
+ &seg, osp, onp, t0, drw->cosp, 0, &mec
+ );
+ if(res) {
+
+#line 2926 "dk3figah.ctr"
+ sp[n1 + n2 - 1].x = dk3xsp_get_x(&seg);
+ sp[n1 + n2 - 1].y = dk3xsp_get_y(&seg);
+ sp[n1 + n2 - 1].s = 0.0;
+
+#line 2929 "dk3figah.ctr"
+ for(i = 0; i < n1; i++) {
+ j = i + 1;
+ if(j == n1) {
+ t = t1;
+ } else {
+ dist = dk3ma_d_add_ok(
+ s, (((double)j / (double)n1) * l1), &mec
+ );
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ }
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+ if(res) {
+ pp[0].x = pp[1].x = 0.0;
+ if(j == n1) {
+ pp[0].y = 0.5 * ah->wi;
+ } else {
+ pp[0].y = 0.5 * ah->wi * ((double)j / (double)n1);
+ }
+ pp[1].y = -1.0 * pp[0].y;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+ sp[n1 + n2 - 1 - j].x = pp[0].x;
+ sp[n1 + n2 - 1 - j].y = pp[0].y;
+
+
+#line 2961 "dk3figah.ctr"
+ sp[n1 + n2 - 1 + j].x = pp[1].x;
+ sp[n1 + n2 - 1 + j].y = pp[1].y;
+
+
+#line 2964 "dk3figah.ctr"
+ sp[n1 + n2 - 1 - j].s = sp[n1 + n2 - 1 + j].s =
+ ((j == n1) ? 0.0 : (-1.0));
+ } else {
+ back = 0; i = n1;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } else {
+ back = 0; i = n1;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ }
+ if(back) {
+ for(i = 0; i < (n2 - 1); i++) {
+ j = i + 1;
+ dist = dk3ma_d_add_ok(
+ dk3ma_d_add_ok(s, l1, &mec),
+ (l2 * ((double)j / (double)n2)),
+ &mec
+ );
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+ if(res) {
+ pp[0].x = pp[1].x = 0.0;
+ pp[0].y = 0.5 * ah->wi * (1.0 - ((double)j/(double)n2));
+ pp[1].y = -1.0 * pp[0].y;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+ sp[n2 - 1 - j].x = pp[0].x;
+ sp[n2 - 1 - j].y = pp[0].y;
+
+
+#line 3002 "dk3figah.ctr"
+ sp[2 * n1 + n2 - 1 + j].x = pp[1].x;
+ sp[2 * n1 + n2 - 1 + j].y = pp[1].y;
+
+
+#line 3005 "dk3figah.ctr"
+ sp[n2 - 1 - j].s = sp[2 * n1 + n2 - 1 + j].s =
+ ((j == n1) ? 0.0 : (-1.0));
+ } else {
+ back = 0; i = n2;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } else {
+ back = 0; i = n2;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ }
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t2, &mec
+ );
+ if(res) {
+ sp[np - 1].x = xpos;
+ sp[np - 1].y = ypos;
+ sp[np - 1].s = 0.0;
+
+#line 3023 "dk3figah.ctr"
+ } else {
+ back = 0;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ }
+ } else {
+ back = 0;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+
+#line 3032 "dk3figah.ctr"
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } else {
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } else {
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ }
+ } break;
+ case DK3_FIG_AS_FULL_CIRCLE_END: {
+
+#line 3045 "dk3figah.ctr"
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t0, &mec
+ );
+ if(res) {
+#if VERSION_BEFORE_20121220
+ xpos = dk3ma_d_sub_ok(
+ xpos,
+ (0.5 * cos(phi) * dk3ma_d_add_ok((0.5 * ah->he), (0.5 * lw), &mec)),
+ &mec
+ );
+ ypos = dk3ma_d_sub_ok(
+ ypos,
+ (0.5 * sin(phi) * dk3ma_d_add_ok((0.5 * ah->he), (0.5 * lw), &mec)),
+ &mec
+ );
+#else
+ xpos = dk3ma_d_sub_ok(
+ xpos,
+ (cos(phi) * dk3ma_d_add_ok((0.5 * ah->he), (0.5 * lw), &mec)),
+ &mec
+ );
+ ypos = dk3ma_d_sub_ok(
+ ypos,
+ (sin(phi) * dk3ma_d_add_ok((0.5 * ah->he), (0.5 * lw), &mec)),
+ &mec
+ );
+#endif
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_ELLIPSE, 3,
+ obj->lw, obj->pc, ((ah->af) ? obj->pc : 7), 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, 0, NULL, drw->app
+ );
+ if(ao1) {
+ back = 1;
+ ah->o1 = (void *)ao1;
+ (ao1->dt).ell.an = 0.0;
+ (ao1->dt).ell.cx = xpos;
+ (ao1->dt).ell.cy = ypos;
+ (ao1->dt).ell.rx = 0.5 * ah->he;
+ (ao1->dt).ell.ry = (ao1->dt).ell.rx;
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ }
+ }
+ } break;
+ case DK3_FIG_AS_HALF_CIRCLE_END: {
+
+#line 3094 "dk3figah.ctr"
+ if(ah->af) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t0, &mec
+ );
+ if(res) {
+ xpos = dk3ma_d_sub_ok(xpos, (0.5 * lw * cos(phi)), &mec);
+ ypos = dk3ma_d_sub_ok(ypos, (0.5 * lw * sin(phi)), &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_PSEUDO_HALF_CIRCLE, 1,
+ obj->lw, obj->pc, obj->pc, 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, 0, NULL, drw->app
+ );
+ if(ao1) {
+ back = 1;
+ ah->o1 = (void *)ao1;
+ (ao1->dt).hci.cx = xpos;
+ (ao1->dt).hci.cy = ypos;
+ (ao1->dt).hci.ra = 0.5 * ah->he;
+ (ao1->dt).hci.an = phi;
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ }
+ }
+ } else {
+ t1 = dk3xsp_get_t_for_distance(
+ osp, onp, (0.5 * ah->he),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if(0.0 <= t1) {
+ dist = fabs(dk3ma_d_sub_ok(t1, t0, &mec));
+
+#line 3127 "dk3figah.ctr"
+ n1 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(dist, drw->splspp, &mec)),
+ &mec
+ );
+
+#line 3131 "dk3figah.ctr"
+ /* 2013-11-23
+ If we want to correct n1, we have to use ceil() in
+ the comparison too.
+ */
+ if(n1 < dk3ma_d_to_sz_ok(ceil(drw->arcspp), &mec)) {
+
+#line 3136 "dk3figah.ctr"
+ n1 = dk3ma_d_to_sz_ok(ceil(drw->arcspp), &mec);
+ }
+
+#line 3138 "dk3figah.ctr"
+ if(n1 < drw->minspp) {
+ n1 = drw->minspp;
+ }
+
+#line 3141 "dk3figah.ctr"
+ np = dk3mem_add_size_t(dk3mem_mul_size_t(2, n1, &mec), 1, &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 4,
+ obj->lw, obj->pc, 7, -1,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1;
+ res = dk3xsp_calculate_position(
+ &seg, osp, onp, t1, drw->cosp, 0, &mec
+ );
+ if(res) {
+
+#line 3158 "dk3figah.ctr"
+ sp[n1].x = dk3xsp_get_x(&seg);
+ sp[n1].y = dk3xsp_get_y(&seg);
+ sp[n1].s = -1.0;
+
+#line 3161 "dk3figah.ctr"
+ for(i = 0; i < n1; i++) {
+ j = i + 1;
+ t1 = dk3xsp_get_t_for_distance(
+ osp, onp,
+ (0.5 * ah->he * cos(M_PI_2 * ((double)j / (double)n1))),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if(0.0 <= t1) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t1, &mec
+ );
+ if(res) {
+ pp[0].x = 0.0;
+ pp[1].x = 0.0;
+ pp[0].y = 0.5 * ah->he
+ * sin(M_PI_2 * ((double)j / (double)n1));
+ pp[1].y = -1.0 * pp[0].y;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+ sp[n1 - j].x = pp[0].x;
+ sp[n1 - j].y = pp[0].y;
+
+#line 3184 "dk3figah.ctr"
+ sp[n1 + j].x = pp[1].x;
+
+#line 3185 "dk3figah.ctr"
+ sp[n1 + j].y = pp[1].y;
+ sp[n1 - j].s = sp[n1 + j].s =
+ ((j == n1) ? 0.0 : (-1.0));
+ } else {
+ back = 0; i = n1;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } else {
+ back = 0;
+ i = n1;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ }
+ } else {
+ back = 0;
+ /* ##### ERROR: Calculation failed! */
+ }
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ }
+ }
+ }
+ } break;
+ case DK3_FIG_AS_RECTANGLE: {
+
+#line 3211 "dk3figah.ctr"
+ t0 = dk3xsp_get_t_for_distance(
+ osp, onp, s, drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ t1 = dk3xsp_get_t_for_distance(
+ osp, onp, dk3ma_d_add_ok(s, ah->he, &mec),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if((0.0 <= t0) && (0.0 <= t1)) {
+
+#line 3219 "dk3figah.ctr"
+ n1 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(fabs(t1 - t0), drw->splspp, &mec)), &mec
+ );
+ if(n1 < drw->minspp) { n1 = drw->minspp; }
+ np = dk3mem_mul_size_t(2, dk3mem_add_size_t(n1, 1, &mec), &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 5,
+ obj->lw, obj->pc, ((ah->af) ? obj->pc : 7), 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1;
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t0, &mec
+ );
+ if(res) {
+
+#line 3240 "dk3figah.ctr"
+ pp[0].x = pp[1].x = 0;
+ pp[0].y = 0.5 * ah->wi;
+ pp[1].y = -0.5 * ah->wi;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+ sp[n1].x = pp[0].x;
+
+#line 3248 "dk3figah.ctr"
+ sp[n1].y = pp[0].y;
+
+#line 3249 "dk3figah.ctr"
+ sp[n1 + 1].x = pp[1].x;
+ sp[n1 + 1].y = pp[1].y;
+ sp[n1].s = sp[n1 + 1].s = 0.0;
+ for(i = 0; i < n1; i++) {
+ j = i + 1;
+ if(j == n1) {
+ t = t1;
+ } else {
+ dist = dk3ma_d_add_ok(
+ s, (ah->he * ((double)j / (double)n1)), &mec
+ );
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ }
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+ if(res) {
+ pp[0].x = pp[1].x = 0.0;
+ pp[0].y = 0.5 * ah->wi;
+ pp[1].y = -0.5 * ah->wi;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+ sp[n1 - j].x = pp[0].x;
+ sp[n1 - j].y = pp[0].y;
+
+
+#line 3280 "dk3figah.ctr"
+ sp[n1 + 1 + j].x = pp[1].x;
+ sp[n1 + 1 + j].y = pp[1].y;
+
+
+#line 3283 "dk3figah.ctr"
+ sp[n1 - j].s = sp[n1 + 1 + j].s =
+ ((j == n1) ? 0.0 : (-1.0));
+
+ } else {
+ back = 0; i = n1;
+ }
+ } else {
+ back = 0; i = n1;
+ }
+ }
+ } else {
+ back = 0;
+ }
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ }
+ } else {
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } break;
+ case DK3_FIG_AS_INVERSE: {
+
+#line 3306 "dk3figah.ctr"
+ t0 = dk3xsp_get_t_for_distance(
+ osp, onp, s, drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ t1 = dk3xsp_get_t_for_distance(
+ osp, onp, dk3ma_d_add_ok(s, ah->he, &mec),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if((0.0 <= t0) && (0.0 <= t1)) {
+
+#line 3314 "dk3figah.ctr"
+ n1 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(fabs(t1 - t0), drw->splspp, &mec)), &mec
+ );
+ if(n1 < drw->minspp) { n1 = drw->minspp; }
+ np = dk3mem_add_size_t(dk3mem_mul_size_t(2, n1, &mec), 1, &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 5,
+ obj->lw, obj->pc, ((ah->af) ? obj->pc : 7), 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1;
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t1, &mec
+ );
+ if(res) {
+
+#line 3335 "dk3figah.ctr"
+ sp[n1].x = xpos;
+ sp[n1].y = ypos;
+ sp[n1].s = 0.0;
+
+#line 3338 "dk3figah.ctr"
+ for(i = 0; i < n1; i++) {
+ j = i + 1;
+ if(j == n1) {
+ t = t0;
+ } else {
+ dist = dk3ma_d_add_ok(
+ s, ((1.0 - ((double)j / (double)n1)) * ah->he), &mec
+ );
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ }
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+ if(res) {
+ pp[0].x = pp[1].x = 0.0;
+ pp[0].y = 0.5 * ((double)j / (double)n1) * ah->wi;
+ pp[1].y = -1.0 * pp[0].y;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+ sp[n1 - j].x = pp[0].x; sp[n1 - j].y = pp[0].y;
+ sp[n1 + j].x = pp[1].x; sp[n1 + j].y = pp[1].y;
+
+
+#line 3366 "dk3figah.ctr"
+
+
+#line 3367 "dk3figah.ctr"
+ sp[n1 - j].s = sp[n1 + j].s = ((j == n1) ? 0.0 : (-1.0));
+ } else {
+ }
+ } else {
+ back = 0; i = n1;
+ }
+ }
+ } else {
+ back = 0;
+ }
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ }
+ }
+ } break;
+ case DK3_FIG_AS_INDENTED_FILLED_HALF: {
+
+#line 3385 "dk3figah.ctr"
+ l1 = dk3ma_d_mul_ok(1.25, ah->he, &mec);
+ l2 = 0.25 * ah->he;
+ t0 = dk3xsp_get_t_for_distance(
+ osp, onp, s, drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ t1 = dk3xsp_get_t_for_distance(
+ osp, onp, dk3ma_d_add_ok(s, l1, &mec),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ t2 = dk3xsp_get_t_for_distance(
+ osp, onp, dk3ma_d_add_ok(s, ah->he, &mec),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if((0.0 <= t0) && (0.0 <= t1) && (0.0 <= t2)) {
+
+#line 3399 "dk3figah.ctr"
+ n1 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(drw->splspp, fabs(t1 - t0), &mec)), &mec
+ );
+
+#line 3402 "dk3figah.ctr"
+ n2 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(drw->splspp, fabs(t1 - t2), &mec)), &mec
+ );
+
+#line 3405 "dk3figah.ctr"
+ n3 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(drw->splspp, fabs(t2 - t0), &mec)), &mec
+ );
+ if(n1 < drw->minspp) { n1 = drw->minspp; }
+ if(n2 < drw->minspp) { n2 = drw->minspp; }
+ if(n3 < drw->minspp) { n3 = drw->minspp; }
+ np = dk3mem_mul_size_t(2, dk3mem_add_size_t(n1, n2, &mec), &mec);
+ nq = dk3mem_add_size_t(dk3mem_add_size_t(n1, n2, &mec), n3, &mec);
+ if(0 == mec) {
+
+#line 3414 "dk3figah.ctr"
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 5,
+ obj->lw, obj->pc, 7, 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ ao2 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 5,
+ 0, obj->pc, obj->pc, 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, nq, NULL, drw->app
+ );
+ if(ao2) {
+ ah->o2 = (void *)ao2;
+ sp2 = (ao2->dt).spl.po;
+ if((sp) && (sp2)) {
+ back = 1;
+ res = dk3xsp_calculate_position(
+ &seg, osp, onp, t0, drw->cosp, 0, &mec
+ );
+ if(res) {
+
+#line 3438 "dk3figah.ctr"
+ sp[n1 + n2 - 1].x = dk3xsp_get_x(&seg);
+ sp[n1 + n2 - 1].y = dk3xsp_get_y(&seg);
+ sp[n1 + n2 - 1].s = 0.0;
+
+#line 3441 "dk3figah.ctr"
+ sp2[0].x = dk3xsp_get_x(&seg);
+ sp2[0].y = dk3xsp_get_y(&seg);
+ sp2[0].s = 0.0;
+
+#line 3444 "dk3figah.ctr"
+ for(i = 0; i < n1; i++) {
+ j = i + 1;
+ if(j == n1) {
+ t = t1;
+ } else {
+ dist = dk3ma_d_add_ok(
+ s, (((double)j / (double)n1) * l1), &mec
+ );
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ }
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+ if(res) {
+ pp[0].x = pp[1].x = 0.0;
+ if(j == n1) {
+ if(ah->af) {
+ pp[0].y = 0.5 * ah->wi;
+ } else {
+ pp[0].y = -0.5 * ah->wi;
+ }
+ } else {
+ if(ah->af) {
+ pp[0].y = 0.5 * ah->wi * ((double)j / (double)n1);
+ } else {
+ pp[0].y = -0.5 * ah->wi * ((double)j / (double)n1);
+ }
+ }
+ pp[1].y = -1.0 * pp[0].y;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+ sp[n1 + n2 - 1 - j].x = pp[0].x;
+ sp[n1 + n2 - 1 - j].y = pp[0].y;
+
+
+#line 3484 "dk3figah.ctr"
+ sp[n1 + n2 - 1 + j].x = pp[1].x;
+ sp[n1 + n2 - 1 + j].y = pp[1].y;
+
+
+#line 3487 "dk3figah.ctr"
+ sp[n1 + n2 - 1 - j].s = sp[n1 + n2 - 1 + j].s =
+ ((j == n1) ? 0.0 : (-1.0));
+ sp2[j].x = pp[0].x;
+ sp2[j].y = pp[0].y;
+ sp2[j].s = ((j == n1) ? 0.0 : (-1.0));
+
+
+#line 3493 "dk3figah.ctr"
+ } else {
+ back = 0; i = n1;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } else {
+ back = 0; i = n1;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ }
+ if(back) {
+ for(i = 0; i < (n2 - 1); i++) {
+ j = i + 1;
+ dist = dk3ma_d_sub_ok(
+ dk3ma_d_add_ok(s, l1, &mec),
+ (l2 * ((double)j / (double)n2)),
+ &mec
+ );
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+ if(res) {
+ pp[0].x = pp[1].x = 0.0;
+ if(ah->af) {
+ pp[0].y = 0.5 * ah->wi
+ * (1.0 - ((double)j/(double)n2));
+ } else {
+ pp[0].y = -0.5 * ah->wi
+ * (1.0 - ((double)j/(double)n2));
+ }
+ pp[1].y = -1.0 * pp[0].y;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+ sp[n2 - 1 - j].x = pp[0].x;
+ sp[n2 - 1 - j].y = pp[0].y;
+
+
+#line 3535 "dk3figah.ctr"
+ sp[2 * n1 + n2 - 1 + j].x = pp[1].x;
+ sp[2 * n1 + n2 - 1 + j].y = pp[1].y;
+
+
+#line 3538 "dk3figah.ctr"
+ sp[n2 - 1 - j].s = sp[2 * n1 + n2 - 1 + j].s =
+ ((j == n1) ? 0.0 : (-1.0));
+ sp2[n1 + j].x = pp[0].x;
+ sp2[n1 + j].y = pp[0].y;
+ sp2[n1 + j].s = ((j == n1) ? 0.0 : (-1.0));
+
+
+#line 3544 "dk3figah.ctr"
+ } else {
+ back = 0; i = n2;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } else {
+ back = 0; i = n2;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ }
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t2, &mec
+ );
+ if(res) {
+ sp[np - 1].x = xpos;
+ sp[np - 1].y = ypos;
+ sp[np - 1].s = 0.0;
+
+#line 3560 "dk3figah.ctr"
+ sp2[n1 + n2].x = xpos;
+ sp2[n1 + n2].y = ypos;
+ sp2[n1 + n2].s = 0.0;
+
+#line 3563 "dk3figah.ctr"
+ } else {
+ back = 0;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ for(i = 0; i < (n3 - 1); i++) {
+ j = i + 1;
+ dist = dk3ma_d_add_ok(
+ s,
+ ((1.0 - ((double)j / (double)n3)) * ah->he),
+ &mec
+ );
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+ if(res) {
+ sp2[n1 + n2 + j].x = xpos;
+ sp2[n1 + n2 + j].y = ypos;
+ sp2[n1 + n2 + j].s = -1.0;
+
+
+#line 3587 "dk3figah.ctr"
+ } else {
+ back = 0; i = n3;
+ }
+ } else {
+ back = 0; i = n3;
+ }
+ }
+ }
+ } else {
+ back = 0;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+
+#line 3599 "dk3figah.ctr"
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } else {
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } else {
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } break;
+ case DK3_FIG_AS_CLOSED_HALF: {
+
+#line 3614 "dk3figah.ctr"
+ t0 = dk3xsp_get_t_for_distance(
+ osp, onp, s, drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if(0.0 <= t0) {
+ t1 = dk3xsp_get_t_for_distance(
+ osp, onp, dk3ma_d_add_ok(s, ah->he, &mec),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if(0.0 <= t1) {
+
+#line 3623 "dk3figah.ctr"
+ n1 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(fabs(t1 - t0), drw->splspp, &mec)), &mec
+ );
+ if(n1 < drw->minspp) { n1 = drw->minspp; }
+ np = dk3mem_add_size_t(dk3mem_mul_size_t(2, n1, &mec), 1, &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la,
+ DK3_FIG_OBJ_SPLINE, 5,
+ obj->lw, obj->pc, ((ah->af) ? obj->pc : 7), 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1;
+ res = dk3xsp_calculate_position(
+ &seg, osp, onp, t0, drw->cosp, 0, &mec
+ );
+ if(res) {
+
+#line 3645 "dk3figah.ctr"
+ sp[n1].x = dk3xsp_get_x(&seg);
+ sp[n1].y = dk3xsp_get_y(&seg);
+ sp[n1].s = 0.0;
+
+#line 3648 "dk3figah.ctr"
+ for(i = 0; i < n1; i++) {
+ j = i + 1;
+
+#line 3650 "dk3figah.ctr"
+ if(j == n1) {
+ t = t1;
+ } else {
+ dist = dk3ma_d_add_ok(
+ s, (((double)j / (double)n1) * ah->he), &mec
+ );
+
+#line 3656 "dk3figah.ctr"
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+
+#line 3660 "dk3figah.ctr"
+
+
+#line 3661 "dk3figah.ctr"
+ }
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+
+#line 3666 "dk3figah.ctr"
+ if(res) {
+ pp[0].x = pp[1].x = 0.0;
+ if(j == n1) {
+ pp[0].y = 0.5 * ah->wi;
+ } else {
+ pp[0].y = 0.5 * ah->wi * ((double)j / (double)n1);
+ }
+ pp[1].y = 0.0;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+ sp[n1 - j].x = pp[0].x;
+
+#line 3679 "dk3figah.ctr"
+ sp[n1 - j].y = pp[0].y;
+
+#line 3680 "dk3figah.ctr"
+ sp[n1 + j].x = pp[1].x;
+ sp[n1 + j].y = pp[1].y;
+ sp[n1 - j].s = sp[n1 + j].s =
+ ((j == n1) ? 0.0 : (-1.0));
+ } else {
+ back = 0; i = n1;
+
+#line 3686 "dk3figah.ctr"
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } else {
+
+#line 3689 "dk3figah.ctr"
+ back = 0; i = n1;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ }
+ } else {
+
+#line 3694 "dk3figah.ctr"
+ back = 0;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+
+#line 3697 "dk3figah.ctr"
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ }
+ }
+ }
+ } break;
+ case DK3_FIG_AS_INDENTED_HALF: {
+
+#line 3706 "dk3figah.ctr"
+ l1 = dk3ma_d_mul_ok(1.25, ah->he, &mec);
+ l2 = 0.25 * ah->he;
+ t0 = dk3xsp_get_t_for_distance(
+ osp, onp, s, drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ t1 = dk3xsp_get_t_for_distance(
+ osp, onp, dk3ma_d_add_ok(s, l1, &mec),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ t2 = dk3xsp_get_t_for_distance(
+ osp, onp, dk3ma_d_add_ok(s, ah->he, &mec),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if((0.0 <= t0) && (0.0 <= t1) && (0.0 <= t2)) {
+
+#line 3720 "dk3figah.ctr"
+ n1 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(drw->splspp, fabs(t1 - t0), &mec)), &mec
+ );
+
+#line 3723 "dk3figah.ctr"
+ n2 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(drw->splspp, fabs(t1 - t2), &mec)), &mec
+ );
+
+#line 3726 "dk3figah.ctr"
+ n3 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(drw->splspp, fabs(t2 - t0), &mec)), &mec
+ );
+ if(n1 < drw->minspp) { n1 = drw->minspp; }
+ if(n2 < drw->minspp) { n2 = drw->minspp; }
+ if(n3 < drw->minspp) { n3 = drw->minspp; }
+ np = dk3mem_add_size_t(dk3mem_add_size_t(n1, n2, &mec), n3, &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 5,
+ obj->lw, obj->pc, ((ah->af) ? obj->pc : 7), 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1;
+
+#line 3745 "dk3figah.ctr"
+ for(i = 0; i < n1; i++) {
+ if(0 == i) {
+ t = t0;
+ } else {
+ dist = dk3ma_d_add_ok(
+ s, (l1 * ((double)i / (double)(n1))), &mec
+ );
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ }
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+ if(res) {
+ pp[0].x = 0.0;
+ pp[0].y = 0.5 * ah->wi * ((double)i / (double)n1);
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ sp[i].x = pp[0].x;
+
+#line 3767 "dk3figah.ctr"
+ sp[i].y = pp[0].y;
+ sp[i].s = ((i == 0) ? 0.0 : (-1.0));
+ } else {
+ back = 0; i = n1;
+ }
+ } else {
+ back = 0; i = n1;
+ }
+ }
+ if(back) {
+ for(i = 0; i < n2; i++) {
+ if(0 == i) {
+ t = t1;
+ } else {
+#if 0
+ dist = dk3ma_d_sub_ok(
+ l1, (l2 * ((double)i / (double)n2)), &mec
+ );
+#endif
+ dist = dk3ma_d_add_ok(
+ s,
+ dk3ma_d_sub_ok(
+ l1, (l2 * ((double)i / (double)n2)), &mec
+ ),
+ &mec
+ );
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ }
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+ if(res) {
+ pp[0].x = 0.0;
+ pp[0].y = 0.5 * ah->wi * (1.0 - ((double)i / (double)n2));
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ sp[n1 + i].x = pp[0].x;
+
+#line 3808 "dk3figah.ctr"
+ sp[n1 + i].y = pp[0].y;
+ sp[n1 + i].s = ((0 == i) ? 0.0 : (-1.0));
+ } else {
+ back = 0; i = n2;
+ }
+ } else {
+ back = 0; i = n2;
+ }
+ }
+ }
+ if(back) {
+ for(i = 0; i < n3; i++) {
+ if(0 == i) {
+ t = t2;
+ } else {
+ dist = dk3ma_d_add_ok(
+ s, (ah->he * (1.0 - ((double)i / (double)n3))), &mec
+ );
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ }
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+ if(res) {
+ sp[n1 + n2 + i].x = xpos;
+ sp[n1 + n2 + i].y = ypos;
+ sp[n1 + n2 + i].s = ((0 == i) ? 0.0 : (-1.0));
+
+
+#line 3840 "dk3figah.ctr"
+ } else {
+ back = 0; i = n3;
+ }
+ } else {
+ back = 0; i = n3;
+ }
+ }
+ }
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ }
+ }
+ } break;
+ case DK3_FIG_AS_BUTTED_HALF: {
+
+#line 3856 "dk3figah.ctr"
+ l1 = 0.75 * ah->he;
+ l2 = 0.25 * ah->he;
+ t0 = dk3xsp_get_t_for_distance(
+ osp, onp, s, drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ t1 = dk3xsp_get_t_for_distance(
+ osp, onp, dk3ma_d_add_ok(s, l1, &mec),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ t2 = dk3xsp_get_t_for_distance(
+ osp, onp, dk3ma_d_add_ok(s, ah->he, &mec),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if((0.0 <= t0) && (0.0 <= t1) && (0.0 <= t2)) {
+
+#line 3870 "dk3figah.ctr"
+ n1 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(drw->splspp, fabs(t1 - t0), &mec)), &mec
+ );
+
+#line 3873 "dk3figah.ctr"
+ n2 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(drw->splspp, fabs(t1 - t2), &mec)), &mec
+ );
+
+#line 3876 "dk3figah.ctr"
+ n3 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(drw->splspp, fabs(t2 - t0), &mec)), &mec
+ );
+ if(n1 < drw->minspp) { n1 = drw->minspp; }
+ if(n2 < drw->minspp) { n2 = drw->minspp; }
+ if(n3 < drw->minspp) { n3 = drw->minspp; }
+ np = dk3mem_add_size_t(dk3mem_add_size_t(n1, n2, &mec), n3, &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 5,
+ obj->lw, obj->pc, ((ah->af) ? obj->pc : 7), 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1;
+
+#line 3895 "dk3figah.ctr"
+ for(i = 0; i < n1; i++) {
+ if(0 == i) {
+ t = t0;
+ } else {
+ dist = dk3ma_d_add_ok(
+ s, (l1 * ((double)i / (double)(n1))), &mec
+ );
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ }
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+ if(res) {
+ pp[0].x = 0.0;
+ pp[0].y = 0.5 * ah->wi * ((double)i / (double)n1);
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ sp[i].x = pp[0].x;
+
+#line 3917 "dk3figah.ctr"
+ sp[i].y = pp[0].y;
+ sp[i].s = ((i == 0) ? 0.0 : (-1.0));
+ } else {
+ back = 0; i = n1;
+ }
+ } else {
+ back = 0; i = n1;
+ }
+ }
+ if(back) {
+ for(i = 0; i < n2; i++) {
+ if(0 == i) {
+ t = t1;
+ } else {
+#if 0
+ dist = dk3ma_d_add_ok(
+ l1, (l2 * ((double)i / (double)n2)), &mec
+ );
+#endif
+ dist = dk3ma_d_add_ok(
+ s,
+ dk3ma_d_add_ok(
+ l1, (l2 * ((double)i / (double)n2)), &mec
+ ),
+ &mec
+ );
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ }
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+ if(res) {
+ pp[0].x = 0.0;
+ pp[0].y = 0.5 * ah->wi * (1.0 - ((double)i / (double)n2));
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ sp[n1 + i].x = pp[0].x;
+
+#line 3958 "dk3figah.ctr"
+ sp[n1 + i].y = pp[0].y;
+ sp[n1 + i].s = ((0 == i) ? 0.0 : (-1.0));
+ } else {
+ back = 0; i = n2;
+ }
+ } else {
+ back = 0; i = n2;
+ }
+ }
+ }
+ if(back) {
+ for(i = 0; i < n3; i++) {
+ if(0 == i) {
+ t = t2;
+ } else {
+ dist = dk3ma_d_add_ok(
+ s, (ah->he * (1.0 - ((double)i / (double)n3))), &mec
+ );
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ }
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+ if(res) {
+ sp[n1 + n2 + i].x = xpos;
+ sp[n1 + n2 + i].y = ypos;
+ sp[n1 + n2 + i].s = ((0 == i) ? 0.0 : (-1.0));
+
+
+#line 3990 "dk3figah.ctr"
+ } else {
+ back = 0; i = n3;
+ }
+ } else {
+ back = 0; i = n3;
+ }
+ }
+ }
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ }
+ }
+ } break;
+ case DK3_FIG_AS_TRIANGLE_FORK: {
+
+#line 4006 "dk3figah.ctr"
+ if(ah->af) {
+ t0 = dk3xsp_get_t_for_distance(
+ osp, onp, s, drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if(0.0 <= t0) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_POLYLINE, 1,
+ obj->lw, obj->pc, obj->pc, -1,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, 2, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ po = (ao1->dt).pol.po;
+ if(po) {
+ back = 1;
+ pp[0].x = pp[1].x = 0.0;
+ pp[0].y = 0.5 * ah->wi;
+ pp[1].y = -0.5 * ah->wi;
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t0, &mec
+ );
+ if(res) {
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+ po[0].x = pp[0].x; po[0].y = pp[0].y;
+ po[1].x = pp[1].x; po[1].y = pp[1].y;
+ } else {
+ back = 0;
+ }
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ }
+ } else {
+ t0 = dk3xsp_get_t_for_distance(
+ osp, onp, s, drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ t1 = dk3xsp_get_t_for_distance(
+ osp, onp, dk3ma_d_add_ok(s, ah->he, &mec),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if((0.0 <= t0) && (0.0 <= t1)) {
+
+#line 4052 "dk3figah.ctr"
+ n1 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(fabs(t1 - t0), drw->splspp, &mec)), &mec
+ );
+ if(n1 < drw->minspp) { n1 = drw->minspp; }
+ np = dk3mem_add_size_t(dk3mem_mul_size_t(2, n1, &mec), 1, &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 4,
+ obj->lw, obj->pc, ((ah->af) ? obj->pc : 7), -1,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1;
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t1, &mec
+ );
+ if(res) {
+
+#line 4073 "dk3figah.ctr"
+ sp[n1].x = xpos;
+ sp[n1].y = ypos;
+ sp[n1].s = 0.0;
+
+#line 4076 "dk3figah.ctr"
+ for(i = 0; i < n1; i++) {
+ j = i + 1;
+ if(j == n1) {
+ t = t0;
+ } else {
+ dist = dk3ma_d_add_ok(
+ s, ((1.0 - ((double)j / (double)n1)) * ah->he), &mec
+ );
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ }
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+ if(res) {
+ pp[0].x = pp[1].x = 0.0;
+ pp[0].y = 0.5 * ((double)j / (double)n1) * ah->wi;
+ pp[1].y = -1.0 * pp[0].y;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+ sp[n1 - j].x = pp[0].x; sp[n1 - j].y = pp[0].y;
+ sp[n1 + j].x = pp[1].x; sp[n1 + j].y = pp[1].y;
+
+
+#line 4104 "dk3figah.ctr"
+
+
+#line 4105 "dk3figah.ctr"
+ sp[n1 - j].s = sp[n1 + j].s =
+ ((j == n1) ? 0.0 : (-1.0));
+ } else {
+ }
+ } else {
+ back = 0; i = n1;
+ }
+ }
+ } else {
+ back = 0;
+ }
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ }
+ }
+ }
+ } break;
+ case DK3_FIG_AS_RECTANGLE_FORK: {
+
+#line 4125 "dk3figah.ctr"
+ if(ah->af) {
+ t0 = dk3xsp_get_t_for_distance(
+ osp, onp, s, drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ l1 = dk3ma_d_add_ok(s, ah->he, &mec);
+ t1 = dk3xsp_get_t_for_distance(
+ osp, onp, l1, drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if((0.0 <= t0) && (0.0 <= t1)) {
+
+#line 4134 "dk3figah.ctr"
+ n1 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(drw->splspp, fabs(t1 - t0), &mec)), &mec
+ );
+ if(n1 < drw->minspp) { n1 = drw->minspp; }
+ np = dk3mem_mul_size_t(2, dk3mem_add_size_t(n1, 1, &mec), &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 4,
+ obj->lw, obj->pc, obj->pc, -1,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1;
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t0, &mec
+ );
+ if(res) {
+
+#line 4155 "dk3figah.ctr"
+ pp[0].x = 0.0; pp[1].x = 0.0;
+ pp[0].y = 0.5 * ah->wi;
+ pp[1].y = -0.5 * ah->wi;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+ sp[n1].x = pp[0].x;
+ sp[n1].y = pp[0].y;
+
+
+#line 4165 "dk3figah.ctr"
+ sp[n1 + 1].x = pp[1].x;
+ sp[n1 + 1].y = pp[1].y;
+
+
+#line 4168 "dk3figah.ctr"
+ sp[n1].s = sp[n1 + 1].s = 0.0;
+ for(i = 0; i < n1; i++) {
+ j = i + 1;
+ if(j == n1) {
+ t = t1;
+ } else {
+ dist = dk3ma_d_add_ok(
+ s, (((double)j / (double)n1) * ah->he), &mec
+ );
+
+#line 4177 "dk3figah.ctr"
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+
+#line 4181 "dk3figah.ctr"
+ }
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+
+#line 4186 "dk3figah.ctr"
+ if(res) {
+ pp[0].x = 0.0; pp[1].x = 0.0;
+ pp[0].y = 0.5 * ah->wi;
+ pp[1].y = -0.5 * ah->wi;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+
+
+#line 4192 "dk3figah.ctr"
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+
+
+#line 4194 "dk3figah.ctr"
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+
+
+#line 4196 "dk3figah.ctr"
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+
+
+#line 4198 "dk3figah.ctr"
+ sp[n1 - j].x = pp[0].x;
+ sp[n1 - j].y = pp[0].y;
+
+
+#line 4201 "dk3figah.ctr"
+ sp[n1 + 1 + j].x = pp[1].x;
+ sp[n1 + 1 + j].y = pp[1].y;
+
+
+#line 4204 "dk3figah.ctr"
+ sp[n1 - j].s = sp[n1 + 1 + j].s =
+ ((j == n1) ? 0.0 : (-1.0));
+ } else {
+ back = 0; i = n1;
+ }
+ } else {
+ back = 0; i = n1;
+ }
+ }
+ } else {
+ back = 0;
+ }
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ }
+ }
+ } else {
+
+#line 4223 "dk3figah.ctr"
+ t0 = ((ab) ? 0.0 : ((obj->dt).spl.np - 1));
+ t1 = dk3xsp_get_t_for_distance(
+ osp, onp, ah->he, drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+
+#line 4227 "dk3figah.ctr"
+ if((0.0 <= t0) && (0.0 <= t1)) {
+
+#line 4228 "dk3figah.ctr"
+ n1 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(drw->splspp, fabs(t1 - t0), &mec)), &mec
+ );
+
+#line 4231 "dk3figah.ctr"
+ if(n1 < drw->minspp) { n1 = drw->minspp; }
+ np = dk3mem_mul_size_t(2, dk3mem_add_size_t(n1, 1, &mec), &mec);
+
+
+#line 4234 "dk3figah.ctr"
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 4,
+ obj->lw, obj->pc, obj->pc, -1,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+
+#line 4241 "dk3figah.ctr"
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+
+#line 4244 "dk3figah.ctr"
+ back = 1;
+
+#line 4245 "dk3figah.ctr"
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t1, &mec
+ );
+
+#line 4248 "dk3figah.ctr"
+ if(res) {
+
+#line 4249 "dk3figah.ctr"
+ pp[0].x = 0.0; pp[1].x = 0.0;
+ pp[0].y = 0.5 * ah->wi;
+ pp[1].y = -0.5 * ah->wi;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+
+
+#line 4254 "dk3figah.ctr"
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+
+
+#line 4256 "dk3figah.ctr"
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+
+
+#line 4258 "dk3figah.ctr"
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+
+
+#line 4260 "dk3figah.ctr"
+ sp[n1].x = pp[0].x;
+ sp[n1].y = pp[0].y;
+
+
+#line 4263 "dk3figah.ctr"
+ sp[n1 + 1].x = pp[1].x;
+ sp[n1 + 1].y = pp[1].y;
+
+
+#line 4266 "dk3figah.ctr"
+ sp[n1].s = sp[n1 + 1].s = 0.0;
+ for(i = 0; i < n1; i++) {
+ j = i + 1;
+ if(j == n1) {
+ t = t0;
+ } else {
+ dist = (1.0 - ((double)j / (double)n1)) * ah->he;
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+
+#line 4277 "dk3figah.ctr"
+ }
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+
+#line 4282 "dk3figah.ctr"
+ if(res) {
+ pp[0].x = 0.0; pp[1].x = 0.0;
+ pp[0].y = 0.5 * ah->wi;
+ pp[1].y = -0.5 * ah->wi;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+
+
+#line 4288 "dk3figah.ctr"
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+
+
+#line 4290 "dk3figah.ctr"
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+
+
+#line 4292 "dk3figah.ctr"
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+
+
+#line 4294 "dk3figah.ctr"
+ sp[n1 - j].x = pp[0].x;
+ sp[n1 - j].y = pp[0].y;
+
+
+#line 4297 "dk3figah.ctr"
+ sp[n1 + 1 + j].x = pp[1].x;
+ sp[n1 + 1 + j].y = pp[1].y;
+
+
+#line 4300 "dk3figah.ctr"
+ sp[n1 - j].s = sp[n1 + 1 + j].s =
+ ((j == n1) ? 0.0 : (-1.0));
+ } else {
+ back = 0; i = n1;
+ }
+ } else {
+ back = 0; i = n1;
+ }
+ }
+ } else {
+
+#line 4310 "dk3figah.ctr"
+ back = 0;
+ }
+ } else {
+
+#line 4313 "dk3figah.ctr"
+ }
+ } else {
+
+#line 4315 "dk3figah.ctr"
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } else {
+
+#line 4318 "dk3figah.ctr"
+ }
+ }
+ } break;
+ }
+ if(mec) {
+
+#line 4323 "dk3figah.ctr"
+ back = 0;
+ if(ec) { *ec = mec; }
+ /* ##### ERROR: Mathematical error occured! */
+ } else {
+ if(!(back)) {
+ /* ##### ERROR: Error in spline arrowhead calculation! */
+ }
+ }
+
+#line 4331 "dk3figah.ctr"
+ return back;
+}
+
+
+
+/** Calculate arrowheads for spline.
+ @param drw Drawing to modify.
+ @param obj Object to modify.
+ @param objno Object number.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figah_calculate_spline(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ unsigned long objno
+)
+{
+ dk3_xspline_segment_t seg;
+ dk3_fig_poly_point_t sp;
+ double cuts = -1.0;
+ double cute = -1.0;
+ double alphaf = 0.0;
+ double alphab = 0.0;
+ double t;
+ int back = 1;
+ int mec = 0;
+ int res = 0;
+
+
+#line 4361 "dk3figah.ctr"
+ if((1 < (obj->dt).spl.np) && ((obj->dt).spl.po)) {
+ /*
+ Defaults for start and end.
+ */
+ (obj->dt).spl.ts = 0.0;
+ (obj->dt).spl.te = (double)((obj->dt).spl.np - 1);
+ /*
+ Calculate line cuts.
+ */
+ if(!(drw->coah)) {
+
+#line 4371 "dk3figah.ctr"
+ if(obj->af) {
+
+#line 4372 "dk3figah.ctr"
+ cute = dk3figah_length_correction(drw, obj, obj->af, &mec);
+ }
+ if(obj->ab) {
+
+#line 4375 "dk3figah.ctr"
+ cuts = dk3figah_length_correction(drw, obj, obj->ab, &mec);
+ }
+
+#line 4377 "dk3figah.ctr"
+ }
+ /*
+ Construct arrowhead objects.
+ */
+ if(drw->coah) {
+ back = 1;
+ if(obj->af) {
+ t = (double)((obj->dt).spl.np - 1);
+ res = dk3xsp_calculate_position(
+ &seg, (obj->dt).spl.po, (obj->dt).spl.np, t, drw->cosp, 0, &mec
+ );
+ if((res) && (0 == mec)) {
+ alphaf = dk3xsp_direction(
+ (obj->dt).spl.po, (obj->dt).spl.np, t, drw->cosp, &mec
+ );
+
+#line 4392 "dk3figah.ctr"
+ if((alphaf >= 0.0) && (0 == mec)) {
+ sp.x = dk3xsp_get_x(&seg);
+ sp.y = dk3xsp_get_y(&seg);
+ res = dk3figah_straight_arrowhead(
+ drw, obj, obj->af, &sp, alphaf, &mec
+ );
+
+#line 4398 "dk3figah.ctr"
+ if(!(res)) { back = 0; }
+ } else {
+ /* ##### ERROR: Arrowhead calculation failed! */
+ back = 0;
+ }
+ } else {
+ /* ##### ERROR: Arrowhead calculation failed! */
+ back = 0;
+ }
+ }
+ if(obj->ab) {
+ res = dk3xsp_calculate_position(
+ &seg, (obj->dt).spl.po, (obj->dt).spl.np, 0.0, drw->cosp, 0, &mec
+ );
+
+#line 4412 "dk3figah.ctr"
+ if((res) && (0 == mec)) {
+ alphab = dk3xsp_direction(
+ (obj->dt).spl.po, (obj->dt).spl.np, 0.0, drw->cosp, &mec
+ );
+
+#line 4416 "dk3figah.ctr"
+ if((alphab >= 0.0) && (0 == mec)) {
+ alphab += M_PI;
+ sp.x = dk3xsp_get_x(&seg);
+ sp.y = dk3xsp_get_y(&seg);
+ res = dk3figah_straight_arrowhead(
+ drw, obj, obj->ab, &sp, alphab, &mec
+ );
+
+#line 4423 "dk3figah.ctr"
+ if(!(res)) { back = 0; }
+ } else {
+ /* ##### ERROR: Arrowhead calculation failed! */
+ back = 0;
+ }
+ } else {
+ /* ##### ERROR: Arrowhead calculation failed! */
+ back = 0;
+ }
+ }
+ } else {
+ if(obj->af) {
+ if(!dk3figah_one_spline_arrowhead(drw, obj, obj->af, 0, &mec)) {
+ back = 0;
+ }
+
+#line 4438 "dk3figah.ctr"
+ }
+ if(obj->ab) {
+ if(!dk3figah_one_spline_arrowhead(drw, obj, obj->ab, 1, &mec)) {
+ back = 0;
+ }
+
+#line 4443 "dk3figah.ctr"
+ }
+ }
+ /*
+ Cut spline if necessary when not using compatible arrowheads.
+ */
+#if VERSION_BEFORE_20150821
+ /* 2015-08-21 Static code analysis complains:
+ The following instruction discards all previous check results!
+ */
+ back = 1;
+#endif
+ if(!(drw->coah)) {
+
+#line 4455 "dk3figah.ctr"
+ if((0.0 < cuts) && (NULL != obj->ab)) {
+
+#line 4456 "dk3figah.ctr"
+ (obj->dt).spl.ts = dk3xsp_get_t_for_distance(
+ (obj->dt).spl.po,
+ (obj->dt).spl.np,
+ cuts,
+ dk3figah_length_correction_tolerance(drw, obj, obj->ab, &mec),
+ (obj->dt).spl.fslc,
+ 1,
+ drw->cosp,
+ &mec
+ );
+
+#line 4466 "dk3figah.ctr"
+ if(0.0 > (obj->dt).spl.ts) {
+
+#line 4467 "dk3figah.ctr"
+ back = 0;
+ }
+ } else {
+
+#line 4470 "dk3figah.ctr"
+ }
+ if((0.0 < cute) && (NULL != obj->af)) {
+
+#line 4472 "dk3figah.ctr"
+ (obj->dt).spl.te = dk3xsp_get_t_for_distance(
+ (obj->dt).spl.po,
+ (obj->dt).spl.np,
+ cute,
+ dk3figah_length_correction_tolerance(drw, obj, obj->af, &mec),
+ (obj->dt).spl.fslc,
+ 0,
+ drw->cosp,
+ &mec
+ );
+
+#line 4482 "dk3figah.ctr"
+ if(0.0 > (obj->dt).spl.te) {
+
+#line 4483 "dk3figah.ctr"
+ back = 0;
+ }
+ } else {
+
+#line 4486 "dk3figah.ctr"
+ }
+ }
+ if(mec) {
+
+#line 4489 "dk3figah.ctr"
+ back = 0;
+ /* ERROR: Math error */
+ dk3app_log_i1(drw->app, DK3_LL_ERROR, 260);
+ }
+ }
+
+
+#line 4495 "dk3figah.ctr"
+ return back;
+}
+
+
+
+/** For corrections on arcs check whether we have to
+ use the full correction formula.
+ @param ah Arrowhead to calculate correction for.
+ @return 1 for correct formula, 0 for c/r.
+*/
+static
+int
+dk3figah_must_use_arc_correction(dk3_fig_ah_t *ah)
+{
+ int back = 0;
+ if(ah) {
+ if(!(ah->af)) {
+ switch(ah->as) {
+ case DK3_FIG_AS_HALF_CIRCLE_END: {
+ back = 1;
+ } break;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Calculate correction angle for arrowhead length correction on arcs.
+ @param r Arc radius.
+ @param c Correction length.
+ @param ec Pointer to error code variable.
+ @return Non-negative number on success, -1.0 on error.
+*/
+static
+double
+dk3figah_arc_correction(double r, double c, int *ec)
+{
+ double back = -1.0;
+ double val;
+ val = dk3ma_d_sub_ok(
+ 1.0,
+ dk3ma_d_div_ok(
+ dk3ma_d_square_ok(c, ec),
+ dk3ma_d_mul_ok(2.0, dk3ma_d_square_ok(r, ec), ec),
+ ec
+ ),
+ ec
+ );
+ if((-1.0 <= val) && (1.0 >= val)) {
+ back = acos(val);
+ } else {
+ if(ec) { *ec = DK3_ERROR_MATH_OUT_OF_RANGE; }
+ }
+ return back;
+}
+
+
+
+/** Calculate one arrowhead on arc.
+ @param drw Drawing structure.
+ @param obj Arc object containing the arrowhead.
+ @param ah Arrowhead structure.
+ @param ab Flag: Backward arrow (0=forward, 1=backward).
+ @param ec Pointer to error code variable.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figah_one_arc_arrowhead(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int ab,
+ int *ec
+)
+{
+ dk3_fig_spline_point_t *sp = NULL;
+ dk3_fig_poly_point_t *po;
+ dk3_fig_poly_point_t pp;
+ dk3_fig_obj_t *ao1; /* Arrowhead object 1. */
+ dk3_fig_obj_t *ao2; /* Arrowhead object 2. */
+ double s; /* Shift length. */
+ double a0; /* Alpha at arrow front pt. */
+ double a1; /* Alpha at real front. */
+ double phi; /* Direction at front. */
+ double b1; /* Beta: Angle for arrowhead. */
+ double b2; /* Beta: Angle for part. */
+ double b3; /* Beta: Angle for inner. */
+ double f = -1.0; /* Factor. */
+ double ga; /* Current point angle. */
+ double r1;
+ double r2;
+ size_t nsegs = 0; /* Number of segments. */
+ size_t ns2 = 0; /* Number of segments 2. */
+ size_t ns3 = 0; /* Number of segments 3. */
+ size_t np = 0; /* Number of spline points. */
+ size_t i;
+ size_t j;
+ int mec = 0;
+ int back = 0;
+ int mustadd = 0;
+
+
+#line 4599 "dk3figah.ctr"
+ if(ab) {
+ a0 = (obj->dt).arc.as;
+ if((obj->dt).arc.ae > (obj->dt).arc.as) {
+ f = 1.0;
+ } else {
+ f = -1.0;
+ }
+ } else {
+ a0 = (obj->dt).arc.ae;
+ if((obj->dt).arc.ae > (obj->dt).arc.as) {
+ f = -1.0;
+ } else {
+ f = 1.0;
+ }
+ }
+
+
+#line 4615 "dk3figah.ctr"
+
+
+#line 4616 "dk3figah.ctr"
+ a1 = a0;
+
+#line 4617 "dk3figah.ctr"
+ phi = a1 - f * M_PI_2;
+
+#line 4618 "dk3figah.ctr"
+ s = dk3figah_find_shift_length(drw, obj, ah, &mec);
+ a0 = dk3ma_d_add_ok(
+ a0,
+ (f * dk3ma_d_div_ok(s, (obj->dt).arc.ra, &mec)),
+ &mec
+ );
+
+#line 4624 "dk3figah.ctr"
+
+
+#line 4625 "dk3figah.ctr"
+ switch(ah->as) {
+ case DK3_FIG_AS_STICK:
+ case DK3_FIG_AS_CLOSED: {
+
+#line 4628 "dk3figah.ctr"
+ b1 = dk3ma_d_div_ok(ah->he, (obj->dt).arc.ra, &mec);
+ if(b1 < (2.0 * M_PI)) {
+
+#line 4630 "dk3figah.ctr"
+ nsegs = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b1, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ );
+
+#line 4634 "dk3figah.ctr"
+ if(drw->minspp > nsegs) { nsegs = drw->minspp; }
+#if TRACE_DEBUG
+ np = 2 * nsegs + 1;
+
+#line 4637 "dk3figah.ctr"
+#endif
+ np = dk3mem_add_size_t(dk3mem_mul_size_t(2, nsegs, &mec), 1, &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la,
+ DK3_FIG_OBJ_SPLINE, 4,
+ obj->lw, obj->pc, -1, -1,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ if(ao1) {
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+
+#line 4652 "dk3figah.ctr"
+ back = 1;
+ sp[nsegs].x = (obj->dt).arc.ra * cos(a0);
+ sp[nsegs].y = (obj->dt).arc.ra * sin(a0);
+ sp[nsegs].s = 0.0;
+ for(i = 0; i < nsegs; i++) {
+
+#line 4657 "dk3figah.ctr"
+ j = i + 1;
+ if(j == nsegs) {
+ ga = a0 + f * b1;
+
+
+#line 4661 "dk3figah.ctr"
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra, (0.5 * ah->wi), &mec
+ );
+
+#line 4664 "dk3figah.ctr"
+ r2 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra, (0.5 * ah->wi), &mec
+ );
+
+#line 4667 "dk3figah.ctr"
+ sp[nsegs - j].s = 0.0;
+ sp[nsegs + j].s = 0.0;
+ } else {
+ ga = a0 + f * b1 * ((double)j / (double)nsegs);
+
+
+#line 4672 "dk3figah.ctr"
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * ((double)j / (double)nsegs)),
+ &mec
+ );
+
+#line 4677 "dk3figah.ctr"
+ r2 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * ((double)j / (double)nsegs)),
+ &mec
+ );
+
+#line 4682 "dk3figah.ctr"
+ sp[nsegs - j].s = -1.0;
+ sp[nsegs + j].s = -1.0;
+ }
+ sp[nsegs - j].x = r1 * cos(ga);
+ sp[nsegs - j].y = r1 * sin(ga);
+ sp[nsegs + j].x = r2 * cos(ga);
+ sp[nsegs + j].y = r2 * sin(ga);
+ }
+ for(i = 0; i < np; i++) {
+ dk3fig_tool_shift_spoint(
+ &(sp[i]), (obj->dt).arc.xc, (obj->dt).arc.yc, &mec
+ );
+
+#line 4694 "dk3figah.ctr"
+ }
+ if(DK3_FIG_AS_CLOSED == ah->as) {
+ ao1->st = 5;
+ if(ah->af) {
+ ao1->fc = obj->pc;
+ } else {
+ ao1->fc = 7;
+ }
+ ao1->fi = 20;
+ ao1->cl = 1;
+ }
+
+#line 4705 "dk3figah.ctr"
+ }
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ }
+ } else {
+ /* ##### ERROR: Arrowhead too long! */
+ }
+ } break;
+ case DK3_FIG_AS_INDENTED: {
+ b1 = dk3ma_d_div_ok(
+ dk3ma_d_mul_ok(1.25, ah->he, &mec),
+ (obj->dt).arc.ra, &mec
+ );
+ b2 = dk3ma_d_div_ok((0.25 * ah->he), (obj->dt).arc.ra, &mec);
+ if((b1 < (2.0 * M_PI)) && (b2 < (2.0 * M_PI))) {
+
+#line 4722 "dk3figah.ctr"
+ nsegs = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b1, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ );
+
+#line 4726 "dk3figah.ctr"
+ ns2 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b2, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ );
+
+#line 4730 "dk3figah.ctr"
+ if(drw->minspp > nsegs) { nsegs = drw->minspp; }
+ if(drw->minspp > ns2) { ns2 = drw->minspp; }
+#if TRACE_DEBUG
+ np = 2 * (nsegs + ns2);
+
+#line 4734 "dk3figah.ctr"
+#endif
+ np = dk3mem_mul_size_t(2, dk3mem_add_size_t(nsegs, ns2, &mec), &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 5,
+ obj->lw, obj->pc, 7, 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1;
+ /* Arrowhead front point */
+ sp[nsegs + ns2 - 1].x = (obj->dt).arc.ra * cos(a0);
+ sp[nsegs + ns2 - 1].y = (obj->dt).arc.ra * sin(a0);
+ sp[nsegs + ns2 - 1].s = 0.0;
+
+
+#line 4753 "dk3figah.ctr"
+ /* Outer edges of arrowhead */
+ for(i = 0; i < nsegs; i++) {
+ j = i + 1;
+ if(j == nsegs) {
+ ga = a0 + f * b1;
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra, (0.5 * ah->wi), &mec
+ );
+ r2 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra, (0.5 * ah->wi), &mec
+ );
+ sp[nsegs + ns2 - 1 - j].s = 0.0;
+ sp[nsegs + ns2 - 1 + j].s = 0.0;
+ } else {
+ ga = a0 + f * b1 * ((double)j / (double)nsegs);
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * ((double)j / (double)nsegs)),
+ &mec
+ );
+ r2 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * ((double)j / (double)nsegs)),
+ &mec
+ );
+ sp[nsegs + ns2 - 1 - j].s = -1.0;
+ sp[nsegs + ns2 - 1 + j].s = -1.0;
+ }
+ sp[nsegs + ns2 - 1 - j].x = r1 * cos(ga);
+ sp[nsegs + ns2 - 1 - j].y = r1 * sin(ga);
+ sp[nsegs + ns2 - 1 + j].x = r2 * cos(ga);
+ sp[nsegs + ns2 - 1 + j].y = r2 * sin(ga);
+
+
+#line 4786 "dk3figah.ctr"
+
+
+#line 4787 "dk3figah.ctr"
+ }
+ /* Inner edges of arrowhead */
+ for(i = 0; i < (ns2 - 1); i++) {
+ j = i + 1;
+ ga = a0 + f * (b1 - b2 * ((double)j / (double)ns2));
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * (1.0 - ((double)j / (double)ns2))),
+ &mec
+ );
+ r2 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * (1.0 - ((double)j / (double)ns2))),
+ &mec
+ );
+ sp[ns2 - 1 - j].x = r1 * cos(ga);
+ sp[ns2 - 1 - j].y = r1 * sin(ga);
+ sp[ns2 - 1 - j].s = -1.0;
+ sp[2 * nsegs + ns2 - 1 + j].x = r2 * cos(ga);
+ sp[2 * nsegs + ns2 - 1 + j].y = r2 * sin(ga);
+ sp[2 * nsegs + ns2 - 1 + j].s = -1.0;
+
+
+#line 4809 "dk3figah.ctr"
+
+
+#line 4810 "dk3figah.ctr"
+ }
+ /* Inner arrowhead front point */
+ ga = a0 + f * (b1 - b2);
+ r1 = (obj->dt).arc.ra;
+ sp[2 * (nsegs + ns2) - 1].x = r1 * cos(ga);
+ sp[2 * (nsegs + ns2) - 1].y = r1 * sin(ga);
+ sp[2 * (nsegs + ns2) - 1].s = 0.0;
+
+
+#line 4818 "dk3figah.ctr"
+ /* Shift all points */
+ for(i = 0; i < np; i++) {
+ dk3fig_tool_shift_spoint(
+ &(sp[i]), (obj->dt).arc.xc, (obj->dt).arc.yc, &mec
+ );
+ }
+ if(ah->af) {
+ ao1->fc = obj->pc;
+ }
+
+#line 4827 "dk3figah.ctr"
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ }
+ } else {
+ /* ##### ERROR: Arrowhead too long! */
+ }
+ } break;
+ case DK3_FIG_AS_POINTED: {
+ b1 = dk3ma_d_div_ok(
+ dk3ma_d_mul_ok(0.75, ah->he, &mec),
+ (obj->dt).arc.ra, &mec
+ );
+ b2 = dk3ma_d_div_ok((0.25 * ah->he), (obj->dt).arc.ra, &mec);
+ if((b1 < (2.0 * M_PI)) && (b2 < (2.0 * M_PI))) {
+
+#line 4843 "dk3figah.ctr"
+ nsegs = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b1, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ );
+
+#line 4847 "dk3figah.ctr"
+ ns2 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b2, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ );
+
+#line 4851 "dk3figah.ctr"
+ if(drw->minspp > nsegs) { nsegs = drw->minspp; }
+ if(drw->minspp > ns2) { ns2 = drw->minspp; }
+#if TRACE_DEBUG
+ np = 2 * (nsegs + ns2);
+
+#line 4855 "dk3figah.ctr"
+#endif
+ np = dk3mem_mul_size_t(2, dk3mem_add_size_t(nsegs, ns2, &mec), &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la,
+ DK3_FIG_OBJ_SPLINE, 5,
+ obj->lw, obj->pc, 7, 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1;
+ /* Arrowhead front point */
+ sp[nsegs + ns2 - 1].x = (obj->dt).arc.ra * cos(a0);
+ sp[nsegs + ns2 - 1].y = (obj->dt).arc.ra * sin(a0);
+ sp[nsegs + ns2 - 1].s = 0.0;
+
+
+#line 4875 "dk3figah.ctr"
+ /* Outer edges of arrowhead */
+ for(i = 0; i < nsegs; i++) {
+ j = i + 1;
+ if(j == nsegs) {
+ ga = a0 + f * b1;
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra, (0.5 * ah->wi), &mec
+ );
+ r2 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra, (0.5 * ah->wi), &mec
+ );
+ sp[nsegs + ns2 - 1 - j].s = 0.0;
+ sp[nsegs + ns2 - 1 + j].s = 0.0;
+ } else {
+ ga = a0 + f * b1 * ((double)j / (double)nsegs);
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * ((double)j / (double)nsegs)),
+ &mec
+ );
+ r2 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * ((double)j / (double)nsegs)),
+ &mec
+ );
+ sp[nsegs + ns2 - 1 - j].s = -1.0;
+ sp[nsegs + ns2 - 1 + j].s = -1.0;
+ }
+ sp[nsegs + ns2 - 1 - j].x = r1 * cos(ga);
+ sp[nsegs + ns2 - 1 - j].y = r1 * sin(ga);
+ sp[nsegs + ns2 - 1 + j].x = r2 * cos(ga);
+ sp[nsegs + ns2 - 1 + j].y = r2 * sin(ga);
+
+
+#line 4908 "dk3figah.ctr"
+
+
+#line 4909 "dk3figah.ctr"
+ }
+ /* Inner edges of arrowhead */
+ for(i = 0; i < (ns2 - 1); i++) {
+ j = i + 1;
+ ga = a0 + f * (b1 + b2 * ((double)j / (double)ns2));
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * (1.0 - ((double)j / (double)ns2))),
+ &mec
+ );
+ r2 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * (1.0 - ((double)j / (double)ns2))),
+ &mec
+ );
+ sp[ns2 - 1 - j].x = r1 * cos(ga);
+ sp[ns2 - 1 - j].y = r1 * sin(ga);
+ sp[ns2 - 1 - j].s = -1.0;
+ sp[2 * nsegs + ns2 - 1 + j].x = r2 * cos(ga);
+ sp[2 * nsegs + ns2 - 1 + j].y = r2 * sin(ga);
+ sp[2 * nsegs + ns2 - 1 + j].s = -1.0;
+
+
+#line 4931 "dk3figah.ctr"
+
+
+#line 4932 "dk3figah.ctr"
+ }
+ /* Inner arrowhead front point */
+ ga = a0 + f * (b1 + b2);
+ r1 = (obj->dt).arc.ra;
+ sp[2 * (nsegs + ns2) - 1].x = r1 * cos(ga);
+ sp[2 * (nsegs + ns2) - 1].y = r1 * sin(ga);
+ sp[2 * (nsegs + ns2) - 1].s = 0.0;
+
+
+#line 4940 "dk3figah.ctr"
+ /* Shift all points */
+ for(i = 0; i < np; i++) {
+ dk3fig_tool_shift_spoint(
+ &(sp[i]), (obj->dt).arc.xc, (obj->dt).arc.yc, &mec
+ );
+ }
+ if(ah->af) {
+ ao1->fc = obj->pc;
+ }
+
+#line 4949 "dk3figah.ctr"
+ }
+ }
+ }
+ } else {
+ /* ##### ERROR: Arrowhead too long! */
+ }
+ } break;
+ case DK3_FIG_AS_RHOMBUS: {
+ if((1 == ah->af) && (DK3_FIG_SRCTYPE_JFIG == drw->srctype)) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la,
+ DK3_FIG_OBJ_ELLIPSE, 3,
+ obj->lw, obj->pc, obj->pc, 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, 0, NULL, drw->app
+ );
+ if(ao1) {
+ back = 1;
+ ah->o1 = (void *)ao1;
+ (ao1->dt).ell.an = 0.0;
+ (ao1->dt).ell.cx = dk3ma_d_add_ok(
+ (obj->dt).arc.xc,
+ ((obj->dt).arc.ra * cos(a0)),
+ &mec
+ );
+ (ao1->dt).ell.cy = dk3ma_d_add_ok(
+ (obj->dt).arc.yc,
+ ((obj->dt).arc.ra * sin(a0)),
+ &mec
+ );
+ (ao1->dt).ell.rx = dk3ma_d_mul_ok(2.0, ah->wi, &mec);
+ (ao1->dt).ell.ry = (ao1->dt).ell.rx;
+ }
+ } else {
+ b1 = dk3ma_d_div_ok(
+ dk3ma_d_mul_ok(0.5, ah->he, &mec),
+ (obj->dt).arc.ra, &mec
+ );
+ b2 = b1;
+ if((b1 < (2.0 * M_PI)) && (b2 < (2.0 * M_PI))) {
+
+#line 4989 "dk3figah.ctr"
+ nsegs = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b1, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ );
+
+#line 4993 "dk3figah.ctr"
+ ns2 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b2, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ );
+
+#line 4997 "dk3figah.ctr"
+ if(drw->minspp > nsegs) { nsegs = drw->minspp; }
+ if(drw->minspp > ns2) { ns2 = drw->minspp; }
+#if TRACE_DEBUG
+ np = 2 * (nsegs + ns2);
+
+#line 5001 "dk3figah.ctr"
+#endif
+ np = dk3mem_mul_size_t(2, dk3mem_add_size_t(nsegs, ns2, &mec), &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la,
+ DK3_FIG_OBJ_SPLINE, 5,
+ obj->lw, obj->pc, 7, 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1;
+ /* Arrowhead front point */
+ sp[nsegs + ns2 - 1].x = (obj->dt).arc.ra * cos(a0);
+ sp[nsegs + ns2 - 1].y = (obj->dt).arc.ra * sin(a0);
+ sp[nsegs + ns2 - 1].s = 0.0;
+
+
+#line 5021 "dk3figah.ctr"
+ /* Outer edges of arrowhead */
+ for(i = 0; i < nsegs; i++) {
+ j = i + 1;
+ if(j == nsegs) {
+ ga = a0 + f * b1;
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra, (0.5 * ah->wi), &mec
+ );
+ r2 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra, (0.5 * ah->wi), &mec
+ );
+ sp[nsegs + ns2 - 1 - j].s = 0.0;
+ sp[nsegs + ns2 - 1 + j].s = 0.0;
+ } else {
+ ga = a0 + f * b1 * ((double)j / (double)nsegs);
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * ((double)j / (double)nsegs)),
+ &mec
+ );
+ r2 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * ((double)j / (double)nsegs)),
+ &mec
+ );
+ sp[nsegs + ns2 - 1 - j].s = -1.0;
+ sp[nsegs + ns2 - 1 + j].s = -1.0;
+ }
+ sp[nsegs + ns2 - 1 - j].x = r1 * cos(ga);
+ sp[nsegs + ns2 - 1 - j].y = r1 * sin(ga);
+ sp[nsegs + ns2 - 1 + j].x = r2 * cos(ga);
+ sp[nsegs + ns2 - 1 + j].y = r2 * sin(ga);
+
+
+#line 5054 "dk3figah.ctr"
+
+
+#line 5055 "dk3figah.ctr"
+ }
+ /* Inner edges of arrowhead */
+ for(i = 0; i < (ns2 - 1); i++) {
+ j = i + 1;
+ ga = a0 + f * (b1 + b2 * ((double)j / (double)ns2));
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * (1.0 - ((double)j / (double)ns2))),
+ &mec
+ );
+ r2 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * (1.0 - ((double)j / (double)ns2))),
+ &mec
+ );
+ sp[ns2 - 1 - j].x = r1 * cos(ga);
+ sp[ns2 - 1 - j].y = r1 * sin(ga);
+ sp[ns2 - 1 - j].s = -1.0;
+ sp[2 * nsegs + ns2 - 1 + j].x = r2 * cos(ga);
+ sp[2 * nsegs + ns2 - 1 + j].y = r2 * sin(ga);
+ sp[2 * nsegs + ns2 - 1 + j].s = -1.0;
+
+
+#line 5077 "dk3figah.ctr"
+
+
+#line 5078 "dk3figah.ctr"
+ }
+ /* Inner arrowhead front point */
+ ga = a0 + f * (b1 + b2);
+ r1 = (obj->dt).arc.ra;
+ sp[2 * (nsegs + ns2) - 1].x = r1 * cos(ga);
+ sp[2 * (nsegs + ns2) - 1].y = r1 * sin(ga);
+ sp[2 * (nsegs + ns2) - 1].s = 0.0;
+
+
+#line 5086 "dk3figah.ctr"
+ /* Shift all points */
+ for(i = 0; i < np; i++) {
+ dk3fig_tool_shift_spoint(
+ &(sp[i]), (obj->dt).arc.xc, (obj->dt).arc.yc, &mec
+ );
+ }
+ if(ah->af) {
+ ao1->fc = obj->pc;
+ }
+
+#line 5095 "dk3figah.ctr"
+ }
+ }
+ }
+ } else {
+ /* ##### ERROR: Arrowhead too long! */
+ }
+ }
+ } break;
+ case DK3_FIG_AS_FULL_CIRCLE_END: {
+ b1 = dk3figah_arc_correction(
+ (obj->dt).arc.ra,
+ dk3ma_d_add_ok(
+ (0.5 * ah->he),
+ (0.5 * dk3fig_tool_get_lw(drw, obj, &mec)),
+ &mec
+ ),
+ &mec
+ );
+ if(0.0 <= b1) {
+#if 0
+ b1 = a0 + f * b1;
+#else
+ b1 = a1 + f * b1;
+#endif
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la,
+ DK3_FIG_OBJ_ELLIPSE, 3,
+ obj->lw, obj->pc, 7, 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, 0, NULL, drw->app
+ );
+ if(ao1) {
+ back = 1;
+ ah->o1 = (void *)ao1;
+ (ao1->dt).ell.an = 0.0;
+ (ao1->dt).ell.cx = dk3ma_d_add_ok(
+ (obj->dt).arc.xc,
+ ((obj->dt).arc.ra * cos(b1)),
+ &mec
+ );
+ (ao1->dt).ell.cy = dk3ma_d_add_ok(
+ (obj->dt).arc.yc,
+ ((obj->dt).arc.ra * sin(b1)),
+ &mec
+ );
+ (ao1->dt).ell.rx = 0.5 * ah->he;
+ (ao1->dt).ell.ry = 0.5 * ah->he;
+ if(ah->af) {
+ ao1->fc = obj->pc;
+ }
+ }
+ } else {
+ mec = DK3_ERROR_MATH_OUT_OF_RANGE;
+ }
+ } break;
+ case DK3_FIG_AS_HALF_CIRCLE_END: {
+ pp.x = (obj->dt).arc.ra * cos(a1);
+ pp.y = (obj->dt).arc.ra * sin(a1);
+ pp.x = dk3ma_d_add_ok(pp.x, (obj->dt).arc.xc, &mec);
+ pp.y = dk3ma_d_add_ok(pp.y, (obj->dt).arc.yc, &mec);
+ if(ah->af) {
+ s = 0.5 * dk3fig_tool_get_lw(drw, obj, ec);
+ pp.x = dk3ma_d_sub_ok(
+ pp.x,
+ (s * cos(phi)),
+ &mec
+ );
+ pp.y = dk3ma_d_sub_ok(
+ pp.y,
+ (s * sin(phi)),
+ &mec
+ );
+ }
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la,
+ DK3_FIG_OBJ_PSEUDO_HALF_CIRCLE, ((ah->af) ? 1 : 0),
+ obj->lw, obj->pc, ((ah->af) ? obj->pc : 7), 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, 0, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ back = 1;
+ (ao1->dt).hci.cx = pp.x;
+ (ao1->dt).hci.cy = pp.y;
+ (ao1->dt).hci.ra = 0.5 * ah->he;
+ (ao1->dt).hci.an = phi;
+ }
+ } break;
+ case DK3_FIG_AS_RECTANGLE: {
+ b1 = dk3ma_d_div_ok(ah->he, (obj->dt).arc.ra, &mec);
+ if(b1 < (2.0 * M_PI)) {
+
+#line 5187 "dk3figah.ctr"
+ nsegs = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b1, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ );
+ if(drw->minspp > nsegs) {
+ nsegs = drw->minspp;
+ }
+
+#line 5194 "dk3figah.ctr"
+#if TRACE_DEBUG
+ np = 2 * nsegs + 2;
+
+#line 5196 "dk3figah.ctr"
+#endif
+ np = dk3mem_add_size_t(dk3mem_mul_size_t(2, nsegs, &mec), 2, &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la,
+ DK3_FIG_OBJ_SPLINE, 5,
+ obj->lw, obj->pc, ((ah->af) ? obj->pc : 7), 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ r1 = dk3ma_d_add_ok((obj->dt).arc.ra, (0.5 * ah->wi), &mec);
+ r2 = dk3ma_d_sub_ok((obj->dt).arc.ra, (0.5 * ah->wi), &mec);
+ back = 1;
+ for(i = 0; i < nsegs; i++) {
+ if(0 == i) {
+ ga = a0;
+ sp[i].s = 0.0;
+ sp[np - 1 - i].s = 0.0;
+ } else {
+ ga = a0 + f * b1 * ((double)i / (double)nsegs);
+ sp[i].s = -1.0;
+ sp[np - 1 - i].s = -1.0;
+ }
+ sp[i].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r1 * cos(ga)), &mec
+ );
+ sp[i].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r1 * sin(ga)), &mec
+ );
+ sp[np - 1 - i].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r2 * cos(ga)), &mec
+ );
+ sp[np - 1 - i].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r2 * sin(ga)), &mec
+ );
+
+
+#line 5236 "dk3figah.ctr"
+
+
+#line 5237 "dk3figah.ctr"
+ }
+ ga = a0 + f * b1;
+ sp[nsegs].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r1 * cos(ga)), &mec
+ );
+ sp[nsegs].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r1 * sin(ga)), &mec
+ );
+ sp[nsegs].s = 0.0;
+ sp[nsegs + 1].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r2 * cos(ga)), &mec
+ );
+ sp[nsegs + 1].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r2 * sin(ga)), &mec
+ );
+ sp[nsegs + 1].s = 0.0;
+
+
+#line 5254 "dk3figah.ctr"
+
+
+#line 5255 "dk3figah.ctr"
+
+
+#line 5256 "dk3figah.ctr"
+ }
+ }
+ }
+ } else {
+ /* ##### ERROR: Arrowhead too long! */
+ }
+ } break;
+ case DK3_FIG_AS_INVERSE: {
+ b1 = dk3ma_d_div_ok(ah->he, (obj->dt).arc.ra, &mec);
+ if(b1 < (2.0 * M_PI)) {
+
+#line 5266 "dk3figah.ctr"
+ nsegs = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b1, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ );
+
+#line 5270 "dk3figah.ctr"
+ if(drw->minspp > nsegs) { nsegs = drw->minspp; }
+ np = dk3mem_add_size_t(dk3mem_mul_size_t(2, nsegs, &mec), 1, &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 5,
+ obj->lw, obj->pc, ((ah->af) ? obj->pc : 7), 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1;
+ sp[0].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, ((obj->dt).arc.ra * cos(a0 + f * b1)), &mec
+ );
+ sp[0].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, ((obj->dt).arc.ra * sin(a0 + f * b1)), &mec
+ );
+ sp[0].s = 0.0;
+
+#line 5291 "dk3figah.ctr"
+ for(i = 0; i < nsegs; i++) {
+ j = i + 1;
+ r1 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * ((double)j / (double)nsegs)),
+ &mec
+ );
+ r2 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * ((double)j / (double)nsegs)),
+ &mec
+ );
+ ga = (
+ (j == nsegs)
+ ? (a0)
+ : (a0 + f * b1 * (1.0 - ((double)j / (double)nsegs)))
+ );
+ sp[j].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r1 * cos(ga)), &mec
+ );
+ sp[j].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r1 * sin(ga)), &mec
+ );
+
+#line 5314 "dk3figah.ctr"
+ sp[j].s = ((j == nsegs) ? 0.0 : (-1.0));
+ sp[np - 1 - i].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r2 * cos(ga)), &mec
+ );
+ sp[np - 1 - i].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r2 * sin(ga)), &mec
+ );
+
+#line 5321 "dk3figah.ctr"
+ sp[np - 1 - i].s = ((j == nsegs) ? 0.0 : (-1.0));
+ }
+
+#line 5323 "dk3figah.ctr"
+ }
+ }
+ }
+ } else {
+ /* ##### ERROR: Arrowhead too long! */
+ }
+ } break;
+ case DK3_FIG_AS_INDENTED_FILLED_HALF: {
+ if(ah->af) {
+ if(ab) { mustadd = 1; }
+ } else {
+ if(!(ab)) { mustadd = 1; }
+ }
+ b1 = dk3ma_d_div_ok(
+ dk3ma_d_mul_ok(1.25, ah->he, &mec),
+ (obj->dt).arc.ra, &mec
+ );
+ b2 = dk3ma_d_div_ok((0.25 * ah->he), (obj->dt).arc.ra, &mec);
+ b3 = dk3ma_d_div_ok(ah->he, (obj->dt).arc.ra, &mec);
+ if((b1 < (2.0 * M_PI)) && (b2 < (2.0 * M_PI)) && (b3 < (2.0 * M_PI))) {
+
+
+#line 5344 "dk3figah.ctr"
+ nsegs = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b1, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ );
+
+#line 5348 "dk3figah.ctr"
+ ns2 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b2, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ );
+
+#line 5352 "dk3figah.ctr"
+ ns3 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b3, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ );
+ if(drw->minspp > nsegs) { nsegs = drw->minspp; }
+ if(drw->minspp > ns2) { ns2 = drw->minspp; }
+ if(drw->minspp > ns3) { ns3 = drw->minspp; }
+ np = dk3mem_mul_size_t(2, dk3mem_add_size_t(nsegs, ns2, &mec), &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la,
+ DK3_FIG_OBJ_SPLINE, 5,
+ obj->lw, obj->pc, 7, 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ /* Arrowhead front point */
+ sp[nsegs + ns2 - 1].x = (obj->dt).arc.ra * cos(a0);
+ sp[nsegs + ns2 - 1].y = (obj->dt).arc.ra * sin(a0);
+ sp[nsegs + ns2 - 1].s = 0.0;
+
+
+#line 5377 "dk3figah.ctr"
+ /* Outer edges of arrowhead */
+ for(i = 0; i < nsegs; i++) {
+ j = i + 1;
+ if(j == nsegs) {
+ ga = a0 + f * b1;
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra, (0.5 * ah->wi), &mec
+ );
+ r2 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra, (0.5 * ah->wi), &mec
+ );
+ sp[nsegs + ns2 - 1 - j].s = 0.0;
+ sp[nsegs + ns2 - 1 + j].s = 0.0;
+ } else {
+ ga = a0 + f * b1 * ((double)j / (double)nsegs);
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * ((double)j / (double)nsegs)),
+ &mec
+ );
+ r2 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * ((double)j / (double)nsegs)),
+ &mec
+ );
+ sp[nsegs + ns2 - 1 - j].s = -1.0;
+ sp[nsegs + ns2 - 1 + j].s = -1.0;
+ }
+ sp[nsegs + ns2 - 1 - j].x = r1 * cos(ga);
+ sp[nsegs + ns2 - 1 - j].y = r1 * sin(ga);
+ sp[nsegs + ns2 - 1 + j].x = r2 * cos(ga);
+ sp[nsegs + ns2 - 1 + j].y = r2 * sin(ga);
+
+
+#line 5410 "dk3figah.ctr"
+
+
+#line 5411 "dk3figah.ctr"
+ }
+ /* Inner edges of arrowhead */
+ for(i = 0; i < (ns2 - 1); i++) {
+ j = i + 1;
+ ga = a0 + f * (b1 - b2 * ((double)j / (double)ns2));
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * (1.0 - ((double)j / (double)ns2))),
+ &mec
+ );
+ r2 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * (1.0 - ((double)j / (double)ns2))),
+ &mec
+ );
+ sp[ns2 - 1 - j].x = r1 * cos(ga);
+ sp[ns2 - 1 - j].y = r1 * sin(ga);
+ sp[ns2 - 1 - j].s = -1.0;
+ sp[2 * nsegs + ns2 - 1 + j].x = r2 * cos(ga);
+ sp[2 * nsegs + ns2 - 1 + j].y = r2 * sin(ga);
+ sp[2 * nsegs + ns2 - 1 + j].s = -1.0;
+
+
+#line 5433 "dk3figah.ctr"
+
+
+#line 5434 "dk3figah.ctr"
+ }
+ /* Inner arrowhead front point */
+ ga = a0 + f * (b1 - b2);
+ r1 = (obj->dt).arc.ra;
+ sp[2 * (nsegs + ns2) - 1].x = r1 * cos(ga);
+ sp[2 * (nsegs + ns2) - 1].y = r1 * sin(ga);
+ sp[2 * (nsegs + ns2) - 1].s = 0.0;
+
+
+#line 5442 "dk3figah.ctr"
+ /* Shift all points */
+ for(i = 0; i < np; i++) {
+ dk3fig_tool_shift_spoint(
+ &(sp[i]), (obj->dt).arc.xc, (obj->dt).arc.yc, &mec
+ );
+ }
+
+#line 5448 "dk3figah.ctr"
+ np = dk3mem_add_size_t(nsegs, dk3mem_add_size_t(ns2, ns3, &mec), &mec);
+ if(0 == mec) {
+ ao2 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 5,
+ 0, obj->pc, obj->pc, 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao2) {
+
+#line 5457 "dk3figah.ctr"
+ ah->o2 = (void *)ao2;
+ sp = (ao2->dt).spl.po;
+ if(sp) {
+ back = 1;
+ sp[0].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, ((obj->dt).arc.ra * cos(a0)), &mec
+ );
+ sp[0].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, ((obj->dt).arc.ra * sin(a0)), &mec
+ );
+ sp[0].s = 0.0;
+
+#line 5468 "dk3figah.ctr"
+ /* Outer edge */
+ for(i = 0; i < nsegs; i++) {
+ j = i + 1;
+ if(j == nsegs) {
+ if(mustadd) {
+ r1 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra, (0.5 * ah->wi), &mec
+ );
+ } else {
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra, (0.5 * ah->wi), &mec
+ );
+ }
+ ga = a0 + f * b1;
+ } else {
+ if(mustadd) {
+ r1 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ((double)j / (double)nsegs) * ah->wi),
+ &mec
+ );
+ } else {
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ((double)j / (double)nsegs) * ah->wi),
+ &mec
+ );
+ }
+ ga = a0 + f * b1 * ((double)j / (double)nsegs);
+ }
+ sp[j].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r1 * cos(ga)), &mec
+ );
+ sp[j].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r1 * sin(ga)), &mec
+ );
+
+#line 5504 "dk3figah.ctr"
+ sp[j].s = ((j == nsegs) ? 0.0 : (-1.0));
+ }
+ /* Indention edge */
+ for(i = 0; i < ns2; i++) {
+ j = i + 1;
+ if(j == ns2) {
+ r1 = (obj->dt).arc.ra;
+ ga = a0 + f * (b1 - b2);
+ } else {
+ if(mustadd) {
+ r1 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * (1.0 - ((double)j / (double)nsegs))),
+ &mec
+ );
+ } else {
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * (1.0 - ((double)j / (double)nsegs))),
+ &mec
+ );
+ }
+ ga = a0 + f * (b1 - ((double)j / (double)nsegs) * b2);
+ }
+ sp[nsegs + j].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r1 * cos(ga)), &mec
+ );
+ sp[nsegs + j].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r1 * sin(ga)), &mec
+ );
+
+#line 5534 "dk3figah.ctr"
+ sp[nsegs + j].s = ((j == ns2) ? 0.0 : (-1.0));
+ }
+ /* Inner edge */
+ for(i = 0; i < (ns3 - 1); i++) {
+ j = i + 1;
+ ga = a0 + f *(b1 - b2 - b3 * ((double)j / (double)nsegs));
+ sp[nsegs + ns2 + j].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, ((obj->dt).arc.ra * cos(ga)), &mec
+ );
+ sp[nsegs + ns2 + j].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, ((obj->dt).arc.ra * sin(ga)), &mec
+ );
+
+#line 5546 "dk3figah.ctr"
+ sp[nsegs + ns2 + j].s = -1.0;
+ }
+
+#line 5548 "dk3figah.ctr"
+ }
+ }
+ }
+ }
+ }
+ }
+ } else {
+ /* ##### ERROR: Arrowhead too long! */
+ }
+ } break;
+ case DK3_FIG_AS_CLOSED_HALF: {
+ b1 = dk3ma_d_div_ok(ah->he, (obj->dt).arc.ra, &mec);
+ if(b1 < (2.0 * M_PI)) {
+
+#line 5561 "dk3figah.ctr"
+ nsegs = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b1, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ );
+ if(drw->minspp > nsegs) { nsegs = drw->minspp; }
+ np = dk3mem_add_size_t(dk3mem_mul_size_t(2, nsegs, &mec), 1, &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 5,
+ obj->lw, obj->pc, ((ah->af) ? obj->pc : 7), 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1;
+ sp[0].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, ((obj->dt).arc.ra * cos(a0)), &mec
+ );
+ sp[0].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, ((obj->dt).arc.ra * sin(a0)), &mec
+ );
+ sp[0].s = 0.0;
+ for(i = 0; i < nsegs; i++) {
+ j = i + 1;
+ if(j == nsegs) {
+ ga = a0 + f * b1;
+ if(ab) {
+ r1 = dk3ma_d_add_ok((obj->dt).arc.ra, (0.5 * ah->wi), &mec);
+ } else {
+ r1 = dk3ma_d_sub_ok((obj->dt).arc.ra, (0.5 * ah->wi), &mec);
+ }
+ } else {
+ if(ab) {
+ r1 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ((double)j / (double)nsegs) * ah->wi),
+ &mec
+ );
+ } else {
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ((double)j / (double)nsegs) * ah->wi),
+ &mec
+ );
+ }
+ ga = a0 + f * b1 * ((double)j / (double)nsegs);
+ }
+ sp[j].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r1 * cos(ga)), &mec
+ );
+ sp[j].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r1 * sin(ga)), &mec
+ );
+ sp[j].s = ((j == nsegs) ? 0.0 : (-1.0));
+ sp[np - 1 - i].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, ((obj->dt).arc.ra * cos(ga)), &mec
+ );
+ sp[np - 1 - i].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, ((obj->dt).arc.ra * sin(ga)), &mec
+ );
+ sp[np - 1 - i].s = ((j == nsegs) ? 0.0 : (-1.0));
+ }
+
+#line 5626 "dk3figah.ctr"
+ }
+ }
+ }
+ } else {
+ /* ##### ERROR: Arrowhead too long! */
+ }
+ } break;
+ case DK3_FIG_AS_INDENTED_HALF: {
+ b1 = dk3ma_d_div_ok(
+ dk3ma_d_mul_ok(1.25, ah->he, &mec), (obj->dt).arc.ra, &mec
+ );
+ b2 = dk3ma_d_div_ok((0.25 * ah->he), (obj->dt).arc.ra, &mec);
+ b3 = dk3ma_d_div_ok(ah->he, (obj->dt).arc.ra, &mec);
+ if((b1 < (2.0 * M_PI)) && (b2 < (2.0 * M_PI)) && (b3 < (2.0 * M_PI))) {
+
+
+#line 5641 "dk3figah.ctr"
+ nsegs = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b1, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ );
+
+#line 5645 "dk3figah.ctr"
+ ns2 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b2, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ );
+
+#line 5649 "dk3figah.ctr"
+ ns3 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b3, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ );
+ if(drw->minspp > nsegs) { nsegs = drw->minspp; }
+ if(drw->minspp > ns2) { ns2 = drw->minspp; }
+ if(drw->minspp > ns3) { ns3 = drw->minspp; }
+ np = dk3mem_add_size_t(dk3mem_add_size_t(nsegs, ns2, &mec), ns3, &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 5,
+ obj->lw, obj->pc, ((ah->af) ? obj->pc : 7), 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+
+#line 5668 "dk3figah.ctr"
+ back = 1;
+ /* front point */
+ sp[0].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, ((obj->dt).arc.ra * cos(a0)), &mec
+ );
+ sp[0].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, ((obj->dt).arc.ra * sin(a0)), &mec
+ );
+
+#line 5676 "dk3figah.ctr"
+ sp[0].s = 0.0;
+ /* outer edge */
+ for(i = 0; i < nsegs; i++) {
+ j = i + 1;
+ if(ab) {
+ r1 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ((double)j / (double)nsegs) * ah->wi),
+ &mec
+ );
+ } else {
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ((double)j / (double)nsegs) * ah->wi),
+ &mec
+ );
+ }
+ ga = a0 + f * b1 * ((double)j / (double)nsegs);
+ if(j == nsegs) {
+ if(ab) {
+ r1 = dk3ma_d_add_ok((obj->dt).arc.ra, (0.5 * ah->wi), &mec);
+ } else {
+ r1 = dk3ma_d_sub_ok((obj->dt).arc.ra, (0.5 * ah->wi), &mec);
+ }
+ ga = a0 + f * b1;
+ }
+ sp[j].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r1 * cos(ga)), &mec
+ );
+ sp[j].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r1 * sin(ga)), &mec
+ );
+
+#line 5708 "dk3figah.ctr"
+ sp[j].s = ((j == nsegs) ? 0.0 : (-1.0));
+ }
+ /* indention edge */
+ for(i = 0; i < ns2; i++) {
+ j = i + 1;
+ if(ab) {
+ r1 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra,
+ (0.5 * (1.0 - ((double)j / (double)ns2)) * ah->wi),
+ &mec
+ );
+ } else {
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra,
+ (0.5 * (1.0 - ((double)j / (double)ns2)) * ah->wi),
+ &mec
+ );
+ }
+ ga = a0 + f * (b1 - b2 * ((double)j / (double)ns2));
+ if(j == ns2) {
+ r1 = (obj->dt).arc.ra;
+ ga = a0 + f * (b1 - b2);
+ }
+ sp[nsegs + j].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r1 * cos(ga)), &mec
+ );
+ sp[nsegs + j].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r1 * sin(ga)), &mec
+ );
+
+#line 5737 "dk3figah.ctr"
+ sp[nsegs + j].s = ((j == ns2) ? 0.0 : (-1.0));
+ }
+ /* inner edge */
+ for(i = 0; i < (ns3 - 1); i++) {
+ j = i + 1;
+ ga = a0 + f * (b1 - b2 - b3 * ((double)j / (double)ns3));
+ sp[nsegs + ns2 + j].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, ((obj->dt).arc.ra * cos(ga)), &mec
+ );
+ sp[nsegs + ns2 + j].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, ((obj->dt).arc.ra * sin(ga)), &mec
+ );
+
+#line 5749 "dk3figah.ctr"
+ sp[nsegs + ns2 + j].s = -1.0;
+ }
+
+#line 5751 "dk3figah.ctr"
+ }
+ }
+ }
+ } else {
+ /* ##### ERROR: Arrow too long */
+ }
+ } break;
+ case DK3_FIG_AS_BUTTED_HALF: {
+ b1 = dk3ma_d_div_ok(
+ (0.75 * ah->he), (obj->dt).arc.ra, &mec
+ );
+ b2 = dk3ma_d_div_ok((0.25 * ah->he), (obj->dt).arc.ra, &mec);
+ b3 = dk3ma_d_div_ok(ah->he, (obj->dt).arc.ra, &mec);
+ if((b1 < (2.0 * M_PI)) && (b2 < (2.0 * M_PI)) && (b3 < (2.0 * M_PI))) {
+
+
+#line 5766 "dk3figah.ctr"
+ nsegs = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b1, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ );
+
+#line 5770 "dk3figah.ctr"
+ ns2 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b2, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ );
+
+#line 5774 "dk3figah.ctr"
+ ns3 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b3, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ );
+ if(drw->minspp > nsegs) { nsegs = drw->minspp; }
+ if(drw->minspp > ns2) { ns2 = drw->minspp; }
+ if(drw->minspp > ns3) { ns3 = drw->minspp; }
+ np = dk3mem_add_size_t(dk3mem_add_size_t(nsegs, ns2, &mec), ns3, &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 5,
+ obj->lw, obj->pc, ((ah->af) ? obj->pc : 7), 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+
+#line 5793 "dk3figah.ctr"
+ back = 1;
+ /* front point */
+ sp[0].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, ((obj->dt).arc.ra * cos(a0)), &mec
+ );
+ sp[0].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, ((obj->dt).arc.ra * sin(a0)), &mec
+ );
+
+#line 5801 "dk3figah.ctr"
+ sp[0].s = 0.0;
+ /* outer edge */
+ for(i = 0; i < nsegs; i++) {
+ j = i + 1;
+ if(ab) {
+ r1 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ((double)j / (double)nsegs) * ah->wi),
+ &mec
+ );
+ } else {
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ((double)j / (double)nsegs) * ah->wi),
+ &mec
+ );
+ }
+ ga = a0 + f * b1 * ((double)j / (double)nsegs);
+ if(j == nsegs) {
+ if(ab) {
+ r1 = dk3ma_d_add_ok((obj->dt).arc.ra, (0.5 * ah->wi), &mec);
+ } else {
+ r1 = dk3ma_d_sub_ok((obj->dt).arc.ra, (0.5 * ah->wi), &mec);
+ }
+ ga = a0 + f * b1;
+ }
+ sp[j].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r1 * cos(ga)), &mec
+ );
+ sp[j].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r1 * sin(ga)), &mec
+ );
+
+#line 5833 "dk3figah.ctr"
+ sp[j].s = ((j == nsegs) ? 0.0 : (-1.0));
+ }
+ /* indention edge */
+ for(i = 0; i < ns2; i++) {
+ j = i + 1;
+ if(ab) {
+ r1 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra,
+ (0.5 * (1.0 - ((double)j / (double)ns2)) * ah->wi),
+ &mec
+ );
+ } else {
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra,
+ (0.5 * (1.0 - ((double)j / (double)ns2)) * ah->wi),
+ &mec
+ );
+ }
+ ga = a0 + f * (b1 + b2 * ((double)j / (double)ns2));
+ if(j == ns2) {
+ r1 = (obj->dt).arc.ra;
+ ga = a0 + f * (b1 + b2);
+ }
+ sp[nsegs + j].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r1 * cos(ga)), &mec
+ );
+ sp[nsegs + j].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r1 * sin(ga)), &mec
+ );
+
+#line 5862 "dk3figah.ctr"
+ sp[nsegs + j].s = ((j == ns2) ? 0.0 : (-1.0));
+ }
+ /* inner edge */
+ for(i = 0; i < (ns3 - 1); i++) {
+ j = i + 1;
+ ga = a0 + f * (b1 + b2 - b3 * ((double)j / (double)ns3));
+ sp[nsegs + ns2 + j].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, ((obj->dt).arc.ra * cos(ga)), &mec
+ );
+ sp[nsegs + ns2 + j].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, ((obj->dt).arc.ra * sin(ga)), &mec
+ );
+
+#line 5874 "dk3figah.ctr"
+ sp[nsegs + ns2 + j].s = -1.0;
+ }
+
+#line 5876 "dk3figah.ctr"
+ }
+ }
+ }
+ } else {
+ /* ##### ERROR: Arrow too long */
+ }
+ } break;
+ case DK3_FIG_AS_TRIANGLE_FORK: {
+ if(ah->af) {
+
+#line 5885 "dk3figah.ctr"
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_POLYLINE, 1,
+ obj->lw, obj->pc, obj->pc, -1,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, 2, NULL, drw->app
+ );
+ if(ao1) {
+
+#line 5892 "dk3figah.ctr"
+ ah->o1 = (void *)ao1;
+ po = (ao1->dt).pol.po;
+ if(po) {
+
+#line 5895 "dk3figah.ctr"
+ back = 1;
+ r1 = dk3ma_d_add_ok((obj->dt).arc.ra, (0.5 * ah->wi), &mec);
+ r2 = dk3ma_d_sub_ok((obj->dt).arc.ra, (0.5 * ah->wi), &mec);
+ po[0].x = dk3ma_d_add_ok((obj->dt).arc.xc, (r1 * cos(a0)), &mec);
+ po[0].y = dk3ma_d_add_ok((obj->dt).arc.yc, (r1 * sin(a0)), &mec);
+ po[1].x = dk3ma_d_add_ok((obj->dt).arc.xc, (r2 * cos(a0)), &mec);
+ po[1].y = dk3ma_d_add_ok((obj->dt).arc.yc, (r2 * sin(a0)), &mec);
+
+
+#line 5903 "dk3figah.ctr"
+
+
+#line 5904 "dk3figah.ctr"
+ }
+ }
+ } else {
+ b1 = dk3ma_d_div_ok(ah->he, (obj->dt).arc.ra, &mec);
+ if(b1 < (2.0 * M_PI)) {
+
+#line 5909 "dk3figah.ctr"
+ nsegs = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b1, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ );
+ if(drw->minspp > nsegs) { nsegs = drw->minspp; }
+ np = dk3mem_add_size_t(dk3mem_mul_size_t(2, nsegs, &mec), 1, &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 4,
+ obj->lw, obj->pc, -1, -1,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1;
+ ga = a0 + f * b1;
+ sp[nsegs].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc,
+ ((obj->dt).arc.ra * cos(ga)),
+ &mec
+ );
+ sp[nsegs].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc,
+ ((obj->dt).arc.ra * sin(ga)),
+ &mec
+ );
+ sp[nsegs].s = 0.0;
+ for(i = 0; i < nsegs; i++) {
+ j = i + 1;
+ r1 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ((double)j / (double)nsegs) * ah->wi),
+ &mec
+ );
+ r2 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ((double)j / (double)nsegs) * ah->wi),
+ &mec
+ );
+ ga = a0 + f * b1 * (1.0 - ((double)j / (double)nsegs));
+ if(j == nsegs) {
+ r1 = dk3ma_d_add_ok((obj->dt).arc.ra, (0.5 * ah->wi), &mec);
+ r2 = dk3ma_d_sub_ok((obj->dt).arc.ra, (0.5 * ah->wi), &mec);
+ ga = a0;
+ }
+ sp[nsegs + j].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r1 * cos(ga)), &mec
+ );
+ sp[nsegs + j].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r1 * sin(ga)), &mec
+ );
+ sp[nsegs + j].s = ((j == nsegs) ? 0.0 : (-1.0));
+ sp[nsegs - j].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r2 * cos(ga)), &mec
+ );
+ sp[nsegs - j].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r2 * sin(ga)), &mec
+ );
+ sp[nsegs - j].s = ((j == nsegs) ? 0.0 : (-1.0));
+ }
+ }
+ }
+ }
+ } else {
+ /* ##### ERROR: Arrow too long! */
+ }
+ }
+ } break;
+ case DK3_FIG_AS_RECTANGLE_FORK: {
+ b1 = dk3ma_d_div_ok(ah->he, (obj->dt).arc.ra, &mec);
+ if(b1 < (2.0 * M_PI)) {
+
+#line 5983 "dk3figah.ctr"
+ nsegs = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b1, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ );
+
+#line 5987 "dk3figah.ctr"
+ if(drw->minspp > nsegs) { nsegs = drw->minspp; }
+ np = dk3mem_mul_size_t(2, dk3mem_add_size_t(nsegs, 1, &mec), &mec);
+ if(0 == mec) {
+
+#line 5990 "dk3figah.ctr"
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 4,
+ obj->lw, obj->pc, obj->pc, -1,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1;
+ r1 = dk3ma_d_add_ok((obj->dt).arc.ra, (0.5 * ah->wi), &mec);
+ r2 = dk3ma_d_sub_ok((obj->dt).arc.ra, (0.5 * ah->wi), &mec);
+ if(ah->af) {
+
+#line 6004 "dk3figah.ctr"
+ ga = a0;
+ } else {
+
+#line 6006 "dk3figah.ctr"
+ ga = a0 + f * b1;
+ }
+ sp[nsegs].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r1 * cos(ga)), &mec
+ );
+ sp[nsegs].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r1 * sin(ga)), &mec
+ );
+
+#line 6014 "dk3figah.ctr"
+ sp[nsegs].s = 0.0;
+ sp[nsegs + 1].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r2 * cos(ga)), &mec
+ );
+ sp[nsegs + 1].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r2 * sin(ga)), &mec
+ );
+
+#line 6021 "dk3figah.ctr"
+ sp[nsegs + 1].s = 0.0;
+ for(i = 0; i < nsegs; i++) {
+ j = i + 1;
+ if(ah->af) {
+ ga = a0 + f * b1 * ((double)j / (double)nsegs);
+ } else {
+ ga = a0 + f * b1 * (1.0 - ((double)j / (double)nsegs));
+ }
+ sp[nsegs - j].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r1 * cos(ga)), &mec
+ );
+ sp[nsegs - j].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r1 * sin(ga)), &mec
+ );
+
+#line 6035 "dk3figah.ctr"
+ sp[nsegs - j].s = 0.0;
+ sp[nsegs + 1 + j].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r2 * cos(ga)), &mec
+ );
+ sp[nsegs + 1 + j].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r2 * sin(ga)), &mec
+ );
+
+#line 6042 "dk3figah.ctr"
+ sp[nsegs + 1 + j].s = 0.0;
+ }
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ }
+ } else {
+ /* ##### ERROR: Arrowhead too long! */
+ }
+ } break;
+ }
+ if(mec) {
+
+#line 6055 "dk3figah.ctr"
+ back = 0;
+ if(ec) { *ec = mec; }
+ }
+
+
+#line 6059 "dk3figah.ctr"
+ return back;
+}
+
+
+
+/** Calculate arrowheads for arc.
+ @param drw Drawing to modify.
+ @param obj Object to modify.
+ @param objno Object number.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figah_calculate_arc(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ unsigned long objno
+)
+{
+ dk3_fig_poly_point_t sp;
+ double cuts = -1.0;
+ double cute = -1.0;
+ double das = 0.0;
+ double dae = 0.0;
+ double newas = 0.0;
+ double newae = 0.0;
+ double alphaf = 0.0;
+ double alphab = 0.0;
+ int back = 1;
+ int mec = 0;
+ int res = 0;
+
+
+#line 6091 "dk3figah.ctr"
+ /*
+ Construct arrowhead objects.
+ */
+ if(obj->af) {
+ cute = dk3figah_length_correction(drw, obj, obj->af, &mec);
+ }
+ if(obj->ab) {
+ cuts = dk3figah_length_correction(drw, obj, obj->ab, &mec);
+ }
+
+#line 6100 "dk3figah.ctr"
+ /*
+ Create arrowhead objects.
+ */
+ if((obj->dt).arc.ae >= (obj->dt).arc.as) {
+ if(obj->af) {
+ alphaf = (obj->dt).arc.ae + M_PI_2;
+ }
+ if(obj->ab) {
+ alphab = (obj->dt).arc.as - M_PI_2;
+ }
+ } else {
+ if(obj->af) {
+ alphaf = (obj->dt).arc.ae - M_PI_2;
+ }
+ if(obj->ab) {
+ alphab = (obj->dt).arc.as + M_PI_2;
+ }
+ }
+ if(drw->coah) {
+ if(obj->af) {
+ sp.x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc,
+ ((obj->dt).arc.ra * cos((obj->dt).arc.ae)),
+ &mec
+ );
+ sp.y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc,
+ ((obj->dt).arc.ra * sin((obj->dt).arc.ae)),
+ &mec
+ );
+
+#line 6130 "dk3figah.ctr"
+ res = dk3figah_straight_arrowhead(
+ drw, obj, obj->af, &sp, alphaf, &mec
+ );
+ if(!(res)) { back = 0; }
+ }
+ if(obj->ab) {
+ sp.x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc,
+ ((obj->dt).arc.ra * cos((obj->dt).arc.as)),
+ &mec
+ );
+ sp.y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc,
+ ((obj->dt).arc.ra * sin((obj->dt).arc.as)),
+ &mec
+ );
+
+#line 6146 "dk3figah.ctr"
+ res = dk3figah_straight_arrowhead(
+ drw, obj, obj->ab, &sp, alphab, &mec
+ );
+ if(!(res)) { back = 0; }
+ }
+ if(mec) { back = 0; }
+ } else {
+ if(obj->af) {
+ if(!dk3figah_one_arc_arrowhead(drw, obj, obj->af, 0, &mec)) {
+ back = 0;
+ }
+ }
+ if(obj->ab) {
+ if(!dk3figah_one_arc_arrowhead(drw, obj, obj->ab, 1, &mec)) {
+ back = 0;
+ }
+ }
+ }
+ /*
+ Cut arc if necessary when not using compatible arrowheads.
+ */
+ if(!(drw->coah)) {
+ newas = (obj->dt).arc.as;
+ newae = (obj->dt).arc.ae;
+ if(0.0 < cuts) {
+
+#line 6171 "dk3figah.ctr"
+ if(dk3figah_must_use_arc_correction(obj->ab)) {
+ das = dk3figah_arc_correction((obj->dt).arc.ra, cuts, &mec);
+ if(0.0 <= das) {
+ if((obj->dt).arc.di) {
+
+#line 6175 "dk3figah.ctr"
+ newas = dk3ma_d_add_ok(newas, das, &mec);
+ } else {
+
+#line 6177 "dk3figah.ctr"
+ newas = dk3ma_d_sub_ok(newas, das, &mec);
+ }
+ } else {
+ mec = DK3_ERROR_MATH_OUT_OF_RANGE;
+ }
+ } else {
+ das = dk3ma_d_div_ok(cuts, (obj->dt).arc.ra, &mec);
+
+
+#line 6185 "dk3figah.ctr"
+ if((obj->dt).arc.di) {
+
+#line 6186 "dk3figah.ctr"
+ newas = dk3ma_d_add_ok(newas, das, &mec);
+ } else {
+
+#line 6188 "dk3figah.ctr"
+ newas = dk3ma_d_sub_ok(newas, das, &mec);
+ }
+ }
+ }
+ if(0.0 < cute) {
+
+#line 6193 "dk3figah.ctr"
+ if(dk3figah_must_use_arc_correction(obj->af)) {
+ dae = dk3figah_arc_correction((obj->dt).arc.ra, cute, &mec);
+ if(0.0 <= dae) {
+ if((obj->dt).arc.di) {
+
+#line 6197 "dk3figah.ctr"
+ newae = dk3ma_d_sub_ok(newae, dae, &mec);
+ } else {
+
+#line 6199 "dk3figah.ctr"
+ newae = dk3ma_d_add_ok(newae, dae, &mec);
+ }
+ } else {
+ mec = DK3_ERROR_MATH_OUT_OF_RANGE;
+ }
+ } else {
+ dae = dk3ma_d_div_ok(cute, (obj->dt).arc.ra, &mec);
+
+
+#line 6207 "dk3figah.ctr"
+ if((obj->dt).arc.di) {
+
+#line 6208 "dk3figah.ctr"
+ newae = dk3ma_d_sub_ok(newae, dae, &mec);
+ } else {
+
+#line 6210 "dk3figah.ctr"
+ newae = dk3ma_d_add_ok(newae, dae, &mec);
+ }
+ }
+ }
+ if(0 == mec) {
+
+
+#line 6216 "dk3figah.ctr"
+
+
+#line 6217 "dk3figah.ctr"
+
+
+#line 6218 "dk3figah.ctr"
+
+
+#line 6219 "dk3figah.ctr"
+
+
+#line 6220 "dk3figah.ctr"
+
+
+#line 6221 "dk3figah.ctr"
+
+
+#line 6222 "dk3figah.ctr"
+
+
+#line 6223 "dk3figah.ctr"
+ (obj->dt).arc.as = newas; (obj->dt).arc.ae = newae;
+ } else {
+ /* ##### ERROR: Math error */
+ back = 0;
+ }
+ } else {
+ if(0 != mec) {
+ back = 0;
+ dk3app_log_i1(drw->app, DK3_LL_ERROR, 260);
+ }
+ }
+
+
+#line 6235 "dk3figah.ctr"
+ return back;
+}
+
+
+
+int
+dk3figah_calculate_arrowheads(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ unsigned long objno
+)
+{
+ int back = 0;
+ int failed = 0;
+
+
+#line 6250 "dk3figah.ctr"
+ if((drw) && (obj)) {
+ back = 1;
+ if(dk3figah_candidate(obj)) {
+ /*
+ Use butted line when arrowheads on both ends.
+ */
+ if((obj->af) && (obj->ab)) { obj->cs = DK3_FIG_LC_BUTT; }
+ switch(obj->ot) {
+ case DK3_FIG_OBJ_POLYLINE: {
+ back = dk3figah_calculate_polyline(drw, obj, objno);
+ if(!(back)) { failed = 1; }
+ } break;
+ case DK3_FIG_OBJ_SPLINE: {
+ back = dk3figah_calculate_spline(drw, obj, objno);
+ if(!(back)) { failed = 1; }
+ } break;
+ case DK3_FIG_OBJ_ARC: {
+ back = dk3figah_calculate_arc(drw, obj, objno);
+ if(!(back)) { failed = 1; }
+ } break;
+ }
+ if(failed) {
+ /* ##### ERROR: Arrowhead calculation failed! */
+ }
+ }
+ }
+ if((!(back)) && (NULL != drw)) {
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 5);
+ }
+
+#line 6279 "dk3figah.ctr"
+ return back;
+}
+
diff --git a/support/dktools/dk3figah.ctr b/support/dktools/dk3figah.ctr
new file mode 100644
index 0000000000..609941aa98
--- /dev/null
+++ b/support/dktools/dk3figah.ctr
@@ -0,0 +1,6281 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Check whether an object is a candidate to have arrowheads.
+ @param obj Object to check.
+ @return 1 if the object may have arrowheads, 0 otherwise.
+*/
+int
+dk3figah_candidate(dk3_fig_obj_t *obj);
+
+/** Calculate arrowheads for open object.
+ @param drw Drawing of object.
+ @param obj Object to modify.
+ @param objno Object number.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3figah_calculate_arrowheads(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ unsigned long objno
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk3all.h"
+#include "dk3fig.h"
+#include "dk3figto.h"
+#include "dk3figpr.h"
+#include "dk3figbb.h"
+#include "dk3figah.h"
+#include "dk3xsp.h"
+
+
+$!trace-include
+
+
+
+/** Calculate c_min (minimum length to cut).
+ @param drw Drawing.
+ @param obj Object to calculate arrowheads for.
+ @param ah Arrowhead data.
+ @param ec Pointer to error code variable, may be NULL.
+ @return The c_min value.
+*/
+static
+double
+dk3figah_cmin(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec
+)
+{
+ double back;
+ double h;
+ double w;
+ double lw; /* Line width. */
+ $? "+ dk3figah_cmin"
+ lw = dk3fig_tool_get_lw(drw, obj, ec);
+ h = ah->he;
+ w = ah->wi;
+ switch(ah->as) {
+ case DK3_FIG_AS_INDENTED:
+ case DK3_FIG_AS_INDENTED_FILLED_HALF:
+ {
+ h = dk3ma_d_mul_ok(1.25, h, ec);
+ } break;
+ case DK3_FIG_AS_POINTED: {
+ h = 0.75 * h;
+ } break;
+ case DK3_FIG_AS_RHOMBUS: {
+ h = 0.5 * h;
+ } break;
+ }
+ back = dk3ma_d_div_ok(dk3ma_d_mul_ok(lw, h, ec), w, ec);
+ $? "- dk3figah_cmin (lw=%lg h=%lg w=%lg) %lg", lw, h, w, back
+ return back;
+}
+
+
+
+/** Calculate s value for arrowhead.
+ @param drw Drawing.
+ @param obj Object to calculate arrowheads for.
+ @param ah Arrowhead data.
+ @param ec Pointer to error code variable, may be NULL.
+ @return The s value.
+*/
+static
+double
+dk3figah_s(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec
+)
+{
+ double back;
+ double lw; /* Line width. */
+ double h; /* Arrow height (length). */
+ double w; /* Arrow width. */
+ $? "+ dk3figah_s"
+ lw = dk3fig_tool_get_lw(drw, obj, ec);
+ h = ah->he;
+ w = ah->wi;
+ switch(ah->as) {
+ case DK3_FIG_AS_INDENTED:
+ case DK3_FIG_AS_INDENTED_FILLED_HALF:
+ {
+ h = dk3ma_d_mul_ok(1.25, h, ec); $? ". s indented"
+ } break;
+ case DK3_FIG_AS_POINTED: {
+ h = 0.75 * h; $? ". s pointed"
+ } break;
+ case DK3_FIG_AS_RHOMBUS: {
+ h = 0.5 * h; $? ". s rhombus"
+ } break;
+ }
+ back = dk3ma_d_mul_ok(
+ dk3ma_d_div_ok(lw, w, ec),
+ sqrt(
+ dk3ma_d_add_ok(
+ dk3ma_d_square_ok(h, ec),
+ dk3ma_d_div_ok(
+ dk3ma_d_square_ok(w, ec),
+ 4.0,
+ ec
+ ),
+ ec
+ )
+ ),
+ ec
+ ); $? "- dk3figah_s (h=%lg w=%lg) %lg", h, w, back
+ return back;
+}
+
+
+
+/** Calculate s value for half arrowhead.
+ @param drw Drawing.
+ @param obj Object to calculate arrowheads for.
+ @param ah Arrowhead data.
+ @param ec Pointer to error code variable, may be NULL.
+ @return The s value.
+*/
+static
+double
+dk3figah_half_arrow_s(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec
+)
+{
+ double back;
+ double lw; /* Line width. */
+ double h; /* Arrow height (length). */
+ double w; /* Arrow width. */
+ $? "+ dk3figah_half_arrow_s"
+ lw = dk3fig_tool_get_lw(drw, obj, ec);
+ h = ah->he;
+ w = ah->wi;
+ switch(ah->as) {
+ case DK3_FIG_AS_INDENTED_HALF:
+ {
+ h = dk3ma_d_mul_ok(1.25, h, ec); $? ". s indented"
+ } break;
+ case DK3_FIG_AS_BUTTED_HALF: {
+ h = 0.75 * h; $? ". s pointed"
+ } break;
+ }
+ back = dk3ma_d_div_ok(
+ dk3ma_d_mul_ok(2.0, dk3ma_d_mul_ok(h, lw, ec), ec), w, ec
+ );
+ $? "- dk3figah_half_arrow_s (h=%lg w=%lg lw=%lg) %lg", h, w, lw, back
+ return back;
+}
+
+
+
+#if 0
+/** Calculate c_max value for arrowhead.
+ @param drw Drawing.
+ @param obj Object to calculate arrowheads for.
+ @param ah Arrowhead data.
+ @param ec Pointer to error code variable, may be NULL.
+ @return The c_max value.
+*/
+static
+double
+dk3figah_cmax(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec
+)
+{
+ double back;
+ $? "+ dk3figah_cmax"
+ back = dk3ma_d_mul_ok(
+ 2.0,
+ dk3figah_s(drw, obj, ah, ec),
+ ec
+ ); $? "- dk3figah_cmax %lg", back
+ return back;
+}
+#endif
+
+
+
+/** Calculate length correction for normal arrows.
+ @param drw Drawing structure.
+ @param obj Object to modify.
+ @param ah Arrowhead to calculate length correction for.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Length correction value.
+*/
+static
+double
+dk3figah_normal_arrow_length_correction(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec
+)
+{
+ double back = 0.0;
+ double cmin;
+ double s;
+ $? "+ dk3figah_normal_arrow_length_correction"
+ cmin = dk3figah_cmin(drw, obj, ah, ec);
+ s = dk3figah_s(drw, obj, ah, ec);
+ switch(obj->cs) {
+ case DK3_FIG_LC_PROJECTING:
+ case DK3_FIG_LC_ROUND: {
+ back = dk3ma_d_add_ok(
+ dk3ma_d_mul_ok(1.5, s, ec),
+ (0.5 * cmin),
+ ec
+ );
+ } break;
+ default: {
+ back = dk3ma_d_add_ok(s, (0.5 * cmin), ec);
+ } break;
+ } $? "- dk3figah_normal_arrow_length_correction %lg", back
+ return back;
+}
+
+
+
+
+/** Calculate length correction tolerance for normal arrows.
+ @param drw Drawing structure.
+ @param obj Object to modify.
+ @param ah Arrowhead to calculate length correction for.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Length correction value.
+*/
+static
+double
+dk3figah_normal_arrow_length_correction_tolerance(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec
+)
+{
+ double back;
+ double cmin;
+ double s;
+ $? "+ dk3figah_normal_arrow_length_correction_tolerance"
+ cmin = dk3figah_cmin(drw, obj, ah, ec);
+ s = dk3figah_s(drw, obj, ah, ec);
+ switch(obj->cs) {
+ case DK3_FIG_LC_PROJECTING:
+ case DK3_FIG_LC_ROUND: {
+ back = 0.25 * dk3ma_d_sub_ok(s, cmin, ec);
+ } break;
+ default: {
+ back = dk3ma_d_sub_ok((0.5 * s), (0.25 * cmin), ec);
+ } break;
+ } $? "- dk3figah_normal_arrow_length_correction_tolerance %lg", back
+ return back;
+}
+
+
+
+/** Calculate length correction for blocking line arrowhead.
+ @param drw Drawing structure.
+ @param obj Object to modify.
+ @param ah Arrowhead to calculate length correction for.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Length correction value.
+*/
+static
+double
+dk3figah_block_line_length_correction(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec
+)
+{
+ double back = 0.0;
+ $? "+ dk3figah_block_line_length_correction"
+ switch(obj->cs) {
+ case DK3_FIG_LC_PROJECTING:
+ case DK3_FIG_LC_ROUND: {
+ back = 0.75 * dk3fig_tool_get_lw(drw, obj, ec);
+ } break;
+ default: {
+ back = 0.5 * dk3fig_tool_get_lw(drw, obj, ec);
+ } break;
+ } $? "- dk3figah_block_line_length_correction %lg", back
+ return back;
+}
+
+
+
+/** Calculate length correction tolerance for blocking line arrowhead.
+ @param drw Drawing structure.
+ @param obj Object to modify.
+ @param ah Arrowhead to calculate length correction for.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Length correction value.
+*/
+static
+double
+dk3figah_block_line_length_correction_tolerance(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec
+)
+{
+ double back = 0.0;
+ $? "+ dk3figah_block_line_length_correction_tolerance"
+ switch(obj->cs) {
+ case DK3_FIG_LC_PROJECTING:
+ case DK3_FIG_LC_ROUND: {
+ back = 0.125 * dk3fig_tool_get_lw(drw, obj, ec);
+ } break;
+ default: {
+ back = 0.25 * dk3fig_tool_get_lw(drw, obj, ec);
+ } break;
+ } $? "- dk3figah_block_line_length_correction_tolerance %lg", back
+ return back;
+}
+
+
+
+/** Length correction for inverted open arrow.
+ @param drw Drawing structure.
+ @param obj Object to modify.
+ @param ah Arrowhead to calculate length correction for.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Length correction value.
+*/
+static
+double
+dk3figah_anti_arrow_length_correction(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec
+)
+{
+ double back;
+ double sqv;
+ double lw;
+ double cmin;
+ double cmax;
+ $? "+ dk3figah_anti_arrow_length_correction"
+ lw = dk3fig_tool_get_lw(drw, obj, ec);
+ sqv = sqrt(
+ dk3ma_d_add_ok(
+ dk3ma_d_square_ok(ah->wi, ec),
+ dk3ma_d_mul_ok(
+ 4.0,
+ dk3ma_d_square_ok(ah->he, ec),
+ ec
+ ),
+ ec
+ )
+ );
+ sqv = dk3ma_d_div_ok(
+ dk3ma_d_mul_ok(lw, sqv, ec),
+ dk3ma_d_mul_ok(2.0, ah->wi, ec),
+ ec
+ );
+ cmin = dk3ma_d_sub_ok(ah->he, sqv, ec);
+ cmax = dk3ma_d_sub_ok(
+ dk3ma_d_add_ok(ah->he, sqv, ec),
+ dk3ma_d_div_ok(
+ dk3ma_d_mul_ok(lw, ah->he, ec),
+ ah->wi,
+ ec
+ ),
+ ec
+ );
+ switch(obj->cs) {
+ case DK3_FIG_LC_PROJECTING: case DK3_FIG_LC_ROUND: {
+ sqv = dk3ma_d_sub_ok(
+ dk3ma_d_sub_ok(cmax, cmin, ec),
+ (0.5 * lw),
+ ec
+ );
+ back = dk3ma_d_sub_ok(
+ cmax,
+ (0.5 * sqv),
+ ec
+ );
+ } break;
+ default: {
+ back = 0.5 * dk3ma_d_add_ok(cmin, cmax, ec);
+ } break;
+ } $? "- dk3figah_anti_arrow_length_correction %lg", back
+ return back;
+}
+
+
+
+/** Length correction tolerance for inverted open arrow.
+ @param drw Drawing structure.
+ @param obj Object to modify.
+ @param ah Arrowhead to calculate length correction for.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Length correction value.
+*/
+static
+double
+dk3figah_anti_arrow_length_correction_tolerance(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec
+)
+{
+ double back;
+ double sqv;
+ double lw;
+ double cmin;
+ double cmax;
+ $? "+ dk3figah_anti_arrow_length_correction_tolerance"
+ lw = dk3fig_tool_get_lw(drw, obj, ec);
+ sqv = sqrt(
+ dk3ma_d_add_ok(
+ dk3ma_d_square_ok(ah->wi, ec),
+ dk3ma_d_mul_ok(
+ 4.0,
+ dk3ma_d_square_ok(ah->he, ec),
+ ec
+ ),
+ ec
+ )
+ );
+ sqv = dk3ma_d_div_ok(
+ dk3ma_d_mul_ok(lw, sqv, ec),
+ dk3ma_d_mul_ok(2.0, ah->wi, ec),
+ ec
+ );
+ cmin = dk3ma_d_sub_ok(ah->he, sqv, ec);
+ cmax = dk3ma_d_sub_ok(
+ dk3ma_d_add_ok(ah->he, sqv, ec),
+ dk3ma_d_div_ok(
+ dk3ma_d_mul_ok(lw, ah->he, ec),
+ ah->wi,
+ ec
+ ),
+ ec
+ );
+ switch(obj->cs) {
+ case DK3_FIG_LC_PROJECTING: case DK3_FIG_LC_ROUND: {
+ back = 0.25 * dk3ma_d_sub_ok(
+ dk3ma_d_sub_ok(cmax, cmin, ec),
+ (0.5 * lw),
+ ec
+ );
+ } break;
+ default: {
+ back = 0.25 * dk3ma_d_sub_ok(cmax, cmin, ec);
+ } break;
+ } $? "- dk3figah_anti_arrow_length_correction_tolerance %lg", back
+ return back;
+}
+
+
+
+/** Length correction for full circle arrowhead.
+ @param drw Drawing structure.
+ @param obj Object to modify.
+ @param ah Arrowhead to calculate length correction for.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Length correction value.
+*/
+static
+double
+dk3figah_full_circle_length_correction(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec
+)
+{
+ double back;
+ double lw;
+ double cmin;
+ double cmax;
+ $? "+ dk3figah_full_circle_length_correction"
+ lw = dk3fig_tool_get_lw(drw, obj, ec);
+ cmin = 0.5 * dk3ma_d_mul_ok(
+ dk3ma_d_add_ok(ah->he, lw, ec),
+ dk3ma_d_sub_ok(
+ 1.0,
+ sqrt(
+ dk3ma_d_sub_ok(
+ 1.0,
+ dk3ma_d_square_ok(
+ dk3ma_d_div_ok(
+ lw,
+ dk3ma_d_add_ok(lw, ah->he, ec),
+ ec
+ ),
+ ec
+ ),
+ ec
+ )
+ ),
+ ec
+ ),
+ ec
+ );
+ cmax = lw;
+ switch(obj->cs) {
+ case DK3_FIG_LC_PROJECTING: case DK3_FIG_LC_ROUND: {
+ back = dk3ma_d_sub_ok(
+ cmax,
+ (0.5 * dk3ma_d_sub_ok(dk3ma_d_sub_ok(cmax, cmin, ec), (0.5 * lw), ec)),
+ ec
+ );
+ } break;
+ default: {
+ back = 0.5 * dk3ma_d_add_ok(cmax, cmin, ec);
+ } break;
+ } $? "- dk3figah_full_circle_length_correction %lg", back
+ return back;
+}
+
+
+
+/** Length correction tolerance for full circle arrowhead.
+ @param drw Drawing structure.
+ @param obj Object to modify.
+ @param ah Arrowhead to calculate length correction for.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Length correction value.
+*/
+static
+double
+dk3figah_full_circle_length_correction_tolerance(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec
+)
+{
+ double back;
+ double lw;
+ double cmin;
+ double cmax;
+ $? "+ dk3figah_full_circle_length_correction_tolerance"
+ lw = dk3fig_tool_get_lw(drw, obj, ec);
+ cmin = 0.5 * dk3ma_d_mul_ok(
+ dk3ma_d_add_ok(ah->he, lw, ec),
+ dk3ma_d_sub_ok(
+ 1.0,
+ sqrt(
+ dk3ma_d_sub_ok(
+ 1.0,
+ dk3ma_d_square_ok(
+ dk3ma_d_div_ok(
+ lw,
+ dk3ma_d_add_ok(lw, ah->he, ec),
+ ec
+ ),
+ ec
+ ),
+ ec
+ )
+ ),
+ ec
+ ),
+ ec
+ );
+ cmax = lw;
+ switch(obj->cs) {
+ case DK3_FIG_LC_PROJECTING: case DK3_FIG_LC_ROUND: {
+ back = 0.25 * dk3ma_d_sub_ok(
+ dk3ma_d_sub_ok(cmax, cmin, ec),
+ (0.5 * lw),
+ ec
+ );
+ } break;
+ default: {
+ back = 0.25 * dk3ma_d_sub_ok(cmax, cmin, ec);
+ } break;
+ } $? "- dk3figah_full_circle_length_correction_tolerance %lg", back
+ return back;
+}
+
+
+
+/** Length correction for half circle arrowhead.
+ @param drw Drawing structure.
+ @param obj Object to modify.
+ @param ah Arrowhead to calculate length correction for.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Length correction value.
+*/
+static
+double
+dk3figah_half_circle_length_correction(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec
+)
+{
+ double back;
+ double lw;
+#if VERSION_BEFORE_20150821
+ double cmin;
+ double cmax;
+#endif
+ $? "+ dk3figah_half_circle_length_correction"
+ lw = dk3fig_tool_get_lw(drw, obj, ec);
+#if VERSION_BEFORE_20150821
+ cmin = dk3ma_d_sub_ok(
+ (0.5 * ah->he),
+ (0.5 * lw),
+ ec
+ );
+ cmax = dk3ma_d_add_ok(
+ (0.5 * ah->he),
+ (0.5 * lw),
+ ec
+ );
+#endif
+ switch(obj->cs) {
+ case DK3_FIG_LC_PROJECTING: case DK3_FIG_LC_ROUND: {
+ back = dk3ma_d_add_ok(
+ (0.5 * ah->he),
+ (0.25 * lw),
+ ec
+ );
+ } break;
+ default: {
+ back = 0.5 * ah->he;
+ } break;
+ } $? "- dk3figah_half_circle_length_correction %lg", back
+ return back;
+}
+
+
+
+
+#if VERSION_BEFORE_20121215
+/** Length correction for half-arrow arrowhead.
+ @param drw Drawing structure.
+ @param obj Object to modify.
+ @param ah Arrowhead to calculate length correction for.
+ @param ec Pointer to error code variable, may be NULL.
+ @param incr Flag: Increase (1=increase, 0=no op, -1=decrease).
+ @return Length correction value.
+*/
+static
+double
+dk3figah_half_arrow_length_correction(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec,
+ int incr
+)
+{
+ double back;
+ double lw;
+ double cmin;
+ double d;
+ double cmax;
+ $? "+ dk3figah_half_arrow_length_correction"
+ lw = dk3fig_tool_get_lw(drw, obj, ec);
+ cmin = dk3ma_d_div_ok(
+ dk3ma_d_mul_ok(
+ dk3ma_d_mul_ok(lw, ah->he, ec),
+ 2.0,
+ ec
+ ),
+ ah->wi,
+ ec
+ );
+ d = dk3ma_d_div_ok(
+ lw,
+ dk3ma_d_mul_ok(
+ 2.0,
+ tan(
+ 0.5 * atan(
+ dk3ma_d_div_ok(
+ ah->wi,
+ dk3ma_d_mul_ok(2.0, ah->he, ec),
+ ec
+ )
+ )
+ ),
+ ec
+ ),
+ ec
+ );
+ cmax = dk3ma_d_add_ok(d, (0.5 * lw), ec);
+ cmax = dk3ma_d_add_ok(
+ cmax,
+ dk3ma_d_mul_ok(
+ ((incr > 0) ? 1.25 : ((incr < 0) ? 0.75 : 1.0)),
+ ah->he,
+ ec
+ ),
+ ec
+ );
+ if(cmax > dk3ma_d_add_ok(cmin, lw, ec)) {
+ cmax = dk3ma_d_add_ok(cmin, lw, ec);
+ }
+ switch(obj->cs) {
+ case DK3_FIG_LC_PROJECTING: case DK3_FIG_LC_ROUND: {
+ back = dk3ma_d_sub_ok(
+ cmax,
+ (0.5 * dk3ma_d_sub_ok(dk3ma_d_sub_ok(cmax, cmin, ec), (0.5*lw), ec)),
+ ec
+ );
+ } break;
+ default: {
+ back = 0.5 * dk3ma_d_add_ok(cmax, cmin, ec);
+ } break;
+ } $? "- dk3figah_half_arrow_length_correction %lg", back
+ return back;
+}
+#else
+/** Length correction for half-arrow arrowhead.
+ @param drw Drawing structure.
+ @param obj Object to modify.
+ @param ah Arrowhead to calculate length correction for.
+ @param ec Pointer to error code variable, may be NULL.
+ @param incr Flag: Increase (1=increase, 0=no op, -1=decrease).
+ @return Length correction value.
+*/
+static
+double
+dk3figah_half_arrow_length_correction(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec,
+ int incr
+)
+{
+ double back;
+ double lw; /* Line width. */
+ double cmin; /* Minimum correction. */
+ double cmax; /* Maximum correction. */
+ double d; /* Shift value. */
+ double w; /* Arrowhead width. */
+ double h; /* Arrowhead height. */
+
+ $? "+ dk3figah_half_arrow_length_correction"
+ w = ah->wi;
+ h = ah->he;
+ switch(incr) {
+ case -1: { /* indented */
+ h = dk3ma_d_mul_ok(1.25, h, ec);
+ } break;
+ case 1: { /* butted */
+ h = 0.75 * h;
+ } break;
+ }
+ lw = dk3fig_tool_get_lw(drw, obj, ec);
+ $? ". w = %lg h = %lg l = %lg", w, h, lw
+ cmin = dk3ma_d_div_ok(
+ dk3ma_d_mul_ok(2.0, dk3ma_d_mul_ok(h, lw, ec), ec), w, ec
+ );
+ d = dk3ma_d_div_ok(
+ lw,
+ dk3ma_d_mul_ok(
+ 2.0,tan(0.5 * atan(dk3ma_d_div_ok(w, dk3ma_d_mul_ok(2.0, h, ec), ec))),ec
+ ),
+ ec
+ );
+ cmax = dk3ma_d_mul_ok(2.0, d, ec);
+ $? ". cmin = %lg cmax = %lg d = %lg", cmin, cmax, d
+ switch(obj->cs) {
+ case DK3_FIG_LC_PROJECTING: case DK3_FIG_LC_ROUND: {
+ back = dk3ma_d_sub_ok(
+ (0.5 * lw),
+ (0.5 * dk3ma_d_sub_ok(dk3ma_d_sub_ok(cmax, cmin, ec), (0.5*lw), ec)),
+ ec
+ );
+ } break;
+ default: {
+ back = 0.5 * dk3ma_d_add_ok(cmax, cmin, ec);
+ } break;
+ } $? "- dk3figah_half_arrow_length_correction %lg", back
+ return back;
+}
+#endif
+
+
+#if VERSION_BEFORE_20121215
+/** Length correction tolerance for half-arrow arrowhead.
+ @param drw Drawing structure.
+ @param obj Object to modify.
+ @param ah Arrowhead to calculate length correction for.
+ @param ec Pointer to error code variable, may be NULL.
+ @param incr Flag: Increase (1=increase, 0=no op, -1=decrease).
+ @return Length correction tolerance value.
+*/
+static
+double
+dk3figah_half_arrow_length_correction_tolerance(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec,
+ int incr
+)
+{
+ double back;
+ double lw;
+ double cmin;
+ double d;
+ double cmax;
+ $? "+ dk3figah_half_arrow_length_correction_tolerance"
+ lw = dk3fig_tool_get_lw(drw, obj, ec);
+ cmin = dk3ma_d_div_ok(
+ dk3ma_d_mul_ok(
+ dk3ma_d_mul_ok(lw, ah->he, ec),
+ 2.0,
+ ec
+ ),
+ ah->wi,
+ ec
+ );
+ d = dk3ma_d_div_ok(
+ lw,
+ dk3ma_d_mul_ok(
+ 2.0,
+ tan(
+ 0.5 * atan(
+ dk3ma_d_div_ok(
+ ah->wi,
+ dk3ma_d_mul_ok(2.0, ah->he, ec),
+ ec
+ )
+ )
+ ),
+ ec
+ ),
+ ec
+ );
+ cmax = dk3ma_d_add_ok(d, (0.5 * lw), ec);
+ cmax = dk3ma_d_add_ok(
+ cmax,
+ dk3ma_d_mul_ok(
+ ((incr > 0) ? 1.25 : ((incr < 0) ? 0.75 : 1.0)),
+ ah->he,
+ ec
+ ),
+ ec
+ );
+ if(cmax > dk3ma_d_add_ok(cmin, lw, ec)) {
+ cmax = dk3ma_d_add_ok(cmin, lw, ec);
+ }
+ switch(obj->cs) {
+ case DK3_FIG_LC_PROJECTING: case DK3_FIG_LC_ROUND: {
+ back = 0.25 * dk3ma_d_sub_ok(dk3ma_d_sub_ok(cmax,cmin,ec),(0.5 * lw),ec);
+ } break;
+ default: {
+ back = 0.25 * dk3ma_d_sub_ok(cmax, cmin, ec);
+ } break;
+ } $? "- dk3figah_half_arrow_length_correction_tolerance %lg", back
+ return back;
+}
+#else
+
+/** Length correction tolerance for half-arrow arrowhead.
+ @param drw Drawing structure.
+ @param obj Object to modify.
+ @param ah Arrowhead to calculate length correction for.
+ @param ec Pointer to error code variable, may be NULL.
+ @param incr Flag: Increase (1=increase, 0=no op, -1=decrease).
+ @return Length correction tolerance value.
+*/
+static
+double
+dk3figah_half_arrow_length_correction_tolerance(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec,
+ int incr
+)
+{
+ double back;
+ double lw; /* Line width. */
+ double cmin; /* Minimum correction. */
+ double cmax; /* Maximum correction. */
+ double d; /* Shift value. */
+ double w; /* Arrowhead width. */
+ double h; /* Arrowhead height. */
+
+ $? "+ dk3figah_half_arrow_length_correction"
+ w = ah->wi;
+ h = ah->he;
+ switch(incr) {
+ case -1: { /* indented */
+ h = dk3ma_d_mul_ok(1.25, h, ec);
+ } break;
+ case 1: { /* butted */
+ h = 0.75 * h;
+ } break;
+ }
+ lw = dk3fig_tool_get_lw(drw, obj, ec);
+ $? ". w = %lg h = %lg l = %lg", w, h, lw
+ cmin = dk3ma_d_div_ok(
+ dk3ma_d_mul_ok(2.0, dk3ma_d_mul_ok(h, lw, ec), ec), w, ec
+ );
+ d = dk3ma_d_div_ok(
+ lw,
+ dk3ma_d_mul_ok(
+ 2.0,tan(0.5 * atan(dk3ma_d_div_ok(w, dk3ma_d_mul_ok(2.0, h, ec), ec))),ec
+ ),
+ ec
+ );
+ cmax = dk3ma_d_mul_ok(2.0, d, ec);
+ $? ". cmin = %lg cmax = %lg d = %lg", cmin, cmax, d
+ back = 0.25 * fabs(dk3ma_d_sub_ok(cmax, cmin, ec));
+ $? "- dk3figah_half_arrow_length_correction_tolerance %lg", back
+ return back;
+}
+#endif
+
+
+
+/** Calculate length correction for arrowhead.
+ Amount to cut the original line.
+ @param drw Drawing.
+ @param obj Object to calculate arrowheads for.
+ @param ah Arrowhead data.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Length to cut from line.
+*/
+static
+double
+dk3figah_length_correction(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec
+)
+{
+ double back = 0.0;
+ $? "+ dk3figah_length_correction s=%d, f=%d, h=%lg, w=%lg", ah->as, ah->af, ah->he, ah->wi
+ switch(ah->as) {
+ case DK3_FIG_AS_RHOMBUS: { /* 4 */
+ if((1 == ah->af) && (DK3_FIG_SRCTYPE_JFIG == drw->srctype)) {
+ back = 0.0;
+ } else {
+ back = dk3figah_normal_arrow_length_correction(drw, obj, ah, ec);
+ }
+ } break;
+ case DK3_FIG_AS_FULL_CIRCLE_END: { /* 5 */
+ back = dk3figah_full_circle_length_correction(drw, obj, ah, ec);
+ } break;
+ case DK3_FIG_AS_RECTANGLE: /* 7 */
+ case DK3_FIG_AS_INVERSE: /* 8 */
+ {
+ back = dk3figah_block_line_length_correction(drw, obj, ah, ec);
+ } break;
+ case DK3_FIG_AS_HALF_CIRCLE_END: { /* 6 */
+ if(1 == ah->af) {
+ back = dk3figah_block_line_length_correction(drw, obj, ah, ec);
+ } else {
+ back = dk3figah_half_circle_length_correction(drw, obj, ah, ec);
+ }
+ } break;
+ case DK3_FIG_AS_CLOSED_HALF: { /* 10 */
+ back = dk3figah_half_arrow_length_correction(drw, obj, ah, ec, 0);
+ } break;
+ case DK3_FIG_AS_INDENTED_HALF: { /* 11 */
+ back = dk3figah_half_arrow_length_correction(drw, obj, ah, ec, -1);
+ } break;
+ case DK3_FIG_AS_BUTTED_HALF: { /* 12 */
+ back = dk3figah_half_arrow_length_correction(drw, obj, ah, ec, 1);
+ } break;
+ case DK3_FIG_AS_TRIANGLE_FORK: { /* 13 */
+ if(1 == ah->af) {
+ back = dk3figah_block_line_length_correction(drw, obj, ah, ec);
+ } else {
+ back = dk3figah_anti_arrow_length_correction(drw, obj, ah, ec);
+ }
+ } break;
+ case DK3_FIG_AS_RECTANGLE_FORK: { /* 14 */
+ if(1 == ah->af) {
+ back = dk3figah_block_line_length_correction(drw, obj, ah, ec);
+ } else {
+#if 0
+ back = dk3figah_block_line_length_correction(drw, obj, ah, ec);
+#endif
+ back = dk3ma_d_add_ok(back, ah->he, ec); $? ". open block"
+ }
+ } break;
+ default: {
+ back = dk3figah_normal_arrow_length_correction(drw, obj, ah, ec);
+ } break;
+ } $? "- dk3figah_length_correction %lg", back
+ return back;
+}
+
+
+
+/** Calculate length correction tolerance for arrowhead.
+ @param drw Drawing.
+ @param obj Object to calculate arrowheads for.
+ @param ah Arrowhead data.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Tolerance for length to cut from line.
+*/
+static
+double
+dk3figah_length_correction_tolerance(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec
+)
+{
+ double back;
+ $? "+ dk3figah_length_correction_tolerance"
+ switch(ah->as) {
+ case DK3_FIG_AS_RHOMBUS: { /* 4 */
+ if((1 == ah->af) && (DK3_FIG_SRCTYPE_JFIG == drw->srctype)) {
+ back = 0.0;
+ } else {
+ back = dk3figah_normal_arrow_length_correction_tolerance(drw,obj,ah,ec);
+ }
+ } break;
+ case DK3_FIG_AS_FULL_CIRCLE_END: { /* 5 */
+ back = dk3figah_full_circle_length_correction_tolerance(drw,obj,ah,ec);
+ } break;
+ case DK3_FIG_AS_RECTANGLE: /* 7 */
+ case DK3_FIG_AS_INVERSE: /* 8 */
+ {
+ back = dk3figah_block_line_length_correction_tolerance(drw,obj,ah,ec);
+ } break;
+ case DK3_FIG_AS_HALF_CIRCLE_END: { /* 6 */
+ back = dk3figah_block_line_length_correction_tolerance(drw,obj,ah,ec);
+ } break;
+ case DK3_FIG_AS_CLOSED_HALF: { /* 10 */
+ back = dk3figah_half_arrow_length_correction_tolerance(drw,obj,ah,ec,0);
+ } break;
+ case DK3_FIG_AS_INDENTED_HALF: { /* 11 */
+ back = dk3figah_half_arrow_length_correction_tolerance(drw,obj,ah,ec,-1);
+ } break;
+ case DK3_FIG_AS_BUTTED_HALF: { /* 12 */
+ back = dk3figah_half_arrow_length_correction_tolerance(drw,obj,ah,ec,1);
+ } break;
+ case DK3_FIG_AS_TRIANGLE_FORK: { /* 13 */
+ if(1 == ah->af) {
+ back = dk3figah_block_line_length_correction_tolerance(drw,obj,ah,ec);
+ } else {
+ back = dk3figah_anti_arrow_length_correction_tolerance(drw,obj,ah,ec);
+ }
+ } break;
+ case DK3_FIG_AS_RECTANGLE_FORK: { /* 14 */
+ back = dk3figah_block_line_length_correction_tolerance(drw,obj,ah,ec);
+ } break;
+ default: {
+ back = dk3figah_normal_arrow_length_correction_tolerance(drw,obj,ah,ec);
+ } break;
+ } $? "- dk3figah_length_correction_tolerance %lg", back
+ return back;
+}
+
+
+
+int
+dk3figah_candidate(dk3_fig_obj_t *obj)
+{
+ int back = 0;
+ $? "+ dk3figah_candidate"
+ if(obj) {
+ switch(obj->ot) {
+ case DK3_FIG_OBJ_POLYLINE: {
+ switch(obj->st) {
+ case 1: { back = 1; } break;
+ }
+ } break;
+ case DK3_FIG_OBJ_SPLINE: {
+ switch(obj->st) {
+ case 0: case 2: case 4: { back = 1; } break;
+ }
+ } break;
+ case DK3_FIG_OBJ_ARC: {
+ switch(obj->st) {
+ case 1: { back = 1; } break;
+ }
+ } break;
+ }
+ if(back) {
+ if(!((obj->af) || (obj->ab))) {
+ back = 0;
+ }
+ }
+ } $? "- dk3figah_candidate %d", back
+ return back;
+}
+
+
+
+/** Find distance to shift arrowhead polygon point from end point.
+ @param drw Drawing structure.
+ @param obj Object containing the arrowhead.
+ @param ah Arrowhead.
+ @param ec Pointer to error code variable.
+ @return Non-negative distance on success, negative value on error.
+*/
+static
+double
+dk3figah_find_shift_length(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int *ec
+)
+{
+ double back = 0.0;
+ $? "+ dk3figah_find_shift_length"
+ switch(ah->as) {
+ case DK3_FIG_AS_TRIANGLE_FORK: {
+ if(ah->af) {
+ back = 0.5 * dk3fig_tool_get_lw(drw, obj, ec);
+ } else {
+ }
+ } break;
+ case DK3_FIG_AS_RECTANGLE_FORK: {
+ if(ah->af) {
+ back = 0.5 * dk3fig_tool_get_lw(drw, obj, ec);
+ }
+ } break;
+ case DK3_FIG_AS_FULL_CIRCLE_END:
+ case DK3_FIG_AS_HALF_CIRCLE_END:
+ case DK3_FIG_AS_RECTANGLE:
+ case DK3_FIG_AS_INVERSE:
+ {
+ back = 0.5 * dk3fig_tool_get_lw(drw, obj, ec);
+ } break;
+ case DK3_FIG_AS_INDENTED_FILLED_HALF:
+ case DK3_FIG_AS_STICK:
+ case DK3_FIG_AS_CLOSED:
+ case DK3_FIG_AS_INDENTED:
+ case DK3_FIG_AS_POINTED:
+ case DK3_FIG_AS_RHOMBUS:
+ {
+ back = dk3figah_s(drw, obj, ah, ec);
+ } break;
+ case DK3_FIG_AS_CLOSED_HALF:
+ case DK3_FIG_AS_INDENTED_HALF:
+ case DK3_FIG_AS_BUTTED_HALF: {
+ back = dk3figah_half_arrow_s(drw, obj, ah, ec);
+ } break;
+ } $? "- dk3figah_find_shift_length %lg", back
+ return back;
+}
+
+
+
+/** Arrowhead for polylines or compatible arrowheads.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param ah Arrowhead to modify.
+ @param ep Endpoint of the arrowhead.
+ @param rotation Arrowhead direction in radians.
+ @param ec Pointer to error code variable.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figah_straight_arrowhead(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ dk3_fig_poly_point_t *ep,
+ double rotation,
+ int *ec
+)
+{
+ dk3_fig_poly_point_t aep;
+ dk3_fig_poly_point_t po[8];
+ double s; /* Shifting the first point */
+ size_t i;
+ int back = 0;
+ $? "+ dk3figah_straight_arrowhead"
+ dk3mem_cpy((void *)(&aep), (void *)ep, sizeof(dk3_fig_poly_point_t));
+ switch(ah->as) {
+ case DK3_FIG_AS_STICK: {
+ if(!(drw->coah)) {
+ s = dk3figah_s(drw, obj, ah, ec);
+ aep.x = dk3ma_d_sub_ok(aep.x, (s * cos(rotation)), ec);
+ aep.y = dk3ma_d_sub_ok(aep.y, (s * sin(rotation)), ec);
+ }
+ po[0].x = -1.0 * ah->he;
+ po[0].y = 0.5 * ah->wi;
+ po[1].x = 0.0;
+ po[1].y = 0.0;
+ po[2].x = po[0].x;
+ po[2].y = -0.5 * ah->wi;
+ for(i = 0; i < 3; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), rotation, ec);
+ dk3fig_tool_shift_point(&(po[i]), aep.x, aep.y, ec);
+ }
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 1, /* Object type, subtype */
+ obj->lw, obj->pc, obj->pc, -1, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 3, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ if(ah->o1) {
+ if((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po) {
+ dk3mem_cpy(
+ (void *)((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po),
+ (void *)po,
+ (3 * sizeof(dk3_fig_poly_point_t))
+ );
+ back = 1;
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } break;
+ case DK3_FIG_AS_CLOSED: {
+ if(!(drw->coah)) {
+ s = dk3figah_s(drw, obj, ah, ec);
+ aep.x = dk3ma_d_sub_ok(aep.x, (s * cos(rotation)), ec);
+ aep.y = dk3ma_d_sub_ok(aep.y, (s * sin(rotation)), ec);
+ }
+ po[0].x = -1.0 * ah->he;
+ po[0].y = 0.5 * ah->wi;
+ po[1].x = 0.0;
+ po[1].y = 0.0;
+ po[2].x = po[0].x;
+ po[2].y = -0.5 * ah->wi;
+ for(i = 0; i < 3; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), rotation, ec);
+ dk3fig_tool_shift_point(&(po[i]), aep.x, aep.y, ec);
+ }
+ if(ah->af) {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, obj->pc, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 3, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ } else {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, 7, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 3, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ }
+ if(ah->o1) {
+ if((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po) {
+ dk3mem_cpy(
+ (void *)((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po),
+ (void *)po,
+ (3 * sizeof(dk3_fig_poly_point_t))
+ );
+ back = 1;
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } break;
+ case DK3_FIG_AS_INDENTED: {
+ if(!(drw->coah)) {
+ s = dk3figah_s(drw, obj, ah, ec);
+ aep.x = dk3ma_d_sub_ok(aep.x, (s * cos(rotation)), ec);
+ aep.y = dk3ma_d_sub_ok(aep.y, (s * sin(rotation)), ec);
+ }
+ po[0].x = dk3ma_d_mul_ok(-1.25, ah->he, ec);
+ po[0].y = 0.5 * ah->wi;
+ po[1].x = 0.0;
+ po[1].y = 0.0;
+ po[2].x = po[0].x;
+ po[2].y = -0.5 * ah->wi;
+ po[3].x = -1.0 * ah->he;
+ po[3].y = 0.0;
+ for(i = 0; i < 4; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), rotation, ec);
+ dk3fig_tool_shift_point(&(po[i]), aep.x, aep.y, ec);
+ }
+ if(ah->af) {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, obj->pc, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 4, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ } else {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, 7, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 4, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ }
+ if(ah->o1) {
+ if((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po) {
+ dk3mem_cpy(
+ (void *)((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po),
+ (void *)po,
+ (4 * sizeof(dk3_fig_poly_point_t))
+ );
+ back = 1;
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } break;
+ case DK3_FIG_AS_POINTED: {
+ if(!(drw->coah)) {
+ s = dk3figah_s(drw, obj, ah, ec);
+ aep.x = dk3ma_d_sub_ok(aep.x, (s * cos(rotation)), ec);
+ aep.y = dk3ma_d_sub_ok(aep.y, (s * sin(rotation)), ec);
+ }
+ po[0].x = -0.75 * ah->he;
+ po[0].y = 0.5 * ah->wi;
+ po[1].x = 0.0;
+ po[1].y = 0.0;
+ po[2].x = po[0].x;
+ po[2].y = -0.5 * ah->wi;
+ po[3].x = -1.0 * ah->he;
+ po[3].y = 0.0;
+ for(i = 0; i < 4; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), rotation, ec);
+ dk3fig_tool_shift_point(&(po[i]), aep.x, aep.y, ec);
+ }
+ if(ah->af) {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, obj->pc, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 4, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ } else {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, 7, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 4, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ }
+ if(ah->o1) {
+ if((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po) {
+ dk3mem_cpy(
+ (void *)((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po),
+ (void *)po,
+ (4 * sizeof(dk3_fig_poly_point_t))
+ );
+ back = 1;
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } break;
+ case DK3_FIG_AS_RHOMBUS: {
+ if((DK3_FIG_SRCTYPE_JFIG == drw->srctype) && (ah->af)) {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_ELLIPSE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, obj->pc, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 0, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ if(ah->o1) {
+ (((dk3_fig_obj_t *)(ah->o1))->dt).ell.an = 0.0;
+ (((dk3_fig_obj_t *)(ah->o1))->dt).ell.cx = aep.x;
+ (((dk3_fig_obj_t *)(ah->o1))->dt).ell.cy = aep.y;
+ (((dk3_fig_obj_t *)(ah->o1))->dt).ell.rx = ah->he;
+ (((dk3_fig_obj_t *)(ah->o1))->dt).ell.ry = ah->he;
+ back = 1;
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } else {
+ if(!(drw->coah)) {
+ s = dk3figah_s(drw, obj, ah, ec);
+ aep.x = dk3ma_d_sub_ok(aep.x, (s * cos(rotation)), ec);
+ aep.y = dk3ma_d_sub_ok(aep.y, (s * sin(rotation)), ec);
+ }
+ po[0].x = -1.0 * ah->he;
+ po[0].y = 0.0;
+ po[1].x = -0.5 * ah->he;
+ po[1].y = 0.5 * ah->wi;
+ po[2].x = 0.0;
+ po[2].y = 0.0;
+ po[3].x = -0.5 * ah->he;
+ po[3].y = -0.5 * ah->wi;
+ for(i = 0; i < 4; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), rotation, ec);
+ dk3fig_tool_shift_point(&(po[i]), aep.x, aep.y, ec);
+ }
+ if(ah->af) {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, obj->pc, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 4, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ } else {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, 7, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 4, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ }
+ if(ah->o1) {
+ if((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po) {
+ dk3mem_cpy(
+ (void *)((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po),
+ (void *)po,
+ (4 * sizeof(dk3_fig_poly_point_t))
+ );
+ back = 1;
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ }
+ } break;
+ case DK3_FIG_AS_FULL_CIRCLE_END: {
+ s = 0.5 * dk3fig_tool_get_lw(drw, obj, ec);
+ aep.x = dk3ma_d_sub_ok(aep.x, (0.5 * ah->he * cos(rotation)), ec);
+ aep.y = dk3ma_d_sub_ok(aep.y, (0.5 * ah->he * sin(rotation)), ec);
+ if(!(drw->coah)) {
+ aep.x = dk3ma_d_sub_ok(aep.x, (s * cos(rotation)), ec);
+ aep.y = dk3ma_d_sub_ok(aep.y, (s * sin(rotation)), ec);
+ }
+ if(ah->af) {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_ELLIPSE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, obj->pc, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 0, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ } else {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_ELLIPSE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, 7, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 0, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ }
+ if(ah->o1) {
+ (((dk3_fig_obj_t *)(ah->o1))->dt).ell.an = 0.0;
+ (((dk3_fig_obj_t *)(ah->o1))->dt).ell.cx = aep.x;
+ (((dk3_fig_obj_t *)(ah->o1))->dt).ell.cy = aep.y;
+ (((dk3_fig_obj_t *)(ah->o1))->dt).ell.rx = 0.5 * ah->he;
+ (((dk3_fig_obj_t *)(ah->o1))->dt).ell.ry = 0.5 * ah->he;
+ back = 1;
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } break;
+ case DK3_FIG_AS_HALF_CIRCLE_END: {
+ if(ah->af) {
+ if(!(drw->coah)) {
+ s = 0.5 * dk3fig_tool_get_lw(drw, obj, ec);
+ aep.x = dk3ma_d_sub_ok(aep.x, (s * cos(rotation)), ec);
+ aep.y = dk3ma_d_sub_ok(aep.y, (s * sin(rotation)), ec);
+ }
+ }
+ if(ah->af) {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_PSEUDO_HALF_CIRCLE, 1, /* Object type, subtype */
+ obj->lw, obj->pc, obj->pc, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 0, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ } else {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_PSEUDO_HALF_CIRCLE, 0, /* Object type, subtype */
+ obj->lw, obj->pc, 7, -1, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 0, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ }
+ if(ah->o1) { $? ". object creation succeeded"
+ (((dk3_fig_obj_t *)(ah->o1))->dt).hci.cx = aep.x;
+ (((dk3_fig_obj_t *)(ah->o1))->dt).hci.cy = aep.y;
+ (((dk3_fig_obj_t *)(ah->o1))->dt).hci.ra = 0.5 * ah->he;
+ (((dk3_fig_obj_t *)(ah->o1))->dt).hci.an = rotation;
+ back = 1;
+ } else { $? "! object creation failed"
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } break;
+ case DK3_FIG_AS_RECTANGLE: {
+ if(!(drw->coah)) {
+ s = 0.5 * dk3fig_tool_get_lw(drw, obj, ec);
+ aep.x = dk3ma_d_sub_ok(aep.x, (s * cos(rotation)), ec);
+ aep.y = dk3ma_d_sub_ok(aep.y, (s * sin(rotation)), ec);
+ }
+ po[0].x = -1.0 * ah->he;
+ po[0].y = 0.5 * ah->wi;
+ po[1].x = 0.0;
+ po[1].y = po[0].y;
+ po[2].x = 0.0;
+ po[2].y = -0.5 * ah->wi;
+ po[3].x = po[0].x;
+ po[3].y = po[2].y;
+ for(i = 0; i < 4; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), rotation, ec);
+ dk3fig_tool_shift_point(&(po[i]), aep.x, aep.y, ec);
+ }
+ if(ah->af) {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, obj->pc, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 4, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ } else {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, 7, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 4, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ }
+ if(ah->o1) {
+ if((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po) {
+ dk3mem_cpy(
+ (void *)((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po),
+ po,
+ (4 * sizeof(dk3_fig_poly_point_t))
+ );
+ (((dk3_fig_obj_t *)(ah->o1))->dt).pol.np = 4;
+ back = 1;
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } break;
+ case DK3_FIG_AS_INVERSE: {
+ if(!(drw->coah)) {
+ s = 0.5 * dk3fig_tool_get_lw(drw, obj, ec);
+ aep.x = dk3ma_d_sub_ok(aep.x, (s * cos(rotation)), ec);
+ aep.y = dk3ma_d_sub_ok(aep.y, (s * sin(rotation)), ec);
+ }
+ po[0].x = -1.0 * ah->he;
+ po[0].y = 0.0;
+ po[1].x = 0.0;
+ po[1].y = 0.5 * ah->wi;
+ po[2].x = 0.0;
+ po[2].y = -0.5 * ah->wi;
+ for(i = 0; i < 3; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), rotation, ec);
+ dk3fig_tool_shift_point(&(po[i]), aep.x, aep.y, ec);
+ }
+ if(ah->af) {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, obj->pc, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 3, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ } else {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, 7, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 3, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ }
+ if(ah->o1) {
+ if((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po) {
+ dk3mem_cpy(
+ (void *)((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po),
+ po,
+ (3 * sizeof(dk3_fig_poly_point_t))
+ );
+ (((dk3_fig_obj_t *)(ah->o1))->dt).pol.np = 3;
+ back = 1;
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } break;
+ case DK3_FIG_AS_INDENTED_FILLED_HALF: {
+#if 0
+ s = 0.0;
+ if(!(drw->coah)) {
+ s = dk3figah_s(drw, obj, ah, ec);
+ aep.x = dk3ma_d_sub_ok(aep.x, (s * cos(rotation)), ec);
+ aep.y = dk3ma_d_sub_ok(aep.y, (s * sin(rotation)), ec);
+ }
+ po[0].x = -1.0 * ah->he;
+ po[0].y = 0.0;
+ po[1].x = -1.25 * ah->he;
+ if(ah->af) {
+ po[1].y = 0.5 * ah->wi;
+ } else {
+ po[1].y = -0.5 * ah->wi;
+ }
+ po[2].x = 0.0;
+ po[2].y = 0.0;
+ po[3].x = po[1].x;
+ if(ah->af) {
+ po[3].y = -0.5 * ah->wi;
+ } else {
+ po[3].y = 0.5 * ah->wi;
+ }
+ for(i = 0; i < 4; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), rotation, ec);
+ dk3fig_tool_shift_point(&(po[i]), aep.x, aep.y, ec);
+ }
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, 7, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 4, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ if(ah->o1) {
+ if((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po) {
+ dk3mem_cpy(
+ (void *)((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po),
+ po,
+ (4 * sizeof(dk3_fig_poly_point_t))
+ );
+ (((dk3_fig_obj_t *)(ah->o1))->dt).pol.np = 4;
+ ah->o2 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, obj->pc, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 3, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ if(ah->o2) {
+ if((((dk3_fig_obj_t *)(ah->o2))->dt).pol.po) {
+ dk3mem_cpy(
+ (void *)((((dk3_fig_obj_t *)(ah->o2))->dt).pol.po),
+ po,
+ (3 * sizeof(dk3_fig_poly_point_t))
+ );
+ (((dk3_fig_obj_t *)(ah->o2))->dt).pol.np = 3;
+ back = 1;
+ }
+ }
+ }
+ }
+#else
+ if(!(drw->coah)) {
+ s = dk3figah_s(drw, obj, ah, ec);
+ aep.x = dk3ma_d_sub_ok(aep.x, (s * cos(rotation)), ec);
+ aep.y = dk3ma_d_sub_ok(aep.y, (s * sin(rotation)), ec);
+ }
+ po[0].x = -1.0 * ah->he;
+ po[0].y = 0.0;
+ po[1].x = dk3ma_d_mul_ok(-1.25, ah->he, ec);
+ if(ah->af) {
+ po[1].y = 0.5 * ah->wi;
+ } else {
+ po[1].y = -0.5 * ah->wi;
+ }
+ po[2].x = 0.0;
+ po[2].y = 0.0;
+ po[3].x = dk3ma_d_mul_ok(-1.25, ah->he, ec);
+ if(ah->af) {
+ po[3].y = -0.5 * ah->wi;
+ } else {
+ po[3].y = 0.5 * ah->wi;
+ }
+ for(i = 0; i < 4; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), rotation, ec);
+ dk3fig_tool_shift_point(&(po[i]), aep.x, aep.y, ec);
+ }
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, 7, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 4, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ if(ah->o1) {
+ if((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po) {
+ dk3mem_cpy(
+ (void *)((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po),
+ (void *)po,
+ (4 * sizeof(dk3_fig_poly_point_t))
+ );
+ (((dk3_fig_obj_t *)(ah->o1))->dt).pol.np = 4;
+ ah->o2 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ 0, obj->pc, obj->pc, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 3, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ if(ah->o2) {
+ if((((dk3_fig_obj_t *)(ah->o2))->dt).pol.po) {
+ dk3mem_cpy(
+ (void *)((((dk3_fig_obj_t *)(ah->o2))->dt).pol.po),
+ (void *)po,
+ (3 * sizeof(dk3_fig_poly_point_t))
+ );
+ (((dk3_fig_obj_t *)(ah->o2))->dt).pol.np = 3;
+ back = 1;
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+#endif
+ } break;
+ case DK3_FIG_AS_CLOSED_HALF: {
+ if(!(drw->coah)) {
+ s = dk3figah_s(drw, obj, ah, ec);
+ aep.x = dk3ma_d_sub_ok(aep.x, (s * cos(rotation)), ec);
+ aep.y = dk3ma_d_sub_ok(aep.y, (s * sin(rotation)), ec);
+ }
+ po[0].x = -1.0 * ah->he;
+ po[0].y = 0.0;
+ po[1].x = -1.0 * ah->he;
+ po[1].y = 0.5 * ah->wi;
+ po[2].x = 0.0;
+ po[2].y = 0.0;
+ for(i = 0; i < 3; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), rotation, ec);
+ dk3fig_tool_shift_point(&(po[i]), aep.x, aep.y, ec);
+ }
+ if(ah->af) {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, obj->pc, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 3, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ } else {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, 7, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 3, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ }
+ if(ah->o1) {
+ if((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po) {
+ dk3mem_cpy(
+ (void *)((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po),
+ po,
+ (3 * sizeof(dk3_fig_poly_point_t))
+ );
+ (((dk3_fig_obj_t *)(ah->o1))->dt).pol.np = 3;
+ back = 1;
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } break;
+ case DK3_FIG_AS_INDENTED_HALF: {
+ if(!(drw->coah)) {
+ s = dk3figah_s(drw, obj, ah, ec);
+ aep.x = dk3ma_d_sub_ok(aep.x, (s * cos(rotation)), ec);
+ aep.y = dk3ma_d_sub_ok(aep.y, (s * sin(rotation)), ec);
+ }
+ po[0].x = -1.0 * ah->he;
+ po[0].y = 0.0;
+ po[1].x = -1.25 * ah->he;
+ po[1].y = 0.5 * ah->wi;
+ po[2].x = 0.0;
+ po[2].y = 0.0;
+ for(i = 0; i < 3; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), rotation, ec);
+ dk3fig_tool_shift_point(&(po[i]), aep.x, aep.y, ec);
+ }
+ if(ah->af) {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, obj->pc, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 3, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ } else {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, 7, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 3, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ }
+ if(ah->o1) {
+ if((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po) {
+ dk3mem_cpy(
+ (void *)((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po),
+ po,
+ (3 * sizeof(dk3_fig_poly_point_t))
+ );
+ (((dk3_fig_obj_t *)(ah->o1))->dt).pol.np = 3;
+ back = 1;
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } break;
+ case DK3_FIG_AS_BUTTED_HALF: {
+ if(!(drw->coah)) {
+ s = dk3figah_s(drw, obj, ah, ec);
+ aep.x = dk3ma_d_sub_ok(aep.x, (s * cos(rotation)), ec);
+ aep.y = dk3ma_d_sub_ok(aep.y, (s * sin(rotation)), ec);
+ }
+ po[0].x = -1.0 * ah->he;
+ po[0].y = 0.0;
+ po[1].x = -0.75 * ah->he;
+ po[1].y = 0.5 * ah->wi;
+ po[2].x = 0.0;
+ po[2].y = 0.0;
+ for(i = 0; i < 3; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), rotation, ec);
+ dk3fig_tool_shift_point(&(po[i]), aep.x, aep.y, ec);
+ }
+ if(ah->af) {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, obj->pc, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 3, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ } else {
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 3, /* Object type, subtype */
+ obj->lw, obj->pc, 7, 20, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 3, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ }
+ if(ah->o1) {
+ if((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po) {
+ dk3mem_cpy(
+ (void *)((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po),
+ po,
+ (3 * sizeof(dk3_fig_poly_point_t))
+ );
+ (((dk3_fig_obj_t *)(ah->o1))->dt).pol.np = 3;
+ back = 1;
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } break;
+ case DK3_FIG_AS_TRIANGLE_FORK: {
+ if(ah->af) {
+ if(!(drw->coah)) {
+ s = 0.5 * dk3fig_tool_get_lw(drw, obj, ec);
+ aep.x = dk3ma_d_sub_ok(aep.x, (s * cos(rotation)), ec);
+ aep.y = dk3ma_d_sub_ok(aep.y, (s * sin(rotation)), ec);
+ }
+ po[0].x = 0.0;
+ po[0].y = 0.5 * ah->wi;
+ po[1].x = 0.0;
+ po[1].y = -0.5 * ah->wi;
+ for(i = 0; i < 2; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), rotation, ec);
+ dk3fig_tool_shift_point(&(po[i]), aep.x, aep.y, ec);
+ }
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 1, /* Object type, subtype */
+ obj->lw, obj->pc, obj->pc, -1, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 2, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ if(ah->o1) {
+ if((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po) {
+ dk3mem_cpy(
+ (void *)((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po),
+ po,
+ (2 * sizeof(dk3_fig_poly_point_t))
+ );
+ (((dk3_fig_obj_t *)(ah->o1))->dt).pol.np = 2;
+ back = 1;
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } else {
+ po[0].x = 0.0;
+ po[0].y = 0.5 * ah->wi;
+ po[1].x = -1.0 * ah->he;
+ po[1].y = 0.0;
+ po[2].x = 0.0;
+ po[2].y = -0.5 * ah->wi;
+ for(i = 0; i < 3; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), rotation, ec);
+ dk3fig_tool_shift_point(&(po[i]), aep.x, aep.y, ec);
+ }
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 1, /* Object type, subtype */
+ obj->lw, obj->pc, obj->pc, -1, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 3, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ if(ah->o1) {
+ if((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po) {
+ dk3mem_cpy(
+ (void *)((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po),
+ po,
+ (3 * sizeof(dk3_fig_poly_point_t))
+ );
+ (((dk3_fig_obj_t *)(ah->o1))->dt).pol.np = 3;
+ back = 1;
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ }
+ } break;
+ case DK3_FIG_AS_RECTANGLE_FORK: {
+ if(ah->af) {
+ if(!(drw->coah)) {
+ s = 0.5 * dk3fig_tool_get_lw(drw, obj, ec);
+ aep.x = dk3ma_d_sub_ok(aep.x, (s * cos(rotation)), ec);
+ aep.y = dk3ma_d_sub_ok(aep.y, (s * sin(rotation)), ec);
+ }
+ po[0].x = -1.0 * ah->he;
+ po[0].y = 0.5 * ah->wi;
+ po[1].x = 0.0;
+ po[1].y = 0.5 * ah->wi;
+ po[2].x = 0.0;
+ po[2].y = -0.5 * ah->wi;
+ po[3].x = -1.0 * ah->he;
+ po[3].y = -0.5 * ah->wi;
+ } else {
+ po[0].x = 0.0;
+ po[0].y = 0.5 * ah->wi;
+ po[1].x = -1.0 * ah->he;
+ po[1].y = 0.5 * ah->wi;
+ po[2].x = -1.0 * ah->he;
+ po[2].y = -0.5 * ah->wi;
+ po[3].x = 0.0;
+ po[3].y = -0.5 * ah->wi;
+ }
+ for(i = 0; i < 4; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), rotation, ec);
+ dk3fig_tool_shift_point(&(po[i]), aep.x, aep.y, ec);
+ }
+ ah->o1 = dk3fig_obj_new(
+ obj->li, obj->la, /* Line number, layer */
+ DK3_FIG_OBJ_POLYLINE, 1, /* Object type, subtype */
+ obj->lw, obj->pc, obj->pc, -1, /* line width, pen, fill, style */
+ DK3_FIG_LC_BUTT, /* line cap */
+ DK3_FIG_LJ_MITER, /* line join */
+ DK3_FIG_LS_SOLID, /* line style */
+ 1.0, /* style value, unused */
+ 0, 0, /* arrowheads flags */
+ 4, /* Number of points */
+ NULL, /* Text */
+ drw->app /* Application */
+ );
+ if(ah->o1) {
+ if((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po) {
+ dk3mem_cpy(
+ (void *)((((dk3_fig_obj_t *)(ah->o1))->dt).pol.po),
+ po,
+ (4 * sizeof(dk3_fig_poly_point_t))
+ );
+ (((dk3_fig_obj_t *)(ah->o1))->dt).pol.np = 4;
+ back = 1;
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } break;
+ }
+ $? "- dk3figah_straight_arrowhead %d", back
+ return back;
+}
+
+
+
+/** Calculate arrowheads for polyline.
+ @param drw Drawing to modify.
+ @param obj Object to modify.
+ @param objno Object number.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figah_calculate_polyline(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ unsigned long objno
+)
+{
+ dk3_fig_poly_point_t *po; /* Points of the polyline. */
+ double cuts = -1.0; /* Cut at start. */
+ double cute = -1.0; /* Cut at end. */
+ double alphaf = 0.0; /* Direction of forward arrowhead. */
+ double alphab = 0.0; /* Direction of backward arrowhead. */
+ size_t np; /* Number of points in polyline. */
+ int mec = 0; /* Math error code. */
+ int res = 0; /* Arrowhead creation result. */
+ int back = 1;
+ $? "+ dk3figah_calculate_polyline"
+ np = (obj->dt).pol.np;
+ po = (obj->dt).pol.po;
+ if((1 < np) && (po)) {
+ /*
+ Calculate line cuttings for arrowhead.
+ */
+ if(obj->af) {
+ cute = dk3figah_length_correction(drw, obj, obj->af, &mec);
+ }
+ if(obj->ab) {
+ cuts = dk3figah_length_correction(drw, obj, obj->ab, &mec);
+ } $? ". mec = %d", mec
+ /*
+ Create arrowhead objects.
+ */
+ if(obj->af) {
+ alphaf = dk3ma_d_atan2(
+ dk3ma_d_sub_ok(po[np - 1].y, po[np - 2].y, &mec),
+ dk3ma_d_sub_ok(po[np - 1].x, po[np - 2].x, &mec)
+ );
+ }
+ if(obj->ab) {
+ alphab = dk3ma_d_atan2(
+ dk3ma_d_sub_ok(po[0].y, po[1].y, &mec),
+ dk3ma_d_sub_ok(po[0].x, po[1].x, &mec)
+ );
+ }
+ if(obj->af) {
+ res = dk3figah_straight_arrowhead(
+ drw, obj, obj->af, &(po[np - 1]), alphaf, &mec
+ );
+ if(!(res)) { back = 0; }
+ }
+ if(obj->ab) {
+ res = dk3figah_straight_arrowhead(
+ drw, obj, obj->ab, &(po[0]), alphab, &mec
+ );
+ if(!(res)) { back = 0; }
+ }
+ /*
+ Cut first and last segment if necessary when not using compatible
+ arrowheads.
+ */
+ if(!(drw->coah)) {
+ if(0.0 < cuts) {
+ if(0 == dk3fig_tool_cut_segment(&(po[0]), &(po[1]), cuts, &mec)) {
+ np = (obj->dt).pol.np = np - 1;
+ dk3fig_tool_poly_point_move_left(&(po[0]), &(po[1]), np);
+ }
+ }
+ if((0.0 < cute) && (1 < np)) {
+ if(0 == dk3fig_tool_cut_segment(&(po[np - 1]),&(po[np - 2]),cute,&mec))
+ {
+ (obj->dt).pol.np = np - 1;
+ }
+ }
+ }
+ }
+ if(mec) {
+ back = 0;
+ /* ERROR: Math error in object! */
+ dk3app_log_i1(drw->app, DK3_LL_ERROR, 260);
+ dk3fig_set_ec(drw, DK3_ERROR_MATH_OVERFLOW);
+ }
+ $? "- dk3figah_calculate_polyline %d", back
+ return back;
+}
+
+
+
+/** Calculate values for a given t.
+ @param drw Drawing object.
+ @param obj Fig object.
+ @param ah Arrowhead to modify.
+ @param xpos Pointer to x position variable.
+ @param ypos Pointer to y position variable.
+ @param phi Pointer to direction variable.
+ @param ab Flag: Is backward arrowhead (0=forward, 1=backward).
+ @param t The t value.
+ @param ec Pointer to error code variable.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figah_spline_values(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ double *xpos,
+ double *ypos,
+ double *phi,
+ int ab,
+ double t,
+ int *ec
+)
+{
+ double p;
+ int back = 0;
+ int mec = 0;
+ p = dk3xsp_direction_and_position(
+ xpos, ypos, (obj->dt).spl.po, (obj->dt).spl.np, t, drw->cosp, &mec
+ );
+ if(0.0 <= p) {
+ back = 1;
+ if(ab) {
+ p = p + M_PI;
+ while((2.0 * M_PI) < p) { p = p - (2.0 * M_PI);}
+ }
+ *phi = p;
+ if(mec) {
+ back = 0;
+ if(ec) { *ec = mec; }
+ }
+ }
+ return back;
+}
+
+
+
+#if TRACE_DEBUG
+/** Report spline points to debug file.
+ @param sp Spline points to report.
+ @param np Number of points to report.
+*/
+static
+void
+dk3figah_report_spline_points(
+ dk3_fig_spline_point_t *sp,
+ size_t np
+)
+{
+ FILE *fipo;
+ size_t i;
+ if((sp) && (np)) {
+ fipo = dktrace_file();
+ if(fipo) {
+ fputs("Spline points report:\n", fipo);
+ for(i = 0; i < np; i++) {
+ fprintf(
+ fipo,
+ "Point %5u:\tx = %lg \ty = %lg \ts = %lg\n",
+ (unsigned)i, sp[i].x, sp[i].y, sp[i].s
+ );
+ }
+ }
+ }
+}
+#endif
+
+
+
+/** Create arrowhead object on end of open spline.
+ @param drw Drawing object.
+ @param obj Fig object.
+ @param ah Arrowhead to modify.
+ @param ab Flag: Is backward arrowhead (0=forward, 1=backward).
+ @param ec Pointer to error code variable.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figah_one_spline_arrowhead(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int ab,
+ int *ec
+)
+{
+ dk3_xspline_segment_t seg; /* Segment for calculations. */
+ dk3_fig_poly_point_t pp[2]; /* For calculation. */
+ dk3_fig_poly_point_t *po; /* New polyline points. */
+ dk3_fig_obj_t *ao1 = NULL; /* Arrowhead object 1. */
+ dk3_fig_obj_t *ao2 = NULL; /* Arrowhead object 2. */
+ dk3_fig_spline_point_t *osp = NULL; /* Original spline points. */
+ dk3_fig_spline_point_t *sp = NULL; /* New spline points. */
+ dk3_fig_spline_point_t *sp2 = NULL; /* Spline points obj 2. */
+ double t0 = 0.0; /* Front point t. */
+ double t1 = 0.0; /* Current t. */
+ double t2 = 0.0; /* Arrow end point t. */
+ double t; /* Current t. */
+ double s = 0.0; /* Shift for front point. */
+ double l1 = 0.0; /* Segment 1 length. */
+ double l2 = 0.0; /* Segment 2 length. */
+ double xpos = 0.0; /* X position. */
+ double ypos = 0.0; /* Y position. */
+ double phi = 0.0; /* Angle at position. */
+ double lw = 0.0; /* Line width. */
+ double dist = 0.0; /* Distance to end point. */
+ size_t onp = 0; /* Object number of points. */
+ size_t n1 = 0; /* Number of sub-segments 1. */
+ size_t n2 = 0; /* Number of sub-segments 2. */
+ size_t n3 = 0; /* Number of sub-segments 3. */
+ size_t np = 0; /* Number of points. */
+ size_t nq = 0; /* Number of points obj 2. */
+ size_t i;
+ size_t j;
+ int res = 0; /* Operation result. */
+ int mec = 0; /* Mathematical error code. */
+ int back = 0;
+ $? "+ dk3figah_one_spline_arrowhead"
+ osp = (obj->dt).spl.po;
+ onp = (obj->dt).spl.np;
+ t0 = ((ab) ? 0.0 : (double)(onp - 1));
+ lw = dk3fig_tool_get_lw(drw, obj, &mec);
+ s = dk3figah_find_shift_length(drw, obj, ah, &mec);
+ switch(ah->as) {
+ case DK3_FIG_AS_STICK:
+ case DK3_FIG_AS_CLOSED: { $? ". closed or stick"
+ t0 = dk3xsp_get_t_for_distance(
+ osp, onp, s, drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if(0.0 <= t0) {
+ t1 = dk3xsp_get_t_for_distance(
+ osp, onp, dk3ma_d_add_ok(s, ah->he, &mec),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if(0.0 <= t1) { $? ". n1"
+ n1 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(fabs(t1 - t0), drw->splspp, &mec)), &mec
+ );
+ if(n1 < drw->minspp) { n1 = drw->minspp; }
+ np = dk3mem_add_size_t(dk3mem_mul_size_t(2, n1, &mec), 1, &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la,
+ DK3_FIG_OBJ_SPLINE,
+ ((DK3_FIG_AS_CLOSED == ah->as) ? 5 : 4),
+ obj->lw, obj->pc, ((ah->af) ? obj->pc : 7),
+ ((DK3_FIG_AS_CLOSED == ah->as) ? 20 : -1),
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1;
+ res = dk3xsp_calculate_position(
+ &seg, osp, onp, t0, drw->cosp, 0, &mec
+ );
+ if(res) { $? ". points %u", (unsigned)np
+ sp[n1].x = dk3xsp_get_x(&seg);
+ sp[n1].y = dk3xsp_get_y(&seg);
+ sp[n1].s = 0.0; $? ". point %u", (unsigned)n1
+ for(i = 0; i < n1; i++) {
+ j = i + 1; $? ". i=%u j=%u", (unsigned)i, (unsigned)j
+ if(j == n1) {
+ t = t1;
+ } else {
+ dist = dk3ma_d_add_ok(
+ s, (((double)j / (double)n1) * ah->he), &mec
+ ); $? ". dist = %lg", dist
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ ); $? ". t = %lg", t
+ $? ". dist = %lg", dk3xsp_open_spline_partial_length(osp, onp, drw->xsprec, t, (obj->dt).spl.fslc, ab, drw->cosp, &mec)
+ }
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ ); $? ". xpos = %lg ypos = %lg phi = %lg",xpos,ypos,phi
+ if(res) {
+ pp[0].x = pp[1].x = 0.0;
+ if(j == n1) {
+ pp[0].y = 0.5 * ah->wi;
+ } else {
+ pp[0].y = 0.5 * ah->wi * ((double)j / (double)n1);
+ }
+ pp[1].y = -1.0 * pp[0].y;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+ sp[n1 - j].x = pp[0].x; $? ". point %u", (unsigned)(n1 - j)
+ sp[n1 - j].y = pp[0].y; $? ". point %u", (unsigned)(n1 + j)
+ sp[n1 + j].x = pp[1].x;
+ sp[n1 + j].y = pp[1].y;
+ sp[n1 - j].s = sp[n1 + j].s =
+ ((j == n1) ? 0.0 : (-1.0));
+ } else {
+ back = 0; i = n1; $? "! calculation error"
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } else { $? "! calculation error"
+ back = 0; i = n1;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ }
+ } else { $? "! calculation error"
+ back = 0;
+ /* ##### ERROR: Spline calculation failed! */
+ } $!trace-code dk3figah_report_spline_points(sp, np);
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ }
+ }
+ }
+ } break;
+ case DK3_FIG_AS_INDENTED: { $? ". indented"
+ l1 = dk3ma_d_mul_ok(1.25, ah->he, &mec);
+ l2 = 0.25 * ah->he;
+ t0 = dk3xsp_get_t_for_distance(
+ osp, onp, s, drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ t1 = dk3xsp_get_t_for_distance(
+ osp, onp, dk3ma_d_add_ok(s, l1, &mec),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ t2 = dk3xsp_get_t_for_distance(
+ osp, onp, dk3ma_d_add_ok(s, ah->he, &mec),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if((0.0 <= t0) && (0.0 <= t1) && (0.0 <= t2)) { $? ". n1"
+ n1 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(drw->splspp, fabs(t1 - t0), &mec)), &mec
+ ); $? ". n2"
+ n2 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(drw->splspp, fabs(t1 - t2), &mec)), &mec
+ );
+ if(n1 < drw->minspp) { n1 = drw->minspp; }
+ if(n2 < drw->minspp) { n2 = drw->minspp; }
+ np = dk3mem_mul_size_t(2, dk3mem_add_size_t(n1, n2, &mec), &mec);
+ if(0 == mec) { $? ". points %u", (unsigned)np
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 5,
+ obj->lw, obj->pc, ((ah->af) ? obj->pc : 7), 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1;
+ res = dk3xsp_calculate_position(
+ &seg, osp, onp, t0, drw->cosp, 0, &mec
+ );
+ if(res) { $? ". points %u", (unsigned)np
+ sp[n1 + n2 - 1].x = dk3xsp_get_x(&seg);
+ sp[n1 + n2 - 1].y = dk3xsp_get_y(&seg);
+ sp[n1 + n2 - 1].s = 0.0; $? ". point %u", (unsigned)(n1 + n2 - 1)
+ for(i = 0; i < n1; i++) {
+ j = i + 1;
+ if(j == n1) {
+ t = t1;
+ } else {
+ dist = dk3ma_d_add_ok(
+ s, (((double)j / (double)n1) * l1), &mec
+ );
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ }
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+ if(res) {
+ pp[0].x = pp[1].x = 0.0;
+ if(j == n1) {
+ pp[0].y = 0.5 * ah->wi;
+ } else {
+ pp[0].y = 0.5 * ah->wi * ((double)j / (double)n1);
+ }
+ pp[1].y = -1.0 * pp[0].y;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+ sp[n1 + n2 - 1 - j].x = pp[0].x;
+ sp[n1 + n2 - 1 - j].y = pp[0].y;
+ $? ". point %u", (unsigned)(n1 + n2 - 1 - j)
+ sp[n1 + n2 - 1 + j].x = pp[1].x;
+ sp[n1 + n2 - 1 + j].y = pp[1].y;
+ $? ". point %u", (unsigned)(n1 + n2 - 1 + j)
+ sp[n1 + n2 - 1 - j].s = sp[n1 + n2 - 1 + j].s =
+ ((j == n1) ? 0.0 : (-1.0));
+ } else {
+ back = 0; i = n1;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } else {
+ back = 0; i = n1;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ }
+ if(back) {
+ for(i = 0; i < (n2 - 1); i++) {
+ j = i + 1;
+ dist = dk3ma_d_sub_ok(
+ dk3ma_d_add_ok(s, l1, &mec),
+ (l2 * ((double)j / (double)n2)),
+ &mec
+ );
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+ if(res) {
+ pp[0].x = pp[1].x = 0.0;
+ pp[0].y = 0.5 * ah->wi * (1.0 - ((double)j/(double)n2));
+ pp[1].y = -1.0 * pp[0].y;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+ sp[n2 - 1 - j].x = pp[0].x;
+ sp[n2 - 1 - j].y = pp[0].y;
+ $? ". point %u", (unsigned)(n2 - 1 - j)
+ sp[2 * n1 + n2 - 1 + j].x = pp[1].x;
+ sp[2 * n1 + n2 - 1 + j].y = pp[1].y;
+ $? ". point %u", (unsigned)(2 * n1 + n2 - 1 + j)
+ sp[n2 - 1 - j].s = sp[2 * n1 + n2 - 1 + j].s =
+ ((j == n1) ? 0.0 : (-1.0));
+ } else {
+ back = 0; i = n2;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } else {
+ back = 0; i = n2;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ }
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t2, &mec
+ );
+ if(res) {
+ sp[np - 1].x = xpos;
+ sp[np - 1].y = ypos;
+ sp[np - 1].s = 0.0; $? ". point %u", (unsigned)(np - 1)
+ } else {
+ back = 0;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ }
+ } else {
+ back = 0;
+ /* ##### ERROR: Spline calculation failed! */
+ } $!trace-code dk3figah_report_spline_points(sp, np);
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } else {
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } else {
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } break;
+ case DK3_FIG_AS_POINTED: { $? ". butted"
+ l1 = 0.75 * ah->he;
+ l2 = 0.25 * ah->he;
+ t0 = dk3xsp_get_t_for_distance(
+ osp, onp, s, drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ t1 = dk3xsp_get_t_for_distance(
+ osp, onp, dk3ma_d_add_ok(s, l1, &mec),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ t2 = dk3xsp_get_t_for_distance(
+ osp, onp, dk3ma_d_add_ok(s, ah->he, &mec),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if((0.0 <= t0) && (0.0 <= t1) && (0.0 <= t2)) { $? ". n1"
+ n1 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(drw->splspp, fabs(t1 - t0), &mec)), &mec
+ ); $? ". n2"
+ n2 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(drw->splspp, fabs(t1 - t2), &mec)), &mec
+ );
+ if(n1 < drw->minspp) { n1 = drw->minspp; }
+ if(n2 < drw->minspp) { n2 = drw->minspp; }
+ np = dk3mem_mul_size_t(2, dk3mem_add_size_t(n1, n2, &mec), &mec);
+ if(0 == mec) { $? ". points %u", (unsigned)np
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 5,
+ obj->lw, obj->pc, ((ah->af) ? obj->pc : 7), 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1;
+ res = dk3xsp_calculate_position(
+ &seg, osp, onp, t0, drw->cosp, 0, &mec
+ );
+ if(res) { $? ". points %u", (unsigned)np
+ sp[n1 + n2 - 1].x = dk3xsp_get_x(&seg);
+ sp[n1 + n2 - 1].y = dk3xsp_get_y(&seg);
+ sp[n1 + n2 - 1].s = 0.0; $? ". point %u", (unsigned)(n1 + n2 - 1)
+ for(i = 0; i < n1; i++) {
+ j = i + 1;
+ if(j == n1) {
+ t = t1;
+ } else {
+ dist = dk3ma_d_add_ok(
+ s, (((double)j / (double)n1) * l1), &mec
+ );
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ }
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+ if(res) {
+ pp[0].x = pp[1].x = 0.0;
+ if(j == n1) {
+ pp[0].y = 0.5 * ah->wi;
+ } else {
+ pp[0].y = 0.5 * ah->wi * ((double)j / (double)n1);
+ }
+ pp[1].y = -1.0 * pp[0].y;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+ sp[n1 + n2 - 1 - j].x = pp[0].x;
+ sp[n1 + n2 - 1 - j].y = pp[0].y;
+ $? ". point %u", (unsigned)(n1 + n2 - 1 - j)
+ sp[n1 + n2 - 1 + j].x = pp[1].x;
+ sp[n1 + n2 - 1 + j].y = pp[1].y;
+ $? ". point %u", (unsigned)(n1 + n2 - 1 + j)
+ sp[n1 + n2 - 1 - j].s = sp[n1 + n2 - 1 + j].s =
+ ((j == n1) ? 0.0 : (-1.0));
+ } else {
+ back = 0; i = n1;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } else {
+ back = 0; i = n1;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ }
+ if(back) {
+ for(i = 0; i < (n2 - 1); i++) {
+ j = i + 1;
+ dist = dk3ma_d_add_ok(
+ dk3ma_d_add_ok(s, l1, &mec),
+ (l2 * ((double)j / (double)n2)),
+ &mec
+ );
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+ if(res) {
+ pp[0].x = pp[1].x = 0.0;
+ pp[0].y = 0.5 * ah->wi * (1.0 - ((double)j/(double)n2));
+ pp[1].y = -1.0 * pp[0].y;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+ sp[n2 - 1 - j].x = pp[0].x;
+ sp[n2 - 1 - j].y = pp[0].y;
+ $? ". point %u", (unsigned)(n2 - 1 - j)
+ sp[2 * n1 + n2 - 1 + j].x = pp[1].x;
+ sp[2 * n1 + n2 - 1 + j].y = pp[1].y;
+ $? ". point %u", (unsigned)(2 * n1 + n2 - 1 + j)
+ sp[n2 - 1 - j].s = sp[2 * n1 + n2 - 1 + j].s =
+ ((j == n1) ? 0.0 : (-1.0));
+ } else {
+ back = 0; i = n2;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } else {
+ back = 0; i = n2;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ }
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t2, &mec
+ );
+ if(res) {
+ sp[np - 1].x = xpos;
+ sp[np - 1].y = ypos;
+ sp[np - 1].s = 0.0; $? ". point %u", (unsigned)(np - 1)
+ } else {
+ back = 0;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ }
+ } else {
+ back = 0;
+ /* ##### ERROR: Spline calculation failed! */
+ } $!trace-code dk3figah_report_spline_points(sp, np);
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } else {
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } else {
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } break;
+ case DK3_FIG_AS_RHOMBUS: {
+ if((1 == ah->af) && (DK3_FIG_SRCTYPE_JFIG == drw->srctype)) { $? ". jfig"
+ if(dk3xsp_calculate_position(&seg, osp, onp, t0, drw->cosp, 0, &mec)) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_ELLIPSE, 3,
+ obj->lw, obj->pc, obj->pc, 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, 0, NULL, drw->app
+ );
+ if(ao1) {
+ back = 1;
+ ah->o1 = (void *)ao1;
+ (ao1->dt).ell.an = 0.0;
+ (ao1->dt).ell.cx = dk3xsp_get_x(&seg);
+ (ao1->dt).ell.cy = dk3xsp_get_y(&seg);
+ (ao1->dt).ell.rx = dk3ma_d_mul_ok(2.0, ah->wi, &mec);
+ (ao1->dt).ell.ry = (ao1->dt).ell.rx;
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } else { $? "! dk3xsp_calculate_position"
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } else { $? ". rhombus"
+ l1 = 0.5 * ah->he;
+ l2 = l1;
+ t0 = dk3xsp_get_t_for_distance(
+ osp, onp, s, drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ t1 = dk3xsp_get_t_for_distance(
+ osp, onp, dk3ma_d_add_ok(s, l1, &mec),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ t2 = dk3xsp_get_t_for_distance(
+ osp, onp, dk3ma_d_add_ok(s, ah->he, &mec),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if((0.0 <= t0) && (0.0 <= t1) && (0.0 <= t2)) { $? ". n1"
+ n1 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(drw->splspp, fabs(t1 - t0), &mec)), &mec
+ ); $? ". n2"
+ n2 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(drw->splspp, fabs(t1 - t2), &mec)), &mec
+ );
+ if(n1 < drw->minspp) { n1 = drw->minspp; }
+ if(n2 < drw->minspp) { n2 = drw->minspp; }
+ np = dk3mem_mul_size_t(2, dk3mem_add_size_t(n1, n2, &mec), &mec);
+ if(0 == mec) { $? ". points %u", (unsigned)np
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 5,
+ obj->lw, obj->pc, ((ah->af) ? obj->pc : 7), 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1;
+ res = dk3xsp_calculate_position(
+ &seg, osp, onp, t0, drw->cosp, 0, &mec
+ );
+ if(res) { $? ". points %u", (unsigned)np
+ sp[n1 + n2 - 1].x = dk3xsp_get_x(&seg);
+ sp[n1 + n2 - 1].y = dk3xsp_get_y(&seg);
+ sp[n1 + n2 - 1].s = 0.0; $? ". point %u", (unsigned)(n1 + n2 - 1)
+ for(i = 0; i < n1; i++) {
+ j = i + 1;
+ if(j == n1) {
+ t = t1;
+ } else {
+ dist = dk3ma_d_add_ok(
+ s, (((double)j / (double)n1) * l1), &mec
+ );
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ }
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+ if(res) {
+ pp[0].x = pp[1].x = 0.0;
+ if(j == n1) {
+ pp[0].y = 0.5 * ah->wi;
+ } else {
+ pp[0].y = 0.5 * ah->wi * ((double)j / (double)n1);
+ }
+ pp[1].y = -1.0 * pp[0].y;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+ sp[n1 + n2 - 1 - j].x = pp[0].x;
+ sp[n1 + n2 - 1 - j].y = pp[0].y;
+ $? ". point %u", (unsigned)(n1 + n2 - 1 - j)
+ sp[n1 + n2 - 1 + j].x = pp[1].x;
+ sp[n1 + n2 - 1 + j].y = pp[1].y;
+ $? ". point %u", (unsigned)(n1 + n2 - 1 + j)
+ sp[n1 + n2 - 1 - j].s = sp[n1 + n2 - 1 + j].s =
+ ((j == n1) ? 0.0 : (-1.0));
+ } else {
+ back = 0; i = n1;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } else {
+ back = 0; i = n1;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ }
+ if(back) {
+ for(i = 0; i < (n2 - 1); i++) {
+ j = i + 1;
+ dist = dk3ma_d_add_ok(
+ dk3ma_d_add_ok(s, l1, &mec),
+ (l2 * ((double)j / (double)n2)),
+ &mec
+ );
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+ if(res) {
+ pp[0].x = pp[1].x = 0.0;
+ pp[0].y = 0.5 * ah->wi * (1.0 - ((double)j/(double)n2));
+ pp[1].y = -1.0 * pp[0].y;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+ sp[n2 - 1 - j].x = pp[0].x;
+ sp[n2 - 1 - j].y = pp[0].y;
+ $? ". point %u", (unsigned)(n2 - 1 - j)
+ sp[2 * n1 + n2 - 1 + j].x = pp[1].x;
+ sp[2 * n1 + n2 - 1 + j].y = pp[1].y;
+ $? ". point %u", (unsigned)(2 * n1 + n2 - 1 + j)
+ sp[n2 - 1 - j].s = sp[2 * n1 + n2 - 1 + j].s =
+ ((j == n1) ? 0.0 : (-1.0));
+ } else {
+ back = 0; i = n2;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } else {
+ back = 0; i = n2;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ }
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t2, &mec
+ );
+ if(res) {
+ sp[np - 1].x = xpos;
+ sp[np - 1].y = ypos;
+ sp[np - 1].s = 0.0; $? ". point %u", (unsigned)(np - 1)
+ } else {
+ back = 0;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ }
+ } else {
+ back = 0;
+ /* ##### ERROR: Spline calculation failed! */
+ } $!trace-code dk3figah_report_spline_points(sp, np);
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } else {
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } else {
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ }
+ } break;
+ case DK3_FIG_AS_FULL_CIRCLE_END: { $? ". full circle"
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t0, &mec
+ );
+ if(res) {
+#if VERSION_BEFORE_20121220
+ xpos = dk3ma_d_sub_ok(
+ xpos,
+ (0.5 * cos(phi) * dk3ma_d_add_ok((0.5 * ah->he), (0.5 * lw), &mec)),
+ &mec
+ );
+ ypos = dk3ma_d_sub_ok(
+ ypos,
+ (0.5 * sin(phi) * dk3ma_d_add_ok((0.5 * ah->he), (0.5 * lw), &mec)),
+ &mec
+ );
+#else
+ xpos = dk3ma_d_sub_ok(
+ xpos,
+ (cos(phi) * dk3ma_d_add_ok((0.5 * ah->he), (0.5 * lw), &mec)),
+ &mec
+ );
+ ypos = dk3ma_d_sub_ok(
+ ypos,
+ (sin(phi) * dk3ma_d_add_ok((0.5 * ah->he), (0.5 * lw), &mec)),
+ &mec
+ );
+#endif
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_ELLIPSE, 3,
+ obj->lw, obj->pc, ((ah->af) ? obj->pc : 7), 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, 0, NULL, drw->app
+ );
+ if(ao1) {
+ back = 1;
+ ah->o1 = (void *)ao1;
+ (ao1->dt).ell.an = 0.0;
+ (ao1->dt).ell.cx = xpos;
+ (ao1->dt).ell.cy = ypos;
+ (ao1->dt).ell.rx = 0.5 * ah->he;
+ (ao1->dt).ell.ry = (ao1->dt).ell.rx;
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ }
+ }
+ } break;
+ case DK3_FIG_AS_HALF_CIRCLE_END: { $? ". half-circle"
+ if(ah->af) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t0, &mec
+ );
+ if(res) {
+ xpos = dk3ma_d_sub_ok(xpos, (0.5 * lw * cos(phi)), &mec);
+ ypos = dk3ma_d_sub_ok(ypos, (0.5 * lw * sin(phi)), &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_PSEUDO_HALF_CIRCLE, 1,
+ obj->lw, obj->pc, obj->pc, 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, 0, NULL, drw->app
+ );
+ if(ao1) {
+ back = 1;
+ ah->o1 = (void *)ao1;
+ (ao1->dt).hci.cx = xpos;
+ (ao1->dt).hci.cy = ypos;
+ (ao1->dt).hci.ra = 0.5 * ah->he;
+ (ao1->dt).hci.an = phi;
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ }
+ }
+ } else {
+ t1 = dk3xsp_get_t_for_distance(
+ osp, onp, (0.5 * ah->he),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if(0.0 <= t1) {
+ dist = fabs(dk3ma_d_sub_ok(t1, t0, &mec)); $? ". n1"
+ n1 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(dist, drw->splspp, &mec)),
+ &mec
+ ); $? ". n1 = %u", (unsigned)n1
+ /* 2013-11-23
+ If we want to correct n1, we have to use ceil() in
+ the comparison too.
+ */
+ if(n1 < dk3ma_d_to_sz_ok(ceil(drw->arcspp), &mec)) { $? ". n1"
+ n1 = dk3ma_d_to_sz_ok(ceil(drw->arcspp), &mec);
+ } $? ". n1 = %u", (unsigned)n1
+ if(n1 < drw->minspp) {
+ n1 = drw->minspp;
+ } $? ". n1 = %u", (unsigned)n1
+ np = dk3mem_add_size_t(dk3mem_mul_size_t(2, n1, &mec), 1, &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 4,
+ obj->lw, obj->pc, 7, -1,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1;
+ res = dk3xsp_calculate_position(
+ &seg, osp, onp, t1, drw->cosp, 0, &mec
+ );
+ if(res) { $? ". points %u", (unsigned)np
+ sp[n1].x = dk3xsp_get_x(&seg);
+ sp[n1].y = dk3xsp_get_y(&seg);
+ sp[n1].s = -1.0; $? ". point %u", (unsigned)n1
+ for(i = 0; i < n1; i++) {
+ j = i + 1;
+ t1 = dk3xsp_get_t_for_distance(
+ osp, onp,
+ (0.5 * ah->he * cos(M_PI_2 * ((double)j / (double)n1))),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if(0.0 <= t1) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t1, &mec
+ );
+ if(res) {
+ pp[0].x = 0.0;
+ pp[1].x = 0.0;
+ pp[0].y = 0.5 * ah->he
+ * sin(M_PI_2 * ((double)j / (double)n1));
+ pp[1].y = -1.0 * pp[0].y;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+ sp[n1 - j].x = pp[0].x;
+ sp[n1 - j].y = pp[0].y; $? ". point %u",(unsigned)(n1-j)
+ sp[n1 + j].x = pp[1].x; $? ". point %u",(unsigned)(n1+j)
+ sp[n1 + j].y = pp[1].y;
+ sp[n1 - j].s = sp[n1 + j].s =
+ ((j == n1) ? 0.0 : (-1.0));
+ } else {
+ back = 0; i = n1;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } else {
+ back = 0;
+ i = n1;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ }
+ } else {
+ back = 0;
+ /* ##### ERROR: Calculation failed! */
+ }
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ }
+ }
+ }
+ } break;
+ case DK3_FIG_AS_RECTANGLE: { $? ". rectangle"
+ t0 = dk3xsp_get_t_for_distance(
+ osp, onp, s, drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ t1 = dk3xsp_get_t_for_distance(
+ osp, onp, dk3ma_d_add_ok(s, ah->he, &mec),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if((0.0 <= t0) && (0.0 <= t1)) { $? ". n1"
+ n1 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(fabs(t1 - t0), drw->splspp, &mec)), &mec
+ );
+ if(n1 < drw->minspp) { n1 = drw->minspp; }
+ np = dk3mem_mul_size_t(2, dk3mem_add_size_t(n1, 1, &mec), &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 5,
+ obj->lw, obj->pc, ((ah->af) ? obj->pc : 7), 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1;
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t0, &mec
+ );
+ if(res) { $? ". points %u", (unsigned)np
+ pp[0].x = pp[1].x = 0;
+ pp[0].y = 0.5 * ah->wi;
+ pp[1].y = -0.5 * ah->wi;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+ sp[n1].x = pp[0].x; $? ". point %u", (unsigned)n1
+ sp[n1].y = pp[0].y; $? ". point %u", (unsigned)(n1 + 1)
+ sp[n1 + 1].x = pp[1].x;
+ sp[n1 + 1].y = pp[1].y;
+ sp[n1].s = sp[n1 + 1].s = 0.0;
+ for(i = 0; i < n1; i++) {
+ j = i + 1;
+ if(j == n1) {
+ t = t1;
+ } else {
+ dist = dk3ma_d_add_ok(
+ s, (ah->he * ((double)j / (double)n1)), &mec
+ );
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ }
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+ if(res) {
+ pp[0].x = pp[1].x = 0.0;
+ pp[0].y = 0.5 * ah->wi;
+ pp[1].y = -0.5 * ah->wi;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+ sp[n1 - j].x = pp[0].x;
+ sp[n1 - j].y = pp[0].y;
+ $? ". point %u", (unsigned)(n1 - j)
+ sp[n1 + 1 + j].x = pp[1].x;
+ sp[n1 + 1 + j].y = pp[1].y;
+ $? ". point %u", (unsigned)(n1 + 1 + j)
+ sp[n1 - j].s = sp[n1 + 1 + j].s =
+ ((j == n1) ? 0.0 : (-1.0));
+
+ } else {
+ back = 0; i = n1;
+ }
+ } else {
+ back = 0; i = n1;
+ }
+ }
+ } else {
+ back = 0;
+ }
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ }
+ } else {
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } break;
+ case DK3_FIG_AS_INVERSE: { $? ". inverse"
+ t0 = dk3xsp_get_t_for_distance(
+ osp, onp, s, drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ t1 = dk3xsp_get_t_for_distance(
+ osp, onp, dk3ma_d_add_ok(s, ah->he, &mec),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if((0.0 <= t0) && (0.0 <= t1)) { $? ". n1"
+ n1 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(fabs(t1 - t0), drw->splspp, &mec)), &mec
+ );
+ if(n1 < drw->minspp) { n1 = drw->minspp; }
+ np = dk3mem_add_size_t(dk3mem_mul_size_t(2, n1, &mec), 1, &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 5,
+ obj->lw, obj->pc, ((ah->af) ? obj->pc : 7), 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1;
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t1, &mec
+ );
+ if(res) { $? ". points %u", (unsigned)np
+ sp[n1].x = xpos;
+ sp[n1].y = ypos;
+ sp[n1].s = 0.0; $? ". point %u", (unsigned)n1
+ for(i = 0; i < n1; i++) {
+ j = i + 1;
+ if(j == n1) {
+ t = t0;
+ } else {
+ dist = dk3ma_d_add_ok(
+ s, ((1.0 - ((double)j / (double)n1)) * ah->he), &mec
+ );
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ }
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+ if(res) {
+ pp[0].x = pp[1].x = 0.0;
+ pp[0].y = 0.5 * ((double)j / (double)n1) * ah->wi;
+ pp[1].y = -1.0 * pp[0].y;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+ sp[n1 - j].x = pp[0].x; sp[n1 - j].y = pp[0].y;
+ sp[n1 + j].x = pp[1].x; sp[n1 + j].y = pp[1].y;
+ $? ". point %u", (unsigned)(n1 - j)
+ $? ". point %u", (unsigned)(n1 + j)
+ sp[n1 - j].s = sp[n1 + j].s = ((j == n1) ? 0.0 : (-1.0));
+ } else {
+ }
+ } else {
+ back = 0; i = n1;
+ }
+ }
+ } else {
+ back = 0;
+ }
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ }
+ }
+ } break;
+ case DK3_FIG_AS_INDENTED_FILLED_HALF: { $? ". indented, half-filled"
+ l1 = dk3ma_d_mul_ok(1.25, ah->he, &mec);
+ l2 = 0.25 * ah->he;
+ t0 = dk3xsp_get_t_for_distance(
+ osp, onp, s, drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ t1 = dk3xsp_get_t_for_distance(
+ osp, onp, dk3ma_d_add_ok(s, l1, &mec),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ t2 = dk3xsp_get_t_for_distance(
+ osp, onp, dk3ma_d_add_ok(s, ah->he, &mec),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if((0.0 <= t0) && (0.0 <= t1) && (0.0 <= t2)) { $? ". n1"
+ n1 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(drw->splspp, fabs(t1 - t0), &mec)), &mec
+ ); $? ". n2"
+ n2 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(drw->splspp, fabs(t1 - t2), &mec)), &mec
+ ); $? ". n3"
+ n3 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(drw->splspp, fabs(t2 - t0), &mec)), &mec
+ );
+ if(n1 < drw->minspp) { n1 = drw->minspp; }
+ if(n2 < drw->minspp) { n2 = drw->minspp; }
+ if(n3 < drw->minspp) { n3 = drw->minspp; }
+ np = dk3mem_mul_size_t(2, dk3mem_add_size_t(n1, n2, &mec), &mec);
+ nq = dk3mem_add_size_t(dk3mem_add_size_t(n1, n2, &mec), n3, &mec);
+ if(0 == mec) { $? ". points %u", (unsigned)np
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 5,
+ obj->lw, obj->pc, 7, 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ ao2 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 5,
+ 0, obj->pc, obj->pc, 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, nq, NULL, drw->app
+ );
+ if(ao2) {
+ ah->o2 = (void *)ao2;
+ sp2 = (ao2->dt).spl.po;
+ if((sp) && (sp2)) {
+ back = 1;
+ res = dk3xsp_calculate_position(
+ &seg, osp, onp, t0, drw->cosp, 0, &mec
+ );
+ if(res) { $? ". points a=%u b=%u", (unsigned)np, (unsigned)nq
+ sp[n1 + n2 - 1].x = dk3xsp_get_x(&seg);
+ sp[n1 + n2 - 1].y = dk3xsp_get_y(&seg);
+ sp[n1 + n2 - 1].s = 0.0; $? ". point a %u", (unsigned)(n1 + n2 - 1)
+ sp2[0].x = dk3xsp_get_x(&seg);
+ sp2[0].y = dk3xsp_get_y(&seg);
+ sp2[0].s = 0.0; $? ". point b 0"
+ for(i = 0; i < n1; i++) {
+ j = i + 1;
+ if(j == n1) {
+ t = t1;
+ } else {
+ dist = dk3ma_d_add_ok(
+ s, (((double)j / (double)n1) * l1), &mec
+ );
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ }
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+ if(res) {
+ pp[0].x = pp[1].x = 0.0;
+ if(j == n1) {
+ if(ah->af) {
+ pp[0].y = 0.5 * ah->wi;
+ } else {
+ pp[0].y = -0.5 * ah->wi;
+ }
+ } else {
+ if(ah->af) {
+ pp[0].y = 0.5 * ah->wi * ((double)j / (double)n1);
+ } else {
+ pp[0].y = -0.5 * ah->wi * ((double)j / (double)n1);
+ }
+ }
+ pp[1].y = -1.0 * pp[0].y;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+ sp[n1 + n2 - 1 - j].x = pp[0].x;
+ sp[n1 + n2 - 1 - j].y = pp[0].y;
+ $? ". point a %u", (unsigned)(n1 + n2 - 1 - j)
+ sp[n1 + n2 - 1 + j].x = pp[1].x;
+ sp[n1 + n2 - 1 + j].y = pp[1].y;
+ $? ". point a %u", (unsigned)(n1 + n2 - 1 + j)
+ sp[n1 + n2 - 1 - j].s = sp[n1 + n2 - 1 + j].s =
+ ((j == n1) ? 0.0 : (-1.0));
+ sp2[j].x = pp[0].x;
+ sp2[j].y = pp[0].y;
+ sp2[j].s = ((j == n1) ? 0.0 : (-1.0));
+ $? ". point b %u", (unsigned)j
+ } else {
+ back = 0; i = n1;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } else {
+ back = 0; i = n1;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ }
+ if(back) {
+ for(i = 0; i < (n2 - 1); i++) {
+ j = i + 1;
+ dist = dk3ma_d_sub_ok(
+ dk3ma_d_add_ok(s, l1, &mec),
+ (l2 * ((double)j / (double)n2)),
+ &mec
+ );
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+ if(res) {
+ pp[0].x = pp[1].x = 0.0;
+ if(ah->af) {
+ pp[0].y = 0.5 * ah->wi
+ * (1.0 - ((double)j/(double)n2));
+ } else {
+ pp[0].y = -0.5 * ah->wi
+ * (1.0 - ((double)j/(double)n2));
+ }
+ pp[1].y = -1.0 * pp[0].y;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+ sp[n2 - 1 - j].x = pp[0].x;
+ sp[n2 - 1 - j].y = pp[0].y;
+ $? ". point a %u", (unsigned)(n2 - 1 - j)
+ sp[2 * n1 + n2 - 1 + j].x = pp[1].x;
+ sp[2 * n1 + n2 - 1 + j].y = pp[1].y;
+ $? ". point a %u", (unsigned)(2 * n1 + n2 - 1 + j)
+ sp[n2 - 1 - j].s = sp[2 * n1 + n2 - 1 + j].s =
+ ((j == n1) ? 0.0 : (-1.0));
+ sp2[n1 + j].x = pp[0].x;
+ sp2[n1 + j].y = pp[0].y;
+ sp2[n1 + j].s = ((j == n1) ? 0.0 : (-1.0));
+ $? ". point b %u", (unsigned)(n1 + j)
+ } else {
+ back = 0; i = n2;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } else {
+ back = 0; i = n2;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ }
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t2, &mec
+ );
+ if(res) {
+ sp[np - 1].x = xpos;
+ sp[np - 1].y = ypos;
+ sp[np - 1].s = 0.0; $? ". point a %u", (unsigned)(np - 1)
+ sp2[n1 + n2].x = xpos;
+ sp2[n1 + n2].y = ypos;
+ sp2[n1 + n2].s = 0.0; $? ". point b %u", (unsigned)(n1 + n2)
+ } else {
+ back = 0;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ for(i = 0; i < (n3 - 1); i++) {
+ j = i + 1;
+ dist = dk3ma_d_add_ok(
+ s,
+ ((1.0 - ((double)j / (double)n3)) * ah->he),
+ &mec
+ );
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+ if(res) {
+ sp2[n1 + n2 + j].x = xpos;
+ sp2[n1 + n2 + j].y = ypos;
+ sp2[n1 + n2 + j].s = -1.0;
+ $? ". point b %u", (unsigned)(n1 + n2 + j)
+ } else {
+ back = 0; i = n3;
+ }
+ } else {
+ back = 0; i = n3;
+ }
+ }
+ }
+ } else {
+ back = 0;
+ /* ##### ERROR: Spline calculation failed! */
+ } $!trace-code dk3figah_report_spline_points(sp, np);
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } else {
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } else {
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } break;
+ case DK3_FIG_AS_CLOSED_HALF: { $? ". closed half-arrow"
+ t0 = dk3xsp_get_t_for_distance(
+ osp, onp, s, drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if(0.0 <= t0) {
+ t1 = dk3xsp_get_t_for_distance(
+ osp, onp, dk3ma_d_add_ok(s, ah->he, &mec),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if(0.0 <= t1) { $? ". n1"
+ n1 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(fabs(t1 - t0), drw->splspp, &mec)), &mec
+ );
+ if(n1 < drw->minspp) { n1 = drw->minspp; }
+ np = dk3mem_add_size_t(dk3mem_mul_size_t(2, n1, &mec), 1, &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la,
+ DK3_FIG_OBJ_SPLINE, 5,
+ obj->lw, obj->pc, ((ah->af) ? obj->pc : 7), 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1;
+ res = dk3xsp_calculate_position(
+ &seg, osp, onp, t0, drw->cosp, 0, &mec
+ );
+ if(res) { $? ". points %u", (unsigned)np
+ sp[n1].x = dk3xsp_get_x(&seg);
+ sp[n1].y = dk3xsp_get_y(&seg);
+ sp[n1].s = 0.0; $? ". point %u", (unsigned)n1
+ for(i = 0; i < n1; i++) {
+ j = i + 1; $? ". i=%u j=%u", (unsigned)i, (unsigned)j
+ if(j == n1) {
+ t = t1;
+ } else {
+ dist = dk3ma_d_add_ok(
+ s, (((double)j / (double)n1) * ah->he), &mec
+ ); $? ". dist = %lg", dist
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ ); $? ". t = %lg", t
+ $? ". dist = %lg", dk3xsp_open_spline_partial_length(osp, onp, drw->xsprec, t, (obj->dt).spl.fslc, ab, drw->cosp, &mec)
+ }
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ ); $? ". xpos = %lg ypos = %lg phi = %lg",xpos,ypos,phi
+ if(res) {
+ pp[0].x = pp[1].x = 0.0;
+ if(j == n1) {
+ pp[0].y = 0.5 * ah->wi;
+ } else {
+ pp[0].y = 0.5 * ah->wi * ((double)j / (double)n1);
+ }
+ pp[1].y = 0.0;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+ sp[n1 - j].x = pp[0].x; $? ". point %u", (unsigned)(n1 - j)
+ sp[n1 - j].y = pp[0].y; $? ". point %u", (unsigned)(n1 + j)
+ sp[n1 + j].x = pp[1].x;
+ sp[n1 + j].y = pp[1].y;
+ sp[n1 - j].s = sp[n1 + j].s =
+ ((j == n1) ? 0.0 : (-1.0));
+ } else {
+ back = 0; i = n1; $? "! calculation error"
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ } else { $? "! calculation error"
+ back = 0; i = n1;
+ /* ##### ERROR: Spline calculation failed! */
+ }
+ }
+ } else { $? "! calculation error"
+ back = 0;
+ /* ##### ERROR: Spline calculation failed! */
+ } $!trace-code dk3figah_report_spline_points(sp, np);
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ }
+ }
+ }
+ } break;
+ case DK3_FIG_AS_INDENTED_HALF: { $? ". indented half-arrow"
+ l1 = dk3ma_d_mul_ok(1.25, ah->he, &mec);
+ l2 = 0.25 * ah->he;
+ t0 = dk3xsp_get_t_for_distance(
+ osp, onp, s, drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ t1 = dk3xsp_get_t_for_distance(
+ osp, onp, dk3ma_d_add_ok(s, l1, &mec),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ t2 = dk3xsp_get_t_for_distance(
+ osp, onp, dk3ma_d_add_ok(s, ah->he, &mec),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if((0.0 <= t0) && (0.0 <= t1) && (0.0 <= t2)) { $? ". n1"
+ n1 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(drw->splspp, fabs(t1 - t0), &mec)), &mec
+ ); $? ". n2"
+ n2 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(drw->splspp, fabs(t1 - t2), &mec)), &mec
+ ); $? ". n3"
+ n3 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(drw->splspp, fabs(t2 - t0), &mec)), &mec
+ );
+ if(n1 < drw->minspp) { n1 = drw->minspp; }
+ if(n2 < drw->minspp) { n2 = drw->minspp; }
+ if(n3 < drw->minspp) { n3 = drw->minspp; }
+ np = dk3mem_add_size_t(dk3mem_add_size_t(n1, n2, &mec), n3, &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 5,
+ obj->lw, obj->pc, ((ah->af) ? obj->pc : 7), 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1; $? ". points %u", (unsigned)np
+ for(i = 0; i < n1; i++) {
+ if(0 == i) {
+ t = t0;
+ } else {
+ dist = dk3ma_d_add_ok(
+ s, (l1 * ((double)i / (double)(n1))), &mec
+ );
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ }
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+ if(res) {
+ pp[0].x = 0.0;
+ pp[0].y = 0.5 * ah->wi * ((double)i / (double)n1);
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ sp[i].x = pp[0].x; $? ". point %u", (unsigned)i
+ sp[i].y = pp[0].y;
+ sp[i].s = ((i == 0) ? 0.0 : (-1.0));
+ } else {
+ back = 0; i = n1;
+ }
+ } else {
+ back = 0; i = n1;
+ }
+ }
+ if(back) {
+ for(i = 0; i < n2; i++) {
+ if(0 == i) {
+ t = t1;
+ } else {
+#if 0
+ dist = dk3ma_d_sub_ok(
+ l1, (l2 * ((double)i / (double)n2)), &mec
+ );
+#endif
+ dist = dk3ma_d_add_ok(
+ s,
+ dk3ma_d_sub_ok(
+ l1, (l2 * ((double)i / (double)n2)), &mec
+ ),
+ &mec
+ );
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ }
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+ if(res) {
+ pp[0].x = 0.0;
+ pp[0].y = 0.5 * ah->wi * (1.0 - ((double)i / (double)n2));
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ sp[n1 + i].x = pp[0].x; $? ". point %u",(unsigned)(n1 + i)
+ sp[n1 + i].y = pp[0].y;
+ sp[n1 + i].s = ((0 == i) ? 0.0 : (-1.0));
+ } else {
+ back = 0; i = n2;
+ }
+ } else {
+ back = 0; i = n2;
+ }
+ }
+ }
+ if(back) {
+ for(i = 0; i < n3; i++) {
+ if(0 == i) {
+ t = t2;
+ } else {
+ dist = dk3ma_d_add_ok(
+ s, (ah->he * (1.0 - ((double)i / (double)n3))), &mec
+ );
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ }
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+ if(res) {
+ sp[n1 + n2 + i].x = xpos;
+ sp[n1 + n2 + i].y = ypos;
+ sp[n1 + n2 + i].s = ((0 == i) ? 0.0 : (-1.0));
+ $? ". point %u", (unsigned)(n1 + n2 + i)
+ } else {
+ back = 0; i = n3;
+ }
+ } else {
+ back = 0; i = n3;
+ }
+ }
+ }
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ }
+ }
+ } break;
+ case DK3_FIG_AS_BUTTED_HALF: { $? ". butted half-arrow"
+ l1 = 0.75 * ah->he;
+ l2 = 0.25 * ah->he;
+ t0 = dk3xsp_get_t_for_distance(
+ osp, onp, s, drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ t1 = dk3xsp_get_t_for_distance(
+ osp, onp, dk3ma_d_add_ok(s, l1, &mec),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ t2 = dk3xsp_get_t_for_distance(
+ osp, onp, dk3ma_d_add_ok(s, ah->he, &mec),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if((0.0 <= t0) && (0.0 <= t1) && (0.0 <= t2)) { $? ". n1"
+ n1 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(drw->splspp, fabs(t1 - t0), &mec)), &mec
+ ); $? ". n2"
+ n2 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(drw->splspp, fabs(t1 - t2), &mec)), &mec
+ ); $? ". n3"
+ n3 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(drw->splspp, fabs(t2 - t0), &mec)), &mec
+ );
+ if(n1 < drw->minspp) { n1 = drw->minspp; }
+ if(n2 < drw->minspp) { n2 = drw->minspp; }
+ if(n3 < drw->minspp) { n3 = drw->minspp; }
+ np = dk3mem_add_size_t(dk3mem_add_size_t(n1, n2, &mec), n3, &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 5,
+ obj->lw, obj->pc, ((ah->af) ? obj->pc : 7), 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1; $? ". points %u", (unsigned)np
+ for(i = 0; i < n1; i++) {
+ if(0 == i) {
+ t = t0;
+ } else {
+ dist = dk3ma_d_add_ok(
+ s, (l1 * ((double)i / (double)(n1))), &mec
+ );
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ }
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+ if(res) {
+ pp[0].x = 0.0;
+ pp[0].y = 0.5 * ah->wi * ((double)i / (double)n1);
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ sp[i].x = pp[0].x; $? ". point %u", (unsigned)i
+ sp[i].y = pp[0].y;
+ sp[i].s = ((i == 0) ? 0.0 : (-1.0));
+ } else {
+ back = 0; i = n1;
+ }
+ } else {
+ back = 0; i = n1;
+ }
+ }
+ if(back) {
+ for(i = 0; i < n2; i++) {
+ if(0 == i) {
+ t = t1;
+ } else {
+#if 0
+ dist = dk3ma_d_add_ok(
+ l1, (l2 * ((double)i / (double)n2)), &mec
+ );
+#endif
+ dist = dk3ma_d_add_ok(
+ s,
+ dk3ma_d_add_ok(
+ l1, (l2 * ((double)i / (double)n2)), &mec
+ ),
+ &mec
+ );
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ }
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+ if(res) {
+ pp[0].x = 0.0;
+ pp[0].y = 0.5 * ah->wi * (1.0 - ((double)i / (double)n2));
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ sp[n1 + i].x = pp[0].x; $? ". point %u",(unsigned)(n1 + i)
+ sp[n1 + i].y = pp[0].y;
+ sp[n1 + i].s = ((0 == i) ? 0.0 : (-1.0));
+ } else {
+ back = 0; i = n2;
+ }
+ } else {
+ back = 0; i = n2;
+ }
+ }
+ }
+ if(back) {
+ for(i = 0; i < n3; i++) {
+ if(0 == i) {
+ t = t2;
+ } else {
+ dist = dk3ma_d_add_ok(
+ s, (ah->he * (1.0 - ((double)i / (double)n3))), &mec
+ );
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ }
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+ if(res) {
+ sp[n1 + n2 + i].x = xpos;
+ sp[n1 + n2 + i].y = ypos;
+ sp[n1 + n2 + i].s = ((0 == i) ? 0.0 : (-1.0));
+ $? ". point %u", (unsigned)(n1 + n2 + i)
+ } else {
+ back = 0; i = n3;
+ }
+ } else {
+ back = 0; i = n3;
+ }
+ }
+ }
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ }
+ }
+ } break;
+ case DK3_FIG_AS_TRIANGLE_FORK: { $? ". triangle fork"
+ if(ah->af) {
+ t0 = dk3xsp_get_t_for_distance(
+ osp, onp, s, drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if(0.0 <= t0) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_POLYLINE, 1,
+ obj->lw, obj->pc, obj->pc, -1,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, 2, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ po = (ao1->dt).pol.po;
+ if(po) {
+ back = 1;
+ pp[0].x = pp[1].x = 0.0;
+ pp[0].y = 0.5 * ah->wi;
+ pp[1].y = -0.5 * ah->wi;
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t0, &mec
+ );
+ if(res) {
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+ po[0].x = pp[0].x; po[0].y = pp[0].y;
+ po[1].x = pp[1].x; po[1].y = pp[1].y;
+ } else {
+ back = 0;
+ }
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ }
+ } else {
+ t0 = dk3xsp_get_t_for_distance(
+ osp, onp, s, drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ t1 = dk3xsp_get_t_for_distance(
+ osp, onp, dk3ma_d_add_ok(s, ah->he, &mec),
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if((0.0 <= t0) && (0.0 <= t1)) { $? ". n1"
+ n1 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(fabs(t1 - t0), drw->splspp, &mec)), &mec
+ );
+ if(n1 < drw->minspp) { n1 = drw->minspp; }
+ np = dk3mem_add_size_t(dk3mem_mul_size_t(2, n1, &mec), 1, &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 4,
+ obj->lw, obj->pc, ((ah->af) ? obj->pc : 7), -1,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1;
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t1, &mec
+ );
+ if(res) { $? ". points %u", (unsigned)np
+ sp[n1].x = xpos;
+ sp[n1].y = ypos;
+ sp[n1].s = 0.0; $? ". point %u", (unsigned)n1
+ for(i = 0; i < n1; i++) {
+ j = i + 1;
+ if(j == n1) {
+ t = t0;
+ } else {
+ dist = dk3ma_d_add_ok(
+ s, ((1.0 - ((double)j / (double)n1)) * ah->he), &mec
+ );
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ }
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ );
+ if(res) {
+ pp[0].x = pp[1].x = 0.0;
+ pp[0].y = 0.5 * ((double)j / (double)n1) * ah->wi;
+ pp[1].y = -1.0 * pp[0].y;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+ sp[n1 - j].x = pp[0].x; sp[n1 - j].y = pp[0].y;
+ sp[n1 + j].x = pp[1].x; sp[n1 + j].y = pp[1].y;
+ $? ". point %u", (unsigned)(n1 - j)
+ $? ". point %u", (unsigned)(n1 + j)
+ sp[n1 - j].s = sp[n1 + j].s =
+ ((j == n1) ? 0.0 : (-1.0));
+ } else {
+ }
+ } else {
+ back = 0; i = n1;
+ }
+ }
+ } else {
+ back = 0;
+ }
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ }
+ }
+ }
+ } break;
+ case DK3_FIG_AS_RECTANGLE_FORK: { $? ". rectangle fork"
+ if(ah->af) {
+ t0 = dk3xsp_get_t_for_distance(
+ osp, onp, s, drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ l1 = dk3ma_d_add_ok(s, ah->he, &mec);
+ t1 = dk3xsp_get_t_for_distance(
+ osp, onp, l1, drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ );
+ if((0.0 <= t0) && (0.0 <= t1)) { $? ". n1"
+ n1 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(drw->splspp, fabs(t1 - t0), &mec)), &mec
+ );
+ if(n1 < drw->minspp) { n1 = drw->minspp; }
+ np = dk3mem_mul_size_t(2, dk3mem_add_size_t(n1, 1, &mec), &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 4,
+ obj->lw, obj->pc, obj->pc, -1,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1;
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t0, &mec
+ );
+ if(res) { $? ". points = %u", (unsigned)np
+ pp[0].x = 0.0; pp[1].x = 0.0;
+ pp[0].y = 0.5 * ah->wi;
+ pp[1].y = -0.5 * ah->wi;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+ sp[n1].x = pp[0].x;
+ sp[n1].y = pp[0].y;
+ $? ". point %u", (unsigned)n1
+ sp[n1 + 1].x = pp[1].x;
+ sp[n1 + 1].y = pp[1].y;
+ $? ". point %u", (unsigned)(n1 + 1)
+ sp[n1].s = sp[n1 + 1].s = 0.0;
+ for(i = 0; i < n1; i++) {
+ j = i + 1;
+ if(j == n1) {
+ t = t1;
+ } else {
+ dist = dk3ma_d_add_ok(
+ s, (((double)j / (double)n1) * ah->he), &mec
+ ); $? ". mec = %d", mec
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ ); $? ". mec = %d", mec
+ }
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ ); $? ". mec = %d", mec
+ if(res) {
+ pp[0].x = 0.0; pp[1].x = 0.0;
+ pp[0].y = 0.5 * ah->wi;
+ pp[1].y = -0.5 * ah->wi;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ $? ". mec = %d", mec
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+ $? ". mec = %d", mec
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ $? ". mec = %d", mec
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+ $? ". mec = %d", mec
+ sp[n1 - j].x = pp[0].x;
+ sp[n1 - j].y = pp[0].y;
+ $? ". point %u", (unsigned)(n1 - j)
+ sp[n1 + 1 + j].x = pp[1].x;
+ sp[n1 + 1 + j].y = pp[1].y;
+ $? ". point %u", (unsigned)(n1 + 1 + j)
+ sp[n1 - j].s = sp[n1 + 1 + j].s =
+ ((j == n1) ? 0.0 : (-1.0));
+ } else {
+ back = 0; i = n1;
+ }
+ } else {
+ back = 0; i = n1;
+ }
+ }
+ } else {
+ back = 0;
+ }
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ }
+ }
+ } else { $? ". not filled"
+ t0 = ((ab) ? 0.0 : ((obj->dt).spl.np - 1));
+ t1 = dk3xsp_get_t_for_distance(
+ osp, onp, ah->he, drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ ); $? ". mec = %d", mec
+ if((0.0 <= t0) && (0.0 <= t1)) { $? ". t0=%lg t1=%lg", t0, t1
+ n1 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(drw->splspp, fabs(t1 - t0), &mec)), &mec
+ ); $? ". mec = %d", mec
+ if(n1 < drw->minspp) { n1 = drw->minspp; }
+ np = dk3mem_mul_size_t(2, dk3mem_add_size_t(n1, 1, &mec), &mec);
+ $? ". mec = %d", mec
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 4,
+ obj->lw, obj->pc, obj->pc, -1,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) { $? ". ao1"
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) { $? ". sp"
+ back = 1; $? ". points %u", (unsigned)np
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t1, &mec
+ ); $? ". mec = %d", mec
+ if(res) { $? ". res"
+ pp[0].x = 0.0; pp[1].x = 0.0;
+ pp[0].y = 0.5 * ah->wi;
+ pp[1].y = -0.5 * ah->wi;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ $? ". mec = %d", mec
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+ $? ". mec = %d", mec
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ $? ". mec = %d", mec
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+ $? ". mec = %d", mec
+ sp[n1].x = pp[0].x;
+ sp[n1].y = pp[0].y;
+ $? ". point %u", (unsigned)n1
+ sp[n1 + 1].x = pp[1].x;
+ sp[n1 + 1].y = pp[1].y;
+ $? ". point %u", (unsigned)(n1 + 1)
+ sp[n1].s = sp[n1 + 1].s = 0.0;
+ for(i = 0; i < n1; i++) {
+ j = i + 1;
+ if(j == n1) {
+ t = t0;
+ } else {
+ dist = (1.0 - ((double)j / (double)n1)) * ah->he;
+ t = dk3xsp_get_t_for_distance(
+ osp, onp, dist,
+ drw->xsprec, (obj->dt).spl.fslc, ab, drw->cosp, &mec
+ ); $? ". mec = %d", mec
+ }
+ if(0.0 <= t) {
+ res = dk3figah_spline_values(
+ drw, obj, ah, &xpos, &ypos, &phi, ab, t, &mec
+ ); $? ". mec = %d", mec
+ if(res) {
+ pp[0].x = 0.0; pp[1].x = 0.0;
+ pp[0].y = 0.5 * ah->wi;
+ pp[1].y = -0.5 * ah->wi;
+ dk3fig_tool_rotate_point(&pp[0], phi, &mec);
+ $? ". mec = %d", mec
+ dk3fig_tool_rotate_point(&pp[1], phi, &mec);
+ $? ". mec = %d", mec
+ dk3fig_tool_shift_point(&pp[0], xpos, ypos, &mec);
+ $? ". mec = %d", mec
+ dk3fig_tool_shift_point(&pp[1], xpos, ypos, &mec);
+ $? ". mec = %d", mec
+ sp[n1 - j].x = pp[0].x;
+ sp[n1 - j].y = pp[0].y;
+ $? ". point %u", (unsigned)(n1 - j)
+ sp[n1 + 1 + j].x = pp[1].x;
+ sp[n1 + 1 + j].y = pp[1].y;
+ $? ". point %u", (unsigned)(n1 + 1 + j)
+ sp[n1 - j].s = sp[n1 + 1 + j].s =
+ ((j == n1) ? 0.0 : (-1.0));
+ } else {
+ back = 0; i = n1;
+ }
+ } else {
+ back = 0; i = n1;
+ }
+ }
+ } else { $? "! res"
+ back = 0;
+ }
+ } else { $? "! sp"
+ }
+ } else { $? "! ao1"
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } else { $? "! t0=%lg t1=%lg", t0, t1
+ }
+ }
+ } break;
+ }
+ if(mec) { $? "! mec = %d", mec
+ back = 0;
+ if(ec) { *ec = mec; }
+ /* ##### ERROR: Mathematical error occured! */
+ } else {
+ if(!(back)) {
+ /* ##### ERROR: Error in spline arrowhead calculation! */
+ }
+ } $? "- dk3figah_one_spline_arrowhead %d", back
+ return back;
+}
+
+
+
+/** Calculate arrowheads for spline.
+ @param drw Drawing to modify.
+ @param obj Object to modify.
+ @param objno Object number.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figah_calculate_spline(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ unsigned long objno
+)
+{
+ dk3_xspline_segment_t seg;
+ dk3_fig_poly_point_t sp;
+ double cuts = -1.0;
+ double cute = -1.0;
+ double alphaf = 0.0;
+ double alphab = 0.0;
+ double t;
+ int back = 1;
+ int mec = 0;
+ int res = 0;
+ $? "+ dk3figah_calculate_spline"
+ if((1 < (obj->dt).spl.np) && ((obj->dt).spl.po)) {
+ /*
+ Defaults for start and end.
+ */
+ (obj->dt).spl.ts = 0.0;
+ (obj->dt).spl.te = (double)((obj->dt).spl.np - 1);
+ /*
+ Calculate line cuts.
+ */
+ if(!(drw->coah)) { $? ". fig2lat arrowheads"
+ if(obj->af) { $? ". arrowhead forward"
+ cute = dk3figah_length_correction(drw, obj, obj->af, &mec);
+ }
+ if(obj->ab) { $? ". arrowhead backward"
+ cuts = dk3figah_length_correction(drw, obj, obj->ab, &mec);
+ } $? ". mec = %d", mec
+ }
+ /*
+ Construct arrowhead objects.
+ */
+ if(drw->coah) {
+ back = 1;
+ if(obj->af) {
+ t = (double)((obj->dt).spl.np - 1);
+ res = dk3xsp_calculate_position(
+ &seg, (obj->dt).spl.po, (obj->dt).spl.np, t, drw->cosp, 0, &mec
+ );
+ if((res) && (0 == mec)) {
+ alphaf = dk3xsp_direction(
+ (obj->dt).spl.po, (obj->dt).spl.np, t, drw->cosp, &mec
+ ); $? ". mec = %d", mec
+ if((alphaf >= 0.0) && (0 == mec)) {
+ sp.x = dk3xsp_get_x(&seg);
+ sp.y = dk3xsp_get_y(&seg);
+ res = dk3figah_straight_arrowhead(
+ drw, obj, obj->af, &sp, alphaf, &mec
+ ); $? ". mec = %d", mec
+ if(!(res)) { back = 0; }
+ } else {
+ /* ##### ERROR: Arrowhead calculation failed! */
+ back = 0;
+ }
+ } else {
+ /* ##### ERROR: Arrowhead calculation failed! */
+ back = 0;
+ }
+ }
+ if(obj->ab) {
+ res = dk3xsp_calculate_position(
+ &seg, (obj->dt).spl.po, (obj->dt).spl.np, 0.0, drw->cosp, 0, &mec
+ ); $? ". mec = %d", mec
+ if((res) && (0 == mec)) {
+ alphab = dk3xsp_direction(
+ (obj->dt).spl.po, (obj->dt).spl.np, 0.0, drw->cosp, &mec
+ ); $? ". mec = %d", mec
+ if((alphab >= 0.0) && (0 == mec)) {
+ alphab += M_PI;
+ sp.x = dk3xsp_get_x(&seg);
+ sp.y = dk3xsp_get_y(&seg);
+ res = dk3figah_straight_arrowhead(
+ drw, obj, obj->ab, &sp, alphab, &mec
+ ); $? ". mec = %d", mec
+ if(!(res)) { back = 0; }
+ } else {
+ /* ##### ERROR: Arrowhead calculation failed! */
+ back = 0;
+ }
+ } else {
+ /* ##### ERROR: Arrowhead calculation failed! */
+ back = 0;
+ }
+ }
+ } else {
+ if(obj->af) {
+ if(!dk3figah_one_spline_arrowhead(drw, obj, obj->af, 0, &mec)) {
+ back = 0;
+ } $? ". mec = %d", mec
+ }
+ if(obj->ab) {
+ if(!dk3figah_one_spline_arrowhead(drw, obj, obj->ab, 1, &mec)) {
+ back = 0;
+ } $? ". mec = %d", mec
+ }
+ }
+ /*
+ Cut spline if necessary when not using compatible arrowheads.
+ */
+#if VERSION_BEFORE_20150821
+ /* 2015-08-21 Static code analysis complains:
+ The following instruction discards all previous check results!
+ */
+ back = 1;
+#endif
+ if(!(drw->coah)) { $? ". fig2lat arrowheads"
+ if((0.0 < cuts) && (NULL != obj->ab)) { $? ". cut at start"
+ (obj->dt).spl.ts = dk3xsp_get_t_for_distance(
+ (obj->dt).spl.po,
+ (obj->dt).spl.np,
+ cuts,
+ dk3figah_length_correction_tolerance(drw, obj, obj->ab, &mec),
+ (obj->dt).spl.fslc,
+ 1,
+ drw->cosp,
+ &mec
+ ); $? ". mec = %d", mec
+ if(0.0 > (obj->dt).spl.ts) { $? "! negative start"
+ back = 0;
+ }
+ } else { $? ". no need to cut at start"
+ }
+ if((0.0 < cute) && (NULL != obj->af)) { $? ". cut at end"
+ (obj->dt).spl.te = dk3xsp_get_t_for_distance(
+ (obj->dt).spl.po,
+ (obj->dt).spl.np,
+ cute,
+ dk3figah_length_correction_tolerance(drw, obj, obj->af, &mec),
+ (obj->dt).spl.fslc,
+ 0,
+ drw->cosp,
+ &mec
+ ); $? ". mec = %d", mec
+ if(0.0 > (obj->dt).spl.te) { $? "! negative end"
+ back = 0;
+ }
+ } else { $? ". no need to cut at end"
+ }
+ }
+ if(mec) { $? "! math error"
+ back = 0;
+ /* ERROR: Math error */
+ dk3app_log_i1(drw->app, DK3_LL_ERROR, 260);
+ }
+ }
+ $? "- dk3figah_calculate_spline %d", back
+ return back;
+}
+
+
+
+/** For corrections on arcs check whether we have to
+ use the full correction formula.
+ @param ah Arrowhead to calculate correction for.
+ @return 1 for correct formula, 0 for c/r.
+*/
+static
+int
+dk3figah_must_use_arc_correction(dk3_fig_ah_t *ah)
+{
+ int back = 0;
+ if(ah) {
+ if(!(ah->af)) {
+ switch(ah->as) {
+ case DK3_FIG_AS_HALF_CIRCLE_END: {
+ back = 1;
+ } break;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Calculate correction angle for arrowhead length correction on arcs.
+ @param r Arc radius.
+ @param c Correction length.
+ @param ec Pointer to error code variable.
+ @return Non-negative number on success, -1.0 on error.
+*/
+static
+double
+dk3figah_arc_correction(double r, double c, int *ec)
+{
+ double back = -1.0;
+ double val;
+ val = dk3ma_d_sub_ok(
+ 1.0,
+ dk3ma_d_div_ok(
+ dk3ma_d_square_ok(c, ec),
+ dk3ma_d_mul_ok(2.0, dk3ma_d_square_ok(r, ec), ec),
+ ec
+ ),
+ ec
+ );
+ if((-1.0 <= val) && (1.0 >= val)) {
+ back = acos(val);
+ } else {
+ if(ec) { *ec = DK3_ERROR_MATH_OUT_OF_RANGE; }
+ }
+ return back;
+}
+
+
+
+/** Calculate one arrowhead on arc.
+ @param drw Drawing structure.
+ @param obj Arc object containing the arrowhead.
+ @param ah Arrowhead structure.
+ @param ab Flag: Backward arrow (0=forward, 1=backward).
+ @param ec Pointer to error code variable.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figah_one_arc_arrowhead(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ int ab,
+ int *ec
+)
+{
+ dk3_fig_spline_point_t *sp = NULL;
+ dk3_fig_poly_point_t *po;
+ dk3_fig_poly_point_t pp;
+ dk3_fig_obj_t *ao1; /* Arrowhead object 1. */
+ dk3_fig_obj_t *ao2; /* Arrowhead object 2. */
+ double s; /* Shift length. */
+ double a0; /* Alpha at arrow front pt. */
+ double a1; /* Alpha at real front. */
+ double phi; /* Direction at front. */
+ double b1; /* Beta: Angle for arrowhead. */
+ double b2; /* Beta: Angle for part. */
+ double b3; /* Beta: Angle for inner. */
+ double f = -1.0; /* Factor. */
+ double ga; /* Current point angle. */
+ double r1;
+ double r2;
+ size_t nsegs = 0; /* Number of segments. */
+ size_t ns2 = 0; /* Number of segments 2. */
+ size_t ns3 = 0; /* Number of segments 3. */
+ size_t np = 0; /* Number of spline points. */
+ size_t i;
+ size_t j;
+ int mec = 0;
+ int back = 0;
+ int mustadd = 0;
+ $? "+ dk3figah_one_arc_arrowhead backward=%d", ab
+ if(ab) {
+ a0 = (obj->dt).arc.as;
+ if((obj->dt).arc.ae > (obj->dt).arc.as) {
+ f = 1.0;
+ } else {
+ f = -1.0;
+ }
+ } else {
+ a0 = (obj->dt).arc.ae;
+ if((obj->dt).arc.ae > (obj->dt).arc.as) {
+ f = -1.0;
+ } else {
+ f = 1.0;
+ }
+ }
+ $? ". arc x = %lg y = %lg r = %lg", (obj->dt).arc.xc, (obj->dt).arc.yc, (obj->dt).arc.ra
+ $? ". start x = %lg y = %lg", (obj->dt).arc.xc + (obj->dt).arc.ra * cos(a0), (obj->dt).arc.yc + (obj->dt).arc.ra * sin(a0)
+ a1 = a0; $? ". a1 = %lg", a1
+ phi = a1 - f * M_PI_2; $? ". phi = %lg", phi
+ s = dk3figah_find_shift_length(drw, obj, ah, &mec);
+ a0 = dk3ma_d_add_ok(
+ a0,
+ (f * dk3ma_d_div_ok(s, (obj->dt).arc.ra, &mec)),
+ &mec
+ ); $? ". after a0=%lg mec=%d", a0, mec
+ $? ". corrected start x= %lg y = %lg", (obj->dt).arc.xc + (obj->dt).arc.ra * cos(a0), (obj->dt).arc.yc * sin(a0)
+ switch(ah->as) {
+ case DK3_FIG_AS_STICK:
+ case DK3_FIG_AS_CLOSED: { $? ". stick or closed"
+ b1 = dk3ma_d_div_ok(ah->he, (obj->dt).arc.ra, &mec);
+ if(b1 < (2.0 * M_PI)) { $? ". nsegs"
+ nsegs = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b1, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ ); $? ". after nsegs %u mec=%d", (unsigned)nsegs, mec
+ if(drw->minspp > nsegs) { nsegs = drw->minspp; }
+#if TRACE_DEBUG
+ np = 2 * nsegs + 1; $? ". np = %u", (unsigned)np
+#endif
+ np = dk3mem_add_size_t(dk3mem_mul_size_t(2, nsegs, &mec), 1, &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la,
+ DK3_FIG_OBJ_SPLINE, 4,
+ obj->lw, obj->pc, -1, -1,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ if(ao1) {
+ sp = (ao1->dt).spl.po;
+ if(sp) { $? ". spline + points ok"
+ back = 1;
+ sp[nsegs].x = (obj->dt).arc.ra * cos(a0);
+ sp[nsegs].y = (obj->dt).arc.ra * sin(a0);
+ sp[nsegs].s = 0.0;
+ for(i = 0; i < nsegs; i++) { $? ". point %u", (unsigned)i
+ j = i + 1;
+ if(j == nsegs) {
+ ga = a0 + f * b1;
+ $? ". after ga=%lg mec=%d", ga, mec
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra, (0.5 * ah->wi), &mec
+ ); $? ". after r1=%lg mec=%d", r1, mec
+ r2 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra, (0.5 * ah->wi), &mec
+ ); $? ". after r2=%lg mec=%d", r2, mec
+ sp[nsegs - j].s = 0.0;
+ sp[nsegs + j].s = 0.0;
+ } else {
+ ga = a0 + f * b1 * ((double)j / (double)nsegs);
+ $? ". after ga=%lg mec=%d", ga, mec
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * ((double)j / (double)nsegs)),
+ &mec
+ ); $? ". after r1=%lg mec=%d", r1, mec
+ r2 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * ((double)j / (double)nsegs)),
+ &mec
+ ); $? ". after r2=%lg mec=%d", r2, mec
+ sp[nsegs - j].s = -1.0;
+ sp[nsegs + j].s = -1.0;
+ }
+ sp[nsegs - j].x = r1 * cos(ga);
+ sp[nsegs - j].y = r1 * sin(ga);
+ sp[nsegs + j].x = r2 * cos(ga);
+ sp[nsegs + j].y = r2 * sin(ga);
+ }
+ for(i = 0; i < np; i++) {
+ dk3fig_tool_shift_spoint(
+ &(sp[i]), (obj->dt).arc.xc, (obj->dt).arc.yc, &mec
+ ); $? ". after shift x=%lg y=%lg mec=%d", sp[i].x, sp[i].y, mec
+ }
+ if(DK3_FIG_AS_CLOSED == ah->as) {
+ ao1->st = 5;
+ if(ah->af) {
+ ao1->fc = obj->pc;
+ } else {
+ ao1->fc = 7;
+ }
+ ao1->fi = 20;
+ ao1->cl = 1;
+ } $!trace-code dk3figah_report_spline_points(sp, np);
+ }
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ }
+ } else {
+ /* ##### ERROR: Arrowhead too long! */
+ }
+ } break;
+ case DK3_FIG_AS_INDENTED: {
+ b1 = dk3ma_d_div_ok(
+ dk3ma_d_mul_ok(1.25, ah->he, &mec),
+ (obj->dt).arc.ra, &mec
+ );
+ b2 = dk3ma_d_div_ok((0.25 * ah->he), (obj->dt).arc.ra, &mec);
+ if((b1 < (2.0 * M_PI)) && (b2 < (2.0 * M_PI))) { $? ". nsegs"
+ nsegs = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b1, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ ); $? ". after nsegs %u mec=%d", (unsigned)nsegs, mec
+ ns2 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b2, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ ); $? ". after ns2 %u mec=%d", (unsigned)ns2, mec
+ if(drw->minspp > nsegs) { nsegs = drw->minspp; }
+ if(drw->minspp > ns2) { ns2 = drw->minspp; }
+#if TRACE_DEBUG
+ np = 2 * (nsegs + ns2); $? ". np = %u", (unsigned)np
+#endif
+ np = dk3mem_mul_size_t(2, dk3mem_add_size_t(nsegs, ns2, &mec), &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 5,
+ obj->lw, obj->pc, 7, 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1;
+ /* Arrowhead front point */
+ sp[nsegs + ns2 - 1].x = (obj->dt).arc.ra * cos(a0);
+ sp[nsegs + ns2 - 1].y = (obj->dt).arc.ra * sin(a0);
+ sp[nsegs + ns2 - 1].s = 0.0;
+ $? ". point %u %lg %lg %lg", (unsigned)(nsegs + ns2 - 1), sp[nsegs + ns2 - 1].x, sp[nsegs + ns2 - 1].y, sp[nsegs + ns2 - 1].s
+ /* Outer edges of arrowhead */
+ for(i = 0; i < nsegs; i++) {
+ j = i + 1;
+ if(j == nsegs) {
+ ga = a0 + f * b1;
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra, (0.5 * ah->wi), &mec
+ );
+ r2 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra, (0.5 * ah->wi), &mec
+ );
+ sp[nsegs + ns2 - 1 - j].s = 0.0;
+ sp[nsegs + ns2 - 1 + j].s = 0.0;
+ } else {
+ ga = a0 + f * b1 * ((double)j / (double)nsegs);
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * ((double)j / (double)nsegs)),
+ &mec
+ );
+ r2 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * ((double)j / (double)nsegs)),
+ &mec
+ );
+ sp[nsegs + ns2 - 1 - j].s = -1.0;
+ sp[nsegs + ns2 - 1 + j].s = -1.0;
+ }
+ sp[nsegs + ns2 - 1 - j].x = r1 * cos(ga);
+ sp[nsegs + ns2 - 1 - j].y = r1 * sin(ga);
+ sp[nsegs + ns2 - 1 + j].x = r2 * cos(ga);
+ sp[nsegs + ns2 - 1 + j].y = r2 * sin(ga);
+ $? ". point %u %lg %lg %lg", (unsigned)(nsegs + ns2 - 1 - j), sp[nsegs + ns2 - 1 - j].x, sp[nsegs + ns2 - 1 - j].y, sp[nsegs + ns2 - 1 - j].s
+ $? ". point %u %lg %lg %lg", (unsigned)(nsegs + ns2 - 1 + j), sp[nsegs + ns2 - 1 + j].x, sp[nsegs + ns2 - 1 + j].y, sp[nsegs + ns2 - 1 + j].s
+ }
+ /* Inner edges of arrowhead */
+ for(i = 0; i < (ns2 - 1); i++) {
+ j = i + 1;
+ ga = a0 + f * (b1 - b2 * ((double)j / (double)ns2));
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * (1.0 - ((double)j / (double)ns2))),
+ &mec
+ );
+ r2 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * (1.0 - ((double)j / (double)ns2))),
+ &mec
+ );
+ sp[ns2 - 1 - j].x = r1 * cos(ga);
+ sp[ns2 - 1 - j].y = r1 * sin(ga);
+ sp[ns2 - 1 - j].s = -1.0;
+ sp[2 * nsegs + ns2 - 1 + j].x = r2 * cos(ga);
+ sp[2 * nsegs + ns2 - 1 + j].y = r2 * sin(ga);
+ sp[2 * nsegs + ns2 - 1 + j].s = -1.0;
+ $? ". point %u %lg %lg %lg", (unsigned)(ns2 - 1 - j), sp[ns2 - 1 - j].x, sp[ns2 - 1 - j].y, sp[ns2 - 1 - j].s
+ $? ". point %u %lg %lg %lg", (unsigned)(2 * nsegs + ns2 - 1 + j), sp[2 * nsegs + ns2 - 1 + j].x, sp[2 * nsegs + ns2 - 1 + j].y, sp[2 * nsegs + ns2 - 1 + j].s
+ }
+ /* Inner arrowhead front point */
+ ga = a0 + f * (b1 - b2);
+ r1 = (obj->dt).arc.ra;
+ sp[2 * (nsegs + ns2) - 1].x = r1 * cos(ga);
+ sp[2 * (nsegs + ns2) - 1].y = r1 * sin(ga);
+ sp[2 * (nsegs + ns2) - 1].s = 0.0;
+ $? ". point %u %lg %lg %lg", (unsigned)(2 * (nsegs + ns2) - 1), sp[2 * (nsegs + ns2) - 1].x, sp[2 * (nsegs + ns2) - 1].y, sp[2 * (nsegs + ns2) - 1].s
+ /* Shift all points */
+ for(i = 0; i < np; i++) {
+ dk3fig_tool_shift_spoint(
+ &(sp[i]), (obj->dt).arc.xc, (obj->dt).arc.yc, &mec
+ );
+ }
+ if(ah->af) {
+ ao1->fc = obj->pc;
+ } $!trace-code dk3figah_report_spline_points(sp, np);
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ }
+ } else {
+ /* ##### ERROR: Arrowhead too long! */
+ }
+ } break;
+ case DK3_FIG_AS_POINTED: {
+ b1 = dk3ma_d_div_ok(
+ dk3ma_d_mul_ok(0.75, ah->he, &mec),
+ (obj->dt).arc.ra, &mec
+ );
+ b2 = dk3ma_d_div_ok((0.25 * ah->he), (obj->dt).arc.ra, &mec);
+ if((b1 < (2.0 * M_PI)) && (b2 < (2.0 * M_PI))) { $? ". nsegs"
+ nsegs = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b1, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ ); $? ". after nsegs %u mec=%d", (unsigned)nsegs, mec
+ ns2 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b2, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ ); $? ". after ns2 %u mec=%d", (unsigned)ns2, mec
+ if(drw->minspp > nsegs) { nsegs = drw->minspp; }
+ if(drw->minspp > ns2) { ns2 = drw->minspp; }
+#if TRACE_DEBUG
+ np = 2 * (nsegs + ns2); $? ". np = %u", (unsigned)np
+#endif
+ np = dk3mem_mul_size_t(2, dk3mem_add_size_t(nsegs, ns2, &mec), &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la,
+ DK3_FIG_OBJ_SPLINE, 5,
+ obj->lw, obj->pc, 7, 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1;
+ /* Arrowhead front point */
+ sp[nsegs + ns2 - 1].x = (obj->dt).arc.ra * cos(a0);
+ sp[nsegs + ns2 - 1].y = (obj->dt).arc.ra * sin(a0);
+ sp[nsegs + ns2 - 1].s = 0.0;
+ $? ". point %u %lg %lg %lg", (unsigned)(nsegs + ns2 - 1), sp[nsegs + ns2 - 1].x, sp[nsegs + ns2 - 1].y, sp[nsegs + ns2 - 1].s
+ /* Outer edges of arrowhead */
+ for(i = 0; i < nsegs; i++) {
+ j = i + 1;
+ if(j == nsegs) {
+ ga = a0 + f * b1;
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra, (0.5 * ah->wi), &mec
+ );
+ r2 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra, (0.5 * ah->wi), &mec
+ );
+ sp[nsegs + ns2 - 1 - j].s = 0.0;
+ sp[nsegs + ns2 - 1 + j].s = 0.0;
+ } else {
+ ga = a0 + f * b1 * ((double)j / (double)nsegs);
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * ((double)j / (double)nsegs)),
+ &mec
+ );
+ r2 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * ((double)j / (double)nsegs)),
+ &mec
+ );
+ sp[nsegs + ns2 - 1 - j].s = -1.0;
+ sp[nsegs + ns2 - 1 + j].s = -1.0;
+ }
+ sp[nsegs + ns2 - 1 - j].x = r1 * cos(ga);
+ sp[nsegs + ns2 - 1 - j].y = r1 * sin(ga);
+ sp[nsegs + ns2 - 1 + j].x = r2 * cos(ga);
+ sp[nsegs + ns2 - 1 + j].y = r2 * sin(ga);
+ $? ". point %u %lg %lg %lg", (unsigned)(nsegs + ns2 - 1 - j), sp[nsegs + ns2 - 1 - j].x, sp[nsegs + ns2 - 1 - j].y, sp[nsegs + ns2 - 1 - j].s
+ $? ". point %u %lg %lg %lg", (unsigned)(nsegs + ns2 - 1 + j), sp[nsegs + ns2 - 1 + j].x, sp[nsegs + ns2 - 1 + j].y, sp[nsegs + ns2 - 1 + j].s
+ }
+ /* Inner edges of arrowhead */
+ for(i = 0; i < (ns2 - 1); i++) {
+ j = i + 1;
+ ga = a0 + f * (b1 + b2 * ((double)j / (double)ns2));
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * (1.0 - ((double)j / (double)ns2))),
+ &mec
+ );
+ r2 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * (1.0 - ((double)j / (double)ns2))),
+ &mec
+ );
+ sp[ns2 - 1 - j].x = r1 * cos(ga);
+ sp[ns2 - 1 - j].y = r1 * sin(ga);
+ sp[ns2 - 1 - j].s = -1.0;
+ sp[2 * nsegs + ns2 - 1 + j].x = r2 * cos(ga);
+ sp[2 * nsegs + ns2 - 1 + j].y = r2 * sin(ga);
+ sp[2 * nsegs + ns2 - 1 + j].s = -1.0;
+ $? ". point %u %lg %lg %lg", (unsigned)(ns2 - 1 - j), sp[ns2 - 1 - j].x, sp[ns2 - 1 - j].y, sp[ns2 - 1 - j].s
+ $? ". point %u %lg %lg %lg", (unsigned)(2 * nsegs + ns2 - 1 + j), sp[2 * nsegs + ns2 - 1 + j].x, sp[2 * nsegs + ns2 - 1 + j].y, sp[2 * nsegs + ns2 - 1 + j].s
+ }
+ /* Inner arrowhead front point */
+ ga = a0 + f * (b1 + b2);
+ r1 = (obj->dt).arc.ra;
+ sp[2 * (nsegs + ns2) - 1].x = r1 * cos(ga);
+ sp[2 * (nsegs + ns2) - 1].y = r1 * sin(ga);
+ sp[2 * (nsegs + ns2) - 1].s = 0.0;
+ $? ". point %u %lg %lg %lg", (unsigned)(2 * (nsegs + ns2) - 1), sp[2 * (nsegs + ns2) - 1].x, sp[2 * (nsegs + ns2) - 1].y, sp[2 * (nsegs + ns2) - 1].s
+ /* Shift all points */
+ for(i = 0; i < np; i++) {
+ dk3fig_tool_shift_spoint(
+ &(sp[i]), (obj->dt).arc.xc, (obj->dt).arc.yc, &mec
+ );
+ }
+ if(ah->af) {
+ ao1->fc = obj->pc;
+ } $!trace-code dk3figah_report_spline_points(sp, np);
+ }
+ }
+ }
+ } else {
+ /* ##### ERROR: Arrowhead too long! */
+ }
+ } break;
+ case DK3_FIG_AS_RHOMBUS: {
+ if((1 == ah->af) && (DK3_FIG_SRCTYPE_JFIG == drw->srctype)) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la,
+ DK3_FIG_OBJ_ELLIPSE, 3,
+ obj->lw, obj->pc, obj->pc, 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, 0, NULL, drw->app
+ );
+ if(ao1) {
+ back = 1;
+ ah->o1 = (void *)ao1;
+ (ao1->dt).ell.an = 0.0;
+ (ao1->dt).ell.cx = dk3ma_d_add_ok(
+ (obj->dt).arc.xc,
+ ((obj->dt).arc.ra * cos(a0)),
+ &mec
+ );
+ (ao1->dt).ell.cy = dk3ma_d_add_ok(
+ (obj->dt).arc.yc,
+ ((obj->dt).arc.ra * sin(a0)),
+ &mec
+ );
+ (ao1->dt).ell.rx = dk3ma_d_mul_ok(2.0, ah->wi, &mec);
+ (ao1->dt).ell.ry = (ao1->dt).ell.rx;
+ }
+ } else {
+ b1 = dk3ma_d_div_ok(
+ dk3ma_d_mul_ok(0.5, ah->he, &mec),
+ (obj->dt).arc.ra, &mec
+ );
+ b2 = b1;
+ if((b1 < (2.0 * M_PI)) && (b2 < (2.0 * M_PI))) { $? ". nsegs"
+ nsegs = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b1, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ ); $? ". after nsegs %u mec=%d", (unsigned)nsegs, mec
+ ns2 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b2, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ ); $? ". after ns2 %u mec=%d", (unsigned)ns2, mec
+ if(drw->minspp > nsegs) { nsegs = drw->minspp; }
+ if(drw->minspp > ns2) { ns2 = drw->minspp; }
+#if TRACE_DEBUG
+ np = 2 * (nsegs + ns2); $? ". np = %u", (unsigned)np
+#endif
+ np = dk3mem_mul_size_t(2, dk3mem_add_size_t(nsegs, ns2, &mec), &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la,
+ DK3_FIG_OBJ_SPLINE, 5,
+ obj->lw, obj->pc, 7, 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1;
+ /* Arrowhead front point */
+ sp[nsegs + ns2 - 1].x = (obj->dt).arc.ra * cos(a0);
+ sp[nsegs + ns2 - 1].y = (obj->dt).arc.ra * sin(a0);
+ sp[nsegs + ns2 - 1].s = 0.0;
+ $? ". point %u %lg %lg %lg", (unsigned)(nsegs + ns2 - 1), sp[nsegs + ns2 - 1].x, sp[nsegs + ns2 - 1].y, sp[nsegs + ns2 - 1].s
+ /* Outer edges of arrowhead */
+ for(i = 0; i < nsegs; i++) {
+ j = i + 1;
+ if(j == nsegs) {
+ ga = a0 + f * b1;
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra, (0.5 * ah->wi), &mec
+ );
+ r2 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra, (0.5 * ah->wi), &mec
+ );
+ sp[nsegs + ns2 - 1 - j].s = 0.0;
+ sp[nsegs + ns2 - 1 + j].s = 0.0;
+ } else {
+ ga = a0 + f * b1 * ((double)j / (double)nsegs);
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * ((double)j / (double)nsegs)),
+ &mec
+ );
+ r2 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * ((double)j / (double)nsegs)),
+ &mec
+ );
+ sp[nsegs + ns2 - 1 - j].s = -1.0;
+ sp[nsegs + ns2 - 1 + j].s = -1.0;
+ }
+ sp[nsegs + ns2 - 1 - j].x = r1 * cos(ga);
+ sp[nsegs + ns2 - 1 - j].y = r1 * sin(ga);
+ sp[nsegs + ns2 - 1 + j].x = r2 * cos(ga);
+ sp[nsegs + ns2 - 1 + j].y = r2 * sin(ga);
+ $? ". point %u %lg %lg %lg", (unsigned)(nsegs + ns2 - 1 - j), sp[nsegs + ns2 - 1 - j].x, sp[nsegs + ns2 - 1 - j].y, sp[nsegs + ns2 - 1 - j].s
+ $? ". point %u %lg %lg %lg", (unsigned)(nsegs + ns2 - 1 + j), sp[nsegs + ns2 - 1 + j].x, sp[nsegs + ns2 - 1 + j].y, sp[nsegs + ns2 - 1 + j].s
+ }
+ /* Inner edges of arrowhead */
+ for(i = 0; i < (ns2 - 1); i++) {
+ j = i + 1;
+ ga = a0 + f * (b1 + b2 * ((double)j / (double)ns2));
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * (1.0 - ((double)j / (double)ns2))),
+ &mec
+ );
+ r2 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * (1.0 - ((double)j / (double)ns2))),
+ &mec
+ );
+ sp[ns2 - 1 - j].x = r1 * cos(ga);
+ sp[ns2 - 1 - j].y = r1 * sin(ga);
+ sp[ns2 - 1 - j].s = -1.0;
+ sp[2 * nsegs + ns2 - 1 + j].x = r2 * cos(ga);
+ sp[2 * nsegs + ns2 - 1 + j].y = r2 * sin(ga);
+ sp[2 * nsegs + ns2 - 1 + j].s = -1.0;
+ $? ". point %u %lg %lg %lg", (unsigned)(ns2 - 1 - j), sp[ns2 - 1 - j].x, sp[ns2 - 1 - j].y, sp[ns2 - 1 - j].s
+ $? ". point %u %lg %lg %lg", (unsigned)(2 * nsegs + ns2 - 1 + j), sp[2 * nsegs + ns2 - 1 + j].x, sp[2 * nsegs + ns2 - 1 + j].y, sp[2 * nsegs + ns2 - 1 + j].s
+ }
+ /* Inner arrowhead front point */
+ ga = a0 + f * (b1 + b2);
+ r1 = (obj->dt).arc.ra;
+ sp[2 * (nsegs + ns2) - 1].x = r1 * cos(ga);
+ sp[2 * (nsegs + ns2) - 1].y = r1 * sin(ga);
+ sp[2 * (nsegs + ns2) - 1].s = 0.0;
+ $? ". point %u %lg %lg %lg", (unsigned)(2 * (nsegs + ns2) - 1), sp[2 * (nsegs + ns2) - 1].x, sp[2 * (nsegs + ns2) - 1].y, sp[2 * (nsegs + ns2) - 1].s
+ /* Shift all points */
+ for(i = 0; i < np; i++) {
+ dk3fig_tool_shift_spoint(
+ &(sp[i]), (obj->dt).arc.xc, (obj->dt).arc.yc, &mec
+ );
+ }
+ if(ah->af) {
+ ao1->fc = obj->pc;
+ } $!trace-code dk3figah_report_spline_points(sp, np);
+ }
+ }
+ }
+ } else {
+ /* ##### ERROR: Arrowhead too long! */
+ }
+ }
+ } break;
+ case DK3_FIG_AS_FULL_CIRCLE_END: {
+ b1 = dk3figah_arc_correction(
+ (obj->dt).arc.ra,
+ dk3ma_d_add_ok(
+ (0.5 * ah->he),
+ (0.5 * dk3fig_tool_get_lw(drw, obj, &mec)),
+ &mec
+ ),
+ &mec
+ );
+ if(0.0 <= b1) {
+#if 0
+ b1 = a0 + f * b1;
+#else
+ b1 = a1 + f * b1;
+#endif
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la,
+ DK3_FIG_OBJ_ELLIPSE, 3,
+ obj->lw, obj->pc, 7, 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, 0, NULL, drw->app
+ );
+ if(ao1) {
+ back = 1;
+ ah->o1 = (void *)ao1;
+ (ao1->dt).ell.an = 0.0;
+ (ao1->dt).ell.cx = dk3ma_d_add_ok(
+ (obj->dt).arc.xc,
+ ((obj->dt).arc.ra * cos(b1)),
+ &mec
+ );
+ (ao1->dt).ell.cy = dk3ma_d_add_ok(
+ (obj->dt).arc.yc,
+ ((obj->dt).arc.ra * sin(b1)),
+ &mec
+ );
+ (ao1->dt).ell.rx = 0.5 * ah->he;
+ (ao1->dt).ell.ry = 0.5 * ah->he;
+ if(ah->af) {
+ ao1->fc = obj->pc;
+ }
+ }
+ } else {
+ mec = DK3_ERROR_MATH_OUT_OF_RANGE;
+ }
+ } break;
+ case DK3_FIG_AS_HALF_CIRCLE_END: {
+ pp.x = (obj->dt).arc.ra * cos(a1);
+ pp.y = (obj->dt).arc.ra * sin(a1);
+ pp.x = dk3ma_d_add_ok(pp.x, (obj->dt).arc.xc, &mec);
+ pp.y = dk3ma_d_add_ok(pp.y, (obj->dt).arc.yc, &mec);
+ if(ah->af) {
+ s = 0.5 * dk3fig_tool_get_lw(drw, obj, ec);
+ pp.x = dk3ma_d_sub_ok(
+ pp.x,
+ (s * cos(phi)),
+ &mec
+ );
+ pp.y = dk3ma_d_sub_ok(
+ pp.y,
+ (s * sin(phi)),
+ &mec
+ );
+ }
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la,
+ DK3_FIG_OBJ_PSEUDO_HALF_CIRCLE, ((ah->af) ? 1 : 0),
+ obj->lw, obj->pc, ((ah->af) ? obj->pc : 7), 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, 0, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ back = 1;
+ (ao1->dt).hci.cx = pp.x;
+ (ao1->dt).hci.cy = pp.y;
+ (ao1->dt).hci.ra = 0.5 * ah->he;
+ (ao1->dt).hci.an = phi;
+ }
+ } break;
+ case DK3_FIG_AS_RECTANGLE: {
+ b1 = dk3ma_d_div_ok(ah->he, (obj->dt).arc.ra, &mec);
+ if(b1 < (2.0 * M_PI)) { $? ". nsegs"
+ nsegs = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b1, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ );
+ if(drw->minspp > nsegs) {
+ nsegs = drw->minspp;
+ } $? ". nsegs = %u", (unsigned)nsegs
+#if TRACE_DEBUG
+ np = 2 * nsegs + 2; $? ". np = %u", (unsigned)np
+#endif
+ np = dk3mem_add_size_t(dk3mem_mul_size_t(2, nsegs, &mec), 2, &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la,
+ DK3_FIG_OBJ_SPLINE, 5,
+ obj->lw, obj->pc, ((ah->af) ? obj->pc : 7), 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ r1 = dk3ma_d_add_ok((obj->dt).arc.ra, (0.5 * ah->wi), &mec);
+ r2 = dk3ma_d_sub_ok((obj->dt).arc.ra, (0.5 * ah->wi), &mec);
+ back = 1;
+ for(i = 0; i < nsegs; i++) {
+ if(0 == i) {
+ ga = a0;
+ sp[i].s = 0.0;
+ sp[np - 1 - i].s = 0.0;
+ } else {
+ ga = a0 + f * b1 * ((double)i / (double)nsegs);
+ sp[i].s = -1.0;
+ sp[np - 1 - i].s = -1.0;
+ }
+ sp[i].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r1 * cos(ga)), &mec
+ );
+ sp[i].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r1 * sin(ga)), &mec
+ );
+ sp[np - 1 - i].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r2 * cos(ga)), &mec
+ );
+ sp[np - 1 - i].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r2 * sin(ga)), &mec
+ );
+ $? ". point %u", (unsigned)i
+ $? ". point %u", (unsigned)(np - 1 - i)
+ }
+ ga = a0 + f * b1;
+ sp[nsegs].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r1 * cos(ga)), &mec
+ );
+ sp[nsegs].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r1 * sin(ga)), &mec
+ );
+ sp[nsegs].s = 0.0;
+ sp[nsegs + 1].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r2 * cos(ga)), &mec
+ );
+ sp[nsegs + 1].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r2 * sin(ga)), &mec
+ );
+ sp[nsegs + 1].s = 0.0;
+ $? ". point %u", (unsigned)nsegs
+ $? ". point %u", (unsigned)(nsegs + 1)
+ $!trace-code dk3figah_report_spline_points(sp, np);
+ }
+ }
+ }
+ } else {
+ /* ##### ERROR: Arrowhead too long! */
+ }
+ } break;
+ case DK3_FIG_AS_INVERSE: {
+ b1 = dk3ma_d_div_ok(ah->he, (obj->dt).arc.ra, &mec);
+ if(b1 < (2.0 * M_PI)) { $? ". nsegs"
+ nsegs = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b1, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ ); $? ". nsegs = %u", (unsigned)nsegs
+ if(drw->minspp > nsegs) { nsegs = drw->minspp; }
+ np = dk3mem_add_size_t(dk3mem_mul_size_t(2, nsegs, &mec), 1, &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 5,
+ obj->lw, obj->pc, ((ah->af) ? obj->pc : 7), 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1;
+ sp[0].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, ((obj->dt).arc.ra * cos(a0 + f * b1)), &mec
+ );
+ sp[0].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, ((obj->dt).arc.ra * sin(a0 + f * b1)), &mec
+ );
+ sp[0].s = 0.0; $? ". point 0"
+ for(i = 0; i < nsegs; i++) {
+ j = i + 1;
+ r1 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * ((double)j / (double)nsegs)),
+ &mec
+ );
+ r2 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * ((double)j / (double)nsegs)),
+ &mec
+ );
+ ga = (
+ (j == nsegs)
+ ? (a0)
+ : (a0 + f * b1 * (1.0 - ((double)j / (double)nsegs)))
+ );
+ sp[j].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r1 * cos(ga)), &mec
+ );
+ sp[j].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r1 * sin(ga)), &mec
+ ); $? ". point %u", (unsigned)j
+ sp[j].s = ((j == nsegs) ? 0.0 : (-1.0));
+ sp[np - 1 - i].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r2 * cos(ga)), &mec
+ );
+ sp[np - 1 - i].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r2 * sin(ga)), &mec
+ ); $? ". point %u", (unsigned)(np - 1 - i)
+ sp[np - 1 - i].s = ((j == nsegs) ? 0.0 : (-1.0));
+ } $!trace-code dk3figah_report_spline_points(sp, np);
+ }
+ }
+ }
+ } else {
+ /* ##### ERROR: Arrowhead too long! */
+ }
+ } break;
+ case DK3_FIG_AS_INDENTED_FILLED_HALF: {
+ if(ah->af) {
+ if(ab) { mustadd = 1; }
+ } else {
+ if(!(ab)) { mustadd = 1; }
+ }
+ b1 = dk3ma_d_div_ok(
+ dk3ma_d_mul_ok(1.25, ah->he, &mec),
+ (obj->dt).arc.ra, &mec
+ );
+ b2 = dk3ma_d_div_ok((0.25 * ah->he), (obj->dt).arc.ra, &mec);
+ b3 = dk3ma_d_div_ok(ah->he, (obj->dt).arc.ra, &mec);
+ if((b1 < (2.0 * M_PI)) && (b2 < (2.0 * M_PI)) && (b3 < (2.0 * M_PI))) {
+ $? ". nsegs"
+ nsegs = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b1, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ ); $? ". after nsegs %u mec=%d", (unsigned)nsegs, mec
+ ns2 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b2, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ ); $? ". after ns2 %u mec=%d", (unsigned)ns2, mec
+ ns3 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b3, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ );
+ if(drw->minspp > nsegs) { nsegs = drw->minspp; }
+ if(drw->minspp > ns2) { ns2 = drw->minspp; }
+ if(drw->minspp > ns3) { ns3 = drw->minspp; }
+ np = dk3mem_mul_size_t(2, dk3mem_add_size_t(nsegs, ns2, &mec), &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la,
+ DK3_FIG_OBJ_SPLINE, 5,
+ obj->lw, obj->pc, 7, 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ /* Arrowhead front point */
+ sp[nsegs + ns2 - 1].x = (obj->dt).arc.ra * cos(a0);
+ sp[nsegs + ns2 - 1].y = (obj->dt).arc.ra * sin(a0);
+ sp[nsegs + ns2 - 1].s = 0.0;
+ $? ". point %u %lg %lg %lg", (unsigned)(nsegs + ns2 - 1), sp[nsegs + ns2 - 1].x, sp[nsegs + ns2 - 1].y, sp[nsegs + ns2 - 1].s
+ /* Outer edges of arrowhead */
+ for(i = 0; i < nsegs; i++) {
+ j = i + 1;
+ if(j == nsegs) {
+ ga = a0 + f * b1;
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra, (0.5 * ah->wi), &mec
+ );
+ r2 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra, (0.5 * ah->wi), &mec
+ );
+ sp[nsegs + ns2 - 1 - j].s = 0.0;
+ sp[nsegs + ns2 - 1 + j].s = 0.0;
+ } else {
+ ga = a0 + f * b1 * ((double)j / (double)nsegs);
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * ((double)j / (double)nsegs)),
+ &mec
+ );
+ r2 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * ((double)j / (double)nsegs)),
+ &mec
+ );
+ sp[nsegs + ns2 - 1 - j].s = -1.0;
+ sp[nsegs + ns2 - 1 + j].s = -1.0;
+ }
+ sp[nsegs + ns2 - 1 - j].x = r1 * cos(ga);
+ sp[nsegs + ns2 - 1 - j].y = r1 * sin(ga);
+ sp[nsegs + ns2 - 1 + j].x = r2 * cos(ga);
+ sp[nsegs + ns2 - 1 + j].y = r2 * sin(ga);
+ $? ". point %u %lg %lg %lg", (unsigned)(nsegs + ns2 - 1 - j), sp[nsegs + ns2 - 1 - j].x, sp[nsegs + ns2 - 1 - j].y, sp[nsegs + ns2 - 1 - j].s
+ $? ". point %u %lg %lg %lg", (unsigned)(nsegs + ns2 - 1 + j), sp[nsegs + ns2 - 1 + j].x, sp[nsegs + ns2 - 1 + j].y, sp[nsegs + ns2 - 1 + j].s
+ }
+ /* Inner edges of arrowhead */
+ for(i = 0; i < (ns2 - 1); i++) {
+ j = i + 1;
+ ga = a0 + f * (b1 - b2 * ((double)j / (double)ns2));
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * (1.0 - ((double)j / (double)ns2))),
+ &mec
+ );
+ r2 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * (1.0 - ((double)j / (double)ns2))),
+ &mec
+ );
+ sp[ns2 - 1 - j].x = r1 * cos(ga);
+ sp[ns2 - 1 - j].y = r1 * sin(ga);
+ sp[ns2 - 1 - j].s = -1.0;
+ sp[2 * nsegs + ns2 - 1 + j].x = r2 * cos(ga);
+ sp[2 * nsegs + ns2 - 1 + j].y = r2 * sin(ga);
+ sp[2 * nsegs + ns2 - 1 + j].s = -1.0;
+ $? ". point %u %lg %lg %lg", (unsigned)(ns2 - 1 - j), sp[ns2 - 1 - j].x, sp[ns2 - 1 - j].y, sp[ns2 - 1 - j].s
+ $? ". point %u %lg %lg %lg", (unsigned)(2 * nsegs + ns2 - 1 + j), sp[2 * nsegs + ns2 - 1 + j].x, sp[2 * nsegs + ns2 - 1 + j].y, sp[2 * nsegs + ns2 - 1 + j].s
+ }
+ /* Inner arrowhead front point */
+ ga = a0 + f * (b1 - b2);
+ r1 = (obj->dt).arc.ra;
+ sp[2 * (nsegs + ns2) - 1].x = r1 * cos(ga);
+ sp[2 * (nsegs + ns2) - 1].y = r1 * sin(ga);
+ sp[2 * (nsegs + ns2) - 1].s = 0.0;
+ $? ". point %u %lg %lg %lg", (unsigned)(2 * (nsegs + ns2) - 1), sp[2 * (nsegs + ns2) - 1].x, sp[2 * (nsegs + ns2) - 1].y, sp[2 * (nsegs + ns2) - 1].s
+ /* Shift all points */
+ for(i = 0; i < np; i++) {
+ dk3fig_tool_shift_spoint(
+ &(sp[i]), (obj->dt).arc.xc, (obj->dt).arc.yc, &mec
+ );
+ } $!trace-code dk3figah_report_spline_points(sp, np);
+ np = dk3mem_add_size_t(nsegs, dk3mem_add_size_t(ns2, ns3, &mec), &mec);
+ if(0 == mec) {
+ ao2 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 5,
+ 0, obj->pc, obj->pc, 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao2) { $? ". points %u", (unsigned)np
+ ah->o2 = (void *)ao2;
+ sp = (ao2->dt).spl.po;
+ if(sp) {
+ back = 1;
+ sp[0].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, ((obj->dt).arc.ra * cos(a0)), &mec
+ );
+ sp[0].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, ((obj->dt).arc.ra * sin(a0)), &mec
+ );
+ sp[0].s = 0.0; $? ". point 0"
+ /* Outer edge */
+ for(i = 0; i < nsegs; i++) {
+ j = i + 1;
+ if(j == nsegs) {
+ if(mustadd) {
+ r1 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra, (0.5 * ah->wi), &mec
+ );
+ } else {
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra, (0.5 * ah->wi), &mec
+ );
+ }
+ ga = a0 + f * b1;
+ } else {
+ if(mustadd) {
+ r1 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ((double)j / (double)nsegs) * ah->wi),
+ &mec
+ );
+ } else {
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ((double)j / (double)nsegs) * ah->wi),
+ &mec
+ );
+ }
+ ga = a0 + f * b1 * ((double)j / (double)nsegs);
+ }
+ sp[j].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r1 * cos(ga)), &mec
+ );
+ sp[j].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r1 * sin(ga)), &mec
+ ); $? ". point %u", (unsigned)j
+ sp[j].s = ((j == nsegs) ? 0.0 : (-1.0));
+ }
+ /* Indention edge */
+ for(i = 0; i < ns2; i++) {
+ j = i + 1;
+ if(j == ns2) {
+ r1 = (obj->dt).arc.ra;
+ ga = a0 + f * (b1 - b2);
+ } else {
+ if(mustadd) {
+ r1 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * (1.0 - ((double)j / (double)nsegs))),
+ &mec
+ );
+ } else {
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ah->wi * (1.0 - ((double)j / (double)nsegs))),
+ &mec
+ );
+ }
+ ga = a0 + f * (b1 - ((double)j / (double)nsegs) * b2);
+ }
+ sp[nsegs + j].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r1 * cos(ga)), &mec
+ );
+ sp[nsegs + j].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r1 * sin(ga)), &mec
+ ); $? ". point %u", (unsigned)(nsegs + j)
+ sp[nsegs + j].s = ((j == ns2) ? 0.0 : (-1.0));
+ }
+ /* Inner edge */
+ for(i = 0; i < (ns3 - 1); i++) {
+ j = i + 1;
+ ga = a0 + f *(b1 - b2 - b3 * ((double)j / (double)nsegs));
+ sp[nsegs + ns2 + j].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, ((obj->dt).arc.ra * cos(ga)), &mec
+ );
+ sp[nsegs + ns2 + j].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, ((obj->dt).arc.ra * sin(ga)), &mec
+ ); $? ". point %u", (unsigned)(nsegs + ns2 + j)
+ sp[nsegs + ns2 + j].s = -1.0;
+ } $!trace-code dk3figah_report_spline_points(sp, np);
+ }
+ }
+ }
+ }
+ }
+ }
+ } else {
+ /* ##### ERROR: Arrowhead too long! */
+ }
+ } break;
+ case DK3_FIG_AS_CLOSED_HALF: {
+ b1 = dk3ma_d_div_ok(ah->he, (obj->dt).arc.ra, &mec);
+ if(b1 < (2.0 * M_PI)) { $? ". nsegs"
+ nsegs = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b1, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ );
+ if(drw->minspp > nsegs) { nsegs = drw->minspp; }
+ np = dk3mem_add_size_t(dk3mem_mul_size_t(2, nsegs, &mec), 1, &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 5,
+ obj->lw, obj->pc, ((ah->af) ? obj->pc : 7), 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1;
+ sp[0].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, ((obj->dt).arc.ra * cos(a0)), &mec
+ );
+ sp[0].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, ((obj->dt).arc.ra * sin(a0)), &mec
+ );
+ sp[0].s = 0.0;
+ for(i = 0; i < nsegs; i++) {
+ j = i + 1;
+ if(j == nsegs) {
+ ga = a0 + f * b1;
+ if(ab) {
+ r1 = dk3ma_d_add_ok((obj->dt).arc.ra, (0.5 * ah->wi), &mec);
+ } else {
+ r1 = dk3ma_d_sub_ok((obj->dt).arc.ra, (0.5 * ah->wi), &mec);
+ }
+ } else {
+ if(ab) {
+ r1 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ((double)j / (double)nsegs) * ah->wi),
+ &mec
+ );
+ } else {
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ((double)j / (double)nsegs) * ah->wi),
+ &mec
+ );
+ }
+ ga = a0 + f * b1 * ((double)j / (double)nsegs);
+ }
+ sp[j].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r1 * cos(ga)), &mec
+ );
+ sp[j].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r1 * sin(ga)), &mec
+ );
+ sp[j].s = ((j == nsegs) ? 0.0 : (-1.0));
+ sp[np - 1 - i].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, ((obj->dt).arc.ra * cos(ga)), &mec
+ );
+ sp[np - 1 - i].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, ((obj->dt).arc.ra * sin(ga)), &mec
+ );
+ sp[np - 1 - i].s = ((j == nsegs) ? 0.0 : (-1.0));
+ } $!trace-code dk3figah_report_spline_points(sp, np);
+ }
+ }
+ }
+ } else {
+ /* ##### ERROR: Arrowhead too long! */
+ }
+ } break;
+ case DK3_FIG_AS_INDENTED_HALF: {
+ b1 = dk3ma_d_div_ok(
+ dk3ma_d_mul_ok(1.25, ah->he, &mec), (obj->dt).arc.ra, &mec
+ );
+ b2 = dk3ma_d_div_ok((0.25 * ah->he), (obj->dt).arc.ra, &mec);
+ b3 = dk3ma_d_div_ok(ah->he, (obj->dt).arc.ra, &mec);
+ if((b1 < (2.0 * M_PI)) && (b2 < (2.0 * M_PI)) && (b3 < (2.0 * M_PI))) {
+ $? ". nsegs"
+ nsegs = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b1, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ ); $? ". after nsegs %u mec=%d", (unsigned)nsegs, mec
+ ns2 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b2, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ ); $? ". after ns2 %u mec=%d", (unsigned)ns2, mec
+ ns3 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b3, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ );
+ if(drw->minspp > nsegs) { nsegs = drw->minspp; }
+ if(drw->minspp > ns2) { ns2 = drw->minspp; }
+ if(drw->minspp > ns3) { ns3 = drw->minspp; }
+ np = dk3mem_add_size_t(dk3mem_add_size_t(nsegs, ns2, &mec), ns3, &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 5,
+ obj->lw, obj->pc, ((ah->af) ? obj->pc : 7), 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) { $? ". np = %u", (unsigned)np
+ back = 1;
+ /* front point */
+ sp[0].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, ((obj->dt).arc.ra * cos(a0)), &mec
+ );
+ sp[0].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, ((obj->dt).arc.ra * sin(a0)), &mec
+ ); $? ". point 0"
+ sp[0].s = 0.0;
+ /* outer edge */
+ for(i = 0; i < nsegs; i++) {
+ j = i + 1;
+ if(ab) {
+ r1 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ((double)j / (double)nsegs) * ah->wi),
+ &mec
+ );
+ } else {
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ((double)j / (double)nsegs) * ah->wi),
+ &mec
+ );
+ }
+ ga = a0 + f * b1 * ((double)j / (double)nsegs);
+ if(j == nsegs) {
+ if(ab) {
+ r1 = dk3ma_d_add_ok((obj->dt).arc.ra, (0.5 * ah->wi), &mec);
+ } else {
+ r1 = dk3ma_d_sub_ok((obj->dt).arc.ra, (0.5 * ah->wi), &mec);
+ }
+ ga = a0 + f * b1;
+ }
+ sp[j].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r1 * cos(ga)), &mec
+ );
+ sp[j].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r1 * sin(ga)), &mec
+ ); $? ". point %u", (unsigned)j
+ sp[j].s = ((j == nsegs) ? 0.0 : (-1.0));
+ }
+ /* indention edge */
+ for(i = 0; i < ns2; i++) {
+ j = i + 1;
+ if(ab) {
+ r1 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra,
+ (0.5 * (1.0 - ((double)j / (double)ns2)) * ah->wi),
+ &mec
+ );
+ } else {
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra,
+ (0.5 * (1.0 - ((double)j / (double)ns2)) * ah->wi),
+ &mec
+ );
+ }
+ ga = a0 + f * (b1 - b2 * ((double)j / (double)ns2));
+ if(j == ns2) {
+ r1 = (obj->dt).arc.ra;
+ ga = a0 + f * (b1 - b2);
+ }
+ sp[nsegs + j].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r1 * cos(ga)), &mec
+ );
+ sp[nsegs + j].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r1 * sin(ga)), &mec
+ ); $? ". point %u", (unsigned)(nsegs + j)
+ sp[nsegs + j].s = ((j == ns2) ? 0.0 : (-1.0));
+ }
+ /* inner edge */
+ for(i = 0; i < (ns3 - 1); i++) {
+ j = i + 1;
+ ga = a0 + f * (b1 - b2 - b3 * ((double)j / (double)ns3));
+ sp[nsegs + ns2 + j].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, ((obj->dt).arc.ra * cos(ga)), &mec
+ );
+ sp[nsegs + ns2 + j].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, ((obj->dt).arc.ra * sin(ga)), &mec
+ ); $? ". point %u", (unsigned)(nsegs + ns2 + j)
+ sp[nsegs + ns2 + j].s = -1.0;
+ } $!trace-code dk3figah_report_spline_points(sp, np);
+ }
+ }
+ }
+ } else {
+ /* ##### ERROR: Arrow too long */
+ }
+ } break;
+ case DK3_FIG_AS_BUTTED_HALF: {
+ b1 = dk3ma_d_div_ok(
+ (0.75 * ah->he), (obj->dt).arc.ra, &mec
+ );
+ b2 = dk3ma_d_div_ok((0.25 * ah->he), (obj->dt).arc.ra, &mec);
+ b3 = dk3ma_d_div_ok(ah->he, (obj->dt).arc.ra, &mec);
+ if((b1 < (2.0 * M_PI)) && (b2 < (2.0 * M_PI)) && (b3 < (2.0 * M_PI))) {
+ $? ". nsegs"
+ nsegs = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b1, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ ); $? ". after nsegs %u mec=%d", (unsigned)nsegs, mec
+ ns2 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b2, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ ); $? ". after ns2 %u mec=%d", (unsigned)ns2, mec
+ ns3 = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b3, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ );
+ if(drw->minspp > nsegs) { nsegs = drw->minspp; }
+ if(drw->minspp > ns2) { ns2 = drw->minspp; }
+ if(drw->minspp > ns3) { ns3 = drw->minspp; }
+ np = dk3mem_add_size_t(dk3mem_add_size_t(nsegs, ns2, &mec), ns3, &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 5,
+ obj->lw, obj->pc, ((ah->af) ? obj->pc : 7), 20,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) { $? ". np = %u", (unsigned)np
+ back = 1;
+ /* front point */
+ sp[0].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, ((obj->dt).arc.ra * cos(a0)), &mec
+ );
+ sp[0].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, ((obj->dt).arc.ra * sin(a0)), &mec
+ ); $? ". point 0"
+ sp[0].s = 0.0;
+ /* outer edge */
+ for(i = 0; i < nsegs; i++) {
+ j = i + 1;
+ if(ab) {
+ r1 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ((double)j / (double)nsegs) * ah->wi),
+ &mec
+ );
+ } else {
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ((double)j / (double)nsegs) * ah->wi),
+ &mec
+ );
+ }
+ ga = a0 + f * b1 * ((double)j / (double)nsegs);
+ if(j == nsegs) {
+ if(ab) {
+ r1 = dk3ma_d_add_ok((obj->dt).arc.ra, (0.5 * ah->wi), &mec);
+ } else {
+ r1 = dk3ma_d_sub_ok((obj->dt).arc.ra, (0.5 * ah->wi), &mec);
+ }
+ ga = a0 + f * b1;
+ }
+ sp[j].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r1 * cos(ga)), &mec
+ );
+ sp[j].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r1 * sin(ga)), &mec
+ ); $? ". point %u", (unsigned)j
+ sp[j].s = ((j == nsegs) ? 0.0 : (-1.0));
+ }
+ /* indention edge */
+ for(i = 0; i < ns2; i++) {
+ j = i + 1;
+ if(ab) {
+ r1 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra,
+ (0.5 * (1.0 - ((double)j / (double)ns2)) * ah->wi),
+ &mec
+ );
+ } else {
+ r1 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra,
+ (0.5 * (1.0 - ((double)j / (double)ns2)) * ah->wi),
+ &mec
+ );
+ }
+ ga = a0 + f * (b1 + b2 * ((double)j / (double)ns2));
+ if(j == ns2) {
+ r1 = (obj->dt).arc.ra;
+ ga = a0 + f * (b1 + b2);
+ }
+ sp[nsegs + j].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r1 * cos(ga)), &mec
+ );
+ sp[nsegs + j].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r1 * sin(ga)), &mec
+ ); $? ". point %u", (unsigned)(nsegs + j)
+ sp[nsegs + j].s = ((j == ns2) ? 0.0 : (-1.0));
+ }
+ /* inner edge */
+ for(i = 0; i < (ns3 - 1); i++) {
+ j = i + 1;
+ ga = a0 + f * (b1 + b2 - b3 * ((double)j / (double)ns3));
+ sp[nsegs + ns2 + j].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, ((obj->dt).arc.ra * cos(ga)), &mec
+ );
+ sp[nsegs + ns2 + j].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, ((obj->dt).arc.ra * sin(ga)), &mec
+ ); $? ". point %u", (unsigned)(nsegs + ns2 + j)
+ sp[nsegs + ns2 + j].s = -1.0;
+ } $!trace-code dk3figah_report_spline_points(sp, np);
+ }
+ }
+ }
+ } else {
+ /* ##### ERROR: Arrow too long */
+ }
+ } break;
+ case DK3_FIG_AS_TRIANGLE_FORK: {
+ if(ah->af) { $? ". before obj_new"
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_POLYLINE, 1,
+ obj->lw, obj->pc, obj->pc, -1,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, 2, NULL, drw->app
+ );
+ if(ao1) { $? ". after obj_new"
+ ah->o1 = (void *)ao1;
+ po = (ao1->dt).pol.po;
+ if(po) { $? ". points available"
+ back = 1;
+ r1 = dk3ma_d_add_ok((obj->dt).arc.ra, (0.5 * ah->wi), &mec);
+ r2 = dk3ma_d_sub_ok((obj->dt).arc.ra, (0.5 * ah->wi), &mec);
+ po[0].x = dk3ma_d_add_ok((obj->dt).arc.xc, (r1 * cos(a0)), &mec);
+ po[0].y = dk3ma_d_add_ok((obj->dt).arc.yc, (r1 * sin(a0)), &mec);
+ po[1].x = dk3ma_d_add_ok((obj->dt).arc.xc, (r2 * cos(a0)), &mec);
+ po[1].y = dk3ma_d_add_ok((obj->dt).arc.yc, (r2 * sin(a0)), &mec);
+ $? ". po[0] = %lg %lg", po[0].x, po[0].y
+ $? ". po[1] = %lg %lg", po[1].x, po[1].y
+ }
+ }
+ } else {
+ b1 = dk3ma_d_div_ok(ah->he, (obj->dt).arc.ra, &mec);
+ if(b1 < (2.0 * M_PI)) { $? ". nsegs"
+ nsegs = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b1, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ );
+ if(drw->minspp > nsegs) { nsegs = drw->minspp; }
+ np = dk3mem_add_size_t(dk3mem_mul_size_t(2, nsegs, &mec), 1, &mec);
+ if(0 == mec) {
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 4,
+ obj->lw, obj->pc, -1, -1,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1;
+ ga = a0 + f * b1;
+ sp[nsegs].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc,
+ ((obj->dt).arc.ra * cos(ga)),
+ &mec
+ );
+ sp[nsegs].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc,
+ ((obj->dt).arc.ra * sin(ga)),
+ &mec
+ );
+ sp[nsegs].s = 0.0;
+ for(i = 0; i < nsegs; i++) {
+ j = i + 1;
+ r1 = dk3ma_d_add_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ((double)j / (double)nsegs) * ah->wi),
+ &mec
+ );
+ r2 = dk3ma_d_sub_ok(
+ (obj->dt).arc.ra,
+ (0.5 * ((double)j / (double)nsegs) * ah->wi),
+ &mec
+ );
+ ga = a0 + f * b1 * (1.0 - ((double)j / (double)nsegs));
+ if(j == nsegs) {
+ r1 = dk3ma_d_add_ok((obj->dt).arc.ra, (0.5 * ah->wi), &mec);
+ r2 = dk3ma_d_sub_ok((obj->dt).arc.ra, (0.5 * ah->wi), &mec);
+ ga = a0;
+ }
+ sp[nsegs + j].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r1 * cos(ga)), &mec
+ );
+ sp[nsegs + j].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r1 * sin(ga)), &mec
+ );
+ sp[nsegs + j].s = ((j == nsegs) ? 0.0 : (-1.0));
+ sp[nsegs - j].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r2 * cos(ga)), &mec
+ );
+ sp[nsegs - j].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r2 * sin(ga)), &mec
+ );
+ sp[nsegs - j].s = ((j == nsegs) ? 0.0 : (-1.0));
+ }
+ }
+ }
+ }
+ } else {
+ /* ##### ERROR: Arrow too long! */
+ }
+ }
+ } break;
+ case DK3_FIG_AS_RECTANGLE_FORK: {
+ b1 = dk3ma_d_div_ok(ah->he, (obj->dt).arc.ra, &mec);
+ if(b1 < (2.0 * M_PI)) { $? ". nsegs"
+ nsegs = dk3ma_d_to_sz_ok(
+ ceil(dk3ma_d_mul_ok(b1, drw->arcspp, &mec) / M_PI_2),
+ &mec
+ ); $? ". after nsegs %u mec=%d", (unsigned)nsegs, mec
+ if(drw->minspp > nsegs) { nsegs = drw->minspp; }
+ np = dk3mem_mul_size_t(2, dk3mem_add_size_t(nsegs, 1, &mec), &mec);
+ if(0 == mec) { $? ". np = %u", (unsigned)np
+ ao1 = dk3fig_obj_new(
+ obj->li, obj->la, DK3_FIG_OBJ_SPLINE, 4,
+ obj->lw, obj->pc, obj->pc, -1,
+ DK3_FIG_LC_BUTT, DK3_FIG_LJ_MITER, DK3_FIG_LS_SOLID,
+ 1.0, 0, 0, np, NULL, drw->app
+ );
+ if(ao1) {
+ ah->o1 = (void *)ao1;
+ sp = (ao1->dt).spl.po;
+ if(sp) {
+ back = 1;
+ r1 = dk3ma_d_add_ok((obj->dt).arc.ra, (0.5 * ah->wi), &mec);
+ r2 = dk3ma_d_sub_ok((obj->dt).arc.ra, (0.5 * ah->wi), &mec);
+ if(ah->af) { $? ". closed front side"
+ ga = a0;
+ } else { $? ". open front side"
+ ga = a0 + f * b1;
+ }
+ sp[nsegs].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r1 * cos(ga)), &mec
+ );
+ sp[nsegs].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r1 * sin(ga)), &mec
+ ); $? ". point %u", (unsigned)nsegs
+ sp[nsegs].s = 0.0;
+ sp[nsegs + 1].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r2 * cos(ga)), &mec
+ );
+ sp[nsegs + 1].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r2 * sin(ga)), &mec
+ ); $? ". point %u", (unsigned)(nsegs + 1)
+ sp[nsegs + 1].s = 0.0;
+ for(i = 0; i < nsegs; i++) {
+ j = i + 1;
+ if(ah->af) {
+ ga = a0 + f * b1 * ((double)j / (double)nsegs);
+ } else {
+ ga = a0 + f * b1 * (1.0 - ((double)j / (double)nsegs));
+ }
+ sp[nsegs - j].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r1 * cos(ga)), &mec
+ );
+ sp[nsegs - j].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r1 * sin(ga)), &mec
+ ); $? ". point %u", (unsigned)(nsegs - j)
+ sp[nsegs - j].s = 0.0;
+ sp[nsegs + 1 + j].x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc, (r2 * cos(ga)), &mec
+ );
+ sp[nsegs + 1 + j].y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc, (r2 * sin(ga)), &mec
+ ); $? ". point %u", (unsigned)(nsegs + 1 + j)
+ sp[nsegs + 1 + j].s = 0.0;
+ }
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ }
+ } else {
+ /* ##### ERROR: Arrowhead too long! */
+ }
+ } break;
+ }
+ if(mec) { $? "! math problem"
+ back = 0;
+ if(ec) { *ec = mec; }
+ }
+ $? "- dk3figah_one_arc_arrowhead %d", back
+ return back;
+}
+
+
+
+/** Calculate arrowheads for arc.
+ @param drw Drawing to modify.
+ @param obj Object to modify.
+ @param objno Object number.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figah_calculate_arc(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ unsigned long objno
+)
+{
+ dk3_fig_poly_point_t sp;
+ double cuts = -1.0;
+ double cute = -1.0;
+ double das = 0.0;
+ double dae = 0.0;
+ double newas = 0.0;
+ double newae = 0.0;
+ double alphaf = 0.0;
+ double alphab = 0.0;
+ int back = 1;
+ int mec = 0;
+ int res = 0;
+ $? "+ dk3figah_calculate_arc"
+ /*
+ Construct arrowhead objects.
+ */
+ if(obj->af) {
+ cute = dk3figah_length_correction(drw, obj, obj->af, &mec);
+ }
+ if(obj->ab) {
+ cuts = dk3figah_length_correction(drw, obj, obj->ab, &mec);
+ } $? ". mec = %d", mec
+ /*
+ Create arrowhead objects.
+ */
+ if((obj->dt).arc.ae >= (obj->dt).arc.as) {
+ if(obj->af) {
+ alphaf = (obj->dt).arc.ae + M_PI_2;
+ }
+ if(obj->ab) {
+ alphab = (obj->dt).arc.as - M_PI_2;
+ }
+ } else {
+ if(obj->af) {
+ alphaf = (obj->dt).arc.ae - M_PI_2;
+ }
+ if(obj->ab) {
+ alphab = (obj->dt).arc.as + M_PI_2;
+ }
+ }
+ if(drw->coah) {
+ if(obj->af) {
+ sp.x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc,
+ ((obj->dt).arc.ra * cos((obj->dt).arc.ae)),
+ &mec
+ );
+ sp.y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc,
+ ((obj->dt).arc.ra * sin((obj->dt).arc.ae)),
+ &mec
+ ); $? ". sp = %lg %lg", sp.x, sp.y
+ res = dk3figah_straight_arrowhead(
+ drw, obj, obj->af, &sp, alphaf, &mec
+ );
+ if(!(res)) { back = 0; }
+ }
+ if(obj->ab) {
+ sp.x = dk3ma_d_add_ok(
+ (obj->dt).arc.xc,
+ ((obj->dt).arc.ra * cos((obj->dt).arc.as)),
+ &mec
+ );
+ sp.y = dk3ma_d_add_ok(
+ (obj->dt).arc.yc,
+ ((obj->dt).arc.ra * sin((obj->dt).arc.as)),
+ &mec
+ ); $? ". sp = %lg %lg", sp.x, sp.y
+ res = dk3figah_straight_arrowhead(
+ drw, obj, obj->ab, &sp, alphab, &mec
+ );
+ if(!(res)) { back = 0; }
+ }
+ if(mec) { back = 0; }
+ } else {
+ if(obj->af) {
+ if(!dk3figah_one_arc_arrowhead(drw, obj, obj->af, 0, &mec)) {
+ back = 0;
+ }
+ }
+ if(obj->ab) {
+ if(!dk3figah_one_arc_arrowhead(drw, obj, obj->ab, 1, &mec)) {
+ back = 0;
+ }
+ }
+ }
+ /*
+ Cut arc if necessary when not using compatible arrowheads.
+ */
+ if(!(drw->coah)) {
+ newas = (obj->dt).arc.as;
+ newae = (obj->dt).arc.ae;
+ if(0.0 < cuts) { $? ". cut at start for arrowhead"
+ if(dk3figah_must_use_arc_correction(obj->ab)) {
+ das = dk3figah_arc_correction((obj->dt).arc.ra, cuts, &mec);
+ if(0.0 <= das) {
+ if((obj->dt).arc.di) { $? ". pos di, add to as"
+ newas = dk3ma_d_add_ok(newas, das, &mec);
+ } else { $? ". neg di, del from as"
+ newas = dk3ma_d_sub_ok(newas, das, &mec);
+ }
+ } else {
+ mec = DK3_ERROR_MATH_OUT_OF_RANGE;
+ }
+ } else {
+ das = dk3ma_d_div_ok(cuts, (obj->dt).arc.ra, &mec);
+ $? ". cut = %lg r = %lg cut arc = %lg", cuts, (obj->dt).arc.ra, das
+ if((obj->dt).arc.di) { $? ". pos di, add to as"
+ newas = dk3ma_d_add_ok(newas, das, &mec);
+ } else { $? ". neg di, del from as"
+ newas = dk3ma_d_sub_ok(newas, das, &mec);
+ }
+ }
+ }
+ if(0.0 < cute) { $? ". cut at end for arrowhead"
+ if(dk3figah_must_use_arc_correction(obj->af)) {
+ dae = dk3figah_arc_correction((obj->dt).arc.ra, cute, &mec);
+ if(0.0 <= dae) {
+ if((obj->dt).arc.di) { $? ". pos di, del from ae"
+ newae = dk3ma_d_sub_ok(newae, dae, &mec);
+ } else { $? ". neg di, add to ae"
+ newae = dk3ma_d_add_ok(newae, dae, &mec);
+ }
+ } else {
+ mec = DK3_ERROR_MATH_OUT_OF_RANGE;
+ }
+ } else {
+ dae = dk3ma_d_div_ok(cute, (obj->dt).arc.ra, &mec);
+ $? ". cut = %lg r = %lg cut arc = %lg", cute, (obj->dt).arc.ra, dae
+ if((obj->dt).arc.di) { $? ". pos di, del from ae"
+ newae = dk3ma_d_sub_ok(newae, dae, &mec);
+ } else { $? ". neg di, add to ae"
+ newae = dk3ma_d_add_ok(newae, dae, &mec);
+ }
+ }
+ }
+ if(0 == mec) {
+ $? ". old as = %lg", (obj->dt).arc.as
+ $? ". old ae = %lg", (obj->dt).arc.ae
+ $? ". new as = %lg", newas
+ $? ". new ae = %lg", newae
+ $? ". old P1 = %lg %lg", (obj->dt).arc.xc + (obj->dt).arc.ra * cos((obj->dt).arc.as), (obj->dt).arc.yc + (obj->dt).arc.ra * sin((obj->dt).arc.as)
+ $? ". old P2 = %lg %lg", (obj->dt).arc.xc + (obj->dt).arc.ra * cos((obj->dt).arc.ae), (obj->dt).arc.yc + (obj->dt).arc.ra * sin((obj->dt).arc.ae)
+ $? ". new P1 = %lg %lg", (obj->dt).arc.xc + (obj->dt).arc.ra * cos((obj->dt).arc.as), (obj->dt).arc.yc + (obj->dt).arc.ra * sin((obj->dt).arc.as)
+ $? ". new P2 = %lg %lg", (obj->dt).arc.xc + (obj->dt).arc.ra * cos((obj->dt).arc.ae), (obj->dt).arc.yc + (obj->dt).arc.ra * sin((obj->dt).arc.ae)
+ (obj->dt).arc.as = newas; (obj->dt).arc.ae = newae;
+ } else {
+ /* ##### ERROR: Math error */
+ back = 0;
+ }
+ } else {
+ if(0 != mec) {
+ back = 0;
+ dk3app_log_i1(drw->app, DK3_LL_ERROR, 260);
+ }
+ }
+ $? "- dk3figah_calculate_arc %d", back
+ return back;
+}
+
+
+
+int
+dk3figah_calculate_arrowheads(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ unsigned long objno
+)
+{
+ int back = 0;
+ int failed = 0;
+ $? "+ dk3figah_calculate_arrowheads"
+ if((drw) && (obj)) {
+ back = 1;
+ if(dk3figah_candidate(obj)) {
+ /*
+ Use butted line when arrowheads on both ends.
+ */
+ if((obj->af) && (obj->ab)) { obj->cs = DK3_FIG_LC_BUTT; }
+ switch(obj->ot) {
+ case DK3_FIG_OBJ_POLYLINE: {
+ back = dk3figah_calculate_polyline(drw, obj, objno);
+ if(!(back)) { failed = 1; }
+ } break;
+ case DK3_FIG_OBJ_SPLINE: {
+ back = dk3figah_calculate_spline(drw, obj, objno);
+ if(!(back)) { failed = 1; }
+ } break;
+ case DK3_FIG_OBJ_ARC: {
+ back = dk3figah_calculate_arc(drw, obj, objno);
+ if(!(back)) { failed = 1; }
+ } break;
+ }
+ if(failed) {
+ /* ##### ERROR: Arrowhead calculation failed! */
+ }
+ }
+ }
+ if((!(back)) && (NULL != drw)) {
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 5);
+ } $? "- dk3figah_calculate_arrowheads %d", back
+ return back;
+}
+
diff --git a/support/dktools/dk3figah.h b/support/dktools/dk3figah.h
new file mode 100644
index 0000000000..7eff19d024
--- /dev/null
+++ b/support/dktools/dk3figah.h
@@ -0,0 +1,75 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3figah.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3figah.h Header file for the dk3figah module.
+*/
+
+#ifndef DK3FIGAH_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3FIGAH_H_INCLUDED 1
+
+
+#line 10 "dk3figah.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Check whether an object is a candidate to have arrowheads.
+ @param obj Object to check.
+ @return 1 if the object may have arrowheads, 0 otherwise.
+*/
+int
+dk3figah_candidate(dk3_fig_obj_t *obj);
+
+/** Calculate arrowheads for open object.
+ @param drw Drawing of object.
+ @param obj Object to modify.
+ @param objno Object number.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3figah_calculate_arrowheads(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ unsigned long objno
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk3figbb.c b/support/dktools/dk3figbb.c
new file mode 100644
index 0000000000..718de84ca6
--- /dev/null
+++ b/support/dktools/dk3figbb.c
@@ -0,0 +1,650 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3figbb.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3figbb.c The dk3figbb module.
+*/
+
+
+#line 126 "dk3figbb.ctr"
+
+#include "dk3all.h"
+#include "dk3fig.h"
+#include "dk3bb.h"
+#include "dk3xsp.h"
+#include "dk3bezcu.h"
+#include "dk3figto.h"
+#include "dk3figbb.h"
+
+
+
+
+
+#line 138 "dk3figbb.ctr"
+
+
+
+/** Check whether a value is in a given range.
+ @param min Interval minimum.
+ @param max Interval maximum.
+ @param val Value to check.
+ @return 1 if the value is in the interval, 0 otherwise.
+*/
+static
+int
+dk3fig_bb_in_range(double min, double max, double val)
+{
+ int back = 0;
+ if(min <= val) {
+ if(max >= val) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+double
+dk3figbb_distance_point_line(
+ double xp,
+ double yp,
+ double beta,
+ int *ec
+)
+{
+ double sinbeta; /* Sinus of angle. */
+ double cosbeta; /* Cosinus of angle. */
+ double deltax; /* X difference. */
+ double deltay; /* Y difference. */
+ double back;
+
+
+#line 176 "dk3figbb.ctr"
+ sinbeta = sin(beta);
+ cosbeta = cos(beta);
+ deltax = dk3ma_d_sub_ok(
+ xp,
+ (dk3ma_d_add_ok((yp * sinbeta), (xp * cosbeta), ec) * cosbeta),
+ ec
+ );
+ deltay = dk3ma_d_sub_ok(
+ yp,
+ (dk3ma_d_add_ok((yp * sinbeta), (xp * cosbeta), ec) * sinbeta),
+ ec
+ );
+ back = sqrt(
+ dk3ma_d_add_ok(
+ dk3ma_d_mul_ok(deltax, deltax, ec),
+ dk3ma_d_mul_ok(deltay, deltay, ec),
+ ec
+ )
+ );
+
+#line 195 "dk3figbb.ctr"
+ return back;
+}
+
+
+
+int
+dk3fig_bb_add_ellipse(
+ dk3_bb_t *bb,
+ dk3_fig_det_ell_t const *elli,
+ double lw
+)
+{
+ double h; /* Height. */
+ double w; /* Width. */
+ double x; /* X coordinate of point. */
+ double y; /* Y coordinate of point. */
+ double th; /* Parameter t for Ph. */
+ double tw; /* Parameter t for Pw. */
+ double pma; /* Pi minus alpha. */
+ double hpma; /* Half pi minus alpha. */
+ int back = 0;
+ int ec = 0; /* Error code for math. */
+ int r; /* Result from dk3bb_add. */
+
+
+#line 219 "dk3figbb.ctr"
+ if((bb) && (elli)) {
+ back = 1;
+
+
+#line 222 "dk3figbb.ctr"
+
+
+#line 223 "dk3figbb.ctr"
+
+
+#line 224 "dk3figbb.ctr"
+
+
+#line 225 "dk3figbb.ctr"
+
+
+#line 226 "dk3figbb.ctr"
+ if(fabs(elli->an) > 1.0e-6) {
+
+#line 227 "dk3figbb.ctr"
+ pma = dk3ma_d_sub_ok(M_PI, elli->an, &ec);
+ hpma = dk3ma_d_sub_ok(M_PI_2, elli->an, &ec);
+ th = dk3ma_d_atan2(
+ (-1.0 * (elli->ry) * cos(pma)),
+ ((elli->rx) * sin(pma))
+ );
+
+#line 233 "dk3figbb.ctr"
+ x = (elli->rx) * cos(th);
+ y = (elli->ry) * sin(th);
+
+#line 235 "dk3figbb.ctr"
+ h = dk3figbb_distance_point_line(
+ x, y, (-1.0 * (elli->an)), &ec
+ );
+
+#line 238 "dk3figbb.ctr"
+ tw = dk3ma_d_atan2(
+ (-1.0 * (elli->ry) * cos(hpma)),
+ ((elli->rx) * sin(hpma))
+ );
+
+#line 242 "dk3figbb.ctr"
+ x = (elli->rx) * cos(tw);
+ y = (elli->ry) * cos(tw);
+
+#line 244 "dk3figbb.ctr"
+ w = dk3figbb_distance_point_line(
+ x, y, dk3ma_d_sub_ok(M_PI_2, (elli->an), &ec), &ec
+ );
+
+#line 247 "dk3figbb.ctr"
+ r = dk3bb_add_y_width(
+ bb,
+ dk3ma_d_sub_ok(elli->cy, h, &ec),
+ (0.5 * lw)
+ );
+ if(!(r)) { back = 0; }
+ r = dk3bb_add_y_width(
+ bb,
+ dk3ma_d_add_ok(elli->cy, h, &ec),
+ (0.5 * lw)
+ );
+ if(!(r)) { back = 0; }
+ r = dk3bb_add_x_width(
+ bb,
+ dk3ma_d_sub_ok(elli->cx, w, &ec),
+ (0.5 * lw)
+ );
+ if(!(r)) { back = 0; }
+ r = dk3bb_add_x_width(
+ bb,
+ dk3ma_d_add_ok(elli->cx, w, &ec),
+ (0.5 * lw)
+ );
+ if(!(r)) { back = 0; }
+ } else {
+
+#line 272 "dk3figbb.ctr"
+ r = dk3bb_add_y_width(
+ bb,
+ dk3ma_d_sub_ok(elli->cy, elli->ry, &ec),
+ (0.5 * lw)
+ );
+ if(!(r)) { back = 0; }
+ r = dk3bb_add_y_width(
+ bb,
+ dk3ma_d_add_ok(elli->cy, elli->ry, &ec),
+ (0.5 * lw)
+ );
+ if(!(r)) { back = 0; }
+ r = dk3bb_add_x_width(
+ bb,
+ dk3ma_d_sub_ok(elli->cx, elli->rx, &ec),
+ (0.5 * lw)
+ );
+ if(!(r)) { back = 0; }
+ r = dk3bb_add_x_width(
+ bb,
+ dk3ma_d_add_ok(elli->cx, elli->rx, &ec),
+ (0.5 * lw)
+ );
+ if(!(r)) { back = 0; }
+ }
+ }
+ if(ec) { back = 0; }
+
+#line 299 "dk3figbb.ctr"
+ return back;
+}
+
+
+
+int
+dk3fig_bb_add_arc(
+ dk3_bb_t *bb,
+ dk3_fig_det_arc_t const *arc,
+ int cl,
+ double lw
+)
+{
+ double min; /* Minimum angle. */
+ double max; /* Maximum angle. */
+ int back = 0;
+ int ec = 0; /* Mathematical error code. */
+
+
+#line 317 "dk3figbb.ctr"
+ if((bb) && (arc)) {
+ back = 1;
+ if(!dk3bb_point_width(bb, arc->x1, arc->y1, lw)) { back = 0; }
+ if(!dk3bb_point_width(bb, arc->x2, arc->y2, lw)) { back = 0; }
+ if(!dk3bb_point_width(bb, arc->x3, arc->y3, lw)) { back = 0; }
+ if(cl) { if(!dk3bb_point_width(bb, arc->xc, arc->yc, lw)) { back = 0; } }
+ if(arc->ae >= arc->as) {
+ min = arc->as; max = arc->ae;
+ } else {
+ min = arc->ae; max = arc->as;
+ }
+
+#line 328 "dk3figbb.ctr"
+ if(dk3fig_bb_in_range(min, max, 0.0)) {
+
+#line 329 "dk3figbb.ctr"
+ if(!dk3bb_add_x_width(bb, dk3ma_d_add_ok(arc->xc, arc->ra, &ec), lw)) {
+ back = 0;
+ }
+ }
+ if(dk3fig_bb_in_range(min, max, M_PI_2)) {
+
+#line 334 "dk3figbb.ctr"
+ if(!dk3bb_add_y_width(bb, dk3ma_d_add_ok(arc->yc, arc->ra, &ec), lw)) {
+ back = 0;
+ }
+ }
+ if(dk3fig_bb_in_range(min, max, M_PI)) {
+
+#line 339 "dk3figbb.ctr"
+ if(!dk3bb_add_x_width(bb, dk3ma_d_sub_ok(arc->xc, arc->ra, &ec), lw)) {
+ back = 0;
+ }
+ }
+ if(dk3fig_bb_in_range(min, max, (3.0 * M_PI_2))) {
+
+#line 344 "dk3figbb.ctr"
+ if(!dk3bb_add_y_width(bb, dk3ma_d_sub_ok(arc->yc, arc->ra, &ec), lw)) {
+ back = 0;
+ }
+ }
+ if(dk3fig_bb_in_range(min, max, (2.0 * M_PI))) {
+
+#line 349 "dk3figbb.ctr"
+ if(!dk3bb_add_x_width(bb, dk3ma_d_add_ok(arc->xc, arc->ra, &ec), lw)) {
+ back = 0;
+ }
+ }
+ if(dk3fig_bb_in_range(min, max, (5.0 * M_PI_2))) {
+
+#line 354 "dk3figbb.ctr"
+ if(!dk3bb_add_y_width(bb, dk3ma_d_add_ok(arc->yc, arc->ra, &ec), lw)) {
+ back = 0;
+ }
+ }
+ if(dk3fig_bb_in_range(min, max, (3.0 * M_PI))) {
+
+#line 359 "dk3figbb.ctr"
+ if(!dk3bb_add_x_width(bb, dk3ma_d_sub_ok(arc->xc, arc->ra, &ec), lw)) {
+ back = 0;
+ }
+ }
+ if(dk3fig_bb_in_range(min, max, (7.0 * M_PI_2))) {
+
+#line 364 "dk3figbb.ctr"
+ if(!dk3bb_add_y_width(bb, dk3ma_d_sub_ok(arc->yc, arc->ra, &ec), lw)) {
+ back = 0;
+ }
+ }
+ if(dk3fig_bb_in_range(min, max, (4.0 * M_PI))) {
+
+#line 369 "dk3figbb.ctr"
+ if(!dk3bb_add_x_width(bb, dk3ma_d_add_ok(arc->xc, arc->ra, &ec), lw)) {
+ back = 0;
+ }
+ }
+ }
+ if(ec) {
+ back = 0;
+ }
+
+#line 377 "dk3figbb.ctr"
+ return back;
+}
+
+
+
+
+int
+dk3fig_bb_add_polyline(
+ dk3_bb_t *bb,
+ dk3_fig_det_pol_t const *pol,
+ double lw
+)
+{
+ dk3_fig_poly_point_t const *ptr; /* Current point. */
+ size_t num; /* Index of current point. */
+ int back = 0;
+
+
+#line 394 "dk3figbb.ctr"
+ if((bb) && (pol)) {
+ if((pol->po) && (0 < pol->np)) {
+ back = 1;
+ ptr = pol->po;
+ num = pol->np;
+ while(num--) {
+ if(!dk3bb_point_width(bb, ptr->x, ptr->y, lw)) { back = 0; }
+ ptr++;
+ }
+ }
+ }
+
+#line 405 "dk3figbb.ctr"
+ return back;
+}
+
+
+
+int
+dk3fig_bb_add_text(
+ dk3_bb_t *bb,
+ dk3_fig_det_txt_t const *txt,
+ double res,
+ int bbts
+)
+{
+ double ymax; /* Maximum y. */
+ int back = 0;
+ int ec = 0; /* Mathematical error code. */
+
+
+#line 422 "dk3figbb.ctr"
+ if((bb) && (txt)) {
+ back = 1;
+ dk3bb_point(bb, txt->x, txt->y);
+ /* 2013-02-03: Y value is used only if bbts is set.
+ */
+ /* 2012-12-01: Y values grow downwards in Fig space, so we
+ must substract instead of add.
+ */
+ if(bbts) {
+ ymax = dk3ma_d_sub_ok(
+ txt->y,
+ dk3ma_d_mul_ok(res, (txt->fs / 72.72), &ec),
+ &ec
+ );
+
+#line 436 "dk3figbb.ctr"
+ dk3bb_point(bb, txt->x, ymax);
+ }
+ if(ec) {
+ back = 0;
+ }
+ }
+
+#line 442 "dk3figbb.ctr"
+ return back;
+}
+
+
+
+/** Add X-spline segment to bounding box.
+ @param bb Bounding box structure to modify.
+ @param pa Point A (left neighbour of segment).
+ @param pb Point B (start of segment).
+ @param pc Point C (end of segment).
+ @param pd Point D (right neighbour of segment).
+ @param xssbs Number of Bezier spline segments per X-spline segment.
+ @param cb Flag: Compatibility to XFig interpolated spline bug.
+ @param ra Radius of points.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3fig_bb_add_xpline_segment(
+ dk3_bb_t *bb,
+ dk3_fig_spline_point_t *pa,
+ dk3_fig_spline_point_t *pb,
+ dk3_fig_spline_point_t *pc,
+ dk3_fig_spline_point_t *pd,
+ size_t xssbs,
+ int cb,
+ double ra
+)
+{
+ dk3_xspline_segment_t xseg; /* Spline segment. */
+ double x; /* Current x. */
+ double y; /* Current y. */
+ double lastx; /* Previous x. */
+ double lasty; /* Previous y. */
+ double dxdt; /* X derived. */
+ double dydt; /* Y derived. */
+ double lastdxdt; /* X derived, previous value. */
+ double lastdydt; /* Y derived, previous value. */
+ double xp; /* Start control point x. */
+ double yp; /* Start control point y. */
+ double xm; /* End control point x. */
+ double ym; /* End control point y. */
+ double t; /* Current t value. */
+ double dxssbs; /* Number of sub segments. */
+ double d3; /* Scale factor for derivatives. */
+ size_t i; /* Current sub segment. */
+ int back = 1;
+ int mec = 0; /* Mathematical error code. */
+
+
+#line 491 "dk3figbb.ctr"
+ dk3xsp_reset(&xseg);
+ if(cb) { dk3xsp_set_cb(&xseg, cb); }
+ dk3xsp_set(&xseg, pa, pb, pc, pd);
+ if(dk3xsp_calculate(&xseg, 0.0, 1)) {
+
+#line 495 "dk3figbb.ctr"
+ dxssbs = (double)xssbs;
+ d3 = dk3ma_d_mul_ok(3.0, dxssbs, &mec);
+ lastx = dk3xsp_get_x(&xseg);
+ lasty = dk3xsp_get_y(&xseg);
+ lastdxdt = dk3xsp_get_dxdt(&xseg);
+ lastdydt = dk3xsp_get_dydt(&xseg);
+ for(i = 1; i <= xssbs; i++) {
+ if(i < xssbs) {
+ t = (double)i / dxssbs;
+ } else {
+ t = 1.0;
+ }
+ if(dk3xsp_calculate(&xseg, t, 1)) {
+ x = dk3xsp_get_x(&xseg);
+ y = dk3xsp_get_y(&xseg);
+ dxdt = dk3xsp_get_dxdt(&xseg);
+ dydt = dk3xsp_get_dydt(&xseg);
+ xp = dk3ma_d_add_ok(
+ lastx,
+ dk3ma_d_div_ok(lastdxdt, d3, &mec),
+ &mec
+ );
+ yp = dk3ma_d_add_ok(
+ lasty,
+ dk3ma_d_div_ok(lastdydt, d3, &mec),
+ &mec
+ );
+ xm = dk3ma_d_sub_ok(
+ x,
+ dk3ma_d_div_ok(dxdt, d3, &mec),
+ &mec
+ );
+ ym = dk3ma_d_sub_ok(
+ y,
+ dk3ma_d_div_ok(dydt, d3, &mec),
+ &mec
+ );
+ if(!dk3bezier_bb(bb, lastx, lasty, xp, yp, xm, ym, x, y, ra, &mec)) {
+ back = 0;
+
+#line 534 "dk3figbb.ctr"
+ }
+ lastx = x;
+ lasty = y;
+ lastdxdt = dxdt;
+ lastdydt = dydt;
+ } else {
+
+#line 540 "dk3figbb.ctr"
+ back = 0;
+ }
+ }
+ } else {
+
+#line 544 "dk3figbb.ctr"
+ back = 0;
+ }
+ if(mec) {
+
+#line 547 "dk3figbb.ctr"
+ back = 0;
+ }
+
+#line 549 "dk3figbb.ctr"
+ return back;
+}
+
+
+
+int
+dk3fig_bb_add_spline(
+ dk3_fig_drawing_t *drw,
+ dk3_bb_t *bb,
+ dk3_fig_det_spl_t const *spl,
+ double lw,
+ int primobj,
+ int iscl
+)
+{
+ dk3_fig_spline_point_t *pa; /* Point A. */
+ dk3_fig_spline_point_t *pb; /* Point B. */
+ dk3_fig_spline_point_t *pc; /* Point C. */
+ dk3_fig_spline_point_t *pd; /* Point D. */
+ size_t xssbs; /* Bezier segments per X-spline segment. */
+ size_t cs; /* Current X-spline segment. */
+ int back = 0;
+
+
+#line 572 "dk3figbb.ctr"
+ if((bb) && (spl)) {
+ if((spl->po) && (((iscl) ? (size_t)2 : (size_t)1) < spl->np)) {
+ back = 1;
+ xssbs = dk3fig_tool_xssbs(drw, primobj);
+ if(iscl) {
+
+#line 577 "dk3figbb.ctr"
+ for(cs = 0; cs < (spl->np); cs++) {
+ pb = &((spl->po)[cs]);
+ pc = &((spl->po)[((cs < (spl->np - 1)) ? (cs + 1) : 0)]);
+ pa = &((spl->po)[(cs > 0) ? (cs - 1) : ((spl->np) - 1)]);
+ pd = &((spl->po)[(cs < (spl->np - 2))?(cs + 2):(cs + 2 - spl->np)]);
+ if(!dk3fig_bb_add_xpline_segment(bb,pa,pb,pc,pd,xssbs,drw->cosp,lw)) {
+ back = 0;
+ }
+ }
+ } else {
+
+#line 587 "dk3figbb.ctr"
+ for(cs = 0; cs < ((spl->np) - 1); cs++) {
+ pa = pd = NULL;
+ pb = &((spl->po)[cs]);
+ pc = &((spl->po)[cs + 1]);
+ if(0 < cs) { pa = &((spl->po)[cs - 1]); }
+ if(cs < ((spl->np) - 2)) { pd = &((spl->po)[cs + 2]); }
+ if(!dk3fig_bb_add_xpline_segment(bb,pa,pb,pc,pd,xssbs,drw->cosp,lw)) {
+ back = 0;
+ }
+ }
+ }
+ } else {
+
+#line 599 "dk3figbb.ctr"
+ }
+ }
+
+#line 601 "dk3figbb.ctr"
+ return back;
+}
+
+
+
+int
+dk3fig_bb_add_hci(
+ dk3_bb_t *outbb,
+ dk3_fig_det_hci_t const *hci,
+ double ra
+)
+{
+ dk3_fig_poly_point_t po[3]; /* End and middle point of arc. */
+ size_t i; /* Used as index when rotating. */
+ int back = 0;
+ int mec = 0; /* Mathematical error code. */
+ if((outbb) && (hci)) {
+ po[0].x = 0.0;
+ po[0].y = hci->ra;
+ po[1].x = -1.0 * hci->ra;
+ po[1].y = 0.0;
+ po[2].x = 0.0;
+ po[2].y = -1.0 * hci->ra;
+ for(i = 0; i < 3; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), hci->an, &mec);
+ dk3fig_tool_shift_point(
+ &(po[i]), hci->cx, hci->cy, &mec
+ );
+ }
+ if(0 == mec) {
+ back = 1;
+ if(!dk3bb_point_width(outbb, po[0].x, po[0].y, ra)) { back = 0; }
+ if(!dk3bb_point_width(outbb, po[1].x, po[1].y, ra)) { back = 0; }
+ if(!dk3bb_point_width(outbb, po[2].x, po[2].y, ra)) { back = 0; }
+ /* ##### HIER WEITER: Weitere Punkte je nach Drehung */
+ }
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk3figbb.ctr b/support/dktools/dk3figbb.ctr
new file mode 100644
index 0000000000..ef90e983f3
--- /dev/null
+++ b/support/dktools/dk3figbb.ctr
@@ -0,0 +1,641 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Calculate distance between a given point and a line through
+ the origin.
+ @param xp X coordinate of given point.
+ @param yp Y coordinate of given point.
+ @param beta Angle of line.
+ @param ec Pointer to error code variable.
+ @return Distance value.
+*/
+double
+dk3figbb_distance_point_line(
+ double xp,
+ double yp,
+ double beta,
+ int *ec
+);
+
+/** Add ellipse data to bounding box.
+ @param bb Bounding box data to modify.
+ @param elli Details of ellipse to add.
+ @param lw Half line width.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3fig_bb_add_ellipse(
+ dk3_bb_t *bb,
+ dk3_fig_det_ell_t const *elli,
+ double lw
+);
+
+/** Add arc data to bounding box.
+ @param bb Bounding box data to modify.
+ @param arc Details of arc to add.
+ @param cl Flag: Closed arc.
+ @param lw Half line width.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3fig_bb_add_arc(
+ dk3_bb_t *bb,
+ dk3_fig_det_arc_t const *arc,
+ int cl,
+ double lw
+);
+
+/** Add polyline data to bounding box.
+ @param bb Bounding box data to modify.
+ @param pol Details of polyline to add.
+ @param lw Half line width.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3fig_bb_add_polyline(
+ dk3_bb_t *bb,
+ dk3_fig_det_pol_t const *pol,
+ double lw
+);
+
+/** Add spline data to bounding box.
+ @param drw Drawing structure.
+ @param bb Bounding box data to modify.
+ @param spl Details of spline object to add.
+ @param lw Half line width.
+ @param primobj Flag: Primary object (1=object, 0=arrowhead).
+ @param iscl Flag: Closed spline (1=closed, 0=open).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3fig_bb_add_spline(
+ dk3_fig_drawing_t *drw,
+ dk3_bb_t *bb,
+ dk3_fig_det_spl_t const *spl,
+ double lw,
+ int primobj,
+ int iscl
+);
+
+/** Add text data to bounding box.
+ @param bb Bounding box data to modify.
+ @param txt Details of text object to add.
+ @param res Fig file resolution.
+ @param bbts Flag: Use text size when calculating bounding box.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3fig_bb_add_text(
+ dk3_bb_t *bb,
+ dk3_fig_det_txt_t const *txt,
+ double res,
+ int bbts
+);
+
+/** Calculate bounding box for half-circle.
+ @param outbb Destination bounding box.
+ @param hci Half-circle details.
+ @param ra Radius around points.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3fig_bb_add_hci(
+ dk3_bb_t *outbb,
+ dk3_fig_det_hci_t const *hci,
+ double ra
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk3all.h"
+#include "dk3fig.h"
+#include "dk3bb.h"
+#include "dk3xsp.h"
+#include "dk3bezcu.h"
+#include "dk3figto.h"
+#include "dk3figbb.h"
+
+
+
+$!trace-include
+
+
+
+/** Check whether a value is in a given range.
+ @param min Interval minimum.
+ @param max Interval maximum.
+ @param val Value to check.
+ @return 1 if the value is in the interval, 0 otherwise.
+*/
+static
+int
+dk3fig_bb_in_range(double min, double max, double val)
+{
+ int back = 0;
+ if(min <= val) {
+ if(max >= val) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+double
+dk3figbb_distance_point_line(
+ double xp,
+ double yp,
+ double beta,
+ int *ec
+)
+{
+ double sinbeta; /* Sinus of angle. */
+ double cosbeta; /* Cosinus of angle. */
+ double deltax; /* X difference. */
+ double deltay; /* Y difference. */
+ double back;
+ $? "+ dk3figbb_distance_point_line x=%lg y=%lg beta=%lg", xp, yp, beta
+ sinbeta = sin(beta);
+ cosbeta = cos(beta);
+ deltax = dk3ma_d_sub_ok(
+ xp,
+ (dk3ma_d_add_ok((yp * sinbeta), (xp * cosbeta), ec) * cosbeta),
+ ec
+ );
+ deltay = dk3ma_d_sub_ok(
+ yp,
+ (dk3ma_d_add_ok((yp * sinbeta), (xp * cosbeta), ec) * sinbeta),
+ ec
+ );
+ back = sqrt(
+ dk3ma_d_add_ok(
+ dk3ma_d_mul_ok(deltax, deltax, ec),
+ dk3ma_d_mul_ok(deltay, deltay, ec),
+ ec
+ )
+ ); $? "- dk3figbb_distance_point_line %lg", back
+ return back;
+}
+
+
+
+int
+dk3fig_bb_add_ellipse(
+ dk3_bb_t *bb,
+ dk3_fig_det_ell_t const *elli,
+ double lw
+)
+{
+ double h; /* Height. */
+ double w; /* Width. */
+ double x; /* X coordinate of point. */
+ double y; /* Y coordinate of point. */
+ double th; /* Parameter t for Ph. */
+ double tw; /* Parameter t for Pw. */
+ double pma; /* Pi minus alpha. */
+ double hpma; /* Half pi minus alpha. */
+ int back = 0;
+ int ec = 0; /* Error code for math. */
+ int r; /* Result from dk3bb_add. */
+ $? "+ dk3fig_bb_add_ellipse %lg", elli->an
+ if((bb) && (elli)) {
+ back = 1;
+ $? ". cx=%lg", elli->cx
+ $? ". cy=%lg", elli->cy
+ $? ". rx=%lg", elli->rx
+ $? ". ry=%lg", elli->ry
+ $? ". an=%lg (%lg degree)", elli->an, (180.0 * elli->an) / M_PI
+ if(fabs(elli->an) > 1.0e-6) { $? ". rotated"
+ pma = dk3ma_d_sub_ok(M_PI, elli->an, &ec);
+ hpma = dk3ma_d_sub_ok(M_PI_2, elli->an, &ec);
+ th = dk3ma_d_atan2(
+ (-1.0 * (elli->ry) * cos(pma)),
+ ((elli->rx) * sin(pma))
+ ); $? ". th=%lg", th
+ x = (elli->rx) * cos(th);
+ y = (elli->ry) * sin(th); $? ". x=%lg y=%lg", x, y
+ h = dk3figbb_distance_point_line(
+ x, y, (-1.0 * (elli->an)), &ec
+ ); $? ". h=%lg", h
+ tw = dk3ma_d_atan2(
+ (-1.0 * (elli->ry) * cos(hpma)),
+ ((elli->rx) * sin(hpma))
+ ); $? ". tw=%lg", tw
+ x = (elli->rx) * cos(tw);
+ y = (elli->ry) * cos(tw); $? ". x=%lg y=%lg", x ,y
+ w = dk3figbb_distance_point_line(
+ x, y, dk3ma_d_sub_ok(M_PI_2, (elli->an), &ec), &ec
+ ); $? ". w=%lg", w
+ r = dk3bb_add_y_width(
+ bb,
+ dk3ma_d_sub_ok(elli->cy, h, &ec),
+ (0.5 * lw)
+ );
+ if(!(r)) { back = 0; }
+ r = dk3bb_add_y_width(
+ bb,
+ dk3ma_d_add_ok(elli->cy, h, &ec),
+ (0.5 * lw)
+ );
+ if(!(r)) { back = 0; }
+ r = dk3bb_add_x_width(
+ bb,
+ dk3ma_d_sub_ok(elli->cx, w, &ec),
+ (0.5 * lw)
+ );
+ if(!(r)) { back = 0; }
+ r = dk3bb_add_x_width(
+ bb,
+ dk3ma_d_add_ok(elli->cx, w, &ec),
+ (0.5 * lw)
+ );
+ if(!(r)) { back = 0; }
+ } else { $? ". not rotated"
+ r = dk3bb_add_y_width(
+ bb,
+ dk3ma_d_sub_ok(elli->cy, elli->ry, &ec),
+ (0.5 * lw)
+ );
+ if(!(r)) { back = 0; }
+ r = dk3bb_add_y_width(
+ bb,
+ dk3ma_d_add_ok(elli->cy, elli->ry, &ec),
+ (0.5 * lw)
+ );
+ if(!(r)) { back = 0; }
+ r = dk3bb_add_x_width(
+ bb,
+ dk3ma_d_sub_ok(elli->cx, elli->rx, &ec),
+ (0.5 * lw)
+ );
+ if(!(r)) { back = 0; }
+ r = dk3bb_add_x_width(
+ bb,
+ dk3ma_d_add_ok(elli->cx, elli->rx, &ec),
+ (0.5 * lw)
+ );
+ if(!(r)) { back = 0; }
+ }
+ }
+ if(ec) { back = 0; } $? "- dk3fig_bb_add_ellipse %d", back
+ return back;
+}
+
+
+
+int
+dk3fig_bb_add_arc(
+ dk3_bb_t *bb,
+ dk3_fig_det_arc_t const *arc,
+ int cl,
+ double lw
+)
+{
+ double min; /* Minimum angle. */
+ double max; /* Maximum angle. */
+ int back = 0;
+ int ec = 0; /* Mathematical error code. */
+ $? "+ dk3fig_bb_add_arc %lg", lw
+ if((bb) && (arc)) {
+ back = 1;
+ if(!dk3bb_point_width(bb, arc->x1, arc->y1, lw)) { back = 0; }
+ if(!dk3bb_point_width(bb, arc->x2, arc->y2, lw)) { back = 0; }
+ if(!dk3bb_point_width(bb, arc->x3, arc->y3, lw)) { back = 0; }
+ if(cl) { if(!dk3bb_point_width(bb, arc->xc, arc->yc, lw)) { back = 0; } }
+ if(arc->ae >= arc->as) {
+ min = arc->as; max = arc->ae;
+ } else {
+ min = arc->ae; max = arc->as;
+ } $? ". range %lg %lg", min, max
+ if(dk3fig_bb_in_range(min, max, 0.0)) { $? ". 0 in Fig space"
+ if(!dk3bb_add_x_width(bb, dk3ma_d_add_ok(arc->xc, arc->ra, &ec), lw)) {
+ back = 0;
+ }
+ }
+ if(dk3fig_bb_in_range(min, max, M_PI_2)) { $? ". 90 degree in Fig space"
+ if(!dk3bb_add_y_width(bb, dk3ma_d_add_ok(arc->yc, arc->ra, &ec), lw)) {
+ back = 0;
+ }
+ }
+ if(dk3fig_bb_in_range(min, max, M_PI)) { $? ". 180 degree in Fig space"
+ if(!dk3bb_add_x_width(bb, dk3ma_d_sub_ok(arc->xc, arc->ra, &ec), lw)) {
+ back = 0;
+ }
+ }
+ if(dk3fig_bb_in_range(min, max, (3.0 * M_PI_2))) { $? ". 270 degree in Fig space"
+ if(!dk3bb_add_y_width(bb, dk3ma_d_sub_ok(arc->yc, arc->ra, &ec), lw)) {
+ back = 0;
+ }
+ }
+ if(dk3fig_bb_in_range(min, max, (2.0 * M_PI))) { $? ". 360 degree in Fig space"
+ if(!dk3bb_add_x_width(bb, dk3ma_d_add_ok(arc->xc, arc->ra, &ec), lw)) {
+ back = 0;
+ }
+ }
+ if(dk3fig_bb_in_range(min, max, (5.0 * M_PI_2))) { $? ". 450 degree in Fig space"
+ if(!dk3bb_add_y_width(bb, dk3ma_d_add_ok(arc->yc, arc->ra, &ec), lw)) {
+ back = 0;
+ }
+ }
+ if(dk3fig_bb_in_range(min, max, (3.0 * M_PI))) { $? ". 540 degree in Fig space"
+ if(!dk3bb_add_x_width(bb, dk3ma_d_sub_ok(arc->xc, arc->ra, &ec), lw)) {
+ back = 0;
+ }
+ }
+ if(dk3fig_bb_in_range(min, max, (7.0 * M_PI_2))) { $? ". 630 degree in Fig space"
+ if(!dk3bb_add_y_width(bb, dk3ma_d_sub_ok(arc->yc, arc->ra, &ec), lw)) {
+ back = 0;
+ }
+ }
+ if(dk3fig_bb_in_range(min, max, (4.0 * M_PI))) { $? ". 720 degree in Fig space"
+ if(!dk3bb_add_x_width(bb, dk3ma_d_add_ok(arc->xc, arc->ra, &ec), lw)) {
+ back = 0;
+ }
+ }
+ }
+ if(ec) {
+ back = 0;
+ } $? "- dk3fig_bb_add_arc %d", back
+ return back;
+}
+
+
+
+
+int
+dk3fig_bb_add_polyline(
+ dk3_bb_t *bb,
+ dk3_fig_det_pol_t const *pol,
+ double lw
+)
+{
+ dk3_fig_poly_point_t const *ptr; /* Current point. */
+ size_t num; /* Index of current point. */
+ int back = 0;
+ $? "+ dk3fig_bb_add_polyline"
+ if((bb) && (pol)) {
+ if((pol->po) && (0 < pol->np)) {
+ back = 1;
+ ptr = pol->po;
+ num = pol->np;
+ while(num--) {
+ if(!dk3bb_point_width(bb, ptr->x, ptr->y, lw)) { back = 0; }
+ ptr++;
+ }
+ }
+ } $? "- dk3fig_bb_add_polyline %d", back
+ return back;
+}
+
+
+
+int
+dk3fig_bb_add_text(
+ dk3_bb_t *bb,
+ dk3_fig_det_txt_t const *txt,
+ double res,
+ int bbts
+)
+{
+ double ymax; /* Maximum y. */
+ int back = 0;
+ int ec = 0; /* Mathematical error code. */
+ $? "+ dk3fig_bb_add_text"
+ if((bb) && (txt)) {
+ back = 1;
+ dk3bb_point(bb, txt->x, txt->y);
+ /* 2013-02-03: Y value is used only if bbts is set.
+ */
+ /* 2012-12-01: Y values grow downwards in Fig space, so we
+ must substract instead of add.
+ */
+ if(bbts) {
+ ymax = dk3ma_d_sub_ok(
+ txt->y,
+ dk3ma_d_mul_ok(res, (txt->fs / 72.72), &ec),
+ &ec
+ ); $? ". ymax = %lg", ymax
+ dk3bb_point(bb, txt->x, ymax);
+ }
+ if(ec) {
+ back = 0;
+ }
+ } $? "- dk3fig_bb_add_text %d", back
+ return back;
+}
+
+
+
+/** Add X-spline segment to bounding box.
+ @param bb Bounding box structure to modify.
+ @param pa Point A (left neighbour of segment).
+ @param pb Point B (start of segment).
+ @param pc Point C (end of segment).
+ @param pd Point D (right neighbour of segment).
+ @param xssbs Number of Bezier spline segments per X-spline segment.
+ @param cb Flag: Compatibility to XFig interpolated spline bug.
+ @param ra Radius of points.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3fig_bb_add_xpline_segment(
+ dk3_bb_t *bb,
+ dk3_fig_spline_point_t *pa,
+ dk3_fig_spline_point_t *pb,
+ dk3_fig_spline_point_t *pc,
+ dk3_fig_spline_point_t *pd,
+ size_t xssbs,
+ int cb,
+ double ra
+)
+{
+ dk3_xspline_segment_t xseg; /* Spline segment. */
+ double x; /* Current x. */
+ double y; /* Current y. */
+ double lastx; /* Previous x. */
+ double lasty; /* Previous y. */
+ double dxdt; /* X derived. */
+ double dydt; /* Y derived. */
+ double lastdxdt; /* X derived, previous value. */
+ double lastdydt; /* Y derived, previous value. */
+ double xp; /* Start control point x. */
+ double yp; /* Start control point y. */
+ double xm; /* End control point x. */
+ double ym; /* End control point y. */
+ double t; /* Current t value. */
+ double dxssbs; /* Number of sub segments. */
+ double d3; /* Scale factor for derivatives. */
+ size_t i; /* Current sub segment. */
+ int back = 1;
+ int mec = 0; /* Mathematical error code. */
+ $? "+ dk3fig_bb_add_xpline_segment"
+ dk3xsp_reset(&xseg);
+ if(cb) { dk3xsp_set_cb(&xseg, cb); }
+ dk3xsp_set(&xseg, pa, pb, pc, pd);
+ if(dk3xsp_calculate(&xseg, 0.0, 1)) { $? ". first calc"
+ dxssbs = (double)xssbs;
+ d3 = dk3ma_d_mul_ok(3.0, dxssbs, &mec);
+ lastx = dk3xsp_get_x(&xseg);
+ lasty = dk3xsp_get_y(&xseg);
+ lastdxdt = dk3xsp_get_dxdt(&xseg);
+ lastdydt = dk3xsp_get_dydt(&xseg);
+ for(i = 1; i <= xssbs; i++) {
+ if(i < xssbs) {
+ t = (double)i / dxssbs;
+ } else {
+ t = 1.0;
+ }
+ if(dk3xsp_calculate(&xseg, t, 1)) {
+ x = dk3xsp_get_x(&xseg);
+ y = dk3xsp_get_y(&xseg);
+ dxdt = dk3xsp_get_dxdt(&xseg);
+ dydt = dk3xsp_get_dydt(&xseg);
+ xp = dk3ma_d_add_ok(
+ lastx,
+ dk3ma_d_div_ok(lastdxdt, d3, &mec),
+ &mec
+ );
+ yp = dk3ma_d_add_ok(
+ lasty,
+ dk3ma_d_div_ok(lastdydt, d3, &mec),
+ &mec
+ );
+ xm = dk3ma_d_sub_ok(
+ x,
+ dk3ma_d_div_ok(dxdt, d3, &mec),
+ &mec
+ );
+ ym = dk3ma_d_sub_ok(
+ y,
+ dk3ma_d_div_ok(dydt, d3, &mec),
+ &mec
+ );
+ if(!dk3bezier_bb(bb, lastx, lasty, xp, yp, xm, ym, x, y, ra, &mec)) {
+ back = 0; $? "! Bezier bb"
+ }
+ lastx = x;
+ lasty = y;
+ lastdxdt = dxdt;
+ lastdydt = dydt;
+ } else { $? "! calc"
+ back = 0;
+ }
+ }
+ } else { $? "! first calc"
+ back = 0;
+ }
+ if(mec) { $? "! math error"
+ back = 0;
+ } $? "- dk3fig_bb_add_xpline_segment %d", back
+ return back;
+}
+
+
+
+int
+dk3fig_bb_add_spline(
+ dk3_fig_drawing_t *drw,
+ dk3_bb_t *bb,
+ dk3_fig_det_spl_t const *spl,
+ double lw,
+ int primobj,
+ int iscl
+)
+{
+ dk3_fig_spline_point_t *pa; /* Point A. */
+ dk3_fig_spline_point_t *pb; /* Point B. */
+ dk3_fig_spline_point_t *pc; /* Point C. */
+ dk3_fig_spline_point_t *pd; /* Point D. */
+ size_t xssbs; /* Bezier segments per X-spline segment. */
+ size_t cs; /* Current X-spline segment. */
+ int back = 0;
+ $? "+ dk3fig_bb_add_spline closed=%d", iscl
+ if((bb) && (spl)) {
+ if((spl->po) && (((iscl) ? (size_t)2 : (size_t)1) < spl->np)) {
+ back = 1;
+ xssbs = dk3fig_tool_xssbs(drw, primobj);
+ if(iscl) { $? ". closed spline"
+ for(cs = 0; cs < (spl->np); cs++) {
+ pb = &((spl->po)[cs]);
+ pc = &((spl->po)[((cs < (spl->np - 1)) ? (cs + 1) : 0)]);
+ pa = &((spl->po)[(cs > 0) ? (cs - 1) : ((spl->np) - 1)]);
+ pd = &((spl->po)[(cs < (spl->np - 2))?(cs + 2):(cs + 2 - spl->np)]);
+ if(!dk3fig_bb_add_xpline_segment(bb,pa,pb,pc,pd,xssbs,drw->cosp,lw)) {
+ back = 0;
+ }
+ }
+ } else { $? ". open spline"
+ for(cs = 0; cs < ((spl->np) - 1); cs++) {
+ pa = pd = NULL;
+ pb = &((spl->po)[cs]);
+ pc = &((spl->po)[cs + 1]);
+ if(0 < cs) { pa = &((spl->po)[cs - 1]); }
+ if(cs < ((spl->np) - 2)) { pd = &((spl->po)[cs + 2]); }
+ if(!dk3fig_bb_add_xpline_segment(bb,pa,pb,pc,pd,xssbs,drw->cosp,lw)) {
+ back = 0;
+ }
+ }
+ }
+ } else { $? "! no point data or too few points"
+ }
+ } $? "- dk3fig_bb_add_spline %d", back
+ return back;
+}
+
+
+
+int
+dk3fig_bb_add_hci(
+ dk3_bb_t *outbb,
+ dk3_fig_det_hci_t const *hci,
+ double ra
+)
+{
+ dk3_fig_poly_point_t po[3]; /* End and middle point of arc. */
+ size_t i; /* Used as index when rotating. */
+ int back = 0;
+ int mec = 0; /* Mathematical error code. */
+ if((outbb) && (hci)) {
+ po[0].x = 0.0;
+ po[0].y = hci->ra;
+ po[1].x = -1.0 * hci->ra;
+ po[1].y = 0.0;
+ po[2].x = 0.0;
+ po[2].y = -1.0 * hci->ra;
+ for(i = 0; i < 3; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), hci->an, &mec);
+ dk3fig_tool_shift_point(
+ &(po[i]), hci->cx, hci->cy, &mec
+ );
+ }
+ if(0 == mec) {
+ back = 1;
+ if(!dk3bb_point_width(outbb, po[0].x, po[0].y, ra)) { back = 0; }
+ if(!dk3bb_point_width(outbb, po[1].x, po[1].y, ra)) { back = 0; }
+ if(!dk3bb_point_width(outbb, po[2].x, po[2].y, ra)) { back = 0; }
+ /* ##### HIER WEITER: Weitere Punkte je nach Drehung */
+ }
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk3figbb.h b/support/dktools/dk3figbb.h
new file mode 100644
index 0000000000..168e970cb0
--- /dev/null
+++ b/support/dktools/dk3figbb.h
@@ -0,0 +1,161 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3figbb.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3figbb.h Header file for the dk3figbb module.
+*/
+
+#ifndef DK3FIGBB_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3FIGBB_H_INCLUDED 1
+
+
+#line 10 "dk3figbb.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Calculate distance between a given point and a line through
+ the origin.
+ @param xp X coordinate of given point.
+ @param yp Y coordinate of given point.
+ @param beta Angle of line.
+ @param ec Pointer to error code variable.
+ @return Distance value.
+*/
+double
+dk3figbb_distance_point_line(
+ double xp,
+ double yp,
+ double beta,
+ int *ec
+);
+
+/** Add ellipse data to bounding box.
+ @param bb Bounding box data to modify.
+ @param elli Details of ellipse to add.
+ @param lw Half line width.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3fig_bb_add_ellipse(
+ dk3_bb_t *bb,
+ dk3_fig_det_ell_t const *elli,
+ double lw
+);
+
+/** Add arc data to bounding box.
+ @param bb Bounding box data to modify.
+ @param arc Details of arc to add.
+ @param cl Flag: Closed arc.
+ @param lw Half line width.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3fig_bb_add_arc(
+ dk3_bb_t *bb,
+ dk3_fig_det_arc_t const *arc,
+ int cl,
+ double lw
+);
+
+/** Add polyline data to bounding box.
+ @param bb Bounding box data to modify.
+ @param pol Details of polyline to add.
+ @param lw Half line width.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3fig_bb_add_polyline(
+ dk3_bb_t *bb,
+ dk3_fig_det_pol_t const *pol,
+ double lw
+);
+
+/** Add spline data to bounding box.
+ @param drw Drawing structure.
+ @param bb Bounding box data to modify.
+ @param spl Details of spline object to add.
+ @param lw Half line width.
+ @param primobj Flag: Primary object (1=object, 0=arrowhead).
+ @param iscl Flag: Closed spline (1=closed, 0=open).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3fig_bb_add_spline(
+ dk3_fig_drawing_t *drw,
+ dk3_bb_t *bb,
+ dk3_fig_det_spl_t const *spl,
+ double lw,
+ int primobj,
+ int iscl
+);
+
+/** Add text data to bounding box.
+ @param bb Bounding box data to modify.
+ @param txt Details of text object to add.
+ @param res Fig file resolution.
+ @param bbts Flag: Use text size when calculating bounding box.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3fig_bb_add_text(
+ dk3_bb_t *bb,
+ dk3_fig_det_txt_t const *txt,
+ double res,
+ int bbts
+);
+
+/** Calculate bounding box for half-circle.
+ @param outbb Destination bounding box.
+ @param hci Half-circle details.
+ @param ra Radius around points.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3fig_bb_add_hci(
+ dk3_bb_t *outbb,
+ dk3_fig_det_hci_t const *hci,
+ double ra
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3figpr.c b/support/dktools/dk3figpr.c
new file mode 100644
index 0000000000..b39fc07474
--- /dev/null
+++ b/support/dktools/dk3figpr.c
@@ -0,0 +1,1390 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3figpr.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3figpr.c The dk3figpr module.
+*/
+
+
+#line 48 "dk3figpr.ctr"
+
+#include "dk3all.h"
+#include "dk3fig.h"
+#include "dk3figto.h"
+#include "dk3figpr.h"
+#include "dk3figbb.h"
+#include "dk3figah.h"
+#include "fig2lat.h"
+
+
+
+#line 58 "dk3figpr.ctr"
+
+
+
+/** If the first object is a background rectangle check
+ whether it was created by jFig or XFig.
+ @param drw Drawing.
+ @param obj Object to check.
+ @param objno Object number.
+*/
+static
+void
+dk3fig_prepare_check_bgrect(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ unsigned long objno
+)
+{
+
+
+#line 76 "dk3figpr.ctr"
+ if(dk3fig_tool_is_bgrect(obj, objno)) {
+ if(DK3_FIG_SRCTYPE_UNKNOWN == drw->srctype) {
+ switch(obj->pc) {
+ case 7: {
+
+#line 80 "dk3figpr.ctr"
+ drw->srctype = DK3_FIG_SRCTYPE_JFIG;
+ } break;
+ default: {
+
+#line 83 "dk3figpr.ctr"
+ drw->srctype = DK3_FIG_SRCTYPE_XFIG;
+ } break;
+ }
+ }
+ }
+
+#line 88 "dk3figpr.ctr"
+}
+
+
+
+#if TRACE_DEBUG
+/** Calculate distance of 2 points, used to verify the correct
+ radius calculation for args.
+ @param x1 Point 1 x.
+ @param x2 Point 2 x.
+ @param y1 Point 1 y.
+ @param y2 Point 2 y.
+ @return Distance between points.
+*/
+static
+double
+dk3fig_prepare_point_distance(
+ double x1, double x2, double y1, double y2
+)
+{
+ double back;
+ back = sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
+ return back;
+}
+#endif
+
+
+
+/** Initialize arc object (calculate center and radius).
+ @param drw Drawing.
+ @param obj Object.
+ @param objno Object number (0 for first object).
+ @param primobj Flag: Primary object (1=object, 0=arrowhead).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3fig_prepare_initialize_arc(
+ dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, unsigned long objno, int primobj
+)
+{
+ dk3_fig_poly_point_t *points;
+ dk3_fig_det_arc_t *arc;
+ double tm; /* The t parameter of the M point. */
+ double n; /* Denominator in tm calculation. */
+ double xa;
+ double ya;
+ double xc;
+ double yc;
+ double r;
+ double eps = DK3_FIG_EPSILON;
+ int back = 1;
+ int ec = 0;
+ int divec = 0;
+
+
+#line 142 "dk3figpr.ctr"
+ arc = &((obj->dt).arc);
+ n = dk3ma_d_sub_ok(
+ dk3ma_d_mul_ok(
+ dk3ma_d_sub_ok(arc->y2, arc->y1, &ec),
+ dk3ma_d_sub_ok(arc->x2, arc->x3, &ec),
+ &ec
+ ),
+ dk3ma_d_mul_ok(
+ dk3ma_d_sub_ok(arc->y3, arc->y2, &ec),
+ dk3ma_d_sub_ok(arc->x1, arc->x2, &ec),
+ &ec
+ ),
+ &ec
+ );
+ tm = 0.5 * dk3ma_d_div_ok(
+ dk3ma_d_sub_ok(
+ dk3ma_d_mul_ok(
+ dk3ma_d_sub_ok(arc->x2, arc->x3, &ec),
+ dk3ma_d_sub_ok(arc->x3, arc->x1, &ec),
+ &ec
+ ),
+ dk3ma_d_mul_ok(
+ dk3ma_d_sub_ok(arc->y3, arc->y2, &ec),
+ dk3ma_d_sub_ok(arc->y3, arc->y1, &ec),
+ &ec
+ ),
+ &ec
+ ),
+ n,
+ &divec
+ );
+ if(0 == divec) {
+ arc->xc = dk3ma_d_add_ok(
+ (0.5 * dk3ma_d_add_ok(arc->x1, arc->x2, &ec)),
+ dk3ma_d_mul_ok(
+ tm,
+ dk3ma_d_sub_ok(arc->y2, arc->y1, &ec),
+ &ec
+ ),
+ &ec
+ );
+ arc->yc = dk3ma_d_add_ok(
+ (0.5 * dk3ma_d_add_ok(arc->y1, arc->y2, &ec)),
+ dk3ma_d_mul_ok(
+ tm,
+ dk3ma_d_sub_ok(arc->x1, arc->x2, &ec),
+ &ec
+ ),
+ &ec
+ );
+ arc->ra = sqrt(
+ dk3ma_d_add_ok(
+ dk3ma_d_mul_ok(
+ dk3ma_d_sub_ok(arc->xc, arc->x1, &ec),
+ dk3ma_d_sub_ok(arc->xc, arc->x1, &ec),
+ &ec
+ ),
+ dk3ma_d_mul_ok(
+ dk3ma_d_sub_ok(arc->yc, arc->y1, &ec),
+ dk3ma_d_sub_ok(arc->yc, arc->y1, &ec),
+ &ec
+ ),
+ &ec
+ )
+ );
+ arc->as = dk3ma_d_atan2(
+ dk3ma_d_sub_ok(arc->y1, arc->yc, &ec),
+ dk3ma_d_sub_ok(arc->x1, arc->xc, &ec)
+ );
+ arc->ae = dk3ma_d_atan2(
+ dk3ma_d_sub_ok(arc->y3, arc->yc, &ec),
+ dk3ma_d_sub_ok(arc->x3, arc->xc, &ec)
+ );
+ if(n >= 0.0) {
+ arc->di = 0x01;
+ while(arc->ae < arc->as) {
+ arc->ae = arc->ae + (2.0 * M_PI);
+ }
+ } else {
+ arc->di = 0x00;
+ while(arc->as < arc->ae) {
+ arc->as = arc->as + (2.0 * M_PI);
+ }
+ }
+
+
+#line 227 "dk3figpr.ctr"
+
+
+#line 228 "dk3figpr.ctr"
+
+
+#line 229 "dk3figpr.ctr"
+
+
+#line 230 "dk3figpr.ctr"
+
+
+#line 231 "dk3figpr.ctr"
+
+
+#line 232 "dk3figpr.ctr"
+
+
+#line 233 "dk3figpr.ctr"
+
+
+#line 234 "dk3figpr.ctr"
+
+
+#line 235 "dk3figpr.ctr"
+
+
+#line 236 "dk3figpr.ctr"
+
+
+#line 237 "dk3figpr.ctr"
+ } else {
+ /* line */
+ back = 0;
+ xa = arc->x1;
+ ya = arc->y1;
+ xc = arc->x3;
+ yc = arc->y3;
+ if(dk3ma_d_equal(xa, xc, eps) && dk3ma_d_equal(ya, yc, eps)) {
+ r = 0.5 * dk3fig_tool_get_lw(drw, obj, &ec);
+ switch(obj->cs) {
+ case DK3_FIG_LC_ROUND: {
+ back = 1;
+ dk3mem_res(
+ (void *)(&((obj->dt))),
+ sizeof(dk3_fig_obj_det_t)
+ );
+ obj->ot = DK3_FIG_OBJ_ELLIPSE;
+ obj->st = 3; /* Circle defined by radius */
+ obj->lw = 0;
+ obj->fc = obj->pc;
+ obj->fi = 20; /* Full saturation of color. */
+ obj->cs = DK3_FIG_LC_BUTT;
+ obj->js = DK3_FIG_LJ_MITER;
+ obj->ls = DK3_FIG_LS_SOLID;
+ obj->cl = 1;
+ (obj->dt).ell.an = 0.0;
+ (obj->dt).ell.cx = xa;
+ (obj->dt).ell.cy = ya;
+ (obj->dt).ell.rx = (obj->dt).ell.ry = r;
+ } break;
+ default: {
+ points = dk3_new_app(dk3_fig_poly_point_t,4,drw->app);
+ if(points) {
+ back = 1;
+ points[0].x = points[3].x = dk3ma_d_sub_ok(xa, r, &ec);
+ points[1].x = points[2].x = dk3ma_d_add_ok(xa, r, &ec);
+ points[0].y = points[1].y = dk3ma_d_sub_ok(ya, r, &ec);
+ points[2].y = points[3].y = dk3ma_d_add_ok(ya, r, &ec);
+ dk3mem_res(
+ (void *)(&((obj->dt))),
+ sizeof(dk3_fig_obj_det_t)
+ );
+ obj->ot = DK3_FIG_OBJ_POLYLINE;
+ obj->st = 3; /* Polygon */
+ obj->lw = 0;
+ obj->fc = obj->pc;
+ obj->fi = 20; /* Full saturation of color. */
+ obj->cs = DK3_FIG_LC_BUTT;
+ obj->js = DK3_FIG_LJ_MITER;
+ obj->ls = DK3_FIG_LS_SOLID;
+ obj->cl = 1;
+ (obj->dt).pol.fn = NULL;
+ (obj->dt).pol.po = points;
+ (obj->dt).pol.ra = 0.0;
+ (obj->dt).pol.xs = 0.0;
+ (obj->dt).pol.ys = 0.0;
+ (obj->dt).pol.xe = 0.0;
+ (obj->dt).pol.ye = 0.0;
+ (obj->dt).pol.np = 4;
+ (obj->dt).pol.flf = 0;
+ } else {
+ back = 0;
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } break;
+ }
+ } else {
+ points = dk3_new_app(dk3_fig_poly_point_t,2,drw->app);
+ if(points) {
+ back = 1;
+ points[0].x = xa;
+ points[0].y = ya;
+ points[1].x = xc;
+ points[1].y = yc;
+ (obj->dt).pol.fn = NULL;
+ (obj->dt).pol.po = points;
+ (obj->dt).pol.ra = 0.0;
+ (obj->dt).pol.xs = xa;
+ (obj->dt).pol.ys = ya;
+ (obj->dt).pol.xe = xc;
+ (obj->dt).pol.ye = yc;
+ (obj->dt).pol.np = 2;
+ (obj->dt).pol.flf = 0;
+ obj->ot = DK3_FIG_OBJ_POLYLINE;
+ obj->st = 1;
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ /* memory allocation failed, reported by back == 0. */
+ }
+ }
+ }
+ if(ec) {
+
+#line 329 "dk3figpr.ctr"
+ back = 0;
+ /* ERROR: Mathematical problem with arc! */
+ dk3fig_set_ec(drw, DK3_ERROR_MATH_OVERFLOW);
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 3);
+ }
+
+
+#line 335 "dk3figpr.ctr"
+ return back;
+}
+
+
+
+/** Convert polyline to circle or squara if necessary.
+ @param drw Drawing.
+ @param obj Object.
+ @param objno Object number (0 for first object).
+ @param primobj Flag: Primary object (1=object, 0=arrowhead).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3fig_prepare_initialize_polyline(
+ dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, unsigned long objno, int primobj
+)
+{
+ dk3_fig_poly_point_t *newpoints;
+ double cx;
+ double cy;
+ double r;
+ double x1;
+ double x2;
+ double y1;
+ double y2;
+ double eps = DK3_FIG_EPSILON;
+ int back = 1;
+ int mc = 0;
+ int ec = 0;
+
+
+#line 366 "dk3figpr.ctr"
+ if(1 == (obj->dt).pol.np) {
+ mc = 1;
+ } else {
+ if(2 == (obj->dt).pol.np) {
+ if(dk3ma_d_equal(((obj->dt).pol.po)[0].x, ((obj->dt).pol.po)[1].x, eps)) {
+ if(dk3ma_d_equal(((obj->dt).pol.po)[0].y, ((obj->dt).pol.po)[1].y, eps)) {
+ mc = 1;
+ }
+ }
+ }
+ }
+ if(mc) {
+ switch(obj->cs) {
+ case DK3_FIG_LC_ROUND: {
+
+#line 380 "dk3figpr.ctr"
+ cx = ((obj->dt).pol.po)[0].x;
+ cy = ((obj->dt).pol.po)[0].y;
+ r = 0.5 * dk3fig_tool_get_lw(drw, obj, &ec);
+ dk3_release((obj->dt).pol.fn);
+ dk3_release((obj->dt).pol.po);
+ dk3mem_res(
+ (void *)(&((obj->dt))),
+ sizeof(dk3_fig_obj_det_t)
+ );
+ obj->ot = DK3_FIG_OBJ_ELLIPSE;
+ obj->st = 3; /* Circle defined by radius */
+ obj->lw = 0;
+ obj->fc = obj->pc;
+ obj->fi = 20; /* Full saturation of color. */
+ obj->cs = DK3_FIG_LC_BUTT;
+ obj->js = DK3_FIG_LJ_MITER;
+ obj->ls = DK3_FIG_LS_SOLID;
+ obj->cl = 1;
+ (obj->dt).ell.an = 0.0;
+ (obj->dt).ell.cx = cx;
+ (obj->dt).ell.cy = cy;
+ (obj->dt).ell.rx = (obj->dt).ell.ry = r;
+ } break;
+ default: {
+
+#line 404 "dk3figpr.ctr"
+ cx = ((obj->dt).pol.po)[0].x;
+ cy = ((obj->dt).pol.po)[0].y;
+ r = 0.5 * dk3fig_tool_get_lw(drw, obj, &ec);
+ x1 = dk3ma_d_sub_ok(cx, r, &ec);
+ x2 = dk3ma_d_add_ok(cx, r, &ec);
+ y1 = dk3ma_d_sub_ok(cy, r, &ec);
+ y2 = dk3ma_d_add_ok(cy, r, &ec);
+ newpoints = dk3_new_app(dk3_fig_poly_point_t,4,drw->app);
+ if(newpoints) {
+ newpoints[0].x = x1; newpoints[0].y = y1;
+ newpoints[1].x = x2; newpoints[1].y = y1;
+ newpoints[2].x = x2; newpoints[2].y = y2;
+ newpoints[3].x = x1; newpoints[3].y = y2;
+ dk3_release((obj->dt).pol.fn);
+ dk3_release((obj->dt).pol.po);
+ dk3mem_res(
+ (void *)(&((obj->dt))),
+ sizeof(dk3_fig_obj_det_t)
+ );
+ obj->ot = DK3_FIG_OBJ_POLYLINE;
+ obj->st = 3; /* Polygon */
+ obj->lw = 0;
+ obj->fc = obj->pc;
+ obj->fi = 20; /* Full saturation of color. */
+ obj->cs = DK3_FIG_LC_BUTT;
+ obj->js = DK3_FIG_LJ_MITER;
+ obj->ls = DK3_FIG_LS_SOLID;
+ obj->cl = 1;
+ (obj->dt).pol.fn = NULL;
+ (obj->dt).pol.po = newpoints;
+ (obj->dt).pol.ra = 0.0;
+ (obj->dt).pol.xs = 0.0;
+ (obj->dt).pol.ys = 0.0;
+ (obj->dt).pol.xe = 0.0;
+ (obj->dt).pol.ye = 0.0;
+ (obj->dt).pol.np = 4;
+ (obj->dt).pol.flf = 0;
+ } else {
+ back = 0;
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } break;
+ }
+ }
+ if(ec) {
+
+#line 449 "dk3figpr.ctr"
+ /* ERROR: Math */
+ dk3fig_set_ec(drw, DK3_ERROR_MATH_OVERFLOW);
+ back = 0;
+ dk3app_log_i1(drw->app, DK3_LL_ERROR, 260);
+ }
+
+#line 454 "dk3figpr.ctr"
+ return back;
+}
+
+
+
+#if 0
+/*
+ Only polylines are allowed to have one point, not splines.
+*/
+/** Convert spline to circle or squara if necessary.
+ @param drw Drawing.
+ @param obj Object.
+ @param objno Object number (0 for first object).
+ @param primobj Flag: Primary object (1=object, 0=arrowhead).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3fig_prepare_initialize_spline(
+ dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, unsigned long objno, int primobj
+)
+{
+ dk3_fig_poly_point_t *newpoints;
+ double cx;
+ double cy;
+ double r;
+ double x1;
+ double x2;
+ double y1;
+ double y2;
+ double eps = DK3_FIG_EPSILON;
+ int back = 1;
+ int mc = 0;
+ int ec = 0;
+
+
+#line 489 "dk3figpr.ctr"
+ if(1 == (obj->dt).spl.np) {
+ mc = 1;
+ } else {
+ if(2 == (obj->dt).spl.np) {
+ if(dk3ma_d_equal(((obj->dt).spl.po)[0].x, ((obj->dt).spl.po)[1].x, eps)) {
+ if(dk3ma_d_equal(((obj->dt).spl.po)[0].y, ((obj->dt).spl.po)[1].y, eps)) {
+ mc = 1;
+ }
+ }
+ }
+ }
+ if(mc) {
+ switch(obj->cs) {
+ case DK3_FIG_LC_ROUND: {
+
+#line 503 "dk3figpr.ctr"
+ cx = ((obj->dt).spl.po)[0].x;
+ cy = ((obj->dt).spl.po)[0].y;
+ r = 0.5 * dk3fig_tool_get_lw(drw, obj, &ec);
+ dk3_release((obj->dt).spl.po);
+ dk3mem_res(
+ (void *)(&((obj->dt))),
+ sizeof(dk3_fig_obj_det_t)
+ );
+ obj->ot = DK3_FIG_OBJ_ELLIPSE;
+ obj->st = 3; /* Circle defined by radius */
+ obj->lw = 0;
+ obj->fc = obj->pc;
+ obj->fi = 20; /* Full saturation of color. */
+ obj->cs = DK3_FIG_LC_BUTT;
+ obj->js = DK3_FIG_LJ_MITER;
+ obj->ls = DK3_FIG_LS_SOLID;
+ obj->cl = 1;
+ (obj->dt).ell.an = 0.0;
+ (obj->dt).ell.cx = cx;
+ (obj->dt).ell.cy = cy;
+ (obj->dt).ell.rx = (obj->dt).ell.ry = r;
+ } break;
+ default: {
+
+#line 526 "dk3figpr.ctr"
+ cx = ((obj->dt).spl.po)[0].x;
+ cy = ((obj->dt).spl.po)[0].y;
+ r = 0.5 * dk3fig_tool_get_lw(drw, obj, &ec);
+ x1 = dk3ma_d_sub_ok(cx, r, &ec);
+ x2 = dk3ma_d_add_ok(cx, r, &ec);
+ y1 = dk3ma_d_sub_ok(cy, r, &ec);
+ y2 = dk3ma_d_add_ok(cy, r, &ec);
+ newpoints = dk3_new_app(dk3_fig_poly_point_t,4,drw->app);
+ if(newpoints) {
+ newpoints[0].x = x1; newpoints[0].y = y1;
+ newpoints[1].x = x2; newpoints[1].y = y1;
+ newpoints[2].x = x2; newpoints[2].y = y2;
+ newpoints[3].x = x1; newpoints[3].y = y2;
+ dk3_release((obj->dt).spl.po);
+ dk3mem_res(
+ (void *)(&((obj->dt))),
+ sizeof(dk3_fig_obj_det_t)
+ );
+ obj->ot = DK3_FIG_OBJ_POLYLINE;
+ obj->st = 3; /* Polygon */
+ obj->lw = 0;
+ obj->fc = obj->pc;
+ obj->fi = 20; /* Full saturation of color. */
+ obj->cs = DK3_FIG_LC_BUTT;
+ obj->js = DK3_FIG_LJ_MITER;
+ obj->ls = DK3_FIG_LS_SOLID;
+ obj->cl = 1;
+ (obj->dt).pol.fn = NULL;
+ (obj->dt).pol.po = newpoints;
+ (obj->dt).pol.ra = 0.0;
+ (obj->dt).pol.xs = 0.0;
+ (obj->dt).pol.ys = 0.0;
+ (obj->dt).pol.xe = 0.0;
+ (obj->dt).pol.ye = 0.0;
+ (obj->dt).pol.np = 4;
+ (obj->dt).pol.flf = 0;
+ } else {
+ back = 0;
+ }
+ } break;
+ }
+ }
+ if(ec) {
+
+#line 569 "dk3figpr.ctr"
+ dk3fig_set_ec(drw, DK3_ERROR_MATH_OVERFLOW);
+ /* ERROR: Math */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 38);
+ }
+
+#line 573 "dk3figpr.ctr"
+ return back;
+}
+#endif
+
+
+
+
+/** Object type specific initialization.
+ @param drw Drawing.
+ @param obj Object.
+ @param objno Object number (0 for first object).
+ @param primobj Flag: Primary object (1=object, 0=arrowhead).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3fig_prepare_initialize_object(
+ dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, unsigned long objno, int primobj
+)
+{
+ int back = 1;
+
+
+#line 595 "dk3figpr.ctr"
+ switch(obj->ot) {
+ case DK3_FIG_OBJ_POLYLINE: {
+ back = dk3fig_prepare_initialize_polyline(drw, obj, objno, primobj);
+ } break;
+#if 0
+ /*
+ Only polylines are allowed to have one point, not splines.
+ */
+ case DK3_FIG_OBJ_SPLINE: {
+ back = dk3fig_prepare_initialize_spline(drw, obj, objno, primobj);
+ } break;
+#endif
+ case DK3_FIG_OBJ_ARC: {
+ back = dk3fig_prepare_initialize_arc(drw, obj, objno, primobj);
+ } break;
+ }
+
+#line 611 "dk3figpr.ctr"
+ return back;
+}
+
+
+
+/** Add object to drawing bounding box.
+ @param drw Drawing to calculate the bounding box for.
+ @param obj Object to add to bounding box.
+ @param primobj Flag: Primary object (1=object, 0=arrowhead).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3fig_prepare_add_to_bb(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t const *obj,
+ int primobj
+);
+
+
+
+/** Add objects for one arrowhead to bounding box.
+ @param drw
+ @param obj
+ @param ah
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3fig_prepare_arrowhead_object(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t const *obj,
+ dk3_fig_ah_t const *ah
+)
+{
+ int back = 1;
+
+
+#line 648 "dk3figpr.ctr"
+ if(ah) {
+ if(ah->o1) {
+ if(!dk3fig_prepare_add_to_bb(drw, (dk3_fig_obj_t *)(ah->o1), 0)) {
+ back = 0;
+ }
+ }
+ if(ah->o2) {
+ if(!dk3fig_prepare_add_to_bb(drw, (dk3_fig_obj_t *)(ah->o2), 0)) {
+ back = 0;
+ }
+ }
+ if(!(back)) {
+ dk3fig_set_ec(drw, DK3_ERROR_MATH_OVERFLOW);
+ /* ERROR: Math overflow */
+ }
+ }
+
+#line 664 "dk3figpr.ctr"
+ return back;
+}
+
+
+
+int
+dk3fig_prepare_obj_bb(
+ dk3_bb_t *dbb,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t const *obj,
+ int primobj
+)
+{
+ int back = 0;
+ int notfound = 0;
+ switch(obj->ot) {
+ case DK3_FIG_OBJ_ELLIPSE: {
+
+#line 681 "dk3figpr.ctr"
+ back = dk3fig_bb_add_ellipse(
+ dbb, &((obj->dt).ell), (0.5 * dk3fig_tool_get_lw(drw, obj, NULL))
+ );
+ } break;
+ case DK3_FIG_OBJ_POLYLINE: {
+
+#line 686 "dk3figpr.ctr"
+ back = dk3fig_bb_add_polyline(
+ dbb, &((obj->dt).pol), (0.5 * dk3fig_tool_get_lw(drw, obj, NULL))
+ );
+ } break;
+ case DK3_FIG_OBJ_SPLINE: {
+
+#line 691 "dk3figpr.ctr"
+ back = dk3fig_bb_add_spline(
+ drw,
+ dbb, &((obj->dt).spl),
+ (0.5 * dk3fig_tool_get_lw(drw, obj, NULL)), primobj,
+ ((obj->cl) ? 1 : 0)
+ );
+ } break;
+ case DK3_FIG_OBJ_TEXT: {
+
+#line 699 "dk3figpr.ctr"
+ back = dk3fig_bb_add_text(
+ dbb, &((obj->dt).txt), drw->res, drw->bbts
+ );
+ } break;
+ case DK3_FIG_OBJ_ARC: {
+
+#line 704 "dk3figpr.ctr"
+ back = dk3fig_bb_add_arc(
+ dbb, &((obj->dt).arc),
+ ((1 != obj->st) ? 1 : 0),
+ (0.5 * dk3fig_tool_get_lw(drw, obj, NULL))
+ );
+ } break;
+ default: {
+
+#line 711 "dk3figpr.ctr"
+ dk3fig_set_ec(drw, DK3_ERROR_SYNTAX);
+ /* ERROR: Unknown object type! */
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 8);
+ notfound = 1;
+ } break;
+ }
+ if(!(back)) {
+ if(!(notfound)) {
+ dk3fig_set_ec(drw, DK3_ERROR_MATH_OVERFLOW);
+ /* ERROR: Math overflow */
+ }
+ }
+ return back;
+}
+
+
+
+static
+int
+dk3fig_prepare_add_to_bb(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t const *obj,
+ int primobj
+)
+{
+#if TEST_SHOW_EACH_BB
+ int back = 0;
+ dk3_bb_t mybb;
+
+
+#line 740 "dk3figpr.ctr"
+ dk3bb_reset(&mybb);
+ switch(obj->ot) {
+ case DK3_FIG_OBJ_ELLIPSE: {
+
+#line 743 "dk3figpr.ctr"
+ back = dk3fig_bb_add_ellipse(
+ &mybb, &((obj->dt).ell), (0.5 * dk3fig_tool_get_lw(drw, obj, NULL))
+ );
+ } break;
+ case DK3_FIG_OBJ_POLYLINE: {
+
+#line 748 "dk3figpr.ctr"
+ back = dk3fig_bb_add_polyline(
+ &mybb, &((obj->dt).pol), (0.5 * dk3fig_tool_get_lw(drw, obj, NULL))
+ );
+ } break;
+ case DK3_FIG_OBJ_SPLINE: {
+
+#line 753 "dk3figpr.ctr"
+ back = dk3fig_bb_add_spline(
+ drw,
+ &mybb, &((obj->dt).spl),
+ (0.5 * dk3fig_tool_get_lw(drw, obj, NULL)), primobj,
+ ((obj->cl) ? 1 : 0)
+ );
+ } break;
+ case DK3_FIG_OBJ_TEXT: {
+
+#line 761 "dk3figpr.ctr"
+ back = dk3fig_bb_add_text(
+ &mybb, &((obj->dt).txt), drw->res, drw->bbts
+ );
+ } break;
+ case DK3_FIG_OBJ_ARC: {
+
+#line 766 "dk3figpr.ctr"
+ back = dk3fig_bb_add_arc(
+ &mybb, &((obj->dt).arc),
+ ((1 != obj->st) ? 1 : 0),
+ (0.5 * dk3fig_tool_get_lw(drw, obj, NULL))
+ );
+ } break;
+ case DK3_FIG_OBJ_PSEUDO_HALF_CIRCLE: {
+ back = dk3fig_bb_add_hci(
+ &mybb, &(obj->dt).hci, (0.5 * dk3fig_tool_get_lw(drw, obj, NULL))
+ );
+ } break;
+ default: {
+
+#line 778 "dk3figpr.ctr"
+ } break;
+ }
+
+#line 780 "dk3figpr.ctr"
+ dk3bb_merge(&(drw->bb), &mybb);
+ if(primobj) {
+ if(!dk3fig_prepare_arrowhead_object(drw, obj, obj->af)) { back = 0; }
+ if(!dk3fig_prepare_arrowhead_object(drw, obj, obj->ab)) { back = 0; }
+ }
+ if(!(back)) {
+ /* ERROR: Math overflow */
+ dk3fig_set_ec(drw, DK3_ERROR_MATH_OVERFLOW);
+ dk3app_log_i1(drw->app, DK3_LL_ERROR, 260);
+ }
+
+
+#line 791 "dk3figpr.ctr"
+ return back;
+#else
+ int back = 0;
+
+
+#line 795 "dk3figpr.ctr"
+ switch(obj->ot) {
+ case DK3_FIG_OBJ_ELLIPSE: {
+
+#line 797 "dk3figpr.ctr"
+ back = dk3fig_bb_add_ellipse(
+ &(drw->bb), &((obj->dt).ell), (0.5 * dk3fig_tool_get_lw(drw, obj, NULL))
+ );
+ } break;
+ case DK3_FIG_OBJ_POLYLINE: {
+
+#line 802 "dk3figpr.ctr"
+ back = dk3fig_bb_add_polyline(
+ &(drw->bb), &((obj->dt).pol), (0.5 * dk3fig_tool_get_lw(drw, obj, NULL))
+ );
+ } break;
+ case DK3_FIG_OBJ_SPLINE: {
+
+#line 807 "dk3figpr.ctr"
+ back = dk3fig_bb_add_spline(
+ drw,
+ &(drw->bb), &((obj->dt).spl),
+ (0.5 * dk3fig_tool_get_lw(drw, obj, NULL)), primobj,
+ ((obj->cl) ? 1 : 0)
+ );
+ } break;
+ case DK3_FIG_OBJ_TEXT: {
+
+#line 815 "dk3figpr.ctr"
+ back = dk3fig_bb_add_text(
+ &(drw->bb), &((obj->dt).txt), drw->res, drw->bbts
+ );
+ } break;
+ case DK3_FIG_OBJ_ARC: {
+
+#line 820 "dk3figpr.ctr"
+ back = dk3fig_bb_add_arc(
+ &(drw->bb), &((obj->dt).arc),
+ ((1 != obj->st) ? 1 : 0),
+ (0.5 * dk3fig_tool_get_lw(drw, obj, NULL))
+ );
+ } break;
+ case DK3_FIG_OBJ_PSEUDO_HALF_CIRCLE: {
+ back = dk3fig_bb_add_hci(
+ &(drw->bb), &((obj->dt).hci), (0.5 * dk3fig_tool_get_lw(drw, obj, NULL))
+ );
+ } break;
+ default: {
+
+#line 832 "dk3figpr.ctr"
+ } break;
+ }
+ if(primobj) {
+ if(!dk3fig_prepare_arrowhead_object(drw, obj, obj->af)) { back = 0; }
+ if(!dk3fig_prepare_arrowhead_object(drw, obj, obj->ab)) { back = 0; }
+ }
+ if(!(back)) {
+ /* ERROR: Math overflow */
+ dk3fig_set_ec(drw, DK3_ERROR_MATH_OVERFLOW);
+ dk3app_log_i1(drw->app, DK3_LL_ERROR, 260);
+ }
+
+
+#line 844 "dk3figpr.ctr"
+ return back;
+#endif
+}
+
+
+
+#if TRACE_DEBUG
+/** Report object to trace file.
+ @param obj Object to report.
+ @param primobj Flag: Primary object (1=object, 0=arrowhead).
+*/
+static
+void
+dk3fig_prepare_report_object(dk3_fig_obj_t *obj, int primobj);
+
+/** Report one arrowhead to trace file.
+ @param ah Arrowhead to report.
+*/
+static
+void
+dk3fig_prepare_report_ah(dk3_fig_ah_t *ah)
+{
+ if(ah) {
+
+
+#line 868 "dk3figpr.ctr"
+ if(ah->o1) {
+ dk3fig_prepare_report_object((dk3_fig_obj_t *)(ah->o1), 0);
+ }
+ if(ah->o2) {
+ dk3fig_prepare_report_object((dk3_fig_obj_t *)(ah->o2), 0);
+ }
+
+
+#line 875 "dk3figpr.ctr"
+ }
+}
+
+
+
+static
+void
+dk3fig_prepare_report_object(dk3_fig_obj_t *obj, int primobj)
+{
+ FILE *fipo;
+ dk3_fig_poly_point_t *pp;
+ dk3_fig_spline_point_t *sp;
+ size_t i;
+
+
+#line 889 "dk3figpr.ctr"
+ fipo = dktrace_file();
+ if(fipo) {
+ switch(obj->ot) {
+ case DK3_FIG_OBJ_ELLIPSE: {
+ fputs("Ellipse\n", fipo);
+ switch(obj->st) {
+ case 1: {
+ fputs("Ellipse by radii\n", fipo);
+ } break;
+ case 2: {
+ fputs("Ellipse by diameter\n", fipo);
+ } break;
+ case 3: {
+ fputs("Circle by radius\n", fipo);
+ } break;
+ case 4: {
+ fputs("Circle by diameter\n", fipo);
+ } break;
+ default: {
+ fputs("UNKNOWN SUB-TYPE\n", fipo);
+ } break;
+ }
+ } break;
+ case DK3_FIG_OBJ_POLYLINE: {
+ fputs("Polyline\n", fipo);
+ switch(obj->st) {
+ case 1: {
+ fputs("Polyline\n", fipo);
+ } break;
+ case 2: {
+ fputs("Box\n", fipo);
+ } break;
+ case 3: {
+ fputs("Polygon\n", fipo);
+ } break;
+ case 4: {
+ fputs("Arc-box\n", fipo);
+ } break;
+ case 5: {
+ fputs("Imported image\n", fipo);
+ } break;
+ default: {
+ fputs("UNKNOWN SUBTYPE\n", fipo);
+ } break;
+ }
+ } break;
+ case DK3_FIG_OBJ_SPLINE: {
+ fputs("Spline\n", fipo);
+ switch(obj->st) {
+ case 0: {
+ fputs("Open approximated\n", fipo);
+ } break;
+ case 1: {
+ fputs("Closed approximated\n", fipo);
+ } break;
+ case 2: {
+ fputs("Open interpolated\n", fipo);
+ } break;
+ case 3: {
+ fputs("Closed interpolated\n", fipo);
+ } break;
+ case 4: {
+ fputs("Open X-spline\n", fipo);
+ } break;
+ case 5: {
+ fputs("Closed X-spline\n", fipo);
+ } break;
+ default: {
+ fputs("UNKNOWN SUBTYPE\n", fipo);
+ } break;
+ }
+ } break;
+ case DK3_FIG_OBJ_TEXT: {
+ fputs("Text\n", fipo);
+ switch(obj->st) {
+ case 0: {
+ fputs("Left-aligned\n", fipo);
+ } break;
+ case 1: {
+ fputs("Centered\n", fipo);
+ } break;
+ case 2: {
+ fputs("Right-aligned\n", fipo);
+ } break;
+ default: {
+ fputs("UNKNOWN SUB-TYPE\n", fipo);
+ } break;
+ }
+ } break;
+ case DK3_FIG_OBJ_ARC: {
+ fputs("Arc\n", fipo);
+ switch(obj->st) {
+ case 1: {
+ fputs("Open arc\n", fipo);
+ } break;
+ case 2: {
+ fputs("Closed arc\n", fipo);
+ } break;
+ default: {
+ fputs("UNKNOWN SUB-TYPE\n", fipo);
+ } break;
+ }
+ } break;
+ case DK3_FIG_OBJ_PSEUDO_HALF_CIRCLE: {
+ fputs("Half-circle\n", fipo);
+ if(obj->st) {
+ fputs("Closed filled half-circle\n", fipo);
+ } else {
+ fputs("Open half-circle\n", fipo);
+ }
+ } break;
+ default: {
+ fputs("UNKNOWN OBJECT TYPE\n", fipo);
+ } break;
+ }
+ fprintf(fipo, "Layer: %d\n", obj->la);
+ fprintf(fipo, "Line number: %lu\n", obj->li);
+ fprintf(fipo, "Closed: %d\n", obj->cl);
+ fprintf(fipo, "Line width: %d\n", obj->lw);
+ fprintf(fipo, "Pen color: %d\n", obj->pc);
+ fprintf(fipo, "Fill color: %d\n", obj->fc);
+ fprintf(fipo, "Fill type: %d\n", obj->fi);
+ fprintf(fipo, "Line cap: %d\n", obj->cs);
+ fprintf(fipo, "Line join: %d\n", obj->js);
+ fprintf(fipo, "Line style: %d\n", obj->ls);
+ fprintf(fipo, "Style value: %g\n", obj->sv);
+ switch(obj->ot) {
+ case DK3_FIG_OBJ_ELLIPSE: {
+ fprintf(fipo, "Center x: %g\n", (obj->dt).ell.cx);
+ fprintf(fipo, "Center y: %g\n", (obj->dt).ell.cy);
+ fprintf(fipo, "Radius x: %g\n", (obj->dt).ell.rx);
+ fprintf(fipo, "Radius y: %g\n", (obj->dt).ell.ry);
+ fprintf(fipo, "Angle: %g\n", (180.0 * (obj->dt).ell.an / M_PI));
+ } break;
+ case DK3_FIG_OBJ_POLYLINE: {
+ fprintf(fipo, "Radius: %g\n", (obj->dt).pol.ra);
+ fprintf(fipo, "Start x: %g\n", (obj->dt).pol.xs);
+ fprintf(fipo, "Start y: %g\n", (obj->dt).pol.ys);
+ fprintf(fipo, "End x: %g\n", (obj->dt).pol.xe);
+ fprintf(fipo, "End y: %g\n", (obj->dt).pol.ye);
+ if(5 == obj->st) {
+ fprintf(fipo, "Flip: %d\n", (obj->dt).pol.flf);
+ fprintf(fipo, "Image: \"%s\"", TR_8STR((obj->dt).pol.fn));
+ }
+ fprintf(fipo, "Points: %lu\n", (unsigned long)((obj->dt).pol.np));
+ if((obj->dt).pol.po) {
+ pp = (obj->dt).pol.po; i = (obj->dt).pol.np;
+ while(i--) {
+ fprintf(fipo, "%g %g\n", pp->x, pp->y);
+ pp++;
+ }
+ } else {
+ fprintf(fipo, "ERROR: NO POINTS!\n");
+ }
+ } break;
+ case DK3_FIG_OBJ_SPLINE: {
+ fprintf(fipo, "Start t: %g\n", (obj->dt).spl.ts);
+ fprintf(fipo, "End t: %g\n", (obj->dt).spl.te);
+ fprintf(fipo, "Points: %lu\n", (unsigned long)((obj->dt).spl.np));
+ if((obj->dt).spl.po) {
+ sp = (obj->dt).spl.po; i = (obj->dt).spl.np;
+ while(i--) {
+ fprintf(fipo, "%g %g %g\n", sp->x, sp->y, sp->s);
+ sp++;
+ }
+ } else {
+ fprintf(fipo, "ERROR: NO POINTS!\n");
+ }
+ } break;
+ case DK3_FIG_OBJ_TEXT: {
+ fprintf(fipo, "Position x: %g\n", (obj->dt).txt.x);
+ fprintf(fipo, "Position y: %g\n", (obj->dt).txt.y);
+ fprintf(fipo, "Angle: %g\n", (obj->dt).txt.an);
+ fprintf(fipo, "Text: \"%s\"\n", TR_8STR((obj->dt).txt.st));
+ fprintf(fipo, "Font flags: %d\n", (obj->dt).txt.ff);
+ fprintf(fipo, "Font: %d\n", (obj->dt).txt.fo);
+ fprintf(fipo, "Font size: %g\n", (obj->dt).txt.fs);
+ } break;
+ case DK3_FIG_OBJ_ARC: {
+ fprintf(fipo, "Center x: %g\n", (obj->dt).arc.xc);
+ fprintf(fipo, "Center y: %g\n", (obj->dt).arc.yc);
+ fprintf(fipo, "Radius: %g\n", (obj->dt).arc.ra);
+ fprintf(fipo, "Start: %g\n", (180.0 * (obj->dt).arc.as / M_PI));
+ fprintf(fipo, "End: %g\n", (180.0 * (obj->dt).arc.ae / M_PI));
+ fprintf(fipo, "Direction: %d", (int)((obj->dt).arc.di));
+ fprintf(fipo, "Point 1 x: %g\n", (obj->dt).arc.x1);
+ fprintf(fipo, "Point 1 y: %g\n", (obj->dt).arc.y1);
+ fprintf(fipo, "Point 2 x: %g\n", (obj->dt).arc.x2);
+ fprintf(fipo, "Point 2 y: %g\n", (obj->dt).arc.y2);
+ fprintf(fipo, "Point 3 x: %g\n", (obj->dt).arc.x3);
+ fprintf(fipo, "Point 3 y: %g\n", (obj->dt).arc.y3);
+ } break;
+ }
+ if(primobj) {
+ if(obj->af) {
+ fprintf(fipo, "ARROWHEAD FORWARD\n");
+ dk3fig_prepare_report_ah(obj->af);
+ }
+ if(obj->ab) {
+ fprintf(fipo, "ARROWHEAD BACKWARD\n");
+ dk3fig_prepare_report_ah(obj->ab);
+ }
+ }
+ }
+
+#line 1093 "dk3figpr.ctr"
+}
+#endif
+
+
+
+/** Check whether the object is an open path and filling is
+ required, change subtype to closed path if necessary.
+ @param drw Drawing containing the object.
+ @param obj Object to check.
+*/
+static
+void
+dk3fig_prepare_check_fill_open_path(dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj)
+{
+ switch(obj->ot) {
+ case DK3_FIG_OBJ_POLYLINE: {
+ if((-1 != obj->fi) && (drw->transcol != obj->fc)) {
+ switch(obj->st) {
+ case 1: {
+ if(drw->cofop) {
+ obj->st = 3;
+ obj->cl = 1;
+ if((drw->app) && (drw->msg)) {
+ dk3app_log_1(drw->app, DK3_LL_DEBUG, drw->msg, 10);
+ }
+ } else {
+ if((drw->app) && (drw->msg)) {
+ dk3app_log_1(drw->app, DK3_LL_WARNING, drw->msg, 9);
+ }
+ }
+ } break;
+ }
+ }
+ } break;
+ case DK3_FIG_OBJ_SPLINE: {
+ if((-1 != obj->fi) && (drw->transcol != obj->fc)) {
+ switch(obj->st) {
+ case 0: {
+ if(drw->cofop) {
+ obj->st = 1;
+ obj->cl = 1;
+ if((drw->app) && (drw->msg)) {
+ dk3app_log_1(drw->app, DK3_LL_DEBUG, drw->msg, 10);
+ }
+ } else {
+ if((drw->app) && (drw->msg)) {
+ dk3app_log_1(drw->app, DK3_LL_WARNING, drw->msg, 9);
+ }
+ }
+ } break;
+ case 2: {
+ if(drw->cofop) {
+ obj->st = 3;
+ obj->cl = 1;
+ if((drw->app) && (drw->msg)) {
+ dk3app_log_1(drw->app, DK3_LL_DEBUG, drw->msg, 10);
+ }
+ } else {
+ if((drw->app) && (drw->msg)) {
+ dk3app_log_1(drw->app, DK3_LL_WARNING, drw->msg, 9);
+ }
+ }
+ } break;
+ case 4: {
+ if(drw->cofop) {
+ obj->st = 5;
+ obj->cl = 1;
+ if((drw->app) && (drw->msg)) {
+ dk3app_log_1(drw->app, DK3_LL_DEBUG, drw->msg, 10);
+ }
+ } else {
+ if((drw->app) && (drw->msg)) {
+ dk3app_log_1(drw->app, DK3_LL_WARNING, drw->msg, 9);
+ }
+ }
+ } break;
+ }
+ }
+ } break;
+ }
+}
+
+
+
+/** Prepare one object.
+ @param drw Drawing.
+ @param obj Object to prepare.
+ @param objno Object number (starting at 0).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3fig_prepare_object(
+ dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, unsigned long objno
+)
+{
+ int back = 1;
+
+
+#line 1191 "dk3figpr.ctr"
+ /*
+ For object 0 check whether it is a background rectangle.
+ Set srctype.
+ */
+ dk3fig_prepare_check_bgrect(drw, obj, objno);
+ /* Check for open path to fill.
+ */
+ dk3fig_prepare_check_fill_open_path(drw, obj);
+ /*
+ Object type specific initialization.
+ For arcs calculate center point and radius.
+ */
+ if(!dk3fig_prepare_initialize_object(drw, obj, objno, 1)) {
+ back = 0;
+
+#line 1205 "dk3figpr.ctr"
+ }
+ /*
+ For open objects calculate arrowheads.
+ */
+ if(back) {
+ if(!dk3figah_calculate_arrowheads(drw, obj, objno)) {
+ back = 0;
+
+
+#line 1213 "dk3figpr.ctr"
+ }
+ }
+ /*
+ Add object to bounding box. For open objects add
+ arrowheads to bounding box too.
+ */
+ if(back) {
+
+#line 1220 "dk3figpr.ctr"
+ if(!dk3fig_prepare_add_to_bb(drw, obj, 1)) {
+ back = 0;
+
+#line 1222 "dk3figpr.ctr"
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 4);
+ }
+ }
+
+#line 1225 "dk3figpr.ctr"
+ return back;
+}
+
+
+
+int
+dk3fig_prepare(dk3_fig_drawing_t *drw)
+{
+ dk3_fig_obj_t *obj;
+ unsigned long oldsourceline = 0UL;
+ unsigned long objno = 0UL;
+ int back = 1;
+
+
+#line 1238 "dk3figpr.ctr"
+ /*
+ Reset bounding box.
+ */
+ dk3bb_reset(&(drw->bb));
+ /*
+ Prepare all drawing elements.
+ */
+ oldsourceline = dk3app_get_source_line(drw->app);
+ dk3sto_it_reset(drw->iobj);
+ while(NULL != (obj = (dk3_fig_obj_t *)dk3sto_it_next(drw->iobj))) {
+ dk3app_set_source_line(drw->app, obj->li);
+ if(!dk3fig_prepare_object(drw, obj, objno++)) {
+ back = 0;
+ }
+ }
+ dk3app_set_source_line(drw->app, oldsourceline);
+
+
+#line 1255 "dk3figpr.ctr"
+
+
+#line 1256 "dk3figpr.ctr"
+ return back;
+}
+
+
diff --git a/support/dktools/dk3figpr.ctr b/support/dktools/dk3figpr.ctr
new file mode 100644
index 0000000000..36669133d5
--- /dev/null
+++ b/support/dktools/dk3figpr.ctr
@@ -0,0 +1,1259 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Prepare drawing for printing.
+ This includes (1) allocating memory for arrowhead Fig objects,
+ (2) attaching arrowhead Fig objects for arrowheads, (3) shortening
+ the paths for arrowheads, and (4) finding
+ object and drawing bounding boxes.
+ @param drw Drawing to prepare.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3fig_prepare(dk3_fig_drawing_t *drw);
+
+/** Add object bounding box to bounding box structure.
+ @param dbb Destination bounding box.
+ @param drw Drawing structure.
+ @param obj Object to add.
+ @param primobj Flag: Primary object (1=object, 0=arrowhead).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3fig_prepare_obj_bb(
+ dk3_bb_t *dbb,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t const *obj,
+ int primobj
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk3all.h"
+#include "dk3fig.h"
+#include "dk3figto.h"
+#include "dk3figpr.h"
+#include "dk3figbb.h"
+#include "dk3figah.h"
+#include "fig2lat.h"
+
+$!trace-include
+
+
+
+/** If the first object is a background rectangle check
+ whether it was created by jFig or XFig.
+ @param drw Drawing.
+ @param obj Object to check.
+ @param objno Object number.
+*/
+static
+void
+dk3fig_prepare_check_bgrect(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ unsigned long objno
+)
+{
+ $? "+ dk3fig_prepare_check_bgrect"
+ if(dk3fig_tool_is_bgrect(obj, objno)) {
+ if(DK3_FIG_SRCTYPE_UNKNOWN == drw->srctype) {
+ switch(obj->pc) {
+ case 7: { $? ". jFig file"
+ drw->srctype = DK3_FIG_SRCTYPE_JFIG;
+ } break;
+ default: { $? ". XFig file"
+ drw->srctype = DK3_FIG_SRCTYPE_XFIG;
+ } break;
+ }
+ }
+ } $? "- dk3fig_prepare_check_bgrect"
+}
+
+
+
+#if TRACE_DEBUG
+/** Calculate distance of 2 points, used to verify the correct
+ radius calculation for args.
+ @param x1 Point 1 x.
+ @param x2 Point 2 x.
+ @param y1 Point 1 y.
+ @param y2 Point 2 y.
+ @return Distance between points.
+*/
+static
+double
+dk3fig_prepare_point_distance(
+ double x1, double x2, double y1, double y2
+)
+{
+ double back;
+ back = sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
+ return back;
+}
+#endif
+
+
+
+/** Initialize arc object (calculate center and radius).
+ @param drw Drawing.
+ @param obj Object.
+ @param objno Object number (0 for first object).
+ @param primobj Flag: Primary object (1=object, 0=arrowhead).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3fig_prepare_initialize_arc(
+ dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, unsigned long objno, int primobj
+)
+{
+ dk3_fig_poly_point_t *points;
+ dk3_fig_det_arc_t *arc;
+ double tm; /* The t parameter of the M point. */
+ double n; /* Denominator in tm calculation. */
+ double xa;
+ double ya;
+ double xc;
+ double yc;
+ double r;
+ double eps = DK3_FIG_EPSILON;
+ int back = 1;
+ int ec = 0;
+ int divec = 0;
+ $? "+ dk3fig_prepare_initialize_arc"
+ arc = &((obj->dt).arc);
+ n = dk3ma_d_sub_ok(
+ dk3ma_d_mul_ok(
+ dk3ma_d_sub_ok(arc->y2, arc->y1, &ec),
+ dk3ma_d_sub_ok(arc->x2, arc->x3, &ec),
+ &ec
+ ),
+ dk3ma_d_mul_ok(
+ dk3ma_d_sub_ok(arc->y3, arc->y2, &ec),
+ dk3ma_d_sub_ok(arc->x1, arc->x2, &ec),
+ &ec
+ ),
+ &ec
+ );
+ tm = 0.5 * dk3ma_d_div_ok(
+ dk3ma_d_sub_ok(
+ dk3ma_d_mul_ok(
+ dk3ma_d_sub_ok(arc->x2, arc->x3, &ec),
+ dk3ma_d_sub_ok(arc->x3, arc->x1, &ec),
+ &ec
+ ),
+ dk3ma_d_mul_ok(
+ dk3ma_d_sub_ok(arc->y3, arc->y2, &ec),
+ dk3ma_d_sub_ok(arc->y3, arc->y1, &ec),
+ &ec
+ ),
+ &ec
+ ),
+ n,
+ &divec
+ );
+ if(0 == divec) {
+ arc->xc = dk3ma_d_add_ok(
+ (0.5 * dk3ma_d_add_ok(arc->x1, arc->x2, &ec)),
+ dk3ma_d_mul_ok(
+ tm,
+ dk3ma_d_sub_ok(arc->y2, arc->y1, &ec),
+ &ec
+ ),
+ &ec
+ );
+ arc->yc = dk3ma_d_add_ok(
+ (0.5 * dk3ma_d_add_ok(arc->y1, arc->y2, &ec)),
+ dk3ma_d_mul_ok(
+ tm,
+ dk3ma_d_sub_ok(arc->x1, arc->x2, &ec),
+ &ec
+ ),
+ &ec
+ );
+ arc->ra = sqrt(
+ dk3ma_d_add_ok(
+ dk3ma_d_mul_ok(
+ dk3ma_d_sub_ok(arc->xc, arc->x1, &ec),
+ dk3ma_d_sub_ok(arc->xc, arc->x1, &ec),
+ &ec
+ ),
+ dk3ma_d_mul_ok(
+ dk3ma_d_sub_ok(arc->yc, arc->y1, &ec),
+ dk3ma_d_sub_ok(arc->yc, arc->y1, &ec),
+ &ec
+ ),
+ &ec
+ )
+ );
+ arc->as = dk3ma_d_atan2(
+ dk3ma_d_sub_ok(arc->y1, arc->yc, &ec),
+ dk3ma_d_sub_ok(arc->x1, arc->xc, &ec)
+ );
+ arc->ae = dk3ma_d_atan2(
+ dk3ma_d_sub_ok(arc->y3, arc->yc, &ec),
+ dk3ma_d_sub_ok(arc->x3, arc->xc, &ec)
+ );
+ if(n >= 0.0) {
+ arc->di = 0x01;
+ while(arc->ae < arc->as) {
+ arc->ae = arc->ae + (2.0 * M_PI);
+ }
+ } else {
+ arc->di = 0x00;
+ while(arc->as < arc->ae) {
+ arc->as = arc->as + (2.0 * M_PI);
+ }
+ }
+ $? ". point 1:\t%lg\t%lg", arc->x1, arc->y1
+ $? ". point 2:\t%lg\t%lg", arc->x2, arc->y2
+ $? ". point 3:\t%lg\t%lg", arc->x3, arc->y3
+ $? ". point M:\t%lg\t%lg", arc->xc, arc->yc
+ $? ". radius: \t%lg", arc->ra
+ $? ". r 1 : \t%lg", dk3fig_prepare_point_distance(arc->x1, arc->xc, arc->y1, arc->yc)
+ $? ". r 1 : \t%lg", dk3fig_prepare_point_distance(arc->x2, arc->xc, arc->y2, arc->yc)
+ $? ". r 1 : \t%lg", dk3fig_prepare_point_distance(arc->x3, arc->xc, arc->y3, arc->yc)
+ $? ". alphas: \t%lg", (180.0 * arc->as) / M_PI
+ $? ". alphae: \t%lg", (180.0 * arc->ae) / M_PI
+ $? ". dir: \t%!8s", ((arc->di) ? "pos" : "neg")
+ } else {
+ /* line */
+ back = 0;
+ xa = arc->x1;
+ ya = arc->y1;
+ xc = arc->x3;
+ yc = arc->y3;
+ if(dk3ma_d_equal(xa, xc, eps) && dk3ma_d_equal(ya, yc, eps)) {
+ r = 0.5 * dk3fig_tool_get_lw(drw, obj, &ec);
+ switch(obj->cs) {
+ case DK3_FIG_LC_ROUND: {
+ back = 1;
+ dk3mem_res(
+ (void *)(&((obj->dt))),
+ sizeof(dk3_fig_obj_det_t)
+ );
+ obj->ot = DK3_FIG_OBJ_ELLIPSE;
+ obj->st = 3; /* Circle defined by radius */
+ obj->lw = 0;
+ obj->fc = obj->pc;
+ obj->fi = 20; /* Full saturation of color. */
+ obj->cs = DK3_FIG_LC_BUTT;
+ obj->js = DK3_FIG_LJ_MITER;
+ obj->ls = DK3_FIG_LS_SOLID;
+ obj->cl = 1;
+ (obj->dt).ell.an = 0.0;
+ (obj->dt).ell.cx = xa;
+ (obj->dt).ell.cy = ya;
+ (obj->dt).ell.rx = (obj->dt).ell.ry = r;
+ } break;
+ default: {
+ points = dk3_new_app(dk3_fig_poly_point_t,4,drw->app);
+ if(points) {
+ back = 1;
+ points[0].x = points[3].x = dk3ma_d_sub_ok(xa, r, &ec);
+ points[1].x = points[2].x = dk3ma_d_add_ok(xa, r, &ec);
+ points[0].y = points[1].y = dk3ma_d_sub_ok(ya, r, &ec);
+ points[2].y = points[3].y = dk3ma_d_add_ok(ya, r, &ec);
+ dk3mem_res(
+ (void *)(&((obj->dt))),
+ sizeof(dk3_fig_obj_det_t)
+ );
+ obj->ot = DK3_FIG_OBJ_POLYLINE;
+ obj->st = 3; /* Polygon */
+ obj->lw = 0;
+ obj->fc = obj->pc;
+ obj->fi = 20; /* Full saturation of color. */
+ obj->cs = DK3_FIG_LC_BUTT;
+ obj->js = DK3_FIG_LJ_MITER;
+ obj->ls = DK3_FIG_LS_SOLID;
+ obj->cl = 1;
+ (obj->dt).pol.fn = NULL;
+ (obj->dt).pol.po = points;
+ (obj->dt).pol.ra = 0.0;
+ (obj->dt).pol.xs = 0.0;
+ (obj->dt).pol.ys = 0.0;
+ (obj->dt).pol.xe = 0.0;
+ (obj->dt).pol.ye = 0.0;
+ (obj->dt).pol.np = 4;
+ (obj->dt).pol.flf = 0;
+ } else {
+ back = 0;
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } break;
+ }
+ } else {
+ points = dk3_new_app(dk3_fig_poly_point_t,2,drw->app);
+ if(points) {
+ back = 1;
+ points[0].x = xa;
+ points[0].y = ya;
+ points[1].x = xc;
+ points[1].y = yc;
+ (obj->dt).pol.fn = NULL;
+ (obj->dt).pol.po = points;
+ (obj->dt).pol.ra = 0.0;
+ (obj->dt).pol.xs = xa;
+ (obj->dt).pol.ys = ya;
+ (obj->dt).pol.xe = xc;
+ (obj->dt).pol.ye = yc;
+ (obj->dt).pol.np = 2;
+ (obj->dt).pol.flf = 0;
+ obj->ot = DK3_FIG_OBJ_POLYLINE;
+ obj->st = 1;
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ /* memory allocation failed, reported by back == 0. */
+ }
+ }
+ }
+ if(ec) { $? "! math problem in arc"
+ back = 0;
+ /* ERROR: Mathematical problem with arc! */
+ dk3fig_set_ec(drw, DK3_ERROR_MATH_OVERFLOW);
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 3);
+ }
+ $? "- dk3fig_prepare_initialize_arc %d", back
+ return back;
+}
+
+
+
+/** Convert polyline to circle or squara if necessary.
+ @param drw Drawing.
+ @param obj Object.
+ @param objno Object number (0 for first object).
+ @param primobj Flag: Primary object (1=object, 0=arrowhead).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3fig_prepare_initialize_polyline(
+ dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, unsigned long objno, int primobj
+)
+{
+ dk3_fig_poly_point_t *newpoints;
+ double cx;
+ double cy;
+ double r;
+ double x1;
+ double x2;
+ double y1;
+ double y2;
+ double eps = DK3_FIG_EPSILON;
+ int back = 1;
+ int mc = 0;
+ int ec = 0;
+ $? "+ dk3fig_prepare_initialize_polyline"
+ if(1 == (obj->dt).pol.np) {
+ mc = 1;
+ } else {
+ if(2 == (obj->dt).pol.np) {
+ if(dk3ma_d_equal(((obj->dt).pol.po)[0].x, ((obj->dt).pol.po)[1].x, eps)) {
+ if(dk3ma_d_equal(((obj->dt).pol.po)[0].y, ((obj->dt).pol.po)[1].y, eps)) {
+ mc = 1;
+ }
+ }
+ }
+ }
+ if(mc) {
+ switch(obj->cs) {
+ case DK3_FIG_LC_ROUND: { $? ". convert polyline dot to circle"
+ cx = ((obj->dt).pol.po)[0].x;
+ cy = ((obj->dt).pol.po)[0].y;
+ r = 0.5 * dk3fig_tool_get_lw(drw, obj, &ec);
+ dk3_release((obj->dt).pol.fn);
+ dk3_release((obj->dt).pol.po);
+ dk3mem_res(
+ (void *)(&((obj->dt))),
+ sizeof(dk3_fig_obj_det_t)
+ );
+ obj->ot = DK3_FIG_OBJ_ELLIPSE;
+ obj->st = 3; /* Circle defined by radius */
+ obj->lw = 0;
+ obj->fc = obj->pc;
+ obj->fi = 20; /* Full saturation of color. */
+ obj->cs = DK3_FIG_LC_BUTT;
+ obj->js = DK3_FIG_LJ_MITER;
+ obj->ls = DK3_FIG_LS_SOLID;
+ obj->cl = 1;
+ (obj->dt).ell.an = 0.0;
+ (obj->dt).ell.cx = cx;
+ (obj->dt).ell.cy = cy;
+ (obj->dt).ell.rx = (obj->dt).ell.ry = r;
+ } break;
+ default: { $? ". convert polyline dot to square"
+ cx = ((obj->dt).pol.po)[0].x;
+ cy = ((obj->dt).pol.po)[0].y;
+ r = 0.5 * dk3fig_tool_get_lw(drw, obj, &ec);
+ x1 = dk3ma_d_sub_ok(cx, r, &ec);
+ x2 = dk3ma_d_add_ok(cx, r, &ec);
+ y1 = dk3ma_d_sub_ok(cy, r, &ec);
+ y2 = dk3ma_d_add_ok(cy, r, &ec);
+ newpoints = dk3_new_app(dk3_fig_poly_point_t,4,drw->app);
+ if(newpoints) {
+ newpoints[0].x = x1; newpoints[0].y = y1;
+ newpoints[1].x = x2; newpoints[1].y = y1;
+ newpoints[2].x = x2; newpoints[2].y = y2;
+ newpoints[3].x = x1; newpoints[3].y = y2;
+ dk3_release((obj->dt).pol.fn);
+ dk3_release((obj->dt).pol.po);
+ dk3mem_res(
+ (void *)(&((obj->dt))),
+ sizeof(dk3_fig_obj_det_t)
+ );
+ obj->ot = DK3_FIG_OBJ_POLYLINE;
+ obj->st = 3; /* Polygon */
+ obj->lw = 0;
+ obj->fc = obj->pc;
+ obj->fi = 20; /* Full saturation of color. */
+ obj->cs = DK3_FIG_LC_BUTT;
+ obj->js = DK3_FIG_LJ_MITER;
+ obj->ls = DK3_FIG_LS_SOLID;
+ obj->cl = 1;
+ (obj->dt).pol.fn = NULL;
+ (obj->dt).pol.po = newpoints;
+ (obj->dt).pol.ra = 0.0;
+ (obj->dt).pol.xs = 0.0;
+ (obj->dt).pol.ys = 0.0;
+ (obj->dt).pol.xe = 0.0;
+ (obj->dt).pol.ye = 0.0;
+ (obj->dt).pol.np = 4;
+ (obj->dt).pol.flf = 0;
+ } else {
+ back = 0;
+ dk3fig_set_ec(drw, DK3_ERROR_MEMORY);
+ }
+ } break;
+ }
+ }
+ if(ec) { $? "! math error"
+ /* ERROR: Math */
+ dk3fig_set_ec(drw, DK3_ERROR_MATH_OVERFLOW);
+ back = 0;
+ dk3app_log_i1(drw->app, DK3_LL_ERROR, 260);
+ } $? "- dk3fig_prepare_initialize_polyline %d", back
+ return back;
+}
+
+
+
+#if 0
+/*
+ Only polylines are allowed to have one point, not splines.
+*/
+/** Convert spline to circle or squara if necessary.
+ @param drw Drawing.
+ @param obj Object.
+ @param objno Object number (0 for first object).
+ @param primobj Flag: Primary object (1=object, 0=arrowhead).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3fig_prepare_initialize_spline(
+ dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, unsigned long objno, int primobj
+)
+{
+ dk3_fig_poly_point_t *newpoints;
+ double cx;
+ double cy;
+ double r;
+ double x1;
+ double x2;
+ double y1;
+ double y2;
+ double eps = DK3_FIG_EPSILON;
+ int back = 1;
+ int mc = 0;
+ int ec = 0;
+ $? "+ dk3fig_prepare_initialize_spline"
+ if(1 == (obj->dt).spl.np) {
+ mc = 1;
+ } else {
+ if(2 == (obj->dt).spl.np) {
+ if(dk3ma_d_equal(((obj->dt).spl.po)[0].x, ((obj->dt).spl.po)[1].x, eps)) {
+ if(dk3ma_d_equal(((obj->dt).spl.po)[0].y, ((obj->dt).spl.po)[1].y, eps)) {
+ mc = 1;
+ }
+ }
+ }
+ }
+ if(mc) {
+ switch(obj->cs) {
+ case DK3_FIG_LC_ROUND: { $? ". convert spline dot to circle"
+ cx = ((obj->dt).spl.po)[0].x;
+ cy = ((obj->dt).spl.po)[0].y;
+ r = 0.5 * dk3fig_tool_get_lw(drw, obj, &ec);
+ dk3_release((obj->dt).spl.po);
+ dk3mem_res(
+ (void *)(&((obj->dt))),
+ sizeof(dk3_fig_obj_det_t)
+ );
+ obj->ot = DK3_FIG_OBJ_ELLIPSE;
+ obj->st = 3; /* Circle defined by radius */
+ obj->lw = 0;
+ obj->fc = obj->pc;
+ obj->fi = 20; /* Full saturation of color. */
+ obj->cs = DK3_FIG_LC_BUTT;
+ obj->js = DK3_FIG_LJ_MITER;
+ obj->ls = DK3_FIG_LS_SOLID;
+ obj->cl = 1;
+ (obj->dt).ell.an = 0.0;
+ (obj->dt).ell.cx = cx;
+ (obj->dt).ell.cy = cy;
+ (obj->dt).ell.rx = (obj->dt).ell.ry = r;
+ } break;
+ default: { $? ". convert spline dot to square"
+ cx = ((obj->dt).spl.po)[0].x;
+ cy = ((obj->dt).spl.po)[0].y;
+ r = 0.5 * dk3fig_tool_get_lw(drw, obj, &ec);
+ x1 = dk3ma_d_sub_ok(cx, r, &ec);
+ x2 = dk3ma_d_add_ok(cx, r, &ec);
+ y1 = dk3ma_d_sub_ok(cy, r, &ec);
+ y2 = dk3ma_d_add_ok(cy, r, &ec);
+ newpoints = dk3_new_app(dk3_fig_poly_point_t,4,drw->app);
+ if(newpoints) {
+ newpoints[0].x = x1; newpoints[0].y = y1;
+ newpoints[1].x = x2; newpoints[1].y = y1;
+ newpoints[2].x = x2; newpoints[2].y = y2;
+ newpoints[3].x = x1; newpoints[3].y = y2;
+ dk3_release((obj->dt).spl.po);
+ dk3mem_res(
+ (void *)(&((obj->dt))),
+ sizeof(dk3_fig_obj_det_t)
+ );
+ obj->ot = DK3_FIG_OBJ_POLYLINE;
+ obj->st = 3; /* Polygon */
+ obj->lw = 0;
+ obj->fc = obj->pc;
+ obj->fi = 20; /* Full saturation of color. */
+ obj->cs = DK3_FIG_LC_BUTT;
+ obj->js = DK3_FIG_LJ_MITER;
+ obj->ls = DK3_FIG_LS_SOLID;
+ obj->cl = 1;
+ (obj->dt).pol.fn = NULL;
+ (obj->dt).pol.po = newpoints;
+ (obj->dt).pol.ra = 0.0;
+ (obj->dt).pol.xs = 0.0;
+ (obj->dt).pol.ys = 0.0;
+ (obj->dt).pol.xe = 0.0;
+ (obj->dt).pol.ye = 0.0;
+ (obj->dt).pol.np = 4;
+ (obj->dt).pol.flf = 0;
+ } else {
+ back = 0;
+ }
+ } break;
+ }
+ }
+ if(ec) { $? "! math error"
+ dk3fig_set_ec(drw, DK3_ERROR_MATH_OVERFLOW);
+ /* ERROR: Math */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 38);
+ } $? "- dk3fig_prepare_initialize_spline %d", back
+ return back;
+}
+#endif
+
+
+
+
+/** Object type specific initialization.
+ @param drw Drawing.
+ @param obj Object.
+ @param objno Object number (0 for first object).
+ @param primobj Flag: Primary object (1=object, 0=arrowhead).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3fig_prepare_initialize_object(
+ dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, unsigned long objno, int primobj
+)
+{
+ int back = 1;
+ $? "+ dk3fig_prepare_initialize_object"
+ switch(obj->ot) {
+ case DK3_FIG_OBJ_POLYLINE: {
+ back = dk3fig_prepare_initialize_polyline(drw, obj, objno, primobj);
+ } break;
+#if 0
+ /*
+ Only polylines are allowed to have one point, not splines.
+ */
+ case DK3_FIG_OBJ_SPLINE: {
+ back = dk3fig_prepare_initialize_spline(drw, obj, objno, primobj);
+ } break;
+#endif
+ case DK3_FIG_OBJ_ARC: {
+ back = dk3fig_prepare_initialize_arc(drw, obj, objno, primobj);
+ } break;
+ } $? "- dk3fig_prepare_initialize_object %d", back
+ return back;
+}
+
+
+
+/** Add object to drawing bounding box.
+ @param drw Drawing to calculate the bounding box for.
+ @param obj Object to add to bounding box.
+ @param primobj Flag: Primary object (1=object, 0=arrowhead).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3fig_prepare_add_to_bb(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t const *obj,
+ int primobj
+);
+
+
+
+/** Add objects for one arrowhead to bounding box.
+ @param drw
+ @param obj
+ @param ah
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3fig_prepare_arrowhead_object(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t const *obj,
+ dk3_fig_ah_t const *ah
+)
+{
+ int back = 1;
+ $? "+ dk3fig_prepare_arrowhead_object"
+ if(ah) {
+ if(ah->o1) {
+ if(!dk3fig_prepare_add_to_bb(drw, (dk3_fig_obj_t *)(ah->o1), 0)) {
+ back = 0;
+ }
+ }
+ if(ah->o2) {
+ if(!dk3fig_prepare_add_to_bb(drw, (dk3_fig_obj_t *)(ah->o2), 0)) {
+ back = 0;
+ }
+ }
+ if(!(back)) {
+ dk3fig_set_ec(drw, DK3_ERROR_MATH_OVERFLOW);
+ /* ERROR: Math overflow */
+ }
+ } $? "- dk3fig_prepare_arrowhead_object %d", back
+ return back;
+}
+
+
+
+int
+dk3fig_prepare_obj_bb(
+ dk3_bb_t *dbb,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t const *obj,
+ int primobj
+)
+{
+ int back = 0;
+ int notfound = 0;
+ switch(obj->ot) {
+ case DK3_FIG_OBJ_ELLIPSE: { $? ". ellipse"
+ back = dk3fig_bb_add_ellipse(
+ dbb, &((obj->dt).ell), (0.5 * dk3fig_tool_get_lw(drw, obj, NULL))
+ );
+ } break;
+ case DK3_FIG_OBJ_POLYLINE: { $? ". polyline %d lw=%d", obj->la, obj->lw
+ back = dk3fig_bb_add_polyline(
+ dbb, &((obj->dt).pol), (0.5 * dk3fig_tool_get_lw(drw, obj, NULL))
+ );
+ } break;
+ case DK3_FIG_OBJ_SPLINE: { $? ". spline"
+ back = dk3fig_bb_add_spline(
+ drw,
+ dbb, &((obj->dt).spl),
+ (0.5 * dk3fig_tool_get_lw(drw, obj, NULL)), primobj,
+ ((obj->cl) ? 1 : 0)
+ );
+ } break;
+ case DK3_FIG_OBJ_TEXT: { $? ". text"
+ back = dk3fig_bb_add_text(
+ dbb, &((obj->dt).txt), drw->res, drw->bbts
+ );
+ } break;
+ case DK3_FIG_OBJ_ARC: { $? ". arc"
+ back = dk3fig_bb_add_arc(
+ dbb, &((obj->dt).arc),
+ ((1 != obj->st) ? 1 : 0),
+ (0.5 * dk3fig_tool_get_lw(drw, obj, NULL))
+ );
+ } break;
+ default: { $? "! unknown object"
+ dk3fig_set_ec(drw, DK3_ERROR_SYNTAX);
+ /* ERROR: Unknown object type! */
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 8);
+ notfound = 1;
+ } break;
+ }
+ if(!(back)) {
+ if(!(notfound)) {
+ dk3fig_set_ec(drw, DK3_ERROR_MATH_OVERFLOW);
+ /* ERROR: Math overflow */
+ }
+ }
+ return back;
+}
+
+
+
+static
+int
+dk3fig_prepare_add_to_bb(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t const *obj,
+ int primobj
+)
+{
+#if TEST_SHOW_EACH_BB
+ int back = 0;
+ dk3_bb_t mybb;
+ $? "+ dk3fig_prepare_add_to_bb"
+ dk3bb_reset(&mybb);
+ switch(obj->ot) {
+ case DK3_FIG_OBJ_ELLIPSE: { $? ". ellipse"
+ back = dk3fig_bb_add_ellipse(
+ &mybb, &((obj->dt).ell), (0.5 * dk3fig_tool_get_lw(drw, obj, NULL))
+ );
+ } break;
+ case DK3_FIG_OBJ_POLYLINE: { $? ". polyline %d lw=%d", obj->la, obj->lw
+ back = dk3fig_bb_add_polyline(
+ &mybb, &((obj->dt).pol), (0.5 * dk3fig_tool_get_lw(drw, obj, NULL))
+ );
+ } break;
+ case DK3_FIG_OBJ_SPLINE: { $? ". spline"
+ back = dk3fig_bb_add_spline(
+ drw,
+ &mybb, &((obj->dt).spl),
+ (0.5 * dk3fig_tool_get_lw(drw, obj, NULL)), primobj,
+ ((obj->cl) ? 1 : 0)
+ );
+ } break;
+ case DK3_FIG_OBJ_TEXT: { $? ". text"
+ back = dk3fig_bb_add_text(
+ &mybb, &((obj->dt).txt), drw->res, drw->bbts
+ );
+ } break;
+ case DK3_FIG_OBJ_ARC: { $? ". arc"
+ back = dk3fig_bb_add_arc(
+ &mybb, &((obj->dt).arc),
+ ((1 != obj->st) ? 1 : 0),
+ (0.5 * dk3fig_tool_get_lw(drw, obj, NULL))
+ );
+ } break;
+ case DK3_FIG_OBJ_PSEUDO_HALF_CIRCLE: {
+ back = dk3fig_bb_add_hci(
+ &mybb, &(obj->dt).hci, (0.5 * dk3fig_tool_get_lw(drw, obj, NULL))
+ );
+ } break;
+ default: { $? "! unknown object"
+ } break;
+ } $? ". bb x = %lg %lg y = %lg %lg",mybb.xmin,mybb.xmax,mybb.ymin,mybb.ymax
+ dk3bb_merge(&(drw->bb), &mybb);
+ if(primobj) {
+ if(!dk3fig_prepare_arrowhead_object(drw, obj, obj->af)) { back = 0; }
+ if(!dk3fig_prepare_arrowhead_object(drw, obj, obj->ab)) { back = 0; }
+ }
+ if(!(back)) {
+ /* ERROR: Math overflow */
+ dk3fig_set_ec(drw, DK3_ERROR_MATH_OVERFLOW);
+ dk3app_log_i1(drw->app, DK3_LL_ERROR, 260);
+ }
+ $? "- dk3fig_prepare_add_to_bb %d", back
+ return back;
+#else
+ int back = 0;
+ $? "+ dk3fig_prepare_add_to_bb"
+ switch(obj->ot) {
+ case DK3_FIG_OBJ_ELLIPSE: { $? ". ellipse"
+ back = dk3fig_bb_add_ellipse(
+ &(drw->bb), &((obj->dt).ell), (0.5 * dk3fig_tool_get_lw(drw, obj, NULL))
+ );
+ } break;
+ case DK3_FIG_OBJ_POLYLINE: { $? ". polyline %d lw=%d", obj->la, obj->lw
+ back = dk3fig_bb_add_polyline(
+ &(drw->bb), &((obj->dt).pol), (0.5 * dk3fig_tool_get_lw(drw, obj, NULL))
+ );
+ } break;
+ case DK3_FIG_OBJ_SPLINE: { $? ". spline"
+ back = dk3fig_bb_add_spline(
+ drw,
+ &(drw->bb), &((obj->dt).spl),
+ (0.5 * dk3fig_tool_get_lw(drw, obj, NULL)), primobj,
+ ((obj->cl) ? 1 : 0)
+ );
+ } break;
+ case DK3_FIG_OBJ_TEXT: { $? ". text"
+ back = dk3fig_bb_add_text(
+ &(drw->bb), &((obj->dt).txt), drw->res, drw->bbts
+ );
+ } break;
+ case DK3_FIG_OBJ_ARC: { $? ". arc"
+ back = dk3fig_bb_add_arc(
+ &(drw->bb), &((obj->dt).arc),
+ ((1 != obj->st) ? 1 : 0),
+ (0.5 * dk3fig_tool_get_lw(drw, obj, NULL))
+ );
+ } break;
+ case DK3_FIG_OBJ_PSEUDO_HALF_CIRCLE: {
+ back = dk3fig_bb_add_hci(
+ &(drw->bb), &((obj->dt).hci), (0.5 * dk3fig_tool_get_lw(drw, obj, NULL))
+ );
+ } break;
+ default: { $? "! unknown object"
+ } break;
+ }
+ if(primobj) {
+ if(!dk3fig_prepare_arrowhead_object(drw, obj, obj->af)) { back = 0; }
+ if(!dk3fig_prepare_arrowhead_object(drw, obj, obj->ab)) { back = 0; }
+ }
+ if(!(back)) {
+ /* ERROR: Math overflow */
+ dk3fig_set_ec(drw, DK3_ERROR_MATH_OVERFLOW);
+ dk3app_log_i1(drw->app, DK3_LL_ERROR, 260);
+ }
+ $? "- dk3fig_prepare_add_to_bb %d", back
+ return back;
+#endif
+}
+
+
+
+#if TRACE_DEBUG
+/** Report object to trace file.
+ @param obj Object to report.
+ @param primobj Flag: Primary object (1=object, 0=arrowhead).
+*/
+static
+void
+dk3fig_prepare_report_object(dk3_fig_obj_t *obj, int primobj);
+
+/** Report one arrowhead to trace file.
+ @param ah Arrowhead to report.
+*/
+static
+void
+dk3fig_prepare_report_ah(dk3_fig_ah_t *ah)
+{
+ if(ah) {
+ $? "+ dk3fig_prepare_report_ah"
+ if(ah->o1) {
+ dk3fig_prepare_report_object((dk3_fig_obj_t *)(ah->o1), 0);
+ }
+ if(ah->o2) {
+ dk3fig_prepare_report_object((dk3_fig_obj_t *)(ah->o2), 0);
+ }
+ $? "- dk3fig_prepare_report_ah"
+ }
+}
+
+
+
+static
+void
+dk3fig_prepare_report_object(dk3_fig_obj_t *obj, int primobj)
+{
+ FILE *fipo;
+ dk3_fig_poly_point_t *pp;
+ dk3_fig_spline_point_t *sp;
+ size_t i;
+ $? "+ dk3fig_prepare_report_object primary=%d", primobj
+ fipo = dktrace_file();
+ if(fipo) {
+ switch(obj->ot) {
+ case DK3_FIG_OBJ_ELLIPSE: {
+ fputs("Ellipse\n", fipo);
+ switch(obj->st) {
+ case 1: {
+ fputs("Ellipse by radii\n", fipo);
+ } break;
+ case 2: {
+ fputs("Ellipse by diameter\n", fipo);
+ } break;
+ case 3: {
+ fputs("Circle by radius\n", fipo);
+ } break;
+ case 4: {
+ fputs("Circle by diameter\n", fipo);
+ } break;
+ default: {
+ fputs("UNKNOWN SUB-TYPE\n", fipo);
+ } break;
+ }
+ } break;
+ case DK3_FIG_OBJ_POLYLINE: {
+ fputs("Polyline\n", fipo);
+ switch(obj->st) {
+ case 1: {
+ fputs("Polyline\n", fipo);
+ } break;
+ case 2: {
+ fputs("Box\n", fipo);
+ } break;
+ case 3: {
+ fputs("Polygon\n", fipo);
+ } break;
+ case 4: {
+ fputs("Arc-box\n", fipo);
+ } break;
+ case 5: {
+ fputs("Imported image\n", fipo);
+ } break;
+ default: {
+ fputs("UNKNOWN SUBTYPE\n", fipo);
+ } break;
+ }
+ } break;
+ case DK3_FIG_OBJ_SPLINE: {
+ fputs("Spline\n", fipo);
+ switch(obj->st) {
+ case 0: {
+ fputs("Open approximated\n", fipo);
+ } break;
+ case 1: {
+ fputs("Closed approximated\n", fipo);
+ } break;
+ case 2: {
+ fputs("Open interpolated\n", fipo);
+ } break;
+ case 3: {
+ fputs("Closed interpolated\n", fipo);
+ } break;
+ case 4: {
+ fputs("Open X-spline\n", fipo);
+ } break;
+ case 5: {
+ fputs("Closed X-spline\n", fipo);
+ } break;
+ default: {
+ fputs("UNKNOWN SUBTYPE\n", fipo);
+ } break;
+ }
+ } break;
+ case DK3_FIG_OBJ_TEXT: {
+ fputs("Text\n", fipo);
+ switch(obj->st) {
+ case 0: {
+ fputs("Left-aligned\n", fipo);
+ } break;
+ case 1: {
+ fputs("Centered\n", fipo);
+ } break;
+ case 2: {
+ fputs("Right-aligned\n", fipo);
+ } break;
+ default: {
+ fputs("UNKNOWN SUB-TYPE\n", fipo);
+ } break;
+ }
+ } break;
+ case DK3_FIG_OBJ_ARC: {
+ fputs("Arc\n", fipo);
+ switch(obj->st) {
+ case 1: {
+ fputs("Open arc\n", fipo);
+ } break;
+ case 2: {
+ fputs("Closed arc\n", fipo);
+ } break;
+ default: {
+ fputs("UNKNOWN SUB-TYPE\n", fipo);
+ } break;
+ }
+ } break;
+ case DK3_FIG_OBJ_PSEUDO_HALF_CIRCLE: {
+ fputs("Half-circle\n", fipo);
+ if(obj->st) {
+ fputs("Closed filled half-circle\n", fipo);
+ } else {
+ fputs("Open half-circle\n", fipo);
+ }
+ } break;
+ default: {
+ fputs("UNKNOWN OBJECT TYPE\n", fipo);
+ } break;
+ }
+ fprintf(fipo, "Layer: %d\n", obj->la);
+ fprintf(fipo, "Line number: %lu\n", obj->li);
+ fprintf(fipo, "Closed: %d\n", obj->cl);
+ fprintf(fipo, "Line width: %d\n", obj->lw);
+ fprintf(fipo, "Pen color: %d\n", obj->pc);
+ fprintf(fipo, "Fill color: %d\n", obj->fc);
+ fprintf(fipo, "Fill type: %d\n", obj->fi);
+ fprintf(fipo, "Line cap: %d\n", obj->cs);
+ fprintf(fipo, "Line join: %d\n", obj->js);
+ fprintf(fipo, "Line style: %d\n", obj->ls);
+ fprintf(fipo, "Style value: %g\n", obj->sv);
+ switch(obj->ot) {
+ case DK3_FIG_OBJ_ELLIPSE: {
+ fprintf(fipo, "Center x: %g\n", (obj->dt).ell.cx);
+ fprintf(fipo, "Center y: %g\n", (obj->dt).ell.cy);
+ fprintf(fipo, "Radius x: %g\n", (obj->dt).ell.rx);
+ fprintf(fipo, "Radius y: %g\n", (obj->dt).ell.ry);
+ fprintf(fipo, "Angle: %g\n", (180.0 * (obj->dt).ell.an / M_PI));
+ } break;
+ case DK3_FIG_OBJ_POLYLINE: {
+ fprintf(fipo, "Radius: %g\n", (obj->dt).pol.ra);
+ fprintf(fipo, "Start x: %g\n", (obj->dt).pol.xs);
+ fprintf(fipo, "Start y: %g\n", (obj->dt).pol.ys);
+ fprintf(fipo, "End x: %g\n", (obj->dt).pol.xe);
+ fprintf(fipo, "End y: %g\n", (obj->dt).pol.ye);
+ if(5 == obj->st) {
+ fprintf(fipo, "Flip: %d\n", (obj->dt).pol.flf);
+ fprintf(fipo, "Image: \"%s\"", TR_8STR((obj->dt).pol.fn));
+ }
+ fprintf(fipo, "Points: %lu\n", (unsigned long)((obj->dt).pol.np));
+ if((obj->dt).pol.po) {
+ pp = (obj->dt).pol.po; i = (obj->dt).pol.np;
+ while(i--) {
+ fprintf(fipo, "%g %g\n", pp->x, pp->y);
+ pp++;
+ }
+ } else {
+ fprintf(fipo, "ERROR: NO POINTS!\n");
+ }
+ } break;
+ case DK3_FIG_OBJ_SPLINE: {
+ fprintf(fipo, "Start t: %g\n", (obj->dt).spl.ts);
+ fprintf(fipo, "End t: %g\n", (obj->dt).spl.te);
+ fprintf(fipo, "Points: %lu\n", (unsigned long)((obj->dt).spl.np));
+ if((obj->dt).spl.po) {
+ sp = (obj->dt).spl.po; i = (obj->dt).spl.np;
+ while(i--) {
+ fprintf(fipo, "%g %g %g\n", sp->x, sp->y, sp->s);
+ sp++;
+ }
+ } else {
+ fprintf(fipo, "ERROR: NO POINTS!\n");
+ }
+ } break;
+ case DK3_FIG_OBJ_TEXT: {
+ fprintf(fipo, "Position x: %g\n", (obj->dt).txt.x);
+ fprintf(fipo, "Position y: %g\n", (obj->dt).txt.y);
+ fprintf(fipo, "Angle: %g\n", (obj->dt).txt.an);
+ fprintf(fipo, "Text: \"%s\"\n", TR_8STR((obj->dt).txt.st));
+ fprintf(fipo, "Font flags: %d\n", (obj->dt).txt.ff);
+ fprintf(fipo, "Font: %d\n", (obj->dt).txt.fo);
+ fprintf(fipo, "Font size: %g\n", (obj->dt).txt.fs);
+ } break;
+ case DK3_FIG_OBJ_ARC: {
+ fprintf(fipo, "Center x: %g\n", (obj->dt).arc.xc);
+ fprintf(fipo, "Center y: %g\n", (obj->dt).arc.yc);
+ fprintf(fipo, "Radius: %g\n", (obj->dt).arc.ra);
+ fprintf(fipo, "Start: %g\n", (180.0 * (obj->dt).arc.as / M_PI));
+ fprintf(fipo, "End: %g\n", (180.0 * (obj->dt).arc.ae / M_PI));
+ fprintf(fipo, "Direction: %d", (int)((obj->dt).arc.di));
+ fprintf(fipo, "Point 1 x: %g\n", (obj->dt).arc.x1);
+ fprintf(fipo, "Point 1 y: %g\n", (obj->dt).arc.y1);
+ fprintf(fipo, "Point 2 x: %g\n", (obj->dt).arc.x2);
+ fprintf(fipo, "Point 2 y: %g\n", (obj->dt).arc.y2);
+ fprintf(fipo, "Point 3 x: %g\n", (obj->dt).arc.x3);
+ fprintf(fipo, "Point 3 y: %g\n", (obj->dt).arc.y3);
+ } break;
+ }
+ if(primobj) {
+ if(obj->af) {
+ fprintf(fipo, "ARROWHEAD FORWARD\n");
+ dk3fig_prepare_report_ah(obj->af);
+ }
+ if(obj->ab) {
+ fprintf(fipo, "ARROWHEAD BACKWARD\n");
+ dk3fig_prepare_report_ah(obj->ab);
+ }
+ }
+ } $? "- dk3fig_prepare_report_object"
+}
+#endif
+
+
+
+/** Check whether the object is an open path and filling is
+ required, change subtype to closed path if necessary.
+ @param drw Drawing containing the object.
+ @param obj Object to check.
+*/
+static
+void
+dk3fig_prepare_check_fill_open_path(dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj)
+{
+ switch(obj->ot) {
+ case DK3_FIG_OBJ_POLYLINE: {
+ if((-1 != obj->fi) && (drw->transcol != obj->fc)) {
+ switch(obj->st) {
+ case 1: {
+ if(drw->cofop) {
+ obj->st = 3;
+ obj->cl = 1;
+ if((drw->app) && (drw->msg)) {
+ dk3app_log_1(drw->app, DK3_LL_DEBUG, drw->msg, 10);
+ }
+ } else {
+ if((drw->app) && (drw->msg)) {
+ dk3app_log_1(drw->app, DK3_LL_WARNING, drw->msg, 9);
+ }
+ }
+ } break;
+ }
+ }
+ } break;
+ case DK3_FIG_OBJ_SPLINE: {
+ if((-1 != obj->fi) && (drw->transcol != obj->fc)) {
+ switch(obj->st) {
+ case 0: {
+ if(drw->cofop) {
+ obj->st = 1;
+ obj->cl = 1;
+ if((drw->app) && (drw->msg)) {
+ dk3app_log_1(drw->app, DK3_LL_DEBUG, drw->msg, 10);
+ }
+ } else {
+ if((drw->app) && (drw->msg)) {
+ dk3app_log_1(drw->app, DK3_LL_WARNING, drw->msg, 9);
+ }
+ }
+ } break;
+ case 2: {
+ if(drw->cofop) {
+ obj->st = 3;
+ obj->cl = 1;
+ if((drw->app) && (drw->msg)) {
+ dk3app_log_1(drw->app, DK3_LL_DEBUG, drw->msg, 10);
+ }
+ } else {
+ if((drw->app) && (drw->msg)) {
+ dk3app_log_1(drw->app, DK3_LL_WARNING, drw->msg, 9);
+ }
+ }
+ } break;
+ case 4: {
+ if(drw->cofop) {
+ obj->st = 5;
+ obj->cl = 1;
+ if((drw->app) && (drw->msg)) {
+ dk3app_log_1(drw->app, DK3_LL_DEBUG, drw->msg, 10);
+ }
+ } else {
+ if((drw->app) && (drw->msg)) {
+ dk3app_log_1(drw->app, DK3_LL_WARNING, drw->msg, 9);
+ }
+ }
+ } break;
+ }
+ }
+ } break;
+ }
+}
+
+
+
+/** Prepare one object.
+ @param drw Drawing.
+ @param obj Object to prepare.
+ @param objno Object number (starting at 0).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3fig_prepare_object(
+ dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj, unsigned long objno
+)
+{
+ int back = 1;
+ $? "+ dk3fig_prepare_object"
+ /*
+ For object 0 check whether it is a background rectangle.
+ Set srctype.
+ */
+ dk3fig_prepare_check_bgrect(drw, obj, objno);
+ /* Check for open path to fill.
+ */
+ dk3fig_prepare_check_fill_open_path(drw, obj);
+ /*
+ Object type specific initialization.
+ For arcs calculate center point and radius.
+ */
+ if(!dk3fig_prepare_initialize_object(drw, obj, objno, 1)) {
+ back = 0; $? "! initialization failed"
+ }
+ /*
+ For open objects calculate arrowheads.
+ */
+ if(back) {
+ if(!dk3figah_calculate_arrowheads(drw, obj, objno)) {
+ back = 0;
+ $? "! arrowhead calculation failed"
+ }
+ }
+ /*
+ Add object to bounding box. For open objects add
+ arrowheads to bounding box too.
+ */
+ if(back) { $!trace-code dk3fig_prepare_report_object(obj, 1);
+ if(!dk3fig_prepare_add_to_bb(drw, obj, 1)) {
+ back = 0; $? "! add to bb failed"
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 4);
+ }
+ } $? "- dk3fig_prepare_object %d", back
+ return back;
+}
+
+
+
+int
+dk3fig_prepare(dk3_fig_drawing_t *drw)
+{
+ dk3_fig_obj_t *obj;
+ unsigned long oldsourceline = 0UL;
+ unsigned long objno = 0UL;
+ int back = 1;
+ $? "+ dk3fig_prepare"
+ /*
+ Reset bounding box.
+ */
+ dk3bb_reset(&(drw->bb));
+ /*
+ Prepare all drawing elements.
+ */
+ oldsourceline = dk3app_get_source_line(drw->app);
+ dk3sto_it_reset(drw->iobj);
+ while(NULL != (obj = (dk3_fig_obj_t *)dk3sto_it_next(drw->iobj))) {
+ dk3app_set_source_line(drw->app, obj->li);
+ if(!dk3fig_prepare_object(drw, obj, objno++)) {
+ back = 0;
+ }
+ }
+ dk3app_set_source_line(drw->app, oldsourceline);
+ $? ". x = %lg ... %lg y = %lg ... %lg", (drw->bb).xmin, (drw->bb).xmax, (drw->bb).ymin, (drw->bb).ymax
+ $? "- dk3fig_prepare %d", back
+ return back;
+}
+
+
diff --git a/support/dktools/dk3figpr.h b/support/dktools/dk3figpr.h
new file mode 100644
index 0000000000..3e22e1b80a
--- /dev/null
+++ b/support/dktools/dk3figpr.h
@@ -0,0 +1,83 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3figpr.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3figpr.h Header file for the dk3figpr module.
+*/
+
+#ifndef DK3FIGPR_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3FIGPR_H_INCLUDED 1
+
+
+#line 10 "dk3figpr.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Prepare drawing for printing.
+ This includes (1) allocating memory for arrowhead Fig objects,
+ (2) attaching arrowhead Fig objects for arrowheads, (3) shortening
+ the paths for arrowheads, and (4) finding
+ object and drawing bounding boxes.
+ @param drw Drawing to prepare.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3fig_prepare(dk3_fig_drawing_t *drw);
+
+/** Add object bounding box to bounding box structure.
+ @param dbb Destination bounding box.
+ @param drw Drawing structure.
+ @param obj Object to add.
+ @param primobj Flag: Primary object (1=object, 0=arrowhead).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3fig_prepare_obj_bb(
+ dk3_bb_t *dbb,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t const *obj,
+ int primobj
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3figrd.c b/support/dktools/dk3figrd.c
new file mode 100644
index 0000000000..67d1a26fee
--- /dev/null
+++ b/support/dktools/dk3figrd.c
@@ -0,0 +1,2128 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3figrd.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3figrd.c The dk3figrd module.
+*/
+
+
+#line 45 "dk3figrd.ctr"
+
+#include "dk3all.h"
+#include "dk3fig.h"
+#include "dk3figrd.h"
+#include "fig2lat.h"
+
+
+
+
+
+#line 54 "dk3figrd.ctr"
+
+
+
+/** Keywords used by the module, not localized.
+*/
+static dkChar const * const dk3figrd_kw[] = {
+/* 0 */
+dkT("r"),
+
+NULL
+
+
+#line 66 "dk3figrd.ctr"
+};
+
+
+/** Keywords used by the module.
+*/
+static char const * const dk3figrd_c8_kw[] = {
+/* 0 */
+"C",
+
+/* 1 */
+"Created",
+
+/* 2 */
+"by",
+
+/* 3 */
+"WinFIG",
+
+NULL
+
+
+#line 84 "dk3figrd.ctr"
+};
+
+
+/** File type tag at start of file.
+*/
+static char const dk3figrd_file_start_tag[] = { "#FIG 3.2" };
+
+
+
+/** Error reporting function.
+ @param drw Drawing structure.
+ @param res Operation result (1=success, 0=error).
+ @param ec Error code (1=syntax, 2=memory, 3=redefinition).
+*/
+static
+void
+dk3figrd_report_error_code(dk3_fig_drawing_t *drw, int res, int ec)
+{
+ if(!(res)) {
+ switch(ec) {
+ case 1: {
+ /* ERROR: Syntax */
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1);
+ } break;
+ case 2: {
+ /* ERROR: Memory */
+ dk3app_log_i1(drw->app, DK3_LL_ERROR, 9);
+ } break;
+ case 3: {
+ /* ERROR: Color redefinition */
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 2);
+ } break;
+ }
+ }
+}
+
+
+
+/** Expect file identifier.
+ @param drw Drawing to modify.
+ @param lp Text line to process.
+ @return 1 on success (identifier found or comment line).
+*/
+static
+int
+dk3figrd_expect_start(dk3_fig_drawing_t *drw, char *lp)
+{
+ int back = 0;
+
+
+#line 133 "dk3figrd.ctr"
+ if('#' == *lp) {
+ back = 1;
+ if(7 < dk3str_c8_len(lp)) {
+ if(0 == dk3str_c8_ncmp(lp, dk3figrd_file_start_tag, 8)) {
+ drw->state = DK3_FIG_RD_STATE_EXPECT_ORIENTATION;
+ } else {
+
+#line 139 "dk3figrd.ctr"
+ }
+ } else {
+
+#line 141 "dk3figrd.ctr"
+ }
+ } else {
+
+#line 143 "dk3figrd.ctr"
+ }
+ if(!(back)) {
+ dk3fig_set_ec(drw, DK3_ERROR_SYNTAX);
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1);
+ }
+
+#line 148 "dk3figrd.ctr"
+ return back;
+}
+
+
+
+/** Retrieve transparent color number.
+ @param drw Drawing to modify.
+ @param lp Text line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figrd_expect_transparent(dk3_fig_drawing_t *drw, char *lp)
+{
+ int back = 0;
+ int i;
+ if(1 == sscanf(lp, "%d", &i)) {
+ back = 1;
+ drw->state = DK3_FIG_RD_STATE_EXPECT_RESOLUTION;
+ drw->transcol = i;
+
+#line 168 "dk3figrd.ctr"
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_SYNTAX);
+ /* ERROR: Not a number! */
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1);
+ }
+ return back;
+}
+
+
+
+/** Retrieve resolution.
+ @param drw Drawing to modify.
+ @param lp Text line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figrd_expect_resolution(dk3_fig_drawing_t *drw, char *lp)
+{
+ long lres;
+ int back = 0;
+ if(1 == sscanf(lp, "%ld", &lres)) {
+ if(0L < lres) {
+ drw->lres = lres;
+#if VERSION_BEFORE_20140716
+ drw->res = dk3ma_l_to_d(lres);
+#else
+ drw->res = (double)lres;
+#endif
+ back = 1;
+ drw->state = DK3_FIG_RD_STATE_READY;
+ }
+ }
+ if(!(back)) { dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); }
+ dk3figrd_report_error_code(drw, back, 1);
+ return back;
+}
+
+
+
+/** Get a hexadecimal digit.
+ @param c Character to process.
+ @param x Pointer to result variable.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figrd_hex_digit(char c, int *x)
+{
+ int back = 0;
+ switch(c) {
+ case '0': { *x = 0; back = 1; } break;
+ case '1': { *x = 1; back = 1; } break;
+ case '2': { *x = 2; back = 1; } break;
+ case '3': { *x = 3; back = 1; } break;
+ case '4': { *x = 4; back = 1; } break;
+ case '5': { *x = 5; back = 1; } break;
+ case '6': { *x = 6; back = 1; } break;
+ case '7': { *x = 7; back = 1; } break;
+ case '8': { *x = 8; back = 1; } break;
+ case '9': { *x = 9; back = 1; } break;
+ case 'a': { *x = 10; back = 1; } break;
+ case 'A': { *x = 10; back = 1; } break;
+ case 'b': { *x = 11; back = 1; } break;
+ case 'B': { *x = 11; back = 1; } break;
+ case 'c': { *x = 12; back = 1; } break;
+ case 'C': { *x = 12; back = 1; } break;
+ case 'd': { *x = 13; back = 1; } break;
+ case 'D': { *x = 13; back = 1; } break;
+ case 'e': { *x = 14; back = 1; } break;
+ case 'E': { *x = 14; back = 1; } break;
+ case 'f': { *x = 15; back = 1; } break;
+ case 'F': { *x = 15; back = 1; } break;
+ }
+ return back;
+}
+
+
+
+/** Read color object.
+ @param drw Drawing to modify.
+ @param args Arguments in color line.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figrd_color_object(dk3_fig_drawing_t *drw, char *args)
+{
+ dk3_fig_color_t col; /* Temporary buffer. */
+ dk3_fig_color_t *pcol; /* Object found in storage. */
+ char *pn; /* Next word to process. */
+ int x; /* Temporary variable. */
+ int back = 0;
+ int ec = 1; /* 1=syntax, 2=memory, 3=redef */
+
+
+#line 263 "dk3figrd.ctr"
+ if(args) {
+ pn = dk3str_c8_next(args, NULL);
+ if(pn) {
+ if(1 == sscanf(args, "%d", &(col.i))) {
+ if(31 < col.i) {
+ if('#' == *(pn++)) {
+ col.r = col.g = col.b = x = 0;
+ if(dk3figrd_hex_digit(*(pn++), &x)) {
+ col.r = x;
+ if(dk3figrd_hex_digit(*(pn++), &x)) {
+ col.r = 16 * col.r + x;
+ if(dk3figrd_hex_digit(*(pn++), &x)) {
+ col.g = x;
+ if(dk3figrd_hex_digit(*(pn++), &x)) {
+ col.g = 16 * col.g + x;
+ if(dk3figrd_hex_digit(*(pn++), &x)) {
+ col.b = x;
+ if(dk3figrd_hex_digit(*(pn++), &x)) {
+ col.b = 16 * col.b + x;
+ if(dk3sto_it_find_like(drw->icol, (void *)(&col), 0)) {
+ ec = 3;
+ } else {
+ pcol = dk3_new_app(dk3_fig_color_t,1,drw->app);
+ if(pcol) {
+ /* 2013-01-15: Copy color data to new buffer!
+ */
+ dk3mem_cpy(
+ (void *)pcol, (void *)(&col),
+ sizeof(dk3_fig_color_t)
+ );
+ if(dk3sto_add(drw->scol, (void *)pcol)) {
+ back = 1;
+ } else {
+ dk3_delete(pcol);
+ ec = 2;
+ }
+ } else {
+ ec = 2;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if(!(back)) {
+ switch(ec) {
+ case 1: case 3: { dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); } break;
+ case 2: { dk3fig_set_ec(drw, DK3_ERROR_MEMORY); } break;
+ }
+ }
+ dk3figrd_report_error_code(drw, back, ec);
+
+
+#line 322 "dk3figrd.ctr"
+ return back;
+}
+
+
+
+/** Complete arc.
+ @param drw Drawing to modify.
+ @param tobj Object to complete.
+ @param args Object arguments in start line.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figrd_arc_complete(dk3_fig_drawing_t *drw, dk3_fig_obj_t *tobj, char *args)
+{
+ dk3_fig_obj_t *pobj; /* New object. */
+ char *pc; /* Current text word to process. */
+ char *pn; /* Next text word to process. */
+ int i; /* Index of current text word. */
+ int af = 0; /* Flag: Arrowhead forward. */
+ int ab = 0; /* Flag: Arrowhead backward. */
+ int ec = 1; /* Error code. */
+ int back = 1;
+
+
+#line 346 "dk3figrd.ctr"
+ pc = args;
+ for(i = 0; ((back) && (pc) && (i < 12)); i++) {
+ pn = dk3str_c8_next(pc, NULL);
+ switch(i) {
+ case 0: { /* int cap style */
+ if(1 != sscanf(pc, "%d", &(tobj->cs))) {
+
+#line 352 "dk3figrd.ctr"
+ back = 0;
+ }
+ } break;
+ case 1: { /* int direction 0=clockwise, ignored */
+ } break;
+ case 2: { /* int arrow forward */
+ if(1 != sscanf(pc, "%d", &af)) {
+
+#line 359 "dk3figrd.ctr"
+ back = 0;
+ }
+ } break;
+ case 3: { /* int arrow backward */
+ if(1 != sscanf(pc, "%d", &ab)) {
+
+#line 364 "dk3figrd.ctr"
+ back = 0;
+ }
+ } break;
+ case 4: { /* double cx */
+ if(1 != sscanf(pc, "%lg", &((tobj->dt).arc.xc))) {
+
+#line 369 "dk3figrd.ctr"
+ back = 0;
+ }
+ } break;
+ case 5: { /* double cy */
+ if(1 != sscanf(pc, "%lg", &((tobj->dt).arc.yc))) {
+
+#line 374 "dk3figrd.ctr"
+ back = 0;
+ }
+ } break;
+ case 6: { /* double x1 */
+ if(1 != sscanf(pc, "%lg", &((tobj->dt).arc.x1))) {
+
+#line 379 "dk3figrd.ctr"
+ back = 0;
+ }
+ } break;
+ case 7: { /* double y1 */
+ if(1 != sscanf(pc, "%lg", &((tobj->dt).arc.y1))) {
+
+#line 384 "dk3figrd.ctr"
+ back = 0;
+ }
+ } break;
+ case 8: { /* double x2 */
+ if(1 != sscanf(pc, "%lg", &((tobj->dt).arc.x2))) {
+
+#line 389 "dk3figrd.ctr"
+ back = 0;
+ }
+ } break;
+ case 9: { /* double y2 */
+ if(1 != sscanf(pc, "%lg", &((tobj->dt).arc.y2))) {
+
+#line 394 "dk3figrd.ctr"
+ back = 0;
+ }
+ } break;
+ case 10: { /* double x3 */
+ if(1 != sscanf(pc, "%lg", &((tobj->dt).arc.x3))) {
+
+#line 399 "dk3figrd.ctr"
+ back = 0;
+ }
+ } break;
+ case 11: { /* double y3 */
+ if(1 != sscanf(pc, "%lg", &((tobj->dt).arc.y3))) {
+
+#line 404 "dk3figrd.ctr"
+ back = 0;
+ }
+ } break;
+ }
+ if(!(pc)) {
+ if(i < 11) {
+
+#line 410 "dk3figrd.ctr"
+ back = 0;
+ }
+ }
+ pc = pn;
+ }
+ if(back) {
+
+#line 416 "dk3figrd.ctr"
+ pobj = dk3fig_obj_new(
+ drw->lineno, tobj->la, tobj->ot, tobj->st, tobj->lw, tobj->pc, tobj->fc,
+ tobj->fi, tobj->cs, tobj->js, tobj->ls, tobj->sv, af, ab,
+ 0, NULL, drw->app
+ );
+ if(pobj) {
+
+
+#line 423 "dk3figrd.ctr"
+
+
+#line 424 "dk3figrd.ctr"
+ if(dk3sto_add(drw->sobj, (void *)pobj)) {
+ dk3mem_cpy(
+ (void *)(&((pobj->dt).arc)),
+ (void *)(&((tobj->dt).arc)),
+ sizeof(dk3_fig_det_arc_t)
+ );
+ if(pobj->ab) {
+ drw->state = DK3_FIG_RD_STATE_ARC_ARROW_BACKWARD;
+ }
+ if(pobj->af) {
+ drw->state = DK3_FIG_RD_STATE_ARC_ARROW_FORWARD;
+ }
+ drw->cobj = pobj;
+ } else {
+ back = 0; ec = 2;
+
+#line 439 "dk3figrd.ctr"
+ dk3fig_obj_delete(pobj);
+ }
+ } else {
+ back = 0; ec = 2;
+
+#line 443 "dk3figrd.ctr"
+ }
+ }
+ if(!(back)) {
+ switch(ec) {
+ case 1: { dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); } break;
+ case 2: { dk3fig_set_ec(drw, DK3_ERROR_MEMORY); } break;
+ }
+ }
+ dk3figrd_report_error_code(drw, back, ec);
+
+
+#line 453 "dk3figrd.ctr"
+ return back;
+}
+
+
+
+/** Complete ellipse.
+ @param drw Drawing to modify.
+ @param tobj Object to complete.
+ @param args Object arguments in start line.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figrd_ellipse_complete(
+ dk3_fig_drawing_t *drw, dk3_fig_obj_t *tobj, char *args
+)
+{
+ dk3_fig_obj_t *pobj; /* New object. */
+ char *pc; /* Current text word to process. */
+ char *pn; /* Next text to process. */
+ int i; /* Index of current text word. */
+ int ec = 1; /* Error code. */
+ int back = 1;
+
+
+#line 477 "dk3figrd.ctr"
+ pc = args;
+ for(i = 0; ((back) && (pc) && (i < 10)); i++) {
+ pn = dk3str_c8_next(pc, NULL);
+ switch(i) {
+ case 0: { /* direction, ignored */
+ } break;
+ case 1: { /* angle */
+ if(1 != sscanf(pc, "%lg", &((tobj->dt).ell.an))) {
+
+#line 485 "dk3figrd.ctr"
+ back = 0;
+ }
+
+#line 487 "dk3figrd.ctr"
+ } break;
+ case 2: { /* cx */
+ if(1 != sscanf(pc, "%lg", &((tobj->dt).ell.cx))) {
+
+#line 490 "dk3figrd.ctr"
+ back = 0;
+ }
+ } break;
+ case 3: { /* cy */
+ if(1 != sscanf(pc, "%lg", &((tobj->dt).ell.cy))) {
+
+#line 495 "dk3figrd.ctr"
+ back = 0;
+ }
+ } break;
+ case 4: { /* rx */
+ if(1 != sscanf(pc, "%lg", &((tobj->dt).ell.rx))) {
+
+#line 500 "dk3figrd.ctr"
+ back = 0;
+ }
+ } break;
+ case 5: { /* ry */
+ if(1 != sscanf(pc, "%lg", &((tobj->dt).ell.ry))) {
+
+#line 505 "dk3figrd.ctr"
+ back = 0;
+ }
+ } break;
+ case 6: { /* start x */
+ } break;
+ case 7: { /* start y */
+ } break;
+ case 8: { /* end x */
+ } break;
+ case 9: { /* end y */
+ } break;
+ }
+ pc = pn;
+ if(!(pc)) {
+ if(i < 9) {
+
+#line 520 "dk3figrd.ctr"
+ back = 0;
+ }
+ }
+ }
+ if(back) {
+ pobj = dk3fig_obj_new(
+ drw->lineno, tobj->la, tobj->ot, tobj->st, tobj->lw, tobj->pc, tobj->fc,
+ tobj->fi, tobj->cs, tobj->js, tobj->ls, tobj->sv, 0, 0,
+ 0, NULL, drw->app
+ );
+ if(pobj) {
+ if(dk3sto_add(drw->sobj, (void *)pobj)) {
+ dk3mem_cpy(
+ (void *)(&((pobj->dt).ell)),
+ (void *)(&((tobj->dt).ell)),
+ sizeof(dk3_fig_det_ell_t)
+ );
+ } else {
+ back = 0; ec = 2;
+ dk3fig_obj_delete(pobj);
+ }
+ } else {
+ back = 0; ec = 2;
+ }
+ }
+ if(!(back)) {
+ switch(ec) {
+ case 1: { dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); } break;
+ case 2: { dk3fig_set_ec(drw, DK3_ERROR_MEMORY); } break;
+ }
+ }
+ dk3figrd_report_error_code(drw, back, ec);
+
+
+#line 553 "dk3figrd.ctr"
+ return back;
+}
+
+
+
+/** Complete polyline.
+ @param drw Drawing to modify.
+ @param tobj Object to complete.
+ @param args Object arguments in start line.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figrd_polyline_complete(
+ dk3_fig_drawing_t *drw, dk3_fig_obj_t *tobj, char *args
+)
+{
+ dk3_fig_obj_t *pobj; /* New object. */
+ char *pc; /* Current text word to process. */
+ char *pn; /* Next text to process. */
+#if VERSION_BEFORE_20140809
+ unsigned u; /* Number of points. */
+#endif
+ int i; /* Index of current text word. */
+ int af = 0; /* Flag: Arrowhead forward. */
+ int ab = 0; /* Flag: Arrowhead backward. */
+ int ec = 1; /* Error code. */
+ int back = 1;
+
+
+#line 582 "dk3figrd.ctr"
+ pc = args;
+ for(i = 0; ((back) && (pc) && (i < 6)); i++) {
+ pn = dk3str_c8_next(pc, NULL);
+ switch(i) {
+ case 0: { /* js, join style */
+ if(1 != sscanf(pc, "%d", &(tobj->js))) {
+
+#line 588 "dk3figrd.ctr"
+ back = 0;
+ }
+ } break;
+ case 1: { /* cs, cap style */
+ if(1 != sscanf(pc, "%d", &(tobj->cs))) {
+
+#line 593 "dk3figrd.ctr"
+ back = 0;
+ }
+ } break;
+ case 2: { /* radius */
+ if(1 != sscanf(pc, "%lg", &((tobj->dt).pol.ra))) {
+
+#line 598 "dk3figrd.ctr"
+ back = 0;
+ }
+ } break;
+ case 3: { /* af, array forward */
+ if(1 != sscanf(pc, "%d", &af)) {
+
+#line 603 "dk3figrd.ctr"
+ back = 0;
+ }
+ } break;
+ case 4: { /* ab, array backward */
+ if(1 != sscanf(pc, "%d", &ab)) {
+
+#line 608 "dk3figrd.ctr"
+ back = 0;
+ }
+ } break;
+ case 5: { /* Number of points */
+#if VERSION_BEFORE_20140809
+ if(1 == sscanf(pc, "%u", &u)) {
+ (tobj->dt).pol.np = (size_t)u;
+ if(u != (unsigned)((tobj->dt).pol.np)) {
+
+#line 616 "dk3figrd.ctr"
+ back = 0;
+ }
+ } else {
+
+#line 619 "dk3figrd.ctr"
+ back = 0;
+ }
+#else
+ dk3_um_t um = DK3_UM_0;
+ int mec = 0;
+ if (dk3ma_um_from_c8_string(&um, pc, NULL)) {
+ (tobj->dt).pol.np = dk3ma_um_to_sz(um, &mec);
+ if (0 != mec) { /* Overflow */
+ back = 0;
+ }
+ } else { /* Not a number */
+ back = 0;
+ }
+#endif
+ } break;
+ }
+ pc = pn;
+ if(!(pc)) {
+ if(i < 5) {
+
+#line 638 "dk3figrd.ctr"
+ back = 0;
+ }
+ }
+ }
+ if(back) {
+ pobj = dk3fig_obj_new(
+ drw->lineno, tobj->la, tobj->ot, tobj->st, tobj->lw, tobj->pc, tobj->fc,
+ tobj->fi, tobj->cs, tobj->js, tobj->ls, tobj->sv, af, ab,
+ (tobj->dt).pol.np, NULL, drw->app
+ );
+ if(pobj) {
+ (pobj->dt).pol.ra = (tobj->dt).pol.ra;
+
+
+#line 651 "dk3figrd.ctr"
+
+
+#line 652 "dk3figrd.ctr"
+ if(dk3sto_add(drw->sobj, (void *)pobj)) {
+ drw->cobj = pobj;
+ drw->cind = 0;
+ drw->cxy = 0;
+ drw->state = DK3_FIG_RD_STATE_PL_POINTS;
+ if(5 == pobj->st) {
+ drw->state = DK3_FIG_RD_STATE_PL_IMAGE;
+ }
+ if(pobj->ab) {
+ drw->state = DK3_FIG_RD_STATE_PL_ARROW_BACKWARD;
+ }
+ if(pobj->af) {
+ drw->state = DK3_FIG_RD_STATE_PL_ARROW_FORWARD;
+ }
+ } else {
+ back = 0; ec = 2;
+
+#line 668 "dk3figrd.ctr"
+ dk3fig_obj_delete(pobj);
+ }
+ } else {
+ back = 0; ec = 2;
+
+#line 672 "dk3figrd.ctr"
+ }
+ }
+ if(!(back)) {
+ switch(ec) {
+ case 1: { dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); } break;
+ case 2: { dk3fig_set_ec(drw, DK3_ERROR_MEMORY); } break;
+ }
+ }
+ dk3figrd_report_error_code(drw, back, ec);
+
+
+#line 682 "dk3figrd.ctr"
+ return back;
+}
+
+
+
+/** Complete spline.
+ @param drw Drawing to modify.
+ @param tobj Object to complete.
+ @param args Object arguments in start line.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figrd_spline_complete(dk3_fig_drawing_t *drw,dk3_fig_obj_t *tobj,char *args)
+{
+ dk3_fig_obj_t *pobj; /* New object. */
+ char *pc; /* Current text word to process. */
+ char *pn; /* Next text to process. */
+#if VERSION_BEFORE_20140809
+ unsigned u; /* Number of points. */
+#endif
+ int i; /* Index of current text word. */
+ int af = 0; /* Flag: Arrowhead forward. */
+ int ab = 0; /* Flag: Arrowhead backward. */
+ int ec = 1; /* Error code. */
+ int back = 1;
+
+
+#line 709 "dk3figrd.ctr"
+ pc = args;
+ for(i = 0; ((back) && (pc) && (i < 4)); i++) {
+ pn = dk3str_c8_next(pc, NULL);
+ switch(i) {
+ case 0: { /* cs, cap style */
+ if(1 != sscanf(pc, "%d", &(tobj->cs))) {
+
+#line 715 "dk3figrd.ctr"
+ back = 0;
+ }
+ } break;
+ case 1: { /* af, arrowhead forward */
+ if(1 != sscanf(pc, "%d", &af)) {
+
+#line 720 "dk3figrd.ctr"
+ back = 0;
+ }
+ } break;
+ case 2: { /* ab, arrowhead backward */
+ if(1 != sscanf(pc, "%d", &ab)) {
+
+#line 725 "dk3figrd.ctr"
+ back = 0;
+ }
+ } break;
+ case 3: { /* np, number of points */
+#if VERSION_BEFORE_20140809
+ if(1 == sscanf(pc, "%u", &u)) {
+ (tobj->dt).pol.np = (size_t)u;
+ if(u != (unsigned)((tobj->dt).pol.np)) {
+
+#line 733 "dk3figrd.ctr"
+ back = 0;
+ }
+ } else {
+ back = 0;
+ }
+#else
+ dk3_um_t um = DK3_UM_0;
+ int mec = 0;
+ if (dk3ma_um_from_c8_string(&um, pc, NULL)) {
+ (tobj->dt).pol.np = dk3ma_um_to_sz(um, &mec);
+ if (0 != mec) { /* Range overflow */
+ back = 0;
+ }
+ } else { /* Not a number */
+ back = 0;
+ }
+#endif
+ } break;
+ }
+ pc = pn;
+ if(!(pc)) {
+ if(i < 3) {
+ back = 0;
+ }
+ }
+ }
+ if(back) {
+ pobj = dk3fig_obj_new(
+ drw->lineno, tobj->la, tobj->ot, tobj->st, tobj->lw, tobj->pc, tobj->fc,
+ tobj->fi, tobj->cs, 0, tobj->ls, tobj->sv, af, ab,
+ (tobj->dt).pol.np, NULL, drw->app
+ );
+ if(pobj) {
+
+
+#line 767 "dk3figrd.ctr"
+
+
+#line 768 "dk3figrd.ctr"
+ if(dk3sto_add(drw->sobj, (void *)pobj)) {
+ drw->cobj = pobj;
+ drw->cind = 0;
+ drw->cxy = 0;
+ drw->state = DK3_FIG_RD_STATE_SP_POINTS;
+ if(pobj->ab) {
+ drw->state = DK3_FIG_RD_STATE_SP_ARROW_BACKWARD;
+ }
+ if(pobj->af) {
+ drw->state = DK3_FIG_RD_STATE_SP_ARROW_FORWARD;
+ }
+ } else {
+
+#line 780 "dk3figrd.ctr"
+ back = 0; ec = 2;
+ dk3fig_obj_delete(pobj);
+ }
+ } else {
+
+#line 784 "dk3figrd.ctr"
+ back = 0; ec = 2;
+ }
+ }
+ if(!(back)) {
+ switch(ec) {
+ case 1: { dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); } break;
+ case 2: { dk3fig_set_ec(drw, DK3_ERROR_MEMORY); } break;
+ }
+ }
+ dk3figrd_report_error_code(drw, back, ec);
+
+
+#line 795 "dk3figrd.ctr"
+ return back;
+}
+
+
+
+/** Read graphics element.
+ @param drw Drawing to modify.
+ @param ot Object type.
+ @param args Object arguments in start line.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figrd_path_object(dk3_fig_drawing_t *drw, int ot, char *args)
+{
+ dk3_fig_obj_t tobj; /* Buffer object. */
+ char *pc; /* Current text word to process. */
+ char *pn; /* Next text to process. */
+ int i; /* Index of current text word. */
+ int back = 0;
+
+
+#line 816 "dk3figrd.ctr"
+ if(args) {
+ dk3fig_obj_init(&tobj);
+ tobj.ot = ot;
+ back = 1;
+ pc = args;
+ for(i = 0; ((back) && (pc) && (i < 9)); i++) {
+ pn = dk3str_c8_next(pc, NULL);
+ switch(i) {
+ case 0: { /* st: sub type */
+ if(1 != sscanf(pc, "%d", &(tobj.st))) {
+
+#line 826 "dk3figrd.ctr"
+ back = 0;
+ dk3fig_set_ec(drw, DK3_ERROR_SYNTAX);
+ /* ERROR: Syntax */
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1);
+ }
+
+#line 831 "dk3figrd.ctr"
+ } break;
+ case 1: { /* ls: line style: int */
+ if(1 != sscanf(pc, "%d", &(tobj.ls))) {
+
+#line 834 "dk3figrd.ctr"
+ back = 0;
+ dk3fig_set_ec(drw, DK3_ERROR_SYNTAX);
+ /* ERROR: Syntax */
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1);
+ }
+ } break;
+ case 2: { /* lw: line thickness: int */
+ if(1 != sscanf(pc, "%d", &(tobj.lw))) {
+
+#line 842 "dk3figrd.ctr"
+ back = 0;
+ dk3fig_set_ec(drw, DK3_ERROR_SYNTAX);
+ /* ERROR: Syntax */
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1);
+ }
+ } break;
+ case 3: { /* pc: pen color: int */
+ if(1 != sscanf(pc, "%d", &(tobj.pc))) {
+
+#line 850 "dk3figrd.ctr"
+ back = 0;
+ dk3fig_set_ec(drw, DK3_ERROR_SYNTAX);
+ /* ERROR: Syntax */
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1);
+ }
+ } break;
+ case 4: { /* fc: fill color: int */
+ if(1 != sscanf(pc, "%d", &(tobj.fc))) {
+
+#line 858 "dk3figrd.ctr"
+ back = 0;
+ dk3fig_set_ec(drw, DK3_ERROR_SYNTAX);
+ /* ERROR: Syntax */
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1);
+ }
+ } break;
+ case 5: { /* la: depth: int */
+ if(1 != sscanf(pc, "%d", &(tobj.la))) {
+
+#line 866 "dk3figrd.ctr"
+ back = 0;
+ dk3fig_set_ec(drw, DK3_ERROR_SYNTAX);
+ /* ERROR: Syntax */
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1);
+ }
+ } break;
+ case 6: { /* pen style: int, unused */
+ } break;
+ case 7: { /* fi: area fill: int */
+ if(1 != sscanf(pc, "%d", &(tobj.fi))) {
+
+#line 876 "dk3figrd.ctr"
+ back = 0;
+ dk3fig_set_ec(drw, DK3_ERROR_SYNTAX);
+ /* ERROR: Syntax */
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1);
+ }
+ } break;
+ case 8: { /* sv: style value: double */
+ if(1 != sscanf(pc, "%lg", &(tobj.sv))) {
+
+#line 884 "dk3figrd.ctr"
+ back = 0;
+ dk3fig_set_ec(drw, DK3_ERROR_SYNTAX);
+ /* ERROR: Syntax */
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1);
+ }
+ } break;
+ }
+ pc = pn;
+ if(!(pc)) {
+
+#line 893 "dk3figrd.ctr"
+ back = 0;
+ dk3fig_set_ec(drw, DK3_ERROR_SYNTAX);
+ /* ERROR: Syntax */
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1);
+ }
+ }
+ if((back) && (pc)) {
+
+
+#line 901 "dk3figrd.ctr"
+ switch(ot) {
+ case DK3_FIG_OBJ_ARC: {
+ back = dk3figrd_arc_complete(drw, &tobj, pc);
+ } break;
+ case DK3_FIG_OBJ_ELLIPSE: {
+ back = dk3figrd_ellipse_complete(drw, &tobj, pc);
+ } break;
+ case DK3_FIG_OBJ_POLYLINE: {
+ back = dk3figrd_polyline_complete(drw, &tobj, pc);
+ } break;
+ case DK3_FIG_OBJ_SPLINE: {
+ back = dk3figrd_spline_complete(drw, &tobj, pc);
+ } break;
+ }
+ } else {
+ /* ERROR: Syntax */
+ dk3fig_set_ec(drw, DK3_ERROR_SYNTAX);
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1);
+ }
+ } else {
+ /* ERROR: Missing arguments! */
+ dk3fig_set_ec(drw, DK3_ERROR_SYNTAX);
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1);
+ }
+
+#line 925 "dk3figrd.ctr"
+ return back;
+}
+
+
+
+/** Copy string from right to left while resolving escape sequences.
+ Destination and source source address point to the same buffer
+ but src must point somewhere right from dst.
+ @param dst Destination pointer.
+ @param src Source pointer.
+*/
+static
+void
+dk3figrd_string_copy_to_left(char *dst, char *src)
+{
+ char *pd; /* Current destination pointer. */
+ char *ps; /* Current source pointer. */
+ pd = dst; ps = src;
+ while(*ps) { *(pd++) = *(ps++); }
+ *pd = '\0';
+}
+
+
+
+/** Squeeze Fig string (resolve octal codes and backslash escapes).
+ @param str String to modify.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figrd_squeeze_string(char *str)
+{
+ char *ptr; /* Current character to process. */
+ int i1 = 0; /* First octal value. */
+ int i2 = 0; /* Second octal value. */
+ int i3 = 0; /* Third octal value. */
+ int back = 1;
+
+
+#line 963 "dk3figrd.ctr"
+ ptr = str;
+ while((back) && (*ptr)) {
+
+#line 965 "dk3figrd.ctr"
+ if('\\' == *ptr) {
+
+#line 966 "dk3figrd.ctr"
+ if((ptr[1] >= '0') && (ptr[1] <= '3')) {
+ if((ptr[2] >= '0') && (ptr[2] <= '7')) {
+ if((ptr[3] >= '0') && (ptr[3] <= '7')) {
+
+#line 969 "dk3figrd.ctr"
+ i1 = i2 = i3 = 0;
+ (void)dk3figrd_hex_digit(ptr[1], &i1);
+
+#line 971 "dk3figrd.ctr"
+ (void)dk3figrd_hex_digit(ptr[2], &i2);
+
+#line 972 "dk3figrd.ctr"
+ (void)dk3figrd_hex_digit(ptr[3], &i3);
+
+#line 973 "dk3figrd.ctr"
+
+
+#line 974 "dk3figrd.ctr"
+ *ptr = (char)(64 * i1 + 8 * i2 + i3);
+ dk3figrd_string_copy_to_left(&(ptr[1]), &(ptr[4]));
+ if(0x01 == *ptr) {
+ *ptr = '\0';
+ } else {
+ ptr++;
+ }
+ } else {
+
+#line 982 "dk3figrd.ctr"
+ back = 0;
+ }
+ } else {
+ back = 0;
+
+#line 986 "dk3figrd.ctr"
+ }
+ } else {
+ switch(ptr[1]) {
+ case '\0': {
+ *ptr = '\0';
+ } break;
+ case 'r': {
+ *ptr = '\r';
+ dk3figrd_string_copy_to_left(&(ptr[1]), &(ptr[2]));
+ ptr++;
+ } break;
+ case 'n': {
+ *ptr = '\n';
+ dk3figrd_string_copy_to_left(&(ptr[1]), &(ptr[2]));
+ ptr++;
+ } break;
+ case 'a': {
+ *ptr = '\a';
+ dk3figrd_string_copy_to_left(&(ptr[1]), &(ptr[2]));
+ ptr++;
+ } break;
+ default: {
+ dk3figrd_string_copy_to_left(ptr, &(ptr[1]));
+ ptr++;
+ } break;
+ }
+ }
+ } else {
+
+#line 1014 "dk3figrd.ctr"
+ ptr++;
+ }
+ }
+ if(!(back)) {
+ }
+
+#line 1019 "dk3figrd.ctr"
+ return back;
+}
+
+
+
+/** Read text element.
+ @param drw Drawing to modify.
+ @param args Object arguments in start line.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figrd_text_object(dk3_fig_drawing_t *drw, char *args)
+{
+ dk3_fig_obj_t tobj; /* Buffer object. */
+ dk3_fig_obj_t *pobj = NULL; /* New object. */
+ char *pc; /* Current text word to process. */
+ char *pn; /* Next text to process. */
+ int back = 0;
+ int ec = 1; /* 1=syntax, 2=memory */
+ int i; /* Index of current text word. */
+
+
+#line 1041 "dk3figrd.ctr"
+ if(args) {
+ dk3fig_obj_init(&tobj);
+ tobj.ot = DK3_FIG_OBJ_TEXT;
+ back = 1;
+ pc = args; pn = NULL;
+ for(i = 0; ((back) && (pc) && (i < 12)); i++) {
+ pn = dk3str_c8_next(pc, NULL);
+ switch(i) {
+ case 0: { /* sub type */
+ if(1 != sscanf(pc, "%d", &(tobj.st))) {
+
+#line 1051 "dk3figrd.ctr"
+ back = 0;
+ }
+ } break;
+ case 1: { /* color */
+ if(1 != sscanf(pc, "%d", &(tobj.pc))) {
+
+#line 1056 "dk3figrd.ctr"
+ back = 0;
+ }
+ } break;
+ case 2: { /* depth (layer) */
+ if(1 != sscanf(pc, "%d", &(tobj.la))) {
+
+#line 1061 "dk3figrd.ctr"
+ back = 0;
+ }
+ } break;
+ case 3: { /* pen style, unused */
+ } break;
+ case 4: { /* font */
+ if(1 != sscanf(pc, "%d", &(tobj.dt.txt.fo))) {
+
+#line 1068 "dk3figrd.ctr"
+ back = 0;
+ }
+ } break;
+ case 5: { /* font size */
+ if(1 == sscanf(pc, "%lg", &(tobj.dt.txt.fs))) {
+
+#line 1073 "dk3figrd.ctr"
+ if(tobj.dt.txt.fs < 0.0) {
+
+#line 1074 "dk3figrd.ctr"
+ back = 0;
+ }
+ } else {
+
+#line 1077 "dk3figrd.ctr"
+ back = 0;
+ }
+ } break;
+ case 6: { /* angle */
+ if(1 != sscanf(pc, "%lg", &(tobj.dt.txt.an))) {
+
+#line 1082 "dk3figrd.ctr"
+ back = 0;
+ }
+ } break;
+ case 7: { /* font flags */
+ if(1 != sscanf(pc, "%d", &(tobj.dt.txt.ff))) {
+
+#line 1087 "dk3figrd.ctr"
+ back = 0;
+ }
+ } break;
+ case 8: { /* height */
+ } break;
+ case 9: { /* length */
+ } break;
+ case 10: { /* x */
+ if(1 != sscanf(pc, "%lg", &(tobj.dt.txt.x))) {
+
+#line 1096 "dk3figrd.ctr"
+ back = 0;
+ }
+ } break;
+ case 11: { /* y */
+ if(1 != sscanf(pc, "%lg", &(tobj.dt.txt.y))) {
+
+#line 1101 "dk3figrd.ctr"
+ back = 0;
+ }
+ } break;
+ }
+ pc = pn;
+ if(!(pc)) {
+
+#line 1107 "dk3figrd.ctr"
+ back = 0;
+ }
+ }
+ if((pc) && (back)) {
+ if(dk3figrd_squeeze_string(pc)) {
+ pobj = dk3fig_obj_new(
+ drw->lineno, tobj.la, tobj.ot, tobj.st, 0, tobj.pc,
+ 0, 0, 0, 0, 0, 0.0, 0, 0, 0, pc, drw->app
+ );
+ if(pobj) {
+ if(dk3sto_add(drw->sobj, (void *)pobj)) {
+ (pobj->dt).txt.x = tobj.dt.txt.x;
+ (pobj->dt).txt.y = tobj.dt.txt.y;
+ (pobj->dt).txt.an = tobj.dt.txt.an;
+ (pobj->dt).txt.fs = tobj.dt.txt.fs;
+ (pobj->dt).txt.he = tobj.dt.txt.he;
+ (pobj->dt).txt.wi = tobj.dt.txt.wi;
+ (pobj->dt).txt.fo = tobj.dt.txt.fo;
+ (pobj->dt).txt.ff = tobj.dt.txt.ff;
+ } else {
+ back = 0; ec = 2;
+
+#line 1128 "dk3figrd.ctr"
+ dk3fig_obj_delete(pobj);
+ }
+ } else {
+ back = 0; ec = 2;
+
+#line 1132 "dk3figrd.ctr"
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_SYNTAX);
+ back = 0;
+
+#line 1136 "dk3figrd.ctr"
+ }
+ }
+ }
+ if(!(back)) {
+ switch(ec) {
+ case 1: { dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); } break;
+ case 2: { dk3fig_set_ec(drw, DK3_ERROR_MEMORY); } break;
+ }
+ }
+ dk3figrd_report_error_code(drw, back, ec);
+
+
+#line 1147 "dk3figrd.ctr"
+ return back;
+}
+
+
+
+
+/** Read start line of an object.
+ @param drw Drawing to modify.
+ @param lp Text line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figrd_start_object(dk3_fig_drawing_t *drw, char *lp)
+{
+ char *pn; /* Pointer to text after object type. */
+ int ot = 0; /* Object type. */
+ int back = 0;
+
+
+#line 1166 "dk3figrd.ctr"
+ pn = dk3str_c8_next(lp, NULL);
+ if(1 == sscanf(lp, "%d", &ot)) {
+ switch(ot) {
+ case DK3_FIG_OBJ_COLOR: {
+ back = dk3figrd_color_object(drw, pn);
+ } break;
+ case DK3_FIG_OBJ_ARC:
+ case DK3_FIG_OBJ_ELLIPSE:
+ case DK3_FIG_OBJ_POLYLINE:
+ case DK3_FIG_OBJ_SPLINE:
+ {
+ back = dk3figrd_path_object(drw, ot, pn);
+ } break;
+ case DK3_FIG_OBJ_TEXT: {
+ back = dk3figrd_text_object(drw, pn);
+ } break;
+ case DK3_FIG_OBJ_COMPOUND: {
+ back = 1;
+ } break;
+ case DK3_FIG_OBJ_ENDCOMPOUND: {
+ back = 1;
+ } break;
+ }
+ } else {
+ /* Syntax error, no numeric object type! */
+ dk3fig_set_ec(drw, DK3_ERROR_SYNTAX);
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1);
+ }
+
+
+#line 1195 "dk3figrd.ctr"
+ return back;
+}
+
+
+
+/** Read arrowhead line.
+ @param drw Drawing.
+ @param obj Current object.
+ @param ah Arrowhead structure to fill.
+ @param lp Text containing arrowhead information.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figrd_arrowhead(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ char *lp
+)
+{
+ char *pc; /* Current text word to process. */
+ char *pn; /* Next text to process. */
+ int i; /* Index of current text word. */
+ int back = 1;
+
+
+#line 1221 "dk3figrd.ctr"
+ pc = dk3str_c8_start(lp, NULL);
+ for(i = 0; ((back) && (pc) && (i < 5)); i++) {
+ pn = dk3str_c8_next(pc, NULL);
+ switch(i) {
+ case 0: { /* arrow type */
+ if(1 != sscanf(pc, "%d", &(ah->as))) {
+
+#line 1227 "dk3figrd.ctr"
+ back = 0;
+ }
+ } break;
+ case 1: { /* arrow style */
+ if(1 != sscanf(pc, "%d", &(ah->af))) {
+
+#line 1232 "dk3figrd.ctr"
+ back = 0;
+ }
+ } break;
+ case 2: { /* thickness (ignored, linewidth used) */
+ } break;
+ case 3: { /* width */
+ if(1 != sscanf(pc, "%lg", &(ah->wi))) {
+
+#line 1239 "dk3figrd.ctr"
+ back = 0;
+ }
+ } break;
+ case 4: { /* height */
+ if(1 != sscanf(pc, "%lg", &(ah->he))) {
+
+#line 1244 "dk3figrd.ctr"
+ back = 0;
+ }
+ } break;
+ }
+ pc = pn;
+ if(!(pc)) {
+ if(i < 4) {
+
+#line 1251 "dk3figrd.ctr"
+ back = 0;
+ }
+ }
+ }
+
+#line 1255 "dk3figrd.ctr"
+ return back;
+}
+
+
+
+/** Attach arrowhead information to arc.
+ @param drw Drawing to modify.
+ @param lp Text line containing arrowhead information.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figrd_arc_arrow(dk3_fig_drawing_t *drw, char *lp)
+{
+ int ec = 1; /* Error code. */
+ int ostate; /* Old object reader state. */
+ int back = 0;
+
+
+#line 1273 "dk3figrd.ctr"
+ ostate = drw->state;
+ if(drw->cobj) {
+ switch(ostate) {
+ case DK3_FIG_RD_STATE_ARC_ARROW_BACKWARD: {
+ if((drw->cobj)->ab) {
+ back = dk3figrd_arrowhead(drw, drw->cobj, (drw->cobj)->ab, lp);
+ } else {
+
+#line 1280 "dk3figrd.ctr"
+ }
+ } break;
+ default: {
+ if((drw->cobj)->af) {
+ back = dk3figrd_arrowhead(drw, drw->cobj, (drw->cobj)->af, lp);
+ } else {
+
+#line 1286 "dk3figrd.ctr"
+ }
+ } break;
+ }
+ drw->state = DK3_FIG_RD_STATE_READY;
+ switch(ostate) {
+ case DK3_FIG_RD_STATE_ARC_ARROW_FORWARD: {
+ if((drw->cobj)->ab) {
+ drw->state = DK3_FIG_RD_STATE_ARC_ARROW_BACKWARD;
+ }
+ } break;
+ }
+ } else {
+
+#line 1298 "dk3figrd.ctr"
+ }
+ if(!(back)) {
+ switch(ec) {
+ case 1: { dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); } break;
+ case 2: { dk3fig_set_ec(drw, DK3_ERROR_MEMORY); } break;
+ }
+ }
+ dk3figrd_report_error_code(drw, back, ec);
+
+#line 1306 "dk3figrd.ctr"
+ return back;
+}
+
+
+
+/** Attach arrowhead information to polyline.
+ @param drw Drawing to modify.
+ @param lp Text line containing arrowhead information.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figrd_polyline_arrow(dk3_fig_drawing_t *drw, char *lp)
+{
+ int ostate; /* Old object reader state. */
+ int ec = 1; /* Error code. */
+ int back = 0;
+
+
+#line 1324 "dk3figrd.ctr"
+ ostate = drw->state;
+ if(drw->cobj) {
+ switch(ostate) {
+ case DK3_FIG_RD_STATE_PL_ARROW_BACKWARD: {
+ if((drw->cobj)->ab) {
+ back = dk3figrd_arrowhead(drw, drw->cobj, (drw->cobj)->ab, lp);
+ } else {
+
+#line 1331 "dk3figrd.ctr"
+ }
+ } break;
+ default: {
+ if((drw->cobj)->af) {
+ back = dk3figrd_arrowhead(drw, drw->cobj, (drw->cobj)->af, lp);
+ } else {
+
+#line 1337 "dk3figrd.ctr"
+ }
+ } break;
+ }
+ drw->state = DK3_FIG_RD_STATE_PL_POINTS;
+ if(5 == (drw->cobj)->st) {
+ drw->state = DK3_FIG_RD_STATE_PL_IMAGE;
+ }
+ switch(ostate) {
+ case DK3_FIG_RD_STATE_PL_ARROW_FORWARD: {
+ if((drw->cobj)->ab) {
+ drw->state = DK3_FIG_RD_STATE_PL_ARROW_BACKWARD;
+ }
+ } break;
+ }
+ } else {
+
+#line 1352 "dk3figrd.ctr"
+ }
+ if(!(back)) {
+ switch(ec) {
+ case 1: { dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); } break;
+ case 2: { dk3fig_set_ec(drw, DK3_ERROR_MEMORY); } break;
+ }
+ }
+ dk3figrd_report_error_code(drw, back, ec);
+
+
+#line 1361 "dk3figrd.ctr"
+ return back;
+}
+
+
+
+/** Attach arrowhead information to spline.
+ @param drw Drawing to modify.
+ @param lp Text line containing arrowhead information.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figrd_spline_arrow(dk3_fig_drawing_t *drw, char *lp)
+{
+ int ostate; /* Old object reader state. */
+ int ec = 1; /* Error code. */
+ int back = 0;
+
+
+#line 1379 "dk3figrd.ctr"
+ ostate = drw->state;
+ if(drw->cobj) {
+ switch(ostate) {
+ case DK3_FIG_RD_STATE_SP_ARROW_BACKWARD: {
+ if((drw->cobj)->ab) {
+ back = dk3figrd_arrowhead(drw, drw->cobj, (drw->cobj)->ab, lp);
+ } else {
+
+#line 1386 "dk3figrd.ctr"
+ }
+ } break;
+ default: {
+ if((drw->cobj)->af) {
+ back = dk3figrd_arrowhead(drw, drw->cobj, (drw->cobj)->af, lp);
+ } else {
+
+#line 1392 "dk3figrd.ctr"
+ }
+ } break;
+ }
+ drw->state = DK3_FIG_RD_STATE_SP_POINTS;
+ switch(ostate) {
+ case DK3_FIG_RD_STATE_SP_ARROW_FORWARD: {
+ if((drw->cobj)->ab) {
+ drw->state = DK3_FIG_RD_STATE_SP_ARROW_BACKWARD;
+ }
+ } break;
+ }
+ } else {
+
+#line 1404 "dk3figrd.ctr"
+ }
+ if(!(back)) {
+ switch(ec) {
+ case 1: { dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); } break;
+ case 2: { dk3fig_set_ec(drw, DK3_ERROR_MEMORY); } break;
+ }
+ }
+ dk3figrd_report_error_code(drw, back, ec);
+
+
+#line 1413 "dk3figrd.ctr"
+ return back;
+}
+
+
+
+/** Read image line for a polyline object.
+ @param drw Drawing to modify.
+ @param lp Text line containing image information.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figrd_polyline_image(dk3_fig_drawing_t *drw, char *lp)
+{
+ char *p1; /* Text for flipped-flag. */
+ char *p2; /* File name. */
+ int i; /* Flag: Flipped. */
+ int ec = 1; /* Error code. */
+ int back = 0;
+
+
+#line 1433 "dk3figrd.ctr"
+ if(drw->cobj) {
+ p1 = dk3str_c8_start(lp, NULL);
+ if(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ if(p2) {
+ if(1 == sscanf(p1, "%d", &i)) {
+ ((drw->cobj)->dt).pol.flf = ((i) ? 1 : 0);
+ if(!(((drw->cobj)->dt).pol.fn)) {
+ ((drw->cobj)->dt).pol.fn = dk3str_c8_dup_app(p2, drw->app);
+ if(((drw->cobj)->dt).pol.fn) {
+ back = 1;
+ drw->state = DK3_FIG_RD_STATE_PL_POINTS;
+ } else {
+ ec = 2;
+ }
+ }
+ }
+ }
+ }
+ } else {
+
+#line 1453 "dk3figrd.ctr"
+ }
+ if(!(back)) {
+ switch(ec) {
+ case 1: { dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); } break;
+ case 2: { dk3fig_set_ec(drw, DK3_ERROR_MEMORY); } break;
+ }
+ }
+ dk3figrd_report_error_code(drw, back, ec);
+
+
+#line 1462 "dk3figrd.ctr"
+ return back;
+}
+
+
+
+/** Read point data or control data.
+ @param drw
+ @param lp
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figrd_point_data(dk3_fig_drawing_t *drw, char *lp)
+{
+ dk3_fig_poly_point_t *pp = NULL; /* Point to read. */
+ dk3_fig_spline_point_t *sp = NULL; /* Point to read. */
+ char *pc; /* Current text word. */
+ char *pn; /* Next text. */
+ double d; /* Result sscanf(). */
+ int cc = 1; /* Flag: Can continue. */
+ int ec = 1; /* Error code. */
+ int back = 1;
+
+
+#line 1485 "dk3figrd.ctr"
+ if(drw->cobj) {
+ switch((drw->cobj)->ot) {
+ case DK3_FIG_OBJ_POLYLINE: {
+ pp = ((drw->cobj)->dt).pol.po;
+ if(!(pp)) { back = 0; dk3fig_set_ec(drw, DK3_ERROR_DATA_DAMAGED); }
+ } break;
+ case DK3_FIG_OBJ_SPLINE: {
+ sp = ((drw->cobj)->dt).spl.po;
+ if(!(sp)) { back = 0; dk3fig_set_ec(drw, DK3_ERROR_DATA_DAMAGED); }
+ } break;
+ default: {
+ back = 0; dk3fig_set_ec(drw, DK3_ERROR_DATA_DAMAGED);
+
+#line 1497 "dk3figrd.ctr"
+ } break;
+ }
+ if(back) {
+ pc = dk3str_c8_start(lp, NULL);
+ while((cc) && (back) && (pc)) {
+ pn = dk3str_c8_next(pc, NULL);
+
+#line 1503 "dk3figrd.ctr"
+ if(1 == sscanf(pc, "%lg", &d)) {
+ switch((drw->cobj)->ot) {
+ case DK3_FIG_OBJ_POLYLINE: {
+ if(drw->cind < ((drw->cobj)->dt).pol.np) {
+ if(drw->cxy) {
+
+#line 1508 "dk3figrd.ctr"
+ pp[drw->cind].y = d;
+ drw->cxy = 0;
+ drw->cind += 1;
+ } else {
+
+#line 1512 "dk3figrd.ctr"
+ pp[drw->cind].x = d;
+ drw->cxy = 1;
+ }
+ }
+ if(drw->cind >= ((drw->cobj)->dt).pol.np) {
+ drw->state = DK3_FIG_RD_STATE_READY;
+ cc = 0;
+ }
+ } break;
+ case DK3_FIG_OBJ_SPLINE: {
+ if(DK3_FIG_RD_STATE_SP_CONTROL == drw->state) {
+ if(drw->cind < ((drw->cobj)->dt).spl.np) {
+ sp[drw->cind].s = d;
+
+#line 1525 "dk3figrd.ctr"
+ drw->cind += 1;
+ }
+ if(drw->cind >= ((drw->cobj)->dt).spl.np) {
+ drw->state = DK3_FIG_RD_STATE_READY;
+ cc = 0;
+ }
+ } else {
+ if(drw->cind < ((drw->cobj)->dt).spl.np) {
+ if(drw->cxy) {
+
+#line 1534 "dk3figrd.ctr"
+ sp[drw->cind].y = d;
+ drw->cxy = 0;
+ drw->cind += 1;
+ } else {
+
+#line 1538 "dk3figrd.ctr"
+ sp[drw->cind].x = d;
+ drw->cxy = 1;
+ }
+ }
+ if(drw->cind >= ((drw->cobj)->dt).spl.np) {
+ drw->state = DK3_FIG_RD_STATE_SP_CONTROL;
+ drw->cind = 0;
+ drw->cxy = 0;
+
+#line 1546 "dk3figrd.ctr"
+ }
+ }
+ } break;
+ }
+ } else {
+ cc = 0;
+ dk3fig_set_ec(drw, DK3_ERROR_SYNTAX);
+ }
+ pc = pn;
+ }
+ }
+ } else {
+
+#line 1558 "dk3figrd.ctr"
+ }
+ dk3figrd_report_error_code(drw, back, ec);
+
+
+#line 1561 "dk3figrd.ctr"
+ return back;
+}
+
+
+
+/** Process comment line.
+ @param drw Drawing to modify.
+ @param lp Text line to process.
+*/
+static
+void
+dk3figrd_process_comment(dk3_fig_drawing_t *drw, char *lp)
+{
+ char *cp[16];
+ char *lp1;
+ size_t ncp;
+
+
+#line 1578 "dk3figrd.ctr"
+ switch(drw->state) {
+ case DK3_FIG_RD_STATE_EXPECT_ORIENTATION: {
+ if(DK3_FIG_SRCTYPE_UNKNOWN == drw->srctype) {
+ lp1 = lp; lp1++;
+ lp1 = dk3str_c8_start(lp1, NULL);
+ if(lp1) {
+ ncp = dk3str_c8_explode(cp, 15, lp1, NULL);
+ if(ncp >= 3) {
+ if(dk3str_c8_casecmp(cp[0], dk3figrd_c8_kw[1]) == 0) {
+ if(dk3str_c8_casecmp(cp[1], dk3figrd_c8_kw[2]) == 0) {
+ if(dk3str_c8_casecmp(cp[2], dk3figrd_c8_kw[3]) == 0) {
+ drw->srctype = DK3_FIG_SRCTYPE_WINFIG;
+
+#line 1590 "dk3figrd.ctr"
+ }
+ }
+ }
+ }
+ }
+ }
+ } break;
+ }
+
+#line 1598 "dk3figrd.ctr"
+}
+
+
+
+/** Apply one input line to drawing, LC_NUMERIC is set correctly.
+ @param drw Drawing to modify.
+ @param lp Text to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3fig_read_my_apply_line(dk3_fig_drawing_t *drw, char *lp)
+{
+ char *p1; /* Start of line. */
+ int back = 0;
+
+
+#line 1614 "dk3figrd.ctr"
+ if((drw) && (lp)) {
+ drw->lineno += 1UL;
+ if(drw->app) { dk3app_set_source_line(drw->app, drw->lineno); }
+ p1 = dk3str_c8_start(lp, NULL);
+ if(p1) {
+ dk3str_c8_delnl(p1);
+ if(DK3_FIG_RD_STATE_START == drw->state) {
+ back = dk3figrd_expect_start(drw, p1);
+ } else {
+ if('#' != *p1) {
+ switch(drw->state) {
+ case DK3_FIG_RD_STATE_EXPECT_ORIENTATION: {
+ back = 1; drw->state = DK3_FIG_RD_STATE_EXPECT_JUSTIFICATION;
+ } break;
+ case DK3_FIG_RD_STATE_EXPECT_JUSTIFICATION: {
+ back = 1; drw->state = DK3_FIG_RD_STATE_EXPECT_UNITS;
+ } break;
+ case DK3_FIG_RD_STATE_EXPECT_UNITS: {
+ back = 1; drw->state = DK3_FIG_RD_STATE_EXPECT_PAPERSIZE;
+ } break;
+ case DK3_FIG_RD_STATE_EXPECT_PAPERSIZE: {
+ back = 1; drw->state = DK3_FIG_RD_STATE_EXPECT_MAGNIFICATION;
+ } break;
+ case DK3_FIG_RD_STATE_EXPECT_MAGNIFICATION: {
+ back = 1; drw->state = DK3_FIG_RD_STATE_EXPECT_MULTIPAGE;
+ } break;
+ case DK3_FIG_RD_STATE_EXPECT_MULTIPAGE: {
+ back = 1; drw->state = DK3_FIG_RD_STATE_EXPECT_TRANSPARENT;
+ } break;
+ case DK3_FIG_RD_STATE_EXPECT_TRANSPARENT: {
+ back = dk3figrd_expect_transparent(drw, p1);
+ } break;
+ case DK3_FIG_RD_STATE_EXPECT_RESOLUTION: {
+ back = dk3figrd_expect_resolution(drw, p1);
+ } break;
+ case DK3_FIG_RD_STATE_READY: {
+ back = dk3figrd_start_object(drw, p1);
+ } break;
+ case DK3_FIG_RD_STATE_ARC_ARROW_FORWARD: {
+ back = dk3figrd_arc_arrow(drw, p1);
+ } break;
+ case DK3_FIG_RD_STATE_ARC_ARROW_BACKWARD: {
+ back = dk3figrd_arc_arrow(drw, p1);
+ } break;
+ case DK3_FIG_RD_STATE_PL_ARROW_FORWARD: {
+ back = dk3figrd_polyline_arrow(drw, p1);
+ } break;
+ case DK3_FIG_RD_STATE_PL_ARROW_BACKWARD: {
+ back = dk3figrd_polyline_arrow(drw, p1);
+ } break;
+ case DK3_FIG_RD_STATE_PL_IMAGE: {
+ back = dk3figrd_polyline_image(drw, p1);
+ } break;
+ case DK3_FIG_RD_STATE_PL_POINTS: {
+ back = dk3figrd_point_data(drw, p1);
+ } break;
+ case DK3_FIG_RD_STATE_SP_ARROW_FORWARD: {
+ back = dk3figrd_spline_arrow(drw, p1);
+ } break;
+ case DK3_FIG_RD_STATE_SP_ARROW_BACKWARD: {
+ back = dk3figrd_spline_arrow(drw, p1);
+ } break;
+ case DK3_FIG_RD_STATE_SP_POINTS: {
+ back = dk3figrd_point_data(drw, p1);
+ } break;
+ case DK3_FIG_RD_STATE_SP_CONTROL: {
+ back = dk3figrd_point_data(drw, p1);
+ } break;
+ }
+ } else {
+ back = 1;
+
+#line 1685 "dk3figrd.ctr"
+ dk3figrd_process_comment(drw, p1);
+ }
+ }
+ } else {
+ back = 1;
+
+#line 1690 "dk3figrd.ctr"
+ }
+ if(!(back)) {
+ drw->state = DK3_FIG_RD_STATE_ERROR;
+ }
+ if(DK3_FIG_RD_STATE_ERROR == drw->state) {
+ /* ERROR: Error while reading input file! */
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 6);
+ }
+ if(DK3_FIG_RD_STATE_READY == drw->state) {
+ drw->cobj = NULL;
+ drw->cind = 0;
+ drw->cxy = 0;
+ }
+ } else {
+
+#line 1704 "dk3figrd.ctr"
+ }
+
+#line 1705 "dk3figrd.ctr"
+ return back;
+}
+
+
+
+int
+dk3fig_read_apply_line(dk3_fig_drawing_t *drw, char *lp)
+{
+ int back;
+#if DK3_HAVE_SETLOCALE && defined(LC_NUMERIC) && DK3_HAVE_LOCALE_H
+ char *oldlocale;
+#endif
+#if DK3_HAVE_SETLOCALE && defined(LC_NUMERIC) && DK3_HAVE_LOCALE_H
+
+
+#line 1719 "dk3figrd.ctr"
+ oldlocale = setlocale(LC_NUMERIC, "C");
+#endif
+ back = dk3fig_read_my_apply_line(drw, lp);
+#if DK3_HAVE_SETLOCALE && defined(LC_NUMERIC) && DK3_HAVE_LOCALE_H
+ if(oldlocale) {
+
+#line 1724 "dk3figrd.ctr"
+ setlocale(LC_NUMERIC, oldlocale);
+ }
+#endif
+ return back;
+}
+
+
+
+int
+dk3fig_read_file(dk3_fig_drawing_t *drw, FILE *fipo)
+{
+ char il[DK3_FIG_LINE_SIZE]; /* Input line buffer. */
+#if DK3_HAVE_SETLOCALE && defined(LC_NUMERIC) && DK3_HAVE_LOCALE_H
+ char *oldlocale;
+#endif
+ int cc; /* Flag: Can continue. */
+ int back = 0;
+
+
+#line 1742 "dk3figrd.ctr"
+ if((drw) && (fipo)) {
+#if DK3_HAVE_SETLOCALE && defined(LC_NUMERIC) && DK3_HAVE_LOCALE_H
+
+
+#line 1745 "dk3figrd.ctr"
+ oldlocale = setlocale(LC_NUMERIC, "C");
+#endif
+ back = 1;
+ cc = 1;
+ while((back) && (cc)) {
+ if(fgets(il, sizeof(il), fipo)) {
+ if(!dk3fig_read_my_apply_line(drw, il)) {
+
+#line 1752 "dk3figrd.ctr"
+ back = 0;
+ }
+ } else {
+
+#line 1755 "dk3figrd.ctr"
+ cc = 0;
+ }
+ }
+#if DK3_HAVE_SETLOCALE && defined(LC_NUMERIC) && DK3_HAVE_LOCALE_H
+ if(oldlocale) {
+
+#line 1760 "dk3figrd.ctr"
+ setlocale(LC_NUMERIC, oldlocale);
+ }
+#endif
+ } else {
+
+#line 1764 "dk3figrd.ctr"
+ }
+
+#line 1765 "dk3figrd.ctr"
+ return back;
+}
+
+
+
+int
+dk3fig_read_file_name(dk3_fig_drawing_t *drw, dkChar const *fn)
+{
+ dkChar const *oldsrcname = NULL; /* Saved source file name. */
+ FILE *fipo; /* Input file. */
+ unsigned long oldsrcline = 0UL; /* Saved source line number. */
+ int back = 0;
+
+
+#line 1778 "dk3figrd.ctr"
+ if((drw) && (fn)) {
+ if(drw->app) {
+ oldsrcname = dk3app_get_source_file(drw->app);
+ oldsrcline = dk3app_get_source_line(drw->app);
+ dk3app_set_source_file(drw->app, fn);
+ dk3app_set_source_line(drw->app, 0UL);
+ }
+ fipo = dk3sf_fopen_app(fn, dk3figrd_kw[0], drw->app);
+ if(fipo) {
+ back = dk3fig_read_file(drw, fipo);
+ fclose(fipo);
+ } else {
+
+#line 1790 "dk3figrd.ctr"
+ dk3fig_set_ec(drw, DK3_ERROR_SYSTEM);
+ }
+ if(drw->app) {
+ dk3app_set_source_file(drw->app, oldsrcname);
+ dk3app_set_source_line(drw->app, oldsrcline);
+ }
+ } else {
+
+#line 1797 "dk3figrd.ctr"
+ if(drw) { dk3fig_set_ec(drw, DK3_ERROR_INVALID_ARGS); }
+ }
+
+#line 1799 "dk3figrd.ctr"
+ return back;
+}
+
+
+
diff --git a/support/dktools/dk3figrd.ctr b/support/dktools/dk3figrd.ctr
new file mode 100644
index 0000000000..e79d3db200
--- /dev/null
+++ b/support/dktools/dk3figrd.ctr
@@ -0,0 +1,1803 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Apply one line from a Fig file to a drawing.
+ @param drw Drawing to modify.
+ @param lp Line to apply. Line is modified during analysis.
+ @return 1 on success, 0 on error with ec set.
+*/
+int
+dk3fig_read_apply_line(dk3_fig_drawing_t *drw, char *lp);
+
+/** Read a Fig drawing from a file specified by name.
+ @param drw Drawing to modify.
+ @param fn File name to read.
+ @return 1 on success, 0 on error with ec set.
+*/
+int
+dk3fig_read_file_name(dk3_fig_drawing_t *drw, dkChar const *fn);
+
+/** Read a Fig drawing from an open file (must be opened for reading
+ in text mode).
+ @param drw Drawing to modify
+ @param fipo Input file to process.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3fig_read_file(dk3_fig_drawing_t *drw, FILE *fipo);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk3all.h"
+#include "dk3fig.h"
+#include "dk3figrd.h"
+#include "fig2lat.h"
+
+
+
+$!trace-include
+
+
+
+/** Keywords used by the module, not localized.
+*/
+static dkChar const * const dk3figrd_kw[] = {
+$!string-table macro=dkT
+#
+# 0: File open mode.
+#
+r
+$!end
+};
+
+
+/** Keywords used by the module.
+*/
+static char const * const dk3figrd_c8_kw[] = {
+$!string-table
+#
+# 0: Locale for input reading.
+#
+C
+#
+# 1/2/3: Created by WinFIG
+#
+Created
+by
+WinFIG
+$!end
+};
+
+
+/** File type tag at start of file.
+*/
+static char const dk3figrd_file_start_tag[] = { "#FIG 3.2" };
+
+
+
+/** Error reporting function.
+ @param drw Drawing structure.
+ @param res Operation result (1=success, 0=error).
+ @param ec Error code (1=syntax, 2=memory, 3=redefinition).
+*/
+static
+void
+dk3figrd_report_error_code(dk3_fig_drawing_t *drw, int res, int ec)
+{
+ if(!(res)) {
+ switch(ec) {
+ case 1: {
+ /* ERROR: Syntax */
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1);
+ } break;
+ case 2: {
+ /* ERROR: Memory */
+ dk3app_log_i1(drw->app, DK3_LL_ERROR, 9);
+ } break;
+ case 3: {
+ /* ERROR: Color redefinition */
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 2);
+ } break;
+ }
+ }
+}
+
+
+
+/** Expect file identifier.
+ @param drw Drawing to modify.
+ @param lp Text line to process.
+ @return 1 on success (identifier found or comment line).
+*/
+static
+int
+dk3figrd_expect_start(dk3_fig_drawing_t *drw, char *lp)
+{
+ int back = 0;
+ $? "+ dk3figrd_expect_start \"%!8s\"", lp
+ if('#' == *lp) {
+ back = 1;
+ if(7 < dk3str_c8_len(lp)) {
+ if(0 == dk3str_c8_ncmp(lp, dk3figrd_file_start_tag, 8)) {
+ drw->state = DK3_FIG_RD_STATE_EXPECT_ORIENTATION;
+ } else { $? "! no Fig signature"
+ }
+ } else { $? "! line too short"
+ }
+ } else { $? "! not a comment line"
+ }
+ if(!(back)) {
+ dk3fig_set_ec(drw, DK3_ERROR_SYNTAX);
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1);
+ } $? "- dk3figrd_expect_start %d", back
+ return back;
+}
+
+
+
+/** Retrieve transparent color number.
+ @param drw Drawing to modify.
+ @param lp Text line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figrd_expect_transparent(dk3_fig_drawing_t *drw, char *lp)
+{
+ int back = 0;
+ int i;
+ if(1 == sscanf(lp, "%d", &i)) {
+ back = 1;
+ drw->state = DK3_FIG_RD_STATE_EXPECT_RESOLUTION;
+ drw->transcol = i; $? ". transparent color = %d", drw->transcol
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_SYNTAX);
+ /* ERROR: Not a number! */
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1);
+ }
+ return back;
+}
+
+
+
+/** Retrieve resolution.
+ @param drw Drawing to modify.
+ @param lp Text line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figrd_expect_resolution(dk3_fig_drawing_t *drw, char *lp)
+{
+ long lres;
+ int back = 0;
+ if(1 == sscanf(lp, "%ld", &lres)) {
+ if(0L < lres) {
+ drw->lres = lres;
+#if VERSION_BEFORE_20140716
+ drw->res = dk3ma_l_to_d(lres);
+#else
+ drw->res = (double)lres;
+#endif
+ back = 1;
+ drw->state = DK3_FIG_RD_STATE_READY;
+ }
+ }
+ if(!(back)) { dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); }
+ dk3figrd_report_error_code(drw, back, 1);
+ return back;
+}
+
+
+
+/** Get a hexadecimal digit.
+ @param c Character to process.
+ @param x Pointer to result variable.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figrd_hex_digit(char c, int *x)
+{
+ int back = 0;
+ switch(c) {
+ case '0': { *x = 0; back = 1; } break;
+ case '1': { *x = 1; back = 1; } break;
+ case '2': { *x = 2; back = 1; } break;
+ case '3': { *x = 3; back = 1; } break;
+ case '4': { *x = 4; back = 1; } break;
+ case '5': { *x = 5; back = 1; } break;
+ case '6': { *x = 6; back = 1; } break;
+ case '7': { *x = 7; back = 1; } break;
+ case '8': { *x = 8; back = 1; } break;
+ case '9': { *x = 9; back = 1; } break;
+ case 'a': { *x = 10; back = 1; } break;
+ case 'A': { *x = 10; back = 1; } break;
+ case 'b': { *x = 11; back = 1; } break;
+ case 'B': { *x = 11; back = 1; } break;
+ case 'c': { *x = 12; back = 1; } break;
+ case 'C': { *x = 12; back = 1; } break;
+ case 'd': { *x = 13; back = 1; } break;
+ case 'D': { *x = 13; back = 1; } break;
+ case 'e': { *x = 14; back = 1; } break;
+ case 'E': { *x = 14; back = 1; } break;
+ case 'f': { *x = 15; back = 1; } break;
+ case 'F': { *x = 15; back = 1; } break;
+ }
+ return back;
+}
+
+
+
+/** Read color object.
+ @param drw Drawing to modify.
+ @param args Arguments in color line.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figrd_color_object(dk3_fig_drawing_t *drw, char *args)
+{
+ dk3_fig_color_t col; /* Temporary buffer. */
+ dk3_fig_color_t *pcol; /* Object found in storage. */
+ char *pn; /* Next word to process. */
+ int x; /* Temporary variable. */
+ int back = 0;
+ int ec = 1; /* 1=syntax, 2=memory, 3=redef */
+ $? "+ dk3figrd_color_object \"%!8s\"", TR_8STR(args)
+ if(args) {
+ pn = dk3str_c8_next(args, NULL);
+ if(pn) {
+ if(1 == sscanf(args, "%d", &(col.i))) {
+ if(31 < col.i) {
+ if('#' == *(pn++)) {
+ col.r = col.g = col.b = x = 0;
+ if(dk3figrd_hex_digit(*(pn++), &x)) {
+ col.r = x;
+ if(dk3figrd_hex_digit(*(pn++), &x)) {
+ col.r = 16 * col.r + x;
+ if(dk3figrd_hex_digit(*(pn++), &x)) {
+ col.g = x;
+ if(dk3figrd_hex_digit(*(pn++), &x)) {
+ col.g = 16 * col.g + x;
+ if(dk3figrd_hex_digit(*(pn++), &x)) {
+ col.b = x;
+ if(dk3figrd_hex_digit(*(pn++), &x)) {
+ col.b = 16 * col.b + x;
+ if(dk3sto_it_find_like(drw->icol, (void *)(&col), 0)) {
+ ec = 3;
+ } else {
+ pcol = dk3_new_app(dk3_fig_color_t,1,drw->app);
+ if(pcol) {
+ /* 2013-01-15: Copy color data to new buffer!
+ */
+ dk3mem_cpy(
+ (void *)pcol, (void *)(&col),
+ sizeof(dk3_fig_color_t)
+ );
+ if(dk3sto_add(drw->scol, (void *)pcol)) {
+ back = 1;
+ } else {
+ dk3_delete(pcol);
+ ec = 2;
+ }
+ } else {
+ ec = 2;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if(!(back)) {
+ switch(ec) {
+ case 1: case 3: { dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); } break;
+ case 2: { dk3fig_set_ec(drw, DK3_ERROR_MEMORY); } break;
+ }
+ }
+ dk3figrd_report_error_code(drw, back, ec);
+ $? "- dk3figrd_color_object %d", back
+ return back;
+}
+
+
+
+/** Complete arc.
+ @param drw Drawing to modify.
+ @param tobj Object to complete.
+ @param args Object arguments in start line.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figrd_arc_complete(dk3_fig_drawing_t *drw, dk3_fig_obj_t *tobj, char *args)
+{
+ dk3_fig_obj_t *pobj; /* New object. */
+ char *pc; /* Current text word to process. */
+ char *pn; /* Next text word to process. */
+ int i; /* Index of current text word. */
+ int af = 0; /* Flag: Arrowhead forward. */
+ int ab = 0; /* Flag: Arrowhead backward. */
+ int ec = 1; /* Error code. */
+ int back = 1;
+ $? "+ dk3figrd_arc_complete \"%!8s\"", args
+ pc = args;
+ for(i = 0; ((back) && (pc) && (i < 12)); i++) {
+ pn = dk3str_c8_next(pc, NULL);
+ switch(i) {
+ case 0: { /* int cap style */
+ if(1 != sscanf(pc, "%d", &(tobj->cs))) { $? "! cap style"
+ back = 0;
+ }
+ } break;
+ case 1: { /* int direction 0=clockwise, ignored */
+ } break;
+ case 2: { /* int arrow forward */
+ if(1 != sscanf(pc, "%d", &af)) { $? "! arrow forward"
+ back = 0;
+ }
+ } break;
+ case 3: { /* int arrow backward */
+ if(1 != sscanf(pc, "%d", &ab)) { $? "! arrow backward"
+ back = 0;
+ }
+ } break;
+ case 4: { /* double cx */
+ if(1 != sscanf(pc, "%lg", &((tobj->dt).arc.xc))) { $? "! cx"
+ back = 0;
+ }
+ } break;
+ case 5: { /* double cy */
+ if(1 != sscanf(pc, "%lg", &((tobj->dt).arc.yc))) { $? "! cy"
+ back = 0;
+ }
+ } break;
+ case 6: { /* double x1 */
+ if(1 != sscanf(pc, "%lg", &((tobj->dt).arc.x1))) { $? "! x1"
+ back = 0;
+ }
+ } break;
+ case 7: { /* double y1 */
+ if(1 != sscanf(pc, "%lg", &((tobj->dt).arc.y1))) { $? "! y1"
+ back = 0;
+ }
+ } break;
+ case 8: { /* double x2 */
+ if(1 != sscanf(pc, "%lg", &((tobj->dt).arc.x2))) { $? "! x2"
+ back = 0;
+ }
+ } break;
+ case 9: { /* double y2 */
+ if(1 != sscanf(pc, "%lg", &((tobj->dt).arc.y2))) { $? "! y2"
+ back = 0;
+ }
+ } break;
+ case 10: { /* double x3 */
+ if(1 != sscanf(pc, "%lg", &((tobj->dt).arc.x3))) { $? "! x3"
+ back = 0;
+ }
+ } break;
+ case 11: { /* double y3 */
+ if(1 != sscanf(pc, "%lg", &((tobj->dt).arc.y3))) { $? "! y3"
+ back = 0;
+ }
+ } break;
+ }
+ if(!(pc)) {
+ if(i < 11) { $? "! no more text"
+ back = 0;
+ }
+ }
+ pc = pn;
+ }
+ if(back) { $? ". no errors yet"
+ pobj = dk3fig_obj_new(
+ drw->lineno, tobj->la, tobj->ot, tobj->st, tobj->lw, tobj->pc, tobj->fc,
+ tobj->fi, tobj->cs, tobj->js, tobj->ls, tobj->sv, af, ab,
+ 0, NULL, drw->app
+ );
+ if(pobj) {
+ $? ". arrowhead:arc af = %d pobj->af = %!8s", af, TR_8PTR(pobj->af)
+ $? ". arrowhead:arc ab = %d pobj->ab = %!8s", ab, TR_8PTR(pobj->ab)
+ if(dk3sto_add(drw->sobj, (void *)pobj)) {
+ dk3mem_cpy(
+ (void *)(&((pobj->dt).arc)),
+ (void *)(&((tobj->dt).arc)),
+ sizeof(dk3_fig_det_arc_t)
+ );
+ if(pobj->ab) {
+ drw->state = DK3_FIG_RD_STATE_ARC_ARROW_BACKWARD;
+ }
+ if(pobj->af) {
+ drw->state = DK3_FIG_RD_STATE_ARC_ARROW_FORWARD;
+ }
+ drw->cobj = pobj;
+ } else {
+ back = 0; ec = 2; $? "! memory"
+ dk3fig_obj_delete(pobj);
+ }
+ } else {
+ back = 0; ec = 2; $? "! memory"
+ }
+ }
+ if(!(back)) {
+ switch(ec) {
+ case 1: { dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); } break;
+ case 2: { dk3fig_set_ec(drw, DK3_ERROR_MEMORY); } break;
+ }
+ }
+ dk3figrd_report_error_code(drw, back, ec);
+ $? "- dk3figrd_arc_complete %d", back
+ return back;
+}
+
+
+
+/** Complete ellipse.
+ @param drw Drawing to modify.
+ @param tobj Object to complete.
+ @param args Object arguments in start line.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figrd_ellipse_complete(
+ dk3_fig_drawing_t *drw, dk3_fig_obj_t *tobj, char *args
+)
+{
+ dk3_fig_obj_t *pobj; /* New object. */
+ char *pc; /* Current text word to process. */
+ char *pn; /* Next text to process. */
+ int i; /* Index of current text word. */
+ int ec = 1; /* Error code. */
+ int back = 1;
+ $? "+ dk3figrd_ellipse_complete \"%!8s\"", args
+ pc = args;
+ for(i = 0; ((back) && (pc) && (i < 10)); i++) {
+ pn = dk3str_c8_next(pc, NULL);
+ switch(i) {
+ case 0: { /* direction, ignored */
+ } break;
+ case 1: { /* angle */
+ if(1 != sscanf(pc, "%lg", &((tobj->dt).ell.an))) { $? "! angle"
+ back = 0;
+ } $? ". angle=%lg", (tobj->dt).ell.an
+ } break;
+ case 2: { /* cx */
+ if(1 != sscanf(pc, "%lg", &((tobj->dt).ell.cx))) { $? "! cx"
+ back = 0;
+ }
+ } break;
+ case 3: { /* cy */
+ if(1 != sscanf(pc, "%lg", &((tobj->dt).ell.cy))) { $? "! cy"
+ back = 0;
+ }
+ } break;
+ case 4: { /* rx */
+ if(1 != sscanf(pc, "%lg", &((tobj->dt).ell.rx))) { $? "! rx"
+ back = 0;
+ }
+ } break;
+ case 5: { /* ry */
+ if(1 != sscanf(pc, "%lg", &((tobj->dt).ell.ry))) { $? "! ry"
+ back = 0;
+ }
+ } break;
+ case 6: { /* start x */
+ } break;
+ case 7: { /* start y */
+ } break;
+ case 8: { /* end x */
+ } break;
+ case 9: { /* end y */
+ } break;
+ }
+ pc = pn;
+ if(!(pc)) {
+ if(i < 9) { $? "! end of line"
+ back = 0;
+ }
+ }
+ }
+ if(back) {
+ pobj = dk3fig_obj_new(
+ drw->lineno, tobj->la, tobj->ot, tobj->st, tobj->lw, tobj->pc, tobj->fc,
+ tobj->fi, tobj->cs, tobj->js, tobj->ls, tobj->sv, 0, 0,
+ 0, NULL, drw->app
+ );
+ if(pobj) {
+ if(dk3sto_add(drw->sobj, (void *)pobj)) {
+ dk3mem_cpy(
+ (void *)(&((pobj->dt).ell)),
+ (void *)(&((tobj->dt).ell)),
+ sizeof(dk3_fig_det_ell_t)
+ );
+ } else {
+ back = 0; ec = 2;
+ dk3fig_obj_delete(pobj);
+ }
+ } else {
+ back = 0; ec = 2;
+ }
+ }
+ if(!(back)) {
+ switch(ec) {
+ case 1: { dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); } break;
+ case 2: { dk3fig_set_ec(drw, DK3_ERROR_MEMORY); } break;
+ }
+ }
+ dk3figrd_report_error_code(drw, back, ec);
+ $? "- dk3figrd_ellipse_complete %d", back
+ return back;
+}
+
+
+
+/** Complete polyline.
+ @param drw Drawing to modify.
+ @param tobj Object to complete.
+ @param args Object arguments in start line.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figrd_polyline_complete(
+ dk3_fig_drawing_t *drw, dk3_fig_obj_t *tobj, char *args
+)
+{
+ dk3_fig_obj_t *pobj; /* New object. */
+ char *pc; /* Current text word to process. */
+ char *pn; /* Next text to process. */
+#if VERSION_BEFORE_20140809
+ unsigned u; /* Number of points. */
+#endif
+ int i; /* Index of current text word. */
+ int af = 0; /* Flag: Arrowhead forward. */
+ int ab = 0; /* Flag: Arrowhead backward. */
+ int ec = 1; /* Error code. */
+ int back = 1;
+ $? "+ dk3figrd_polyline_complete \"%!8s\"", args
+ pc = args;
+ for(i = 0; ((back) && (pc) && (i < 6)); i++) {
+ pn = dk3str_c8_next(pc, NULL);
+ switch(i) {
+ case 0: { /* js, join style */
+ if(1 != sscanf(pc, "%d", &(tobj->js))) { $? "! join style"
+ back = 0;
+ }
+ } break;
+ case 1: { /* cs, cap style */
+ if(1 != sscanf(pc, "%d", &(tobj->cs))) { $? "! cap style"
+ back = 0;
+ }
+ } break;
+ case 2: { /* radius */
+ if(1 != sscanf(pc, "%lg", &((tobj->dt).pol.ra))) { $? "! radius"
+ back = 0;
+ }
+ } break;
+ case 3: { /* af, array forward */
+ if(1 != sscanf(pc, "%d", &af)) { $? "! arrow forward"
+ back = 0;
+ }
+ } break;
+ case 4: { /* ab, array backward */
+ if(1 != sscanf(pc, "%d", &ab)) { $? "! arrow backward"
+ back = 0;
+ }
+ } break;
+ case 5: { /* Number of points */
+#if VERSION_BEFORE_20140809
+ if(1 == sscanf(pc, "%u", &u)) {
+ (tobj->dt).pol.np = (size_t)u;
+ if(u != (unsigned)((tobj->dt).pol.np)) { $? "! overflow"
+ back = 0;
+ }
+ } else { $? "! number of points"
+ back = 0;
+ }
+#else
+ dk3_um_t um = DK3_UM_0;
+ int mec = 0;
+ if (dk3ma_um_from_c8_string(&um, pc, NULL)) {
+ (tobj->dt).pol.np = dk3ma_um_to_sz(um, &mec);
+ if (0 != mec) { /* Overflow */
+ back = 0;
+ }
+ } else { /* Not a number */
+ back = 0;
+ }
+#endif
+ } break;
+ }
+ pc = pn;
+ if(!(pc)) {
+ if(i < 5) { $? "! line end"
+ back = 0;
+ }
+ }
+ }
+ if(back) {
+ pobj = dk3fig_obj_new(
+ drw->lineno, tobj->la, tobj->ot, tobj->st, tobj->lw, tobj->pc, tobj->fc,
+ tobj->fi, tobj->cs, tobj->js, tobj->ls, tobj->sv, af, ab,
+ (tobj->dt).pol.np, NULL, drw->app
+ );
+ if(pobj) {
+ (pobj->dt).pol.ra = (tobj->dt).pol.ra;
+ $? ". arrowhead:poly af = %d pobj->af = %!8s", af, TR_8PTR(pobj->af)
+ $? ". arrowhead:poly ab = %d pobj->ab = %!8s", ab, TR_8PTR(pobj->ab)
+ if(dk3sto_add(drw->sobj, (void *)pobj)) {
+ drw->cobj = pobj;
+ drw->cind = 0;
+ drw->cxy = 0;
+ drw->state = DK3_FIG_RD_STATE_PL_POINTS;
+ if(5 == pobj->st) {
+ drw->state = DK3_FIG_RD_STATE_PL_IMAGE;
+ }
+ if(pobj->ab) {
+ drw->state = DK3_FIG_RD_STATE_PL_ARROW_BACKWARD;
+ }
+ if(pobj->af) {
+ drw->state = DK3_FIG_RD_STATE_PL_ARROW_FORWARD;
+ }
+ } else {
+ back = 0; ec = 2; $? "! memory"
+ dk3fig_obj_delete(pobj);
+ }
+ } else {
+ back = 0; ec = 2; $? "! memory"
+ }
+ }
+ if(!(back)) {
+ switch(ec) {
+ case 1: { dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); } break;
+ case 2: { dk3fig_set_ec(drw, DK3_ERROR_MEMORY); } break;
+ }
+ }
+ dk3figrd_report_error_code(drw, back, ec);
+ $? "- dk3figrd_polyline_complete %d", back
+ return back;
+}
+
+
+
+/** Complete spline.
+ @param drw Drawing to modify.
+ @param tobj Object to complete.
+ @param args Object arguments in start line.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figrd_spline_complete(dk3_fig_drawing_t *drw,dk3_fig_obj_t *tobj,char *args)
+{
+ dk3_fig_obj_t *pobj; /* New object. */
+ char *pc; /* Current text word to process. */
+ char *pn; /* Next text to process. */
+#if VERSION_BEFORE_20140809
+ unsigned u; /* Number of points. */
+#endif
+ int i; /* Index of current text word. */
+ int af = 0; /* Flag: Arrowhead forward. */
+ int ab = 0; /* Flag: Arrowhead backward. */
+ int ec = 1; /* Error code. */
+ int back = 1;
+ $? "+ dk3figrd_spline_complete %d %d \"%!8s\"", tobj->ot, tobj->st, args
+ pc = args;
+ for(i = 0; ((back) && (pc) && (i < 4)); i++) {
+ pn = dk3str_c8_next(pc, NULL);
+ switch(i) {
+ case 0: { /* cs, cap style */
+ if(1 != sscanf(pc, "%d", &(tobj->cs))) { $? "! cap style"
+ back = 0;
+ }
+ } break;
+ case 1: { /* af, arrowhead forward */
+ if(1 != sscanf(pc, "%d", &af)) { $? "! arrow forward"
+ back = 0;
+ }
+ } break;
+ case 2: { /* ab, arrowhead backward */
+ if(1 != sscanf(pc, "%d", &ab)) { $? "! arrow backward"
+ back = 0;
+ }
+ } break;
+ case 3: { /* np, number of points */
+#if VERSION_BEFORE_20140809
+ if(1 == sscanf(pc, "%u", &u)) {
+ (tobj->dt).pol.np = (size_t)u;
+ if(u != (unsigned)((tobj->dt).pol.np)) { $? "! range overflow"
+ back = 0;
+ }
+ } else {
+ back = 0;
+ }
+#else
+ dk3_um_t um = DK3_UM_0;
+ int mec = 0;
+ if (dk3ma_um_from_c8_string(&um, pc, NULL)) {
+ (tobj->dt).pol.np = dk3ma_um_to_sz(um, &mec);
+ if (0 != mec) { /* Range overflow */
+ back = 0;
+ }
+ } else { /* Not a number */
+ back = 0;
+ }
+#endif
+ } break;
+ }
+ pc = pn;
+ if(!(pc)) {
+ if(i < 3) {
+ back = 0;
+ }
+ }
+ }
+ if(back) {
+ pobj = dk3fig_obj_new(
+ drw->lineno, tobj->la, tobj->ot, tobj->st, tobj->lw, tobj->pc, tobj->fc,
+ tobj->fi, tobj->cs, 0, tobj->ls, tobj->sv, af, ab,
+ (tobj->dt).pol.np, NULL, drw->app
+ );
+ if(pobj) {
+ $? ". arrowhead:spline af = %d pobj->af = %!8s", af, TR_8PTR(pobj->af)
+ $? ". arrowhead:spline ab = %d pobj->ab = %!8s", ab, TR_8PTR(pobj->ab)
+ if(dk3sto_add(drw->sobj, (void *)pobj)) {
+ drw->cobj = pobj;
+ drw->cind = 0;
+ drw->cxy = 0;
+ drw->state = DK3_FIG_RD_STATE_SP_POINTS;
+ if(pobj->ab) {
+ drw->state = DK3_FIG_RD_STATE_SP_ARROW_BACKWARD;
+ }
+ if(pobj->af) {
+ drw->state = DK3_FIG_RD_STATE_SP_ARROW_FORWARD;
+ }
+ } else { $? "! memory"
+ back = 0; ec = 2;
+ dk3fig_obj_delete(pobj);
+ }
+ } else { $? "! memory"
+ back = 0; ec = 2;
+ }
+ }
+ if(!(back)) {
+ switch(ec) {
+ case 1: { dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); } break;
+ case 2: { dk3fig_set_ec(drw, DK3_ERROR_MEMORY); } break;
+ }
+ }
+ dk3figrd_report_error_code(drw, back, ec);
+ $? "- dk3figrd_spline_complete %d", back
+ return back;
+}
+
+
+
+/** Read graphics element.
+ @param drw Drawing to modify.
+ @param ot Object type.
+ @param args Object arguments in start line.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figrd_path_object(dk3_fig_drawing_t *drw, int ot, char *args)
+{
+ dk3_fig_obj_t tobj; /* Buffer object. */
+ char *pc; /* Current text word to process. */
+ char *pn; /* Next text to process. */
+ int i; /* Index of current text word. */
+ int back = 0;
+ $? "+ dk3figrd_path_object %d \"%!8s\"", ot, TR_8STR(args)
+ if(args) {
+ dk3fig_obj_init(&tobj);
+ tobj.ot = ot;
+ back = 1;
+ pc = args;
+ for(i = 0; ((back) && (pc) && (i < 9)); i++) {
+ pn = dk3str_c8_next(pc, NULL);
+ switch(i) {
+ case 0: { /* st: sub type */
+ if(1 != sscanf(pc, "%d", &(tobj.st))) { $? "! sub type"
+ back = 0;
+ dk3fig_set_ec(drw, DK3_ERROR_SYNTAX);
+ /* ERROR: Syntax */
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1);
+ } $? ". st = %d", tobj.st
+ } break;
+ case 1: { /* ls: line style: int */
+ if(1 != sscanf(pc, "%d", &(tobj.ls))) { $? "! line style"
+ back = 0;
+ dk3fig_set_ec(drw, DK3_ERROR_SYNTAX);
+ /* ERROR: Syntax */
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1);
+ }
+ } break;
+ case 2: { /* lw: line thickness: int */
+ if(1 != sscanf(pc, "%d", &(tobj.lw))) { $? "! line thickness"
+ back = 0;
+ dk3fig_set_ec(drw, DK3_ERROR_SYNTAX);
+ /* ERROR: Syntax */
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1);
+ }
+ } break;
+ case 3: { /* pc: pen color: int */
+ if(1 != sscanf(pc, "%d", &(tobj.pc))) { $? "! pen clor"
+ back = 0;
+ dk3fig_set_ec(drw, DK3_ERROR_SYNTAX);
+ /* ERROR: Syntax */
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1);
+ }
+ } break;
+ case 4: { /* fc: fill color: int */
+ if(1 != sscanf(pc, "%d", &(tobj.fc))) { $? "! fill color"
+ back = 0;
+ dk3fig_set_ec(drw, DK3_ERROR_SYNTAX);
+ /* ERROR: Syntax */
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1);
+ }
+ } break;
+ case 5: { /* la: depth: int */
+ if(1 != sscanf(pc, "%d", &(tobj.la))) { $? "! depth"
+ back = 0;
+ dk3fig_set_ec(drw, DK3_ERROR_SYNTAX);
+ /* ERROR: Syntax */
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1);
+ }
+ } break;
+ case 6: { /* pen style: int, unused */
+ } break;
+ case 7: { /* fi: area fill: int */
+ if(1 != sscanf(pc, "%d", &(tobj.fi))) { $? "! area fill"
+ back = 0;
+ dk3fig_set_ec(drw, DK3_ERROR_SYNTAX);
+ /* ERROR: Syntax */
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1);
+ }
+ } break;
+ case 8: { /* sv: style value: double */
+ if(1 != sscanf(pc, "%lg", &(tobj.sv))) { $? "! style value"
+ back = 0;
+ dk3fig_set_ec(drw, DK3_ERROR_SYNTAX);
+ /* ERROR: Syntax */
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1);
+ }
+ } break;
+ }
+ pc = pn;
+ if(!(pc)) { $? "! end of line"
+ back = 0;
+ dk3fig_set_ec(drw, DK3_ERROR_SYNTAX);
+ /* ERROR: Syntax */
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1);
+ }
+ }
+ if((back) && (pc)) {
+ $? ". first part la=%d lw=%d pc=%d fc=%d ls=%d", tobj.la, tobj.lw, tobj.pc, tobj.fc, tobj.ls
+ switch(ot) {
+ case DK3_FIG_OBJ_ARC: {
+ back = dk3figrd_arc_complete(drw, &tobj, pc);
+ } break;
+ case DK3_FIG_OBJ_ELLIPSE: {
+ back = dk3figrd_ellipse_complete(drw, &tobj, pc);
+ } break;
+ case DK3_FIG_OBJ_POLYLINE: {
+ back = dk3figrd_polyline_complete(drw, &tobj, pc);
+ } break;
+ case DK3_FIG_OBJ_SPLINE: {
+ back = dk3figrd_spline_complete(drw, &tobj, pc);
+ } break;
+ }
+ } else {
+ /* ERROR: Syntax */
+ dk3fig_set_ec(drw, DK3_ERROR_SYNTAX);
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1);
+ }
+ } else {
+ /* ERROR: Missing arguments! */
+ dk3fig_set_ec(drw, DK3_ERROR_SYNTAX);
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1);
+ } $? "- dk3figrd_path_object %d", back
+ return back;
+}
+
+
+
+/** Copy string from right to left while resolving escape sequences.
+ Destination and source source address point to the same buffer
+ but src must point somewhere right from dst.
+ @param dst Destination pointer.
+ @param src Source pointer.
+*/
+static
+void
+dk3figrd_string_copy_to_left(char *dst, char *src)
+{
+ char *pd; /* Current destination pointer. */
+ char *ps; /* Current source pointer. */
+ pd = dst; ps = src;
+ while(*ps) { *(pd++) = *(ps++); }
+ *pd = '\0';
+}
+
+
+
+/** Squeeze Fig string (resolve octal codes and backslash escapes).
+ @param str String to modify.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figrd_squeeze_string(char *str)
+{
+ char *ptr; /* Current character to process. */
+ int i1 = 0; /* First octal value. */
+ int i2 = 0; /* Second octal value. */
+ int i3 = 0; /* Third octal value. */
+ int back = 1;
+ $? "+ dk3figrd_squeeze_string \"%!8s\"", TR_8STR(str)
+ ptr = str;
+ while((back) && (*ptr)) { $? ". position \"%!8s\"", ptr
+ if('\\' == *ptr) { $? ". backslash"
+ if((ptr[1] >= '0') && (ptr[1] <= '3')) {
+ if((ptr[2] >= '0') && (ptr[2] <= '7')) {
+ if((ptr[3] >= '0') && (ptr[3] <= '7')) { $? ". octal"
+ i1 = i2 = i3 = 0;
+ (void)dk3figrd_hex_digit(ptr[1], &i1); $? ". i1 = %d", i1
+ (void)dk3figrd_hex_digit(ptr[2], &i2); $? ". i2 = %d", i2
+ (void)dk3figrd_hex_digit(ptr[3], &i3); $? ". i3 = %d", i3
+ $? ". %d", 64 * i1 + 8 * i2 + i3
+ *ptr = (char)(64 * i1 + 8 * i2 + i3);
+ dk3figrd_string_copy_to_left(&(ptr[1]), &(ptr[4]));
+ if(0x01 == *ptr) {
+ *ptr = '\0';
+ } else {
+ ptr++;
+ }
+ } else { $? "! octal 3"
+ back = 0;
+ }
+ } else {
+ back = 0; $? "! octal 2"
+ }
+ } else {
+ switch(ptr[1]) {
+ case '\0': {
+ *ptr = '\0';
+ } break;
+ case 'r': {
+ *ptr = '\r';
+ dk3figrd_string_copy_to_left(&(ptr[1]), &(ptr[2]));
+ ptr++;
+ } break;
+ case 'n': {
+ *ptr = '\n';
+ dk3figrd_string_copy_to_left(&(ptr[1]), &(ptr[2]));
+ ptr++;
+ } break;
+ case 'a': {
+ *ptr = '\a';
+ dk3figrd_string_copy_to_left(&(ptr[1]), &(ptr[2]));
+ ptr++;
+ } break;
+ default: {
+ dk3figrd_string_copy_to_left(ptr, &(ptr[1]));
+ ptr++;
+ } break;
+ }
+ }
+ } else { $? ". normal char"
+ ptr++;
+ }
+ }
+ if(!(back)) {
+ } $? "- dk3figrd_squeeze_string %d \"%!8s\"", back, TR_8STR(str)
+ return back;
+}
+
+
+
+/** Read text element.
+ @param drw Drawing to modify.
+ @param args Object arguments in start line.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figrd_text_object(dk3_fig_drawing_t *drw, char *args)
+{
+ dk3_fig_obj_t tobj; /* Buffer object. */
+ dk3_fig_obj_t *pobj = NULL; /* New object. */
+ char *pc; /* Current text word to process. */
+ char *pn; /* Next text to process. */
+ int back = 0;
+ int ec = 1; /* 1=syntax, 2=memory */
+ int i; /* Index of current text word. */
+ $? "+ dk3figrd_text_object \"%!8s\"", TR_8STR(args)
+ if(args) {
+ dk3fig_obj_init(&tobj);
+ tobj.ot = DK3_FIG_OBJ_TEXT;
+ back = 1;
+ pc = args; pn = NULL;
+ for(i = 0; ((back) && (pc) && (i < 12)); i++) {
+ pn = dk3str_c8_next(pc, NULL);
+ switch(i) {
+ case 0: { /* sub type */
+ if(1 != sscanf(pc, "%d", &(tobj.st))) { $? "! sub type"
+ back = 0;
+ }
+ } break;
+ case 1: { /* color */
+ if(1 != sscanf(pc, "%d", &(tobj.pc))) { $? "! pen color"
+ back = 0;
+ }
+ } break;
+ case 2: { /* depth (layer) */
+ if(1 != sscanf(pc, "%d", &(tobj.la))) { $? "! depth"
+ back = 0;
+ }
+ } break;
+ case 3: { /* pen style, unused */
+ } break;
+ case 4: { /* font */
+ if(1 != sscanf(pc, "%d", &(tobj.dt.txt.fo))) { $? "! font"
+ back = 0;
+ }
+ } break;
+ case 5: { /* font size */
+ if(1 == sscanf(pc, "%lg", &(tobj.dt.txt.fs))) { $? ". size"
+ if(tobj.dt.txt.fs < 0.0) { $? "! neg size"
+ back = 0;
+ }
+ } else { $? "! size"
+ back = 0;
+ }
+ } break;
+ case 6: { /* angle */
+ if(1 != sscanf(pc, "%lg", &(tobj.dt.txt.an))) { $? "! angle"
+ back = 0;
+ }
+ } break;
+ case 7: { /* font flags */
+ if(1 != sscanf(pc, "%d", &(tobj.dt.txt.ff))) { $? "! flags"
+ back = 0;
+ }
+ } break;
+ case 8: { /* height */
+ } break;
+ case 9: { /* length */
+ } break;
+ case 10: { /* x */
+ if(1 != sscanf(pc, "%lg", &(tobj.dt.txt.x))) { $? "! x"
+ back = 0;
+ }
+ } break;
+ case 11: { /* y */
+ if(1 != sscanf(pc, "%lg", &(tobj.dt.txt.y))) { $? "! y"
+ back = 0;
+ }
+ } break;
+ }
+ pc = pn;
+ if(!(pc)) { $? "! text"
+ back = 0;
+ }
+ }
+ if((pc) && (back)) {
+ if(dk3figrd_squeeze_string(pc)) {
+ pobj = dk3fig_obj_new(
+ drw->lineno, tobj.la, tobj.ot, tobj.st, 0, tobj.pc,
+ 0, 0, 0, 0, 0, 0.0, 0, 0, 0, pc, drw->app
+ );
+ if(pobj) {
+ if(dk3sto_add(drw->sobj, (void *)pobj)) {
+ (pobj->dt).txt.x = tobj.dt.txt.x;
+ (pobj->dt).txt.y = tobj.dt.txt.y;
+ (pobj->dt).txt.an = tobj.dt.txt.an;
+ (pobj->dt).txt.fs = tobj.dt.txt.fs;
+ (pobj->dt).txt.he = tobj.dt.txt.he;
+ (pobj->dt).txt.wi = tobj.dt.txt.wi;
+ (pobj->dt).txt.fo = tobj.dt.txt.fo;
+ (pobj->dt).txt.ff = tobj.dt.txt.ff;
+ } else {
+ back = 0; ec = 2; $? "! memory"
+ dk3fig_obj_delete(pobj);
+ }
+ } else {
+ back = 0; ec = 2; $? "! memory"
+ }
+ } else {
+ dk3fig_set_ec(drw, DK3_ERROR_SYNTAX);
+ back = 0; $? "! no text or previous error"
+ }
+ }
+ }
+ if(!(back)) {
+ switch(ec) {
+ case 1: { dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); } break;
+ case 2: { dk3fig_set_ec(drw, DK3_ERROR_MEMORY); } break;
+ }
+ }
+ dk3figrd_report_error_code(drw, back, ec);
+ $? "- dk3figrd_text_object %d", back
+ return back;
+}
+
+
+
+
+/** Read start line of an object.
+ @param drw Drawing to modify.
+ @param lp Text line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figrd_start_object(dk3_fig_drawing_t *drw, char *lp)
+{
+ char *pn; /* Pointer to text after object type. */
+ int ot = 0; /* Object type. */
+ int back = 0;
+ $? "+ dk3figrd_start_object \"%!8s\"", lp
+ pn = dk3str_c8_next(lp, NULL);
+ if(1 == sscanf(lp, "%d", &ot)) {
+ switch(ot) {
+ case DK3_FIG_OBJ_COLOR: {
+ back = dk3figrd_color_object(drw, pn);
+ } break;
+ case DK3_FIG_OBJ_ARC:
+ case DK3_FIG_OBJ_ELLIPSE:
+ case DK3_FIG_OBJ_POLYLINE:
+ case DK3_FIG_OBJ_SPLINE:
+ {
+ back = dk3figrd_path_object(drw, ot, pn);
+ } break;
+ case DK3_FIG_OBJ_TEXT: {
+ back = dk3figrd_text_object(drw, pn);
+ } break;
+ case DK3_FIG_OBJ_COMPOUND: {
+ back = 1;
+ } break;
+ case DK3_FIG_OBJ_ENDCOMPOUND: {
+ back = 1;
+ } break;
+ }
+ } else {
+ /* Syntax error, no numeric object type! */
+ dk3fig_set_ec(drw, DK3_ERROR_SYNTAX);
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 1);
+ }
+ $? "- dk3figrd_start_object %d", back
+ return back;
+}
+
+
+
+/** Read arrowhead line.
+ @param drw Drawing.
+ @param obj Current object.
+ @param ah Arrowhead structure to fill.
+ @param lp Text containing arrowhead information.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figrd_arrowhead(
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_ah_t *ah,
+ char *lp
+)
+{
+ char *pc; /* Current text word to process. */
+ char *pn; /* Next text to process. */
+ int i; /* Index of current text word. */
+ int back = 1;
+ $? "+ dk3figrd_arrowhead \"%!8s\"", TR_8STR(lp)
+ pc = dk3str_c8_start(lp, NULL);
+ for(i = 0; ((back) && (pc) && (i < 5)); i++) {
+ pn = dk3str_c8_next(pc, NULL);
+ switch(i) {
+ case 0: { /* arrow type */
+ if(1 != sscanf(pc, "%d", &(ah->as))) { $? "! arrow type"
+ back = 0;
+ }
+ } break;
+ case 1: { /* arrow style */
+ if(1 != sscanf(pc, "%d", &(ah->af))) { $? "! arrow fill style"
+ back = 0;
+ }
+ } break;
+ case 2: { /* thickness (ignored, linewidth used) */
+ } break;
+ case 3: { /* width */
+ if(1 != sscanf(pc, "%lg", &(ah->wi))) { $? "! arrow width"
+ back = 0;
+ }
+ } break;
+ case 4: { /* height */
+ if(1 != sscanf(pc, "%lg", &(ah->he))) { $? "! Arrow height"
+ back = 0;
+ }
+ } break;
+ }
+ pc = pn;
+ if(!(pc)) {
+ if(i < 4) { $? "! unexpected end of line"
+ back = 0;
+ }
+ }
+ } $? "- dk3figrd_arrowhead %d", back
+ return back;
+}
+
+
+
+/** Attach arrowhead information to arc.
+ @param drw Drawing to modify.
+ @param lp Text line containing arrowhead information.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figrd_arc_arrow(dk3_fig_drawing_t *drw, char *lp)
+{
+ int ec = 1; /* Error code. */
+ int ostate; /* Old object reader state. */
+ int back = 0;
+ $? "+ dk3figrd_arc_arrow \"%!8s\"", TR_8STR(lp)
+ ostate = drw->state;
+ if(drw->cobj) {
+ switch(ostate) {
+ case DK3_FIG_RD_STATE_ARC_ARROW_BACKWARD: {
+ if((drw->cobj)->ab) {
+ back = dk3figrd_arrowhead(drw, drw->cobj, (drw->cobj)->ab, lp);
+ } else { $? "! bug ab"
+ }
+ } break;
+ default: {
+ if((drw->cobj)->af) {
+ back = dk3figrd_arrowhead(drw, drw->cobj, (drw->cobj)->af, lp);
+ } else { $? "! bug af"
+ }
+ } break;
+ }
+ drw->state = DK3_FIG_RD_STATE_READY;
+ switch(ostate) {
+ case DK3_FIG_RD_STATE_ARC_ARROW_FORWARD: {
+ if((drw->cobj)->ab) {
+ drw->state = DK3_FIG_RD_STATE_ARC_ARROW_BACKWARD;
+ }
+ } break;
+ }
+ } else { $? "! bug cobj"
+ }
+ if(!(back)) {
+ switch(ec) {
+ case 1: { dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); } break;
+ case 2: { dk3fig_set_ec(drw, DK3_ERROR_MEMORY); } break;
+ }
+ }
+ dk3figrd_report_error_code(drw, back, ec); $? "- dk3figrd_arc_arrow %d", back
+ return back;
+}
+
+
+
+/** Attach arrowhead information to polyline.
+ @param drw Drawing to modify.
+ @param lp Text line containing arrowhead information.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figrd_polyline_arrow(dk3_fig_drawing_t *drw, char *lp)
+{
+ int ostate; /* Old object reader state. */
+ int ec = 1; /* Error code. */
+ int back = 0;
+ $? "+ dk3figrd_polyline_arrow \"%!8s\"", TR_8STR(lp)
+ ostate = drw->state;
+ if(drw->cobj) {
+ switch(ostate) {
+ case DK3_FIG_RD_STATE_PL_ARROW_BACKWARD: {
+ if((drw->cobj)->ab) {
+ back = dk3figrd_arrowhead(drw, drw->cobj, (drw->cobj)->ab, lp);
+ } else { $? "! bug ab"
+ }
+ } break;
+ default: {
+ if((drw->cobj)->af) {
+ back = dk3figrd_arrowhead(drw, drw->cobj, (drw->cobj)->af, lp);
+ } else { $? "! bug af"
+ }
+ } break;
+ }
+ drw->state = DK3_FIG_RD_STATE_PL_POINTS;
+ if(5 == (drw->cobj)->st) {
+ drw->state = DK3_FIG_RD_STATE_PL_IMAGE;
+ }
+ switch(ostate) {
+ case DK3_FIG_RD_STATE_PL_ARROW_FORWARD: {
+ if((drw->cobj)->ab) {
+ drw->state = DK3_FIG_RD_STATE_PL_ARROW_BACKWARD;
+ }
+ } break;
+ }
+ } else { $? "! bug cobj"
+ }
+ if(!(back)) {
+ switch(ec) {
+ case 1: { dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); } break;
+ case 2: { dk3fig_set_ec(drw, DK3_ERROR_MEMORY); } break;
+ }
+ }
+ dk3figrd_report_error_code(drw, back, ec);
+ $? "- dk3figrd_polyline_arrow %d", back
+ return back;
+}
+
+
+
+/** Attach arrowhead information to spline.
+ @param drw Drawing to modify.
+ @param lp Text line containing arrowhead information.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figrd_spline_arrow(dk3_fig_drawing_t *drw, char *lp)
+{
+ int ostate; /* Old object reader state. */
+ int ec = 1; /* Error code. */
+ int back = 0;
+ $? "+ dk3figrd_spline_arrow \"%!8s\"", TR_8STR(lp)
+ ostate = drw->state;
+ if(drw->cobj) {
+ switch(ostate) {
+ case DK3_FIG_RD_STATE_SP_ARROW_BACKWARD: {
+ if((drw->cobj)->ab) {
+ back = dk3figrd_arrowhead(drw, drw->cobj, (drw->cobj)->ab, lp);
+ } else { $? "! bug ab"
+ }
+ } break;
+ default: {
+ if((drw->cobj)->af) {
+ back = dk3figrd_arrowhead(drw, drw->cobj, (drw->cobj)->af, lp);
+ } else { $? "! bug af"
+ }
+ } break;
+ }
+ drw->state = DK3_FIG_RD_STATE_SP_POINTS;
+ switch(ostate) {
+ case DK3_FIG_RD_STATE_SP_ARROW_FORWARD: {
+ if((drw->cobj)->ab) {
+ drw->state = DK3_FIG_RD_STATE_SP_ARROW_BACKWARD;
+ }
+ } break;
+ }
+ } else { $? "! bug cobj"
+ }
+ if(!(back)) {
+ switch(ec) {
+ case 1: { dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); } break;
+ case 2: { dk3fig_set_ec(drw, DK3_ERROR_MEMORY); } break;
+ }
+ }
+ dk3figrd_report_error_code(drw, back, ec);
+ $? "- dk3figrd_spline_arrow %d", back
+ return back;
+}
+
+
+
+/** Read image line for a polyline object.
+ @param drw Drawing to modify.
+ @param lp Text line containing image information.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figrd_polyline_image(dk3_fig_drawing_t *drw, char *lp)
+{
+ char *p1; /* Text for flipped-flag. */
+ char *p2; /* File name. */
+ int i; /* Flag: Flipped. */
+ int ec = 1; /* Error code. */
+ int back = 0;
+ $? "+ dk3figrd_polyline_image \"%!8s\"", TR_8STR(lp)
+ if(drw->cobj) {
+ p1 = dk3str_c8_start(lp, NULL);
+ if(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ if(p2) {
+ if(1 == sscanf(p1, "%d", &i)) {
+ ((drw->cobj)->dt).pol.flf = ((i) ? 1 : 0);
+ if(!(((drw->cobj)->dt).pol.fn)) {
+ ((drw->cobj)->dt).pol.fn = dk3str_c8_dup_app(p2, drw->app);
+ if(((drw->cobj)->dt).pol.fn) {
+ back = 1;
+ drw->state = DK3_FIG_RD_STATE_PL_POINTS;
+ } else {
+ ec = 2;
+ }
+ }
+ }
+ }
+ }
+ } else { $? "! bug cobj"
+ }
+ if(!(back)) {
+ switch(ec) {
+ case 1: { dk3fig_set_ec(drw, DK3_ERROR_SYNTAX); } break;
+ case 2: { dk3fig_set_ec(drw, DK3_ERROR_MEMORY); } break;
+ }
+ }
+ dk3figrd_report_error_code(drw, back, ec);
+ $? "- dk3figrd_polyline_image %d", back
+ return back;
+}
+
+
+
+/** Read point data or control data.
+ @param drw
+ @param lp
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3figrd_point_data(dk3_fig_drawing_t *drw, char *lp)
+{
+ dk3_fig_poly_point_t *pp = NULL; /* Point to read. */
+ dk3_fig_spline_point_t *sp = NULL; /* Point to read. */
+ char *pc; /* Current text word. */
+ char *pn; /* Next text. */
+ double d; /* Result sscanf(). */
+ int cc = 1; /* Flag: Can continue. */
+ int ec = 1; /* Error code. */
+ int back = 1;
+ $? "+ dk3figrd_point_data \"%!8s\"", TR_8STR(lp)
+ if(drw->cobj) {
+ switch((drw->cobj)->ot) {
+ case DK3_FIG_OBJ_POLYLINE: {
+ pp = ((drw->cobj)->dt).pol.po;
+ if(!(pp)) { back = 0; dk3fig_set_ec(drw, DK3_ERROR_DATA_DAMAGED); }
+ } break;
+ case DK3_FIG_OBJ_SPLINE: {
+ sp = ((drw->cobj)->dt).spl.po;
+ if(!(sp)) { back = 0; dk3fig_set_ec(drw, DK3_ERROR_DATA_DAMAGED); }
+ } break;
+ default: {
+ back = 0; dk3fig_set_ec(drw, DK3_ERROR_DATA_DAMAGED); $? "! wrong object type bug"
+ } break;
+ }
+ if(back) {
+ pc = dk3str_c8_start(lp, NULL);
+ while((cc) && (back) && (pc)) {
+ pn = dk3str_c8_next(pc, NULL); $? ". pc = \"%!8s\"", pc
+ if(1 == sscanf(pc, "%lg", &d)) {
+ switch((drw->cobj)->ot) {
+ case DK3_FIG_OBJ_POLYLINE: {
+ if(drw->cind < ((drw->cobj)->dt).pol.np) {
+ if(drw->cxy) { $? ". polyline y %lu",(unsigned long)(drw->cind)
+ pp[drw->cind].y = d;
+ drw->cxy = 0;
+ drw->cind += 1;
+ } else { $? ". polyline x %lu",(unsigned long)(drw->cind)
+ pp[drw->cind].x = d;
+ drw->cxy = 1;
+ }
+ }
+ if(drw->cind >= ((drw->cobj)->dt).pol.np) {
+ drw->state = DK3_FIG_RD_STATE_READY;
+ cc = 0;
+ }
+ } break;
+ case DK3_FIG_OBJ_SPLINE: {
+ if(DK3_FIG_RD_STATE_SP_CONTROL == drw->state) {
+ if(drw->cind < ((drw->cobj)->dt).spl.np) {
+ sp[drw->cind].s = d; $? ". spl s %lu", (unsigned long)(drw->cind)
+ drw->cind += 1;
+ }
+ if(drw->cind >= ((drw->cobj)->dt).spl.np) {
+ drw->state = DK3_FIG_RD_STATE_READY;
+ cc = 0;
+ }
+ } else {
+ if(drw->cind < ((drw->cobj)->dt).spl.np) {
+ if(drw->cxy) { $? ". spl y %lu", (unsigned long)(drw->cind)
+ sp[drw->cind].y = d;
+ drw->cxy = 0;
+ drw->cind += 1;
+ } else { $? ". spl x %lu", (unsigned long)(drw->cind)
+ sp[drw->cind].x = d;
+ drw->cxy = 1;
+ }
+ }
+ if(drw->cind >= ((drw->cobj)->dt).spl.np) {
+ drw->state = DK3_FIG_RD_STATE_SP_CONTROL;
+ drw->cind = 0;
+ drw->cxy = 0; $? ". switching to spline control"
+ }
+ }
+ } break;
+ }
+ } else {
+ cc = 0;
+ dk3fig_set_ec(drw, DK3_ERROR_SYNTAX);
+ }
+ pc = pn;
+ }
+ }
+ } else { $? "! cobj bug"
+ }
+ dk3figrd_report_error_code(drw, back, ec);
+ $? "- dk3figrd_point_data %d", back
+ return back;
+}
+
+
+
+/** Process comment line.
+ @param drw Drawing to modify.
+ @param lp Text line to process.
+*/
+static
+void
+dk3figrd_process_comment(dk3_fig_drawing_t *drw, char *lp)
+{
+ char *cp[16];
+ char *lp1;
+ size_t ncp;
+ $? "+ dk3figrd_process_comment \"%!8s\"", TR_8STR(lp)
+ switch(drw->state) {
+ case DK3_FIG_RD_STATE_EXPECT_ORIENTATION: {
+ if(DK3_FIG_SRCTYPE_UNKNOWN == drw->srctype) {
+ lp1 = lp; lp1++;
+ lp1 = dk3str_c8_start(lp1, NULL);
+ if(lp1) {
+ ncp = dk3str_c8_explode(cp, 15, lp1, NULL);
+ if(ncp >= 3) {
+ if(dk3str_c8_casecmp(cp[0], dk3figrd_c8_kw[1]) == 0) {
+ if(dk3str_c8_casecmp(cp[1], dk3figrd_c8_kw[2]) == 0) {
+ if(dk3str_c8_casecmp(cp[2], dk3figrd_c8_kw[3]) == 0) {
+ drw->srctype = DK3_FIG_SRCTYPE_WINFIG; $? ". WinFIG"
+ }
+ }
+ }
+ }
+ }
+ }
+ } break;
+ } $? "- dk3figrd_process_comment"
+}
+
+
+
+/** Apply one input line to drawing, LC_NUMERIC is set correctly.
+ @param drw Drawing to modify.
+ @param lp Text to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3fig_read_my_apply_line(dk3_fig_drawing_t *drw, char *lp)
+{
+ char *p1; /* Start of line. */
+ int back = 0;
+ $? "+ dk3fig_read_my_apply_line %lu \"%!8s\"",(1UL + drw->lineno),TR_8STR(lp)
+ if((drw) && (lp)) {
+ drw->lineno += 1UL;
+ if(drw->app) { dk3app_set_source_line(drw->app, drw->lineno); }
+ p1 = dk3str_c8_start(lp, NULL);
+ if(p1) {
+ dk3str_c8_delnl(p1);
+ if(DK3_FIG_RD_STATE_START == drw->state) {
+ back = dk3figrd_expect_start(drw, p1);
+ } else {
+ if('#' != *p1) {
+ switch(drw->state) {
+ case DK3_FIG_RD_STATE_EXPECT_ORIENTATION: {
+ back = 1; drw->state = DK3_FIG_RD_STATE_EXPECT_JUSTIFICATION;
+ } break;
+ case DK3_FIG_RD_STATE_EXPECT_JUSTIFICATION: {
+ back = 1; drw->state = DK3_FIG_RD_STATE_EXPECT_UNITS;
+ } break;
+ case DK3_FIG_RD_STATE_EXPECT_UNITS: {
+ back = 1; drw->state = DK3_FIG_RD_STATE_EXPECT_PAPERSIZE;
+ } break;
+ case DK3_FIG_RD_STATE_EXPECT_PAPERSIZE: {
+ back = 1; drw->state = DK3_FIG_RD_STATE_EXPECT_MAGNIFICATION;
+ } break;
+ case DK3_FIG_RD_STATE_EXPECT_MAGNIFICATION: {
+ back = 1; drw->state = DK3_FIG_RD_STATE_EXPECT_MULTIPAGE;
+ } break;
+ case DK3_FIG_RD_STATE_EXPECT_MULTIPAGE: {
+ back = 1; drw->state = DK3_FIG_RD_STATE_EXPECT_TRANSPARENT;
+ } break;
+ case DK3_FIG_RD_STATE_EXPECT_TRANSPARENT: {
+ back = dk3figrd_expect_transparent(drw, p1);
+ } break;
+ case DK3_FIG_RD_STATE_EXPECT_RESOLUTION: {
+ back = dk3figrd_expect_resolution(drw, p1);
+ } break;
+ case DK3_FIG_RD_STATE_READY: {
+ back = dk3figrd_start_object(drw, p1);
+ } break;
+ case DK3_FIG_RD_STATE_ARC_ARROW_FORWARD: {
+ back = dk3figrd_arc_arrow(drw, p1);
+ } break;
+ case DK3_FIG_RD_STATE_ARC_ARROW_BACKWARD: {
+ back = dk3figrd_arc_arrow(drw, p1);
+ } break;
+ case DK3_FIG_RD_STATE_PL_ARROW_FORWARD: {
+ back = dk3figrd_polyline_arrow(drw, p1);
+ } break;
+ case DK3_FIG_RD_STATE_PL_ARROW_BACKWARD: {
+ back = dk3figrd_polyline_arrow(drw, p1);
+ } break;
+ case DK3_FIG_RD_STATE_PL_IMAGE: {
+ back = dk3figrd_polyline_image(drw, p1);
+ } break;
+ case DK3_FIG_RD_STATE_PL_POINTS: {
+ back = dk3figrd_point_data(drw, p1);
+ } break;
+ case DK3_FIG_RD_STATE_SP_ARROW_FORWARD: {
+ back = dk3figrd_spline_arrow(drw, p1);
+ } break;
+ case DK3_FIG_RD_STATE_SP_ARROW_BACKWARD: {
+ back = dk3figrd_spline_arrow(drw, p1);
+ } break;
+ case DK3_FIG_RD_STATE_SP_POINTS: {
+ back = dk3figrd_point_data(drw, p1);
+ } break;
+ case DK3_FIG_RD_STATE_SP_CONTROL: {
+ back = dk3figrd_point_data(drw, p1);
+ } break;
+ }
+ } else {
+ back = 1; $? ". comment line"
+ dk3figrd_process_comment(drw, p1);
+ }
+ }
+ } else {
+ back = 1; $? ". empty line"
+ }
+ if(!(back)) {
+ drw->state = DK3_FIG_RD_STATE_ERROR;
+ }
+ if(DK3_FIG_RD_STATE_ERROR == drw->state) {
+ /* ERROR: Error while reading input file! */
+ dk3app_log_1(drw->app, DK3_LL_ERROR, drw->msg, 6);
+ }
+ if(DK3_FIG_RD_STATE_READY == drw->state) {
+ drw->cobj = NULL;
+ drw->cind = 0;
+ drw->cxy = 0;
+ }
+ } else { $? "! args"
+ } $? "- dk3fig_read_my_apply_line %d", back
+ return back;
+}
+
+
+
+int
+dk3fig_read_apply_line(dk3_fig_drawing_t *drw, char *lp)
+{
+ int back;
+#if DK3_HAVE_SETLOCALE && defined(LC_NUMERIC) && DK3_HAVE_LOCALE_H
+ char *oldlocale;
+#endif
+#if DK3_HAVE_SETLOCALE && defined(LC_NUMERIC) && DK3_HAVE_LOCALE_H
+ $? ". set locale to C"
+ oldlocale = setlocale(LC_NUMERIC, "C");
+#endif
+ back = dk3fig_read_my_apply_line(drw, lp);
+#if DK3_HAVE_SETLOCALE && defined(LC_NUMERIC) && DK3_HAVE_LOCALE_H
+ if(oldlocale) { $? ". restore old locale"
+ setlocale(LC_NUMERIC, oldlocale);
+ }
+#endif
+ return back;
+}
+
+
+
+int
+dk3fig_read_file(dk3_fig_drawing_t *drw, FILE *fipo)
+{
+ char il[DK3_FIG_LINE_SIZE]; /* Input line buffer. */
+#if DK3_HAVE_SETLOCALE && defined(LC_NUMERIC) && DK3_HAVE_LOCALE_H
+ char *oldlocale;
+#endif
+ int cc; /* Flag: Can continue. */
+ int back = 0;
+ $? "+ dk3fig_read_file"
+ if((drw) && (fipo)) {
+#if DK3_HAVE_SETLOCALE && defined(LC_NUMERIC) && DK3_HAVE_LOCALE_H
+ $? ". change locale to C"
+ oldlocale = setlocale(LC_NUMERIC, "C");
+#endif
+ back = 1;
+ cc = 1;
+ while((back) && (cc)) {
+ if(fgets(il, sizeof(il), fipo)) {
+ if(!dk3fig_read_my_apply_line(drw, il)) { $? "! error in line"
+ back = 0;
+ }
+ } else { $? ". end of file"
+ cc = 0;
+ }
+ }
+#if DK3_HAVE_SETLOCALE && defined(LC_NUMERIC) && DK3_HAVE_LOCALE_H
+ if(oldlocale) { $? ". restore old locale"
+ setlocale(LC_NUMERIC, oldlocale);
+ }
+#endif
+ } else { $? "! args"
+ } $? "- dk3fig_read_file %d", back
+ return back;
+}
+
+
+
+int
+dk3fig_read_file_name(dk3_fig_drawing_t *drw, dkChar const *fn)
+{
+ dkChar const *oldsrcname = NULL; /* Saved source file name. */
+ FILE *fipo; /* Input file. */
+ unsigned long oldsrcline = 0UL; /* Saved source line number. */
+ int back = 0;
+ $? "+ dk3fig_read_file_name \"%!ds\"", TR_STR(fn)
+ if((drw) && (fn)) {
+ if(drw->app) {
+ oldsrcname = dk3app_get_source_file(drw->app);
+ oldsrcline = dk3app_get_source_line(drw->app);
+ dk3app_set_source_file(drw->app, fn);
+ dk3app_set_source_line(drw->app, 0UL);
+ }
+ fipo = dk3sf_fopen_app(fn, dk3figrd_kw[0], drw->app);
+ if(fipo) {
+ back = dk3fig_read_file(drw, fipo);
+ fclose(fipo);
+ } else { $? "! fopen"
+ dk3fig_set_ec(drw, DK3_ERROR_SYSTEM);
+ }
+ if(drw->app) {
+ dk3app_set_source_file(drw->app, oldsrcname);
+ dk3app_set_source_line(drw->app, oldsrcline);
+ }
+ } else { $? "! args"
+ if(drw) { dk3fig_set_ec(drw, DK3_ERROR_INVALID_ARGS); }
+ } $? "- dk3fig_read_file_name %d", back
+ return back;
+}
+
+
+
diff --git a/support/dktools/dk3figrd.h b/support/dktools/dk3figrd.h
new file mode 100644
index 0000000000..722fefe32e
--- /dev/null
+++ b/support/dktools/dk3figrd.h
@@ -0,0 +1,80 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3figrd.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3figrd.h Header file for the dk3figrd module.
+*/
+
+#ifndef DK3FIGRD_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3FIGRD_H_INCLUDED 1
+
+
+#line 10 "dk3figrd.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Apply one line from a Fig file to a drawing.
+ @param drw Drawing to modify.
+ @param lp Line to apply. Line is modified during analysis.
+ @return 1 on success, 0 on error with ec set.
+*/
+int
+dk3fig_read_apply_line(dk3_fig_drawing_t *drw, char *lp);
+
+/** Read a Fig drawing from a file specified by name.
+ @param drw Drawing to modify.
+ @param fn File name to read.
+ @return 1 on success, 0 on error with ec set.
+*/
+int
+dk3fig_read_file_name(dk3_fig_drawing_t *drw, dkChar const *fn);
+
+/** Read a Fig drawing from an open file (must be opened for reading
+ in text mode).
+ @param drw Drawing to modify
+ @param fipo Input file to process.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3fig_read_file(dk3_fig_drawing_t *drw, FILE *fipo);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk3figto.c b/support/dktools/dk3figto.c
new file mode 100644
index 0000000000..2dd8ed4158
--- /dev/null
+++ b/support/dktools/dk3figto.c
@@ -0,0 +1,1007 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3figto.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3figto.c The dk3figto module.
+*/
+
+
+#line 284 "dk3figto.ctr"
+
+
+#include "dk3all.h"
+#include "dk3fig.h"
+#include "dk3figto.h"
+#include "fig2lat.h"
+
+
+
+
+
+#line 294 "dk3figto.ctr"
+
+
+
+/** Color palette for colors 0...31 as calculated from the floating point
+ numbers.
+*/
+static dk3_fig_color_t dk3fig_tool_low_rgb[] = {
+ /* 0: black */ { 0, 0, 0, 0 },
+ /* 1: blue */ { 1, 0, 0, 255 },
+ /* 2: green */ { 2, 0, 255, 0 },
+ /* 3: cyan */ { 3, 0, 255, 255 },
+ /* 4: red */ { 4, 255, 0, 0 },
+ /* 5: magenta */ { 5, 255, 0, 255 },
+ /* 6: yellow */ { 6, 255, 255, 0 },
+ /* 7: white */ { 7, 255, 255, 255 },
+ /* 8: dark blue */ { 8, 0, 0, 143 },
+ /* 9: blue */ { 9, 0, 0, 176 },
+ /* 10: blue */ { 10, 0, 0, 209 },
+ /* 11: blue */ { 11, 135, 207, 255 },
+ /* 12: dark green */ { 12, 0, 143, 0 },
+ /* 13: green */ { 13, 0, 176, 0 },
+ /* 14: green */ { 14, 0, 209, 0 },
+ /* 15: dark cyan */ { 15, 0, 143, 143 },
+ /* 16: cyan */ { 16, 0, 176, 176 },
+ /* 17: cyan */ { 17, 0, 209, 209 },
+ /* 18: dark red */ { 18, 143, 0, 0 },
+ /* 19: red */ { 19, 176, 0, 0 },
+ /* 20: red */ { 20, 209, 0, 0 },
+ /* 21: dark magenta */ { 21, 143, 0, 143 },
+ /* 22: magenta */ { 22, 176, 0, 176 },
+ /* 23: magenta */ { 23, 209, 0, 209 },
+ /* 24: dark brown */ { 24, 127, 48, 0 },
+ /* 25: brown */ { 25, 160, 63, 0 },
+ /* 26: brown */ { 26, 191, 97, 0 },
+ /* 27: dark pink */ { 27, 255, 127, 127 },
+ /* 28: pink */ { 28, 255, 160, 160 },
+ /* 29: pink */ { 29, 255, 191, 191 },
+ /* 30: pink */ { 30, 255, 224, 224 },
+ /* 31: gold */ { 31, 255, 214, 0 }
+};
+
+
+
+int
+dk3fig_tool_is_bgrect(dk3_fig_obj_t const *obj, unsigned long objno)
+{
+ int back = 0;
+ if(obj) {
+ if(0UL == objno) {
+ if(DK3_FIG_OBJ_POLYLINE == obj->ot) {
+ if(2 == obj->st) {
+ if(999 == obj->la) {
+ if(0 == obj->lw) {
+ if(-1 == obj->fi) {
+ if((-1 == obj->pc) || (7 == obj->pc)) {
+ back = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+double
+dk3fig_tool_get_lw(
+ dk3_fig_drawing_t const *drw,
+ dk3_fig_obj_t const *obj,
+ int *ec
+)
+{
+ int mec = 0; /* Mathematical error code. */
+#if VERSION_BEFORE_20140330
+ double lw; /* Line width. */
+#endif
+ double back = 0.0;
+
+
+#line 376 "dk3figto.ctr"
+#if VERSION_BEFORE_20140330
+ if((drw) && (obj)) {
+ lw = (double)(obj->lw);
+
+#line 379 "dk3figto.ctr"
+ back = dk3ma_d_mul_ok(lw, drw->res, &mec) / 80.0;
+
+#line 380 "dk3figto.ctr"
+ if(drw->lighten) { back = back / 2.0; }
+
+#line 381 "dk3figto.ctr"
+ if(mec) {
+ back = 0.0;
+ if(ec) { *ec = mec; }
+ }
+ }
+#else
+ if ((drw) && (obj)) {
+ /* back = obj->lw * drw->lwbp * drw->res / 72 */
+ back = dk3ma_d_mul_ok(
+ dk3ma_d_mul_ok(obj->lw, drw->lwbp, &mec),
+ drw->res,
+ &mec
+ ) / 72.0;
+ if (mec) {
+ back = 0.0;
+ if (ec) { *ec = mec; }
+ }
+ }
+#endif
+
+
+#line 401 "dk3figto.ctr"
+ return back;
+}
+
+
+
+double
+dk3fig_tool_get_lw_in_bp(
+ dk3_fig_drawing_t const *drw,
+ dk3_fig_obj_t const *obj,
+ int *ec
+)
+{
+ double back = 0.0;
+ int mec = 0;
+ if ((drw) && (obj)) {
+ back = dk3ma_d_mul_ok(obj->lw, drw->lwbp, &mec);
+ if (mec) {
+ back = 0.0;
+ if (ec) { *ec = mec; }
+ }
+ }
+ return back;
+}
+
+
+double
+dk3fig_tool_arc_kappa(double alpha, int *ec)
+{
+ double back;
+ double emcosa; /* 1 - cos(alpha). */
+ int mec = 0; /* Mathematical error code. */
+
+
+#line 433 "dk3figto.ctr"
+ emcosa = 1.0 - cos(alpha);
+ back = dk3ma_d_div_ok(
+ ((2.0 * sqrt(8.0 * emcosa)) - (4.0 * sin(alpha))),
+ dk3ma_d_mul_ok(alpha, (3.0 * emcosa), &mec),
+ &mec
+ );
+ if(mec) {
+ back = -1.0;
+ if(ec) { *ec = mec; }
+ }
+
+#line 443 "dk3figto.ctr"
+ return back;
+}
+
+
+
+size_t
+dk3fig_tool_xssbs(dk3_fig_drawing_t *drw, int primobj)
+{
+ size_t back = 8;
+
+
+#line 453 "dk3figto.ctr"
+ if(drw) { back = drw->xssbs; }
+ if(!(primobj)) { back = back / 2; }
+ if(back < 2) { back = 2; }
+
+
+#line 457 "dk3figto.ctr"
+ return back;
+}
+
+
+
+double
+dk3fig_tool_point_distance(
+ dk3_fig_poly_point_t const *p1,
+ dk3_fig_poly_point_t const *p2,
+ int *ec
+)
+{
+ double back = 0.0;
+
+
+#line 471 "dk3figto.ctr"
+ if((p1) && (p2)) {
+ back = sqrt(
+ dk3ma_d_add_ok(
+ dk3ma_d_square_ok(
+ dk3ma_d_sub_ok(p2->x, p1->x, ec),
+ ec
+ ),
+ dk3ma_d_square_ok(
+ dk3ma_d_sub_ok(p2->y, p1->y, ec),
+ ec
+ ),
+ ec
+ )
+ );
+ }
+
+#line 486 "dk3figto.ctr"
+ return back;
+}
+
+
+
+void
+dk3fig_tool_poly_point_move_left(
+ dk3_fig_poly_point_t *dst,
+ dk3_fig_poly_point_t *src,
+ size_t np
+)
+{
+ dk3_fig_poly_point_t *dptr; /* Destination buffer pointer. */
+ dk3_fig_poly_point_t *sptr; /* Source buffer pointer. */
+ size_t i; /* Index to traverse all elements. */
+
+
+#line 502 "dk3figto.ctr"
+ if((dst) && (src) && (np)) {
+ dptr = dst; sptr = src; i = np;
+ while(i--) { *(dptr++) = *(sptr++); }
+ }
+
+#line 506 "dk3figto.ctr"
+}
+
+
+
+int
+dk3fig_tool_cut_segment(
+ dk3_fig_poly_point_t *endpoint,
+ dk3_fig_poly_point_t const *innerpoint,
+ double distance,
+ int *ec
+)
+{
+ double delta; /* Segment length. */
+ double q; /* Cut factor. */
+ double newx; /* New x of end point. */
+ double newy; /* New y of end point. */
+ int back = 0;
+ int mec = 0; /* Mathematical error code. */
+
+
+#line 525 "dk3figto.ctr"
+ if((endpoint) && (innerpoint)) {
+
+#line 526 "dk3figto.ctr"
+
+
+#line 527 "dk3figto.ctr"
+ if(0.0 < distance) {
+
+#line 528 "dk3figto.ctr"
+ delta = sqrt(
+ dk3ma_d_add_ok(
+ dk3ma_d_square_ok(
+ dk3ma_d_sub_ok(innerpoint->x, endpoint->x, &mec),
+ &mec
+ ),
+ dk3ma_d_square_ok(
+ dk3ma_d_sub_ok(innerpoint->y, endpoint->y, &mec),
+ &mec
+ ),
+ &mec
+ )
+ );
+
+#line 541 "dk3figto.ctr"
+ if(delta > distance) {
+
+#line 542 "dk3figto.ctr"
+ q = dk3ma_d_div_ok(distance, delta, &mec);
+
+#line 543 "dk3figto.ctr"
+ newx = dk3ma_d_add_ok(
+ endpoint->x,
+ dk3ma_d_mul_ok(
+ q,
+ dk3ma_d_sub_ok(innerpoint->x, endpoint->x, &mec),
+ &mec
+ ),
+ &mec
+ );
+ newy = dk3ma_d_add_ok(
+ endpoint->y,
+ dk3ma_d_mul_ok(
+ q,
+ dk3ma_d_sub_ok(innerpoint->y, endpoint->y, &mec),
+ &mec
+ ),
+ &mec
+ );
+ if(0 == mec) {
+
+#line 562 "dk3figto.ctr"
+ endpoint->x = newx; endpoint->y = newy;
+ back = 1;
+ }
+ } else {
+
+#line 566 "dk3figto.ctr"
+ }
+ } else {
+
+#line 568 "dk3figto.ctr"
+ }
+ } else {
+
+#line 570 "dk3figto.ctr"
+ }
+ if(mec) { if(ec) { *ec = mec; } }
+
+#line 572 "dk3figto.ctr"
+ return back;
+}
+
+
+
+int
+dk3fig_tool_get_operation(dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj)
+{
+ int back = 0;
+
+
+#line 582 "dk3figto.ctr"
+ if((drw) && (obj)) {
+ if(0 < obj->lw) {
+ if(obj->pc != drw->transcol) {
+ back |= DK3_FIG_OP_STROKE;
+ }
+ }
+ if(obj->cl) {
+ if(-1 != obj->fi) {
+ if(obj->fc != drw->transcol) {
+ back |= DK3_FIG_OP_FILL;
+ }
+ if(40 < obj->fi) {
+ if(63 > obj->fi) {
+ back |= DK3_FIG_OP_PATTERN;
+ }
+ }
+ }
+ }
+ }
+
+#line 601 "dk3figto.ctr"
+ return back;
+}
+
+
+
+/** Mix a color component against black or white.
+ @param x Color component to mix.
+ @param y Black (0) or white (1).
+ @param alpha Ratio of x in 1/20.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Mix result.
+*/
+static
+double
+dk3fig_tool_color_alpha(double x, double y, double alpha, int *ec)
+{
+ double back;
+
+
+#line 619 "dk3figto.ctr"
+ back = dk3ma_d_add_ok(
+ dk3ma_d_mul_ok(x, alpha, ec),
+ dk3ma_d_mul_ok(y, dk3ma_d_sub_ok(20.0, alpha, ec), ec),
+ ec
+ ) / 20.0;
+
+#line 624 "dk3figto.ctr"
+ return back;
+}
+
+
+
+/** Modify color depending on the fill style.
+ @param rgb Destination and source pointer.
+ @param endval Value to mix against.
+ @param twe Coeffiecient for rgb, 1/20.
+*/
+static
+void
+dk3fig_tool_mix_color(
+ dk3_rgb_color_t *rgb,
+ double endval,
+ int twe
+)
+{
+ dk3_rgb_color_t myrgb; /* Intermediate result buffer. */
+ double alpha; /* Factor for mixing. */
+ int ec = 0; /* Mathematical error code. */
+
+
+#line 646 "dk3figto.ctr"
+ myrgb.r = rgb->r;
+ myrgb.g = rgb->g;
+ myrgb.b = rgb->b;
+ alpha = (double)twe;
+ myrgb.r = dk3fig_tool_color_alpha(rgb->r, endval, alpha, &ec);
+ myrgb.g = dk3fig_tool_color_alpha(rgb->g, endval, alpha, &ec);
+ myrgb.b = dk3fig_tool_color_alpha(rgb->b, endval, alpha, &ec);
+ if(0 == ec) {
+ rgb->r = myrgb.r; rgb->g = myrgb.g; rgb->b = myrgb.b;
+ }
+
+#line 656 "dk3figto.ctr"
+}
+
+
+
+/** Mix one color value against another value.
+ @param cv Primary color.
+ @param ov Other color (background color) to mix against.
+ @param twe Weight of cv, multiples of 1/20.
+ @return Color mixing result.
+*/
+static
+int
+dk3fig_tool_mix_one_int_color(int cv, int ov, int twe)
+{
+ int back;
+ back = ((twe * cv) + ((20 - twe) * ov)) / 20;
+ return back;
+}
+
+
+
+/** Mix color against background color value (white or black).
+ @param col Color to mix, input and output.
+ @param val Value to mix against (background color 0=black, 255=white).
+ @param twe Weight of input color, multiples of 1/20.
+*/
+static
+void
+dk3fig_tool_mix_int_color(
+ dk3_fig_color_t *col,
+ int val,
+ int twe
+)
+{
+ col->r = dk3fig_tool_mix_one_int_color(col->r, val, twe);
+ col->g = dk3fig_tool_mix_one_int_color(col->g, val, twe);
+ col->b = dk3fig_tool_mix_one_int_color(col->b, val, twe);
+}
+
+
+
+void
+dk3fig_tool_find_color(
+ dk3_rgb_color_t *rgb,
+ dk3_fig_drawing_t *drw,
+ int colno,
+ int fs
+)
+{
+ dk3_fig_color_t *pfc; /* Pointer to already defined color. */
+ int mycolno; /* Color number. */
+
+
+#line 708 "dk3figto.ctr"
+ mycolno = 0;
+ if(rgb) {
+ rgb->r = rgb->g = rgb->b = 0.0;
+ if(drw) {
+
+#line 712 "dk3figto.ctr"
+ if(drw->scol) {
+
+#line 713 "dk3figto.ctr"
+ if(drw->icol) {
+
+#line 714 "dk3figto.ctr"
+ if((0 <= colno) && (colno <= 31)) {
+
+#line 715 "dk3figto.ctr"
+ pfc = &(dk3fig_tool_low_rgb[colno]);
+ } else {
+
+#line 717 "dk3figto.ctr"
+ pfc = (dk3_fig_color_t *)dk3sto_it_find_like(
+ drw->icol, (void *)(&colno), 1
+ );
+ }
+ if(pfc) {
+ rgb->r = (double)(pfc->r) / 255.0;
+ rgb->g = (double)(pfc->g) / 255.0;
+ rgb->b = (double)(pfc->b) / 255.0;
+ mycolno = colno;
+ } else {
+
+#line 727 "dk3figto.ctr"
+ if(-1 != colno) {
+ /* ERROR: Color not found, using black as default! */
+ dk3app_log_1(drw->app, DK3_LL_WARNING, drw->msg, 7);
+ }
+ }
+ } else {
+
+#line 733 "dk3figto.ctr"
+ }
+ } else {
+
+#line 735 "dk3figto.ctr"
+ }
+ } else {
+
+#line 737 "dk3figto.ctr"
+ }
+ if(-1 < fs) {
+ if(20 > fs) {
+
+#line 740 "dk3figto.ctr"
+ switch(mycolno) {
+ case 0: {
+ dk3fig_tool_mix_color(rgb, 1.0, fs);
+ } break;
+ case 7: {
+ dk3fig_tool_mix_color(rgb, 0.0, fs);
+ } break;
+ default: {
+ dk3fig_tool_mix_color(rgb, 0.0, fs);
+ } break;
+ }
+ } else {
+ if(41 > fs) {
+ if(20 < fs) {
+
+#line 754 "dk3figto.ctr"
+ switch(mycolno) {
+ case 0: {
+ } break;
+ case 7: {
+ } break;
+ default: {
+ dk3fig_tool_mix_color(rgb, 1.0, (40 - fs));
+ } break;
+ }
+ }
+ }
+ }
+ }
+ if(NULL != drw) {
+ if(drw->codi) {
+ rgb->r = dk3ma_d_restrict_digits(rgb->r, drw->codi);
+ rgb->g = dk3ma_d_restrict_digits(rgb->g, drw->codi);
+ rgb->b = dk3ma_d_restrict_digits(rgb->b, drw->codi);
+ }
+ }
+ }
+
+#line 775 "dk3figto.ctr"
+}
+
+
+
+void
+dk3fig_tool_find_int_color(
+ dk3_fig_color_t *dst,
+ dk3_fig_drawing_t *drw,
+ int colno,
+ int fs
+)
+{
+ dk3_fig_color_t *pfc = NULL;
+ int mycolno;
+
+ mycolno = 0;
+ if(dst) {
+ dst->r = dst->g = dst->b = 0;
+ if(drw) {
+ if((0 <= colno) && (colno <= 31)) {
+ pfc = &(dk3fig_tool_low_rgb[colno]);
+ } else {
+ if(drw->scol) {
+ if(drw->icol) {
+ pfc = (dk3_fig_color_t *)dk3sto_it_find_like(
+ drw->icol, (void *)(&colno), 1
+ );
+ }
+ }
+ }
+ if(pfc) {
+ mycolno = colno;
+ dst->r = pfc->r; dst->g = pfc->g; dst->b = pfc->b;
+ } else {
+ if(-1 != colno) {
+ /* ERROR: Color not found, using black as default! */
+ dk3app_log_1(drw->app, DK3_LL_WARNING, drw->msg, 7);
+ }
+ }
+ }
+ if(-1 < fs) {
+ if(20 > fs) {
+
+#line 817 "dk3figto.ctr"
+ switch(mycolno) {
+ case 0: {
+ dk3fig_tool_mix_int_color(dst, 255, fs);
+ } break;
+ case 7: {
+ dk3fig_tool_mix_int_color(dst, 0, fs);
+ } break;
+ default: {
+ dk3fig_tool_mix_int_color(dst, 0, fs);
+ } break;
+ }
+ } else {
+ if((20 < fs) && (41 > fs)) {
+
+#line 830 "dk3figto.ctr"
+ switch(mycolno) {
+ case 0: {
+ } break;
+ case 7: {
+ } break;
+ default: {
+ dk3fig_tool_mix_int_color(dst, 255, (40 - fs));
+ } break;
+ }
+ }
+ }
+ }
+ }
+}
+
+
+
+void
+dk3fig_tool_rotate_point(
+ dk3_fig_poly_point_t *point,
+ double angle,
+ int *ec
+)
+{
+ double r; /* Radius from origin to point. */
+ double alpha; /* angle of point. */
+
+ if(point) {
+ r = sqrt(
+ dk3ma_d_add_ok(
+ dk3ma_d_square_ok(point->x, ec),
+ dk3ma_d_square_ok(point->y, ec),
+ ec
+ )
+ );
+ alpha = dk3ma_d_atan2(point->y, point->x);
+ alpha = dk3ma_d_add_ok(alpha, angle, ec);
+ point->x = r * cos(alpha);
+ point->y = r * sin(alpha);
+ }
+}
+
+
+
+void
+dk3fig_tool_rotate_spoint(
+ dk3_fig_spline_point_t *point,
+ double angle,
+ int *ec
+)
+{
+ double r; /* Radius origin to point. */
+ double alpha; /* Angle of point. */
+
+ if(point) {
+ r = sqrt(
+ dk3ma_d_add_ok(
+ dk3ma_d_square_ok(point->x, ec),
+ dk3ma_d_square_ok(point->y, ec),
+ ec
+ )
+ );
+ alpha = dk3ma_d_atan2(point->y, point->x);
+ alpha = dk3ma_d_add_ok(alpha, angle, ec);
+ point->x = r * cos(alpha);
+ point->y = r * sin(alpha);
+ }
+}
+
+
+void
+dk3fig_tool_shift_point(
+ dk3_fig_poly_point_t *point,
+ double x,
+ double y,
+ int *ec
+)
+{
+ if(point) {
+ point->x = dk3ma_d_add_ok(point->x, x, ec);
+ point->y = dk3ma_d_add_ok(point->y, y, ec);
+ }
+}
+
+
+
+void
+dk3fig_tool_shift_spoint(
+ dk3_fig_spline_point_t *point,
+ double x,
+ double y,
+ int *ec
+)
+{
+ if(point) {
+ point->x = dk3ma_d_add_ok(point->x, x, ec);
+ point->y = dk3ma_d_add_ok(point->y, y, ec);
+ }
+}
+
+
+
+int
+dk3fig_tool_font_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3_fig_font_t const *pl; /* Left pointer. */
+ dk3_fig_font_t const *pr; /* Right pointer. */
+ if(l) {
+ if(r) {
+ pl = (dk3_fig_font_t const *)l;
+ pr = (dk3_fig_font_t const *)r;
+ if(pl->psfont > pr->psfont) {
+ back = 1;
+ } else {
+ if(pl->psfont < pr->psfont) {
+ back = -1;
+ } else {
+ if(pl->fontno > pr->fontno) {
+ back = 1;
+ } else {
+ if(pl->fontno < pr->fontno) {
+ back = -1;
+ } else {
+ if(pl->fontsz > (pr->fontsz + 1.0e-6)) {
+ back = 1;
+ } else {
+ if(pl->fontsz < (pr->fontsz - 1.0e-6)) {
+ back = -1;
+ }
+ }
+ }
+ }
+ }
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3fig_tool_ps_font_number(dk3_fig_obj_t *obj)
+{
+ int back = -1;
+ int ff; /* Font flags. */
+
+ if(obj) {
+ if(DK3_FIG_OBJ_TEXT == obj->ot) {
+ ff = (obj->dt).txt.ff;
+ if(!(ff & DK3_FIG_FONT_FLAG_HIDDEN)) {
+ if(!(ff & DK3_FIG_FONT_FLAG_SPECIAL)) {
+ if(ff & DK3_FIG_FONT_FLAG_PS) {
+ back = (obj->dt).txt.fo;
+ } else {
+ switch((obj->dt).txt.fo) {
+ case DK3_FIG_FONT_LATEX_BOLD: { back = 2; } break;
+ case DK3_FIG_FONT_LATEX_ITALIC: { back = 1; } break;
+ case DK3_FIG_FONT_LATEX_SANS_SERIF: { back = 16; } break;
+ case DK3_FIG_FONT_LATEX_TYPEWRITER: { back = 12; } break;
+ default: { back = 0; } break;
+ }
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3fig_tool_must_set_color(
+ int hc1,
+ double r1,
+ double g1,
+ double b1,
+ double r2,
+ double g2,
+ double b2
+)
+{
+ int back = 1;
+ int ec = 0; /* Mathematical error code. */
+
+ if(hc1) {
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok(r1, r2, &ec))) {
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok(g1, g2, &ec))) {
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok(b1, b2, &ec))) {
+ if(0 == ec) {
+ back = 0;
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3fig_tool_must_set_font(
+ int hfn,
+ int ofn,
+ double ofs,
+ int nfn,
+ double nfs
+)
+{
+ int back = 1;
+ int ec = 0; /* Mathematical error code. */
+
+ if(hfn) {
+ if(ofn == nfn) {
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok(ofs, nfs, &ec))) {
+ if(0 == ec) {
+ back = 0;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Compare two text handling structures.
+ @param l Left text handling structure.
+ @param r Right text handling structure.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+int
+dk3fig_tool_text_handling_compare(void const *l, void const *r, int cr)
+{
+ f2l_text_handling_t const *pl; /* Left pointer. */
+ f2l_text_handling_t const *pr; /* Right pointer. */
+ int back = 0;
+
+ if(l) {
+ if(r) {
+ pl = (f2l_text_handling_t const *)l;
+ pr = (f2l_text_handling_t const *)r;
+ if(pl->psFontNo > pr->psFontNo) {
+ back = 1;
+ } else {
+ if(pl->psFontNo < pr->psFontNo) {
+ back = -1;
+ }
+ }
+ if(0 == back) {
+ if(pl->fontSize > (pr->fontSize + 1.0e-6)) {
+ back = 1;
+ } else {
+ if(pr->fontSize > (pl->fontSize + 1.0e-6)) {
+ back = -1;
+ }
+ }
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+char const *
+dk3fig_tool_short_output_file_name(
+ dkChar const *fullName,
+ dk3_app_t *app
+)
+{
+ char buf[DK3_MAX_PATH]; /* Conversion buffer. */
+ dkChar const *snptr; /* Start of old short name. */
+ dkChar const *ptr; /* Traverse fullName. */
+ char const *back = NULL;
+ int res = 0; /* Operation result. */
+
+
+#line 1119 "dk3figto.ctr"
+ if(fullName) {
+ snptr = NULL; ptr = fullName;
+ while(*ptr) {
+ if((*ptr == dkT('/')) || (*ptr == dkT('\\'))) {
+ snptr = ptr;
+ }
+ ptr++;
+ }
+ if(snptr) {
+ snptr++;
+ } else {
+ snptr = fullName;
+ }
+ if(snptr) {
+ switch(dk3app_get_encoding(app)) {
+ case DK3_ENCODING_UTF8: {
+ res = dk3str_to_c8u_app(
+ buf, sizeof(buf), snptr, dk3app_get_encoding(app), app
+ );
+ } break;
+ default: {
+ res = dk3str_to_c8p_app(
+ buf, sizeof(buf), snptr, dk3app_get_encoding(app), app
+ );
+ } break;
+ }
+ if(res) {
+ back = dk3str_c8_dup_app(buf, app);
+ }
+ }
+ }
+
+#line 1150 "dk3figto.ctr"
+ return back;
+}
+
diff --git a/support/dktools/dk3figto.ctr b/support/dktools/dk3figto.ctr
new file mode 100644
index 0000000000..d071e4b7a6
--- /dev/null
+++ b/support/dktools/dk3figto.ctr
@@ -0,0 +1,1152 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Check whether or not an object is a background rectangle.
+ A background rectangle is not drawn to output, it is only
+ used to calculate the bounding box of the drawing.
+ @param obj Object to check.
+ @param objno Object number in storage.
+ @return 1 for background rectangle, 0 for normal object.
+*/
+int
+dk3fig_tool_is_bgrect(dk3_fig_obj_t const *obj, unsigned long objno);
+
+/** Find line width for object.
+ @param drw Drawing to which the object belongs.
+ @param obj Object to find line width for.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Positive line width in Fig units on success, 0.0 on error.
+*/
+double
+dk3fig_tool_get_lw(
+ dk3_fig_drawing_t const *drw,
+ dk3_fig_obj_t const *obj,
+ int *ec
+);
+
+/** Get object line width in bp.
+ @param drw Drawing to which the object belongs.
+ @param obj Object to find line width for.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Positive line width in Fig units on success, 0.0 on error.
+*/
+double
+dk3fig_tool_get_lw_in_bp(
+ dk3_fig_drawing_t const *drw,
+ dk3_fig_obj_t const *obj,
+ int *ec
+);
+
+/** Calculate kappa value for arc.
+ To approximate arcs using Bezier spline segments we calculate
+ the control points as xcs = xstart + kappa * x'(0) and
+ xce = xend - kappa * x'(1). Using a kappa depending on the
+ angle alpha results in a better approximation than using the
+ fixed constant 1/3.
+ @param alpha Arc angle.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Non-negative value on success, -1.0 on error.
+*/
+double
+dk3fig_tool_arc_kappa(double alpha, int *ec);
+
+/** Find number of Bezier segments per X-spline segment.
+ @param drw Drawing.
+ @param primobj Flag: Primary object (1=object, 0=arrowhead).
+ @return Number of Bezier segments per X-spline segment.
+*/
+size_t
+dk3fig_tool_xssbs(dk3_fig_drawing_t *drw, int primobj);
+
+/** Calculate distance between two points.
+ @param p1 Point 1.
+ @param p2 Point 2.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Distance value.
+*/
+double
+dk3fig_tool_point_distance(
+ dk3_fig_poly_point_t const *p1,
+ dk3_fig_poly_point_t const *p2,
+ int *ec
+);
+
+/** Move polyline points to the left to skip first segment.
+ @param dst Destination pointer (address of element 0).
+ @param src Source pointer (address of element 1).
+ @param np Number of elements to shift.
+*/
+void
+dk3fig_tool_poly_point_move_left(
+ dk3_fig_poly_point_t *dst,
+ dk3_fig_poly_point_t *src,
+ size_t np
+);
+
+/** Shorten a line segment.
+ @param endpoint Endpoint of the polyline.
+ @param innerpoint Inner point of the polyline.
+ @param distance Distance to cut.
+ @param ec Pointer to error code variable, may be NULL.
+ @return 1 on success, 0 on error (point distance too short).
+*/
+int
+dk3fig_tool_cut_segment(
+ dk3_fig_poly_point_t *endpoint,
+ dk3_fig_poly_point_t const *innerpoint,
+ double distance,
+ int *ec
+);
+
+/** Find operations necessary to draw an object.
+ @param drw Drawing.
+ @param obj Object.
+ @return Drawing operations combination, see @ref dk3figoperations.
+*/
+int
+dk3fig_tool_get_operation(dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj);
+
+/** Find RGB color (double values).
+ @param rgb Color structure to set up.
+ @param drw Drawing to find color for.
+ @param colno Color number.
+ @param fs Fill style.
+*/
+void
+dk3fig_tool_find_color(
+ dk3_rgb_color_t *rgb,
+ dk3_fig_drawing_t *drw,
+ int colno,
+ int fs
+);
+
+/** Find RGB color (int values).
+ @param dst Color structure to set up.
+ @param drw Drawing to find color for.
+ @param colno Color number.
+ @param fs Fill style.
+*/
+void
+dk3fig_tool_find_int_color(
+ dk3_fig_color_t *dst,
+ dk3_fig_drawing_t *drw,
+ int colno,
+ int fs
+);
+
+/** Rotate a point.
+ @param point Point to rotate.
+ @param angle Rotation angle in radians.
+ @param ec Pointer to error code variable, may be NULL.
+*/
+void
+dk3fig_tool_rotate_point(
+ dk3_fig_poly_point_t *point,
+ double angle,
+ int *ec
+);
+
+/** Rotate a spline point.
+ @param point Point to rotate.
+ @param angle Rotation angle in radians.
+ @param ec Pointer to error code variable, may be NULL.
+*/
+void
+dk3fig_tool_rotate_spoint(
+ dk3_fig_spline_point_t *point,
+ double angle,
+ int *ec
+);
+
+/** Shift a point.
+ @param point Point to shift.
+ @param x X shift.
+ @param y Y shift.
+ @param ec Pointer to error code variable, may be NULL.
+*/
+void
+dk3fig_tool_shift_point(
+ dk3_fig_poly_point_t *point,
+ double x,
+ double y,
+ int *ec
+);
+
+/** Shift a spline point.
+ @param point Point to shift.
+ @param x X shift.
+ @param y Y shift.
+ @param ec Pointer to error code variable, may be NULL.
+*/
+void
+dk3fig_tool_shift_spoint(
+ dk3_fig_spline_point_t *point,
+ double x,
+ double y,
+ int *ec
+);
+
+/** Compare two font structures.
+ Comparison by font number first, font size later.
+ @param l Left font structure.
+ @param r Right font structure.
+ @param cr Comparison criteria, ignored.
+ @return Comparison result.
+*/
+int
+dk3fig_tool_font_compare(void const *l, void const *r, int cr);
+
+/** Find PS font number for text object.
+ @param obj Text object.
+ @return Non-negative font number on success
+ (PS font suitable for this text object),
+ -1 on error (not a text object or hidden or special text).
+*/
+int
+dk3fig_tool_ps_font_number(dk3_fig_obj_t *obj);
+
+/** Check whether a new color must be set.
+ @param hc1 Flag: Old color configured.
+ @param r1 Old red.
+ @param g1 Old green.
+ @param b1 Old blue.
+ @param r2 New red.
+ @param g2 New green.
+ @param b2 New blue.
+ @return 1 if the color must be set, 0 otherwise.
+*/
+int
+dk3fig_tool_must_set_color(
+ int hc1,
+ double r1,
+ double g1,
+ double b1,
+ double r2,
+ double g2,
+ double b2
+);
+
+/** Check whether we must set up a new font.
+ @param hfn Flag: Have old font number and size.
+ @param ofn Old font number.
+ @param ofs Old font size.
+ @param nfn New font number.
+ @param nfs New font size.
+ @return 1 if we must install the new font, 0 otherwise.
+*/
+int
+dk3fig_tool_must_set_font(
+ int hfn,
+ int ofn,
+ double ofs,
+ int nfn,
+ double nfs
+);
+
+/** Obtain short output file name as 8-bit character string.
+ The result of this function is used as argument to an
+ includegraphics LaTeX instruction.
+ @param fullName Full name of output file.
+ @param app Application structure.
+ @return Pointer to 8-bit character string on success, NULL on error.
+*/
+char const *
+dk3fig_tool_short_output_file_name(
+ dkChar const *fullName,
+ dk3_app_t *app
+);
+
+/** Compare two text handling entries.
+ @param l Left pointer.
+ @param r Right pointer.
+ @param cr Comparison criteria.
+ @return Comparison result.
+*/
+int
+dk3fig_tool_text_handling_compare(void const *l, void const *r, int cr);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+
+#include "dk3all.h"
+#include "dk3fig.h"
+#include "dk3figto.h"
+#include "fig2lat.h"
+
+
+
+$!trace-include
+
+
+
+/** Color palette for colors 0...31 as calculated from the floating point
+ numbers.
+*/
+static dk3_fig_color_t dk3fig_tool_low_rgb[] = {
+ /* 0: black */ { 0, 0, 0, 0 },
+ /* 1: blue */ { 1, 0, 0, 255 },
+ /* 2: green */ { 2, 0, 255, 0 },
+ /* 3: cyan */ { 3, 0, 255, 255 },
+ /* 4: red */ { 4, 255, 0, 0 },
+ /* 5: magenta */ { 5, 255, 0, 255 },
+ /* 6: yellow */ { 6, 255, 255, 0 },
+ /* 7: white */ { 7, 255, 255, 255 },
+ /* 8: dark blue */ { 8, 0, 0, 143 },
+ /* 9: blue */ { 9, 0, 0, 176 },
+ /* 10: blue */ { 10, 0, 0, 209 },
+ /* 11: blue */ { 11, 135, 207, 255 },
+ /* 12: dark green */ { 12, 0, 143, 0 },
+ /* 13: green */ { 13, 0, 176, 0 },
+ /* 14: green */ { 14, 0, 209, 0 },
+ /* 15: dark cyan */ { 15, 0, 143, 143 },
+ /* 16: cyan */ { 16, 0, 176, 176 },
+ /* 17: cyan */ { 17, 0, 209, 209 },
+ /* 18: dark red */ { 18, 143, 0, 0 },
+ /* 19: red */ { 19, 176, 0, 0 },
+ /* 20: red */ { 20, 209, 0, 0 },
+ /* 21: dark magenta */ { 21, 143, 0, 143 },
+ /* 22: magenta */ { 22, 176, 0, 176 },
+ /* 23: magenta */ { 23, 209, 0, 209 },
+ /* 24: dark brown */ { 24, 127, 48, 0 },
+ /* 25: brown */ { 25, 160, 63, 0 },
+ /* 26: brown */ { 26, 191, 97, 0 },
+ /* 27: dark pink */ { 27, 255, 127, 127 },
+ /* 28: pink */ { 28, 255, 160, 160 },
+ /* 29: pink */ { 29, 255, 191, 191 },
+ /* 30: pink */ { 30, 255, 224, 224 },
+ /* 31: gold */ { 31, 255, 214, 0 }
+};
+
+
+
+int
+dk3fig_tool_is_bgrect(dk3_fig_obj_t const *obj, unsigned long objno)
+{
+ int back = 0;
+ if(obj) {
+ if(0UL == objno) {
+ if(DK3_FIG_OBJ_POLYLINE == obj->ot) {
+ if(2 == obj->st) {
+ if(999 == obj->la) {
+ if(0 == obj->lw) {
+ if(-1 == obj->fi) {
+ if((-1 == obj->pc) || (7 == obj->pc)) {
+ back = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+double
+dk3fig_tool_get_lw(
+ dk3_fig_drawing_t const *drw,
+ dk3_fig_obj_t const *obj,
+ int *ec
+)
+{
+ int mec = 0; /* Mathematical error code. */
+#if VERSION_BEFORE_20140330
+ double lw; /* Line width. */
+#endif
+ double back = 0.0;
+ $? "+ dk3fig_tool_get_lw"
+#if VERSION_BEFORE_20140330
+ if((drw) && (obj)) {
+ lw = (double)(obj->lw); $? ". lw=%lg res=%lg", lw, drw->res
+ back = dk3ma_d_mul_ok(lw, drw->res, &mec) / 80.0; $? ". back = %lg", back
+ if(drw->lighten) { back = back / 2.0; } $? ". back = %lg", back
+ if(mec) {
+ back = 0.0;
+ if(ec) { *ec = mec; }
+ }
+ }
+#else
+ if ((drw) && (obj)) {
+ /* back = obj->lw * drw->lwbp * drw->res / 72 */
+ back = dk3ma_d_mul_ok(
+ dk3ma_d_mul_ok(obj->lw, drw->lwbp, &mec),
+ drw->res,
+ &mec
+ ) / 72.0;
+ if (mec) {
+ back = 0.0;
+ if (ec) { *ec = mec; }
+ }
+ }
+#endif
+ $? "- dk3fig_tool_get_lw %lg", back
+ return back;
+}
+
+
+
+double
+dk3fig_tool_get_lw_in_bp(
+ dk3_fig_drawing_t const *drw,
+ dk3_fig_obj_t const *obj,
+ int *ec
+)
+{
+ double back = 0.0;
+ int mec = 0;
+ if ((drw) && (obj)) {
+ back = dk3ma_d_mul_ok(obj->lw, drw->lwbp, &mec);
+ if (mec) {
+ back = 0.0;
+ if (ec) { *ec = mec; }
+ }
+ }
+ return back;
+}
+
+
+double
+dk3fig_tool_arc_kappa(double alpha, int *ec)
+{
+ double back;
+ double emcosa; /* 1 - cos(alpha). */
+ int mec = 0; /* Mathematical error code. */
+ $? "+ dk3fig_tool_arc_kappa alpha=%lg", alpha
+ emcosa = 1.0 - cos(alpha);
+ back = dk3ma_d_div_ok(
+ ((2.0 * sqrt(8.0 * emcosa)) - (4.0 * sin(alpha))),
+ dk3ma_d_mul_ok(alpha, (3.0 * emcosa), &mec),
+ &mec
+ );
+ if(mec) {
+ back = -1.0;
+ if(ec) { *ec = mec; }
+ } $? "- dk3fig_tool_arc_kappa %lg", back
+ return back;
+}
+
+
+
+size_t
+dk3fig_tool_xssbs(dk3_fig_drawing_t *drw, int primobj)
+{
+ size_t back = 8;
+ $? "+ dk3fig_tool_xssbs"
+ if(drw) { back = drw->xssbs; }
+ if(!(primobj)) { back = back / 2; }
+ if(back < 2) { back = 2; }
+ $? "- dk3fig_tool_xssbs %u", (unsigned)back
+ return back;
+}
+
+
+
+double
+dk3fig_tool_point_distance(
+ dk3_fig_poly_point_t const *p1,
+ dk3_fig_poly_point_t const *p2,
+ int *ec
+)
+{
+ double back = 0.0;
+ $? "+ dk3fig_tool_point_distance"
+ if((p1) && (p2)) {
+ back = sqrt(
+ dk3ma_d_add_ok(
+ dk3ma_d_square_ok(
+ dk3ma_d_sub_ok(p2->x, p1->x, ec),
+ ec
+ ),
+ dk3ma_d_square_ok(
+ dk3ma_d_sub_ok(p2->y, p1->y, ec),
+ ec
+ ),
+ ec
+ )
+ );
+ } $? "- dk3fig_tool_point_distance %lg", back
+ return back;
+}
+
+
+
+void
+dk3fig_tool_poly_point_move_left(
+ dk3_fig_poly_point_t *dst,
+ dk3_fig_poly_point_t *src,
+ size_t np
+)
+{
+ dk3_fig_poly_point_t *dptr; /* Destination buffer pointer. */
+ dk3_fig_poly_point_t *sptr; /* Source buffer pointer. */
+ size_t i; /* Index to traverse all elements. */
+ $? "+ dk3fig_tool_poly_point_move_left"
+ if((dst) && (src) && (np)) {
+ dptr = dst; sptr = src; i = np;
+ while(i--) { *(dptr++) = *(sptr++); }
+ } $? "- dk3fig_tool_poly_point_move_left"
+}
+
+
+
+int
+dk3fig_tool_cut_segment(
+ dk3_fig_poly_point_t *endpoint,
+ dk3_fig_poly_point_t const *innerpoint,
+ double distance,
+ int *ec
+)
+{
+ double delta; /* Segment length. */
+ double q; /* Cut factor. */
+ double newx; /* New x of end point. */
+ double newy; /* New y of end point. */
+ int back = 0;
+ int mec = 0; /* Mathematical error code. */
+ $? "+ dk3fig_tool_cut_segment"
+ if((endpoint) && (innerpoint)) { $? ". points ok"
+ $? ". (%lg,%lg) (%lg,%lg)", endpoint->x, endpoint->y, innerpoint->x, innerpoint->y
+ if(0.0 < distance) { $? ". distance %lg ok", distance
+ delta = sqrt(
+ dk3ma_d_add_ok(
+ dk3ma_d_square_ok(
+ dk3ma_d_sub_ok(innerpoint->x, endpoint->x, &mec),
+ &mec
+ ),
+ dk3ma_d_square_ok(
+ dk3ma_d_sub_ok(innerpoint->y, endpoint->y, &mec),
+ &mec
+ ),
+ &mec
+ )
+ ); $? ". delta=%lg distance=%lg", delta, distance
+ if(delta > distance) { $? ". delta ok"
+ q = dk3ma_d_div_ok(distance, delta, &mec); $? ". q=%lg", q
+ newx = dk3ma_d_add_ok(
+ endpoint->x,
+ dk3ma_d_mul_ok(
+ q,
+ dk3ma_d_sub_ok(innerpoint->x, endpoint->x, &mec),
+ &mec
+ ),
+ &mec
+ );
+ newy = dk3ma_d_add_ok(
+ endpoint->y,
+ dk3ma_d_mul_ok(
+ q,
+ dk3ma_d_sub_ok(innerpoint->y, endpoint->y, &mec),
+ &mec
+ ),
+ &mec
+ );
+ if(0 == mec) { $? ". (%lg,%lg)", newx, newy
+ endpoint->x = newx; endpoint->y = newy;
+ back = 1;
+ }
+ } else { $? "! segment too short"
+ }
+ } else { $? "! distance"
+ }
+ } else { $? "! points"
+ }
+ if(mec) { if(ec) { *ec = mec; } } $? "- dk3fig_tool_cut_segment %d", back
+ return back;
+}
+
+
+
+int
+dk3fig_tool_get_operation(dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj)
+{
+ int back = 0;
+ $? "+ dk3fig_tool_get_operation"
+ if((drw) && (obj)) {
+ if(0 < obj->lw) {
+ if(obj->pc != drw->transcol) {
+ back |= DK3_FIG_OP_STROKE;
+ }
+ }
+ if(obj->cl) {
+ if(-1 != obj->fi) {
+ if(obj->fc != drw->transcol) {
+ back |= DK3_FIG_OP_FILL;
+ }
+ if(40 < obj->fi) {
+ if(63 > obj->fi) {
+ back |= DK3_FIG_OP_PATTERN;
+ }
+ }
+ }
+ }
+ } $? "- dk3fig_tool_get_operation %d", back
+ return back;
+}
+
+
+
+/** Mix a color component against black or white.
+ @param x Color component to mix.
+ @param y Black (0) or white (1).
+ @param alpha Ratio of x in 1/20.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Mix result.
+*/
+static
+double
+dk3fig_tool_color_alpha(double x, double y, double alpha, int *ec)
+{
+ double back;
+ $? "+ dk3fig_tool_color_alpha x=%lg y=%lg, alpha=%lg", x, y, alpha
+ back = dk3ma_d_add_ok(
+ dk3ma_d_mul_ok(x, alpha, ec),
+ dk3ma_d_mul_ok(y, dk3ma_d_sub_ok(20.0, alpha, ec), ec),
+ ec
+ ) / 20.0; $? "- dk3fig_tool_color_alpha %lg", back
+ return back;
+}
+
+
+
+/** Modify color depending on the fill style.
+ @param rgb Destination and source pointer.
+ @param endval Value to mix against.
+ @param twe Coeffiecient for rgb, 1/20.
+*/
+static
+void
+dk3fig_tool_mix_color(
+ dk3_rgb_color_t *rgb,
+ double endval,
+ int twe
+)
+{
+ dk3_rgb_color_t myrgb; /* Intermediate result buffer. */
+ double alpha; /* Factor for mixing. */
+ int ec = 0; /* Mathematical error code. */
+ $? "+ dk3fig_tool_mix_color"
+ myrgb.r = rgb->r;
+ myrgb.g = rgb->g;
+ myrgb.b = rgb->b;
+ alpha = (double)twe;
+ myrgb.r = dk3fig_tool_color_alpha(rgb->r, endval, alpha, &ec);
+ myrgb.g = dk3fig_tool_color_alpha(rgb->g, endval, alpha, &ec);
+ myrgb.b = dk3fig_tool_color_alpha(rgb->b, endval, alpha, &ec);
+ if(0 == ec) {
+ rgb->r = myrgb.r; rgb->g = myrgb.g; rgb->b = myrgb.b;
+ } $? "- dk3fig_tool_mix_color"
+}
+
+
+
+/** Mix one color value against another value.
+ @param cv Primary color.
+ @param ov Other color (background color) to mix against.
+ @param twe Weight of cv, multiples of 1/20.
+ @return Color mixing result.
+*/
+static
+int
+dk3fig_tool_mix_one_int_color(int cv, int ov, int twe)
+{
+ int back;
+ back = ((twe * cv) + ((20 - twe) * ov)) / 20;
+ return back;
+}
+
+
+
+/** Mix color against background color value (white or black).
+ @param col Color to mix, input and output.
+ @param val Value to mix against (background color 0=black, 255=white).
+ @param twe Weight of input color, multiples of 1/20.
+*/
+static
+void
+dk3fig_tool_mix_int_color(
+ dk3_fig_color_t *col,
+ int val,
+ int twe
+)
+{
+ col->r = dk3fig_tool_mix_one_int_color(col->r, val, twe);
+ col->g = dk3fig_tool_mix_one_int_color(col->g, val, twe);
+ col->b = dk3fig_tool_mix_one_int_color(col->b, val, twe);
+}
+
+
+
+void
+dk3fig_tool_find_color(
+ dk3_rgb_color_t *rgb,
+ dk3_fig_drawing_t *drw,
+ int colno,
+ int fs
+)
+{
+ dk3_fig_color_t *pfc; /* Pointer to already defined color. */
+ int mycolno; /* Color number. */
+ $? "+ dk3fig_tool_find_color %d", colno
+ mycolno = 0;
+ if(rgb) {
+ rgb->r = rgb->g = rgb->b = 0.0;
+ if(drw) { $? ". drw"
+ if(drw->scol) { $? ". scol"
+ if(drw->icol) { $? ". icol"
+ if((0 <= colno) && (colno <= 31)) { $? ". built-in color"
+ pfc = &(dk3fig_tool_low_rgb[colno]);
+ } else { $? ". defined color"
+ pfc = (dk3_fig_color_t *)dk3sto_it_find_like(
+ drw->icol, (void *)(&colno), 1
+ );
+ }
+ if(pfc) {
+ rgb->r = (double)(pfc->r) / 255.0;
+ rgb->g = (double)(pfc->g) / 255.0;
+ rgb->b = (double)(pfc->b) / 255.0;
+ mycolno = colno;
+ } else { $? "! color not found %d", colno
+ if(-1 != colno) {
+ /* ERROR: Color not found, using black as default! */
+ dk3app_log_1(drw->app, DK3_LL_WARNING, drw->msg, 7);
+ }
+ }
+ } else { $? "! icol"
+ }
+ } else { $? "! scol"
+ }
+ } else { $? "! drw"
+ }
+ if(-1 < fs) {
+ if(20 > fs) { $? ". mix against black"
+ switch(mycolno) {
+ case 0: {
+ dk3fig_tool_mix_color(rgb, 1.0, fs);
+ } break;
+ case 7: {
+ dk3fig_tool_mix_color(rgb, 0.0, fs);
+ } break;
+ default: {
+ dk3fig_tool_mix_color(rgb, 0.0, fs);
+ } break;
+ }
+ } else {
+ if(41 > fs) {
+ if(20 < fs) { $? ". mix against white"
+ switch(mycolno) {
+ case 0: {
+ } break;
+ case 7: {
+ } break;
+ default: {
+ dk3fig_tool_mix_color(rgb, 1.0, (40 - fs));
+ } break;
+ }
+ }
+ }
+ }
+ }
+ if(NULL != drw) {
+ if(drw->codi) {
+ rgb->r = dk3ma_d_restrict_digits(rgb->r, drw->codi);
+ rgb->g = dk3ma_d_restrict_digits(rgb->g, drw->codi);
+ rgb->b = dk3ma_d_restrict_digits(rgb->b, drw->codi);
+ }
+ }
+ } $? "- dk3fig_tool_find_color"
+}
+
+
+
+void
+dk3fig_tool_find_int_color(
+ dk3_fig_color_t *dst,
+ dk3_fig_drawing_t *drw,
+ int colno,
+ int fs
+)
+{
+ dk3_fig_color_t *pfc = NULL;
+ int mycolno;
+
+ mycolno = 0;
+ if(dst) {
+ dst->r = dst->g = dst->b = 0;
+ if(drw) {
+ if((0 <= colno) && (colno <= 31)) {
+ pfc = &(dk3fig_tool_low_rgb[colno]);
+ } else {
+ if(drw->scol) {
+ if(drw->icol) {
+ pfc = (dk3_fig_color_t *)dk3sto_it_find_like(
+ drw->icol, (void *)(&colno), 1
+ );
+ }
+ }
+ }
+ if(pfc) {
+ mycolno = colno;
+ dst->r = pfc->r; dst->g = pfc->g; dst->b = pfc->b;
+ } else {
+ if(-1 != colno) {
+ /* ERROR: Color not found, using black as default! */
+ dk3app_log_1(drw->app, DK3_LL_WARNING, drw->msg, 7);
+ }
+ }
+ }
+ if(-1 < fs) {
+ if(20 > fs) { $? ". mix against black"
+ switch(mycolno) {
+ case 0: {
+ dk3fig_tool_mix_int_color(dst, 255, fs);
+ } break;
+ case 7: {
+ dk3fig_tool_mix_int_color(dst, 0, fs);
+ } break;
+ default: {
+ dk3fig_tool_mix_int_color(dst, 0, fs);
+ } break;
+ }
+ } else {
+ if((20 < fs) && (41 > fs)) { $? ". mix against white"
+ switch(mycolno) {
+ case 0: {
+ } break;
+ case 7: {
+ } break;
+ default: {
+ dk3fig_tool_mix_int_color(dst, 255, (40 - fs));
+ } break;
+ }
+ }
+ }
+ }
+ }
+}
+
+
+
+void
+dk3fig_tool_rotate_point(
+ dk3_fig_poly_point_t *point,
+ double angle,
+ int *ec
+)
+{
+ double r; /* Radius from origin to point. */
+ double alpha; /* angle of point. */
+
+ if(point) {
+ r = sqrt(
+ dk3ma_d_add_ok(
+ dk3ma_d_square_ok(point->x, ec),
+ dk3ma_d_square_ok(point->y, ec),
+ ec
+ )
+ );
+ alpha = dk3ma_d_atan2(point->y, point->x);
+ alpha = dk3ma_d_add_ok(alpha, angle, ec);
+ point->x = r * cos(alpha);
+ point->y = r * sin(alpha);
+ }
+}
+
+
+
+void
+dk3fig_tool_rotate_spoint(
+ dk3_fig_spline_point_t *point,
+ double angle,
+ int *ec
+)
+{
+ double r; /* Radius origin to point. */
+ double alpha; /* Angle of point. */
+
+ if(point) {
+ r = sqrt(
+ dk3ma_d_add_ok(
+ dk3ma_d_square_ok(point->x, ec),
+ dk3ma_d_square_ok(point->y, ec),
+ ec
+ )
+ );
+ alpha = dk3ma_d_atan2(point->y, point->x);
+ alpha = dk3ma_d_add_ok(alpha, angle, ec);
+ point->x = r * cos(alpha);
+ point->y = r * sin(alpha);
+ }
+}
+
+
+void
+dk3fig_tool_shift_point(
+ dk3_fig_poly_point_t *point,
+ double x,
+ double y,
+ int *ec
+)
+{
+ if(point) {
+ point->x = dk3ma_d_add_ok(point->x, x, ec);
+ point->y = dk3ma_d_add_ok(point->y, y, ec);
+ }
+}
+
+
+
+void
+dk3fig_tool_shift_spoint(
+ dk3_fig_spline_point_t *point,
+ double x,
+ double y,
+ int *ec
+)
+{
+ if(point) {
+ point->x = dk3ma_d_add_ok(point->x, x, ec);
+ point->y = dk3ma_d_add_ok(point->y, y, ec);
+ }
+}
+
+
+
+int
+dk3fig_tool_font_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3_fig_font_t const *pl; /* Left pointer. */
+ dk3_fig_font_t const *pr; /* Right pointer. */
+ if(l) {
+ if(r) {
+ pl = (dk3_fig_font_t const *)l;
+ pr = (dk3_fig_font_t const *)r;
+ if(pl->psfont > pr->psfont) {
+ back = 1;
+ } else {
+ if(pl->psfont < pr->psfont) {
+ back = -1;
+ } else {
+ if(pl->fontno > pr->fontno) {
+ back = 1;
+ } else {
+ if(pl->fontno < pr->fontno) {
+ back = -1;
+ } else {
+ if(pl->fontsz > (pr->fontsz + 1.0e-6)) {
+ back = 1;
+ } else {
+ if(pl->fontsz < (pr->fontsz - 1.0e-6)) {
+ back = -1;
+ }
+ }
+ }
+ }
+ }
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3fig_tool_ps_font_number(dk3_fig_obj_t *obj)
+{
+ int back = -1;
+ int ff; /* Font flags. */
+
+ if(obj) {
+ if(DK3_FIG_OBJ_TEXT == obj->ot) {
+ ff = (obj->dt).txt.ff;
+ if(!(ff & DK3_FIG_FONT_FLAG_HIDDEN)) {
+ if(!(ff & DK3_FIG_FONT_FLAG_SPECIAL)) {
+ if(ff & DK3_FIG_FONT_FLAG_PS) {
+ back = (obj->dt).txt.fo;
+ } else {
+ switch((obj->dt).txt.fo) {
+ case DK3_FIG_FONT_LATEX_BOLD: { back = 2; } break;
+ case DK3_FIG_FONT_LATEX_ITALIC: { back = 1; } break;
+ case DK3_FIG_FONT_LATEX_SANS_SERIF: { back = 16; } break;
+ case DK3_FIG_FONT_LATEX_TYPEWRITER: { back = 12; } break;
+ default: { back = 0; } break;
+ }
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3fig_tool_must_set_color(
+ int hc1,
+ double r1,
+ double g1,
+ double b1,
+ double r2,
+ double g2,
+ double b2
+)
+{
+ int back = 1;
+ int ec = 0; /* Mathematical error code. */
+
+ if(hc1) {
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok(r1, r2, &ec))) {
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok(g1, g2, &ec))) {
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok(b1, b2, &ec))) {
+ if(0 == ec) {
+ back = 0;
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3fig_tool_must_set_font(
+ int hfn,
+ int ofn,
+ double ofs,
+ int nfn,
+ double nfs
+)
+{
+ int back = 1;
+ int ec = 0; /* Mathematical error code. */
+
+ if(hfn) {
+ if(ofn == nfn) {
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok(ofs, nfs, &ec))) {
+ if(0 == ec) {
+ back = 0;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Compare two text handling structures.
+ @param l Left text handling structure.
+ @param r Right text handling structure.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+int
+dk3fig_tool_text_handling_compare(void const *l, void const *r, int cr)
+{
+ f2l_text_handling_t const *pl; /* Left pointer. */
+ f2l_text_handling_t const *pr; /* Right pointer. */
+ int back = 0;
+
+ if(l) {
+ if(r) {
+ pl = (f2l_text_handling_t const *)l;
+ pr = (f2l_text_handling_t const *)r;
+ if(pl->psFontNo > pr->psFontNo) {
+ back = 1;
+ } else {
+ if(pl->psFontNo < pr->psFontNo) {
+ back = -1;
+ }
+ }
+ if(0 == back) {
+ if(pl->fontSize > (pr->fontSize + 1.0e-6)) {
+ back = 1;
+ } else {
+ if(pr->fontSize > (pl->fontSize + 1.0e-6)) {
+ back = -1;
+ }
+ }
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+char const *
+dk3fig_tool_short_output_file_name(
+ dkChar const *fullName,
+ dk3_app_t *app
+)
+{
+ char buf[DK3_MAX_PATH]; /* Conversion buffer. */
+ dkChar const *snptr; /* Start of old short name. */
+ dkChar const *ptr; /* Traverse fullName. */
+ char const *back = NULL;
+ int res = 0; /* Operation result. */
+ $? "+ dk3fig_tool_short_output_file_name"
+ if(fullName) {
+ snptr = NULL; ptr = fullName;
+ while(*ptr) {
+ if((*ptr == dkT('/')) || (*ptr == dkT('\\'))) {
+ snptr = ptr;
+ }
+ ptr++;
+ }
+ if(snptr) {
+ snptr++;
+ } else {
+ snptr = fullName;
+ }
+ if(snptr) {
+ switch(dk3app_get_encoding(app)) {
+ case DK3_ENCODING_UTF8: {
+ res = dk3str_to_c8u_app(
+ buf, sizeof(buf), snptr, dk3app_get_encoding(app), app
+ );
+ } break;
+ default: {
+ res = dk3str_to_c8p_app(
+ buf, sizeof(buf), snptr, dk3app_get_encoding(app), app
+ );
+ } break;
+ }
+ if(res) {
+ back = dk3str_c8_dup_app(buf, app);
+ }
+ }
+ } $? "- dk3fig_tool_short_output_file_name %!8s", TR_8STR(back)
+ return back;
+}
+
diff --git a/support/dktools/dk3figto.h b/support/dktools/dk3figto.h
new file mode 100644
index 0000000000..9b794547f7
--- /dev/null
+++ b/support/dktools/dk3figto.h
@@ -0,0 +1,319 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3figto.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3figto.h Header file for the dk3figto module.
+*/
+
+#ifndef DK3FIGTO_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3FIGTO_H_INCLUDED 1
+
+
+#line 10 "dk3figto.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Check whether or not an object is a background rectangle.
+ A background rectangle is not drawn to output, it is only
+ used to calculate the bounding box of the drawing.
+ @param obj Object to check.
+ @param objno Object number in storage.
+ @return 1 for background rectangle, 0 for normal object.
+*/
+int
+dk3fig_tool_is_bgrect(dk3_fig_obj_t const *obj, unsigned long objno);
+
+/** Find line width for object.
+ @param drw Drawing to which the object belongs.
+ @param obj Object to find line width for.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Positive line width in Fig units on success, 0.0 on error.
+*/
+double
+dk3fig_tool_get_lw(
+ dk3_fig_drawing_t const *drw,
+ dk3_fig_obj_t const *obj,
+ int *ec
+);
+
+/** Get object line width in bp.
+ @param drw Drawing to which the object belongs.
+ @param obj Object to find line width for.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Positive line width in Fig units on success, 0.0 on error.
+*/
+double
+dk3fig_tool_get_lw_in_bp(
+ dk3_fig_drawing_t const *drw,
+ dk3_fig_obj_t const *obj,
+ int *ec
+);
+
+/** Calculate kappa value for arc.
+ To approximate arcs using Bezier spline segments we calculate
+ the control points as xcs = xstart + kappa * x'(0) and
+ xce = xend - kappa * x'(1). Using a kappa depending on the
+ angle alpha results in a better approximation than using the
+ fixed constant 1/3.
+ @param alpha Arc angle.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Non-negative value on success, -1.0 on error.
+*/
+double
+dk3fig_tool_arc_kappa(double alpha, int *ec);
+
+/** Find number of Bezier segments per X-spline segment.
+ @param drw Drawing.
+ @param primobj Flag: Primary object (1=object, 0=arrowhead).
+ @return Number of Bezier segments per X-spline segment.
+*/
+size_t
+dk3fig_tool_xssbs(dk3_fig_drawing_t *drw, int primobj);
+
+/** Calculate distance between two points.
+ @param p1 Point 1.
+ @param p2 Point 2.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Distance value.
+*/
+double
+dk3fig_tool_point_distance(
+ dk3_fig_poly_point_t const *p1,
+ dk3_fig_poly_point_t const *p2,
+ int *ec
+);
+
+/** Move polyline points to the left to skip first segment.
+ @param dst Destination pointer (address of element 0).
+ @param src Source pointer (address of element 1).
+ @param np Number of elements to shift.
+*/
+void
+dk3fig_tool_poly_point_move_left(
+ dk3_fig_poly_point_t *dst,
+ dk3_fig_poly_point_t *src,
+ size_t np
+);
+
+/** Shorten a line segment.
+ @param endpoint Endpoint of the polyline.
+ @param innerpoint Inner point of the polyline.
+ @param distance Distance to cut.
+ @param ec Pointer to error code variable, may be NULL.
+ @return 1 on success, 0 on error (point distance too short).
+*/
+int
+dk3fig_tool_cut_segment(
+ dk3_fig_poly_point_t *endpoint,
+ dk3_fig_poly_point_t const *innerpoint,
+ double distance,
+ int *ec
+);
+
+/** Find operations necessary to draw an object.
+ @param drw Drawing.
+ @param obj Object.
+ @return Drawing operations combination, see @ref dk3figoperations.
+*/
+int
+dk3fig_tool_get_operation(dk3_fig_drawing_t *drw, dk3_fig_obj_t *obj);
+
+/** Find RGB color (double values).
+ @param rgb Color structure to set up.
+ @param drw Drawing to find color for.
+ @param colno Color number.
+ @param fs Fill style.
+*/
+void
+dk3fig_tool_find_color(
+ dk3_rgb_color_t *rgb,
+ dk3_fig_drawing_t *drw,
+ int colno,
+ int fs
+);
+
+/** Find RGB color (int values).
+ @param dst Color structure to set up.
+ @param drw Drawing to find color for.
+ @param colno Color number.
+ @param fs Fill style.
+*/
+void
+dk3fig_tool_find_int_color(
+ dk3_fig_color_t *dst,
+ dk3_fig_drawing_t *drw,
+ int colno,
+ int fs
+);
+
+/** Rotate a point.
+ @param point Point to rotate.
+ @param angle Rotation angle in radians.
+ @param ec Pointer to error code variable, may be NULL.
+*/
+void
+dk3fig_tool_rotate_point(
+ dk3_fig_poly_point_t *point,
+ double angle,
+ int *ec
+);
+
+/** Rotate a spline point.
+ @param point Point to rotate.
+ @param angle Rotation angle in radians.
+ @param ec Pointer to error code variable, may be NULL.
+*/
+void
+dk3fig_tool_rotate_spoint(
+ dk3_fig_spline_point_t *point,
+ double angle,
+ int *ec
+);
+
+/** Shift a point.
+ @param point Point to shift.
+ @param x X shift.
+ @param y Y shift.
+ @param ec Pointer to error code variable, may be NULL.
+*/
+void
+dk3fig_tool_shift_point(
+ dk3_fig_poly_point_t *point,
+ double x,
+ double y,
+ int *ec
+);
+
+/** Shift a spline point.
+ @param point Point to shift.
+ @param x X shift.
+ @param y Y shift.
+ @param ec Pointer to error code variable, may be NULL.
+*/
+void
+dk3fig_tool_shift_spoint(
+ dk3_fig_spline_point_t *point,
+ double x,
+ double y,
+ int *ec
+);
+
+/** Compare two font structures.
+ Comparison by font number first, font size later.
+ @param l Left font structure.
+ @param r Right font structure.
+ @param cr Comparison criteria, ignored.
+ @return Comparison result.
+*/
+int
+dk3fig_tool_font_compare(void const *l, void const *r, int cr);
+
+/** Find PS font number for text object.
+ @param obj Text object.
+ @return Non-negative font number on success
+ (PS font suitable for this text object),
+ -1 on error (not a text object or hidden or special text).
+*/
+int
+dk3fig_tool_ps_font_number(dk3_fig_obj_t *obj);
+
+/** Check whether a new color must be set.
+ @param hc1 Flag: Old color configured.
+ @param r1 Old red.
+ @param g1 Old green.
+ @param b1 Old blue.
+ @param r2 New red.
+ @param g2 New green.
+ @param b2 New blue.
+ @return 1 if the color must be set, 0 otherwise.
+*/
+int
+dk3fig_tool_must_set_color(
+ int hc1,
+ double r1,
+ double g1,
+ double b1,
+ double r2,
+ double g2,
+ double b2
+);
+
+/** Check whether we must set up a new font.
+ @param hfn Flag: Have old font number and size.
+ @param ofn Old font number.
+ @param ofs Old font size.
+ @param nfn New font number.
+ @param nfs New font size.
+ @return 1 if we must install the new font, 0 otherwise.
+*/
+int
+dk3fig_tool_must_set_font(
+ int hfn,
+ int ofn,
+ double ofs,
+ int nfn,
+ double nfs
+);
+
+/** Obtain short output file name as 8-bit character string.
+ The result of this function is used as argument to an
+ includegraphics LaTeX instruction.
+ @param fullName Full name of output file.
+ @param app Application structure.
+ @return Pointer to 8-bit character string on success, NULL on error.
+*/
+char const *
+dk3fig_tool_short_output_file_name(
+ dkChar const *fullName,
+ dk3_app_t *app
+);
+
+/** Compare two text handling entries.
+ @param l Left pointer.
+ @param r Right pointer.
+ @param cr Comparison criteria.
+ @return Comparison result.
+*/
+int
+dk3fig_tool_text_handling_compare(void const *l, void const *r, int cr);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk3font.c b/support/dktools/dk3font.c
new file mode 100644
index 0000000000..2d7b952c9b
--- /dev/null
+++ b/support/dktools/dk3font.c
@@ -0,0 +1,979 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3font.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3font.c The dk3font module.
+*/
+
+
+#line 132 "dk3font.ctr"
+
+#include "dk3all.h"
+#include "dk3font.h"
+
+
+
+
+
+#line 139 "dk3font.ctr"
+
+
+
+/*
+ PLACES TO SEARCH FOR PFB FILES:
+ ===============================
+
+ Linux
+ -----
+ /usr/share/ghostscript/_version_/Resource/Font/_newname_
+ /usr/share/fonts/default/Type1/_oldname_.pfb
+
+ Windows
+ -------
+ _windowsdirectory_/Fonts
+ Ghostscript font directories
+*/
+
+
+
+/** Additional system font families usable as replacements.
+*/
+static char const * const dk3font_times_family_names[] = {
+/* 0 */
+"Times New Roman",
+
+/* 1 */
+"Bodoni MT",
+
+NULL
+
+
+#line 166 "dk3font.ctr"
+};
+
+
+
+/** Additional system font families usable as replacements.
+*/
+static char const * const dk3font_avantgarde_family_names[] = {
+/* 0 */
+"Trebuchet MS",
+
+/* 1 */
+"Verdana",
+
+NULL
+
+
+#line 177 "dk3font.ctr"
+};
+
+
+
+/** Additional system font families usable as replacements.
+*/
+static char const * const dk3font_bookman_light_family_names[] = {
+/* 0 */
+"Bookman Old Style",
+
+/* 1 */
+"Times New Roman",
+
+NULL
+
+
+#line 188 "dk3font.ctr"
+};
+
+
+
+/** Additional system font families usable as replacements.
+*/
+static char const * const dk3font_courier_family_names[] = {
+/* 0 */
+"Courier New",
+
+NULL
+
+
+#line 198 "dk3font.ctr"
+};
+
+
+
+/** Additional system font families usable as replacements.
+*/
+static char const * const dk3font_helvetica_family_names[] = {
+/* 0 */
+"Arial",
+
+/* 1 */
+"Gill Sans MT",
+
+/* 2 */
+"Lucida Sans",
+
+/* 3 */
+"Tahoma",
+
+NULL
+
+
+#line 211 "dk3font.ctr"
+};
+
+
+
+/** Additional system font families usable as replacements.
+*/
+static char const * const dk3font_helvetica_narrow_family_names[] = {
+/* 0 */
+"Arial Narrow",
+
+/* 1 */
+"Arial",
+
+NULL
+
+
+#line 222 "dk3font.ctr"
+};
+
+
+
+/** Additional system font families usable as replacements.
+*/
+static char const * const dk3font_ncschoolbook_family_names[] = {
+/* 0 */
+"Century Schoolbook",
+
+/* 1 */
+"Times New Roman",
+
+NULL
+
+
+#line 233 "dk3font.ctr"
+};
+
+
+
+/** Additional system font families usable as replacements.
+*/
+static char const * const dk3font_palatino_family_names[] = {
+/* 0 */
+"Palatino Linotype",
+
+/* 1 */
+"Times New Roman",
+
+NULL
+
+
+#line 244 "dk3font.ctr"
+};
+
+
+
+/** Additional system font families usable as replacements.
+*/
+static char const * const dk3font_symbol_family_names[] = {
+/* 0 */
+"Symbol",
+
+NULL
+
+
+#line 254 "dk3font.ctr"
+};
+
+
+
+/** Additional system font families usable as replacements.
+*/
+static char const * const dk3font_zapfchancery_family_names[] = {
+/* 0 */
+"Edwardian Script ITC",
+
+/* 1 */
+"Blackadder ITC",
+
+NULL
+
+
+#line 265 "dk3font.ctr"
+};
+
+
+
+/** Additional system font families usable as replacements.
+*/
+static char const * const dk3font_zapfdingbats_family_names[] = {
+/* 0 */
+"WingDings",
+
+NULL
+
+
+#line 275 "dk3font.ctr"
+};
+
+
+
+/** Font information.
+*/
+static dk3_font_t const dk3font_data[] = {
+ { /* 0 */
+ "Times-Roman",
+ "ptmr",
+ "ptm",
+ "NimbusRomNo9L-Regu",
+ "n021003l",
+ "NimbusRomNo9L-Regu",
+ "Times",
+ "Nimbus Roman No9 L",
+ "NimbusRomanNo9L-Regu",
+ dk3font_times_family_names,
+ DK3_FONT_ROMAN,
+ DK3_FONT_ROMAN,
+ 400
+ },
+ { /* 1 */
+ "Times-Italic",
+ "ptmri",
+ "ptm",
+ "NimbusRomNo9L-ReguItal",
+ "n021023l",
+ "NimbusRomNo9L-ReguItal",
+ "Times",
+ "Nimbus Roman No9 L",
+ "NimbusRomNo9L-ReguItal",
+ dk3font_times_family_names,
+ (DK3_FONT_ROMAN | DK3_FONT_ITALIC),
+ (DK3_FONT_ROMAN | DK3_FONT_ITALIC),
+ 400
+ },
+ { /* 2 */
+ "Times-Bold",
+ "ptmb",
+ "ptm",
+ "NimbusRomNo9L-Medi",
+ "n021004l",
+ "NimbusRomNo9L-Medi",
+ "Times",
+ "Nimbus Roman No9 L",
+ "NimbusRomNo9L-Medi",
+ dk3font_times_family_names,
+ (DK3_FONT_ROMAN | DK3_FONT_BOLD),
+ DK3_FONT_ROMAN,
+ 500
+ },
+ { /* 3 */
+ "Times-BoldItalic",
+ "ptmbi",
+ "ptm",
+ "NimbusRomNo9L-MediItal",
+ "n021024l",
+ "NimbusRomNo9L-MediItal",
+ "Times",
+ "Nimbus Roman No9 L",
+ "NimbusRomNo9L-MediItal",
+ dk3font_times_family_names,
+ (DK3_FONT_ROMAN | DK3_FONT_ITALIC | DK3_FONT_BOLD),
+ (DK3_FONT_ROMAN | DK3_FONT_ITALIC),
+ 500
+ },
+ { /* 4 */
+ "AvantGarde-Book",
+ "pagk",
+ "pag",
+ "URWGothicL-Book",
+ "a010013l",
+ "URWGothicL-Book",
+ "AvantGarde",
+ "URW Gothic L",
+ "URWGothicL-Book",
+ dk3font_avantgarde_family_names,
+ DK3_FONT_SANS_SERIF,
+ DK3_FONT_SANS_SERIF,
+ 400
+ },
+ { /* 5 */
+ "AvantGarde-BookOblique",
+ "pagko",
+ "pag",
+ "URWGothicL-BookObli",
+ "a010033l",
+ "URWGothicL-BookObli",
+ "AvantGarde",
+ "URW Gothic L",
+ "URWGothicL-BookObli",
+ dk3font_avantgarde_family_names,
+ (DK3_FONT_SANS_SERIF | DK3_FONT_ITALIC),
+ (DK3_FONT_SANS_SERIF | DK3_FONT_OBLIQUE),
+ 400
+ },
+ { /* 6 */
+ "AvantGarde-Demi",
+ "pagd",
+ "pag",
+ "URWGothicL-Demi",
+ "a010015l",
+ "URWGothicL-Demi",
+ "AvantGarde",
+ "URW Gothic L",
+ "URWGothicL-Demi",
+ dk3font_avantgarde_family_names,
+ (DK3_FONT_SANS_SERIF | DK3_FONT_BOLD),
+ DK3_FONT_SANS_SERIF,
+ 600
+ },
+ { /* 7 */
+ "AvantGarde-DemiOblique",
+ "pagdo",
+ "pag",
+ "URWGothicL-DemiObli",
+ "a010035l",
+ "URWGothicL-DemiObli",
+ "AvantGarde",
+ "URW Gothic L",
+ "URWGothicL-DemiObli",
+ dk3font_avantgarde_family_names,
+ (DK3_FONT_SANS_SERIF | DK3_FONT_ITALIC | DK3_FONT_BOLD),
+ (DK3_FONT_SANS_SERIF | DK3_FONT_OBLIQUE | DK3_FONT_BOLD),
+ 600
+ },
+ { /* 8 */
+ "Bookman-Light",
+ "pbkl",
+ "pbk",
+ "URWBookmanL-Ligh",
+ "b018012l",
+ "URWBookmanL-Ligh",
+ "Bookman",
+ "URW Bookman L",
+ "URWBookmanL-Ligh",
+ dk3font_bookman_light_family_names,
+ DK3_FONT_ROMAN,
+ DK3_FONT_ROMAN,
+ 400
+ },
+ { /* 9 */
+ "Bookman-LightItalic",
+ "pbkli",
+ "pbk",
+ "URWBookmanL-LighItal",
+ "b018032l",
+ "URWBookmanL-LighItal",
+ "Bookman",
+ "URW Bookman L",
+ "URWBookmanL-LighItal",
+ dk3font_bookman_light_family_names,
+ (DK3_FONT_ROMAN | DK3_FONT_ITALIC),
+ (DK3_FONT_ROMAN | DK3_FONT_ITALIC),
+ 400
+ },
+ { /* 10 */
+ "Bookman-Demi",
+ "pbkd",
+ "pbk",
+ "URWBookmanL-DemiBold", /* 2.2.22: URWBookmanL-Demi */
+ "b018015l",
+ "URWBookmanL-DemiBold",
+ "Bookman",
+ "URW Bookman L",
+ "URWBookmanL-DemiBold",
+ dk3font_bookman_light_family_names,
+ (DK3_FONT_ROMAN | DK3_FONT_BOLD),
+ DK3_FONT_ROMAN,
+ 600
+ },
+ { /* 11 */
+ "Bookman-DemiItalic",
+ "pbkdi",
+ "pbk",
+ "URWBookmanL-DemiBoldItal", /* 2.2.22: URWBookmanL-DemiItal */
+ "b018035l",
+ "URWBookmanL-DemiBoldItal",
+ "Bookman",
+ "URW Bookman L",
+ "URWBookmanL-DemiBoldItal",
+ dk3font_bookman_light_family_names,
+ (DK3_FONT_ROMAN | DK3_FONT_ITALIC | DK3_FONT_BOLD),
+ (DK3_FONT_ROMAN | DK3_FONT_ITALIC),
+ 600
+ },
+ { /* 12 */
+ "Courier",
+ "pcrr",
+ "pcr",
+ "NimbusMonL-Regu",
+ "n022003l",
+ "NimbusMonL-Regu",
+ "Courier",
+ "Nimbus Mono L",
+ "NimbusMonL-Regu",
+ dk3font_courier_family_names,
+ DK3_FONT_TYPEWRITER,
+ DK3_FONT_TYPEWRITER,
+ 400
+ },
+ { /* 13 */
+ "Courier-Oblique",
+ "pcrro",
+ "pcr",
+ "NimbusMonL-ReguObli",
+ "n022023l",
+ "NimbusMonL-ReguObli",
+ "Courier",
+ "Nimbus Mono L",
+ "NimbusMonL-ReguObli",
+ dk3font_courier_family_names,
+ (DK3_FONT_TYPEWRITER | DK3_FONT_ITALIC),
+ (DK3_FONT_TYPEWRITER | DK3_FONT_OBLIQUE),
+ 400
+ },
+ { /* 14 */
+ "Courier-Bold",
+ "pcrb",
+ "pcr",
+ "NimbusMonL-Bold",
+ "n022004l",
+ "NimbusMonL-Bold",
+ "Courier",
+ "Nimbus Mono L",
+ "NimbusMonL-Bold",
+ dk3font_courier_family_names,
+ (DK3_FONT_TYPEWRITER | DK3_FONT_BOLD),
+ DK3_FONT_TYPEWRITER,
+ 700
+ },
+ { /* 15 */
+ "Courier-BoldOblique",
+ "pcrbo",
+ "pcr",
+ "NimbusMonL-BoldObli",
+ "n022024l",
+ "NimbusMonL-BoldObli",
+ "Courier",
+ "Nimbus Mono L",
+ "NimbusMonL-BoldObli",
+ dk3font_courier_family_names,
+ (DK3_FONT_TYPEWRITER | DK3_FONT_ITALIC | DK3_FONT_BOLD),
+ (DK3_FONT_TYPEWRITER | DK3_FONT_OBLIQUE),
+ 700
+ },
+ { /* 16 */
+ "Helvetica",
+ "phvr",
+ "phv",
+ "NimbusSanL-Regu",
+ "n019003l",
+ "NimbusSanL-Regu",
+ "Helvetica",
+ "Nimbus Sans L",
+ "NimbusSansL-Regu",
+ dk3font_helvetica_family_names,
+ DK3_FONT_SANS_SERIF,
+ DK3_FONT_SANS_SERIF,
+ 400
+ },
+ { /* 17 */
+ "Helvetica-Oblique",
+ "phvro",
+ "phv",
+ "NimbusSanL-ReguItal",
+ "n019023l",
+ "NimbusSanL-ReguItal",
+ "Helvetica",
+ "Nimbus Sans L",
+ "NimbusSanL-ReguItal",
+ dk3font_helvetica_family_names,
+ (DK3_FONT_SANS_SERIF | DK3_FONT_OBLIQUE),
+ (DK3_FONT_SANS_SERIF | DK3_FONT_ITALIC),
+ 400
+ },
+ { /* 18 */
+ "Helvetica-Bold",
+ "phvb",
+ "phv",
+ "NimbusSanL-Bold",
+ "n019004l",
+ "NimbusSanL-Bold",
+ "Helvetica",
+ "Nimbus Sans L",
+ "NimbusSanL-Bold",
+ dk3font_helvetica_family_names,
+ (DK3_FONT_SANS_SERIF | DK3_FONT_BOLD),
+ DK3_FONT_SANS_SERIF,
+ 700
+ },
+ { /* 19 */
+ "Helvetica-BoldOblique",
+ "phvbo",
+ "phv",
+ "NimbusSanL-BoldItal",
+ "n019024l",
+ "NimbusSanL-BoldItal",
+ "Helvetica",
+ "Nimbus Sans L",
+ "NimbusSanL-BoldItal",
+ dk3font_helvetica_family_names,
+ (DK3_FONT_SANS_SERIF | DK3_FONT_OBLIQUE | DK3_FONT_BOLD),
+ (DK3_FONT_SANS_SERIF | DK3_FONT_ITALIC),
+ 700
+ },
+ { /* 20 */
+ "Helvetica-Narrow",
+ "phvrrn",
+ "phv",
+ "NimbusSanL-ReguCond",
+ "n019043l",
+ "NimbusSanL-ReguCond",
+ "Helvetica Narrow",
+ "Nimbus Sans L",
+ "NimbusSanL-ReguCond",
+ dk3font_helvetica_narrow_family_names,
+ DK3_FONT_SANS_SERIF,
+ DK3_FONT_SANS_SERIF,
+ 400
+ },
+ { /* 21 */
+ "Helvetica-Narrow-Oblique",
+ "phvron",
+ "phv",
+ "NimbusSanL-ReguCondItal",
+ "n019063l",
+ "NimbusSanL-ReguCondItal",
+ "Helvetica Narrow",
+ "Nimbus Sans L",
+ "NimbusSanL-ReguCondItal",
+ dk3font_helvetica_narrow_family_names,
+ (DK3_FONT_SANS_SERIF | DK3_FONT_OBLIQUE),
+ (DK3_FONT_SANS_SERIF | DK3_FONT_ITALIC),
+ 400
+ },
+ { /* 22 */
+ "Helvetica-Narrow-Bold",
+ "phvbrn",
+ "phv",
+ "NimbusSanL-BoldCond",
+ "n019044l",
+ "NimbusSanL-BoldCond",
+ "Helvetica Narrow",
+ "Nimbus Sans L",
+ "NimbusSanL-BoldCond",
+ dk3font_helvetica_narrow_family_names,
+ (DK3_FONT_SANS_SERIF | DK3_FONT_BOLD),
+ DK3_FONT_SANS_SERIF,
+ 700
+ },
+ { /* 23 */
+ "Helvetica-Narrow-BoldOblique",
+ "phvbon",
+ "phv",
+ "NimbusSanL-BoldCondItal",
+ "n019064l",
+ "NimbusSanL-BoldCondItal",
+ "Helvetica Narrow",
+ "Nimbus Sans L",
+ "NimbusSanL-BoldCondItal",
+ dk3font_helvetica_narrow_family_names,
+ (DK3_FONT_SANS_SERIF | DK3_FONT_OBLIQUE | DK3_FONT_BOLD),
+ (DK3_FONT_SANS_SERIF | DK3_FONT_ITALIC),
+ 700
+ },
+ { /* 24 */
+ "NewCenturySchlbk-Roman",
+ "pncr",
+ "pnc",
+ "CenturySchL-Roma",
+ "c059013l",
+ "CenturySchL-Roma",
+ "New Century Schoolbook",
+ "Century Schoolbook L",
+ "CenturySchL-Roma",
+ dk3font_ncschoolbook_family_names,
+ DK3_FONT_ROMAN,
+ DK3_FONT_ROMAN,
+ 400
+ },
+ { /* 25 */
+ "NewCenturySchlbk-Italic",
+ "pncri",
+ "pnc",
+ "CenturySchL-RomaItal",
+ "c059033l",
+ "CenturySchL-Ital",
+ "New Century Schoolbook",
+ "Century Schoolbook L",
+ "CenturySchL-Ital",
+ dk3font_ncschoolbook_family_names,
+ (DK3_FONT_ROMAN | DK3_FONT_ITALIC),
+ (DK3_FONT_ROMAN | DK3_FONT_ITALIC),
+ 400
+ },
+ { /* 26 */
+ "NewCenturySchlbk-Bold",
+ "pncb",
+ "pnc",
+ "CenturySchL-Bold",
+ "c059016l",
+ "CenturySchL-Bold",
+ "New Century Schoolbook",
+ "Century Schoolbook L",
+ "CenturySchL-Bold",
+ dk3font_ncschoolbook_family_names,
+ (DK3_FONT_ROMAN | DK3_FONT_BOLD),
+ DK3_FONT_ROMAN,
+ 700
+ },
+ { /* 27 */
+ "NewCenturySchlbk-BoldItalic",
+ "pncbi",
+ "pnc",
+ "CenturySchL-BoldItal",
+ "c059036l",
+ "CenturySchL-BoldItal",
+ "New Century Schoolbook",
+ "Century Schoolbook L",
+ "CenturySchL-BoldItal",
+ dk3font_ncschoolbook_family_names,
+ (DK3_FONT_ROMAN | DK3_FONT_ITALIC | DK3_FONT_BOLD),
+ (DK3_FONT_ROMAN | DK3_FONT_ITALIC),
+ 700
+ },
+ { /* 28 */
+ "Palatino-Roman",
+ "pplr",
+ "ppl",
+ "URWPalladioL-Roma",
+ "p052003l",
+ "URWPalladioL-Roma",
+ "Palatino",
+ "URW Palladio L",
+ "URWPalladioL-Roma",
+ dk3font_palatino_family_names,
+ DK3_FONT_ROMAN,
+ DK3_FONT_ROMAN,
+ 400
+ },
+ { /* 29 */
+ "Palatino-Italic",
+ "pplri",
+ "ppl",
+ "URWPalladioL-Ital",
+ "p052023l",
+ "URWPalladioL-Ital",
+ "Palatino",
+ "URW Palladio L",
+ "URWPalladioL-Ital",
+ dk3font_palatino_family_names,
+ (DK3_FONT_ROMAN | DK3_FONT_ITALIC),
+ (DK3_FONT_ROMAN | DK3_FONT_ITALIC),
+ 400
+ },
+ { /* 30 */
+ "Palatino-Bold",
+ "pplb",
+ "ppl",
+ "URWPalladioL-Bold",
+ "p052004l",
+ "URWPalladioL-Bold",
+ "Palatino",
+ "URW Palladio L",
+ "URWPalladioL-Bold",
+ dk3font_palatino_family_names,
+ (DK3_FONT_ROMAN | DK3_FONT_BOLD),
+ DK3_FONT_ROMAN,
+ 700
+ },
+ { /* 31 */
+ "Palatino-BoldItalic",
+ "pplbi",
+ "ppl",
+ "URWPalladioL-BoldItal",
+ "p052024l",
+ "URWPalladioL-BoldItal",
+ "Palatino",
+ "URW Palladio L",
+ "URWPalladioL-BoldItal",
+ dk3font_palatino_family_names,
+ (DK3_FONT_ROMAN | DK3_FONT_ITALIC | DK3_FONT_BOLD),
+ (DK3_FONT_ROMAN | DK3_FONT_ITALIC),
+ 700
+ },
+ { /* 32 */
+ "Symbol",
+ "psyr",
+ "psy",
+ "StandardSymL",
+ "s050000l",
+ "StandardSymL",
+ "Symbol",
+ "Standard Symbols L",
+ "StandardSymL",
+ dk3font_symbol_family_names,
+ 0,
+ 0,
+ 400
+ },
+ { /* 33 */
+ "ZapfChancery-MediumItalic",
+ "pzcmi",
+ "pzc",
+ "URWChanceryL-MediItal",
+ "z003034l",
+ "URWChanceryL-MediItal",
+ "Zapf Chancery",
+ "URW Chancery L",
+ "URWChanceryL-MediItal",
+ dk3font_zapfchancery_family_names,
+ (DK3_FONT_ROMAN | DK3_FONT_ITALIC),
+ (DK3_FONT_ROMAN | DK3_FONT_ITALIC),
+ 500
+ },
+ { /* 34 */
+ "ZapfDingbats",
+ "pzdr",
+ "pzd",
+ "Dingbats",
+ "d050000l",
+ "Dingbats",
+ "DingBats",
+ "Dingbats",
+ "Dingbats",
+ dk3font_zapfdingbats_family_names,
+ 0,
+ 0,
+ 400
+ }
+};
+
+
+
+/** Preference names to search for GhostScript font files.
+*/
+static dkChar const * const dk3font_base_pref_names[] = {
+dkT("/fonts/ghostscript/web"),
+dkT("/fonts/ghostscript/local"),
+NULL
+};
+
+
+
+char const *
+dk3font_get_ps_font_name(int fontno)
+{
+ char const *back = NULL;
+ if((fontno >= 0) && (fontno < 35)) {
+ back = dk3font_data[fontno].psFontName;
+ }
+ return back;
+}
+
+
+
+char const *
+dk3font_get_gs_font_name(int fontno)
+{
+ char const *back = NULL;
+ if((fontno >= 0) && (fontno < 35)) {
+ back = dk3font_data[fontno].gsFontName;
+ }
+ return back;
+}
+
+
+
+char const *
+dk3font_get_tex_font_name(int fontno)
+{
+ char const *back = NULL;
+ if((fontno >= 0) && (fontno < 35)) {
+ back = dk3font_data[fontno].texFontName;
+ }
+ return back;
+}
+
+
+
+char const *
+dk3font_get_tex_family_name(int fontno)
+{
+ char const *back = NULL;
+ if((fontno >= 0) && (fontno < 35)) {
+ back = dk3font_data[fontno].texFamilyName;
+ }
+ return back;
+}
+
+
+
+char const *
+dk3font_get_gs_old_file(int fontno)
+{
+ char const *back = NULL;
+ if((fontno >= 0) && (fontno < 35)) {
+ back = dk3font_data[fontno].gsFileOld;
+ }
+ return back;
+}
+
+
+
+char const *
+dk3font_get_gs_new_file(int fontno)
+{
+ char const *back = NULL;
+ if((fontno >= 0) && (fontno < 35)) {
+ back = dk3font_data[fontno].gsFileNew;
+ }
+ return back;
+}
+
+
+
+int
+dk3font_get_features(int fontno)
+{
+ int back = 0;
+ if((fontno >= 0) && (fontno < 35)) {
+ back = dk3font_data[fontno].features;
+ }
+ return back;
+}
+
+
+int
+dk3font_get_svg_features(int fontno)
+{
+ int back = 0;
+ if((fontno >= 0) && (fontno < 35)) {
+ back = dk3font_data[fontno].svgFeatures;
+ }
+ return back;
+}
+
+
+
+char const *
+dk3font_get_ps_family(int fontno)
+{
+ char const *back = NULL;
+ if((fontno >= 0) && (fontno < 35)) {
+ back = dk3font_data[fontno].psFamilyName;
+ }
+ return back;
+}
+
+
+
+char const *
+dk3font_get_svg_family(int fontno)
+{
+ char const *back = NULL;
+
+
+#line 933 "dk3font.ctr"
+ if((fontno >= 0) && (fontno < 35)) {
+ back = dk3font_data[fontno].svgFamilyName;
+ }
+
+#line 936 "dk3font.ctr"
+ return back;
+}
+
+
+
+char const *
+dk3font_get_svg_fontid(int fontno)
+{
+ char const *back = NULL;
+
+
+#line 946 "dk3font.ctr"
+ if((fontno >= 0) && (fontno < 35)) {
+ back = dk3font_data[fontno].svgFontId;
+ }
+
+#line 949 "dk3font.ctr"
+ return back;
+}
+
+
+
+int
+dk3font_get_svg_font_weight(int fontno)
+{
+ int back = 0;
+ if((fontno >= 0) && (fontno < 35)) {
+ back = dk3font_data[fontno].svgFontWeight;
+ }
+ return back;
+}
+
+
+
+int
+dk3font_gs_base_web(dk3_app_t *app, dkChar *buf, size_t bs)
+{
+ int back;
+ back = dk3app_get_dir_from_pref(app, dk3font_base_pref_names[0], buf, bs, 0);
+ return back;
+}
+
+
+
+int
+dk3font_gs_base_local(dk3_app_t *app, dkChar *buf, size_t bs)
+{
+ int back;
+ back = dk3app_get_dir_from_pref(app, dk3font_base_pref_names[1], buf, bs, 1);
+ return back;
+}
+
+
+
+char const * const *
+dk3font_get_replacement_families(int fontno)
+{
+ char const * const *back = NULL;
+ if((0 <= fontno) && (fontno < 35)) {
+ back = dk3font_data[fontno].replacements;
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk3font.ctr b/support/dktools/dk3font.ctr
new file mode 100644
index 0000000000..d0544037df
--- /dev/null
+++ b/support/dktools/dk3font.ctr
@@ -0,0 +1,996 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve PS font name for font without leading slash.
+ @param fontno Font number.
+ @return Pointer to name on success, NULL on error.
+*/
+char const *
+dk3font_get_ps_font_name(int fontno);
+
+/** Retrieve GS font name for font.
+ @param fontno Font number.
+ @return Pointer to name on success, NULL on error.
+*/
+char const *
+dk3font_get_gs_font_name(int fontno);
+
+/** Retrieve TeX/LaTeX font name.
+ @param fontno Font number.
+ @return Pointer to name on success, NULL on error.
+*/
+char const *
+dk3font_get_tex_font_name(int fontno);
+
+/** Get TeX/LaTeX font family name.
+ @param fontno Font number.
+ @return Pointer to family name on success, NULL on error.
+*/
+char const *
+dk3font_get_tex_family_name(int fontno);
+
+/** Get old GS font file name without leading path and without suffix.
+ Typically you need to append ".pfb".
+ @param fontno Font number.
+ @return Pointer to name on success, NULL on error.
+*/
+char const *
+dk3font_get_gs_old_file(int fontno);
+
+/** Get new GS font file name without leading path and without suffix.
+ @param fontno Font number.
+ @return Pointer to name on success, NULL on error.
+*/
+char const *
+dk3font_get_gs_new_file(int fontno);
+
+/** Retrieve font feature set.
+ @param fontno Font number.
+ @return Font feature set.
+*/
+int
+dk3font_get_features(int fontno);
+
+/** Retrieve SVG font feature set.
+ @param fontno Font number.
+ @return Font feature set.
+*/
+int
+dk3font_get_svg_features(int fontno);
+
+/** Retrieve PS font family name.
+ @param fontno Font number.
+ @return Family name on success, NULL on error.
+*/
+char const *
+dk3font_get_ps_family(int fontno);
+
+/** Retrieve list of replacement family names.
+ @param fontno Font number.
+ @return NULL-terminated array of names.
+*/
+char const * const *
+dk3font_get_replacement_families(int fontno);
+
+/** Retrieve SVG font family name.
+ @param fontno Font number.
+ @return Family name on success, NULL on error.
+*/
+char const *
+dk3font_get_svg_family(int fontno);
+
+/** Retrieve SVG font ID.
+ @param fontno Font number.
+ @return Font ID on success, NULL on error.
+*/
+char const *
+dk3font_get_svg_fontid(int fontno);
+
+/** Retrieve SVG font weight.
+ @param fontno Font number.
+ @return The weight as numeric value.
+*/
+int
+dk3font_get_svg_font_weight(int fontno);
+
+/** Find font base URI.
+ @param app Application structure.
+ @param buf Destination buffer.
+ @param bs Size of @arg buf (number of dkChar).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3font_gs_base_web(dk3_app_t *app, dkChar *buf, size_t bs);
+
+/** Find local font base directory.
+ @param app Application structure.
+ @param buf Destination buffer.
+ @param bs Size of @arg buf (number of dkChar).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3font_gs_base_local(dk3_app_t *app, dkChar *buf, size_t bs);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk3all.h"
+#include "dk3font.h"
+
+
+
+$!trace-include
+
+
+
+/*
+ PLACES TO SEARCH FOR PFB FILES:
+ ===============================
+
+ Linux
+ -----
+ /usr/share/ghostscript/_version_/Resource/Font/_newname_
+ /usr/share/fonts/default/Type1/_oldname_.pfb
+
+ Windows
+ -------
+ _windowsdirectory_/Fonts
+ Ghostscript font directories
+*/
+
+
+
+/** Additional system font families usable as replacements.
+*/
+static char const * const dk3font_times_family_names[] = {
+$!string-table
+Times New Roman
+Bodoni MT
+$!end
+};
+
+
+
+/** Additional system font families usable as replacements.
+*/
+static char const * const dk3font_avantgarde_family_names[] = {
+$!string-table
+Trebuchet MS
+Verdana
+$!end
+};
+
+
+
+/** Additional system font families usable as replacements.
+*/
+static char const * const dk3font_bookman_light_family_names[] = {
+$!string-table
+Bookman Old Style
+Times New Roman
+$!end
+};
+
+
+
+/** Additional system font families usable as replacements.
+*/
+static char const * const dk3font_courier_family_names[] = {
+$!string-table
+Courier New
+$!end
+};
+
+
+
+/** Additional system font families usable as replacements.
+*/
+static char const * const dk3font_helvetica_family_names[] = {
+$!string-table
+Arial
+Gill Sans MT
+Lucida Sans
+Tahoma
+$!end
+};
+
+
+
+/** Additional system font families usable as replacements.
+*/
+static char const * const dk3font_helvetica_narrow_family_names[] = {
+$!string-table
+Arial Narrow
+Arial
+$!end
+};
+
+
+
+/** Additional system font families usable as replacements.
+*/
+static char const * const dk3font_ncschoolbook_family_names[] = {
+$!string-table
+Century Schoolbook
+Times New Roman
+$!end
+};
+
+
+
+/** Additional system font families usable as replacements.
+*/
+static char const * const dk3font_palatino_family_names[] = {
+$!string-table
+Palatino Linotype
+Times New Roman
+$!end
+};
+
+
+
+/** Additional system font families usable as replacements.
+*/
+static char const * const dk3font_symbol_family_names[] = {
+$!string-table
+Symbol
+$!end
+};
+
+
+
+/** Additional system font families usable as replacements.
+*/
+static char const * const dk3font_zapfchancery_family_names[] = {
+$!string-table
+Edwardian Script ITC
+Blackadder ITC
+$!end
+};
+
+
+
+/** Additional system font families usable as replacements.
+*/
+static char const * const dk3font_zapfdingbats_family_names[] = {
+$!string-table
+WingDings
+$!end
+};
+
+
+
+/** Font information.
+*/
+static dk3_font_t const dk3font_data[] = {
+ { /* 0 */
+ "Times-Roman",
+ "ptmr",
+ "ptm",
+ "NimbusRomNo9L-Regu",
+ "n021003l",
+ "NimbusRomNo9L-Regu",
+ "Times",
+ "Nimbus Roman No9 L",
+ "NimbusRomanNo9L-Regu",
+ dk3font_times_family_names,
+ DK3_FONT_ROMAN,
+ DK3_FONT_ROMAN,
+ 400
+ },
+ { /* 1 */
+ "Times-Italic",
+ "ptmri",
+ "ptm",
+ "NimbusRomNo9L-ReguItal",
+ "n021023l",
+ "NimbusRomNo9L-ReguItal",
+ "Times",
+ "Nimbus Roman No9 L",
+ "NimbusRomNo9L-ReguItal",
+ dk3font_times_family_names,
+ (DK3_FONT_ROMAN | DK3_FONT_ITALIC),
+ (DK3_FONT_ROMAN | DK3_FONT_ITALIC),
+ 400
+ },
+ { /* 2 */
+ "Times-Bold",
+ "ptmb",
+ "ptm",
+ "NimbusRomNo9L-Medi",
+ "n021004l",
+ "NimbusRomNo9L-Medi",
+ "Times",
+ "Nimbus Roman No9 L",
+ "NimbusRomNo9L-Medi",
+ dk3font_times_family_names,
+ (DK3_FONT_ROMAN | DK3_FONT_BOLD),
+ DK3_FONT_ROMAN,
+ 500
+ },
+ { /* 3 */
+ "Times-BoldItalic",
+ "ptmbi",
+ "ptm",
+ "NimbusRomNo9L-MediItal",
+ "n021024l",
+ "NimbusRomNo9L-MediItal",
+ "Times",
+ "Nimbus Roman No9 L",
+ "NimbusRomNo9L-MediItal",
+ dk3font_times_family_names,
+ (DK3_FONT_ROMAN | DK3_FONT_ITALIC | DK3_FONT_BOLD),
+ (DK3_FONT_ROMAN | DK3_FONT_ITALIC),
+ 500
+ },
+ { /* 4 */
+ "AvantGarde-Book",
+ "pagk",
+ "pag",
+ "URWGothicL-Book",
+ "a010013l",
+ "URWGothicL-Book",
+ "AvantGarde",
+ "URW Gothic L",
+ "URWGothicL-Book",
+ dk3font_avantgarde_family_names,
+ DK3_FONT_SANS_SERIF,
+ DK3_FONT_SANS_SERIF,
+ 400
+ },
+ { /* 5 */
+ "AvantGarde-BookOblique",
+ "pagko",
+ "pag",
+ "URWGothicL-BookObli",
+ "a010033l",
+ "URWGothicL-BookObli",
+ "AvantGarde",
+ "URW Gothic L",
+ "URWGothicL-BookObli",
+ dk3font_avantgarde_family_names,
+ (DK3_FONT_SANS_SERIF | DK3_FONT_ITALIC),
+ (DK3_FONT_SANS_SERIF | DK3_FONT_OBLIQUE),
+ 400
+ },
+ { /* 6 */
+ "AvantGarde-Demi",
+ "pagd",
+ "pag",
+ "URWGothicL-Demi",
+ "a010015l",
+ "URWGothicL-Demi",
+ "AvantGarde",
+ "URW Gothic L",
+ "URWGothicL-Demi",
+ dk3font_avantgarde_family_names,
+ (DK3_FONT_SANS_SERIF | DK3_FONT_BOLD),
+ DK3_FONT_SANS_SERIF,
+ 600
+ },
+ { /* 7 */
+ "AvantGarde-DemiOblique",
+ "pagdo",
+ "pag",
+ "URWGothicL-DemiObli",
+ "a010035l",
+ "URWGothicL-DemiObli",
+ "AvantGarde",
+ "URW Gothic L",
+ "URWGothicL-DemiObli",
+ dk3font_avantgarde_family_names,
+ (DK3_FONT_SANS_SERIF | DK3_FONT_ITALIC | DK3_FONT_BOLD),
+ (DK3_FONT_SANS_SERIF | DK3_FONT_OBLIQUE | DK3_FONT_BOLD),
+ 600
+ },
+ { /* 8 */
+ "Bookman-Light",
+ "pbkl",
+ "pbk",
+ "URWBookmanL-Ligh",
+ "b018012l",
+ "URWBookmanL-Ligh",
+ "Bookman",
+ "URW Bookman L",
+ "URWBookmanL-Ligh",
+ dk3font_bookman_light_family_names,
+ DK3_FONT_ROMAN,
+ DK3_FONT_ROMAN,
+ 400
+ },
+ { /* 9 */
+ "Bookman-LightItalic",
+ "pbkli",
+ "pbk",
+ "URWBookmanL-LighItal",
+ "b018032l",
+ "URWBookmanL-LighItal",
+ "Bookman",
+ "URW Bookman L",
+ "URWBookmanL-LighItal",
+ dk3font_bookman_light_family_names,
+ (DK3_FONT_ROMAN | DK3_FONT_ITALIC),
+ (DK3_FONT_ROMAN | DK3_FONT_ITALIC),
+ 400
+ },
+ { /* 10 */
+ "Bookman-Demi",
+ "pbkd",
+ "pbk",
+ "URWBookmanL-DemiBold", /* 2.2.22: URWBookmanL-Demi */
+ "b018015l",
+ "URWBookmanL-DemiBold",
+ "Bookman",
+ "URW Bookman L",
+ "URWBookmanL-DemiBold",
+ dk3font_bookman_light_family_names,
+ (DK3_FONT_ROMAN | DK3_FONT_BOLD),
+ DK3_FONT_ROMAN,
+ 600
+ },
+ { /* 11 */
+ "Bookman-DemiItalic",
+ "pbkdi",
+ "pbk",
+ "URWBookmanL-DemiBoldItal", /* 2.2.22: URWBookmanL-DemiItal */
+ "b018035l",
+ "URWBookmanL-DemiBoldItal",
+ "Bookman",
+ "URW Bookman L",
+ "URWBookmanL-DemiBoldItal",
+ dk3font_bookman_light_family_names,
+ (DK3_FONT_ROMAN | DK3_FONT_ITALIC | DK3_FONT_BOLD),
+ (DK3_FONT_ROMAN | DK3_FONT_ITALIC),
+ 600
+ },
+ { /* 12 */
+ "Courier",
+ "pcrr",
+ "pcr",
+ "NimbusMonL-Regu",
+ "n022003l",
+ "NimbusMonL-Regu",
+ "Courier",
+ "Nimbus Mono L",
+ "NimbusMonL-Regu",
+ dk3font_courier_family_names,
+ DK3_FONT_TYPEWRITER,
+ DK3_FONT_TYPEWRITER,
+ 400
+ },
+ { /* 13 */
+ "Courier-Oblique",
+ "pcrro",
+ "pcr",
+ "NimbusMonL-ReguObli",
+ "n022023l",
+ "NimbusMonL-ReguObli",
+ "Courier",
+ "Nimbus Mono L",
+ "NimbusMonL-ReguObli",
+ dk3font_courier_family_names,
+ (DK3_FONT_TYPEWRITER | DK3_FONT_ITALIC),
+ (DK3_FONT_TYPEWRITER | DK3_FONT_OBLIQUE),
+ 400
+ },
+ { /* 14 */
+ "Courier-Bold",
+ "pcrb",
+ "pcr",
+ "NimbusMonL-Bold",
+ "n022004l",
+ "NimbusMonL-Bold",
+ "Courier",
+ "Nimbus Mono L",
+ "NimbusMonL-Bold",
+ dk3font_courier_family_names,
+ (DK3_FONT_TYPEWRITER | DK3_FONT_BOLD),
+ DK3_FONT_TYPEWRITER,
+ 700
+ },
+ { /* 15 */
+ "Courier-BoldOblique",
+ "pcrbo",
+ "pcr",
+ "NimbusMonL-BoldObli",
+ "n022024l",
+ "NimbusMonL-BoldObli",
+ "Courier",
+ "Nimbus Mono L",
+ "NimbusMonL-BoldObli",
+ dk3font_courier_family_names,
+ (DK3_FONT_TYPEWRITER | DK3_FONT_ITALIC | DK3_FONT_BOLD),
+ (DK3_FONT_TYPEWRITER | DK3_FONT_OBLIQUE),
+ 700
+ },
+ { /* 16 */
+ "Helvetica",
+ "phvr",
+ "phv",
+ "NimbusSanL-Regu",
+ "n019003l",
+ "NimbusSanL-Regu",
+ "Helvetica",
+ "Nimbus Sans L",
+ "NimbusSansL-Regu",
+ dk3font_helvetica_family_names,
+ DK3_FONT_SANS_SERIF,
+ DK3_FONT_SANS_SERIF,
+ 400
+ },
+ { /* 17 */
+ "Helvetica-Oblique",
+ "phvro",
+ "phv",
+ "NimbusSanL-ReguItal",
+ "n019023l",
+ "NimbusSanL-ReguItal",
+ "Helvetica",
+ "Nimbus Sans L",
+ "NimbusSanL-ReguItal",
+ dk3font_helvetica_family_names,
+ (DK3_FONT_SANS_SERIF | DK3_FONT_OBLIQUE),
+ (DK3_FONT_SANS_SERIF | DK3_FONT_ITALIC),
+ 400
+ },
+ { /* 18 */
+ "Helvetica-Bold",
+ "phvb",
+ "phv",
+ "NimbusSanL-Bold",
+ "n019004l",
+ "NimbusSanL-Bold",
+ "Helvetica",
+ "Nimbus Sans L",
+ "NimbusSanL-Bold",
+ dk3font_helvetica_family_names,
+ (DK3_FONT_SANS_SERIF | DK3_FONT_BOLD),
+ DK3_FONT_SANS_SERIF,
+ 700
+ },
+ { /* 19 */
+ "Helvetica-BoldOblique",
+ "phvbo",
+ "phv",
+ "NimbusSanL-BoldItal",
+ "n019024l",
+ "NimbusSanL-BoldItal",
+ "Helvetica",
+ "Nimbus Sans L",
+ "NimbusSanL-BoldItal",
+ dk3font_helvetica_family_names,
+ (DK3_FONT_SANS_SERIF | DK3_FONT_OBLIQUE | DK3_FONT_BOLD),
+ (DK3_FONT_SANS_SERIF | DK3_FONT_ITALIC),
+ 700
+ },
+ { /* 20 */
+ "Helvetica-Narrow",
+ "phvrrn",
+ "phv",
+ "NimbusSanL-ReguCond",
+ "n019043l",
+ "NimbusSanL-ReguCond",
+ "Helvetica Narrow",
+ "Nimbus Sans L",
+ "NimbusSanL-ReguCond",
+ dk3font_helvetica_narrow_family_names,
+ DK3_FONT_SANS_SERIF,
+ DK3_FONT_SANS_SERIF,
+ 400
+ },
+ { /* 21 */
+ "Helvetica-Narrow-Oblique",
+ "phvron",
+ "phv",
+ "NimbusSanL-ReguCondItal",
+ "n019063l",
+ "NimbusSanL-ReguCondItal",
+ "Helvetica Narrow",
+ "Nimbus Sans L",
+ "NimbusSanL-ReguCondItal",
+ dk3font_helvetica_narrow_family_names,
+ (DK3_FONT_SANS_SERIF | DK3_FONT_OBLIQUE),
+ (DK3_FONT_SANS_SERIF | DK3_FONT_ITALIC),
+ 400
+ },
+ { /* 22 */
+ "Helvetica-Narrow-Bold",
+ "phvbrn",
+ "phv",
+ "NimbusSanL-BoldCond",
+ "n019044l",
+ "NimbusSanL-BoldCond",
+ "Helvetica Narrow",
+ "Nimbus Sans L",
+ "NimbusSanL-BoldCond",
+ dk3font_helvetica_narrow_family_names,
+ (DK3_FONT_SANS_SERIF | DK3_FONT_BOLD),
+ DK3_FONT_SANS_SERIF,
+ 700
+ },
+ { /* 23 */
+ "Helvetica-Narrow-BoldOblique",
+ "phvbon",
+ "phv",
+ "NimbusSanL-BoldCondItal",
+ "n019064l",
+ "NimbusSanL-BoldCondItal",
+ "Helvetica Narrow",
+ "Nimbus Sans L",
+ "NimbusSanL-BoldCondItal",
+ dk3font_helvetica_narrow_family_names,
+ (DK3_FONT_SANS_SERIF | DK3_FONT_OBLIQUE | DK3_FONT_BOLD),
+ (DK3_FONT_SANS_SERIF | DK3_FONT_ITALIC),
+ 700
+ },
+ { /* 24 */
+ "NewCenturySchlbk-Roman",
+ "pncr",
+ "pnc",
+ "CenturySchL-Roma",
+ "c059013l",
+ "CenturySchL-Roma",
+ "New Century Schoolbook",
+ "Century Schoolbook L",
+ "CenturySchL-Roma",
+ dk3font_ncschoolbook_family_names,
+ DK3_FONT_ROMAN,
+ DK3_FONT_ROMAN,
+ 400
+ },
+ { /* 25 */
+ "NewCenturySchlbk-Italic",
+ "pncri",
+ "pnc",
+ "CenturySchL-RomaItal",
+ "c059033l",
+ "CenturySchL-Ital",
+ "New Century Schoolbook",
+ "Century Schoolbook L",
+ "CenturySchL-Ital",
+ dk3font_ncschoolbook_family_names,
+ (DK3_FONT_ROMAN | DK3_FONT_ITALIC),
+ (DK3_FONT_ROMAN | DK3_FONT_ITALIC),
+ 400
+ },
+ { /* 26 */
+ "NewCenturySchlbk-Bold",
+ "pncb",
+ "pnc",
+ "CenturySchL-Bold",
+ "c059016l",
+ "CenturySchL-Bold",
+ "New Century Schoolbook",
+ "Century Schoolbook L",
+ "CenturySchL-Bold",
+ dk3font_ncschoolbook_family_names,
+ (DK3_FONT_ROMAN | DK3_FONT_BOLD),
+ DK3_FONT_ROMAN,
+ 700
+ },
+ { /* 27 */
+ "NewCenturySchlbk-BoldItalic",
+ "pncbi",
+ "pnc",
+ "CenturySchL-BoldItal",
+ "c059036l",
+ "CenturySchL-BoldItal",
+ "New Century Schoolbook",
+ "Century Schoolbook L",
+ "CenturySchL-BoldItal",
+ dk3font_ncschoolbook_family_names,
+ (DK3_FONT_ROMAN | DK3_FONT_ITALIC | DK3_FONT_BOLD),
+ (DK3_FONT_ROMAN | DK3_FONT_ITALIC),
+ 700
+ },
+ { /* 28 */
+ "Palatino-Roman",
+ "pplr",
+ "ppl",
+ "URWPalladioL-Roma",
+ "p052003l",
+ "URWPalladioL-Roma",
+ "Palatino",
+ "URW Palladio L",
+ "URWPalladioL-Roma",
+ dk3font_palatino_family_names,
+ DK3_FONT_ROMAN,
+ DK3_FONT_ROMAN,
+ 400
+ },
+ { /* 29 */
+ "Palatino-Italic",
+ "pplri",
+ "ppl",
+ "URWPalladioL-Ital",
+ "p052023l",
+ "URWPalladioL-Ital",
+ "Palatino",
+ "URW Palladio L",
+ "URWPalladioL-Ital",
+ dk3font_palatino_family_names,
+ (DK3_FONT_ROMAN | DK3_FONT_ITALIC),
+ (DK3_FONT_ROMAN | DK3_FONT_ITALIC),
+ 400
+ },
+ { /* 30 */
+ "Palatino-Bold",
+ "pplb",
+ "ppl",
+ "URWPalladioL-Bold",
+ "p052004l",
+ "URWPalladioL-Bold",
+ "Palatino",
+ "URW Palladio L",
+ "URWPalladioL-Bold",
+ dk3font_palatino_family_names,
+ (DK3_FONT_ROMAN | DK3_FONT_BOLD),
+ DK3_FONT_ROMAN,
+ 700
+ },
+ { /* 31 */
+ "Palatino-BoldItalic",
+ "pplbi",
+ "ppl",
+ "URWPalladioL-BoldItal",
+ "p052024l",
+ "URWPalladioL-BoldItal",
+ "Palatino",
+ "URW Palladio L",
+ "URWPalladioL-BoldItal",
+ dk3font_palatino_family_names,
+ (DK3_FONT_ROMAN | DK3_FONT_ITALIC | DK3_FONT_BOLD),
+ (DK3_FONT_ROMAN | DK3_FONT_ITALIC),
+ 700
+ },
+ { /* 32 */
+ "Symbol",
+ "psyr",
+ "psy",
+ "StandardSymL",
+ "s050000l",
+ "StandardSymL",
+ "Symbol",
+ "Standard Symbols L",
+ "StandardSymL",
+ dk3font_symbol_family_names,
+ 0,
+ 0,
+ 400
+ },
+ { /* 33 */
+ "ZapfChancery-MediumItalic",
+ "pzcmi",
+ "pzc",
+ "URWChanceryL-MediItal",
+ "z003034l",
+ "URWChanceryL-MediItal",
+ "Zapf Chancery",
+ "URW Chancery L",
+ "URWChanceryL-MediItal",
+ dk3font_zapfchancery_family_names,
+ (DK3_FONT_ROMAN | DK3_FONT_ITALIC),
+ (DK3_FONT_ROMAN | DK3_FONT_ITALIC),
+ 500
+ },
+ { /* 34 */
+ "ZapfDingbats",
+ "pzdr",
+ "pzd",
+ "Dingbats",
+ "d050000l",
+ "Dingbats",
+ "DingBats",
+ "Dingbats",
+ "Dingbats",
+ dk3font_zapfdingbats_family_names,
+ 0,
+ 0,
+ 400
+ }
+};
+
+
+
+/** Preference names to search for GhostScript font files.
+*/
+static dkChar const * const dk3font_base_pref_names[] = {
+dkT("/fonts/ghostscript/web"),
+dkT("/fonts/ghostscript/local"),
+NULL
+};
+
+
+
+char const *
+dk3font_get_ps_font_name(int fontno)
+{
+ char const *back = NULL;
+ if((fontno >= 0) && (fontno < 35)) {
+ back = dk3font_data[fontno].psFontName;
+ }
+ return back;
+}
+
+
+
+char const *
+dk3font_get_gs_font_name(int fontno)
+{
+ char const *back = NULL;
+ if((fontno >= 0) && (fontno < 35)) {
+ back = dk3font_data[fontno].gsFontName;
+ }
+ return back;
+}
+
+
+
+char const *
+dk3font_get_tex_font_name(int fontno)
+{
+ char const *back = NULL;
+ if((fontno >= 0) && (fontno < 35)) {
+ back = dk3font_data[fontno].texFontName;
+ }
+ return back;
+}
+
+
+
+char const *
+dk3font_get_tex_family_name(int fontno)
+{
+ char const *back = NULL;
+ if((fontno >= 0) && (fontno < 35)) {
+ back = dk3font_data[fontno].texFamilyName;
+ }
+ return back;
+}
+
+
+
+char const *
+dk3font_get_gs_old_file(int fontno)
+{
+ char const *back = NULL;
+ if((fontno >= 0) && (fontno < 35)) {
+ back = dk3font_data[fontno].gsFileOld;
+ }
+ return back;
+}
+
+
+
+char const *
+dk3font_get_gs_new_file(int fontno)
+{
+ char const *back = NULL;
+ if((fontno >= 0) && (fontno < 35)) {
+ back = dk3font_data[fontno].gsFileNew;
+ }
+ return back;
+}
+
+
+
+int
+dk3font_get_features(int fontno)
+{
+ int back = 0;
+ if((fontno >= 0) && (fontno < 35)) {
+ back = dk3font_data[fontno].features;
+ }
+ return back;
+}
+
+
+int
+dk3font_get_svg_features(int fontno)
+{
+ int back = 0;
+ if((fontno >= 0) && (fontno < 35)) {
+ back = dk3font_data[fontno].svgFeatures;
+ }
+ return back;
+}
+
+
+
+char const *
+dk3font_get_ps_family(int fontno)
+{
+ char const *back = NULL;
+ if((fontno >= 0) && (fontno < 35)) {
+ back = dk3font_data[fontno].psFamilyName;
+ }
+ return back;
+}
+
+
+
+char const *
+dk3font_get_svg_family(int fontno)
+{
+ char const *back = NULL;
+ $? "+ dk3font_get_svg_family"
+ if((fontno >= 0) && (fontno < 35)) {
+ back = dk3font_data[fontno].svgFamilyName;
+ } $? "- dk3font_get_svg_family %!8s", TR_8STR(back)
+ return back;
+}
+
+
+
+char const *
+dk3font_get_svg_fontid(int fontno)
+{
+ char const *back = NULL;
+ $? "+ dk3font_get_svg_fontid"
+ if((fontno >= 0) && (fontno < 35)) {
+ back = dk3font_data[fontno].svgFontId;
+ } $? "- dk3font_get_svg_fontid %!8s", TR_8STR(back)
+ return back;
+}
+
+
+
+int
+dk3font_get_svg_font_weight(int fontno)
+{
+ int back = 0;
+ if((fontno >= 0) && (fontno < 35)) {
+ back = dk3font_data[fontno].svgFontWeight;
+ }
+ return back;
+}
+
+
+
+int
+dk3font_gs_base_web(dk3_app_t *app, dkChar *buf, size_t bs)
+{
+ int back;
+ back = dk3app_get_dir_from_pref(app, dk3font_base_pref_names[0], buf, bs, 0);
+ return back;
+}
+
+
+
+int
+dk3font_gs_base_local(dk3_app_t *app, dkChar *buf, size_t bs)
+{
+ int back;
+ back = dk3app_get_dir_from_pref(app, dk3font_base_pref_names[1], buf, bs, 1);
+ return back;
+}
+
+
+
+char const * const *
+dk3font_get_replacement_families(int fontno)
+{
+ char const * const *back = NULL;
+ if((0 <= fontno) && (fontno < 35)) {
+ back = dk3font_data[fontno].replacements;
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk3font.h b/support/dktools/dk3font.h
new file mode 100644
index 0000000000..046ac94795
--- /dev/null
+++ b/support/dktools/dk3font.h
@@ -0,0 +1,167 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3font.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3font.h Header file for the dk3font module.
+*/
+
+#ifndef DK3FONT_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3FONT_H_INCLUDED 1
+
+
+#line 10 "dk3font.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve PS font name for font without leading slash.
+ @param fontno Font number.
+ @return Pointer to name on success, NULL on error.
+*/
+char const *
+dk3font_get_ps_font_name(int fontno);
+
+/** Retrieve GS font name for font.
+ @param fontno Font number.
+ @return Pointer to name on success, NULL on error.
+*/
+char const *
+dk3font_get_gs_font_name(int fontno);
+
+/** Retrieve TeX/LaTeX font name.
+ @param fontno Font number.
+ @return Pointer to name on success, NULL on error.
+*/
+char const *
+dk3font_get_tex_font_name(int fontno);
+
+/** Get TeX/LaTeX font family name.
+ @param fontno Font number.
+ @return Pointer to family name on success, NULL on error.
+*/
+char const *
+dk3font_get_tex_family_name(int fontno);
+
+/** Get old GS font file name without leading path and without suffix.
+ Typically you need to append ".pfb".
+ @param fontno Font number.
+ @return Pointer to name on success, NULL on error.
+*/
+char const *
+dk3font_get_gs_old_file(int fontno);
+
+/** Get new GS font file name without leading path and without suffix.
+ @param fontno Font number.
+ @return Pointer to name on success, NULL on error.
+*/
+char const *
+dk3font_get_gs_new_file(int fontno);
+
+/** Retrieve font feature set.
+ @param fontno Font number.
+ @return Font feature set.
+*/
+int
+dk3font_get_features(int fontno);
+
+/** Retrieve SVG font feature set.
+ @param fontno Font number.
+ @return Font feature set.
+*/
+int
+dk3font_get_svg_features(int fontno);
+
+/** Retrieve PS font family name.
+ @param fontno Font number.
+ @return Family name on success, NULL on error.
+*/
+char const *
+dk3font_get_ps_family(int fontno);
+
+/** Retrieve list of replacement family names.
+ @param fontno Font number.
+ @return NULL-terminated array of names.
+*/
+char const * const *
+dk3font_get_replacement_families(int fontno);
+
+/** Retrieve SVG font family name.
+ @param fontno Font number.
+ @return Family name on success, NULL on error.
+*/
+char const *
+dk3font_get_svg_family(int fontno);
+
+/** Retrieve SVG font ID.
+ @param fontno Font number.
+ @return Font ID on success, NULL on error.
+*/
+char const *
+dk3font_get_svg_fontid(int fontno);
+
+/** Retrieve SVG font weight.
+ @param fontno Font number.
+ @return The weight as numeric value.
+*/
+int
+dk3font_get_svg_font_weight(int fontno);
+
+/** Find font base URI.
+ @param app Application structure.
+ @param buf Destination buffer.
+ @param bs Size of @arg buf (number of dkChar).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3font_gs_base_web(dk3_app_t *app, dkChar *buf, size_t bs);
+
+/** Find local font base directory.
+ @param app Application structure.
+ @param buf Destination buffer.
+ @param bs Size of @arg buf (number of dkChar).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3font_gs_base_local(dk3_app_t *app, dkChar *buf, size_t bs);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3info.c b/support/dktools/dk3info.c
new file mode 100644
index 0000000000..b26e719268
--- /dev/null
+++ b/support/dktools/dk3info.c
@@ -0,0 +1,193 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3info.ctr
+*/
+
+/** @file dk3info.c The dk3info module.
+*/
+
+
+#line 5 "dk3info.ctr"
+
+#include "dk3all.h"
+#include "dk3sf.h"
+#include "dk3info1.c"
+
+
+/** Option names for configure.
+*/
+static dkChar const *option_names[] = {
+/* 0 */
+dkT("--prefix="),
+
+/* 1 */
+dkT("--sysconfdir="),
+
+/* 2 */
+dkT("--datarootdir="),
+
+/* 3 */
+dkT("--localstatedir="),
+
+/* 4 */
+dkT("--bindir="),
+
+/* 5 */
+dkT("--sbindir="),
+
+/* 6 */
+dkT("--libdir="),
+
+/* 7 */
+dkT("--includedir="),
+
+/* 8 */
+dkT("--mandir="),
+
+/* 9 */
+dkT("--execprefix="),
+
+/* 10 */
+dkT("--libexecdir="),
+
+NULL
+
+
+#line 27 "dk3info.ctr"
+};
+
+
+
+/** Options order.
+*/
+static size_t option_order[] = {
+ 0, 1, 3, 2, 4, 5, 6, 7, 8, 10
+};
+
+
+
+/** Number of options.
+*/
+static size_t num_options = (sizeof(option_order))/sizeof(size_t);
+
+
+
+/** Application group name.
+*/
+static dkChar const dk3info_group_name[] = { dkT("dktools") };
+
+
+
+/** Print the information.
+ @param app Application structure.
+ @param longvers Flag: Print long version.
+*/
+static
+void
+run_with_app(dk3_app_t *app, int longvers)
+{
+ dkChar const *val; /* Directory value (compiled). */
+ dkChar const *xval; /* Directory value (actually used). */
+ size_t maxlgt = 0; /* Maximum option name length. */
+ size_t lgt; /* Current option name length. */
+ size_t i; /* Traverse all options. */
+ size_t k; /* Print space. */
+ size_t di; /* Directory index. */
+ int mp; /* Flag: Must print actual data. */
+
+ /* Find maximum length of option names.
+ */
+ for(i = 0; i < num_options; i++) {
+ di = option_order[i];
+ /* ##### Count number of screen positions! */
+ lgt = dk3str_len(option_names[di]);
+ if(lgt > maxlgt) { maxlgt = lgt; }
+ }
+ /* Now print the information.
+ */
+ dk3sf_initialize_stdout();
+ for(i = 0; i < num_options; i++) {
+ di = option_order[i];
+ lgt = dk3str_len(option_names[di]);
+ if(lgt < maxlgt) {
+ lgt = maxlgt - lgt;
+ while(lgt--) {
+ dk3sf_fputc(dkT(' '), stdout);
+ }
+ }
+ dk3sf_fputs(option_names[di], stdout);
+ val = dk3inst_get_directory(di);
+ if(val) {
+ dk3sf_fputs(val, stdout);
+ }
+ dk3sf_fputc(dkT('\n'), stdout);
+ if(app) {
+ xval = NULL;
+ mp = 1;
+ switch(di) {
+ case DK3_INST_SYSCONF: xval = dk3app_get_etcdir(app); break;
+ case DK3_INST_DATAROOT: xval = dk3app_get_sharedir(app); break;
+ case DK3_INST_BIN: xval = dk3app_get_bindir(app); break;
+ case DK3_INST_LOCALSTATE: xval = dk3app_get_vardir(app); break;
+ }
+ if(xval) {
+ if(val) {
+ if(0 == dk3str_fncmp(val, xval)) {
+ mp = 0;
+ }
+ }
+ if(mp) {
+ for(k = 0; k < maxlgt; k++) dk3sf_fputc(dkT(' '), stdout);
+ dk3sf_fputs(xval, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ }
+ }
+ }
+ if(longvers) {
+ show_defines();
+ }
+}
+
+
+
+/** The main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+DK3_MAIN
+{
+ dk3_app_t *app = NULL;
+ dkChar const * const *xargv;
+ int longvers = 0;
+ int xargc;
+ app = dk3app_open_command(
+ argc, (dkChar const * const *)argv, dk3info_group_name
+ );
+ if(app) {
+ xargc = dk3app_get_argc(app);
+ xargv = dk3app_get_argv(app);
+ if(1 < xargc) {
+ if(dk3str_cmp(xargv[1], dkT("-l")) == 0) {
+ longvers = 1;
+ }
+ }
+ run_with_app(app, longvers);
+ dk3app_close(app);
+ } else {
+ if(1 < argc) {
+ if(dk3str_cmp(argv[1], dkT("-l")) == 0) {
+ longvers = 1;
+ }
+ }
+ run_with_app(NULL, longvers);
+ }
+ fflush(stdout);
+ exit(0); return 0;
+}
+
+
+
diff --git a/support/dktools/dk3info.ctr b/support/dktools/dk3info.ctr
new file mode 100644
index 0000000000..36e4ebc8cc
--- /dev/null
+++ b/support/dktools/dk3info.ctr
@@ -0,0 +1,161 @@
+%% options
+
+
+%% module
+
+#include "dk3all.h"
+#include "dk3sf.h"
+#include "dk3info1.c"
+
+
+/** Option names for configure.
+*/
+static dkChar const *option_names[] = {
+$!string-table macro=dkT
+--prefix=
+--sysconfdir=
+--datarootdir=
+--localstatedir=
+--bindir=
+--sbindir=
+--libdir=
+--includedir=
+--mandir=
+--execprefix=
+--libexecdir=
+$!end
+};
+
+
+
+/** Options order.
+*/
+static size_t option_order[] = {
+ 0, 1, 3, 2, 4, 5, 6, 7, 8, 10
+};
+
+
+
+/** Number of options.
+*/
+static size_t num_options = (sizeof(option_order))/sizeof(size_t);
+
+
+
+/** Application group name.
+*/
+static dkChar const dk3info_group_name[] = { dkT("dktools") };
+
+
+
+/** Print the information.
+ @param app Application structure.
+ @param longvers Flag: Print long version.
+*/
+static
+void
+run_with_app(dk3_app_t *app, int longvers)
+{
+ dkChar const *val; /* Directory value (compiled). */
+ dkChar const *xval; /* Directory value (actually used). */
+ size_t maxlgt = 0; /* Maximum option name length. */
+ size_t lgt; /* Current option name length. */
+ size_t i; /* Traverse all options. */
+ size_t k; /* Print space. */
+ size_t di; /* Directory index. */
+ int mp; /* Flag: Must print actual data. */
+
+ /* Find maximum length of option names.
+ */
+ for(i = 0; i < num_options; i++) {
+ di = option_order[i];
+ /* ##### Count number of screen positions! */
+ lgt = dk3str_len(option_names[di]);
+ if(lgt > maxlgt) { maxlgt = lgt; }
+ }
+ /* Now print the information.
+ */
+ dk3sf_initialize_stdout();
+ for(i = 0; i < num_options; i++) {
+ di = option_order[i];
+ lgt = dk3str_len(option_names[di]);
+ if(lgt < maxlgt) {
+ lgt = maxlgt - lgt;
+ while(lgt--) {
+ dk3sf_fputc(dkT(' '), stdout);
+ }
+ }
+ dk3sf_fputs(option_names[di], stdout);
+ val = dk3inst_get_directory(di);
+ if(val) {
+ dk3sf_fputs(val, stdout);
+ }
+ dk3sf_fputc(dkT('\n'), stdout);
+ if(app) {
+ xval = NULL;
+ mp = 1;
+ switch(di) {
+ case DK3_INST_SYSCONF: xval = dk3app_get_etcdir(app); break;
+ case DK3_INST_DATAROOT: xval = dk3app_get_sharedir(app); break;
+ case DK3_INST_BIN: xval = dk3app_get_bindir(app); break;
+ case DK3_INST_LOCALSTATE: xval = dk3app_get_vardir(app); break;
+ }
+ if(xval) {
+ if(val) {
+ if(0 == dk3str_fncmp(val, xval)) {
+ mp = 0;
+ }
+ }
+ if(mp) {
+ for(k = 0; k < maxlgt; k++) dk3sf_fputc(dkT(' '), stdout);
+ dk3sf_fputs(xval, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ }
+ }
+ }
+ if(longvers) {
+ show_defines();
+ }
+}
+
+
+
+/** The main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+DK3_MAIN
+{
+ dk3_app_t *app = NULL;
+ dkChar const * const *xargv;
+ int longvers = 0;
+ int xargc;
+ app = dk3app_open_command(
+ argc, (dkChar const * const *)argv, dk3info_group_name
+ );
+ if(app) {
+ xargc = dk3app_get_argc(app);
+ xargv = dk3app_get_argv(app);
+ if(1 < xargc) {
+ if(dk3str_cmp(xargv[1], dkT("-l")) == 0) {
+ longvers = 1;
+ }
+ }
+ run_with_app(app, longvers);
+ dk3app_close(app);
+ } else {
+ if(1 < argc) {
+ if(dk3str_cmp(argv[1], dkT("-l")) == 0) {
+ longvers = 1;
+ }
+ }
+ run_with_app(NULL, longvers);
+ }
+ fflush(stdout);
+ exit(0); return 0;
+}
+
+
+
diff --git a/support/dktools/dk3info.rc b/support/dktools/dk3info.rc
new file mode 100644
index 0000000000..0ad30eccb2
--- /dev/null
+++ b/support/dktools/dk3info.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Show setup information\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "Show setup information\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "dk3info\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/dk3info1.c b/support/dktools/dk3info1.c
new file mode 100644
index 0000000000..1b0690d8d6
--- /dev/null
+++ b/support/dktools/dk3info1.c
@@ -0,0 +1,1705 @@
+void show_defines(void)
+{
+ dkChar buf[64];
+#if DK3_HAVE_ACOSH
+ dk3sf_fputs(dkT("DK3_HAVE_ACOSH = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_ACOSH = 0\n"), stdout);
+#endif
+#if DK3_HAVE_ACOSHL
+ dk3sf_fputs(dkT("DK3_HAVE_ACOSHL = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_ACOSHL = 0\n"), stdout);
+#endif
+#if DK3_HAVE_ACOSL
+ dk3sf_fputs(dkT("DK3_HAVE_ACOSL = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_ACOSL = 0\n"), stdout);
+#endif
+#if DK3_HAVE_ALLOC_H
+ dk3sf_fputs(dkT("DK3_HAVE_ALLOC_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_ALLOC_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_ARPA_INET_H
+ dk3sf_fputs(dkT("DK3_HAVE_ARPA_INET_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_ARPA_INET_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_ASINH
+ dk3sf_fputs(dkT("DK3_HAVE_ASINH = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_ASINH = 0\n"), stdout);
+#endif
+#if DK3_HAVE_ASINHL
+ dk3sf_fputs(dkT("DK3_HAVE_ASINHL = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_ASINHL = 0\n"), stdout);
+#endif
+#if DK3_HAVE_ASINL
+ dk3sf_fputs(dkT("DK3_HAVE_ASINL = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_ASINL = 0\n"), stdout);
+#endif
+#if DK3_HAVE_ATAN2
+ dk3sf_fputs(dkT("DK3_HAVE_ATAN2 = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_ATAN2 = 0\n"), stdout);
+#endif
+#if DK3_HAVE_ATAN2L
+ dk3sf_fputs(dkT("DK3_HAVE_ATAN2L = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_ATAN2L = 0\n"), stdout);
+#endif
+#if DK3_HAVE_ATANH
+ dk3sf_fputs(dkT("DK3_HAVE_ATANH = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_ATANH = 0\n"), stdout);
+#endif
+#if DK3_HAVE_ATANHL
+ dk3sf_fputs(dkT("DK3_HAVE_ATANHL = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_ATANHL = 0\n"), stdout);
+#endif
+#if DK3_HAVE_ATANL
+ dk3sf_fputs(dkT("DK3_HAVE_ATANL = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_ATANL = 0\n"), stdout);
+#endif
+#if DK3_HAVE_BACKSLASH
+ dk3sf_fputs(dkT("DK3_HAVE_BACKSLASH = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_BACKSLASH = 0\n"), stdout);
+#endif
+#if DK3_HAVE_BCMP
+ dk3sf_fputs(dkT("DK3_HAVE_BCMP = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_BCMP = 0\n"), stdout);
+#endif
+#if DK3_HAVE_BCOPY
+ dk3sf_fputs(dkT("DK3_HAVE_BCOPY = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_BCOPY = 0\n"), stdout);
+#endif
+#if DK3_HAVE_BZERO
+ dk3sf_fputs(dkT("DK3_HAVE_BZERO = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_BZERO = 0\n"), stdout);
+#endif
+#if DK3_HAVE_BZLIB_H
+ dk3sf_fputs(dkT("DK3_HAVE_BZLIB_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_BZLIB_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_CEIL
+ dk3sf_fputs(dkT("DK3_HAVE_CEIL = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_CEIL = 0\n"), stdout);
+#endif
+#if DK3_HAVE_CEILL
+ dk3sf_fputs(dkT("DK3_HAVE_CEILL = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_CEILL = 0\n"), stdout);
+#endif
+#if DK3_HAVE_CHDIR
+ dk3sf_fputs(dkT("DK3_HAVE_CHDIR = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_CHDIR = 0\n"), stdout);
+#endif
+#if DK3_HAVE_CHMOD
+ dk3sf_fputs(dkT("DK3_HAVE_CHMOD = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_CHMOD = 0\n"), stdout);
+#endif
+#if DK3_HAVE_CHOWN
+ dk3sf_fputs(dkT("DK3_HAVE_CHOWN = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_CHOWN = 0\n"), stdout);
+#endif
+#if DK3_HAVE_CLOSEDIR
+ dk3sf_fputs(dkT("DK3_HAVE_CLOSEDIR = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_CLOSEDIR = 0\n"), stdout);
+#endif
+#if DK3_HAVE_CONIO_H
+ dk3sf_fputs(dkT("DK3_HAVE_CONIO_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_CONIO_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_CONST
+ dk3sf_fputs(dkT("DK3_HAVE_CONST = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_CONST = 0\n"), stdout);
+#endif
+#if DK3_HAVE_COSHL
+ dk3sf_fputs(dkT("DK3_HAVE_COSHL = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_COSHL = 0\n"), stdout);
+#endif
+#if DK3_HAVE_COSL
+ dk3sf_fputs(dkT("DK3_HAVE_COSL = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_COSL = 0\n"), stdout);
+#endif
+#if DK3_HAVE_CTYPE_H
+ dk3sf_fputs(dkT("DK3_HAVE_CTYPE_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_CTYPE_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_DB_CURSOR_C_GET
+ dk3sf_fputs(dkT("DK3_HAVE_DB_CURSOR_C_GET = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_DB_CURSOR_C_GET = 0\n"), stdout);
+#endif
+#if DK3_HAVE_DB_H
+ dk3sf_fputs(dkT("DK3_HAVE_DB_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_DB_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_DEV_RANDOM
+ dk3sf_fputs(dkT("DK3_HAVE_DEV_RANDOM = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_DEV_RANDOM = 0\n"), stdout);
+#endif
+#if DK3_HAVE_DEV_URANDOM
+ dk3sf_fputs(dkT("DK3_HAVE_DEV_URANDOM = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_DEV_URANDOM = 0\n"), stdout);
+#endif
+#if DK3_HAVE_DIRECT_H
+ dk3sf_fputs(dkT("DK3_HAVE_DIRECT_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_DIRECT_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_DIRENT_H
+ dk3sf_fputs(dkT("DK3_HAVE_DIRENT_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_DIRENT_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_DIR_H
+ dk3sf_fputs(dkT("DK3_HAVE_DIR_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_DIR_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_DOS_H
+ dk3sf_fputs(dkT("DK3_HAVE_DOS_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_DOS_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_ENDGRENT
+ dk3sf_fputs(dkT("DK3_HAVE_ENDGRENT = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_ENDGRENT = 0\n"), stdout);
+#endif
+#if DK3_HAVE_ENDPWENT
+ dk3sf_fputs(dkT("DK3_HAVE_ENDPWENT = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_ENDPWENT = 0\n"), stdout);
+#endif
+#if DK3_HAVE_ERRNO_H
+ dk3sf_fputs(dkT("DK3_HAVE_ERRNO_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_ERRNO_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_ERR_H
+ dk3sf_fputs(dkT("DK3_HAVE_ERR_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_ERR_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_EXPL
+ dk3sf_fputs(dkT("DK3_HAVE_EXPL = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_EXPL = 0\n"), stdout);
+#endif
+#if DK3_HAVE_FABS
+ dk3sf_fputs(dkT("DK3_HAVE_FABS = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_FABS = 0\n"), stdout);
+#endif
+#if DK3_HAVE_FABSL
+ dk3sf_fputs(dkT("DK3_HAVE_FABSL = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_FABSL = 0\n"), stdout);
+#endif
+#if DK3_HAVE_FCLOSE
+ dk3sf_fputs(dkT("DK3_HAVE_FCLOSE = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_FCLOSE = 0\n"), stdout);
+#endif
+#if DK3_HAVE_FCNTL_H
+ dk3sf_fputs(dkT("DK3_HAVE_FCNTL_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_FCNTL_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_FENV_H
+ dk3sf_fputs(dkT("DK3_HAVE_FENV_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_FENV_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_FEOF
+ dk3sf_fputs(dkT("DK3_HAVE_FEOF = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_FEOF = 0\n"), stdout);
+#endif
+#if DK3_HAVE_FERROR
+ dk3sf_fputs(dkT("DK3_HAVE_FERROR = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_FERROR = 0\n"), stdout);
+#endif
+#if DK3_HAVE_FETESTEXCEPT
+ dk3sf_fputs(dkT("DK3_HAVE_FETESTEXCEPT = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_FETESTEXCEPT = 0\n"), stdout);
+#endif
+#if DK3_HAVE_FFLUSH
+ dk3sf_fputs(dkT("DK3_HAVE_FFLUSH = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_FFLUSH = 0\n"), stdout);
+#endif
+#if DK3_HAVE_FLOAT_H
+ dk3sf_fputs(dkT("DK3_HAVE_FLOAT_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_FLOAT_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_FLOOR
+ dk3sf_fputs(dkT("DK3_HAVE_FLOOR = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_FLOOR = 0\n"), stdout);
+#endif
+#if DK3_HAVE_FLOORL
+ dk3sf_fputs(dkT("DK3_HAVE_FLOORL = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_FLOORL = 0\n"), stdout);
+#endif
+#if DK3_HAVE_FNCASEINS
+ dk3sf_fputs(dkT("DK3_HAVE_FNCASEINS = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_FNCASEINS = 0\n"), stdout);
+#endif
+#if DK3_HAVE_FOPEN
+ dk3sf_fputs(dkT("DK3_HAVE_FOPEN = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_FOPEN = 0\n"), stdout);
+#endif
+#if DK3_HAVE_FOPEN64
+ dk3sf_fputs(dkT("DK3_HAVE_FOPEN64 = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_FOPEN64 = 0\n"), stdout);
+#endif
+#if DK3_HAVE_FOPEN_S
+ dk3sf_fputs(dkT("DK3_HAVE_FOPEN_S = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_FOPEN_S = 0\n"), stdout);
+#endif
+#if DK3_HAVE_FORK
+ dk3sf_fputs(dkT("DK3_HAVE_FORK = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_FORK = 0\n"), stdout);
+#endif
+#if DK3_HAVE_FPCLASSIFY
+ dk3sf_fputs(dkT("DK3_HAVE_FPCLASSIFY = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_FPCLASSIFY = 0\n"), stdout);
+#endif
+#if DK3_HAVE_FREAD
+ dk3sf_fputs(dkT("DK3_HAVE_FREAD = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_FREAD = 0\n"), stdout);
+#endif
+#if DK3_HAVE_FREE
+ dk3sf_fputs(dkT("DK3_HAVE_FREE = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_FREE = 0\n"), stdout);
+#endif
+#if DK3_HAVE_FWRITE
+ dk3sf_fputs(dkT("DK3_HAVE_FWRITE = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_FWRITE = 0\n"), stdout);
+#endif
+#if DK3_HAVE_GDBM_H
+ dk3sf_fputs(dkT("DK3_HAVE_GDBM_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_GDBM_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_GETADDRINFO
+ dk3sf_fputs(dkT("DK3_HAVE_GETADDRINFO = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_GETADDRINFO = 0\n"), stdout);
+#endif
+#if DK3_HAVE_GETCWD
+ dk3sf_fputs(dkT("DK3_HAVE_GETCWD = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_GETCWD = 0\n"), stdout);
+#endif
+#if DK3_HAVE_GETENV
+ dk3sf_fputs(dkT("DK3_HAVE_GETENV = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_GETENV = 0\n"), stdout);
+#endif
+#if DK3_HAVE_GETEUID
+ dk3sf_fputs(dkT("DK3_HAVE_GETEUID = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_GETEUID = 0\n"), stdout);
+#endif
+#if DK3_HAVE_GETGRENT
+ dk3sf_fputs(dkT("DK3_HAVE_GETGRENT = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_GETGRENT = 0\n"), stdout);
+#endif
+#if DK3_HAVE_GETGRGID
+ dk3sf_fputs(dkT("DK3_HAVE_GETGRGID = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_GETGRGID = 0\n"), stdout);
+#endif
+#if DK3_HAVE_GETGRNAM
+ dk3sf_fputs(dkT("DK3_HAVE_GETGRNAM = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_GETGRNAM = 0\n"), stdout);
+#endif
+#if DK3_HAVE_GETHOSTBYNAME
+ dk3sf_fputs(dkT("DK3_HAVE_GETHOSTBYNAME = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_GETHOSTBYNAME = 0\n"), stdout);
+#endif
+#if DK3_HAVE_GETHOSTNAME
+ dk3sf_fputs(dkT("DK3_HAVE_GETHOSTNAME = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_GETHOSTNAME = 0\n"), stdout);
+#endif
+#if DK3_HAVE_GETPEERNAME
+ dk3sf_fputs(dkT("DK3_HAVE_GETPEERNAME = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_GETPEERNAME = 0\n"), stdout);
+#endif
+#if DK3_HAVE_GETPID
+ dk3sf_fputs(dkT("DK3_HAVE_GETPID = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_GETPID = 0\n"), stdout);
+#endif
+#if DK3_HAVE_GETPWENT
+ dk3sf_fputs(dkT("DK3_HAVE_GETPWENT = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_GETPWENT = 0\n"), stdout);
+#endif
+#if DK3_HAVE_GETPWNAM
+ dk3sf_fputs(dkT("DK3_HAVE_GETPWNAM = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_GETPWNAM = 0\n"), stdout);
+#endif
+#if DK3_HAVE_GETPWUID
+ dk3sf_fputs(dkT("DK3_HAVE_GETPWUID = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_GETPWUID = 0\n"), stdout);
+#endif
+#if DK3_HAVE_GETRLIMIT
+ dk3sf_fputs(dkT("DK3_HAVE_GETRLIMIT = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_GETRLIMIT = 0\n"), stdout);
+#endif
+#if DK3_HAVE_GETSOCKNAME
+ dk3sf_fputs(dkT("DK3_HAVE_GETSOCKNAME = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_GETSOCKNAME = 0\n"), stdout);
+#endif
+#if DK3_HAVE_GETUID
+ dk3sf_fputs(dkT("DK3_HAVE_GETUID = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_GETUID = 0\n"), stdout);
+#endif
+#if DK3_HAVE_GRP_H
+ dk3sf_fputs(dkT("DK3_HAVE_GRP_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_GRP_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_HTONL
+ dk3sf_fputs(dkT("DK3_HAVE_HTONL = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_HTONL = 0\n"), stdout);
+#endif
+#if DK3_HAVE_IEEE_754_DOUBLE
+ dk3sf_fputs(dkT("DK3_HAVE_IEEE_754_DOUBLE = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_IEEE_754_DOUBLE = 0\n"), stdout);
+#endif
+#if DK3_HAVE_IN6_ADDR
+ dk3sf_fputs(dkT("DK3_HAVE_IN6_ADDR = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_IN6_ADDR = 0\n"), stdout);
+#endif
+#if DK3_HAVE_INET_ADDR
+ dk3sf_fputs(dkT("DK3_HAVE_INET_ADDR = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_INET_ADDR = 0\n"), stdout);
+#endif
+#if DK3_HAVE_INET_ATON
+ dk3sf_fputs(dkT("DK3_HAVE_INET_ATON = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_INET_ATON = 0\n"), stdout);
+#endif
+#if DK3_HAVE_INET_PTON
+ dk3sf_fputs(dkT("DK3_HAVE_INET_PTON = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_INET_PTON = 0\n"), stdout);
+#endif
+#if DK3_HAVE_INITSTATE
+ dk3sf_fputs(dkT("DK3_HAVE_INITSTATE = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_INITSTATE = 0\n"), stdout);
+#endif
+#if DK3_HAVE_INODES
+ dk3sf_fputs(dkT("DK3_HAVE_INODES = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_INODES = 0\n"), stdout);
+#endif
+#if DK3_HAVE_INTMAX_T
+ dk3sf_fputs(dkT("DK3_HAVE_INTMAX_T = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_INTMAX_T = 0\n"), stdout);
+#endif
+#if DK3_HAVE_INTTYPES_H
+ dk3sf_fputs(dkT("DK3_HAVE_INTTYPES_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_INTTYPES_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_IN_ADDR
+ dk3sf_fputs(dkT("DK3_HAVE_IN_ADDR = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_IN_ADDR = 0\n"), stdout);
+#endif
+#if DK3_HAVE_IO_H
+ dk3sf_fputs(dkT("DK3_HAVE_IO_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_IO_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_ISATTY
+ dk3sf_fputs(dkT("DK3_HAVE_ISATTY = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_ISATTY = 0\n"), stdout);
+#endif
+#if DK3_HAVE_ISFINITE
+ dk3sf_fputs(dkT("DK3_HAVE_ISFINITE = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_ISFINITE = 0\n"), stdout);
+#endif
+#if DK3_HAVE_ISNORMAL
+ dk3sf_fputs(dkT("DK3_HAVE_ISNORMAL = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_ISNORMAL = 0\n"), stdout);
+#endif
+#if DK3_HAVE_JPEGLIB_H
+ dk3sf_fputs(dkT("DK3_HAVE_JPEGLIB_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_JPEGLIB_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_LABS
+ dk3sf_fputs(dkT("DK3_HAVE_LABS = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_LABS = 0\n"), stdout);
+#endif
+#if DK3_HAVE_LARGEFILE64_SOURCE
+ dk3sf_fputs(dkT("DK3_HAVE_LARGEFILE64_SOURCE = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_LARGEFILE64_SOURCE = 0\n"), stdout);
+#endif
+#if DK3_HAVE_LIBNETSNMP
+ dk3sf_fputs(dkT("DK3_HAVE_LIBNETSNMP = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_LIBNETSNMP = 0\n"), stdout);
+#endif
+#if DK3_HAVE_LIMITS_H
+ dk3sf_fputs(dkT("DK3_HAVE_LIMITS_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_LIMITS_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_LOCALE_H
+ dk3sf_fputs(dkT("DK3_HAVE_LOCALE_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_LOCALE_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_LOCALTIME
+ dk3sf_fputs(dkT("DK3_HAVE_LOCALTIME = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_LOCALTIME = 0\n"), stdout);
+#endif
+#if DK3_HAVE_LOCALTIME
+ dk3sf_fputs(dkT("DK3_HAVE_LOCALTIME = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_LOCALTIME = 0\n"), stdout);
+#endif
+#if DK3_HAVE_LOCALTIME_R
+ dk3sf_fputs(dkT("DK3_HAVE_LOCALTIME_R = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_LOCALTIME_R = 0\n"), stdout);
+#endif
+#if DK3_HAVE_LOCALTIME_S
+ dk3sf_fputs(dkT("DK3_HAVE_LOCALTIME_S = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_LOCALTIME_S = 0\n"), stdout);
+#endif
+#if DK3_HAVE_LOGL
+ dk3sf_fputs(dkT("DK3_HAVE_LOGL = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_LOGL = 0\n"), stdout);
+#endif
+#if DK3_HAVE_LONG_DOUBLE
+ dk3sf_fputs(dkT("DK3_HAVE_LONG_DOUBLE = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_LONG_DOUBLE = 0\n"), stdout);
+#endif
+#if DK3_HAVE_LONG_LONG
+ dk3sf_fputs(dkT("DK3_HAVE_LONG_LONG = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_LONG_LONG = 0\n"), stdout);
+#endif
+#if DK3_HAVE_LPRNG_H
+ dk3sf_fputs(dkT("DK3_HAVE_LPRNG_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_LPRNG_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_LRAND48
+ dk3sf_fputs(dkT("DK3_HAVE_LRAND48 = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_LRAND48 = 0\n"), stdout);
+#endif
+#if DK3_HAVE_LSTAT
+ dk3sf_fputs(dkT("DK3_HAVE_LSTAT = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_LSTAT = 0\n"), stdout);
+#endif
+#if DK3_HAVE_LSTAT32
+ dk3sf_fputs(dkT("DK3_HAVE_LSTAT32 = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_LSTAT32 = 0\n"), stdout);
+#endif
+#if DK3_HAVE_LSTAT64
+ dk3sf_fputs(dkT("DK3_HAVE_LSTAT64 = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_LSTAT64 = 0\n"), stdout);
+#endif
+#if DK3_HAVE_MALLOC
+ dk3sf_fputs(dkT("DK3_HAVE_MALLOC = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_MALLOC = 0\n"), stdout);
+#endif
+#if DK3_HAVE_MALLOC_H
+ dk3sf_fputs(dkT("DK3_HAVE_MALLOC_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_MALLOC_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_MATH_H
+ dk3sf_fputs(dkT("DK3_HAVE_MATH_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_MATH_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_MEMCMP
+ dk3sf_fputs(dkT("DK3_HAVE_MEMCMP = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_MEMCMP = 0\n"), stdout);
+#endif
+#if DK3_HAVE_MEMCPY
+ dk3sf_fputs(dkT("DK3_HAVE_MEMCPY = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_MEMCPY = 0\n"), stdout);
+#endif
+#if DK3_HAVE_MEMSET
+ dk3sf_fputs(dkT("DK3_HAVE_MEMSET = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_MEMSET = 0\n"), stdout);
+#endif
+#if DK3_HAVE_MKDIR
+ dk3sf_fputs(dkT("DK3_HAVE_MKDIR = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_MKDIR = 0\n"), stdout);
+#endif
+#if DK3_HAVE_MKDIR2
+ dk3sf_fputs(dkT("DK3_HAVE_MKDIR2 = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_MKDIR2 = 0\n"), stdout);
+#endif
+#if DK3_HAVE_MPCTL
+ dk3sf_fputs(dkT("DK3_HAVE_MPCTL = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_MPCTL = 0\n"), stdout);
+#endif
+#if DK3_HAVE_MYSQL_LIBRARY_END
+ dk3sf_fputs(dkT("DK3_HAVE_MYSQL_LIBRARY_END = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_MYSQL_LIBRARY_END = 0\n"), stdout);
+#endif
+#if DK3_HAVE_MYSQL_LIBRARY_INIT
+ dk3sf_fputs(dkT("DK3_HAVE_MYSQL_LIBRARY_INIT = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_MYSQL_LIBRARY_INIT = 0\n"), stdout);
+#endif
+#if DK3_HAVE_MYSQL_MYSQL_H
+ dk3sf_fputs(dkT("DK3_HAVE_MYSQL_MYSQL_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_MYSQL_MYSQL_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_MYSQL_SET_CHARACTER_SET
+ dk3sf_fputs(dkT("DK3_HAVE_MYSQL_SET_CHARACTER_SET = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_MYSQL_SET_CHARACTER_SET = 0\n"), stdout);
+#endif
+#if DK3_HAVE_NDBM_H
+ dk3sf_fputs(dkT("DK3_HAVE_NDBM_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_NDBM_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_NETDB_H
+ dk3sf_fputs(dkT("DK3_HAVE_NETDB_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_NETDB_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_NETINET_IN_H
+ dk3sf_fputs(dkT("DK3_HAVE_NETINET_IN_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_NETINET_IN_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_NETSNMP_ENABLE_FILELOG
+ dk3sf_fputs(dkT("DK3_HAVE_NETSNMP_ENABLE_FILELOG = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_NETSNMP_ENABLE_FILELOG = 0\n"), stdout);
+#endif
+#if DK3_HAVE_NRAND48
+ dk3sf_fputs(dkT("DK3_HAVE_NRAND48 = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_NRAND48 = 0\n"), stdout);
+#endif
+#if DK3_HAVE_OPENDIR
+ dk3sf_fputs(dkT("DK3_HAVE_OPENDIR = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_OPENDIR = 0\n"), stdout);
+#endif
+#if DK3_HAVE_OPENSSL_MD5_H
+ dk3sf_fputs(dkT("DK3_HAVE_OPENSSL_MD5_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_OPENSSL_MD5_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_OPENSSL_RAND_H
+ dk3sf_fputs(dkT("DK3_HAVE_OPENSSL_RAND_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_OPENSSL_RAND_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_OPENSSL_RIPEMD_H
+ dk3sf_fputs(dkT("DK3_HAVE_OPENSSL_RIPEMD_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_OPENSSL_RIPEMD_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_OPENSSL_SHA_H
+ dk3sf_fputs(dkT("DK3_HAVE_OPENSSL_SHA_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_OPENSSL_SHA_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_PNG_GET_PIXELS_PER_INCH
+ dk3sf_fputs(dkT("DK3_HAVE_PNG_GET_PIXELS_PER_INCH = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_PNG_GET_PIXELS_PER_INCH = 0\n"), stdout);
+#endif
+#if DK3_HAVE_PNG_H
+ dk3sf_fputs(dkT("DK3_HAVE_PNG_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_PNG_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_POPEN
+ dk3sf_fputs(dkT("DK3_HAVE_POPEN = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_POPEN = 0\n"), stdout);
+#endif
+#if DK3_HAVE_PROCESS_H
+ dk3sf_fputs(dkT("DK3_HAVE_PROCESS_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_PROCESS_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_PTHREAD_H
+ dk3sf_fputs(dkT("DK3_HAVE_PTHREAD_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_PTHREAD_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_PWD_H
+ dk3sf_fputs(dkT("DK3_HAVE_PWD_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_PWD_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_RAND
+ dk3sf_fputs(dkT("DK3_HAVE_RAND = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_RAND = 0\n"), stdout);
+#endif
+#if DK3_HAVE_RANDOM
+ dk3sf_fputs(dkT("DK3_HAVE_RANDOM = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_RANDOM = 0\n"), stdout);
+#endif
+#if DK3_HAVE_READ
+ dk3sf_fputs(dkT("DK3_HAVE_READ = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_READ = 0\n"), stdout);
+#endif
+#if DK3_HAVE_READDIR
+ dk3sf_fputs(dkT("DK3_HAVE_READDIR = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_READDIR = 0\n"), stdout);
+#endif
+#if DK3_HAVE_RFC_2249
+ dk3sf_fputs(dkT("DK3_HAVE_RFC_2249 = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_RFC_2249 = 0\n"), stdout);
+#endif
+#if DK3_HAVE_RINT
+ dk3sf_fputs(dkT("DK3_HAVE_RINT = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_RINT = 0\n"), stdout);
+#endif
+#if DK3_HAVE_RINTL
+ dk3sf_fputs(dkT("DK3_HAVE_RINTL = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_RINTL = 0\n"), stdout);
+#endif
+#if DK3_HAVE_RMDIR
+ dk3sf_fputs(dkT("DK3_HAVE_RMDIR = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_RMDIR = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SEED48
+ dk3sf_fputs(dkT("DK3_HAVE_SEED48 = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SEED48 = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SELECT
+ dk3sf_fputs(dkT("DK3_HAVE_SELECT = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SELECT = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SETGID
+ dk3sf_fputs(dkT("DK3_HAVE_SETGID = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SETGID = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SETGRENT
+ dk3sf_fputs(dkT("DK3_HAVE_SETGRENT = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SETGRENT = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SETJMP_H
+ dk3sf_fputs(dkT("DK3_HAVE_SETJMP_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SETJMP_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SETLOCALE
+ dk3sf_fputs(dkT("DK3_HAVE_SETLOCALE = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SETLOCALE = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SETPGRP
+ dk3sf_fputs(dkT("DK3_HAVE_SETPGRP = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SETPGRP = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SETPWENT
+ dk3sf_fputs(dkT("DK3_HAVE_SETPWENT = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SETPWENT = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SETSID
+ dk3sf_fputs(dkT("DK3_HAVE_SETSID = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SETSID = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SETSOCKOPT
+ dk3sf_fputs(dkT("DK3_HAVE_SETSOCKOPT = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SETSOCKOPT = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SETSTATE
+ dk3sf_fputs(dkT("DK3_HAVE_SETSTATE = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SETSTATE = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SETUID
+ dk3sf_fputs(dkT("DK3_HAVE_SETUID = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SETUID = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SHA224
+ dk3sf_fputs(dkT("DK3_HAVE_SHA224 = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SHA224 = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SHA256
+ dk3sf_fputs(dkT("DK3_HAVE_SHA256 = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SHA256 = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SHA384
+ dk3sf_fputs(dkT("DK3_HAVE_SHA384 = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SHA384 = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SHA512
+ dk3sf_fputs(dkT("DK3_HAVE_SHA512 = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SHA512 = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SHADOW_H
+ dk3sf_fputs(dkT("DK3_HAVE_SHADOW_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SHADOW_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SIGACTION
+ dk3sf_fputs(dkT("DK3_HAVE_SIGACTION = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SIGACTION = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SIGNAL
+ dk3sf_fputs(dkT("DK3_HAVE_SIGNAL = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SIGNAL = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SIGNAL_H
+ dk3sf_fputs(dkT("DK3_HAVE_SIGNAL_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SIGNAL_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SIGSET
+ dk3sf_fputs(dkT("DK3_HAVE_SIGSET = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SIGSET = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SIG_ATOMIC_T
+ dk3sf_fputs(dkT("DK3_HAVE_SIG_ATOMIC_T = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SIG_ATOMIC_T = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SINHL
+ dk3sf_fputs(dkT("DK3_HAVE_SINHL = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SINHL = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SINL
+ dk3sf_fputs(dkT("DK3_HAVE_SINL = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SINL = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SNPRINTF
+ dk3sf_fputs(dkT("DK3_HAVE_SNPRINTF = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SNPRINTF = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SNWPRINTF
+ dk3sf_fputs(dkT("DK3_HAVE_SNWPRINTF = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SNWPRINTF = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SOCKET
+ dk3sf_fputs(dkT("DK3_HAVE_SOCKET = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SOCKET = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SOCKLEN_T
+ dk3sf_fputs(dkT("DK3_HAVE_SOCKLEN_T = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SOCKLEN_T = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SPRINTF_S
+ dk3sf_fputs(dkT("DK3_HAVE_SPRINTF_S = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SPRINTF_S = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SQRTL
+ dk3sf_fputs(dkT("DK3_HAVE_SQRTL = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SQRTL = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SRAND
+ dk3sf_fputs(dkT("DK3_HAVE_SRAND = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SRAND = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SSCANF_S
+ dk3sf_fputs(dkT("DK3_HAVE_SSCANF_S = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SSCANF_S = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SSIZE_T
+ dk3sf_fputs(dkT("DK3_HAVE_SSIZE_T = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SSIZE_T = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STAT
+ dk3sf_fputs(dkT("DK3_HAVE_STAT = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STAT = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STAT32
+ dk3sf_fputs(dkT("DK3_HAVE_STAT32 = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STAT32 = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STAT64
+ dk3sf_fputs(dkT("DK3_HAVE_STAT64 = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STAT64 = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STDARG_H
+ dk3sf_fputs(dkT("DK3_HAVE_STDARG_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STDARG_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STDDEF_H
+ dk3sf_fputs(dkT("DK3_HAVE_STDDEF_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STDDEF_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STDINT_H
+ dk3sf_fputs(dkT("DK3_HAVE_STDINT_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STDINT_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STDIO_H
+ dk3sf_fputs(dkT("DK3_HAVE_STDIO_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STDIO_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STDLIB_H
+ dk3sf_fputs(dkT("DK3_HAVE_STDLIB_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STDLIB_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STRCASECMP
+ dk3sf_fputs(dkT("DK3_HAVE_STRCASECMP = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STRCASECMP = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STRCAT
+ dk3sf_fputs(dkT("DK3_HAVE_STRCAT = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STRCAT = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STRCAT_S
+ dk3sf_fputs(dkT("DK3_HAVE_STRCAT_S = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STRCAT_S = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STRCHR
+ dk3sf_fputs(dkT("DK3_HAVE_STRCHR = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STRCHR = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STRCMP
+ dk3sf_fputs(dkT("DK3_HAVE_STRCMP = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STRCMP = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STRCPY
+ dk3sf_fputs(dkT("DK3_HAVE_STRCPY = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STRCPY = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STRCPY_S
+ dk3sf_fputs(dkT("DK3_HAVE_STRCPY_S = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STRCPY_S = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STRDUP
+ dk3sf_fputs(dkT("DK3_HAVE_STRDUP = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STRDUP = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STRERROR
+ dk3sf_fputs(dkT("DK3_HAVE_STRERROR = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STRERROR = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STRICMP
+ dk3sf_fputs(dkT("DK3_HAVE_STRICMP = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STRICMP = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STRINGS_H
+ dk3sf_fputs(dkT("DK3_HAVE_STRINGS_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STRINGS_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STRING_H
+ dk3sf_fputs(dkT("DK3_HAVE_STRING_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STRING_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STRLEN
+ dk3sf_fputs(dkT("DK3_HAVE_STRLEN = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STRLEN = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STRNCMP
+ dk3sf_fputs(dkT("DK3_HAVE_STRNCMP = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STRNCMP = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STRNCPY
+ dk3sf_fputs(dkT("DK3_HAVE_STRNCPY = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STRNCPY = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STRNCPY_S
+ dk3sf_fputs(dkT("DK3_HAVE_STRNCPY_S = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STRNCPY_S = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STROPTS_H
+ dk3sf_fputs(dkT("DK3_HAVE_STROPTS_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STROPTS_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STRRCHR
+ dk3sf_fputs(dkT("DK3_HAVE_STRRCHR = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STRRCHR = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STRTOD
+ dk3sf_fputs(dkT("DK3_HAVE_STRTOD = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STRTOD = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STRTOIMAX
+ dk3sf_fputs(dkT("DK3_HAVE_STRTOIMAX = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STRTOIMAX = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STRTOL
+ dk3sf_fputs(dkT("DK3_HAVE_STRTOL = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STRTOL = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STRTOLL
+ dk3sf_fputs(dkT("DK3_HAVE_STRTOLL = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STRTOLL = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STRTOUL
+ dk3sf_fputs(dkT("DK3_HAVE_STRTOUL = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STRTOUL = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STRTOULL
+ dk3sf_fputs(dkT("DK3_HAVE_STRTOULL = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STRTOULL = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STRTOUMAX
+ dk3sf_fputs(dkT("DK3_HAVE_STRTOUMAX = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STRTOUMAX = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STRUCT_ADDRINFO
+ dk3sf_fputs(dkT("DK3_HAVE_STRUCT_ADDRINFO = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STRUCT_ADDRINFO = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STRUCT_SOCKADDR_IN
+ dk3sf_fputs(dkT("DK3_HAVE_STRUCT_SOCKADDR_IN = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STRUCT_SOCKADDR_IN = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STRUCT_SOCKADDR_IN6
+ dk3sf_fputs(dkT("DK3_HAVE_STRUCT_SOCKADDR_IN6 = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STRUCT_SOCKADDR_IN6 = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STRUCT_SOCKADDR_STORAGE
+ dk3sf_fputs(dkT("DK3_HAVE_STRUCT_SOCKADDR_STORAGE = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STRUCT_SOCKADDR_STORAGE = 0\n"), stdout);
+#endif
+#if DK3_HAVE_STRUCT_SOCKADDR_UN
+ dk3sf_fputs(dkT("DK3_HAVE_STRUCT_SOCKADDR_UN = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_STRUCT_SOCKADDR_UN = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SWSCANF_S
+ dk3sf_fputs(dkT("DK3_HAVE_SWSCANF_S = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SWSCANF_S = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SYSCONF
+ dk3sf_fputs(dkT("DK3_HAVE_SYSCONF = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SYSCONF = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SYSCTL
+ dk3sf_fputs(dkT("DK3_HAVE_SYSCTL = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SYSCTL = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SYSLOG
+ dk3sf_fputs(dkT("DK3_HAVE_SYSLOG = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SYSLOG = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SYSLOG_H
+ dk3sf_fputs(dkT("DK3_HAVE_SYSLOG_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SYSLOG_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SYSRES_H
+ dk3sf_fputs(dkT("DK3_HAVE_SYSRES_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SYSRES_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SYS_FILE_H
+ dk3sf_fputs(dkT("DK3_HAVE_SYS_FILE_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SYS_FILE_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SYS_PARAM_H
+ dk3sf_fputs(dkT("DK3_HAVE_SYS_PARAM_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SYS_PARAM_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SYS_RESOURCE_H
+ dk3sf_fputs(dkT("DK3_HAVE_SYS_RESOURCE_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SYS_RESOURCE_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SYS_SOCKET_H
+ dk3sf_fputs(dkT("DK3_HAVE_SYS_SOCKET_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SYS_SOCKET_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SYS_STATVFS_H
+ dk3sf_fputs(dkT("DK3_HAVE_SYS_STATVFS_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SYS_STATVFS_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SYS_STAT_H
+ dk3sf_fputs(dkT("DK3_HAVE_SYS_STAT_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SYS_STAT_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SYS_STROPTS_H
+ dk3sf_fputs(dkT("DK3_HAVE_SYS_STROPTS_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SYS_STROPTS_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SYS_SUNDDI_H
+ dk3sf_fputs(dkT("DK3_HAVE_SYS_SUNDDI_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SYS_SUNDDI_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SYS_SYSCTL_H
+ dk3sf_fputs(dkT("DK3_HAVE_SYS_SYSCTL_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SYS_SYSCTL_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SYS_SYSTEMINFO_H
+ dk3sf_fputs(dkT("DK3_HAVE_SYS_SYSTEMINFO_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SYS_SYSTEMINFO_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SYS_TERMIOS_H
+ dk3sf_fputs(dkT("DK3_HAVE_SYS_TERMIOS_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SYS_TERMIOS_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SYS_TIME_H
+ dk3sf_fputs(dkT("DK3_HAVE_SYS_TIME_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SYS_TIME_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SYS_TTOLD_H
+ dk3sf_fputs(dkT("DK3_HAVE_SYS_TTOLD_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SYS_TTOLD_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SYS_TYPES_H
+ dk3sf_fputs(dkT("DK3_HAVE_SYS_TYPES_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SYS_TYPES_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SYS_UIO_H
+ dk3sf_fputs(dkT("DK3_HAVE_SYS_UIO_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SYS_UIO_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SYS_UN_H
+ dk3sf_fputs(dkT("DK3_HAVE_SYS_UN_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SYS_UN_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_SYS_WAIT_H
+ dk3sf_fputs(dkT("DK3_HAVE_SYS_WAIT_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_SYS_WAIT_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_TANHL
+ dk3sf_fputs(dkT("DK3_HAVE_TANHL = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_TANHL = 0\n"), stdout);
+#endif
+#if DK3_HAVE_TANL
+ dk3sf_fputs(dkT("DK3_HAVE_TANL = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_TANL = 0\n"), stdout);
+#endif
+#if DK3_HAVE_TCFLUSH
+ dk3sf_fputs(dkT("DK3_HAVE_TCFLUSH = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_TCFLUSH = 0\n"), stdout);
+#endif
+#if DK3_HAVE_TCGETATTR
+ dk3sf_fputs(dkT("DK3_HAVE_TCGETATTR = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_TCGETATTR = 0\n"), stdout);
+#endif
+#if DK3_HAVE_TERMIOS_H
+ dk3sf_fputs(dkT("DK3_HAVE_TERMIOS_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_TERMIOS_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_TIFF_H
+ dk3sf_fputs(dkT("DK3_HAVE_TIFF_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_TIFF_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_TIME
+ dk3sf_fputs(dkT("DK3_HAVE_TIME = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_TIME = 0\n"), stdout);
+#endif
+#if DK3_HAVE_TIME_H
+ dk3sf_fputs(dkT("DK3_HAVE_TIME_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_TIME_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_TWOS_COMPLEMENT
+ dk3sf_fputs(dkT("DK3_HAVE_TWOS_COMPLEMENT = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_TWOS_COMPLEMENT = 0\n"), stdout);
+#endif
+#if DK3_HAVE_UMASK
+ dk3sf_fputs(dkT("DK3_HAVE_UMASK = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_UMASK = 0\n"), stdout);
+#endif
+#if DK3_HAVE_UNISTD_H
+ dk3sf_fputs(dkT("DK3_HAVE_UNISTD_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_UNISTD_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_UNLINK
+ dk3sf_fputs(dkT("DK3_HAVE_UNLINK = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_UNLINK = 0\n"), stdout);
+#endif
+#if DK3_HAVE_USER_NAMES_CASE_INSENSITIVE
+ dk3sf_fputs(dkT("DK3_HAVE_USER_NAMES_CASE_INSENSITIVE = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_USER_NAMES_CASE_INSENSITIVE = 0\n"), stdout);
+#endif
+#if DK3_HAVE_VARARGS_H
+ dk3sf_fputs(dkT("DK3_HAVE_VARARGS_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_VARARGS_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_VARARG_H
+ dk3sf_fputs(dkT("DK3_HAVE_VARARG_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_VARARG_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_VOLATILE
+ dk3sf_fputs(dkT("DK3_HAVE_VOLATILE = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_VOLATILE = 0\n"), stdout);
+#endif
+#if DK3_HAVE_WCHAR_H
+ dk3sf_fputs(dkT("DK3_HAVE_WCHAR_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_WCHAR_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_WCHAR_T
+ dk3sf_fputs(dkT("DK3_HAVE_WCHAR_T = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_WCHAR_T = 0\n"), stdout);
+#endif
+#if DK3_HAVE_WCSCAT
+ dk3sf_fputs(dkT("DK3_HAVE_WCSCAT = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_WCSCAT = 0\n"), stdout);
+#endif
+#if DK3_HAVE_WCSCAT_S
+ dk3sf_fputs(dkT("DK3_HAVE_WCSCAT_S = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_WCSCAT_S = 0\n"), stdout);
+#endif
+#if DK3_HAVE_WCSCHR
+ dk3sf_fputs(dkT("DK3_HAVE_WCSCHR = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_WCSCHR = 0\n"), stdout);
+#endif
+#if DK3_HAVE_WCSCMP
+ dk3sf_fputs(dkT("DK3_HAVE_WCSCMP = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_WCSCMP = 0\n"), stdout);
+#endif
+#if DK3_HAVE_WCSCPY
+ dk3sf_fputs(dkT("DK3_HAVE_WCSCPY = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_WCSCPY = 0\n"), stdout);
+#endif
+#if DK3_HAVE_WCSCPY_S
+ dk3sf_fputs(dkT("DK3_HAVE_WCSCPY_S = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_WCSCPY_S = 0\n"), stdout);
+#endif
+#if DK3_HAVE_WCSDUP
+ dk3sf_fputs(dkT("DK3_HAVE_WCSDUP = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_WCSDUP = 0\n"), stdout);
+#endif
+#if DK3_HAVE_WCSICMP
+ dk3sf_fputs(dkT("DK3_HAVE_WCSICMP = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_WCSICMP = 0\n"), stdout);
+#endif
+#if DK3_HAVE_WCSLEN
+ dk3sf_fputs(dkT("DK3_HAVE_WCSLEN = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_WCSLEN = 0\n"), stdout);
+#endif
+#if DK3_HAVE_WCSNCMP
+ dk3sf_fputs(dkT("DK3_HAVE_WCSNCMP = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_WCSNCMP = 0\n"), stdout);
+#endif
+#if DK3_HAVE_WCSNCPY
+ dk3sf_fputs(dkT("DK3_HAVE_WCSNCPY = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_WCSNCPY = 0\n"), stdout);
+#endif
+#if DK3_HAVE_WCSNCPY_S
+ dk3sf_fputs(dkT("DK3_HAVE_WCSNCPY_S = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_WCSNCPY_S = 0\n"), stdout);
+#endif
+#if DK3_HAVE_WCSRCHR
+ dk3sf_fputs(dkT("DK3_HAVE_WCSRCHR = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_WCSRCHR = 0\n"), stdout);
+#endif
+#if DK3_HAVE_WCSTOD
+ dk3sf_fputs(dkT("DK3_HAVE_WCSTOD = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_WCSTOD = 0\n"), stdout);
+#endif
+#if DK3_HAVE_WCSTOIMAX
+ dk3sf_fputs(dkT("DK3_HAVE_WCSTOIMAX = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_WCSTOIMAX = 0\n"), stdout);
+#endif
+#if DK3_HAVE_WCSTOL
+ dk3sf_fputs(dkT("DK3_HAVE_WCSTOL = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_WCSTOL = 0\n"), stdout);
+#endif
+#if DK3_HAVE_WCSTOLL
+ dk3sf_fputs(dkT("DK3_HAVE_WCSTOLL = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_WCSTOLL = 0\n"), stdout);
+#endif
+#if DK3_HAVE_WCSTOUL
+ dk3sf_fputs(dkT("DK3_HAVE_WCSTOUL = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_WCSTOUL = 0\n"), stdout);
+#endif
+#if DK3_HAVE_WCSTOULL
+ dk3sf_fputs(dkT("DK3_HAVE_WCSTOULL = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_WCSTOULL = 0\n"), stdout);
+#endif
+#if DK3_HAVE_WCSTOUMAX
+ dk3sf_fputs(dkT("DK3_HAVE_WCSTOUMAX = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_WCSTOUMAX = 0\n"), stdout);
+#endif
+#if DK3_HAVE_WINBASE_H
+ dk3sf_fputs(dkT("DK3_HAVE_WINBASE_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_WINBASE_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_WINCON_H
+ dk3sf_fputs(dkT("DK3_HAVE_WINCON_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_WINCON_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_WINDOWS_H
+ dk3sf_fputs(dkT("DK3_HAVE_WINDOWS_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_WINDOWS_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_WINREG_H
+ dk3sf_fputs(dkT("DK3_HAVE_WINREG_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_WINREG_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_WINSOCK2_H
+ dk3sf_fputs(dkT("DK3_HAVE_WINSOCK2_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_WINSOCK2_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_WRITE
+ dk3sf_fputs(dkT("DK3_HAVE_WRITE = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_WRITE = 0\n"), stdout);
+#endif
+#if DK3_HAVE_WS2TCPIP_H
+ dk3sf_fputs(dkT("DK3_HAVE_WS2TCPIP_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_WS2TCPIP_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE_ZLIB_H
+ dk3sf_fputs(dkT("DK3_HAVE_ZLIB_H = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE_ZLIB_H = 0\n"), stdout);
+#endif
+#if DK3_HAVE__CLEARFP
+ dk3sf_fputs(dkT("DK3_HAVE__CLEARFP = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__CLEARFP = 0\n"), stdout);
+#endif
+#if DK3_HAVE__FCLOSE
+ dk3sf_fputs(dkT("DK3_HAVE__FCLOSE = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__FCLOSE = 0\n"), stdout);
+#endif
+#if DK3_HAVE__FEOF
+ dk3sf_fputs(dkT("DK3_HAVE__FEOF = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__FEOF = 0\n"), stdout);
+#endif
+#if DK3_HAVE__FERROR
+ dk3sf_fputs(dkT("DK3_HAVE__FERROR = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__FERROR = 0\n"), stdout);
+#endif
+#if DK3_HAVE__FFLUSH
+ dk3sf_fputs(dkT("DK3_HAVE__FFLUSH = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__FFLUSH = 0\n"), stdout);
+#endif
+#if DK3_HAVE__FOPEN
+ dk3sf_fputs(dkT("DK3_HAVE__FOPEN = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__FOPEN = 0\n"), stdout);
+#endif
+#if DK3_HAVE__FREAD
+ dk3sf_fputs(dkT("DK3_HAVE__FREAD = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__FREAD = 0\n"), stdout);
+#endif
+#if DK3_HAVE__FWRITE
+ dk3sf_fputs(dkT("DK3_HAVE__FWRITE = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__FWRITE = 0\n"), stdout);
+#endif
+#if DK3_HAVE__GETCWD
+ dk3sf_fputs(dkT("DK3_HAVE__GETCWD = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__GETCWD = 0\n"), stdout);
+#endif
+#if DK3_HAVE__GETENV_S
+ dk3sf_fputs(dkT("DK3_HAVE__GETENV_S = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__GETENV_S = 0\n"), stdout);
+#endif
+#if DK3_HAVE__GETPID
+ dk3sf_fputs(dkT("DK3_HAVE__GETPID = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__GETPID = 0\n"), stdout);
+#endif
+#if DK3_HAVE__LSTAT
+ dk3sf_fputs(dkT("DK3_HAVE__LSTAT = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__LSTAT = 0\n"), stdout);
+#endif
+#if DK3_HAVE__LSTAT32
+ dk3sf_fputs(dkT("DK3_HAVE__LSTAT32 = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__LSTAT32 = 0\n"), stdout);
+#endif
+#if DK3_HAVE__LSTAT64
+ dk3sf_fputs(dkT("DK3_HAVE__LSTAT64 = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__LSTAT64 = 0\n"), stdout);
+#endif
+#if DK3_HAVE__MKDIR
+ dk3sf_fputs(dkT("DK3_HAVE__MKDIR = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__MKDIR = 0\n"), stdout);
+#endif
+#if DK3_HAVE__POPEN
+ dk3sf_fputs(dkT("DK3_HAVE__POPEN = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__POPEN = 0\n"), stdout);
+#endif
+#if DK3_HAVE__READ
+ dk3sf_fputs(dkT("DK3_HAVE__READ = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__READ = 0\n"), stdout);
+#endif
+#if DK3_HAVE__RMDIR
+ dk3sf_fputs(dkT("DK3_HAVE__RMDIR = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__RMDIR = 0\n"), stdout);
+#endif
+#if DK3_HAVE__SNPRINTF
+ dk3sf_fputs(dkT("DK3_HAVE__SNPRINTF = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__SNPRINTF = 0\n"), stdout);
+#endif
+#if DK3_HAVE__SNPRINTF_S
+ dk3sf_fputs(dkT("DK3_HAVE__SNPRINTF_S = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__SNPRINTF_S = 0\n"), stdout);
+#endif
+#if DK3_HAVE__SNWPRINTF
+ dk3sf_fputs(dkT("DK3_HAVE__SNWPRINTF = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__SNWPRINTF = 0\n"), stdout);
+#endif
+#if DK3_HAVE__SNWPRINTF_S
+ dk3sf_fputs(dkT("DK3_HAVE__SNWPRINTF_S = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__SNWPRINTF_S = 0\n"), stdout);
+#endif
+#if DK3_HAVE__STAT
+ dk3sf_fputs(dkT("DK3_HAVE__STAT = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__STAT = 0\n"), stdout);
+#endif
+#if DK3_HAVE__STAT32
+ dk3sf_fputs(dkT("DK3_HAVE__STAT32 = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__STAT32 = 0\n"), stdout);
+#endif
+#if DK3_HAVE__STAT64
+ dk3sf_fputs(dkT("DK3_HAVE__STAT64 = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__STAT64 = 0\n"), stdout);
+#endif
+#if DK3_HAVE__STRDUP
+ dk3sf_fputs(dkT("DK3_HAVE__STRDUP = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__STRDUP = 0\n"), stdout);
+#endif
+#if DK3_HAVE__STRICMP
+ dk3sf_fputs(dkT("DK3_HAVE__STRICMP = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__STRICMP = 0\n"), stdout);
+#endif
+#if DK3_HAVE__UNLINK
+ dk3sf_fputs(dkT("DK3_HAVE__UNLINK = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__UNLINK = 0\n"), stdout);
+#endif
+#if DK3_HAVE__WCSCAT
+ dk3sf_fputs(dkT("DK3_HAVE__WCSCAT = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__WCSCAT = 0\n"), stdout);
+#endif
+#if DK3_HAVE__WCSCHR
+ dk3sf_fputs(dkT("DK3_HAVE__WCSCHR = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__WCSCHR = 0\n"), stdout);
+#endif
+#if DK3_HAVE__WCSCMP
+ dk3sf_fputs(dkT("DK3_HAVE__WCSCMP = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__WCSCMP = 0\n"), stdout);
+#endif
+#if DK3_HAVE__WCSCPY
+ dk3sf_fputs(dkT("DK3_HAVE__WCSCPY = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__WCSCPY = 0\n"), stdout);
+#endif
+#if DK3_HAVE__WCSDUP
+ dk3sf_fputs(dkT("DK3_HAVE__WCSDUP = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__WCSDUP = 0\n"), stdout);
+#endif
+#if DK3_HAVE__WCSICMP
+ dk3sf_fputs(dkT("DK3_HAVE__WCSICMP = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__WCSICMP = 0\n"), stdout);
+#endif
+#if DK3_HAVE__WCSLEN
+ dk3sf_fputs(dkT("DK3_HAVE__WCSLEN = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__WCSLEN = 0\n"), stdout);
+#endif
+#if DK3_HAVE__WCSNCMP
+ dk3sf_fputs(dkT("DK3_HAVE__WCSNCMP = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__WCSNCMP = 0\n"), stdout);
+#endif
+#if DK3_HAVE__WCSNCPY
+ dk3sf_fputs(dkT("DK3_HAVE__WCSNCPY = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__WCSNCPY = 0\n"), stdout);
+#endif
+#if DK3_HAVE__WCSRCHR
+ dk3sf_fputs(dkT("DK3_HAVE__WCSRCHR = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__WCSRCHR = 0\n"), stdout);
+#endif
+#if DK3_HAVE__WFOPEN_S
+ dk3sf_fputs(dkT("DK3_HAVE__WFOPEN_S = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__WFOPEN_S = 0\n"), stdout);
+#endif
+#if DK3_HAVE__WGETENV
+ dk3sf_fputs(dkT("DK3_HAVE__WGETENV = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__WGETENV = 0\n"), stdout);
+#endif
+#if DK3_HAVE__WRITE
+ dk3sf_fputs(dkT("DK3_HAVE__WRITE = 1\n"), stdout);
+#else
+ dk3sf_fputs(dkT("DK3_HAVE__WRITE = 0\n"), stdout);
+#endif
+ dk3sf_sprintf3(buf, dkT("%u"), (unsigned)(DK3_SIZEOF_SHORT));
+ dk3sf_fputs(dkT("DK3_SIZEOF_SHORT = "), stdout);
+ dk3sf_fputs(buf, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ dk3sf_sprintf3(buf, dkT("%u"), (unsigned)(DK3_SIZEOF_INT));
+ dk3sf_fputs(dkT("DK3_SIZEOF_INT = "), stdout);
+ dk3sf_fputs(buf, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ dk3sf_sprintf3(buf, dkT("%u"), (unsigned)(DK3_SIZEOF_LONG));
+ dk3sf_fputs(dkT("DK3_SIZEOF_LONG = "), stdout);
+ dk3sf_fputs(buf, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ dk3sf_sprintf3(buf, dkT("%u"), (unsigned)(DK3_SIZEOF_SIZE_T));
+ dk3sf_fputs(dkT("DK3_SIZEOF_SIZE_T = "), stdout);
+ dk3sf_fputs(buf, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ dk3sf_sprintf3(buf, dkT("%u"), (unsigned)(DK3_SIZEOF_INTMAX_T));
+ dk3sf_fputs(dkT("DK3_SIZEOF_INTMAX_T = "), stdout);
+ dk3sf_fputs(buf, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ dk3sf_sprintf3(buf, dkT("%u"), (unsigned)(DK3_SIZEOF_LONG_LONG));
+ dk3sf_fputs(dkT("DK3_SIZEOF_LONG_LONG = "), stdout);
+ dk3sf_fputs(buf, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ dk3sf_sprintf3(buf, dkT("%u"), (unsigned)(DK3_SIZEOF_DOUBLE));
+ dk3sf_fputs(dkT("DK3_SIZEOF_DOUBLE = "), stdout);
+ dk3sf_fputs(buf, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ dk3sf_sprintf3(buf, dkT("%u"), (unsigned)(DK3_SIZEOF_LONG_DOUBLE));
+ dk3sf_fputs(dkT("DK3_SIZEOF_LONG_DOUBLE = "), stdout);
+ dk3sf_fputs(buf, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ dk3sf_sprintf3(buf, dkT("%u"), (unsigned)(DK3_SIZEOF_WCHAR_T));
+ dk3sf_fputs(dkT("DK3_SIZEOF_WCHAR_T = "), stdout);
+ dk3sf_fputs(buf, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+}
diff --git a/support/dktools/dk3inst.c b/support/dktools/dk3inst.c
new file mode 100644
index 0000000000..4de3e751e2
--- /dev/null
+++ b/support/dktools/dk3inst.c
@@ -0,0 +1,50 @@
+
+#include "dk3conf.h"
+#include "dk3types.h"
+#include "dk3inst.h"
+
+
+dkChar const * const dk3inst_directories[] = {
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+ /* 0 */ dkT("C:\\Program Files\\Krause"),
+ /* 1 */ dkT("C:\\Program Files\\Krause\\etc"),
+ /* 2 */ dkT("C:\\Program Files\\Krause\\share"),
+ /* 3 */ dkT("C:\\Program Files\\Krause\\var"),
+ /* 4 */ dkT("C:\\Program Files\\Krause\\bin"),
+ /* 5 */ dkT("C:\\Program Files\\Krause\\sbin"),
+ /* 6 */ dkT("C:\\Program Files\\Krause\\lib"),
+ /* 7 */ dkT("C:\\Program Files\\Krause\\include"),
+ /* 8 */ dkT("C:\\Program Files\\Krause\\man"),
+ /* 9 */ dkT("C:\\Program Files\\Krause"),
+ /* 10 */ dkT("C:\\Program Files\\Krause\\libexec"),
+#else
+ /* 0 */ dkT("/usr/local"),
+ /* 1 */ dkT("/usr/local/etc"),
+ /* 2 */ dkT("/usr/local/share"),
+ /* 3 */ dkT("/usr/local/var"),
+ /* 4 */ dkT("/usr/local/bin"),
+ /* 5 */ dkT("/usr/local/sbin"),
+ /* 6 */ dkT("/usr/local/lib"),
+ /* 7 */ dkT("/usr/local/include"),
+ /* 8 */ dkT("/usr/local/share/man"),
+ /* 9 */ dkT("/usr/local"),
+ /* 10 */ dkT("/usr/local/libexec"),
+#endif
+};
+
+
+
+dkChar const *
+dk3inst_get_directory(size_t i)
+/* {{{ */
+{
+ dkChar const *back = NULL;
+ if(i <= 10) { back = dk3inst_directories[i]; }
+ return back;
+}
+/* }}} */
+
+
+
+/* vim: set ai sw=2 filetype=c foldmethod=marker foldopen=all : */
+
diff --git a/support/dktools/dk3inst.h b/support/dktools/dk3inst.h
new file mode 100644
index 0000000000..ef346ae7fa
--- /dev/null
+++ b/support/dktools/dk3inst.h
@@ -0,0 +1,34 @@
+
+/** @file dk3inst.h Get installation directory names.
+ */
+
+#ifndef DK3_INST_H_INCLUDED
+#define DK3_INST_H_INCLUDED 1
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve one directory name.
+* @param i Index of directory in array.
+* 0=prefix (i.e. /usr), 1=system configuration directory
+* (i.e. /etc), 2=data root directory (i.e. /usr/share),
+* 3=local state directory (i.e. /var), 4=binaries directory
+* (i.e. /usr/bin), 5=administrators binaries directory
+* (i.e. /usr/sbin), 6=library directory (i.e. /usr/lib),
+* 7=include directory (i.e. /usr/include), 8=manual directory
+* (i.e. /usr/man), 9=..., 10=libexec directory (i.e. /usr/libexec).
+* @return The directory name on success, NULL on error.
+*/
+/*^null^*/
+/*^dependent^*/
+dkChar const *
+dk3inst_get_directory(size_t i) /*^*/ ;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/support/dktools/dk3kv.c b/support/dktools/dk3kv.c
new file mode 100644
index 0000000000..b623a15eed
--- /dev/null
+++ b/support/dktools/dk3kv.c
@@ -0,0 +1,114 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3kv.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3kv.c The dk3kv module.
+*/
+
+
+#line 43 "dk3kv.ctr"
+
+
+#include "dk3all.h"
+
+
+
+int
+dk3kv_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3_key_value_t const *pl;
+ dk3_key_value_t const *pr;
+ if(l) {
+ if(r) {
+ pl = (dk3_key_value_t const *)l;
+ switch(cr) {
+ case 1: {
+ back = dk3str_cmp(pl->key, (dkChar const *)r);
+ } break;
+ default: {
+ pr = (dk3_key_value_t const *)r;
+ back = dk3str_cmp(pl->key, pr->key);
+ } break;
+ }
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ }
+ return back;
+}
+
+
+
+void
+dk3kv_delete(dk3_key_value_t *p)
+{
+ if(p) {
+ dk3_release(p->key);
+ dk3_release(p->val);
+ dk3_delete(p);
+ }
+}
+
+
+
+dk3_key_value_t *
+dk3kv_new_app(dkChar const *k, dkChar const *v, dk3_app_t *app)
+{
+ dk3_key_value_t *back = NULL;
+ if(k) {
+ back = dk3_new_app(dk3_key_value_t,1,app);
+ if(back) {
+ back->key = NULL;
+ back->val = NULL;
+ back->key = dk3str_dup_app(k, app);
+ if(back->key) {
+ if(v) {
+ back->val = dk3str_dup_app(v, app);
+ if(!(back->val)) {
+ dk3kv_delete(back);
+ back = NULL;
+ }
+ }
+ } else {
+ dk3kv_delete(back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
diff --git a/support/dktools/dk3kv.ctr b/support/dktools/dk3kv.ctr
new file mode 100644
index 0000000000..f7b929a215
--- /dev/null
+++ b/support/dktools/dk3kv.ctr
@@ -0,0 +1,116 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2014-xxxx
+license = bsd
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Compare key value pairs.
+ @param l Left object.
+ @param r Right object.
+ @param cr Comparison criteria (0=object/object, 1=object/string).
+ @return Comparison result
+*/
+int
+dk3kv_compare(void const *l, void const *r, int cr);
+
+/** Remove key value pair, release memory.
+ @param p Key value pair to release.
+*/
+void
+dk3kv_delete(dk3_key_value_t *p);
+
+/** Create new key value pair.
+ @param k Key.
+ @param v Value, may be NULL.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new data on success, NULL on error.
+*/
+dk3_key_value_t *
+dk3kv_new_app(dkChar const *k, dkChar const *v, dk3_app_t *app);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+
+#include "dk3all.h"
+
+
+
+int
+dk3kv_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3_key_value_t const *pl;
+ dk3_key_value_t const *pr;
+ if(l) {
+ if(r) {
+ pl = (dk3_key_value_t const *)l;
+ switch(cr) {
+ case 1: {
+ back = dk3str_cmp(pl->key, (dkChar const *)r);
+ } break;
+ default: {
+ pr = (dk3_key_value_t const *)r;
+ back = dk3str_cmp(pl->key, pr->key);
+ } break;
+ }
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ }
+ return back;
+}
+
+
+
+void
+dk3kv_delete(dk3_key_value_t *p)
+{
+ if(p) {
+ dk3_release(p->key);
+ dk3_release(p->val);
+ dk3_delete(p);
+ }
+}
+
+
+
+dk3_key_value_t *
+dk3kv_new_app(dkChar const *k, dkChar const *v, dk3_app_t *app)
+{
+ dk3_key_value_t *back = NULL;
+ if(k) {
+ back = dk3_new_app(dk3_key_value_t,1,app);
+ if(back) {
+ back->key = NULL;
+ back->val = NULL;
+ back->key = dk3str_dup_app(k, app);
+ if(back->key) {
+ if(v) {
+ back->val = dk3str_dup_app(v, app);
+ if(!(back->val)) {
+ dk3kv_delete(back);
+ back = NULL;
+ }
+ }
+ } else {
+ dk3kv_delete(back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
diff --git a/support/dktools/dk3kv.h b/support/dktools/dk3kv.h
new file mode 100644
index 0000000000..196312819f
--- /dev/null
+++ b/support/dktools/dk3kv.h
@@ -0,0 +1,80 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3kv.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3kv.h Header file for the dk3kv module.
+*/
+
+#ifndef DK3KV_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3KV_H_INCLUDED 1
+
+
+#line 8 "dk3kv.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Compare key value pairs.
+ @param l Left object.
+ @param r Right object.
+ @param cr Comparison criteria (0=object/object, 1=object/string).
+ @return Comparison result
+*/
+int
+dk3kv_compare(void const *l, void const *r, int cr);
+
+/** Remove key value pair, release memory.
+ @param p Key value pair to release.
+*/
+void
+dk3kv_delete(dk3_key_value_t *p);
+
+/** Create new key value pair.
+ @param k Key.
+ @param v Value, may be NULL.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new data on success, NULL on error.
+*/
+dk3_key_value_t *
+dk3kv_new_app(dkChar const *k, dkChar const *v, dk3_app_t *app);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk3ma.h b/support/dktools/dk3ma.h
new file mode 100644
index 0000000000..d0c87c8816
--- /dev/null
+++ b/support/dktools/dk3ma.h
@@ -0,0 +1,72 @@
+
+#ifndef DK3MA_H_INCLUDED
+#define DK3MA_H_INCLUDED 1
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+
+#include <dk3types.h>
+#include <dk3numco.h>
+#include <dk3const.h>
+
+
+
+#include <dk3mas.h>
+#include <dk3maus.h>
+#include <dk3mai.h>
+#include <dk3maui.h>
+#include <dk3mal.h>
+#include <dk3maul.h>
+#include <dk3mad.h>
+#include <dk3madsc.h>
+#include <dk3madic.h>
+#include <dk3madlc.h>
+#include <dk3maid8.h>
+#include <dk3maih8.h>
+#include <dk3maidd.h>
+#include <dk3maihd.h>
+#include <dk3maod8.h>
+#include <dk3maoh8.h>
+#include <dk3maodd.h>
+#include <dk3maohd.h>
+#include <dk3madfo.h>
+#include <dk3madso.h>
+#include <dk3madsi.h>
+
+
+
+/* Yes, there are systems without M_PI or M_PI_2 in math.h */
+
+#ifndef M_PI
+/** Define pi if not already defined in math.h */
+#define M_PI (3.14159265358979323846)
+#endif
+#ifndef M_PI_2
+/** Define 0.5 * pi if not already defined in math.h */
+#define M_PI_2 (1.57079632679489661923)
+#endif
+
+
+
+#endif
+
diff --git a/support/dktools/dk3mad.c b/support/dktools/dk3mad.c
new file mode 100644
index 0000000000..bcc688aee4
--- /dev/null
+++ b/support/dktools/dk3mad.c
@@ -0,0 +1,517 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3mad.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3mad.c The dk3mad module.
+*/
+
+
+#line 161 "dk3mad.ctr"
+
+#include "dk3ma.h"
+#include "dk3const.h"
+
+
+
+
+
+#line 168 "dk3mad.ctr"
+
+
+
+#if (DK3_SIZEOF_DOUBLE == 8) && (DK3_HAVE_IEEE_754_DOUBLE)
+/** Type to construct double value from binary (hex) data.
+*/
+typedef union {
+ unsigned char c[sizeof(double)]; /**< Bytes to specify hex. */
+ double d; /**< Double value to retrieve. */
+} __dk3ma_max_double_t;
+
+/** Maximum double value.
+*/
+__dk3ma_max_double_t const __dk3ma_max_double = {
+#if DK3_WORDS_BIGENDIAN
+ { 0x7F, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
+#else
+ { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0x7F }
+#endif
+};
+/** Maximum double value for internal use.
+*/
+#define dk3ma_i_max_double __dk3ma_max_double.d
+#else
+#ifndef DK3_MAX_DOUBLE
+#define DK3_MAX_DOUBLE 1.7e308
+#endif
+/** Maximum double value for internal use.
+*/
+#define dk3ma_i_max_double DK3_MAX_DOUBLE
+#endif
+
+
+
+double
+dk3ma_d_abs(double x)
+{
+#if DK3_HAVE_FABS
+ return (fabs(x));
+#else
+ return ((0.0 <= x) ? x : (0.0 - x));
+#endif
+}
+
+
+
+double
+dk3ma_d_rint(double x)
+{
+#if DK3_HAVE_RINT
+ return (rint(x));
+#else
+ return (floor(x + 0.5));
+#endif
+}
+
+
+
+double
+dk3ma_d_add_ok(double a, double b, int *ec)
+{
+
+
+#line 230 "dk3mad.ctr"
+ if (NULL != ec) {
+ if ((0.0 < a) && (0.0 < b)) {
+ if ((dk3ma_i_max_double - a) < b) {
+
+
+#line 234 "dk3mad.ctr"
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if ((0.0 > a) && (0.0 > b)) {
+ if ( ( (-1.0 * dk3ma_i_max_double) - a ) > b ) {
+
+
+#line 240 "dk3mad.ctr"
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ }
+ }
+
+#line 245 "dk3mad.ctr"
+ return (a + b);
+}
+
+
+
+double
+dk3ma_d_sub_ok(double a, double b, int *ec)
+{
+
+
+#line 254 "dk3mad.ctr"
+ if (NULL != ec) {
+ if ((0.0 < a) && (0.0 > b)) {
+ if( (dk3ma_i_max_double + b) < a ) {
+
+
+#line 258 "dk3mad.ctr"
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if ((0.0 > a) && (0.0 < b)) {
+ if ( ( (-1.0 * dk3ma_i_max_double) + b ) > a ) {
+
+
+#line 264 "dk3mad.ctr"
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ }
+ }
+
+#line 269 "dk3mad.ctr"
+ return (a - b);
+}
+
+
+
+double
+dk3ma_d_mul_ok(double a, double b, int *ec)
+{
+
+
+#line 278 "dk3mad.ctr"
+ if (ec) {
+ if (dk3ma_d_abs(a) > 1.0) {
+ if ( (dk3ma_i_max_double / dk3ma_d_abs(a)) < dk3ma_d_abs(b) ) {
+
+
+#line 282 "dk3mad.ctr"
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ }
+
+#line 286 "dk3mad.ctr"
+ return (a * b);
+}
+
+
+
+double
+dk3ma_d_div_ok(double a, double b, int *ec)
+{
+#if DK3_HAVE_FPCLASSIFY && defined(FP_ZERO)
+ if (FP_ZERO == fpclassify(b)) {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_DIVZERO; }
+ if (FP_ZERO == fpclassify(a)) {
+ return (NAN);
+ } else {
+ if (0.0 <= a) {
+ return (INFINITY);
+ } else {
+ return (-INFINITY);
+ }
+ }
+ } else {
+ if (dk3ma_d_abs(b) >= 1.0) {
+ return (a / b);
+ } else {
+ if ((dk3ma_i_max_double * dk3ma_d_abs(b)) < dk3ma_d_abs(a)) {
+ if (ec) {
+
+#line 312 "dk3mad.ctr"
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ if (((0.0 <= a) && (0.0 <= b)) || ((0.0 > a) && (0.0 > b))) {
+ return (INFINITY);
+ } else {
+ return (-INFINITY);
+ }
+ } else {
+ return (a / b);
+ }
+ }
+ }
+#else
+#if DK3_ON_WINDOWS
+ switch(_fpclass(b)) {
+ case _FPCLASS_NZ:
+ case _FPCLASS_PZ: {
+ if (ec) {
+
+#line 330 "dk3mad.ctr"
+ *ec = DK3_ERROR_MATH_DIVZERO;
+ }
+ switch(_fpclass(a)) {
+ case _FPCLASS_NZ:
+ case _FPCLASS_PZ: {
+#if defined(NAN)
+ return (NAN);
+#else
+ return (dk3ma_i_max_double);
+#endif
+ } break;
+ default: {
+ if (0.0 <= a) {
+ return (HUGE_VAL);
+ } else {
+ return (-HUGE_VAL);
+ }
+ } break;
+ }
+ } break;
+ default: {
+ if (dk3ma_d_abs(b) >= 1.0) {
+ return (a / b);
+ } else {
+ if ((dk3ma_i_max_double * dk3ma_d_abs(b)) < dk3ma_d_abs(a)) {
+ if (ec) {
+
+#line 356 "dk3mad.ctr"
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ if (((0.0 <= a) && (0.0 <= b)) || ((0.0 > a) && (0.0 > b))) {
+ return (HUGE_VAL);
+ } else {
+ return (-HUGE_VAL);
+ }
+ } else {
+ return (a / b);
+ }
+ }
+ } break;
+ }
+#else
+ if (dk3ma_d_abs(b) >= 1.0) {
+ return (a / b);
+ } else {
+ if ((dk3ma_i_max_double * dk3ma_d_abs(b)) < dk3ma_d_abs(a)) {
+ if (ec) {
+
+#line 375 "dk3mad.ctr"
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ if (((0.0 <= a) && (0.0 <= b)) || ((0.0 > a) && (0.0 > b))) {
+#ifdef INFINITY
+ return (INFINITY);
+#else
+#ifdef HUGE_VAL
+ return (HUGE_VAL);
+#else
+ return (dk3ma_i_max_double);
+#endif
+#endif
+ } else {
+#ifdef INFINITY
+ return (-INFINITY);
+#else
+#ifdef HUGE_VAL
+ return (-HUGE_VAL);
+#else
+ return (-1.0 * dk3ma_i_max_double);
+#endif
+#endif
+ }
+ } else {
+ return (a / b);
+ }
+ }
+#endif
+#endif
+}
+
+
+
+double
+dk3ma_d_square_ok(double x, int *ec)
+{
+#if 0
+ double back = -1.0;
+
+
+#line 414 "dk3mad.ctr"
+ if (0.0 <= x) {
+ back = sqrt(x);
+ } else {
+ if (NULL != ec) {
+
+#line 418 "dk3mad.ctr"
+ *ec = DK3_ERROR_MATH_OUT_OF_RANGE;
+ }
+ }
+
+#line 421 "dk3mad.ctr"
+ return back;
+#else
+ return (dk3ma_d_mul_ok(x, x, ec));
+#endif
+}
+
+
+
+int
+dk3ma_d_equal(double a, double b, double epsilon)
+{
+ int back = 0;
+ int ec = 0;
+ if (dk3ma_d_abs(dk3ma_d_sub_ok(a, b, &ec)) < epsilon) {
+ if (0 == ec) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+double
+dk3ma_d_atan2(double y, double x)
+{
+#if DK3_HAVE_ATAN2
+ double back;
+
+
+#line 450 "dk3mad.ctr"
+ back = atan2(y, x);
+
+#line 451 "dk3mad.ctr"
+ while (back < 0.0) { back += (2.0 * M_PI); }
+ while (back > (2.0 * M_PI)) { back -= (2.0 * M_PI); }
+
+
+#line 454 "dk3mad.ctr"
+ return back;
+#else
+ double back = -5.0 * M_PI;
+ double v;
+
+
+#line 459 "dk3mad.ctr"
+ v = dk3ma_d_div_ok(y, x, &mec);
+ if (mec) {
+
+#line 461 "dk3mad.ctr"
+ if(y < 0.0) {
+
+#line 462 "dk3mad.ctr"
+ back = 1.5 * M_PI;
+ } else {
+
+#line 464 "dk3mad.ctr"
+ back = 0.5 * M_PI;
+ }
+ } else {
+
+#line 467 "dk3mad.ctr"
+ back = atan(v);
+ if (x < 0.0) {
+
+#line 469 "dk3mad.ctr"
+ back += M_PI;
+ }
+ }
+
+#line 472 "dk3mad.ctr"
+ while (back < 0.0) { back += (2.0 * M_PI); }
+ while (back > (2.0 * M_PI)) { back -= (2.0 * M_PI); }
+
+
+#line 475 "dk3mad.ctr"
+ return back;
+#endif
+}
+
+
+
+double
+dk3ma_d_restrict_digits(double x, size_t n)
+{
+ double back;
+ double newval;
+ size_t i;
+ size_t mult;
+ int ec = 0;
+
+ back = x;
+ mult = 0;
+ /* Multiplications
+ */
+ for (i = 0; ((0 == ec) && (i < n)); i++) {
+ newval = dk3ma_d_mul_ok(back, 10.0, &ec);
+ if (0 == ec) {
+ back = newval;
+ mult++;
+ }
+ }
+ /* Rounding
+ */
+ back = dk3ma_d_rint(back);
+ /* Divisions
+ */
+ for (i = 0; i < mult; i++) {
+ back = back / 10.0;
+ }
+ return back;
+}
+
+
+
+double
+dk3ma_d_restrict_digits_ceil(double x, size_t n)
+{
+ double back;
+ double newval;
+ size_t i;
+ size_t mult;
+ int ec = 0;
+
+ back = x;
+ mult = 0;
+ /* Multiplications
+ */
+ for (i = 0; ((0 == ec) && (i < n)); i++) {
+ newval = dk3ma_d_mul_ok(back, 10.0, &ec);
+ if (0 == ec) {
+ back = newval;
+ mult++;
+ }
+ }
+ /* Rounding
+ */
+ back = ceil(back);
+ /* Divisions
+ */
+ for (i = 0; i < mult; i++) {
+ back = back / 10.0;
+ }
+ return back;
+}
+
+
+
+double
+dk3ma_d_restrict_digits_floor(double x, size_t n)
+{
+ double back;
+ double newval;
+ size_t i;
+ size_t mult;
+ int ec = 0;
+
+ back = x;
+ mult = 0;
+ /* Multiplications
+ */
+ for (i = 0; ((0 == ec) && (i < n)); i++) {
+ newval = dk3ma_d_mul_ok(back, 10.0, &ec);
+ if (0 == ec) {
+ back = newval;
+ mult++;
+ }
+ }
+ /* Rounding
+ */
+ back = floor(back);
+ /* Divisions
+ */
+ for (i = 0; i < mult; i++) {
+ back = back / 10.0;
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk3mad.ctr b/support/dktools/dk3mad.ctr
new file mode 100644
index 0000000000..c4fc603930
--- /dev/null
+++ b/support/dktools/dk3mad.ctr
@@ -0,0 +1,577 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2014-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk3mad.h Mathematical operations on double numbers.
+
+Note: You should not use dk3ma_d_add_ok(), dk3ma_d_sub_ok(),
+dk3ma_d_mul_ok(), dk3ma_d_div_ok() and dk3ma_d_div_ok()
+for new programs.
+Perform the calculations traditionally and use the
+functions from the dk3mafpe module to check for floating point exceptions.
+
+*/
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Absolute value.
+ @param x Original value.
+ @return Absolute value of x.
+*/
+double
+dk3ma_d_abs(double x);
+
+/** Rounding to next integer.
+ @param x Double value.
+ @return Value rounded to nearest integer.
+*/
+double
+dk3ma_d_rint(double x);
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Summary of a and b.
+*/
+double
+dk3ma_d_add_ok(double a, double b, int *ec);
+
+/** Substraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Difference of a and b.
+*/
+double
+dk3ma_d_sub_ok(double a, double b, int *ec);
+
+/** Multiplication.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Product of a and b.
+*/
+double
+dk3ma_d_mul_ok(double a, double b, int *ec);
+
+/** Division.
+ @param a Left operand (nominator).
+ @param b Right operand (denominator).
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW or
+ DK3_ERROR_MATH_DIVZERO when returning.
+ @return Fraction of a and b.
+*/
+double
+dk3ma_d_div_ok(double a, double b, int *ec);
+
+/** Square root.
+ @param x Original value.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OUT_OF_RANGE
+ if the input is negative.
+ @return Square root of x.
+*/
+double
+dk3ma_d_square_ok(double x, int *ec);
+
+/** Equality check.
+ @param a Left operand.
+ @param b Right operand.
+ @param epsilon Maximum allowed difference between a and b.
+ @return 1 for equal values, 0 for unequal values.
+*/
+int
+dk3ma_d_equal(double a, double b, double epsilon);
+
+/** Arcus tangens for two lengths.
+ @param y Y length (height).
+ @param x X length (width).
+ @return Angle alpha for y/x = tan(alpha).
+*/
+double
+dk3ma_d_atan2(double y, double x);
+
+/** Restrict number of digits following the decimal dot.
+ @param x Original value.
+ @param n Number of digits after decimal dot.
+ @return Rounded result.
+*/
+double
+dk3ma_d_restrict_digits(double x, size_t n);
+
+/** Restrict number of digits following the decimal dot,
+ round downwards.
+ @param x Original value.
+ @param n Number of digits after decimal dot.
+ @return Rounded result.
+*/
+double
+dk3ma_d_restrict_digits_floor(double x, size_t n);
+
+/** Restrict number of digits following the decimal dot,
+ round upwards.
+ @param x Original value.
+ @param n Number of digits after decimal dot.
+ @return Rounded result.
+*/
+double
+dk3ma_d_restrict_digits_ceil(double x, size_t n);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk3ma.h"
+#include "dk3const.h"
+
+
+
+$!trace-include
+
+
+
+#if (DK3_SIZEOF_DOUBLE == 8) && (DK3_HAVE_IEEE_754_DOUBLE)
+/** Type to construct double value from binary (hex) data.
+*/
+typedef union {
+ unsigned char c[sizeof(double)]; /**< Bytes to specify hex. */
+ double d; /**< Double value to retrieve. */
+} __dk3ma_max_double_t;
+
+/** Maximum double value.
+*/
+__dk3ma_max_double_t const __dk3ma_max_double = {
+#if DK3_WORDS_BIGENDIAN
+ { 0x7F, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
+#else
+ { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0x7F }
+#endif
+};
+/** Maximum double value for internal use.
+*/
+#define dk3ma_i_max_double __dk3ma_max_double.d
+#else
+#ifndef DK3_MAX_DOUBLE
+#define DK3_MAX_DOUBLE 1.7e308
+#endif
+/** Maximum double value for internal use.
+*/
+#define dk3ma_i_max_double DK3_MAX_DOUBLE
+#endif
+
+
+
+double
+dk3ma_d_abs(double x)
+{
+#if DK3_HAVE_FABS
+ return (fabs(x));
+#else
+ return ((0.0 <= x) ? x : (0.0 - x));
+#endif
+}
+
+
+
+double
+dk3ma_d_rint(double x)
+{
+#if DK3_HAVE_RINT
+ return (rint(x));
+#else
+ return (floor(x + 0.5));
+#endif
+}
+
+
+
+double
+dk3ma_d_add_ok(double a, double b, int *ec)
+{
+ $? "+ dk3ma_d_add_ok %lg %lg", a, b
+ if (NULL != ec) {
+ if ((0.0 < a) && (0.0 < b)) {
+ if ((dk3ma_i_max_double - a) < b) {
+ $? "! overflow"
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if ((0.0 > a) && (0.0 > b)) {
+ if ( ( (-1.0 * dk3ma_i_max_double) - a ) > b ) {
+ $? "! overflow"
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ }
+ } $? "- dk3ma_d_add_ok %lg", (a + b)
+ return (a + b);
+}
+
+
+
+double
+dk3ma_d_sub_ok(double a, double b, int *ec)
+{
+ $? "+ dk3ma_d_sub_ok %lg %lg", a, b
+ if (NULL != ec) {
+ if ((0.0 < a) && (0.0 > b)) {
+ if( (dk3ma_i_max_double + b) < a ) {
+ $? "! overflow"
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if ((0.0 > a) && (0.0 < b)) {
+ if ( ( (-1.0 * dk3ma_i_max_double) + b ) > a ) {
+ $? "! overflow"
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ }
+ } $? "- dk3ma_d_sub_ok %lg", (a - b)
+ return (a - b);
+}
+
+
+
+double
+dk3ma_d_mul_ok(double a, double b, int *ec)
+{
+ $? "+ dk3ma_d_mul_ok %lg %lg", a, b
+ if (ec) {
+ if (dk3ma_d_abs(a) > 1.0) {
+ if ( (dk3ma_i_max_double / dk3ma_d_abs(a)) < dk3ma_d_abs(b) ) {
+ $? "! overflow"
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ } $? "- dk3ma_d_mul_ok %lg", (a * b)
+ return (a * b);
+}
+
+
+
+double
+dk3ma_d_div_ok(double a, double b, int *ec)
+{
+#if DK3_HAVE_FPCLASSIFY && defined(FP_ZERO)
+ if (FP_ZERO == fpclassify(b)) {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_DIVZERO; }
+ if (FP_ZERO == fpclassify(a)) {
+ return (NAN);
+ } else {
+ if (0.0 <= a) {
+ return (INFINITY);
+ } else {
+ return (-INFINITY);
+ }
+ }
+ } else {
+ if (dk3ma_d_abs(b) >= 1.0) {
+ return (a / b);
+ } else {
+ if ((dk3ma_i_max_double * dk3ma_d_abs(b)) < dk3ma_d_abs(a)) {
+ if (ec) { $? "= ! division overflow"
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ if (((0.0 <= a) && (0.0 <= b)) || ((0.0 > a) && (0.0 > b))) {
+ return (INFINITY);
+ } else {
+ return (-INFINITY);
+ }
+ } else {
+ return (a / b);
+ }
+ }
+ }
+#else
+#if DK3_ON_WINDOWS
+ switch(_fpclass(b)) {
+ case _FPCLASS_NZ:
+ case _FPCLASS_PZ: {
+ if (ec) { $? "= ! division zero"
+ *ec = DK3_ERROR_MATH_DIVZERO;
+ }
+ switch(_fpclass(a)) {
+ case _FPCLASS_NZ:
+ case _FPCLASS_PZ: {
+#if defined(NAN)
+ return (NAN);
+#else
+ return (dk3ma_i_max_double);
+#endif
+ } break;
+ default: {
+ if (0.0 <= a) {
+ return (HUGE_VAL);
+ } else {
+ return (-HUGE_VAL);
+ }
+ } break;
+ }
+ } break;
+ default: {
+ if (dk3ma_d_abs(b) >= 1.0) {
+ return (a / b);
+ } else {
+ if ((dk3ma_i_max_double * dk3ma_d_abs(b)) < dk3ma_d_abs(a)) {
+ if (ec) { $? "= ! division overflow"
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ if (((0.0 <= a) && (0.0 <= b)) || ((0.0 > a) && (0.0 > b))) {
+ return (HUGE_VAL);
+ } else {
+ return (-HUGE_VAL);
+ }
+ } else {
+ return (a / b);
+ }
+ }
+ } break;
+ }
+#else
+ if (dk3ma_d_abs(b) >= 1.0) {
+ return (a / b);
+ } else {
+ if ((dk3ma_i_max_double * dk3ma_d_abs(b)) < dk3ma_d_abs(a)) {
+ if (ec) { $? "= ! division overflow"
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ if (((0.0 <= a) && (0.0 <= b)) || ((0.0 > a) && (0.0 > b))) {
+#ifdef INFINITY
+ return (INFINITY);
+#else
+#ifdef HUGE_VAL
+ return (HUGE_VAL);
+#else
+ return (dk3ma_i_max_double);
+#endif
+#endif
+ } else {
+#ifdef INFINITY
+ return (-INFINITY);
+#else
+#ifdef HUGE_VAL
+ return (-HUGE_VAL);
+#else
+ return (-1.0 * dk3ma_i_max_double);
+#endif
+#endif
+ }
+ } else {
+ return (a / b);
+ }
+ }
+#endif
+#endif
+}
+
+
+
+double
+dk3ma_d_square_ok(double x, int *ec)
+{
+#if 0
+ double back = -1.0;
+ $? "+ dk3ma_d_square_ok"
+ if (0.0 <= x) {
+ back = sqrt(x);
+ } else {
+ if (NULL != ec) { $? "! out of range"
+ *ec = DK3_ERROR_MATH_OUT_OF_RANGE;
+ }
+ } $? "- dk3ma_d_square_ok %lg", back
+ return back;
+#else
+ return (dk3ma_d_mul_ok(x, x, ec));
+#endif
+}
+
+
+
+int
+dk3ma_d_equal(double a, double b, double epsilon)
+{
+ int back = 0;
+ int ec = 0;
+ if (dk3ma_d_abs(dk3ma_d_sub_ok(a, b, &ec)) < epsilon) {
+ if (0 == ec) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+double
+dk3ma_d_atan2(double y, double x)
+{
+#if DK3_HAVE_ATAN2
+ double back;
+ $? "+ dk3ma_atan2_ok y=%lg x=%lg", y, x
+ back = atan2(y, x); $? ". back = %lg", back
+ while (back < 0.0) { back += (2.0 * M_PI); }
+ while (back > (2.0 * M_PI)) { back -= (2.0 * M_PI); }
+ $? "- dk3ma_atan2_ok (atan2) %lg", back
+ return back;
+#else
+ double back = -5.0 * M_PI;
+ double v;
+ $? "+ dk3ma_atan2_ok y=%lg x=%lg", y, x
+ v = dk3ma_d_div_ok(y, x, &mec);
+ if (mec) { $? "! division error"
+ if(y < 0.0) { $? ". negative y"
+ back = 1.5 * M_PI;
+ } else { $? ". positive y"
+ back = 0.5 * M_PI;
+ }
+ } else { $? ". use atan"
+ back = atan(v);
+ if (x < 0.0) { $? ". add pi"
+ back += M_PI;
+ }
+ } $? ". back = %lg", back
+ while (back < 0.0) { back += (2.0 * M_PI); }
+ while (back > (2.0 * M_PI)) { back -= (2.0 * M_PI); }
+ $? "- dk3ma_atan2_ok (atan) %lg", back
+ return back;
+#endif
+}
+
+
+
+double
+dk3ma_d_restrict_digits(double x, size_t n)
+{
+ double back;
+ double newval;
+ size_t i;
+ size_t mult;
+ int ec = 0;
+
+ back = x;
+ mult = 0;
+ /* Multiplications
+ */
+ for (i = 0; ((0 == ec) && (i < n)); i++) {
+ newval = dk3ma_d_mul_ok(back, 10.0, &ec);
+ if (0 == ec) {
+ back = newval;
+ mult++;
+ }
+ }
+ /* Rounding
+ */
+ back = dk3ma_d_rint(back);
+ /* Divisions
+ */
+ for (i = 0; i < mult; i++) {
+ back = back / 10.0;
+ }
+ return back;
+}
+
+
+
+double
+dk3ma_d_restrict_digits_ceil(double x, size_t n)
+{
+ double back;
+ double newval;
+ size_t i;
+ size_t mult;
+ int ec = 0;
+
+ back = x;
+ mult = 0;
+ /* Multiplications
+ */
+ for (i = 0; ((0 == ec) && (i < n)); i++) {
+ newval = dk3ma_d_mul_ok(back, 10.0, &ec);
+ if (0 == ec) {
+ back = newval;
+ mult++;
+ }
+ }
+ /* Rounding
+ */
+ back = ceil(back);
+ /* Divisions
+ */
+ for (i = 0; i < mult; i++) {
+ back = back / 10.0;
+ }
+ return back;
+}
+
+
+
+double
+dk3ma_d_restrict_digits_floor(double x, size_t n)
+{
+ double back;
+ double newval;
+ size_t i;
+ size_t mult;
+ int ec = 0;
+
+ back = x;
+ mult = 0;
+ /* Multiplications
+ */
+ for (i = 0; ((0 == ec) && (i < n)); i++) {
+ newval = dk3ma_d_mul_ok(back, 10.0, &ec);
+ if (0 == ec) {
+ back = newval;
+ mult++;
+ }
+ }
+ /* Rounding
+ */
+ back = floor(back);
+ /* Divisions
+ */
+ for (i = 0; i < mult; i++) {
+ back = back / 10.0;
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk3mad.h b/support/dktools/dk3mad.h
new file mode 100644
index 0000000000..e32f2e690e
--- /dev/null
+++ b/support/dktools/dk3mad.h
@@ -0,0 +1,193 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3mad.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK3MAD_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3MAD_H_INCLUDED 1
+
+
+#line 10 "dk3mad.ctr"
+
+/** @file dk3mad.h Mathematical operations on double numbers.
+
+Note: You should not use dk3ma_d_add_ok(), dk3ma_d_sub_ok(),
+dk3ma_d_mul_ok(), dk3ma_d_div_ok() and dk3ma_d_div_ok()
+for new programs.
+Perform the calculations traditionally and use the
+functions from the dk3mafpe module to check for floating point exceptions.
+
+*/
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Absolute value.
+ @param x Original value.
+ @return Absolute value of x.
+*/
+double
+dk3ma_d_abs(double x);
+
+/** Rounding to next integer.
+ @param x Double value.
+ @return Value rounded to nearest integer.
+*/
+double
+dk3ma_d_rint(double x);
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Summary of a and b.
+*/
+double
+dk3ma_d_add_ok(double a, double b, int *ec);
+
+/** Substraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Difference of a and b.
+*/
+double
+dk3ma_d_sub_ok(double a, double b, int *ec);
+
+/** Multiplication.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Product of a and b.
+*/
+double
+dk3ma_d_mul_ok(double a, double b, int *ec);
+
+/** Division.
+ @param a Left operand (nominator).
+ @param b Right operand (denominator).
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW or
+ DK3_ERROR_MATH_DIVZERO when returning.
+ @return Fraction of a and b.
+*/
+double
+dk3ma_d_div_ok(double a, double b, int *ec);
+
+/** Square root.
+ @param x Original value.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OUT_OF_RANGE
+ if the input is negative.
+ @return Square root of x.
+*/
+double
+dk3ma_d_square_ok(double x, int *ec);
+
+/** Equality check.
+ @param a Left operand.
+ @param b Right operand.
+ @param epsilon Maximum allowed difference between a and b.
+ @return 1 for equal values, 0 for unequal values.
+*/
+int
+dk3ma_d_equal(double a, double b, double epsilon);
+
+/** Arcus tangens for two lengths.
+ @param y Y length (height).
+ @param x X length (width).
+ @return Angle alpha for y/x = tan(alpha).
+*/
+double
+dk3ma_d_atan2(double y, double x);
+
+/** Restrict number of digits following the decimal dot.
+ @param x Original value.
+ @param n Number of digits after decimal dot.
+ @return Rounded result.
+*/
+double
+dk3ma_d_restrict_digits(double x, size_t n);
+
+/** Restrict number of digits following the decimal dot,
+ round downwards.
+ @param x Original value.
+ @param n Number of digits after decimal dot.
+ @return Rounded result.
+*/
+double
+dk3ma_d_restrict_digits_floor(double x, size_t n);
+
+/** Restrict number of digits following the decimal dot,
+ round upwards.
+ @param x Original value.
+ @param n Number of digits after decimal dot.
+ @return Rounded result.
+*/
+double
+dk3ma_d_restrict_digits_ceil(double x, size_t n);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk3madfo.c b/support/dktools/dk3madfo.c
new file mode 100644
index 0000000000..667ac924c2
--- /dev/null
+++ b/support/dktools/dk3madfo.c
@@ -0,0 +1,227 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3madfo.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3madfo.c The dk3madfo module.
+*/
+
+
+#line 67 "dk3madfo.ctr"
+
+
+
+#include "dk3ma.h"
+#if DK3_HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if DK3_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if DK3_HAVE_STRING_H
+#include <string.h>
+#endif
+#if DK3_HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+
+
+#line 85 "dk3madfo.ctr"
+
+
+
+void
+dk3ma_print_double_c8_str_no_sci(FILE *of, char *buffer)
+{
+ char *start; /* Start of string. */
+ char *eptr; /* Start of exponent substring. */
+ char *ptr; /* Traverse string. */
+ size_t lgt; /* String length. */
+ int dp; /* Decimal dot position. */
+ int exponent; /* Exponent. */
+ int i; /* Traverse the string. */
+
+
+#line 99 "dk3madfo.ctr"
+ if((of) && (buffer)) {
+ eptr = NULL;
+ start = buffer;
+ /*
+ Print sign.
+ */
+ switch(*start) {
+ case '-': {
+ fputc('-', of);
+ start++;
+ } break;
+ case '+': {
+ start++;
+ } break;
+ }
+ /*
+ Find exponent substring and exponent.
+ */
+ eptr = NULL;
+ ptr = start;
+ while(*ptr) {
+ switch(*ptr) {
+ case 'e': case 'E': {
+ eptr = ptr;
+ } break;
+ }
+ ptr++;
+ }
+ if(eptr) {
+ *(eptr++) = '\0';
+#if VERSION_BEFORE_20140716
+ if(sscanf(eptr, "%d", &exponent) != 1)
+#else
+ if (0 == dk3ma_i_from_c8_string(&exponent, eptr, NULL))
+#endif
+ {
+ exponent = 0;
+ }
+ } else {
+ exponent = 0;
+ }
+ /*
+ Find decimal dot.
+ */
+ eptr = strchr(start, '.');
+ if(eptr) {
+ /*
+ Keep dot position in dp, squeeze string.
+ */
+ *eptr = '\0';
+ dp = (int)strlen(start);
+ *eptr = '.';
+ while(*eptr) {
+ eptr[0] = eptr[1];
+ eptr++;
+ }
+ } else {
+ /*
+ Dot position is after the string.
+ */
+ dp = (int)strlen(start);
+ }
+ /*
+ Correct dot position.
+ */
+ dp = dp + exponent;
+ /*
+ Remove leading zeroes (if any).
+ */
+ while('0' == *start) {
+ start++; dp--;
+ }
+ /*
+ Remove trailing zeroes (if any).
+ */
+ eptr = NULL;
+ ptr = start;
+ while(*ptr) {
+ if('0' == *ptr) {
+ if(!(eptr)) { eptr = ptr; }
+ } else {
+ eptr = NULL;
+ }
+ ptr++;
+ }
+ if(eptr) { *eptr = '\0'; }
+ lgt = strlen(start);
+ if(0 < lgt) {
+ if(dp >= (int)lgt) {
+ /*
+ Decimal dot is at end or after string.
+ */
+ fputs(start, of);
+ /*
+ Decimal dot is after the string.
+ */
+ for(i = 0; i < (dp - (int)lgt); i++) {
+ fputc('0', of);
+ }
+ } else {
+ if(dp <= 0) {
+ /*
+ Decimal dot is before the string.
+ */
+ fputc('0', of);
+ fputc('.', of);
+ while(dp++ < 0) {
+ fputc('0', of);
+ }
+ fputs(start, of);
+ } else {
+ /*
+ Decimal dot is in the string.
+ */
+ for(i = 0; i < (int)lgt; i++) {
+ if(dp == i) {
+ fputc('.', of);
+ }
+ fputc(start[i], of);
+ }
+ }
+ }
+ } else {
+ /*
+ No non-zero digits in string.
+ */
+ fputc('0', of);
+ }
+ }
+
+#line 228 "dk3madfo.ctr"
+}
+
+
+
+void
+dk3ma_print_double_c8_no_sci(FILE *of, double x)
+{
+ char buffer[64];
+
+
+#line 237 "dk3madfo.ctr"
+ if(of) {
+ sprintf(buffer, "%g", x);
+ dk3ma_print_double_c8_str_no_sci(of, buffer);
+ }
+
+#line 241 "dk3madfo.ctr"
+}
+
+
diff --git a/support/dktools/dk3madfo.ctr b/support/dktools/dk3madfo.ctr
new file mode 100644
index 0000000000..ff2f98eb6d
--- /dev/null
+++ b/support/dktools/dk3madfo.ctr
@@ -0,0 +1,243 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2014-xxxx
+license = bsd
+
+
+%% header
+
+/** @file dk3madfo.h Output functions for double values.
+*/
+
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Print floating point value specified as string to
+ output file, avoid exponential notation.
+ @param of Output file.
+ @param buffer Buffer containing string representation of
+ value, probably in scientific notatation. The buffer content
+ is modified by this function.
+ The string represenation should be built using
+ sprintf(buffer, "%lg", value).
+*/
+void
+dk3ma_print_double_c8_str_no_sci(FILE *of, char *buffer);
+
+/** Print floating point value to output file,
+ avoid exponential notation.
+ @param of Output file.
+ @param x Value to print.
+*/
+void
+dk3ma_print_double_c8_no_sci(FILE *of, double x);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+
+
+#include "dk3ma.h"
+#if DK3_HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if DK3_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if DK3_HAVE_STRING_H
+#include <string.h>
+#endif
+#if DK3_HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+$!trace-include
+
+
+
+void
+dk3ma_print_double_c8_str_no_sci(FILE *of, char *buffer)
+{
+ char *start; /* Start of string. */
+ char *eptr; /* Start of exponent substring. */
+ char *ptr; /* Traverse string. */
+ size_t lgt; /* String length. */
+ int dp; /* Decimal dot position. */
+ int exponent; /* Exponent. */
+ int i; /* Traverse the string. */
+ $? "+ dk3ma_print_double_c8_str_no_sci"
+ if((of) && (buffer)) {
+ eptr = NULL;
+ start = buffer;
+ /*
+ Print sign.
+ */
+ switch(*start) {
+ case '-': {
+ fputc('-', of);
+ start++;
+ } break;
+ case '+': {
+ start++;
+ } break;
+ }
+ /*
+ Find exponent substring and exponent.
+ */
+ eptr = NULL;
+ ptr = start;
+ while(*ptr) {
+ switch(*ptr) {
+ case 'e': case 'E': {
+ eptr = ptr;
+ } break;
+ }
+ ptr++;
+ }
+ if(eptr) {
+ *(eptr++) = '\0';
+#if VERSION_BEFORE_20140716
+ if(sscanf(eptr, "%d", &exponent) != 1)
+#else
+ if (0 == dk3ma_i_from_c8_string(&exponent, eptr, NULL))
+#endif
+ {
+ exponent = 0;
+ }
+ } else {
+ exponent = 0;
+ }
+ /*
+ Find decimal dot.
+ */
+ eptr = strchr(start, '.');
+ if(eptr) {
+ /*
+ Keep dot position in dp, squeeze string.
+ */
+ *eptr = '\0';
+ dp = (int)strlen(start);
+ *eptr = '.';
+ while(*eptr) {
+ eptr[0] = eptr[1];
+ eptr++;
+ }
+ } else {
+ /*
+ Dot position is after the string.
+ */
+ dp = (int)strlen(start);
+ }
+ /*
+ Correct dot position.
+ */
+ dp = dp + exponent;
+ /*
+ Remove leading zeroes (if any).
+ */
+ while('0' == *start) {
+ start++; dp--;
+ }
+ /*
+ Remove trailing zeroes (if any).
+ */
+ eptr = NULL;
+ ptr = start;
+ while(*ptr) {
+ if('0' == *ptr) {
+ if(!(eptr)) { eptr = ptr; }
+ } else {
+ eptr = NULL;
+ }
+ ptr++;
+ }
+ if(eptr) { *eptr = '\0'; }
+ lgt = strlen(start);
+ if(0 < lgt) {
+ if(dp >= (int)lgt) {
+ /*
+ Decimal dot is at end or after string.
+ */
+ fputs(start, of);
+ /*
+ Decimal dot is after the string.
+ */
+ for(i = 0; i < (dp - (int)lgt); i++) {
+ fputc('0', of);
+ }
+ } else {
+ if(dp <= 0) {
+ /*
+ Decimal dot is before the string.
+ */
+ fputc('0', of);
+ fputc('.', of);
+ while(dp++ < 0) {
+ fputc('0', of);
+ }
+ fputs(start, of);
+ } else {
+ /*
+ Decimal dot is in the string.
+ */
+ for(i = 0; i < (int)lgt; i++) {
+ if(dp == i) {
+ fputc('.', of);
+ }
+ fputc(start[i], of);
+ }
+ }
+ }
+ } else {
+ /*
+ No non-zero digits in string.
+ */
+ fputc('0', of);
+ }
+ } $? "- dk3ma_print_double_c8_str_no_sci"
+}
+
+
+
+void
+dk3ma_print_double_c8_no_sci(FILE *of, double x)
+{
+ char buffer[64];
+ $? "+ dk3ma_print_double_c8_no_sci"
+ if(of) {
+ sprintf(buffer, "%g", x);
+ dk3ma_print_double_c8_str_no_sci(of, buffer);
+ } $? "- dk3ma_print_double_c8_no_sci"
+}
+
+
diff --git a/support/dktools/dk3madfo.h b/support/dktools/dk3madfo.h
new file mode 100644
index 0000000000..b6049f6b27
--- /dev/null
+++ b/support/dktools/dk3madfo.h
@@ -0,0 +1,100 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3madfo.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK3MADFO_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3MADFO_H_INCLUDED 1
+
+
+#line 9 "dk3madfo.ctr"
+
+/** @file dk3madfo.h Output functions for double values.
+*/
+
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Print floating point value specified as string to
+ output file, avoid exponential notation.
+ @param of Output file.
+ @param buffer Buffer containing string representation of
+ value, probably in scientific notatation. The buffer content
+ is modified by this function.
+ The string represenation should be built using
+ sprintf(buffer, "%lg", value).
+*/
+void
+dk3ma_print_double_c8_str_no_sci(FILE *of, char *buffer);
+
+/** Print floating point value to output file,
+ avoid exponential notation.
+ @param of Output file.
+ @param x Value to print.
+*/
+void
+dk3ma_print_double_c8_no_sci(FILE *of, double x);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3madic.c b/support/dktools/dk3madic.c
new file mode 100644
index 0000000000..8168f0748e
--- /dev/null
+++ b/support/dktools/dk3madic.c
@@ -0,0 +1,91 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3madic.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3madic.c The dk3madic module.
+*/
+
+
+#line 64 "dk3madic.ctr"
+
+
+
+#include "dk3ma.h"
+
+
+
+
+
+#line 72 "dk3madic.ctr"
+
+
+
+int
+dk3ma_d_to_i_ok(double x, int *ec)
+{
+ int back = 0;
+ if ((double)DK3_I_MIN <= x) {
+ if ((double)DK3_I_MAX >= x) {
+ back = (int)x;
+ } else {
+ back = DK3_I_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ back = DK3_I_MIN;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ return back;
+}
+
+
+
+unsigned
+dk3ma_d_to_u_ok(double x, int *ec)
+{
+ unsigned back = 0U;
+ if (0.0 <= x) {
+ if ((double)DK3_U_MAX >= x) {
+ back = (unsigned)x;
+ } else {
+ back = DK3_U_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OUT_OF_RANGE; }
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk3madic.ctr b/support/dktools/dk3madic.ctr
new file mode 100644
index 0000000000..cc3360658d
--- /dev/null
+++ b/support/dktools/dk3madic.ctr
@@ -0,0 +1,112 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2014-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk3madic.h Conversion from double to int/unsigned.
+*/
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert double value to int.
+ @param x Double value to convert.
+ @param ec Pointer to error code variable.
+ Set to DK3_ERROR_MATH_OVERFLOW if the absolute value of x is too large.
+ @return Conversion result.
+*/
+int
+dk3ma_d_to_i_ok(double x, int *ec);
+
+/** Convert double value to unsigned.
+ @param x Double value to convert.
+ @param ec Pointer to error code variable.
+ Set to DK3_ERROR_MATH_OVERFLOW if the absolute value of x is too large,
+ DK3_ERROR_MATH_OUT_OF_RANGE for negative x.
+ @return Conversion result.
+*/
+unsigned
+dk3ma_d_to_u_ok(double x, int *ec);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+
+
+#include "dk3ma.h"
+
+
+
+$!trace-include
+
+
+
+int
+dk3ma_d_to_i_ok(double x, int *ec)
+{
+ int back = 0;
+ if ((double)DK3_I_MIN <= x) {
+ if ((double)DK3_I_MAX >= x) {
+ back = (int)x;
+ } else {
+ back = DK3_I_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ back = DK3_I_MIN;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ return back;
+}
+
+
+
+unsigned
+dk3ma_d_to_u_ok(double x, int *ec)
+{
+ unsigned back = 0U;
+ if (0.0 <= x) {
+ if ((double)DK3_U_MAX >= x) {
+ back = (unsigned)x;
+ } else {
+ back = DK3_U_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OUT_OF_RANGE; }
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk3madic.h b/support/dktools/dk3madic.h
new file mode 100644
index 0000000000..30fe041b7a
--- /dev/null
+++ b/support/dktools/dk3madic.h
@@ -0,0 +1,96 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3madic.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK3MADIC_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3MADIC_H_INCLUDED 1
+
+
+#line 10 "dk3madic.ctr"
+
+/** @file dk3madic.h Conversion from double to int/unsigned.
+*/
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert double value to int.
+ @param x Double value to convert.
+ @param ec Pointer to error code variable.
+ Set to DK3_ERROR_MATH_OVERFLOW if the absolute value of x is too large.
+ @return Conversion result.
+*/
+int
+dk3ma_d_to_i_ok(double x, int *ec);
+
+/** Convert double value to unsigned.
+ @param x Double value to convert.
+ @param ec Pointer to error code variable.
+ Set to DK3_ERROR_MATH_OVERFLOW if the absolute value of x is too large,
+ DK3_ERROR_MATH_OUT_OF_RANGE for negative x.
+ @return Conversion result.
+*/
+unsigned
+dk3ma_d_to_u_ok(double x, int *ec);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk3madlc.c b/support/dktools/dk3madlc.c
new file mode 100644
index 0000000000..88257f1a07
--- /dev/null
+++ b/support/dktools/dk3madlc.c
@@ -0,0 +1,706 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3madlc.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3madlc.c The dk3madlc module.
+*/
+
+
+#line 142 "dk3madlc.ctr"
+
+
+
+#include "dk3ma.h"
+
+
+
+
+
+#line 150 "dk3madlc.ctr"
+
+
+
+/* formerly DK3_HAVE_COMPILER_CONVERSIONS */
+#if 1
+
+
+
+size_t
+dk3ma_d_to_sz_ok(double v, int *ec)
+{
+ size_t back = 0;
+
+
+#line 163 "dk3madlc.ctr"
+ if (0.0 <= v) {
+ if ((double)DK3_SIZE_T_MAX >= v) {
+
+#line 165 "dk3madlc.ctr"
+ back = (size_t)v;
+ } else {
+ if (NULL != ec) {
+
+#line 168 "dk3madlc.ctr"
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ } else {
+ if (NULL != ec) {
+
+#line 173 "dk3madlc.ctr"
+ *ec = DK3_ERROR_MATH_OUT_OF_RANGE;
+ }
+ }
+
+#line 176 "dk3madlc.ctr"
+ return back;
+}
+
+
+
+long
+dk3ma_d_to_l_ok(double x, int *ec)
+{
+ long back = 0L;
+
+
+#line 186 "dk3madlc.ctr"
+ if ((double)DK3_L_MIN <= x) {
+ if ((double)DK3_L_MAX >= x) {
+ back = (long)x;
+ } else {
+ back = DK3_L_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ back = DK3_L_MIN;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+
+#line 197 "dk3madlc.ctr"
+ return back;
+}
+
+
+
+unsigned long
+dk3ma_d_to_ul_ok(double x, int *ec)
+{
+ unsigned long back = 0UL;
+
+
+#line 207 "dk3madlc.ctr"
+ if (0.0 <= x) {
+ if ((double)DK3_UL_MAX >= x) {
+ back = (unsigned long)x;
+ } else {
+ back = DK3_UL_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OUT_OF_RANGE; }
+ }
+ } else {
+ back = 0UL;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OUT_OF_RANGE; }
+ }
+
+#line 218 "dk3madlc.ctr"
+ return back;
+}
+
+
+
+#if DK3_HAVE_LONG_LONG
+
+long long
+dk3ma_d_to_ll_ok(double x, int *ec)
+{
+ long long back = 0LL;
+
+
+#line 230 "dk3madlc.ctr"
+ if ((double)DK3_LL_MIN <= x) {
+ if ((double)DK3_LL_MAX >= x) {
+ back = (long long)x;
+ } else {
+ back = DK3_LL_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ back = DK3_LL_MIN;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+
+#line 241 "dk3madlc.ctr"
+ return back;
+}
+
+
+
+unsigned long long
+dk3ma_d_to_ull_ok(double x, int *ec)
+{
+ unsigned long long back = 0ULL;
+
+
+#line 251 "dk3madlc.ctr"
+ if (0.0 <= x) {
+ if ((double)DK3_ULL_MAX >= x) {
+ back = (unsigned long long)x;
+ } else {
+ back = DK3_ULL_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OUT_OF_RANGE; }
+ }
+
+#line 261 "dk3madlc.ctr"
+ return back;
+}
+
+#endif
+
+
+#if DK3_HAVE_INTMAX_T
+
+intmax_t
+dk3ma_d_to_intmax_t_ok(double x, int *ec)
+{
+ intmax_t back = DK3_INTMAX_T_0;
+
+
+#line 274 "dk3madlc.ctr"
+ if ((double)DK3_INTMAX_T_MIN <= x) {
+ if ((double)DK3_INTMAX_T_MAX >= x) {
+ back = (intmax_t)x;
+ } else {
+ back = DK3_INTMAX_T_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ back = DK3_INTMAX_T_MIN;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+
+#line 285 "dk3madlc.ctr"
+ return back;
+}
+
+
+
+uintmax_t
+dk3ma_d_to_uintmax_t_ok(double x, int *ec)
+{
+ uintmax_t back = DK3_UINTMAX_T_0;
+
+
+#line 295 "dk3madlc.ctr"
+ if (0.0 <= x) {
+ if ((double)DK3_UINTMAX_T_MAX >= x) {
+ back = (uintmax_t)x;
+ } else {
+ back = DK3_UINTMAX_T_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OUT_OF_RANGE; }
+ }
+
+#line 305 "dk3madlc.ctr"
+ return back;
+}
+
+#endif
+
+
+
+dk3_im_t
+dk3ma_d_to_im_ok(double x, int *ec)
+{
+#if DK3_HAVE_INTMAX_T
+ return (dk3ma_d_to_intmax_t_ok(x, ec));
+#else
+#if DK3_HAVE_LONG_LONG
+ return (dk3ma_d_to_ll_ok(x, ec));
+#else
+ return (dk3ma_d_to_l_ok(x, ec));
+#endif
+#endif
+}
+
+
+
+dk3_um_t
+dk3ma_d_to_um_ok(double x, int *ec)
+{
+#if DK3_HAVE_INTMAX_T
+ return (dk3ma_d_to_uintmax_t_ok(x, ec));
+#else
+#if DK3_HAVE_LONG_LONG
+ return (dk3ma_d_to_ull_ok(x, ec));
+#else
+ return (dk3ma_d_to_ul_ok(x, ec));
+#endif
+#endif
+}
+
+
+
+#else
+/* if 1, formerly if DK3_HAVE_COMPILER_CONVERSIONS */
+
+
+/* If you see the error message below during build process, you have
+ disabled compiler conversions when running the configure script.
+ During the last 10 year I did not see any compiler doing
+ type casts from double to integers wrong, so the default is to
+ enable compiler conversions.
+ If you are really sure your compiler is doing type casts from
+ double to integer types wrong, remove the error compiler directive
+ below.
+ Note: The code for manual conversion from double to integers
+ is not well-tested as on all my systems the compilers type casts
+ do fine. Make sure you know what you are doing.
+*/
+#error "Compiler conversions turned off! See comment section above!"
+
+
+
+#if DK3_HAVE_INTMAX_T
+/* + uintmax_t */
+#if DK3_SIZEOF_INTMAX_T > 2
+#if DK3_SIZEOF_INTMAX_T > 4
+#if DK3_SIZEOF_INTMAX_T > 8
+#error "Can not handle such a large uintmax_t!"
+#else
+/* 8 */
+#if DK3_HAVE_LONG_LONG
+/** First bit of a dk3_um_t.
+*/
+#define DK3_UM_FIRST_BIT (9223372036854775808ULL)
+#else
+/** First bit of a dk3_um_t.
+*/
+#define DK3_UM_FIRST_BIT (9223372036854775808UL)
+#endif
+/** First bit of a dk3_um_t written as double.
+*/
+#define DK3_UM_FIRST_DOUBLE (9223372036854775808.0)
+#endif
+#else
+/* 4 */
+#if DK3_HAVE_LONG_LONG
+/** First bit of a dk3_um_t.
+*/
+#define DK3_UM_FIRST_BIT (2147483648ULL)
+#else
+/** First bit of a dk3_um_t.
+*/
+#define DK3_UM_FIRST_BIT (2147483648UL)
+#endif
+/** First bit of a dk3_um_t written as double.
+*/
+#define DK3_UM_FIRST_DOUBLE (2147483648.0)
+#endif
+#else
+/* 2 */
+#if DK3_HAVE_LONG_LONG
+/** First bit of a dk3_um_t.
+*/
+#define DK3_UM_FIRST_BIT (32768ULL)
+#else
+/** First bit of a dk3_um_t.
+*/
+#define DK3_UM_FIRST_BIT (32768UL)
+#endif
+/** First bit of a dk3_um_t written as double.
+*/
+#define DK3_UM_FIRST_DOUBLE (32768.0)
+#endif
+/* - uintmax_t */
+#else
+#if DK3_HAVE_LONG_LONG
+/* + unsigned long long */
+#if DK3_SIZEOF_LONG_LONG > 2
+#if DK3_SIZEOF_LONG_LONG > 4
+#if DK3_SIZEOF_LONG_LONG > 8
+#error "Can not handle such a large unsigned long long!"
+#else
+/* 8 */
+/** First bit of a dk3_um_t.
+*/
+#define DK3_UM_FIRST_BIT (9223372036854775808ULL)
+/** First bit of a dk3_um_t written as double.
+*/
+#define DK3_UM_FIRST_DOUBLE (9223372036854775808.0)
+#endif
+#else
+/* 4 */
+/** First bit of a dk3_um_t.
+*/
+#define DK3_UM_FIRST_BIT (2147483648ULL)
+/** First bit of a dk3_um_t written as double.
+*/
+#define DK3_UM_FIRST_DOUBLE (2147483648.0)
+#endif
+#else
+/* 2*/
+/** First bit of a dk3_um_t.
+*/
+#define DK3_UM_FIRST_BIT (32768ULL)
+/** First bit of a dk3_um_t written as double.
+*/
+#define DK3_UM_FIRST_DOUBLE (32768.0)
+#endif
+/* - unsigned long long */
+#else
+/* + unsigned long */
+#if DK3_SIZEOF_LONG > 2
+#if DK3_SIZEOF_LONG > 4
+#if DK3_SIZEOF_LONG > 8
+#error "Can not handle such a large unsigned long!"
+#else
+/* 8 */
+/** First bit of a dk3_um_t.
+*/
+#define DK3_UM_FIRST_BIT (9223372036854775808UL)
+/** First bit of a dk3_um_t written as double.
+*/
+#define DK3_UM_FIRST_DOUBLE (9223372036854775808.0)
+#endif
+#else
+/* 4 */
+#define DK3_UM_FIRST_BIT (2147483648UL)
+#define DK3_UM_FIRST_DOUBLE (2147483648.0)
+#endif
+#else
+/* 2 */
+/** First bit of a dk3_um_t.
+*/
+#define DK3_UM_FIRST_BIT (32768UL)
+/** First bit of a dk3_um_t written as double.
+*/
+#define DK3_UM_FIRST_DOUBLE (32768.0)
+#endif
+/* - unsigned long */
+#endif
+#endif
+
+
+
+/** Constant value 2 as dk3_um_t.
+*/
+static dk3_um_t const dk3ma_um2 =
+#if DK3_HAVE_LONG_LONG
+ (dk3_um_t)2ULL
+#else
+ (dk3_um_t)2UL
+#endif
+;
+
+
+dk3_um_t
+dk3ma_d_to_um_ok(double x, int *ec)
+{
+ dk3_um_t back = DK3_UM_0;
+ dk3_um_t testu;
+ double testd;
+
+
+#line 504 "dk3madlc.ctr"
+ if (0.0 <= x) {
+#if DK3_HAVE_LONG_DOUBLE
+ if ((long double)DK3_UM_MAX >= (long double)x)
+#else
+ if ((double)DK3_UM_MAX >= x)
+#endif
+ {
+ testd = DK3_UM_FIRST_DOUBLE;
+ testu = DK3_UM_FIRST_BIT;
+ for (i = 0; i < (8 * DK3_SIZEOF_UM); i++) {
+ if (x >= testd) {
+ x = x - testd;
+ back = back + testu;
+ }
+ testd = testd / 2.0;
+ testu = testu / dk3ma_um2;
+ }
+ }
+ else
+ {
+ back = DK3_UM_MAX
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OUT_OF_RANGE; }
+ }
+
+
+#line 531 "dk3madlc.ctr"
+ return back;
+}
+
+
+
+dk3_im_t
+dk3ma_d_to_im_ok(double x, int *ec)
+{
+ dk3_im_t back = DK3_IM_0;
+ dk3_um_t tmp;
+ int mec = 0;
+
+ if (x >= 0.0) {
+ tmp = dk3ma_d_to_um_ok(x, &mec);
+ if (0 == mec) {
+ if ((dk3_um_t)DK3_IM_MAX >= tmp) {
+ back = (dk3_im_t)tmp;
+ } else {
+ back = DK3_IM_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ if (NULL != ec) { *ec = mec; }
+ }
+ } else {
+ if ((double)DK3_IM_MIN > x) {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ back = DK3_IM_MIN;
+ } else {
+ if ((double)(-DK3_IM_MAX) > x) {
+ back = DK3_IM_MIN;
+ } else {
+ tmp = dk3ma_d_to_um_ok((0.0 - x), &mec);
+ if (0 == mec) {
+ if ((dk3_um_t)DK3_IM_MAX >= tmp) {
+ back = DK3_IM_0 - (dk3_im_t)tmp;
+ } else {
+ back = DK3_IM_MIN;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ if (NULL != ec) { *ec = mec; }
+ }
+ }
+ }
+ }
+}
+
+
+
+#if DK3_HAVE_INTMAX_T
+
+uintmax_t
+dk3ma_d_to_uintmax_t_ok(double x, int *ec)
+{
+ return (dk3ma_d_to_um_ok(x, ec));
+}
+
+intmax_t
+dk3ma_d_to_intmax_t_ok(double x, int *ec)
+{
+ return (dk3ma_d_to_im_ok(x, ec));
+}
+
+#endif
+
+
+
+#if DK3_HAVE_LONG_LONG
+
+unsigned long long
+dk3ma_d_to_ull_ok(double x, int *ec)
+{
+#if (!(DK3_HAVE_INTMAX_T))
+ return (dk3ma_d_to_um_ok(x, ec));
+#else
+ dk3_um_t tmp;
+ unsigned long long back = 0ULL;
+ int mec = 0;
+ if (0.0 <= x) {
+ tmp = dk3ma_d_to_um_ok(x, &mec);
+ if (0 == mec) {
+#if DK3_SIZEOF_LONG_LONG >= DK3_SIZEOF_UM
+ back = (unsigned long long)tmp;
+#else
+ if ((dk3_um_t)DK3_ULL_MAX >= tmp) {
+ back = (unsigned long long)tmp;
+ } else {
+ back = DK3_ULL_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+#endif
+ } else {
+ if (NULL != ec) { *ec = mec; }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OUT_OF_RANGE; }
+ }
+ return back;
+#endif
+}
+
+
+
+long long
+dk3ma_d_to_ll_ok(double x, int *ec)
+{
+#if (!(DK3_HAVE_INTMAX_T))
+ return (dk3ma_d_to_im_ok(x, ec));
+#else
+ dk3_im_t tmp;
+ long long back = 0LL;
+ int mec = 0;
+
+ tmp = dk3ma_d_to_im_ok(x, &mec);
+ if (0 == mec) {
+#if DK3_SIZEOF_LONG_LONG >= DK3_SIZEOF_UM
+ back = (long long)tmp;
+#else
+ if ((dk3_im_t)DK3_LL_MIN <= tmp) {
+ if ((dk3_im_t)DK3_LL_MAX >= tmp) {
+ back = (long long)tmp;
+ } else {
+ back = DK3_LL_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ back = DK3_LL_MIN;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+#endif
+ } else {
+ if (NULL != ec) { *ec = mec; }
+ }
+#endif
+}
+
+#endif
+
+
+
+unsigned long
+dk3ma_d_to_ul_ok(double x, int *ec)
+{
+#if (!((DK3_HAVE_INTMAX_T) || (DK3_HAVE_LONG_LONG)))
+ return (dk3ma_d_to_um_ok(x, ec));
+#else
+ dk3_um_t tmp;
+ unsigned long back = 0UL;
+ int mec = 0;
+
+ tmp = dk3ma_d_to_um_ok(x, &mec);
+ if (0 == mec) {
+#if DK3_SIZEOF_LONG >= DK3_SIZEOF_UM
+ back = (unsigned long)tmp;
+#else
+ if ((dk3_um_t)DK3_UL_MAX >= tmp) {
+ back = (unsigned long)tmp;
+ } else {
+ back = DK3_UL_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+#endif
+ } else {
+ if (NULL != ec) { *ec = mec; }
+ }
+ return back;
+#endif
+}
+
+
+
+long
+dk3ma_d_to_l_ok(double x, int *ec)
+{
+#if (!((DK3_HAVE_INTMAX_T) || (DK3_HAVE_LONG_LONG)))
+ return (dk3ma_d_to_im_ok(x, ec));
+#else
+ dk3_im_t tmp;
+ long back = 0L;
+ int mec = 0;
+ tmp = dk3ma_d_to_im_ok(x, &mec);
+ if (0 == mec) {
+#if DK3_SIZEOF_LONG >= DK3_SIZEOF_UM
+ back = (long)tmp;
+#else
+ if ((dk3_im_t)DK3_L_MIN <= tmp) {
+ if ((dk3_im_t)DK3_L_MAX >= tmp) {
+ back = (dk3_im_t)tmp;
+ } else {
+ back = DK3_L_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ back = DK3_L_MIN;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+#endif
+ } else {
+ if (NULL != ec) { *ec = mec; }
+ }
+ return back;
+#endif
+}
+
+
+
+size_t
+dk3ma_d_to_sz_ok(double v, int *ec)
+{
+ dk3_um_t tmp;
+ size_t back = 0;
+ int mec = 0;
+
+ tmp = dk3ma_d_to_um_ok(v, &mec);
+ if (0 == mec) {
+#if DK3_SIZEOF_SIZE_T >= DK3_SIZEOF_UM
+ back = (size_t)tmp;
+#else
+ if ((dk3_um_t)DK3_SIZE_T_MAX >= tmp) {
+ back = (size_t)tmp;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+#endif
+ } else {
+ if (NULL != ec) { *ec = mec; }
+ }
+ return back;
+}
+
+
+
+#endif
+/* if 1, formerly if DK3_HAVE_COMPILER_CONVERSIONS */
+
+
diff --git a/support/dktools/dk3madlc.ctr b/support/dktools/dk3madlc.ctr
new file mode 100644
index 0000000000..4417aa426a
--- /dev/null
+++ b/support/dktools/dk3madlc.ctr
@@ -0,0 +1,767 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2014-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk3madlc.h Conversion from double to long,
+ unsigned long, long long, unsigned long long, intmax_t, uintmax_t,
+ dk3_im_t and dk3_um_t.
+*/
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert double number to size.
+ @param v Value to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_MATH_OUT_OF_RANGE for negative v values,
+ DK3_ERROR_MATH_OVERFLOW for values too large.
+ @return Conversion result.
+*/
+size_t
+dk3ma_d_to_sz_ok(double v, int *ec);
+
+/** Convert double value to long.
+ @param x Double value.
+ @param ec Pointer to error code variable.
+ Set to DK3_ERROR_MATH_OVERFLOW if the absolute value is too large.
+ @return Conversion result.
+*/
+long
+dk3ma_d_to_l_ok(double x, int *ec);
+
+/** Convert double value to unsigned long.
+ @param x Double value.
+ @param ec Pointer to error code variable.
+ Set to DK3_ERROR_MATH_OUT_OF_RANGE for negative v values,
+ DK3_ERROR_MATH_OVERFLOW for values too large.
+ @return Conversion result.
+*/
+unsigned long
+dk3ma_d_to_ul_ok(double x, int *ec);
+
+#if DK3_HAVE_LONG_LONG
+
+/** Convert double to long long.
+ @param x Value to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_MATH_OVERFLOW if the absolute value is too large.
+ @return Conversion result.
+*/
+long long
+dk3ma_d_to_ll_ok(double x, int *ec);
+
+/** Convert double to unsigned long long.
+ @param x Value to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_MATH_OUT_OF_RANGE for negative v values,
+ DK3_ERROR_MATH_OVERFLOW for values too large.
+ @return Conversion result.
+*/
+unsigned long long
+dk3ma_d_to_ull_ok(double x, int *ec);
+
+#endif
+
+
+#if DK3_HAVE_INTMAX_T
+
+/** Convert double to intmax_t.
+ @param x Value to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_MATH_OVERFLOW if the absolute value is too large.
+ @return Conversion result.
+*/
+intmax_t
+dk3ma_d_to_intmax_t_ok(double x, int *ec);
+
+/** Convert double to uintmax_t.
+ @param x Value to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_MATH_OUT_OF_RANGE for negative v values,
+ DK3_ERROR_MATH_OVERFLOW for values too large.
+ @return Conversion result.
+*/
+uintmax_t
+dk3ma_d_to_uintmax_t_ok(double x, int *ec);
+
+#endif
+
+/** Convert double precision floating point number to dk3_im_t.
+ @param x Value to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_MATH_OVERFLOW if the absolute value is too large.
+ @return Conversion result.
+*/
+dk3_im_t
+dk3ma_d_to_im_ok(double x, int *ec);
+
+/** Convert double precision floating point number to dk3_um_t.
+ @param x Value to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_MATH_OUT_OF_RANGE for negative v values,
+ DK3_ERROR_MATH_OVERFLOW for values too large.
+ @return Conversion result.
+*/
+dk3_um_t
+dk3ma_d_to_um_ok(double x, int *ec);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+
+
+#include "dk3ma.h"
+
+
+
+$!trace-include
+
+
+
+/* formerly DK3_HAVE_COMPILER_CONVERSIONS */
+#if 1
+
+
+
+size_t
+dk3ma_d_to_sz_ok(double v, int *ec)
+{
+ size_t back = 0;
+ $? "+ dk3ma_d_to_sz_ok %lg", v
+ if (0.0 <= v) {
+ if ((double)DK3_SIZE_T_MAX >= v) { $? ". size ok"
+ back = (size_t)v;
+ } else {
+ if (NULL != ec) { $? "! overflow"
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ } else {
+ if (NULL != ec) { $? "! out of range"
+ *ec = DK3_ERROR_MATH_OUT_OF_RANGE;
+ }
+ } $? "- dk3ma_d_to_sz_ok %lu", (unsigned long)back
+ return back;
+}
+
+
+
+long
+dk3ma_d_to_l_ok(double x, int *ec)
+{
+ long back = 0L;
+ $? "+ dk3ma_d_to_l_ok %lg", x
+ if ((double)DK3_L_MIN <= x) {
+ if ((double)DK3_L_MAX >= x) {
+ back = (long)x;
+ } else {
+ back = DK3_L_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ back = DK3_L_MIN;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ } $? "- dk3ma_d_to_l_ok %ld", back
+ return back;
+}
+
+
+
+unsigned long
+dk3ma_d_to_ul_ok(double x, int *ec)
+{
+ unsigned long back = 0UL;
+ $? "+ dk3ma_d_to_ul_ok %lg", x
+ if (0.0 <= x) {
+ if ((double)DK3_UL_MAX >= x) {
+ back = (unsigned long)x;
+ } else {
+ back = DK3_UL_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OUT_OF_RANGE; }
+ }
+ } else {
+ back = 0UL;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OUT_OF_RANGE; }
+ } $? "- dk3ma_d_to_ul_ok %lu", back
+ return back;
+}
+
+
+
+#if DK3_HAVE_LONG_LONG
+
+long long
+dk3ma_d_to_ll_ok(double x, int *ec)
+{
+ long long back = 0LL;
+ $? "+ dk3ma_d_to_ll_ok %lg", x
+ if ((double)DK3_LL_MIN <= x) {
+ if ((double)DK3_LL_MAX >= x) {
+ back = (long long)x;
+ } else {
+ back = DK3_LL_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ back = DK3_LL_MIN;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ } $? "- dk3ma_d_to_ll_ok %lld", back
+ return back;
+}
+
+
+
+unsigned long long
+dk3ma_d_to_ull_ok(double x, int *ec)
+{
+ unsigned long long back = 0ULL;
+ $? "+ dk3ma_d_to_ull_ok %lg", x
+ if (0.0 <= x) {
+ if ((double)DK3_ULL_MAX >= x) {
+ back = (unsigned long long)x;
+ } else {
+ back = DK3_ULL_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OUT_OF_RANGE; }
+ } $? "- dk3ma_d_to_ull_ok %llu", back
+ return back;
+}
+
+#endif
+
+
+#if DK3_HAVE_INTMAX_T
+
+intmax_t
+dk3ma_d_to_intmax_t_ok(double x, int *ec)
+{
+ intmax_t back = DK3_INTMAX_T_0;
+ $? "+ dk3ma_d_to_intmax_t_ok %lg", x
+ if ((double)DK3_INTMAX_T_MIN <= x) {
+ if ((double)DK3_INTMAX_T_MAX >= x) {
+ back = (intmax_t)x;
+ } else {
+ back = DK3_INTMAX_T_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ back = DK3_INTMAX_T_MIN;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ } $? "- dk3ma_d_to_intmax_t_ok %jd", back
+ return back;
+}
+
+
+
+uintmax_t
+dk3ma_d_to_uintmax_t_ok(double x, int *ec)
+{
+ uintmax_t back = DK3_UINTMAX_T_0;
+ $? "+ dk3ma_d_to_uintmax_t_ok %lg", x
+ if (0.0 <= x) {
+ if ((double)DK3_UINTMAX_T_MAX >= x) {
+ back = (uintmax_t)x;
+ } else {
+ back = DK3_UINTMAX_T_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OUT_OF_RANGE; }
+ } $? "- dk3ma_d_to_uintmax_t_ok %ju", back
+ return back;
+}
+
+#endif
+
+
+
+dk3_im_t
+dk3ma_d_to_im_ok(double x, int *ec)
+{
+#if DK3_HAVE_INTMAX_T
+ return (dk3ma_d_to_intmax_t_ok(x, ec));
+#else
+#if DK3_HAVE_LONG_LONG
+ return (dk3ma_d_to_ll_ok(x, ec));
+#else
+ return (dk3ma_d_to_l_ok(x, ec));
+#endif
+#endif
+}
+
+
+
+dk3_um_t
+dk3ma_d_to_um_ok(double x, int *ec)
+{
+#if DK3_HAVE_INTMAX_T
+ return (dk3ma_d_to_uintmax_t_ok(x, ec));
+#else
+#if DK3_HAVE_LONG_LONG
+ return (dk3ma_d_to_ull_ok(x, ec));
+#else
+ return (dk3ma_d_to_ul_ok(x, ec));
+#endif
+#endif
+}
+
+
+
+#else
+/* if 1, formerly if DK3_HAVE_COMPILER_CONVERSIONS */
+
+
+/* If you see the error message below during build process, you have
+ disabled compiler conversions when running the configure script.
+ During the last 10 year I did not see any compiler doing
+ type casts from double to integers wrong, so the default is to
+ enable compiler conversions.
+ If you are really sure your compiler is doing type casts from
+ double to integer types wrong, remove the error compiler directive
+ below.
+ Note: The code for manual conversion from double to integers
+ is not well-tested as on all my systems the compilers type casts
+ do fine. Make sure you know what you are doing.
+*/
+#error "Compiler conversions turned off! See comment section above!"
+
+
+
+#if DK3_HAVE_INTMAX_T
+/* + uintmax_t */
+#if DK3_SIZEOF_INTMAX_T > 2
+#if DK3_SIZEOF_INTMAX_T > 4
+#if DK3_SIZEOF_INTMAX_T > 8
+#error "Can not handle such a large uintmax_t!"
+#else
+/* 8 */
+#if DK3_HAVE_LONG_LONG
+/** First bit of a dk3_um_t.
+*/
+#define DK3_UM_FIRST_BIT (9223372036854775808ULL)
+#else
+/** First bit of a dk3_um_t.
+*/
+#define DK3_UM_FIRST_BIT (9223372036854775808UL)
+#endif
+/** First bit of a dk3_um_t written as double.
+*/
+#define DK3_UM_FIRST_DOUBLE (9223372036854775808.0)
+#endif
+#else
+/* 4 */
+#if DK3_HAVE_LONG_LONG
+/** First bit of a dk3_um_t.
+*/
+#define DK3_UM_FIRST_BIT (2147483648ULL)
+#else
+/** First bit of a dk3_um_t.
+*/
+#define DK3_UM_FIRST_BIT (2147483648UL)
+#endif
+/** First bit of a dk3_um_t written as double.
+*/
+#define DK3_UM_FIRST_DOUBLE (2147483648.0)
+#endif
+#else
+/* 2 */
+#if DK3_HAVE_LONG_LONG
+/** First bit of a dk3_um_t.
+*/
+#define DK3_UM_FIRST_BIT (32768ULL)
+#else
+/** First bit of a dk3_um_t.
+*/
+#define DK3_UM_FIRST_BIT (32768UL)
+#endif
+/** First bit of a dk3_um_t written as double.
+*/
+#define DK3_UM_FIRST_DOUBLE (32768.0)
+#endif
+/* - uintmax_t */
+#else
+#if DK3_HAVE_LONG_LONG
+/* + unsigned long long */
+#if DK3_SIZEOF_LONG_LONG > 2
+#if DK3_SIZEOF_LONG_LONG > 4
+#if DK3_SIZEOF_LONG_LONG > 8
+#error "Can not handle such a large unsigned long long!"
+#else
+/* 8 */
+/** First bit of a dk3_um_t.
+*/
+#define DK3_UM_FIRST_BIT (9223372036854775808ULL)
+/** First bit of a dk3_um_t written as double.
+*/
+#define DK3_UM_FIRST_DOUBLE (9223372036854775808.0)
+#endif
+#else
+/* 4 */
+/** First bit of a dk3_um_t.
+*/
+#define DK3_UM_FIRST_BIT (2147483648ULL)
+/** First bit of a dk3_um_t written as double.
+*/
+#define DK3_UM_FIRST_DOUBLE (2147483648.0)
+#endif
+#else
+/* 2*/
+/** First bit of a dk3_um_t.
+*/
+#define DK3_UM_FIRST_BIT (32768ULL)
+/** First bit of a dk3_um_t written as double.
+*/
+#define DK3_UM_FIRST_DOUBLE (32768.0)
+#endif
+/* - unsigned long long */
+#else
+/* + unsigned long */
+#if DK3_SIZEOF_LONG > 2
+#if DK3_SIZEOF_LONG > 4
+#if DK3_SIZEOF_LONG > 8
+#error "Can not handle such a large unsigned long!"
+#else
+/* 8 */
+/** First bit of a dk3_um_t.
+*/
+#define DK3_UM_FIRST_BIT (9223372036854775808UL)
+/** First bit of a dk3_um_t written as double.
+*/
+#define DK3_UM_FIRST_DOUBLE (9223372036854775808.0)
+#endif
+#else
+/* 4 */
+#define DK3_UM_FIRST_BIT (2147483648UL)
+#define DK3_UM_FIRST_DOUBLE (2147483648.0)
+#endif
+#else
+/* 2 */
+/** First bit of a dk3_um_t.
+*/
+#define DK3_UM_FIRST_BIT (32768UL)
+/** First bit of a dk3_um_t written as double.
+*/
+#define DK3_UM_FIRST_DOUBLE (32768.0)
+#endif
+/* - unsigned long */
+#endif
+#endif
+
+
+
+/** Constant value 2 as dk3_um_t.
+*/
+static dk3_um_t const dk3ma_um2 =
+#if DK3_HAVE_LONG_LONG
+ (dk3_um_t)2ULL
+#else
+ (dk3_um_t)2UL
+#endif
+;
+
+
+dk3_um_t
+dk3ma_d_to_um_ok(double x, int *ec)
+{
+ dk3_um_t back = DK3_UM_0;
+ dk3_um_t testu;
+ double testd;
+ $? "+ dk3ma_d_to_um_ok %lg", x
+ if (0.0 <= x) {
+#if DK3_HAVE_LONG_DOUBLE
+ if ((long double)DK3_UM_MAX >= (long double)x)
+#else
+ if ((double)DK3_UM_MAX >= x)
+#endif
+ {
+ testd = DK3_UM_FIRST_DOUBLE;
+ testu = DK3_UM_FIRST_BIT;
+ for (i = 0; i < (8 * DK3_SIZEOF_UM); i++) {
+ if (x >= testd) {
+ x = x - testd;
+ back = back + testu;
+ }
+ testd = testd / 2.0;
+ testu = testu / dk3ma_um2;
+ }
+ }
+ else
+ {
+ back = DK3_UM_MAX
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OUT_OF_RANGE; }
+ }
+ $? "- dk3ma_d_to_um_ok %ju", back
+ return back;
+}
+
+
+
+dk3_im_t
+dk3ma_d_to_im_ok(double x, int *ec)
+{
+ dk3_im_t back = DK3_IM_0;
+ dk3_um_t tmp;
+ int mec = 0;
+
+ if (x >= 0.0) {
+ tmp = dk3ma_d_to_um_ok(x, &mec);
+ if (0 == mec) {
+ if ((dk3_um_t)DK3_IM_MAX >= tmp) {
+ back = (dk3_im_t)tmp;
+ } else {
+ back = DK3_IM_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ if (NULL != ec) { *ec = mec; }
+ }
+ } else {
+ if ((double)DK3_IM_MIN > x) {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ back = DK3_IM_MIN;
+ } else {
+ if ((double)(-DK3_IM_MAX) > x) {
+ back = DK3_IM_MIN;
+ } else {
+ tmp = dk3ma_d_to_um_ok((0.0 - x), &mec);
+ if (0 == mec) {
+ if ((dk3_um_t)DK3_IM_MAX >= tmp) {
+ back = DK3_IM_0 - (dk3_im_t)tmp;
+ } else {
+ back = DK3_IM_MIN;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ if (NULL != ec) { *ec = mec; }
+ }
+ }
+ }
+ }
+}
+
+
+
+#if DK3_HAVE_INTMAX_T
+
+uintmax_t
+dk3ma_d_to_uintmax_t_ok(double x, int *ec)
+{
+ return (dk3ma_d_to_um_ok(x, ec));
+}
+
+intmax_t
+dk3ma_d_to_intmax_t_ok(double x, int *ec)
+{
+ return (dk3ma_d_to_im_ok(x, ec));
+}
+
+#endif
+
+
+
+#if DK3_HAVE_LONG_LONG
+
+unsigned long long
+dk3ma_d_to_ull_ok(double x, int *ec)
+{
+#if (!(DK3_HAVE_INTMAX_T))
+ return (dk3ma_d_to_um_ok(x, ec));
+#else
+ dk3_um_t tmp;
+ unsigned long long back = 0ULL;
+ int mec = 0;
+ if (0.0 <= x) {
+ tmp = dk3ma_d_to_um_ok(x, &mec);
+ if (0 == mec) {
+#if DK3_SIZEOF_LONG_LONG >= DK3_SIZEOF_UM
+ back = (unsigned long long)tmp;
+#else
+ if ((dk3_um_t)DK3_ULL_MAX >= tmp) {
+ back = (unsigned long long)tmp;
+ } else {
+ back = DK3_ULL_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+#endif
+ } else {
+ if (NULL != ec) { *ec = mec; }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OUT_OF_RANGE; }
+ }
+ return back;
+#endif
+}
+
+
+
+long long
+dk3ma_d_to_ll_ok(double x, int *ec)
+{
+#if (!(DK3_HAVE_INTMAX_T))
+ return (dk3ma_d_to_im_ok(x, ec));
+#else
+ dk3_im_t tmp;
+ long long back = 0LL;
+ int mec = 0;
+
+ tmp = dk3ma_d_to_im_ok(x, &mec);
+ if (0 == mec) {
+#if DK3_SIZEOF_LONG_LONG >= DK3_SIZEOF_UM
+ back = (long long)tmp;
+#else
+ if ((dk3_im_t)DK3_LL_MIN <= tmp) {
+ if ((dk3_im_t)DK3_LL_MAX >= tmp) {
+ back = (long long)tmp;
+ } else {
+ back = DK3_LL_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ back = DK3_LL_MIN;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+#endif
+ } else {
+ if (NULL != ec) { *ec = mec; }
+ }
+#endif
+}
+
+#endif
+
+
+
+unsigned long
+dk3ma_d_to_ul_ok(double x, int *ec)
+{
+#if (!((DK3_HAVE_INTMAX_T) || (DK3_HAVE_LONG_LONG)))
+ return (dk3ma_d_to_um_ok(x, ec));
+#else
+ dk3_um_t tmp;
+ unsigned long back = 0UL;
+ int mec = 0;
+
+ tmp = dk3ma_d_to_um_ok(x, &mec);
+ if (0 == mec) {
+#if DK3_SIZEOF_LONG >= DK3_SIZEOF_UM
+ back = (unsigned long)tmp;
+#else
+ if ((dk3_um_t)DK3_UL_MAX >= tmp) {
+ back = (unsigned long)tmp;
+ } else {
+ back = DK3_UL_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+#endif
+ } else {
+ if (NULL != ec) { *ec = mec; }
+ }
+ return back;
+#endif
+}
+
+
+
+long
+dk3ma_d_to_l_ok(double x, int *ec)
+{
+#if (!((DK3_HAVE_INTMAX_T) || (DK3_HAVE_LONG_LONG)))
+ return (dk3ma_d_to_im_ok(x, ec));
+#else
+ dk3_im_t tmp;
+ long back = 0L;
+ int mec = 0;
+ tmp = dk3ma_d_to_im_ok(x, &mec);
+ if (0 == mec) {
+#if DK3_SIZEOF_LONG >= DK3_SIZEOF_UM
+ back = (long)tmp;
+#else
+ if ((dk3_im_t)DK3_L_MIN <= tmp) {
+ if ((dk3_im_t)DK3_L_MAX >= tmp) {
+ back = (dk3_im_t)tmp;
+ } else {
+ back = DK3_L_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ back = DK3_L_MIN;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+#endif
+ } else {
+ if (NULL != ec) { *ec = mec; }
+ }
+ return back;
+#endif
+}
+
+
+
+size_t
+dk3ma_d_to_sz_ok(double v, int *ec)
+{
+ dk3_um_t tmp;
+ size_t back = 0;
+ int mec = 0;
+
+ tmp = dk3ma_d_to_um_ok(v, &mec);
+ if (0 == mec) {
+#if DK3_SIZEOF_SIZE_T >= DK3_SIZEOF_UM
+ back = (size_t)tmp;
+#else
+ if ((dk3_um_t)DK3_SIZE_T_MAX >= tmp) {
+ back = (size_t)tmp;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+#endif
+ } else {
+ if (NULL != ec) { *ec = mec; }
+ }
+ return back;
+}
+
+
+
+#endif
+/* if 1, formerly if DK3_HAVE_COMPILER_CONVERSIONS */
+
+
diff --git a/support/dktools/dk3madlc.h b/support/dktools/dk3madlc.h
new file mode 100644
index 0000000000..8f1f139b0b
--- /dev/null
+++ b/support/dktools/dk3madlc.h
@@ -0,0 +1,174 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3madlc.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK3MADLC_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3MADLC_H_INCLUDED 1
+
+
+#line 10 "dk3madlc.ctr"
+
+/** @file dk3madlc.h Conversion from double to long,
+ unsigned long, long long, unsigned long long, intmax_t, uintmax_t,
+ dk3_im_t and dk3_um_t.
+*/
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert double number to size.
+ @param v Value to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_MATH_OUT_OF_RANGE for negative v values,
+ DK3_ERROR_MATH_OVERFLOW for values too large.
+ @return Conversion result.
+*/
+size_t
+dk3ma_d_to_sz_ok(double v, int *ec);
+
+/** Convert double value to long.
+ @param x Double value.
+ @param ec Pointer to error code variable.
+ Set to DK3_ERROR_MATH_OVERFLOW if the absolute value is too large.
+ @return Conversion result.
+*/
+long
+dk3ma_d_to_l_ok(double x, int *ec);
+
+/** Convert double value to unsigned long.
+ @param x Double value.
+ @param ec Pointer to error code variable.
+ Set to DK3_ERROR_MATH_OUT_OF_RANGE for negative v values,
+ DK3_ERROR_MATH_OVERFLOW for values too large.
+ @return Conversion result.
+*/
+unsigned long
+dk3ma_d_to_ul_ok(double x, int *ec);
+
+#if DK3_HAVE_LONG_LONG
+
+/** Convert double to long long.
+ @param x Value to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_MATH_OVERFLOW if the absolute value is too large.
+ @return Conversion result.
+*/
+long long
+dk3ma_d_to_ll_ok(double x, int *ec);
+
+/** Convert double to unsigned long long.
+ @param x Value to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_MATH_OUT_OF_RANGE for negative v values,
+ DK3_ERROR_MATH_OVERFLOW for values too large.
+ @return Conversion result.
+*/
+unsigned long long
+dk3ma_d_to_ull_ok(double x, int *ec);
+
+#endif
+
+
+#if DK3_HAVE_INTMAX_T
+
+/** Convert double to intmax_t.
+ @param x Value to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_MATH_OVERFLOW if the absolute value is too large.
+ @return Conversion result.
+*/
+intmax_t
+dk3ma_d_to_intmax_t_ok(double x, int *ec);
+
+/** Convert double to uintmax_t.
+ @param x Value to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_MATH_OUT_OF_RANGE for negative v values,
+ DK3_ERROR_MATH_OVERFLOW for values too large.
+ @return Conversion result.
+*/
+uintmax_t
+dk3ma_d_to_uintmax_t_ok(double x, int *ec);
+
+#endif
+
+/** Convert double precision floating point number to dk3_im_t.
+ @param x Value to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_MATH_OVERFLOW if the absolute value is too large.
+ @return Conversion result.
+*/
+dk3_im_t
+dk3ma_d_to_im_ok(double x, int *ec);
+
+/** Convert double precision floating point number to dk3_um_t.
+ @param x Value to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_MATH_OUT_OF_RANGE for negative v values,
+ DK3_ERROR_MATH_OVERFLOW for values too large.
+ @return Conversion result.
+*/
+dk3_um_t
+dk3ma_d_to_um_ok(double x, int *ec);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk3madsc.c b/support/dktools/dk3madsc.c
new file mode 100644
index 0000000000..06e502b2b7
--- /dev/null
+++ b/support/dktools/dk3madsc.c
@@ -0,0 +1,90 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3madsc.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3madsc.c The dk3madsc module.
+*/
+
+
+#line 68 "dk3madsc.ctr"
+
+
+
+#include "dk3ma.h"
+
+
+
+
+
+#line 76 "dk3madsc.ctr"
+
+
+
+short
+dk3ma_d_to_s_ok(double x, int *ec)
+{
+ short back = 0;
+ if ((double)DK3_S_MIN <= x) {
+ if ((double)DK3_S_MAX >= x) {
+ back = (short)x;
+ } else {
+ back = DK3_S_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ back = DK3_S_MIN;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ return back;
+}
+
+
+
+unsigned short
+dk3ma_d_to_us_ok(double x, int *ec)
+{
+ unsigned short back = 0U;
+ if (0.0 <= x) {
+ if ((double)DK3_US_MAX >= x) {
+ back = (unsigned short)x;
+ } else {
+ back = DK3_US_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OUT_OF_RANGE; }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk3madsc.ctr b/support/dktools/dk3madsc.ctr
new file mode 100644
index 0000000000..be4ccbf67b
--- /dev/null
+++ b/support/dktools/dk3madsc.ctr
@@ -0,0 +1,115 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2014-xxxx
+license = bsd
+
+
+%% header
+
+
+/** @file dk3madsc.h Conversion from double to short and
+ unsigned short.
+*/
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert double value to short.
+ @param x Double value to convert.
+ @param ec Pointer to error code variable.
+ Set to DK3_ERROR_MATH_OVERFLOW if the absolute value of x is too large.
+ @return Conversion result.
+*/
+short
+dk3ma_d_to_s_ok(double x, int *ec);
+
+/** Convert double value to unsigned short.
+ @param x Double value to convert.
+ @param ec Pointer to error code variable.
+ Set to DK3_ERROR_MATH_OVERFLOW if the absolute value of x is too large,
+ DK3_ERROR_MATH_OUT_OF_RANGE for negative x.
+ @return Conversion result.
+*/
+unsigned short
+dk3ma_d_to_us_ok(double x, int *ec);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+
+
+#include "dk3ma.h"
+
+
+
+$!trace-include
+
+
+
+short
+dk3ma_d_to_s_ok(double x, int *ec)
+{
+ short back = 0;
+ if ((double)DK3_S_MIN <= x) {
+ if ((double)DK3_S_MAX >= x) {
+ back = (short)x;
+ } else {
+ back = DK3_S_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ back = DK3_S_MIN;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ return back;
+}
+
+
+
+unsigned short
+dk3ma_d_to_us_ok(double x, int *ec)
+{
+ unsigned short back = 0U;
+ if (0.0 <= x) {
+ if ((double)DK3_US_MAX >= x) {
+ back = (unsigned short)x;
+ } else {
+ back = DK3_US_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OUT_OF_RANGE; }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk3madsc.h b/support/dktools/dk3madsc.h
new file mode 100644
index 0000000000..c5fc905446
--- /dev/null
+++ b/support/dktools/dk3madsc.h
@@ -0,0 +1,101 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3madsc.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK3MADSC_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3MADSC_H_INCLUDED 1
+
+
+#line 9 "dk3madsc.ctr"
+
+
+/** @file dk3madsc.h Conversion from double to short and
+ unsigned short.
+*/
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert double value to short.
+ @param x Double value to convert.
+ @param ec Pointer to error code variable.
+ Set to DK3_ERROR_MATH_OVERFLOW if the absolute value of x is too large.
+ @return Conversion result.
+*/
+short
+dk3ma_d_to_s_ok(double x, int *ec);
+
+/** Convert double value to unsigned short.
+ @param x Double value to convert.
+ @param ec Pointer to error code variable.
+ Set to DK3_ERROR_MATH_OVERFLOW if the absolute value of x is too large,
+ DK3_ERROR_MATH_OUT_OF_RANGE for negative x.
+ @return Conversion result.
+*/
+unsigned short
+dk3ma_d_to_us_ok(double x, int *ec);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3madsi.c b/support/dktools/dk3madsi.c
new file mode 100644
index 0000000000..6929acc5e2
--- /dev/null
+++ b/support/dktools/dk3madsi.c
@@ -0,0 +1,194 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3madsi.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3madsi.c The dk3madsi module.
+*/
+
+
+#line 71 "dk3madsi.ctr"
+
+
+
+#include "dk3ma.h"
+#if DK3_HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if DK3_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if DK3_HAVE_STRING_H
+#include <string.h>
+#endif
+#if DK3_HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+
+
+#line 89 "dk3madsi.ctr"
+
+
+
+int
+dk3ma_d_from_c8_string(double *rp, char const *src, int *ec)
+{
+#if DK3_HAVE_STRTOD
+ char *endptr = NULL;
+ double val = 0.0;
+ int back = 0;
+
+
+#line 100 "dk3madsi.ctr"
+ if ((NULL != rp) && (NULL != src)) {
+ errno = 0;
+ val = strtod(src, &endptr);
+ if (endptr) {
+ if ('\0' == *endptr) {
+ back = 1;
+ } else {
+ if (endptr != src) {
+ back = 1;
+ }
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ } else {
+ back = 1;
+ }
+ if (0 != back) {
+ if (ERANGE == errno) {
+ if ((HUGE_VAL == val) || (-HUGE_VAL == val) || (0.0 == val)) {
+ back = 0;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ }
+ *rp = val;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+
+#line 127 "dk3madsi.ctr"
+ return back;
+#else
+ double val = 0.0;
+ int back = 0;
+
+
+#line 132 "dk3madsi.ctr"
+ if ((NULL != rp) && (NULL != src)) {
+ if (1 == sscanf(src, "%lf", &val)) {
+ *rp = val;
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+
+#line 142 "dk3madsi.ctr"
+ return back;
+#endif
+}
+
+
+
+int
+dk3ma_d_from_string(double *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_HAVE_WCSTOD
+ dkChar *endptr = NULL;
+ double val;
+ int back = 0;
+
+
+#line 157 "dk3madsi.ctr"
+ if ((NULL != rp) && (NULL != src)) {
+ errno = 0;
+ val = wcstod(src, &endptr);
+ if (endptr) {
+ if ('\0' == *endptr) {
+ back = 1;
+ } else {
+ if (endptr != src) {
+ back = 1;
+ }
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ } else {
+ back = 1;
+ }
+ if (0 != back) {
+ if (ERANGE == errno) {
+ if ((HUGE_VAL == val) || (-HUGE_VAL == val) || (0.0 == val)) {
+ back = 0;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ }
+ *rp = val;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+
+#line 184 "dk3madsi.ctr"
+ return back;
+#else
+ double val = 0.0;
+ int back = 0;
+
+
+#line 189 "dk3madsi.ctr"
+ if ((NULL != rp) && (NULL != src)) {
+ if (1 == swscanf(src, dkT("%lf"), &val)) {
+ *rp = val;
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+
+#line 199 "dk3madsi.ctr"
+ return back;
+#endif
+#else
+ return (dk3ma_d_from_c8_string(rp, src, ec));
+#endif
+}
+
+
diff --git a/support/dktools/dk3madsi.ctr b/support/dktools/dk3madsi.ctr
new file mode 100644
index 0000000000..d180255699
--- /dev/null
+++ b/support/dktools/dk3madsi.ctr
@@ -0,0 +1,206 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2014-xxxx
+license = bsd
+
+
+%% header
+
+/** @file dk3madsi.h Convert string to double value.
+*/
+
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve double value from string.
+ @param rp Result variable pointer.
+ @param src Text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ @return 1 on success, 0 on error.
+ On error the error code variable is set to
+ DK3_ERROR_INVALID_ARGS (one of the pointers rp or src is NULL)
+ or DK3_ERROR_SYNTAX (text does not contain a double value).
+*/
+int
+dk3ma_d_from_string(double *rp, dkChar const *src, int *ec);
+
+/** Retrieve double value from string.
+ @param rp Result variable pointer.
+ @param src Text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ @return 1 on success, 0 on error.
+ On error the error code variable is set to
+ DK3_ERROR_INVALID_ARGS (one of the pointers rp or src is NULL)
+ or DK3_ERROR_SYNTAX (text does not contain a double value).
+*/
+int
+dk3ma_d_from_c8_string(double *rp, char const *src, int *ec);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+
+
+#include "dk3ma.h"
+#if DK3_HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if DK3_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if DK3_HAVE_STRING_H
+#include <string.h>
+#endif
+#if DK3_HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+$!trace-include
+
+
+
+int
+dk3ma_d_from_c8_string(double *rp, char const *src, int *ec)
+{
+#if DK3_HAVE_STRTOD
+ char *endptr = NULL;
+ double val = 0.0;
+ int back = 0;
+ $? "+ dk3ma_d_from_string \"%!8s\"", TR_8STR(src)
+ if ((NULL != rp) && (NULL != src)) {
+ errno = 0;
+ val = strtod(src, &endptr);
+ if (endptr) {
+ if ('\0' == *endptr) {
+ back = 1;
+ } else {
+ if (endptr != src) {
+ back = 1;
+ }
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ } else {
+ back = 1;
+ }
+ if (0 != back) {
+ if (ERANGE == errno) {
+ if ((HUGE_VAL == val) || (-HUGE_VAL == val) || (0.0 == val)) {
+ back = 0;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ }
+ *rp = val;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ } $? "- dk3ma_d_from_string %lg %d", val, back
+ return back;
+#else
+ double val = 0.0;
+ int back = 0;
+ $? "+ dk3ma_d_from_string \"%!8s\"", TR_8STR(src)
+ if ((NULL != rp) && (NULL != src)) {
+ if (1 == sscanf(src, "%lf", &val)) {
+ *rp = val;
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ } $? "- dk3ma_d_from_string %lg %d", val, back
+ return back;
+#endif
+}
+
+
+
+int
+dk3ma_d_from_string(double *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_HAVE_WCSTOD
+ dkChar *endptr = NULL;
+ double val;
+ int back = 0;
+ $? "+ dk3ma_d_from_string \"%!ds\"", TR_STR(src)
+ if ((NULL != rp) && (NULL != src)) {
+ errno = 0;
+ val = wcstod(src, &endptr);
+ if (endptr) {
+ if ('\0' == *endptr) {
+ back = 1;
+ } else {
+ if (endptr != src) {
+ back = 1;
+ }
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ } else {
+ back = 1;
+ }
+ if (0 != back) {
+ if (ERANGE == errno) {
+ if ((HUGE_VAL == val) || (-HUGE_VAL == val) || (0.0 == val)) {
+ back = 0;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ }
+ *rp = val;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ } $? "- dk3ma_d_from_string %lg %d", val, back
+ return back;
+#else
+ double val = 0.0;
+ int back = 0;
+ $? "+ dk3ma_d_from_string \"%!ds\"", TR_STR(src)
+ if ((NULL != rp) && (NULL != src)) {
+ if (1 == swscanf(src, dkT("%lf"), &val)) {
+ *rp = val;
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ } $? "- dk3ma_d_from_string %lg %d", val, back
+ return back;
+#endif
+#else
+ return (dk3ma_d_from_c8_string(rp, src, ec));
+#endif
+}
+
+
diff --git a/support/dktools/dk3madsi.h b/support/dktools/dk3madsi.h
new file mode 100644
index 0000000000..99512bc5d8
--- /dev/null
+++ b/support/dktools/dk3madsi.h
@@ -0,0 +1,104 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3madsi.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK3MADSI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3MADSI_H_INCLUDED 1
+
+
+#line 9 "dk3madsi.ctr"
+
+/** @file dk3madsi.h Convert string to double value.
+*/
+
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve double value from string.
+ @param rp Result variable pointer.
+ @param src Text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ @return 1 on success, 0 on error.
+ On error the error code variable is set to
+ DK3_ERROR_INVALID_ARGS (one of the pointers rp or src is NULL)
+ or DK3_ERROR_SYNTAX (text does not contain a double value).
+*/
+int
+dk3ma_d_from_string(double *rp, dkChar const *src, int *ec);
+
+/** Retrieve double value from string.
+ @param rp Result variable pointer.
+ @param src Text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ @return 1 on success, 0 on error.
+ On error the error code variable is set to
+ DK3_ERROR_INVALID_ARGS (one of the pointers rp or src is NULL)
+ or DK3_ERROR_SYNTAX (text does not contain a double value).
+*/
+int
+dk3ma_d_from_c8_string(double *rp, char const *src, int *ec);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3madso.c b/support/dktools/dk3madso.c
new file mode 100644
index 0000000000..04bbcb39be
--- /dev/null
+++ b/support/dktools/dk3madso.c
@@ -0,0 +1,137 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3madso.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3madso.c The dk3madso module.
+*/
+
+
+#line 65 "dk3madso.ctr"
+
+
+
+#include "dk3ma.h"
+#if DK3_HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if DK3_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if DK3_HAVE_STRING_H
+#include <string.h>
+#endif
+#if DK3_HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include "dk3str.h"
+
+
+
+
+
+#line 87 "dk3madso.ctr"
+
+
+
+int
+dk3ma_d_to_c8_string(char *rb, size_t sz, double va)
+{
+ int back = 0;
+#if DK3_HAVE_SNPRINTF || DK3_HAVE__SNPRINTF || DK3_ON_WINDOWS
+ int res;
+ if ((NULL != rb) && (0 < sz)) {
+#if DK3_HAVE_SNPRINTF
+ res = snprintf(rb, sz, "%g", va);
+#else
+ res = _snprintf(rb, sz, "%g", va);
+#endif
+ if (0 < res) { /* Anything written? */
+ if ((size_t)res < sz) { /* Buffer large enough? */
+ rb[res] = '\0';
+ rb[sz - 1] = '\0';
+ back = 1;
+ } else { /* Buffer too small! */
+ rb[sz - 1] = '\0';
+ }
+ } else { /* Nothing written! */
+ rb[0] = '\0';
+ }
+ }
+#else
+ char buf[128];
+ if ((NULL != rb) && (0 < sz)) {
+ sprintf(buf, "%g", va);
+ if (dk3str_c8_len(buf) < sz) {
+ dk3str_c8_cpy(rb, buf);
+ back = 1;
+ } else {
+ rb[0] = '\0';
+ }
+ }
+#endif
+ return back;
+}
+
+
+
+int
+dk3ma_d_to_string(dkChar *rb, size_t sz, double va)
+{
+#if DK3_CHAR_SIZE > 1
+ char buf[128];
+ char *cptr;
+ dkChar *dptr;
+ int back = 0;
+ if ((NULL != rb) && (0 < sz)) {
+ if (dk3ma_d_to_c8_string(buf, sizeof(buf), va)) {
+ if (dk3str_c8_len(buf) < sz) {
+ back = 1;
+ dptr = rb; cptr = buf;
+ while(*cptr) { *(dptr++) = (dkChar)(*(cptr++)); }
+ *dptr = dkT('\0');
+ } else {
+ rb[0] = dkT('\0');
+ }
+ } else {
+ rb[0] = dkT('\0');
+ }
+ }
+ return back;
+#else
+ return (dk3ma_d_to_c8_string(rb, sz, va));
+#endif
+}
+
+
diff --git a/support/dktools/dk3madso.ctr b/support/dktools/dk3madso.ctr
new file mode 100644
index 0000000000..75d204c01e
--- /dev/null
+++ b/support/dktools/dk3madso.ctr
@@ -0,0 +1,159 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2014-xxxx
+license = bsd
+
+
+%% header
+
+/** @file dk3madso.h Output double values to string.
+*/
+
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert double value to string.
+ @param rb Result buffer.
+ @param sz Size of rb (number of char).
+ @param va Value to convert.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3ma_d_to_c8_string(char *rb, size_t sz, double va);
+
+/** Convert double value to string.
+ @param rb Result buffer.
+ @param sz Size of rb (number of dkChar).
+ @param va Value to convert.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3ma_d_to_string(dkChar *rb, size_t sz, double va);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+
+
+#include "dk3ma.h"
+#if DK3_HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if DK3_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if DK3_HAVE_STRING_H
+#include <string.h>
+#endif
+#if DK3_HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include "dk3str.h"
+
+
+
+$!trace-include
+
+
+
+int
+dk3ma_d_to_c8_string(char *rb, size_t sz, double va)
+{
+ int back = 0;
+#if DK3_HAVE_SNPRINTF || DK3_HAVE__SNPRINTF || DK3_ON_WINDOWS
+ int res;
+ if ((NULL != rb) && (0 < sz)) {
+#if DK3_HAVE_SNPRINTF
+ res = snprintf(rb, sz, "%g", va);
+#else
+ res = _snprintf(rb, sz, "%g", va);
+#endif
+ if (0 < res) { /* Anything written? */
+ if ((size_t)res < sz) { /* Buffer large enough? */
+ rb[res] = '\0';
+ rb[sz - 1] = '\0';
+ back = 1;
+ } else { /* Buffer too small! */
+ rb[sz - 1] = '\0';
+ }
+ } else { /* Nothing written! */
+ rb[0] = '\0';
+ }
+ }
+#else
+ char buf[128];
+ if ((NULL != rb) && (0 < sz)) {
+ sprintf(buf, "%g", va);
+ if (dk3str_c8_len(buf) < sz) {
+ dk3str_c8_cpy(rb, buf);
+ back = 1;
+ } else {
+ rb[0] = '\0';
+ }
+ }
+#endif
+ return back;
+}
+
+
+
+int
+dk3ma_d_to_string(dkChar *rb, size_t sz, double va)
+{
+#if DK3_CHAR_SIZE > 1
+ char buf[128];
+ char *cptr;
+ dkChar *dptr;
+ int back = 0;
+ if ((NULL != rb) && (0 < sz)) {
+ if (dk3ma_d_to_c8_string(buf, sizeof(buf), va)) {
+ if (dk3str_c8_len(buf) < sz) {
+ back = 1;
+ dptr = rb; cptr = buf;
+ while(*cptr) { *(dptr++) = (dkChar)(*(cptr++)); }
+ *dptr = dkT('\0');
+ } else {
+ rb[0] = dkT('\0');
+ }
+ } else {
+ rb[0] = dkT('\0');
+ }
+ }
+ return back;
+#else
+ return (dk3ma_d_to_c8_string(rb, sz, va));
+#endif
+}
+
+
diff --git a/support/dktools/dk3madso.h b/support/dktools/dk3madso.h
new file mode 100644
index 0000000000..3f684d335f
--- /dev/null
+++ b/support/dktools/dk3madso.h
@@ -0,0 +1,98 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3madso.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK3MADSO_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3MADSO_H_INCLUDED 1
+
+
+#line 9 "dk3madso.ctr"
+
+/** @file dk3madso.h Output double values to string.
+*/
+
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert double value to string.
+ @param rb Result buffer.
+ @param sz Size of rb (number of char).
+ @param va Value to convert.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3ma_d_to_c8_string(char *rb, size_t sz, double va);
+
+/** Convert double value to string.
+ @param rb Result buffer.
+ @param sz Size of rb (number of dkChar).
+ @param va Value to convert.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3ma_d_to_string(dkChar *rb, size_t sz, double va);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3mafpe.c b/support/dktools/dk3mafpe.c
new file mode 100644
index 0000000000..3c6c3858af
--- /dev/null
+++ b/support/dktools/dk3mafpe.c
@@ -0,0 +1,245 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3mafpe.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3mafpe.c The dk3mafpe module.
+*/
+
+
+#line 260 "dk3mafpe.ctr"
+
+#include "dk3mafpe.h"
+
+
+
+
+
+#line 266 "dk3mafpe.ctr"
+
+
+
+#if TRACE_DEBUG
+
+static
+void
+dk3mafpe_debug(dk3_ma_fpe_t fpes)
+{
+
+
+#line 276 "dk3mafpe.ctr"
+ if (NULL != dktrace_file()) {
+ if (0 != (fpes & DK3MAFPE_DIVBYZERO)) {
+ fputs("DIVBYZERO\n", dktrace_file());
+ }
+ if (0 != (fpes & DK3MAFPE_INEXACT)) {
+ fputs("INEXACT\n", dktrace_file());
+ }
+ if (0 != (fpes & DK3MAFPE_OVERFLOW)) {
+ fputs("OVERFLOW\n", dktrace_file());
+ }
+ if (0 != (fpes & DK3MAFPE_UNDERFLOW)) {
+ fputs("UNDERFLOW\n", dktrace_file());
+ }
+ if (0 != (fpes & DK3MAFPE_INVALID)) {
+ fputs("INVALID\n", dktrace_file());
+ }
+ }
+
+
+#line 294 "dk3mafpe.ctr"
+}
+
+#endif
+
+dk3_ma_fpe_t
+dk3mafpe_get(void)
+{
+#if DK3_ON_WINDOWS
+#if DK3_HAVE__CLEARFP
+#if TRACE_DEBUG
+ dk3_ma_fpe_t back;
+ back = _statusfp();
+ dk3mafpe_debug(back);
+ return back;
+#else
+ return (_statusfp());
+#endif
+#else
+ return 0;
+#endif
+#else
+#if DK3_HAVE_FETESTEXCEPT
+#if TRACE_DEBUG
+ dk3_ma_fpe_t back;
+ back = fetestexcept(FE_ALL_EXCEPT);
+ dk3mafpe_debug(back);
+ return back;
+#else
+ return (fetestexcept(FE_ALL_EXCEPT));
+#endif
+#else
+ return 0;
+#endif
+#endif
+}
+
+
+
+void
+dk3mafpe_clear(void)
+{
+#if DK3_ON_WINDOWS
+#if DK3_HAVE__CLEARFP
+ (void)_clearfp();
+#else
+
+#endif
+#else
+#if DK3_HAVE_FETESTEXCEPT
+ feclearexcept(FE_ALL_EXCEPT);
+#else
+
+#endif
+#endif
+}
+
+
+
+dk3_ma_fpe_t
+dk3mafpe_get_and_clear(void)
+{
+#if DK3_ON_WINDOWS
+#if DK3_HAVE__CLEARFP
+#if TRACE_DEBUG
+ dk3_ma_fpe_t back;
+ back = _clearfp();
+ dk3mafpe_debug(back);
+ return back;
+#else
+ return (_clearfp());
+#endif
+#else
+ return 0;
+#endif
+#else
+#if DK3_HAVE_FETESTEXCEPT
+ dk3_ma_fpe_t back;
+ back = fetestexcept(FE_ALL_EXCEPT);
+ feclearexcept(FE_ALL_EXCEPT);
+#if TRACE_DEBUG
+ dk3mafpe_debug(back);
+#endif
+ return back;
+#else
+ return 0;
+#endif
+#endif
+}
+
+
+
+int
+dk3mafpe_get_handling_type(void)
+{
+#if DK3_ON_WINDOWS
+#if DK3_HAVE__CLEARFP
+ return DK3_MA_FPE_HANDLING_CLEARFP;
+#else
+ return DK3_MA_FPE_HANDLING_NONE;
+#endif
+#else
+#if DK3_HAVE_FETESTEXCEPT
+ return DK3_MA_FPE_HANDLING_FETESTEXCEPT;
+#else
+ return DK3_MA_FPE_HANDLING_NONE;
+#endif
+#endif
+}
+
+
+
+int
+dk3mafpe_isfinite(double x)
+{
+#if DK3_ON_WINDOWS
+ int back = 0;
+ if (_finite(x)) {
+ back = 1;
+ }
+ return back;
+#else
+#if DK3_HAVE_ISFINITE
+ int back = 0;
+ if (isfinite(x)) {
+ back = 1;
+ }
+ return back;
+#else
+#error "No function or macro isfinite(x) available!"
+ return 1;
+#endif
+#endif
+}
+
+
+
+
+int
+dk3mafpe_isnormal(double x)
+{
+#if DK3_ON_WINDOWS
+ int back = 0;
+ if (_finite(x)) {
+ back = 1;
+ switch (_fpclass(x)) {
+ case _FPCLASS_ND: case _FPCLASS_PD: {
+ back = 0;
+ } break;
+ }
+ }
+ return back;
+#else
+#if DK3_HAVE_ISNORMAL
+ int back = 0;
+ if (isnormal(x)) {
+ back = 1;
+ }
+ return back;
+#else
+#error "No function or macro isnormal(x) available!"
+ return 1;
+#endif
+#endif
+}
+
diff --git a/support/dktools/dk3mafpe.ctr b/support/dktools/dk3mafpe.ctr
new file mode 100644
index 0000000000..cb6b6c3337
--- /dev/null
+++ b/support/dktools/dk3mafpe.ctr
@@ -0,0 +1,458 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2014-xxxx
+license = bsd
+
+
+%% header
+
+/** @file dk3mafpe.h Floating point exception handling.
+
+Before doing any floating point calculation, use dk3mafpe_get_handling_type()
+to check whether an exception handling mechanism is available.
+
+The function returns DK3_MA_FPE_HANDLING_CLEARFP on Windows systems
+if _clearfp() and _statusfp() are available. It returns
+DK3_MA_FPE_HANDLING_FETESTEXCEPT if the POSIX floating point exception
+functions fetestexcept() and feclearexcept() are available.
+
+If none of these mechanisms is available, DK3_MA_FPE_HANDLING_NONE is
+returned. Your program should issue a warning.
+
+Before doing a floating point calculation use dk3mafpe_clear() to
+clear the FPU status word.
+
+After doing a floating point calculation use dk3mafpe_get() or
+dk3mafpe_get_and_clear() to retrieve the status word.
+Check the status word against DK3MAFPE_ALL (and-combine them) to see
+if any exception occured.
+
+If your calculation results in just one double you can use
+dk3mafpe_isfinite() and/or dk3mafpe_isnormal() to check the value.
+If the dk3mafpe_isfinite() test fails, the value is of no use.
+If the dk3mafpe_isnormal() test fails, the result is very small, it uses
+denormalized representation and has probably and likely lost
+much of it's precision.
+*/
+
+#include <dk3conf.h>
+
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+#if DK3_HAVE_FENV_H
+#include <fenv.h>
+#endif
+
+
+
+#if DK3_ON_WINDOWS
+/** Floating point exceptions set.
+*/
+typedef unsigned int dk3_ma_fpe_t;
+
+#if DK3_HAVE__CLEARFP
+
+/** Division by 0.
+*/
+#define DK3MAFPE_DIVBYZERO (_SW_ZERODIVIDE)
+
+/** Inexact result (either overflow or underflow).
+*/
+#define DK3MAFPE_INEXACT (_SW_INEXACT)
+
+/** Not a number (0/0 or infty - infty).
+*/
+#define DK3MAFPE_INVALID (_SW_INVALID)
+
+/** Result too large for representation.
+*/
+#define DK3MAFPE_OVERFLOW (_SW_OVERFLOW)
+
+/** Result too small for normalized representation.
+*/
+#define DK3MAFPE_UNDERFLOW (_SW_UNDERFLOW)
+
+/** Denormalized number.
+*/
+#define DK3MAFPE_DENORMAL (_SW_DENORMAL)
+
+/** Or-combination of all supported exceptions.
+*/
+#define DK3MAFPE_ALL \
+ ((_SW_ZERODIVIDE) \
+ | (_SW_INEXACT) \
+ | (_SW_INVALID) \
+ | (_SW_OVERFLOW) \
+ | (_SW_UNDERFLOW) \
+ | (_SW_DENORMAL))
+
+#else
+
+/** Division by 0.
+*/
+#define DK3MAFPE_DIVBYZERO 0
+
+/** Inexact result (either overflow or underflow).
+*/
+#define DK3MAFPE_INEXACT 0
+
+/** Not a number (0/0 or infty - infty).
+*/
+#define DK3MAFPE_INVALID 0
+
+/** Result too large for representation.
+*/
+#define DK3MAFPE_OVERFLOW 0
+
+/** Result too small for normalized representation.
+*/
+#define DK3MAFPE_UNDERFLOW 0
+
+/** Denormalized number.
+*/
+#define DK3MAFPE_DENORMAL 0
+
+/** Or-combination of all supported exceptions.
+*/
+#define DK3MAFPE_ALL 0
+
+#endif
+#else
+/** Floating point exceptions set.
+*/
+typedef int dk3_ma_fpe_t;
+
+#if DK3_HAVE_FETESTEXCEPT
+
+/** Division by 0.
+*/
+#define DK3MAFPE_DIVBYZERO (FE_DIVBYZERO)
+
+/** Inexact result (either overflow or underflow).
+*/
+#define DK3MAFPE_INEXACT (FE_INEXACT)
+
+/** Not a number (0/0 or infty - infty).
+*/
+#define DK3MAFPE_INVALID (FE_INVALID)
+
+/** Result too large for representation.
+*/
+#define DK3MAFPE_OVERFLOW (FE_OVERFLOW)
+
+/** Result too small for normalized representation.
+*/
+#define DK3MAFPE_UNDERFLOW (FE_UNDERFLOW)
+
+/** Denormalized number.
+*/
+#define DK3MAFPE_DENORMAL 0
+
+/** Or-combination of all supported exceptions.
+*/
+#define DK3MAFPE_ALL (FE_ALL_EXCEPT)
+
+#else
+
+/** Division by 0.
+*/
+#define DK3MAFPE_DIVBYZERO 0
+
+/** Inexact result (either overflow or underflow).
+*/
+#define DK3MAFPE_INEXACT 0
+
+/** Not a number (0/0 or infty - infty).
+*/
+#define DK3MAFPE_INVALID 0
+
+/** Result too large for representation.
+*/
+#define DK3MAFPE_OVERFLOW 0
+
+/** Result too small for normalized representation.
+*/
+#define DK3MAFPE_UNDERFLOW 0
+
+/** Denormalized number.
+*/
+#define DK3MAFPE_DENORMAL 0
+
+/** Or-combination of all supported exceptions.
+*/
+#define DK3MAFPE_ALL 0
+
+#endif
+#endif
+
+
+
+/** Different handling types for floating point exceptions.
+*/
+enum {
+
+ /** No fpe exception handling available.
+ */
+ DK3_MA_FPE_HANDLING_NONE = 0,
+
+ /** POSIX exception handling using fetestexcept() and friends.
+ */
+ DK3_MA_FPE_HANDLING_FETESTEXCEPT,
+
+ /** Windows exception handling using _clearfp() and friends.
+ */
+ DK3_MA_FPE_HANDLING_CLEARFP
+
+};
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve exception set.
+ @return Exceptions found.
+*/
+dk3_ma_fpe_t
+dk3mafpe_get(void);
+
+/** Clear exception set.
+*/
+void
+dk3mafpe_clear(void);
+
+/** Retrieve exception set and clear.
+ @return Exceptions found.
+*/
+dk3_ma_fpe_t
+dk3mafpe_get_and_clear(void);
+
+/** Get exception handling type.
+ @return One from DK3_MA_FPE_HANDLING_NONE,
+ DK3_MA_FPE_HANDLING_FETESTEXCEPT, DK3_MA_FPE_HANDLING_CLEARFP.
+*/
+int
+dk3mafpe_get_handling_type(void);
+
+/** Check whether a number is normalized.
+ @param x Number to check.
+ @return Non-null result on success, 0 on error.
+*/
+int
+dk3mafpe_isnormal(double x);
+
+/** Check whether a number is finite (not NAN, not INF).
+ @param x Number to check.
+ @return Non-null result on success, 0 on error.
+*/
+int
+dk3mafpe_isfinite(double x);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk3mafpe.h"
+
+
+
+$!trace-include
+
+
+
+#if TRACE_DEBUG
+
+static
+void
+dk3mafpe_debug(dk3_ma_fpe_t fpes)
+{
+ $? "+ dk3mafpe_debug"
+ if (NULL != dktrace_file()) {
+ if (0 != (fpes & DK3MAFPE_DIVBYZERO)) {
+ fputs("DIVBYZERO\n", dktrace_file());
+ }
+ if (0 != (fpes & DK3MAFPE_INEXACT)) {
+ fputs("INEXACT\n", dktrace_file());
+ }
+ if (0 != (fpes & DK3MAFPE_OVERFLOW)) {
+ fputs("OVERFLOW\n", dktrace_file());
+ }
+ if (0 != (fpes & DK3MAFPE_UNDERFLOW)) {
+ fputs("UNDERFLOW\n", dktrace_file());
+ }
+ if (0 != (fpes & DK3MAFPE_INVALID)) {
+ fputs("INVALID\n", dktrace_file());
+ }
+ }
+ $? "- dk3mafpe_debug"
+}
+
+#endif
+
+dk3_ma_fpe_t
+dk3mafpe_get(void)
+{
+#if DK3_ON_WINDOWS
+#if DK3_HAVE__CLEARFP
+#if TRACE_DEBUG
+ dk3_ma_fpe_t back;
+ back = _statusfp();
+ dk3mafpe_debug(back);
+ return back;
+#else
+ return (_statusfp());
+#endif
+#else
+ return 0;
+#endif
+#else
+#if DK3_HAVE_FETESTEXCEPT
+#if TRACE_DEBUG
+ dk3_ma_fpe_t back;
+ back = fetestexcept(FE_ALL_EXCEPT);
+ dk3mafpe_debug(back);
+ return back;
+#else
+ return (fetestexcept(FE_ALL_EXCEPT));
+#endif
+#else
+ return 0;
+#endif
+#endif
+}
+
+
+
+void
+dk3mafpe_clear(void)
+{
+#if DK3_ON_WINDOWS
+#if DK3_HAVE__CLEARFP
+ (void)_clearfp();
+#else
+
+#endif
+#else
+#if DK3_HAVE_FETESTEXCEPT
+ feclearexcept(FE_ALL_EXCEPT);
+#else
+
+#endif
+#endif
+}
+
+
+
+dk3_ma_fpe_t
+dk3mafpe_get_and_clear(void)
+{
+#if DK3_ON_WINDOWS
+#if DK3_HAVE__CLEARFP
+#if TRACE_DEBUG
+ dk3_ma_fpe_t back;
+ back = _clearfp();
+ dk3mafpe_debug(back);
+ return back;
+#else
+ return (_clearfp());
+#endif
+#else
+ return 0;
+#endif
+#else
+#if DK3_HAVE_FETESTEXCEPT
+ dk3_ma_fpe_t back;
+ back = fetestexcept(FE_ALL_EXCEPT);
+ feclearexcept(FE_ALL_EXCEPT);
+#if TRACE_DEBUG
+ dk3mafpe_debug(back);
+#endif
+ return back;
+#else
+ return 0;
+#endif
+#endif
+}
+
+
+
+int
+dk3mafpe_get_handling_type(void)
+{
+#if DK3_ON_WINDOWS
+#if DK3_HAVE__CLEARFP
+ return DK3_MA_FPE_HANDLING_CLEARFP;
+#else
+ return DK3_MA_FPE_HANDLING_NONE;
+#endif
+#else
+#if DK3_HAVE_FETESTEXCEPT
+ return DK3_MA_FPE_HANDLING_FETESTEXCEPT;
+#else
+ return DK3_MA_FPE_HANDLING_NONE;
+#endif
+#endif
+}
+
+
+
+int
+dk3mafpe_isfinite(double x)
+{
+#if DK3_ON_WINDOWS
+ int back = 0;
+ if (_finite(x)) {
+ back = 1;
+ }
+ return back;
+#else
+#if DK3_HAVE_ISFINITE
+ int back = 0;
+ if (isfinite(x)) {
+ back = 1;
+ }
+ return back;
+#else
+#error "No function or macro isfinite(x) available!"
+ return 1;
+#endif
+#endif
+}
+
+
+
+
+int
+dk3mafpe_isnormal(double x)
+{
+#if DK3_ON_WINDOWS
+ int back = 0;
+ if (_finite(x)) {
+ back = 1;
+ switch (_fpclass(x)) {
+ case _FPCLASS_ND: case _FPCLASS_PD: {
+ back = 0;
+ } break;
+ }
+ }
+ return back;
+#else
+#if DK3_HAVE_ISNORMAL
+ int back = 0;
+ if (isnormal(x)) {
+ back = 1;
+ }
+ return back;
+#else
+#error "No function or macro isnormal(x) available!"
+ return 1;
+#endif
+#endif
+}
+
diff --git a/support/dktools/dk3mafpe.h b/support/dktools/dk3mafpe.h
new file mode 100644
index 0000000000..4ee576ed46
--- /dev/null
+++ b/support/dktools/dk3mafpe.h
@@ -0,0 +1,293 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3mafpe.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK3MAFPE_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3MAFPE_H_INCLUDED 1
+
+
+#line 9 "dk3mafpe.ctr"
+
+/** @file dk3mafpe.h Floating point exception handling.
+
+Before doing any floating point calculation, use dk3mafpe_get_handling_type()
+to check whether an exception handling mechanism is available.
+
+The function returns DK3_MA_FPE_HANDLING_CLEARFP on Windows systems
+if _clearfp() and _statusfp() are available. It returns
+DK3_MA_FPE_HANDLING_FETESTEXCEPT if the POSIX floating point exception
+functions fetestexcept() and feclearexcept() are available.
+
+If none of these mechanisms is available, DK3_MA_FPE_HANDLING_NONE is
+returned. Your program should issue a warning.
+
+Before doing a floating point calculation use dk3mafpe_clear() to
+clear the FPU status word.
+
+After doing a floating point calculation use dk3mafpe_get() or
+dk3mafpe_get_and_clear() to retrieve the status word.
+Check the status word against DK3MAFPE_ALL (and-combine them) to see
+if any exception occured.
+
+If your calculation results in just one double you can use
+dk3mafpe_isfinite() and/or dk3mafpe_isnormal() to check the value.
+If the dk3mafpe_isfinite() test fails, the value is of no use.
+If the dk3mafpe_isnormal() test fails, the result is very small, it uses
+denormalized representation and has probably and likely lost
+much of it's precision.
+*/
+
+#include <dk3conf.h>
+
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+#if DK3_HAVE_FENV_H
+#include <fenv.h>
+#endif
+
+
+
+#if DK3_ON_WINDOWS
+/** Floating point exceptions set.
+*/
+typedef unsigned int dk3_ma_fpe_t;
+
+#if DK3_HAVE__CLEARFP
+
+/** Division by 0.
+*/
+#define DK3MAFPE_DIVBYZERO (_SW_ZERODIVIDE)
+
+/** Inexact result (either overflow or underflow).
+*/
+#define DK3MAFPE_INEXACT (_SW_INEXACT)
+
+/** Not a number (0/0 or infty - infty).
+*/
+#define DK3MAFPE_INVALID (_SW_INVALID)
+
+/** Result too large for representation.
+*/
+#define DK3MAFPE_OVERFLOW (_SW_OVERFLOW)
+
+/** Result too small for normalized representation.
+*/
+#define DK3MAFPE_UNDERFLOW (_SW_UNDERFLOW)
+
+/** Denormalized number.
+*/
+#define DK3MAFPE_DENORMAL (_SW_DENORMAL)
+
+/** Or-combination of all supported exceptions.
+*/
+#define DK3MAFPE_ALL \
+ ((_SW_ZERODIVIDE) \
+ | (_SW_INEXACT) \
+ | (_SW_INVALID) \
+ | (_SW_OVERFLOW) \
+ | (_SW_UNDERFLOW) \
+ | (_SW_DENORMAL))
+
+#else
+
+/** Division by 0.
+*/
+#define DK3MAFPE_DIVBYZERO 0
+
+/** Inexact result (either overflow or underflow).
+*/
+#define DK3MAFPE_INEXACT 0
+
+/** Not a number (0/0 or infty - infty).
+*/
+#define DK3MAFPE_INVALID 0
+
+/** Result too large for representation.
+*/
+#define DK3MAFPE_OVERFLOW 0
+
+/** Result too small for normalized representation.
+*/
+#define DK3MAFPE_UNDERFLOW 0
+
+/** Denormalized number.
+*/
+#define DK3MAFPE_DENORMAL 0
+
+/** Or-combination of all supported exceptions.
+*/
+#define DK3MAFPE_ALL 0
+
+#endif
+#else
+/** Floating point exceptions set.
+*/
+typedef int dk3_ma_fpe_t;
+
+#if DK3_HAVE_FETESTEXCEPT
+
+/** Division by 0.
+*/
+#define DK3MAFPE_DIVBYZERO (FE_DIVBYZERO)
+
+/** Inexact result (either overflow or underflow).
+*/
+#define DK3MAFPE_INEXACT (FE_INEXACT)
+
+/** Not a number (0/0 or infty - infty).
+*/
+#define DK3MAFPE_INVALID (FE_INVALID)
+
+/** Result too large for representation.
+*/
+#define DK3MAFPE_OVERFLOW (FE_OVERFLOW)
+
+/** Result too small for normalized representation.
+*/
+#define DK3MAFPE_UNDERFLOW (FE_UNDERFLOW)
+
+/** Denormalized number.
+*/
+#define DK3MAFPE_DENORMAL 0
+
+/** Or-combination of all supported exceptions.
+*/
+#define DK3MAFPE_ALL (FE_ALL_EXCEPT)
+
+#else
+
+/** Division by 0.
+*/
+#define DK3MAFPE_DIVBYZERO 0
+
+/** Inexact result (either overflow or underflow).
+*/
+#define DK3MAFPE_INEXACT 0
+
+/** Not a number (0/0 or infty - infty).
+*/
+#define DK3MAFPE_INVALID 0
+
+/** Result too large for representation.
+*/
+#define DK3MAFPE_OVERFLOW 0
+
+/** Result too small for normalized representation.
+*/
+#define DK3MAFPE_UNDERFLOW 0
+
+/** Denormalized number.
+*/
+#define DK3MAFPE_DENORMAL 0
+
+/** Or-combination of all supported exceptions.
+*/
+#define DK3MAFPE_ALL 0
+
+#endif
+#endif
+
+
+
+/** Different handling types for floating point exceptions.
+*/
+enum {
+
+ /** No fpe exception handling available.
+ */
+ DK3_MA_FPE_HANDLING_NONE = 0,
+
+ /** POSIX exception handling using fetestexcept() and friends.
+ */
+ DK3_MA_FPE_HANDLING_FETESTEXCEPT,
+
+ /** Windows exception handling using _clearfp() and friends.
+ */
+ DK3_MA_FPE_HANDLING_CLEARFP
+
+};
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve exception set.
+ @return Exceptions found.
+*/
+dk3_ma_fpe_t
+dk3mafpe_get(void);
+
+/** Clear exception set.
+*/
+void
+dk3mafpe_clear(void);
+
+/** Retrieve exception set and clear.
+ @return Exceptions found.
+*/
+dk3_ma_fpe_t
+dk3mafpe_get_and_clear(void);
+
+/** Get exception handling type.
+ @return One from DK3_MA_FPE_HANDLING_NONE,
+ DK3_MA_FPE_HANDLING_FETESTEXCEPT, DK3_MA_FPE_HANDLING_CLEARFP.
+*/
+int
+dk3mafpe_get_handling_type(void);
+
+/** Check whether a number is normalized.
+ @param x Number to check.
+ @return Non-null result on success, 0 on error.
+*/
+int
+dk3mafpe_isnormal(double x);
+
+/** Check whether a number is finite (not NAN, not INF).
+ @param x Number to check.
+ @return Non-null result on success, 0 on error.
+*/
+int
+dk3mafpe_isfinite(double x);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk3mai.c b/support/dktools/dk3mai.c
new file mode 100644
index 0000000000..b515018885
--- /dev/null
+++ b/support/dktools/dk3mai.c
@@ -0,0 +1,224 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3mai.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3mai.c The dk3mai module.
+*/
+
+
+#line 108 "dk3mai.ctr"
+
+
+
+#include "dk3ma.h"
+
+
+
+
+
+#line 116 "dk3mai.ctr"
+
+
+
+int
+dk3ma_i_abs_ok(int a, int *ec)
+{
+ if (NULL != ec) { if (DK3_I_MIN == a) { *ec = DK3_ERROR_MATH_OVERFLOW; } }
+ return ((0 <= a) ? a : (0 - a));
+}
+
+
+
+int
+dk3ma_i_add_ok(int a, int b, int *ec)
+{
+ if (NULL != ec) {
+ if ((0 < a) && (0 < b)) {
+ if((DK3_I_MAX - a) < b) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ } else {
+ if ((0 > a) && (0 > b)) {
+ if (DK3_I_MIN == a) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ } else {
+ if ((DK3_I_MIN - a) > b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ }
+ }
+ }
+ return (a + b);
+}
+
+
+
+int
+dk3ma_i_sub_ok(int a, int b, int *ec)
+{
+ if (NULL != ec) {
+ if ((0 < a) && (0 > b)) {
+ if((DK3_I_MAX + b) < a) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ } else {
+ if ((0 > a) && (0 < b)) {
+ if((DK3_I_MIN + b) > a) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ }
+ return (a - b);
+}
+
+
+
+#if VERSION_BEFORE_20141018
+int
+dk3ma_i_mul_ok(int a, int b, int *ec)
+{
+ if (NULL != ec) {
+ if ((0 != a) && (0 != b)) {
+ if ((DK3_I_MIN == a) && (1 != b)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ goto checksfinished;
+ }
+ if ((DK3_I_MIN == b) && (1 != a)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ goto checksfinished;
+ }
+ if ((DK3_I_MAX / dk3ma_i_abs_ok(a, ec)) < dk3ma_i_abs_ok(b, ec)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ /* goto checksfinished; -- when adding further tests -- */
+ }
+ }
+ }
+ checksfinished:
+ return (a * b);
+}
+#else
+int
+dk3ma_i_mul_ok(int a, int b, int *ec)
+{
+ if ((NULL != ec) && (0 != a) && (0 != b)) {
+ if (DK3_I_MIN == a) {
+ if (1 != b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ goto finished;
+ }
+ if (DK3_I_MIN == b) {
+ if (1 != a) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ goto finished;
+ }
+ if (0 < a) {
+ if (0 < b) {
+ if ((DK3_I_MAX / a) < b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if ((DK3_I_MIN / a) > b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ } else {
+ if (0 < b) {
+ if ((DK3_I_MIN / b) > a) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if ((DK3_I_MAX / (0 - a)) < (0 - b)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ }
+ }
+finished:
+ return (a * b);
+}
+#endif
+
+
+
+int
+dk3ma_i_div_ok(int a, int b, int *ec)
+{
+ int back = 0;
+ if (0 != b) {
+ if ((DK3_I_MIN == a) && (-1 == b)) {
+ back = DK3_I_MAX;
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ } else {
+ back = a / b;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_DIVZERO; }
+ if (0 <= a) { back = DK3_I_MAX; }
+ else { back = DK3_I_MIN; }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_i_gcd_ok(int a, int b, int *ec)
+{
+ int h;
+ if (0 > a) {
+ if (DK3_I_MIN == a) {
+ a = 0;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ goto finished;
+ } else {
+ a = 0 - a;
+ }
+ }
+ if (0 > b) {
+ if (DK3_I_MIN == b) {
+ a = 0;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ goto finished;
+ } else {
+ b = 0 - b;
+ }
+ }
+ while (0 < b) {
+ h = a % b;
+ a = b;
+ b = h;
+ }
+ if (0 == a) { a = 1; }
+ finished:
+ return a;
+}
+
diff --git a/support/dktools/dk3mai.ctr b/support/dktools/dk3mai.ctr
new file mode 100644
index 0000000000..549310259f
--- /dev/null
+++ b/support/dktools/dk3mai.ctr
@@ -0,0 +1,289 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2014-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk3mai.h Mathematical operations on int.
+*/
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Absolute value.
+ @param a Original value.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Non-negative value on success,
+ DK3_I_MAX and ec = DK3_ERROR_MATH_OVERFLOW on error.
+*/
+int
+dk3ma_i_abs_ok(int a, int *ec);
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Summary of a and b.
+*/
+int
+dk3ma_i_add_ok(int a, int b, int *ec);
+
+/** Substraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Difference of a and b.
+*/
+int
+dk3ma_i_sub_ok(int a, int b, int *ec);
+
+/** Multiplication.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Product of a and b.
+*/
+int
+dk3ma_i_mul_ok(int a, int b, int *ec);
+
+/** Division.
+ @param a Left operand (nominator).
+ @param b Right operand (denominator).
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW or
+ DK3_ERROR_MATH_DIVZERO when returning.
+ @return Fraction of a and b.
+*/
+int
+dk3ma_i_div_ok(int a, int b, int *ec);
+
+/** Greatest common divisor.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Greatest common divisor of a and b.
+*/
+int
+dk3ma_i_gcd_ok(int a, int b, int *ec);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+
+
+#include "dk3ma.h"
+
+
+
+$!trace-include
+
+
+
+int
+dk3ma_i_abs_ok(int a, int *ec)
+{
+ if (NULL != ec) { if (DK3_I_MIN == a) { *ec = DK3_ERROR_MATH_OVERFLOW; } }
+ return ((0 <= a) ? a : (0 - a));
+}
+
+
+
+int
+dk3ma_i_add_ok(int a, int b, int *ec)
+{
+ if (NULL != ec) {
+ if ((0 < a) && (0 < b)) {
+ if((DK3_I_MAX - a) < b) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ } else {
+ if ((0 > a) && (0 > b)) {
+ if (DK3_I_MIN == a) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ } else {
+ if ((DK3_I_MIN - a) > b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ }
+ }
+ }
+ return (a + b);
+}
+
+
+
+int
+dk3ma_i_sub_ok(int a, int b, int *ec)
+{
+ if (NULL != ec) {
+ if ((0 < a) && (0 > b)) {
+ if((DK3_I_MAX + b) < a) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ } else {
+ if ((0 > a) && (0 < b)) {
+ if((DK3_I_MIN + b) > a) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ }
+ return (a - b);
+}
+
+
+
+#if VERSION_BEFORE_20141018
+int
+dk3ma_i_mul_ok(int a, int b, int *ec)
+{
+ if (NULL != ec) {
+ if ((0 != a) && (0 != b)) {
+ if ((DK3_I_MIN == a) && (1 != b)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ goto checksfinished;
+ }
+ if ((DK3_I_MIN == b) && (1 != a)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ goto checksfinished;
+ }
+ if ((DK3_I_MAX / dk3ma_i_abs_ok(a, ec)) < dk3ma_i_abs_ok(b, ec)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ /* goto checksfinished; -- when adding further tests -- */
+ }
+ }
+ }
+ checksfinished:
+ return (a * b);
+}
+#else
+int
+dk3ma_i_mul_ok(int a, int b, int *ec)
+{
+ if ((NULL != ec) && (0 != a) && (0 != b)) {
+ if (DK3_I_MIN == a) {
+ if (1 != b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ goto finished;
+ }
+ if (DK3_I_MIN == b) {
+ if (1 != a) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ goto finished;
+ }
+ if (0 < a) {
+ if (0 < b) {
+ if ((DK3_I_MAX / a) < b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if ((DK3_I_MIN / a) > b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ } else {
+ if (0 < b) {
+ if ((DK3_I_MIN / b) > a) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if ((DK3_I_MAX / (0 - a)) < (0 - b)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ }
+ }
+finished:
+ return (a * b);
+}
+#endif
+
+
+
+int
+dk3ma_i_div_ok(int a, int b, int *ec)
+{
+ int back = 0;
+ if (0 != b) {
+ if ((DK3_I_MIN == a) && (-1 == b)) {
+ back = DK3_I_MAX;
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ } else {
+ back = a / b;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_DIVZERO; }
+ if (0 <= a) { back = DK3_I_MAX; }
+ else { back = DK3_I_MIN; }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_i_gcd_ok(int a, int b, int *ec)
+{
+ int h;
+ if (0 > a) {
+ if (DK3_I_MIN == a) {
+ a = 0;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ goto finished;
+ } else {
+ a = 0 - a;
+ }
+ }
+ if (0 > b) {
+ if (DK3_I_MIN == b) {
+ a = 0;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ goto finished;
+ } else {
+ b = 0 - b;
+ }
+ }
+ while (0 < b) {
+ h = a % b;
+ a = b;
+ b = h;
+ }
+ if (0 == a) { a = 1; }
+ finished:
+ return a;
+}
+
diff --git a/support/dktools/dk3mai.h b/support/dktools/dk3mai.h
new file mode 100644
index 0000000000..ebb748ee51
--- /dev/null
+++ b/support/dktools/dk3mai.h
@@ -0,0 +1,140 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3mai.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK3MAI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3MAI_H_INCLUDED 1
+
+
+#line 10 "dk3mai.ctr"
+
+/** @file dk3mai.h Mathematical operations on int.
+*/
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Absolute value.
+ @param a Original value.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Non-negative value on success,
+ DK3_I_MAX and ec = DK3_ERROR_MATH_OVERFLOW on error.
+*/
+int
+dk3ma_i_abs_ok(int a, int *ec);
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Summary of a and b.
+*/
+int
+dk3ma_i_add_ok(int a, int b, int *ec);
+
+/** Substraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Difference of a and b.
+*/
+int
+dk3ma_i_sub_ok(int a, int b, int *ec);
+
+/** Multiplication.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Product of a and b.
+*/
+int
+dk3ma_i_mul_ok(int a, int b, int *ec);
+
+/** Division.
+ @param a Left operand (nominator).
+ @param b Right operand (denominator).
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW or
+ DK3_ERROR_MATH_DIVZERO when returning.
+ @return Fraction of a and b.
+*/
+int
+dk3ma_i_div_ok(int a, int b, int *ec);
+
+/** Greatest common divisor.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Greatest common divisor of a and b.
+*/
+int
+dk3ma_i_gcd_ok(int a, int b, int *ec);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3maid8.c b/support/dktools/dk3maid8.c
new file mode 100644
index 0000000000..ab5ab1a7d4
--- /dev/null
+++ b/support/dktools/dk3maid8.c
@@ -0,0 +1,542 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3maid8.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3maid8.c The dk3maid8 module.
+*/
+
+
+#line 224 "dk3maid8.ctr"
+
+#include "dk3ma.h"
+
+
+
+
+
+#line 230 "dk3maid8.ctr"
+
+
+
+/** Constant numeric values.
+*/
+static dk3_um_t const dk3maid8_um_array[] = {
+#if DK3_HAVE_LONG_LONG
+ /* 0 */ (dk3_um_t)10ULL,
+ /* 1 */ (dk3_um_t)1ULL,
+ /* 2 */ (dk3_um_t)2ULL,
+ /* 3 */ (dk3_um_t)3ULL,
+ /* 4 */ (dk3_um_t)4ULL,
+ /* 5 */ (dk3_um_t)5ULL,
+ /* 6 */ (dk3_um_t)6ULL,
+ /* 7 */ (dk3_um_t)7ULL,
+ /* 8 */ (dk3_um_t)8ULL,
+ /* 9 */ (dk3_um_t)9ULL,
+ /* 10 */ (dk3_um_t)10ULL,
+ /* 11 */ (dk3_um_t)11ULL,
+ /* 12 */ (dk3_um_t)12ULL,
+ /* 13 */ (dk3_um_t)13ULL,
+ /* 14 */ (dk3_um_t)14ULL,
+ /* 15 */ (dk3_um_t)15ULL,
+ /* 16 */ (dk3_um_t)16ULL
+#else
+ /* 0 */ (dk3_um_t)10UL,
+ /* 1 */ (dk3_um_t)1UL,
+ /* 2 */ (dk3_um_t)2UL,
+ /* 3 */ (dk3_um_t)3UL,
+ /* 4 */ (dk3_um_t)4UL,
+ /* 5 */ (dk3_um_t)5UL,
+ /* 6 */ (dk3_um_t)6UL,
+ /* 7 */ (dk3_um_t)7UL,
+ /* 8 */ (dk3_um_t)8UL,
+ /* 9 */ (dk3_um_t)9UL,
+ /* 10 */ (dk3_um_t)10UL,
+ /* 11 */ (dk3_um_t)11UL,
+ /* 12 */ (dk3_um_t)12UL,
+ /* 13 */ (dk3_um_t)13UL,
+ /* 14 */ (dk3_um_t)14UL,
+ /* 15 */ (dk3_um_t)15UL,
+ /* 16 */ (dk3_um_t)16UL
+#endif
+};
+
+
+
+/** Find start of text in string.
+ @param str String to search for text.
+ @return Pointer to start of text on success, NULL on error.
+*/
+static
+char const *
+dk3maid8_str_c8_start(char const *str)
+{
+ char const *back = NULL;
+ if (NULL != str) {
+ back = str;
+ while((' ' == *back) || ('\t' == *back)) { back++; }
+ switch(*back) {
+ case '\0': case '\n': case '\r': {
+ back = NULL;
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_um_from_c8_string(dk3_um_t *rp, char const *src, int *ec)
+{
+ char const *ptr = NULL; /* Current char to process */
+ dk3_um_t val = DK3_UM_0; /* Value found */
+ dk3_um_t op = DK3_UM_0; /* Operand to add */
+ int mec = 0; /* Math error code */
+ int back = 0; /* Function result */
+ int found = 0; /* Flag: Digits found */
+ int cc = 1; /* Flag: Can continue */
+ int action = 0; /* Action to take */
+
+
+#line 312 "dk3maid8.ctr"
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3maid8_str_c8_start(src);
+ if (NULL != ptr) {
+ while (0 != cc) {
+ action = 0;
+ switch(*(ptr++)) {
+ case '\0': { /* End of string */
+ cc = 0;
+ if (0 != found) {
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ } break;
+ case '0': {
+ found = 1; action = 1; op = DK3_UM_0;
+ } break;
+ case '1': {
+ found = 1; action = 1; op = dk3maid8_um_array[1];
+ } break;
+ case '2': {
+ found = 1; action = 1; op = dk3maid8_um_array[2];
+ } break;
+ case '3': {
+ found = 1; action = 1; op = dk3maid8_um_array[3];
+ } break;
+ case '4': {
+ found = 1; action = 1; op = dk3maid8_um_array[4];
+ } break;
+ case '5': {
+ found = 1; action = 1; op = dk3maid8_um_array[5];
+ } break;
+ case '6': {
+ found = 1; action = 1; op = dk3maid8_um_array[6];
+ } break;
+ case '7': {
+ found = 1; action = 1; op = dk3maid8_um_array[7];
+ } break;
+ case '8': {
+ found = 1; action = 1; op = dk3maid8_um_array[8];
+ } break;
+ case '9': {
+ found = 1; action = 1; op = dk3maid8_um_array[9];
+ } break;
+ default: { /* Non-digit */
+ cc = 0;
+ if (0 != found) {
+ back = 1;
+ }
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ } break;
+ }
+ if (0 != cc) {
+ switch(action) {
+ case 1: {
+ val = dk3ma_um_add_ok(
+ dk3ma_um_mul_ok(val, dk3maid8_um_array[0], &mec), op, &mec
+ );
+
+#line 370 "dk3maid8.ctr"
+ if (0 != mec) {
+
+#line 371 "dk3maid8.ctr"
+ cc = 0;
+ val = DK3_UM_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } break;
+ }
+ }
+
+#line 378 "dk3maid8.ctr"
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ *rp = val;
+#if DK3_ON_WINDOWS
+
+
+#line 385 "dk3maid8.ctr"
+#else
+#if DK3_HAVE_INTMAX_T
+
+
+#line 388 "dk3maid8.ctr"
+#else
+#if DK3_HAVE_LONG_LONG
+
+
+#line 391 "dk3maid8.ctr"
+#else
+
+
+#line 393 "dk3maid8.ctr"
+#endif
+#endif
+#endif
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+
+#line 399 "dk3maid8.ctr"
+ return back;
+}
+
+
+
+int
+dk3ma_im_from_c8_string(dk3_im_t *rp, char const *src, int *ec)
+{
+ char const *ptr = NULL; /* Start of text */
+ dk3_um_t umv = DK3_UM_0; /* Temporary value */
+ dk3_im_t val = DK3_IM_0; /* Conversion result */
+ int back = 0; /* Function result */
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3maid8_str_c8_start(src);
+ if (NULL != ptr) {
+ if ('-' == *ptr) {
+ ptr++;
+ if (0 != dk3ma_um_from_c8_string(&umv, ptr, ec)) {
+ if ((dk3_um_t)DK3_IM_MAX >= umv) {
+ val = (dk3_im_t)umv;
+ val = DK3_IM_0 - val;
+ back = 1;
+ } else {
+ val = DK3_IM_MIN;
+#if 0
+ if ((dk3_um_t)(DK3_IM_MAX + (dk3_im_t)1L) == umv)
+#else
+ if (((dk3_um_t)DK3_IM_MAX + (dk3_um_t)1UL) == umv)
+#endif
+ {
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ }
+ } else {
+ if (0 != dk3ma_um_from_c8_string(&umv, ptr, ec)) {
+ if ((dk3_um_t)DK3_IM_MAX >= umv) {
+ val = (dk3_im_t)umv;
+ back = 1;
+ } else {
+ val = DK3_IM_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ *rp = val;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_us_from_c8_string(unsigned short *rp, char const *src, int *ec)
+{
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_c8_string(&val, src, ec)) {
+ if ((dk3_um_t)DK3_US_MAX >= val) {
+ *rp = (unsigned short)val;
+ back = 1;
+ } else {
+ *rp = DK3_US_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (unsigned short)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_s_from_c8_string(short *rp, char const *src, int *ec)
+{
+ dk3_im_t val = DK3_IM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_im_from_c8_string(&val, src, ec)) {
+ if (((dk3_im_t)DK3_S_MIN <= val) && ((dk3_im_t)DK3_S_MAX >= val)) {
+ *rp = (short)val;
+ back = 1;
+ } else {
+ if (DK3_IM_0 > val) {
+ *rp = DK3_S_MIN;
+ } else {
+ *rp = DK3_S_MAX;
+ }
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (short)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_ui_from_c8_string(unsigned *rp, char const *src, int *ec)
+{
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_c8_string(&val, src, ec)) {
+ if ((dk3_um_t)DK3_U_MAX >= val) {
+ *rp = (unsigned) val;
+ back = 1;
+ } else {
+ *rp = DK3_U_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (unsigned)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_i_from_c8_string(int *rp, char const *src, int *ec)
+{
+ dk3_im_t val = DK3_IM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_im_from_c8_string(&val, src, ec)) {
+ if (((dk3_im_t)DK3_I_MIN <= val) && ((dk3_im_t)DK3_I_MAX >= val)) {
+ *rp = (int)val;
+ back = 1;
+ } else {
+ if (DK3_IM_0 > val) { *rp = DK3_I_MIN; } else { *rp = DK3_I_MAX; }
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (int)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_ul_from_c8_string(unsigned long *rp, char const *src, int *ec)
+{
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_c8_string(&val, src, ec)) {
+ if ((dk3_um_t)DK3_UL_MAX >= val) {
+ *rp = (unsigned long)val;
+ back = 1;
+ } else {
+ *rp = DK3_UL_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (unsigned long)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_l_from_c8_string(long *rp, char const *src, int *ec)
+{
+ dk3_im_t val = DK3_IM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_im_from_c8_string(&val, src, ec)) {
+ if (((dk3_im_t)DK3_L_MIN <= val) && ((dk3_im_t)DK3_L_MAX >= val)) {
+ *rp = (long)val;
+ back = 1;
+ } else {
+ if (DK3_IM_0 > val) { *rp = DK3_L_MIN; } else { *rp = DK3_L_MAX; }
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (long)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+
+
+#if DK3_HAVE_LONG_LONG
+
+int
+dk3ma_ull_from_c8_string(unsigned long long *rp, char const *src, int *ec)
+{
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_c8_string(&val, src, ec)) {
+ if ((dk3_um_t)DK3_ULL_MAX >= val) {
+ *rp = (unsigned long long)val;
+ back = 1;
+ } else {
+ *rp = DK3_ULL_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (unsigned long long)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+
+int
+dk3ma_ll_from_c8_string(long long *rp, char const *src, int *ec)
+{
+ dk3_im_t val = DK3_IM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_im_from_c8_string(&val, src, ec)) {
+ if (((dk3_im_t)DK3_LL_MIN <= val) && ((dk3_im_t)DK3_LL_MAX >= val)) {
+ *rp = (long long)val;
+ back = 1;
+ } else {
+ if (DK3_IM_0 > val) { *rp = DK3_LL_MIN; } else { *rp = DK3_LL_MAX; }
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (long long)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+#endif
+
+
+
+#if DK3_HAVE_INTMAX_T
+
+int
+dk3ma_uintmax_t_from_c8_string(uintmax_t *rp, char const *src, int *ec)
+{
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_c8_string(&val, src, ec)) {
+ *rp = (uintmax_t)val;
+ back = 1;
+ } else {
+ *rp = (uintmax_t)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_intmax_t_from_c8_string(intmax_t *rp, char const *src, int *ec)
+{
+ dk3_im_t val = DK3_IM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_im_from_c8_string(&val, src, ec)) {
+ *rp = (intmax_t)val;
+ back = 1;
+ } else {
+ *rp = (intmax_t)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+#endif
diff --git a/support/dktools/dk3maid8.ctr b/support/dktools/dk3maid8.ctr
new file mode 100644
index 0000000000..77c799dcae
--- /dev/null
+++ b/support/dktools/dk3maid8.ctr
@@ -0,0 +1,705 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2014-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk3maid8.h Retrieve numbers from decimal char strings.
+*/
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+#include <dk3types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert string to dk3_um_t.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_um_from_c8_string(dk3_um_t *rp, char const *src, int *ec);
+
+/** Convert string to dk3_im_t.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_im_from_c8_string(dk3_im_t *rp, char const *src, int *ec);
+
+/** Convert string to short.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_s_from_c8_string(short *rp, char const *src, int *ec);
+
+/** Convert string to unsigned short.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_us_from_c8_string(unsigned short *rp, char const *src, int *ec);
+
+/** Convert string to int.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_i_from_c8_string(int *rp, char const *src, int *ec);
+
+/** Convert string to unsigned.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_ui_from_c8_string(unsigned *rp, char const *src, int *ec);
+
+/** Convert string to long.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_l_from_c8_string(long *rp, char const *src, int *ec);
+
+/** Convert string to unsigned long.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_ul_from_c8_string(unsigned long *rp, char const *src, int *ec);
+
+#if DK3_HAVE_LONG_LONG
+
+/** Convert string to long long.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_ll_from_c8_string(long long *rp, char const *src, int *ec);
+
+/** Convert string to unsigned long long.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_ull_from_c8_string(unsigned long long *rp, char const *src, int *ec);
+
+#endif
+
+
+#if DK3_HAVE_INTMAX_T
+
+/** Convert string to intmax_t.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_intmax_t_from_c8_string(intmax_t *rp, char const *src, int *ec);
+
+/** Convert string to uintmax_t.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_uintmax_t_from_c8_string(uintmax_t *rp, char const *src, int *ec);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk3ma.h"
+
+
+
+$!trace-include
+
+
+
+/** Constant numeric values.
+*/
+static dk3_um_t const dk3maid8_um_array[] = {
+#if DK3_HAVE_LONG_LONG
+ /* 0 */ (dk3_um_t)10ULL,
+ /* 1 */ (dk3_um_t)1ULL,
+ /* 2 */ (dk3_um_t)2ULL,
+ /* 3 */ (dk3_um_t)3ULL,
+ /* 4 */ (dk3_um_t)4ULL,
+ /* 5 */ (dk3_um_t)5ULL,
+ /* 6 */ (dk3_um_t)6ULL,
+ /* 7 */ (dk3_um_t)7ULL,
+ /* 8 */ (dk3_um_t)8ULL,
+ /* 9 */ (dk3_um_t)9ULL,
+ /* 10 */ (dk3_um_t)10ULL,
+ /* 11 */ (dk3_um_t)11ULL,
+ /* 12 */ (dk3_um_t)12ULL,
+ /* 13 */ (dk3_um_t)13ULL,
+ /* 14 */ (dk3_um_t)14ULL,
+ /* 15 */ (dk3_um_t)15ULL,
+ /* 16 */ (dk3_um_t)16ULL
+#else
+ /* 0 */ (dk3_um_t)10UL,
+ /* 1 */ (dk3_um_t)1UL,
+ /* 2 */ (dk3_um_t)2UL,
+ /* 3 */ (dk3_um_t)3UL,
+ /* 4 */ (dk3_um_t)4UL,
+ /* 5 */ (dk3_um_t)5UL,
+ /* 6 */ (dk3_um_t)6UL,
+ /* 7 */ (dk3_um_t)7UL,
+ /* 8 */ (dk3_um_t)8UL,
+ /* 9 */ (dk3_um_t)9UL,
+ /* 10 */ (dk3_um_t)10UL,
+ /* 11 */ (dk3_um_t)11UL,
+ /* 12 */ (dk3_um_t)12UL,
+ /* 13 */ (dk3_um_t)13UL,
+ /* 14 */ (dk3_um_t)14UL,
+ /* 15 */ (dk3_um_t)15UL,
+ /* 16 */ (dk3_um_t)16UL
+#endif
+};
+
+
+
+/** Find start of text in string.
+ @param str String to search for text.
+ @return Pointer to start of text on success, NULL on error.
+*/
+static
+char const *
+dk3maid8_str_c8_start(char const *str)
+{
+ char const *back = NULL;
+ if (NULL != str) {
+ back = str;
+ while((' ' == *back) || ('\t' == *back)) { back++; }
+ switch(*back) {
+ case '\0': case '\n': case '\r': {
+ back = NULL;
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_um_from_c8_string(dk3_um_t *rp, char const *src, int *ec)
+{
+ char const *ptr = NULL; /* Current char to process */
+ dk3_um_t val = DK3_UM_0; /* Value found */
+ dk3_um_t op = DK3_UM_0; /* Operand to add */
+ int mec = 0; /* Math error code */
+ int back = 0; /* Function result */
+ int found = 0; /* Flag: Digits found */
+ int cc = 1; /* Flag: Can continue */
+ int action = 0; /* Action to take */
+ $? "+ dk3ma_um_from_c8_string \"%!8s\"", TR_8STR(src)
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3maid8_str_c8_start(src);
+ if (NULL != ptr) {
+ while (0 != cc) {
+ action = 0;
+ switch(*(ptr++)) {
+ case '\0': { /* End of string */
+ cc = 0;
+ if (0 != found) {
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ } break;
+ case '0': {
+ found = 1; action = 1; op = DK3_UM_0;
+ } break;
+ case '1': {
+ found = 1; action = 1; op = dk3maid8_um_array[1];
+ } break;
+ case '2': {
+ found = 1; action = 1; op = dk3maid8_um_array[2];
+ } break;
+ case '3': {
+ found = 1; action = 1; op = dk3maid8_um_array[3];
+ } break;
+ case '4': {
+ found = 1; action = 1; op = dk3maid8_um_array[4];
+ } break;
+ case '5': {
+ found = 1; action = 1; op = dk3maid8_um_array[5];
+ } break;
+ case '6': {
+ found = 1; action = 1; op = dk3maid8_um_array[6];
+ } break;
+ case '7': {
+ found = 1; action = 1; op = dk3maid8_um_array[7];
+ } break;
+ case '8': {
+ found = 1; action = 1; op = dk3maid8_um_array[8];
+ } break;
+ case '9': {
+ found = 1; action = 1; op = dk3maid8_um_array[9];
+ } break;
+ default: { /* Non-digit */
+ cc = 0;
+ if (0 != found) {
+ back = 1;
+ }
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ } break;
+ }
+ if (0 != cc) {
+ switch(action) {
+ case 1: {
+ val = dk3ma_um_add_ok(
+ dk3ma_um_mul_ok(val, dk3maid8_um_array[0], &mec), op, &mec
+ ); $? ". mec = %d", mec
+ if (0 != mec) { $? "! mec != 0"
+ cc = 0;
+ val = DK3_UM_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } break;
+ }
+ } $? ". mec = %d", mec
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ *rp = val;
+#if DK3_ON_WINDOWS
+ $? ". value = %I64u", val
+#else
+#if DK3_HAVE_INTMAX_T
+ $? ". value = %ju", val
+#else
+#if DK3_HAVE_LONG_LONG
+ $? ". value = %llu", val
+#else
+ $? ". value = %lu", val
+#endif
+#endif
+#endif
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ } $? "- dk3ma_um_from_c8_string %d", back
+ return back;
+}
+
+
+
+int
+dk3ma_im_from_c8_string(dk3_im_t *rp, char const *src, int *ec)
+{
+ char const *ptr = NULL; /* Start of text */
+ dk3_um_t umv = DK3_UM_0; /* Temporary value */
+ dk3_im_t val = DK3_IM_0; /* Conversion result */
+ int back = 0; /* Function result */
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3maid8_str_c8_start(src);
+ if (NULL != ptr) {
+ if ('-' == *ptr) {
+ ptr++;
+ if (0 != dk3ma_um_from_c8_string(&umv, ptr, ec)) {
+ if ((dk3_um_t)DK3_IM_MAX >= umv) {
+ val = (dk3_im_t)umv;
+ val = DK3_IM_0 - val;
+ back = 1;
+ } else {
+ val = DK3_IM_MIN;
+#if 0
+ if ((dk3_um_t)(DK3_IM_MAX + (dk3_im_t)1L) == umv)
+#else
+ if (((dk3_um_t)DK3_IM_MAX + (dk3_um_t)1UL) == umv)
+#endif
+ {
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ }
+ } else {
+ if (0 != dk3ma_um_from_c8_string(&umv, ptr, ec)) {
+ if ((dk3_um_t)DK3_IM_MAX >= umv) {
+ val = (dk3_im_t)umv;
+ back = 1;
+ } else {
+ val = DK3_IM_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ *rp = val;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_us_from_c8_string(unsigned short *rp, char const *src, int *ec)
+{
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_c8_string(&val, src, ec)) {
+ if ((dk3_um_t)DK3_US_MAX >= val) {
+ *rp = (unsigned short)val;
+ back = 1;
+ } else {
+ *rp = DK3_US_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (unsigned short)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_s_from_c8_string(short *rp, char const *src, int *ec)
+{
+ dk3_im_t val = DK3_IM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_im_from_c8_string(&val, src, ec)) {
+ if (((dk3_im_t)DK3_S_MIN <= val) && ((dk3_im_t)DK3_S_MAX >= val)) {
+ *rp = (short)val;
+ back = 1;
+ } else {
+ if (DK3_IM_0 > val) {
+ *rp = DK3_S_MIN;
+ } else {
+ *rp = DK3_S_MAX;
+ }
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (short)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_ui_from_c8_string(unsigned *rp, char const *src, int *ec)
+{
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_c8_string(&val, src, ec)) {
+ if ((dk3_um_t)DK3_U_MAX >= val) {
+ *rp = (unsigned) val;
+ back = 1;
+ } else {
+ *rp = DK3_U_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (unsigned)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_i_from_c8_string(int *rp, char const *src, int *ec)
+{
+ dk3_im_t val = DK3_IM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_im_from_c8_string(&val, src, ec)) {
+ if (((dk3_im_t)DK3_I_MIN <= val) && ((dk3_im_t)DK3_I_MAX >= val)) {
+ *rp = (int)val;
+ back = 1;
+ } else {
+ if (DK3_IM_0 > val) { *rp = DK3_I_MIN; } else { *rp = DK3_I_MAX; }
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (int)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_ul_from_c8_string(unsigned long *rp, char const *src, int *ec)
+{
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_c8_string(&val, src, ec)) {
+ if ((dk3_um_t)DK3_UL_MAX >= val) {
+ *rp = (unsigned long)val;
+ back = 1;
+ } else {
+ *rp = DK3_UL_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (unsigned long)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_l_from_c8_string(long *rp, char const *src, int *ec)
+{
+ dk3_im_t val = DK3_IM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_im_from_c8_string(&val, src, ec)) {
+ if (((dk3_im_t)DK3_L_MIN <= val) && ((dk3_im_t)DK3_L_MAX >= val)) {
+ *rp = (long)val;
+ back = 1;
+ } else {
+ if (DK3_IM_0 > val) { *rp = DK3_L_MIN; } else { *rp = DK3_L_MAX; }
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (long)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+
+
+#if DK3_HAVE_LONG_LONG
+
+int
+dk3ma_ull_from_c8_string(unsigned long long *rp, char const *src, int *ec)
+{
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_c8_string(&val, src, ec)) {
+ if ((dk3_um_t)DK3_ULL_MAX >= val) {
+ *rp = (unsigned long long)val;
+ back = 1;
+ } else {
+ *rp = DK3_ULL_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (unsigned long long)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+
+int
+dk3ma_ll_from_c8_string(long long *rp, char const *src, int *ec)
+{
+ dk3_im_t val = DK3_IM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_im_from_c8_string(&val, src, ec)) {
+ if (((dk3_im_t)DK3_LL_MIN <= val) && ((dk3_im_t)DK3_LL_MAX >= val)) {
+ *rp = (long long)val;
+ back = 1;
+ } else {
+ if (DK3_IM_0 > val) { *rp = DK3_LL_MIN; } else { *rp = DK3_LL_MAX; }
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (long long)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+#endif
+
+
+
+#if DK3_HAVE_INTMAX_T
+
+int
+dk3ma_uintmax_t_from_c8_string(uintmax_t *rp, char const *src, int *ec)
+{
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_c8_string(&val, src, ec)) {
+ *rp = (uintmax_t)val;
+ back = 1;
+ } else {
+ *rp = (uintmax_t)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_intmax_t_from_c8_string(intmax_t *rp, char const *src, int *ec)
+{
+ dk3_im_t val = DK3_IM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_im_from_c8_string(&val, src, ec)) {
+ *rp = (intmax_t)val;
+ back = 1;
+ } else {
+ *rp = (intmax_t)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+#endif
diff --git a/support/dktools/dk3maid8.h b/support/dktools/dk3maid8.h
new file mode 100644
index 0000000000..2ff3b8a2b0
--- /dev/null
+++ b/support/dktools/dk3maid8.h
@@ -0,0 +1,256 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3maid8.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK3MAID8_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3MAID8_H_INCLUDED 1
+
+
+#line 10 "dk3maid8.ctr"
+
+/** @file dk3maid8.h Retrieve numbers from decimal char strings.
+*/
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+#include <dk3types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert string to dk3_um_t.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_um_from_c8_string(dk3_um_t *rp, char const *src, int *ec);
+
+/** Convert string to dk3_im_t.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_im_from_c8_string(dk3_im_t *rp, char const *src, int *ec);
+
+/** Convert string to short.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_s_from_c8_string(short *rp, char const *src, int *ec);
+
+/** Convert string to unsigned short.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_us_from_c8_string(unsigned short *rp, char const *src, int *ec);
+
+/** Convert string to int.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_i_from_c8_string(int *rp, char const *src, int *ec);
+
+/** Convert string to unsigned.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_ui_from_c8_string(unsigned *rp, char const *src, int *ec);
+
+/** Convert string to long.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_l_from_c8_string(long *rp, char const *src, int *ec);
+
+/** Convert string to unsigned long.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_ul_from_c8_string(unsigned long *rp, char const *src, int *ec);
+
+#if DK3_HAVE_LONG_LONG
+
+/** Convert string to long long.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_ll_from_c8_string(long long *rp, char const *src, int *ec);
+
+/** Convert string to unsigned long long.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_ull_from_c8_string(unsigned long long *rp, char const *src, int *ec);
+
+#endif
+
+
+#if DK3_HAVE_INTMAX_T
+
+/** Convert string to intmax_t.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_intmax_t_from_c8_string(intmax_t *rp, char const *src, int *ec);
+
+/** Convert string to uintmax_t.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_uintmax_t_from_c8_string(uintmax_t *rp, char const *src, int *ec);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk3maidd.c b/support/dktools/dk3maidd.c
new file mode 100644
index 0000000000..341984107d
--- /dev/null
+++ b/support/dktools/dk3maidd.c
@@ -0,0 +1,592 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3maidd.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3maidd.c The dk3maidd module.
+*/
+
+
+#line 223 "dk3maidd.ctr"
+
+#include "dk3ma.h"
+
+
+
+
+
+#line 229 "dk3maidd.ctr"
+
+
+
+/** Constant numeric values.
+*/
+static dk3_um_t const dk3maidd_um_array[] = {
+#if DK3_HAVE_LONG_LONG
+ /* 0 */ (dk3_um_t)10ULL,
+ /* 1 */ (dk3_um_t)1ULL,
+ /* 2 */ (dk3_um_t)2ULL,
+ /* 3 */ (dk3_um_t)3ULL,
+ /* 4 */ (dk3_um_t)4ULL,
+ /* 5 */ (dk3_um_t)5ULL,
+ /* 6 */ (dk3_um_t)6ULL,
+ /* 7 */ (dk3_um_t)7ULL,
+ /* 8 */ (dk3_um_t)8ULL,
+ /* 9 */ (dk3_um_t)9ULL,
+ /* 10 */ (dk3_um_t)10ULL,
+ /* 11 */ (dk3_um_t)11ULL,
+ /* 12 */ (dk3_um_t)12ULL,
+ /* 13 */ (dk3_um_t)13ULL,
+ /* 14 */ (dk3_um_t)14ULL,
+ /* 15 */ (dk3_um_t)15ULL,
+ /* 16 */ (dk3_um_t)16ULL
+#else
+ /* 0 */ (dk3_um_t)10UL,
+ /* 1 */ (dk3_um_t)1UL,
+ /* 2 */ (dk3_um_t)2UL,
+ /* 3 */ (dk3_um_t)3UL,
+ /* 4 */ (dk3_um_t)4UL,
+ /* 5 */ (dk3_um_t)5UL,
+ /* 6 */ (dk3_um_t)6UL,
+ /* 7 */ (dk3_um_t)7UL,
+ /* 8 */ (dk3_um_t)8UL,
+ /* 9 */ (dk3_um_t)9UL,
+ /* 10 */ (dk3_um_t)10UL,
+ /* 11 */ (dk3_um_t)11UL,
+ /* 12 */ (dk3_um_t)12UL,
+ /* 13 */ (dk3_um_t)13UL,
+ /* 14 */ (dk3_um_t)14UL,
+ /* 15 */ (dk3_um_t)15UL,
+ /* 16 */ (dk3_um_t)16UL
+#endif
+};
+
+
+
+#if DK3_CHAR_SIZE > 1
+/** Find start of text in string.
+ @param str String to search for text.
+ @return Pointer to start of text on success, NULL on error.
+*/
+static
+dkChar const *
+dk3maidd_str_start(dkChar const *str)
+{
+ dkChar const *back = NULL;
+ if (NULL != str) {
+ back = str;
+ while((dkT(' ') == *back) || (dkT('\t') == *back)) { back++; }
+ switch(*back) {
+ case dkT('\0'): case dkT('\n'): case dkT('\r'): {
+ back = NULL;
+ } break;
+ }
+ }
+ return back;
+}
+#endif
+
+
+
+int
+dk3ma_um_from_string(dk3_um_t *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dkChar const *ptr = NULL; /* Current char to process */
+ dk3_um_t val = DK3_UM_0; /* Value found */
+ dk3_um_t op = DK3_UM_0; /* Operand to add */
+ int mec = 0; /* Math error code */
+ int back = 0; /* Function result */
+ int found = 0; /* Flag: Digits found */
+ int cc = 1; /* Flag: Can continue */
+ int action = 0; /* Action to take */
+
+
+#line 314 "dk3maidd.ctr"
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3maidd_str_start(src);
+ if (NULL != ptr) {
+ while (0 != cc) {
+ action = 0;
+ switch(*(ptr++)) {
+ case dkT('\0'): { /* End of string */
+ cc = 0;
+ if (0 != found) {
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ } break;
+ case dkT('0'): {
+ found = 1; action = 1; op = DK3_UM_0;
+ } break;
+ case dkT('1'): {
+ found = 1; action = 1; op = dk3maidd_um_array[1];
+ } break;
+ case dkT('2'): {
+ found = 1; action = 1; op = dk3maidd_um_array[2];
+ } break;
+ case dkT('3'): {
+ found = 1; action = 1; op = dk3maidd_um_array[3];
+ } break;
+ case dkT('4'): {
+ found = 1; action = 1; op = dk3maidd_um_array[4];
+ } break;
+ case dkT('5'): {
+ found = 1; action = 1; op = dk3maidd_um_array[5];
+ } break;
+ case dkT('6'): {
+ found = 1; action = 1; op = dk3maidd_um_array[6];
+ } break;
+ case dkT('7'): {
+ found = 1; action = 1; op = dk3maidd_um_array[7];
+ } break;
+ case dkT('8'): {
+ found = 1; action = 1; op = dk3maidd_um_array[8];
+ } break;
+ case dkT('9'): {
+ found = 1; action = 1; op = dk3maidd_um_array[9];
+ } break;
+ default: { /* Non-digit */
+ cc = 0;
+ if (0 != found) {
+ back = 1;
+ }
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ } break;
+ }
+ if (0 != cc) {
+ switch(action) {
+ case 1: {
+ val = dk3ma_um_add_ok(
+ dk3ma_um_mul_ok(val, dk3maidd_um_array[0], &mec), op, &mec
+ );
+
+#line 372 "dk3maidd.ctr"
+ if (0 != mec) {
+
+#line 373 "dk3maidd.ctr"
+ cc = 0;
+ val = DK3_UM_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } break;
+ }
+ }
+
+#line 380 "dk3maidd.ctr"
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ *rp = val;
+#if DK3_ON_WINDOWS
+
+
+#line 387 "dk3maidd.ctr"
+#else
+#if DK3_HAVE_INTMAX_T
+
+
+#line 390 "dk3maidd.ctr"
+#else
+#if DK3_HAVE_LONG_LONG
+
+
+#line 393 "dk3maidd.ctr"
+#else
+
+
+#line 395 "dk3maidd.ctr"
+#endif
+#endif
+#endif
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+
+#line 401 "dk3maidd.ctr"
+ return back;
+#else
+ return (dk3ma_um_from_c8_string(rp, src, ec));
+#endif
+}
+
+
+
+int
+dk3ma_im_from_string(dk3_im_t *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dkChar const *ptr = NULL; /* Start of text */
+ dk3_um_t umv = DK3_UM_0; /* Temporary value */
+ dk3_im_t val = DK3_IM_0; /* Conversion result */
+ int back = 0; /* Function result */
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3maidd_str_start(src);
+ if (NULL != ptr) {
+ if (dkT('-') == *ptr) {
+ ptr++;
+ if (0 != dk3ma_um_from_string(&umv, ptr, ec)) {
+ if ((dk3_um_t)DK3_IM_MAX >= umv) {
+ val = (dk3_im_t)umv;
+ val = DK3_IM_0 - val;
+ back = 1;
+ } else {
+ val = DK3_IM_MIN;
+#if VERSION_BEFORE_20140924
+ if ((dk3_um_t)(DK3_IM_MAX + (dk3_im_t)1L) == umv)
+#else
+ /* 2014-09-24: Fixed warning about integer overflow in constant.
+ */
+ if (((dk3_um_t)(DK3_IM_MAX) + (dk3_um_t)1UL) == umv)
+#endif
+ {
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ } else {
+ val = (dk3_im_t)umv;
+ }
+ } else {
+ if (0 != dk3ma_um_from_string(&umv, ptr, ec)) {
+ if ((dk3_um_t)DK3_IM_MAX >= umv) {
+ val = (dk3_im_t)umv;
+ back = 1;
+ } else {
+ val = DK3_IM_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ val = (dk3_im_t)umv;
+ }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ *rp = val;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_im_from_c8_string(rp, src, ec));
+#endif
+}
+
+
+
+int
+dk3ma_us_from_string(unsigned short *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_string(&val, src, ec)) {
+ if ((dk3_um_t)DK3_US_MAX >= val) {
+ *rp = (unsigned short)val;
+ back = 1;
+ } else {
+ *rp = DK3_US_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (unsigned short)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_us_from_c8_string(rp, src, ec));
+#endif
+}
+
+
+
+int
+dk3ma_s_from_string(short *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dk3_im_t val = DK3_IM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_im_from_string(&val, src, ec)) {
+ if (((dk3_im_t)DK3_S_MIN <= val) && ((dk3_im_t)DK3_S_MAX >= val)) {
+ *rp = (short)val;
+ back = 1;
+ } else {
+ if (DK3_IM_0 > val) { *rp = DK3_S_MIN; } else { *rp = DK3_S_MAX; }
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (short)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_s_from_c8_string(rp, src, ec));
+#endif
+}
+
+
+
+int
+dk3ma_ui_from_string(unsigned *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_string(&val, src, ec)) {
+ if ((dk3_um_t)DK3_U_MAX >= val) {
+ *rp = (unsigned)val;
+ back = 1;
+ } else {
+ *rp = DK3_U_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (unsigned)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_ui_from_c8_string(rp, src, ec));
+#endif
+}
+
+
+
+int
+dk3ma_i_from_string(int *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dk3_im_t val = DK3_IM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_im_from_string(&val, src, ec)) {
+ if (((dk3_im_t)DK3_I_MIN <= val) && ((dk3_im_t)DK3_I_MAX >= val)) {
+ *rp = (int)val;
+ back = 1;
+ } else {
+ if (DK3_IM_0 > val) { *rp = DK3_I_MIN; } else { *rp = DK3_I_MAX; }
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (int)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_i_from_c8_string(rp, src, ec));
+#endif
+}
+
+
+
+int
+dk3ma_ul_from_string(unsigned long *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_string(&val, src, ec)) {
+ if ((dk3_um_t)DK3_UL_MAX >= val) {
+ *rp = (unsigned long)val;
+ back = 1;
+ } else {
+ *rp = DK3_UL_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (unsigned long)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_ul_from_c8_string(rp, src, ec));
+#endif
+}
+
+
+
+int
+dk3ma_l_from_string(long *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dk3_im_t val = DK3_IM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_im_from_string(&val, src, ec)) {
+ if (((dk3_im_t)DK3_L_MIN <= val) && ((dk3_im_t)DK3_L_MAX >= val)) {
+ *rp = (long)val;
+ back = 1;
+ } else {
+ if (DK3_IM_0 > val) { *rp = DK3_L_MIN; } else { *rp = DK3_L_MAX; }
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (long)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_l_from_c8_string(rp, src, ec));
+#endif
+}
+
+
+#if DK3_HAVE_LONG_LONG
+
+int
+dk3ma_ull_from_string(unsigned long long *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_string(&val, src, ec)) {
+ if ((dk3_um_t)DK3_ULL_MAX >= val) {
+ *rp = (unsigned long long)val;
+ back = 1;
+ } else {
+ *rp = DK3_ULL_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (unsigned long long)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_ull_from_c8_string(rp, src, ec));
+#endif
+}
+
+
+
+int
+dk3ma_ll_from_string(long long *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dk3_im_t val = DK3_IM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_im_from_string(&val, src, ec)) {
+ if (((dk3_im_t)DK3_LL_MIN <= val) && ((dk3_im_t)DK3_LL_MAX >= val)) {
+ *rp = (long long)val;
+ back = 1;
+ } else {
+ if (DK3_IM_0 > val) { *rp = DK3_LL_MIN; } else { *rp = DK3_LL_MAX; }
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (long long)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_ll_from_c8_string(rp, src, ec));
+#endif
+}
+
+#endif
+
+#if DK3_HAVE_INTMAX_T
+
+int
+dk3ma_uintmax_t_from_string(uintmax_t *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_string(&val, src, ec)) {
+ *rp = (uintmax_t)val;
+ back = 1;
+ } else {
+ *rp = (uintmax_t)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_uintmax_t_from_c8_string(rp, src, ec));
+#endif
+}
+
+
+
+int
+dk3ma_intmax_t_from_string(intmax_t *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dk3_im_t val = DK3_IM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_im_from_string(&val, src, ec)) {
+ *rp = (intmax_t)val;
+ back = 1;
+ } else {
+ *rp = (intmax_t)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_intmax_t_from_c8_string(rp, src, ec));
+#endif
+}
+
+#endif
diff --git a/support/dktools/dk3maidd.ctr b/support/dktools/dk3maidd.ctr
new file mode 100644
index 0000000000..30563b4e44
--- /dev/null
+++ b/support/dktools/dk3maidd.ctr
@@ -0,0 +1,754 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2014-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk3maidd.h Retrieve numbers from decimal dkChar strings.
+*/
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+#include <dk3types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert string to dk3_um_t.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_um_from_string(dk3_um_t *rp, dkChar const *src, int *ec);
+
+/** Convert string to dk3_im_t.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_im_from_string(dk3_im_t *rp, dkChar const *src, int *ec);
+
+/** Convert string to short.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_s_from_string(short *rp, dkChar const *src, int *ec);
+
+/** Convert string to unsigned short.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_us_from_string(unsigned short *rp, dkChar const *src, int *ec);
+
+/** Convert string to int.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_i_from_string(int *rp, dkChar const *src, int *ec);
+
+/** Convert string to unsigned.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_ui_from_string(unsigned *rp, dkChar const *src, int *ec);
+
+/** Convert string to long.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_l_from_string(long *rp, dkChar const *src, int *ec);
+
+/** Convert string to unsigned long.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_ul_from_string(unsigned long *rp, dkChar const *src, int *ec);
+
+#if DK3_HAVE_LONG_LONG
+
+/** Convert string to long long.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_ll_from_string(long long *rp, dkChar const *src, int *ec);
+
+/** Convert string to unsigned long long.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_ull_from_string(unsigned long long *rp, dkChar const *src, int *ec);
+
+#endif
+
+#if DK3_HAVE_INTMAX_T
+
+/** Convert string to intmax_t.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_intmax_t_from_string(intmax_t *rp, dkChar const *src, int *ec);
+
+/** Convert string to uintmax_t.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_uintmax_t_from_string(uintmax_t *rp, dkChar const *src, int *ec);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk3ma.h"
+
+
+
+$!trace-include
+
+
+
+/** Constant numeric values.
+*/
+static dk3_um_t const dk3maidd_um_array[] = {
+#if DK3_HAVE_LONG_LONG
+ /* 0 */ (dk3_um_t)10ULL,
+ /* 1 */ (dk3_um_t)1ULL,
+ /* 2 */ (dk3_um_t)2ULL,
+ /* 3 */ (dk3_um_t)3ULL,
+ /* 4 */ (dk3_um_t)4ULL,
+ /* 5 */ (dk3_um_t)5ULL,
+ /* 6 */ (dk3_um_t)6ULL,
+ /* 7 */ (dk3_um_t)7ULL,
+ /* 8 */ (dk3_um_t)8ULL,
+ /* 9 */ (dk3_um_t)9ULL,
+ /* 10 */ (dk3_um_t)10ULL,
+ /* 11 */ (dk3_um_t)11ULL,
+ /* 12 */ (dk3_um_t)12ULL,
+ /* 13 */ (dk3_um_t)13ULL,
+ /* 14 */ (dk3_um_t)14ULL,
+ /* 15 */ (dk3_um_t)15ULL,
+ /* 16 */ (dk3_um_t)16ULL
+#else
+ /* 0 */ (dk3_um_t)10UL,
+ /* 1 */ (dk3_um_t)1UL,
+ /* 2 */ (dk3_um_t)2UL,
+ /* 3 */ (dk3_um_t)3UL,
+ /* 4 */ (dk3_um_t)4UL,
+ /* 5 */ (dk3_um_t)5UL,
+ /* 6 */ (dk3_um_t)6UL,
+ /* 7 */ (dk3_um_t)7UL,
+ /* 8 */ (dk3_um_t)8UL,
+ /* 9 */ (dk3_um_t)9UL,
+ /* 10 */ (dk3_um_t)10UL,
+ /* 11 */ (dk3_um_t)11UL,
+ /* 12 */ (dk3_um_t)12UL,
+ /* 13 */ (dk3_um_t)13UL,
+ /* 14 */ (dk3_um_t)14UL,
+ /* 15 */ (dk3_um_t)15UL,
+ /* 16 */ (dk3_um_t)16UL
+#endif
+};
+
+
+
+#if DK3_CHAR_SIZE > 1
+/** Find start of text in string.
+ @param str String to search for text.
+ @return Pointer to start of text on success, NULL on error.
+*/
+static
+dkChar const *
+dk3maidd_str_start(dkChar const *str)
+{
+ dkChar const *back = NULL;
+ if (NULL != str) {
+ back = str;
+ while((dkT(' ') == *back) || (dkT('\t') == *back)) { back++; }
+ switch(*back) {
+ case dkT('\0'): case dkT('\n'): case dkT('\r'): {
+ back = NULL;
+ } break;
+ }
+ }
+ return back;
+}
+#endif
+
+
+
+int
+dk3ma_um_from_string(dk3_um_t *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dkChar const *ptr = NULL; /* Current char to process */
+ dk3_um_t val = DK3_UM_0; /* Value found */
+ dk3_um_t op = DK3_UM_0; /* Operand to add */
+ int mec = 0; /* Math error code */
+ int back = 0; /* Function result */
+ int found = 0; /* Flag: Digits found */
+ int cc = 1; /* Flag: Can continue */
+ int action = 0; /* Action to take */
+ $? "+ dk3ma_um_from_string \"%!ds\"", TR_STR(src)
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3maidd_str_start(src);
+ if (NULL != ptr) {
+ while (0 != cc) {
+ action = 0;
+ switch(*(ptr++)) {
+ case dkT('\0'): { /* End of string */
+ cc = 0;
+ if (0 != found) {
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ } break;
+ case dkT('0'): {
+ found = 1; action = 1; op = DK3_UM_0;
+ } break;
+ case dkT('1'): {
+ found = 1; action = 1; op = dk3maidd_um_array[1];
+ } break;
+ case dkT('2'): {
+ found = 1; action = 1; op = dk3maidd_um_array[2];
+ } break;
+ case dkT('3'): {
+ found = 1; action = 1; op = dk3maidd_um_array[3];
+ } break;
+ case dkT('4'): {
+ found = 1; action = 1; op = dk3maidd_um_array[4];
+ } break;
+ case dkT('5'): {
+ found = 1; action = 1; op = dk3maidd_um_array[5];
+ } break;
+ case dkT('6'): {
+ found = 1; action = 1; op = dk3maidd_um_array[6];
+ } break;
+ case dkT('7'): {
+ found = 1; action = 1; op = dk3maidd_um_array[7];
+ } break;
+ case dkT('8'): {
+ found = 1; action = 1; op = dk3maidd_um_array[8];
+ } break;
+ case dkT('9'): {
+ found = 1; action = 1; op = dk3maidd_um_array[9];
+ } break;
+ default: { /* Non-digit */
+ cc = 0;
+ if (0 != found) {
+ back = 1;
+ }
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ } break;
+ }
+ if (0 != cc) {
+ switch(action) {
+ case 1: {
+ val = dk3ma_um_add_ok(
+ dk3ma_um_mul_ok(val, dk3maidd_um_array[0], &mec), op, &mec
+ ); $? ". mec = %d", mec
+ if (0 != mec) { $? "! mec != 0"
+ cc = 0;
+ val = DK3_UM_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } break;
+ }
+ } $? ". mec = %d", mec
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ *rp = val;
+#if DK3_ON_WINDOWS
+ $? ". value = %I64u", val
+#else
+#if DK3_HAVE_INTMAX_T
+ $? ". value = %ju", val
+#else
+#if DK3_HAVE_LONG_LONG
+ $? ". value = %llu", val
+#else
+ $? ". value = %lu", val
+#endif
+#endif
+#endif
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ } $? "- dk3ma_um_from_string %d", back
+ return back;
+#else
+ return (dk3ma_um_from_c8_string(rp, src, ec));
+#endif
+}
+
+
+
+int
+dk3ma_im_from_string(dk3_im_t *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dkChar const *ptr = NULL; /* Start of text */
+ dk3_um_t umv = DK3_UM_0; /* Temporary value */
+ dk3_im_t val = DK3_IM_0; /* Conversion result */
+ int back = 0; /* Function result */
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3maidd_str_start(src);
+ if (NULL != ptr) {
+ if (dkT('-') == *ptr) {
+ ptr++;
+ if (0 != dk3ma_um_from_string(&umv, ptr, ec)) {
+ if ((dk3_um_t)DK3_IM_MAX >= umv) {
+ val = (dk3_im_t)umv;
+ val = DK3_IM_0 - val;
+ back = 1;
+ } else {
+ val = DK3_IM_MIN;
+#if VERSION_BEFORE_20140924
+ if ((dk3_um_t)(DK3_IM_MAX + (dk3_im_t)1L) == umv)
+#else
+ /* 2014-09-24: Fixed warning about integer overflow in constant.
+ */
+ if (((dk3_um_t)(DK3_IM_MAX) + (dk3_um_t)1UL) == umv)
+#endif
+ {
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ } else {
+ val = (dk3_im_t)umv;
+ }
+ } else {
+ if (0 != dk3ma_um_from_string(&umv, ptr, ec)) {
+ if ((dk3_um_t)DK3_IM_MAX >= umv) {
+ val = (dk3_im_t)umv;
+ back = 1;
+ } else {
+ val = DK3_IM_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ val = (dk3_im_t)umv;
+ }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ *rp = val;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_im_from_c8_string(rp, src, ec));
+#endif
+}
+
+
+
+int
+dk3ma_us_from_string(unsigned short *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_string(&val, src, ec)) {
+ if ((dk3_um_t)DK3_US_MAX >= val) {
+ *rp = (unsigned short)val;
+ back = 1;
+ } else {
+ *rp = DK3_US_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (unsigned short)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_us_from_c8_string(rp, src, ec));
+#endif
+}
+
+
+
+int
+dk3ma_s_from_string(short *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dk3_im_t val = DK3_IM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_im_from_string(&val, src, ec)) {
+ if (((dk3_im_t)DK3_S_MIN <= val) && ((dk3_im_t)DK3_S_MAX >= val)) {
+ *rp = (short)val;
+ back = 1;
+ } else {
+ if (DK3_IM_0 > val) { *rp = DK3_S_MIN; } else { *rp = DK3_S_MAX; }
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (short)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_s_from_c8_string(rp, src, ec));
+#endif
+}
+
+
+
+int
+dk3ma_ui_from_string(unsigned *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_string(&val, src, ec)) {
+ if ((dk3_um_t)DK3_U_MAX >= val) {
+ *rp = (unsigned)val;
+ back = 1;
+ } else {
+ *rp = DK3_U_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (unsigned)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_ui_from_c8_string(rp, src, ec));
+#endif
+}
+
+
+
+int
+dk3ma_i_from_string(int *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dk3_im_t val = DK3_IM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_im_from_string(&val, src, ec)) {
+ if (((dk3_im_t)DK3_I_MIN <= val) && ((dk3_im_t)DK3_I_MAX >= val)) {
+ *rp = (int)val;
+ back = 1;
+ } else {
+ if (DK3_IM_0 > val) { *rp = DK3_I_MIN; } else { *rp = DK3_I_MAX; }
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (int)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_i_from_c8_string(rp, src, ec));
+#endif
+}
+
+
+
+int
+dk3ma_ul_from_string(unsigned long *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_string(&val, src, ec)) {
+ if ((dk3_um_t)DK3_UL_MAX >= val) {
+ *rp = (unsigned long)val;
+ back = 1;
+ } else {
+ *rp = DK3_UL_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (unsigned long)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_ul_from_c8_string(rp, src, ec));
+#endif
+}
+
+
+
+int
+dk3ma_l_from_string(long *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dk3_im_t val = DK3_IM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_im_from_string(&val, src, ec)) {
+ if (((dk3_im_t)DK3_L_MIN <= val) && ((dk3_im_t)DK3_L_MAX >= val)) {
+ *rp = (long)val;
+ back = 1;
+ } else {
+ if (DK3_IM_0 > val) { *rp = DK3_L_MIN; } else { *rp = DK3_L_MAX; }
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (long)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_l_from_c8_string(rp, src, ec));
+#endif
+}
+
+
+#if DK3_HAVE_LONG_LONG
+
+int
+dk3ma_ull_from_string(unsigned long long *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_string(&val, src, ec)) {
+ if ((dk3_um_t)DK3_ULL_MAX >= val) {
+ *rp = (unsigned long long)val;
+ back = 1;
+ } else {
+ *rp = DK3_ULL_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (unsigned long long)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_ull_from_c8_string(rp, src, ec));
+#endif
+}
+
+
+
+int
+dk3ma_ll_from_string(long long *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dk3_im_t val = DK3_IM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_im_from_string(&val, src, ec)) {
+ if (((dk3_im_t)DK3_LL_MIN <= val) && ((dk3_im_t)DK3_LL_MAX >= val)) {
+ *rp = (long long)val;
+ back = 1;
+ } else {
+ if (DK3_IM_0 > val) { *rp = DK3_LL_MIN; } else { *rp = DK3_LL_MAX; }
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (long long)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_ll_from_c8_string(rp, src, ec));
+#endif
+}
+
+#endif
+
+#if DK3_HAVE_INTMAX_T
+
+int
+dk3ma_uintmax_t_from_string(uintmax_t *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_string(&val, src, ec)) {
+ *rp = (uintmax_t)val;
+ back = 1;
+ } else {
+ *rp = (uintmax_t)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_uintmax_t_from_c8_string(rp, src, ec));
+#endif
+}
+
+
+
+int
+dk3ma_intmax_t_from_string(intmax_t *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dk3_im_t val = DK3_IM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_im_from_string(&val, src, ec)) {
+ *rp = (intmax_t)val;
+ back = 1;
+ } else {
+ *rp = (intmax_t)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_intmax_t_from_c8_string(rp, src, ec));
+#endif
+}
+
+#endif
diff --git a/support/dktools/dk3maidd.h b/support/dktools/dk3maidd.h
new file mode 100644
index 0000000000..ad4db9f280
--- /dev/null
+++ b/support/dktools/dk3maidd.h
@@ -0,0 +1,255 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3maidd.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK3MAIDD_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3MAIDD_H_INCLUDED 1
+
+
+#line 10 "dk3maidd.ctr"
+
+/** @file dk3maidd.h Retrieve numbers from decimal dkChar strings.
+*/
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+#include <dk3types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert string to dk3_um_t.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_um_from_string(dk3_um_t *rp, dkChar const *src, int *ec);
+
+/** Convert string to dk3_im_t.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_im_from_string(dk3_im_t *rp, dkChar const *src, int *ec);
+
+/** Convert string to short.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_s_from_string(short *rp, dkChar const *src, int *ec);
+
+/** Convert string to unsigned short.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_us_from_string(unsigned short *rp, dkChar const *src, int *ec);
+
+/** Convert string to int.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_i_from_string(int *rp, dkChar const *src, int *ec);
+
+/** Convert string to unsigned.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_ui_from_string(unsigned *rp, dkChar const *src, int *ec);
+
+/** Convert string to long.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_l_from_string(long *rp, dkChar const *src, int *ec);
+
+/** Convert string to unsigned long.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_ul_from_string(unsigned long *rp, dkChar const *src, int *ec);
+
+#if DK3_HAVE_LONG_LONG
+
+/** Convert string to long long.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_ll_from_string(long long *rp, dkChar const *src, int *ec);
+
+/** Convert string to unsigned long long.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_ull_from_string(unsigned long long *rp, dkChar const *src, int *ec);
+
+#endif
+
+#if DK3_HAVE_INTMAX_T
+
+/** Convert string to intmax_t.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_intmax_t_from_string(intmax_t *rp, dkChar const *src, int *ec);
+
+/** Convert string to uintmax_t.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_uintmax_t_from_string(uintmax_t *rp, dkChar const *src, int *ec);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk3maih8.c b/support/dktools/dk3maih8.c
new file mode 100644
index 0000000000..d50c8f0385
--- /dev/null
+++ b/support/dktools/dk3maih8.c
@@ -0,0 +1,657 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3maih8.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3maih8.c The dk3maih8 module.
+*/
+
+
+#line 223 "dk3maih8.ctr"
+
+#include "dk3ma.h"
+
+
+
+
+
+#line 229 "dk3maih8.ctr"
+
+
+
+/** Constant numeric values.
+*/
+static dk3_um_t const dk3maih8_um_array[] = {
+#if DK3_HAVE_LONG_LONG
+ /* 0 */ (dk3_um_t)10ULL,
+ /* 1 */ (dk3_um_t)1ULL,
+ /* 2 */ (dk3_um_t)2ULL,
+ /* 3 */ (dk3_um_t)3ULL,
+ /* 4 */ (dk3_um_t)4ULL,
+ /* 5 */ (dk3_um_t)5ULL,
+ /* 6 */ (dk3_um_t)6ULL,
+ /* 7 */ (dk3_um_t)7ULL,
+ /* 8 */ (dk3_um_t)8ULL,
+ /* 9 */ (dk3_um_t)9ULL,
+ /* 10 */ (dk3_um_t)10ULL,
+ /* 11 */ (dk3_um_t)11ULL,
+ /* 12 */ (dk3_um_t)12ULL,
+ /* 13 */ (dk3_um_t)13ULL,
+ /* 14 */ (dk3_um_t)14ULL,
+ /* 15 */ (dk3_um_t)15ULL,
+ /* 16 */ (dk3_um_t)16ULL
+#else
+ /* 0 */ (dk3_um_t)10UL,
+ /* 1 */ (dk3_um_t)1UL,
+ /* 2 */ (dk3_um_t)2UL,
+ /* 3 */ (dk3_um_t)3UL,
+ /* 4 */ (dk3_um_t)4UL,
+ /* 5 */ (dk3_um_t)5UL,
+ /* 6 */ (dk3_um_t)6UL,
+ /* 7 */ (dk3_um_t)7UL,
+ /* 8 */ (dk3_um_t)8UL,
+ /* 9 */ (dk3_um_t)9UL,
+ /* 10 */ (dk3_um_t)10UL,
+ /* 11 */ (dk3_um_t)11UL,
+ /* 12 */ (dk3_um_t)12UL,
+ /* 13 */ (dk3_um_t)13UL,
+ /* 14 */ (dk3_um_t)14UL,
+ /* 15 */ (dk3_um_t)15UL,
+ /* 16 */ (dk3_um_t)16UL
+#endif
+};
+
+
+
+/** Find start of text in string.
+ @param str String to search for text.
+ @return Pointer to start of text on success, NULL on error.
+*/
+static
+char const *
+dk3maih8_str_c8_start(char const *str)
+{
+ char const *back = NULL;
+ if (NULL != str) {
+ back = str;
+ while((' ' == *back) || ('\t' == *back)) { back++; }
+ switch(*back) {
+ case '\0': case '\n': case '\r': {
+ back = NULL;
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_um_from_c8_hex_string(dk3_um_t *rp, char const *src, int *ec)
+{
+ char const *ptr = NULL; /* Current char to process */
+ dk3_um_t val = DK3_UM_0; /* Value found */
+ dk3_um_t op = DK3_UM_0; /* Operand to add */
+ int mec = 0; /* Math error code */
+ int back = 0; /* Function result */
+ int found = 0; /* Flag: Digits found */
+ int cc = 1; /* Flag: Can continue */
+ int action = 0; /* Action to take */
+
+
+#line 311 "dk3maih8.ctr"
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3maih8_str_c8_start(src);
+ if (NULL != ptr) {
+ if ('0' == *ptr) { if(('x' == ptr[1])||('X' == ptr[1])) {ptr++; ptr++;} }
+ while (0 != cc) {
+ action = 0;
+ switch(*(ptr++)) {
+ case '\0': { /* End of string */
+ cc = 0;
+ if (0 != found) {
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ } break;
+ case '0': {
+ found = 1; action = 1; op = DK3_UM_0;
+ } break;
+ case '1': {
+ found = 1; action = 1; op = dk3maih8_um_array[1];
+ } break;
+ case '2': {
+ found = 1; action = 1; op = dk3maih8_um_array[2];
+ } break;
+ case '3': {
+ found = 1; action = 1; op = dk3maih8_um_array[3];
+ } break;
+ case '4': {
+ found = 1; action = 1; op = dk3maih8_um_array[4];
+ } break;
+ case '5': {
+ found = 1; action = 1; op = dk3maih8_um_array[5];
+ } break;
+ case '6': {
+ found = 1; action = 1; op = dk3maih8_um_array[6];
+ } break;
+ case '7': {
+ found = 1; action = 1; op = dk3maih8_um_array[7];
+ } break;
+ case '8': {
+ found = 1; action = 1; op = dk3maih8_um_array[8];
+ } break;
+ case '9': {
+ found = 1; action = 1; op = dk3maih8_um_array[9];
+ } break;
+ case 'a': case 'A': {
+ found = 1; action = 1; op = dk3maih8_um_array[10];
+ } break;
+ case 'b': case 'B': {
+ found = 1; action = 1; op = dk3maih8_um_array[11];
+ } break;
+ case 'c': case 'C': {
+ found = 1; action = 1; op = dk3maih8_um_array[12];
+ } break;
+ case 'd': case 'D': {
+ found = 1; action = 1; op = dk3maih8_um_array[13];
+ } break;
+ case 'e': case 'E': {
+ found = 1; action = 1; op = dk3maih8_um_array[14];
+ } break;
+ case 'f': case 'F': {
+ found = 1; action = 1; op = dk3maih8_um_array[15];
+ } break;
+ default: { /* Non-digit */
+ cc = 0;
+ if (0 != found) {
+ back = 1;
+ }
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ } break;
+ }
+ if (0 != cc) {
+ switch(action) {
+ case 1: {
+ val = dk3ma_um_add_ok(
+ dk3ma_um_mul_ok(val, dk3maih8_um_array[16], &mec), op, &mec
+ );
+
+#line 388 "dk3maih8.ctr"
+ if (0 != mec) {
+
+#line 389 "dk3maih8.ctr"
+ cc = 0;
+ val = DK3_UM_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } break;
+ }
+ }
+
+#line 396 "dk3maih8.ctr"
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ *rp = val;
+#if DK3_ON_WINDOWS
+
+
+#line 403 "dk3maih8.ctr"
+#else
+#if DK3_HAVE_INTMAX_T
+
+
+#line 406 "dk3maih8.ctr"
+#else
+#if DK3_HAVE_LONG_LONG
+
+
+#line 409 "dk3maih8.ctr"
+#else
+
+
+#line 411 "dk3maih8.ctr"
+#endif
+#endif
+#endif
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+
+#line 417 "dk3maih8.ctr"
+ return back;
+}
+
+
+
+int
+dk3ma_im_from_c8_hex_string(dk3_im_t *rp, char const *src, int *ec)
+{
+ char const *ptr = NULL; /* Start of text */
+ dk3_um_t umv = DK3_UM_0; /* Temporary value */
+ dk3_im_t val = DK3_IM_0; /* Conversion result */
+ int back = 0; /* Function result */
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3maih8_str_c8_start(src);
+ if (NULL != ptr) {
+ if ('-' == *ptr) {
+ ptr++;
+ if (0 != dk3ma_um_from_c8_hex_string(&umv, ptr, ec)) {
+ if ((dk3_um_t)DK3_IM_MAX >= umv) {
+ val = (dk3_im_t)umv;
+ val = DK3_IM_0 - val;
+ back = 1;
+ } else {
+ val = DK3_IM_MIN;
+#if 0
+ if ((dk3_um_t)(DK3_IM_MAX + (dk3_im_t)1L) == umv)
+#else
+ if (((dk3_um_t)DK3_IM_MAX + (dk3_um_t)1UL) == umv)
+#endif
+ {
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ } else {
+ val = (dk3_im_t)umv;
+ }
+ } else {
+ if (0 != dk3ma_um_from_c8_hex_string(&umv, ptr, ec)) {
+ val = (dk3_im_t)umv;
+ back = 1;
+ } else {
+ val = (dk3_im_t)umv;
+ }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ *rp = val;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_us_from_c8_hex_string(unsigned short *rp, char const *src, int *ec)
+{
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_c8_hex_string(&val, src, ec)) {
+ if ((dk3_um_t)DK3_US_MAX >= val) {
+ *rp = (unsigned short)val;
+ back = 1;
+ } else {
+ *rp = DK3_US_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (unsigned short)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_s_from_c8_hex_string(short *rp, char const *src, int *ec)
+{
+ const char *ptr;
+ unsigned short val = 0U;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3maih8_str_c8_start(src);
+ if (NULL != ptr) {
+ if ('-' == *ptr) {
+ if (0 != dk3ma_us_from_c8_hex_string(&val, &(ptr[1]), ec)) {
+ if ((unsigned short)DK3_S_MAX >= val) {
+ *rp = (short)(0 - (short)val);
+ back = 1;
+ } else {
+ *rp = DK3_S_MIN;
+ if (((unsigned short)DK3_S_MAX + (unsigned short)1U) == val) {
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ } else {
+ *rp = (short)val;
+ }
+ } else {
+ if (0 != dk3ma_us_from_c8_hex_string(&val, ptr, ec)) {
+ *rp = (short)val;
+ back = 1;
+ } else {
+ *rp = (short)val;
+ }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_ui_from_c8_hex_string(unsigned *rp, char const *src, int *ec)
+{
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_c8_hex_string(&val, src, ec)) {
+ if ((dk3_um_t)DK3_U_MAX >= val) {
+ *rp = (unsigned)val;
+ back = 1;
+ } else {
+ *rp = DK3_U_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (unsigned)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_i_from_c8_hex_string(int *rp, char const *src, int *ec)
+{
+ const char *ptr;
+ unsigned val = 0U;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3maih8_str_c8_start(src);
+ if (NULL != ptr) {
+ if ('-' == *ptr) {
+ if (0 != dk3ma_ui_from_c8_hex_string(&val, &(ptr[1]), ec)) {
+ if ((unsigned)DK3_I_MAX >= val) {
+ *rp = 0 - (int)val;
+ } else {
+ *rp = DK3_I_MIN;
+ if (((unsigned)DK3_I_MAX + 1U) == val) {
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ } else {
+ *rp = (int)val;
+ }
+ } else {
+ if (0 != dk3ma_ui_from_c8_hex_string(&val, ptr, ec)) {
+ *rp = (int)val;
+ back = 1;
+ } else {
+ *rp = (int)val;
+ }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_ul_from_c8_hex_string(unsigned long *rp, char const *src, int *ec)
+{
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_c8_hex_string(&val, src, ec)) {
+ if ((dk3_um_t)DK3_UL_MAX >= val) {
+ *rp = (unsigned long)val;
+ back = 1;
+ } else {
+ *rp = DK3_UL_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (unsigned long)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_l_from_c8_hex_string(long *rp, char const *src, int *ec)
+{
+ const char *ptr;
+ unsigned long val = 0UL;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3maih8_str_c8_start(src);
+ if (NULL != ptr) {
+ if ('-' == *ptr) {
+ if (0 != dk3ma_ul_from_c8_hex_string(&val, &(ptr[1]), ec)) {
+ if ((unsigned long)DK3_L_MAX >= val) {
+ *rp = (long)(0L - (long)val);
+ back = 1;
+ } else {
+ *rp = DK3_L_MIN;
+ if (((unsigned long)DK3_L_MAX + 1UL) == val) {
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ } else {
+ *rp = (long)val;
+ }
+ } else {
+ if (0 != dk3ma_ul_from_c8_hex_string(&val, ptr, ec)) {
+ *rp = (long)val;
+ back = 1;
+ } else {
+ *rp = (long)val;
+ }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+
+
+#if DK3_HAVE_LONG_LONG
+
+int
+dk3ma_ull_from_c8_hex_string(unsigned long long *rp, char const *src, int *ec)
+{
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_c8_hex_string(&val, src, ec)) {
+ if ((dk3_um_t)DK3_ULL_MAX >= val) {
+ *rp = (unsigned long long)val;
+ back = 1;
+ } else {
+ *rp = DK3_ULL_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (unsigned long long)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_ll_from_c8_hex_string(long long *rp, char const *src, int *ec)
+{
+ char const *ptr;
+ unsigned long long val = 0ULL;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3maih8_str_c8_start(src);
+ if (NULL != ptr) {
+ if ('-' == *ptr) {
+ if (0 != dk3ma_ull_from_c8_hex_string(&val, &(ptr[1]), ec)) {
+ if ((unsigned long long)DK3_LL_MAX >= val) {
+ *rp = (long long)(0LL - (long long)val);
+ back = 1;
+ } else {
+ *rp = DK3_LL_MIN;
+ if (((unsigned long long)DK3_LL_MAX + 1ULL) == val) {
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ } else {
+ *rp = (long long)val;
+ }
+ } else {
+ if (0 != dk3ma_ull_from_c8_hex_string(&val, ptr, ec)) {
+ *rp = (long long)val;
+ back = 1;
+ } else {
+ *rp = (long long)val;
+ }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+#endif
+
+
+
+#if DK3_HAVE_INTMAX_T
+
+int
+dk3ma_uintmax_t_from_c8_hex_string(uintmax_t *rp, char const *src, int *ec)
+{
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_c8_hex_string(&val, src, ec)) {
+ *rp = (uintmax_t)val;
+ back = 1;
+ } else {
+ *rp = (uintmax_t)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_intmax_t_from_c8_hex_string(intmax_t *rp, char const *src, int *ec)
+{
+ const char *ptr;
+ uintmax_t val = DK3_UINTMAX_T_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3maih8_str_c8_start(src);
+ if (NULL != ptr) {
+ if ('-' == *ptr) {
+ if (0 != dk3ma_uintmax_t_from_c8_hex_string(&val, &(ptr[1]), ec)) {
+ if ((uintmax_t)DK3_INTMAX_T_MAX >= val) {
+ *rp = (intmax_t)(DK3_INTMAX_T_0 - (intmax_t)val);
+ back = 1;
+ } else {
+ *rp = DK3_INTMAX_T_MIN;
+ if (((uintmax_t)DK3_INTMAX_T_MAX + DK3_UINTMAX_T_1) == val) {
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ } else {
+ *rp = (intmax_t)val;
+ }
+ } else {
+ if (0 != dk3ma_uintmax_t_from_c8_hex_string(&val, ptr, ec)) {
+ *rp = (intmax_t)val;
+ back = 1;
+ } else {
+ *rp = (intmax_t)val;
+ }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+#endif
+
diff --git a/support/dktools/dk3maih8.ctr b/support/dktools/dk3maih8.ctr
new file mode 100644
index 0000000000..29ecec837a
--- /dev/null
+++ b/support/dktools/dk3maih8.ctr
@@ -0,0 +1,819 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2014-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk3maih8.h Retrieve numbers from hexadecimal char strings.
+*/
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+#include <dk3types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert string to dk3_um_t.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_um_from_c8_hex_string(dk3_um_t *rp, char const *src, int *ec);
+
+/** Convert string to dk3_im_t.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_im_from_c8_hex_string(dk3_im_t *rp, char const *src, int *ec);
+
+/** Convert string to short.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_s_from_c8_hex_string(short *rp, char const *src, int *ec);
+
+/** Convert string to unsigned short.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_us_from_c8_hex_string(unsigned short *rp, char const *src, int *ec);
+
+/** Convert string to int.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_i_from_c8_hex_string(int *rp, char const *src, int *ec);
+
+/** Convert string to unsigned.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_ui_from_c8_hex_string(unsigned *rp, char const *src, int *ec);
+
+/** Convert string to long.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_l_from_c8_hex_string(long *rp, char const *src, int *ec);
+
+/** Convert string to unsigned long.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_ul_from_c8_hex_string(unsigned long *rp, char const *src, int *ec);
+
+#if DK3_HAVE_LONG_LONG
+
+/** Convert string to long long.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_ll_from_c8_hex_string(long long *rp, char const *src, int *ec);
+
+/** Convert string to unsigned long long.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_ull_from_c8_hex_string(unsigned long long *rp, char const *src, int *ec);
+
+#endif
+
+#if DK3_HAVE_INTMAX_T
+
+/** Convert string to intmax_t.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_intmax_t_from_c8_hex_string(intmax_t *rp, char const *src, int *ec);
+
+/** Convert string to uintmax_t.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_uintmax_t_from_c8_hex_string(uintmax_t *rp, char const *src, int *ec);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk3ma.h"
+
+
+
+$!trace-include
+
+
+
+/** Constant numeric values.
+*/
+static dk3_um_t const dk3maih8_um_array[] = {
+#if DK3_HAVE_LONG_LONG
+ /* 0 */ (dk3_um_t)10ULL,
+ /* 1 */ (dk3_um_t)1ULL,
+ /* 2 */ (dk3_um_t)2ULL,
+ /* 3 */ (dk3_um_t)3ULL,
+ /* 4 */ (dk3_um_t)4ULL,
+ /* 5 */ (dk3_um_t)5ULL,
+ /* 6 */ (dk3_um_t)6ULL,
+ /* 7 */ (dk3_um_t)7ULL,
+ /* 8 */ (dk3_um_t)8ULL,
+ /* 9 */ (dk3_um_t)9ULL,
+ /* 10 */ (dk3_um_t)10ULL,
+ /* 11 */ (dk3_um_t)11ULL,
+ /* 12 */ (dk3_um_t)12ULL,
+ /* 13 */ (dk3_um_t)13ULL,
+ /* 14 */ (dk3_um_t)14ULL,
+ /* 15 */ (dk3_um_t)15ULL,
+ /* 16 */ (dk3_um_t)16ULL
+#else
+ /* 0 */ (dk3_um_t)10UL,
+ /* 1 */ (dk3_um_t)1UL,
+ /* 2 */ (dk3_um_t)2UL,
+ /* 3 */ (dk3_um_t)3UL,
+ /* 4 */ (dk3_um_t)4UL,
+ /* 5 */ (dk3_um_t)5UL,
+ /* 6 */ (dk3_um_t)6UL,
+ /* 7 */ (dk3_um_t)7UL,
+ /* 8 */ (dk3_um_t)8UL,
+ /* 9 */ (dk3_um_t)9UL,
+ /* 10 */ (dk3_um_t)10UL,
+ /* 11 */ (dk3_um_t)11UL,
+ /* 12 */ (dk3_um_t)12UL,
+ /* 13 */ (dk3_um_t)13UL,
+ /* 14 */ (dk3_um_t)14UL,
+ /* 15 */ (dk3_um_t)15UL,
+ /* 16 */ (dk3_um_t)16UL
+#endif
+};
+
+
+
+/** Find start of text in string.
+ @param str String to search for text.
+ @return Pointer to start of text on success, NULL on error.
+*/
+static
+char const *
+dk3maih8_str_c8_start(char const *str)
+{
+ char const *back = NULL;
+ if (NULL != str) {
+ back = str;
+ while((' ' == *back) || ('\t' == *back)) { back++; }
+ switch(*back) {
+ case '\0': case '\n': case '\r': {
+ back = NULL;
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_um_from_c8_hex_string(dk3_um_t *rp, char const *src, int *ec)
+{
+ char const *ptr = NULL; /* Current char to process */
+ dk3_um_t val = DK3_UM_0; /* Value found */
+ dk3_um_t op = DK3_UM_0; /* Operand to add */
+ int mec = 0; /* Math error code */
+ int back = 0; /* Function result */
+ int found = 0; /* Flag: Digits found */
+ int cc = 1; /* Flag: Can continue */
+ int action = 0; /* Action to take */
+ $? "+ dk3ma_um_from_c8_hex_string \"%!8s\"", TR_8STR(src)
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3maih8_str_c8_start(src);
+ if (NULL != ptr) {
+ if ('0' == *ptr) { if(('x' == ptr[1])||('X' == ptr[1])) {ptr++; ptr++;} }
+ while (0 != cc) {
+ action = 0;
+ switch(*(ptr++)) {
+ case '\0': { /* End of string */
+ cc = 0;
+ if (0 != found) {
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ } break;
+ case '0': {
+ found = 1; action = 1; op = DK3_UM_0;
+ } break;
+ case '1': {
+ found = 1; action = 1; op = dk3maih8_um_array[1];
+ } break;
+ case '2': {
+ found = 1; action = 1; op = dk3maih8_um_array[2];
+ } break;
+ case '3': {
+ found = 1; action = 1; op = dk3maih8_um_array[3];
+ } break;
+ case '4': {
+ found = 1; action = 1; op = dk3maih8_um_array[4];
+ } break;
+ case '5': {
+ found = 1; action = 1; op = dk3maih8_um_array[5];
+ } break;
+ case '6': {
+ found = 1; action = 1; op = dk3maih8_um_array[6];
+ } break;
+ case '7': {
+ found = 1; action = 1; op = dk3maih8_um_array[7];
+ } break;
+ case '8': {
+ found = 1; action = 1; op = dk3maih8_um_array[8];
+ } break;
+ case '9': {
+ found = 1; action = 1; op = dk3maih8_um_array[9];
+ } break;
+ case 'a': case 'A': {
+ found = 1; action = 1; op = dk3maih8_um_array[10];
+ } break;
+ case 'b': case 'B': {
+ found = 1; action = 1; op = dk3maih8_um_array[11];
+ } break;
+ case 'c': case 'C': {
+ found = 1; action = 1; op = dk3maih8_um_array[12];
+ } break;
+ case 'd': case 'D': {
+ found = 1; action = 1; op = dk3maih8_um_array[13];
+ } break;
+ case 'e': case 'E': {
+ found = 1; action = 1; op = dk3maih8_um_array[14];
+ } break;
+ case 'f': case 'F': {
+ found = 1; action = 1; op = dk3maih8_um_array[15];
+ } break;
+ default: { /* Non-digit */
+ cc = 0;
+ if (0 != found) {
+ back = 1;
+ }
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ } break;
+ }
+ if (0 != cc) {
+ switch(action) {
+ case 1: {
+ val = dk3ma_um_add_ok(
+ dk3ma_um_mul_ok(val, dk3maih8_um_array[16], &mec), op, &mec
+ ); $? ". mec = %d", mec
+ if (0 != mec) { $? "! mec != 0"
+ cc = 0;
+ val = DK3_UM_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } break;
+ }
+ } $? ". mec = %d", mec
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ *rp = val;
+#if DK3_ON_WINDOWS
+ $? ". value = %I64u", val
+#else
+#if DK3_HAVE_INTMAX_T
+ $? ". value = %ju", val
+#else
+#if DK3_HAVE_LONG_LONG
+ $? ". value = %llu", val
+#else
+ $? ". value = %lu", val
+#endif
+#endif
+#endif
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ } $? "- dk3ma_um_from_c8_hex_string %d", back
+ return back;
+}
+
+
+
+int
+dk3ma_im_from_c8_hex_string(dk3_im_t *rp, char const *src, int *ec)
+{
+ char const *ptr = NULL; /* Start of text */
+ dk3_um_t umv = DK3_UM_0; /* Temporary value */
+ dk3_im_t val = DK3_IM_0; /* Conversion result */
+ int back = 0; /* Function result */
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3maih8_str_c8_start(src);
+ if (NULL != ptr) {
+ if ('-' == *ptr) {
+ ptr++;
+ if (0 != dk3ma_um_from_c8_hex_string(&umv, ptr, ec)) {
+ if ((dk3_um_t)DK3_IM_MAX >= umv) {
+ val = (dk3_im_t)umv;
+ val = DK3_IM_0 - val;
+ back = 1;
+ } else {
+ val = DK3_IM_MIN;
+#if 0
+ if ((dk3_um_t)(DK3_IM_MAX + (dk3_im_t)1L) == umv)
+#else
+ if (((dk3_um_t)DK3_IM_MAX + (dk3_um_t)1UL) == umv)
+#endif
+ {
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ } else {
+ val = (dk3_im_t)umv;
+ }
+ } else {
+ if (0 != dk3ma_um_from_c8_hex_string(&umv, ptr, ec)) {
+ val = (dk3_im_t)umv;
+ back = 1;
+ } else {
+ val = (dk3_im_t)umv;
+ }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ *rp = val;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_us_from_c8_hex_string(unsigned short *rp, char const *src, int *ec)
+{
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_c8_hex_string(&val, src, ec)) {
+ if ((dk3_um_t)DK3_US_MAX >= val) {
+ *rp = (unsigned short)val;
+ back = 1;
+ } else {
+ *rp = DK3_US_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (unsigned short)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_s_from_c8_hex_string(short *rp, char const *src, int *ec)
+{
+ const char *ptr;
+ unsigned short val = 0U;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3maih8_str_c8_start(src);
+ if (NULL != ptr) {
+ if ('-' == *ptr) {
+ if (0 != dk3ma_us_from_c8_hex_string(&val, &(ptr[1]), ec)) {
+ if ((unsigned short)DK3_S_MAX >= val) {
+ *rp = (short)(0 - (short)val);
+ back = 1;
+ } else {
+ *rp = DK3_S_MIN;
+ if (((unsigned short)DK3_S_MAX + (unsigned short)1U) == val) {
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ } else {
+ *rp = (short)val;
+ }
+ } else {
+ if (0 != dk3ma_us_from_c8_hex_string(&val, ptr, ec)) {
+ *rp = (short)val;
+ back = 1;
+ } else {
+ *rp = (short)val;
+ }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_ui_from_c8_hex_string(unsigned *rp, char const *src, int *ec)
+{
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_c8_hex_string(&val, src, ec)) {
+ if ((dk3_um_t)DK3_U_MAX >= val) {
+ *rp = (unsigned)val;
+ back = 1;
+ } else {
+ *rp = DK3_U_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (unsigned)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_i_from_c8_hex_string(int *rp, char const *src, int *ec)
+{
+ const char *ptr;
+ unsigned val = 0U;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3maih8_str_c8_start(src);
+ if (NULL != ptr) {
+ if ('-' == *ptr) {
+ if (0 != dk3ma_ui_from_c8_hex_string(&val, &(ptr[1]), ec)) {
+ if ((unsigned)DK3_I_MAX >= val) {
+ *rp = 0 - (int)val;
+ } else {
+ *rp = DK3_I_MIN;
+ if (((unsigned)DK3_I_MAX + 1U) == val) {
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ } else {
+ *rp = (int)val;
+ }
+ } else {
+ if (0 != dk3ma_ui_from_c8_hex_string(&val, ptr, ec)) {
+ *rp = (int)val;
+ back = 1;
+ } else {
+ *rp = (int)val;
+ }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_ul_from_c8_hex_string(unsigned long *rp, char const *src, int *ec)
+{
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_c8_hex_string(&val, src, ec)) {
+ if ((dk3_um_t)DK3_UL_MAX >= val) {
+ *rp = (unsigned long)val;
+ back = 1;
+ } else {
+ *rp = DK3_UL_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (unsigned long)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_l_from_c8_hex_string(long *rp, char const *src, int *ec)
+{
+ const char *ptr;
+ unsigned long val = 0UL;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3maih8_str_c8_start(src);
+ if (NULL != ptr) {
+ if ('-' == *ptr) {
+ if (0 != dk3ma_ul_from_c8_hex_string(&val, &(ptr[1]), ec)) {
+ if ((unsigned long)DK3_L_MAX >= val) {
+ *rp = (long)(0L - (long)val);
+ back = 1;
+ } else {
+ *rp = DK3_L_MIN;
+ if (((unsigned long)DK3_L_MAX + 1UL) == val) {
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ } else {
+ *rp = (long)val;
+ }
+ } else {
+ if (0 != dk3ma_ul_from_c8_hex_string(&val, ptr, ec)) {
+ *rp = (long)val;
+ back = 1;
+ } else {
+ *rp = (long)val;
+ }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+
+
+#if DK3_HAVE_LONG_LONG
+
+int
+dk3ma_ull_from_c8_hex_string(unsigned long long *rp, char const *src, int *ec)
+{
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_c8_hex_string(&val, src, ec)) {
+ if ((dk3_um_t)DK3_ULL_MAX >= val) {
+ *rp = (unsigned long long)val;
+ back = 1;
+ } else {
+ *rp = DK3_ULL_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (unsigned long long)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_ll_from_c8_hex_string(long long *rp, char const *src, int *ec)
+{
+ char const *ptr;
+ unsigned long long val = 0ULL;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3maih8_str_c8_start(src);
+ if (NULL != ptr) {
+ if ('-' == *ptr) {
+ if (0 != dk3ma_ull_from_c8_hex_string(&val, &(ptr[1]), ec)) {
+ if ((unsigned long long)DK3_LL_MAX >= val) {
+ *rp = (long long)(0LL - (long long)val);
+ back = 1;
+ } else {
+ *rp = DK3_LL_MIN;
+ if (((unsigned long long)DK3_LL_MAX + 1ULL) == val) {
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ } else {
+ *rp = (long long)val;
+ }
+ } else {
+ if (0 != dk3ma_ull_from_c8_hex_string(&val, ptr, ec)) {
+ *rp = (long long)val;
+ back = 1;
+ } else {
+ *rp = (long long)val;
+ }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+#endif
+
+
+
+#if DK3_HAVE_INTMAX_T
+
+int
+dk3ma_uintmax_t_from_c8_hex_string(uintmax_t *rp, char const *src, int *ec)
+{
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_c8_hex_string(&val, src, ec)) {
+ *rp = (uintmax_t)val;
+ back = 1;
+ } else {
+ *rp = (uintmax_t)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_intmax_t_from_c8_hex_string(intmax_t *rp, char const *src, int *ec)
+{
+ const char *ptr;
+ uintmax_t val = DK3_UINTMAX_T_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3maih8_str_c8_start(src);
+ if (NULL != ptr) {
+ if ('-' == *ptr) {
+ if (0 != dk3ma_uintmax_t_from_c8_hex_string(&val, &(ptr[1]), ec)) {
+ if ((uintmax_t)DK3_INTMAX_T_MAX >= val) {
+ *rp = (intmax_t)(DK3_INTMAX_T_0 - (intmax_t)val);
+ back = 1;
+ } else {
+ *rp = DK3_INTMAX_T_MIN;
+ if (((uintmax_t)DK3_INTMAX_T_MAX + DK3_UINTMAX_T_1) == val) {
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ } else {
+ *rp = (intmax_t)val;
+ }
+ } else {
+ if (0 != dk3ma_uintmax_t_from_c8_hex_string(&val, ptr, ec)) {
+ *rp = (intmax_t)val;
+ back = 1;
+ } else {
+ *rp = (intmax_t)val;
+ }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+}
+
+#endif
+
diff --git a/support/dktools/dk3maih8.h b/support/dktools/dk3maih8.h
new file mode 100644
index 0000000000..b08818e6a3
--- /dev/null
+++ b/support/dktools/dk3maih8.h
@@ -0,0 +1,255 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3maih8.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK3MAIH8_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3MAIH8_H_INCLUDED 1
+
+
+#line 10 "dk3maih8.ctr"
+
+/** @file dk3maih8.h Retrieve numbers from hexadecimal char strings.
+*/
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+#include <dk3types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert string to dk3_um_t.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_um_from_c8_hex_string(dk3_um_t *rp, char const *src, int *ec);
+
+/** Convert string to dk3_im_t.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_im_from_c8_hex_string(dk3_im_t *rp, char const *src, int *ec);
+
+/** Convert string to short.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_s_from_c8_hex_string(short *rp, char const *src, int *ec);
+
+/** Convert string to unsigned short.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_us_from_c8_hex_string(unsigned short *rp, char const *src, int *ec);
+
+/** Convert string to int.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_i_from_c8_hex_string(int *rp, char const *src, int *ec);
+
+/** Convert string to unsigned.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_ui_from_c8_hex_string(unsigned *rp, char const *src, int *ec);
+
+/** Convert string to long.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_l_from_c8_hex_string(long *rp, char const *src, int *ec);
+
+/** Convert string to unsigned long.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_ul_from_c8_hex_string(unsigned long *rp, char const *src, int *ec);
+
+#if DK3_HAVE_LONG_LONG
+
+/** Convert string to long long.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_ll_from_c8_hex_string(long long *rp, char const *src, int *ec);
+
+/** Convert string to unsigned long long.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_ull_from_c8_hex_string(unsigned long long *rp, char const *src, int *ec);
+
+#endif
+
+#if DK3_HAVE_INTMAX_T
+
+/** Convert string to intmax_t.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_intmax_t_from_c8_hex_string(intmax_t *rp, char const *src, int *ec);
+
+/** Convert string to uintmax_t.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_uintmax_t_from_c8_hex_string(uintmax_t *rp, char const *src, int *ec);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk3maihd.c b/support/dktools/dk3maihd.c
new file mode 100644
index 0000000000..09a4b16ce1
--- /dev/null
+++ b/support/dktools/dk3maihd.c
@@ -0,0 +1,706 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3maihd.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3maihd.c The dk3maihd module.
+*/
+
+
+#line 224 "dk3maihd.ctr"
+
+#include "dk3ma.h"
+
+
+
+
+
+#line 230 "dk3maihd.ctr"
+
+
+
+/** Constant numeric values.
+*/
+static dk3_um_t const dk3maihd_um_array[] = {
+#if DK3_HAVE_LONG_LONG
+ /* 0 */ (dk3_um_t)10ULL,
+ /* 1 */ (dk3_um_t)1ULL,
+ /* 2 */ (dk3_um_t)2ULL,
+ /* 3 */ (dk3_um_t)3ULL,
+ /* 4 */ (dk3_um_t)4ULL,
+ /* 5 */ (dk3_um_t)5ULL,
+ /* 6 */ (dk3_um_t)6ULL,
+ /* 7 */ (dk3_um_t)7ULL,
+ /* 8 */ (dk3_um_t)8ULL,
+ /* 9 */ (dk3_um_t)9ULL,
+ /* 10 */ (dk3_um_t)10ULL,
+ /* 11 */ (dk3_um_t)11ULL,
+ /* 12 */ (dk3_um_t)12ULL,
+ /* 13 */ (dk3_um_t)13ULL,
+ /* 14 */ (dk3_um_t)14ULL,
+ /* 15 */ (dk3_um_t)15ULL,
+ /* 16 */ (dk3_um_t)16ULL
+#else
+ /* 0 */ (dk3_um_t)10UL,
+ /* 1 */ (dk3_um_t)1UL,
+ /* 2 */ (dk3_um_t)2UL,
+ /* 3 */ (dk3_um_t)3UL,
+ /* 4 */ (dk3_um_t)4UL,
+ /* 5 */ (dk3_um_t)5UL,
+ /* 6 */ (dk3_um_t)6UL,
+ /* 7 */ (dk3_um_t)7UL,
+ /* 8 */ (dk3_um_t)8UL,
+ /* 9 */ (dk3_um_t)9UL,
+ /* 10 */ (dk3_um_t)10UL,
+ /* 11 */ (dk3_um_t)11UL,
+ /* 12 */ (dk3_um_t)12UL,
+ /* 13 */ (dk3_um_t)13UL,
+ /* 14 */ (dk3_um_t)14UL,
+ /* 15 */ (dk3_um_t)15UL,
+ /* 16 */ (dk3_um_t)16UL
+#endif
+};
+
+
+
+#if DK3_CHAR_SIZE > 1
+/** Find start of text in string.
+ @param str String to search for text.
+ @return Pointer to start of text on success, NULL on error.
+*/
+static
+dkChar const *
+dk3maihd_str_start(dkChar const *str)
+{
+ dkChar const *back = NULL;
+ if (NULL != str) {
+ back = str;
+ while((dkT(' ') == *back) || (dkT('\t') == *back)) { back++; }
+ switch(*back) {
+ case dkT('\0'): case dkT('\n'): case dkT('\r'): {
+ back = NULL;
+ } break;
+ }
+ }
+ return back;
+}
+#endif
+
+
+
+int
+dk3ma_um_from_hex_string(dk3_um_t *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dkChar const *ptr = NULL; /* Current char to process */
+ dk3_um_t val = DK3_UM_0; /* Value found */
+ dk3_um_t op = DK3_UM_0; /* Operand to add */
+ int mec = 0; /* Math error code */
+ int back = 0; /* Function result */
+ int found = 0; /* Flag: Digits found */
+ int cc = 1; /* Flag: Can continue */
+ int action = 0; /* Action to take */
+
+
+#line 315 "dk3maihd.ctr"
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3maihd_str_start(src);
+ if (NULL != ptr) {
+ while (0 != cc) {
+ action = 0;
+ switch(*(ptr++)) {
+ case dkT('\0'): { /* End of string */
+ cc = 0;
+ if (0 != found) {
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ } break;
+ case dkT('0'): {
+ found = 1; action = 1; op = DK3_UM_0;
+ } break;
+ case dkT('1'): {
+ found = 1; action = 1; op = dk3maihd_um_array[1];
+ } break;
+ case dkT('2'): {
+ found = 1; action = 1; op = dk3maihd_um_array[2];
+ } break;
+ case dkT('3'): {
+ found = 1; action = 1; op = dk3maihd_um_array[3];
+ } break;
+ case dkT('4'): {
+ found = 1; action = 1; op = dk3maihd_um_array[4];
+ } break;
+ case dkT('5'): {
+ found = 1; action = 1; op = dk3maihd_um_array[5];
+ } break;
+ case dkT('6'): {
+ found = 1; action = 1; op = dk3maihd_um_array[6];
+ } break;
+ case dkT('7'): {
+ found = 1; action = 1; op = dk3maihd_um_array[7];
+ } break;
+ case dkT('8'): {
+ found = 1; action = 1; op = dk3maihd_um_array[8];
+ } break;
+ case dkT('9'): {
+ found = 1; action = 1; op = dk3maihd_um_array[9];
+ } break;
+ case dkT('a'): case dkT('A'): {
+ found = 1; action = 1; op = dk3maihd_um_array[10];
+ } break;
+ case dkT('b'): case dkT('B'): {
+ found = 1; action = 1; op = dk3maihd_um_array[11];
+ } break;
+ case dkT('c'): case dkT('C'): {
+ found = 1; action = 1; op = dk3maihd_um_array[12];
+ } break;
+ case dkT('d'): case dkT('D'): {
+ found = 1; action = 1; op = dk3maihd_um_array[13];
+ } break;
+ case dkT('e'): case dkT('E'): {
+ found = 1; action = 1; op = dk3maihd_um_array[14];
+ } break;
+ case dkT('f'): case dkT('F'): {
+ found = 1; action = 1; op = dk3maihd_um_array[15];
+ } break;
+ default: { /* Non-digit */
+ cc = 0;
+ if (0 != found) {
+ back = 1;
+ }
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ } break;
+ }
+ if (0 != cc) {
+ switch(action) {
+ case 1: {
+ val = dk3ma_um_add_ok(
+ dk3ma_um_mul_ok(val, dk3maihd_um_array[16], &mec), op, &mec
+ );
+
+#line 391 "dk3maihd.ctr"
+ if (0 != mec) {
+
+#line 392 "dk3maihd.ctr"
+ cc = 0;
+ val = DK3_UM_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } break;
+ }
+ }
+
+#line 399 "dk3maihd.ctr"
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ *rp = val;
+#if DK3_ON_WINDOWS
+
+
+#line 406 "dk3maihd.ctr"
+#else
+#if DK3_HAVE_INTMAX_T
+
+
+#line 409 "dk3maihd.ctr"
+#else
+#if DK3_HAVE_LONG_LONG
+
+
+#line 412 "dk3maihd.ctr"
+#else
+
+
+#line 414 "dk3maihd.ctr"
+#endif
+#endif
+#endif
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+
+#line 420 "dk3maihd.ctr"
+ return back;
+#else
+ return (dk3ma_um_from_c8_hex_string(rp, src, ec));
+#endif
+}
+
+
+
+int
+dk3ma_im_from_hex_string(dk3_im_t *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dkChar const *ptr = NULL; /* Start of text */
+ dk3_um_t umv = DK3_UM_0; /* Temporary value */
+ dk3_im_t val = DK3_IM_0; /* Conversion result */
+ int back = 0; /* Function result */
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3maihd_str_start(src);
+ if (NULL != ptr) {
+ if (dkT('-') == *ptr) {
+ ptr++;
+ if (0 != dk3ma_um_from_hex_string(&umv, ptr, ec)) {
+ if ((dk3_um_t)DK3_IM_MAX >= umv) {
+ val = (dk3_im_t)umv;
+ val = DK3_IM_0 - val;
+ back = 1;
+ } else {
+ val = DK3_IM_MIN;
+#if VERSION_BEFORE_20140924
+ if ((dk3_um_t)(DK3_IM_MAX + (dk3_im_t)1L) == umv)
+#else
+ /* 2014-09-24: Fixed warning about integer overflow in constant.
+ */
+ if (((dk3_um_t)(DK3_IM_MAX) + (dk3_um_t)1UL) == umv)
+#endif
+ {
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ } else {
+ val = (dk3_im_t)umv;
+ }
+ } else {
+ if (0 != dk3ma_um_from_hex_string(&umv, ptr, ec)) {
+ val = (dk3_im_t)umv;
+ back = 1;
+ } else {
+ val = (dk3_im_t)umv;
+ }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ *rp = val;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_im_from_c8_hex_string(rp, src, ec));
+#endif
+}
+
+
+
+int
+dk3ma_us_from_hex_string(unsigned short *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_hex_string(&val, src, ec)) {
+ if ((dk3_um_t)DK3_US_MAX >= val) {
+ *rp = (unsigned short)val;
+ back = 1;
+ } else {
+ *rp = DK3_US_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (unsigned short)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_us_from_c8_hex_string(rp, src, ec));
+#endif
+}
+
+
+
+int
+dk3ma_s_from_hex_string(short *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ const dkChar *ptr;
+ unsigned short val = 0U;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3maihd_str_start(src);
+ if (NULL != ptr) {
+ if (dkT('-') == *ptr) {
+ if (0 != dk3ma_us_from_hex_string(&val, &(ptr[1]), ec)) {
+ if ((unsigned short)DK3_S_MAX >= val) {
+ *rp = (short)(0 - (short)val);
+ back = 1;
+ } else {
+ *rp = DK3_S_MIN;
+ if (((unsigned short)DK3_S_MAX + (unsigned short)1U) == val) {
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ } else {
+ *rp = (short)val;
+ }
+ } else {
+ if (0 != dk3ma_us_from_hex_string(&val, ptr, ec)) {
+ *rp = (short)val;
+ back = 1;
+ } else {
+ *rp = (short)val;
+ }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_s_from_c8_hex_string(rp, src, ec));
+#endif
+}
+
+
+
+int
+dk3ma_ui_from_hex_string(unsigned *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_hex_string(&val, src, ec)) {
+ if ((dk3_um_t)DK3_U_MAX >= val) {
+ *rp = (unsigned)val;
+ back = 1;
+ } else {
+ *rp = DK3_U_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (unsigned)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_ui_from_c8_hex_string(rp, src, ec));
+#endif
+}
+
+
+
+int
+dk3ma_i_from_hex_string(int *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ const dkChar *ptr;
+ unsigned val = 0U;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3maihd_str_start(src);
+ if (NULL != ptr) {
+ if (dkT('-') == *ptr) {
+ if (0 != dk3ma_ui_from_hex_string(&val, &(ptr[1]), ec)) {
+ if ((unsigned)DK3_I_MAX >= val) {
+ *rp = 0 - (int)val;
+ back = 1;
+ } else {
+ *rp = DK3_I_MIN;
+ if (((unsigned)DK3_I_MAX + 1U) == val) {
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ } else {
+ *rp = (int)val;
+ }
+ } else {
+ if (0 != dk3ma_ui_from_hex_string(&val, ptr, ec)) {
+ *rp = (int)val;
+ back = 1;
+ } else {
+ *rp = (int)val;
+ }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_i_from_c8_hex_string(rp, src, ec));
+#endif
+}
+
+
+
+int
+dk3ma_ul_from_hex_string(unsigned long *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_hex_string(&val, src, ec)) {
+ if ((dk3_um_t)DK3_UL_MAX >= val) {
+ *rp = (unsigned long)val;
+ back = 1;
+ } else {
+ *rp = DK3_UL_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (unsigned long)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_ul_from_c8_hex_string(rp, src, ec));
+#endif
+}
+
+
+
+int
+dk3ma_l_from_hex_string(long *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ const dkChar *ptr;
+ unsigned long val = 0U;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3maihd_str_start(src);
+ if (NULL != ptr) {
+ if (dkT('-') == *ptr) {
+ if (0 != dk3ma_ul_from_hex_string(&val, &(ptr[1]), ec)) {
+ if ((unsigned long)DK3_L_MAX >= val) {
+ *rp = 0L - (long)val;
+ back = 1;
+ } else {
+ *rp = DK3_L_MIN;
+ if (((unsigned long)DK3_L_MAX + 1UL) == val) {
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ } else {
+ *rp = (long)val;
+ }
+ } else {
+ if (0 != dk3ma_ul_from_hex_string(&val, ptr, ec)) {
+ *rp = (long)val;
+ back = 1;
+ } else {
+ *rp = (long)val;
+ }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_l_from_c8_hex_string(rp, src, ec));
+#endif
+}
+
+
+
+#if DK3_HAVE_LONG_LONG
+
+int
+dk3ma_ull_from_hex_string(unsigned long long *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_hex_string(&val, src, ec)) {
+ if ((dk3_um_t)DK3_ULL_MAX >= val) {
+ *rp = (unsigned long long)val;
+ back = 1;
+ } else {
+ *rp = DK3_ULL_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (unsigned long long)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_ull_from_c8_hex_string(rp, src, ec));
+#endif
+}
+
+
+
+int
+dk3ma_ll_from_hex_string(long long *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ const dkChar *ptr;
+ unsigned long long val = 0ULL;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3maihd_str_start(src);
+ if (NULL != ptr) {
+ if (dkT('-') == *ptr) {
+ if (0 != dk3ma_ull_from_hex_string(&val, &(ptr[1]), ec)) {
+ if ((unsigned long long)DK3_LL_MAX >= val) {
+ *rp = 0LL - (long long)val;
+ back = 1;
+ } else {
+ *rp = DK3_LL_MIN;
+ if (((unsigned long long)DK3_LL_MAX + 1ULL) == val) {
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ } else {
+ *rp = (long long)val;
+ }
+ } else {
+ if (0 != dk3ma_ull_from_hex_string(&val, ptr, ec)) {
+ *rp = (long long)val;
+ back = 1;
+ } else {
+ *rp = (long long)val;
+ }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_ll_from_c8_hex_string(rp, src, ec));
+#endif
+}
+
+#endif
+
+#if DK3_HAVE_INTMAX_T
+
+int
+dk3ma_uintmax_t_from_hex_string(uintmax_t *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_hex_string(&val, src, ec)) {
+ *rp = (uintmax_t)val;
+ back = 1;
+ } else {
+ *rp = (uintmax_t)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_uintmax_t_from_c8_hex_string(rp, src, ec));
+#endif
+}
+
+
+
+int
+dk3ma_intmax_t_from_hex_string(intmax_t *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ const dkChar *ptr;
+ uintmax_t val = (uintmax_t)0U;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3maihd_str_start(src);
+ if (NULL != ptr) {
+ if (dkT('-') == *ptr) {
+ if (0 != dk3ma_uintmax_t_from_hex_string(&val, &(ptr[1]), ec)) {
+ if ((uintmax_t)DK3_INTMAX_T_MAX >= val) {
+ *rp = (intmax_t)0L - (intmax_t)val;
+ back = 1;
+ } else {
+ *rp = DK3_INTMAX_T_MIN;
+ if (((uintmax_t)DK3_INTMAX_T_MAX + (uintmax_t)1UL) == val) {
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ } else {
+ *rp = (intmax_t)val;
+ }
+ } else {
+ if (0 != dk3ma_uintmax_t_from_hex_string(&val, ptr, ec)) {
+ *rp = (intmax_t)val;
+ back = 1;
+ } else {
+ *rp = (intmax_t)val;
+ }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_intmax_t_from_c8_hex_string(rp, src, ec));
+#endif
+}
+
+#endif
diff --git a/support/dktools/dk3maihd.ctr b/support/dktools/dk3maihd.ctr
new file mode 100644
index 0000000000..a3093beb5f
--- /dev/null
+++ b/support/dktools/dk3maihd.ctr
@@ -0,0 +1,869 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2014-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk3maihd.h Retrieve numbers from hexadecimal dkChar strings.
+*/
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+#include <dk3types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert string to dk3_um_t.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_um_from_hex_string(dk3_um_t *rp, dkChar const *src, int *ec);
+
+/** Convert string to dk3_im_t.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_im_from_hex_string(dk3_im_t *rp, dkChar const *src, int *ec);
+
+/** Convert string to short.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_s_from_hex_string(short *rp, dkChar const *src, int *ec);
+
+/** Convert string to unsigned short.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_us_from_hex_string(unsigned short *rp, dkChar const *src, int *ec);
+
+/** Convert string to int.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_i_from_hex_string(int *rp, dkChar const *src, int *ec);
+
+/** Convert string to unsigned int.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_ui_from_hex_string(unsigned *rp, dkChar const *src, int *ec);
+
+/** Convert string to long.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_l_from_hex_string(long *rp, dkChar const *src, int *ec);
+
+/** Convert string to unsigned long.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_ul_from_hex_string(unsigned long *rp, dkChar const *src, int *ec);
+
+#if DK3_HAVE_LONG_LONG
+
+/** Convert string to long long.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_ll_from_hex_string(long long *rp, dkChar const *src, int *ec);
+
+/** Convert string to unsigned long long.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_ull_from_hex_string(unsigned long long *rp, dkChar const *src, int *ec);
+
+#endif
+
+#if DK3_HAVE_INTMAX_T
+
+/** Convert string to intmax_t.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_intmax_t_from_hex_string(intmax_t *rp, dkChar const *src, int *ec);
+
+/** Convert string to uintmax_t.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_uintmax_t_from_hex_string(uintmax_t *rp, dkChar const *src, int *ec);
+
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk3ma.h"
+
+
+
+$!trace-include
+
+
+
+/** Constant numeric values.
+*/
+static dk3_um_t const dk3maihd_um_array[] = {
+#if DK3_HAVE_LONG_LONG
+ /* 0 */ (dk3_um_t)10ULL,
+ /* 1 */ (dk3_um_t)1ULL,
+ /* 2 */ (dk3_um_t)2ULL,
+ /* 3 */ (dk3_um_t)3ULL,
+ /* 4 */ (dk3_um_t)4ULL,
+ /* 5 */ (dk3_um_t)5ULL,
+ /* 6 */ (dk3_um_t)6ULL,
+ /* 7 */ (dk3_um_t)7ULL,
+ /* 8 */ (dk3_um_t)8ULL,
+ /* 9 */ (dk3_um_t)9ULL,
+ /* 10 */ (dk3_um_t)10ULL,
+ /* 11 */ (dk3_um_t)11ULL,
+ /* 12 */ (dk3_um_t)12ULL,
+ /* 13 */ (dk3_um_t)13ULL,
+ /* 14 */ (dk3_um_t)14ULL,
+ /* 15 */ (dk3_um_t)15ULL,
+ /* 16 */ (dk3_um_t)16ULL
+#else
+ /* 0 */ (dk3_um_t)10UL,
+ /* 1 */ (dk3_um_t)1UL,
+ /* 2 */ (dk3_um_t)2UL,
+ /* 3 */ (dk3_um_t)3UL,
+ /* 4 */ (dk3_um_t)4UL,
+ /* 5 */ (dk3_um_t)5UL,
+ /* 6 */ (dk3_um_t)6UL,
+ /* 7 */ (dk3_um_t)7UL,
+ /* 8 */ (dk3_um_t)8UL,
+ /* 9 */ (dk3_um_t)9UL,
+ /* 10 */ (dk3_um_t)10UL,
+ /* 11 */ (dk3_um_t)11UL,
+ /* 12 */ (dk3_um_t)12UL,
+ /* 13 */ (dk3_um_t)13UL,
+ /* 14 */ (dk3_um_t)14UL,
+ /* 15 */ (dk3_um_t)15UL,
+ /* 16 */ (dk3_um_t)16UL
+#endif
+};
+
+
+
+#if DK3_CHAR_SIZE > 1
+/** Find start of text in string.
+ @param str String to search for text.
+ @return Pointer to start of text on success, NULL on error.
+*/
+static
+dkChar const *
+dk3maihd_str_start(dkChar const *str)
+{
+ dkChar const *back = NULL;
+ if (NULL != str) {
+ back = str;
+ while((dkT(' ') == *back) || (dkT('\t') == *back)) { back++; }
+ switch(*back) {
+ case dkT('\0'): case dkT('\n'): case dkT('\r'): {
+ back = NULL;
+ } break;
+ }
+ }
+ return back;
+}
+#endif
+
+
+
+int
+dk3ma_um_from_hex_string(dk3_um_t *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dkChar const *ptr = NULL; /* Current char to process */
+ dk3_um_t val = DK3_UM_0; /* Value found */
+ dk3_um_t op = DK3_UM_0; /* Operand to add */
+ int mec = 0; /* Math error code */
+ int back = 0; /* Function result */
+ int found = 0; /* Flag: Digits found */
+ int cc = 1; /* Flag: Can continue */
+ int action = 0; /* Action to take */
+ $? "+ dk3ma_um_from_hex_string \"%!ds\"", TR_STR(src)
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3maihd_str_start(src);
+ if (NULL != ptr) {
+ while (0 != cc) {
+ action = 0;
+ switch(*(ptr++)) {
+ case dkT('\0'): { /* End of string */
+ cc = 0;
+ if (0 != found) {
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ } break;
+ case dkT('0'): {
+ found = 1; action = 1; op = DK3_UM_0;
+ } break;
+ case dkT('1'): {
+ found = 1; action = 1; op = dk3maihd_um_array[1];
+ } break;
+ case dkT('2'): {
+ found = 1; action = 1; op = dk3maihd_um_array[2];
+ } break;
+ case dkT('3'): {
+ found = 1; action = 1; op = dk3maihd_um_array[3];
+ } break;
+ case dkT('4'): {
+ found = 1; action = 1; op = dk3maihd_um_array[4];
+ } break;
+ case dkT('5'): {
+ found = 1; action = 1; op = dk3maihd_um_array[5];
+ } break;
+ case dkT('6'): {
+ found = 1; action = 1; op = dk3maihd_um_array[6];
+ } break;
+ case dkT('7'): {
+ found = 1; action = 1; op = dk3maihd_um_array[7];
+ } break;
+ case dkT('8'): {
+ found = 1; action = 1; op = dk3maihd_um_array[8];
+ } break;
+ case dkT('9'): {
+ found = 1; action = 1; op = dk3maihd_um_array[9];
+ } break;
+ case dkT('a'): case dkT('A'): {
+ found = 1; action = 1; op = dk3maihd_um_array[10];
+ } break;
+ case dkT('b'): case dkT('B'): {
+ found = 1; action = 1; op = dk3maihd_um_array[11];
+ } break;
+ case dkT('c'): case dkT('C'): {
+ found = 1; action = 1; op = dk3maihd_um_array[12];
+ } break;
+ case dkT('d'): case dkT('D'): {
+ found = 1; action = 1; op = dk3maihd_um_array[13];
+ } break;
+ case dkT('e'): case dkT('E'): {
+ found = 1; action = 1; op = dk3maihd_um_array[14];
+ } break;
+ case dkT('f'): case dkT('F'): {
+ found = 1; action = 1; op = dk3maihd_um_array[15];
+ } break;
+ default: { /* Non-digit */
+ cc = 0;
+ if (0 != found) {
+ back = 1;
+ }
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ } break;
+ }
+ if (0 != cc) {
+ switch(action) {
+ case 1: {
+ val = dk3ma_um_add_ok(
+ dk3ma_um_mul_ok(val, dk3maihd_um_array[16], &mec), op, &mec
+ ); $? ". mec = %d", mec
+ if (0 != mec) { $? "! mec != 0"
+ cc = 0;
+ val = DK3_UM_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } break;
+ }
+ } $? ". mec = %d", mec
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ *rp = val;
+#if DK3_ON_WINDOWS
+ $? ". value = %I64u", val
+#else
+#if DK3_HAVE_INTMAX_T
+ $? ". value = %ju", val
+#else
+#if DK3_HAVE_LONG_LONG
+ $? ". value = %llu", val
+#else
+ $? ". value = %lu", val
+#endif
+#endif
+#endif
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ } $? "- dk3ma_um_from_hex_string %d", back
+ return back;
+#else
+ return (dk3ma_um_from_c8_hex_string(rp, src, ec));
+#endif
+}
+
+
+
+int
+dk3ma_im_from_hex_string(dk3_im_t *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dkChar const *ptr = NULL; /* Start of text */
+ dk3_um_t umv = DK3_UM_0; /* Temporary value */
+ dk3_im_t val = DK3_IM_0; /* Conversion result */
+ int back = 0; /* Function result */
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3maihd_str_start(src);
+ if (NULL != ptr) {
+ if (dkT('-') == *ptr) {
+ ptr++;
+ if (0 != dk3ma_um_from_hex_string(&umv, ptr, ec)) {
+ if ((dk3_um_t)DK3_IM_MAX >= umv) {
+ val = (dk3_im_t)umv;
+ val = DK3_IM_0 - val;
+ back = 1;
+ } else {
+ val = DK3_IM_MIN;
+#if VERSION_BEFORE_20140924
+ if ((dk3_um_t)(DK3_IM_MAX + (dk3_im_t)1L) == umv)
+#else
+ /* 2014-09-24: Fixed warning about integer overflow in constant.
+ */
+ if (((dk3_um_t)(DK3_IM_MAX) + (dk3_um_t)1UL) == umv)
+#endif
+ {
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ } else {
+ val = (dk3_im_t)umv;
+ }
+ } else {
+ if (0 != dk3ma_um_from_hex_string(&umv, ptr, ec)) {
+ val = (dk3_im_t)umv;
+ back = 1;
+ } else {
+ val = (dk3_im_t)umv;
+ }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ *rp = val;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_im_from_c8_hex_string(rp, src, ec));
+#endif
+}
+
+
+
+int
+dk3ma_us_from_hex_string(unsigned short *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_hex_string(&val, src, ec)) {
+ if ((dk3_um_t)DK3_US_MAX >= val) {
+ *rp = (unsigned short)val;
+ back = 1;
+ } else {
+ *rp = DK3_US_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (unsigned short)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_us_from_c8_hex_string(rp, src, ec));
+#endif
+}
+
+
+
+int
+dk3ma_s_from_hex_string(short *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ const dkChar *ptr;
+ unsigned short val = 0U;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3maihd_str_start(src);
+ if (NULL != ptr) {
+ if (dkT('-') == *ptr) {
+ if (0 != dk3ma_us_from_hex_string(&val, &(ptr[1]), ec)) {
+ if ((unsigned short)DK3_S_MAX >= val) {
+ *rp = (short)(0 - (short)val);
+ back = 1;
+ } else {
+ *rp = DK3_S_MIN;
+ if (((unsigned short)DK3_S_MAX + (unsigned short)1U) == val) {
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ } else {
+ *rp = (short)val;
+ }
+ } else {
+ if (0 != dk3ma_us_from_hex_string(&val, ptr, ec)) {
+ *rp = (short)val;
+ back = 1;
+ } else {
+ *rp = (short)val;
+ }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_s_from_c8_hex_string(rp, src, ec));
+#endif
+}
+
+
+
+int
+dk3ma_ui_from_hex_string(unsigned *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_hex_string(&val, src, ec)) {
+ if ((dk3_um_t)DK3_U_MAX >= val) {
+ *rp = (unsigned)val;
+ back = 1;
+ } else {
+ *rp = DK3_U_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (unsigned)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_ui_from_c8_hex_string(rp, src, ec));
+#endif
+}
+
+
+
+int
+dk3ma_i_from_hex_string(int *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ const dkChar *ptr;
+ unsigned val = 0U;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3maihd_str_start(src);
+ if (NULL != ptr) {
+ if (dkT('-') == *ptr) {
+ if (0 != dk3ma_ui_from_hex_string(&val, &(ptr[1]), ec)) {
+ if ((unsigned)DK3_I_MAX >= val) {
+ *rp = 0 - (int)val;
+ back = 1;
+ } else {
+ *rp = DK3_I_MIN;
+ if (((unsigned)DK3_I_MAX + 1U) == val) {
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ } else {
+ *rp = (int)val;
+ }
+ } else {
+ if (0 != dk3ma_ui_from_hex_string(&val, ptr, ec)) {
+ *rp = (int)val;
+ back = 1;
+ } else {
+ *rp = (int)val;
+ }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_i_from_c8_hex_string(rp, src, ec));
+#endif
+}
+
+
+
+int
+dk3ma_ul_from_hex_string(unsigned long *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_hex_string(&val, src, ec)) {
+ if ((dk3_um_t)DK3_UL_MAX >= val) {
+ *rp = (unsigned long)val;
+ back = 1;
+ } else {
+ *rp = DK3_UL_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (unsigned long)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_ul_from_c8_hex_string(rp, src, ec));
+#endif
+}
+
+
+
+int
+dk3ma_l_from_hex_string(long *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ const dkChar *ptr;
+ unsigned long val = 0U;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3maihd_str_start(src);
+ if (NULL != ptr) {
+ if (dkT('-') == *ptr) {
+ if (0 != dk3ma_ul_from_hex_string(&val, &(ptr[1]), ec)) {
+ if ((unsigned long)DK3_L_MAX >= val) {
+ *rp = 0L - (long)val;
+ back = 1;
+ } else {
+ *rp = DK3_L_MIN;
+ if (((unsigned long)DK3_L_MAX + 1UL) == val) {
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ } else {
+ *rp = (long)val;
+ }
+ } else {
+ if (0 != dk3ma_ul_from_hex_string(&val, ptr, ec)) {
+ *rp = (long)val;
+ back = 1;
+ } else {
+ *rp = (long)val;
+ }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_l_from_c8_hex_string(rp, src, ec));
+#endif
+}
+
+
+
+#if DK3_HAVE_LONG_LONG
+
+int
+dk3ma_ull_from_hex_string(unsigned long long *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_hex_string(&val, src, ec)) {
+ if ((dk3_um_t)DK3_ULL_MAX >= val) {
+ *rp = (unsigned long long)val;
+ back = 1;
+ } else {
+ *rp = DK3_ULL_MAX;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ *rp = (unsigned long long)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_ull_from_c8_hex_string(rp, src, ec));
+#endif
+}
+
+
+
+int
+dk3ma_ll_from_hex_string(long long *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ const dkChar *ptr;
+ unsigned long long val = 0ULL;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3maihd_str_start(src);
+ if (NULL != ptr) {
+ if (dkT('-') == *ptr) {
+ if (0 != dk3ma_ull_from_hex_string(&val, &(ptr[1]), ec)) {
+ if ((unsigned long long)DK3_LL_MAX >= val) {
+ *rp = 0LL - (long long)val;
+ back = 1;
+ } else {
+ *rp = DK3_LL_MIN;
+ if (((unsigned long long)DK3_LL_MAX + 1ULL) == val) {
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ } else {
+ *rp = (long long)val;
+ }
+ } else {
+ if (0 != dk3ma_ull_from_hex_string(&val, ptr, ec)) {
+ *rp = (long long)val;
+ back = 1;
+ } else {
+ *rp = (long long)val;
+ }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_ll_from_c8_hex_string(rp, src, ec));
+#endif
+}
+
+#endif
+
+#if DK3_HAVE_INTMAX_T
+
+int
+dk3ma_uintmax_t_from_hex_string(uintmax_t *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ dk3_um_t val = DK3_UM_0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk3ma_um_from_hex_string(&val, src, ec)) {
+ *rp = (uintmax_t)val;
+ back = 1;
+ } else {
+ *rp = (uintmax_t)val;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_uintmax_t_from_c8_hex_string(rp, src, ec));
+#endif
+}
+
+
+
+int
+dk3ma_intmax_t_from_hex_string(intmax_t *rp, dkChar const *src, int *ec)
+{
+#if DK3_CHAR_SIZE > 1
+ const dkChar *ptr;
+ uintmax_t val = (uintmax_t)0U;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3maihd_str_start(src);
+ if (NULL != ptr) {
+ if (dkT('-') == *ptr) {
+ if (0 != dk3ma_uintmax_t_from_hex_string(&val, &(ptr[1]), ec)) {
+ if ((uintmax_t)DK3_INTMAX_T_MAX >= val) {
+ *rp = (intmax_t)0L - (intmax_t)val;
+ back = 1;
+ } else {
+ *rp = DK3_INTMAX_T_MIN;
+ if (((uintmax_t)DK3_INTMAX_T_MAX + (uintmax_t)1UL) == val) {
+ back = 1;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ } else {
+ *rp = (intmax_t)val;
+ }
+ } else {
+ if (0 != dk3ma_uintmax_t_from_hex_string(&val, ptr, ec)) {
+ *rp = (intmax_t)val;
+ back = 1;
+ } else {
+ *rp = (intmax_t)val;
+ }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_SYNTAX; }
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ return back;
+#else
+ return (dk3ma_intmax_t_from_c8_hex_string(rp, src, ec));
+#endif
+}
+
+#endif
diff --git a/support/dktools/dk3maihd.h b/support/dktools/dk3maihd.h
new file mode 100644
index 0000000000..6bb5615b31
--- /dev/null
+++ b/support/dktools/dk3maihd.h
@@ -0,0 +1,256 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3maihd.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK3MAIHD_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3MAIHD_H_INCLUDED 1
+
+
+#line 10 "dk3maihd.ctr"
+
+/** @file dk3maihd.h Retrieve numbers from hexadecimal dkChar strings.
+*/
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+#include <dk3types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert string to dk3_um_t.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_um_from_hex_string(dk3_um_t *rp, dkChar const *src, int *ec);
+
+/** Convert string to dk3_im_t.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_im_from_hex_string(dk3_im_t *rp, dkChar const *src, int *ec);
+
+/** Convert string to short.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_s_from_hex_string(short *rp, dkChar const *src, int *ec);
+
+/** Convert string to unsigned short.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_us_from_hex_string(unsigned short *rp, dkChar const *src, int *ec);
+
+/** Convert string to int.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_i_from_hex_string(int *rp, dkChar const *src, int *ec);
+
+/** Convert string to unsigned int.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_ui_from_hex_string(unsigned *rp, dkChar const *src, int *ec);
+
+/** Convert string to long.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_l_from_hex_string(long *rp, dkChar const *src, int *ec);
+
+/** Convert string to unsigned long.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_ul_from_hex_string(unsigned long *rp, dkChar const *src, int *ec);
+
+#if DK3_HAVE_LONG_LONG
+
+/** Convert string to long long.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_ll_from_hex_string(long long *rp, dkChar const *src, int *ec);
+
+/** Convert string to unsigned long long.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_ull_from_hex_string(unsigned long long *rp, dkChar const *src, int *ec);
+
+#endif
+
+#if DK3_HAVE_INTMAX_T
+
+/** Convert string to intmax_t.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_intmax_t_from_hex_string(intmax_t *rp, dkChar const *src, int *ec);
+
+/** Convert string to uintmax_t.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+ If trailing garbage is found after the number, the function
+ returns 1 and sets the error code variable to DK3_ERROR_SYNTAX.
+*/
+int
+dk3ma_uintmax_t_from_hex_string(uintmax_t *rp, dkChar const *src, int *ec);
+
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk3mal.c b/support/dktools/dk3mal.c
new file mode 100644
index 0000000000..8a12f8f8aa
--- /dev/null
+++ b/support/dktools/dk3mal.c
@@ -0,0 +1,680 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3mal.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3mal.c The dk3mal module.
+*/
+
+
+#line 306 "dk3mal.ctr"
+
+
+
+#include "dk3ma.h"
+
+
+
+
+
+#line 314 "dk3mal.ctr"
+
+
+
+long
+dk3ma_l_abs_ok(long a, int *ec)
+{
+ if (NULL != ec) { if(DK3_L_MIN == a) { *ec = DK3_ERROR_MATH_OVERFLOW; } }
+ return ((0L <= a) ? a : (0L - a));
+}
+
+
+
+long
+dk3ma_l_add_ok(long a, long b, int *ec)
+{
+ if (NULL != ec) {
+ if ((0L < a) && (0L < b)) {
+ if((DK3_L_MAX - a) < b) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ } else {
+ if ((0L > a) && (0L > b)) {
+ if (DK3_L_MIN == a) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ } else {
+ if ((DK3_L_MIN - a) > b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ }
+ }
+ }
+ return (a + b);
+}
+
+
+
+long
+dk3ma_l_sub_ok(long a, long b, int *ec)
+{
+ if (NULL != ec) {
+ if ((0L < a) && (0L > b)) {
+ if((DK3_L_MAX + b) < a) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ } else {
+ if ((0L > a) && (0L < b)) {
+ if((DK3_L_MIN + b) > a) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ }
+ return (a - b);
+}
+
+
+
+#if VERSION_BEFORE_20141018
+long
+dk3ma_l_mul_ok(long a, long b, int *ec)
+{
+ if (NULL != ec) {
+ if ((0L != a) && (0L != b)) {
+ if ((DK3_L_MIN == a) && (1L != b)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ goto checksfinished;
+ }
+ if ((DK3_L_MIN == b) && (1L != a)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ goto checksfinished;
+ }
+ if ((DK3_L_MAX / dk3ma_l_abs_ok(a, ec)) < dk3ma_l_abs_ok(b, ec)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ /* goto checksfinished; -- when adding further tests -- */
+ }
+ }
+ }
+ checksfinished:
+ return (a * b);
+}
+#else
+long
+dk3ma_l_mul_ok(long a, long b, int *ec)
+{
+ if ((NULL != ec) && (0L != a) && (0L != b)) {
+ if (DK3_L_MIN == a) {
+ if (1L != b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ goto finished;
+ }
+ if (DK3_L_MIN == b) {
+ if (1L != a) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ goto finished;
+ }
+ if (0L < a) {
+ if (0L < b) {
+ if ((DK3_L_MAX / a) < b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if ((DK3_L_MIN / a) > b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ } else {
+ if (0L < b) {
+ if ((DK3_L_MIN / b) > a) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if ((DK3_L_MAX / (0L - a)) < (0L - b)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ }
+ }
+finished:
+ return (a * b);
+}
+#endif
+
+
+
+long
+dk3ma_l_div_ok(long a, long b, int *ec)
+{
+ long back = 0L;
+ if (0L != b) {
+ if ((DK3_L_MIN == a) && (-1L == b)) {
+ back = DK3_L_MAX;
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ } else {
+ back = a / b;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_DIVZERO; }
+ if (0L <= a) { back = DK3_L_MAX; }
+ else { back = DK3_L_MIN; }
+ }
+ return back;
+}
+
+
+
+long
+dk3ma_l_gcd_ok(long a, long b, int *ec)
+{
+ long h;
+ if (0L > a) {
+ if (DK3_L_MIN == a) {
+ a = 0L;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ goto finished;
+ } else {
+ a = 0L - a;
+ }
+ }
+ if (0L > b) {
+ if (DK3_L_MIN == b) {
+ a = 0L;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ goto finished;
+ } else {
+ b = 0L - b;
+ }
+ }
+ while (0L < b) {
+ h = a % b;
+ a = b;
+ b = h;
+ }
+ if (0L == a) { a = 1L; }
+ finished:
+ return a;
+}
+
+
+
+#if DK3_HAVE_LONG_LONG
+
+
+
+long long
+dk3ma_ll_abs_ok(long long a, int *ec)
+{
+ if (NULL != ec) { if(DK3_LL_MIN == a) { *ec = DK3_ERROR_MATH_OVERFLOW; } }
+ return ((0LL <= a) ? a : (0L - a));
+}
+
+
+
+long long
+dk3ma_ll_add_ok(long long a, long long b, int *ec)
+{
+ if (NULL != ec) {
+ if ((0LL < a) && (0LL < b)) {
+ if((DK3_LL_MAX - a) < b) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ } else {
+ if ((0LL > a) && (0LL > b)) {
+ if (DK3_LL_MIN == a) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ } else {
+ if ((DK3_LL_MIN - a) > b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ }
+ }
+ }
+ return (a + b);
+}
+
+
+
+long long
+dk3ma_ll_sub_ok(long long a, long long b, int *ec)
+{
+ if (NULL != ec) {
+ if ((0LL < a) && (0LL > b)) {
+ if((DK3_LL_MAX + b) < a) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ } else {
+ if ((0LL > a) && (0LL < b)) {
+ if((DK3_LL_MIN + b) > a) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ }
+ return (a - b);
+}
+
+
+
+#if VERSION_BEFORE_20141018
+long long
+dk3ma_ll_mul_ok(long long a, long long b, int *ec)
+{
+ if (NULL != ec) {
+ if ((0LL != a) && (0LL != b)) {
+ if ((DK3_LL_MIN == a) && (1LL != b)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ goto checksfinished;
+ }
+ if ((DK3_LL_MIN == b) && (1LL != a)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ goto checksfinished;
+ }
+ if ((DK3_LL_MAX / dk3ma_ll_abs_ok(a, ec)) < dk3ma_ll_abs_ok(b, ec)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ /* goto checksfinished; -- when adding further tests -- */
+ }
+ }
+ }
+ checksfinished:
+ return (a * b);
+}
+#else
+long long
+dk3ma_ll_mul_ok(long long a, long long b, int *ec)
+{
+ if ((NULL != ec) && (0LL != a) && (0LL != b)) {
+ if (DK3_LL_MIN == a) {
+ if (1LL != b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ goto finished;
+ }
+ if (DK3_LL_MIN == b) {
+ if (1LL != a) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ goto finished;
+ }
+ if (0LL < a) {
+ if (0LL < b) {
+ if ((DK3_LL_MAX / a) < b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if ((DK3_LL_MIN / a) > b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ } else {
+ if (0LL < b) {
+ if ((DK3_LL_MIN / b) > a) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if ((DK3_LL_MAX / (0LL - a)) < (0LL - b)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ }
+ }
+finished:
+ return (a * b);
+}
+#endif
+
+
+
+long long
+dk3ma_ll_div_ok(long long a, long long b, int *ec)
+{
+ long long back = 0L;
+ if (0LL != b) {
+ if ((DK3_LL_MIN == a) && (-1LL == b)) {
+ back = DK3_LL_MAX;
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ } else {
+ back = a / b;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_DIVZERO; }
+ if (0LL <= a) { back = DK3_LL_MAX; }
+ else { back = DK3_LL_MIN; }
+ }
+ return back;
+}
+
+
+
+long long
+dk3ma_ll_gcd_ok(long long a, long long b, int *ec)
+{
+ long long h;
+ if (0LL > a) {
+ if (DK3_LL_MIN == a) {
+ a = 0LL;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ goto finished;
+ } else {
+ a = 0LL - a;
+ }
+ }
+ if (0LL > b) {
+ if (DK3_LL_MIN == b) {
+ a = 0LL;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ goto finished;
+ } else {
+ b = 0LL - b;
+ }
+ }
+ while (0LL < b) {
+ h = a % b;
+ a = b;
+ b = h;
+ }
+ if (0LL == a) { a = 1LL; }
+ finished:
+ return a;
+}
+
+
+#endif
+
+
+
+#if DK3_HAVE_INTMAX_T
+
+intmax_t
+dk3ma_intmax_t_abs_ok(intmax_t a, int *ec)
+{
+ if (ec) { if (DK3_INTMAX_T_MIN == a) { *ec = DK3_ERROR_MATH_OVERFLOW; } }
+ return ((DK3_INTMAX_T_0 <= a) ? a : (DK3_INTMAX_T_0 - a));
+}
+
+
+
+intmax_t
+dk3ma_intmax_t_add_ok(intmax_t a, intmax_t b, int *ec)
+{
+ if (NULL != ec) {
+ if ((DK3_INTMAX_T_0 < a) && (DK3_INTMAX_T_0 < b)) {
+ if ((DK3_INTMAX_T_MAX - a) < b) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ } else {
+ if ((DK3_INTMAX_T_0 > a) && (DK3_INTMAX_T_0 > b)) {
+ if (DK3_INTMAX_T_MIN == a) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ } else {
+ if ((DK3_INTMAX_T_MIN - a) > b) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ }
+ }
+ return (a + b);
+}
+
+
+
+intmax_t
+dk3ma_intmax_t_sub_ok(intmax_t a, intmax_t b, int *ec)
+{
+ if (NULL != ec) {
+ if((DK3_INTMAX_T_0 < a) && (DK3_INTMAX_T_0 > b)) {
+ if((DK3_INTMAX_T_MAX + b) < a) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ } else {
+ if((DK3_INTMAX_T_0 > a) && (DK3_INTMAX_T_0 < b)) {
+ if((DK3_INTMAX_T_MIN + b) > a) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ }
+ return (a - b);
+}
+
+
+
+#if VERSION_BEFORE_20141018
+intmax_t
+dk3ma_intmax_t_mul_ok(intmax_t a, intmax_t b, int *ec)
+{
+ if (NULL != ec) {
+ if ((DK3_INTMAX_T_0 != a) && (DK3_INTMAX_T_0 != b)) {
+ if ((DK3_INTMAX_T_MIN == a) && (DK3_INTMAX_T_1 != b)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ goto checksfinished;
+ }
+ if ((DK3_INTMAX_T_MIN == b) && (DK3_INTMAX_T_1 != a)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ goto checksfinished;
+ }
+ if (
+ (DK3_INTMAX_T_MAX / dk3ma_intmax_t_abs_ok(a, ec))
+ < dk3ma_intmax_t_abs_ok(b, ec)
+ )
+ {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ /* goto checksfinished; -- when adding further tests -- */
+ }
+ }
+ }
+ checksfinished:
+ return (a * b);
+}
+#else
+intmax_t
+dk3ma_intmax_t_mul_ok(intmax_t a, intmax_t b, int *ec)
+{
+ if ((NULL != ec) && (DK3_INTMAX_T_0 != a) && (DK3_INTMAX_T_0 != b)) {
+ if (DK3_INTMAX_T_MIN == a) {
+ if (DK3_INTMAX_T_1 != b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ goto finished;
+ }
+ if (DK3_INTMAX_T_MIN == b) {
+ if (DK3_INTMAX_T_1 != a) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ goto finished;
+ }
+ if (DK3_INTMAX_T_0 < a) {
+ if (DK3_INTMAX_T_0 < b) {
+ if ((DK3_INTMAX_T_MAX / a) < b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if ((DK3_INTMAX_T_MIN / a) > b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ } else {
+ if (DK3_INTMAX_T_0 < b) {
+ if ((DK3_INTMAX_T_MIN / b) > a) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if ((DK3_INTMAX_T_MAX / (DK3_INTMAX_T_0 - a)) < (DK3_INTMAX_T_0 - b)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ }
+ }
+finished:
+ return (a * b);
+}
+#endif
+
+
+
+intmax_t
+dk3ma_intmax_t_div_ok(intmax_t a, intmax_t b, int *ec)
+{
+ intmax_t back = DK3_INTMAX_T_0;
+ if (DK3_INTMAX_T_0 != b) {
+ if ((DK3_INTMAX_T_MIN == a) && ((-DK3_INTMAX_T_1) == b)) {
+ back = DK3_INTMAX_T_MAX;
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ } else {
+ back = (a / b);
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_DIVZERO; }
+ if (DK3_INTMAX_T_0 <= a) { back = DK3_INTMAX_T_MAX; }
+ else { back = DK3_INTMAX_T_MIN; }
+ }
+ return back;
+}
+
+
+
+intmax_t
+dk3ma_intmax_t_gcd_ok(intmax_t a, intmax_t b, int *ec)
+{
+ intmax_t h;
+ if (DK3_INTMAX_T_0 > a) {
+ if (DK3_INTMAX_T_MIN == a) {
+ a = DK3_INTMAX_T_0;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ goto finished;
+ } else {
+ a = DK3_INTMAX_T_0 - a;
+ }
+ }
+ if (DK3_INTMAX_T_0 > b) {
+ if (DK3_INTMAX_T_MIN == b) {
+ a = DK3_INTMAX_T_0;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ goto finished;
+ } else {
+ b = DK3_INTMAX_T_0 - b;
+ }
+ }
+ while (DK3_INTMAX_T_0 < b) {
+ h = a % b;
+ a = b;
+ b = h;
+ }
+ if (DK3_INTMAX_T_0 == a) { a = DK3_INTMAX_T_1 ; }
+ finished:
+ return a;
+}
+
+#endif
+
+
+
+dk3_im_t
+dk3ma_im_abs_ok(dk3_im_t a, int *ec)
+{
+#if DK3_HAVE_INTMAX_T
+ return (dk3ma_intmax_t_abs_ok(a, ec));
+#else
+#if DK3_HAVE_LONG_LONG
+ return (dk3ma_ll_abs_ok(a, ec));
+#else
+ return (dk3ma_l_abs_ok(a, ec));
+#endif
+#endif
+}
+
+
+
+dk3_im_t
+dk3ma_im_add_ok(dk3_im_t a, dk3_im_t b, int *ec)
+{
+#if DK3_HAVE_INTMAX_T
+ return (dk3ma_intmax_t_add_ok(a, b, ec));
+#else
+#if DK3_HAVE_LONG_LONG
+ return (dk3ma_ll_add_ok(a, b, ec));
+#else
+ return (dk3ma_l_add_ok(a, b, ec));
+#endif
+#endif
+}
+
+
+
+dk3_im_t
+dk3ma_im_sub_ok(dk3_im_t a, dk3_im_t b, int *ec)
+{
+#if DK3_HAVE_INTMAX_T
+ return (dk3ma_intmax_t_sub_ok(a, b, ec));
+#else
+#if DK3_HAVE_LONG_LONG
+ return (dk3ma_ll_sub_ok(a, b, ec));
+#else
+ return (dk3ma_l_sub_ok(a, b, ec));
+#endif
+#endif
+}
+
+
+
+dk3_im_t
+dk3ma_im_mul_ok(dk3_im_t a, dk3_im_t b, int *ec)
+{
+#if DK3_HAVE_INTMAX_T
+ return (dk3ma_intmax_t_mul_ok(a, b, ec));
+#else
+#if DK3_HAVE_LONG_LONG
+ return (dk3ma_ll_mul_ok(a, b, ec));
+#else
+ return (dk3ma_l_mul_ok(a, b, ec));
+#endif
+#endif
+}
+
+
+
+dk3_im_t
+dk3ma_im_div_ok(dk3_im_t a, dk3_im_t b, int *ec)
+{
+#if DK3_HAVE_INTMAX_T
+ return (dk3ma_intmax_t_div_ok(a, b, ec));
+#else
+#if DK3_HAVE_LONG_LONG
+ return (dk3ma_ll_div_ok(a, b, ec));
+#else
+ return (dk3ma_l_div_ok(a, b, ec));
+#endif
+#endif
+}
+
+
+
+dk3_im_t
+dk3ma_im_gcd_ok(dk3_im_t a, dk3_im_t b, int *ec)
+{
+#if DK3_HAVE_INTMAX_T
+ return (dk3ma_intmax_t_gcd_ok(a, b, ec));
+#else
+#if DK3_HAVE_LONG_LONG
+ return (dk3ma_ll_gcd_ok(a, b, ec));
+#else
+ return (dk3ma_l_gcd_ok(a, b, ec));
+#endif
+#endif
+}
+
+
diff --git a/support/dktools/dk3mal.ctr b/support/dktools/dk3mal.ctr
new file mode 100644
index 0000000000..730cbf7b4e
--- /dev/null
+++ b/support/dktools/dk3mal.ctr
@@ -0,0 +1,943 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2014-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk3mal.h Mathematical operations on long, long long,
+ intmax_t and dk3_im_t.
+*/
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Absolute value.
+ @param a Original value.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Non-negative value on success,
+ DK3_L_MAX and ec = DK3_ERROR_MATH_OVERFLOW on error.
+*/
+long
+dk3ma_l_abs_ok(long a, int *ec);
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Summary of a and b.
+*/
+long
+dk3ma_l_add_ok(long a, long b, int *ec);
+
+/** Substraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Difference of a and b.
+*/
+long
+dk3ma_l_sub_ok(long a, long b, int *ec);
+
+/** Multiplication.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Product of a and b.
+*/
+long
+dk3ma_l_mul_ok(long a, long b, int *ec);
+
+/** Division.
+ @param a Left operand (nominator).
+ @param b Right operand (denominator).
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW or
+ DK3_ERROR_MATH_DIVZERO when returning.
+ @return Fraction of a and b.
+*/
+long
+dk3ma_l_div_ok(long a, long b, int *ec);
+
+/** Greatest common divisor.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Greatest common divisor of a and b on success,
+ 0L and ec = DK3_ERROR_MATH_OVERFLOW on error.
+*/
+long
+dk3ma_l_gcd_ok(long a, long b, int *ec);
+
+
+
+#if DK3_HAVE_LONG_LONG
+
+/** Absolute value.
+ @param a Original value.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Non-negative value on success,
+ DK3_L_MAX and ec = DK3_ERROR_MATH_OVERFLOW on error.
+*/
+long long
+dk3ma_ll_abs_ok(long long a, int *ec);
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Summary of a and b.
+*/
+long long
+dk3ma_ll_add_ok(long long a, long long b, int *ec);
+
+/** Substraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Difference of a and b.
+*/
+long long
+dk3ma_ll_sub_ok(long long a, long long b, int *ec);
+
+/** Multiplication.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Product of a and b.
+*/
+long long
+dk3ma_ll_mul_ok(long long a, long long b, int *ec);
+
+/** Division.
+ @param a Left operand (nominator).
+ @param b Right operand (denominator).
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW or
+ DK3_ERROR_MATH_DIVZERO when returning.
+ @return Fraction of a and b.
+*/
+long long
+dk3ma_ll_div_ok(long long a, long long b, int *ec);
+
+/** Greatest common divisor.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Greatest common divisor of a and b on success,
+ 0L and ec = DK3_ERROR_MATH_OVERFLOW on error.
+*/
+long long
+dk3ma_ll_gcd_ok(long long a, long long b, int *ec);
+
+#endif
+/* if DK3_HAVE_LONG_LONG */
+
+
+
+#if DK3_HAVE_INTMAX_T
+
+/** Absolute value.
+ @param a Original value.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Non-negative value on success,
+ DK3_L_MAX and ec = DK3_ERROR_MATH_OVERFLOW on error.
+*/
+intmax_t
+dk3ma_intmax_t_abs_ok(intmax_t a, int *ec);
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Summary of a and b.
+*/
+intmax_t
+dk3ma_intmax_t_add_ok(intmax_t a, intmax_t b, int *ec);
+
+/** Substraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Difference of a and b.
+*/
+intmax_t
+dk3ma_intmax_t_sub_ok(intmax_t a, intmax_t b, int *ec);
+
+/** Multiplication.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Product of a and b.
+*/
+intmax_t
+dk3ma_intmax_t_mul_ok(intmax_t a, intmax_t b, int *ec);
+
+/** Division.
+ @param a Left operand (nominator).
+ @param b Right operand (denominator).
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW or
+ DK3_ERROR_MATH_DIVZERO when returning.
+ @return Fraction of a and b.
+*/
+intmax_t
+dk3ma_intmax_t_div_ok(intmax_t a, intmax_t b, int *ec);
+
+/** Greatest common divisor.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Greatest common divisor of a and b on success,
+ 0L and ec = DK3_ERROR_MATH_OVERFLOW on error.
+*/
+intmax_t
+dk3ma_intmax_t_gcd_ok(intmax_t a, intmax_t b, int *ec);
+
+#endif
+
+/** Absolute value.
+ @param a Original value.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Non-negative value on success,
+ DK3_L_MAX and ec = DK3_ERROR_MATH_OVERFLOW on error.
+*/
+dk3_im_t
+dk3ma_im_abs_ok(dk3_im_t a, int *ec);
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Summary of a and b.
+*/
+dk3_im_t
+dk3ma_im_add_ok(dk3_im_t a, dk3_im_t b, int *ec);
+
+/** Substraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Difference of a and b.
+*/
+dk3_im_t
+dk3ma_im_sub_ok(dk3_im_t a, dk3_im_t b, int *ec);
+
+/** Multiplication.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Product of a and b.
+*/
+dk3_im_t
+dk3ma_im_mul_ok(dk3_im_t a, dk3_im_t b, int *ec);
+
+/** Division.
+ @param a Left operand (nominator).
+ @param b Right operand (denominator).
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW or
+ DK3_ERROR_MATH_DIVZERO when returning.
+ @return Fraction of a and b.
+*/
+dk3_im_t
+dk3ma_im_div_ok(dk3_im_t a, dk3_im_t b, int *ec);
+
+/** Greatest common divisor.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Greatest common divisor of a and b on success,
+ 0L and ec = DK3_ERROR_MATH_OVERFLOW on error.
+*/
+dk3_im_t
+dk3ma_im_gcd_ok(dk3_im_t a, dk3_im_t b, int *ec);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+
+
+#include "dk3ma.h"
+
+
+
+$!trace-include
+
+
+
+long
+dk3ma_l_abs_ok(long a, int *ec)
+{
+ if (NULL != ec) { if(DK3_L_MIN == a) { *ec = DK3_ERROR_MATH_OVERFLOW; } }
+ return ((0L <= a) ? a : (0L - a));
+}
+
+
+
+long
+dk3ma_l_add_ok(long a, long b, int *ec)
+{
+ if (NULL != ec) {
+ if ((0L < a) && (0L < b)) {
+ if((DK3_L_MAX - a) < b) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ } else {
+ if ((0L > a) && (0L > b)) {
+ if (DK3_L_MIN == a) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ } else {
+ if ((DK3_L_MIN - a) > b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ }
+ }
+ }
+ return (a + b);
+}
+
+
+
+long
+dk3ma_l_sub_ok(long a, long b, int *ec)
+{
+ if (NULL != ec) {
+ if ((0L < a) && (0L > b)) {
+ if((DK3_L_MAX + b) < a) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ } else {
+ if ((0L > a) && (0L < b)) {
+ if((DK3_L_MIN + b) > a) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ }
+ return (a - b);
+}
+
+
+
+#if VERSION_BEFORE_20141018
+long
+dk3ma_l_mul_ok(long a, long b, int *ec)
+{
+ if (NULL != ec) {
+ if ((0L != a) && (0L != b)) {
+ if ((DK3_L_MIN == a) && (1L != b)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ goto checksfinished;
+ }
+ if ((DK3_L_MIN == b) && (1L != a)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ goto checksfinished;
+ }
+ if ((DK3_L_MAX / dk3ma_l_abs_ok(a, ec)) < dk3ma_l_abs_ok(b, ec)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ /* goto checksfinished; -- when adding further tests -- */
+ }
+ }
+ }
+ checksfinished:
+ return (a * b);
+}
+#else
+long
+dk3ma_l_mul_ok(long a, long b, int *ec)
+{
+ if ((NULL != ec) && (0L != a) && (0L != b)) {
+ if (DK3_L_MIN == a) {
+ if (1L != b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ goto finished;
+ }
+ if (DK3_L_MIN == b) {
+ if (1L != a) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ goto finished;
+ }
+ if (0L < a) {
+ if (0L < b) {
+ if ((DK3_L_MAX / a) < b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if ((DK3_L_MIN / a) > b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ } else {
+ if (0L < b) {
+ if ((DK3_L_MIN / b) > a) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if ((DK3_L_MAX / (0L - a)) < (0L - b)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ }
+ }
+finished:
+ return (a * b);
+}
+#endif
+
+
+
+long
+dk3ma_l_div_ok(long a, long b, int *ec)
+{
+ long back = 0L;
+ if (0L != b) {
+ if ((DK3_L_MIN == a) && (-1L == b)) {
+ back = DK3_L_MAX;
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ } else {
+ back = a / b;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_DIVZERO; }
+ if (0L <= a) { back = DK3_L_MAX; }
+ else { back = DK3_L_MIN; }
+ }
+ return back;
+}
+
+
+
+long
+dk3ma_l_gcd_ok(long a, long b, int *ec)
+{
+ long h;
+ if (0L > a) {
+ if (DK3_L_MIN == a) {
+ a = 0L;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ goto finished;
+ } else {
+ a = 0L - a;
+ }
+ }
+ if (0L > b) {
+ if (DK3_L_MIN == b) {
+ a = 0L;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ goto finished;
+ } else {
+ b = 0L - b;
+ }
+ }
+ while (0L < b) {
+ h = a % b;
+ a = b;
+ b = h;
+ }
+ if (0L == a) { a = 1L; }
+ finished:
+ return a;
+}
+
+
+
+#if DK3_HAVE_LONG_LONG
+
+
+
+long long
+dk3ma_ll_abs_ok(long long a, int *ec)
+{
+ if (NULL != ec) { if(DK3_LL_MIN == a) { *ec = DK3_ERROR_MATH_OVERFLOW; } }
+ return ((0LL <= a) ? a : (0L - a));
+}
+
+
+
+long long
+dk3ma_ll_add_ok(long long a, long long b, int *ec)
+{
+ if (NULL != ec) {
+ if ((0LL < a) && (0LL < b)) {
+ if((DK3_LL_MAX - a) < b) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ } else {
+ if ((0LL > a) && (0LL > b)) {
+ if (DK3_LL_MIN == a) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ } else {
+ if ((DK3_LL_MIN - a) > b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ }
+ }
+ }
+ return (a + b);
+}
+
+
+
+long long
+dk3ma_ll_sub_ok(long long a, long long b, int *ec)
+{
+ if (NULL != ec) {
+ if ((0LL < a) && (0LL > b)) {
+ if((DK3_LL_MAX + b) < a) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ } else {
+ if ((0LL > a) && (0LL < b)) {
+ if((DK3_LL_MIN + b) > a) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ }
+ return (a - b);
+}
+
+
+
+#if VERSION_BEFORE_20141018
+long long
+dk3ma_ll_mul_ok(long long a, long long b, int *ec)
+{
+ if (NULL != ec) {
+ if ((0LL != a) && (0LL != b)) {
+ if ((DK3_LL_MIN == a) && (1LL != b)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ goto checksfinished;
+ }
+ if ((DK3_LL_MIN == b) && (1LL != a)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ goto checksfinished;
+ }
+ if ((DK3_LL_MAX / dk3ma_ll_abs_ok(a, ec)) < dk3ma_ll_abs_ok(b, ec)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ /* goto checksfinished; -- when adding further tests -- */
+ }
+ }
+ }
+ checksfinished:
+ return (a * b);
+}
+#else
+long long
+dk3ma_ll_mul_ok(long long a, long long b, int *ec)
+{
+ if ((NULL != ec) && (0LL != a) && (0LL != b)) {
+ if (DK3_LL_MIN == a) {
+ if (1LL != b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ goto finished;
+ }
+ if (DK3_LL_MIN == b) {
+ if (1LL != a) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ goto finished;
+ }
+ if (0LL < a) {
+ if (0LL < b) {
+ if ((DK3_LL_MAX / a) < b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if ((DK3_LL_MIN / a) > b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ } else {
+ if (0LL < b) {
+ if ((DK3_LL_MIN / b) > a) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if ((DK3_LL_MAX / (0LL - a)) < (0LL - b)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ }
+ }
+finished:
+ return (a * b);
+}
+#endif
+
+
+
+long long
+dk3ma_ll_div_ok(long long a, long long b, int *ec)
+{
+ long long back = 0L;
+ if (0LL != b) {
+ if ((DK3_LL_MIN == a) && (-1LL == b)) {
+ back = DK3_LL_MAX;
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ } else {
+ back = a / b;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_DIVZERO; }
+ if (0LL <= a) { back = DK3_LL_MAX; }
+ else { back = DK3_LL_MIN; }
+ }
+ return back;
+}
+
+
+
+long long
+dk3ma_ll_gcd_ok(long long a, long long b, int *ec)
+{
+ long long h;
+ if (0LL > a) {
+ if (DK3_LL_MIN == a) {
+ a = 0LL;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ goto finished;
+ } else {
+ a = 0LL - a;
+ }
+ }
+ if (0LL > b) {
+ if (DK3_LL_MIN == b) {
+ a = 0LL;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ goto finished;
+ } else {
+ b = 0LL - b;
+ }
+ }
+ while (0LL < b) {
+ h = a % b;
+ a = b;
+ b = h;
+ }
+ if (0LL == a) { a = 1LL; }
+ finished:
+ return a;
+}
+
+
+#endif
+
+
+
+#if DK3_HAVE_INTMAX_T
+
+intmax_t
+dk3ma_intmax_t_abs_ok(intmax_t a, int *ec)
+{
+ if (ec) { if (DK3_INTMAX_T_MIN == a) { *ec = DK3_ERROR_MATH_OVERFLOW; } }
+ return ((DK3_INTMAX_T_0 <= a) ? a : (DK3_INTMAX_T_0 - a));
+}
+
+
+
+intmax_t
+dk3ma_intmax_t_add_ok(intmax_t a, intmax_t b, int *ec)
+{
+ if (NULL != ec) {
+ if ((DK3_INTMAX_T_0 < a) && (DK3_INTMAX_T_0 < b)) {
+ if ((DK3_INTMAX_T_MAX - a) < b) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ } else {
+ if ((DK3_INTMAX_T_0 > a) && (DK3_INTMAX_T_0 > b)) {
+ if (DK3_INTMAX_T_MIN == a) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ } else {
+ if ((DK3_INTMAX_T_MIN - a) > b) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ }
+ }
+ return (a + b);
+}
+
+
+
+intmax_t
+dk3ma_intmax_t_sub_ok(intmax_t a, intmax_t b, int *ec)
+{
+ if (NULL != ec) {
+ if((DK3_INTMAX_T_0 < a) && (DK3_INTMAX_T_0 > b)) {
+ if((DK3_INTMAX_T_MAX + b) < a) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ } else {
+ if((DK3_INTMAX_T_0 > a) && (DK3_INTMAX_T_0 < b)) {
+ if((DK3_INTMAX_T_MIN + b) > a) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ }
+ return (a - b);
+}
+
+
+
+#if VERSION_BEFORE_20141018
+intmax_t
+dk3ma_intmax_t_mul_ok(intmax_t a, intmax_t b, int *ec)
+{
+ if (NULL != ec) {
+ if ((DK3_INTMAX_T_0 != a) && (DK3_INTMAX_T_0 != b)) {
+ if ((DK3_INTMAX_T_MIN == a) && (DK3_INTMAX_T_1 != b)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ goto checksfinished;
+ }
+ if ((DK3_INTMAX_T_MIN == b) && (DK3_INTMAX_T_1 != a)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ goto checksfinished;
+ }
+ if (
+ (DK3_INTMAX_T_MAX / dk3ma_intmax_t_abs_ok(a, ec))
+ < dk3ma_intmax_t_abs_ok(b, ec)
+ )
+ {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ /* goto checksfinished; -- when adding further tests -- */
+ }
+ }
+ }
+ checksfinished:
+ return (a * b);
+}
+#else
+intmax_t
+dk3ma_intmax_t_mul_ok(intmax_t a, intmax_t b, int *ec)
+{
+ if ((NULL != ec) && (DK3_INTMAX_T_0 != a) && (DK3_INTMAX_T_0 != b)) {
+ if (DK3_INTMAX_T_MIN == a) {
+ if (DK3_INTMAX_T_1 != b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ goto finished;
+ }
+ if (DK3_INTMAX_T_MIN == b) {
+ if (DK3_INTMAX_T_1 != a) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ goto finished;
+ }
+ if (DK3_INTMAX_T_0 < a) {
+ if (DK3_INTMAX_T_0 < b) {
+ if ((DK3_INTMAX_T_MAX / a) < b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if ((DK3_INTMAX_T_MIN / a) > b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ } else {
+ if (DK3_INTMAX_T_0 < b) {
+ if ((DK3_INTMAX_T_MIN / b) > a) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if ((DK3_INTMAX_T_MAX / (DK3_INTMAX_T_0 - a)) < (DK3_INTMAX_T_0 - b)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ }
+ }
+finished:
+ return (a * b);
+}
+#endif
+
+
+
+intmax_t
+dk3ma_intmax_t_div_ok(intmax_t a, intmax_t b, int *ec)
+{
+ intmax_t back = DK3_INTMAX_T_0;
+ if (DK3_INTMAX_T_0 != b) {
+ if ((DK3_INTMAX_T_MIN == a) && ((-DK3_INTMAX_T_1) == b)) {
+ back = DK3_INTMAX_T_MAX;
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ } else {
+ back = (a / b);
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_DIVZERO; }
+ if (DK3_INTMAX_T_0 <= a) { back = DK3_INTMAX_T_MAX; }
+ else { back = DK3_INTMAX_T_MIN; }
+ }
+ return back;
+}
+
+
+
+intmax_t
+dk3ma_intmax_t_gcd_ok(intmax_t a, intmax_t b, int *ec)
+{
+ intmax_t h;
+ if (DK3_INTMAX_T_0 > a) {
+ if (DK3_INTMAX_T_MIN == a) {
+ a = DK3_INTMAX_T_0;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ goto finished;
+ } else {
+ a = DK3_INTMAX_T_0 - a;
+ }
+ }
+ if (DK3_INTMAX_T_0 > b) {
+ if (DK3_INTMAX_T_MIN == b) {
+ a = DK3_INTMAX_T_0;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ goto finished;
+ } else {
+ b = DK3_INTMAX_T_0 - b;
+ }
+ }
+ while (DK3_INTMAX_T_0 < b) {
+ h = a % b;
+ a = b;
+ b = h;
+ }
+ if (DK3_INTMAX_T_0 == a) { a = DK3_INTMAX_T_1 ; }
+ finished:
+ return a;
+}
+
+#endif
+
+
+
+dk3_im_t
+dk3ma_im_abs_ok(dk3_im_t a, int *ec)
+{
+#if DK3_HAVE_INTMAX_T
+ return (dk3ma_intmax_t_abs_ok(a, ec));
+#else
+#if DK3_HAVE_LONG_LONG
+ return (dk3ma_ll_abs_ok(a, ec));
+#else
+ return (dk3ma_l_abs_ok(a, ec));
+#endif
+#endif
+}
+
+
+
+dk3_im_t
+dk3ma_im_add_ok(dk3_im_t a, dk3_im_t b, int *ec)
+{
+#if DK3_HAVE_INTMAX_T
+ return (dk3ma_intmax_t_add_ok(a, b, ec));
+#else
+#if DK3_HAVE_LONG_LONG
+ return (dk3ma_ll_add_ok(a, b, ec));
+#else
+ return (dk3ma_l_add_ok(a, b, ec));
+#endif
+#endif
+}
+
+
+
+dk3_im_t
+dk3ma_im_sub_ok(dk3_im_t a, dk3_im_t b, int *ec)
+{
+#if DK3_HAVE_INTMAX_T
+ return (dk3ma_intmax_t_sub_ok(a, b, ec));
+#else
+#if DK3_HAVE_LONG_LONG
+ return (dk3ma_ll_sub_ok(a, b, ec));
+#else
+ return (dk3ma_l_sub_ok(a, b, ec));
+#endif
+#endif
+}
+
+
+
+dk3_im_t
+dk3ma_im_mul_ok(dk3_im_t a, dk3_im_t b, int *ec)
+{
+#if DK3_HAVE_INTMAX_T
+ return (dk3ma_intmax_t_mul_ok(a, b, ec));
+#else
+#if DK3_HAVE_LONG_LONG
+ return (dk3ma_ll_mul_ok(a, b, ec));
+#else
+ return (dk3ma_l_mul_ok(a, b, ec));
+#endif
+#endif
+}
+
+
+
+dk3_im_t
+dk3ma_im_div_ok(dk3_im_t a, dk3_im_t b, int *ec)
+{
+#if DK3_HAVE_INTMAX_T
+ return (dk3ma_intmax_t_div_ok(a, b, ec));
+#else
+#if DK3_HAVE_LONG_LONG
+ return (dk3ma_ll_div_ok(a, b, ec));
+#else
+ return (dk3ma_l_div_ok(a, b, ec));
+#endif
+#endif
+}
+
+
+
+dk3_im_t
+dk3ma_im_gcd_ok(dk3_im_t a, dk3_im_t b, int *ec)
+{
+#if DK3_HAVE_INTMAX_T
+ return (dk3ma_intmax_t_gcd_ok(a, b, ec));
+#else
+#if DK3_HAVE_LONG_LONG
+ return (dk3ma_ll_gcd_ok(a, b, ec));
+#else
+ return (dk3ma_l_gcd_ok(a, b, ec));
+#endif
+#endif
+}
+
+
diff --git a/support/dktools/dk3mal.h b/support/dktools/dk3mal.h
new file mode 100644
index 0000000000..3529255da7
--- /dev/null
+++ b/support/dktools/dk3mal.h
@@ -0,0 +1,338 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3mal.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK3MAL_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3MAL_H_INCLUDED 1
+
+
+#line 10 "dk3mal.ctr"
+
+/** @file dk3mal.h Mathematical operations on long, long long,
+ intmax_t and dk3_im_t.
+*/
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Absolute value.
+ @param a Original value.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Non-negative value on success,
+ DK3_L_MAX and ec = DK3_ERROR_MATH_OVERFLOW on error.
+*/
+long
+dk3ma_l_abs_ok(long a, int *ec);
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Summary of a and b.
+*/
+long
+dk3ma_l_add_ok(long a, long b, int *ec);
+
+/** Substraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Difference of a and b.
+*/
+long
+dk3ma_l_sub_ok(long a, long b, int *ec);
+
+/** Multiplication.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Product of a and b.
+*/
+long
+dk3ma_l_mul_ok(long a, long b, int *ec);
+
+/** Division.
+ @param a Left operand (nominator).
+ @param b Right operand (denominator).
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW or
+ DK3_ERROR_MATH_DIVZERO when returning.
+ @return Fraction of a and b.
+*/
+long
+dk3ma_l_div_ok(long a, long b, int *ec);
+
+/** Greatest common divisor.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Greatest common divisor of a and b on success,
+ 0L and ec = DK3_ERROR_MATH_OVERFLOW on error.
+*/
+long
+dk3ma_l_gcd_ok(long a, long b, int *ec);
+
+
+
+#if DK3_HAVE_LONG_LONG
+
+/** Absolute value.
+ @param a Original value.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Non-negative value on success,
+ DK3_L_MAX and ec = DK3_ERROR_MATH_OVERFLOW on error.
+*/
+long long
+dk3ma_ll_abs_ok(long long a, int *ec);
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Summary of a and b.
+*/
+long long
+dk3ma_ll_add_ok(long long a, long long b, int *ec);
+
+/** Substraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Difference of a and b.
+*/
+long long
+dk3ma_ll_sub_ok(long long a, long long b, int *ec);
+
+/** Multiplication.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Product of a and b.
+*/
+long long
+dk3ma_ll_mul_ok(long long a, long long b, int *ec);
+
+/** Division.
+ @param a Left operand (nominator).
+ @param b Right operand (denominator).
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW or
+ DK3_ERROR_MATH_DIVZERO when returning.
+ @return Fraction of a and b.
+*/
+long long
+dk3ma_ll_div_ok(long long a, long long b, int *ec);
+
+/** Greatest common divisor.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Greatest common divisor of a and b on success,
+ 0L and ec = DK3_ERROR_MATH_OVERFLOW on error.
+*/
+long long
+dk3ma_ll_gcd_ok(long long a, long long b, int *ec);
+
+#endif
+/* if DK3_HAVE_LONG_LONG */
+
+
+
+#if DK3_HAVE_INTMAX_T
+
+/** Absolute value.
+ @param a Original value.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Non-negative value on success,
+ DK3_L_MAX and ec = DK3_ERROR_MATH_OVERFLOW on error.
+*/
+intmax_t
+dk3ma_intmax_t_abs_ok(intmax_t a, int *ec);
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Summary of a and b.
+*/
+intmax_t
+dk3ma_intmax_t_add_ok(intmax_t a, intmax_t b, int *ec);
+
+/** Substraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Difference of a and b.
+*/
+intmax_t
+dk3ma_intmax_t_sub_ok(intmax_t a, intmax_t b, int *ec);
+
+/** Multiplication.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Product of a and b.
+*/
+intmax_t
+dk3ma_intmax_t_mul_ok(intmax_t a, intmax_t b, int *ec);
+
+/** Division.
+ @param a Left operand (nominator).
+ @param b Right operand (denominator).
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW or
+ DK3_ERROR_MATH_DIVZERO when returning.
+ @return Fraction of a and b.
+*/
+intmax_t
+dk3ma_intmax_t_div_ok(intmax_t a, intmax_t b, int *ec);
+
+/** Greatest common divisor.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Greatest common divisor of a and b on success,
+ 0L and ec = DK3_ERROR_MATH_OVERFLOW on error.
+*/
+intmax_t
+dk3ma_intmax_t_gcd_ok(intmax_t a, intmax_t b, int *ec);
+
+#endif
+
+/** Absolute value.
+ @param a Original value.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Non-negative value on success,
+ DK3_L_MAX and ec = DK3_ERROR_MATH_OVERFLOW on error.
+*/
+dk3_im_t
+dk3ma_im_abs_ok(dk3_im_t a, int *ec);
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Summary of a and b.
+*/
+dk3_im_t
+dk3ma_im_add_ok(dk3_im_t a, dk3_im_t b, int *ec);
+
+/** Substraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Difference of a and b.
+*/
+dk3_im_t
+dk3ma_im_sub_ok(dk3_im_t a, dk3_im_t b, int *ec);
+
+/** Multiplication.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Product of a and b.
+*/
+dk3_im_t
+dk3ma_im_mul_ok(dk3_im_t a, dk3_im_t b, int *ec);
+
+/** Division.
+ @param a Left operand (nominator).
+ @param b Right operand (denominator).
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW or
+ DK3_ERROR_MATH_DIVZERO when returning.
+ @return Fraction of a and b.
+*/
+dk3_im_t
+dk3ma_im_div_ok(dk3_im_t a, dk3_im_t b, int *ec);
+
+/** Greatest common divisor.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Greatest common divisor of a and b on success,
+ 0L and ec = DK3_ERROR_MATH_OVERFLOW on error.
+*/
+dk3_im_t
+dk3ma_im_gcd_ok(dk3_im_t a, dk3_im_t b, int *ec);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3maod8.c b/support/dktools/dk3maod8.c
new file mode 100644
index 0000000000..afa4de204c
--- /dev/null
+++ b/support/dktools/dk3maod8.c
@@ -0,0 +1,148 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3maod8.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3maod8.c The dk3maod8 module.
+*/
+
+
+#line 65 "dk3maod8.ctr"
+
+#include "dk3ma.h"
+
+
+
+
+
+#line 71 "dk3maod8.ctr"
+
+
+
+/** Size correction for alignment.
+*/
+#define DK3MAOD8_ALIGN(sz,al) \
+((0 == (sz % al)) ? (sz) : (((sz / al) + 1) * al))
+
+
+int
+dk3ma_um_to_c8_string(char *rb, size_t sz, dk3_um_t va)
+{
+ char buf[DK3MAOD8_ALIGN((8*DK3_SIZEOF_UM),16)];
+ char *ptr;
+ dk3_um_t x;
+ size_t szmax = sizeof(buf);
+ size_t szused = 0;
+ size_t i;
+ int back = 1;
+ char c;
+
+ if ((NULL != rb) && (0 < sz)) {
+ rb[0] = '\0';
+ ptr = buf;
+ if (2 <= szmax) {
+ do {
+ x = va % 10;
+ va = va / 10;
+ c = '\0';
+ switch((int)x) {
+ case 0: { c = '0'; } break;
+ case 1: { c = '1'; } break;
+ case 2: { c = '2'; } break;
+ case 3: { c = '3'; } break;
+ case 4: { c = '4'; } break;
+ case 5: { c = '5'; } break;
+ case 6: { c = '6'; } break;
+ case 7: { c = '7'; } break;
+ case 8: { c = '8'; } break;
+ case 9: { c = '9'; } break;
+ }
+ if (szused < szmax) {
+ *(ptr++) = c;
+ szused++;
+ } else {
+ back = 0;
+ }
+ } while((DK3_UM_0 != va) && (szused < szmax) && (1 == back));
+ if (szused < szmax) {
+ buf[szused] = '\0';
+ } else {
+ back = 0;
+ buf[szmax - 1] = '\0';
+ }
+ if (1 == back) {
+ if (szused < sz) {
+ for (i = 0; i < szused; i++) {
+ rb[i] = buf[szused - i - 1];
+ }
+ rb[szused] = '\0';
+ } else {
+ back = 0;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_im_to_c8_string(char *rb, size_t sz, dk3_im_t va)
+{
+ char *orb;
+ dk3_um_t umva;
+ int back = 0;
+ if ((NULL != rb) && (0 < sz)) {
+ orb = rb;
+ rb[0] = '\0';
+ if (2 < sz) {
+ if (DK3_IM_0 > va) {
+ *(rb++) = '-';
+ sz--;
+ if (DK3_IM_MIN == va) {
+ umva = (dk3_um_t)DK3_IM_MAX;
+ umva++;
+ } else {
+ umva = (dk3_um_t)(DK3_IM_0 - va);
+ }
+ } else {
+ umva = (dk3_um_t)va;
+ }
+ back = dk3ma_um_to_c8_string(rb, sz, umva);
+ }
+ if (0 == back) { *orb = '\0'; }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk3maod8.ctr b/support/dktools/dk3maod8.ctr
new file mode 100644
index 0000000000..188845e042
--- /dev/null
+++ b/support/dktools/dk3maod8.ctr
@@ -0,0 +1,170 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2014-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk3maod8.h Write numbers to decimal char strings.
+*/
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+#include <dk3types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert largest size integer to string.
+ @param rb Result buffer.
+ @param sz Result buffer size (number of bytes).
+ @param va Value to convert.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3ma_im_to_c8_string(char *rb, size_t sz, dk3_im_t va);
+
+/** Convert largest size unsigned integer to string.
+ @param rb Result buffer.
+ @param sz Result buffer size (number of bytes).
+ @param va Value to convert.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3ma_um_to_c8_string(char *rb, size_t sz, dk3_um_t va);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk3ma.h"
+
+
+
+$!trace-include
+
+
+
+/** Size correction for alignment.
+*/
+#define DK3MAOD8_ALIGN(sz,al) \
+((0 == (sz % al)) ? (sz) : (((sz / al) + 1) * al))
+
+
+int
+dk3ma_um_to_c8_string(char *rb, size_t sz, dk3_um_t va)
+{
+ char buf[DK3MAOD8_ALIGN((8*DK3_SIZEOF_UM),16)];
+ char *ptr;
+ dk3_um_t x;
+ size_t szmax = sizeof(buf);
+ size_t szused = 0;
+ size_t i;
+ int back = 1;
+ char c;
+
+ if ((NULL != rb) && (0 < sz)) {
+ rb[0] = '\0';
+ ptr = buf;
+ if (2 <= szmax) {
+ do {
+ x = va % 10;
+ va = va / 10;
+ c = '\0';
+ switch((int)x) {
+ case 0: { c = '0'; } break;
+ case 1: { c = '1'; } break;
+ case 2: { c = '2'; } break;
+ case 3: { c = '3'; } break;
+ case 4: { c = '4'; } break;
+ case 5: { c = '5'; } break;
+ case 6: { c = '6'; } break;
+ case 7: { c = '7'; } break;
+ case 8: { c = '8'; } break;
+ case 9: { c = '9'; } break;
+ }
+ if (szused < szmax) {
+ *(ptr++) = c;
+ szused++;
+ } else {
+ back = 0;
+ }
+ } while((DK3_UM_0 != va) && (szused < szmax) && (1 == back));
+ if (szused < szmax) {
+ buf[szused] = '\0';
+ } else {
+ back = 0;
+ buf[szmax - 1] = '\0';
+ }
+ if (1 == back) {
+ if (szused < sz) {
+ for (i = 0; i < szused; i++) {
+ rb[i] = buf[szused - i - 1];
+ }
+ rb[szused] = '\0';
+ } else {
+ back = 0;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_im_to_c8_string(char *rb, size_t sz, dk3_im_t va)
+{
+ char *orb;
+ dk3_um_t umva;
+ int back = 0;
+ if ((NULL != rb) && (0 < sz)) {
+ orb = rb;
+ rb[0] = '\0';
+ if (2 < sz) {
+ if (DK3_IM_0 > va) {
+ *(rb++) = '-';
+ sz--;
+ if (DK3_IM_MIN == va) {
+ umva = (dk3_um_t)DK3_IM_MAX;
+ umva++;
+ } else {
+ umva = (dk3_um_t)(DK3_IM_0 - va);
+ }
+ } else {
+ umva = (dk3_um_t)va;
+ }
+ back = dk3ma_um_to_c8_string(rb, sz, umva);
+ }
+ if (0 == back) { *orb = '\0'; }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk3maod8.h b/support/dktools/dk3maod8.h
new file mode 100644
index 0000000000..da0e5b892c
--- /dev/null
+++ b/support/dktools/dk3maod8.h
@@ -0,0 +1,97 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3maod8.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK3MAOD8_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3MAOD8_H_INCLUDED 1
+
+
+#line 10 "dk3maod8.ctr"
+
+/** @file dk3maod8.h Write numbers to decimal char strings.
+*/
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+#include <dk3types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert largest size integer to string.
+ @param rb Result buffer.
+ @param sz Result buffer size (number of bytes).
+ @param va Value to convert.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3ma_im_to_c8_string(char *rb, size_t sz, dk3_im_t va);
+
+/** Convert largest size unsigned integer to string.
+ @param rb Result buffer.
+ @param sz Result buffer size (number of bytes).
+ @param va Value to convert.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3ma_um_to_c8_string(char *rb, size_t sz, dk3_um_t va);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk3maodd.c b/support/dktools/dk3maodd.c
new file mode 100644
index 0000000000..ef55e8ce7b
--- /dev/null
+++ b/support/dktools/dk3maodd.c
@@ -0,0 +1,157 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3maodd.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3maodd.c The dk3maodd module.
+*/
+
+
+#line 65 "dk3maodd.ctr"
+
+#include "dk3ma.h"
+
+
+
+
+
+#line 71 "dk3maodd.ctr"
+
+
+
+/** Size correction for alignment.
+*/
+#define DK3MAODD_ALIGN(sz,al) \
+((0 == (sz % al)) ? (sz) : (((sz / al) + 1) * al))
+
+
+
+int
+dk3ma_um_to_string(dkChar *rb, size_t sz, dk3_um_t va)
+{
+#if DK3_CHAR_SIZE > 1
+ char buf[DK3MAODD_ALIGN((8*DK3_SIZEOF_UM),16)];
+ char *ptr;
+ dk3_um_t x;
+ size_t szmax = sizeof(buf);
+ size_t szused = 0;
+ size_t i;
+ int back = 1;
+ char c;
+
+ if ((NULL != rb) && (0 < sz)) {
+ rb[0] = dkT('\0');
+ ptr = buf;
+ if (2 <= szmax) {
+ do {
+ x = va % 10;
+ va = va / 10;
+ c = '\0';
+ switch((int)x) {
+ case 0: { c = '0'; } break;
+ case 1: { c = '1'; } break;
+ case 2: { c = '2'; } break;
+ case 3: { c = '3'; } break;
+ case 4: { c = '4'; } break;
+ case 5: { c = '5'; } break;
+ case 6: { c = '6'; } break;
+ case 7: { c = '7'; } break;
+ case 8: { c = '8'; } break;
+ case 9: { c = '9'; } break;
+ }
+ if (szused < szmax) {
+ *(ptr++) = c;
+ szused++;
+ } else {
+ back = 0;
+ }
+ } while((DK3_UM_0 != va) && (szused < szmax) && (1 == back));
+ if (szused < szmax) {
+ buf[szused] = '\0';
+ } else {
+ back = 0;
+ buf[szmax - 1] = '\0';
+ }
+ if (1 == back) {
+ if (szused < sz) {
+ for (i = 0; i < szused; i++) {
+ rb[i] = (dkChar)(buf[szused - i - 1]);
+ }
+ rb[szused] = dkT('\0');
+ } else {
+ back = 0;
+ }
+ }
+ }
+ }
+ return back;
+#else
+ return (dk3ma_um_to_c8_string(rb, sz, va));
+#endif
+}
+
+
+
+int
+dk3ma_im_to_string(dkChar *rb, size_t sz, dk3_im_t va)
+{
+#if DK3_CHAR_SIZE > 1
+ dkChar *orb;
+ dk3_um_t umva;
+ int back = 0;
+ if ((NULL != rb) && (0 < sz)) {
+ orb = rb;
+ rb[0] = dkT('\0');
+ if (2 < sz) {
+ if (DK3_IM_0 > va) {
+ *(rb++) = dkT('-');
+ sz--;
+ if (DK3_IM_MIN == va) {
+ umva = (dk3_um_t)DK3_IM_MAX;
+ umva++;
+ } else {
+ umva = (dk3_um_t)(DK3_IM_0 - va);
+ }
+ } else {
+ umva = (dk3_um_t)va;
+ }
+ back = dk3ma_um_to_string(rb, sz, umva);
+ }
+ if (0 == back) { *orb = dkT('\0'); }
+ }
+ return back;
+#else
+ return (dk3ma_im_to_c8_string(rb, sz, va));
+#endif
+}
+
diff --git a/support/dktools/dk3maodd.ctr b/support/dktools/dk3maodd.ctr
new file mode 100644
index 0000000000..011bc04723
--- /dev/null
+++ b/support/dktools/dk3maodd.ctr
@@ -0,0 +1,179 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2014-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk3maodd.h Write numbers to decimal dkChar strings.
+*/
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+#include <dk3types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert largest size integer to string.
+ @param rb Result buffer.
+ @param sz Result buffer size (number of bytes).
+ @param va Value to convert.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3ma_im_to_string(dkChar *rb, size_t sz, dk3_im_t va);
+
+/** Convert largest size unsigned integer to string.
+ @param rb Result buffer.
+ @param sz Result buffer size (number of bytes).
+ @param va Value to convert.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3ma_um_to_string(dkChar *rb, size_t sz, dk3_um_t va);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk3ma.h"
+
+
+
+$!trace-include
+
+
+
+/** Size correction for alignment.
+*/
+#define DK3MAODD_ALIGN(sz,al) \
+((0 == (sz % al)) ? (sz) : (((sz / al) + 1) * al))
+
+
+
+int
+dk3ma_um_to_string(dkChar *rb, size_t sz, dk3_um_t va)
+{
+#if DK3_CHAR_SIZE > 1
+ char buf[DK3MAODD_ALIGN((8*DK3_SIZEOF_UM),16)];
+ char *ptr;
+ dk3_um_t x;
+ size_t szmax = sizeof(buf);
+ size_t szused = 0;
+ size_t i;
+ int back = 1;
+ char c;
+
+ if ((NULL != rb) && (0 < sz)) {
+ rb[0] = dkT('\0');
+ ptr = buf;
+ if (2 <= szmax) {
+ do {
+ x = va % 10;
+ va = va / 10;
+ c = '\0';
+ switch((int)x) {
+ case 0: { c = '0'; } break;
+ case 1: { c = '1'; } break;
+ case 2: { c = '2'; } break;
+ case 3: { c = '3'; } break;
+ case 4: { c = '4'; } break;
+ case 5: { c = '5'; } break;
+ case 6: { c = '6'; } break;
+ case 7: { c = '7'; } break;
+ case 8: { c = '8'; } break;
+ case 9: { c = '9'; } break;
+ }
+ if (szused < szmax) {
+ *(ptr++) = c;
+ szused++;
+ } else {
+ back = 0;
+ }
+ } while((DK3_UM_0 != va) && (szused < szmax) && (1 == back));
+ if (szused < szmax) {
+ buf[szused] = '\0';
+ } else {
+ back = 0;
+ buf[szmax - 1] = '\0';
+ }
+ if (1 == back) {
+ if (szused < sz) {
+ for (i = 0; i < szused; i++) {
+ rb[i] = (dkChar)(buf[szused - i - 1]);
+ }
+ rb[szused] = dkT('\0');
+ } else {
+ back = 0;
+ }
+ }
+ }
+ }
+ return back;
+#else
+ return (dk3ma_um_to_c8_string(rb, sz, va));
+#endif
+}
+
+
+
+int
+dk3ma_im_to_string(dkChar *rb, size_t sz, dk3_im_t va)
+{
+#if DK3_CHAR_SIZE > 1
+ dkChar *orb;
+ dk3_um_t umva;
+ int back = 0;
+ if ((NULL != rb) && (0 < sz)) {
+ orb = rb;
+ rb[0] = dkT('\0');
+ if (2 < sz) {
+ if (DK3_IM_0 > va) {
+ *(rb++) = dkT('-');
+ sz--;
+ if (DK3_IM_MIN == va) {
+ umva = (dk3_um_t)DK3_IM_MAX;
+ umva++;
+ } else {
+ umva = (dk3_um_t)(DK3_IM_0 - va);
+ }
+ } else {
+ umva = (dk3_um_t)va;
+ }
+ back = dk3ma_um_to_string(rb, sz, umva);
+ }
+ if (0 == back) { *orb = dkT('\0'); }
+ }
+ return back;
+#else
+ return (dk3ma_im_to_c8_string(rb, sz, va));
+#endif
+}
+
diff --git a/support/dktools/dk3maodd.h b/support/dktools/dk3maodd.h
new file mode 100644
index 0000000000..5e02f404da
--- /dev/null
+++ b/support/dktools/dk3maodd.h
@@ -0,0 +1,97 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3maodd.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK3MAODD_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3MAODD_H_INCLUDED 1
+
+
+#line 10 "dk3maodd.ctr"
+
+/** @file dk3maodd.h Write numbers to decimal dkChar strings.
+*/
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+#include <dk3types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert largest size integer to string.
+ @param rb Result buffer.
+ @param sz Result buffer size (number of bytes).
+ @param va Value to convert.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3ma_im_to_string(dkChar *rb, size_t sz, dk3_im_t va);
+
+/** Convert largest size unsigned integer to string.
+ @param rb Result buffer.
+ @param sz Result buffer size (number of bytes).
+ @param va Value to convert.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3ma_um_to_string(dkChar *rb, size_t sz, dk3_um_t va);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk3maoh8.c b/support/dktools/dk3maoh8.c
new file mode 100644
index 0000000000..8e7a21e59d
--- /dev/null
+++ b/support/dktools/dk3maoh8.c
@@ -0,0 +1,178 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3maoh8.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3maoh8.c The dk3maoh8 module.
+*/
+
+
+#line 69 "dk3maoh8.ctr"
+
+#include "dk3ma.h"
+
+
+
+
+
+#line 75 "dk3maoh8.ctr"
+
+
+
+#ifndef DK3MASTR_HEX_PADDED_LEFT
+/** When converting to hexadecimal notation, use padding.
+*/
+#define DK3MASTR_HEX_PADDED_LEFT 1
+#endif
+
+
+
+/** Size correction for alignment.
+*/
+#define DK3MAOH8_ALIGN(sz,al) \
+((0 == (sz % al)) ? (sz) : (((sz / al) + 1) * al))
+
+
+
+int
+dk3ma_um_to_c8_hex_string(char *rb, size_t sz, dk3_um_t va, size_t leftpad)
+{
+ char buf[DK3MAOH8_ALIGN((8*DK3_SIZEOF_UM),16)];
+ char *ptr;
+ dk3_um_t x;
+ size_t szmax = sizeof(buf);
+ size_t szused = 0;
+ size_t i;
+ int back = 1;
+ char c;
+
+ if ((NULL != rb) && (0 < sz)) {
+ rb[0] = '\0';
+ ptr = buf;
+ if (2 <= szmax) {
+ do {
+ x = va % 16;
+ va = va / 16;
+ c = '\0';
+ switch((int)x) {
+ case 0: { c = '0'; } break;
+ case 1: { c = '1'; } break;
+ case 2: { c = '2'; } break;
+ case 3: { c = '3'; } break;
+ case 4: { c = '4'; } break;
+ case 5: { c = '5'; } break;
+ case 6: { c = '6'; } break;
+ case 7: { c = '7'; } break;
+ case 8: { c = '8'; } break;
+ case 9: { c = '9'; } break;
+ case 10: { c = 'A'; } break;
+ case 11: { c = 'B'; } break;
+ case 12: { c = 'C'; } break;
+ case 13: { c = 'D'; } break;
+ case 14: { c = 'E'; } break;
+ case 15: { c = 'F'; } break;
+ }
+ if (szused < szmax) {
+ *(ptr++) = c;
+ szused++;
+ } else {
+ back = 0;
+ }
+ } while((DK3_UM_0 != va) && (szused < szmax) && (1 == back));
+ if (szused < szmax) {
+ buf[szused] = '\0';
+ } else {
+ back = 0;
+ buf[szmax - 1] = '\0';
+ }
+ if (1 == back) {
+ if (szused < sz) {
+#if VERSION_BEFORE_20141005
+/*
+*/
+#if DK3MASTR_HEX_PADDED_LEFT
+ if ((2 * DK3_SIZEOF_UM) < sz) {
+ for (i = 0; i < (2 * DK3_SIZEOF_UM); i++) {
+ rb[i] = '0';
+ }
+ rb[2 * DK3_SIZEOF_UM] = '\0';
+ for (i = 0; i < szused; i++) {
+ rb[(2 * DK3_SIZEOF_UM) - 1 - i] = buf[i];
+ }
+ } else {
+#endif
+ for (i = 0; i < szused; i++) {
+ rb[i] = buf[szused - i - 1];
+ }
+ rb[szused] = '\0';
+#if DK3MASTR_HEX_PADDED_LEFT
+ }
+#endif
+#else
+ if (1 == leftpad) { leftpad = 2 * DK3_SIZEOF_UM; }
+ if (0 != leftpad) {
+ if ((szused <= leftpad) && (leftpad < sz)) {
+ for (i = 0; i < leftpad; i++) {
+ rb[i] = '0';
+ }
+ rb[leftpad] = '\0';
+ for (i = 0; i < szused; i++) {
+ rb[leftpad - 1 - i] = buf[i];
+ }
+ } else {
+ back = 0;
+ }
+ } else {
+ for (i = 0; i < szused; i++) {
+ rb[i] = buf[szused - i - 1];
+ }
+ rb[szused] = '\0';
+ }
+#endif
+ } else {
+ back = 0;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_im_to_c8_hex_string(char *rb, size_t sz, dk3_im_t va, size_t leftpad)
+{
+ return (dk3ma_um_to_c8_hex_string(rb, sz, (dk3_um_t)va, leftpad));
+}
+
diff --git a/support/dktools/dk3maoh8.ctr b/support/dktools/dk3maoh8.ctr
new file mode 100644
index 0000000000..b2aa479dc9
--- /dev/null
+++ b/support/dktools/dk3maoh8.ctr
@@ -0,0 +1,204 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2014-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk3maod8.h Write numbers to hexadecimal char strings.
+*/
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+#include <dk3types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert largest size unsigned integer to hexadecimal string.
+ @param rb Result buffer.
+ @param sz Result buffer size (number of bytes).
+ @param va Value to convert.
+ @param leftpad Padding size, 0 for no padding, 1 for automatic
+ choice (2*sizeof(dk3_um_t)), other values specified directly.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3ma_um_to_c8_hex_string(char *rb, size_t sz, dk3_um_t va, size_t leftpad);
+
+/** Convert largest size unsigned integer to hexadecimal string.
+ @param rb Result buffer.
+ @param sz Result buffer size (number of bytes).
+ @param va Value to convert.
+ @param leftpad Padding size, 0 for no padding, 1 for automatic
+ choice (2*sizeof(dk3_im_t)), other values specified directly.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3ma_im_to_c8_hex_string(char *rb, size_t sz, dk3_im_t va, size_t leftpad);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk3ma.h"
+
+
+
+$!trace-include
+
+
+
+#ifndef DK3MASTR_HEX_PADDED_LEFT
+/** When converting to hexadecimal notation, use padding.
+*/
+#define DK3MASTR_HEX_PADDED_LEFT 1
+#endif
+
+
+
+/** Size correction for alignment.
+*/
+#define DK3MAOH8_ALIGN(sz,al) \
+((0 == (sz % al)) ? (sz) : (((sz / al) + 1) * al))
+
+
+
+int
+dk3ma_um_to_c8_hex_string(char *rb, size_t sz, dk3_um_t va, size_t leftpad)
+{
+ char buf[DK3MAOH8_ALIGN((8*DK3_SIZEOF_UM),16)];
+ char *ptr;
+ dk3_um_t x;
+ size_t szmax = sizeof(buf);
+ size_t szused = 0;
+ size_t i;
+ int back = 1;
+ char c;
+
+ if ((NULL != rb) && (0 < sz)) {
+ rb[0] = '\0';
+ ptr = buf;
+ if (2 <= szmax) {
+ do {
+ x = va % 16;
+ va = va / 16;
+ c = '\0';
+ switch((int)x) {
+ case 0: { c = '0'; } break;
+ case 1: { c = '1'; } break;
+ case 2: { c = '2'; } break;
+ case 3: { c = '3'; } break;
+ case 4: { c = '4'; } break;
+ case 5: { c = '5'; } break;
+ case 6: { c = '6'; } break;
+ case 7: { c = '7'; } break;
+ case 8: { c = '8'; } break;
+ case 9: { c = '9'; } break;
+ case 10: { c = 'A'; } break;
+ case 11: { c = 'B'; } break;
+ case 12: { c = 'C'; } break;
+ case 13: { c = 'D'; } break;
+ case 14: { c = 'E'; } break;
+ case 15: { c = 'F'; } break;
+ }
+ if (szused < szmax) {
+ *(ptr++) = c;
+ szused++;
+ } else {
+ back = 0;
+ }
+ } while((DK3_UM_0 != va) && (szused < szmax) && (1 == back));
+ if (szused < szmax) {
+ buf[szused] = '\0';
+ } else {
+ back = 0;
+ buf[szmax - 1] = '\0';
+ }
+ if (1 == back) {
+ if (szused < sz) {
+#if VERSION_BEFORE_20141005
+/*
+*/
+#if DK3MASTR_HEX_PADDED_LEFT
+ if ((2 * DK3_SIZEOF_UM) < sz) {
+ for (i = 0; i < (2 * DK3_SIZEOF_UM); i++) {
+ rb[i] = '0';
+ }
+ rb[2 * DK3_SIZEOF_UM] = '\0';
+ for (i = 0; i < szused; i++) {
+ rb[(2 * DK3_SIZEOF_UM) - 1 - i] = buf[i];
+ }
+ } else {
+#endif
+ for (i = 0; i < szused; i++) {
+ rb[i] = buf[szused - i - 1];
+ }
+ rb[szused] = '\0';
+#if DK3MASTR_HEX_PADDED_LEFT
+ }
+#endif
+#else
+ if (1 == leftpad) { leftpad = 2 * DK3_SIZEOF_UM; }
+ if (0 != leftpad) {
+ if ((szused <= leftpad) && (leftpad < sz)) {
+ for (i = 0; i < leftpad; i++) {
+ rb[i] = '0';
+ }
+ rb[leftpad] = '\0';
+ for (i = 0; i < szused; i++) {
+ rb[leftpad - 1 - i] = buf[i];
+ }
+ } else {
+ back = 0;
+ }
+ } else {
+ for (i = 0; i < szused; i++) {
+ rb[i] = buf[szused - i - 1];
+ }
+ rb[szused] = '\0';
+ }
+#endif
+ } else {
+ back = 0;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3ma_im_to_c8_hex_string(char *rb, size_t sz, dk3_im_t va, size_t leftpad)
+{
+ return (dk3ma_um_to_c8_hex_string(rb, sz, (dk3_um_t)va, leftpad));
+}
+
diff --git a/support/dktools/dk3maoh8.h b/support/dktools/dk3maoh8.h
new file mode 100644
index 0000000000..addf331dc9
--- /dev/null
+++ b/support/dktools/dk3maoh8.h
@@ -0,0 +1,101 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3maoh8.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK3MAOH8_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3MAOH8_H_INCLUDED 1
+
+
+#line 10 "dk3maoh8.ctr"
+
+/** @file dk3maod8.h Write numbers to hexadecimal char strings.
+*/
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+#include <dk3types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert largest size unsigned integer to hexadecimal string.
+ @param rb Result buffer.
+ @param sz Result buffer size (number of bytes).
+ @param va Value to convert.
+ @param leftpad Padding size, 0 for no padding, 1 for automatic
+ choice (2*sizeof(dk3_um_t)), other values specified directly.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3ma_um_to_c8_hex_string(char *rb, size_t sz, dk3_um_t va, size_t leftpad);
+
+/** Convert largest size unsigned integer to hexadecimal string.
+ @param rb Result buffer.
+ @param sz Result buffer size (number of bytes).
+ @param va Value to convert.
+ @param leftpad Padding size, 0 for no padding, 1 for automatic
+ choice (2*sizeof(dk3_im_t)), other values specified directly.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3ma_im_to_c8_hex_string(char *rb, size_t sz, dk3_im_t va, size_t leftpad);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk3maohd.c b/support/dktools/dk3maohd.c
new file mode 100644
index 0000000000..7d4f3f92b8
--- /dev/null
+++ b/support/dktools/dk3maohd.c
@@ -0,0 +1,169 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3maohd.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3maohd.c The dk3maohd module.
+*/
+
+
+#line 69 "dk3maohd.ctr"
+
+#include "dk3ma.h"
+
+
+
+
+
+#line 75 "dk3maohd.ctr"
+
+
+
+/** Size correction for alignment.
+*/
+#define DK3MAOHD_ALIGN(sz,al) \
+((0 == (sz % al)) ? (sz) : (((sz / al) + 1) * al))
+
+
+
+int
+dk3ma_um_to_hex_string(dkChar *rb, size_t sz, dk3_um_t va, size_t leftpad)
+{
+#if DK3_CHAR_SIZE > 1
+ char buf[DK3MAOHD_ALIGN((8*DK3_SIZEOF_UM),16)];
+ char *ptr;
+ dk3_um_t x;
+ size_t szmax = sizeof(buf);
+ size_t szused = 0;
+ size_t i;
+ int back = 1;
+ char c;
+
+ if ((NULL != rb) && (0 < sz)) {
+ rb[0] = dkT('\0');
+ ptr = buf;
+ if (2 <= szmax) {
+ do {
+ x = va % 16;
+ va = va / 16;
+ c = '\0';
+ switch((int)x) {
+ case 0: { c = '0'; } break;
+ case 1: { c = '1'; } break;
+ case 2: { c = '2'; } break;
+ case 3: { c = '3'; } break;
+ case 4: { c = '4'; } break;
+ case 5: { c = '5'; } break;
+ case 6: { c = '6'; } break;
+ case 7: { c = '7'; } break;
+ case 8: { c = '8'; } break;
+ case 9: { c = '9'; } break;
+ case 10: { c = 'A'; } break;
+ case 11: { c = 'B'; } break;
+ case 12: { c = 'C'; } break;
+ case 13: { c = 'D'; } break;
+ case 14: { c = 'E'; } break;
+ case 15: { c = 'F'; } break;
+ }
+ if (szused < szmax) {
+ *(ptr++) = c;
+ szused++;
+ } else {
+ back = 0;
+ }
+ } while((DK3_UM_0 != va) && (szused < szmax) && (1 == back));
+ if (szused < szmax) {
+ buf[szused] = '\0';
+ } else {
+ back = 0;
+ buf[szmax - 1] = '\0';
+ }
+ if (1 == back) {
+ if (szused < sz) {
+#if VERSION_BEFORE_20141005
+ if ((0 != leftpad) && ((2 * DK3_SIZEOF_UM) < sz)) {
+ for (i = 0; i < (2 * DK3_SIZEOF_UM); i++) {
+ rb[i] = dkT('0');
+ }
+ rb[2 * DK3_SIZEOF_UM] = dkT('\0');
+ for (i = 0; i < szused; i++) {
+ rb[(2 * DK3_SIZEOF_UM) - 1 - i] = (dkChar)(buf[i]);
+ }
+ } else {
+ for (i = 0; i < szused; i++) {
+ rb[i] = (dkChar)(buf[szused - i - 1]);
+ }
+ rb[szused] = dkT('\0');
+ }
+#else
+ if (1 == leftpad) { leftpad = 2 * DK3_SIZEOF_UM; }
+ if (0 != leftpad) {
+ if ((szused <= leftpad) && (leftpad < sz)) {
+ for (i = 0; i < leftpad; i++) {
+ rb[i] = dkT('0');
+ }
+ rb[leftpad] = dkT('\0');
+ for (i = 0; i < szused; i++) {
+ rb[leftpad - 1 - i] = (dkChar)(buf[i]);
+ }
+ } else {
+ back = 0;
+ }
+ } else {
+ for (i = 0; i < szused; i++) {
+ rb[i] = (dkChar)(buf[szused - i - 1]);
+ }
+ rb[szused] = dkT('\0');
+ }
+#endif
+ } else {
+ back = 0;
+ }
+ }
+ }
+ }
+ return back;
+#else
+ return (dk3ma_um_to_c8_hex_string(rb, sz, va, leftpad));
+#endif
+}
+
+
+
+int
+dk3ma_im_to_hex_string(dkChar *rb, size_t sz, dk3_im_t va, size_t leftpad)
+{
+ return (dk3ma_um_to_hex_string(rb, sz, (dk3_um_t)va, leftpad));
+}
+
+
diff --git a/support/dktools/dk3maohd.ctr b/support/dktools/dk3maohd.ctr
new file mode 100644
index 0000000000..cb87f0fc4e
--- /dev/null
+++ b/support/dktools/dk3maohd.ctr
@@ -0,0 +1,195 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2014-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk3maohd.h Write numbers to hexadecimal dkChar strings.
+*/
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+#include <dk3types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert largest size unsigned integer to hexadecimal string.
+ @param rb Result buffer.
+ @param sz Result buffer size (number of bytes).
+ @param va Value to convert.
+ @param leftpad Padding-Length: 0 for no padding, 1 for automatic
+ detection of size, other values are specified directly.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3ma_um_to_hex_string(dkChar *rb, size_t sz, dk3_um_t va, size_t leftpad);
+
+/** Convert largest size unsigned integer to hexadecimal string.
+ @param rb Result buffer.
+ @param sz Result buffer size (number of bytes).
+ @param va Value to convert.
+ @param leftpad Padding-Length: 0 for no padding, 1 for automatic
+ detection of size, other values are specified directly.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3ma_im_to_hex_string(dkChar *rb, size_t sz, dk3_im_t va, size_t leftpad);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk3ma.h"
+
+
+
+$!trace-include
+
+
+
+/** Size correction for alignment.
+*/
+#define DK3MAOHD_ALIGN(sz,al) \
+((0 == (sz % al)) ? (sz) : (((sz / al) + 1) * al))
+
+
+
+int
+dk3ma_um_to_hex_string(dkChar *rb, size_t sz, dk3_um_t va, size_t leftpad)
+{
+#if DK3_CHAR_SIZE > 1
+ char buf[DK3MAOHD_ALIGN((8*DK3_SIZEOF_UM),16)];
+ char *ptr;
+ dk3_um_t x;
+ size_t szmax = sizeof(buf);
+ size_t szused = 0;
+ size_t i;
+ int back = 1;
+ char c;
+
+ if ((NULL != rb) && (0 < sz)) {
+ rb[0] = dkT('\0');
+ ptr = buf;
+ if (2 <= szmax) {
+ do {
+ x = va % 16;
+ va = va / 16;
+ c = '\0';
+ switch((int)x) {
+ case 0: { c = '0'; } break;
+ case 1: { c = '1'; } break;
+ case 2: { c = '2'; } break;
+ case 3: { c = '3'; } break;
+ case 4: { c = '4'; } break;
+ case 5: { c = '5'; } break;
+ case 6: { c = '6'; } break;
+ case 7: { c = '7'; } break;
+ case 8: { c = '8'; } break;
+ case 9: { c = '9'; } break;
+ case 10: { c = 'A'; } break;
+ case 11: { c = 'B'; } break;
+ case 12: { c = 'C'; } break;
+ case 13: { c = 'D'; } break;
+ case 14: { c = 'E'; } break;
+ case 15: { c = 'F'; } break;
+ }
+ if (szused < szmax) {
+ *(ptr++) = c;
+ szused++;
+ } else {
+ back = 0;
+ }
+ } while((DK3_UM_0 != va) && (szused < szmax) && (1 == back));
+ if (szused < szmax) {
+ buf[szused] = '\0';
+ } else {
+ back = 0;
+ buf[szmax - 1] = '\0';
+ }
+ if (1 == back) {
+ if (szused < sz) {
+#if VERSION_BEFORE_20141005
+ if ((0 != leftpad) && ((2 * DK3_SIZEOF_UM) < sz)) {
+ for (i = 0; i < (2 * DK3_SIZEOF_UM); i++) {
+ rb[i] = dkT('0');
+ }
+ rb[2 * DK3_SIZEOF_UM] = dkT('\0');
+ for (i = 0; i < szused; i++) {
+ rb[(2 * DK3_SIZEOF_UM) - 1 - i] = (dkChar)(buf[i]);
+ }
+ } else {
+ for (i = 0; i < szused; i++) {
+ rb[i] = (dkChar)(buf[szused - i - 1]);
+ }
+ rb[szused] = dkT('\0');
+ }
+#else
+ if (1 == leftpad) { leftpad = 2 * DK3_SIZEOF_UM; }
+ if (0 != leftpad) {
+ if ((szused <= leftpad) && (leftpad < sz)) {
+ for (i = 0; i < leftpad; i++) {
+ rb[i] = dkT('0');
+ }
+ rb[leftpad] = dkT('\0');
+ for (i = 0; i < szused; i++) {
+ rb[leftpad - 1 - i] = (dkChar)(buf[i]);
+ }
+ } else {
+ back = 0;
+ }
+ } else {
+ for (i = 0; i < szused; i++) {
+ rb[i] = (dkChar)(buf[szused - i - 1]);
+ }
+ rb[szused] = dkT('\0');
+ }
+#endif
+ } else {
+ back = 0;
+ }
+ }
+ }
+ }
+ return back;
+#else
+ return (dk3ma_um_to_c8_hex_string(rb, sz, va, leftpad));
+#endif
+}
+
+
+
+int
+dk3ma_im_to_hex_string(dkChar *rb, size_t sz, dk3_im_t va, size_t leftpad)
+{
+ return (dk3ma_um_to_hex_string(rb, sz, (dk3_um_t)va, leftpad));
+}
+
+
diff --git a/support/dktools/dk3maohd.h b/support/dktools/dk3maohd.h
new file mode 100644
index 0000000000..57c713a9fc
--- /dev/null
+++ b/support/dktools/dk3maohd.h
@@ -0,0 +1,101 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3maohd.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK3MAOHD_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3MAOHD_H_INCLUDED 1
+
+
+#line 10 "dk3maohd.ctr"
+
+/** @file dk3maohd.h Write numbers to hexadecimal dkChar strings.
+*/
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+#include <dk3types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert largest size unsigned integer to hexadecimal string.
+ @param rb Result buffer.
+ @param sz Result buffer size (number of bytes).
+ @param va Value to convert.
+ @param leftpad Padding-Length: 0 for no padding, 1 for automatic
+ detection of size, other values are specified directly.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3ma_um_to_hex_string(dkChar *rb, size_t sz, dk3_um_t va, size_t leftpad);
+
+/** Convert largest size unsigned integer to hexadecimal string.
+ @param rb Result buffer.
+ @param sz Result buffer size (number of bytes).
+ @param va Value to convert.
+ @param leftpad Padding-Length: 0 for no padding, 1 for automatic
+ detection of size, other values are specified directly.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3ma_im_to_hex_string(dkChar *rb, size_t sz, dk3_im_t va, size_t leftpad);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk3mas.c b/support/dktools/dk3mas.c
new file mode 100644
index 0000000000..4482aa85bf
--- /dev/null
+++ b/support/dktools/dk3mas.c
@@ -0,0 +1,232 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3mas.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3mas.c The dk3mas module.
+*/
+
+
+#line 108 "dk3mas.ctr"
+
+
+
+#include "dk3ma.h"
+
+
+
+
+
+#line 116 "dk3mas.ctr"
+
+
+
+short
+dk3ma_s_add_ok(short a, short b, int *ec)
+{
+ if (NULL != ec) {
+ if ((0 < a) && (0 < b)) {
+ if((DK3_S_MAX - a) < b) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ } else {
+ if ((0 > a) && (0 > b)) {
+ if (DK3_S_MIN == a) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ } else {
+ if ((DK3_S_MIN - a) > b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ }
+ }
+ }
+ return (a + b);
+}
+
+
+
+short
+dk3ma_s_sub_ok(short a, short b, int *ec)
+{
+ if (NULL != ec) {
+ if ((0 < a) && (0 > b)) {
+ if((DK3_S_MAX + b) < a) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ } else {
+ if ((0 > a) && (0 < b)) {
+ if((DK3_S_MIN + b) > a) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ }
+ return (a - b);
+}
+
+
+
+short
+dk3ma_s_abs_ok(short a, int *ec)
+{
+ if (NULL != ec) { if (DK3_S_MIN == a) { *ec = DK3_ERROR_MATH_OVERFLOW; } }
+ return((0 <= a) ? a : ((short)(0 - a)));
+}
+
+
+#if VERSION_BEFORE_20141018
+short
+dk3ma_s_mul_ok(short a, short b, int *ec)
+{
+ if (NULL != ec) {
+ if ((0 != a) && (0 != b)) {
+ if ((DK3_S_MIN == a) && (1 != b)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ } else {
+ if ((DK3_S_MIN == b) && (1 != a)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ } else {
+ if ((DK3_S_MAX / dk3ma_s_abs_ok(a, ec)) < dk3ma_s_abs_ok(b, ec)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ }
+ }
+ }
+ return (a * b);
+}
+#else
+short
+dk3ma_s_mul_ok(short a, short b, int *ec)
+{
+ if ((NULL != ec) && (0 != a) && (0 != b)) {
+ if (DK3_S_MIN == a) {
+ if (1 != b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ goto finished;
+ }
+ if (DK3_S_MIN == b) {
+ if (1 != a) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ goto finished;
+ }
+ if (0 < a) {
+ if (0 < b) {
+ if ((DK3_S_MAX / a) < b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if ((DK3_S_MIN / (0 - a)) > b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ } else {
+ if (0 < b) {
+ if ((DK3_S_MIN / (0 - b)) > a) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if ((DK3_S_MAX / (0 - a)) < (0 - b)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ }
+ }
+finished:
+ return (a * b);
+}
+#endif
+
+
+short
+dk3ma_s_div_ok(short a, short b, int *ec)
+{
+ short back = (short)0;
+ if (0 != b) {
+ if ((DK3_S_MIN == a) && (-1 == b)) {
+ back = DK3_S_MAX;
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ } else {
+ back = a / b;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_DIVZERO; }
+ if (0 <= a) { back = DK3_S_MAX; }
+ else { back = DK3_S_MIN; }
+ }
+ return back;
+}
+
+
+
+short
+dk3ma_s_gcd_ok(short a, short b, int *ec)
+{
+ short h;
+
+ /* Check a
+ */
+ if (0 > a) {
+ if (DK3_S_MIN == a) {
+ a = (short)0;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ goto finished;
+ } else {
+ a = (short)(0 - a);
+ }
+ }
+
+ /* Check b
+ */
+ if (0 > b) {
+ if (DK3_S_MIN == b) {
+ a = (short)0;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ goto finished;
+ } else {
+ b = (short)(0 - b);
+ }
+ }
+
+ /* Calculate gcd.
+ */
+ while (0 < b) {
+ h = a % b;
+ a = b;
+ b = h;
+ }
+ if(0 == a) { a = (short)1; }
+
+ /* Return result.
+ */
+ finished:
+ return a;
+}
+
diff --git a/support/dktools/dk3mas.ctr b/support/dktools/dk3mas.ctr
new file mode 100644
index 0000000000..2f1cf52714
--- /dev/null
+++ b/support/dktools/dk3mas.ctr
@@ -0,0 +1,297 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2014-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk3mas.h Mathematical operations on short.
+*/
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Absolute value.
+ @param a Original value.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Non-negative value on success,
+ DK3_S_MAX and ec = DK3_ERROR_MATH_OVERFLOW on error.
+*/
+short
+dk3ma_s_abs_ok(short a, int *ec);
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Summary of a and b.
+*/
+short
+dk3ma_s_add_ok(short a, short b, int *ec);
+
+/** Substraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Difference of a and b.
+*/
+short
+dk3ma_s_sub_ok(short a, short b, int *ec);
+
+/** Multiplication.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Product of a and b.
+*/
+short
+dk3ma_s_mul_ok(short a, short b, int *ec);
+
+/** Division.
+ @param a Left operand (nominator).
+ @param b Right operand (denominator).
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW or
+ DK3_ERROR_MATH_DIVZERO when returning.
+ @return Fraction of a and b.
+*/
+short
+dk3ma_s_div_ok(short a, short b, int *ec);
+
+/** Greatest common divisor.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Greatest common divisor of a and b.
+*/
+short
+dk3ma_s_gcd_ok(short a, short b, int *ec);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+
+
+#include "dk3ma.h"
+
+
+
+$!trace-include
+
+
+
+short
+dk3ma_s_add_ok(short a, short b, int *ec)
+{
+ if (NULL != ec) {
+ if ((0 < a) && (0 < b)) {
+ if((DK3_S_MAX - a) < b) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ } else {
+ if ((0 > a) && (0 > b)) {
+ if (DK3_S_MIN == a) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ } else {
+ if ((DK3_S_MIN - a) > b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ }
+ }
+ }
+ return (a + b);
+}
+
+
+
+short
+dk3ma_s_sub_ok(short a, short b, int *ec)
+{
+ if (NULL != ec) {
+ if ((0 < a) && (0 > b)) {
+ if((DK3_S_MAX + b) < a) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ } else {
+ if ((0 > a) && (0 < b)) {
+ if((DK3_S_MIN + b) > a) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ }
+ return (a - b);
+}
+
+
+
+short
+dk3ma_s_abs_ok(short a, int *ec)
+{
+ if (NULL != ec) { if (DK3_S_MIN == a) { *ec = DK3_ERROR_MATH_OVERFLOW; } }
+ return((0 <= a) ? a : ((short)(0 - a)));
+}
+
+
+#if VERSION_BEFORE_20141018
+short
+dk3ma_s_mul_ok(short a, short b, int *ec)
+{
+ if (NULL != ec) {
+ if ((0 != a) && (0 != b)) {
+ if ((DK3_S_MIN == a) && (1 != b)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ } else {
+ if ((DK3_S_MIN == b) && (1 != a)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ } else {
+ if ((DK3_S_MAX / dk3ma_s_abs_ok(a, ec)) < dk3ma_s_abs_ok(b, ec)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ }
+ }
+ }
+ return (a * b);
+}
+#else
+short
+dk3ma_s_mul_ok(short a, short b, int *ec)
+{
+ if ((NULL != ec) && (0 != a) && (0 != b)) {
+ if (DK3_S_MIN == a) {
+ if (1 != b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ goto finished;
+ }
+ if (DK3_S_MIN == b) {
+ if (1 != a) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ goto finished;
+ }
+ if (0 < a) {
+ if (0 < b) {
+ if ((DK3_S_MAX / a) < b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if ((DK3_S_MIN / (0 - a)) > b) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ } else {
+ if (0 < b) {
+ if ((DK3_S_MIN / (0 - b)) > a) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+ if ((DK3_S_MAX / (0 - a)) < (0 - b)) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ }
+ }
+finished:
+ return (a * b);
+}
+#endif
+
+
+short
+dk3ma_s_div_ok(short a, short b, int *ec)
+{
+ short back = (short)0;
+ if (0 != b) {
+ if ((DK3_S_MIN == a) && (-1 == b)) {
+ back = DK3_S_MAX;
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ } else {
+ back = a / b;
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_DIVZERO; }
+ if (0 <= a) { back = DK3_S_MAX; }
+ else { back = DK3_S_MIN; }
+ }
+ return back;
+}
+
+
+
+short
+dk3ma_s_gcd_ok(short a, short b, int *ec)
+{
+ short h;
+
+ /* Check a
+ */
+ if (0 > a) {
+ if (DK3_S_MIN == a) {
+ a = (short)0;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ goto finished;
+ } else {
+ a = (short)(0 - a);
+ }
+ }
+
+ /* Check b
+ */
+ if (0 > b) {
+ if (DK3_S_MIN == b) {
+ a = (short)0;
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ goto finished;
+ } else {
+ b = (short)(0 - b);
+ }
+ }
+
+ /* Calculate gcd.
+ */
+ while (0 < b) {
+ h = a % b;
+ a = b;
+ b = h;
+ }
+ if(0 == a) { a = (short)1; }
+
+ /* Return result.
+ */
+ finished:
+ return a;
+}
+
diff --git a/support/dktools/dk3mas.h b/support/dktools/dk3mas.h
new file mode 100644
index 0000000000..b79bc872b0
--- /dev/null
+++ b/support/dktools/dk3mas.h
@@ -0,0 +1,140 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3mas.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK3MAS_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3MAS_H_INCLUDED 1
+
+
+#line 10 "dk3mas.ctr"
+
+/** @file dk3mas.h Mathematical operations on short.
+*/
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Absolute value.
+ @param a Original value.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Non-negative value on success,
+ DK3_S_MAX and ec = DK3_ERROR_MATH_OVERFLOW on error.
+*/
+short
+dk3ma_s_abs_ok(short a, int *ec);
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Summary of a and b.
+*/
+short
+dk3ma_s_add_ok(short a, short b, int *ec);
+
+/** Substraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Difference of a and b.
+*/
+short
+dk3ma_s_sub_ok(short a, short b, int *ec);
+
+/** Multiplication.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Product of a and b.
+*/
+short
+dk3ma_s_mul_ok(short a, short b, int *ec);
+
+/** Division.
+ @param a Left operand (nominator).
+ @param b Right operand (denominator).
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW or
+ DK3_ERROR_MATH_DIVZERO when returning.
+ @return Fraction of a and b.
+*/
+short
+dk3ma_s_div_ok(short a, short b, int *ec);
+
+/** Greatest common divisor.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Greatest common divisor of a and b.
+*/
+short
+dk3ma_s_gcd_ok(short a, short b, int *ec);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3masts.c b/support/dktools/dk3masts.c
new file mode 100644
index 0000000000..fe21a8c6d5
--- /dev/null
+++ b/support/dktools/dk3masts.c
@@ -0,0 +1,189 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3masts.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3masts.c The dk3masts module.
+*/
+
+
+#line 39 "dk3masts.ctr"
+
+#include "dk3ma.h"
+#include <stdio.h>
+#include "dk3mem.h"
+#include "dk3str.h"
+
+
+
+
+
+#line 48 "dk3masts.ctr"
+
+
+
+int
+dk3ma_sz_from_string(size_t *rp, dkChar const *src, int *ec)
+{
+ /* Private copy of string, can be modified. */
+ dkChar buffer[DK3_MEM_ALIGN((8*sizeof(dk3_um_t)+1),16)];
+ dkChar const *ptr; /* Start of original text */
+ size_t lgt; /* Length of text in buffer */
+ dk3_um_t convres = (dk3_um_t)1; /* Conversion result */
+ dk3_um_t factor = (dk3_um_t)1; /* Constant factor */
+ int myec = 0; /* Private error code */
+ int back = 0; /* Function result */
+ int done = 0; /* Flag: No conversion necessary */
+
+
+#line 64 "dk3masts.ctr"
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3str_start(src, NULL);
+ if (NULL != ptr) {
+ if (dk3str_len(ptr) < DK3_SIZEOF(buffer,dkChar)) {
+ dk3str_cpy(buffer, ptr);
+ dk3str_chomp(buffer, NULL);
+ lgt = dk3str_len(buffer);
+ if (0 < lgt) {
+ switch(buffer[lgt-1]) {
+ case dkT('k'): case dkT('K'): {
+ factor = (dk3_um_t)1024;
+ buffer[lgt-1] = dkT('\0');
+ if (1 == lgt) { done = 1; }
+ } break;
+ case dkT('m'): case dkT('M'): {
+ factor = dk3ma_um_mul_ok((dk3_um_t)1024, (dk3_um_t)1024, &myec);
+ buffer[lgt-1] = dkT('\0');
+ if (1 == lgt) { done = 1; }
+ } break;
+ case dkT('g'): case dkT('G'): {
+ factor = dk3ma_um_mul_ok(
+ dk3ma_um_mul_ok((dk3_um_t)1024, (dk3_um_t)1024, &myec),
+ (dk3_um_t)1024, &myec
+ );
+ buffer[lgt-1] = dkT('\0');
+ if (1 == lgt) { done = 1; }
+ } break;
+ }
+ if (0 == myec) {
+ if (0 == done) {
+
+#line 94 "dk3masts.ctr"
+ if (0 != dk3ma_um_from_string(&convres, buffer, ec)) {
+
+
+#line 96 "dk3masts.ctr"
+ convres = dk3ma_um_mul_ok(convres, factor, &myec);
+ if ((dk3_um_t)DK3_SIZE_T_MAX >= convres) {
+ *rp = (size_t)convres;
+ back = 1;
+#if DK3_ON_WINDOWS
+
+
+#line 102 "dk3masts.ctr"
+#else
+
+
+#line 104 "dk3masts.ctr"
+#endif
+ } else {
+
+#line 106 "dk3masts.ctr"
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+
+#line 109 "dk3masts.ctr"
+ }
+ } else {
+
+#line 111 "dk3masts.ctr"
+ convres = dk3ma_um_mul_ok(convres, factor, &myec);
+ if ((dk3_um_t)DK3_SIZE_T_MAX >= convres) {
+ *rp = (size_t)convres;
+ back = 1;
+
+#line 115 "dk3masts.ctr"
+#if DK3_ON_WINDOWS
+
+
+#line 117 "dk3masts.ctr"
+#else
+
+
+#line 119 "dk3masts.ctr"
+#endif
+ } else {
+
+#line 121 "dk3masts.ctr"
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ if (1 == back) {
+ if (0 != myec) {
+
+#line 126 "dk3masts.ctr"
+ back = 0;
+ if (NULL != ec) { *ec = myec; }
+ }
+ }
+ } else {
+
+#line 131 "dk3masts.ctr"
+ if (NULL != ec) { *ec = myec; }
+ }
+ } else {
+
+#line 134 "dk3masts.ctr"
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ } else {
+
+#line 137 "dk3masts.ctr"
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ } else {
+
+#line 140 "dk3masts.ctr"
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ } else {
+
+#line 143 "dk3masts.ctr"
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+
+#line 145 "dk3masts.ctr"
+ return back;
+}
+
diff --git a/support/dktools/dk3masts.ctr b/support/dktools/dk3masts.ctr
new file mode 100644
index 0000000000..556d0f9b43
--- /dev/null
+++ b/support/dktools/dk3masts.ctr
@@ -0,0 +1,147 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2014-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk3masts.h Retrieve size_t from dkChar text.
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert string to size_t. The string can optionally contain an
+ ``k'', ``K'', ``m'', ``M'', ``g'', or ``G'' suffix.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL or
+ the string is too long for the internal buffer,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+*/
+int
+dk3ma_sz_from_string(size_t *rp, dkChar const *src, int *ec);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk3ma.h"
+#include <stdio.h>
+#include "dk3mem.h"
+#include "dk3str.h"
+
+
+
+$!trace-include
+
+
+
+int
+dk3ma_sz_from_string(size_t *rp, dkChar const *src, int *ec)
+{
+ /* Private copy of string, can be modified. */
+ dkChar buffer[DK3_MEM_ALIGN((8*sizeof(dk3_um_t)+1),16)];
+ dkChar const *ptr; /* Start of original text */
+ size_t lgt; /* Length of text in buffer */
+ dk3_um_t convres = (dk3_um_t)1; /* Conversion result */
+ dk3_um_t factor = (dk3_um_t)1; /* Constant factor */
+ int myec = 0; /* Private error code */
+ int back = 0; /* Function result */
+ int done = 0; /* Flag: No conversion necessary */
+ $? "+ dk3ma_sz_from_string %!ds", TR_STR(src)
+ if ((NULL != rp) && (NULL != src)) {
+ ptr = dk3str_start(src, NULL);
+ if (NULL != ptr) {
+ if (dk3str_len(ptr) < DK3_SIZEOF(buffer,dkChar)) {
+ dk3str_cpy(buffer, ptr);
+ dk3str_chomp(buffer, NULL);
+ lgt = dk3str_len(buffer);
+ if (0 < lgt) {
+ switch(buffer[lgt-1]) {
+ case dkT('k'): case dkT('K'): {
+ factor = (dk3_um_t)1024;
+ buffer[lgt-1] = dkT('\0');
+ if (1 == lgt) { done = 1; }
+ } break;
+ case dkT('m'): case dkT('M'): {
+ factor = dk3ma_um_mul_ok((dk3_um_t)1024, (dk3_um_t)1024, &myec);
+ buffer[lgt-1] = dkT('\0');
+ if (1 == lgt) { done = 1; }
+ } break;
+ case dkT('g'): case dkT('G'): {
+ factor = dk3ma_um_mul_ok(
+ dk3ma_um_mul_ok((dk3_um_t)1024, (dk3_um_t)1024, &myec),
+ (dk3_um_t)1024, &myec
+ );
+ buffer[lgt-1] = dkT('\0');
+ if (1 == lgt) { done = 1; }
+ } break;
+ }
+ if (0 == myec) {
+ if (0 == done) { $? ". must scan"
+ if (0 != dk3ma_um_from_string(&convres, buffer, ec)) {
+ $? ". scan ok"
+ convres = dk3ma_um_mul_ok(convres, factor, &myec);
+ if ((dk3_um_t)DK3_SIZE_T_MAX >= convres) {
+ *rp = (size_t)convres;
+ back = 1;
+#if DK3_ON_WINDOWS
+ $? ". size = %I64u", convres
+#else
+ $? ". size = %ju", (uintmax_t)convres
+#endif
+ } else { $? "! overflow"
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else { $? "! failed to scan"
+ }
+ } else { $? ". simply unit, no number"
+ convres = dk3ma_um_mul_ok(convres, factor, &myec);
+ if ((dk3_um_t)DK3_SIZE_T_MAX >= convres) {
+ *rp = (size_t)convres;
+ back = 1; $? ". success"
+#if DK3_ON_WINDOWS
+ $? ". size = %I64u", convres
+#else
+ $? ". size = %ju", (uintmax_t)convres
+#endif
+ } else { $? "! overflow"
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ if (1 == back) {
+ if (0 != myec) { $? "! internal error"
+ back = 0;
+ if (NULL != ec) { *ec = myec; }
+ }
+ }
+ } else { $? "! myec set"
+ if (NULL != ec) { *ec = myec; }
+ }
+ } else { $? "! empty string"
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ } else { $? "! string too long"
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ } else { $? "! empty string"
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ } else { $? "! invalid arguments"
+ if (NULL != ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ } $? "- dk3ma_sz_from_string %d", back
+ return back;
+}
+
diff --git a/support/dktools/dk3masts.h b/support/dktools/dk3masts.h
new file mode 100644
index 0000000000..8e54363335
--- /dev/null
+++ b/support/dktools/dk3masts.h
@@ -0,0 +1,71 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3masts.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK3MASTS_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3MASTS_H_INCLUDED 1
+
+
+#line 10 "dk3masts.ctr"
+
+/** @file dk3masts.h Retrieve size_t from dkChar text.
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert string to size_t. The string can optionally contain an
+ ``k'', ``K'', ``m'', ``M'', ``g'', or ``G'' suffix.
+ @param rp Pointer to result variable.
+ @param src Source text to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_INVALID_ARGS if rp and/or src is NULL or
+ the string is too long for the internal buffer,
+ DK3_ERROR_SYNTAX if unacceptable characters found,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return 1 on success, 0 on error (see ec).
+*/
+int
+dk3ma_sz_from_string(size_t *rp, dkChar const *src, int *ec);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3maui.c b/support/dktools/dk3maui.c
new file mode 100644
index 0000000000..6e56eddc8e
--- /dev/null
+++ b/support/dktools/dk3maui.c
@@ -0,0 +1,114 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3maui.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3maui.c The dk3maui module.
+*/
+
+
+#line 98 "dk3maui.ctr"
+
+
+
+#include "dk3ma.h"
+
+
+
+
+
+#line 106 "dk3maui.ctr"
+
+
+
+unsigned
+dk3ma_ui_add_ok(unsigned a, unsigned b, int *ec)
+{
+ if (NULL != ec) {
+ if ((DK3_U_MAX - a) < b) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ return (a + b);
+}
+
+
+
+unsigned
+dk3ma_ui_sub_ok(unsigned a, unsigned b, int *ec)
+{
+ if (NULL != ec) { if (b > a) { *ec = DK3_ERROR_MATH_OVERFLOW; } }
+ return (a - b);
+}
+
+
+
+unsigned
+dk3ma_ui_mul_ok(unsigned a, unsigned b, int *ec)
+{
+ if (NULL != ec) {
+ if (0U != a) {
+ if ((DK3_U_MAX / a) < b) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ return (a * b);
+}
+
+
+
+unsigned
+dk3ma_ui_div_ok(unsigned a, unsigned b, int *ec)
+{
+ unsigned back = (unsigned)0;
+ if (0U != b) {
+ back = a / b;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_DIVZERO; }
+ back = DK3_U_MAX;
+ }
+ return back;
+}
+
+
+
+unsigned
+dk3ma_ui_gcd(unsigned a, unsigned b)
+{
+ unsigned h;
+ while (0U < b) {
+ h = a % b;
+ a = b;
+ b = h;
+ }
+ if (0U == a) { a = 1U; }
+ return a;
+}
+
diff --git a/support/dktools/dk3maui.ctr b/support/dktools/dk3maui.ctr
new file mode 100644
index 0000000000..da637fd464
--- /dev/null
+++ b/support/dktools/dk3maui.ctr
@@ -0,0 +1,169 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2014-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk3maui.h Mathematical operations on unsigned int.
+*/
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Summary of a and b.
+*/
+unsigned
+dk3ma_ui_add_ok(unsigned a, unsigned b, int *ec);
+
+/** Substraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Difference of a and b.
+*/
+unsigned
+dk3ma_ui_sub_ok(unsigned a, unsigned b, int *ec);
+
+/** Multiplication.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Product of a and b.
+*/
+unsigned
+dk3ma_ui_mul_ok(unsigned a, unsigned b, int *ec);
+
+/** Division.
+ @param a Left operand (nominator).
+ @param b Right operand (denominator).
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW or
+ DK3_ERROR_MATH_DIVZERO when returning.
+ @return Fraction of a and b.
+*/
+unsigned
+dk3ma_ui_div_ok(unsigned a, unsigned b, int *ec);
+
+/** Greatest common divisor.
+ @param a Left operand.
+ @param b Right operand.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Greatest common divisor of a and b.
+*/
+unsigned
+dk3ma_ui_gcd(unsigned a, unsigned b);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+
+
+#include "dk3ma.h"
+
+
+
+$!trace-include
+
+
+
+unsigned
+dk3ma_ui_add_ok(unsigned a, unsigned b, int *ec)
+{
+ if (NULL != ec) {
+ if ((DK3_U_MAX - a) < b) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ return (a + b);
+}
+
+
+
+unsigned
+dk3ma_ui_sub_ok(unsigned a, unsigned b, int *ec)
+{
+ if (NULL != ec) { if (b > a) { *ec = DK3_ERROR_MATH_OVERFLOW; } }
+ return (a - b);
+}
+
+
+
+unsigned
+dk3ma_ui_mul_ok(unsigned a, unsigned b, int *ec)
+{
+ if (NULL != ec) {
+ if (0U != a) {
+ if ((DK3_U_MAX / a) < b) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ return (a * b);
+}
+
+
+
+unsigned
+dk3ma_ui_div_ok(unsigned a, unsigned b, int *ec)
+{
+ unsigned back = (unsigned)0;
+ if (0U != b) {
+ back = a / b;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_DIVZERO; }
+ back = DK3_U_MAX;
+ }
+ return back;
+}
+
+
+
+unsigned
+dk3ma_ui_gcd(unsigned a, unsigned b)
+{
+ unsigned h;
+ while (0U < b) {
+ h = a % b;
+ a = b;
+ b = h;
+ }
+ if (0U == a) { a = 1U; }
+ return a;
+}
+
diff --git a/support/dktools/dk3maui.h b/support/dktools/dk3maui.h
new file mode 100644
index 0000000000..032f00b733
--- /dev/null
+++ b/support/dktools/dk3maui.h
@@ -0,0 +1,130 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3maui.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK3MAUI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3MAUI_H_INCLUDED 1
+
+
+#line 10 "dk3maui.ctr"
+
+/** @file dk3maui.h Mathematical operations on unsigned int.
+*/
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Summary of a and b.
+*/
+unsigned
+dk3ma_ui_add_ok(unsigned a, unsigned b, int *ec);
+
+/** Substraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Difference of a and b.
+*/
+unsigned
+dk3ma_ui_sub_ok(unsigned a, unsigned b, int *ec);
+
+/** Multiplication.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Product of a and b.
+*/
+unsigned
+dk3ma_ui_mul_ok(unsigned a, unsigned b, int *ec);
+
+/** Division.
+ @param a Left operand (nominator).
+ @param b Right operand (denominator).
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW or
+ DK3_ERROR_MATH_DIVZERO when returning.
+ @return Fraction of a and b.
+*/
+unsigned
+dk3ma_ui_div_ok(unsigned a, unsigned b, int *ec);
+
+/** Greatest common divisor.
+ @param a Left operand.
+ @param b Right operand.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Greatest common divisor of a and b.
+*/
+unsigned
+dk3ma_ui_gcd(unsigned a, unsigned b);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3maul.c b/support/dktools/dk3maul.c
new file mode 100644
index 0000000000..104f5902cd
--- /dev/null
+++ b/support/dktools/dk3maul.c
@@ -0,0 +1,601 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3maul.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3maul.c The dk3maul module.
+*/
+
+
+#line 271 "dk3maul.ctr"
+
+
+
+#include "dk3ma.h"
+
+
+
+
+
+#line 279 "dk3maul.ctr"
+
+
+
+unsigned long
+dk3ma_ul_add_ok(unsigned long a, unsigned long b, int *ec)
+{
+
+
+#line 286 "dk3maul.ctr"
+ if (NULL != ec) {
+
+#line 287 "dk3maul.ctr"
+ if ((DK3_UL_MAX - a) < b) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+
+#line 289 "dk3maul.ctr"
+ return (a + b);
+}
+
+
+
+unsigned long
+dk3ma_ul_sub_ok(unsigned long a, unsigned long b, int *ec)
+{
+
+
+#line 298 "dk3maul.ctr"
+ if (NULL != ec) {
+ if (b > a) {
+
+#line 300 "dk3maul.ctr"
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ return (a - b);
+}
+
+
+
+unsigned long
+dk3ma_ul_mul_ok(unsigned long a, unsigned long b, int *ec)
+{
+
+
+#line 312 "dk3maul.ctr"
+ if (NULL != ec) {
+ if (0UL != a) {
+ if ((DK3_UL_MAX / a) < b) {
+
+#line 315 "dk3maul.ctr"
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ }
+
+#line 319 "dk3maul.ctr"
+ return (a * b);
+}
+
+
+
+unsigned long
+dk3ma_ul_div_ok(unsigned long a, unsigned long b, int *ec)
+{
+ unsigned long back = (unsigned long)0;
+
+
+#line 329 "dk3maul.ctr"
+ if (0UL != b) {
+ back = a / b;
+ } else {
+ if (NULL != ec) {
+
+#line 333 "dk3maul.ctr"
+ *ec = DK3_ERROR_MATH_DIVZERO;
+ }
+ back = DK3_UL_MAX;
+ }
+
+#line 337 "dk3maul.ctr"
+ return back;
+}
+
+
+
+unsigned long
+dk3ma_ul_gcd(unsigned long a, unsigned long b)
+{
+ unsigned long h;
+
+
+#line 347 "dk3maul.ctr"
+ while (0UL < b) {
+ h = a % b;
+ a = b;
+ b = h;
+ }
+ if (0UL == a) { a = 1UL; }
+
+#line 353 "dk3maul.ctr"
+ return a;
+}
+
+
+
+#if DK3_HAVE_LONG_LONG
+
+unsigned long long
+dk3ma_ull_add_ok(unsigned long long a, unsigned long long b, int *ec)
+{
+#if DK3_ON_WINDOWS
+
+
+#line 365 "dk3maul.ctr"
+#else
+
+
+#line 367 "dk3maul.ctr"
+#endif
+ if (NULL != ec) {
+ if ((DK3_ULL_MAX - a) < b) {
+
+#line 370 "dk3maul.ctr"
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+#if DK3_ON_WINDOWS
+
+
+#line 375 "dk3maul.ctr"
+#else
+
+
+#line 377 "dk3maul.ctr"
+#endif
+ return (a + b);
+}
+
+
+
+unsigned long long
+dk3ma_ull_sub_ok(unsigned long long a, unsigned long long b, int *ec)
+{
+#if DK3_ON_WINDOWS
+
+
+#line 388 "dk3maul.ctr"
+#else
+
+
+#line 390 "dk3maul.ctr"
+#endif
+ if (NULL != ec) {
+ if (b > a) {
+
+#line 393 "dk3maul.ctr"
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+#if DK3_ON_WINDOWS
+
+
+#line 398 "dk3maul.ctr"
+#else
+
+
+#line 400 "dk3maul.ctr"
+#endif
+ return (a - b);
+}
+
+
+
+unsigned long long
+dk3ma_ull_mul_ok(unsigned long long a, unsigned long long b, int *ec)
+{
+#if DK3_ON_WINDOWS
+
+
+#line 411 "dk3maul.ctr"
+#else
+
+
+#line 413 "dk3maul.ctr"
+#endif
+ if (NULL != ec) {
+ if (0ULL != a) {
+
+#line 416 "dk3maul.ctr"
+ if ((DK3_ULL_MAX / a) < b) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+#if DK3_ON_WINDOWS
+
+
+#line 421 "dk3maul.ctr"
+#else
+
+
+#line 423 "dk3maul.ctr"
+#endif
+ return (a * b);
+}
+
+
+
+unsigned long long
+dk3ma_ull_div_ok(unsigned long long a, unsigned long long b, int *ec)
+{
+ unsigned long long back = (unsigned long long)0;
+#if DK3_ON_WINDOWS
+
+
+#line 435 "dk3maul.ctr"
+#else
+
+
+#line 437 "dk3maul.ctr"
+#endif
+ if (0ULL != b) {
+ back = a / b;
+ } else {
+ if (NULL != ec) {
+
+#line 442 "dk3maul.ctr"
+ *ec = DK3_ERROR_MATH_DIVZERO;
+ }
+ back = DK3_ULL_MAX;
+ }
+#if DK3_ON_WINDOWS
+
+
+#line 448 "dk3maul.ctr"
+#else
+
+
+#line 450 "dk3maul.ctr"
+#endif
+ return back;
+}
+
+
+
+unsigned long long
+dk3ma_ull_gcd(unsigned long long a, unsigned long long b)
+{
+ unsigned long long h;
+#if DK3_ON_WINDOWS
+
+
+#line 462 "dk3maul.ctr"
+#else
+
+
+#line 464 "dk3maul.ctr"
+#endif
+ while (0ULL < b) {
+ h = a % b;
+ a = b;
+ b = h;
+ }
+ if (0ULL == a) { a = 1ULL; }
+#if DK3_ON_WINDOWS
+
+
+#line 473 "dk3maul.ctr"
+#else
+
+
+#line 475 "dk3maul.ctr"
+#endif
+ return a;
+}
+
+
+#endif
+
+
+
+#if DK3_HAVE_INTMAX_T
+
+uintmax_t
+dk3ma_uintmax_t_add_ok(uintmax_t a, uintmax_t b, int *ec)
+{
+#if DK3_ON_WINDOWS
+
+
+#line 491 "dk3maul.ctr"
+#else
+
+
+#line 493 "dk3maul.ctr"
+#endif
+ if (NULL != ec) {
+ if ((DK3_UINTMAX_T_MAX - a) < b) {
+
+#line 496 "dk3maul.ctr"
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+#if DK3_ON_WINDOWS
+
+
+#line 501 "dk3maul.ctr"
+#else
+
+
+#line 503 "dk3maul.ctr"
+#endif
+ return (a + b);
+}
+
+
+
+uintmax_t
+dk3ma_uintmax_t_sub_ok(uintmax_t a, uintmax_t b, int *ec)
+{
+#if DK3_ON_WINDOWS
+
+
+#line 514 "dk3maul.ctr"
+#else
+
+
+#line 516 "dk3maul.ctr"
+#endif
+ if (NULL != ec) {
+ if (b > a) {
+
+#line 519 "dk3maul.ctr"
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+#if DK3_ON_WINDOWS
+
+
+#line 524 "dk3maul.ctr"
+#else
+
+
+#line 526 "dk3maul.ctr"
+#endif
+ return (a - b);
+}
+
+
+
+uintmax_t
+dk3ma_uintmax_t_mul_ok(uintmax_t a, uintmax_t b, int *ec)
+{
+#if DK3_ON_WINDOWS
+
+
+#line 537 "dk3maul.ctr"
+#else
+
+
+#line 539 "dk3maul.ctr"
+#endif
+ if (NULL != ec) {
+ if (DK3_UINTMAX_T_0 != a) {
+ if ((DK3_UINTMAX_T_MAX / a) < b) {
+
+#line 543 "dk3maul.ctr"
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ }
+#if DK3_ON_WINDOWS
+
+
+#line 549 "dk3maul.ctr"
+#else
+
+
+#line 551 "dk3maul.ctr"
+#endif
+ return (a * b);
+}
+
+
+
+uintmax_t
+dk3ma_uintmax_t_div_ok(uintmax_t a, uintmax_t b, int *ec)
+{
+ uintmax_t back = (uintmax_t)0;
+#if DK3_ON_WINDOWS
+
+
+#line 563 "dk3maul.ctr"
+#else
+
+
+#line 565 "dk3maul.ctr"
+#endif
+ if (DK3_UINTMAX_T_0 != b) {
+ back = a / b;
+ } else {
+ if (NULL != ec) {
+
+#line 570 "dk3maul.ctr"
+ *ec = DK3_ERROR_MATH_DIVZERO;
+ }
+ back = DK3_UINTMAX_T_MAX;
+ }
+#if DK3_ON_WINDOWS
+
+
+#line 576 "dk3maul.ctr"
+#else
+
+
+#line 578 "dk3maul.ctr"
+#endif
+ return back;
+}
+
+
+
+uintmax_t
+dk3ma_uintmax_t_gcd(uintmax_t a, uintmax_t b)
+{
+ uintmax_t h;
+#if DK3_ON_WINDOWS
+
+
+#line 590 "dk3maul.ctr"
+#else
+
+
+#line 592 "dk3maul.ctr"
+#endif
+ while (DK3_UINTMAX_T_0 < b) {
+ h = a % b;
+ a = b;
+ b = h;
+ }
+ if (DK3_UINTMAX_T_0 == a) { a = DK3_UINTMAX_T_1; }
+#if DK3_ON_WINDOWS
+
+
+#line 601 "dk3maul.ctr"
+#else
+
+
+#line 603 "dk3maul.ctr"
+#endif
+ return a;
+}
+
+
+#endif
+
+
+
+dk3_um_t
+dk3ma_um_add_ok(dk3_um_t a, dk3_um_t b, int *ec)
+{
+#if DK3_HAVE_INTMAX_T
+ return (dk3ma_uintmax_t_add_ok(a, b, ec));
+#else
+#if DK3_HAVE_LONG_LONG
+ return (dk3ma_ull_add_ok(a, b, ec));
+#else
+ return (dk3ma_ul_add_ok(a, b, ec));
+#endif
+#endif
+}
+
+
+
+dk3_um_t
+dk3ma_um_sub_ok(dk3_um_t a, dk3_um_t b, int *ec)
+{
+#if DK3_HAVE_INTMAX_T
+ return (dk3ma_uintmax_t_sub_ok(a, b, ec));
+#else
+#if DK3_HAVE_LONG_LONG
+ return (dk3ma_ull_sub_ok(a, b, ec));
+#else
+ return (dk3ma_ul_sub_ok(a, b, ec));
+#endif
+#endif
+}
+
+
+
+dk3_um_t
+dk3ma_um_mul_ok(dk3_um_t a, dk3_um_t b, int *ec)
+{
+#if DK3_HAVE_INTMAX_T
+ return (dk3ma_uintmax_t_mul_ok(a, b, ec));
+#else
+#if DK3_HAVE_LONG_LONG
+ return (dk3ma_ull_mul_ok(a, b, ec));
+#else
+ return (dk3ma_ul_mul_ok(a, b, ec));
+#endif
+#endif
+}
+
+
+
+dk3_um_t
+dk3ma_um_div_ok(dk3_um_t a, dk3_um_t b, int *ec)
+{
+#if DK3_HAVE_INTMAX_T
+ return (dk3ma_uintmax_t_div_ok(a, b, ec));
+#else
+#if DK3_HAVE_LONG_LONG
+ return (dk3ma_ull_div_ok(a, b, ec));
+#else
+ return (dk3ma_ul_div_ok(a, b, ec));
+#endif
+#endif
+}
+
+
+
+dk3_um_t
+dk3ma_um_gcd(dk3_um_t a, dk3_um_t b)
+{
+#if DK3_HAVE_INTMAX_T
+ return (dk3ma_uintmax_t_gcd(a, b));
+#else
+#if DK3_HAVE_LONG_LONG
+ return (dk3ma_ull_gcd(a, b));
+#else
+ return (dk3ma_ul_gcd(a, b));
+#endif
+#endif
+}
+
+
+
+size_t
+dk3ma_um_to_sz(dk3_um_t um, int *ec)
+{
+ size_t back = 0;
+#if DK3_SIZEOF_SIZE_T >= DK3_SIZEOF_UM
+ back = (size_t)um;
+#else
+ if ((dk3_um_t)DK3_SIZE_T_MAX >= um) {
+ back = (size_t)um;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+#endif
+ return back;
+}
+
diff --git a/support/dktools/dk3maul.ctr b/support/dktools/dk3maul.ctr
new file mode 100644
index 0000000000..72d803d1cd
--- /dev/null
+++ b/support/dktools/dk3maul.ctr
@@ -0,0 +1,707 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2014-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk3maul.h Mathematical operations on
+ unsigned long, unsigned long long, uintmax_t and dk3_um_t.
+*/
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Summary of a and b.
+*/
+unsigned long
+dk3ma_ul_add_ok(unsigned long a, unsigned long b, int *ec);
+
+/** Substraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Difference of a and b.
+*/
+unsigned long
+dk3ma_ul_sub_ok(unsigned long a, unsigned long b, int *ec);
+
+/** Multiplication.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Product of a and b.
+*/
+unsigned long
+dk3ma_ul_mul_ok(unsigned long a, unsigned long b, int *ec);
+
+/** Division.
+ @param a Left operand (nominator).
+ @param b Right operand (denominator).
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW or
+ DK3_ERROR_MATH_DIVZERO when returning.
+ @return Fraction of a and b.
+*/
+unsigned long
+dk3ma_ul_div_ok(unsigned long a, unsigned long b, int *ec);
+
+/** Greatest common divisor.
+ @param a Left operand.
+ @param b Right operand.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Greatest common divisor of a and b.
+*/
+unsigned long
+dk3ma_ul_gcd(unsigned long a, unsigned long b);
+
+
+#if DK3_HAVE_LONG_LONG
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Summary of a and b.
+*/
+unsigned long long
+dk3ma_ull_add_ok(unsigned long long a, unsigned long long b, int *ec);
+
+/** Substraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Difference of a and b.
+*/
+unsigned long long
+dk3ma_ull_sub_ok(unsigned long long a, unsigned long long b, int *ec);
+
+/** Multiplication.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Product of a and b.
+*/
+unsigned long long
+dk3ma_ull_mul_ok(unsigned long long a, unsigned long long b, int *ec);
+
+/** Division.
+ @param a Left operand (nominator).
+ @param b Right operand (denominator).
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW or
+ DK3_ERROR_MATH_DIVZERO when returning.
+ @return Fraction of a and b.
+*/
+unsigned long long
+dk3ma_ull_div_ok(unsigned long long a, unsigned long long b, int *ec);
+
+/** Greatest common divisor.
+ @param a Left operand.
+ @param b Right operand.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Greatest common divisor of a and b.
+*/
+unsigned long long
+dk3ma_ull_gcd(unsigned long long a, unsigned long long b);
+
+#endif
+
+
+
+#if DK3_HAVE_INTMAX_T
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Summary of a and b.
+*/
+uintmax_t
+dk3ma_uintmax_t_add_ok(uintmax_t a, uintmax_t b, int *ec);
+
+/** Substraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Difference of a and b.
+*/
+uintmax_t
+dk3ma_uintmax_t_sub_ok(uintmax_t a, uintmax_t b, int *ec);
+
+/** Multiplication.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Product of a and b.
+*/
+uintmax_t
+dk3ma_uintmax_t_mul_ok(uintmax_t a, uintmax_t b, int *ec);
+
+/** Division.
+ @param a Left operand (nominator).
+ @param b Right operand (denominator).
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW or
+ DK3_ERROR_MATH_DIVZERO when returning.
+ @return Fraction of a and b.
+*/
+uintmax_t
+dk3ma_uintmax_t_div_ok(uintmax_t a, uintmax_t b, int *ec);
+
+/** Greatest common divisor.
+ @param a Left operand.
+ @param b Right operand.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Greatest common divisor of a and b.
+*/
+uintmax_t
+dk3ma_uintmax_t_gcd(uintmax_t a, uintmax_t b);
+
+#endif
+
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Summary of a and b.
+*/
+dk3_um_t
+dk3ma_um_add_ok(dk3_um_t a, dk3_um_t b, int *ec);
+
+/** Substraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Difference of a and b.
+*/
+dk3_um_t
+dk3ma_um_sub_ok(dk3_um_t a, dk3_um_t b, int *ec);
+
+/** Multiplication.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Product of a and b.
+*/
+dk3_um_t
+dk3ma_um_mul_ok(dk3_um_t a, dk3_um_t b, int *ec);
+
+/** Division.
+ @param a Left operand (nominator).
+ @param b Right operand (denominator).
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW or
+ DK3_ERROR_MATH_DIVZERO when returning.
+ @return Fraction of a and b.
+*/
+dk3_um_t
+dk3ma_um_div_ok(dk3_um_t a, dk3_um_t b, int *ec);
+
+/** Greatest common divisor.
+ @param a Left operand.
+ @param b Right operand.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Greatest common divisor of a and b.
+*/
+dk3_um_t
+dk3ma_um_gcd(dk3_um_t a, dk3_um_t b);
+
+/** Convert dk3_um_t to size_t.
+ @param um Positive dk3_um_t value to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_MATH_OVERFLOW on conversion errors.
+ @return Positive number on success, 0 on error
+ (significant bits lost in conversion).
+*/
+size_t
+dk3ma_um_to_sz(dk3_um_t um, int *ec);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+
+
+#include "dk3ma.h"
+
+
+
+$!trace-include
+
+
+
+unsigned long
+dk3ma_ul_add_ok(unsigned long a, unsigned long b, int *ec)
+{
+ $? "+ dk3ma_ul_add_ok %lu %lu", a, b
+ if (NULL != ec) { $? "! overflow"
+ if ((DK3_UL_MAX - a) < b) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ } $? "- dk3ma_ul_add_ok %lu", (a + b)
+ return (a + b);
+}
+
+
+
+unsigned long
+dk3ma_ul_sub_ok(unsigned long a, unsigned long b, int *ec)
+{
+ $? "+ dk3ma_ul_sub_ok %lu %lu", a, b
+ if (NULL != ec) {
+ if (b > a) { $? "! overflow"
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ return (a - b);
+}
+
+
+
+unsigned long
+dk3ma_ul_mul_ok(unsigned long a, unsigned long b, int *ec)
+{
+ $? "+ dk3ma_ul_mul_ok %lu %lu", a, b
+ if (NULL != ec) {
+ if (0UL != a) {
+ if ((DK3_UL_MAX / a) < b) { $? "! overflow"
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ } $? "- dk3ma_ul_mul_ok %lu", (a * b)
+ return (a * b);
+}
+
+
+
+unsigned long
+dk3ma_ul_div_ok(unsigned long a, unsigned long b, int *ec)
+{
+ unsigned long back = (unsigned long)0;
+ $? "+ dk3ma_ul_div_ok %lu %lu", a, b
+ if (0UL != b) {
+ back = a / b;
+ } else {
+ if (NULL != ec) { $? "! division by zero"
+ *ec = DK3_ERROR_MATH_DIVZERO;
+ }
+ back = DK3_UL_MAX;
+ } $? "- dk3ma_ul_div_ok %lu", back
+ return back;
+}
+
+
+
+unsigned long
+dk3ma_ul_gcd(unsigned long a, unsigned long b)
+{
+ unsigned long h;
+ $? "+ dk3ma_ul_gcd %lu %lu", a, b
+ while (0UL < b) {
+ h = a % b;
+ a = b;
+ b = h;
+ }
+ if (0UL == a) { a = 1UL; } $? "- dk3ma_ul_gcd %lu", a
+ return a;
+}
+
+
+
+#if DK3_HAVE_LONG_LONG
+
+unsigned long long
+dk3ma_ull_add_ok(unsigned long long a, unsigned long long b, int *ec)
+{
+#if DK3_ON_WINDOWS
+ $? "+ dk3ma_ull_add_ok %I64u %I64u", a, b
+#else
+ $? "+ dk3ma_ull_add_ok %llu %llu", a, b
+#endif
+ if (NULL != ec) {
+ if ((DK3_ULL_MAX - a) < b) { $? "! overflow"
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+#if DK3_ON_WINDOWS
+ $? "- dk3ma_ull_add_ok %I64u", (a + b)
+#else
+ $? "- dk3ma_ull_add_ok %llu", (a + b)
+#endif
+ return (a + b);
+}
+
+
+
+unsigned long long
+dk3ma_ull_sub_ok(unsigned long long a, unsigned long long b, int *ec)
+{
+#if DK3_ON_WINDOWS
+ $? "+ dk3ma_ull_sub_ok %I64u %I64u", a, b
+#else
+ $? "+ dk3ma_ull_sub_ok %llu %llu", a, b
+#endif
+ if (NULL != ec) {
+ if (b > a) { $? "! overflow"
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+#if DK3_ON_WINDOWS
+ $? "- dk3ma_ull_sub_ok %I64u", (a - b)
+#else
+ $? "- dk3ma_ull_sub_ok %llu", (a - b)
+#endif
+ return (a - b);
+}
+
+
+
+unsigned long long
+dk3ma_ull_mul_ok(unsigned long long a, unsigned long long b, int *ec)
+{
+#if DK3_ON_WINDOWS
+ $? "+ dk3ma_ull_mul_ok %I64u %I64u", a, b
+#else
+ $? "+ dk3ma_ull_mul_ok %llu %llu", a, b
+#endif
+ if (NULL != ec) {
+ if (0ULL != a) { $? "! overflow"
+ if ((DK3_ULL_MAX / a) < b) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+#if DK3_ON_WINDOWS
+ $? "- dk3ma_ull_mul_ok %I64u", (a * b)
+#else
+ $? "- dk3ma_ull_mul_ok %llu", (a * b)
+#endif
+ return (a * b);
+}
+
+
+
+unsigned long long
+dk3ma_ull_div_ok(unsigned long long a, unsigned long long b, int *ec)
+{
+ unsigned long long back = (unsigned long long)0;
+#if DK3_ON_WINDOWS
+ $? "+ dk3ma_ull_div_ok %I64u %I64u", a, b
+#else
+ $? "+ dk3ma_ull_div_ok %llu %llu", a, b
+#endif
+ if (0ULL != b) {
+ back = a / b;
+ } else {
+ if (NULL != ec) { $? "! division by zero"
+ *ec = DK3_ERROR_MATH_DIVZERO;
+ }
+ back = DK3_ULL_MAX;
+ }
+#if DK3_ON_WINDOWS
+ $? "- dk3ma_ull_div_ok %I64u", back
+#else
+ $? "- dk3ma_ull_div_ok %llu", back
+#endif
+ return back;
+}
+
+
+
+unsigned long long
+dk3ma_ull_gcd(unsigned long long a, unsigned long long b)
+{
+ unsigned long long h;
+#if DK3_ON_WINDOWS
+ $? "+ dk3ma_ull_gcd_ok %I64u %I64u", a, b
+#else
+ $? "+ dk3ma_ull_gcd_ok %llu %llu", a, b
+#endif
+ while (0ULL < b) {
+ h = a % b;
+ a = b;
+ b = h;
+ }
+ if (0ULL == a) { a = 1ULL; }
+#if DK3_ON_WINDOWS
+ $? "- dk3ma_ull_add_ok %I64u", a
+#else
+ $? "- dk3ma_ull_add_ok %llu", a
+#endif
+ return a;
+}
+
+
+#endif
+
+
+
+#if DK3_HAVE_INTMAX_T
+
+uintmax_t
+dk3ma_uintmax_t_add_ok(uintmax_t a, uintmax_t b, int *ec)
+{
+#if DK3_ON_WINDOWS
+ $? "+ dk3ma_uintmax_t_add_ok %I64u %I64u", a, b
+#else
+ $? "+ dk3ma_uintmax_t_add_ok %ju %ju", a, b
+#endif
+ if (NULL != ec) {
+ if ((DK3_UINTMAX_T_MAX - a) < b) { $? "! overflow"
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+#if DK3_ON_WINDOWS
+ $? "- dk3ma_uintmax_t_add_ok %I64u", (a + b)
+#else
+ $? "- dk3ma_uintmax_t_add_ok %ju", (a + b)
+#endif
+ return (a + b);
+}
+
+
+
+uintmax_t
+dk3ma_uintmax_t_sub_ok(uintmax_t a, uintmax_t b, int *ec)
+{
+#if DK3_ON_WINDOWS
+ $? "+ dk3ma_uintmax_t_sub_ok %I64u %I64u", a, b
+#else
+ $? "+ dk3ma_uintmax_t_sub_ok %ju %ju", a, b
+#endif
+ if (NULL != ec) {
+ if (b > a) { $? "! overflow"
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+#if DK3_ON_WINDOWS
+ $? "- dk3ma_uintmax_t_sub_ok %I64u", (a - b)
+#else
+ $? "- dk3ma_uintmax_t_sub_ok %ju", (a - b)
+#endif
+ return (a - b);
+}
+
+
+
+uintmax_t
+dk3ma_uintmax_t_mul_ok(uintmax_t a, uintmax_t b, int *ec)
+{
+#if DK3_ON_WINDOWS
+ $? "+ dk3ma_uintmax_t_mul_ok %I64u %I64u", a, b
+#else
+ $? "+ dk3ma_uintmax_t_mul_ok %ju %ju", a, b
+#endif
+ if (NULL != ec) {
+ if (DK3_UINTMAX_T_0 != a) {
+ if ((DK3_UINTMAX_T_MAX / a) < b) { $? "! overflow"
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ }
+#if DK3_ON_WINDOWS
+ $? "- dk3ma_uintmax_t_mul_ok %I64u", (a * b)
+#else
+ $? "- dk3ma_uintmax_t_mul_ok %ju", (a * b)
+#endif
+ return (a * b);
+}
+
+
+
+uintmax_t
+dk3ma_uintmax_t_div_ok(uintmax_t a, uintmax_t b, int *ec)
+{
+ uintmax_t back = (uintmax_t)0;
+#if DK3_ON_WINDOWS
+ $? "+ dk3ma_uintmax_t_div_ok %I64u %I64u", a, b
+#else
+ $? "+ dk3ma_uintmax_t_div_ok %ju %ju", a, b
+#endif
+ if (DK3_UINTMAX_T_0 != b) {
+ back = a / b;
+ } else {
+ if (NULL != ec) { $? "! division by zero"
+ *ec = DK3_ERROR_MATH_DIVZERO;
+ }
+ back = DK3_UINTMAX_T_MAX;
+ }
+#if DK3_ON_WINDOWS
+ $? "- dk3ma_uintmax_t_div_ok %I64u", back
+#else
+ $? "- dk3ma_uintmax_t_div_ok %ju", back
+#endif
+ return back;
+}
+
+
+
+uintmax_t
+dk3ma_uintmax_t_gcd(uintmax_t a, uintmax_t b)
+{
+ uintmax_t h;
+#if DK3_ON_WINDOWS
+ $? "+ dk3ma_uintmax_t_gcd_ok %I64u %I64u", a, b
+#else
+ $? "+ dk3ma_uintmax_t_gcd_ok %ju %ju", a, b
+#endif
+ while (DK3_UINTMAX_T_0 < b) {
+ h = a % b;
+ a = b;
+ b = h;
+ }
+ if (DK3_UINTMAX_T_0 == a) { a = DK3_UINTMAX_T_1; }
+#if DK3_ON_WINDOWS
+ $? "- dk3ma_uintmax_t_gcd_ok %I64u", a
+#else
+ $? "- dk3ma_uintmax_t_gcd_ok %ju", a
+#endif
+ return a;
+}
+
+
+#endif
+
+
+
+dk3_um_t
+dk3ma_um_add_ok(dk3_um_t a, dk3_um_t b, int *ec)
+{
+#if DK3_HAVE_INTMAX_T
+ return (dk3ma_uintmax_t_add_ok(a, b, ec));
+#else
+#if DK3_HAVE_LONG_LONG
+ return (dk3ma_ull_add_ok(a, b, ec));
+#else
+ return (dk3ma_ul_add_ok(a, b, ec));
+#endif
+#endif
+}
+
+
+
+dk3_um_t
+dk3ma_um_sub_ok(dk3_um_t a, dk3_um_t b, int *ec)
+{
+#if DK3_HAVE_INTMAX_T
+ return (dk3ma_uintmax_t_sub_ok(a, b, ec));
+#else
+#if DK3_HAVE_LONG_LONG
+ return (dk3ma_ull_sub_ok(a, b, ec));
+#else
+ return (dk3ma_ul_sub_ok(a, b, ec));
+#endif
+#endif
+}
+
+
+
+dk3_um_t
+dk3ma_um_mul_ok(dk3_um_t a, dk3_um_t b, int *ec)
+{
+#if DK3_HAVE_INTMAX_T
+ return (dk3ma_uintmax_t_mul_ok(a, b, ec));
+#else
+#if DK3_HAVE_LONG_LONG
+ return (dk3ma_ull_mul_ok(a, b, ec));
+#else
+ return (dk3ma_ul_mul_ok(a, b, ec));
+#endif
+#endif
+}
+
+
+
+dk3_um_t
+dk3ma_um_div_ok(dk3_um_t a, dk3_um_t b, int *ec)
+{
+#if DK3_HAVE_INTMAX_T
+ return (dk3ma_uintmax_t_div_ok(a, b, ec));
+#else
+#if DK3_HAVE_LONG_LONG
+ return (dk3ma_ull_div_ok(a, b, ec));
+#else
+ return (dk3ma_ul_div_ok(a, b, ec));
+#endif
+#endif
+}
+
+
+
+dk3_um_t
+dk3ma_um_gcd(dk3_um_t a, dk3_um_t b)
+{
+#if DK3_HAVE_INTMAX_T
+ return (dk3ma_uintmax_t_gcd(a, b));
+#else
+#if DK3_HAVE_LONG_LONG
+ return (dk3ma_ull_gcd(a, b));
+#else
+ return (dk3ma_ul_gcd(a, b));
+#endif
+#endif
+}
+
+
+
+size_t
+dk3ma_um_to_sz(dk3_um_t um, int *ec)
+{
+ size_t back = 0;
+#if DK3_SIZEOF_SIZE_T >= DK3_SIZEOF_UM
+ back = (size_t)um;
+#else
+ if ((dk3_um_t)DK3_SIZE_T_MAX >= um) {
+ back = (size_t)um;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+#endif
+ return back;
+}
+
diff --git a/support/dktools/dk3maul.h b/support/dktools/dk3maul.h
new file mode 100644
index 0000000000..809bcdd255
--- /dev/null
+++ b/support/dktools/dk3maul.h
@@ -0,0 +1,303 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3maul.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK3MAUL_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3MAUL_H_INCLUDED 1
+
+
+#line 10 "dk3maul.ctr"
+
+/** @file dk3maul.h Mathematical operations on
+ unsigned long, unsigned long long, uintmax_t and dk3_um_t.
+*/
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Summary of a and b.
+*/
+unsigned long
+dk3ma_ul_add_ok(unsigned long a, unsigned long b, int *ec);
+
+/** Substraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Difference of a and b.
+*/
+unsigned long
+dk3ma_ul_sub_ok(unsigned long a, unsigned long b, int *ec);
+
+/** Multiplication.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Product of a and b.
+*/
+unsigned long
+dk3ma_ul_mul_ok(unsigned long a, unsigned long b, int *ec);
+
+/** Division.
+ @param a Left operand (nominator).
+ @param b Right operand (denominator).
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW or
+ DK3_ERROR_MATH_DIVZERO when returning.
+ @return Fraction of a and b.
+*/
+unsigned long
+dk3ma_ul_div_ok(unsigned long a, unsigned long b, int *ec);
+
+/** Greatest common divisor.
+ @param a Left operand.
+ @param b Right operand.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Greatest common divisor of a and b.
+*/
+unsigned long
+dk3ma_ul_gcd(unsigned long a, unsigned long b);
+
+
+#if DK3_HAVE_LONG_LONG
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Summary of a and b.
+*/
+unsigned long long
+dk3ma_ull_add_ok(unsigned long long a, unsigned long long b, int *ec);
+
+/** Substraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Difference of a and b.
+*/
+unsigned long long
+dk3ma_ull_sub_ok(unsigned long long a, unsigned long long b, int *ec);
+
+/** Multiplication.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Product of a and b.
+*/
+unsigned long long
+dk3ma_ull_mul_ok(unsigned long long a, unsigned long long b, int *ec);
+
+/** Division.
+ @param a Left operand (nominator).
+ @param b Right operand (denominator).
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW or
+ DK3_ERROR_MATH_DIVZERO when returning.
+ @return Fraction of a and b.
+*/
+unsigned long long
+dk3ma_ull_div_ok(unsigned long long a, unsigned long long b, int *ec);
+
+/** Greatest common divisor.
+ @param a Left operand.
+ @param b Right operand.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Greatest common divisor of a and b.
+*/
+unsigned long long
+dk3ma_ull_gcd(unsigned long long a, unsigned long long b);
+
+#endif
+
+
+
+#if DK3_HAVE_INTMAX_T
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Summary of a and b.
+*/
+uintmax_t
+dk3ma_uintmax_t_add_ok(uintmax_t a, uintmax_t b, int *ec);
+
+/** Substraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Difference of a and b.
+*/
+uintmax_t
+dk3ma_uintmax_t_sub_ok(uintmax_t a, uintmax_t b, int *ec);
+
+/** Multiplication.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Product of a and b.
+*/
+uintmax_t
+dk3ma_uintmax_t_mul_ok(uintmax_t a, uintmax_t b, int *ec);
+
+/** Division.
+ @param a Left operand (nominator).
+ @param b Right operand (denominator).
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW or
+ DK3_ERROR_MATH_DIVZERO when returning.
+ @return Fraction of a and b.
+*/
+uintmax_t
+dk3ma_uintmax_t_div_ok(uintmax_t a, uintmax_t b, int *ec);
+
+/** Greatest common divisor.
+ @param a Left operand.
+ @param b Right operand.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Greatest common divisor of a and b.
+*/
+uintmax_t
+dk3ma_uintmax_t_gcd(uintmax_t a, uintmax_t b);
+
+#endif
+
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Summary of a and b.
+*/
+dk3_um_t
+dk3ma_um_add_ok(dk3_um_t a, dk3_um_t b, int *ec);
+
+/** Substraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Difference of a and b.
+*/
+dk3_um_t
+dk3ma_um_sub_ok(dk3_um_t a, dk3_um_t b, int *ec);
+
+/** Multiplication.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Product of a and b.
+*/
+dk3_um_t
+dk3ma_um_mul_ok(dk3_um_t a, dk3_um_t b, int *ec);
+
+/** Division.
+ @param a Left operand (nominator).
+ @param b Right operand (denominator).
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW or
+ DK3_ERROR_MATH_DIVZERO when returning.
+ @return Fraction of a and b.
+*/
+dk3_um_t
+dk3ma_um_div_ok(dk3_um_t a, dk3_um_t b, int *ec);
+
+/** Greatest common divisor.
+ @param a Left operand.
+ @param b Right operand.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Greatest common divisor of a and b.
+*/
+dk3_um_t
+dk3ma_um_gcd(dk3_um_t a, dk3_um_t b);
+
+/** Convert dk3_um_t to size_t.
+ @param um Positive dk3_um_t value to convert.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_MATH_OVERFLOW on conversion errors.
+ @return Positive number on success, 0 on error
+ (significant bits lost in conversion).
+*/
+size_t
+dk3ma_um_to_sz(dk3_um_t um, int *ec);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3maus.c b/support/dktools/dk3maus.c
new file mode 100644
index 0000000000..97fc88e944
--- /dev/null
+++ b/support/dktools/dk3maus.c
@@ -0,0 +1,114 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3maus.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3maus.c The dk3maus module.
+*/
+
+
+#line 98 "dk3maus.ctr"
+
+
+
+#include "dk3ma.h"
+
+
+
+
+
+#line 106 "dk3maus.ctr"
+
+
+
+unsigned short
+dk3ma_us_add_ok(unsigned short a, unsigned short b, int *ec)
+{
+ if (NULL != ec) {
+ if ((DK3_US_MAX - a) < b) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ return (a + b);
+}
+
+
+
+unsigned short
+dk3ma_us_sub_ok(unsigned short a, unsigned short b, int *ec)
+{
+ if (NULL != ec) { if (b > a) { *ec = DK3_ERROR_MATH_OVERFLOW; } }
+ return (a - b);
+}
+
+
+
+unsigned short
+dk3ma_us_mul_ok(unsigned short a, unsigned short b, int *ec)
+{
+ if (NULL != ec) {
+ if (0 != a) {
+ if ((DK3_US_MAX / a) < b) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ return (a * b);
+}
+
+
+
+unsigned short
+dk3ma_us_div_ok(unsigned short a, unsigned short b, int *ec)
+{
+ unsigned short back = (unsigned short)0;
+ if (0 != b) {
+ back = a / b;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_DIVZERO; }
+ back = DK3_US_MAX;
+ }
+ return back;
+}
+
+
+
+unsigned short
+dk3ma_us_gcd(unsigned short a, unsigned short b)
+{
+ unsigned short h;
+ while (0 < b) {
+ h = a % b;
+ a = b;
+ b = h;
+ }
+ if (0 == a) { a = (unsigned short)1; }
+ return a;
+}
+
diff --git a/support/dktools/dk3maus.ctr b/support/dktools/dk3maus.ctr
new file mode 100644
index 0000000000..cfbb8cff15
--- /dev/null
+++ b/support/dktools/dk3maus.ctr
@@ -0,0 +1,169 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2014-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk3maus.h Mathematical operations on unsigned short.
+*/
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Summary of a and b.
+*/
+unsigned short
+dk3ma_us_add_ok(unsigned short a, unsigned short b, int *ec);
+
+/** Substraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Difference of a and b.
+*/
+unsigned short
+dk3ma_us_sub_ok(unsigned short a, unsigned short b, int *ec);
+
+/** Multiplication.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Product of a and b.
+*/
+unsigned short
+dk3ma_us_mul_ok(unsigned short a, unsigned short b, int *ec);
+
+/** Division.
+ @param a Left operand (nominator).
+ @param b Right operand (denominator).
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW or
+ DK3_ERROR_MATH_DIVZERO when returning.
+ @return Fraction of a and b.
+*/
+unsigned short
+dk3ma_us_div_ok(unsigned short a, unsigned short b, int *ec);
+
+/** Greatest common divisor.
+ @param a Left operand.
+ @param b Right operand.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Greatest common divisor of a and b.
+*/
+unsigned short
+dk3ma_us_gcd(unsigned short a, unsigned short b);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+
+
+#include "dk3ma.h"
+
+
+
+$!trace-include
+
+
+
+unsigned short
+dk3ma_us_add_ok(unsigned short a, unsigned short b, int *ec)
+{
+ if (NULL != ec) {
+ if ((DK3_US_MAX - a) < b) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ return (a + b);
+}
+
+
+
+unsigned short
+dk3ma_us_sub_ok(unsigned short a, unsigned short b, int *ec)
+{
+ if (NULL != ec) { if (b > a) { *ec = DK3_ERROR_MATH_OVERFLOW; } }
+ return (a - b);
+}
+
+
+
+unsigned short
+dk3ma_us_mul_ok(unsigned short a, unsigned short b, int *ec)
+{
+ if (NULL != ec) {
+ if (0 != a) {
+ if ((DK3_US_MAX / a) < b) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ return (a * b);
+}
+
+
+
+unsigned short
+dk3ma_us_div_ok(unsigned short a, unsigned short b, int *ec)
+{
+ unsigned short back = (unsigned short)0;
+ if (0 != b) {
+ back = a / b;
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_DIVZERO; }
+ back = DK3_US_MAX;
+ }
+ return back;
+}
+
+
+
+unsigned short
+dk3ma_us_gcd(unsigned short a, unsigned short b)
+{
+ unsigned short h;
+ while (0 < b) {
+ h = a % b;
+ a = b;
+ b = h;
+ }
+ if (0 == a) { a = (unsigned short)1; }
+ return a;
+}
+
diff --git a/support/dktools/dk3maus.h b/support/dktools/dk3maus.h
new file mode 100644
index 0000000000..3f6f91b984
--- /dev/null
+++ b/support/dktools/dk3maus.h
@@ -0,0 +1,130 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3maus.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK3MAUS_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3MAUS_H_INCLUDED 1
+
+
+#line 10 "dk3maus.ctr"
+
+/** @file dk3maus.h Mathematical operations on unsigned short.
+*/
+
+#include <dk3conf.h>
+
+#include <stdio.h>
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if DK3_HAVE_MATH_H
+#include <math.h>
+#endif
+#if DK3_HAVE_FLOAT_H
+#include <float.h>
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Summary of a and b.
+*/
+unsigned short
+dk3ma_us_add_ok(unsigned short a, unsigned short b, int *ec);
+
+/** Substraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Difference of a and b.
+*/
+unsigned short
+dk3ma_us_sub_ok(unsigned short a, unsigned short b, int *ec);
+
+/** Multiplication.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Product of a and b.
+*/
+unsigned short
+dk3ma_us_mul_ok(unsigned short a, unsigned short b, int *ec);
+
+/** Division.
+ @param a Left operand (nominator).
+ @param b Right operand (denominator).
+ @param ec Pointer to error code variable, may be NULL.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW or
+ DK3_ERROR_MATH_DIVZERO when returning.
+ @return Fraction of a and b.
+*/
+unsigned short
+dk3ma_us_div_ok(unsigned short a, unsigned short b, int *ec);
+
+/** Greatest common divisor.
+ @param a Left operand.
+ @param b Right operand.
+ The variable may be set to DK3_ERROR_MATH_OVERFLOW when returning.
+ @return Greatest common divisor of a and b.
+*/
+unsigned short
+dk3ma_us_gcd(unsigned short a, unsigned short b);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3md.c b/support/dktools/dk3md.c
new file mode 100644
index 0000000000..1be6062877
--- /dev/null
+++ b/support/dktools/dk3md.c
@@ -0,0 +1,644 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3md.ctr
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3md.c The dk3md module.
+*/
+
+
+#line 283 "dk3md.ctr"
+
+#include "dk3all.h"
+#include "dk3md.h"
+#include <math.h>
+
+
+/** Maximum value for long double.
+*/
+#define DK3_MAX_LONG_DOUBLE DK3_MAX_DOUBLE
+
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+
+/* Real long double (start)
+*/
+
+/** Conversion format strings in dkChar size.
+*/
+static dkChar const * const dk3md_conversion_formats[] = {
+dkT("%Le"),
+dkT("%Lf"),
+dkT("%Lg"),
+NULL
+};
+
+/** Conversion format strings in char size.
+*/
+static char const * const dk3md_c8_conversion_formats[] = {
+"%Le",
+"%Lf",
+"%Lg",
+NULL
+};
+
+/* Real long double (end)
+*/
+
+#else
+
+/* Fallback to normal double (start)
+*/
+
+/** Conversion format strings in dkChar size.
+*/
+static dkChar const * const dk3md_conversion_formats[] = {
+dkT("%le"),
+dkT("%lf"),
+dkT("%lg"),
+NULL
+};
+
+/** Conversion format strings in char size.
+*/
+static char const * const dk3md_c8_conversion_formats[] = {
+"%le",
+"%lf",
+"%lg",
+NULL
+};
+
+/* Fallback to normal double (end)
+*/
+
+#endif
+
+
+dkChar const *
+dk3md_format(char c)
+{
+ dkChar const *back;
+
+ back = dk3md_conversion_formats[0];
+ switch(c) {
+ case 'f': case 'F': {
+ back = dk3md_conversion_formats[1];
+ } break;
+ case 'g': case 'G': {
+ back = dk3md_conversion_formats[2];
+ } break;
+ }
+ return back;
+}
+
+
+
+char const *
+dk3md_c8_format(char c)
+{
+ char const *back;
+
+ back = dk3md_c8_conversion_formats[0];
+ switch(c) {
+ case 'f': case 'F': {
+ back = dk3md_c8_conversion_formats[1];
+ } break;
+ case 'g': case 'G': {
+ back = dk3md_c8_conversion_formats[2];
+ } break;
+ }
+ return back;
+}
+
+
+
+int
+dk3md_have_long_double(void)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+
+
+dk3_double_t dk3md_add_ok(dk3_double_t a, dk3_double_t b, int *ec)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+ double back;
+ if(a >= 0.0L) {
+ if(b >= 0.0L) {
+ back = a + b;
+ if((DK3_MAX_LONG_DOUBLE - a) < b) {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ back = a + b;
+ }
+ } else {
+ if(b >= 0.0L) {
+ back = a + b;
+ } else {
+ back = -1.0L * dk3md_add_ok(fabsl(a), fabsl(b), ec);
+ }
+ }
+ return back;
+#else
+ return(dk3ma_d_add_ok(a, b, ec));
+#endif
+}
+
+
+
+dk3_double_t dk3md_sub_ok(dk3_double_t a, dk3_double_t b, int *ec)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+ double back;
+ if(a >= 0.0L) {
+ if(b >= 0.0L) {
+ back = a - b;
+ } else {
+ back = dk3md_add_ok(a, fabsl(b), ec);
+ }
+ } else {
+ if(b >= 0.0L) {
+ back = -1.0L * dk3md_add_ok(fabsl(a), b, ec);
+ } else {
+ back = a - b;
+ }
+ }
+ return back;
+#else
+ return(dk3ma_d_sub_ok(a, b, ec));
+#endif
+}
+
+
+
+dk3_double_t dk3md_mul_ok(dk3_double_t a, dk3_double_t b, int *ec)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+ double back;
+ if(a >= 0.0L) {
+ if(b >= 0.0L) {
+ back = a * b;
+ if(a > 1.0L) {
+ if((DK3_MAX_LONG_DOUBLE / a) < b) {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ } else {
+ back = -1.0L * dk3md_mul_ok(a, fabsl(b), ec);
+ }
+ } else {
+ if(b >= 0.0L) {
+ back = -1.0L * dk3md_mul_ok(fabsl(a), b, ec);
+ } else {
+ back = dk3md_mul_ok(fabsl(a), fabsl(b), ec);
+ }
+ }
+ return back;
+#else
+ return(dk3ma_d_mul_ok(a, b, ec));
+#endif
+}
+
+
+
+dk3_double_t dk3md_div_ok(dk3_double_t a, dk3_double_t b, int *ec)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+ double back;
+ if(a >= 0.0L) {
+ if(b >= 0.0L) {
+ if(b < 1.0L) {
+ if((DK3_MAX_LONG_DOUBLE * b) > a) {
+ back = a / b;
+ } else {
+ back = 0.0L;
+ if(ec) { *ec = DK3_ERROR_MATH_DIVZERO; }
+ }
+ } else {
+ back = a / b;
+ }
+ } else {
+ back = -1.0L * dk3md_div_ok(a, fabsl(b), ec);
+ }
+ } else {
+ if(b >= 0.0L) {
+ back = -1.0L * dk3md_div_ok(fabsl(a), b, ec);
+ } else {
+ back = dk3md_div_ok(fabsl(a), fabsl(b), ec);
+ }
+ }
+ return back;
+#else
+ return(dk3ma_d_div_ok(a, b, ec));
+#endif
+}
+
+
+
+dk3_double_t
+dk3md_sin(dk3_double_t x)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if DK3_HAVE_SINL
+ return(sinl(x));
+#else
+ return((long double)sin((double)(x)));
+#endif
+#else
+ return(sin(x));
+#endif
+}
+
+
+
+dk3_double_t
+dk3md_cos(dk3_double_t x)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if DK3_HAVE_COSL
+ return(cosl(x));
+#else
+ return((long double)cos((double)(x)));
+#endif
+#else
+ return(cos(x));
+#endif
+}
+
+
+
+dk3_double_t
+dk3md_tan(dk3_double_t x)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if DK3_HAVE_TANL
+ return(tanl(x));
+#else
+ return((long double)tan((double)(x)));
+#endif
+#else
+ return(tan(x));
+#endif
+}
+
+
+
+dk3_double_t
+dk3md_asin(dk3_double_t x)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if DK3_HAVE_ASINL
+ return(asinl(x));
+#else
+ return((long double)asin((double)(x)));
+#endif
+#else
+ return(asin(x));
+#endif
+}
+
+
+
+dk3_double_t
+dk3md_acos(dk3_double_t x)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if DK3_HAVE_ACOSL
+ return(acosl(x));
+#else
+ return((long double)acos((double)(x)));
+#endif
+#else
+ return(acos(x));
+#endif
+}
+
+
+
+dk3_double_t
+dk3md_atan(dk3_double_t x)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if DK3_HAVE_ATANL
+ return(atanl(x));
+#else
+ return((long double)atan((double)(x)));
+#endif
+#else
+ return(atan(x));
+#endif
+}
+
+
+
+dk3_double_t
+dk3md_atan2(dk3_double_t y, dk3_double_t x)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if DK3_HAVE_ATAN2L
+ return(atan2l(y, x));
+#else
+#if DK3_HAVE_ATAN2
+ return((long double)atan2((double)(y), (double)(x)));
+#else
+ return((long double)dk3ma_d_atan2((double)y, (double)x));
+#endif
+#endif
+#else
+#if DK3_HAVE_ATAN2
+ return(atan2(y, x));
+#else
+ return(dk3ma_d_atan2(y,x));
+#endif
+#endif
+}
+
+
+
+dk3_double_t
+dk3md_fabs(dk3_double_t x)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if DK3_HAVE_FABSL
+ return(fabsl(x));
+#else
+ return((long double)fabs((double)(x)));
+#endif
+#else
+ return(fabs(x));
+#endif
+}
+
+
+
+dk3_double_t
+dk3md_floor(dk3_double_t x)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if DK3_HAVE_FLOORL
+ return(floorl(x));
+#else
+ return((long double)floor((double)(x)));
+#endif
+#else
+ return(floor(x));
+#endif
+}
+
+
+
+dk3_double_t
+dk3md_ceil(dk3_double_t x)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if DK3_HAVE_CEILL
+ return(ceill(x));
+#else
+ return((long double)ceil((double)(x)));
+#endif
+#else
+ return(ceil(x));
+#endif
+}
+
+
+
+dk3_double_t
+dk3md_rint(dk3_double_t x)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if DK3_HAVE_RINTL
+ return(rintl(x));
+#else
+#if DK3_HAVE_RINT
+ return((long double)rint((double)(x)));
+#else
+ return((long double)dk3ma_d_rint((double)(x)));
+#endif
+#endif
+#else
+#if DK3_HAVE_RINT
+ return(rint(x));
+#else
+ return(dk3ma_d_rint(x));
+#endif
+#endif
+}
+
+
+
+dk3_double_t
+dk3md_exp(dk3_double_t x)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if DK3_HAVE_EXPL
+ return(expl(x));
+#else
+ return((long double)exp((double)(x)));
+#endif
+#else
+ return(exp(x));
+#endif
+}
+
+
+
+dk3_double_t
+dk3md_log(dk3_double_t x)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if DK3_HAVE_LOGL
+ return(logl(x));
+#else
+ return((long double)log((double)(x)));
+#endif
+#else
+ return(log(x));
+#endif
+}
+
+
+
+dk3_double_t
+dk3md_sqrt(dk3_double_t x)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if DK3_HAVE_SQRTL
+ return(sqrtl(x));
+#else
+ return((long double)sqrt((double)(x)));
+#endif
+#else
+ return(sqrt(x));
+#endif
+}
+
+
+
+dk3_double_t
+dk3md_sinh(dk3_double_t x)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if DK3_HAVE_SINHL
+ return(sinhl(x));
+#else
+ return((long double)sinh((double)(x)));
+#endif
+#else
+ return(sinh(x));
+#endif
+}
+
+
+
+dk3_double_t
+dk3md_cosh(dk3_double_t x)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if DK3_HAVE_COSHL
+ return(coshl(x));
+#else
+ return((long double)cosh((double)(x)));
+#endif
+#else
+ return(cosh(x));
+#endif
+}
+
+
+
+dk3_double_t
+dk3md_tanh(dk3_double_t x)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if DK3_HAVE_TANHL
+ return(tanhl(x));
+#else
+ return((long double)tanh((double)(x)));
+#endif
+#else
+ return(tanh(x));
+#endif
+}
+
+
+
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if (DK3_HAVE_ASINHL) && (DK3_HAVE_ACOSHL) && (DK3_HAVE_ATANHL)
+
+dk3_double_t
+dk3md_asinh(dk3_double_t x)
+{
+ return(asinhl(x));
+}
+
+
+dk3_double_t
+dk3md_acosh(dk3_double_t x)
+{
+ return(acoshl(x));
+}
+
+
+dk3_double_t
+dk3md_atanh(dk3_double_t x)
+{
+ return(atanhl(x));
+}
+
+#else
+#if (DK3_HAVE_ASINH) && (DK3_HAVE_ACOSH) && (DK3_HAVE_ATANH)
+
+dk3_double_t
+dk3md_asinh(dk3_double_t x)
+{
+ return((long double)asinh((double)x));
+}
+
+
+dk3_double_t
+dk3md_acosh(dk3_double_t x)
+{
+ return((long double)acosh((double)x));
+}
+
+
+dk3_double_t
+dk3md_atanh(dk3_double_t x)
+{
+ return((long double)atanh((double)x));
+}
+
+#else
+#if (DK3_NEED_ASINH) || (DK3_NEED_ACOSH) || (DK3_NEED_ATANH)
+#error "No asinh/acosh/atanh function in math library!"
+#endif
+#endif
+#endif
+#else
+
+#if (DK3_HAVE_ASINH) && (DK3_HAVE_ACOSH) && (DK3_HAVE_ATANH)
+
+dk3_double_t
+dk3md_asinh(dk3_double_t x)
+{
+ return(asinh(x));
+}
+
+
+dk3_double_t
+dk3md_acosh(dk3_double_t x)
+{
+ return(acosh(x));
+}
+
+
+dk3_double_t
+dk3md_atanh(dk3_double_t x)
+{
+ return(atanh(x));
+}
+
+#else
+#if (DK3_NEED_ASINH) || (DK3_NEED_ACOSH) || (DK3_NEED_ATANH)
+#error "No asinh/acosh/atanh function in math library!"
+#endif
+#endif
+#endif
+
+
diff --git a/support/dktools/dk3md.ctr b/support/dktools/dk3md.ctr
new file mode 100644
index 0000000000..28f3b52605
--- /dev/null
+++ b/support/dktools/dk3md.ctr
@@ -0,0 +1,886 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2013-xxxx
+license = bsd
+
+
+%% header
+
+#include <dk3conf.h>
+#include <dk3types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Addition of double or long double.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable.
+ @return Operation result.
+*/
+dk3_double_t
+dk3md_add_ok(dk3_double_t a, dk3_double_t b, int *ec);
+
+/** Substraction of double or long double.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable.
+ @return Operation result.
+*/
+dk3_double_t
+dk3md_sub_ok(dk3_double_t a, dk3_double_t b, int *ec);
+
+/** Multiplication of double or long double.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable.
+ @return Operation result.
+*/
+dk3_double_t
+dk3md_mul_ok(dk3_double_t a, dk3_double_t b, int *ec);
+
+/** Division of double or long double.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable.
+ @return Operation result.
+*/
+dk3_double_t
+dk3md_div_ok(dk3_double_t a, dk3_double_t b, int *ec);
+
+/** Obtain format string for conversions.
+ @param c Key character 'e', 'f', or 'g'.
+ @return Conversion format string.
+*/
+dkChar const *
+dk3md_format(char c);
+
+/** Obtain format string for conversions.
+ @param c Key character 'e', 'f', or 'g'.
+ @return Conversion format string.
+*/
+char const *
+dk3md_c8_format(char c);
+
+/** Check availability of long double.
+ @return 1 for long double available, 0 for fallback to double.
+*/
+int
+dk3md_have_long_double(void);
+
+/** Sinus.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_sin(dk3_double_t x);
+
+/** Cosinus.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_cos(dk3_double_t x);
+
+/** Tangens.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_tan(dk3_double_t x);
+
+/** Arcus sinus.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_asin(dk3_double_t x);
+
+/** Arcus cosinus.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_acos(dk3_double_t x);
+
+/** Arcus tangens.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_atan(dk3_double_t x);
+
+/** Arcus tangens for two arguments.
+ @param y Y position.
+ @param x X position.
+ @return Result.
+*/
+dk3_double_t
+dk3md_atan2(dk3_double_t y, dk3_double_t x);
+
+/** Absolute value.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_fabs(dk3_double_t x);
+
+/** Round downwards.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_floor(dk3_double_t x);
+
+/** Round upwards.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_ceil(dk3_double_t x);
+
+/** Round to next integer.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_rint(dk3_double_t x);
+
+/** Exponential function.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_exp(dk3_double_t x);
+
+/** Logarithm.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_log(dk3_double_t x);
+
+/** Square root.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_sqrt(dk3_double_t x);
+
+/** Sinus hyperbolicus.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_sinh(dk3_double_t x);
+
+/** Cosinus hyperbolicus.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_cosh(dk3_double_t x);
+
+/** Tangens hyperbolicus.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_tanh(dk3_double_t x);
+
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if (DK3_HAVE_ASINHL) && (DK3_HAVE_ACOSHL) && (DK3_HAVE_ATANHL)
+
+/** Arcus sinus hyperbolicus.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_asinh(dk3_double_t x);
+
+/** Arcus cosinus hyperbolicus.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_acosh(dk3_double_t x);
+
+/** Arcus tangens hyperbolicus.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_atanh(dk3_double_t x);
+
+#else
+#if (DK3_HAVE_ASINH) && (DK3_HAVE_ACOSH) && (DK3_HAVE_ATANH)
+
+/** Arcus sinus hyperbolicus.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_asinh(dk3_double_t x);
+
+/** Arcus cosinus hyperbolicus.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_acosh(dk3_double_t x);
+
+/** Arcus tangens hyperbolicus.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_atanh(dk3_double_t x);
+
+#else
+#if (DK3_NEED_ASINH) || (DK3_NEED_ACOSH) || (DK3_NEED_ATANH)
+#error "No asinh/acosh/atanh function in math library!"
+#endif
+#endif
+#endif
+#else
+#if (DK3_HAVE_ASINH) && (DK3_HAVE_ACOSH) && (DK3_HAVE_ATANH)
+
+/** Arcus sinus hyperbolicus.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_asinh(dk3_double_t x);
+
+/** Arcus cosinus hyperbolicus.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_acosh(dk3_double_t x);
+
+/** Arcus tangens hyperbolicus.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_atanh(dk3_double_t x);
+#else
+
+#if (DK3_NEED_ASINH) || (DK3_NEED_ACOSH) || (DK3_NEED_ATANH)
+#error "No asinh/acosh/atanh function in math library!"
+#endif
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk3all.h"
+#include "dk3md.h"
+#include <math.h>
+
+
+/** Maximum value for long double.
+*/
+#define DK3_MAX_LONG_DOUBLE DK3_MAX_DOUBLE
+
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+
+/* Real long double (start)
+*/
+
+/** Conversion format strings in dkChar size.
+*/
+static dkChar const * const dk3md_conversion_formats[] = {
+dkT("%Le"),
+dkT("%Lf"),
+dkT("%Lg"),
+NULL
+};
+
+/** Conversion format strings in char size.
+*/
+static char const * const dk3md_c8_conversion_formats[] = {
+"%Le",
+"%Lf",
+"%Lg",
+NULL
+};
+
+/* Real long double (end)
+*/
+
+#else
+
+/* Fallback to normal double (start)
+*/
+
+/** Conversion format strings in dkChar size.
+*/
+static dkChar const * const dk3md_conversion_formats[] = {
+dkT("%le"),
+dkT("%lf"),
+dkT("%lg"),
+NULL
+};
+
+/** Conversion format strings in char size.
+*/
+static char const * const dk3md_c8_conversion_formats[] = {
+"%le",
+"%lf",
+"%lg",
+NULL
+};
+
+/* Fallback to normal double (end)
+*/
+
+#endif
+
+
+dkChar const *
+dk3md_format(char c)
+{
+ dkChar const *back;
+
+ back = dk3md_conversion_formats[0];
+ switch(c) {
+ case 'f': case 'F': {
+ back = dk3md_conversion_formats[1];
+ } break;
+ case 'g': case 'G': {
+ back = dk3md_conversion_formats[2];
+ } break;
+ }
+ return back;
+}
+
+
+
+char const *
+dk3md_c8_format(char c)
+{
+ char const *back;
+
+ back = dk3md_c8_conversion_formats[0];
+ switch(c) {
+ case 'f': case 'F': {
+ back = dk3md_c8_conversion_formats[1];
+ } break;
+ case 'g': case 'G': {
+ back = dk3md_c8_conversion_formats[2];
+ } break;
+ }
+ return back;
+}
+
+
+
+int
+dk3md_have_long_double(void)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+
+
+dk3_double_t dk3md_add_ok(dk3_double_t a, dk3_double_t b, int *ec)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+ double back;
+ if(a >= 0.0L) {
+ if(b >= 0.0L) {
+ back = a + b;
+ if((DK3_MAX_LONG_DOUBLE - a) < b) {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ back = a + b;
+ }
+ } else {
+ if(b >= 0.0L) {
+ back = a + b;
+ } else {
+ back = -1.0L * dk3md_add_ok(fabsl(a), fabsl(b), ec);
+ }
+ }
+ return back;
+#else
+ return(dk3ma_d_add_ok(a, b, ec));
+#endif
+}
+
+
+
+dk3_double_t dk3md_sub_ok(dk3_double_t a, dk3_double_t b, int *ec)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+ double back;
+ if(a >= 0.0L) {
+ if(b >= 0.0L) {
+ back = a - b;
+ } else {
+ back = dk3md_add_ok(a, fabsl(b), ec);
+ }
+ } else {
+ if(b >= 0.0L) {
+ back = -1.0L * dk3md_add_ok(fabsl(a), b, ec);
+ } else {
+ back = a - b;
+ }
+ }
+ return back;
+#else
+ return(dk3ma_d_sub_ok(a, b, ec));
+#endif
+}
+
+
+
+dk3_double_t dk3md_mul_ok(dk3_double_t a, dk3_double_t b, int *ec)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+ double back;
+ if(a >= 0.0L) {
+ if(b >= 0.0L) {
+ back = a * b;
+ if(a > 1.0L) {
+ if((DK3_MAX_LONG_DOUBLE / a) < b) {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ }
+ } else {
+ back = -1.0L * dk3md_mul_ok(a, fabsl(b), ec);
+ }
+ } else {
+ if(b >= 0.0L) {
+ back = -1.0L * dk3md_mul_ok(fabsl(a), b, ec);
+ } else {
+ back = dk3md_mul_ok(fabsl(a), fabsl(b), ec);
+ }
+ }
+ return back;
+#else
+ return(dk3ma_d_mul_ok(a, b, ec));
+#endif
+}
+
+
+
+dk3_double_t dk3md_div_ok(dk3_double_t a, dk3_double_t b, int *ec)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+ double back;
+ if(a >= 0.0L) {
+ if(b >= 0.0L) {
+ if(b < 1.0L) {
+ if((DK3_MAX_LONG_DOUBLE * b) > a) {
+ back = a / b;
+ } else {
+ back = 0.0L;
+ if(ec) { *ec = DK3_ERROR_MATH_DIVZERO; }
+ }
+ } else {
+ back = a / b;
+ }
+ } else {
+ back = -1.0L * dk3md_div_ok(a, fabsl(b), ec);
+ }
+ } else {
+ if(b >= 0.0L) {
+ back = -1.0L * dk3md_div_ok(fabsl(a), b, ec);
+ } else {
+ back = dk3md_div_ok(fabsl(a), fabsl(b), ec);
+ }
+ }
+ return back;
+#else
+ return(dk3ma_d_div_ok(a, b, ec));
+#endif
+}
+
+
+
+dk3_double_t
+dk3md_sin(dk3_double_t x)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if DK3_HAVE_SINL
+ return(sinl(x));
+#else
+ return((long double)sin((double)(x)));
+#endif
+#else
+ return(sin(x));
+#endif
+}
+
+
+
+dk3_double_t
+dk3md_cos(dk3_double_t x)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if DK3_HAVE_COSL
+ return(cosl(x));
+#else
+ return((long double)cos((double)(x)));
+#endif
+#else
+ return(cos(x));
+#endif
+}
+
+
+
+dk3_double_t
+dk3md_tan(dk3_double_t x)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if DK3_HAVE_TANL
+ return(tanl(x));
+#else
+ return((long double)tan((double)(x)));
+#endif
+#else
+ return(tan(x));
+#endif
+}
+
+
+
+dk3_double_t
+dk3md_asin(dk3_double_t x)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if DK3_HAVE_ASINL
+ return(asinl(x));
+#else
+ return((long double)asin((double)(x)));
+#endif
+#else
+ return(asin(x));
+#endif
+}
+
+
+
+dk3_double_t
+dk3md_acos(dk3_double_t x)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if DK3_HAVE_ACOSL
+ return(acosl(x));
+#else
+ return((long double)acos((double)(x)));
+#endif
+#else
+ return(acos(x));
+#endif
+}
+
+
+
+dk3_double_t
+dk3md_atan(dk3_double_t x)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if DK3_HAVE_ATANL
+ return(atanl(x));
+#else
+ return((long double)atan((double)(x)));
+#endif
+#else
+ return(atan(x));
+#endif
+}
+
+
+
+dk3_double_t
+dk3md_atan2(dk3_double_t y, dk3_double_t x)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if DK3_HAVE_ATAN2L
+ return(atan2l(y, x));
+#else
+#if DK3_HAVE_ATAN2
+ return((long double)atan2((double)(y), (double)(x)));
+#else
+ return((long double)dk3ma_d_atan2((double)y, (double)x));
+#endif
+#endif
+#else
+#if DK3_HAVE_ATAN2
+ return(atan2(y, x));
+#else
+ return(dk3ma_d_atan2(y,x));
+#endif
+#endif
+}
+
+
+
+dk3_double_t
+dk3md_fabs(dk3_double_t x)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if DK3_HAVE_FABSL
+ return(fabsl(x));
+#else
+ return((long double)fabs((double)(x)));
+#endif
+#else
+ return(fabs(x));
+#endif
+}
+
+
+
+dk3_double_t
+dk3md_floor(dk3_double_t x)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if DK3_HAVE_FLOORL
+ return(floorl(x));
+#else
+ return((long double)floor((double)(x)));
+#endif
+#else
+ return(floor(x));
+#endif
+}
+
+
+
+dk3_double_t
+dk3md_ceil(dk3_double_t x)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if DK3_HAVE_CEILL
+ return(ceill(x));
+#else
+ return((long double)ceil((double)(x)));
+#endif
+#else
+ return(ceil(x));
+#endif
+}
+
+
+
+dk3_double_t
+dk3md_rint(dk3_double_t x)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if DK3_HAVE_RINTL
+ return(rintl(x));
+#else
+#if DK3_HAVE_RINT
+ return((long double)rint((double)(x)));
+#else
+ return((long double)dk3ma_d_rint((double)(x)));
+#endif
+#endif
+#else
+#if DK3_HAVE_RINT
+ return(rint(x));
+#else
+ return(dk3ma_d_rint(x));
+#endif
+#endif
+}
+
+
+
+dk3_double_t
+dk3md_exp(dk3_double_t x)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if DK3_HAVE_EXPL
+ return(expl(x));
+#else
+ return((long double)exp((double)(x)));
+#endif
+#else
+ return(exp(x));
+#endif
+}
+
+
+
+dk3_double_t
+dk3md_log(dk3_double_t x)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if DK3_HAVE_LOGL
+ return(logl(x));
+#else
+ return((long double)log((double)(x)));
+#endif
+#else
+ return(log(x));
+#endif
+}
+
+
+
+dk3_double_t
+dk3md_sqrt(dk3_double_t x)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if DK3_HAVE_SQRTL
+ return(sqrtl(x));
+#else
+ return((long double)sqrt((double)(x)));
+#endif
+#else
+ return(sqrt(x));
+#endif
+}
+
+
+
+dk3_double_t
+dk3md_sinh(dk3_double_t x)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if DK3_HAVE_SINHL
+ return(sinhl(x));
+#else
+ return((long double)sinh((double)(x)));
+#endif
+#else
+ return(sinh(x));
+#endif
+}
+
+
+
+dk3_double_t
+dk3md_cosh(dk3_double_t x)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if DK3_HAVE_COSHL
+ return(coshl(x));
+#else
+ return((long double)cosh((double)(x)));
+#endif
+#else
+ return(cosh(x));
+#endif
+}
+
+
+
+dk3_double_t
+dk3md_tanh(dk3_double_t x)
+{
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if DK3_HAVE_TANHL
+ return(tanhl(x));
+#else
+ return((long double)tanh((double)(x)));
+#endif
+#else
+ return(tanh(x));
+#endif
+}
+
+
+
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if (DK3_HAVE_ASINHL) && (DK3_HAVE_ACOSHL) && (DK3_HAVE_ATANHL)
+
+dk3_double_t
+dk3md_asinh(dk3_double_t x)
+{
+ return(asinhl(x));
+}
+
+
+dk3_double_t
+dk3md_acosh(dk3_double_t x)
+{
+ return(acoshl(x));
+}
+
+
+dk3_double_t
+dk3md_atanh(dk3_double_t x)
+{
+ return(atanhl(x));
+}
+
+#else
+#if (DK3_HAVE_ASINH) && (DK3_HAVE_ACOSH) && (DK3_HAVE_ATANH)
+
+dk3_double_t
+dk3md_asinh(dk3_double_t x)
+{
+ return((long double)asinh((double)x));
+}
+
+
+dk3_double_t
+dk3md_acosh(dk3_double_t x)
+{
+ return((long double)acosh((double)x));
+}
+
+
+dk3_double_t
+dk3md_atanh(dk3_double_t x)
+{
+ return((long double)atanh((double)x));
+}
+
+#else
+#if (DK3_NEED_ASINH) || (DK3_NEED_ACOSH) || (DK3_NEED_ATANH)
+#error "No asinh/acosh/atanh function in math library!"
+#endif
+#endif
+#endif
+#else
+
+#if (DK3_HAVE_ASINH) && (DK3_HAVE_ACOSH) && (DK3_HAVE_ATANH)
+
+dk3_double_t
+dk3md_asinh(dk3_double_t x)
+{
+ return(asinh(x));
+}
+
+
+dk3_double_t
+dk3md_acosh(dk3_double_t x)
+{
+ return(acosh(x));
+}
+
+
+dk3_double_t
+dk3md_atanh(dk3_double_t x)
+{
+ return(atanh(x));
+}
+
+#else
+#if (DK3_NEED_ASINH) || (DK3_NEED_ACOSH) || (DK3_NEED_ATANH)
+#error "No asinh/acosh/atanh function in math library!"
+#endif
+#endif
+#endif
+
+
diff --git a/support/dktools/dk3md.h b/support/dktools/dk3md.h
new file mode 100644
index 0000000000..ddbd24514d
--- /dev/null
+++ b/support/dktools/dk3md.h
@@ -0,0 +1,319 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3md.ctr
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3md.h Header file for the dk3md module.
+*/
+
+#ifndef DK3MD_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3MD_H_INCLUDED 1
+
+
+#line 9 "dk3md.ctr"
+
+#include <dk3conf.h>
+#include <dk3types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Addition of double or long double.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable.
+ @return Operation result.
+*/
+dk3_double_t
+dk3md_add_ok(dk3_double_t a, dk3_double_t b, int *ec);
+
+/** Substraction of double or long double.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable.
+ @return Operation result.
+*/
+dk3_double_t
+dk3md_sub_ok(dk3_double_t a, dk3_double_t b, int *ec);
+
+/** Multiplication of double or long double.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable.
+ @return Operation result.
+*/
+dk3_double_t
+dk3md_mul_ok(dk3_double_t a, dk3_double_t b, int *ec);
+
+/** Division of double or long double.
+ @param a Left operand.
+ @param b Right operand.
+ @param ec Pointer to error code variable.
+ @return Operation result.
+*/
+dk3_double_t
+dk3md_div_ok(dk3_double_t a, dk3_double_t b, int *ec);
+
+/** Obtain format string for conversions.
+ @param c Key character 'e', 'f', or 'g'.
+ @return Conversion format string.
+*/
+dkChar const *
+dk3md_format(char c);
+
+/** Obtain format string for conversions.
+ @param c Key character 'e', 'f', or 'g'.
+ @return Conversion format string.
+*/
+char const *
+dk3md_c8_format(char c);
+
+/** Check availability of long double.
+ @return 1 for long double available, 0 for fallback to double.
+*/
+int
+dk3md_have_long_double(void);
+
+/** Sinus.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_sin(dk3_double_t x);
+
+/** Cosinus.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_cos(dk3_double_t x);
+
+/** Tangens.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_tan(dk3_double_t x);
+
+/** Arcus sinus.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_asin(dk3_double_t x);
+
+/** Arcus cosinus.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_acos(dk3_double_t x);
+
+/** Arcus tangens.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_atan(dk3_double_t x);
+
+/** Arcus tangens for two arguments.
+ @param y Y position.
+ @param x X position.
+ @return Result.
+*/
+dk3_double_t
+dk3md_atan2(dk3_double_t y, dk3_double_t x);
+
+/** Absolute value.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_fabs(dk3_double_t x);
+
+/** Round downwards.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_floor(dk3_double_t x);
+
+/** Round upwards.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_ceil(dk3_double_t x);
+
+/** Round to next integer.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_rint(dk3_double_t x);
+
+/** Exponential function.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_exp(dk3_double_t x);
+
+/** Logarithm.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_log(dk3_double_t x);
+
+/** Square root.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_sqrt(dk3_double_t x);
+
+/** Sinus hyperbolicus.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_sinh(dk3_double_t x);
+
+/** Cosinus hyperbolicus.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_cosh(dk3_double_t x);
+
+/** Tangens hyperbolicus.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_tanh(dk3_double_t x);
+
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+#if (DK3_HAVE_ASINHL) && (DK3_HAVE_ACOSHL) && (DK3_HAVE_ATANHL)
+
+/** Arcus sinus hyperbolicus.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_asinh(dk3_double_t x);
+
+/** Arcus cosinus hyperbolicus.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_acosh(dk3_double_t x);
+
+/** Arcus tangens hyperbolicus.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_atanh(dk3_double_t x);
+
+#else
+#if (DK3_HAVE_ASINH) && (DK3_HAVE_ACOSH) && (DK3_HAVE_ATANH)
+
+/** Arcus sinus hyperbolicus.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_asinh(dk3_double_t x);
+
+/** Arcus cosinus hyperbolicus.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_acosh(dk3_double_t x);
+
+/** Arcus tangens hyperbolicus.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_atanh(dk3_double_t x);
+
+#else
+#if (DK3_NEED_ASINH) || (DK3_NEED_ACOSH) || (DK3_NEED_ATANH)
+#error "No asinh/acosh/atanh function in math library!"
+#endif
+#endif
+#endif
+#else
+#if (DK3_HAVE_ASINH) && (DK3_HAVE_ACOSH) && (DK3_HAVE_ATANH)
+
+/** Arcus sinus hyperbolicus.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_asinh(dk3_double_t x);
+
+/** Arcus cosinus hyperbolicus.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_acosh(dk3_double_t x);
+
+/** Arcus tangens hyperbolicus.
+ @param x Argument.
+ @return Result.
+*/
+dk3_double_t
+dk3md_atanh(dk3_double_t x);
+#else
+
+#if (DK3_NEED_ASINH) || (DK3_NEED_ACOSH) || (DK3_NEED_ATANH)
+#error "No asinh/acosh/atanh function in math library!"
+#endif
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk3mem.c b/support/dktools/dk3mem.c
new file mode 100644
index 0000000000..43681a09b1
--- /dev/null
+++ b/support/dktools/dk3mem.c
@@ -0,0 +1,348 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3mem.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3mem.c The dk3mem module.
+*/
+
+
+#line 166 "dk3mem.ctr"
+
+#include "dk3all.h"
+
+
+
+
+
+
+#line 172 "dk3mem.ctr"
+
+
+
+void
+dk3mem_res(void *mp, size_t sz)
+/* {{{ */
+{
+ if((NULL != mp) && (0 != sz)) {
+#if DK3_HAVE_MEMSET
+ memset(mp, (int)'\0', sz);
+#else
+#if DK3_HAVE_BZERO
+ bzero(mp, sz);
+#else
+ register char *ptr;
+ register size_t i;
+ ptr = (char *)mp; i = sz;
+ while(i--) { *(ptr++) = '\0'; }
+#endif
+#endif
+ }
+}
+/* }}} */
+
+
+
+void
+dk3mem_cpy(void *dp, void const *sp, size_t sz)
+/* {{{ */
+{
+ if((NULL != dp) && (NULL != sp) && (0 != sz)) {
+#if DK3_HAVE_MEMCPY
+ memcpy(dp, sp, sz);
+#else
+#if DK3_HAVE_BCOPY
+ bcopy(sp, dp, sz);
+#else
+ register char *mydp;
+ register char const *mysp;
+ register size_t i;
+ mydp = (char *)dp;
+ mysp = (char const *)sp;
+ i = sz;
+ while(i--) { *(mydp++) = *(mysp++); }
+#endif
+#endif
+ }
+}
+/* }}} */
+
+
+
+int
+dk3mem_cmp(void const *s1, void const *s2, size_t sz)
+/* {{{ */
+{
+ int back = 0;
+ if(NULL != s1) {
+ if(NULL != s2) {
+#if DK3_HAVE_MEMCMP
+ back = memcmp(s1, s2, sz);
+#else
+#if DK3_HAVE_BCMP
+ back = bcmp(s1, s2, sz);
+#else
+ register unsigned char const *mys1;
+ register unsigned char const *mys2;
+ register size_t i;
+ register int myback = 0;
+ mys1 = (unsigned char const *)s1;
+ mys2 = (unsigned char const *)s2;
+ for(i = 0; ((i < sz) && (0 == myback)); i++) {
+ if(*mys1 > *mys2) {
+ myback = 1;
+ } else {
+ if(*mys1 < *mys2) {
+ myback = -1;
+ } else {
+ mys1++; mys2++;
+ }
+ }
+ }
+ back = myback;
+#endif
+#endif
+ } else { back = 1; }
+ } else {
+ if(s2) { back = -1; }
+ }
+ return back;
+}
+/* }}} */
+
+
+
+void *
+dk3mem_malloc_app(size_t sz, dk3_app_t *app)
+/* {{{ */
+{
+ void *back = NULL;
+ char c8buffer[64]; /* Buffer to show number of bytes. */
+ dkChar dkbuffer[64]; /* Buffer to show number of bytes. */
+
+
+#line 275 "dk3mem.ctr"
+ if(0 != sz) {
+#if DK3_ON_WINDOWS && (_MSC_VER > 1100)
+
+
+#line 278 "dk3mem.ctr"
+ back = (void *)LocalAlloc((LMEM_FIXED | LMEM_ZEROINIT), sz);
+#else
+#if DK3_HAVE_MALLOC && DK3_HAVE_FREE
+
+
+#line 282 "dk3mem.ctr"
+ back = malloc(sz);
+
+
+#line 284 "dk3mem.ctr"
+#else
+#error "The malloc and free functions are not available here!"
+#endif
+#endif
+ if(NULL != back) {
+
+#line 289 "dk3mem.ctr"
+ dk3mem_res(back, sz);
+ } else {
+
+#line 291 "dk3mem.ctr"
+ if(NULL != app) {
+
+#line 292 "dk3mem.ctr"
+ /* ERROR: Failed to allocate n bytes! */
+ if(0 != dk3ma_um_to_c8_string(c8buffer,sizeof(c8buffer),(dk3_um_t)sz)) {
+ (void)dk3str_cnv_c8_to_str_app(
+ dkbuffer, DK3_SIZEOF(dkbuffer,dkChar), c8buffer, NULL
+ );
+ dk3app_log_i3(app, DK3_LL_ERROR, 12, 13, dkbuffer);
+ } else {
+ dk3app_log_i1(app, DK3_LL_ERROR, 14);
+ }
+ }
+ }
+ }
+
+#line 304 "dk3mem.ctr"
+ return back;
+}
+/* }}} */
+
+
+void *
+dk3mem_malloc(size_t sz)
+/* {{{ */
+{
+ void *back;
+ back = dk3mem_malloc_app(sz, NULL);
+ return back;
+}
+/* }}} */
+
+
+
+size_t
+dk3mem_mul_size_t(size_t sz, size_t ne, int *ec)
+/* {{{ */
+{
+ size_t back = 0;
+ if (0 < sz) {
+ if ((DK3_SIZE_T_MAX / sz) < ne) {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ } else {
+ back = (sz * ne);
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OUT_OF_RANGE; }
+ }
+ return back;
+}
+/* }}} */
+
+
+
+size_t
+dk3mem_add_size_t(size_t a, size_t b, int *ec)
+{
+ size_t back = 0;
+ if((DK3_SIZE_T_MAX - a) >= b) { back = a + b; }
+ else { if(NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; } }
+ return back;
+}
+
+
+void *
+dk3mem_alloc_app(size_t sz, size_t ne, dk3_app_t *app)
+/* {{{ */
+{
+ void *back = NULL;
+ size_t as = 0; /* Allocation size. */
+ char c8b1[64]; /* Buffer for element size. */
+ char c8b2[64]; /* Buffer for number of elements. */
+ dkChar dkb1[64]; /* Buffer for element size. */
+ dkChar dkb2[64]; /* Buffer for number of elements. */
+ int ok = 0; /* Flag: Success. */
+
+
+#line 363 "dk3mem.ctr"
+ if((0 != sz) && (0 != ne)) {
+ as = dk3mem_mul_size_t(sz, ne, NULL);
+ if(0 != as) {
+ back = dk3mem_malloc_app(as, app);
+ } else {
+ if(NULL != app) {
+ /* ERROR: Numeric overflow! */
+ ok = 0;
+ dkb1[0] = dkb2[0] = dkT('\0');
+ if(0 != dk3ma_um_to_c8_string(c8b1, sizeof(c8b1),(dk3_um_t)sz)) {
+ if(0 != dk3ma_um_to_c8_string(c8b2, sizeof(c8b2),(dk3_um_t)ne)) {
+ (void)dk3str_cnv_c8_to_str_app(
+ dkb1, DK3_SIZEOF(dkb1,dkChar), c8b1, NULL
+ );
+ (void)dk3str_cnv_c8_to_str_app(
+ dkb2, DK3_SIZEOF(dkb2,dkChar), c8b2, NULL
+ );
+ ok = 1;
+ }
+ }
+ if(0 != ok) {
+ dk3app_log_i5(app, DK3_LL_ERROR, 16, 17, 18, dkb1, dkb2);
+ } else {
+ dk3app_log_i1(app, DK3_LL_ERROR, 15);
+ }
+ }
+ }
+ }
+
+#line 391 "dk3mem.ctr"
+ return back;
+}
+/* }}} */
+
+
+
+void *
+dk3mem_alloc(size_t sz, size_t ne)
+/* {{{ */
+{
+ void *back;
+ back = dk3mem_alloc_app(sz, ne, NULL);
+ return back;
+}
+/* }}} */
+
+
+
+void
+dk3mem_free (void *po)
+/* {{{ */
+{
+ if(NULL != po) {
+#if DK3_ON_WINDOWS && (_MSC_VER > 1100)
+ LocalFree((HLOCAL)po);
+#else
+#if DK3_HAVE_MALLOC && DK3_HAVE_FREE
+ free(po);
+#endif
+#endif
+ }
+}
+/* }}} */
+
+int
+dk3mem_reset_secure(void *mp, size_t sz)
+{
+ char *ptr;
+ int back = 0;
+ if ((NULL != mp) && (0 < sz)) {
+#if DK3_ON_WINDOWS
+ SecureZeroMemory(mp, sz);
+ back = 1;
+#else
+ dk3mem_res(mp, sz);
+ back = 1;
+ ptr = (char *)mp;
+ while (sz--) {
+ if ('\0' != *(ptr++)) {
+ back = 0;
+ }
+ }
+#endif
+ }
+ return back;
+}
+
+
+/* vim: set ai sw=2 filetype=c foldmethod=marker foldopen=all : */
+
diff --git a/support/dktools/dk3mem.ctr b/support/dktools/dk3mem.ctr
new file mode 100644
index 0000000000..87037412af
--- /dev/null
+++ b/support/dktools/dk3mem.ctr
@@ -0,0 +1,450 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% header
+
+#include "dk3conf.h"
+#include "dk3types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** Reset memory range.
+ * @param mp Memory pointer.
+ * @param sz Size of memory range in bytes.
+ */
+void
+dk3mem_res(void *mp, size_t sz) ;
+
+/** Reset memory range.
+ * @param mp Memory pointer.
+ * @param sz Size of memory range in bytes.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3mem_reset_secure(void *mp, size_t sz) ;
+
+/** Copy memory range. The buffers must not overlap!
+ * @param dp Destination buffer pointer.
+ * @param sp Source pointer.
+ * @param sz Number of bytes to copy.
+ */
+void
+dk3mem_cpy(void *dp, void const *sp, size_t sz);
+
+/** Compare two memory ranges byte by byte.
+ * @param s1 Left pointer.
+ * @param s2 Right pointer.
+ * @param sz Maximum number of bytes to use in comparison.
+ * @return 1 for s1>s2, 0 for s1==s2, -1 for s1<s2.
+ */
+int
+dk3mem_cmp(void const *s1, void const *s2, size_t sz);
+
+/** Allocate memory dynamically.
+ * @param sz Number of bytes to allocate.
+ * @return Pointer to new memory on success, NULL on error.
+ */
+void *
+dk3mem_malloc(size_t sz);
+
+/** Allocate memory dynamically.
+ * @param sz Number of bytes to allocate.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Pointer to new memory on success, NULL on error.
+ */
+void *
+dk3mem_malloc_app(size_t sz, dk3_app_t *app);
+
+/** Allocate memory dynamically.
+ * @param sz Element size.
+ * @param ne Number of elements.
+ * @return Pointer to new memory on success, NULL on error.
+ */
+void *
+dk3mem_alloc(size_t sz, size_t ne);
+
+/** Allocate memory dynamically.
+ * @param sz Element size.
+ * @param ne Number of elements.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Pointer to new memory on success, NULL on error.
+ */
+void *
+dk3mem_alloc_app(size_t sz, size_t ne, dk3_app_t *app);
+
+/** Release dynamically allocated memory.
+ * @param po Pointer to memory.
+ */
+void
+dk3mem_free(void *po);
+
+/** Calculate number of bytes (product element size, number of elements).
+ @param sz Element size.
+ @param ne Number of elements.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_MATH_OUT_OF_RANGE if the element size sz is 0,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return Product on success, 0 on error (mathematical overflow,
+ one of the sizes 0).
+*/
+size_t
+dk3mem_mul_size_t(size_t sz, size_t ne, int *ec);
+
+/** Summary of two sizes.
+ @param a One size.
+ @param b Other size.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_MATH_OVERFLOW if a numeric overflow occurs.
+ @return Positive number on success, 0 on error (mathematical overflow).
+*/
+size_t
+dk3mem_add_size_t(size_t a, size_t b, int *ec);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** Get number of elements in an array.
+ * @param v Variable.
+ * @param t Type.
+ * @return Number of elememnts of type \a t in \a v.
+ */
+#define DK3_SIZEOF(v,t) (sizeof(v)/sizeof(t))
+
+/** Calculate byte alignment for a given size, round upwards if necessary.
+ @param a Original size.
+ @param b Alignment size.
+ @return a, corrected upwards if necessary.
+*/
+#define DK3_MEM_ALIGN(a,b) \
+((0 == b) ? (a) : ((0 == (a) % (b)) ? (a) : ((b) * (((a) / (b)) + 1))))
+
+/** Allocate memory dynamically.
+ * @param t Type.
+ * @param s Number of elements.
+ * @return Type-casted pointer to new memory or NULL.
+ */
+#define dk3_new(t,s) ((t *)dk3mem_alloc_app(sizeof(t),(size_t)(s),NULL))
+
+/** Allocate memory dynamically.
+ * @param t Type.
+ * @param s Number of elements.
+ * @param a Application structure for diagnostics, may be NULL.
+ * @return Type-casted pointer to new memory or NULL.
+ */
+#define dk3_new_app(t,s,a) ((t *)dk3mem_alloc_app(sizeof(t),(size_t)(s),(a)))
+
+/** Release memory.
+ * @param po Pointer to memory to release.
+ */
+#define dk3_delete(po) \
+do { if(po) { dk3mem_free((void *)(po)); } } while(0)
+
+/** Release memory.
+ * @param po Pointer to memory to release.
+ */
+#define dk3_release(po) \
+do { if(po) { dk3mem_free((void *)(po)); } po = NULL; } while(0)
+
+/** Release C++ object.
+ * @param po Object pointer.
+ */
+#define dk3_cpp_release(po) \
+do { if(po) { delete(po); } po = NULL; } while(0)
+
+
+
+%% module
+
+#include "dk3all.h"
+
+
+
+$(trace-include)
+
+
+
+void
+dk3mem_res(void *mp, size_t sz)
+/* {{{ */
+{
+ if((NULL != mp) && (0 != sz)) {
+#if DK3_HAVE_MEMSET
+ memset(mp, (int)'\0', sz);
+#else
+#if DK3_HAVE_BZERO
+ bzero(mp, sz);
+#else
+ register char *ptr;
+ register size_t i;
+ ptr = (char *)mp; i = sz;
+ while(i--) { *(ptr++) = '\0'; }
+#endif
+#endif
+ }
+}
+/* }}} */
+
+
+
+void
+dk3mem_cpy(void *dp, void const *sp, size_t sz)
+/* {{{ */
+{
+ if((NULL != dp) && (NULL != sp) && (0 != sz)) {
+#if DK3_HAVE_MEMCPY
+ memcpy(dp, sp, sz);
+#else
+#if DK3_HAVE_BCOPY
+ bcopy(sp, dp, sz);
+#else
+ register char *mydp;
+ register char const *mysp;
+ register size_t i;
+ mydp = (char *)dp;
+ mysp = (char const *)sp;
+ i = sz;
+ while(i--) { *(mydp++) = *(mysp++); }
+#endif
+#endif
+ }
+}
+/* }}} */
+
+
+
+int
+dk3mem_cmp(void const *s1, void const *s2, size_t sz)
+/* {{{ */
+{
+ int back = 0;
+ if(NULL != s1) {
+ if(NULL != s2) {
+#if DK3_HAVE_MEMCMP
+ back = memcmp(s1, s2, sz);
+#else
+#if DK3_HAVE_BCMP
+ back = bcmp(s1, s2, sz);
+#else
+ register unsigned char const *mys1;
+ register unsigned char const *mys2;
+ register size_t i;
+ register int myback = 0;
+ mys1 = (unsigned char const *)s1;
+ mys2 = (unsigned char const *)s2;
+ for(i = 0; ((i < sz) && (0 == myback)); i++) {
+ if(*mys1 > *mys2) {
+ myback = 1;
+ } else {
+ if(*mys1 < *mys2) {
+ myback = -1;
+ } else {
+ mys1++; mys2++;
+ }
+ }
+ }
+ back = myback;
+#endif
+#endif
+ } else { back = 1; }
+ } else {
+ if(s2) { back = -1; }
+ }
+ return back;
+}
+/* }}} */
+
+
+
+void *
+dk3mem_malloc_app(size_t sz, dk3_app_t *app)
+/* {{{ */
+{
+ void *back = NULL;
+ char c8buffer[64]; /* Buffer to show number of bytes. */
+ dkChar dkbuffer[64]; /* Buffer to show number of bytes. */
+ $? "+ dk3mem_malloc %u", (unsigned)sz
+ if(0 != sz) {
+#if DK3_ON_WINDOWS && (_MSC_VER > 1100)
+ $? ". use LocalAlloc"
+ back = (void *)LocalAlloc((LMEM_FIXED | LMEM_ZEROINIT), sz);
+#else
+#if DK3_HAVE_MALLOC && DK3_HAVE_FREE
+ $? ". use malloc %u", (unsigned)sz
+ back = malloc(sz);
+ $? ". malloc used %!8s", TR_8PTR(back)
+#else
+#error "The malloc and free functions are not available here!"
+#endif
+#endif
+ if(NULL != back) { $? ". attempt to reset"
+ dk3mem_res(back, sz);
+ } else { $? "! allocation failed"
+ if(NULL != app) { $? ". writing error message"
+ /* ERROR: Failed to allocate n bytes! */
+ if(0 != dk3ma_um_to_c8_string(c8buffer,sizeof(c8buffer),(dk3_um_t)sz)) {
+ (void)dk3str_cnv_c8_to_str_app(
+ dkbuffer, DK3_SIZEOF(dkbuffer,dkChar), c8buffer, NULL
+ );
+ dk3app_log_i3(app, DK3_LL_ERROR, 12, 13, dkbuffer);
+ } else {
+ dk3app_log_i1(app, DK3_LL_ERROR, 14);
+ }
+ }
+ }
+ } $? "- dk3mem_malloc %!8s", TR_8PTR(back)
+ return back;
+}
+/* }}} */
+
+
+void *
+dk3mem_malloc(size_t sz)
+/* {{{ */
+{
+ void *back;
+ back = dk3mem_malloc_app(sz, NULL);
+ return back;
+}
+/* }}} */
+
+
+
+size_t
+dk3mem_mul_size_t(size_t sz, size_t ne, int *ec)
+/* {{{ */
+{
+ size_t back = 0;
+ if (0 < sz) {
+ if ((DK3_SIZE_T_MAX / sz) < ne) {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ } else {
+ back = (sz * ne);
+ }
+ } else {
+ if (NULL != ec) { *ec = DK3_ERROR_MATH_OUT_OF_RANGE; }
+ }
+ return back;
+}
+/* }}} */
+
+
+
+size_t
+dk3mem_add_size_t(size_t a, size_t b, int *ec)
+{
+ size_t back = 0;
+ if((DK3_SIZE_T_MAX - a) >= b) { back = a + b; }
+ else { if(NULL != ec) { *ec = DK3_ERROR_MATH_OVERFLOW; } }
+ return back;
+}
+
+
+void *
+dk3mem_alloc_app(size_t sz, size_t ne, dk3_app_t *app)
+/* {{{ */
+{
+ void *back = NULL;
+ size_t as = 0; /* Allocation size. */
+ char c8b1[64]; /* Buffer for element size. */
+ char c8b2[64]; /* Buffer for number of elements. */
+ dkChar dkb1[64]; /* Buffer for element size. */
+ dkChar dkb2[64]; /* Buffer for number of elements. */
+ int ok = 0; /* Flag: Success. */
+ $? "+ dk3mem_alloc %u %u", (unsigned)sz, (unsigned)ne
+ if((0 != sz) && (0 != ne)) {
+ as = dk3mem_mul_size_t(sz, ne, NULL);
+ if(0 != as) {
+ back = dk3mem_malloc_app(as, app);
+ } else {
+ if(NULL != app) {
+ /* ERROR: Numeric overflow! */
+ ok = 0;
+ dkb1[0] = dkb2[0] = dkT('\0');
+ if(0 != dk3ma_um_to_c8_string(c8b1, sizeof(c8b1),(dk3_um_t)sz)) {
+ if(0 != dk3ma_um_to_c8_string(c8b2, sizeof(c8b2),(dk3_um_t)ne)) {
+ (void)dk3str_cnv_c8_to_str_app(
+ dkb1, DK3_SIZEOF(dkb1,dkChar), c8b1, NULL
+ );
+ (void)dk3str_cnv_c8_to_str_app(
+ dkb2, DK3_SIZEOF(dkb2,dkChar), c8b2, NULL
+ );
+ ok = 1;
+ }
+ }
+ if(0 != ok) {
+ dk3app_log_i5(app, DK3_LL_ERROR, 16, 17, 18, dkb1, dkb2);
+ } else {
+ dk3app_log_i1(app, DK3_LL_ERROR, 15);
+ }
+ }
+ }
+ } $? "- dk3mem_alloc %!8s", TR_8PTR(back)
+ return back;
+}
+/* }}} */
+
+
+
+void *
+dk3mem_alloc(size_t sz, size_t ne)
+/* {{{ */
+{
+ void *back;
+ back = dk3mem_alloc_app(sz, ne, NULL);
+ return back;
+}
+/* }}} */
+
+
+
+void
+dk3mem_free (void *po)
+/* {{{ */
+{
+ if(NULL != po) {
+#if DK3_ON_WINDOWS && (_MSC_VER > 1100)
+ LocalFree((HLOCAL)po);
+#else
+#if DK3_HAVE_MALLOC && DK3_HAVE_FREE
+ free(po);
+#endif
+#endif
+ }
+}
+/* }}} */
+
+int
+dk3mem_reset_secure(void *mp, size_t sz)
+{
+ char *ptr;
+ int back = 0;
+ if ((NULL != mp) && (0 < sz)) {
+#if DK3_ON_WINDOWS
+ SecureZeroMemory(mp, sz);
+ back = 1;
+#else
+ dk3mem_res(mp, sz);
+ back = 1;
+ ptr = (char *)mp;
+ while (sz--) {
+ if ('\0' != *(ptr++)) {
+ back = 0;
+ }
+ }
+#endif
+ }
+ return back;
+}
+
+
+/* vim: set ai sw=2 filetype=c foldmethod=marker foldopen=all : */
+
diff --git a/support/dktools/dk3mem.h b/support/dktools/dk3mem.h
new file mode 100644
index 0000000000..aa6b231ecb
--- /dev/null
+++ b/support/dktools/dk3mem.h
@@ -0,0 +1,201 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3mem.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3mem.h Header file for the dk3mem module.
+*/
+
+#ifndef DK3MEM_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3MEM_H_INCLUDED 1
+
+
+#line 10 "dk3mem.ctr"
+
+#include "dk3conf.h"
+#include "dk3types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** Reset memory range.
+ * @param mp Memory pointer.
+ * @param sz Size of memory range in bytes.
+ */
+void
+dk3mem_res(void *mp, size_t sz) ;
+
+/** Reset memory range.
+ * @param mp Memory pointer.
+ * @param sz Size of memory range in bytes.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3mem_reset_secure(void *mp, size_t sz) ;
+
+/** Copy memory range. The buffers must not overlap!
+ * @param dp Destination buffer pointer.
+ * @param sp Source pointer.
+ * @param sz Number of bytes to copy.
+ */
+void
+dk3mem_cpy(void *dp, void const *sp, size_t sz);
+
+/** Compare two memory ranges byte by byte.
+ * @param s1 Left pointer.
+ * @param s2 Right pointer.
+ * @param sz Maximum number of bytes to use in comparison.
+ * @return 1 for s1>s2, 0 for s1==s2, -1 for s1<s2.
+ */
+int
+dk3mem_cmp(void const *s1, void const *s2, size_t sz);
+
+/** Allocate memory dynamically.
+ * @param sz Number of bytes to allocate.
+ * @return Pointer to new memory on success, NULL on error.
+ */
+void *
+dk3mem_malloc(size_t sz);
+
+/** Allocate memory dynamically.
+ * @param sz Number of bytes to allocate.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Pointer to new memory on success, NULL on error.
+ */
+void *
+dk3mem_malloc_app(size_t sz, dk3_app_t *app);
+
+/** Allocate memory dynamically.
+ * @param sz Element size.
+ * @param ne Number of elements.
+ * @return Pointer to new memory on success, NULL on error.
+ */
+void *
+dk3mem_alloc(size_t sz, size_t ne);
+
+/** Allocate memory dynamically.
+ * @param sz Element size.
+ * @param ne Number of elements.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Pointer to new memory on success, NULL on error.
+ */
+void *
+dk3mem_alloc_app(size_t sz, size_t ne, dk3_app_t *app);
+
+/** Release dynamically allocated memory.
+ * @param po Pointer to memory.
+ */
+void
+dk3mem_free(void *po);
+
+/** Calculate number of bytes (product element size, number of elements).
+ @param sz Element size.
+ @param ne Number of elements.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_MATH_OUT_OF_RANGE if the element size sz is 0,
+ DK3_ERROR_MATH_OVERFLOW on numeric overflow.
+ @return Product on success, 0 on error (mathematical overflow,
+ one of the sizes 0).
+*/
+size_t
+dk3mem_mul_size_t(size_t sz, size_t ne, int *ec);
+
+/** Summary of two sizes.
+ @param a One size.
+ @param b Other size.
+ @param ec Pointer to error code variable, may be NULL.
+ Set to DK3_ERROR_MATH_OVERFLOW if a numeric overflow occurs.
+ @return Positive number on success, 0 on error (mathematical overflow).
+*/
+size_t
+dk3mem_add_size_t(size_t a, size_t b, int *ec);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** Get number of elements in an array.
+ * @param v Variable.
+ * @param t Type.
+ * @return Number of elememnts of type \a t in \a v.
+ */
+#define DK3_SIZEOF(v,t) (sizeof(v)/sizeof(t))
+
+/** Calculate byte alignment for a given size, round upwards if necessary.
+ @param a Original size.
+ @param b Alignment size.
+ @return a, corrected upwards if necessary.
+*/
+#define DK3_MEM_ALIGN(a,b) \
+((0 == b) ? (a) : ((0 == (a) % (b)) ? (a) : ((b) * (((a) / (b)) + 1))))
+
+/** Allocate memory dynamically.
+ * @param t Type.
+ * @param s Number of elements.
+ * @return Type-casted pointer to new memory or NULL.
+ */
+#define dk3_new(t,s) ((t *)dk3mem_alloc_app(sizeof(t),(size_t)(s),NULL))
+
+/** Allocate memory dynamically.
+ * @param t Type.
+ * @param s Number of elements.
+ * @param a Application structure for diagnostics, may be NULL.
+ * @return Type-casted pointer to new memory or NULL.
+ */
+#define dk3_new_app(t,s,a) ((t *)dk3mem_alloc_app(sizeof(t),(size_t)(s),(a)))
+
+/** Release memory.
+ * @param po Pointer to memory to release.
+ */
+#define dk3_delete(po) \
+do { if(po) { dk3mem_free((void *)(po)); } } while(0)
+
+/** Release memory.
+ * @param po Pointer to memory to release.
+ */
+#define dk3_release(po) \
+do { if(po) { dk3mem_free((void *)(po)); } po = NULL; } while(0)
+
+/** Release C++ object.
+ * @param po Object pointer.
+ */
+#define dk3_cpp_release(po) \
+do { if(po) { delete(po); } po = NULL; } while(0)
+
+
+
+
+#endif
diff --git a/support/dktools/dk3nettp.h b/support/dktools/dk3nettp.h
new file mode 100644
index 0000000000..90867028fd
--- /dev/null
+++ b/support/dktools/dk3nettp.h
@@ -0,0 +1,103 @@
+
+#ifndef DK3NETTP_H_INCLUDED
+#define DK3NETTP_H_INCLUDED 1
+
+
+#include <dk3all.h>
+
+
+
+#if DK3_ON_WINDOWS || DK3_HAVE_SOCKET
+
+
+
+/** IPv4 address.
+*/
+typedef struct {
+
+ /** IP address in net representation.
+ */
+ struct sockaddr_in soin;
+
+ /** Minimum port number to use for local ip address.
+ */
+ unsigned short portmin;
+
+ /** Maximum port number. When binding a local address we can specify
+ a port range portno-portmax.
+ */
+ unsigned short portmax;
+
+} dk3_ip_addr_t;
+
+
+
+
+/** Socket address.
+*/
+typedef struct sockaddr DK3_SOA;
+
+/** Internet socket address.
+*/
+typedef struct sockaddr_in DK3_SOAIN;
+
+/** Size of internet socket address.
+*/
+#define DK3_SZ_SOAIN sizeof(DK3_SOAIN)
+
+
+
+/** Network socket.
+*/
+typedef struct {
+
+ /** Local IP address.
+ */
+ dk3_ip_addr_t local;
+
+ /** Remote IP address wished.
+ This address is used when sending UDP packets.
+ */
+ dk3_ip_addr_t remote_wished;
+
+ /** Remote IP address found.
+ When receiving UDP packets, the sender address is stored here.
+ */
+ dk3_ip_addr_t remote_found;
+
+ /** Application structure for diagnostics and preferences.
+ */
+ dk3_app_t *app;
+
+#if DK3_ON_WINDOWS
+ /** File descriptor, the real socket.
+ */
+ SOCKET fd;
+#else
+ /** File descriptor, the real socket.
+ */
+ int fd;
+#endif
+
+ /** Socket state, DK3_SOCKET_STATE_xxx.
+ */
+ int st;
+
+ /** Flag: End of input data found (0 bytes read).
+ */
+ int eod_found;
+
+ /** Flag: Write shutdown was sent to peer during close operation.
+ */
+ int shutdown_done;
+
+} dk3_socket_t;
+
+
+#endif
+/* if DK3_ON_WINDOWS || DK3_HAVE_SOCKET */
+
+
+#endif
+/* if DK3NETTP_H_INCLUDED */
+
diff --git a/support/dktools/dk3numco.h b/support/dktools/dk3numco.h
new file mode 100644
index 0000000000..b5b1e1c4ab
--- /dev/null
+++ b/support/dktools/dk3numco.h
@@ -0,0 +1,640 @@
+
+#ifndef DK3NUMCO_H_INCLUDED
+#define DK3NUMCO_H_INCLUDED 1
+
+/** @file dk3numco.h Numeric constants.
+Use system-defined mininum and maximum values if available.
+Define own contants using two s complement if no system definitions available.
+*/
+
+#include <dk3conf.h>
+#include <dk3types.h>
+
+#if DK3_HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#if DK3_HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+
+
+#if (!(DK3_HAVE_TWOS_COMPLEMENT))
+
+/* The definitions in this header file are only valid if the
+ twos complement representation is used for negative integer
+ values.
+ If the compiler aborts compilation showing the error below,
+ the configure script failed to verify the use of twos complement
+ for signed integers.
+ There are two possible reasons:
+ 1. Your C compiler and the libraries use another integer
+ representation. So you can not use this header file or
+ the dk3maxxx modules.
+ 2. Failure in the verification process. If you are sure your
+ compiler and libraries use twos complement, set
+ #define DK3_HAVE_TWOS_COMPLEMENT 1
+ in dk3conf.h and run
+ make clean
+ before attempting to build.
+*/
+#error "Module only available if twos complement is used for signed integers!"
+
+#endif
+
+
+
+/* short
+ -----
+*/
+
+#if defined(SHRT_MIN) && defined(SHRT_MAX)
+
+/** Maximum short value.
+*/
+#define DK3_S_MAX (SHRT_MAX)
+
+/** Minimum short value.
+*/
+#define DK3_S_MIN (SHRT_MIN)
+
+#else
+
+#if DK3_SIZEOF_SHORT > 2
+#if DK3_SIZEOF_SHORT > 4
+#if DK3_SIZEOF_SHORT > 8
+#error "No definitions for shorts larger than 8 bytes yet!"
+#else
+/** Maximum short value.
+*/
+#define DK3_S_MAX (9223372036854775807)
+/** Minimum short value.
+*/
+#define DK3_S_MIN (-DK3_S_MAX - 1)
+#endif
+#else
+/** Maximum short value.
+*/
+#define DK3_S_MAX (2147483647)
+/** Minimum short value.
+*/
+#define DK3_S_MIN (-DK3_S_MAX - 1)
+#endif
+#else
+/** Maximum short value.
+*/
+#define DK3_S_MAX (32767)
+/** Minimum short value.
+*/
+#define DK3_S_MIN (-DK3_S_MAX - 1)
+#endif
+#endif
+
+/* unsigned short
+ --------------
+*/
+#if defined(USHRT_MAX)
+
+/** Maximum unsigned short value.
+*/
+#define DK3_US_MAX (USHRT_MAX)
+
+#else
+#if DK3_SIZEOF_SHORT > 2
+#if DK3_SIZEOF_SHORT > 4
+#if DK3_SIZEOF_SHORT > 8
+#error "No definition for short values larger than 8 bytes yet!"
+#else
+/** Maximum unsigned short value.
+*/
+#define DK3_US_MAX (18446744073709551615U)
+#endif
+#else
+/** Maximum unsigned short value.
+*/
+#define DK3_US_MAX (4294967295U)
+#endif
+#else
+/** Maximum unsigned short value.
+*/
+#define DK3_US_MAX (65535U)
+#endif
+#endif
+
+/* int
+ ---
+*/
+#if defined(INT_MIN) && defined(INT_MAX)
+
+/** Maximum integer.
+*/
+#define DK3_I_MAX (INT_MAX)
+
+/** Minimum integer.
+*/
+#define DK3_I_MIN (INT_MIN)
+
+#else
+
+#if DK3_SIZEOF_INT > 2
+#if DK3_SIZEOF_INT > 4
+#if DK3_SIZEOF_INT > 8
+#error "No definition for int larger than 8 bytes yet!"
+#else
+/** Maximum integer.
+*/
+#define DK3_I_MAX (9223372036854775807)
+/** Minimum integer.
+*/
+#define DK3_I_MIN (-DK3_I_MAX - 1)
+#endif
+#else
+/** Maximum integer.
+*/
+#define DK3_I_MAX (2147483647)
+/** Minimum integer.
+*/
+#define DK3_I_MIN (-DK3_I_MAX - 1)
+#endif
+#else
+/** Maximum integer.
+*/
+#define DK3_I_MAX (32767)
+/** Minimum integer.
+*/
+#define DK3_I_MIN (-DK3_I_MAX - 1)
+#endif
+#endif
+
+
+
+/* unsigned int
+ ------------
+*/
+#if defined UINT_MAX
+
+/** Maximum unsigned integer.
+*/
+#define DK3_U_MAX (UINT_MAX)
+
+#else
+
+#if DK3_SIZEOF_INT > 2
+#if DK3_SIZEOF_INT > 4
+#if DK3_SIZEOF_INT > 8
+#error "No definitions for unsigned int larger than 8 bytes yet!"
+#else
+/** Maximum unsigned integer.
+*/
+#define DK3_U_MAX (18446744073709551615)
+#endif
+#else
+/** Maximum unsigned integer.
+*/
+#define DK3_U_MAX (4294967295)
+#endif
+#else
+/** Maximum unsigned integer.
+*/
+#define DK3_U_MAX (65535)
+#endif
+
+#endif
+
+
+
+
+/* long
+ ----
+*/
+#if defined(LONG_MIN) && defined(LONG_MAX)
+
+/** Maximum long integer.
+*/
+#define DK3_L_MAX (LONG_MAX)
+
+/** Minimum long integer.
+*/
+#define DK3_L_MIN (LONG_MIN)
+
+#else
+
+#if DK3_SIZEOF_LONG > 2
+#if DK3_SIZEOF_LONG > 4
+#if DK3_SIZEOF_LONG > 8
+#error "No definitions for long larger than 8 bytes yet!"
+#else
+/** Maximum long integer.
+*/
+#define DK3_L_MAX (9223372036854775807)
+
+/** Minimum long integer.
+*/
+#define DK3_L_MIN (-DK3_L_MAX - 1L)
+#endif
+#else
+/** Maximum long integer.
+*/
+#define DK3_L_MAX (2147483647)
+
+/** Minimum long integer.
+*/
+#define DK3_L_MIN (-DK3_L_MAX - 1L)
+#endif
+#else
+/** Maximum long integer.
+*/
+#define DK3_L_MAX (32767)
+/** Minimum long integer.
+*/
+#define DK3_L_MIN (-DK3_L_MAX - 1L)
+#endif
+#endif
+
+
+
+/* unsigned long
+ -------------
+*/
+#if defined(ULONG_MAX)
+
+/** Maximum unsigned long.
+*/
+#define DK3_UL_MAX (ULONG_MAX)
+
+#else
+#if DK3_SIZEOF_LONG > 2
+#if DK3_SIZEOF_LONG > 4
+#if DK3_SIZEOF_LONG > 8
+#error "No definitions for unsigned long larger than 8 bytes yet!"
+#else
+/** Maximum unsigned long.
+*/
+#define DK3_UL_MAX (18446744073709551615UL)
+#endif
+#else
+/** Maximum unsigned long.
+*/
+#define DK3_UL_MAX (4294967295UL)
+#endif
+#else
+/** Maximum unsigned long.
+*/
+#define DK3_UL_MAX (65535UL)
+#endif
+#endif
+
+#if DK3_HAVE_LONG_LONG
+/* long long
+ ---------
+*/
+#if defined(LLONG_MAX) && defined(LLONG_MIN)
+
+/** Maximum long long.
+*/
+#define DK3_LL_MAX (LLONG_MAX)
+
+/** Minimum long long.
+*/
+#define DK3_LL_MIN (LLONG_MIN)
+
+#else
+#if DK3_SIZEOF_LONG_LONG > 2
+#if DK3_SIZEOF_LONG_LONG > 4
+#if DK3_SIZEOF_LONG_LONG > 8
+#error "No definitions for long long larger than 8 bytes yet!"
+#else
+/** Maximum long long.
+*/
+#define DK3_LL_MAX (9223372036854775807LL)
+/** Minimum long long.
+*/
+#define DK3_LL_MIN (-DK3_LL_MAX - 1LL)
+#endif
+#else
+/** Maximum long long.
+*/
+#define DK3_LL_MAX (2147483647LL)
+/** Minimum long long.
+*/
+#define DK3_LL_MIN (-DK3_LL_MAX - 1LL)
+#endif
+#else
+/** Maximum long long.
+*/
+#define DK3_LL_MAX (32767LL)
+/** Minimum long long.
+*/
+#define DK3_LL_MIN (-DK3_LL_MAX - 1LL)
+#endif
+#endif
+
+/* unsigned long long
+ ------------------
+*/
+#if defined(ULLONG_MAX)
+
+/** Maximum unsigned long long.
+*/
+#define DK3_ULL_MAX (ULLONG_MAX)
+
+#else
+#if DK3_SIZEOF_LONG_LONG > 2
+#if DK3_SIZEOF_LONG_LONG > 4
+#if DK3_SIZEOF_LONG_LONG > 8
+#error "No definitions for unsigned long long larger than 8 bytes yet!"
+#else
+/** Maximum unsigned long long.
+*/
+#define DK3_ULL_MAX (18446744073709551615ULL)
+#endif
+#else
+/** Maximum unsigned long long.
+*/
+#define DK3_ULL_MAX (4294967295ULL)
+#endif
+#else
+/** Maximum unsigned long long.
+*/
+#define DK3_ULL_MAX (65535ULL)
+#endif
+#endif
+
+#endif
+/* if DK3_HAVE_LONG_LONG */
+
+
+
+#if DK3_HAVE_INTMAX_T
+/* intmax_t
+ --------
+*/
+#if defined(INTMAX_MIN) && defined(INTMAX_MAX)
+
+/** Maximum intmax_t value.
+*/
+#define DK3_INTMAX_T_MAX (INTMAX_MAX)
+
+/** Minimum intmax_t value.
+*/
+#define DK3_INTMAX_T_MIN (INTMAX_MIN)
+
+#else
+#if DK3_SIZEOF_INTMAX_T > 2
+#if DK3_SIZEOF_INTMAX_T > 4
+#if DK3_SIZEOF_INTMAX_T > 8
+#error "No definitions for intmax_t larger than 8 bytes yet!"
+#else
+#if DK3_SIZEOF_INTMAX_T == DK3_SIZEOF_LONG
+/** Maximum intmax_t value.
+*/
+#define DK3_INTMAX_T_MAX (9223372036854775807L)
+/** Minimum intmax_t value.
+*/
+#define DK3_INTMAX_T_MIN (-DK3_INTMAX_T_MAX - 1L)
+#else
+/** Maximum intmax_t value.
+*/
+#define DK3_INTMAX_T_MAX (9223372036854775807LL)
+/** Minimum intmax_t value.
+*/
+#define DK3_INTMAX_T_MIN (-DK3_INTMAX_T_MAX - 1LL)
+#endif
+#endif
+#else
+/** Maximum intmax_t value.
+*/
+#define DK3_INTMAX_T_MAX (2147483647L)
+/** Minimum intmax_t value.
+*/
+#define DK3_INTMAX_T_MIN (-DK3_INTMAX_T_MAX - 1L)
+#endif
+#else
+/** Maximum intmax_t value.
+*/
+#define DK3_INTMAX_T_MAX (32767L)
+/** Minimum intmax_t value.
+*/
+#define DK3_INTMAX_T_MIN (-DK3_INTMAX_T_MAX - 1)
+#endif
+#endif
+
+
+/* uintmax_t
+ ---------
+*/
+#if defined(UINTMAX_MAX)
+
+/** Maximum uintmax_t value.
+*/
+#define DK3_UINTMAX_T_MAX (UINTMAX_MAX)
+
+#else
+#if DK3_SIZEOF_INTMAX_T > 2
+#if DK3_SIZEOF_INTMAX_T > 4
+#if DK3_SIZEOF_INTMAX_T > 8
+#error "No definitions for uintmax_t larger than 8 bytes yet!"
+#else
+#if DK3_SIZEOF_INTMAX_T == DK3_SIZEOF_LONG
+/** Maximum uintmax_t value.
+*/
+#define DK3_UINTMAX_T_MAX (18446744073709551615UL)
+#else
+/** Maximum uintmax_t value.
+*/
+#define DK3_UINTMAX_T_MAX (18446744073709551615ULL)
+#endif
+#endif
+#else
+/** Maximum uintmax_t value.
+*/
+#define DK3_UINTMAX_T_MAX (4294967295UL)
+#endif
+#else
+/** Maximum uintmax_t value.
+*/
+#define DK3_UINTMAX_T_MAX (65535U)
+#endif
+#endif
+
+#if DK3_HAVE_LONG_LONG
+/** intmax_t 0.
+*/
+#define DK3_INTMAX_T_0 ((intmax_t)0LL)
+/** intmax_t 1.
+*/
+#define DK3_INTMAX_T_1 ((intmax_t)1LL)
+#else
+/** intmax_t 0.
+*/
+#define DK3_INTMAX_T_0 ((intmax_t)0L)
+/** intmax_t 1.
+*/
+#define DK3_INTMAX_T_1 ((intmax_t)1L)
+#endif
+
+#if DK3_HAVE_LONG_LONG
+/** uintmax_t 0.
+*/
+#define DK3_UINTMAX_T_0 ((uintmax_t)0ULL)
+/** uintmax_t 1.
+*/
+#define DK3_UINTMAX_T_1 ((uintmax_t)1ULL)
+#else
+/** uintmax_t 0.
+*/
+#define DK3_UINTMAX_T_0 ((uintmax_t)0UL)
+/** uintmax_t 1.
+*/
+#define DK3_UINTMAX_T_1 ((uintmax_t)1UL)
+#endif
+
+#endif
+/* if DK3_HAVE_INTMAX_T */
+
+
+/* dk3_im_t
+ --------
+*/
+#if DK3_HAVE_INTMAX_T
+/** Minimum dk3_im_t value.
+*/
+#define DK3_IM_MIN (DK3_INTMAX_T_MIN)
+
+/** Maximum dk3_im_t value.
+*/
+#define DK3_IM_MAX (DK3_INTMAX_T_MAX)
+
+#else
+#if DK3_HAVE_LONG_LONG
+/** Minimum dk3_im_t value.
+*/
+#define DK3_IM_MIN (DK3_LL_MIN)
+
+/** Maximum dk3_im_t value.
+*/
+#define DK3_IM_MAX (DK3_LL_MAX)
+#else
+/** Minimum dk3_im_t value.
+*/
+#define DK3_IM_MIN (DK3_L_MIN)
+
+/** Maximum dk3_im_t value.
+*/
+#define DK3_IM_MAX (DK3_L_MAX)
+#endif
+#endif
+
+
+#if DK3_HAVE_LONG_LONG
+/** 0 in dk3_im_t.
+*/
+#define DK3_IM_0 ((dk3_im_t)0LL)
+/** 0 in dk3_um_t.
+*/
+#define DK3_UM_0 ((dk3_um_t)0ULL)
+/** 1 in dk3_um_t.
+*/
+#define DK3_UM_1 ((dk3_um_t)1ULL)
+#else
+/** 0 in dk3_im_t.
+*/
+#define DK3_IM_0 ((dk3_im_t)0L)
+/** 0 in dk3_um_t.
+*/
+#define DK3_UM_0 ((dk3_um_t)0UL)
+/** 1 in dk3_um_t.
+*/
+#define DK3_UM_1 ((dk3_um_t)1UL)
+#endif
+
+/* dk3_um_t
+ --------
+*/
+#if DK3_HAVE_INTMAX_T
+/** Maximum dk3_um_t value.
+*/
+#define DK3_UM_MAX (DK3_UINTMAX_T_MAX)
+#else
+#if DK3_HAVE_LONG_LONG
+/** Maximum dk3_um_t value.
+*/
+#define DK3_UM_MAX (DK3_ULL_MAX)
+#else
+/** Maximum dk3_um_t value.
+*/
+#define DK3_UM_MAX (DK3_UL_MAX)
+#endif
+#endif
+
+
+
+#if defined(SIZE_MAX)
+/** Maximum size_t value.
+*/
+#define DK3_SIZE_T_MAX (SIZE_MAX)
+#else
+#if DK3_SIZEOF_SIZE_T == DK3_SIZEOF_INT
+/** Maximum size_t value.
+*/
+#define DK3_SIZE_T_MAX (DK3_U_MAX)
+#else
+#if DK3_SIZEOF_SIZE_T == DK3_SIZEOF_LONG
+/** Maximum size_t value.
+*/
+#define DK3_SIZE_T_MAX (DK3_UL_MAX)
+#else
+#if (DK3_HAVE_LONG_LONG) && (DK3_SIZEOF_SIZE_T == DK3_SIZEOF_LONG_LONG)
+/** Maximum size_t value.
+*/
+#define DK3_SIZE_T_MAX (DK3_ULL_MAX)
+#else
+#if (DK3_HAVE_INTMAX_T) && (DK3_SIZE OF_SIZE_T == DK3_SIZEOF_INTMAX_T) && (defined(UINT_MAX))
+/** Maximum size_t value.
+*/
+#define DK3_SIZE_T_MAX (DK3_UM_MAX)
+#else
+#if DK3_SIZEOF_SIZE_T > 2
+#if DK3_SIZEOF_SIZE_T > 4
+#if DK3_SIZEOF_SIZE_T > 8
+#error "No definitions for size_t larger than 8 bytes yet!"
+#else
+/** Maximum size_t value.
+*/
+#define DK3_SIZE_T_MAX (18446744073709551615ULL)
+#endif
+#else
+/** Maximum size_t value.
+*/
+#define DK3_SIZE_T_MAX (4294967295UL)
+#endif
+#else
+/** Maximum size_t value.
+*/
+#define DK3_SIZE_T_MAX (65535U)
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+
+#if DK3_HAVE_INTMAX_T
+/** Size of the dk3_um_t type.
+*/
+#define DK3_SIZEOF_UM DK3_SIZEOF_INTMAX_T
+#else
+#if DK3_HAVE_LONG_LONG
+/** Size of the dk3_um_t type.
+*/
+#define DK3_SIZEOF_UM DK3_SIZEOF_LONG_LONG
+#else
+/** Size of the dk3_um_t type.
+*/
+#define DK3_SIZEOF_UM DK3_SIZEOF_LONG
+#endif
+#endif
+
+#endif
+/* ifndef DK3NUMCO_H_INCLUDED */
+
diff --git a/support/dktools/dk3of.c b/support/dktools/dk3of.c
new file mode 100644
index 0000000000..1e6171f4c5
--- /dev/null
+++ b/support/dktools/dk3of.c
@@ -0,0 +1,1376 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3of.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3of.c The dk3of module.
+*/
+
+
+#line 150 "dk3of.ctr"
+
+
+#include "dk3all.h"
+
+
+
+
+
+#line 157 "dk3of.ctr"
+
+
+
+/** Keywords used by this module.
+*/
+static char const * dk3of_kw[] = {
+/* 0 */ "\n",
+/* 1 */ "\r\n",
+/* 2 */ ">", /* ASCII/Hex finalizer. */
+/* 3 */ "~>", /* ASCII85 finalizer. */
+};
+
+
+
+/** Characters used for ASCII-Hex conversion.
+*/
+static char const dk3of_hex_chars[] = { "0123456789ABCDEF" };
+
+
+
+/** Masks for single bits in an unsigned char.
+*/
+static unsigned char const dk3of_bits_in_char[] = {
+ 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
+};
+
+
+
+/** Masks for single bits in an unsigned short.
+*/
+static unsigned short const dk3of_bits_in_short[] = {
+ 0x0001U, 0x0002U, 0x0004U, 0x0008U, 0x0010U, 0x0020U, 0x0040U, 0x0080U,
+ 0x0100U, 0x0200U, 0x0400U, 0x0800U, 0x1000U, 0x2000U, 0x4000U, 0x8000U
+};
+
+
+
+/** Constant factors used in ASCII85 encoding.
+*/
+static unsigned long const dk3of_a85_factors[] = {
+ (85UL * 85UL * 85UL * 85UL),
+ (85UL * 85UL * 85UL),
+ (85UL * 85UL),
+ 85UL
+};
+
+
+
+/** Destroy filter cell, release memory.
+ @param cp Filter cell to delete.
+*/
+static
+void
+dk3of_cell_close(dk3_of_cell_t *cp)
+{
+
+
+#line 213 "dk3of.ctr"
+ if(cp) {
+ switch(cp->type) {
+ case DK3_OF_CELL_TYPE_HEX: {
+ /* Nothing to do here, only static data structures. */
+ } break;
+ case DK3_OF_CELL_TYPE_A85: {
+ /* Nothing to do here, only static data structures. */
+ } break;
+ case DK3_OF_CELL_TYPE_RUN_LENGTH: {
+ dk3_delete((cp->data).psrl.bu);
+ } break;
+ case DK3_OF_CELL_TYPE_FLATE: {
+#if DK3_HAVE_ZLIB_H
+ dk3_release((cp->data).flate.zs);
+ dk3_release((cp->data).flate.ibu);
+ dk3_release((cp->data).flate.obu);
+ (cp->data).flate.iused = 0UL;
+ (cp->data).flate.ok = 0;
+#else
+#endif
+ } break;
+ default: {
+
+#line 235 "dk3of.ctr"
+ /* Nothing to do here as type is unknown. */
+ } break;
+ }
+ dk3_delete(cp);
+ }
+
+#line 240 "dk3of.ctr"
+}
+
+
+
+/** Create new filter cell for a filter.
+ @param of Output filter.
+ @param ct Cell type.
+ @return Pointer to the new filter cell on success, NULL on error.
+*/
+static
+dk3_of_cell_t *
+dk3of_cell_open(dk3_of_t *of, int ct)
+{
+ dk3_of_cell_t *back = NULL;
+
+
+#line 255 "dk3of.ctr"
+ if(of) {
+ back = dk3_new_app(dk3_of_cell_t,1,(of->app));
+ if(back) {
+ back->down = NULL;
+ back->up = NULL;
+ back->of = of;
+ back->type = ct;
+ switch(ct) {
+ case DK3_OF_CELL_TYPE_HEX: {
+ (back->data).ah.nl = 0;
+ } break;
+ case DK3_OF_CELL_TYPE_A85: {
+ (back->data).a85.val = 0UL;
+ (back->data).a85.nc = 0;
+ (back->data).a85.nl = 0;
+ } break;
+ case DK3_OF_CELL_TYPE_RUN_LENGTH: {
+ (back->data).psrl.bu = NULL;
+ (back->data).psrl.used = 0;
+ (back->data).psrl.same = 0;
+ (back->data).psrl.pc = 0x00;
+ (back->data).psrl.hc = 0x00;
+ (back->data).psrl.run = 0x00;
+ (back->data).psrl.bu = dk3_new_app(unsigned char,128,of->app);
+ if(!((back->data).psrl.bu)) {
+ dk3of_cell_close(back); back = NULL;
+ }
+ } break;
+ case DK3_OF_CELL_TYPE_FLATE: {
+#if DK3_HAVE_ZLIB_H
+ int ok = 0;
+ (back->data).flate.zs = NULL;
+ (back->data).flate.ibu = NULL;
+ (back->data).flate.obu = NULL;
+ (back->data).flate.iused = 0UL;
+ (back->data).flate.ok = 0;
+ (back->data).flate.zs = dk3_new_app(z_stream,1,of->app);
+ if((back->data).flate.zs) {
+ (back->data).flate.ibu =
+ dk3_new_app(unsigned char,DK3_OF_FLATE_IN_BUFFER_SIZE,of->app);
+ if((back->data).flate.ibu) {
+ /* (back->data).flate.ilgt = DK3_OF_FLATE_IN_BUFFER_SIZE; */
+ (back->data).flate.obu =
+ dk3_new_app(unsigned char,DK3_OF_FLATE_OUT_BUFFER_SIZE,of->app);
+ if((back->data).flate.obu) {
+ (back->data).flate.ok = 1;
+ ok = 1;
+ }
+ }
+ }
+ if(!(ok)) {
+ dk3of_cell_close(back); back = NULL;
+ }
+#else
+ back = 0;
+ /* ERROR: Not supported. */
+ if(of->app) {
+ dk3app_log_i1(of->app, DK3_LL_ERROR, 262);
+ }
+#endif
+ } break;
+ default: {
+
+#line 317 "dk3of.ctr"
+ dk3_delete(back);
+ back = NULL;
+ if(of->app) {
+ /* ERROR: Unknown type! */
+ dk3app_log_i1(of->app, DK3_LL_ERROR, 262);
+ }
+ } break;
+ }
+ }
+ }
+
+#line 327 "dk3of.ctr"
+ return back;
+}
+
+
+
+dk3_of_t *
+dk3of_open_app(dk3_stream_t *os, dk3_app_t *app)
+{
+ dk3_of_t *back = NULL;
+
+
+#line 337 "dk3of.ctr"
+ if(os) {
+ back = dk3_new_app(dk3_of_t,1,app);
+ if(back) {
+ back->app = app;
+ back->os = os;
+ back->bottom = NULL;
+ back->top = NULL;
+ back->nCells = 0;
+ back->nBits = 0;
+ back->bits = 0x00;
+ back->flags = DK3_OF_FLAG_FINALIZE;
+ }
+ }
+
+#line 350 "dk3of.ctr"
+ return back;
+}
+
+
+
+dk3_of_t *
+dk3of_open(dk3_stream_t *os)
+{
+ dk3_of_t *back = NULL;
+
+
+#line 360 "dk3of.ctr"
+ if(os) {
+ back = dk3of_open_app(os, NULL);
+ }
+
+#line 363 "dk3of.ctr"
+ return back;
+}
+
+
+
+void
+dk3of_close(dk3_of_t *of)
+{
+ dk3_of_cell_t *cc;
+ dk3_of_cell_t *nc;
+
+
+#line 374 "dk3of.ctr"
+ if(of) {
+ cc = of->top;
+ while(cc) {
+ nc = cc->down;
+ dk3of_cell_close(cc);
+ cc = nc;
+ }
+ }
+
+#line 382 "dk3of.ctr"
+}
+
+
+
+int
+dk3of_add_cell(dk3_of_t *of, int ct)
+{
+ dk3_of_cell_t *nc; /* New cell. */
+ dk3_of_cell_t *ot; /* Old top. */
+ int back = 0;
+
+
+#line 393 "dk3of.ctr"
+ if(of) {
+ switch(ct) {
+ case DK3_OF_CELL_TYPE_HEX:
+ case DK3_OF_CELL_TYPE_A85:
+ case DK3_OF_CELL_TYPE_RUN_LENGTH:
+ case DK3_OF_CELL_TYPE_FLATE:
+ {
+ nc = dk3of_cell_open(of, ct);
+ if(nc) {
+ back = 1;
+ nc->of = (void *)of;
+ ot = of->top;
+ if(ot) {
+
+#line 406 "dk3of.ctr"
+ ot->up = nc;
+ nc->down = ot;
+ } else {
+
+#line 409 "dk3of.ctr"
+ of->bottom = nc;
+ nc->down = NULL;
+ }
+ nc->up = NULL;
+ of->top = nc;
+ of->nCells += 1;
+ }
+ }
+ break;
+ default: {
+ /* ERROR: Illegal cell type! */
+ if(of->app) {
+ dk3app_log_i1(of->app, DK3_LL_ERROR, 263);
+ }
+ } break;
+ }
+ }
+
+#line 426 "dk3of.ctr"
+ return back;
+}
+
+
+
+int
+dk3of_start_chunk(dk3_of_t *of)
+{
+ dk3_of_cell_t *cellptr;
+ int back = 0;
+
+
+#line 437 "dk3of.ctr"
+ if(of) {
+ if(of->top) {
+ back = 1;
+ cellptr = of->top;
+ while(cellptr) {
+ switch(cellptr->type) {
+ case DK3_OF_CELL_TYPE_HEX: {
+ (cellptr->data).ah.nl = 0;
+ } break;
+ case DK3_OF_CELL_TYPE_A85: {
+ (cellptr->data).a85.val = 0UL;
+ (cellptr->data).a85.nc = 0;
+ (cellptr->data).a85.nl = 0;
+ } break;
+ case DK3_OF_CELL_TYPE_RUN_LENGTH: {
+ if((cellptr->data).psrl.bu) {
+ dk3mem_res((void *)((cellptr->data).psrl.bu), 128);
+ (cellptr->data).psrl.used = 0;
+ (cellptr->data).psrl.same = 0;
+ (cellptr->data).psrl.pc = 0x00;
+ (cellptr->data).psrl.hc = 0x00;
+ (cellptr->data).psrl.run = 0x00;
+ } else {
+ back = 0;
+ }
+ } break;
+ case DK3_OF_CELL_TYPE_FLATE: {
+#if DK3_HAVE_ZLIB_H
+ (cellptr->data).flate.iused = 0UL;
+ ((cellptr->data).flate.zs)->zfree = (free_func)0;
+ ((cellptr->data).flate.zs)->zalloc = (alloc_func)0;
+ ((cellptr->data).flate.zs)->opaque = (voidpf)0;
+ if(deflateInit((cellptr->data).flate.zs, 9) == Z_OK) {
+ (cellptr->data).flate.ok = 1;
+ } else {
+ (cellptr->data).flate.ok = 0;
+ back = 0;
+ }
+#else
+ back = 0;
+#endif
+ } break;
+ default: {
+ back = 0;
+ /* ERROR: Illegal cell type! */
+ if(of->app) {
+ dk3app_log_i1(of->app, DK3_LL_ERROR, 263);
+ }
+ } break;
+ }
+ cellptr = cellptr->down;
+ }
+ }
+ }
+
+#line 491 "dk3of.ctr"
+ return back;
+}
+
+
+
+/** Write Newline downwards.
+ @param of Output filter.
+ @param cellptr Current filter cell producing the newline.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3of_nl_from_cell(dk3_of_t *of, dk3_of_cell_t *cellptr)
+{
+ int back = 0;
+
+
+#line 507 "dk3of.ctr"
+ if((of->flags) & DK3_OF_FLAG_CRNL) {
+ back = dk3of_bytes_from_cell(
+ cellptr,
+ (unsigned char const *)(dk3of_kw[1]),
+ strlen(dk3of_kw[1])
+ );
+ } else {
+ back = dk3of_bytes_from_cell(
+ cellptr,
+ (unsigned char const *)(dk3of_kw[0]),
+ strlen(dk3of_kw[0])
+ );
+ }
+
+#line 520 "dk3of.ctr"
+ return back;
+}
+
+
+
+/** Write data from ASCII85 encoding cell downwards.
+ @param of Output filter.
+ @param cp Pointer to cell.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3of_write_a85_cell(dk3_of_t *of, dk3_of_cell_t *cp)
+{
+ int back = 0;
+ unsigned long v;
+ unsigned char bu[5];
+
+
+#line 538 "dk3of.ctr"
+ if((cp->data).a85.nc > 0) {
+ v = (cp->data).a85.val;
+ bu[0] = (unsigned char)(33UL + v / dk3of_a85_factors[0]);
+ v = v % dk3of_a85_factors[0];
+ bu[1] = (unsigned char)(33UL + v / dk3of_a85_factors[1]);
+ v = v % dk3of_a85_factors[1];
+ bu[2] = (unsigned char)(33UL + v / dk3of_a85_factors[2]);
+ v = v % dk3of_a85_factors[2];
+ bu[3] = (unsigned char)(33UL + v / dk3of_a85_factors[3]);
+ v = v % dk3of_a85_factors[3];
+ bu[4] = (unsigned char)(33UL + v);
+
+#line 549 "dk3of.ctr"
+ back = dk3of_bytes_from_cell(cp, bu, (1 + (cp->data).a85.nc));
+ } else {
+ back = 1;
+ }
+
+#line 553 "dk3of.ctr"
+ return back;
+}
+
+
+
+/** Save a run.
+ @param of Output filter.
+ @param cp Filter cell.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3of_psrl_save_run(dk3_of_t *of, dk3_of_cell_t *cp)
+{
+ int back = 0;
+ size_t sz;
+ unsigned char bu[2];
+
+ sz = 257 - (cp->data).psrl.used;
+ bu[0] = (unsigned char)sz;
+ bu[1] = (cp->data).psrl.pc;
+ back = dk3of_bytes_from_cell(cp, bu, 2);
+ (cp->data).psrl.used = 0;
+ (cp->data).psrl.same = 0;
+ (cp->data).psrl.pc = 0x00;
+ (cp->data).psrl.hc = 0x00;
+ (cp->data).psrl.run = 0x00;
+ return back;
+}
+
+
+
+/** Save data.
+ @param of Output filter.
+ @param cp Filter cell.
+ @param final Flag: Final action for chunk.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3of_psrl_save_data(dk3_of_t *of, dk3_of_cell_t *cp, int final)
+{
+ size_t i;
+ int back = 0;
+ unsigned char c;
+ size_t lgt;
+
+
+#line 600 "dk3of.ctr"
+ if(final) {
+ /*
+ Save data as is.
+ */
+ c = (unsigned char)((cp->data).psrl.used - 1);
+ if(dk3of_bytes_from_cell(cp, &c, 1)) {
+ if(dk3of_bytes_from_cell(cp, (cp->data).psrl.bu, (cp->data).psrl.used)) {
+ back = 1;
+ }
+ }
+ (cp->data).psrl.used = 0;
+ (cp->data).psrl.same = 0;
+ (cp->data).psrl.pc = 0x00;
+ (cp->data).psrl.hc = 0x00;
+ (cp->data).psrl.run = 0x00;
+ } else {
+ /*
+ Save data and attempt to switch into a run.
+ */
+ if((cp->data).psrl.same >= 1) {
+ if(((cp->data).psrl.same) < ((cp->data).psrl.used)) {
+ lgt = (cp->data).psrl.used - (cp->data).psrl.same - 1;
+
+#line 622 "dk3of.ctr"
+ if(lgt > 0) {
+ c = (unsigned char)(lgt - 1);
+ if(dk3of_bytes_from_cell(cp, &c, 1)) {
+ if(dk3of_bytes_from_cell(cp, (cp->data).psrl.bu, lgt)) {
+ back = 1;
+ }
+ }
+ for(i = 0; i < (cp->data).psrl.same + 1; i++) {
+ ((cp->data).psrl.bu)[i] = ((cp->data).psrl.bu)[lgt + i];
+ }
+ (cp->data).psrl.used = (cp->data).psrl.same + 1;
+ if((cp->data).psrl.same >= 1) {
+ (cp->data).psrl.run = 0x01;
+
+#line 635 "dk3of.ctr"
+ }
+ } else {
+ back = 1; /* Nothing to do here. */
+ if((cp->data).psrl.same > 1) {
+ (cp->data).psrl.run = 0x01;
+
+#line 640 "dk3of.ctr"
+ }
+ }
+ } else {
+
+#line 643 "dk3of.ctr"
+ }
+ } else {
+ back = dk3of_psrl_save_data(of, cp, 1);
+ }
+ }
+
+#line 648 "dk3of.ctr"
+ return back;
+}
+
+
+
+int
+dk3of_end_chunk(dk3_of_t *of)
+{
+ dk3_of_cell_t *cellptr;
+#if DK3_HAVE_ZLIB_H
+ size_t sz;
+#endif
+ int back = 0;
+ int res;
+
+
+#line 663 "dk3of.ctr"
+ if(of) {
+ if(of->top) {
+ back = dk3of_flush_bits(of);
+ cellptr = of->top;
+ while(cellptr) {
+ switch(cellptr->type) {
+ case DK3_OF_CELL_TYPE_HEX: {
+ if((of->flags) & DK3_OF_FLAG_FINALIZE) {
+ res = dk3of_bytes_from_cell(
+ cellptr,
+ (unsigned char const *)(dk3of_kw[2]),
+ strlen(dk3of_kw[2])
+ );
+ if(!(res)) { back = 0; }
+ if(!dk3of_nl_from_cell(of, cellptr)) { back = 0; }
+ }
+ } break;
+ case DK3_OF_CELL_TYPE_A85: {
+ if(!dk3of_write_a85_cell(of, cellptr)) {
+ back = 0;
+ }
+ if((of->flags) & DK3_OF_FLAG_FINALIZE) {
+ res = dk3of_bytes_from_cell(
+ cellptr,
+ (unsigned char const *)(dk3of_kw[3]),
+ strlen(dk3of_kw[3])
+ );
+ if(!(res)) { back = 0; }
+ if(!dk3of_nl_from_cell(of, cellptr)) { back = 0; }
+ }
+ } break;
+ case DK3_OF_CELL_TYPE_RUN_LENGTH: {
+ if((cellptr->data).psrl.bu) {
+ if((cellptr->data).psrl.run) {
+ if(!dk3of_psrl_save_run(of, cellptr)) {
+ back = 0;
+ }
+ } else {
+ if(!dk3of_psrl_save_data(of, cellptr, 1)) {
+ back = 0;
+ }
+ }
+ } else {
+ back = 0;
+ }
+ } break;
+ case DK3_OF_CELL_TYPE_FLATE: {
+#if DK3_HAVE_ZLIB_H
+ int cc = 1;
+ ((cellptr->data).flate.zs)->next_in = (cellptr->data).flate.ibu;
+ ((cellptr->data).flate.zs)->avail_in = (cellptr->data).flate.iused;
+ while(cc) {
+ cc = 0;
+ ((cellptr->data).flate.zs)->next_out = (cellptr->data).flate.obu;
+ ((cellptr->data).flate.zs)->avail_out = DK3_OF_FLATE_OUT_BUFFER_SIZE;
+ res = deflate((cellptr->data).flate.zs, Z_FINISH);
+ switch(res) {
+ case Z_STREAM_END: {
+ sz = (size_t)(
+ DK3_OF_FLATE_OUT_BUFFER_SIZE
+ - ((cellptr->data).flate.zs)->avail_out
+ );
+ if(sz) {
+ if(!dk3of_bytes_from_cell(
+ cellptr,
+ (unsigned char const *)((cellptr->data).flate.obu),
+ sz
+ )
+ )
+ {
+ back = 0;
+ }
+ }
+ } break;
+ case Z_OK: {
+ cc = 1;
+ sz = (size_t)(
+ DK3_OF_FLATE_OUT_BUFFER_SIZE
+ - ((cellptr->data).flate.zs)->avail_out
+ );
+ if(sz) {
+ if(!dk3of_bytes_from_cell(
+ cellptr,
+ (unsigned char const *)((cellptr->data).flate.obu),
+ sz
+ )
+ )
+ {
+ back = 0;
+ }
+ }
+ } break;
+ default: {
+ back = 0;
+ } break;
+ }
+ }
+ if(deflateEnd((cellptr->data).flate.zs) != Z_OK) {
+ back = 0;
+ }
+ (cellptr->data).flate.iused = 0UL;
+ (cellptr->data).flate.ok = 0;
+#else
+ back = 0;
+#endif
+ } break;
+ default: {
+ back = 0;
+ /* ERROR: Illegal cell type! */
+ if(of->app) {
+ dk3app_log_i1(of->app, DK3_LL_ERROR, 263);
+ }
+ } break;
+ }
+ cellptr = cellptr->down;
+ }
+ }
+ }
+
+#line 781 "dk3of.ctr"
+ return back;
+}
+
+
+
+int
+dk3of_bytes_from_cell(dk3_of_cell_t *cp, unsigned char const *bu, size_t sz)
+{
+#if VERSION_BEFORE_20150821
+ dk3_app_t *app;
+#endif
+ dk3_of_t *of;
+ int back = 0;
+ size_t bw;
+
+
+#line 796 "dk3of.ctr"
+ if((cp) && (bu) && (sz)) {
+#if VERSION_BEFORE_20150821
+ of = NULL; app = NULL;
+#endif
+ if(cp->of) {
+ of = (dk3_of_t *)(cp->of);
+#if VERSION_BEFORE_20150821
+ if(of->app) { app = of->app; }
+#endif
+ if(cp->down) {
+
+#line 806 "dk3of.ctr"
+ back = dk3of_bytes_to_cell(cp->down, bu, sz);
+ } else {
+
+#line 808 "dk3of.ctr"
+ if(of->os) {
+ bw = dk3stream_write_bytes(of->os, (char const *)bu, sz);
+ if(bw == sz) {
+ back = 1;
+ }
+ } else {
+
+#line 814 "dk3of.ctr"
+ /* BUG: Output filter has no destination stream! */
+ }
+ }
+ } else {
+
+#line 818 "dk3of.ctr"
+ /* BUG: Missing output filter pointer! */
+ }
+ }
+
+#line 821 "dk3of.ctr"
+ return back;
+}
+
+
+
+/** Process one byte in a filter cell.
+ @param cp Filter cell.
+ @param uc Byte to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3of_one_byte_to_cell(dk3_of_cell_t *cp, unsigned char uc)
+{
+ dk3_of_t *of = NULL;
+ unsigned long ul;
+ size_t u1;
+ size_t u2;
+#if DK3_HAVE_ZLIB_H
+ size_t sz;
+ int cc;
+ int err;
+#endif
+ int back = 0;
+ unsigned char b[5];
+
+
+#line 847 "dk3of.ctr"
+ of = (dk3_of_t *)(cp->of);
+ switch(cp->type) {
+ case DK3_OF_CELL_TYPE_HEX: {
+
+#line 850 "dk3of.ctr"
+ u1 = (size_t)uc;
+ u2 = (size_t)uc;
+ u1 = (u1 >> 4) & 0x000FU;
+ u2 = u2 & 0x000FU;
+ b[0] = (unsigned char)(dk3of_hex_chars[u1]);
+ b[1] = (unsigned char)(dk3of_hex_chars[u2]);
+ back = dk3of_bytes_from_cell(cp, b, 2);
+ (cp->data).ah.nl += 1;
+ if((cp->data).ah.nl >= 35) {
+ (cp->data).ah.nl = 0;
+ if(cp->of) {
+ of = (dk3_of_t *)(cp->of);
+ if(!dk3of_nl_from_cell(of, cp)) { back = 0; }
+ } else {
+ back = 0;
+ /* BUG: Stream not configured for cell! */
+ }
+ }
+ } break;
+ case DK3_OF_CELL_TYPE_A85: {
+
+#line 870 "dk3of.ctr"
+ ul = (unsigned long)uc;
+ switch((cp->data).a85.nc) {
+ case 0: {
+ ul = ((ul << 24) & 0xFF000000UL);
+ } break;
+ case 1: {
+ ul = ((ul << 16) & 0x00FF0000UL);
+ } break;
+ case 2: {
+ ul = ((ul << 8) & 0x0000FF00UL);
+ } break;
+ default: {
+ ul = (ul & 0x000000FFUL);
+ } break;
+ }
+ (cp->data).a85.val |= ul;
+ (cp->data).a85.nc += 1;
+ back = 1;
+ if((cp->data).a85.nc >= 4) {
+ back = dk3of_write_a85_cell(of, cp);
+ (cp->data).a85.nc = 0;
+ (cp->data).a85.val = 0UL;
+ (cp->data).a85.nl += 1;
+ if((cp->data).a85.nl >= 14) {
+ (cp->data).a85.nl = 0;
+ if(!dk3of_nl_from_cell(of, cp)) {
+ back = 0;
+ }
+ }
+ }
+ } break;
+ case DK3_OF_CELL_TYPE_RUN_LENGTH: {
+
+#line 902 "dk3of.ctr"
+ back = 1;
+ if((cp->data).psrl.run) {
+
+#line 904 "dk3of.ctr"
+ if(uc == (cp->data).psrl.pc) {
+
+#line 905 "dk3of.ctr"
+ ((cp->data).psrl.bu)[(cp->data).psrl.used] = uc;
+ (cp->data).psrl.used += 1;
+ (cp->data).psrl.same += 1;
+ if((cp->data).psrl.used >= 127) {
+ if(!dk3of_psrl_save_run(of, cp)) {
+ back = 0;
+ }
+ }
+ } else {
+
+#line 914 "dk3of.ctr"
+ if(!dk3of_psrl_save_run(of, cp)) {
+ back = 0;
+ }
+ ((cp->data).psrl.bu)[0] = uc;
+ (cp->data).psrl.used = 1;
+ (cp->data).psrl.pc = uc;
+ (cp->data).psrl.hc = 0x01;
+ }
+ } else {
+
+#line 923 "dk3of.ctr"
+ ((cp->data).psrl.bu)[(cp->data).psrl.used] = uc;
+ (cp->data).psrl.used += 1;
+ if((cp->data).psrl.hc) {
+
+#line 926 "dk3of.ctr"
+ if(uc == (cp->data).psrl.pc) {
+
+#line 927 "dk3of.ctr"
+ (cp->data).psrl.same += 1;
+
+#line 928 "dk3of.ctr"
+ } else {
+
+#line 929 "dk3of.ctr"
+ (cp->data).psrl.same = 0;
+ }
+ } else {
+
+#line 932 "dk3of.ctr"
+ (cp->data).psrl.same = 0;
+ }
+ (cp->data).psrl.hc = 0x01;
+ (cp->data).psrl.pc = uc;
+ if(((cp->data).psrl.used >= 127) || ((cp->data).psrl.same >= 2)) {
+ if(!dk3of_psrl_save_data(of, cp, 0)) {
+ back = 0;
+ }
+ }
+ }
+
+#line 942 "dk3of.ctr"
+ } break;
+ case DK3_OF_CELL_TYPE_FLATE: {
+
+#line 944 "dk3of.ctr"
+#if DK3_HAVE_ZLIB_H
+ if((cp->data).flate.ok) {
+ back = 1;
+ ((cp->data).flate.ibu)[(cp->data).flate.iused] = uc;
+ (cp->data).flate.iused += 1;
+ if((cp->data).flate.iused >= DK3_OF_FLATE_IN_BUFFER_SIZE) {
+ cc = 1;
+ ((cp->data).flate.zs)->next_in = (cp->data).flate.ibu;
+ ((cp->data).flate.zs)->avail_in = (cp->data).flate.iused;
+ while(cc) {
+ cc = 0;
+ ((cp->data).flate.zs)->next_out = (cp->data).flate.obu;
+ ((cp->data).flate.zs)->avail_out = DK3_OF_FLATE_OUT_BUFFER_SIZE;
+ err = deflate((cp->data).flate.zs, 0);
+ switch(err) {
+ case Z_OK: {
+ if(((cp->data).flate.zs)->avail_in) {
+ cc= 1;
+ }
+ sz = (size_t)(
+ DK3_OF_FLATE_OUT_BUFFER_SIZE
+ - ((cp->data).flate.zs)->avail_out
+ );
+ if(!dk3of_bytes_from_cell(cp, (cp->data).flate.obu, sz)) {
+ back = 0;
+ }
+ } break;
+ default: {
+ (cp->data).flate.ok = 0;
+ } break;
+ }
+ }
+ (cp->data).flate.iused = 0;
+ }
+ } else {
+ /* ERROR: Previous operations failed! */
+ if(of->app) {
+ dk3app_log_i1(of->app, DK3_LL_ERROR, 264);
+ }
+ }
+#else
+ /* ERROR: Compression not supported! */
+ if(of->app) {
+ dk3app_log_i1(of->app, DK3_LL_ERROR, 262);
+ }
+#endif
+ } break;
+ }
+
+#line 992 "dk3of.ctr"
+ return back;
+}
+
+
+
+int
+dk3of_bytes_to_cell(dk3_of_cell_t *cp, unsigned char const *bu, size_t sz)
+{
+ int back = 0;
+ size_t i;
+ unsigned char const *ptr;
+
+
+#line 1004 "dk3of.ctr"
+ if((NULL != cp) && (NULL != bu) && (0 < sz)) {
+ back = 1;
+ ptr = bu;
+ for(i = 0; i < sz; i++) {
+ /* 2016-01-20
+ Static code analysis from clang complains about the
+ assigned value *(ptr++) is garbage or undefined.
+ Depends on the calling code.
+ */
+ if(!dk3of_one_byte_to_cell(cp, *(ptr++))) {
+ back = 0;
+ }
+ }
+ }
+
+#line 1018 "dk3of.ctr"
+ return back;
+}
+
+
+
+int
+dk3of_write_bits(dk3_of_t *of, unsigned short bv, size_t sz)
+{
+ size_t i;
+ int back = 0;
+ int bit;
+
+
+#line 1030 "dk3of.ctr"
+ if((of) && (sz)) {
+ if(sz <= 16) {
+ back = 1;
+ for(i = 0; i < sz; i++) {
+ bit = 0;
+ if(bv & dk3of_bits_in_short[sz - i - 1]) { bit = 1; }
+ if(bit) {
+
+#line 1037 "dk3of.ctr"
+ of->bits = (of->bits) | (dk3of_bits_in_char[of->nBits]);
+ } else {
+
+#line 1039 "dk3of.ctr"
+ of->bits = (of->bits) & (~(dk3of_bits_in_char[of->nBits]));
+ }
+ of->nBits += 1;
+
+#line 1042 "dk3of.ctr"
+ if(of->nBits >= 8) {
+
+#line 1043 "dk3of.ctr"
+ if(!dk3of_flush_bits(of)) {
+
+#line 1044 "dk3of.ctr"
+ back = 0;
+ }
+ }
+ }
+ }
+ }
+
+#line 1050 "dk3of.ctr"
+ return back;
+}
+
+
+
+int
+dk3of_write_bytes(dk3_of_t *of, unsigned char const *bu, size_t sz)
+{
+ int back = 0;
+ unsigned char const *ptr;
+ unsigned char uc;
+ unsigned short us;
+ size_t i;
+
+
+#line 1064 "dk3of.ctr"
+ if((NULL != of) && (NULL != bu) && (0 < sz)) {
+ if(of->nBits) {
+
+#line 1066 "dk3of.ctr"
+ back = 1;
+ ptr = bu;
+ for(i = 0; i < sz; i++) {
+ /* 2016-01-20
+ Static code analysis from clang complains about the
+ assigned value *(ptr++) is garbage or undefined.
+ Depends on the calling code.
+ */
+ uc = *(ptr++);
+ us = (unsigned short)uc;
+ us &= 0x00FFU;
+ if(!dk3of_write_bits(of, us, 8)) {
+ back = 0;
+ }
+ }
+ } else {
+
+#line 1082 "dk3of.ctr"
+ if(of->top) {
+ back = dk3of_bytes_to_cell(of->top, bu, sz);
+ }
+ }
+ }
+
+#line 1087 "dk3of.ctr"
+ return back;
+}
+
+
+
+int
+dk3of_write_c8_string(dk3_of_t *of, char const *st)
+{
+ int back = 0;
+ size_t sl;
+ if((of) && (st)) {
+ sl = strlen(st);
+ back = dk3of_write_bytes(of, (unsigned char const *)st, sl);
+ }
+ return back;
+}
+
+
+
+int
+dk3of_flush_bits(dk3_of_t *of)
+{
+ int back = 0;
+
+
+#line 1111 "dk3of.ctr"
+ if(of) {
+ if(of->nBits) {
+
+#line 1113 "dk3of.ctr"
+ back = dk3of_bytes_to_cell(of->top, &(of->bits), 1);
+ of->bits = 0x00;
+ of->nBits = 0;
+ } else {
+
+#line 1117 "dk3of.ctr"
+ back = 1;
+ }
+ }
+
+#line 1120 "dk3of.ctr"
+ return back;
+}
+
+
+
+void
+dk3of_set_crnl(dk3_of_t *of, int fl)
+{
+
+
+#line 1129 "dk3of.ctr"
+ if(of) {
+ if(fl) {
+ of->flags |= DK3_OF_FLAG_CRNL;
+ } else {
+ of->flags &= (~(DK3_OF_FLAG_CRNL));
+ }
+ }
+
+#line 1136 "dk3of.ctr"
+}
+
+
+
+void
+dk3of_set_finalize(dk3_of_t *of, int fl)
+{
+
+
+#line 1144 "dk3of.ctr"
+ if(of) {
+ if(fl) {
+ of->flags |= DK3_OF_FLAG_FINALIZE;
+ } else {
+ of->flags &= (~(DK3_OF_FLAG_FINALIZE));
+ }
+ }
+
+#line 1151 "dk3of.ctr"
+}
+
+
+
+int
+dk3of_double_str_no_sci(dk3_of_t *of, char *buffer)
+{
+ char *start; /* Start of string. */
+ char *eptr; /* Start of exponent substring. */
+ char *ptr; /* Traverse string. */
+ size_t lgt; /* String length. */
+ int dp; /* Decimal dot position. */
+ int exponent; /* Exponent. */
+ int i; /* Traverse the string. */
+ char chr[2];
+ int back = 0;
+
+ chr[1] = '\0';
+ if ((NULL != of) && (NULL != buffer)) {
+ /* 2015-08-21 Set success now, errors reset back to 0 */
+ back = 1;
+ eptr = NULL;
+ start = buffer;
+ /*
+ Print sign.
+ */
+ switch(*start) {
+ case '-': {
+ chr[0] = '-';
+ if (0 == dk3of_write_c8_string(of, chr)) { back = 0; }
+ start++;
+ } break;
+ case '+': {
+ start++;
+ } break;
+ }
+ /*
+ Find exponent substring and exponent.
+ */
+ eptr = NULL;
+ ptr = start;
+ while(*ptr) {
+ switch(*ptr) {
+ case 'e': case 'E': {
+ eptr = ptr;
+ } break;
+ }
+ ptr++;
+ }
+ if(eptr) {
+ *(eptr++) = '\0';
+#if VERSION_BEFORE_20141002
+ if(sscanf(eptr, "%d", &exponent) != 1) {
+ exponent = 0;
+ }
+#else
+ if (0 == dk3ma_i_from_c8_string(&exponent, eptr, NULL)) {
+ exponent = 0;
+ }
+#endif
+ } else {
+ exponent = 0;
+ }
+ /*
+ Find decimal dot.
+ */
+ eptr = strchr(start, '.');
+ if(eptr) {
+ /*
+ Keep dot position in dp, squeeze string.
+ */
+ *eptr = '\0';
+ dp = (int)strlen(start);
+ *eptr = '.';
+ while(*eptr) {
+ eptr[0] = eptr[1];
+ eptr++;
+ }
+ } else {
+ /*
+ Dot position is after the string.
+ */
+ dp = (int)strlen(start);
+ }
+ /*
+ Correct dot position.
+ */
+ dp = dp + exponent;
+ /*
+ Remove leading zeroes (if any).
+ */
+ while('0' == *start) {
+ start++; dp--;
+ }
+ /*
+ Remove trailing zeroes (if any).
+ */
+ eptr = NULL;
+ ptr = start;
+ while(*ptr) {
+ if('0' == *ptr) {
+ if(!(eptr)) { eptr = ptr; }
+ } else {
+ eptr = NULL;
+ }
+ ptr++;
+ }
+ if(eptr) { *eptr = '\0'; }
+ lgt = strlen(start);
+ if(0 < lgt) {
+ if(dp >= (int)lgt) {
+ /*
+ Decimal dot is at end or after string.
+ */
+ if (0 == dk3of_write_c8_string(of, start)) { back = 0; }
+ /*
+ Decimal dot is after the string.
+ */
+ for(i = 0; i < (dp - (int)lgt); i++) {
+ chr[0] = '0';
+ if (0 == dk3of_write_c8_string(of, chr)) { back = 0; }
+ }
+ } else {
+ if(dp <= 0) {
+ /*
+ Decimal dot is before the string.
+ */
+ chr[0] = '0';
+ if (0 == dk3of_write_c8_string(of, chr)) { back = 0; }
+ chr[0] = '.';
+ if (0 == dk3of_write_c8_string(of, chr)) { back = 0; }
+ while(dp++ < 0) {
+ chr[0] = '0';
+ if (0 == dk3of_write_c8_string(of, chr)) { back = 0; }
+ }
+ if (0 == dk3of_write_c8_string(of, start)) { back = 0; }
+ } else {
+ /*
+ Decimal dot is in the string.
+ */
+ for(i = 0; i < (int)lgt; i++) {
+ if(dp == i) {
+ chr[0] = '.';
+ if (0 == dk3of_write_c8_string(of, chr)) { back = 0; }
+ }
+ chr[0] = start[i];
+ if (0 == dk3of_write_c8_string(of, chr)) { back = 0; }
+ }
+ }
+ }
+ } else {
+ /*
+ No non-zero digits in string.
+ */
+ chr[0] = '0';
+ if (0 == dk3of_write_c8_string(of, chr)) { back = 0; }
+ }
+#if VERSION_BEFORE_20150821
+ back = 1;
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3of_double_to_c8_no_sci(dk3_of_t *of, double x)
+{
+ char buffer[64];
+ char *ptr;
+ int back = 0;
+ if (NULL != of) {
+ sprintf(buffer, "%g", x);
+ ptr = buffer;
+ while ('\0' != *ptr) { if(',' == *ptr) { *ptr = '.'; } ptr++;}
+ back = dk3of_double_str_no_sci(of, buffer);
+ }
+ return back;
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dk3of.ctr b/support/dktools/dk3of.ctr
new file mode 100644
index 0000000000..d11e1e8c89
--- /dev/null
+++ b/support/dktools/dk3of.ctr
@@ -0,0 +1,1335 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% header
+
+#include "dk3conf.h"
+#include "dk3types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Create output filter for a stream.
+ @param os Output stream.
+ @param app Application structure for diagnostics.
+ @return Pointer to new filter on success, NULL on error.
+*/
+dk3_of_t *
+dk3of_open_app(dk3_stream_t *os, dk3_app_t *app);
+
+/** Create output filter for a stream.
+ @param os Output stream.
+ @return Pointer to new filter on success, NULL on error.
+*/
+dk3_of_t *
+dk3of_open(dk3_stream_t *os);
+
+/** Close output filter, release memory.
+ @param of Filter to delete.
+*/
+void
+dk3of_close(dk3_of_t *of);
+
+/** Add filter cell.
+ @param of Output filter.
+ @param ct Cell type (DK3_OF_CELL_TYPE_xxx).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3of_add_cell(dk3_of_t *of, int ct);
+
+/** Start data chunk.
+ @param of Output filter.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3of_start_chunk(dk3_of_t *of);
+
+/** End data chunk, flush buffers.
+ @param of Output filter.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3of_end_chunk(dk3_of_t *of);
+
+/** Write bytes to filter cell.
+ @param cp Filter cell.
+ @param bu Buffer containing the bytes.
+ @param sz Number of bytes.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3of_bytes_to_cell(dk3_of_cell_t *cp, unsigned char const *bu, size_t sz);
+
+/** Write bytes from filter cell, either to the next filter cell
+ downwards or to the destination stream.
+ @param cp Filter cell.
+ @param bu Buffer containing the bytes.
+ @param sz Number of bytes.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3of_bytes_from_cell(dk3_of_cell_t *cp, unsigned char const *bu, size_t sz);
+
+/** Write bytes to output filter.
+ @param of Output filter.
+ @param bu Buffer containing the bytes.
+ @param sz Number of bytes.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3of_write_bytes(dk3_of_t *of, unsigned char const *bu, size_t sz);
+
+/** Write string to output filter.
+ @param of Output filter.
+ @param st String to write.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3of_write_c8_string(dk3_of_t *of, char const *st);
+
+/** Write bits to output filter.
+ @param of Output filter.
+ @param bv Bit values.
+ @param sz Number of bits.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3of_write_bits(dk3_of_t *of, unsigned short bv, size_t sz);
+
+/** Flush bit buffer.
+ @param of Output filter.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3of_flush_bits(dk3_of_t *of);
+
+/** Configure use of cr/nl sequences.
+ @param of Output filter.
+ @param fl 0 for disable, any other value to enable.
+*/
+void
+dk3of_set_crnl(dk3_of_t *of, int fl);
+
+/** Configure use of finalizers.
+ @param of Output filter.
+ @param fl 0 for disable, any other value to enable.
+*/
+void
+dk3of_set_finalize(dk3_of_t *of, int fl);
+
+/** Write double number to output, avoid exponential notation.
+ @param of Output filter.
+ @param x Value to write.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3of_double_to_c8_no_sci(dk3_of_t *of, double x);
+
+/** Write double number to output.
+ @param of Output filter to write to.
+ @param buffer String buffer containing number as string.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3of_double_str_no_sci(dk3_of_t *of, char *buffer);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+
+#include "dk3all.h"
+
+
+
+$!trace-include
+
+
+
+/** Keywords used by this module.
+*/
+static char const * dk3of_kw[] = {
+/* 0 */ "\n",
+/* 1 */ "\r\n",
+/* 2 */ ">", /* ASCII/Hex finalizer. */
+/* 3 */ "~>", /* ASCII85 finalizer. */
+};
+
+
+
+/** Characters used for ASCII-Hex conversion.
+*/
+static char const dk3of_hex_chars[] = { "0123456789ABCDEF" };
+
+
+
+/** Masks for single bits in an unsigned char.
+*/
+static unsigned char const dk3of_bits_in_char[] = {
+ 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
+};
+
+
+
+/** Masks for single bits in an unsigned short.
+*/
+static unsigned short const dk3of_bits_in_short[] = {
+ 0x0001U, 0x0002U, 0x0004U, 0x0008U, 0x0010U, 0x0020U, 0x0040U, 0x0080U,
+ 0x0100U, 0x0200U, 0x0400U, 0x0800U, 0x1000U, 0x2000U, 0x4000U, 0x8000U
+};
+
+
+
+/** Constant factors used in ASCII85 encoding.
+*/
+static unsigned long const dk3of_a85_factors[] = {
+ (85UL * 85UL * 85UL * 85UL),
+ (85UL * 85UL * 85UL),
+ (85UL * 85UL),
+ 85UL
+};
+
+
+
+/** Destroy filter cell, release memory.
+ @param cp Filter cell to delete.
+*/
+static
+void
+dk3of_cell_close(dk3_of_cell_t *cp)
+{
+ $? "+ dk3of_cell_close %!8s", TR_8PTR(cp)
+ if(cp) {
+ switch(cp->type) {
+ case DK3_OF_CELL_TYPE_HEX: {
+ /* Nothing to do here, only static data structures. */
+ } break;
+ case DK3_OF_CELL_TYPE_A85: {
+ /* Nothing to do here, only static data structures. */
+ } break;
+ case DK3_OF_CELL_TYPE_RUN_LENGTH: {
+ dk3_delete((cp->data).psrl.bu);
+ } break;
+ case DK3_OF_CELL_TYPE_FLATE: {
+#if DK3_HAVE_ZLIB_H
+ dk3_release((cp->data).flate.zs);
+ dk3_release((cp->data).flate.ibu);
+ dk3_release((cp->data).flate.obu);
+ (cp->data).flate.iused = 0UL;
+ (cp->data).flate.ok = 0;
+#else
+#endif
+ } break;
+ default: { $? "! unknown type"
+ /* Nothing to do here as type is unknown. */
+ } break;
+ }
+ dk3_delete(cp);
+ } $? "- dk3of_cell_close"
+}
+
+
+
+/** Create new filter cell for a filter.
+ @param of Output filter.
+ @param ct Cell type.
+ @return Pointer to the new filter cell on success, NULL on error.
+*/
+static
+dk3_of_cell_t *
+dk3of_cell_open(dk3_of_t *of, int ct)
+{
+ dk3_of_cell_t *back = NULL;
+ $? "+ dk3of_cell_open %!8s %d", TR_8PTR(of), ct
+ if(of) {
+ back = dk3_new_app(dk3_of_cell_t,1,(of->app));
+ if(back) {
+ back->down = NULL;
+ back->up = NULL;
+ back->of = of;
+ back->type = ct;
+ switch(ct) {
+ case DK3_OF_CELL_TYPE_HEX: {
+ (back->data).ah.nl = 0;
+ } break;
+ case DK3_OF_CELL_TYPE_A85: {
+ (back->data).a85.val = 0UL;
+ (back->data).a85.nc = 0;
+ (back->data).a85.nl = 0;
+ } break;
+ case DK3_OF_CELL_TYPE_RUN_LENGTH: {
+ (back->data).psrl.bu = NULL;
+ (back->data).psrl.used = 0;
+ (back->data).psrl.same = 0;
+ (back->data).psrl.pc = 0x00;
+ (back->data).psrl.hc = 0x00;
+ (back->data).psrl.run = 0x00;
+ (back->data).psrl.bu = dk3_new_app(unsigned char,128,of->app);
+ if(!((back->data).psrl.bu)) {
+ dk3of_cell_close(back); back = NULL;
+ }
+ } break;
+ case DK3_OF_CELL_TYPE_FLATE: {
+#if DK3_HAVE_ZLIB_H
+ int ok = 0;
+ (back->data).flate.zs = NULL;
+ (back->data).flate.ibu = NULL;
+ (back->data).flate.obu = NULL;
+ (back->data).flate.iused = 0UL;
+ (back->data).flate.ok = 0;
+ (back->data).flate.zs = dk3_new_app(z_stream,1,of->app);
+ if((back->data).flate.zs) {
+ (back->data).flate.ibu =
+ dk3_new_app(unsigned char,DK3_OF_FLATE_IN_BUFFER_SIZE,of->app);
+ if((back->data).flate.ibu) {
+ /* (back->data).flate.ilgt = DK3_OF_FLATE_IN_BUFFER_SIZE; */
+ (back->data).flate.obu =
+ dk3_new_app(unsigned char,DK3_OF_FLATE_OUT_BUFFER_SIZE,of->app);
+ if((back->data).flate.obu) {
+ (back->data).flate.ok = 1;
+ ok = 1;
+ }
+ }
+ }
+ if(!(ok)) {
+ dk3of_cell_close(back); back = NULL;
+ }
+#else
+ back = 0;
+ /* ERROR: Not supported. */
+ if(of->app) {
+ dk3app_log_i1(of->app, DK3_LL_ERROR, 262);
+ }
+#endif
+ } break;
+ default: { $? "! unknown type"
+ dk3_delete(back);
+ back = NULL;
+ if(of->app) {
+ /* ERROR: Unknown type! */
+ dk3app_log_i1(of->app, DK3_LL_ERROR, 262);
+ }
+ } break;
+ }
+ }
+ } $? "- dk3of_cell_open %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+dk3_of_t *
+dk3of_open_app(dk3_stream_t *os, dk3_app_t *app)
+{
+ dk3_of_t *back = NULL;
+ $? "+ dk3of_open_app %!8s %!8s", TR_8PTR(os), TR_8PTR(app)
+ if(os) {
+ back = dk3_new_app(dk3_of_t,1,app);
+ if(back) {
+ back->app = app;
+ back->os = os;
+ back->bottom = NULL;
+ back->top = NULL;
+ back->nCells = 0;
+ back->nBits = 0;
+ back->bits = 0x00;
+ back->flags = DK3_OF_FLAG_FINALIZE;
+ }
+ } $? "- dk3of_open_app %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+dk3_of_t *
+dk3of_open(dk3_stream_t *os)
+{
+ dk3_of_t *back = NULL;
+ $? "+ dk3of_open %!8s", TR_8PTR(os)
+ if(os) {
+ back = dk3of_open_app(os, NULL);
+ } $? "- dk3of_open %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+void
+dk3of_close(dk3_of_t *of)
+{
+ dk3_of_cell_t *cc;
+ dk3_of_cell_t *nc;
+ $? "+ dk3of_close %!8s", TR_8PTR(of)
+ if(of) {
+ cc = of->top;
+ while(cc) {
+ nc = cc->down;
+ dk3of_cell_close(cc);
+ cc = nc;
+ }
+ } $? "- dk3of_close"
+}
+
+
+
+int
+dk3of_add_cell(dk3_of_t *of, int ct)
+{
+ dk3_of_cell_t *nc; /* New cell. */
+ dk3_of_cell_t *ot; /* Old top. */
+ int back = 0;
+ $? "+ dk3of_add_cell %!8s %d", TR_8PTR(of), ct
+ if(of) {
+ switch(ct) {
+ case DK3_OF_CELL_TYPE_HEX:
+ case DK3_OF_CELL_TYPE_A85:
+ case DK3_OF_CELL_TYPE_RUN_LENGTH:
+ case DK3_OF_CELL_TYPE_FLATE:
+ {
+ nc = dk3of_cell_open(of, ct);
+ if(nc) {
+ back = 1;
+ nc->of = (void *)of;
+ ot = of->top;
+ if(ot) { $? ". already have cells in stream"
+ ot->up = nc;
+ nc->down = ot;
+ } else { $? ". first cell for stream"
+ of->bottom = nc;
+ nc->down = NULL;
+ }
+ nc->up = NULL;
+ of->top = nc;
+ of->nCells += 1;
+ }
+ }
+ break;
+ default: {
+ /* ERROR: Illegal cell type! */
+ if(of->app) {
+ dk3app_log_i1(of->app, DK3_LL_ERROR, 263);
+ }
+ } break;
+ }
+ } $? "- dk3of_add_cell %d", back
+ return back;
+}
+
+
+
+int
+dk3of_start_chunk(dk3_of_t *of)
+{
+ dk3_of_cell_t *cellptr;
+ int back = 0;
+ $? "+ dk3of_start_chunk %!8s", TR_8PTR(of)
+ if(of) {
+ if(of->top) {
+ back = 1;
+ cellptr = of->top;
+ while(cellptr) {
+ switch(cellptr->type) {
+ case DK3_OF_CELL_TYPE_HEX: {
+ (cellptr->data).ah.nl = 0;
+ } break;
+ case DK3_OF_CELL_TYPE_A85: {
+ (cellptr->data).a85.val = 0UL;
+ (cellptr->data).a85.nc = 0;
+ (cellptr->data).a85.nl = 0;
+ } break;
+ case DK3_OF_CELL_TYPE_RUN_LENGTH: {
+ if((cellptr->data).psrl.bu) {
+ dk3mem_res((void *)((cellptr->data).psrl.bu), 128);
+ (cellptr->data).psrl.used = 0;
+ (cellptr->data).psrl.same = 0;
+ (cellptr->data).psrl.pc = 0x00;
+ (cellptr->data).psrl.hc = 0x00;
+ (cellptr->data).psrl.run = 0x00;
+ } else {
+ back = 0;
+ }
+ } break;
+ case DK3_OF_CELL_TYPE_FLATE: {
+#if DK3_HAVE_ZLIB_H
+ (cellptr->data).flate.iused = 0UL;
+ ((cellptr->data).flate.zs)->zfree = (free_func)0;
+ ((cellptr->data).flate.zs)->zalloc = (alloc_func)0;
+ ((cellptr->data).flate.zs)->opaque = (voidpf)0;
+ if(deflateInit((cellptr->data).flate.zs, 9) == Z_OK) {
+ (cellptr->data).flate.ok = 1;
+ } else {
+ (cellptr->data).flate.ok = 0;
+ back = 0;
+ }
+#else
+ back = 0;
+#endif
+ } break;
+ default: {
+ back = 0;
+ /* ERROR: Illegal cell type! */
+ if(of->app) {
+ dk3app_log_i1(of->app, DK3_LL_ERROR, 263);
+ }
+ } break;
+ }
+ cellptr = cellptr->down;
+ }
+ }
+ } $? "- dk3of_start_chunk %d", back
+ return back;
+}
+
+
+
+/** Write Newline downwards.
+ @param of Output filter.
+ @param cellptr Current filter cell producing the newline.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3of_nl_from_cell(dk3_of_t *of, dk3_of_cell_t *cellptr)
+{
+ int back = 0;
+ $? "+ dk3of_nl_from_cell"
+ if((of->flags) & DK3_OF_FLAG_CRNL) {
+ back = dk3of_bytes_from_cell(
+ cellptr,
+ (unsigned char const *)(dk3of_kw[1]),
+ strlen(dk3of_kw[1])
+ );
+ } else {
+ back = dk3of_bytes_from_cell(
+ cellptr,
+ (unsigned char const *)(dk3of_kw[0]),
+ strlen(dk3of_kw[0])
+ );
+ } $? "- dk3of_nl_from_cell %d", back
+ return back;
+}
+
+
+
+/** Write data from ASCII85 encoding cell downwards.
+ @param of Output filter.
+ @param cp Pointer to cell.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3of_write_a85_cell(dk3_of_t *of, dk3_of_cell_t *cp)
+{
+ int back = 0;
+ unsigned long v;
+ unsigned char bu[5];
+ $? "+ dk3of_write_a85_cell"
+ if((cp->data).a85.nc > 0) {
+ v = (cp->data).a85.val;
+ bu[0] = (unsigned char)(33UL + v / dk3of_a85_factors[0]);
+ v = v % dk3of_a85_factors[0];
+ bu[1] = (unsigned char)(33UL + v / dk3of_a85_factors[1]);
+ v = v % dk3of_a85_factors[1];
+ bu[2] = (unsigned char)(33UL + v / dk3of_a85_factors[2]);
+ v = v % dk3of_a85_factors[2];
+ bu[3] = (unsigned char)(33UL + v / dk3of_a85_factors[3]);
+ v = v % dk3of_a85_factors[3];
+ bu[4] = (unsigned char)(33UL + v); $? ". %u bytes", (unsigned)(1 + (cp->data).a85.nc)
+ back = dk3of_bytes_from_cell(cp, bu, (1 + (cp->data).a85.nc));
+ } else {
+ back = 1;
+ } $? "- dk3of_write_a85_cell %d", back
+ return back;
+}
+
+
+
+/** Save a run.
+ @param of Output filter.
+ @param cp Filter cell.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3of_psrl_save_run(dk3_of_t *of, dk3_of_cell_t *cp)
+{
+ int back = 0;
+ size_t sz;
+ unsigned char bu[2];
+
+ sz = 257 - (cp->data).psrl.used;
+ bu[0] = (unsigned char)sz;
+ bu[1] = (cp->data).psrl.pc;
+ back = dk3of_bytes_from_cell(cp, bu, 2);
+ (cp->data).psrl.used = 0;
+ (cp->data).psrl.same = 0;
+ (cp->data).psrl.pc = 0x00;
+ (cp->data).psrl.hc = 0x00;
+ (cp->data).psrl.run = 0x00;
+ return back;
+}
+
+
+
+/** Save data.
+ @param of Output filter.
+ @param cp Filter cell.
+ @param final Flag: Final action for chunk.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3of_psrl_save_data(dk3_of_t *of, dk3_of_cell_t *cp, int final)
+{
+ size_t i;
+ int back = 0;
+ unsigned char c;
+ size_t lgt;
+ $? "+ dk3of_psrl_save_data"
+ if(final) {
+ /*
+ Save data as is.
+ */
+ c = (unsigned char)((cp->data).psrl.used - 1);
+ if(dk3of_bytes_from_cell(cp, &c, 1)) {
+ if(dk3of_bytes_from_cell(cp, (cp->data).psrl.bu, (cp->data).psrl.used)) {
+ back = 1;
+ }
+ }
+ (cp->data).psrl.used = 0;
+ (cp->data).psrl.same = 0;
+ (cp->data).psrl.pc = 0x00;
+ (cp->data).psrl.hc = 0x00;
+ (cp->data).psrl.run = 0x00;
+ } else {
+ /*
+ Save data and attempt to switch into a run.
+ */
+ if((cp->data).psrl.same >= 1) {
+ if(((cp->data).psrl.same) < ((cp->data).psrl.used)) {
+ lgt = (cp->data).psrl.used - (cp->data).psrl.same - 1; $? ". lgt = %u", (unsigned)lgt
+ if(lgt > 0) {
+ c = (unsigned char)(lgt - 1);
+ if(dk3of_bytes_from_cell(cp, &c, 1)) {
+ if(dk3of_bytes_from_cell(cp, (cp->data).psrl.bu, lgt)) {
+ back = 1;
+ }
+ }
+ for(i = 0; i < (cp->data).psrl.same + 1; i++) {
+ ((cp->data).psrl.bu)[i] = ((cp->data).psrl.bu)[lgt + i];
+ }
+ (cp->data).psrl.used = (cp->data).psrl.same + 1;
+ if((cp->data).psrl.same >= 1) {
+ (cp->data).psrl.run = 0x01; $? ". now in a run"
+ }
+ } else {
+ back = 1; /* Nothing to do here. */
+ if((cp->data).psrl.same > 1) {
+ (cp->data).psrl.run = 0x01; $? ". now in a run"
+ }
+ }
+ } else { $? "! BUG"
+ }
+ } else {
+ back = dk3of_psrl_save_data(of, cp, 1);
+ }
+ } $? "- dk3of_psrl_save_data %d", back
+ return back;
+}
+
+
+
+int
+dk3of_end_chunk(dk3_of_t *of)
+{
+ dk3_of_cell_t *cellptr;
+#if DK3_HAVE_ZLIB_H
+ size_t sz;
+#endif
+ int back = 0;
+ int res;
+ $? "+ dk3of_end_chunk %!8s", TR_8PTR(of)
+ if(of) {
+ if(of->top) {
+ back = dk3of_flush_bits(of);
+ cellptr = of->top;
+ while(cellptr) {
+ switch(cellptr->type) {
+ case DK3_OF_CELL_TYPE_HEX: {
+ if((of->flags) & DK3_OF_FLAG_FINALIZE) {
+ res = dk3of_bytes_from_cell(
+ cellptr,
+ (unsigned char const *)(dk3of_kw[2]),
+ strlen(dk3of_kw[2])
+ );
+ if(!(res)) { back = 0; }
+ if(!dk3of_nl_from_cell(of, cellptr)) { back = 0; }
+ }
+ } break;
+ case DK3_OF_CELL_TYPE_A85: {
+ if(!dk3of_write_a85_cell(of, cellptr)) {
+ back = 0;
+ }
+ if((of->flags) & DK3_OF_FLAG_FINALIZE) {
+ res = dk3of_bytes_from_cell(
+ cellptr,
+ (unsigned char const *)(dk3of_kw[3]),
+ strlen(dk3of_kw[3])
+ );
+ if(!(res)) { back = 0; }
+ if(!dk3of_nl_from_cell(of, cellptr)) { back = 0; }
+ }
+ } break;
+ case DK3_OF_CELL_TYPE_RUN_LENGTH: {
+ if((cellptr->data).psrl.bu) {
+ if((cellptr->data).psrl.run) {
+ if(!dk3of_psrl_save_run(of, cellptr)) {
+ back = 0;
+ }
+ } else {
+ if(!dk3of_psrl_save_data(of, cellptr, 1)) {
+ back = 0;
+ }
+ }
+ } else {
+ back = 0;
+ }
+ } break;
+ case DK3_OF_CELL_TYPE_FLATE: {
+#if DK3_HAVE_ZLIB_H
+ int cc = 1;
+ ((cellptr->data).flate.zs)->next_in = (cellptr->data).flate.ibu;
+ ((cellptr->data).flate.zs)->avail_in = (cellptr->data).flate.iused;
+ while(cc) {
+ cc = 0;
+ ((cellptr->data).flate.zs)->next_out = (cellptr->data).flate.obu;
+ ((cellptr->data).flate.zs)->avail_out = DK3_OF_FLATE_OUT_BUFFER_SIZE;
+ res = deflate((cellptr->data).flate.zs, Z_FINISH);
+ switch(res) {
+ case Z_STREAM_END: {
+ sz = (size_t)(
+ DK3_OF_FLATE_OUT_BUFFER_SIZE
+ - ((cellptr->data).flate.zs)->avail_out
+ );
+ if(sz) {
+ if(!dk3of_bytes_from_cell(
+ cellptr,
+ (unsigned char const *)((cellptr->data).flate.obu),
+ sz
+ )
+ )
+ {
+ back = 0;
+ }
+ }
+ } break;
+ case Z_OK: {
+ cc = 1;
+ sz = (size_t)(
+ DK3_OF_FLATE_OUT_BUFFER_SIZE
+ - ((cellptr->data).flate.zs)->avail_out
+ );
+ if(sz) {
+ if(!dk3of_bytes_from_cell(
+ cellptr,
+ (unsigned char const *)((cellptr->data).flate.obu),
+ sz
+ )
+ )
+ {
+ back = 0;
+ }
+ }
+ } break;
+ default: {
+ back = 0;
+ } break;
+ }
+ }
+ if(deflateEnd((cellptr->data).flate.zs) != Z_OK) {
+ back = 0;
+ }
+ (cellptr->data).flate.iused = 0UL;
+ (cellptr->data).flate.ok = 0;
+#else
+ back = 0;
+#endif
+ } break;
+ default: {
+ back = 0;
+ /* ERROR: Illegal cell type! */
+ if(of->app) {
+ dk3app_log_i1(of->app, DK3_LL_ERROR, 263);
+ }
+ } break;
+ }
+ cellptr = cellptr->down;
+ }
+ }
+ } $? "- dk3of_end_chunk %d", back
+ return back;
+}
+
+
+
+int
+dk3of_bytes_from_cell(dk3_of_cell_t *cp, unsigned char const *bu, size_t sz)
+{
+#if VERSION_BEFORE_20150821
+ dk3_app_t *app;
+#endif
+ dk3_of_t *of;
+ int back = 0;
+ size_t bw;
+ $? "+ dk3of_bytes_from_cell %!8s %!8s %u",TR_8PTR(cp),TR_8PTR(bu),(unsigned)sz
+ if((cp) && (bu) && (sz)) {
+#if VERSION_BEFORE_20150821
+ of = NULL; app = NULL;
+#endif
+ if(cp->of) {
+ of = (dk3_of_t *)(cp->of);
+#if VERSION_BEFORE_20150821
+ if(of->app) { app = of->app; }
+#endif
+ if(cp->down) { $? ". bytes to next cell downwards"
+ back = dk3of_bytes_to_cell(cp->down, bu, sz);
+ } else { $? ". bytes to output stream"
+ if(of->os) {
+ bw = dk3stream_write_bytes(of->os, (char const *)bu, sz);
+ if(bw == sz) {
+ back = 1;
+ }
+ } else { $? "! BUG: Output filter has no destination stream!"
+ /* BUG: Output filter has no destination stream! */
+ }
+ }
+ } else { $? "! BUG: Missing output filter pointer!"
+ /* BUG: Missing output filter pointer! */
+ }
+ } $? "- dk3of_bytes_from_cell %d", back
+ return back;
+}
+
+
+
+/** Process one byte in a filter cell.
+ @param cp Filter cell.
+ @param uc Byte to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3of_one_byte_to_cell(dk3_of_cell_t *cp, unsigned char uc)
+{
+ dk3_of_t *of = NULL;
+ unsigned long ul;
+ size_t u1;
+ size_t u2;
+#if DK3_HAVE_ZLIB_H
+ size_t sz;
+ int cc;
+ int err;
+#endif
+ int back = 0;
+ unsigned char b[5];
+ $? "+ dk3of_one_byte_to_cell %x", (int)uc
+ of = (dk3_of_t *)(cp->of);
+ switch(cp->type) {
+ case DK3_OF_CELL_TYPE_HEX: { $? ". hex"
+ u1 = (size_t)uc;
+ u2 = (size_t)uc;
+ u1 = (u1 >> 4) & 0x000FU;
+ u2 = u2 & 0x000FU;
+ b[0] = (unsigned char)(dk3of_hex_chars[u1]);
+ b[1] = (unsigned char)(dk3of_hex_chars[u2]);
+ back = dk3of_bytes_from_cell(cp, b, 2);
+ (cp->data).ah.nl += 1;
+ if((cp->data).ah.nl >= 35) {
+ (cp->data).ah.nl = 0;
+ if(cp->of) {
+ of = (dk3_of_t *)(cp->of);
+ if(!dk3of_nl_from_cell(of, cp)) { back = 0; }
+ } else {
+ back = 0;
+ /* BUG: Stream not configured for cell! */
+ }
+ }
+ } break;
+ case DK3_OF_CELL_TYPE_A85: { $? ". a85"
+ ul = (unsigned long)uc;
+ switch((cp->data).a85.nc) {
+ case 0: {
+ ul = ((ul << 24) & 0xFF000000UL);
+ } break;
+ case 1: {
+ ul = ((ul << 16) & 0x00FF0000UL);
+ } break;
+ case 2: {
+ ul = ((ul << 8) & 0x0000FF00UL);
+ } break;
+ default: {
+ ul = (ul & 0x000000FFUL);
+ } break;
+ }
+ (cp->data).a85.val |= ul;
+ (cp->data).a85.nc += 1;
+ back = 1;
+ if((cp->data).a85.nc >= 4) {
+ back = dk3of_write_a85_cell(of, cp);
+ (cp->data).a85.nc = 0;
+ (cp->data).a85.val = 0UL;
+ (cp->data).a85.nl += 1;
+ if((cp->data).a85.nl >= 14) {
+ (cp->data).a85.nl = 0;
+ if(!dk3of_nl_from_cell(of, cp)) {
+ back = 0;
+ }
+ }
+ }
+ } break;
+ case DK3_OF_CELL_TYPE_RUN_LENGTH: { $? ". rl start"
+ back = 1;
+ if((cp->data).psrl.run) { $? ". have existing run"
+ if(uc == (cp->data).psrl.pc) { $? ". append to run"
+ ((cp->data).psrl.bu)[(cp->data).psrl.used] = uc;
+ (cp->data).psrl.used += 1;
+ (cp->data).psrl.same += 1;
+ if((cp->data).psrl.used >= 127) {
+ if(!dk3of_psrl_save_run(of, cp)) {
+ back = 0;
+ }
+ }
+ } else { $? ". finished run"
+ if(!dk3of_psrl_save_run(of, cp)) {
+ back = 0;
+ }
+ ((cp->data).psrl.bu)[0] = uc;
+ (cp->data).psrl.used = 1;
+ (cp->data).psrl.pc = uc;
+ (cp->data).psrl.hc = 0x01;
+ }
+ } else { $? ". no existing run"
+ ((cp->data).psrl.bu)[(cp->data).psrl.used] = uc;
+ (cp->data).psrl.used += 1;
+ if((cp->data).psrl.hc) { $? ". already contents in buffer"
+ if(uc == (cp->data).psrl.pc) { $? ". same char"
+ (cp->data).psrl.same += 1; $? ". same %u/%u", (unsigned)((cp->data).psrl.same), (unsigned)((cp->data).psrl.used)
+ } else { $? ". not the same char"
+ (cp->data).psrl.same = 0;
+ }
+ } else { $? ". no contents in buffer yet"
+ (cp->data).psrl.same = 0;
+ }
+ (cp->data).psrl.hc = 0x01;
+ (cp->data).psrl.pc = uc;
+ if(((cp->data).psrl.used >= 127) || ((cp->data).psrl.same >= 2)) {
+ if(!dk3of_psrl_save_data(of, cp, 0)) {
+ back = 0;
+ }
+ }
+ } $? ". rl end"
+ } break;
+ case DK3_OF_CELL_TYPE_FLATE: { $? ". flate"
+#if DK3_HAVE_ZLIB_H
+ if((cp->data).flate.ok) {
+ back = 1;
+ ((cp->data).flate.ibu)[(cp->data).flate.iused] = uc;
+ (cp->data).flate.iused += 1;
+ if((cp->data).flate.iused >= DK3_OF_FLATE_IN_BUFFER_SIZE) {
+ cc = 1;
+ ((cp->data).flate.zs)->next_in = (cp->data).flate.ibu;
+ ((cp->data).flate.zs)->avail_in = (cp->data).flate.iused;
+ while(cc) {
+ cc = 0;
+ ((cp->data).flate.zs)->next_out = (cp->data).flate.obu;
+ ((cp->data).flate.zs)->avail_out = DK3_OF_FLATE_OUT_BUFFER_SIZE;
+ err = deflate((cp->data).flate.zs, 0);
+ switch(err) {
+ case Z_OK: {
+ if(((cp->data).flate.zs)->avail_in) {
+ cc= 1;
+ }
+ sz = (size_t)(
+ DK3_OF_FLATE_OUT_BUFFER_SIZE
+ - ((cp->data).flate.zs)->avail_out
+ );
+ if(!dk3of_bytes_from_cell(cp, (cp->data).flate.obu, sz)) {
+ back = 0;
+ }
+ } break;
+ default: {
+ (cp->data).flate.ok = 0;
+ } break;
+ }
+ }
+ (cp->data).flate.iused = 0;
+ }
+ } else {
+ /* ERROR: Previous operations failed! */
+ if(of->app) {
+ dk3app_log_i1(of->app, DK3_LL_ERROR, 264);
+ }
+ }
+#else
+ /* ERROR: Compression not supported! */
+ if(of->app) {
+ dk3app_log_i1(of->app, DK3_LL_ERROR, 262);
+ }
+#endif
+ } break;
+ } $? "- dk3of_one_byte_to_cell %d", back
+ return back;
+}
+
+
+
+int
+dk3of_bytes_to_cell(dk3_of_cell_t *cp, unsigned char const *bu, size_t sz)
+{
+ int back = 0;
+ size_t i;
+ unsigned char const *ptr;
+ $? "+ dk3of_bytes_to_cell %!8s %!8s %u",TR_8PTR(cp),TR_8PTR(bu),(unsigned)sz
+ if((NULL != cp) && (NULL != bu) && (0 < sz)) {
+ back = 1;
+ ptr = bu;
+ for(i = 0; i < sz; i++) {
+ /* 2016-01-20
+ Static code analysis from clang complains about the
+ assigned value *(ptr++) is garbage or undefined.
+ Depends on the calling code.
+ */
+ if(!dk3of_one_byte_to_cell(cp, *(ptr++))) {
+ back = 0;
+ }
+ }
+ } $? "- dk3of_bytes_to_cell %d", back
+ return back;
+}
+
+
+
+int
+dk3of_write_bits(dk3_of_t *of, unsigned short bv, size_t sz)
+{
+ size_t i;
+ int back = 0;
+ int bit;
+ $? "+ dk3of_write_bits %u %u", (unsigned)bv, (unsigned)sz
+ if((of) && (sz)) {
+ if(sz <= 16) {
+ back = 1;
+ for(i = 0; i < sz; i++) {
+ bit = 0;
+ if(bv & dk3of_bits_in_short[sz - i - 1]) { bit = 1; }
+ if(bit) { $? ". set bit %u", (unsigned)(of->nBits)
+ of->bits = (of->bits) | (dk3of_bits_in_char[of->nBits]);
+ } else { $? ". reset bit %u", (unsigned)(of->nBits)
+ of->bits = (of->bits) & (~(dk3of_bits_in_char[of->nBits]));
+ }
+ of->nBits += 1; $? ". nBits now %u", (unsigned)(of->nBits)
+ if(of->nBits >= 8) { $? ". time to flush"
+ if(!dk3of_flush_bits(of)) { $? "! error in bit flush"
+ back = 0;
+ }
+ }
+ }
+ }
+ } $? "- dk3of_write_bits %d", back
+ return back;
+}
+
+
+
+int
+dk3of_write_bytes(dk3_of_t *of, unsigned char const *bu, size_t sz)
+{
+ int back = 0;
+ unsigned char const *ptr;
+ unsigned char uc;
+ unsigned short us;
+ size_t i;
+ $? "+ dk3of_write_bytes %!8s %u", TR_8PTR(bu), (unsigned)sz
+ if((NULL != of) && (NULL != bu) && (0 < sz)) {
+ if(of->nBits) { $? ". write bit by bit"
+ back = 1;
+ ptr = bu;
+ for(i = 0; i < sz; i++) {
+ /* 2016-01-20
+ Static code analysis from clang complains about the
+ assigned value *(ptr++) is garbage or undefined.
+ Depends on the calling code.
+ */
+ uc = *(ptr++);
+ us = (unsigned short)uc;
+ us &= 0x00FFU;
+ if(!dk3of_write_bits(of, us, 8)) {
+ back = 0;
+ }
+ }
+ } else { $? ". write bytes"
+ if(of->top) {
+ back = dk3of_bytes_to_cell(of->top, bu, sz);
+ }
+ }
+ } $? "- dk3of_write_bytes %d", back
+ return back;
+}
+
+
+
+int
+dk3of_write_c8_string(dk3_of_t *of, char const *st)
+{
+ int back = 0;
+ size_t sl;
+ if((of) && (st)) {
+ sl = strlen(st);
+ back = dk3of_write_bytes(of, (unsigned char const *)st, sl);
+ }
+ return back;
+}
+
+
+
+int
+dk3of_flush_bits(dk3_of_t *of)
+{
+ int back = 0;
+ $? "+ dk3of_flush_bits"
+ if(of) {
+ if(of->nBits) { $? ". have bits to flush %u %x", (unsigned)(of->nBits), (int)(of->bits)
+ back = dk3of_bytes_to_cell(of->top, &(of->bits), 1);
+ of->bits = 0x00;
+ of->nBits = 0;
+ } else { $? ". no bits to flush"
+ back = 1;
+ }
+ } $? "- dk3of_flush_bits %d", back
+ return back;
+}
+
+
+
+void
+dk3of_set_crnl(dk3_of_t *of, int fl)
+{
+ $? "+ dk3of_set_crnl %d", fl
+ if(of) {
+ if(fl) {
+ of->flags |= DK3_OF_FLAG_CRNL;
+ } else {
+ of->flags &= (~(DK3_OF_FLAG_CRNL));
+ }
+ } $? "- dk3of_set_crnl"
+}
+
+
+
+void
+dk3of_set_finalize(dk3_of_t *of, int fl)
+{
+ $? "+ dk3of_set_finalize %d", fl
+ if(of) {
+ if(fl) {
+ of->flags |= DK3_OF_FLAG_FINALIZE;
+ } else {
+ of->flags &= (~(DK3_OF_FLAG_FINALIZE));
+ }
+ } $? "- dk3of_set_finalize"
+}
+
+
+
+int
+dk3of_double_str_no_sci(dk3_of_t *of, char *buffer)
+{
+ char *start; /* Start of string. */
+ char *eptr; /* Start of exponent substring. */
+ char *ptr; /* Traverse string. */
+ size_t lgt; /* String length. */
+ int dp; /* Decimal dot position. */
+ int exponent; /* Exponent. */
+ int i; /* Traverse the string. */
+ char chr[2];
+ int back = 0;
+
+ chr[1] = '\0';
+ if ((NULL != of) && (NULL != buffer)) {
+ /* 2015-08-21 Set success now, errors reset back to 0 */
+ back = 1;
+ eptr = NULL;
+ start = buffer;
+ /*
+ Print sign.
+ */
+ switch(*start) {
+ case '-': {
+ chr[0] = '-';
+ if (0 == dk3of_write_c8_string(of, chr)) { back = 0; }
+ start++;
+ } break;
+ case '+': {
+ start++;
+ } break;
+ }
+ /*
+ Find exponent substring and exponent.
+ */
+ eptr = NULL;
+ ptr = start;
+ while(*ptr) {
+ switch(*ptr) {
+ case 'e': case 'E': {
+ eptr = ptr;
+ } break;
+ }
+ ptr++;
+ }
+ if(eptr) {
+ *(eptr++) = '\0';
+#if VERSION_BEFORE_20141002
+ if(sscanf(eptr, "%d", &exponent) != 1) {
+ exponent = 0;
+ }
+#else
+ if (0 == dk3ma_i_from_c8_string(&exponent, eptr, NULL)) {
+ exponent = 0;
+ }
+#endif
+ } else {
+ exponent = 0;
+ }
+ /*
+ Find decimal dot.
+ */
+ eptr = strchr(start, '.');
+ if(eptr) {
+ /*
+ Keep dot position in dp, squeeze string.
+ */
+ *eptr = '\0';
+ dp = (int)strlen(start);
+ *eptr = '.';
+ while(*eptr) {
+ eptr[0] = eptr[1];
+ eptr++;
+ }
+ } else {
+ /*
+ Dot position is after the string.
+ */
+ dp = (int)strlen(start);
+ }
+ /*
+ Correct dot position.
+ */
+ dp = dp + exponent;
+ /*
+ Remove leading zeroes (if any).
+ */
+ while('0' == *start) {
+ start++; dp--;
+ }
+ /*
+ Remove trailing zeroes (if any).
+ */
+ eptr = NULL;
+ ptr = start;
+ while(*ptr) {
+ if('0' == *ptr) {
+ if(!(eptr)) { eptr = ptr; }
+ } else {
+ eptr = NULL;
+ }
+ ptr++;
+ }
+ if(eptr) { *eptr = '\0'; }
+ lgt = strlen(start);
+ if(0 < lgt) {
+ if(dp >= (int)lgt) {
+ /*
+ Decimal dot is at end or after string.
+ */
+ if (0 == dk3of_write_c8_string(of, start)) { back = 0; }
+ /*
+ Decimal dot is after the string.
+ */
+ for(i = 0; i < (dp - (int)lgt); i++) {
+ chr[0] = '0';
+ if (0 == dk3of_write_c8_string(of, chr)) { back = 0; }
+ }
+ } else {
+ if(dp <= 0) {
+ /*
+ Decimal dot is before the string.
+ */
+ chr[0] = '0';
+ if (0 == dk3of_write_c8_string(of, chr)) { back = 0; }
+ chr[0] = '.';
+ if (0 == dk3of_write_c8_string(of, chr)) { back = 0; }
+ while(dp++ < 0) {
+ chr[0] = '0';
+ if (0 == dk3of_write_c8_string(of, chr)) { back = 0; }
+ }
+ if (0 == dk3of_write_c8_string(of, start)) { back = 0; }
+ } else {
+ /*
+ Decimal dot is in the string.
+ */
+ for(i = 0; i < (int)lgt; i++) {
+ if(dp == i) {
+ chr[0] = '.';
+ if (0 == dk3of_write_c8_string(of, chr)) { back = 0; }
+ }
+ chr[0] = start[i];
+ if (0 == dk3of_write_c8_string(of, chr)) { back = 0; }
+ }
+ }
+ }
+ } else {
+ /*
+ No non-zero digits in string.
+ */
+ chr[0] = '0';
+ if (0 == dk3of_write_c8_string(of, chr)) { back = 0; }
+ }
+#if VERSION_BEFORE_20150821
+ back = 1;
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3of_double_to_c8_no_sci(dk3_of_t *of, double x)
+{
+ char buffer[64];
+ char *ptr;
+ int back = 0;
+ if (NULL != of) {
+ sprintf(buffer, "%g", x);
+ ptr = buffer;
+ while ('\0' != *ptr) { if(',' == *ptr) { *ptr = '.'; } ptr++;}
+ back = dk3of_double_str_no_sci(of, buffer);
+ }
+ return back;
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dk3of.h b/support/dktools/dk3of.h
new file mode 100644
index 0000000000..9c44dfb868
--- /dev/null
+++ b/support/dktools/dk3of.h
@@ -0,0 +1,185 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3of.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3of.h Header file for the dk3of module.
+*/
+
+#ifndef DK3OF_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3OF_H_INCLUDED 1
+
+
+#line 10 "dk3of.ctr"
+
+#include "dk3conf.h"
+#include "dk3types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Create output filter for a stream.
+ @param os Output stream.
+ @param app Application structure for diagnostics.
+ @return Pointer to new filter on success, NULL on error.
+*/
+dk3_of_t *
+dk3of_open_app(dk3_stream_t *os, dk3_app_t *app);
+
+/** Create output filter for a stream.
+ @param os Output stream.
+ @return Pointer to new filter on success, NULL on error.
+*/
+dk3_of_t *
+dk3of_open(dk3_stream_t *os);
+
+/** Close output filter, release memory.
+ @param of Filter to delete.
+*/
+void
+dk3of_close(dk3_of_t *of);
+
+/** Add filter cell.
+ @param of Output filter.
+ @param ct Cell type (DK3_OF_CELL_TYPE_xxx).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3of_add_cell(dk3_of_t *of, int ct);
+
+/** Start data chunk.
+ @param of Output filter.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3of_start_chunk(dk3_of_t *of);
+
+/** End data chunk, flush buffers.
+ @param of Output filter.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3of_end_chunk(dk3_of_t *of);
+
+/** Write bytes to filter cell.
+ @param cp Filter cell.
+ @param bu Buffer containing the bytes.
+ @param sz Number of bytes.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3of_bytes_to_cell(dk3_of_cell_t *cp, unsigned char const *bu, size_t sz);
+
+/** Write bytes from filter cell, either to the next filter cell
+ downwards or to the destination stream.
+ @param cp Filter cell.
+ @param bu Buffer containing the bytes.
+ @param sz Number of bytes.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3of_bytes_from_cell(dk3_of_cell_t *cp, unsigned char const *bu, size_t sz);
+
+/** Write bytes to output filter.
+ @param of Output filter.
+ @param bu Buffer containing the bytes.
+ @param sz Number of bytes.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3of_write_bytes(dk3_of_t *of, unsigned char const *bu, size_t sz);
+
+/** Write string to output filter.
+ @param of Output filter.
+ @param st String to write.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3of_write_c8_string(dk3_of_t *of, char const *st);
+
+/** Write bits to output filter.
+ @param of Output filter.
+ @param bv Bit values.
+ @param sz Number of bits.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3of_write_bits(dk3_of_t *of, unsigned short bv, size_t sz);
+
+/** Flush bit buffer.
+ @param of Output filter.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3of_flush_bits(dk3_of_t *of);
+
+/** Configure use of cr/nl sequences.
+ @param of Output filter.
+ @param fl 0 for disable, any other value to enable.
+*/
+void
+dk3of_set_crnl(dk3_of_t *of, int fl);
+
+/** Configure use of finalizers.
+ @param of Output filter.
+ @param fl 0 for disable, any other value to enable.
+*/
+void
+dk3of_set_finalize(dk3_of_t *of, int fl);
+
+/** Write double number to output, avoid exponential notation.
+ @param of Output filter.
+ @param x Value to write.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3of_double_to_c8_no_sci(dk3_of_t *of, double x);
+
+/** Write double number to output.
+ @param of Output filter to write to.
+ @param buffer String buffer containing number as string.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3of_double_str_no_sci(dk3_of_t *of, char *buffer);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3opt.c b/support/dktools/dk3opt.c
new file mode 100644
index 0000000000..e7e72f2f80
--- /dev/null
+++ b/support/dktools/dk3opt.c
@@ -0,0 +1,754 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3opt.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3opt.c The dk3opt module.
+*/
+
+
+#line 168 "dk3opt.ctr"
+
+#include "dk3all.h"
+
+
+
+
+
+#line 174 "dk3opt.ctr"
+
+
+
+/** Find index of character in options set.
+ @param os Options set.
+ @param c Character to search for.
+ @param pind Pointer to destination variable.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3opt_find_index_short(
+ dk3_option_set_t const *os,
+ dkChar c,
+ size_t *pind
+)
+{
+ int back = 0;
+ size_t i;
+
+
+#line 194 "dk3opt.ctr"
+ if((os) && (pind)) {
+ if((os->options) && (os->szoptions)) {
+ for(i = 0; ((i < os->szoptions) && (back == 0)); i++) {
+ if(((os->options)[i]).so == c) {
+ *pind = i; back = 1;
+
+#line 199 "dk3opt.ctr"
+ }
+ }
+ }
+ }
+
+#line 203 "dk3opt.ctr"
+ return back;
+}
+
+
+
+/** Find index of long option in options set.
+ @param os Options set.
+ @param t Long option name to search for.
+ @param pind Pointer to destination variable.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3opt_find_index_long(
+ dk3_option_set_t const *os,
+ dkChar const *t,
+ size_t *pind
+)
+{
+ int back = 0;
+ size_t i;
+
+
+#line 225 "dk3opt.ctr"
+ if((os) && (t) && (pind)) {
+ if((os->options) && (os->szoptions)) {
+ for(i = 0; ((i < os->szoptions) && (back == 0)); i++) {
+ if(((os->options)[i]).lo) {
+ if(dk3str_cmp(((os->options)[i]).lo, t) == 0) {
+ *pind = i; back = 1;
+
+#line 231 "dk3opt.ctr"
+ }
+ }
+ }
+ }
+ }
+
+#line 236 "dk3opt.ctr"
+ return back;
+}
+
+
+
+/** Apply the command line options to the options set.
+ @param os Options set.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+*/
+static
+void
+dk3opt_apply_options(
+ dk3_option_set_t *os,
+ int argc,
+ dkChar const * const *argv
+)
+{
+ dkChar const * const *lfdptr;
+ dkChar const *ptr;
+ dkChar const *optr;
+ dkChar const *cptr;
+ int i;
+ size_t j;
+ int done;
+ dkChar bu[2 * DK3_MAX_PATH];
+ dkChar *p1;
+
+
+#line 264 "dk3opt.ctr"
+ lfdptr = argv; i = 0;
+ while(i < argc) {
+ optr = ptr = *lfdptr;
+ if(*ptr == dkT('-')) {
+
+#line 268 "dk3opt.ctr"
+ ptr++;
+ if(*ptr == dkT('-')) {
+
+#line 270 "dk3opt.ctr"
+ ptr++;
+ if(dk3str_len(ptr) < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy_not_overlapped(bu, ptr);
+ p1 = dk3str_chr(bu, dkT('='));
+ if(p1) {
+ *p1 = dkT('\0');
+ }
+ done = 0;
+ if(os->focl) {
+ if(dk3str_cmp(os->focl, bu) == 0) {
+ done = 1;
+ cptr = dk3str_chr(ptr, dkT('='));
+ if(cptr) {
+ cptr++;
+ if(!(*cptr)) {
+ cptr = NULL;
+ }
+ }
+ if(!(cptr)) {
+ lfdptr++; i++; if(i < argc) { cptr = *lfdptr; }
+ }
+ if(cptr) {
+ (os->fo)[os->fou] = cptr;
+ os->fou += 1;
+ } else {
+ /* ERROR: Option needs argument! */
+ os->ec = 1;
+ if(os->app) {
+ dk3app_log_i3(os->app, DK3_LL_ERROR, 133, 134, optr);
+ }
+ }
+ }
+ }
+ if(!done) {
+ if(dk3opt_find_index_long(os, bu, &j)) {
+ (os->found)[j] += 1;
+ if((os->found)[j] == 0) { /* Overflow */
+ (os->found)[j] = 0x7FFF;
+ }
+ if(((os->options)[j]).na) {
+ cptr = dk3str_chr(ptr, dkT('='));
+ if(cptr) { cptr++; if(!(*cptr)) { cptr = NULL; } }
+ if(!(cptr)) {
+ lfdptr++; i++; if(i < argc) { cptr = *lfdptr; }
+ }
+ if(cptr) {
+ if((os->optargs)[j]) {
+ /* Warning: Redefinition */
+ /* os->ec = 1; */
+ if(os->app) {
+ dk3app_log_i5(
+ os->app, DK3_LL_WARNING, 206, 207, 208,
+ (os->optargs)[j], cptr
+ );
+ }
+ }
+ (os->optargs)[j] = cptr;
+ } else {
+ /* ERROR: Option needs argument! */
+ os->ec = 1;
+ if(os->app) {
+ dk3app_log_i3(os->app, DK3_LL_ERROR, 133, 134, optr);
+ }
+ }
+ }
+ } else {
+ /* ERROR: Illegal option! */
+ os->ec = 1;
+ if(os->app) {
+ dk3app_log_i3(os->app, DK3_LL_ERROR, 139, 140, optr);
+ }
+ }
+ }
+ } else {
+ /* ERROR: Option too long! */
+ os->ec = 1;
+ if(os->app) {
+ dk3app_log_i3(os->app, DK3_LL_ERROR, 135, 136, optr);
+ }
+ }
+ } else {
+
+#line 351 "dk3opt.ctr"
+ if(*ptr == os->foc) {
+
+#line 352 "dk3opt.ctr"
+ ptr++;
+ if(!(*ptr)) {
+ ptr = NULL;
+ lfdptr++; i++;
+ if(i < argc) { ptr = *lfdptr; }
+ }
+ if(ptr) {
+ (os->fo)[os->fou] = ptr;
+ os->fou += 1;
+ } else {
+ /* ERROR: Option needs an argument! */
+ os->ec = 1;
+ if(os->app) {
+ dk3app_log_i3(os->app, DK3_LL_ERROR, 133, 134, optr);
+ }
+ }
+ } else {
+
+#line 369 "dk3opt.ctr"
+ if(dk3opt_find_index_short(os, *ptr, &j)) {
+ (os->found)[j] += 1;
+ if((os->found)[j] == 0) { /* Overflow */
+ (os->found)[j] = 0x7FFF;
+ }
+ if(((os->options)[j]).na) {
+ ptr++;
+ if(!(*ptr)) {
+ ptr = NULL;
+ lfdptr++; i++;
+ if(i < argc) { ptr = *lfdptr; }
+ }
+ if(ptr) {
+ if((os->optargs)[j]) {
+ /* Warning: Redefinition of option. */
+ /* os->ec = 1; */
+ if(os->app) {
+ dk3app_log_i5(
+ os->app, DK3_LL_WARNING, 206, 207, 208,
+ (os->optargs)[j], ptr
+ );
+ }
+ }
+ (os->optargs)[j] = ptr;
+ } else {
+ /* ERROR: Option needs an argument! */
+ os->ec = 1;
+ if(os->app) {
+ dk3app_log_i3(os->app, DK3_LL_ERROR, 133, 134, optr);
+ }
+ }
+ } else {
+ ptr++;
+ if(*ptr) {
+ if((os->optargs)[j]) {
+ if(os->app) {
+ dk3app_log_i5(
+ os->app, DK3_LL_WARNING, 206, 207, 208,
+ (os->optargs)[j], ptr
+ );
+ }
+ }
+ (os->optargs)[j] = ptr;
+ }
+ }
+ } else {
+ /* ERROR: Illegal option! */
+ os->ec = 1;
+ if(os->app) {
+ dk3app_log_i3(os->app, DK3_LL_ERROR, 139, 140, optr);
+ }
+ }
+ }
+ }
+ } else {
+
+#line 424 "dk3opt.ctr"
+ (os->args)[os->argsused] = ptr;
+ os->argsused += 1;
+ }
+ lfdptr++; i++;
+ }
+
+#line 429 "dk3opt.ctr"
+}
+
+
+
+dk3_option_set_t *
+dk3opt_open_app(
+ dk3_option_t const *options,
+ size_t szoptions,
+ dkChar foc,
+ dkChar const *focl,
+ int argc,
+ dkChar const * const *argv,
+ dk3_app_t *app
+)
+{
+ dk3_option_set_t *back = NULL;
+ int ok = 0;
+ int i = 0;
+ size_t j = 0;
+
+
+#line 449 "dk3opt.ctr"
+ if((options) && (szoptions)) {
+
+#line 450 "dk3opt.ctr"
+ back = dk3_new_app(dk3_option_set_t,1,app);
+ if(back) {
+
+#line 452 "dk3opt.ctr"
+ back->app = app;
+ back->options = options;
+ back->szoptions = szoptions;
+ back->found = NULL;
+ back->optargs = NULL;
+ back->args = NULL;
+ back->fo = NULL;
+ back->foc = foc;
+ back->focl = focl;
+ back->argsav = 0;
+ back->argsused = 0;
+ back->foav = 0;
+ back->fou = 0;
+ back->ec = 0;
+ back->found = dk3_new_app(int,szoptions,app);
+ if(back->found) {
+
+#line 468 "dk3opt.ctr"
+ for(j = 0; j < szoptions; j++) {
+ (back->found)[j] = 0;
+ }
+
+#line 471 "dk3opt.ctr"
+ back->optargs = dk3_new_app(DK3_PCDKCHAR,szoptions,app);
+ if(back->optargs) {
+
+#line 473 "dk3opt.ctr"
+ for(j = 0; j < szoptions; j++) {
+ (back->optargs)[j] = NULL;
+ }
+ if(argc) {
+ back->args = dk3_new_app(DK3_PCDKCHAR,argc,app);
+ if(back->args) {
+ back->argsav = argc;
+ for(i = 0; i < argc; i++) { (back->args)[i] = NULL; }
+ back->fo = dk3_new_app(DK3_PCDKCHAR,argc,app);
+ if(back->fo) {
+ back->foav = argc;
+ for(i = 0; i < argc; i++) { (back->fo)[i] = NULL; }
+ ok = 1;
+
+#line 486 "dk3opt.ctr"
+ dk3opt_apply_options(back, argc, argv);
+ }
+ }
+ } else {
+ ok = 1;
+ }
+ } else {
+
+#line 493 "dk3opt.ctr"
+ }
+ } else {
+
+#line 495 "dk3opt.ctr"
+ }
+ if(!ok) {
+ dk3opt_close(back); back = NULL;
+ }
+ if(back) {
+ if(back->ec) {
+ if(app) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 252);
+ }
+ }
+ }
+ }
+ }
+
+#line 508 "dk3opt.ctr"
+ return back;
+}
+
+
+
+dk3_option_set_t *
+dk3opt_open_from_app(
+ dk3_option_t const *options,
+ size_t szoptions,
+ dkChar foc,
+ dkChar const *focl,
+ dk3_app_t *app
+)
+{
+ dk3_option_set_t *back = NULL;
+ dkChar const * const *argv;
+ int argc;
+
+
+#line 526 "dk3opt.ctr"
+ if((options) && (szoptions) && (app)) {
+ argc = dk3app_get_argc(app);
+ argv = dk3app_get_argv(app);
+ argv++; argc--;
+ back = dk3opt_open_app(options, szoptions, foc, focl, argc, argv, app);
+ }
+
+#line 532 "dk3opt.ctr"
+ return back;
+}
+
+
+
+int
+dk3opt_is_set(
+ dk3_option_set_t const *optset,
+ dkChar shortopt
+)
+{
+ int back = 0;
+ size_t i;
+
+
+#line 546 "dk3opt.ctr"
+ if(optset) {
+ if(dk3opt_find_index_short(optset, shortopt, &i)) {
+ if(optset->found) {
+ back = (optset->found)[i];
+ }
+ }
+ }
+
+#line 553 "dk3opt.ctr"
+ return back;
+}
+
+
+
+int
+dk3opt_is_set_long(
+ dk3_option_set_t const *optset,
+ dkChar const *longopt
+)
+{
+ int back = 0;
+ size_t i;
+
+
+#line 567 "dk3opt.ctr"
+ if((optset) && (longopt)) {
+ if(dk3opt_find_index_long(optset, longopt, &i)) {
+ if(optset->found) {
+ back = (optset->found)[i];
+
+#line 571 "dk3opt.ctr"
+ }
+ }
+ }
+
+#line 574 "dk3opt.ctr"
+ return back;
+}
+
+
+
+dkChar const *
+dk3opt_get_short_arg(
+ dk3_option_set_t const *optset,
+ dkChar shortopt
+)
+{
+ dkChar const *back = NULL;
+ size_t i;
+
+
+#line 588 "dk3opt.ctr"
+ if(optset) {
+ if(dk3opt_find_index_short(optset, shortopt, &i)) {
+ if(optset->options) {
+ if(((optset->options)[i]).na) {
+ if(optset->optargs) {
+ back = (optset->optargs)[i];
+ }
+ }
+ }
+ }
+ }
+
+#line 599 "dk3opt.ctr"
+ return back;
+}
+
+
+
+dkChar const *
+dk3opt_get_long_arg(
+ dk3_option_set_t const *optset,
+ dkChar const *longopt
+)
+{
+ dkChar const *back = NULL;
+ size_t i;
+
+
+#line 613 "dk3opt.ctr"
+ if((optset) && (longopt)) {
+ if(dk3opt_find_index_long(optset, longopt, &i)) {
+ if(optset->options) {
+ if(((optset->options)[i]).na) {
+ if(optset->optargs) {
+ back = (optset->optargs)[i];
+ }
+ }
+ }
+ }
+ }
+
+#line 624 "dk3opt.ctr"
+ return back;
+}
+
+
+
+int
+dk3opt_get_num_args(
+ dk3_option_set_t const *optset
+)
+{
+ int back = 0;
+
+
+#line 636 "dk3opt.ctr"
+ if(optset) {
+ back = optset->argsused;
+ }
+
+#line 639 "dk3opt.ctr"
+ return back;
+}
+
+
+
+dkChar const *
+dk3opt_get_arg(
+ dk3_option_set_t const *optset,
+ int num
+)
+{
+ dkChar const *back = NULL;
+
+
+#line 652 "dk3opt.ctr"
+ if((optset) && (num >= 0)) {
+ if(num < optset->argsused) {
+ if(optset->args) {
+ back = (optset->args)[num];
+ }
+ }
+ }
+
+#line 659 "dk3opt.ctr"
+ return back;
+}
+
+
+
+int
+dk3opt_get_num_fo(
+ dk3_option_set_t const *os
+)
+{
+ int back = 0;
+
+
+#line 671 "dk3opt.ctr"
+ if(os) {
+ back = os->fou;
+ }
+
+#line 674 "dk3opt.ctr"
+ return back;
+}
+
+
+
+dkChar const *
+dk3opt_get_fo(
+ dk3_option_set_t const *os,
+ int num
+)
+{
+ dkChar const *back = NULL;
+
+
+#line 687 "dk3opt.ctr"
+ if((os) && (num >= 0)) {
+ if(num < os->fou) {
+ if(os->fo) {
+ back = (os->fo)[num];
+ }
+ }
+ }
+
+#line 694 "dk3opt.ctr"
+ return back;
+}
+
+
+
+void
+dk3opt_close(
+ dk3_option_set_t *os
+)
+{
+ int i;
+ size_t j;
+
+
+#line 707 "dk3opt.ctr"
+ if(os) {
+ if(os->optargs) {
+ for(j = 0; j < os->szoptions; j++) { (os->optargs)[j] = NULL; }
+
+
+#line 711 "dk3opt.ctr"
+ dk3_delete(os->optargs);
+
+
+#line 713 "dk3opt.ctr"
+ } os->optargs = NULL;
+ if(os->found) {
+ for(j = 0; j < os->szoptions; j++) { (os->found)[j] = 0;}
+
+
+#line 717 "dk3opt.ctr"
+ dk3_delete(os->found);
+
+
+#line 719 "dk3opt.ctr"
+ } os->found = NULL;
+ if(os->args) {
+ for(i = 0; i < os->argsav; i++) { (os->args)[i] = NULL; }
+
+
+#line 723 "dk3opt.ctr"
+ dk3_delete(os->args);
+
+
+#line 725 "dk3opt.ctr"
+ } os->args = NULL;
+ if(os->fo) {
+ for(i = 0; i < os->foav; i++) { (os->fo)[i] = NULL; }
+
+
+#line 729 "dk3opt.ctr"
+ dk3_delete(os->fo);
+
+
+#line 731 "dk3opt.ctr"
+ } os->fo = NULL;
+ os->options = NULL;
+ os->szoptions = 0;
+ os->argsav = os->argsused = 0;
+ os->foav = os->fou = 0;
+ os->ec = 0;
+ os->focl = NULL;
+ os->foc = dkT('\0');
+
+
+#line 740 "dk3opt.ctr"
+ dk3_delete(os);
+
+
+#line 742 "dk3opt.ctr"
+ }
+
+#line 743 "dk3opt.ctr"
+}
+
+
+
+int
+dk3opt_get_error_code(dk3_option_set_t const *os)
+{
+ int back = 0;
+ if(os) {
+ back = os->ec;
+ }
+ return back;
+}
+
+
+void
+dk3opt_reset_error_code(dk3_option_set_t *os)
+{
+ if(os) {
+ os->ec = 0;
+ }
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dk3opt.ctr b/support/dktools/dk3opt.ctr
new file mode 100644
index 0000000000..941c4c1644
--- /dev/null
+++ b/support/dktools/dk3opt.ctr
@@ -0,0 +1,769 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% header
+
+#include "dk3conf.h"
+#include "dk3types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Create new options set.
+ @param options Array of option descriptions.
+ @param szoptions Number of entries in options.
+ @param foc Character introducing a further option.
+ @param focl String introducing a further option.
+ @param argc Number of command line arguments to process.
+ @param argv Command line arguments array pointer.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to option set on success, NULL on error.
+*/
+dk3_option_set_t *
+dk3opt_open_app(
+ dk3_option_t const *options,
+ size_t szoptions,
+ dkChar foc,
+ dkChar const *focl,
+ int argc,
+ dkChar const * const *argv,
+ dk3_app_t *app
+);
+
+/** Create new options set.
+ @param options Array of option descriptions.
+ @param szoptions Number of entries in options.
+ @param foc Character to indicate a further option.
+ @param focl Long option for further options.
+ @param app Application structure.
+ @return Pointer to option set on success, NULL on error.
+*/
+dk3_option_set_t *
+dk3opt_open_from_app(
+ dk3_option_t const *options,
+ size_t szoptions,
+ dkChar foc,
+ dkChar const *focl,
+ dk3_app_t *app
+);
+
+/** Check whether or not an option is set.
+ @param optset Options set.
+ @param shortopt Option character.
+ @return 1 for option was set, 0 for option was not set.
+*/
+int
+dk3opt_is_set(
+ dk3_option_set_t const *optset,
+ dkChar shortopt
+);
+
+/** Check whether or not a long option is set.
+ @param optset Options set.
+ @param longopt Long option name string.
+ @return 1 for option was set, 0 for option was not set.
+*/
+int
+dk3opt_is_set_long(
+ dk3_option_set_t const *optset,
+ dkChar const *longopt
+);
+
+/** Get option argument.
+ @param optset Options set.
+ @param shortopt Option character.
+ @return Option argument (if any) or NULL.
+*/
+dkChar const *
+dk3opt_get_short_arg(
+ dk3_option_set_t const *optset,
+ dkChar shortopt
+);
+
+/** Get long option argument.
+ @param optset Options set.
+ @param longopt Option name.
+ @return Option argument (if any) or NULL.
+*/
+dkChar const *
+dk3opt_get_long_arg(
+ dk3_option_set_t const *optset,
+ dkChar const *longopt
+);
+
+/** Get number of command line arguments without options.
+ @param optset Options set.
+ @return Number of command line arguments.
+*/
+int
+dk3opt_get_num_args(
+ dk3_option_set_t const *optset
+);
+
+/** Get one command line argument.
+ @param optset Options set.
+ @param num Index of argument.
+ @return The argument on success, NULL on error.
+*/
+dkChar const *
+dk3opt_get_arg(
+ dk3_option_set_t const *optset,
+ int num
+);
+
+/** Get number of further options.
+ @param os Options set.
+ @return Number of further options.
+*/
+int
+dk3opt_get_num_fo(
+ dk3_option_set_t const *os
+);
+
+/** Get one further option.
+ @param os Options set.
+ @param num Index of option.
+ @return The further option on success, NULL on error.
+*/
+dkChar const *
+dk3opt_get_fo(
+ dk3_option_set_t const *os,
+ int num
+);
+
+/** Destroy option set.
+ @param os Option set to destroy.
+*/
+void
+dk3opt_close(
+ dk3_option_set_t *os
+);
+
+/** Get error code.
+ @param os Option set to check for errors.
+ @return Error code value.
+*/
+int
+dk3opt_get_error_code(dk3_option_set_t const *os);
+
+/** Reset error code.
+ @param os Option set to clean up.
+*/
+void
+dk3opt_reset_error_code(dk3_option_set_t *os);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk3all.h"
+
+
+
+$!trace-include
+
+
+
+/** Find index of character in options set.
+ @param os Options set.
+ @param c Character to search for.
+ @param pind Pointer to destination variable.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3opt_find_index_short(
+ dk3_option_set_t const *os,
+ dkChar c,
+ size_t *pind
+)
+{
+ int back = 0;
+ size_t i;
+ $? "+ dk3opt_find_index_short %!dc", c
+ if((os) && (pind)) {
+ if((os->options) && (os->szoptions)) {
+ for(i = 0; ((i < os->szoptions) && (back == 0)); i++) {
+ if(((os->options)[i]).so == c) {
+ *pind = i; back = 1; $? ". index=%u", (unsigned)i
+ }
+ }
+ }
+ } $? "- dk3opt_find_index_short %d", back
+ return back;
+}
+
+
+
+/** Find index of long option in options set.
+ @param os Options set.
+ @param t Long option name to search for.
+ @param pind Pointer to destination variable.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3opt_find_index_long(
+ dk3_option_set_t const *os,
+ dkChar const *t,
+ size_t *pind
+)
+{
+ int back = 0;
+ size_t i;
+ $? "+ dk3opt_find_index_long \"%!ds\"", TR_STR(t)
+ if((os) && (t) && (pind)) {
+ if((os->options) && (os->szoptions)) {
+ for(i = 0; ((i < os->szoptions) && (back == 0)); i++) {
+ if(((os->options)[i]).lo) {
+ if(dk3str_cmp(((os->options)[i]).lo, t) == 0) {
+ *pind = i; back = 1; $? ". index=%u", (unsigned)i
+ }
+ }
+ }
+ }
+ } $? "- dk3opt_find_index_long %d", back
+ return back;
+}
+
+
+
+/** Apply the command line options to the options set.
+ @param os Options set.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+*/
+static
+void
+dk3opt_apply_options(
+ dk3_option_set_t *os,
+ int argc,
+ dkChar const * const *argv
+)
+{
+ dkChar const * const *lfdptr;
+ dkChar const *ptr;
+ dkChar const *optr;
+ dkChar const *cptr;
+ int i;
+ size_t j;
+ int done;
+ dkChar bu[2 * DK3_MAX_PATH];
+ dkChar *p1;
+ $? "+ dk3opt_apply_options"
+ lfdptr = argv; i = 0;
+ while(i < argc) {
+ optr = ptr = *lfdptr;
+ if(*ptr == dkT('-')) { $? ". option"
+ ptr++;
+ if(*ptr == dkT('-')) { $? ". long option"
+ ptr++;
+ if(dk3str_len(ptr) < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy_not_overlapped(bu, ptr);
+ p1 = dk3str_chr(bu, dkT('='));
+ if(p1) {
+ *p1 = dkT('\0');
+ }
+ done = 0;
+ if(os->focl) {
+ if(dk3str_cmp(os->focl, bu) == 0) {
+ done = 1;
+ cptr = dk3str_chr(ptr, dkT('='));
+ if(cptr) {
+ cptr++;
+ if(!(*cptr)) {
+ cptr = NULL;
+ }
+ }
+ if(!(cptr)) {
+ lfdptr++; i++; if(i < argc) { cptr = *lfdptr; }
+ }
+ if(cptr) {
+ (os->fo)[os->fou] = cptr;
+ os->fou += 1;
+ } else {
+ /* ERROR: Option needs argument! */
+ os->ec = 1;
+ if(os->app) {
+ dk3app_log_i3(os->app, DK3_LL_ERROR, 133, 134, optr);
+ }
+ }
+ }
+ }
+ if(!done) {
+ if(dk3opt_find_index_long(os, bu, &j)) {
+ (os->found)[j] += 1;
+ if((os->found)[j] == 0) { /* Overflow */
+ (os->found)[j] = 0x7FFF;
+ }
+ if(((os->options)[j]).na) {
+ cptr = dk3str_chr(ptr, dkT('='));
+ if(cptr) { cptr++; if(!(*cptr)) { cptr = NULL; } }
+ if(!(cptr)) {
+ lfdptr++; i++; if(i < argc) { cptr = *lfdptr; }
+ }
+ if(cptr) {
+ if((os->optargs)[j]) {
+ /* Warning: Redefinition */
+ /* os->ec = 1; */
+ if(os->app) {
+ dk3app_log_i5(
+ os->app, DK3_LL_WARNING, 206, 207, 208,
+ (os->optargs)[j], cptr
+ );
+ }
+ }
+ (os->optargs)[j] = cptr;
+ } else {
+ /* ERROR: Option needs argument! */
+ os->ec = 1;
+ if(os->app) {
+ dk3app_log_i3(os->app, DK3_LL_ERROR, 133, 134, optr);
+ }
+ }
+ }
+ } else {
+ /* ERROR: Illegal option! */
+ os->ec = 1;
+ if(os->app) {
+ dk3app_log_i3(os->app, DK3_LL_ERROR, 139, 140, optr);
+ }
+ }
+ }
+ } else {
+ /* ERROR: Option too long! */
+ os->ec = 1;
+ if(os->app) {
+ dk3app_log_i3(os->app, DK3_LL_ERROR, 135, 136, optr);
+ }
+ }
+ } else { $? ". short option"
+ if(*ptr == os->foc) { $? ". a further option"
+ ptr++;
+ if(!(*ptr)) {
+ ptr = NULL;
+ lfdptr++; i++;
+ if(i < argc) { ptr = *lfdptr; }
+ }
+ if(ptr) {
+ (os->fo)[os->fou] = ptr;
+ os->fou += 1;
+ } else {
+ /* ERROR: Option needs an argument! */
+ os->ec = 1;
+ if(os->app) {
+ dk3app_log_i3(os->app, DK3_LL_ERROR, 133, 134, optr);
+ }
+ }
+ } else { $? ". normal option"
+ if(dk3opt_find_index_short(os, *ptr, &j)) {
+ (os->found)[j] += 1;
+ if((os->found)[j] == 0) { /* Overflow */
+ (os->found)[j] = 0x7FFF;
+ }
+ if(((os->options)[j]).na) {
+ ptr++;
+ if(!(*ptr)) {
+ ptr = NULL;
+ lfdptr++; i++;
+ if(i < argc) { ptr = *lfdptr; }
+ }
+ if(ptr) {
+ if((os->optargs)[j]) {
+ /* Warning: Redefinition of option. */
+ /* os->ec = 1; */
+ if(os->app) {
+ dk3app_log_i5(
+ os->app, DK3_LL_WARNING, 206, 207, 208,
+ (os->optargs)[j], ptr
+ );
+ }
+ }
+ (os->optargs)[j] = ptr;
+ } else {
+ /* ERROR: Option needs an argument! */
+ os->ec = 1;
+ if(os->app) {
+ dk3app_log_i3(os->app, DK3_LL_ERROR, 133, 134, optr);
+ }
+ }
+ } else {
+ ptr++;
+ if(*ptr) {
+ if((os->optargs)[j]) {
+ if(os->app) {
+ dk3app_log_i5(
+ os->app, DK3_LL_WARNING, 206, 207, 208,
+ (os->optargs)[j], ptr
+ );
+ }
+ }
+ (os->optargs)[j] = ptr;
+ }
+ }
+ } else {
+ /* ERROR: Illegal option! */
+ os->ec = 1;
+ if(os->app) {
+ dk3app_log_i3(os->app, DK3_LL_ERROR, 139, 140, optr);
+ }
+ }
+ }
+ }
+ } else { $? ". file name"
+ (os->args)[os->argsused] = ptr;
+ os->argsused += 1;
+ }
+ lfdptr++; i++;
+ } $? "- dk3opt_apply_options"
+}
+
+
+
+dk3_option_set_t *
+dk3opt_open_app(
+ dk3_option_t const *options,
+ size_t szoptions,
+ dkChar foc,
+ dkChar const *focl,
+ int argc,
+ dkChar const * const *argv,
+ dk3_app_t *app
+)
+{
+ dk3_option_set_t *back = NULL;
+ int ok = 0;
+ int i = 0;
+ size_t j = 0;
+ $? "+ dk3opt_open_app"
+ if((options) && (szoptions)) { $? ". args ok"
+ back = dk3_new_app(dk3_option_set_t,1,app);
+ if(back) { $? ". back ok"
+ back->app = app;
+ back->options = options;
+ back->szoptions = szoptions;
+ back->found = NULL;
+ back->optargs = NULL;
+ back->args = NULL;
+ back->fo = NULL;
+ back->foc = foc;
+ back->focl = focl;
+ back->argsav = 0;
+ back->argsused = 0;
+ back->foav = 0;
+ back->fou = 0;
+ back->ec = 0;
+ back->found = dk3_new_app(int,szoptions,app);
+ if(back->found) { $? ". back->found ok cleaning"
+ for(j = 0; j < szoptions; j++) {
+ (back->found)[j] = 0;
+ } $? ". cleaning finished, going to allocate optargs"
+ back->optargs = dk3_new_app(DK3_PCDKCHAR,szoptions,app);
+ if(back->optargs) { $? ". back->optargs ok"
+ for(j = 0; j < szoptions; j++) {
+ (back->optargs)[j] = NULL;
+ }
+ if(argc) {
+ back->args = dk3_new_app(DK3_PCDKCHAR,argc,app);
+ if(back->args) {
+ back->argsav = argc;
+ for(i = 0; i < argc; i++) { (back->args)[i] = NULL; }
+ back->fo = dk3_new_app(DK3_PCDKCHAR,argc,app);
+ if(back->fo) {
+ back->foav = argc;
+ for(i = 0; i < argc; i++) { (back->fo)[i] = NULL; }
+ ok = 1; $? ". all memory ok"
+ dk3opt_apply_options(back, argc, argv);
+ }
+ }
+ } else {
+ ok = 1;
+ }
+ } else { $? "! back->optargs"
+ }
+ } else { $? "! back->found"
+ }
+ if(!ok) {
+ dk3opt_close(back); back = NULL;
+ }
+ if(back) {
+ if(back->ec) {
+ if(app) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 252);
+ }
+ }
+ }
+ }
+ } $? "- dk3opt_open_app %s", TR_PTR(back)
+ return back;
+}
+
+
+
+dk3_option_set_t *
+dk3opt_open_from_app(
+ dk3_option_t const *options,
+ size_t szoptions,
+ dkChar foc,
+ dkChar const *focl,
+ dk3_app_t *app
+)
+{
+ dk3_option_set_t *back = NULL;
+ dkChar const * const *argv;
+ int argc;
+ $? "+ dk3opt_open_from_app"
+ if((options) && (szoptions) && (app)) {
+ argc = dk3app_get_argc(app);
+ argv = dk3app_get_argv(app);
+ argv++; argc--;
+ back = dk3opt_open_app(options, szoptions, foc, focl, argc, argv, app);
+ } $? "- dk3opt_open_from_app %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+int
+dk3opt_is_set(
+ dk3_option_set_t const *optset,
+ dkChar shortopt
+)
+{
+ int back = 0;
+ size_t i;
+ $? "+ dk3opt_is_set %!dc", shortopt
+ if(optset) {
+ if(dk3opt_find_index_short(optset, shortopt, &i)) {
+ if(optset->found) {
+ back = (optset->found)[i];
+ }
+ }
+ } $? "- dk3opt_is_set %d", back
+ return back;
+}
+
+
+
+int
+dk3opt_is_set_long(
+ dk3_option_set_t const *optset,
+ dkChar const *longopt
+)
+{
+ int back = 0;
+ size_t i;
+ $? "+ dk3opt_is_set_long \"%!ds\"", TR_STR(longopt)
+ if((optset) && (longopt)) {
+ if(dk3opt_find_index_long(optset, longopt, &i)) {
+ if(optset->found) {
+ back = (optset->found)[i]; $? ". index=%u", (unsigned)i
+ }
+ }
+ } $? "- dk3opt_is_set_long %d", back
+ return back;
+}
+
+
+
+dkChar const *
+dk3opt_get_short_arg(
+ dk3_option_set_t const *optset,
+ dkChar shortopt
+)
+{
+ dkChar const *back = NULL;
+ size_t i;
+ $? "+ dk3opt_get_short_arg %!dc", shortopt
+ if(optset) {
+ if(dk3opt_find_index_short(optset, shortopt, &i)) {
+ if(optset->options) {
+ if(((optset->options)[i]).na) {
+ if(optset->optargs) {
+ back = (optset->optargs)[i];
+ }
+ }
+ }
+ }
+ } $? "- dk3opt_get_short_arg \"%!ds\"", TR_STR(back)
+ return back;
+}
+
+
+
+dkChar const *
+dk3opt_get_long_arg(
+ dk3_option_set_t const *optset,
+ dkChar const *longopt
+)
+{
+ dkChar const *back = NULL;
+ size_t i;
+ $? "+ dk3opt_get_long_arg \"%!ds\"", TR_STR(longopt)
+ if((optset) && (longopt)) {
+ if(dk3opt_find_index_long(optset, longopt, &i)) {
+ if(optset->options) {
+ if(((optset->options)[i]).na) {
+ if(optset->optargs) {
+ back = (optset->optargs)[i];
+ }
+ }
+ }
+ }
+ } $? "- dk3opt_get_long_arg \"%!ds\"", TR_STR(back)
+ return back;
+}
+
+
+
+int
+dk3opt_get_num_args(
+ dk3_option_set_t const *optset
+)
+{
+ int back = 0;
+ $? "+ dk3opt_get_num_args"
+ if(optset) {
+ back = optset->argsused;
+ } $? "- dk3opt_get_num_args %d", back
+ return back;
+}
+
+
+
+dkChar const *
+dk3opt_get_arg(
+ dk3_option_set_t const *optset,
+ int num
+)
+{
+ dkChar const *back = NULL;
+ $? "+ dk3opt_get_arg %d", num
+ if((optset) && (num >= 0)) {
+ if(num < optset->argsused) {
+ if(optset->args) {
+ back = (optset->args)[num];
+ }
+ }
+ } $? "- dk3opt_get_arg \"%!ds\"", TR_STR(back)
+ return back;
+}
+
+
+
+int
+dk3opt_get_num_fo(
+ dk3_option_set_t const *os
+)
+{
+ int back = 0;
+ $? "+ dk3opt_get_num_fo"
+ if(os) {
+ back = os->fou;
+ } $? "- dk3opt_get_num_fo %d", back
+ return back;
+}
+
+
+
+dkChar const *
+dk3opt_get_fo(
+ dk3_option_set_t const *os,
+ int num
+)
+{
+ dkChar const *back = NULL;
+ $? "+ dk3opt_get_fo %d", num
+ if((os) && (num >= 0)) {
+ if(num < os->fou) {
+ if(os->fo) {
+ back = (os->fo)[num];
+ }
+ }
+ } $? "- dk3opt_get_fo \"%!ds\"", TR_STR(back)
+ return back;
+}
+
+
+
+void
+dk3opt_close(
+ dk3_option_set_t *os
+)
+{
+ int i;
+ size_t j;
+ $? "+ dk3opt_close"
+ if(os) {
+ if(os->optargs) {
+ for(j = 0; j < os->szoptions; j++) { (os->optargs)[j] = NULL; }
+ $? ". del optargs +"
+ dk3_delete(os->optargs);
+ $? ". del optargs -"
+ } os->optargs = NULL;
+ if(os->found) {
+ for(j = 0; j < os->szoptions; j++) { (os->found)[j] = 0;}
+ $? ". del found +"
+ dk3_delete(os->found);
+ $? ". del found -"
+ } os->found = NULL;
+ if(os->args) {
+ for(i = 0; i < os->argsav; i++) { (os->args)[i] = NULL; }
+ $? ". del args +"
+ dk3_delete(os->args);
+ $? ". del args -"
+ } os->args = NULL;
+ if(os->fo) {
+ for(i = 0; i < os->foav; i++) { (os->fo)[i] = NULL; }
+ $? ". del fo +"
+ dk3_delete(os->fo);
+ $? ". del fo -"
+ } os->fo = NULL;
+ os->options = NULL;
+ os->szoptions = 0;
+ os->argsav = os->argsused = 0;
+ os->foav = os->fou = 0;
+ os->ec = 0;
+ os->focl = NULL;
+ os->foc = dkT('\0');
+ $? ". del os +"
+ dk3_delete(os);
+ $? ". del os -"
+ } $? "- dk3opt_close"
+}
+
+
+
+int
+dk3opt_get_error_code(dk3_option_set_t const *os)
+{
+ int back = 0;
+ if(os) {
+ back = os->ec;
+ }
+ return back;
+}
+
+
+void
+dk3opt_reset_error_code(dk3_option_set_t *os)
+{
+ if(os) {
+ os->ec = 0;
+ }
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dk3opt.h b/support/dktools/dk3opt.h
new file mode 100644
index 0000000000..826019559e
--- /dev/null
+++ b/support/dktools/dk3opt.h
@@ -0,0 +1,203 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3opt.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3opt.h Header file for the dk3opt module.
+*/
+
+#ifndef DK3OPT_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3OPT_H_INCLUDED 1
+
+
+#line 10 "dk3opt.ctr"
+
+#include "dk3conf.h"
+#include "dk3types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Create new options set.
+ @param options Array of option descriptions.
+ @param szoptions Number of entries in options.
+ @param foc Character introducing a further option.
+ @param focl String introducing a further option.
+ @param argc Number of command line arguments to process.
+ @param argv Command line arguments array pointer.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to option set on success, NULL on error.
+*/
+dk3_option_set_t *
+dk3opt_open_app(
+ dk3_option_t const *options,
+ size_t szoptions,
+ dkChar foc,
+ dkChar const *focl,
+ int argc,
+ dkChar const * const *argv,
+ dk3_app_t *app
+);
+
+/** Create new options set.
+ @param options Array of option descriptions.
+ @param szoptions Number of entries in options.
+ @param foc Character to indicate a further option.
+ @param focl Long option for further options.
+ @param app Application structure.
+ @return Pointer to option set on success, NULL on error.
+*/
+dk3_option_set_t *
+dk3opt_open_from_app(
+ dk3_option_t const *options,
+ size_t szoptions,
+ dkChar foc,
+ dkChar const *focl,
+ dk3_app_t *app
+);
+
+/** Check whether or not an option is set.
+ @param optset Options set.
+ @param shortopt Option character.
+ @return 1 for option was set, 0 for option was not set.
+*/
+int
+dk3opt_is_set(
+ dk3_option_set_t const *optset,
+ dkChar shortopt
+);
+
+/** Check whether or not a long option is set.
+ @param optset Options set.
+ @param longopt Long option name string.
+ @return 1 for option was set, 0 for option was not set.
+*/
+int
+dk3opt_is_set_long(
+ dk3_option_set_t const *optset,
+ dkChar const *longopt
+);
+
+/** Get option argument.
+ @param optset Options set.
+ @param shortopt Option character.
+ @return Option argument (if any) or NULL.
+*/
+dkChar const *
+dk3opt_get_short_arg(
+ dk3_option_set_t const *optset,
+ dkChar shortopt
+);
+
+/** Get long option argument.
+ @param optset Options set.
+ @param longopt Option name.
+ @return Option argument (if any) or NULL.
+*/
+dkChar const *
+dk3opt_get_long_arg(
+ dk3_option_set_t const *optset,
+ dkChar const *longopt
+);
+
+/** Get number of command line arguments without options.
+ @param optset Options set.
+ @return Number of command line arguments.
+*/
+int
+dk3opt_get_num_args(
+ dk3_option_set_t const *optset
+);
+
+/** Get one command line argument.
+ @param optset Options set.
+ @param num Index of argument.
+ @return The argument on success, NULL on error.
+*/
+dkChar const *
+dk3opt_get_arg(
+ dk3_option_set_t const *optset,
+ int num
+);
+
+/** Get number of further options.
+ @param os Options set.
+ @return Number of further options.
+*/
+int
+dk3opt_get_num_fo(
+ dk3_option_set_t const *os
+);
+
+/** Get one further option.
+ @param os Options set.
+ @param num Index of option.
+ @return The further option on success, NULL on error.
+*/
+dkChar const *
+dk3opt_get_fo(
+ dk3_option_set_t const *os,
+ int num
+);
+
+/** Destroy option set.
+ @param os Option set to destroy.
+*/
+void
+dk3opt_close(
+ dk3_option_set_t *os
+);
+
+/** Get error code.
+ @param os Option set to check for errors.
+ @return Error code value.
+*/
+int
+dk3opt_get_error_code(dk3_option_set_t const *os);
+
+/** Reset error code.
+ @param os Option set to clean up.
+*/
+void
+dk3opt_reset_error_code(dk3_option_set_t *os);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3paper.c b/support/dktools/dk3paper.c
new file mode 100644
index 0000000000..e62f58e52c
--- /dev/null
+++ b/support/dktools/dk3paper.c
@@ -0,0 +1,542 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3paper.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3paper.c The dk3paper module.
+*/
+
+
+#line 57 "dk3paper.ctr"
+
+#include "dk3all.h"
+#include "dk3paper.h"
+
+
+
+
+
+#line 64 "dk3paper.ctr"
+
+
+
+/** Built-in named paper sizes, may be overwritten in configuration files.
+*/
+static dkChar const * const dk3paper_default_sizes[] = {
+dkT("A4\t\t=\t595\t842"),
+dkT("Letter\t\t=\t612\t792"),
+dkT("a4\t\t=\t595\t842\t56\t28\t14\t14"),
+dkT("letter\t\t=\t612\t792\t56\t28\t14\t14"),
+NULL
+
+
+#line 76 "dk3paper.ctr"
+};
+
+
+
+/** File name for configuration file.
+*/
+static dkChar const dk3paper_config_file_name[] = { dkT("dk3paper.conf") };
+
+
+
+/** Delete named paper size, release memory.
+ @param nps Data to delete.
+*/
+static
+void
+dk3paper_nps_delete(dk3_named_paper_size_t *nps)
+{
+
+
+#line 94 "dk3paper.ctr"
+ if(nps->name) {
+ dk3_release(nps->name);
+ }
+ dk3_delete(nps);
+
+
+#line 99 "dk3paper.ctr"
+}
+
+
+
+/** Create named paper size structure, allocate memory.
+ @param app Application structure for diagnostics.
+ @param name Paper size name.
+ @return Pointer to new paper size on success, NULL on error.
+*/
+static
+dk3_named_paper_size_t *
+dk3paper_nps_new(dk3_app_t *app, dkChar const *name)
+{
+ dk3_named_paper_size_t *back = NULL;
+
+
+#line 114 "dk3paper.ctr"
+ if((app) && (name)) {
+ back = dk3_new_app(dk3_named_paper_size_t,1,app);
+ if(back) {
+ back->name = NULL;
+ (back->size).w = (back->size).h = 0.0;
+ (back->size).i = (back->size).o = (back->size).t = (back->size).b = 0.0;
+ back->name = dk3str_dup_app(name, app);
+ if(!(back->name)) {
+ dk3paper_nps_delete(back); back = NULL;
+ }
+ }
+ }
+
+#line 126 "dk3paper.ctr"
+ return back;
+}
+
+
+
+/** Compare two named paper sizes by name.
+ @param l Left structure.
+ @param r Right structure.
+ @param cr Comparison criteria (0=size/size, 1=size/name).
+ @return Comparison result.
+*/
+static
+int
+dk3paper_nps_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3_named_paper_size_t const *pl; /* Pointer to left structure. */
+ dk3_named_paper_size_t const *pr; /* Pointer to right structure. */
+ if(l) {
+ if(r) {
+ pl = (dk3_named_paper_size_t const *)l;
+ switch(cr) {
+ case 1: {
+ /*
+ Compare structure against a name string.
+ */
+ if(pl->name) {
+ back = dk3str_cmp(pl->name, (dkChar const *)r);
+ } else {
+ back = -1;
+ }
+ } break;
+ default: {
+ /*
+ Compare two structures by name.
+ */
+ pr = (dk3_named_paper_size_t const *)r;
+ if(pl->name) {
+ if(pr->name) {
+ back = dk3str_cmp(pl->name, pr->name);
+ } else {
+ back = 1;
+ }
+ } else {
+ if(pr->name) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+ if(back < -1) back = -1;
+ if(back > 1) back = 1;
+ return back;
+}
+
+
+
+/** Set values in a named paper size.
+ @param np Named paper size.
+ @param v Values array.
+ @param num Number of values (2 or 6).
+ Width and height are mandatory, borders are
+ optional.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3paper_set_values(dk3_named_paper_size_t *np, double const *v, size_t num)
+{
+ int back = 0;
+
+
+#line 205 "dk3paper.ctr"
+ (np->size).i = (np->size).o = (np->size).t = (np->size).b = 0.0;
+ (np->size).w = v[0]; (np->size).h = v[1];
+ if(num > 2) {
+ (np->size).i = v[2]; (np->size).o = v[3];
+ (np->size).t = v[4]; (np->size).b = v[5];
+ }
+ /*
+ Indicate success only if all values are reasonable.
+ */
+ if((np->size).w > 0.0) {
+ if((np->size).h > 0.0) {
+ if((np->size).i >= 0.0) {
+ if((np->size).o >= 0.0) {
+ if((np->size).t >= 0.0) {
+ if((np->size).b >= 0.0) {
+ back = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+
+#line 227 "dk3paper.ctr"
+ return back;
+}
+
+
+
+/** Handler function for one configuration file line.
+ @param obj Paper size collection.
+ @param il Input line to process.
+ @return 1 for OK, 0 for recoverable error, -1 for abort.
+*/
+static
+int
+dk3paper_const_line_handler(void *obj, dkChar const *il)
+{
+ dkChar bu[DK3_PAPER_CONFIG_LINE_SIZE]; /* Private copy. */
+ dkChar *parts[16]; /* Split number sequence. */
+ double v[8]; /* Values from text line. */
+ dk3_paper_size_collection_t *psc; /* Paper size collection. */
+ dk3_named_paper_size_t *np; /* Paper size to edit. */
+ dkChar *p1; /* Paper size name. */
+ dkChar *p2; /* Values for that size. */
+ size_t nparts; /* Number of values. */
+ size_t i; /* Traverse all values. */
+ int back = 1;
+ int res = 0; /* Flag: No reporting necessary. */
+
+
+#line 253 "dk3paper.ctr"
+ if((obj) && (il)) {
+
+#line 254 "dk3paper.ctr"
+ psc = (dk3_paper_size_collection_t *)obj;
+ if(dk3str_len(il) < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy_not_overlapped(bu, il);
+ p1 = dk3str_start(bu, NULL);
+ if(p1) {
+ if(*p1 != dkT('#')) {
+ p2 = dk3str_chr(p1, dkT('='));
+ if(p2) {
+ *(p2++) = dkT('\0');
+ p2 = dk3str_start(p2, NULL);
+ if(p2) {
+ dk3str_chomp(p1, NULL);
+ nparts = dk3str_explode(parts, 15, p2, NULL);
+ if((nparts == 2) || (nparts == 6)) {
+ /*
+ Line syntax ok so far.
+ */
+ res = 1;
+ /*
+ Read double value from all text words.
+ */
+ for(i = 0; i < nparts; i++) {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(parts[i], dkT("%lg"), &(v[i])) != 1)
+#else
+ /* Bugfix 2014-09-01: If the action fails, the
+ res variable is set to failure, not on success.
+ */
+#if VERSION_BEFORE_20140901
+/* WRONG*/ if (dk3ma_d_from_string(&(v[i]), parts[i], NULL))
+#else
+/* OK */ if (0 == dk3ma_d_from_string(&(v[i]), parts[i], NULL))
+#endif
+#endif
+ {
+ res = 0;
+ }
+ }
+ if(res) {
+ if(dk3str_len(p1) > 0) {
+ /*
+ Attempt to find existing size for that name.
+ */
+ np = (dk3_named_paper_size_t *)dk3sto_it_find_like(
+ psc->i_sizes, (void *)p1, 1
+ );
+ if(np) {
+ /*
+ Entry exists, reconfigure entry.
+ */
+ res = dk3paper_set_values(np, v, nparts);
+ } else {
+ /*
+ Create new entry.
+ */
+ np = dk3paper_nps_new(psc->app, p1);
+ if(np) {
+ if(dk3sto_add(psc->s_sizes, (void *)np)) {
+ res = dk3paper_set_values(np, v, nparts);
+ } else {
+ /* ERROR: Memory */
+ dk3paper_nps_delete(np); np = NULL;
+ back = 0;
+ }
+ } else {
+ /* ERROR: Memory */
+ back = 0;
+ }
+ }
+ } else { res = 0; }
+ }
+ }
+ }
+ }
+ } else { res = 1; }
+ } else { res = 1; }
+ if(!(res)) {
+ /* ERROR: Syntax */
+ dk3str_cpy_not_overlapped(bu, il);
+ dk3str_normalize(bu, NULL, dkT(' '));
+ dk3app_log_i3(psc->app, DK3_LL_ERROR, 211, 212, bu);
+ }
+ }
+ }
+
+#line 338 "dk3paper.ctr"
+ return back;
+}
+
+
+
+/** Handler function for one configuration file line.
+ @param obj Paper size collection.
+ @param il Input line to process.
+ @return 1 for OK, 0 for recoverable error, -1 for abort.
+*/
+static
+int
+dk3paper_line_handler(void *obj, dkChar *il)
+{
+ int back;
+ back = dk3paper_const_line_handler(obj, il);
+ return back;
+}
+
+
+
+dk3_paper_size_collection_t *
+dk3paper_open_app(dk3_app_t *app)
+{
+ dkChar bu[DK3_PAPER_CONFIG_LINE_SIZE]; /* Buffer. */
+ dk3_paper_size_collection_t *back = NULL;
+ dk3_search_t *sr;
+ dkChar const *fn;
+ dkChar const * const *lfdptr;
+ int ok = 0;
+ int res;
+ int de;
+ int se;
+
+
+#line 372 "dk3paper.ctr"
+ if(app) {
+ back = dk3_new_app(dk3_paper_size_collection_t,1,app);
+ if(back) {
+
+#line 375 "dk3paper.ctr"
+ back->app = app;
+ back->s_sizes = NULL; back->i_sizes = NULL;
+ back->s_sizes = dk3sto_open_app(app);
+ if(back->s_sizes) {
+
+#line 379 "dk3paper.ctr"
+ dk3sto_set_comp(back->s_sizes, dk3paper_nps_compare, 0);
+ back->i_sizes = dk3sto_it_open(back->s_sizes);
+ if(back->i_sizes) {
+
+#line 382 "dk3paper.ctr"
+ ok = 1;
+ /*
+ Read built-in lines.
+ */
+ lfdptr = dk3paper_default_sizes;
+ while(*lfdptr) {
+
+#line 388 "dk3paper.ctr"
+ if(!dk3paper_const_line_handler((void *)back, *lfdptr)) {
+ ok = 0;
+
+#line 390 "dk3paper.ctr"
+ }
+ lfdptr++;
+ }
+ /*
+ Read configuration files.
+ */
+ sr = dk3app_find_config_file(app, dk3paper_config_file_name, 0);
+ if(sr) {
+
+#line 398 "dk3paper.ctr"
+ dk3search_reset(sr);
+ se = dk3app_get_encoding(app);
+ de = dk3app_get_input_file_encoding(app);
+ while((fn = dk3search_next(sr)) != NULL) {
+
+
+#line 403 "dk3paper.ctr"
+ res = dk3stream_process_filename_lines_app(
+ (void *)back, dk3paper_line_handler, fn,
+ bu, DK3_SIZEOF(bu,dkChar), se, de, app
+ );
+ if(!(res)) {
+ ok = 0;
+ }
+ }
+ dk3search_close(sr);
+ } else {
+
+#line 413 "dk3paper.ctr"
+ }
+ } else {
+
+#line 415 "dk3paper.ctr"
+ }
+ } else {
+
+#line 417 "dk3paper.ctr"
+ }
+ if(!(ok)) {
+ dk3paper_close(back); back = NULL;
+ }
+ } else {
+
+#line 422 "dk3paper.ctr"
+ }
+ }
+
+#line 424 "dk3paper.ctr"
+ return back;
+}
+
+
+
+void
+dk3paper_close(dk3_paper_size_collection_t *psc)
+{
+ dk3_named_paper_size_t *nps; /* Current size to release. */
+
+
+#line 434 "dk3paper.ctr"
+ if(psc) {
+ if(psc->s_sizes) {
+ if(psc->i_sizes) {
+ dk3sto_it_reset(psc->i_sizes);
+ while((nps = (dk3_named_paper_size_t *)dk3sto_it_next(psc->i_sizes))
+ != NULL
+ )
+ {
+ dk3paper_nps_delete(nps);
+ }
+ dk3sto_it_close(psc->i_sizes);
+ }
+ dk3sto_close(psc->s_sizes);
+ }
+ psc->s_sizes = NULL;
+ psc->app = NULL;
+ dk3_delete(psc);
+ }
+
+#line 452 "dk3paper.ctr"
+}
+
+
+dk3_paper_size_t const *
+dk3paper_find(dk3_paper_size_collection_t *psc, dkChar const *psn)
+{
+ dk3_paper_size_t const *back = NULL;
+ dk3_named_paper_size_t *nps; /* Named size. */
+
+
+#line 461 "dk3paper.ctr"
+ if((psc) && (psn)) {
+ nps = (dk3_named_paper_size_t *)dk3sto_it_find_like(
+ psc->i_sizes, (void *)psn, 1
+ );
+ if(nps) {
+
+#line 466 "dk3paper.ctr"
+ back = (dk3_paper_size_t const *)(&(nps->size));
+ }
+ }
+
+#line 469 "dk3paper.ctr"
+ return back;
+}
+
+
+
+void
+dk3paper_reset(dk3_paper_size_collection_t *psc)
+{
+ if(psc) {
+ if(psc->i_sizes) {
+ dk3sto_it_reset(psc->i_sizes);
+ }
+ }
+}
+
+
+
+
+dk3_named_paper_size_t const *
+dk3paper_next(dk3_paper_size_collection_t *psc)
+{
+ dk3_named_paper_size_t const *back = NULL;
+ if(psc) {
+ if(psc->i_sizes) {
+ back = (dk3_named_paper_size_t const *)dk3sto_it_next(psc->i_sizes);
+ }
+ }
+ return back;
+}
+
+
+
diff --git a/support/dktools/dk3paper.ctr b/support/dktools/dk3paper.ctr
new file mode 100644
index 0000000000..8028257945
--- /dev/null
+++ b/support/dktools/dk3paper.ctr
@@ -0,0 +1,500 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Create paper sizes collection, read dk3paper.conf files.
+ @param app Application structure for diagnostics and file search,
+ must not be NULL.
+ @return Pointer to new collection on success, NULL on error.
+*/
+dk3_paper_size_collection_t *
+dk3paper_open_app(dk3_app_t *app);
+
+/** Find paper size by name.
+ @param psc Paper size collection.
+ @param psn Paper size name.
+ @return Pointer to paper size on success, NULL on error.
+*/
+dk3_paper_size_t const *
+dk3paper_find(dk3_paper_size_collection_t *psc, dkChar const *psn);
+
+/** Close paper size collection, release memory.
+ @param psc Collection to close.
+*/
+void
+dk3paper_close(dk3_paper_size_collection_t *psc);
+
+/** Prepare traversing the paper size collection for named paper sizes.
+ @param psc Paper size collection.
+*/
+void
+dk3paper_reset(dk3_paper_size_collection_t *psc);
+
+/** Retrieve next named paper size from size collection.
+ @param psc Paper size collection.
+ @return Pointer to named paper size on success, NULL on error/end.
+*/
+dk3_named_paper_size_t const *
+dk3paper_next(dk3_paper_size_collection_t *psc);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk3all.h"
+#include "dk3paper.h"
+
+
+
+$!trace-include
+
+
+
+/** Built-in named paper sizes, may be overwritten in configuration files.
+*/
+static dkChar const * const dk3paper_default_sizes[] = {
+$!text macro=dkT
+A4 = 595 842
+Letter = 612 792
+a4 = 595 842 56 28 14 14
+letter = 612 792 56 28 14 14
+$!end
+};
+
+
+
+/** File name for configuration file.
+*/
+static dkChar const dk3paper_config_file_name[] = { dkT("dk3paper.conf") };
+
+
+
+/** Delete named paper size, release memory.
+ @param nps Data to delete.
+*/
+static
+void
+dk3paper_nps_delete(dk3_named_paper_size_t *nps)
+{
+ $? "+ dk3paper_nps_delete \"%!ds\"", TR_STR(nps->name)
+ if(nps->name) {
+ dk3_release(nps->name);
+ }
+ dk3_delete(nps);
+ $? "- dk3paper_nps_delete"
+}
+
+
+
+/** Create named paper size structure, allocate memory.
+ @param app Application structure for diagnostics.
+ @param name Paper size name.
+ @return Pointer to new paper size on success, NULL on error.
+*/
+static
+dk3_named_paper_size_t *
+dk3paper_nps_new(dk3_app_t *app, dkChar const *name)
+{
+ dk3_named_paper_size_t *back = NULL;
+ $? "+ dk3paper_nps_new"
+ if((app) && (name)) {
+ back = dk3_new_app(dk3_named_paper_size_t,1,app);
+ if(back) {
+ back->name = NULL;
+ (back->size).w = (back->size).h = 0.0;
+ (back->size).i = (back->size).o = (back->size).t = (back->size).b = 0.0;
+ back->name = dk3str_dup_app(name, app);
+ if(!(back->name)) {
+ dk3paper_nps_delete(back); back = NULL;
+ }
+ }
+ } $? "- dk3paper_nps_new %s", TR_PTR(back)
+ return back;
+}
+
+
+
+/** Compare two named paper sizes by name.
+ @param l Left structure.
+ @param r Right structure.
+ @param cr Comparison criteria (0=size/size, 1=size/name).
+ @return Comparison result.
+*/
+static
+int
+dk3paper_nps_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3_named_paper_size_t const *pl; /* Pointer to left structure. */
+ dk3_named_paper_size_t const *pr; /* Pointer to right structure. */
+ if(l) {
+ if(r) {
+ pl = (dk3_named_paper_size_t const *)l;
+ switch(cr) {
+ case 1: {
+ /*
+ Compare structure against a name string.
+ */
+ if(pl->name) {
+ back = dk3str_cmp(pl->name, (dkChar const *)r);
+ } else {
+ back = -1;
+ }
+ } break;
+ default: {
+ /*
+ Compare two structures by name.
+ */
+ pr = (dk3_named_paper_size_t const *)r;
+ if(pl->name) {
+ if(pr->name) {
+ back = dk3str_cmp(pl->name, pr->name);
+ } else {
+ back = 1;
+ }
+ } else {
+ if(pr->name) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+ if(back < -1) back = -1;
+ if(back > 1) back = 1;
+ return back;
+}
+
+
+
+/** Set values in a named paper size.
+ @param np Named paper size.
+ @param v Values array.
+ @param num Number of values (2 or 6).
+ Width and height are mandatory, borders are
+ optional.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3paper_set_values(dk3_named_paper_size_t *np, double const *v, size_t num)
+{
+ int back = 0;
+ $? "+ dk3paper_set_values"
+ (np->size).i = (np->size).o = (np->size).t = (np->size).b = 0.0;
+ (np->size).w = v[0]; (np->size).h = v[1];
+ if(num > 2) {
+ (np->size).i = v[2]; (np->size).o = v[3];
+ (np->size).t = v[4]; (np->size).b = v[5];
+ }
+ /*
+ Indicate success only if all values are reasonable.
+ */
+ if((np->size).w > 0.0) {
+ if((np->size).h > 0.0) {
+ if((np->size).i >= 0.0) {
+ if((np->size).o >= 0.0) {
+ if((np->size).t >= 0.0) {
+ if((np->size).b >= 0.0) {
+ back = 1;
+ }
+ }
+ }
+ }
+ }
+ } $? "- dk3paper_set_values %d", back
+ return back;
+}
+
+
+
+/** Handler function for one configuration file line.
+ @param obj Paper size collection.
+ @param il Input line to process.
+ @return 1 for OK, 0 for recoverable error, -1 for abort.
+*/
+static
+int
+dk3paper_const_line_handler(void *obj, dkChar const *il)
+{
+ dkChar bu[DK3_PAPER_CONFIG_LINE_SIZE]; /* Private copy. */
+ dkChar *parts[16]; /* Split number sequence. */
+ double v[8]; /* Values from text line. */
+ dk3_paper_size_collection_t *psc; /* Paper size collection. */
+ dk3_named_paper_size_t *np; /* Paper size to edit. */
+ dkChar *p1; /* Paper size name. */
+ dkChar *p2; /* Values for that size. */
+ size_t nparts; /* Number of values. */
+ size_t i; /* Traverse all values. */
+ int back = 1;
+ int res = 0; /* Flag: No reporting necessary. */
+ $? "+ dk3paper_const_line_handler"
+ if((obj) && (il)) { $? ". line=\"%!ds\"", il
+ psc = (dk3_paper_size_collection_t *)obj;
+ if(dk3str_len(il) < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy_not_overlapped(bu, il);
+ p1 = dk3str_start(bu, NULL);
+ if(p1) {
+ if(*p1 != dkT('#')) {
+ p2 = dk3str_chr(p1, dkT('='));
+ if(p2) {
+ *(p2++) = dkT('\0');
+ p2 = dk3str_start(p2, NULL);
+ if(p2) {
+ dk3str_chomp(p1, NULL);
+ nparts = dk3str_explode(parts, 15, p2, NULL);
+ if((nparts == 2) || (nparts == 6)) {
+ /*
+ Line syntax ok so far.
+ */
+ res = 1;
+ /*
+ Read double value from all text words.
+ */
+ for(i = 0; i < nparts; i++) {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(parts[i], dkT("%lg"), &(v[i])) != 1)
+#else
+ /* Bugfix 2014-09-01: If the action fails, the
+ res variable is set to failure, not on success.
+ */
+#if VERSION_BEFORE_20140901
+/* WRONG*/ if (dk3ma_d_from_string(&(v[i]), parts[i], NULL))
+#else
+/* OK */ if (0 == dk3ma_d_from_string(&(v[i]), parts[i], NULL))
+#endif
+#endif
+ {
+ res = 0;
+ }
+ }
+ if(res) {
+ if(dk3str_len(p1) > 0) {
+ /*
+ Attempt to find existing size for that name.
+ */
+ np = (dk3_named_paper_size_t *)dk3sto_it_find_like(
+ psc->i_sizes, (void *)p1, 1
+ );
+ if(np) {
+ /*
+ Entry exists, reconfigure entry.
+ */
+ res = dk3paper_set_values(np, v, nparts);
+ } else {
+ /*
+ Create new entry.
+ */
+ np = dk3paper_nps_new(psc->app, p1);
+ if(np) {
+ if(dk3sto_add(psc->s_sizes, (void *)np)) {
+ res = dk3paper_set_values(np, v, nparts);
+ } else {
+ /* ERROR: Memory */
+ dk3paper_nps_delete(np); np = NULL;
+ back = 0;
+ }
+ } else {
+ /* ERROR: Memory */
+ back = 0;
+ }
+ }
+ } else { res = 0; }
+ }
+ }
+ }
+ }
+ } else { res = 1; }
+ } else { res = 1; }
+ if(!(res)) {
+ /* ERROR: Syntax */
+ dk3str_cpy_not_overlapped(bu, il);
+ dk3str_normalize(bu, NULL, dkT(' '));
+ dk3app_log_i3(psc->app, DK3_LL_ERROR, 211, 212, bu);
+ }
+ }
+ } $? "- dk3paper_const_line_handler %d", back
+ return back;
+}
+
+
+
+/** Handler function for one configuration file line.
+ @param obj Paper size collection.
+ @param il Input line to process.
+ @return 1 for OK, 0 for recoverable error, -1 for abort.
+*/
+static
+int
+dk3paper_line_handler(void *obj, dkChar *il)
+{
+ int back;
+ back = dk3paper_const_line_handler(obj, il);
+ return back;
+}
+
+
+
+dk3_paper_size_collection_t *
+dk3paper_open_app(dk3_app_t *app)
+{
+ dkChar bu[DK3_PAPER_CONFIG_LINE_SIZE]; /* Buffer. */
+ dk3_paper_size_collection_t *back = NULL;
+ dk3_search_t *sr;
+ dkChar const *fn;
+ dkChar const * const *lfdptr;
+ int ok = 0;
+ int res;
+ int de;
+ int se;
+ $? "+ dk3paper_open_app"
+ if(app) {
+ back = dk3_new_app(dk3_paper_size_collection_t,1,app);
+ if(back) { $? ". allocation ok"
+ back->app = app;
+ back->s_sizes = NULL; back->i_sizes = NULL;
+ back->s_sizes = dk3sto_open_app(app);
+ if(back->s_sizes) { $? ". storage ok"
+ dk3sto_set_comp(back->s_sizes, dk3paper_nps_compare, 0);
+ back->i_sizes = dk3sto_it_open(back->s_sizes);
+ if(back->i_sizes) { $? ". iterator ok"
+ ok = 1;
+ /*
+ Read built-in lines.
+ */
+ lfdptr = dk3paper_default_sizes;
+ while(*lfdptr) { $? ". processing buildin line \"%!ds\"", *lfdptr
+ if(!dk3paper_const_line_handler((void *)back, *lfdptr)) {
+ ok = 0; $? "! failed"
+ }
+ lfdptr++;
+ }
+ /*
+ Read configuration files.
+ */
+ sr = dk3app_find_config_file(app, dk3paper_config_file_name, 0);
+ if(sr) { $? ". search results available"
+ dk3search_reset(sr);
+ se = dk3app_get_encoding(app);
+ de = dk3app_get_input_file_encoding(app);
+ while((fn = dk3search_next(sr)) != NULL) {
+ $? ". processing file \"%!ds\"", fn
+ res = dk3stream_process_filename_lines_app(
+ (void *)back, dk3paper_line_handler, fn,
+ bu, DK3_SIZEOF(bu,dkChar), se, de, app
+ );
+ if(!(res)) {
+ ok = 0;
+ }
+ }
+ dk3search_close(sr);
+ } else { $? "! no search results"
+ }
+ } else { $? "! iterator alloc failed"
+ }
+ } else { $? "! storage alloc failed"
+ }
+ if(!(ok)) {
+ dk3paper_close(back); back = NULL;
+ }
+ } else { $? "! allocation failed"
+ }
+ } $? "- dk3paper_open_app %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+void
+dk3paper_close(dk3_paper_size_collection_t *psc)
+{
+ dk3_named_paper_size_t *nps; /* Current size to release. */
+ $? "+ dk3paper_close"
+ if(psc) {
+ if(psc->s_sizes) {
+ if(psc->i_sizes) {
+ dk3sto_it_reset(psc->i_sizes);
+ while((nps = (dk3_named_paper_size_t *)dk3sto_it_next(psc->i_sizes))
+ != NULL
+ )
+ {
+ dk3paper_nps_delete(nps);
+ }
+ dk3sto_it_close(psc->i_sizes);
+ }
+ dk3sto_close(psc->s_sizes);
+ }
+ psc->s_sizes = NULL;
+ psc->app = NULL;
+ dk3_delete(psc);
+ } $? "- dk3paper_close"
+}
+
+
+dk3_paper_size_t const *
+dk3paper_find(dk3_paper_size_collection_t *psc, dkChar const *psn)
+{
+ dk3_paper_size_t const *back = NULL;
+ dk3_named_paper_size_t *nps; /* Named size. */
+ $? "+ dk3paper_find \"%!ds\"", psn
+ if((psc) && (psn)) {
+ nps = (dk3_named_paper_size_t *)dk3sto_it_find_like(
+ psc->i_sizes, (void *)psn, 1
+ );
+ if(nps) { $? ". nps ok"
+ back = (dk3_paper_size_t const *)(&(nps->size));
+ }
+ } $? "- dk3paper_find %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+void
+dk3paper_reset(dk3_paper_size_collection_t *psc)
+{
+ if(psc) {
+ if(psc->i_sizes) {
+ dk3sto_it_reset(psc->i_sizes);
+ }
+ }
+}
+
+
+
+
+dk3_named_paper_size_t const *
+dk3paper_next(dk3_paper_size_collection_t *psc)
+{
+ dk3_named_paper_size_t const *back = NULL;
+ if(psc) {
+ if(psc->i_sizes) {
+ back = (dk3_named_paper_size_t const *)dk3sto_it_next(psc->i_sizes);
+ }
+ }
+ return back;
+}
+
+
+
diff --git a/support/dktools/dk3paper.h b/support/dktools/dk3paper.h
new file mode 100644
index 0000000000..ade14d6422
--- /dev/null
+++ b/support/dktools/dk3paper.h
@@ -0,0 +1,92 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3paper.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3paper.h Header file for the dk3paper module.
+*/
+
+#ifndef DK3PAPER_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3PAPER_H_INCLUDED 1
+
+
+#line 10 "dk3paper.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Create paper sizes collection, read dk3paper.conf files.
+ @param app Application structure for diagnostics and file search,
+ must not be NULL.
+ @return Pointer to new collection on success, NULL on error.
+*/
+dk3_paper_size_collection_t *
+dk3paper_open_app(dk3_app_t *app);
+
+/** Find paper size by name.
+ @param psc Paper size collection.
+ @param psn Paper size name.
+ @return Pointer to paper size on success, NULL on error.
+*/
+dk3_paper_size_t const *
+dk3paper_find(dk3_paper_size_collection_t *psc, dkChar const *psn);
+
+/** Close paper size collection, release memory.
+ @param psc Collection to close.
+*/
+void
+dk3paper_close(dk3_paper_size_collection_t *psc);
+
+/** Prepare traversing the paper size collection for named paper sizes.
+ @param psc Paper size collection.
+*/
+void
+dk3paper_reset(dk3_paper_size_collection_t *psc);
+
+/** Retrieve next named paper size from size collection.
+ @param psc Paper size collection.
+ @return Pointer to named paper size on success, NULL on error/end.
+*/
+dk3_named_paper_size_t const *
+dk3paper_next(dk3_paper_size_collection_t *psc);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3pdf.c b/support/dktools/dk3pdf.c
new file mode 100644
index 0000000000..44de63ad35
--- /dev/null
+++ b/support/dktools/dk3pdf.c
@@ -0,0 +1,4295 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3pdf.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3pdf.c The dk3pdf module.
+*/
+
+
+#line 393 "dk3pdf.ctr"
+
+/*
+ Object numbers
+ --------------
+ 1 Info object (producer)
+ 2 Root object (type catalog, reference to pages object)
+ 3 Pages object, reference to page)
+
+ Xobject dictionary object (assign names to object numbers)
+
+ Page object (references to xobject dictionary, contents stream)
+ Page contents stream object, compressed
+
+*/
+
+
+
+#include "dk3all.h"
+#include "dk3pdf.h"
+#include "dk3bmj.h"
+#include "dk3bif.h"
+#include "dk3bifa.h"
+
+
+
+
+#line 418 "dk3pdf.ctr"
+
+
+
+/** Start position of PDF object.
+*/
+typedef struct {
+
+ /** Object number.
+ */
+ unsigned long objno;
+
+ /** Start position in file or stream.
+ */
+ dk3_um_t startpos;
+
+} dk3_pdf_object_start_t;
+
+
+
+/** Job information for PDF writing.
+*/
+typedef struct {
+
+ /** The PDF writer structure to write to file.
+ */
+ dk3_pdf_t *pdf;
+
+ /** Output file.
+ */
+ FILE *of;
+
+ /** Output stream.
+ */
+ dk3_stream_t *os;
+
+ /** Object start position collection.
+ */
+ dk3_sto_t *s_objstart;
+
+ /** Iterator for object start positions.
+ */
+ dk3_sto_it_t *i_objstart;
+
+ /** Object number for first page to show.
+ */
+ unsigned long firstPageObjectNumber;
+
+ /** Largest object number seen.
+ */
+ unsigned long largestObjectNumber;
+
+ /** Height of first page.
+ */
+ dk3_bif_coord_t firstPageHeight;
+
+} dk3_pdf_writer_job_t;
+
+
+
+/** Conversion job for one image.
+*/
+typedef struct {
+
+ /** Output PDF.
+ */
+ dk3_pdf_t *pdf;
+
+ /** XObject to produce.
+ */
+ dk3_pdf_xobject_t *xo;
+
+ /** Output filter.
+ */
+ dk3_of_t *of;
+
+ /** Conversion option set.
+ */
+ dk3_bm_eps_options_t *opt;
+
+ /** Input image.
+ */
+ dk3_bif_t *bif;
+
+ /** Conversion procedure, DK3_BMEPS_xxx, see @ref bmepscompression.
+ */
+ int procedure;
+
+ /** Flag: Color data found.
+ */
+ int h_color;
+
+ /** Flag: Alpha data found.
+ */
+ int h_alpha;
+
+ /** Bits per component.
+ */
+ int bpc;
+
+ /** Flag: Use dct.
+ */
+ int use_dct;
+
+} dk3_pdf_image_job_t;
+
+
+
+/** Keywords used by the dk3pdf module.
+*/
+static char const * dk3pdf_c8_kw[] = {
+/* 0 */ "\n",
+/* 1 */ " ",
+/* 2 */ "q\n",
+/* 3 */ "Q\n",
+/* 4 */ "cm\n",
+/* 5 */ "/X",
+/* 6 */ " Do\n",
+/* 7 */ "%PDF-1.4\n",
+/* 8 */ " 0 obj\n",
+/* 9 */ "endobj\n",
+/* 10 */ "<<\n/Producer (http://dktools.sourceforge.net)\n",
+/* 11 */ "<<\n",
+/* 12 */ ">>\n",
+/* 13 */ "/Type /Catalog\n",
+/* 14 */ "/Pages 3 0 R\n",
+/* 15 */ "/OpenAction [ ",
+/* 16 */ " 0 R /FitH ",
+/* 17 */ " ]\n",
+/* 18 */ "xref 0 ",
+/* 19 */ "0000000000 65535 f \n",
+/* 20 */ "0",
+/* 21 */ " 00000 n \n",
+/* 22 */ "trailer\n<< /Size ",
+/* 23 */ " /Info 1 0 R /Root 2 0 R >>\nstartxref\n",
+/* 24 */ "\n%%EOF\n",
+/* 25 */ "stream\n",
+/* 26 */ "\nendstream\n",
+/* 27 */ "/Type /XObject\n",
+/* 28 */ "/Subtype /Image\n",
+/* 29 */ "/Width ",
+/* 30 */ "/Height ",
+/* 31 */ "/BitsPerComponent ",
+/* 32 */ "/ColorSpace ",
+/* 33 */ "/DeviceCMYK\n",
+/* 34 */ "/DeviceGray\n",
+/* 35 */ "/DeviceRGB\n",
+/* 36 */ "/Filter ",
+/* 37 */ "/FlateDecode\n",
+/* 38 */ "/DCTDecode\n",
+/* 39 */ "/Length ",
+/* 40 */ "/Decode [ 1 0 1 0 1 0 1 0 ]\n",
+/* 41 */ "/Predictor 2\n",
+/* 42 */ "/Predictor 11\n",
+/* 43 */ "/Predictor 12\n",
+/* 44 */ "/Predictor 13\n",
+/* 45 */ "/Predictor 14\n",
+/* 46 */ "/SMask ",
+/* 47 */ " 0 R\n",
+/* 48 */ "/Type /Page\n",
+/* 49 */ "/Parent 3 0 R\n",
+/* 50 */ "/MediaBox [ %ld %ld %ld %ld ]\n",
+/* 51 */ "/Resources ",
+/* 52 */ "/ProcSet [ /PDF /ImageB /ImageC ]\n",
+/* 53 */ "/XObject %lu 0 R\n",
+/* 54 */ "/Contents %lu 0 R\n",
+/* 55 */ "/Group << /S /Transparency /I true /CS /DeviceRGB >>\n",
+/* 56 */ "/X%lu %lu 0 R\n",
+/* 57 */ "/Type /Pages\n",
+/* 58 */ "/Count ",
+/* 59 */ "%lu\n",
+/* 60 */ "/Kids [\n",
+/* 61 */ "]\n",
+/* 62 */ "%lu 0 R\n",
+/* 63 */ "/Interpolate true\n",
+/* 64 */ "/DecodeParms <<\n",
+/* 65 */ "/Colors ",
+/* 66 */ "4",
+/* 67 */ "1",
+/* 68 */ "3",
+/* 69 */ "/Columns ",
+/* 70 */ "%lg",
+/* 71 */ "m\n", /* PDF moveto */
+/* 72 */ "l\n", /* PDF lineto */
+/* 73 */ "g\n", /* PDF nonstroke setgray */
+/* 74 */ "G\n", /* PDF stroke setgray */
+/* 75 */ "b\n", /* PDF closepath, fill (nonzero), and stroke */
+/* 76 */ "B\n", /* PDF fill (nonzero), and stroke */
+/* 77 */ "b*\n", /* PDF closepath, fill (even/odd), and stroke */
+/* 78 */ "B*\n", /* PDF fill (even/odd), and stroke */
+/* 79 */ "f\n", /* PDF fill (nonzero) */
+/* 80 */ "f*\n", /* PDF fill (even/odd) */
+/* 81 */ "h\n", /* PDF closepath */
+/* 82 */ "rg\n", /* PDF setrgbcolor (nonstroking) */
+/* 83 */ "RG\n", /* PDF setrgbcolor (stroking) */
+/* 84 */ "2", /* PDF Line cap style square */
+/* 85 */ " J\n", /* PDF setlinecap */
+/* 86 */ "s\n", /* PDF closepath and stroke */
+/* 87 */ " w\n", /* PDF setlinewidth */
+/* 88 */ "W* n\n", /* PDF eoclip */
+/* 89 */ "c\n", /* PDF curveto */
+/* 90 */ " j\n", /* PDF setlinejoin */
+/* 91 */ " d\n", /* PDF setdash */
+/* 92 */ "[",
+/* 93 */ "]",
+/* 94 */ " S\n", /* PDF stroke */
+/* 95 */ "%ld",
+/* 96 */ " re W n\n", /* PDF re eoclip */
+/* 97 */ " W n\n",
+/* 98 */ "% ",
+/* 99 */ "0",
+/* 100 */ "/CropBox [ %ld %ld %ld %ld ]\n",
+/* 101 */ "%04d%02d%02d%02d%02d%02d",
+/* 102 */ "/CreationDate (D:",
+/* 103 */ ")\n/ModDate (D:",
+/* 104 */ ")\n",
+};
+
+
+
+/** Adjust a value to a given range.
+ @param min Range minimum.
+ @param max Range maximum.
+ @param val Uncorrected value.
+ @return Value, corrected if necessary.
+*/
+static
+double
+dk3pdf_to_range(double min, double max, double val)
+{
+ double back;
+
+
+#line 649 "dk3pdf.ctr"
+ back = val;
+ if(back < min) { back = min; }
+ if(back > max) { back = max; }
+
+#line 652 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+/** Compare to PDF pages.
+ @param l Left pointer.
+ @param r Right pointer.
+ @param cr Comparison criteria (0=page/page, 1=page/number).
+ @return Comparison result.
+*/
+static
+int
+dk3pdf_compare_pages(void const *l, void const *r, int cr)
+{
+ dk3_pdf_page_t const *pl; /* Left page object. */
+ dk3_pdf_page_t const *pr; /* Right page object. */
+ unsigned long const *ul; /* Page number. */
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (dk3_pdf_page_t const *)l;
+ switch(cr) {
+ case 1: {
+ ul = (unsigned long const *)r;
+ if(pl->pageno > *ul) {
+ back = 1;
+ } else {
+ if(pl->pageno < *ul) {
+ back = -1;
+ }
+ }
+ } break;
+ default: {
+ pr = (dk3_pdf_page_t const *)r;
+ if(pl->pageno > pr->pageno) {
+ back = 1;
+ } else {
+ if(pl->pageno < pr->pageno) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Compare two object start entries.
+ @param l Left pointer.
+ @param r Right pointer.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+static
+int
+dk3pdf_compare_object_start(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3_pdf_object_start_t const *pl; /* Left object start. */
+ dk3_pdf_object_start_t const *pr; /* Right object start. */
+ if(l) {
+ if(r) {
+ pl = (dk3_pdf_object_start_t const *)l;
+ pr = (dk3_pdf_object_start_t const *)r;
+ if(pl->objno > pr->objno) {
+ back = 1;
+ } else {
+ if(pl->objno < pr->objno) {
+ back = -1;
+ }
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Compare Xobjects.
+ @param l Left object.
+ @param r Right object.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result (0=xobject/xobject, 1=xobject/number).
+*/
+static
+int
+dk3pdf_compare_xobjects(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3_pdf_xobject_t const *pl; /* Left XObject. */
+ dk3_pdf_xobject_t const *pr; /* Right XObject. */
+ unsigned long const *ul; /* Right XObject number. */
+ if(l) {
+ if(r) {
+ pl = (dk3_pdf_xobject_t const *)l;
+ switch(cr) {
+ case 1: {
+ ul = (unsigned long const *)r;
+ if(pl->objno > *ul) {
+ back = 1;
+ } else {
+ if(pl->objno < *ul) {
+ back = -1;
+ }
+ }
+ } break;
+ default: {
+ pr = (dk3_pdf_xobject_t const *)r;
+ if(pl->objno > pr->objno) {
+ back = 1;
+ } else {
+ if(pl->objno < pr->objno) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Initialize PDF job.
+ @param job PDF creator job.
+ @param pdf PDF structure.
+ @param of Output filter.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3pdf_job_init(dk3_pdf_writer_job_t *job, dk3_pdf_t *pdf, FILE *of)
+{
+ int back = 0;
+
+
+#line 810 "dk3pdf.ctr"
+ job->of = NULL;
+ job->os = NULL;
+ job->s_objstart = NULL;
+ job->i_objstart = NULL;
+ job->largestObjectNumber = 0UL;
+ job->firstPageObjectNumber = 0UL;
+ job->firstPageHeight = 0L;
+ if((pdf) && (of)) {
+ job->of = of;
+ job->pdf = pdf;
+ job->os = dk3stream_open_file_app(of, DK3_STREAM_FLAG_WRITE, pdf->app);
+ if(job->os) {
+ job->s_objstart = dk3sto_open_app(pdf->app);
+ if(job->s_objstart) {
+ dk3sto_set_comp(job->s_objstart, dk3pdf_compare_object_start, 0);
+ job->i_objstart = dk3sto_it_open(job->s_objstart);
+ if(job->i_objstart) {
+
+#line 827 "dk3pdf.ctr"
+ back = 1;
+ } else {
+
+#line 829 "dk3pdf.ctr"
+ }
+ } else {
+
+#line 831 "dk3pdf.ctr"
+ }
+ } else {
+
+#line 833 "dk3pdf.ctr"
+ }
+ } else {
+
+#line 835 "dk3pdf.ctr"
+ }
+
+#line 836 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+/** Clean up PDF writer job.
+ @param job Job to clean up.
+*/
+static
+void
+dk3pdf_job_end(dk3_pdf_writer_job_t *job)
+{
+ dk3_pdf_position_t *pos; /* Traverse start position collection. */
+
+
+#line 850 "dk3pdf.ctr"
+ if(job->os) {
+ dk3stream_close(job->os);
+ }
+ job->os = NULL;
+ if(job->i_objstart) {
+ dk3sto_it_reset(job->i_objstart);
+ while((pos = (dk3_pdf_position_t *)dk3sto_it_next(job->i_objstart)) != NULL)
+ {
+ dk3_delete(pos);
+ }
+ dk3sto_it_close(job->i_objstart);
+ }
+ job->i_objstart = NULL;
+ if(job->s_objstart) {
+ dk3sto_close(job->s_objstart);
+ }
+ job->s_objstart = NULL;
+
+#line 867 "dk3pdf.ctr"
+}
+
+
+
+/** Destroy XObject, release memory.
+ @param xo Object to destroy.
+*/
+static
+void
+dk3pdf_xobject_delete(dk3_pdf_xobject_t *xo)
+{
+
+
+#line 879 "dk3pdf.ctr"
+ if(xo) {
+
+#line 880 "dk3pdf.ctr"
+ if(xo->tempfilename) {
+ dk3sf_remove_file_app(xo->tempfilename, NULL);
+ dk3_delete(xo->tempfilename);
+ }
+ xo->tempfilename = NULL;
+ xo->mask = NULL;
+ xo->width = 0L;
+ xo->height = 0L;
+ xo->objno = 0UL;
+ xo->xot = 0;
+ xo->procedure = DK3_BMEPS_RGB_FLATE;
+ xo->bpc = 0;
+ xo->dct = 0;
+ xo->pred = 0;
+ dk3_delete(xo);
+ }
+
+#line 896 "dk3pdf.ctr"
+}
+
+
+
+/** Create image XObject, allocate memory.
+ @param pdf PDF structure.
+ @return Pointer to new XObject on success, NULL on error.
+*/
+static
+dk3_pdf_xobject_t *
+dk3pdf_xobject_new(dk3_pdf_t *pdf)
+{
+ dkChar buf[DK3_MAX_PATH]; /* Buffer for conversion. */
+ dk3_pdf_xobject_t *back = NULL;
+ int ok = 0; /* Flag: Success so far. */
+
+
+#line 912 "dk3pdf.ctr"
+ back = dk3_new_app(dk3_pdf_xobject_t,1,pdf->app);
+ if(back) {
+ back->tempfilename = NULL;
+ back->mask = NULL;
+ back->width = 0L;
+ back->height = 0L;
+ back->objno = 0UL;
+ back->xot = DK3_PDF_XO_TYPE_IMAGE;
+ back->procedure = 0;
+ back->bpc = 8;
+ back->dct = 0;
+ back->pred = 0;
+ back->slgt = DK3_UM_0;
+ back->adobe_marker_found = 0;
+ back->interpolate = 0;
+ if(dk3app_get_temp_file_name(pdf->app, buf, DK3_SIZEOF(buf,dkChar))) {
+ back->tempfilename = dk3str_dup_app(buf, pdf->app);
+ if(back->tempfilename) {
+ ok = 1;
+ }
+ }
+ if(!(ok)) {
+ dk3pdf_xobject_delete(back);
+ back = NULL;
+ }
+ }
+
+#line 938 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+/** Destroy page object, release memory.
+ @param pa Page object to destroy.
+*/
+void
+dk3pdf_page_delete(dk3_pdf_page_t *pa)
+{
+
+
+#line 950 "dk3pdf.ctr"
+ if(pa) {
+
+#line 951 "dk3pdf.ctr"
+ if(pa->tempof) {
+ dk3of_close(pa->tempof);
+ }
+ if(pa->tempstream) {
+ dk3stream_close(pa->tempstream);
+ }
+ if(pa->tempfile) {
+ fclose(pa->tempfile);
+ }
+ if(pa->tempfilename) {
+ dk3sf_remove_file_app(pa->tempfilename,NULL);
+ dk3_delete(pa->tempfilename);
+ }
+ if(pa->i_xobjects) {
+ dk3sto_it_close(pa->i_xobjects);
+ }
+ if(pa->s_xobjects) {
+ dk3sto_close(pa->s_xobjects);
+ }
+ pa->tempfilename = NULL;
+ pa->tempfile = NULL;
+ pa->tempstream = NULL;
+ pa->tempof = NULL;
+ pa->s_xobjects = NULL;
+ pa->i_xobjects = NULL;
+ pa->objno = 0UL;
+ pa->pageno = 0UL;
+ pa->mbx0 = 0L;
+ pa->mbx1 = 0L;
+ pa->mby0 = 0L;
+ pa->mby1 = 0L;
+ dk3_delete(pa);
+ }
+
+#line 984 "dk3pdf.ctr"
+}
+
+
+
+/** Create new page object.
+ @param pdf PDF structure.
+ @return Pointer to new page object on success, NULL on error.
+*/
+static
+dk3_pdf_page_t *
+dk3pdf_page_new(dk3_pdf_t *pdf)
+{
+ dkChar fnb[DK3_MAX_PATH]; /* Conversion buffer. */
+ dk3_pdf_page_t *back = NULL;
+ int ok = 0; /* Flag: OK so far. */
+
+
+#line 1000 "dk3pdf.ctr"
+ if(dk3app_get_temp_file_name(pdf->app, fnb, DK3_SIZEOF(fnb,dkChar))) {
+ back = dk3_new_app(dk3_pdf_page_t,1,pdf->app);
+ if(back) {
+ back->tempfilename = NULL;
+ back->tempfile = NULL;
+ back->tempstream = NULL;
+ back->tempof = NULL;
+ back->s_xobjects = NULL;
+ back->i_xobjects = NULL;
+ back->objno = 0UL;
+ back->pageno = pdf->nextpage;
+ back->mbx0 = pdf->mbx0;
+ back->mbx1 = pdf->mbx1;
+ back->mby0 = pdf->mby0;
+ back->mby1 = pdf->mby1;
+ back->slgt = DK3_UM_0;
+ back->tempfilename = dk3str_dup_app(fnb, pdf->app);
+ if(back->tempfilename) {
+ back->tempfile = dk3sf_fopen_app(
+ back->tempfilename,
+ dk3app_not_localized(53),
+ pdf->app
+ );
+ }
+ if(back->tempfile) {
+ back->tempstream = dk3stream_open_file_app(
+ back->tempfile,
+ DK3_STREAM_FLAG_WRITE,
+ pdf->app
+ );
+ }
+ if(back->tempstream) {
+ back->tempof = dk3of_open_app(back->tempstream, pdf->app);
+ if(back->tempof) {
+ if(dk3of_add_cell(back->tempof, DK3_OF_CELL_TYPE_FLATE)) {
+ back->s_xobjects = dk3sto_open_app(pdf->app);
+ if(back->s_xobjects) {
+ back->i_xobjects = dk3sto_it_open(back->s_xobjects);
+ if(back->i_xobjects) {
+ ok = 1;
+ }
+ }
+ }
+ }
+ }
+ if(!(ok)) {
+ dk3pdf_page_delete(back);
+ back = NULL;
+ }
+ }
+ }
+
+#line 1051 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+
+dk3_pdf_t *
+dk3pdf_open_app(dk3_app_t *app)
+{
+ dk3_pdf_t *back = NULL;
+ int ok = 0; /* Flag: Success. */
+
+
+#line 1063 "dk3pdf.ctr"
+ if(app) {
+ back = dk3_new_app(dk3_pdf_t,1,app);
+ if(back) {
+ back->app = app;
+ back->s_xobjects = NULL;
+ back->i_xobjects = NULL;
+ back->s_pages = NULL;
+ back->i_pages = NULL;
+ back->cp = NULL;
+ back->nextobject = 4UL;
+ back->nextpage = 0UL;
+ back->mbx0 = 0L;
+ back->mbx1 = 595L;
+ back->mby0 = 0L;
+ back->mby1 = 842L;
+ back->documentMode = 0;
+ back->s_xobjects = dk3sto_open_app(app);
+ if(back->s_xobjects) {
+ dk3sto_set_comp(back->s_xobjects, dk3pdf_compare_xobjects, 0);
+ back->i_xobjects = dk3sto_it_open(back->s_xobjects);
+ }
+ back->s_pages = dk3sto_open_app(app);
+ if(back->s_pages) {
+ dk3sto_set_comp(back->s_pages, dk3pdf_compare_pages, 0);
+ back->i_pages = dk3sto_it_open(back->s_pages);
+ }
+ if(back->s_xobjects) {
+ if(back->i_xobjects) {
+ if(back->s_pages) {
+ if(back->i_pages) {
+ ok = 1;
+ }
+ }
+ }
+ }
+ if(!(ok)) {
+ dk3pdf_close(back);
+ back = NULL;
+ }
+ }
+ }
+
+#line 1104 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+void
+dk3pdf_close(dk3_pdf_t *pdf)
+{
+ dk3_pdf_xobject_t *xo; /* Traverse XObjects collection to clean up. */
+ dk3_pdf_page_t *pa; /* Traverse page collection to clean up. */
+
+
+#line 1115 "dk3pdf.ctr"
+ if(pdf) {
+ if(pdf->s_xobjects) {
+ if(pdf->i_xobjects) {
+ dk3sto_it_reset(pdf->i_xobjects);
+ while((xo = (dk3_pdf_xobject_t *)dk3sto_it_next(pdf->i_xobjects))
+ != NULL
+ )
+ {
+ dk3pdf_xobject_delete(xo);
+ }
+ dk3sto_it_close(pdf->i_xobjects);
+ }
+ dk3sto_close(pdf->s_xobjects);
+ }
+ pdf->s_xobjects = NULL;
+ pdf->i_xobjects = NULL;
+ if(pdf->s_pages) {
+ if(pdf->i_pages) {
+ dk3sto_it_reset(pdf->i_pages);
+ while((pa = (dk3_pdf_page_t *)dk3sto_it_next(pdf->i_pages)) != NULL) {
+ dk3pdf_page_delete(pa);
+ }
+ dk3sto_it_close(pdf->i_pages);
+ }
+ dk3sto_close(pdf->s_pages);
+ }
+ pdf->s_pages = NULL;
+ pdf->i_pages = NULL;
+ pdf->s_xobjects = NULL;
+ dk3_delete(pdf);
+ }
+
+#line 1146 "dk3pdf.ctr"
+}
+
+
+
+
+void
+dk3pdf_set_next_mediabox(
+ dk3_pdf_t *pdf,
+ long x0,
+ long x1,
+ long y0,
+ long y1
+)
+{
+ if(pdf) {
+ pdf->mbx0 = x0;
+ pdf->mbx1 = x1;
+ pdf->mby0 = y0;
+ pdf->mby1 = y1;
+ }
+
+#line 1166 "dk3pdf.ctr"
+}
+
+
+
+/** Write long value.
+ @param of Output filter stream.
+ @param x Value to write.
+*/
+static
+void
+dk3pdf_write_long(dk3_of_t *of, long x)
+{
+ char buf[64]; /* Conversion buffer. */
+ sprintf(buf, dk3pdf_c8_kw[95], x);
+ dk3of_write_c8_string(of, buf);
+
+#line 1181 "dk3pdf.ctr"
+}
+
+
+
+int
+dk3pdf_open_page_with_clip(dk3_pdf_t *pdf, int wc)
+{
+ dk3_pdf_page_t *np; /* Next page pointer. */
+ int back = 0;
+#if 1
+ long x;
+ long y;
+ long w;
+ long h;
+#endif
+
+
+#line 1197 "dk3pdf.ctr"
+ if(pdf) {
+ if(pdf->cp) {
+ dk3pdf_close_page(pdf);
+ }
+ np = dk3pdf_page_new(pdf);
+ if(np) {
+ if(dk3sto_add(pdf->s_pages, (void *)np)) {
+ pdf->nextpage += 1UL;
+ pdf->cp = np;
+ if(np->tempof) {
+ back = dk3of_start_chunk(np->tempof);
+ if(back) {
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[2]);
+ if(wc) {
+ /* 2013-01-10: Set clip path.
+ */
+ if(np->mbx0 < np->mbx1) {
+ x = np->mbx0; w = np->mbx1 - np->mbx0;
+ } else {
+ x = np->mbx1; w = np->mbx0 - np->mbx1;
+ }
+ if(np->mby0 < np->mby1) {
+ y = np->mby0; h = np->mby1 - np->mby0;
+ } else {
+ y = np->mby1; h = np->mby0 - np->mby1;
+ }
+ dk3pdf_write_long((pdf->cp)->tempof, x);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]);
+ dk3pdf_write_long((pdf->cp)->tempof, y);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]);
+ dk3pdf_write_long((pdf->cp)->tempof, w);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]);
+ dk3pdf_write_long((pdf->cp)->tempof, h);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[96]);
+ }
+ }
+ }
+ }
+ }
+ }
+
+#line 1237 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+int
+dk3pdf_open_page(dk3_pdf_t *pdf)
+{
+ int back;
+ back = dk3pdf_open_page_with_clip(pdf, 0);
+ return back;
+}
+
+
+
+int
+dk3pdf_close_page(dk3_pdf_t *pdf)
+{
+ dk3_stat_t stb; /* Stat buffer for contents stream file. */
+ int back = 0;
+
+
+#line 1258 "dk3pdf.ctr"
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[3]);
+ back = dk3of_end_chunk((pdf->cp)->tempof);
+ dk3of_close((pdf->cp)->tempof);
+ (pdf->cp)->tempof = NULL;
+ }
+ if((pdf->cp)->tempstream) {
+ dk3stream_close((pdf->cp)->tempstream);
+ (pdf->cp)->tempstream = NULL;
+ }
+ if((pdf->cp)->tempfile) {
+ if(!dk3sf_fclose_fn_app(
+ (pdf->cp)->tempfile, (pdf->cp)->tempfilename, pdf->app
+ )
+ )
+ {
+ back = 0;
+ }
+ pdf->cp->tempfile = NULL;
+ }
+ if((pdf->cp)->tempfilename) {
+ if(dk3sf_stat_app(&stb, (pdf->cp)->tempfilename, pdf->app)) {
+ (pdf->cp)->slgt = stb.sz;
+ } else {
+ back = 0;
+ /* ERROR: Stat failed for content stream! */
+ }
+ }
+ }
+ pdf->cp = NULL;
+ }
+
+#line 1291 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+int
+dk3pdf_gsave(dk3_pdf_t *pdf)
+{
+ int back = 0;
+
+
+#line 1301 "dk3pdf.ctr"
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[2]);
+ back = 1;
+ }
+ }
+ }
+
+#line 1309 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+int
+dk3pdf_grestore(dk3_pdf_t *pdf)
+{
+ int back = 0;
+
+
+#line 1319 "dk3pdf.ctr"
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[3]);
+ back = 1;
+ }
+ }
+ }
+
+#line 1327 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+/** Change current transformation matrix.
+ @param of Output filter to write to.
+ @param cmv Matrix values.
+*/
+static
+void
+dk3pdf_cm_long(dk3_of_t *of, long *cmv)
+{
+ char buf[64]; /* Conversion buffer. */
+
+
+#line 1342 "dk3pdf.ctr"
+ sprintf(buf, "%ld", cmv[0]);
+ dk3of_write_c8_string(of, buf);
+ dk3of_write_c8_string(of, dk3pdf_c8_kw[1]);
+ sprintf(buf, "%ld", cmv[1]);
+ dk3of_write_c8_string(of, buf);
+ dk3of_write_c8_string(of, dk3pdf_c8_kw[1]);
+ sprintf(buf, "%ld", cmv[2]);
+ dk3of_write_c8_string(of, buf);
+ dk3of_write_c8_string(of, dk3pdf_c8_kw[1]);
+ sprintf(buf, "%ld", cmv[3]);
+ dk3of_write_c8_string(of, buf);
+ dk3of_write_c8_string(of, dk3pdf_c8_kw[1]);
+ sprintf(buf, "%ld", cmv[4]);
+ dk3of_write_c8_string(of, buf);
+ dk3of_write_c8_string(of, dk3pdf_c8_kw[1]);
+ sprintf(buf, "%ld", cmv[5]);
+ dk3of_write_c8_string(of, buf);
+ dk3of_write_c8_string(of, dk3pdf_c8_kw[1]);
+ dk3of_write_c8_string(of, dk3pdf_c8_kw[4]);
+ dk3of_write_c8_string(of, dk3pdf_c8_kw[0]);
+
+#line 1362 "dk3pdf.ctr"
+}
+
+
+
+/** Write double value, correct comma to dot.
+ @param of Output filter stream.
+ @param x Value to write.
+*/
+static
+void
+dk3pdf_write_double(dk3_of_t *of, double x)
+{
+#if VERSION_BEFORE_20140722
+ char buf[64]; /* Conversion buffer. */
+ char *ptr;
+ sprintf(buf, dk3pdf_c8_kw[70], x);
+ ptr = buf;
+ while(*ptr) { if(*ptr == ',') { *ptr = '.'; } ptr++; }
+ dk3of_write_c8_string(of, buf);
+
+#line 1381 "dk3pdf.ctr"
+#else
+ if (1.0e-8 <= fabs(x)) {
+ (void)dk3of_double_to_c8_no_sci(of, x);
+ } else {
+ dk3of_write_c8_string(of, dk3pdf_c8_kw[99]);
+ }
+#endif
+}
+
+
+
+/** Change current transformation matrix.
+ @param of Output filter to write to.
+ @param cmv Matrix values.
+*/
+static
+void
+dk3pdf_cm_double(dk3_of_t *of, double *cmv)
+{
+
+
+#line 1401 "dk3pdf.ctr"
+ dk3pdf_write_double(of, cmv[0]);
+ dk3of_write_c8_string(of, dk3pdf_c8_kw[1]);
+ dk3pdf_write_double(of, cmv[1]);
+ dk3of_write_c8_string(of, dk3pdf_c8_kw[1]);
+ dk3pdf_write_double(of, cmv[2]);
+ dk3of_write_c8_string(of, dk3pdf_c8_kw[1]);
+ dk3pdf_write_double(of, cmv[3]);
+ dk3of_write_c8_string(of, dk3pdf_c8_kw[1]);
+ dk3pdf_write_double(of, cmv[4]);
+ dk3of_write_c8_string(of, dk3pdf_c8_kw[1]);
+ dk3pdf_write_double(of, cmv[5]);
+ dk3of_write_c8_string(of, dk3pdf_c8_kw[1]);
+ dk3of_write_c8_string(of, dk3pdf_c8_kw[4]);
+
+#line 1414 "dk3pdf.ctr"
+}
+
+
+
+int
+dk3pdf_translate_long(dk3_pdf_t *pdf, long x, long y)
+{
+ long cmv[] = { 0L, 0L, 0L, 0L, 0L, 0L }; /* Matrix values. */
+ int back = 0;
+
+
+#line 1424 "dk3pdf.ctr"
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ cmv[0] = 1L;
+ cmv[3] = 1L;
+ cmv[4] = x;
+ cmv[5] = y;
+ dk3pdf_cm_long((pdf->cp)->tempof, cmv);
+ }
+ }
+ }
+
+#line 1436 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+int
+dk3pdf_translate_double(dk3_pdf_t *pdf, double x, double y)
+{
+ double cmv[] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; /* Matrix values. */
+ int back = 0;
+
+
+#line 1447 "dk3pdf.ctr"
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ cmv[0] = 1.0;
+ cmv[3] = 1.0;
+ cmv[4] = x;
+ cmv[5] = y;
+ dk3pdf_cm_double((pdf->cp)->tempof, cmv);
+ }
+ }
+ }
+
+#line 1459 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+/** Convert long value to double.
+ @param l Long value to convert.
+ @return Conversion result.
+*/
+static
+double
+dk3pdf_l_to_d(long l)
+{
+ return ((double)l);
+}
+
+int
+dk3pdf_rotate_int(dk3_pdf_t *pdf, int angle)
+{
+ long cmv[] = { 0L, 0L, 0L, 0L, 0L, 0L }; /* Matrix values. */
+ int back = 0;
+
+
+#line 1481 "dk3pdf.ctr"
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ if(angle % 90) {
+ back = dk3pdf_rotate_double(pdf, dk3pdf_l_to_d((long)angle));
+ } else {
+ if(angle % 360) {
+ switch(angle % 360) {
+ case 90: {
+ cmv[1] = 1L;
+ cmv[2] = -1L;
+ } break;
+ case 180: {
+ cmv[0] = -1L;
+ cmv[3] = -1L;
+ } break;
+ case 270: {
+ cmv[1] = -1L;
+ cmv[2] = 1L;
+ } break;
+ }
+ dk3pdf_cm_long((pdf->cp)->tempof, cmv);
+ }
+ }
+ }
+ }
+ }
+
+#line 1509 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+int
+dk3pdf_rotate_double(dk3_pdf_t *pdf, double angle)
+{
+ double cmv[] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; /* Matrix values. */
+ int back = 0;
+
+
+#line 1520 "dk3pdf.ctr"
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ cmv[0] = cos(angle);
+ cmv[1] = sin(angle);
+ cmv[2] = 0.0 - cmv[1];
+ cmv[3] = cmv[0];
+ dk3pdf_cm_double((pdf->cp)->tempof, cmv);
+ }
+ }
+ }
+
+#line 1532 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+int
+dk3pdf_scale_long(dk3_pdf_t *pdf, long x, long y)
+{
+ long cmv[] = { 0L, 0L, 0L, 0L, 0L, 0L }; /* Matrix values. */
+ int back = 0;
+
+
+#line 1543 "dk3pdf.ctr"
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ cmv[0] = x;
+ cmv[3] = y;
+ dk3pdf_cm_long((pdf->cp)->tempof, cmv);
+ }
+ }
+ }
+
+#line 1553 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+int
+dk3pdf_scale_double(dk3_pdf_t *pdf, double x, double y)
+{
+ double cmv[] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; /* Matrix values. */
+ int back = 0;
+
+
+#line 1564 "dk3pdf.ctr"
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ cmv[0] = x;
+ cmv[3] = y;
+ dk3pdf_cm_double((pdf->cp)->tempof, cmv);
+ }
+ }
+ }
+
+#line 1574 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+int
+dk3pdf_add_xobject_to_page(dk3_pdf_t *pdf, dk3_pdf_xobject_t *xo)
+{
+ char buf[64]; /* Conversion buffer for number. */
+ int back = 0;
+
+
+#line 1585 "dk3pdf.ctr"
+ if((pdf) && (xo)) {
+
+#line 1586 "dk3pdf.ctr"
+ if(pdf->cp) {
+
+#line 1587 "dk3pdf.ctr"
+ if((pdf->cp)->tempof) {
+
+#line 1588 "dk3pdf.ctr"
+ sprintf(buf, "%lu", xo->objno);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[5]);
+ dk3of_write_c8_string((pdf->cp)->tempof, buf);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[6]);
+ if(!((pdf->cp)->s_xobjects)) {
+ (pdf->cp)->s_xobjects = dk3sto_open_app(pdf->app);
+ }
+ if(!((pdf->cp)->i_xobjects)) {
+ if((pdf->cp)->s_xobjects) {
+ (pdf->cp)->i_xobjects = dk3sto_it_open((pdf->cp)->s_xobjects);
+ }
+ }
+ if(((pdf->cp)->s_xobjects) && ((pdf->cp)->i_xobjects)) {
+
+#line 1601 "dk3pdf.ctr"
+ if(dk3sto_add((pdf->cp)->s_xobjects, (void *)xo)) {
+
+#line 1602 "dk3pdf.ctr"
+ back = 1;
+ }
+ }
+ } else {
+
+#line 1606 "dk3pdf.ctr"
+ }
+ } else {
+
+#line 1608 "dk3pdf.ctr"
+ }
+ } else {
+
+#line 1610 "dk3pdf.ctr"
+ }
+
+#line 1611 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+/** Initialize image conversion job.
+ @param job Image conversion job to initialize.
+ @param opt Conversion options.
+ @param pdf Destination pdf structure.
+ @param bif Source bitmap image.
+*/
+static
+void
+dk3pdf_image_job_init(
+ dk3_pdf_image_job_t *job,
+ dk3_bm_eps_options_t *opt,
+ dk3_pdf_t *pdf,
+ dk3_bif_t *bif
+)
+{
+
+
+#line 1632 "dk3pdf.ctr"
+ job->pdf = pdf;
+ job->bif = bif;
+ job->of = NULL;
+ job->procedure = DK3_BMEPS_RGB_FLATE;
+ job->h_color = 0;
+ job->h_alpha = 0;
+ job->bpc = 8;
+ job->opt = opt;
+ job->use_dct = 0;
+ job->xo = NULL;
+
+#line 1642 "dk3pdf.ctr"
+}
+
+
+
+/** Transfer DCT-encoded data directly from JPEG image to
+ output file.
+ @param ofile Destination file.
+ @param bif Source image.
+ @param app Application structure for diagnostics, may be NULL.
+*/
+static
+void
+dk3pdf_transfer_dct_data(FILE *ofile, dk3_bif_t *bif, dk3_app_t *app)
+{
+ char buf[4096]; /* Data buffer. */
+ FILE *ifile; /* Input file. */
+ size_t rb; /* Number of bytes read. */
+ int cc; /* Flag: Can continue. */
+
+
+#line 1661 "dk3pdf.ctr"
+ ifile = dk3bif_get_file(bif);
+ if(ifile) {
+ rewind(ifile);
+ do {
+ cc = 0;
+ rb = dk3sf_fread_app(buf, 1, sizeof(buf), ifile, app);
+ if(rb > 0) {
+ cc = 1;
+ dk3sf_fwrite_app(buf, 1, rb, ofile, app);
+ }
+ } while(cc);
+ }
+
+#line 1673 "dk3pdf.ctr"
+}
+
+
+
+
+/** Add color data mixed, 8 bits per component.
+ @param job Image conversion job.
+ @param pcomm Communicator object.
+ @param minpb Minimum progress bar value.
+ @param maxpb Maximum progress bar value.
+*/
+static
+void
+dk3pdf_out_col_8_mixed(
+ dk3_pdf_image_job_t *job,
+ void *pcomm,
+ int minpb,
+ int maxpb
+)
+{
+ dk3_bif_coord_t y; /* Current line. */
+ dk3_bif_coord_t x; /* Current column. */
+ dk3_bif_coord_t h; /* Image height. */
+ dk3_bif_coord_t w; /* Image width. */
+ unsigned char v[3]; /* RGB values. */
+ unsigned char ored, og, ob; /* Previous RGB values. */
+ unsigned char r, g, b; /* RGB values. */
+
+
+#line 1701 "dk3pdf.ctr"
+ w = dk3bif_get_width(job->bif);
+ h = dk3bif_get_height(job->bif);
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ for(y = 0L; y < h; y++) {
+ ored = og = ob = 0x00;
+ for(x = 0L; x < w; x++) {
+ r = (unsigned char)dk3bif_get_mixed_red(job->bif, x, y);
+ g = (unsigned char)dk3bif_get_mixed_green(job->bif, x, y);
+ b = (unsigned char)dk3bif_get_mixed_blue(job->bif, x, y);
+ v[0] = r - ored;
+ v[1] = g - og;
+ v[2] = b - ob;
+ dk3of_write_bytes(job->of, v, 3);
+ ored = r; og = g; ob = b;
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_SUB: {
+ for(y = 0L; y < h; y++) {
+ r = 0x01;
+ dk3of_write_bytes(job->of, &r, 1);
+ ored = og = ob = 0x00;
+ for(x = 0L; x < w; x++) {
+ r = (unsigned char)dk3bif_get_mixed_red(job->bif, x, y);
+ g = (unsigned char)dk3bif_get_mixed_green(job->bif, x, y);
+ b = (unsigned char)dk3bif_get_mixed_blue(job->bif, x, y);
+ v[0] = r - ored;
+ v[1] = g - og;
+ v[2] = b - ob;
+ dk3of_write_bytes(job->of, v, 3);
+ ored = r; og = g; ob = b;
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_UP: {
+ for(y = 0L; y < h; y++) {
+ r = 0x02;
+ dk3of_write_bytes(job->of, &r, 1);
+ for(x = 0L; x < w; x++) {
+ ored = (unsigned char)dk3bif_get_mixed_red(job->bif, x, (y - 1L));
+ og = (unsigned char)dk3bif_get_mixed_green(job->bif, x, (y - 1L));
+ ob = (unsigned char)dk3bif_get_mixed_blue(job->bif, x, (y - 1L));
+ r = (unsigned char)dk3bif_get_mixed_red(job->bif, x, y);
+ g = (unsigned char)dk3bif_get_mixed_green(job->bif, x, y);
+ b = (unsigned char)dk3bif_get_mixed_blue(job->bif, x, y);
+ v[0] = r - ored;
+ v[1] = g - og;
+ v[2] = b - ob;
+ dk3of_write_bytes(job->of, v, 3);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_AVERAGE: {
+ for(y = 0L; y < h; y++) {
+ r = 0x03;
+ dk3of_write_bytes(job->of, &r, 1);
+ for(x = 0L; x < w; x++) {
+ r = (unsigned char)dk3bif_get_mixed_red(job->bif, x, y);
+ g = (unsigned char)dk3bif_get_mixed_green(job->bif, x, y);
+ b = (unsigned char)dk3bif_get_mixed_blue(job->bif, x, y);
+ ored = (unsigned char)dk3bif_get_mixed_red(job->bif, (x - 1L), y);
+ og = (unsigned char)dk3bif_get_mixed_red(job->bif, x, (y - 1L));
+ ored = (unsigned char)dk3bif_average(ored, og);
+ v[0] = r - ored;
+ ored = (unsigned char)dk3bif_get_mixed_green(job->bif, (x - 1L), y);
+ og = (unsigned char)dk3bif_get_mixed_green(job->bif, x, (y - 1L));
+ ored = (unsigned char)dk3bif_average(ored, og);
+ v[1] = g - ored;
+ ored = (unsigned char)dk3bif_get_mixed_blue(job->bif, (x - 1L), y);
+ og = (unsigned char)dk3bif_get_mixed_blue(job->bif, x, (y - 1L));
+ ored = (unsigned char)dk3bif_average(ored, og);
+ v[2] = b - ored;
+ dk3of_write_bytes(job->of, v, 3);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_PAETH: {
+ for(y = 0L; y < h; y++) {
+ r = 0x04;
+ dk3of_write_bytes(job->of, &r, 1);
+ for(x = 0L; x < w; x++) {
+ r = (unsigned char)dk3bif_get_mixed_red(job->bif, x, y);
+ g = (unsigned char)dk3bif_get_mixed_green(job->bif, x, y);
+ b = (unsigned char)dk3bif_get_mixed_blue(job->bif, x, y);
+ ored = (unsigned char)dk3bif_paeth(
+ dk3bif_get_mixed_red(job->bif, (x - 1L), y),
+ dk3bif_get_mixed_red(job->bif, x, (y - 1L)),
+ dk3bif_get_mixed_red(job->bif, (x - 1L), (y - 1L))
+ );
+ og = (unsigned char)dk3bif_paeth(
+ dk3bif_get_mixed_green(job->bif, (x - 1L), y),
+ dk3bif_get_mixed_green(job->bif, x, (y - 1L)),
+ dk3bif_get_mixed_green(job->bif, (x - 1L), (y - 1L))
+ );
+ ob = (unsigned char)dk3bif_paeth(
+ dk3bif_get_mixed_blue(job->bif, (x - 1L), y),
+ dk3bif_get_mixed_blue(job->bif, x, (y - 1L)),
+ dk3bif_get_mixed_blue(job->bif, (x - 1L), (y - 1L))
+ );
+ v[0] = r - ored;
+ v[1] = g - og;
+ v[2] = b - ob;
+ dk3of_write_bytes(job->of, v, 3);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ default: {
+ for(y = 0L; y < h; y++) {
+ for(x = 0L; x < w; x++) {
+ v[0] = (unsigned char)dk3bif_get_mixed_red(job->bif, x, y);
+ v[1] = (unsigned char)dk3bif_get_mixed_green(job->bif, x, y);
+ v[2] = (unsigned char)dk3bif_get_mixed_blue(job->bif, x, y);
+ dk3of_write_bytes(job->of, v, 3);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ }
+
+#line 1837 "dk3pdf.ctr"
+}
+
+
+
+/** Add color data directly, 8 bits per component.
+ @param job Image conversion job.
+ @param pcomm Communicator object.
+ @param minpb Minimum progress bar value.
+ @param maxpb Maximum progress bar value.
+*/
+static
+void
+dk3pdf_out_col_8_not_mixed(
+ dk3_pdf_image_job_t *job,
+ void *pcomm,
+ int minpb,
+ int maxpb
+)
+{
+ dk3_bif_coord_t y; /* Current line. */
+ dk3_bif_coord_t x; /* Current column. */
+ dk3_bif_coord_t h; /* Image height. */
+ dk3_bif_coord_t w; /* Image width. */
+ unsigned char v[3]; /* RGB values. */
+ unsigned char ored, og, ob; /* Previous RGB values. */
+ unsigned char r, g, b; /* RGB values. */
+
+
+#line 1864 "dk3pdf.ctr"
+ w = dk3bif_get_width(job->bif);
+ h = dk3bif_get_height(job->bif);
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ for(y = 0L; y < h; y++) {
+ ored = og = ob = 0x00;
+ for(x = 0L; x < w; x++) {
+ r = (unsigned char)dk3bif_get_red(job->bif, x, y);
+ g = (unsigned char)dk3bif_get_green(job->bif, x, y);
+ b = (unsigned char)dk3bif_get_blue(job->bif, x, y);
+ v[0] = r - ored;
+ v[1] = g - og;
+ v[2] = b - ob;
+ dk3of_write_bytes(job->of, v, 3);
+ ored = r; og = g; ob = b;
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_SUB: {
+ for(y = 0L; y < h; y++) {
+ r = 0x01;
+ dk3of_write_bytes(job->of, &r, 1);
+ ored = og = ob = 0x00;
+ for(x = 0L; x < w; x++) {
+ r = (unsigned char)dk3bif_get_red(job->bif, x, y);
+ g = (unsigned char)dk3bif_get_green(job->bif, x, y);
+ b = (unsigned char)dk3bif_get_blue(job->bif, x, y);
+ v[0] = r - ored;
+ v[1] = g - og;
+ v[2] = b - ob;
+ dk3of_write_bytes(job->of, v, 3);
+ ored = r; og = g; ob = b;
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_UP: {
+ for(y = 0L; y < h; y++) {
+ r = 0x02;
+ dk3of_write_bytes(job->of, &r, 1);
+ for(x = 0L; x < w; x++) {
+ ored = (unsigned char)dk3bif_get_red(job->bif, x, (y - 1L));
+ og = (unsigned char)dk3bif_get_green(job->bif, x, (y - 1L));
+ ob = (unsigned char)dk3bif_get_blue(job->bif, x, (y - 1L));
+ r = (unsigned char)dk3bif_get_red(job->bif, x, y);
+ g = (unsigned char)dk3bif_get_green(job->bif, x, y);
+ b = (unsigned char)dk3bif_get_blue(job->bif, x, y);
+ v[0] = r - ored;
+ v[1] = g - og;
+ v[2] = b - ob;
+ dk3of_write_bytes(job->of, v, 3);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_AVERAGE: {
+ for(y = 0L; y < h; y++) {
+ r = 0x03;
+ dk3of_write_bytes(job->of, &r, 1);
+ for(x = 0L; x < w; x++) {
+ r = (unsigned char)dk3bif_get_red(job->bif, x, y);
+ g = (unsigned char)dk3bif_get_green(job->bif, x, y);
+ b = (unsigned char)dk3bif_get_blue(job->bif, x, y);
+ ored = (unsigned char)dk3bif_get_red(job->bif, (x - 1L), y);
+ og = (unsigned char)dk3bif_get_red(job->bif, x, (y - 1L));
+ ored = (unsigned char)dk3bif_average(ored, og);
+ v[0] = r - ored;
+ ored = (unsigned char)dk3bif_get_green(job->bif, (x - 1L), y);
+ og = (unsigned char)dk3bif_get_green(job->bif, x, (y - 1L));
+ ored = (unsigned char)dk3bif_average(ored, og);
+ v[1] = g - ored;
+ ored = (unsigned char)dk3bif_get_blue(job->bif, (x - 1L), y);
+ og = (unsigned char)dk3bif_get_blue(job->bif, x, (y - 1L));
+ ored = (unsigned char)dk3bif_average(ored, og);
+ v[2] = b - ored;
+ dk3of_write_bytes(job->of, v, 3);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_PAETH: {
+ for(y = 0L; y < h; y++) {
+ r = 0x04;
+ dk3of_write_bytes(job->of, &r, 1);
+ for(x = 0L; x < w; x++) {
+ r = (unsigned char)dk3bif_get_red(job->bif, x, y);
+ g = (unsigned char)dk3bif_get_green(job->bif, x, y);
+ b = (unsigned char)dk3bif_get_blue(job->bif, x, y);
+ ored = (unsigned char)dk3bif_paeth(
+ dk3bif_get_red(job->bif, (x - 1L), y),
+ dk3bif_get_red(job->bif, x, (y - 1L)),
+ dk3bif_get_red(job->bif, (x - 1L), (y - 1L))
+ );
+ og = (unsigned char)dk3bif_paeth(
+ dk3bif_get_green(job->bif, (x - 1L), y),
+ dk3bif_get_green(job->bif, x, (y - 1L)),
+ dk3bif_get_green(job->bif, (x - 1L), (y - 1L))
+ );
+ ob = (unsigned char)dk3bif_paeth(
+ dk3bif_get_blue(job->bif, (x - 1L), y),
+ dk3bif_get_blue(job->bif, x, (y - 1L)),
+ dk3bif_get_blue(job->bif, (x - 1L), (y - 1L))
+ );
+ v[0] = r - ored;
+ v[1] = g - og;
+ v[2] = b - ob;
+ dk3of_write_bytes(job->of, v, 3);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ default: {
+ for(y = 0L; y < h; y++) {
+ for(x = 0L; x < w; x++) {
+ v[0] = (unsigned char)dk3bif_get_red(job->bif, x, y);
+ v[1] = (unsigned char)dk3bif_get_green(job->bif, x, y);
+ v[2] = (unsigned char)dk3bif_get_blue(job->bif, x, y);
+ dk3of_write_bytes(job->of, v, 3);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ }
+
+#line 2000 "dk3pdf.ctr"
+}
+
+
+
+/** Add gray data mixed, 8 bits per component.
+ @param job Image conversion job.
+ @param pcomm Communicator object.
+ @param minpb Minimum progress bar value.
+ @param maxpb Maximum progress bar value.
+*/
+static
+void
+dk3pdf_out_gray_8_mixed(
+ dk3_pdf_image_job_t *job,
+ void *pcomm,
+ int minpb,
+ int maxpb
+)
+{
+ dk3_bif_coord_t y; /* Current line. */
+ dk3_bif_coord_t x; /* Current column. */
+ dk3_bif_coord_t h; /* Image height. */
+ dk3_bif_coord_t w; /* Image width. */
+ unsigned char v, p, q; /* Value and predictor(s). */
+
+
+#line 2025 "dk3pdf.ctr"
+ w = dk3bif_get_width(job->bif);
+ h = dk3bif_get_height(job->bif);
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ for(y = 0L; y < h; y++) {
+ p = 0x00;
+ for(x = 0L; x < w; x++) {
+ v = (unsigned char)dk3bif_get_mixed_gray(job->bif, x, y);
+ q = v - p;
+ dk3of_write_bytes(job->of, &q, 1);
+ p = v;
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_SUB: {
+ for(y = 0L; y < h; y++) {
+ q = 0x01;
+ dk3of_write_bytes(job->of, &q, 1);
+ p = 0x00;
+ for(x = 0L; x < w; x++) {
+ v = (unsigned char)dk3bif_get_mixed_gray(job->bif, x, y);
+ q = v - p;
+ dk3of_write_bytes(job->of, &q, 1);
+ p = v;
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_UP: {
+ for(y = 0L; y < h; y++) {
+ q = 0x02;
+ dk3of_write_bytes(job->of, &q, 1);
+ for(x = 0L; x < w; x++) {
+ p = (unsigned char)dk3bif_get_mixed_gray(job->bif, x, (y - 1L));
+ v = (unsigned char)dk3bif_get_mixed_gray(job->bif, x, y);
+ q = v - p;
+ dk3of_write_bytes(job->of, &q, 1);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_AVERAGE: {
+ for(y = 0L; y < h; y++) {
+ q = 0x03;
+ dk3of_write_bytes(job->of, &q, 1);
+ for(x = 0L; x < w; x++) {
+ p = (unsigned char)dk3bif_average(
+ dk3bif_get_mixed_gray(job->bif, x, (y - 1L)),
+ dk3bif_get_mixed_gray(job->bif, (x - 1L), y)
+ );
+ v = (unsigned char)dk3bif_get_mixed_gray(job->bif, x, y);
+ q = v - p;
+ dk3of_write_bytes(job->of, &q, 1);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_PAETH: {
+ for(y = 0L; y < h; y++) {
+ q = 0x04;
+ dk3of_write_bytes(job->of, &q, 1);
+ for(x = 0L; x < w; x++) {
+ v = (unsigned char)dk3bif_get_mixed_gray(job->bif, x, y);
+ p = (unsigned char)dk3bif_paeth(
+ dk3bif_get_mixed_gray(job->bif, (x - 1L), y),
+ dk3bif_get_mixed_gray(job->bif, x, (y - 1L)),
+ dk3bif_get_mixed_gray(job->bif, (x - 1L), (y - 1L))
+ );
+ q = v - p;
+ dk3of_write_bytes(job->of, &q, 1);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ default: {
+ for(y = 0L; y < h; y++) {
+ for(x = 0L; x < w; x++) {
+ v = (unsigned char)dk3bif_get_mixed_gray(job->bif, x, y);
+ dk3of_write_bytes(job->of, &v, 1);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ }
+
+#line 2122 "dk3pdf.ctr"
+}
+
+
+
+/** Add gray data directly, 8 bits per component.
+ @param job Image conversion job.
+ @param pcomm Communicator object.
+ @param minpb Minimum progress bar value.
+ @param maxpb Maximum progress bar value.
+*/
+static
+void
+dk3pdf_out_gray_8_not_mixed(
+ dk3_pdf_image_job_t *job,
+ void *pcomm,
+ int minpb,
+ int maxpb
+)
+{
+ dk3_bif_coord_t y; /* Current line. */
+ dk3_bif_coord_t x; /* Current column. */
+ dk3_bif_coord_t h; /* Image height. */
+ dk3_bif_coord_t w; /* Image width. */
+ unsigned char v, p, q; /* Value and predictors. */
+
+
+#line 2147 "dk3pdf.ctr"
+ w = dk3bif_get_width(job->bif);
+ h = dk3bif_get_height(job->bif);
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+
+#line 2151 "dk3pdf.ctr"
+ for(y = 0L; y < h; y++) {
+ p = 0x00;
+ for(x = 0L; x < w; x++) {
+ v = (unsigned char)dk3bif_get_gray(job->bif, x, y);
+ q = v - p;
+
+#line 2156 "dk3pdf.ctr"
+ dk3of_write_bytes(job->of, &q, 1);
+ p = v;
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_SUB: {
+ for(y = 0L; y < h; y++) {
+ q = 0x01;
+ dk3of_write_bytes(job->of, &q, 1);
+ p = 0x00;
+ for(x = 0L; x < w; x++) {
+ v = (unsigned char)dk3bif_get_gray(job->bif, x, y);
+ q = v - p;
+ dk3of_write_bytes(job->of, &q, 1);
+ p = v;
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_UP: {
+ for(y = 0L; y < h; y++) {
+ q = 0x02;
+ dk3of_write_bytes(job->of, &q, 1);
+ for(x = 0L; x < w; x++) {
+ p = (unsigned char)dk3bif_get_gray(job->bif, x, (y - 1L));
+ v = (unsigned char)dk3bif_get_gray(job->bif, x, y);
+ q = v - p;
+ dk3of_write_bytes(job->of, &q, 1);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_AVERAGE: {
+ dk3_bif_pixel_t lv;
+ dk3_bif_pixel_t uv;
+ for(y = 0L; y < h; y++) {
+ q = 0x03;
+ dk3of_write_bytes(job->of, &q, 1);
+ for(x = 0L; x < w; x++) {
+ uv = dk3bif_get_gray(job->bif, x, (y - 1L));
+ lv = dk3bif_get_gray(job->bif, (x - 1L), y);
+ lv = dk3bif_average(uv, lv);
+ p = (unsigned char)lv;
+ v = (unsigned char)dk3bif_get_gray(job->bif, x, y);
+ q = v - p;
+ dk3of_write_bytes(job->of, &q, 1);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_PAETH: {
+ for(y = 0L; y < h; y++) {
+ q = 0x04;
+ dk3of_write_bytes(job->of, &q, 1);
+ for(x = 0L; x < w; x++) {
+ v = (unsigned char)dk3bif_get_gray(job->bif, x, y);
+ p = (unsigned char)dk3bif_paeth(
+ dk3bif_get_gray(job->bif, (x - 1L), y),
+ dk3bif_get_gray(job->bif, x, (y - 1L)),
+ dk3bif_get_gray(job->bif, (x - 1L), (y - 1L))
+ );
+ q = v - p;
+ dk3of_write_bytes(job->of, &q, 1);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ default: {
+
+#line 2235 "dk3pdf.ctr"
+ for(y = 0L; y < h; y++) {
+ for(x = 0L; x < w; x++) {
+ v = (unsigned char)dk3bif_get_gray(job->bif, x, y);
+ dk3of_write_bytes(job->of, &v, 1);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ }
+
+#line 2246 "dk3pdf.ctr"
+}
+
+
+
+/** Add color data mixed, bits per component not 8.
+ @param job Image conversion job.
+ @param pcomm Communicator object.
+ @param minpb Minimum progress bar value.
+ @param maxpb Maximum progress bar value.
+*/
+static
+void
+dk3pdf_out_col_not8_mixed(
+ dk3_pdf_image_job_t *job,
+ void *pcomm,
+ int minpb,
+ int maxpb
+)
+{
+ dk3_bif_coord_t y; /* Current line. */
+ dk3_bif_coord_t x; /* Current column. */
+ dk3_bif_coord_t h; /* Image height. */
+ dk3_bif_coord_t w; /* Image width. */
+ dk3_bif_pixel_t r; /* Red. */
+ dk3_bif_pixel_t g; /* Green. */
+ dk3_bif_pixel_t b; /* Blue. */
+ dk3_bif_pixel_t ored; /* Previous red. */
+ dk3_bif_pixel_t og; /* Previous green. */
+ dk3_bif_pixel_t ob; /* Previous blue. */
+
+
+#line 2276 "dk3pdf.ctr"
+ w = dk3bif_get_width(job->bif);
+ h = dk3bif_get_height(job->bif);
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ for(y = 0L; y < h; y++) {
+ ored = 0U; og = 0U; ob = 0U;
+ for(x = 0L; x < w; x++) {
+ r = dk3bif_get_mixed_red(job->bif, x, y);
+ g = dk3bif_get_mixed_green(job->bif, x, y);
+ b = dk3bif_get_mixed_blue(job->bif, x, y);
+ dk3of_write_bits(job->of, (r - ored), job->bpc);
+ dk3of_write_bits(job->of, (g - og), job->bpc);
+ dk3of_write_bits(job->of, (b - ob), job->bpc);
+ ored = r;
+ og = g;
+ ob = b;
+ }
+ dk3of_flush_bits(job->of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ default: {
+ for(y = 0L; y < h; y++) {
+ for(x = 0L; x < w; x++) {
+ r = dk3bif_get_mixed_red(job->bif, x, y);
+ g = dk3bif_get_mixed_green(job->bif, x, y);
+ b = dk3bif_get_mixed_blue(job->bif, x, y);
+ dk3of_write_bits(job->of, r, job->bpc);
+ dk3of_write_bits(job->of, g, job->bpc);
+ dk3of_write_bits(job->of, b, job->bpc);
+ }
+ dk3of_flush_bits(job->of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ }
+
+#line 2316 "dk3pdf.ctr"
+}
+
+
+
+/** Add color data directly, bits per component not 8.
+ @param job Image conversion job.
+ @param pcomm Communicator object.
+ @param minpb Minimum progress bar value.
+ @param maxpb Maximum progress bar value.
+*/
+static
+void
+dk3pdf_out_col_not8_not_mixed(
+ dk3_pdf_image_job_t *job,
+ void *pcomm,
+ int minpb,
+ int maxpb
+)
+{
+ dk3_bif_coord_t y; /* Current line. */
+ dk3_bif_coord_t x; /* Current column. */
+ dk3_bif_coord_t h; /* Image height. */
+ dk3_bif_coord_t w; /* Image width. */
+ dk3_bif_pixel_t r; /* Red. */
+ dk3_bif_pixel_t g; /* Green. */
+ dk3_bif_pixel_t b; /* Blue. */
+ dk3_bif_pixel_t ored; /* Previous red. */
+ dk3_bif_pixel_t og; /* Previous green. */
+ dk3_bif_pixel_t ob; /* Previous blue. */
+
+
+#line 2346 "dk3pdf.ctr"
+ w = dk3bif_get_width(job->bif);
+ h = dk3bif_get_height(job->bif);
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ for(y = 0L; y < h; y++) {
+ ored = 0U; og = 0U; ob = 0U;
+ for(x = 0L; x < w; x++) {
+ r = dk3bif_get_red(job->bif, x, y);
+ g = dk3bif_get_green(job->bif, x, y);
+ b = dk3bif_get_blue(job->bif, x, y);
+ dk3of_write_bits(job->of, (r - ored), job->bpc);
+ dk3of_write_bits(job->of, (g - og), job->bpc);
+ dk3of_write_bits(job->of, (b - ob), job->bpc);
+ ored = r;
+ og = g;
+ ob = b;
+ }
+ dk3of_flush_bits(job->of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ default: {
+ for(y = 0L; y < h; y++) {
+ for(x = 0L; x < w; x++) {
+ r = dk3bif_get_red(job->bif, x, y);
+ g = dk3bif_get_green(job->bif, x, y);
+ b = dk3bif_get_blue(job->bif, x, y);
+ dk3of_write_bits(job->of, r, job->bpc);
+ dk3of_write_bits(job->of, g, job->bpc);
+ dk3of_write_bits(job->of, b, job->bpc);
+ }
+ dk3of_flush_bits(job->of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ }
+
+#line 2386 "dk3pdf.ctr"
+}
+
+
+
+/** Add gray data mixed, bits per component not 8.
+ @param job Image conversion job.
+ @param pcomm Communicator object.
+ @param minpb Minimum progress bar value.
+ @param maxpb Maximum progress bar value.
+*/
+static
+void
+dk3pdf_out_gray_not8_mixed(
+ dk3_pdf_image_job_t *job,
+ void *pcomm,
+ int minpb,
+ int maxpb
+)
+{
+ dk3_bif_coord_t y; /* Current line. */
+ dk3_bif_coord_t x; /* Current column. */
+ dk3_bif_coord_t h; /* Image height. */
+ dk3_bif_coord_t w; /* Image width. */
+ dk3_bif_pixel_t g; /* Current gray. */
+ dk3_bif_pixel_t og; /* Previous gray. */
+
+
+#line 2412 "dk3pdf.ctr"
+ w = dk3bif_get_width(job->bif);
+ h = dk3bif_get_height(job->bif);
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ for(y = 0L; y < h; y++) {
+ og = 0U;
+ for(x = 0L; x < w; x++) {
+ g = dk3bif_get_mixed_gray(job->bif, x, y);
+ dk3of_write_bits(job->of, (g - og), job->bpc);
+ og = g;
+ }
+ dk3of_flush_bits(job->of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ default: {
+ for(y = 0L; y < h; y++) {
+ for(x = 0L; x < w; x++) {
+ g = dk3bif_get_mixed_gray(job->bif, x, y);
+ dk3of_write_bits(job->of, g, job->bpc);
+ }
+ dk3of_flush_bits(job->of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ }
+
+#line 2442 "dk3pdf.ctr"
+}
+
+
+
+/** Add gray data directly, bits per component not 8.
+ @param job Image conversion job.
+ @param pcomm Communicator object.
+ @param minpb Minimum progress bar value.
+ @param maxpb Maximum progress bar value.
+*/
+static
+void
+dk3pdf_out_gray_not8_not_mixed(
+ dk3_pdf_image_job_t *job,
+ void *pcomm,
+ int minpb,
+ int maxpb
+)
+{
+ dk3_bif_coord_t y; /* Current line. */
+ dk3_bif_coord_t x; /* Current column. */
+ dk3_bif_coord_t h; /* Image height. */
+ dk3_bif_coord_t w; /* Image width. */
+ dk3_bif_pixel_t g; /* Current point gray. */
+ dk3_bif_pixel_t og; /* Previous gray. */
+
+
+#line 2468 "dk3pdf.ctr"
+ w = dk3bif_get_width(job->bif);
+ h = dk3bif_get_height(job->bif);
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ for(y = 0L; y < h; y++) {
+ og = 0U;
+ for(x = 0L; x < w; x++) {
+ g = dk3bif_get_gray(job->bif, x, y);
+ dk3of_write_bits(job->of, (g - og), job->bpc);
+ og = g;
+ }
+ dk3of_flush_bits(job->of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ default: {
+ for(y = 0L; y < h; y++) {
+ for(x = 0L; x < w; x++) {
+ g = dk3bif_get_gray(job->bif, x, y);
+ dk3of_write_bits(job->of, g, job->bpc);
+ }
+ dk3of_flush_bits(job->of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ }
+
+#line 2498 "dk3pdf.ctr"
+}
+
+
+
+/** Add another Xobject containing the alpha channel from the
+ current XObject.
+ @param job Image conversion job.
+ @param pcomm Communicator object.
+ @param min Minimum progress bar value.
+ @param max Maximum progress bar value.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3pdf_add_alpha_xobject(
+ dk3_pdf_image_job_t *job,
+ void *pcomm,
+ int min,
+ int max
+)
+{
+ dk3_stat_t stb; /* Stat buffer. */
+ dk3_pdf_xobject_t *mo; /* Mask object. */
+ FILE *fipo; /* Output file. */
+ dk3_stream_t *os; /* Output stream. */
+ dk3_of_t *of; /* Output filter. */
+ dk3_bif_coord_t w; /* Image width. */
+ dk3_bif_coord_t h; /* Image height. */
+ dk3_bif_coord_t x; /* Current column. */
+ dk3_bif_coord_t y; /* Current row. */
+ dk3_bif_pixel_t v; /* Pixel value. */
+ dk3_bif_pixel_t p; /* Previous value. */
+ int back = 0;
+ unsigned char vc; /* Value as byte. */
+ unsigned char pc; /* Predictor as byte. */
+ unsigned char wc; /* Predictor as byte. */
+
+
+#line 2535 "dk3pdf.ctr"
+ mo = dk3pdf_xobject_new(job->pdf);
+ if(mo) {
+ mo->objno = (job->pdf)->nextobject;
+ if(dk3sto_add((job->pdf)->s_xobjects, (void *)mo)) {
+ (job->pdf)->nextobject += 1UL;
+ w = mo->width = dk3bif_get_width(job->bif);
+ h = mo->height = dk3bif_get_height(job->bif);
+ mo->xot = DK3_PDF_XO_TYPE_ALPHA;
+ mo->procedure = DK3_BMEPS_GRAY_FLATE;
+ mo->bpc = job->bpc;
+ mo->pred = (job->opt)->pred;
+ fipo = dk3sf_fopen_app(
+ mo->tempfilename,
+ dk3app_not_localized(53),
+ (job->pdf)->app
+ );
+ if(fipo) {
+ (job->xo)->mask = mo;
+ os = dk3stream_open_file_app(
+ fipo,
+ DK3_STREAM_FLAG_WRITE,
+ (job->pdf)->app
+ );
+ if(os) {
+ of = dk3of_open_app(os, (job->pdf)->app);
+ if(of) {
+ if(dk3of_add_cell(of, DK3_OF_CELL_TYPE_FLATE)) {
+ if(dk3of_start_chunk(of)) {
+ if(job->bpc == 8) {
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ for(y = 0; y < h; y++) {
+ pc = 0x00;
+ for(x = 0; x < w; x++) {
+ vc = (unsigned char)dk3bif_get_alpha(job->bif, x, y);
+ wc = vc - pc;
+ dk3of_write_bytes(of, &wc, 1);
+ pc = vc;
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,min,max,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_SUB: {
+ for(y = 0; y < h; y++) {
+ pc = 0x00;
+ wc = 0x01;
+ dk3of_write_bytes(of, &wc, 1);
+ for(x = 0; x < w; x++) {
+ vc = (unsigned char)dk3bif_get_alpha(job->bif, x, y);
+ wc = vc - pc;
+ dk3of_write_bytes(of, &wc, 1);
+ pc = vc;
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,min,max,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_UP: {
+ for(y = 0; y < h; y++) {
+ wc = 0x02;
+ dk3of_write_bytes(of, &wc, 1);
+ for(x = 0; x < w; x++) {
+ vc = (unsigned char)dk3bif_get_alpha(job->bif, x, y);
+ pc = (unsigned char)dk3bif_get_alpha(
+ job->bif, x, (y - 1L)
+ );
+ wc = vc - pc;
+ dk3of_write_bytes(of, &wc, 1);
+#if VERSION_BEFORE_20150821
+ pc = vc;
+#endif
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,min,max,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_AVERAGE: {
+ for(y = 0; y < h; y++) {
+ wc = 0x03;
+ dk3of_write_bytes(of, &wc, 1);
+ for(x = 0; x < w; x++) {
+ vc = (unsigned char)dk3bif_get_alpha(job->bif, x, y);
+ pc = (unsigned char)dk3bif_get_alpha(
+ job->bif, x, (y - 1L)
+ );
+ wc = (unsigned char)dk3bif_get_alpha(
+ job->bif, (x - 1L), y
+ );
+ pc = (unsigned char)dk3bif_average(pc, wc);
+ wc = vc - pc;
+ dk3of_write_bytes(of, &wc, 1);
+#if VERSION_BEFORE_20150821
+ pc = vc;
+#endif
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,min,max,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_PAETH: {
+ for(y = 0; y < h; y++) {
+ wc = 0x04;
+ dk3of_write_bytes(of, &wc, 1);
+ for(x = 0; x < w; x++) {
+ vc = (unsigned char)dk3bif_get_alpha(job->bif, x, y);
+ pc = (unsigned char)dk3bif_paeth(
+ (unsigned char)dk3bif_get_alpha(
+ job->bif, (x - 1L), y
+ ),
+ (unsigned char)dk3bif_get_alpha(
+ job->bif, x, (y - 1L)
+ ),
+ (unsigned char)dk3bif_get_alpha(
+ job->bif, (x - 1L), (y - 1L)
+ )
+ );
+ wc = vc - pc;
+ dk3of_write_bytes(of, &wc, 1);
+#if VERSION_BEFORE_20150821
+ pc = vc;
+#endif
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,min,max,h,y);
+#endif
+ }
+ } break;
+ default: {
+ for(y = 0; y < h; y++) {
+ for(x = 0; x < w; x++) {
+ vc = (unsigned char)dk3bif_get_alpha(job->bif, x, y);
+ dk3of_write_bytes(of, &vc, 1);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,min,max,h,y);
+#endif
+ }
+ } break;
+ }
+ } else {
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ for(y = 0; y < h; y++) {
+ p = 0U;
+ for(x = 0; x < w; x++) {
+ v = dk3bif_get_alpha(job->bif, x, y);
+ dk3of_write_bits(of, (v - p), job->bpc);
+ p = v;
+ }
+ dk3of_flush_bits(of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,min,max,h,y);
+#endif
+ }
+ } break;
+ default: {
+ for(y = 0; y < h; y++) {
+ for(x = 0; x < w; x++) {
+ v = dk3bif_get_alpha(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ }
+ dk3of_flush_bits(of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,min,max,h,y);
+#endif
+ }
+ } break;
+ }
+ }
+ back = dk3of_end_chunk(of);
+ }
+ }
+ dk3of_close(of);
+ }
+ dk3stream_close(os);
+ }
+ if(!dk3sf_fclose_fn_app(fipo, mo->tempfilename, (job->pdf)->app)) {
+ back = 0;
+ }
+ if(dk3sf_stat_app(&stb, mo->tempfilename, (job->pdf)->app)) {
+ mo->slgt = stb.sz;
+ } else {
+ back = 0;
+ /* ERROR: Stat failed! */
+ }
+ }
+ } else {
+ dk3pdf_xobject_delete(mo);
+ }
+ }
+
+#line 2730 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+/** Create data stream for XObject in temporary file.
+ @param job Image conversion job.
+ @param pc Communication object.
+ @param min Minimum progress bar value.
+ @param max Maximum progress bar value.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3pdf_xobject_data(
+ dk3_pdf_image_job_t *job,
+ void *pc,
+ int min,
+ int max
+)
+{
+ dk3_stat_t stb; /* Stat buffer for content stream file. */
+ FILE *fipo; /* Input file. */
+ dk3_stream_t *os; /* Output stream. */
+ int back = 0;
+ int xmax; /* Centered progress bar value. */
+
+
+#line 2757 "dk3pdf.ctr"
+ xmax = max;
+ if(!(job->use_dct)) {
+ switch(job->procedure) {
+ case DK3_BMEPS_GRAY_ALPHA_FLATE: case DK3_BMEPS_RGB_ALPHA_FLATE: {
+ xmax = (min + max) / 2;
+ } break;
+ }
+ }
+
+#line 2765 "dk3pdf.ctr"
+ (job->xo)->width = dk3bif_get_width(job->bif);
+ (job->xo)->height = dk3bif_get_height(job->bif);
+ (job->xo)->xot = DK3_PDF_XO_TYPE_IMAGE;
+ (job->xo)->procedure = job->procedure;
+ (job->xo)->bpc = job->bpc;
+ if(job->use_dct) { (job->xo)->dct = 1; }
+ if(!(job->use_dct)) { (job->xo)->pred = (job->opt)->pred; }
+ fipo = dk3sf_fopen_app(
+ (job->xo)->tempfilename,
+ dk3app_not_localized(53),
+ (job->pdf)->app
+ );
+ if(fipo) {
+
+#line 2778 "dk3pdf.ctr"
+ if(job->use_dct) {
+
+#line 2779 "dk3pdf.ctr"
+ back = 1;
+ dk3pdf_transfer_dct_data(fipo, job->bif, (job->pdf)->app);
+ } else {
+ dk3bif_set_bits_per_pixel(job->bif, job->bpc);
+ os = dk3stream_open_file_app(fipo,DK3_STREAM_FLAG_WRITE,(job->pdf)->app);
+ if(os) {
+ job->of = dk3of_open_app(os, (job->pdf)->app);
+ if(job->of) {
+ if(dk3of_add_cell(job->of, DK3_OF_CELL_TYPE_FLATE)) {
+ if(dk3of_start_chunk(job->of)) {
+ if(job->bpc == 8) {
+ if(job->h_alpha) {
+ switch(job->procedure) {
+ case DK3_BMEPS_RGB_FLATE: {
+ dk3pdf_out_col_8_mixed(job, pc, min, xmax);
+ } break;
+ case DK3_BMEPS_RGB_ALPHA_FLATE: {
+ dk3pdf_out_col_8_not_mixed(job, pc, min, xmax);
+ } break;
+ case DK3_BMEPS_GRAY_FLATE: {
+ dk3pdf_out_gray_8_mixed(job, pc, min, xmax);
+ } break;
+ case DK3_BMEPS_GRAY_ALPHA_FLATE: {
+ dk3pdf_out_gray_8_not_mixed(job, pc, min, xmax);
+ } break;
+ }
+ } else {
+ switch(job->procedure) {
+ case DK3_BMEPS_RGB_FLATE: {
+ dk3pdf_out_col_8_not_mixed(job, pc, min, xmax);
+ } break;
+ case DK3_BMEPS_RGB_ALPHA_FLATE: {
+ dk3pdf_out_col_8_not_mixed(job, pc, min, xmax);
+ } break;
+ case DK3_BMEPS_GRAY_FLATE: {
+ dk3pdf_out_gray_8_not_mixed(job, pc, min, xmax);
+ } break;
+ case DK3_BMEPS_GRAY_ALPHA_FLATE: {
+ dk3pdf_out_gray_8_not_mixed(job, pc, min, xmax);
+ } break;
+ }
+ }
+ } else {
+ if(job->h_alpha) {
+ switch(job->procedure) {
+ case DK3_BMEPS_RGB_FLATE: {
+ dk3pdf_out_col_not8_mixed(job, pc, min, xmax);
+ } break;
+ case DK3_BMEPS_RGB_ALPHA_FLATE: {
+ dk3pdf_out_col_not8_not_mixed(job, pc, min, xmax);
+ } break;
+ case DK3_BMEPS_GRAY_FLATE: {
+ dk3pdf_out_gray_not8_mixed(job, pc, min, xmax);
+ } break;
+ case DK3_BMEPS_GRAY_ALPHA_FLATE: {
+ dk3pdf_out_gray_not8_not_mixed(job, pc, min, xmax);
+ } break;
+ }
+ } else {
+ switch(job->procedure) {
+ case DK3_BMEPS_RGB_FLATE: {
+ dk3pdf_out_col_not8_not_mixed(job, pc, min, xmax);
+ } break;
+ case DK3_BMEPS_RGB_ALPHA_FLATE: {
+ dk3pdf_out_col_not8_not_mixed(job, pc, min, xmax);
+ } break;
+ case DK3_BMEPS_GRAY_FLATE: {
+ dk3pdf_out_gray_not8_not_mixed(job, pc, min, xmax);
+ } break;
+ case DK3_BMEPS_GRAY_ALPHA_FLATE: {
+ dk3pdf_out_gray_not8_not_mixed(job, pc, min, xmax);
+ } break;
+ }
+ }
+ }
+ back = dk3of_end_chunk(job->of);
+ }
+ }
+ dk3of_close(job->of); job->of = NULL;
+ }
+ dk3stream_close(os);
+ }
+ if(back) {
+ switch(job->procedure) {
+ case DK3_BMEPS_GRAY_ALPHA_FLATE: case DK3_BMEPS_RGB_ALPHA_FLATE: {
+ back = dk3pdf_add_alpha_xobject(job, pc, xmax, max);
+ } break;
+ }
+ }
+ }
+ if(!dk3sf_fclose_fn_app(fipo, (job->xo)->tempfilename, (job->pdf)->app)) {
+ back = 0;
+ }
+ if(dk3sf_stat_app(&stb, (job->xo)->tempfilename, (job->pdf)->app)) {
+ (job->xo)->slgt = stb.sz;
+ } else {
+ back = 0;
+ /* ERROR: stat failed! */
+ }
+ } else {
+
+#line 2879 "dk3pdf.ctr"
+ }
+
+#line 2880 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+dk3_pdf_xobject_t *
+dk3pdf_create_ixobject_progress(
+ dk3_pdf_t *pdf,
+ dk3_bif_t *bif,
+ dk3_bm_eps_options_t *opt,
+ void *pc,
+ int min,
+ int max
+)
+{
+ dk3_pdf_image_job_t job; /* Conversion job. */
+ dk3_pdf_xobject_t *back = NULL;
+ int analysis_types = 0; /* Analysis setup. */
+ size_t nbits; /* Bits per component. */
+
+
+#line 2900 "dk3pdf.ctr"
+ nbits = dk3bif_get_bits_per_pixel(bif);
+ dk3pdf_image_job_init(&job, opt, pdf, bif);
+ switch(dk3bif_get_color_space(bif)) {
+ case DK3_COLOR_SPACE_RGBA: case DK3_COLOR_SPACE_GRAY_ALPHA: {
+ job.h_alpha = 1;
+ } break;
+ }
+ switch(dk3bif_get_color_space(bif)) {
+ case DK3_COLOR_SPACE_GRAY_ALPHA: case DK3_COLOR_SPACE_GRAY: {
+ } break;
+ default: {
+ job.h_color = 1;
+ } break;
+ }
+
+#line 2914 "dk3pdf.ctr"
+ switch(dk3bif_get_type(bif)) {
+ case DK3_BIF_IMAGE_TYPE_JPEG: {
+
+#line 2916 "dk3pdf.ctr"
+ if(opt->dct) {
+
+#line 2917 "dk3pdf.ctr"
+ switch(dk3bif_get_bits_per_pixel(bif)) {
+ case 1: case 2: case 4: case 8: {
+
+#line 2919 "dk3pdf.ctr"
+ switch(dk3bif_jpeg_get_num_components(bif)) {
+ case 1: {
+ job.procedure = DK3_BMEPS_GRAY_DCT;
+ job.bpc = (int)dk3bif_get_bits_per_pixel(bif);
+ job.use_dct = 1;
+ } break;
+ case 3: {
+ job.procedure = DK3_BMEPS_RGB_DCT;
+ job.bpc = (int)dk3bif_get_bits_per_pixel(bif);
+ job.use_dct = 1;
+ } break;
+ case 4: {
+ job.procedure = DK3_BMEPS_CMYK_DCT;
+ job.bpc = (int)dk3bif_get_bits_per_pixel(bif);
+ job.use_dct = 1;
+ } break;
+ default: {
+
+#line 2936 "dk3pdf.ctr"
+ } break;
+ }
+ } break;
+ default: {
+
+#line 2940 "dk3pdf.ctr"
+ } break;
+ }
+ }
+ } break;
+ }
+ if(!(job.use_dct)) {
+ if(job.h_color) { analysis_types |= DK3_BIF_ANALYSIS_COLOR; }
+ if(job.h_alpha) { analysis_types |= DK3_BIF_ANALYSIS_ALPHA; }
+ if(opt->rbpc) { analysis_types |= DK3_BIF_ANALYSIS_BITS; }
+ if(analysis_types) {
+ dk3bif_analyze_progress(bif, analysis_types, pc, min, ((max + min)/2));
+ if(opt->rbpc) { nbits = dk3bif_real_bits_per_pixel(bif); }
+ if(job.h_color) { job.h_color = dk3bif_real_color(bif); }
+ if(job.h_alpha) { job.h_alpha = dk3bif_real_alpha(bif); }
+ }
+#if 0
+ /* 2014-03-2
+ New algorithms for bits per component detection and reduction.
+ */
+ job.bpc = 1;
+ if(nbits > 1) {
+ job.bpc = 2;
+ if(nbits > 2) {
+ job.bpc = 4;
+ if(nbits > 4) {
+ job.bpc = 8;
+ }
+ }
+ }
+#else
+ switch (nbits) {
+ case 1: { job.bpc = 1; } break;
+ case 2: { job.bpc = 2; } break;
+ case 4: { job.bpc = 4; } break;
+ default: { job.bpc = 8; } break;
+ }
+#endif
+ if(job.h_color) {
+ if(job.h_alpha) {
+ switch(opt->mode) {
+ case DK3_BMEPS_MODE_OBJECT:
+ case DK3_BMEPS_MODE_PLACED_OBJECT: {
+ job.procedure = DK3_BMEPS_RGB_ALPHA_FLATE;
+ } break;
+ default: {
+ job.procedure = DK3_BMEPS_RGB_FLATE;
+ } break;
+ }
+ } else {
+ job.procedure = DK3_BMEPS_RGB_FLATE;
+ }
+ } else {
+ if(job.h_alpha) {
+ switch(opt->mode) {
+ case DK3_BMEPS_MODE_OBJECT:
+ case DK3_BMEPS_MODE_PLACED_OBJECT: {
+ job.procedure = DK3_BMEPS_GRAY_ALPHA_FLATE;
+ } break;
+ default: {
+ job.procedure = DK3_BMEPS_GRAY_FLATE;
+ } break;
+ }
+ } else {
+ job.procedure = DK3_BMEPS_GRAY_FLATE;
+ }
+ }
+ if(opt->pred > DK3_COMPRESSION_PREDICTOR_TIFF) {
+ job.bpc = 8;
+ }
+ }
+#if DK3_USE_WX
+
+
+#line 3012 "dk3pdf.ctr"
+ dk3bmj_progress(pc, (min + max)/2);
+#endif
+ back = dk3pdf_xobject_new(pdf);
+ if(back) {
+ back->objno = pdf->nextobject;
+ if(dk3sto_add(pdf->s_xobjects, (void *)back)) {
+ pdf->nextobject += 1UL;
+ job.xo = back;
+ if(job.procedure == DK3_BMEPS_CMYK_DCT) {
+ if(dk3bif_jpeg_get_found_adobe_marker(bif)) {
+ back->adobe_marker_found = 1;
+ }
+ }
+ if(opt->ip) {
+ switch(dk3bif_get_type(bif)) {
+ case DK3_BIF_IMAGE_TYPE_JPEG: {
+ if(opt->jip) {
+ back->interpolate = 1;
+ }
+ } break;
+ default: {
+ back->interpolate = 1;
+ } break;
+ }
+ }
+ if(!dk3pdf_xobject_data(&job, pc, (min + max)/2, max)) {
+ back = NULL;
+ }
+ } else {
+ dk3pdf_xobject_delete(back);
+ back = NULL;
+ }
+ }
+#if DK3_USE_WX
+
+
+#line 3047 "dk3pdf.ctr"
+ dk3bmj_progress(pc, max);
+#endif
+
+
+#line 3050 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+/* Now we use the function with progress indicator. */
+#if VERSION_BEFORE_20120104
+/** Create image XObject.
+ @param pdf PDF writer structure.
+ @param bif Image, the current frame will be added.
+ @param opt Conversion options.
+ @return Pointer to new object on success, NULL on error.
+*/
+static
+dk3_pdf_xobject_t *
+dk3pdf_create_ixobject(
+ dk3_pdf_t *pdf,
+ dk3_bif_t *bif,
+ dk3_bm_eps_options_t *opt
+)
+{
+ dk3_pdf_xobject_t *back;
+
+
+#line 3073 "dk3pdf.ctr"
+ back = dk3pdf_create_ixobject_progress(pdf, bif, opt, NULL, 0, 1000);
+
+
+#line 3075 "dk3pdf.ctr"
+ return back;
+}
+#endif
+
+
+
+dk3_pdf_xobject_t *
+dk3pdf_add_image_progress(
+ dk3_pdf_t *pdf,
+ dk3_bif_t *bif,
+ dk3_bm_eps_options_t *opt,
+ void *pc,
+ int min,
+ int max
+)
+{
+ dk3_pdf_xobject_t *back = NULL;
+
+
+#line 3093 "dk3pdf.ctr"
+ if((pdf) && (bif)) {
+
+#line 3094 "dk3pdf.ctr"
+ if(pdf->cp) {
+
+#line 3095 "dk3pdf.ctr"
+ if((pdf->cp)->tempof) {
+
+#line 3096 "dk3pdf.ctr"
+ back = dk3pdf_create_ixobject_progress(pdf, bif, opt, pc, min, max);
+ if(back) {
+
+#line 3098 "dk3pdf.ctr"
+ if(!dk3pdf_add_xobject_to_page(pdf, back)) {
+ back = NULL;
+ }
+ }
+ }
+ }
+ }
+
+#line 3105 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+dk3_pdf_xobject_t *
+dk3pdf_add_image(
+ dk3_pdf_t *pdf,
+ dk3_bif_t *bif,
+ dk3_bm_eps_options_t *opt
+)
+{
+ dk3_pdf_xobject_t *back = NULL;
+
+
+#line 3119 "dk3pdf.ctr"
+ back = dk3pdf_add_image_progress(pdf, bif, opt, NULL, 0, 1000);
+
+
+#line 3121 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+/** Write line to start object, keep object start position.
+ @param job PDF writer job structure.
+ @param on Object number.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3pdf_begin_object(dk3_pdf_writer_job_t *job, unsigned long on)
+{
+ char buf[64]; /* Conversion buffer. */
+ dk3_pdf_object_start_t *start; /* Start position object. */
+ dk3_um_t pos; /* Start position. */
+ int back = 0;
+
+
+#line 3140 "dk3pdf.ctr"
+ pos = dk3stream_bytes_written(job->os);
+
+#line 3141 "dk3pdf.ctr"
+ if(on > job->largestObjectNumber) { job->largestObjectNumber = on; }
+ start = dk3_new_app(dk3_pdf_object_start_t,1,(job->pdf)->app);
+ if(start) {
+
+#line 3144 "dk3pdf.ctr"
+ start->objno = on;
+ start->startpos = pos;
+ if(dk3sto_add(job->s_objstart, (void *)start)) {
+
+#line 3147 "dk3pdf.ctr"
+ back = 1;
+ sprintf(buf, "%lu", on);
+
+#line 3149 "dk3pdf.ctr"
+ dk3stream_c8_fputs(job->os, buf);
+
+#line 3150 "dk3pdf.ctr"
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[8]);
+
+#line 3151 "dk3pdf.ctr"
+ } else {
+
+#line 3152 "dk3pdf.ctr"
+ dk3_delete(start);
+ }
+ } else {
+
+#line 3155 "dk3pdf.ctr"
+ }
+
+#line 3156 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+/** Write object end.
+ @param job PDF writer job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+void
+dk3pdf_end_object(dk3_pdf_writer_job_t *job)
+{
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[9]);
+
+#line 3170 "dk3pdf.ctr"
+}
+
+
+
+
+/** Write start of PDF file.
+ @param job PDF writer job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3pdf_write_file_start(dk3_pdf_writer_job_t *job)
+{
+ char buf[64]; /* Conversion buffer. */
+ dk3_pdf_page_t *pp; /* Current page. */
+ unsigned long ul = 0UL; /* Number of pages. */
+ dk3_time_t timer = 0UL; /* Current time. */
+ dk3_tm_t locti; /* Local time. */
+ int back = 1;
+
+
+#line 3190 "dk3pdf.ctr"
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[7]);
+ if(dk3pdf_begin_object(job, 1UL)) {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[10]);
+ if (0 != dk3sf_time(&timer)) {
+ if (0 != dk3sf_localtime_app(&locti, &timer, NULL)) {
+ sprintf(
+ buf, dk3pdf_c8_kw[101],
+ locti.Y, locti.M, locti.D, locti.h, locti.m, locti.s
+ );
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[102]);
+ dk3stream_c8_fputs(job->os, buf);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[103]);
+ dk3stream_c8_fputs(job->os, buf);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[104]);
+ }
+ }
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[12]);
+ dk3pdf_end_object(job);
+ if(dk3pdf_begin_object(job, 2UL)) {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[11]);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[13]);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[14]);
+ if((job->pdf)->documentMode) {
+ if((job->firstPageObjectNumber) && (job->firstPageHeight)) {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[15]);
+ sprintf(buf, "%lu", job->firstPageObjectNumber);
+ dk3stream_c8_fputs(job->os, buf);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[16]);
+ sprintf(buf, "%ld", job->firstPageHeight);
+ dk3stream_c8_fputs(job->os, buf);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[17]);
+ }
+ }
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[12]);
+ dk3pdf_end_object(job);
+ if(dk3pdf_begin_object(job, 3UL)) {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[11]);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[57]);
+ ul = 0UL;
+ dk3sto_it_reset((job->pdf)->i_pages);
+ while((pp = (dk3_pdf_page_t *)dk3sto_it_next((job->pdf)->i_pages))
+ != NULL
+ )
+ {
+ ul++;
+ }
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[58]);
+ sprintf(buf, dk3pdf_c8_kw[59], ul);
+ dk3stream_c8_fputs(job->os, buf);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[60]);
+ dk3sto_it_reset((job->pdf)->i_pages);
+ while((pp = (dk3_pdf_page_t *)dk3sto_it_next((job->pdf)->i_pages))
+ != NULL
+ )
+ {
+ sprintf(buf, dk3pdf_c8_kw[62], pp->objno);
+ dk3stream_c8_fputs(job->os, buf);
+ }
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[61]);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[12]);
+ dk3pdf_end_object(job);
+ } else {
+
+#line 3252 "dk3pdf.ctr"
+ back = 0;
+ }
+ } else {
+
+#line 3255 "dk3pdf.ctr"
+ back = 0;
+ }
+ } else {
+
+#line 3258 "dk3pdf.ctr"
+ back = 0;
+ }
+
+#line 3260 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+/** Write decode params for flate compression when
+ using a predictor.
+ @param os Output stream.
+ @param predictorline Index of predictor line.
+ @param bpc Bits per component.
+ @param procedure Compression procedure.
+ @param width Image width.
+*/
+static
+void
+dk3pdf_decode_parms(
+ dk3_stream_t *os,
+ int predictorline,
+ int bpc,
+ int procedure,
+ dk3_bif_coord_t width
+)
+{
+ char buf[256]; /* Conversion buffer. */
+
+
+#line 3285 "dk3pdf.ctr"
+ dk3stream_c8_fputs(os, dk3pdf_c8_kw[64]);
+ dk3stream_c8_fputs(os, dk3pdf_c8_kw[predictorline]);
+ sprintf(buf, "%d", bpc);
+ dk3stream_c8_fputs(os, dk3pdf_c8_kw[31]);
+ dk3stream_c8_fputs(os, buf);
+ dk3stream_c8_fputs(os, dk3pdf_c8_kw[0]);
+ dk3stream_c8_fputs(os, dk3pdf_c8_kw[65]);
+ switch(procedure) {
+ case DK3_BMEPS_CMYK_DCT: {
+ dk3stream_c8_fputs(os, dk3pdf_c8_kw[66]);
+ } break;
+ case DK3_BMEPS_GRAY_UNCOMPRESSED:
+ case DK3_BMEPS_GRAY_RUNLENGTH:
+ case DK3_BMEPS_GRAY_DCT:
+ case DK3_BMEPS_GRAY_FLATE:
+ case DK3_BMEPS_GRAY_ALPHA_FLATE: {
+ dk3stream_c8_fputs(os, dk3pdf_c8_kw[67]);
+ } break;
+ default: {
+ dk3stream_c8_fputs(os, dk3pdf_c8_kw[68]);
+ } break;
+ }
+ dk3stream_c8_fputs(os, dk3pdf_c8_kw[0]);
+ dk3stream_c8_fputs(os, dk3pdf_c8_kw[69]);
+ sprintf(buf, "%ld", width);
+ dk3stream_c8_fputs(os, buf);
+ dk3stream_c8_fputs(os, dk3pdf_c8_kw[0]);
+ dk3stream_c8_fputs(os, dk3pdf_c8_kw[12]);
+
+#line 3313 "dk3pdf.ctr"
+}
+
+
+
+/** Write XObjects of PDF file.
+ @param job PDF writer job structure.
+ @param pcomm Communicator object.
+ @param minpb Minimum progress bar value.
+ @param maxpb Maximum progress bar value.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3pdf_write_file_xobjects(
+ dk3_pdf_writer_job_t *job,
+ void *pcomm,
+ int minpb,
+ int maxpb
+)
+{
+ char buf[64]; /* Conversion buffer. */
+ char sbuf[4096]; /* Data transfer bufer. */
+ dk3_pdf_xobject_t *xo; /* Current XObject. */
+ dk3_pdf_xobject_t *xmask; /* Mask for object. */
+ FILE *fipo; /* Input file (object stream). */
+ size_t rb; /* Number of bytes read. */
+ int back = 1;
+ int cc; /* Flag: Can continue transfer. */
+
+
+#line 3342 "dk3pdf.ctr"
+ dk3sto_it_reset((job->pdf)->i_xobjects);
+ while((xo = (dk3_pdf_xobject_t *)dk3sto_it_next((job->pdf)->i_xobjects))
+ != NULL
+ )
+ {
+ if(dk3pdf_begin_object(job, xo->objno)) {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[11]);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[27]); /* /Type /XObject */
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[28]); /* /Subtype /Image */
+ sprintf(buf, "%ld", xo->width);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[29]);
+ dk3stream_c8_fputs(job->os, buf);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[0]);
+ sprintf(buf, "%ld", xo->height);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[30]);
+ dk3stream_c8_fputs(job->os, buf);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[0]);
+ sprintf(buf, "%d", xo->bpc);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[31]);
+ dk3stream_c8_fputs(job->os, buf);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[0]);
+ switch(xo->xot) {
+ case DK3_PDF_XO_TYPE_ALPHA: {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[32]);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[34]);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[36]);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[37]);
+ } break;
+ default: {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[32]);
+ switch(xo->procedure) {
+ case DK3_BMEPS_CMYK_DCT: {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[33]);
+ if(xo->adobe_marker_found) {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[40]);
+ }
+ } break;
+ case DK3_BMEPS_GRAY_DCT:
+ case DK3_BMEPS_GRAY_FLATE:
+ case DK3_BMEPS_GRAY_ALPHA_FLATE: {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[34]);
+ } break;
+ default: {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[35]);
+ } break;
+ }
+ if(xo->mask) {
+ xmask = (dk3_pdf_xobject_t *)(xo->mask);
+ sprintf(buf, "%lu", xmask->objno);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[46]);
+ dk3stream_c8_fputs(job->os, buf);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[47]);
+ }
+ if(xo->interpolate) {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[63]);
+ }
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[36]);
+ if(xo->dct) {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[38]);
+ } else {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[37]);
+ }
+ } break;
+ }
+ if(!(xo->dct)) {
+ switch(xo->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ dk3pdf_decode_parms(job->os, 41, xo->bpc, xo->procedure, xo->width);
+ /* dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[41]); */
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_SUB: {
+ dk3pdf_decode_parms(job->os, 42, xo->bpc, xo->procedure, xo->width);
+ /* dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[42]); */
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_UP: {
+ dk3pdf_decode_parms(job->os, 43, xo->bpc, xo->procedure, xo->width);
+ /* dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[43]); */
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_AVERAGE: {
+ dk3pdf_decode_parms(job->os, 44, xo->bpc, xo->procedure, xo->width);
+ /* dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[44]); */
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_PAETH: {
+ dk3pdf_decode_parms(job->os, 45, xo->bpc, xo->procedure, xo->width);
+ /* dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[45]); */
+ } break;
+ }
+ }
+ if(dk3ma_um_to_c8_string(buf, sizeof(buf), xo->slgt)) {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[39]);
+ dk3stream_c8_fputs(job->os, buf);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[0]);
+ }
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[12]);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[25]);
+ /* Data stream */
+ fipo = dk3sf_fopen_app(
+ xo->tempfilename,
+ dk3app_not_localized(36),
+ (job->pdf)->app
+ );
+ if(fipo) {
+ do {
+ cc = 0;
+ rb = dk3sf_fread_app(sbuf, 1, sizeof(sbuf), fipo, (job->pdf)->app);
+ if(rb > 0) {
+ cc = 1;
+ if(rb != dk3stream_write_bytes(job->os, sbuf, rb)) {
+ back = 0;
+ /* ERROR While writing data! */
+ }
+ }
+ } while(cc);
+ if(!dk3sf_fclose_fn_app(fipo, xo->tempfilename, (job->pdf)->app)) {
+ back = 0;
+ }
+ fipo = NULL;
+ } else {
+ back = 0;
+ /* ERROR: Failed to open file! */
+ }
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[26]);
+ dk3pdf_end_object(job);
+ } else {
+ back = 0;
+ /* ERROR: Failed to begin Xobject! */
+ }
+#if DK3_USE_WX
+ dk3bmj_obj_progress(pcomm,minpb,maxpb,(job->pdf)->nextobject,(xo->objno + 1UL));
+#endif
+ }
+
+#line 3473 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+/** Write pages of PDF file.
+ @param job PDF writer job structure.
+ @param pcomm Communicator object.
+ @param minpb Minimum progress bar value.
+ @param maxpb Maximum progress bar value.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3pdf_write_file_pages(
+ dk3_pdf_writer_job_t *job,
+ void *pcomm,
+ int minpb,
+ int maxpb
+)
+{
+ char buf[4096]; /* Data transfer buffer. */
+ FILE *fipo; /* Input file (page contents stream). */
+ dk3_pdf_page_t *cp; /* Current page. */
+ dk3_pdf_xobject_t *xo; /* Traverse XObjects. */
+ size_t rb; /* Number of bytes read. */
+ int back = 1;
+ int have_mask; /* Flag: Have alpha mask. */
+ int cc; /* Flag: Can continue transfer. */
+
+
+#line 3503 "dk3pdf.ctr"
+ dk3sto_it_reset((job->pdf)->i_pages);
+ while((cp = (dk3_pdf_page_t *)dk3sto_it_next((job->pdf)->i_pages)) != NULL) {
+
+
+#line 3506 "dk3pdf.ctr"
+ /*
+ Mark all Xobjects as unused.
+ */
+ dk3sto_it_reset((job->pdf)->i_xobjects);
+ while((xo = (dk3_pdf_xobject_t *)dk3sto_it_next((job->pdf)->i_xobjects))
+ != NULL
+ )
+ {
+ xo->used = 0;
+ }
+
+#line 3516 "dk3pdf.ctr"
+ /*
+ Mark Xobjects used by this page.
+ */
+ have_mask = 0;
+ if((cp->s_xobjects) && (cp->i_xobjects)) {
+ dk3sto_it_reset(cp->i_xobjects);
+ while((xo = (dk3_pdf_xobject_t *)dk3sto_it_next(cp->i_xobjects)) != NULL)
+ {
+ xo->used = 1;
+
+#line 3525 "dk3pdf.ctr"
+ if(xo->mask) {
+
+#line 3526 "dk3pdf.ctr"
+ have_mask = 1;
+ }
+ }
+ }
+
+#line 3530 "dk3pdf.ctr"
+ /*
+ Write page object.
+ */
+
+
+#line 3534 "dk3pdf.ctr"
+ if(dk3pdf_begin_object(job, cp->objno)) {
+
+#line 3535 "dk3pdf.ctr"
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[11]); /* << */
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[48]);
+
+#line 3537 "dk3pdf.ctr"
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[49]);
+
+#line 3538 "dk3pdf.ctr"
+ sprintf(buf, dk3pdf_c8_kw[50], cp->mbx0, cp->mby0, cp->mbx1, cp->mby1);
+ dk3stream_c8_fputs(job->os, buf);
+
+#line 3540 "dk3pdf.ctr"
+ sprintf(buf, dk3pdf_c8_kw[100], cp->mbx0, cp->mby0, cp->mbx1, cp->mby1);
+ dk3stream_c8_fputs(job->os, buf);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[51]); /* /Resources << */
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[11]);
+
+#line 3544 "dk3pdf.ctr"
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[52]);
+
+#line 3545 "dk3pdf.ctr"
+ if((cp->s_xobjects) && (cp->i_xobjects)) {
+
+#line 3546 "dk3pdf.ctr"
+ sprintf(buf, dk3pdf_c8_kw[53], (cp->objno + 2UL));
+
+#line 3547 "dk3pdf.ctr"
+ dk3stream_c8_fputs(job->os, buf);
+
+#line 3548 "dk3pdf.ctr"
+ }
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[12]); /* >> */
+ sprintf(buf, dk3pdf_c8_kw[54], (cp->objno + 1UL));
+
+#line 3551 "dk3pdf.ctr"
+ dk3stream_c8_fputs(job->os, buf);
+
+#line 3552 "dk3pdf.ctr"
+ /* Group (for alpha) */
+ if(have_mask) {
+
+#line 3554 "dk3pdf.ctr"
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[55]);
+
+#line 3555 "dk3pdf.ctr"
+ }
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[12]); /* >> */
+ dk3pdf_end_object(job);
+
+#line 3558 "dk3pdf.ctr"
+ /*
+ Write content stream object.
+ */
+ if(dk3pdf_begin_object(job, (cp->objno + 1UL))) {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[11]);
+ if(dk3ma_um_to_c8_string(buf, sizeof(buf), cp->slgt)) {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[39]);
+ dk3stream_c8_fputs(job->os, buf);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[0]);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[36]);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[37]);
+ } else {
+ back = 0;
+ /* ERROR: Failed to convert length! */
+ }
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[12]);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[25]);
+ fipo = dk3sf_fopen_app(
+ cp->tempfilename,
+ dk3app_not_localized(36),
+ (job->pdf)->app
+ );
+ if(fipo) {
+ do {
+ cc = 0;
+ rb = dk3sf_fread_app(buf, 1, sizeof(buf), fipo, (job->pdf)->app);
+ if(rb > 0) {
+ cc = 1;
+ if(rb != dk3stream_write_bytes(job->os, buf, rb)) {
+ back = 0;
+ /* ERROR: Write failed! */
+ }
+ }
+ } while(cc);
+ if(!dk3sf_fclose_fn_app(fipo, cp->tempfilename, (job->pdf)->app)) {
+ back = 0;
+ }
+ } else {
+ back = 0;
+ /* ERROR: Failed to open file! */
+ }
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[26]);
+ dk3pdf_end_object(job);
+
+#line 3601 "dk3pdf.ctr"
+ /*
+ Write XObjects dictionary.
+ */
+ if((cp->s_xobjects) && (cp->i_xobjects)) {
+ if(dk3pdf_begin_object(job, (cp->objno + 2UL))) {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[11]);
+ dk3sto_it_reset((job->pdf)->i_xobjects);
+ while((xo =
+ (dk3_pdf_xobject_t *)dk3sto_it_next((job->pdf)->i_xobjects)
+ )
+ != NULL
+ )
+ {
+ sprintf(buf, dk3pdf_c8_kw[56], xo->objno, xo->objno);
+ dk3stream_c8_fputs(job->os, buf);
+ }
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[12]);
+ dk3pdf_end_object(job);
+
+#line 3619 "dk3pdf.ctr"
+ } else {
+ back = 0;
+ /* ERROR: Memory */
+ }
+ }
+ } else {
+ back = 0;
+ /* ERROR: Memory */
+ }
+ } else {
+
+#line 3629 "dk3pdf.ctr"
+ back = 0;
+ /* ERROR: Memory */
+ }
+#if DK3_USE_WX
+ dk3bmj_obj_progress(pcomm,minpb,maxpb,(job->pdf)->nextobject,(cp->objno + 1UL));
+#endif
+ }
+
+#line 3636 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+/** Write end of PDF file.
+ @param job PDF writer job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3pdf_write_file_end(dk3_pdf_writer_job_t *job)
+{
+ char buf[64]; /* Conversion buffer. */
+ dk3_pdf_position_t *pos; /* Position structure. */
+ dk3_um_t startxref; /* Position of xref start. */
+ size_t sl; /* Buffer length. */
+ size_t i; /* Fill buffer with '0'. */
+ int back = 1;
+
+
+#line 3656 "dk3pdf.ctr"
+ startxref = dk3stream_bytes_written(job->os);
+ sprintf(buf, "%lu", (job->largestObjectNumber + 1UL));
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[18]);
+ dk3stream_c8_fputs(job->os, buf);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[0]);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[19]);
+ dk3sto_it_reset(job->i_objstart);
+ while((pos = (dk3_pdf_position_t *)dk3sto_it_next(job->i_objstart)) != NULL) {
+ if(dk3ma_um_to_c8_string(buf, sizeof(buf), pos->startpos)) {
+ if((sl = strlen(buf)) <= 10) {
+ for(i = sl; i < 10; i++) {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[20]);
+ }
+ dk3stream_c8_fputs(job->os, buf);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[21]);
+ } else {
+ back = 0;
+ /* Object start position too large! */
+ }
+ } else {
+ back = 0;
+ /* ERROR: Failed to convert position! */
+ }
+ }
+ sprintf(buf, "%lu", (job->largestObjectNumber + 1UL));
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[22]);
+ dk3stream_c8_fputs(job->os, buf);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[23]);
+ if(dk3ma_um_to_c8_string(buf, sizeof(buf), startxref)) {
+ dk3stream_c8_fputs(job->os, buf);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[24]);
+ } else {
+ back = 0;
+ /* ERROR: Failed to convert number! */
+ }
+
+#line 3691 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+/** Assign object numbers to pages.
+*/
+static
+void
+dk3pdf_enumerate_pages(dk3_pdf_writer_job_t *job)
+{
+ dk3_pdf_page_t *pa; /* Current page. */
+ unsigned long on; /* Next object number. */
+
+
+#line 3705 "dk3pdf.ctr"
+ on = (job->pdf)->nextobject;
+ dk3sto_it_reset((job->pdf)->i_pages);
+ while((pa = (dk3_pdf_page_t *)dk3sto_it_next((job->pdf)->i_pages)) != NULL)
+ {
+ if(!(job->firstPageObjectNumber)) {
+ job->firstPageObjectNumber = on;
+ job->firstPageHeight = pa->mby1;
+ }
+ /*
+ Each page consumes at least two object numbers:
+ Page object and page content stream object.
+ */
+ pa->objno = on++;
+ on++;
+ /*
+ If the page uses XObjects we must create an
+ XObject dictionary.
+ */
+ if((pa->s_xobjects) && (pa->i_xobjects)) { on++; }
+ }
+ (job->pdf)->nextobject = on;
+
+
+#line 3727 "dk3pdf.ctr"
+}
+
+
+
+int
+dk3pdf_write_file_progress(
+ dk3_pdf_t *pdf,
+ FILE *ofile,
+ void *pcomm,
+ int minpb,
+ int maxpb
+)
+{
+ dk3_pdf_writer_job_t job; /* Writer job. */
+ int back = 0;
+
+
+#line 3743 "dk3pdf.ctr"
+ if((pdf) && (ofile)) {
+
+#line 3744 "dk3pdf.ctr"
+ if(pdf->cp) { dk3pdf_close_page(pdf); }
+ if(dk3pdf_job_init(&job, pdf, ofile)) {
+ back = 1;
+ dk3pdf_enumerate_pages(&job);
+ if(!dk3pdf_write_file_start(&job)) { back = 0; }
+ if(!dk3pdf_write_file_xobjects(&job, pcomm, minpb, maxpb)) { back = 0; }
+ if(!dk3pdf_write_file_pages(&job, pcomm, minpb, maxpb)) { back = 0; }
+ if(!dk3pdf_write_file_end(&job)) { back = 0; }
+ }
+ dk3pdf_job_end(&job);
+ } else {
+ if(!(pdf)) {
+
+#line 3756 "dk3pdf.ctr"
+ }
+ if(!(ofile)) {
+
+#line 3758 "dk3pdf.ctr"
+ }
+ }
+
+#line 3760 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+int
+dk3pdf_write_file(dk3_pdf_t *pdf, FILE *ofile)
+{
+ int back;
+
+
+#line 3770 "dk3pdf.ctr"
+ back = dk3pdf_write_file_progress(pdf, ofile, NULL, 0, 1000);
+
+
+#line 3772 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+/** Write point coordinates to output filter.
+ @param of Output filter.
+ @param x X value.
+ @param y Y value.
+*/
+static
+void
+dk3pdf_write_point(dk3_of_t *of, double x, double y)
+{
+ dk3pdf_write_double(of, x);
+ dk3of_write_c8_string(of, dk3pdf_c8_kw[1]);
+ dk3pdf_write_double(of, y);
+ dk3of_write_c8_string(of, dk3pdf_c8_kw[1]);
+
+
+#line 3791 "dk3pdf.ctr"
+}
+
+
+
+int
+dk3pdf_newpath_moveto(dk3_pdf_t *pdf, double x, double y)
+{
+ int back = 0;
+
+
+#line 3800 "dk3pdf.ctr"
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ dk3pdf_write_point((pdf->cp)->tempof, x, y);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[71]);
+ }
+ }
+ }
+
+#line 3809 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+int
+dk3pdf_lineto(dk3_pdf_t *pdf, double x, double y)
+{
+ int back = 0;
+
+
+#line 3819 "dk3pdf.ctr"
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ dk3pdf_write_point((pdf->cp)->tempof, x, y);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[72]);
+ }
+ }
+ }
+
+#line 3828 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+int
+dk3pdf_curveto(
+ dk3_pdf_t *pdf,
+ double xcs, double ycs,
+ double xce, double yce,
+ double xe, double ye
+)
+{
+ int back = 0;
+
+
+#line 3843 "dk3pdf.ctr"
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ dk3pdf_write_point((pdf->cp)->tempof, xcs, ycs);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]);
+ dk3pdf_write_point((pdf->cp)->tempof, xce, yce);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]);
+ dk3pdf_write_point((pdf->cp)->tempof, xe, ye);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[89]);
+ }
+ }
+ }
+
+#line 3856 "dk3pdf.ctr"
+ return back;
+}
+
+
+int
+dk3pdf_set_nonstroking_gray(dk3_pdf_t *pdf, double g)
+{
+ int back = 0;
+ double ng; /* Corrected gray value. */
+
+
+#line 3866 "dk3pdf.ctr"
+ ng = dk3pdf_to_range(0.0, 1.0, g);
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ dk3pdf_write_double((pdf->cp)->tempof, ng);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[73]);
+ }
+ }
+ }
+
+#line 3877 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+int
+dk3pdf_set_stroking_gray(dk3_pdf_t *pdf, double g)
+{
+ int back = 0;
+ double ng; /* Corrected gray value. */
+
+
+#line 3888 "dk3pdf.ctr"
+ ng = dk3pdf_to_range(0.0, 1.0, g);
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ dk3pdf_write_double((pdf->cp)->tempof, ng);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[74]);
+ }
+ }
+ }
+
+#line 3899 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+int
+dk3pdf_closepath_fill_stroke_nz(dk3_pdf_t *pdf)
+{
+ int back = 0;
+
+
+#line 3909 "dk3pdf.ctr"
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[75]);
+ }
+ }
+ }
+
+#line 3917 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+
+int
+dk3pdf_closepath_fill_stroke_eo(dk3_pdf_t *pdf)
+{
+ int back = 0;
+
+
+#line 3928 "dk3pdf.ctr"
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[77]);
+ }
+ }
+ }
+
+#line 3936 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+int
+dk3pdf_closepath(dk3_pdf_t *pdf)
+{
+ int back = 0;
+
+
+#line 3946 "dk3pdf.ctr"
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[81]);
+ }
+ }
+ }
+
+#line 3954 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+int
+dk3pdf_fill_nz(dk3_pdf_t *pdf)
+{
+ int back = 0;
+
+
+#line 3964 "dk3pdf.ctr"
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[79]);
+ }
+ }
+ }
+
+#line 3972 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+int
+dk3pdf_fill_eo(dk3_pdf_t *pdf)
+{
+ int back = 0;
+
+
+#line 3982 "dk3pdf.ctr"
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[80]);
+ }
+ }
+ }
+
+#line 3990 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+int
+dk3pdf_clip_eo(dk3_pdf_t *pdf)
+{
+ int back = 0;
+
+
+#line 4000 "dk3pdf.ctr"
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[88]);
+ }
+ }
+ }
+
+#line 4008 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+int
+dk3pdf_clip_nz(dk3_pdf_t *pdf)
+{
+ int back = 0;
+
+
+#line 4018 "dk3pdf.ctr"
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[97]);
+ }
+ }
+ }
+
+#line 4026 "dk3pdf.ctr"
+ return back;
+}
+
+
+int
+dk3pdf_nonstroking_rgb(dk3_pdf_t *pdf, double r, double g, double b)
+{
+ int back = 0;
+ double nr; /* Corrected red. */
+ double ng; /* Corrected green. */
+ double nb; /* Corrected blue. */
+
+
+#line 4038 "dk3pdf.ctr"
+ nr = dk3pdf_to_range(0.0, 1.0, r);
+ ng = dk3pdf_to_range(0.0, 1.0, g);
+ nb = dk3pdf_to_range(0.0, 1.0, b);
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ dk3pdf_write_double((pdf->cp)->tempof, nr);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]);
+ dk3pdf_write_double((pdf->cp)->tempof, ng);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]);
+ dk3pdf_write_double((pdf->cp)->tempof, nb);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[82]);
+ }
+ }
+ }
+
+#line 4055 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+int
+dk3pdf_stroking_rgb(dk3_pdf_t *pdf, double r, double g, double b)
+{
+ int back = 0;
+ double nr; /* Corrected red. */
+ double ng; /* Corrected green. */
+ double nb; /* Corrected blue. */
+
+
+#line 4068 "dk3pdf.ctr"
+ nr = dk3pdf_to_range(0.0, 1.0, r);
+ ng = dk3pdf_to_range(0.0, 1.0, g);
+ nb = dk3pdf_to_range(0.0, 1.0, b);
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ dk3pdf_write_double((pdf->cp)->tempof, nr);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]);
+ dk3pdf_write_double((pdf->cp)->tempof, ng);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]);
+ dk3pdf_write_double((pdf->cp)->tempof, nb);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[83]);
+ }
+ }
+ }
+
+#line 4085 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+int
+dk3pdf_set_linecap(dk3_pdf_t *pdf, int lc)
+{
+ int back = 0;
+
+
+#line 4095 "dk3pdf.ctr"
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ switch(lc) {
+ case DK3_LINECAP_SQUARE: {
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[84]);
+ } break;
+ case DK3_LINECAP_ROUND: {
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[67]);
+ } break;
+ default: {
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[20]);
+ } break;
+ }
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[85]);
+ }
+ }
+ }
+
+#line 4114 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+int
+dk3pdf_set_linejoin(dk3_pdf_t *pdf, int lj)
+{
+ int back = 0;
+
+
+#line 4124 "dk3pdf.ctr"
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ switch(lj) {
+ case DK3_LINEJOIN_BEVEL: {
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[84]);
+ } break;
+ case DK3_LINEJOIN_ROUND: {
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[67]);
+ } break;
+ default: {
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[20]);
+ } break;
+ }
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[90]);
+ }
+ }
+ }
+
+#line 4143 "dk3pdf.ctr"
+ return back;
+}
+
+
+int
+dk3pdf_stroke(dk3_pdf_t *pdf)
+{
+ int back = 0;
+
+
+#line 4152 "dk3pdf.ctr"
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[94]);
+ }
+ }
+ }
+
+#line 4160 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+
+int
+dk3pdf_set_linewidth(dk3_pdf_t *pdf, double lw)
+{
+ int back = 0;
+
+
+#line 4171 "dk3pdf.ctr"
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ dk3pdf_write_double((pdf->cp)->tempof, lw);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[87]);
+ }
+ }
+ }
+
+#line 4180 "dk3pdf.ctr"
+ return back;
+}
+
+
+
+int
+dk3pdf_set_line_dash(dk3_pdf_t *pdf, double *sv, size_t nsv, double ph)
+{
+ size_t i;
+ int back = 0;
+ if((pdf) && (sv)) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ /* [ */
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[92]);
+ for(i = 0; i < nsv; i++) {
+ if(0 < i) {
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]);
+ }
+ dk3pdf_write_double((pdf->cp)->tempof, sv[i]);
+ }
+ /* ] */
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[93]);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]);
+ /* phase */
+ dk3pdf_write_double((pdf->cp)->tempof, ph);
+ /* d + newline */
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[91]);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3pdf_write_debug_line(dk3_pdf_t *pdf, char const *txt)
+{
+ int back = 0;
+ if((pdf) && (txt)) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[98]);
+ dk3of_write_c8_string((pdf->cp)->tempof, txt);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[0]);
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk3pdf.ctr b/support/dktools/dk3pdf.ctr
new file mode 100644
index 0000000000..afcab2fd66
--- /dev/null
+++ b/support/dktools/dk3pdf.ctr
@@ -0,0 +1,4233 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Create PDF writer structure.
+ @param app Application structure, required here.
+ @return Pointer to new structure on success, NULL on error.
+*/
+dk3_pdf_t *
+dk3pdf_open_app(dk3_app_t *app);
+
+/** Write PDF to output file.
+ @param pdf PDF writer structure.
+ @param ofile Output file.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_write_file(dk3_pdf_t *pdf, FILE *ofile);
+
+/** Write PDF to output file.
+ @param pdf PDF writer structure.
+ @param ofile Output file.
+ @param pcomm Communicator object.
+ @param minpb Minimum progress bar value.
+ @param maxpb Maximum progress bar value.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_write_file_progress(
+ dk3_pdf_t *pdf,
+ FILE *ofile,
+ void *pcomm,
+ int minpb,
+ int maxpb
+);
+
+/** Destroy PDF writer structure, release memory.
+ @param pdf Structure to destroy.
+*/
+void
+dk3pdf_close(dk3_pdf_t *pdf);
+
+/** Prepare media box for next page to open.
+ @param pdf PDF writer structure.
+ @param x0 Left x.
+ @param x1 Right x.
+ @param y0 Bottom y.
+ @param y1 Top y.
+*/
+void
+dk3pdf_set_next_mediabox(
+ dk3_pdf_t *pdf,
+ long x0,
+ long x1,
+ long y0,
+ long y1
+);
+
+/** Open a new page.
+ @param pdf PDF writer structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_open_page(dk3_pdf_t *pdf);
+
+/** Open a new page, set clip path to media box.
+ @param pdf PDF writer structure.
+ @param wc Flag: With clip path setting.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_open_page_with_clip(dk3_pdf_t *pdf, int wc);
+
+/** Close the current page.
+ @param pdf PDF writer structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_close_page(dk3_pdf_t *pdf);
+
+/** Write save graphics state instruction to current page.
+ @param pdf PDF writer structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_gsave(dk3_pdf_t *pdf);
+
+/** Write restore graphics state instruction to current page.
+ @param pdf PDF writer structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_grestore(dk3_pdf_t *pdf);
+
+/** Translate coordinates, use long values.
+ @param pdf PDF writer structure.
+ @param x X translation.
+ @param y Y translation.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_translate_long(dk3_pdf_t *pdf, long x, long y);
+
+/** Translate coordinates, use double values.
+ @param pdf PDF writer structure.
+ @param x X translation.
+ @param y Y translation.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_translate_double(dk3_pdf_t *pdf, double x, double y);
+
+/** Rotate coordinates, use integer value.
+ @param pdf PDF writer structure.
+ @param angle Rotation angle in degree.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_rotate_int(dk3_pdf_t *pdf, int angle);
+
+/** Rotate coordinates, use double value.
+ @param pdf PDF writer structure.
+ @param angle Rotation angle in degree.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_rotate_double(dk3_pdf_t *pdf, double angle);
+
+/** Scale coordinates, use long values.
+ @param pdf PDF writer structure.
+ @param x X scale factor.
+ @param y Y scale factor.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_scale_long(dk3_pdf_t *pdf, long x, long y);
+
+/** Scale coordinates, use double values.
+ @param pdf PDF writer structure.
+ @param x X scale factor.
+ @param y Y scale factor.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_scale_double(dk3_pdf_t *pdf, double x, double y);
+
+/** Add XObject to current page.
+ @param pdf PDF writer structure.
+ @param xo XObject to add.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_add_xobject_to_page(dk3_pdf_t *pdf, dk3_pdf_xobject_t *xo);
+
+/** Add image.
+ @param pdf PDF writer structure.
+ @param bif Image, the current frame will be added.
+ @param opt Conversion options.
+ @param pc Communicator object.
+ @param min Minimum progress bar value (0-1000).
+ @param max Maximum progress bar value (0-1000).
+ @return Pointer to object on success, NULL on error.
+*/
+dk3_pdf_xobject_t *
+dk3pdf_add_image_progress(
+ dk3_pdf_t *pdf,
+ dk3_bif_t *bif,
+ dk3_bm_eps_options_t *opt,
+ void *pc,
+ int min,
+ int max
+);
+
+/** Add image.
+ @param pdf PDF writer structure.
+ @param bif Image, the current frame will be added.
+ @param opt Conversion options.
+ @return Pointer to object on success, NULL on error.
+*/
+dk3_pdf_xobject_t *
+dk3pdf_add_image(
+ dk3_pdf_t *pdf,
+ dk3_bif_t *bif,
+ dk3_bm_eps_options_t *opt
+);
+
+/** PDF newpath and lineto. Start new path and move to specified position.
+ @param pdf PDF writer structure.
+ @param x New x position.
+ @param y New y position.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_newpath_moveto(dk3_pdf_t *pdf, double x, double y);
+
+/** PDF lineto.
+ @param pdf PDF writer structure.
+ @param x New x
+ @param y New y.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_lineto(dk3_pdf_t *pdf, double x, double y);
+
+/** PDF curveto.
+ @param pdf PDF writer structure.
+ @param xcs Control point X near start.
+ @param ycs Control point Y near start.
+ @param xce Control point X near end.
+ @param yce Control point Y near end.
+ @param xe End point X.
+ @param ye End point Y.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_curveto(
+ dk3_pdf_t *pdf,
+ double xcs, double ycs,
+ double xce, double yce,
+ double xe, double ye
+);
+
+/** Set nonstroking gray.
+ @param pdf PDF writer structure.
+ @param g New gray value.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_set_nonstroking_gray(dk3_pdf_t *pdf, double g);
+
+/** Set stroking gray.
+ @param pdf PDF writer structure.
+ @param g New gray value.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_set_stroking_gray(dk3_pdf_t *pdf, double g);
+
+/** Close path, fill (non-zero winding rule), and stroke path.
+ @param pdf PDF writer structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_closepath_fill_stroke_nz(dk3_pdf_t *pdf);
+
+/** Close path, fill (even/odd rule), and stroke path.
+ @param pdf PDF writer structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_closepath_fill_stroke_eo(dk3_pdf_t *pdf);
+
+/** Close path.
+ @param pdf PDF writer structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_closepath(dk3_pdf_t *pdf);
+
+/** Fill current path (non-zero winding rule).
+ @param pdf PDF writer structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_fill_nz(dk3_pdf_t *pdf);
+
+/** Fill current path (even/odd rule).
+ @param pdf PDF writer structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_fill_eo(dk3_pdf_t *pdf);
+
+/** Clip to current path (even/odd rule).
+ @param pdf PDF writer structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_clip_eo(dk3_pdf_t *pdf);
+
+/** Clip to current path (non-zero rule).
+ @param pdf PDF writer structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_clip_nz(dk3_pdf_t *pdf);
+
+/** Set RGB color for nonstroking operations.
+ @param pdf PDF writer structure.
+ @param r Red.
+ @param g Green.
+ @param b Blue.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_nonstroking_rgb(dk3_pdf_t *pdf, double r, double g, double b);
+
+/** Set RGB color for stroking operations.
+ @param pdf PDF writer structure.
+ @param r Red.
+ @param g Green.
+ @param b Blue.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_stroking_rgb(dk3_pdf_t *pdf, double r, double g, double b);
+
+/** Set line cap mode.
+ @param pdf PDF writer structure.
+ @param lc Line cap DK3_LINECAP_xxx, see @ref linecap.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_set_linecap(dk3_pdf_t *pdf, int lc);
+
+/** Set line join mode.
+ @param pdf PDF writer structure.
+ @param lj Line cap DK3_LINECAP_xxx, see @ref linecap.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_set_linejoin(dk3_pdf_t *pdf, int lj);
+
+/** Set line dash pattern.
+ @param pdf PDF writer structure.
+ @param sv Style values array.
+ @param nsv Number of elements in sv.
+ @param ph Phase (initial shift).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_set_line_dash(dk3_pdf_t *pdf, double *sv, size_t nsv, double ph);
+
+/** Stroke current path.
+ @param pdf PDF writer structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_stroke(dk3_pdf_t *pdf);
+
+/** Set line width for stroke operations.
+ @param pdf PDF writer structure.
+ @param lw New line width.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_set_linewidth(dk3_pdf_t *pdf, double lw);
+
+/** Create image XObject.
+ @param pdf PDF writer structure.
+ @param bif Image, the current frame will be added.
+ @param opt Conversion options.
+ @param pc Communication object.
+ @param min Minimum progress bar value (0-1000).
+ @param max Maximum progress bar value (0-1000).
+ @return Pointer to new object on success, NULL on error.
+*/
+dk3_pdf_xobject_t *
+dk3pdf_create_ixobject_progress(
+ dk3_pdf_t *pdf,
+ dk3_bif_t *bif,
+ dk3_bm_eps_options_t *opt,
+ void *pc,
+ int min,
+ int max
+);
+
+/** Write debug line to graphics contents stream.
+ @param pdf PDF output structure.
+ @param txt Text to write.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_write_debug_line(dk3_pdf_t *pdf, char const *txt);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+/*
+ Object numbers
+ --------------
+ 1 Info object (producer)
+ 2 Root object (type catalog, reference to pages object)
+ 3 Pages object, reference to page)
+
+ Xobject dictionary object (assign names to object numbers)
+
+ Page object (references to xobject dictionary, contents stream)
+ Page contents stream object, compressed
+
+*/
+
+
+
+#include "dk3all.h"
+#include "dk3pdf.h"
+#include "dk3bmj.h"
+#include "dk3bif.h"
+#include "dk3bifa.h"
+
+
+$!trace-include
+
+
+
+/** Start position of PDF object.
+*/
+typedef struct {
+
+ /** Object number.
+ */
+ unsigned long objno;
+
+ /** Start position in file or stream.
+ */
+ dk3_um_t startpos;
+
+} dk3_pdf_object_start_t;
+
+
+
+/** Job information for PDF writing.
+*/
+typedef struct {
+
+ /** The PDF writer structure to write to file.
+ */
+ dk3_pdf_t *pdf;
+
+ /** Output file.
+ */
+ FILE *of;
+
+ /** Output stream.
+ */
+ dk3_stream_t *os;
+
+ /** Object start position collection.
+ */
+ dk3_sto_t *s_objstart;
+
+ /** Iterator for object start positions.
+ */
+ dk3_sto_it_t *i_objstart;
+
+ /** Object number for first page to show.
+ */
+ unsigned long firstPageObjectNumber;
+
+ /** Largest object number seen.
+ */
+ unsigned long largestObjectNumber;
+
+ /** Height of first page.
+ */
+ dk3_bif_coord_t firstPageHeight;
+
+} dk3_pdf_writer_job_t;
+
+
+
+/** Conversion job for one image.
+*/
+typedef struct {
+
+ /** Output PDF.
+ */
+ dk3_pdf_t *pdf;
+
+ /** XObject to produce.
+ */
+ dk3_pdf_xobject_t *xo;
+
+ /** Output filter.
+ */
+ dk3_of_t *of;
+
+ /** Conversion option set.
+ */
+ dk3_bm_eps_options_t *opt;
+
+ /** Input image.
+ */
+ dk3_bif_t *bif;
+
+ /** Conversion procedure, DK3_BMEPS_xxx, see @ref bmepscompression.
+ */
+ int procedure;
+
+ /** Flag: Color data found.
+ */
+ int h_color;
+
+ /** Flag: Alpha data found.
+ */
+ int h_alpha;
+
+ /** Bits per component.
+ */
+ int bpc;
+
+ /** Flag: Use dct.
+ */
+ int use_dct;
+
+} dk3_pdf_image_job_t;
+
+
+
+/** Keywords used by the dk3pdf module.
+*/
+static char const * dk3pdf_c8_kw[] = {
+/* 0 */ "\n",
+/* 1 */ " ",
+/* 2 */ "q\n",
+/* 3 */ "Q\n",
+/* 4 */ "cm\n",
+/* 5 */ "/X",
+/* 6 */ " Do\n",
+/* 7 */ "%PDF-1.4\n",
+/* 8 */ " 0 obj\n",
+/* 9 */ "endobj\n",
+/* 10 */ "<<\n/Producer (http://dktools.sourceforge.net)\n",
+/* 11 */ "<<\n",
+/* 12 */ ">>\n",
+/* 13 */ "/Type /Catalog\n",
+/* 14 */ "/Pages 3 0 R\n",
+/* 15 */ "/OpenAction [ ",
+/* 16 */ " 0 R /FitH ",
+/* 17 */ " ]\n",
+/* 18 */ "xref 0 ",
+/* 19 */ "0000000000 65535 f \n",
+/* 20 */ "0",
+/* 21 */ " 00000 n \n",
+/* 22 */ "trailer\n<< /Size ",
+/* 23 */ " /Info 1 0 R /Root 2 0 R >>\nstartxref\n",
+/* 24 */ "\n%%EOF\n",
+/* 25 */ "stream\n",
+/* 26 */ "\nendstream\n",
+/* 27 */ "/Type /XObject\n",
+/* 28 */ "/Subtype /Image\n",
+/* 29 */ "/Width ",
+/* 30 */ "/Height ",
+/* 31 */ "/BitsPerComponent ",
+/* 32 */ "/ColorSpace ",
+/* 33 */ "/DeviceCMYK\n",
+/* 34 */ "/DeviceGray\n",
+/* 35 */ "/DeviceRGB\n",
+/* 36 */ "/Filter ",
+/* 37 */ "/FlateDecode\n",
+/* 38 */ "/DCTDecode\n",
+/* 39 */ "/Length ",
+/* 40 */ "/Decode [ 1 0 1 0 1 0 1 0 ]\n",
+/* 41 */ "/Predictor 2\n",
+/* 42 */ "/Predictor 11\n",
+/* 43 */ "/Predictor 12\n",
+/* 44 */ "/Predictor 13\n",
+/* 45 */ "/Predictor 14\n",
+/* 46 */ "/SMask ",
+/* 47 */ " 0 R\n",
+/* 48 */ "/Type /Page\n",
+/* 49 */ "/Parent 3 0 R\n",
+/* 50 */ "/MediaBox [ %ld %ld %ld %ld ]\n",
+/* 51 */ "/Resources ",
+/* 52 */ "/ProcSet [ /PDF /ImageB /ImageC ]\n",
+/* 53 */ "/XObject %lu 0 R\n",
+/* 54 */ "/Contents %lu 0 R\n",
+/* 55 */ "/Group << /S /Transparency /I true /CS /DeviceRGB >>\n",
+/* 56 */ "/X%lu %lu 0 R\n",
+/* 57 */ "/Type /Pages\n",
+/* 58 */ "/Count ",
+/* 59 */ "%lu\n",
+/* 60 */ "/Kids [\n",
+/* 61 */ "]\n",
+/* 62 */ "%lu 0 R\n",
+/* 63 */ "/Interpolate true\n",
+/* 64 */ "/DecodeParms <<\n",
+/* 65 */ "/Colors ",
+/* 66 */ "4",
+/* 67 */ "1",
+/* 68 */ "3",
+/* 69 */ "/Columns ",
+/* 70 */ "%lg",
+/* 71 */ "m\n", /* PDF moveto */
+/* 72 */ "l\n", /* PDF lineto */
+/* 73 */ "g\n", /* PDF nonstroke setgray */
+/* 74 */ "G\n", /* PDF stroke setgray */
+/* 75 */ "b\n", /* PDF closepath, fill (nonzero), and stroke */
+/* 76 */ "B\n", /* PDF fill (nonzero), and stroke */
+/* 77 */ "b*\n", /* PDF closepath, fill (even/odd), and stroke */
+/* 78 */ "B*\n", /* PDF fill (even/odd), and stroke */
+/* 79 */ "f\n", /* PDF fill (nonzero) */
+/* 80 */ "f*\n", /* PDF fill (even/odd) */
+/* 81 */ "h\n", /* PDF closepath */
+/* 82 */ "rg\n", /* PDF setrgbcolor (nonstroking) */
+/* 83 */ "RG\n", /* PDF setrgbcolor (stroking) */
+/* 84 */ "2", /* PDF Line cap style square */
+/* 85 */ " J\n", /* PDF setlinecap */
+/* 86 */ "s\n", /* PDF closepath and stroke */
+/* 87 */ " w\n", /* PDF setlinewidth */
+/* 88 */ "W* n\n", /* PDF eoclip */
+/* 89 */ "c\n", /* PDF curveto */
+/* 90 */ " j\n", /* PDF setlinejoin */
+/* 91 */ " d\n", /* PDF setdash */
+/* 92 */ "[",
+/* 93 */ "]",
+/* 94 */ " S\n", /* PDF stroke */
+/* 95 */ "%ld",
+/* 96 */ " re W n\n", /* PDF re eoclip */
+/* 97 */ " W n\n",
+/* 98 */ "% ",
+/* 99 */ "0",
+/* 100 */ "/CropBox [ %ld %ld %ld %ld ]\n",
+/* 101 */ "%04d%02d%02d%02d%02d%02d",
+/* 102 */ "/CreationDate (D:",
+/* 103 */ ")\n/ModDate (D:",
+/* 104 */ ")\n",
+};
+
+
+
+/** Adjust a value to a given range.
+ @param min Range minimum.
+ @param max Range maximum.
+ @param val Uncorrected value.
+ @return Value, corrected if necessary.
+*/
+static
+double
+dk3pdf_to_range(double min, double max, double val)
+{
+ double back;
+ $? "+ dk3pdf_to_range min=%lg max=%lg val=%lg", min, max, val
+ back = val;
+ if(back < min) { back = min; }
+ if(back > max) { back = max; } $? "- dk3pdf_to_range %lg", back
+ return back;
+}
+
+
+
+/** Compare to PDF pages.
+ @param l Left pointer.
+ @param r Right pointer.
+ @param cr Comparison criteria (0=page/page, 1=page/number).
+ @return Comparison result.
+*/
+static
+int
+dk3pdf_compare_pages(void const *l, void const *r, int cr)
+{
+ dk3_pdf_page_t const *pl; /* Left page object. */
+ dk3_pdf_page_t const *pr; /* Right page object. */
+ unsigned long const *ul; /* Page number. */
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (dk3_pdf_page_t const *)l;
+ switch(cr) {
+ case 1: {
+ ul = (unsigned long const *)r;
+ if(pl->pageno > *ul) {
+ back = 1;
+ } else {
+ if(pl->pageno < *ul) {
+ back = -1;
+ }
+ }
+ } break;
+ default: {
+ pr = (dk3_pdf_page_t const *)r;
+ if(pl->pageno > pr->pageno) {
+ back = 1;
+ } else {
+ if(pl->pageno < pr->pageno) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Compare two object start entries.
+ @param l Left pointer.
+ @param r Right pointer.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+static
+int
+dk3pdf_compare_object_start(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3_pdf_object_start_t const *pl; /* Left object start. */
+ dk3_pdf_object_start_t const *pr; /* Right object start. */
+ if(l) {
+ if(r) {
+ pl = (dk3_pdf_object_start_t const *)l;
+ pr = (dk3_pdf_object_start_t const *)r;
+ if(pl->objno > pr->objno) {
+ back = 1;
+ } else {
+ if(pl->objno < pr->objno) {
+ back = -1;
+ }
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Compare Xobjects.
+ @param l Left object.
+ @param r Right object.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result (0=xobject/xobject, 1=xobject/number).
+*/
+static
+int
+dk3pdf_compare_xobjects(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3_pdf_xobject_t const *pl; /* Left XObject. */
+ dk3_pdf_xobject_t const *pr; /* Right XObject. */
+ unsigned long const *ul; /* Right XObject number. */
+ if(l) {
+ if(r) {
+ pl = (dk3_pdf_xobject_t const *)l;
+ switch(cr) {
+ case 1: {
+ ul = (unsigned long const *)r;
+ if(pl->objno > *ul) {
+ back = 1;
+ } else {
+ if(pl->objno < *ul) {
+ back = -1;
+ }
+ }
+ } break;
+ default: {
+ pr = (dk3_pdf_xobject_t const *)r;
+ if(pl->objno > pr->objno) {
+ back = 1;
+ } else {
+ if(pl->objno < pr->objno) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Initialize PDF job.
+ @param job PDF creator job.
+ @param pdf PDF structure.
+ @param of Output filter.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3pdf_job_init(dk3_pdf_writer_job_t *job, dk3_pdf_t *pdf, FILE *of)
+{
+ int back = 0;
+ $? "+ dk3pdf_job_init"
+ job->of = NULL;
+ job->os = NULL;
+ job->s_objstart = NULL;
+ job->i_objstart = NULL;
+ job->largestObjectNumber = 0UL;
+ job->firstPageObjectNumber = 0UL;
+ job->firstPageHeight = 0L;
+ if((pdf) && (of)) {
+ job->of = of;
+ job->pdf = pdf;
+ job->os = dk3stream_open_file_app(of, DK3_STREAM_FLAG_WRITE, pdf->app);
+ if(job->os) {
+ job->s_objstart = dk3sto_open_app(pdf->app);
+ if(job->s_objstart) {
+ dk3sto_set_comp(job->s_objstart, dk3pdf_compare_object_start, 0);
+ job->i_objstart = dk3sto_it_open(job->s_objstart);
+ if(job->i_objstart) { $? ". ok"
+ back = 1;
+ } else { $? "! iterator"
+ }
+ } else { $? "! storage"
+ }
+ } else { $? "! stream"
+ }
+ } else { $? "! arguments"
+ } $? "- dk3pdf_job_init %d", back
+ return back;
+}
+
+
+
+/** Clean up PDF writer job.
+ @param job Job to clean up.
+*/
+static
+void
+dk3pdf_job_end(dk3_pdf_writer_job_t *job)
+{
+ dk3_pdf_position_t *pos; /* Traverse start position collection. */
+ $? "+ dk3pdf_job_end"
+ if(job->os) {
+ dk3stream_close(job->os);
+ }
+ job->os = NULL;
+ if(job->i_objstart) {
+ dk3sto_it_reset(job->i_objstart);
+ while((pos = (dk3_pdf_position_t *)dk3sto_it_next(job->i_objstart)) != NULL)
+ {
+ dk3_delete(pos);
+ }
+ dk3sto_it_close(job->i_objstart);
+ }
+ job->i_objstart = NULL;
+ if(job->s_objstart) {
+ dk3sto_close(job->s_objstart);
+ }
+ job->s_objstart = NULL; $? "- dk3pdf_job_end"
+}
+
+
+
+/** Destroy XObject, release memory.
+ @param xo Object to destroy.
+*/
+static
+void
+dk3pdf_xobject_delete(dk3_pdf_xobject_t *xo)
+{
+ $? "+ dk3pdf_xobject_delete"
+ if(xo) { $? ". object %lu", xo->objno
+ if(xo->tempfilename) {
+ dk3sf_remove_file_app(xo->tempfilename, NULL);
+ dk3_delete(xo->tempfilename);
+ }
+ xo->tempfilename = NULL;
+ xo->mask = NULL;
+ xo->width = 0L;
+ xo->height = 0L;
+ xo->objno = 0UL;
+ xo->xot = 0;
+ xo->procedure = DK3_BMEPS_RGB_FLATE;
+ xo->bpc = 0;
+ xo->dct = 0;
+ xo->pred = 0;
+ dk3_delete(xo);
+ } $? "- dk3pdf_xobject_delete"
+}
+
+
+
+/** Create image XObject, allocate memory.
+ @param pdf PDF structure.
+ @return Pointer to new XObject on success, NULL on error.
+*/
+static
+dk3_pdf_xobject_t *
+dk3pdf_xobject_new(dk3_pdf_t *pdf)
+{
+ dkChar buf[DK3_MAX_PATH]; /* Buffer for conversion. */
+ dk3_pdf_xobject_t *back = NULL;
+ int ok = 0; /* Flag: Success so far. */
+ $? "+ dk3pdf_xobject_new"
+ back = dk3_new_app(dk3_pdf_xobject_t,1,pdf->app);
+ if(back) {
+ back->tempfilename = NULL;
+ back->mask = NULL;
+ back->width = 0L;
+ back->height = 0L;
+ back->objno = 0UL;
+ back->xot = DK3_PDF_XO_TYPE_IMAGE;
+ back->procedure = 0;
+ back->bpc = 8;
+ back->dct = 0;
+ back->pred = 0;
+ back->slgt = DK3_UM_0;
+ back->adobe_marker_found = 0;
+ back->interpolate = 0;
+ if(dk3app_get_temp_file_name(pdf->app, buf, DK3_SIZEOF(buf,dkChar))) {
+ back->tempfilename = dk3str_dup_app(buf, pdf->app);
+ if(back->tempfilename) {
+ ok = 1;
+ }
+ }
+ if(!(ok)) {
+ dk3pdf_xobject_delete(back);
+ back = NULL;
+ }
+ } $? "- dk3pdf_xobject_new %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+/** Destroy page object, release memory.
+ @param pa Page object to destroy.
+*/
+void
+dk3pdf_page_delete(dk3_pdf_page_t *pa)
+{
+ $? "+ dk3pdf_page_delete"
+ if(pa) { $? ". object %lu page %lu", pa->objno, pa->pageno
+ if(pa->tempof) {
+ dk3of_close(pa->tempof);
+ }
+ if(pa->tempstream) {
+ dk3stream_close(pa->tempstream);
+ }
+ if(pa->tempfile) {
+ fclose(pa->tempfile);
+ }
+ if(pa->tempfilename) {
+ dk3sf_remove_file_app(pa->tempfilename,NULL);
+ dk3_delete(pa->tempfilename);
+ }
+ if(pa->i_xobjects) {
+ dk3sto_it_close(pa->i_xobjects);
+ }
+ if(pa->s_xobjects) {
+ dk3sto_close(pa->s_xobjects);
+ }
+ pa->tempfilename = NULL;
+ pa->tempfile = NULL;
+ pa->tempstream = NULL;
+ pa->tempof = NULL;
+ pa->s_xobjects = NULL;
+ pa->i_xobjects = NULL;
+ pa->objno = 0UL;
+ pa->pageno = 0UL;
+ pa->mbx0 = 0L;
+ pa->mbx1 = 0L;
+ pa->mby0 = 0L;
+ pa->mby1 = 0L;
+ dk3_delete(pa);
+ } $? "- dk3pdf_page_delete"
+}
+
+
+
+/** Create new page object.
+ @param pdf PDF structure.
+ @return Pointer to new page object on success, NULL on error.
+*/
+static
+dk3_pdf_page_t *
+dk3pdf_page_new(dk3_pdf_t *pdf)
+{
+ dkChar fnb[DK3_MAX_PATH]; /* Conversion buffer. */
+ dk3_pdf_page_t *back = NULL;
+ int ok = 0; /* Flag: OK so far. */
+ $? "+ dk3pdf_page_new"
+ if(dk3app_get_temp_file_name(pdf->app, fnb, DK3_SIZEOF(fnb,dkChar))) {
+ back = dk3_new_app(dk3_pdf_page_t,1,pdf->app);
+ if(back) {
+ back->tempfilename = NULL;
+ back->tempfile = NULL;
+ back->tempstream = NULL;
+ back->tempof = NULL;
+ back->s_xobjects = NULL;
+ back->i_xobjects = NULL;
+ back->objno = 0UL;
+ back->pageno = pdf->nextpage;
+ back->mbx0 = pdf->mbx0;
+ back->mbx1 = pdf->mbx1;
+ back->mby0 = pdf->mby0;
+ back->mby1 = pdf->mby1;
+ back->slgt = DK3_UM_0;
+ back->tempfilename = dk3str_dup_app(fnb, pdf->app);
+ if(back->tempfilename) {
+ back->tempfile = dk3sf_fopen_app(
+ back->tempfilename,
+ dk3app_not_localized(53),
+ pdf->app
+ );
+ }
+ if(back->tempfile) {
+ back->tempstream = dk3stream_open_file_app(
+ back->tempfile,
+ DK3_STREAM_FLAG_WRITE,
+ pdf->app
+ );
+ }
+ if(back->tempstream) {
+ back->tempof = dk3of_open_app(back->tempstream, pdf->app);
+ if(back->tempof) {
+ if(dk3of_add_cell(back->tempof, DK3_OF_CELL_TYPE_FLATE)) {
+ back->s_xobjects = dk3sto_open_app(pdf->app);
+ if(back->s_xobjects) {
+ back->i_xobjects = dk3sto_it_open(back->s_xobjects);
+ if(back->i_xobjects) {
+ ok = 1;
+ }
+ }
+ }
+ }
+ }
+ if(!(ok)) {
+ dk3pdf_page_delete(back);
+ back = NULL;
+ }
+ }
+ } $? "- dk3pdf_page_new %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+
+dk3_pdf_t *
+dk3pdf_open_app(dk3_app_t *app)
+{
+ dk3_pdf_t *back = NULL;
+ int ok = 0; /* Flag: Success. */
+ $? "+ dk3pdf_open_app"
+ if(app) {
+ back = dk3_new_app(dk3_pdf_t,1,app);
+ if(back) {
+ back->app = app;
+ back->s_xobjects = NULL;
+ back->i_xobjects = NULL;
+ back->s_pages = NULL;
+ back->i_pages = NULL;
+ back->cp = NULL;
+ back->nextobject = 4UL;
+ back->nextpage = 0UL;
+ back->mbx0 = 0L;
+ back->mbx1 = 595L;
+ back->mby0 = 0L;
+ back->mby1 = 842L;
+ back->documentMode = 0;
+ back->s_xobjects = dk3sto_open_app(app);
+ if(back->s_xobjects) {
+ dk3sto_set_comp(back->s_xobjects, dk3pdf_compare_xobjects, 0);
+ back->i_xobjects = dk3sto_it_open(back->s_xobjects);
+ }
+ back->s_pages = dk3sto_open_app(app);
+ if(back->s_pages) {
+ dk3sto_set_comp(back->s_pages, dk3pdf_compare_pages, 0);
+ back->i_pages = dk3sto_it_open(back->s_pages);
+ }
+ if(back->s_xobjects) {
+ if(back->i_xobjects) {
+ if(back->s_pages) {
+ if(back->i_pages) {
+ ok = 1;
+ }
+ }
+ }
+ }
+ if(!(ok)) {
+ dk3pdf_close(back);
+ back = NULL;
+ }
+ }
+ } $? "- dk3pdf_open_app %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+void
+dk3pdf_close(dk3_pdf_t *pdf)
+{
+ dk3_pdf_xobject_t *xo; /* Traverse XObjects collection to clean up. */
+ dk3_pdf_page_t *pa; /* Traverse page collection to clean up. */
+ $? "+ dk3pdf_close"
+ if(pdf) {
+ if(pdf->s_xobjects) {
+ if(pdf->i_xobjects) {
+ dk3sto_it_reset(pdf->i_xobjects);
+ while((xo = (dk3_pdf_xobject_t *)dk3sto_it_next(pdf->i_xobjects))
+ != NULL
+ )
+ {
+ dk3pdf_xobject_delete(xo);
+ }
+ dk3sto_it_close(pdf->i_xobjects);
+ }
+ dk3sto_close(pdf->s_xobjects);
+ }
+ pdf->s_xobjects = NULL;
+ pdf->i_xobjects = NULL;
+ if(pdf->s_pages) {
+ if(pdf->i_pages) {
+ dk3sto_it_reset(pdf->i_pages);
+ while((pa = (dk3_pdf_page_t *)dk3sto_it_next(pdf->i_pages)) != NULL) {
+ dk3pdf_page_delete(pa);
+ }
+ dk3sto_it_close(pdf->i_pages);
+ }
+ dk3sto_close(pdf->s_pages);
+ }
+ pdf->s_pages = NULL;
+ pdf->i_pages = NULL;
+ pdf->s_xobjects = NULL;
+ dk3_delete(pdf);
+ } $? "- dk3pdf_close"
+}
+
+
+
+
+void
+dk3pdf_set_next_mediabox(
+ dk3_pdf_t *pdf,
+ long x0,
+ long x1,
+ long y0,
+ long y1
+)
+{
+ if(pdf) {
+ pdf->mbx0 = x0;
+ pdf->mbx1 = x1;
+ pdf->mby0 = y0;
+ pdf->mby1 = y1;
+ } $? "= dk3pdf_set_next_mediabox x0=%ld y0=%ld x1=%ld y1=%ld", x0, y0, x1, y1
+}
+
+
+
+/** Write long value.
+ @param of Output filter stream.
+ @param x Value to write.
+*/
+static
+void
+dk3pdf_write_long(dk3_of_t *of, long x)
+{
+ char buf[64]; /* Conversion buffer. */
+ sprintf(buf, dk3pdf_c8_kw[95], x);
+ dk3of_write_c8_string(of, buf); $? "= dk3pdf_write_long %ld", x
+}
+
+
+
+int
+dk3pdf_open_page_with_clip(dk3_pdf_t *pdf, int wc)
+{
+ dk3_pdf_page_t *np; /* Next page pointer. */
+ int back = 0;
+#if 1
+ long x;
+ long y;
+ long w;
+ long h;
+#endif
+ $? "+ dk3pdf_open_page"
+ if(pdf) {
+ if(pdf->cp) {
+ dk3pdf_close_page(pdf);
+ }
+ np = dk3pdf_page_new(pdf);
+ if(np) {
+ if(dk3sto_add(pdf->s_pages, (void *)np)) {
+ pdf->nextpage += 1UL;
+ pdf->cp = np;
+ if(np->tempof) {
+ back = dk3of_start_chunk(np->tempof);
+ if(back) {
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[2]);
+ if(wc) {
+ /* 2013-01-10: Set clip path.
+ */
+ if(np->mbx0 < np->mbx1) {
+ x = np->mbx0; w = np->mbx1 - np->mbx0;
+ } else {
+ x = np->mbx1; w = np->mbx0 - np->mbx1;
+ }
+ if(np->mby0 < np->mby1) {
+ y = np->mby0; h = np->mby1 - np->mby0;
+ } else {
+ y = np->mby1; h = np->mby0 - np->mby1;
+ }
+ dk3pdf_write_long((pdf->cp)->tempof, x);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]);
+ dk3pdf_write_long((pdf->cp)->tempof, y);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]);
+ dk3pdf_write_long((pdf->cp)->tempof, w);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]);
+ dk3pdf_write_long((pdf->cp)->tempof, h);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[96]);
+ }
+ }
+ }
+ }
+ }
+ } $? "- dk3pdf_open_page %d", back
+ return back;
+}
+
+
+
+int
+dk3pdf_open_page(dk3_pdf_t *pdf)
+{
+ int back;
+ back = dk3pdf_open_page_with_clip(pdf, 0);
+ return back;
+}
+
+
+
+int
+dk3pdf_close_page(dk3_pdf_t *pdf)
+{
+ dk3_stat_t stb; /* Stat buffer for contents stream file. */
+ int back = 0;
+ $? "+ dk3pdf_close_page"
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[3]);
+ back = dk3of_end_chunk((pdf->cp)->tempof);
+ dk3of_close((pdf->cp)->tempof);
+ (pdf->cp)->tempof = NULL;
+ }
+ if((pdf->cp)->tempstream) {
+ dk3stream_close((pdf->cp)->tempstream);
+ (pdf->cp)->tempstream = NULL;
+ }
+ if((pdf->cp)->tempfile) {
+ if(!dk3sf_fclose_fn_app(
+ (pdf->cp)->tempfile, (pdf->cp)->tempfilename, pdf->app
+ )
+ )
+ {
+ back = 0;
+ }
+ pdf->cp->tempfile = NULL;
+ }
+ if((pdf->cp)->tempfilename) {
+ if(dk3sf_stat_app(&stb, (pdf->cp)->tempfilename, pdf->app)) {
+ (pdf->cp)->slgt = stb.sz;
+ } else {
+ back = 0;
+ /* ERROR: Stat failed for content stream! */
+ }
+ }
+ }
+ pdf->cp = NULL;
+ } $? "- dk3pdf_close_page %d", back
+ return back;
+}
+
+
+
+int
+dk3pdf_gsave(dk3_pdf_t *pdf)
+{
+ int back = 0;
+ $? "+ dk3pdf_gsave"
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[2]);
+ back = 1;
+ }
+ }
+ } $? "- dk3pdf_gsave %d", back
+ return back;
+}
+
+
+
+int
+dk3pdf_grestore(dk3_pdf_t *pdf)
+{
+ int back = 0;
+ $? "+ dk3pdf_grestore"
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[3]);
+ back = 1;
+ }
+ }
+ } $? "- dk3pdf_grestore %d", back
+ return back;
+}
+
+
+
+/** Change current transformation matrix.
+ @param of Output filter to write to.
+ @param cmv Matrix values.
+*/
+static
+void
+dk3pdf_cm_long(dk3_of_t *of, long *cmv)
+{
+ char buf[64]; /* Conversion buffer. */
+ $? "+ dk3pdf_cm_long"
+ sprintf(buf, "%ld", cmv[0]);
+ dk3of_write_c8_string(of, buf);
+ dk3of_write_c8_string(of, dk3pdf_c8_kw[1]);
+ sprintf(buf, "%ld", cmv[1]);
+ dk3of_write_c8_string(of, buf);
+ dk3of_write_c8_string(of, dk3pdf_c8_kw[1]);
+ sprintf(buf, "%ld", cmv[2]);
+ dk3of_write_c8_string(of, buf);
+ dk3of_write_c8_string(of, dk3pdf_c8_kw[1]);
+ sprintf(buf, "%ld", cmv[3]);
+ dk3of_write_c8_string(of, buf);
+ dk3of_write_c8_string(of, dk3pdf_c8_kw[1]);
+ sprintf(buf, "%ld", cmv[4]);
+ dk3of_write_c8_string(of, buf);
+ dk3of_write_c8_string(of, dk3pdf_c8_kw[1]);
+ sprintf(buf, "%ld", cmv[5]);
+ dk3of_write_c8_string(of, buf);
+ dk3of_write_c8_string(of, dk3pdf_c8_kw[1]);
+ dk3of_write_c8_string(of, dk3pdf_c8_kw[4]);
+ dk3of_write_c8_string(of, dk3pdf_c8_kw[0]); $? "- dk3pdf_cm_long"
+}
+
+
+
+/** Write double value, correct comma to dot.
+ @param of Output filter stream.
+ @param x Value to write.
+*/
+static
+void
+dk3pdf_write_double(dk3_of_t *of, double x)
+{
+#if VERSION_BEFORE_20140722
+ char buf[64]; /* Conversion buffer. */
+ char *ptr;
+ sprintf(buf, dk3pdf_c8_kw[70], x);
+ ptr = buf;
+ while(*ptr) { if(*ptr == ',') { *ptr = '.'; } ptr++; }
+ dk3of_write_c8_string(of, buf); $? "= dk3pdf_write_double %lg", x
+#else
+ if (1.0e-8 <= fabs(x)) {
+ (void)dk3of_double_to_c8_no_sci(of, x);
+ } else {
+ dk3of_write_c8_string(of, dk3pdf_c8_kw[99]);
+ }
+#endif
+}
+
+
+
+/** Change current transformation matrix.
+ @param of Output filter to write to.
+ @param cmv Matrix values.
+*/
+static
+void
+dk3pdf_cm_double(dk3_of_t *of, double *cmv)
+{
+ $? "+ dk3pdf_cm_double"
+ dk3pdf_write_double(of, cmv[0]);
+ dk3of_write_c8_string(of, dk3pdf_c8_kw[1]);
+ dk3pdf_write_double(of, cmv[1]);
+ dk3of_write_c8_string(of, dk3pdf_c8_kw[1]);
+ dk3pdf_write_double(of, cmv[2]);
+ dk3of_write_c8_string(of, dk3pdf_c8_kw[1]);
+ dk3pdf_write_double(of, cmv[3]);
+ dk3of_write_c8_string(of, dk3pdf_c8_kw[1]);
+ dk3pdf_write_double(of, cmv[4]);
+ dk3of_write_c8_string(of, dk3pdf_c8_kw[1]);
+ dk3pdf_write_double(of, cmv[5]);
+ dk3of_write_c8_string(of, dk3pdf_c8_kw[1]);
+ dk3of_write_c8_string(of, dk3pdf_c8_kw[4]); $? "- dk3pdf_cm_double"
+}
+
+
+
+int
+dk3pdf_translate_long(dk3_pdf_t *pdf, long x, long y)
+{
+ long cmv[] = { 0L, 0L, 0L, 0L, 0L, 0L }; /* Matrix values. */
+ int back = 0;
+ $? "+ dk3pdf_translate_long %ld %ld", x, y
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ cmv[0] = 1L;
+ cmv[3] = 1L;
+ cmv[4] = x;
+ cmv[5] = y;
+ dk3pdf_cm_long((pdf->cp)->tempof, cmv);
+ }
+ }
+ } $? "- dk3pdf_translate_long %d", back
+ return back;
+}
+
+
+
+int
+dk3pdf_translate_double(dk3_pdf_t *pdf, double x, double y)
+{
+ double cmv[] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; /* Matrix values. */
+ int back = 0;
+ $? "+ dk3pdf_translate_double %lg %lg", x, y
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ cmv[0] = 1.0;
+ cmv[3] = 1.0;
+ cmv[4] = x;
+ cmv[5] = y;
+ dk3pdf_cm_double((pdf->cp)->tempof, cmv);
+ }
+ }
+ } $? "- dk3pdf_translate_double %d", back
+ return back;
+}
+
+
+
+/** Convert long value to double.
+ @param l Long value to convert.
+ @return Conversion result.
+*/
+static
+double
+dk3pdf_l_to_d(long l)
+{
+ return ((double)l);
+}
+
+int
+dk3pdf_rotate_int(dk3_pdf_t *pdf, int angle)
+{
+ long cmv[] = { 0L, 0L, 0L, 0L, 0L, 0L }; /* Matrix values. */
+ int back = 0;
+ $? "+ dk3pdf_rotate_int %d", angle
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ if(angle % 90) {
+ back = dk3pdf_rotate_double(pdf, dk3pdf_l_to_d((long)angle));
+ } else {
+ if(angle % 360) {
+ switch(angle % 360) {
+ case 90: {
+ cmv[1] = 1L;
+ cmv[2] = -1L;
+ } break;
+ case 180: {
+ cmv[0] = -1L;
+ cmv[3] = -1L;
+ } break;
+ case 270: {
+ cmv[1] = -1L;
+ cmv[2] = 1L;
+ } break;
+ }
+ dk3pdf_cm_long((pdf->cp)->tempof, cmv);
+ }
+ }
+ }
+ }
+ } $? "- dk3pdf_rotate_int %d", back
+ return back;
+}
+
+
+
+int
+dk3pdf_rotate_double(dk3_pdf_t *pdf, double angle)
+{
+ double cmv[] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; /* Matrix values. */
+ int back = 0;
+ $? "+ dk3pdf_rotate_double %lg", angle
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ cmv[0] = cos(angle);
+ cmv[1] = sin(angle);
+ cmv[2] = 0.0 - cmv[1];
+ cmv[3] = cmv[0];
+ dk3pdf_cm_double((pdf->cp)->tempof, cmv);
+ }
+ }
+ } $? "- dk3pdf_rotate_double %d", back
+ return back;
+}
+
+
+
+int
+dk3pdf_scale_long(dk3_pdf_t *pdf, long x, long y)
+{
+ long cmv[] = { 0L, 0L, 0L, 0L, 0L, 0L }; /* Matrix values. */
+ int back = 0;
+ $? "+ dk3pdf_scale_long %ld %ld", x, y
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ cmv[0] = x;
+ cmv[3] = y;
+ dk3pdf_cm_long((pdf->cp)->tempof, cmv);
+ }
+ }
+ } $? "- dk3pdf_scale_long %d", back
+ return back;
+}
+
+
+
+int
+dk3pdf_scale_double(dk3_pdf_t *pdf, double x, double y)
+{
+ double cmv[] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; /* Matrix values. */
+ int back = 0;
+ $? "+ dk3pdf_scale_double %lg %lg", x, y
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ cmv[0] = x;
+ cmv[3] = y;
+ dk3pdf_cm_double((pdf->cp)->tempof, cmv);
+ }
+ }
+ } $? "- dk3pdf_scale_double %d", back
+ return back;
+}
+
+
+
+int
+dk3pdf_add_xobject_to_page(dk3_pdf_t *pdf, dk3_pdf_xobject_t *xo)
+{
+ char buf[64]; /* Conversion buffer for number. */
+ int back = 0;
+ $? "+ dk3pdf_add_xobject_to_page"
+ if((pdf) && (xo)) { $? ". pdf && xo"
+ if(pdf->cp) { $? ". cp "
+ if((pdf->cp)->tempof) { $? ". tempof"
+ sprintf(buf, "%lu", xo->objno);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[5]);
+ dk3of_write_c8_string((pdf->cp)->tempof, buf);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[6]);
+ if(!((pdf->cp)->s_xobjects)) {
+ (pdf->cp)->s_xobjects = dk3sto_open_app(pdf->app);
+ }
+ if(!((pdf->cp)->i_xobjects)) {
+ if((pdf->cp)->s_xobjects) {
+ (pdf->cp)->i_xobjects = dk3sto_it_open((pdf->cp)->s_xobjects);
+ }
+ }
+ if(((pdf->cp)->s_xobjects) && ((pdf->cp)->i_xobjects)) { $? ". sto ok"
+ if(dk3sto_add((pdf->cp)->s_xobjects, (void *)xo)) { $? ". add ok"
+ back = 1;
+ }
+ }
+ } else { $? "! tempof"
+ }
+ } else { $? "! cp"
+ }
+ } else { $? "! pdf && xo"
+ } $? "- dk3pdf_add_xobject_to_page %d", back
+ return back;
+}
+
+
+
+/** Initialize image conversion job.
+ @param job Image conversion job to initialize.
+ @param opt Conversion options.
+ @param pdf Destination pdf structure.
+ @param bif Source bitmap image.
+*/
+static
+void
+dk3pdf_image_job_init(
+ dk3_pdf_image_job_t *job,
+ dk3_bm_eps_options_t *opt,
+ dk3_pdf_t *pdf,
+ dk3_bif_t *bif
+)
+{
+ $? "+ dk3pdf_image_job_init"
+ job->pdf = pdf;
+ job->bif = bif;
+ job->of = NULL;
+ job->procedure = DK3_BMEPS_RGB_FLATE;
+ job->h_color = 0;
+ job->h_alpha = 0;
+ job->bpc = 8;
+ job->opt = opt;
+ job->use_dct = 0;
+ job->xo = NULL; $? "- dk3pdf_image_job_init"
+}
+
+
+
+/** Transfer DCT-encoded data directly from JPEG image to
+ output file.
+ @param ofile Destination file.
+ @param bif Source image.
+ @param app Application structure for diagnostics, may be NULL.
+*/
+static
+void
+dk3pdf_transfer_dct_data(FILE *ofile, dk3_bif_t *bif, dk3_app_t *app)
+{
+ char buf[4096]; /* Data buffer. */
+ FILE *ifile; /* Input file. */
+ size_t rb; /* Number of bytes read. */
+ int cc; /* Flag: Can continue. */
+ $? "+ dk3pdf_transfer_dct_data"
+ ifile = dk3bif_get_file(bif);
+ if(ifile) {
+ rewind(ifile);
+ do {
+ cc = 0;
+ rb = dk3sf_fread_app(buf, 1, sizeof(buf), ifile, app);
+ if(rb > 0) {
+ cc = 1;
+ dk3sf_fwrite_app(buf, 1, rb, ofile, app);
+ }
+ } while(cc);
+ } $? "- dk3pdf_transfer_dct_data"
+}
+
+
+
+
+/** Add color data mixed, 8 bits per component.
+ @param job Image conversion job.
+ @param pcomm Communicator object.
+ @param minpb Minimum progress bar value.
+ @param maxpb Maximum progress bar value.
+*/
+static
+void
+dk3pdf_out_col_8_mixed(
+ dk3_pdf_image_job_t *job,
+ void *pcomm,
+ int minpb,
+ int maxpb
+)
+{
+ dk3_bif_coord_t y; /* Current line. */
+ dk3_bif_coord_t x; /* Current column. */
+ dk3_bif_coord_t h; /* Image height. */
+ dk3_bif_coord_t w; /* Image width. */
+ unsigned char v[3]; /* RGB values. */
+ unsigned char ored, og, ob; /* Previous RGB values. */
+ unsigned char r, g, b; /* RGB values. */
+ $? "+ dk3pdf_out_col_8_mixed %!8s min=%d max=%d", TR_8PTR(pcomm), minpb, maxpb
+ w = dk3bif_get_width(job->bif);
+ h = dk3bif_get_height(job->bif);
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ for(y = 0L; y < h; y++) {
+ ored = og = ob = 0x00;
+ for(x = 0L; x < w; x++) {
+ r = (unsigned char)dk3bif_get_mixed_red(job->bif, x, y);
+ g = (unsigned char)dk3bif_get_mixed_green(job->bif, x, y);
+ b = (unsigned char)dk3bif_get_mixed_blue(job->bif, x, y);
+ v[0] = r - ored;
+ v[1] = g - og;
+ v[2] = b - ob;
+ dk3of_write_bytes(job->of, v, 3);
+ ored = r; og = g; ob = b;
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_SUB: {
+ for(y = 0L; y < h; y++) {
+ r = 0x01;
+ dk3of_write_bytes(job->of, &r, 1);
+ ored = og = ob = 0x00;
+ for(x = 0L; x < w; x++) {
+ r = (unsigned char)dk3bif_get_mixed_red(job->bif, x, y);
+ g = (unsigned char)dk3bif_get_mixed_green(job->bif, x, y);
+ b = (unsigned char)dk3bif_get_mixed_blue(job->bif, x, y);
+ v[0] = r - ored;
+ v[1] = g - og;
+ v[2] = b - ob;
+ dk3of_write_bytes(job->of, v, 3);
+ ored = r; og = g; ob = b;
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_UP: {
+ for(y = 0L; y < h; y++) {
+ r = 0x02;
+ dk3of_write_bytes(job->of, &r, 1);
+ for(x = 0L; x < w; x++) {
+ ored = (unsigned char)dk3bif_get_mixed_red(job->bif, x, (y - 1L));
+ og = (unsigned char)dk3bif_get_mixed_green(job->bif, x, (y - 1L));
+ ob = (unsigned char)dk3bif_get_mixed_blue(job->bif, x, (y - 1L));
+ r = (unsigned char)dk3bif_get_mixed_red(job->bif, x, y);
+ g = (unsigned char)dk3bif_get_mixed_green(job->bif, x, y);
+ b = (unsigned char)dk3bif_get_mixed_blue(job->bif, x, y);
+ v[0] = r - ored;
+ v[1] = g - og;
+ v[2] = b - ob;
+ dk3of_write_bytes(job->of, v, 3);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_AVERAGE: {
+ for(y = 0L; y < h; y++) {
+ r = 0x03;
+ dk3of_write_bytes(job->of, &r, 1);
+ for(x = 0L; x < w; x++) {
+ r = (unsigned char)dk3bif_get_mixed_red(job->bif, x, y);
+ g = (unsigned char)dk3bif_get_mixed_green(job->bif, x, y);
+ b = (unsigned char)dk3bif_get_mixed_blue(job->bif, x, y);
+ ored = (unsigned char)dk3bif_get_mixed_red(job->bif, (x - 1L), y);
+ og = (unsigned char)dk3bif_get_mixed_red(job->bif, x, (y - 1L));
+ ored = (unsigned char)dk3bif_average(ored, og);
+ v[0] = r - ored;
+ ored = (unsigned char)dk3bif_get_mixed_green(job->bif, (x - 1L), y);
+ og = (unsigned char)dk3bif_get_mixed_green(job->bif, x, (y - 1L));
+ ored = (unsigned char)dk3bif_average(ored, og);
+ v[1] = g - ored;
+ ored = (unsigned char)dk3bif_get_mixed_blue(job->bif, (x - 1L), y);
+ og = (unsigned char)dk3bif_get_mixed_blue(job->bif, x, (y - 1L));
+ ored = (unsigned char)dk3bif_average(ored, og);
+ v[2] = b - ored;
+ dk3of_write_bytes(job->of, v, 3);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_PAETH: {
+ for(y = 0L; y < h; y++) {
+ r = 0x04;
+ dk3of_write_bytes(job->of, &r, 1);
+ for(x = 0L; x < w; x++) {
+ r = (unsigned char)dk3bif_get_mixed_red(job->bif, x, y);
+ g = (unsigned char)dk3bif_get_mixed_green(job->bif, x, y);
+ b = (unsigned char)dk3bif_get_mixed_blue(job->bif, x, y);
+ ored = (unsigned char)dk3bif_paeth(
+ dk3bif_get_mixed_red(job->bif, (x - 1L), y),
+ dk3bif_get_mixed_red(job->bif, x, (y - 1L)),
+ dk3bif_get_mixed_red(job->bif, (x - 1L), (y - 1L))
+ );
+ og = (unsigned char)dk3bif_paeth(
+ dk3bif_get_mixed_green(job->bif, (x - 1L), y),
+ dk3bif_get_mixed_green(job->bif, x, (y - 1L)),
+ dk3bif_get_mixed_green(job->bif, (x - 1L), (y - 1L))
+ );
+ ob = (unsigned char)dk3bif_paeth(
+ dk3bif_get_mixed_blue(job->bif, (x - 1L), y),
+ dk3bif_get_mixed_blue(job->bif, x, (y - 1L)),
+ dk3bif_get_mixed_blue(job->bif, (x - 1L), (y - 1L))
+ );
+ v[0] = r - ored;
+ v[1] = g - og;
+ v[2] = b - ob;
+ dk3of_write_bytes(job->of, v, 3);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ default: {
+ for(y = 0L; y < h; y++) {
+ for(x = 0L; x < w; x++) {
+ v[0] = (unsigned char)dk3bif_get_mixed_red(job->bif, x, y);
+ v[1] = (unsigned char)dk3bif_get_mixed_green(job->bif, x, y);
+ v[2] = (unsigned char)dk3bif_get_mixed_blue(job->bif, x, y);
+ dk3of_write_bytes(job->of, v, 3);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ } $? "- dk3pdf_out_col_8_mixed"
+}
+
+
+
+/** Add color data directly, 8 bits per component.
+ @param job Image conversion job.
+ @param pcomm Communicator object.
+ @param minpb Minimum progress bar value.
+ @param maxpb Maximum progress bar value.
+*/
+static
+void
+dk3pdf_out_col_8_not_mixed(
+ dk3_pdf_image_job_t *job,
+ void *pcomm,
+ int minpb,
+ int maxpb
+)
+{
+ dk3_bif_coord_t y; /* Current line. */
+ dk3_bif_coord_t x; /* Current column. */
+ dk3_bif_coord_t h; /* Image height. */
+ dk3_bif_coord_t w; /* Image width. */
+ unsigned char v[3]; /* RGB values. */
+ unsigned char ored, og, ob; /* Previous RGB values. */
+ unsigned char r, g, b; /* RGB values. */
+ $? "+ dk3pdf_out_col_8_not_mixed"
+ w = dk3bif_get_width(job->bif);
+ h = dk3bif_get_height(job->bif);
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ for(y = 0L; y < h; y++) {
+ ored = og = ob = 0x00;
+ for(x = 0L; x < w; x++) {
+ r = (unsigned char)dk3bif_get_red(job->bif, x, y);
+ g = (unsigned char)dk3bif_get_green(job->bif, x, y);
+ b = (unsigned char)dk3bif_get_blue(job->bif, x, y);
+ v[0] = r - ored;
+ v[1] = g - og;
+ v[2] = b - ob;
+ dk3of_write_bytes(job->of, v, 3);
+ ored = r; og = g; ob = b;
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_SUB: {
+ for(y = 0L; y < h; y++) {
+ r = 0x01;
+ dk3of_write_bytes(job->of, &r, 1);
+ ored = og = ob = 0x00;
+ for(x = 0L; x < w; x++) {
+ r = (unsigned char)dk3bif_get_red(job->bif, x, y);
+ g = (unsigned char)dk3bif_get_green(job->bif, x, y);
+ b = (unsigned char)dk3bif_get_blue(job->bif, x, y);
+ v[0] = r - ored;
+ v[1] = g - og;
+ v[2] = b - ob;
+ dk3of_write_bytes(job->of, v, 3);
+ ored = r; og = g; ob = b;
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_UP: {
+ for(y = 0L; y < h; y++) {
+ r = 0x02;
+ dk3of_write_bytes(job->of, &r, 1);
+ for(x = 0L; x < w; x++) {
+ ored = (unsigned char)dk3bif_get_red(job->bif, x, (y - 1L));
+ og = (unsigned char)dk3bif_get_green(job->bif, x, (y - 1L));
+ ob = (unsigned char)dk3bif_get_blue(job->bif, x, (y - 1L));
+ r = (unsigned char)dk3bif_get_red(job->bif, x, y);
+ g = (unsigned char)dk3bif_get_green(job->bif, x, y);
+ b = (unsigned char)dk3bif_get_blue(job->bif, x, y);
+ v[0] = r - ored;
+ v[1] = g - og;
+ v[2] = b - ob;
+ dk3of_write_bytes(job->of, v, 3);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_AVERAGE: {
+ for(y = 0L; y < h; y++) {
+ r = 0x03;
+ dk3of_write_bytes(job->of, &r, 1);
+ for(x = 0L; x < w; x++) {
+ r = (unsigned char)dk3bif_get_red(job->bif, x, y);
+ g = (unsigned char)dk3bif_get_green(job->bif, x, y);
+ b = (unsigned char)dk3bif_get_blue(job->bif, x, y);
+ ored = (unsigned char)dk3bif_get_red(job->bif, (x - 1L), y);
+ og = (unsigned char)dk3bif_get_red(job->bif, x, (y - 1L));
+ ored = (unsigned char)dk3bif_average(ored, og);
+ v[0] = r - ored;
+ ored = (unsigned char)dk3bif_get_green(job->bif, (x - 1L), y);
+ og = (unsigned char)dk3bif_get_green(job->bif, x, (y - 1L));
+ ored = (unsigned char)dk3bif_average(ored, og);
+ v[1] = g - ored;
+ ored = (unsigned char)dk3bif_get_blue(job->bif, (x - 1L), y);
+ og = (unsigned char)dk3bif_get_blue(job->bif, x, (y - 1L));
+ ored = (unsigned char)dk3bif_average(ored, og);
+ v[2] = b - ored;
+ dk3of_write_bytes(job->of, v, 3);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_PAETH: {
+ for(y = 0L; y < h; y++) {
+ r = 0x04;
+ dk3of_write_bytes(job->of, &r, 1);
+ for(x = 0L; x < w; x++) {
+ r = (unsigned char)dk3bif_get_red(job->bif, x, y);
+ g = (unsigned char)dk3bif_get_green(job->bif, x, y);
+ b = (unsigned char)dk3bif_get_blue(job->bif, x, y);
+ ored = (unsigned char)dk3bif_paeth(
+ dk3bif_get_red(job->bif, (x - 1L), y),
+ dk3bif_get_red(job->bif, x, (y - 1L)),
+ dk3bif_get_red(job->bif, (x - 1L), (y - 1L))
+ );
+ og = (unsigned char)dk3bif_paeth(
+ dk3bif_get_green(job->bif, (x - 1L), y),
+ dk3bif_get_green(job->bif, x, (y - 1L)),
+ dk3bif_get_green(job->bif, (x - 1L), (y - 1L))
+ );
+ ob = (unsigned char)dk3bif_paeth(
+ dk3bif_get_blue(job->bif, (x - 1L), y),
+ dk3bif_get_blue(job->bif, x, (y - 1L)),
+ dk3bif_get_blue(job->bif, (x - 1L), (y - 1L))
+ );
+ v[0] = r - ored;
+ v[1] = g - og;
+ v[2] = b - ob;
+ dk3of_write_bytes(job->of, v, 3);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ default: {
+ for(y = 0L; y < h; y++) {
+ for(x = 0L; x < w; x++) {
+ v[0] = (unsigned char)dk3bif_get_red(job->bif, x, y);
+ v[1] = (unsigned char)dk3bif_get_green(job->bif, x, y);
+ v[2] = (unsigned char)dk3bif_get_blue(job->bif, x, y);
+ dk3of_write_bytes(job->of, v, 3);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ } $? "- dk3pdf_out_col_8_not_mixed"
+}
+
+
+
+/** Add gray data mixed, 8 bits per component.
+ @param job Image conversion job.
+ @param pcomm Communicator object.
+ @param minpb Minimum progress bar value.
+ @param maxpb Maximum progress bar value.
+*/
+static
+void
+dk3pdf_out_gray_8_mixed(
+ dk3_pdf_image_job_t *job,
+ void *pcomm,
+ int minpb,
+ int maxpb
+)
+{
+ dk3_bif_coord_t y; /* Current line. */
+ dk3_bif_coord_t x; /* Current column. */
+ dk3_bif_coord_t h; /* Image height. */
+ dk3_bif_coord_t w; /* Image width. */
+ unsigned char v, p, q; /* Value and predictor(s). */
+ $? "+ dk3pdf_out_gray_8_mixed"
+ w = dk3bif_get_width(job->bif);
+ h = dk3bif_get_height(job->bif);
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ for(y = 0L; y < h; y++) {
+ p = 0x00;
+ for(x = 0L; x < w; x++) {
+ v = (unsigned char)dk3bif_get_mixed_gray(job->bif, x, y);
+ q = v - p;
+ dk3of_write_bytes(job->of, &q, 1);
+ p = v;
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_SUB: {
+ for(y = 0L; y < h; y++) {
+ q = 0x01;
+ dk3of_write_bytes(job->of, &q, 1);
+ p = 0x00;
+ for(x = 0L; x < w; x++) {
+ v = (unsigned char)dk3bif_get_mixed_gray(job->bif, x, y);
+ q = v - p;
+ dk3of_write_bytes(job->of, &q, 1);
+ p = v;
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_UP: {
+ for(y = 0L; y < h; y++) {
+ q = 0x02;
+ dk3of_write_bytes(job->of, &q, 1);
+ for(x = 0L; x < w; x++) {
+ p = (unsigned char)dk3bif_get_mixed_gray(job->bif, x, (y - 1L));
+ v = (unsigned char)dk3bif_get_mixed_gray(job->bif, x, y);
+ q = v - p;
+ dk3of_write_bytes(job->of, &q, 1);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_AVERAGE: {
+ for(y = 0L; y < h; y++) {
+ q = 0x03;
+ dk3of_write_bytes(job->of, &q, 1);
+ for(x = 0L; x < w; x++) {
+ p = (unsigned char)dk3bif_average(
+ dk3bif_get_mixed_gray(job->bif, x, (y - 1L)),
+ dk3bif_get_mixed_gray(job->bif, (x - 1L), y)
+ );
+ v = (unsigned char)dk3bif_get_mixed_gray(job->bif, x, y);
+ q = v - p;
+ dk3of_write_bytes(job->of, &q, 1);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_PAETH: {
+ for(y = 0L; y < h; y++) {
+ q = 0x04;
+ dk3of_write_bytes(job->of, &q, 1);
+ for(x = 0L; x < w; x++) {
+ v = (unsigned char)dk3bif_get_mixed_gray(job->bif, x, y);
+ p = (unsigned char)dk3bif_paeth(
+ dk3bif_get_mixed_gray(job->bif, (x - 1L), y),
+ dk3bif_get_mixed_gray(job->bif, x, (y - 1L)),
+ dk3bif_get_mixed_gray(job->bif, (x - 1L), (y - 1L))
+ );
+ q = v - p;
+ dk3of_write_bytes(job->of, &q, 1);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ default: {
+ for(y = 0L; y < h; y++) {
+ for(x = 0L; x < w; x++) {
+ v = (unsigned char)dk3bif_get_mixed_gray(job->bif, x, y);
+ dk3of_write_bytes(job->of, &v, 1);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ } $? "- dk3pdf_out_gray_8_mixed"
+}
+
+
+
+/** Add gray data directly, 8 bits per component.
+ @param job Image conversion job.
+ @param pcomm Communicator object.
+ @param minpb Minimum progress bar value.
+ @param maxpb Maximum progress bar value.
+*/
+static
+void
+dk3pdf_out_gray_8_not_mixed(
+ dk3_pdf_image_job_t *job,
+ void *pcomm,
+ int minpb,
+ int maxpb
+)
+{
+ dk3_bif_coord_t y; /* Current line. */
+ dk3_bif_coord_t x; /* Current column. */
+ dk3_bif_coord_t h; /* Image height. */
+ dk3_bif_coord_t w; /* Image width. */
+ unsigned char v, p, q; /* Value and predictors. */
+ $? "+ dk3pdf_out_gray_8_not_mixed"
+ w = dk3bif_get_width(job->bif);
+ h = dk3bif_get_height(job->bif);
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: { $? ". tiff predictor"
+ for(y = 0L; y < h; y++) {
+ p = 0x00;
+ for(x = 0L; x < w; x++) {
+ v = (unsigned char)dk3bif_get_gray(job->bif, x, y);
+ q = v - p; $? ". x=%ld y=%ld v=%x p=%x q=%x", x, y, (int)v, (int)p, (int)q
+ dk3of_write_bytes(job->of, &q, 1);
+ p = v;
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_SUB: {
+ for(y = 0L; y < h; y++) {
+ q = 0x01;
+ dk3of_write_bytes(job->of, &q, 1);
+ p = 0x00;
+ for(x = 0L; x < w; x++) {
+ v = (unsigned char)dk3bif_get_gray(job->bif, x, y);
+ q = v - p;
+ dk3of_write_bytes(job->of, &q, 1);
+ p = v;
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_UP: {
+ for(y = 0L; y < h; y++) {
+ q = 0x02;
+ dk3of_write_bytes(job->of, &q, 1);
+ for(x = 0L; x < w; x++) {
+ p = (unsigned char)dk3bif_get_gray(job->bif, x, (y - 1L));
+ v = (unsigned char)dk3bif_get_gray(job->bif, x, y);
+ q = v - p;
+ dk3of_write_bytes(job->of, &q, 1);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_AVERAGE: {
+ dk3_bif_pixel_t lv;
+ dk3_bif_pixel_t uv;
+ for(y = 0L; y < h; y++) {
+ q = 0x03;
+ dk3of_write_bytes(job->of, &q, 1);
+ for(x = 0L; x < w; x++) {
+ uv = dk3bif_get_gray(job->bif, x, (y - 1L));
+ lv = dk3bif_get_gray(job->bif, (x - 1L), y);
+ lv = dk3bif_average(uv, lv);
+ p = (unsigned char)lv;
+ v = (unsigned char)dk3bif_get_gray(job->bif, x, y);
+ q = v - p;
+ dk3of_write_bytes(job->of, &q, 1);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_PAETH: {
+ for(y = 0L; y < h; y++) {
+ q = 0x04;
+ dk3of_write_bytes(job->of, &q, 1);
+ for(x = 0L; x < w; x++) {
+ v = (unsigned char)dk3bif_get_gray(job->bif, x, y);
+ p = (unsigned char)dk3bif_paeth(
+ dk3bif_get_gray(job->bif, (x - 1L), y),
+ dk3bif_get_gray(job->bif, x, (y - 1L)),
+ dk3bif_get_gray(job->bif, (x - 1L), (y - 1L))
+ );
+ q = v - p;
+ dk3of_write_bytes(job->of, &q, 1);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ default: { $? ". no predictor"
+ for(y = 0L; y < h; y++) {
+ for(x = 0L; x < w; x++) {
+ v = (unsigned char)dk3bif_get_gray(job->bif, x, y);
+ dk3of_write_bytes(job->of, &v, 1);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ } $? "- dk3pdf_out_gray_8_not_mixed"
+}
+
+
+
+/** Add color data mixed, bits per component not 8.
+ @param job Image conversion job.
+ @param pcomm Communicator object.
+ @param minpb Minimum progress bar value.
+ @param maxpb Maximum progress bar value.
+*/
+static
+void
+dk3pdf_out_col_not8_mixed(
+ dk3_pdf_image_job_t *job,
+ void *pcomm,
+ int minpb,
+ int maxpb
+)
+{
+ dk3_bif_coord_t y; /* Current line. */
+ dk3_bif_coord_t x; /* Current column. */
+ dk3_bif_coord_t h; /* Image height. */
+ dk3_bif_coord_t w; /* Image width. */
+ dk3_bif_pixel_t r; /* Red. */
+ dk3_bif_pixel_t g; /* Green. */
+ dk3_bif_pixel_t b; /* Blue. */
+ dk3_bif_pixel_t ored; /* Previous red. */
+ dk3_bif_pixel_t og; /* Previous green. */
+ dk3_bif_pixel_t ob; /* Previous blue. */
+ $? "+ dk3pdf_out_col_not8_mixed"
+ w = dk3bif_get_width(job->bif);
+ h = dk3bif_get_height(job->bif);
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ for(y = 0L; y < h; y++) {
+ ored = 0U; og = 0U; ob = 0U;
+ for(x = 0L; x < w; x++) {
+ r = dk3bif_get_mixed_red(job->bif, x, y);
+ g = dk3bif_get_mixed_green(job->bif, x, y);
+ b = dk3bif_get_mixed_blue(job->bif, x, y);
+ dk3of_write_bits(job->of, (r - ored), job->bpc);
+ dk3of_write_bits(job->of, (g - og), job->bpc);
+ dk3of_write_bits(job->of, (b - ob), job->bpc);
+ ored = r;
+ og = g;
+ ob = b;
+ }
+ dk3of_flush_bits(job->of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ default: {
+ for(y = 0L; y < h; y++) {
+ for(x = 0L; x < w; x++) {
+ r = dk3bif_get_mixed_red(job->bif, x, y);
+ g = dk3bif_get_mixed_green(job->bif, x, y);
+ b = dk3bif_get_mixed_blue(job->bif, x, y);
+ dk3of_write_bits(job->of, r, job->bpc);
+ dk3of_write_bits(job->of, g, job->bpc);
+ dk3of_write_bits(job->of, b, job->bpc);
+ }
+ dk3of_flush_bits(job->of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ } $? "- dk3pdf_out_col_not8_mixed"
+}
+
+
+
+/** Add color data directly, bits per component not 8.
+ @param job Image conversion job.
+ @param pcomm Communicator object.
+ @param minpb Minimum progress bar value.
+ @param maxpb Maximum progress bar value.
+*/
+static
+void
+dk3pdf_out_col_not8_not_mixed(
+ dk3_pdf_image_job_t *job,
+ void *pcomm,
+ int minpb,
+ int maxpb
+)
+{
+ dk3_bif_coord_t y; /* Current line. */
+ dk3_bif_coord_t x; /* Current column. */
+ dk3_bif_coord_t h; /* Image height. */
+ dk3_bif_coord_t w; /* Image width. */
+ dk3_bif_pixel_t r; /* Red. */
+ dk3_bif_pixel_t g; /* Green. */
+ dk3_bif_pixel_t b; /* Blue. */
+ dk3_bif_pixel_t ored; /* Previous red. */
+ dk3_bif_pixel_t og; /* Previous green. */
+ dk3_bif_pixel_t ob; /* Previous blue. */
+ $? "+ dk3pdf_out_col_not8_not_mixed"
+ w = dk3bif_get_width(job->bif);
+ h = dk3bif_get_height(job->bif);
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ for(y = 0L; y < h; y++) {
+ ored = 0U; og = 0U; ob = 0U;
+ for(x = 0L; x < w; x++) {
+ r = dk3bif_get_red(job->bif, x, y);
+ g = dk3bif_get_green(job->bif, x, y);
+ b = dk3bif_get_blue(job->bif, x, y);
+ dk3of_write_bits(job->of, (r - ored), job->bpc);
+ dk3of_write_bits(job->of, (g - og), job->bpc);
+ dk3of_write_bits(job->of, (b - ob), job->bpc);
+ ored = r;
+ og = g;
+ ob = b;
+ }
+ dk3of_flush_bits(job->of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ default: {
+ for(y = 0L; y < h; y++) {
+ for(x = 0L; x < w; x++) {
+ r = dk3bif_get_red(job->bif, x, y);
+ g = dk3bif_get_green(job->bif, x, y);
+ b = dk3bif_get_blue(job->bif, x, y);
+ dk3of_write_bits(job->of, r, job->bpc);
+ dk3of_write_bits(job->of, g, job->bpc);
+ dk3of_write_bits(job->of, b, job->bpc);
+ }
+ dk3of_flush_bits(job->of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ } $? "- dk3pdf_out_col_not8_not_mixed"
+}
+
+
+
+/** Add gray data mixed, bits per component not 8.
+ @param job Image conversion job.
+ @param pcomm Communicator object.
+ @param minpb Minimum progress bar value.
+ @param maxpb Maximum progress bar value.
+*/
+static
+void
+dk3pdf_out_gray_not8_mixed(
+ dk3_pdf_image_job_t *job,
+ void *pcomm,
+ int minpb,
+ int maxpb
+)
+{
+ dk3_bif_coord_t y; /* Current line. */
+ dk3_bif_coord_t x; /* Current column. */
+ dk3_bif_coord_t h; /* Image height. */
+ dk3_bif_coord_t w; /* Image width. */
+ dk3_bif_pixel_t g; /* Current gray. */
+ dk3_bif_pixel_t og; /* Previous gray. */
+ $? "+ dk3pdf_out_gray_not8_mixed"
+ w = dk3bif_get_width(job->bif);
+ h = dk3bif_get_height(job->bif);
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ for(y = 0L; y < h; y++) {
+ og = 0U;
+ for(x = 0L; x < w; x++) {
+ g = dk3bif_get_mixed_gray(job->bif, x, y);
+ dk3of_write_bits(job->of, (g - og), job->bpc);
+ og = g;
+ }
+ dk3of_flush_bits(job->of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ default: {
+ for(y = 0L; y < h; y++) {
+ for(x = 0L; x < w; x++) {
+ g = dk3bif_get_mixed_gray(job->bif, x, y);
+ dk3of_write_bits(job->of, g, job->bpc);
+ }
+ dk3of_flush_bits(job->of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ } $? "- dk3pdf_out_gray_not8_mixed"
+}
+
+
+
+/** Add gray data directly, bits per component not 8.
+ @param job Image conversion job.
+ @param pcomm Communicator object.
+ @param minpb Minimum progress bar value.
+ @param maxpb Maximum progress bar value.
+*/
+static
+void
+dk3pdf_out_gray_not8_not_mixed(
+ dk3_pdf_image_job_t *job,
+ void *pcomm,
+ int minpb,
+ int maxpb
+)
+{
+ dk3_bif_coord_t y; /* Current line. */
+ dk3_bif_coord_t x; /* Current column. */
+ dk3_bif_coord_t h; /* Image height. */
+ dk3_bif_coord_t w; /* Image width. */
+ dk3_bif_pixel_t g; /* Current point gray. */
+ dk3_bif_pixel_t og; /* Previous gray. */
+ $? "+ dk3pdf_out_gray_not8_not_mixed"
+ w = dk3bif_get_width(job->bif);
+ h = dk3bif_get_height(job->bif);
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ for(y = 0L; y < h; y++) {
+ og = 0U;
+ for(x = 0L; x < w; x++) {
+ g = dk3bif_get_gray(job->bif, x, y);
+ dk3of_write_bits(job->of, (g - og), job->bpc);
+ og = g;
+ }
+ dk3of_flush_bits(job->of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ default: {
+ for(y = 0L; y < h; y++) {
+ for(x = 0L; x < w; x++) {
+ g = dk3bif_get_gray(job->bif, x, y);
+ dk3of_write_bits(job->of, g, job->bpc);
+ }
+ dk3of_flush_bits(job->of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y);
+#endif
+ }
+ } break;
+ } $? "- dk3pdf_out_gray_not8_not_mixed"
+}
+
+
+
+/** Add another Xobject containing the alpha channel from the
+ current XObject.
+ @param job Image conversion job.
+ @param pcomm Communicator object.
+ @param min Minimum progress bar value.
+ @param max Maximum progress bar value.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3pdf_add_alpha_xobject(
+ dk3_pdf_image_job_t *job,
+ void *pcomm,
+ int min,
+ int max
+)
+{
+ dk3_stat_t stb; /* Stat buffer. */
+ dk3_pdf_xobject_t *mo; /* Mask object. */
+ FILE *fipo; /* Output file. */
+ dk3_stream_t *os; /* Output stream. */
+ dk3_of_t *of; /* Output filter. */
+ dk3_bif_coord_t w; /* Image width. */
+ dk3_bif_coord_t h; /* Image height. */
+ dk3_bif_coord_t x; /* Current column. */
+ dk3_bif_coord_t y; /* Current row. */
+ dk3_bif_pixel_t v; /* Pixel value. */
+ dk3_bif_pixel_t p; /* Previous value. */
+ int back = 0;
+ unsigned char vc; /* Value as byte. */
+ unsigned char pc; /* Predictor as byte. */
+ unsigned char wc; /* Predictor as byte. */
+ $? "+ dk3pdf_add_alpha_xobject"
+ mo = dk3pdf_xobject_new(job->pdf);
+ if(mo) {
+ mo->objno = (job->pdf)->nextobject;
+ if(dk3sto_add((job->pdf)->s_xobjects, (void *)mo)) {
+ (job->pdf)->nextobject += 1UL;
+ w = mo->width = dk3bif_get_width(job->bif);
+ h = mo->height = dk3bif_get_height(job->bif);
+ mo->xot = DK3_PDF_XO_TYPE_ALPHA;
+ mo->procedure = DK3_BMEPS_GRAY_FLATE;
+ mo->bpc = job->bpc;
+ mo->pred = (job->opt)->pred;
+ fipo = dk3sf_fopen_app(
+ mo->tempfilename,
+ dk3app_not_localized(53),
+ (job->pdf)->app
+ );
+ if(fipo) {
+ (job->xo)->mask = mo;
+ os = dk3stream_open_file_app(
+ fipo,
+ DK3_STREAM_FLAG_WRITE,
+ (job->pdf)->app
+ );
+ if(os) {
+ of = dk3of_open_app(os, (job->pdf)->app);
+ if(of) {
+ if(dk3of_add_cell(of, DK3_OF_CELL_TYPE_FLATE)) {
+ if(dk3of_start_chunk(of)) {
+ if(job->bpc == 8) {
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ for(y = 0; y < h; y++) {
+ pc = 0x00;
+ for(x = 0; x < w; x++) {
+ vc = (unsigned char)dk3bif_get_alpha(job->bif, x, y);
+ wc = vc - pc;
+ dk3of_write_bytes(of, &wc, 1);
+ pc = vc;
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,min,max,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_SUB: {
+ for(y = 0; y < h; y++) {
+ pc = 0x00;
+ wc = 0x01;
+ dk3of_write_bytes(of, &wc, 1);
+ for(x = 0; x < w; x++) {
+ vc = (unsigned char)dk3bif_get_alpha(job->bif, x, y);
+ wc = vc - pc;
+ dk3of_write_bytes(of, &wc, 1);
+ pc = vc;
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,min,max,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_UP: {
+ for(y = 0; y < h; y++) {
+ wc = 0x02;
+ dk3of_write_bytes(of, &wc, 1);
+ for(x = 0; x < w; x++) {
+ vc = (unsigned char)dk3bif_get_alpha(job->bif, x, y);
+ pc = (unsigned char)dk3bif_get_alpha(
+ job->bif, x, (y - 1L)
+ );
+ wc = vc - pc;
+ dk3of_write_bytes(of, &wc, 1);
+#if VERSION_BEFORE_20150821
+ pc = vc;
+#endif
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,min,max,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_AVERAGE: {
+ for(y = 0; y < h; y++) {
+ wc = 0x03;
+ dk3of_write_bytes(of, &wc, 1);
+ for(x = 0; x < w; x++) {
+ vc = (unsigned char)dk3bif_get_alpha(job->bif, x, y);
+ pc = (unsigned char)dk3bif_get_alpha(
+ job->bif, x, (y - 1L)
+ );
+ wc = (unsigned char)dk3bif_get_alpha(
+ job->bif, (x - 1L), y
+ );
+ pc = (unsigned char)dk3bif_average(pc, wc);
+ wc = vc - pc;
+ dk3of_write_bytes(of, &wc, 1);
+#if VERSION_BEFORE_20150821
+ pc = vc;
+#endif
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,min,max,h,y);
+#endif
+ }
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_PAETH: {
+ for(y = 0; y < h; y++) {
+ wc = 0x04;
+ dk3of_write_bytes(of, &wc, 1);
+ for(x = 0; x < w; x++) {
+ vc = (unsigned char)dk3bif_get_alpha(job->bif, x, y);
+ pc = (unsigned char)dk3bif_paeth(
+ (unsigned char)dk3bif_get_alpha(
+ job->bif, (x - 1L), y
+ ),
+ (unsigned char)dk3bif_get_alpha(
+ job->bif, x, (y - 1L)
+ ),
+ (unsigned char)dk3bif_get_alpha(
+ job->bif, (x - 1L), (y - 1L)
+ )
+ );
+ wc = vc - pc;
+ dk3of_write_bytes(of, &wc, 1);
+#if VERSION_BEFORE_20150821
+ pc = vc;
+#endif
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,min,max,h,y);
+#endif
+ }
+ } break;
+ default: {
+ for(y = 0; y < h; y++) {
+ for(x = 0; x < w; x++) {
+ vc = (unsigned char)dk3bif_get_alpha(job->bif, x, y);
+ dk3of_write_bytes(of, &vc, 1);
+ }
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,min,max,h,y);
+#endif
+ }
+ } break;
+ }
+ } else {
+ switch((job->opt)->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ for(y = 0; y < h; y++) {
+ p = 0U;
+ for(x = 0; x < w; x++) {
+ v = dk3bif_get_alpha(job->bif, x, y);
+ dk3of_write_bits(of, (v - p), job->bpc);
+ p = v;
+ }
+ dk3of_flush_bits(of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,min,max,h,y);
+#endif
+ }
+ } break;
+ default: {
+ for(y = 0; y < h; y++) {
+ for(x = 0; x < w; x++) {
+ v = dk3bif_get_alpha(job->bif, x, y);
+ dk3of_write_bits(of, v, job->bpc);
+ }
+ dk3of_flush_bits(of);
+#if DK3_USE_WX
+ dk3bmj_lines_progress(pcomm,min,max,h,y);
+#endif
+ }
+ } break;
+ }
+ }
+ back = dk3of_end_chunk(of);
+ }
+ }
+ dk3of_close(of);
+ }
+ dk3stream_close(os);
+ }
+ if(!dk3sf_fclose_fn_app(fipo, mo->tempfilename, (job->pdf)->app)) {
+ back = 0;
+ }
+ if(dk3sf_stat_app(&stb, mo->tempfilename, (job->pdf)->app)) {
+ mo->slgt = stb.sz;
+ } else {
+ back = 0;
+ /* ERROR: Stat failed! */
+ }
+ }
+ } else {
+ dk3pdf_xobject_delete(mo);
+ }
+ } $? "- dk3pdf_add_alpha_xobject %d", back
+ return back;
+}
+
+
+
+/** Create data stream for XObject in temporary file.
+ @param job Image conversion job.
+ @param pc Communication object.
+ @param min Minimum progress bar value.
+ @param max Maximum progress bar value.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3pdf_xobject_data(
+ dk3_pdf_image_job_t *job,
+ void *pc,
+ int min,
+ int max
+)
+{
+ dk3_stat_t stb; /* Stat buffer for content stream file. */
+ FILE *fipo; /* Input file. */
+ dk3_stream_t *os; /* Output stream. */
+ int back = 0;
+ int xmax; /* Centered progress bar value. */
+ $? "+ dk3pdf_xobject_data %!8s min=%d max=%d", TR_8PTR(pc), min, max
+ xmax = max;
+ if(!(job->use_dct)) {
+ switch(job->procedure) {
+ case DK3_BMEPS_GRAY_ALPHA_FLATE: case DK3_BMEPS_RGB_ALPHA_FLATE: {
+ xmax = (min + max) / 2;
+ } break;
+ }
+ } $? ". min=%d xmax=%d max=%d", min, xmax, max
+ (job->xo)->width = dk3bif_get_width(job->bif);
+ (job->xo)->height = dk3bif_get_height(job->bif);
+ (job->xo)->xot = DK3_PDF_XO_TYPE_IMAGE;
+ (job->xo)->procedure = job->procedure;
+ (job->xo)->bpc = job->bpc;
+ if(job->use_dct) { (job->xo)->dct = 1; }
+ if(!(job->use_dct)) { (job->xo)->pred = (job->opt)->pred; }
+ fipo = dk3sf_fopen_app(
+ (job->xo)->tempfilename,
+ dk3app_not_localized(53),
+ (job->pdf)->app
+ );
+ if(fipo) { $? ". fipo"
+ if(job->use_dct) { $? ". use_dct"
+ back = 1;
+ dk3pdf_transfer_dct_data(fipo, job->bif, (job->pdf)->app);
+ } else {
+ dk3bif_set_bits_per_pixel(job->bif, job->bpc);
+ os = dk3stream_open_file_app(fipo,DK3_STREAM_FLAG_WRITE,(job->pdf)->app);
+ if(os) {
+ job->of = dk3of_open_app(os, (job->pdf)->app);
+ if(job->of) {
+ if(dk3of_add_cell(job->of, DK3_OF_CELL_TYPE_FLATE)) {
+ if(dk3of_start_chunk(job->of)) {
+ if(job->bpc == 8) {
+ if(job->h_alpha) {
+ switch(job->procedure) {
+ case DK3_BMEPS_RGB_FLATE: {
+ dk3pdf_out_col_8_mixed(job, pc, min, xmax);
+ } break;
+ case DK3_BMEPS_RGB_ALPHA_FLATE: {
+ dk3pdf_out_col_8_not_mixed(job, pc, min, xmax);
+ } break;
+ case DK3_BMEPS_GRAY_FLATE: {
+ dk3pdf_out_gray_8_mixed(job, pc, min, xmax);
+ } break;
+ case DK3_BMEPS_GRAY_ALPHA_FLATE: {
+ dk3pdf_out_gray_8_not_mixed(job, pc, min, xmax);
+ } break;
+ }
+ } else {
+ switch(job->procedure) {
+ case DK3_BMEPS_RGB_FLATE: {
+ dk3pdf_out_col_8_not_mixed(job, pc, min, xmax);
+ } break;
+ case DK3_BMEPS_RGB_ALPHA_FLATE: {
+ dk3pdf_out_col_8_not_mixed(job, pc, min, xmax);
+ } break;
+ case DK3_BMEPS_GRAY_FLATE: {
+ dk3pdf_out_gray_8_not_mixed(job, pc, min, xmax);
+ } break;
+ case DK3_BMEPS_GRAY_ALPHA_FLATE: {
+ dk3pdf_out_gray_8_not_mixed(job, pc, min, xmax);
+ } break;
+ }
+ }
+ } else {
+ if(job->h_alpha) {
+ switch(job->procedure) {
+ case DK3_BMEPS_RGB_FLATE: {
+ dk3pdf_out_col_not8_mixed(job, pc, min, xmax);
+ } break;
+ case DK3_BMEPS_RGB_ALPHA_FLATE: {
+ dk3pdf_out_col_not8_not_mixed(job, pc, min, xmax);
+ } break;
+ case DK3_BMEPS_GRAY_FLATE: {
+ dk3pdf_out_gray_not8_mixed(job, pc, min, xmax);
+ } break;
+ case DK3_BMEPS_GRAY_ALPHA_FLATE: {
+ dk3pdf_out_gray_not8_not_mixed(job, pc, min, xmax);
+ } break;
+ }
+ } else {
+ switch(job->procedure) {
+ case DK3_BMEPS_RGB_FLATE: {
+ dk3pdf_out_col_not8_not_mixed(job, pc, min, xmax);
+ } break;
+ case DK3_BMEPS_RGB_ALPHA_FLATE: {
+ dk3pdf_out_col_not8_not_mixed(job, pc, min, xmax);
+ } break;
+ case DK3_BMEPS_GRAY_FLATE: {
+ dk3pdf_out_gray_not8_not_mixed(job, pc, min, xmax);
+ } break;
+ case DK3_BMEPS_GRAY_ALPHA_FLATE: {
+ dk3pdf_out_gray_not8_not_mixed(job, pc, min, xmax);
+ } break;
+ }
+ }
+ }
+ back = dk3of_end_chunk(job->of);
+ }
+ }
+ dk3of_close(job->of); job->of = NULL;
+ }
+ dk3stream_close(os);
+ }
+ if(back) {
+ switch(job->procedure) {
+ case DK3_BMEPS_GRAY_ALPHA_FLATE: case DK3_BMEPS_RGB_ALPHA_FLATE: {
+ back = dk3pdf_add_alpha_xobject(job, pc, xmax, max);
+ } break;
+ }
+ }
+ }
+ if(!dk3sf_fclose_fn_app(fipo, (job->xo)->tempfilename, (job->pdf)->app)) {
+ back = 0;
+ }
+ if(dk3sf_stat_app(&stb, (job->xo)->tempfilename, (job->pdf)->app)) {
+ (job->xo)->slgt = stb.sz;
+ } else {
+ back = 0;
+ /* ERROR: stat failed! */
+ }
+ } else { $? "! failed to write to temp file"
+ } $? "- dk3pdf_xobject_data %d", back
+ return back;
+}
+
+
+
+dk3_pdf_xobject_t *
+dk3pdf_create_ixobject_progress(
+ dk3_pdf_t *pdf,
+ dk3_bif_t *bif,
+ dk3_bm_eps_options_t *opt,
+ void *pc,
+ int min,
+ int max
+)
+{
+ dk3_pdf_image_job_t job; /* Conversion job. */
+ dk3_pdf_xobject_t *back = NULL;
+ int analysis_types = 0; /* Analysis setup. */
+ size_t nbits; /* Bits per component. */
+ $? "+ dk3pdf_create_ixobject_progress %!8s min=%d max=%d",TR_8PTR(pc),min,max
+ nbits = dk3bif_get_bits_per_pixel(bif);
+ dk3pdf_image_job_init(&job, opt, pdf, bif);
+ switch(dk3bif_get_color_space(bif)) {
+ case DK3_COLOR_SPACE_RGBA: case DK3_COLOR_SPACE_GRAY_ALPHA: {
+ job.h_alpha = 1;
+ } break;
+ }
+ switch(dk3bif_get_color_space(bif)) {
+ case DK3_COLOR_SPACE_GRAY_ALPHA: case DK3_COLOR_SPACE_GRAY: {
+ } break;
+ default: {
+ job.h_color = 1;
+ } break;
+ } $? ". bif type = %d", dk3bif_get_type(bif)
+ switch(dk3bif_get_type(bif)) {
+ case DK3_BIF_IMAGE_TYPE_JPEG: { $? ". have jpeg"
+ if(opt->dct) { $? ". dct allowed"
+ switch(dk3bif_get_bits_per_pixel(bif)) {
+ case 1: case 2: case 4: case 8: { $? ". bpc ok"
+ switch(dk3bif_jpeg_get_num_components(bif)) {
+ case 1: {
+ job.procedure = DK3_BMEPS_GRAY_DCT;
+ job.bpc = (int)dk3bif_get_bits_per_pixel(bif);
+ job.use_dct = 1;
+ } break;
+ case 3: {
+ job.procedure = DK3_BMEPS_RGB_DCT;
+ job.bpc = (int)dk3bif_get_bits_per_pixel(bif);
+ job.use_dct = 1;
+ } break;
+ case 4: {
+ job.procedure = DK3_BMEPS_CMYK_DCT;
+ job.bpc = (int)dk3bif_get_bits_per_pixel(bif);
+ job.use_dct = 1;
+ } break;
+ default: { $? "! num_comp=%u", (unsigned)dk3bif_jpeg_get_num_components(bif)
+ } break;
+ }
+ } break;
+ default: { $? "! bpc=%u", (unsigned)dk3bif_get_bits_per_pixel(bif)
+ } break;
+ }
+ }
+ } break;
+ }
+ if(!(job.use_dct)) {
+ if(job.h_color) { analysis_types |= DK3_BIF_ANALYSIS_COLOR; }
+ if(job.h_alpha) { analysis_types |= DK3_BIF_ANALYSIS_ALPHA; }
+ if(opt->rbpc) { analysis_types |= DK3_BIF_ANALYSIS_BITS; }
+ if(analysis_types) {
+ dk3bif_analyze_progress(bif, analysis_types, pc, min, ((max + min)/2));
+ if(opt->rbpc) { nbits = dk3bif_real_bits_per_pixel(bif); }
+ if(job.h_color) { job.h_color = dk3bif_real_color(bif); }
+ if(job.h_alpha) { job.h_alpha = dk3bif_real_alpha(bif); }
+ }
+#if 0
+ /* 2014-03-2
+ New algorithms for bits per component detection and reduction.
+ */
+ job.bpc = 1;
+ if(nbits > 1) {
+ job.bpc = 2;
+ if(nbits > 2) {
+ job.bpc = 4;
+ if(nbits > 4) {
+ job.bpc = 8;
+ }
+ }
+ }
+#else
+ switch (nbits) {
+ case 1: { job.bpc = 1; } break;
+ case 2: { job.bpc = 2; } break;
+ case 4: { job.bpc = 4; } break;
+ default: { job.bpc = 8; } break;
+ }
+#endif
+ if(job.h_color) {
+ if(job.h_alpha) {
+ switch(opt->mode) {
+ case DK3_BMEPS_MODE_OBJECT:
+ case DK3_BMEPS_MODE_PLACED_OBJECT: {
+ job.procedure = DK3_BMEPS_RGB_ALPHA_FLATE;
+ } break;
+ default: {
+ job.procedure = DK3_BMEPS_RGB_FLATE;
+ } break;
+ }
+ } else {
+ job.procedure = DK3_BMEPS_RGB_FLATE;
+ }
+ } else {
+ if(job.h_alpha) {
+ switch(opt->mode) {
+ case DK3_BMEPS_MODE_OBJECT:
+ case DK3_BMEPS_MODE_PLACED_OBJECT: {
+ job.procedure = DK3_BMEPS_GRAY_ALPHA_FLATE;
+ } break;
+ default: {
+ job.procedure = DK3_BMEPS_GRAY_FLATE;
+ } break;
+ }
+ } else {
+ job.procedure = DK3_BMEPS_GRAY_FLATE;
+ }
+ }
+ if(opt->pred > DK3_COMPRESSION_PREDICTOR_TIFF) {
+ job.bpc = 8;
+ }
+ }
+#if DK3_USE_WX
+ $? ". show progress"
+ dk3bmj_progress(pc, (min + max)/2);
+#endif
+ back = dk3pdf_xobject_new(pdf);
+ if(back) {
+ back->objno = pdf->nextobject;
+ if(dk3sto_add(pdf->s_xobjects, (void *)back)) {
+ pdf->nextobject += 1UL;
+ job.xo = back;
+ if(job.procedure == DK3_BMEPS_CMYK_DCT) {
+ if(dk3bif_jpeg_get_found_adobe_marker(bif)) {
+ back->adobe_marker_found = 1;
+ }
+ }
+ if(opt->ip) {
+ switch(dk3bif_get_type(bif)) {
+ case DK3_BIF_IMAGE_TYPE_JPEG: {
+ if(opt->jip) {
+ back->interpolate = 1;
+ }
+ } break;
+ default: {
+ back->interpolate = 1;
+ } break;
+ }
+ }
+ if(!dk3pdf_xobject_data(&job, pc, (min + max)/2, max)) {
+ back = NULL;
+ }
+ } else {
+ dk3pdf_xobject_delete(back);
+ back = NULL;
+ }
+ }
+#if DK3_USE_WX
+ $? ". %d", max
+ dk3bmj_progress(pc, max);
+#endif
+ $? "- dk3pdf_create_ixobject_progress %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+/* Now we use the function with progress indicator. */
+#if VERSION_BEFORE_20120104
+/** Create image XObject.
+ @param pdf PDF writer structure.
+ @param bif Image, the current frame will be added.
+ @param opt Conversion options.
+ @return Pointer to new object on success, NULL on error.
+*/
+static
+dk3_pdf_xobject_t *
+dk3pdf_create_ixobject(
+ dk3_pdf_t *pdf,
+ dk3_bif_t *bif,
+ dk3_bm_eps_options_t *opt
+)
+{
+ dk3_pdf_xobject_t *back;
+ $? "+ dk3pdf_create_ixobject"
+ back = dk3pdf_create_ixobject_progress(pdf, bif, opt, NULL, 0, 1000);
+ $? "- dk3pdf_create_ixobject %!8s", TR_8PTR(back)
+ return back;
+}
+#endif
+
+
+
+dk3_pdf_xobject_t *
+dk3pdf_add_image_progress(
+ dk3_pdf_t *pdf,
+ dk3_bif_t *bif,
+ dk3_bm_eps_options_t *opt,
+ void *pc,
+ int min,
+ int max
+)
+{
+ dk3_pdf_xobject_t *back = NULL;
+ $? "+ dk3pdf_add_image %!8s min=%d max=%d", TR_8PTR(pc), min, max
+ if((pdf) && (bif)) { $? ". pdf && bif"
+ if(pdf->cp) { $? ". pdf->cp"
+ if((pdf->cp)->tempof) { $? ". tempof"
+ back = dk3pdf_create_ixobject_progress(pdf, bif, opt, pc, min, max);
+ if(back) { $? ". back"
+ if(!dk3pdf_add_xobject_to_page(pdf, back)) {
+ back = NULL;
+ }
+ }
+ }
+ }
+ } $? "- dk3pdf_add_image %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+dk3_pdf_xobject_t *
+dk3pdf_add_image(
+ dk3_pdf_t *pdf,
+ dk3_bif_t *bif,
+ dk3_bm_eps_options_t *opt
+)
+{
+ dk3_pdf_xobject_t *back = NULL;
+ $? "+ dk3pdf_add_image"
+ back = dk3pdf_add_image_progress(pdf, bif, opt, NULL, 0, 1000);
+ $? "- dk3pdf_add_image %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+/** Write line to start object, keep object start position.
+ @param job PDF writer job structure.
+ @param on Object number.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3pdf_begin_object(dk3_pdf_writer_job_t *job, unsigned long on)
+{
+ char buf[64]; /* Conversion buffer. */
+ dk3_pdf_object_start_t *start; /* Start position object. */
+ dk3_um_t pos; /* Start position. */
+ int back = 0;
+ $? "+ dk3pdf_begin_object %lu", on
+ pos = dk3stream_bytes_written(job->os); $? ". pos"
+ if(on > job->largestObjectNumber) { job->largestObjectNumber = on; }
+ start = dk3_new_app(dk3_pdf_object_start_t,1,(job->pdf)->app);
+ if(start) { $? ". start"
+ start->objno = on;
+ start->startpos = pos;
+ if(dk3sto_add(job->s_objstart, (void *)start)) { $? ". add ok"
+ back = 1;
+ sprintf(buf, "%lu", on); $? ". sprintf"
+ dk3stream_c8_fputs(job->os, buf); $? ". buf"
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[8]); $? ". 8"
+ } else { $? "! add failed"
+ dk3_delete(start);
+ }
+ } else { $? "! start"
+ } $? "- dk3pdf_begin_object %d", back
+ return back;
+}
+
+
+
+/** Write object end.
+ @param job PDF writer job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+void
+dk3pdf_end_object(dk3_pdf_writer_job_t *job)
+{
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[9]); $? "= dk3pdf_end_object"
+}
+
+
+
+
+/** Write start of PDF file.
+ @param job PDF writer job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3pdf_write_file_start(dk3_pdf_writer_job_t *job)
+{
+ char buf[64]; /* Conversion buffer. */
+ dk3_pdf_page_t *pp; /* Current page. */
+ unsigned long ul = 0UL; /* Number of pages. */
+ dk3_time_t timer = 0UL; /* Current time. */
+ dk3_tm_t locti; /* Local time. */
+ int back = 1;
+ $? "+ dk3pdf_write_file_start"
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[7]);
+ if(dk3pdf_begin_object(job, 1UL)) {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[10]);
+ if (0 != dk3sf_time(&timer)) {
+ if (0 != dk3sf_localtime_app(&locti, &timer, NULL)) {
+ sprintf(
+ buf, dk3pdf_c8_kw[101],
+ locti.Y, locti.M, locti.D, locti.h, locti.m, locti.s
+ );
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[102]);
+ dk3stream_c8_fputs(job->os, buf);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[103]);
+ dk3stream_c8_fputs(job->os, buf);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[104]);
+ }
+ }
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[12]);
+ dk3pdf_end_object(job);
+ if(dk3pdf_begin_object(job, 2UL)) {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[11]);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[13]);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[14]);
+ if((job->pdf)->documentMode) {
+ if((job->firstPageObjectNumber) && (job->firstPageHeight)) {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[15]);
+ sprintf(buf, "%lu", job->firstPageObjectNumber);
+ dk3stream_c8_fputs(job->os, buf);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[16]);
+ sprintf(buf, "%ld", job->firstPageHeight);
+ dk3stream_c8_fputs(job->os, buf);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[17]);
+ }
+ }
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[12]);
+ dk3pdf_end_object(job);
+ if(dk3pdf_begin_object(job, 3UL)) {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[11]);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[57]);
+ ul = 0UL;
+ dk3sto_it_reset((job->pdf)->i_pages);
+ while((pp = (dk3_pdf_page_t *)dk3sto_it_next((job->pdf)->i_pages))
+ != NULL
+ )
+ {
+ ul++;
+ }
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[58]);
+ sprintf(buf, dk3pdf_c8_kw[59], ul);
+ dk3stream_c8_fputs(job->os, buf);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[60]);
+ dk3sto_it_reset((job->pdf)->i_pages);
+ while((pp = (dk3_pdf_page_t *)dk3sto_it_next((job->pdf)->i_pages))
+ != NULL
+ )
+ {
+ sprintf(buf, dk3pdf_c8_kw[62], pp->objno);
+ dk3stream_c8_fputs(job->os, buf);
+ }
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[61]);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[12]);
+ dk3pdf_end_object(job);
+ } else { $? "! begin_object"
+ back = 0;
+ }
+ } else { $? "! begin_object"
+ back = 0;
+ }
+ } else { $? "! begin_object"
+ back = 0;
+ } $? "- dk3pdf_write_file_start %d", back
+ return back;
+}
+
+
+
+/** Write decode params for flate compression when
+ using a predictor.
+ @param os Output stream.
+ @param predictorline Index of predictor line.
+ @param bpc Bits per component.
+ @param procedure Compression procedure.
+ @param width Image width.
+*/
+static
+void
+dk3pdf_decode_parms(
+ dk3_stream_t *os,
+ int predictorline,
+ int bpc,
+ int procedure,
+ dk3_bif_coord_t width
+)
+{
+ char buf[256]; /* Conversion buffer. */
+ $? "+ dk3pdf_decode_parms"
+ dk3stream_c8_fputs(os, dk3pdf_c8_kw[64]);
+ dk3stream_c8_fputs(os, dk3pdf_c8_kw[predictorline]);
+ sprintf(buf, "%d", bpc);
+ dk3stream_c8_fputs(os, dk3pdf_c8_kw[31]);
+ dk3stream_c8_fputs(os, buf);
+ dk3stream_c8_fputs(os, dk3pdf_c8_kw[0]);
+ dk3stream_c8_fputs(os, dk3pdf_c8_kw[65]);
+ switch(procedure) {
+ case DK3_BMEPS_CMYK_DCT: {
+ dk3stream_c8_fputs(os, dk3pdf_c8_kw[66]);
+ } break;
+ case DK3_BMEPS_GRAY_UNCOMPRESSED:
+ case DK3_BMEPS_GRAY_RUNLENGTH:
+ case DK3_BMEPS_GRAY_DCT:
+ case DK3_BMEPS_GRAY_FLATE:
+ case DK3_BMEPS_GRAY_ALPHA_FLATE: {
+ dk3stream_c8_fputs(os, dk3pdf_c8_kw[67]);
+ } break;
+ default: {
+ dk3stream_c8_fputs(os, dk3pdf_c8_kw[68]);
+ } break;
+ }
+ dk3stream_c8_fputs(os, dk3pdf_c8_kw[0]);
+ dk3stream_c8_fputs(os, dk3pdf_c8_kw[69]);
+ sprintf(buf, "%ld", width);
+ dk3stream_c8_fputs(os, buf);
+ dk3stream_c8_fputs(os, dk3pdf_c8_kw[0]);
+ dk3stream_c8_fputs(os, dk3pdf_c8_kw[12]); $? "- dk3pdf_decode_parms"
+}
+
+
+
+/** Write XObjects of PDF file.
+ @param job PDF writer job structure.
+ @param pcomm Communicator object.
+ @param minpb Minimum progress bar value.
+ @param maxpb Maximum progress bar value.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3pdf_write_file_xobjects(
+ dk3_pdf_writer_job_t *job,
+ void *pcomm,
+ int minpb,
+ int maxpb
+)
+{
+ char buf[64]; /* Conversion buffer. */
+ char sbuf[4096]; /* Data transfer bufer. */
+ dk3_pdf_xobject_t *xo; /* Current XObject. */
+ dk3_pdf_xobject_t *xmask; /* Mask for object. */
+ FILE *fipo; /* Input file (object stream). */
+ size_t rb; /* Number of bytes read. */
+ int back = 1;
+ int cc; /* Flag: Can continue transfer. */
+ $? "+ dk3pdf_write_file_xobjects"
+ dk3sto_it_reset((job->pdf)->i_xobjects);
+ while((xo = (dk3_pdf_xobject_t *)dk3sto_it_next((job->pdf)->i_xobjects))
+ != NULL
+ )
+ {
+ if(dk3pdf_begin_object(job, xo->objno)) {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[11]);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[27]); /* /Type /XObject */
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[28]); /* /Subtype /Image */
+ sprintf(buf, "%ld", xo->width);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[29]);
+ dk3stream_c8_fputs(job->os, buf);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[0]);
+ sprintf(buf, "%ld", xo->height);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[30]);
+ dk3stream_c8_fputs(job->os, buf);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[0]);
+ sprintf(buf, "%d", xo->bpc);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[31]);
+ dk3stream_c8_fputs(job->os, buf);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[0]);
+ switch(xo->xot) {
+ case DK3_PDF_XO_TYPE_ALPHA: {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[32]);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[34]);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[36]);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[37]);
+ } break;
+ default: {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[32]);
+ switch(xo->procedure) {
+ case DK3_BMEPS_CMYK_DCT: {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[33]);
+ if(xo->adobe_marker_found) {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[40]);
+ }
+ } break;
+ case DK3_BMEPS_GRAY_DCT:
+ case DK3_BMEPS_GRAY_FLATE:
+ case DK3_BMEPS_GRAY_ALPHA_FLATE: {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[34]);
+ } break;
+ default: {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[35]);
+ } break;
+ }
+ if(xo->mask) {
+ xmask = (dk3_pdf_xobject_t *)(xo->mask);
+ sprintf(buf, "%lu", xmask->objno);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[46]);
+ dk3stream_c8_fputs(job->os, buf);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[47]);
+ }
+ if(xo->interpolate) {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[63]);
+ }
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[36]);
+ if(xo->dct) {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[38]);
+ } else {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[37]);
+ }
+ } break;
+ }
+ if(!(xo->dct)) {
+ switch(xo->pred) {
+ case DK3_COMPRESSION_PREDICTOR_TIFF: {
+ dk3pdf_decode_parms(job->os, 41, xo->bpc, xo->procedure, xo->width);
+ /* dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[41]); */
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_SUB: {
+ dk3pdf_decode_parms(job->os, 42, xo->bpc, xo->procedure, xo->width);
+ /* dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[42]); */
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_UP: {
+ dk3pdf_decode_parms(job->os, 43, xo->bpc, xo->procedure, xo->width);
+ /* dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[43]); */
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_AVERAGE: {
+ dk3pdf_decode_parms(job->os, 44, xo->bpc, xo->procedure, xo->width);
+ /* dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[44]); */
+ } break;
+ case DK3_COMPRESSION_PREDICTOR_PNG_PAETH: {
+ dk3pdf_decode_parms(job->os, 45, xo->bpc, xo->procedure, xo->width);
+ /* dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[45]); */
+ } break;
+ }
+ }
+ if(dk3ma_um_to_c8_string(buf, sizeof(buf), xo->slgt)) {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[39]);
+ dk3stream_c8_fputs(job->os, buf);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[0]);
+ }
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[12]);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[25]);
+ /* Data stream */
+ fipo = dk3sf_fopen_app(
+ xo->tempfilename,
+ dk3app_not_localized(36),
+ (job->pdf)->app
+ );
+ if(fipo) {
+ do {
+ cc = 0;
+ rb = dk3sf_fread_app(sbuf, 1, sizeof(sbuf), fipo, (job->pdf)->app);
+ if(rb > 0) {
+ cc = 1;
+ if(rb != dk3stream_write_bytes(job->os, sbuf, rb)) {
+ back = 0;
+ /* ERROR While writing data! */
+ }
+ }
+ } while(cc);
+ if(!dk3sf_fclose_fn_app(fipo, xo->tempfilename, (job->pdf)->app)) {
+ back = 0;
+ }
+ fipo = NULL;
+ } else {
+ back = 0;
+ /* ERROR: Failed to open file! */
+ }
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[26]);
+ dk3pdf_end_object(job);
+ } else {
+ back = 0;
+ /* ERROR: Failed to begin Xobject! */
+ }
+#if DK3_USE_WX
+ dk3bmj_obj_progress(pcomm,minpb,maxpb,(job->pdf)->nextobject,(xo->objno + 1UL));
+#endif
+ } $? "- dk3pdf_write_file_xobjects %d", back
+ return back;
+}
+
+
+
+/** Write pages of PDF file.
+ @param job PDF writer job structure.
+ @param pcomm Communicator object.
+ @param minpb Minimum progress bar value.
+ @param maxpb Maximum progress bar value.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3pdf_write_file_pages(
+ dk3_pdf_writer_job_t *job,
+ void *pcomm,
+ int minpb,
+ int maxpb
+)
+{
+ char buf[4096]; /* Data transfer buffer. */
+ FILE *fipo; /* Input file (page contents stream). */
+ dk3_pdf_page_t *cp; /* Current page. */
+ dk3_pdf_xobject_t *xo; /* Traverse XObjects. */
+ size_t rb; /* Number of bytes read. */
+ int back = 1;
+ int have_mask; /* Flag: Have alpha mask. */
+ int cc; /* Flag: Can continue transfer. */
+ $? "+ dk3pdf_write_file_pages"
+ dk3sto_it_reset((job->pdf)->i_pages);
+ while((cp = (dk3_pdf_page_t *)dk3sto_it_next((job->pdf)->i_pages)) != NULL) {
+ $? ". page found"
+ /*
+ Mark all Xobjects as unused.
+ */
+ dk3sto_it_reset((job->pdf)->i_xobjects);
+ while((xo = (dk3_pdf_xobject_t *)dk3sto_it_next((job->pdf)->i_xobjects))
+ != NULL
+ )
+ {
+ xo->used = 0;
+ } $? ". all objects marked as unused"
+ /*
+ Mark Xobjects used by this page.
+ */
+ have_mask = 0;
+ if((cp->s_xobjects) && (cp->i_xobjects)) {
+ dk3sto_it_reset(cp->i_xobjects);
+ while((xo = (dk3_pdf_xobject_t *)dk3sto_it_next(cp->i_xobjects)) != NULL)
+ {
+ xo->used = 1; $? ". object found"
+ if(xo->mask) { $? ". object with mask"
+ have_mask = 1;
+ }
+ }
+ } $? ". used objects marked"
+ /*
+ Write page object.
+ */
+ $? ". going to write objects"
+ if(dk3pdf_begin_object(job, cp->objno)) { $? ". begin_object"
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[11]); /* << */
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[48]); $? ". 48"
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[49]); $? ". 49"
+ sprintf(buf, dk3pdf_c8_kw[50], cp->mbx0, cp->mby0, cp->mbx1, cp->mby1);
+ dk3stream_c8_fputs(job->os, buf); $? ". buf"
+ sprintf(buf, dk3pdf_c8_kw[100], cp->mbx0, cp->mby0, cp->mbx1, cp->mby1);
+ dk3stream_c8_fputs(job->os, buf);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[51]); /* /Resources << */
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[11]); $? ". 11"
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[52]); $? ". 52"
+ if((cp->s_xobjects) && (cp->i_xobjects)) { $? ". objects"
+ sprintf(buf, dk3pdf_c8_kw[53], (cp->objno + 2UL)); $? ". sprintf"
+ dk3stream_c8_fputs(job->os, buf); $? ". buf"
+ }
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[12]); /* >> */
+ sprintf(buf, dk3pdf_c8_kw[54], (cp->objno + 1UL)); $? ". sprintf"
+ dk3stream_c8_fputs(job->os, buf); $? ". buf"
+ /* Group (for alpha) */
+ if(have_mask) { $? ". have_mask"
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[55]); $? ". 55"
+ }
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[12]); /* >> */
+ dk3pdf_end_object(job); $? ". page object finished"
+ /*
+ Write content stream object.
+ */
+ if(dk3pdf_begin_object(job, (cp->objno + 1UL))) {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[11]);
+ if(dk3ma_um_to_c8_string(buf, sizeof(buf), cp->slgt)) {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[39]);
+ dk3stream_c8_fputs(job->os, buf);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[0]);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[36]);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[37]);
+ } else {
+ back = 0;
+ /* ERROR: Failed to convert length! */
+ }
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[12]);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[25]);
+ fipo = dk3sf_fopen_app(
+ cp->tempfilename,
+ dk3app_not_localized(36),
+ (job->pdf)->app
+ );
+ if(fipo) {
+ do {
+ cc = 0;
+ rb = dk3sf_fread_app(buf, 1, sizeof(buf), fipo, (job->pdf)->app);
+ if(rb > 0) {
+ cc = 1;
+ if(rb != dk3stream_write_bytes(job->os, buf, rb)) {
+ back = 0;
+ /* ERROR: Write failed! */
+ }
+ }
+ } while(cc);
+ if(!dk3sf_fclose_fn_app(fipo, cp->tempfilename, (job->pdf)->app)) {
+ back = 0;
+ }
+ } else {
+ back = 0;
+ /* ERROR: Failed to open file! */
+ }
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[26]);
+ dk3pdf_end_object(job); $? ". stream object finished"
+ /*
+ Write XObjects dictionary.
+ */
+ if((cp->s_xobjects) && (cp->i_xobjects)) {
+ if(dk3pdf_begin_object(job, (cp->objno + 2UL))) {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[11]);
+ dk3sto_it_reset((job->pdf)->i_xobjects);
+ while((xo =
+ (dk3_pdf_xobject_t *)dk3sto_it_next((job->pdf)->i_xobjects)
+ )
+ != NULL
+ )
+ {
+ sprintf(buf, dk3pdf_c8_kw[56], xo->objno, xo->objno);
+ dk3stream_c8_fputs(job->os, buf);
+ }
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[12]);
+ dk3pdf_end_object(job); $? ". dictionary finished"
+ } else {
+ back = 0;
+ /* ERROR: Memory */
+ }
+ }
+ } else {
+ back = 0;
+ /* ERROR: Memory */
+ }
+ } else { $? "! failed to start object"
+ back = 0;
+ /* ERROR: Memory */
+ }
+#if DK3_USE_WX
+ dk3bmj_obj_progress(pcomm,minpb,maxpb,(job->pdf)->nextobject,(cp->objno + 1UL));
+#endif
+ } $? "- dk3pdf_write_file_pages %d", back
+ return back;
+}
+
+
+
+/** Write end of PDF file.
+ @param job PDF writer job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3pdf_write_file_end(dk3_pdf_writer_job_t *job)
+{
+ char buf[64]; /* Conversion buffer. */
+ dk3_pdf_position_t *pos; /* Position structure. */
+ dk3_um_t startxref; /* Position of xref start. */
+ size_t sl; /* Buffer length. */
+ size_t i; /* Fill buffer with '0'. */
+ int back = 1;
+ $? "+ dk3pdf_write_file_end"
+ startxref = dk3stream_bytes_written(job->os);
+ sprintf(buf, "%lu", (job->largestObjectNumber + 1UL));
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[18]);
+ dk3stream_c8_fputs(job->os, buf);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[0]);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[19]);
+ dk3sto_it_reset(job->i_objstart);
+ while((pos = (dk3_pdf_position_t *)dk3sto_it_next(job->i_objstart)) != NULL) {
+ if(dk3ma_um_to_c8_string(buf, sizeof(buf), pos->startpos)) {
+ if((sl = strlen(buf)) <= 10) {
+ for(i = sl; i < 10; i++) {
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[20]);
+ }
+ dk3stream_c8_fputs(job->os, buf);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[21]);
+ } else {
+ back = 0;
+ /* Object start position too large! */
+ }
+ } else {
+ back = 0;
+ /* ERROR: Failed to convert position! */
+ }
+ }
+ sprintf(buf, "%lu", (job->largestObjectNumber + 1UL));
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[22]);
+ dk3stream_c8_fputs(job->os, buf);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[23]);
+ if(dk3ma_um_to_c8_string(buf, sizeof(buf), startxref)) {
+ dk3stream_c8_fputs(job->os, buf);
+ dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[24]);
+ } else {
+ back = 0;
+ /* ERROR: Failed to convert number! */
+ } $? "- dk3pdf_write_file_end %d", back
+ return back;
+}
+
+
+
+/** Assign object numbers to pages.
+*/
+static
+void
+dk3pdf_enumerate_pages(dk3_pdf_writer_job_t *job)
+{
+ dk3_pdf_page_t *pa; /* Current page. */
+ unsigned long on; /* Next object number. */
+ $? "+ dk3pdf_enumerate_pages"
+ on = (job->pdf)->nextobject;
+ dk3sto_it_reset((job->pdf)->i_pages);
+ while((pa = (dk3_pdf_page_t *)dk3sto_it_next((job->pdf)->i_pages)) != NULL)
+ {
+ if(!(job->firstPageObjectNumber)) {
+ job->firstPageObjectNumber = on;
+ job->firstPageHeight = pa->mby1;
+ }
+ /*
+ Each page consumes at least two object numbers:
+ Page object and page content stream object.
+ */
+ pa->objno = on++;
+ on++;
+ /*
+ If the page uses XObjects we must create an
+ XObject dictionary.
+ */
+ if((pa->s_xobjects) && (pa->i_xobjects)) { on++; }
+ }
+ (job->pdf)->nextobject = on;
+ $? "- dk3pdf_enumerate_pages"
+}
+
+
+
+int
+dk3pdf_write_file_progress(
+ dk3_pdf_t *pdf,
+ FILE *ofile,
+ void *pcomm,
+ int minpb,
+ int maxpb
+)
+{
+ dk3_pdf_writer_job_t job; /* Writer job. */
+ int back = 0;
+ $? "+ dk3pdf_write_file"
+ if((pdf) && (ofile)) { $? ". args ok"
+ if(pdf->cp) { dk3pdf_close_page(pdf); }
+ if(dk3pdf_job_init(&job, pdf, ofile)) {
+ back = 1;
+ dk3pdf_enumerate_pages(&job);
+ if(!dk3pdf_write_file_start(&job)) { back = 0; }
+ if(!dk3pdf_write_file_xobjects(&job, pcomm, minpb, maxpb)) { back = 0; }
+ if(!dk3pdf_write_file_pages(&job, pcomm, minpb, maxpb)) { back = 0; }
+ if(!dk3pdf_write_file_end(&job)) { back = 0; }
+ }
+ dk3pdf_job_end(&job);
+ } else {
+ if(!(pdf)) { $? "! pdf"
+ }
+ if(!(ofile)) { $? "! ofile"
+ }
+ } $? "- dk3pdf_write_file %d", back
+ return back;
+}
+
+
+
+int
+dk3pdf_write_file(dk3_pdf_t *pdf, FILE *ofile)
+{
+ int back;
+ $? "+ dk3pdf_write_file"
+ back = dk3pdf_write_file_progress(pdf, ofile, NULL, 0, 1000);
+ $? "- dk3pdf_write_file %d", back
+ return back;
+}
+
+
+
+/** Write point coordinates to output filter.
+ @param of Output filter.
+ @param x X value.
+ @param y Y value.
+*/
+static
+void
+dk3pdf_write_point(dk3_of_t *of, double x, double y)
+{
+ dk3pdf_write_double(of, x);
+ dk3of_write_c8_string(of, dk3pdf_c8_kw[1]);
+ dk3pdf_write_double(of, y);
+ dk3of_write_c8_string(of, dk3pdf_c8_kw[1]);
+ $? "= dk3pdf_write_point %lg %lg", x, y
+}
+
+
+
+int
+dk3pdf_newpath_moveto(dk3_pdf_t *pdf, double x, double y)
+{
+ int back = 0;
+ $? "+ dk3pdf_newpath_moveto %lg %lg", x, y
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ dk3pdf_write_point((pdf->cp)->tempof, x, y);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[71]);
+ }
+ }
+ } $? "- dk3pdf_newpath_moveto %d", back
+ return back;
+}
+
+
+
+int
+dk3pdf_lineto(dk3_pdf_t *pdf, double x, double y)
+{
+ int back = 0;
+ $? "+ dk3pdf_lineto %lg %lg", x, y
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ dk3pdf_write_point((pdf->cp)->tempof, x, y);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[72]);
+ }
+ }
+ } $? "- dk3pdf_lineto %d", back
+ return back;
+}
+
+
+
+int
+dk3pdf_curveto(
+ dk3_pdf_t *pdf,
+ double xcs, double ycs,
+ double xce, double yce,
+ double xe, double ye
+)
+{
+ int back = 0;
+ $? "+ dk3pdf_curveto"
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ dk3pdf_write_point((pdf->cp)->tempof, xcs, ycs);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]);
+ dk3pdf_write_point((pdf->cp)->tempof, xce, yce);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]);
+ dk3pdf_write_point((pdf->cp)->tempof, xe, ye);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[89]);
+ }
+ }
+ } $? "- dk3pdf_curveto %d", back
+ return back;
+}
+
+
+int
+dk3pdf_set_nonstroking_gray(dk3_pdf_t *pdf, double g)
+{
+ int back = 0;
+ double ng; /* Corrected gray value. */
+ $? "+ dk3pdf_set_nonstroking_gray %lg", g
+ ng = dk3pdf_to_range(0.0, 1.0, g);
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ dk3pdf_write_double((pdf->cp)->tempof, ng);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[73]);
+ }
+ }
+ } $? "- dk3pdf_set_nonstroking_gray %d", back
+ return back;
+}
+
+
+
+int
+dk3pdf_set_stroking_gray(dk3_pdf_t *pdf, double g)
+{
+ int back = 0;
+ double ng; /* Corrected gray value. */
+ $? "+ dk3pdf_set_stroking_gray %lg", g
+ ng = dk3pdf_to_range(0.0, 1.0, g);
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ dk3pdf_write_double((pdf->cp)->tempof, ng);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[74]);
+ }
+ }
+ } $? "- dk3pdf_set_stroking_gray %d", back
+ return back;
+}
+
+
+
+int
+dk3pdf_closepath_fill_stroke_nz(dk3_pdf_t *pdf)
+{
+ int back = 0;
+ $? "+ dk3pdf_closepath_fill_stroke_nz"
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[75]);
+ }
+ }
+ } $? "- dk3pdf_closepath_fill_stroke_nz %d", back
+ return back;
+}
+
+
+
+
+int
+dk3pdf_closepath_fill_stroke_eo(dk3_pdf_t *pdf)
+{
+ int back = 0;
+ $? "+ dk3pdf_closepath_fill_stroke_eo"
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[77]);
+ }
+ }
+ } $? "- dk3pdf_closepath_fill_stroke_eo %d", back
+ return back;
+}
+
+
+
+int
+dk3pdf_closepath(dk3_pdf_t *pdf)
+{
+ int back = 0;
+ $? "+ dk3pdf_closepath"
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[81]);
+ }
+ }
+ } $? "- dk3pdf_closepath %d", back
+ return back;
+}
+
+
+
+int
+dk3pdf_fill_nz(dk3_pdf_t *pdf)
+{
+ int back = 0;
+ $? "+ dk3pdf_fill_nz"
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[79]);
+ }
+ }
+ } $? "- dk3pdf_fill_nz %d", back
+ return back;
+}
+
+
+
+int
+dk3pdf_fill_eo(dk3_pdf_t *pdf)
+{
+ int back = 0;
+ $? "+ dk3pdf_fill_eo"
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[80]);
+ }
+ }
+ } $? "- dk3pdf_fill_eo %d", back
+ return back;
+}
+
+
+
+int
+dk3pdf_clip_eo(dk3_pdf_t *pdf)
+{
+ int back = 0;
+ $? "+ dk3pdf_clip_eo"
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[88]);
+ }
+ }
+ } $? "- dk3pdf_clip_eo %d", back
+ return back;
+}
+
+
+
+int
+dk3pdf_clip_nz(dk3_pdf_t *pdf)
+{
+ int back = 0;
+ $? "+ dk3pdf_clip_eo"
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[97]);
+ }
+ }
+ } $? "- dk3pdf_clip_eo %d", back
+ return back;
+}
+
+
+int
+dk3pdf_nonstroking_rgb(dk3_pdf_t *pdf, double r, double g, double b)
+{
+ int back = 0;
+ double nr; /* Corrected red. */
+ double ng; /* Corrected green. */
+ double nb; /* Corrected blue. */
+ $? "+ dk3pdf_nonstroking_rgb %lg %lg %lg", r, g, b
+ nr = dk3pdf_to_range(0.0, 1.0, r);
+ ng = dk3pdf_to_range(0.0, 1.0, g);
+ nb = dk3pdf_to_range(0.0, 1.0, b);
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ dk3pdf_write_double((pdf->cp)->tempof, nr);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]);
+ dk3pdf_write_double((pdf->cp)->tempof, ng);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]);
+ dk3pdf_write_double((pdf->cp)->tempof, nb);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[82]);
+ }
+ }
+ } $? "- dk3pdf_nonstroking_rgb %d", back
+ return back;
+}
+
+
+
+int
+dk3pdf_stroking_rgb(dk3_pdf_t *pdf, double r, double g, double b)
+{
+ int back = 0;
+ double nr; /* Corrected red. */
+ double ng; /* Corrected green. */
+ double nb; /* Corrected blue. */
+ $? "+ dk3pdf_stroking_rgb %lg %lg %lg", r, g, b
+ nr = dk3pdf_to_range(0.0, 1.0, r);
+ ng = dk3pdf_to_range(0.0, 1.0, g);
+ nb = dk3pdf_to_range(0.0, 1.0, b);
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ dk3pdf_write_double((pdf->cp)->tempof, nr);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]);
+ dk3pdf_write_double((pdf->cp)->tempof, ng);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]);
+ dk3pdf_write_double((pdf->cp)->tempof, nb);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[83]);
+ }
+ }
+ } $? "- dk3pdf_stroking_rgb %d", back
+ return back;
+}
+
+
+
+int
+dk3pdf_set_linecap(dk3_pdf_t *pdf, int lc)
+{
+ int back = 0;
+ $? "+ dk3pdf_set_linecap %d", lc
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ switch(lc) {
+ case DK3_LINECAP_SQUARE: {
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[84]);
+ } break;
+ case DK3_LINECAP_ROUND: {
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[67]);
+ } break;
+ default: {
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[20]);
+ } break;
+ }
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[85]);
+ }
+ }
+ } $? "- dk3pdf_set_linecap %d", back
+ return back;
+}
+
+
+
+int
+dk3pdf_set_linejoin(dk3_pdf_t *pdf, int lj)
+{
+ int back = 0;
+ $? "+ dk3pdf_set_linecap %d", lj
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ switch(lj) {
+ case DK3_LINEJOIN_BEVEL: {
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[84]);
+ } break;
+ case DK3_LINEJOIN_ROUND: {
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[67]);
+ } break;
+ default: {
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[20]);
+ } break;
+ }
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[90]);
+ }
+ }
+ } $? "- dk3pdf_set_linecap %d", back
+ return back;
+}
+
+
+int
+dk3pdf_stroke(dk3_pdf_t *pdf)
+{
+ int back = 0;
+ $? "+ dk3pdf_stroke"
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[94]);
+ }
+ }
+ } $? "- dk3pdf_stroke %d", back
+ return back;
+}
+
+
+
+
+int
+dk3pdf_set_linewidth(dk3_pdf_t *pdf, double lw)
+{
+ int back = 0;
+ $? "+ dk3pdf_set_linewidth %lg", lw
+ if(pdf) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ dk3pdf_write_double((pdf->cp)->tempof, lw);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[87]);
+ }
+ }
+ } $? "- dk3pdf_set_linewidth %d", back
+ return back;
+}
+
+
+
+int
+dk3pdf_set_line_dash(dk3_pdf_t *pdf, double *sv, size_t nsv, double ph)
+{
+ size_t i;
+ int back = 0;
+ if((pdf) && (sv)) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ back = 1;
+ /* [ */
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[92]);
+ for(i = 0; i < nsv; i++) {
+ if(0 < i) {
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]);
+ }
+ dk3pdf_write_double((pdf->cp)->tempof, sv[i]);
+ }
+ /* ] */
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[93]);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]);
+ /* phase */
+ dk3pdf_write_double((pdf->cp)->tempof, ph);
+ /* d + newline */
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[91]);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3pdf_write_debug_line(dk3_pdf_t *pdf, char const *txt)
+{
+ int back = 0;
+ if((pdf) && (txt)) {
+ if(pdf->cp) {
+ if((pdf->cp)->tempof) {
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[98]);
+ dk3of_write_c8_string((pdf->cp)->tempof, txt);
+ dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[0]);
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk3pdf.h b/support/dktools/dk3pdf.h
new file mode 100644
index 0000000000..5a9e03e575
--- /dev/null
+++ b/support/dktools/dk3pdf.h
@@ -0,0 +1,428 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3pdf.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3pdf.h Header file for the dk3pdf module.
+*/
+
+#ifndef DK3PDF_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3PDF_H_INCLUDED 1
+
+
+#line 10 "dk3pdf.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Create PDF writer structure.
+ @param app Application structure, required here.
+ @return Pointer to new structure on success, NULL on error.
+*/
+dk3_pdf_t *
+dk3pdf_open_app(dk3_app_t *app);
+
+/** Write PDF to output file.
+ @param pdf PDF writer structure.
+ @param ofile Output file.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_write_file(dk3_pdf_t *pdf, FILE *ofile);
+
+/** Write PDF to output file.
+ @param pdf PDF writer structure.
+ @param ofile Output file.
+ @param pcomm Communicator object.
+ @param minpb Minimum progress bar value.
+ @param maxpb Maximum progress bar value.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_write_file_progress(
+ dk3_pdf_t *pdf,
+ FILE *ofile,
+ void *pcomm,
+ int minpb,
+ int maxpb
+);
+
+/** Destroy PDF writer structure, release memory.
+ @param pdf Structure to destroy.
+*/
+void
+dk3pdf_close(dk3_pdf_t *pdf);
+
+/** Prepare media box for next page to open.
+ @param pdf PDF writer structure.
+ @param x0 Left x.
+ @param x1 Right x.
+ @param y0 Bottom y.
+ @param y1 Top y.
+*/
+void
+dk3pdf_set_next_mediabox(
+ dk3_pdf_t *pdf,
+ long x0,
+ long x1,
+ long y0,
+ long y1
+);
+
+/** Open a new page.
+ @param pdf PDF writer structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_open_page(dk3_pdf_t *pdf);
+
+/** Open a new page, set clip path to media box.
+ @param pdf PDF writer structure.
+ @param wc Flag: With clip path setting.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_open_page_with_clip(dk3_pdf_t *pdf, int wc);
+
+/** Close the current page.
+ @param pdf PDF writer structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_close_page(dk3_pdf_t *pdf);
+
+/** Write save graphics state instruction to current page.
+ @param pdf PDF writer structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_gsave(dk3_pdf_t *pdf);
+
+/** Write restore graphics state instruction to current page.
+ @param pdf PDF writer structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_grestore(dk3_pdf_t *pdf);
+
+/** Translate coordinates, use long values.
+ @param pdf PDF writer structure.
+ @param x X translation.
+ @param y Y translation.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_translate_long(dk3_pdf_t *pdf, long x, long y);
+
+/** Translate coordinates, use double values.
+ @param pdf PDF writer structure.
+ @param x X translation.
+ @param y Y translation.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_translate_double(dk3_pdf_t *pdf, double x, double y);
+
+/** Rotate coordinates, use integer value.
+ @param pdf PDF writer structure.
+ @param angle Rotation angle in degree.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_rotate_int(dk3_pdf_t *pdf, int angle);
+
+/** Rotate coordinates, use double value.
+ @param pdf PDF writer structure.
+ @param angle Rotation angle in degree.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_rotate_double(dk3_pdf_t *pdf, double angle);
+
+/** Scale coordinates, use long values.
+ @param pdf PDF writer structure.
+ @param x X scale factor.
+ @param y Y scale factor.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_scale_long(dk3_pdf_t *pdf, long x, long y);
+
+/** Scale coordinates, use double values.
+ @param pdf PDF writer structure.
+ @param x X scale factor.
+ @param y Y scale factor.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_scale_double(dk3_pdf_t *pdf, double x, double y);
+
+/** Add XObject to current page.
+ @param pdf PDF writer structure.
+ @param xo XObject to add.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_add_xobject_to_page(dk3_pdf_t *pdf, dk3_pdf_xobject_t *xo);
+
+/** Add image.
+ @param pdf PDF writer structure.
+ @param bif Image, the current frame will be added.
+ @param opt Conversion options.
+ @param pc Communicator object.
+ @param min Minimum progress bar value (0-1000).
+ @param max Maximum progress bar value (0-1000).
+ @return Pointer to object on success, NULL on error.
+*/
+dk3_pdf_xobject_t *
+dk3pdf_add_image_progress(
+ dk3_pdf_t *pdf,
+ dk3_bif_t *bif,
+ dk3_bm_eps_options_t *opt,
+ void *pc,
+ int min,
+ int max
+);
+
+/** Add image.
+ @param pdf PDF writer structure.
+ @param bif Image, the current frame will be added.
+ @param opt Conversion options.
+ @return Pointer to object on success, NULL on error.
+*/
+dk3_pdf_xobject_t *
+dk3pdf_add_image(
+ dk3_pdf_t *pdf,
+ dk3_bif_t *bif,
+ dk3_bm_eps_options_t *opt
+);
+
+/** PDF newpath and lineto. Start new path and move to specified position.
+ @param pdf PDF writer structure.
+ @param x New x position.
+ @param y New y position.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_newpath_moveto(dk3_pdf_t *pdf, double x, double y);
+
+/** PDF lineto.
+ @param pdf PDF writer structure.
+ @param x New x
+ @param y New y.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_lineto(dk3_pdf_t *pdf, double x, double y);
+
+/** PDF curveto.
+ @param pdf PDF writer structure.
+ @param xcs Control point X near start.
+ @param ycs Control point Y near start.
+ @param xce Control point X near end.
+ @param yce Control point Y near end.
+ @param xe End point X.
+ @param ye End point Y.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_curveto(
+ dk3_pdf_t *pdf,
+ double xcs, double ycs,
+ double xce, double yce,
+ double xe, double ye
+);
+
+/** Set nonstroking gray.
+ @param pdf PDF writer structure.
+ @param g New gray value.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_set_nonstroking_gray(dk3_pdf_t *pdf, double g);
+
+/** Set stroking gray.
+ @param pdf PDF writer structure.
+ @param g New gray value.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_set_stroking_gray(dk3_pdf_t *pdf, double g);
+
+/** Close path, fill (non-zero winding rule), and stroke path.
+ @param pdf PDF writer structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_closepath_fill_stroke_nz(dk3_pdf_t *pdf);
+
+/** Close path, fill (even/odd rule), and stroke path.
+ @param pdf PDF writer structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_closepath_fill_stroke_eo(dk3_pdf_t *pdf);
+
+/** Close path.
+ @param pdf PDF writer structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_closepath(dk3_pdf_t *pdf);
+
+/** Fill current path (non-zero winding rule).
+ @param pdf PDF writer structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_fill_nz(dk3_pdf_t *pdf);
+
+/** Fill current path (even/odd rule).
+ @param pdf PDF writer structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_fill_eo(dk3_pdf_t *pdf);
+
+/** Clip to current path (even/odd rule).
+ @param pdf PDF writer structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_clip_eo(dk3_pdf_t *pdf);
+
+/** Clip to current path (non-zero rule).
+ @param pdf PDF writer structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_clip_nz(dk3_pdf_t *pdf);
+
+/** Set RGB color for nonstroking operations.
+ @param pdf PDF writer structure.
+ @param r Red.
+ @param g Green.
+ @param b Blue.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_nonstroking_rgb(dk3_pdf_t *pdf, double r, double g, double b);
+
+/** Set RGB color for stroking operations.
+ @param pdf PDF writer structure.
+ @param r Red.
+ @param g Green.
+ @param b Blue.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_stroking_rgb(dk3_pdf_t *pdf, double r, double g, double b);
+
+/** Set line cap mode.
+ @param pdf PDF writer structure.
+ @param lc Line cap DK3_LINECAP_xxx, see @ref linecap.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_set_linecap(dk3_pdf_t *pdf, int lc);
+
+/** Set line join mode.
+ @param pdf PDF writer structure.
+ @param lj Line cap DK3_LINECAP_xxx, see @ref linecap.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_set_linejoin(dk3_pdf_t *pdf, int lj);
+
+/** Set line dash pattern.
+ @param pdf PDF writer structure.
+ @param sv Style values array.
+ @param nsv Number of elements in sv.
+ @param ph Phase (initial shift).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_set_line_dash(dk3_pdf_t *pdf, double *sv, size_t nsv, double ph);
+
+/** Stroke current path.
+ @param pdf PDF writer structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_stroke(dk3_pdf_t *pdf);
+
+/** Set line width for stroke operations.
+ @param pdf PDF writer structure.
+ @param lw New line width.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_set_linewidth(dk3_pdf_t *pdf, double lw);
+
+/** Create image XObject.
+ @param pdf PDF writer structure.
+ @param bif Image, the current frame will be added.
+ @param opt Conversion options.
+ @param pc Communication object.
+ @param min Minimum progress bar value (0-1000).
+ @param max Maximum progress bar value (0-1000).
+ @return Pointer to new object on success, NULL on error.
+*/
+dk3_pdf_xobject_t *
+dk3pdf_create_ixobject_progress(
+ dk3_pdf_t *pdf,
+ dk3_bif_t *bif,
+ dk3_bm_eps_options_t *opt,
+ void *pc,
+ int min,
+ int max
+);
+
+/** Write debug line to graphics contents stream.
+ @param pdf PDF output structure.
+ @param txt Text to write.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pdf_write_debug_line(dk3_pdf_t *pdf, char const *txt);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3pixre.c b/support/dktools/dk3pixre.c
new file mode 100644
index 0000000000..75dc922d85
--- /dev/null
+++ b/support/dktools/dk3pixre.c
@@ -0,0 +1,453 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3pixre.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3pixre.c The dk3pixre module.
+*/
+
+
+#line 75 "dk3pixre.ctr"
+
+#include "dk3all.h"
+#include "dk3pixre.h"
+
+
+
+
+
+#line 82 "dk3pixre.ctr"
+
+
+
+dk3_bif_pixel_t
+dk3pixre_maximum_for_width(size_t w)
+{
+ dk3_bif_pixel_t back = 0;
+ unsigned val = 1;
+ size_t i;
+ for(i = 0; i < w; i++) {
+ val = val * 2;
+ }
+ if(val) {
+ val--;
+ back = (dk3_bif_pixel_t)val;
+#if VERSION_BEFORE_20140809
+ if (((unsigned)back) != val) {
+ back = 0;
+ }
+#else
+ if (val > (unsigned)(DK3_US_MAX)) {
+ back = 0;
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3pixre_set(dk3_pixel_resample_t *pp, size_t inw, size_t outw)
+{
+ int back = 0;
+ dk3_bif_pixel_t im;
+ dk3_bif_pixel_t om;
+
+ if (pp) {
+ im = dk3pixre_maximum_for_width(inw);
+ om = dk3pixre_maximum_for_width(outw);
+ if ((im) && (om)) {
+ pp->iw = inw;
+ pp->ow = outw;
+ pp->im = im;
+ pp->om = om;
+ pp->im2 = im / 2;
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+#if DK3_SIZEOF_INT >= (2 * DK3_SIZEOF_BIF_PIXEL_T)
+
+/* BEGIN unsigned */
+
+dk3_bif_pixel_t
+dk3pixre_convert(dk3_pixel_resample_t const *pp, dk3_bif_pixel_t inval)
+{
+ unsigned counter;
+ unsigned res;
+ unsigned rem;
+ int ec = 0;
+ dk3_bif_pixel_t back;
+ back = inval;
+ if (pp) {
+ if (pp->iw != pp->ow) {
+ if (1 < pp->ow) {
+ counter = dk3ma_ui_mul_ok(
+ (unsigned)inval,
+ (unsigned)(pp->om),
+ &ec
+ );
+ if (0 == ec) {
+ if (pp->im) {
+ res = counter / (unsigned)(pp->im);
+ rem = counter % (unsigned)(pp->im);
+ if (rem > ((unsigned)(pp->im2))) { res++; }
+ back = (dk3_bif_pixel_t)res;
+#if VERSION_BEFORE_20140809
+ if (((unsigned)back) != res) {
+ back = 0;
+ }
+#else
+ if (res > (unsigned)(DK3_US_MAX)) {
+ back = 0;
+ }
+#endif
+ }
+ }
+ } else {
+ back = ((inval > pp->im2) ? 1 : 0);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3pixre_can_convert(dk3_pixel_resample_t const *pp, dk3_bif_pixel_t inval)
+{
+ unsigned counter;
+ unsigned rem;
+ unsigned res;
+ int ec = 0;
+ int back = 0;
+#if VERSION_BEFORE_20140809
+ dk3_bif_pixel_t tv;
+#endif
+ if (pp) {
+ if (pp->iw != pp->ow) {
+ if (1 < pp->ow) {
+ counter = dk3ma_ui_mul_ok(
+ (unsigned)inval,
+ (unsigned)(pp->om),
+ &ec
+ );
+ if (0 == ec) {
+ if (pp->im) {
+ res = counter / (unsigned)(pp->im);
+ rem = counter % (unsigned)(pp->im);
+ if (0 == rem) {
+#if VERSION_BEFORE_20140809
+ tv = (dk3_bif_pixel_t)res;
+ if (((unsigned)tv) == res) {
+ back = 1;
+ }
+#else
+ if (res <= (unsigned)(DK3_US_MAX)) {
+ back = 1;
+ }
+#endif
+ }
+ }
+ }
+ } else {
+ if ((0 == inval) || (pp->im == inval)) { back = 1; }
+ }
+ } else {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+/* END unsigned */
+
+#else
+#if DK3_SIZEOF_LONG >= (2 * DK3_SIZEOF_BIF_PIXEL_T)
+
+/* BEGIN unsigned long */
+
+dk3_bif_pixel_t
+dk3pixre_convert(dk3_pixel_resample_t const *pp, dk3_bif_pixel_t inval)
+{
+ unsigned long counter;
+ unsigned long res;
+ unsigned long rem;
+ int ec = 0;
+ dk3_bif_pixel_t back;
+ back = inval;
+ if (pp) {
+ if (pp->iw != pp->ow) {
+ counter = dk3ma_ul_mul_ok(
+ (unsigned long)inval,
+ (unsigned long)(pp->om),
+ &ec
+ );
+ if (0 == ec) {
+ if (pp->im) {
+ res = counter / (unsigned long)(pp->im);
+ rem = counter % (unsigned long)(pp->im);
+ if (rem > (((unsigned long)(pp->im)) / 2UL)) { res++; }
+ back = (dk3_bif_pixel_t)res;
+#if VERSION_BEFORE_20140809
+ if (((unsigned long)back) != res) {
+ back = 0;
+ }
+#else
+ if (res > (unsigned long)(DK3_US_MAX)) {
+ back = 0;
+ }
+#endif
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3pixre_can_convert(dk3_pixel_resample_t const *pp, dk3_bif_pixel_t inval)
+{
+ unsigned long counter;
+ unsigned long rem;
+ unsigned long res;
+ int ec = 0;
+ int back = 0;
+#if VERSION_BEFORE_20140809
+ dk3_bif_pixel_t tv;
+#endif
+ if (pp) {
+ if (pp->iw != pp->ow) {
+ counter = dk3ma_ul_mul_ok(
+ (unsigned long)inval,
+ (unsigned long)(pp->om),
+ &ec
+ );
+ if (0 == ec) {
+ if (pp->im) {
+ res = counter / (unsigned long)(pp->im);
+ rem = counter % (unsigned long)(pp->im);
+ if (0 == rem) {
+#if VERSION_BEFORE_20140809
+ tv = (dk3_bif_pixel_t)res;
+ if (((unsigned long)tv) == res) {
+ back = 1;
+ }
+#else
+ if (res <= (unsigned long)(DK3_US_MAX)) {
+ back = 1;
+ }
+#endif
+ }
+ }
+ }
+ } else {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+/* END unsigned long */
+
+#else
+
+/* BEGIN dk3_um_t */
+
+dk3_bif_pixel_t
+dk3pixre_convert(dk3_pixel_resample_t const *pp, dk3_bif_pixel_t inval)
+{
+ dk3_um_t counter;
+ dk3_um_t res;
+ dk3_um_t rem;
+ int ec = 0;
+ dk3_bif_pixel_t back;
+ back = inval;
+ if (pp) {
+ if (pp->iw != pp->ow) {
+ counter = dk3ma_um_mul_ok(
+ (dk3_um_t)inval,
+ (dk3_um_t)(pp->om),
+ &ec
+ );
+ if (0 == ec) {
+ if (pp->im) {
+ res = counter / (dk3_um_t)(pp->im);
+ rem = counter % (dk3_um_t)(pp->im);
+ if (rem > (((dk3_um_t)(pp->im)) / DK3_UM_2)) { res++; }
+ back = (dk3_bif_pixel_t)res;
+ if (((dk3_um_t)back) != res) {
+ back = 0;
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3pixre_can_convert(dk3_pixel_resample_t const *pp, dk3_bif_pixel_t inval)
+{
+ dk3_um_t counter;
+ dk3_um_t rem;
+ dk3_um_t res;
+ int ec = 0;
+ int back = 0;
+ dk3_bif_pixel_t tv;
+ if (pp) {
+ if (pp->iw != pp->ow) {
+ counter = dk3ma_um_mul_ok(
+ (dk3_um_t)inval,
+ (dk3_um_t)(pp->om),
+ &ec
+ );
+ if (0 == ec) {
+ if (pp->im) {
+ res = counter / (dk3_um_t)(pp->im);
+ rem = counter % (dk3_um_t)(pp->im);
+ if (0 == rem) {
+ tv = (dk3_bif_pixel_t)res;
+ if (((dk3_um_t)tv) == res) {
+ back = 1;
+ }
+ }
+ }
+ }
+ } else {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+/* END dk3_um_t */
+
+#endif
+#endif
+
+
+dk3_bif_pixel_t
+dk3pixre_get_value_from_packed_bytes(
+ unsigned char const *row,
+ dk3_bif_coord_t vi,
+ size_t bpc
+)
+{
+ unsigned short const *us;
+ unsigned char uc;
+ dk3_bif_coord_t byteindex;
+ dk3_bif_coord_t inbyte;
+
+ dk3_bif_pixel_t back = (dk3_bif_pixel_t)0;
+ switch(bpc) {
+ case 16: {
+ us = (unsigned short const *)row;
+ back = us[vi];
+ } break;
+ case 8: {
+ back = (dk3_bif_pixel_t)(row[vi]);
+ back &= 0x00FFU;
+ } break;
+ case 4: {
+ byteindex = vi / 2L;
+ inbyte = vi % 2L;
+ uc = row[byteindex];
+ switch((int)inbyte) {
+ case 0: {
+ uc = uc >> 4;
+ } break;
+ }
+ back = (dk3_bif_pixel_t)uc;
+ back &= 0x000FU;
+ } break;
+ case 2: {
+ byteindex = vi / 4L;
+ inbyte = vi % 4L;
+ uc = row[byteindex];
+ switch((int)inbyte) {
+ case 0: {
+ uc = uc >> 6;
+ } break;
+ case 1: {
+ uc = uc >> 4;
+ } break;
+ case 2: {
+ uc = uc >> 2;
+ } break;
+ }
+ back = (dk3_bif_pixel_t)uc;
+ back &= 0x0003U;
+ } break;
+ case 1: {
+ byteindex = vi / 8L;
+ inbyte = vi % 8L;
+ uc = row[byteindex];
+ switch((int)inbyte) {
+ case 0: { uc = uc >> 7; } break;
+ case 1: { uc = uc >> 6; } break;
+ case 2: { uc = uc >> 5; } break;
+ case 3: { uc = uc >> 4; } break;
+ case 4: { uc = uc >> 3; } break;
+ case 5: { uc = uc >> 2; } break;
+ case 6: { uc = uc >> 1; } break;
+ }
+ back = (dk3_bif_pixel_t)uc;
+ back &= 0x0001U;
+ } break;
+ }
+ return back;
+}
+
+
+
+dk3_bif_pixel_t
+dk3pixre_get_max_value(dk3_pixel_resample_t const *pp)
+{
+ dk3_bif_pixel_t back = (dk3_bif_pixel_t)0U;
+ if(pp) {
+ back = pp->om;
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk3pixre.ctr b/support/dktools/dk3pixre.ctr
new file mode 100644
index 0000000000..d5fb73866e
--- /dev/null
+++ b/support/dktools/dk3pixre.ctr
@@ -0,0 +1,485 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Set up resampling structure.
+ This function must be called before you start
+ any conversion using dk3pixre_convert().
+ @param pp Resampling structure.
+ @param inw Input number of bits per component.
+ @param outw Output number of bits per component.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pixre_set(dk3_pixel_resample_t *pp, size_t inw, size_t outw);
+
+/** Check whether a pixel value can be converted without quality loss.
+ @param pp Pixel resampling structure.
+ @param inval Value to convert.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pixre_can_convert(dk3_pixel_resample_t const *pp, dk3_bif_pixel_t inval);
+
+/** Resample pixel. The dk3_pixel_resample_t structure must
+ already be set up using dk3pixre_set().
+ @param pp Resampling structure.
+ @param inval Value to resample.
+ @return Pixel component resampled.
+*/
+dk3_bif_pixel_t
+dk3pixre_convert(dk3_pixel_resample_t const *pp, dk3_bif_pixel_t inval);
+
+/** Get mask for maximum output value.
+ @param pp Resampling structure.
+ @return Maximum value for given number of output bits.
+*/
+dk3_bif_pixel_t
+dk3pixre_get_max_value(dk3_pixel_resample_t const *pp);
+
+/** Get one pixel component value from packed bytes.
+ @param row Pixel data.
+ @param vi Value index.
+ @param bpc Number of bits per component.
+ @return Pixel component value.
+*/
+dk3_bif_pixel_t
+dk3pixre_get_value_from_packed_bytes(
+ unsigned char const *row,
+ dk3_bif_coord_t vi,
+ size_t bpc
+);
+
+/** Get maximum pixel value for a given bit width.
+ @param w Bit width.
+ @return Maximum value on success, 0 on error.
+*/
+dk3_bif_pixel_t
+dk3pixre_maximum_for_width(size_t w);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk3all.h"
+#include "dk3pixre.h"
+
+
+
+$!trace-include
+
+
+
+dk3_bif_pixel_t
+dk3pixre_maximum_for_width(size_t w)
+{
+ dk3_bif_pixel_t back = 0;
+ unsigned val = 1;
+ size_t i;
+ for(i = 0; i < w; i++) {
+ val = val * 2;
+ }
+ if(val) {
+ val--;
+ back = (dk3_bif_pixel_t)val;
+#if VERSION_BEFORE_20140809
+ if (((unsigned)back) != val) {
+ back = 0;
+ }
+#else
+ if (val > (unsigned)(DK3_US_MAX)) {
+ back = 0;
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3pixre_set(dk3_pixel_resample_t *pp, size_t inw, size_t outw)
+{
+ int back = 0;
+ dk3_bif_pixel_t im;
+ dk3_bif_pixel_t om;
+
+ if (pp) {
+ im = dk3pixre_maximum_for_width(inw);
+ om = dk3pixre_maximum_for_width(outw);
+ if ((im) && (om)) {
+ pp->iw = inw;
+ pp->ow = outw;
+ pp->im = im;
+ pp->om = om;
+ pp->im2 = im / 2;
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+#if DK3_SIZEOF_INT >= (2 * DK3_SIZEOF_BIF_PIXEL_T)
+
+/* BEGIN unsigned */
+
+dk3_bif_pixel_t
+dk3pixre_convert(dk3_pixel_resample_t const *pp, dk3_bif_pixel_t inval)
+{
+ unsigned counter;
+ unsigned res;
+ unsigned rem;
+ int ec = 0;
+ dk3_bif_pixel_t back;
+ back = inval;
+ if (pp) {
+ if (pp->iw != pp->ow) {
+ if (1 < pp->ow) {
+ counter = dk3ma_ui_mul_ok(
+ (unsigned)inval,
+ (unsigned)(pp->om),
+ &ec
+ );
+ if (0 == ec) {
+ if (pp->im) {
+ res = counter / (unsigned)(pp->im);
+ rem = counter % (unsigned)(pp->im);
+ if (rem > ((unsigned)(pp->im2))) { res++; }
+ back = (dk3_bif_pixel_t)res;
+#if VERSION_BEFORE_20140809
+ if (((unsigned)back) != res) {
+ back = 0;
+ }
+#else
+ if (res > (unsigned)(DK3_US_MAX)) {
+ back = 0;
+ }
+#endif
+ }
+ }
+ } else {
+ back = ((inval > pp->im2) ? 1 : 0);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3pixre_can_convert(dk3_pixel_resample_t const *pp, dk3_bif_pixel_t inval)
+{
+ unsigned counter;
+ unsigned rem;
+ unsigned res;
+ int ec = 0;
+ int back = 0;
+#if VERSION_BEFORE_20140809
+ dk3_bif_pixel_t tv;
+#endif
+ if (pp) {
+ if (pp->iw != pp->ow) {
+ if (1 < pp->ow) {
+ counter = dk3ma_ui_mul_ok(
+ (unsigned)inval,
+ (unsigned)(pp->om),
+ &ec
+ );
+ if (0 == ec) {
+ if (pp->im) {
+ res = counter / (unsigned)(pp->im);
+ rem = counter % (unsigned)(pp->im);
+ if (0 == rem) {
+#if VERSION_BEFORE_20140809
+ tv = (dk3_bif_pixel_t)res;
+ if (((unsigned)tv) == res) {
+ back = 1;
+ }
+#else
+ if (res <= (unsigned)(DK3_US_MAX)) {
+ back = 1;
+ }
+#endif
+ }
+ }
+ }
+ } else {
+ if ((0 == inval) || (pp->im == inval)) { back = 1; }
+ }
+ } else {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+/* END unsigned */
+
+#else
+#if DK3_SIZEOF_LONG >= (2 * DK3_SIZEOF_BIF_PIXEL_T)
+
+/* BEGIN unsigned long */
+
+dk3_bif_pixel_t
+dk3pixre_convert(dk3_pixel_resample_t const *pp, dk3_bif_pixel_t inval)
+{
+ unsigned long counter;
+ unsigned long res;
+ unsigned long rem;
+ int ec = 0;
+ dk3_bif_pixel_t back;
+ back = inval;
+ if (pp) {
+ if (pp->iw != pp->ow) {
+ counter = dk3ma_ul_mul_ok(
+ (unsigned long)inval,
+ (unsigned long)(pp->om),
+ &ec
+ );
+ if (0 == ec) {
+ if (pp->im) {
+ res = counter / (unsigned long)(pp->im);
+ rem = counter % (unsigned long)(pp->im);
+ if (rem > (((unsigned long)(pp->im)) / 2UL)) { res++; }
+ back = (dk3_bif_pixel_t)res;
+#if VERSION_BEFORE_20140809
+ if (((unsigned long)back) != res) {
+ back = 0;
+ }
+#else
+ if (res > (unsigned long)(DK3_US_MAX)) {
+ back = 0;
+ }
+#endif
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3pixre_can_convert(dk3_pixel_resample_t const *pp, dk3_bif_pixel_t inval)
+{
+ unsigned long counter;
+ unsigned long rem;
+ unsigned long res;
+ int ec = 0;
+ int back = 0;
+#if VERSION_BEFORE_20140809
+ dk3_bif_pixel_t tv;
+#endif
+ if (pp) {
+ if (pp->iw != pp->ow) {
+ counter = dk3ma_ul_mul_ok(
+ (unsigned long)inval,
+ (unsigned long)(pp->om),
+ &ec
+ );
+ if (0 == ec) {
+ if (pp->im) {
+ res = counter / (unsigned long)(pp->im);
+ rem = counter % (unsigned long)(pp->im);
+ if (0 == rem) {
+#if VERSION_BEFORE_20140809
+ tv = (dk3_bif_pixel_t)res;
+ if (((unsigned long)tv) == res) {
+ back = 1;
+ }
+#else
+ if (res <= (unsigned long)(DK3_US_MAX)) {
+ back = 1;
+ }
+#endif
+ }
+ }
+ }
+ } else {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+/* END unsigned long */
+
+#else
+
+/* BEGIN dk3_um_t */
+
+dk3_bif_pixel_t
+dk3pixre_convert(dk3_pixel_resample_t const *pp, dk3_bif_pixel_t inval)
+{
+ dk3_um_t counter;
+ dk3_um_t res;
+ dk3_um_t rem;
+ int ec = 0;
+ dk3_bif_pixel_t back;
+ back = inval;
+ if (pp) {
+ if (pp->iw != pp->ow) {
+ counter = dk3ma_um_mul_ok(
+ (dk3_um_t)inval,
+ (dk3_um_t)(pp->om),
+ &ec
+ );
+ if (0 == ec) {
+ if (pp->im) {
+ res = counter / (dk3_um_t)(pp->im);
+ rem = counter % (dk3_um_t)(pp->im);
+ if (rem > (((dk3_um_t)(pp->im)) / DK3_UM_2)) { res++; }
+ back = (dk3_bif_pixel_t)res;
+ if (((dk3_um_t)back) != res) {
+ back = 0;
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3pixre_can_convert(dk3_pixel_resample_t const *pp, dk3_bif_pixel_t inval)
+{
+ dk3_um_t counter;
+ dk3_um_t rem;
+ dk3_um_t res;
+ int ec = 0;
+ int back = 0;
+ dk3_bif_pixel_t tv;
+ if (pp) {
+ if (pp->iw != pp->ow) {
+ counter = dk3ma_um_mul_ok(
+ (dk3_um_t)inval,
+ (dk3_um_t)(pp->om),
+ &ec
+ );
+ if (0 == ec) {
+ if (pp->im) {
+ res = counter / (dk3_um_t)(pp->im);
+ rem = counter % (dk3_um_t)(pp->im);
+ if (0 == rem) {
+ tv = (dk3_bif_pixel_t)res;
+ if (((dk3_um_t)tv) == res) {
+ back = 1;
+ }
+ }
+ }
+ }
+ } else {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+/* END dk3_um_t */
+
+#endif
+#endif
+
+
+dk3_bif_pixel_t
+dk3pixre_get_value_from_packed_bytes(
+ unsigned char const *row,
+ dk3_bif_coord_t vi,
+ size_t bpc
+)
+{
+ unsigned short const *us;
+ unsigned char uc;
+ dk3_bif_coord_t byteindex;
+ dk3_bif_coord_t inbyte;
+
+ dk3_bif_pixel_t back = (dk3_bif_pixel_t)0;
+ switch(bpc) {
+ case 16: {
+ us = (unsigned short const *)row;
+ back = us[vi];
+ } break;
+ case 8: {
+ back = (dk3_bif_pixel_t)(row[vi]);
+ back &= 0x00FFU;
+ } break;
+ case 4: {
+ byteindex = vi / 2L;
+ inbyte = vi % 2L;
+ uc = row[byteindex];
+ switch((int)inbyte) {
+ case 0: {
+ uc = uc >> 4;
+ } break;
+ }
+ back = (dk3_bif_pixel_t)uc;
+ back &= 0x000FU;
+ } break;
+ case 2: {
+ byteindex = vi / 4L;
+ inbyte = vi % 4L;
+ uc = row[byteindex];
+ switch((int)inbyte) {
+ case 0: {
+ uc = uc >> 6;
+ } break;
+ case 1: {
+ uc = uc >> 4;
+ } break;
+ case 2: {
+ uc = uc >> 2;
+ } break;
+ }
+ back = (dk3_bif_pixel_t)uc;
+ back &= 0x0003U;
+ } break;
+ case 1: {
+ byteindex = vi / 8L;
+ inbyte = vi % 8L;
+ uc = row[byteindex];
+ switch((int)inbyte) {
+ case 0: { uc = uc >> 7; } break;
+ case 1: { uc = uc >> 6; } break;
+ case 2: { uc = uc >> 5; } break;
+ case 3: { uc = uc >> 4; } break;
+ case 4: { uc = uc >> 3; } break;
+ case 5: { uc = uc >> 2; } break;
+ case 6: { uc = uc >> 1; } break;
+ }
+ back = (dk3_bif_pixel_t)uc;
+ back &= 0x0001U;
+ } break;
+ }
+ return back;
+}
+
+
+
+dk3_bif_pixel_t
+dk3pixre_get_max_value(dk3_pixel_resample_t const *pp)
+{
+ dk3_bif_pixel_t back = (dk3_bif_pixel_t)0U;
+ if(pp) {
+ back = pp->om;
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk3pixre.h b/support/dktools/dk3pixre.h
new file mode 100644
index 0000000000..695c91ded0
--- /dev/null
+++ b/support/dktools/dk3pixre.h
@@ -0,0 +1,110 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3pixre.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3pixre.h Header file for the dk3pixre module.
+*/
+
+#ifndef DK3PIXRE_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3PIXRE_H_INCLUDED 1
+
+
+#line 10 "dk3pixre.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Set up resampling structure.
+ This function must be called before you start
+ any conversion using dk3pixre_convert().
+ @param pp Resampling structure.
+ @param inw Input number of bits per component.
+ @param outw Output number of bits per component.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pixre_set(dk3_pixel_resample_t *pp, size_t inw, size_t outw);
+
+/** Check whether a pixel value can be converted without quality loss.
+ @param pp Pixel resampling structure.
+ @param inval Value to convert.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3pixre_can_convert(dk3_pixel_resample_t const *pp, dk3_bif_pixel_t inval);
+
+/** Resample pixel. The dk3_pixel_resample_t structure must
+ already be set up using dk3pixre_set().
+ @param pp Resampling structure.
+ @param inval Value to resample.
+ @return Pixel component resampled.
+*/
+dk3_bif_pixel_t
+dk3pixre_convert(dk3_pixel_resample_t const *pp, dk3_bif_pixel_t inval);
+
+/** Get mask for maximum output value.
+ @param pp Resampling structure.
+ @return Maximum value for given number of output bits.
+*/
+dk3_bif_pixel_t
+dk3pixre_get_max_value(dk3_pixel_resample_t const *pp);
+
+/** Get one pixel component value from packed bytes.
+ @param row Pixel data.
+ @param vi Value index.
+ @param bpc Number of bits per component.
+ @return Pixel component value.
+*/
+dk3_bif_pixel_t
+dk3pixre_get_value_from_packed_bytes(
+ unsigned char const *row,
+ dk3_bif_coord_t vi,
+ size_t bpc
+);
+
+/** Get maximum pixel value for a given bit width.
+ @param w Bit width.
+ @return Maximum value on success, 0 on error.
+*/
+dk3_bif_pixel_t
+dk3pixre_maximum_for_width(size_t w);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk3prcfg.c b/support/dktools/dk3prcfg.c
new file mode 100644
index 0000000000..6ae9c17cbb
--- /dev/null
+++ b/support/dktools/dk3prcfg.c
@@ -0,0 +1,2187 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3prcfg.ctr
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3prcfg.c The dk3prcfg module.
+*/
+
+
+#line 25 "dk3prcfg.ctr"
+
+
+#include "dk3all.h"
+#include "dk3print.h"
+#include "dk3prcfg.h"
+
+
+
+
+
+#line 34 "dk3prcfg.ctr"
+
+
+
+/** Print configuration file processor.
+*/
+typedef struct {
+ dk3_print_conf_t *pc; /**< Print configuration to set up. */
+ dk3_printer_t *pr; /**< Current printer to modify. */
+ dk3_print_host_t *ho; /**< Current host to modify. */
+} dk3_print_config_processor_t;
+
+
+
+/** Keywords used by the module, not localized.
+*/
+static dkChar const * const dk3prcfg_nl[] = {
+/* 0 */
+dkT("dk3print.conf"),
+
+/* 1 */
+dkT("%u"),
+
+/* 2 */
+dkT("%d"),
+
+/* 3 */
+dkT("%lf"),
+
+NULL
+
+
+#line 68 "dk3prcfg.ctr"
+};
+
+
+
+/** SNMP versions.
+*/
+static dkChar const * const dk3prcfg_snmp_versions[] = {
+/* 0 */
+dkT("1"),
+
+/* 1 */
+dkT("2c"),
+
+/* 2 */
+dkT("2p"),
+
+/* 3 */
+dkT("3"),
+
+NULL
+
+
+#line 81 "dk3prcfg.ctr"
+};
+
+
+
+/** Keywords for section start.
+*/
+static dkChar const * const dk3prcfg_host_or_printer[] = {
+/* 0 */
+dkT("host"),
+
+/* 1 */
+dkT("printer"),
+
+NULL
+
+
+#line 92 "dk3prcfg.ctr"
+};
+
+
+
+/** Keywords for printer configuration lines.
+*/
+static dkChar const * const dk3prcfg_printer_keywords[] = {
+/* 0 */
+dkT("alias"),
+
+/* 1 */
+dkT("type"),
+
+/* 2 */
+dkT("host"),
+
+/* 3 */
+dkT("queue"),
+
+/* 4 */
+dkT("port"),
+
+/* 5 */
+dkT("ps"),
+
+/* 6 */
+dkT("ps level"),
+
+/* 7 */
+dkT("default"),
+
+/* 8 */
+dkT("snmp host"),
+
+/* 9 */
+dkT("snmp community"),
+
+/* 10 */
+dkT("snmp version"),
+
+/* 11 */
+dkT("connect timeout"),
+
+/* 12 */
+dkT("send timeout"),
+
+/* 13 */
+dkT("receive timeout"),
+
+/* 14 */
+dkT("orderly release"),
+
+NULL
+
+
+#line 161 "dk3prcfg.ctr"
+};
+
+
+
+/** Keywords to configure print hosts.
+*/
+static dkChar const * const dk3prcfg_host_keywords[] = {
+/* 0 */
+dkT("alias"),
+
+/* 1 */
+dkT("encoding"),
+
+/* 2 */
+dkT("connect timeout"),
+
+/* 3 */
+dkT("send timeout"),
+
+/* 4 */
+dkT("receive timeout"),
+
+/* 5 */
+dkT("default"),
+
+NULL
+
+
+#line 194 "dk3prcfg.ctr"
+};
+
+
+
+/** Print queues host types.
+*/
+static dkChar const * const dk3print_queue_types[] = {
+/* 0 */
+dkT("socket"),
+
+/* 1 */
+dkT("lpd"),
+
+/* 2 */
+dkT("lprng"),
+
+NULL
+
+
+#line 206 "dk3prcfg.ctr"
+};
+
+
+
+/** Initialize a print configuration processor.
+ @param pr Processor to initialize.
+ @param pc Print configuration to set up.
+*/
+static
+void
+dk3print_initialize_print_config_processor(
+ dk3_print_config_processor_t *pr,
+ dk3_print_conf_t *pc
+)
+{
+ pr->pc = pc;
+ pr->pr = NULL;
+ pr->ho = NULL;
+}
+
+
+
+/** Process configuration line to process current printer or host.
+ @param proc Configuration processor.
+ @param pc Print configuration to set up.
+ @param il Input line to process.
+ @return 1 on succuess, 0 on recoverable errors, -1 on
+ unrecoverable errors.
+*/
+static
+int
+dk3print_lh_printer_or_host(
+ dk3_print_config_processor_t *proc,
+ dk3_print_conf_t *pc,
+ dkChar *il
+)
+{
+ dkChar *p1; /* Start of value. */
+ dkChar *p2; /* Finalizing square bracket. */
+ dkChar *p3; /* Start of input line. */
+ int back = 0;
+
+
+#line 248 "dk3prcfg.ctr"
+ p3 = il;
+ p3++;
+ p3 = dk3str_start(p3, NULL);
+ if(p3) {
+ p1 = dk3str_next(p3, NULL);
+ if(p1) {
+
+#line 254 "dk3prcfg.ctr"
+ p2 = dk3str_chr(p1, dkT(']'));
+ if(p2) { *p2 = dkT('\0'); }
+ else {
+
+#line 257 "dk3prcfg.ctr"
+ /* WARNING: Missing closing bracket! */
+ dk3app_log_1(pc->app, DK3_LL_WARNING, pc->msg, 27);
+ }
+ switch(dk3str_array_index(dk3prcfg_host_or_printer, p3, 0)) {
+ case 1: {
+
+#line 262 "dk3prcfg.ctr"
+ proc->pr = dk3print_printer_new(pc, p1);
+ if(proc->pr) {
+ back = 1;
+ } else {
+ back = -1;
+ }
+ } break;
+ case 0: {
+
+#line 270 "dk3prcfg.ctr"
+ proc->ho = dk3print_host_new(pc, p1);
+ if(proc->ho) {
+ back = 1;
+ } else {
+ back = -1;
+ }
+ } break;
+ default: {
+
+#line 278 "dk3prcfg.ctr"
+ /* ERROR: Not "host" or "printer"! */
+ dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 28, 29, p3);
+ } break;
+ }
+ } else {
+
+#line 283 "dk3prcfg.ctr"
+ /* ERROR: Printer or host name is missing! */
+ dk3app_log_1(pc->app, DK3_LL_ERROR, pc->msg, 30);
+ }
+ }
+
+
+#line 288 "dk3prcfg.ctr"
+ return back;
+}
+
+
+
+/** Create a printer alias.
+ @param pc Print configuration to set up.
+ @param pr Current printer.
+ @param vptr Alias name.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable error.
+*/
+static
+int
+dk3print_lh_pr_alias(
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ dkChar const *vptr
+)
+{
+ dk3_printer_alias_t *al; /* Alias already found. */
+ int back = -1;
+
+
+#line 310 "dk3prcfg.ctr"
+ if(vptr) {
+ if(dk3sto_it_find_like(pc->iPrinters, (void *)vptr, 1)) {
+ /* ERROR: Printer name already exists! */
+ dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 31, 32, vptr);
+ } else {
+ if(dk3sto_it_find_like(pc->iPrintAliases, (void *)vptr, 1)) {
+ /* ERROR: Alias name already exists! */
+ dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 33, 34, vptr);
+ } else {
+ al = dk3_new_app(dk3_printer_alias_t,1,pc->app);
+ if(al) {
+ al->printer = pr;
+ al->name = dk3str_dup_app(vptr, pc->app);
+ if(al->name) {
+ if(dk3sto_add(pc->sPrintAliases, (void *)al)) {
+ back = 1;
+ } else {
+ dk3print_alias_delete(al);
+ }
+ } else {
+ dk3print_alias_delete(al);
+ }
+ }
+ }
+ }
+ } else {
+ /* ERROR: Argument required! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
+ dk3prcfg_printer_keywords[0]
+ );
+ }
+
+#line 342 "dk3prcfg.ctr"
+ return back;
+}
+
+
+
+/** Set print queue type.
+ @param pc Print configuration to set up.
+ @param pr Current printer.
+ @param pqt New print queue type.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable errors.
+*/
+static
+int
+dk3print_lh_pr_set_pqt(
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ int pqt
+)
+{
+ int back = -1;
+
+
+#line 363 "dk3prcfg.ctr"
+ switch(pr->t_p) {
+ case DK3_PRINTER_TYPE_NONE: {
+ pr->t_p = pqt;
+ dk3print_set_det(&(pr->det_p), pqt);
+ back = 1;
+ } break;
+ case DK3_PRINTER_TYPE_WINDOWS: {
+ switch(pr->t_s) {
+ case DK3_PRINTER_TYPE_NONE: {
+ pr->t_s = pqt;
+ dk3print_set_det(&(pr->det_s), pqt);
+ back = 1;
+ } break;
+ default: {
+ /* ERROR: Queue type already set up! */
+ dk3app_log_1(pc->app, DK3_LL_ERROR, pc->msg, 37);
+ } break;
+ }
+ } break;
+ default: {
+ /* ERROR: Queue type already set up! */
+ dk3app_log_1(pc->app, DK3_LL_ERROR, pc->msg, 37);
+ } break;
+ }
+
+#line 387 "dk3prcfg.ctr"
+ return back;
+}
+
+
+
+/** Set printer type.
+ @param pc Print configuration to set up.
+ @param pr Current printer.
+ @param vptr New value.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable error.
+*/
+static
+int
+dk3print_lh_pr_type(
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ dkChar const *vptr
+)
+{
+ int pqt; /* Print queue type. */
+ int back = -1;
+
+
+#line 409 "dk3prcfg.ctr"
+ if(vptr) {
+ pqt = dk3str_array_index(dk3print_queue_types, vptr, 0);
+ if(-1 < pqt) {
+ pqt = 2 + pqt;
+ back = dk3print_lh_pr_set_pqt(pc, pr, pqt);
+ } else {
+ /* ERROR: Unknown print queue type! */
+ dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 38, 39, vptr);
+ }
+ } else {
+ /* ERRROR: Argument required! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
+ dk3prcfg_printer_keywords[1]
+ );
+ }
+
+#line 425 "dk3prcfg.ctr"
+ return back;
+}
+
+
+
+/** Process line containing host details.
+ @param pc Print configuration to modify.
+ @param det Current details structure to modify.
+ @param tp Current printer type.
+ @param name Text to apply.
+ @return 1 on success, 0 on errors.
+*/
+static
+int
+dk3print_lh_pr_det_host(
+ dk3_print_conf_t *pc,
+ dk3_printer_details_t *det,
+ int tp,
+ dkChar const *name
+)
+{
+ int back = -1;
+
+
+#line 448 "dk3prcfg.ctr"
+ switch(tp) {
+ case DK3_PRINTER_TYPE_SOCKET: {
+ if((det->sock).hostname) {
+ /* WARNING: Overwriting configured host name! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 40, 41,
+ (det->sock).hostname
+ );
+ dk3_release((det->sock).hostname);
+ }
+ (det->sock).hostname = dk3str_dup_app(name, pc->app);
+ if((det->sock).hostname) {
+ back = 1;
+ }
+ } break;
+ case DK3_PRINTER_TYPE_LPD:
+ case DK3_PRINTER_TYPE_LPRNG: {
+ if((det->lprng).hostname) {
+ /* WARNING: Overwriting configured host name! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 40, 41,
+ (det->lprng).hostname
+ );
+ dk3_release((det->lprng).hostname);
+ }
+ (det->lprng).hostname = dk3str_dup_app(name, pc->app);
+ if((det->lprng).hostname) {
+ back = 1;
+ }
+ } break;
+ }
+
+#line 479 "dk3prcfg.ctr"
+ return back;
+}
+
+
+
+/** Set printer host.
+ @param pc Print configuration to set up.
+ @param pr Current printer.
+ @param vptr New value.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable error.
+*/
+static
+int
+dk3print_lh_pr_host(
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ dkChar const *vptr
+)
+{
+ int back = -1;
+
+
+#line 500 "dk3prcfg.ctr"
+ if(vptr) {
+ switch(pr->t_p) {
+ case DK3_PRINTER_TYPE_WINDOWS: {
+ switch(pr->t_s) {
+ case DK3_PRINTER_TYPE_SOCKET:
+ case DK3_PRINTER_TYPE_LPD:
+ case DK3_PRINTER_TYPE_LPRNG: {
+ back = dk3print_lh_pr_det_host(pc, &(pr->det_s), pr->t_s, vptr);
+ } break;
+ default: {
+ /* ERROR: Option not available for this printer type! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
+ dk3prcfg_printer_keywords[2]
+ );
+ } break;
+ }
+ } break;
+ case DK3_PRINTER_TYPE_SOCKET:
+ case DK3_PRINTER_TYPE_LPD:
+ case DK3_PRINTER_TYPE_LPRNG: {
+ back = dk3print_lh_pr_det_host(pc, &(pr->det_p), pr->t_p, vptr);
+ } break;
+ default: {
+ /* ERROR: Option not available for this printer type! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
+ dk3prcfg_printer_keywords[2]
+ );
+ } break;
+ }
+ } else {
+ /* ERROR: Argument required! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
+ dk3prcfg_printer_keywords[2]
+ );
+ }
+
+
+#line 539 "dk3prcfg.ctr"
+ return back;
+}
+
+
+
+/** Set print queue entry for current printer.
+ @param pc Print configuration to modify.
+ @param det Details structure for current printer.
+ @param tp Current printer type.
+ @param name Configuration text to apply.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3print_lh_pr_set_queue(
+ dk3_print_conf_t *pc,
+ dk3_printer_details_t *det,
+ int tp,
+ dkChar const *name
+)
+{
+ int back = -1;
+
+
+#line 562 "dk3prcfg.ctr"
+ switch(tp) {
+ case DK3_PRINTER_TYPE_LPD:
+ case DK3_PRINTER_TYPE_LPRNG: {
+ if((det->lprng).queuename) {
+ /* WARNING: Overriding queue name! */
+ dk3app_log_3(
+ pc->app, DK3_LL_WARNING, pc->msg, 44, 45,
+ (det->lprng).queuename
+ );
+ dk3_release((det->lprng).queuename);
+ }
+ (det->lprng).queuename = dk3str_dup_app(name, pc->app);
+ if((det->lprng).queuename) {
+ back = 1;
+ }
+ } break;
+ }
+
+#line 579 "dk3prcfg.ctr"
+ return back;
+}
+
+
+
+/** Set printer queue.
+ @param pc Print configuration to set up.
+ @param pr Current printer.
+ @param vptr New value.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable error.
+*/
+static
+int
+dk3print_lh_pr_queue(
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ dkChar const *vptr
+)
+{
+ int back = -1;
+
+
+#line 600 "dk3prcfg.ctr"
+ if(vptr) {
+ switch(pr->t_p) {
+ case DK3_PRINTER_TYPE_WINDOWS: {
+ switch(pr->t_s) {
+ case DK3_PRINTER_TYPE_LPD:
+ case DK3_PRINTER_TYPE_LPRNG: {
+ back = dk3print_lh_pr_set_queue(pc, &(pr->det_s), pr->t_s, vptr);
+ } break;
+ default: {
+ /* ERROR: Option not available for printer type! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
+ dk3prcfg_printer_keywords[3]
+ );
+ } break;
+ }
+ } break;
+ case DK3_PRINTER_TYPE_LPD:
+ case DK3_PRINTER_TYPE_LPRNG: {
+ back = dk3print_lh_pr_set_queue(pc, &(pr->det_p), pr->t_p, vptr);
+ } break;
+ default: {
+ /* ERROR: Option not available for printer type! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
+ dk3prcfg_printer_keywords[3]
+ );
+ } break;
+ }
+ } else {
+ /* ERROR: Argument required! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
+ dk3prcfg_printer_keywords[3]
+ );
+ }
+
+#line 636 "dk3prcfg.ctr"
+ return back;
+}
+
+
+
+/** Set port number for current printer.
+ @param pc Print configuration to modify.
+ @param det Details structure for current printer.
+ @param tp Current printer type.
+ @param name Configuration text to apply.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3print_lh_pr_set_port(
+ dk3_print_conf_t *pc,
+ dk3_printer_details_t *det,
+ int tp,
+ dkChar const *name
+)
+{
+ dkChar buf[64]; /* Used to show existing port no. */
+ int back = -1;
+ int conr = 0; /* Result from conversion. */
+ unsigned u; /* Temporary conversion result. */
+ unsigned short us; /* New port number. */
+
+
+#line 663 "dk3prcfg.ctr"
+ switch(tp) {
+ case DK3_PRINTER_TYPE_SOCKET: {
+
+#line 665 "dk3prcfg.ctr"
+ if((det->sock).portno) {
+ /* Warning: Overriding port number! */
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(buf,dkT("%u"),(unsigned)((det->sock).portno));
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 46, 47, buf);
+#else
+ conr = dk3ma_um_to_string(
+ buf, DK3_SIZEOF(buf,dkChar),
+ (dk3_um_t)((det->sock).portno)
+ );
+ if (0 != conr) {
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 46, 47, buf);
+ }
+#endif
+ }
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(name, dk3prcfg_nl[1], &u))
+#else
+ if (0 != dk3ma_ui_from_string(&u, name, NULL))
+#endif
+ {
+ us = (unsigned short)u;
+#if VERSION_BEFORE_20140809
+ if(u == (unsigned)us)
+#else
+ if (u <= (unsigned)(DK3_US_MAX))
+#endif
+ {
+
+#line 693 "dk3prcfg.ctr"
+ (det->sock).portno = us;
+ back = 1;
+ } else {
+
+#line 696 "dk3prcfg.ctr"
+ /* ERROR: Numeric overflow! */
+ dk3app_log_1(pc->app, DK3_LL_ERROR, pc->msg, 48);
+ }
+ } else {
+
+#line 700 "dk3prcfg.ctr"
+ /* ERROR: Not a number! */
+ dk3app_log_i3(pc->app, DK3_LL_ERROR, 141, 142, name);
+ }
+ } break;
+ default: {
+
+#line 705 "dk3prcfg.ctr"
+ } break;
+ }
+
+#line 707 "dk3prcfg.ctr"
+ return back;
+}
+
+
+
+/** Set printer port.
+ @param pc Print configuration to set up.
+ @param pr Current printer.
+ @param vptr New value.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable error.
+*/
+static
+int
+dk3print_lh_pr_port(
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ dkChar const *vptr
+)
+{
+ int back = -1;
+
+
+#line 728 "dk3prcfg.ctr"
+ if(vptr) {
+ switch(pr->t_p) {
+ case DK3_PRINTER_TYPE_WINDOWS: {
+ switch(pr->t_s) {
+ case DK3_PRINTER_TYPE_SOCKET: {
+
+#line 733 "dk3prcfg.ctr"
+ back = dk3print_lh_pr_set_port(pc, &(pr->det_s), pr->t_s, vptr);
+ } break;
+ default: {
+ /* ERROR: Option not available for print queue type! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
+ dk3prcfg_printer_keywords[4]
+ );
+ } break;
+ }
+ } break;
+ case DK3_PRINTER_TYPE_SOCKET: {
+
+#line 745 "dk3prcfg.ctr"
+ back = dk3print_lh_pr_set_port(pc, &(pr->det_p), pr->t_p, vptr);
+ } break;
+ default: {
+ /* ERROR: Option not available for print queue type! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
+ dk3prcfg_printer_keywords[4]
+ );
+ } break;
+ }
+ } else {
+ /* ERROR: Argument required! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
+ dk3prcfg_printer_keywords[4]
+ );
+ }
+
+#line 762 "dk3prcfg.ctr"
+ return back;
+}
+
+
+
+/** Set printer PS.
+ @param pc Print configuration to set up.
+ @param pr Current printer.
+ @param vptr New value.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable error.
+*/
+static
+int
+dk3print_lh_pr_ps(
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ dkChar const *vptr
+)
+{
+ int back = -1;
+
+
+#line 783 "dk3prcfg.ctr"
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ pr->ps = ((dk3str_is_on(vptr)) ? (pc->defPsl) : (0));
+ } else {
+ /* ERROR: Not a boolean value! */
+ dk3app_log_i3(pc->app, DK3_LL_ERROR, 146, 147, vptr);
+ }
+ } else {
+ pr->ps = pc->defPsl;
+ }
+
+#line 793 "dk3prcfg.ctr"
+ return back;
+}
+
+
+
+/** Set printer PS level.
+ @param pc Print configuration to set up.
+ @param pr Current printer.
+ @param vptr New value.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable error.
+*/
+static
+int
+dk3print_lh_pr_psl(
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ dkChar const *vptr
+)
+{
+ int back = -1;
+ int i; /* Temporary conversion result. */
+
+
+#line 815 "dk3prcfg.ctr"
+ if(vptr) {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(vptr,dk3prcfg_nl[2],&i))
+#else
+ if (0 != dk3ma_i_from_string(&i, vptr, NULL))
+#endif
+ {
+ if((2 <= i) && (3 >= i)) {
+ pr->ps = i;
+ back = 1;
+ } else {
+ /* ERROR: Out of range! */
+ dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 49, 50, vptr);
+ }
+ } else {
+ /* ERROR: Not a number! */
+ dk3app_log_i3(pc->app, DK3_LL_ERROR, 141, 142, vptr);
+ }
+ } else {
+ /* ERROR: Value required! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
+ dk3prcfg_printer_keywords[6]
+ );
+ }
+
+#line 840 "dk3prcfg.ctr"
+ return back;
+}
+
+
+
+/** Set printer as default.
+ @param pc Print configuration to set up.
+ @param pr Current printer.
+ @param vptr New value.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable error.
+*/
+static
+int
+dk3print_lh_pr_default(
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ dkChar const *vptr
+)
+{
+ int back = -1;
+
+
+#line 861 "dk3prcfg.ctr"
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ if(dk3str_is_on(vptr)) {
+ pc->defPrinter = pr;
+ back = 1;
+ }
+ } else {
+ /* ERROR: Not a boolean value! */
+ dk3app_log_i3(pc->app, DK3_LL_ERROR, 146, 147, vptr);
+ }
+ } else {
+ pc->defPrinter = pr;
+ back = 1;
+ }
+
+#line 875 "dk3prcfg.ctr"
+ return back;
+}
+
+
+
+/** Set SNMP host.
+ @param pc Print configuration to set up.
+ @param pr Current printer.
+ @param vptr New value.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable error.
+*/
+static
+int
+dk3print_lh_pr_snmp_host(
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ dkChar const *vptr
+)
+{
+ int back = -1;
+
+
+#line 896 "dk3prcfg.ctr"
+ if(vptr) {
+ if(pr->h_snmp) {
+ /* WARNING: Overwriting SNMP host! */
+ dk3app_log_3(
+ pc->app, DK3_LL_WARNING, pc->msg, 51, 52,
+ pr->h_snmp
+ );
+ dk3_release(pr->h_snmp);
+ }
+ pr->h_snmp = dk3str_dup_app(vptr, pc->app);
+ if(pr->h_snmp) {
+ back = 1;
+ }
+ } else {
+ /* ERROR: Value required! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
+ dk3prcfg_printer_keywords[8]
+ );
+ }
+
+#line 916 "dk3prcfg.ctr"
+ return back;
+}
+
+
+
+/** Set SNMP community.
+ @param pc Print configuration to set up.
+ @param pr Current printer.
+ @param vptr New value.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable error.
+*/
+static
+int
+dk3print_lh_pr_snmp_community(
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ dkChar const *vptr
+)
+{
+ int back = -1;
+
+
+#line 937 "dk3prcfg.ctr"
+ if(vptr) {
+ if(pr->c_snmp) {
+ /* WARNING: Overwriting SNMP community! */
+ dk3app_log_3(
+ pc->app, DK3_LL_WARNING, pc->msg, 53, 54,
+ pr->c_snmp
+ );
+ dk3_release(pr->c_snmp);
+ }
+ pr->c_snmp = dk3str_dup_app(vptr, pc->app);
+ if(pr->c_snmp) {
+ back = 1;
+ }
+ } else {
+ /* ERROR: Value required! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
+ dk3prcfg_printer_keywords[9]
+ );
+ }
+
+#line 957 "dk3prcfg.ctr"
+ return back;
+}
+
+
+
+/** Set SNMP version.
+ @param pc Print configuration to set up.
+ @param pr Current printer.
+ @param vptr New value.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable error.
+*/
+static
+int
+dk3print_lh_pr_snmp_version(
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ dkChar const *vptr
+)
+{
+ int back = -1;
+
+
+#line 978 "dk3prcfg.ctr"
+ if(vptr) {
+ if(DK3_SNMP_VERSION_UNKNOWN != pr->v_snmp) {
+ /* Warning: Overwriting SNMP version! */
+ dk3app_log_1(pc->app, DK3_LL_WARNING, pc->msg, 55);
+ }
+ switch(dk3str_array_index(dk3prcfg_snmp_versions, vptr, 0)) {
+ case 0: {
+ pr->v_snmp = DK3_SNMP_VERSION_1; back = 1;
+ } break;
+ case 1: {
+ pr->v_snmp = DK3_SNMP_VERSION_2C; back = 1;
+ } break;
+ case 2: {
+ pr->v_snmp = DK3_SNMP_VERSION_2P; back = 1;
+ } break;
+ case 3: {
+ pr->v_snmp = DK3_SNMP_VERSION_3; back = 1;
+ } break;
+ default: {
+ /* ERROR: Unknown SNMP version! */
+ dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 56, 57, vptr);
+ } break;
+ }
+ } else {
+ /* ERROR: Value required! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
+ dk3prcfg_printer_keywords[10]
+ );
+ }
+
+#line 1008 "dk3prcfg.ctr"
+ return back;
+}
+
+
+
+/** Set timeout.
+ @param pc Print configuration to set up.
+ @param det Details for current printer.
+ @param tp Current printer type.
+ @param vptr Value text.
+ @param sel Timeout selection (0=connect, 1=send, 2=receive).
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable errors.
+*/
+static
+int
+dk3print_lh_pr_set_timeout(
+ dk3_print_conf_t *pc,
+ dk3_printer_details_t *det,
+ int tp,
+ dkChar const *vptr,
+ int sel
+)
+{
+ dkChar buf[128]; /* Buffer to show existing value. */
+ double d = -1.0; /* Temporary conversion result. */
+ int conr = 0; /* Result from conversion. */
+ int back = -1;
+
+
+#line 1036 "dk3prcfg.ctr"
+ if(vptr) {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(vptr, dk3prcfg_nl[3],&d))
+#else
+ if(0 != dk3ma_d_from_string(&d, vptr, NULL))
+#endif
+ {
+ if(d < 0.0) {
+ d = -1.0;
+ }
+ switch(tp) {
+ case DK3_PRINTER_TYPE_SOCKET: {
+ switch(sel) {
+ case 2: {
+ if((det->sock).to_r > 0.0) {
+ /* WARNING: Overwriting receive timeout! */
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(buf,dkT("%g"),(det->sock).to_r);
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 58, 59, buf);
+#else
+ conr = dk3ma_d_to_string(
+ buf, DK3_SIZEOF(buf,dkChar), (det->sock).to_r
+ );
+ if (0 != conr) {
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 58, 59, buf);
+ }
+#endif
+ }
+ (det->sock).to_r = d;
+ back = 1;
+ } break;
+ case 1: {
+ if((det->sock).to_s > 0.0) {
+ /* WARNING: Overwriting send timeout! */
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(buf,dkT("%g"),(det->sock).to_s);
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 60, 61, buf);
+#else
+ conr = dk3ma_d_to_string(
+ buf, DK3_SIZEOF(buf,dkChar), (det->sock).to_s
+ );
+ if (0 != conr) {
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 60, 61, buf);
+ }
+#endif
+ }
+ (det->sock).to_s = d;
+ back = 1;
+ } break;
+ default: {
+ if((det->sock).to_c > 0.0) {
+ /* WARNING: Overwriting connect timeout! */
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(buf,dkT("%g"),(det->sock).to_c);
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 62, 63, buf);
+#else
+ conr = dk3ma_d_to_string(
+ buf, DK3_SIZEOF(buf,dkChar), (det->sock).to_c
+ );
+ if (0 != conr) {
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 62, 63, buf);
+ }
+#endif
+ }
+ (det->sock).to_c = d;
+ back = 1;
+ } break;
+ }
+ } break;
+ case DK3_PRINTER_TYPE_LPD:
+ case DK3_PRINTER_TYPE_LPRNG: {
+ switch(sel) {
+ case 2: {
+ if((det->lprng).to_r > 0.0) {
+ /* WARNING: Overwriting receive timeout! */
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(buf,dkT("%g"),(det->lprng).to_r);
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 58, 59, buf);
+#else
+ conr = dk3ma_d_to_string(
+ buf, DK3_SIZEOF(buf,dkChar), (det->lprng).to_r
+ );
+ if (0 != conr) {
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 58, 59, buf);
+ }
+#endif
+ }
+ (det->lprng).to_r = d;
+ back = 1;
+ } break;
+ case 1: {
+ if((det->lprng).to_s > 0.0) {
+ /* WARNING: Overwriting send timeout! */
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(buf,dkT("%g"),(det->lprng).to_s);
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 60, 61, buf);
+#else
+ conr = dk3ma_d_to_string(
+ buf, DK3_SIZEOF(buf,dkChar), (det->lprng).to_s
+ );
+ if (0 != conr) {
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 60, 61, buf);
+ }
+#endif
+ }
+ (det->lprng).to_s = d;
+ back = 1;
+ } break;
+ default: {
+ if((det->lprng).to_c > 0.0) {
+ /* WARNING: Overwriting connect timeout! */
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(buf,dkT("%g"),(det->lprng).to_c);
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 62, 63, buf);
+#else
+ conr = dk3ma_d_to_string(
+ buf, DK3_SIZEOF(buf,dkChar), (det->lprng).to_c
+ );
+ if (0 != conr) {
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 62, 63, buf);
+ }
+#endif
+ }
+ (det->lprng).to_c = d;
+ back = 1;
+ } break;
+ }
+ } break;
+ }
+ } else {
+ /* ERROR: Not a number! */
+ dk3app_log_i3(pc->app, DK3_LL_ERROR, 141, 142, vptr);
+ }
+ }
+
+#line 1170 "dk3prcfg.ctr"
+ return back;
+}
+
+
+
+/** Set connect timeout.
+ @param pc Print configuration to set up.
+ @param pr Current printer.
+ @param vptr New value.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable error.
+*/
+static
+int
+dk3print_lh_pr_connect_timeout(
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ dkChar const *vptr
+)
+{
+ int back = -1;
+
+
+#line 1191 "dk3prcfg.ctr"
+ if(vptr) {
+ switch(pr->t_p) {
+ case DK3_PRINTER_TYPE_WINDOWS: {
+ switch(pr->t_s) {
+ case DK3_PRINTER_TYPE_SOCKET: {
+ back = dk3print_lh_pr_set_timeout(pc,&(pr->det_s),pr->t_s,vptr,0);
+ } break;
+ case DK3_PRINTER_TYPE_LPD:
+ case DK3_PRINTER_TYPE_LPRNG: {
+ back = dk3print_lh_pr_set_timeout(pc,&(pr->det_s),pr->t_s,vptr,0);
+ } break;
+ default: {
+ /* ERROR: Option not available! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
+ dk3prcfg_printer_keywords[11]
+ );
+ } break;
+ }
+ } break;
+ case DK3_PRINTER_TYPE_SOCKET: {
+ back = dk3print_lh_pr_set_timeout(pc, &(pr->det_p), pr->t_p, vptr, 0);
+ } break;
+ case DK3_PRINTER_TYPE_LPD:
+ case DK3_PRINTER_TYPE_LPRNG: {
+ back = dk3print_lh_pr_set_timeout(pc, &(pr->det_p), pr->t_p, vptr, 0);
+ } break;
+ default: {
+ /* ERROR: Option not available! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
+ dk3prcfg_printer_keywords[11]
+ );
+ } break;
+ }
+ } else {
+ /* ERROR: Value required! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
+ dk3prcfg_printer_keywords[11]
+ );
+ }
+
+#line 1233 "dk3prcfg.ctr"
+ return back;
+}
+
+
+
+/** Set send timeout.
+ @param pc Print configuration to set up.
+ @param pr Current printer.
+ @param vptr New value.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable error.
+*/
+static
+int
+dk3print_lh_pr_send_timeout(
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ dkChar const *vptr
+)
+{
+ int back = -1;
+
+
+#line 1254 "dk3prcfg.ctr"
+ if(vptr) {
+ switch(pr->t_p) {
+ case DK3_PRINTER_TYPE_WINDOWS: {
+ switch(pr->t_s) {
+ case DK3_PRINTER_TYPE_SOCKET: {
+ back = dk3print_lh_pr_set_timeout(pc,&(pr->det_s),pr->t_s,vptr,1);
+ } break;
+ case DK3_PRINTER_TYPE_LPD:
+ case DK3_PRINTER_TYPE_LPRNG: {
+ back = dk3print_lh_pr_set_timeout(pc,&(pr->det_s),pr->t_s,vptr,1);
+ } break;
+ default: {
+ /* ERROR: Option not available! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
+ dk3prcfg_printer_keywords[12]
+ );
+ } break;
+ }
+ } break;
+ case DK3_PRINTER_TYPE_SOCKET: {
+ back = dk3print_lh_pr_set_timeout(pc, &(pr->det_p), pr->t_p, vptr, 1);
+ } break;
+ case DK3_PRINTER_TYPE_LPD:
+ case DK3_PRINTER_TYPE_LPRNG: {
+ back = dk3print_lh_pr_set_timeout(pc, &(pr->det_p), pr->t_p, vptr, 1);
+ } break;
+ default: {
+ /* ERROR: Option not available! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
+ dk3prcfg_printer_keywords[12]
+ );
+ } break;
+ }
+ } else {
+ /* ERROR: Value required! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
+ dk3prcfg_printer_keywords[12]
+ );
+ }
+
+#line 1296 "dk3prcfg.ctr"
+ return back;
+}
+
+
+
+/** Set receive timeout.
+ @param pc Print configuration to set up.
+ @param pr Current printer.
+ @param vptr New value.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable error.
+*/
+static
+int
+dk3print_lh_pr_receive_timeout(
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ dkChar const *vptr
+)
+{
+ int back = -1;
+
+
+#line 1317 "dk3prcfg.ctr"
+ if(vptr) {
+ switch(pr->t_p) {
+ case DK3_PRINTER_TYPE_WINDOWS: {
+ switch(pr->t_s) {
+ case DK3_PRINTER_TYPE_SOCKET: {
+ back = dk3print_lh_pr_set_timeout(pc,&(pr->det_s),pr->t_s,vptr,2);
+ } break;
+ case DK3_PRINTER_TYPE_LPD:
+ case DK3_PRINTER_TYPE_LPRNG: {
+ back = dk3print_lh_pr_set_timeout(pc,&(pr->det_s),pr->t_s,vptr,2);
+ } break;
+ default: {
+ /* ERROR: Option not available! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
+ dk3prcfg_printer_keywords[13]
+ );
+ } break;
+ }
+ } break;
+ case DK3_PRINTER_TYPE_SOCKET: {
+ back = dk3print_lh_pr_set_timeout(pc, &(pr->det_p), pr->t_p, vptr, 2);
+ } break;
+ case DK3_PRINTER_TYPE_LPD:
+ case DK3_PRINTER_TYPE_LPRNG: {
+ back = dk3print_lh_pr_set_timeout(pc, &(pr->det_p), pr->t_p, vptr, 2);
+ } break;
+ default: {
+ /* ERROR: Option not available! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
+ dk3prcfg_printer_keywords[13]
+ );
+ } break;
+ }
+ } else {
+ /* ERROR: Value required! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
+ dk3prcfg_printer_keywords[13]
+ );
+ }
+
+#line 1359 "dk3prcfg.ctr"
+ return back;
+}
+
+
+
+/** Set orderly release.
+ @param pc Print configuration to set up.
+ @param pr Printer to set up.
+ @param det Details for current printer.
+ @param tp Current printer type.
+ @param vptr Value text.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable errors.
+*/
+static
+int
+dk3print_lh_pr_set_orderly_release(
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ dk3_printer_details_t *det,
+ int tp,
+ dkChar const *vptr
+)
+{
+ int back = -1;
+
+
+#line 1384 "dk3prcfg.ctr"
+ if(DK3_PRINTER_TYPE_SOCKET == tp) {
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ (det->sock).ordrel = ((dk3str_is_on(vptr)) ? 0x01 : 0x00);
+ back = 1;
+ } else {
+ /* ERROR: Not a boolean! */
+ dk3app_log_i3(pc->app, DK3_LL_ERROR, 146, 147, vptr);
+ }
+ } else {
+ (det->sock).ordrel = 0x01;
+ back = 1;
+ }
+ }
+
+#line 1398 "dk3prcfg.ctr"
+ return back;
+}
+
+
+
+/** Set orderly release.
+ @param pc Print configuration to set up.
+ @param pr Current printer.
+ @param vptr New value.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable error.
+*/
+static
+int
+dk3print_lh_pr_orderly_release(
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ dkChar const *vptr
+)
+{
+ int back = -1;
+
+
+#line 1419 "dk3prcfg.ctr"
+ switch(pr->t_p) {
+ case DK3_PRINTER_TYPE_WINDOWS: {
+ switch(pr->t_s) {
+ case DK3_PRINTER_TYPE_SOCKET: {
+ back =
+ dk3print_lh_pr_set_orderly_release(pc,pr,&(pr->det_s),pr->t_s,vptr);
+ } break;
+ default: {
+ /* ERROR: Option not available */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
+ dk3prcfg_printer_keywords[14]
+ );
+ } break;
+ }
+ } break;
+ case DK3_PRINTER_TYPE_SOCKET: {
+ back =
+ dk3print_lh_pr_set_orderly_release(pc,pr,&(pr->det_p),pr->t_p,vptr);
+ } break;
+ default: {
+ /* ERROR: Option not available */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
+ dk3prcfg_printer_keywords[14]
+ );
+ } break;
+ }
+
+#line 1447 "dk3prcfg.ctr"
+ return back;
+}
+
+
+
+/** Process configuration line for current printer.
+ @param proc Configuration processor.
+ @param pc Print configuration to set up.
+ @param pr Current printer to modify.
+ @param il Input line to process.
+ @return 1 on succuess, 0 on recoverable errors, -1 on
+ unrecoverable errors.
+*/
+static
+int
+dk3print_lh_printer_line(
+ dk3_print_config_processor_t *proc,
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ dkChar *il
+)
+{
+ dkChar *kptr; /* Start of key text. */
+ dkChar *vptr; /* Start of value text. */
+ int back = -1;
+
+
+#line 1473 "dk3prcfg.ctr"
+ kptr = vptr = NULL;
+ kptr = dk3str_start(il, NULL);
+ if(kptr) {
+ vptr = dk3str_chr(kptr, dkT('='));
+ if(vptr) {
+ *(vptr++) = dkT('\0');
+ vptr = dk3str_start(vptr, NULL);
+ }
+ dk3str_normalize(kptr, NULL, dkT(' '));
+ switch(dk3str_array_index(dk3prcfg_printer_keywords, kptr, 0)) {
+ case 0: {
+
+#line 1484 "dk3prcfg.ctr"
+ back = dk3print_lh_pr_alias(pc, pr, vptr);
+ } break;
+ case 1: {
+
+#line 1487 "dk3prcfg.ctr"
+ back = dk3print_lh_pr_type(pc, pr, vptr);
+ } break;
+ case 2: {
+
+#line 1490 "dk3prcfg.ctr"
+ back = dk3print_lh_pr_host(pc, pr, vptr);
+ } break;
+ case 3: {
+
+#line 1493 "dk3prcfg.ctr"
+ back = dk3print_lh_pr_queue(pc, pr, vptr);
+ } break;
+ case 4: {
+
+#line 1496 "dk3prcfg.ctr"
+ back = dk3print_lh_pr_port(pc, pr, vptr);
+ } break;
+ case 5: {
+
+#line 1499 "dk3prcfg.ctr"
+ back = dk3print_lh_pr_ps(pc, pr, vptr);
+ } break;
+ case 6: {
+
+#line 1502 "dk3prcfg.ctr"
+ back = dk3print_lh_pr_psl(pc, pr, vptr);
+ } break;
+ case 7: {
+
+#line 1505 "dk3prcfg.ctr"
+ back = dk3print_lh_pr_default(pc, pr, vptr);
+ } break;
+ case 8: {
+
+#line 1508 "dk3prcfg.ctr"
+ back = dk3print_lh_pr_snmp_host(pc, pr, vptr);
+ } break;
+ case 9: {
+
+#line 1511 "dk3prcfg.ctr"
+ back = dk3print_lh_pr_snmp_community(pc, pr, vptr);
+ } break;
+ case 10: {
+
+#line 1514 "dk3prcfg.ctr"
+ back = dk3print_lh_pr_snmp_version(pc, pr, vptr);
+ } break;
+ case 11: {
+
+#line 1517 "dk3prcfg.ctr"
+ back = dk3print_lh_pr_connect_timeout(pc, pr, vptr);
+ } break;
+ case 12: {
+
+#line 1520 "dk3prcfg.ctr"
+ back = dk3print_lh_pr_send_timeout(pc, pr, vptr);
+ } break;
+ case 13: {
+
+#line 1523 "dk3prcfg.ctr"
+ back = dk3print_lh_pr_receive_timeout(pc, pr, vptr);
+ } break;
+ case 14: {
+ back = dk3print_lh_pr_orderly_release(pc, pr, vptr);
+ } break;
+ default: {
+ /* ERROR: Unknown keyword! */
+ dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 64, 65, vptr);
+ } break;
+ }
+ } else {
+ back = 1;
+ }
+
+#line 1536 "dk3prcfg.ctr"
+ return back;
+}
+
+
+
+/** Set alias.
+ @param pc Print configuration to set up.
+ @param ho Current host.
+ @param vptr Text containing the value.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable errors.
+*/
+static
+int
+dk3print_lh_ho_alias(
+ dk3_print_conf_t *pc,
+ dk3_print_host_t *ho,
+ dkChar const *vptr
+)
+{
+ dk3_print_host_alias_t *al; /* New alias. */
+ void *ptr; /* Existing alias. */
+ int back = -1;
+
+
+#line 1559 "dk3prcfg.ctr"
+ if(vptr) {
+ ptr = dk3sto_it_find_like(pc->iPrintHosts, (void *)vptr, 1);
+ if(ptr) {
+ /* ERROR: Print host already exists! */
+ dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 66, 67, vptr);
+ } else {
+ ptr = dk3sto_it_find_like(pc->iHostAliases, (void *)vptr, 1);
+ if(ptr) {
+ /* ERROR: Host alias already exists! */
+ dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 68, 69, vptr);
+ } else {
+ al = dk3_new_app(dk3_print_host_alias_t,1,pc->app);
+ if(al) {
+ al->host = ho;
+ al->name = dk3str_dup_app(vptr, pc->app);
+ if(al->name) {
+ if(dk3sto_add(pc->sHostAliases, (void *)al)) {
+ back = 1;
+ } else {
+ dk3print_host_alias_delete(al);
+ }
+ } else {
+ dk3print_host_alias_delete(al);
+ }
+ }
+ }
+ }
+ } else {
+ /* ERROR: Value required! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
+ dk3prcfg_host_keywords[0]
+ );
+ }
+
+#line 1593 "dk3prcfg.ctr"
+ return back;
+}
+
+
+
+/** Set encoding.
+ @param pc Print configuration to set up.
+ @param ho Current host.
+ @param vptr Text containing the value.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable errors.
+*/
+static
+int
+dk3print_lh_ho_encoding(
+ dk3_print_conf_t *pc,
+ dk3_print_host_t *ho,
+ dkChar const *vptr
+)
+{
+ int back = -1;
+ int enc; /* Encoding used on host. */
+
+
+#line 1615 "dk3prcfg.ctr"
+ if(vptr) {
+ enc = dk3enc_get_text_encoding_app(vptr, pc->app);
+ if(-1 != enc) {
+ switch(enc) {
+ case DK3_FILE_ENCODING_UTF8: {
+ ho->enc = enc; back = 1;
+ } break;
+ case DK3_FILE_ENCODING_ASCII: {
+ ho->enc = enc; back = 1;
+ } break;
+ default: {
+ /* ERROR: Illegal encoding for LPD protocol! */
+ dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 70, 71, vptr);
+ } break;
+ }
+ }
+ } else {
+ /* ERROR: Value required! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
+ dk3prcfg_host_keywords[1]
+ );
+ }
+
+#line 1638 "dk3prcfg.ctr"
+ return back;
+}
+
+
+
+/** Set timeout.
+ @param pc Print configuration to set up.
+ @param ho Current host.
+ @param vptr Text containing the value.
+ @param sel Timeout type selector (0=connect, 1=send, 2=receive).
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable errors.
+*/
+static
+int
+dk3print_lh_ho_timeout(
+ dk3_print_conf_t *pc,
+ dk3_print_host_t *ho,
+ dkChar const *vptr,
+ int sel
+)
+{
+ dkChar buf[64]; /* Buffer to show existing value. */
+ double d; /* Temporary conversion result. */
+ int conr = 0; /* Conversion result. */
+ int back = -1;
+
+
+#line 1664 "dk3prcfg.ctr"
+ if(vptr) {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(vptr,dk3prcfg_nl[3],&d))
+#else
+ if (0 != dk3ma_d_from_string(&d, vptr, NULL))
+#endif
+ {
+ switch(sel) {
+ case 2: {
+ if(-1.0 < ho->to_r) {
+ /* Warning: Overwriting receive timeout! */
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(buf,dkT("%g"),ho->to_r);
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 58, 59, buf);
+#else
+ conr = dk3ma_d_to_string(
+ buf, DK3_SIZEOF(buf,dkChar), ho->to_r
+ );
+ if (0 != conr) {
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 58, 59, buf);
+ }
+#endif
+ }
+ ho->to_r = d;
+ back = 1;
+ } break;
+ case 1: {
+ if(-1.0 < ho->to_s) {
+ /* Warning: Overwriting send timeout! */
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(buf,dkT("%g"),ho->to_s);
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 60, 61, buf);
+#else
+ conr = dk3ma_d_to_string(
+ buf, DK3_SIZEOF(buf,dkChar), ho->to_s
+ );
+ if (0 != conr) {
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 60, 61, buf);
+ }
+#endif
+ }
+ ho->to_s = d;
+ back = 1;
+ } break;
+ case 0: {
+ if(-1.0 < ho->to_c) {
+ /* Warning: Overwriting connect timeout! */
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(buf,dkT("%g"),ho->to_c);
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 62, 63, buf);
+#else
+ conr = dk3ma_d_to_string(
+ buf, DK3_SIZEOF(buf,dkChar), ho->to_c
+ );
+ if (0 != conr) {
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 62, 63, buf);
+ }
+#endif
+ }
+ ho->to_c = d;
+ back = 1;
+ } break;
+ }
+ } else {
+ /* ERROR: Not numeric! */
+ dk3app_log_i3(pc->app, DK3_LL_ERROR, 141, 142, vptr);
+ }
+ } else {
+ /* ERROR: Value required! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
+ dk3prcfg_host_keywords[2 + sel]
+ );
+ }
+
+#line 1738 "dk3prcfg.ctr"
+ return back;
+}
+
+
+
+/** Set default host.
+ @param pc Print configuration to set up.
+ @param ho Current host.
+ @param vptr Text containing the value.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable errors.
+*/
+static
+int
+dk3print_lh_ho_default(
+ dk3_print_conf_t *pc,
+ dk3_print_host_t *ho,
+ dkChar const *vptr
+)
+{
+ int back = -1;
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ if(dk3str_is_on(vptr)) {
+ pc->defHost = ho;
+ back = 1;
+ }
+ } else {
+ /* ERROR: Not a boolean! */
+ dk3app_log_i3(pc->app, DK3_LL_ERROR, 146, 147, vptr);
+ }
+ } else {
+ pc->defHost = ho;
+ back = 1;
+ }
+ return back;
+}
+
+
+
+/** Process configuration line for current host.
+ @param proc Configuration processor.
+ @param pc Print configuration to set up.
+ @param ho Current host.
+ @param il Input line to process.
+ @return 1 on succuess, 0 on recoverable errors, -1 on
+ unrecoverable errors.
+*/
+static
+int
+dk3print_lh_host_line(
+ dk3_print_config_processor_t *proc,
+ dk3_print_conf_t *pc,
+ dk3_print_host_t *ho,
+ dkChar *il
+)
+{
+ dkChar *kptr; /* Start of key text. */
+ dkChar *vptr; /* Start of value text. */
+ int back = -1;
+
+
+#line 1798 "dk3prcfg.ctr"
+ kptr = vptr = NULL;
+ kptr = dk3str_start(il, NULL);
+ if(kptr) {
+ vptr = dk3str_chr(kptr, dkT('='));
+ if(vptr) {
+ *(vptr++) = dkT('\0');
+ vptr = dk3str_start(vptr, NULL);
+ }
+ dk3str_normalize(kptr, NULL, dkT(' '));
+ switch(dk3str_array_index(dk3prcfg_host_keywords, kptr, 0)) {
+ case 0: {
+
+#line 1809 "dk3prcfg.ctr"
+ back = dk3print_lh_ho_alias(pc, ho, vptr);
+ } break;
+ case 1: {
+
+#line 1812 "dk3prcfg.ctr"
+ back = dk3print_lh_ho_encoding(pc, ho, vptr);
+ } break;
+ case 2: {
+
+#line 1815 "dk3prcfg.ctr"
+ back = dk3print_lh_ho_timeout(pc, ho, vptr, 0);
+ } break;
+ case 3: {
+
+#line 1818 "dk3prcfg.ctr"
+ back = dk3print_lh_ho_timeout(pc, ho, vptr, 1);
+ } break;
+ case 4: {
+
+#line 1821 "dk3prcfg.ctr"
+ back = dk3print_lh_ho_timeout(pc, ho, vptr, 2);
+ } break;
+ case 5: {
+ back = dk3print_lh_ho_default(pc, ho, vptr);
+ } break;
+ default: {
+
+#line 1827 "dk3prcfg.ctr"
+ /* ERROR: Unknown option! */
+ dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 64, 65, vptr);
+ } break;
+ }
+ } else {
+ back = 1;
+ }
+
+#line 1834 "dk3prcfg.ctr"
+ return back;
+}
+
+
+
+/** Handler function to process one configuration line.
+ @param obj Print configuration processor.
+ @param il Input line to process.
+ @return 1 on success, 0 on recoverable error, -1 on unrecoverable
+ error.
+*/
+static
+int
+dk3print_config_line_handler(void *obj, dkChar *il)
+{
+ dk3_print_config_processor_t *pr; /* Print conf processor. */
+ dk3_print_conf_t *pc; /* Configuration to set up. */
+ dkChar *p1; /* Start of text line. */
+ int back = 1;
+
+
+#line 1854 "dk3prcfg.ctr"
+ pr = (dk3_print_config_processor_t *)obj;
+ pc = pr->pc;
+ p1 = dk3str_start(il, NULL);
+ if(p1) {
+ dk3str_delnl(p1);
+
+#line 1859 "dk3prcfg.ctr"
+ if(dkT('#') != *p1) {
+
+#line 1860 "dk3prcfg.ctr"
+ if(dkT('[') == *p1) {
+
+#line 1861 "dk3prcfg.ctr"
+ pr->pr = NULL;
+ pr->ho = NULL;
+ back = dk3print_lh_printer_or_host(pr, pc, p1);
+ } else {
+
+#line 1865 "dk3prcfg.ctr"
+ if(pr->pr) {
+
+#line 1866 "dk3prcfg.ctr"
+ back = dk3print_lh_printer_line(pr, pc, pr->pr, p1);
+ } else {
+ if(pr->ho) {
+
+#line 1869 "dk3prcfg.ctr"
+ back = dk3print_lh_host_line(pr, pc, pr->ho, p1);
+ } else {
+
+#line 1871 "dk3prcfg.ctr"
+ /* WARNING: Line not belonging to printer or host! */
+ dk3app_log_1(pc->app, DK3_LL_WARNING, pc->msg, 72);
+ }
+ }
+ }
+ }
+ } else {
+
+#line 1878 "dk3prcfg.ctr"
+ }
+
+#line 1879 "dk3prcfg.ctr"
+ return back;
+}
+
+
+
+/** Process one configuration file.
+ @param pc Configuration to set up.
+ @param fn File name to apply to configuration.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3print_process_one_config_file(dk3_print_conf_t *pc, dkChar const *fn)
+{
+ dkChar buf[1024]; /* Input line buffer. */
+ dk3_print_config_processor_t pr; /* Config processor. */
+ dkChar const *oldsrcname = NULL; /* Old source file. */
+ unsigned long oldsrcline = 0UL; /* Old source line. */
+ int se; /* System encoding. */
+ int de; /* Default encoding. */
+ int back = 0;
+
+
+#line 1901 "dk3prcfg.ctr"
+ if(pc->app) {
+ oldsrcname = dk3app_get_source_file(pc->app);
+ oldsrcline = dk3app_get_source_line(pc->app);
+ dk3app_set_source_file(pc->app, fn);
+ dk3app_set_source_line(pc->app, 0UL);
+ se = dk3app_get_encoding(pc->app);
+ de = dk3app_get_input_file_encoding(pc->app);
+ } else {
+#if DK3_ON_WINDOWS
+ se = dk3enc_get_encoding(NULL);
+ de = DK3_ENCODING_PLAIN;
+#else
+ se = de = dk3enc_get_encoding(NULL);
+#endif
+ }
+ dk3print_initialize_print_config_processor(&pr, pc);
+ back = dk3stream_process_filename_lines_app(
+ (void *)(&pr),
+ dk3print_config_line_handler,
+ fn,
+ buf,
+ DK3_SIZEOF(buf,dkChar),
+ se,
+ de,
+ pc->app
+ );
+ if(pc->app) {
+ dk3app_set_source_file(pc->app, oldsrcname);
+ dk3app_set_source_line(pc->app, oldsrcline);
+ }
+
+#line 1931 "dk3prcfg.ctr"
+ return back;
+}
+
+
+
+int
+dk3print_read_config_files(dk3_print_conf_t *pc)
+{
+ dk3_search_t *srch; /* Configuration file search results. */
+ dkChar const *fn; /* Current file name to process. */
+ int back = 1;
+
+
+#line 1943 "dk3prcfg.ctr"
+ if(pc) {
+ if(pc->app) {
+ srch = dk3app_find_config_file(pc->app, dk3prcfg_nl[0], 0);
+ if(srch) {
+ dk3search_reset(srch);
+ while(NULL != (fn = dk3search_next(srch))) {
+
+#line 1949 "dk3prcfg.ctr"
+ if(!dk3print_process_one_config_file(pc, fn)) {
+ back = 0;
+ }
+ }
+ dk3search_close(srch);
+ }
+ }
+ }
+
+#line 1957 "dk3prcfg.ctr"
+ return back;
+}
+
+
diff --git a/support/dktools/dk3prcfg.ctr b/support/dktools/dk3prcfg.ctr
new file mode 100644
index 0000000000..e99e0e1761
--- /dev/null
+++ b/support/dktools/dk3prcfg.ctr
@@ -0,0 +1,1960 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2013-xxxx
+license = bsd
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Read dk3print.conf files.
+ @param pc Configuration to set up.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3print_read_config_files(dk3_print_conf_t *pc);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+
+#include "dk3all.h"
+#include "dk3print.h"
+#include "dk3prcfg.h"
+
+
+
+$!trace-include
+
+
+
+/** Print configuration file processor.
+*/
+typedef struct {
+ dk3_print_conf_t *pc; /**< Print configuration to set up. */
+ dk3_printer_t *pr; /**< Current printer to modify. */
+ dk3_print_host_t *ho; /**< Current host to modify. */
+} dk3_print_config_processor_t;
+
+
+
+/** Keywords used by the module, not localized.
+*/
+static dkChar const * const dk3prcfg_nl[] = {
+$!string-table macro=dkT
+#
+# 0: File name of print configuration.
+#
+dk3print.conf
+#
+# 1: Conversion format.
+#
+%u
+#
+# 2: Conversion format.
+#
+%d
+#
+# 3: Conversion format.
+#
+%lf
+$!end
+};
+
+
+
+/** SNMP versions.
+*/
+static dkChar const * const dk3prcfg_snmp_versions[] = {
+$!string-table macro=dkT
+1
+2c
+2p
+3
+$!end
+};
+
+
+
+/** Keywords for section start.
+*/
+static dkChar const * const dk3prcfg_host_or_printer[] = {
+$!string-table macro=dkT
+host
+printer
+$!end
+};
+
+
+
+/** Keywords for printer configuration lines.
+*/
+static dkChar const * const dk3prcfg_printer_keywords[] = {
+$!string-table macro=dkT
+#
+# 0
+#
+alias
+#
+# 1
+#
+type
+#
+# 2
+#
+host
+#
+# 3
+#
+queue
+#
+# 4
+#
+port
+#
+# 5
+#
+ps
+#
+# 6
+#
+ps level
+#
+# 7
+#
+default
+#
+# 8
+#
+snmp host
+#
+# 9
+#
+snmp community
+#
+# 10
+#
+snmp version
+#
+# 11
+#
+connect timeout
+#
+# 12
+#
+send timeout
+#
+# 13
+#
+receive timeout
+#
+# 14
+#
+orderly release
+$!end
+};
+
+
+
+/** Keywords to configure print hosts.
+*/
+static dkChar const * const dk3prcfg_host_keywords[] = {
+$!string-table macro=dkT
+#
+# 0
+#
+alias
+#
+# 1
+#
+encoding
+#
+# 2
+#
+connect timeout
+#
+# 3
+#
+send timeout
+#
+# 4
+#
+receive timeout
+#
+# 5
+#
+default
+$!end
+};
+
+
+
+/** Print queues host types.
+*/
+static dkChar const * const dk3print_queue_types[] = {
+$!string-table macro=dkT
+socket
+lpd
+lprng
+$!end
+};
+
+
+
+/** Initialize a print configuration processor.
+ @param pr Processor to initialize.
+ @param pc Print configuration to set up.
+*/
+static
+void
+dk3print_initialize_print_config_processor(
+ dk3_print_config_processor_t *pr,
+ dk3_print_conf_t *pc
+)
+{
+ pr->pc = pc;
+ pr->pr = NULL;
+ pr->ho = NULL;
+}
+
+
+
+/** Process configuration line to process current printer or host.
+ @param proc Configuration processor.
+ @param pc Print configuration to set up.
+ @param il Input line to process.
+ @return 1 on succuess, 0 on recoverable errors, -1 on
+ unrecoverable errors.
+*/
+static
+int
+dk3print_lh_printer_or_host(
+ dk3_print_config_processor_t *proc,
+ dk3_print_conf_t *pc,
+ dkChar *il
+)
+{
+ dkChar *p1; /* Start of value. */
+ dkChar *p2; /* Finalizing square bracket. */
+ dkChar *p3; /* Start of input line. */
+ int back = 0;
+ $? "+ dk3print_lh_printer_or_host"
+ p3 = il;
+ p3++;
+ p3 = dk3str_start(p3, NULL);
+ if(p3) {
+ p1 = dk3str_next(p3, NULL);
+ if(p1) { $? ". p1"
+ p2 = dk3str_chr(p1, dkT(']'));
+ if(p2) { *p2 = dkT('\0'); }
+ else { $? "! p2"
+ /* WARNING: Missing closing bracket! */
+ dk3app_log_1(pc->app, DK3_LL_WARNING, pc->msg, 27);
+ }
+ switch(dk3str_array_index(dk3prcfg_host_or_printer, p3, 0)) {
+ case 1: { $? ". printer"
+ proc->pr = dk3print_printer_new(pc, p1);
+ if(proc->pr) {
+ back = 1;
+ } else {
+ back = -1;
+ }
+ } break;
+ case 0: { $? ". host"
+ proc->ho = dk3print_host_new(pc, p1);
+ if(proc->ho) {
+ back = 1;
+ } else {
+ back = -1;
+ }
+ } break;
+ default: { $? "! not host or printer \"%!ds\"", p3
+ /* ERROR: Not "host" or "printer"! */
+ dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 28, 29, p3);
+ } break;
+ }
+ } else { $? "! p1"
+ /* ERROR: Printer or host name is missing! */
+ dk3app_log_1(pc->app, DK3_LL_ERROR, pc->msg, 30);
+ }
+ }
+ $? "- dk3print_lh_printer_or_host %d", back
+ return back;
+}
+
+
+
+/** Create a printer alias.
+ @param pc Print configuration to set up.
+ @param pr Current printer.
+ @param vptr Alias name.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable error.
+*/
+static
+int
+dk3print_lh_pr_alias(
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ dkChar const *vptr
+)
+{
+ dk3_printer_alias_t *al; /* Alias already found. */
+ int back = -1;
+ $? "+ dk3print_lh_pr_alias"
+ if(vptr) {
+ if(dk3sto_it_find_like(pc->iPrinters, (void *)vptr, 1)) {
+ /* ERROR: Printer name already exists! */
+ dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 31, 32, vptr);
+ } else {
+ if(dk3sto_it_find_like(pc->iPrintAliases, (void *)vptr, 1)) {
+ /* ERROR: Alias name already exists! */
+ dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 33, 34, vptr);
+ } else {
+ al = dk3_new_app(dk3_printer_alias_t,1,pc->app);
+ if(al) {
+ al->printer = pr;
+ al->name = dk3str_dup_app(vptr, pc->app);
+ if(al->name) {
+ if(dk3sto_add(pc->sPrintAliases, (void *)al)) {
+ back = 1;
+ } else {
+ dk3print_alias_delete(al);
+ }
+ } else {
+ dk3print_alias_delete(al);
+ }
+ }
+ }
+ }
+ } else {
+ /* ERROR: Argument required! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
+ dk3prcfg_printer_keywords[0]
+ );
+ } $? "- dk3print_lh_pr_alias %d", back
+ return back;
+}
+
+
+
+/** Set print queue type.
+ @param pc Print configuration to set up.
+ @param pr Current printer.
+ @param pqt New print queue type.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable errors.
+*/
+static
+int
+dk3print_lh_pr_set_pqt(
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ int pqt
+)
+{
+ int back = -1;
+ $? "+ dk3print_lh_pr_set_pqt"
+ switch(pr->t_p) {
+ case DK3_PRINTER_TYPE_NONE: {
+ pr->t_p = pqt;
+ dk3print_set_det(&(pr->det_p), pqt);
+ back = 1;
+ } break;
+ case DK3_PRINTER_TYPE_WINDOWS: {
+ switch(pr->t_s) {
+ case DK3_PRINTER_TYPE_NONE: {
+ pr->t_s = pqt;
+ dk3print_set_det(&(pr->det_s), pqt);
+ back = 1;
+ } break;
+ default: {
+ /* ERROR: Queue type already set up! */
+ dk3app_log_1(pc->app, DK3_LL_ERROR, pc->msg, 37);
+ } break;
+ }
+ } break;
+ default: {
+ /* ERROR: Queue type already set up! */
+ dk3app_log_1(pc->app, DK3_LL_ERROR, pc->msg, 37);
+ } break;
+ } $? "- dk3print_lh_pr_set_pqt %d", back
+ return back;
+}
+
+
+
+/** Set printer type.
+ @param pc Print configuration to set up.
+ @param pr Current printer.
+ @param vptr New value.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable error.
+*/
+static
+int
+dk3print_lh_pr_type(
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ dkChar const *vptr
+)
+{
+ int pqt; /* Print queue type. */
+ int back = -1;
+ $? "+ dk3print_lh_pr_type"
+ if(vptr) {
+ pqt = dk3str_array_index(dk3print_queue_types, vptr, 0);
+ if(-1 < pqt) {
+ pqt = 2 + pqt;
+ back = dk3print_lh_pr_set_pqt(pc, pr, pqt);
+ } else {
+ /* ERROR: Unknown print queue type! */
+ dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 38, 39, vptr);
+ }
+ } else {
+ /* ERRROR: Argument required! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
+ dk3prcfg_printer_keywords[1]
+ );
+ } $? "- dk3print_lh_pr_type %d", back
+ return back;
+}
+
+
+
+/** Process line containing host details.
+ @param pc Print configuration to modify.
+ @param det Current details structure to modify.
+ @param tp Current printer type.
+ @param name Text to apply.
+ @return 1 on success, 0 on errors.
+*/
+static
+int
+dk3print_lh_pr_det_host(
+ dk3_print_conf_t *pc,
+ dk3_printer_details_t *det,
+ int tp,
+ dkChar const *name
+)
+{
+ int back = -1;
+ $? "+ dk3print_lh_pr_det_host"
+ switch(tp) {
+ case DK3_PRINTER_TYPE_SOCKET: {
+ if((det->sock).hostname) {
+ /* WARNING: Overwriting configured host name! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 40, 41,
+ (det->sock).hostname
+ );
+ dk3_release((det->sock).hostname);
+ }
+ (det->sock).hostname = dk3str_dup_app(name, pc->app);
+ if((det->sock).hostname) {
+ back = 1;
+ }
+ } break;
+ case DK3_PRINTER_TYPE_LPD:
+ case DK3_PRINTER_TYPE_LPRNG: {
+ if((det->lprng).hostname) {
+ /* WARNING: Overwriting configured host name! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 40, 41,
+ (det->lprng).hostname
+ );
+ dk3_release((det->lprng).hostname);
+ }
+ (det->lprng).hostname = dk3str_dup_app(name, pc->app);
+ if((det->lprng).hostname) {
+ back = 1;
+ }
+ } break;
+ } $? "- dk3print_lh_pr_det_host %d", back
+ return back;
+}
+
+
+
+/** Set printer host.
+ @param pc Print configuration to set up.
+ @param pr Current printer.
+ @param vptr New value.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable error.
+*/
+static
+int
+dk3print_lh_pr_host(
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ dkChar const *vptr
+)
+{
+ int back = -1;
+ $? "+ dk3print_lh_pr_host"
+ if(vptr) {
+ switch(pr->t_p) {
+ case DK3_PRINTER_TYPE_WINDOWS: {
+ switch(pr->t_s) {
+ case DK3_PRINTER_TYPE_SOCKET:
+ case DK3_PRINTER_TYPE_LPD:
+ case DK3_PRINTER_TYPE_LPRNG: {
+ back = dk3print_lh_pr_det_host(pc, &(pr->det_s), pr->t_s, vptr);
+ } break;
+ default: {
+ /* ERROR: Option not available for this printer type! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
+ dk3prcfg_printer_keywords[2]
+ );
+ } break;
+ }
+ } break;
+ case DK3_PRINTER_TYPE_SOCKET:
+ case DK3_PRINTER_TYPE_LPD:
+ case DK3_PRINTER_TYPE_LPRNG: {
+ back = dk3print_lh_pr_det_host(pc, &(pr->det_p), pr->t_p, vptr);
+ } break;
+ default: {
+ /* ERROR: Option not available for this printer type! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
+ dk3prcfg_printer_keywords[2]
+ );
+ } break;
+ }
+ } else {
+ /* ERROR: Argument required! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
+ dk3prcfg_printer_keywords[2]
+ );
+ }
+ $? "- dk3print_lh_pr_host %d", back
+ return back;
+}
+
+
+
+/** Set print queue entry for current printer.
+ @param pc Print configuration to modify.
+ @param det Details structure for current printer.
+ @param tp Current printer type.
+ @param name Configuration text to apply.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3print_lh_pr_set_queue(
+ dk3_print_conf_t *pc,
+ dk3_printer_details_t *det,
+ int tp,
+ dkChar const *name
+)
+{
+ int back = -1;
+ $? "+ dk3print_lh_pr_set_queue"
+ switch(tp) {
+ case DK3_PRINTER_TYPE_LPD:
+ case DK3_PRINTER_TYPE_LPRNG: {
+ if((det->lprng).queuename) {
+ /* WARNING: Overriding queue name! */
+ dk3app_log_3(
+ pc->app, DK3_LL_WARNING, pc->msg, 44, 45,
+ (det->lprng).queuename
+ );
+ dk3_release((det->lprng).queuename);
+ }
+ (det->lprng).queuename = dk3str_dup_app(name, pc->app);
+ if((det->lprng).queuename) {
+ back = 1;
+ }
+ } break;
+ } $? "- dk3print_lh_pr_set_queue %d", back
+ return back;
+}
+
+
+
+/** Set printer queue.
+ @param pc Print configuration to set up.
+ @param pr Current printer.
+ @param vptr New value.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable error.
+*/
+static
+int
+dk3print_lh_pr_queue(
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ dkChar const *vptr
+)
+{
+ int back = -1;
+ $? "+ dk3print_lh_pr_queue"
+ if(vptr) {
+ switch(pr->t_p) {
+ case DK3_PRINTER_TYPE_WINDOWS: {
+ switch(pr->t_s) {
+ case DK3_PRINTER_TYPE_LPD:
+ case DK3_PRINTER_TYPE_LPRNG: {
+ back = dk3print_lh_pr_set_queue(pc, &(pr->det_s), pr->t_s, vptr);
+ } break;
+ default: {
+ /* ERROR: Option not available for printer type! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
+ dk3prcfg_printer_keywords[3]
+ );
+ } break;
+ }
+ } break;
+ case DK3_PRINTER_TYPE_LPD:
+ case DK3_PRINTER_TYPE_LPRNG: {
+ back = dk3print_lh_pr_set_queue(pc, &(pr->det_p), pr->t_p, vptr);
+ } break;
+ default: {
+ /* ERROR: Option not available for printer type! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
+ dk3prcfg_printer_keywords[3]
+ );
+ } break;
+ }
+ } else {
+ /* ERROR: Argument required! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
+ dk3prcfg_printer_keywords[3]
+ );
+ } $? "- dk3print_lh_pr_queue %d", back
+ return back;
+}
+
+
+
+/** Set port number for current printer.
+ @param pc Print configuration to modify.
+ @param det Details structure for current printer.
+ @param tp Current printer type.
+ @param name Configuration text to apply.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3print_lh_pr_set_port(
+ dk3_print_conf_t *pc,
+ dk3_printer_details_t *det,
+ int tp,
+ dkChar const *name
+)
+{
+ dkChar buf[64]; /* Used to show existing port no. */
+ int back = -1;
+ int conr = 0; /* Result from conversion. */
+ unsigned u; /* Temporary conversion result. */
+ unsigned short us; /* New port number. */
+ $? "+ dk3print_lh_pr_set_port"
+ switch(tp) {
+ case DK3_PRINTER_TYPE_SOCKET: { $? ". socket"
+ if((det->sock).portno) {
+ /* Warning: Overriding port number! */
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(buf,dkT("%u"),(unsigned)((det->sock).portno));
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 46, 47, buf);
+#else
+ conr = dk3ma_um_to_string(
+ buf, DK3_SIZEOF(buf,dkChar),
+ (dk3_um_t)((det->sock).portno)
+ );
+ if (0 != conr) {
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 46, 47, buf);
+ }
+#endif
+ }
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(name, dk3prcfg_nl[1], &u))
+#else
+ if (0 != dk3ma_ui_from_string(&u, name, NULL))
+#endif
+ {
+ us = (unsigned short)u;
+#if VERSION_BEFORE_20140809
+ if(u == (unsigned)us)
+#else
+ if (u <= (unsigned)(DK3_US_MAX))
+#endif
+ { $? ". success"
+ (det->sock).portno = us;
+ back = 1;
+ } else { $? "! overflow"
+ /* ERROR: Numeric overflow! */
+ dk3app_log_1(pc->app, DK3_LL_ERROR, pc->msg, 48);
+ }
+ } else { $? "! not a number"
+ /* ERROR: Not a number! */
+ dk3app_log_i3(pc->app, DK3_LL_ERROR, 141, 142, name);
+ }
+ } break;
+ default: { $? "! wrong type %d", tp
+ } break;
+ } $? "- dk3print_lh_pr_set_port %d", back
+ return back;
+}
+
+
+
+/** Set printer port.
+ @param pc Print configuration to set up.
+ @param pr Current printer.
+ @param vptr New value.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable error.
+*/
+static
+int
+dk3print_lh_pr_port(
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ dkChar const *vptr
+)
+{
+ int back = -1;
+ $? "+ dk3print_lh_pr_port"
+ if(vptr) {
+ switch(pr->t_p) {
+ case DK3_PRINTER_TYPE_WINDOWS: {
+ switch(pr->t_s) {
+ case DK3_PRINTER_TYPE_SOCKET: { $? ". socket"
+ back = dk3print_lh_pr_set_port(pc, &(pr->det_s), pr->t_s, vptr);
+ } break;
+ default: {
+ /* ERROR: Option not available for print queue type! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
+ dk3prcfg_printer_keywords[4]
+ );
+ } break;
+ }
+ } break;
+ case DK3_PRINTER_TYPE_SOCKET: { $? ". primary socket"
+ back = dk3print_lh_pr_set_port(pc, &(pr->det_p), pr->t_p, vptr);
+ } break;
+ default: {
+ /* ERROR: Option not available for print queue type! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
+ dk3prcfg_printer_keywords[4]
+ );
+ } break;
+ }
+ } else {
+ /* ERROR: Argument required! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
+ dk3prcfg_printer_keywords[4]
+ );
+ } $? "- dk3print_lh_pr_port %d", back
+ return back;
+}
+
+
+
+/** Set printer PS.
+ @param pc Print configuration to set up.
+ @param pr Current printer.
+ @param vptr New value.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable error.
+*/
+static
+int
+dk3print_lh_pr_ps(
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ dkChar const *vptr
+)
+{
+ int back = -1;
+ $? "+ dk3print_lh_pr_ps"
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ pr->ps = ((dk3str_is_on(vptr)) ? (pc->defPsl) : (0));
+ } else {
+ /* ERROR: Not a boolean value! */
+ dk3app_log_i3(pc->app, DK3_LL_ERROR, 146, 147, vptr);
+ }
+ } else {
+ pr->ps = pc->defPsl;
+ } $? "- dk3print_lh_pr_ps %d", back
+ return back;
+}
+
+
+
+/** Set printer PS level.
+ @param pc Print configuration to set up.
+ @param pr Current printer.
+ @param vptr New value.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable error.
+*/
+static
+int
+dk3print_lh_pr_psl(
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ dkChar const *vptr
+)
+{
+ int back = -1;
+ int i; /* Temporary conversion result. */
+ $? "+ dk3print_lh_pr_psl"
+ if(vptr) {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(vptr,dk3prcfg_nl[2],&i))
+#else
+ if (0 != dk3ma_i_from_string(&i, vptr, NULL))
+#endif
+ {
+ if((2 <= i) && (3 >= i)) {
+ pr->ps = i;
+ back = 1;
+ } else {
+ /* ERROR: Out of range! */
+ dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 49, 50, vptr);
+ }
+ } else {
+ /* ERROR: Not a number! */
+ dk3app_log_i3(pc->app, DK3_LL_ERROR, 141, 142, vptr);
+ }
+ } else {
+ /* ERROR: Value required! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
+ dk3prcfg_printer_keywords[6]
+ );
+ } $? "- dk3print_lh_pr_psl %d", back
+ return back;
+}
+
+
+
+/** Set printer as default.
+ @param pc Print configuration to set up.
+ @param pr Current printer.
+ @param vptr New value.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable error.
+*/
+static
+int
+dk3print_lh_pr_default(
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ dkChar const *vptr
+)
+{
+ int back = -1;
+ $? "+ dk3print_lh_pr_default"
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ if(dk3str_is_on(vptr)) {
+ pc->defPrinter = pr;
+ back = 1;
+ }
+ } else {
+ /* ERROR: Not a boolean value! */
+ dk3app_log_i3(pc->app, DK3_LL_ERROR, 146, 147, vptr);
+ }
+ } else {
+ pc->defPrinter = pr;
+ back = 1;
+ } $? "- dk3print_lh_pr_default %d", back
+ return back;
+}
+
+
+
+/** Set SNMP host.
+ @param pc Print configuration to set up.
+ @param pr Current printer.
+ @param vptr New value.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable error.
+*/
+static
+int
+dk3print_lh_pr_snmp_host(
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ dkChar const *vptr
+)
+{
+ int back = -1;
+ $? "+ dk3print_lh_pr_snmp_host"
+ if(vptr) {
+ if(pr->h_snmp) {
+ /* WARNING: Overwriting SNMP host! */
+ dk3app_log_3(
+ pc->app, DK3_LL_WARNING, pc->msg, 51, 52,
+ pr->h_snmp
+ );
+ dk3_release(pr->h_snmp);
+ }
+ pr->h_snmp = dk3str_dup_app(vptr, pc->app);
+ if(pr->h_snmp) {
+ back = 1;
+ }
+ } else {
+ /* ERROR: Value required! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
+ dk3prcfg_printer_keywords[8]
+ );
+ } $? "- dk3print_lh_pr_snmp_host %d", back
+ return back;
+}
+
+
+
+/** Set SNMP community.
+ @param pc Print configuration to set up.
+ @param pr Current printer.
+ @param vptr New value.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable error.
+*/
+static
+int
+dk3print_lh_pr_snmp_community(
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ dkChar const *vptr
+)
+{
+ int back = -1;
+ $? "+ dk3print_lh_pr_snmp_community"
+ if(vptr) {
+ if(pr->c_snmp) {
+ /* WARNING: Overwriting SNMP community! */
+ dk3app_log_3(
+ pc->app, DK3_LL_WARNING, pc->msg, 53, 54,
+ pr->c_snmp
+ );
+ dk3_release(pr->c_snmp);
+ }
+ pr->c_snmp = dk3str_dup_app(vptr, pc->app);
+ if(pr->c_snmp) {
+ back = 1;
+ }
+ } else {
+ /* ERROR: Value required! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
+ dk3prcfg_printer_keywords[9]
+ );
+ } $? "- dk3print_lh_pr_snmp_community %d", back
+ return back;
+}
+
+
+
+/** Set SNMP version.
+ @param pc Print configuration to set up.
+ @param pr Current printer.
+ @param vptr New value.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable error.
+*/
+static
+int
+dk3print_lh_pr_snmp_version(
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ dkChar const *vptr
+)
+{
+ int back = -1;
+ $? "+ dk3print_lh_pr_snmp_version"
+ if(vptr) {
+ if(DK3_SNMP_VERSION_UNKNOWN != pr->v_snmp) {
+ /* Warning: Overwriting SNMP version! */
+ dk3app_log_1(pc->app, DK3_LL_WARNING, pc->msg, 55);
+ }
+ switch(dk3str_array_index(dk3prcfg_snmp_versions, vptr, 0)) {
+ case 0: {
+ pr->v_snmp = DK3_SNMP_VERSION_1; back = 1;
+ } break;
+ case 1: {
+ pr->v_snmp = DK3_SNMP_VERSION_2C; back = 1;
+ } break;
+ case 2: {
+ pr->v_snmp = DK3_SNMP_VERSION_2P; back = 1;
+ } break;
+ case 3: {
+ pr->v_snmp = DK3_SNMP_VERSION_3; back = 1;
+ } break;
+ default: {
+ /* ERROR: Unknown SNMP version! */
+ dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 56, 57, vptr);
+ } break;
+ }
+ } else {
+ /* ERROR: Value required! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
+ dk3prcfg_printer_keywords[10]
+ );
+ } $? "- dk3print_lh_pr_snmp_version %d", back
+ return back;
+}
+
+
+
+/** Set timeout.
+ @param pc Print configuration to set up.
+ @param det Details for current printer.
+ @param tp Current printer type.
+ @param vptr Value text.
+ @param sel Timeout selection (0=connect, 1=send, 2=receive).
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable errors.
+*/
+static
+int
+dk3print_lh_pr_set_timeout(
+ dk3_print_conf_t *pc,
+ dk3_printer_details_t *det,
+ int tp,
+ dkChar const *vptr,
+ int sel
+)
+{
+ dkChar buf[128]; /* Buffer to show existing value. */
+ double d = -1.0; /* Temporary conversion result. */
+ int conr = 0; /* Result from conversion. */
+ int back = -1;
+ $? "+ dk3print_lh_pr_set_timeout"
+ if(vptr) {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(vptr, dk3prcfg_nl[3],&d))
+#else
+ if(0 != dk3ma_d_from_string(&d, vptr, NULL))
+#endif
+ {
+ if(d < 0.0) {
+ d = -1.0;
+ }
+ switch(tp) {
+ case DK3_PRINTER_TYPE_SOCKET: {
+ switch(sel) {
+ case 2: {
+ if((det->sock).to_r > 0.0) {
+ /* WARNING: Overwriting receive timeout! */
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(buf,dkT("%g"),(det->sock).to_r);
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 58, 59, buf);
+#else
+ conr = dk3ma_d_to_string(
+ buf, DK3_SIZEOF(buf,dkChar), (det->sock).to_r
+ );
+ if (0 != conr) {
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 58, 59, buf);
+ }
+#endif
+ }
+ (det->sock).to_r = d;
+ back = 1;
+ } break;
+ case 1: {
+ if((det->sock).to_s > 0.0) {
+ /* WARNING: Overwriting send timeout! */
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(buf,dkT("%g"),(det->sock).to_s);
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 60, 61, buf);
+#else
+ conr = dk3ma_d_to_string(
+ buf, DK3_SIZEOF(buf,dkChar), (det->sock).to_s
+ );
+ if (0 != conr) {
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 60, 61, buf);
+ }
+#endif
+ }
+ (det->sock).to_s = d;
+ back = 1;
+ } break;
+ default: {
+ if((det->sock).to_c > 0.0) {
+ /* WARNING: Overwriting connect timeout! */
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(buf,dkT("%g"),(det->sock).to_c);
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 62, 63, buf);
+#else
+ conr = dk3ma_d_to_string(
+ buf, DK3_SIZEOF(buf,dkChar), (det->sock).to_c
+ );
+ if (0 != conr) {
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 62, 63, buf);
+ }
+#endif
+ }
+ (det->sock).to_c = d;
+ back = 1;
+ } break;
+ }
+ } break;
+ case DK3_PRINTER_TYPE_LPD:
+ case DK3_PRINTER_TYPE_LPRNG: {
+ switch(sel) {
+ case 2: {
+ if((det->lprng).to_r > 0.0) {
+ /* WARNING: Overwriting receive timeout! */
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(buf,dkT("%g"),(det->lprng).to_r);
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 58, 59, buf);
+#else
+ conr = dk3ma_d_to_string(
+ buf, DK3_SIZEOF(buf,dkChar), (det->lprng).to_r
+ );
+ if (0 != conr) {
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 58, 59, buf);
+ }
+#endif
+ }
+ (det->lprng).to_r = d;
+ back = 1;
+ } break;
+ case 1: {
+ if((det->lprng).to_s > 0.0) {
+ /* WARNING: Overwriting send timeout! */
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(buf,dkT("%g"),(det->lprng).to_s);
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 60, 61, buf);
+#else
+ conr = dk3ma_d_to_string(
+ buf, DK3_SIZEOF(buf,dkChar), (det->lprng).to_s
+ );
+ if (0 != conr) {
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 60, 61, buf);
+ }
+#endif
+ }
+ (det->lprng).to_s = d;
+ back = 1;
+ } break;
+ default: {
+ if((det->lprng).to_c > 0.0) {
+ /* WARNING: Overwriting connect timeout! */
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(buf,dkT("%g"),(det->lprng).to_c);
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 62, 63, buf);
+#else
+ conr = dk3ma_d_to_string(
+ buf, DK3_SIZEOF(buf,dkChar), (det->lprng).to_c
+ );
+ if (0 != conr) {
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 62, 63, buf);
+ }
+#endif
+ }
+ (det->lprng).to_c = d;
+ back = 1;
+ } break;
+ }
+ } break;
+ }
+ } else {
+ /* ERROR: Not a number! */
+ dk3app_log_i3(pc->app, DK3_LL_ERROR, 141, 142, vptr);
+ }
+ } $? "- dk3print_lh_pr_set_timeout %d", back
+ return back;
+}
+
+
+
+/** Set connect timeout.
+ @param pc Print configuration to set up.
+ @param pr Current printer.
+ @param vptr New value.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable error.
+*/
+static
+int
+dk3print_lh_pr_connect_timeout(
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ dkChar const *vptr
+)
+{
+ int back = -1;
+ $? "+ dk3print_lh_pr_connect_timeout"
+ if(vptr) {
+ switch(pr->t_p) {
+ case DK3_PRINTER_TYPE_WINDOWS: {
+ switch(pr->t_s) {
+ case DK3_PRINTER_TYPE_SOCKET: {
+ back = dk3print_lh_pr_set_timeout(pc,&(pr->det_s),pr->t_s,vptr,0);
+ } break;
+ case DK3_PRINTER_TYPE_LPD:
+ case DK3_PRINTER_TYPE_LPRNG: {
+ back = dk3print_lh_pr_set_timeout(pc,&(pr->det_s),pr->t_s,vptr,0);
+ } break;
+ default: {
+ /* ERROR: Option not available! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
+ dk3prcfg_printer_keywords[11]
+ );
+ } break;
+ }
+ } break;
+ case DK3_PRINTER_TYPE_SOCKET: {
+ back = dk3print_lh_pr_set_timeout(pc, &(pr->det_p), pr->t_p, vptr, 0);
+ } break;
+ case DK3_PRINTER_TYPE_LPD:
+ case DK3_PRINTER_TYPE_LPRNG: {
+ back = dk3print_lh_pr_set_timeout(pc, &(pr->det_p), pr->t_p, vptr, 0);
+ } break;
+ default: {
+ /* ERROR: Option not available! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
+ dk3prcfg_printer_keywords[11]
+ );
+ } break;
+ }
+ } else {
+ /* ERROR: Value required! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
+ dk3prcfg_printer_keywords[11]
+ );
+ } $? "- dk3print_lh_pr_connect_timeout %d", back
+ return back;
+}
+
+
+
+/** Set send timeout.
+ @param pc Print configuration to set up.
+ @param pr Current printer.
+ @param vptr New value.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable error.
+*/
+static
+int
+dk3print_lh_pr_send_timeout(
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ dkChar const *vptr
+)
+{
+ int back = -1;
+ $? "+ dk3print_lh_pr_send_timeout"
+ if(vptr) {
+ switch(pr->t_p) {
+ case DK3_PRINTER_TYPE_WINDOWS: {
+ switch(pr->t_s) {
+ case DK3_PRINTER_TYPE_SOCKET: {
+ back = dk3print_lh_pr_set_timeout(pc,&(pr->det_s),pr->t_s,vptr,1);
+ } break;
+ case DK3_PRINTER_TYPE_LPD:
+ case DK3_PRINTER_TYPE_LPRNG: {
+ back = dk3print_lh_pr_set_timeout(pc,&(pr->det_s),pr->t_s,vptr,1);
+ } break;
+ default: {
+ /* ERROR: Option not available! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
+ dk3prcfg_printer_keywords[12]
+ );
+ } break;
+ }
+ } break;
+ case DK3_PRINTER_TYPE_SOCKET: {
+ back = dk3print_lh_pr_set_timeout(pc, &(pr->det_p), pr->t_p, vptr, 1);
+ } break;
+ case DK3_PRINTER_TYPE_LPD:
+ case DK3_PRINTER_TYPE_LPRNG: {
+ back = dk3print_lh_pr_set_timeout(pc, &(pr->det_p), pr->t_p, vptr, 1);
+ } break;
+ default: {
+ /* ERROR: Option not available! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
+ dk3prcfg_printer_keywords[12]
+ );
+ } break;
+ }
+ } else {
+ /* ERROR: Value required! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
+ dk3prcfg_printer_keywords[12]
+ );
+ } $? "- dk3print_lh_pr_send_timeout %d", back
+ return back;
+}
+
+
+
+/** Set receive timeout.
+ @param pc Print configuration to set up.
+ @param pr Current printer.
+ @param vptr New value.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable error.
+*/
+static
+int
+dk3print_lh_pr_receive_timeout(
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ dkChar const *vptr
+)
+{
+ int back = -1;
+ $? "+ dk3print_lh_pr_receive_timeout"
+ if(vptr) {
+ switch(pr->t_p) {
+ case DK3_PRINTER_TYPE_WINDOWS: {
+ switch(pr->t_s) {
+ case DK3_PRINTER_TYPE_SOCKET: {
+ back = dk3print_lh_pr_set_timeout(pc,&(pr->det_s),pr->t_s,vptr,2);
+ } break;
+ case DK3_PRINTER_TYPE_LPD:
+ case DK3_PRINTER_TYPE_LPRNG: {
+ back = dk3print_lh_pr_set_timeout(pc,&(pr->det_s),pr->t_s,vptr,2);
+ } break;
+ default: {
+ /* ERROR: Option not available! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
+ dk3prcfg_printer_keywords[13]
+ );
+ } break;
+ }
+ } break;
+ case DK3_PRINTER_TYPE_SOCKET: {
+ back = dk3print_lh_pr_set_timeout(pc, &(pr->det_p), pr->t_p, vptr, 2);
+ } break;
+ case DK3_PRINTER_TYPE_LPD:
+ case DK3_PRINTER_TYPE_LPRNG: {
+ back = dk3print_lh_pr_set_timeout(pc, &(pr->det_p), pr->t_p, vptr, 2);
+ } break;
+ default: {
+ /* ERROR: Option not available! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
+ dk3prcfg_printer_keywords[13]
+ );
+ } break;
+ }
+ } else {
+ /* ERROR: Value required! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
+ dk3prcfg_printer_keywords[13]
+ );
+ } $? "- dk3print_lh_pr_receive_timeout %d", back
+ return back;
+}
+
+
+
+/** Set orderly release.
+ @param pc Print configuration to set up.
+ @param pr Printer to set up.
+ @param det Details for current printer.
+ @param tp Current printer type.
+ @param vptr Value text.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable errors.
+*/
+static
+int
+dk3print_lh_pr_set_orderly_release(
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ dk3_printer_details_t *det,
+ int tp,
+ dkChar const *vptr
+)
+{
+ int back = -1;
+ $? "+ dk3print_lh_pr_set_orderly_release"
+ if(DK3_PRINTER_TYPE_SOCKET == tp) {
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ (det->sock).ordrel = ((dk3str_is_on(vptr)) ? 0x01 : 0x00);
+ back = 1;
+ } else {
+ /* ERROR: Not a boolean! */
+ dk3app_log_i3(pc->app, DK3_LL_ERROR, 146, 147, vptr);
+ }
+ } else {
+ (det->sock).ordrel = 0x01;
+ back = 1;
+ }
+ } $? "- dk3print_lh_pr_set_orderly_release %d", back
+ return back;
+}
+
+
+
+/** Set orderly release.
+ @param pc Print configuration to set up.
+ @param pr Current printer.
+ @param vptr New value.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable error.
+*/
+static
+int
+dk3print_lh_pr_orderly_release(
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ dkChar const *vptr
+)
+{
+ int back = -1;
+ $? "+ dk3print_lh_pr_orderly_release"
+ switch(pr->t_p) {
+ case DK3_PRINTER_TYPE_WINDOWS: {
+ switch(pr->t_s) {
+ case DK3_PRINTER_TYPE_SOCKET: {
+ back =
+ dk3print_lh_pr_set_orderly_release(pc,pr,&(pr->det_s),pr->t_s,vptr);
+ } break;
+ default: {
+ /* ERROR: Option not available */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
+ dk3prcfg_printer_keywords[14]
+ );
+ } break;
+ }
+ } break;
+ case DK3_PRINTER_TYPE_SOCKET: {
+ back =
+ dk3print_lh_pr_set_orderly_release(pc,pr,&(pr->det_p),pr->t_p,vptr);
+ } break;
+ default: {
+ /* ERROR: Option not available */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
+ dk3prcfg_printer_keywords[14]
+ );
+ } break;
+ } $? "- dk3print_lh_pr_orderly_release %d", back
+ return back;
+}
+
+
+
+/** Process configuration line for current printer.
+ @param proc Configuration processor.
+ @param pc Print configuration to set up.
+ @param pr Current printer to modify.
+ @param il Input line to process.
+ @return 1 on succuess, 0 on recoverable errors, -1 on
+ unrecoverable errors.
+*/
+static
+int
+dk3print_lh_printer_line(
+ dk3_print_config_processor_t *proc,
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ dkChar *il
+)
+{
+ dkChar *kptr; /* Start of key text. */
+ dkChar *vptr; /* Start of value text. */
+ int back = -1;
+ $? "+ dk3print_lh_printer_line"
+ kptr = vptr = NULL;
+ kptr = dk3str_start(il, NULL);
+ if(kptr) {
+ vptr = dk3str_chr(kptr, dkT('='));
+ if(vptr) {
+ *(vptr++) = dkT('\0');
+ vptr = dk3str_start(vptr, NULL);
+ }
+ dk3str_normalize(kptr, NULL, dkT(' '));
+ switch(dk3str_array_index(dk3prcfg_printer_keywords, kptr, 0)) {
+ case 0: { $? ". alias"
+ back = dk3print_lh_pr_alias(pc, pr, vptr);
+ } break;
+ case 1: { $? ". type"
+ back = dk3print_lh_pr_type(pc, pr, vptr);
+ } break;
+ case 2: { $? ". host"
+ back = dk3print_lh_pr_host(pc, pr, vptr);
+ } break;
+ case 3: { $? ". queue"
+ back = dk3print_lh_pr_queue(pc, pr, vptr);
+ } break;
+ case 4: { $? ". port"
+ back = dk3print_lh_pr_port(pc, pr, vptr);
+ } break;
+ case 5: { $? ". ps"
+ back = dk3print_lh_pr_ps(pc, pr, vptr);
+ } break;
+ case 6: { $? ". ps level"
+ back = dk3print_lh_pr_psl(pc, pr, vptr);
+ } break;
+ case 7: { $? ". default"
+ back = dk3print_lh_pr_default(pc, pr, vptr);
+ } break;
+ case 8: { $? ". snmp host"
+ back = dk3print_lh_pr_snmp_host(pc, pr, vptr);
+ } break;
+ case 9: { $? ". snmp community"
+ back = dk3print_lh_pr_snmp_community(pc, pr, vptr);
+ } break;
+ case 10: { $? ". snmp version"
+ back = dk3print_lh_pr_snmp_version(pc, pr, vptr);
+ } break;
+ case 11: { $? ". connect timeout"
+ back = dk3print_lh_pr_connect_timeout(pc, pr, vptr);
+ } break;
+ case 12: { $? ". send timeout"
+ back = dk3print_lh_pr_send_timeout(pc, pr, vptr);
+ } break;
+ case 13: { $? ". receive timeout"
+ back = dk3print_lh_pr_receive_timeout(pc, pr, vptr);
+ } break;
+ case 14: {
+ back = dk3print_lh_pr_orderly_release(pc, pr, vptr);
+ } break;
+ default: {
+ /* ERROR: Unknown keyword! */
+ dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 64, 65, vptr);
+ } break;
+ }
+ } else {
+ back = 1;
+ } $? "- dk3print_lh_printer_line %d", back
+ return back;
+}
+
+
+
+/** Set alias.
+ @param pc Print configuration to set up.
+ @param ho Current host.
+ @param vptr Text containing the value.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable errors.
+*/
+static
+int
+dk3print_lh_ho_alias(
+ dk3_print_conf_t *pc,
+ dk3_print_host_t *ho,
+ dkChar const *vptr
+)
+{
+ dk3_print_host_alias_t *al; /* New alias. */
+ void *ptr; /* Existing alias. */
+ int back = -1;
+ $? "+ dk3print_lh_ho_alias"
+ if(vptr) {
+ ptr = dk3sto_it_find_like(pc->iPrintHosts, (void *)vptr, 1);
+ if(ptr) {
+ /* ERROR: Print host already exists! */
+ dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 66, 67, vptr);
+ } else {
+ ptr = dk3sto_it_find_like(pc->iHostAliases, (void *)vptr, 1);
+ if(ptr) {
+ /* ERROR: Host alias already exists! */
+ dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 68, 69, vptr);
+ } else {
+ al = dk3_new_app(dk3_print_host_alias_t,1,pc->app);
+ if(al) {
+ al->host = ho;
+ al->name = dk3str_dup_app(vptr, pc->app);
+ if(al->name) {
+ if(dk3sto_add(pc->sHostAliases, (void *)al)) {
+ back = 1;
+ } else {
+ dk3print_host_alias_delete(al);
+ }
+ } else {
+ dk3print_host_alias_delete(al);
+ }
+ }
+ }
+ }
+ } else {
+ /* ERROR: Value required! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
+ dk3prcfg_host_keywords[0]
+ );
+ } $? "- dk3print_lh_ho_alias %d", back
+ return back;
+}
+
+
+
+/** Set encoding.
+ @param pc Print configuration to set up.
+ @param ho Current host.
+ @param vptr Text containing the value.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable errors.
+*/
+static
+int
+dk3print_lh_ho_encoding(
+ dk3_print_conf_t *pc,
+ dk3_print_host_t *ho,
+ dkChar const *vptr
+)
+{
+ int back = -1;
+ int enc; /* Encoding used on host. */
+ $? "+ dk3print_lh_ho_encoding"
+ if(vptr) {
+ enc = dk3enc_get_text_encoding_app(vptr, pc->app);
+ if(-1 != enc) {
+ switch(enc) {
+ case DK3_FILE_ENCODING_UTF8: {
+ ho->enc = enc; back = 1;
+ } break;
+ case DK3_FILE_ENCODING_ASCII: {
+ ho->enc = enc; back = 1;
+ } break;
+ default: {
+ /* ERROR: Illegal encoding for LPD protocol! */
+ dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 70, 71, vptr);
+ } break;
+ }
+ }
+ } else {
+ /* ERROR: Value required! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
+ dk3prcfg_host_keywords[1]
+ );
+ } $? "- dk3print_lh_ho_encoding %d", back
+ return back;
+}
+
+
+
+/** Set timeout.
+ @param pc Print configuration to set up.
+ @param ho Current host.
+ @param vptr Text containing the value.
+ @param sel Timeout type selector (0=connect, 1=send, 2=receive).
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable errors.
+*/
+static
+int
+dk3print_lh_ho_timeout(
+ dk3_print_conf_t *pc,
+ dk3_print_host_t *ho,
+ dkChar const *vptr,
+ int sel
+)
+{
+ dkChar buf[64]; /* Buffer to show existing value. */
+ double d; /* Temporary conversion result. */
+ int conr = 0; /* Conversion result. */
+ int back = -1;
+ $? "+ dk3print_lh_ho_timeout"
+ if(vptr) {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(vptr,dk3prcfg_nl[3],&d))
+#else
+ if (0 != dk3ma_d_from_string(&d, vptr, NULL))
+#endif
+ {
+ switch(sel) {
+ case 2: {
+ if(-1.0 < ho->to_r) {
+ /* Warning: Overwriting receive timeout! */
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(buf,dkT("%g"),ho->to_r);
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 58, 59, buf);
+#else
+ conr = dk3ma_d_to_string(
+ buf, DK3_SIZEOF(buf,dkChar), ho->to_r
+ );
+ if (0 != conr) {
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 58, 59, buf);
+ }
+#endif
+ }
+ ho->to_r = d;
+ back = 1;
+ } break;
+ case 1: {
+ if(-1.0 < ho->to_s) {
+ /* Warning: Overwriting send timeout! */
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(buf,dkT("%g"),ho->to_s);
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 60, 61, buf);
+#else
+ conr = dk3ma_d_to_string(
+ buf, DK3_SIZEOF(buf,dkChar), ho->to_s
+ );
+ if (0 != conr) {
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 60, 61, buf);
+ }
+#endif
+ }
+ ho->to_s = d;
+ back = 1;
+ } break;
+ case 0: {
+ if(-1.0 < ho->to_c) {
+ /* Warning: Overwriting connect timeout! */
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(buf,dkT("%g"),ho->to_c);
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 62, 63, buf);
+#else
+ conr = dk3ma_d_to_string(
+ buf, DK3_SIZEOF(buf,dkChar), ho->to_c
+ );
+ if (0 != conr) {
+ dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 62, 63, buf);
+ }
+#endif
+ }
+ ho->to_c = d;
+ back = 1;
+ } break;
+ }
+ } else {
+ /* ERROR: Not numeric! */
+ dk3app_log_i3(pc->app, DK3_LL_ERROR, 141, 142, vptr);
+ }
+ } else {
+ /* ERROR: Value required! */
+ dk3app_log_3(
+ pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
+ dk3prcfg_host_keywords[2 + sel]
+ );
+ } $? "- dk3print_lh_ho_timeout %d", back
+ return back;
+}
+
+
+
+/** Set default host.
+ @param pc Print configuration to set up.
+ @param ho Current host.
+ @param vptr Text containing the value.
+ @return 1 on success, 0 on recoverable, -1 on unrecoverable errors.
+*/
+static
+int
+dk3print_lh_ho_default(
+ dk3_print_conf_t *pc,
+ dk3_print_host_t *ho,
+ dkChar const *vptr
+)
+{
+ int back = -1;
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ if(dk3str_is_on(vptr)) {
+ pc->defHost = ho;
+ back = 1;
+ }
+ } else {
+ /* ERROR: Not a boolean! */
+ dk3app_log_i3(pc->app, DK3_LL_ERROR, 146, 147, vptr);
+ }
+ } else {
+ pc->defHost = ho;
+ back = 1;
+ }
+ return back;
+}
+
+
+
+/** Process configuration line for current host.
+ @param proc Configuration processor.
+ @param pc Print configuration to set up.
+ @param ho Current host.
+ @param il Input line to process.
+ @return 1 on succuess, 0 on recoverable errors, -1 on
+ unrecoverable errors.
+*/
+static
+int
+dk3print_lh_host_line(
+ dk3_print_config_processor_t *proc,
+ dk3_print_conf_t *pc,
+ dk3_print_host_t *ho,
+ dkChar *il
+)
+{
+ dkChar *kptr; /* Start of key text. */
+ dkChar *vptr; /* Start of value text. */
+ int back = -1;
+ $? "+ dk3print_lh_host_line"
+ kptr = vptr = NULL;
+ kptr = dk3str_start(il, NULL);
+ if(kptr) {
+ vptr = dk3str_chr(kptr, dkT('='));
+ if(vptr) {
+ *(vptr++) = dkT('\0');
+ vptr = dk3str_start(vptr, NULL);
+ }
+ dk3str_normalize(kptr, NULL, dkT(' '));
+ switch(dk3str_array_index(dk3prcfg_host_keywords, kptr, 0)) {
+ case 0: { $? ". alias"
+ back = dk3print_lh_ho_alias(pc, ho, vptr);
+ } break;
+ case 1: { $? ". encoding"
+ back = dk3print_lh_ho_encoding(pc, ho, vptr);
+ } break;
+ case 2: { $? ". connect timeout"
+ back = dk3print_lh_ho_timeout(pc, ho, vptr, 0);
+ } break;
+ case 3: { $? ". send timeout"
+ back = dk3print_lh_ho_timeout(pc, ho, vptr, 1);
+ } break;
+ case 4: { $? ". receive timeout"
+ back = dk3print_lh_ho_timeout(pc, ho, vptr, 2);
+ } break;
+ case 5: {
+ back = dk3print_lh_ho_default(pc, ho, vptr);
+ } break;
+ default: { $? "! unknown"
+ /* ERROR: Unknown option! */
+ dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 64, 65, vptr);
+ } break;
+ }
+ } else {
+ back = 1;
+ } $? "- dk3print_lh_host_line %d", back
+ return back;
+}
+
+
+
+/** Handler function to process one configuration line.
+ @param obj Print configuration processor.
+ @param il Input line to process.
+ @return 1 on success, 0 on recoverable error, -1 on unrecoverable
+ error.
+*/
+static
+int
+dk3print_config_line_handler(void *obj, dkChar *il)
+{
+ dk3_print_config_processor_t *pr; /* Print conf processor. */
+ dk3_print_conf_t *pc; /* Configuration to set up. */
+ dkChar *p1; /* Start of text line. */
+ int back = 1;
+ $? "+ dk3print_config_line_handler"
+ pr = (dk3_print_config_processor_t *)obj;
+ pc = pr->pc;
+ p1 = dk3str_start(il, NULL);
+ if(p1) {
+ dk3str_delnl(p1); $? ". line \"%!ds\"", p1
+ if(dkT('#') != *p1) { $? ". comment line"
+ if(dkT('[') == *p1) { $? ". start printer or host"
+ pr->pr = NULL;
+ pr->ho = NULL;
+ back = dk3print_lh_printer_or_host(pr, pc, p1);
+ } else { $? ". printer or host details"
+ if(pr->pr) { $? ". configure printer"
+ back = dk3print_lh_printer_line(pr, pc, pr->pr, p1);
+ } else {
+ if(pr->ho) { $? ". configure host"
+ back = dk3print_lh_host_line(pr, pc, pr->ho, p1);
+ } else { $? ". no printer or host open"
+ /* WARNING: Line not belonging to printer or host! */
+ dk3app_log_1(pc->app, DK3_LL_WARNING, pc->msg, 72);
+ }
+ }
+ }
+ }
+ } else { $? ". empty line ok"
+ } $? "- dk3print_config_line_handler %d", back
+ return back;
+}
+
+
+
+/** Process one configuration file.
+ @param pc Configuration to set up.
+ @param fn File name to apply to configuration.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3print_process_one_config_file(dk3_print_conf_t *pc, dkChar const *fn)
+{
+ dkChar buf[1024]; /* Input line buffer. */
+ dk3_print_config_processor_t pr; /* Config processor. */
+ dkChar const *oldsrcname = NULL; /* Old source file. */
+ unsigned long oldsrcline = 0UL; /* Old source line. */
+ int se; /* System encoding. */
+ int de; /* Default encoding. */
+ int back = 0;
+ $? "+ dk3print_process_one_config_file \"%!ds\"", fn
+ if(pc->app) {
+ oldsrcname = dk3app_get_source_file(pc->app);
+ oldsrcline = dk3app_get_source_line(pc->app);
+ dk3app_set_source_file(pc->app, fn);
+ dk3app_set_source_line(pc->app, 0UL);
+ se = dk3app_get_encoding(pc->app);
+ de = dk3app_get_input_file_encoding(pc->app);
+ } else {
+#if DK3_ON_WINDOWS
+ se = dk3enc_get_encoding(NULL);
+ de = DK3_ENCODING_PLAIN;
+#else
+ se = de = dk3enc_get_encoding(NULL);
+#endif
+ }
+ dk3print_initialize_print_config_processor(&pr, pc);
+ back = dk3stream_process_filename_lines_app(
+ (void *)(&pr),
+ dk3print_config_line_handler,
+ fn,
+ buf,
+ DK3_SIZEOF(buf,dkChar),
+ se,
+ de,
+ pc->app
+ );
+ if(pc->app) {
+ dk3app_set_source_file(pc->app, oldsrcname);
+ dk3app_set_source_line(pc->app, oldsrcline);
+ } $? "- dk3print_process_one_config_file %d", back
+ return back;
+}
+
+
+
+int
+dk3print_read_config_files(dk3_print_conf_t *pc)
+{
+ dk3_search_t *srch; /* Configuration file search results. */
+ dkChar const *fn; /* Current file name to process. */
+ int back = 1;
+ $? "+ dk3print_read_config_files"
+ if(pc) {
+ if(pc->app) {
+ srch = dk3app_find_config_file(pc->app, dk3prcfg_nl[0], 0);
+ if(srch) {
+ dk3search_reset(srch);
+ while(NULL != (fn = dk3search_next(srch))) { $? ". fn=\"%!ds\"", fn
+ if(!dk3print_process_one_config_file(pc, fn)) {
+ back = 0;
+ }
+ }
+ dk3search_close(srch);
+ }
+ }
+ } $? "- dk3print_read_config_files %d", back
+ return back;
+}
+
+
diff --git a/support/dktools/dk3prcfg.h b/support/dktools/dk3prcfg.h
new file mode 100644
index 0000000000..9fd8860f72
--- /dev/null
+++ b/support/dktools/dk3prcfg.h
@@ -0,0 +1,62 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3prcfg.ctr
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3prcfg.h Header file for the dk3prcfg module.
+*/
+
+#ifndef DK3PRCFG_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3PRCFG_H_INCLUDED 1
+
+
+#line 8 "dk3prcfg.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Read dk3print.conf files.
+ @param pc Configuration to set up.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3print_read_config_files(dk3_print_conf_t *pc);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk3print.c b/support/dktools/dk3print.c
new file mode 100644
index 0000000000..f9c489ceb5
--- /dev/null
+++ b/support/dktools/dk3print.c
@@ -0,0 +1,1269 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3print.ctr
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3print.c The dk3print module.
+*/
+
+
+#line 136 "dk3print.ctr"
+
+
+
+#include "dk3all.h"
+#include "dk3print.h"
+#include "dk3prcfg.h"
+#include "dk3prreq.h"
+
+
+
+
+
+#line 147 "dk3print.ctr"
+
+
+
+/** Keywords used by the module, not localized.
+*/
+static dkChar const * const dk3print_nl[] = {
+/* 0 */
+dkT("dk3print.conf"),
+
+/* 1 */
+dkT("dk3print.str"),
+
+/* 2 */
+dkT("PS"),
+
+/* 3 */
+dkT("PostScript"),
+
+/* 4 */
+dkT("Ghostscript PDF"),
+
+/* 5 */
+dkT("/print/ps/level"),
+
+/* 6 */
+dkT("%d"),
+
+NULL
+
+
+#line 183 "dk3print.ctr"
+};
+
+
+
+/** Texts used by the module, normaly replaced by localized texts.
+*/
+static dkChar const * const dk3print_msg[] = {
+/* 0 */
+dkT("PRINTER:"),
+
+/* 1 */
+dkT("PRIMARY CONFIGURATION:"),
+
+/* 2 */
+dkT("SECONDARY CONFIGURATION:"),
+
+/* 3 */
+dkT("Printer type: "),
+
+/* 4 */
+dkT("Host: "),
+
+/* 5 */
+dkT("Queue: "),
+
+/* 6 */
+dkT("Port: "),
+
+/* 7 */
+dkT("Connect timeout: "),
+
+/* 8 */
+dkT("Send timeout: "),
+
+/* 9 */
+dkT("Receive timeout: "),
+
+/* 10 */
+dkT("PS level: "),
+
+/* 11 */
+dkT("Default: "),
+
+/* 12 */
+dkT("SNMP host: "),
+
+/* 13 */
+dkT("SNMP community: "),
+
+/* 14 */
+dkT("SNMP version: "),
+
+/* 15 */
+dkT("Orderly release: "),
+
+/* 16 */
+dkT("unknown"),
+
+/* 17 */
+dkT("Windows"),
+
+/* 18 */
+dkT("Socket"),
+
+/* 19 */
+dkT("LPD"),
+
+/* 20 */
+dkT("LPRng"),
+
+/* 21 */
+dkT("yes"),
+
+/* 22 */
+dkT("no"),
+
+/* 23 */
+dkT("1"),
+
+/* 24 */
+dkT("2c"),
+
+/* 25 */
+dkT("2p"),
+
+/* 26 */
+dkT("3"),
+
+/* 27 */
+dkT("Missing closing bracket ']'!"),
+
+/* 28 */
+dkT("Keyword \""),
+
+/* 29 */
+dkT("\" not allowed here, must be \"host\" or \"printer\"!"),
+
+/* 30 */
+dkT("Missing name for printer or host!"),
+
+/* 31 */
+dkT("Printer \""),
+
+/* 32 */
+dkT("\" already exists!"),
+
+/* 33 */
+dkT("Printer alias \""),
+
+/* 34 */
+dkT("\" already exists!"),
+
+/* 35 */
+dkT("Option \""),
+
+/* 36 */
+dkT("\" requires an argument!"),
+
+/* 37 */
+dkT("Queue type is already set!"),
+
+/* 38 */
+dkT("Unknown print queue type \""),
+
+/* 39 */
+dkT("\"!"),
+
+/* 40 */
+dkT("Overwriting host name \""),
+
+/* 41 */
+dkT("\"!"),
+
+/* 42 */
+dkT("Option \""),
+
+/* 43 */
+dkT("\" invalid for printer type!"),
+
+/* 44 */
+dkT("Overwriting queue name \""),
+
+/* 45 */
+dkT("\"!"),
+
+/* 46 */
+dkT("Overwriting port number "),
+
+/* 47 */
+dkT("!"),
+
+/* 48 */
+dkT("Numeric overflow!"),
+
+/* 49 */
+dkT("Illegal PS level \""),
+
+/* 50 */
+dkT("\", must be 2 or 3!"),
+
+/* 51 */
+dkT("Overwriting SNMP host \""),
+
+/* 52 */
+dkT("\"!"),
+
+/* 53 */
+dkT("Overwriting SNMP community \""),
+
+/* 54 */
+dkT("\"!"),
+
+/* 55 */
+dkT("Overwriting SNMP version!"),
+
+/* 56 */
+dkT("Unknown SNMP version \""),
+
+/* 57 */
+dkT("\"!"),
+
+/* 58 */
+dkT("Overwriting receive timeout \""),
+
+/* 59 */
+dkT("\"!"),
+
+/* 60 */
+dkT("Overwriting send timeout \""),
+
+/* 61 */
+dkT("\"!"),
+
+/* 62 */
+dkT("Overwriting connect timeout \""),
+
+/* 63 */
+dkT("\"!"),
+
+/* 64 */
+dkT("Unknown configuration option \""),
+
+/* 65 */
+dkT("\"!"),
+
+/* 66 */
+dkT("Print host \""),
+
+/* 67 */
+dkT("\" already exists!"),
+
+/* 68 */
+dkT("Print host alias \""),
+
+/* 69 */
+dkT("\" already exists!"),
+
+/* 70 */
+dkT("Illegal encoding \""),
+
+/* 71 */
+dkT("\" for LPD protocol!"),
+
+/* 72 */
+dkT("Line outside scope, not belonging to printer or host!"),
+
+NULL
+
+
+#line 415 "dk3print.ctr"
+};
+
+
+
+void
+dk3print_win_det_cleanup(dk3_printer_windows_details_t *ptr)
+{
+
+
+#line 423 "dk3print.ctr"
+ if(ptr) {
+ }
+
+
+#line 426 "dk3print.ctr"
+}
+
+
+
+void
+dk3print_lprng_det_cleanup(dk3_printer_lprng_details_t *ptr)
+{
+
+
+#line 434 "dk3print.ctr"
+ if(ptr) {
+ dk3_release(ptr->hostname);
+ dk3_release(ptr->queuename);
+ }
+
+
+#line 439 "dk3print.ctr"
+}
+
+
+
+void
+dk3print_socket_det_cleanup(dk3_printer_socket_t *ptr)
+{
+
+
+#line 447 "dk3print.ctr"
+ if(ptr) {
+ dk3_release(ptr->hostname);
+ ptr->portno = 0;
+ ptr->ordrel = 0x00;
+ }
+
+
+#line 453 "dk3print.ctr"
+}
+
+
+
+void
+dk3print_det_cleanup(int tp, dk3_printer_details_t *ptr)
+{
+
+
+#line 461 "dk3print.ctr"
+ if(ptr) {
+ switch(tp) {
+ case DK3_PRINTER_TYPE_WINDOWS: {
+ dk3print_win_det_cleanup(&(ptr->win));
+ } break;
+ case DK3_PRINTER_TYPE_SOCKET: {
+ dk3print_socket_det_cleanup(&(ptr->sock));
+ } break;
+ case DK3_PRINTER_TYPE_LPD: {
+ dk3print_lprng_det_cleanup(&(ptr->lprng));
+ } break;
+ case DK3_PRINTER_TYPE_LPRNG: {
+ dk3print_lprng_det_cleanup(&(ptr->lprng));
+ } break;
+ }
+ }
+
+
+#line 478 "dk3print.ctr"
+}
+
+
+
+void
+dk3print_printer_delete(dk3_printer_t *ptr)
+{
+
+
+#line 486 "dk3print.ctr"
+ if(ptr) {
+ dk3print_det_cleanup(ptr->t_p, &(ptr->det_p));
+ dk3print_det_cleanup(ptr->t_s, &(ptr->det_s));
+ dk3_release(ptr->name);
+ dk3_release(ptr->h_snmp);
+ dk3_release(ptr->c_snmp);
+ dk3_delete(ptr);
+ }
+
+#line 494 "dk3print.ctr"
+}
+
+
+
+dk3_printer_t *
+dk3print_printer_new(dk3_print_conf_t *pc, dkChar const *name)
+{
+ dk3_printer_t *back = NULL;
+ if((pc) && (name)) {
+ back =
+ (dk3_printer_t *)dk3sto_it_find_like(pc->iPrinters, (void *)name, 1);
+ if(!(back)) {
+ back = dk3_new_app(dk3_printer_t,1,pc->app);
+ if(back) {
+ back->name = NULL;
+ back->h_snmp = NULL;
+ back->c_snmp = 0;
+ back->t_p = DK3_PRINTER_TYPE_NONE;
+ back->t_s = DK3_PRINTER_TYPE_NONE;
+ back->v_snmp = DK3_SNMP_VERSION_UNKNOWN;
+ back->ps = 0;
+ back->name = dk3str_dup_app(name, pc->app);
+ if(back->name) {
+ if(!dk3sto_add(pc->sPrinters, back)) {
+ dk3print_printer_delete(back);
+ back = NULL;
+ }
+ } else {
+ dk3print_printer_delete(back);
+ back = NULL;
+ }
+ }
+ }
+ if(back) {
+ if(!(pc->defPrinter)) {
+ pc->defPrinter = back;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void
+dk3print_alias_delete(dk3_printer_alias_t *ptr)
+{
+
+
+#line 542 "dk3print.ctr"
+ if(ptr) {
+ dk3_release(ptr->name);
+ ptr->printer = NULL;
+ dk3_delete(ptr);
+ }
+
+
+#line 548 "dk3print.ctr"
+}
+
+
+
+void
+dk3print_host_delete(dk3_print_host_t *ptr)
+{
+
+
+#line 556 "dk3print.ctr"
+ if(ptr) {
+ dk3_release(ptr->name);
+ dk3_delete(ptr);
+ }
+
+
+#line 561 "dk3print.ctr"
+}
+
+
+
+dk3_print_host_t *
+dk3print_host_new(dk3_print_conf_t *pc, dkChar const *name)
+{
+ dk3_print_host_t *back = NULL;
+ if((pc) && (name)) {
+ back =
+ (dk3_print_host_t *)dk3sto_it_find_like(pc->iPrintHosts, (void *)name, 1);
+ if(!(back)) {
+ back = dk3_new_app(dk3_print_host_t,1,pc->app);
+ if(back) {
+ back->name = NULL;
+ /* Further initialization. */
+ back->to_c = -1.0;
+ back->to_r = -1.0;
+ back->to_s = -1.0;
+ back->enc = DK3_ENCODING_UTF8;
+ /* Save name. */
+ back->name = dk3str_dup_app(name, pc->app);
+ if(back->name) {
+ /* Add to configuration. */
+ if(!dk3sto_add(pc->sPrintHosts, back)) {
+ dk3print_host_delete(back);
+ back = NULL;
+ }
+ } else {
+ dk3print_host_delete(back);
+ back = NULL;
+ }
+ }
+ }
+ if(back) {
+ if(!(pc->defHost)) {
+ pc->defHost = back;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void
+dk3print_host_alias_delete(dk3_print_host_alias_t *ptr)
+{
+
+
+#line 610 "dk3print.ctr"
+ if(ptr) {
+ dk3_release(ptr->name);
+ ptr->host = NULL;
+ dk3_delete(ptr);
+ }
+
+
+#line 616 "dk3print.ctr"
+}
+
+
+
+void
+dk3print_conf_delete(dk3_print_conf_t *pc)
+{
+ void *vptr; /* Current element to delete. */
+
+
+
+#line 626 "dk3print.ctr"
+ if(pc) {
+ pc->defPrinter = NULL;
+ pc->defHost = NULL;
+ if(pc->sHostAliases) {
+ if(pc->iHostAliases) {
+ dk3sto_it_reset(pc->iHostAliases);
+ while(NULL != (vptr = dk3sto_it_next(pc->iHostAliases))) {
+ dk3print_host_alias_delete((dk3_print_host_alias_t *)vptr);
+ }
+ dk3sto_it_close(pc->iHostAliases);
+ }
+ dk3sto_close(pc->sHostAliases);
+ } pc->sHostAliases = NULL; pc->iHostAliases = NULL;
+ if(pc->sPrintHosts) {
+ if(pc->iPrintHosts) {
+ dk3sto_it_reset(pc->iPrintHosts);
+ while(NULL != (vptr = dk3sto_it_next(pc->iPrintHosts))) {
+ dk3print_host_delete((dk3_print_host_t *)vptr);
+ }
+ dk3sto_it_close(pc->iPrintHosts);
+ }
+ dk3sto_close(pc->sPrintHosts);
+ } pc->sPrintHosts = NULL; pc->iPrintHosts = NULL;
+ if(pc->sPrintAliases) {
+ if(pc->iPrintAliases) {
+ dk3sto_it_reset(pc->iPrintAliases);
+ while(NULL != (vptr = dk3sto_it_next(pc->iPrintAliases))) {
+ dk3print_alias_delete((dk3_printer_alias_t *)vptr);
+ }
+ dk3sto_it_close(pc->iPrintAliases);
+ }
+ dk3sto_close(pc->sPrintAliases);
+ } pc->sPrintAliases = NULL; pc->iPrintAliases = NULL;
+ if(pc->sPrinters) {
+ if(pc->iPrinters) {
+ dk3sto_it_reset(pc->iPrinters);
+ while(NULL != (vptr = dk3sto_it_next(pc->iPrinters))) {
+ dk3print_printer_delete((dk3_printer_t *)vptr);
+ }
+ dk3sto_it_close(pc->iPrinters);
+ }
+ dk3sto_close(pc->sPrinters);
+ } pc->sPrinters = NULL; pc->iPrinters = NULL;
+ pc->app = NULL;
+ pc->msg = NULL;
+ dk3_delete(pc);
+ }
+
+#line 673 "dk3print.ctr"
+}
+
+
+
+/** Compare two printers by name.
+ @param l Left object.
+ @param r Right object or name.
+ @param cr Comparison criteria (0=printer/printer, 1=printer/name).
+ @return Comparison result.
+*/
+static
+int
+dk3print_compare_printer(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3_printer_t const *pl; /* Pointer to left printer. */
+ dk3_printer_t const *pr; /* Pointer to right printer. */
+ dkChar const *n; /* Pointer to right name. */
+ if(l) {
+ if(r) {
+ pl = (dk3_printer_t const *)l;
+ switch(cr) {
+ case 1: {
+ n = (dkChar const *)r;
+ if(pl->name) {
+ back = dk3str_cmp(pl->name, n);
+ if(back < 0) back = -1;
+ if(back > 0) back = 1;
+ } else {
+ back = -1;
+ }
+ } break;
+ default: {
+ pr = (dk3_printer_t const *)r;
+ if(pl->name) {
+ if(pr->name) {
+ back = dk3str_cmp(pl->name, pr->name);
+ if(back < 0) back = -1;
+ if(back > 0) back = 1;
+ } else {
+ back = 1;
+ }
+ } else {
+ if(pr->name) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Compare two printer aliases by name.
+ @param l Left object.
+ @param r Right object or name.
+ @param cr Comparison criteria (0=alias/alias, 1=alias/name).
+ @return Comparison result.
+*/
+static
+int
+dk3print_compare_print_alias(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3_printer_alias_t const *pl; /* Left printer alias. */
+ dk3_printer_alias_t const *pr; /* Right printer alias. */
+ dkChar const *n; /* Right alias name. */
+ if(l) {
+ if(r) {
+ pl = (dk3_printer_alias_t const *)l;
+ switch(cr) {
+ case 1: {
+ n = (dkChar const *)r;
+ if(pl->name) {
+ back = dk3str_cmp(pl->name, n);
+ if(back < 0) back = -1;
+ if(back > 0) back = 1;
+ } else {
+ back = -1;
+ }
+ } break;
+ default: {
+ pr = (dk3_printer_alias_t const *)r;
+ if(pl->name) {
+ if(pr->name) {
+ back = dk3str_cmp(pl->name, pr->name);
+ if(back < 0) back = -1;
+ if(back > 0) back = 1;
+ } else {
+ back = 1;
+ }
+ } else {
+ if(pr->name) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Compare two print hosts by name.
+ @param l Left object.
+ @param r Right object or name.
+ @param cr Comparison criteria (0=host/host, 1=host/name).
+ @return Comparison result.
+*/
+static
+int
+dk3print_compare_host(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3_print_host_t const *pl; /* Left print host. */
+ dk3_print_host_t const *pr; /* Right print host. */
+ dkChar const *n; /* Right print host name. */
+ if(l) {
+ if(r) {
+ pl = (dk3_print_host_t const *)l;
+ switch(cr) {
+ case 1: {
+ n = (dkChar const *)r;
+ if(pl->name) {
+ back = dk3str_cmp(pl->name, n);
+ if(back < 0) back = -1;
+ if(back > 0) back = 1;
+ } else {
+ back = -1;
+ }
+ } break;
+ default: {
+ pr = (dk3_print_host_t const *)r;
+ if(pl->name) {
+ if(pr->name) {
+ back = dk3str_cmp(pl->name, pr->name);
+ if(back < 0) back = -1;
+ if(back > 0) back = 1;
+ } else {
+ back = 1;
+ }
+ } else {
+ if(pr->name) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Compare two print host aliases by name.
+ @param l Left object.
+ @param r Right object or name.
+ @param cr Comparison criteria (0=alias/alias, 1=alias/name).
+ @return Comparison result.
+*/
+static
+int
+dk3print_compare_host_alias(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3_print_host_alias_t const *pl; /* Left host alias. */
+ dk3_print_host_alias_t const *pr; /* Right host alias. */
+ dkChar const *n; /* Right alias name. */
+ if(l) {
+ if(r) {
+ pl = (dk3_print_host_alias_t const *)l;
+ switch(cr) {
+ case 1: {
+ n = (dkChar const *)r;
+ if(pl->name) {
+ back = dk3str_cmp(pl->name, n);
+ if(back < 0) back = -1;
+ if(back > 0) back = 1;
+ } else {
+ back = -1;
+ }
+ } break;
+ default: {
+ pr = (dk3_print_host_alias_t const *)r;
+ if(pl->name) {
+ if(pr->name) {
+ back = dk3str_cmp(pl->name, pr->name);
+ if(back < 0) back = -1;
+ if(back > 0) back = 1;
+ } else {
+ back = 1;
+ }
+ } else {
+ if(pr->name) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+dk3_print_conf_t *
+dk3print_config_new(dk3_app_t *app)
+{
+ dk3_print_conf_t *back = NULL;
+ int ok = 0; /* Flag: Success. */
+
+
+#line 915 "dk3print.ctr"
+ if(app) {
+ back = dk3_new_app(dk3_print_conf_t,1,app);
+ if(back) {
+ /* Initialize members. */
+ back->sPrinters = NULL; back->iPrinters = NULL;
+ back->sPrintAliases = NULL; back->iPrintAliases = NULL;
+ back->sPrintHosts = NULL; back->iPrintHosts = NULL;
+ back->defPrinter = NULL;
+ back->defHost = NULL;
+ back->defPsl = 3;
+ back->app = app;
+ back->msg = dk3app_messages(app, dk3print_nl[1], dk3print_msg);
+ if(!(back->msg)) { back->msg = dk3print_msg; }
+ /* Allocate resources for storages. */
+ back->sPrinters = dk3sto_open_app(app);
+ if(back->sPrinters) {
+ dk3sto_set_comp(back->sPrinters, dk3print_compare_printer, 0);
+ back->iPrinters = dk3sto_it_open(back->sPrinters);
+ if(back->iPrinters) {
+ back->sPrintAliases = dk3sto_open_app(app);
+ if(back->sPrintAliases) {
+ dk3sto_set_comp(back->sPrintAliases,dk3print_compare_print_alias,0);
+ back->iPrintAliases = dk3sto_it_open(back->sPrintAliases);
+ if(back->iPrintAliases) {
+ back->sPrintHosts = dk3sto_open_app(app);
+ if(back->sPrintHosts) {
+ dk3sto_set_comp(back->sPrintHosts, dk3print_compare_host, 0);
+ back->iPrintHosts = dk3sto_it_open(back->sPrintHosts);
+ if(back->iPrintHosts) {
+ back->sHostAliases = dk3sto_open_app(app);
+ if(back->sHostAliases) {
+ dk3sto_set_comp(
+ back->sHostAliases, dk3print_compare_host_alias, 0
+ );
+ back->iHostAliases = dk3sto_it_open(back->sHostAliases);
+ if(back->iHostAliases) {
+ ok = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ /* Destroy configuration if allocations failed. */
+ if(!(ok)) {
+ dk3print_conf_delete(back);
+ back = NULL;
+ }
+ }
+ }
+
+#line 967 "dk3print.ctr"
+ return back;
+}
+
+
+#if DK3_ON_WINDOWS
+
+/** Check whether a printer name contains the words
+ "PostScript" or "PS".
+ @param pc Print configuration to set up.
+ @param pr Printer structure to modify.
+ @param str Printer string to check.
+*/
+static
+void
+dk3print_check_postscript(
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ dkChar const *str
+)
+{
+ dkChar buf[DK3_MAX_PATH]; /* Private copy. */
+ dkChar *c; /* Current string. */
+ dkChar *n; /* Next string. */
+
+ if(!(pr->ps)) {
+ if(dk3str_len(str) < DK3_SIZEOF(buf,dkChar)) {
+ dk3str_cpy_not_overlapped(buf, str);
+ c = dk3str_start(buf, NULL);
+ while(c) {
+ n = dk3str_next(c, NULL);
+ if(dk3str_cmp(c, dk3print_nl[2]) == 0) {
+ pr->ps = pc->defPsl;
+ } else {
+ if(dk3str_casecmp(c, dk3print_nl[3]) == 0) {
+ pr->ps = pc->defPsl;
+ }
+ }
+ c = n;
+ }
+ }
+ if(!(pr->ps)) {
+ if(dk3str_casecmp(str, dk3print_nl[4]) == 0) {
+ pr->ps = pc->defPsl;
+ }
+ }
+ }
+}
+
+#endif
+
+
+
+#if DK3_ON_WINDOWS
+/* + Windows */
+
+/** Read printer information from system.
+ @param pc Print configuration to set up.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3print_read_system(dk3_print_conf_t *pc)
+{
+ dkChar buf[1024]; /* Default printer name. */
+ char *peb; /* Result buffer. */
+#if DK3_CHAR_SIZE > 1
+ PRINTER_INFO_2W *pi2; /* Printer information. */
+#else
+ PRINTER_INFO_2A *pi2; /* Printer information. */
+#endif
+ dk3_printer_t *printer; /* New printer to create. */
+ DWORD cbNeeded; /* Bytes needed. */
+ DWORD cbReturned; /* Bytes returned. */
+ DWORD szPeb; /* Size of peb. */
+ DWORD i; /* Index of current information. */
+ DWORD dwSz; /* Buffer size. */
+ BOOL res; /* Operation result. */
+ int back = 1;
+
+
+#line 1046 "dk3print.ctr"
+ cbNeeded = cbReturned = szPeb = (DWORD)0UL;
+#if DK3_CHAR_SIZE > 1
+ EnumPrintersW(PRINTER_ENUM_LOCAL,NULL,2,NULL,szPeb,&cbNeeded,&cbReturned);
+#else
+ EnumPrintersA(PRINTER_ENUM_LOCAL,NULL,2,NULL,szPeb,&cbNeeded,&cbReturned);
+#endif
+ if(cbNeeded > 0) {
+ szPeb = cbNeeded;
+ peb = dk3_new_app(char,(size_t)cbNeeded,pc->app);
+ if(peb) {
+ cbNeeded = cbReturned = (DWORD)0UL;
+#if DK3_CHAR_SIZE > 1
+ res = EnumPrintersW(
+ PRINTER_ENUM_LOCAL,NULL,2,(LPBYTE)peb,szPeb,&cbNeeded,&cbReturned
+ );
+#else
+ res = EnumPrintersA(
+ PRINTER_ENUM_LOCAL,NULL,2,(LPBYTE)peb,szPeb,&cbNeeded,&cbReturned
+ );
+#endif
+ if(res) {
+ if((DWORD)0UL < cbReturned) {
+ pi2 = (PRINTER_INFO_2 *)peb;
+ for(i = (DWORD)0UL; i < cbReturned; i++) {
+ printer = dk3print_printer_new(pc, pi2->pPrinterName);
+ if(printer) {
+ printer->t_p = DK3_PRINTER_TYPE_WINDOWS;
+ if(pi2->pDriverName) {
+ dk3print_check_postscript(pc, printer, pi2->pDriverName);
+ }
+ if(pi2->pComment) {
+ dk3print_check_postscript(pc, printer, pi2->pComment);
+ }
+ } else {
+ back = 0;
+ }
+ pi2++;
+ }
+ } else {
+
+#line 1085 "dk3print.ctr"
+ }
+ } else {
+
+#line 1087 "dk3print.ctr"
+ back = 0;
+ }
+ dk3_delete(peb);
+ } else {
+
+#line 1091 "dk3print.ctr"
+ back = 0;
+ }
+ if(back) {
+ dwSz = (DWORD)DK3_SIZEOF(buf,dkChar) ;
+#if DK3_CHAR_SIZE > 1
+ res = GetDefaultPrinterW(buf, &dwSz);
+#else
+ res = GetDefaultPrinterA(buf, &dwSz);
+#endif
+ if(res) {
+ if(dwSz > (DWORD)0UL) {
+ if(dwSz < DK3_SIZEOF(buf,dkChar)) {
+ buf[dwSz - 1] = dkT('\0');
+ printer =
+ (dk3_printer_t *)dk3sto_it_find_like(pc->iPrinters, (void *)buf, 1);
+ if(printer) {
+ pc->defPrinter = printer;
+ }
+ }
+ }
+ }
+ }
+ } else {
+
+#line 1114 "dk3print.ctr"
+ }
+
+
+#line 1116 "dk3print.ctr"
+ return back;
+}
+
+/* - Windows */
+
+#else
+/* + non-Windows */
+
+/** Read printer information from system.
+ @param pc Print configuration to set up.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3print_read_system(dk3_print_conf_t *pc)
+{
+ int back = 1;
+
+
+#line 1134 "dk3print.ctr"
+ /* ##### Read /etc/printcap */
+
+
+#line 1136 "dk3print.ctr"
+ return back;
+}
+
+/* - non-Windows */
+#endif
+
+
+/** Read print configuration data from system and/or configuration files.
+ @param pc Print configuration to set up.
+ @param useConfigFiles Flag: Use dk3print conf files.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3print_read_configuration(dk3_print_conf_t *pc, int useConfigFiles)
+{
+ dkChar buf[512]; /* Buffer used for values in diagnostics. */
+ int i; /* Temporary conversion result (PS level). */
+ int back = 0;
+
+
+
+#line 1157 "dk3print.ctr"
+ /* Find default PS level from preferences */
+ if(pc->app) {
+ if(dk3app_get_pref(pc->app, dk3print_nl[5], buf, DK3_SIZEOF(buf,dkChar))) {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(buf, dk3print_nl[6], &i) == 1)
+#else
+ if (0 != dk3ma_i_from_string(&i, buf, NULL))
+#endif
+ {
+ if((2 <= i) && (3 >= i)) {
+ pc->defPsl = i;
+ } else {
+ /* ERROR: PS level out of range! */
+ dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 49, 50, buf);
+ }
+ } else {
+ /* ERROR: PS level not numeric! */
+ dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 49, 50, buf);
+ }
+ }
+ }
+ /* Read system printers and configuration files. */
+ if(dk3print_read_system(pc)) {
+ if(useConfigFiles) {
+ if(dk3print_read_config_files(pc)) {
+ back = 1;
+ }
+ } else {
+ back = 1;
+ }
+ }
+
+#line 1188 "dk3print.ctr"
+ return back;
+}
+
+
+
+dk3_print_conf_t *
+dk3print_conf_open(dk3_app_t *app, int useConfigFiles)
+{
+ dk3_print_conf_t *back = NULL;
+
+
+#line 1198 "dk3print.ctr"
+ if(app) {
+ back = dk3print_config_new(app);
+ if(back) {
+ if(!dk3print_read_configuration(back, useConfigFiles)) {
+ dk3print_conf_delete(back);
+ back = NULL;
+ }
+ }
+ }
+
+#line 1207 "dk3print.ctr"
+ return back;
+}
+
+
+
+void
+dk3print_conf_close(dk3_print_conf_t *pc)
+{
+
+
+#line 1216 "dk3print.ctr"
+ if(pc) {
+ dk3print_conf_delete(pc);
+ }
+
+#line 1219 "dk3print.ctr"
+}
+
+
+
+void
+dk3print_set_det(dk3_printer_details_t *det, int tp)
+{
+
+
+#line 1227 "dk3print.ctr"
+ if(det) {
+ switch(tp) {
+ case DK3_PRINTER_TYPE_WINDOWS: {
+ (det->win).dummy = 0;
+ } break;
+ case DK3_PRINTER_TYPE_SOCKET: {
+ (det->sock).hostname = NULL;
+ (det->sock).portno = 0;
+ (det->sock).ordrel = 0x00;
+ (det->sock).to_c = -1.0;
+ (det->sock).to_r = -1.0;
+ (det->sock).to_s = -1.0;
+ } break;
+ case DK3_PRINTER_TYPE_LPD: case DK3_PRINTER_TYPE_LPRNG: {
+ (det->lprng).hostname = NULL;
+ (det->lprng).queuename = NULL;
+ (det->lprng).to_c = -1.0;
+ (det->lprng).to_r = -1.0;
+ (det->lprng).to_s = -1.0;
+ } break;
+ default: {
+ } break;
+ }
+ }
+
+#line 1251 "dk3print.ctr"
+}
+
+
+
+dk3_printer_t *
+dk3print_get_printer(dk3_print_conf_t *pc, dkChar const *pn)
+{
+ dk3_printer_t *back = NULL;
+ dk3_printer_alias_t *al = NULL; /* Alias for printer. */
+
+ if((pc) && (pn)) {
+ back = (dk3_printer_t *)dk3sto_it_find_like(pc->iPrinters, (void *)pn, 1);
+ if(!(back)) {
+ al = (dk3_printer_alias_t *)dk3sto_it_find_like(
+ pc->iPrintAliases, (void *)pn, 1
+ );
+ if(al) {
+ back = al->printer;
+ }
+ }
+ }
+ return back;
+}
+
+
+dk3_print_host_t *
+dk3print_get_host(dk3_print_conf_t *pc, dkChar const *hn)
+{
+ dk3_print_host_t *back = NULL;
+ dk3_print_host_alias_t *al = NULL; /* Alias for host. */
+
+ if((pc) && (hn)) {
+ back = (dk3_print_host_t *)dk3sto_it_find_like(
+ pc->iPrintHosts, (void *)hn, 1
+ );
+ if(!(back)) {
+ al = (dk3_print_host_alias_t *)dk3sto_it_find_like(
+ pc->iHostAliases, (void *)hn, 1
+ );
+ if(al) {
+ back = al->host;
+ }
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk3print.ctr b/support/dktools/dk3print.ctr
new file mode 100644
index 0000000000..d979b0191d
--- /dev/null
+++ b/support/dktools/dk3print.ctr
@@ -0,0 +1,1297 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2013-xxxx
+license = bsd
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Clean up details for Windows printer.
+ @param ptr Details to clean up.
+*/
+void
+dk3print_win_det_cleanup(dk3_printer_windows_details_t *ptr);
+
+/** Clean up details for LPRng/LPD printer.
+ @param ptr Details to clean up.
+*/
+void
+dk3print_lprng_det_cleanup(dk3_printer_lprng_details_t *ptr);
+
+/** Clean up details for socket printer.
+ @param ptr Details to clean up.
+*/
+void
+dk3print_socket_det_cleanup(dk3_printer_socket_t *ptr);
+
+/** Clean up type-specific details for a printer.
+ @param tp Printer type.
+ @param ptr Pointer to details data.
+*/
+void
+dk3print_det_cleanup(int tp, dk3_printer_details_t *ptr);
+
+/** Create new printer entry if necessary.
+ @param pc Print configuration to set up.
+ @param name Printer name.
+ @return Pointer to new or existing printer entry on success,
+ NULL on error.
+*/
+dk3_printer_t *
+dk3print_printer_new(dk3_print_conf_t *pc, dkChar const *name);
+
+/** Destroy printer entry in print configuration, release memory.
+ @param ptr Printer entry to destroy.
+*/
+void
+dk3print_printer_delete(dk3_printer_t *ptr);
+
+/** Destroy printer alias entry in print configuration, release memory.
+ @param ptr Alias to destroy.
+*/
+void
+dk3print_alias_delete(dk3_printer_alias_t *ptr);
+
+/** Create new print host entry if necessary.
+ @param pc Print configuration to set up.
+ @param name Print host name.
+ @return Pointer to new or existing printer entry on success,
+ NULL on error.
+*/
+dk3_print_host_t *
+dk3print_host_new(dk3_print_conf_t *pc, dkChar const *name);
+
+/** Destroy print host entry in print configuration, release memory.
+ @param ptr Print host entry to destroy.
+*/
+void
+dk3print_host_delete(dk3_print_host_t *ptr);
+
+/** Destroy print host alias entry in print configuration, release memory.
+ @param ptr Alias to destroy.
+*/
+void
+dk3print_host_alias_delete(dk3_print_host_alias_t *ptr);
+
+/** Destroy print configuration, release resources.
+ @param pc Print configuration to destroy.
+*/
+void
+dk3print_conf_delete(dk3_print_conf_t *pc);
+
+/** Create new print configuration, allocate resources for storages.
+ @param app Application structur, must not be NULL.
+ @return Pointer to new configuration on success, NULL on error.
+*/
+dk3_print_conf_t *
+dk3print_config_new(dk3_app_t *app);
+
+/** Create new print configuration, initialize it from configuration files.
+ @param app Application structure, must not be NULL.
+ @param useConfigFiles Flag: Use dk3print configuration files.
+ @return Pointer to new configuration on success, NULL on error.
+*/
+dk3_print_conf_t *
+dk3print_conf_open(dk3_app_t *app, int useConfigFiles);
+
+/** Close print configuration.
+ @param pc Print configuration to close.
+*/
+void
+dk3print_conf_close(dk3_print_conf_t *pc);
+
+/** Initialize details based on print queue type.
+ @param det Details to initialize.
+ @param tp Print queue type.
+*/
+void
+dk3print_set_det(dk3_printer_details_t *det, int tp);
+
+/** Find named printer (either directly or via alias).
+ @param pc Print configuration.
+ @param pn Printer name.
+ @return Pointer to printer on success, NULL on error (not found).
+*/
+dk3_printer_t *
+dk3print_get_printer(dk3_print_conf_t *pc, dkChar const *pn);
+
+/** Find named print host (either directly or via alias).
+ @param pc Print configuration.
+ @param hn Host name.
+ @return Pointer to print host on success, NULL on error (not found).
+*/
+dk3_print_host_t *
+dk3print_get_host(dk3_print_conf_t *pc, dkChar const *hn);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+
+
+#include "dk3all.h"
+#include "dk3print.h"
+#include "dk3prcfg.h"
+#include "dk3prreq.h"
+
+
+
+$!trace-include
+
+
+
+/** Keywords used by the module, not localized.
+*/
+static dkChar const * const dk3print_nl[] = {
+$!string-table macro=dkT
+#
+# 0: Name of configuration file.
+#
+dk3print.conf
+#
+# 1: String table file name.
+#
+dk3print.str
+#
+# 2: PS
+#
+PS
+#
+# 3: PostScript
+#
+PostScript
+#
+# 4: Driver name GhostScript PDF
+#
+Ghostscript PDF
+#
+# 5: Default PS level preference.
+#
+/print/ps/level
+#
+# 6: Conversion format for PS level.
+#
+%d
+$!end
+};
+
+
+
+/** Texts used by the module, normaly replaced by localized texts.
+*/
+static dkChar const * const dk3print_msg[] = {
+$!string-table macro=dkT
+#
+# 0
+#
+PRINTER:
+#
+# 1
+#
+PRIMARY CONFIGURATION:
+#
+# 2
+#
+SECONDARY CONFIGURATION:
+#
+# 3
+#
+Printer type:
+#
+# 4
+#
+Host:
+#
+# 5
+#
+Queue:
+#
+# 6
+#
+Port:
+#
+# 7
+#
+Connect timeout:
+#
+# 8
+#
+Send timeout:
+#
+# 9
+#
+Receive timeout:
+#
+# 10
+#
+PS level:
+#
+# 11
+#
+Default:
+#
+# 12
+#
+SNMP host:
+#
+# 13
+#
+SNMP community:
+#
+# 14
+#
+SNMP version:
+#
+# 15
+#
+Orderly release:
+#
+# 16
+#
+unknown
+#
+# 17
+#
+Windows
+#
+# 18
+#
+Socket
+#
+# 19
+#
+LPD
+#
+# 20
+#
+LPRng
+#
+# 21
+#
+yes
+#
+# 22
+#
+no
+#
+# 23 24 25 26
+#
+1
+2c
+2p
+3
+#
+# 27
+#
+Missing closing bracket ']'!
+#
+# 28 29
+#
+Keyword "
+" not allowed here, must be "host" or "printer"!
+#
+# 30
+#
+Missing name for printer or host!
+#
+# 31 32
+#
+Printer "
+" already exists!
+#
+# 33 34
+#
+Printer alias "
+" already exists!
+#
+# 35 36
+#
+Option "
+" requires an argument!
+#
+# 37
+#
+Queue type is already set!
+#
+# 38 39
+#
+Unknown print queue type "
+"!
+#
+# 40 41
+#
+Overwriting host name "
+"!
+#
+# 42 43
+#
+Option "
+" invalid for printer type!
+#
+# 44 45
+#
+Overwriting queue name "
+"!
+#
+# 46 47
+#
+Overwriting port number
+!
+#
+# 48
+#
+Numeric overflow!
+#
+# 49 50
+#
+Illegal PS level "
+", must be 2 or 3!
+#
+# 51 52
+#
+Overwriting SNMP host "
+"!
+#
+# 53 54
+#
+Overwriting SNMP community "
+"!
+#
+# 55
+#
+Overwriting SNMP version!
+#
+# 56 57
+#
+Unknown SNMP version "
+"!
+#
+# 58 59
+#
+Overwriting receive timeout "
+"!
+#
+# 60 61
+#
+Overwriting send timeout "
+"!
+#
+# 62 63
+#
+Overwriting connect timeout "
+"!
+#
+# 64 65
+#
+Unknown configuration option "
+"!
+#
+# 66 67
+#
+Print host "
+" already exists!
+#
+# 68 69
+#
+Print host alias "
+" already exists!
+#
+# 70 71
+#
+Illegal encoding "
+" for LPD protocol!
+#
+# 72
+#
+Line outside scope, not belonging to printer or host!
+$!end
+};
+
+
+
+void
+dk3print_win_det_cleanup(dk3_printer_windows_details_t *ptr)
+{
+ $? "+ dk3print_win_det_cleanup"
+ if(ptr) {
+ }
+ $? "- dk3print_win_det_cleanup"
+}
+
+
+
+void
+dk3print_lprng_det_cleanup(dk3_printer_lprng_details_t *ptr)
+{
+ $? "+ dk3print_lprng_det_cleanup"
+ if(ptr) {
+ dk3_release(ptr->hostname);
+ dk3_release(ptr->queuename);
+ }
+ $? "- dk3print_lprng_det_cleanup"
+}
+
+
+
+void
+dk3print_socket_det_cleanup(dk3_printer_socket_t *ptr)
+{
+ $? "+ dk3print_socket_det_cleanup"
+ if(ptr) {
+ dk3_release(ptr->hostname);
+ ptr->portno = 0;
+ ptr->ordrel = 0x00;
+ }
+ $? "- dk3print_socket_det_cleanup"
+}
+
+
+
+void
+dk3print_det_cleanup(int tp, dk3_printer_details_t *ptr)
+{
+ $? "+ dk3print_det_cleanup"
+ if(ptr) {
+ switch(tp) {
+ case DK3_PRINTER_TYPE_WINDOWS: {
+ dk3print_win_det_cleanup(&(ptr->win));
+ } break;
+ case DK3_PRINTER_TYPE_SOCKET: {
+ dk3print_socket_det_cleanup(&(ptr->sock));
+ } break;
+ case DK3_PRINTER_TYPE_LPD: {
+ dk3print_lprng_det_cleanup(&(ptr->lprng));
+ } break;
+ case DK3_PRINTER_TYPE_LPRNG: {
+ dk3print_lprng_det_cleanup(&(ptr->lprng));
+ } break;
+ }
+ }
+ $? "- dk3print_det_cleanup"
+}
+
+
+
+void
+dk3print_printer_delete(dk3_printer_t *ptr)
+{
+ $? "+ dk3print_printer_delete"
+ if(ptr) {
+ dk3print_det_cleanup(ptr->t_p, &(ptr->det_p));
+ dk3print_det_cleanup(ptr->t_s, &(ptr->det_s));
+ dk3_release(ptr->name);
+ dk3_release(ptr->h_snmp);
+ dk3_release(ptr->c_snmp);
+ dk3_delete(ptr);
+ } $? "- dk3print_printer_delete"
+}
+
+
+
+dk3_printer_t *
+dk3print_printer_new(dk3_print_conf_t *pc, dkChar const *name)
+{
+ dk3_printer_t *back = NULL;
+ if((pc) && (name)) {
+ back =
+ (dk3_printer_t *)dk3sto_it_find_like(pc->iPrinters, (void *)name, 1);
+ if(!(back)) {
+ back = dk3_new_app(dk3_printer_t,1,pc->app);
+ if(back) {
+ back->name = NULL;
+ back->h_snmp = NULL;
+ back->c_snmp = 0;
+ back->t_p = DK3_PRINTER_TYPE_NONE;
+ back->t_s = DK3_PRINTER_TYPE_NONE;
+ back->v_snmp = DK3_SNMP_VERSION_UNKNOWN;
+ back->ps = 0;
+ back->name = dk3str_dup_app(name, pc->app);
+ if(back->name) {
+ if(!dk3sto_add(pc->sPrinters, back)) {
+ dk3print_printer_delete(back);
+ back = NULL;
+ }
+ } else {
+ dk3print_printer_delete(back);
+ back = NULL;
+ }
+ }
+ }
+ if(back) {
+ if(!(pc->defPrinter)) {
+ pc->defPrinter = back;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void
+dk3print_alias_delete(dk3_printer_alias_t *ptr)
+{
+ $? "+ dk3print_alias_delete"
+ if(ptr) {
+ dk3_release(ptr->name);
+ ptr->printer = NULL;
+ dk3_delete(ptr);
+ }
+ $? "- dk3print_alias_delete"
+}
+
+
+
+void
+dk3print_host_delete(dk3_print_host_t *ptr)
+{
+ $? "+ dk3print_host_delete"
+ if(ptr) {
+ dk3_release(ptr->name);
+ dk3_delete(ptr);
+ }
+ $? "- dk3print_host_delete"
+}
+
+
+
+dk3_print_host_t *
+dk3print_host_new(dk3_print_conf_t *pc, dkChar const *name)
+{
+ dk3_print_host_t *back = NULL;
+ if((pc) && (name)) {
+ back =
+ (dk3_print_host_t *)dk3sto_it_find_like(pc->iPrintHosts, (void *)name, 1);
+ if(!(back)) {
+ back = dk3_new_app(dk3_print_host_t,1,pc->app);
+ if(back) {
+ back->name = NULL;
+ /* Further initialization. */
+ back->to_c = -1.0;
+ back->to_r = -1.0;
+ back->to_s = -1.0;
+ back->enc = DK3_ENCODING_UTF8;
+ /* Save name. */
+ back->name = dk3str_dup_app(name, pc->app);
+ if(back->name) {
+ /* Add to configuration. */
+ if(!dk3sto_add(pc->sPrintHosts, back)) {
+ dk3print_host_delete(back);
+ back = NULL;
+ }
+ } else {
+ dk3print_host_delete(back);
+ back = NULL;
+ }
+ }
+ }
+ if(back) {
+ if(!(pc->defHost)) {
+ pc->defHost = back;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void
+dk3print_host_alias_delete(dk3_print_host_alias_t *ptr)
+{
+ $? "+ dk3print_host_alias_delete"
+ if(ptr) {
+ dk3_release(ptr->name);
+ ptr->host = NULL;
+ dk3_delete(ptr);
+ }
+ $? "- dk3print_host_alias_delete"
+}
+
+
+
+void
+dk3print_conf_delete(dk3_print_conf_t *pc)
+{
+ void *vptr; /* Current element to delete. */
+
+ $? "+ dk3print_conf_delete %!8s", TR_8PTR(pc)
+ if(pc) {
+ pc->defPrinter = NULL;
+ pc->defHost = NULL;
+ if(pc->sHostAliases) {
+ if(pc->iHostAliases) {
+ dk3sto_it_reset(pc->iHostAliases);
+ while(NULL != (vptr = dk3sto_it_next(pc->iHostAliases))) {
+ dk3print_host_alias_delete((dk3_print_host_alias_t *)vptr);
+ }
+ dk3sto_it_close(pc->iHostAliases);
+ }
+ dk3sto_close(pc->sHostAliases);
+ } pc->sHostAliases = NULL; pc->iHostAliases = NULL;
+ if(pc->sPrintHosts) {
+ if(pc->iPrintHosts) {
+ dk3sto_it_reset(pc->iPrintHosts);
+ while(NULL != (vptr = dk3sto_it_next(pc->iPrintHosts))) {
+ dk3print_host_delete((dk3_print_host_t *)vptr);
+ }
+ dk3sto_it_close(pc->iPrintHosts);
+ }
+ dk3sto_close(pc->sPrintHosts);
+ } pc->sPrintHosts = NULL; pc->iPrintHosts = NULL;
+ if(pc->sPrintAliases) {
+ if(pc->iPrintAliases) {
+ dk3sto_it_reset(pc->iPrintAliases);
+ while(NULL != (vptr = dk3sto_it_next(pc->iPrintAliases))) {
+ dk3print_alias_delete((dk3_printer_alias_t *)vptr);
+ }
+ dk3sto_it_close(pc->iPrintAliases);
+ }
+ dk3sto_close(pc->sPrintAliases);
+ } pc->sPrintAliases = NULL; pc->iPrintAliases = NULL;
+ if(pc->sPrinters) {
+ if(pc->iPrinters) {
+ dk3sto_it_reset(pc->iPrinters);
+ while(NULL != (vptr = dk3sto_it_next(pc->iPrinters))) {
+ dk3print_printer_delete((dk3_printer_t *)vptr);
+ }
+ dk3sto_it_close(pc->iPrinters);
+ }
+ dk3sto_close(pc->sPrinters);
+ } pc->sPrinters = NULL; pc->iPrinters = NULL;
+ pc->app = NULL;
+ pc->msg = NULL;
+ dk3_delete(pc);
+ } $? "- dk3print_conf_delete"
+}
+
+
+
+/** Compare two printers by name.
+ @param l Left object.
+ @param r Right object or name.
+ @param cr Comparison criteria (0=printer/printer, 1=printer/name).
+ @return Comparison result.
+*/
+static
+int
+dk3print_compare_printer(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3_printer_t const *pl; /* Pointer to left printer. */
+ dk3_printer_t const *pr; /* Pointer to right printer. */
+ dkChar const *n; /* Pointer to right name. */
+ if(l) {
+ if(r) {
+ pl = (dk3_printer_t const *)l;
+ switch(cr) {
+ case 1: {
+ n = (dkChar const *)r;
+ if(pl->name) {
+ back = dk3str_cmp(pl->name, n);
+ if(back < 0) back = -1;
+ if(back > 0) back = 1;
+ } else {
+ back = -1;
+ }
+ } break;
+ default: {
+ pr = (dk3_printer_t const *)r;
+ if(pl->name) {
+ if(pr->name) {
+ back = dk3str_cmp(pl->name, pr->name);
+ if(back < 0) back = -1;
+ if(back > 0) back = 1;
+ } else {
+ back = 1;
+ }
+ } else {
+ if(pr->name) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Compare two printer aliases by name.
+ @param l Left object.
+ @param r Right object or name.
+ @param cr Comparison criteria (0=alias/alias, 1=alias/name).
+ @return Comparison result.
+*/
+static
+int
+dk3print_compare_print_alias(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3_printer_alias_t const *pl; /* Left printer alias. */
+ dk3_printer_alias_t const *pr; /* Right printer alias. */
+ dkChar const *n; /* Right alias name. */
+ if(l) {
+ if(r) {
+ pl = (dk3_printer_alias_t const *)l;
+ switch(cr) {
+ case 1: {
+ n = (dkChar const *)r;
+ if(pl->name) {
+ back = dk3str_cmp(pl->name, n);
+ if(back < 0) back = -1;
+ if(back > 0) back = 1;
+ } else {
+ back = -1;
+ }
+ } break;
+ default: {
+ pr = (dk3_printer_alias_t const *)r;
+ if(pl->name) {
+ if(pr->name) {
+ back = dk3str_cmp(pl->name, pr->name);
+ if(back < 0) back = -1;
+ if(back > 0) back = 1;
+ } else {
+ back = 1;
+ }
+ } else {
+ if(pr->name) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Compare two print hosts by name.
+ @param l Left object.
+ @param r Right object or name.
+ @param cr Comparison criteria (0=host/host, 1=host/name).
+ @return Comparison result.
+*/
+static
+int
+dk3print_compare_host(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3_print_host_t const *pl; /* Left print host. */
+ dk3_print_host_t const *pr; /* Right print host. */
+ dkChar const *n; /* Right print host name. */
+ if(l) {
+ if(r) {
+ pl = (dk3_print_host_t const *)l;
+ switch(cr) {
+ case 1: {
+ n = (dkChar const *)r;
+ if(pl->name) {
+ back = dk3str_cmp(pl->name, n);
+ if(back < 0) back = -1;
+ if(back > 0) back = 1;
+ } else {
+ back = -1;
+ }
+ } break;
+ default: {
+ pr = (dk3_print_host_t const *)r;
+ if(pl->name) {
+ if(pr->name) {
+ back = dk3str_cmp(pl->name, pr->name);
+ if(back < 0) back = -1;
+ if(back > 0) back = 1;
+ } else {
+ back = 1;
+ }
+ } else {
+ if(pr->name) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Compare two print host aliases by name.
+ @param l Left object.
+ @param r Right object or name.
+ @param cr Comparison criteria (0=alias/alias, 1=alias/name).
+ @return Comparison result.
+*/
+static
+int
+dk3print_compare_host_alias(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3_print_host_alias_t const *pl; /* Left host alias. */
+ dk3_print_host_alias_t const *pr; /* Right host alias. */
+ dkChar const *n; /* Right alias name. */
+ if(l) {
+ if(r) {
+ pl = (dk3_print_host_alias_t const *)l;
+ switch(cr) {
+ case 1: {
+ n = (dkChar const *)r;
+ if(pl->name) {
+ back = dk3str_cmp(pl->name, n);
+ if(back < 0) back = -1;
+ if(back > 0) back = 1;
+ } else {
+ back = -1;
+ }
+ } break;
+ default: {
+ pr = (dk3_print_host_alias_t const *)r;
+ if(pl->name) {
+ if(pr->name) {
+ back = dk3str_cmp(pl->name, pr->name);
+ if(back < 0) back = -1;
+ if(back > 0) back = 1;
+ } else {
+ back = 1;
+ }
+ } else {
+ if(pr->name) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+dk3_print_conf_t *
+dk3print_config_new(dk3_app_t *app)
+{
+ dk3_print_conf_t *back = NULL;
+ int ok = 0; /* Flag: Success. */
+ $? "+ dk3print_config_new"
+ if(app) {
+ back = dk3_new_app(dk3_print_conf_t,1,app);
+ if(back) {
+ /* Initialize members. */
+ back->sPrinters = NULL; back->iPrinters = NULL;
+ back->sPrintAliases = NULL; back->iPrintAliases = NULL;
+ back->sPrintHosts = NULL; back->iPrintHosts = NULL;
+ back->defPrinter = NULL;
+ back->defHost = NULL;
+ back->defPsl = 3;
+ back->app = app;
+ back->msg = dk3app_messages(app, dk3print_nl[1], dk3print_msg);
+ if(!(back->msg)) { back->msg = dk3print_msg; }
+ /* Allocate resources for storages. */
+ back->sPrinters = dk3sto_open_app(app);
+ if(back->sPrinters) {
+ dk3sto_set_comp(back->sPrinters, dk3print_compare_printer, 0);
+ back->iPrinters = dk3sto_it_open(back->sPrinters);
+ if(back->iPrinters) {
+ back->sPrintAliases = dk3sto_open_app(app);
+ if(back->sPrintAliases) {
+ dk3sto_set_comp(back->sPrintAliases,dk3print_compare_print_alias,0);
+ back->iPrintAliases = dk3sto_it_open(back->sPrintAliases);
+ if(back->iPrintAliases) {
+ back->sPrintHosts = dk3sto_open_app(app);
+ if(back->sPrintHosts) {
+ dk3sto_set_comp(back->sPrintHosts, dk3print_compare_host, 0);
+ back->iPrintHosts = dk3sto_it_open(back->sPrintHosts);
+ if(back->iPrintHosts) {
+ back->sHostAliases = dk3sto_open_app(app);
+ if(back->sHostAliases) {
+ dk3sto_set_comp(
+ back->sHostAliases, dk3print_compare_host_alias, 0
+ );
+ back->iHostAliases = dk3sto_it_open(back->sHostAliases);
+ if(back->iHostAliases) {
+ ok = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ /* Destroy configuration if allocations failed. */
+ if(!(ok)) {
+ dk3print_conf_delete(back);
+ back = NULL;
+ }
+ }
+ } $? "- dk3print_config_new %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+#if DK3_ON_WINDOWS
+
+/** Check whether a printer name contains the words
+ "PostScript" or "PS".
+ @param pc Print configuration to set up.
+ @param pr Printer structure to modify.
+ @param str Printer string to check.
+*/
+static
+void
+dk3print_check_postscript(
+ dk3_print_conf_t *pc,
+ dk3_printer_t *pr,
+ dkChar const *str
+)
+{
+ dkChar buf[DK3_MAX_PATH]; /* Private copy. */
+ dkChar *c; /* Current string. */
+ dkChar *n; /* Next string. */
+
+ if(!(pr->ps)) {
+ if(dk3str_len(str) < DK3_SIZEOF(buf,dkChar)) {
+ dk3str_cpy_not_overlapped(buf, str);
+ c = dk3str_start(buf, NULL);
+ while(c) {
+ n = dk3str_next(c, NULL);
+ if(dk3str_cmp(c, dk3print_nl[2]) == 0) {
+ pr->ps = pc->defPsl;
+ } else {
+ if(dk3str_casecmp(c, dk3print_nl[3]) == 0) {
+ pr->ps = pc->defPsl;
+ }
+ }
+ c = n;
+ }
+ }
+ if(!(pr->ps)) {
+ if(dk3str_casecmp(str, dk3print_nl[4]) == 0) {
+ pr->ps = pc->defPsl;
+ }
+ }
+ }
+}
+
+#endif
+
+
+
+#if DK3_ON_WINDOWS
+/* + Windows */
+
+/** Read printer information from system.
+ @param pc Print configuration to set up.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3print_read_system(dk3_print_conf_t *pc)
+{
+ dkChar buf[1024]; /* Default printer name. */
+ char *peb; /* Result buffer. */
+#if DK3_CHAR_SIZE > 1
+ PRINTER_INFO_2W *pi2; /* Printer information. */
+#else
+ PRINTER_INFO_2A *pi2; /* Printer information. */
+#endif
+ dk3_printer_t *printer; /* New printer to create. */
+ DWORD cbNeeded; /* Bytes needed. */
+ DWORD cbReturned; /* Bytes returned. */
+ DWORD szPeb; /* Size of peb. */
+ DWORD i; /* Index of current information. */
+ DWORD dwSz; /* Buffer size. */
+ BOOL res; /* Operation result. */
+ int back = 1;
+ $? "+ dk3print_read_system (Windows 16-bit)"
+ cbNeeded = cbReturned = szPeb = (DWORD)0UL;
+#if DK3_CHAR_SIZE > 1
+ EnumPrintersW(PRINTER_ENUM_LOCAL,NULL,2,NULL,szPeb,&cbNeeded,&cbReturned);
+#else
+ EnumPrintersA(PRINTER_ENUM_LOCAL,NULL,2,NULL,szPeb,&cbNeeded,&cbReturned);
+#endif
+ if(cbNeeded > 0) {
+ szPeb = cbNeeded;
+ peb = dk3_new_app(char,(size_t)cbNeeded,pc->app);
+ if(peb) {
+ cbNeeded = cbReturned = (DWORD)0UL;
+#if DK3_CHAR_SIZE > 1
+ res = EnumPrintersW(
+ PRINTER_ENUM_LOCAL,NULL,2,(LPBYTE)peb,szPeb,&cbNeeded,&cbReturned
+ );
+#else
+ res = EnumPrintersA(
+ PRINTER_ENUM_LOCAL,NULL,2,(LPBYTE)peb,szPeb,&cbNeeded,&cbReturned
+ );
+#endif
+ if(res) {
+ if((DWORD)0UL < cbReturned) {
+ pi2 = (PRINTER_INFO_2 *)peb;
+ for(i = (DWORD)0UL; i < cbReturned; i++) {
+ printer = dk3print_printer_new(pc, pi2->pPrinterName);
+ if(printer) {
+ printer->t_p = DK3_PRINTER_TYPE_WINDOWS;
+ if(pi2->pDriverName) {
+ dk3print_check_postscript(pc, printer, pi2->pDriverName);
+ }
+ if(pi2->pComment) {
+ dk3print_check_postscript(pc, printer, pi2->pComment);
+ }
+ } else {
+ back = 0;
+ }
+ pi2++;
+ }
+ } else { $? ". no printers found"
+ }
+ } else { $? "! printer enumeration failed"
+ back = 0;
+ }
+ dk3_delete(peb);
+ } else { $? "! memory"
+ back = 0;
+ }
+ if(back) {
+ dwSz = (DWORD)DK3_SIZEOF(buf,dkChar) ;
+#if DK3_CHAR_SIZE > 1
+ res = GetDefaultPrinterW(buf, &dwSz);
+#else
+ res = GetDefaultPrinterA(buf, &dwSz);
+#endif
+ if(res) {
+ if(dwSz > (DWORD)0UL) {
+ if(dwSz < DK3_SIZEOF(buf,dkChar)) {
+ buf[dwSz - 1] = dkT('\0');
+ printer =
+ (dk3_printer_t *)dk3sto_it_find_like(pc->iPrinters, (void *)buf, 1);
+ if(printer) {
+ pc->defPrinter = printer;
+ }
+ }
+ }
+ }
+ }
+ } else { $? ". no local printers"
+ }
+ $? "- dk3print_read_system %d", back
+ return back;
+}
+
+/* - Windows */
+
+#else
+/* + non-Windows */
+
+/** Read printer information from system.
+ @param pc Print configuration to set up.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3print_read_system(dk3_print_conf_t *pc)
+{
+ int back = 1;
+ $? "+ dk3print_read_system (UNIX)"
+ /* ##### Read /etc/printcap */
+ $? "- dk3print_read_system %d", back
+ return back;
+}
+
+/* - non-Windows */
+#endif
+
+
+/** Read print configuration data from system and/or configuration files.
+ @param pc Print configuration to set up.
+ @param useConfigFiles Flag: Use dk3print conf files.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3print_read_configuration(dk3_print_conf_t *pc, int useConfigFiles)
+{
+ dkChar buf[512]; /* Buffer used for values in diagnostics. */
+ int i; /* Temporary conversion result (PS level). */
+ int back = 0;
+
+ $? "+ dk3print_read_configuration"
+ /* Find default PS level from preferences */
+ if(pc->app) {
+ if(dk3app_get_pref(pc->app, dk3print_nl[5], buf, DK3_SIZEOF(buf,dkChar))) {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(buf, dk3print_nl[6], &i) == 1)
+#else
+ if (0 != dk3ma_i_from_string(&i, buf, NULL))
+#endif
+ {
+ if((2 <= i) && (3 >= i)) {
+ pc->defPsl = i;
+ } else {
+ /* ERROR: PS level out of range! */
+ dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 49, 50, buf);
+ }
+ } else {
+ /* ERROR: PS level not numeric! */
+ dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 49, 50, buf);
+ }
+ }
+ }
+ /* Read system printers and configuration files. */
+ if(dk3print_read_system(pc)) {
+ if(useConfigFiles) {
+ if(dk3print_read_config_files(pc)) {
+ back = 1;
+ }
+ } else {
+ back = 1;
+ }
+ } $? "- dk3print_read_configuration %d", back
+ return back;
+}
+
+
+
+dk3_print_conf_t *
+dk3print_conf_open(dk3_app_t *app, int useConfigFiles)
+{
+ dk3_print_conf_t *back = NULL;
+ $? "+ dk3print_conf_open"
+ if(app) {
+ back = dk3print_config_new(app);
+ if(back) {
+ if(!dk3print_read_configuration(back, useConfigFiles)) {
+ dk3print_conf_delete(back);
+ back = NULL;
+ }
+ }
+ } $? "- dk3print_conf_open %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+void
+dk3print_conf_close(dk3_print_conf_t *pc)
+{
+ $? "+ dk3print_conf_close"
+ if(pc) {
+ dk3print_conf_delete(pc);
+ } $? "- dk3print_conf_close"
+}
+
+
+
+void
+dk3print_set_det(dk3_printer_details_t *det, int tp)
+{
+ $? "+ dk3print_set_det"
+ if(det) {
+ switch(tp) {
+ case DK3_PRINTER_TYPE_WINDOWS: {
+ (det->win).dummy = 0;
+ } break;
+ case DK3_PRINTER_TYPE_SOCKET: {
+ (det->sock).hostname = NULL;
+ (det->sock).portno = 0;
+ (det->sock).ordrel = 0x00;
+ (det->sock).to_c = -1.0;
+ (det->sock).to_r = -1.0;
+ (det->sock).to_s = -1.0;
+ } break;
+ case DK3_PRINTER_TYPE_LPD: case DK3_PRINTER_TYPE_LPRNG: {
+ (det->lprng).hostname = NULL;
+ (det->lprng).queuename = NULL;
+ (det->lprng).to_c = -1.0;
+ (det->lprng).to_r = -1.0;
+ (det->lprng).to_s = -1.0;
+ } break;
+ default: {
+ } break;
+ }
+ } $? "- dk3print_set_det"
+}
+
+
+
+dk3_printer_t *
+dk3print_get_printer(dk3_print_conf_t *pc, dkChar const *pn)
+{
+ dk3_printer_t *back = NULL;
+ dk3_printer_alias_t *al = NULL; /* Alias for printer. */
+
+ if((pc) && (pn)) {
+ back = (dk3_printer_t *)dk3sto_it_find_like(pc->iPrinters, (void *)pn, 1);
+ if(!(back)) {
+ al = (dk3_printer_alias_t *)dk3sto_it_find_like(
+ pc->iPrintAliases, (void *)pn, 1
+ );
+ if(al) {
+ back = al->printer;
+ }
+ }
+ }
+ return back;
+}
+
+
+dk3_print_host_t *
+dk3print_get_host(dk3_print_conf_t *pc, dkChar const *hn)
+{
+ dk3_print_host_t *back = NULL;
+ dk3_print_host_alias_t *al = NULL; /* Alias for host. */
+
+ if((pc) && (hn)) {
+ back = (dk3_print_host_t *)dk3sto_it_find_like(
+ pc->iPrintHosts, (void *)hn, 1
+ );
+ if(!(back)) {
+ al = (dk3_print_host_alias_t *)dk3sto_it_find_like(
+ pc->iHostAliases, (void *)hn, 1
+ );
+ if(al) {
+ back = al->host;
+ }
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk3print.h b/support/dktools/dk3print.h
new file mode 100644
index 0000000000..47fcd15b80
--- /dev/null
+++ b/support/dktools/dk3print.h
@@ -0,0 +1,172 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3print.ctr
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3print.h Header file for the dk3print module.
+*/
+
+#ifndef DK3PRINT_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3PRINT_H_INCLUDED 1
+
+
+#line 9 "dk3print.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Clean up details for Windows printer.
+ @param ptr Details to clean up.
+*/
+void
+dk3print_win_det_cleanup(dk3_printer_windows_details_t *ptr);
+
+/** Clean up details for LPRng/LPD printer.
+ @param ptr Details to clean up.
+*/
+void
+dk3print_lprng_det_cleanup(dk3_printer_lprng_details_t *ptr);
+
+/** Clean up details for socket printer.
+ @param ptr Details to clean up.
+*/
+void
+dk3print_socket_det_cleanup(dk3_printer_socket_t *ptr);
+
+/** Clean up type-specific details for a printer.
+ @param tp Printer type.
+ @param ptr Pointer to details data.
+*/
+void
+dk3print_det_cleanup(int tp, dk3_printer_details_t *ptr);
+
+/** Create new printer entry if necessary.
+ @param pc Print configuration to set up.
+ @param name Printer name.
+ @return Pointer to new or existing printer entry on success,
+ NULL on error.
+*/
+dk3_printer_t *
+dk3print_printer_new(dk3_print_conf_t *pc, dkChar const *name);
+
+/** Destroy printer entry in print configuration, release memory.
+ @param ptr Printer entry to destroy.
+*/
+void
+dk3print_printer_delete(dk3_printer_t *ptr);
+
+/** Destroy printer alias entry in print configuration, release memory.
+ @param ptr Alias to destroy.
+*/
+void
+dk3print_alias_delete(dk3_printer_alias_t *ptr);
+
+/** Create new print host entry if necessary.
+ @param pc Print configuration to set up.
+ @param name Print host name.
+ @return Pointer to new or existing printer entry on success,
+ NULL on error.
+*/
+dk3_print_host_t *
+dk3print_host_new(dk3_print_conf_t *pc, dkChar const *name);
+
+/** Destroy print host entry in print configuration, release memory.
+ @param ptr Print host entry to destroy.
+*/
+void
+dk3print_host_delete(dk3_print_host_t *ptr);
+
+/** Destroy print host alias entry in print configuration, release memory.
+ @param ptr Alias to destroy.
+*/
+void
+dk3print_host_alias_delete(dk3_print_host_alias_t *ptr);
+
+/** Destroy print configuration, release resources.
+ @param pc Print configuration to destroy.
+*/
+void
+dk3print_conf_delete(dk3_print_conf_t *pc);
+
+/** Create new print configuration, allocate resources for storages.
+ @param app Application structur, must not be NULL.
+ @return Pointer to new configuration on success, NULL on error.
+*/
+dk3_print_conf_t *
+dk3print_config_new(dk3_app_t *app);
+
+/** Create new print configuration, initialize it from configuration files.
+ @param app Application structure, must not be NULL.
+ @param useConfigFiles Flag: Use dk3print configuration files.
+ @return Pointer to new configuration on success, NULL on error.
+*/
+dk3_print_conf_t *
+dk3print_conf_open(dk3_app_t *app, int useConfigFiles);
+
+/** Close print configuration.
+ @param pc Print configuration to close.
+*/
+void
+dk3print_conf_close(dk3_print_conf_t *pc);
+
+/** Initialize details based on print queue type.
+ @param det Details to initialize.
+ @param tp Print queue type.
+*/
+void
+dk3print_set_det(dk3_printer_details_t *det, int tp);
+
+/** Find named printer (either directly or via alias).
+ @param pc Print configuration.
+ @param pn Printer name.
+ @return Pointer to printer on success, NULL on error (not found).
+*/
+dk3_printer_t *
+dk3print_get_printer(dk3_print_conf_t *pc, dkChar const *pn);
+
+/** Find named print host (either directly or via alias).
+ @param pc Print configuration.
+ @param hn Host name.
+ @return Pointer to print host on success, NULL on error (not found).
+*/
+dk3_print_host_t *
+dk3print_get_host(dk3_print_conf_t *pc, dkChar const *hn);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk3prreq.c b/support/dktools/dk3prreq.c
new file mode 100644
index 0000000000..5c12f7a039
--- /dev/null
+++ b/support/dktools/dk3prreq.c
@@ -0,0 +1,298 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3prreq.ctr
+*/
+
+/** @file dk3prreq.c The dk3prreq module.
+*/
+
+
+#line 20 "dk3prreq.ctr"
+
+
+#include "dk3all.h"
+#include "dk3print.h"
+#include "dk3prcfg.h"
+#include "dk3prreq.h"
+
+
+
+/** Report printer details found.
+ @param pc Print configuration.
+ @param det Details for current printer.
+ @param pr Current printer to process.
+ @param tp Current printer type.
+ @param isprim Flag: Reporting primary details.
+*/
+static
+void
+dk3prreq_details_report(
+ dk3_print_conf_t *pc,
+ dk3_printer_details_t *det,
+ dk3_printer_t *pr,
+ int tp,
+ int isprim
+)
+{
+ dkChar buf[16]; /* Buffer for numeric values. */
+ int isdefault = 0; /* Flag: This is the default printer. */
+ int res; /* Result from conv to string. */
+
+ /* Type */
+ dk3sf_fputs((pc->msg)[3], stdout);
+ switch(tp) {
+ case DK3_PRINTER_TYPE_WINDOWS: {
+ dk3sf_fputs((pc->msg)[17], stdout);
+ } break;
+ case DK3_PRINTER_TYPE_SOCKET: {
+ dk3sf_fputs((pc->msg)[18], stdout);
+ } break;
+ case DK3_PRINTER_TYPE_LPD: {
+ dk3sf_fputs((pc->msg)[19], stdout);
+ } break;
+ case DK3_PRINTER_TYPE_LPRNG: {
+ dk3sf_fputs((pc->msg)[20], stdout);
+ } break;
+ default: {
+ dk3sf_fputs((pc->msg)[16], stdout);
+ } break;
+ }
+ dk3sf_fputc(dkT('\n'), stdout);
+ /* Default */
+ if(isprim) {
+ if(pc->defPrinter) {
+ if(dk3str_cmp((pc->defPrinter)->name, pr->name) == 0) {
+ isdefault = 1;
+ dk3sf_fputs((pc->msg)[11], stdout);
+ dk3sf_fputs((pc->msg)[21], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ }
+ }
+ /* PS level */
+ if(isprim) {
+ if(pr->ps) {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sprintf3(buf,dkT("%d"),pr->ps))
+#else
+ if(0 != dk3ma_im_to_string(buf,DK3_SIZEOF(buf,dkChar),(dk3_im_t)(pr->ps)))
+#endif
+ {
+ dk3sf_fputs((pc->msg)[10], stdout);
+ dk3sf_fputs(buf, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ }
+ }
+ /* Specific details */
+ switch(tp) {
+ case DK3_PRINTER_TYPE_WINDOWS: {
+ } break;
+ case DK3_PRINTER_TYPE_SOCKET: {
+ /* Host name */
+ dk3sf_fputs((pc->msg)[4], stdout);
+ if((det->sock).hostname) {
+ dk3sf_fputs((det->sock).hostname, stdout);
+ } else {
+ dk3sf_fputs((pc->msg)[16], stdout);
+ }
+ dk3sf_fputc(dkT('\n'), stdout);
+ /* Port number */
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sprintf3(buf,dkT("%u"),(unsigned)((det->sock).portno)))
+#else
+ res = dk3ma_um_to_string(
+ buf, DK3_SIZEOF(buf,dkChar), (dk3_um_t)((det->sock).portno)
+ );
+ if (0 != res)
+#endif
+ {
+ dk3sf_fputs((pc->msg)[7], stdout);
+ dk3sf_fputs(buf, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ /* Orderly release */
+ dk3sf_fputs((pc->msg)[15], stdout);
+ dk3sf_fputs((pc->msg)[((det->sock).ordrel) ? 21 : 22], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ /* Connect timeout */
+ if((det->sock).to_c > 0.0) {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sprintf3(buf,dkT("%g"), (det->sock).to_c))
+#else
+ if (0 != dk3ma_d_to_string(buf,DK3_SIZEOF(buf,dkChar),(det->sock).to_c))
+#endif
+ {
+ dk3sf_fputs((pc->msg)[7], stdout);
+ dk3sf_fputs(buf, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ }
+ /* Send timeout */
+ if((det->sock).to_s > 0.0) {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sprintf3(buf,dkT("%g"), (det->sock).to_s))
+#else
+ if (0 != dk3ma_d_to_string(buf,DK3_SIZEOF(buf,dkChar),(det->sock).to_s))
+#endif
+ {
+ dk3sf_fputs((pc->msg)[8], stdout);
+ dk3sf_fputs(buf, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ }
+ /* Receive timeout */
+ if((det->sock).to_r > 0.0) {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sprintf3(buf,dkT("%g"), (det->sock).to_r))
+#else
+ if (0 != dk3ma_d_to_string(buf,DK3_SIZEOF(buf,dkChar),(det->sock).to_r))
+#endif
+ {
+ dk3sf_fputs((pc->msg)[9], stdout);
+ dk3sf_fputs(buf, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ }
+ } break;
+ case DK3_PRINTER_TYPE_LPD: case DK3_PRINTER_TYPE_LPRNG: {
+ /* Host name */
+ dk3sf_fputs((pc->msg)[4], stdout);
+ if((det->lprng).hostname) {
+ dk3sf_fputs((det->lprng).hostname, stdout);
+ } else {
+ dk3sf_fputs((pc->msg)[16], stdout);
+ }
+ dk3sf_fputc(dkT('\n'), stdout);
+ /* Queue name */
+ dk3sf_fputs((pc->msg)[5], stdout);
+ if((det->lprng).queuename) {
+ dk3sf_fputs((det->lprng).queuename, stdout);
+ } else {
+ dk3sf_fputs((pc->msg)[16], stdout);
+ }
+ dk3sf_fputc(dkT('\n'), stdout);
+ /* Connect timeout */
+ if((det->lprng).to_c > 0.0) {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sprintf3(buf,dkT("%g"), (det->lprng).to_c))
+#else
+ if(0 != dk3ma_d_to_string(buf,DK3_SIZEOF(buf,dkChar),(det->lprng).to_c))
+#endif
+ {
+ dk3sf_fputs((pc->msg)[7], stdout);
+ dk3sf_fputs(buf, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ }
+ /* Send timeout */
+ if((det->lprng).to_s > 0.0) {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sprintf3(buf,dkT("%g"), (det->lprng).to_s))
+#else
+ if(0 != dk3ma_d_to_string(buf,DK3_SIZEOF(buf,dkChar),(det->lprng).to_s))
+#endif
+ {
+ dk3sf_fputs((pc->msg)[8], stdout);
+ dk3sf_fputs(buf, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ }
+ /* Receive timeout */
+ if((det->lprng).to_r > 0.0) {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sprintf3(buf,dkT("%g"), (det->lprng).to_r))
+#else
+ if(0 != dk3ma_d_to_string(buf,DK3_SIZEOF(buf,dkChar),(det->lprng).to_r))
+#endif
+ {
+ dk3sf_fputs((pc->msg)[9], stdout);
+ dk3sf_fputs(buf, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ }
+ } break;
+ }
+ if(isprim) {
+ if((pr->h_snmp) || (pr->c_snmp) || (DK3_SNMP_VERSION_UNKNOWN != pr->v_snmp))
+ {
+ /* SNMP host */
+ dk3sf_fputs((pc->msg)[12], stdout);
+ if(pr->h_snmp) {
+ dk3sf_fputs(pr->h_snmp, stdout);
+ } else {
+ dk3sf_fputs((pc->msg)[16], stdout);
+ }
+ dk3sf_fputc(dkT('\n'), stdout);
+ /* SNMP version */
+ dk3sf_fputs((pc->msg)[14], stdout);
+ switch(pr->v_snmp) {
+ case DK3_SNMP_VERSION_1: {
+ dk3sf_fputs((pc->msg)[23], stdout);
+ } break;
+ case DK3_SNMP_VERSION_2C: {
+ dk3sf_fputs((pc->msg)[24], stdout);
+ } break;
+ case DK3_SNMP_VERSION_2P: {
+ dk3sf_fputs((pc->msg)[25], stdout);
+ } break;
+ case DK3_SNMP_VERSION_3: {
+ dk3sf_fputs((pc->msg)[26], stdout);
+ } break;
+ default: {
+ dk3sf_fputs((pc->msg)[16], stdout);
+ } break;
+ }
+ dk3sf_fputc(dkT('\n'), stdout);
+ /* SNMP community */
+ dk3sf_fputs((pc->msg)[13], stdout);
+ if(pr->c_snmp) {
+ dk3sf_fputs(pr->c_snmp, stdout);
+ } else {
+ dk3sf_fputs((pc->msg)[16], stdout);
+ }
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ }
+}
+
+
+
+void
+dk3prreq_report(dk3_print_conf_t *pc)
+{
+ void *vptr; /* Current printer from iterator. */
+ dk3_printer_t *pr; /* Current printer. */
+ int isfirst = 1; /* Flag: Current is first to show. */
+
+ dk3sf_initialize_stdout();
+ dk3sto_it_reset(pc->iPrinters);
+ while(NULL != (vptr = dk3sto_it_next(pc->iPrinters))) {
+ pr = (dk3_printer_t *)vptr;
+ if(isfirst) {
+ isfirst = 0;
+ } else {
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ /* Printer name */
+ dk3sf_fputs((pc->msg)[0], stdout);
+ dk3sf_fputc(dkT(' '), stdout);
+ dk3sf_fputs(pr->name, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ /* Primary data */
+ dk3sf_fputs((pc->msg)[1], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ dk3prreq_details_report(pc, &(pr->det_p), pr, pr->t_p, 1);
+ if(DK3_PRINTER_TYPE_WINDOWS == pr->t_p) {
+ if(DK3_PRINTER_TYPE_NONE != pr->t_s) {
+ dk3sf_fputs((pc->msg)[2], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ dk3prreq_details_report(pc, &(pr->det_s), pr, pr->t_s, 0);
+ }
+ }
+ }
+}
+
+
diff --git a/support/dktools/dk3prreq.ctr b/support/dktools/dk3prreq.ctr
new file mode 100644
index 0000000000..8fb1a04944
--- /dev/null
+++ b/support/dktools/dk3prreq.ctr
@@ -0,0 +1,305 @@
+%% options
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Report all printers found in the current configuration.
+ @param pc Print configuration.
+*/
+void
+dk3prreq_report(dk3_print_conf_t *pc);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+
+#include "dk3all.h"
+#include "dk3print.h"
+#include "dk3prcfg.h"
+#include "dk3prreq.h"
+
+
+
+/** Report printer details found.
+ @param pc Print configuration.
+ @param det Details for current printer.
+ @param pr Current printer to process.
+ @param tp Current printer type.
+ @param isprim Flag: Reporting primary details.
+*/
+static
+void
+dk3prreq_details_report(
+ dk3_print_conf_t *pc,
+ dk3_printer_details_t *det,
+ dk3_printer_t *pr,
+ int tp,
+ int isprim
+)
+{
+ dkChar buf[16]; /* Buffer for numeric values. */
+ int isdefault = 0; /* Flag: This is the default printer. */
+ int res; /* Result from conv to string. */
+
+ /* Type */
+ dk3sf_fputs((pc->msg)[3], stdout);
+ switch(tp) {
+ case DK3_PRINTER_TYPE_WINDOWS: {
+ dk3sf_fputs((pc->msg)[17], stdout);
+ } break;
+ case DK3_PRINTER_TYPE_SOCKET: {
+ dk3sf_fputs((pc->msg)[18], stdout);
+ } break;
+ case DK3_PRINTER_TYPE_LPD: {
+ dk3sf_fputs((pc->msg)[19], stdout);
+ } break;
+ case DK3_PRINTER_TYPE_LPRNG: {
+ dk3sf_fputs((pc->msg)[20], stdout);
+ } break;
+ default: {
+ dk3sf_fputs((pc->msg)[16], stdout);
+ } break;
+ }
+ dk3sf_fputc(dkT('\n'), stdout);
+ /* Default */
+ if(isprim) {
+ if(pc->defPrinter) {
+ if(dk3str_cmp((pc->defPrinter)->name, pr->name) == 0) {
+ isdefault = 1;
+ dk3sf_fputs((pc->msg)[11], stdout);
+ dk3sf_fputs((pc->msg)[21], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ }
+ }
+ /* PS level */
+ if(isprim) {
+ if(pr->ps) {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sprintf3(buf,dkT("%d"),pr->ps))
+#else
+ if(0 != dk3ma_im_to_string(buf,DK3_SIZEOF(buf,dkChar),(dk3_im_t)(pr->ps)))
+#endif
+ {
+ dk3sf_fputs((pc->msg)[10], stdout);
+ dk3sf_fputs(buf, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ }
+ }
+ /* Specific details */
+ switch(tp) {
+ case DK3_PRINTER_TYPE_WINDOWS: {
+ } break;
+ case DK3_PRINTER_TYPE_SOCKET: {
+ /* Host name */
+ dk3sf_fputs((pc->msg)[4], stdout);
+ if((det->sock).hostname) {
+ dk3sf_fputs((det->sock).hostname, stdout);
+ } else {
+ dk3sf_fputs((pc->msg)[16], stdout);
+ }
+ dk3sf_fputc(dkT('\n'), stdout);
+ /* Port number */
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sprintf3(buf,dkT("%u"),(unsigned)((det->sock).portno)))
+#else
+ res = dk3ma_um_to_string(
+ buf, DK3_SIZEOF(buf,dkChar), (dk3_um_t)((det->sock).portno)
+ );
+ if (0 != res)
+#endif
+ {
+ dk3sf_fputs((pc->msg)[7], stdout);
+ dk3sf_fputs(buf, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ /* Orderly release */
+ dk3sf_fputs((pc->msg)[15], stdout);
+ dk3sf_fputs((pc->msg)[((det->sock).ordrel) ? 21 : 22], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ /* Connect timeout */
+ if((det->sock).to_c > 0.0) {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sprintf3(buf,dkT("%g"), (det->sock).to_c))
+#else
+ if (0 != dk3ma_d_to_string(buf,DK3_SIZEOF(buf,dkChar),(det->sock).to_c))
+#endif
+ {
+ dk3sf_fputs((pc->msg)[7], stdout);
+ dk3sf_fputs(buf, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ }
+ /* Send timeout */
+ if((det->sock).to_s > 0.0) {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sprintf3(buf,dkT("%g"), (det->sock).to_s))
+#else
+ if (0 != dk3ma_d_to_string(buf,DK3_SIZEOF(buf,dkChar),(det->sock).to_s))
+#endif
+ {
+ dk3sf_fputs((pc->msg)[8], stdout);
+ dk3sf_fputs(buf, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ }
+ /* Receive timeout */
+ if((det->sock).to_r > 0.0) {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sprintf3(buf,dkT("%g"), (det->sock).to_r))
+#else
+ if (0 != dk3ma_d_to_string(buf,DK3_SIZEOF(buf,dkChar),(det->sock).to_r))
+#endif
+ {
+ dk3sf_fputs((pc->msg)[9], stdout);
+ dk3sf_fputs(buf, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ }
+ } break;
+ case DK3_PRINTER_TYPE_LPD: case DK3_PRINTER_TYPE_LPRNG: {
+ /* Host name */
+ dk3sf_fputs((pc->msg)[4], stdout);
+ if((det->lprng).hostname) {
+ dk3sf_fputs((det->lprng).hostname, stdout);
+ } else {
+ dk3sf_fputs((pc->msg)[16], stdout);
+ }
+ dk3sf_fputc(dkT('\n'), stdout);
+ /* Queue name */
+ dk3sf_fputs((pc->msg)[5], stdout);
+ if((det->lprng).queuename) {
+ dk3sf_fputs((det->lprng).queuename, stdout);
+ } else {
+ dk3sf_fputs((pc->msg)[16], stdout);
+ }
+ dk3sf_fputc(dkT('\n'), stdout);
+ /* Connect timeout */
+ if((det->lprng).to_c > 0.0) {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sprintf3(buf,dkT("%g"), (det->lprng).to_c))
+#else
+ if(0 != dk3ma_d_to_string(buf,DK3_SIZEOF(buf,dkChar),(det->lprng).to_c))
+#endif
+ {
+ dk3sf_fputs((pc->msg)[7], stdout);
+ dk3sf_fputs(buf, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ }
+ /* Send timeout */
+ if((det->lprng).to_s > 0.0) {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sprintf3(buf,dkT("%g"), (det->lprng).to_s))
+#else
+ if(0 != dk3ma_d_to_string(buf,DK3_SIZEOF(buf,dkChar),(det->lprng).to_s))
+#endif
+ {
+ dk3sf_fputs((pc->msg)[8], stdout);
+ dk3sf_fputs(buf, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ }
+ /* Receive timeout */
+ if((det->lprng).to_r > 0.0) {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sprintf3(buf,dkT("%g"), (det->lprng).to_r))
+#else
+ if(0 != dk3ma_d_to_string(buf,DK3_SIZEOF(buf,dkChar),(det->lprng).to_r))
+#endif
+ {
+ dk3sf_fputs((pc->msg)[9], stdout);
+ dk3sf_fputs(buf, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ }
+ } break;
+ }
+ if(isprim) {
+ if((pr->h_snmp) || (pr->c_snmp) || (DK3_SNMP_VERSION_UNKNOWN != pr->v_snmp))
+ {
+ /* SNMP host */
+ dk3sf_fputs((pc->msg)[12], stdout);
+ if(pr->h_snmp) {
+ dk3sf_fputs(pr->h_snmp, stdout);
+ } else {
+ dk3sf_fputs((pc->msg)[16], stdout);
+ }
+ dk3sf_fputc(dkT('\n'), stdout);
+ /* SNMP version */
+ dk3sf_fputs((pc->msg)[14], stdout);
+ switch(pr->v_snmp) {
+ case DK3_SNMP_VERSION_1: {
+ dk3sf_fputs((pc->msg)[23], stdout);
+ } break;
+ case DK3_SNMP_VERSION_2C: {
+ dk3sf_fputs((pc->msg)[24], stdout);
+ } break;
+ case DK3_SNMP_VERSION_2P: {
+ dk3sf_fputs((pc->msg)[25], stdout);
+ } break;
+ case DK3_SNMP_VERSION_3: {
+ dk3sf_fputs((pc->msg)[26], stdout);
+ } break;
+ default: {
+ dk3sf_fputs((pc->msg)[16], stdout);
+ } break;
+ }
+ dk3sf_fputc(dkT('\n'), stdout);
+ /* SNMP community */
+ dk3sf_fputs((pc->msg)[13], stdout);
+ if(pr->c_snmp) {
+ dk3sf_fputs(pr->c_snmp, stdout);
+ } else {
+ dk3sf_fputs((pc->msg)[16], stdout);
+ }
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ }
+}
+
+
+
+void
+dk3prreq_report(dk3_print_conf_t *pc)
+{
+ void *vptr; /* Current printer from iterator. */
+ dk3_printer_t *pr; /* Current printer. */
+ int isfirst = 1; /* Flag: Current is first to show. */
+
+ dk3sf_initialize_stdout();
+ dk3sto_it_reset(pc->iPrinters);
+ while(NULL != (vptr = dk3sto_it_next(pc->iPrinters))) {
+ pr = (dk3_printer_t *)vptr;
+ if(isfirst) {
+ isfirst = 0;
+ } else {
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ /* Printer name */
+ dk3sf_fputs((pc->msg)[0], stdout);
+ dk3sf_fputc(dkT(' '), stdout);
+ dk3sf_fputs(pr->name, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ /* Primary data */
+ dk3sf_fputs((pc->msg)[1], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ dk3prreq_details_report(pc, &(pr->det_p), pr, pr->t_p, 1);
+ if(DK3_PRINTER_TYPE_WINDOWS == pr->t_p) {
+ if(DK3_PRINTER_TYPE_NONE != pr->t_s) {
+ dk3sf_fputs((pc->msg)[2], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ dk3prreq_details_report(pc, &(pr->det_s), pr, pr->t_s, 0);
+ }
+ }
+ }
+}
+
+
diff --git a/support/dktools/dk3prreq.h b/support/dktools/dk3prreq.h
new file mode 100644
index 0000000000..a0a357b4e8
--- /dev/null
+++ b/support/dktools/dk3prreq.h
@@ -0,0 +1,33 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3prreq.ctr
+*/
+
+/** @file dk3prreq.h Header file for the dk3prreq module.
+*/
+
+#ifndef DK3PRREQ_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3PRREQ_H_INCLUDED 1
+
+
+#line 4 "dk3prreq.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Report all printers found in the current configuration.
+ @param pc Print configuration.
+*/
+void
+dk3prreq_report(dk3_print_conf_t *pc);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk3range.h b/support/dktools/dk3range.h
new file mode 100644
index 0000000000..8b4666e1a4
--- /dev/null
+++ b/support/dktools/dk3range.h
@@ -0,0 +1,15 @@
+
+
+#ifndef DK3_RANGE_H_INCLUDED
+#define DK3_RANGE_H_INCLUDED 1
+
+/** Fit a value into a range.
+ @param i Value to fit.
+ @param min Range minimum.
+ @param max Range maximum.
+ @return Value or min or max.
+*/
+#define DK3_TO_RANGE(i,min,max) ((i < min) ? min : ((i > max) ? max : i))
+
+#endif
+
diff --git a/support/dktools/dk3se.c b/support/dktools/dk3se.c
new file mode 100644
index 0000000000..db3d0a2960
--- /dev/null
+++ b/support/dktools/dk3se.c
@@ -0,0 +1,502 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3se.ctr
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3se.c The dk3se module.
+*/
+
+
+#line 97 "dk3se.ctr"
+
+
+
+#include "dk3all.h"
+#include "dk3se.h"
+
+
+
+
+
+#line 106 "dk3se.ctr"
+
+
+
+/** Find ANSI character for 32-bit character.
+ @param dp Pointer to destination variable.
+ @param c32 32-bit character.
+ @return 1 on success (character found), 0 on error (not available).
+*/
+static
+int
+dk3se_find_ansi_char(char *dp, dk3_c32_t c32)
+{
+ int back = 0;
+ unsigned u;
+ unsigned char uc;
+ char c = '\0';
+
+
+#line 123 "dk3se.ctr"
+ if((dk3_c32_t)0x00010000UL > c32) {
+ u = (unsigned)c32;
+ if(((dk3_c32_t)0x00000019UL < c32) && ((dk3_c32_t)0x00000080UL > c32)) {
+ uc = (unsigned char)u; c = (char)uc;
+ back = 1;
+ } else {
+ if(((dk3_c32_t)0x0000009FUL < c32) && ((dk3_c32_t)0x00000100UL > c32)) {
+ uc = (unsigned char)u; c = (char)uc;
+ back = 1;
+ } else {
+ switch(u) {
+ case 0x20AC: { c = (char)0x80; back = 1; } break;
+ case 0x0081: { c = (char)0x81; back = 1; } break;
+ case 0x201A: { c = (char)0x82; back = 1; } break;
+ case 0x0192: { c = (char)0x83; back = 1; } break;
+ case 0x201E: { c = (char)0x84; back = 1; } break;
+ case 0x2026: { c = (char)0x85; back = 1; } break;
+ case 0x2020: { c = (char)0x86; back = 1; } break;
+ case 0x2021: { c = (char)0x87; back = 1; } break;
+ case 0x02C6: { c = (char)0x88; back = 1; } break;
+ case 0x2030: { c = (char)0x89; back = 1; } break;
+ case 0x0160: { c = (char)0x8A; back = 1; } break;
+ case 0x2039: { c = (char)0x8B; back = 1; } break;
+ case 0x0152: { c = (char)0x8C; back = 1; } break;
+ case 0x008D: { c = (char)0x8D; back = 1; } break;
+ case 0x017D: { c = (char)0x8E; back = 1; } break;
+ case 0x008F: { c = (char)0x8F; back = 1; } break;
+ case 0x0090: { c = (char)0x90; back = 1; } break;
+ case 0x2018: { c = (char)0x91; back = 1; } break;
+ case 0x2019: { c = (char)0x92; back = 1; } break;
+ case 0x201C: { c = (char)0x93; back = 1; } break;
+ case 0x201D: { c = (char)0x94; back = 1; } break;
+ case 0x2022: { c = (char)0x95; back = 1; } break;
+ case 0x2013: { c = (char)0x96; back = 1; } break;
+ case 0x2014: { c = (char)0x97; back = 1; } break;
+ case 0x02DC: { c = (char)0x98; back = 1; } break;
+ case 0x2122: { c = (char)0x99; back = 1; } break;
+ case 0x0161: { c = (char)0x9A; back = 1; } break;
+ case 0x203A: { c = (char)0x9B; back = 1; } break;
+ case 0x0153: { c = (char)0x9C; back = 1; } break;
+ case 0x009D: { c = (char)0x9D; back = 1; } break;
+ case 0x017E: { c = (char)0x9E; back = 1; } break;
+ case 0x0178: { c = (char)0x9F; back = 1; } break;
+ }
+ }
+ }
+ }
+ if(back) {
+
+#line 171 "dk3se.ctr"
+ *dp = c;
+ }
+
+#line 173 "dk3se.ctr"
+ return back;
+}
+
+
+
+/** Check whether a character must be hex-encoded for output
+ as URL.
+ @param c Character to check.
+ @return 1 for percent-hex encoding, 0 for direct output.
+*/
+static
+int
+dk3se_must_encode_for_url(char c)
+{
+ int back = 1;
+
+
+#line 189 "dk3se.ctr"
+ if(('a' <= c) && ('z' >= c)) {
+ back = 0;
+ } else {
+ if(('A' <= c) && ('Z' >= c)) {
+ back = 0;
+ } else {
+ if(('0' <= c) && ('9' >= c)) {
+ back = 0;
+ } else {
+ switch(c) {
+ case '-': case '_': case '.': case '~': {
+ back = 0;
+ } break;
+ }
+ }
+ }
+ }
+
+#line 206 "dk3se.ctr"
+ return back;
+}
+
+
+
+/** Write one 32-bit character to 8-bit character file or check
+ whether writing would be possible.
+ @param c32 Character to write or test.
+ @param fipo File to write to (NULL for check only).
+ @param se Special encoding conditions.
+ @param ev Pointer to variable to store encoding violations.
+ @param we Pointer to write error variable.
+ @param app Application structure for diagnostics, may be NULL.
+*/
+static
+int
+dk3se_fputc_checked(
+ dk3_c32_t c32,
+ FILE *fipo,
+ int se,
+ int *ev,
+ int *we,
+ dk3_app_t *app
+)
+{
+ char buf[16];
+ int back = 0;
+ unsigned u;
+ unsigned char uc = '\0';
+ char c = '\0';
+
+
+#line 237 "dk3se.ctr"
+ if(se & DK3SE_ANSI) {
+
+#line 238 "dk3se.ctr"
+ back = dk3se_find_ansi_char(&c, c32);
+ if(!(back)) {
+ if(ev) { *ev = ((*ev) | DK3SE_ANSI); }
+ if(app) {
+ }
+ }
+ } else {
+
+#line 245 "dk3se.ctr"
+ if((dk3_c32_t)0x00000100UL > c32) {
+ u = (unsigned)c32; uc = (unsigned char)u; c = (char)uc;
+ back = 1;
+ } else {
+ if(ev) { *ev = ((*ev) | DK3SE_URL); }
+ if(app) {
+ }
+ }
+ }
+ if(back) {
+
+#line 255 "dk3se.ctr"
+ if(fipo) {
+ if(se & DK3SE_URL) {
+
+#line 257 "dk3se.ctr"
+ if(dk3se_must_encode_for_url(c)) {
+ buf[0] = '%';
+
+#line 259 "dk3se.ctr"
+ sprintf(&(buf[1]), "%02lx", (unsigned long)c32);
+ if(EOF == fputs(buf, fipo)) {
+ back = 0;
+ if(we) { *we = 1;}
+ }
+ } else {
+
+#line 265 "dk3se.ctr"
+ if(EOF == fputc(c, fipo)) {
+ back = 0;
+ if(we) { *we = 1; }
+ }
+ }
+ } else {
+
+#line 271 "dk3se.ctr"
+ if(EOF == fputc(c, fipo)) {
+ back = 0;
+ if(we) { *we = 1; }
+ }
+ }
+ }
+ }
+
+#line 278 "dk3se.ctr"
+ return back;
+}
+
+
+
+/** Show results for testing or writing a string.
+ @param str String to write or test.
+ @param ev Pointer to result variable: Encoding violations.
+ @param we Pointer to result variable: Write error.
+ @param myev Found encoding violations.
+ @param mywe Found write errors.
+ @param myde Found decoding errors.
+ @param app Application structure for diagnostics, may be NULL.
+*/
+static
+void
+dk3se_show_results(
+ dkChar const *str,
+ int *ev,
+ int *we,
+ int myev,
+ int mywe,
+ int myde,
+ dk3_app_t *app
+)
+{
+ if(ev) { *ev = myev; }
+ if(we) { *we = mywe; }
+ if(app) {
+ if(myde) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 392, 367, str);
+ }
+ if(myev & DK3SE_ANSI) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 393, 367, str);
+ }
+ if(myev & DK3SE_URL) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 394, 367, str);
+ }
+ if(mywe) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 343, 344, str);
+ }
+ }
+}
+
+
+
+/** Write or test one string.
+ @param str String to write or test.
+ @param enc String encoding.
+ @param fipo Output file.
+ @param se Required encodings.
+ @param ev Pointer to result variable: Encoding violations.
+ @param we Pointer to result variable: Write error.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on errors.
+*/
+static
+int
+dk3se_fct
+(
+ dkChar const *str,
+ int enc,
+ FILE *fipo,
+ int se,
+ int *ev,
+ int *we,
+ dk3_app_t *app
+)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ dkChar const *ptr;
+ int back = 1;
+ int myev = 0;
+ int mywe = 0;
+
+
+#line 354 "dk3se.ctr"
+ ptr = str;
+ while(*ptr) {
+ if(!dk3se_fputc_checked(*ptr, fipo, se, &myev, &mywe, app)) { back = 0; }
+ ptr++;
+ }
+ if(!(back)) {
+ dk3se_show_results(str, ev, we, myev, mywe, 0, app);
+ }
+
+#line 362 "dk3se.ctr"
+ return back;
+#else
+ dk3_c16_t const *sp;
+ dk3_c32_t c32;
+ size_t sl;
+ size_t used;
+ int back = 1;
+ int myev = 0;
+ int mywe = 0;
+ int myde = 0;
+
+
+#line 373 "dk3se.ctr"
+ sp = (dk3_c16_t const *)str;
+ sl = dk3str_len(str);
+ while(sl > 0) {
+ used = 0;
+ if(dk3enc_utf162uc(&c32, sp, sl, &used)) {
+ if(!dk3se_fputc_checked(c32, fipo, se, &myev, &mywe, app)) { back = 0; }
+ if(used > 0) {
+ if(sl >= used) {
+ sl = sl - used;
+ sp = &(sp[used]);
+ } else {
+ sl = 0;
+ back = 0;
+ myde = 1;
+ }
+ } else {
+ sl = 0;
+ back = 0;
+ myde = 1;
+ }
+ } else {
+ sl = 0;
+ back = 0;
+ myde = 1;
+ }
+ }
+ if(!(back)) {
+ dk3se_show_results(str, ev, we, myev, mywe, myde, app);
+ }
+
+#line 402 "dk3se.ctr"
+ return back;
+#endif
+#else
+ dk3_c32_t c32;
+ unsigned char const *sp;
+ size_t sl;
+ size_t used;
+ int back = 1;
+ int myev = 0;
+ int mywe = 0;
+ int myde = 0;
+ char c;
+
+
+#line 415 "dk3se.ctr"
+ sp = (unsigned char const *)str;
+ sl = dk3str_c8_len((char const *)sp);
+ if(DK3_ENCODING_UTF8 == enc) {
+ while(sl > 0) {
+ used = 0;
+ if(dk3enc_utf82uc(&c32, sp, sl, &used)) {
+ if(!dk3se_fputc_checked(c32, fipo, se, &myev, &mywe, app)) { back = 0; }
+ if(used > 0) {
+ if(sl >= used) {
+ sl = sl - used;
+ sp = &(sp[used]);
+ } else {
+ sl = 0;
+ back = 0;
+ myde = 1;
+ }
+ } else {
+ sl = 0;
+ back = 0;
+ myde = 1;
+ }
+ } else {
+ sl = 0;
+ back = 0;
+ myde = 1;
+ }
+ }
+ if(!(back)) {
+ dk3se_show_results(str, ev, we, myev, mywe, myde, app);
+ }
+ } else {
+ while(*sp) {
+ c = *(sp++);
+ c32 = (dk3_c32_t)c;
+ c32 &= 0x000000FFUL;
+ if(!dk3se_fputc_checked(c32, fipo, se, &myev, &mywe, app)) { back = 0; }
+ }
+ if(!(back)) {
+ dk3se_show_results(str, ev, we, myev, mywe, 0, app);
+ }
+ }
+
+#line 456 "dk3se.ctr"
+ return back;
+#endif
+}
+
+
+
+
+int
+dk3se_ansi_fputc(dk3_c32_t c32, FILE *fipo)
+{
+ return(dk3se_fputc_checked(c32, fipo, DK3SE_ANSI, NULL, NULL, NULL));
+}
+
+
+
+int
+dk3se_url_fputc(dk3_c32_t c32, FILE *fipo)
+{
+ return(dk3se_fputc_checked(c32, fipo, DK3SE_URL, NULL, NULL, NULL));
+}
+
+
+
+int
+dk3se_ansi_url_fputc(dk3_c32_t c32, FILE *fipo)
+{
+ return(dk3se_fputc_checked(c32,fipo,(DK3SE_ANSI | DK3SE_URL),NULL,NULL,NULL));
+}
+
+
+
+int
+dk3se_ansi_fputs(dkChar const *str, int enc, FILE *fipo, dk3_app_t *app)
+{
+ return(dk3se_fct(str, enc, fipo, DK3SE_ANSI, NULL, NULL, app));
+}
+
+
+
+int
+dk3se_url_fputs(dkChar const *str, int enc, FILE *fipo, dk3_app_t *app)
+{
+ return(dk3se_fct(str, enc, fipo, DK3SE_URL, NULL, NULL, app));
+}
+
+
+int
+dk3se_ansi_url_fputs(dkChar const *str, int enc, FILE *fipo, dk3_app_t *app)
+{
+ return(dk3se_fct(str, enc, fipo, (DK3SE_ANSI | DK3SE_URL), NULL, NULL, app));
+}
+
+
+
+int
+dk3se_check(dkChar const *str, int enc, int se, int *ev, int *we,dk3_app_t *app)
+{
+ return(dk3se_fct(str, enc, NULL, se, ev, we, app));
+}
+
+
diff --git a/support/dktools/dk3se.ctr b/support/dktools/dk3se.ctr
new file mode 100644
index 0000000000..115f02d881
--- /dev/null
+++ b/support/dktools/dk3se.ctr
@@ -0,0 +1,516 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2013-xxxx
+license = bsd
+
+
+%% header
+
+#include <dk3conf.h>
+#include <dk3types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Write ANSI character or check ANSI compatibility.
+ @param c32 Character to write or check.
+ @param fipo File to write to (NULL for check).
+ @return 1 on success, 0 on error (No representation for this
+ character in ANSI encoding).
+*/
+int
+dk3se_ansi_fputc(dk3_c32_t c32, FILE *fipo);
+
+/** Write URL character or check URL compatibility.
+ @param c32 Character to write or check.
+ @param fipo File to write to (NULL for check).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3se_url_fputc(dk3_c32_t c32, FILE *fipo);
+
+/** Convert to ANSI and write URL character or check URL compatibility.
+ @param c32 Character to write or check.
+ @param fipo File to write to (NULL for check).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3se_ansi_url_fputc(dk3_c32_t c32, FILE *fipo);
+
+/** Write ANSI string or check ANSI compatibility.
+ @param str String to write.
+ @param enc String encoding.
+ @param fipo File to write to (NULL for compatibility check).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3se_ansi_fputs(dkChar const *str, int enc, FILE *fipo, dk3_app_t *app);
+
+/** Write URL string or check URL compatibility.
+ @param str String to write.
+ @param enc String encoding.
+ @param fipo File to write to (NULL for compatibility check).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3se_url_fputs(dkChar const *str, int enc, FILE *fipo, dk3_app_t *app);
+
+/** Convert to ANSI and write URL string or check URL compatibility.
+ @param str String to write.
+ @param enc String encoding.
+ @param fipo File to write to (NULL for compatibility check).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3se_ansi_url_fputs(dkChar const *str, int enc, FILE *fipo, dk3_app_t *app);
+
+/** Check whether a string can be converted to ANSI or URL.
+ @param str String to test.
+ @param enc String encoding.
+ @param se Output encoding (DK3SE_ANSI and/or DK3SE_URL).
+ @param ev Pointer to encoding violation variable.
+ @param we Pointer to write error variable.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3se_check(dkChar const *str,int enc,int se,int *ev,int *we,dk3_app_t *app);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** ANSI encoding.
+*/
+#define DK3SE_ANSI 1
+
+/** URL encoding.
+*/
+#define DK3SE_URL 2
+
+%% module
+
+
+
+#include "dk3all.h"
+#include "dk3se.h"
+
+
+
+$!trace-include
+
+
+
+/** Find ANSI character for 32-bit character.
+ @param dp Pointer to destination variable.
+ @param c32 32-bit character.
+ @return 1 on success (character found), 0 on error (not available).
+*/
+static
+int
+dk3se_find_ansi_char(char *dp, dk3_c32_t c32)
+{
+ int back = 0;
+ unsigned u;
+ unsigned char uc;
+ char c = '\0';
+ $? "+ dk3se_find_ansi_char 0x%lx %lu", (unsigned long)c32, (unsigned long)c32
+ if((dk3_c32_t)0x00010000UL > c32) {
+ u = (unsigned)c32;
+ if(((dk3_c32_t)0x00000019UL < c32) && ((dk3_c32_t)0x00000080UL > c32)) {
+ uc = (unsigned char)u; c = (char)uc;
+ back = 1;
+ } else {
+ if(((dk3_c32_t)0x0000009FUL < c32) && ((dk3_c32_t)0x00000100UL > c32)) {
+ uc = (unsigned char)u; c = (char)uc;
+ back = 1;
+ } else {
+ switch(u) {
+ case 0x20AC: { c = (char)0x80; back = 1; } break;
+ case 0x0081: { c = (char)0x81; back = 1; } break;
+ case 0x201A: { c = (char)0x82; back = 1; } break;
+ case 0x0192: { c = (char)0x83; back = 1; } break;
+ case 0x201E: { c = (char)0x84; back = 1; } break;
+ case 0x2026: { c = (char)0x85; back = 1; } break;
+ case 0x2020: { c = (char)0x86; back = 1; } break;
+ case 0x2021: { c = (char)0x87; back = 1; } break;
+ case 0x02C6: { c = (char)0x88; back = 1; } break;
+ case 0x2030: { c = (char)0x89; back = 1; } break;
+ case 0x0160: { c = (char)0x8A; back = 1; } break;
+ case 0x2039: { c = (char)0x8B; back = 1; } break;
+ case 0x0152: { c = (char)0x8C; back = 1; } break;
+ case 0x008D: { c = (char)0x8D; back = 1; } break;
+ case 0x017D: { c = (char)0x8E; back = 1; } break;
+ case 0x008F: { c = (char)0x8F; back = 1; } break;
+ case 0x0090: { c = (char)0x90; back = 1; } break;
+ case 0x2018: { c = (char)0x91; back = 1; } break;
+ case 0x2019: { c = (char)0x92; back = 1; } break;
+ case 0x201C: { c = (char)0x93; back = 1; } break;
+ case 0x201D: { c = (char)0x94; back = 1; } break;
+ case 0x2022: { c = (char)0x95; back = 1; } break;
+ case 0x2013: { c = (char)0x96; back = 1; } break;
+ case 0x2014: { c = (char)0x97; back = 1; } break;
+ case 0x02DC: { c = (char)0x98; back = 1; } break;
+ case 0x2122: { c = (char)0x99; back = 1; } break;
+ case 0x0161: { c = (char)0x9A; back = 1; } break;
+ case 0x203A: { c = (char)0x9B; back = 1; } break;
+ case 0x0153: { c = (char)0x9C; back = 1; } break;
+ case 0x009D: { c = (char)0x9D; back = 1; } break;
+ case 0x017E: { c = (char)0x9E; back = 1; } break;
+ case 0x0178: { c = (char)0x9F; back = 1; } break;
+ }
+ }
+ }
+ }
+ if(back) { $? ". success \"%!8c\"", c
+ *dp = c;
+ } $? "- dk3se_find_ansi_char %d", back
+ return back;
+}
+
+
+
+/** Check whether a character must be hex-encoded for output
+ as URL.
+ @param c Character to check.
+ @return 1 for percent-hex encoding, 0 for direct output.
+*/
+static
+int
+dk3se_must_encode_for_url(char c)
+{
+ int back = 1;
+ $? "+ dk3se_must_encode_for_url %x \"%!8c\"", (int)c, c
+ if(('a' <= c) && ('z' >= c)) {
+ back = 0;
+ } else {
+ if(('A' <= c) && ('Z' >= c)) {
+ back = 0;
+ } else {
+ if(('0' <= c) && ('9' >= c)) {
+ back = 0;
+ } else {
+ switch(c) {
+ case '-': case '_': case '.': case '~': {
+ back = 0;
+ } break;
+ }
+ }
+ }
+ } $? "- dk3se_must_encode_for_url %d", back
+ return back;
+}
+
+
+
+/** Write one 32-bit character to 8-bit character file or check
+ whether writing would be possible.
+ @param c32 Character to write or test.
+ @param fipo File to write to (NULL for check only).
+ @param se Special encoding conditions.
+ @param ev Pointer to variable to store encoding violations.
+ @param we Pointer to write error variable.
+ @param app Application structure for diagnostics, may be NULL.
+*/
+static
+int
+dk3se_fputc_checked(
+ dk3_c32_t c32,
+ FILE *fipo,
+ int se,
+ int *ev,
+ int *we,
+ dk3_app_t *app
+)
+{
+ char buf[16];
+ int back = 0;
+ unsigned u;
+ unsigned char uc = '\0';
+ char c = '\0';
+ $? "+ dk3se_fputc_checked 0x%lx %lu", (unsigned long)c32, (unsigned long)c32
+ if(se & DK3SE_ANSI) { $? ". ANSI required"
+ back = dk3se_find_ansi_char(&c, c32);
+ if(!(back)) {
+ if(ev) { *ev = ((*ev) | DK3SE_ANSI); }
+ if(app) {
+ }
+ }
+ } else { $? ". ANSI not required"
+ if((dk3_c32_t)0x00000100UL > c32) {
+ u = (unsigned)c32; uc = (unsigned char)u; c = (char)uc;
+ back = 1;
+ } else {
+ if(ev) { *ev = ((*ev) | DK3SE_URL); }
+ if(app) {
+ }
+ }
+ }
+ if(back) { $? ". ok so far"
+ if(fipo) {
+ if(se & DK3SE_URL) { $? ". output as URL"
+ if(dk3se_must_encode_for_url(c)) {
+ buf[0] = '%'; $? ". percent/hex encoding"
+ sprintf(&(buf[1]), "%02lx", (unsigned long)c32);
+ if(EOF == fputs(buf, fipo)) {
+ back = 0;
+ if(we) { *we = 1;}
+ }
+ } else { $? ". no percent/hex encoding necessary"
+ if(EOF == fputc(c, fipo)) {
+ back = 0;
+ if(we) { *we = 1; }
+ }
+ }
+ } else { $? ". output as is"
+ if(EOF == fputc(c, fipo)) {
+ back = 0;
+ if(we) { *we = 1; }
+ }
+ }
+ }
+ } $? "- dk3se_fputc_checked %d", back
+ return back;
+}
+
+
+
+/** Show results for testing or writing a string.
+ @param str String to write or test.
+ @param ev Pointer to result variable: Encoding violations.
+ @param we Pointer to result variable: Write error.
+ @param myev Found encoding violations.
+ @param mywe Found write errors.
+ @param myde Found decoding errors.
+ @param app Application structure for diagnostics, may be NULL.
+*/
+static
+void
+dk3se_show_results(
+ dkChar const *str,
+ int *ev,
+ int *we,
+ int myev,
+ int mywe,
+ int myde,
+ dk3_app_t *app
+)
+{
+ if(ev) { *ev = myev; }
+ if(we) { *we = mywe; }
+ if(app) {
+ if(myde) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 392, 367, str);
+ }
+ if(myev & DK3SE_ANSI) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 393, 367, str);
+ }
+ if(myev & DK3SE_URL) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 394, 367, str);
+ }
+ if(mywe) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 343, 344, str);
+ }
+ }
+}
+
+
+
+/** Write or test one string.
+ @param str String to write or test.
+ @param enc String encoding.
+ @param fipo Output file.
+ @param se Required encodings.
+ @param ev Pointer to result variable: Encoding violations.
+ @param we Pointer to result variable: Write error.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on errors.
+*/
+static
+int
+dk3se_fct
+(
+ dkChar const *str,
+ int enc,
+ FILE *fipo,
+ int se,
+ int *ev,
+ int *we,
+ dk3_app_t *app
+)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ dkChar const *ptr;
+ int back = 1;
+ int myev = 0;
+ int mywe = 0;
+ $? "+ dk3se_fct (32 bit)"
+ ptr = str;
+ while(*ptr) {
+ if(!dk3se_fputc_checked(*ptr, fipo, se, &myev, &mywe, app)) { back = 0; }
+ ptr++;
+ }
+ if(!(back)) {
+ dk3se_show_results(str, ev, we, myev, mywe, 0, app);
+ } $? "- dk3se_fct %d", back
+ return back;
+#else
+ dk3_c16_t const *sp;
+ dk3_c32_t c32;
+ size_t sl;
+ size_t used;
+ int back = 1;
+ int myev = 0;
+ int mywe = 0;
+ int myde = 0;
+ $? "+ dk3se_fct (16 bit)"
+ sp = (dk3_c16_t const *)str;
+ sl = dk3str_len(str);
+ while(sl > 0) {
+ used = 0;
+ if(dk3enc_utf162uc(&c32, sp, sl, &used)) {
+ if(!dk3se_fputc_checked(c32, fipo, se, &myev, &mywe, app)) { back = 0; }
+ if(used > 0) {
+ if(sl >= used) {
+ sl = sl - used;
+ sp = &(sp[used]);
+ } else {
+ sl = 0;
+ back = 0;
+ myde = 1;
+ }
+ } else {
+ sl = 0;
+ back = 0;
+ myde = 1;
+ }
+ } else {
+ sl = 0;
+ back = 0;
+ myde = 1;
+ }
+ }
+ if(!(back)) {
+ dk3se_show_results(str, ev, we, myev, mywe, myde, app);
+ } $? "- dk3se_fct %d", back
+ return back;
+#endif
+#else
+ dk3_c32_t c32;
+ unsigned char const *sp;
+ size_t sl;
+ size_t used;
+ int back = 1;
+ int myev = 0;
+ int mywe = 0;
+ int myde = 0;
+ char c;
+ $? "+ dk3se_fct (8 bit)"
+ sp = (unsigned char const *)str;
+ sl = dk3str_c8_len((char const *)sp);
+ if(DK3_ENCODING_UTF8 == enc) {
+ while(sl > 0) {
+ used = 0;
+ if(dk3enc_utf82uc(&c32, sp, sl, &used)) {
+ if(!dk3se_fputc_checked(c32, fipo, se, &myev, &mywe, app)) { back = 0; }
+ if(used > 0) {
+ if(sl >= used) {
+ sl = sl - used;
+ sp = &(sp[used]);
+ } else {
+ sl = 0;
+ back = 0;
+ myde = 1;
+ }
+ } else {
+ sl = 0;
+ back = 0;
+ myde = 1;
+ }
+ } else {
+ sl = 0;
+ back = 0;
+ myde = 1;
+ }
+ }
+ if(!(back)) {
+ dk3se_show_results(str, ev, we, myev, mywe, myde, app);
+ }
+ } else {
+ while(*sp) {
+ c = *(sp++);
+ c32 = (dk3_c32_t)c;
+ c32 &= 0x000000FFUL;
+ if(!dk3se_fputc_checked(c32, fipo, se, &myev, &mywe, app)) { back = 0; }
+ }
+ if(!(back)) {
+ dk3se_show_results(str, ev, we, myev, mywe, 0, app);
+ }
+ } $? "- dk3se_fct %d", back
+ return back;
+#endif
+}
+
+
+
+
+int
+dk3se_ansi_fputc(dk3_c32_t c32, FILE *fipo)
+{
+ return(dk3se_fputc_checked(c32, fipo, DK3SE_ANSI, NULL, NULL, NULL));
+}
+
+
+
+int
+dk3se_url_fputc(dk3_c32_t c32, FILE *fipo)
+{
+ return(dk3se_fputc_checked(c32, fipo, DK3SE_URL, NULL, NULL, NULL));
+}
+
+
+
+int
+dk3se_ansi_url_fputc(dk3_c32_t c32, FILE *fipo)
+{
+ return(dk3se_fputc_checked(c32,fipo,(DK3SE_ANSI | DK3SE_URL),NULL,NULL,NULL));
+}
+
+
+
+int
+dk3se_ansi_fputs(dkChar const *str, int enc, FILE *fipo, dk3_app_t *app)
+{
+ return(dk3se_fct(str, enc, fipo, DK3SE_ANSI, NULL, NULL, app));
+}
+
+
+
+int
+dk3se_url_fputs(dkChar const *str, int enc, FILE *fipo, dk3_app_t *app)
+{
+ return(dk3se_fct(str, enc, fipo, DK3SE_URL, NULL, NULL, app));
+}
+
+
+int
+dk3se_ansi_url_fputs(dkChar const *str, int enc, FILE *fipo, dk3_app_t *app)
+{
+ return(dk3se_fct(str, enc, fipo, (DK3SE_ANSI | DK3SE_URL), NULL, NULL, app));
+}
+
+
+
+int
+dk3se_check(dkChar const *str, int enc, int se, int *ev, int *we,dk3_app_t *app)
+{
+ return(dk3se_fct(str, enc, NULL, se, ev, we, app));
+}
+
+
diff --git a/support/dktools/dk3se.h b/support/dktools/dk3se.h
new file mode 100644
index 0000000000..7b1c7b5e22
--- /dev/null
+++ b/support/dktools/dk3se.h
@@ -0,0 +1,133 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3se.ctr
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3se.h Header file for the dk3se module.
+*/
+
+#ifndef DK3SE_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3SE_H_INCLUDED 1
+
+
+#line 9 "dk3se.ctr"
+
+#include <dk3conf.h>
+#include <dk3types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Write ANSI character or check ANSI compatibility.
+ @param c32 Character to write or check.
+ @param fipo File to write to (NULL for check).
+ @return 1 on success, 0 on error (No representation for this
+ character in ANSI encoding).
+*/
+int
+dk3se_ansi_fputc(dk3_c32_t c32, FILE *fipo);
+
+/** Write URL character or check URL compatibility.
+ @param c32 Character to write or check.
+ @param fipo File to write to (NULL for check).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3se_url_fputc(dk3_c32_t c32, FILE *fipo);
+
+/** Convert to ANSI and write URL character or check URL compatibility.
+ @param c32 Character to write or check.
+ @param fipo File to write to (NULL for check).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3se_ansi_url_fputc(dk3_c32_t c32, FILE *fipo);
+
+/** Write ANSI string or check ANSI compatibility.
+ @param str String to write.
+ @param enc String encoding.
+ @param fipo File to write to (NULL for compatibility check).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3se_ansi_fputs(dkChar const *str, int enc, FILE *fipo, dk3_app_t *app);
+
+/** Write URL string or check URL compatibility.
+ @param str String to write.
+ @param enc String encoding.
+ @param fipo File to write to (NULL for compatibility check).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3se_url_fputs(dkChar const *str, int enc, FILE *fipo, dk3_app_t *app);
+
+/** Convert to ANSI and write URL string or check URL compatibility.
+ @param str String to write.
+ @param enc String encoding.
+ @param fipo File to write to (NULL for compatibility check).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3se_ansi_url_fputs(dkChar const *str, int enc, FILE *fipo, dk3_app_t *app);
+
+/** Check whether a string can be converted to ANSI or URL.
+ @param str String to test.
+ @param enc String encoding.
+ @param se Output encoding (DK3SE_ANSI and/or DK3SE_URL).
+ @param ev Pointer to encoding violation variable.
+ @param we Pointer to write error variable.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3se_check(dkChar const *str,int enc,int se,int *ev,int *we,dk3_app_t *app);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** ANSI encoding.
+*/
+#define DK3SE_ANSI 1
+
+/** URL encoding.
+*/
+#define DK3SE_URL 2
+
+
+#endif
diff --git a/support/dktools/dk3sf.c b/support/dktools/dk3sf.c
new file mode 100644
index 0000000000..bc00c1e947
--- /dev/null
+++ b/support/dktools/dk3sf.c
@@ -0,0 +1,4291 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3sf.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3sf.c The dk3sf module.
+*/
+
+
+#line 748 "dk3sf.ctr"
+
+#include "dk3all.h"
+
+
+
+
+
+
+#line 754 "dk3sf.ctr"
+
+
+
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+
+/** File path component separator.
+*/
+#define DK3_C8_SEP '\\'
+
+/** Not a file path component separator.
+*/
+#define DK3_C8_NOSEP '/'
+
+#else
+
+/** File path component separator.
+*/
+#define DK3_C8_SEP '/'
+
+/** Not a file path component separator.
+*/
+#define DK3_C8_NOSEP '\\'
+
+#endif
+
+
+
+/** Add bit to set after testing another bit.
+*/
+#define DK3SF_ADDIF(a,b) if(m & a) { back |= b; }
+
+
+
+/** Function names used in error messages.
+*/
+dkChar const * const dk3sf_function_names[] = {
+/* 0 */
+dkT(""),
+
+/* 1 */
+dkT("fclose: "),
+
+/* 2 */
+dkT("rmdir: "),
+
+/* 3 */
+dkT("unlink: "),
+
+/* 4 */
+dkT("getpwuid: "),
+
+/* 5 */
+dkT("lstat64: "),
+
+/* 6 */
+dkT("stat64: "),
+
+/* 7 */
+dkT("stat: "),
+
+/* 8 */
+dkT("lstat: "),
+
+/* 9 */
+dkT("fopen: "),
+
+/* 10 */
+dkT("localtime_r: "),
+
+/* 11 */
+dkT("getcwd: "),
+
+/* 12 */
+dkT("mkdir: "),
+
+/* 13 */
+dkT("gethostname: "),
+
+/* 14 */
+dkT("read: "),
+
+/* 15 */
+dkT("_read: "),
+
+/* 16 */
+dkT("write: "),
+
+/* 17 */
+dkT("_write: "),
+
+/* 18 */
+dkT("fread: "),
+
+/* 19 */
+dkT("_fread: "),
+
+/* 20 */
+dkT("fwrite: "),
+
+/* 21 */
+dkT("_fwrite: "),
+
+/* 22 */
+dkT("chdir: "),
+
+/* 23 */
+dkT("fputs: "),
+
+/* 24 */
+dkT("fputc: "),
+
+/* 25 */
+dkT("fgets: "),
+
+NULL
+
+
+#line 896 "dk3sf.ctr"
+};
+
+
+
+void
+dk3sf_report_errno(dk3_app_t *app, int err, dkChar const *fctn)
+{
+#if (DK3_CHAR_SIZE == 1) && DK3_HAVE_STRERROR && (!DK3_ON_WINDOWS)
+ dkChar const *msgarray[2];
+#if DK3_HAVE_GETENV && DK3_HAVE_SETLOCALE
+ char const *oldlocale = NULL;
+ char const *langptr = NULL;
+#endif
+ if((app) && (fctn)) {
+ msgarray[0] = fctn;
+ errno = 0;
+#if DK3_HAVE_GETENV && DK3_HAVE_SETLOCALE
+ langptr = getenv("LANG");
+ if(langptr) {
+ oldlocale = setlocale(LC_MESSAGES, langptr);
+ }
+#endif
+ msgarray[1] = strerror(err);
+ if(0 == errno) {
+ dk3app_log_3(app, DK3_LL_ERROR, msgarray, 0, 1, dk3sf_function_names[0]);
+ }
+#if DK3_HAVE_GETENV && DK3_HAVE_SETLOCALE
+ if(langptr) {
+ if(oldlocale) { setlocale(LC_MESSAGES, oldlocale); }
+ }
+#endif
+ }
+#endif
+}
+
+
+
+
+#if DK3_ON_WINDOWS
+/* +++ Windows +++ */
+
+
+
+/** Unlocalized 8-bit character keywords used by module.
+*/
+static char const * const dk3sf_kw_win_c8[] = {
+/* 0 */ "HOMEDRIVE",
+/* 1 */ "HOMEPATH",
+/* 2 */ "USERPROFILE",
+/* 3 */ "LOCALAPPDATA",
+/* 4 */ "\\AppData\\Local",
+/* 5 */ "APPDATA",
+/* 6 */ "\\AppData\\Roaming",
+/* 7 */ "TEMP",
+/* 8 */ "TMP",
+/* 9 */ "\\AppData\\Local\\Temp",
+NULL
+};
+
+
+
+/** Unlocalized 16-bit character keywords used by module.
+*/
+static wchar_t const * const dk3sf_kw_win_c16[] = {
+/* 0 */ L"HOMEDRIVE",
+/* 1 */ L"HOMEPATH",
+/* 2 */ L"USERPROFILE",
+/* 3 */ L"LOCALAPPDATA",
+/* 4 */ L"\\AppData\\Local",
+/* 5 */ L"APPDATA",
+/* 6 */ L"\\AppData\\Roaming",
+/* 7 */ L"TEMP",
+/* 8 */ L"TMP",
+/* 9 */ L"\\AppData\\Local\\Temp",
+NULL
+};
+
+
+
+dk3_um_t
+dk3sf_getpid(void)
+{
+ dk3_um_t back;
+ back = (dk3_um_t)_getpid();
+ return back;
+}
+
+
+
+dk3_c16_t *
+dk3sf_c16_getenv(dk3_c16_t const *name)
+{
+ dk3_c16_t *back = NULL;
+ if(name) {
+ back = _wgetenv(name);
+ }
+ return back;
+}
+
+
+dk3_c8_t *
+dk3sf_c8_getenv(char const *name)
+{
+ char *back = NULL;
+ if(name) {
+ back = getenv(name);
+ }
+ return back;
+}
+
+
+int
+dk3sf_c16_remove_dir_app(dk3_c16_t const *n, dk3_app_t *app)
+{
+ int back = 0;
+ if(n) {
+ if(_wrmdir(n) == 0) {
+ back = 1;
+ } else {
+ if(app) {
+ /* Failed to remove directory! */
+#if DK3_CHAR_SIZE == 2
+ dk3app_log_i3(app, DK3_LL_ERROR, 69, 70, n);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 68);
+#endif
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c8_remove_dir_app(char const *n, dk3_app_t *app)
+{
+ int back = 0;
+ if(n) {
+ if(_rmdir(n) == 0) {
+ back = 1;
+ } else {
+ if(app) {
+ /* Failed to remove directory! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 69, 70, n);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 68);
+#endif
+ }
+ }
+ }
+ return back;
+}
+
+
+int
+dk3sf_c16_remove_file_app(dk3_c16_t const *n, dk3_app_t *app)
+{
+ int back = 0;
+ if(n) {
+ if(_wunlink(n) == 0) {
+ back = 1;
+ } else {
+ if(app) {
+ /* Failed to remove file! */
+#if DK3_CHAR_SIZE == 2
+ dk3app_log_i3(app, DK3_LL_ERROR, 88, 89, n);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 90);
+#endif
+ }
+ }
+ }
+ return back;
+}
+
+
+int
+dk3sf_c8_remove_file_app(char const *n, dk3_app_t *app)
+{
+ int back = 0;
+ if(n) {
+ if(_unlink(n) == 0) {
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Failed to remove file! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 88, 89, n);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 90);
+#endif
+ }
+ }
+ }
+ return back;
+}
+
+
+/** Attempt to retrieve home directory name.
+ @param d Destination buffer.
+ @param sz Size of \a d (number of characters).
+ @param n1 Name of first environment variable to check.
+ @param n2 Name of second environment variable to check.
+ @param n3 Trailing string to remove if found.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3sf_c8_attempt_home(
+ char *d, size_t sz, char const *n1, char const *n2, char const *n3
+)
+{
+ int back = 0;
+ char *p1 = NULL; /* Value of first environment variable. */
+ char *p2 = NULL; /* Value of second environment variable. */
+ size_t s = 0; /* Buffer size needed. */
+ size_t s2 = 0; /* Size of trailing part to remove. */
+ p2 = NULL;
+
+
+#line 1117 "dk3sf.ctr"
+ p1 = getenv(n1);
+ if(p1) {
+ if(n2) { p2 = getenv(n2); }
+ if((p2) || (!(n2))) {
+ s = dk3str_c8_len(p1);
+ if(p2) { s += dk3str_c8_len(p2); }
+ if(s < sz) {
+ dk3str_c8_cpy_not_overlapped(d, p1);
+ if(p2) { dk3str_c8_cat(d, p2); }
+ if(n3) {
+ s2 = dk3str_c8_len(n3);
+ if(s2 < 2) {
+ if(dk3str_c8_casecmp(&(d[s - s2]), n3) == 0) {
+ d[s - s2] = '\0';
+ back = 1;
+ }
+ }
+ } else {
+ back = 1;
+ }
+ }
+ }
+
+
+#line 1140 "dk3sf.ctr"
+
+
+#line 1141 "dk3sf.ctr"
+
+
+#line 1142 "dk3sf.ctr"
+ }
+
+#line 1143 "dk3sf.ctr"
+ return back;
+}
+
+
+int
+dk3sf_c8_get_home_app(char *d, size_t s, dk3_app_t *app)
+{
+ int back = 0;
+ if((d) && (s)) {
+ back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[0], dk3sf_kw_win_c8[1], NULL);
+ if(!back) {
+ back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[2], NULL, NULL);
+ }
+ if(!back) {
+ back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[3], NULL, dk3sf_kw_win_c8[4]);
+ }
+ if(!back) {
+ back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[5], NULL, dk3sf_kw_win_c8[6]);
+ }
+ if(!back) {
+ back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[7], NULL, dk3sf_kw_win_c8[9]);
+ }
+ if(!back) {
+ back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[8], NULL, dk3sf_kw_win_c8[9]);
+ }
+ if(!back) {
+ back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[3], NULL, NULL);
+ }
+ if(!back) {
+ back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[5], NULL, NULL);
+ }
+ if(!back) {
+ back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[7], NULL, NULL);
+ }
+ if(!back) {
+ back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[8], NULL, NULL);
+ }
+
+
+#line 1181 "dk3sf.ctr"
+
+
+#line 1182 "dk3sf.ctr"
+
+
+#line 1183 "dk3sf.ctr"
+ }
+ return back;
+}
+
+
+
+/** Attempt to retrieve home directory name.
+ @param d Destination buffer.
+ @param sz Size of \a d (number of characters).
+ @param n1 Name of first environment variable to check.
+ @param n2 Name of second environment variable to check.
+ @param n3 Trailing string to remove if found.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3sf_c16_attempt_home(
+ dk3_c16_t *d, size_t sz,
+ dk3_c16_t const *n1, dk3_c16_t const *n2, dk3_c16_t const *n3
+)
+{
+ int back = 0;
+ dk3_c16_t *p1 = NULL; /* Value of first environment variable. */
+ dk3_c16_t *p2 = NULL; /* Value of second environment variable. */
+ size_t s = 0; /* Buffer size needed. */
+ size_t s2 = 0; /* Size of trailing text to remove. */
+ p2 = NULL;
+
+
+#line 1211 "dk3sf.ctr"
+ p1 = _wgetenv(n1);
+ if(p1) {
+ if(n2) { p2 = _wgetenv(n2); }
+ if((p2) || (!(n2))) {
+ s = dk3str_c16_len(p1);
+ if(p2) { s += dk3str_c16_len(p2); }
+ if(s < sz) {
+ dk3str_c16_cpy(d, p1);
+ if(p2) { dk3str_c16_cat(d, p2); }
+ if(n3) {
+ s2 = dk3str_c16_len(n3);
+ if(s2 < 2) {
+ if(dk3str_c16_casecmp(&(d[s - s2]), n3) == 0) {
+ d[s - s2] = 0x0000U;
+ back = 1;
+ }
+ }
+ } else {
+ back = 1;
+ }
+ }
+ }
+
+
+#line 1234 "dk3sf.ctr"
+
+
+#line 1235 "dk3sf.ctr"
+
+
+#line 1236 "dk3sf.ctr"
+ }
+
+#line 1237 "dk3sf.ctr"
+ return back;
+}
+
+
+
+int
+dk3sf_c16_get_home_app(dk3_c16_t *d, size_t s, dk3_app_t *app)
+{
+ int back = 0;
+ if((d) && (s)) {
+ back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[0], dk3sf_kw_win_c16[1], NULL);
+ if(!back) {
+ back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[2], NULL, NULL);
+ }
+ if(!back) {
+ back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[3], NULL, dk3sf_kw_win_c16[4]);
+ }
+ if(!back) {
+ back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[5], NULL, dk3sf_kw_win_c16[6]);
+ }
+ if(!back) {
+ back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[7], NULL, dk3sf_kw_win_c16[9]);
+ }
+ if(!back) {
+ back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[8], NULL, dk3sf_kw_win_c16[9]);
+ }
+ if(!back) {
+ back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[3], NULL, NULL);
+ }
+ if(!back) {
+ back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[5], NULL, NULL);
+ }
+ if(!back) {
+ back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[7], NULL, NULL);
+ }
+ if(!back) {
+ back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[8], NULL, NULL);
+ }
+
+
+#line 1276 "dk3sf.ctr"
+
+
+#line 1277 "dk3sf.ctr"
+
+
+#line 1278 "dk3sf.ctr"
+ }
+ return back;
+}
+
+
+int
+dk3sf_c8_get_logname_app(char *d, size_t s, dk3_app_t *app)
+{
+ int back = 0;
+ DWORD sz = 0; /* Buffer size / Result length. */
+ sz = (DWORD)s;
+ if((d) && (s)) {
+ if(GetUserNameA(d, &sz)) {
+ if(sz) {
+ d[((size_t)sz < s) ? ((size_t)sz) : (s - 1)] = '\0';
+ back = 1;
+ }
+ } else {
+ if(app) {
+ /* Failed to find current user name */
+ dk3app_log_i1(app, DK3_LL_ERROR, 43);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c16_get_logname_app(dk3_c16_t *d, size_t s, dk3_app_t *app)
+{
+ int back = 0;
+ DWORD sz = 0; /* Buffer size / result length. */
+ if((d) && (s)) {
+ sz = (DWORD)s;
+ if(GetUserNameW(d, &sz)) {
+ if(sz) {
+ d[((size_t)sz < s) ? ((size_t)sz) : (s - 1)] = 0U;
+ back = 1;
+ }
+ } else {
+ if(app) {
+ /* Failed to find current user name */
+ dk3app_log_i1(app, DK3_LL_ERROR, 43);
+ }
+ }
+ }
+ return back;
+}
+
+
+int
+dk3sf_time(dk3_time_t *timer)
+{
+ int back = 1;
+ _time64(timer);
+ return back;
+}
+
+
+
+static
+int
+dk3sf_convert_file_type(int m)
+{
+ int back = 0;
+ switch(m & _S_IFMT) {
+#ifdef _S_IFIFO
+ case _S_IFIFO: back = DK3_FT_FIFO; break;
+#endif
+#ifdef _S_IFCHR
+ case _S_IFCHR: back = DK3_FT_SPECIAL_CHAR; break;
+#endif
+#ifdef _S_IFDIR
+ case _S_IFDIR: back = DK3_FT_DIRECTORY; break;
+#endif
+#ifdef _S_IFBLK
+ case _S_IFBLK: back = DK3_FT_SPECIAL_BLOCK; break;
+#endif
+#ifdef _S_IFREG
+ case _S_IFREG: back = DK3_FT_REGULAR; break;
+#endif
+ }
+ return back;
+}
+
+
+
+static
+int
+dk3sf_convert_file_permissions(int m)
+{
+ int back = 0;
+ DK3SF_ADDIF(_S_IREAD,DK3_FPERM_U_READ)
+ DK3SF_ADDIF(_S_IWRITE,DK3_FPERM_U_WRITE)
+ DK3SF_ADDIF(_S_IEXEC,DK3_FPERM_U_EXEC)
+ return back;
+}
+
+
+
+/** Convert file permissions back from dktools to system values.
+ @param m File permissions in dktools notation.
+ @return File permissions in system notation.
+*/
+static
+int
+dk3sf_convert_back_file_permissions(int m)
+{
+ int back = 0;
+ DK3SF_ADDIF(DK3_FPERM_U_READ,S_IREAD)
+ DK3SF_ADDIF(DK3_FPERM_U_WRITE,S_IWRITE)
+ DK3SF_ADDIF(DK3_FPERM_U_EXEC,S_IEXEC)
+ return back;
+}
+
+
+
+static
+void
+dk3sf_convert_filetime(dk3_time_t *pd, FILETIME *ps)
+{
+ __int64 i1;
+ __int64 i2;
+ i1 = (__int64)(ps->dwHighDateTime);
+ i2 = (__int64)(ps->dwLowDateTime);
+ i1 = ((i1 << 32) & 0xFFFFFFFF00000000UL) | (i2 & 0x00000000FFFFFFFFUL);
+ *pd = (dk3_time_t)i1;
+}
+
+
+
+int
+dk3sf_c8_stat_app(dk3_stat_t *st, char const *fn, dk3_app_t *app)
+{
+ WIN32_FIND_DATAA wfd;
+ DWORD dwFileAttributes;
+ HANDLE hFFF;
+ int ec = 0;
+ int back = 0;
+ struct __stat64 stb; /* Internal buffer for _stat64(). */
+
+
+#line 1421 "dk3sf.ctr"
+ if((st) && (fn)) {
+ dk3mem_res((void *)st, sizeof(dk3_stat_t));
+ st->cReparse = 0x00;
+ st->dwReparse = (DWORD)0;
+ if(_stat64(fn, &stb) == 0) {
+ back = 1;
+ st->u = (dk3_um_t)(stb.st_uid);
+ st->g = (dk3_um_t)(stb.st_gid);
+ st->device = (dk3_um_t)(stb.st_dev);
+ st->rdev = (dk3_um_t)(stb.st_rdev);
+ st->inode = (dk3_um_t)(stb.st_ino);
+ st->nlink = (dk3_um_t)(stb.st_nlink);
+ st->cre = (dk3_time_t)(stb.st_ctime);
+ st->mod = (dk3_time_t)(stb.st_mtime);
+ st->acc = (dk3_time_t)(stb.st_atime);
+ st->ft = dk3sf_convert_file_type(stb.st_mode);
+ st->perm = dk3sf_convert_file_permissions(stb.st_mode);
+ st->sz = (dk3_um_t)(stb.st_size);
+ st->lsz = st->sz;
+ st->ai = 0x00;
+ dk3mem_cpy((void *)(&(st->lcre)), (void *)(&(st->cre)), sizeof(dk3_time_t));
+ dk3mem_cpy((void *)(&(st->lmod)), (void *)(&(st->mod)), sizeof(dk3_time_t));
+ dk3mem_cpy((void *)(&(st->lacc)), (void *)(&(st->acc)), sizeof(dk3_time_t));
+ st->lu = st->u;
+ st->lg = st->g;
+ st->ldevice = st->device;
+ st->lrdev = st->rdev;
+ st->linode = st->inode;
+ st->lnlink = st->nlink;
+ st->lft = st->ft;
+ st->lperm = st->perm;
+ st->lsz = st->sz;
+#if VERSION_BEFORE_2012_04_14
+ if(DK3_FT_DIRECTORY == st->ft) {
+ WIN32_FIND_DATAA wfdFileDetails;
+ HANDLE hFileSearch;
+
+
+#line 1458 "dk3sf.ctr"
+ hFileSearch = FindFirstFileA(fn, &wfdFileDetails);
+ if(INVALID_HANDLE_VALUE != hFileSearch) {
+ if(FILE_ATTRIBUTE_REPARSE_POINT & (wfdFileDetails.dwFileAttributes)) {
+ if(IO_REPARSE_TAG_MOUNT_POINT == wfdFileDetails.dwReserved0) {
+ /* ##### st->ft = DK3_FT_WINDOWS_MOUNT_POINT; */
+ } else {
+ if(IO_REPARSE_TAG_SYMLINK == wfdFileDetails.dwReserved0) {
+ /* Symbolic link */
+ st->lsz = dk3ma_um_add_ok(
+ dk3ma_um_mul_ok(
+ (dk3_um_t)(wfdFileDetails.nFileSizeHigh),
+ dk3ma_um_add_ok(
+ (dk3_um_t)(MAXDWORD),
+ DK3_UM_1,
+ &ec
+ ),
+ &ec
+ ),
+ (dk3_um_t)(wfdFileDetails.nFileSizeLow),
+ &ec
+ );
+ dk3sf_convert_filetime(&(st->lcre), &(wfdFileDetails.ftCreationTime));
+ dk3sf_convert_filetime(&(st->lmod), &(wfdFileDetails.ftLastWriteTime));
+ dk3sf_convert_filetime(&(st->lacc), &(wfdFileDetails.ftLastAccessTime));
+ st->ft |= DK3_FT_SYMLINK;
+ } else {
+ }
+ }
+ }
+ FindClose(hFileSearch);
+ }
+ }
+#else
+ dwFileAttributes = GetFileAttributesA(fn);
+ if(INVALID_FILE_ATTRIBUTES != dwFileAttributes) {
+ if(dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
+ st->cReparse = 'r';
+ hFFF = FindFirstFileA(fn, &wfd);
+ if(INVALID_HANDLE_VALUE != hFFF) {
+ if((wfd.dwFileAttributes) & FILE_ATTRIBUTE_REPARSE_POINT) {
+ st->dwReparse = wfd.dwReserved0;
+ switch(wfd.dwReserved0) {
+ case IO_REPARSE_TAG_MOUNT_POINT: {
+ st->cReparse = 'm';
+ } break;
+ case IO_REPARSE_TAG_SYMLINK: {
+ st->cReparse = 'l';
+ } break;
+ }
+ }
+ FindClose(hFFF);
+ }
+ }
+ }
+#endif
+ } else {
+ if(app) {
+ /* stat() failed! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 61, 62, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 73);
+#endif
+ }
+ }
+ }
+
+#line 1524 "dk3sf.ctr"
+ return back;
+}
+
+
+
+/** Check whether opening a file is allowed.
+ @param fn File name.
+ @param want_to_write Flag: Write access is wanted.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 for write allowed, 0 for write denied.
+*/
+static
+int
+dk3sf_c8_check_open_file(char const *fn, int want_to_write, dk3_app_t *app)
+{
+ int back = 1;
+ dk3_stat_t stb; /* Internal buffer for checks. */
+ if(dk3sf_c8_stat_app(&stb, fn, NULL)) {
+ if(((stb.ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_DIRECTORY) {
+ if(app) {
+ back = 0;
+ /* ERROR: Name refers a directory! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 74, 75, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 76);
+#endif
+ }
+ }
+ if(want_to_write) {
+ /* Place for additional checks to write files here. */
+ }
+ }
+ return back;
+}
+
+
+
+FILE *
+dk3sf_c8_fopen_app(char const *fn, char const *mo, dk3_app_t *app)
+{
+ FILE *back = NULL;
+ char const *moptr = NULL; /* Check mode string. */
+ int want_to_write = 0; /* Flag: Write access wanted. */
+
+
+#line 1569 "dk3sf.ctr"
+ if((fn) && (mo)) {
+ moptr = mo;
+ while(*moptr) {
+ switch(*moptr) {
+ case 'w': case 'a': case '+': { want_to_write = 1; } break;
+ }
+ moptr++;
+ }
+ if(dk3sf_c8_check_open_file(fn, want_to_write, app)) {
+ back = fopen(fn, mo);
+ if(!(back)) {
+ if(app) {
+ /* Failed to open file for writing! */
+ if(want_to_write) {
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 77, 78, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 79);
+#endif
+ } else {
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 143, 144, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 145);
+#endif
+ }
+ }
+ }
+ }
+ }
+
+#line 1599 "dk3sf.ctr"
+ return back;
+}
+
+
+
+
+int
+dk3sf_localtime_app(
+ dk3_tm_t *dest,
+ dk3_time_t *timer,
+ dk3_app_t *app
+)
+{
+ int back = 0;
+ struct tm res;
+ if((dest) && (timer)) {
+ if(0 == _localtime64_s(&res, timer)) {
+ back = 1;
+ dest->Y = 1900 + res.tm_year;
+ dest->M = 1 + res.tm_mon;
+ dest->D = res.tm_mday;
+ dest->h = res.tm_hour;
+ dest->m = res.tm_min;
+ dest->s = res.tm_sec;
+ } else {
+ if(app) {
+ /* ERROR: _localtime64_s failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 268);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c8_time_convert_app(
+ char *dest, size_t sz, dk3_time_t const *timer, dk3_app_t *app
+)
+{
+ int back = 0;
+ char buffer[64]; /* Buffer for sprintf() result. */
+ struct tm res; /* Result from localtime(). */
+ if((dest) && (sz) && (timer)) {
+ if(0 == _localtime64_s(&res, timer)) {
+ sprintf(
+ buffer,
+ "%04d-%02d-%02d %02d:%02d:%02d",
+ (1900 + res.tm_year),
+ (1 + res.tm_mon),
+ res.tm_mday,
+ res.tm_hour,
+ res.tm_min,
+ res.tm_sec
+ );
+ if(sz > dk3str_c8_len(buffer)) {
+ dk3str_c8_cpy_not_overlapped(dest, buffer);
+ back = 1;
+ } else {
+ if(app) {
+ /* Buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ } else {
+ if(app) {
+ /* _localtime64_s failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 80);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c8_getcwd_app(char *dest, size_t sz, dk3_app_t *app)
+{
+ int back = 0;
+ if((dest) && (sz)) {
+ if(_getcwd(dest, (int)sz)) {
+ back = 1;
+ } else {
+ if(app) {
+ switch(errno) {
+ case ERANGE: {
+ /* Buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ } break;
+ default: {
+ dk3app_log_i1(app, DK3_LL_ERROR, 53);
+ } break;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c8_find_exec_app(
+ char *d, size_t s, char const *w, char const *c, dk3_app_t *app
+)
+{
+ int back = 0;
+ if((d) && (s)) {
+ if(GetModuleFileNameA(GetModuleHandle(NULL),d,(DWORD)s)) {
+ back = 1;
+ } else {
+ if(app) {
+ /* Failed to find name of executable! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 40);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+static
+int
+dk3sf_c8_is_drive(char const *p)
+{
+ int back = 0;
+
+
+#line 1729 "dk3sf.ctr"
+ if(dk3str_c8_len(p) == 2) {
+ if((*p >= 'a') && (*p <= 'z')) {
+ back = 1;
+ }
+ if((*p >= 'A') && (*p <= 'Z')) {
+ back = 1;
+ }
+ if(back) {
+ back = 0;
+ if(p[1] == ':') { back = 1; }
+ }
+ }
+
+#line 1741 "dk3sf.ctr"
+ return back;
+}
+
+
+int
+dk3sf_c8_mkdir_app(char const *p, int mo, dk3_app_t *app)
+{
+ int back = 0;
+ char buffer[DK3_MAX_PATH]; /* Path name for parent directories. */
+ char *ptr = NULL; /* Slash/backslash position. */
+ int cc = 1; /* Flag: Can continue. */
+ int m = 0; /* File permissions. */
+ dk3_stat_t stb;
+
+
+#line 1755 "dk3sf.ctr"
+ if(p) {
+ m = dk3sf_convert_back_file_permissions(mo);
+ if(dk3str_c8_len(p) < sizeof(buffer)) {
+
+#line 1758 "dk3sf.ctr"
+ dk3str_c8_cpy_not_overlapped(buffer, p);
+ ptr = buffer; cc = 1;
+ while((cc) && (ptr)) {
+
+#line 1761 "dk3sf.ctr"
+ ptr = dk3str_c8_chr(ptr, '\\');
+ if(ptr) {
+ *ptr = '\0';
+
+#line 1764 "dk3sf.ctr"
+ if((dk3str_c8_len(buffer) > 0) && (!dk3sf_c8_is_drive(buffer))) {
+ if(dk3sf_c8_stat_app(&stb, buffer, NULL)) {
+
+#line 1766 "dk3sf.ctr"
+ if(((stb.ft) & (~(DK3_FT_SYMLINK))) != DK3_FT_DIRECTORY) {
+ cc = 0;
+
+#line 1768 "dk3sf.ctr"
+ if(app) {
+ /* Not a directory! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 81, 82, buffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 83);
+#endif
+ }
+ }
+ } else {
+
+#line 1778 "dk3sf.ctr"
+ if(_mkdir(buffer) != 0) {
+
+#line 1779 "dk3sf.ctr"
+ cc = 0;
+ if(app) {
+ /* Failed to create directory! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 84, 85, buffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 86);
+#endif
+ }
+ }
+ }
+ }
+ *ptr = '\\';
+ ptr++;
+ }
+ }
+ if(cc) {
+
+#line 1796 "dk3sf.ctr"
+ if(dk3sf_c8_stat_app(&stb, buffer, NULL)) {
+
+#line 1797 "dk3sf.ctr"
+ if(((stb.ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_DIRECTORY) {
+ back = 1;
+
+#line 1799 "dk3sf.ctr"
+ } else {
+
+#line 1800 "dk3sf.ctr"
+ if(app) {
+ /* Not a directory! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 81, 82, buffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 83);
+#endif
+ }
+ }
+ } else {
+
+#line 1810 "dk3sf.ctr"
+ if(_mkdir(buffer) == 0) {
+ back = 1;
+ } else {
+
+#line 1813 "dk3sf.ctr"
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 84, 85, buffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 86);
+#endif
+ }
+ }
+ }
+ } else {
+
+#line 1822 "dk3sf.ctr"
+ if(app) {
+ /* Path too long! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 59, 60, p);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 87);
+#endif
+ }
+ }
+ }
+
+#line 1832 "dk3sf.ctr"
+ return back;
+}
+
+
+
+int
+dk3sf_c16_stat_app(dk3_stat_t *st, dk3_c16_t const *fn, dk3_app_t *app)
+{
+ WIN32_FIND_DATAW wfd;
+ DWORD dwFileAttributes;
+ HANDLE hFFF;
+ int ec = 0;
+ int back = 0;
+ struct __stat64 stb; /* Result from _wstat64(). */
+
+
+#line 1847 "dk3sf.ctr"
+ if((st) && (fn)) {
+ dk3mem_res((void *)st, sizeof(dk3_stat_t));
+ st->cReparse = 0x00;
+ st->dwReparse = (DWORD)0;
+ if(_wstat64(fn, &stb) == 0) {
+ back = 1;
+ st->u = (dk3_um_t)(stb.st_uid);
+ st->g = (dk3_um_t)(stb.st_gid);
+ st->device = (dk3_um_t)(stb.st_dev);
+ st->rdev = (dk3_um_t)(stb.st_rdev);
+ st->inode = (dk3_um_t)(stb.st_ino);
+ st->nlink = (dk3_um_t)(stb.st_nlink);
+ st->cre = (dk3_time_t)(stb.st_ctime);
+ st->mod = (dk3_time_t)(stb.st_mtime);
+ st->acc = (dk3_time_t)(stb.st_atime);
+ st->ft = dk3sf_convert_file_type(stb.st_mode);
+ st->perm = dk3sf_convert_file_permissions(stb.st_mode);
+ st->sz = (dk3_um_t)(stb.st_size);
+ st->lsz = st->sz;
+ st->ai = 0x00;
+ dk3mem_cpy((void *)(&(st->lcre)), (void *)(&(st->cre)), sizeof(dk3_time_t));
+ dk3mem_cpy((void *)(&(st->lmod)), (void *)(&(st->mod)), sizeof(dk3_time_t));
+ dk3mem_cpy((void *)(&(st->lacc)), (void *)(&(st->acc)), sizeof(dk3_time_t));
+ st->lu = st->u;
+ st->lg = st->g;
+ st->ldevice = st->device;
+ st->lrdev = st->rdev;
+ st->linode = st->inode;
+ st->lnlink = st->nlink;
+ st->lft = st->ft;
+ st->lperm = st->perm;
+ st->lsz = st->sz;
+#if VERSION_BEFORE_2012_04_14
+ if(DK3_FT_DIRECTORY == st->ft) {
+ WIN32_FIND_DATAW wfdFileDetails;
+ HANDLE hFileSearch;
+
+
+#line 1884 "dk3sf.ctr"
+ hFileSearch = FindFirstFileW(fn, &wfdFileDetails);
+ if(INVALID_HANDLE_VALUE != hFileSearch) {
+
+#line 1886 "dk3sf.ctr"
+ if(FILE_ATTRIBUTE_REPARSE_POINT & (wfdFileDetails.dwFileAttributes)) {
+
+
+#line 1888 "dk3sf.ctr"
+ if(IO_REPARSE_TAG_MOUNT_POINT == wfdFileDetails.dwReserved0) {
+
+
+#line 1890 "dk3sf.ctr"
+ /* ##### st->ft = DK3_FT_WINDOWS_MOUNT_POINT; */
+ } else {
+ if(IO_REPARSE_TAG_SYMLINK == wfdFileDetails.dwReserved0) {
+
+
+#line 1894 "dk3sf.ctr"
+ /* Symbolic link */
+ st->lsz = dk3ma_um_add_ok(
+ dk3ma_um_mul_ok(
+ (dk3_um_t)(wfdFileDetails.nFileSizeHigh),
+ dk3ma_um_add_ok(
+ (dk3_um_t)(MAXDWORD),
+ DK3_UM_1,
+ &ec
+ ),
+ &ec
+ ),
+ (dk3_um_t)(wfdFileDetails.nFileSizeLow),
+ &ec
+ );
+ dk3sf_convert_filetime(&(st->lcre), &(wfdFileDetails.ftCreationTime));
+ dk3sf_convert_filetime(&(st->lmod), &(wfdFileDetails.ftLastWriteTime));
+ dk3sf_convert_filetime(&(st->lacc), &(wfdFileDetails.ftLastAccessTime));
+ st->ft |= DK3_FT_SYMLINK;
+ } else {
+ }
+ }
+ }
+ FindClose(hFileSearch);
+ }
+ }
+#else
+ dwFileAttributes = GetFileAttributesW(fn);
+ if(INVALID_FILE_ATTRIBUTES != dwFileAttributes) {
+ if(dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
+ st->cReparse = 'r';
+ hFFF = FindFirstFileW(fn, &wfd);
+ if(INVALID_HANDLE_VALUE != hFFF) {
+ if((wfd.dwFileAttributes) & FILE_ATTRIBUTE_REPARSE_POINT) {
+ st->dwReparse = wfd.dwReserved0;
+ switch(wfd.dwReserved0) {
+ case IO_REPARSE_TAG_MOUNT_POINT: {
+ st->cReparse = 'm';
+ } break;
+ case IO_REPARSE_TAG_SYMLINK: {
+ st->cReparse = 'l';
+ } break;
+ }
+ }
+ FindClose(hFFF);
+ }
+ }
+ }
+#endif
+ } else {
+ if(app) {
+ /* _wstat64() failed! */
+#if DK3_CHAR_SIZE == 2
+ dk3app_log_i3(app, DK3_LL_ERROR, 61, 163, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 73);
+#endif
+ }
+ }
+ }
+
+#line 1953 "dk3sf.ctr"
+ return back;
+}
+
+
+
+static
+int
+dk3sf_c16_check_open_file(dk3_c16_t const *fn, int want_to_write, dk3_app_t *app)
+{
+ int back = 1;
+ dk3_stat_t stb; /* Check for existing file. */
+ if(dk3sf_c16_stat_app(&stb, fn, NULL)) {
+ if(((stb.ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_DIRECTORY) {
+ if(app) {
+ back = 0;
+ /* Name refers a directory! */
+#if DK3_CHAR_SIZE == 2
+ dk3app_log_i3(app, DK3_LL_ERROR, 74, 75, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 76);
+#endif
+ }
+ }
+ if(want_to_write) {
+ /* Place for additional checks to write files here. */
+ }
+ }
+ return back;
+}
+
+
+
+FILE *
+dk3sf_c16_fopen_app(dk3_c16_t const *fn, dk3_c16_t const *mo, dk3_app_t *app)
+{
+ FILE *back = NULL;
+ dk3_c16_t const *moptr = NULL; /* Traverse mode string. */
+ int want_to_write = 0; /* Flag: Write access wanted. */
+ if((fn) && (mo)) {
+ moptr = mo;
+ while(*moptr) {
+ switch(*moptr) {
+ case L'w': case L'a': case L'+': { want_to_write = 1; } break;
+ }
+ moptr++;
+ }
+ if(dk3sf_c16_check_open_file(fn, want_to_write, app)) {
+ back = _wfopen(fn, mo);
+ if(!(back)) {
+ if(app) {
+ /* Failed to open file for writing! */
+ if(want_to_write) {
+#if DK3_CHAR_SIZE == 2
+ dk3app_log_i3(app, DK3_LL_ERROR, 77, 78, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 79);
+#endif
+ } else {
+#if DK3_CHAR_SIZE == 2
+ dk3app_log_i3(app, DK3_LL_ERROR, 143, 144, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 145);
+#endif
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c16_time_convert_app(
+ dk3_c16_t *dest, size_t sz, dk3_time_t const *timer, dk3_app_t *app
+)
+{
+ int back = 0;
+ char buffer[64];
+ if(dk3sf_c8_time_convert_app(buffer, sizeof(buffer), timer, app)) {
+ back = dk3str_cnv_c8p_to_c16_app(dest, sz, buffer, app);
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c16_getcwd_app(dk3_c16_t *dest, size_t sz, dk3_app_t *app)
+{
+ int back = 0;
+ if((dest) && (sz)) {
+ if(_wgetcwd(dest, (int)sz)) {
+ back = 1;
+ } else {
+ if(app) {
+ switch(errno) {
+#ifdef ERANGE
+ case ERANGE: {
+ /* Buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ } break;
+#endif
+ default: {
+ /* Failed to find current working directory! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 53);
+ } break;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c16_find_exec_app(
+ dk3_c16_t *d, size_t s, dk3_c16_t const *w, dk3_c16_t const *c, dk3_app_t *app
+)
+{
+ int back = 0;
+ if((d) && (s)) {
+ if(GetModuleFileNameW(GetModuleHandle(NULL),d,(DWORD)s)) {
+ back = 1;
+ } else {
+ if(app) {
+ /* Failed to find name of executable! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 40);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+static
+int
+dk3sf_c16_is_drive(dk3_c16_t const *p)
+{
+ int back = 0;
+ if(dk3str_c16_len(p) == 2) {
+ if((*p >= L'A') && (*p <= L'Z')) {
+ back = 1;
+ }
+ if((*p >= L'a') && (*p <= L'z')) {
+ back = 1;
+ }
+ if(back) {
+ back = 0;
+ if(p[1] == L':') { back = 1; }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c16_mkdir_app(dk3_c16_t const *p, int mo, dk3_app_t *app)
+{
+ int back = 0;
+ dk3_c16_t buffer[DK3_MAX_PATH]; /* File names of parent directories. */
+ dk3_c16_t *ptr = NULL; /* Current slash/backslash position. */
+ int cc = 1; /* Flag: Can continue. */
+ int m = 0; /* Permissions. */
+ dk3_stat_t stb; /* Test whether file/dir exists. */
+ if(p) {
+ m = dk3sf_convert_back_file_permissions(mo);
+ if(dk3str_c16_len(p) < sizeof(buffer)) {
+ dk3str_c16_cpy(buffer, p);
+ ptr = buffer; cc = 1;
+ while((cc) && (ptr)) {
+ ptr = dk3str_c16_chr(ptr, 0x005CU);
+ if(ptr) {
+ *ptr = 0U;
+ if((dk3str_c16_len(buffer) > 0) && (!dk3sf_c16_is_drive(buffer))) {
+ if(dk3sf_c16_stat_app(&stb, buffer, NULL)) {
+ if(((stb.ft) & (~(DK3_FT_SYMLINK))) != DK3_FT_DIRECTORY) {
+ cc = 0;
+ if(app) {
+ /* Not a directory! */
+#if DK3_CHAR_SIZE == 2
+ dk3app_log_i3(app, DK3_LL_ERROR, 81, 82, buffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 83);
+#endif
+ }
+ }
+ } else {
+ if(_wmkdir(buffer) != 0) {
+ cc = 0;
+ if(app) {
+ /* Failed to create directory! */
+#if DK3_CHAR_SIZE == 2
+ dk3app_log_i3(app, DK3_LL_ERROR, 84, 85, buffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 86);
+#endif
+ }
+ }
+ }
+ }
+ *ptr = 0x005CU;
+ ptr++;
+ }
+ }
+ if(cc) {
+ if(dk3sf_c16_stat_app(&stb, buffer, NULL)) {
+ if(((stb.ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_DIRECTORY) {
+ back = 1;
+ } else {
+ if(app) {
+ /* Not a directory! */
+#if DK3_CHAR_SIZE == 2
+ dk3app_log_i3(app, DK3_LL_ERROR, 81, 82, buffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 83);
+#endif
+ }
+ }
+ } else {
+ if(_wmkdir(buffer) == 0) {
+ back = 1;
+ } else {
+#if DK3_CHAR_SIZE == 2
+ dk3app_log_i3(app, DK3_LL_ERROR, 84, 85, buffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 86);
+#endif
+ }
+ }
+ }
+ } else {
+ if(app) {
+ /* Path too long! */
+#if DK3_CHAR_SIZE == 2
+ dk3app_log_i3(app, DK3_LL_ERROR, 59, 60, p);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 87);
+#endif
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c16_get_hostname_app(dk3_c16_t *db, size_t sz, dk3_app_t *app)
+{
+ int back = 0;
+ DWORD s = 0; /* Buffer size / result length. */
+ if((db) && (sz)) {
+ s = (DWORD)sz;
+ if(GetComputerNameExW(ComputerNameNetBIOS, db, &s)) {
+ if((size_t)s < sz) {
+ db[(size_t)s] = L'\0';
+ } else {
+ db[sz - 1] = L'\0';
+ }
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Failed to find NetBIOS name! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 131);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c8_get_hostname_app(char *db, size_t sz, dk3_app_t *app)
+{
+ int back = 0;
+ DWORD s = 0; /* Buffer size / result length. */
+ if((db) && (sz)) {
+ s = (DWORD)sz;
+ if(GetComputerNameExA(ComputerNameNetBIOS, db, &s)) {
+ if((size_t)s < sz) {
+ db[(size_t)s] = '\0';
+ } else {
+ db[sz - 1] = '\0';
+ }
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Failed to find NetBIOS name! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 131);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "dkChar must be 8 or 16 bit!"
+#else
+/* +++ Windows, dkChar 16 bit +++ */
+
+
+
+int
+dk3sf_fgets_fn_app(
+ dkChar *db, size_t sz, FILE *fi, dkChar const *fn, dk3_app_t *app
+)
+{
+ int back = 0;
+
+
+#line 2271 "dk3sf.ctr"
+ if((db) && (sz) && (fi)) {
+ if(fgetws(db, (int)sz, fi)) {
+ if(db[0] == DK3_CHAR_BOM) {
+
+#line 2274 "dk3sf.ctr"
+ dk3str_c16_cpy(db, &(db[1]));
+ }
+ back = 1;
+ } else {
+ if(!feof(fi)) {
+ if(app) {
+ if(fn) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 346, 347, fn);
+ } else {
+ dk3app_log_i1(app, DK3_LL_ERROR, 345);
+ }
+ }
+ }
+ }
+ }
+
+#line 2289 "dk3sf.ctr"
+ return back;
+}
+
+
+
+int
+dk3sf_fputc_fn_app(dkChar ch, FILE *fi, dkChar const *fn, dk3_app_t *app)
+{
+ int back = 0;
+ if(fi) {
+ if(fputwc(ch, fi) != WEOF) {
+ back = 1;
+ } else {
+ if(app) {
+ if(fn) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 343, 344, fn);
+ } else {
+ dk3app_log_i1(app, DK3_LL_ERROR, 120);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_fputs_fn_app(dkChar const *st,FILE *fi,dkChar const *fn,dk3_app_t *app)
+{
+ int back = 0;
+ if((st) && (fi)) {
+ if(fputws(st, fi) != WEOF) {
+ back = 1;
+ } else {
+ if(app) {
+ if(fn) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 343, 344, fn);
+ } else {
+ dk3app_log_i1(app, DK3_LL_ERROR, 120);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void
+dk3sf_initialize_stdout(void)
+{
+ static int not_bom_written_to_stdout = 1;
+ if(not_bom_written_to_stdout) {
+ not_bom_written_to_stdout = 0;
+ (void)_setmode(_fileno(stdout), _O_U16TEXT);
+ if(!_isatty(_fileno(stdout))) {
+ fputwc(0xFEFF, stdout);
+ }
+ }
+}
+
+
+
+void
+dk3sf_initialize_stdout_no_bom(void)
+{
+ static int not_bom_written_to_stdout = 1;
+ if(not_bom_written_to_stdout) {
+ not_bom_written_to_stdout = 0;
+ (void)_setmode(_fileno(stdout), _O_U16TEXT);
+ }
+}
+
+
+
+void
+dk3sf_initialize_stderr(void)
+{
+ static int not_bom_written_to_stderr = 1;
+ if(not_bom_written_to_stderr) {
+ not_bom_written_to_stderr = 0;
+ (void)_setmode(_fileno(stderr), _O_U16TEXT);
+ if(!_isatty(_fileno(stderr))) {
+ fputwc(0xFEFF, stderr);
+ }
+ }
+}
+
+
+
+void
+dk3sf_initialize_file(FILE *fipo)
+{
+ (void)_setmode(_fileno(fipo), _O_U16TEXT);
+ fputwc(0xFEFF, fipo);
+}
+
+
+
+/* --- Windows, dkChar 16 bit --- */
+#endif
+#else
+/* +++ Windows, dkChar 8 bit +++ */
+
+
+
+int
+dk3sf_fgets_fn_app(
+ dkChar *db, size_t sz, FILE *fi, dkChar const *fn, dk3_app_t *app
+)
+{
+ int back = 0;
+ if((db) && (sz) && (fi)) {
+ if(fgets(db, sz, fi)) {
+ back = 1;
+ } else {
+ if(!feof(fi)) {
+ if(app) {
+ if(fn) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 346, 347, fn);
+ } else {
+ dk3app_log_i1(app, DK3_LL_ERROR, 345);
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+int
+dk3sf_fputs_fn_app(dkChar const *st,FILE *fi,dkChar const *fn,dk3_app_t *app)
+{
+ int back = 0;
+ if((st) && (fi)) {
+ if(fputs(st, fi) != EOF) {
+ back = 1;
+ } else {
+ if(app) {
+ if(fn) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 343, 344, fn);
+ } else {
+ dk3app_log_i1(app, DK3_LL_ERROR, 120);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_fputc_fn_app(dkChar ch, FILE *fi, dkChar const *fn, dk3_app_t *app)
+{
+ int back = 0;
+ if(fi) {
+ if(fputc(ch, fi) != EOF) {
+ back = 1;
+ } else {
+ if(app) {
+ if(fn) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 343, 344, fn);
+ } else {
+ dk3app_log_i1(app, DK3_LL_ERROR, 120);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void
+dk3sf_initialize_stdout(void)
+{
+}
+
+
+
+void
+dk3sf_initialize_stderr(void)
+{
+}
+
+
+void
+dk3sf_initialize_file(FILE *fipo)
+{
+}
+
+
+/* --- Windows, dkChar 8 bit --- */
+#endif
+
+/* --- Windows --- */
+#else
+/* +++ non-Windows +++ */
+
+
+
+/** 8-bit character keywords for use on non-Windows systems.
+*/
+static char const * const kw_c8_no_win[] = {
+/* 0 */ "/",
+/* 1 */ "PATH",
+NULL
+};
+
+
+
+dk3_um_t
+dk3sf_getpid(void)
+{
+ dk3_um_t back = DK3_UM_0;
+#if DK3_HAVE_GETPID
+ back = (dk3_um_t)getpid();
+#else
+#if DK3_HAVE__GETPID
+ back = (dk3_um_t)_getpid();
+#else
+#error "No getpid() function!"
+#endif
+#endif
+ return back;
+}
+
+
+
+dk3_c8_t *
+dk3sf_c8_getenv(char const *name)
+{
+ char *back = NULL;
+ if(name) {
+ back = getenv(name);
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c8_remove_dir_app(char const *n, dk3_app_t *app)
+{
+ int back = 0;
+ if(n) {
+#if DK3_HAVE_RMDIR
+ if(rmdir(n) == 0) {
+ back = 1;
+ } else {
+ if(app) {
+ /* Failed to remove directory! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 69, 70, n);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 68);
+#endif
+ dk3sf_report_errno(app, errno, dk3sf_function_names[2]);
+ }
+ }
+#else
+#error "No rmdir() function!"
+#endif
+ }
+ return back;
+}
+
+
+int
+dk3sf_c8_remove_file_app(char const *n, dk3_app_t *app)
+{
+ int back = 0;
+ if(n) {
+#if DK3_HAVE_UNLINK
+ if(unlink(n) == 0) {
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Failed to unlink file */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 88, 89, n);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 90);
+#endif
+ dk3sf_report_errno(app, errno, dk3sf_function_names[3]);
+ }
+ }
+#else
+#error "No support for unlink"
+#endif
+ }
+ return back;
+}
+
+
+/** Copy logname of user record to buffer.
+ @param d Destination buffer.
+ @param s Size of \a d.
+ @param p User record.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3sf_c8_copy_logname(char *d, size_t s, struct passwd *p, dk3_app_t *app)
+{
+ int back = 0;
+
+
+#line 2600 "dk3sf.ctr"
+ if(p) {
+
+#line 2601 "dk3sf.ctr"
+ if(p->pw_name) {
+
+#line 2602 "dk3sf.ctr"
+ if(dk3str_c8_len(p->pw_name) < s) {
+
+#line 2603 "dk3sf.ctr"
+ dk3str_c8_cpy_not_overlapped(d, p->pw_name);
+ back = 1;
+ } else {
+
+#line 2606 "dk3sf.ctr"
+ if(app) {
+ /* Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ } else {
+ if(app) {
+ /* No name entry in record! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 91);
+ }
+ }
+ }
+
+#line 2618 "dk3sf.ctr"
+ return back;
+}
+
+
+
+int
+dk3sf_c8_get_logname_app(char *d, size_t s, dk3_app_t *app)
+{
+ int back = 0;
+ uid_t u = 0; /* Current user ID. */
+ struct passwd *p = NULL; /* Current user to process. */
+ char uidbuffer[128]; /* Text buffer to store UID. */
+
+
+#line 2631 "dk3sf.ctr"
+ if((d) && (s)) {
+ u = getuid();
+#if DK3_HAVE_GETPWUID
+ p = getpwuid(u);
+
+#line 2635 "dk3sf.ctr"
+ if(p) {
+
+#line 2636 "dk3sf.ctr"
+ back = dk3sf_c8_copy_logname(d, s, p, app);
+ } else {
+
+#line 2638 "dk3sf.ctr"
+ if(app) {
+ /* No passwd record for UID! */
+#if DK3_CHAR_SIZE == 1
+ dk3ma_um_to_c8_string(uidbuffer, sizeof(uidbuffer), (dk3_um_t)u);
+ dk3app_log_i3(app, DK3_LL_ERROR, 92, 93, uidbuffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 94);
+#endif
+ dk3sf_report_errno(app, errno, dk3sf_function_names[4]);
+ }
+ }
+#else
+#if DK3_HAVE_SETPWENT
+ setpwent();
+#endif
+ {
+ int cc;
+ int found;
+
+#line 2656 "dk3sf.ctr"
+ cc = 1; found = 0;
+ while(cc) {
+ p = getpwent();
+ if(p) {
+ if(p->pw_uid == u) {
+ cc = 0;
+ found = 1;
+
+#line 2663 "dk3sf.ctr"
+ back = dk3sf_c8_copy_logname(d, s, p, app);
+ }
+ } else { cc = 0; }
+ }
+ if(!found) {
+
+#line 2668 "dk3sf.ctr"
+ if(app) {
+ /* No passwd record for UID! */
+#if DK3_CHAR_SIZE == 1
+ dk3ma_um_to_c8_string(uidbuffer, sizeof(uidbuffer), (dk3_um_t)u);
+ dk3app_log_i3(app, DK3_LL_ERROR, 92, 93, uidbuffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 94);
+#endif
+ }
+ }
+ }
+#if DK3_HAVE_SETPWENT
+ endpwent();
+#endif
+#endif
+ }
+
+#line 2684 "dk3sf.ctr"
+ return back;
+}
+
+
+
+int
+dk3sf_c8_get_home_app(char *d, size_t s, dk3_app_t *app)
+{
+ int back = 0;
+ uid_t u = 0; /* Current user ID to process. */
+ struct passwd *p = NULL; /* Current user to process. */
+ char uidbuffer[128]; /* Text buffer to store UID. */
+ if((d) && (s)) {
+ u = getuid();
+#if DK3_HAVE_GETPWUID
+ p = getpwuid(u);
+ if(p) {
+ if(p->pw_dir) {
+ if(dk3str_c8_len(p->pw_dir) < s) {
+ dk3str_c8_cpy_not_overlapped(d, p->pw_dir);
+ back = 1;
+ } else {
+ if(app) {
+ /* Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ } else {
+ if(app) {
+ /* Home directory entry empty! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 95);
+ }
+ }
+ } else {
+ if(app) {
+ /* No passwd record for uid! */
+#if DK3_CHAR_SIZE == 1
+ dk3ma_um_to_c8_string(uidbuffer, sizeof(uidbuffer), (dk3_um_t)u);
+ dk3app_log_i3(app, DK3_LL_ERROR, 92, 93, uidbuffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 94);
+#endif
+ dk3sf_report_errno(app, errno, dk3sf_function_names[4]);
+ }
+ }
+#else
+ {
+ int cc;
+ int found;
+ cc = 1; found = 0;
+#if DK3_HAVE_SETPWENT
+ setpwent();
+#endif
+ while(cc) {
+ p = getpwent();
+ if(p) {
+ if(p->pw_uid == u) {
+ cc = 0; found = 1;
+ if(p->pw_dir) {
+ if(dk3str_c8_len(p->pw_dir) < s) {
+ dk3str_c8_cpy_not_overlapped(d, p->pw_dir);
+ back = 1;
+ } else {
+ if(app) {
+ /* Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ } else {
+ if(app) {
+ /* Home directory entry empty! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 95);
+ }
+ }
+ }
+ } else { cc = 0; }
+ }
+#if DK3_HAVE_SETPWENT
+ endpwent();
+#endif
+ if(!found) {
+ if(app) {
+ /* No entry for uid! */
+#if DK3_CHAR_SIZE == 1
+ dk3ma_um_to_c8_string(uidbuffer, sizeof(uidbuffer), (dk3_um_t)u);
+ dk3app_log_i3(app, DK3_LL_ERROR, 92, 93, uidbuffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 94);
+#endif
+ }
+ }
+ }
+#endif
+ }
+ return back;
+}
+
+
+int
+dk3sf_time(dk3_time_t *timer)
+{
+ int back = 1;
+ time(timer);
+ return back;
+}
+
+
+
+/** Convert file type from system representation to DK3_FT_xxx.
+ @param m File type as found by stat().
+ @return DK3_FT_xxx.
+*/
+static
+int
+dk3sf_convert_file_type(mode_t m)
+{
+ int back = 0;
+ switch(m & S_IFMT) {
+ case S_IFIFO: back = DK3_FT_FIFO; break;
+ case S_IFCHR: back = DK3_FT_SPECIAL_CHAR; break;
+ case S_IFDIR: back = DK3_FT_DIRECTORY; break;
+ case S_IFBLK: back = DK3_FT_SPECIAL_BLOCK; break;
+ case S_IFREG: back = DK3_FT_REGULAR; break;
+ case S_IFSOCK: back = DK3_FT_SOCKET; break;
+#ifdef S_IFMPC
+ case S_IFMPC: back = DK3_FT_MUX_CHAR; break;
+#endif
+#ifdef S_IFNAM
+ case S_IFNAM: back = DK3_FT_XENIX_SPECIAL; break;
+#endif
+#ifdef S_INSEM
+ case S_INSEM: back = DK3_FT_XENIX_SEMAPHORE; break;
+#endif
+#ifdef S_INSHD
+ case S_INSHD: back = DK3_FT_XENIX_SHARED_DATA; break;
+#endif
+#ifdef S_IFMPB
+ case S_IFMPB: back = DK3_FT_MUX_BLOCK; break;
+#endif
+#ifdef S_IFCMP
+ case S_IFCMP: back = DK3_FT_VXFS_COMPRESSED; break;
+#endif
+#ifdef S_IFNWK
+ case S_IFNWK: back = DK3_FT_NETWORK_SPECIAL; break;
+#endif
+#ifdef S_IFSHAD
+ case S_IFSHAD: back = DK3_FT_ACL_SHADOW; break;
+#endif
+#ifdef S_IFDOOR
+ case S_IFDOOR: back = DK3_FT_DOOR; break;
+#endif
+#ifdef S_IFWHT
+ case S_IFWHT: back = DK3_FT_WHITEOUT; break;
+#endif
+ }
+ return back;
+}
+
+
+
+/** Convert file permissions from system representation to
+ DK3_PERM_xxx
+ @param m File mode as obtained from stat().
+ @return DK3_PERM_xxx value or combination.
+*/
+static
+int
+dk3sf_convert_file_permissions(mode_t m)
+{
+ int back = 0;
+ DK3SF_ADDIF(S_IRUSR,DK3_FPERM_U_READ)
+ DK3SF_ADDIF(S_IWUSR,DK3_FPERM_U_WRITE)
+ DK3SF_ADDIF(S_IXUSR,DK3_FPERM_U_EXEC)
+ DK3SF_ADDIF(S_IRGRP,DK3_FPERM_G_READ)
+ DK3SF_ADDIF(S_IWGRP,DK3_FPERM_G_WRITE)
+ DK3SF_ADDIF(S_IXGRP,DK3_FPERM_G_EXEC)
+ DK3SF_ADDIF(S_IROTH,DK3_FPERM_O_READ)
+ DK3SF_ADDIF(S_IWOTH,DK3_FPERM_O_WRITE)
+ DK3SF_ADDIF(S_IXOTH,DK3_FPERM_O_EXEC)
+ DK3SF_ADDIF(S_ISUID,DK3_FPERM_SUID)
+ DK3SF_ADDIF(S_ISGID,DK3_FPERM_SGID)
+ DK3SF_ADDIF(S_ISVTX,DK3_FPERM_VTX)
+ return back;
+}
+
+
+
+/** Convert file permissions back from dktools to system values.
+ @param m File permissions in dktools notation.
+ @return File permissions in system notation.
+*/
+static
+mode_t
+dk3sf_convert_back_file_permissions(int m)
+{
+ mode_t back = 0;
+ DK3SF_ADDIF(DK3_FPERM_U_READ,S_IRUSR)
+ DK3SF_ADDIF(DK3_FPERM_U_WRITE,S_IWUSR)
+ DK3SF_ADDIF(DK3_FPERM_U_EXEC,S_IXUSR)
+ DK3SF_ADDIF(DK3_FPERM_G_READ,S_IRGRP)
+ DK3SF_ADDIF(DK3_FPERM_G_WRITE,S_IWGRP)
+ DK3SF_ADDIF(DK3_FPERM_G_EXEC,S_IXGRP)
+ DK3SF_ADDIF(DK3_FPERM_O_READ,S_IROTH)
+ DK3SF_ADDIF(DK3_FPERM_O_WRITE,S_IWOTH)
+ DK3SF_ADDIF(DK3_FPERM_O_EXEC,S_IXOTH)
+ DK3SF_ADDIF(DK3_FPERM_SUID,S_ISUID)
+ DK3SF_ADDIF(DK3_FPERM_SGID,S_ISGID)
+ DK3SF_ADDIF(DK3_FPERM_VTX,S_ISVTX)
+ return back;
+}
+
+
+int
+dk3sf_c8_stat_app(dk3_stat_t *st, char const *fn, dk3_app_t *app)
+{
+ int back = 0;
+
+
+#line 2901 "dk3sf.ctr"
+ if((st) && (fn)) {
+#if DK3_HAVE_LARGEFILE64_SOURCE && DK3_HAVE_STAT64
+ struct stat64 stb; /* Result from stat64(). */
+#if DK3_HAVE_LSTAT64
+ struct stat64 lstb; /* Result from lstat64(). */
+#endif
+
+
+#line 2908 "dk3sf.ctr"
+ if(stat64(fn, &stb) == 0) {
+
+#line 2909 "dk3sf.ctr"
+ st->u = (dk3_um_t)(stb.st_uid);
+ st->g = (dk3_um_t)(stb.st_gid);
+ st->device = (dk3_um_t)(stb.st_dev);
+ st->rdev = (dk3_um_t)(stb.st_rdev);
+ st->inode = (dk3_um_t)(stb.st_ino);
+ st->nlink = (dk3_um_t)(stb.st_nlink);
+ st->cre = (dk3_time_t)(stb.st_ctime);
+ st->mod = (dk3_time_t)(stb.st_mtime);
+ st->acc = (dk3_time_t)(stb.st_atime);
+ st->ft = dk3sf_convert_file_type(stb.st_mode);
+ st->perm = dk3sf_convert_file_permissions(stb.st_mode);
+ st->sz = (dk3_um_t)(stb.st_size);
+ st->lsz = st->sz;
+ st->ai = 0x00;
+#if DK3_HAVE_LSTAT64
+ if(lstat64(fn, &lstb) == 0) {
+ back = 1;
+ if(((lstb.st_mode) & S_IFMT) == S_IFLNK) {
+ st->ft |= DK3_FT_SYMLINK;
+ st->lu = (dk3_um_t)(lstb.st_uid);
+ st->lg = (dk3_um_t)(lstb.st_gid);
+ st->ldevice = (dk3_um_t)(lstb.st_dev);
+ st->lrdev = (dk3_um_t)(lstb.st_rdev);
+ st->linode = (dk3_um_t)(lstb.st_ino);
+ st->lnlink = (dk3_um_t)(lstb.st_nlink);
+ st->lcre = (dk3_time_t)(lstb.st_ctime);
+ st->lmod = (dk3_time_t)(lstb.st_mtime);
+ st->lacc = (dk3_time_t)(lstb.st_atime);
+ st->lft = dk3sf_convert_file_type(lstb.st_mode);
+ st->lperm = dk3sf_convert_file_permissions(lstb.st_mode);
+ st->lsz = (dk3_um_t)(lstb.st_size);
+ if(lstb.st_uid != stb.st_uid) {
+ st->ai |= DK3_STAT_AI_USER_DIFFERS;
+ }
+ if(lstb.st_gid != stb.st_gid) {
+ st->ai |= DK3_STAT_AI_GROUP_DIFFERS;
+ }
+ if(lstb.st_dev != stb.st_dev) {
+ st->ai |= DK3_STAT_AI_FAR_LINK;
+ }
+ }
+
+#line 2950 "dk3sf.ctr"
+ } else {
+
+#line 2951 "dk3sf.ctr"
+ if(app) {
+ /* lstat() failed! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 96, 97, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 98);
+#endif
+ }
+ }
+#else
+ back = 1;
+#endif
+ } else {
+
+#line 2964 "dk3sf.ctr"
+#if DK3_HAVE_LSTAT64
+ if(lstat64(fn, &lstb) == 0) {
+ back = 1;
+ st->u = DK3_UM_0;
+ st->g = DK3_UM_0;
+ st->device = DK3_UM_0;
+ st->rdev = DK3_UM_0;
+ st->inode = DK3_UM_0;
+ st->nlink = DK3_UM_0;
+ st->cre = (dk3_time_t)0UL;
+ st->mod = (dk3_time_t)0UL;
+ st->acc = (dk3_time_t)0UL;
+ st->ft = DK3_FT_SYMLINK | DK3_FT_BAD_SYMLINK;
+ st->perm = 0;
+ st->sz = DK3_UM_0;
+ st->ai = 0x00;
+ st->lu = (dk3_um_t)(lstb.st_uid);
+ st->lg = (dk3_um_t)(lstb.st_gid);
+ st->ldevice = (dk3_um_t)(lstb.st_dev);
+ st->lrdev = (dk3_um_t)(lstb.st_rdev);
+ st->linode = (dk3_um_t)(lstb.st_ino);
+ st->lnlink = (dk3_um_t)(lstb.st_nlink);
+ st->lcre = (dk3_time_t)(lstb.st_ctime);
+ st->lmod = (dk3_time_t)(lstb.st_mtime);
+ st->lacc = (dk3_time_t)(lstb.st_atime);
+ st->lft = dk3sf_convert_file_type(lstb.st_mode);
+ st->lperm = dk3sf_convert_file_permissions(lstb.st_mode);
+ st->lsz = (dk3_um_t)(lstb.st_size);
+ } else {
+ if(app) {
+ /* stat failed */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 61, 62, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 99);
+#endif
+ dk3sf_report_errno(app, errno, dk3sf_function_names[5]);
+ }
+ }
+#else
+ if(app) {
+ /* stat failed */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 61, 62, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 99);
+#endif
+ dk3sf_report_errno(app, errno, dk3sf_function_names[6]);
+ }
+#endif
+ }
+#else
+#if DK3_HAVE_STAT
+ struct stat stb;
+#if DK3_HAVE_LSTAT
+ struct stat lstb;
+#endif
+
+
+#line 3022 "dk3sf.ctr"
+ if(stat(fn, &stb) == 0) {
+
+#line 3023 "dk3sf.ctr"
+ st->u = (dk3_um_t)(stb.st_uid);
+ st->g = (dk3_um_t)(stb.st_gid);
+ st->device = (dk3_um_t)(stb.st_dev);
+ st->rdev = (dk3_um_t)(stb.st_rdev);
+ st->inode = (dk3_um_t)(stb.st_ino);
+ st->nlink = (dk3_um_t)(stb.st_nlink);
+ st->cre = (dk3_time_t)(stb.st_ctime);
+ st->mod = (dk3_time_t)(stb.st_mtime);
+ st->acc = (dk3_time_t)(stb.st_atime);
+ st->ft = dk3sf_convert_file_type(stb.st_mode);
+ st->perm = dk3sf_convert_file_permissions(stb.st_mode);
+ st->sz = (dk3_um_t)(stb.st_size);
+ sz->lsz = st->sz;
+ st->ai = 0x00;
+#if DK3_HAVE_LSTAT
+ if(lstat(fn, &lstb) == 0) {
+ back = 1;
+ if(((lstb.st_mode) & S_IFMT) == S_IFLNK) {
+ st->ft |= DK3_FT_SYMLINK;
+ st->lu = (dk3_um_t)(lstb.st_uid);
+ st->lg = (dk3_um_t)(lstb.st_gid);
+ st->ldevice = (dk3_um_t)(lstb.st_dev);
+ st->lrdev = (dk3_um_t)(lstb.st_rdev);
+ st->linode = (dk3_um_t)(lstb.st_ino);
+ st->lnlink = (dk3_um_t)(lstb.st_nlink);
+ st->lcre = (dk3_time_t)(lstb.st_ctime);
+ st->lmod = (dk3_time_t)(lstb.st_mtime);
+ st->lacc = (dk3_time_t)(lstb.st_atime);
+ st->lft = dk3sf_convert_file_type(lstb.st_mode);
+ st->lperm = dk3sf_convert_file_permissions(lstb.st_mode);
+ sz->lsz = (dk3_um_t)(lstb.st_size);
+ if(lstb.st_uid != stb.st_uid) {
+ st->ai |= DK3_STAT_AI_USER_DIFFERS;
+ }
+ if(lstb.st_gid != stb.st_gid) {
+ st->ai |= DK3_STAT_AI_GROUP_DIFFERS;
+ }
+ if(lstb.st_dev != stb.st_dev) {
+ st->ai |= DK3_STAT_AI_FAR_LINK;
+ }
+ }
+
+#line 3064 "dk3sf.ctr"
+ } else {
+
+#line 3065 "dk3sf.ctr"
+ if(app) {
+ /* lstat() failed! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 96, 97, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 98);
+#endif
+ }
+ }
+#else
+ back = 1;
+#endif
+ } else {
+
+#line 3078 "dk3sf.ctr"
+#if DK3_HAVE_LSTAT
+ if(lstat(fn,&lstb) == 0) {
+ back = 1;
+ st->u = DK3_UM_0;
+ st->g = DK3_UM_0;
+ st->device = DK3_UM_0;
+ st->rdev = DK3_UM_0;
+ st->inode = DK3_UM_0;
+ st->nlink = DK3_UM_0;
+ st->cre = (dk3_time_t)0UL;
+ st->mod = (dk3_time_t)0UL;
+ st->acc = (dk3_time_t)0UL;
+ st->ft = DK3_FT_SYMLINK | DK3_FT_BAD_SYMLINK;
+ st->perm = 0;
+ st->sz = DK3_UM_0;
+ st->ai = 0x00;
+ st->lu = (dk3_um_t)(lstb.st_uid);
+ st->lg = (dk3_um_t)(lstb.st_gid);
+ st->ldevice = (dk3_um_t)(lstb.st_dev);
+ st->lrdev = (dk3_um_t)(lstb.st_rdev);
+ st->linode = (dk3_um_t)(lstb.st_ino);
+ st->lnlink = (dk3_um_t)(lstb.st_nlink);
+ st->lcre = (dk3_time_t)(lstb.st_ctime);
+ st->lmod = (dk3_time_t)(lstb.st_mtime);
+ st->lacc = (dk3_time_t)(lstb.st_atime);
+ st->lft = dk3sf_convert_file_type(lstb.st_mode);
+ st->lperm = dk3sf_convert_file_permissions(lstb.st_mode);
+ st->lsz = (dk3_um_t)(lstb.st_size);
+ } else {
+ if(app) {
+ /* stat() failed! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 61, 62, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 99);
+#endif
+ dk3sf_report_errno(app, errno, dk3sf_function_names[8]);
+ }
+ }
+#else
+ if(app) {
+ /* stat() failed! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 61, 62, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 99);
+#endif
+ dk3sf_report_errno(app, errno, dk3sf_function_names[7]);
+ }
+#endif
+ }
+#else
+#error "Not stat() function available!"
+#endif
+#endif
+ }
+
+#line 3134 "dk3sf.ctr"
+ return back;
+}
+
+
+
+/** Check whether opening a file is allowed.
+ @param fn File name.
+ @param want_to_write Flag: Write access is wanted.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 for write allowed, 0 for write denied.
+*/
+static
+int
+dk3sf_c8_check_open_file(char const *fn, int want_to_write, dk3_app_t *app)
+{
+ int back = 1;
+ dk3_stat_t stb; /* Check for existing file. */
+ if(dk3sf_c8_stat_app(&stb, fn, NULL)) {
+ if(((stb.ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_DIRECTORY) {
+ if(app) {
+ back = 0;
+ /* Name refers a directory! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 74, 75, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 76);
+#endif
+ }
+ }
+ if(want_to_write) {
+ if((stb.ft) & DK3_FT_SYMLINK) {
+ if((stb.ai) & DK3_STAT_AI_USER_DIFFERS) {
+ back = 0;
+ /* Symlink owner is not file owner! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 100, 101, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 102);
+#endif
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+FILE *
+dk3sf_c8_fopen_app(char const *fn, char const *mo, dk3_app_t *app)
+{
+ FILE *back = NULL;
+ char const *moptr = NULL; /* Traverse mode string. */
+ int want_to_write = 0; /* Flag: Write access wanted. */
+
+
+#line 3189 "dk3sf.ctr"
+ if((fn) && (mo)) {
+ moptr = mo;
+ while(*moptr) {
+ switch(*moptr) {
+ case 'w': case 'a': case '+': { want_to_write = 1; } break;
+ }
+ moptr++;
+ }
+ if(dk3sf_c8_check_open_file(fn, want_to_write, app)) {
+#if DK3_HAVE_LARGEFILE64_SOURCE && DK3_HAVE_FOPEN64
+ back = fopen64(fn, mo);
+
+#line 3200 "dk3sf.ctr"
+#else
+ back = fopen(fn, mo);
+
+#line 3202 "dk3sf.ctr"
+#endif
+ if(!(back)) {
+ if(app) {
+ /* Failed to open file for writing! */
+ if(want_to_write) {
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 77, 78, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 79);
+#endif
+ } else {
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 143, 144, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 145);
+#endif
+ }
+ dk3sf_report_errno(app, errno, dk3sf_function_names[9]);
+ }
+ }
+ }
+ }
+
+#line 3224 "dk3sf.ctr"
+ return back;
+}
+
+
+#if DK3_HAVE_LOCALTIME_R
+int
+dk3sf_localtime_app(
+ dk3_tm_t *dest,
+ dk3_time_t *timer,
+ dk3_app_t *app
+)
+{
+ int back = 0;
+ struct tm res, *rp;
+ if((dest) && (timer)) {
+ if((rp = localtime_r(timer, &res)) != NULL) {
+ back = 1;
+ dest->Y = 1900 + rp->tm_year;
+ dest->M = 1 + rp->tm_mon;
+ dest->D = rp->tm_mday;
+ dest->h = rp->tm_hour;
+ dest->m = rp->tm_min;
+ dest->s = rp->tm_sec;
+ } else {
+ if(app) {
+ /* ERROR: localtime_r failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 268);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[10]);
+ }
+ }
+ }
+ return back;
+}
+
+int
+dk3sf_c8_time_convert_app(
+ dkChar *dest, size_t sz, dk3_time_t const *timer, dk3_app_t *app
+)
+{
+ int back = 0;
+ char buffer[64]; /* Buffer. */
+ struct tm res, *rp; /* Conversion result. */
+ if((dest) && (sz) && (timer)) {
+ rp = localtime_r(timer, &res);
+ if(rp) {
+ sprintf(
+ buffer,
+ "%04d-%02d-%02d %02d:%02d:%02d",
+ (1900 + rp->tm_year),
+ (1 + rp->tm_mon),
+ rp->tm_mday,
+ rp->tm_hour,
+ rp->tm_min,
+ rp->tm_sec
+ );
+ if(sz > dk3str_c8_len(buffer)) {
+ dk3str_c8_cpy_not_overlapped(dest, buffer);
+ back = 1;
+ } else {
+ if(app) {
+ /* Buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ } else {
+ if(app) {
+ /* localtime_r failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 80);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[10]);
+ }
+ }
+ }
+ return back;
+}
+#else
+#error "Function localtime_r() not available!"
+#endif
+
+
+
+#if DK3_HAVE_GETCWD || DK3_HAVE__GETCWD
+int
+dk3sf_c8_getcwd_app(char *dest, size_t sz, dk3_app_t *app)
+{
+ int back = 0;
+ if((dest) && (sz)) {
+#if DK3_HAVE_GETCWD
+ if(getcwd(dest, sz))
+#else
+ if(_getcwd(dest, sz))
+#endif
+ {
+ back = 1;
+ } else {
+ if(app) {
+ switch(errno) {
+#ifdef ERANGE
+ case ERANGE: {
+ /* Buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ } break;
+#endif
+ default: {
+ dk3app_log_i1(app, DK3_LL_ERROR, 53);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[11]);
+ } break;
+ }
+ }
+ }
+ }
+ return back;
+}
+#else
+#error "Neither getcwd() or _getcwd() available!"
+#endif
+
+
+
+/** Check whether or not a file is executable.
+ @param f File name.
+ @return 1 for exectuable, 0 for not executable.
+*/
+static
+int
+dk3sf_c8_check_exec(char const *f)
+{
+ int back = 0;
+ int testperm; /* Permissions of file. */
+ dk3_stat_t stb; /* stat() result to check for file. */
+
+
+#line 3354 "dk3sf.ctr"
+ if(dk3sf_c8_stat_app(&stb, f, NULL)) {
+
+#line 3355 "dk3sf.ctr"
+ if(((stb.ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_REGULAR) {
+
+#line 3356 "dk3sf.ctr"
+ testperm = (DK3_FPERM_U_EXEC | DK3_FPERM_G_EXEC | DK3_FPERM_O_EXEC);
+ if((stb.perm) & testperm) {
+
+#line 3358 "dk3sf.ctr"
+ back = 1;
+ } else {
+
+#line 3360 "dk3sf.ctr"
+ }
+ } else {
+
+#line 3362 "dk3sf.ctr"
+ }
+ } else {
+
+#line 3364 "dk3sf.ctr"
+ }
+
+#line 3365 "dk3sf.ctr"
+ return back;
+}
+
+
+
+int
+dk3sf_c8_find_exec_app(
+ char *d, size_t s, char const *w, char const *c, dk3_app_t *app
+)
+{
+ int back = 0;
+ int cc = 0; /* Flag: Can continue. */
+ char *pathcopy = NULL; /* Copy of parent directory. */
+ char *p = NULL;
+ char *pn = NULL;
+ size_t tsl = 0; /* Needed buffer length. */
+
+
+#line 3382 "dk3sf.ctr"
+ if((d) && (s) && (w) && (c)) {
+
+#line 3383 "dk3sf.ctr"
+ if(dk3str_c8_chr(c, DK3_C8_SEP)) {
+
+#line 3384 "dk3sf.ctr"
+ if(dk3str_c8_is_abs_path(c)) {
+
+#line 3385 "dk3sf.ctr"
+ if(dk3str_c8_len(c) < s) {
+
+#line 3386 "dk3sf.ctr"
+ dk3str_c8_cpy_not_overlapped(d, c);
+ back = 1;
+
+#line 3388 "dk3sf.ctr"
+ } else {
+
+#line 3389 "dk3sf.ctr"
+ if(app) {
+ /* c too long! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 103, 104, c);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 105);
+#endif
+ }
+ }
+ } else {
+
+#line 3399 "dk3sf.ctr"
+ if(dk3str_c8_len(w) < s) {
+ dk3str_c8_cpy_not_overlapped(d, w);
+ back = dk3str_c8_append_path_app(d, s, c, app);
+ if(back) {
+
+#line 3403 "dk3sf.ctr"
+ }
+ } else {
+
+#line 3405 "dk3sf.ctr"
+ if(app) {
+ /* w too long! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 59, 60, w);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 87);
+#endif
+ }
+ }
+ }
+ } else {
+
+#line 3416 "dk3sf.ctr"
+ p = getenv(kw_c8_no_win[1]);
+ if(p) {
+
+#line 3418 "dk3sf.ctr"
+ pathcopy = dk3str_dup_app(p, app);
+ if(pathcopy) {
+
+#line 3420 "dk3sf.ctr"
+ p = pathcopy; cc = 1;
+ while((p) && (cc) && (back == 0)) {
+ pn = dk3str_c8_chr(p, ':');
+ if(pn) { *(pn++) = '\0'; }
+ if(dk3str_c8_len(p)) {
+
+#line 3425 "dk3sf.ctr"
+ tsl = dk3str_c8_len(p);
+ tsl += dk3str_c8_len(kw_c8_no_win[0]);
+ tsl += dk3str_c8_len(c);
+ if(tsl < s) {
+
+#line 3429 "dk3sf.ctr"
+ dk3str_c8_cpy_not_overlapped(d, p);
+ dk3str_c8_cat(d, kw_c8_no_win[0]);
+ dk3str_c8_cat(d, c);
+ back = dk3sf_c8_check_exec(d);
+ } else {
+
+#line 3434 "dk3sf.ctr"
+ cc = 0;
+ if(app) {
+ /* Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ } else {
+
+#line 3441 "dk3sf.ctr"
+ tsl = dk3str_c8_len(w);
+ tsl += dk3str_c8_len(kw_c8_no_win[0]);
+ tsl += dk3str_c8_len(c);
+ if(tsl < s) {
+
+#line 3445 "dk3sf.ctr"
+ dk3str_c8_cpy_not_overlapped(d, w);
+ dk3str_c8_cat(d, kw_c8_no_win[0]);
+ dk3str_c8_cat(d, c);
+ back = dk3sf_c8_check_exec(d);
+ } else {
+
+#line 3450 "dk3sf.ctr"
+ cc = 0;
+ if(app) {
+ /* Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ p = pn;
+ }
+ dk3_delete(pathcopy);
+ } else {
+
+#line 3461 "dk3sf.ctr"
+ }
+ } else {
+
+#line 3463 "dk3sf.ctr"
+ if(app) {
+ /* PATH environment variable not defined. */
+ dk3app_log_i1(app, DK3_LL_ERROR, 106);
+ }
+ }
+ }
+ }
+
+#line 3470 "dk3sf.ctr"
+ return back;
+}
+
+
+
+int
+dk3sf_c8_mkdir_app(char const *p, int mo, dk3_app_t *app)
+{
+ int back = 0;
+ char buffer[DK3_MAX_PATH]; /* File names of parent directories. */
+ char *ptr = NULL; /* Current path separator. */
+ int cc = 0; /* Flag: Can continue. */
+ mode_t m = 0; /* File creation mode. */
+ dk3_stat_t stb; /* Check for existance of file or directory. */
+
+
+#line 3485 "dk3sf.ctr"
+ if(p) {
+
+#line 3486 "dk3sf.ctr"
+ m = dk3sf_convert_back_file_permissions(mo);
+ if(dk3str_c8_len(p) < sizeof(buffer)) {
+
+#line 3488 "dk3sf.ctr"
+ dk3str_c8_cpy_not_overlapped(buffer, p);
+ ptr = buffer; cc = 1;
+ while((cc) && (ptr)) {
+
+#line 3491 "dk3sf.ctr"
+ ptr = dk3str_c8_chr(ptr, DK3_C8_SEP);
+ if(ptr) {
+ *ptr = '\0';
+
+#line 3494 "dk3sf.ctr"
+ if(dk3str_c8_len(buffer) > 0) {
+ if(dk3sf_c8_stat_app(&stb, buffer, NULL)) {
+
+#line 3496 "dk3sf.ctr"
+ if(((stb.ft) & (~(DK3_FT_SYMLINK))) != DK3_FT_DIRECTORY) {
+ cc = 0;
+
+#line 3498 "dk3sf.ctr"
+ if(app) {
+ /* Not a directory! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 81, 82, buffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 83);
+#endif
+ }
+ }
+ } else {
+
+#line 3508 "dk3sf.ctr"
+#if DK3_HAVE_MKDIR
+#if DK3_HAVE_MKDIR2
+ if(mkdir(buffer, m) == 0)
+#else
+ if(mkdir(buffer) == 0)
+#endif
+ {
+#if DK3_HAVE_CHMOD
+ (void)chmod(buffer, m);
+
+#line 3517 "dk3sf.ctr"
+#endif
+ } else {
+ cc = 0;
+
+#line 3520 "dk3sf.ctr"
+ if(app) {
+ /* Failed to create directory! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 84, 85, buffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 86);
+#endif
+ dk3sf_report_errno(app, errno, dk3sf_function_names[12]);
+ }
+ }
+#else
+ cc = 0;
+ if(app) {
+
+#line 3533 "dk3sf.ctr"
+ /* No mkdir() function available! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 107);
+ }
+#endif
+ }
+ }
+ *ptr = DK3_C8_SEP;
+ ptr++;
+ }
+ }
+ if(cc) {
+
+#line 3544 "dk3sf.ctr"
+ if(dk3sf_c8_stat_app(&stb, buffer, NULL)) {
+
+#line 3545 "dk3sf.ctr"
+ if(((stb.ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_DIRECTORY) {
+ back = 1;
+
+#line 3547 "dk3sf.ctr"
+ } else {
+
+#line 3548 "dk3sf.ctr"
+ if(app) {
+ /* Not a directory! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 81, 82, buffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 83);
+#endif
+ }
+ }
+ } else {
+
+#line 3558 "dk3sf.ctr"
+#if DK3_HAVE_MKDIR
+#if DK3_HAVE_MKDIR2
+ if(mkdir(buffer, m) == 0)
+#else
+ if(mkdir(buffer) == 0)
+#endif
+ {
+ back = 1;
+
+#line 3566 "dk3sf.ctr"
+#if DK3_HAVE_CHMOD
+ (void)chmod(buffer, m);
+
+#line 3568 "dk3sf.ctr"
+#endif
+ } else {
+
+#line 3570 "dk3sf.ctr"
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 84, 85, buffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 86);
+#endif
+ dk3sf_report_errno(app, errno, dk3sf_function_names[12]);
+ }
+#else
+ if(app) {
+
+#line 3579 "dk3sf.ctr"
+ /* No mkdir() function available! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 107);
+ }
+#endif
+ }
+ }
+ } else {
+
+#line 3586 "dk3sf.ctr"
+ if(app) {
+ /* Path too long! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 59, 60, p);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 87);
+#endif
+ }
+ }
+ }
+
+#line 3596 "dk3sf.ctr"
+ return back;
+}
+
+
+int
+dk3sf_c8_get_hostname_app(char *db, size_t sz, dk3_app_t *app)
+{
+ int back = 0;
+ char *ptr = NULL; /* Begin of DNS domain name. */
+ if((db) && (sz)) {
+ if(gethostname(db, sz) == 0) {
+ back = 1;
+ ptr = dk3str_c8_chr(db, '.');
+ if(ptr) {
+ *ptr = '\0';
+ }
+ } else {
+ if(app) {
+ /* ERROR: Failed to find host name! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 131);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[13]);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+#if DK3_CHAR_SIZE > 1
+#error "dkChar must be 8 bit on non-Windows systems!"
+#else
+/* +++ non-Windows, dkChar 8 bit +++ */
+
+
+
+int
+dk3sf_fgets_fn_app(
+ dkChar *db, size_t sz, FILE *fi, dkChar const *fn, dk3_app_t *app
+)
+{
+ int back = 0;
+ if((db) && (sz) && (fi)) {
+ if(fgets(db, sz, fi)) {
+ back = 1;
+ } else {
+ if(!feof(fi)) {
+ if(app) {
+ if(fn) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 346, 347, fn);
+ } else {
+ dk3app_log_i1(app, DK3_LL_ERROR, 345);
+ }
+ dk3sf_report_errno(app, errno, dk3sf_function_names[25]);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_fputs_fn_app(dkChar const *st,FILE *fi,dkChar const *fn,dk3_app_t *app)
+{
+ int back = 0;
+ if((st) && (fi)) {
+ if(fputs(st, fi) >= 0) {
+ back = 1;
+ } else {
+ if(app) {
+ if(fn) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 343, 344, fn);
+ } else {
+ dk3app_log_i1(app, DK3_LL_ERROR, 120);
+ }
+ dk3sf_report_errno(app, errno, dk3sf_function_names[23]);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_fputc_fn_app(dkChar ch, FILE *fi, dkChar const *fn, dk3_app_t *app)
+{
+ int back = 0;
+ if(fi) {
+ if(fputc(ch, fi) != EOF) {
+ back = 1;
+ } else {
+ if(app) {
+ if(fn) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 343, 344, fn);
+ } else {
+ dk3app_log_i1(app, DK3_LL_ERROR, 120);
+ }
+ dk3sf_report_errno(app, errno, dk3sf_function_names[24]);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void
+dk3sf_initialize_stdout(void)
+{
+}
+
+
+
+void
+dk3sf_initialize_stderr(void)
+{
+}
+
+
+
+void
+dk3sf_initialize_file(FILE *fipo)
+{
+}
+
+
+
+/* --- non-Windows, dkChar 8 bit --- */
+#endif
+
+/* --- non-Windows --- */
+#endif
+
+
+
+int
+dk3sf_must_expand(dkChar const *fn)
+{
+ int back = 0;
+
+
+#line 3739 "dk3sf.ctr"
+ if(fn) {
+#if DK3_ON_WINDOWS
+ dkChar const *ptr;
+ ptr = fn;
+ while((*ptr) && (back == 0)) {
+ switch(*ptr) {
+ case dkT('?'):
+ case dkT('*'):
+ {
+ back = 1;
+ }
+ break;
+ }
+ ptr++;
+ }
+#endif
+ }
+
+#line 3756 "dk3sf.ctr"
+ return back;
+}
+
+
+
+int
+dk3sf_c8_fputc(char c, FILE *f)
+{
+ int back = 0;
+ if(f) {
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ if(fputwc((((wchar_t)c) & 0x000000FFUL), f) != WEOF) {
+ back = 1;
+ }
+#else
+ if(fputwc((((wchar_t)c) & 0x00FFU), f) != WEOF) {
+ back = 1;
+ }
+#endif
+#else
+ if(fputc(c, f) != EOF) {
+ back = 1;
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c8_fputs(char const *s, FILE *f)
+{
+ int back = 0;
+ char const *ptr = NULL;
+ if((s) && (f)) {
+ back = 1;
+ ptr = s;
+ while(*ptr) {
+ if(!dk3sf_c8_fputc(*(ptr++), f)) {
+ back = 0;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+size_t
+dk3sf_read_app(int fd, void *buf, size_t s, dk3_app_t *app)
+{
+ size_t back = 0;
+
+
+#line 3811 "dk3sf.ctr"
+ if((buf) && (s)) {
+#if DK3_ON_WINDOWS
+ int rb;
+
+
+#line 3815 "dk3sf.ctr"
+ rb = _read(fd, buf, (unsigned int)s);
+ if(rb >= 0) {
+ back = (size_t)rb;
+ } else {
+ /* ERROR: Read failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 124);
+ }
+
+
+#line 3823 "dk3sf.ctr"
+#else
+
+
+#line 3825 "dk3sf.ctr"
+#if DK3_HAVE_READ
+ ssize_t rb = 0; /* Number of bytes read. */
+
+
+#line 3828 "dk3sf.ctr"
+ rb = read(fd, buf, s);
+ if(rb >= (ssize_t)0) {
+ back = (size_t)rb;
+ } else {
+ if(app) {
+ /* ERROR: Read failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 124);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[14]);
+ }
+ }
+
+#line 3838 "dk3sf.ctr"
+#else
+#if DK3_HAVE__READ
+ ssize_t rb = 0; /* Number of bytes read. */
+
+
+#line 3842 "dk3sf.ctr"
+ rb = _read(fd, buf, s);
+ if(rb >= (ssize_t)0) {
+ back = (size_t)rb;
+ } else {
+ if(app) {
+ /* ERROR: Read failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 124);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[15]);
+ }
+ }
+
+#line 3852 "dk3sf.ctr"
+#else
+#error "No read() function available!"
+#endif
+#endif
+
+
+#line 3857 "dk3sf.ctr"
+#endif
+ }
+
+#line 3859 "dk3sf.ctr"
+ return back;
+}
+
+
+
+int
+dk3sf_write_app(int fd, char const *buf, size_t s, dk3_app_t *app)
+{
+ int back = 0;
+ if((buf) && (s)) {
+#if DK3_ON_WINDOWS
+ int wb;
+ wb = _write(fd, buf, (unsigned int)s);
+ if(wb >= 0) {
+ if((size_t)wb == s) {
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Not all bytes written! */
+ dk3app_log_write_error(app, DK3_LL_ERROR, s, wb);
+ }
+ }
+ } else {
+ if(app) {
+ /* ERROR: Write failed! */
+ dk3app_log_i1( app, DK3_LL_ERROR, 173);
+ }
+ }
+#else
+#if DK3_HAVE_WRITE
+ ssize_t wb;
+ wb = write(fd, buf, s);
+ if(wb >= 0) {
+ if((size_t)wb == s) {
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Not all bytes written! */
+ dk3app_log_write_error(app, DK3_LL_ERROR, s, wb);
+ }
+ }
+ } else {
+ if(app) {
+ /* ERROR: Write failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 173);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[16]);
+ }
+ }
+#else
+#if DK3_HAVE__WRITE
+ ssize_t wb;
+ wb = _write(fd, buf, s);
+ if(wb >= 0) {
+ if((size_t)wb == s) {
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Not all bytes written! */
+ dk3app_log_write_error(app, DK3_LL_ERROR, s, wb);
+ }
+ }
+ } else {
+ if(app) {
+ /* ERROR: Write failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 173);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[17]);
+ }
+ }
+#else
+#error "No write() function available!"
+#endif
+#endif
+#endif
+ }
+ return back;
+}
+
+
+size_t
+dk3sf_fread_app(void *db, size_t sz, size_t ne, FILE *fi, dk3_app_t *app)
+{
+ size_t back = 0;
+ if((db) && (sz) && (ne) && (fi)) {
+#if DK3_ON_WINDOWS
+ back = fread(db, sz, ne, fi);
+ if(back < ne) {
+ if(ferror(fi)) {
+ if(app) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 124);
+ }
+ }
+ clearerr(fi);
+ }
+#else
+#if DK3_HAVE_FREAD
+ back = fread(db, sz, ne, fi);
+ if(back < ne) {
+ if(ferror(fi)) {
+ if(app) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 124);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[18]);
+ }
+ } clearerr(fi);
+ }
+#else
+#if DK3_HAVE__FREAD
+ back = _fread(db, sz, ne, fi);
+ if(back < ne) {
+ if(ferror(fi)) {
+ if(app) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 124);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[19]);
+ }
+ } clearerr(fi);
+ }
+#else
+#error "No fread() function available!"
+#endif
+#endif
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_fwrite_app(void const *sb, size_t sz, size_t ne, FILE *fi, dk3_app_t *app)
+{
+ int back = 0;
+ if((sb) && (sz) && (ne) && (fi)) {
+#if DK3_ON_WINDOWS
+ size_t wb;
+ wb = fwrite(sb, sz, ne, fi);
+ if(wb == ne) {
+ back = 1;
+ } else {
+ if(app) {
+ dk3app_log_fwrite_error(app, DK3_LL_ERROR, ne, wb);
+ }
+ }
+#else
+#if DK3_HAVE_FWRITE
+ size_t wb;
+ wb = fwrite(sb, sz, ne, fi);
+ if(wb == ne) {
+ back = 1;
+ } else {
+ if(app) {
+ dk3app_log_fwrite_error(app, DK3_LL_ERROR, ne, wb);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[20]);
+ }
+ }
+#else
+#if DK3_HAVE__FWRITE
+ size_t wb;
+ wb = _fwrite(sb, sz, ne, fi);
+ if(wb == ne) {
+ back = 1;
+ } else {
+ if(app) {
+ dk3app_log_fwrite_error(app, DK3_LL_ERROR, ne, wb);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[21]);
+ }
+ }
+#else
+#error "No fwrite() function available!"
+#endif
+#endif
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_inspect_bom_skip_app(
+ dkChar const *fn,
+ int dv,
+ size_t *skb,
+ dk3_app_t *app
+)
+{
+ int back = -1;
+ int found = 0; /* Flag: Any form of BOM found .*/
+ FILE *fipo = NULL; /* Input file. */
+ unsigned char bb[4]; /* Buffer for BOM. */
+ size_t rb = 0; /* Number of bytes read. */
+
+
+#line 4049 "dk3sf.ctr"
+ if(skb) { *skb = 0; }
+ back = dv;
+ if(fn) {
+ fipo = dk3sf_fopen_app(fn, dk3app_not_localized(36), app);
+ if(fipo) {
+ rb = dk3sf_fread_app(bb, 1, 4, fipo, app);
+ /* Check UTF-8 */
+ if(rb >= 3) {
+ if((bb[0] == 0xEF) && (bb[1] == 0xBB) && (bb[2] == 0xBF)) {
+ found = 1; back = DK3_FILE_ENCODING_UTF8;
+
+#line 4059 "dk3sf.ctr"
+ if(skb) { *skb = 3; }
+ }
+ }
+ if(!found) {
+ if(rb >= 2) {
+ if((bb[0] == 0xFE) && (bb[1] == 0xFF)) {
+ found = 1; back = DK3_FILE_ENCODING_UTF16_MSB_FIRST;
+
+#line 4066 "dk3sf.ctr"
+ if(skb) { *skb = 2; }
+ } else {
+ if((bb[0] == 0xFF) && (bb[1] == 0xFE)) {
+ found = 1; back = DK3_FILE_ENCODING_UTF16_LSB_FIRST;
+
+#line 4070 "dk3sf.ctr"
+ if(skb) { *skb = 2; }
+ if(rb >= 4) {
+ if((bb[2] == 0x00) && (bb[3] == 0x00)) {
+ back = DK3_FILE_ENCODING_UNICODE_LSB_FIRST;
+
+#line 4074 "dk3sf.ctr"
+ if(skb) { *skb = 4; }
+ }
+ }
+ }
+ }
+ }
+ }
+ if(!found) {
+ if(rb >= 4) {
+ if((bb[0] == 0x00) && (bb[1] == 0x00)
+ && (bb[2] == 0xFE) && (bb[3] == 0xFF)
+ )
+ {
+ found = 1; back = DK3_FILE_ENCODING_UNICODE_MSB_FIRST;
+
+#line 4088 "dk3sf.ctr"
+ if(skb) { *skb = 4; }
+ }
+ }
+ }
+ if(!found) {
+ /* No BOM found */
+ back = dv;
+ }
+ fclose(fipo);
+ }
+ }
+
+#line 4099 "dk3sf.ctr"
+ return back;
+}
+
+
+
+int
+dk3sf_inspect_bom_app(dkChar const *fn, int dv, dk3_app_t *app)
+{
+ int back;
+ back = dk3sf_inspect_bom_skip_app(fn, dv, NULL, app);
+ return back;
+}
+
+
+
+int
+dk3sf_apply_bom_to_file_app(FILE *fipo, int enc, dk3_app_t *app)
+{
+ int back = 0;
+
+
+#line 4119 "dk3sf.ctr"
+#if DK3_ON_WINDOWS
+ if(fipo) {
+ switch(enc) {
+ case DK3_FILE_ENCODING_ASCII: {
+ back = 1;
+
+#line 4124 "dk3sf.ctr"
+ } break;
+ case DK3_FILE_ENCODING_UTF8: {
+ back = 1;
+ _setmode(_fileno(fipo), _O_U8TEXT);
+
+#line 4128 "dk3sf.ctr"
+ } break;
+ case DK3_FILE_ENCODING_UTF16_LSB_FIRST: {
+ _setmode(_fileno(fipo), _O_U16TEXT);
+
+#line 4131 "dk3sf.ctr"
+ } break;
+ default: {
+ /* ERROR: Encoding can not be handled directly by file! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 204);
+ } break;
+ }
+ }
+#else
+ if(fipo) {
+ switch(enc) {
+ case DK3_FILE_ENCODING_ASCII: case DK3_FILE_ENCODING_UTF8: {
+ back = 1;
+
+#line 4143 "dk3sf.ctr"
+ } break;
+ default: {
+ /* ERROR: Encoding can not be handled direcly by file! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 204);
+ } break;
+ }
+ }
+#endif
+
+
+#line 4152 "dk3sf.ctr"
+ return back;
+}
+
+
+
+int
+dk3sf_is_dir_app(dkChar const *n, dk3_app_t *app)
+{
+ int back = 0;
+ dk3_stat_t stb;
+ if(dk3sf_stat_app(&stb, n, app)) {
+ if(((stb.ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_DIRECTORY) {
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: n is not a directory! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 202, 203, n);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_chdir_app(dkChar const *dn, dk3_app_t *app)
+{
+ int back = 0;
+ if(dn) {
+#if DK3_CHAR_SIZE > 1
+#if DK3_ON_WINDOWS
+ if(_wchdir(dn) == 0) {
+ back = 1;
+ } else {
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 242, 243, dn);
+ }
+ }
+#else
+#error "No chdir() function (16-bit) on non-Windows systems!"
+#endif
+#else
+#if DK3_ON_WINDOWS
+ if(chdir(dn) == 0) {
+ back = 1;
+ } else {
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 242, 243, dn);
+ }
+ }
+#else
+#if DK3_HAVE_CHDIR
+ if(chdir(dn) == 0) {
+ back = 1;
+ } else {
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 242, 243, dn);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[22]);
+ }
+ }
+#else
+#error "No chdir() function available!"
+#endif
+#endif
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_must_rebuild(dkChar const *dn, dkChar const *sn)
+{
+ int back = 1;
+ dk3_stat_t stbs;
+ dk3_stat_t stbd;
+ if((dn) && (sn)) {
+ if(dk3sf_stat_app(&stbd, dn, NULL)) {
+ if(dk3sf_stat_app(&stbs, sn, NULL)) {
+ if(stbd.mod > stbs.mod) {
+ back = 0;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_filename_to_c8(
+ char *fnb, size_t szfnb, dkChar const *src, dk3_app_t *app
+)
+{
+ int back = 0;
+ if((fnb) && (szfnb) && (src)) {
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "Only 1- or 2-byte character support available!"
+#else
+#if DK3_ON_WINDOWS
+ back = dk3str_cnv_c16_to_c8p_app(fnb, szfnb, src, app);
+#else
+#error "2-byte character support is available on Windows platforms only!"
+#endif
+#endif
+#else
+ if(dk3str_len(src) < szfnb) {
+ dk3str_cpy_not_overlapped(fnb, src);
+ back = 1;
+ } else {
+ /* ERROR: File name too long! */
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 65, 66, src);
+ }
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_scan_double_app(dkChar const *txt, double *v, dk3_app_t *app)
+{
+ int back = 0;
+
+
+#line 4283 "dk3sf.ctr"
+ if((txt) && (v)) {
+
+#line 4284 "dk3sf.ctr"
+#if DK3_HAVE_SETLOCALE
+ char oldlocale[64];
+ char *lcptr;
+
+ lcptr = setlocale(LC_NUMERIC, NULL);
+
+#line 4289 "dk3sf.ctr"
+ if(lcptr) {
+
+#line 4290 "dk3sf.ctr"
+ if(dk3str_c8_len(lcptr) < sizeof(oldlocale)) {
+
+#line 4291 "dk3sf.ctr"
+ dk3str_c8_cpy_not_overlapped(oldlocale, lcptr);
+ setlocale(LC_NUMERIC, "C");
+#if VERSION_BEFORE_20140716
+ back = dk3sf_sscanf3(txt,dkT("%lf"),v);
+#else
+ back = dk3ma_d_from_string(v, txt, NULL);
+#endif
+ setlocale(LC_NUMERIC, oldlocale);
+ } else {
+
+#line 4300 "dk3sf.ctr"
+#if VERSION_BEFORE_20140716
+ dk3sf_sscanf3(txt,dkT("%lf"),v);
+#else
+ back = dk3ma_d_from_string(v, txt, NULL);
+#endif
+ if(app) {
+ /* ERROR: Failed to save current locale! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 254);
+ }
+ }
+ } else {
+
+#line 4311 "dk3sf.ctr"
+#if VERSION_BEFORE_20140716
+ dk3sf_sscanf3(txt,dkT("%lf"),v);
+#else
+ back = dk3ma_d_from_string(v, txt, NULL);
+#endif
+ if(app) {
+ /* ERROR: Failed to obtain current locale! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 253);
+ }
+ }
+#else
+#if VERSION_BEFORE_20140716
+ back = dk3sf_sscanf3(txt,dkT("%lf"),v);
+
+#line 4324 "dk3sf.ctr"
+#else
+ back = dk3ma_d_from_string(v, txt, NULL);
+#endif
+#endif
+ }
+
+#line 4329 "dk3sf.ctr"
+ return back;
+}
+
+
+
+int
+dk3sf_get_max_files(void)
+{
+ int back = 1024;
+#if DK3_HAVE_SYS_RESOURCE_H
+#if DK3_HAVE_GETRLIMIT
+ struct rlimit rl;
+ if(getrlimit(RLIMIT_NOFILE, &rl) >= 0) {
+ if(rl.rlim_max != RLIM_INFINITY) {
+ back = rl.rlim_max;
+ }
+ }
+#endif
+#endif
+ return back;
+}
+
+
+
+
+int
+dk3sf_fclose_fn_app(FILE *fipo, dkChar const *fn, dk3_app_t *app)
+{
+ int back = 0;
+ int res;
+ if(fipo) {
+ res = fclose(fipo);
+ if(0 == res) {
+ back = 1;
+ } else {
+ if(fn) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 341, 342, fn);
+ } else {
+ dk3app_log_i1(app, DK3_LL_ERROR, 340);
+ }
+ dk3sf_report_errno(app, errno, dk3sf_function_names[1]);
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_fclose_app(FILE *fipo, dk3_app_t *app)
+{
+ int back = 0;
+ back = dk3sf_fclose_fn_app(fipo, NULL, app);
+ return back;
+}
+
+
+
+int
+dk3sf_fgets(dkChar *db, size_t sz, FILE *fi)
+{
+ int back;
+ back = dk3sf_fgets_fn_app(db, sz, fi, NULL, NULL);
+ return back;
+}
+
+
+
+int
+dk3sf_fputs(dkChar const *st, FILE *fi)
+{
+ int back;
+ back = dk3sf_fputs_fn_app(st, fi, NULL, NULL);
+ return back;
+}
+
+
+
+int
+dk3sf_fputt(dkChar const * const *txt, FILE *fi)
+{
+ dkChar const * const *ptr;
+ int back = 0;
+ if((txt) && (fi)) {
+ back = 1;
+ ptr = txt;
+ while(*ptr) {
+ if(!(dk3sf_fputs(*(ptr++), fi))) {
+ back = 0;
+ }
+ dk3sf_fputc(dkT('\n'), fi);
+ }
+ }
+ return back;
+}
+
+
+int
+dk3sf_fputc(dkChar c, FILE *fi)
+{
+ int back;
+ back = dk3sf_fputc_fn_app(c, fi, NULL, NULL);
+ return back;
+}
+
+
+
+int
+dk3sf_stat_app(dk3_stat_t *st, dkChar const *fn, dk3_app_t *app)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "System function for b-byte character strings not available!"
+#else
+#if DK3_ON_WINDOWS
+ return(dk3sf_c16_stat_app(st, fn, app));
+#else
+#error "Wide character functions not defined on non-Windows systems!"
+#endif
+#endif
+#else
+ return(dk3sf_c8_stat_app(st, fn, app));
+#endif
+}
+
+
+
+FILE *
+dk3sf_fopen_app(dkChar const *fn, dkChar const *mo, dk3_app_t *app)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "System function for b-byte character strings not available!"
+#else
+#if DK3_ON_WINDOWS
+ return(dk3sf_c16_fopen_app(fn, mo, app));
+#else
+#error "Wide character functions not defined on non-Windows systems!"
+#endif
+#endif
+#else
+ return(dk3sf_c8_fopen_app(fn, mo, app));
+#endif
+}
+
+
+
+int
+dk3sf_time_convert_app(
+ dkChar *dest,
+ size_t sz,
+ dk3_time_t const *timer,
+ dk3_app_t *app
+)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "System function for b-byte character strings not available!"
+#else
+#if DK3_ON_WINDOWS
+ return(dk3sf_c16_time_convert_app(dest, sz, timer, app));
+#else
+#error "Wide character functions not defined on non-Windows systems!"
+#endif
+#endif
+#else
+ return(dk3sf_c8_time_convert_app(dest, sz, timer, app));
+#endif
+}
+
+
+
+int
+dk3sf_getcwd_app(dkChar *dest, size_t sz, dk3_app_t *app)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "System function for b-byte character strings not available!"
+#else
+#if DK3_ON_WINDOWS
+ return(dk3sf_c16_getcwd_app(dest, sz, app));
+#else
+#error "Wide character functions not defined on non-Windows systems!"
+#endif
+#endif
+#else
+ return(dk3sf_c8_getcwd_app(dest, sz, app));
+#endif
+}
+
+
+
+int
+dk3sf_find_exec_app(
+ dkChar *d,
+ size_t s,
+ dkChar const *w,
+ dkChar const *c,
+ dk3_app_t *app
+)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "System function for b-byte character strings not available!"
+#else
+#if DK3_ON_WINDOWS
+ return(dk3sf_c16_find_exec_app(d, s, w, c, app));
+#else
+#error "Wide character functions not defined on non-Windows systems!"
+#endif
+#endif
+#else
+ return(dk3sf_c8_find_exec_app(d, s, w, c, app));
+#endif
+}
+
+
+
+int
+dk3sf_get_logname_app(dkChar *d, size_t s, dk3_app_t *app)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "System function for b-byte character strings not available!"
+#else
+#if DK3_ON_WINDOWS
+ return(dk3sf_c16_get_logname_app(d, s, app));
+#else
+#error "Wide character functions not defined on non-Windows systems!"
+#endif
+#endif
+#else
+ return(dk3sf_c8_get_logname_app(d, s, app));
+#endif
+}
+
+
+
+int
+dk3sf_get_home_app(dkChar *d, size_t s, dk3_app_t *app)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "System function for b-byte character strings not available!"
+#else
+#if DK3_ON_WINDOWS
+ return(dk3sf_c16_get_home_app(d, s, app));
+#else
+#error "Wide character functions not defined on non-Windows systems!"
+#endif
+#endif
+#else
+ return(dk3sf_c8_get_home_app(d, s, app));
+#endif
+}
+
+
+
+int
+dk3sf_mkdir_app(dkChar const *p, int mo, dk3_app_t *app)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "System function for b-byte character strings not available!"
+#else
+#if DK3_ON_WINDOWS
+ return(dk3sf_c16_mkdir_app(p, mo, app));
+#else
+#error "Wide character functions not defined on non-Windows systems!"
+#endif
+#endif
+#else
+ return(dk3sf_c8_mkdir_app(p, mo, app));
+#endif
+}
+
+
+
+int
+dk3sf_remove_file_app(dkChar const *n, dk3_app_t *app)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "System function for b-byte character strings not available!"
+#else
+#if DK3_ON_WINDOWS
+ return(dk3sf_c16_remove_file_app(n, app));
+#else
+#error "Wide character functions not defined on non-Windows systems!"
+#endif
+#endif
+#else
+ return(dk3sf_c8_remove_file_app(n, app));
+#endif
+}
+
+
+
+int
+dk3sf_remove_dir_app(dkChar const *n, dk3_app_t *app)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "System function for b-byte character strings not available!"
+#else
+#if DK3_ON_WINDOWS
+ return(dk3sf_c16_remove_dir_app(n, app));
+#else
+#error "Wide character functions not defined on non-Windows systems!"
+#endif
+#endif
+#else
+ return(dk3sf_c8_remove_dir_app(n, app));
+#endif
+}
+
+
+
+int
+dk3sf_get_hostname_app(dkChar *db, size_t sz, dk3_app_t *app)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "System function for b-byte character strings not available!"
+#else
+#if DK3_ON_WINDOWS
+ return(dk3sf_c16_get_hostname_app(db, sz, app));
+#else
+#error "Wide character functions not defined on non-Windows systems!"
+#endif
+#endif
+#else
+ return(dk3sf_c8_get_hostname_app(db, sz, app));
+#endif
+}
+
+
+
+dkChar *
+dk3sf_getenv(dkChar const *name)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "System function for b-byte character strings not available!"
+#else
+#if DK3_ON_WINDOWS
+ return(dk3sf_c16_getenv(name));
+#else
+#error "Wide character functions not defined on non-Windows systems!"
+#endif
+#endif
+#else
+ return(dk3sf_c8_getenv(name));
+#endif
+}
+
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dk3sf.ctr b/support/dktools/dk3sf.ctr
new file mode 100644
index 0000000000..b12b4621cd
--- /dev/null
+++ b/support/dktools/dk3sf.ctr
@@ -0,0 +1,4689 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% header
+
+#include "dk3conf.h"
+#include "dk3types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if DK3_ON_WINDOWS
+
+/** Retrieve information about a file.
+ @param st File information buffer.
+ @param fn File name.
+ @param app Application structure, used for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c16_stat_app(dk3_stat_t *st, dk3_c16_t const *fn, dk3_app_t *app);
+
+/** Open a file.
+ @param fn File name.
+ @param mo Mode.
+ @param app Application structure, used for diagnostics.
+ @return FILE pointer on success, NULL on error.
+*/
+FILE *
+dk3sf_c16_fopen_app(dk3_c16_t const *fn, dk3_c16_t const *mo, dk3_app_t *app);
+
+/** Convert timestamp to text.
+ @param dest Destination buffer.
+ @param sz Size of \a dest (number of characters).
+ @param timer Timestamp to convert.
+ @param app Application structure, used for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c16_time_convert_app(
+ dk3_c16_t *dest, size_t sz, dk3_time_t const *timer, dk3_app_t *app
+);
+
+/** Get current working directory.
+ @param dest Destination buffer.
+ @param sz Size of \a dest.
+ The size must not exceed INT_MAX/2.
+ Practically this is not a limitation
+ as the useful buffer size is DK3_MAX_PATH elements.
+ @param app Application structure, used for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c16_getcwd_app(dk3_c16_t *dest, size_t sz, dk3_app_t *app);
+
+/** Find executable file.
+ @param d Destination buffer.
+ @param s Size of \a d (number of characters).
+ The size must not exceed 2^31-1. Practically this is not a
+ limitation as the useful buffer size is DK3_MAX_PATH elements.
+ @param w Current working directory.
+ @param c Command as typed in the command line.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c16_find_exec_app(
+ dk3_c16_t *d, size_t s, dk3_c16_t const *w, dk3_c16_t const *c, dk3_app_t *app
+);
+
+/** Find users home directory.
+ @param d Destination buffer.
+ @param s Size of \a d (number of characters).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c16_get_home_app(dk3_c16_t *d, size_t s, dk3_app_t *app);
+
+
+/** Remove (unlink) path.
+ @param n Path name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c16_remove_file_app(dk3_c16_t const *n, dk3_app_t *app);
+
+
+/** Remove directory.
+ @param n Directory name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c16_remove_dir_app(dk3_c16_t const *n, dk3_app_t *app);
+
+/** Retrieve host name (short name, without DNS domain).
+ @param db Destination buffer.
+ @param sz Size of \a db (number of characters).
+ The size must not exceed INT_MAX. Practically this is not a
+ limitation as I have never seen host names longer than 80 characters.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c16_get_hostname_app(dk3_c16_t *db, size_t sz, dk3_app_t *app);
+
+/** Get login name.
+ @param d Destination buffer.
+ @param s Size of \a d (number of characters).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c16_get_logname_app(dk3_c16_t *d, size_t s, dk3_app_t *app);
+
+
+/** Create directory if it does not yet exist.
+ @param p Path name.
+ @param mo Creation mode.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c16_mkdir_app(dk3_c16_t const *p, int mo, dk3_app_t *app);;
+
+/** Get environment variable.
+ @param name Environment variable name.
+ @return Value on success, NULL on error.
+*/
+dk3_c16_t *
+dk3sf_c16_getenv(dk3_c16_t const *name);
+
+#else
+
+
+#endif
+
+/** Retrieve information about a file.
+ @param st File information buffer.
+ @param fn File name.
+ @param app Application structure, used for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c8_stat_app(dk3_stat_t *st, char const *fn, dk3_app_t *app);
+
+/** Open a file.
+ @param fn File name.
+ @param mo Mode.
+ @param app Application structure, used for diagnostics.
+ @return FILE pointer on success, NULL on error.
+*/
+FILE *
+dk3sf_c8_fopen_app(char const *fn, char const *mo, dk3_app_t *app);
+
+/** Convert timestamp to text.
+ @param dest Destination buffer.
+ @param sz Size of \a dest (number of characters).
+ @param timer Timestamp to convert.
+ @param app Application structure, used for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c8_time_convert_app(
+ char *dest, size_t sz, dk3_time_t const *timer, dk3_app_t *app
+);
+
+/** Get current working directory.
+ @param dest Destination buffer.
+ @param sz Size of \a dest.
+ On some platforms the size is converted to int, so it
+ should not exceed 32767. Practically this is not a limitation
+ as the userful buffer size is DK3_MAX_PATH.
+ @param app Application structure, used for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c8_getcwd_app(char *dest, size_t sz, dk3_app_t *app);
+
+/** Read input line.
+ @param db Destination buffer.
+ @param sz Size of \a db (number of characters).
+ @param fi Input file.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_fgets(dkChar *db, size_t sz, FILE *fi);
+
+/** Read input line.
+ @param db Destination buffer.
+ @param sz Size of \a db (number of characters).
+ The size must not exceed 32767 as it is converted to int on some
+ systems.
+ @param fi Input file.
+ @param fn Input file name, may be NULL.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_fgets_fn_app(
+ dkChar *db, size_t sz, FILE *fi, dkChar const *fn, dk3_app_t *app
+);
+
+/** Write string to file.
+ @param st String to write.
+ @param fi File to write to.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_fputs(dkChar const *st, FILE *fi);
+
+/** Write string to file, report errors if any.
+ @param st String to write.
+ @param fi Output file to write to.
+ @param fn File name for error messages, may be NULL.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_fputs_fn_app(dkChar const *st,FILE *fi,dkChar const *fn,dk3_app_t *app);
+
+/** Write array of line strings to file.
+ @param txt Pointer to array of lines.
+ @param fi Output file to write to.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_fputt(dkChar const * const *txt, FILE *fi);
+
+/** Write one character to file.
+ @param ch Character to write.
+ @param fi File to write to.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_fputc(dkChar ch, FILE *fi);
+
+/** Write one character to file.
+ @param ch Character to write.
+ @param fi File to write to.
+ @param fn File name of output file.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_fputc_fn_app(dkChar ch, FILE *fi, dkChar const *fn, dk3_app_t *app);
+
+/** Write byte order marker 0xFEFF to standard output.
+*/
+void
+dk3sf_initialize_stdout(void);
+
+/** Only set stdout mode, do not write byte order marker
+ 0xFEFF to standard output.
+*/
+void
+dk3sf_initialize_stdout_no_bom(void);
+
+/** Write byte order marker 0xFEFF to standard error output.
+*/
+void
+dk3sf_initialize_stderr(void);
+
+/** Write byte order marker 0xFEFF to file.
+ @param fipo File to set up.
+*/
+void
+dk3sf_initialize_file(FILE *fipo);
+
+/** Prepare standard output and standard error output for multibyte
+ characters (write byte order marker 0xFEFF).
+*/
+void
+dk3sf_initialize_output(void);
+
+/** Get current timestamp.
+ @param timer Pointer to result variable.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_time(dk3_time_t *timer);
+
+/** Find executable file.
+ @param d Destination buffer.
+ @param s Size of \a d (number of characters).
+ The size should not exceed 2^32-1 as it is converted to
+ a DWORD. Practically this is not a restriction as DK3_MAX_PATH
+ is the useful buffer size.
+ @param w Current working directory.
+ @param c Command as typed in the command line.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c8_find_exec_app(
+ char *d, size_t s, char const *w, char const *c, dk3_app_t *app
+);
+
+/** Find users home directory.
+ @param d Destination buffer.
+ @param s Size of \a d (number of characters).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c8_get_home_app(char *d, size_t s, dk3_app_t *app);
+
+/** Get current users login name.
+ @param d Destination buffer.
+ @param s Size of \a d (number of characters).
+ @param app Application structure for diagnostics, may be NULL.
+*/
+int
+dk3sf_c8_get_logname_app(char *d, size_t s, dk3_app_t *app);
+
+/** Create directory if it does not yet exist.
+ @param p Path name.
+ @param mo Creation mode.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c8_mkdir_app(char const *p, int mo, dk3_app_t *app);
+
+/** Remove (unlink) path.
+ @param n Path name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c8_remove_file_app(char const *n, dk3_app_t *app);
+
+/** Remove directory.
+ @param n Directory name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c8_remove_dir_app(char const *n, dk3_app_t *app);
+
+/** Get current process ID.
+ @return Process ID.
+*/
+dk3_um_t
+dk3sf_getpid(void);
+
+/** Check whether we must expand a file name.
+ @param fn File name to check.
+ @return 1 for "must expand", 0 for "no need to expand".
+*/
+int
+dk3sf_must_expand(dkChar const *fn);
+
+/** Retrieve host name (short name).
+ @param db Destination buffer.
+ @param sz Size of \a db (number of characters).
+ The size must not exceed 2^32-1. Practically this is not a
+ limitation as the useful buffer size for host name is below 256.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c8_get_hostname_app(char *db, size_t sz, dk3_app_t *app);
+
+/** Print 8-bit character to file, convert to 16 bit if necessary.
+ @param c Character to print.
+ @param f File to write to.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c8_fputc(char c, FILE *f);
+
+/** Print 8-bit character string to file, convert to 16 bit if necessary.
+ @param s String to print.
+ @param f File to write to.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c8_fputs(char const *s, FILE *f);
+
+/** Read bytes from file descriptor into buffer.
+ @param fd File descriptor.
+ @param buf Buffer.
+ @param s Size of \a buf.
+ The size must not exceed 65535 as it is converted to unsigned int
+ on some systems.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Number of bytes read.
+*/
+size_t
+dk3sf_read_app(int fd, void *buf, size_t s, dk3_app_t *app);
+
+/** Write bytes to file descriptor.
+ @param fd File descriptor.
+ @param buf Buffer to write.
+ @param s Size of \a buf in bytes.
+ The size must not exceed 65535 as it is converted to unsigned int
+ on some systems.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 for success (all bytes written), 0 on error.
+*/
+int
+dk3sf_write_app(int fd, char const *buf, size_t s, dk3_app_t *app);
+
+/** Read from file.
+ @param db Destination buffer.
+ @param sz Size of one element.
+ @param ne Number of elements.
+ @param fi File to read from.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Number of elements read.
+*/
+size_t
+dk3sf_fread_app(void *db, size_t sz, size_t ne, FILE *fi, dk3_app_t *app);
+
+/** Write to file.
+ @param sb Source buffer.
+ @param sz Size of one element.
+ @param ne Number of elements.
+ @param fi File to write to.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success (all elements written), 0 on error.
+*/
+int
+dk3sf_fwrite_app(void const *sb,size_t sz,size_t ne,FILE *fi,dk3_app_t *app);
+
+/** Inspect file, search for byte order marker.
+ The function inspects the first 4 bytes from file and attempts
+ to find the file encoding (DK3_FILE_ENCODING_xxx).
+ If there is no BOM at the beginning of the file the default
+ value \a dv is returned. A value for \a dv can be obtained
+ from dk3app_get_output_encoding() or by inspecting the DK3_CHAR_SIZE
+ value and the language setting (ending on "UTF-8" or "utf8"?).
+ @param fn File name.
+ @param dv Default value for file encoding.
+ @param app Application structure for diagnostics, may be NULL.
+ @return File encoding if BOM found, default value \a dv otherwise.
+*/
+int
+dk3sf_inspect_bom_app(dkChar const *fn, int dv, dk3_app_t *app);
+
+/** Inspect file, search for byte order marker. If byte order marker
+ is found save number of bytes to skip at beginning of file
+ to variable.
+ The function inspects the first 4 bytes from file and attempts
+ to find the file encoding (DK3_FILE_ENCODING_xxx).
+ If there is no BOM at the beginning of the file the default
+ value \a dv is returned. A value for \a dv can be obtained
+ from dk3app_get_output_encoding() or by inspecting the DK3_CHAR_SIZE
+ value and the language setting (ending on "UTF-8" or "utf8"?).
+ @param fn File name.
+ @param dv Default value for file encoding.
+ @param skb Pointer to size_t variable for number of bytes
+ to skip at the beginning of the file.
+ @param app Application structure for diagnostics, may be NULL.
+ @return File encoding if BOM found, default value \a dv otherwise.
+*/
+int
+dk3sf_inspect_bom_skip_app(
+ dkChar const *fn,
+ int dv,
+ size_t *skb,
+ dk3_app_t *app
+);
+
+/** Attempt to apply an encoding found from BOM to an input FILE.
+ This function has an effect on Windows systems only.
+ For \a enc we can handle DK3_FILE_ENCODING_ASCII (mapped to
+ _O_TEXT), DK3_FILE_ENCODING_UTF8 (mapped to _O_U8TEXT) and
+ DK3_FILE_ENCODING_UTF16_LSB (mapped to _O_U16TEXT).
+ @param fipo File pointer.
+ @param enc Encoding found from dk3sf_inspect_bom_app().
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_apply_bom_to_file_app(FILE *fipo, int enc, dk3_app_t *app);
+
+/** Get environment variable.
+ @param name Environment variable name.
+ @return Value on success, NULL on error.
+*/
+char *
+dk3sf_c8_getenv(char const *name);
+
+/** Check whether or not the given file name is a directory.
+ @param n File name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success (is directory), 0 on error.
+*/
+int
+dk3sf_is_dir_app(dkChar const *n, dk3_app_t *app);
+
+/** Change into directory.
+ * @param dn Directory name.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3sf_chdir_app(dkChar const *dn, dk3_app_t *app);
+
+/** Check whether we need to re-build a destination file from a source.
+ * @param dn Destination file name.
+ * @param sn Source file name.
+ * @return 1 for rebuild necessary, 0 for not necessary.
+ */
+int
+dk3sf_must_rebuild(dkChar const *dn, dkChar const *sn);
+
+/** Create 8-bit file name from dkChar file name.
+ @param fnb File name buffer for result.
+ @param szfnb Size of @a fnb (number of bytes).
+ @param src Source file name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_filename_to_c8(
+ char *fnb, size_t szfnb, dkChar const *src, dk3_app_t *app
+);
+
+/** Retrieve a double value in POSIX notation from a string.
+ The sscanf() function depends on the current locale setting.
+ This function retrieves and saves the current locale setting,
+ establishes C locale temporarily for the the sscanf() call and
+ restores the original setting before exiting.
+ @param txt Text to inspect.
+ @param v Pointer to result variable.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_scan_double_app(dkChar const *txt, double *v, dk3_app_t *app);
+
+/** Convert timestamp to human readable date and time.
+ @param dest Destination structure.
+ @param timer Source timestamp.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_localtime_app(dk3_tm_t *dest, dk3_time_t *timer, dk3_app_t *app);
+
+/** Retrieve maximum number of open files.
+ @return Maximum number of open files.
+*/
+int
+dk3sf_get_max_files(void);
+
+/** Report error detailes.
+ @param app Application structure for diagnostics.
+ @param err Error code from errno.
+ @param fctn Function name.
+*/
+void
+dk3sf_report_errno(dk3_app_t *app, int err, dkChar const *fctn);
+
+/** Close a file.
+ @param fipo FILE to close.
+ @param fn File name, may be NULL.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_fclose_fn_app(FILE *fipo, dkChar const *fn, dk3_app_t *app);
+
+/** Close a file.
+ @param fipo FILE to close.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_fclose_app(FILE *fipo, dk3_app_t *app);
+
+/** Retrieve information about a file.
+ @param st File information buffer.
+ @param fn File name.
+ @param app Application structure, used for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_stat_app(dk3_stat_t *st, dkChar const *fn, dk3_app_t *app);
+
+/** Open a file.
+ @param fn File name.
+ @param mo Mode.
+ @param app Application structure, used for diagnostics.
+ @return FILE pointer on success, NULL on error.
+*/
+FILE *
+dk3sf_fopen_app(dkChar const *fn, dkChar const *mo, dk3_app_t *app);
+
+/** Convert timestamp to text.
+ @param dest Destination buffer.
+ @param sz Size of \a dest (number of dkChar).
+ @param timer Timestamp to convert.
+ @param app Application structure, used for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_time_convert_app(
+ dkChar *dest,
+ size_t sz,
+ dk3_time_t const *timer,
+ dk3_app_t *app
+);
+
+/** Get current working directory.
+ @param dest Destination buffer.
+ @param sz Size of \a dest (number of dkChar).
+ The size must not exceed INT_MAX/2. Practically this is not a
+ limitation as the useful buffer size is DK3_MAX_PATH elements.
+ @param app Application structure, used for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_getcwd_app(dkChar *dest, size_t sz, dk3_app_t *app);
+
+/** Find executable file.
+ @param d Destination buffer.
+ @param s Size of \a d (number of dkChar).
+ The size must not exceed 2^31-1. Practically this is not a
+ limitation as the useful buffer size is DK3_MAX_PATH elements.
+ @param w Current working directory.
+ @param c Command as typed in the command line.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_find_exec_app(
+ dkChar *d,
+ size_t s,
+ dkChar const *w,
+ dkChar const *c,
+ dk3_app_t *app
+);
+
+/** Get login name.
+ @param d Destination buffer.
+ @param s Size of \a d (number of dkChar).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_get_logname_app(dkChar *d, size_t s, dk3_app_t *app);
+
+/** Find users home directory.
+ @param d Destination buffer.
+ @param s Size of \a d (number of dkChar).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_get_home_app(dkChar *d, size_t s, dk3_app_t *app);
+
+/** Create directory if it does not yet exist.
+ @param p Path name.
+ @param mo Creation mode.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_mkdir_app(dkChar const *p, int mo, dk3_app_t *app);
+
+/** Remove (unlink) path.
+ @param n Path name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_remove_file_app(dkChar const *n, dk3_app_t *app);
+
+/** Remove directory.
+ @param n Directory name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_remove_dir_app(dkChar const *n, dk3_app_t *app);
+
+/** Retrieve host name (short name, without DNS domain).
+ @param db Destination buffer.
+ @param sz Size of \a db (number of dkChar).
+ The size must not exceed 2^31-1. Practically this is not a
+ limitation as I have never seen host names longer than 80 characters.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_get_hostname_app(dkChar *db, size_t sz, dk3_app_t *app);
+
+/** Get environment variable.
+ @param name Environment variable name.
+ @return Value on success, NULL on error.
+*/
+dkChar *
+dk3sf_getenv(dkChar const *name);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "No functions to support large characters!"
+#else
+#if DK3_ON_WINDOWS
+
+/** Macro to choose correct character size for sscanf()/swscanf().
+*/
+#define dk3sf_sscanf3(s,f,d) swscanf(s,f,d)
+
+/** Macro to choose correct character size for sprintf()/swprintf().
+ NOTE: The first argument must be a *buffer*, *not* a pointer.
+*/
+#define dk3sf_sprintf3(s,f,d) swprintf(s,(sizeof(s)/sizeof(wchar_t)),f,d)
+#else
+#error "16 bit characters are supported on Windows platforms only!"
+#endif
+#endif
+#else
+
+
+/** Macro to choose correct character size for sscanf().
+*/
+#define dk3sf_sscanf3(s,f,d) sscanf(s,f,d)
+
+/** Macro to choose correct character size for sprintf().
+ NOTE: The first argument *must* be a buffer, *not* a pointer.
+*/
+#define dk3sf_sprintf3(s,f,d) sprintf(s,f,d)
+
+#endif
+
+
+
+%% module
+
+#include "dk3all.h"
+
+
+
+$(trace-include)
+
+
+
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+
+/** File path component separator.
+*/
+#define DK3_C8_SEP '\\'
+
+/** Not a file path component separator.
+*/
+#define DK3_C8_NOSEP '/'
+
+#else
+
+/** File path component separator.
+*/
+#define DK3_C8_SEP '/'
+
+/** Not a file path component separator.
+*/
+#define DK3_C8_NOSEP '\\'
+
+#endif
+
+
+
+/** Add bit to set after testing another bit.
+*/
+#define DK3SF_ADDIF(a,b) if(m & a) { back |= b; }
+
+
+
+/** Function names used in error messages.
+*/
+dkChar const * const dk3sf_function_names[] = {
+$!string-table macro=dkT
+#
+# 0
+#
+
+#
+# 1
+#
+fclose:
+#
+# 2
+#
+rmdir:
+#
+# 3
+#
+unlink:
+#
+# 4
+#
+getpwuid:
+#
+# 5
+#
+lstat64:
+#
+# 6
+#
+stat64:
+#
+# 7
+#
+stat:
+#
+# 8
+#
+lstat:
+#
+# 9
+#
+fopen:
+#
+# 10
+#
+localtime_r:
+#
+# 11
+#
+getcwd:
+#
+# 12
+#
+mkdir:
+#
+# 13
+#
+gethostname:
+#
+# 14
+#
+read:
+#
+# 15
+#
+_read:
+#
+# 16
+#
+write:
+#
+# 17
+#
+_write:
+#
+# 18
+#
+fread:
+#
+# 19
+#
+_fread:
+#
+# 20
+#
+fwrite:
+#
+# 21
+#
+_fwrite:
+#
+# 22
+#
+chdir:
+#
+# 23
+#
+fputs:
+#
+# 24
+#
+fputc:
+#
+# 25
+#
+fgets:
+$!end
+};
+
+
+
+void
+dk3sf_report_errno(dk3_app_t *app, int err, dkChar const *fctn)
+{
+#if (DK3_CHAR_SIZE == 1) && DK3_HAVE_STRERROR && (!DK3_ON_WINDOWS)
+ dkChar const *msgarray[2];
+#if DK3_HAVE_GETENV && DK3_HAVE_SETLOCALE
+ char const *oldlocale = NULL;
+ char const *langptr = NULL;
+#endif
+ if((app) && (fctn)) {
+ msgarray[0] = fctn;
+ errno = 0;
+#if DK3_HAVE_GETENV && DK3_HAVE_SETLOCALE
+ langptr = getenv("LANG");
+ if(langptr) {
+ oldlocale = setlocale(LC_MESSAGES, langptr);
+ }
+#endif
+ msgarray[1] = strerror(err);
+ if(0 == errno) {
+ dk3app_log_3(app, DK3_LL_ERROR, msgarray, 0, 1, dk3sf_function_names[0]);
+ }
+#if DK3_HAVE_GETENV && DK3_HAVE_SETLOCALE
+ if(langptr) {
+ if(oldlocale) { setlocale(LC_MESSAGES, oldlocale); }
+ }
+#endif
+ }
+#endif
+}
+
+
+
+
+#if DK3_ON_WINDOWS
+/* +++ Windows +++ */
+
+
+
+/** Unlocalized 8-bit character keywords used by module.
+*/
+static char const * const dk3sf_kw_win_c8[] = {
+/* 0 */ "HOMEDRIVE",
+/* 1 */ "HOMEPATH",
+/* 2 */ "USERPROFILE",
+/* 3 */ "LOCALAPPDATA",
+/* 4 */ "\\AppData\\Local",
+/* 5 */ "APPDATA",
+/* 6 */ "\\AppData\\Roaming",
+/* 7 */ "TEMP",
+/* 8 */ "TMP",
+/* 9 */ "\\AppData\\Local\\Temp",
+NULL
+};
+
+
+
+/** Unlocalized 16-bit character keywords used by module.
+*/
+static wchar_t const * const dk3sf_kw_win_c16[] = {
+/* 0 */ L"HOMEDRIVE",
+/* 1 */ L"HOMEPATH",
+/* 2 */ L"USERPROFILE",
+/* 3 */ L"LOCALAPPDATA",
+/* 4 */ L"\\AppData\\Local",
+/* 5 */ L"APPDATA",
+/* 6 */ L"\\AppData\\Roaming",
+/* 7 */ L"TEMP",
+/* 8 */ L"TMP",
+/* 9 */ L"\\AppData\\Local\\Temp",
+NULL
+};
+
+
+
+dk3_um_t
+dk3sf_getpid(void)
+{
+ dk3_um_t back;
+ back = (dk3_um_t)_getpid();
+ return back;
+}
+
+
+
+dk3_c16_t *
+dk3sf_c16_getenv(dk3_c16_t const *name)
+{
+ dk3_c16_t *back = NULL;
+ if(name) {
+ back = _wgetenv(name);
+ }
+ return back;
+}
+
+
+dk3_c8_t *
+dk3sf_c8_getenv(char const *name)
+{
+ char *back = NULL;
+ if(name) {
+ back = getenv(name);
+ }
+ return back;
+}
+
+
+int
+dk3sf_c16_remove_dir_app(dk3_c16_t const *n, dk3_app_t *app)
+{
+ int back = 0;
+ if(n) {
+ if(_wrmdir(n) == 0) {
+ back = 1;
+ } else {
+ if(app) {
+ /* Failed to remove directory! */
+#if DK3_CHAR_SIZE == 2
+ dk3app_log_i3(app, DK3_LL_ERROR, 69, 70, n);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 68);
+#endif
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c8_remove_dir_app(char const *n, dk3_app_t *app)
+{
+ int back = 0;
+ if(n) {
+ if(_rmdir(n) == 0) {
+ back = 1;
+ } else {
+ if(app) {
+ /* Failed to remove directory! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 69, 70, n);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 68);
+#endif
+ }
+ }
+ }
+ return back;
+}
+
+
+int
+dk3sf_c16_remove_file_app(dk3_c16_t const *n, dk3_app_t *app)
+{
+ int back = 0;
+ if(n) {
+ if(_wunlink(n) == 0) {
+ back = 1;
+ } else {
+ if(app) {
+ /* Failed to remove file! */
+#if DK3_CHAR_SIZE == 2
+ dk3app_log_i3(app, DK3_LL_ERROR, 88, 89, n);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 90);
+#endif
+ }
+ }
+ }
+ return back;
+}
+
+
+int
+dk3sf_c8_remove_file_app(char const *n, dk3_app_t *app)
+{
+ int back = 0;
+ if(n) {
+ if(_unlink(n) == 0) {
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Failed to remove file! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 88, 89, n);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 90);
+#endif
+ }
+ }
+ }
+ return back;
+}
+
+
+/** Attempt to retrieve home directory name.
+ @param d Destination buffer.
+ @param sz Size of \a d (number of characters).
+ @param n1 Name of first environment variable to check.
+ @param n2 Name of second environment variable to check.
+ @param n3 Trailing string to remove if found.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3sf_c8_attempt_home(
+ char *d, size_t sz, char const *n1, char const *n2, char const *n3
+)
+{
+ int back = 0;
+ char *p1 = NULL; /* Value of first environment variable. */
+ char *p2 = NULL; /* Value of second environment variable. */
+ size_t s = 0; /* Buffer size needed. */
+ size_t s2 = 0; /* Size of trailing part to remove. */
+ p2 = NULL;
+ $? "+ dk3sf_c8_attempt_home \"%!8s\" \"%!8s\" \"%!8s\"", TR_8STR(n1), TR_8STR(n2), TR_8STR(n3)
+ p1 = getenv(n1);
+ if(p1) {
+ if(n2) { p2 = getenv(n2); }
+ if((p2) || (!(n2))) {
+ s = dk3str_c8_len(p1);
+ if(p2) { s += dk3str_c8_len(p2); }
+ if(s < sz) {
+ dk3str_c8_cpy_not_overlapped(d, p1);
+ if(p2) { dk3str_c8_cat(d, p2); }
+ if(n3) {
+ s2 = dk3str_c8_len(n3);
+ if(s2 < 2) {
+ if(dk3str_c8_casecmp(&(d[s - s2]), n3) == 0) {
+ d[s - s2] = '\0';
+ back = 1;
+ }
+ }
+ } else {
+ back = 1;
+ }
+ }
+ }
+ $!trace-code if(back) {
+ $? ". home = \"%!8s\"", d
+ $!trace-code }
+ } $? "- dk3sf_c8_attempt_home %d", back
+ return back;
+}
+
+
+int
+dk3sf_c8_get_home_app(char *d, size_t s, dk3_app_t *app)
+{
+ int back = 0;
+ if((d) && (s)) {
+ back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[0], dk3sf_kw_win_c8[1], NULL);
+ if(!back) {
+ back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[2], NULL, NULL);
+ }
+ if(!back) {
+ back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[3], NULL, dk3sf_kw_win_c8[4]);
+ }
+ if(!back) {
+ back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[5], NULL, dk3sf_kw_win_c8[6]);
+ }
+ if(!back) {
+ back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[7], NULL, dk3sf_kw_win_c8[9]);
+ }
+ if(!back) {
+ back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[8], NULL, dk3sf_kw_win_c8[9]);
+ }
+ if(!back) {
+ back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[3], NULL, NULL);
+ }
+ if(!back) {
+ back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[5], NULL, NULL);
+ }
+ if(!back) {
+ back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[7], NULL, NULL);
+ }
+ if(!back) {
+ back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[8], NULL, NULL);
+ }
+ $!trace-code if(back) {
+ $? ". home = \"%!8s\"", d
+ $!trace-code }
+ }
+ return back;
+}
+
+
+
+/** Attempt to retrieve home directory name.
+ @param d Destination buffer.
+ @param sz Size of \a d (number of characters).
+ @param n1 Name of first environment variable to check.
+ @param n2 Name of second environment variable to check.
+ @param n3 Trailing string to remove if found.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3sf_c16_attempt_home(
+ dk3_c16_t *d, size_t sz,
+ dk3_c16_t const *n1, dk3_c16_t const *n2, dk3_c16_t const *n3
+)
+{
+ int back = 0;
+ dk3_c16_t *p1 = NULL; /* Value of first environment variable. */
+ dk3_c16_t *p2 = NULL; /* Value of second environment variable. */
+ size_t s = 0; /* Buffer size needed. */
+ size_t s2 = 0; /* Size of trailing text to remove. */
+ p2 = NULL;
+ $? "+ dk3sf_c8_attempt_home \"%ls\" \"%ls\" \"%ls\"", TR_LSTR(n1), TR_LSTR(n2), TR_LSTR(n3)
+ p1 = _wgetenv(n1);
+ if(p1) {
+ if(n2) { p2 = _wgetenv(n2); }
+ if((p2) || (!(n2))) {
+ s = dk3str_c16_len(p1);
+ if(p2) { s += dk3str_c16_len(p2); }
+ if(s < sz) {
+ dk3str_c16_cpy(d, p1);
+ if(p2) { dk3str_c16_cat(d, p2); }
+ if(n3) {
+ s2 = dk3str_c16_len(n3);
+ if(s2 < 2) {
+ if(dk3str_c16_casecmp(&(d[s - s2]), n3) == 0) {
+ d[s - s2] = 0x0000U;
+ back = 1;
+ }
+ }
+ } else {
+ back = 1;
+ }
+ }
+ }
+ $!trace-code if(back) {
+ $? ". home = \"%ls\"", d
+ $!trace-code }
+ } $? "- dk3sf_c8_attempt_home %d", back
+ return back;
+}
+
+
+
+int
+dk3sf_c16_get_home_app(dk3_c16_t *d, size_t s, dk3_app_t *app)
+{
+ int back = 0;
+ if((d) && (s)) {
+ back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[0], dk3sf_kw_win_c16[1], NULL);
+ if(!back) {
+ back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[2], NULL, NULL);
+ }
+ if(!back) {
+ back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[3], NULL, dk3sf_kw_win_c16[4]);
+ }
+ if(!back) {
+ back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[5], NULL, dk3sf_kw_win_c16[6]);
+ }
+ if(!back) {
+ back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[7], NULL, dk3sf_kw_win_c16[9]);
+ }
+ if(!back) {
+ back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[8], NULL, dk3sf_kw_win_c16[9]);
+ }
+ if(!back) {
+ back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[3], NULL, NULL);
+ }
+ if(!back) {
+ back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[5], NULL, NULL);
+ }
+ if(!back) {
+ back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[7], NULL, NULL);
+ }
+ if(!back) {
+ back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[8], NULL, NULL);
+ }
+ $!trace-code if(back) {
+ $? ". home = \"%ls\"", d
+ $!trace-code }
+ }
+ return back;
+}
+
+
+int
+dk3sf_c8_get_logname_app(char *d, size_t s, dk3_app_t *app)
+{
+ int back = 0;
+ DWORD sz = 0; /* Buffer size / Result length. */
+ sz = (DWORD)s;
+ if((d) && (s)) {
+ if(GetUserNameA(d, &sz)) {
+ if(sz) {
+ d[((size_t)sz < s) ? ((size_t)sz) : (s - 1)] = '\0';
+ back = 1;
+ }
+ } else {
+ if(app) {
+ /* Failed to find current user name */
+ dk3app_log_i1(app, DK3_LL_ERROR, 43);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c16_get_logname_app(dk3_c16_t *d, size_t s, dk3_app_t *app)
+{
+ int back = 0;
+ DWORD sz = 0; /* Buffer size / result length. */
+ if((d) && (s)) {
+ sz = (DWORD)s;
+ if(GetUserNameW(d, &sz)) {
+ if(sz) {
+ d[((size_t)sz < s) ? ((size_t)sz) : (s - 1)] = 0U;
+ back = 1;
+ }
+ } else {
+ if(app) {
+ /* Failed to find current user name */
+ dk3app_log_i1(app, DK3_LL_ERROR, 43);
+ }
+ }
+ }
+ return back;
+}
+
+
+int
+dk3sf_time(dk3_time_t *timer)
+{
+ int back = 1;
+ _time64(timer);
+ return back;
+}
+
+
+
+static
+int
+dk3sf_convert_file_type(int m)
+{
+ int back = 0;
+ switch(m & _S_IFMT) {
+#ifdef _S_IFIFO
+ case _S_IFIFO: back = DK3_FT_FIFO; break;
+#endif
+#ifdef _S_IFCHR
+ case _S_IFCHR: back = DK3_FT_SPECIAL_CHAR; break;
+#endif
+#ifdef _S_IFDIR
+ case _S_IFDIR: back = DK3_FT_DIRECTORY; break;
+#endif
+#ifdef _S_IFBLK
+ case _S_IFBLK: back = DK3_FT_SPECIAL_BLOCK; break;
+#endif
+#ifdef _S_IFREG
+ case _S_IFREG: back = DK3_FT_REGULAR; break;
+#endif
+ }
+ return back;
+}
+
+
+
+static
+int
+dk3sf_convert_file_permissions(int m)
+{
+ int back = 0;
+ DK3SF_ADDIF(_S_IREAD,DK3_FPERM_U_READ)
+ DK3SF_ADDIF(_S_IWRITE,DK3_FPERM_U_WRITE)
+ DK3SF_ADDIF(_S_IEXEC,DK3_FPERM_U_EXEC)
+ return back;
+}
+
+
+
+/** Convert file permissions back from dktools to system values.
+ @param m File permissions in dktools notation.
+ @return File permissions in system notation.
+*/
+static
+int
+dk3sf_convert_back_file_permissions(int m)
+{
+ int back = 0;
+ DK3SF_ADDIF(DK3_FPERM_U_READ,S_IREAD)
+ DK3SF_ADDIF(DK3_FPERM_U_WRITE,S_IWRITE)
+ DK3SF_ADDIF(DK3_FPERM_U_EXEC,S_IEXEC)
+ return back;
+}
+
+
+
+static
+void
+dk3sf_convert_filetime(dk3_time_t *pd, FILETIME *ps)
+{
+ __int64 i1;
+ __int64 i2;
+ i1 = (__int64)(ps->dwHighDateTime);
+ i2 = (__int64)(ps->dwLowDateTime);
+ i1 = ((i1 << 32) & 0xFFFFFFFF00000000UL) | (i2 & 0x00000000FFFFFFFFUL);
+ *pd = (dk3_time_t)i1;
+}
+
+
+
+int
+dk3sf_c8_stat_app(dk3_stat_t *st, char const *fn, dk3_app_t *app)
+{
+ WIN32_FIND_DATAA wfd;
+ DWORD dwFileAttributes;
+ HANDLE hFFF;
+ int ec = 0;
+ int back = 0;
+ struct __stat64 stb; /* Internal buffer for _stat64(). */
+ $? "+ dk3sf_c8_stat_app \"%!8s\"", fn
+ if((st) && (fn)) {
+ dk3mem_res((void *)st, sizeof(dk3_stat_t));
+ st->cReparse = 0x00;
+ st->dwReparse = (DWORD)0;
+ if(_stat64(fn, &stb) == 0) {
+ back = 1;
+ st->u = (dk3_um_t)(stb.st_uid);
+ st->g = (dk3_um_t)(stb.st_gid);
+ st->device = (dk3_um_t)(stb.st_dev);
+ st->rdev = (dk3_um_t)(stb.st_rdev);
+ st->inode = (dk3_um_t)(stb.st_ino);
+ st->nlink = (dk3_um_t)(stb.st_nlink);
+ st->cre = (dk3_time_t)(stb.st_ctime);
+ st->mod = (dk3_time_t)(stb.st_mtime);
+ st->acc = (dk3_time_t)(stb.st_atime);
+ st->ft = dk3sf_convert_file_type(stb.st_mode);
+ st->perm = dk3sf_convert_file_permissions(stb.st_mode);
+ st->sz = (dk3_um_t)(stb.st_size);
+ st->lsz = st->sz;
+ st->ai = 0x00;
+ dk3mem_cpy((void *)(&(st->lcre)), (void *)(&(st->cre)), sizeof(dk3_time_t));
+ dk3mem_cpy((void *)(&(st->lmod)), (void *)(&(st->mod)), sizeof(dk3_time_t));
+ dk3mem_cpy((void *)(&(st->lacc)), (void *)(&(st->acc)), sizeof(dk3_time_t));
+ st->lu = st->u;
+ st->lg = st->g;
+ st->ldevice = st->device;
+ st->lrdev = st->rdev;
+ st->linode = st->inode;
+ st->lnlink = st->nlink;
+ st->lft = st->ft;
+ st->lperm = st->perm;
+ st->lsz = st->sz;
+#if VERSION_BEFORE_2012_04_14
+ if(DK3_FT_DIRECTORY == st->ft) {
+ WIN32_FIND_DATAA wfdFileDetails;
+ HANDLE hFileSearch;
+ $? ". check directory"
+ hFileSearch = FindFirstFileA(fn, &wfdFileDetails);
+ if(INVALID_HANDLE_VALUE != hFileSearch) {
+ if(FILE_ATTRIBUTE_REPARSE_POINT & (wfdFileDetails.dwFileAttributes)) {
+ if(IO_REPARSE_TAG_MOUNT_POINT == wfdFileDetails.dwReserved0) {
+ /* ##### st->ft = DK3_FT_WINDOWS_MOUNT_POINT; */
+ } else {
+ if(IO_REPARSE_TAG_SYMLINK == wfdFileDetails.dwReserved0) {
+ /* Symbolic link */
+ st->lsz = dk3ma_um_add_ok(
+ dk3ma_um_mul_ok(
+ (dk3_um_t)(wfdFileDetails.nFileSizeHigh),
+ dk3ma_um_add_ok(
+ (dk3_um_t)(MAXDWORD),
+ DK3_UM_1,
+ &ec
+ ),
+ &ec
+ ),
+ (dk3_um_t)(wfdFileDetails.nFileSizeLow),
+ &ec
+ );
+ dk3sf_convert_filetime(&(st->lcre), &(wfdFileDetails.ftCreationTime));
+ dk3sf_convert_filetime(&(st->lmod), &(wfdFileDetails.ftLastWriteTime));
+ dk3sf_convert_filetime(&(st->lacc), &(wfdFileDetails.ftLastAccessTime));
+ st->ft |= DK3_FT_SYMLINK;
+ } else {
+ }
+ }
+ }
+ FindClose(hFileSearch);
+ }
+ }
+#else
+ dwFileAttributes = GetFileAttributesA(fn);
+ if(INVALID_FILE_ATTRIBUTES != dwFileAttributes) {
+ if(dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
+ st->cReparse = 'r';
+ hFFF = FindFirstFileA(fn, &wfd);
+ if(INVALID_HANDLE_VALUE != hFFF) {
+ if((wfd.dwFileAttributes) & FILE_ATTRIBUTE_REPARSE_POINT) {
+ st->dwReparse = wfd.dwReserved0;
+ switch(wfd.dwReserved0) {
+ case IO_REPARSE_TAG_MOUNT_POINT: {
+ st->cReparse = 'm';
+ } break;
+ case IO_REPARSE_TAG_SYMLINK: {
+ st->cReparse = 'l';
+ } break;
+ }
+ }
+ FindClose(hFFF);
+ }
+ }
+ }
+#endif
+ } else {
+ if(app) {
+ /* stat() failed! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 61, 62, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 73);
+#endif
+ }
+ }
+ } $? "- dk3sf_c8_stat_app %d", back
+ return back;
+}
+
+
+
+/** Check whether opening a file is allowed.
+ @param fn File name.
+ @param want_to_write Flag: Write access is wanted.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 for write allowed, 0 for write denied.
+*/
+static
+int
+dk3sf_c8_check_open_file(char const *fn, int want_to_write, dk3_app_t *app)
+{
+ int back = 1;
+ dk3_stat_t stb; /* Internal buffer for checks. */
+ if(dk3sf_c8_stat_app(&stb, fn, NULL)) {
+ if(((stb.ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_DIRECTORY) {
+ if(app) {
+ back = 0;
+ /* ERROR: Name refers a directory! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 74, 75, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 76);
+#endif
+ }
+ }
+ if(want_to_write) {
+ /* Place for additional checks to write files here. */
+ }
+ }
+ return back;
+}
+
+
+
+FILE *
+dk3sf_c8_fopen_app(char const *fn, char const *mo, dk3_app_t *app)
+{
+ FILE *back = NULL;
+ char const *moptr = NULL; /* Check mode string. */
+ int want_to_write = 0; /* Flag: Write access wanted. */
+ $? "+ dk3sf_c8_fopen_app \"%!8s\"", TR_8STR(fn)
+ if((fn) && (mo)) {
+ moptr = mo;
+ while(*moptr) {
+ switch(*moptr) {
+ case 'w': case 'a': case '+': { want_to_write = 1; } break;
+ }
+ moptr++;
+ }
+ if(dk3sf_c8_check_open_file(fn, want_to_write, app)) {
+ back = fopen(fn, mo);
+ if(!(back)) {
+ if(app) {
+ /* Failed to open file for writing! */
+ if(want_to_write) {
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 77, 78, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 79);
+#endif
+ } else {
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 143, 144, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 145);
+#endif
+ }
+ }
+ }
+ }
+ } $? "- dk3sf_c8_fopen_app %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+
+int
+dk3sf_localtime_app(
+ dk3_tm_t *dest,
+ dk3_time_t *timer,
+ dk3_app_t *app
+)
+{
+ int back = 0;
+ struct tm res;
+ if((dest) && (timer)) {
+ if(0 == _localtime64_s(&res, timer)) {
+ back = 1;
+ dest->Y = 1900 + res.tm_year;
+ dest->M = 1 + res.tm_mon;
+ dest->D = res.tm_mday;
+ dest->h = res.tm_hour;
+ dest->m = res.tm_min;
+ dest->s = res.tm_sec;
+ } else {
+ if(app) {
+ /* ERROR: _localtime64_s failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 268);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c8_time_convert_app(
+ char *dest, size_t sz, dk3_time_t const *timer, dk3_app_t *app
+)
+{
+ int back = 0;
+ char buffer[64]; /* Buffer for sprintf() result. */
+ struct tm res; /* Result from localtime(). */
+ if((dest) && (sz) && (timer)) {
+ if(0 == _localtime64_s(&res, timer)) {
+ sprintf(
+ buffer,
+ "%04d-%02d-%02d %02d:%02d:%02d",
+ (1900 + res.tm_year),
+ (1 + res.tm_mon),
+ res.tm_mday,
+ res.tm_hour,
+ res.tm_min,
+ res.tm_sec
+ );
+ if(sz > dk3str_c8_len(buffer)) {
+ dk3str_c8_cpy_not_overlapped(dest, buffer);
+ back = 1;
+ } else {
+ if(app) {
+ /* Buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ } else {
+ if(app) {
+ /* _localtime64_s failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 80);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c8_getcwd_app(char *dest, size_t sz, dk3_app_t *app)
+{
+ int back = 0;
+ if((dest) && (sz)) {
+ if(_getcwd(dest, (int)sz)) {
+ back = 1;
+ } else {
+ if(app) {
+ switch(errno) {
+ case ERANGE: {
+ /* Buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ } break;
+ default: {
+ dk3app_log_i1(app, DK3_LL_ERROR, 53);
+ } break;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c8_find_exec_app(
+ char *d, size_t s, char const *w, char const *c, dk3_app_t *app
+)
+{
+ int back = 0;
+ if((d) && (s)) {
+ if(GetModuleFileNameA(GetModuleHandle(NULL),d,(DWORD)s)) {
+ back = 1;
+ } else {
+ if(app) {
+ /* Failed to find name of executable! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 40);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+static
+int
+dk3sf_c8_is_drive(char const *p)
+{
+ int back = 0;
+ $? "+ dk3sf_c8_is_drive \"%!8s\"", TR_8STR(p)
+ if(dk3str_c8_len(p) == 2) {
+ if((*p >= 'a') && (*p <= 'z')) {
+ back = 1;
+ }
+ if((*p >= 'A') && (*p <= 'Z')) {
+ back = 1;
+ }
+ if(back) {
+ back = 0;
+ if(p[1] == ':') { back = 1; }
+ }
+ } $? "- dk3sf_c8_is_drive %d", back
+ return back;
+}
+
+
+int
+dk3sf_c8_mkdir_app(char const *p, int mo, dk3_app_t *app)
+{
+ int back = 0;
+ char buffer[DK3_MAX_PATH]; /* Path name for parent directories. */
+ char *ptr = NULL; /* Slash/backslash position. */
+ int cc = 1; /* Flag: Can continue. */
+ int m = 0; /* File permissions. */
+ dk3_stat_t stb;
+ $? "+ dk3sf_c8_mkdir_app \"%!8s\"", TR_8STR(p)
+ if(p) {
+ m = dk3sf_convert_back_file_permissions(mo);
+ if(dk3str_c8_len(p) < sizeof(buffer)) { $? ". length ok"
+ dk3str_c8_cpy_not_overlapped(buffer, p);
+ ptr = buffer; cc = 1;
+ while((cc) && (ptr)) { $? ". loop ptr=\"%!8s\"", TR_8STR(ptr)
+ ptr = dk3str_c8_chr(ptr, '\\');
+ if(ptr) {
+ *ptr = '\0'; $? ". directory=\"%!8s\"", buffer
+ if((dk3str_c8_len(buffer) > 0) && (!dk3sf_c8_is_drive(buffer))) {
+ if(dk3sf_c8_stat_app(&stb, buffer, NULL)) { $? ". path exists"
+ if(((stb.ft) & (~(DK3_FT_SYMLINK))) != DK3_FT_DIRECTORY) {
+ cc = 0; $? ". path \"%!8s\" no directory", buffer
+ if(app) {
+ /* Not a directory! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 81, 82, buffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 83);
+#endif
+ }
+ }
+ } else { $? ". must create directory \"%!8s\"", buffer
+ if(_mkdir(buffer) != 0) { $? "! failed to create \"%!8s\"", buffer
+ cc = 0;
+ if(app) {
+ /* Failed to create directory! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 84, 85, buffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 86);
+#endif
+ }
+ }
+ }
+ }
+ *ptr = '\\';
+ ptr++;
+ }
+ }
+ if(cc) { $? ". all parents ok"
+ if(dk3sf_c8_stat_app(&stb, buffer, NULL)) { $? ". \"%!8s\" exists", buffer
+ if(((stb.ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_DIRECTORY) {
+ back = 1; $? ". is directory"
+ } else { $? ". \"%!8s\" is not a directory", buffer
+ if(app) {
+ /* Not a directory! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 81, 82, buffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 83);
+#endif
+ }
+ }
+ } else { $? ". must create \"%!8s\"", buffer
+ if(_mkdir(buffer) == 0) {
+ back = 1;
+ } else { $? "! failed to create \"%!8s\"", buffer
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 84, 85, buffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 86);
+#endif
+ }
+ }
+ }
+ } else { $? "! directory name too long"
+ if(app) {
+ /* Path too long! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 59, 60, p);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 87);
+#endif
+ }
+ }
+ } $? "- dk3sf_c8_mkdir_app %d", back
+ return back;
+}
+
+
+
+int
+dk3sf_c16_stat_app(dk3_stat_t *st, dk3_c16_t const *fn, dk3_app_t *app)
+{
+ WIN32_FIND_DATAW wfd;
+ DWORD dwFileAttributes;
+ HANDLE hFFF;
+ int ec = 0;
+ int back = 0;
+ struct __stat64 stb; /* Result from _wstat64(). */
+ $? "+ dk3sf_c16_stat_app \"%ls\"", fn
+ if((st) && (fn)) {
+ dk3mem_res((void *)st, sizeof(dk3_stat_t));
+ st->cReparse = 0x00;
+ st->dwReparse = (DWORD)0;
+ if(_wstat64(fn, &stb) == 0) {
+ back = 1;
+ st->u = (dk3_um_t)(stb.st_uid);
+ st->g = (dk3_um_t)(stb.st_gid);
+ st->device = (dk3_um_t)(stb.st_dev);
+ st->rdev = (dk3_um_t)(stb.st_rdev);
+ st->inode = (dk3_um_t)(stb.st_ino);
+ st->nlink = (dk3_um_t)(stb.st_nlink);
+ st->cre = (dk3_time_t)(stb.st_ctime);
+ st->mod = (dk3_time_t)(stb.st_mtime);
+ st->acc = (dk3_time_t)(stb.st_atime);
+ st->ft = dk3sf_convert_file_type(stb.st_mode);
+ st->perm = dk3sf_convert_file_permissions(stb.st_mode);
+ st->sz = (dk3_um_t)(stb.st_size);
+ st->lsz = st->sz;
+ st->ai = 0x00;
+ dk3mem_cpy((void *)(&(st->lcre)), (void *)(&(st->cre)), sizeof(dk3_time_t));
+ dk3mem_cpy((void *)(&(st->lmod)), (void *)(&(st->mod)), sizeof(dk3_time_t));
+ dk3mem_cpy((void *)(&(st->lacc)), (void *)(&(st->acc)), sizeof(dk3_time_t));
+ st->lu = st->u;
+ st->lg = st->g;
+ st->ldevice = st->device;
+ st->lrdev = st->rdev;
+ st->linode = st->inode;
+ st->lnlink = st->nlink;
+ st->lft = st->ft;
+ st->lperm = st->perm;
+ st->lsz = st->sz;
+#if VERSION_BEFORE_2012_04_14
+ if(DK3_FT_DIRECTORY == st->ft) {
+ WIN32_FIND_DATAW wfdFileDetails;
+ HANDLE hFileSearch;
+ $? ". directory special check"
+ hFileSearch = FindFirstFileW(fn, &wfdFileDetails);
+ if(INVALID_HANDLE_VALUE != hFileSearch) { $? ". handle ok"
+ if(FILE_ATTRIBUTE_REPARSE_POINT & (wfdFileDetails.dwFileAttributes)) {
+ $? ". reparse point"
+ if(IO_REPARSE_TAG_MOUNT_POINT == wfdFileDetails.dwReserved0) {
+ $? ". mount point"
+ /* ##### st->ft = DK3_FT_WINDOWS_MOUNT_POINT; */
+ } else {
+ if(IO_REPARSE_TAG_SYMLINK == wfdFileDetails.dwReserved0) {
+ $? ". symbolic link"
+ /* Symbolic link */
+ st->lsz = dk3ma_um_add_ok(
+ dk3ma_um_mul_ok(
+ (dk3_um_t)(wfdFileDetails.nFileSizeHigh),
+ dk3ma_um_add_ok(
+ (dk3_um_t)(MAXDWORD),
+ DK3_UM_1,
+ &ec
+ ),
+ &ec
+ ),
+ (dk3_um_t)(wfdFileDetails.nFileSizeLow),
+ &ec
+ );
+ dk3sf_convert_filetime(&(st->lcre), &(wfdFileDetails.ftCreationTime));
+ dk3sf_convert_filetime(&(st->lmod), &(wfdFileDetails.ftLastWriteTime));
+ dk3sf_convert_filetime(&(st->lacc), &(wfdFileDetails.ftLastAccessTime));
+ st->ft |= DK3_FT_SYMLINK;
+ } else {
+ }
+ }
+ }
+ FindClose(hFileSearch);
+ }
+ }
+#else
+ dwFileAttributes = GetFileAttributesW(fn);
+ if(INVALID_FILE_ATTRIBUTES != dwFileAttributes) {
+ if(dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
+ st->cReparse = 'r';
+ hFFF = FindFirstFileW(fn, &wfd);
+ if(INVALID_HANDLE_VALUE != hFFF) {
+ if((wfd.dwFileAttributes) & FILE_ATTRIBUTE_REPARSE_POINT) {
+ st->dwReparse = wfd.dwReserved0;
+ switch(wfd.dwReserved0) {
+ case IO_REPARSE_TAG_MOUNT_POINT: {
+ st->cReparse = 'm';
+ } break;
+ case IO_REPARSE_TAG_SYMLINK: {
+ st->cReparse = 'l';
+ } break;
+ }
+ }
+ FindClose(hFFF);
+ }
+ }
+ }
+#endif
+ } else {
+ if(app) {
+ /* _wstat64() failed! */
+#if DK3_CHAR_SIZE == 2
+ dk3app_log_i3(app, DK3_LL_ERROR, 61, 163, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 73);
+#endif
+ }
+ }
+ } $? "- dk3sf_c16_stat_app %d", back
+ return back;
+}
+
+
+
+static
+int
+dk3sf_c16_check_open_file(dk3_c16_t const *fn, int want_to_write, dk3_app_t *app)
+{
+ int back = 1;
+ dk3_stat_t stb; /* Check for existing file. */
+ if(dk3sf_c16_stat_app(&stb, fn, NULL)) {
+ if(((stb.ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_DIRECTORY) {
+ if(app) {
+ back = 0;
+ /* Name refers a directory! */
+#if DK3_CHAR_SIZE == 2
+ dk3app_log_i3(app, DK3_LL_ERROR, 74, 75, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 76);
+#endif
+ }
+ }
+ if(want_to_write) {
+ /* Place for additional checks to write files here. */
+ }
+ }
+ return back;
+}
+
+
+
+FILE *
+dk3sf_c16_fopen_app(dk3_c16_t const *fn, dk3_c16_t const *mo, dk3_app_t *app)
+{
+ FILE *back = NULL;
+ dk3_c16_t const *moptr = NULL; /* Traverse mode string. */
+ int want_to_write = 0; /* Flag: Write access wanted. */
+ if((fn) && (mo)) {
+ moptr = mo;
+ while(*moptr) {
+ switch(*moptr) {
+ case L'w': case L'a': case L'+': { want_to_write = 1; } break;
+ }
+ moptr++;
+ }
+ if(dk3sf_c16_check_open_file(fn, want_to_write, app)) {
+ back = _wfopen(fn, mo);
+ if(!(back)) {
+ if(app) {
+ /* Failed to open file for writing! */
+ if(want_to_write) {
+#if DK3_CHAR_SIZE == 2
+ dk3app_log_i3(app, DK3_LL_ERROR, 77, 78, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 79);
+#endif
+ } else {
+#if DK3_CHAR_SIZE == 2
+ dk3app_log_i3(app, DK3_LL_ERROR, 143, 144, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 145);
+#endif
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c16_time_convert_app(
+ dk3_c16_t *dest, size_t sz, dk3_time_t const *timer, dk3_app_t *app
+)
+{
+ int back = 0;
+ char buffer[64];
+ if(dk3sf_c8_time_convert_app(buffer, sizeof(buffer), timer, app)) {
+ back = dk3str_cnv_c8p_to_c16_app(dest, sz, buffer, app);
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c16_getcwd_app(dk3_c16_t *dest, size_t sz, dk3_app_t *app)
+{
+ int back = 0;
+ if((dest) && (sz)) {
+ if(_wgetcwd(dest, (int)sz)) {
+ back = 1;
+ } else {
+ if(app) {
+ switch(errno) {
+#ifdef ERANGE
+ case ERANGE: {
+ /* Buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ } break;
+#endif
+ default: {
+ /* Failed to find current working directory! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 53);
+ } break;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c16_find_exec_app(
+ dk3_c16_t *d, size_t s, dk3_c16_t const *w, dk3_c16_t const *c, dk3_app_t *app
+)
+{
+ int back = 0;
+ if((d) && (s)) {
+ if(GetModuleFileNameW(GetModuleHandle(NULL),d,(DWORD)s)) {
+ back = 1;
+ } else {
+ if(app) {
+ /* Failed to find name of executable! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 40);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+static
+int
+dk3sf_c16_is_drive(dk3_c16_t const *p)
+{
+ int back = 0;
+ if(dk3str_c16_len(p) == 2) {
+ if((*p >= L'A') && (*p <= L'Z')) {
+ back = 1;
+ }
+ if((*p >= L'a') && (*p <= L'z')) {
+ back = 1;
+ }
+ if(back) {
+ back = 0;
+ if(p[1] == L':') { back = 1; }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c16_mkdir_app(dk3_c16_t const *p, int mo, dk3_app_t *app)
+{
+ int back = 0;
+ dk3_c16_t buffer[DK3_MAX_PATH]; /* File names of parent directories. */
+ dk3_c16_t *ptr = NULL; /* Current slash/backslash position. */
+ int cc = 1; /* Flag: Can continue. */
+ int m = 0; /* Permissions. */
+ dk3_stat_t stb; /* Test whether file/dir exists. */
+ if(p) {
+ m = dk3sf_convert_back_file_permissions(mo);
+ if(dk3str_c16_len(p) < sizeof(buffer)) {
+ dk3str_c16_cpy(buffer, p);
+ ptr = buffer; cc = 1;
+ while((cc) && (ptr)) {
+ ptr = dk3str_c16_chr(ptr, 0x005CU);
+ if(ptr) {
+ *ptr = 0U;
+ if((dk3str_c16_len(buffer) > 0) && (!dk3sf_c16_is_drive(buffer))) {
+ if(dk3sf_c16_stat_app(&stb, buffer, NULL)) {
+ if(((stb.ft) & (~(DK3_FT_SYMLINK))) != DK3_FT_DIRECTORY) {
+ cc = 0;
+ if(app) {
+ /* Not a directory! */
+#if DK3_CHAR_SIZE == 2
+ dk3app_log_i3(app, DK3_LL_ERROR, 81, 82, buffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 83);
+#endif
+ }
+ }
+ } else {
+ if(_wmkdir(buffer) != 0) {
+ cc = 0;
+ if(app) {
+ /* Failed to create directory! */
+#if DK3_CHAR_SIZE == 2
+ dk3app_log_i3(app, DK3_LL_ERROR, 84, 85, buffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 86);
+#endif
+ }
+ }
+ }
+ }
+ *ptr = 0x005CU;
+ ptr++;
+ }
+ }
+ if(cc) {
+ if(dk3sf_c16_stat_app(&stb, buffer, NULL)) {
+ if(((stb.ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_DIRECTORY) {
+ back = 1;
+ } else {
+ if(app) {
+ /* Not a directory! */
+#if DK3_CHAR_SIZE == 2
+ dk3app_log_i3(app, DK3_LL_ERROR, 81, 82, buffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 83);
+#endif
+ }
+ }
+ } else {
+ if(_wmkdir(buffer) == 0) {
+ back = 1;
+ } else {
+#if DK3_CHAR_SIZE == 2
+ dk3app_log_i3(app, DK3_LL_ERROR, 84, 85, buffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 86);
+#endif
+ }
+ }
+ }
+ } else {
+ if(app) {
+ /* Path too long! */
+#if DK3_CHAR_SIZE == 2
+ dk3app_log_i3(app, DK3_LL_ERROR, 59, 60, p);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 87);
+#endif
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c16_get_hostname_app(dk3_c16_t *db, size_t sz, dk3_app_t *app)
+{
+ int back = 0;
+ DWORD s = 0; /* Buffer size / result length. */
+ if((db) && (sz)) {
+ s = (DWORD)sz;
+ if(GetComputerNameExW(ComputerNameNetBIOS, db, &s)) {
+ if((size_t)s < sz) {
+ db[(size_t)s] = L'\0';
+ } else {
+ db[sz - 1] = L'\0';
+ }
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Failed to find NetBIOS name! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 131);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c8_get_hostname_app(char *db, size_t sz, dk3_app_t *app)
+{
+ int back = 0;
+ DWORD s = 0; /* Buffer size / result length. */
+ if((db) && (sz)) {
+ s = (DWORD)sz;
+ if(GetComputerNameExA(ComputerNameNetBIOS, db, &s)) {
+ if((size_t)s < sz) {
+ db[(size_t)s] = '\0';
+ } else {
+ db[sz - 1] = '\0';
+ }
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Failed to find NetBIOS name! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 131);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "dkChar must be 8 or 16 bit!"
+#else
+/* +++ Windows, dkChar 16 bit +++ */
+
+
+
+int
+dk3sf_fgets_fn_app(
+ dkChar *db, size_t sz, FILE *fi, dkChar const *fn, dk3_app_t *app
+)
+{
+ int back = 0;
+ $? "+ dk3sf_fgets"
+ if((db) && (sz) && (fi)) {
+ if(fgetws(db, (int)sz, fi)) {
+ if(db[0] == DK3_CHAR_BOM) { $? ". BOM at start of line"
+ dk3str_c16_cpy(db, &(db[1]));
+ }
+ back = 1;
+ } else {
+ if(!feof(fi)) {
+ if(app) {
+ if(fn) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 346, 347, fn);
+ } else {
+ dk3app_log_i1(app, DK3_LL_ERROR, 345);
+ }
+ }
+ }
+ }
+ } $? "- dk3sf_fgets %d", back
+ return back;
+}
+
+
+
+int
+dk3sf_fputc_fn_app(dkChar ch, FILE *fi, dkChar const *fn, dk3_app_t *app)
+{
+ int back = 0;
+ if(fi) {
+ if(fputwc(ch, fi) != WEOF) {
+ back = 1;
+ } else {
+ if(app) {
+ if(fn) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 343, 344, fn);
+ } else {
+ dk3app_log_i1(app, DK3_LL_ERROR, 120);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_fputs_fn_app(dkChar const *st,FILE *fi,dkChar const *fn,dk3_app_t *app)
+{
+ int back = 0;
+ if((st) && (fi)) {
+ if(fputws(st, fi) != WEOF) {
+ back = 1;
+ } else {
+ if(app) {
+ if(fn) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 343, 344, fn);
+ } else {
+ dk3app_log_i1(app, DK3_LL_ERROR, 120);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void
+dk3sf_initialize_stdout(void)
+{
+ static int not_bom_written_to_stdout = 1;
+ if(not_bom_written_to_stdout) {
+ not_bom_written_to_stdout = 0;
+ (void)_setmode(_fileno(stdout), _O_U16TEXT);
+ if(!_isatty(_fileno(stdout))) {
+ fputwc(0xFEFF, stdout);
+ }
+ }
+}
+
+
+
+void
+dk3sf_initialize_stdout_no_bom(void)
+{
+ static int not_bom_written_to_stdout = 1;
+ if(not_bom_written_to_stdout) {
+ not_bom_written_to_stdout = 0;
+ (void)_setmode(_fileno(stdout), _O_U16TEXT);
+ }
+}
+
+
+
+void
+dk3sf_initialize_stderr(void)
+{
+ static int not_bom_written_to_stderr = 1;
+ if(not_bom_written_to_stderr) {
+ not_bom_written_to_stderr = 0;
+ (void)_setmode(_fileno(stderr), _O_U16TEXT);
+ if(!_isatty(_fileno(stderr))) {
+ fputwc(0xFEFF, stderr);
+ }
+ }
+}
+
+
+
+void
+dk3sf_initialize_file(FILE *fipo)
+{
+ (void)_setmode(_fileno(fipo), _O_U16TEXT);
+ fputwc(0xFEFF, fipo);
+}
+
+
+
+/* --- Windows, dkChar 16 bit --- */
+#endif
+#else
+/* +++ Windows, dkChar 8 bit +++ */
+
+
+
+int
+dk3sf_fgets_fn_app(
+ dkChar *db, size_t sz, FILE *fi, dkChar const *fn, dk3_app_t *app
+)
+{
+ int back = 0;
+ if((db) && (sz) && (fi)) {
+ if(fgets(db, sz, fi)) {
+ back = 1;
+ } else {
+ if(!feof(fi)) {
+ if(app) {
+ if(fn) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 346, 347, fn);
+ } else {
+ dk3app_log_i1(app, DK3_LL_ERROR, 345);
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+int
+dk3sf_fputs_fn_app(dkChar const *st,FILE *fi,dkChar const *fn,dk3_app_t *app)
+{
+ int back = 0;
+ if((st) && (fi)) {
+ if(fputs(st, fi) != EOF) {
+ back = 1;
+ } else {
+ if(app) {
+ if(fn) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 343, 344, fn);
+ } else {
+ dk3app_log_i1(app, DK3_LL_ERROR, 120);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_fputc_fn_app(dkChar ch, FILE *fi, dkChar const *fn, dk3_app_t *app)
+{
+ int back = 0;
+ if(fi) {
+ if(fputc(ch, fi) != EOF) {
+ back = 1;
+ } else {
+ if(app) {
+ if(fn) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 343, 344, fn);
+ } else {
+ dk3app_log_i1(app, DK3_LL_ERROR, 120);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void
+dk3sf_initialize_stdout(void)
+{
+}
+
+
+
+void
+dk3sf_initialize_stderr(void)
+{
+}
+
+
+void
+dk3sf_initialize_file(FILE *fipo)
+{
+}
+
+
+/* --- Windows, dkChar 8 bit --- */
+#endif
+
+/* --- Windows --- */
+#else
+/* +++ non-Windows +++ */
+
+
+
+/** 8-bit character keywords for use on non-Windows systems.
+*/
+static char const * const kw_c8_no_win[] = {
+/* 0 */ "/",
+/* 1 */ "PATH",
+NULL
+};
+
+
+
+dk3_um_t
+dk3sf_getpid(void)
+{
+ dk3_um_t back = DK3_UM_0;
+#if DK3_HAVE_GETPID
+ back = (dk3_um_t)getpid();
+#else
+#if DK3_HAVE__GETPID
+ back = (dk3_um_t)_getpid();
+#else
+#error "No getpid() function!"
+#endif
+#endif
+ return back;
+}
+
+
+
+dk3_c8_t *
+dk3sf_c8_getenv(char const *name)
+{
+ char *back = NULL;
+ if(name) {
+ back = getenv(name);
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c8_remove_dir_app(char const *n, dk3_app_t *app)
+{
+ int back = 0;
+ if(n) {
+#if DK3_HAVE_RMDIR
+ if(rmdir(n) == 0) {
+ back = 1;
+ } else {
+ if(app) {
+ /* Failed to remove directory! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 69, 70, n);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 68);
+#endif
+ dk3sf_report_errno(app, errno, dk3sf_function_names[2]);
+ }
+ }
+#else
+#error "No rmdir() function!"
+#endif
+ }
+ return back;
+}
+
+
+int
+dk3sf_c8_remove_file_app(char const *n, dk3_app_t *app)
+{
+ int back = 0;
+ if(n) {
+#if DK3_HAVE_UNLINK
+ if(unlink(n) == 0) {
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Failed to unlink file */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 88, 89, n);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 90);
+#endif
+ dk3sf_report_errno(app, errno, dk3sf_function_names[3]);
+ }
+ }
+#else
+#error "No support for unlink"
+#endif
+ }
+ return back;
+}
+
+
+/** Copy logname of user record to buffer.
+ @param d Destination buffer.
+ @param s Size of \a d.
+ @param p User record.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3sf_c8_copy_logname(char *d, size_t s, struct passwd *p, dk3_app_t *app)
+{
+ int back = 0;
+ $? "+ dk3sf_c8_copy_logname"
+ if(p) { $? ". p ok"
+ if(p->pw_name) { $? ". name ok"
+ if(dk3str_c8_len(p->pw_name) < s) { $? ". name length ok"
+ dk3str_c8_cpy_not_overlapped(d, p->pw_name);
+ back = 1;
+ } else { $? "! name too long"
+ if(app) {
+ /* Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ } else {
+ if(app) {
+ /* No name entry in record! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 91);
+ }
+ }
+ } $? "- dk3sf_c8_copy_logname %d", back
+ return back;
+}
+
+
+
+int
+dk3sf_c8_get_logname_app(char *d, size_t s, dk3_app_t *app)
+{
+ int back = 0;
+ uid_t u = 0; /* Current user ID. */
+ struct passwd *p = NULL; /* Current user to process. */
+ char uidbuffer[128]; /* Text buffer to store UID. */
+ $? "+ dk3sf_c8_get_logname_app"
+ if((d) && (s)) {
+ u = getuid();
+#if DK3_HAVE_GETPWUID
+ p = getpwuid(u); $? ". getpwuid()"
+ if(p) { $? ". entry found"
+ back = dk3sf_c8_copy_logname(d, s, p, app);
+ } else { $? "! entry not found"
+ if(app) {
+ /* No passwd record for UID! */
+#if DK3_CHAR_SIZE == 1
+ dk3ma_um_to_c8_string(uidbuffer, sizeof(uidbuffer), (dk3_um_t)u);
+ dk3app_log_i3(app, DK3_LL_ERROR, 92, 93, uidbuffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 94);
+#endif
+ dk3sf_report_errno(app, errno, dk3sf_function_names[4]);
+ }
+ }
+#else
+#if DK3_HAVE_SETPWENT
+ setpwent();
+#endif
+ {
+ int cc;
+ int found; $? ". getpwent()"
+ cc = 1; found = 0;
+ while(cc) {
+ p = getpwent();
+ if(p) {
+ if(p->pw_uid == u) {
+ cc = 0;
+ found = 1; $? ". entry found"
+ back = dk3sf_c8_copy_logname(d, s, p, app);
+ }
+ } else { cc = 0; }
+ }
+ if(!found) { $? "! entry not found"
+ if(app) {
+ /* No passwd record for UID! */
+#if DK3_CHAR_SIZE == 1
+ dk3ma_um_to_c8_string(uidbuffer, sizeof(uidbuffer), (dk3_um_t)u);
+ dk3app_log_i3(app, DK3_LL_ERROR, 92, 93, uidbuffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 94);
+#endif
+ }
+ }
+ }
+#if DK3_HAVE_SETPWENT
+ endpwent();
+#endif
+#endif
+ } $? "- dk3sf_c8_get_logname_app %d", back
+ return back;
+}
+
+
+
+int
+dk3sf_c8_get_home_app(char *d, size_t s, dk3_app_t *app)
+{
+ int back = 0;
+ uid_t u = 0; /* Current user ID to process. */
+ struct passwd *p = NULL; /* Current user to process. */
+ char uidbuffer[128]; /* Text buffer to store UID. */
+ if((d) && (s)) {
+ u = getuid();
+#if DK3_HAVE_GETPWUID
+ p = getpwuid(u);
+ if(p) {
+ if(p->pw_dir) {
+ if(dk3str_c8_len(p->pw_dir) < s) {
+ dk3str_c8_cpy_not_overlapped(d, p->pw_dir);
+ back = 1;
+ } else {
+ if(app) {
+ /* Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ } else {
+ if(app) {
+ /* Home directory entry empty! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 95);
+ }
+ }
+ } else {
+ if(app) {
+ /* No passwd record for uid! */
+#if DK3_CHAR_SIZE == 1
+ dk3ma_um_to_c8_string(uidbuffer, sizeof(uidbuffer), (dk3_um_t)u);
+ dk3app_log_i3(app, DK3_LL_ERROR, 92, 93, uidbuffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 94);
+#endif
+ dk3sf_report_errno(app, errno, dk3sf_function_names[4]);
+ }
+ }
+#else
+ {
+ int cc;
+ int found;
+ cc = 1; found = 0;
+#if DK3_HAVE_SETPWENT
+ setpwent();
+#endif
+ while(cc) {
+ p = getpwent();
+ if(p) {
+ if(p->pw_uid == u) {
+ cc = 0; found = 1;
+ if(p->pw_dir) {
+ if(dk3str_c8_len(p->pw_dir) < s) {
+ dk3str_c8_cpy_not_overlapped(d, p->pw_dir);
+ back = 1;
+ } else {
+ if(app) {
+ /* Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ } else {
+ if(app) {
+ /* Home directory entry empty! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 95);
+ }
+ }
+ }
+ } else { cc = 0; }
+ }
+#if DK3_HAVE_SETPWENT
+ endpwent();
+#endif
+ if(!found) {
+ if(app) {
+ /* No entry for uid! */
+#if DK3_CHAR_SIZE == 1
+ dk3ma_um_to_c8_string(uidbuffer, sizeof(uidbuffer), (dk3_um_t)u);
+ dk3app_log_i3(app, DK3_LL_ERROR, 92, 93, uidbuffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 94);
+#endif
+ }
+ }
+ }
+#endif
+ }
+ return back;
+}
+
+
+int
+dk3sf_time(dk3_time_t *timer)
+{
+ int back = 1;
+ time(timer);
+ return back;
+}
+
+
+
+/** Convert file type from system representation to DK3_FT_xxx.
+ @param m File type as found by stat().
+ @return DK3_FT_xxx.
+*/
+static
+int
+dk3sf_convert_file_type(mode_t m)
+{
+ int back = 0;
+ switch(m & S_IFMT) {
+ case S_IFIFO: back = DK3_FT_FIFO; break;
+ case S_IFCHR: back = DK3_FT_SPECIAL_CHAR; break;
+ case S_IFDIR: back = DK3_FT_DIRECTORY; break;
+ case S_IFBLK: back = DK3_FT_SPECIAL_BLOCK; break;
+ case S_IFREG: back = DK3_FT_REGULAR; break;
+ case S_IFSOCK: back = DK3_FT_SOCKET; break;
+#ifdef S_IFMPC
+ case S_IFMPC: back = DK3_FT_MUX_CHAR; break;
+#endif
+#ifdef S_IFNAM
+ case S_IFNAM: back = DK3_FT_XENIX_SPECIAL; break;
+#endif
+#ifdef S_INSEM
+ case S_INSEM: back = DK3_FT_XENIX_SEMAPHORE; break;
+#endif
+#ifdef S_INSHD
+ case S_INSHD: back = DK3_FT_XENIX_SHARED_DATA; break;
+#endif
+#ifdef S_IFMPB
+ case S_IFMPB: back = DK3_FT_MUX_BLOCK; break;
+#endif
+#ifdef S_IFCMP
+ case S_IFCMP: back = DK3_FT_VXFS_COMPRESSED; break;
+#endif
+#ifdef S_IFNWK
+ case S_IFNWK: back = DK3_FT_NETWORK_SPECIAL; break;
+#endif
+#ifdef S_IFSHAD
+ case S_IFSHAD: back = DK3_FT_ACL_SHADOW; break;
+#endif
+#ifdef S_IFDOOR
+ case S_IFDOOR: back = DK3_FT_DOOR; break;
+#endif
+#ifdef S_IFWHT
+ case S_IFWHT: back = DK3_FT_WHITEOUT; break;
+#endif
+ }
+ return back;
+}
+
+
+
+/** Convert file permissions from system representation to
+ DK3_PERM_xxx
+ @param m File mode as obtained from stat().
+ @return DK3_PERM_xxx value or combination.
+*/
+static
+int
+dk3sf_convert_file_permissions(mode_t m)
+{
+ int back = 0;
+ DK3SF_ADDIF(S_IRUSR,DK3_FPERM_U_READ)
+ DK3SF_ADDIF(S_IWUSR,DK3_FPERM_U_WRITE)
+ DK3SF_ADDIF(S_IXUSR,DK3_FPERM_U_EXEC)
+ DK3SF_ADDIF(S_IRGRP,DK3_FPERM_G_READ)
+ DK3SF_ADDIF(S_IWGRP,DK3_FPERM_G_WRITE)
+ DK3SF_ADDIF(S_IXGRP,DK3_FPERM_G_EXEC)
+ DK3SF_ADDIF(S_IROTH,DK3_FPERM_O_READ)
+ DK3SF_ADDIF(S_IWOTH,DK3_FPERM_O_WRITE)
+ DK3SF_ADDIF(S_IXOTH,DK3_FPERM_O_EXEC)
+ DK3SF_ADDIF(S_ISUID,DK3_FPERM_SUID)
+ DK3SF_ADDIF(S_ISGID,DK3_FPERM_SGID)
+ DK3SF_ADDIF(S_ISVTX,DK3_FPERM_VTX)
+ return back;
+}
+
+
+
+/** Convert file permissions back from dktools to system values.
+ @param m File permissions in dktools notation.
+ @return File permissions in system notation.
+*/
+static
+mode_t
+dk3sf_convert_back_file_permissions(int m)
+{
+ mode_t back = 0;
+ DK3SF_ADDIF(DK3_FPERM_U_READ,S_IRUSR)
+ DK3SF_ADDIF(DK3_FPERM_U_WRITE,S_IWUSR)
+ DK3SF_ADDIF(DK3_FPERM_U_EXEC,S_IXUSR)
+ DK3SF_ADDIF(DK3_FPERM_G_READ,S_IRGRP)
+ DK3SF_ADDIF(DK3_FPERM_G_WRITE,S_IWGRP)
+ DK3SF_ADDIF(DK3_FPERM_G_EXEC,S_IXGRP)
+ DK3SF_ADDIF(DK3_FPERM_O_READ,S_IROTH)
+ DK3SF_ADDIF(DK3_FPERM_O_WRITE,S_IWOTH)
+ DK3SF_ADDIF(DK3_FPERM_O_EXEC,S_IXOTH)
+ DK3SF_ADDIF(DK3_FPERM_SUID,S_ISUID)
+ DK3SF_ADDIF(DK3_FPERM_SGID,S_ISGID)
+ DK3SF_ADDIF(DK3_FPERM_VTX,S_ISVTX)
+ return back;
+}
+
+
+int
+dk3sf_c8_stat_app(dk3_stat_t *st, char const *fn, dk3_app_t *app)
+{
+ int back = 0;
+ $? "+ dk3sf_c8_stat_app \"%!8s\"", fn
+ if((st) && (fn)) {
+#if DK3_HAVE_LARGEFILE64_SOURCE && DK3_HAVE_STAT64
+ struct stat64 stb; /* Result from stat64(). */
+#if DK3_HAVE_LSTAT64
+ struct stat64 lstb; /* Result from lstat64(). */
+#endif
+ $? ". use stat64() / lstat64()"
+ if(stat64(fn, &stb) == 0) { $? ". stat64 ok"
+ st->u = (dk3_um_t)(stb.st_uid);
+ st->g = (dk3_um_t)(stb.st_gid);
+ st->device = (dk3_um_t)(stb.st_dev);
+ st->rdev = (dk3_um_t)(stb.st_rdev);
+ st->inode = (dk3_um_t)(stb.st_ino);
+ st->nlink = (dk3_um_t)(stb.st_nlink);
+ st->cre = (dk3_time_t)(stb.st_ctime);
+ st->mod = (dk3_time_t)(stb.st_mtime);
+ st->acc = (dk3_time_t)(stb.st_atime);
+ st->ft = dk3sf_convert_file_type(stb.st_mode);
+ st->perm = dk3sf_convert_file_permissions(stb.st_mode);
+ st->sz = (dk3_um_t)(stb.st_size);
+ st->lsz = st->sz;
+ st->ai = 0x00;
+#if DK3_HAVE_LSTAT64
+ if(lstat64(fn, &lstb) == 0) {
+ back = 1;
+ if(((lstb.st_mode) & S_IFMT) == S_IFLNK) {
+ st->ft |= DK3_FT_SYMLINK;
+ st->lu = (dk3_um_t)(lstb.st_uid);
+ st->lg = (dk3_um_t)(lstb.st_gid);
+ st->ldevice = (dk3_um_t)(lstb.st_dev);
+ st->lrdev = (dk3_um_t)(lstb.st_rdev);
+ st->linode = (dk3_um_t)(lstb.st_ino);
+ st->lnlink = (dk3_um_t)(lstb.st_nlink);
+ st->lcre = (dk3_time_t)(lstb.st_ctime);
+ st->lmod = (dk3_time_t)(lstb.st_mtime);
+ st->lacc = (dk3_time_t)(lstb.st_atime);
+ st->lft = dk3sf_convert_file_type(lstb.st_mode);
+ st->lperm = dk3sf_convert_file_permissions(lstb.st_mode);
+ st->lsz = (dk3_um_t)(lstb.st_size);
+ if(lstb.st_uid != stb.st_uid) {
+ st->ai |= DK3_STAT_AI_USER_DIFFERS;
+ }
+ if(lstb.st_gid != stb.st_gid) {
+ st->ai |= DK3_STAT_AI_GROUP_DIFFERS;
+ }
+ if(lstb.st_dev != stb.st_dev) {
+ st->ai |= DK3_STAT_AI_FAR_LINK;
+ }
+ } $? ". ft = %d", st->ft
+ } else { $? "! lstat64() failed"
+ if(app) {
+ /* lstat() failed! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 96, 97, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 98);
+#endif
+ }
+ }
+#else
+ back = 1;
+#endif
+ } else { $? "! stat64() failed for \"%!8s\"", fn
+#if DK3_HAVE_LSTAT64
+ if(lstat64(fn, &lstb) == 0) {
+ back = 1;
+ st->u = DK3_UM_0;
+ st->g = DK3_UM_0;
+ st->device = DK3_UM_0;
+ st->rdev = DK3_UM_0;
+ st->inode = DK3_UM_0;
+ st->nlink = DK3_UM_0;
+ st->cre = (dk3_time_t)0UL;
+ st->mod = (dk3_time_t)0UL;
+ st->acc = (dk3_time_t)0UL;
+ st->ft = DK3_FT_SYMLINK | DK3_FT_BAD_SYMLINK;
+ st->perm = 0;
+ st->sz = DK3_UM_0;
+ st->ai = 0x00;
+ st->lu = (dk3_um_t)(lstb.st_uid);
+ st->lg = (dk3_um_t)(lstb.st_gid);
+ st->ldevice = (dk3_um_t)(lstb.st_dev);
+ st->lrdev = (dk3_um_t)(lstb.st_rdev);
+ st->linode = (dk3_um_t)(lstb.st_ino);
+ st->lnlink = (dk3_um_t)(lstb.st_nlink);
+ st->lcre = (dk3_time_t)(lstb.st_ctime);
+ st->lmod = (dk3_time_t)(lstb.st_mtime);
+ st->lacc = (dk3_time_t)(lstb.st_atime);
+ st->lft = dk3sf_convert_file_type(lstb.st_mode);
+ st->lperm = dk3sf_convert_file_permissions(lstb.st_mode);
+ st->lsz = (dk3_um_t)(lstb.st_size);
+ } else {
+ if(app) {
+ /* stat failed */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 61, 62, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 99);
+#endif
+ dk3sf_report_errno(app, errno, dk3sf_function_names[5]);
+ }
+ }
+#else
+ if(app) {
+ /* stat failed */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 61, 62, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 99);
+#endif
+ dk3sf_report_errno(app, errno, dk3sf_function_names[6]);
+ }
+#endif
+ }
+#else
+#if DK3_HAVE_STAT
+ struct stat stb;
+#if DK3_HAVE_LSTAT
+ struct stat lstb;
+#endif
+ $? ". used stat() / lstat()"
+ if(stat(fn, &stb) == 0) { $? ". stat() ok"
+ st->u = (dk3_um_t)(stb.st_uid);
+ st->g = (dk3_um_t)(stb.st_gid);
+ st->device = (dk3_um_t)(stb.st_dev);
+ st->rdev = (dk3_um_t)(stb.st_rdev);
+ st->inode = (dk3_um_t)(stb.st_ino);
+ st->nlink = (dk3_um_t)(stb.st_nlink);
+ st->cre = (dk3_time_t)(stb.st_ctime);
+ st->mod = (dk3_time_t)(stb.st_mtime);
+ st->acc = (dk3_time_t)(stb.st_atime);
+ st->ft = dk3sf_convert_file_type(stb.st_mode);
+ st->perm = dk3sf_convert_file_permissions(stb.st_mode);
+ st->sz = (dk3_um_t)(stb.st_size);
+ sz->lsz = st->sz;
+ st->ai = 0x00;
+#if DK3_HAVE_LSTAT
+ if(lstat(fn, &lstb) == 0) {
+ back = 1;
+ if(((lstb.st_mode) & S_IFMT) == S_IFLNK) {
+ st->ft |= DK3_FT_SYMLINK;
+ st->lu = (dk3_um_t)(lstb.st_uid);
+ st->lg = (dk3_um_t)(lstb.st_gid);
+ st->ldevice = (dk3_um_t)(lstb.st_dev);
+ st->lrdev = (dk3_um_t)(lstb.st_rdev);
+ st->linode = (dk3_um_t)(lstb.st_ino);
+ st->lnlink = (dk3_um_t)(lstb.st_nlink);
+ st->lcre = (dk3_time_t)(lstb.st_ctime);
+ st->lmod = (dk3_time_t)(lstb.st_mtime);
+ st->lacc = (dk3_time_t)(lstb.st_atime);
+ st->lft = dk3sf_convert_file_type(lstb.st_mode);
+ st->lperm = dk3sf_convert_file_permissions(lstb.st_mode);
+ sz->lsz = (dk3_um_t)(lstb.st_size);
+ if(lstb.st_uid != stb.st_uid) {
+ st->ai |= DK3_STAT_AI_USER_DIFFERS;
+ }
+ if(lstb.st_gid != stb.st_gid) {
+ st->ai |= DK3_STAT_AI_GROUP_DIFFERS;
+ }
+ if(lstb.st_dev != stb.st_dev) {
+ st->ai |= DK3_STAT_AI_FAR_LINK;
+ }
+ } $? ". ft = %d", st->ft
+ } else { $? "! lstat() failed"
+ if(app) {
+ /* lstat() failed! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 96, 97, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 98);
+#endif
+ }
+ }
+#else
+ back = 1;
+#endif
+ } else { $? "! stat() failed"
+#if DK3_HAVE_LSTAT
+ if(lstat(fn,&lstb) == 0) {
+ back = 1;
+ st->u = DK3_UM_0;
+ st->g = DK3_UM_0;
+ st->device = DK3_UM_0;
+ st->rdev = DK3_UM_0;
+ st->inode = DK3_UM_0;
+ st->nlink = DK3_UM_0;
+ st->cre = (dk3_time_t)0UL;
+ st->mod = (dk3_time_t)0UL;
+ st->acc = (dk3_time_t)0UL;
+ st->ft = DK3_FT_SYMLINK | DK3_FT_BAD_SYMLINK;
+ st->perm = 0;
+ st->sz = DK3_UM_0;
+ st->ai = 0x00;
+ st->lu = (dk3_um_t)(lstb.st_uid);
+ st->lg = (dk3_um_t)(lstb.st_gid);
+ st->ldevice = (dk3_um_t)(lstb.st_dev);
+ st->lrdev = (dk3_um_t)(lstb.st_rdev);
+ st->linode = (dk3_um_t)(lstb.st_ino);
+ st->lnlink = (dk3_um_t)(lstb.st_nlink);
+ st->lcre = (dk3_time_t)(lstb.st_ctime);
+ st->lmod = (dk3_time_t)(lstb.st_mtime);
+ st->lacc = (dk3_time_t)(lstb.st_atime);
+ st->lft = dk3sf_convert_file_type(lstb.st_mode);
+ st->lperm = dk3sf_convert_file_permissions(lstb.st_mode);
+ st->lsz = (dk3_um_t)(lstb.st_size);
+ } else {
+ if(app) {
+ /* stat() failed! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 61, 62, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 99);
+#endif
+ dk3sf_report_errno(app, errno, dk3sf_function_names[8]);
+ }
+ }
+#else
+ if(app) {
+ /* stat() failed! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 61, 62, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 99);
+#endif
+ dk3sf_report_errno(app, errno, dk3sf_function_names[7]);
+ }
+#endif
+ }
+#else
+#error "Not stat() function available!"
+#endif
+#endif
+ } $? "- dk3sf_c8_stat_app %d", back
+ return back;
+}
+
+
+
+/** Check whether opening a file is allowed.
+ @param fn File name.
+ @param want_to_write Flag: Write access is wanted.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 for write allowed, 0 for write denied.
+*/
+static
+int
+dk3sf_c8_check_open_file(char const *fn, int want_to_write, dk3_app_t *app)
+{
+ int back = 1;
+ dk3_stat_t stb; /* Check for existing file. */
+ if(dk3sf_c8_stat_app(&stb, fn, NULL)) {
+ if(((stb.ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_DIRECTORY) {
+ if(app) {
+ back = 0;
+ /* Name refers a directory! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 74, 75, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 76);
+#endif
+ }
+ }
+ if(want_to_write) {
+ if((stb.ft) & DK3_FT_SYMLINK) {
+ if((stb.ai) & DK3_STAT_AI_USER_DIFFERS) {
+ back = 0;
+ /* Symlink owner is not file owner! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 100, 101, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 102);
+#endif
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+FILE *
+dk3sf_c8_fopen_app(char const *fn, char const *mo, dk3_app_t *app)
+{
+ FILE *back = NULL;
+ char const *moptr = NULL; /* Traverse mode string. */
+ int want_to_write = 0; /* Flag: Write access wanted. */
+ $? "+ dk3sf_c8_fopen_app \"%!8s\" \"%!8s\"", TR_8STR(fn), TR_8STR(mo)
+ if((fn) && (mo)) {
+ moptr = mo;
+ while(*moptr) {
+ switch(*moptr) {
+ case 'w': case 'a': case '+': { want_to_write = 1; } break;
+ }
+ moptr++;
+ }
+ if(dk3sf_c8_check_open_file(fn, want_to_write, app)) {
+#if DK3_HAVE_LARGEFILE64_SOURCE && DK3_HAVE_FOPEN64
+ back = fopen64(fn, mo); $? ". attempt fopen64"
+#else
+ back = fopen(fn, mo); $? ". attempt fopen"
+#endif
+ if(!(back)) {
+ if(app) {
+ /* Failed to open file for writing! */
+ if(want_to_write) {
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 77, 78, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 79);
+#endif
+ } else {
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 143, 144, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 145);
+#endif
+ }
+ dk3sf_report_errno(app, errno, dk3sf_function_names[9]);
+ }
+ }
+ }
+ } $? "- dk3sf_c8_fopen_app %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+#if DK3_HAVE_LOCALTIME_R
+int
+dk3sf_localtime_app(
+ dk3_tm_t *dest,
+ dk3_time_t *timer,
+ dk3_app_t *app
+)
+{
+ int back = 0;
+ struct tm res, *rp;
+ if((dest) && (timer)) {
+ if((rp = localtime_r(timer, &res)) != NULL) {
+ back = 1;
+ dest->Y = 1900 + rp->tm_year;
+ dest->M = 1 + rp->tm_mon;
+ dest->D = rp->tm_mday;
+ dest->h = rp->tm_hour;
+ dest->m = rp->tm_min;
+ dest->s = rp->tm_sec;
+ } else {
+ if(app) {
+ /* ERROR: localtime_r failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 268);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[10]);
+ }
+ }
+ }
+ return back;
+}
+
+int
+dk3sf_c8_time_convert_app(
+ dkChar *dest, size_t sz, dk3_time_t const *timer, dk3_app_t *app
+)
+{
+ int back = 0;
+ char buffer[64]; /* Buffer. */
+ struct tm res, *rp; /* Conversion result. */
+ if((dest) && (sz) && (timer)) {
+ rp = localtime_r(timer, &res);
+ if(rp) {
+ sprintf(
+ buffer,
+ "%04d-%02d-%02d %02d:%02d:%02d",
+ (1900 + rp->tm_year),
+ (1 + rp->tm_mon),
+ rp->tm_mday,
+ rp->tm_hour,
+ rp->tm_min,
+ rp->tm_sec
+ );
+ if(sz > dk3str_c8_len(buffer)) {
+ dk3str_c8_cpy_not_overlapped(dest, buffer);
+ back = 1;
+ } else {
+ if(app) {
+ /* Buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ } else {
+ if(app) {
+ /* localtime_r failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 80);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[10]);
+ }
+ }
+ }
+ return back;
+}
+#else
+#error "Function localtime_r() not available!"
+#endif
+
+
+
+#if DK3_HAVE_GETCWD || DK3_HAVE__GETCWD
+int
+dk3sf_c8_getcwd_app(char *dest, size_t sz, dk3_app_t *app)
+{
+ int back = 0;
+ if((dest) && (sz)) {
+#if DK3_HAVE_GETCWD
+ if(getcwd(dest, sz))
+#else
+ if(_getcwd(dest, sz))
+#endif
+ {
+ back = 1;
+ } else {
+ if(app) {
+ switch(errno) {
+#ifdef ERANGE
+ case ERANGE: {
+ /* Buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ } break;
+#endif
+ default: {
+ dk3app_log_i1(app, DK3_LL_ERROR, 53);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[11]);
+ } break;
+ }
+ }
+ }
+ }
+ return back;
+}
+#else
+#error "Neither getcwd() or _getcwd() available!"
+#endif
+
+
+
+/** Check whether or not a file is executable.
+ @param f File name.
+ @return 1 for exectuable, 0 for not executable.
+*/
+static
+int
+dk3sf_c8_check_exec(char const *f)
+{
+ int back = 0;
+ int testperm; /* Permissions of file. */
+ dk3_stat_t stb; /* stat() result to check for file. */
+ $? "+ dk3sf_c8_check_exec \"%!8s\"", f
+ if(dk3sf_c8_stat_app(&stb, f, NULL)) { $? ". file name ok"
+ if(((stb.ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_REGULAR) { $? ". type ok"
+ testperm = (DK3_FPERM_U_EXEC | DK3_FPERM_G_EXEC | DK3_FPERM_O_EXEC);
+ if((stb.perm) & testperm) { $? ". permissions ok"
+ back = 1;
+ } else { $? "! wrong permissions"
+ }
+ } else { $? "! wrong file type"
+ }
+ } else { $? "! file does not exist"
+ } $? "- dk3sf_c8_check_exec %d", back
+ return back;
+}
+
+
+
+int
+dk3sf_c8_find_exec_app(
+ char *d, size_t s, char const *w, char const *c, dk3_app_t *app
+)
+{
+ int back = 0;
+ int cc = 0; /* Flag: Can continue. */
+ char *pathcopy = NULL; /* Copy of parent directory. */
+ char *p = NULL;
+ char *pn = NULL;
+ size_t tsl = 0; /* Needed buffer length. */
+ $? "+ dk3sf_c8_find_exec_app"
+ if((d) && (s) && (w) && (c)) { $? ". args ok"
+ if(dk3str_c8_chr(c, DK3_C8_SEP)) { $? ". combine w and c"
+ if(dk3str_c8_is_abs_path(c)) { $? ". c is absolute path"
+ if(dk3str_c8_len(c) < s) { $? ". buffer length ok"
+ dk3str_c8_cpy_not_overlapped(d, c);
+ back = 1; $? ". result \"%!8s\"", d
+ } else { $? "! buffer too short"
+ if(app) {
+ /* c too long! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 103, 104, c);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 105);
+#endif
+ }
+ }
+ } else { $? ". c is relative path"
+ if(dk3str_c8_len(w) < s) {
+ dk3str_c8_cpy_not_overlapped(d, w);
+ back = dk3str_c8_append_path_app(d, s, c, app);
+ if(back) { $? ". result \"%!8s\"", d
+ }
+ } else { $? "! buffer too short"
+ if(app) {
+ /* w too long! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 59, 60, w);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 87);
+#endif
+ }
+ }
+ }
+ } else { $? ". search PATH"
+ p = getenv(kw_c8_no_win[1]);
+ if(p) { $? ". PATH ok"
+ pathcopy = dk3str_dup_app(p, app);
+ if(pathcopy) { $? ". copy ok"
+ p = pathcopy; cc = 1;
+ while((p) && (cc) && (back == 0)) {
+ pn = dk3str_c8_chr(p, ':');
+ if(pn) { *(pn++) = '\0'; }
+ if(dk3str_c8_len(p)) { $? ". one directory"
+ tsl = dk3str_c8_len(p);
+ tsl += dk3str_c8_len(kw_c8_no_win[0]);
+ tsl += dk3str_c8_len(c);
+ if(tsl < s) { $? ". buffer length ok"
+ dk3str_c8_cpy_not_overlapped(d, p);
+ dk3str_c8_cat(d, kw_c8_no_win[0]);
+ dk3str_c8_cat(d, c);
+ back = dk3sf_c8_check_exec(d);
+ } else { $? "! buffer too short"
+ cc = 0;
+ if(app) {
+ /* Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ } else { $? ". current directory"
+ tsl = dk3str_c8_len(w);
+ tsl += dk3str_c8_len(kw_c8_no_win[0]);
+ tsl += dk3str_c8_len(c);
+ if(tsl < s) { $? ". buffer length ok"
+ dk3str_c8_cpy_not_overlapped(d, w);
+ dk3str_c8_cat(d, kw_c8_no_win[0]);
+ dk3str_c8_cat(d, c);
+ back = dk3sf_c8_check_exec(d);
+ } else { $? "! buffer too short"
+ cc = 0;
+ if(app) {
+ /* Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ p = pn;
+ }
+ dk3_delete(pathcopy);
+ } else { $? "! memory"
+ }
+ } else { $? "! No PATH"
+ if(app) {
+ /* PATH environment variable not defined. */
+ dk3app_log_i1(app, DK3_LL_ERROR, 106);
+ }
+ }
+ }
+ } $? "- dk3sf_c8_find_exec_app %d", back
+ return back;
+}
+
+
+
+int
+dk3sf_c8_mkdir_app(char const *p, int mo, dk3_app_t *app)
+{
+ int back = 0;
+ char buffer[DK3_MAX_PATH]; /* File names of parent directories. */
+ char *ptr = NULL; /* Current path separator. */
+ int cc = 0; /* Flag: Can continue. */
+ mode_t m = 0; /* File creation mode. */
+ dk3_stat_t stb; /* Check for existance of file or directory. */
+ $? "+ dk3sf_c8_mkdir_app \"%!8s\"", TR_8STR(p)
+ if(p) { $? ". name ok"
+ m = dk3sf_convert_back_file_permissions(mo);
+ if(dk3str_c8_len(p) < sizeof(buffer)) { $? ". length ok"
+ dk3str_c8_cpy_not_overlapped(buffer, p);
+ ptr = buffer; cc = 1;
+ while((cc) && (ptr)) { $? ". loop \"%!8s\"", ptr
+ ptr = dk3str_c8_chr(ptr, DK3_C8_SEP);
+ if(ptr) {
+ *ptr = '\0'; $? ". directory \"%!8s\"", buffer
+ if(dk3str_c8_len(buffer) > 0) {
+ if(dk3sf_c8_stat_app(&stb, buffer, NULL)) { $? ". path exists"
+ if(((stb.ft) & (~(DK3_FT_SYMLINK))) != DK3_FT_DIRECTORY) {
+ cc = 0; $? "! path is not a directory"
+ if(app) {
+ /* Not a directory! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 81, 82, buffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 83);
+#endif
+ }
+ }
+ } else { $? ". must create dir \"%!8s\"", buffer
+#if DK3_HAVE_MKDIR
+#if DK3_HAVE_MKDIR2
+ if(mkdir(buffer, m) == 0)
+#else
+ if(mkdir(buffer) == 0)
+#endif
+ {
+#if DK3_HAVE_CHMOD
+ (void)chmod(buffer, m); $? ". mode %o", m
+#endif
+ } else {
+ cc = 0; $? "! failed to create directory"
+ if(app) {
+ /* Failed to create directory! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 84, 85, buffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 86);
+#endif
+ dk3sf_report_errno(app, errno, dk3sf_function_names[12]);
+ }
+ }
+#else
+ cc = 0;
+ if(app) { $? "! no mkdir) function"
+ /* No mkdir() function available! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 107);
+ }
+#endif
+ }
+ }
+ *ptr = DK3_C8_SEP;
+ ptr++;
+ }
+ }
+ if(cc) { $? ". all parents ok path now \"%!8s\"", buffer
+ if(dk3sf_c8_stat_app(&stb, buffer, NULL)) { $? ". path exists"
+ if(((stb.ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_DIRECTORY) {
+ back = 1; $? ". path is a directory"
+ } else { $? "! path is not a directory"
+ if(app) {
+ /* Not a directory! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 81, 82, buffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 83);
+#endif
+ }
+ }
+ } else { $? ". must create \"%!8s\"", buffer
+#if DK3_HAVE_MKDIR
+#if DK3_HAVE_MKDIR2
+ if(mkdir(buffer, m) == 0)
+#else
+ if(mkdir(buffer) == 0)
+#endif
+ {
+ back = 1; $? ". \"%!8s\" created successfully", buffer
+#if DK3_HAVE_CHMOD
+ (void)chmod(buffer, m); $? ". mode %o", m
+#endif
+ } else { $? "! failed to create \"%!8s\"", buffer
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 84, 85, buffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 86);
+#endif
+ dk3sf_report_errno(app, errno, dk3sf_function_names[12]);
+ }
+#else
+ if(app) { $? "! no mkdir() function"
+ /* No mkdir() function available! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 107);
+ }
+#endif
+ }
+ }
+ } else { $? "! directory name too long"
+ if(app) {
+ /* Path too long! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 59, 60, p);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 87);
+#endif
+ }
+ }
+ } $? "- dk3sf_c8_mkdir_app %d", back
+ return back;
+}
+
+
+int
+dk3sf_c8_get_hostname_app(char *db, size_t sz, dk3_app_t *app)
+{
+ int back = 0;
+ char *ptr = NULL; /* Begin of DNS domain name. */
+ if((db) && (sz)) {
+ if(gethostname(db, sz) == 0) {
+ back = 1;
+ ptr = dk3str_c8_chr(db, '.');
+ if(ptr) {
+ *ptr = '\0';
+ }
+ } else {
+ if(app) {
+ /* ERROR: Failed to find host name! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 131);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[13]);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+#if DK3_CHAR_SIZE > 1
+#error "dkChar must be 8 bit on non-Windows systems!"
+#else
+/* +++ non-Windows, dkChar 8 bit +++ */
+
+
+
+int
+dk3sf_fgets_fn_app(
+ dkChar *db, size_t sz, FILE *fi, dkChar const *fn, dk3_app_t *app
+)
+{
+ int back = 0;
+ if((db) && (sz) && (fi)) {
+ if(fgets(db, sz, fi)) {
+ back = 1;
+ } else {
+ if(!feof(fi)) {
+ if(app) {
+ if(fn) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 346, 347, fn);
+ } else {
+ dk3app_log_i1(app, DK3_LL_ERROR, 345);
+ }
+ dk3sf_report_errno(app, errno, dk3sf_function_names[25]);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_fputs_fn_app(dkChar const *st,FILE *fi,dkChar const *fn,dk3_app_t *app)
+{
+ int back = 0;
+ if((st) && (fi)) {
+ if(fputs(st, fi) >= 0) {
+ back = 1;
+ } else {
+ if(app) {
+ if(fn) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 343, 344, fn);
+ } else {
+ dk3app_log_i1(app, DK3_LL_ERROR, 120);
+ }
+ dk3sf_report_errno(app, errno, dk3sf_function_names[23]);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_fputc_fn_app(dkChar ch, FILE *fi, dkChar const *fn, dk3_app_t *app)
+{
+ int back = 0;
+ if(fi) {
+ if(fputc(ch, fi) != EOF) {
+ back = 1;
+ } else {
+ if(app) {
+ if(fn) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 343, 344, fn);
+ } else {
+ dk3app_log_i1(app, DK3_LL_ERROR, 120);
+ }
+ dk3sf_report_errno(app, errno, dk3sf_function_names[24]);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void
+dk3sf_initialize_stdout(void)
+{
+}
+
+
+
+void
+dk3sf_initialize_stderr(void)
+{
+}
+
+
+
+void
+dk3sf_initialize_file(FILE *fipo)
+{
+}
+
+
+
+/* --- non-Windows, dkChar 8 bit --- */
+#endif
+
+/* --- non-Windows --- */
+#endif
+
+
+
+int
+dk3sf_must_expand(dkChar const *fn)
+{
+ int back = 0;
+ $? "+ dk3sf_must_expand"
+ if(fn) {
+#if DK3_ON_WINDOWS
+ dkChar const *ptr;
+ ptr = fn;
+ while((*ptr) && (back == 0)) {
+ switch(*ptr) {
+ case dkT('?'):
+ case dkT('*'):
+ {
+ back = 1;
+ }
+ break;
+ }
+ ptr++;
+ }
+#endif
+ } $? "- dk3sf_must_expand %d", back
+ return back;
+}
+
+
+
+int
+dk3sf_c8_fputc(char c, FILE *f)
+{
+ int back = 0;
+ if(f) {
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ if(fputwc((((wchar_t)c) & 0x000000FFUL), f) != WEOF) {
+ back = 1;
+ }
+#else
+ if(fputwc((((wchar_t)c) & 0x00FFU), f) != WEOF) {
+ back = 1;
+ }
+#endif
+#else
+ if(fputc(c, f) != EOF) {
+ back = 1;
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c8_fputs(char const *s, FILE *f)
+{
+ int back = 0;
+ char const *ptr = NULL;
+ if((s) && (f)) {
+ back = 1;
+ ptr = s;
+ while(*ptr) {
+ if(!dk3sf_c8_fputc(*(ptr++), f)) {
+ back = 0;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+size_t
+dk3sf_read_app(int fd, void *buf, size_t s, dk3_app_t *app)
+{
+ size_t back = 0;
+ $? "+ dk3sf_read_app buf=%!8s s=%u", TR_8PTR(buf), (unsigned)s
+ if((buf) && (s)) {
+#if DK3_ON_WINDOWS
+ int rb;
+ $? ". Windows +"
+ rb = _read(fd, buf, (unsigned int)s);
+ if(rb >= 0) {
+ back = (size_t)rb;
+ } else {
+ /* ERROR: Read failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 124);
+ }
+ $? ". Windows -"
+#else
+ $? ". non-Windows +"
+#if DK3_HAVE_READ
+ ssize_t rb = 0; /* Number of bytes read. */
+ $? ". read() +"
+ rb = read(fd, buf, s);
+ if(rb >= (ssize_t)0) {
+ back = (size_t)rb;
+ } else {
+ if(app) {
+ /* ERROR: Read failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 124);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[14]);
+ }
+ } $? ". read() -"
+#else
+#if DK3_HAVE__READ
+ ssize_t rb = 0; /* Number of bytes read. */
+ $? ". _read() +"
+ rb = _read(fd, buf, s);
+ if(rb >= (ssize_t)0) {
+ back = (size_t)rb;
+ } else {
+ if(app) {
+ /* ERROR: Read failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 124);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[15]);
+ }
+ } $? ". _read() -"
+#else
+#error "No read() function available!"
+#endif
+#endif
+ $? ". non-Windows -"
+#endif
+ } $? "- dk3sf_read_app %u", (unsigned)back
+ return back;
+}
+
+
+
+int
+dk3sf_write_app(int fd, char const *buf, size_t s, dk3_app_t *app)
+{
+ int back = 0;
+ if((buf) && (s)) {
+#if DK3_ON_WINDOWS
+ int wb;
+ wb = _write(fd, buf, (unsigned int)s);
+ if(wb >= 0) {
+ if((size_t)wb == s) {
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Not all bytes written! */
+ dk3app_log_write_error(app, DK3_LL_ERROR, s, wb);
+ }
+ }
+ } else {
+ if(app) {
+ /* ERROR: Write failed! */
+ dk3app_log_i1( app, DK3_LL_ERROR, 173);
+ }
+ }
+#else
+#if DK3_HAVE_WRITE
+ ssize_t wb;
+ wb = write(fd, buf, s);
+ if(wb >= 0) {
+ if((size_t)wb == s) {
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Not all bytes written! */
+ dk3app_log_write_error(app, DK3_LL_ERROR, s, wb);
+ }
+ }
+ } else {
+ if(app) {
+ /* ERROR: Write failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 173);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[16]);
+ }
+ }
+#else
+#if DK3_HAVE__WRITE
+ ssize_t wb;
+ wb = _write(fd, buf, s);
+ if(wb >= 0) {
+ if((size_t)wb == s) {
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Not all bytes written! */
+ dk3app_log_write_error(app, DK3_LL_ERROR, s, wb);
+ }
+ }
+ } else {
+ if(app) {
+ /* ERROR: Write failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 173);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[17]);
+ }
+ }
+#else
+#error "No write() function available!"
+#endif
+#endif
+#endif
+ }
+ return back;
+}
+
+
+size_t
+dk3sf_fread_app(void *db, size_t sz, size_t ne, FILE *fi, dk3_app_t *app)
+{
+ size_t back = 0;
+ if((db) && (sz) && (ne) && (fi)) {
+#if DK3_ON_WINDOWS
+ back = fread(db, sz, ne, fi);
+ if(back < ne) {
+ if(ferror(fi)) {
+ if(app) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 124);
+ }
+ }
+ clearerr(fi);
+ }
+#else
+#if DK3_HAVE_FREAD
+ back = fread(db, sz, ne, fi);
+ if(back < ne) {
+ if(ferror(fi)) {
+ if(app) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 124);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[18]);
+ }
+ } clearerr(fi);
+ }
+#else
+#if DK3_HAVE__FREAD
+ back = _fread(db, sz, ne, fi);
+ if(back < ne) {
+ if(ferror(fi)) {
+ if(app) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 124);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[19]);
+ }
+ } clearerr(fi);
+ }
+#else
+#error "No fread() function available!"
+#endif
+#endif
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_fwrite_app(void const *sb, size_t sz, size_t ne, FILE *fi, dk3_app_t *app)
+{
+ int back = 0;
+ if((sb) && (sz) && (ne) && (fi)) {
+#if DK3_ON_WINDOWS
+ size_t wb;
+ wb = fwrite(sb, sz, ne, fi);
+ if(wb == ne) {
+ back = 1;
+ } else {
+ if(app) {
+ dk3app_log_fwrite_error(app, DK3_LL_ERROR, ne, wb);
+ }
+ }
+#else
+#if DK3_HAVE_FWRITE
+ size_t wb;
+ wb = fwrite(sb, sz, ne, fi);
+ if(wb == ne) {
+ back = 1;
+ } else {
+ if(app) {
+ dk3app_log_fwrite_error(app, DK3_LL_ERROR, ne, wb);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[20]);
+ }
+ }
+#else
+#if DK3_HAVE__FWRITE
+ size_t wb;
+ wb = _fwrite(sb, sz, ne, fi);
+ if(wb == ne) {
+ back = 1;
+ } else {
+ if(app) {
+ dk3app_log_fwrite_error(app, DK3_LL_ERROR, ne, wb);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[21]);
+ }
+ }
+#else
+#error "No fwrite() function available!"
+#endif
+#endif
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_inspect_bom_skip_app(
+ dkChar const *fn,
+ int dv,
+ size_t *skb,
+ dk3_app_t *app
+)
+{
+ int back = -1;
+ int found = 0; /* Flag: Any form of BOM found .*/
+ FILE *fipo = NULL; /* Input file. */
+ unsigned char bb[4]; /* Buffer for BOM. */
+ size_t rb = 0; /* Number of bytes read. */
+ $? "+ dk3sf_inspect_bom_app %d", dv
+ if(skb) { *skb = 0; }
+ back = dv;
+ if(fn) {
+ fipo = dk3sf_fopen_app(fn, dk3app_not_localized(36), app);
+ if(fipo) {
+ rb = dk3sf_fread_app(bb, 1, 4, fipo, app);
+ /* Check UTF-8 */
+ if(rb >= 3) {
+ if((bb[0] == 0xEF) && (bb[1] == 0xBB) && (bb[2] == 0xBF)) {
+ found = 1; back = DK3_FILE_ENCODING_UTF8; $? ". UTF-8"
+ if(skb) { *skb = 3; }
+ }
+ }
+ if(!found) {
+ if(rb >= 2) {
+ if((bb[0] == 0xFE) && (bb[1] == 0xFF)) {
+ found = 1; back = DK3_FILE_ENCODING_UTF16_MSB_FIRST; $? ". U16 M"
+ if(skb) { *skb = 2; }
+ } else {
+ if((bb[0] == 0xFF) && (bb[1] == 0xFE)) {
+ found = 1; back = DK3_FILE_ENCODING_UTF16_LSB_FIRST; $? ". U16 L"
+ if(skb) { *skb = 2; }
+ if(rb >= 4) {
+ if((bb[2] == 0x00) && (bb[3] == 0x00)) {
+ back = DK3_FILE_ENCODING_UNICODE_LSB_FIRST; $? ". U32 L"
+ if(skb) { *skb = 4; }
+ }
+ }
+ }
+ }
+ }
+ }
+ if(!found) {
+ if(rb >= 4) {
+ if((bb[0] == 0x00) && (bb[1] == 0x00)
+ && (bb[2] == 0xFE) && (bb[3] == 0xFF)
+ )
+ {
+ found = 1; back = DK3_FILE_ENCODING_UNICODE_MSB_FIRST; $? ". U32 M"
+ if(skb) { *skb = 4; }
+ }
+ }
+ }
+ if(!found) {
+ /* No BOM found */
+ back = dv;
+ }
+ fclose(fipo);
+ }
+ } $? "- dk3sf_inspect_bom_app %d", back
+ return back;
+}
+
+
+
+int
+dk3sf_inspect_bom_app(dkChar const *fn, int dv, dk3_app_t *app)
+{
+ int back;
+ back = dk3sf_inspect_bom_skip_app(fn, dv, NULL, app);
+ return back;
+}
+
+
+
+int
+dk3sf_apply_bom_to_file_app(FILE *fipo, int enc, dk3_app_t *app)
+{
+ int back = 0;
+ $? "+ dk3sf_apply_bom_to_file_app"
+#if DK3_ON_WINDOWS
+ if(fipo) {
+ switch(enc) {
+ case DK3_FILE_ENCODING_ASCII: {
+ back = 1; $? ". keep default"
+ } break;
+ case DK3_FILE_ENCODING_UTF8: {
+ back = 1;
+ _setmode(_fileno(fipo), _O_U8TEXT); $? ". 8"
+ } break;
+ case DK3_FILE_ENCODING_UTF16_LSB_FIRST: {
+ _setmode(_fileno(fipo), _O_U16TEXT); $? ". 16 L"
+ } break;
+ default: {
+ /* ERROR: Encoding can not be handled directly by file! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 204);
+ } break;
+ }
+ }
+#else
+ if(fipo) {
+ switch(enc) {
+ case DK3_FILE_ENCODING_ASCII: case DK3_FILE_ENCODING_UTF8: {
+ back = 1; $? ". 8-bit, ok"
+ } break;
+ default: {
+ /* ERROR: Encoding can not be handled direcly by file! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 204);
+ } break;
+ }
+ }
+#endif
+ $? "- dk3sf_apply_bom_to_file_app %d", back
+ return back;
+}
+
+
+
+int
+dk3sf_is_dir_app(dkChar const *n, dk3_app_t *app)
+{
+ int back = 0;
+ dk3_stat_t stb;
+ if(dk3sf_stat_app(&stb, n, app)) {
+ if(((stb.ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_DIRECTORY) {
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: n is not a directory! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 202, 203, n);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_chdir_app(dkChar const *dn, dk3_app_t *app)
+{
+ int back = 0;
+ if(dn) {
+#if DK3_CHAR_SIZE > 1
+#if DK3_ON_WINDOWS
+ if(_wchdir(dn) == 0) {
+ back = 1;
+ } else {
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 242, 243, dn);
+ }
+ }
+#else
+#error "No chdir() function (16-bit) on non-Windows systems!"
+#endif
+#else
+#if DK3_ON_WINDOWS
+ if(chdir(dn) == 0) {
+ back = 1;
+ } else {
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 242, 243, dn);
+ }
+ }
+#else
+#if DK3_HAVE_CHDIR
+ if(chdir(dn) == 0) {
+ back = 1;
+ } else {
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 242, 243, dn);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[22]);
+ }
+ }
+#else
+#error "No chdir() function available!"
+#endif
+#endif
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_must_rebuild(dkChar const *dn, dkChar const *sn)
+{
+ int back = 1;
+ dk3_stat_t stbs;
+ dk3_stat_t stbd;
+ if((dn) && (sn)) {
+ if(dk3sf_stat_app(&stbd, dn, NULL)) {
+ if(dk3sf_stat_app(&stbs, sn, NULL)) {
+ if(stbd.mod > stbs.mod) {
+ back = 0;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_filename_to_c8(
+ char *fnb, size_t szfnb, dkChar const *src, dk3_app_t *app
+)
+{
+ int back = 0;
+ if((fnb) && (szfnb) && (src)) {
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "Only 1- or 2-byte character support available!"
+#else
+#if DK3_ON_WINDOWS
+ back = dk3str_cnv_c16_to_c8p_app(fnb, szfnb, src, app);
+#else
+#error "2-byte character support is available on Windows platforms only!"
+#endif
+#endif
+#else
+ if(dk3str_len(src) < szfnb) {
+ dk3str_cpy_not_overlapped(fnb, src);
+ back = 1;
+ } else {
+ /* ERROR: File name too long! */
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 65, 66, src);
+ }
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_scan_double_app(dkChar const *txt, double *v, dk3_app_t *app)
+{
+ int back = 0;
+ $? "+ dk3sf_scan_double"
+ if((txt) && (v)) { $? ". args ok"
+#if DK3_HAVE_SETLOCALE
+ char oldlocale[64];
+ char *lcptr;
+
+ lcptr = setlocale(LC_NUMERIC, NULL); $? ". have setlocale"
+ if(lcptr) { $? ". setlocale (1) ok"
+ if(dk3str_c8_len(lcptr) < sizeof(oldlocale)) { $? ". length ok"
+ dk3str_c8_cpy_not_overlapped(oldlocale, lcptr);
+ setlocale(LC_NUMERIC, "C");
+#if VERSION_BEFORE_20140716
+ back = dk3sf_sscanf3(txt,dkT("%lf"),v);
+#else
+ back = dk3ma_d_from_string(v, txt, NULL);
+#endif
+ setlocale(LC_NUMERIC, oldlocale);
+ } else { $? "! too long"
+#if VERSION_BEFORE_20140716
+ dk3sf_sscanf3(txt,dkT("%lf"),v);
+#else
+ back = dk3ma_d_from_string(v, txt, NULL);
+#endif
+ if(app) {
+ /* ERROR: Failed to save current locale! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 254);
+ }
+ }
+ } else { $? "! setlocale (1)"
+#if VERSION_BEFORE_20140716
+ dk3sf_sscanf3(txt,dkT("%lf"),v);
+#else
+ back = dk3ma_d_from_string(v, txt, NULL);
+#endif
+ if(app) {
+ /* ERROR: Failed to obtain current locale! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 253);
+ }
+ }
+#else
+#if VERSION_BEFORE_20140716
+ back = dk3sf_sscanf3(txt,dkT("%lf"),v); $? ". no setlocale"
+#else
+ back = dk3ma_d_from_string(v, txt, NULL);
+#endif
+#endif
+ } $? "- dk3sf_scan_double %d", back
+ return back;
+}
+
+
+
+int
+dk3sf_get_max_files(void)
+{
+ int back = 1024;
+#if DK3_HAVE_SYS_RESOURCE_H
+#if DK3_HAVE_GETRLIMIT
+ struct rlimit rl;
+ if(getrlimit(RLIMIT_NOFILE, &rl) >= 0) {
+ if(rl.rlim_max != RLIM_INFINITY) {
+ back = rl.rlim_max;
+ }
+ }
+#endif
+#endif
+ return back;
+}
+
+
+
+
+int
+dk3sf_fclose_fn_app(FILE *fipo, dkChar const *fn, dk3_app_t *app)
+{
+ int back = 0;
+ int res;
+ if(fipo) {
+ res = fclose(fipo);
+ if(0 == res) {
+ back = 1;
+ } else {
+ if(fn) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 341, 342, fn);
+ } else {
+ dk3app_log_i1(app, DK3_LL_ERROR, 340);
+ }
+ dk3sf_report_errno(app, errno, dk3sf_function_names[1]);
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_fclose_app(FILE *fipo, dk3_app_t *app)
+{
+ int back = 0;
+ back = dk3sf_fclose_fn_app(fipo, NULL, app);
+ return back;
+}
+
+
+
+int
+dk3sf_fgets(dkChar *db, size_t sz, FILE *fi)
+{
+ int back;
+ back = dk3sf_fgets_fn_app(db, sz, fi, NULL, NULL);
+ return back;
+}
+
+
+
+int
+dk3sf_fputs(dkChar const *st, FILE *fi)
+{
+ int back;
+ back = dk3sf_fputs_fn_app(st, fi, NULL, NULL);
+ return back;
+}
+
+
+
+int
+dk3sf_fputt(dkChar const * const *txt, FILE *fi)
+{
+ dkChar const * const *ptr;
+ int back = 0;
+ if((txt) && (fi)) {
+ back = 1;
+ ptr = txt;
+ while(*ptr) {
+ if(!(dk3sf_fputs(*(ptr++), fi))) {
+ back = 0;
+ }
+ dk3sf_fputc(dkT('\n'), fi);
+ }
+ }
+ return back;
+}
+
+
+int
+dk3sf_fputc(dkChar c, FILE *fi)
+{
+ int back;
+ back = dk3sf_fputc_fn_app(c, fi, NULL, NULL);
+ return back;
+}
+
+
+
+int
+dk3sf_stat_app(dk3_stat_t *st, dkChar const *fn, dk3_app_t *app)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "System function for b-byte character strings not available!"
+#else
+#if DK3_ON_WINDOWS
+ return(dk3sf_c16_stat_app(st, fn, app));
+#else
+#error "Wide character functions not defined on non-Windows systems!"
+#endif
+#endif
+#else
+ return(dk3sf_c8_stat_app(st, fn, app));
+#endif
+}
+
+
+
+FILE *
+dk3sf_fopen_app(dkChar const *fn, dkChar const *mo, dk3_app_t *app)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "System function for b-byte character strings not available!"
+#else
+#if DK3_ON_WINDOWS
+ return(dk3sf_c16_fopen_app(fn, mo, app));
+#else
+#error "Wide character functions not defined on non-Windows systems!"
+#endif
+#endif
+#else
+ return(dk3sf_c8_fopen_app(fn, mo, app));
+#endif
+}
+
+
+
+int
+dk3sf_time_convert_app(
+ dkChar *dest,
+ size_t sz,
+ dk3_time_t const *timer,
+ dk3_app_t *app
+)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "System function for b-byte character strings not available!"
+#else
+#if DK3_ON_WINDOWS
+ return(dk3sf_c16_time_convert_app(dest, sz, timer, app));
+#else
+#error "Wide character functions not defined on non-Windows systems!"
+#endif
+#endif
+#else
+ return(dk3sf_c8_time_convert_app(dest, sz, timer, app));
+#endif
+}
+
+
+
+int
+dk3sf_getcwd_app(dkChar *dest, size_t sz, dk3_app_t *app)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "System function for b-byte character strings not available!"
+#else
+#if DK3_ON_WINDOWS
+ return(dk3sf_c16_getcwd_app(dest, sz, app));
+#else
+#error "Wide character functions not defined on non-Windows systems!"
+#endif
+#endif
+#else
+ return(dk3sf_c8_getcwd_app(dest, sz, app));
+#endif
+}
+
+
+
+int
+dk3sf_find_exec_app(
+ dkChar *d,
+ size_t s,
+ dkChar const *w,
+ dkChar const *c,
+ dk3_app_t *app
+)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "System function for b-byte character strings not available!"
+#else
+#if DK3_ON_WINDOWS
+ return(dk3sf_c16_find_exec_app(d, s, w, c, app));
+#else
+#error "Wide character functions not defined on non-Windows systems!"
+#endif
+#endif
+#else
+ return(dk3sf_c8_find_exec_app(d, s, w, c, app));
+#endif
+}
+
+
+
+int
+dk3sf_get_logname_app(dkChar *d, size_t s, dk3_app_t *app)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "System function for b-byte character strings not available!"
+#else
+#if DK3_ON_WINDOWS
+ return(dk3sf_c16_get_logname_app(d, s, app));
+#else
+#error "Wide character functions not defined on non-Windows systems!"
+#endif
+#endif
+#else
+ return(dk3sf_c8_get_logname_app(d, s, app));
+#endif
+}
+
+
+
+int
+dk3sf_get_home_app(dkChar *d, size_t s, dk3_app_t *app)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "System function for b-byte character strings not available!"
+#else
+#if DK3_ON_WINDOWS
+ return(dk3sf_c16_get_home_app(d, s, app));
+#else
+#error "Wide character functions not defined on non-Windows systems!"
+#endif
+#endif
+#else
+ return(dk3sf_c8_get_home_app(d, s, app));
+#endif
+}
+
+
+
+int
+dk3sf_mkdir_app(dkChar const *p, int mo, dk3_app_t *app)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "System function for b-byte character strings not available!"
+#else
+#if DK3_ON_WINDOWS
+ return(dk3sf_c16_mkdir_app(p, mo, app));
+#else
+#error "Wide character functions not defined on non-Windows systems!"
+#endif
+#endif
+#else
+ return(dk3sf_c8_mkdir_app(p, mo, app));
+#endif
+}
+
+
+
+int
+dk3sf_remove_file_app(dkChar const *n, dk3_app_t *app)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "System function for b-byte character strings not available!"
+#else
+#if DK3_ON_WINDOWS
+ return(dk3sf_c16_remove_file_app(n, app));
+#else
+#error "Wide character functions not defined on non-Windows systems!"
+#endif
+#endif
+#else
+ return(dk3sf_c8_remove_file_app(n, app));
+#endif
+}
+
+
+
+int
+dk3sf_remove_dir_app(dkChar const *n, dk3_app_t *app)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "System function for b-byte character strings not available!"
+#else
+#if DK3_ON_WINDOWS
+ return(dk3sf_c16_remove_dir_app(n, app));
+#else
+#error "Wide character functions not defined on non-Windows systems!"
+#endif
+#endif
+#else
+ return(dk3sf_c8_remove_dir_app(n, app));
+#endif
+}
+
+
+
+int
+dk3sf_get_hostname_app(dkChar *db, size_t sz, dk3_app_t *app)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "System function for b-byte character strings not available!"
+#else
+#if DK3_ON_WINDOWS
+ return(dk3sf_c16_get_hostname_app(db, sz, app));
+#else
+#error "Wide character functions not defined on non-Windows systems!"
+#endif
+#endif
+#else
+ return(dk3sf_c8_get_hostname_app(db, sz, app));
+#endif
+}
+
+
+
+dkChar *
+dk3sf_getenv(dkChar const *name)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "System function for b-byte character strings not available!"
+#else
+#if DK3_ON_WINDOWS
+ return(dk3sf_c16_getenv(name));
+#else
+#error "Wide character functions not defined on non-Windows systems!"
+#endif
+#endif
+#else
+ return(dk3sf_c8_getenv(name));
+#endif
+}
+
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dk3sf.h b/support/dktools/dk3sf.h
new file mode 100644
index 0000000000..dbd2905927
--- /dev/null
+++ b/support/dktools/dk3sf.h
@@ -0,0 +1,783 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3sf.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3sf.h Header file for the dk3sf module.
+*/
+
+#ifndef DK3SF_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3SF_H_INCLUDED 1
+
+
+#line 10 "dk3sf.ctr"
+
+#include "dk3conf.h"
+#include "dk3types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if DK3_ON_WINDOWS
+
+/** Retrieve information about a file.
+ @param st File information buffer.
+ @param fn File name.
+ @param app Application structure, used for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c16_stat_app(dk3_stat_t *st, dk3_c16_t const *fn, dk3_app_t *app);
+
+/** Open a file.
+ @param fn File name.
+ @param mo Mode.
+ @param app Application structure, used for diagnostics.
+ @return FILE pointer on success, NULL on error.
+*/
+FILE *
+dk3sf_c16_fopen_app(dk3_c16_t const *fn, dk3_c16_t const *mo, dk3_app_t *app);
+
+/** Convert timestamp to text.
+ @param dest Destination buffer.
+ @param sz Size of \a dest (number of characters).
+ @param timer Timestamp to convert.
+ @param app Application structure, used for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c16_time_convert_app(
+ dk3_c16_t *dest, size_t sz, dk3_time_t const *timer, dk3_app_t *app
+);
+
+/** Get current working directory.
+ @param dest Destination buffer.
+ @param sz Size of \a dest.
+ The size must not exceed INT_MAX/2.
+ Practically this is not a limitation
+ as the useful buffer size is DK3_MAX_PATH elements.
+ @param app Application structure, used for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c16_getcwd_app(dk3_c16_t *dest, size_t sz, dk3_app_t *app);
+
+/** Find executable file.
+ @param d Destination buffer.
+ @param s Size of \a d (number of characters).
+ The size must not exceed 2^31-1. Practically this is not a
+ limitation as the useful buffer size is DK3_MAX_PATH elements.
+ @param w Current working directory.
+ @param c Command as typed in the command line.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c16_find_exec_app(
+ dk3_c16_t *d, size_t s, dk3_c16_t const *w, dk3_c16_t const *c, dk3_app_t *app
+);
+
+/** Find users home directory.
+ @param d Destination buffer.
+ @param s Size of \a d (number of characters).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c16_get_home_app(dk3_c16_t *d, size_t s, dk3_app_t *app);
+
+
+/** Remove (unlink) path.
+ @param n Path name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c16_remove_file_app(dk3_c16_t const *n, dk3_app_t *app);
+
+
+/** Remove directory.
+ @param n Directory name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c16_remove_dir_app(dk3_c16_t const *n, dk3_app_t *app);
+
+/** Retrieve host name (short name, without DNS domain).
+ @param db Destination buffer.
+ @param sz Size of \a db (number of characters).
+ The size must not exceed INT_MAX. Practically this is not a
+ limitation as I have never seen host names longer than 80 characters.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c16_get_hostname_app(dk3_c16_t *db, size_t sz, dk3_app_t *app);
+
+/** Get login name.
+ @param d Destination buffer.
+ @param s Size of \a d (number of characters).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c16_get_logname_app(dk3_c16_t *d, size_t s, dk3_app_t *app);
+
+
+/** Create directory if it does not yet exist.
+ @param p Path name.
+ @param mo Creation mode.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c16_mkdir_app(dk3_c16_t const *p, int mo, dk3_app_t *app);;
+
+/** Get environment variable.
+ @param name Environment variable name.
+ @return Value on success, NULL on error.
+*/
+dk3_c16_t *
+dk3sf_c16_getenv(dk3_c16_t const *name);
+
+#else
+
+
+#endif
+
+/** Retrieve information about a file.
+ @param st File information buffer.
+ @param fn File name.
+ @param app Application structure, used for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c8_stat_app(dk3_stat_t *st, char const *fn, dk3_app_t *app);
+
+/** Open a file.
+ @param fn File name.
+ @param mo Mode.
+ @param app Application structure, used for diagnostics.
+ @return FILE pointer on success, NULL on error.
+*/
+FILE *
+dk3sf_c8_fopen_app(char const *fn, char const *mo, dk3_app_t *app);
+
+/** Convert timestamp to text.
+ @param dest Destination buffer.
+ @param sz Size of \a dest (number of characters).
+ @param timer Timestamp to convert.
+ @param app Application structure, used for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c8_time_convert_app(
+ char *dest, size_t sz, dk3_time_t const *timer, dk3_app_t *app
+);
+
+/** Get current working directory.
+ @param dest Destination buffer.
+ @param sz Size of \a dest.
+ On some platforms the size is converted to int, so it
+ should not exceed 32767. Practically this is not a limitation
+ as the userful buffer size is DK3_MAX_PATH.
+ @param app Application structure, used for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c8_getcwd_app(char *dest, size_t sz, dk3_app_t *app);
+
+/** Read input line.
+ @param db Destination buffer.
+ @param sz Size of \a db (number of characters).
+ @param fi Input file.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_fgets(dkChar *db, size_t sz, FILE *fi);
+
+/** Read input line.
+ @param db Destination buffer.
+ @param sz Size of \a db (number of characters).
+ The size must not exceed 32767 as it is converted to int on some
+ systems.
+ @param fi Input file.
+ @param fn Input file name, may be NULL.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_fgets_fn_app(
+ dkChar *db, size_t sz, FILE *fi, dkChar const *fn, dk3_app_t *app
+);
+
+/** Write string to file.
+ @param st String to write.
+ @param fi File to write to.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_fputs(dkChar const *st, FILE *fi);
+
+/** Write string to file, report errors if any.
+ @param st String to write.
+ @param fi Output file to write to.
+ @param fn File name for error messages, may be NULL.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_fputs_fn_app(dkChar const *st,FILE *fi,dkChar const *fn,dk3_app_t *app);
+
+/** Write array of line strings to file.
+ @param txt Pointer to array of lines.
+ @param fi Output file to write to.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_fputt(dkChar const * const *txt, FILE *fi);
+
+/** Write one character to file.
+ @param ch Character to write.
+ @param fi File to write to.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_fputc(dkChar ch, FILE *fi);
+
+/** Write one character to file.
+ @param ch Character to write.
+ @param fi File to write to.
+ @param fn File name of output file.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_fputc_fn_app(dkChar ch, FILE *fi, dkChar const *fn, dk3_app_t *app);
+
+/** Write byte order marker 0xFEFF to standard output.
+*/
+void
+dk3sf_initialize_stdout(void);
+
+/** Only set stdout mode, do not write byte order marker
+ 0xFEFF to standard output.
+*/
+void
+dk3sf_initialize_stdout_no_bom(void);
+
+/** Write byte order marker 0xFEFF to standard error output.
+*/
+void
+dk3sf_initialize_stderr(void);
+
+/** Write byte order marker 0xFEFF to file.
+ @param fipo File to set up.
+*/
+void
+dk3sf_initialize_file(FILE *fipo);
+
+/** Prepare standard output and standard error output for multibyte
+ characters (write byte order marker 0xFEFF).
+*/
+void
+dk3sf_initialize_output(void);
+
+/** Get current timestamp.
+ @param timer Pointer to result variable.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_time(dk3_time_t *timer);
+
+/** Find executable file.
+ @param d Destination buffer.
+ @param s Size of \a d (number of characters).
+ The size should not exceed 2^32-1 as it is converted to
+ a DWORD. Practically this is not a restriction as DK3_MAX_PATH
+ is the useful buffer size.
+ @param w Current working directory.
+ @param c Command as typed in the command line.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c8_find_exec_app(
+ char *d, size_t s, char const *w, char const *c, dk3_app_t *app
+);
+
+/** Find users home directory.
+ @param d Destination buffer.
+ @param s Size of \a d (number of characters).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c8_get_home_app(char *d, size_t s, dk3_app_t *app);
+
+/** Get current users login name.
+ @param d Destination buffer.
+ @param s Size of \a d (number of characters).
+ @param app Application structure for diagnostics, may be NULL.
+*/
+int
+dk3sf_c8_get_logname_app(char *d, size_t s, dk3_app_t *app);
+
+/** Create directory if it does not yet exist.
+ @param p Path name.
+ @param mo Creation mode.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c8_mkdir_app(char const *p, int mo, dk3_app_t *app);
+
+/** Remove (unlink) path.
+ @param n Path name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c8_remove_file_app(char const *n, dk3_app_t *app);
+
+/** Remove directory.
+ @param n Directory name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c8_remove_dir_app(char const *n, dk3_app_t *app);
+
+/** Get current process ID.
+ @return Process ID.
+*/
+dk3_um_t
+dk3sf_getpid(void);
+
+/** Check whether we must expand a file name.
+ @param fn File name to check.
+ @return 1 for "must expand", 0 for "no need to expand".
+*/
+int
+dk3sf_must_expand(dkChar const *fn);
+
+/** Retrieve host name (short name).
+ @param db Destination buffer.
+ @param sz Size of \a db (number of characters).
+ The size must not exceed 2^32-1. Practically this is not a
+ limitation as the useful buffer size for host name is below 256.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c8_get_hostname_app(char *db, size_t sz, dk3_app_t *app);
+
+/** Print 8-bit character to file, convert to 16 bit if necessary.
+ @param c Character to print.
+ @param f File to write to.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c8_fputc(char c, FILE *f);
+
+/** Print 8-bit character string to file, convert to 16 bit if necessary.
+ @param s String to print.
+ @param f File to write to.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c8_fputs(char const *s, FILE *f);
+
+/** Read bytes from file descriptor into buffer.
+ @param fd File descriptor.
+ @param buf Buffer.
+ @param s Size of \a buf.
+ The size must not exceed 65535 as it is converted to unsigned int
+ on some systems.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Number of bytes read.
+*/
+size_t
+dk3sf_read_app(int fd, void *buf, size_t s, dk3_app_t *app);
+
+/** Write bytes to file descriptor.
+ @param fd File descriptor.
+ @param buf Buffer to write.
+ @param s Size of \a buf in bytes.
+ The size must not exceed 65535 as it is converted to unsigned int
+ on some systems.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 for success (all bytes written), 0 on error.
+*/
+int
+dk3sf_write_app(int fd, char const *buf, size_t s, dk3_app_t *app);
+
+/** Read from file.
+ @param db Destination buffer.
+ @param sz Size of one element.
+ @param ne Number of elements.
+ @param fi File to read from.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Number of elements read.
+*/
+size_t
+dk3sf_fread_app(void *db, size_t sz, size_t ne, FILE *fi, dk3_app_t *app);
+
+/** Write to file.
+ @param sb Source buffer.
+ @param sz Size of one element.
+ @param ne Number of elements.
+ @param fi File to write to.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success (all elements written), 0 on error.
+*/
+int
+dk3sf_fwrite_app(void const *sb,size_t sz,size_t ne,FILE *fi,dk3_app_t *app);
+
+/** Inspect file, search for byte order marker.
+ The function inspects the first 4 bytes from file and attempts
+ to find the file encoding (DK3_FILE_ENCODING_xxx).
+ If there is no BOM at the beginning of the file the default
+ value \a dv is returned. A value for \a dv can be obtained
+ from dk3app_get_output_encoding() or by inspecting the DK3_CHAR_SIZE
+ value and the language setting (ending on "UTF-8" or "utf8"?).
+ @param fn File name.
+ @param dv Default value for file encoding.
+ @param app Application structure for diagnostics, may be NULL.
+ @return File encoding if BOM found, default value \a dv otherwise.
+*/
+int
+dk3sf_inspect_bom_app(dkChar const *fn, int dv, dk3_app_t *app);
+
+/** Inspect file, search for byte order marker. If byte order marker
+ is found save number of bytes to skip at beginning of file
+ to variable.
+ The function inspects the first 4 bytes from file and attempts
+ to find the file encoding (DK3_FILE_ENCODING_xxx).
+ If there is no BOM at the beginning of the file the default
+ value \a dv is returned. A value for \a dv can be obtained
+ from dk3app_get_output_encoding() or by inspecting the DK3_CHAR_SIZE
+ value and the language setting (ending on "UTF-8" or "utf8"?).
+ @param fn File name.
+ @param dv Default value for file encoding.
+ @param skb Pointer to size_t variable for number of bytes
+ to skip at the beginning of the file.
+ @param app Application structure for diagnostics, may be NULL.
+ @return File encoding if BOM found, default value \a dv otherwise.
+*/
+int
+dk3sf_inspect_bom_skip_app(
+ dkChar const *fn,
+ int dv,
+ size_t *skb,
+ dk3_app_t *app
+);
+
+/** Attempt to apply an encoding found from BOM to an input FILE.
+ This function has an effect on Windows systems only.
+ For \a enc we can handle DK3_FILE_ENCODING_ASCII (mapped to
+ _O_TEXT), DK3_FILE_ENCODING_UTF8 (mapped to _O_U8TEXT) and
+ DK3_FILE_ENCODING_UTF16_LSB (mapped to _O_U16TEXT).
+ @param fipo File pointer.
+ @param enc Encoding found from dk3sf_inspect_bom_app().
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_apply_bom_to_file_app(FILE *fipo, int enc, dk3_app_t *app);
+
+/** Get environment variable.
+ @param name Environment variable name.
+ @return Value on success, NULL on error.
+*/
+char *
+dk3sf_c8_getenv(char const *name);
+
+/** Check whether or not the given file name is a directory.
+ @param n File name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success (is directory), 0 on error.
+*/
+int
+dk3sf_is_dir_app(dkChar const *n, dk3_app_t *app);
+
+/** Change into directory.
+ * @param dn Directory name.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3sf_chdir_app(dkChar const *dn, dk3_app_t *app);
+
+/** Check whether we need to re-build a destination file from a source.
+ * @param dn Destination file name.
+ * @param sn Source file name.
+ * @return 1 for rebuild necessary, 0 for not necessary.
+ */
+int
+dk3sf_must_rebuild(dkChar const *dn, dkChar const *sn);
+
+/** Create 8-bit file name from dkChar file name.
+ @param fnb File name buffer for result.
+ @param szfnb Size of @a fnb (number of bytes).
+ @param src Source file name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_filename_to_c8(
+ char *fnb, size_t szfnb, dkChar const *src, dk3_app_t *app
+);
+
+/** Retrieve a double value in POSIX notation from a string.
+ The sscanf() function depends on the current locale setting.
+ This function retrieves and saves the current locale setting,
+ establishes C locale temporarily for the the sscanf() call and
+ restores the original setting before exiting.
+ @param txt Text to inspect.
+ @param v Pointer to result variable.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_scan_double_app(dkChar const *txt, double *v, dk3_app_t *app);
+
+/** Convert timestamp to human readable date and time.
+ @param dest Destination structure.
+ @param timer Source timestamp.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_localtime_app(dk3_tm_t *dest, dk3_time_t *timer, dk3_app_t *app);
+
+/** Retrieve maximum number of open files.
+ @return Maximum number of open files.
+*/
+int
+dk3sf_get_max_files(void);
+
+/** Report error detailes.
+ @param app Application structure for diagnostics.
+ @param err Error code from errno.
+ @param fctn Function name.
+*/
+void
+dk3sf_report_errno(dk3_app_t *app, int err, dkChar const *fctn);
+
+/** Close a file.
+ @param fipo FILE to close.
+ @param fn File name, may be NULL.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_fclose_fn_app(FILE *fipo, dkChar const *fn, dk3_app_t *app);
+
+/** Close a file.
+ @param fipo FILE to close.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_fclose_app(FILE *fipo, dk3_app_t *app);
+
+/** Retrieve information about a file.
+ @param st File information buffer.
+ @param fn File name.
+ @param app Application structure, used for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_stat_app(dk3_stat_t *st, dkChar const *fn, dk3_app_t *app);
+
+/** Open a file.
+ @param fn File name.
+ @param mo Mode.
+ @param app Application structure, used for diagnostics.
+ @return FILE pointer on success, NULL on error.
+*/
+FILE *
+dk3sf_fopen_app(dkChar const *fn, dkChar const *mo, dk3_app_t *app);
+
+/** Convert timestamp to text.
+ @param dest Destination buffer.
+ @param sz Size of \a dest (number of dkChar).
+ @param timer Timestamp to convert.
+ @param app Application structure, used for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_time_convert_app(
+ dkChar *dest,
+ size_t sz,
+ dk3_time_t const *timer,
+ dk3_app_t *app
+);
+
+/** Get current working directory.
+ @param dest Destination buffer.
+ @param sz Size of \a dest (number of dkChar).
+ The size must not exceed INT_MAX/2. Practically this is not a
+ limitation as the useful buffer size is DK3_MAX_PATH elements.
+ @param app Application structure, used for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_getcwd_app(dkChar *dest, size_t sz, dk3_app_t *app);
+
+/** Find executable file.
+ @param d Destination buffer.
+ @param s Size of \a d (number of dkChar).
+ The size must not exceed 2^31-1. Practically this is not a
+ limitation as the useful buffer size is DK3_MAX_PATH elements.
+ @param w Current working directory.
+ @param c Command as typed in the command line.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_find_exec_app(
+ dkChar *d,
+ size_t s,
+ dkChar const *w,
+ dkChar const *c,
+ dk3_app_t *app
+);
+
+/** Get login name.
+ @param d Destination buffer.
+ @param s Size of \a d (number of dkChar).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_get_logname_app(dkChar *d, size_t s, dk3_app_t *app);
+
+/** Find users home directory.
+ @param d Destination buffer.
+ @param s Size of \a d (number of dkChar).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_get_home_app(dkChar *d, size_t s, dk3_app_t *app);
+
+/** Create directory if it does not yet exist.
+ @param p Path name.
+ @param mo Creation mode.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_mkdir_app(dkChar const *p, int mo, dk3_app_t *app);
+
+/** Remove (unlink) path.
+ @param n Path name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_remove_file_app(dkChar const *n, dk3_app_t *app);
+
+/** Remove directory.
+ @param n Directory name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_remove_dir_app(dkChar const *n, dk3_app_t *app);
+
+/** Retrieve host name (short name, without DNS domain).
+ @param db Destination buffer.
+ @param sz Size of \a db (number of dkChar).
+ The size must not exceed 2^31-1. Practically this is not a
+ limitation as I have never seen host names longer than 80 characters.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_get_hostname_app(dkChar *db, size_t sz, dk3_app_t *app);
+
+/** Get environment variable.
+ @param name Environment variable name.
+ @return Value on success, NULL on error.
+*/
+dkChar *
+dk3sf_getenv(dkChar const *name);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "No functions to support large characters!"
+#else
+#if DK3_ON_WINDOWS
+
+/** Macro to choose correct character size for sscanf()/swscanf().
+*/
+#define dk3sf_sscanf3(s,f,d) swscanf(s,f,d)
+
+/** Macro to choose correct character size for sprintf()/swprintf().
+ NOTE: The first argument must be a *buffer*, *not* a pointer.
+*/
+#define dk3sf_sprintf3(s,f,d) swprintf(s,(sizeof(s)/sizeof(wchar_t)),f,d)
+#else
+#error "16 bit characters are supported on Windows platforms only!"
+#endif
+#endif
+#else
+
+
+/** Macro to choose correct character size for sscanf().
+*/
+#define dk3sf_sscanf3(s,f,d) sscanf(s,f,d)
+
+/** Macro to choose correct character size for sprintf().
+ NOTE: The first argument *must* be a buffer, *not* a pointer.
+*/
+#define dk3sf_sprintf3(s,f,d) sprintf(s,f,d)
+
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3signl.c b/support/dktools/dk3signl.c
new file mode 100644
index 0000000000..c09096c651
--- /dev/null
+++ b/support/dktools/dk3signl.c
@@ -0,0 +1,151 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3signl.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3signl.c The dk3signl module.
+*/
+
+
+#line 47 "dk3signl.ctr"
+
+#include "dk3all.h"
+
+
+
+
+
+#line 53 "dk3signl.ctr"
+
+
+
+#if DK3_HAVE_SIGACTION
+/** Set new signal disposition.
+ @param signo Signal number of signal to modify.
+ @param fct New signal disposition.
+ @return Previous signal disposition.
+*/
+static
+dk3_signal_disp_t
+dk3signal_sigaction(int signo, dk3_signal_disp_t fct)
+{
+ dk3_signal_disp_t back = (dk3_signal_disp_t)SIG_ERR;
+ struct sigaction act, oact;
+
+ act.sa_handler = fct;
+ sigemptyset(&act.sa_mask);
+ if(signo == SIGALRM) {
+#ifdef SA_INTERRUPT
+ act.sa_flags |= SA_INTERRUPT;
+#else
+#ifdef SA_RESTART
+ act.sa_flags |= SA_RESTART;
+#endif
+#endif
+ }
+ if(sigaction(signo, &act, &oact) < 0) {
+ back = (dk3_signal_disp_t)SIG_ERR;
+ } else {
+ back = (dk3_signal_disp_t)oact.sa_handler;
+ }
+ return back;
+}
+#endif
+
+
+dk3_signal_disp_t
+dk3signal_set(int signo, dk3_signal_disp_t fct)
+{
+ dk3_signal_disp_t back = NULL;
+#if DK3_HAVE_SIGACTION
+/* + sigaction */
+ back = dk3signal_sigaction(signo, fct);
+/* - sigaction */
+#else
+#if DK3_HAVE_SIGSET
+/* + sigset */
+ back = (dk3_signal_disp_t)sigset(signo,fct);
+/* - sigset */
+#else
+#if DK3_HAVE_SIGNAL
+/* + signal */
+ back = (dk3_signal_disp_t)signal(signo,fct);
+/* - signal */
+#else
+#error "No signal handling functions available"
+#endif
+#endif
+#endif
+ return back;
+}
+
+
+
+void
+dk3signal_refresh(int signo, dk3_signal_disp_t fct)
+{
+#if DK3_HAVE_SIGACTION
+#else
+#if DK3_HAVE_SIGSET
+#else
+#if DK3_HAVE_SIGNAL
+ (void)signal(signo, fct);
+#else
+#endif
+#endif
+#endif
+}
+
+
+int
+dk3signal_available(void)
+{
+ int back = DK3_SIGNAL_HANDLING_TYPE_NONE;
+#if DK3_HAVE_SIGACTION
+ back = DK3_SIGNAL_HANDLING_TYPE_SIGACTION;
+#else
+#if DK3_HAVE_SIGSET
+ back = DK3_SIGNAL_HANDLING_TYPE_SIGSET;
+#else
+#if DK3_HAVE_SIGNAL
+ back = DK3_SIGNAL_HANDLING_TYPE_SIGNAL;
+#endif
+#endif
+#endif
+ return back;
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dk3signl.ctr b/support/dktools/dk3signl.ctr
new file mode 100644
index 0000000000..a518c3aff5
--- /dev/null
+++ b/support/dktools/dk3signl.ctr
@@ -0,0 +1,155 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% header
+
+#include "dk3conf.h"
+#include "dk3types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Set new handler for the specified signal.
+ @param signo Signal number.
+ @param fct Handler function address.
+ @return The previous handler function address.
+*/
+dk3_signal_disp_t
+dk3signal_set(int signo, dk3_signal_disp_t fct);
+
+/** Refresh signal handler, if only signal() mechanism available.
+ Should be a signal handlers first action.
+ @param signo Signal number.
+ @param fct Handler function address.
+*/
+void
+dk3signal_refresh(int signo, dk3_signal_disp_t fct);
+
+/** Find best available signal handling mechanism.
+ @return DK3_SIGNAL_HANDLING_TYPE_xxx.
+*/
+int
+dk3signal_available(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk3all.h"
+
+
+
+$!trace-include
+
+
+
+#if DK3_HAVE_SIGACTION
+/** Set new signal disposition.
+ @param signo Signal number of signal to modify.
+ @param fct New signal disposition.
+ @return Previous signal disposition.
+*/
+static
+dk3_signal_disp_t
+dk3signal_sigaction(int signo, dk3_signal_disp_t fct)
+{
+ dk3_signal_disp_t back = (dk3_signal_disp_t)SIG_ERR;
+ struct sigaction act, oact;
+
+ act.sa_handler = fct;
+ sigemptyset(&act.sa_mask);
+ if(signo == SIGALRM) {
+#ifdef SA_INTERRUPT
+ act.sa_flags |= SA_INTERRUPT;
+#else
+#ifdef SA_RESTART
+ act.sa_flags |= SA_RESTART;
+#endif
+#endif
+ }
+ if(sigaction(signo, &act, &oact) < 0) {
+ back = (dk3_signal_disp_t)SIG_ERR;
+ } else {
+ back = (dk3_signal_disp_t)oact.sa_handler;
+ }
+ return back;
+}
+#endif
+
+
+dk3_signal_disp_t
+dk3signal_set(int signo, dk3_signal_disp_t fct)
+{
+ dk3_signal_disp_t back = NULL;
+#if DK3_HAVE_SIGACTION
+/* + sigaction */
+ back = dk3signal_sigaction(signo, fct);
+/* - sigaction */
+#else
+#if DK3_HAVE_SIGSET
+/* + sigset */
+ back = (dk3_signal_disp_t)sigset(signo,fct);
+/* - sigset */
+#else
+#if DK3_HAVE_SIGNAL
+/* + signal */
+ back = (dk3_signal_disp_t)signal(signo,fct);
+/* - signal */
+#else
+#error "No signal handling functions available"
+#endif
+#endif
+#endif
+ return back;
+}
+
+
+
+void
+dk3signal_refresh(int signo, dk3_signal_disp_t fct)
+{
+#if DK3_HAVE_SIGACTION
+#else
+#if DK3_HAVE_SIGSET
+#else
+#if DK3_HAVE_SIGNAL
+ (void)signal(signo, fct);
+#else
+#endif
+#endif
+#endif
+}
+
+
+int
+dk3signal_available(void)
+{
+ int back = DK3_SIGNAL_HANDLING_TYPE_NONE;
+#if DK3_HAVE_SIGACTION
+ back = DK3_SIGNAL_HANDLING_TYPE_SIGACTION;
+#else
+#if DK3_HAVE_SIGSET
+ back = DK3_SIGNAL_HANDLING_TYPE_SIGSET;
+#else
+#if DK3_HAVE_SIGNAL
+ back = DK3_SIGNAL_HANDLING_TYPE_SIGNAL;
+#endif
+#endif
+#endif
+ return back;
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dk3signl.h b/support/dktools/dk3signl.h
new file mode 100644
index 0000000000..cbe9e9f8fb
--- /dev/null
+++ b/support/dktools/dk3signl.h
@@ -0,0 +1,82 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3signl.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3signl.h Header file for the dk3signl module.
+*/
+
+#ifndef DK3SIGNL_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3SIGNL_H_INCLUDED 1
+
+
+#line 10 "dk3signl.ctr"
+
+#include "dk3conf.h"
+#include "dk3types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Set new handler for the specified signal.
+ @param signo Signal number.
+ @param fct Handler function address.
+ @return The previous handler function address.
+*/
+dk3_signal_disp_t
+dk3signal_set(int signo, dk3_signal_disp_t fct);
+
+/** Refresh signal handler, if only signal() mechanism available.
+ Should be a signal handlers first action.
+ @param signo Signal number.
+ @param fct Handler function address.
+*/
+void
+dk3signal_refresh(int signo, dk3_signal_disp_t fct);
+
+/** Find best available signal handling mechanism.
+ @return DK3_SIGNAL_HANDLING_TYPE_xxx.
+*/
+int
+dk3signal_available(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3srch.c b/support/dktools/dk3srch.c
new file mode 100644
index 0000000000..31b2c9ff48
--- /dev/null
+++ b/support/dktools/dk3srch.c
@@ -0,0 +1,237 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3srch.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3srch.c The dk3srch module.
+*/
+
+
+#line 61 "dk3srch.ctr"
+
+#include "dk3all.h"
+
+
+
+
+
+
+#line 67 "dk3srch.ctr"
+
+
+
+/** One result node.
+*/
+typedef struct _dk3_search_node_t_ {
+ unsigned long n; /**< Node number. */
+ dkChar const *fn; /**< File name. */
+} dk3_search_node_t;
+
+
+
+/** Compare two line nodes.
+ @param l Left node.
+ @param r Right node.
+ @param cr Comparison criteria.
+ @return Comparison result.
+*/
+static
+int
+node_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3_search_node_t const *pl; /* Left node. */
+ dk3_search_node_t const *pr; /* Right node. */
+ if(l) {
+ if(r) {
+ pl = (dk3_search_node_t const *)l;
+ pr = (dk3_search_node_t const *)r;
+ if(pl->n > pr->n) { back = 1; }
+ else { if(pl->n < pr->n) { back = -1; } }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ if(cr) { back = 0 - back; }
+ return back;
+}
+
+
+
+/** Delete one node, release memory.
+ @param n Node to delete.
+*/
+static
+void
+dk3search_node_delete(dk3_search_node_t *n)
+{
+ if(n) {
+ dk3_release(n->fn);
+ n->n = 0UL;
+ dk3_delete(n);
+ }
+}
+
+
+
+/** Create new node, allocate memory.
+ @param n Node number.
+ @param fn File name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new node on success, NULL on error.
+*/
+static
+dk3_search_node_t *
+dk3search_node_new_app(unsigned long n, dkChar const *fn, dk3_app_t *app)
+{
+ dk3_search_node_t *back = NULL;
+
+
+#line 136 "dk3srch.ctr"
+ back = dk3_new_app(dk3_search_node_t,1,app);
+ if(back) {
+ back->n = n;
+ back->fn = dk3str_dup_app(fn, app);
+ if(!(back->fn)) {
+
+#line 141 "dk3srch.ctr"
+ dk3search_node_delete(back); back = NULL;
+ }
+ }
+
+#line 144 "dk3srch.ctr"
+ return back;
+}
+
+
+
+void
+dk3search_close(dk3_search_t *sp)
+{
+ dk3_search_node_t *n = NULL;
+ if(sp) {
+ if(sp->s_fn) {
+ if(sp->i_fn) {
+ dk3sto_it_reset(sp->i_fn);
+ while((n = (dk3_search_node_t *)dk3sto_it_next(sp->i_fn)) != NULL) {
+ dk3search_node_delete(n);
+ }
+ dk3sto_it_close(sp->i_fn);
+ }
+ dk3sto_close(sp->s_fn);
+ } sp->s_fn = NULL; sp->i_fn = NULL;
+ sp->app = NULL;
+ dk3_delete(sp);
+ }
+}
+
+
+
+dk3_search_t *
+dk3search_open_app(int i, dk3_app_t *app)
+{
+ dk3_search_t *back = NULL;
+ back = dk3_new_app(dk3_search_t,1,app);
+ if(back) {
+ back->s_fn = NULL; back->i_fn = NULL; back->inverted = (i ? 1 : 0);
+ back->nf = 0UL; back->app = app;
+ back->s_fn = dk3sto_open_app(app);
+ if(back->s_fn) {
+ back->i_fn = dk3sto_it_open(back->s_fn);
+ dk3sto_set_comp(back->s_fn, node_compare, 0);
+ }
+ if(!((back->s_fn) && (back->i_fn))) {
+ dk3search_close(back); back = NULL;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3search_add(dk3_search_t *sp, dkChar const *fn)
+{
+ int back = 0;
+ dk3_search_node_t *n = NULL; /* New node. */
+
+
+#line 199 "dk3srch.ctr"
+ if((sp) && (fn)) {
+ n = dk3search_node_new_app(sp->nf, fn, sp->app);
+ if(n) {
+ if(dk3sto_add(sp->s_fn, n)) {
+ back = 1;
+ sp->nf += 1UL;
+ } else {
+ dk3search_node_delete(n);
+ }
+ }
+ }
+
+#line 210 "dk3srch.ctr"
+ return back;
+}
+
+
+
+void
+dk3search_reset(dk3_search_t *sp)
+{
+ if(sp) {
+ dk3sto_it_reset(sp->i_fn);
+ }
+}
+
+
+
+dkChar const *
+dk3search_next(dk3_search_t *sp)
+{
+ dkChar const *back = NULL;
+ dk3_search_node_t *node = NULL; /* Next node. */
+ if(sp) {
+ node = (dk3_search_node_t *)dk3sto_it_next(sp->i_fn);
+ if(node) {
+ back = node->fn;
+ }
+ }
+
+#line 236 "dk3srch.ctr"
+ return back;
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dk3srch.ctr b/support/dktools/dk3srch.ctr
new file mode 100644
index 0000000000..f80a2c5700
--- /dev/null
+++ b/support/dktools/dk3srch.ctr
@@ -0,0 +1,242 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% header
+
+#include "dk3conf.h"
+#include "dk3types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open search structure, allocate memory.
+ @param i Flag: Inverse sort order.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new structure on success, NULL on error.
+*/
+dk3_search_t *
+dk3search_open_app(int i, dk3_app_t *app);
+
+/** Close search structure, release memory.
+ @param sp Search structure to close.
+*/
+void
+dk3search_close(dk3_search_t *sp);
+
+/** Add one result to result set.
+ @param sp Search structure.
+ @param fn File name to add.
+ @return 1 on success, 0 on error (not enough memory).
+*/
+int
+dk3search_add(dk3_search_t *sp, dkChar const *fn);
+
+/** Reset result traversal to traverse results again.
+ @param sp Search structure.
+*/
+void
+dk3search_reset(dk3_search_t *sp);
+
+/** Get next result entry.
+ @param sp Search structure.
+ @return Pointer to next file name or NULL.
+*/
+dkChar const *
+dk3search_next(dk3_search_t *sp);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk3all.h"
+
+
+
+$(trace-include)
+
+
+
+/** One result node.
+*/
+typedef struct _dk3_search_node_t_ {
+ unsigned long n; /**< Node number. */
+ dkChar const *fn; /**< File name. */
+} dk3_search_node_t;
+
+
+
+/** Compare two line nodes.
+ @param l Left node.
+ @param r Right node.
+ @param cr Comparison criteria.
+ @return Comparison result.
+*/
+static
+int
+node_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3_search_node_t const *pl; /* Left node. */
+ dk3_search_node_t const *pr; /* Right node. */
+ if(l) {
+ if(r) {
+ pl = (dk3_search_node_t const *)l;
+ pr = (dk3_search_node_t const *)r;
+ if(pl->n > pr->n) { back = 1; }
+ else { if(pl->n < pr->n) { back = -1; } }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ if(cr) { back = 0 - back; }
+ return back;
+}
+
+
+
+/** Delete one node, release memory.
+ @param n Node to delete.
+*/
+static
+void
+dk3search_node_delete(dk3_search_node_t *n)
+{
+ if(n) {
+ dk3_release(n->fn);
+ n->n = 0UL;
+ dk3_delete(n);
+ }
+}
+
+
+
+/** Create new node, allocate memory.
+ @param n Node number.
+ @param fn File name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new node on success, NULL on error.
+*/
+static
+dk3_search_node_t *
+dk3search_node_new_app(unsigned long n, dkChar const *fn, dk3_app_t *app)
+{
+ dk3_search_node_t *back = NULL;
+ $? "+ dk3search_node_new_app \"%!ds\"", fn
+ back = dk3_new_app(dk3_search_node_t,1,app);
+ if(back) {
+ back->n = n;
+ back->fn = dk3str_dup_app(fn, app);
+ if(!(back->fn)) { $? "! failed to create string copy"
+ dk3search_node_delete(back); back = NULL;
+ }
+ } $? "- dk3search_node_new_app %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+void
+dk3search_close(dk3_search_t *sp)
+{
+ dk3_search_node_t *n = NULL;
+ if(sp) {
+ if(sp->s_fn) {
+ if(sp->i_fn) {
+ dk3sto_it_reset(sp->i_fn);
+ while((n = (dk3_search_node_t *)dk3sto_it_next(sp->i_fn)) != NULL) {
+ dk3search_node_delete(n);
+ }
+ dk3sto_it_close(sp->i_fn);
+ }
+ dk3sto_close(sp->s_fn);
+ } sp->s_fn = NULL; sp->i_fn = NULL;
+ sp->app = NULL;
+ dk3_delete(sp);
+ }
+}
+
+
+
+dk3_search_t *
+dk3search_open_app(int i, dk3_app_t *app)
+{
+ dk3_search_t *back = NULL;
+ back = dk3_new_app(dk3_search_t,1,app);
+ if(back) {
+ back->s_fn = NULL; back->i_fn = NULL; back->inverted = (i ? 1 : 0);
+ back->nf = 0UL; back->app = app;
+ back->s_fn = dk3sto_open_app(app);
+ if(back->s_fn) {
+ back->i_fn = dk3sto_it_open(back->s_fn);
+ dk3sto_set_comp(back->s_fn, node_compare, 0);
+ }
+ if(!((back->s_fn) && (back->i_fn))) {
+ dk3search_close(back); back = NULL;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3search_add(dk3_search_t *sp, dkChar const *fn)
+{
+ int back = 0;
+ dk3_search_node_t *n = NULL; /* New node. */
+ $? "+ dk3search_add \"%!ds\"", TR_STR(fn)
+ if((sp) && (fn)) {
+ n = dk3search_node_new_app(sp->nf, fn, sp->app);
+ if(n) {
+ if(dk3sto_add(sp->s_fn, n)) {
+ back = 1;
+ sp->nf += 1UL;
+ } else {
+ dk3search_node_delete(n);
+ }
+ }
+ } $? "- dk3search_add %d", back
+ return back;
+}
+
+
+
+void
+dk3search_reset(dk3_search_t *sp)
+{
+ if(sp) {
+ dk3sto_it_reset(sp->i_fn);
+ }
+}
+
+
+
+dkChar const *
+dk3search_next(dk3_search_t *sp)
+{
+ dkChar const *back = NULL;
+ dk3_search_node_t *node = NULL; /* Next node. */
+ if(sp) {
+ node = (dk3_search_node_t *)dk3sto_it_next(sp->i_fn);
+ if(node) {
+ back = node->fn;
+ }
+ } $? "= dk3search_next \"%!ds\"", TR_STR(back)
+ return back;
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dk3srch.h b/support/dktools/dk3srch.h
new file mode 100644
index 0000000000..d800c3aa48
--- /dev/null
+++ b/support/dktools/dk3srch.h
@@ -0,0 +1,96 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3srch.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3srch.h Header file for the dk3srch module.
+*/
+
+#ifndef DK3SRCH_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3SRCH_H_INCLUDED 1
+
+
+#line 10 "dk3srch.ctr"
+
+#include "dk3conf.h"
+#include "dk3types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open search structure, allocate memory.
+ @param i Flag: Inverse sort order.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new structure on success, NULL on error.
+*/
+dk3_search_t *
+dk3search_open_app(int i, dk3_app_t *app);
+
+/** Close search structure, release memory.
+ @param sp Search structure to close.
+*/
+void
+dk3search_close(dk3_search_t *sp);
+
+/** Add one result to result set.
+ @param sp Search structure.
+ @param fn File name to add.
+ @return 1 on success, 0 on error (not enough memory).
+*/
+int
+dk3search_add(dk3_search_t *sp, dkChar const *fn);
+
+/** Reset result traversal to traverse results again.
+ @param sp Search structure.
+*/
+void
+dk3search_reset(dk3_search_t *sp);
+
+/** Get next result entry.
+ @param sp Search structure.
+ @return Pointer to next file name or NULL.
+*/
+dkChar const *
+dk3search_next(dk3_search_t *sp);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3stm.h b/support/dktools/dk3stm.h
new file mode 100644
index 0000000000..0974e1114f
--- /dev/null
+++ b/support/dktools/dk3stm.h
@@ -0,0 +1,24 @@
+
+#ifndef DK3STM_H_INCLUDED
+/** Protection against multiple inclusions. */
+#define DK3STM_H_INCLUDED 1
+
+/** Results when adding input to a state machine
+*/
+enum {
+ /** Input accepted, no result yet, continue.
+ */
+ DK3_STM_ACCEPT = 0,
+
+ /** Input accepted, result found.
+ */
+ DK3_STM_FINISHED ,
+
+ /** Can not accept input.
+ */
+ DK3_STM_ERROR
+};
+
+#endif
+/* ifndef DK3STM_H_INCLUDED */
+
diff --git a/support/dktools/dk3sto.c b/support/dktools/dk3sto.c
new file mode 100644
index 0000000000..0b2dec7a73
--- /dev/null
+++ b/support/dktools/dk3sto.c
@@ -0,0 +1,2238 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3sto.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3sto.c The dk3sto module.
+*/
+
+
+#line 255 "dk3sto.ctr"
+
+#include "dk3all.h"
+
+
+
+
+
+
+#line 261 "dk3sto.ctr"
+
+
+
+/** Comparison criteria: Do not compare the objects (unsorted storage).
+*/
+#define DK3STO_COMPARE_NONE 0
+
+/** Comparison criteria: Use comparison function.
+*/
+#define DK3STO_COMPARE_FCT 1
+
+/** Comparison criteria: Evaluate objects to char values.
+*/
+#define DK3STO_COMPARE_CHAR 2
+
+/** Comparison criteria: Evaluate objects to unsigned char values.
+*/
+#define DK3STO_COMPARE_UCHAR 3
+
+/** Comparison criteria: Evaluate objects to short values.
+*/
+#define DK3STO_COMPARE_SHORT 4
+
+/** Comparison criteria: Evaluate objects to unsigned short values.
+*/
+#define DK3STO_COMPARE_USHORT 5
+
+/** Comparison criteria: Evaluate objects to int values.
+*/
+#define DK3STO_COMPARE_INT 6
+
+/** Comparison criteria: Evaluate objects to unsigned int values.
+*/
+#define DK3STO_COMPARE_UINT 7
+
+/** Comparison criteria: Evaluate objects to long values.
+*/
+#define DK3STO_COMPARE_LONG 8
+
+/** Comparison criteria: Evaluate objects to unsigned long values.
+*/
+#define DK3STO_COMPARE_ULONG 9
+
+/** Comparison criteria: Evaluate objects to float values.
+*/
+#define DK3STO_COMPARE_FLOAT 10
+
+/** Comparison criteria: Evaluate objects to double values.
+*/
+#define DK3STO_COMPARE_DOUBLE 11
+
+
+
+/*
+ GENERAL STATIC FUNCTIONS
+*/
+
+/** Initialize storage node for object.
+ @param n Storage node.
+ @param o Object.
+ @param s Storage.
+ @param crit Comparison/evaluation criteria used by storage.
+*/
+static void
+dk3sto_node_init_for_object(dk3_sto_node_t *n, void *o, dk3_sto_t *s, int crit)
+{
+
+
+#line 328 "dk3sto.ctr"
+ n->p = n->l = n->r = NULL;
+ n->b = n->w = 0;
+ n->o = o;
+ switch(s->h) {
+ case DK3STO_COMPARE_CHAR: (n->v).c = (*((s->e).c))(o,crit); break;
+ case DK3STO_COMPARE_UCHAR: (n->v).uc = (*((s->e).uc))(o,crit); break;
+ case DK3STO_COMPARE_SHORT: (n->v).s = (*((s->e).s))(o,crit); break;
+ case DK3STO_COMPARE_USHORT: (n->v).us = (*((s->e).us))(o,crit); break;
+ case DK3STO_COMPARE_INT: (n->v).i = (*((s->e).i))(o,crit); break;
+ case DK3STO_COMPARE_UINT: (n->v).ui = (*((s->e).ui))(o,crit); break;
+ case DK3STO_COMPARE_LONG: (n->v).l = (*((s->e).l))(o,crit); break;
+ case DK3STO_COMPARE_ULONG: (n->v).ul = (*((s->e).ul))(o,crit); break;
+ case DK3STO_COMPARE_FLOAT: (n->v).f = (*((s->e).f))(o,crit); break;
+ case DK3STO_COMPARE_DOUBLE: (n->v).d = (*((s->e).d))(o,crit); break;
+ }
+
+#line 343 "dk3sto.ctr"
+}
+
+
+
+/** Copy data from one storage node to another.
+ @param d Destination node.
+ @param s Source node.
+ @param st Storage.
+*/
+static void
+dk3sto_node_data_copy(dk3_sto_node_t *d, dk3_sto_node_t *s, dk3_sto_t *st)
+{
+
+
+#line 356 "dk3sto.ctr"
+ d->o = s->o;
+ switch(st->h) {
+ case DK3STO_COMPARE_CHAR: (d->v).c = (s->v).c ; break;
+ case DK3STO_COMPARE_UCHAR: (d->v).uc = (s->v).uc ; break;
+ case DK3STO_COMPARE_SHORT: (d->v).s = (s->v).s ; break;
+ case DK3STO_COMPARE_USHORT: (d->v).us = (s->v).us ; break;
+ case DK3STO_COMPARE_INT: (d->v).i = (s->v).i ; break;
+ case DK3STO_COMPARE_UINT: (d->v).ui = (s->v).ui ; break;
+ case DK3STO_COMPARE_LONG: (d->v).l = (s->v).l ; break;
+ case DK3STO_COMPARE_ULONG: (d->v).ul = (s->v).ul ; break;
+ case DK3STO_COMPARE_FLOAT: (d->v).f = (s->v).f ; break;
+ case DK3STO_COMPARE_DOUBLE: (d->v).d = (s->v).d ; break;
+ }
+
+
+#line 370 "dk3sto.ctr"
+}
+
+
+
+/** Compare two storage nodes.
+ @param l Left node.
+ @param r Right node.
+ @param s Storage.
+ @param c Comparison criteria.
+ @return Comparison result.
+*/
+static int
+dk3sto_node_compare(dk3_sto_node_t *l, dk3_sto_node_t *r, dk3_sto_t *s, int c)
+{
+ int back = 0;
+
+
+#line 386 "dk3sto.ctr"
+ switch(s->h) {
+ case DK3STO_COMPARE_FCT: {
+
+#line 388 "dk3sto.ctr"
+ back = (*((s->e).comp))((void *)(l->o),(void *)(r->o),c);
+ if(back < 0) back = -1;
+ if(back > 0) back = 1;
+ } break;
+ case DK3STO_COMPARE_CHAR: {
+
+#line 393 "dk3sto.ctr"
+ if(((l->v).c) > ((r->v).c)) { back = 1; }
+ else { if(((l->v).c) < ((r->v).c)) { back = -1; } }
+ } break;
+ case DK3STO_COMPARE_UCHAR: {
+
+#line 397 "dk3sto.ctr"
+ if(((l->v).uc) > ((r->v).uc)) { back = 1; }
+ else { if(((l->v).uc) < ((r->v).uc)) { back = -1; } }
+ } break;
+ case DK3STO_COMPARE_SHORT: {
+
+#line 401 "dk3sto.ctr"
+ if(((l->v).s) > ((r->v).s)) { back = 1; }
+ else { if(((l->v).s) < ((r->v).s)) { back = -1; } }
+ } break;
+ case DK3STO_COMPARE_USHORT: {
+
+#line 405 "dk3sto.ctr"
+ if(((l->v).us) > ((r->v).us)) { back = 1; }
+ else { if(((l->v).us) < ((r->v).us)) { back = -1; } }
+ } break;
+ case DK3STO_COMPARE_INT: {
+
+#line 409 "dk3sto.ctr"
+ if(((l->v).i) > ((r->v).i)) { back = 1; }
+ else { if(((l->v).i) < ((r->v).i)) { back = -1; } }
+ } break;
+ case DK3STO_COMPARE_UINT: {
+
+#line 413 "dk3sto.ctr"
+ if(((l->v).ui) > ((r->v).ui)) { back = 1; }
+ else { if(((l->v).ui) < ((r->v).ui)) { back = -1; } }
+ } break;
+ case DK3STO_COMPARE_LONG: {
+
+#line 417 "dk3sto.ctr"
+ if(((l->v).l) > ((r->v).l)) { back = 1; }
+ else { if(((l->v).l) < ((r->v).l)) { back = -1; } }
+ } break;
+ case DK3STO_COMPARE_ULONG: {
+
+#line 421 "dk3sto.ctr"
+ if(((l->v).ul) > ((r->v).ul)) { back = 1; }
+ else { if(((l->v).ul) < ((r->v).ul)) { back = -1; } }
+ } break;
+ case DK3STO_COMPARE_FLOAT: {
+
+#line 425 "dk3sto.ctr"
+ if(((l->v).f) > ((r->v).f)) { back = 1; }
+ else { if(((l->v).f) < ((r->v).f)) { back = -1; } }
+ } break;
+ case DK3STO_COMPARE_DOUBLE: {
+
+#line 429 "dk3sto.ctr"
+ if(((l->v).d) > ((r->v).d)) { back = 1; }
+ else { if(((l->v).d) < ((r->v).d)) { back = -1; } }
+ } break;
+ }
+
+#line 433 "dk3sto.ctr"
+ return back;
+}
+
+
+
+/*
+ UNSORTED DATA HANDLING
+*/
+
+/** Remove node from an unsorted storage.
+ @param ro Root node.
+ @param n Node to remove.
+ @return New root node.
+*/
+static dk3_sto_node_t *
+dk3sto_unsorted_remove(dk3_sto_node_t *ro, dk3_sto_node_t *n)
+{
+ dk3_sto_node_t *back = NULL;
+ dk3_sto_node_t *l = NULL; /* Left element. */
+ dk3_sto_node_t *r = NULL; /* Right element. */
+
+
+#line 454 "dk3sto.ctr"
+ back = ro;
+ l = n->l; r = n->r;
+ if(r) {
+ r->l = l;
+ }
+ if(l) {
+ l->r = r;
+ } else {
+ back = r;
+ }
+
+#line 464 "dk3sto.ctr"
+ return back;
+}
+
+
+
+/** Add node to an unsorted storage.
+ @param r Old root node.
+ @param n Node to add.
+ @return New root node or NULL.
+*/
+static dk3_sto_node_t *
+dk3sto_unsorted_add(dk3_sto_node_t *r, dk3_sto_node_t *n)
+{
+ dk3_sto_node_t *back;
+
+
+#line 479 "dk3sto.ctr"
+ back = n;
+ n->r = r;
+ if(r) {
+ r->l = n;
+ }
+
+#line 484 "dk3sto.ctr"
+ return back;
+}
+
+
+
+/** Release all nodes in an unsorted storage.
+ @param r Root node.
+*/
+static void
+dk3sto_unsorted_release_all_nodes(dk3_sto_node_t *r)
+{
+ dk3_sto_node_t *c; /* Current element. */
+ dk3_sto_node_t *n; /* Next element. */
+
+
+#line 498 "dk3sto.ctr"
+ c = r;
+ while(c) {
+ n = c->r;
+ c->p = c->l = c->r = NULL;
+ c->o = NULL;
+ c->b = c->w = 0;
+ dk3_delete(c) ;
+ c = n;
+ }
+
+
+#line 508 "dk3sto.ctr"
+}
+
+
+
+/** Find next node in an unsorted storage.
+ @param n Current node.
+ @param r Root node.
+ @return Pointer to next node or NULL.
+*/
+static dk3_sto_node_t *
+dk3sto_unsorted_find_next_node(dk3_sto_node_t *n, dk3_sto_node_t *r)
+{
+ dk3_sto_node_t *back = NULL;
+
+
+#line 522 "dk3sto.ctr"
+ if(n) {
+ back = n->r;
+ } else {
+ back = r;
+ }
+
+#line 527 "dk3sto.ctr"
+ return back;
+}
+
+
+
+/** Find last node in an unsorted storage.
+ @param n Root node.
+ @return Last node or NULL.
+*/
+static dk3_sto_node_t *
+dk3sto_unsorted_find_last_node(dk3_sto_node_t *n)
+{
+ dk3_sto_node_t *back = NULL;
+
+
+#line 541 "dk3sto.ctr"
+ if(n) back = n->l;
+
+
+#line 543 "dk3sto.ctr"
+ return back;
+}
+
+
+
+/** Find node for an object in an unsorted storage.
+ @param r Root node.
+ @param o Object.
+ @return Node for object or NULL.
+*/
+static dk3_sto_node_t *
+dk3sto_unsorted_find_exact(dk3_sto_node_t *r, void const *o)
+{
+ dk3_sto_node_t *back = NULL;
+ dk3_sto_node_t *c; /* Current node. */
+
+
+#line 559 "dk3sto.ctr"
+ c = r;
+ while(c && (!back)) {
+ if((c->o) == o) {
+ back = c;
+ }
+ c = c->r;
+ }
+
+#line 566 "dk3sto.ctr"
+ return back;
+}
+
+
+
+/*
+ SORTED DATA HANDLING
+*/
+
+
+
+/** Go to direction: Left.
+*/
+#define DK3STO_WALK_LEFT 1
+
+/** Go to direction: Right.
+*/
+#define DK3STO_WALK_RIGHT 2
+
+
+
+/** Perform left rotation at node.
+ @param p Subpath to modify.
+ @return New subpath root node or NULL.
+*/
+static dk3_sto_node_t *
+dk3sto_left_rotation(dk3_sto_node_t *p)
+{
+ dk3_sto_node_t *p1;
+
+
+#line 596 "dk3sto.ctr"
+ p1 = p->r;
+ p->r = p1->l;
+ if(p->r) (p->r)->p = p;
+ p1->l = p;
+ if(p) p->p = p1;
+
+
+#line 602 "dk3sto.ctr"
+ return p1;
+}
+
+
+
+/** Perform right rotation at node.
+ @param p Subpath to modify.
+ @return New subpath root node or NULL.
+*/
+static dk3_sto_node_t *
+dk3sto_right_rotation(dk3_sto_node_t *p)
+{
+ dk3_sto_node_t *p1;
+
+
+#line 616 "dk3sto.ctr"
+ p1 = p->l;
+ p->l = p1->r;
+ if(p->l) (p->l)->p = p;
+ p1->r = p;
+ if(p) p->p = p1;
+
+
+#line 622 "dk3sto.ctr"
+ return p1;
+}
+
+
+
+/** Increment balance field of a storage node.
+ @param p Node to modify.
+*/
+static void
+dk3sto_inc_balance(dk3_sto_node_t *p)
+{
+ short x; /* New balance value. */
+
+
+#line 635 "dk3sto.ctr"
+ x = p->b;
+
+#line 636 "dk3sto.ctr"
+ x++;
+ if(x > 3) x = 0;
+ p->b = x;
+
+#line 639 "dk3sto.ctr"
+}
+
+
+
+/** Decrement balance field of a storage node.
+ @param p Storage node.
+*/
+static void
+dk3sto_dec_balance(dk3_sto_node_t *p)
+{
+ short x; /* New balance value. */
+
+
+#line 651 "dk3sto.ctr"
+ x = p->b;
+
+#line 652 "dk3sto.ctr"
+ x--;
+ if(x < 0) x = 3;
+ p->b = x;
+
+#line 655 "dk3sto.ctr"
+}
+
+
+
+
+/** Set mark for "left node deleted".
+ @param p Node.
+ @param h Pointer to balance variable.
+ @return New root node for path behind \a p.
+*/
+static dk3_sto_node_t *
+dk3sto_left_deleted(dk3_sto_node_t *p, short *h)
+{
+
+
+#line 669 "dk3sto.ctr"
+ switch(p->b) {
+ case 0: *h = - *h;
+ case 3:
+
+
+#line 673 "dk3sto.ctr"
+ dk3sto_inc_balance(p);
+
+
+#line 675 "dk3sto.ctr"
+ break;
+ case 1: {
+ switch((p->r)->b) {
+ case 0:
+ (p->r)->b = 3;
+ *h = - *h;
+ p = dk3sto_left_rotation(p);
+ break;
+ case 1:
+ (p->r)->b = 0;
+ p->b = 0;
+ p = dk3sto_left_rotation(p);
+ break;
+ case 3:
+ p->b = (((((p->r)->l)->b) == 1) ? 3 : 0);
+ (p->r)->b = (((((p->r)->l)->b) == 3) ? 1 : 0);
+ p->r = dk3sto_right_rotation(p->r);
+ if(p->r) (p->r)->p = p;
+ p = dk3sto_left_rotation(p);
+ p->b = 0;
+ }
+ }
+ }
+
+
+#line 699 "dk3sto.ctr"
+ return p;
+}
+
+
+
+/** Set mark for "right node deleted".
+ @param p Node.
+ @param h Pointer to balance variable.
+ @return New root node for path behind \a p.
+*/
+static dk3_sto_node_t *
+dk3sto_right_deleted(dk3_sto_node_t *p, short *h)
+{
+
+
+#line 713 "dk3sto.ctr"
+ switch(p->b) {
+ case 0: *h = - *h;
+ case 1: dk3sto_dec_balance(p);
+ break;
+ case 3: {
+ switch((p->l)->b) {
+ case 0:
+ (p->l)->b = 1;
+ *h = - *h;
+ p = dk3sto_right_rotation(p);
+ break;
+ case 3:
+ (p->l)->b = 0;
+ p->b = 0;
+ p = dk3sto_right_rotation(p);
+ break;
+ case 1:
+ p->b = (((((p->l)->r)->b) == 3) ? 1 : 0);
+ (p->l)->b = (((((p->l)->r)->b) == 1) ? 3 : 0);
+ p->l = dk3sto_left_rotation(p->l);
+ if(p->l) (p->l)->p = p;
+ p = dk3sto_right_rotation(p);
+ p->b = 0;
+ }
+ }
+ }
+
+
+#line 740 "dk3sto.ctr"
+ return p;
+}
+
+
+
+/** Add node to tree storage.
+ @param root Root node.
+ @param newnode Node to add.
+ @param st Storage.
+ @return New root node or NULL.
+*/
+static dk3_sto_node_t *
+dk3sto_avlt_add(dk3_sto_node_t *root, dk3_sto_node_t *newnode, dk3_sto_t *st)
+{
+ dk3_sto_node_t *back = NULL;
+ dk3_sto_node_t *p = NULL; /* Current node. */
+ dk3_sto_node_t *q = NULL; /* Father of p. */
+ dk3_sto_node_t *r = NULL; /* Critical node. */
+ dk3_sto_node_t *s = NULL; /* Father of r. */
+
+
+#line 760 "dk3sto.ctr"
+ back = root;
+ p = r = root; q = s = NULL;
+ /*
+ Search place for insertion, write direction into
+ the "w" field in each node.
+ The final new node has an empty "w" field.
+ */
+ while(p) {
+ if(p->b) {
+ s = q; r = p;
+ }
+ q = p;
+ if(dk3sto_node_compare(p,newnode,st,st->c) > 0) {
+ p->w = DK3STO_WALK_LEFT;
+ p = p->l;
+ } else {
+ p->w = DK3STO_WALK_RIGHT;
+ p = p->r;
+ }
+ }
+ p = newnode;
+ if(!back) {
+ /*
+ When inserting into an empty tree we are done here.
+ */
+ back = p;
+ } else {
+ /*
+ The tree is not empty.
+ The new node p is concatenated to the parent q.
+ */
+ if(dk3sto_node_compare(q,newnode,st,st->c) > 0) {
+ q->l = p;
+ q->w = DK3STO_WALK_LEFT;
+ } else {
+ q->r = p;
+ q->w = DK3STO_WALK_RIGHT;
+ }
+ /*
+ Now we must balance the tree again if necessary.
+ */
+ p->p = q;
+ if(r) {
+ /*
+ There is a critical node.
+ */
+ p = r;
+ /*
+ Modify balance fields from critial node
+ until we find our new node.
+ */
+ while(p->w) {
+ if(p->w == DK3STO_WALK_LEFT) {
+ dk3sto_dec_balance(p);
+ p = p->l;
+ } else {
+ dk3sto_inc_balance(p);
+ p = p->r;
+ }
+ }
+ p = r;
+ /*
+ Now look whether we are dis-balanced,
+ correct if necessary.
+ */
+ if((p->b) == 2) {
+ /* We must balance */
+ if(p->w == DK3STO_WALK_LEFT) {
+ if((p->l)->b == 3) {
+ p->b = 0;
+ p = dk3sto_right_rotation(p);
+ } else {
+ p->b = (((((p->l)->r)->b) == 3) ? 1 : 0);
+ (p->l)->b = (((((p->l)->r)->b) == 1) ? 3 : 0);
+ p->l = dk3sto_left_rotation(p->l);
+ if(p->l) (p->l)->p = p;
+ p = dk3sto_right_rotation(p);
+ }
+ } else {
+ if((p->r)->b == 1) {
+ p->b = 0;
+ p = dk3sto_left_rotation(p);
+ } else {
+ p->b = (((((p->r)->l)->b) == 1) ? 3 : 0);
+ (p->r)->b = (((((p->r)->l)->b) == 3) ? 1 : 0);
+ p->r = dk3sto_right_rotation(p->r);
+ if(p->r) (p->r)->p = p;
+ p = dk3sto_left_rotation(p);
+ }
+ }
+ p->b = 0;
+ /*
+ Balance at the critical nodes father (if
+ there is one) or create new root.
+ */
+ if(s) {
+ if(s->w == DK3STO_WALK_LEFT) {
+ s->l = p;
+ } else {
+ s->r = p;
+ }
+ if(p) p->p = s;
+ } else {
+ back = p;
+ }
+ }
+ }
+ }
+ if(back) {
+ back->p = NULL;
+ }
+
+
+#line 872 "dk3sto.ctr"
+ return back;
+}
+
+
+
+/** Remove storage node from tree storage.
+ @param root Root object.
+ @param node Node to remove.
+ @param delpath Deletion path (used for tree balancing).
+ @param st Storage.
+ @param success_indicator Pointer to success variable.
+ @param toremove Node to remove.
+ @return New root object.
+*/
+static dk3_sto_node_t *
+dk3sto_avlt_delete(
+ dk3_sto_node_t *root, dk3_sto_node_t *node, dk3_sto_node_t **delpath,
+ dk3_sto_t *st, int *success_indicator, dk3_sto_node_t **toremove
+)
+{
+ dk3_sto_node_t *back = NULL;
+ dk3_sto_node_t *p = NULL; /* Current node. */
+ dk3_sto_node_t *q = NULL; /* Father of p. */
+ dk3_sto_node_t *r = NULL; /* Critical node. */
+ dk3_sto_node_t *todel = NULL; /* Node to delete. */
+ short x1 = 0; /* Balance value. */
+ short delroot = 0; /* Flag: Delete tree node. */
+ int can_continue = 1; /* Flag: Can continue. */
+ back = root;
+ todel = node;
+
+
+#line 903 "dk3sto.ctr"
+ /*
+ Make sure the node to delete has max.
+ 1 subtree.
+ */
+ if((todel->l) && (todel->r)) {
+
+
+#line 909 "dk3sto.ctr"
+ todel = todel->l;
+ while(todel->r) todel = todel->r;
+ dk3sto_node_data_copy(node,todel,st);
+ }
+ if(!(todel->p)) {
+
+#line 914 "dk3sto.ctr"
+ delroot = 1;
+ }
+ /*
+ Mark the way in the "w" fields.
+ */
+ *toremove = todel;
+ todel->w = 0;
+ while(todel->p) {
+ if((todel->p)->l == todel) {
+
+
+#line 924 "dk3sto.ctr"
+ (todel->p)->w = DK3STO_WALK_LEFT;
+ } else {
+
+
+#line 927 "dk3sto.ctr"
+ (todel->p)->w = DK3STO_WALK_RIGHT;
+ }
+ todel = todel->p;
+ }
+ p = back;
+ q = r = NULL;
+ x1 = 0;
+ can_continue = 1;
+ while(can_continue) {
+
+
+#line 937 "dk3sto.ctr"
+#if VERSION_BEFORE_20151002
+ if(p) {
+
+#line 939 "dk3sto.ctr"
+#endif
+ if(p->w) {
+
+#line 941 "dk3sto.ctr"
+ if(p->b == 0) {
+ x1 = 0;
+
+#line 943 "dk3sto.ctr"
+ }
+ delpath[x1++] = p;
+
+#line 945 "dk3sto.ctr"
+ if(x1 >= st->l) {
+
+#line 946 "dk3sto.ctr"
+ /* x1 too large */
+ *success_indicator = 0;
+ goto error_mark;
+ }
+ if(p->w == DK3STO_WALK_LEFT) {
+
+#line 951 "dk3sto.ctr"
+ p = p->l;
+ } else {
+
+#line 953 "dk3sto.ctr"
+ p = p->r;
+ }
+ } else {
+ can_continue = 0;
+
+#line 957 "dk3sto.ctr"
+ }
+#if VERSION_BEFORE_20151002
+ } else {
+ can_continue = 0;
+
+#line 961 "dk3sto.ctr"
+ }
+#endif
+ }
+#if VERSION_BEFORE_20151002
+ r = p;
+#endif
+ /* Static code analysis: Dereference potential NULL pointer p */
+ /* I think p can not be NULL. */
+ if(p->l) q = p->l;
+ else q = p->r;
+ if(x1 == 0) {
+ if(delroot) {
+
+#line 973 "dk3sto.ctr"
+ back = q;
+ }
+ }
+ while(x1 > 0) {
+
+#line 977 "dk3sto.ctr"
+ x1--;
+ p = delpath[x1];
+ if(p->w == DK3STO_WALK_LEFT) {
+
+
+#line 981 "dk3sto.ctr"
+ p->l = q; if(q) q->p = p;
+ q = dk3sto_left_deleted(p, &x1);
+
+
+#line 984 "dk3sto.ctr"
+ } else {
+
+
+#line 986 "dk3sto.ctr"
+ p->r = q; if(q) q->p = p;
+ q = dk3sto_right_deleted(p, &x1);
+
+
+#line 989 "dk3sto.ctr"
+ }
+ if(x1 == 0) {
+
+
+#line 992 "dk3sto.ctr"
+ if(delpath[x1] == back) {
+
+
+#line 994 "dk3sto.ctr"
+ back = q;
+ }
+ }
+ if(x1 < 0) {
+
+#line 998 "dk3sto.ctr"
+ p = delpath[0 - x1 - 1];
+ if(p->w == DK3STO_WALK_LEFT) {
+ p->l = q;
+ } else {
+ p->r = q;
+ }
+ if(q) q->p = p;
+ }
+ }
+error_mark:
+ if(back) {
+ back->p = NULL;
+ }
+
+
+#line 1012 "dk3sto.ctr"
+ return back;
+}
+
+
+
+/** Find storage node for an object evaluated like a given object.
+ @param root Root node.
+ @param testnode Node of the given object.
+ @param st Storage.
+ @param crit Comparison criteria.
+ @param cand Pointer for candidate.
+ @return Pointer to storage node or NULL.
+*/
+static dk3_sto_node_t *
+dk3sto_tree_find_like(
+ dk3_sto_node_t *root, dk3_sto_node_t *testnode, dk3_sto_t *st, int crit,
+ dk3_sto_node_t **cand
+)
+{
+ dk3_sto_node_t *back = NULL;
+ dk3_sto_node_t *c = NULL; /* Current node. */
+ int testval = 0; /* Comparison result. */
+
+
+#line 1035 "dk3sto.ctr"
+ c = root;
+ while(c) {
+ testval = dk3sto_node_compare(c,testnode,st,crit);
+ switch(testval) {
+ case -1: {
+ if(cand) *cand = c;
+ c = c->r;
+ } break;
+ case 0: {
+ back = c; c = c->l;
+ } break;
+ default: {
+ c = c->l;
+ } break;
+ }
+ }
+
+#line 1051 "dk3sto.ctr"
+ return back;
+}
+
+
+
+/** Add node to a tree.
+ @param r Root node.
+ @param n New node to add.
+ @param s Storage.
+ @return Node pointer on success, NULL on error.
+*/
+static dk3_sto_node_t *
+dk3sto_tree_add(dk3_sto_node_t *r, dk3_sto_node_t *n, dk3_sto_t *s)
+{
+ dk3_sto_node_t *back;
+ back = dk3sto_avlt_add(r,n,s);
+ return back;
+}
+
+
+
+/** Release all nodes in a tree storage.
+ @param r Root node.
+*/
+static void
+dk3sto_tree_release_all_nodes(dk3_sto_node_t *r)
+{
+
+
+#line 1079 "dk3sto.ctr"
+ if(r) {
+ dk3sto_tree_release_all_nodes(r->l);
+ dk3sto_tree_release_all_nodes(r->r);
+ r->l = r->r = r->p = NULL;
+ r->o = NULL;
+ r->b = 0; r->w = 0;
+ dk3_delete(r) ;
+ }
+
+#line 1087 "dk3sto.ctr"
+}
+
+
+
+/** Find next node in a tree storage.
+ @param n Current node.
+ @param r Root node.
+ @return Pointer to next node or NULL.
+*/
+static dk3_sto_node_t *
+dk3sto_tree_find_next_node(dk3_sto_node_t *n, dk3_sto_node_t *r)
+{
+ dk3_sto_node_t *back = NULL;
+ dk3_sto_node_t *c = NULL; /* Current node. */
+ dk3_sto_node_t *p = NULL; /* Parent of c. */
+
+
+#line 1103 "dk3sto.ctr"
+ /*
+ if(n) {
+ if(n->r) {
+ back = n->r;
+ while(back->l) { back = back->l; }
+ } else {
+ c = n; p = c->p;
+ while(p && (!back)) {
+ if((p->l) == c) {
+ back = p;
+ } else {
+ c = p; p = c->p;
+ }
+ }
+ }
+ } else {
+ back = r;
+ if(back) { while(back->l) { back = back->l; } }
+ }
+ */
+ if(n) {
+ if(n->r) {
+ back = n->r;
+ while(back->l) back = back->l;
+ } else {
+ c = n; p = c->p;
+ while(p && (!back)) {
+ if(p->l == c) {
+ back = p;
+ } else {
+ c = p; p = c->p;
+ }
+ }
+ }
+ } else {
+ back = r;
+ if(back) {
+ while(back->l) back = back->l;
+ }
+ }
+
+
+#line 1144 "dk3sto.ctr"
+ return back;
+}
+
+
+
+/** Find last node in a tree storage.
+ @param n Node to start search from.
+ @return Last node or NULL.
+*/
+static dk3_sto_node_t *
+dk3sto_tree_find_last_node(dk3_sto_node_t *n)
+{
+ dk3_sto_node_t *back = NULL;
+ dk3_sto_node_t *c; /* Current node. */
+ dk3_sto_node_t *p; /* Father of c. */
+
+
+#line 1160 "dk3sto.ctr"
+ if(n->l) {
+ back = n->l;
+ while(back->r) { back = back->r; }
+ } else {
+ c = n; p = c->p;
+ while(p && (!back)) {
+ if((p->r) == c) {
+ back = p;
+ } else {
+ c = p; p = c->p;
+ }
+ }
+ }
+
+#line 1173 "dk3sto.ctr"
+ return back;
+}
+
+
+
+/** Find node for object in tree storage (exact search).
+ @param r Root node.
+ @param o Object to find node for.
+ @param s Storage.
+ @return Pointer to node or NULL.
+*/
+static dk3_sto_node_t *
+dk3sto_tree_find_exact(dk3_sto_node_t *r, void const *o, dk3_sto_t *s)
+{
+ dk3_sto_node_t *back = NULL;
+ dk3_sto_node_t testnode; /* Test node for comparisons. */
+ dk3_sto_node_t *c; /* Current node to test. */
+ dk3_sto_node_t *candidate; /* Candidate for found node. */
+ int testval = 0; /* Comparison result. */
+
+
+#line 1193 "dk3sto.ctr"
+ dk3sto_node_init_for_object(&testnode, (void *)o, s, s->c);
+ c = dk3sto_tree_find_like(r, &testnode, s, s->c, &candidate);
+ while(c && (!back)) {
+ testval = dk3sto_node_compare(c, &testnode, s, s->c);
+ if(testval == 0) {
+ if((c->o) == o) {
+ back = c;
+ } else {
+ c = dk3sto_tree_find_next_node(c, r);
+ }
+ } else {
+ c = NULL;
+ }
+ }
+
+#line 1207 "dk3sto.ctr"
+ return back;
+}
+
+
+
+/** Remove storage node from tree storage.
+ @param ro Root node.
+ @param n Node to delete.
+ @param st Storage.
+ @param sci ???
+ @param toremove Node to remove.
+ @return New root node.
+*/
+static dk3_sto_node_t *
+dk3sto_tree_remove(
+ dk3_sto_node_t *ro, dk3_sto_node_t *n, dk3_sto_t *st, int *sci,
+ dk3_sto_node_t **toremove
+)
+{
+ dk3_sto_node_t *back;
+ back = dk3sto_avlt_delete(ro,n,st->d,st,sci,toremove);
+ return back;
+}
+
+
+
+/*
+ USE DOUBLE LINKED LIST
+*/
+
+/** Find node for an object evaluated like a given object in a list storage.
+ @param root Root node.
+ @param testnode Node with object for comparison.
+ @param st Storage.
+ @param crit Comparison criteria.
+ @param cand Test candidate.
+ @return Pointer to storage node or NULL.
+*/
+static dk3_sto_node_t *
+dk3sto_list_find_like(
+ dk3_sto_node_t *root, dk3_sto_node_t *testnode, dk3_sto_t *st, int crit,
+ dk3_sto_node_t **cand
+)
+{
+ dk3_sto_node_t *back = NULL;
+ dk3_sto_node_t *c = NULL; /* Current node. */
+ int testval = 0; /* Comparison result. */
+
+
+#line 1255 "dk3sto.ctr"
+ c = root;
+ while(c && (!back)) {
+ testval = dk3sto_node_compare(c,testnode,st,crit);
+ switch(testval) {
+ case -1: {
+ if(cand) *cand = c;
+ c = c->r;
+ } break;
+ case 0: {
+ back = c; c = NULL;
+ } break;
+ default : {
+ c = NULL;
+ } break;
+ }
+ }
+
+#line 1271 "dk3sto.ctr"
+ return back;
+}
+
+
+
+/** Find node for an object (exact search).
+ @param r Root node.
+ @param o Object.
+ @param s Storage.
+ @return Pointer to the objects node or NULL.
+*/
+static dk3_sto_node_t *
+dk3sto_list_find_exact(dk3_sto_node_t *r, void const *o, dk3_sto_t *s)
+{
+ dk3_sto_node_t *back;
+
+
+#line 1287 "dk3sto.ctr"
+ back = dk3sto_unsorted_find_exact(r,o);
+
+
+#line 1289 "dk3sto.ctr"
+ return back;
+}
+
+
+
+/** Add node to list storage.
+ @param r Root node.
+ @param n New node.
+ @param s Storage.
+ @return Pointer on success, NULL on error.
+*/
+static dk3_sto_node_t *
+dk3sto_list_add(dk3_sto_node_t *r, dk3_sto_node_t *n, dk3_sto_t *s)
+{
+ dk3_sto_node_t *back;
+ dk3_sto_node_t *larger = NULL; /* Last found larger entry. */
+ dk3_sto_node_t *current = NULL; /* Current node. */
+ dk3_sto_node_t *smaller = NULL; /* Last found smaller entry. */
+ int ende;
+
+
+#line 1309 "dk3sto.ctr"
+ back = r;
+ if(r) {
+ larger = smaller = NULL;
+ current = r;
+ ende = 0;
+ while(!ende) {
+ if(dk3sto_node_compare(current,n,s,s->c) >= 0) {
+ larger = current; ende = 1;
+ } else {
+ smaller = current;
+ }
+ if(current->r) {
+ current = current->r;
+ } else {
+ ende = 1;
+ }
+ }
+ if(larger) {
+ n->r = larger;
+ larger->l = n;
+ if(smaller) {
+ smaller->r = n;
+ n->l = smaller;
+ } else {
+ back = n;
+ }
+ } else {
+ if(smaller) {
+ smaller->r = n;
+ n->l = smaller;
+ }
+ }
+ } else {
+ back = n;
+ }
+
+#line 1344 "dk3sto.ctr"
+ return back;
+}
+
+
+
+/** Release all nodes of a list storage.
+ @param r Root node.
+*/
+static void
+dk3sto_list_release_all_nodes(dk3_sto_node_t *r)
+{
+
+
+#line 1356 "dk3sto.ctr"
+ dk3sto_unsorted_release_all_nodes(r);
+
+
+#line 1358 "dk3sto.ctr"
+}
+
+
+
+/** Find next node.
+ @param n Current node.
+ @param r Root node.
+ @return Pointer to next node or NULL.
+*/
+static dk3_sto_node_t *
+dk3sto_list_find_next_node(dk3_sto_node_t *n, dk3_sto_node_t *r)
+{
+ dk3_sto_node_t *back;
+
+
+#line 1372 "dk3sto.ctr"
+ back = dk3sto_unsorted_find_next_node(n,r);
+
+
+#line 1374 "dk3sto.ctr"
+ return back;
+}
+
+
+
+/** Find last (previous) node.
+ @param n Current node.
+ @return Pointer to previous node or NULL.
+*/
+static dk3_sto_node_t *
+dk3sto_list_find_last_node(dk3_sto_node_t *n)
+{
+ dk3_sto_node_t *back;
+
+
+#line 1388 "dk3sto.ctr"
+ back = dk3sto_unsorted_find_last_node(n);
+
+
+#line 1390 "dk3sto.ctr"
+ return back;
+}
+
+
+
+/** Remove storage node from list storage.
+ @param ro Root node.
+ @param n Node to remove.
+ @param st Storage.
+ @param sci ???
+ @param toremove ???
+*/
+static dk3_sto_node_t *
+dk3sto_list_remove(
+ dk3_sto_node_t *ro, dk3_sto_node_t *n, dk3_sto_t *st, int *sci,
+ dk3_sto_node_t **toremove
+)
+{
+ dk3_sto_node_t *back;
+
+
+#line 1410 "dk3sto.ctr"
+ back = dk3sto_unsorted_remove(ro,n);
+
+
+#line 1412 "dk3sto.ctr"
+ return back;
+}
+
+
+/*
+ COMMON STATIC FUNCTIONS
+*/
+
+
+/** Get object node (traverse storage).
+ @param it Storage iterator.
+ @param o Object to find storage node.
+ @return Pointer to node or NULL.
+*/
+static dk3_sto_node_t *
+dk3sto_traverse_iterators_for(void *it, void *o)
+{
+ dk3_sto_node_t *back = NULL;
+ dk3_sto_it_t *c = NULL; /* Current node. */
+
+
+#line 1432 "dk3sto.ctr"
+ if(it) {
+ c = (dk3_sto_it_t *)it;
+ while(c && (!back)) {
+ if(c->c) {
+ if(((c->c)->o) == o) {
+ back = c->c;
+ }
+ }
+ if(!back) c = c->r;
+ }
+ }
+
+#line 1443 "dk3sto.ctr"
+ return back;
+}
+
+
+
+/** Find last storage node.
+ @param n Current storage node.
+ @param st Storage.
+ @return Pointer to last node or NULL.
+*/
+static dk3_sto_node_t *
+dk3sto_find_last_node(dk3_sto_node_t *n, dk3_sto_t *st)
+{
+ dk3_sto_node_t *back = NULL;
+
+
+#line 1458 "dk3sto.ctr"
+ if(st->h) {
+ if(st->t) {
+ back = dk3sto_tree_find_last_node(n);
+ } else {
+ back = dk3sto_list_find_last_node(n);
+ }
+ } else {
+ back = dk3sto_unsorted_find_last_node(n);
+ }
+
+
+#line 1468 "dk3sto.ctr"
+ return back;
+}
+
+
+
+/** Initialize storage.
+ @param st Storage to initialize.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static int
+dk3sto_storage_init(dk3_sto_t *st, dk3_app_t *app)
+{
+ int back = 0;
+ short l = 0; /* Critical path length. */
+
+
+#line 1484 "dk3sto.ctr"
+ /* delpath begin address and length */
+ st->d = NULL; st->l = 0;
+ /* root node */
+ st->r = NULL;
+ /* comparison method */
+ st->h = 0;
+ /* comparison criteria */
+ st->c = 0;
+ /* iterators list */
+ st->i = NULL;
+ st->l = l = 1536;
+ st->app = app;
+ st->d = dk3_new_app(dk3_sto_node_p,l,app);
+ st->t = 1;
+ if(st->d) {
+ back = 1;
+ }
+
+#line 1501 "dk3sto.ctr"
+ return back;
+}
+
+
+
+/** Close the storage, release memory.
+ @param st Storage to close.
+*/
+static void
+dk3sto_storage_end(dk3_sto_t *st)
+{
+
+
+#line 1513 "dk3sto.ctr"
+ /* release iterators */
+ {
+ dk3_sto_it_t *c = NULL; /* Current iterator. */
+ dk3_sto_it_t *n = NULL; /* Next iterator. */
+ c = (dk3_sto_it_t *)(st->i);
+ st->i = NULL;
+ while(c) {
+
+
+#line 1521 "dk3sto.ctr"
+ n = c->r;
+ c->r = NULL;
+ c->l = NULL;
+ c->c = NULL;
+ c->s = NULL;
+ dk3_delete(c) ;
+ c = n;
+ }
+ st->i = NULL;
+ }
+
+
+#line 1532 "dk3sto.ctr"
+ /* release nodes */
+ {
+ if(st->h) {
+ if(st->t) {
+ dk3sto_tree_release_all_nodes(st->r);
+ } else {
+ dk3sto_list_release_all_nodes(st->r);
+ }
+ } else {
+ dk3sto_unsorted_release_all_nodes(st->r);
+ }
+ st->r = NULL;
+ }
+
+
+#line 1546 "dk3sto.ctr"
+ /* release delpath */
+ {
+ dk3_sto_node_p *p;
+ p = st->d;
+ dk3_delete(p);
+ st->d = NULL; st->l = 0;
+ }
+
+
+#line 1554 "dk3sto.ctr"
+ /* set pointers to NULL */
+ {
+ st->h = 0;
+ st->c = 0;
+ }
+
+
+#line 1560 "dk3sto.ctr"
+
+
+#line 1561 "dk3sto.ctr"
+}
+
+
+
+/*
+ PUBLIC INTERFACES
+*/
+
+
+dk3_sto_t *
+dk3sto_open_app(dk3_app_t *app)
+{
+ dk3_sto_t *back = NULL;
+
+
+#line 1575 "dk3sto.ctr"
+ back = dk3_new_app(dk3_sto_t,1,app) ;
+ if(back) {
+ if(!dk3sto_storage_init(back,app)) {
+ dk3_delete(back);
+ back = NULL;
+ }
+ }
+
+#line 1582 "dk3sto.ctr"
+ return back;
+}
+
+
+
+void
+dk3sto_close(dk3_sto_t *st)
+{
+
+
+#line 1591 "dk3sto.ctr"
+ if(st) {
+ dk3sto_storage_end(st);
+ dk3_delete(st) ;
+ }
+
+#line 1595 "dk3sto.ctr"
+}
+
+
+
+void
+dk3sto_remove_all(dk3_sto_t *st)
+{
+ if(st) {
+ /* reset all iterators */
+ dk3_sto_it_t *c = NULL; /* Curent iterator. */
+ dk3_sto_it_t *n = NULL; /* Next iterator. */
+ c = (dk3_sto_it_t *)(st->i);
+ while(c) {
+ n = c->r;
+ c->c = NULL;
+ c = n;
+ }
+ /* remove all nodes */
+ if(st->r) {
+ if(st->h) {
+ if(st->t) {
+ dk3sto_tree_release_all_nodes(st->r);
+ } else {
+ dk3sto_list_release_all_nodes(st->r);
+ }
+ } else {
+ dk3sto_unsorted_release_all_nodes(st->r);
+ }
+ }
+ st->r = NULL;
+ }
+}
+
+
+
+int
+dk3sto_remove(dk3_sto_t *st, void *o)
+{
+ int back = 0;
+ dk3_sto_node_t *node_to_remove = NULL; /* Node to remove. */
+ dk3_sto_node_t *ln = NULL; /* Last node. */
+ dk3_sto_it_t *iterator = NULL; /* Traverse all iterators. */
+
+
+#line 1638 "dk3sto.ctr"
+ if(st && o) {
+ node_to_remove = dk3sto_traverse_iterators_for(st->i, o);
+ if(!node_to_remove) {
+ if(st->h) {
+ if(st->t) {
+ node_to_remove = dk3sto_tree_find_exact(st->r,o,st);
+ } else {
+ node_to_remove = dk3sto_list_find_exact(st->r,o,st);
+ }
+ } else {
+ node_to_remove = dk3sto_unsorted_find_exact(st->r,o);
+ }
+ }
+ if(node_to_remove) {
+ back = 1;
+ ln = dk3sto_find_last_node(node_to_remove,st);
+ iterator = (dk3_sto_it_t *)(st->i);
+ while(iterator) {
+ if((iterator->c) == node_to_remove) {
+ iterator->c = ln;
+ }
+ iterator = iterator->r;
+ }
+ if(st->h) {
+ if(st->t) {
+ st->r = dk3sto_tree_remove(st->r,node_to_remove,st,&back,&node_to_remove);
+ } else {
+ st->r = dk3sto_list_remove(st->r,node_to_remove,st,&back,&node_to_remove);
+ }
+ } else {
+ st->r = dk3sto_unsorted_remove(st->r,node_to_remove);
+ }
+ node_to_remove->l = node_to_remove->r = node_to_remove->p = NULL;
+ node_to_remove->o = NULL;
+ dk3_delete(node_to_remove);
+ }
+ }
+
+#line 1675 "dk3sto.ctr"
+ return back;
+}
+
+
+
+int
+dk3sto_add(dk3_sto_t *st, void *o)
+{
+ int back = 0;
+ dk3_sto_node_t *n = NULL; /* New node. */
+
+
+#line 1686 "dk3sto.ctr"
+ if(st && o) {
+ if(st->app) {
+ n = dk3_new_app(dk3_sto_node_t,1,((dk3_app_t *)(st->app))) ;
+ } else {
+ n = dk3_new(dk3_sto_node_t,1);
+ }
+ if(n) {
+ dk3sto_node_init_for_object(n,o,st,st->c);
+ if(st->h) {
+ if(st->t) {
+ st->r = dk3sto_tree_add(st->r, n, st);
+ } else {
+ st->r = dk3sto_list_add(st->r, n, st);
+ }
+ } else {
+ st->r = dk3sto_unsorted_add(st->r, n);
+ }
+ back = 1;
+ }
+ }
+
+#line 1706 "dk3sto.ctr"
+ return back;
+}
+
+
+
+dk3_sto_it_t *
+dk3sto_it_open(dk3_sto_t *st)
+{
+ dk3_sto_it_t *back = NULL;
+
+
+#line 1716 "dk3sto.ctr"
+ if(st) {
+ if(st->app) {
+ back = dk3_new_app(dk3_sto_it_t,1,((dk3_app_t *)(st->app))) ;
+ } else {
+ back = dk3_new(dk3_sto_it_t,1);
+ }
+ if(back) {
+ back->s = st;
+ back->l = NULL;
+ back->r = (dk3_sto_it_t *)(st->i);
+ back->c = NULL;
+ st->i = (void *)back;
+ }
+ }
+
+#line 1730 "dk3sto.ctr"
+ return back;
+}
+
+
+
+void
+dk3sto_it_close(dk3_sto_it_t *it)
+{
+ dk3_sto_it_t *l = NULL; /* Left iterator. */
+ dk3_sto_it_t *r = NULL; /* Right iterator. */
+ dk3_sto_t *s = NULL; /* The storage. */
+
+
+#line 1742 "dk3sto.ctr"
+ if(it) {
+ s = it->s;
+ l = it->l;
+ r = it->r;
+ if(l) {
+ l->r = r;
+ } else {
+ s->i = (void *)(r);
+ }
+ if(r) {
+ r->l = l;
+ }
+ it->s = NULL;
+ it->l = it->r = NULL;
+ it->c = NULL;
+ dk3_delete(it) ;
+ }
+
+#line 1759 "dk3sto.ctr"
+}
+
+
+
+void
+dk3sto_it_reset(dk3_sto_it_t *it)
+{
+
+
+#line 1767 "dk3sto.ctr"
+ if(it) {
+ it->c = NULL;
+ }
+
+#line 1770 "dk3sto.ctr"
+}
+
+
+
+void *
+dk3sto_it_next(dk3_sto_it_t *it)
+{
+ void *back = NULL;
+
+
+#line 1779 "dk3sto.ctr"
+ if(it) {
+ if(it->s) {
+ if((it->s)->h) {
+ if((it->s)->t) {
+ it->c = dk3sto_tree_find_next_node(it->c, (it->s)->r);
+ } else {
+ it->c = dk3sto_list_find_next_node(it->c, (it->s)->r);
+ }
+ } else {
+ it->c = dk3sto_unsorted_find_next_node(it->c, (it->s)->r);
+ }
+ if(it->c) {
+ back = (it->c)->o;
+ }
+ }
+ }
+
+#line 1795 "dk3sto.ctr"
+ return back;
+}
+
+
+
+void *
+dk3sto_it_find_exact(dk3_sto_it_t *i, void const *o)
+{
+ void *back = NULL;
+
+
+#line 1805 "dk3sto.ctr"
+ if(i && o) {
+ if(i->s) {
+ if((i->s)->h) {
+ if((i->s)->t) {
+ i->c = dk3sto_tree_find_exact((i->s)->r, o, i->s);
+ } else {
+ i->c = dk3sto_list_find_exact((i->s)->r, o, i->s);
+ }
+ } else {
+ i->c = dk3sto_unsorted_find_exact((i->s)->r, o);
+ }
+ }
+ if(i->c) {
+ back = (i->c)->o;
+ }
+ }
+
+#line 1821 "dk3sto.ctr"
+ return back;
+}
+
+
+
+void *
+dk3sto_it_find_like(dk3_sto_it_t *i, void const *o, int cr)
+{
+ void *back = NULL;
+ dk3_sto_node_t testnode; /* Test node for comparisons. */
+ dk3_sto_node_t *candidate = NULL; /* Candicate node. */
+
+
+#line 1833 "dk3sto.ctr"
+ if(i && o) {
+ if(i->s) {
+ candidate = NULL;
+ if((i->s)->h) {
+ dk3sto_node_init_for_object(&testnode, (void *)o, (i->s), cr);
+ if((i->s)->t) {
+ i->c = dk3sto_tree_find_like((i->s)->r, &testnode, i->s, cr, &candidate);
+ } else {
+ i->c = dk3sto_list_find_like((i->s)->r, &testnode, i->s, cr, &candidate);
+ }
+ } else {
+ i->c = dk3sto_unsorted_find_exact((i->s)->r, o);
+ }
+ if(i->c) {
+ back = (i->c)->o;
+ } else {
+ i->c = candidate;
+ }
+ }
+ }
+
+#line 1853 "dk3sto.ctr"
+ return back;
+}
+
+
+
+int
+dk3sto_set_eval_c(dk3_sto_t *st, dk3_fct_eval_c_t *f, int cr)
+{
+ int back = 0;
+
+
+#line 1863 "dk3sto.ctr"
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).c = f;
+ st->c = cr;
+ st->h = DK3STO_COMPARE_CHAR;
+ }
+ }
+
+#line 1871 "dk3sto.ctr"
+ return back;
+}
+
+
+
+int
+dk3sto_set_eval_uc(dk3_sto_t *st, dk3_fct_eval_uc_t *f, int cr)
+{
+ int back = 0;
+
+
+#line 1881 "dk3sto.ctr"
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).uc = f;
+ st->c = cr;
+ st->h = DK3STO_COMPARE_UCHAR;
+ }
+ }
+
+#line 1889 "dk3sto.ctr"
+ return back;
+}
+
+
+
+int
+dk3sto_set_eval_s(dk3_sto_t *st, dk3_fct_eval_s_t *f, int cr)
+{
+ int back = 0;
+
+
+#line 1899 "dk3sto.ctr"
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).s = f;
+ st->c = cr;
+ st->h = DK3STO_COMPARE_SHORT;
+ }
+ }
+
+#line 1907 "dk3sto.ctr"
+ return back;
+}
+
+
+
+int
+dk3sto_set_eval_us(dk3_sto_t *st, dk3_fct_eval_us_t *f, int cr)
+{
+ int back = 0;
+
+
+#line 1917 "dk3sto.ctr"
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).us = f;
+ st->c = cr;
+ st->h = DK3STO_COMPARE_USHORT;
+ }
+ }
+
+#line 1925 "dk3sto.ctr"
+ return back;
+}
+
+
+
+int
+dk3sto_set_eval_i(dk3_sto_t *st, dk3_fct_eval_i_t *f, int cr)
+{
+ int back = 0;
+
+
+#line 1935 "dk3sto.ctr"
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).i = f;
+ st->c = cr;
+ st->h = DK3STO_COMPARE_INT;
+ }
+ }
+
+#line 1943 "dk3sto.ctr"
+ return back;
+}
+
+
+
+int
+dk3sto_set_eval_ui(dk3_sto_t *st, dk3_fct_eval_ui_t *f, int cr)
+{
+ int back = 0;
+
+
+#line 1953 "dk3sto.ctr"
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).ui = f;
+ st->c = cr;
+ st->h = DK3STO_COMPARE_UINT;
+ }
+ }
+
+#line 1961 "dk3sto.ctr"
+ return back;
+}
+
+
+
+int
+dk3sto_set_eval_l(dk3_sto_t *st, dk3_fct_eval_l_t *f, int cr)
+{
+ int back = 0;
+
+
+#line 1971 "dk3sto.ctr"
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).l = f;
+ st->c = cr;
+ st->h = DK3STO_COMPARE_LONG;
+ }
+ }
+
+#line 1979 "dk3sto.ctr"
+ return back;
+}
+
+
+
+int
+dk3sto_set_eval_ul(dk3_sto_t *st, dk3_fct_eval_ul_t *f, int cr)
+{
+ int back = 0;
+
+
+#line 1989 "dk3sto.ctr"
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).ul = f;
+ st->c = cr;
+ st->h = DK3STO_COMPARE_ULONG;
+ }
+ }
+
+#line 1997 "dk3sto.ctr"
+ return back;
+}
+
+
+
+int
+dk3sto_set_eval_f(dk3_sto_t *st, dk3_fct_eval_f_t *f, int cr)
+{
+ int back = 0;
+
+
+#line 2007 "dk3sto.ctr"
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).f = f;
+ st->c = cr;
+ st->h = DK3STO_COMPARE_FLOAT;
+ }
+ }
+
+#line 2015 "dk3sto.ctr"
+ return back;
+}
+
+
+
+int
+dk3sto_set_eval_d(dk3_sto_t *st, dk3_fct_eval_d_t *f, int cr)
+{
+ int back = 0;
+
+
+#line 2025 "dk3sto.ctr"
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).d = f;
+ st->c = cr;
+ st->h = DK3STO_COMPARE_DOUBLE;
+ }
+ }
+
+#line 2033 "dk3sto.ctr"
+ return back;
+}
+
+
+
+int
+dk3sto_set_comp(dk3_sto_t *st, dk3_fct_comp_t *f, int cr)
+{
+ int back = 0;
+
+
+#line 2043 "dk3sto.ctr"
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).comp = f;
+ st->c = cr;
+ st->h = DK3STO_COMPARE_FCT;
+ }
+ }
+
+#line 2051 "dk3sto.ctr"
+ return back;
+}
+
+
+
+int
+dk3sto_use_trees(dk3_sto_t *st,int ok)
+{
+ int back = 0;
+ if(st) {
+ if(!(st->r)) {
+ st->t = (ok ? 1 : 0);
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+void *
+dk3sto_find_root(dk3_sto_t *s)
+{
+ void *back = NULL;
+ if(s) {
+ if(s->r) {
+ back = (s->r)->o;
+ }
+ }
+ return back;
+}
+
+
+
+void *
+dk3sto_it_find_parent(dk3_sto_it_t *i)
+{
+ void *back = NULL;
+ if(i) {
+ if(i->c) {
+ if((i->c)->p) {
+ back = ((i->c)->p)->o;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void *
+dk3sto_it_find_left(dk3_sto_it_t *i)
+{
+ void *back = NULL;
+ if(i) {
+ if(i->c) {
+ if((i->c)->l) {
+ back = ((i->c)->l)->o;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void *
+dk3sto_it_find_right(dk3_sto_it_t *i)
+{
+ void *back = NULL;
+ if(i) {
+ if(i->c) {
+ if((i->c)->r) {
+ back = ((i->c)->r)->o;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void *
+dk3sto_it_find_root(dk3_sto_it_t *i)
+{
+ void *back = NULL;
+ if(i) {
+ if(i->s) {
+ back = dk3sto_find_root(i->s);
+ }
+ }
+ return back;
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dk3sto.ctr b/support/dktools/dk3sto.ctr
new file mode 100644
index 0000000000..5c160687d3
--- /dev/null
+++ b/support/dktools/dk3sto.ctr
@@ -0,0 +1,2147 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% header
+
+#include "dk3conf.h"
+#include "dk3types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Create new storage.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new storage on succcess, NULL on error.
+ Use dk3sto_close() to destroy the storage when done with it.
+*/
+dk3_sto_t *
+dk3sto_open_app(dk3_app_t *app);
+
+/** Destroy storage, release memory.
+ @param st Storage to destroy.
+*/
+void
+dk3sto_close(dk3_sto_t *st);
+
+/** Remove all pointers from a storage.
+ @param st Storage.
+*/
+void
+dk3sto_remove_all(dk3_sto_t *st);
+
+/** Remove one pointer from storage.
+ @param st Storage.
+ @param o Object pointer to remove.
+ @return 1 on success, 0 on error (not found).
+*/
+int
+dk3sto_remove(dk3_sto_t *st, void *o);
+
+/** Add object pointer to storage.
+ @param st Storage.
+ @param o Object pointer to add.
+ @return 1 on success, 0 on error (not enough memory).
+*/
+int
+dk3sto_add(dk3_sto_t *st, void *o);
+
+/** Create iterator for storage.
+ @param st Storage.
+ @return Pointer to new iterator on success, NULL on error.
+ Use dk3sto_it_close() to destroy the iterator when done with it.
+ When closing/destroying a storage all iterators for that
+ storage are destroyed automatically.
+*/
+dk3_sto_it_t *
+dk3sto_it_open(dk3_sto_t *st);
+
+/** Destroy iterator.
+ @param it Iterator to destroy.
+*/
+void
+dk3sto_it_close(dk3_sto_it_t *it);
+
+/** Reset iterator (next call to dk3sto_it_next() will return the
+ first object pointer.
+ @param it Iterator.
+*/
+void
+dk3sto_it_reset(dk3_sto_it_t *it);
+
+/** Return next object pointer.
+ @param it Iterator.
+ @return Pointer to next object on success, NULL on error
+ (no more pointers available).
+*/
+void *
+dk3sto_it_next(dk3_sto_it_t *it);
+
+/** Find a pointer exactly.
+ @param i Iterator.
+ @param o Object pointer.
+ @return Object pointer on success, NULL on error (object not found).
+ The next calls to dk3sto_it_next() will return pointers to objects
+ after the specified object \a o.
+*/
+void *
+dk3sto_it_find_exact(dk3_sto_it_t *i, void const *o);
+
+/** Find object pointer for object evaluating equally to \a o.
+ @param i Iterator.
+ @param o Object pointer.
+ @param cr Comparison criteria.
+ @return Object pointer on success, NULL on error (no such object).
+*/
+void *
+dk3sto_it_find_like(dk3_sto_it_t *i, void const *o, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to a char.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sto_set_eval_c(dk3_sto_t *st, dk3_fct_eval_c_t *f, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to an unsigned char.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sto_set_eval_uc(dk3_sto_t *st, dk3_fct_eval_uc_t *f, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to a short.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sto_set_eval_s(dk3_sto_t *st, dk3_fct_eval_s_t *f, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to an unsigned short.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sto_set_eval_us(dk3_sto_t *st, dk3_fct_eval_us_t *f, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to an int.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sto_set_eval_i(dk3_sto_t *st, dk3_fct_eval_i_t *f, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to an unsigned int.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sto_set_eval_ui(dk3_sto_t *st, dk3_fct_eval_ui_t *f, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to a long.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sto_set_eval_l(dk3_sto_t *st, dk3_fct_eval_l_t *f, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to an unsigned long.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sto_set_eval_ul(dk3_sto_t *st, dk3_fct_eval_ul_t *f, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to a float.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sto_set_eval_f(dk3_sto_t *st, dk3_fct_eval_f_t *f, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to a double.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sto_set_eval_d(dk3_sto_t *st, dk3_fct_eval_d_t *f, int cr);
+
+/** Set comparison function.
+ @param st Storage.
+ @param f Function comparing two object pointers.
+ @param cr Comparison criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sto_set_comp(dk3_sto_t *st, dk3_fct_comp_t *f, int cr);
+
+/** Allow use of tree structures.
+ This function must be called before adding any data.
+ @param st Storage.
+ @param ok Flag: Trees may be used.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sto_use_trees(dk3_sto_t *st,int ok);
+
+/** Find object pointer at the trees root.
+ @param s Storage.
+*/
+void *
+dk3sto_find_root(dk3_sto_t *s);
+
+/** Find object pointer for the parent node
+ of the last found object.
+ @param i Iterator.
+ @return Object pointer on success, NULL on error.
+*/
+void *
+dk3sto_it_find_parent(dk3_sto_it_t *i);
+
+/** Find object pointer for node on left child of the last found object.
+ @param i Iterator.
+ @return Object pointer on success, NULL on error.
+*/
+void *
+dk3sto_it_find_left(dk3_sto_it_t *i);
+
+/** Find object pointer for node on right child of the last found object.
+ @param i Iterator.
+ @return Object pointer on success, NULL on error.
+*/
+void *
+dk3sto_it_find_right(dk3_sto_it_t *i);
+
+/** Find object pointer at the trees root.
+ @param i Iterator.
+*/
+void *
+dk3sto_it_find_root(dk3_sto_it_t *i);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk3all.h"
+
+
+
+$(trace-include)
+
+
+
+/** Comparison criteria: Do not compare the objects (unsorted storage).
+*/
+#define DK3STO_COMPARE_NONE 0
+
+/** Comparison criteria: Use comparison function.
+*/
+#define DK3STO_COMPARE_FCT 1
+
+/** Comparison criteria: Evaluate objects to char values.
+*/
+#define DK3STO_COMPARE_CHAR 2
+
+/** Comparison criteria: Evaluate objects to unsigned char values.
+*/
+#define DK3STO_COMPARE_UCHAR 3
+
+/** Comparison criteria: Evaluate objects to short values.
+*/
+#define DK3STO_COMPARE_SHORT 4
+
+/** Comparison criteria: Evaluate objects to unsigned short values.
+*/
+#define DK3STO_COMPARE_USHORT 5
+
+/** Comparison criteria: Evaluate objects to int values.
+*/
+#define DK3STO_COMPARE_INT 6
+
+/** Comparison criteria: Evaluate objects to unsigned int values.
+*/
+#define DK3STO_COMPARE_UINT 7
+
+/** Comparison criteria: Evaluate objects to long values.
+*/
+#define DK3STO_COMPARE_LONG 8
+
+/** Comparison criteria: Evaluate objects to unsigned long values.
+*/
+#define DK3STO_COMPARE_ULONG 9
+
+/** Comparison criteria: Evaluate objects to float values.
+*/
+#define DK3STO_COMPARE_FLOAT 10
+
+/** Comparison criteria: Evaluate objects to double values.
+*/
+#define DK3STO_COMPARE_DOUBLE 11
+
+
+
+/*
+ GENERAL STATIC FUNCTIONS
+*/
+
+/** Initialize storage node for object.
+ @param n Storage node.
+ @param o Object.
+ @param s Storage.
+ @param crit Comparison/evaluation criteria used by storage.
+*/
+static void
+dk3sto_node_init_for_object(dk3_sto_node_t *n, void *o, dk3_sto_t *s, int crit)
+{
+ $? "+ dk3sto_node_init_for_object %!8s %!8s %!8s %d", TR_8PTR(n), TR_8PTR(o), TR_8PTR(s), crit
+ n->p = n->l = n->r = NULL;
+ n->b = n->w = 0;
+ n->o = o;
+ switch(s->h) {
+ case DK3STO_COMPARE_CHAR: (n->v).c = (*((s->e).c))(o,crit); break;
+ case DK3STO_COMPARE_UCHAR: (n->v).uc = (*((s->e).uc))(o,crit); break;
+ case DK3STO_COMPARE_SHORT: (n->v).s = (*((s->e).s))(o,crit); break;
+ case DK3STO_COMPARE_USHORT: (n->v).us = (*((s->e).us))(o,crit); break;
+ case DK3STO_COMPARE_INT: (n->v).i = (*((s->e).i))(o,crit); break;
+ case DK3STO_COMPARE_UINT: (n->v).ui = (*((s->e).ui))(o,crit); break;
+ case DK3STO_COMPARE_LONG: (n->v).l = (*((s->e).l))(o,crit); break;
+ case DK3STO_COMPARE_ULONG: (n->v).ul = (*((s->e).ul))(o,crit); break;
+ case DK3STO_COMPARE_FLOAT: (n->v).f = (*((s->e).f))(o,crit); break;
+ case DK3STO_COMPARE_DOUBLE: (n->v).d = (*((s->e).d))(o,crit); break;
+ } $? "- dk3sto_node_init_for_object"
+}
+
+
+
+/** Copy data from one storage node to another.
+ @param d Destination node.
+ @param s Source node.
+ @param st Storage.
+*/
+static void
+dk3sto_node_data_copy(dk3_sto_node_t *d, dk3_sto_node_t *s, dk3_sto_t *st)
+{
+ $? "+ dk3sto_node_data_copy %!8s %!8s", TR_8PTR(d), TR_8PTR(s)
+ d->o = s->o;
+ switch(st->h) {
+ case DK3STO_COMPARE_CHAR: (d->v).c = (s->v).c ; break;
+ case DK3STO_COMPARE_UCHAR: (d->v).uc = (s->v).uc ; break;
+ case DK3STO_COMPARE_SHORT: (d->v).s = (s->v).s ; break;
+ case DK3STO_COMPARE_USHORT: (d->v).us = (s->v).us ; break;
+ case DK3STO_COMPARE_INT: (d->v).i = (s->v).i ; break;
+ case DK3STO_COMPARE_UINT: (d->v).ui = (s->v).ui ; break;
+ case DK3STO_COMPARE_LONG: (d->v).l = (s->v).l ; break;
+ case DK3STO_COMPARE_ULONG: (d->v).ul = (s->v).ul ; break;
+ case DK3STO_COMPARE_FLOAT: (d->v).f = (s->v).f ; break;
+ case DK3STO_COMPARE_DOUBLE: (d->v).d = (s->v).d ; break;
+ }
+ $? "- dk3sto_node_data_copy"
+}
+
+
+
+/** Compare two storage nodes.
+ @param l Left node.
+ @param r Right node.
+ @param s Storage.
+ @param c Comparison criteria.
+ @return Comparison result.
+*/
+static int
+dk3sto_node_compare(dk3_sto_node_t *l, dk3_sto_node_t *r, dk3_sto_t *s, int c)
+{
+ int back = 0;
+ $? "+ dk3sto_node_compare %!8s %!8s %!8s %d", TR_8PTR(l), TR_8PTR(r), TR_8PTR(s), c
+ switch(s->h) {
+ case DK3STO_COMPARE_FCT: { $? ". compare by function"
+ back = (*((s->e).comp))((void *)(l->o),(void *)(r->o),c);
+ if(back < 0) back = -1;
+ if(back > 0) back = 1;
+ } break;
+ case DK3STO_COMPARE_CHAR: { $? ". compare character"
+ if(((l->v).c) > ((r->v).c)) { back = 1; }
+ else { if(((l->v).c) < ((r->v).c)) { back = -1; } }
+ } break;
+ case DK3STO_COMPARE_UCHAR: { $? ". compare unsigned character"
+ if(((l->v).uc) > ((r->v).uc)) { back = 1; }
+ else { if(((l->v).uc) < ((r->v).uc)) { back = -1; } }
+ } break;
+ case DK3STO_COMPARE_SHORT: { $? ". compare short"
+ if(((l->v).s) > ((r->v).s)) { back = 1; }
+ else { if(((l->v).s) < ((r->v).s)) { back = -1; } }
+ } break;
+ case DK3STO_COMPARE_USHORT: { $? ". compare unsigned short"
+ if(((l->v).us) > ((r->v).us)) { back = 1; }
+ else { if(((l->v).us) < ((r->v).us)) { back = -1; } }
+ } break;
+ case DK3STO_COMPARE_INT: { $? ". compare int"
+ if(((l->v).i) > ((r->v).i)) { back = 1; }
+ else { if(((l->v).i) < ((r->v).i)) { back = -1; } }
+ } break;
+ case DK3STO_COMPARE_UINT: { $? ". compare unsigned int"
+ if(((l->v).ui) > ((r->v).ui)) { back = 1; }
+ else { if(((l->v).ui) < ((r->v).ui)) { back = -1; } }
+ } break;
+ case DK3STO_COMPARE_LONG: { $? ". compare long"
+ if(((l->v).l) > ((r->v).l)) { back = 1; }
+ else { if(((l->v).l) < ((r->v).l)) { back = -1; } }
+ } break;
+ case DK3STO_COMPARE_ULONG: { $? ". compare unsigned long"
+ if(((l->v).ul) > ((r->v).ul)) { back = 1; }
+ else { if(((l->v).ul) < ((r->v).ul)) { back = -1; } }
+ } break;
+ case DK3STO_COMPARE_FLOAT: { $? ". compare float"
+ if(((l->v).f) > ((r->v).f)) { back = 1; }
+ else { if(((l->v).f) < ((r->v).f)) { back = -1; } }
+ } break;
+ case DK3STO_COMPARE_DOUBLE: { $? ". compare double"
+ if(((l->v).d) > ((r->v).d)) { back = 1; }
+ else { if(((l->v).d) < ((r->v).d)) { back = -1; } }
+ } break;
+ } $? "- dk3sto_node_compare %d", back
+ return back;
+}
+
+
+
+/*
+ UNSORTED DATA HANDLING
+*/
+
+/** Remove node from an unsorted storage.
+ @param ro Root node.
+ @param n Node to remove.
+ @return New root node.
+*/
+static dk3_sto_node_t *
+dk3sto_unsorted_remove(dk3_sto_node_t *ro, dk3_sto_node_t *n)
+{
+ dk3_sto_node_t *back = NULL;
+ dk3_sto_node_t *l = NULL; /* Left element. */
+ dk3_sto_node_t *r = NULL; /* Right element. */
+ $? "+ dk3sto_unsorted_remove %s %s", TR_PTR(ro), TR_PTR(n)
+ back = ro;
+ l = n->l; r = n->r;
+ if(r) {
+ r->l = l;
+ }
+ if(l) {
+ l->r = r;
+ } else {
+ back = r;
+ } $? "- dk3sto_unsorted_remove %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+/** Add node to an unsorted storage.
+ @param r Old root node.
+ @param n Node to add.
+ @return New root node or NULL.
+*/
+static dk3_sto_node_t *
+dk3sto_unsorted_add(dk3_sto_node_t *r, dk3_sto_node_t *n)
+{
+ dk3_sto_node_t *back;
+ $? "+ dk3sto_unsorted_add %!8s %!8s", TR_8PTR(r), TR_8PTR(n)
+ back = n;
+ n->r = r;
+ if(r) {
+ r->l = n;
+ } $? "- dk3sto_unsorted_add %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+/** Release all nodes in an unsorted storage.
+ @param r Root node.
+*/
+static void
+dk3sto_unsorted_release_all_nodes(dk3_sto_node_t *r)
+{
+ dk3_sto_node_t *c; /* Current element. */
+ dk3_sto_node_t *n; /* Next element. */
+ $? "+ dk3sto_unsorted_release_all_nodes %!8s", TR_8PTR(r)
+ c = r;
+ while(c) {
+ n = c->r;
+ c->p = c->l = c->r = NULL;
+ c->o = NULL;
+ c->b = c->w = 0;
+ dk3_delete(c) ;
+ c = n;
+ }
+ $? "- dk3sto_unsorted_release_all_nodes"
+}
+
+
+
+/** Find next node in an unsorted storage.
+ @param n Current node.
+ @param r Root node.
+ @return Pointer to next node or NULL.
+*/
+static dk3_sto_node_t *
+dk3sto_unsorted_find_next_node(dk3_sto_node_t *n, dk3_sto_node_t *r)
+{
+ dk3_sto_node_t *back = NULL;
+ $? "+ dk3sto_unsorted_find_next_node %!8s %!8s", TR_8PTR(n), TR_8PTR(r)
+ if(n) {
+ back = n->r;
+ } else {
+ back = r;
+ } $? "- dk3sto_unsorted_find_next_node %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+/** Find last node in an unsorted storage.
+ @param n Root node.
+ @return Last node or NULL.
+*/
+static dk3_sto_node_t *
+dk3sto_unsorted_find_last_node(dk3_sto_node_t *n)
+{
+ dk3_sto_node_t *back = NULL;
+ $? "+ dk3sto_unsorted_find_last_node %!8s", TR_8PTR(n)
+ if(n) back = n->l;
+ $? "- dk3sto_unsorted_find_last_node %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+/** Find node for an object in an unsorted storage.
+ @param r Root node.
+ @param o Object.
+ @return Node for object or NULL.
+*/
+static dk3_sto_node_t *
+dk3sto_unsorted_find_exact(dk3_sto_node_t *r, void const *o)
+{
+ dk3_sto_node_t *back = NULL;
+ dk3_sto_node_t *c; /* Current node. */
+ $? "+ dk3sto_unsorted_find_exact %!8s %!8s", TR_8PTR(r), TR_8PTR(o)
+ c = r;
+ while(c && (!back)) {
+ if((c->o) == o) {
+ back = c;
+ }
+ c = c->r;
+ } $? "- dk3sto_unsorted_find_exact %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+/*
+ SORTED DATA HANDLING
+*/
+
+
+
+/** Go to direction: Left.
+*/
+#define DK3STO_WALK_LEFT 1
+
+/** Go to direction: Right.
+*/
+#define DK3STO_WALK_RIGHT 2
+
+
+
+/** Perform left rotation at node.
+ @param p Subpath to modify.
+ @return New subpath root node or NULL.
+*/
+static dk3_sto_node_t *
+dk3sto_left_rotation(dk3_sto_node_t *p)
+{
+ dk3_sto_node_t *p1;
+ $? "+ dk3sto_left_rotation %!8s", TR_8PTR(p)
+ p1 = p->r;
+ p->r = p1->l;
+ if(p->r) (p->r)->p = p;
+ p1->l = p;
+ if(p) p->p = p1;
+ $? "- dk3sto_left_rotation %!8s", TR_8PTR(p1)
+ return p1;
+}
+
+
+
+/** Perform right rotation at node.
+ @param p Subpath to modify.
+ @return New subpath root node or NULL.
+*/
+static dk3_sto_node_t *
+dk3sto_right_rotation(dk3_sto_node_t *p)
+{
+ dk3_sto_node_t *p1;
+ $? "+ dk3sto_right_rotation %!8s", TR_8PTR(p)
+ p1 = p->l;
+ p->l = p1->r;
+ if(p->l) (p->l)->p = p;
+ p1->r = p;
+ if(p) p->p = p1;
+ $? "- dk3sto_right_rotation %!8s", TR_8PTR(p1)
+ return p1;
+}
+
+
+
+/** Increment balance field of a storage node.
+ @param p Node to modify.
+*/
+static void
+dk3sto_inc_balance(dk3_sto_node_t *p)
+{
+ short x; /* New balance value. */
+ $? "+ dk3sto_inc_balance %!8s", TR_8PTR(p)
+ x = p->b; $? ". old balance %d", x
+ x++;
+ if(x > 3) x = 0;
+ p->b = x; $? "- dk3sto_inc_balance %d", p->b
+}
+
+
+
+/** Decrement balance field of a storage node.
+ @param p Storage node.
+*/
+static void
+dk3sto_dec_balance(dk3_sto_node_t *p)
+{
+ short x; /* New balance value. */
+ $? "+ dk3sto_dec_balance %!8s", TR_8PTR(p)
+ x = p->b; $? ". old balance %d", x
+ x--;
+ if(x < 0) x = 3;
+ p->b = x; $? "- dk3sto_dec_balance %d", p->b
+}
+
+
+
+
+/** Set mark for "left node deleted".
+ @param p Node.
+ @param h Pointer to balance variable.
+ @return New root node for path behind \a p.
+*/
+static dk3_sto_node_t *
+dk3sto_left_deleted(dk3_sto_node_t *p, short *h)
+{
+ $? "+ dk3sto_left_deleted %!8s %!8s", TR_8PTR(p), TR_8PTR(h)
+ switch(p->b) {
+ case 0: *h = - *h;
+ case 3:
+ $? ". going to increment balance field of %!8s", TR_8PTR(p)
+ dk3sto_inc_balance(p);
+ $? ". balance field incremented"
+ break;
+ case 1: {
+ switch((p->r)->b) {
+ case 0:
+ (p->r)->b = 3;
+ *h = - *h;
+ p = dk3sto_left_rotation(p);
+ break;
+ case 1:
+ (p->r)->b = 0;
+ p->b = 0;
+ p = dk3sto_left_rotation(p);
+ break;
+ case 3:
+ p->b = (((((p->r)->l)->b) == 1) ? 3 : 0);
+ (p->r)->b = (((((p->r)->l)->b) == 3) ? 1 : 0);
+ p->r = dk3sto_right_rotation(p->r);
+ if(p->r) (p->r)->p = p;
+ p = dk3sto_left_rotation(p);
+ p->b = 0;
+ }
+ }
+ }
+ $? "- dk3sto_left_deleted %!8s", TR_8PTR(p)
+ return p;
+}
+
+
+
+/** Set mark for "right node deleted".
+ @param p Node.
+ @param h Pointer to balance variable.
+ @return New root node for path behind \a p.
+*/
+static dk3_sto_node_t *
+dk3sto_right_deleted(dk3_sto_node_t *p, short *h)
+{
+ $? "+ dk3sto_right_deleted %!8s %!8s", TR_8PTR(p), TR_8PTR(h)
+ switch(p->b) {
+ case 0: *h = - *h;
+ case 1: dk3sto_dec_balance(p);
+ break;
+ case 3: {
+ switch((p->l)->b) {
+ case 0:
+ (p->l)->b = 1;
+ *h = - *h;
+ p = dk3sto_right_rotation(p);
+ break;
+ case 3:
+ (p->l)->b = 0;
+ p->b = 0;
+ p = dk3sto_right_rotation(p);
+ break;
+ case 1:
+ p->b = (((((p->l)->r)->b) == 3) ? 1 : 0);
+ (p->l)->b = (((((p->l)->r)->b) == 1) ? 3 : 0);
+ p->l = dk3sto_left_rotation(p->l);
+ if(p->l) (p->l)->p = p;
+ p = dk3sto_right_rotation(p);
+ p->b = 0;
+ }
+ }
+ }
+ $? "- dk3sto_right_deleted %!8s", TR_8PTR(p)
+ return p;
+}
+
+
+
+/** Add node to tree storage.
+ @param root Root node.
+ @param newnode Node to add.
+ @param st Storage.
+ @return New root node or NULL.
+*/
+static dk3_sto_node_t *
+dk3sto_avlt_add(dk3_sto_node_t *root, dk3_sto_node_t *newnode, dk3_sto_t *st)
+{
+ dk3_sto_node_t *back = NULL;
+ dk3_sto_node_t *p = NULL; /* Current node. */
+ dk3_sto_node_t *q = NULL; /* Father of p. */
+ dk3_sto_node_t *r = NULL; /* Critical node. */
+ dk3_sto_node_t *s = NULL; /* Father of r. */
+ $? "+ dk3sto_avlt_add %!8s %!8s %!8s", TR_8PTR(root), TR_8PTR(newnode), TR_8PTR(st)
+ back = root;
+ p = r = root; q = s = NULL;
+ /*
+ Search place for insertion, write direction into
+ the "w" field in each node.
+ The final new node has an empty "w" field.
+ */
+ while(p) {
+ if(p->b) {
+ s = q; r = p;
+ }
+ q = p;
+ if(dk3sto_node_compare(p,newnode,st,st->c) > 0) {
+ p->w = DK3STO_WALK_LEFT;
+ p = p->l;
+ } else {
+ p->w = DK3STO_WALK_RIGHT;
+ p = p->r;
+ }
+ }
+ p = newnode;
+ if(!back) {
+ /*
+ When inserting into an empty tree we are done here.
+ */
+ back = p;
+ } else {
+ /*
+ The tree is not empty.
+ The new node p is concatenated to the parent q.
+ */
+ if(dk3sto_node_compare(q,newnode,st,st->c) > 0) {
+ q->l = p;
+ q->w = DK3STO_WALK_LEFT;
+ } else {
+ q->r = p;
+ q->w = DK3STO_WALK_RIGHT;
+ }
+ /*
+ Now we must balance the tree again if necessary.
+ */
+ p->p = q;
+ if(r) {
+ /*
+ There is a critical node.
+ */
+ p = r;
+ /*
+ Modify balance fields from critial node
+ until we find our new node.
+ */
+ while(p->w) {
+ if(p->w == DK3STO_WALK_LEFT) {
+ dk3sto_dec_balance(p);
+ p = p->l;
+ } else {
+ dk3sto_inc_balance(p);
+ p = p->r;
+ }
+ }
+ p = r;
+ /*
+ Now look whether we are dis-balanced,
+ correct if necessary.
+ */
+ if((p->b) == 2) {
+ /* We must balance */
+ if(p->w == DK3STO_WALK_LEFT) {
+ if((p->l)->b == 3) {
+ p->b = 0;
+ p = dk3sto_right_rotation(p);
+ } else {
+ p->b = (((((p->l)->r)->b) == 3) ? 1 : 0);
+ (p->l)->b = (((((p->l)->r)->b) == 1) ? 3 : 0);
+ p->l = dk3sto_left_rotation(p->l);
+ if(p->l) (p->l)->p = p;
+ p = dk3sto_right_rotation(p);
+ }
+ } else {
+ if((p->r)->b == 1) {
+ p->b = 0;
+ p = dk3sto_left_rotation(p);
+ } else {
+ p->b = (((((p->r)->l)->b) == 1) ? 3 : 0);
+ (p->r)->b = (((((p->r)->l)->b) == 3) ? 1 : 0);
+ p->r = dk3sto_right_rotation(p->r);
+ if(p->r) (p->r)->p = p;
+ p = dk3sto_left_rotation(p);
+ }
+ }
+ p->b = 0;
+ /*
+ Balance at the critical nodes father (if
+ there is one) or create new root.
+ */
+ if(s) {
+ if(s->w == DK3STO_WALK_LEFT) {
+ s->l = p;
+ } else {
+ s->r = p;
+ }
+ if(p) p->p = s;
+ } else {
+ back = p;
+ }
+ }
+ }
+ }
+ if(back) {
+ back->p = NULL;
+ }
+ $? "- dk3sto_avlt_add %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+/** Remove storage node from tree storage.
+ @param root Root object.
+ @param node Node to remove.
+ @param delpath Deletion path (used for tree balancing).
+ @param st Storage.
+ @param success_indicator Pointer to success variable.
+ @param toremove Node to remove.
+ @return New root object.
+*/
+static dk3_sto_node_t *
+dk3sto_avlt_delete(
+ dk3_sto_node_t *root, dk3_sto_node_t *node, dk3_sto_node_t **delpath,
+ dk3_sto_t *st, int *success_indicator, dk3_sto_node_t **toremove
+)
+{
+ dk3_sto_node_t *back = NULL;
+ dk3_sto_node_t *p = NULL; /* Current node. */
+ dk3_sto_node_t *q = NULL; /* Father of p. */
+ dk3_sto_node_t *r = NULL; /* Critical node. */
+ dk3_sto_node_t *todel = NULL; /* Node to delete. */
+ short x1 = 0; /* Balance value. */
+ short delroot = 0; /* Flag: Delete tree node. */
+ int can_continue = 1; /* Flag: Can continue. */
+ back = root;
+ todel = node;
+ $? "+ dk3sto_avlt_delete %!8s %!8s %!8s %!8s %!8s", TR_8PTR(root), TR_8PTR(node), TR_8PTR(delpath), TR_8PTR(st), TR_8PTR(success_indicator)
+ /*
+ Make sure the node to delete has max.
+ 1 subtree.
+ */
+ if((todel->l) && (todel->r)) {
+ $? ". finding another node to delete"
+ todel = todel->l;
+ while(todel->r) todel = todel->r;
+ dk3sto_node_data_copy(node,todel,st);
+ }
+ if(!(todel->p)) { $? ". deleting the root node"
+ delroot = 1;
+ }
+ /*
+ Mark the way in the "w" fields.
+ */
+ *toremove = todel;
+ todel->w = 0;
+ while(todel->p) {
+ if((todel->p)->l == todel) {
+ $? ". walk left"
+ (todel->p)->w = DK3STO_WALK_LEFT;
+ } else {
+ $? ". walk right"
+ (todel->p)->w = DK3STO_WALK_RIGHT;
+ }
+ todel = todel->p;
+ }
+ p = back;
+ q = r = NULL;
+ x1 = 0;
+ can_continue = 1;
+ while(can_continue) {
+ $? ". new while loop 1 %d", x1
+#if VERSION_BEFORE_20151002
+ if(p) { $? ". have current node"
+#endif
+ if(p->w) { $? ". not final node"
+ if(p->b == 0) {
+ x1 = 0; $? ". current node is balanced"
+ }
+ delpath[x1++] = p; $? ". adding current node to delpath %d", (x1 - 1)
+ if(x1 >= st->l) { $? ". x1 out of range"
+ /* x1 too large */
+ *success_indicator = 0;
+ goto error_mark;
+ }
+ if(p->w == DK3STO_WALK_LEFT) { $? ". going down left"
+ p = p->l;
+ } else { $? ". going down right"
+ p = p->r;
+ }
+ } else {
+ can_continue = 0; $? ". we are at the final point"
+ }
+#if VERSION_BEFORE_20151002
+ } else {
+ can_continue = 0; $? ". no more nodes to visit"
+ }
+#endif
+ }
+#if VERSION_BEFORE_20151002
+ r = p;
+#endif
+ /* Static code analysis: Dereference potential NULL pointer p */
+ /* I think p can not be NULL. */
+ if(p->l) q = p->l;
+ else q = p->r;
+ if(x1 == 0) {
+ if(delroot) { $? ". setting new root node"
+ back = q;
+ }
+ }
+ while(x1 > 0) { $? ". begin of while loop 2 %d", (x1 - 1)
+ x1--;
+ p = delpath[x1];
+ if(p->w == DK3STO_WALK_LEFT) {
+ $? ". going to left"
+ p->l = q; if(q) q->p = p;
+ q = dk3sto_left_deleted(p, &x1);
+ $? ". after dk3sto_left_deleted"
+ } else {
+ $? ". going to right"
+ p->r = q; if(q) q->p = p;
+ q = dk3sto_right_deleted(p, &x1);
+ $? ". after dk3sto_right_deleted"
+ }
+ if(x1 == 0) {
+ $? ". final node"
+ if(delpath[x1] == back) {
+ $? ". setting new root node"
+ back = q;
+ }
+ }
+ if(x1 < 0) { $? ". finished"
+ p = delpath[0 - x1 - 1];
+ if(p->w == DK3STO_WALK_LEFT) {
+ p->l = q;
+ } else {
+ p->r = q;
+ }
+ if(q) q->p = p;
+ }
+ }
+error_mark:
+ if(back) {
+ back->p = NULL;
+ }
+ $? "- dk3sto_avlt_delete %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+/** Find storage node for an object evaluated like a given object.
+ @param root Root node.
+ @param testnode Node of the given object.
+ @param st Storage.
+ @param crit Comparison criteria.
+ @param cand Pointer for candidate.
+ @return Pointer to storage node or NULL.
+*/
+static dk3_sto_node_t *
+dk3sto_tree_find_like(
+ dk3_sto_node_t *root, dk3_sto_node_t *testnode, dk3_sto_t *st, int crit,
+ dk3_sto_node_t **cand
+)
+{
+ dk3_sto_node_t *back = NULL;
+ dk3_sto_node_t *c = NULL; /* Current node. */
+ int testval = 0; /* Comparison result. */
+ $? "+ sorted_find_like %!8s %!8s %!8s %d", TR_8PTR(root), TR_8PTR(testnode), TR_8PTR(st), crit
+ c = root;
+ while(c) {
+ testval = dk3sto_node_compare(c,testnode,st,crit);
+ switch(testval) {
+ case -1: {
+ if(cand) *cand = c;
+ c = c->r;
+ } break;
+ case 0: {
+ back = c; c = c->l;
+ } break;
+ default: {
+ c = c->l;
+ } break;
+ }
+ } $? "- sorted_find_like %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+/** Add node to a tree.
+ @param r Root node.
+ @param n New node to add.
+ @param s Storage.
+ @return Node pointer on success, NULL on error.
+*/
+static dk3_sto_node_t *
+dk3sto_tree_add(dk3_sto_node_t *r, dk3_sto_node_t *n, dk3_sto_t *s)
+{
+ dk3_sto_node_t *back;
+ back = dk3sto_avlt_add(r,n,s);
+ return back;
+}
+
+
+
+/** Release all nodes in a tree storage.
+ @param r Root node.
+*/
+static void
+dk3sto_tree_release_all_nodes(dk3_sto_node_t *r)
+{
+ $? "+ sorted_release_all_nodes %!8s", TR_8PTR(r)
+ if(r) {
+ dk3sto_tree_release_all_nodes(r->l);
+ dk3sto_tree_release_all_nodes(r->r);
+ r->l = r->r = r->p = NULL;
+ r->o = NULL;
+ r->b = 0; r->w = 0;
+ dk3_delete(r) ;
+ } $? "- sorted_release_all_nodes"
+}
+
+
+
+/** Find next node in a tree storage.
+ @param n Current node.
+ @param r Root node.
+ @return Pointer to next node or NULL.
+*/
+static dk3_sto_node_t *
+dk3sto_tree_find_next_node(dk3_sto_node_t *n, dk3_sto_node_t *r)
+{
+ dk3_sto_node_t *back = NULL;
+ dk3_sto_node_t *c = NULL; /* Current node. */
+ dk3_sto_node_t *p = NULL; /* Parent of c. */
+ $? "+ sorted_find_next_node %!8s %!8s", TR_8PTR(n), TR_8PTR(r)
+ /*
+ if(n) {
+ if(n->r) {
+ back = n->r;
+ while(back->l) { back = back->l; }
+ } else {
+ c = n; p = c->p;
+ while(p && (!back)) {
+ if((p->l) == c) {
+ back = p;
+ } else {
+ c = p; p = c->p;
+ }
+ }
+ }
+ } else {
+ back = r;
+ if(back) { while(back->l) { back = back->l; } }
+ }
+ */
+ if(n) {
+ if(n->r) {
+ back = n->r;
+ while(back->l) back = back->l;
+ } else {
+ c = n; p = c->p;
+ while(p && (!back)) {
+ if(p->l == c) {
+ back = p;
+ } else {
+ c = p; p = c->p;
+ }
+ }
+ }
+ } else {
+ back = r;
+ if(back) {
+ while(back->l) back = back->l;
+ }
+ }
+ $? "- sorted_find_next_node %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+/** Find last node in a tree storage.
+ @param n Node to start search from.
+ @return Last node or NULL.
+*/
+static dk3_sto_node_t *
+dk3sto_tree_find_last_node(dk3_sto_node_t *n)
+{
+ dk3_sto_node_t *back = NULL;
+ dk3_sto_node_t *c; /* Current node. */
+ dk3_sto_node_t *p; /* Father of c. */
+ $? "+ sorted_find_last_node %!8s", TR_8PTR(n)
+ if(n->l) {
+ back = n->l;
+ while(back->r) { back = back->r; }
+ } else {
+ c = n; p = c->p;
+ while(p && (!back)) {
+ if((p->r) == c) {
+ back = p;
+ } else {
+ c = p; p = c->p;
+ }
+ }
+ } $? "- sorted_find_last_node %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+/** Find node for object in tree storage (exact search).
+ @param r Root node.
+ @param o Object to find node for.
+ @param s Storage.
+ @return Pointer to node or NULL.
+*/
+static dk3_sto_node_t *
+dk3sto_tree_find_exact(dk3_sto_node_t *r, void const *o, dk3_sto_t *s)
+{
+ dk3_sto_node_t *back = NULL;
+ dk3_sto_node_t testnode; /* Test node for comparisons. */
+ dk3_sto_node_t *c; /* Current node to test. */
+ dk3_sto_node_t *candidate; /* Candidate for found node. */
+ int testval = 0; /* Comparison result. */
+ $? "+ sorted_find_exact %!8s %!8s %!8s", TR_8PTR(r), TR_8PTR(o), TR_8PTR(s)
+ dk3sto_node_init_for_object(&testnode, (void *)o, s, s->c);
+ c = dk3sto_tree_find_like(r, &testnode, s, s->c, &candidate);
+ while(c && (!back)) {
+ testval = dk3sto_node_compare(c, &testnode, s, s->c);
+ if(testval == 0) {
+ if((c->o) == o) {
+ back = c;
+ } else {
+ c = dk3sto_tree_find_next_node(c, r);
+ }
+ } else {
+ c = NULL;
+ }
+ } $? "- sorted_find_exact %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+/** Remove storage node from tree storage.
+ @param ro Root node.
+ @param n Node to delete.
+ @param st Storage.
+ @param sci ???
+ @param toremove Node to remove.
+ @return New root node.
+*/
+static dk3_sto_node_t *
+dk3sto_tree_remove(
+ dk3_sto_node_t *ro, dk3_sto_node_t *n, dk3_sto_t *st, int *sci,
+ dk3_sto_node_t **toremove
+)
+{
+ dk3_sto_node_t *back;
+ back = dk3sto_avlt_delete(ro,n,st->d,st,sci,toremove);
+ return back;
+}
+
+
+
+/*
+ USE DOUBLE LINKED LIST
+*/
+
+/** Find node for an object evaluated like a given object in a list storage.
+ @param root Root node.
+ @param testnode Node with object for comparison.
+ @param st Storage.
+ @param crit Comparison criteria.
+ @param cand Test candidate.
+ @return Pointer to storage node or NULL.
+*/
+static dk3_sto_node_t *
+dk3sto_list_find_like(
+ dk3_sto_node_t *root, dk3_sto_node_t *testnode, dk3_sto_t *st, int crit,
+ dk3_sto_node_t **cand
+)
+{
+ dk3_sto_node_t *back = NULL;
+ dk3_sto_node_t *c = NULL; /* Current node. */
+ int testval = 0; /* Comparison result. */
+ $? "+ sorted_find_like %!8s %!8s %!8s %d", TR_8PTR(root), TR_8PTR(testnode), TR_8PTR(st), crit
+ c = root;
+ while(c && (!back)) {
+ testval = dk3sto_node_compare(c,testnode,st,crit);
+ switch(testval) {
+ case -1: {
+ if(cand) *cand = c;
+ c = c->r;
+ } break;
+ case 0: {
+ back = c; c = NULL;
+ } break;
+ default : {
+ c = NULL;
+ } break;
+ }
+ } $? "- sorted_find_like %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+/** Find node for an object (exact search).
+ @param r Root node.
+ @param o Object.
+ @param s Storage.
+ @return Pointer to the objects node or NULL.
+*/
+static dk3_sto_node_t *
+dk3sto_list_find_exact(dk3_sto_node_t *r, void const *o, dk3_sto_t *s)
+{
+ dk3_sto_node_t *back;
+ $? "+ sorted_find_exact %!8s %!8s %!8s", TR_8PTR(r), TR_8PTR(o), TR_8PTR(s)
+ back = dk3sto_unsorted_find_exact(r,o);
+ $? "- sorted_find_exact %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+/** Add node to list storage.
+ @param r Root node.
+ @param n New node.
+ @param s Storage.
+ @return Pointer on success, NULL on error.
+*/
+static dk3_sto_node_t *
+dk3sto_list_add(dk3_sto_node_t *r, dk3_sto_node_t *n, dk3_sto_t *s)
+{
+ dk3_sto_node_t *back;
+ dk3_sto_node_t *larger = NULL; /* Last found larger entry. */
+ dk3_sto_node_t *current = NULL; /* Current node. */
+ dk3_sto_node_t *smaller = NULL; /* Last found smaller entry. */
+ int ende;
+ $? "+ sorted_add %!8s %!8s %!8s", TR_8PTR(r), TR_8PTR(n), TR_8PTR(s)
+ back = r;
+ if(r) {
+ larger = smaller = NULL;
+ current = r;
+ ende = 0;
+ while(!ende) {
+ if(dk3sto_node_compare(current,n,s,s->c) >= 0) {
+ larger = current; ende = 1;
+ } else {
+ smaller = current;
+ }
+ if(current->r) {
+ current = current->r;
+ } else {
+ ende = 1;
+ }
+ }
+ if(larger) {
+ n->r = larger;
+ larger->l = n;
+ if(smaller) {
+ smaller->r = n;
+ n->l = smaller;
+ } else {
+ back = n;
+ }
+ } else {
+ if(smaller) {
+ smaller->r = n;
+ n->l = smaller;
+ }
+ }
+ } else {
+ back = n;
+ } $? "- sorted_add %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+/** Release all nodes of a list storage.
+ @param r Root node.
+*/
+static void
+dk3sto_list_release_all_nodes(dk3_sto_node_t *r)
+{
+ $? "+ sorted_release_all_nodes"
+ dk3sto_unsorted_release_all_nodes(r);
+ $? "- sorted_release_all_nodes"
+}
+
+
+
+/** Find next node.
+ @param n Current node.
+ @param r Root node.
+ @return Pointer to next node or NULL.
+*/
+static dk3_sto_node_t *
+dk3sto_list_find_next_node(dk3_sto_node_t *n, dk3_sto_node_t *r)
+{
+ dk3_sto_node_t *back;
+ $? "+ sorted_find_next_node %!8s %!8s", TR_8PTR(n), TR_8PTR(r)
+ back = dk3sto_unsorted_find_next_node(n,r);
+ $? "- sorted_find_next_node %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+/** Find last (previous) node.
+ @param n Current node.
+ @return Pointer to previous node or NULL.
+*/
+static dk3_sto_node_t *
+dk3sto_list_find_last_node(dk3_sto_node_t *n)
+{
+ dk3_sto_node_t *back;
+ $? "+ sorted_find_last_node %!8s", TR_8PTR(n)
+ back = dk3sto_unsorted_find_last_node(n);
+ $? "- sorted_find_last_node %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+/** Remove storage node from list storage.
+ @param ro Root node.
+ @param n Node to remove.
+ @param st Storage.
+ @param sci ???
+ @param toremove ???
+*/
+static dk3_sto_node_t *
+dk3sto_list_remove(
+ dk3_sto_node_t *ro, dk3_sto_node_t *n, dk3_sto_t *st, int *sci,
+ dk3_sto_node_t **toremove
+)
+{
+ dk3_sto_node_t *back;
+ $? "+ sorted_remove %!8s %!8s %!8s", TR_8PTR(ro), TR_8PTR(n), TR_8PTR(st)
+ back = dk3sto_unsorted_remove(ro,n);
+ $? "- sorted_remove %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+/*
+ COMMON STATIC FUNCTIONS
+*/
+
+
+/** Get object node (traverse storage).
+ @param it Storage iterator.
+ @param o Object to find storage node.
+ @return Pointer to node or NULL.
+*/
+static dk3_sto_node_t *
+dk3sto_traverse_iterators_for(void *it, void *o)
+{
+ dk3_sto_node_t *back = NULL;
+ dk3_sto_it_t *c = NULL; /* Current node. */
+ $? "+ dk3sto_traverse_iterators_for %!8s %!8s", TR_8PTR(it), TR_8PTR(o)
+ if(it) {
+ c = (dk3_sto_it_t *)it;
+ while(c && (!back)) {
+ if(c->c) {
+ if(((c->c)->o) == o) {
+ back = c->c;
+ }
+ }
+ if(!back) c = c->r;
+ }
+ } $? "- dk3sto_traverse_iterators_for %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+/** Find last storage node.
+ @param n Current storage node.
+ @param st Storage.
+ @return Pointer to last node or NULL.
+*/
+static dk3_sto_node_t *
+dk3sto_find_last_node(dk3_sto_node_t *n, dk3_sto_t *st)
+{
+ dk3_sto_node_t *back = NULL;
+ $? "+ dk3sto_find_last_node %!8s %!8s", TR_8PTR(n), TR_8PTR(st)
+ if(st->h) {
+ if(st->t) {
+ back = dk3sto_tree_find_last_node(n);
+ } else {
+ back = dk3sto_list_find_last_node(n);
+ }
+ } else {
+ back = dk3sto_unsorted_find_last_node(n);
+ }
+ $? "- dk3sto_find_last_node %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+/** Initialize storage.
+ @param st Storage to initialize.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static int
+dk3sto_storage_init(dk3_sto_t *st, dk3_app_t *app)
+{
+ int back = 0;
+ short l = 0; /* Critical path length. */
+ $? "+ dk3sto_storage_init %!8s", TR_8PTR(st)
+ /* delpath begin address and length */
+ st->d = NULL; st->l = 0;
+ /* root node */
+ st->r = NULL;
+ /* comparison method */
+ st->h = 0;
+ /* comparison criteria */
+ st->c = 0;
+ /* iterators list */
+ st->i = NULL;
+ st->l = l = 1536;
+ st->app = app;
+ st->d = dk3_new_app(dk3_sto_node_p,l,app);
+ st->t = 1;
+ if(st->d) {
+ back = 1;
+ } $? "- dk3sto_storage_init %d", back
+ return back;
+}
+
+
+
+/** Close the storage, release memory.
+ @param st Storage to close.
+*/
+static void
+dk3sto_storage_end(dk3_sto_t *st)
+{
+ $? "+ dk3sto_storage_end %!8s", TR_8PTR(st)
+ /* release iterators */
+ {
+ dk3_sto_it_t *c = NULL; /* Current iterator. */
+ dk3_sto_it_t *n = NULL; /* Next iterator. */
+ c = (dk3_sto_it_t *)(st->i);
+ st->i = NULL;
+ while(c) {
+ $? ". going to release iterator %!8s", TR_8PTR(c)
+ n = c->r;
+ c->r = NULL;
+ c->l = NULL;
+ c->c = NULL;
+ c->s = NULL;
+ dk3_delete(c) ;
+ c = n;
+ }
+ st->i = NULL;
+ }
+ $? ". iterators released"
+ /* release nodes */
+ {
+ if(st->h) {
+ if(st->t) {
+ dk3sto_tree_release_all_nodes(st->r);
+ } else {
+ dk3sto_list_release_all_nodes(st->r);
+ }
+ } else {
+ dk3sto_unsorted_release_all_nodes(st->r);
+ }
+ st->r = NULL;
+ }
+ $? ". nodes released"
+ /* release delpath */
+ {
+ dk3_sto_node_p *p;
+ p = st->d;
+ dk3_delete(p);
+ st->d = NULL; st->l = 0;
+ }
+ $? ". delpath released"
+ /* set pointers to NULL */
+ {
+ st->h = 0;
+ st->c = 0;
+ }
+ $? ". function pointers resetted"
+ $? "- dk3sto_storage_end"
+}
+
+
+
+/*
+ PUBLIC INTERFACES
+*/
+
+
+dk3_sto_t *
+dk3sto_open_app(dk3_app_t *app)
+{
+ dk3_sto_t *back = NULL;
+ $? "+ dk3sto_open"
+ back = dk3_new_app(dk3_sto_t,1,app) ;
+ if(back) {
+ if(!dk3sto_storage_init(back,app)) {
+ dk3_delete(back);
+ back = NULL;
+ }
+ } $? "- dk3sto_open %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+void
+dk3sto_close(dk3_sto_t *st)
+{
+ $? "+ dk3sto_close %!8s", TR_8PTR(st)
+ if(st) {
+ dk3sto_storage_end(st);
+ dk3_delete(st) ;
+ } $? "- dk3sto_close"
+}
+
+
+
+void
+dk3sto_remove_all(dk3_sto_t *st)
+{
+ if(st) {
+ /* reset all iterators */
+ dk3_sto_it_t *c = NULL; /* Curent iterator. */
+ dk3_sto_it_t *n = NULL; /* Next iterator. */
+ c = (dk3_sto_it_t *)(st->i);
+ while(c) {
+ n = c->r;
+ c->c = NULL;
+ c = n;
+ }
+ /* remove all nodes */
+ if(st->r) {
+ if(st->h) {
+ if(st->t) {
+ dk3sto_tree_release_all_nodes(st->r);
+ } else {
+ dk3sto_list_release_all_nodes(st->r);
+ }
+ } else {
+ dk3sto_unsorted_release_all_nodes(st->r);
+ }
+ }
+ st->r = NULL;
+ }
+}
+
+
+
+int
+dk3sto_remove(dk3_sto_t *st, void *o)
+{
+ int back = 0;
+ dk3_sto_node_t *node_to_remove = NULL; /* Node to remove. */
+ dk3_sto_node_t *ln = NULL; /* Last node. */
+ dk3_sto_it_t *iterator = NULL; /* Traverse all iterators. */
+ $? "+ dk3sto_remove %!8s %!8s", TR_8PTR(st), TR_8PTR(o)
+ if(st && o) {
+ node_to_remove = dk3sto_traverse_iterators_for(st->i, o);
+ if(!node_to_remove) {
+ if(st->h) {
+ if(st->t) {
+ node_to_remove = dk3sto_tree_find_exact(st->r,o,st);
+ } else {
+ node_to_remove = dk3sto_list_find_exact(st->r,o,st);
+ }
+ } else {
+ node_to_remove = dk3sto_unsorted_find_exact(st->r,o);
+ }
+ }
+ if(node_to_remove) {
+ back = 1;
+ ln = dk3sto_find_last_node(node_to_remove,st);
+ iterator = (dk3_sto_it_t *)(st->i);
+ while(iterator) {
+ if((iterator->c) == node_to_remove) {
+ iterator->c = ln;
+ }
+ iterator = iterator->r;
+ }
+ if(st->h) {
+ if(st->t) {
+ st->r = dk3sto_tree_remove(st->r,node_to_remove,st,&back,&node_to_remove);
+ } else {
+ st->r = dk3sto_list_remove(st->r,node_to_remove,st,&back,&node_to_remove);
+ }
+ } else {
+ st->r = dk3sto_unsorted_remove(st->r,node_to_remove);
+ }
+ node_to_remove->l = node_to_remove->r = node_to_remove->p = NULL;
+ node_to_remove->o = NULL;
+ dk3_delete(node_to_remove);
+ }
+ } $? "- dk3sto_remove %d", back
+ return back;
+}
+
+
+
+int
+dk3sto_add(dk3_sto_t *st, void *o)
+{
+ int back = 0;
+ dk3_sto_node_t *n = NULL; /* New node. */
+ $? "+ dk3sto_add %!8s %!8s", TR_8PTR(st), TR_8PTR(o)
+ if(st && o) {
+ if(st->app) {
+ n = dk3_new_app(dk3_sto_node_t,1,((dk3_app_t *)(st->app))) ;
+ } else {
+ n = dk3_new(dk3_sto_node_t,1);
+ }
+ if(n) {
+ dk3sto_node_init_for_object(n,o,st,st->c);
+ if(st->h) {
+ if(st->t) {
+ st->r = dk3sto_tree_add(st->r, n, st);
+ } else {
+ st->r = dk3sto_list_add(st->r, n, st);
+ }
+ } else {
+ st->r = dk3sto_unsorted_add(st->r, n);
+ }
+ back = 1;
+ }
+ } $? "- dk3sto_add %d", back
+ return back;
+}
+
+
+
+dk3_sto_it_t *
+dk3sto_it_open(dk3_sto_t *st)
+{
+ dk3_sto_it_t *back = NULL;
+ $? "+ dk3sto_it_open %!8s", TR_8PTR(st)
+ if(st) {
+ if(st->app) {
+ back = dk3_new_app(dk3_sto_it_t,1,((dk3_app_t *)(st->app))) ;
+ } else {
+ back = dk3_new(dk3_sto_it_t,1);
+ }
+ if(back) {
+ back->s = st;
+ back->l = NULL;
+ back->r = (dk3_sto_it_t *)(st->i);
+ back->c = NULL;
+ st->i = (void *)back;
+ }
+ } $? "- dk3sto_it_open %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+void
+dk3sto_it_close(dk3_sto_it_t *it)
+{
+ dk3_sto_it_t *l = NULL; /* Left iterator. */
+ dk3_sto_it_t *r = NULL; /* Right iterator. */
+ dk3_sto_t *s = NULL; /* The storage. */
+ $? "+ dk3sto_it_close %!8s", TR_8PTR(it)
+ if(it) {
+ s = it->s;
+ l = it->l;
+ r = it->r;
+ if(l) {
+ l->r = r;
+ } else {
+ s->i = (void *)(r);
+ }
+ if(r) {
+ r->l = l;
+ }
+ it->s = NULL;
+ it->l = it->r = NULL;
+ it->c = NULL;
+ dk3_delete(it) ;
+ } $? "- dk3sto_it_close"
+}
+
+
+
+void
+dk3sto_it_reset(dk3_sto_it_t *it)
+{
+ $? "+ dk3sto_it_reset %!8s", TR_8PTR(it)
+ if(it) {
+ it->c = NULL;
+ } $? "- dk3sto_it_reset"
+}
+
+
+
+void *
+dk3sto_it_next(dk3_sto_it_t *it)
+{
+ void *back = NULL;
+ $? "+ dk3sto_it_next %!8s", TR_8PTR(it)
+ if(it) {
+ if(it->s) {
+ if((it->s)->h) {
+ if((it->s)->t) {
+ it->c = dk3sto_tree_find_next_node(it->c, (it->s)->r);
+ } else {
+ it->c = dk3sto_list_find_next_node(it->c, (it->s)->r);
+ }
+ } else {
+ it->c = dk3sto_unsorted_find_next_node(it->c, (it->s)->r);
+ }
+ if(it->c) {
+ back = (it->c)->o;
+ }
+ }
+ } $? "- dk3sto_it_next %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+void *
+dk3sto_it_find_exact(dk3_sto_it_t *i, void const *o)
+{
+ void *back = NULL;
+ $? "+ dk3sto_it_find_exact %!8s %!8s", TR_8PTR(i), TR_8PTR(o)
+ if(i && o) {
+ if(i->s) {
+ if((i->s)->h) {
+ if((i->s)->t) {
+ i->c = dk3sto_tree_find_exact((i->s)->r, o, i->s);
+ } else {
+ i->c = dk3sto_list_find_exact((i->s)->r, o, i->s);
+ }
+ } else {
+ i->c = dk3sto_unsorted_find_exact((i->s)->r, o);
+ }
+ }
+ if(i->c) {
+ back = (i->c)->o;
+ }
+ } $? "- dk3sto_it_find_exact %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+void *
+dk3sto_it_find_like(dk3_sto_it_t *i, void const *o, int cr)
+{
+ void *back = NULL;
+ dk3_sto_node_t testnode; /* Test node for comparisons. */
+ dk3_sto_node_t *candidate = NULL; /* Candicate node. */
+ $? "+ dk3sto_it_find_like %!8s %!8s %d", TR_8PTR(i), TR_8PTR(o), cr
+ if(i && o) {
+ if(i->s) {
+ candidate = NULL;
+ if((i->s)->h) {
+ dk3sto_node_init_for_object(&testnode, (void *)o, (i->s), cr);
+ if((i->s)->t) {
+ i->c = dk3sto_tree_find_like((i->s)->r, &testnode, i->s, cr, &candidate);
+ } else {
+ i->c = dk3sto_list_find_like((i->s)->r, &testnode, i->s, cr, &candidate);
+ }
+ } else {
+ i->c = dk3sto_unsorted_find_exact((i->s)->r, o);
+ }
+ if(i->c) {
+ back = (i->c)->o;
+ } else {
+ i->c = candidate;
+ }
+ }
+ } $? "- dk3sto_it_find_like %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+int
+dk3sto_set_eval_c(dk3_sto_t *st, dk3_fct_eval_c_t *f, int cr)
+{
+ int back = 0;
+ $? "+ dk3sto_set_eval_c %!8s %!8s %d", TR_8PTR(st), TR_8PTR(f), cr
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).c = f;
+ st->c = cr;
+ st->h = DK3STO_COMPARE_CHAR;
+ }
+ } $? "- dk3sto_set_eval_c %d", back
+ return back;
+}
+
+
+
+int
+dk3sto_set_eval_uc(dk3_sto_t *st, dk3_fct_eval_uc_t *f, int cr)
+{
+ int back = 0;
+ $? "+ dk3sto_set_eval_uc %!8s %!8s %d", TR_8PTR(st), TR_8PTR(f), cr
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).uc = f;
+ st->c = cr;
+ st->h = DK3STO_COMPARE_UCHAR;
+ }
+ } $? "- dk3sto_set_eval_uc %d", back
+ return back;
+}
+
+
+
+int
+dk3sto_set_eval_s(dk3_sto_t *st, dk3_fct_eval_s_t *f, int cr)
+{
+ int back = 0;
+ $? "+ dk3sto_set_eval_s %!8s %!8s %d", TR_8PTR(st), TR_8PTR(f), cr
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).s = f;
+ st->c = cr;
+ st->h = DK3STO_COMPARE_SHORT;
+ }
+ } $? "- dk3sto_set_eval_s %d", back
+ return back;
+}
+
+
+
+int
+dk3sto_set_eval_us(dk3_sto_t *st, dk3_fct_eval_us_t *f, int cr)
+{
+ int back = 0;
+ $? "+ dk3sto_set_eval_us %!8s %!8s %d", TR_8PTR(st), TR_8PTR(f), cr
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).us = f;
+ st->c = cr;
+ st->h = DK3STO_COMPARE_USHORT;
+ }
+ } $? "- dk3sto_set_eval_us %d", back
+ return back;
+}
+
+
+
+int
+dk3sto_set_eval_i(dk3_sto_t *st, dk3_fct_eval_i_t *f, int cr)
+{
+ int back = 0;
+ $? "+ dk3sto_set_eval_i %!8s %!8s %d", TR_8PTR(st), TR_8PTR(f), cr
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).i = f;
+ st->c = cr;
+ st->h = DK3STO_COMPARE_INT;
+ }
+ } $? "- dk3sto_set_eval_i %d", back
+ return back;
+}
+
+
+
+int
+dk3sto_set_eval_ui(dk3_sto_t *st, dk3_fct_eval_ui_t *f, int cr)
+{
+ int back = 0;
+ $? "+ dk3sto_set_eval_ui %!8s %!8s %d", TR_8PTR(st), TR_8PTR(f), cr
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).ui = f;
+ st->c = cr;
+ st->h = DK3STO_COMPARE_UINT;
+ }
+ } $? "- dk3sto_set_eval_ui %d", back
+ return back;
+}
+
+
+
+int
+dk3sto_set_eval_l(dk3_sto_t *st, dk3_fct_eval_l_t *f, int cr)
+{
+ int back = 0;
+ $? "+ dk3sto_set_eval_l %!8s %!8s %d", TR_8PTR(st), TR_8PTR(f), cr
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).l = f;
+ st->c = cr;
+ st->h = DK3STO_COMPARE_LONG;
+ }
+ } $? "- dk3sto_set_eval_l %d", back
+ return back;
+}
+
+
+
+int
+dk3sto_set_eval_ul(dk3_sto_t *st, dk3_fct_eval_ul_t *f, int cr)
+{
+ int back = 0;
+ $? "+ dk3sto_set_eval_ul %!8s %!8s %d", TR_8PTR(st), TR_8PTR(f), cr
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).ul = f;
+ st->c = cr;
+ st->h = DK3STO_COMPARE_ULONG;
+ }
+ } $? "- dk3sto_set_eval_ul %d", back
+ return back;
+}
+
+
+
+int
+dk3sto_set_eval_f(dk3_sto_t *st, dk3_fct_eval_f_t *f, int cr)
+{
+ int back = 0;
+ $? "+ dk3sto_set_eval_f %!8s %!8s %d", TR_8PTR(st), TR_8PTR(f), cr
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).f = f;
+ st->c = cr;
+ st->h = DK3STO_COMPARE_FLOAT;
+ }
+ } $? "- dk3sto_set_eval_f %d", back
+ return back;
+}
+
+
+
+int
+dk3sto_set_eval_d(dk3_sto_t *st, dk3_fct_eval_d_t *f, int cr)
+{
+ int back = 0;
+ $? "+ dk3sto_set_eval_d %!8s %!8s %d", TR_8PTR(st), TR_8PTR(f), cr
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).d = f;
+ st->c = cr;
+ st->h = DK3STO_COMPARE_DOUBLE;
+ }
+ } $? "- dk3sto_set_eval_d %d", back
+ return back;
+}
+
+
+
+int
+dk3sto_set_comp(dk3_sto_t *st, dk3_fct_comp_t *f, int cr)
+{
+ int back = 0;
+ $? "+ dk3sto_set_eval_d %!8s %!8s %d", TR_8PTR(st), TR_8PTR(f), cr
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).comp = f;
+ st->c = cr;
+ st->h = DK3STO_COMPARE_FCT;
+ }
+ } $? "- dk3sto_set_eval_d %d", back
+ return back;
+}
+
+
+
+int
+dk3sto_use_trees(dk3_sto_t *st,int ok)
+{
+ int back = 0;
+ if(st) {
+ if(!(st->r)) {
+ st->t = (ok ? 1 : 0);
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+void *
+dk3sto_find_root(dk3_sto_t *s)
+{
+ void *back = NULL;
+ if(s) {
+ if(s->r) {
+ back = (s->r)->o;
+ }
+ }
+ return back;
+}
+
+
+
+void *
+dk3sto_it_find_parent(dk3_sto_it_t *i)
+{
+ void *back = NULL;
+ if(i) {
+ if(i->c) {
+ if((i->c)->p) {
+ back = ((i->c)->p)->o;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void *
+dk3sto_it_find_left(dk3_sto_it_t *i)
+{
+ void *back = NULL;
+ if(i) {
+ if(i->c) {
+ if((i->c)->l) {
+ back = ((i->c)->l)->o;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void *
+dk3sto_it_find_right(dk3_sto_it_t *i)
+{
+ void *back = NULL;
+ if(i) {
+ if(i->c) {
+ if((i->c)->r) {
+ back = ((i->c)->r)->o;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void *
+dk3sto_it_find_root(dk3_sto_it_t *i)
+{
+ void *back = NULL;
+ if(i) {
+ if(i->s) {
+ back = dk3sto_find_root(i->s);
+ }
+ }
+ return back;
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dk3sto.h b/support/dktools/dk3sto.h
new file mode 100644
index 0000000000..4a07a573a3
--- /dev/null
+++ b/support/dktools/dk3sto.h
@@ -0,0 +1,290 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3sto.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3sto.h Header file for the dk3sto module.
+*/
+
+#ifndef DK3STO_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3STO_H_INCLUDED 1
+
+
+#line 10 "dk3sto.ctr"
+
+#include "dk3conf.h"
+#include "dk3types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Create new storage.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new storage on succcess, NULL on error.
+ Use dk3sto_close() to destroy the storage when done with it.
+*/
+dk3_sto_t *
+dk3sto_open_app(dk3_app_t *app);
+
+/** Destroy storage, release memory.
+ @param st Storage to destroy.
+*/
+void
+dk3sto_close(dk3_sto_t *st);
+
+/** Remove all pointers from a storage.
+ @param st Storage.
+*/
+void
+dk3sto_remove_all(dk3_sto_t *st);
+
+/** Remove one pointer from storage.
+ @param st Storage.
+ @param o Object pointer to remove.
+ @return 1 on success, 0 on error (not found).
+*/
+int
+dk3sto_remove(dk3_sto_t *st, void *o);
+
+/** Add object pointer to storage.
+ @param st Storage.
+ @param o Object pointer to add.
+ @return 1 on success, 0 on error (not enough memory).
+*/
+int
+dk3sto_add(dk3_sto_t *st, void *o);
+
+/** Create iterator for storage.
+ @param st Storage.
+ @return Pointer to new iterator on success, NULL on error.
+ Use dk3sto_it_close() to destroy the iterator when done with it.
+ When closing/destroying a storage all iterators for that
+ storage are destroyed automatically.
+*/
+dk3_sto_it_t *
+dk3sto_it_open(dk3_sto_t *st);
+
+/** Destroy iterator.
+ @param it Iterator to destroy.
+*/
+void
+dk3sto_it_close(dk3_sto_it_t *it);
+
+/** Reset iterator (next call to dk3sto_it_next() will return the
+ first object pointer.
+ @param it Iterator.
+*/
+void
+dk3sto_it_reset(dk3_sto_it_t *it);
+
+/** Return next object pointer.
+ @param it Iterator.
+ @return Pointer to next object on success, NULL on error
+ (no more pointers available).
+*/
+void *
+dk3sto_it_next(dk3_sto_it_t *it);
+
+/** Find a pointer exactly.
+ @param i Iterator.
+ @param o Object pointer.
+ @return Object pointer on success, NULL on error (object not found).
+ The next calls to dk3sto_it_next() will return pointers to objects
+ after the specified object \a o.
+*/
+void *
+dk3sto_it_find_exact(dk3_sto_it_t *i, void const *o);
+
+/** Find object pointer for object evaluating equally to \a o.
+ @param i Iterator.
+ @param o Object pointer.
+ @param cr Comparison criteria.
+ @return Object pointer on success, NULL on error (no such object).
+*/
+void *
+dk3sto_it_find_like(dk3_sto_it_t *i, void const *o, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to a char.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sto_set_eval_c(dk3_sto_t *st, dk3_fct_eval_c_t *f, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to an unsigned char.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sto_set_eval_uc(dk3_sto_t *st, dk3_fct_eval_uc_t *f, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to a short.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sto_set_eval_s(dk3_sto_t *st, dk3_fct_eval_s_t *f, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to an unsigned short.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sto_set_eval_us(dk3_sto_t *st, dk3_fct_eval_us_t *f, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to an int.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sto_set_eval_i(dk3_sto_t *st, dk3_fct_eval_i_t *f, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to an unsigned int.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sto_set_eval_ui(dk3_sto_t *st, dk3_fct_eval_ui_t *f, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to a long.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sto_set_eval_l(dk3_sto_t *st, dk3_fct_eval_l_t *f, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to an unsigned long.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sto_set_eval_ul(dk3_sto_t *st, dk3_fct_eval_ul_t *f, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to a float.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sto_set_eval_f(dk3_sto_t *st, dk3_fct_eval_f_t *f, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to a double.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sto_set_eval_d(dk3_sto_t *st, dk3_fct_eval_d_t *f, int cr);
+
+/** Set comparison function.
+ @param st Storage.
+ @param f Function comparing two object pointers.
+ @param cr Comparison criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sto_set_comp(dk3_sto_t *st, dk3_fct_comp_t *f, int cr);
+
+/** Allow use of tree structures.
+ This function must be called before adding any data.
+ @param st Storage.
+ @param ok Flag: Trees may be used.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sto_use_trees(dk3_sto_t *st,int ok);
+
+/** Find object pointer at the trees root.
+ @param s Storage.
+*/
+void *
+dk3sto_find_root(dk3_sto_t *s);
+
+/** Find object pointer for the parent node
+ of the last found object.
+ @param i Iterator.
+ @return Object pointer on success, NULL on error.
+*/
+void *
+dk3sto_it_find_parent(dk3_sto_it_t *i);
+
+/** Find object pointer for node on left child of the last found object.
+ @param i Iterator.
+ @return Object pointer on success, NULL on error.
+*/
+void *
+dk3sto_it_find_left(dk3_sto_it_t *i);
+
+/** Find object pointer for node on right child of the last found object.
+ @param i Iterator.
+ @return Object pointer on success, NULL on error.
+*/
+void *
+dk3sto_it_find_right(dk3_sto_it_t *i);
+
+/** Find object pointer at the trees root.
+ @param i Iterator.
+*/
+void *
+dk3sto_it_find_root(dk3_sto_it_t *i);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3str.c b/support/dktools/dk3str.c
new file mode 100644
index 0000000000..4b6067158f
--- /dev/null
+++ b/support/dktools/dk3str.c
@@ -0,0 +1,4640 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3str.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3str.c The dk3str module.
+*/
+
+
+#line 1426 "dk3str.ctr"
+
+#include "dk3all.h"
+
+
+
+
+#line 1431 "dk3str.ctr"
+
+
+/* ************************************************************************ */
+/* * * */
+/* * Static data * */
+/* * * */
+/* ************************************************************************ */
+
+
+#line 1436 "dk3str.ctr"
+
+
+/** The set of whitespace characters.
+*/
+static char const dk3str_c8_def_whsp[] = { " \t\r\n" };
+
+/** The current directory.
+*/
+static char const dk3str_c8_dot[] = { "." };
+
+/** The parent directory.
+*/
+static char const dk3str_c8_dot_dot[] = { ".." };
+
+/** File name separator.
+*/
+static char const dk3str_c8_fnsep[] = {
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+"\\"
+#else
+"/"
+#endif
+};
+
+
+/** Keywords to set boolean values.
+*/
+static char const * const dk3str_c8_bool_kw[] = {
+ "0",
+ "n$o",
+ "of$f",
+ "f$alse",
+ "-",
+ "+",
+ "1",
+ "y$es",
+ "on",
+ "ok",
+ "t$rue",
+ NULL
+};
+
+/** Index of first "true" entry in \a dk3str_c8_bool_kw.
+*/
+#define INDEX_OF_FIRST_BOOLEAN_TRUE 5
+
+
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+/** File name separator character.
+*/
+#define FNS_C8 '\\'
+/** Not the file name separator character.
+*/
+#define NO_FNS_C8 '/'
+#else
+/** File name separator character.
+*/
+#define FNS_C8 '/'
+/** Not the file name separator character.
+*/
+#define NO_FNS_C8 '\\'
+#endif
+
+
+
+/** Default white spaces set.
+*/
+static dk3_c16_t const c16_def_whsp[] = {
+ 0x0020U, 0x0009U, 0x000AU, 0x000DU, 0U
+};
+
+/** The dot for the current directory.
+*/
+static dk3_c16_t const c16_dot[] = {
+ 0x002EU, 0U
+};
+
+/** The dot dot for the parent directory.
+*/
+static dk3_c16_t const c16_dot_dot[] = {
+ 0x002EU, 0x002EU, 0U
+};
+
+/** File name separator (slash or backslash).
+*/
+static dk3_c16_t const c16_fnsep[] = {
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+0x005CU,
+#else
+0x002FU,
+#endif
+0U
+};
+
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+/** File name separator for 16-bit character strings.
+*/
+#define FNS_C16 0x005CU
+/** Not the file name separator for 16-bit character strings.
+*/
+#define NO_FNS_C16 0x002FU
+#else
+/** File name separator for 16-bit character strings.
+*/
+#define FNS_C16 0x002FU
+/** Not the file name separator for 16-bit character strings.
+*/
+#define NO_FNS_C16 0x005CU
+#endif
+
+
+
+/** Default whitespaces set.
+*/
+static dk3_c32_t const c32_def_whsp[] = {
+ 0x00000020UL, 0x00000009UL, 0x0000000AUL, 0x0000000DUL, 0UL
+};
+
+/** The dot is the current directory.
+*/
+static dk3_c32_t const c32_dot[] = {
+ 0x0000002EUL, 0UL
+};
+
+/** The dot dot is the parent directory.
+*/
+static dk3_c32_t const c32_dot_dot[] = {
+ 0x0000002EUL, 0x0000002EUL, 0UL
+};
+
+/** File name separator (slash or backslash).
+*/
+static dk3_c32_t const c32_fnsep[] = {
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+0x0000005CUL,
+#else
+0x0000002FUL,
+#endif
+0U
+};
+
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+/** File name separator for 32-bit character strings.
+*/
+#define FNS_C32 0x0000005CUL
+/** Not a file name separator for 32-bit character strings.
+*/
+#define NO_FNS_C32 0x0000002FUL
+#else
+/** File name separator for 32-bit character strings.
+*/
+#define FNS_C32 0x0000002FUL
+/** Not a file name separator for 32-bit character strings.
+*/
+#define NO_FNS_C32 0x0000005CUL
+#endif
+
+
+
+size_t
+dk3str_c8_len(char const *s)
+{
+ register size_t back; /* Function result. */
+#if DK3_HAVE_STRLEN
+ back = strlen(s);
+#else
+ register char const *ptr; /* Pointer to traverse s. */
+ back = 0; ptr = s;
+ while(*(ptr++)) back++;
+#endif
+ return back;
+}
+
+
+
+size_t
+dk3str_c16_len(dk3_c16_t const *s)
+{
+ register size_t back;
+#if (DK3_HAVE_WCSLEN) && (DK3_SIZEOF_WCHAR_T == 2)
+ back = wcslen(s);
+#else
+#if (DK3_HAVE__WCSLEN) && (DK3_SIZEOF_WCHAR_T == 2)
+ back = _wcslen(s);
+#else
+ register dk3_c16_t const *ptr; /* Traverse string. */
+ back = 0; ptr = s;
+ while(*(ptr++)) back++;
+#endif
+#endif
+ return back;
+}
+
+
+
+size_t
+dk3str_c32_len(dk3_c32_t const *s)
+{
+ register size_t back;
+#if (DK3_HAVE_WCSLEN) && (DK3_SIZEOF_WCHAR_T == 4)
+ back = wcslen(s);
+#else
+#if (DK3_HAVE__WCSLEN) && (DK3_SIZEOF_WCHAR_T == 4)
+ back = _wcslen(s);
+#else
+ register dk3_c32_t const *ptr; /* Traverse source string. */
+ back = 0; ptr = s;
+ while(*(ptr++)) back++;
+#endif
+#endif
+ return back;
+}
+
+
+
+size_t
+dk3str_len(dkChar const *s)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_len(s));
+#else
+ return(dk3str_c16_len(s));
+#endif
+#else
+ return(dk3str_c8_len(s));
+#endif
+}
+
+
+
+int
+dk3str_c8_cmp(char const *s1, char const *s2)
+{
+ register int back; /* Function result. */
+#if DK3_HAVE_STRCMP
+ back = strcmp(s1, s2);
+#else
+ register char const *p1; /* Pointer to traverse s1. */
+ register char const *p2; /* Pointer to traverse s2. */
+ register int cc; /* Flag: Can continue. */
+ back = 0; p1 = s1; p2 = s2; cc = 1;
+ while((cc) && (back == 0)) {
+ if(*p1 > *p2) {
+ back = 1;
+ } else {
+ if(*p1 < *p2) {
+ back = -1;
+ } else {
+ if((*p1) && (*p2)) {
+ p1++; p2++;
+ } else {
+ cc = 0;
+ }
+ }
+ }
+ }
+#endif
+ return back;
+}
+
+
+
+int
+dk3str_c16_cmp(dk3_c16_t const *s1, dk3_c16_t const *s2)
+{
+ register int back;
+#if (DK3_HAVE_WCSCPY) && (DK3_SIZEOF_WCHAR_T == 2)
+ back = wcscmp(s1, s2);
+#else
+#if (DK3_HAVE__WCSCPY) && (DK3_SIZEOF_WCHAR_T == 2)
+ back = _wcscmp(s1, s2);
+#else
+ register dk3_c16_t const *p1; /* Traverse left string. */
+ register dk3_c16_t const *p2; /* Traverse right string. */
+ register int cc; /* Flag: Can continue. */
+
+ back = 0; p1 = s1; p2 = s2; cc = 1;
+ while((cc) && (back == 0)) {
+ if(*p1 > *p2) {
+ back = 1;
+ } else {
+ if(*p1 < *p2) {
+ back = -1;
+ } else {
+ if((*p1) && (*p2)) {
+ p1++; p2++;
+ } else {
+ cc = 0;
+ }
+ }
+ }
+ }
+#endif
+#endif
+ return back;
+}
+
+
+
+int
+dk3str_c32_cmp(dk3_c32_t const *s1, dk3_c32_t const *s2)
+{
+ register int back;
+#if (DK3_HAVE_WCSCMP) && (DK3_SIZEOF_WCHAR_T == 4)
+ back = wcscmp(s1, s2);
+#else
+#if (DK3_HAVE__WCSCMP) && (DK3_SIZEOF_WCHAR_T == 4)
+ back = _wcscmp(s1, s2);
+#else
+ register dk3_c32_t const *p1; /* Traverse left string. */
+ register dk3_c32_t const *p2; /* Traverse right string. */
+ register int cc; /* Flag: Can continue. */
+
+ back = 0; p1 = s1; p2 = s2; cc = 1;
+ while((cc) && (back == 0)) {
+ if(*p1 > *p2) {
+ back = 1;
+ } else {
+ if(*p1 < *p2) {
+ back = -1;
+ } else {
+ if((*p1) && (*p2)) {
+ p1++; p2++;
+ } else {
+ cc = 0;
+ }
+ }
+ }
+ }
+#endif
+#endif
+ return back;
+}
+
+
+
+int
+dk3str_cmp(dkChar const *s1, dkChar const *s2)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_cmp(s1, s2));
+#else
+ return(dk3str_c16_cmp(s1, s2));
+#endif
+#else
+ return(dk3str_c8_cmp(s1, s2));
+#endif
+}
+
+
+
+int
+dk3str_c8_casecmp(char const *s1, char const *s2)
+{
+ register int back; /* Function result. */
+#if DK3_HAVE_STRCASECMP
+ back = strcasecmp(s1, s2);
+#else
+#if DK3_HAVE_STRICMP && (!DK3_ON_WINDOWS)
+ back = stricmp(s1, s2);
+#else
+#if DK3_HAVE__STRICMP || DK3_ON_WINDOWS
+ back = _stricmp(s1, s2);
+#else
+ register char const *p1; /* Pointer to traverse s1. */
+ register char const *p2; /* Pointer to traverse s2. */
+ register char c1; /* Current character from s1. */
+ register char c2; /* Current character from s2. */
+ register int cc; /* Flag: Can continue. */
+ back = 0; p1 = s1; p2 = s2; cc = 1;
+ while((cc) && (back == 0)) {
+ c1 = *p1; c2 = *p2;
+ if((c1 >= 'A') && (c1 <= 'Z')) { c1 = 'a' + (c1 - 'A'); }
+ if((c2 >= 'A') && (c2 <= 'Z')) { c2 = 'a' + (c2 - 'A'); }
+ if(c1 > c2) {
+ back = 1;
+ } else {
+ if(c1 < c2) {
+ back = -1;
+ } else {
+ if((c1) && (c2)) {
+ p1++; p2++;
+ } else {
+ cc = 0;
+ }
+ }
+ }
+ }
+#endif
+#endif
+#endif
+ return back;
+}
+
+
+
+int
+dk3str_c16_casecmp(dk3_c16_t const *s1, dk3_c16_t const *s2)
+{
+ register int back;
+#if (DK3_HAVE_WCSICMP) && (DK3_SIZEOF_WCHAR_T == 2)
+ back = wcsicmp(s1, s2);
+#else
+#if (DK3_HAVE__WCSICMP) && (DK3_SIZEOF_WCHAR_T == 2)
+ back = _wcsicmp(s1, s2);
+#else
+ register dk3_c16_t const *p1; /* Traverse left string. */
+ register dk3_c16_t const *p2; /* Traverse right string. */
+ register dk3_c16_t c1; /* Left character. */
+ register dk3_c16_t c2; /* Right character. */
+ register int cc; /* Flag: Can continue. */
+
+
+#line 1850 "dk3str.ctr"
+ back = 0; p1 = s1; p2 = s2; cc = 1;
+ while((cc) && (back == 0)) {
+ c1 = *p1; c2 = *p2;
+ if((c1 >= 0x0041U) && (c1 <= 0x005AU)) { c1 = 0x0061U + (c1 - 0x0041U); }
+ if((c2 >= 0x0041U) && (c2 <= 0x005AU)) { c2 = 0x0061U + (c2 - 0x0041U); }
+ if(c1 > c2) {
+ back = 1;
+ } else {
+ if(c1 < c2) {
+ back = -1;
+ } else {
+ if((c1) && (c2)) {
+ p1++; p2++;
+ } else {
+ cc = 0;
+ }
+ }
+ }
+ }
+
+#line 1869 "dk3str.ctr"
+#endif
+#endif
+ return back;
+}
+
+
+
+int
+dk3str_c32_casecmp(dk3_c32_t const *s1, dk3_c32_t const *s2)
+{
+ register int back;
+#if (DK3_HAVE_WCSICMP) && (DK3_SIZEOF_WCHAR_T == 4)
+ back = wcsicmp(s1, s2);
+#else
+#if (DK3_HAVE__WCSICMP) && (DK3_SIZEOF_WCHAR_T == 4)
+ back = _wcsicmp(s1, s2);
+#else
+ register dk3_c32_t const *p1; /* Traverse left string. */
+ register dk3_c32_t const *p2; /* Traverse right string. */
+ register dk3_c32_t c1; /* Left character. */
+ register dk3_c32_t c2; /* Right character. */
+ register int cc; /* Flag: Can continue. */
+
+ back = 0; p1 = s1; p2 = s2; cc = 1;
+ while((cc) && (back == 0)) {
+ c1 = *p1; c2 = *p2;
+ if((c1 >= (dk3_c32_t)0x00000041UL) && (c1 <= (dk3_c32_t)0x0000005AUL)) {
+ c1 = 0x00000061UL + (c1 - 0x00000041UL);
+ }
+ if((c2 >= (dk3_c32_t)0x00000041UL) && (c2 <= (dk3_c32_t)0x0000005AUL)) {
+ c2 = 0x00000061UL + (c2 - 0x00000041UL);
+ }
+ if(c1 > c2) {
+ back = 1;
+ } else {
+ if(c1 < c2) {
+ back = -1;
+ } else {
+ if((c1) && (c2)) {
+ p1++; p2++;
+ } else {
+ cc = 0;
+ }
+ }
+ }
+ }
+#endif
+#endif
+ return back;
+}
+
+
+
+int
+dk3str_casecmp(dkChar const *s1, dkChar const *s2)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_casecmp(s1, s2));
+#else
+ return(dk3str_c16_casecmp(s1, s2));
+#endif
+#else
+ return(dk3str_c8_casecmp(s1, s2));
+#endif
+}
+
+
+
+int
+dk3str_fncmp(dkChar const *s1, dkChar const *s2)
+{
+#if DK3_ON_WINDOWS || DK3_HAVE_FNCASEINS
+ return(dk3str_casecmp(s1, s2));
+#else
+ return(dk3str_cmp(s1, s2));
+#endif
+}
+
+
+int
+dk3str_c8_ncmp(char const *s1, char const *s2, size_t n)
+{
+ register int back; /* Function result. */
+#if DK3_HAVE_STRNCMP
+ back = strncmp(s1, s2, n);
+#else
+ register char const *p1; /* Pointer to traverse s1. */
+ register char const *p2; /* Pointer to traverse s2. */
+ register size_t max; /* Register copy of n. */
+ register size_t used; /* Number of chars already used. */
+ back = 0; p1 = s1; p2 = s2; max = n; used = 0;
+ while((used < max) && (back == 0)) {
+ if(*p1 > *p2) {
+ back = 1;
+ } else {
+ if(*p1 < *p2) {
+ back = -1;
+ } else {
+ if((*p1) && (*p2)) {
+ p1++; p2++; used++;
+ } else {
+ used = max;
+ }
+ }
+ }
+ }
+#endif
+ return back;
+}
+
+
+
+int
+dk3str_c16_ncmp(dk3_c16_t const *s1, dk3_c16_t const *s2, size_t n)
+{
+ register int back;
+#if (DK3_HAVE_WCSNCMP) && (DK3_SIZEOF_WCHAR_T == 2)
+ back = wcsncmp(s1, s2, n);
+#else
+#if (DK3_HAVE__WCSNCMP) && (DK3_SIZEOF_WCHAR_T == 2)
+ back = _wcsncmp(s1, s2, n);
+#else
+ register dk3_c16_t const *p1; /* Traverse left string. */
+ register dk3_c16_t const *p2; /* Traverse right string. */
+ register size_t max; /* Maximum number of characters to compare. */
+ register size_t used; /* Number of characters already compared. */
+
+ back = 0; p1 = s1; p2 = s2; max = n; used = 0;
+ while((used < max) && (back == 0)) {
+ if(*p1 > *p2) {
+ back = 1;
+ } else {
+ if(*p1 < *p2) {
+ back = -1;
+ } else {
+ if((*p1) && (*p2)) {
+ p1++; p2++; used++;
+ } else {
+ used = max;
+ }
+ }
+ }
+ }
+#endif
+#endif
+ return back;
+}
+
+
+
+int
+dk3str_c32_ncmp(dk3_c32_t const *s1, dk3_c32_t const *s2, size_t n)
+{
+ register int back;
+#if (DK3_HAVE_WCSNCMP) && (DK3_SIZEOF_WCHAR_T == 4)
+ back = wcsncmp(s1, s2, n);
+#else
+#if (DK3_HAVE__WCSNCMP) && (DK3_SIZEOF_WCHAR_T == 4)
+ back = _wcsncmp(s1, s2, n);
+#else
+ register dk3_c32_t const *p1; /* Traverse left string. */
+ register dk3_c32_t const *p2; /* Traverse right string. */
+ register size_t max; /* Maximum number of characters to compare. */
+ register size_t used; /* Number of characters used. */
+
+ back = 0; p1 = s1; p2 = s2; max = n; used = 0;
+ while((used < max) && (back == 0)) {
+ if(*p1 > *p2) {
+ back = 1;
+ } else {
+ if(*p1 < *p2) {
+ back = -1;
+ } else {
+ if((*p1) && (*p2)) {
+ p1++; p2++; used++;
+ } else {
+ used = max;
+ }
+ }
+ }
+ }
+#endif
+#endif
+ return back;
+}
+
+
+
+int
+dk3str_ncmp(dkChar const *s1, dkChar const *s2, size_t n)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_ncmp(s1, s2, n));
+#else
+ return(dk3str_c16_ncmp(s1, s2, n));
+#endif
+#else
+ return(dk3str_c8_ncmp(s1, s2, n));
+#endif
+}
+
+
+
+char *
+dk3str_c8_chr(char const *s, char c)
+{
+ register char *back; /* Function result. */
+#if DK3_HAVE_STRCHR
+ back = strchr(s, c);
+#else
+ register char const *ptr; /* Pointer to traverse s. */
+ register char chr; /* Register copy of c. */
+ back = NULL; ptr = s; chr = c;
+ while((*ptr) && (back == NULL)) {
+ if(*ptr == chr) { back = (char *)ptr; } else { ptr++; }
+ }
+#endif
+ return back;
+}
+
+
+
+dk3_c16_t *
+dk3str_c16_chr(dk3_c16_t const *s, dk3_c16_t c)
+{
+ register dk3_c16_t *back;
+#if (DK3_HAVE_WCSCHR) && (DK3_SIZEOF_WCHAR_T == 2)
+ back = wcschr(s, c);
+#else
+#if (DK3_HAVE__WCSCHR) && (DK3_SIZEOF_WCHAR_T == 2)
+ back = _wcschr(s, c);
+#else
+ register dk3_c16_t const *ptr; /* Traverse source string. */
+ register dk3_c16_t chr; /* Character to search for. */
+ back = NULL; ptr = s; chr = c;
+ while((*ptr) && (back == NULL)) {
+ if(*ptr == chr) { back = (dk3_c16_t *)ptr; } else { ptr++; }
+ }
+#endif
+#endif
+ return back;
+}
+
+
+
+dk3_c32_t *
+dk3str_c32_chr(dk3_c32_t const *s, dk3_c32_t c)
+{
+ register dk3_c32_t *back;
+#if (DK3_HAVE_WCSCHR) && (DK3_SIZEOF_WCHAR_T == 4)
+ back = wcschr(s, c);
+#else
+#if (DK3_HAVE__WCSCHR) && (DK3_SIZEOF_WCHAR_T == 4)
+ back = _wcschr(s, c);
+#else
+ register dk3_c32_t const *ptr; /* Traverse source string. */
+ register dk3_c32_t chr; /* Character to find. */
+
+ back = NULL; ptr = s; chr = c;
+ while((*ptr) && (back == NULL)) {
+ if(*ptr == chr) { back = (dk3_c32_t *)ptr; } else { ptr++; }
+ }
+#endif
+#endif
+ return back;
+}
+
+
+
+dkChar *
+dk3str_chr(dkChar const *s, dkChar c)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_chr(s, c));
+#else
+ return(dk3str_c16_chr(s, c));
+#endif
+#else
+ return(dk3str_c8_chr(s, c));
+#endif
+}
+
+
+char *
+dk3str_c8_rchr(char const *s, char c)
+{
+ register char *back; /* Function result. */
+#if DK3_HAVE_STRRCHR
+ back = strrchr(s, c);
+#else
+ register char const *ptr; /* Pointer to traverse s. */
+ register char chr; /* Register copy of c. */
+ back = NULL; ptr = s; chr = c;
+ while(*ptr) {
+ if(*ptr == chr) { back = (char *)ptr; }
+ ptr++;
+ }
+#endif
+ return back;
+}
+
+
+
+
+dk3_c16_t *
+dk3str_c16_rchr(dk3_c16_t const *s, dk3_c16_t c)
+{
+ register dk3_c16_t *back;
+#if (DK3_HAVE_WCSRCHR) && (DK3_SIZEOF_WCHAR_T == 2)
+ back = wcsrchr(s, c);
+#else
+#if (DK3_HAVE__WCSRCHR) && (DK3_SIZEOF_WCHAR_T == 2)
+ back = _wcsrchr(s, c);
+#else
+ register dk3_c16_t const *ptr; /* Traverse the string. */
+ register dk3_c16_t chr; /* Character to search for. */
+ back = NULL; ptr = s; chr = c;
+ while(*ptr) {
+ if(*ptr == chr) { back = (dk3_c16_t *)ptr; }
+ ptr++;
+ }
+#endif
+#endif
+ return back;
+}
+
+
+
+dk3_c32_t *
+dk3str_c32_rchr(dk3_c32_t const *s, dk3_c32_t c)
+{
+ register dk3_c32_t *back;
+#if (DK3_HAVE_WCSRCHR) && (DK3_SIZEOF_WCHAR_T == 4)
+ back = wcsrchr(s, c);
+#else
+#if (DK3_HAVE__WCSRCHR) && (DK3_SIZEOF_WCHAR_T == 4)
+ back = _wcsrchr(s, c);
+#else
+ register dk3_c32_t const *ptr; /* Traverse source string. */
+ register dk3_c32_t chr; /* Character to search for. */
+
+ back = NULL; ptr = s; chr = c;
+ while(*ptr) {
+ if(*ptr == chr) { back = (dk3_c32_t *)ptr; }
+ ptr++;
+ }
+#endif
+#endif
+ return back;
+}
+
+
+
+dkChar *
+dk3str_rchr(dkChar const *s, dkChar c)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_rchr(s, c));
+#else
+ return(dk3str_c16_rchr(s, c));
+#endif
+#else
+ return(dk3str_c8_rchr(s, c));
+#endif
+}
+
+
+void
+dk3str_c8_cpy(char *d, char const *s)
+{
+ register char *dp; /* Destination buffer pointer. */
+ register char const *sp; /* Source buffer pointer. */
+ register char x;
+ dp = d; sp = s;
+ while(*sp) { x = *(sp++); *(dp++) = x; }
+ *dp = '\0';
+}
+
+
+
+void
+dk3str_c16_cpy(dk3_c16_t *d, dk3_c16_t const *s)
+{
+ register dk3_c16_t *dp; /* Destination pointer. */
+ register dk3_c16_t const *sp; /* Source pointer. */
+ register dk3_c16_t x; /* Current character. */
+
+ dp = d; sp = s;
+ while(*sp) { x = *(sp++); *(dp++) = x; }
+ *dp = 0U;
+}
+
+
+
+void
+dk3str_c32_cpy(dk3_c32_t *d, dk3_c32_t const *s)
+{
+ register dk3_c32_t *dp; /* Destination pointer. */
+ register dk3_c32_t const *sp; /* Source pointer. */
+ register dk3_c32_t x; /* Current character. */
+ dp = d; sp = s;
+ while(*sp) { x = *(sp++); *(dp++) = x; }
+ *dp = 0UL;
+}
+
+
+
+void
+dk3str_cpy(dkChar *d, dkChar const *s)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ dk3str_c32_cpy(d, s);
+#else
+ dk3str_c16_cpy(d, s);
+#endif
+#else
+ dk3str_c8_cpy(d, s);
+#endif
+}
+
+
+void
+dk3str_c8_cpy_not_overlapped(char *d, char const *s)
+{
+#if DK3_HAVE_STRCPY
+ strcpy(d, s);
+#else
+#if DK3_HAVE_STRLEN
+ size_t sz;
+ int ec = 0;
+ sz = dk3mem_add_size_t(1, strlen(s), &ec);
+ if((0 != sz) && (0 == ec)) {
+ dk3mem_cpy(d,s,sz);
+ } else {
+ dk3str_c8_cpy(d, s);
+ }
+#else
+ dk3str_c8_cpy(d, s);
+#endif
+#endif
+}
+
+
+
+void
+dk3str_c16_cpy_not_overlapped(dk3_c16_t *d, dk3_c16_t const *s)
+{
+#if (DK3_HAVE_WCSCPY) && (DK3_SIZEOF_WCHAR_T == 2)
+ wcscpy(d, s);
+#else
+#if (DK3_HAVE__WCSCPY) && (DK3_SIZEOF_WCHAR_T == 2)
+ _wcscpy(d, s);
+#else
+#if (DK3_HAVE_WCSLEN) && (DK3_SIZEOF_WCHAR_T == 2)
+ size_t sz;
+ int ec = 0;
+ sz = dk3mem_mul_size_t(2, dk3mem_add_size_t(1, wcslen(s), &ec), &ec);
+ if((0 != sz) && (0 == ec)) {
+ dk3mem_cpy(d, s, sz);
+ } else {
+ dk3str_c16_cpy(d,s);
+ }
+#else
+#if (DK3_HAVE__WCSLEN) && (DK3_SIZEOF_WCHAR_T == 2)
+ size_t sz;
+ int ec = 0;
+ sz = dk3mem_mul_size_t(2, dk3mem_add_size_t(1, _wcslen(s), &ec), &ec);
+ if((0 != sz) && (0 == ec)) {
+ dk3mem_cpy(d, s, sz);
+ } else {
+ dk3str_c16_cpy(d,s);
+ }
+#else
+ dk3str_c16_cpy(d,s);
+#endif
+#endif
+#endif
+#endif
+}
+
+
+
+void
+dk3str_c32_cpy_not_overlapped(dk3_c32_t *d, dk3_c32_t const *s)
+{
+#if (DK3_HAVE_WCSCPY) && (DK3_SIZEOF_WCHAR_T == 4)
+ wcscpy(d, s);
+#else
+#if (DK3_HAVE__WCSCPY) && (DK3_SIZEOF_WCHAR_T == 4)
+ _wcscpy(d, s);
+#else
+#if (DK3_HAVE_WCSLEN) && (DK3_SIZEOF_WCHAR_T == 4)
+ size_t sz;
+ int ec = 0;
+ sz = dk3mem_mul_size_t(4, dk3mem_add_size_t(1, wcslen(s), &ec), &ec);
+ if((0 != sz) && (0 == ec)) {
+ dk3mem_cpy(d, s, sz);
+ } else {
+ dk3str_c32_cpy(d,s);
+ }
+#else
+#if (DK3_HAVE__WCSLEN) && (DK3_SIZEOF_WCHAR_T == 4)
+ size_t sz;
+ int ec = 0;
+ sz = dk3mem_mul_size_t(4, dk3mem_add_size_t(1, _wcslen(s), &ec), &ec);
+ if((0 != sz) && (0 == ec)) {
+ dk3mem_cpy(d, s, sz);
+ } else {
+ dk3str_c32_cpy(d,s);
+ }
+#else
+ dk3str_c32_cpy(d,s);
+#endif
+#endif
+#endif
+#endif
+}
+
+
+
+void
+dk3str_cpy_not_overlapped(dkChar *d, dkChar const *s)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ dk3str_c32_cpy_not_overlapped(d, s);
+#else
+ dk3str_c16_cpy_not_overlapped(d, s);
+#endif
+#else
+ dk3str_c8_cpy_not_overlapped(d, s);
+#endif
+}
+
+
+void
+dk3str_c8_ncpy(char *d, char const *s, size_t n)
+{
+#if DK3_HAVE_STRNCPY
+ strncpy(d,s,n);
+ d[n-1] = '\0';
+#else
+ register char *dp; /* Destination buffer pointer. */
+ register char const *sp; /* Source buffer pointer. */
+ register size_t max; /* Register copy of n. */
+ register size_t used; /* Number of characters already copied. */
+ register char x;
+ dp = d; sp = s; max = n; used = 0;
+ while((*sp) && (used < max)) { x = *(sp++); *(dp++) = x; used++; }
+ if(used < max) { *dp = '\0'; }
+ else { d[max - 1] = '\0'; }
+#endif
+}
+
+
+
+void
+dk3str_c16_ncpy(dk3_c16_t *d, dk3_c16_t const *s, size_t n)
+{
+#if (DK3_HAVE_WCSNCPY) && (DK3_SIZEOF_WCHAR_T == 2)
+ wcsncpy(d,s,n);
+ d[n-1] = 0U;
+#else
+#if (DK3_HAVE__WCSNCPY) && (DK3_SIZEOF_WCHAR_T == 2)
+ _wcsncpy(d,s,n);
+ d[n-1] = 0U;
+#else
+ register dk3_c16_t *dp; /* Destionation pointer. */
+ register dk3_c16_t const *sp; /* Source pointer. */
+ register dk3_c16_t x; /* Current character. */
+ register size_t max; /* Maximum number of characters to copy. */
+ register size_t used; /* Characters already copied. */
+
+ dp = d; sp = s; max = n; used = 0;
+ while((*sp) && (used < max)) { x = *(sp++); *(dp++) = x; used++; }
+ if(used < max) { *dp = 0U; }
+ else { d[max - 1] = 0U; }
+#endif
+#endif
+}
+
+
+
+void
+dk3str_c32_ncpy(dk3_c32_t *d, dk3_c32_t const *s, size_t n)
+{
+#if (DK3_HAVE_WCSNCPY) && (DK3_SIZEOF_WCHAR_T == 4)
+ wcsncpy(d,s,n);
+ d[n-1] = 0UL;
+#else
+#if (DK3_HAVE__WCSNCPY) && (DK3_SIZEOF_WCHAR_T == 4)
+ _wcsncpy(d,s,n);
+ d[n-1] = 0UL;
+#else
+ register dk3_c32_t *dp; /* Destination pointer. */
+ register dk3_c32_t const *sp; /* Source pointer. */
+ register dk3_c32_t x; /* Current character. */
+ register size_t max; /* Maximum number of characters to copy. */
+ register size_t used; /* Number of characters copied. */
+
+ dp = d; sp = s; max = n; used = 0;
+ while((*sp) && (used < max)) { x = *(sp++); *(dp++) = x; used++; }
+ if(used < max) { *dp = 0UL; }
+ else { d[max - 1] = 0UL; }
+#endif
+#endif
+}
+
+
+
+void
+dk3str_ncpy(dkChar *d, dkChar const *s, size_t n)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ dk3str_c32_ncpy(d, s, n);
+#else
+ dk3str_c16_ncpy(d, s, n);
+#endif
+#else
+ dk3str_c8_ncpy(d, s, n);
+#endif
+}
+
+
+
+void
+dk3str_c8_cat(char *d, char const *s)
+{
+#if DK3_HAVE_STRCAT
+ strcat(d, s);
+#else
+ register char *dp; /* Destination buffer pointer. */
+ register char const *sp; /* Source buffer pointer. */
+ register char x;
+ dp = d; sp = s;
+ while(*dp) dp++;
+ while(*sp) { x = *(sp++); *(dp++) = x; }
+ *dp = '\0';
+#endif
+}
+
+
+
+void
+dk3str_c16_cat(dk3_c16_t *d, dk3_c16_t const *s)
+{
+#if (DK3_HAVE_WCSCAT) && (DK3_SIZEOF_WCHAR_T == 2)
+ wcscat(d, s);
+#else
+#if (DK3_HAVE__WCSCAT) && (DK3_SIZEOF_WCHAR_T == 2)
+ _wcscat(d, s);
+#else
+ register dk3_c16_t *dp; /* Destination pointer. */
+ register dk3_c16_t const *sp; /* Source pointer. */
+ register dk3_c16_t x; /* Current character. */
+ dp = d; sp = s;
+ while(*dp) dp++;
+ while(*sp) { x = *(sp++); *(dp++) = x; }
+ *dp = 0U;
+#endif
+#endif
+}
+
+
+
+void
+dk3str_c32_cat(dk3_c32_t *d, dk3_c32_t const *s)
+{
+#if (DK3_HAVE_WCSCAT) && (DK3_SIZEOF_WCHAR_T == 4)
+ wcscat(d, s);
+#else
+#if (DK3_HAVE__WCSCAT) && (DK3_SIZEOF_WCHAR_T == 4)
+ _wcscat(d, s);
+#else
+ register dk3_c32_t *dp; /* Destination pointer. */
+ register dk3_c32_t const *sp; /* Source pointer. */
+ register dk3_c32_t x; /* Current character. */
+
+ dp = d; sp = s;
+ while(*dp) dp++;
+ while(*sp) { x = *(sp++); *(dp++) = x; }
+ *dp = 0UL;
+#endif
+#endif
+}
+
+
+
+void
+dk3str_cat(dkChar *d, dkChar const *s)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ dk3str_c32_cat(d, s);
+#else
+ dk3str_c16_cat(d, s);
+#endif
+#else
+ dk3str_c8_cat(d, s);
+#endif
+}
+
+
+
+/** Report memory allocation error.
+ @param app Application structure.
+ @param elsize Size of one character.
+ @param nelem Number of characters required.
+*/
+static
+void
+dk3str_memory_error(dk3_app_t *app, size_t elsize, size_t nelem)
+{
+#if VERSION_BEFORE_20140716
+ dkChar bu1[64];
+ unsigned long prod;
+ prod = (unsigned long)elsize * (unsigned long)nelem;
+ dk3sf_sprintf3(bu1, dkT("%lu"), prod);
+ dk3app_log_i3(app, DK3_LL_ERROR, 12, 13, bu1);
+#else
+ dkChar bu1[64];
+ dk3_um_t prod;
+ int mec = 0;
+ prod = dk3ma_um_mul_ok((dk3_um_t)elsize, (dk3_um_t)nelem, &mec);
+ if (0 == mec) {
+ if (dk3ma_um_to_string(bu1, DK3_SIZEOF(bu1,dkChar), (dk3_um_t)prod)) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 12, 13, bu1);
+ }
+ } else {
+ /* Math overflow in size calculation */
+ dk3app_log_i1(app, DK3_LL_ERROR, 15);
+ }
+#endif
+}
+
+
+
+char *
+dk3str_c8_dup_app(char const *s, dk3_app_t *app)
+{
+ char *back;
+#if DK3_HAVE_STRDUP && (!DK3_ON_WINDOWS)
+ back = strdup(s);
+ if(!(back)) {
+ if(app) {
+ dk3str_memory_error(app, 1, (1+strlen(s)));
+ }
+ }
+#else
+#if DK3_HAVE__STRDUP || DK3_ON_WINDOWS
+ back = _strdup(s);
+ if(!(back)) {
+ if(app) {
+ dk3str_memory_error(app, 1, (1+strlen(s)));
+ }
+ }
+#else
+ size_t sz;
+ sz = 1 + dk3str_c8_len(s);
+ if(app) {
+ back = dk3_new_app(char,sz,app);
+ } else {
+ back = dk3_new(char,sz);
+ }
+ if(back) {
+ dk3str_c8_cpy_not_overlapped(back, s);
+ }
+#endif
+#endif
+ return back;
+}
+
+
+
+dk3_c16_t *
+dk3str_c16_dup_app(dk3_c16_t const *s, dk3_app_t *app)
+{
+ dk3_c16_t *back;
+#if (DK3_HAVE_WCSDUP) && (DK3_SIZEOF_WCHAR_T == 2)
+ back = wcsdup(s);
+ if(!(back)) {
+ if(app) {
+ dk3str_memory_error(app, 2, (1 + dk3str_c16_len(s)));
+ }
+ }
+#else
+#if (DK3_HAVE__WCSDUP) && (DK3_SIZEOF_WCHAR_T == 2)
+ back = _wcsdup(s);
+ if(!(back)) {
+ if(app) {
+ dk3str_memory_error(app, 2, (1 + dk3str_c16_len(s)));
+ }
+ }
+#else
+ size_t sz;
+ sz = 1 + dk3str_c16_len(s);
+ if(app) {
+ back = dk3_new_app(dk3_c16_t,sz,app);
+ } else {
+ back = dk3_new(dk3_c16_t,sz);
+ }
+ if(back) {
+ dk3str_c16_cpy_not_overlapped(back, s);
+ }
+#endif
+#endif
+ return back;
+}
+
+
+
+dk3_c32_t *
+dk3str_c32_dup_app(dk3_c32_t const *s, dk3_app_t *app)
+{
+ dk3_c32_t *back;
+#if (DK3_HAVE_WCSDUP) && (DK3_SIZEOF_WCHAR_T == 4)
+ back = wcsdup(s);
+ if(!(back)) {
+ if(app) {
+ dk3str_memory_error(app, 4, (1 + dk3str_c32_len(s)));
+ }
+ }
+#else
+#if (DK3_HAVE__WCSDUP) && (DK3_SIZEOF_WCHAR_T == 4)
+ back = _wcsdup(s);
+ if(!(back)) {
+ if(app) {
+ dk3str_memory_error(app, 4, (1 + dk3str_c32_len(s)));
+ }
+ }
+#else
+ size_t sz;
+ sz = 1 + dk3str_c32_len(s);
+ if(app) {
+ back = dk3_new_app(dk3_c32_t,sz,app);
+ } else {
+ back = dk3_new(dk3_c32_t,sz);
+ }
+ if(back) {
+ dk3str_c32_cpy(back, s);
+ }
+#endif
+#endif
+ return back;
+}
+
+
+
+dkChar *
+dk3str_dup_app(dkChar const *s, dk3_app_t *app)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_dup_app(s, app));
+#else
+ return(dk3str_c16_dup_app(s, app));
+#endif
+#else
+ return(dk3str_c8_dup_app(s, app));
+#endif
+}
+
+
+char
+dk3str_c8_tolower(char c)
+{
+ char back; /* Function result. */
+ back = c;
+ if((back >= 'A') && (back <= 'Z')) {
+ back = 'a' + (back - 'A');
+ }
+ return back;
+}
+
+
+
+dk3_c16_t
+dk3str_c16_tolower(dk3_c16_t c)
+{
+ dk3_c16_t back;
+ back = c;
+ if((back >= 0x0041U) && (back <= 0x005AU)) {
+ back = 0x0061U + (back - 0x0041U);
+ }
+ return back;
+}
+
+
+
+dk3_c32_t
+dk3str_c32_tolower(dk3_c32_t c)
+{
+ dk3_c32_t back;
+ back = c;
+ if((back >= (dk3_c32_t)0x00000041UL) && (back <= (dk3_c32_t)0x0000005AUL)) {
+ back = (dk3_c32_t)0x00000061UL + (back - (dk3_c32_t)0x00000041UL);
+ }
+ return back;
+}
+
+
+
+dkChar
+dk3str_tolower(dkChar c)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_tolower(c));
+#else
+ return(dk3str_c16_tolower(c));
+#endif
+#else
+ return(dk3str_c8_tolower(c));
+#endif
+}
+
+
+
+char
+dk3str_c8_toupper(char c)
+{
+ char back; /* Function result. */
+ back = c;
+ if((back >= 'a') && (back <= 'z')) {
+ back = 'A' + (back - 'a');
+ }
+ return back;
+}
+
+
+
+dk3_c16_t
+dk3str_c16_toupper(dk3_c16_t c)
+{
+ dk3_c16_t back;
+ back = c;
+ if((back >= 0x0061U) && (back <= 0x007AU)) {
+ back = 0x0041U + (back - 0x0061U);
+ }
+ return back;
+}
+
+
+
+dk3_c32_t
+dk3str_c32_toupper(dk3_c32_t c)
+{
+ dk3_c32_t back;
+ back = c;
+ if((back >= (dk3_c32_t)0x00000061UL) && (back <= (dk3_c32_t)0x0000007AUL)) {
+ back = (dk3_c32_t)0x00000041UL + (back - (dk3_c32_t)0x00000061UL);
+ }
+ return back;
+}
+
+
+
+dkChar
+dk3str_toupper(dkChar c)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_toupper(c));
+#else
+ return(dk3str_c16_toupper(c));
+#endif
+#else
+ return(dk3str_c8_toupper(c));
+#endif
+}
+
+
+
+char *
+dk3str_c8_start(char const *str, char const *whsp)
+{
+ char *back = NULL; /* Function result. */
+ char const *ptr; /* Pointer to traverse str. */
+ char const *wh; /* Whitespaces set. */
+
+
+#line 2855 "dk3str.ctr"
+ if(str) {
+ wh = (whsp ? whsp : dk3str_c8_def_whsp);
+ ptr = str;
+ while((*ptr) && (!(back))) {
+ if(dk3str_c8_chr(wh,*ptr)) {
+ ptr++;
+ } else {
+ back = (char *)ptr;
+ }
+ }
+ }
+
+#line 2866 "dk3str.ctr"
+ return back;
+}
+
+
+
+dk3_c16_t *
+dk3str_c16_start(dk3_c16_t const *str, dk3_c16_t const *whsp)
+{
+ dk3_c16_t *back = NULL;
+ dk3_c16_t const *ptr; /* Pointer into string. */
+ dk3_c16_t const *wh; /* Whitespaces set. */
+
+ if(str) {
+ wh = (whsp ? whsp : c16_def_whsp);
+ ptr = str;
+ while((*ptr) && (!(back))) {
+ if(dk3str_c16_chr(wh, *ptr)) {
+ ptr++;
+ } else {
+ back = (dk3_c16_t *)ptr;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+dk3_c32_t *
+dk3str_c32_start(dk3_c32_t const *str, dk3_c32_t const *whsp)
+{
+ dk3_c32_t *back = NULL;
+ dk3_c32_t const *ptr = NULL; /* Current character. */
+ dk3_c32_t const *wh = NULL; /* Whitespaces set. */
+
+
+#line 2901 "dk3str.ctr"
+ if(str) {
+ wh = (whsp ? whsp : c32_def_whsp);
+ ptr = str;
+ while((*ptr) && (!(back))) {
+ if(dk3str_c32_chr(wh, *ptr)) {
+ ptr++;
+ } else {
+ back = (dk3_c32_t *)ptr;
+ }
+ }
+ }
+
+#line 2912 "dk3str.ctr"
+ return back;
+}
+
+
+
+dkChar *
+dk3str_start(dkChar const *str, dkChar const *whsp)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_start(str, whsp));
+#else
+ return(dk3str_c16_start(str, whsp));
+#endif
+#else
+ return(dk3str_c8_start(str, whsp));
+#endif
+}
+
+
+
+char *
+dk3str_c8_next(char *str, char const *whsp)
+{
+ char *back = NULL; /* Function result. */
+ char *ptr = NULL; /* Pointer to traverse str. */
+ char const *wh = NULL; /* Whitespaces set to use. */
+ int state = 0; /* Current processing state. */
+
+
+#line 2941 "dk3str.ctr"
+ if(str) {
+ ptr = str;
+ wh = (whsp ? whsp : dk3str_c8_def_whsp);
+ state = 0;
+ while((state < 2) && (*ptr)) {
+ if(dk3str_c8_chr(wh, *ptr)) {
+ if(state == 1) {
+ state = 2;
+ *(ptr++) = '\0';
+ back = dk3str_c8_start(ptr, wh);
+ } else {
+ ptr++;
+ }
+ } else {
+ state = 1;
+ ptr++;
+ }
+ }
+ }
+
+#line 2960 "dk3str.ctr"
+ return back;
+}
+
+
+
+dk3_c16_t *
+dk3str_c16_next(dk3_c16_t *str, dk3_c16_t const *whsp)
+{
+ dk3_c16_t *back = NULL;
+ dk3_c16_t *ptr; /* Pointer into string. */
+ dk3_c16_t const *wh; /* Whitespaces set. */
+ int state; /* Current state. */
+
+ if(str) {
+ ptr = str;
+ wh = (whsp ? whsp : c16_def_whsp);
+ state = 0;
+ while((state < 2) && (*ptr)) {
+ if(dk3str_c16_chr(wh, *ptr)) {
+ if(state == 1) {
+ state = 2;
+ *(ptr++) = 0U;
+ back = dk3str_c16_start(ptr, wh);
+ } else {
+ ptr++;
+ }
+ } else {
+ state = 1; ptr++;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+dk3_c32_t *
+dk3str_c32_next(dk3_c32_t *str, dk3_c32_t const *whsp)
+{
+ dk3_c32_t *back = NULL;
+ dk3_c32_t *ptr = NULL; /* Pointer into string. */
+ dk3_c32_t const *wh = NULL; /* Whitespaces. */
+ int state = 0; /* Current processing state. */
+
+
+#line 3004 "dk3str.ctr"
+ if(str) {
+ ptr = str;
+ wh = (whsp ? whsp : c32_def_whsp);
+ state = 0;
+ while((state < 2) && (*ptr)) {
+ if(dk3str_c32_chr(wh, *ptr)) {
+
+#line 3010 "dk3str.ctr"
+ if(state == 1) {
+ state = 2;
+ *(ptr++) = 0UL;
+ back = dk3str_c32_start(ptr, wh);
+ } else {
+ ptr++;
+ }
+ } else {
+ state = 1; ptr++;
+ }
+ }
+ }
+
+#line 3022 "dk3str.ctr"
+ return back;
+}
+
+
+
+dkChar *
+dk3str_next(dkChar *str, dkChar const *whsp)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_next(str, whsp));
+#else
+ return(dk3str_c16_next(str, whsp));
+#endif
+#else
+ return(dk3str_c8_next(str, whsp));
+#endif
+}
+
+
+
+void
+dk3str_c8_chomp(char *str, char const *whsp)
+{
+ char const *wh; /* Whitespaces set to use. */
+ char *ptr; /* Pointer to traverse str. */
+ char *x; /* Start position of final space sequence. */
+
+
+#line 3050 "dk3str.ctr"
+ if(str) {
+ wh = (whsp ? whsp : dk3str_c8_def_whsp);
+ x = NULL; ptr = str;
+ while(*ptr) {
+ if(dk3str_c8_chr(wh, *ptr)) {
+ if(!(x)) { x = ptr; }
+ } else {
+ x = NULL;
+ }
+ ptr++;
+ }
+ if(x) { *x = '\0'; }
+ }
+
+
+#line 3064 "dk3str.ctr"
+}
+
+
+
+void
+dk3str_c16_chomp(dk3_c16_t *str, dk3_c16_t const *whsp)
+{
+ dk3_c16_t const *wh; /* Whitespaces set. */
+ dk3_c16_t *ptr; /* Pointer into string. */
+ dk3_c16_t *x; /* Test pointer for whitespaces set. */
+
+ if(str) {
+ wh = (whsp ? whsp : c16_def_whsp);
+ x = NULL; ptr = str;
+ while(*ptr) {
+ if(dk3str_c16_chr(wh, *ptr)) {
+ if(!(x)) x = ptr;
+ } else {
+ x = NULL;
+ }
+ ptr++;
+ }
+ if(x) { *x = 0U; }
+ }
+}
+
+
+
+void
+dk3str_c32_chomp(dk3_c32_t *str, dk3_c32_t const *whsp)
+{
+ dk3_c32_t const *wh = NULL; /* Whitespaces set. */
+ dk3_c32_t *ptr = NULL; /* Pointer into string. */
+ dk3_c32_t *x = NULL; /* For whitespace-set test. */
+
+ if(str) {
+ wh = (whsp ? whsp : c32_def_whsp);
+ x = NULL; ptr = str;
+ while(*ptr) {
+ if(dk3str_c32_chr(wh, *ptr)) {
+ if(!(x)) x = ptr;
+ } else {
+ x = NULL;
+ }
+ ptr++;
+ }
+ if(x) { *x = 0UL; }
+ }
+}
+
+
+
+void
+dk3str_chomp(dkChar *str, dkChar const *whsp)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ dk3str_c32_chomp(str, whsp);
+#else
+ dk3str_c16_chomp(str, whsp);
+#endif
+#else
+ dk3str_c8_chomp(str, whsp);
+#endif
+}
+
+
+
+void
+dk3str_c8_delnl(char *str)
+{
+ char *ptr;
+ if(str) {
+ ptr = str;
+ while(*ptr) {
+ if(*ptr == 0x0D) {
+ if(ptr[1] == 0x0A) {
+ *ptr = '\0';
+ } else {
+ ptr++;
+ }
+ } else {
+ if(*ptr == 0x0A) {
+ *ptr = '\0';
+ } else {
+ ptr++;
+ }
+ }
+ }
+ }
+}
+
+
+
+void
+dk3str_c16_delnl(dk3_c16_t *str)
+{
+ dk3_c16_t *ptr;
+ if(str) {
+ ptr = str;
+ while(*ptr) {
+ if(*ptr == 0x000DU) {
+ if(ptr[1] == 0x000AU) {
+ *ptr = (dk3_c16_t)0U;
+ } else {
+ ptr++;
+ }
+ } else {
+ if(*ptr == 0x000AU) {
+ *ptr = (dk3_c16_t)0U;
+ } else {
+ ptr++;
+ }
+ }
+ }
+ }
+}
+
+
+
+void
+dk3str_c32_delnl(dk3_c32_t *str)
+{
+ dk3_c32_t *ptr;
+ if(str) {
+ ptr = str;
+ while(*ptr) {
+ if(*ptr == 0x0000000DUL) {
+ if(ptr[1] == 0x0000000AUL) {
+ *ptr = (dk3_c32_t)0UL;
+ } else {
+ ptr++;
+ }
+ } else {
+ if(*ptr == 0x0000000AUL) {
+ *ptr = (dk3_c32_t)0UL;
+ } else {
+ ptr++;
+ }
+ }
+ }
+ }
+}
+
+
+
+void
+dk3str_delnl(dkChar *str)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ dk3str_c32_delnl(str);
+#else
+ dk3str_c16_delnl(str);
+#endif
+#else
+ dk3str_c8_delnl(str);
+#endif
+}
+
+
+
+int
+dk3str_c8_array_index(char const * const *a, char const *s, int c)
+{
+ int back = -1; /* Function result. */
+ int ci; /* Current array index for test. */
+ char const * const *ap; /* Pointer to traverse array a. */
+ if((a) && (s)) {
+ ap = a; ci = 0;
+ while((*ap) && (back == -1)) {
+ if(c) {
+ if(dk3str_c8_cmp(*ap, s) == 0) back = ci;
+ } else {
+ if(dk3str_c8_casecmp(*ap, s) == 0) back = ci;
+ }
+ if(back == -1) { ap++; ci++; }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3str_c16_array_index(dk3_c16_t const * const *a, dk3_c16_t const *s, int c)
+{
+ int back = -1;
+ int ci; /* Current index. */
+ dk3_c16_t const * const *ap; /* Pointer into array. */
+ if((a) && (s)) {
+ ap = a; ci = 0;
+ while((*ap) && (back == -1)) {
+ if(c) {
+ if(dk3str_c16_cmp(*ap, s) == 0) back = ci;
+ } else {
+ if(dk3str_c16_casecmp(*ap, s) == 0) back = ci;
+ }
+ if(back == -1) { ap++; ci++; }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3str_c32_array_index(dk3_c32_t const * const *a, dk3_c32_t const *s, int c)
+{
+ int back = -1;
+ int ci; /* Current index. */
+ dk3_c32_t const * const *ap; /* Pointer into array. */
+
+ if((a) && (s)) {
+ ap = a; ci = 0;
+ while((*ap) && (back == -1)) {
+ if(c) {
+ if(dk3str_c32_cmp(*ap, s) == 0) back = ci;
+ } else {
+ if(dk3str_c32_casecmp(*ap, s) == 0) back = ci;
+ }
+ if(back == -1) { ap++; ci++; }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3str_array_index(dkChar const * const *a, dkChar const *s, int c)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_array_index(a, s, c));
+#else
+ return(dk3str_c16_array_index(a, s, c));
+#endif
+#else
+ return(dk3str_c8_array_index(a, s, c));
+#endif
+}
+
+
+
+int
+dk3str_c8_is_abbr(char const *line,char const *pattern,char spec,int cs)
+{
+ int back = 0; /* Function result. */
+ char cl; /* Current character from line. */
+ char cp; /* Current character from pattern. */
+ char const *lptr = NULL; /* Pointer to traverse line. */
+ char const *pptr = NULL; /* Pointer to traverse pattern. */
+ int afterspec = 0; /* Flag: cs was already found in the pattern. */
+ int cc = 0; /* Flag: Can continue. */
+
+
+#line 3320 "dk3str.ctr"
+ if((line) && (pattern)) {
+ lptr = line; pptr = pattern; afterspec = 0; cc = 1;
+ while(cc) {
+ if(*pptr) {
+ if((!afterspec) && (*pptr == spec)) {
+ afterspec = 1; pptr++;
+ } else {
+ if(*lptr) {
+ cl = *lptr; cp = *pptr;
+ if(!cs) {
+ cl = dk3str_c8_toupper(cl);
+ cp = dk3str_c8_toupper(cp);
+ }
+ if(cl == cp) {
+ lptr++; pptr++;
+ } else {
+ cc = 0; back = 0;
+ }
+ } else {
+ cc = 0;
+ if(afterspec) back = 1;
+ }
+ }
+ } else {
+ cc = 0;
+ if(!(*lptr)) {
+ back = 1;
+ }
+ }
+ }
+ }
+
+
+#line 3352 "dk3str.ctr"
+ return back;
+}
+
+
+
+int
+dk3str_c16_is_abbr(dk3_c16_t const *line, dk3_c16_t const *pattern, dk3_c16_t spec, int cs)
+{
+ int back = 0;
+ dk3_c16_t cl; /* Current character from line. */
+ dk3_c16_t cp; /* Current character from pattern. */
+ dk3_c16_t const *lptr; /* Input text to check. */
+ dk3_c16_t const *pptr; /* Pattern. */
+ int afterspec; /* Flag: Abbreviation inidicator found. */
+ int cc; /* Flag: Can continue. */
+
+ if((line) && (pattern)) {
+ lptr = line; pptr = pattern; afterspec = 0; cc = 1;
+ while(cc) {
+ if(*pptr) {
+ if((!afterspec) && (*pptr == spec)) {
+ afterspec = 1; pptr++;
+ } else {
+ if(*lptr) {
+ cl = *lptr; cp = *pptr;
+ if(!cs) {
+ cl = dk3str_c16_toupper(cl);
+ cp = dk3str_c16_toupper(cp);
+ }
+ if(cl == cp) {
+ lptr++; pptr++;
+ } else {
+ cc = 0; back = 0;
+ }
+ } else {
+ cc = 0;
+ if(afterspec) back = 1;
+ }
+ }
+ } else {
+ cc = 0;
+ if(!(*lptr)) {
+ back = 1;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3str_c32_is_abbr(dk3_c32_t const *line, dk3_c32_t const *pattern, dk3_c32_t spec, int cs)
+{
+ int back = 0;
+ dk3_c32_t cl = 0UL; /* Text character. */
+ dk3_c32_t cp = 0UL; /* Pattern character. */
+ dk3_c32_t const *lptr = NULL; /* Pointer into text. */
+ dk3_c32_t const *pptr = NULL; /* Pointer into pattern. */
+ int afterspec = 0; /* Flag: Abbreviation indicator was found. */
+ int cc = 0; /* Flag: Can continue. */
+
+ if((line) && (pattern)) {
+ lptr = line; pptr = pattern; afterspec = 0; cc = 1;
+ while(cc) {
+ if(*pptr) {
+ if((!afterspec) && (*pptr == spec)) {
+ afterspec = 1; pptr++;
+ } else {
+ if(*lptr) {
+ cl = *lptr; cp = *pptr;
+ if(!cs) {
+ cl = dk3str_c32_toupper(cl);
+ cp = dk3str_c32_toupper(cp);
+ }
+ if(cl == cp) {
+ lptr++; pptr++;
+ } else {
+ cc = 0; back = 0;
+ }
+ } else {
+ cc = 0;
+ if(afterspec) back = 1;
+ }
+ }
+ } else {
+ cc = 0;
+ if(!(*lptr)) { back = 1; }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3str_is_abbr(dkChar const *line, dkChar const *pattern, dkChar spec, int cs)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_is_abbr(line, pattern, spec, cs));
+#else
+ return(dk3str_c16_is_abbr(line, pattern, spec, cs));
+#endif
+#else
+ return(dk3str_c8_is_abbr(line, pattern, spec, cs));
+#endif
+}
+
+
+
+int
+dk3str_c8_array_abbr(char const * const *ar, char const *str, char sp, int cs)
+{
+ int back = -1; /* Function result. */
+ char const * const *ptr; /* Pointer to traverse array ar. */
+ int i; /* Current index of ptr in ar. */
+
+
+#line 3472 "dk3str.ctr"
+ if((ar) && (str)) {
+ i = 0; ptr = ar;
+ while((*ptr) && (back == -1)) {
+
+
+#line 3476 "dk3str.ctr"
+ if(dk3str_c8_is_abbr(str, *ptr, sp, cs)) {
+ back = i;
+ }
+ if(back == -1) {
+ ptr++; i++;
+ }
+
+
+#line 3483 "dk3str.ctr"
+ }
+ }
+
+#line 3485 "dk3str.ctr"
+ return back;
+}
+
+
+
+int
+dk3str_c16_array_abbr(dk3_c16_t const * const *arr, dk3_c16_t const *str, dk3_c16_t sp, int cs)
+{
+ int back = -1;
+ dk3_c16_t const * const *ptr; /* Pointer into array. */
+ int i; /* Current index. */
+
+
+#line 3497 "dk3str.ctr"
+ if((arr) && (str)) {
+
+#line 3498 "dk3str.ctr"
+ i = 0; ptr = arr;
+ while((*ptr) && (back == -1)) {
+
+#line 3500 "dk3str.ctr"
+ if(dk3str_c16_is_abbr(str, *ptr, sp, cs)) {
+
+#line 3501 "dk3str.ctr"
+ back = i;
+ } else {
+
+#line 3503 "dk3str.ctr"
+ }
+ if(back == -1) {
+ ptr++; i++;
+ }
+
+#line 3507 "dk3str.ctr"
+ }
+
+#line 3508 "dk3str.ctr"
+ }
+
+#line 3509 "dk3str.ctr"
+ return back;
+}
+
+
+
+int
+dk3str_c32_array_abbr(dk3_c32_t const * const *arr, dk3_c32_t const *str, dk3_c32_t sp, int cs)
+{
+ int back = -1;
+ dk3_c32_t const * const *ptr = NULL; /* Pointer into array. */
+ int i = 0; /* Current index. */
+
+ if((arr) && (str)) {
+ i = 0; ptr = arr;
+ while((*ptr) && (back == -1)) {
+ if(dk3str_c32_is_abbr(str, *ptr, sp, cs)) {
+ back = i;
+ }
+ if(back == -1) {
+ ptr++; i++;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3str_array_abbr(dkChar const * const *ar,dkChar const *str,dkChar sp,int cs)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_array_abbr(ar, str, sp, cs));
+#else
+ return(dk3str_c16_array_abbr(ar, str, sp, cs));
+#endif
+#else
+ return(dk3str_c8_array_abbr(ar, str, sp, cs));
+#endif
+}
+
+
+
+int
+dk3str_c8_is_bool(char const *str)
+{
+ int back = 0; /* Function result. */
+
+
+#line 3558 "dk3str.ctr"
+ if(str) {
+ if(dk3str_c8_array_abbr(dk3str_c8_bool_kw,str,'$',0) >= 0) {
+ back = 1;
+ }
+ }
+
+#line 3563 "dk3str.ctr"
+ return back;
+}
+
+
+
+int
+dk3str_c16_is_bool(dk3_c16_t const *str)
+{
+ int back = 0;
+ char mytest[256]; /* 8-bit version of the str text. */
+ if(str) {
+#if VERSION_BEFORE_20130928
+ if(dk3str_c16_to_c8_simple(mytest, sizeof(mytest), str)) {
+ back = dk3str_c8_is_bool(mytest);
+ }
+#else
+ if(dk3str_cnv_c16_to_c8u_app(mytest, sizeof(mytest), str, NULL)) {
+ back = dk3str_c8_is_bool(mytest);
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3str_c32_is_bool(dk3_c32_t const *str)
+{
+ int back = 0;
+ char mytest[256]; /* 8-bit text copy of str. */
+ if(str) {
+#if VERSION_BEFORE_20130928
+ if(dk3str_c32_to_c8_simple(mytest, sizeof(mytest), str)) {
+ back = dk3str_c8_is_bool(mytest);
+ }
+#else
+ if(dk3str_cnv_c32_to_c8u_app(mytest, sizeof(mytest), str, NULL)) {
+ back = dk3str_c8_is_bool(mytest);
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3str_is_bool(dkChar const *str)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_is_bool(str));
+#else
+ return(dk3str_c16_is_bool(str));
+#endif
+#else
+ return(dk3str_c8_is_bool(str));
+#endif
+}
+
+
+
+int
+dk3str_c8_is_on(char const *str)
+{
+ int back = 0; /* Function result. */
+
+
+#line 3631 "dk3str.ctr"
+ if(str) {
+ if(dk3str_c8_array_abbr(dk3str_c8_bool_kw,str,'$',0) >= INDEX_OF_FIRST_BOOLEAN_TRUE) {
+ back = 1;
+ }
+ }
+
+#line 3636 "dk3str.ctr"
+ return back;
+}
+
+
+
+int
+dk3str_c16_is_on(dk3_c16_t const *str)
+{
+ int back = 0;
+ char mytest[256]; /* 8-bit version of the str text. */
+ if(str) {
+#if VERSION_BEFORE_20130928
+ if(dk3str_c16_to_c8_simple(mytest, sizeof(mytest), str)) {
+ back = dk3str_c8_is_on(mytest);
+ }
+#else
+ if(dk3str_cnv_c16_to_c8u_app(mytest, sizeof(mytest), str, NULL)) {
+ back = dk3str_c8_is_on(mytest);
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3str_c32_is_on(dk3_c32_t const *str)
+{
+ int back = 0;
+ char mytest[256]; /* 8-bit copy of str text. */
+ if(str) {
+#if VERSION_BEFORE_20130928
+ if(dk3str_c32_to_c8_simple(mytest, sizeof(mytest), str)) {
+ back = dk3str_c8_is_on(mytest);
+ }
+#else
+ if(dk3str_cnv_c32_to_c8u_app(mytest, sizeof(mytest), str, NULL)) {
+ back = dk3str_c8_is_on(mytest);
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3str_is_on(dkChar const *str)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_is_on(str));
+#else
+ return(dk3str_c16_is_on(str));
+#endif
+#else
+ return(dk3str_c8_is_on(str));
+#endif
+}
+
+
+
+size_t
+dk3str_c8_explode(char **array, size_t sz, char *str, char const *whsp)
+{
+ size_t back = 0; /* Function result. */
+ char const *wh = NULL; /* White spaces set to use. */
+ char *current = NULL; /* Current text word to process. */
+ char *next = NULL; /* Remaining text after processing the word. */
+ char **ptr = NULL; /* Pointer to current array element. */
+ size_t i = 0; /* Number of remaining usable array elements. */
+ if((array) && (sz > 1) && (str)) {
+ wh = (whsp ? whsp : dk3str_c8_def_whsp);
+ ptr = array; i = sz;
+ while(i--) { *(ptr++) = NULL; }
+ ptr = array; i = 0;
+ current = dk3str_c8_start(str, wh);
+ while((current) && (i < (sz - 1))) {
+ next = dk3str_c8_next(current,wh);
+ *(ptr++) = current; i++; back++;
+ current = next;
+ }
+ }
+ return back;
+}
+
+
+
+size_t
+dk3str_c16_explode(dk3_c16_t **array, size_t sz, dk3_c16_t *str, dk3_c16_t const *whsp)
+{
+ size_t back = 0;
+ dk3_c16_t const *wh = NULL; /* Whitespaces set. */
+ dk3_c16_t *current = NULL; /* Start of current word. */
+ dk3_c16_t *next = NULL; /* Start of next word after current. */
+ dk3_c16_t **ptr = NULL; /* Pointer into array. */
+ size_t i = 0; /* Number of words found. */
+
+ if((array) && (sz > 1) && (str)) {
+ wh = (whsp ? whsp : c16_def_whsp);
+ ptr = array; i = sz;
+ while(i--) { *(ptr++) = NULL; }
+ ptr = array; i = 0;
+ current = dk3str_c16_start(str, wh);
+ while((current) && (i < (sz - 1))) {
+ next = dk3str_c16_next(current, wh);
+ *(ptr++) = current; i++; back++;
+ current = next;
+ }
+ }
+ return back;
+}
+
+
+
+size_t
+dk3str_c32_explode(dk3_c32_t **array, size_t sz, dk3_c32_t *str, dk3_c32_t const *whsp)
+{
+ size_t back = 0;
+ dk3_c32_t const *wh = NULL; /* Whitespace set. */
+ dk3_c32_t *current = NULL; /* Current word. */
+ dk3_c32_t *next = NULL; /* Next word. */
+ dk3_c32_t **ptr = NULL; /* Pointer into destination array. */
+ size_t i = 0; /* Current index. */
+ if((array) && (sz > 1) && (str)) {
+ wh = (whsp ? whsp : c32_def_whsp);
+ ptr = array; i = sz;
+ while(i--) { *(ptr++) = NULL; }
+ ptr = array; i = 0;
+ current = dk3str_c32_start(str, wh);
+ while((current) && (i < (sz - 1))) {
+ next = dk3str_c32_next(current, wh);
+ *(ptr++) = current; i++; back++;
+ current = next;
+ }
+ }
+ return back;
+}
+
+
+
+size_t
+dk3str_explode(dkChar **array, size_t sz, dkChar *str, dkChar const *whsp)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_explode(array, sz, str, whsp));
+#else
+ return(dk3str_c16_explode(array, sz, str, whsp));
+#endif
+#else
+ return(dk3str_c8_explode(array, sz, str, whsp));
+#endif
+}
+
+
+
+void
+dk3str_c8_normalize(char *l, char const *w, char s)
+{
+ char *parts[256]; /* All the text words. */
+ char *dp = NULL; /* Destination pointer. */
+ char *sp = NULL; /* Source pointer. */
+ size_t np = 0; /* Number of parts used. */
+ size_t i = 0; /* Current word to process. */
+ if(l) {
+ np = dk3str_c8_explode(parts, 255, l, w);
+ if(np > 0) {
+ dp = l;
+ for(i = 0; i < np; i++) {
+ sp = parts[i];
+ if(i) { *(dp++) = s; }
+ while(*sp) { *(dp++) = *(sp++); }
+ }
+ *dp = '\0';
+ }
+ }
+}
+
+
+
+void
+dk3str_c16_normalize(dk3_c16_t *l, dk3_c16_t const *w, dk3_c16_t s)
+{
+ dk3_c16_t *parts[256]; /* Pointers to the words. */
+ dk3_c16_t *dp = NULL; /* Destination pointer. */
+ dk3_c16_t *sp = NULL; /* Source pointer. */
+ size_t np = 0; /* Number of parts. */
+ size_t i = 0; /* Index of current part. */
+
+ if(l) {
+ np = dk3str_c16_explode(parts, 255, l, w);
+ if(np > 0) {
+ dp = l;
+ for(i = 0; i < np; i++) {
+ sp = parts[i];
+ if(i) { *(dp++) = s; }
+ while(*sp) { *(sp++) = *(dp++); }
+ }
+ *dp = 0U;
+ }
+ }
+}
+
+
+
+void
+dk3str_c32_normalize(dk3_c32_t *l, dk3_c32_t const *w, dk3_c32_t s)
+{
+ dk3_c32_t *parts[256]; /* Words. */
+ dk3_c32_t *dp = NULL; /* Destination pointer. */
+ dk3_c32_t *sp = NULL; /* Source pointer. */
+ size_t np = 0; /* Number of words. */
+ size_t i = 0; /* Index of current word. */
+ if(l) {
+ np = dk3str_c32_explode(parts, 255, l, w);
+ if(np > 0) {
+ dp = l;
+ for(i = 0; i < np; i++) {
+ sp = parts[i];
+ if(i) { *(dp++) = s; }
+ while(*sp) { *(dp++) = *(sp++); }
+ }
+ *dp = 0UL;
+ }
+ }
+}
+
+
+
+void
+dk3str_normalize(dkChar *l, dkChar const *w, dkChar s)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ dk3str_c32_normalize(l, w, s);
+#else
+ dk3str_c16_normalize(l, w, s);
+#endif
+#else
+ dk3str_c8_normalize(l, w, s);
+#endif
+}
+
+
+
+void
+dk3str_c8_correct_filename(char *n)
+{
+ register char *p;
+ p = n;
+ while(*p) { if(*p == NO_FNS_C8) { *p = FNS_C8; } p++; }
+}
+
+
+
+void
+dk3str_c16_correct_filename(dk3_c16_t *n)
+{
+ register dk3_c16_t *p;
+ p = n;
+ while(*p) { if(*p == NO_FNS_C16) { *p = FNS_C16; } p++;}
+}
+
+
+
+void
+dk3str_c32_correct_filename(dk3_c32_t *n)
+{
+ register dk3_c32_t *p; /* Pointer into text. */
+ p = n;
+ while(*p) { if(*p == NO_FNS_C32) { *p = FNS_C32; } p++;}
+}
+
+
+
+void
+dk3str_correct_filename(dkChar *n)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ dk3str_c32_correct_filename(n);
+#else
+ dk3str_c16_correct_filename(n);
+#endif
+#else
+ dk3str_c8_correct_filename(n);
+#endif
+}
+
+
+
+int
+dk3str_c8_is_abs_path(char const *n)
+{
+ int back = 0;
+ if(n) {
+ if(*n == FNS_C8) {
+ back = 1;
+ } else {
+#if DK3_ON_WINDOWS
+ if(((*n >= 'A') && (*n <= 'Z')) || ((*n >= 'a') && (*n <= 'z'))) {
+ if(n[1] == ':') {
+ if(n[2] == FNS_C8) {
+ back = 1;
+ }
+ }
+ }
+#endif
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3str_c16_is_abs_path(dk3_c16_t const *n)
+{
+ int back = 0;
+ if(n) {
+ if(*n == FNS_C16) {
+ back = 1;
+ } else {
+#if DK3_ON_WINDOWS
+ if(((*n >= 0x0061U) && (*n <= 0x007AU))
+ || ((*n >= 0x0041U) && (*n <= 0x005AU)))
+ {
+ if(n[1] == 0x003AU) {
+ if(n[2] == FNS_C16) {
+ back = 1;
+ }
+ }
+ }
+#endif
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3str_c32_is_abs_path(dk3_c32_t const *n)
+{
+ int back = 0;
+
+
+#line 3984 "dk3str.ctr"
+ if(n) {
+ if(*n == FNS_C32) {
+ back = 1;
+ } else {
+#if DK3_ON_WINDOWS
+ if(((*n >= 0x00000061UL) && (*n <= 0x0000007AUL))
+ || ((*n >= 0x00000041UL) && (*n <= 0x0000005AUL)))
+ {
+ if(n[1] == 0x0000003AUL) {
+ if(n[2] == FNS_C32) {
+ back = 1;
+ }
+ }
+ }
+#endif
+ }
+ }
+
+#line 4001 "dk3str.ctr"
+ return back;
+}
+
+
+
+int
+dk3str_is_abs_path(dkChar const *n)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_is_abs_path(n));
+#else
+ return(dk3str_c16_is_abs_path(n));
+#endif
+#else
+ return(dk3str_c8_is_abs_path(n));
+#endif
+}
+
+
+
+int
+dk3str_c8_append_path_app(char *d, size_t sz, char const *n, dk3_app_t *app)
+{
+ int back = 0; /* Function result. */
+ char myn[DK3_MAX_PATH]; /* My editable copy of n. */
+ char *p1 = NULL; /* Current name part. */
+ char *p2 = NULL; /* Remaining text. */
+ char *p3 = NULL; /* Used to delete one part from path. */
+ size_t tsz; /* Size for tests. */
+ if((d) && (sz) && (n)) {
+ if(dk3str_c8_is_abs_path(n)) { /* Absolute path, copy. */
+ if(dk3str_c8_len(n) < sz) {
+ dk3str_c8_cpy(d,n);
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Name n too long! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 109);
+ }
+ }
+ } else { /* Relative path, append. */
+ if(dk3str_c8_len(n) < sizeof(myn)) {
+ back = 1;
+ dk3str_c8_cpy(myn,n);
+ p1 = myn;
+ while((p1) && (back)) {
+ p2 = dk3str_c8_chr(p1,FNS_C8);
+ if(p2) { *(p2++) = '\0'; }
+ if(dk3str_c8_cmp(dk3str_c8_dot,p1)) {
+ if(dk3str_c8_cmp(dk3str_c8_dot_dot,p1)) { /* Add another part. */
+ tsz = dk3str_c8_len(d) + dk3str_c8_len(dk3str_c8_fnsep)
+ + dk3str_c8_len(p1);
+ if(tsz < sz) {
+ dk3str_c8_cat(d,dk3str_c8_fnsep);
+ dk3str_c8_cat(d,p1);
+ } else {
+ if(app) {
+ /* ERROR: Result too long for destination buffer! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ } else { /* Remove last part. */
+ p3 = dk3str_c8_rchr(d,FNS_C8);
+ if(p3) {
+ *p3 = '\0';
+ } else {
+ if(app) {
+ /* ERROR: Too many ".." entries! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 110, 111, n);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 126);
+#endif
+ }
+ }
+ }
+ }
+ p1 = p2;
+ }
+ } else {
+ if(app) {
+ /* ERROR: Name n too long! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 109);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3str_c16_append_path_app(dk3_c16_t *d, size_t sz, dk3_c16_t const *n, dk3_app_t *app)
+{
+ int back = 0;
+ dk3_c16_t myn[DK3_MAX_PATH];
+ dk3_c16_t *p1 = NULL; /* Path component to process. */
+ dk3_c16_t *p2 = NULL; /* Remainder of path. */
+ dk3_c16_t *p3 = NULL; /* Last path component to remove. */
+ size_t tsz; /* Test size. */
+
+ if((d) && (sz) && (n)) {
+ if(dk3str_c16_is_abs_path(n)) {
+ if(dk3str_c16_len(n) < sz) {
+ dk3str_c16_cpy(d,n) ;
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Name n too long! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 109);
+ }
+ }
+ } else {
+ if(dk3str_c16_len(n) < DK3_SIZEOF(myn,dk3_c16_t)) {
+ back = 1;
+ dk3str_c16_cpy(myn,n) ;
+ p1 = myn;
+ while((p1) && (back)) {
+ p2 = dk3str_c16_chr(p1, FNS_C16);
+ if(p2) { *(p2++) = 0U; }
+ if(dk3str_c16_cmp(c16_dot,p1)) {
+ if(dk3str_c16_cmp(c16_dot_dot,p1)) {
+ tsz = dk3str_c16_len(d) + dk3str_c16_len(c16_fnsep)
+ + dk3str_c16_len(p1);
+ if(tsz < sz) {
+ dk3str_c16_cat(d,c16_fnsep);
+ dk3str_c16_cat(d,p1);
+ } else {
+ if(app) {
+ /* ERROR: Result too long for destination buffer! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ } else {
+ p3 = dk3str_c16_rchr(d,FNS_C16);
+ if(p3) {
+ *p3 = 0U;
+ } else {
+ if(app) {
+ /* ERROR: Too many ".." entries! */
+#if DK3_CHAR_SIZE == 2
+ dk3app_log_i3(app, DK3_LL_ERROR, 110, 111, n);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 126);
+#endif
+ }
+ }
+ }
+ }
+ p1 = p2;
+ }
+ } else {
+ if(app) {
+ /* ERROR: Name n too long! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 109);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3str_c32_append_path_app(dk3_c32_t *d, size_t sz, dk3_c32_t const *n, dk3_app_t *app)
+{
+ int back = 0;
+ dk3_c32_t myn[DK3_MAX_PATH]; /* My editable copy of n. */
+ dk3_c32_t *p1 = NULL; /* Current name part. */
+ dk3_c32_t *p2 = NULL; /* Remaining text. */
+ dk3_c32_t *p3 = NULL; /* Used to delete one part from path. */
+ size_t tsz; /* Test size. */
+
+
+
+#line 4178 "dk3str.ctr"
+ if((d) && (sz) && (n)) {
+ if(dk3str_c32_is_abs_path(n)) {
+
+#line 4180 "dk3str.ctr"
+ if(dk3str_c32_len(n) < sz) {
+ dk3str_c32_cpy(d,n) ;
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Name n too long! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 109);
+ }
+ }
+ } else {
+
+#line 4190 "dk3str.ctr"
+ if(dk3str_c32_len(n) < DK3_SIZEOF(myn,dk3_c32_t)) {
+ back = 1;
+ dk3str_c32_cpy(myn,n) ;
+ p1 = myn;
+ while((p1) && (back)) {
+ p2 = dk3str_c32_chr(p1,FNS_C32);
+ if(p2) { *(p2++) = 0UL; }
+ if(dk3str_c32_cmp(c32_dot,p1)) {
+ if(dk3str_c32_cmp(c32_dot_dot,p1)) {
+ tsz = dk3str_c32_len(d) + dk3str_c32_len(c32_fnsep)
+ + dk3str_c32_len(p1);
+ if(tsz < sz) {
+ dk3str_c32_cat(d,c32_fnsep);
+ dk3str_c32_cat(d,p1);
+ } else {
+ if(app) {
+ /* ERROR: Result too long for destination buffer! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ } else {
+ p3 = dk3str_c32_rchr(d,FNS_C32);
+ if(p3) {
+ *p3 = 0UL;
+ } else {
+ if(app) {
+ /* ERROR: Too many ".." entries! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 110);
+ }
+ }
+ }
+ }
+ p1 = p2;
+ }
+ } else {
+ if(app) {
+ /* ERROR: Name n too long! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 109);
+ }
+ }
+ }
+ }
+ if(back) {
+
+#line 4233 "dk3str.ctr"
+ }
+
+#line 4234 "dk3str.ctr"
+ return back;
+}
+
+
+
+int
+dk3str_append_path_app(dkChar *d, size_t sz, dkChar const *n, dk3_app_t *app)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_append_path_app(d, sz, n, app));
+#else
+ return(dk3str_c16_append_path_app(d, sz, n, app));
+#endif
+#else
+ return(dk3str_c8_append_path_app(d, sz, n, app));
+#endif
+}
+
+
+
+char *
+dk3str_c8_get_suffix(char const *s)
+{
+ char *back = NULL;
+ char const *ptr;
+ if(s) {
+ ptr = s;
+ while(*ptr) {
+ if(*ptr == '.') {
+ back = (char *)ptr;
+ } else {
+ if(*ptr == FNS_C8) {
+ back = NULL;
+ }
+ }
+ ptr++;
+ }
+ }
+ return back;
+}
+
+
+
+dk3_c16_t *
+dk3str_c16_get_suffix(dk3_c16_t const *s)
+{
+ dk3_c16_t *back = NULL;
+ dk3_c16_t const *ptr;
+
+ if(s) {
+ ptr = s;
+ while(*ptr) {
+ if(*ptr == 0x002EU) {
+ back = (dk3_c16_t *)ptr;
+ } else {
+ if(*ptr == FNS_C16) {
+ back = NULL;
+ }
+ }
+ ptr++;
+ }
+ }
+ return back;
+}
+
+
+
+dk3_c32_t *
+dk3str_c32_get_suffix(dk3_c32_t const *s)
+{
+ dk3_c32_t *back = NULL;
+ dk3_c32_t const *ptr;
+ if(s) {
+ ptr = s;
+ while(*ptr) {
+ if(*ptr == 0x0000002EUL) {
+ back = (dk3_c32_t *)ptr;
+ } else {
+ if(*ptr == FNS_C32) {
+ back = NULL;
+ }
+ }
+ ptr++;
+ }
+ }
+ return back;
+}
+
+
+
+dkChar *
+dk3str_get_suffix(dkChar const *s)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_get_suffix(s));
+#else
+ return(dk3str_c16_get_suffix(s));
+#endif
+#else
+ return(dk3str_c8_get_suffix(s));
+#endif
+}
+
+
+
+int
+dk3str_c32_to_c8_simple_app(char *d, size_t sz, dk3_c32_t const *s, dk3_app_t *app)
+{
+ int back = 0;
+ dk3_c32_t const *ptr = NULL; /* Pointer into source string. */
+ dk3_c32_t c = 0UL; /* Source character. */
+ unsigned char uc = 0x00; /* Destination character. */
+ char *dptr = NULL; /* Destination pointer. */
+
+ if((d) && (sz) && (s)) {
+ if(dk3str_c32_len(s) < sz) {
+ back = 1; ptr = s; dptr = d;
+ while(0UL != (c = *ptr)) {
+ if(c < (dk3_c32_t)0x00000100UL) {
+ uc = (unsigned char)c;
+ *(dptr++) = (char)uc;
+ } else {
+ if((back == 1) && (app)) {
+ /* ERROR: Illegal character(s) in source string! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 112);
+ }
+ back = 0;
+ }
+ ptr++;
+ }
+ *dptr = '\0';
+ } else {
+ d[0] = '\0';
+ if(app) {
+ /* ERROR: Source string too long! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 108);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+
+
+
+
+/** Convert 8-bit plain text to other encodings.
+ @param d Destination buffer (NULL to just count result elements).
+ @param s Source string.
+ @param app Application structure for diagnostics, may be NULL.
+ @param enc Destination encoding (DK3_ENCODING_xxx).
+ @return Number of destination elements created.
+*/
+static
+size_t
+dk3str_i_cnv_c8p(void *d, char const *s, dk3_app_t *app, int enc)
+{
+ size_t back = 0;
+ int error = 0; /* Flag: Error occured. */
+ char const *sptr = NULL; /* Source pointer. */
+ char *dp8 = NULL; /* Pointer to 8-bit destination. */
+ dk3_c16_t *dp16 = NULL; /* Pointer to 16-bit destination. */
+ dk3_c32_t *dp32 = NULL; /* Pointer to 32-bit destination. */
+ char c = 0x00; /* Current source character to process. */
+ unsigned char uc = 0x00; /* Destination byte. */
+ dk3_c32_t ul = 0UL; /* Conversion result. */
+ unsigned char myuc[16]; /* Conversion result buffer. */
+ dk3_c16_t myc16[16]; /* Conversion result buffer. */
+ size_t u8u = 0; /* UTF-8 bytes used for encoding. */
+ size_t u16u = 0; /* UTF-16 characters used for encoding. */
+ size_t sl = 0; /* Number of remaining characters in source. */
+ size_t i = 0; /* Copy converted characters to destination. */
+
+
+#line 4411 "dk3str.ctr"
+ if(s) {
+ sptr = s; sl = dk3str_c8_len(s);
+ if(d) {
+ switch(enc) {
+ case DK3_ENCODING_UTF8: { dp8 = (char *)d; } break;
+ case DK3_ENCODING_UTF16: { dp16 = (dk3_c16_t *)d; } break;
+ case DK3_ENCODING_UNICODE: { dp32 = (dk3_c32_t *)d; } break;
+ default: {
+ if(app) {
+ /* ERROR: Illegal destination encoding! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 114);
+ }
+ } break;
+ }
+ }
+ while((sl) && (0 == error)) {
+ c = *(sptr++); sl--;
+ uc = (unsigned char)c;
+ ul = (dk3_c32_t)uc;
+ ul &= 0x000000FFUL;
+ switch(enc) {
+ case DK3_ENCODING_UTF8: {
+ u8u = dk3enc_uc2utf8(ul, myuc, 16);
+ if(u8u) {
+ back = dk3mem_add_size_t(back, u8u, &error);
+ if(d) {
+ for(i = 0; i < u8u; i++) { *(dp8++) = myuc[i]; }
+ }
+ } else {
+ if(0 == error) {
+ if(app) {
+ /* ERROR: Conversion to UTF-8 failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 115);
+ }
+ } error = 1;
+ }
+ } break;
+ case DK3_ENCODING_UTF16: {
+ u16u = dk3enc_uc2utf16(ul, myc16, 16);
+ if(u16u) {
+ back = dk3mem_add_size_t(back, u16u, &error);
+ if(d) {
+ for(i = 0; i < u16u; i++) { *(dp16++) = myc16[i]; }
+ }
+ } else {
+ if(0 == error) {
+ if(app) {
+
+#line 4458 "dk3str.ctr"
+ /* ERROR: Conversion to UTF-16 failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 116);
+ }
+ } error = 1;
+ }
+ } break;
+ case DK3_ENCODING_UNICODE: {
+ back = dk3mem_add_size_t(back, 1, &error);
+ if(d) { *(dp32++) = ul; }
+ } break;
+ }
+ }
+ if(d) {
+ switch(enc) {
+ case DK3_ENCODING_UTF8: { *dp8 = '\0'; } break;
+ case DK3_ENCODING_UTF16: { *dp16 = 0U; } break;
+ case DK3_ENCODING_UNICODE: { *dp32 = 0UL; } break;
+ }
+ }
+ back = dk3mem_add_size_t(back, 1, &error);
+ if(error) {
+ back = 0;
+ if(error == DK3_ERROR_MATH_OVERFLOW) {
+ if(app) {
+ /* ERROR: Input string too long for conversion! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 108);
+ }
+ }
+ }
+ }
+
+#line 4488 "dk3str.ctr"
+ return back;
+}
+
+
+
+
+size_t
+dk3str_cnvsz_c8p_to_c8u_app(char const *s, dk3_app_t *app)
+{
+ size_t back = 0;
+ if(s) {
+ back = dk3str_i_cnv_c8p(NULL, s, app, DK3_ENCODING_UTF8);
+ }
+ return back;
+}
+
+
+int
+dk3str_cnv_c8p_to_c8u_app(char *d, size_t ds, char const *s, dk3_app_t *app)
+{
+ int back = 0;
+ size_t sz; /* Number of chars produced. */
+ if((d) && (ds) && (s)) {
+ sz = dk3str_i_cnv_c8p(NULL, s, app, DK3_ENCODING_UTF8);
+ if(sz) {
+ if(ds >= sz) {
+ if(dk3str_i_cnv_c8p((void *)d, s, app, DK3_ENCODING_UTF8)) {
+ back = 1;
+ }
+ } else {
+ if(app) {
+ /* ERROR: Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+char *
+dk3str_cnvnew_c8p_to_c8u_app(char const *s, dk3_app_t *app)
+{
+ char *back = NULL;
+ size_t sz; /* Number of characters produced. */
+ if(s) {
+ sz = dk3str_i_cnv_c8p(NULL, s, app, DK3_ENCODING_UTF8);
+ if(sz) {
+ back = dk3_new_app(char,sz,app);
+ if(back) {
+ if(!dk3str_i_cnv_c8p((void *)back, s, app, DK3_ENCODING_UTF8)) {
+ dk3_delete(back); back = NULL;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+size_t
+dk3str_cnvsz_c8p_to_c16_app(char const *s, dk3_app_t *app)
+{
+ size_t back = 0;
+ if(s) {
+ back = dk3str_i_cnv_c8p(NULL, s, app, DK3_ENCODING_UTF16);
+ }
+ return back;
+}
+
+
+
+int
+dk3str_cnv_c8p_to_c16_app(dk3_c16_t *d, size_t ds, char const *s, dk3_app_t *app)
+{
+ int back = 0;
+ size_t sz; /* Destination buffer length needed. */
+ if((d) && (ds) && (s)) {
+ sz = dk3str_i_cnv_c8p(NULL, s, app, DK3_ENCODING_UTF16);
+ if(sz) {
+ if(ds >= sz) {
+ if(dk3str_i_cnv_c8p((void *)d, s, app, DK3_ENCODING_UTF16)) {
+ back = 1;
+ }
+ } else {
+ if(app) {
+ /* ERROR: Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+dk3_c16_t *
+dk3str_cnvnew_c8p_to_c16_app(char const *s, dk3_app_t *app)
+{
+ dk3_c16_t *back = NULL;
+ size_t sz; /* Destination buffer length needed. */
+ if(s) {
+ sz = dk3str_i_cnv_c8p(NULL, s, app, DK3_ENCODING_UTF16);
+ if(sz) {
+ back = dk3_new_app(dk3_c16_t,sz,app);
+ if(back) {
+ if(!dk3str_i_cnv_c8p((void *)back, s, app, DK3_ENCODING_UTF16)) {
+ dk3_delete(back); back = NULL;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+size_t
+dk3str_cnvsz_c8p_to_c32_app(char const *s, dk3_app_t *app)
+{
+ size_t back = 0;
+ if(s) {
+ back = dk3str_i_cnv_c8p(NULL, s, app, DK3_ENCODING_UNICODE);
+ }
+ return back;
+}
+
+
+
+int
+dk3str_cnv_c8p_to_c32_app(dk3_c32_t *d, size_t ds, char const *s, dk3_app_t *app)
+{
+ int back = 0;
+ size_t sz; /* Destination buffer length needed. */
+ if((d) && (ds) && (s)) {
+ sz = dk3str_i_cnv_c8p(NULL, s, app, DK3_ENCODING_UNICODE);
+ if(sz) {
+ if(ds >= sz) {
+ if(dk3str_i_cnv_c8p((void *)d, s, app, DK3_ENCODING_UNICODE)) {
+ back = 1;
+ }
+ } else {
+ if(app) {
+ /* ERROR: Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+dk3_c32_t *
+dk3str_cnvnew_c8p_to_c32_app(char const *s, dk3_app_t *app)
+{
+ dk3_c32_t *back = NULL;
+ size_t sz; /* Destination buffer length needed. */
+ if(s) {
+ sz = dk3str_i_cnv_c8p(NULL, s, app, DK3_ENCODING_UNICODE);
+ if(sz) {
+ back = dk3_new_app(dk3_c32_t,sz,app);
+ if(back) {
+ if(!dk3str_i_cnv_c8p((void *)back, s, app, DK3_ENCODING_UNICODE)) {
+ dk3_delete(back); back = NULL;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Convert UTF-8 string to other encodings.
+ @param d Destination pointer, may be NULL.
+ @param s Source string.
+ @param app Application structure for diagnostics, may be NULL.
+ @param enc Destination encoding.
+ @return Buffer length used (d!=NULL) or needed (d==NULL).
+*/
+static
+size_t
+dk3str_i_cnv_c8u(void *d, char const *s, dk3_app_t *app, int enc)
+{
+ size_t back = 0;
+ int error = 0; /* Flag: Error occued. */
+ char *dp8 = NULL; /* Pointer to 8-bit destination. */
+ dk3_c16_t *dp16 = NULL; /* Pointer to 16-bit destination. */
+ dk3_c32_t *dp32 = NULL; /* Pointer to 32-bit destination. */
+ dk3_c16_t myc16[16]; /* Conversion result buffer. */
+ dk3_c32_t c32 = 0UL; /* Conversion result. */
+ unsigned char uc = 0x00; /* Result character. */
+ char c = 0x00; /* Current character to process. */
+ unsigned char const *sptr = NULL; /* Source ponter. */
+ size_t u8u = 0; /* Number of UTF-8 bytes used. */
+ size_t u16u = 0; /* Number of UTF-16 chars produced. */
+ size_t i = 0; /* Copy buffer to destination. */
+ size_t sl = 0; /* Remaining source string length. */
+
+
+#line 4693 "dk3str.ctr"
+ if(s) {
+ /* Initialize variables */
+ sptr = (unsigned char const *)s; sl = dk3str_c8_len(s);
+ if(d) {
+ switch(enc) {
+ case DK3_ENCODING_PLAIN: { dp8 = (char *)d; } break;
+ case DK3_ENCODING_UTF16: { dp16 = (dk3_c16_t *)d; } break;
+ case DK3_ENCODING_UNICODE: { dp32 = (dk3_c32_t *)d; } break;
+ default: {
+ if(0 == error) {
+ if(app) {
+ /* ERROR: Illegal output encoding! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 114);
+ }
+ } error = 1;
+ } break;
+ }
+ }
+ /* Process input */
+ while((sl) && (0 == error)) {
+ u8u = 0;
+ if(dk3enc_utf82uc(&c32, sptr, sl, &u8u)) {
+ if(u8u) {
+ switch(enc) {
+ case DK3_ENCODING_PLAIN: {
+ if(c32 < (dk3_c32_t)0x00000100UL) {
+ back = dk3mem_add_size_t(back, 1, &error);
+ if(d) {
+ uc = (unsigned char)c32;
+ c = (char)uc;
+ *(dp8++) = c;
+ }
+ } else {
+ if(0 == error) {
+ if(app) {
+ /* ERROR: Result character out of range! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 117);
+ }
+ } error = 1;
+ }
+ } break;
+ case DK3_ENCODING_UTF16: {
+ u16u = dk3enc_uc2utf16(c32, myc16, 16);
+ if(u16u) {
+ back = dk3mem_add_size_t(back, u16u, &error);
+ if(d) {
+ for(i = 0; i < u16u; i++) { *(dp16++) = myc16[i]; }
+ }
+ } else {
+ if(0 == error) {
+ if(app) {
+
+#line 4744 "dk3str.ctr"
+ /* ERROR: Conversion to UTF-16 failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 116);
+ }
+ } error = 1;
+ }
+ } break;
+ case DK3_ENCODING_UNICODE: {
+ back = dk3mem_add_size_t(back, 1, &error);
+ if(d) { *(dp32++) = c32; }
+ } break;
+ }
+ if(sl >= u8u) {
+ sl = sl - u8u;
+ sptr = &(sptr[u8u]);
+ } else {
+ sl = 0;
+ }
+ } else {
+ if(0 == error) {
+ if(app) {
+ /* ERROR: UTF-8 decode operation failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 118);
+ }
+ } error = 1;
+ }
+ } else {
+ if(0 == error) {
+ if(app) {
+ /* ERROR: UTF-8 decode operation failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 118);
+ }
+ } error = 1;
+ }
+ }
+ /* Finalize output */
+ back = dk3mem_add_size_t(back, 1, &error);
+ if(d) {
+ switch(enc) {
+ case DK3_ENCODING_PLAIN: { *dp8 = '\0'; } break;
+ case DK3_ENCODING_UTF16: { *dp16 = 0U; } break;
+ case DK3_ENCODING_UNICODE: { *dp32 = 0UL; } break;
+ }
+ }
+ if(error) {
+ back = 0;
+ if(error == DK3_ERROR_MATH_OVERFLOW) {
+ if(app) {
+ /* ERROR: Input string too long for conversion! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 108);
+ }
+ }
+ }
+ }
+
+#line 4797 "dk3str.ctr"
+ return back;
+}
+
+
+
+size_t
+dk3str_cnvsz_c8u_to_c8p_app(char const *s, dk3_app_t *app)
+{
+ size_t back = 0;
+ if(s) {
+ back = dk3str_i_cnv_c8u(NULL, s, app, DK3_ENCODING_PLAIN);
+ }
+ return back;
+}
+
+
+
+int
+dk3str_cnv_c8u_to_c8p_app(char *d, size_t ds, char const *s, dk3_app_t *app)
+{
+ int back = 0;
+ size_t sz; /* Destination buffer length needed. */
+ if((d) && (ds) && (s)) {
+ sz = dk3str_i_cnv_c8u(NULL, s, app, DK3_ENCODING_PLAIN);
+ if(sz) {
+ if(ds >= sz) {
+ if(dk3str_i_cnv_c8u((void *)d, s, app, DK3_ENCODING_PLAIN)) {
+ back = 1;
+ }
+ } else {
+ if(app) {
+ /* ERROR: Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+char *
+dk3str_cnvnew_c8u_to_c8p_app(char const *s, dk3_app_t *app)
+{
+ char *back = NULL;
+ size_t sz; /* Destination buffer length needed. */
+ if(s) {
+ sz = dk3str_i_cnv_c8u(NULL, s, app, DK3_ENCODING_PLAIN);
+ if(sz) {
+ back = dk3_new_app(char,sz,app);
+ if(back) {
+ if(!dk3str_i_cnv_c8u((void *)back, s, app, DK3_ENCODING_PLAIN)) {
+ dk3_delete(back); back = NULL;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+
+size_t
+dk3str_cnvsz_c8u_to_c16_app(char const *s, dk3_app_t *app)
+{
+ size_t back = 0;
+ if(s) {
+ back = dk3str_i_cnv_c8u(NULL, s, app, DK3_ENCODING_UTF16);
+ }
+ return back;
+}
+
+
+
+int
+dk3str_cnv_c8u_to_c16_app(dk3_c16_t *d, size_t ds, char const *s, dk3_app_t *app)
+{
+ int back = 0;
+ size_t sz; /* Destination buffer length needed. */
+ if((d) && (ds) && (s)) {
+ sz = dk3str_i_cnv_c8u(NULL, s, app, DK3_ENCODING_UTF16);
+ if(sz) {
+ if(ds >= sz) {
+ if(dk3str_i_cnv_c8u((void *)d, s, app, DK3_ENCODING_UTF16)) {
+ back = 1;
+ }
+ } else {
+ if(app) {
+ /* ERROR: Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+dk3_c16_t *
+dk3str_cnvnew_c8u_to_c16_app(char const *s, dk3_app_t *app)
+{
+ dk3_c16_t *back = NULL;
+ size_t sz; /* Destination buffer length needed. */
+ if(s) {
+ sz = dk3str_i_cnv_c8u(NULL, s, app, DK3_ENCODING_UTF16);
+ if(sz) {
+ back = dk3_new_app(dk3_c16_t,sz,app);
+ if(back) {
+ if(!dk3str_i_cnv_c8u((void *)back, s, app, DK3_ENCODING_UTF16)) {
+ dk3_delete(back); back = NULL;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+size_t
+dk3str_cnvsz_c8u_to_c32_app(char const *s, dk3_app_t *app)
+{
+ size_t back = 0;
+
+
+#line 4923 "dk3str.ctr"
+ if(s) {
+ back = dk3str_i_cnv_c8u(NULL, s, app, DK3_ENCODING_UNICODE);
+ }
+
+#line 4926 "dk3str.ctr"
+ return back;
+}
+
+
+
+int
+dk3str_cnv_c8u_to_c32_app(dk3_c32_t *d, size_t ds, char const *s, dk3_app_t *app)
+{
+ int back = 0;
+ size_t sz; /* Destination buffer length needed. */
+ if((d) && (ds) && (s)) {
+ sz = dk3str_i_cnv_c8u(NULL, s, app, DK3_ENCODING_UNICODE);
+ if(sz) {
+ if(ds >= sz) {
+ if(dk3str_i_cnv_c8u((void *)d, s, app, DK3_ENCODING_UNICODE)) {
+ back = 1;
+ }
+ } else {
+ if(app) {
+ /* ERROR: Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+dk3_c32_t *
+dk3str_cnvnew_c8u_to_c32_app(char const *s, dk3_app_t *app)
+{
+ dk3_c32_t *back = NULL;
+ size_t sz; /* Destination buffer length needed. */
+ if(s) {
+ sz = dk3str_i_cnv_c8u(NULL, s, app, DK3_ENCODING_UNICODE);
+ if(sz) {
+ back = dk3_new_app(dk3_c32_t,sz,app);
+ if(back) {
+ if(!dk3str_i_cnv_c8u((void *)back, s, app, DK3_ENCODING_UNICODE)) {
+ dk3_delete(back); back = NULL;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Convert 16-bit character string to other encodings.
+ @param d Destination pointer (NULL for size check).
+ @param s Source string.
+ @param app Application structure for diagnostics.
+ @param enc Destination encoding.
+ @return Number of destination characters needed/produced.
+*/
+static
+size_t
+dk3str_i_cnv_c16(void *d, dk3_c16_t const *s, dk3_app_t *app, int enc)
+{
+ size_t back = 0;
+ int error = 0; /* Flag: Error occured. */
+ char *dp8 = NULL; /* Pointer to 8-bit destination. */
+ dk3_c32_t *dp32 = NULL; /* Pointer to 32-bit destination. */
+ dk3_c16_t const *sptr = NULL; /* Source pointer. */
+ dk3_c32_t c32 = 0UL; /* Conversion result. */
+ unsigned char uc = 0x00; /* Current output character. */
+ char c = 0x00; /* Current output character. */
+ unsigned char myuc[16]; /* Conversion result buffer. */
+ size_t sl = 0; /* Remaining string length. */
+ size_t u16u = 0; /* Number of U16 characters used. */
+ size_t u8u = 0; /* Number of 8-bit chars produced. */
+ size_t i = 0; /* Copy buffer to destination. */
+ if(s) {
+ /* Initialize variables */
+ sptr = s; sl = dk3str_c16_len(s);
+ if(d) {
+ switch(enc) {
+ case DK3_ENCODING_PLAIN: { dp8 = (char *)d; } break;
+ case DK3_ENCODING_UTF8: { dp8 = (char *)d; } break;
+ case DK3_ENCODING_UNICODE: { dp32 = (dk3_c32_t *)d; } break;
+ default: {
+ if(0 == error) {
+ if(app) {
+ /* ERROR: Illegal output encoding! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 114);
+ }
+ } error = 1;
+ } break;
+ }
+ }
+ /* Process input */
+ while((sl) && (0 == error)) {
+ u16u = 0;
+ if(dk3enc_utf162uc(&c32, sptr, sl, &u16u)) {
+ if(u16u) {
+ if(sl >= u16u) {
+ switch(enc) {
+ case DK3_ENCODING_PLAIN: {
+ if(c32 < (dk3_c32_t)0x00000100UL) {
+ back = dk3mem_add_size_t(back, 1, &error);
+ if(d) {
+ uc = (unsigned char)c32; c = (char)uc;
+ *(dp8++) = c;
+ }
+ } else {
+ if(0 == error) {
+ if(app) {
+ /* ERROR: Result character out of range! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 117);
+ }
+ } error = 1;
+ }
+ } break;
+ case DK3_ENCODING_UTF8: {
+ u8u = dk3enc_uc2utf8(c32, myuc, 16);
+ if(u8u) {
+ back = dk3mem_add_size_t(back, u8u, &error);
+ if(d) {
+ for(i = 0; i < u8u; i++) { *(dp8++) = myuc[i]; }
+ }
+ } else {
+ if(0 == error) {
+ if(app) {
+ /* ERROR: Conversion to UTF-8 failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 115);
+ }
+ } error = 1;
+ }
+ } break;
+ case DK3_ENCODING_UNICODE: {
+ back = dk3mem_add_size_t(back, 1, &error);
+ if(d) { *(dp32++) = c32; }
+ } break;
+ }
+ sl = sl - u16u;
+ sptr = &(sptr[u16u]);
+ } else {
+ sl = 0;
+ }
+ } else {
+ if(0 == error) {
+ if(app) {
+ /* ERROR: UTF-16 decode operation failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 119);
+ }
+ } error = 1;
+ }
+ } else {
+ if(0 == error) {
+ if(app) {
+ /* ERROR: UTF-16 decode operation failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 119);
+ }
+ } error = 1;
+ }
+ }
+ /* Finalize output */
+ back = dk3mem_add_size_t(back, 1, &error);
+ if(d) {
+ switch(enc) {
+ case DK3_ENCODING_PLAIN: { *dp8 = '\0'; } break;
+ case DK3_ENCODING_UTF8: { *dp8 = '\0'; } break;
+ case DK3_ENCODING_UNICODE: { *dp32 = 0UL; } break;
+ }
+ }
+ if(error) {
+ back = 0;
+ if(error == DK3_ERROR_MATH_OVERFLOW) {
+ if(app) {
+ /* ERROR: Input string too long for conversion! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 108);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+size_t
+dk3str_cnvsz_c16_to_c8p_app(dk3_c16_t const *s, dk3_app_t *app)
+{
+ size_t back = 0;
+ if(s) {
+ back = dk3str_i_cnv_c16(NULL, s, app, DK3_ENCODING_PLAIN);
+ }
+ return back;
+}
+
+
+
+int
+dk3str_cnv_c16_to_c8p_app(char *d, size_t ds, dk3_c16_t const *s, dk3_app_t *app)
+{
+ int back = 0;
+ size_t sz; /* Destination buffer size needed. */
+ if((d) && (ds) && (s)) {
+ sz = dk3str_i_cnv_c16(NULL, s, app, DK3_ENCODING_PLAIN);
+ if(sz) {
+ if(ds >= sz) {
+ if(dk3str_i_cnv_c16((void *)d, s, app, DK3_ENCODING_PLAIN)) {
+ back = 1;
+ }
+ } else {
+ if(app) {
+ /* ERROR: Result buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+char *
+dk3str_cnvnew_c16_to_c8p_app(dk3_c16_t const *s, dk3_app_t *app)
+{
+ char *back = NULL;
+ size_t sz; /* Destination buffer size needed. */
+ if(s) {
+ sz = dk3str_i_cnv_c16(NULL, s, app, DK3_ENCODING_PLAIN);
+ if(sz) {
+ back = dk3_new_app(char,sz,app);
+ if(back) {
+ if(!dk3str_i_cnv_c16((void *)back, s, app, DK3_ENCODING_PLAIN)) {
+ dk3_delete(back); back = NULL;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+size_t
+dk3str_cnvsz_c16_to_c8u_app(dk3_c16_t const *s, dk3_app_t *app)
+{
+ size_t back = 0;
+ if(s) {
+ back = dk3str_i_cnv_c16(NULL, s, app, DK3_ENCODING_UTF8);
+ }
+ return back;
+}
+
+
+
+int
+dk3str_cnv_c16_to_c8u_app(char *d, size_t ds, dk3_c16_t const *s, dk3_app_t *app)
+{
+ int back = 0;
+ size_t sz; /* Destination buffer size needed. */
+ if((d) && (ds) && (s)) {
+ sz = dk3str_i_cnv_c16(NULL, s, app, DK3_ENCODING_UTF8);
+ if(sz) {
+ if(ds >= sz) {
+ if(dk3str_i_cnv_c16((void *)d, s, app, DK3_ENCODING_UTF8)) {
+ back = 1;
+ }
+ } else {
+ if(app) {
+ /* ERROR: Result buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+char *
+dk3str_cnvnew_c16_to_c8u_app(dk3_c16_t const *s, dk3_app_t *app)
+{
+ char *back = NULL;
+ size_t sz; /* Destination buffer size needed. */
+ if(s) {
+ sz = dk3str_i_cnv_c16(NULL, s, app, DK3_ENCODING_UTF8);
+ if(sz) {
+ back = dk3_new_app(char,sz,app);
+ if(back) {
+ if(!dk3str_i_cnv_c16((void *)back, s, app, DK3_ENCODING_UTF8)) {
+ dk3_delete(back); back = NULL;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3str_c16_to_c8_simple_app(
+ char *d, size_t sz, dk3_c16_t const *s, dk3_app_t *app
+)
+{
+ int back = 0;
+ dk3_c16_t const *ptr; /* Source pointer. */
+ dk3_c16_t c; /* Source character. */
+ unsigned char uc; /* Destination character. */
+ char *dptr; /* Destination pointer. */
+
+ if((d) && (sz) && (s)) {
+ if(dk3str_c16_len(s) < sz) {
+ back = 1; ptr = s; dptr = d;
+ while(0U != (c = *ptr)) {
+ if(c < 0x0100U) {
+ uc = (unsigned char)c;
+ *(dptr++) = (char)uc;
+ } else {
+ if((back == 1) && (app)) {
+ /* ERROR: Illegal character(s) in source string! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 112);
+ }
+ back = 0;
+ }
+ ptr++;
+ }
+ *dptr = '\0';
+ } else {
+ d[0] = '\0';
+ if(app) {
+ /* ERROR: Source string too long! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 108);
+ }
+ }
+ }
+ return back;
+}
+
+
+size_t
+dk3str_cnvsz_c16_to_c32_app(dk3_c16_t const *s, dk3_app_t *app)
+{
+ size_t back = 0;
+ if(s) {
+ back = dk3str_i_cnv_c16(NULL, s, app, DK3_ENCODING_UNICODE);
+ }
+ return back;
+}
+
+
+
+int
+dk3str_cnv_c16_to_c32_app(dk3_c32_t *d, size_t ds, dk3_c16_t const *s, dk3_app_t *app)
+{
+ int back = 0;
+ size_t sz; /* Destination buffer size needed. */
+ if((d) && (ds) && (s)) {
+ sz = dk3str_i_cnv_c16(NULL, s, app, DK3_ENCODING_UNICODE);
+ if(sz) {
+ if(ds >= sz) {
+ if(dk3str_i_cnv_c16((void *)d, s, app, DK3_ENCODING_UNICODE)) {
+ back = 1;
+ }
+ } else {
+ if(app) {
+ /* ERROR: Result buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+dk3_c32_t *
+dk3str_cnvnew_c16_to_c32_app(dk3_c16_t const *s, dk3_app_t *app)
+{
+ dk3_c32_t *back = NULL;
+ size_t sz; /* Destination buffer size needed. */
+ if(s) {
+ sz = dk3str_i_cnv_c16(NULL, s, app, DK3_ENCODING_UNICODE);
+ if(sz) {
+ back = dk3_new_app(dk3_c32_t,sz,app);
+ if(back) {
+ if(!dk3str_i_cnv_c16((void *)back, s, app, DK3_ENCODING_UNICODE)) {
+ dk3_delete(back); back = NULL;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Convert 32-bit character string to other encodings.
+ @param d Destination buffer pointer (may be NULL for size check).
+ @param s Source string.
+ @param app Application structure for diagnostics.
+ @param enc Output encoding.
+ @return Number of destination characters produced/needed.
+*/
+static
+size_t
+dk3str_i_cnv_c32(void *d, dk3_c32_t const *s, dk3_app_t *app, int enc)
+{
+ size_t back = 0;
+ int error = 0; /* Flag: Error occured. */
+ char *dp8 = NULL; /* Pointer to 8-bit destination. */
+ dk3_c16_t *dp16 = NULL; /* Pointer to 16-bit destination. */
+ dk3_c32_t const *sptr = NULL; /* Source pointer. */
+ dk3_c32_t c32 = 0UL; /* Current character to process. */
+ dk3_c16_t myc16[16]; /* Conversion result buffer. */
+ unsigned char myuc[16]; /* Conversion result buffer. */
+ unsigned char uc = 0x00; /* Output character. */
+ char c = 0x00; /* Output character. */
+ size_t sl = 0; /* Remaining string length. */
+ size_t u8u = 0; /* Number of UTF-8 chars produced. */
+ size_t u16u = 0; /* Numer of UTF-16 chars produced. */
+ size_t i = 0; /* Copy buffer to destination. */
+
+
+#line 5348 "dk3str.ctr"
+ if(s) {
+ /* Initialize variables */
+ sptr = s; sl = dk3str_c32_len(s);
+ if(d) {
+ switch(enc) {
+ case DK3_ENCODING_PLAIN: { dp8 = (char *)d; } break;
+ case DK3_ENCODING_UTF8: { dp8 = (char *)d; } break;
+ case DK3_ENCODING_UTF16: { dp16 = (dk3_c16_t *)d; } break;
+ default: {
+ if(0 == error) {
+ if(app) {
+ /* ERROR: Illegal output encoding! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 114);
+ }
+ } error = 1;
+ } break;
+ }
+ }
+ /* Process input */
+ while((sl) && (0 == error)) {
+ c32 = *(sptr++); sl--;
+ switch(enc) {
+ case DK3_ENCODING_PLAIN: {
+ if(c32 < (dk3_c32_t)0x00000100UL) {
+ back = dk3mem_add_size_t(back, 1, &error);
+ if(d) {
+ uc = (unsigned char)c32; c = (char)uc;
+ *(dp8++) = c;
+ }
+ } else {
+ if(0 == error) {
+ if(app) {
+ /* ERROR: Output character out of range! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 117);
+ }
+ } error = 1;
+ }
+ } break;
+ case DK3_ENCODING_UTF8: {
+ u8u = dk3enc_uc2utf8(c32, myuc, 16);
+ if(u8u) {
+ back = dk3mem_add_size_t(back, u8u, &error);
+ if(d) {
+ for(i = 0; i < u8u; i++) { *(dp8++) = myuc[i]; }
+ }
+ } else {
+ if(0 == error) {
+ if(app) {
+ /* ERROR: UTF-8 encoding failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 115);
+ }
+ } error = 1;
+ }
+ } break;
+ case DK3_ENCODING_UTF16: {
+ u16u = dk3enc_uc2utf16(c32, myc16, 16);
+ if(u16u) {
+ back = dk3mem_add_size_t(back, u16u, &error);
+ if(d) {
+ for(i = 0; i < u16u; i++) { *(dp16++) = myc16[i]; }
+ }
+ } else {
+ if(0 == error) {
+ if(app) {
+
+#line 5412 "dk3str.ctr"
+ /* ERROR: Conversion to UTF-16 failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 116);
+ }
+ } error = 1;
+ }
+ } break;
+ }
+ }
+ /* Finalize output */
+ back = dk3mem_add_size_t(back, 1, &error);
+ if(d) {
+ switch(enc) {
+ case DK3_ENCODING_PLAIN: { *dp8 = '\0'; } break;
+ case DK3_ENCODING_UTF8: { *dp8 = '\0'; } break;
+ case DK3_ENCODING_UTF16: { *dp16 = 0U; } break;
+ }
+ }
+ if(error) {
+ back = 0;
+ if(error == DK3_ERROR_MATH_OVERFLOW) {
+ if(app) {
+ /* ERROR: Input string too long for conversion! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 108);
+ }
+ }
+ }
+ }
+
+#line 5439 "dk3str.ctr"
+ return back;
+}
+
+
+
+size_t
+dk3str_cnvsz_c32_to_c8p_app(dk3_c32_t const *s, dk3_app_t *app)
+{
+ size_t back = 0;
+ if(s) {
+ back = dk3str_i_cnv_c32(NULL, s, app, DK3_ENCODING_PLAIN);
+ }
+ return back;
+}
+
+
+
+int
+dk3str_cnv_c32_to_c8p_app(char *d, size_t ds, dk3_c32_t const *s, dk3_app_t *app)
+{
+ int back = 0;
+ size_t sz; /* Destination buffer size needed. */
+ if((d) && (ds) && (s)) {
+ sz = dk3str_i_cnv_c32(NULL, s, app, DK3_ENCODING_PLAIN);
+ if(sz) {
+ if(ds >= sz) {
+ if(dk3str_i_cnv_c32((void *)d, s, app, DK3_ENCODING_PLAIN)) {
+ back = 1;
+ }
+ } else {
+ if(app) {
+ /* ERROR: Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+char *
+dk3str_cnvnew_c32_to_c8p_app(dk3_c32_t const *s, dk3_app_t *app)
+{
+ char *back = NULL;
+ size_t sz; /* Destination buffer size needed. */
+ if(s) {
+ sz = dk3str_i_cnv_c32(NULL, s, app, DK3_ENCODING_PLAIN);
+ if(sz) {
+ back = dk3_new_app(char,sz,app);
+ if(back) {
+ if(!dk3str_i_cnv_c32((void *)back, s, app, DK3_ENCODING_PLAIN)) {
+ dk3_delete(back); back = NULL;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+size_t
+dk3str_cnvsz_c32_to_c8u_app(dk3_c32_t const *s, dk3_app_t *app)
+{
+ size_t back = 0;
+ if(s) {
+ back = dk3str_i_cnv_c32(NULL, s, app, DK3_ENCODING_UTF8);
+ }
+ return back;
+}
+
+
+
+int
+dk3str_cnv_c32_to_c8u_app(char *d, size_t ds, dk3_c32_t const *s, dk3_app_t *app)
+{
+ int back = 0;
+ size_t sz; /* Destination buffer size needed. */
+ if((d) && (ds) && (s)) {
+ sz = dk3str_i_cnv_c32(NULL, s, app, DK3_ENCODING_UTF8);
+ if(sz) {
+ if(ds >= sz) {
+ if(dk3str_i_cnv_c32((void *)d, s, app, DK3_ENCODING_UTF8)) {
+ back = 1;
+ }
+ } else {
+ if(app) {
+ /* ERROR: Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+char *
+dk3str_cnvnew_c32_to_c8u_app(dk3_c32_t const *s, dk3_app_t *app)
+{
+ char *back = NULL;
+ size_t sz; /* Destination buffer size needed. */
+ if(s) {
+ sz = dk3str_i_cnv_c32(NULL, s, app, DK3_ENCODING_UTF8);
+ if(sz) {
+ back = dk3_new_app(char,sz,app);
+ if(back) {
+ if(!dk3str_i_cnv_c32((void *)back, s, app, DK3_ENCODING_UTF8)) {
+ dk3_delete(back); back = NULL;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+size_t
+dk3str_cnvsz_c32_to_c16_app(dk3_c32_t const *s, dk3_app_t *app)
+{
+ size_t back = 0;
+ if(s) {
+ back = dk3str_i_cnv_c32(NULL, s, app, DK3_ENCODING_UTF16);
+ }
+ return back;
+}
+
+
+
+int
+dk3str_cnv_c32_to_c16_app(dk3_c16_t *d, size_t ds, dk3_c32_t const *s, dk3_app_t *app)
+{
+ int back = 0;
+ size_t sz; /* Destination buffer size needed. */
+ if((d) && (ds) && (s)) {
+ sz = dk3str_i_cnv_c32(NULL, s, app, DK3_ENCODING_UTF16);
+ if(sz) {
+ if(ds >= sz) {
+ if(dk3str_i_cnv_c32((void *)d, s, app, DK3_ENCODING_UTF16)) {
+ back = 1;
+ }
+ } else {
+ if(app) {
+ /* ERROR: Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+dk3_c16_t *
+dk3str_cnvnew_c32_to_c16_app(dk3_c32_t const *s, dk3_app_t *app)
+{
+ dk3_c16_t *back = NULL;
+ size_t sz; /* Destination buffer size needed. */
+ if(s) {
+ sz = dk3str_i_cnv_c32(NULL, s, app, DK3_ENCODING_UTF16);
+ if(sz) {
+ back = dk3_new_app(dk3_c16_t,sz,app);
+ if(back) {
+ if(!dk3str_i_cnv_c32((void *)back, s, app, DK3_ENCODING_UTF16)) {
+ dk3_delete(back); back = NULL;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3str_cnv_c8_to_str_app(dkChar *d, size_t sz, char const *s, dk3_app_t *app)
+{
+ register int back = 0;
+ register size_t l; /* Number of destination chars used. */
+ register char const *sptr; /* Source pointer. */
+ register dkChar *dptr; /* Destination pointer. */
+ register char x = 0x00; /* Current character to process. */
+
+ if((d) && (sz) && (s)) {
+ sptr = s; dptr = d; l = 0; back = 1;
+ while((*sptr) && (l < (sz - 1))) {
+ x = *(sptr++);
+ *(dptr++) = (dkChar)x;
+ l++;
+ }
+ *dptr = (dkChar)'\0';
+ if(*sptr) {
+ back = 0;
+ if(app) {
+ /* ERROR: Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3str_string_to_c8_simple_app(char *db,size_t sz,dkChar const *s,dk3_app_t *ap)
+{
+ int back = 0;
+ register dkChar const *sptr; /* Source pointer. */
+ register dkChar x; /* Current source character. */
+ register char *dptr; /* Destination pointer. */
+
+ if((db) && (sz) && (s)) {
+ if(dk3str_len(s) < sz) {
+ back = 1;
+ sptr = s; dptr = db;
+ while(*sptr) {
+ x = *(sptr++);
+ *(dptr++) = (char)x;
+#if DK3_CHAR_SIZE > 1
+ if(x > (dkChar)0xFF) {
+ back = 0;
+ }
+#endif
+ }
+ *dptr = '\0';
+ if(!(back)) {
+ if(ap) {
+ /* ERROR: Non-ISO-LATIN-1 characters found! */
+ dk3app_log_i1(ap, DK3_LL_ERROR, 219);
+ }
+ }
+ } else {
+ if(ap) {
+ /* ERROR: Destination buffer too short! */
+ dk3app_log_i1(ap, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void
+dk3str_string_tolower(dkChar *s)
+{
+ dkChar *ptr; /* Pointer into string. */
+ if(s) {
+ ptr = s;
+ while(*ptr) {
+ *ptr = dk3str_tolower(*ptr);
+ ptr++;
+ }
+ }
+}
+
+
+
+int
+dk3str_c8_to_str_simple_app(
+ dkChar *dp, size_t ds, char const *sp, dk3_app_t *app
+)
+{
+ int back = 0;
+ char const *sptr; /* Pointer into source buffer. */
+ dkChar *dptr; /* Pointer into destination buffer. */
+ size_t sz; /* Required destination size. */
+ if((dp) && (ds) && (sp)) {
+ sz = dk3str_c8_len(sp);
+ if(ds > sz) {
+ back = 1; sptr = sp; dptr = dp;
+ while(*sptr) { *(dptr++) = (dkChar)(*(sptr++)); }
+ *dptr = dkT('\0');
+ } else {
+ if(app) {
+ /* ERROR: Destination buffer too short! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3str_to_c8p_app(
+ char *dp, size_t sz, dkChar const *src, int ie, dk3_app_t *app
+)
+{
+ int back = 0;
+ if((dp) && (sz) && (src)) {
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ back = dk3str_cnv_c32_to_c8p_app(dp, sz, src, app);
+#else
+ back = dk3str_cnv_c16_to_c8p_app(dp, sz, src, app);
+#endif
+#else
+ if(ie == DK3_ENCODING_PLAIN) {
+ if(sz > dk3str_c8_len(src)) {
+ dk3str_c8_cpy(dp, src);
+ back = 1;
+ }
+ } else {
+ back = dk3str_cnv_c8u_to_c8p_app(dp, sz, src, app);
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3str_to_c8u_app(
+ char *dp, size_t sz, dkChar const *src, int ie, dk3_app_t *app
+)
+{
+ int back = 0;
+ if((dp) && (sz) && (src)) {
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ back = dk3str_cnv_c32_to_c8u_app(dp, sz, src, app);
+#else
+ back = dk3str_cnv_c16_to_c8u_app(dp, sz, src, app);
+#endif
+#else
+ if(ie == DK3_ENCODING_PLAIN) {
+ back = dk3str_cnv_c8p_to_c8u_app(dp, sz, src, app);
+ } else {
+ if(sz > dk3str_c8_len(src)) {
+ dk3str_c8_cpy(dp, src);
+ back = 1;
+ }
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3str_str_to_c8u_app(
+ char *d,
+ size_t dsz,
+ dkChar const *s,
+ int se,
+ dk3_app_t *app
+)
+{
+ int back = 0;
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ back = dk3str_cnv_c32_to_c8u_app(d, dsz, s, app);
+#else
+ back = dk3str_cnv_c16_to_c8u_app(d, dsz, s, app);
+#endif
+#else
+ switch(se) {
+ case DK3_ENCODING_UTF8: {
+ if(dk3str_c8_len(s) < dsz) {
+ dk3str_c8_cpy(d, s);
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: String too long! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 108);
+ }
+ }
+ } break;
+ default: {
+ back = dk3str_cnv_c8p_to_c8u_app(d, dsz, s, app);
+ } break;
+ }
+#endif
+ return back;
+}
+
+
+
+int
+dk3str_c8u_to_str_app(
+ dkChar *d,
+ size_t dsz,
+ int de,
+ char const *s,
+ dk3_app_t *app
+)
+{
+ int back = 0;
+
+
+#line 5838 "dk3str.ctr"
+ if((d) && (dsz) && (s)) {
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+
+
+#line 5842 "dk3str.ctr"
+ back = dk3str_cnv_c8u_to_c32_app(d, dsz, s, app);
+#else
+
+
+#line 5845 "dk3str.ctr"
+ back = dk3str_cnv_c8u_to_c16_app(d, dsz, s, app);
+#endif
+#else
+ switch(de) {
+ case DK3_ENCODING_UTF8: {
+
+
+#line 5851 "dk3str.ctr"
+ if(dsz > dk3str_c8_len(s)) {
+ dk3str_c8_cpy(d, s);
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Source string too long! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 108);
+ }
+ }
+ } break;
+ default: {
+
+
+#line 5863 "dk3str.ctr"
+ back = dk3str_cnv_c8u_to_c8p_app(d, dsz, s, app);
+ } break;
+ }
+#endif
+ }
+
+#line 5868 "dk3str.ctr"
+ return back;
+}
+
+
+
+int
+dk3str_to_c8_app(char *dp, size_t szdp, dkChar const *src, dk3_app_t *app)
+{
+ int back = 0;
+
+
+#line 5878 "dk3str.ctr"
+ if((dp) && (szdp) && (src)) {
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ back = dk3str_cnv_c32_to_c8p_app(dp, szdp, src, app);
+#else
+ back = dk3str_cnv_c16_to_c8p_app(dp, szdp, src, app);
+#endif
+#else
+ if(strlen(src) < szdp) {
+ strcpy(dp, src);
+ back = 1;
+ } else {
+ /* ERROR: Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+#endif
+ }
+
+#line 5895 "dk3str.ctr"
+ return back;
+}
+
+
+
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dk3str.ctr b/support/dktools/dk3str.ctr
new file mode 100644
index 0000000000..063198c42d
--- /dev/null
+++ b/support/dktools/dk3str.ctr
@@ -0,0 +1,5904 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+%% header
+
+#include "dk3conf.h"
+#include "dk3types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Calculate string length.
+ * @param s String to process.
+ * @return String length (number of characters).
+ */
+size_t
+dk3str_c8_len(char const *s);
+
+/** Calculate string length.
+ * @param s String to process.
+ * @return String length (number of characters).
+ */
+size_t
+dk3str_c16_len(dk3_c16_t const *s);
+
+/** Calculate string length.
+ * @param s String to process.
+ * @return String length (number of characters).
+ */
+size_t
+dk3str_c32_len(dk3_c32_t const *s);
+
+/** Calculate string length.
+ * @param s String to process.
+ * @return String length (number of characters).
+ */
+size_t
+dk3str_len(dkChar const *s);
+
+/** Compare two strings.
+ * @param s1 Left side string.
+ * @param s2 Right side string.
+ * @return 1 for s1>s2, 0 for s1=s2, -1 for s1<s2.
+ */
+int
+dk3str_c8_cmp(char const *s1, char const *s2);
+
+/** Compare two strings.
+ * @param s1 Left side string.
+ * @param s2 Right side string.
+ * @return 1 for s1>s2, 0 for s1=s2, -1 for s1<s2.
+ */
+int
+dk3str_c16_cmp(dk3_c16_t const *s1, dk3_c16_t const *s2);
+
+/** Compare two strings.
+ * @param s1 Left side string.
+ * @param s2 Right side string.
+ * @return 1 for s1>s2, 0 for s1=s2, -1 for s1<s2.
+ */
+int
+dk3str_c32_cmp(dk3_c32_t const *s1, dk3_c32_t const *s2);
+
+/** Compare two strings.
+ * @param s1 Left side string.
+ * @param s2 Right side string.
+ * @return 1 for s1>s2, 0 for s1=s2, -1 for s1<s2.
+ */
+int
+dk3str_cmp(dkChar const *s1, dkChar const *s2);
+
+/** Case-insensitve string comparison.
+ * @param s1 Left side string.
+ * @param s2 Right side string.
+ * @return 1 for s1>s2, 0 for s1=s2, -1 for s1<s2.
+ */
+int
+dk3str_c8_casecmp(char const *s1, char const *s2);
+
+
+/** Case-insensitve string comparison.
+ * @param s1 Left side string.
+ * @param s2 Right side string.
+ * @return 1 for s1>s2, 0 for s1=s2, -1 for s1<s2.
+ */
+int
+dk3str_c16_casecmp(dk3_c16_t const *s1, dk3_c16_t const *s2);
+
+/** Case-insensitve string comparison.
+ * @param s1 Left side string.
+ * @param s2 Right side string.
+ * @return 1 for s1>s2, 0 for s1=s2, -1 for s1<s2.
+ */
+int
+dk3str_c32_casecmp(dk3_c32_t const *s1, dk3_c32_t const *s2);
+
+/** Case-insensitve string comparison.
+ * @param s1 Left side string.
+ * @param s2 Right side string.
+ * @return 1 for s1>s2, 0 for s1=s2, -1 for s1<s2.
+ */
+int
+dk3str_casecmp(dkChar const *s1, dkChar const *s2);
+
+/** File name comparison, case-sensitive on some systems,
+ * case-insensitive on other systems.
+ * @param s1 Left side string.
+ * @param s2 Right side string.
+ * @return 1 for s1>s2, 0 for s1=s2, -1 for s1<s2.
+ */
+int
+dk3str_fncmp(dkChar const *s1, dkChar const *s2) ;
+
+/** Compare two strings, use only the first \a n characters.
+ * @param s1 Left side string.
+ * @param s2 Right side string.
+ * @param n Number of characters to use in comparison.
+ * @return 1 for s1>s2, 0 for s1=s2, -1 for s1<s2.
+ */
+int
+dk3str_c8_ncmp(char const *s1, char const *s2, size_t n);
+
+/** Compare two strings, use only the first \a n characters.
+ * @param s1 Left side string.
+ * @param s2 Right side string.
+ * @param n Number of characters to use in comparison.
+ * @return 1 for s1>s2, 0 for s1=s2, -1 for s1<s2.
+ */
+int
+dk3str_c16_ncmp(dk3_c16_t const *s1, dk3_c16_t const *s2, size_t n);
+
+/** Compare two strings, use only the first \a n characters.
+ * @param s1 Left side string.
+ * @param s2 Right side string.
+ * @param n Number of characters to use in comparison.
+ * @return 1 for s1>s2, 0 for s1=s2, -1 for s1<s2.
+ */
+int
+dk3str_c32_ncmp(dk3_c32_t const *s1, dk3_c32_t const *s2, size_t n);
+
+/** Compare two strings, use only the first \a n characters.
+ * @param s1 Left side string.
+ * @param s2 Right side string.
+ * @param n Number of characters to use in comparison.
+ * @return 1 for s1>s2, 0 for s1=s2, -1 for s1<s2.
+ */
+int
+dk3str_ncmp(dkChar const *s1, dkChar const *s2, size_t n);
+
+/** Find left-most orrucance of character in string.
+ * @param s String probably containing the character.
+ * @param c Character to search for.
+ * @return Pointer to character position on success, NULL on error.
+ */
+char *
+dk3str_c8_chr(char const *s, char c);
+
+/** Find left-most orrucance of character in string.
+ * @param s String probably containing the character.
+ * @param c Character to search for.
+ * @return Pointer to character position on success, NULL on error.
+ */
+dk3_c16_t *
+dk3str_c16_chr(dk3_c16_t const *s, dk3_c16_t c);
+
+/** Find left-most orrucance of character in string.
+ * @param s String probably containing the character.
+ * @param c Character to search for.
+ * @return Pointer to character position on success, NULL on error.
+ */
+dk3_c32_t *
+dk3str_c32_chr(dk3_c32_t const *s, dk3_c32_t c);
+
+/** Find left-most orrucance of character in string.
+ * @param s String probably containing the character.
+ * @param c Character to search for.
+ * @return Pointer to character position on success, NULL on error.
+ */
+dkChar *
+dk3str_chr(dkChar const *s, dkChar c);
+
+/** Find right-most orrucance of character in string.
+ * @param s String probably containing the character.
+ * @param c Character to search for.
+ * @return Pointer to character position on success, NULL on error.
+ */
+char *
+dk3str_c8_rchr(char const *s, char c);
+
+/** Find right-most orrucance of character in string.
+ * @param s String probably containing the character.
+ * @param c Character to search for.
+ * @return Pointer to character position on success, NULL on error.
+ */
+dk3_c16_t *
+dk3str_c16_rchr(dk3_c16_t const *s, dk3_c16_t c);
+
+/** Find right-most orrucance of character in string.
+ * @param s String probably containing the character.
+ * @param c Character to search for.
+ * @return Pointer to character position on success, NULL on error.
+ */
+dk3_c32_t *
+dk3str_c32_rchr(dk3_c32_t const *s, dk3_c32_t c);
+
+/** Find right-most orrucance of character in string.
+ * @param s String probably containing the character.
+ * @param c Character to search for.
+ * @return Pointer to character position on success, NULL on error.
+ */
+dkChar *
+dk3str_rchr(dkChar const *s, dkChar c);
+
+/** Copy string.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ */
+void
+dk3str_c8_cpy(char *d, char const *s);
+
+/** Copy string.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ */
+void
+dk3str_c16_cpy(dk3_c16_t *d, dk3_c16_t const *s);
+
+/** Copy string.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ */
+void
+dk3str_c32_cpy(dk3_c32_t *d, dk3_c32_t const *s);
+
+/** Copy string.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ */
+void
+dk3str_cpy(dkChar *d, dkChar const *s);
+
+/** Copy string.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ */
+void
+dk3str_c8_cpy_not_overlapped(char *d, char const *s);
+
+/** Copy string.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ */
+void
+dk3str_c16_cpy_not_overlapped(dk3_c16_t *d, dk3_c16_t const *s);
+
+/** Copy string.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ */
+void
+dk3str_c32_cpy_not_overlapped(dk3_c32_t *d, dk3_c32_t const *s);
+
+/** Copy string.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ */
+void
+dk3str_cpy_not_overlapped(dkChar *d, dkChar const *s);
+
+/** Copy string, cut to buffer size if necessary.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ * @param n Size of \a d (number of characters).
+ */
+void
+dk3str_c8_ncpy(char *d, char const *s, size_t n);
+
+/** Copy string, cut to buffer size if necessary.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ * @param n Size of \a d (number of characters).
+ */
+void
+dk3str_c16_ncpy(dk3_c16_t *d, dk3_c16_t const *s, size_t n);
+
+/** Copy string, cut to buffer size if necessary.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ * @param n Size of \a d (number of characters).
+ */
+void
+dk3str_c32_ncpy(dk3_c32_t *d, dk3_c32_t const *s, size_t n);
+
+/** Copy string, cut to buffer size if necessary.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ * @param n Size of \a d (number of characters).
+ */
+void
+dk3str_ncpy(dkChar *d, dkChar const *s, size_t n);
+
+/** Concatenate two strings.
+ * Do not use this function directly, use dk3str_c8_cat() instead.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ */
+void
+dk3str_c8_cat(char *d, char const *s);
+
+/** Concatenate two strings.
+ * Do not use this function directly, use dk3str_c16_cat() instead.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ */
+void
+dk3str_c16_cat(dk3_c16_t *d, dk3_c16_t const *s);
+
+/** Concatenate two strings.
+ * Do not use this function directly, use dk3str_c32_cat() instead.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ */
+void
+dk3str_c32_cat(dk3_c32_t *d, dk3_c32_t const *s);
+
+/** Concatenate two strings.
+ * Do not use this function directly, use dk3str_c32_cat() instead.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ */
+void
+dk3str_cat(dkChar *d, dkChar const *s);
+
+/** Create a string copy in dynamically allocated memory.
+ @param s Original string.
+ @param app Application structure for diagnostics.
+ @return Pointer to copy on success, NULL on error.
+ The pointer returned on success must be released by
+ dk3_release() when done with it.
+*/
+char *
+dk3str_c8_dup_app(char const *s, dk3_app_t *app);
+
+/** Create a string copy in dynamically allocated memory.
+ @param s Original string.
+ @param app Application structure for diagnostics.
+ @return Pointer to copy on success, NULL on error.
+ The pointer returned on success must be released by
+ dk3_release() when done with it.
+*/
+dk3_c16_t *
+dk3str_c16_dup_app(dk3_c16_t const *s, dk3_app_t *app);
+
+/** Create a string copy in dynamically allocated memory.
+ @param s Original string.
+ @param app Application structure for diagnostics.
+ @return Pointer to copy on success, NULL on error.
+ The pointer returned on success must be released by
+ dk3_release() when done with it.
+*/
+dk3_c32_t *
+dk3str_c32_dup_app(dk3_c32_t const *s, dk3_app_t *app);
+
+/** Create a string copy in dynamically allocated memory.
+ @param s Original string.
+ @param app Application structure for diagnostics.
+ @return Pointer to copy on success, NULL on error.
+ The pointer returned on success must be released by
+ dk3_release() when done with it.
+*/
+dkChar *
+dk3str_dup_app(dkChar const *s, dk3_app_t *app);
+
+/** Convert to lower-case character.
+ * @param c Character to convert.
+ * @return Conversion result.
+ */
+char
+dk3str_c8_tolower(char c);
+
+/** Convert to lower-case character.
+ * @param c Character to convert.
+ * @return Conversion result.
+ */
+dk3_c16_t
+dk3str_c16_tolower(dk3_c16_t c);
+
+/** Convert to lower-case character.
+ * @param c Character to convert.
+ * @return Conversion result.
+ */
+dk3_c32_t
+dk3str_c32_tolower(dk3_c32_t c);
+
+/** Convert to lower-case character.
+ * @param c Character to convert.
+ * @return Conversion result.
+ */
+dkChar
+dk3str_tolower(dkChar c);
+
+/** Convert to upper-case character.
+ * @param c Character to convert.
+ * @return Conversion result.
+ */
+char
+dk3str_c8_toupper(char c);
+
+/** Convert to upper-case character.
+ * @param c Character to convert.
+ * @return Conversion result.
+ */
+dk3_c16_t
+dk3str_c16_toupper(dk3_c16_t c);
+
+/** Convert to upper-case character.
+ * @param c Character to convert.
+ * @return Conversion result.
+ */
+dk3_c32_t
+dk3str_c32_toupper(dk3_c32_t c);
+
+/** Convert to upper-case character.
+ * @param c Character to convert.
+ * @return Conversion result.
+ */
+dkChar
+dk3str_toupper(dkChar c);
+
+/** Find start of string (first non-whitespace).
+ * @param str String to process.
+ * @param whsp Whitespaces set (use NULL for default whitespace set).
+ * @return Pointer to first non-whitespace on success, NULL on error.
+ */
+char *
+dk3str_c8_start(char const *str, char const *whsp);
+
+/** Find start of string (first non-whitespace).
+ * @param str String to process.
+ * @param whsp Whitespaces set (use NULL for default whitespace set).
+ * @return Pointer to first non-whitespace on success, NULL on error.
+ */
+dk3_c16_t *
+dk3str_c16_start(dk3_c16_t const *str, dk3_c16_t const *whsp);
+
+/** Find start of string (first non-whitespace).
+ * @param str String to process.
+ * @param whsp Whitespaces set (use NULL for default whitespace set).
+ * @return Pointer to first non-whitespace on success, NULL on error.
+ */
+dk3_c32_t *
+dk3str_c32_start(dk3_c32_t const *str, dk3_c32_t const *whsp);
+
+/** Find start of string (first non-whitespace).
+ * @param str String to process.
+ * @param whsp Whitespaces set (use NULL for default whitespace set).
+ * @return Pointer to first non-whitespace on success, NULL on error.
+ */
+dkChar *
+dk3str_start(dkChar const *str, dkChar const *whsp);
+
+/** Find start of second text
+ * @param str String to process.
+ * @param whsp Whitespaces set (use NULL for default whitespace set).
+ * @return Pointer to second non-whitespace sequence on success, or NULL.
+ */
+char *
+dk3str_c8_next(char *str, char const *whsp);
+
+/** Find start of second text
+ * @param str String to process.
+ * @param whsp Whitespaces set (use NULL for default whitespace set).
+ * @return Pointer to second non-whitespace sequence on success, or NULL.
+ */
+dk3_c16_t *
+dk3str_c16_next(dk3_c16_t *str, dk3_c16_t const *whsp);
+
+/** Find start of second text
+ * @param str String to process.
+ * @param whsp Whitespaces set (use NULL for default whitespace set).
+ * @return Pointer to second non-whitespace sequence on success, or NULL.
+ */
+dk3_c32_t *
+dk3str_c32_next(dk3_c32_t *str, dk3_c32_t const *whsp);
+
+/** Find start of second text
+ * @param str String to process.
+ * @param whsp Whitespaces set (use NULL for default whitespace set).
+ * @return Pointer to second non-whitespace sequence on success, or NULL.
+ */
+dkChar *
+dk3str_next(dkChar *str, dkChar const *whsp);
+
+/** Remove trailing whitespaces from string.
+ * @param str String to process.
+ * @param whsp Whitespaces set (use NULL for default whitespace set).
+ */
+void
+dk3str_c8_chomp(char *str, char const *whsp);
+
+/** Remove trailing whitespaces from string.
+ * @param str String to process.
+ * @param whsp Whitespaces set (use NULL for default whitespace set).
+ */
+void
+dk3str_c16_chomp(dk3_c16_t *str, dk3_c16_t const *whsp);
+
+/** Remove trailing whitespaces from string.
+ * @param str String to process.
+ * @param whsp Whitespaces set (use NULL for default whitespace set).
+ */
+void
+dk3str_c32_chomp(dk3_c32_t *str, dk3_c32_t const *whsp);
+
+/** Remove trailing whitespaces from string.
+ * @param str String to process.
+ * @param whsp Whitespaces set (use NULL for default whitespace set).
+ */
+void
+dk3str_chomp(dkChar *str, dkChar const *whsp);
+
+/** Remove trailing newline.
+ @param str String to modify.
+*/
+void
+dk3str_c8_delnl(char *str);
+
+/** Remove trailing newline.
+ @param str String to modify.
+*/
+void
+dk3str_c16_delnl(dk3_c16_t *str);
+
+/** Remove trailing newline.
+ @param str String to modify.
+*/
+void
+dk3str_c32_delnl(dk3_c32_t *str);
+
+/** Remove trailing newline.
+ @param str String to modify.
+*/
+void
+dk3str_delnl(dkChar *str);
+
+/** Find index of a string in an array of patterns.
+ * @param a Patterns array.
+ * @param s String to find.
+ * @param c Flag: Case-sensitive (1) or not (0).
+ * @return Index of \a s in \a a on success, -1 on error (not found).
+ */
+int
+dk3str_c8_array_index(char const * const *a, char const *s, int c);
+
+/** Find index of a string in an array of patterns.
+ * @param a Patterns array.
+ * @param s String to find.
+ * @param c Flag: Case-sensitive (1) or not (0).
+ * @return Index of \a s in \a a on success, -1 on error (not found).
+ */
+int
+dk3str_c16_array_index(dk3_c16_t const * const *a, dk3_c16_t const *s, int c);
+
+/** Find index of a string in an array of patterns.
+ * @param a Patterns array.
+ * @param s String to find.
+ * @param c Flag: Case-sensitive (1) or not (0).
+ * @return Index of \a s in \a a on success, -1 on error (not found).
+ */
+int
+dk3str_c32_array_index(dk3_c32_t const * const *a, dk3_c32_t const *s, int c);
+
+/** Find index of a string in an array of patterns.
+ * @param a Patterns array.
+ * @param s String to find.
+ * @param c Flag: Case-sensitive (1) or not (0).
+ * @return Index of \a s in \a a on success, -1 on error (not found).
+ */
+int
+dk3str_array_index(dkChar const * const *a, dkChar const *s, int c);
+
+/** Check whether a text matches a pattern, the text may be abbreviated.
+ * @param line Text to check.
+ * @param pattern Pattern for comparison.
+ * @param spec Special character marking the abbreviation in the
+ * pattern.
+ * @param cs Flag: Case sensitive (1) or not (0).
+ * @return 1 for a match, 0 otherwise.
+ */
+int
+dk3str_c8_is_abbr(char const *line,char const *pattern,char spec,int cs);
+
+/** Check whether a text matches a pattern, the text may be abbreviated.
+ * @param line Text to check.
+ * @param pattern Pattern for comparison.
+ * @param spec Special character marking the abbreviation in the
+ * pattern.
+ * @param cs Flag: Case sensitive (1) or not (0).
+ * @return 1 for a match, 0 otherwise.
+ */
+int
+dk3str_c16_is_abbr(
+ dk3_c16_t const *line, dk3_c16_t const *pattern, dk3_c16_t spec, int cs
+);
+
+/** Check whether a text matches a pattern, the text may be abbreviated.
+ * @param line Text to check.
+ * @param pattern Pattern for comparison.
+ * @param spec Special character marking the abbreviation in the
+ * pattern.
+ * @param cs Flag: Case sensitive (1) or not (0).
+ * @return 1 for a match, 0 otherwise.
+ */
+int
+dk3str_c32_is_abbr(
+ dk3_c32_t const *line, dk3_c32_t const *pattern, dk3_c32_t spec, int cs
+);
+
+/** Check whether a text matches a pattern, the text may be abbreviated.
+ * @param line Text to check.
+ * @param pattern Pattern for comparison.
+ * @param spec Special character marking the abbreviation in the
+ * pattern.
+ * @param cs Flag: Case sensitive (1) or not (0).
+ * @return 1 for a match, 0 otherwise.
+ */
+int
+dk3str_is_abbr(dkChar const *line, dkChar const *pattern, dkChar spec, int cs);
+
+/** Search for a string in an array of patterns with abbreviations allowed.
+ * @param ar Pattern array.
+ * @param str String to search for.
+ * @param sp Special character to mark abbreviation position.
+ * @param cs Flag: Case-sensitive (1) or not (0).
+ * @return Index of \a str in \a ar on success, -1 on error (not found).
+ */
+int
+dk3str_c8_array_abbr(char const * const *ar, char const *str, char sp, int cs);
+
+/** Search for a string in an array of patterns with abbreviations allowed.
+ * @param arr Pattern array.
+ * @param str String to search for.
+ * @param sp Special character to mark abbreviation position.
+ * @param cs Flag: Case-sensitive (1) or not (0).
+ * @return Index of \a str in \a ar on success, -1 on error (not found).
+ */
+int
+dk3str_c16_array_abbr(
+ dk3_c16_t const * const *arr, dk3_c16_t const *str, dk3_c16_t sp, int cs
+);
+
+/** Search for a string in an array of patterns with abbreviations allowed.
+ * @param arr Pattern array.
+ * @param str String to search for.
+ * @param sp Special character to mark abbreviation position.
+ * @param cs Flag: Case-sensitive (1) or not (0).
+ * @return Index of \a str in \a ar on success, -1 on error (not found).
+ */
+int
+dk3str_c32_array_abbr(
+ dk3_c32_t const * const *arr, dk3_c32_t const *str, dk3_c32_t sp, int cs
+);
+
+/** Search for a string in an array of patterns with abbreviations allowed.
+ * @param ar Pattern array.
+ * @param str String to search for.
+ * @param sp Special character to mark abbreviation position.
+ * @param cs Flag: Case-sensitive (1) or not (0).
+ * @return Index of \a str in \a ar on success, -1 on error (not found).
+ */
+int
+dk3str_array_abbr(dkChar const * const *ar,dkChar const *str,dkChar sp,int cs);
+
+/** Check whether the text represents a boolean value.
+ * @param str Text to process.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_c8_is_bool(char const *str);
+
+/** Check whether the text represents a boolean value.
+ * @param str Text to process.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_c16_is_bool(dk3_c16_t const *str);
+
+/** Check whether the text represents a boolean value.
+ * @param str Text to process.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_c32_is_bool(dk3_c32_t const *str);
+
+/** Check whether the text represents a boolean value.
+ * @param str Text to process.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_is_bool(dkChar const *str);
+
+/** Check whether the text represents the boolean value "true".
+ * @param str Text to process.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_c8_is_on(char const *str);
+
+/** Check whether the text represents the boolean value "true".
+ * @param str Text to process.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_c16_is_on(dk3_c16_t const *str);
+
+/** Check whether the text represents the boolean value "true".
+ * @param str Text to process.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_c32_is_on(dk3_c32_t const *str);
+
+/** Check whether the text represents the boolean value "true".
+ * @param str Text to process.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_is_on(dkChar const *str);
+
+/** Explode a string (split string into array of text words).
+ @param array Destination pointers array.
+ @param sz Size of \a array (number of elements).
+ @param str String to process.
+ @param whsp Whitespaces set (may be NULL).
+ @return Number of elements set in \a array, 0 on error.
+*/
+size_t
+dk3str_c8_explode(char **array, size_t sz, char *str, char const *whsp);
+
+/** Explode a string (split string into array of text words).
+ @param array Destination pointers array.
+ @param sz Size of \a array (number of elements).
+ @param str String to process.
+ @param whsp Whitespaces set (may be NULL).
+ @return Number of elements set in \a array, 0 on error.
+*/
+size_t
+dk3str_c16_explode(
+ dk3_c16_t **array, size_t sz, dk3_c16_t *str, dk3_c16_t const *whsp
+);
+
+/** Explode a string (split string into array of text words).
+ @param array Destination pointers array.
+ @param sz Size of \a array (number of elements).
+ @param str String to process.
+ @param whsp Whitespaces set (may be NULL).
+ @return Number of elements set in \a array, 0 on error.
+*/
+size_t
+dk3str_c32_explode(
+ dk3_c32_t **array, size_t sz, dk3_c32_t *str, dk3_c32_t const *whsp
+);
+
+/** Explode a string (split string into array of text words).
+ @param array Destination pointers array.
+ @param sz Size of \a array (number of elements).
+ @param str String to process.
+ @param whsp Whitespaces set (may be NULL).
+ @return Number of elements set in \a array, 0 on error.
+*/
+size_t
+dk3str_explode(dkChar **array, size_t sz, dkChar *str, dkChar const *whsp);
+
+/** Normalize text line.
+ @param l Text line to modify.
+ @param w Whitespaces set (may be NULL).
+ @param s Separator character.
+*/
+void
+dk3str_c8_normalize(char *l, char const *w, char s);
+
+/** Normalize text line.
+ @param l Text line to modify.
+ @param w Whitespaces set (may be NULL).
+ @param s Separator character.
+*/
+void
+dk3str_c16_normalize(dk3_c16_t *l, dk3_c16_t const *w, dk3_c16_t s);
+
+/** Normalize text line.
+ @param l Text line to modify.
+ @param w Whitespaces set (may be NULL).
+ @param s Separator character.
+*/
+void
+dk3str_c32_normalize(dk3_c32_t *l, dk3_c32_t const *w, dk3_c32_t s);
+
+/** Normalize text line.
+ @param l Text line to modify.
+ @param w Whitespaces set (may be NULL).
+ @param s Separator character.
+*/
+void
+dk3str_normalize(dkChar *l, dkChar const *w, dkChar s);
+
+/** Correct file name.
+ * @param n File name to correct.
+ */
+void
+dk3str_c8_correct_filename(char *n);
+
+/** Correct file name.
+ * @param n File name to correct.
+ */
+void
+dk3str_c16_correct_filename(dk3_c16_t *n);
+
+/** Correct file name.
+ * @param n File name to correct.
+ */
+void
+dk3str_c32_correct_filename(dk3_c32_t *n);
+
+/** Correct file name.
+ * @param n File name to correct.
+ */
+void
+dk3str_correct_filename(dkChar *n);
+
+/** Check whether a file/directory name is an absolute path.
+ * @param n Name to check.
+ * @return 1 for absolute path, 0 otherwise.
+ */
+int
+dk3str_c8_is_abs_path(char const *n);
+
+/** Check whether a file/directory name is an absolute path.
+ * @param n Name to check.
+ * @return 1 for absolute path, 0 otherwise.
+ */
+int
+dk3str_c16_is_abs_path(dk3_c16_t const *n);
+
+/** Check whether a file/directory name is an absolute path.
+ * @param n Name to check.
+ * @return 1 for absolute path, 0 otherwise.
+ */
+int
+dk3str_c32_is_abs_path(dk3_c32_t const *n);
+
+/** Check whether a file/directory name is an absolute path.
+ * @param n Name to check.
+ * @return 1 for absolute path, 0 otherwise.
+ */
+int
+dk3str_is_abs_path(dkChar const *n);
+
+/** Append path to a given directory.
+ * @param d In: directory, out: modified path.
+ * @param sz Destination buffer size (number of characters).
+ * @param n Path name to append.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on errors.
+ */
+int
+dk3str_c8_append_path_app(char *d, size_t sz, char const *n, dk3_app_t *app);
+
+/** Append path to a given directory.
+ * @param d In: directory, out: modified path.
+ * @param sz Destination buffer size (number of characters).
+ * @param n Path name to append.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on errors.
+ */
+int
+dk3str_c16_append_path_app(
+ dk3_c16_t *d, size_t sz, dk3_c16_t const *n, dk3_app_t *app
+);
+
+/** Append path to a given directory.
+ * @param d In: directory, out: modified path.
+ * @param sz Destination buffer size (number of characters).
+ * @param n Path name to append.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on errors.
+ */
+int
+dk3str_c32_append_path_app(
+ dk3_c32_t *d, size_t sz, dk3_c32_t const *n, dk3_app_t *app
+);
+
+/** Append path to a given directory.
+ * @param d In: directory, out: modified path.
+ * @param sz Destination buffer size (number of characters).
+ * @param n Path name to append.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on errors.
+ */
+int
+dk3str_append_path_app(dkChar *d, size_t sz, dkChar const *n, dk3_app_t *app);
+
+
+/** Get file name suffix.
+ @param s File name.
+ @return Pointer to suffix on success, NULL on error (no
+ suffix found).
+*/
+char *
+dk3str_c8_get_suffix(char const *s);
+
+/** Get file name suffix.
+ @param s File name.
+ @return Pointer to suffix on success, NULL on error (no
+ suffix found).
+*/
+dk3_c16_t *
+dk3str_c16_get_suffix(dk3_c16_t const *s);
+
+/** Get file name suffix.
+ @param s File name.
+ @return Pointer to suffix on success, NULL on error (no
+ suffix found).
+*/
+dk3_c32_t *
+dk3str_c32_get_suffix(dk3_c32_t const *s);
+
+/** Get file name suffix.
+ @param s File name.
+ @return Pointer to suffix on success, NULL on error (no
+ suffix found).
+*/
+dkChar *
+dk3str_get_suffix(dkChar const *s);
+
+/** Convert 16-bit string to 8-bit string (only ASCII characters).
+ * @param d Destination buffer.
+ * @param sz Size of \a d in bytes.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on error (illegal characters or buffer too
+ * short).
+ */
+int
+dk3str_c16_to_c8_simple_app(
+ char *d, size_t sz, dk3_c16_t const *s, dk3_app_t *app
+);
+
+/** Convert 32-bit string to 8-bit string (only ASCII characters).
+ * @param d Destination buffer.
+ * @param sz Size of \a d in bytes.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on error (illegal characters or buffer too
+ * short).
+ */
+int
+dk3str_c32_to_c8_simple_app(
+ char *d, size_t sz, dk3_c32_t const *s, dk3_app_t *app
+);
+
+/** Find buffer size needed to convert from 8-bit plain to 8-bit UTF-8.
+ * @param s Source string (ASCII/ISO-LATIN-1 encoded).
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Number of bytes needed for UTF-8 encoded string,
+ * the number includes the finalizing 0x00 byte.
+ */
+size_t
+dk3str_cnvsz_c8p_to_c8u_app(char const *s, dk3_app_t *app);
+
+/** Find buffer size needed to convert from UTF-8 to ISO-LATIN-1.
+ * @param s Source string (UTF-8 encoded).
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Number of bytes needed for ISO-LATIN-1 encoded string,
+ * the number includes the finalizing 0x00 byte.
+ */
+size_t
+dk3str_cnvsz_c8u_to_c8p_app(char const *s, dk3_app_t *app);
+
+/** Find buffer size needed to convert from ISO-LATIN-1 to UTF-16.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Number of 16-bit characters needed for result
+ * including the finalizer.
+ */
+size_t
+dk3str_cnvsz_c8p_to_c16_app(char const *s, dk3_app_t *app);
+
+/** Find buffer size needed to convert from UTF-8 to UTF-16.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Number of 16-bit characters needed for result
+ * including the finalizer.
+ */
+size_t
+dk3str_cnvsz_c8u_to_c16_app(char const *s, dk3_app_t *app);
+
+/** Find buffer size needed to convert from UTF-16 to ISO-LATIN-1.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Number of bytes needed for result, including finalizer.
+ */
+size_t
+dk3str_cnvsz_c16_to_c8p_app(dk3_c16_t const *s, dk3_app_t *app);
+
+/** Find buffer size needed to convert from UTF-16 to UTF-8.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Number of bytes needed for result, including finalizer.
+ */
+size_t
+dk3str_cnvsz_c16_to_c8u_app(dk3_c16_t const *s, dk3_app_t *app);
+
+/** Find buffer size needed to convert from ISO-LATIN-1 to 32-bit.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Number of 32-bit characters needed for result,
+ * including finalizer.
+ */
+size_t
+dk3str_cnvsz_c8p_to_c32_app(char const *s, dk3_app_t *app);
+
+/** Find buffer size needed to convert from UTF-8 to 32-bit.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Number of 32-bit characters needed for result,
+ * including finalizer.
+ */
+size_t
+dk3str_cnvsz_c8u_to_c32_app(char const *s, dk3_app_t *app);
+
+/** Find buffer size needed to convert from UTF-16 to 32-bit.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Number of 32-bit characters needed for result,
+ * including finalizer.
+ */
+size_t
+dk3str_cnvsz_c16_to_c32_app(dk3_c16_t const *s, dk3_app_t *app);
+
+/** Find buffer size needed to convert from 32-bit to ISO-LATIN-1.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Number of bytes needed for result, including finalizer.
+ */
+size_t
+dk3str_cnvsz_c32_to_c8p_app(dk3_c32_t const *s, dk3_app_t *app);
+
+/** Find buffer size needed to convert from 32-bit to UTF-8.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Number of bytes needed for result, including finalizer.
+ */
+size_t
+dk3str_cnvsz_c32_to_c8u_app(dk3_c32_t const *s, dk3_app_t *app);
+
+/** Find buffer size needed to convert from 32-bit to UTF-16.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Number of UTF-16 chars needed for result, including finalizer.
+ */
+size_t
+dk3str_cnvsz_c32_to_c16_app(dk3_c32_t const *s, dk3_app_t *app);
+
+/** Convert ISO-LATIN-1 string to UTF-8.
+ * @param d Destination buffer.
+ * @param ds Size of \a d (number of elements).
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_cnv_c8p_to_c8u_app(char *d, size_t ds, char const *s, dk3_app_t *app);
+
+/** Convert UTF-8 string to ISO-LATIN-1.
+ * @param d Destination buffer.
+ * @param ds Size of \a d (number of elements).
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_cnv_c8u_to_c8p_app(char *d, size_t ds, char const *s, dk3_app_t *app);
+
+/** Convert ISO-LATIN-1 string to UTF-16.
+ * @param d Destination buffer.
+ * @param ds Size of \a d (number of elements).
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_cnv_c8p_to_c16_app(
+ dk3_c16_t *d, size_t ds, char const *s, dk3_app_t *app
+);
+
+/** Convert UTF-8 string to UTF-16.
+ * @param d Destination buffer.
+ * @param ds Size of \a d (number of elements).
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_cnv_c8u_to_c16_app(
+ dk3_c16_t *d, size_t ds, char const *s, dk3_app_t *app
+);
+
+/** Convert UTF-16 string to ISO-LATIN-1.
+ * @param d Destination buffer.
+ * @param ds Size of \a d (number of elements).
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_cnv_c16_to_c8p_app(
+ char *d, size_t ds, dk3_c16_t const *s, dk3_app_t *app
+);
+
+/** Convert UTF-16 string to UTF-8.
+ * @param d Destination buffer.
+ * @param ds Size of \a d (number of elements).
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_cnv_c16_to_c8u_app(
+ char *d, size_t ds, dk3_c16_t const *s, dk3_app_t *app
+);
+
+/** Convert ISO-LATIN-1 string to 32-bit.
+ * @param d Destination buffer.
+ * @param ds Size of \a d (number of elements).
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_cnv_c8p_to_c32_app(
+ dk3_c32_t *d, size_t ds, char const *s, dk3_app_t *app
+);
+
+/** Convert UTF-8 string to 32-bit.
+ * @param d Destination buffer.
+ * @param ds Size of \a d (number of elements).
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_cnv_c8u_to_c32_app(
+ dk3_c32_t *d, size_t ds, char const *s, dk3_app_t *app
+);
+
+/** Convert UTF-16 string to 32-bit.
+ * @param d Destination buffer.
+ * @param ds Size of \a d (number of elements).
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_cnv_c16_to_c32_app(
+ dk3_c32_t *d, size_t ds, dk3_c16_t const *s, dk3_app_t *app
+);
+
+/** Convert 32-bit string to ISO-LATIN-1.
+ * @param d Destination buffer.
+ * @param ds Size of \a d (number of elements).
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_cnv_c32_to_c8p_app(
+ char *d, size_t ds, dk3_c32_t const *s, dk3_app_t *app
+);
+
+/** Convert 32-bit string to UTF-8.
+ * @param d Destination buffer.
+ * @param ds Size of \a d (number of elements).
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_cnv_c32_to_c8u_app(
+ char *d, size_t ds, dk3_c32_t const *s, dk3_app_t *app
+);
+
+/** Convert 32-bit string to UTF-16.
+ * @param d Destination buffer.
+ * @param ds Size of \a d (number of elements).
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_cnv_c32_to_c16_app(
+ dk3_c16_t *d, size_t ds, dk3_c32_t const *s, dk3_app_t *app
+);
+
+/** Convert ISO-LATIN-1 string to UTF-8, allocate new memory for result.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Pointer to new result string on success, NULL on error.
+ */
+char *
+dk3str_cnvnew_c8p_to_c8u_app(char const *s, dk3_app_t *app);
+
+/** Convert UTF-8 string to ISO-LATIN-1, allocate new memory for result.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Pointer to new result string on success, NULL on error.
+ */
+char *
+dk3str_cnvnew_c8u_to_c8p_app(char const *s, dk3_app_t *app);
+
+/** Convert ISO-LATIN-1 string to UTF-16, allocate new memory for result.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Pointer to new result string on success, NULL on error.
+ */
+dk3_c16_t *
+dk3str_cnvnew_c8p_to_c16_app(char const *s, dk3_app_t *app);
+
+/** Convert UTF-8 string to UTF-16, allocate new memory for result.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Pointer to new result string on success, NULL on error.
+ */
+dk3_c16_t *
+dk3str_cnvnew_c8u_to_c16_app(char const *s, dk3_app_t *app);
+
+/** Convert UTF-16 string to ISO-LATIN-1, allocate new memory for result.
+ * @param s Source string.
+ * @param app Application structure, used for diagnostics.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Pointer to new result string on success, NULL on error.
+ */
+char *
+dk3str_cnvnew_c16_to_c8p_app(dk3_c16_t const *s, dk3_app_t *app);
+
+/** Convert UTF-16 string to UTF-8, allocate new memory for result.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Pointer to new result string on success, NULL on error.
+ */
+char *
+dk3str_cnvnew_c16_to_c8u_app(dk3_c16_t const *s, dk3_app_t *app);
+
+/** Convert ISO-LATIN-1 string to 32-bit, allocate new memory for result.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Pointer to new result string on success, NULL on error.
+ */
+dk3_c32_t *
+dk3str_cnvnew_c8p_to_c32_app(char const *s, dk3_app_t *app);
+
+/** Convert UTF-8 string to 32-bit, allocate new memory for result.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Pointer to new result string on success, NULL on error.
+ */
+dk3_c32_t *
+dk3str_cnvnew_c8u_to_c32_app(char const *s, dk3_app_t *app);
+
+/** Convert UTF-16 string to 32-bit, allocate new memory for result.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Pointer to new result string on success, NULL on error.
+ */
+dk3_c32_t *
+dk3str_cnvnew_c16_to_c32_app(dk3_c16_t const *s, dk3_app_t *app);
+
+/** Convert 32-bit string to ISO_LATIN-1, allocate new memory for result.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Pointer to new result string on success, NULL on error.
+ */
+char *
+dk3str_cnvnew_c32_to_c8p_app(dk3_c32_t const *s, dk3_app_t *app);
+
+/** Convert 32-bit string to UTF-8, allocate new memory for result.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Pointer to new result string on success, NULL on error.
+ */
+char *
+dk3str_cnvnew_c32_to_c8u_app(dk3_c32_t const *s, dk3_app_t *app);
+
+/** Convert 32-bit to UTF_16, allocate new memory for result.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Pointer to new result string on success, NULL on error.
+ */
+dk3_c16_t *
+dk3str_cnvnew_c32_to_c16_app(dk3_c32_t const *s, dk3_app_t *app);
+
+/** Convert 8-bit character to 8/16-bit character
+ without re-encoding. This function is mainly intended to convert
+ pure ASCII characters like numeric values.
+ @param d Destination buffer.
+ @param sz Size of \a d in characters.
+ @param s Source string.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3str_cnv_c8_to_str_app(dkChar *d, size_t sz, char const *s, dk3_app_t *app);
+
+/** Convert dkChar string to 8-bit (simple version,
+ used to read numeric values).
+ @param db Destination buffer.
+ @param sz Size of \a db.
+ @param s Source string.
+ @param ap Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error
+ (buffer too short or character out of range).
+*/
+int
+dk3str_string_to_c8_simple_app(
+ char *db,size_t sz,dkChar const *s,dk3_app_t *ap
+);
+
+/** Convert string to all lower-case characters.
+ @param s String to modify.
+*/
+void
+dk3str_string_tolower(dkChar *s);
+
+/** Convert 8-bit text to dkChar string.
+ @param dp Destination pointer.
+ @param ds Size of \a dp (number of characters).
+ @param sp Source pointer.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error (output buffer too small).
+*/
+int
+dk3str_c8_to_str_simple_app(
+ dkChar *dp, size_t ds, char const *sp, dk3_app_t *app
+);
+
+/** Convert dkChar string to plain 8-bit text.
+ @param dp Destination buffer pointer.
+ @param sz Size of \a dp (number of bytes).
+ @param src Source text.
+ @param ie Input encoding (used only for 8-bit characters).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3str_to_c8p_app(
+ char *dp, size_t sz, dkChar const *src, int ie, dk3_app_t *app
+);
+
+/** Convert dkChar string to UTF-8 text.
+ @param dp Destination buffer pointer.
+ @param sz Size of \a dp (number of bytes).
+ @param src Source text.
+ @param ie Input encoding (used only for 8-bit characters).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3str_to_c8u_app(
+ char *dp, size_t sz, dkChar const *src, int ie, dk3_app_t *app
+);
+
+/** Convert UTF-8 encoded string to dkChar string.
+ @param d Destination buffer.
+ @param dsz Size of @a d (number of elements).
+ @param de Destination buffer encoding.
+ @param s Source string.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3str_c8u_to_str_app(
+ dkChar *d,
+ size_t dsz,
+ int de,
+ char const *s,
+ dk3_app_t *app
+);
+
+/** Convert dkChar string to UTF-8 encoded string.
+ @param d Destination buffer.
+ @param dsz Size of @a d (number of bytes).
+ @param s Source string.
+ @param se Source encoding (used for 8-bit characters only).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3str_str_to_c8u_app(
+ char *d,
+ size_t dsz,
+ dkChar const *s,
+ int se,
+ dk3_app_t *app
+);
+
+/** Convert dkChar string to 8-bit character string.
+ @param dp Destination buffer pointer.
+ @param szdp Size of dp.
+ @param src Source string.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3str_to_c8_app(char *dp, size_t szdp, dkChar const *src, dk3_app_t *app);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk3all.h"
+
+
+$!trace-include
+
+
+$*
+ Static data
+$*
+
+
+/** The set of whitespace characters.
+*/
+static char const dk3str_c8_def_whsp[] = { " \t\r\n" };
+
+/** The current directory.
+*/
+static char const dk3str_c8_dot[] = { "." };
+
+/** The parent directory.
+*/
+static char const dk3str_c8_dot_dot[] = { ".." };
+
+/** File name separator.
+*/
+static char const dk3str_c8_fnsep[] = {
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+"\\"
+#else
+"/"
+#endif
+};
+
+
+/** Keywords to set boolean values.
+*/
+static char const * const dk3str_c8_bool_kw[] = {
+ "0",
+ "n$o",
+ "of$f",
+ "f$alse",
+ "-",
+ "+",
+ "1",
+ "y$es",
+ "on",
+ "ok",
+ "t$rue",
+ NULL
+};
+
+/** Index of first "true" entry in \a dk3str_c8_bool_kw.
+*/
+#define INDEX_OF_FIRST_BOOLEAN_TRUE 5
+
+
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+/** File name separator character.
+*/
+#define FNS_C8 '\\'
+/** Not the file name separator character.
+*/
+#define NO_FNS_C8 '/'
+#else
+/** File name separator character.
+*/
+#define FNS_C8 '/'
+/** Not the file name separator character.
+*/
+#define NO_FNS_C8 '\\'
+#endif
+
+
+
+/** Default white spaces set.
+*/
+static dk3_c16_t const c16_def_whsp[] = {
+ 0x0020U, 0x0009U, 0x000AU, 0x000DU, 0U
+};
+
+/** The dot for the current directory.
+*/
+static dk3_c16_t const c16_dot[] = {
+ 0x002EU, 0U
+};
+
+/** The dot dot for the parent directory.
+*/
+static dk3_c16_t const c16_dot_dot[] = {
+ 0x002EU, 0x002EU, 0U
+};
+
+/** File name separator (slash or backslash).
+*/
+static dk3_c16_t const c16_fnsep[] = {
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+0x005CU,
+#else
+0x002FU,
+#endif
+0U
+};
+
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+/** File name separator for 16-bit character strings.
+*/
+#define FNS_C16 0x005CU
+/** Not the file name separator for 16-bit character strings.
+*/
+#define NO_FNS_C16 0x002FU
+#else
+/** File name separator for 16-bit character strings.
+*/
+#define FNS_C16 0x002FU
+/** Not the file name separator for 16-bit character strings.
+*/
+#define NO_FNS_C16 0x005CU
+#endif
+
+
+
+/** Default whitespaces set.
+*/
+static dk3_c32_t const c32_def_whsp[] = {
+ 0x00000020UL, 0x00000009UL, 0x0000000AUL, 0x0000000DUL, 0UL
+};
+
+/** The dot is the current directory.
+*/
+static dk3_c32_t const c32_dot[] = {
+ 0x0000002EUL, 0UL
+};
+
+/** The dot dot is the parent directory.
+*/
+static dk3_c32_t const c32_dot_dot[] = {
+ 0x0000002EUL, 0x0000002EUL, 0UL
+};
+
+/** File name separator (slash or backslash).
+*/
+static dk3_c32_t const c32_fnsep[] = {
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+0x0000005CUL,
+#else
+0x0000002FUL,
+#endif
+0U
+};
+
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+/** File name separator for 32-bit character strings.
+*/
+#define FNS_C32 0x0000005CUL
+/** Not a file name separator for 32-bit character strings.
+*/
+#define NO_FNS_C32 0x0000002FUL
+#else
+/** File name separator for 32-bit character strings.
+*/
+#define FNS_C32 0x0000002FUL
+/** Not a file name separator for 32-bit character strings.
+*/
+#define NO_FNS_C32 0x0000005CUL
+#endif
+
+
+
+size_t
+dk3str_c8_len(char const *s)
+{
+ register size_t back; /* Function result. */
+#if DK3_HAVE_STRLEN
+ back = strlen(s);
+#else
+ register char const *ptr; /* Pointer to traverse s. */
+ back = 0; ptr = s;
+ while(*(ptr++)) back++;
+#endif
+ return back;
+}
+
+
+
+size_t
+dk3str_c16_len(dk3_c16_t const *s)
+{
+ register size_t back;
+#if (DK3_HAVE_WCSLEN) && (DK3_SIZEOF_WCHAR_T == 2)
+ back = wcslen(s);
+#else
+#if (DK3_HAVE__WCSLEN) && (DK3_SIZEOF_WCHAR_T == 2)
+ back = _wcslen(s);
+#else
+ register dk3_c16_t const *ptr; /* Traverse string. */
+ back = 0; ptr = s;
+ while(*(ptr++)) back++;
+#endif
+#endif
+ return back;
+}
+
+
+
+size_t
+dk3str_c32_len(dk3_c32_t const *s)
+{
+ register size_t back;
+#if (DK3_HAVE_WCSLEN) && (DK3_SIZEOF_WCHAR_T == 4)
+ back = wcslen(s);
+#else
+#if (DK3_HAVE__WCSLEN) && (DK3_SIZEOF_WCHAR_T == 4)
+ back = _wcslen(s);
+#else
+ register dk3_c32_t const *ptr; /* Traverse source string. */
+ back = 0; ptr = s;
+ while(*(ptr++)) back++;
+#endif
+#endif
+ return back;
+}
+
+
+
+size_t
+dk3str_len(dkChar const *s)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_len(s));
+#else
+ return(dk3str_c16_len(s));
+#endif
+#else
+ return(dk3str_c8_len(s));
+#endif
+}
+
+
+
+int
+dk3str_c8_cmp(char const *s1, char const *s2)
+{
+ register int back; /* Function result. */
+#if DK3_HAVE_STRCMP
+ back = strcmp(s1, s2);
+#else
+ register char const *p1; /* Pointer to traverse s1. */
+ register char const *p2; /* Pointer to traverse s2. */
+ register int cc; /* Flag: Can continue. */
+ back = 0; p1 = s1; p2 = s2; cc = 1;
+ while((cc) && (back == 0)) {
+ if(*p1 > *p2) {
+ back = 1;
+ } else {
+ if(*p1 < *p2) {
+ back = -1;
+ } else {
+ if((*p1) && (*p2)) {
+ p1++; p2++;
+ } else {
+ cc = 0;
+ }
+ }
+ }
+ }
+#endif
+ return back;
+}
+
+
+
+int
+dk3str_c16_cmp(dk3_c16_t const *s1, dk3_c16_t const *s2)
+{
+ register int back;
+#if (DK3_HAVE_WCSCPY) && (DK3_SIZEOF_WCHAR_T == 2)
+ back = wcscmp(s1, s2);
+#else
+#if (DK3_HAVE__WCSCPY) && (DK3_SIZEOF_WCHAR_T == 2)
+ back = _wcscmp(s1, s2);
+#else
+ register dk3_c16_t const *p1; /* Traverse left string. */
+ register dk3_c16_t const *p2; /* Traverse right string. */
+ register int cc; /* Flag: Can continue. */
+
+ back = 0; p1 = s1; p2 = s2; cc = 1;
+ while((cc) && (back == 0)) {
+ if(*p1 > *p2) {
+ back = 1;
+ } else {
+ if(*p1 < *p2) {
+ back = -1;
+ } else {
+ if((*p1) && (*p2)) {
+ p1++; p2++;
+ } else {
+ cc = 0;
+ }
+ }
+ }
+ }
+#endif
+#endif
+ return back;
+}
+
+
+
+int
+dk3str_c32_cmp(dk3_c32_t const *s1, dk3_c32_t const *s2)
+{
+ register int back;
+#if (DK3_HAVE_WCSCMP) && (DK3_SIZEOF_WCHAR_T == 4)
+ back = wcscmp(s1, s2);
+#else
+#if (DK3_HAVE__WCSCMP) && (DK3_SIZEOF_WCHAR_T == 4)
+ back = _wcscmp(s1, s2);
+#else
+ register dk3_c32_t const *p1; /* Traverse left string. */
+ register dk3_c32_t const *p2; /* Traverse right string. */
+ register int cc; /* Flag: Can continue. */
+
+ back = 0; p1 = s1; p2 = s2; cc = 1;
+ while((cc) && (back == 0)) {
+ if(*p1 > *p2) {
+ back = 1;
+ } else {
+ if(*p1 < *p2) {
+ back = -1;
+ } else {
+ if((*p1) && (*p2)) {
+ p1++; p2++;
+ } else {
+ cc = 0;
+ }
+ }
+ }
+ }
+#endif
+#endif
+ return back;
+}
+
+
+
+int
+dk3str_cmp(dkChar const *s1, dkChar const *s2)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_cmp(s1, s2));
+#else
+ return(dk3str_c16_cmp(s1, s2));
+#endif
+#else
+ return(dk3str_c8_cmp(s1, s2));
+#endif
+}
+
+
+
+int
+dk3str_c8_casecmp(char const *s1, char const *s2)
+{
+ register int back; /* Function result. */
+#if DK3_HAVE_STRCASECMP
+ back = strcasecmp(s1, s2);
+#else
+#if DK3_HAVE_STRICMP && (!DK3_ON_WINDOWS)
+ back = stricmp(s1, s2);
+#else
+#if DK3_HAVE__STRICMP || DK3_ON_WINDOWS
+ back = _stricmp(s1, s2);
+#else
+ register char const *p1; /* Pointer to traverse s1. */
+ register char const *p2; /* Pointer to traverse s2. */
+ register char c1; /* Current character from s1. */
+ register char c2; /* Current character from s2. */
+ register int cc; /* Flag: Can continue. */
+ back = 0; p1 = s1; p2 = s2; cc = 1;
+ while((cc) && (back == 0)) {
+ c1 = *p1; c2 = *p2;
+ if((c1 >= 'A') && (c1 <= 'Z')) { c1 = 'a' + (c1 - 'A'); }
+ if((c2 >= 'A') && (c2 <= 'Z')) { c2 = 'a' + (c2 - 'A'); }
+ if(c1 > c2) {
+ back = 1;
+ } else {
+ if(c1 < c2) {
+ back = -1;
+ } else {
+ if((c1) && (c2)) {
+ p1++; p2++;
+ } else {
+ cc = 0;
+ }
+ }
+ }
+ }
+#endif
+#endif
+#endif
+ return back;
+}
+
+
+
+int
+dk3str_c16_casecmp(dk3_c16_t const *s1, dk3_c16_t const *s2)
+{
+ register int back;
+#if (DK3_HAVE_WCSICMP) && (DK3_SIZEOF_WCHAR_T == 2)
+ back = wcsicmp(s1, s2);
+#else
+#if (DK3_HAVE__WCSICMP) && (DK3_SIZEOF_WCHAR_T == 2)
+ back = _wcsicmp(s1, s2);
+#else
+ register dk3_c16_t const *p1; /* Traverse left string. */
+ register dk3_c16_t const *p2; /* Traverse right string. */
+ register dk3_c16_t c1; /* Left character. */
+ register dk3_c16_t c2; /* Right character. */
+ register int cc; /* Flag: Can continue. */
+ $? "+ dk3str_c16_casecmp_fb"
+ back = 0; p1 = s1; p2 = s2; cc = 1;
+ while((cc) && (back == 0)) {
+ c1 = *p1; c2 = *p2;
+ if((c1 >= 0x0041U) && (c1 <= 0x005AU)) { c1 = 0x0061U + (c1 - 0x0041U); }
+ if((c2 >= 0x0041U) && (c2 <= 0x005AU)) { c2 = 0x0061U + (c2 - 0x0041U); }
+ if(c1 > c2) {
+ back = 1;
+ } else {
+ if(c1 < c2) {
+ back = -1;
+ } else {
+ if((c1) && (c2)) {
+ p1++; p2++;
+ } else {
+ cc = 0;
+ }
+ }
+ }
+ } $? "- dk3str_c16_casecmp_fb %d", back
+#endif
+#endif
+ return back;
+}
+
+
+
+int
+dk3str_c32_casecmp(dk3_c32_t const *s1, dk3_c32_t const *s2)
+{
+ register int back;
+#if (DK3_HAVE_WCSICMP) && (DK3_SIZEOF_WCHAR_T == 4)
+ back = wcsicmp(s1, s2);
+#else
+#if (DK3_HAVE__WCSICMP) && (DK3_SIZEOF_WCHAR_T == 4)
+ back = _wcsicmp(s1, s2);
+#else
+ register dk3_c32_t const *p1; /* Traverse left string. */
+ register dk3_c32_t const *p2; /* Traverse right string. */
+ register dk3_c32_t c1; /* Left character. */
+ register dk3_c32_t c2; /* Right character. */
+ register int cc; /* Flag: Can continue. */
+
+ back = 0; p1 = s1; p2 = s2; cc = 1;
+ while((cc) && (back == 0)) {
+ c1 = *p1; c2 = *p2;
+ if((c1 >= (dk3_c32_t)0x00000041UL) && (c1 <= (dk3_c32_t)0x0000005AUL)) {
+ c1 = 0x00000061UL + (c1 - 0x00000041UL);
+ }
+ if((c2 >= (dk3_c32_t)0x00000041UL) && (c2 <= (dk3_c32_t)0x0000005AUL)) {
+ c2 = 0x00000061UL + (c2 - 0x00000041UL);
+ }
+ if(c1 > c2) {
+ back = 1;
+ } else {
+ if(c1 < c2) {
+ back = -1;
+ } else {
+ if((c1) && (c2)) {
+ p1++; p2++;
+ } else {
+ cc = 0;
+ }
+ }
+ }
+ }
+#endif
+#endif
+ return back;
+}
+
+
+
+int
+dk3str_casecmp(dkChar const *s1, dkChar const *s2)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_casecmp(s1, s2));
+#else
+ return(dk3str_c16_casecmp(s1, s2));
+#endif
+#else
+ return(dk3str_c8_casecmp(s1, s2));
+#endif
+}
+
+
+
+int
+dk3str_fncmp(dkChar const *s1, dkChar const *s2)
+{
+#if DK3_ON_WINDOWS || DK3_HAVE_FNCASEINS
+ return(dk3str_casecmp(s1, s2));
+#else
+ return(dk3str_cmp(s1, s2));
+#endif
+}
+
+
+int
+dk3str_c8_ncmp(char const *s1, char const *s2, size_t n)
+{
+ register int back; /* Function result. */
+#if DK3_HAVE_STRNCMP
+ back = strncmp(s1, s2, n);
+#else
+ register char const *p1; /* Pointer to traverse s1. */
+ register char const *p2; /* Pointer to traverse s2. */
+ register size_t max; /* Register copy of n. */
+ register size_t used; /* Number of chars already used. */
+ back = 0; p1 = s1; p2 = s2; max = n; used = 0;
+ while((used < max) && (back == 0)) {
+ if(*p1 > *p2) {
+ back = 1;
+ } else {
+ if(*p1 < *p2) {
+ back = -1;
+ } else {
+ if((*p1) && (*p2)) {
+ p1++; p2++; used++;
+ } else {
+ used = max;
+ }
+ }
+ }
+ }
+#endif
+ return back;
+}
+
+
+
+int
+dk3str_c16_ncmp(dk3_c16_t const *s1, dk3_c16_t const *s2, size_t n)
+{
+ register int back;
+#if (DK3_HAVE_WCSNCMP) && (DK3_SIZEOF_WCHAR_T == 2)
+ back = wcsncmp(s1, s2, n);
+#else
+#if (DK3_HAVE__WCSNCMP) && (DK3_SIZEOF_WCHAR_T == 2)
+ back = _wcsncmp(s1, s2, n);
+#else
+ register dk3_c16_t const *p1; /* Traverse left string. */
+ register dk3_c16_t const *p2; /* Traverse right string. */
+ register size_t max; /* Maximum number of characters to compare. */
+ register size_t used; /* Number of characters already compared. */
+
+ back = 0; p1 = s1; p2 = s2; max = n; used = 0;
+ while((used < max) && (back == 0)) {
+ if(*p1 > *p2) {
+ back = 1;
+ } else {
+ if(*p1 < *p2) {
+ back = -1;
+ } else {
+ if((*p1) && (*p2)) {
+ p1++; p2++; used++;
+ } else {
+ used = max;
+ }
+ }
+ }
+ }
+#endif
+#endif
+ return back;
+}
+
+
+
+int
+dk3str_c32_ncmp(dk3_c32_t const *s1, dk3_c32_t const *s2, size_t n)
+{
+ register int back;
+#if (DK3_HAVE_WCSNCMP) && (DK3_SIZEOF_WCHAR_T == 4)
+ back = wcsncmp(s1, s2, n);
+#else
+#if (DK3_HAVE__WCSNCMP) && (DK3_SIZEOF_WCHAR_T == 4)
+ back = _wcsncmp(s1, s2, n);
+#else
+ register dk3_c32_t const *p1; /* Traverse left string. */
+ register dk3_c32_t const *p2; /* Traverse right string. */
+ register size_t max; /* Maximum number of characters to compare. */
+ register size_t used; /* Number of characters used. */
+
+ back = 0; p1 = s1; p2 = s2; max = n; used = 0;
+ while((used < max) && (back == 0)) {
+ if(*p1 > *p2) {
+ back = 1;
+ } else {
+ if(*p1 < *p2) {
+ back = -1;
+ } else {
+ if((*p1) && (*p2)) {
+ p1++; p2++; used++;
+ } else {
+ used = max;
+ }
+ }
+ }
+ }
+#endif
+#endif
+ return back;
+}
+
+
+
+int
+dk3str_ncmp(dkChar const *s1, dkChar const *s2, size_t n)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_ncmp(s1, s2, n));
+#else
+ return(dk3str_c16_ncmp(s1, s2, n));
+#endif
+#else
+ return(dk3str_c8_ncmp(s1, s2, n));
+#endif
+}
+
+
+
+char *
+dk3str_c8_chr(char const *s, char c)
+{
+ register char *back; /* Function result. */
+#if DK3_HAVE_STRCHR
+ back = strchr(s, c);
+#else
+ register char const *ptr; /* Pointer to traverse s. */
+ register char chr; /* Register copy of c. */
+ back = NULL; ptr = s; chr = c;
+ while((*ptr) && (back == NULL)) {
+ if(*ptr == chr) { back = (char *)ptr; } else { ptr++; }
+ }
+#endif
+ return back;
+}
+
+
+
+dk3_c16_t *
+dk3str_c16_chr(dk3_c16_t const *s, dk3_c16_t c)
+{
+ register dk3_c16_t *back;
+#if (DK3_HAVE_WCSCHR) && (DK3_SIZEOF_WCHAR_T == 2)
+ back = wcschr(s, c);
+#else
+#if (DK3_HAVE__WCSCHR) && (DK3_SIZEOF_WCHAR_T == 2)
+ back = _wcschr(s, c);
+#else
+ register dk3_c16_t const *ptr; /* Traverse source string. */
+ register dk3_c16_t chr; /* Character to search for. */
+ back = NULL; ptr = s; chr = c;
+ while((*ptr) && (back == NULL)) {
+ if(*ptr == chr) { back = (dk3_c16_t *)ptr; } else { ptr++; }
+ }
+#endif
+#endif
+ return back;
+}
+
+
+
+dk3_c32_t *
+dk3str_c32_chr(dk3_c32_t const *s, dk3_c32_t c)
+{
+ register dk3_c32_t *back;
+#if (DK3_HAVE_WCSCHR) && (DK3_SIZEOF_WCHAR_T == 4)
+ back = wcschr(s, c);
+#else
+#if (DK3_HAVE__WCSCHR) && (DK3_SIZEOF_WCHAR_T == 4)
+ back = _wcschr(s, c);
+#else
+ register dk3_c32_t const *ptr; /* Traverse source string. */
+ register dk3_c32_t chr; /* Character to find. */
+
+ back = NULL; ptr = s; chr = c;
+ while((*ptr) && (back == NULL)) {
+ if(*ptr == chr) { back = (dk3_c32_t *)ptr; } else { ptr++; }
+ }
+#endif
+#endif
+ return back;
+}
+
+
+
+dkChar *
+dk3str_chr(dkChar const *s, dkChar c)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_chr(s, c));
+#else
+ return(dk3str_c16_chr(s, c));
+#endif
+#else
+ return(dk3str_c8_chr(s, c));
+#endif
+}
+
+
+char *
+dk3str_c8_rchr(char const *s, char c)
+{
+ register char *back; /* Function result. */
+#if DK3_HAVE_STRRCHR
+ back = strrchr(s, c);
+#else
+ register char const *ptr; /* Pointer to traverse s. */
+ register char chr; /* Register copy of c. */
+ back = NULL; ptr = s; chr = c;
+ while(*ptr) {
+ if(*ptr == chr) { back = (char *)ptr; }
+ ptr++;
+ }
+#endif
+ return back;
+}
+
+
+
+
+dk3_c16_t *
+dk3str_c16_rchr(dk3_c16_t const *s, dk3_c16_t c)
+{
+ register dk3_c16_t *back;
+#if (DK3_HAVE_WCSRCHR) && (DK3_SIZEOF_WCHAR_T == 2)
+ back = wcsrchr(s, c);
+#else
+#if (DK3_HAVE__WCSRCHR) && (DK3_SIZEOF_WCHAR_T == 2)
+ back = _wcsrchr(s, c);
+#else
+ register dk3_c16_t const *ptr; /* Traverse the string. */
+ register dk3_c16_t chr; /* Character to search for. */
+ back = NULL; ptr = s; chr = c;
+ while(*ptr) {
+ if(*ptr == chr) { back = (dk3_c16_t *)ptr; }
+ ptr++;
+ }
+#endif
+#endif
+ return back;
+}
+
+
+
+dk3_c32_t *
+dk3str_c32_rchr(dk3_c32_t const *s, dk3_c32_t c)
+{
+ register dk3_c32_t *back;
+#if (DK3_HAVE_WCSRCHR) && (DK3_SIZEOF_WCHAR_T == 4)
+ back = wcsrchr(s, c);
+#else
+#if (DK3_HAVE__WCSRCHR) && (DK3_SIZEOF_WCHAR_T == 4)
+ back = _wcsrchr(s, c);
+#else
+ register dk3_c32_t const *ptr; /* Traverse source string. */
+ register dk3_c32_t chr; /* Character to search for. */
+
+ back = NULL; ptr = s; chr = c;
+ while(*ptr) {
+ if(*ptr == chr) { back = (dk3_c32_t *)ptr; }
+ ptr++;
+ }
+#endif
+#endif
+ return back;
+}
+
+
+
+dkChar *
+dk3str_rchr(dkChar const *s, dkChar c)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_rchr(s, c));
+#else
+ return(dk3str_c16_rchr(s, c));
+#endif
+#else
+ return(dk3str_c8_rchr(s, c));
+#endif
+}
+
+
+void
+dk3str_c8_cpy(char *d, char const *s)
+{
+ register char *dp; /* Destination buffer pointer. */
+ register char const *sp; /* Source buffer pointer. */
+ register char x;
+ dp = d; sp = s;
+ while(*sp) { x = *(sp++); *(dp++) = x; }
+ *dp = '\0';
+}
+
+
+
+void
+dk3str_c16_cpy(dk3_c16_t *d, dk3_c16_t const *s)
+{
+ register dk3_c16_t *dp; /* Destination pointer. */
+ register dk3_c16_t const *sp; /* Source pointer. */
+ register dk3_c16_t x; /* Current character. */
+
+ dp = d; sp = s;
+ while(*sp) { x = *(sp++); *(dp++) = x; }
+ *dp = 0U;
+}
+
+
+
+void
+dk3str_c32_cpy(dk3_c32_t *d, dk3_c32_t const *s)
+{
+ register dk3_c32_t *dp; /* Destination pointer. */
+ register dk3_c32_t const *sp; /* Source pointer. */
+ register dk3_c32_t x; /* Current character. */
+ dp = d; sp = s;
+ while(*sp) { x = *(sp++); *(dp++) = x; }
+ *dp = 0UL;
+}
+
+
+
+void
+dk3str_cpy(dkChar *d, dkChar const *s)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ dk3str_c32_cpy(d, s);
+#else
+ dk3str_c16_cpy(d, s);
+#endif
+#else
+ dk3str_c8_cpy(d, s);
+#endif
+}
+
+
+void
+dk3str_c8_cpy_not_overlapped(char *d, char const *s)
+{
+#if DK3_HAVE_STRCPY
+ strcpy(d, s);
+#else
+#if DK3_HAVE_STRLEN
+ size_t sz;
+ int ec = 0;
+ sz = dk3mem_add_size_t(1, strlen(s), &ec);
+ if((0 != sz) && (0 == ec)) {
+ dk3mem_cpy(d,s,sz);
+ } else {
+ dk3str_c8_cpy(d, s);
+ }
+#else
+ dk3str_c8_cpy(d, s);
+#endif
+#endif
+}
+
+
+
+void
+dk3str_c16_cpy_not_overlapped(dk3_c16_t *d, dk3_c16_t const *s)
+{
+#if (DK3_HAVE_WCSCPY) && (DK3_SIZEOF_WCHAR_T == 2)
+ wcscpy(d, s);
+#else
+#if (DK3_HAVE__WCSCPY) && (DK3_SIZEOF_WCHAR_T == 2)
+ _wcscpy(d, s);
+#else
+#if (DK3_HAVE_WCSLEN) && (DK3_SIZEOF_WCHAR_T == 2)
+ size_t sz;
+ int ec = 0;
+ sz = dk3mem_mul_size_t(2, dk3mem_add_size_t(1, wcslen(s), &ec), &ec);
+ if((0 != sz) && (0 == ec)) {
+ dk3mem_cpy(d, s, sz);
+ } else {
+ dk3str_c16_cpy(d,s);
+ }
+#else
+#if (DK3_HAVE__WCSLEN) && (DK3_SIZEOF_WCHAR_T == 2)
+ size_t sz;
+ int ec = 0;
+ sz = dk3mem_mul_size_t(2, dk3mem_add_size_t(1, _wcslen(s), &ec), &ec);
+ if((0 != sz) && (0 == ec)) {
+ dk3mem_cpy(d, s, sz);
+ } else {
+ dk3str_c16_cpy(d,s);
+ }
+#else
+ dk3str_c16_cpy(d,s);
+#endif
+#endif
+#endif
+#endif
+}
+
+
+
+void
+dk3str_c32_cpy_not_overlapped(dk3_c32_t *d, dk3_c32_t const *s)
+{
+#if (DK3_HAVE_WCSCPY) && (DK3_SIZEOF_WCHAR_T == 4)
+ wcscpy(d, s);
+#else
+#if (DK3_HAVE__WCSCPY) && (DK3_SIZEOF_WCHAR_T == 4)
+ _wcscpy(d, s);
+#else
+#if (DK3_HAVE_WCSLEN) && (DK3_SIZEOF_WCHAR_T == 4)
+ size_t sz;
+ int ec = 0;
+ sz = dk3mem_mul_size_t(4, dk3mem_add_size_t(1, wcslen(s), &ec), &ec);
+ if((0 != sz) && (0 == ec)) {
+ dk3mem_cpy(d, s, sz);
+ } else {
+ dk3str_c32_cpy(d,s);
+ }
+#else
+#if (DK3_HAVE__WCSLEN) && (DK3_SIZEOF_WCHAR_T == 4)
+ size_t sz;
+ int ec = 0;
+ sz = dk3mem_mul_size_t(4, dk3mem_add_size_t(1, _wcslen(s), &ec), &ec);
+ if((0 != sz) && (0 == ec)) {
+ dk3mem_cpy(d, s, sz);
+ } else {
+ dk3str_c32_cpy(d,s);
+ }
+#else
+ dk3str_c32_cpy(d,s);
+#endif
+#endif
+#endif
+#endif
+}
+
+
+
+void
+dk3str_cpy_not_overlapped(dkChar *d, dkChar const *s)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ dk3str_c32_cpy_not_overlapped(d, s);
+#else
+ dk3str_c16_cpy_not_overlapped(d, s);
+#endif
+#else
+ dk3str_c8_cpy_not_overlapped(d, s);
+#endif
+}
+
+
+void
+dk3str_c8_ncpy(char *d, char const *s, size_t n)
+{
+#if DK3_HAVE_STRNCPY
+ strncpy(d,s,n);
+ d[n-1] = '\0';
+#else
+ register char *dp; /* Destination buffer pointer. */
+ register char const *sp; /* Source buffer pointer. */
+ register size_t max; /* Register copy of n. */
+ register size_t used; /* Number of characters already copied. */
+ register char x;
+ dp = d; sp = s; max = n; used = 0;
+ while((*sp) && (used < max)) { x = *(sp++); *(dp++) = x; used++; }
+ if(used < max) { *dp = '\0'; }
+ else { d[max - 1] = '\0'; }
+#endif
+}
+
+
+
+void
+dk3str_c16_ncpy(dk3_c16_t *d, dk3_c16_t const *s, size_t n)
+{
+#if (DK3_HAVE_WCSNCPY) && (DK3_SIZEOF_WCHAR_T == 2)
+ wcsncpy(d,s,n);
+ d[n-1] = 0U;
+#else
+#if (DK3_HAVE__WCSNCPY) && (DK3_SIZEOF_WCHAR_T == 2)
+ _wcsncpy(d,s,n);
+ d[n-1] = 0U;
+#else
+ register dk3_c16_t *dp; /* Destionation pointer. */
+ register dk3_c16_t const *sp; /* Source pointer. */
+ register dk3_c16_t x; /* Current character. */
+ register size_t max; /* Maximum number of characters to copy. */
+ register size_t used; /* Characters already copied. */
+
+ dp = d; sp = s; max = n; used = 0;
+ while((*sp) && (used < max)) { x = *(sp++); *(dp++) = x; used++; }
+ if(used < max) { *dp = 0U; }
+ else { d[max - 1] = 0U; }
+#endif
+#endif
+}
+
+
+
+void
+dk3str_c32_ncpy(dk3_c32_t *d, dk3_c32_t const *s, size_t n)
+{
+#if (DK3_HAVE_WCSNCPY) && (DK3_SIZEOF_WCHAR_T == 4)
+ wcsncpy(d,s,n);
+ d[n-1] = 0UL;
+#else
+#if (DK3_HAVE__WCSNCPY) && (DK3_SIZEOF_WCHAR_T == 4)
+ _wcsncpy(d,s,n);
+ d[n-1] = 0UL;
+#else
+ register dk3_c32_t *dp; /* Destination pointer. */
+ register dk3_c32_t const *sp; /* Source pointer. */
+ register dk3_c32_t x; /* Current character. */
+ register size_t max; /* Maximum number of characters to copy. */
+ register size_t used; /* Number of characters copied. */
+
+ dp = d; sp = s; max = n; used = 0;
+ while((*sp) && (used < max)) { x = *(sp++); *(dp++) = x; used++; }
+ if(used < max) { *dp = 0UL; }
+ else { d[max - 1] = 0UL; }
+#endif
+#endif
+}
+
+
+
+void
+dk3str_ncpy(dkChar *d, dkChar const *s, size_t n)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ dk3str_c32_ncpy(d, s, n);
+#else
+ dk3str_c16_ncpy(d, s, n);
+#endif
+#else
+ dk3str_c8_ncpy(d, s, n);
+#endif
+}
+
+
+
+void
+dk3str_c8_cat(char *d, char const *s)
+{
+#if DK3_HAVE_STRCAT
+ strcat(d, s);
+#else
+ register char *dp; /* Destination buffer pointer. */
+ register char const *sp; /* Source buffer pointer. */
+ register char x;
+ dp = d; sp = s;
+ while(*dp) dp++;
+ while(*sp) { x = *(sp++); *(dp++) = x; }
+ *dp = '\0';
+#endif
+}
+
+
+
+void
+dk3str_c16_cat(dk3_c16_t *d, dk3_c16_t const *s)
+{
+#if (DK3_HAVE_WCSCAT) && (DK3_SIZEOF_WCHAR_T == 2)
+ wcscat(d, s);
+#else
+#if (DK3_HAVE__WCSCAT) && (DK3_SIZEOF_WCHAR_T == 2)
+ _wcscat(d, s);
+#else
+ register dk3_c16_t *dp; /* Destination pointer. */
+ register dk3_c16_t const *sp; /* Source pointer. */
+ register dk3_c16_t x; /* Current character. */
+ dp = d; sp = s;
+ while(*dp) dp++;
+ while(*sp) { x = *(sp++); *(dp++) = x; }
+ *dp = 0U;
+#endif
+#endif
+}
+
+
+
+void
+dk3str_c32_cat(dk3_c32_t *d, dk3_c32_t const *s)
+{
+#if (DK3_HAVE_WCSCAT) && (DK3_SIZEOF_WCHAR_T == 4)
+ wcscat(d, s);
+#else
+#if (DK3_HAVE__WCSCAT) && (DK3_SIZEOF_WCHAR_T == 4)
+ _wcscat(d, s);
+#else
+ register dk3_c32_t *dp; /* Destination pointer. */
+ register dk3_c32_t const *sp; /* Source pointer. */
+ register dk3_c32_t x; /* Current character. */
+
+ dp = d; sp = s;
+ while(*dp) dp++;
+ while(*sp) { x = *(sp++); *(dp++) = x; }
+ *dp = 0UL;
+#endif
+#endif
+}
+
+
+
+void
+dk3str_cat(dkChar *d, dkChar const *s)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ dk3str_c32_cat(d, s);
+#else
+ dk3str_c16_cat(d, s);
+#endif
+#else
+ dk3str_c8_cat(d, s);
+#endif
+}
+
+
+
+/** Report memory allocation error.
+ @param app Application structure.
+ @param elsize Size of one character.
+ @param nelem Number of characters required.
+*/
+static
+void
+dk3str_memory_error(dk3_app_t *app, size_t elsize, size_t nelem)
+{
+#if VERSION_BEFORE_20140716
+ dkChar bu1[64];
+ unsigned long prod;
+ prod = (unsigned long)elsize * (unsigned long)nelem;
+ dk3sf_sprintf3(bu1, dkT("%lu"), prod);
+ dk3app_log_i3(app, DK3_LL_ERROR, 12, 13, bu1);
+#else
+ dkChar bu1[64];
+ dk3_um_t prod;
+ int mec = 0;
+ prod = dk3ma_um_mul_ok((dk3_um_t)elsize, (dk3_um_t)nelem, &mec);
+ if (0 == mec) {
+ if (dk3ma_um_to_string(bu1, DK3_SIZEOF(bu1,dkChar), (dk3_um_t)prod)) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 12, 13, bu1);
+ }
+ } else {
+ /* Math overflow in size calculation */
+ dk3app_log_i1(app, DK3_LL_ERROR, 15);
+ }
+#endif
+}
+
+
+
+char *
+dk3str_c8_dup_app(char const *s, dk3_app_t *app)
+{
+ char *back;
+#if DK3_HAVE_STRDUP && (!DK3_ON_WINDOWS)
+ back = strdup(s);
+ if(!(back)) {
+ if(app) {
+ dk3str_memory_error(app, 1, (1+strlen(s)));
+ }
+ }
+#else
+#if DK3_HAVE__STRDUP || DK3_ON_WINDOWS
+ back = _strdup(s);
+ if(!(back)) {
+ if(app) {
+ dk3str_memory_error(app, 1, (1+strlen(s)));
+ }
+ }
+#else
+ size_t sz;
+ sz = 1 + dk3str_c8_len(s);
+ if(app) {
+ back = dk3_new_app(char,sz,app);
+ } else {
+ back = dk3_new(char,sz);
+ }
+ if(back) {
+ dk3str_c8_cpy_not_overlapped(back, s);
+ }
+#endif
+#endif
+ return back;
+}
+
+
+
+dk3_c16_t *
+dk3str_c16_dup_app(dk3_c16_t const *s, dk3_app_t *app)
+{
+ dk3_c16_t *back;
+#if (DK3_HAVE_WCSDUP) && (DK3_SIZEOF_WCHAR_T == 2)
+ back = wcsdup(s);
+ if(!(back)) {
+ if(app) {
+ dk3str_memory_error(app, 2, (1 + dk3str_c16_len(s)));
+ }
+ }
+#else
+#if (DK3_HAVE__WCSDUP) && (DK3_SIZEOF_WCHAR_T == 2)
+ back = _wcsdup(s);
+ if(!(back)) {
+ if(app) {
+ dk3str_memory_error(app, 2, (1 + dk3str_c16_len(s)));
+ }
+ }
+#else
+ size_t sz;
+ sz = 1 + dk3str_c16_len(s);
+ if(app) {
+ back = dk3_new_app(dk3_c16_t,sz,app);
+ } else {
+ back = dk3_new(dk3_c16_t,sz);
+ }
+ if(back) {
+ dk3str_c16_cpy_not_overlapped(back, s);
+ }
+#endif
+#endif
+ return back;
+}
+
+
+
+dk3_c32_t *
+dk3str_c32_dup_app(dk3_c32_t const *s, dk3_app_t *app)
+{
+ dk3_c32_t *back;
+#if (DK3_HAVE_WCSDUP) && (DK3_SIZEOF_WCHAR_T == 4)
+ back = wcsdup(s);
+ if(!(back)) {
+ if(app) {
+ dk3str_memory_error(app, 4, (1 + dk3str_c32_len(s)));
+ }
+ }
+#else
+#if (DK3_HAVE__WCSDUP) && (DK3_SIZEOF_WCHAR_T == 4)
+ back = _wcsdup(s);
+ if(!(back)) {
+ if(app) {
+ dk3str_memory_error(app, 4, (1 + dk3str_c32_len(s)));
+ }
+ }
+#else
+ size_t sz;
+ sz = 1 + dk3str_c32_len(s);
+ if(app) {
+ back = dk3_new_app(dk3_c32_t,sz,app);
+ } else {
+ back = dk3_new(dk3_c32_t,sz);
+ }
+ if(back) {
+ dk3str_c32_cpy(back, s);
+ }
+#endif
+#endif
+ return back;
+}
+
+
+
+dkChar *
+dk3str_dup_app(dkChar const *s, dk3_app_t *app)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_dup_app(s, app));
+#else
+ return(dk3str_c16_dup_app(s, app));
+#endif
+#else
+ return(dk3str_c8_dup_app(s, app));
+#endif
+}
+
+
+char
+dk3str_c8_tolower(char c)
+{
+ char back; /* Function result. */
+ back = c;
+ if((back >= 'A') && (back <= 'Z')) {
+ back = 'a' + (back - 'A');
+ }
+ return back;
+}
+
+
+
+dk3_c16_t
+dk3str_c16_tolower(dk3_c16_t c)
+{
+ dk3_c16_t back;
+ back = c;
+ if((back >= 0x0041U) && (back <= 0x005AU)) {
+ back = 0x0061U + (back - 0x0041U);
+ }
+ return back;
+}
+
+
+
+dk3_c32_t
+dk3str_c32_tolower(dk3_c32_t c)
+{
+ dk3_c32_t back;
+ back = c;
+ if((back >= (dk3_c32_t)0x00000041UL) && (back <= (dk3_c32_t)0x0000005AUL)) {
+ back = (dk3_c32_t)0x00000061UL + (back - (dk3_c32_t)0x00000041UL);
+ }
+ return back;
+}
+
+
+
+dkChar
+dk3str_tolower(dkChar c)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_tolower(c));
+#else
+ return(dk3str_c16_tolower(c));
+#endif
+#else
+ return(dk3str_c8_tolower(c));
+#endif
+}
+
+
+
+char
+dk3str_c8_toupper(char c)
+{
+ char back; /* Function result. */
+ back = c;
+ if((back >= 'a') && (back <= 'z')) {
+ back = 'A' + (back - 'a');
+ }
+ return back;
+}
+
+
+
+dk3_c16_t
+dk3str_c16_toupper(dk3_c16_t c)
+{
+ dk3_c16_t back;
+ back = c;
+ if((back >= 0x0061U) && (back <= 0x007AU)) {
+ back = 0x0041U + (back - 0x0061U);
+ }
+ return back;
+}
+
+
+
+dk3_c32_t
+dk3str_c32_toupper(dk3_c32_t c)
+{
+ dk3_c32_t back;
+ back = c;
+ if((back >= (dk3_c32_t)0x00000061UL) && (back <= (dk3_c32_t)0x0000007AUL)) {
+ back = (dk3_c32_t)0x00000041UL + (back - (dk3_c32_t)0x00000061UL);
+ }
+ return back;
+}
+
+
+
+dkChar
+dk3str_toupper(dkChar c)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_toupper(c));
+#else
+ return(dk3str_c16_toupper(c));
+#endif
+#else
+ return(dk3str_c8_toupper(c));
+#endif
+}
+
+
+
+char *
+dk3str_c8_start(char const *str, char const *whsp)
+{
+ char *back = NULL; /* Function result. */
+ char const *ptr; /* Pointer to traverse str. */
+ char const *wh; /* Whitespaces set. */
+ $? "+ dkstr_start %!8s", TR_8STR(str)
+ if(str) {
+ wh = (whsp ? whsp : dk3str_c8_def_whsp);
+ ptr = str;
+ while((*ptr) && (!(back))) {
+ if(dk3str_c8_chr(wh,*ptr)) {
+ ptr++;
+ } else {
+ back = (char *)ptr;
+ }
+ }
+ } $? "- dkstr_start %!8s", TR_8STR(back)
+ return back;
+}
+
+
+
+dk3_c16_t *
+dk3str_c16_start(dk3_c16_t const *str, dk3_c16_t const *whsp)
+{
+ dk3_c16_t *back = NULL;
+ dk3_c16_t const *ptr; /* Pointer into string. */
+ dk3_c16_t const *wh; /* Whitespaces set. */
+
+ if(str) {
+ wh = (whsp ? whsp : c16_def_whsp);
+ ptr = str;
+ while((*ptr) && (!(back))) {
+ if(dk3str_c16_chr(wh, *ptr)) {
+ ptr++;
+ } else {
+ back = (dk3_c16_t *)ptr;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+dk3_c32_t *
+dk3str_c32_start(dk3_c32_t const *str, dk3_c32_t const *whsp)
+{
+ dk3_c32_t *back = NULL;
+ dk3_c32_t const *ptr = NULL; /* Current character. */
+ dk3_c32_t const *wh = NULL; /* Whitespaces set. */
+ $? "+ dk3str_c32_start \"%!ws\"", (str ? str : L"NULL")
+ if(str) {
+ wh = (whsp ? whsp : c32_def_whsp);
+ ptr = str;
+ while((*ptr) && (!(back))) {
+ if(dk3str_c32_chr(wh, *ptr)) {
+ ptr++;
+ } else {
+ back = (dk3_c32_t *)ptr;
+ }
+ }
+ } $? "- dk3str_c32_start \"%!ws\"", (back ? back : L"NULL")
+ return back;
+}
+
+
+
+dkChar *
+dk3str_start(dkChar const *str, dkChar const *whsp)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_start(str, whsp));
+#else
+ return(dk3str_c16_start(str, whsp));
+#endif
+#else
+ return(dk3str_c8_start(str, whsp));
+#endif
+}
+
+
+
+char *
+dk3str_c8_next(char *str, char const *whsp)
+{
+ char *back = NULL; /* Function result. */
+ char *ptr = NULL; /* Pointer to traverse str. */
+ char const *wh = NULL; /* Whitespaces set to use. */
+ int state = 0; /* Current processing state. */
+ $? "+ dkstr_next %!8s", TR_8STR(str)
+ if(str) {
+ ptr = str;
+ wh = (whsp ? whsp : dk3str_c8_def_whsp);
+ state = 0;
+ while((state < 2) && (*ptr)) {
+ if(dk3str_c8_chr(wh, *ptr)) {
+ if(state == 1) {
+ state = 2;
+ *(ptr++) = '\0';
+ back = dk3str_c8_start(ptr, wh);
+ } else {
+ ptr++;
+ }
+ } else {
+ state = 1;
+ ptr++;
+ }
+ }
+ } $? "- dkstr_next %!8s", TR_8STR(back)
+ return back;
+}
+
+
+
+dk3_c16_t *
+dk3str_c16_next(dk3_c16_t *str, dk3_c16_t const *whsp)
+{
+ dk3_c16_t *back = NULL;
+ dk3_c16_t *ptr; /* Pointer into string. */
+ dk3_c16_t const *wh; /* Whitespaces set. */
+ int state; /* Current state. */
+
+ if(str) {
+ ptr = str;
+ wh = (whsp ? whsp : c16_def_whsp);
+ state = 0;
+ while((state < 2) && (*ptr)) {
+ if(dk3str_c16_chr(wh, *ptr)) {
+ if(state == 1) {
+ state = 2;
+ *(ptr++) = 0U;
+ back = dk3str_c16_start(ptr, wh);
+ } else {
+ ptr++;
+ }
+ } else {
+ state = 1; ptr++;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+dk3_c32_t *
+dk3str_c32_next(dk3_c32_t *str, dk3_c32_t const *whsp)
+{
+ dk3_c32_t *back = NULL;
+ dk3_c32_t *ptr = NULL; /* Pointer into string. */
+ dk3_c32_t const *wh = NULL; /* Whitespaces. */
+ int state = 0; /* Current processing state. */
+ $? "+ dk3str_c32_next \"%ls\"\n", str
+ if(str) {
+ ptr = str;
+ wh = (whsp ? whsp : c32_def_whsp);
+ state = 0;
+ while((state < 2) && (*ptr)) {
+ if(dk3str_c32_chr(wh, *ptr)) { $? ". loop state=%d ptr=\"%!ws\"", state, (ptr ? ptr : L"NULL")
+ if(state == 1) {
+ state = 2;
+ *(ptr++) = 0UL;
+ back = dk3str_c32_start(ptr, wh);
+ } else {
+ ptr++;
+ }
+ } else {
+ state = 1; ptr++;
+ }
+ }
+ } $? "- dk3str_c32_next \"%!ws\"\n", (back ? back : L"NULL")
+ return back;
+}
+
+
+
+dkChar *
+dk3str_next(dkChar *str, dkChar const *whsp)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_next(str, whsp));
+#else
+ return(dk3str_c16_next(str, whsp));
+#endif
+#else
+ return(dk3str_c8_next(str, whsp));
+#endif
+}
+
+
+
+void
+dk3str_c8_chomp(char *str, char const *whsp)
+{
+ char const *wh; /* Whitespaces set to use. */
+ char *ptr; /* Pointer to traverse str. */
+ char *x; /* Start position of final space sequence. */
+ $? "+ dkstr_chomp %!8s", TR_8STR(str)
+ if(str) {
+ wh = (whsp ? whsp : dk3str_c8_def_whsp);
+ x = NULL; ptr = str;
+ while(*ptr) {
+ if(dk3str_c8_chr(wh, *ptr)) {
+ if(!(x)) { x = ptr; }
+ } else {
+ x = NULL;
+ }
+ ptr++;
+ }
+ if(x) { *x = '\0'; }
+ }
+ $? "- dkstr_chomp %!8s", TR_8STR(str)
+}
+
+
+
+void
+dk3str_c16_chomp(dk3_c16_t *str, dk3_c16_t const *whsp)
+{
+ dk3_c16_t const *wh; /* Whitespaces set. */
+ dk3_c16_t *ptr; /* Pointer into string. */
+ dk3_c16_t *x; /* Test pointer for whitespaces set. */
+
+ if(str) {
+ wh = (whsp ? whsp : c16_def_whsp);
+ x = NULL; ptr = str;
+ while(*ptr) {
+ if(dk3str_c16_chr(wh, *ptr)) {
+ if(!(x)) x = ptr;
+ } else {
+ x = NULL;
+ }
+ ptr++;
+ }
+ if(x) { *x = 0U; }
+ }
+}
+
+
+
+void
+dk3str_c32_chomp(dk3_c32_t *str, dk3_c32_t const *whsp)
+{
+ dk3_c32_t const *wh = NULL; /* Whitespaces set. */
+ dk3_c32_t *ptr = NULL; /* Pointer into string. */
+ dk3_c32_t *x = NULL; /* For whitespace-set test. */
+
+ if(str) {
+ wh = (whsp ? whsp : c32_def_whsp);
+ x = NULL; ptr = str;
+ while(*ptr) {
+ if(dk3str_c32_chr(wh, *ptr)) {
+ if(!(x)) x = ptr;
+ } else {
+ x = NULL;
+ }
+ ptr++;
+ }
+ if(x) { *x = 0UL; }
+ }
+}
+
+
+
+void
+dk3str_chomp(dkChar *str, dkChar const *whsp)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ dk3str_c32_chomp(str, whsp);
+#else
+ dk3str_c16_chomp(str, whsp);
+#endif
+#else
+ dk3str_c8_chomp(str, whsp);
+#endif
+}
+
+
+
+void
+dk3str_c8_delnl(char *str)
+{
+ char *ptr;
+ if(str) {
+ ptr = str;
+ while(*ptr) {
+ if(*ptr == 0x0D) {
+ if(ptr[1] == 0x0A) {
+ *ptr = '\0';
+ } else {
+ ptr++;
+ }
+ } else {
+ if(*ptr == 0x0A) {
+ *ptr = '\0';
+ } else {
+ ptr++;
+ }
+ }
+ }
+ }
+}
+
+
+
+void
+dk3str_c16_delnl(dk3_c16_t *str)
+{
+ dk3_c16_t *ptr;
+ if(str) {
+ ptr = str;
+ while(*ptr) {
+ if(*ptr == 0x000DU) {
+ if(ptr[1] == 0x000AU) {
+ *ptr = (dk3_c16_t)0U;
+ } else {
+ ptr++;
+ }
+ } else {
+ if(*ptr == 0x000AU) {
+ *ptr = (dk3_c16_t)0U;
+ } else {
+ ptr++;
+ }
+ }
+ }
+ }
+}
+
+
+
+void
+dk3str_c32_delnl(dk3_c32_t *str)
+{
+ dk3_c32_t *ptr;
+ if(str) {
+ ptr = str;
+ while(*ptr) {
+ if(*ptr == 0x0000000DUL) {
+ if(ptr[1] == 0x0000000AUL) {
+ *ptr = (dk3_c32_t)0UL;
+ } else {
+ ptr++;
+ }
+ } else {
+ if(*ptr == 0x0000000AUL) {
+ *ptr = (dk3_c32_t)0UL;
+ } else {
+ ptr++;
+ }
+ }
+ }
+ }
+}
+
+
+
+void
+dk3str_delnl(dkChar *str)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ dk3str_c32_delnl(str);
+#else
+ dk3str_c16_delnl(str);
+#endif
+#else
+ dk3str_c8_delnl(str);
+#endif
+}
+
+
+
+int
+dk3str_c8_array_index(char const * const *a, char const *s, int c)
+{
+ int back = -1; /* Function result. */
+ int ci; /* Current array index for test. */
+ char const * const *ap; /* Pointer to traverse array a. */
+ if((a) && (s)) {
+ ap = a; ci = 0;
+ while((*ap) && (back == -1)) {
+ if(c) {
+ if(dk3str_c8_cmp(*ap, s) == 0) back = ci;
+ } else {
+ if(dk3str_c8_casecmp(*ap, s) == 0) back = ci;
+ }
+ if(back == -1) { ap++; ci++; }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3str_c16_array_index(dk3_c16_t const * const *a, dk3_c16_t const *s, int c)
+{
+ int back = -1;
+ int ci; /* Current index. */
+ dk3_c16_t const * const *ap; /* Pointer into array. */
+ if((a) && (s)) {
+ ap = a; ci = 0;
+ while((*ap) && (back == -1)) {
+ if(c) {
+ if(dk3str_c16_cmp(*ap, s) == 0) back = ci;
+ } else {
+ if(dk3str_c16_casecmp(*ap, s) == 0) back = ci;
+ }
+ if(back == -1) { ap++; ci++; }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3str_c32_array_index(dk3_c32_t const * const *a, dk3_c32_t const *s, int c)
+{
+ int back = -1;
+ int ci; /* Current index. */
+ dk3_c32_t const * const *ap; /* Pointer into array. */
+
+ if((a) && (s)) {
+ ap = a; ci = 0;
+ while((*ap) && (back == -1)) {
+ if(c) {
+ if(dk3str_c32_cmp(*ap, s) == 0) back = ci;
+ } else {
+ if(dk3str_c32_casecmp(*ap, s) == 0) back = ci;
+ }
+ if(back == -1) { ap++; ci++; }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3str_array_index(dkChar const * const *a, dkChar const *s, int c)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_array_index(a, s, c));
+#else
+ return(dk3str_c16_array_index(a, s, c));
+#endif
+#else
+ return(dk3str_c8_array_index(a, s, c));
+#endif
+}
+
+
+
+int
+dk3str_c8_is_abbr(char const *line,char const *pattern,char spec,int cs)
+{
+ int back = 0; /* Function result. */
+ char cl; /* Current character from line. */
+ char cp; /* Current character from pattern. */
+ char const *lptr = NULL; /* Pointer to traverse line. */
+ char const *pptr = NULL; /* Pointer to traverse pattern. */
+ int afterspec = 0; /* Flag: cs was already found in the pattern. */
+ int cc = 0; /* Flag: Can continue. */
+ $? "+ dkstr_is_abbr %!8s %!8s %!8c %d", TR_8STR(line), TR_8STR(pattern), spec, cs
+ if((line) && (pattern)) {
+ lptr = line; pptr = pattern; afterspec = 0; cc = 1;
+ while(cc) {
+ if(*pptr) {
+ if((!afterspec) && (*pptr == spec)) {
+ afterspec = 1; pptr++;
+ } else {
+ if(*lptr) {
+ cl = *lptr; cp = *pptr;
+ if(!cs) {
+ cl = dk3str_c8_toupper(cl);
+ cp = dk3str_c8_toupper(cp);
+ }
+ if(cl == cp) {
+ lptr++; pptr++;
+ } else {
+ cc = 0; back = 0;
+ }
+ } else {
+ cc = 0;
+ if(afterspec) back = 1;
+ }
+ }
+ } else {
+ cc = 0;
+ if(!(*lptr)) {
+ back = 1;
+ }
+ }
+ }
+ }
+ $? "- dkstr_is_abbr %d", back
+ return back;
+}
+
+
+
+int
+dk3str_c16_is_abbr(dk3_c16_t const *line, dk3_c16_t const *pattern, dk3_c16_t spec, int cs)
+{
+ int back = 0;
+ dk3_c16_t cl; /* Current character from line. */
+ dk3_c16_t cp; /* Current character from pattern. */
+ dk3_c16_t const *lptr; /* Input text to check. */
+ dk3_c16_t const *pptr; /* Pattern. */
+ int afterspec; /* Flag: Abbreviation inidicator found. */
+ int cc; /* Flag: Can continue. */
+
+ if((line) && (pattern)) {
+ lptr = line; pptr = pattern; afterspec = 0; cc = 1;
+ while(cc) {
+ if(*pptr) {
+ if((!afterspec) && (*pptr == spec)) {
+ afterspec = 1; pptr++;
+ } else {
+ if(*lptr) {
+ cl = *lptr; cp = *pptr;
+ if(!cs) {
+ cl = dk3str_c16_toupper(cl);
+ cp = dk3str_c16_toupper(cp);
+ }
+ if(cl == cp) {
+ lptr++; pptr++;
+ } else {
+ cc = 0; back = 0;
+ }
+ } else {
+ cc = 0;
+ if(afterspec) back = 1;
+ }
+ }
+ } else {
+ cc = 0;
+ if(!(*lptr)) {
+ back = 1;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3str_c32_is_abbr(dk3_c32_t const *line, dk3_c32_t const *pattern, dk3_c32_t spec, int cs)
+{
+ int back = 0;
+ dk3_c32_t cl = 0UL; /* Text character. */
+ dk3_c32_t cp = 0UL; /* Pattern character. */
+ dk3_c32_t const *lptr = NULL; /* Pointer into text. */
+ dk3_c32_t const *pptr = NULL; /* Pointer into pattern. */
+ int afterspec = 0; /* Flag: Abbreviation indicator was found. */
+ int cc = 0; /* Flag: Can continue. */
+
+ if((line) && (pattern)) {
+ lptr = line; pptr = pattern; afterspec = 0; cc = 1;
+ while(cc) {
+ if(*pptr) {
+ if((!afterspec) && (*pptr == spec)) {
+ afterspec = 1; pptr++;
+ } else {
+ if(*lptr) {
+ cl = *lptr; cp = *pptr;
+ if(!cs) {
+ cl = dk3str_c32_toupper(cl);
+ cp = dk3str_c32_toupper(cp);
+ }
+ if(cl == cp) {
+ lptr++; pptr++;
+ } else {
+ cc = 0; back = 0;
+ }
+ } else {
+ cc = 0;
+ if(afterspec) back = 1;
+ }
+ }
+ } else {
+ cc = 0;
+ if(!(*lptr)) { back = 1; }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3str_is_abbr(dkChar const *line, dkChar const *pattern, dkChar spec, int cs)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_is_abbr(line, pattern, spec, cs));
+#else
+ return(dk3str_c16_is_abbr(line, pattern, spec, cs));
+#endif
+#else
+ return(dk3str_c8_is_abbr(line, pattern, spec, cs));
+#endif
+}
+
+
+
+int
+dk3str_c8_array_abbr(char const * const *ar, char const *str, char sp, int cs)
+{
+ int back = -1; /* Function result. */
+ char const * const *ptr; /* Pointer to traverse array ar. */
+ int i; /* Current index of ptr in ar. */
+ $? "+ dk3str_c8_array_abbr %!8s %!8s %d", TR_8PTR(ar), TR_8STR(str), cs
+ if((ar) && (str)) {
+ i = 0; ptr = ar;
+ while((*ptr) && (back == -1)) {
+ $? ". i=%d ptr=%!8s", i, TR_8STR(*ptr)
+ if(dk3str_c8_is_abbr(str, *ptr, sp, cs)) {
+ back = i;
+ }
+ if(back == -1) {
+ ptr++; i++;
+ }
+ $? ". back=%d", back
+ }
+ } $? "- dk3str_c8_array_abbr %d", back
+ return back;
+}
+
+
+
+int
+dk3str_c16_array_abbr(dk3_c16_t const * const *arr, dk3_c16_t const *str, dk3_c16_t sp, int cs)
+{
+ int back = -1;
+ dk3_c16_t const * const *ptr; /* Pointer into array. */
+ int i; /* Current index. */
+ $? "+ dk3str_c16_array_abbr"
+ if((arr) && (str)) { $? ". arguments ok"
+ i = 0; ptr = arr;
+ while((*ptr) && (back == -1)) { $? ". loop start"
+ if(dk3str_c16_is_abbr(str, *ptr, sp, cs)) { $? ". match"
+ back = i;
+ } else { $? "! no match"
+ }
+ if(back == -1) {
+ ptr++; i++;
+ } $? ". loop end"
+ } $? ". after loop"
+ } $? "- dk3str_array_abbr %d", back
+ return back;
+}
+
+
+
+int
+dk3str_c32_array_abbr(dk3_c32_t const * const *arr, dk3_c32_t const *str, dk3_c32_t sp, int cs)
+{
+ int back = -1;
+ dk3_c32_t const * const *ptr = NULL; /* Pointer into array. */
+ int i = 0; /* Current index. */
+
+ if((arr) && (str)) {
+ i = 0; ptr = arr;
+ while((*ptr) && (back == -1)) {
+ if(dk3str_c32_is_abbr(str, *ptr, sp, cs)) {
+ back = i;
+ }
+ if(back == -1) {
+ ptr++; i++;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3str_array_abbr(dkChar const * const *ar,dkChar const *str,dkChar sp,int cs)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_array_abbr(ar, str, sp, cs));
+#else
+ return(dk3str_c16_array_abbr(ar, str, sp, cs));
+#endif
+#else
+ return(dk3str_c8_array_abbr(ar, str, sp, cs));
+#endif
+}
+
+
+
+int
+dk3str_c8_is_bool(char const *str)
+{
+ int back = 0; /* Function result. */
+ $? "+ dkstr_is_bool %!8s", TR_8STR(str)
+ if(str) {
+ if(dk3str_c8_array_abbr(dk3str_c8_bool_kw,str,'$',0) >= 0) {
+ back = 1;
+ }
+ } $? "- dkstr_is_bool %d", back
+ return back;
+}
+
+
+
+int
+dk3str_c16_is_bool(dk3_c16_t const *str)
+{
+ int back = 0;
+ char mytest[256]; /* 8-bit version of the str text. */
+ if(str) {
+#if VERSION_BEFORE_20130928
+ if(dk3str_c16_to_c8_simple(mytest, sizeof(mytest), str)) {
+ back = dk3str_c8_is_bool(mytest);
+ }
+#else
+ if(dk3str_cnv_c16_to_c8u_app(mytest, sizeof(mytest), str, NULL)) {
+ back = dk3str_c8_is_bool(mytest);
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3str_c32_is_bool(dk3_c32_t const *str)
+{
+ int back = 0;
+ char mytest[256]; /* 8-bit text copy of str. */
+ if(str) {
+#if VERSION_BEFORE_20130928
+ if(dk3str_c32_to_c8_simple(mytest, sizeof(mytest), str)) {
+ back = dk3str_c8_is_bool(mytest);
+ }
+#else
+ if(dk3str_cnv_c32_to_c8u_app(mytest, sizeof(mytest), str, NULL)) {
+ back = dk3str_c8_is_bool(mytest);
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3str_is_bool(dkChar const *str)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_is_bool(str));
+#else
+ return(dk3str_c16_is_bool(str));
+#endif
+#else
+ return(dk3str_c8_is_bool(str));
+#endif
+}
+
+
+
+int
+dk3str_c8_is_on(char const *str)
+{
+ int back = 0; /* Function result. */
+ $? "+ dkstr_is_on %!8s",TR_8STR(str)
+ if(str) {
+ if(dk3str_c8_array_abbr(dk3str_c8_bool_kw,str,'$',0) >= INDEX_OF_FIRST_BOOLEAN_TRUE) {
+ back = 1;
+ }
+ } $? "- dkstr_is_on %d", back
+ return back;
+}
+
+
+
+int
+dk3str_c16_is_on(dk3_c16_t const *str)
+{
+ int back = 0;
+ char mytest[256]; /* 8-bit version of the str text. */
+ if(str) {
+#if VERSION_BEFORE_20130928
+ if(dk3str_c16_to_c8_simple(mytest, sizeof(mytest), str)) {
+ back = dk3str_c8_is_on(mytest);
+ }
+#else
+ if(dk3str_cnv_c16_to_c8u_app(mytest, sizeof(mytest), str, NULL)) {
+ back = dk3str_c8_is_on(mytest);
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3str_c32_is_on(dk3_c32_t const *str)
+{
+ int back = 0;
+ char mytest[256]; /* 8-bit copy of str text. */
+ if(str) {
+#if VERSION_BEFORE_20130928
+ if(dk3str_c32_to_c8_simple(mytest, sizeof(mytest), str)) {
+ back = dk3str_c8_is_on(mytest);
+ }
+#else
+ if(dk3str_cnv_c32_to_c8u_app(mytest, sizeof(mytest), str, NULL)) {
+ back = dk3str_c8_is_on(mytest);
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3str_is_on(dkChar const *str)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_is_on(str));
+#else
+ return(dk3str_c16_is_on(str));
+#endif
+#else
+ return(dk3str_c8_is_on(str));
+#endif
+}
+
+
+
+size_t
+dk3str_c8_explode(char **array, size_t sz, char *str, char const *whsp)
+{
+ size_t back = 0; /* Function result. */
+ char const *wh = NULL; /* White spaces set to use. */
+ char *current = NULL; /* Current text word to process. */
+ char *next = NULL; /* Remaining text after processing the word. */
+ char **ptr = NULL; /* Pointer to current array element. */
+ size_t i = 0; /* Number of remaining usable array elements. */
+ if((array) && (sz > 1) && (str)) {
+ wh = (whsp ? whsp : dk3str_c8_def_whsp);
+ ptr = array; i = sz;
+ while(i--) { *(ptr++) = NULL; }
+ ptr = array; i = 0;
+ current = dk3str_c8_start(str, wh);
+ while((current) && (i < (sz - 1))) {
+ next = dk3str_c8_next(current,wh);
+ *(ptr++) = current; i++; back++;
+ current = next;
+ }
+ }
+ return back;
+}
+
+
+
+size_t
+dk3str_c16_explode(dk3_c16_t **array, size_t sz, dk3_c16_t *str, dk3_c16_t const *whsp)
+{
+ size_t back = 0;
+ dk3_c16_t const *wh = NULL; /* Whitespaces set. */
+ dk3_c16_t *current = NULL; /* Start of current word. */
+ dk3_c16_t *next = NULL; /* Start of next word after current. */
+ dk3_c16_t **ptr = NULL; /* Pointer into array. */
+ size_t i = 0; /* Number of words found. */
+
+ if((array) && (sz > 1) && (str)) {
+ wh = (whsp ? whsp : c16_def_whsp);
+ ptr = array; i = sz;
+ while(i--) { *(ptr++) = NULL; }
+ ptr = array; i = 0;
+ current = dk3str_c16_start(str, wh);
+ while((current) && (i < (sz - 1))) {
+ next = dk3str_c16_next(current, wh);
+ *(ptr++) = current; i++; back++;
+ current = next;
+ }
+ }
+ return back;
+}
+
+
+
+size_t
+dk3str_c32_explode(dk3_c32_t **array, size_t sz, dk3_c32_t *str, dk3_c32_t const *whsp)
+{
+ size_t back = 0;
+ dk3_c32_t const *wh = NULL; /* Whitespace set. */
+ dk3_c32_t *current = NULL; /* Current word. */
+ dk3_c32_t *next = NULL; /* Next word. */
+ dk3_c32_t **ptr = NULL; /* Pointer into destination array. */
+ size_t i = 0; /* Current index. */
+ if((array) && (sz > 1) && (str)) {
+ wh = (whsp ? whsp : c32_def_whsp);
+ ptr = array; i = sz;
+ while(i--) { *(ptr++) = NULL; }
+ ptr = array; i = 0;
+ current = dk3str_c32_start(str, wh);
+ while((current) && (i < (sz - 1))) {
+ next = dk3str_c32_next(current, wh);
+ *(ptr++) = current; i++; back++;
+ current = next;
+ }
+ }
+ return back;
+}
+
+
+
+size_t
+dk3str_explode(dkChar **array, size_t sz, dkChar *str, dkChar const *whsp)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_explode(array, sz, str, whsp));
+#else
+ return(dk3str_c16_explode(array, sz, str, whsp));
+#endif
+#else
+ return(dk3str_c8_explode(array, sz, str, whsp));
+#endif
+}
+
+
+
+void
+dk3str_c8_normalize(char *l, char const *w, char s)
+{
+ char *parts[256]; /* All the text words. */
+ char *dp = NULL; /* Destination pointer. */
+ char *sp = NULL; /* Source pointer. */
+ size_t np = 0; /* Number of parts used. */
+ size_t i = 0; /* Current word to process. */
+ if(l) {
+ np = dk3str_c8_explode(parts, 255, l, w);
+ if(np > 0) {
+ dp = l;
+ for(i = 0; i < np; i++) {
+ sp = parts[i];
+ if(i) { *(dp++) = s; }
+ while(*sp) { *(dp++) = *(sp++); }
+ }
+ *dp = '\0';
+ }
+ }
+}
+
+
+
+void
+dk3str_c16_normalize(dk3_c16_t *l, dk3_c16_t const *w, dk3_c16_t s)
+{
+ dk3_c16_t *parts[256]; /* Pointers to the words. */
+ dk3_c16_t *dp = NULL; /* Destination pointer. */
+ dk3_c16_t *sp = NULL; /* Source pointer. */
+ size_t np = 0; /* Number of parts. */
+ size_t i = 0; /* Index of current part. */
+
+ if(l) {
+ np = dk3str_c16_explode(parts, 255, l, w);
+ if(np > 0) {
+ dp = l;
+ for(i = 0; i < np; i++) {
+ sp = parts[i];
+ if(i) { *(dp++) = s; }
+ while(*sp) { *(sp++) = *(dp++); }
+ }
+ *dp = 0U;
+ }
+ }
+}
+
+
+
+void
+dk3str_c32_normalize(dk3_c32_t *l, dk3_c32_t const *w, dk3_c32_t s)
+{
+ dk3_c32_t *parts[256]; /* Words. */
+ dk3_c32_t *dp = NULL; /* Destination pointer. */
+ dk3_c32_t *sp = NULL; /* Source pointer. */
+ size_t np = 0; /* Number of words. */
+ size_t i = 0; /* Index of current word. */
+ if(l) {
+ np = dk3str_c32_explode(parts, 255, l, w);
+ if(np > 0) {
+ dp = l;
+ for(i = 0; i < np; i++) {
+ sp = parts[i];
+ if(i) { *(dp++) = s; }
+ while(*sp) { *(dp++) = *(sp++); }
+ }
+ *dp = 0UL;
+ }
+ }
+}
+
+
+
+void
+dk3str_normalize(dkChar *l, dkChar const *w, dkChar s)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ dk3str_c32_normalize(l, w, s);
+#else
+ dk3str_c16_normalize(l, w, s);
+#endif
+#else
+ dk3str_c8_normalize(l, w, s);
+#endif
+}
+
+
+
+void
+dk3str_c8_correct_filename(char *n)
+{
+ register char *p;
+ p = n;
+ while(*p) { if(*p == NO_FNS_C8) { *p = FNS_C8; } p++; }
+}
+
+
+
+void
+dk3str_c16_correct_filename(dk3_c16_t *n)
+{
+ register dk3_c16_t *p;
+ p = n;
+ while(*p) { if(*p == NO_FNS_C16) { *p = FNS_C16; } p++;}
+}
+
+
+
+void
+dk3str_c32_correct_filename(dk3_c32_t *n)
+{
+ register dk3_c32_t *p; /* Pointer into text. */
+ p = n;
+ while(*p) { if(*p == NO_FNS_C32) { *p = FNS_C32; } p++;}
+}
+
+
+
+void
+dk3str_correct_filename(dkChar *n)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ dk3str_c32_correct_filename(n);
+#else
+ dk3str_c16_correct_filename(n);
+#endif
+#else
+ dk3str_c8_correct_filename(n);
+#endif
+}
+
+
+
+int
+dk3str_c8_is_abs_path(char const *n)
+{
+ int back = 0;
+ if(n) {
+ if(*n == FNS_C8) {
+ back = 1;
+ } else {
+#if DK3_ON_WINDOWS
+ if(((*n >= 'A') && (*n <= 'Z')) || ((*n >= 'a') && (*n <= 'z'))) {
+ if(n[1] == ':') {
+ if(n[2] == FNS_C8) {
+ back = 1;
+ }
+ }
+ }
+#endif
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3str_c16_is_abs_path(dk3_c16_t const *n)
+{
+ int back = 0;
+ if(n) {
+ if(*n == FNS_C16) {
+ back = 1;
+ } else {
+#if DK3_ON_WINDOWS
+ if(((*n >= 0x0061U) && (*n <= 0x007AU))
+ || ((*n >= 0x0041U) && (*n <= 0x005AU)))
+ {
+ if(n[1] == 0x003AU) {
+ if(n[2] == FNS_C16) {
+ back = 1;
+ }
+ }
+ }
+#endif
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3str_c32_is_abs_path(dk3_c32_t const *n)
+{
+ int back = 0;
+ $? "+ dk3str_c32_is_abs_path \"%ls\"", n
+ if(n) {
+ if(*n == FNS_C32) {
+ back = 1;
+ } else {
+#if DK3_ON_WINDOWS
+ if(((*n >= 0x00000061UL) && (*n <= 0x0000007AUL))
+ || ((*n >= 0x00000041UL) && (*n <= 0x0000005AUL)))
+ {
+ if(n[1] == 0x0000003AUL) {
+ if(n[2] == FNS_C32) {
+ back = 1;
+ }
+ }
+ }
+#endif
+ }
+ } $? "- dk3str_c32_is_abs_path %d", back
+ return back;
+}
+
+
+
+int
+dk3str_is_abs_path(dkChar const *n)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_is_abs_path(n));
+#else
+ return(dk3str_c16_is_abs_path(n));
+#endif
+#else
+ return(dk3str_c8_is_abs_path(n));
+#endif
+}
+
+
+
+int
+dk3str_c8_append_path_app(char *d, size_t sz, char const *n, dk3_app_t *app)
+{
+ int back = 0; /* Function result. */
+ char myn[DK3_MAX_PATH]; /* My editable copy of n. */
+ char *p1 = NULL; /* Current name part. */
+ char *p2 = NULL; /* Remaining text. */
+ char *p3 = NULL; /* Used to delete one part from path. */
+ size_t tsz; /* Size for tests. */
+ if((d) && (sz) && (n)) {
+ if(dk3str_c8_is_abs_path(n)) { /* Absolute path, copy. */
+ if(dk3str_c8_len(n) < sz) {
+ dk3str_c8_cpy(d,n);
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Name n too long! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 109);
+ }
+ }
+ } else { /* Relative path, append. */
+ if(dk3str_c8_len(n) < sizeof(myn)) {
+ back = 1;
+ dk3str_c8_cpy(myn,n);
+ p1 = myn;
+ while((p1) && (back)) {
+ p2 = dk3str_c8_chr(p1,FNS_C8);
+ if(p2) { *(p2++) = '\0'; }
+ if(dk3str_c8_cmp(dk3str_c8_dot,p1)) {
+ if(dk3str_c8_cmp(dk3str_c8_dot_dot,p1)) { /* Add another part. */
+ tsz = dk3str_c8_len(d) + dk3str_c8_len(dk3str_c8_fnsep)
+ + dk3str_c8_len(p1);
+ if(tsz < sz) {
+ dk3str_c8_cat(d,dk3str_c8_fnsep);
+ dk3str_c8_cat(d,p1);
+ } else {
+ if(app) {
+ /* ERROR: Result too long for destination buffer! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ } else { /* Remove last part. */
+ p3 = dk3str_c8_rchr(d,FNS_C8);
+ if(p3) {
+ *p3 = '\0';
+ } else {
+ if(app) {
+ /* ERROR: Too many ".." entries! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 110, 111, n);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 126);
+#endif
+ }
+ }
+ }
+ }
+ p1 = p2;
+ }
+ } else {
+ if(app) {
+ /* ERROR: Name n too long! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 109);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3str_c16_append_path_app(dk3_c16_t *d, size_t sz, dk3_c16_t const *n, dk3_app_t *app)
+{
+ int back = 0;
+ dk3_c16_t myn[DK3_MAX_PATH];
+ dk3_c16_t *p1 = NULL; /* Path component to process. */
+ dk3_c16_t *p2 = NULL; /* Remainder of path. */
+ dk3_c16_t *p3 = NULL; /* Last path component to remove. */
+ size_t tsz; /* Test size. */
+
+ if((d) && (sz) && (n)) {
+ if(dk3str_c16_is_abs_path(n)) {
+ if(dk3str_c16_len(n) < sz) {
+ dk3str_c16_cpy(d,n) ;
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Name n too long! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 109);
+ }
+ }
+ } else {
+ if(dk3str_c16_len(n) < DK3_SIZEOF(myn,dk3_c16_t)) {
+ back = 1;
+ dk3str_c16_cpy(myn,n) ;
+ p1 = myn;
+ while((p1) && (back)) {
+ p2 = dk3str_c16_chr(p1, FNS_C16);
+ if(p2) { *(p2++) = 0U; }
+ if(dk3str_c16_cmp(c16_dot,p1)) {
+ if(dk3str_c16_cmp(c16_dot_dot,p1)) {
+ tsz = dk3str_c16_len(d) + dk3str_c16_len(c16_fnsep)
+ + dk3str_c16_len(p1);
+ if(tsz < sz) {
+ dk3str_c16_cat(d,c16_fnsep);
+ dk3str_c16_cat(d,p1);
+ } else {
+ if(app) {
+ /* ERROR: Result too long for destination buffer! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ } else {
+ p3 = dk3str_c16_rchr(d,FNS_C16);
+ if(p3) {
+ *p3 = 0U;
+ } else {
+ if(app) {
+ /* ERROR: Too many ".." entries! */
+#if DK3_CHAR_SIZE == 2
+ dk3app_log_i3(app, DK3_LL_ERROR, 110, 111, n);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 126);
+#endif
+ }
+ }
+ }
+ }
+ p1 = p2;
+ }
+ } else {
+ if(app) {
+ /* ERROR: Name n too long! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 109);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3str_c32_append_path_app(dk3_c32_t *d, size_t sz, dk3_c32_t const *n, dk3_app_t *app)
+{
+ int back = 0;
+ dk3_c32_t myn[DK3_MAX_PATH]; /* My editable copy of n. */
+ dk3_c32_t *p1 = NULL; /* Current name part. */
+ dk3_c32_t *p2 = NULL; /* Remaining text. */
+ dk3_c32_t *p3 = NULL; /* Used to delete one part from path. */
+ size_t tsz; /* Test size. */
+
+ $? "+ dk3str_c32_append_path_app \"%ls\" \"%ls\"", d, n
+ if((d) && (sz) && (n)) {
+ if(dk3str_c32_is_abs_path(n)) { $? ". abs"
+ if(dk3str_c32_len(n) < sz) {
+ dk3str_c32_cpy(d,n) ;
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Name n too long! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 109);
+ }
+ }
+ } else { $? ". rel"
+ if(dk3str_c32_len(n) < DK3_SIZEOF(myn,dk3_c32_t)) {
+ back = 1;
+ dk3str_c32_cpy(myn,n) ;
+ p1 = myn;
+ while((p1) && (back)) {
+ p2 = dk3str_c32_chr(p1,FNS_C32);
+ if(p2) { *(p2++) = 0UL; }
+ if(dk3str_c32_cmp(c32_dot,p1)) {
+ if(dk3str_c32_cmp(c32_dot_dot,p1)) {
+ tsz = dk3str_c32_len(d) + dk3str_c32_len(c32_fnsep)
+ + dk3str_c32_len(p1);
+ if(tsz < sz) {
+ dk3str_c32_cat(d,c32_fnsep);
+ dk3str_c32_cat(d,p1);
+ } else {
+ if(app) {
+ /* ERROR: Result too long for destination buffer! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ } else {
+ p3 = dk3str_c32_rchr(d,FNS_C32);
+ if(p3) {
+ *p3 = 0UL;
+ } else {
+ if(app) {
+ /* ERROR: Too many ".." entries! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 110);
+ }
+ }
+ }
+ }
+ p1 = p2;
+ }
+ } else {
+ if(app) {
+ /* ERROR: Name n too long! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 109);
+ }
+ }
+ }
+ }
+ if(back) { $? ". result \"%ls\"", d
+ } $? "- dk3str_c32_append_path_app %d", back
+ return back;
+}
+
+
+
+int
+dk3str_append_path_app(dkChar *d, size_t sz, dkChar const *n, dk3_app_t *app)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_append_path_app(d, sz, n, app));
+#else
+ return(dk3str_c16_append_path_app(d, sz, n, app));
+#endif
+#else
+ return(dk3str_c8_append_path_app(d, sz, n, app));
+#endif
+}
+
+
+
+char *
+dk3str_c8_get_suffix(char const *s)
+{
+ char *back = NULL;
+ char const *ptr;
+ if(s) {
+ ptr = s;
+ while(*ptr) {
+ if(*ptr == '.') {
+ back = (char *)ptr;
+ } else {
+ if(*ptr == FNS_C8) {
+ back = NULL;
+ }
+ }
+ ptr++;
+ }
+ }
+ return back;
+}
+
+
+
+dk3_c16_t *
+dk3str_c16_get_suffix(dk3_c16_t const *s)
+{
+ dk3_c16_t *back = NULL;
+ dk3_c16_t const *ptr;
+
+ if(s) {
+ ptr = s;
+ while(*ptr) {
+ if(*ptr == 0x002EU) {
+ back = (dk3_c16_t *)ptr;
+ } else {
+ if(*ptr == FNS_C16) {
+ back = NULL;
+ }
+ }
+ ptr++;
+ }
+ }
+ return back;
+}
+
+
+
+dk3_c32_t *
+dk3str_c32_get_suffix(dk3_c32_t const *s)
+{
+ dk3_c32_t *back = NULL;
+ dk3_c32_t const *ptr;
+ if(s) {
+ ptr = s;
+ while(*ptr) {
+ if(*ptr == 0x0000002EUL) {
+ back = (dk3_c32_t *)ptr;
+ } else {
+ if(*ptr == FNS_C32) {
+ back = NULL;
+ }
+ }
+ ptr++;
+ }
+ }
+ return back;
+}
+
+
+
+dkChar *
+dk3str_get_suffix(dkChar const *s)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ return(dk3str_c32_get_suffix(s));
+#else
+ return(dk3str_c16_get_suffix(s));
+#endif
+#else
+ return(dk3str_c8_get_suffix(s));
+#endif
+}
+
+
+
+int
+dk3str_c32_to_c8_simple_app(char *d, size_t sz, dk3_c32_t const *s, dk3_app_t *app)
+{
+ int back = 0;
+ dk3_c32_t const *ptr = NULL; /* Pointer into source string. */
+ dk3_c32_t c = 0UL; /* Source character. */
+ unsigned char uc = 0x00; /* Destination character. */
+ char *dptr = NULL; /* Destination pointer. */
+
+ if((d) && (sz) && (s)) {
+ if(dk3str_c32_len(s) < sz) {
+ back = 1; ptr = s; dptr = d;
+ while(0UL != (c = *ptr)) {
+ if(c < (dk3_c32_t)0x00000100UL) {
+ uc = (unsigned char)c;
+ *(dptr++) = (char)uc;
+ } else {
+ if((back == 1) && (app)) {
+ /* ERROR: Illegal character(s) in source string! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 112);
+ }
+ back = 0;
+ }
+ ptr++;
+ }
+ *dptr = '\0';
+ } else {
+ d[0] = '\0';
+ if(app) {
+ /* ERROR: Source string too long! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 108);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+
+
+
+
+/** Convert 8-bit plain text to other encodings.
+ @param d Destination buffer (NULL to just count result elements).
+ @param s Source string.
+ @param app Application structure for diagnostics, may be NULL.
+ @param enc Destination encoding (DK3_ENCODING_xxx).
+ @return Number of destination elements created.
+*/
+static
+size_t
+dk3str_i_cnv_c8p(void *d, char const *s, dk3_app_t *app, int enc)
+{
+ size_t back = 0;
+ int error = 0; /* Flag: Error occured. */
+ char const *sptr = NULL; /* Source pointer. */
+ char *dp8 = NULL; /* Pointer to 8-bit destination. */
+ dk3_c16_t *dp16 = NULL; /* Pointer to 16-bit destination. */
+ dk3_c32_t *dp32 = NULL; /* Pointer to 32-bit destination. */
+ char c = 0x00; /* Current source character to process. */
+ unsigned char uc = 0x00; /* Destination byte. */
+ dk3_c32_t ul = 0UL; /* Conversion result. */
+ unsigned char myuc[16]; /* Conversion result buffer. */
+ dk3_c16_t myc16[16]; /* Conversion result buffer. */
+ size_t u8u = 0; /* UTF-8 bytes used for encoding. */
+ size_t u16u = 0; /* UTF-16 characters used for encoding. */
+ size_t sl = 0; /* Number of remaining characters in source. */
+ size_t i = 0; /* Copy converted characters to destination. */
+ $? "+ dk3str_i_cnv_c8p"
+ if(s) {
+ sptr = s; sl = dk3str_c8_len(s);
+ if(d) {
+ switch(enc) {
+ case DK3_ENCODING_UTF8: { dp8 = (char *)d; } break;
+ case DK3_ENCODING_UTF16: { dp16 = (dk3_c16_t *)d; } break;
+ case DK3_ENCODING_UNICODE: { dp32 = (dk3_c32_t *)d; } break;
+ default: {
+ if(app) {
+ /* ERROR: Illegal destination encoding! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 114);
+ }
+ } break;
+ }
+ }
+ while((sl) && (0 == error)) {
+ c = *(sptr++); sl--;
+ uc = (unsigned char)c;
+ ul = (dk3_c32_t)uc;
+ ul &= 0x000000FFUL;
+ switch(enc) {
+ case DK3_ENCODING_UTF8: {
+ u8u = dk3enc_uc2utf8(ul, myuc, 16);
+ if(u8u) {
+ back = dk3mem_add_size_t(back, u8u, &error);
+ if(d) {
+ for(i = 0; i < u8u; i++) { *(dp8++) = myuc[i]; }
+ }
+ } else {
+ if(0 == error) {
+ if(app) {
+ /* ERROR: Conversion to UTF-8 failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 115);
+ }
+ } error = 1;
+ }
+ } break;
+ case DK3_ENCODING_UTF16: {
+ u16u = dk3enc_uc2utf16(ul, myc16, 16);
+ if(u16u) {
+ back = dk3mem_add_size_t(back, u16u, &error);
+ if(d) {
+ for(i = 0; i < u16u; i++) { *(dp16++) = myc16[i]; }
+ }
+ } else {
+ if(0 == error) {
+ if(app) { $? "! conversion to UTF-16"
+ /* ERROR: Conversion to UTF-16 failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 116);
+ }
+ } error = 1;
+ }
+ } break;
+ case DK3_ENCODING_UNICODE: {
+ back = dk3mem_add_size_t(back, 1, &error);
+ if(d) { *(dp32++) = ul; }
+ } break;
+ }
+ }
+ if(d) {
+ switch(enc) {
+ case DK3_ENCODING_UTF8: { *dp8 = '\0'; } break;
+ case DK3_ENCODING_UTF16: { *dp16 = 0U; } break;
+ case DK3_ENCODING_UNICODE: { *dp32 = 0UL; } break;
+ }
+ }
+ back = dk3mem_add_size_t(back, 1, &error);
+ if(error) {
+ back = 0;
+ if(error == DK3_ERROR_MATH_OVERFLOW) {
+ if(app) {
+ /* ERROR: Input string too long for conversion! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 108);
+ }
+ }
+ }
+ } $? "- dk3str_i_cnv_c8p %u", (unsigned)back
+ return back;
+}
+
+
+
+
+size_t
+dk3str_cnvsz_c8p_to_c8u_app(char const *s, dk3_app_t *app)
+{
+ size_t back = 0;
+ if(s) {
+ back = dk3str_i_cnv_c8p(NULL, s, app, DK3_ENCODING_UTF8);
+ }
+ return back;
+}
+
+
+int
+dk3str_cnv_c8p_to_c8u_app(char *d, size_t ds, char const *s, dk3_app_t *app)
+{
+ int back = 0;
+ size_t sz; /* Number of chars produced. */
+ if((d) && (ds) && (s)) {
+ sz = dk3str_i_cnv_c8p(NULL, s, app, DK3_ENCODING_UTF8);
+ if(sz) {
+ if(ds >= sz) {
+ if(dk3str_i_cnv_c8p((void *)d, s, app, DK3_ENCODING_UTF8)) {
+ back = 1;
+ }
+ } else {
+ if(app) {
+ /* ERROR: Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+char *
+dk3str_cnvnew_c8p_to_c8u_app(char const *s, dk3_app_t *app)
+{
+ char *back = NULL;
+ size_t sz; /* Number of characters produced. */
+ if(s) {
+ sz = dk3str_i_cnv_c8p(NULL, s, app, DK3_ENCODING_UTF8);
+ if(sz) {
+ back = dk3_new_app(char,sz,app);
+ if(back) {
+ if(!dk3str_i_cnv_c8p((void *)back, s, app, DK3_ENCODING_UTF8)) {
+ dk3_delete(back); back = NULL;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+size_t
+dk3str_cnvsz_c8p_to_c16_app(char const *s, dk3_app_t *app)
+{
+ size_t back = 0;
+ if(s) {
+ back = dk3str_i_cnv_c8p(NULL, s, app, DK3_ENCODING_UTF16);
+ }
+ return back;
+}
+
+
+
+int
+dk3str_cnv_c8p_to_c16_app(dk3_c16_t *d, size_t ds, char const *s, dk3_app_t *app)
+{
+ int back = 0;
+ size_t sz; /* Destination buffer length needed. */
+ if((d) && (ds) && (s)) {
+ sz = dk3str_i_cnv_c8p(NULL, s, app, DK3_ENCODING_UTF16);
+ if(sz) {
+ if(ds >= sz) {
+ if(dk3str_i_cnv_c8p((void *)d, s, app, DK3_ENCODING_UTF16)) {
+ back = 1;
+ }
+ } else {
+ if(app) {
+ /* ERROR: Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+dk3_c16_t *
+dk3str_cnvnew_c8p_to_c16_app(char const *s, dk3_app_t *app)
+{
+ dk3_c16_t *back = NULL;
+ size_t sz; /* Destination buffer length needed. */
+ if(s) {
+ sz = dk3str_i_cnv_c8p(NULL, s, app, DK3_ENCODING_UTF16);
+ if(sz) {
+ back = dk3_new_app(dk3_c16_t,sz,app);
+ if(back) {
+ if(!dk3str_i_cnv_c8p((void *)back, s, app, DK3_ENCODING_UTF16)) {
+ dk3_delete(back); back = NULL;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+size_t
+dk3str_cnvsz_c8p_to_c32_app(char const *s, dk3_app_t *app)
+{
+ size_t back = 0;
+ if(s) {
+ back = dk3str_i_cnv_c8p(NULL, s, app, DK3_ENCODING_UNICODE);
+ }
+ return back;
+}
+
+
+
+int
+dk3str_cnv_c8p_to_c32_app(dk3_c32_t *d, size_t ds, char const *s, dk3_app_t *app)
+{
+ int back = 0;
+ size_t sz; /* Destination buffer length needed. */
+ if((d) && (ds) && (s)) {
+ sz = dk3str_i_cnv_c8p(NULL, s, app, DK3_ENCODING_UNICODE);
+ if(sz) {
+ if(ds >= sz) {
+ if(dk3str_i_cnv_c8p((void *)d, s, app, DK3_ENCODING_UNICODE)) {
+ back = 1;
+ }
+ } else {
+ if(app) {
+ /* ERROR: Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+dk3_c32_t *
+dk3str_cnvnew_c8p_to_c32_app(char const *s, dk3_app_t *app)
+{
+ dk3_c32_t *back = NULL;
+ size_t sz; /* Destination buffer length needed. */
+ if(s) {
+ sz = dk3str_i_cnv_c8p(NULL, s, app, DK3_ENCODING_UNICODE);
+ if(sz) {
+ back = dk3_new_app(dk3_c32_t,sz,app);
+ if(back) {
+ if(!dk3str_i_cnv_c8p((void *)back, s, app, DK3_ENCODING_UNICODE)) {
+ dk3_delete(back); back = NULL;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Convert UTF-8 string to other encodings.
+ @param d Destination pointer, may be NULL.
+ @param s Source string.
+ @param app Application structure for diagnostics, may be NULL.
+ @param enc Destination encoding.
+ @return Buffer length used (d!=NULL) or needed (d==NULL).
+*/
+static
+size_t
+dk3str_i_cnv_c8u(void *d, char const *s, dk3_app_t *app, int enc)
+{
+ size_t back = 0;
+ int error = 0; /* Flag: Error occued. */
+ char *dp8 = NULL; /* Pointer to 8-bit destination. */
+ dk3_c16_t *dp16 = NULL; /* Pointer to 16-bit destination. */
+ dk3_c32_t *dp32 = NULL; /* Pointer to 32-bit destination. */
+ dk3_c16_t myc16[16]; /* Conversion result buffer. */
+ dk3_c32_t c32 = 0UL; /* Conversion result. */
+ unsigned char uc = 0x00; /* Result character. */
+ char c = 0x00; /* Current character to process. */
+ unsigned char const *sptr = NULL; /* Source ponter. */
+ size_t u8u = 0; /* Number of UTF-8 bytes used. */
+ size_t u16u = 0; /* Number of UTF-16 chars produced. */
+ size_t i = 0; /* Copy buffer to destination. */
+ size_t sl = 0; /* Remaining source string length. */
+ $? "+ dk3str_i_cnv_c8u \"%!8s\"", TR_8STR(s)
+ if(s) {
+ /* Initialize variables */
+ sptr = (unsigned char const *)s; sl = dk3str_c8_len(s);
+ if(d) {
+ switch(enc) {
+ case DK3_ENCODING_PLAIN: { dp8 = (char *)d; } break;
+ case DK3_ENCODING_UTF16: { dp16 = (dk3_c16_t *)d; } break;
+ case DK3_ENCODING_UNICODE: { dp32 = (dk3_c32_t *)d; } break;
+ default: {
+ if(0 == error) {
+ if(app) {
+ /* ERROR: Illegal output encoding! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 114);
+ }
+ } error = 1;
+ } break;
+ }
+ }
+ /* Process input */
+ while((sl) && (0 == error)) {
+ u8u = 0;
+ if(dk3enc_utf82uc(&c32, sptr, sl, &u8u)) {
+ if(u8u) {
+ switch(enc) {
+ case DK3_ENCODING_PLAIN: {
+ if(c32 < (dk3_c32_t)0x00000100UL) {
+ back = dk3mem_add_size_t(back, 1, &error);
+ if(d) {
+ uc = (unsigned char)c32;
+ c = (char)uc;
+ *(dp8++) = c;
+ }
+ } else {
+ if(0 == error) {
+ if(app) {
+ /* ERROR: Result character out of range! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 117);
+ }
+ } error = 1;
+ }
+ } break;
+ case DK3_ENCODING_UTF16: {
+ u16u = dk3enc_uc2utf16(c32, myc16, 16);
+ if(u16u) {
+ back = dk3mem_add_size_t(back, u16u, &error);
+ if(d) {
+ for(i = 0; i < u16u; i++) { *(dp16++) = myc16[i]; }
+ }
+ } else {
+ if(0 == error) {
+ if(app) { $? "! conversion to UTF-16"
+ /* ERROR: Conversion to UTF-16 failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 116);
+ }
+ } error = 1;
+ }
+ } break;
+ case DK3_ENCODING_UNICODE: {
+ back = dk3mem_add_size_t(back, 1, &error);
+ if(d) { *(dp32++) = c32; }
+ } break;
+ }
+ if(sl >= u8u) {
+ sl = sl - u8u;
+ sptr = &(sptr[u8u]);
+ } else {
+ sl = 0;
+ }
+ } else {
+ if(0 == error) {
+ if(app) {
+ /* ERROR: UTF-8 decode operation failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 118);
+ }
+ } error = 1;
+ }
+ } else {
+ if(0 == error) {
+ if(app) {
+ /* ERROR: UTF-8 decode operation failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 118);
+ }
+ } error = 1;
+ }
+ }
+ /* Finalize output */
+ back = dk3mem_add_size_t(back, 1, &error);
+ if(d) {
+ switch(enc) {
+ case DK3_ENCODING_PLAIN: { *dp8 = '\0'; } break;
+ case DK3_ENCODING_UTF16: { *dp16 = 0U; } break;
+ case DK3_ENCODING_UNICODE: { *dp32 = 0UL; } break;
+ }
+ }
+ if(error) {
+ back = 0;
+ if(error == DK3_ERROR_MATH_OVERFLOW) {
+ if(app) {
+ /* ERROR: Input string too long for conversion! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 108);
+ }
+ }
+ }
+ } $? "- dk3str_i_cnv_c8u %u", (unsigned)back
+ return back;
+}
+
+
+
+size_t
+dk3str_cnvsz_c8u_to_c8p_app(char const *s, dk3_app_t *app)
+{
+ size_t back = 0;
+ if(s) {
+ back = dk3str_i_cnv_c8u(NULL, s, app, DK3_ENCODING_PLAIN);
+ }
+ return back;
+}
+
+
+
+int
+dk3str_cnv_c8u_to_c8p_app(char *d, size_t ds, char const *s, dk3_app_t *app)
+{
+ int back = 0;
+ size_t sz; /* Destination buffer length needed. */
+ if((d) && (ds) && (s)) {
+ sz = dk3str_i_cnv_c8u(NULL, s, app, DK3_ENCODING_PLAIN);
+ if(sz) {
+ if(ds >= sz) {
+ if(dk3str_i_cnv_c8u((void *)d, s, app, DK3_ENCODING_PLAIN)) {
+ back = 1;
+ }
+ } else {
+ if(app) {
+ /* ERROR: Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+char *
+dk3str_cnvnew_c8u_to_c8p_app(char const *s, dk3_app_t *app)
+{
+ char *back = NULL;
+ size_t sz; /* Destination buffer length needed. */
+ if(s) {
+ sz = dk3str_i_cnv_c8u(NULL, s, app, DK3_ENCODING_PLAIN);
+ if(sz) {
+ back = dk3_new_app(char,sz,app);
+ if(back) {
+ if(!dk3str_i_cnv_c8u((void *)back, s, app, DK3_ENCODING_PLAIN)) {
+ dk3_delete(back); back = NULL;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+
+size_t
+dk3str_cnvsz_c8u_to_c16_app(char const *s, dk3_app_t *app)
+{
+ size_t back = 0;
+ if(s) {
+ back = dk3str_i_cnv_c8u(NULL, s, app, DK3_ENCODING_UTF16);
+ }
+ return back;
+}
+
+
+
+int
+dk3str_cnv_c8u_to_c16_app(dk3_c16_t *d, size_t ds, char const *s, dk3_app_t *app)
+{
+ int back = 0;
+ size_t sz; /* Destination buffer length needed. */
+ if((d) && (ds) && (s)) {
+ sz = dk3str_i_cnv_c8u(NULL, s, app, DK3_ENCODING_UTF16);
+ if(sz) {
+ if(ds >= sz) {
+ if(dk3str_i_cnv_c8u((void *)d, s, app, DK3_ENCODING_UTF16)) {
+ back = 1;
+ }
+ } else {
+ if(app) {
+ /* ERROR: Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+dk3_c16_t *
+dk3str_cnvnew_c8u_to_c16_app(char const *s, dk3_app_t *app)
+{
+ dk3_c16_t *back = NULL;
+ size_t sz; /* Destination buffer length needed. */
+ if(s) {
+ sz = dk3str_i_cnv_c8u(NULL, s, app, DK3_ENCODING_UTF16);
+ if(sz) {
+ back = dk3_new_app(dk3_c16_t,sz,app);
+ if(back) {
+ if(!dk3str_i_cnv_c8u((void *)back, s, app, DK3_ENCODING_UTF16)) {
+ dk3_delete(back); back = NULL;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+size_t
+dk3str_cnvsz_c8u_to_c32_app(char const *s, dk3_app_t *app)
+{
+ size_t back = 0;
+ $? "+ dk3str_cnvsz_c8u_to_c32_app \"%!8s\"", TR_8STR(s)
+ if(s) {
+ back = dk3str_i_cnv_c8u(NULL, s, app, DK3_ENCODING_UNICODE);
+ } $? "- dk3str_cnvsz_c8u_to_c32_app %u", (unsigned)back
+ return back;
+}
+
+
+
+int
+dk3str_cnv_c8u_to_c32_app(dk3_c32_t *d, size_t ds, char const *s, dk3_app_t *app)
+{
+ int back = 0;
+ size_t sz; /* Destination buffer length needed. */
+ if((d) && (ds) && (s)) {
+ sz = dk3str_i_cnv_c8u(NULL, s, app, DK3_ENCODING_UNICODE);
+ if(sz) {
+ if(ds >= sz) {
+ if(dk3str_i_cnv_c8u((void *)d, s, app, DK3_ENCODING_UNICODE)) {
+ back = 1;
+ }
+ } else {
+ if(app) {
+ /* ERROR: Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+dk3_c32_t *
+dk3str_cnvnew_c8u_to_c32_app(char const *s, dk3_app_t *app)
+{
+ dk3_c32_t *back = NULL;
+ size_t sz; /* Destination buffer length needed. */
+ if(s) {
+ sz = dk3str_i_cnv_c8u(NULL, s, app, DK3_ENCODING_UNICODE);
+ if(sz) {
+ back = dk3_new_app(dk3_c32_t,sz,app);
+ if(back) {
+ if(!dk3str_i_cnv_c8u((void *)back, s, app, DK3_ENCODING_UNICODE)) {
+ dk3_delete(back); back = NULL;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Convert 16-bit character string to other encodings.
+ @param d Destination pointer (NULL for size check).
+ @param s Source string.
+ @param app Application structure for diagnostics.
+ @param enc Destination encoding.
+ @return Number of destination characters needed/produced.
+*/
+static
+size_t
+dk3str_i_cnv_c16(void *d, dk3_c16_t const *s, dk3_app_t *app, int enc)
+{
+ size_t back = 0;
+ int error = 0; /* Flag: Error occured. */
+ char *dp8 = NULL; /* Pointer to 8-bit destination. */
+ dk3_c32_t *dp32 = NULL; /* Pointer to 32-bit destination. */
+ dk3_c16_t const *sptr = NULL; /* Source pointer. */
+ dk3_c32_t c32 = 0UL; /* Conversion result. */
+ unsigned char uc = 0x00; /* Current output character. */
+ char c = 0x00; /* Current output character. */
+ unsigned char myuc[16]; /* Conversion result buffer. */
+ size_t sl = 0; /* Remaining string length. */
+ size_t u16u = 0; /* Number of U16 characters used. */
+ size_t u8u = 0; /* Number of 8-bit chars produced. */
+ size_t i = 0; /* Copy buffer to destination. */
+ if(s) {
+ /* Initialize variables */
+ sptr = s; sl = dk3str_c16_len(s);
+ if(d) {
+ switch(enc) {
+ case DK3_ENCODING_PLAIN: { dp8 = (char *)d; } break;
+ case DK3_ENCODING_UTF8: { dp8 = (char *)d; } break;
+ case DK3_ENCODING_UNICODE: { dp32 = (dk3_c32_t *)d; } break;
+ default: {
+ if(0 == error) {
+ if(app) {
+ /* ERROR: Illegal output encoding! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 114);
+ }
+ } error = 1;
+ } break;
+ }
+ }
+ /* Process input */
+ while((sl) && (0 == error)) {
+ u16u = 0;
+ if(dk3enc_utf162uc(&c32, sptr, sl, &u16u)) {
+ if(u16u) {
+ if(sl >= u16u) {
+ switch(enc) {
+ case DK3_ENCODING_PLAIN: {
+ if(c32 < (dk3_c32_t)0x00000100UL) {
+ back = dk3mem_add_size_t(back, 1, &error);
+ if(d) {
+ uc = (unsigned char)c32; c = (char)uc;
+ *(dp8++) = c;
+ }
+ } else {
+ if(0 == error) {
+ if(app) {
+ /* ERROR: Result character out of range! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 117);
+ }
+ } error = 1;
+ }
+ } break;
+ case DK3_ENCODING_UTF8: {
+ u8u = dk3enc_uc2utf8(c32, myuc, 16);
+ if(u8u) {
+ back = dk3mem_add_size_t(back, u8u, &error);
+ if(d) {
+ for(i = 0; i < u8u; i++) { *(dp8++) = myuc[i]; }
+ }
+ } else {
+ if(0 == error) {
+ if(app) {
+ /* ERROR: Conversion to UTF-8 failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 115);
+ }
+ } error = 1;
+ }
+ } break;
+ case DK3_ENCODING_UNICODE: {
+ back = dk3mem_add_size_t(back, 1, &error);
+ if(d) { *(dp32++) = c32; }
+ } break;
+ }
+ sl = sl - u16u;
+ sptr = &(sptr[u16u]);
+ } else {
+ sl = 0;
+ }
+ } else {
+ if(0 == error) {
+ if(app) {
+ /* ERROR: UTF-16 decode operation failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 119);
+ }
+ } error = 1;
+ }
+ } else {
+ if(0 == error) {
+ if(app) {
+ /* ERROR: UTF-16 decode operation failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 119);
+ }
+ } error = 1;
+ }
+ }
+ /* Finalize output */
+ back = dk3mem_add_size_t(back, 1, &error);
+ if(d) {
+ switch(enc) {
+ case DK3_ENCODING_PLAIN: { *dp8 = '\0'; } break;
+ case DK3_ENCODING_UTF8: { *dp8 = '\0'; } break;
+ case DK3_ENCODING_UNICODE: { *dp32 = 0UL; } break;
+ }
+ }
+ if(error) {
+ back = 0;
+ if(error == DK3_ERROR_MATH_OVERFLOW) {
+ if(app) {
+ /* ERROR: Input string too long for conversion! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 108);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+size_t
+dk3str_cnvsz_c16_to_c8p_app(dk3_c16_t const *s, dk3_app_t *app)
+{
+ size_t back = 0;
+ if(s) {
+ back = dk3str_i_cnv_c16(NULL, s, app, DK3_ENCODING_PLAIN);
+ }
+ return back;
+}
+
+
+
+int
+dk3str_cnv_c16_to_c8p_app(char *d, size_t ds, dk3_c16_t const *s, dk3_app_t *app)
+{
+ int back = 0;
+ size_t sz; /* Destination buffer size needed. */
+ if((d) && (ds) && (s)) {
+ sz = dk3str_i_cnv_c16(NULL, s, app, DK3_ENCODING_PLAIN);
+ if(sz) {
+ if(ds >= sz) {
+ if(dk3str_i_cnv_c16((void *)d, s, app, DK3_ENCODING_PLAIN)) {
+ back = 1;
+ }
+ } else {
+ if(app) {
+ /* ERROR: Result buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+char *
+dk3str_cnvnew_c16_to_c8p_app(dk3_c16_t const *s, dk3_app_t *app)
+{
+ char *back = NULL;
+ size_t sz; /* Destination buffer size needed. */
+ if(s) {
+ sz = dk3str_i_cnv_c16(NULL, s, app, DK3_ENCODING_PLAIN);
+ if(sz) {
+ back = dk3_new_app(char,sz,app);
+ if(back) {
+ if(!dk3str_i_cnv_c16((void *)back, s, app, DK3_ENCODING_PLAIN)) {
+ dk3_delete(back); back = NULL;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+size_t
+dk3str_cnvsz_c16_to_c8u_app(dk3_c16_t const *s, dk3_app_t *app)
+{
+ size_t back = 0;
+ if(s) {
+ back = dk3str_i_cnv_c16(NULL, s, app, DK3_ENCODING_UTF8);
+ }
+ return back;
+}
+
+
+
+int
+dk3str_cnv_c16_to_c8u_app(char *d, size_t ds, dk3_c16_t const *s, dk3_app_t *app)
+{
+ int back = 0;
+ size_t sz; /* Destination buffer size needed. */
+ if((d) && (ds) && (s)) {
+ sz = dk3str_i_cnv_c16(NULL, s, app, DK3_ENCODING_UTF8);
+ if(sz) {
+ if(ds >= sz) {
+ if(dk3str_i_cnv_c16((void *)d, s, app, DK3_ENCODING_UTF8)) {
+ back = 1;
+ }
+ } else {
+ if(app) {
+ /* ERROR: Result buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+char *
+dk3str_cnvnew_c16_to_c8u_app(dk3_c16_t const *s, dk3_app_t *app)
+{
+ char *back = NULL;
+ size_t sz; /* Destination buffer size needed. */
+ if(s) {
+ sz = dk3str_i_cnv_c16(NULL, s, app, DK3_ENCODING_UTF8);
+ if(sz) {
+ back = dk3_new_app(char,sz,app);
+ if(back) {
+ if(!dk3str_i_cnv_c16((void *)back, s, app, DK3_ENCODING_UTF8)) {
+ dk3_delete(back); back = NULL;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3str_c16_to_c8_simple_app(
+ char *d, size_t sz, dk3_c16_t const *s, dk3_app_t *app
+)
+{
+ int back = 0;
+ dk3_c16_t const *ptr; /* Source pointer. */
+ dk3_c16_t c; /* Source character. */
+ unsigned char uc; /* Destination character. */
+ char *dptr; /* Destination pointer. */
+
+ if((d) && (sz) && (s)) {
+ if(dk3str_c16_len(s) < sz) {
+ back = 1; ptr = s; dptr = d;
+ while(0U != (c = *ptr)) {
+ if(c < 0x0100U) {
+ uc = (unsigned char)c;
+ *(dptr++) = (char)uc;
+ } else {
+ if((back == 1) && (app)) {
+ /* ERROR: Illegal character(s) in source string! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 112);
+ }
+ back = 0;
+ }
+ ptr++;
+ }
+ *dptr = '\0';
+ } else {
+ d[0] = '\0';
+ if(app) {
+ /* ERROR: Source string too long! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 108);
+ }
+ }
+ }
+ return back;
+}
+
+
+size_t
+dk3str_cnvsz_c16_to_c32_app(dk3_c16_t const *s, dk3_app_t *app)
+{
+ size_t back = 0;
+ if(s) {
+ back = dk3str_i_cnv_c16(NULL, s, app, DK3_ENCODING_UNICODE);
+ }
+ return back;
+}
+
+
+
+int
+dk3str_cnv_c16_to_c32_app(dk3_c32_t *d, size_t ds, dk3_c16_t const *s, dk3_app_t *app)
+{
+ int back = 0;
+ size_t sz; /* Destination buffer size needed. */
+ if((d) && (ds) && (s)) {
+ sz = dk3str_i_cnv_c16(NULL, s, app, DK3_ENCODING_UNICODE);
+ if(sz) {
+ if(ds >= sz) {
+ if(dk3str_i_cnv_c16((void *)d, s, app, DK3_ENCODING_UNICODE)) {
+ back = 1;
+ }
+ } else {
+ if(app) {
+ /* ERROR: Result buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+dk3_c32_t *
+dk3str_cnvnew_c16_to_c32_app(dk3_c16_t const *s, dk3_app_t *app)
+{
+ dk3_c32_t *back = NULL;
+ size_t sz; /* Destination buffer size needed. */
+ if(s) {
+ sz = dk3str_i_cnv_c16(NULL, s, app, DK3_ENCODING_UNICODE);
+ if(sz) {
+ back = dk3_new_app(dk3_c32_t,sz,app);
+ if(back) {
+ if(!dk3str_i_cnv_c16((void *)back, s, app, DK3_ENCODING_UNICODE)) {
+ dk3_delete(back); back = NULL;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Convert 32-bit character string to other encodings.
+ @param d Destination buffer pointer (may be NULL for size check).
+ @param s Source string.
+ @param app Application structure for diagnostics.
+ @param enc Output encoding.
+ @return Number of destination characters produced/needed.
+*/
+static
+size_t
+dk3str_i_cnv_c32(void *d, dk3_c32_t const *s, dk3_app_t *app, int enc)
+{
+ size_t back = 0;
+ int error = 0; /* Flag: Error occured. */
+ char *dp8 = NULL; /* Pointer to 8-bit destination. */
+ dk3_c16_t *dp16 = NULL; /* Pointer to 16-bit destination. */
+ dk3_c32_t const *sptr = NULL; /* Source pointer. */
+ dk3_c32_t c32 = 0UL; /* Current character to process. */
+ dk3_c16_t myc16[16]; /* Conversion result buffer. */
+ unsigned char myuc[16]; /* Conversion result buffer. */
+ unsigned char uc = 0x00; /* Output character. */
+ char c = 0x00; /* Output character. */
+ size_t sl = 0; /* Remaining string length. */
+ size_t u8u = 0; /* Number of UTF-8 chars produced. */
+ size_t u16u = 0; /* Numer of UTF-16 chars produced. */
+ size_t i = 0; /* Copy buffer to destination. */
+ $? "+ dk3str_i_cnv_c32"
+ if(s) {
+ /* Initialize variables */
+ sptr = s; sl = dk3str_c32_len(s);
+ if(d) {
+ switch(enc) {
+ case DK3_ENCODING_PLAIN: { dp8 = (char *)d; } break;
+ case DK3_ENCODING_UTF8: { dp8 = (char *)d; } break;
+ case DK3_ENCODING_UTF16: { dp16 = (dk3_c16_t *)d; } break;
+ default: {
+ if(0 == error) {
+ if(app) {
+ /* ERROR: Illegal output encoding! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 114);
+ }
+ } error = 1;
+ } break;
+ }
+ }
+ /* Process input */
+ while((sl) && (0 == error)) {
+ c32 = *(sptr++); sl--;
+ switch(enc) {
+ case DK3_ENCODING_PLAIN: {
+ if(c32 < (dk3_c32_t)0x00000100UL) {
+ back = dk3mem_add_size_t(back, 1, &error);
+ if(d) {
+ uc = (unsigned char)c32; c = (char)uc;
+ *(dp8++) = c;
+ }
+ } else {
+ if(0 == error) {
+ if(app) {
+ /* ERROR: Output character out of range! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 117);
+ }
+ } error = 1;
+ }
+ } break;
+ case DK3_ENCODING_UTF8: {
+ u8u = dk3enc_uc2utf8(c32, myuc, 16);
+ if(u8u) {
+ back = dk3mem_add_size_t(back, u8u, &error);
+ if(d) {
+ for(i = 0; i < u8u; i++) { *(dp8++) = myuc[i]; }
+ }
+ } else {
+ if(0 == error) {
+ if(app) {
+ /* ERROR: UTF-8 encoding failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 115);
+ }
+ } error = 1;
+ }
+ } break;
+ case DK3_ENCODING_UTF16: {
+ u16u = dk3enc_uc2utf16(c32, myc16, 16);
+ if(u16u) {
+ back = dk3mem_add_size_t(back, u16u, &error);
+ if(d) {
+ for(i = 0; i < u16u; i++) { *(dp16++) = myc16[i]; }
+ }
+ } else {
+ if(0 == error) {
+ if(app) { $? "! conversion to UTF-16"
+ /* ERROR: Conversion to UTF-16 failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 116);
+ }
+ } error = 1;
+ }
+ } break;
+ }
+ }
+ /* Finalize output */
+ back = dk3mem_add_size_t(back, 1, &error);
+ if(d) {
+ switch(enc) {
+ case DK3_ENCODING_PLAIN: { *dp8 = '\0'; } break;
+ case DK3_ENCODING_UTF8: { *dp8 = '\0'; } break;
+ case DK3_ENCODING_UTF16: { *dp16 = 0U; } break;
+ }
+ }
+ if(error) {
+ back = 0;
+ if(error == DK3_ERROR_MATH_OVERFLOW) {
+ if(app) {
+ /* ERROR: Input string too long for conversion! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 108);
+ }
+ }
+ }
+ } $? "- dk3str_i_cnv_c32 %u", (unsigned)back
+ return back;
+}
+
+
+
+size_t
+dk3str_cnvsz_c32_to_c8p_app(dk3_c32_t const *s, dk3_app_t *app)
+{
+ size_t back = 0;
+ if(s) {
+ back = dk3str_i_cnv_c32(NULL, s, app, DK3_ENCODING_PLAIN);
+ }
+ return back;
+}
+
+
+
+int
+dk3str_cnv_c32_to_c8p_app(char *d, size_t ds, dk3_c32_t const *s, dk3_app_t *app)
+{
+ int back = 0;
+ size_t sz; /* Destination buffer size needed. */
+ if((d) && (ds) && (s)) {
+ sz = dk3str_i_cnv_c32(NULL, s, app, DK3_ENCODING_PLAIN);
+ if(sz) {
+ if(ds >= sz) {
+ if(dk3str_i_cnv_c32((void *)d, s, app, DK3_ENCODING_PLAIN)) {
+ back = 1;
+ }
+ } else {
+ if(app) {
+ /* ERROR: Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+char *
+dk3str_cnvnew_c32_to_c8p_app(dk3_c32_t const *s, dk3_app_t *app)
+{
+ char *back = NULL;
+ size_t sz; /* Destination buffer size needed. */
+ if(s) {
+ sz = dk3str_i_cnv_c32(NULL, s, app, DK3_ENCODING_PLAIN);
+ if(sz) {
+ back = dk3_new_app(char,sz,app);
+ if(back) {
+ if(!dk3str_i_cnv_c32((void *)back, s, app, DK3_ENCODING_PLAIN)) {
+ dk3_delete(back); back = NULL;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+size_t
+dk3str_cnvsz_c32_to_c8u_app(dk3_c32_t const *s, dk3_app_t *app)
+{
+ size_t back = 0;
+ if(s) {
+ back = dk3str_i_cnv_c32(NULL, s, app, DK3_ENCODING_UTF8);
+ }
+ return back;
+}
+
+
+
+int
+dk3str_cnv_c32_to_c8u_app(char *d, size_t ds, dk3_c32_t const *s, dk3_app_t *app)
+{
+ int back = 0;
+ size_t sz; /* Destination buffer size needed. */
+ if((d) && (ds) && (s)) {
+ sz = dk3str_i_cnv_c32(NULL, s, app, DK3_ENCODING_UTF8);
+ if(sz) {
+ if(ds >= sz) {
+ if(dk3str_i_cnv_c32((void *)d, s, app, DK3_ENCODING_UTF8)) {
+ back = 1;
+ }
+ } else {
+ if(app) {
+ /* ERROR: Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+char *
+dk3str_cnvnew_c32_to_c8u_app(dk3_c32_t const *s, dk3_app_t *app)
+{
+ char *back = NULL;
+ size_t sz; /* Destination buffer size needed. */
+ if(s) {
+ sz = dk3str_i_cnv_c32(NULL, s, app, DK3_ENCODING_UTF8);
+ if(sz) {
+ back = dk3_new_app(char,sz,app);
+ if(back) {
+ if(!dk3str_i_cnv_c32((void *)back, s, app, DK3_ENCODING_UTF8)) {
+ dk3_delete(back); back = NULL;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+size_t
+dk3str_cnvsz_c32_to_c16_app(dk3_c32_t const *s, dk3_app_t *app)
+{
+ size_t back = 0;
+ if(s) {
+ back = dk3str_i_cnv_c32(NULL, s, app, DK3_ENCODING_UTF16);
+ }
+ return back;
+}
+
+
+
+int
+dk3str_cnv_c32_to_c16_app(dk3_c16_t *d, size_t ds, dk3_c32_t const *s, dk3_app_t *app)
+{
+ int back = 0;
+ size_t sz; /* Destination buffer size needed. */
+ if((d) && (ds) && (s)) {
+ sz = dk3str_i_cnv_c32(NULL, s, app, DK3_ENCODING_UTF16);
+ if(sz) {
+ if(ds >= sz) {
+ if(dk3str_i_cnv_c32((void *)d, s, app, DK3_ENCODING_UTF16)) {
+ back = 1;
+ }
+ } else {
+ if(app) {
+ /* ERROR: Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+dk3_c16_t *
+dk3str_cnvnew_c32_to_c16_app(dk3_c32_t const *s, dk3_app_t *app)
+{
+ dk3_c16_t *back = NULL;
+ size_t sz; /* Destination buffer size needed. */
+ if(s) {
+ sz = dk3str_i_cnv_c32(NULL, s, app, DK3_ENCODING_UTF16);
+ if(sz) {
+ back = dk3_new_app(dk3_c16_t,sz,app);
+ if(back) {
+ if(!dk3str_i_cnv_c32((void *)back, s, app, DK3_ENCODING_UTF16)) {
+ dk3_delete(back); back = NULL;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3str_cnv_c8_to_str_app(dkChar *d, size_t sz, char const *s, dk3_app_t *app)
+{
+ register int back = 0;
+ register size_t l; /* Number of destination chars used. */
+ register char const *sptr; /* Source pointer. */
+ register dkChar *dptr; /* Destination pointer. */
+ register char x = 0x00; /* Current character to process. */
+
+ if((d) && (sz) && (s)) {
+ sptr = s; dptr = d; l = 0; back = 1;
+ while((*sptr) && (l < (sz - 1))) {
+ x = *(sptr++);
+ *(dptr++) = (dkChar)x;
+ l++;
+ }
+ *dptr = (dkChar)'\0';
+ if(*sptr) {
+ back = 0;
+ if(app) {
+ /* ERROR: Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3str_string_to_c8_simple_app(char *db,size_t sz,dkChar const *s,dk3_app_t *ap)
+{
+ int back = 0;
+ register dkChar const *sptr; /* Source pointer. */
+ register dkChar x; /* Current source character. */
+ register char *dptr; /* Destination pointer. */
+
+ if((db) && (sz) && (s)) {
+ if(dk3str_len(s) < sz) {
+ back = 1;
+ sptr = s; dptr = db;
+ while(*sptr) {
+ x = *(sptr++);
+ *(dptr++) = (char)x;
+#if DK3_CHAR_SIZE > 1
+ if(x > (dkChar)0xFF) {
+ back = 0;
+ }
+#endif
+ }
+ *dptr = '\0';
+ if(!(back)) {
+ if(ap) {
+ /* ERROR: Non-ISO-LATIN-1 characters found! */
+ dk3app_log_i1(ap, DK3_LL_ERROR, 219);
+ }
+ }
+ } else {
+ if(ap) {
+ /* ERROR: Destination buffer too short! */
+ dk3app_log_i1(ap, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void
+dk3str_string_tolower(dkChar *s)
+{
+ dkChar *ptr; /* Pointer into string. */
+ if(s) {
+ ptr = s;
+ while(*ptr) {
+ *ptr = dk3str_tolower(*ptr);
+ ptr++;
+ }
+ }
+}
+
+
+
+int
+dk3str_c8_to_str_simple_app(
+ dkChar *dp, size_t ds, char const *sp, dk3_app_t *app
+)
+{
+ int back = 0;
+ char const *sptr; /* Pointer into source buffer. */
+ dkChar *dptr; /* Pointer into destination buffer. */
+ size_t sz; /* Required destination size. */
+ if((dp) && (ds) && (sp)) {
+ sz = dk3str_c8_len(sp);
+ if(ds > sz) {
+ back = 1; sptr = sp; dptr = dp;
+ while(*sptr) { *(dptr++) = (dkChar)(*(sptr++)); }
+ *dptr = dkT('\0');
+ } else {
+ if(app) {
+ /* ERROR: Destination buffer too short! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3str_to_c8p_app(
+ char *dp, size_t sz, dkChar const *src, int ie, dk3_app_t *app
+)
+{
+ int back = 0;
+ if((dp) && (sz) && (src)) {
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ back = dk3str_cnv_c32_to_c8p_app(dp, sz, src, app);
+#else
+ back = dk3str_cnv_c16_to_c8p_app(dp, sz, src, app);
+#endif
+#else
+ if(ie == DK3_ENCODING_PLAIN) {
+ if(sz > dk3str_c8_len(src)) {
+ dk3str_c8_cpy(dp, src);
+ back = 1;
+ }
+ } else {
+ back = dk3str_cnv_c8u_to_c8p_app(dp, sz, src, app);
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3str_to_c8u_app(
+ char *dp, size_t sz, dkChar const *src, int ie, dk3_app_t *app
+)
+{
+ int back = 0;
+ if((dp) && (sz) && (src)) {
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ back = dk3str_cnv_c32_to_c8u_app(dp, sz, src, app);
+#else
+ back = dk3str_cnv_c16_to_c8u_app(dp, sz, src, app);
+#endif
+#else
+ if(ie == DK3_ENCODING_PLAIN) {
+ back = dk3str_cnv_c8p_to_c8u_app(dp, sz, src, app);
+ } else {
+ if(sz > dk3str_c8_len(src)) {
+ dk3str_c8_cpy(dp, src);
+ back = 1;
+ }
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3str_str_to_c8u_app(
+ char *d,
+ size_t dsz,
+ dkChar const *s,
+ int se,
+ dk3_app_t *app
+)
+{
+ int back = 0;
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ back = dk3str_cnv_c32_to_c8u_app(d, dsz, s, app);
+#else
+ back = dk3str_cnv_c16_to_c8u_app(d, dsz, s, app);
+#endif
+#else
+ switch(se) {
+ case DK3_ENCODING_UTF8: {
+ if(dk3str_c8_len(s) < dsz) {
+ dk3str_c8_cpy(d, s);
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: String too long! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 108);
+ }
+ }
+ } break;
+ default: {
+ back = dk3str_cnv_c8p_to_c8u_app(d, dsz, s, app);
+ } break;
+ }
+#endif
+ return back;
+}
+
+
+
+int
+dk3str_c8u_to_str_app(
+ dkChar *d,
+ size_t dsz,
+ int de,
+ char const *s,
+ dk3_app_t *app
+)
+{
+ int back = 0;
+ $? "+ dk3str_c8u_to_str_app"
+ if((d) && (dsz) && (s)) {
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ $? ". 32-bit"
+ back = dk3str_cnv_c8u_to_c32_app(d, dsz, s, app);
+#else
+ $? ". 16-bit"
+ back = dk3str_cnv_c8u_to_c16_app(d, dsz, s, app);
+#endif
+#else
+ switch(de) {
+ case DK3_ENCODING_UTF8: {
+ $? ". UTF-8"
+ if(dsz > dk3str_c8_len(s)) {
+ dk3str_c8_cpy(d, s);
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Source string too long! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 108);
+ }
+ }
+ } break;
+ default: {
+ $? ". LATIN-1"
+ back = dk3str_cnv_c8u_to_c8p_app(d, dsz, s, app);
+ } break;
+ }
+#endif
+ } $? "- dk3str_c8u_to_str_app %d", back
+ return back;
+}
+
+
+
+int
+dk3str_to_c8_app(char *dp, size_t szdp, dkChar const *src, dk3_app_t *app)
+{
+ int back = 0;
+ $? "+ dk3str_to_c8_app"
+ if((dp) && (szdp) && (src)) {
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ back = dk3str_cnv_c32_to_c8p_app(dp, szdp, src, app);
+#else
+ back = dk3str_cnv_c16_to_c8p_app(dp, szdp, src, app);
+#endif
+#else
+ if(strlen(src) < szdp) {
+ strcpy(dp, src);
+ back = 1;
+ } else {
+ /* ERROR: Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+#endif
+ } $? "- dk3str_to_c8_app %d", back
+ return back;
+}
+
+
+
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dk3str.h b/support/dktools/dk3str.h
new file mode 100644
index 0000000000..163cb30738
--- /dev/null
+++ b/support/dktools/dk3str.h
@@ -0,0 +1,1463 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3str.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3str.h Header file for the dk3str module.
+*/
+
+#ifndef DK3STR_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3STR_H_INCLUDED 1
+
+
+#line 8 "dk3str.ctr"
+
+#include "dk3conf.h"
+#include "dk3types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Calculate string length.
+ * @param s String to process.
+ * @return String length (number of characters).
+ */
+size_t
+dk3str_c8_len(char const *s);
+
+/** Calculate string length.
+ * @param s String to process.
+ * @return String length (number of characters).
+ */
+size_t
+dk3str_c16_len(dk3_c16_t const *s);
+
+/** Calculate string length.
+ * @param s String to process.
+ * @return String length (number of characters).
+ */
+size_t
+dk3str_c32_len(dk3_c32_t const *s);
+
+/** Calculate string length.
+ * @param s String to process.
+ * @return String length (number of characters).
+ */
+size_t
+dk3str_len(dkChar const *s);
+
+/** Compare two strings.
+ * @param s1 Left side string.
+ * @param s2 Right side string.
+ * @return 1 for s1>s2, 0 for s1=s2, -1 for s1<s2.
+ */
+int
+dk3str_c8_cmp(char const *s1, char const *s2);
+
+/** Compare two strings.
+ * @param s1 Left side string.
+ * @param s2 Right side string.
+ * @return 1 for s1>s2, 0 for s1=s2, -1 for s1<s2.
+ */
+int
+dk3str_c16_cmp(dk3_c16_t const *s1, dk3_c16_t const *s2);
+
+/** Compare two strings.
+ * @param s1 Left side string.
+ * @param s2 Right side string.
+ * @return 1 for s1>s2, 0 for s1=s2, -1 for s1<s2.
+ */
+int
+dk3str_c32_cmp(dk3_c32_t const *s1, dk3_c32_t const *s2);
+
+/** Compare two strings.
+ * @param s1 Left side string.
+ * @param s2 Right side string.
+ * @return 1 for s1>s2, 0 for s1=s2, -1 for s1<s2.
+ */
+int
+dk3str_cmp(dkChar const *s1, dkChar const *s2);
+
+/** Case-insensitve string comparison.
+ * @param s1 Left side string.
+ * @param s2 Right side string.
+ * @return 1 for s1>s2, 0 for s1=s2, -1 for s1<s2.
+ */
+int
+dk3str_c8_casecmp(char const *s1, char const *s2);
+
+
+/** Case-insensitve string comparison.
+ * @param s1 Left side string.
+ * @param s2 Right side string.
+ * @return 1 for s1>s2, 0 for s1=s2, -1 for s1<s2.
+ */
+int
+dk3str_c16_casecmp(dk3_c16_t const *s1, dk3_c16_t const *s2);
+
+/** Case-insensitve string comparison.
+ * @param s1 Left side string.
+ * @param s2 Right side string.
+ * @return 1 for s1>s2, 0 for s1=s2, -1 for s1<s2.
+ */
+int
+dk3str_c32_casecmp(dk3_c32_t const *s1, dk3_c32_t const *s2);
+
+/** Case-insensitve string comparison.
+ * @param s1 Left side string.
+ * @param s2 Right side string.
+ * @return 1 for s1>s2, 0 for s1=s2, -1 for s1<s2.
+ */
+int
+dk3str_casecmp(dkChar const *s1, dkChar const *s2);
+
+/** File name comparison, case-sensitive on some systems,
+ * case-insensitive on other systems.
+ * @param s1 Left side string.
+ * @param s2 Right side string.
+ * @return 1 for s1>s2, 0 for s1=s2, -1 for s1<s2.
+ */
+int
+dk3str_fncmp(dkChar const *s1, dkChar const *s2) ;
+
+/** Compare two strings, use only the first \a n characters.
+ * @param s1 Left side string.
+ * @param s2 Right side string.
+ * @param n Number of characters to use in comparison.
+ * @return 1 for s1>s2, 0 for s1=s2, -1 for s1<s2.
+ */
+int
+dk3str_c8_ncmp(char const *s1, char const *s2, size_t n);
+
+/** Compare two strings, use only the first \a n characters.
+ * @param s1 Left side string.
+ * @param s2 Right side string.
+ * @param n Number of characters to use in comparison.
+ * @return 1 for s1>s2, 0 for s1=s2, -1 for s1<s2.
+ */
+int
+dk3str_c16_ncmp(dk3_c16_t const *s1, dk3_c16_t const *s2, size_t n);
+
+/** Compare two strings, use only the first \a n characters.
+ * @param s1 Left side string.
+ * @param s2 Right side string.
+ * @param n Number of characters to use in comparison.
+ * @return 1 for s1>s2, 0 for s1=s2, -1 for s1<s2.
+ */
+int
+dk3str_c32_ncmp(dk3_c32_t const *s1, dk3_c32_t const *s2, size_t n);
+
+/** Compare two strings, use only the first \a n characters.
+ * @param s1 Left side string.
+ * @param s2 Right side string.
+ * @param n Number of characters to use in comparison.
+ * @return 1 for s1>s2, 0 for s1=s2, -1 for s1<s2.
+ */
+int
+dk3str_ncmp(dkChar const *s1, dkChar const *s2, size_t n);
+
+/** Find left-most orrucance of character in string.
+ * @param s String probably containing the character.
+ * @param c Character to search for.
+ * @return Pointer to character position on success, NULL on error.
+ */
+char *
+dk3str_c8_chr(char const *s, char c);
+
+/** Find left-most orrucance of character in string.
+ * @param s String probably containing the character.
+ * @param c Character to search for.
+ * @return Pointer to character position on success, NULL on error.
+ */
+dk3_c16_t *
+dk3str_c16_chr(dk3_c16_t const *s, dk3_c16_t c);
+
+/** Find left-most orrucance of character in string.
+ * @param s String probably containing the character.
+ * @param c Character to search for.
+ * @return Pointer to character position on success, NULL on error.
+ */
+dk3_c32_t *
+dk3str_c32_chr(dk3_c32_t const *s, dk3_c32_t c);
+
+/** Find left-most orrucance of character in string.
+ * @param s String probably containing the character.
+ * @param c Character to search for.
+ * @return Pointer to character position on success, NULL on error.
+ */
+dkChar *
+dk3str_chr(dkChar const *s, dkChar c);
+
+/** Find right-most orrucance of character in string.
+ * @param s String probably containing the character.
+ * @param c Character to search for.
+ * @return Pointer to character position on success, NULL on error.
+ */
+char *
+dk3str_c8_rchr(char const *s, char c);
+
+/** Find right-most orrucance of character in string.
+ * @param s String probably containing the character.
+ * @param c Character to search for.
+ * @return Pointer to character position on success, NULL on error.
+ */
+dk3_c16_t *
+dk3str_c16_rchr(dk3_c16_t const *s, dk3_c16_t c);
+
+/** Find right-most orrucance of character in string.
+ * @param s String probably containing the character.
+ * @param c Character to search for.
+ * @return Pointer to character position on success, NULL on error.
+ */
+dk3_c32_t *
+dk3str_c32_rchr(dk3_c32_t const *s, dk3_c32_t c);
+
+/** Find right-most orrucance of character in string.
+ * @param s String probably containing the character.
+ * @param c Character to search for.
+ * @return Pointer to character position on success, NULL on error.
+ */
+dkChar *
+dk3str_rchr(dkChar const *s, dkChar c);
+
+/** Copy string.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ */
+void
+dk3str_c8_cpy(char *d, char const *s);
+
+/** Copy string.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ */
+void
+dk3str_c16_cpy(dk3_c16_t *d, dk3_c16_t const *s);
+
+/** Copy string.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ */
+void
+dk3str_c32_cpy(dk3_c32_t *d, dk3_c32_t const *s);
+
+/** Copy string.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ */
+void
+dk3str_cpy(dkChar *d, dkChar const *s);
+
+/** Copy string.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ */
+void
+dk3str_c8_cpy_not_overlapped(char *d, char const *s);
+
+/** Copy string.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ */
+void
+dk3str_c16_cpy_not_overlapped(dk3_c16_t *d, dk3_c16_t const *s);
+
+/** Copy string.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ */
+void
+dk3str_c32_cpy_not_overlapped(dk3_c32_t *d, dk3_c32_t const *s);
+
+/** Copy string.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ */
+void
+dk3str_cpy_not_overlapped(dkChar *d, dkChar const *s);
+
+/** Copy string, cut to buffer size if necessary.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ * @param n Size of \a d (number of characters).
+ */
+void
+dk3str_c8_ncpy(char *d, char const *s, size_t n);
+
+/** Copy string, cut to buffer size if necessary.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ * @param n Size of \a d (number of characters).
+ */
+void
+dk3str_c16_ncpy(dk3_c16_t *d, dk3_c16_t const *s, size_t n);
+
+/** Copy string, cut to buffer size if necessary.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ * @param n Size of \a d (number of characters).
+ */
+void
+dk3str_c32_ncpy(dk3_c32_t *d, dk3_c32_t const *s, size_t n);
+
+/** Copy string, cut to buffer size if necessary.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ * @param n Size of \a d (number of characters).
+ */
+void
+dk3str_ncpy(dkChar *d, dkChar const *s, size_t n);
+
+/** Concatenate two strings.
+ * Do not use this function directly, use dk3str_c8_cat() instead.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ */
+void
+dk3str_c8_cat(char *d, char const *s);
+
+/** Concatenate two strings.
+ * Do not use this function directly, use dk3str_c16_cat() instead.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ */
+void
+dk3str_c16_cat(dk3_c16_t *d, dk3_c16_t const *s);
+
+/** Concatenate two strings.
+ * Do not use this function directly, use dk3str_c32_cat() instead.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ */
+void
+dk3str_c32_cat(dk3_c32_t *d, dk3_c32_t const *s);
+
+/** Concatenate two strings.
+ * Do not use this function directly, use dk3str_c32_cat() instead.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ */
+void
+dk3str_cat(dkChar *d, dkChar const *s);
+
+/** Create a string copy in dynamically allocated memory.
+ @param s Original string.
+ @param app Application structure for diagnostics.
+ @return Pointer to copy on success, NULL on error.
+ The pointer returned on success must be released by
+ dk3_release() when done with it.
+*/
+char *
+dk3str_c8_dup_app(char const *s, dk3_app_t *app);
+
+/** Create a string copy in dynamically allocated memory.
+ @param s Original string.
+ @param app Application structure for diagnostics.
+ @return Pointer to copy on success, NULL on error.
+ The pointer returned on success must be released by
+ dk3_release() when done with it.
+*/
+dk3_c16_t *
+dk3str_c16_dup_app(dk3_c16_t const *s, dk3_app_t *app);
+
+/** Create a string copy in dynamically allocated memory.
+ @param s Original string.
+ @param app Application structure for diagnostics.
+ @return Pointer to copy on success, NULL on error.
+ The pointer returned on success must be released by
+ dk3_release() when done with it.
+*/
+dk3_c32_t *
+dk3str_c32_dup_app(dk3_c32_t const *s, dk3_app_t *app);
+
+/** Create a string copy in dynamically allocated memory.
+ @param s Original string.
+ @param app Application structure for diagnostics.
+ @return Pointer to copy on success, NULL on error.
+ The pointer returned on success must be released by
+ dk3_release() when done with it.
+*/
+dkChar *
+dk3str_dup_app(dkChar const *s, dk3_app_t *app);
+
+/** Convert to lower-case character.
+ * @param c Character to convert.
+ * @return Conversion result.
+ */
+char
+dk3str_c8_tolower(char c);
+
+/** Convert to lower-case character.
+ * @param c Character to convert.
+ * @return Conversion result.
+ */
+dk3_c16_t
+dk3str_c16_tolower(dk3_c16_t c);
+
+/** Convert to lower-case character.
+ * @param c Character to convert.
+ * @return Conversion result.
+ */
+dk3_c32_t
+dk3str_c32_tolower(dk3_c32_t c);
+
+/** Convert to lower-case character.
+ * @param c Character to convert.
+ * @return Conversion result.
+ */
+dkChar
+dk3str_tolower(dkChar c);
+
+/** Convert to upper-case character.
+ * @param c Character to convert.
+ * @return Conversion result.
+ */
+char
+dk3str_c8_toupper(char c);
+
+/** Convert to upper-case character.
+ * @param c Character to convert.
+ * @return Conversion result.
+ */
+dk3_c16_t
+dk3str_c16_toupper(dk3_c16_t c);
+
+/** Convert to upper-case character.
+ * @param c Character to convert.
+ * @return Conversion result.
+ */
+dk3_c32_t
+dk3str_c32_toupper(dk3_c32_t c);
+
+/** Convert to upper-case character.
+ * @param c Character to convert.
+ * @return Conversion result.
+ */
+dkChar
+dk3str_toupper(dkChar c);
+
+/** Find start of string (first non-whitespace).
+ * @param str String to process.
+ * @param whsp Whitespaces set (use NULL for default whitespace set).
+ * @return Pointer to first non-whitespace on success, NULL on error.
+ */
+char *
+dk3str_c8_start(char const *str, char const *whsp);
+
+/** Find start of string (first non-whitespace).
+ * @param str String to process.
+ * @param whsp Whitespaces set (use NULL for default whitespace set).
+ * @return Pointer to first non-whitespace on success, NULL on error.
+ */
+dk3_c16_t *
+dk3str_c16_start(dk3_c16_t const *str, dk3_c16_t const *whsp);
+
+/** Find start of string (first non-whitespace).
+ * @param str String to process.
+ * @param whsp Whitespaces set (use NULL for default whitespace set).
+ * @return Pointer to first non-whitespace on success, NULL on error.
+ */
+dk3_c32_t *
+dk3str_c32_start(dk3_c32_t const *str, dk3_c32_t const *whsp);
+
+/** Find start of string (first non-whitespace).
+ * @param str String to process.
+ * @param whsp Whitespaces set (use NULL for default whitespace set).
+ * @return Pointer to first non-whitespace on success, NULL on error.
+ */
+dkChar *
+dk3str_start(dkChar const *str, dkChar const *whsp);
+
+/** Find start of second text
+ * @param str String to process.
+ * @param whsp Whitespaces set (use NULL for default whitespace set).
+ * @return Pointer to second non-whitespace sequence on success, or NULL.
+ */
+char *
+dk3str_c8_next(char *str, char const *whsp);
+
+/** Find start of second text
+ * @param str String to process.
+ * @param whsp Whitespaces set (use NULL for default whitespace set).
+ * @return Pointer to second non-whitespace sequence on success, or NULL.
+ */
+dk3_c16_t *
+dk3str_c16_next(dk3_c16_t *str, dk3_c16_t const *whsp);
+
+/** Find start of second text
+ * @param str String to process.
+ * @param whsp Whitespaces set (use NULL for default whitespace set).
+ * @return Pointer to second non-whitespace sequence on success, or NULL.
+ */
+dk3_c32_t *
+dk3str_c32_next(dk3_c32_t *str, dk3_c32_t const *whsp);
+
+/** Find start of second text
+ * @param str String to process.
+ * @param whsp Whitespaces set (use NULL for default whitespace set).
+ * @return Pointer to second non-whitespace sequence on success, or NULL.
+ */
+dkChar *
+dk3str_next(dkChar *str, dkChar const *whsp);
+
+/** Remove trailing whitespaces from string.
+ * @param str String to process.
+ * @param whsp Whitespaces set (use NULL for default whitespace set).
+ */
+void
+dk3str_c8_chomp(char *str, char const *whsp);
+
+/** Remove trailing whitespaces from string.
+ * @param str String to process.
+ * @param whsp Whitespaces set (use NULL for default whitespace set).
+ */
+void
+dk3str_c16_chomp(dk3_c16_t *str, dk3_c16_t const *whsp);
+
+/** Remove trailing whitespaces from string.
+ * @param str String to process.
+ * @param whsp Whitespaces set (use NULL for default whitespace set).
+ */
+void
+dk3str_c32_chomp(dk3_c32_t *str, dk3_c32_t const *whsp);
+
+/** Remove trailing whitespaces from string.
+ * @param str String to process.
+ * @param whsp Whitespaces set (use NULL for default whitespace set).
+ */
+void
+dk3str_chomp(dkChar *str, dkChar const *whsp);
+
+/** Remove trailing newline.
+ @param str String to modify.
+*/
+void
+dk3str_c8_delnl(char *str);
+
+/** Remove trailing newline.
+ @param str String to modify.
+*/
+void
+dk3str_c16_delnl(dk3_c16_t *str);
+
+/** Remove trailing newline.
+ @param str String to modify.
+*/
+void
+dk3str_c32_delnl(dk3_c32_t *str);
+
+/** Remove trailing newline.
+ @param str String to modify.
+*/
+void
+dk3str_delnl(dkChar *str);
+
+/** Find index of a string in an array of patterns.
+ * @param a Patterns array.
+ * @param s String to find.
+ * @param c Flag: Case-sensitive (1) or not (0).
+ * @return Index of \a s in \a a on success, -1 on error (not found).
+ */
+int
+dk3str_c8_array_index(char const * const *a, char const *s, int c);
+
+/** Find index of a string in an array of patterns.
+ * @param a Patterns array.
+ * @param s String to find.
+ * @param c Flag: Case-sensitive (1) or not (0).
+ * @return Index of \a s in \a a on success, -1 on error (not found).
+ */
+int
+dk3str_c16_array_index(dk3_c16_t const * const *a, dk3_c16_t const *s, int c);
+
+/** Find index of a string in an array of patterns.
+ * @param a Patterns array.
+ * @param s String to find.
+ * @param c Flag: Case-sensitive (1) or not (0).
+ * @return Index of \a s in \a a on success, -1 on error (not found).
+ */
+int
+dk3str_c32_array_index(dk3_c32_t const * const *a, dk3_c32_t const *s, int c);
+
+/** Find index of a string in an array of patterns.
+ * @param a Patterns array.
+ * @param s String to find.
+ * @param c Flag: Case-sensitive (1) or not (0).
+ * @return Index of \a s in \a a on success, -1 on error (not found).
+ */
+int
+dk3str_array_index(dkChar const * const *a, dkChar const *s, int c);
+
+/** Check whether a text matches a pattern, the text may be abbreviated.
+ * @param line Text to check.
+ * @param pattern Pattern for comparison.
+ * @param spec Special character marking the abbreviation in the
+ * pattern.
+ * @param cs Flag: Case sensitive (1) or not (0).
+ * @return 1 for a match, 0 otherwise.
+ */
+int
+dk3str_c8_is_abbr(char const *line,char const *pattern,char spec,int cs);
+
+/** Check whether a text matches a pattern, the text may be abbreviated.
+ * @param line Text to check.
+ * @param pattern Pattern for comparison.
+ * @param spec Special character marking the abbreviation in the
+ * pattern.
+ * @param cs Flag: Case sensitive (1) or not (0).
+ * @return 1 for a match, 0 otherwise.
+ */
+int
+dk3str_c16_is_abbr(
+ dk3_c16_t const *line, dk3_c16_t const *pattern, dk3_c16_t spec, int cs
+);
+
+/** Check whether a text matches a pattern, the text may be abbreviated.
+ * @param line Text to check.
+ * @param pattern Pattern for comparison.
+ * @param spec Special character marking the abbreviation in the
+ * pattern.
+ * @param cs Flag: Case sensitive (1) or not (0).
+ * @return 1 for a match, 0 otherwise.
+ */
+int
+dk3str_c32_is_abbr(
+ dk3_c32_t const *line, dk3_c32_t const *pattern, dk3_c32_t spec, int cs
+);
+
+/** Check whether a text matches a pattern, the text may be abbreviated.
+ * @param line Text to check.
+ * @param pattern Pattern for comparison.
+ * @param spec Special character marking the abbreviation in the
+ * pattern.
+ * @param cs Flag: Case sensitive (1) or not (0).
+ * @return 1 for a match, 0 otherwise.
+ */
+int
+dk3str_is_abbr(dkChar const *line, dkChar const *pattern, dkChar spec, int cs);
+
+/** Search for a string in an array of patterns with abbreviations allowed.
+ * @param ar Pattern array.
+ * @param str String to search for.
+ * @param sp Special character to mark abbreviation position.
+ * @param cs Flag: Case-sensitive (1) or not (0).
+ * @return Index of \a str in \a ar on success, -1 on error (not found).
+ */
+int
+dk3str_c8_array_abbr(char const * const *ar, char const *str, char sp, int cs);
+
+/** Search for a string in an array of patterns with abbreviations allowed.
+ * @param arr Pattern array.
+ * @param str String to search for.
+ * @param sp Special character to mark abbreviation position.
+ * @param cs Flag: Case-sensitive (1) or not (0).
+ * @return Index of \a str in \a ar on success, -1 on error (not found).
+ */
+int
+dk3str_c16_array_abbr(
+ dk3_c16_t const * const *arr, dk3_c16_t const *str, dk3_c16_t sp, int cs
+);
+
+/** Search for a string in an array of patterns with abbreviations allowed.
+ * @param arr Pattern array.
+ * @param str String to search for.
+ * @param sp Special character to mark abbreviation position.
+ * @param cs Flag: Case-sensitive (1) or not (0).
+ * @return Index of \a str in \a ar on success, -1 on error (not found).
+ */
+int
+dk3str_c32_array_abbr(
+ dk3_c32_t const * const *arr, dk3_c32_t const *str, dk3_c32_t sp, int cs
+);
+
+/** Search for a string in an array of patterns with abbreviations allowed.
+ * @param ar Pattern array.
+ * @param str String to search for.
+ * @param sp Special character to mark abbreviation position.
+ * @param cs Flag: Case-sensitive (1) or not (0).
+ * @return Index of \a str in \a ar on success, -1 on error (not found).
+ */
+int
+dk3str_array_abbr(dkChar const * const *ar,dkChar const *str,dkChar sp,int cs);
+
+/** Check whether the text represents a boolean value.
+ * @param str Text to process.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_c8_is_bool(char const *str);
+
+/** Check whether the text represents a boolean value.
+ * @param str Text to process.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_c16_is_bool(dk3_c16_t const *str);
+
+/** Check whether the text represents a boolean value.
+ * @param str Text to process.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_c32_is_bool(dk3_c32_t const *str);
+
+/** Check whether the text represents a boolean value.
+ * @param str Text to process.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_is_bool(dkChar const *str);
+
+/** Check whether the text represents the boolean value "true".
+ * @param str Text to process.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_c8_is_on(char const *str);
+
+/** Check whether the text represents the boolean value "true".
+ * @param str Text to process.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_c16_is_on(dk3_c16_t const *str);
+
+/** Check whether the text represents the boolean value "true".
+ * @param str Text to process.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_c32_is_on(dk3_c32_t const *str);
+
+/** Check whether the text represents the boolean value "true".
+ * @param str Text to process.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_is_on(dkChar const *str);
+
+/** Explode a string (split string into array of text words).
+ @param array Destination pointers array.
+ @param sz Size of \a array (number of elements).
+ @param str String to process.
+ @param whsp Whitespaces set (may be NULL).
+ @return Number of elements set in \a array, 0 on error.
+*/
+size_t
+dk3str_c8_explode(char **array, size_t sz, char *str, char const *whsp);
+
+/** Explode a string (split string into array of text words).
+ @param array Destination pointers array.
+ @param sz Size of \a array (number of elements).
+ @param str String to process.
+ @param whsp Whitespaces set (may be NULL).
+ @return Number of elements set in \a array, 0 on error.
+*/
+size_t
+dk3str_c16_explode(
+ dk3_c16_t **array, size_t sz, dk3_c16_t *str, dk3_c16_t const *whsp
+);
+
+/** Explode a string (split string into array of text words).
+ @param array Destination pointers array.
+ @param sz Size of \a array (number of elements).
+ @param str String to process.
+ @param whsp Whitespaces set (may be NULL).
+ @return Number of elements set in \a array, 0 on error.
+*/
+size_t
+dk3str_c32_explode(
+ dk3_c32_t **array, size_t sz, dk3_c32_t *str, dk3_c32_t const *whsp
+);
+
+/** Explode a string (split string into array of text words).
+ @param array Destination pointers array.
+ @param sz Size of \a array (number of elements).
+ @param str String to process.
+ @param whsp Whitespaces set (may be NULL).
+ @return Number of elements set in \a array, 0 on error.
+*/
+size_t
+dk3str_explode(dkChar **array, size_t sz, dkChar *str, dkChar const *whsp);
+
+/** Normalize text line.
+ @param l Text line to modify.
+ @param w Whitespaces set (may be NULL).
+ @param s Separator character.
+*/
+void
+dk3str_c8_normalize(char *l, char const *w, char s);
+
+/** Normalize text line.
+ @param l Text line to modify.
+ @param w Whitespaces set (may be NULL).
+ @param s Separator character.
+*/
+void
+dk3str_c16_normalize(dk3_c16_t *l, dk3_c16_t const *w, dk3_c16_t s);
+
+/** Normalize text line.
+ @param l Text line to modify.
+ @param w Whitespaces set (may be NULL).
+ @param s Separator character.
+*/
+void
+dk3str_c32_normalize(dk3_c32_t *l, dk3_c32_t const *w, dk3_c32_t s);
+
+/** Normalize text line.
+ @param l Text line to modify.
+ @param w Whitespaces set (may be NULL).
+ @param s Separator character.
+*/
+void
+dk3str_normalize(dkChar *l, dkChar const *w, dkChar s);
+
+/** Correct file name.
+ * @param n File name to correct.
+ */
+void
+dk3str_c8_correct_filename(char *n);
+
+/** Correct file name.
+ * @param n File name to correct.
+ */
+void
+dk3str_c16_correct_filename(dk3_c16_t *n);
+
+/** Correct file name.
+ * @param n File name to correct.
+ */
+void
+dk3str_c32_correct_filename(dk3_c32_t *n);
+
+/** Correct file name.
+ * @param n File name to correct.
+ */
+void
+dk3str_correct_filename(dkChar *n);
+
+/** Check whether a file/directory name is an absolute path.
+ * @param n Name to check.
+ * @return 1 for absolute path, 0 otherwise.
+ */
+int
+dk3str_c8_is_abs_path(char const *n);
+
+/** Check whether a file/directory name is an absolute path.
+ * @param n Name to check.
+ * @return 1 for absolute path, 0 otherwise.
+ */
+int
+dk3str_c16_is_abs_path(dk3_c16_t const *n);
+
+/** Check whether a file/directory name is an absolute path.
+ * @param n Name to check.
+ * @return 1 for absolute path, 0 otherwise.
+ */
+int
+dk3str_c32_is_abs_path(dk3_c32_t const *n);
+
+/** Check whether a file/directory name is an absolute path.
+ * @param n Name to check.
+ * @return 1 for absolute path, 0 otherwise.
+ */
+int
+dk3str_is_abs_path(dkChar const *n);
+
+/** Append path to a given directory.
+ * @param d In: directory, out: modified path.
+ * @param sz Destination buffer size (number of characters).
+ * @param n Path name to append.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on errors.
+ */
+int
+dk3str_c8_append_path_app(char *d, size_t sz, char const *n, dk3_app_t *app);
+
+/** Append path to a given directory.
+ * @param d In: directory, out: modified path.
+ * @param sz Destination buffer size (number of characters).
+ * @param n Path name to append.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on errors.
+ */
+int
+dk3str_c16_append_path_app(
+ dk3_c16_t *d, size_t sz, dk3_c16_t const *n, dk3_app_t *app
+);
+
+/** Append path to a given directory.
+ * @param d In: directory, out: modified path.
+ * @param sz Destination buffer size (number of characters).
+ * @param n Path name to append.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on errors.
+ */
+int
+dk3str_c32_append_path_app(
+ dk3_c32_t *d, size_t sz, dk3_c32_t const *n, dk3_app_t *app
+);
+
+/** Append path to a given directory.
+ * @param d In: directory, out: modified path.
+ * @param sz Destination buffer size (number of characters).
+ * @param n Path name to append.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on errors.
+ */
+int
+dk3str_append_path_app(dkChar *d, size_t sz, dkChar const *n, dk3_app_t *app);
+
+
+/** Get file name suffix.
+ @param s File name.
+ @return Pointer to suffix on success, NULL on error (no
+ suffix found).
+*/
+char *
+dk3str_c8_get_suffix(char const *s);
+
+/** Get file name suffix.
+ @param s File name.
+ @return Pointer to suffix on success, NULL on error (no
+ suffix found).
+*/
+dk3_c16_t *
+dk3str_c16_get_suffix(dk3_c16_t const *s);
+
+/** Get file name suffix.
+ @param s File name.
+ @return Pointer to suffix on success, NULL on error (no
+ suffix found).
+*/
+dk3_c32_t *
+dk3str_c32_get_suffix(dk3_c32_t const *s);
+
+/** Get file name suffix.
+ @param s File name.
+ @return Pointer to suffix on success, NULL on error (no
+ suffix found).
+*/
+dkChar *
+dk3str_get_suffix(dkChar const *s);
+
+/** Convert 16-bit string to 8-bit string (only ASCII characters).
+ * @param d Destination buffer.
+ * @param sz Size of \a d in bytes.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on error (illegal characters or buffer too
+ * short).
+ */
+int
+dk3str_c16_to_c8_simple_app(
+ char *d, size_t sz, dk3_c16_t const *s, dk3_app_t *app
+);
+
+/** Convert 32-bit string to 8-bit string (only ASCII characters).
+ * @param d Destination buffer.
+ * @param sz Size of \a d in bytes.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on error (illegal characters or buffer too
+ * short).
+ */
+int
+dk3str_c32_to_c8_simple_app(
+ char *d, size_t sz, dk3_c32_t const *s, dk3_app_t *app
+);
+
+/** Find buffer size needed to convert from 8-bit plain to 8-bit UTF-8.
+ * @param s Source string (ASCII/ISO-LATIN-1 encoded).
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Number of bytes needed for UTF-8 encoded string,
+ * the number includes the finalizing 0x00 byte.
+ */
+size_t
+dk3str_cnvsz_c8p_to_c8u_app(char const *s, dk3_app_t *app);
+
+/** Find buffer size needed to convert from UTF-8 to ISO-LATIN-1.
+ * @param s Source string (UTF-8 encoded).
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Number of bytes needed for ISO-LATIN-1 encoded string,
+ * the number includes the finalizing 0x00 byte.
+ */
+size_t
+dk3str_cnvsz_c8u_to_c8p_app(char const *s, dk3_app_t *app);
+
+/** Find buffer size needed to convert from ISO-LATIN-1 to UTF-16.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Number of 16-bit characters needed for result
+ * including the finalizer.
+ */
+size_t
+dk3str_cnvsz_c8p_to_c16_app(char const *s, dk3_app_t *app);
+
+/** Find buffer size needed to convert from UTF-8 to UTF-16.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Number of 16-bit characters needed for result
+ * including the finalizer.
+ */
+size_t
+dk3str_cnvsz_c8u_to_c16_app(char const *s, dk3_app_t *app);
+
+/** Find buffer size needed to convert from UTF-16 to ISO-LATIN-1.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Number of bytes needed for result, including finalizer.
+ */
+size_t
+dk3str_cnvsz_c16_to_c8p_app(dk3_c16_t const *s, dk3_app_t *app);
+
+/** Find buffer size needed to convert from UTF-16 to UTF-8.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Number of bytes needed for result, including finalizer.
+ */
+size_t
+dk3str_cnvsz_c16_to_c8u_app(dk3_c16_t const *s, dk3_app_t *app);
+
+/** Find buffer size needed to convert from ISO-LATIN-1 to 32-bit.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Number of 32-bit characters needed for result,
+ * including finalizer.
+ */
+size_t
+dk3str_cnvsz_c8p_to_c32_app(char const *s, dk3_app_t *app);
+
+/** Find buffer size needed to convert from UTF-8 to 32-bit.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Number of 32-bit characters needed for result,
+ * including finalizer.
+ */
+size_t
+dk3str_cnvsz_c8u_to_c32_app(char const *s, dk3_app_t *app);
+
+/** Find buffer size needed to convert from UTF-16 to 32-bit.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Number of 32-bit characters needed for result,
+ * including finalizer.
+ */
+size_t
+dk3str_cnvsz_c16_to_c32_app(dk3_c16_t const *s, dk3_app_t *app);
+
+/** Find buffer size needed to convert from 32-bit to ISO-LATIN-1.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Number of bytes needed for result, including finalizer.
+ */
+size_t
+dk3str_cnvsz_c32_to_c8p_app(dk3_c32_t const *s, dk3_app_t *app);
+
+/** Find buffer size needed to convert from 32-bit to UTF-8.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Number of bytes needed for result, including finalizer.
+ */
+size_t
+dk3str_cnvsz_c32_to_c8u_app(dk3_c32_t const *s, dk3_app_t *app);
+
+/** Find buffer size needed to convert from 32-bit to UTF-16.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Number of UTF-16 chars needed for result, including finalizer.
+ */
+size_t
+dk3str_cnvsz_c32_to_c16_app(dk3_c32_t const *s, dk3_app_t *app);
+
+/** Convert ISO-LATIN-1 string to UTF-8.
+ * @param d Destination buffer.
+ * @param ds Size of \a d (number of elements).
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_cnv_c8p_to_c8u_app(char *d, size_t ds, char const *s, dk3_app_t *app);
+
+/** Convert UTF-8 string to ISO-LATIN-1.
+ * @param d Destination buffer.
+ * @param ds Size of \a d (number of elements).
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_cnv_c8u_to_c8p_app(char *d, size_t ds, char const *s, dk3_app_t *app);
+
+/** Convert ISO-LATIN-1 string to UTF-16.
+ * @param d Destination buffer.
+ * @param ds Size of \a d (number of elements).
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_cnv_c8p_to_c16_app(
+ dk3_c16_t *d, size_t ds, char const *s, dk3_app_t *app
+);
+
+/** Convert UTF-8 string to UTF-16.
+ * @param d Destination buffer.
+ * @param ds Size of \a d (number of elements).
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_cnv_c8u_to_c16_app(
+ dk3_c16_t *d, size_t ds, char const *s, dk3_app_t *app
+);
+
+/** Convert UTF-16 string to ISO-LATIN-1.
+ * @param d Destination buffer.
+ * @param ds Size of \a d (number of elements).
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_cnv_c16_to_c8p_app(
+ char *d, size_t ds, dk3_c16_t const *s, dk3_app_t *app
+);
+
+/** Convert UTF-16 string to UTF-8.
+ * @param d Destination buffer.
+ * @param ds Size of \a d (number of elements).
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_cnv_c16_to_c8u_app(
+ char *d, size_t ds, dk3_c16_t const *s, dk3_app_t *app
+);
+
+/** Convert ISO-LATIN-1 string to 32-bit.
+ * @param d Destination buffer.
+ * @param ds Size of \a d (number of elements).
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_cnv_c8p_to_c32_app(
+ dk3_c32_t *d, size_t ds, char const *s, dk3_app_t *app
+);
+
+/** Convert UTF-8 string to 32-bit.
+ * @param d Destination buffer.
+ * @param ds Size of \a d (number of elements).
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_cnv_c8u_to_c32_app(
+ dk3_c32_t *d, size_t ds, char const *s, dk3_app_t *app
+);
+
+/** Convert UTF-16 string to 32-bit.
+ * @param d Destination buffer.
+ * @param ds Size of \a d (number of elements).
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_cnv_c16_to_c32_app(
+ dk3_c32_t *d, size_t ds, dk3_c16_t const *s, dk3_app_t *app
+);
+
+/** Convert 32-bit string to ISO-LATIN-1.
+ * @param d Destination buffer.
+ * @param ds Size of \a d (number of elements).
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_cnv_c32_to_c8p_app(
+ char *d, size_t ds, dk3_c32_t const *s, dk3_app_t *app
+);
+
+/** Convert 32-bit string to UTF-8.
+ * @param d Destination buffer.
+ * @param ds Size of \a d (number of elements).
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_cnv_c32_to_c8u_app(
+ char *d, size_t ds, dk3_c32_t const *s, dk3_app_t *app
+);
+
+/** Convert 32-bit string to UTF-16.
+ * @param d Destination buffer.
+ * @param ds Size of \a d (number of elements).
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3str_cnv_c32_to_c16_app(
+ dk3_c16_t *d, size_t ds, dk3_c32_t const *s, dk3_app_t *app
+);
+
+/** Convert ISO-LATIN-1 string to UTF-8, allocate new memory for result.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Pointer to new result string on success, NULL on error.
+ */
+char *
+dk3str_cnvnew_c8p_to_c8u_app(char const *s, dk3_app_t *app);
+
+/** Convert UTF-8 string to ISO-LATIN-1, allocate new memory for result.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Pointer to new result string on success, NULL on error.
+ */
+char *
+dk3str_cnvnew_c8u_to_c8p_app(char const *s, dk3_app_t *app);
+
+/** Convert ISO-LATIN-1 string to UTF-16, allocate new memory for result.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Pointer to new result string on success, NULL on error.
+ */
+dk3_c16_t *
+dk3str_cnvnew_c8p_to_c16_app(char const *s, dk3_app_t *app);
+
+/** Convert UTF-8 string to UTF-16, allocate new memory for result.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Pointer to new result string on success, NULL on error.
+ */
+dk3_c16_t *
+dk3str_cnvnew_c8u_to_c16_app(char const *s, dk3_app_t *app);
+
+/** Convert UTF-16 string to ISO-LATIN-1, allocate new memory for result.
+ * @param s Source string.
+ * @param app Application structure, used for diagnostics.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Pointer to new result string on success, NULL on error.
+ */
+char *
+dk3str_cnvnew_c16_to_c8p_app(dk3_c16_t const *s, dk3_app_t *app);
+
+/** Convert UTF-16 string to UTF-8, allocate new memory for result.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Pointer to new result string on success, NULL on error.
+ */
+char *
+dk3str_cnvnew_c16_to_c8u_app(dk3_c16_t const *s, dk3_app_t *app);
+
+/** Convert ISO-LATIN-1 string to 32-bit, allocate new memory for result.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Pointer to new result string on success, NULL on error.
+ */
+dk3_c32_t *
+dk3str_cnvnew_c8p_to_c32_app(char const *s, dk3_app_t *app);
+
+/** Convert UTF-8 string to 32-bit, allocate new memory for result.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Pointer to new result string on success, NULL on error.
+ */
+dk3_c32_t *
+dk3str_cnvnew_c8u_to_c32_app(char const *s, dk3_app_t *app);
+
+/** Convert UTF-16 string to 32-bit, allocate new memory for result.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Pointer to new result string on success, NULL on error.
+ */
+dk3_c32_t *
+dk3str_cnvnew_c16_to_c32_app(dk3_c16_t const *s, dk3_app_t *app);
+
+/** Convert 32-bit string to ISO_LATIN-1, allocate new memory for result.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Pointer to new result string on success, NULL on error.
+ */
+char *
+dk3str_cnvnew_c32_to_c8p_app(dk3_c32_t const *s, dk3_app_t *app);
+
+/** Convert 32-bit string to UTF-8, allocate new memory for result.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Pointer to new result string on success, NULL on error.
+ */
+char *
+dk3str_cnvnew_c32_to_c8u_app(dk3_c32_t const *s, dk3_app_t *app);
+
+/** Convert 32-bit to UTF_16, allocate new memory for result.
+ * @param s Source string.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Pointer to new result string on success, NULL on error.
+ */
+dk3_c16_t *
+dk3str_cnvnew_c32_to_c16_app(dk3_c32_t const *s, dk3_app_t *app);
+
+/** Convert 8-bit character to 8/16-bit character
+ without re-encoding. This function is mainly intended to convert
+ pure ASCII characters like numeric values.
+ @param d Destination buffer.
+ @param sz Size of \a d in characters.
+ @param s Source string.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3str_cnv_c8_to_str_app(dkChar *d, size_t sz, char const *s, dk3_app_t *app);
+
+/** Convert dkChar string to 8-bit (simple version,
+ used to read numeric values).
+ @param db Destination buffer.
+ @param sz Size of \a db.
+ @param s Source string.
+ @param ap Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error
+ (buffer too short or character out of range).
+*/
+int
+dk3str_string_to_c8_simple_app(
+ char *db,size_t sz,dkChar const *s,dk3_app_t *ap
+);
+
+/** Convert string to all lower-case characters.
+ @param s String to modify.
+*/
+void
+dk3str_string_tolower(dkChar *s);
+
+/** Convert 8-bit text to dkChar string.
+ @param dp Destination pointer.
+ @param ds Size of \a dp (number of characters).
+ @param sp Source pointer.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error (output buffer too small).
+*/
+int
+dk3str_c8_to_str_simple_app(
+ dkChar *dp, size_t ds, char const *sp, dk3_app_t *app
+);
+
+/** Convert dkChar string to plain 8-bit text.
+ @param dp Destination buffer pointer.
+ @param sz Size of \a dp (number of bytes).
+ @param src Source text.
+ @param ie Input encoding (used only for 8-bit characters).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3str_to_c8p_app(
+ char *dp, size_t sz, dkChar const *src, int ie, dk3_app_t *app
+);
+
+/** Convert dkChar string to UTF-8 text.
+ @param dp Destination buffer pointer.
+ @param sz Size of \a dp (number of bytes).
+ @param src Source text.
+ @param ie Input encoding (used only for 8-bit characters).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3str_to_c8u_app(
+ char *dp, size_t sz, dkChar const *src, int ie, dk3_app_t *app
+);
+
+/** Convert UTF-8 encoded string to dkChar string.
+ @param d Destination buffer.
+ @param dsz Size of @a d (number of elements).
+ @param de Destination buffer encoding.
+ @param s Source string.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3str_c8u_to_str_app(
+ dkChar *d,
+ size_t dsz,
+ int de,
+ char const *s,
+ dk3_app_t *app
+);
+
+/** Convert dkChar string to UTF-8 encoded string.
+ @param d Destination buffer.
+ @param dsz Size of @a d (number of bytes).
+ @param s Source string.
+ @param se Source encoding (used for 8-bit characters only).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3str_str_to_c8u_app(
+ char *d,
+ size_t dsz,
+ dkChar const *s,
+ int se,
+ dk3_app_t *app
+);
+
+/** Convert dkChar string to 8-bit character string.
+ @param dp Destination buffer pointer.
+ @param szdp Size of dp.
+ @param src Source string.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3str_to_c8_app(char *dp, size_t szdp, dkChar const *src, dk3_app_t *app);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3strkv.c b/support/dktools/dk3strkv.c
new file mode 100644
index 0000000000..1f89f03519
--- /dev/null
+++ b/support/dktools/dk3strkv.c
@@ -0,0 +1,674 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3strkv.ctr
+*/
+
+/** @file dk3strkv.c The dk3strkv module.
+*/
+
+/** @defgroup dkct_state_machine_dk3strkv_stm The dk3strkv_stm state machine. */
+/**@{*/
+
+#ifndef ST_DQ_EXPECT
+/** State: Expect double quoted value */
+#line 41 "dk3strkv.ctr"
+#define ST_DQ_EXPECT 0
+#else
+#line 41 "dk3strkv.ctr"
+#error "Redefinition of ST_DQ_EXPECT"
+#endif
+
+#ifndef ST_DQ_VALUE
+/** State: Having double quoted value */
+#line 43 "dk3strkv.ctr"
+#define ST_DQ_VALUE 1
+#else
+#line 43 "dk3strkv.ctr"
+#error "Redefinition of ST_DQ_VALUE"
+#endif
+
+#ifndef ST_ERROR
+/** State: Error occured */
+#line 44 "dk3strkv.ctr"
+#define ST_ERROR 2
+#else
+#line 44 "dk3strkv.ctr"
+#error "Redefinition of ST_ERROR"
+#endif
+
+#ifndef ST_EXPECT
+/** State: Expect value */
+#line 38 "dk3strkv.ctr"
+#define ST_EXPECT 3
+#else
+#line 38 "dk3strkv.ctr"
+#error "Redefinition of ST_EXPECT"
+#endif
+
+#ifndef ST_KEY
+/** State: In a key */
+#line 37 "dk3strkv.ctr"
+#define ST_KEY 4
+#else
+#line 37 "dk3strkv.ctr"
+#error "Redefinition of ST_KEY"
+#endif
+
+#ifndef ST_SQ_EXPECT
+/** State: Expect single quoted value */
+#line 40 "dk3strkv.ctr"
+#define ST_SQ_EXPECT 5
+#else
+#line 40 "dk3strkv.ctr"
+#error "Redefinition of ST_SQ_EXPECT"
+#endif
+
+#ifndef ST_SQ_VALUE
+/** State: Having single quoted value */
+#line 42 "dk3strkv.ctr"
+#define ST_SQ_VALUE 6
+#else
+#line 42 "dk3strkv.ctr"
+#error "Redefinition of ST_SQ_VALUE"
+#endif
+
+#ifndef ST_START
+/** State: Waiting for anything to happen */
+#line 36 "dk3strkv.ctr"
+#define ST_START 7
+#else
+#line 36 "dk3strkv.ctr"
+#error "Redefinition of ST_START"
+#endif
+
+#ifndef ST_VALUE
+/** State: Having value */
+#line 39 "dk3strkv.ctr"
+#define ST_VALUE 8
+#else
+#line 39 "dk3strkv.ctr"
+#error "Redefinition of ST_VALUE"
+#endif
+
+#ifndef I_BS
+/** State machine input: Backslash */
+#line 50 "dk3strkv.ctr"
+#define I_BS 0
+#else
+#line 50 "dk3strkv.ctr"
+#error "Redefinition of I_BS"
+#endif
+
+#ifndef I_DQ
+/** State machine input: Double quote */
+#line 49 "dk3strkv.ctr"
+#define I_DQ 1
+#else
+#line 49 "dk3strkv.ctr"
+#error "Redefinition of I_DQ"
+#endif
+
+#ifndef I_EQ
+/** State machine input: Equal sign */
+#line 51 "dk3strkv.ctr"
+#define I_EQ 2
+#else
+#line 51 "dk3strkv.ctr"
+#error "Redefinition of I_EQ"
+#endif
+
+#ifndef I_OT
+/** State machine input: Any other character */
+#line 46 "dk3strkv.ctr"
+#define I_OT 3
+#else
+#line 46 "dk3strkv.ctr"
+#error "Redefinition of I_OT"
+#endif
+
+#ifndef I_SQ
+/** State machine input: Single quote */
+#line 48 "dk3strkv.ctr"
+#define I_SQ 4
+#else
+#line 48 "dk3strkv.ctr"
+#error "Redefinition of I_SQ"
+#endif
+
+#ifndef I_WH
+/** State machine input: White space */
+#line 47 "dk3strkv.ctr"
+#define I_WH 5
+#else
+#line 47 "dk3strkv.ctr"
+#error "Redefinition of I_WH"
+#endif
+
+#ifndef O_ENDCOUNT
+/** State machine output: End key string and count upwards */
+#line 58 "dk3strkv.ctr"
+#define O_ENDCOUNT 0
+#else
+#line 58 "dk3strkv.ctr"
+#error "Redefinition of O_ENDCOUNT"
+#endif
+
+#ifndef O_ENDKEY
+/** State machine output: End key string (change to finalizer) */
+#line 57 "dk3strkv.ctr"
+#define O_ENDKEY 1
+#else
+#line 57 "dk3strkv.ctr"
+#error "Redefinition of O_ENDKEY"
+#endif
+
+#ifndef O_ENDVAL
+/** State machine output: End value string (change to finalizer) */
+#line 59 "dk3strkv.ctr"
+#define O_ENDVAL 2
+#else
+#line 59 "dk3strkv.ctr"
+#error "Redefinition of O_ENDVAL"
+#endif
+
+#ifndef O_ERROR
+/** State machine output: Error occured */
+#line 53 "dk3strkv.ctr"
+#define O_ERROR 3
+#else
+#line 53 "dk3strkv.ctr"
+#error "Redefinition of O_ERROR"
+#endif
+
+#ifndef O_NO
+/** State machine output: Do nothing */
+#line 54 "dk3strkv.ctr"
+#define O_NO 4
+#else
+#line 54 "dk3strkv.ctr"
+#error "Redefinition of O_NO"
+#endif
+
+#ifndef O_SEVAL
+/** State machine output: Start and end value */
+#line 62 "dk3strkv.ctr"
+#define O_SEVAL 5
+#else
+#line 62 "dk3strkv.ctr"
+#error "Redefinition of O_SEVAL"
+#endif
+
+#ifndef O_SKEY
+/** State machine output: Start key */
+#line 56 "dk3strkv.ctr"
+#define O_SKEY 6
+#else
+#line 56 "dk3strkv.ctr"
+#error "Redefinition of O_SKEY"
+#endif
+
+#ifndef O_SQ
+/** State machine output: Squeeze */
+#line 55 "dk3strkv.ctr"
+#define O_SQ 7
+#else
+#line 55 "dk3strkv.ctr"
+#error "Redefinition of O_SQ"
+#endif
+
+#ifndef O_SQ_SVAL
+/** State machine output: Squeeze and start value */
+#line 61 "dk3strkv.ctr"
+#define O_SQ_SVAL 8
+#else
+#line 61 "dk3strkv.ctr"
+#error "Redefinition of O_SQ_SVAL"
+#endif
+
+#ifndef O_SVAL
+/** State machine output: Start value */
+#line 60 "dk3strkv.ctr"
+#define O_SVAL 9
+#else
+#line 60 "dk3strkv.ctr"
+#error "Redefinition of O_SVAL"
+#endif
+
+/**@}*/
+
+/** Reset dk3strkv_stm state machine.
+ @param st Pointer to state variable.
+*/
+static
+void
+dk3strkv_stm_reset(int *st)
+{
+ if(st) { *st = ST_START; }
+}
+
+/** State machine dk3strkv_stm step.
+ @param st Pointer to state variable.
+ @param in Input.
+ @return Transition output.
+*/
+static
+int
+dk3strkv_stm_step(int *st, int in)
+{
+ int back = O_ERROR;
+ if(st) {
+ int os;
+ int nf = 1;
+ int ns = ST_ERROR;
+ os = *st;
+ switch(os) {
+ case ST_DQ_EXPECT: {
+ switch(in) {
+ case I_BS: {
+ ns = ST_DQ_VALUE; back = O_SQ_SVAL; nf = 0;
+ } break;
+ case I_DQ: {
+ ns = ST_START; back = O_SEVAL; nf = 0;
+ } break;
+ }
+ } break;
+ case ST_DQ_VALUE: {
+ switch(in) {
+ case I_BS: {
+ ns = ST_DQ_VALUE; back = O_SQ; nf = 0;
+ } break;
+ case I_DQ: {
+ ns = ST_START; back = O_ENDVAL; nf = 0;
+ } break;
+ }
+ } break;
+ case ST_EXPECT: {
+ switch(in) {
+ case I_BS: {
+ ns = ST_VALUE; back = O_SQ_SVAL; nf = 0;
+ } break;
+ case I_DQ: {
+ ns = ST_DQ_EXPECT; back = O_NO; nf = 0;
+ } break;
+ case I_SQ: {
+ ns = ST_SQ_EXPECT; back = O_NO; nf = 0;
+ } break;
+ case I_WH: {
+ ns = ST_EXPECT; back = O_NO; nf = 0;
+ } break;
+ }
+ } break;
+ case ST_KEY: {
+ switch(in) {
+ case I_EQ: {
+ ns = ST_EXPECT; back = O_ENDKEY; nf = 0;
+ } break;
+ case I_WH: {
+ ns = ST_START; back = O_ENDCOUNT; nf = 0;
+ } break;
+ }
+ } break;
+ case ST_SQ_EXPECT: {
+ switch(in) {
+ case I_BS: {
+ ns = ST_SQ_VALUE; back = O_SQ_SVAL; nf = 0;
+ } break;
+ case I_SQ: {
+ ns = ST_START; back = O_SEVAL; nf = 0;
+ } break;
+ }
+ } break;
+ case ST_SQ_VALUE: {
+ switch(in) {
+ case I_BS: {
+ ns = ST_SQ_VALUE; back = O_SQ; nf = 0;
+ } break;
+ case I_SQ: {
+ ns = ST_START; back = O_ENDVAL; nf = 0;
+ } break;
+ }
+ } break;
+ case ST_START: {
+ switch(in) {
+ case I_OT: {
+ ns = ST_KEY; back = O_SKEY; nf = 0;
+ } break;
+ case I_WH: {
+ ns = ST_START; back = O_NO; nf = 0;
+ } break;
+ }
+ } break;
+ case ST_VALUE: {
+ switch(in) {
+ case I_BS: {
+ ns = ST_VALUE; back = O_SQ; nf = 0;
+ } break;
+ case I_WH: {
+ ns = ST_START; back = O_ENDVAL; nf = 0;
+ } break;
+ }
+ } break;
+ }
+ if(nf) {
+ if(os == ST_KEY) {
+ ns = ST_KEY; back = O_NO;
+ } else {
+ if(os == ST_EXPECT) {
+ ns = ST_VALUE; back = O_SVAL;
+ } else {
+ if(os == ST_VALUE) {
+ ns = ST_VALUE; back = O_NO;
+ } else {
+ if(os == ST_SQ_EXPECT) {
+ ns = ST_SQ_VALUE; back = O_SVAL;
+ } else {
+ if(os == ST_SQ_VALUE) {
+ ns = ST_SQ_VALUE; back = O_NO;
+ } else {
+ if(os == ST_DQ_EXPECT) {
+ ns = ST_DQ_VALUE; back = O_SVAL;
+ } else {
+ if(os == ST_DQ_VALUE) {
+ ns = ST_DQ_VALUE; back = O_NO;
+ } else {
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ *st = ns;
+ } else {
+ }
+ return back;
+}
+
+
+#line 100 "dk3strkv.ctr"
+
+
+#include "dk3all.h"
+#include "dk3strkv.h"
+
+
+
+/** Classify input character
+ @param c Character to classify.
+ @return Character class.
+*/
+static
+int
+dk3strkv_classify(dkChar c)
+{
+ int back = I_OT;
+
+
+#line 117 "dk3strkv.ctr"
+ switch(c) {
+ case dkT(' '): case dkT('\t'): {
+ back = I_WH;
+ } break;
+ case dkT('"'): {
+ back = I_DQ;
+ } break;
+ case dkT('\''): {
+ back = I_SQ;
+ } break;
+ case dkT('\\'): {
+ back = I_BS;
+ } break;
+ case dkT('='): {
+ back = I_EQ;
+ } break;
+ }
+
+#line 134 "dk3strkv.ctr"
+ return back;
+}
+
+
+
+/** Empty line.
+*/
+static dkChar const dk3strkv_empty_line[] = { dkT("") };
+
+
+
+/** Report error for unexpected end of text.
+ @param app Application structure for diagnostics, may be NULL.
+ @param il Input line to complain about.
+*/
+static
+void
+dk3strkv_error_unexpected_eot(dk3_app_t *app, dkChar *il)
+{
+ dkChar const *ptr;
+ if(app) {
+ ptr = il;
+ if(!(ptr)) { ptr = dk3strkv_empty_line; }
+ dk3app_log_i3(app, DK3_LL_ERROR, 389, 390, ptr);
+ }
+}
+
+
+
+/** Report error, too many key value items.
+ @param app Application structure for diagnostics, may be NULL.
+ @param il Input line to complain about.
+ @param pos Position in line.
+*/
+static
+void
+dk3strkv_error_too_many(dk3_app_t *app, dkChar *il, unsigned long pos)
+{
+ dkChar buffer[64];
+ dkChar const *ptr;
+ if(app) {
+ ptr = il;
+ if(!(ptr)) { ptr = dk3strkv_empty_line; }
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(buffer, dkT("%lu"), pos);
+ dk3app_log_i5(app, DK3_LL_ERROR, 386, 387, 388, buffer, ptr);
+#else
+ if (dk3ma_um_to_string(buffer, DK3_SIZEOF(buffer, dkChar), (dk3_um_t)pos)) {
+ dk3app_log_i5(app, DK3_LL_ERROR, 386, 387, 388, buffer, ptr);
+ }
+#endif
+ }
+}
+
+
+
+
+int
+dk3str_to_key_value(
+ dk3_key_value_t *kvp,
+ size_t *szp,
+ dkChar *il,
+ dk3_app_t *app
+)
+{
+ dkChar *ptr; /* Traverse string. */
+ dkChar *mycopy; /* Private copy for diagnostics. */
+ unsigned long charno; /* Character number. */
+ size_t i; /* Current key value pair index. */
+ int icl; /* Input class. */
+ int act; /* Action to take. */
+ int stm; /* State machine. */
+ int cc; /* Flag: Can continue. */
+ int rtm = 0; /* Reported too many. */
+ int error = 0; /* Flag: Have error. */
+ int back = 0;
+
+
+#line 211 "dk3strkv.ctr"
+ if((kvp) && (szp)) {
+ for(i = 0; i < *szp; i++) { kvp[i].key = NULL; kvp[i].val = NULL; }
+ }
+ if((kvp) && (szp) && (il)) {
+ if(*szp) {
+ mycopy = dk3str_dup_app(il, app);
+ i = 0;
+ ptr = il; cc = 1; charno = 1UL;
+ dk3strkv_stm_reset(&stm);
+ while(cc) {
+ if(*ptr) {
+
+#line 222 "dk3strkv.ctr"
+ icl = dk3strkv_classify(*ptr);
+
+#line 223 "dk3strkv.ctr"
+ act = dk3strkv_stm_step(&stm, icl);
+
+#line 224 "dk3strkv.ctr"
+ switch(act) {
+ case O_ERROR: {
+
+#line 226 "dk3strkv.ctr"
+ error = 1;
+ } break;
+ case O_SQ: {
+
+#line 229 "dk3strkv.ctr"
+ dk3str_cpy(ptr, &(ptr[1]));
+ if(*ptr) {
+ charno++;
+ } else {
+ cc = 0;
+ error = 1;
+ dk3strkv_error_unexpected_eot(app, mycopy);
+ }
+ } break;
+ case O_SKEY: {
+
+#line 239 "dk3strkv.ctr"
+ if(i < (*szp)) {
+ kvp[i].key = ptr;
+ } else {
+ error = 1;
+ if(0 == rtm) {
+ rtm = 1;
+ dk3strkv_error_too_many(app, mycopy, charno);
+ }
+ }
+ } break;
+ case O_ENDKEY: {
+
+#line 250 "dk3strkv.ctr"
+ *ptr = dkT('\0');
+ } break;
+ case O_ENDCOUNT: {
+
+#line 253 "dk3strkv.ctr"
+ *ptr = dkT('\0');
+ i++;
+ } break;
+ case O_ENDVAL: {
+
+#line 257 "dk3strkv.ctr"
+ *ptr = dkT('\0');
+ i++;
+ } break;
+ case O_SVAL: {
+
+#line 261 "dk3strkv.ctr"
+ if(i < (*szp)) {
+ kvp[i].val = ptr;
+ } else {
+ error = 1;
+ if(0 == rtm) {
+ rtm = 1;
+ dk3strkv_error_too_many(app, mycopy, charno);
+ }
+ }
+ } break;
+ case O_SQ_SVAL: {
+
+#line 272 "dk3strkv.ctr"
+ dk3str_cpy(ptr, &(ptr[1]));
+ if(*ptr) {
+ charno++;
+ if(i < (*szp)) {
+ kvp[i].val = ptr;
+ } else {
+ error = 1;
+ if(0 == rtm) {
+ rtm = 1;
+ dk3strkv_error_too_many(app, mycopy, charno);
+ }
+ }
+ } else {
+ cc = 0;
+ error = 1;
+ dk3strkv_error_unexpected_eot(app, mycopy);
+ }
+ } break;
+ case O_SEVAL: {
+
+#line 291 "dk3strkv.ctr"
+ *ptr = dkT('\0');
+ if(i < (*szp)) {
+ kvp[i].val = ptr;
+ i++;
+ } else {
+ error = 1;
+ if(0 == rtm) {
+ rtm = 1;
+ dk3strkv_error_too_many(app, mycopy, charno);
+ }
+ }
+ } break;
+ }
+ ptr++;
+ charno++;
+ } else {
+ cc = 0;
+ }
+ }
+ switch(stm) {
+ case ST_START: {
+
+#line 312 "dk3strkv.ctr"
+ if(0 == error) {
+ back = 1;
+ *szp = i;
+ }
+ } break;
+ case ST_KEY: {
+
+#line 318 "dk3strkv.ctr"
+ if(0 == error) {
+ i++;
+ back = 1;
+ *szp = i;
+ }
+ } break;
+ case ST_VALUE: {
+
+#line 325 "dk3strkv.ctr"
+ if(0 == error) {
+ i++;
+ back = 1;
+ *szp = i;
+ }
+ } break;
+ }
+ dk3_release(mycopy);
+ }
+ } else {
+ if((kvp) && (szp) && (!(il))) {
+ *szp = 0;
+ back = 1;
+ }
+ }
+
+#line 340 "dk3strkv.ctr"
+ return back;
+}
+
+
+
diff --git a/support/dktools/dk3strkv.ctr b/support/dktools/dk3strkv.ctr
new file mode 100644
index 0000000000..027836fbff
--- /dev/null
+++ b/support/dktools/dk3strkv.ctr
@@ -0,0 +1,344 @@
+%% options
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert input line into key value pairs.
+ @param kvp Array of key value structures for results.
+ @param szp Size of array (in), used elements (out).
+ @param il Input line to process.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success (number of elements in sz), 0 on error.
+*/
+int
+dk3str_to_key_value(
+ dk3_key_value_t *kvp,
+ size_t *szp,
+ dkChar *il,
+ dk3_app_t *app
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% state machine
+
+[options]
+ name = dk3strkv_stm
+ write header = no
+[states]
+ ST_START # Waiting for anything to happen
+ ST_KEY # In a key
+ ST_EXPECT # Expect value
+ ST_VALUE # Having value
+ ST_SQ_EXPECT # Expect single quoted value
+ ST_DQ_EXPECT # Expect double quoted value
+ ST_SQ_VALUE # Having single quoted value
+ ST_DQ_VALUE # Having double quoted value
+ ST_ERROR # Error occured
+[inputs]
+ I_OT # Any other character
+ I_WH # White space
+ I_SQ # Single quote
+ I_DQ # Double quote
+ I_BS # Backslash
+ I_EQ # Equal sign
+[output]
+ O_ERROR # Error occured
+ O_NO # Do nothing
+ O_SQ # Squeeze
+ O_SKEY # Start key
+ O_ENDKEY # End key string (change to finalizer)
+ O_ENDCOUNT # End key string and count upwards
+ O_ENDVAL # End value string (change to finalizer)
+ O_SVAL # Start value
+ O_SQ_SVAL # Squeeze and start value
+ O_SEVAL # Start and end value
+[rules]
+ * * ST_ERROR O_ERROR
+
+ ST_START I_WH ST_START O_NO
+ ST_START I_OT ST_KEY O_SKEY
+
+ ST_KEY * ST_KEY O_NO
+ ST_KEY I_WH ST_START O_ENDCOUNT
+ ST_KEY I_EQ ST_EXPECT O_ENDKEY
+
+ ST_EXPECT I_WH ST_EXPECT O_NO
+ ST_EXPECT * ST_VALUE O_SVAL
+ ST_EXPECT I_BS ST_VALUE O_SQ_SVAL
+ ST_EXPECT I_SQ ST_SQ_EXPECT O_NO
+ ST_EXPECT I_DQ ST_DQ_EXPECT O_NO
+
+ ST_VALUE * ST_VALUE O_NO
+ ST_VALUE I_BS ST_VALUE O_SQ
+ ST_VALUE I_WH ST_START O_ENDVAL
+
+ ST_SQ_EXPECT * ST_SQ_VALUE O_SVAL
+ ST_SQ_EXPECT I_BS ST_SQ_VALUE O_SQ_SVAL
+ ST_SQ_EXPECT I_SQ ST_START O_SEVAL
+
+ ST_SQ_VALUE * ST_SQ_VALUE O_NO
+ ST_SQ_VALUE I_SQ ST_START O_ENDVAL
+ ST_SQ_VALUE I_BS ST_SQ_VALUE O_SQ
+
+ ST_DQ_EXPECT * ST_DQ_VALUE O_SVAL
+ ST_DQ_EXPECT I_BS ST_DQ_VALUE O_SQ_SVAL
+ ST_DQ_EXPECT I_DQ ST_START O_SEVAL
+
+ ST_DQ_VALUE * ST_DQ_VALUE O_NO
+ ST_DQ_VALUE I_BS ST_DQ_VALUE O_SQ
+ ST_DQ_VALUE I_DQ ST_START O_ENDVAL
+
+%% module
+
+
+#include "dk3all.h"
+#include "dk3strkv.h"
+
+
+
+/** Classify input character
+ @param c Character to classify.
+ @return Character class.
+*/
+static
+int
+dk3strkv_classify(dkChar c)
+{
+ int back = I_OT;
+ $? "+ dk3strkv_classify %d", (int)c
+ switch(c) {
+ case dkT(' '): case dkT('\t'): {
+ back = I_WH;
+ } break;
+ case dkT('"'): {
+ back = I_DQ;
+ } break;
+ case dkT('\''): {
+ back = I_SQ;
+ } break;
+ case dkT('\\'): {
+ back = I_BS;
+ } break;
+ case dkT('='): {
+ back = I_EQ;
+ } break;
+ } $? "- dk3strkv_classify %d", back
+ return back;
+}
+
+
+
+/** Empty line.
+*/
+static dkChar const dk3strkv_empty_line[] = { dkT("") };
+
+
+
+/** Report error for unexpected end of text.
+ @param app Application structure for diagnostics, may be NULL.
+ @param il Input line to complain about.
+*/
+static
+void
+dk3strkv_error_unexpected_eot(dk3_app_t *app, dkChar *il)
+{
+ dkChar const *ptr;
+ if(app) {
+ ptr = il;
+ if(!(ptr)) { ptr = dk3strkv_empty_line; }
+ dk3app_log_i3(app, DK3_LL_ERROR, 389, 390, ptr);
+ }
+}
+
+
+
+/** Report error, too many key value items.
+ @param app Application structure for diagnostics, may be NULL.
+ @param il Input line to complain about.
+ @param pos Position in line.
+*/
+static
+void
+dk3strkv_error_too_many(dk3_app_t *app, dkChar *il, unsigned long pos)
+{
+ dkChar buffer[64];
+ dkChar const *ptr;
+ if(app) {
+ ptr = il;
+ if(!(ptr)) { ptr = dk3strkv_empty_line; }
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(buffer, dkT("%lu"), pos);
+ dk3app_log_i5(app, DK3_LL_ERROR, 386, 387, 388, buffer, ptr);
+#else
+ if (dk3ma_um_to_string(buffer, DK3_SIZEOF(buffer, dkChar), (dk3_um_t)pos)) {
+ dk3app_log_i5(app, DK3_LL_ERROR, 386, 387, 388, buffer, ptr);
+ }
+#endif
+ }
+}
+
+
+
+
+int
+dk3str_to_key_value(
+ dk3_key_value_t *kvp,
+ size_t *szp,
+ dkChar *il,
+ dk3_app_t *app
+)
+{
+ dkChar *ptr; /* Traverse string. */
+ dkChar *mycopy; /* Private copy for diagnostics. */
+ unsigned long charno; /* Character number. */
+ size_t i; /* Current key value pair index. */
+ int icl; /* Input class. */
+ int act; /* Action to take. */
+ int stm; /* State machine. */
+ int cc; /* Flag: Can continue. */
+ int rtm = 0; /* Reported too many. */
+ int error = 0; /* Flag: Have error. */
+ int back = 0;
+ $? "+ dk3str_to_key_value \"%!ds\"", il
+ if((kvp) && (szp)) {
+ for(i = 0; i < *szp; i++) { kvp[i].key = NULL; kvp[i].val = NULL; }
+ }
+ if((kvp) && (szp) && (il)) {
+ if(*szp) {
+ mycopy = dk3str_dup_app(il, app);
+ i = 0;
+ ptr = il; cc = 1; charno = 1UL;
+ dk3strkv_stm_reset(&stm);
+ while(cc) {
+ if(*ptr) { $? ". begin of loop \"%!ds\"", ptr
+ icl = dk3strkv_classify(*ptr); $? ". icl = %d", icl
+ act = dk3strkv_stm_step(&stm, icl); $? ". act = %d", act
+ switch(act) {
+ case O_ERROR: { $? ". error"
+ error = 1;
+ } break;
+ case O_SQ: { $? ". O_SQ"
+ dk3str_cpy(ptr, &(ptr[1]));
+ if(*ptr) {
+ charno++;
+ } else {
+ cc = 0;
+ error = 1;
+ dk3strkv_error_unexpected_eot(app, mycopy);
+ }
+ } break;
+ case O_SKEY: { $? ". O_SKEY"
+ if(i < (*szp)) {
+ kvp[i].key = ptr;
+ } else {
+ error = 1;
+ if(0 == rtm) {
+ rtm = 1;
+ dk3strkv_error_too_many(app, mycopy, charno);
+ }
+ }
+ } break;
+ case O_ENDKEY: { $? ". O_ENDKEY"
+ *ptr = dkT('\0');
+ } break;
+ case O_ENDCOUNT: { $? ". O_ENDCOUNT"
+ *ptr = dkT('\0');
+ i++;
+ } break;
+ case O_ENDVAL: { $? ". O_ENDVAL"
+ *ptr = dkT('\0');
+ i++;
+ } break;
+ case O_SVAL: { $? ". O_SVAL"
+ if(i < (*szp)) {
+ kvp[i].val = ptr;
+ } else {
+ error = 1;
+ if(0 == rtm) {
+ rtm = 1;
+ dk3strkv_error_too_many(app, mycopy, charno);
+ }
+ }
+ } break;
+ case O_SQ_SVAL: { $? ". O_SQ_SVAL"
+ dk3str_cpy(ptr, &(ptr[1]));
+ if(*ptr) {
+ charno++;
+ if(i < (*szp)) {
+ kvp[i].val = ptr;
+ } else {
+ error = 1;
+ if(0 == rtm) {
+ rtm = 1;
+ dk3strkv_error_too_many(app, mycopy, charno);
+ }
+ }
+ } else {
+ cc = 0;
+ error = 1;
+ dk3strkv_error_unexpected_eot(app, mycopy);
+ }
+ } break;
+ case O_SEVAL: { $? ". O_SEVAL"
+ *ptr = dkT('\0');
+ if(i < (*szp)) {
+ kvp[i].val = ptr;
+ i++;
+ } else {
+ error = 1;
+ if(0 == rtm) {
+ rtm = 1;
+ dk3strkv_error_too_many(app, mycopy, charno);
+ }
+ }
+ } break;
+ }
+ ptr++;
+ charno++;
+ } else {
+ cc = 0;
+ }
+ }
+ switch(stm) {
+ case ST_START: { $? ". nothing to finish"
+ if(0 == error) {
+ back = 1;
+ *szp = i;
+ }
+ } break;
+ case ST_KEY: { $? ". finish key"
+ if(0 == error) {
+ i++;
+ back = 1;
+ *szp = i;
+ }
+ } break;
+ case ST_VALUE: { $? ". finish value"
+ if(0 == error) {
+ i++;
+ back = 1;
+ *szp = i;
+ }
+ } break;
+ }
+ dk3_release(mycopy);
+ }
+ } else {
+ if((kvp) && (szp) && (!(il))) {
+ *szp = 0;
+ back = 1;
+ }
+ } $? "- dk3str_to_key_value %d", back
+ return back;
+}
+
+
+
diff --git a/support/dktools/dk3strkv.h b/support/dktools/dk3strkv.h
new file mode 100644
index 0000000000..0e1ded43b4
--- /dev/null
+++ b/support/dktools/dk3strkv.h
@@ -0,0 +1,44 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3strkv.ctr
+*/
+
+/** @file dk3strkv.h Header file for the dk3strkv module.
+*/
+
+#ifndef DK3STRKV_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3STRKV_H_INCLUDED 1
+
+
+#line 4 "dk3strkv.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert input line into key value pairs.
+ @param kvp Array of key value structures for results.
+ @param szp Size of array (in), used elements (out).
+ @param il Input line to process.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success (number of elements in sz), 0 on error.
+*/
+int
+dk3str_to_key_value(
+ dk3_key_value_t *kvp,
+ size_t *szp,
+ dkChar *il,
+ dk3_app_t *app
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3strm.c b/support/dktools/dk3strm.c
new file mode 100644
index 0000000000..2e465f5710
--- /dev/null
+++ b/support/dktools/dk3strm.c
@@ -0,0 +1,2808 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3strm.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3strm.c The dk3strm module.
+*/
+
+
+#line 424 "dk3strm.ctr"
+
+#include "dk3all.h"
+
+
+
+
+
+#line 429 "dk3strm.ctr"
+
+
+
+#ifndef BUFSIZ
+#define BUFSIZ 8192
+#endif
+
+
+
+#if 0
+/** Low-level stream function to deal with bzip2 compression.
+ Closing the stream also closes the bzip2-file.
+ @param api API structure.
+*/
+static
+void
+dk3stream_bz_fct(dk3_stream_api_t *api)
+{
+#if DK3_HAVE_BZLIB_H
+ BZFILE *b = NULL; /* Low level I/O object. */
+ int res = 0; /* Operation result. */
+#endif
+ api->suc = 0;
+ (api->res).sz = 0;
+ (api->res).ec = DK3_ERROR_NOT_SUPPORTED;
+#if DK3_HAVE_BZLIB_H
+ b = (BZFILE *)((api->arg).d);
+ (api->res).ec = 0;
+ switch(api->cmd) {
+ case DK3_STREAM_API_READ: {
+ if(((api->arg).b) && ((api->arg).sz) && ((api->arg).d)) {
+ res = BZ2_bzread(b, (api->arg).b, (api->arg).sz);
+ if(res > 0) {
+ api->suc = 1; (api->res).ec = 0; (api->res).sz = (size_t)res;
+ }
+ }
+ } break;
+ case DK3_STREAM_API_WRITE: {
+ if(((api->arg).b) && ((api->arg).sz) && ((api->arg).d)) {
+ res = BZ2_bzwrite(b, (api->arg).b, (api->arg).sz);
+ if(res > 0) {
+ (api->res).sz = (size_t)res;
+ if((size_t)res == (api->arg).sz) {
+ api->suc = 1; (api->res).ec = 0;
+ }
+ }
+ }
+ } break;
+ case DK3_STREAM_API_FLUSH: {
+ if((api->arg).d) {
+ BZ2_bzflush(b);
+ api->suc = 1; (api->res).ec = 0;
+ /*
+ As the library manual explains BZ2_bzflush() does nothing.
+ So we always return success.
+ */
+ }
+ } break;
+ case DK3_STREAM_API_AT_END: {
+
+ } break;
+ case DK3_STREAM_API_CLOSE: {
+ if((api->arg).d) {
+ BZ2_bzclose(b);
+ api->suc = 1; (api->res).ec = 0;
+ }
+ } break;
+ case DK3_STREAM_API_ZERO_IS_END: {
+ api->suc = 1; (api->res).ec = 0; /* Correct if necessary */
+ } break;
+ case DK3_STREAM_API_ERROR: {
+ } break;
+ }
+#endif
+}
+
+
+
+/** Low-level stream function to deal with bzip2 compression.
+ Closing the stream does not close the bzip2 file.
+ @param api API structure.
+*/
+static
+void
+dk3stream_bz_fct_no_close(dk3_stream_api_t *api)
+{
+ if(api->cmd != DK3_STREAM_API_CLOSE) {
+ dk3stream_bz_fct(api);
+ } else {
+ api->suc = 1; (api->res).ec = 0;
+ }
+}
+
+#endif
+
+#if 0
+
+/** Low-level stream function to deal with gzip compression.
+ Closing the stream also closes the gzip-file.
+ @param api API structure.
+*/
+static
+void
+dk3stream_gz_fct(dk3_stream_api_t *api)
+{
+#if DK3_HAVE_ZLIB_H
+ int res = 0; /* Operation result. */
+ gzFile g = NULL; /* Low-level I/O object. */
+#endif
+ api->suc = 0;
+ (api->res).sz = 0;
+ (api->res).ec = DK3_ERROR_NOT_SUPPORTED;
+#if DK3_HAVE_ZLIB_H
+ (api->res).ec = 0;
+ g = (gzFile)((api->arg).d);
+ switch(api->cmd) {
+ case DK3_STREAM_API_READ: {
+ if(((api->arg).b) && ((api->arg).sz) && ((api->arg).d)) {
+ res = gzread(g, (api->arg).b, (api->arg).sz);
+ if(res > 0) {
+ api->suc = 1; (api->res).ec = 0; (api->res).sz = (size_t)res;
+ }
+ }
+ } break;
+ case DK3_STREAM_API_WRITE: {
+ if(((api->arg).b) && ((api->arg).sz) && ((api->arg).d)) {
+ res = gzwrite(g, (api->arg).b, (api->arg).sz);
+ (api->res).sz = (size_t)res;
+ if((size_t)res == (api->arg).sz) {
+ api->suc = 1; (api->res).ec = 0;
+ }
+ }
+ } break;
+ case DK3_STREAM_API_FLUSH: {
+ if((api->arg).d) {
+ if(gzflush(g, Z_FULL_FLUSH) == Z_OK) {
+ api->suc = 1; (api->res).ec = 0;
+ }
+ }
+ } break;
+ case DK3_STREAM_API_AT_END: {
+ if((api->arg).d) {
+ if(gzeof(g) == 1) {
+ api->suc = 1;
+ }
+ }
+ } break;
+ case DK3_STREAM_API_CLOSE: {
+ if((api->arg).d) {
+ if(gzclose(g) == Z_OK) {
+ api->suc = 1;
+ }
+ }
+ } break;
+ case DK3_STREAM_API_ZERO_IS_END: {
+ api->suc = 0;
+ } break;
+ case DK3_STREAM_API_ERROR: {
+ api->suc = 0;
+ } break;
+ }
+#endif
+}
+
+
+
+/** Low-level stream function to deal with gzip compression.
+ Closing the stream does not close the gzip-file.
+ @param api API structure.
+*/
+static
+void
+dk3stream_gz_fct_no_close(dk3_stream_api_t *api)
+{
+ if(api->cmd != DK3_STREAM_API_CLOSE) {
+ dk3stream_gz_fct(api);
+ } else {
+ api->suc = 1; (api->res).ec = 0;
+ }
+}
+
+#endif
+
+
+
+/** Low-level stream function to deal with plain files.
+ Closing the stream also closes the file.
+ @param api API structure.
+*/
+static
+void
+dk3stream_file_fct(dk3_stream_api_t *api)
+{
+ FILE *fipo = NULL; /* Low-level I/O object. */
+ size_t res = 0; /* Operation result. */
+
+
+#line 625 "dk3strm.ctr"
+ api->suc = 0;
+ (api->res).sz = 0;
+ (api->res).ec = 0;
+ switch(api->cmd) {
+ case DK3_STREAM_API_READ: {
+
+#line 630 "dk3strm.ctr"
+ if(((api->arg).b) && ((api->arg).sz) && ((api->arg).d)) {
+ fipo = (FILE *)((api->arg).d);
+#if DK3_ON_WINDOWS
+ res = fread((api->arg).b, 1, (api->arg).sz, fipo);
+ if(res) {
+ api->suc = 1; (api->res).ec = 0; (api->res).sz = res;
+ } else {
+ if(!ferror(fipo)) {
+ api->suc = 1; (api->res).ec = 0;
+ }
+ }
+#else
+#if DK3_HAVE_FREAD
+ res = fread((api->arg).b, 1, (api->arg).sz, fipo);
+ if(res) {
+ api->suc = 1; (api->res).ec = 0; (api->res).sz = res;
+ } else {
+ if(!ferror(fipo)) {
+ api->suc = 1; (api->res).ec = 0;
+ }
+ }
+#else
+#if DK3_HAVE__FREAD
+ res = _fread((api->arg).b, 1, (api->arg).sz, fipo);
+ if(res) {
+ api->suc = 1; (api->res).ec = 0; (api->res).sz = res;
+ } else {
+ if(!ferror(fipo)) {
+ api->suc = 1; (api->res).ec = 0;
+ }
+ }
+#else
+#error "No fread() function!"
+#endif
+#endif
+#endif
+ }
+ } break;
+ case DK3_STREAM_API_WRITE: {
+
+#line 669 "dk3strm.ctr"
+ if(((api->arg).b) && ((api->arg).sz) && ((api->arg).d)) {
+ fipo = (FILE *)((api->arg).d);
+#if DK3_ON_WINDOWS
+ res = fwrite((api->arg).b, 1, (api->arg).sz, fipo);
+ (api->res).sz = res;
+ if(res == (api->arg).sz) {
+ api->suc = 1; (api->res).ec = 0;
+ }
+#else
+#if DK3_HAVE_FWRITE
+ res = fwrite((api->arg).b, 1, (api->arg).sz, fipo);
+ (api->res).sz = res;
+ if(res == (api->arg).sz) {
+ api->suc = 1; (api->res).ec = 0;
+ }
+#else
+#if DK3_HAVE__FWRITE
+ res = _fwrite((api->arg).b, 1, (api->arg).sz, fipo);
+ if(res == (api->arg).sz) {
+ api->suc = 1; (api->res).ec = 0; (api->res).sz = res;
+ }
+#else
+#error "No fwrite() function!"
+#endif
+#endif
+#endif
+ }
+ } break;
+ case DK3_STREAM_API_FLUSH: {
+
+#line 698 "dk3strm.ctr"
+ if((api->arg).d) {
+ fipo = (FILE *)((api->arg).d);
+ if(fflush(fipo) == 0) {
+ api->suc = 1; (api->res).ec = 0;
+ }
+ }
+ } break;
+ case DK3_STREAM_API_AT_END: {
+
+#line 706 "dk3strm.ctr"
+ if((api->arg).d) {
+ fipo = (FILE *)((api->arg).d);
+ if(feof(fipo)) {
+ api->suc = 1; (api->res).ec = 0;
+ }
+ }
+ } break;
+ case DK3_STREAM_API_CLOSE: {
+
+#line 714 "dk3strm.ctr"
+ if((api->arg).d) {
+ fipo = (FILE *)((api->arg).d);
+ if(fclose(fipo) == 0) {
+ api->suc = 1; (api->res).ec = 0;
+ }
+ }
+ } break;
+ case DK3_STREAM_API_ZERO_IS_END: {
+
+#line 722 "dk3strm.ctr"
+ if((api->arg).d) {
+ api->suc = 1; (api->res).ec = 0;
+ }
+ } break;
+ case DK3_STREAM_API_ERROR: {
+
+#line 727 "dk3strm.ctr"
+ if((api->arg).d) {
+ fipo = (FILE *)((api->arg).d);
+ if(ferror(fipo)) {
+ api->suc = 1; (api->res).ec = 0;
+ }
+ }
+ } break;
+ }
+
+#line 735 "dk3strm.ctr"
+}
+
+
+
+/** Low-level stream function to deal with plain files.
+ Closing the stream does not close the file.
+ @param api API structure.
+*/
+static
+void
+dk3stream_file_fct_no_close(dk3_stream_api_t *api)
+{
+
+#line 747 "dk3strm.ctr"
+ if(api->cmd != DK3_STREAM_API_CLOSE) {
+ dk3stream_file_fct(api);
+ } else {
+ api->suc = 1; (api->res).ec = 0;
+ }
+
+#line 752 "dk3strm.ctr"
+}
+
+
+
+/** Initialize stream API structure.
+ @param api Structure to initialize.
+*/
+static
+void
+dk3stream_api_init(dk3_stream_api_t *api)
+{
+
+#line 763 "dk3strm.ctr"
+ if(api) {
+ api->cmd = 0;
+ api->suc = 0;
+ (api->arg).b = NULL;
+ (api->arg).sz = 0;
+ (api->arg).d = NULL;
+ (api->res).sz = 0;
+ (api->res).ec = 0;
+ }
+
+#line 772 "dk3strm.ctr"
+}
+
+
+
+/** Delete stream, release memory.
+ @param st Stream to delete.
+*/
+static
+void
+dk3stream_delete_stream(dk3_stream_t *st)
+{
+
+#line 783 "dk3strm.ctr"
+ if(st) {
+ dk3_release(st->ib);
+ dk3_release(st->ob);
+ dk3_delete(st);
+ }
+
+#line 788 "dk3strm.ctr"
+}
+
+
+
+/** Flush stream.
+ @param st Stream to flush.
+ @param fd Flag: Flush downstream object.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3stream_do_flush(dk3_stream_t *st, int fd)
+{
+ int back = 0;
+ dk3_stream_api_t api;
+
+
+#line 804 "dk3strm.ctr"
+ if(st) {
+ back = 1;
+ st->ec = 0;
+ if((st->fl) & DK3_STREAM_FLAG_WRITE) {
+ if(st->us_ob) {
+ dk3stream_api_init(&api);
+ api.cmd = DK3_STREAM_API_WRITE;
+ api.arg.b = st->ob;
+ api.arg.sz = st->us_ob;
+ api.arg.d = st->d;
+ (*(st->f))(&api);
+ if(!(api.suc)) {
+ st->ec = api.res.ec;
+ back = 0;
+ if(st->app) {
+ /* ERROR: Failed to write data! */
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 120);
+ }
+ }
+ }
+ st->us_ob = 0;
+ if(fd) {
+ dk3stream_api_init(&api);
+ api.cmd = DK3_STREAM_API_FLUSH;
+ api.arg.d = st->d;
+ (*(st->f))(&api);
+ if(!(api.suc)) {
+ if(back) {
+ if(st->app) {
+ /* ERROR: Flush failed! */
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 121);
+ }
+ st->ec = api.res.ec;
+ }
+ back = 0;
+ }
+ }
+ }
+ }
+
+#line 843 "dk3strm.ctr"
+ return back;
+}
+
+
+
+/** Open new stream, allocate memory.
+ @param app Application structure, used for diagnostics.
+ @return Pointer to new stream on success, NULL on error.
+*/
+static
+dk3_stream_t *
+dk3stream_new_stream(dk3_app_t *app)
+{
+ dk3_stream_t *back = NULL;
+
+
+#line 858 "dk3strm.ctr"
+ back = dk3_new_app(dk3_stream_t,1,app);
+ if(back) {
+ back->app = NULL;
+ back->d = NULL;
+ back->f = NULL;
+ back->ib = NULL;
+ back->ob = NULL;
+ back->wr = DK3_UM_0;
+ back->sz_ib = 0;
+ back->av_ib = 0;
+ back->us_ib = 0;
+ back->sz_ob = 0;
+ back->us_ob = 0;
+ back->fl = 0;
+ back->lf = 0;
+ back->fe = 0;
+ back->ec = 0;
+ back->oe = 0;
+ back->ze = 0;
+ back->er = 0;
+ back->ib = dk3_new_app(char,4096,app);
+ back->ob = dk3_new_app(char,4096,app);
+ if((back->ib) && (back->ob)) {
+ back->sz_ib = 4096;
+ back->sz_ob = 4096;
+ } else {
+ dk3stream_delete_stream(back);
+ back = NULL;
+ }
+ }
+
+#line 888 "dk3strm.ctr"
+ return back;
+}
+
+
+
+int
+dk3stream_close(dk3_stream_t *st)
+{
+ int back = 0;
+ dk3_stream_api_t api;
+
+
+#line 899 "dk3strm.ctr"
+ if(st) {
+ back = dk3stream_do_flush(st, 1);
+ dk3stream_api_init(&api);
+ api.cmd = DK3_STREAM_API_CLOSE;
+ api.arg.d = st->d;
+ (*(st->f))(&api);
+ if(!(api.suc)) {
+ back = 0;
+ if(st->app) {
+ /* ERROR: Failed to close stream data object! */
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 122);
+ }
+ }
+ st->d = NULL; st->f = NULL; st->app = NULL;
+ dk3stream_delete_stream(st);
+ }
+
+#line 915 "dk3strm.ctr"
+ return back;
+}
+
+
+
+dk3_stream_t *
+dk3stream_open_app(void *d, dk3_stream_api_fct_t *f, int fl, dk3_app_t *app)
+{
+ dk3_stream_t *back = NULL;
+ dk3_stream_api_t api;
+
+
+#line 926 "dk3strm.ctr"
+ if((d) && (f)) {
+ back = dk3stream_new_stream(app);
+ if(back) {
+ back->app = app;
+ back->d = d;
+ back->f = f;
+ back->fl = fl;
+ dk3stream_api_init(&api);
+ api.cmd = DK3_STREAM_API_ZERO_IS_END;
+ api.arg.d = d;
+ (*f)(&api);
+ if(api.suc) {
+ back->ze = 1;
+ }
+ }
+ }
+
+#line 942 "dk3strm.ctr"
+ return back;
+}
+
+
+
+/** Write one byte.
+ @param st Stream to write to.
+ @param ch Byte to write.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3stream_my_write_byte(dk3_stream_t *st, char ch)
+{
+ int back = 1;
+ int fld = 0; /* Flag: Flush downwards. */
+
+
+#line 959 "dk3strm.ctr"
+ (st->ob)[st->us_ob] = ch;
+ st->us_ob += 1;
+ st->wr += DK3_UM_1;
+ if((st->us_ob == st->sz_ob) || ((ch == '\n') && (st->lf)))
+ {
+ if(ch == '\n') { if(st->lf == 2) { fld = 1; } }
+ back = dk3stream_do_flush(st, fld);
+ }
+
+#line 967 "dk3strm.ctr"
+ return back;
+}
+
+
+
+size_t
+dk3stream_write_bytes(dk3_stream_t *st, char const *sb, size_t sz)
+{
+ size_t back = 0;
+ char const *sp = NULL; /* Source pointer. */
+ size_t l = 0; /* Bytes remaining. */
+
+
+#line 979 "dk3strm.ctr"
+ if((st) && (sb) && (sz)) {
+ if((st->fl) & DK3_STREAM_FLAG_WRITE) {
+ sp = sb; l = sz;
+ while(l--) {
+ if(dk3stream_my_write_byte(st, *sp)) {
+ back++;
+ }
+ sp++;
+ }
+ } else {
+ if(st->app) {
+ /* ERROR: Stream not opened for write operations! */
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 123);
+ }
+ }
+ }
+
+#line 995 "dk3strm.ctr"
+ return back;
+}
+
+
+
+/** Read one byte from buffer, reload buffer if necessary.
+ @param st Stream to read from.
+ @param cp One-byte buffer for destination.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3stream_my_read_byte(dk3_stream_t *st, char *cp)
+{
+ int back = 0;
+ dk3_stream_api_t api;
+
+
+#line 1012 "dk3strm.ctr"
+ if(st->us_ib >= st->av_ib) {
+
+#line 1013 "dk3strm.ctr"
+ st->us_ib = 0;
+ st->av_ib = 0;
+ dk3stream_api_init(&api);
+ api.cmd = DK3_STREAM_API_READ;
+ api.arg.b = st->ib;
+ api.arg.sz = st->sz_ib;
+ api.arg.d = st->d;
+ (*(st->f))(&api);
+ if(api.suc) {
+
+#line 1022 "dk3strm.ctr"
+ st->av_ib = api.res.sz;
+ if(st->av_ib) {
+
+#line 1024 "dk3strm.ctr"
+ if(st->av_ib < st->sz_ib) {
+
+#line 1025 "dk3strm.ctr"
+ dk3stream_api_init(&api);
+ api.cmd = DK3_STREAM_API_AT_END;
+ api.arg.d = st->d;
+ (*(st->f))(&api);
+ if(api.suc) {
+
+#line 1030 "dk3strm.ctr"
+ st->fe = 1;
+ }
+ }
+ } else {
+
+#line 1034 "dk3strm.ctr"
+ if(st->ze) {
+ st->fe = 1; /* End of input reached. */
+ } else {
+ dk3stream_api_init(&api);
+ api.cmd = DK3_STREAM_API_ERROR;
+ api.arg.d = st->d;
+ (*(st->f))(&api);
+ if(api.suc) {
+ st->er = 1;
+ st->fe = 1;
+ }
+ }
+ }
+ } else {
+
+#line 1048 "dk3strm.ctr"
+ st->ec = api.res.ec;
+ st->fe = 1; /* Error found, end of input data. */
+ dk3stream_api_init(&api);
+ api.cmd = DK3_STREAM_API_AT_END;
+ api.arg.d = st->d;
+ (*(st->f))(&api);
+ if(api.suc) {
+ st->ec = 0;
+ } else {
+ if(st->app) {
+ /* ERROR: Read operation failed! */
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 124);
+ }
+ st->er = 1;
+ }
+ }
+ }
+ if(st->us_ib < st->av_ib) {
+
+#line 1066 "dk3strm.ctr"
+ *cp = (st->ib)[st->us_ib];
+ st->us_ib += 1;
+ back = 1;
+ }
+
+#line 1070 "dk3strm.ctr"
+ return back;
+}
+
+
+
+size_t
+dk3stream_read_bytes(dk3_stream_t *st, char *db, size_t sz)
+{
+ size_t back = 0;
+ char c = 0x00; /* Current byte read. */
+ char *dp = NULL; /* Destination pointer. */
+ int cc = 0; /* Flag: Can continue. */
+
+
+#line 1083 "dk3strm.ctr"
+ if((st) && (db) && (sz)) {
+ dp = db; cc = 1;
+ while((back < sz) && (cc)) {
+ if(dk3stream_my_read_byte(st, &c)) {
+ *(dp++) = c; back++;
+ } else {
+ cc = 0;
+ }
+ }
+ }
+
+#line 1093 "dk3strm.ctr"
+ return back;
+}
+
+
+
+int
+dk3stream_feof(dk3_stream_t const *st)
+{
+ int back = 0;
+ if(st) {
+ if(st->fe) {
+ if(st->us_ib >= st->av_ib) {
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3stream_c8_fgets(dk3_stream_t *st, char *db, size_t sz)
+{
+ int back = 0;
+ char *dp = NULL; /* Destination pointer. */
+ size_t l = 0; /* Number of bytes already found. */
+ int cc = 0; /* Flag: Can continue. */
+ char c = 0x00; /* Current character. */
+
+
+#line 1123 "dk3strm.ctr"
+ if((st) && (db) && (sz)) {
+ *db = '\0';
+ dp = db; l = 0; cc = 1;
+ while((l < (sz - 1)) && (cc)) {
+ if(dk3stream_my_read_byte(st, &c)) {
+ *(dp++) = c; l++;
+ if(c == '\n') { cc = 0; }
+ } else {
+ cc = 0;
+ }
+ }
+ if(l < sz) {
+ *dp = '\0';
+ } else {
+ db[sz - 1] = '\0';
+ }
+ if(l) { back = 1; }
+ }
+
+#line 1141 "dk3strm.ctr"
+ return back;
+}
+
+
+
+int
+dk3stream_c8_fputs(dk3_stream_t *st, char const *str)
+{
+ int back = 0;
+ char const *sp = NULL; /* Source pointer. */
+ if((st) && (str)) {
+ back = 1; sp = str;
+ while(*sp) {
+ if(!dk3stream_my_write_byte(st, *(sp++))) {
+ back = 0;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3stream_c16_fgets(dk3_stream_t *st, dk3_c16_t *db, size_t sz, int msbfirst)
+{
+ int back = 0;
+ int cc = 1; /* Flag: Can continue. */
+ int eo = 0; /* Flag: 0=first byte, 1=second byte */
+ int res = 0; /* Result from my_read_byte. */
+ int msbf = 0; /* Flag: MSB first. */
+ char c1 = 0x00; /* First byte. */
+ char c2 = 0x00; /* Second byte. */
+ dk3_c16_t *ptr = NULL; /* Pointer into destination buffer. */
+ size_t bt = 0; /* Number of characters read. */
+ unsigned char uc1; /* First byte as unsigned char. */
+ unsigned char uc2; /* Second byte as unsigned char. */
+ unsigned u1; /* First byte as unsigned. */
+ unsigned u2; /* Second byte as unsigned. */
+ if((st) && (db) && (sz)) {
+ back = 1; ptr = db; bt = 0; msbf = msbfirst; cc = 1; eo = 0;
+ while(cc) {
+#if VERSION_BEFORE_20150821
+ res = 0;
+#endif
+ if(eo) {
+ res = dk3stream_my_read_byte(st, &c2);
+ } else {
+ res = dk3stream_my_read_byte(st, &c1);
+ }
+ if(res) {
+ if(eo) {
+ eo = 0;
+ uc1 = (unsigned char)c1;
+ uc2 = (unsigned char)c2;
+ u1 = (unsigned)uc1;
+ u2 = (unsigned)uc2;
+ u1 &= 0x00FFU;
+ u2 &= 0x00FFU;
+ if(msbf) {
+ u1 = ((u1 << 8) & 0xFF00U) | u2;
+ } else {
+ u1 = ((u2 << 8) & 0xFF00U) | u1;
+ }
+ if(u1 != 0xFEFFU) {
+ if(u1 == 0xFFFEU) {
+ msbf = (msbf ? 0 : 1);
+ } else {
+ *(ptr++) = (dk3_c16_t)u1;
+ bt++;
+ if(u1 == (dk3_c16_t)'\n') {
+ cc = 0;
+ }
+ }
+ }
+ } else {
+ eo = 1;
+ }
+ } else {
+ cc = 0;
+ if(eo) { back = 0; }
+ }
+ if(bt >= (sz - 1)) { cc = 0; }
+ }
+ if(bt < sz) { *ptr = 0U; }
+ db[sz - 1] = 0U;
+ }
+ if(bt == 0) { back = 0; }
+ return back;
+}
+
+
+
+int
+dk3stream_c32_fgets(dk3_stream_t *st, dk3_c32_t *db, size_t sz, int msbfirst)
+{
+ int back = 0;
+ int cc = 1; /* Flag: Can continue. */
+ int eo = 0; /* Flag: 0=first byte, 1=second byte */
+ int res = 0; /* Result from my_read_byte. */
+ int msbf = 0; /* Flag: MSB first. */
+ char c1 = 0x00; /* First byte. */
+ char c2 = 0x00; /* Second byte. */
+ char c3 = 0x00; /* Third byte. */
+ char c4 = 0x00; /* Fourth byte. */
+ dk3_c32_t *ptr = NULL; /* Pointer into destination buffer. */
+ size_t bt = 0; /* Number of characters read. */
+ unsigned char uc1; /* First byte as unsigned char. */
+ unsigned char uc2; /* Second byte as unsigned char. */
+ unsigned char uc3; /* Third byte as unsigned char. */
+ unsigned char uc4; /* Fourth byte as unsigned char. */
+ unsigned long u1; /* First byte as unsigned. */
+ unsigned long u2; /* Second byte as unsigned. */
+ unsigned long u3; /* Third byte as unsigned. */
+ unsigned long u4; /* Fourth byte as unsigned. */
+
+ if((st) && (db) && (sz)) {
+ back = 1; ptr = db; bt = 0; msbf = msbfirst; cc = 1; eo = 0;
+ while(cc) {
+ res = 0;
+ switch(eo) {
+ case 0: {
+ res = dk3stream_my_read_byte(st, &c1);
+ } break;
+ case 1: {
+ res = dk3stream_my_read_byte(st, &c2);
+ } break;
+ case 2: {
+ res = dk3stream_my_read_byte(st, &c3);
+ } break;
+ case 3: {
+ res = dk3stream_my_read_byte(st, &c4);
+ } break;
+ }
+ if(res) {
+ eo++;
+ if(eo >= 4) {
+ eo = 0;
+ uc1 = (unsigned char)c1;
+ uc2 = (unsigned char)c2;
+ uc3 = (unsigned char)c3;
+ uc4 = (unsigned char)c4;
+ u1 = (unsigned long)uc1;
+ u2 = (unsigned long)uc2;
+ u3 = (unsigned long)uc3;
+ u4 = (unsigned long)uc4;
+ if(msbf) {
+ u1 = (u1 << 24) & 0xFF000000UL;
+ u2 = (u2 << 16) & 0x00FF0000UL;
+ u3 = (u2 << 8) & 0x0000FF00UL;
+ u4 = u4 & 0x000000FFUL;
+ } else {
+ u1 = u1 & 0x000000FFUL;
+ u2 = (u2 << 8) & 0x0000FF00UL;
+ u3 = (u3 << 16) & 0x00FF0000UL;
+ u4 = (u4 << 24) & 0xFF000000UL;
+ }
+ u1 = (u1 | u2 | u3 | u4);
+ if(u1 != 0x0000FEFFUL) {
+ if(u1 == 0x0000FFFEUL) {
+ msbf = (msbf ? 0 : 1);
+ } else {
+ *(ptr++) = u1; bt++;
+ if(u1 == 0x0000000AUL) {
+ cc = 0;
+ }
+ }
+ }
+ }
+ } else {
+ cc = 0;
+ if(eo) { back = 0; }
+ }
+ if(bt >= (sz - 1)) { cc = 0; }
+ }
+ if(bt < sz) { *ptr = 0UL; }
+ db[sz - 1] = 0UL;
+ }
+ if(bt == 0) { back = 0; }
+ return back;
+}
+
+
+
+void
+dk3stream_set_output_encoding(dk3_stream_t *st, int oe)
+{
+ if(st) {
+ switch(oe) {
+ case DK3_FILE_ENCODING_ASCII:
+ case DK3_FILE_ENCODING_UTF8:
+ case DK3_FILE_ENCODING_UTF16_MSB_FIRST:
+ case DK3_FILE_ENCODING_UTF16_LSB_FIRST:
+ case DK3_FILE_ENCODING_UNICODE_MSB_FIRST:
+ case DK3_FILE_ENCODING_UNICODE_LSB_FIRST:
+ {
+ st->oe = oe;
+ } break;
+ default:
+ {
+ if(st->app) {
+ /* ERROR: Illegal output encoding! */
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 114);
+ }
+ } break;
+ }
+ }
+}
+
+
+
+/** Write one 16-bit character to stream.
+ @param st Output stream.
+ @param c16 Character to write.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3stream_my_write_16(dk3_stream_t *st, dk3_c16_t c16)
+{
+ int back = 0;
+ switch(st->oe) {
+ case DK3_FILE_ENCODING_UTF16_MSB_FIRST: {
+ if(dk3stream_my_write_byte(st, (char)((c16 >> 8) & 0x00FFU))) {
+ if(dk3stream_my_write_byte(st, (char)(c16 & 0x00FFU))) {
+ back = 1;
+ }
+ }
+ } break;
+ case DK3_FILE_ENCODING_UTF16_LSB_FIRST: {
+ if(dk3stream_my_write_byte(st, (char)(c16 & 0x00FFU))) {
+ if(dk3stream_my_write_byte(st, (char)((c16 >> 8) & 0x00FFU))) {
+ back = 1;
+ }
+ }
+ } break;
+ }
+ return back;
+}
+
+
+
+/** Write one 32-bit character to output stream.
+ @param st Stream.
+ @param c32 Character to write.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3stream_my_write_32(dk3_stream_t *st, dk3_c32_t c32)
+{
+ int back = 0;
+ switch(st->oe) {
+ case DK3_FILE_ENCODING_UNICODE_MSB_FIRST: {
+ if(dk3stream_my_write_byte(st, (char)((c32 >> 24) & 0x000000FFUL))) {
+ if(dk3stream_my_write_byte(st, (char)((c32 >> 16) & 0x000000FFUL))) {
+ if(dk3stream_my_write_byte(st, (char)((c32 >> 8) & 0x000000FFUL))) {
+ if(dk3stream_my_write_byte(st, (char)(c32 & 0x000000FFUL))) {
+ back = 1;
+ }
+ }
+ }
+ }
+ } break;
+ case DK3_FILE_ENCODING_UNICODE_LSB_FIRST: {
+ if(dk3stream_my_write_byte(st, (char)(c32 & 0x000000FFUL))) {
+ if(dk3stream_my_write_byte(st, (char)((c32 >> 8) & 0x000000FFUL))) {
+ if(dk3stream_my_write_byte(st, (char)((c32 >> 16) & 0x000000FFUL))) {
+ if(dk3stream_my_write_byte(st, (char)((c32 >> 24) & 0x000000FFUL))) {
+ back = 1;
+ }
+ }
+ }
+ }
+ } break;
+ }
+ return back;
+}
+
+
+
+int
+dk3stream_fputc_c32(dk3_stream_t *st, dk3_c32_t c32, int *err_enc_rep)
+{
+ int back = 0;
+ dk3_c16_t myc16[4]; /* Buffer for UTF-16 encoding. */
+ unsigned char myuc[16]; /* Buffer for UTF-8 encoding. */
+ size_t l = 0; /* Length of encoded string. */
+ size_t i = 0; /* Index of current element to write. */
+
+
+#line 1431 "dk3strm.ctr"
+ switch(st->oe) {
+ case DK3_FILE_ENCODING_UNICODE_MSB_FIRST:
+ case DK3_FILE_ENCODING_UNICODE_LSB_FIRST: {
+ back = dk3stream_my_write_32(st, c32);
+ } break;
+ case DK3_FILE_ENCODING_UTF16_MSB_FIRST:
+ case DK3_FILE_ENCODING_UTF16_LSB_FIRST: {
+ l = dk3enc_uc2utf16(c32, myc16, 4);
+ if(l) {
+ back = 1;
+ for(i = 0; i < l; i++) {
+ if(!dk3stream_my_write_16(st, myc16[i])) {
+ back = 1;
+ }
+ }
+ } else {
+ if(!(*err_enc_rep)) {
+ if(st->app) {
+
+#line 1449 "dk3strm.ctr"
+ /* ERROR: UTF-16 encode failed! */
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 116);
+ }
+ } *err_enc_rep = 1;
+ }
+ } break;
+ case DK3_FILE_ENCODING_ASCII: {
+ if(c32 < (dk3_c32_t)0x00000100UL) {
+ back = dk3stream_my_write_byte(st, (char)(c32 & 0x000000FFUL));
+ } else {
+ if(!(*err_enc_rep)) {
+ if(st->app) {
+ /* ERROR: Character out of range! */
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 117);
+ }
+ } *err_enc_rep = 1;
+ }
+ } break;
+ case DK3_FILE_ENCODING_UTF8: {
+ l = dk3enc_uc2utf8(c32, myuc, 16);
+ if(l) {
+ i = dk3stream_write_bytes(st, (char const *)myuc, l);
+ if(i == l) { back = 1; }
+ } else {
+ if(!(*err_enc_rep)) {
+ if(st->app) {
+ /* ERROR: UTF-8 encode failed! */
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 115);
+ }
+ } *err_enc_rep = 1;
+ }
+ } break;
+ }
+
+#line 1482 "dk3strm.ctr"
+ return back;
+}
+
+
+
+int
+dk3stream_write_byte_order_marker(dk3_stream_t *st)
+{
+ int back = 0;
+ if(st) {
+ switch(st->oe) {
+ case DK3_FILE_ENCODING_UTF16_MSB_FIRST:
+ case DK3_FILE_ENCODING_UTF16_LSB_FIRST:
+ {
+ back = dk3stream_my_write_16(st, 0xFEFFU);
+ } break;
+ case DK3_FILE_ENCODING_UNICODE_MSB_FIRST:
+ case DK3_FILE_ENCODING_UNICODE_LSB_FIRST:
+ {
+ back = dk3stream_my_write_32(st, 0x0000FEFFUL);
+ } break;
+ default: {
+ back = 1;
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3stream_write_byte_order_marker_if_necessary(dk3_stream_t *st, int se)
+{
+ int back = 1;
+ switch(st->oe) {
+ case DK3_FILE_ENCODING_UTF16_MSB_FIRST:
+ case DK3_FILE_ENCODING_UTF16_LSB_FIRST:
+ case DK3_FILE_ENCODING_UNICODE_MSB_FIRST:
+ case DK3_FILE_ENCODING_UNICODE_LSB_FIRST: {
+ back = dk3stream_write_byte_order_marker(st);
+ } break;
+ case DK3_FILE_ENCODING_UTF8: {
+ if(DK3_FILE_ENCODING_UTF8 != se) {
+ back = dk3stream_write_byte_order_marker(st);
+ }
+ } break;
+ default: {
+ } break;
+ }
+ return back;
+}
+
+
+int
+dk3stream_fputs_c8_plain(dk3_stream_t *st, char const *s)
+{
+ int back = 0;
+ int err_rep_enc = 0; /* Flag: Encoding error reported. */
+ char const *sp = NULL; /* Source pointer. */
+ char c = 0x00; /* Current character. */
+ unsigned char uc = 0x00; /* Unsigned version of current char. */
+ unsigned long ul = 0UL; /* 32-bit version of current char. */
+ if((st) && (s)) {
+ switch(st->oe) {
+ case DK3_FILE_ENCODING_ASCII: {
+ back = dk3stream_c8_fputs(st, s);
+ } break;
+ default: {
+ back = 1;
+ sp = s;
+ while(*sp) {
+ c = *(sp++);
+ uc = (unsigned char)c;
+ ul = (unsigned long)uc;
+ ul &= 0x000000FFUL;
+ if(!dk3stream_fputc_c32(st, ul, &err_rep_enc)) { back = 0; }
+ }
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3stream_fputs_c8_utf8(dk3_stream_t *st, char const *s)
+{
+ int back = 0;
+ int err_rep_dec = 0; /* Flag: Decoding error reported. */
+ int err_rep_enc = 0; /* Flag: Encoding error reported. */
+ unsigned char const *sp = NULL; /* Source pointer. */
+ dk3_c32_t c32 = 0UL; /* 32-bit version of current char. */
+ size_t sl = 0; /* Remaining source bytes. */
+ size_t used = 0; /* Bytes used. */
+ if((st) && (s)) {
+ switch(st->oe) {
+ case DK3_FILE_ENCODING_UTF8: {
+ back = dk3stream_c8_fputs(st, s);
+ } break;
+ default: {
+ back = 1;
+ sp = (unsigned char const *)s; sl = dk3str_c8_len(s);
+ while(sl) {
+ used = 0;
+ if(dk3enc_utf82uc(&c32, sp, sl, &used)) {
+ if(used) {
+ if(!dk3stream_fputc_c32(st, c32, &err_rep_enc)) { back = 0; }
+ if(sl >= used) {
+ sl = sl - used;
+ sp = &(sp[used]);
+ } else {
+ sl = 0;
+ }
+ } else {
+ sl = 0; back = 0;
+ if(!err_rep_dec) {
+ if(st->app) {
+ /* ERROR: UTF-8 decode failed! */
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118);
+ }
+ } err_rep_dec = 1;
+ }
+ } else {
+ sl = 0; back = 0;
+ if(!err_rep_dec) {
+ if(st->app) {
+ /* ERROR: UTF-8 decode failed! */
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118);
+ }
+ } err_rep_dec = 1;
+ }
+ }
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3stream_fputs_c16(dk3_stream_t *st, dk3_c16_t const *s)
+{
+ int back = 0;
+ int err_rep_dec = 0; /* Flag: Decoding error reported. */
+ int err_rep_enc = 0; /* Flag: Encoding error reported. */
+ dk3_c16_t const *sp = NULL; /* Source pointer. */
+ dk3_c32_t c32 = 0UL; /* 32-bit version of current char. */
+ size_t sl = 0; /* Remaining source bytes. */
+ size_t used = 0; /* Source bytes used. */
+ if((st) && (s)) {
+ switch(st->oe) {
+ case DK3_FILE_ENCODING_UTF16_MSB_FIRST:
+ case DK3_FILE_ENCODING_UTF16_LSB_FIRST: {
+ sp = s; back = 1;
+ while(*sp) { if(!dk3stream_my_write_16(st, *(sp++))) { back = 0; } }
+ } break;
+ default: {
+ sp = s; sl = dk3str_c16_len(s);
+ while(sl) {
+ used = 0;
+ if(dk3enc_utf162uc(&c32, sp, sl, &used)) {
+ if(used) {
+ if(!dk3stream_fputc_c32(st, c32, &err_rep_enc)) { back = 0; }
+ if(sl >= used) {
+ sl = sl - used;
+ sp = &(sp[used]);
+ } else {
+ sl = 0;
+ }
+ } else {
+ back = 0; sl = 0;
+ if(!err_rep_dec) {
+ if(st->app) {
+ /* ERROR: Decode UTF-16 failed! */
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 119);
+ }
+ } err_rep_dec = 1;
+ }
+ } else {
+ back = 0; sl = 0;
+ if(!err_rep_dec) {
+ if(st->app) {
+ /* ERROR: Decode UTF-16 failed! */
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 119);
+ }
+ } err_rep_dec = 1;
+ }
+ }
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3stream_fputs_c32(dk3_stream_t *st, dk3_c32_t const *s)
+{
+ int back = 0;
+ int err_rep_enc = 0; /* Flag: Encoding error reported. */
+ dk3_c32_t const *sp = NULL; /* Source pointer. */
+ if((st) && (s)) {
+ sp = s;
+ back = 1;
+ while(*sp) {
+ if(!dk3stream_fputc_c32(st, *(sp++), &err_rep_enc)) { back = 0; }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3stream_strputs(dk3_stream_t *st, dkChar const *s, int ie)
+{
+ int back = 0;
+
+
+#line 1704 "dk3strm.ctr"
+ if((st) && (s)) {
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ if(ie == DK3_ENCODING_UNICODE) {
+ back = dk3stream_fputs_c32(st, s);
+ } else {
+ if(st->app) {
+ /* ERROR: Encoding does not match character size! */
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 125);
+ }
+ }
+#else
+ if(ie == DK3_ENCODING_UTF16) {
+ back = dk3stream_fputs_c16(st, s);
+ } else {
+ if(st->app) {
+ /* ERROR: Encoding does not match character size! */
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 125);
+ }
+ }
+#endif
+#else
+ switch(ie) {
+ case DK3_ENCODING_PLAIN: {
+ back = dk3stream_fputs_c8_plain(st, s);
+ } break;
+ case DK3_ENCODING_UTF8: {
+ back = dk3stream_fputs_c8_utf8(st, s);
+ } break;
+ default: {
+ if(st->app) {
+ /* ERROR: Encoding does not match character size! */
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 125);
+ }
+ } break;
+ }
+#endif
+ }
+
+#line 1742 "dk3strm.ctr"
+ return back;
+}
+
+
+
+int
+dk3stream_strnl(dk3_stream_t *st)
+{
+ int back = 1;
+ int err_enc_rep = 0; /* Flag: Encoding error reported. */
+#if DK3_ON_WINDOWS
+ if(!dk3stream_fputc_c32(st, 0x0000000DUL, &err_enc_rep)) {
+ back = 0;
+ }
+#endif
+ if(!dk3stream_fputc_c32(st, 0x0000000AUL, &err_enc_rep)) {
+ back = 0;
+ }
+ return back;
+}
+
+
+
+int
+dk3stream_set_line_flush(dk3_stream_t *st, int fl)
+{
+ int back = 0;
+
+
+#line 1770 "dk3strm.ctr"
+ if(st) { st->lf = fl; back = 1; }
+
+#line 1771 "dk3strm.ctr"
+ return back;
+}
+
+
+
+dk3_um_t
+dk3stream_bytes_written(dk3_stream_t const *st)
+{
+ dk3_um_t back = DK3_UM_0;
+
+
+#line 1781 "dk3strm.ctr"
+ if(st) {
+ back = st->wr;
+ }
+
+#line 1784 "dk3strm.ctr"
+ return back;
+}
+
+
+
+dk3_stream_t *
+dk3stream_open_file_app(FILE *fi, int fl, dk3_app_t *app)
+{
+ dk3_stream_t *back = NULL;
+
+
+#line 1794 "dk3strm.ctr"
+ if(fi) {
+ back = dk3stream_open_app((void *)fi, dk3stream_file_fct_no_close, fl, app);
+ }
+
+#line 1797 "dk3strm.ctr"
+ return back;
+}
+
+
+#if 0
+
+#if DK3_HAVE_ZLIB_H
+dk3_stream_t *
+dk3stream_open_gz_app(gzFile g, int fl, dk3_app_t *app)
+{
+ dk3_stream_t *back = NULL;
+ if(g) {
+ back = dk3stream_open_app((void *)g, dk3stream_gz_fct_no_close, fl, app);
+ }
+ return back;
+}
+#endif
+
+#endif
+
+
+
+#if 0
+
+#if DK3_HAVE_BZLIB_H
+dk3_stream_t *
+dk3stream_open_bz2_app(BZFILE *b, int fl, dk3_app_t *app)
+{
+ dk3_stream_t *back = NULL;
+ if(b) {
+ back = dk3stream_open_app((void *)b, dk3stream_bz_fct_no_close, fl, app);
+ }
+ return back;
+}
+#endif
+
+#endif
+
+
+int
+dk3stream_process_chars(
+ dk3_stream_t *st,
+ void *obj,
+ dk3_char_handler_t *hf,
+ int ie
+)
+{
+ int back = 0;
+ int res; /* Handler function result. */
+ int cc; /* Flag: Can continue. */
+ int myie; /* Input encoding. */
+ int done; /* Flag: Character already handled. */
+#if VERSION_BEFORE_20150821
+ int surrogate; /* UTF-16 surrogate type. */
+#endif
+ char c1; /* First byte. */
+ char c2; /* Second byte. */
+ char c3; /* Third byte. */
+ char c4; /* Fourth byte. */
+ unsigned char u1; /* Current byte. */
+ dk3_c32_t uc1; /* First part of result. */
+ dk3_c32_t uc2; /* Second part of result. */
+ dk3_c32_t uc3; /* Third part of result. */
+ dk3_c32_t uc4; /* Fourth part of result. */
+ dk3_c32_t c32; /* Character found in decoding. */
+ unsigned long lineno; /* Current line number. */
+ unsigned long oldlineno = 0UL; /* Line number before start. */
+
+
+#line 1865 "dk3strm.ctr"
+ if((st) && (hf)) {
+ if(st->app) {
+
+#line 1867 "dk3strm.ctr"
+ oldlineno = dk3app_get_source_line((dk3_app_t *)(st->app));
+ dk3app_set_source_line((dk3_app_t *)(st->app), 1UL);
+ }
+ lineno = 1UL;
+ back = 1;
+#if VERSION_BEFORE_20150821
+ cc = 1;
+#endif
+ myie = ie;
+
+#line 1876 "dk3strm.ctr"
+ do {
+
+#line 1877 "dk3strm.ctr"
+ cc = 0;
+ done = 0;
+ c32 = 0UL;
+ switch(myie) {
+ case DK3_FILE_ENCODING_ASCII: {
+
+#line 1882 "dk3strm.ctr"
+ if(dk3stream_my_read_byte(st, &c1)) {
+
+#line 1883 "dk3strm.ctr"
+ cc = 1;
+ c32 = (dk3_c32_t)c1;
+ c32 &= 0x000000FFUL;
+ }
+ } break;
+ case DK3_FILE_ENCODING_UTF8: {
+
+#line 1889 "dk3strm.ctr"
+ if(dk3stream_my_read_byte(st, &c1)) {
+
+#line 1890 "dk3strm.ctr"
+ u1 = (unsigned char)c1;
+ if(u1 > 0x7F) {
+
+#line 1892 "dk3strm.ctr"
+ if((u1 & 0xE0) == 0xC0) {
+
+#line 1893 "dk3strm.ctr"
+ c32 = ((((dk3_c32_t)u1) << 6) & 0x000007C0UL);
+ if(dk3stream_my_read_byte(st, &c1)) {
+
+#line 1895 "dk3strm.ctr"
+ u1 = (unsigned char)c1;
+ c32 |= (((dk3_c32_t)u1) & 0x0000003FUL);
+ cc = 1;
+ } else {
+ /* ERROR: Incomplete sequence! */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118);
+ }
+ }
+ } else {
+ if((u1 & 0xF0) == 0xE0) {
+
+#line 1906 "dk3strm.ctr"
+ c32 = ((((dk3_c32_t)u1) << 12) & 0x0000F000UL);
+ if(dk3stream_my_read_byte(st, &c1)) {
+
+#line 1908 "dk3strm.ctr"
+ u1 = (unsigned char)c1;
+ c32 |= ((((dk3_c32_t)u1) << 6) & 0x00000FC0UL);
+ if(dk3stream_my_read_byte(st, &c1)) {
+
+#line 1911 "dk3strm.ctr"
+ u1 = (unsigned char)c1;
+ c32 |= (((dk3_c32_t)u1) & 0x0000003FUL);
+ cc = 1;
+ } else {
+ /* ERROR: Incomplete sequence! */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118);
+ }
+ }
+ } else {
+ /* ERROR: Incomplete sequence! */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118);
+ }
+ }
+ } else {
+ if((u1 & 0xF8) == 0xF0) {
+
+#line 1928 "dk3strm.ctr"
+ c32 = ((((dk3_c32_t)u1) << 18) & 0x001C0000UL);
+ if(dk3stream_my_read_byte(st, &c1)) {
+
+#line 1930 "dk3strm.ctr"
+ u1 = (unsigned char)c1;
+ c32 |= ((((dk3_c32_t)u1) << 12) & 0x0003F000UL);
+ if(dk3stream_my_read_byte(st, &c1)) {
+
+#line 1933 "dk3strm.ctr"
+ u1 = (unsigned char)c1;
+ c32 |= ((((dk3_c32_t)u1) << 6) & 0x00000FC0UL);
+ if(dk3stream_my_read_byte(st, &c1)) {
+
+#line 1936 "dk3strm.ctr"
+ u1 = (unsigned char)c1;
+ c32 |= (((dk3_c32_t)u1) & 0x0000003FUL);
+ cc = 1;
+ } else {
+ /* ERROR: Incomplete sequence */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118);
+ }
+ }
+ } else {
+ /* ERROR: Incomplete sequence */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118);
+ }
+ }
+ } else {
+ /* ERROR: Incomplete sequence */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118);
+ }
+ }
+ } else {
+ if((u1 & 0xFC) == 0xF8) {
+
+#line 1959 "dk3strm.ctr"
+ c32 = ((((dk3_c32_t)u1) << 24) & 0x03000000UL);
+ if(dk3stream_my_read_byte(st, &c1)) {
+
+#line 1961 "dk3strm.ctr"
+ u1 = (unsigned char)c1;
+ c32 |= ((((dk3_c32_t)u1) << 18) & 0x00FC0000UL);
+ if(dk3stream_my_read_byte(st, &c1)) {
+
+#line 1964 "dk3strm.ctr"
+ u1 = (unsigned char)c1;
+ c32 |= ((((dk3_c32_t)u1) << 12) & 0x0003F000UL);
+ if(dk3stream_my_read_byte(st, &c1)) {
+
+#line 1967 "dk3strm.ctr"
+ u1 = (unsigned char)c1;
+ c32 |= ((((dk3_c32_t)u1) << 6) & 0x00000FC0UL);
+ if(dk3stream_my_read_byte(st, &c1)) {
+
+#line 1970 "dk3strm.ctr"
+ u1 = (unsigned char)c1;
+ c32 |= (((dk3_c32_t)u1) & 0x0000003FUL);
+ cc = 1;
+ } else {
+ /* ERROR: Incomplete sequence */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118);
+ }
+ }
+ } else {
+ /* ERROR: Incomplete sequence */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118);
+ }
+ }
+ } else {
+ /* ERROR: Incomplete sequence */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118);
+ }
+ }
+ } else {
+ /* ERROR: Incomplete sequence */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118);
+ }
+ }
+ } else {
+ if((u1 & 0xFE) == 0xFC) {
+
+#line 1999 "dk3strm.ctr"
+ c32 = 0x40000000UL;
+ if(dk3stream_my_read_byte(st, &c1)) {
+
+#line 2001 "dk3strm.ctr"
+ u1 = (unsigned char)c1;
+ c32 |= ((((dk3_c32_t)u1) << 24) & 0x3F000000UL);
+ if(dk3stream_my_read_byte(st, &c1)) {
+
+#line 2004 "dk3strm.ctr"
+ u1 = (unsigned char)c1;
+ c32 |= ((((dk3_c32_t)u1) << 18) & 0x00FC0000UL);
+ if(dk3stream_my_read_byte(st, &c1)) {
+
+#line 2007 "dk3strm.ctr"
+ u1 = (unsigned char)c1;
+ c32 |= ((((dk3_c32_t)u1) << 12) & 0x0003F000UL);
+ if(dk3stream_my_read_byte(st, &c1)) {
+ u1 = (unsigned char)c1;
+
+#line 2011 "dk3strm.ctr"
+ c32 |= ((((dk3_c32_t)u1) << 6) & 0x00000FC0UL);
+ if(dk3stream_my_read_byte(st, &c1)) {
+ u1 = (unsigned char)c1;
+
+#line 2014 "dk3strm.ctr"
+ c32 |= (((dk3_c32_t)u1) & 0x0000003FUL);
+ cc = 1;
+ } else {
+ /* ERROR: Incomplete sequence */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118);
+ }
+ }
+ } else {
+ /* ERROR: Incomplete sequence */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118);
+ }
+ }
+ } else {
+ /* ERROR: Incomplete sequence */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118);
+ }
+ }
+ } else {
+ /* ERROR: Incomplete sequence */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118);
+ }
+ }
+ } else {
+ /* ERROR: Incomplete sequence */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118);
+ }
+ }
+ } else {
+ }
+ }
+ }
+ }
+ }
+ } else {
+ c32 = ((dk3_c32_t)u1) & 0x000000FFUL;
+ cc = 1;
+ }
+ }
+ } break;
+ case DK3_FILE_ENCODING_UTF16_MSB_FIRST:
+ case DK3_FILE_ENCODING_UTF16_LSB_FIRST:
+ {
+
+#line 2061 "dk3strm.ctr"
+#if VERSION_BEFORE_20150821
+ surrogate = 0;
+#endif
+ if(dk3stream_my_read_byte(st, &c1)) {
+
+#line 2065 "dk3strm.ctr"
+ if(dk3stream_my_read_byte(st, &c2)) {
+
+#line 2066 "dk3strm.ctr"
+ if(myie == DK3_FILE_ENCODING_UTF16_MSB_FIRST) {
+ uc1 = (((dk3_c32_t)c1) << 8) & 0x0000FF00UL;
+ uc2 = ((dk3_c32_t)c2) & 0x000000FFUL;
+ } else {
+ uc1 = (((dk3_c32_t)c2) << 8) & 0x0000FF00UL;
+ uc2 = ((dk3_c32_t)c1) & 0x000000FFUL;
+ }
+ c32 = (uc1 | uc2);
+
+#line 2074 "dk3strm.ctr"
+#if 0
+ if((c32 & 0x0000DC00UL) == 0x0000DC00UL)
+#else
+ if((c32 & 0x0000FC00UL) == 0x0000DC00UL)
+#endif
+ {
+
+#line 2080 "dk3strm.ctr"
+ if(dk3stream_my_read_byte(st, &c1)) {
+
+#line 2081 "dk3strm.ctr"
+ if(dk3stream_my_read_byte(st, &c2)) {
+
+#line 2082 "dk3strm.ctr"
+ if(myie == DK3_FILE_ENCODING_UTF16_MSB_FIRST) {
+ uc1 = (((dk3_c32_t)c1) << 8) & 0x0000FF00UL;
+ uc2 = ((dk3_c32_t)c2) & 0x000000FFUL;
+ } else {
+ uc1 = (((dk3_c32_t)c2) << 8) & 0x0000FF00UL;
+ uc2 = ((dk3_c32_t)c1) & 0x000000FFUL;
+ }
+ uc1 |= uc2;
+#if 0
+ if((uc1 & 0x0000DC00UL) == 0x0000D800UL)
+#else
+ if((uc1 & 0x0000FC00UL) == 0x0000D800UL)
+#endif
+ {
+ uc1 &= 0x000003FFUL;
+ uc1 = (uc1 << 10);
+ uc1 &= 0x000FFC00UL;
+ c32 &= 0x000003FFUL;
+ c32 |= uc1;
+ c32 += 0x00010000UL;
+ cc = 1;
+ } else {
+ /* ERROR: Decoding. */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 119);
+ }
+ }
+ } else {
+ /* ERROR: Incomplete sequence */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 119);
+ }
+ }
+ } else {
+ /* ERROR: Incomplete sequence */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 119);
+ }
+ }
+ } else {
+#if 0
+ if((c32 & 0x0000DC00UL) == 0x0000D800UL)
+#else
+ if((c32 & 0x0000FC00UL) == 0x0000D800UL)
+#endif
+ {
+
+#line 2128 "dk3strm.ctr"
+ if(dk3stream_my_read_byte(st, &c1)) {
+
+#line 2129 "dk3strm.ctr"
+ if(dk3stream_my_read_byte(st, &c2)) {
+
+#line 2130 "dk3strm.ctr"
+ if(myie == DK3_FILE_ENCODING_UTF16_MSB_FIRST) {
+ uc1 = (((dk3_c32_t)c1) << 8) & 0x0000FF00UL;
+ uc2 = ((dk3_c32_t)c2) & 0x000000FFUL;
+ } else {
+ uc1 = (((dk3_c32_t)c2) << 8) & 0x0000FF00UL;
+ uc2 = ((dk3_c32_t)c1) & 0x000000FFUL;
+ }
+ uc1 |= uc2;
+#if 0
+ if((uc1 & 0x0000DC00UL) == 0x0000DC00UL)
+#else
+ if((uc1 & 0x0000DF00UL) == 0x0000DC00UL)
+#endif
+ {
+ c32 &= 0x000003FFUL;
+ c32 = (c32 << 10);
+ c32 &= 0x000FFC00UL;
+ uc1 &= 0x000003FFUL;
+ c32 |= uc1;
+ c32 += 0x00010000UL;
+ cc = 1;
+ } else {
+ /* ERROR: Decoding. */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 119);
+ }
+ }
+ } else {
+ /* ERROR: Incomplete sequence */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 119);
+ }
+ }
+ } else {
+ /* ERROR: Incomplete sequence */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 119);
+ }
+ }
+ } else {
+
+#line 2170 "dk3strm.ctr"
+ cc = 1;
+ }
+ }
+ } else {
+ /* ERROR: Incomplete word. */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 119);
+ }
+ }
+ }
+ }
+ break;
+ case DK3_FILE_ENCODING_UNICODE_MSB_FIRST:
+ case DK3_FILE_ENCODING_UNICODE_LSB_FIRST:
+ {
+
+#line 2185 "dk3strm.ctr"
+ if(dk3stream_my_read_byte(st, &c1)) {
+
+#line 2186 "dk3strm.ctr"
+ if(dk3stream_my_read_byte(st, &c2)) {
+
+#line 2187 "dk3strm.ctr"
+ if(dk3stream_my_read_byte(st, &c3)) {
+
+#line 2188 "dk3strm.ctr"
+ if(dk3stream_my_read_byte(st, &c4)) {
+
+#line 2189 "dk3strm.ctr"
+ if(myie == DK3_FILE_ENCODING_UNICODE_MSB_FIRST) {
+ uc1 = (((dk3_c32_t)c1) << 24) & 0xFF000000UL;
+ uc2 = (((dk3_c32_t)c2) << 16) & 0x00FF0000UL;
+ uc3 = (((dk3_c32_t)c3) << 8) & 0x0000FF00UL;
+ uc4 = (((dk3_c32_t)c4) ) & 0x000000FFUL;
+ } else {
+ uc1 = (((dk3_c32_t)c4) << 24) & 0xFF000000UL;
+ uc2 = (((dk3_c32_t)c3) << 16) & 0x00FF0000UL;
+ uc3 = (((dk3_c32_t)c2) << 8) & 0x0000FF00UL;
+ uc4 = (((dk3_c32_t)c1) ) & 0x000000FFUL;
+ }
+ cc = 1;
+ c32 = (uc1 | uc2 | uc3 | uc4);
+ } else {
+ /* ERROR: Incomplete DWORD */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 218);
+ }
+ }
+ } else {
+ /* ERROR: Incomplete DWORD */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 218);
+ }
+ }
+ } else {
+ /* ERROR: Incomplete DWORD */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 218);
+ }
+ }
+ }
+ }
+ break;
+ }
+ if(cc) {
+
+#line 2225 "dk3strm.ctr"
+ if(c32 != 0x0000FEFFUL) {
+
+#line 2226 "dk3strm.ctr"
+ switch(myie) {
+ case DK3_FILE_ENCODING_UTF16_MSB_FIRST: {
+ if(c32 == 0x0000FFFEUL) {
+
+#line 2229 "dk3strm.ctr"
+ myie = DK3_FILE_ENCODING_UTF16_LSB_FIRST;
+ done = 1;
+
+#line 2231 "dk3strm.ctr"
+ }
+ } break;
+ case DK3_FILE_ENCODING_UTF16_LSB_FIRST: {
+ if(c32 == 0x0000FFFEUL) {
+
+#line 2235 "dk3strm.ctr"
+ myie = DK3_FILE_ENCODING_UTF16_MSB_FIRST;
+ done = 1;
+
+#line 2237 "dk3strm.ctr"
+ }
+ } break;
+ case DK3_FILE_ENCODING_UNICODE_MSB_FIRST: {
+ if((unsigned long)c32 == 0xFFFE0000UL) {
+
+#line 2241 "dk3strm.ctr"
+ myie = DK3_FILE_ENCODING_UNICODE_LSB_FIRST;
+ done = 1;
+
+#line 2243 "dk3strm.ctr"
+ }
+ } break;
+ case DK3_FILE_ENCODING_UNICODE_LSB_FIRST: {
+ if((unsigned long)c32 == 0xFFFE0000UL) {
+
+#line 2247 "dk3strm.ctr"
+ myie = DK3_FILE_ENCODING_UNICODE_MSB_FIRST;
+ done = 1;
+
+#line 2249 "dk3strm.ctr"
+ }
+ } break;
+ }
+ if(!done) {
+
+#line 2253 "dk3strm.ctr"
+ res = (*hf)(obj, c32);
+ if(res < 1) { back = 0; if(res < 0) { cc = 0; } }
+ }
+ if(c32 == 0x0000000AUL) {
+
+#line 2257 "dk3strm.ctr"
+ lineno++;
+ /* Set line number */
+ if(st->app) {
+ dk3app_set_source_line((dk3_app_t *)(st->app), lineno);
+ }
+ }
+ }
+ }
+ } while(cc);
+ if(st->app) {
+ dk3app_set_source_line((dk3_app_t *)(st->app), oldlineno);
+ }
+ }
+
+#line 2270 "dk3strm.ctr"
+ return back;
+}
+
+
+
+/* NOTE: This function does not check the BOM at start of files.
+ Whenever applicable, use dk3stream_process_filename_chars_app()
+ instead.
+*/
+int
+dk3stream_process_file_chars_app(
+ void *obj,
+ dk3_char_handler_t *hf,
+ FILE *fipo,
+ dkChar const *fn,
+ int ie,
+ dk3_app_t *app
+)
+{
+ int back = 0;
+ dkChar const *oldsourcefile = NULL;
+ unsigned long oldsourceline = 0UL;
+ dk3_stream_t *is = NULL;
+
+
+#line 2294 "dk3strm.ctr"
+ if((hf) && (fipo)) {
+
+#line 2295 "dk3strm.ctr"
+ if(app) {
+ oldsourcefile = dk3app_get_source_file(app);
+ oldsourceline = dk3app_get_source_line(app);
+ dk3app_set_source_file(app, fn);
+ }
+ is = dk3stream_open_file_app(fipo, DK3_STREAM_FLAG_READ, app);
+ if(is) {
+ back = dk3stream_process_chars(is, obj, hf, ie);
+ dk3stream_close(is);
+ }
+ if(app) {
+ dk3app_set_source_file(app, oldsourcefile);
+ dk3app_set_source_line(app, oldsourceline);
+ }
+ }
+
+#line 2310 "dk3strm.ctr"
+ return back;
+}
+
+
+
+int
+dk3stream_process_filename_chars_app(
+ void *obj,
+ dk3_char_handler_t *hf,
+ dkChar const *fn,
+ int de,
+ dk3_app_t *app
+)
+{
+ char bombuf[4];
+ FILE *fipo; /* Input file. */
+ size_t skb;
+ int back = 0;
+ int ie; /* Input encoding. */
+
+
+#line 2330 "dk3strm.ctr"
+ if((hf) && (fn)) {
+ ie = de;
+
+#line 2332 "dk3strm.ctr"
+ skb = 0;
+ ie = dk3sf_inspect_bom_skip_app(fn, ie, &skb, NULL);
+
+#line 2334 "dk3strm.ctr"
+ fipo = dk3sf_fopen_app(fn, dk3app_not_localized(36), app);
+ if(fipo) {
+ if((skb > 0) && (skb <=4)) {
+ dk3sf_fread_app(bombuf, 1, skb, fipo, app);
+ }
+ back = dk3stream_process_file_chars_app(obj, hf, fipo, fn, ie, app);
+ fclose(fipo);
+ }
+ }
+
+#line 2343 "dk3strm.ctr"
+ return back;
+}
+
+
+
+/** Add one found 32-bit character to input line,
+ process input line if newline found or if buffer is full.
+ @param lhv A dk3_line_handler_data_t pointer.
+ @param c32 Current character to process.
+ @return 1=OK, can continue, 0=error, can continue, -1=error, abort.
+*/
+static
+int
+dk3stream_add_character_to_line(void *lhv, dk3_c32_t c32)
+{
+ int back = 1;
+ dk3_line_handler_data_t *lh;
+ dkChar *cp; /* Current position. */
+ int res; /* Handler result. */
+#if DK3_CHAR_SIZE > 1
+ dk3_c16_t u16p[8]; /* Buffer UTF-16 */
+ size_t used; /* Elements used in u16p. */
+ size_t i; /* Running index. */
+#else
+ unsigned char uc; /* Unsigned char. */
+ char c; /* Current char. */
+ unsigned char u8p[8]; /* Buffer UTF-8. */
+ size_t used; /* Elements used in u8p. */
+ size_t i; /* Running index. */
+#endif
+
+
+#line 2374 "dk3strm.ctr"
+ lh = (dk3_line_handler_data_t *)lhv;
+#if DK3_CHAR_SIZE > 1
+ used = dk3enc_uc2utf16(c32, u16p, DK3_SIZEOF(u16p,dk3_c16_t));
+ if(used > 0) {
+ if((lh->bufus + used) < (lh->szbuf - 1)) {
+ cp = lh->cp;
+ for(i = 0; i < used; i++) { cp[i] = u16p[i]; }
+ cp = &(cp[used]);
+ *cp = dkT('\0');
+ lh->cp = cp;
+ lh->bufus += used;
+ if(c32 == 0x0000000AUL) {
+ /* FLUSH OUTPUT */
+ (lh->buf)[lh->szbuf - 1] = dkT('\0');
+ res = (*(lh->hf))(lh->obj, lh->buf);
+ if(res < 1) {
+ back = 0;
+ if(res < 0) {
+ back = -1;
+ }
+ }
+ /* Start new line */
+ lh->cp = lh->buf;
+ (lh->buf)[0] = '\0';
+ lh->bufus = 0;
+ }
+ } else {
+ back = 0;
+ /* Warning: Line too long */
+ if(lh->app) {
+ dk3app_log_i1((dk3_app_t *)(lh->app), DK3_LL_WARNING, 108);
+ }
+ (lh->buf)[lh->szbuf - 1] = dkT('\0');
+ res = (*(lh->hf))(lh->obj, lh->buf);
+ if(res < -1) { back = -1; }
+ cp = lh->buf;
+ for(i = 0; i < used; i++) { cp[i] = u16p[i]; }
+ cp = &(cp[used]);
+ *cp = dkT('\0');
+ lh->cp = cp;
+ lh->bufus = used;
+ if(c32 == 0x0000000AUL) {
+ lh->cp = lh->buf;
+ *(lh->buf) = dkT('\0');
+ lh->bufus = 0;
+ }
+ }
+ } else {
+ /* ERROR: Encoding failed! */
+ if(lh->app) {
+ dk3app_log_i1((dk3_app_t *)(lh->app), DK3_LL_ERROR, 119);
+ }
+ }
+#else
+
+
+#line 2429 "dk3strm.ctr"
+ if(lh->se == DK3_ENCODING_UTF8) {
+
+#line 2430 "dk3strm.ctr"
+ used = dk3enc_uc2utf8(c32, u8p, sizeof(u8p));
+ if(used > 0) {
+
+#line 2432 "dk3strm.ctr"
+ if((lh->bufus + used) < (lh->szbuf - 1)) {
+
+#line 2433 "dk3strm.ctr"
+ cp = lh->cp;
+
+#line 2434 "dk3strm.ctr"
+ for(i = 0; i < used; i++) { cp[i] = u8p[i]; }
+ cp = &(cp[used]);
+
+#line 2436 "dk3strm.ctr"
+ *cp = '\0';
+ lh->cp = cp;
+ lh->bufus += used;
+
+#line 2439 "dk3strm.ctr"
+ if(c32 == 0x0000000AUL) {
+
+#line 2440 "dk3strm.ctr"
+ /* FLUSH OUTPUT */
+ (lh->buf)[lh->szbuf - 1] = dkT('\0');
+ res = (*(lh->hf))(lh->obj, lh->buf);
+ if(res < 1) {
+ back = 0;
+ if(res < 0) {
+ back = -1;
+ }
+ }
+ /* Start new line */
+ lh->cp = lh->buf;
+ (lh->buf)[0] = '\0';
+ lh->bufus = 0;
+ }
+
+#line 2454 "dk3strm.ctr"
+ } else {
+
+#line 2455 "dk3strm.ctr"
+ back = 0;
+ /* Warning: Line too long! */
+ if(lh->app) {
+ dk3app_log_i1(lh->app, DK3_LL_WARNING, 108);
+ }
+ /* FLUSH OUTPUT */
+ (lh->buf)[lh->szbuf - 1] = dkT('\0');
+ res = (*(lh->hf))(lh->obj, lh->buf);
+ if(res < -1) { back = -1; }
+ /* Start new line. */
+ cp = lh->buf;
+ for(i = 0; i < used; i++) { cp[i] = u8p[i]; }
+ cp = &(cp[used]);
+ *cp = '\0';
+ lh->cp = cp;
+ lh->bufus = used;
+ if(c32 == 0x0000000AUL) {
+ *(lh->buf) = '\0';
+ lh->cp = lh->buf;
+ lh->bufus = 0;
+ }
+ }
+ } else {
+
+#line 2478 "dk3strm.ctr"
+ back = 0;
+ /* ERROR: Encoding failed! */
+ if(lh->app) {
+
+#line 2481 "dk3strm.ctr"
+ dk3app_log_i1(lh->app, DK3_LL_ERROR, 115);
+ }
+ }
+ } else {
+
+#line 2485 "dk3strm.ctr"
+ if((unsigned long)c32 > 0x000000FFUL) {
+ /* Warning: Character out of range. */
+ if(lh->app) {
+ dk3app_log_i1(lh->app, DK3_LL_WARNING, 219);
+ }
+ }
+ uc = (unsigned char)c32;
+ c = (char)uc;
+ if((lh->bufus + 1) < (lh->szbuf - 1)) {
+ cp = lh->cp;
+ *(cp++) = c;
+ *cp = '\0';
+ lh->cp = cp;
+ lh->bufus += 1;
+ if(c32 == 0x0000000AUL) {
+ /* FLUSH OUTPUT */
+ (lh->buf)[lh->szbuf - 1] = dkT('\0');
+ res = (*(lh->hf))(lh->obj, lh->buf);
+ if(res < 1) {
+ back = 0;
+ if(res < 0) {
+ back = -1;
+ }
+ }
+ /* Start new line */
+ lh->cp = lh->buf;
+ (lh->buf)[0] = '\0';
+ lh->bufus = 0;
+ }
+ } else {
+ back = 0;
+ /* Warning: Line too long! */
+ if(lh->app) {
+ dk3app_log_i1(lh->app, DK3_LL_WARNING, 108);
+ }
+ /* FLUSH OUTPUT */
+ (lh->buf)[lh->szbuf - 1] = dkT('\0');
+ res = (*(lh->hf))(lh->obj, lh->buf);
+ if(res < -1) { back = -1; }
+ /* Start new line. */
+ cp = lh->buf;
+ *(cp++) = c;
+ *cp = '\0';
+ lh->cp = cp;
+ lh->bufus = 1;
+ if(c32 == 0x0000000AUL) {
+ *(lh->buf) = '\0';
+ lh->cp = lh->buf;
+ lh->bufus = 0;
+ }
+ }
+ }
+#endif
+
+
+#line 2539 "dk3strm.ctr"
+ return back;
+}
+
+
+
+int
+dk3stream_process_lines(
+ dk3_stream_t *st,
+ void *obj,
+ dk3_line_handler_t *hf,
+ dkChar *buf,
+ size_t szbuf,
+ int se,
+ int ie
+)
+{
+ int back = 0;
+ dk3_line_handler_data_t lh;
+
+
+#line 2558 "dk3strm.ctr"
+ if((st) && (hf) && (buf) && (szbuf)) {
+ lh.app = (dk3_app_t *)(st->app);
+ lh.obj = obj;
+ lh.hf = hf;
+ lh.buf = buf;
+ buf[0] = dkT('\0');
+ lh.szbuf = szbuf;
+ lh.cp = lh.buf;
+ lh.bufus = 0;
+ lh.se = se;
+ back = dk3stream_process_chars(
+ st, (void *)(&lh), dk3stream_add_character_to_line, ie
+ );
+ }
+
+#line 2572 "dk3strm.ctr"
+ return back;
+}
+
+
+
+/* NOTE: This function does not check for a BOM at the beginning
+ of the file. Whenever applicable, use
+ dk3stream_process_filename_lines_app() instead.
+*/
+int
+dk3stream_process_file_lines_app(
+ void *obj,
+ dk3_line_handler_t *hf,
+ FILE *fipo,
+ dkChar const *fn,
+ dkChar *buf,
+ size_t szbuf,
+ int se,
+ int ie,
+ dk3_app_t *app
+)
+{
+ int back = 0;
+ dkChar const *oldsourcename = NULL;
+ unsigned long oldsourceline = 0UL;
+ dk3_stream_t *is;
+
+
+#line 2599 "dk3strm.ctr"
+ if((hf) && (fipo)) {
+
+#line 2600 "dk3strm.ctr"
+ if(app) {
+
+#line 2601 "dk3strm.ctr"
+ oldsourcename = dk3app_get_source_file(app);
+ oldsourceline = dk3app_get_source_line(app);
+ dk3app_set_source_file(app, fn);
+ dk3app_set_source_line(app, 1UL);
+ }
+ is = dk3stream_open_file_app(fipo, DK3_STREAM_FLAG_READ, app);
+ if(is) {
+
+#line 2608 "dk3strm.ctr"
+ back = dk3stream_process_lines(is, obj, hf, buf, szbuf, se, ie);
+ dk3stream_close(is);
+ } else {
+
+#line 2611 "dk3strm.ctr"
+ }
+ if(app) {
+
+#line 2613 "dk3strm.ctr"
+ dk3app_set_source_file(app, oldsourcename);
+ dk3app_set_source_line(app, oldsourceline);
+ }
+ }
+
+#line 2617 "dk3strm.ctr"
+ return back;
+}
+
+
+
+int
+dk3stream_process_filename_lines_app(
+ void *obj,
+ dk3_line_handler_t *hf,
+ dkChar const *fn,
+ dkChar *buf,
+ size_t szbuf,
+ int se,
+ int de,
+ dk3_app_t *app
+)
+{
+ char bombuf[4];
+ FILE *fipo; /* Input file. */
+ size_t skb; /* Bytes to skip at start of input. */
+ int ie; /* Input encoding. */
+ int back = 0;
+
+
+#line 2640 "dk3strm.ctr"
+ if((hf) && (fn)) {
+ ie = dk3sf_inspect_bom_skip_app(fn, de, &skb, app);
+
+#line 2642 "dk3strm.ctr"
+ fipo = dk3sf_fopen_app(fn, dk3app_not_localized(36), app);
+ if(fipo) {
+
+#line 2644 "dk3strm.ctr"
+ if((skb > 0) && (skb <= 4)) {
+ dk3sf_fread_app(bombuf, 1, skb, fipo, app);
+ }
+ back = dk3stream_process_file_lines_app(
+ obj, hf, fipo, fn, buf, szbuf, se, ie, app
+ );
+ fclose(fipo);
+ }
+ }
+
+#line 2653 "dk3strm.ctr"
+ return back;
+}
+
+
+
+int
+dk3stream_process_filename_sanitized_lines_app(
+ void *obj,
+ dk3_line_handler_t *hf,
+ dkChar const *fn,
+ dkChar *buf,
+ size_t szbuf,
+ int se,
+ int de,
+ dk3_app_t *app
+)
+{
+ char bombuf[4];
+#if DK3_HAVE_SETVBUF
+ char *filebuf = NULL; /* File buffer. */
+#endif
+ FILE *fipo; /* Input file. */
+ size_t skb; /* Bytes to skip at start of input. */
+ int ie; /* Input encoding. */
+ int back = 0;
+
+
+#line 2679 "dk3strm.ctr"
+ if((hf) && (fn)) {
+ ie = dk3sf_inspect_bom_skip_app(fn, de, &skb, app);
+
+#line 2681 "dk3strm.ctr"
+#if DK3_HAVE_SETVBUF
+ filebuf = dk3_new_app(char,BUFSIZ,app);
+ if (NULL != filebuf) {
+#endif
+ fipo = dk3sf_fopen_app(fn, dk3app_not_localized(36), app);
+ if(fipo) {
+
+#line 2687 "dk3strm.ctr"
+#if DK3_HAVE_SETVBUF
+ if (0 == setvbuf(fipo, filebuf, _IOFBF, BUFSIZ)) {
+#endif
+ if((skb > 0) && (skb <= 4)) {
+ dk3sf_fread_app(bombuf, 1, skb, fipo, app);
+ }
+ back = dk3stream_process_file_lines_app(
+ obj, hf, fipo, fn, buf, szbuf, se, ie, app
+ );
+#if DK3_HAVE_SETVBUF
+ } else {
+ /* ERROR: Failed to set buffer for file */
+ dk3app_log_i3(app, DK3_LL_ERROR, 412, 413, fn);
+ }
+#endif
+ fclose(fipo);
+ }
+#if DK3_HAVE_SETVBUF
+ dk3mem_reset_secure(filebuf, BUFSIZ);
+ dk3mem_free(filebuf); filebuf = NULL;
+ }
+#endif
+ }
+
+#line 2710 "dk3strm.ctr"
+ return back;
+}
+
+
+int
+dk3strm_double_c8_str_no_sci(dk3_stream_t *os, char *buffer)
+{
+ char *start; /* Start of string. */
+ char *eptr; /* Start of exponent substring. */
+ char *ptr; /* Traverse string. */
+ size_t lgt; /* String length. */
+ int dp; /* Decimal dot position. */
+ int exponent; /* Exponent. */
+ int i; /* Traverse the string. */
+ int back = 1; /* Result */
+ char chr; /* Character to write out */
+
+
+#line 2727 "dk3strm.ctr"
+ if((os) && (buffer)) {
+ eptr = NULL;
+ start = buffer;
+ /*
+ Print sign.
+ */
+ switch(*start) {
+ case '-': {
+ if (1 != dk3stream_write_bytes(os, start, 1)) { back = 0; }
+ start++;
+ } break;
+ case '+': {
+ start++;
+ } break;
+ }
+ /*
+ Find exponent substring and exponent.
+ */
+ eptr = NULL;
+ ptr = start;
+ while(*ptr) {
+ switch(*ptr) {
+ case 'e': case 'E': {
+ eptr = ptr;
+ } break;
+ }
+ ptr++;
+ }
+ if(eptr) {
+ *(eptr++) = '\0';
+#if VERSION_BEFORE_20140716
+ if(sscanf(eptr, "%d", &exponent) != 1)
+#else
+ if (0 == dk3ma_i_from_c8_string(&exponent, eptr, NULL))
+#endif
+ {
+ exponent = 0;
+ }
+ } else {
+ exponent = 0;
+ }
+ /*
+ Find decimal dot.
+ */
+ eptr = strchr(start, '.');
+ if(eptr) {
+ /*
+ Keep dot position in dp, squeeze string.
+ */
+ *eptr = '\0';
+ dp = (int)strlen(start);
+ *eptr = '.';
+ while(*eptr) {
+ eptr[0] = eptr[1];
+ eptr++;
+ }
+ } else {
+ /*
+ Dot position is after the string.
+ */
+ dp = (int)strlen(start);
+ }
+ /*
+ Correct dot position.
+ */
+ dp = dp + exponent;
+ /*
+ Remove leading zeroes (if any).
+ */
+ while('0' == *start) {
+ start++; dp--;
+ }
+ /*
+ Remove trailing zeroes (if any).
+ */
+ eptr = NULL;
+ ptr = start;
+ while(*ptr) {
+ if('0' == *ptr) {
+ if(!(eptr)) { eptr = ptr; }
+ } else {
+ eptr = NULL;
+ }
+ ptr++;
+ }
+ if(eptr) { *eptr = '\0'; }
+ lgt = strlen(start);
+ if(0 < lgt) {
+ if(dp >= (int)lgt) {
+ /*
+ Decimal dot is at end or after string.
+ */
+ if (1 != dk3stream_c8_fputs(os, start)) { back = 0; }
+ /*
+ Decimal dot is after the string.
+ */
+ for(i = 0; i < (dp - (int)lgt); i++) {
+ chr = '0';
+ if (1 != dk3stream_write_bytes(os, &chr, 1)) { back = 0; }
+ }
+ } else {
+ if(dp <= 0) {
+ /*
+ Decimal dot is before the string.
+ */
+ chr = '0';
+ if (1 != dk3stream_write_bytes(os, &chr, 1)) { back = 0; }
+ chr = '.';
+ if (1 != dk3stream_write_bytes(os, &chr, 1)) { back = 0; }
+ chr = 0;
+ while(dp++ < 0) {
+ if (1 != dk3stream_write_bytes(os, &chr, 1)) { back = 0; }
+ }
+ if (1 != dk3stream_c8_fputs(os, start)) { back = 0; }
+ } else {
+ /*
+ Decimal dot is in the string.
+ */
+ for(i = 0; i < (int)lgt; i++) {
+ if(dp == i) {
+ chr = '.';
+ if (1 != dk3stream_write_bytes(os, &chr, 1)) { back = 0; }
+ }
+ if (1 != dk3stream_write_bytes(os, &(start[i]), 1)) { back = 0; }
+ }
+ }
+ }
+ } else {
+ /*
+ No non-zero digits in string.
+ */
+ chr = '0';
+ if (1 != dk3stream_write_bytes(os, &chr, 1)) { back = 0; }
+ }
+ }
+
+#line 2862 "dk3strm.ctr"
+ return back;
+}
+
+
+
+int
+dk3strm_double_c8_no_sci(dk3_stream_t *os, double x)
+{
+ char buffer[64];
+ char *ptr;
+ int back = 0;
+ if (NULL != os) {
+ if (1 == sprintf(buffer, "%g", x)) {
+ ptr = buffer;
+ while(*ptr) { if (',' == *ptr) { *ptr = '.'; } ptr++; }
+ back = dk3strm_double_c8_str_no_sci(os, buffer);
+ }
+ }
+ return back;
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dk3strm.ctr b/support/dktools/dk3strm.ctr
new file mode 100644
index 0000000000..506551f461
--- /dev/null
+++ b/support/dktools/dk3strm.ctr
@@ -0,0 +1,2886 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% header
+
+#include "dk3conf.h"
+#include "dk3types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open a stream, allocate memory.
+ @param d Stream data object.
+ @param f Stream low-level function.
+ @param fl Flags to indicate read and/or write access.
+ @param app Application structure, used for diagnostics.
+ @return Pointer to new stream on success, NULL on error.
+*/
+dk3_stream_t *
+dk3stream_open_app(void *d, dk3_stream_api_fct_t *f, int fl, dk3_app_t *app);
+
+/** Close a stream, release memory.
+ @param st Stream to close.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3stream_close(dk3_stream_t *st);
+
+/** Set up automatic flushing when writing newlines.
+ @param st Stream to set up.
+ @param fl Flag value (0=no flush, 1=flush buffer,
+ 2=buffer and low-level object).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3stream_set_line_flush(dk3_stream_t *st, int fl);
+
+/** Write a buffer of bytes to stream.
+ @param st Stream to write to.
+ @param sb Source buffer.
+ @param sz Size of \ sb (number of bytes).
+ The size must not exceed 32767 as it is converted to int
+ for some compression libraries.
+ @return Number of bytes written.
+*/
+size_t
+dk3stream_write_bytes(dk3_stream_t *st, char const *sb, size_t sz);
+
+/** Read bytes into buffer.
+ @param st Stream to read from.
+ @param db Destination buffer address.
+ @param sz Size of \a db in bytes.
+ The size must not exceed 32767 as it is converted to int
+ for some compression libraries.
+ @return Number of bytes read (may be 0).
+*/
+size_t
+dk3stream_read_bytes(dk3_stream_t *st, char *db, size_t sz);
+
+/** Check whether end of input data was reached.
+ @param st Stream to check.
+ @return 1 for end of input reached, 0 otherwise.
+*/
+int
+dk3stream_feof(dk3_stream_t const *st);
+
+/** Get a text line (8-bit characters).
+ @param st Stream to read from.
+ @param db Destination buffer.
+ @param sz Size of \a db in bytes.
+ The size must not exceed 32767 as it is converted to int
+ for some compression libraries.
+ @return 1 on success (line found), 0 on error.
+*/
+int
+dk3stream_c8_fgets(dk3_stream_t *st, char *db, size_t sz);
+
+/** Write a text line (8-bit characters) without any re-encoding.
+ @param st Stream to write to.
+ @param str Text to write.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3stream_c8_fputs(dk3_stream_t *st, char const *str);
+
+/** Set output encoding.
+ @param st Stream to set up.
+ @param oe New output encoding.
+*/
+void
+dk3stream_set_output_encoding(dk3_stream_t *st, int oe);
+
+/** Write byte order marker 0xFEFF converted to the streams
+ output encoding.
+ @param st Stream to write to.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3stream_write_byte_order_marker(dk3_stream_t *st);
+
+/** Write byte order marker if necessary on the system.
+ @param st Stream to write to.
+ @param se System encoding.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3stream_write_byte_order_marker_if_necessary(dk3_stream_t *st, int se);
+
+/** Write 8-bit character text, convert to the streams output encoding.
+ @param st Stream to write to.
+ @param s String to write.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3stream_fputs_c8_plain(dk3_stream_t *st, char const *s);
+
+/** Write UTF-8 encoded text, convert to the streams output encoding.
+ @param st Stream to write to.
+ @param s String to write.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3stream_fputs_c8_utf8(dk3_stream_t *st, char const *s);
+
+/** Write UTF-16 encoded text, convert to the streams output encoding.
+ @param st Stream to write to.
+ @param s String to write.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3stream_fputs_c16(dk3_stream_t *st, dk3_c16_t const *s);
+
+/** Write UNICODE text, convert to the streams output encoding.
+ @param st Stream to write to.
+ @param s String to write.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3stream_fputs_c32(dk3_stream_t *st, dk3_c32_t const *s);
+
+/** Write generic dkChar text, convert to the streams output encoding.
+ @param st Stream to write to.
+ @param s String to write.
+ @param ie Input encoding (used for 8-bit characters only).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3stream_strputs(dk3_stream_t *st, dkChar const *s, int ie);
+
+/** Write newline to stream.
+ @param st Stream to write to.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3stream_strnl(dk3_stream_t *st);
+
+/** Get number of bytes written.
+ @param st Stream to check.
+ @return Number of bytes written to the stream.
+*/
+dk3_um_t
+dk3stream_bytes_written(dk3_stream_t const *st);
+
+/** Open stream for a file. The file is not closed when the stream
+ is closed.
+ @param fi File.
+ @param fl Read/write flags.
+ @param app Application structure, used for diagnostics.
+ @return Stream pointer on success, NULL on error.
+*/
+dk3_stream_t *
+dk3stream_open_file_app(FILE *fi, int fl, dk3_app_t *app);
+
+/** Get 16-bit text line.
+ @param st Stream.
+ @param db Destination buffer.
+ @param sz Size of \a db (number of 16-bit characters).
+ The size must not exceed 16383 as buffer sizes arre converted to int
+ for some compression libraries.
+ @param msbfirst Flag: MSB first.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3stream_c16_fgets(dk3_stream_t *st, dk3_c16_t *db, size_t sz, int msbfirst);
+
+/** Get 32-bit text line.
+ @param st Stream.
+ @param db Destination buffer.
+ @param sz Size of \a db (number of 32-bit characters).
+ The size must not exceed 8191 as buffer sizes are converted to int
+ for some compression libraries and 4*8192 exceeds the int range
+ on 16-bit systems.
+ @param msbfirst Flag: MSB first.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3stream_c32_fgets(dk3_stream_t *st, dk3_c32_t *db, size_t sz, int msbfirst);
+
+#if DK3_HAVE_ZLIB_H
+/** Open stream for a gzFile. The gzFile is not closed when the stream
+ is closed.
+ @param g gzFile.
+ @param fl Read/write flags.
+ @param app Application structure, used for diagnostics.
+ @return Stream pointer on success, NULL on error.
+*/
+dk3_stream_t *
+dk3stream_open_gz_app(gzFile g, int fl, dk3_app_t *app);
+#endif
+
+#if DK3_HAVE_BZLIB_H
+/** Open stream for a BZFILE. The BZFILE is not closed when the stream
+ is closed.
+ @param b BZFILE.
+ @param fl Read/write flags.
+ @param app Application structure, used for diagnostics.
+ @return Stream pointer on success, NULL on error.
+*/
+dk3_stream_t *
+dk3stream_open_bz2_app(BZFILE *b, int fl, dk3_app_t *app);
+#endif
+
+/** Process an input stream character by character.
+ @param st Stream containing the input data to process.
+ @param obj Object to modify with input stream.
+ @param hf Character handler function.
+ @param ie Input encoding.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3stream_process_chars(
+ dk3_stream_t *st,
+ void *obj,
+ dk3_char_handler_t *hf,
+ int ie
+);
+
+/** Process all characters in a file.
+ NOTE: If you have the file name, you should use
+ dk3stream_process_filename_chars_app() instead. The
+ dk3stream_process_filename_chars_app() checks for a BOM at the
+ beginning of the file and corrects the input encoding if
+ necessary.
+ @param obj Object to modify while processing the input file.
+ @param hf Handler function.
+ @param fipo Input file.
+ @param fn File name.
+ @param ie Input file encoding.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3stream_process_file_chars_app(
+ void *obj,
+ dk3_char_handler_t *hf,
+ FILE *fipo,
+ dkChar const *fn,
+ int ie,
+ dk3_app_t *app
+);
+
+/** Process all characters in a file.
+ @param obj Object to modify while processing the input file.
+ @param hf Handler function.
+ @param fn File name.
+ @param de Default file encoding.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3stream_process_filename_chars_app(
+ void *obj,
+ dk3_char_handler_t *hf,
+ dkChar const *fn,
+ int de,
+ dk3_app_t *app
+);
+
+/** Put 32-bit character to stream, convert if necessary.
+ @param st Output stream.
+ @param c32 Character to write.
+ @param err_enc_rep Pointer to flag: Encoding error reported.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3stream_fputc_c32(dk3_stream_t *st, dk3_c32_t c32, int *err_enc_rep);
+
+/** Process stream contents line by line.
+ @param st Input stream.
+ @param obj Object to modify while processing input.
+ @param hf Handler function.
+ @param buf Buffer for input lines.
+ @param szbuf Size of \a buf (number of characters).
+ The size must not exceed 8191 as buffer sizes are converted to int
+ for some compression libraries and 4*8192 exceeds the int range
+ on 16-bit systems.
+ @param se System character encoding (DK3_ENCODING_xxx).
+ @param ie Input encoding (DK3_FILE_ENCODING_xxx).
+ @return 1 on success, 0 on error, -1 on error with abort.
+*/
+int
+dk3stream_process_lines(
+ dk3_stream_t *st,
+ void *obj,
+ dk3_line_handler_t *hf,
+ dkChar *buf,
+ size_t szbuf,
+ int se,
+ int ie
+);
+
+/** Process input file contents line by line.
+ NOTE: If you have a file name available, you should use
+ dk3stream_process_filename_lines_app() instead, as the
+ dk3stream_process_filename_lines_app() function checks for a BOM
+ at the start of the file and corrects the input encoding if
+ necessary.
+ @param obj Object to modify while processing input.
+ @param hf Handler function.
+ @param fipo Input file.
+ @param fn File name.
+ @param buf Input line buffer.
+ @param szbuf Size of \a buf (number of characters).
+ The size must not exceed 8191 as buffer sizes are converted to int
+ for some compression libraries.
+ @param se System character encoding (DK3_ENCODING_xxx).
+ @param ie Input encoding (DK3_FILE_ENCODING_xxx).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error, -1 on error with abort.
+*/
+int
+dk3stream_process_file_lines_app(
+ void *obj,
+ dk3_line_handler_t *hf,
+ FILE *fipo,
+ dkChar const *fn,
+ dkChar *buf,
+ size_t szbuf,
+ int se,
+ int ie,
+ dk3_app_t *app
+);
+
+/** Process input file line by line.
+ @param obj Object to modify while processing input.
+ @param hf Handler function.
+ @param fn File name.
+ @param buf Input line buffer.
+ @param szbuf Size of \a buf (number of characters).
+ The size must not exceed 8191 as buffer sizes are converted to int
+ for some compression libraries.
+ @param se System character encoding (DK3_ENCODING_xxx).
+ @param de Default file encoding (DK3_FILE_ENCODING_xxx).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error, -1 on error with abort.
+*/
+int
+dk3stream_process_filename_lines_app(
+ void *obj,
+ dk3_line_handler_t *hf,
+ dkChar const *fn,
+ dkChar *buf,
+ size_t szbuf,
+ int se,
+ int de,
+ dk3_app_t *app
+);
+
+/** Process input file line by line, sanitize file buffer.
+ @param obj Object to modify while processing input.
+ @param hf Handler function.
+ @param fn File name.
+ @param buf Input line buffer.
+ @param szbuf Size of \a buf (number of characters).
+ The size must not exceed 8191 as buffer sizes are converted to int
+ for some compression libraries.
+ @param se System character encoding (DK3_ENCODING_xxx).
+ @param de Default file encoding (DK3_FILE_ENCODING_xxx).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error, -1 on error with abort.
+*/
+int
+dk3stream_process_filename_sanitized_lines_app(
+ void *obj,
+ dk3_line_handler_t *hf,
+ dkChar const *fn,
+ dkChar *buf,
+ size_t szbuf,
+ int se,
+ int de,
+ dk3_app_t *app
+);
+
+/** Write double value to stream as text, avoid exponential notation.
+ @param os Stream to write to.
+ @param x Value to write.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3strm_double_c8_no_sci(dk3_stream_t *os, double x);
+
+/** Write double value from string buffer to stream, avoid exponential
+ notation.
+ @param os Stream to write to.
+ @param buffer Buffer containing double converted to text.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3strm_double_c8_str_no_sci(dk3_stream_t *os, char *buffer);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk3all.h"
+
+
+$(trace-include)
+
+
+
+#ifndef BUFSIZ
+#define BUFSIZ 8192
+#endif
+
+
+
+#if 0
+/** Low-level stream function to deal with bzip2 compression.
+ Closing the stream also closes the bzip2-file.
+ @param api API structure.
+*/
+static
+void
+dk3stream_bz_fct(dk3_stream_api_t *api)
+{
+#if DK3_HAVE_BZLIB_H
+ BZFILE *b = NULL; /* Low level I/O object. */
+ int res = 0; /* Operation result. */
+#endif
+ api->suc = 0;
+ (api->res).sz = 0;
+ (api->res).ec = DK3_ERROR_NOT_SUPPORTED;
+#if DK3_HAVE_BZLIB_H
+ b = (BZFILE *)((api->arg).d);
+ (api->res).ec = 0;
+ switch(api->cmd) {
+ case DK3_STREAM_API_READ: {
+ if(((api->arg).b) && ((api->arg).sz) && ((api->arg).d)) {
+ res = BZ2_bzread(b, (api->arg).b, (api->arg).sz);
+ if(res > 0) {
+ api->suc = 1; (api->res).ec = 0; (api->res).sz = (size_t)res;
+ }
+ }
+ } break;
+ case DK3_STREAM_API_WRITE: {
+ if(((api->arg).b) && ((api->arg).sz) && ((api->arg).d)) {
+ res = BZ2_bzwrite(b, (api->arg).b, (api->arg).sz);
+ if(res > 0) {
+ (api->res).sz = (size_t)res;
+ if((size_t)res == (api->arg).sz) {
+ api->suc = 1; (api->res).ec = 0;
+ }
+ }
+ }
+ } break;
+ case DK3_STREAM_API_FLUSH: {
+ if((api->arg).d) {
+ BZ2_bzflush(b);
+ api->suc = 1; (api->res).ec = 0;
+ /*
+ As the library manual explains BZ2_bzflush() does nothing.
+ So we always return success.
+ */
+ }
+ } break;
+ case DK3_STREAM_API_AT_END: {
+
+ } break;
+ case DK3_STREAM_API_CLOSE: {
+ if((api->arg).d) {
+ BZ2_bzclose(b);
+ api->suc = 1; (api->res).ec = 0;
+ }
+ } break;
+ case DK3_STREAM_API_ZERO_IS_END: {
+ api->suc = 1; (api->res).ec = 0; /* Correct if necessary */
+ } break;
+ case DK3_STREAM_API_ERROR: {
+ } break;
+ }
+#endif
+}
+
+
+
+/** Low-level stream function to deal with bzip2 compression.
+ Closing the stream does not close the bzip2 file.
+ @param api API structure.
+*/
+static
+void
+dk3stream_bz_fct_no_close(dk3_stream_api_t *api)
+{
+ if(api->cmd != DK3_STREAM_API_CLOSE) {
+ dk3stream_bz_fct(api);
+ } else {
+ api->suc = 1; (api->res).ec = 0;
+ }
+}
+
+#endif
+
+#if 0
+
+/** Low-level stream function to deal with gzip compression.
+ Closing the stream also closes the gzip-file.
+ @param api API structure.
+*/
+static
+void
+dk3stream_gz_fct(dk3_stream_api_t *api)
+{
+#if DK3_HAVE_ZLIB_H
+ int res = 0; /* Operation result. */
+ gzFile g = NULL; /* Low-level I/O object. */
+#endif
+ api->suc = 0;
+ (api->res).sz = 0;
+ (api->res).ec = DK3_ERROR_NOT_SUPPORTED;
+#if DK3_HAVE_ZLIB_H
+ (api->res).ec = 0;
+ g = (gzFile)((api->arg).d);
+ switch(api->cmd) {
+ case DK3_STREAM_API_READ: {
+ if(((api->arg).b) && ((api->arg).sz) && ((api->arg).d)) {
+ res = gzread(g, (api->arg).b, (api->arg).sz);
+ if(res > 0) {
+ api->suc = 1; (api->res).ec = 0; (api->res).sz = (size_t)res;
+ }
+ }
+ } break;
+ case DK3_STREAM_API_WRITE: {
+ if(((api->arg).b) && ((api->arg).sz) && ((api->arg).d)) {
+ res = gzwrite(g, (api->arg).b, (api->arg).sz);
+ (api->res).sz = (size_t)res;
+ if((size_t)res == (api->arg).sz) {
+ api->suc = 1; (api->res).ec = 0;
+ }
+ }
+ } break;
+ case DK3_STREAM_API_FLUSH: {
+ if((api->arg).d) {
+ if(gzflush(g, Z_FULL_FLUSH) == Z_OK) {
+ api->suc = 1; (api->res).ec = 0;
+ }
+ }
+ } break;
+ case DK3_STREAM_API_AT_END: {
+ if((api->arg).d) {
+ if(gzeof(g) == 1) {
+ api->suc = 1;
+ }
+ }
+ } break;
+ case DK3_STREAM_API_CLOSE: {
+ if((api->arg).d) {
+ if(gzclose(g) == Z_OK) {
+ api->suc = 1;
+ }
+ }
+ } break;
+ case DK3_STREAM_API_ZERO_IS_END: {
+ api->suc = 0;
+ } break;
+ case DK3_STREAM_API_ERROR: {
+ api->suc = 0;
+ } break;
+ }
+#endif
+}
+
+
+
+/** Low-level stream function to deal with gzip compression.
+ Closing the stream does not close the gzip-file.
+ @param api API structure.
+*/
+static
+void
+dk3stream_gz_fct_no_close(dk3_stream_api_t *api)
+{
+ if(api->cmd != DK3_STREAM_API_CLOSE) {
+ dk3stream_gz_fct(api);
+ } else {
+ api->suc = 1; (api->res).ec = 0;
+ }
+}
+
+#endif
+
+
+
+/** Low-level stream function to deal with plain files.
+ Closing the stream also closes the file.
+ @param api API structure.
+*/
+static
+void
+dk3stream_file_fct(dk3_stream_api_t *api)
+{
+ FILE *fipo = NULL; /* Low-level I/O object. */
+ size_t res = 0; /* Operation result. */
+ $? "+ dk3stream_file_fct"
+ api->suc = 0;
+ (api->res).sz = 0;
+ (api->res).ec = 0;
+ switch(api->cmd) {
+ case DK3_STREAM_API_READ: { $? ". read"
+ if(((api->arg).b) && ((api->arg).sz) && ((api->arg).d)) {
+ fipo = (FILE *)((api->arg).d);
+#if DK3_ON_WINDOWS
+ res = fread((api->arg).b, 1, (api->arg).sz, fipo);
+ if(res) {
+ api->suc = 1; (api->res).ec = 0; (api->res).sz = res;
+ } else {
+ if(!ferror(fipo)) {
+ api->suc = 1; (api->res).ec = 0;
+ }
+ }
+#else
+#if DK3_HAVE_FREAD
+ res = fread((api->arg).b, 1, (api->arg).sz, fipo);
+ if(res) {
+ api->suc = 1; (api->res).ec = 0; (api->res).sz = res;
+ } else {
+ if(!ferror(fipo)) {
+ api->suc = 1; (api->res).ec = 0;
+ }
+ }
+#else
+#if DK3_HAVE__FREAD
+ res = _fread((api->arg).b, 1, (api->arg).sz, fipo);
+ if(res) {
+ api->suc = 1; (api->res).ec = 0; (api->res).sz = res;
+ } else {
+ if(!ferror(fipo)) {
+ api->suc = 1; (api->res).ec = 0;
+ }
+ }
+#else
+#error "No fread() function!"
+#endif
+#endif
+#endif
+ }
+ } break;
+ case DK3_STREAM_API_WRITE: { $? ". write"
+ if(((api->arg).b) && ((api->arg).sz) && ((api->arg).d)) {
+ fipo = (FILE *)((api->arg).d);
+#if DK3_ON_WINDOWS
+ res = fwrite((api->arg).b, 1, (api->arg).sz, fipo);
+ (api->res).sz = res;
+ if(res == (api->arg).sz) {
+ api->suc = 1; (api->res).ec = 0;
+ }
+#else
+#if DK3_HAVE_FWRITE
+ res = fwrite((api->arg).b, 1, (api->arg).sz, fipo);
+ (api->res).sz = res;
+ if(res == (api->arg).sz) {
+ api->suc = 1; (api->res).ec = 0;
+ }
+#else
+#if DK3_HAVE__FWRITE
+ res = _fwrite((api->arg).b, 1, (api->arg).sz, fipo);
+ if(res == (api->arg).sz) {
+ api->suc = 1; (api->res).ec = 0; (api->res).sz = res;
+ }
+#else
+#error "No fwrite() function!"
+#endif
+#endif
+#endif
+ }
+ } break;
+ case DK3_STREAM_API_FLUSH: { $? ". flush"
+ if((api->arg).d) {
+ fipo = (FILE *)((api->arg).d);
+ if(fflush(fipo) == 0) {
+ api->suc = 1; (api->res).ec = 0;
+ }
+ }
+ } break;
+ case DK3_STREAM_API_AT_END: { $? ". at-end"
+ if((api->arg).d) {
+ fipo = (FILE *)((api->arg).d);
+ if(feof(fipo)) {
+ api->suc = 1; (api->res).ec = 0;
+ }
+ }
+ } break;
+ case DK3_STREAM_API_CLOSE: { $? ". close"
+ if((api->arg).d) {
+ fipo = (FILE *)((api->arg).d);
+ if(fclose(fipo) == 0) {
+ api->suc = 1; (api->res).ec = 0;
+ }
+ }
+ } break;
+ case DK3_STREAM_API_ZERO_IS_END: { $? ". zero-is-end"
+ if((api->arg).d) {
+ api->suc = 1; (api->res).ec = 0;
+ }
+ } break;
+ case DK3_STREAM_API_ERROR: { $? ". error"
+ if((api->arg).d) {
+ fipo = (FILE *)((api->arg).d);
+ if(ferror(fipo)) {
+ api->suc = 1; (api->res).ec = 0;
+ }
+ }
+ } break;
+ } $? "- dk3stream_file_fct %d", api->suc
+}
+
+
+
+/** Low-level stream function to deal with plain files.
+ Closing the stream does not close the file.
+ @param api API structure.
+*/
+static
+void
+dk3stream_file_fct_no_close(dk3_stream_api_t *api)
+{ $? "+ dk3stream_file_fct_no_close"
+ if(api->cmd != DK3_STREAM_API_CLOSE) {
+ dk3stream_file_fct(api);
+ } else {
+ api->suc = 1; (api->res).ec = 0;
+ } $? "- dk3stream_file_fct_no_close"
+}
+
+
+
+/** Initialize stream API structure.
+ @param api Structure to initialize.
+*/
+static
+void
+dk3stream_api_init(dk3_stream_api_t *api)
+{ $? "+ dk3stream_api_init"
+ if(api) {
+ api->cmd = 0;
+ api->suc = 0;
+ (api->arg).b = NULL;
+ (api->arg).sz = 0;
+ (api->arg).d = NULL;
+ (api->res).sz = 0;
+ (api->res).ec = 0;
+ } $? "- dk3stream_api_init"
+}
+
+
+
+/** Delete stream, release memory.
+ @param st Stream to delete.
+*/
+static
+void
+dk3stream_delete_stream(dk3_stream_t *st)
+{ $? "+ dk3stream_delete_stream"
+ if(st) {
+ dk3_release(st->ib);
+ dk3_release(st->ob);
+ dk3_delete(st);
+ } $? "- dk3stream_delete_stream"
+}
+
+
+
+/** Flush stream.
+ @param st Stream to flush.
+ @param fd Flag: Flush downstream object.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3stream_do_flush(dk3_stream_t *st, int fd)
+{
+ int back = 0;
+ dk3_stream_api_t api;
+ $? "+ dk3stream_do_flush"
+ if(st) {
+ back = 1;
+ st->ec = 0;
+ if((st->fl) & DK3_STREAM_FLAG_WRITE) {
+ if(st->us_ob) {
+ dk3stream_api_init(&api);
+ api.cmd = DK3_STREAM_API_WRITE;
+ api.arg.b = st->ob;
+ api.arg.sz = st->us_ob;
+ api.arg.d = st->d;
+ (*(st->f))(&api);
+ if(!(api.suc)) {
+ st->ec = api.res.ec;
+ back = 0;
+ if(st->app) {
+ /* ERROR: Failed to write data! */
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 120);
+ }
+ }
+ }
+ st->us_ob = 0;
+ if(fd) {
+ dk3stream_api_init(&api);
+ api.cmd = DK3_STREAM_API_FLUSH;
+ api.arg.d = st->d;
+ (*(st->f))(&api);
+ if(!(api.suc)) {
+ if(back) {
+ if(st->app) {
+ /* ERROR: Flush failed! */
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 121);
+ }
+ st->ec = api.res.ec;
+ }
+ back = 0;
+ }
+ }
+ }
+ } $? "- dk3stream_do_flush %d", back
+ return back;
+}
+
+
+
+/** Open new stream, allocate memory.
+ @param app Application structure, used for diagnostics.
+ @return Pointer to new stream on success, NULL on error.
+*/
+static
+dk3_stream_t *
+dk3stream_new_stream(dk3_app_t *app)
+{
+ dk3_stream_t *back = NULL;
+ $? "+ dk3stream_new_stream"
+ back = dk3_new_app(dk3_stream_t,1,app);
+ if(back) {
+ back->app = NULL;
+ back->d = NULL;
+ back->f = NULL;
+ back->ib = NULL;
+ back->ob = NULL;
+ back->wr = DK3_UM_0;
+ back->sz_ib = 0;
+ back->av_ib = 0;
+ back->us_ib = 0;
+ back->sz_ob = 0;
+ back->us_ob = 0;
+ back->fl = 0;
+ back->lf = 0;
+ back->fe = 0;
+ back->ec = 0;
+ back->oe = 0;
+ back->ze = 0;
+ back->er = 0;
+ back->ib = dk3_new_app(char,4096,app);
+ back->ob = dk3_new_app(char,4096,app);
+ if((back->ib) && (back->ob)) {
+ back->sz_ib = 4096;
+ back->sz_ob = 4096;
+ } else {
+ dk3stream_delete_stream(back);
+ back = NULL;
+ }
+ } $? "- dk3stream_new_stream %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+int
+dk3stream_close(dk3_stream_t *st)
+{
+ int back = 0;
+ dk3_stream_api_t api;
+ $? "+ dk3stream_close"
+ if(st) {
+ back = dk3stream_do_flush(st, 1);
+ dk3stream_api_init(&api);
+ api.cmd = DK3_STREAM_API_CLOSE;
+ api.arg.d = st->d;
+ (*(st->f))(&api);
+ if(!(api.suc)) {
+ back = 0;
+ if(st->app) {
+ /* ERROR: Failed to close stream data object! */
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 122);
+ }
+ }
+ st->d = NULL; st->f = NULL; st->app = NULL;
+ dk3stream_delete_stream(st);
+ } $? "- dk3stream_close %d", back
+ return back;
+}
+
+
+
+dk3_stream_t *
+dk3stream_open_app(void *d, dk3_stream_api_fct_t *f, int fl, dk3_app_t *app)
+{
+ dk3_stream_t *back = NULL;
+ dk3_stream_api_t api;
+ $? "+ dk3stream_open_app"
+ if((d) && (f)) {
+ back = dk3stream_new_stream(app);
+ if(back) {
+ back->app = app;
+ back->d = d;
+ back->f = f;
+ back->fl = fl;
+ dk3stream_api_init(&api);
+ api.cmd = DK3_STREAM_API_ZERO_IS_END;
+ api.arg.d = d;
+ (*f)(&api);
+ if(api.suc) {
+ back->ze = 1;
+ }
+ }
+ } $? "- dk3stream_open_app %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+/** Write one byte.
+ @param st Stream to write to.
+ @param ch Byte to write.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3stream_my_write_byte(dk3_stream_t *st, char ch)
+{
+ int back = 1;
+ int fld = 0; /* Flag: Flush downwards. */
+ $? "+ dk3stream_my_write_byte"
+ (st->ob)[st->us_ob] = ch;
+ st->us_ob += 1;
+ st->wr += DK3_UM_1;
+ if((st->us_ob == st->sz_ob) || ((ch == '\n') && (st->lf)))
+ {
+ if(ch == '\n') { if(st->lf == 2) { fld = 1; } }
+ back = dk3stream_do_flush(st, fld);
+ } $? "- dk3stream_my_write_byte %d", back
+ return back;
+}
+
+
+
+size_t
+dk3stream_write_bytes(dk3_stream_t *st, char const *sb, size_t sz)
+{
+ size_t back = 0;
+ char const *sp = NULL; /* Source pointer. */
+ size_t l = 0; /* Bytes remaining. */
+ $? "+ dk3stream_write_bytes"
+ if((st) && (sb) && (sz)) {
+ if((st->fl) & DK3_STREAM_FLAG_WRITE) {
+ sp = sb; l = sz;
+ while(l--) {
+ if(dk3stream_my_write_byte(st, *sp)) {
+ back++;
+ }
+ sp++;
+ }
+ } else {
+ if(st->app) {
+ /* ERROR: Stream not opened for write operations! */
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 123);
+ }
+ }
+ } $? "- dk3stream_write_bytes %lu", (unsigned long)back
+ return back;
+}
+
+
+
+/** Read one byte from buffer, reload buffer if necessary.
+ @param st Stream to read from.
+ @param cp One-byte buffer for destination.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3stream_my_read_byte(dk3_stream_t *st, char *cp)
+{
+ int back = 0;
+ dk3_stream_api_t api;
+ $? "+ dk3stream_my_read_byte"
+ if(st->us_ib >= st->av_ib) { $? ". must read from downstream"
+ st->us_ib = 0;
+ st->av_ib = 0;
+ dk3stream_api_init(&api);
+ api.cmd = DK3_STREAM_API_READ;
+ api.arg.b = st->ib;
+ api.arg.sz = st->sz_ib;
+ api.arg.d = st->d;
+ (*(st->f))(&api);
+ if(api.suc) { $? ". read operation succeeded"
+ st->av_ib = api.res.sz;
+ if(st->av_ib) { $? ". bytes found"
+ if(st->av_ib < st->sz_ib) { $? ". less bytes than expected"
+ dk3stream_api_init(&api);
+ api.cmd = DK3_STREAM_API_AT_END;
+ api.arg.d = st->d;
+ (*(st->f))(&api);
+ if(api.suc) { $? ". end of input"
+ st->fe = 1;
+ }
+ }
+ } else { $? "! 0 bytes were read"
+ if(st->ze) {
+ st->fe = 1; /* End of input reached. */
+ } else {
+ dk3stream_api_init(&api);
+ api.cmd = DK3_STREAM_API_ERROR;
+ api.arg.d = st->d;
+ (*(st->f))(&api);
+ if(api.suc) {
+ st->er = 1;
+ st->fe = 1;
+ }
+ }
+ }
+ } else { $? "! read operation failed"
+ st->ec = api.res.ec;
+ st->fe = 1; /* Error found, end of input data. */
+ dk3stream_api_init(&api);
+ api.cmd = DK3_STREAM_API_AT_END;
+ api.arg.d = st->d;
+ (*(st->f))(&api);
+ if(api.suc) {
+ st->ec = 0;
+ } else {
+ if(st->app) {
+ /* ERROR: Read operation failed! */
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 124);
+ }
+ st->er = 1;
+ }
+ }
+ }
+ if(st->us_ib < st->av_ib) { $? ". data available"
+ *cp = (st->ib)[st->us_ib];
+ st->us_ib += 1;
+ back = 1;
+ } $? "- dk3stream_my_read_byte %d", back
+ return back;
+}
+
+
+
+size_t
+dk3stream_read_bytes(dk3_stream_t *st, char *db, size_t sz)
+{
+ size_t back = 0;
+ char c = 0x00; /* Current byte read. */
+ char *dp = NULL; /* Destination pointer. */
+ int cc = 0; /* Flag: Can continue. */
+ $? "+ dk3stream_read_bytes"
+ if((st) && (db) && (sz)) {
+ dp = db; cc = 1;
+ while((back < sz) && (cc)) {
+ if(dk3stream_my_read_byte(st, &c)) {
+ *(dp++) = c; back++;
+ } else {
+ cc = 0;
+ }
+ }
+ } $? "- dk3stream_read_bytes %lu", (unsigned long)back
+ return back;
+}
+
+
+
+int
+dk3stream_feof(dk3_stream_t const *st)
+{
+ int back = 0;
+ if(st) {
+ if(st->fe) {
+ if(st->us_ib >= st->av_ib) {
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3stream_c8_fgets(dk3_stream_t *st, char *db, size_t sz)
+{
+ int back = 0;
+ char *dp = NULL; /* Destination pointer. */
+ size_t l = 0; /* Number of bytes already found. */
+ int cc = 0; /* Flag: Can continue. */
+ char c = 0x00; /* Current character. */
+ $? "+ dk3stream_c8_fgets"
+ if((st) && (db) && (sz)) {
+ *db = '\0';
+ dp = db; l = 0; cc = 1;
+ while((l < (sz - 1)) && (cc)) {
+ if(dk3stream_my_read_byte(st, &c)) {
+ *(dp++) = c; l++;
+ if(c == '\n') { cc = 0; }
+ } else {
+ cc = 0;
+ }
+ }
+ if(l < sz) {
+ *dp = '\0';
+ } else {
+ db[sz - 1] = '\0';
+ }
+ if(l) { back = 1; }
+ } $? "- dk3stream_c8_fgets %d", back
+ return back;
+}
+
+
+
+int
+dk3stream_c8_fputs(dk3_stream_t *st, char const *str)
+{
+ int back = 0;
+ char const *sp = NULL; /* Source pointer. */
+ if((st) && (str)) {
+ back = 1; sp = str;
+ while(*sp) {
+ if(!dk3stream_my_write_byte(st, *(sp++))) {
+ back = 0;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3stream_c16_fgets(dk3_stream_t *st, dk3_c16_t *db, size_t sz, int msbfirst)
+{
+ int back = 0;
+ int cc = 1; /* Flag: Can continue. */
+ int eo = 0; /* Flag: 0=first byte, 1=second byte */
+ int res = 0; /* Result from my_read_byte. */
+ int msbf = 0; /* Flag: MSB first. */
+ char c1 = 0x00; /* First byte. */
+ char c2 = 0x00; /* Second byte. */
+ dk3_c16_t *ptr = NULL; /* Pointer into destination buffer. */
+ size_t bt = 0; /* Number of characters read. */
+ unsigned char uc1; /* First byte as unsigned char. */
+ unsigned char uc2; /* Second byte as unsigned char. */
+ unsigned u1; /* First byte as unsigned. */
+ unsigned u2; /* Second byte as unsigned. */
+ if((st) && (db) && (sz)) {
+ back = 1; ptr = db; bt = 0; msbf = msbfirst; cc = 1; eo = 0;
+ while(cc) {
+#if VERSION_BEFORE_20150821
+ res = 0;
+#endif
+ if(eo) {
+ res = dk3stream_my_read_byte(st, &c2);
+ } else {
+ res = dk3stream_my_read_byte(st, &c1);
+ }
+ if(res) {
+ if(eo) {
+ eo = 0;
+ uc1 = (unsigned char)c1;
+ uc2 = (unsigned char)c2;
+ u1 = (unsigned)uc1;
+ u2 = (unsigned)uc2;
+ u1 &= 0x00FFU;
+ u2 &= 0x00FFU;
+ if(msbf) {
+ u1 = ((u1 << 8) & 0xFF00U) | u2;
+ } else {
+ u1 = ((u2 << 8) & 0xFF00U) | u1;
+ }
+ if(u1 != 0xFEFFU) {
+ if(u1 == 0xFFFEU) {
+ msbf = (msbf ? 0 : 1);
+ } else {
+ *(ptr++) = (dk3_c16_t)u1;
+ bt++;
+ if(u1 == (dk3_c16_t)'\n') {
+ cc = 0;
+ }
+ }
+ }
+ } else {
+ eo = 1;
+ }
+ } else {
+ cc = 0;
+ if(eo) { back = 0; }
+ }
+ if(bt >= (sz - 1)) { cc = 0; }
+ }
+ if(bt < sz) { *ptr = 0U; }
+ db[sz - 1] = 0U;
+ }
+ if(bt == 0) { back = 0; }
+ return back;
+}
+
+
+
+int
+dk3stream_c32_fgets(dk3_stream_t *st, dk3_c32_t *db, size_t sz, int msbfirst)
+{
+ int back = 0;
+ int cc = 1; /* Flag: Can continue. */
+ int eo = 0; /* Flag: 0=first byte, 1=second byte */
+ int res = 0; /* Result from my_read_byte. */
+ int msbf = 0; /* Flag: MSB first. */
+ char c1 = 0x00; /* First byte. */
+ char c2 = 0x00; /* Second byte. */
+ char c3 = 0x00; /* Third byte. */
+ char c4 = 0x00; /* Fourth byte. */
+ dk3_c32_t *ptr = NULL; /* Pointer into destination buffer. */
+ size_t bt = 0; /* Number of characters read. */
+ unsigned char uc1; /* First byte as unsigned char. */
+ unsigned char uc2; /* Second byte as unsigned char. */
+ unsigned char uc3; /* Third byte as unsigned char. */
+ unsigned char uc4; /* Fourth byte as unsigned char. */
+ unsigned long u1; /* First byte as unsigned. */
+ unsigned long u2; /* Second byte as unsigned. */
+ unsigned long u3; /* Third byte as unsigned. */
+ unsigned long u4; /* Fourth byte as unsigned. */
+
+ if((st) && (db) && (sz)) {
+ back = 1; ptr = db; bt = 0; msbf = msbfirst; cc = 1; eo = 0;
+ while(cc) {
+ res = 0;
+ switch(eo) {
+ case 0: {
+ res = dk3stream_my_read_byte(st, &c1);
+ } break;
+ case 1: {
+ res = dk3stream_my_read_byte(st, &c2);
+ } break;
+ case 2: {
+ res = dk3stream_my_read_byte(st, &c3);
+ } break;
+ case 3: {
+ res = dk3stream_my_read_byte(st, &c4);
+ } break;
+ }
+ if(res) {
+ eo++;
+ if(eo >= 4) {
+ eo = 0;
+ uc1 = (unsigned char)c1;
+ uc2 = (unsigned char)c2;
+ uc3 = (unsigned char)c3;
+ uc4 = (unsigned char)c4;
+ u1 = (unsigned long)uc1;
+ u2 = (unsigned long)uc2;
+ u3 = (unsigned long)uc3;
+ u4 = (unsigned long)uc4;
+ if(msbf) {
+ u1 = (u1 << 24) & 0xFF000000UL;
+ u2 = (u2 << 16) & 0x00FF0000UL;
+ u3 = (u2 << 8) & 0x0000FF00UL;
+ u4 = u4 & 0x000000FFUL;
+ } else {
+ u1 = u1 & 0x000000FFUL;
+ u2 = (u2 << 8) & 0x0000FF00UL;
+ u3 = (u3 << 16) & 0x00FF0000UL;
+ u4 = (u4 << 24) & 0xFF000000UL;
+ }
+ u1 = (u1 | u2 | u3 | u4);
+ if(u1 != 0x0000FEFFUL) {
+ if(u1 == 0x0000FFFEUL) {
+ msbf = (msbf ? 0 : 1);
+ } else {
+ *(ptr++) = u1; bt++;
+ if(u1 == 0x0000000AUL) {
+ cc = 0;
+ }
+ }
+ }
+ }
+ } else {
+ cc = 0;
+ if(eo) { back = 0; }
+ }
+ if(bt >= (sz - 1)) { cc = 0; }
+ }
+ if(bt < sz) { *ptr = 0UL; }
+ db[sz - 1] = 0UL;
+ }
+ if(bt == 0) { back = 0; }
+ return back;
+}
+
+
+
+void
+dk3stream_set_output_encoding(dk3_stream_t *st, int oe)
+{
+ if(st) {
+ switch(oe) {
+ case DK3_FILE_ENCODING_ASCII:
+ case DK3_FILE_ENCODING_UTF8:
+ case DK3_FILE_ENCODING_UTF16_MSB_FIRST:
+ case DK3_FILE_ENCODING_UTF16_LSB_FIRST:
+ case DK3_FILE_ENCODING_UNICODE_MSB_FIRST:
+ case DK3_FILE_ENCODING_UNICODE_LSB_FIRST:
+ {
+ st->oe = oe;
+ } break;
+ default:
+ {
+ if(st->app) {
+ /* ERROR: Illegal output encoding! */
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 114);
+ }
+ } break;
+ }
+ }
+}
+
+
+
+/** Write one 16-bit character to stream.
+ @param st Output stream.
+ @param c16 Character to write.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3stream_my_write_16(dk3_stream_t *st, dk3_c16_t c16)
+{
+ int back = 0;
+ switch(st->oe) {
+ case DK3_FILE_ENCODING_UTF16_MSB_FIRST: {
+ if(dk3stream_my_write_byte(st, (char)((c16 >> 8) & 0x00FFU))) {
+ if(dk3stream_my_write_byte(st, (char)(c16 & 0x00FFU))) {
+ back = 1;
+ }
+ }
+ } break;
+ case DK3_FILE_ENCODING_UTF16_LSB_FIRST: {
+ if(dk3stream_my_write_byte(st, (char)(c16 & 0x00FFU))) {
+ if(dk3stream_my_write_byte(st, (char)((c16 >> 8) & 0x00FFU))) {
+ back = 1;
+ }
+ }
+ } break;
+ }
+ return back;
+}
+
+
+
+/** Write one 32-bit character to output stream.
+ @param st Stream.
+ @param c32 Character to write.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3stream_my_write_32(dk3_stream_t *st, dk3_c32_t c32)
+{
+ int back = 0;
+ switch(st->oe) {
+ case DK3_FILE_ENCODING_UNICODE_MSB_FIRST: {
+ if(dk3stream_my_write_byte(st, (char)((c32 >> 24) & 0x000000FFUL))) {
+ if(dk3stream_my_write_byte(st, (char)((c32 >> 16) & 0x000000FFUL))) {
+ if(dk3stream_my_write_byte(st, (char)((c32 >> 8) & 0x000000FFUL))) {
+ if(dk3stream_my_write_byte(st, (char)(c32 & 0x000000FFUL))) {
+ back = 1;
+ }
+ }
+ }
+ }
+ } break;
+ case DK3_FILE_ENCODING_UNICODE_LSB_FIRST: {
+ if(dk3stream_my_write_byte(st, (char)(c32 & 0x000000FFUL))) {
+ if(dk3stream_my_write_byte(st, (char)((c32 >> 8) & 0x000000FFUL))) {
+ if(dk3stream_my_write_byte(st, (char)((c32 >> 16) & 0x000000FFUL))) {
+ if(dk3stream_my_write_byte(st, (char)((c32 >> 24) & 0x000000FFUL))) {
+ back = 1;
+ }
+ }
+ }
+ }
+ } break;
+ }
+ return back;
+}
+
+
+
+int
+dk3stream_fputc_c32(dk3_stream_t *st, dk3_c32_t c32, int *err_enc_rep)
+{
+ int back = 0;
+ dk3_c16_t myc16[4]; /* Buffer for UTF-16 encoding. */
+ unsigned char myuc[16]; /* Buffer for UTF-8 encoding. */
+ size_t l = 0; /* Length of encoded string. */
+ size_t i = 0; /* Index of current element to write. */
+ $? "+ dk3stream_fputc_c32"
+ switch(st->oe) {
+ case DK3_FILE_ENCODING_UNICODE_MSB_FIRST:
+ case DK3_FILE_ENCODING_UNICODE_LSB_FIRST: {
+ back = dk3stream_my_write_32(st, c32);
+ } break;
+ case DK3_FILE_ENCODING_UTF16_MSB_FIRST:
+ case DK3_FILE_ENCODING_UTF16_LSB_FIRST: {
+ l = dk3enc_uc2utf16(c32, myc16, 4);
+ if(l) {
+ back = 1;
+ for(i = 0; i < l; i++) {
+ if(!dk3stream_my_write_16(st, myc16[i])) {
+ back = 1;
+ }
+ }
+ } else {
+ if(!(*err_enc_rep)) {
+ if(st->app) { $? "! conversion to UTF-16"
+ /* ERROR: UTF-16 encode failed! */
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 116);
+ }
+ } *err_enc_rep = 1;
+ }
+ } break;
+ case DK3_FILE_ENCODING_ASCII: {
+ if(c32 < (dk3_c32_t)0x00000100UL) {
+ back = dk3stream_my_write_byte(st, (char)(c32 & 0x000000FFUL));
+ } else {
+ if(!(*err_enc_rep)) {
+ if(st->app) {
+ /* ERROR: Character out of range! */
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 117);
+ }
+ } *err_enc_rep = 1;
+ }
+ } break;
+ case DK3_FILE_ENCODING_UTF8: {
+ l = dk3enc_uc2utf8(c32, myuc, 16);
+ if(l) {
+ i = dk3stream_write_bytes(st, (char const *)myuc, l);
+ if(i == l) { back = 1; }
+ } else {
+ if(!(*err_enc_rep)) {
+ if(st->app) {
+ /* ERROR: UTF-8 encode failed! */
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 115);
+ }
+ } *err_enc_rep = 1;
+ }
+ } break;
+ } $? "- dk3stream_fputc_c32 %d", back
+ return back;
+}
+
+
+
+int
+dk3stream_write_byte_order_marker(dk3_stream_t *st)
+{
+ int back = 0;
+ if(st) {
+ switch(st->oe) {
+ case DK3_FILE_ENCODING_UTF16_MSB_FIRST:
+ case DK3_FILE_ENCODING_UTF16_LSB_FIRST:
+ {
+ back = dk3stream_my_write_16(st, 0xFEFFU);
+ } break;
+ case DK3_FILE_ENCODING_UNICODE_MSB_FIRST:
+ case DK3_FILE_ENCODING_UNICODE_LSB_FIRST:
+ {
+ back = dk3stream_my_write_32(st, 0x0000FEFFUL);
+ } break;
+ default: {
+ back = 1;
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3stream_write_byte_order_marker_if_necessary(dk3_stream_t *st, int se)
+{
+ int back = 1;
+ switch(st->oe) {
+ case DK3_FILE_ENCODING_UTF16_MSB_FIRST:
+ case DK3_FILE_ENCODING_UTF16_LSB_FIRST:
+ case DK3_FILE_ENCODING_UNICODE_MSB_FIRST:
+ case DK3_FILE_ENCODING_UNICODE_LSB_FIRST: {
+ back = dk3stream_write_byte_order_marker(st);
+ } break;
+ case DK3_FILE_ENCODING_UTF8: {
+ if(DK3_FILE_ENCODING_UTF8 != se) {
+ back = dk3stream_write_byte_order_marker(st);
+ }
+ } break;
+ default: {
+ } break;
+ }
+ return back;
+}
+
+
+int
+dk3stream_fputs_c8_plain(dk3_stream_t *st, char const *s)
+{
+ int back = 0;
+ int err_rep_enc = 0; /* Flag: Encoding error reported. */
+ char const *sp = NULL; /* Source pointer. */
+ char c = 0x00; /* Current character. */
+ unsigned char uc = 0x00; /* Unsigned version of current char. */
+ unsigned long ul = 0UL; /* 32-bit version of current char. */
+ if((st) && (s)) {
+ switch(st->oe) {
+ case DK3_FILE_ENCODING_ASCII: {
+ back = dk3stream_c8_fputs(st, s);
+ } break;
+ default: {
+ back = 1;
+ sp = s;
+ while(*sp) {
+ c = *(sp++);
+ uc = (unsigned char)c;
+ ul = (unsigned long)uc;
+ ul &= 0x000000FFUL;
+ if(!dk3stream_fputc_c32(st, ul, &err_rep_enc)) { back = 0; }
+ }
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3stream_fputs_c8_utf8(dk3_stream_t *st, char const *s)
+{
+ int back = 0;
+ int err_rep_dec = 0; /* Flag: Decoding error reported. */
+ int err_rep_enc = 0; /* Flag: Encoding error reported. */
+ unsigned char const *sp = NULL; /* Source pointer. */
+ dk3_c32_t c32 = 0UL; /* 32-bit version of current char. */
+ size_t sl = 0; /* Remaining source bytes. */
+ size_t used = 0; /* Bytes used. */
+ if((st) && (s)) {
+ switch(st->oe) {
+ case DK3_FILE_ENCODING_UTF8: {
+ back = dk3stream_c8_fputs(st, s);
+ } break;
+ default: {
+ back = 1;
+ sp = (unsigned char const *)s; sl = dk3str_c8_len(s);
+ while(sl) {
+ used = 0;
+ if(dk3enc_utf82uc(&c32, sp, sl, &used)) {
+ if(used) {
+ if(!dk3stream_fputc_c32(st, c32, &err_rep_enc)) { back = 0; }
+ if(sl >= used) {
+ sl = sl - used;
+ sp = &(sp[used]);
+ } else {
+ sl = 0;
+ }
+ } else {
+ sl = 0; back = 0;
+ if(!err_rep_dec) {
+ if(st->app) {
+ /* ERROR: UTF-8 decode failed! */
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118);
+ }
+ } err_rep_dec = 1;
+ }
+ } else {
+ sl = 0; back = 0;
+ if(!err_rep_dec) {
+ if(st->app) {
+ /* ERROR: UTF-8 decode failed! */
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118);
+ }
+ } err_rep_dec = 1;
+ }
+ }
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3stream_fputs_c16(dk3_stream_t *st, dk3_c16_t const *s)
+{
+ int back = 0;
+ int err_rep_dec = 0; /* Flag: Decoding error reported. */
+ int err_rep_enc = 0; /* Flag: Encoding error reported. */
+ dk3_c16_t const *sp = NULL; /* Source pointer. */
+ dk3_c32_t c32 = 0UL; /* 32-bit version of current char. */
+ size_t sl = 0; /* Remaining source bytes. */
+ size_t used = 0; /* Source bytes used. */
+ if((st) && (s)) {
+ switch(st->oe) {
+ case DK3_FILE_ENCODING_UTF16_MSB_FIRST:
+ case DK3_FILE_ENCODING_UTF16_LSB_FIRST: {
+ sp = s; back = 1;
+ while(*sp) { if(!dk3stream_my_write_16(st, *(sp++))) { back = 0; } }
+ } break;
+ default: {
+ sp = s; sl = dk3str_c16_len(s);
+ while(sl) {
+ used = 0;
+ if(dk3enc_utf162uc(&c32, sp, sl, &used)) {
+ if(used) {
+ if(!dk3stream_fputc_c32(st, c32, &err_rep_enc)) { back = 0; }
+ if(sl >= used) {
+ sl = sl - used;
+ sp = &(sp[used]);
+ } else {
+ sl = 0;
+ }
+ } else {
+ back = 0; sl = 0;
+ if(!err_rep_dec) {
+ if(st->app) {
+ /* ERROR: Decode UTF-16 failed! */
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 119);
+ }
+ } err_rep_dec = 1;
+ }
+ } else {
+ back = 0; sl = 0;
+ if(!err_rep_dec) {
+ if(st->app) {
+ /* ERROR: Decode UTF-16 failed! */
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 119);
+ }
+ } err_rep_dec = 1;
+ }
+ }
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3stream_fputs_c32(dk3_stream_t *st, dk3_c32_t const *s)
+{
+ int back = 0;
+ int err_rep_enc = 0; /* Flag: Encoding error reported. */
+ dk3_c32_t const *sp = NULL; /* Source pointer. */
+ if((st) && (s)) {
+ sp = s;
+ back = 1;
+ while(*sp) {
+ if(!dk3stream_fputc_c32(st, *(sp++), &err_rep_enc)) { back = 0; }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3stream_strputs(dk3_stream_t *st, dkChar const *s, int ie)
+{
+ int back = 0;
+ $? "+ dk3stream_strputs"
+ if((st) && (s)) {
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ if(ie == DK3_ENCODING_UNICODE) {
+ back = dk3stream_fputs_c32(st, s);
+ } else {
+ if(st->app) {
+ /* ERROR: Encoding does not match character size! */
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 125);
+ }
+ }
+#else
+ if(ie == DK3_ENCODING_UTF16) {
+ back = dk3stream_fputs_c16(st, s);
+ } else {
+ if(st->app) {
+ /* ERROR: Encoding does not match character size! */
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 125);
+ }
+ }
+#endif
+#else
+ switch(ie) {
+ case DK3_ENCODING_PLAIN: {
+ back = dk3stream_fputs_c8_plain(st, s);
+ } break;
+ case DK3_ENCODING_UTF8: {
+ back = dk3stream_fputs_c8_utf8(st, s);
+ } break;
+ default: {
+ if(st->app) {
+ /* ERROR: Encoding does not match character size! */
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 125);
+ }
+ } break;
+ }
+#endif
+ } $? "- dk3stream_strputs %d", back
+ return back;
+}
+
+
+
+int
+dk3stream_strnl(dk3_stream_t *st)
+{
+ int back = 1;
+ int err_enc_rep = 0; /* Flag: Encoding error reported. */
+#if DK3_ON_WINDOWS
+ if(!dk3stream_fputc_c32(st, 0x0000000DUL, &err_enc_rep)) {
+ back = 0;
+ }
+#endif
+ if(!dk3stream_fputc_c32(st, 0x0000000AUL, &err_enc_rep)) {
+ back = 0;
+ }
+ return back;
+}
+
+
+
+int
+dk3stream_set_line_flush(dk3_stream_t *st, int fl)
+{
+ int back = 0;
+ $? "+ dk3stream_set_line_flush"
+ if(st) { st->lf = fl; back = 1; } $? "- dk3stream_set_line_flush %d", back
+ return back;
+}
+
+
+
+dk3_um_t
+dk3stream_bytes_written(dk3_stream_t const *st)
+{
+ dk3_um_t back = DK3_UM_0;
+ $? "+ dk3stream_bytes_written"
+ if(st) {
+ back = st->wr;
+ } $? "- dk3stream_bytes_written %llu", (unsigned long long)back
+ return back;
+}
+
+
+
+dk3_stream_t *
+dk3stream_open_file_app(FILE *fi, int fl, dk3_app_t *app)
+{
+ dk3_stream_t *back = NULL;
+ $? "+ dk3stream_open_file_app"
+ if(fi) {
+ back = dk3stream_open_app((void *)fi, dk3stream_file_fct_no_close, fl, app);
+ } $? "- dk3stream_open_file_app %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+#if 0
+
+#if DK3_HAVE_ZLIB_H
+dk3_stream_t *
+dk3stream_open_gz_app(gzFile g, int fl, dk3_app_t *app)
+{
+ dk3_stream_t *back = NULL;
+ if(g) {
+ back = dk3stream_open_app((void *)g, dk3stream_gz_fct_no_close, fl, app);
+ }
+ return back;
+}
+#endif
+
+#endif
+
+
+
+#if 0
+
+#if DK3_HAVE_BZLIB_H
+dk3_stream_t *
+dk3stream_open_bz2_app(BZFILE *b, int fl, dk3_app_t *app)
+{
+ dk3_stream_t *back = NULL;
+ if(b) {
+ back = dk3stream_open_app((void *)b, dk3stream_bz_fct_no_close, fl, app);
+ }
+ return back;
+}
+#endif
+
+#endif
+
+
+int
+dk3stream_process_chars(
+ dk3_stream_t *st,
+ void *obj,
+ dk3_char_handler_t *hf,
+ int ie
+)
+{
+ int back = 0;
+ int res; /* Handler function result. */
+ int cc; /* Flag: Can continue. */
+ int myie; /* Input encoding. */
+ int done; /* Flag: Character already handled. */
+#if VERSION_BEFORE_20150821
+ int surrogate; /* UTF-16 surrogate type. */
+#endif
+ char c1; /* First byte. */
+ char c2; /* Second byte. */
+ char c3; /* Third byte. */
+ char c4; /* Fourth byte. */
+ unsigned char u1; /* Current byte. */
+ dk3_c32_t uc1; /* First part of result. */
+ dk3_c32_t uc2; /* Second part of result. */
+ dk3_c32_t uc3; /* Third part of result. */
+ dk3_c32_t uc4; /* Fourth part of result. */
+ dk3_c32_t c32; /* Character found in decoding. */
+ unsigned long lineno; /* Current line number. */
+ unsigned long oldlineno = 0UL; /* Line number before start. */
+ $? "+ dk3stream_process_chars"
+ if((st) && (hf)) {
+ if(st->app) { $? ". input encoding = %d", ie
+ oldlineno = dk3app_get_source_line((dk3_app_t *)(st->app));
+ dk3app_set_source_line((dk3_app_t *)(st->app), 1UL);
+ }
+ lineno = 1UL;
+ back = 1;
+#if VERSION_BEFORE_20150821
+ cc = 1;
+#endif
+ myie = ie; $? ". myie = %d", myie
+ do { $? ". loop start"
+ cc = 0;
+ done = 0;
+ c32 = 0UL;
+ switch(myie) {
+ case DK3_FILE_ENCODING_ASCII: { $? ". ascii"
+ if(dk3stream_my_read_byte(st, &c1)) { $? ". byte 1 ok"
+ cc = 1;
+ c32 = (dk3_c32_t)c1;
+ c32 &= 0x000000FFUL;
+ }
+ } break;
+ case DK3_FILE_ENCODING_UTF8: { $? ". utf-8"
+ if(dk3stream_my_read_byte(st, &c1)) { $? ". byte 1 ok"
+ u1 = (unsigned char)c1;
+ if(u1 > 0x7F) { $? ". > 1 byte"
+ if((u1 & 0xE0) == 0xC0) { $? ". 2 bytes"
+ c32 = ((((dk3_c32_t)u1) << 6) & 0x000007C0UL);
+ if(dk3stream_my_read_byte(st, &c1)) { $? ". byte 2 ok"
+ u1 = (unsigned char)c1;
+ c32 |= (((dk3_c32_t)u1) & 0x0000003FUL);
+ cc = 1;
+ } else {
+ /* ERROR: Incomplete sequence! */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118);
+ }
+ }
+ } else {
+ if((u1 & 0xF0) == 0xE0) { $? ". 3 bytes"
+ c32 = ((((dk3_c32_t)u1) << 12) & 0x0000F000UL);
+ if(dk3stream_my_read_byte(st, &c1)) { $? ". byte 2 ok"
+ u1 = (unsigned char)c1;
+ c32 |= ((((dk3_c32_t)u1) << 6) & 0x00000FC0UL);
+ if(dk3stream_my_read_byte(st, &c1)) { $? ". byte 3 ok"
+ u1 = (unsigned char)c1;
+ c32 |= (((dk3_c32_t)u1) & 0x0000003FUL);
+ cc = 1;
+ } else {
+ /* ERROR: Incomplete sequence! */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118);
+ }
+ }
+ } else {
+ /* ERROR: Incomplete sequence! */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118);
+ }
+ }
+ } else {
+ if((u1 & 0xF8) == 0xF0) { $? ". 4 bytes"
+ c32 = ((((dk3_c32_t)u1) << 18) & 0x001C0000UL);
+ if(dk3stream_my_read_byte(st, &c1)) { $? ". byte 2 ok"
+ u1 = (unsigned char)c1;
+ c32 |= ((((dk3_c32_t)u1) << 12) & 0x0003F000UL);
+ if(dk3stream_my_read_byte(st, &c1)) { $? ". byte 3 ok"
+ u1 = (unsigned char)c1;
+ c32 |= ((((dk3_c32_t)u1) << 6) & 0x00000FC0UL);
+ if(dk3stream_my_read_byte(st, &c1)) { $? ". byte 4 ok"
+ u1 = (unsigned char)c1;
+ c32 |= (((dk3_c32_t)u1) & 0x0000003FUL);
+ cc = 1;
+ } else {
+ /* ERROR: Incomplete sequence */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118);
+ }
+ }
+ } else {
+ /* ERROR: Incomplete sequence */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118);
+ }
+ }
+ } else {
+ /* ERROR: Incomplete sequence */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118);
+ }
+ }
+ } else {
+ if((u1 & 0xFC) == 0xF8) { $? ". 5 bytes"
+ c32 = ((((dk3_c32_t)u1) << 24) & 0x03000000UL);
+ if(dk3stream_my_read_byte(st, &c1)) { $? ". byte 2 ok"
+ u1 = (unsigned char)c1;
+ c32 |= ((((dk3_c32_t)u1) << 18) & 0x00FC0000UL);
+ if(dk3stream_my_read_byte(st, &c1)) { $? ". byte 3 ok"
+ u1 = (unsigned char)c1;
+ c32 |= ((((dk3_c32_t)u1) << 12) & 0x0003F000UL);
+ if(dk3stream_my_read_byte(st, &c1)) { $? ". byte 4 ok"
+ u1 = (unsigned char)c1;
+ c32 |= ((((dk3_c32_t)u1) << 6) & 0x00000FC0UL);
+ if(dk3stream_my_read_byte(st, &c1)) { $? ". byte 5 ok"
+ u1 = (unsigned char)c1;
+ c32 |= (((dk3_c32_t)u1) & 0x0000003FUL);
+ cc = 1;
+ } else {
+ /* ERROR: Incomplete sequence */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118);
+ }
+ }
+ } else {
+ /* ERROR: Incomplete sequence */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118);
+ }
+ }
+ } else {
+ /* ERROR: Incomplete sequence */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118);
+ }
+ }
+ } else {
+ /* ERROR: Incomplete sequence */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118);
+ }
+ }
+ } else {
+ if((u1 & 0xFE) == 0xFC) { $? ". 6 bytes"
+ c32 = 0x40000000UL;
+ if(dk3stream_my_read_byte(st, &c1)) { $? ". byte 2 ok"
+ u1 = (unsigned char)c1;
+ c32 |= ((((dk3_c32_t)u1) << 24) & 0x3F000000UL);
+ if(dk3stream_my_read_byte(st, &c1)) { $? ". byte 3 ok"
+ u1 = (unsigned char)c1;
+ c32 |= ((((dk3_c32_t)u1) << 18) & 0x00FC0000UL);
+ if(dk3stream_my_read_byte(st, &c1)) { $? ". byte 4 ok"
+ u1 = (unsigned char)c1;
+ c32 |= ((((dk3_c32_t)u1) << 12) & 0x0003F000UL);
+ if(dk3stream_my_read_byte(st, &c1)) {
+ u1 = (unsigned char)c1; $? ". byte 5 ok"
+ c32 |= ((((dk3_c32_t)u1) << 6) & 0x00000FC0UL);
+ if(dk3stream_my_read_byte(st, &c1)) {
+ u1 = (unsigned char)c1; $? ". byte 6 ok"
+ c32 |= (((dk3_c32_t)u1) & 0x0000003FUL);
+ cc = 1;
+ } else {
+ /* ERROR: Incomplete sequence */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118);
+ }
+ }
+ } else {
+ /* ERROR: Incomplete sequence */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118);
+ }
+ }
+ } else {
+ /* ERROR: Incomplete sequence */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118);
+ }
+ }
+ } else {
+ /* ERROR: Incomplete sequence */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118);
+ }
+ }
+ } else {
+ /* ERROR: Incomplete sequence */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118);
+ }
+ }
+ } else {
+ }
+ }
+ }
+ }
+ }
+ } else {
+ c32 = ((dk3_c32_t)u1) & 0x000000FFUL;
+ cc = 1;
+ }
+ }
+ } break;
+ case DK3_FILE_ENCODING_UTF16_MSB_FIRST:
+ case DK3_FILE_ENCODING_UTF16_LSB_FIRST:
+ { $? ". UTF-16"
+#if VERSION_BEFORE_20150821
+ surrogate = 0;
+#endif
+ if(dk3stream_my_read_byte(st, &c1)) { $? ". c1=%02x", (int)c1
+ if(dk3stream_my_read_byte(st, &c2)) { $? ". c2=%02x", (int)c2
+ if(myie == DK3_FILE_ENCODING_UTF16_MSB_FIRST) {
+ uc1 = (((dk3_c32_t)c1) << 8) & 0x0000FF00UL;
+ uc2 = ((dk3_c32_t)c2) & 0x000000FFUL;
+ } else {
+ uc1 = (((dk3_c32_t)c2) << 8) & 0x0000FF00UL;
+ uc2 = ((dk3_c32_t)c1) & 0x000000FFUL;
+ }
+ c32 = (uc1 | uc2); $? ". c32=%08lx", (unsigned long)c32
+#if 0
+ if((c32 & 0x0000DC00UL) == 0x0000DC00UL)
+#else
+ if((c32 & 0x0000FC00UL) == 0x0000DC00UL)
+#endif
+ { $? ". low surr"
+ if(dk3stream_my_read_byte(st, &c1)) { $? ". b1 ok"
+ if(dk3stream_my_read_byte(st, &c2)) { $? ". b2 ok"
+ if(myie == DK3_FILE_ENCODING_UTF16_MSB_FIRST) {
+ uc1 = (((dk3_c32_t)c1) << 8) & 0x0000FF00UL;
+ uc2 = ((dk3_c32_t)c2) & 0x000000FFUL;
+ } else {
+ uc1 = (((dk3_c32_t)c2) << 8) & 0x0000FF00UL;
+ uc2 = ((dk3_c32_t)c1) & 0x000000FFUL;
+ }
+ uc1 |= uc2;
+#if 0
+ if((uc1 & 0x0000DC00UL) == 0x0000D800UL)
+#else
+ if((uc1 & 0x0000FC00UL) == 0x0000D800UL)
+#endif
+ {
+ uc1 &= 0x000003FFUL;
+ uc1 = (uc1 << 10);
+ uc1 &= 0x000FFC00UL;
+ c32 &= 0x000003FFUL;
+ c32 |= uc1;
+ c32 += 0x00010000UL;
+ cc = 1;
+ } else {
+ /* ERROR: Decoding. */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 119);
+ }
+ }
+ } else {
+ /* ERROR: Incomplete sequence */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 119);
+ }
+ }
+ } else {
+ /* ERROR: Incomplete sequence */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 119);
+ }
+ }
+ } else {
+#if 0
+ if((c32 & 0x0000DC00UL) == 0x0000D800UL)
+#else
+ if((c32 & 0x0000FC00UL) == 0x0000D800UL)
+#endif
+ { $? ". hi surr"
+ if(dk3stream_my_read_byte(st, &c1)) { $? ". b1 ok"
+ if(dk3stream_my_read_byte(st, &c2)) { $? ". b2 ok"
+ if(myie == DK3_FILE_ENCODING_UTF16_MSB_FIRST) {
+ uc1 = (((dk3_c32_t)c1) << 8) & 0x0000FF00UL;
+ uc2 = ((dk3_c32_t)c2) & 0x000000FFUL;
+ } else {
+ uc1 = (((dk3_c32_t)c2) << 8) & 0x0000FF00UL;
+ uc2 = ((dk3_c32_t)c1) & 0x000000FFUL;
+ }
+ uc1 |= uc2;
+#if 0
+ if((uc1 & 0x0000DC00UL) == 0x0000DC00UL)
+#else
+ if((uc1 & 0x0000DF00UL) == 0x0000DC00UL)
+#endif
+ {
+ c32 &= 0x000003FFUL;
+ c32 = (c32 << 10);
+ c32 &= 0x000FFC00UL;
+ uc1 &= 0x000003FFUL;
+ c32 |= uc1;
+ c32 += 0x00010000UL;
+ cc = 1;
+ } else {
+ /* ERROR: Decoding. */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 119);
+ }
+ }
+ } else {
+ /* ERROR: Incomplete sequence */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 119);
+ }
+ }
+ } else {
+ /* ERROR: Incomplete sequence */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 119);
+ }
+ }
+ } else { $? ". no surr"
+ cc = 1;
+ }
+ }
+ } else {
+ /* ERROR: Incomplete word. */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 119);
+ }
+ }
+ }
+ }
+ break;
+ case DK3_FILE_ENCODING_UNICODE_MSB_FIRST:
+ case DK3_FILE_ENCODING_UNICODE_LSB_FIRST:
+ { $? ". UC32"
+ if(dk3stream_my_read_byte(st, &c1)) { $? ". byte 1 ok"
+ if(dk3stream_my_read_byte(st, &c2)) { $? ". byte 2 ok"
+ if(dk3stream_my_read_byte(st, &c3)) { $? ". byte 3 ok"
+ if(dk3stream_my_read_byte(st, &c4)) { $? ". byte 4 ok"
+ if(myie == DK3_FILE_ENCODING_UNICODE_MSB_FIRST) {
+ uc1 = (((dk3_c32_t)c1) << 24) & 0xFF000000UL;
+ uc2 = (((dk3_c32_t)c2) << 16) & 0x00FF0000UL;
+ uc3 = (((dk3_c32_t)c3) << 8) & 0x0000FF00UL;
+ uc4 = (((dk3_c32_t)c4) ) & 0x000000FFUL;
+ } else {
+ uc1 = (((dk3_c32_t)c4) << 24) & 0xFF000000UL;
+ uc2 = (((dk3_c32_t)c3) << 16) & 0x00FF0000UL;
+ uc3 = (((dk3_c32_t)c2) << 8) & 0x0000FF00UL;
+ uc4 = (((dk3_c32_t)c1) ) & 0x000000FFUL;
+ }
+ cc = 1;
+ c32 = (uc1 | uc2 | uc3 | uc4);
+ } else {
+ /* ERROR: Incomplete DWORD */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 218);
+ }
+ }
+ } else {
+ /* ERROR: Incomplete DWORD */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 218);
+ }
+ }
+ } else {
+ /* ERROR: Incomplete DWORD */
+ if(st->app) {
+ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 218);
+ }
+ }
+ }
+ }
+ break;
+ }
+ if(cc) { $? ". character found"
+ if(c32 != 0x0000FEFFUL) { $? ". not BOM"
+ switch(myie) {
+ case DK3_FILE_ENCODING_UTF16_MSB_FIRST: {
+ if(c32 == 0x0000FFFEUL) { $? ". BOM inverted"
+ myie = DK3_FILE_ENCODING_UTF16_LSB_FIRST;
+ done = 1; $? ". myie = %d", myie
+ }
+ } break;
+ case DK3_FILE_ENCODING_UTF16_LSB_FIRST: {
+ if(c32 == 0x0000FFFEUL) { $? ". BOM inverted"
+ myie = DK3_FILE_ENCODING_UTF16_MSB_FIRST;
+ done = 1; $? ". myie = %d", myie
+ }
+ } break;
+ case DK3_FILE_ENCODING_UNICODE_MSB_FIRST: {
+ if((unsigned long)c32 == 0xFFFE0000UL) { $? ". BOM inverted"
+ myie = DK3_FILE_ENCODING_UNICODE_LSB_FIRST;
+ done = 1; $? ". myie = %d", myie
+ }
+ } break;
+ case DK3_FILE_ENCODING_UNICODE_LSB_FIRST: {
+ if((unsigned long)c32 == 0xFFFE0000UL) { $? ". BOM inverted"
+ myie = DK3_FILE_ENCODING_UNICODE_MSB_FIRST;
+ done = 1; $? ". myie = %d", myie
+ }
+ } break;
+ }
+ if(!done) { $? ". process character 0x%08lx=%lu (%!8c)", (unsigned long)c32, (unsigned long)c32, (char)c32
+ res = (*hf)(obj, c32);
+ if(res < 1) { back = 0; if(res < 0) { cc = 0; } }
+ }
+ if(c32 == 0x0000000AUL) { $? ". new line"
+ lineno++;
+ /* Set line number */
+ if(st->app) {
+ dk3app_set_source_line((dk3_app_t *)(st->app), lineno);
+ }
+ }
+ }
+ }
+ } while(cc);
+ if(st->app) {
+ dk3app_set_source_line((dk3_app_t *)(st->app), oldlineno);
+ }
+ } $? "- dk3stream_process_chars %d", back
+ return back;
+}
+
+
+
+/* NOTE: This function does not check the BOM at start of files.
+ Whenever applicable, use dk3stream_process_filename_chars_app()
+ instead.
+*/
+int
+dk3stream_process_file_chars_app(
+ void *obj,
+ dk3_char_handler_t *hf,
+ FILE *fipo,
+ dkChar const *fn,
+ int ie,
+ dk3_app_t *app
+)
+{
+ int back = 0;
+ dkChar const *oldsourcefile = NULL;
+ unsigned long oldsourceline = 0UL;
+ dk3_stream_t *is = NULL;
+ $? "+ dk3stream_process_file_chars_app"
+ if((hf) && (fipo)) { $? ". input encoding = %d", ie
+ if(app) {
+ oldsourcefile = dk3app_get_source_file(app);
+ oldsourceline = dk3app_get_source_line(app);
+ dk3app_set_source_file(app, fn);
+ }
+ is = dk3stream_open_file_app(fipo, DK3_STREAM_FLAG_READ, app);
+ if(is) {
+ back = dk3stream_process_chars(is, obj, hf, ie);
+ dk3stream_close(is);
+ }
+ if(app) {
+ dk3app_set_source_file(app, oldsourcefile);
+ dk3app_set_source_line(app, oldsourceline);
+ }
+ } $? "- dk3stream_process_file_chars_app %d", back
+ return back;
+}
+
+
+
+int
+dk3stream_process_filename_chars_app(
+ void *obj,
+ dk3_char_handler_t *hf,
+ dkChar const *fn,
+ int de,
+ dk3_app_t *app
+)
+{
+ char bombuf[4];
+ FILE *fipo; /* Input file. */
+ size_t skb;
+ int back = 0;
+ int ie; /* Input encoding. */
+ $? "+ dk3stream_process_filename_chars_app \"%!ds\"", TR_STR(fn)
+ if((hf) && (fn)) {
+ ie = de; $? ". ie (original) = %d", ie
+ skb = 0;
+ ie = dk3sf_inspect_bom_skip_app(fn, ie, &skb, NULL); $? ". ie (BOM) = %d", ie
+ fipo = dk3sf_fopen_app(fn, dk3app_not_localized(36), app);
+ if(fipo) {
+ if((skb > 0) && (skb <=4)) {
+ dk3sf_fread_app(bombuf, 1, skb, fipo, app);
+ }
+ back = dk3stream_process_file_chars_app(obj, hf, fipo, fn, ie, app);
+ fclose(fipo);
+ }
+ } $? "- dk3stream_process_filename_chars_app %d", back
+ return back;
+}
+
+
+
+/** Add one found 32-bit character to input line,
+ process input line if newline found or if buffer is full.
+ @param lhv A dk3_line_handler_data_t pointer.
+ @param c32 Current character to process.
+ @return 1=OK, can continue, 0=error, can continue, -1=error, abort.
+*/
+static
+int
+dk3stream_add_character_to_line(void *lhv, dk3_c32_t c32)
+{
+ int back = 1;
+ dk3_line_handler_data_t *lh;
+ dkChar *cp; /* Current position. */
+ int res; /* Handler result. */
+#if DK3_CHAR_SIZE > 1
+ dk3_c16_t u16p[8]; /* Buffer UTF-16 */
+ size_t used; /* Elements used in u16p. */
+ size_t i; /* Running index. */
+#else
+ unsigned char uc; /* Unsigned char. */
+ char c; /* Current char. */
+ unsigned char u8p[8]; /* Buffer UTF-8. */
+ size_t used; /* Elements used in u8p. */
+ size_t i; /* Running index. */
+#endif
+ $? "+ dk3stream_add_character_to_line"
+ lh = (dk3_line_handler_data_t *)lhv;
+#if DK3_CHAR_SIZE > 1
+ used = dk3enc_uc2utf16(c32, u16p, DK3_SIZEOF(u16p,dk3_c16_t));
+ if(used > 0) {
+ if((lh->bufus + used) < (lh->szbuf - 1)) {
+ cp = lh->cp;
+ for(i = 0; i < used; i++) { cp[i] = u16p[i]; }
+ cp = &(cp[used]);
+ *cp = dkT('\0');
+ lh->cp = cp;
+ lh->bufus += used;
+ if(c32 == 0x0000000AUL) {
+ /* FLUSH OUTPUT */
+ (lh->buf)[lh->szbuf - 1] = dkT('\0');
+ res = (*(lh->hf))(lh->obj, lh->buf);
+ if(res < 1) {
+ back = 0;
+ if(res < 0) {
+ back = -1;
+ }
+ }
+ /* Start new line */
+ lh->cp = lh->buf;
+ (lh->buf)[0] = '\0';
+ lh->bufus = 0;
+ }
+ } else {
+ back = 0;
+ /* Warning: Line too long */
+ if(lh->app) {
+ dk3app_log_i1((dk3_app_t *)(lh->app), DK3_LL_WARNING, 108);
+ }
+ (lh->buf)[lh->szbuf - 1] = dkT('\0');
+ res = (*(lh->hf))(lh->obj, lh->buf);
+ if(res < -1) { back = -1; }
+ cp = lh->buf;
+ for(i = 0; i < used; i++) { cp[i] = u16p[i]; }
+ cp = &(cp[used]);
+ *cp = dkT('\0');
+ lh->cp = cp;
+ lh->bufus = used;
+ if(c32 == 0x0000000AUL) {
+ lh->cp = lh->buf;
+ *(lh->buf) = dkT('\0');
+ lh->bufus = 0;
+ }
+ }
+ } else {
+ /* ERROR: Encoding failed! */
+ if(lh->app) {
+ dk3app_log_i1((dk3_app_t *)(lh->app), DK3_LL_ERROR, 119);
+ }
+ }
+#else
+ $? ". 1 byte character"
+ if(lh->se == DK3_ENCODING_UTF8) { $? ". process character as UTF-8"
+ used = dk3enc_uc2utf8(c32, u8p, sizeof(u8p));
+ if(used > 0) { $? ". conversion result ok"
+ if((lh->bufus + used) < (lh->szbuf - 1)) { $? ". buffer length ok"
+ cp = lh->cp; $? ". copy bytes"
+ for(i = 0; i < used; i++) { cp[i] = u8p[i]; }
+ cp = &(cp[used]); $? ". copy ok"
+ *cp = '\0';
+ lh->cp = cp;
+ lh->bufus += used; $? ". buffer used %u", (unsigned)(lh->bufus)
+ if(c32 == 0x0000000AUL) { $? ". newline"
+ /* FLUSH OUTPUT */
+ (lh->buf)[lh->szbuf - 1] = dkT('\0');
+ res = (*(lh->hf))(lh->obj, lh->buf);
+ if(res < 1) {
+ back = 0;
+ if(res < 0) {
+ back = -1;
+ }
+ }
+ /* Start new line */
+ lh->cp = lh->buf;
+ (lh->buf)[0] = '\0';
+ lh->bufus = 0;
+ } $? ". processing finished"
+ } else { $? "! line too long"
+ back = 0;
+ /* Warning: Line too long! */
+ if(lh->app) {
+ dk3app_log_i1(lh->app, DK3_LL_WARNING, 108);
+ }
+ /* FLUSH OUTPUT */
+ (lh->buf)[lh->szbuf - 1] = dkT('\0');
+ res = (*(lh->hf))(lh->obj, lh->buf);
+ if(res < -1) { back = -1; }
+ /* Start new line. */
+ cp = lh->buf;
+ for(i = 0; i < used; i++) { cp[i] = u8p[i]; }
+ cp = &(cp[used]);
+ *cp = '\0';
+ lh->cp = cp;
+ lh->bufus = used;
+ if(c32 == 0x0000000AUL) {
+ *(lh->buf) = '\0';
+ lh->cp = lh->buf;
+ lh->bufus = 0;
+ }
+ }
+ } else { $? "! UTF-8 conversion failed"
+ back = 0;
+ /* ERROR: Encoding failed! */
+ if(lh->app) { $? "! conversion to UTF-8"
+ dk3app_log_i1(lh->app, DK3_LL_ERROR, 115);
+ }
+ }
+ } else { $? ". process plain character"
+ if((unsigned long)c32 > 0x000000FFUL) {
+ /* Warning: Character out of range. */
+ if(lh->app) {
+ dk3app_log_i1(lh->app, DK3_LL_WARNING, 219);
+ }
+ }
+ uc = (unsigned char)c32;
+ c = (char)uc;
+ if((lh->bufus + 1) < (lh->szbuf - 1)) {
+ cp = lh->cp;
+ *(cp++) = c;
+ *cp = '\0';
+ lh->cp = cp;
+ lh->bufus += 1;
+ if(c32 == 0x0000000AUL) {
+ /* FLUSH OUTPUT */
+ (lh->buf)[lh->szbuf - 1] = dkT('\0');
+ res = (*(lh->hf))(lh->obj, lh->buf);
+ if(res < 1) {
+ back = 0;
+ if(res < 0) {
+ back = -1;
+ }
+ }
+ /* Start new line */
+ lh->cp = lh->buf;
+ (lh->buf)[0] = '\0';
+ lh->bufus = 0;
+ }
+ } else {
+ back = 0;
+ /* Warning: Line too long! */
+ if(lh->app) {
+ dk3app_log_i1(lh->app, DK3_LL_WARNING, 108);
+ }
+ /* FLUSH OUTPUT */
+ (lh->buf)[lh->szbuf - 1] = dkT('\0');
+ res = (*(lh->hf))(lh->obj, lh->buf);
+ if(res < -1) { back = -1; }
+ /* Start new line. */
+ cp = lh->buf;
+ *(cp++) = c;
+ *cp = '\0';
+ lh->cp = cp;
+ lh->bufus = 1;
+ if(c32 == 0x0000000AUL) {
+ *(lh->buf) = '\0';
+ lh->cp = lh->buf;
+ lh->bufus = 0;
+ }
+ }
+ }
+#endif
+ $? "- dk3stream_add_character_to_line %d", back
+ return back;
+}
+
+
+
+int
+dk3stream_process_lines(
+ dk3_stream_t *st,
+ void *obj,
+ dk3_line_handler_t *hf,
+ dkChar *buf,
+ size_t szbuf,
+ int se,
+ int ie
+)
+{
+ int back = 0;
+ dk3_line_handler_data_t lh;
+ $? "+ dk3stream_process_lines"
+ if((st) && (hf) && (buf) && (szbuf)) {
+ lh.app = (dk3_app_t *)(st->app);
+ lh.obj = obj;
+ lh.hf = hf;
+ lh.buf = buf;
+ buf[0] = dkT('\0');
+ lh.szbuf = szbuf;
+ lh.cp = lh.buf;
+ lh.bufus = 0;
+ lh.se = se;
+ back = dk3stream_process_chars(
+ st, (void *)(&lh), dk3stream_add_character_to_line, ie
+ );
+ } $? "- dk3stream_process_lines %d", back
+ return back;
+}
+
+
+
+/* NOTE: This function does not check for a BOM at the beginning
+ of the file. Whenever applicable, use
+ dk3stream_process_filename_lines_app() instead.
+*/
+int
+dk3stream_process_file_lines_app(
+ void *obj,
+ dk3_line_handler_t *hf,
+ FILE *fipo,
+ dkChar const *fn,
+ dkChar *buf,
+ size_t szbuf,
+ int se,
+ int ie,
+ dk3_app_t *app
+)
+{
+ int back = 0;
+ dkChar const *oldsourcename = NULL;
+ unsigned long oldsourceline = 0UL;
+ dk3_stream_t *is;
+ $? "+ dk3stream_process_file_lines_app"
+ if((hf) && (fipo)) { $? ". args ok"
+ if(app) { $? ". saving old position"
+ oldsourcename = dk3app_get_source_file(app);
+ oldsourceline = dk3app_get_source_line(app);
+ dk3app_set_source_file(app, fn);
+ dk3app_set_source_line(app, 1UL);
+ }
+ is = dk3stream_open_file_app(fipo, DK3_STREAM_FLAG_READ, app);
+ if(is) { $? ". stream opened"
+ back = dk3stream_process_lines(is, obj, hf, buf, szbuf, se, ie);
+ dk3stream_close(is);
+ } else { $? "! no stream"
+ }
+ if(app) { $? ". restoring old position"
+ dk3app_set_source_file(app, oldsourcename);
+ dk3app_set_source_line(app, oldsourceline);
+ }
+ } $? "- dk3stream_process_file_lines_app %d", back
+ return back;
+}
+
+
+
+int
+dk3stream_process_filename_lines_app(
+ void *obj,
+ dk3_line_handler_t *hf,
+ dkChar const *fn,
+ dkChar *buf,
+ size_t szbuf,
+ int se,
+ int de,
+ dk3_app_t *app
+)
+{
+ char bombuf[4];
+ FILE *fipo; /* Input file. */
+ size_t skb; /* Bytes to skip at start of input. */
+ int ie; /* Input encoding. */
+ int back = 0;
+ $? "+ dk3stream_process_filename_lines_app \"%!ds\" %d", TR_STR(fn), de
+ if((hf) && (fn)) {
+ ie = dk3sf_inspect_bom_skip_app(fn, de, &skb, app); $? ". ie=%d", ie
+ fipo = dk3sf_fopen_app(fn, dk3app_not_localized(36), app);
+ if(fipo) { $? ". file opened"
+ if((skb > 0) && (skb <= 4)) {
+ dk3sf_fread_app(bombuf, 1, skb, fipo, app);
+ }
+ back = dk3stream_process_file_lines_app(
+ obj, hf, fipo, fn, buf, szbuf, se, ie, app
+ );
+ fclose(fipo);
+ }
+ } $? "- dk3stream_process_filename_lines_app %d", back
+ return back;
+}
+
+
+
+int
+dk3stream_process_filename_sanitized_lines_app(
+ void *obj,
+ dk3_line_handler_t *hf,
+ dkChar const *fn,
+ dkChar *buf,
+ size_t szbuf,
+ int se,
+ int de,
+ dk3_app_t *app
+)
+{
+ char bombuf[4];
+#if DK3_HAVE_SETVBUF
+ char *filebuf = NULL; /* File buffer. */
+#endif
+ FILE *fipo; /* Input file. */
+ size_t skb; /* Bytes to skip at start of input. */
+ int ie; /* Input encoding. */
+ int back = 0;
+ $? "+ dk3stream_process_filename_lines_app \"%!ds\" %d", TR_STR(fn), de
+ if((hf) && (fn)) {
+ ie = dk3sf_inspect_bom_skip_app(fn, de, &skb, app); $? ". ie=%d", ie
+#if DK3_HAVE_SETVBUF
+ filebuf = dk3_new_app(char,BUFSIZ,app);
+ if (NULL != filebuf) {
+#endif
+ fipo = dk3sf_fopen_app(fn, dk3app_not_localized(36), app);
+ if(fipo) { $? ". file opened"
+#if DK3_HAVE_SETVBUF
+ if (0 == setvbuf(fipo, filebuf, _IOFBF, BUFSIZ)) {
+#endif
+ if((skb > 0) && (skb <= 4)) {
+ dk3sf_fread_app(bombuf, 1, skb, fipo, app);
+ }
+ back = dk3stream_process_file_lines_app(
+ obj, hf, fipo, fn, buf, szbuf, se, ie, app
+ );
+#if DK3_HAVE_SETVBUF
+ } else {
+ /* ERROR: Failed to set buffer for file */
+ dk3app_log_i3(app, DK3_LL_ERROR, 412, 413, fn);
+ }
+#endif
+ fclose(fipo);
+ }
+#if DK3_HAVE_SETVBUF
+ dk3mem_reset_secure(filebuf, BUFSIZ);
+ dk3mem_free(filebuf); filebuf = NULL;
+ }
+#endif
+ } $? "- dk3stream_process_filename_lines_app %d", back
+ return back;
+}
+
+
+int
+dk3strm_double_c8_str_no_sci(dk3_stream_t *os, char *buffer)
+{
+ char *start; /* Start of string. */
+ char *eptr; /* Start of exponent substring. */
+ char *ptr; /* Traverse string. */
+ size_t lgt; /* String length. */
+ int dp; /* Decimal dot position. */
+ int exponent; /* Exponent. */
+ int i; /* Traverse the string. */
+ int back = 1; /* Result */
+ char chr; /* Character to write out */
+ $? "+ dk3ma_print_double_c8_str_no_sci"
+ if((os) && (buffer)) {
+ eptr = NULL;
+ start = buffer;
+ /*
+ Print sign.
+ */
+ switch(*start) {
+ case '-': {
+ if (1 != dk3stream_write_bytes(os, start, 1)) { back = 0; }
+ start++;
+ } break;
+ case '+': {
+ start++;
+ } break;
+ }
+ /*
+ Find exponent substring and exponent.
+ */
+ eptr = NULL;
+ ptr = start;
+ while(*ptr) {
+ switch(*ptr) {
+ case 'e': case 'E': {
+ eptr = ptr;
+ } break;
+ }
+ ptr++;
+ }
+ if(eptr) {
+ *(eptr++) = '\0';
+#if VERSION_BEFORE_20140716
+ if(sscanf(eptr, "%d", &exponent) != 1)
+#else
+ if (0 == dk3ma_i_from_c8_string(&exponent, eptr, NULL))
+#endif
+ {
+ exponent = 0;
+ }
+ } else {
+ exponent = 0;
+ }
+ /*
+ Find decimal dot.
+ */
+ eptr = strchr(start, '.');
+ if(eptr) {
+ /*
+ Keep dot position in dp, squeeze string.
+ */
+ *eptr = '\0';
+ dp = (int)strlen(start);
+ *eptr = '.';
+ while(*eptr) {
+ eptr[0] = eptr[1];
+ eptr++;
+ }
+ } else {
+ /*
+ Dot position is after the string.
+ */
+ dp = (int)strlen(start);
+ }
+ /*
+ Correct dot position.
+ */
+ dp = dp + exponent;
+ /*
+ Remove leading zeroes (if any).
+ */
+ while('0' == *start) {
+ start++; dp--;
+ }
+ /*
+ Remove trailing zeroes (if any).
+ */
+ eptr = NULL;
+ ptr = start;
+ while(*ptr) {
+ if('0' == *ptr) {
+ if(!(eptr)) { eptr = ptr; }
+ } else {
+ eptr = NULL;
+ }
+ ptr++;
+ }
+ if(eptr) { *eptr = '\0'; }
+ lgt = strlen(start);
+ if(0 < lgt) {
+ if(dp >= (int)lgt) {
+ /*
+ Decimal dot is at end or after string.
+ */
+ if (1 != dk3stream_c8_fputs(os, start)) { back = 0; }
+ /*
+ Decimal dot is after the string.
+ */
+ for(i = 0; i < (dp - (int)lgt); i++) {
+ chr = '0';
+ if (1 != dk3stream_write_bytes(os, &chr, 1)) { back = 0; }
+ }
+ } else {
+ if(dp <= 0) {
+ /*
+ Decimal dot is before the string.
+ */
+ chr = '0';
+ if (1 != dk3stream_write_bytes(os, &chr, 1)) { back = 0; }
+ chr = '.';
+ if (1 != dk3stream_write_bytes(os, &chr, 1)) { back = 0; }
+ chr = 0;
+ while(dp++ < 0) {
+ if (1 != dk3stream_write_bytes(os, &chr, 1)) { back = 0; }
+ }
+ if (1 != dk3stream_c8_fputs(os, start)) { back = 0; }
+ } else {
+ /*
+ Decimal dot is in the string.
+ */
+ for(i = 0; i < (int)lgt; i++) {
+ if(dp == i) {
+ chr = '.';
+ if (1 != dk3stream_write_bytes(os, &chr, 1)) { back = 0; }
+ }
+ if (1 != dk3stream_write_bytes(os, &(start[i]), 1)) { back = 0; }
+ }
+ }
+ }
+ } else {
+ /*
+ No non-zero digits in string.
+ */
+ chr = '0';
+ if (1 != dk3stream_write_bytes(os, &chr, 1)) { back = 0; }
+ }
+ } $? "- dk3ma_print_double_c8_str_no_sci"
+ return back;
+}
+
+
+
+int
+dk3strm_double_c8_no_sci(dk3_stream_t *os, double x)
+{
+ char buffer[64];
+ char *ptr;
+ int back = 0;
+ if (NULL != os) {
+ if (1 == sprintf(buffer, "%g", x)) {
+ ptr = buffer;
+ while(*ptr) { if (',' == *ptr) { *ptr = '.'; } ptr++; }
+ back = dk3strm_double_c8_str_no_sci(os, buffer);
+ }
+ }
+ return back;
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dk3strm.h b/support/dktools/dk3strm.h
new file mode 100644
index 0000000000..1d1688cdca
--- /dev/null
+++ b/support/dktools/dk3strm.h
@@ -0,0 +1,459 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3strm.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3strm.h Header file for the dk3strm module.
+*/
+
+#ifndef DK3STRM_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3STRM_H_INCLUDED 1
+
+
+#line 10 "dk3strm.ctr"
+
+#include "dk3conf.h"
+#include "dk3types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open a stream, allocate memory.
+ @param d Stream data object.
+ @param f Stream low-level function.
+ @param fl Flags to indicate read and/or write access.
+ @param app Application structure, used for diagnostics.
+ @return Pointer to new stream on success, NULL on error.
+*/
+dk3_stream_t *
+dk3stream_open_app(void *d, dk3_stream_api_fct_t *f, int fl, dk3_app_t *app);
+
+/** Close a stream, release memory.
+ @param st Stream to close.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3stream_close(dk3_stream_t *st);
+
+/** Set up automatic flushing when writing newlines.
+ @param st Stream to set up.
+ @param fl Flag value (0=no flush, 1=flush buffer,
+ 2=buffer and low-level object).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3stream_set_line_flush(dk3_stream_t *st, int fl);
+
+/** Write a buffer of bytes to stream.
+ @param st Stream to write to.
+ @param sb Source buffer.
+ @param sz Size of \ sb (number of bytes).
+ The size must not exceed 32767 as it is converted to int
+ for some compression libraries.
+ @return Number of bytes written.
+*/
+size_t
+dk3stream_write_bytes(dk3_stream_t *st, char const *sb, size_t sz);
+
+/** Read bytes into buffer.
+ @param st Stream to read from.
+ @param db Destination buffer address.
+ @param sz Size of \a db in bytes.
+ The size must not exceed 32767 as it is converted to int
+ for some compression libraries.
+ @return Number of bytes read (may be 0).
+*/
+size_t
+dk3stream_read_bytes(dk3_stream_t *st, char *db, size_t sz);
+
+/** Check whether end of input data was reached.
+ @param st Stream to check.
+ @return 1 for end of input reached, 0 otherwise.
+*/
+int
+dk3stream_feof(dk3_stream_t const *st);
+
+/** Get a text line (8-bit characters).
+ @param st Stream to read from.
+ @param db Destination buffer.
+ @param sz Size of \a db in bytes.
+ The size must not exceed 32767 as it is converted to int
+ for some compression libraries.
+ @return 1 on success (line found), 0 on error.
+*/
+int
+dk3stream_c8_fgets(dk3_stream_t *st, char *db, size_t sz);
+
+/** Write a text line (8-bit characters) without any re-encoding.
+ @param st Stream to write to.
+ @param str Text to write.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3stream_c8_fputs(dk3_stream_t *st, char const *str);
+
+/** Set output encoding.
+ @param st Stream to set up.
+ @param oe New output encoding.
+*/
+void
+dk3stream_set_output_encoding(dk3_stream_t *st, int oe);
+
+/** Write byte order marker 0xFEFF converted to the streams
+ output encoding.
+ @param st Stream to write to.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3stream_write_byte_order_marker(dk3_stream_t *st);
+
+/** Write byte order marker if necessary on the system.
+ @param st Stream to write to.
+ @param se System encoding.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3stream_write_byte_order_marker_if_necessary(dk3_stream_t *st, int se);
+
+/** Write 8-bit character text, convert to the streams output encoding.
+ @param st Stream to write to.
+ @param s String to write.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3stream_fputs_c8_plain(dk3_stream_t *st, char const *s);
+
+/** Write UTF-8 encoded text, convert to the streams output encoding.
+ @param st Stream to write to.
+ @param s String to write.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3stream_fputs_c8_utf8(dk3_stream_t *st, char const *s);
+
+/** Write UTF-16 encoded text, convert to the streams output encoding.
+ @param st Stream to write to.
+ @param s String to write.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3stream_fputs_c16(dk3_stream_t *st, dk3_c16_t const *s);
+
+/** Write UNICODE text, convert to the streams output encoding.
+ @param st Stream to write to.
+ @param s String to write.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3stream_fputs_c32(dk3_stream_t *st, dk3_c32_t const *s);
+
+/** Write generic dkChar text, convert to the streams output encoding.
+ @param st Stream to write to.
+ @param s String to write.
+ @param ie Input encoding (used for 8-bit characters only).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3stream_strputs(dk3_stream_t *st, dkChar const *s, int ie);
+
+/** Write newline to stream.
+ @param st Stream to write to.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3stream_strnl(dk3_stream_t *st);
+
+/** Get number of bytes written.
+ @param st Stream to check.
+ @return Number of bytes written to the stream.
+*/
+dk3_um_t
+dk3stream_bytes_written(dk3_stream_t const *st);
+
+/** Open stream for a file. The file is not closed when the stream
+ is closed.
+ @param fi File.
+ @param fl Read/write flags.
+ @param app Application structure, used for diagnostics.
+ @return Stream pointer on success, NULL on error.
+*/
+dk3_stream_t *
+dk3stream_open_file_app(FILE *fi, int fl, dk3_app_t *app);
+
+/** Get 16-bit text line.
+ @param st Stream.
+ @param db Destination buffer.
+ @param sz Size of \a db (number of 16-bit characters).
+ The size must not exceed 16383 as buffer sizes arre converted to int
+ for some compression libraries.
+ @param msbfirst Flag: MSB first.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3stream_c16_fgets(dk3_stream_t *st, dk3_c16_t *db, size_t sz, int msbfirst);
+
+/** Get 32-bit text line.
+ @param st Stream.
+ @param db Destination buffer.
+ @param sz Size of \a db (number of 32-bit characters).
+ The size must not exceed 8191 as buffer sizes are converted to int
+ for some compression libraries and 4*8192 exceeds the int range
+ on 16-bit systems.
+ @param msbfirst Flag: MSB first.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3stream_c32_fgets(dk3_stream_t *st, dk3_c32_t *db, size_t sz, int msbfirst);
+
+#if DK3_HAVE_ZLIB_H
+/** Open stream for a gzFile. The gzFile is not closed when the stream
+ is closed.
+ @param g gzFile.
+ @param fl Read/write flags.
+ @param app Application structure, used for diagnostics.
+ @return Stream pointer on success, NULL on error.
+*/
+dk3_stream_t *
+dk3stream_open_gz_app(gzFile g, int fl, dk3_app_t *app);
+#endif
+
+#if DK3_HAVE_BZLIB_H
+/** Open stream for a BZFILE. The BZFILE is not closed when the stream
+ is closed.
+ @param b BZFILE.
+ @param fl Read/write flags.
+ @param app Application structure, used for diagnostics.
+ @return Stream pointer on success, NULL on error.
+*/
+dk3_stream_t *
+dk3stream_open_bz2_app(BZFILE *b, int fl, dk3_app_t *app);
+#endif
+
+/** Process an input stream character by character.
+ @param st Stream containing the input data to process.
+ @param obj Object to modify with input stream.
+ @param hf Character handler function.
+ @param ie Input encoding.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3stream_process_chars(
+ dk3_stream_t *st,
+ void *obj,
+ dk3_char_handler_t *hf,
+ int ie
+);
+
+/** Process all characters in a file.
+ NOTE: If you have the file name, you should use
+ dk3stream_process_filename_chars_app() instead. The
+ dk3stream_process_filename_chars_app() checks for a BOM at the
+ beginning of the file and corrects the input encoding if
+ necessary.
+ @param obj Object to modify while processing the input file.
+ @param hf Handler function.
+ @param fipo Input file.
+ @param fn File name.
+ @param ie Input file encoding.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3stream_process_file_chars_app(
+ void *obj,
+ dk3_char_handler_t *hf,
+ FILE *fipo,
+ dkChar const *fn,
+ int ie,
+ dk3_app_t *app
+);
+
+/** Process all characters in a file.
+ @param obj Object to modify while processing the input file.
+ @param hf Handler function.
+ @param fn File name.
+ @param de Default file encoding.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3stream_process_filename_chars_app(
+ void *obj,
+ dk3_char_handler_t *hf,
+ dkChar const *fn,
+ int de,
+ dk3_app_t *app
+);
+
+/** Put 32-bit character to stream, convert if necessary.
+ @param st Output stream.
+ @param c32 Character to write.
+ @param err_enc_rep Pointer to flag: Encoding error reported.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3stream_fputc_c32(dk3_stream_t *st, dk3_c32_t c32, int *err_enc_rep);
+
+/** Process stream contents line by line.
+ @param st Input stream.
+ @param obj Object to modify while processing input.
+ @param hf Handler function.
+ @param buf Buffer for input lines.
+ @param szbuf Size of \a buf (number of characters).
+ The size must not exceed 8191 as buffer sizes are converted to int
+ for some compression libraries and 4*8192 exceeds the int range
+ on 16-bit systems.
+ @param se System character encoding (DK3_ENCODING_xxx).
+ @param ie Input encoding (DK3_FILE_ENCODING_xxx).
+ @return 1 on success, 0 on error, -1 on error with abort.
+*/
+int
+dk3stream_process_lines(
+ dk3_stream_t *st,
+ void *obj,
+ dk3_line_handler_t *hf,
+ dkChar *buf,
+ size_t szbuf,
+ int se,
+ int ie
+);
+
+/** Process input file contents line by line.
+ NOTE: If you have a file name available, you should use
+ dk3stream_process_filename_lines_app() instead, as the
+ dk3stream_process_filename_lines_app() function checks for a BOM
+ at the start of the file and corrects the input encoding if
+ necessary.
+ @param obj Object to modify while processing input.
+ @param hf Handler function.
+ @param fipo Input file.
+ @param fn File name.
+ @param buf Input line buffer.
+ @param szbuf Size of \a buf (number of characters).
+ The size must not exceed 8191 as buffer sizes are converted to int
+ for some compression libraries.
+ @param se System character encoding (DK3_ENCODING_xxx).
+ @param ie Input encoding (DK3_FILE_ENCODING_xxx).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error, -1 on error with abort.
+*/
+int
+dk3stream_process_file_lines_app(
+ void *obj,
+ dk3_line_handler_t *hf,
+ FILE *fipo,
+ dkChar const *fn,
+ dkChar *buf,
+ size_t szbuf,
+ int se,
+ int ie,
+ dk3_app_t *app
+);
+
+/** Process input file line by line.
+ @param obj Object to modify while processing input.
+ @param hf Handler function.
+ @param fn File name.
+ @param buf Input line buffer.
+ @param szbuf Size of \a buf (number of characters).
+ The size must not exceed 8191 as buffer sizes are converted to int
+ for some compression libraries.
+ @param se System character encoding (DK3_ENCODING_xxx).
+ @param de Default file encoding (DK3_FILE_ENCODING_xxx).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error, -1 on error with abort.
+*/
+int
+dk3stream_process_filename_lines_app(
+ void *obj,
+ dk3_line_handler_t *hf,
+ dkChar const *fn,
+ dkChar *buf,
+ size_t szbuf,
+ int se,
+ int de,
+ dk3_app_t *app
+);
+
+/** Process input file line by line, sanitize file buffer.
+ @param obj Object to modify while processing input.
+ @param hf Handler function.
+ @param fn File name.
+ @param buf Input line buffer.
+ @param szbuf Size of \a buf (number of characters).
+ The size must not exceed 8191 as buffer sizes are converted to int
+ for some compression libraries.
+ @param se System character encoding (DK3_ENCODING_xxx).
+ @param de Default file encoding (DK3_FILE_ENCODING_xxx).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error, -1 on error with abort.
+*/
+int
+dk3stream_process_filename_sanitized_lines_app(
+ void *obj,
+ dk3_line_handler_t *hf,
+ dkChar const *fn,
+ dkChar *buf,
+ size_t szbuf,
+ int se,
+ int de,
+ dk3_app_t *app
+);
+
+/** Write double value to stream as text, avoid exponential notation.
+ @param os Stream to write to.
+ @param x Value to write.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3strm_double_c8_no_sci(dk3_stream_t *os, double x);
+
+/** Write double value from string buffer to stream, avoid exponential
+ notation.
+ @param os Stream to write to.
+ @param buffer Buffer containing double converted to text.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3strm_double_c8_str_no_sci(dk3_stream_t *os, char *buffer);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3strmb.c b/support/dktools/dk3strmb.c
new file mode 100644
index 0000000000..669ea64611
--- /dev/null
+++ b/support/dktools/dk3strmb.c
@@ -0,0 +1,161 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3strmb.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3strmb.c The dk3strmb module.
+*/
+
+
+#line 10 "dk3strmb.ctr"
+
+#include "dk3all.h"
+
+
+
+
+
+
+#line 16 "dk3strmb.ctr"
+
+
+
+/** Low-level stream function to deal with bzip2 compression.
+ Closing the stream also closes the bzip2-file.
+ @param api API structure.
+*/
+static
+void
+dk3stream_bz_fct(dk3_stream_api_t *api)
+{
+#if DK3_HAVE_BZLIB_H
+ BZFILE *b = NULL; /* Low level I/O object. */
+ int res = 0; /* Operation result. */
+#endif
+ api->suc = 0;
+ (api->res).sz = 0;
+ (api->res).ec = DK3_ERROR_NOT_SUPPORTED;
+#if DK3_HAVE_BZLIB_H
+ b = (BZFILE *)((api->arg).d);
+ (api->res).ec = 0;
+ switch(api->cmd) {
+ case DK3_STREAM_API_READ: {
+ if(((api->arg).b) && ((api->arg).sz) && ((api->arg).d)) {
+ res = BZ2_bzread(b, (api->arg).b, (int)((api->arg).sz));
+ if(res > 0) {
+ api->suc = 1; (api->res).ec = 0; (api->res).sz = (size_t)res;
+ }
+ }
+ } break;
+ case DK3_STREAM_API_WRITE: {
+ if(((api->arg).b) && ((api->arg).sz) && ((api->arg).d)) {
+ res = BZ2_bzwrite(b, (api->arg).b, (int)((api->arg).sz));
+ if(res > 0) {
+ (api->res).sz = (size_t)res;
+ if((size_t)res == (api->arg).sz) {
+ api->suc = 1; (api->res).ec = 0;
+ }
+ }
+ }
+ } break;
+ case DK3_STREAM_API_FLUSH: {
+ if((api->arg).d) {
+ BZ2_bzflush(b);
+ api->suc = 1; (api->res).ec = 0;
+ /*
+ As the library manual explains BZ2_bzflush() does nothing.
+ So we always return success.
+ */
+ }
+ } break;
+ case DK3_STREAM_API_AT_END: {
+
+ } break;
+ case DK3_STREAM_API_CLOSE: {
+ if((api->arg).d) {
+ BZ2_bzclose(b);
+ api->suc = 1; (api->res).ec = 0;
+ }
+ } break;
+ case DK3_STREAM_API_ZERO_IS_END: {
+ api->suc = 1; (api->res).ec = 0; /* Correct if necessary */
+ } break;
+ case DK3_STREAM_API_ERROR: {
+ } break;
+ }
+#endif
+}
+
+
+
+/** Low-level stream function to deal with bzip2 compression.
+ Closing the stream does not close the bzip2 file.
+ @param api API structure.
+*/
+static
+void
+dk3stream_bz_fct_no_close(dk3_stream_api_t *api)
+{
+ if(api->cmd != DK3_STREAM_API_CLOSE) {
+ dk3stream_bz_fct(api);
+ } else {
+ api->suc = 1; (api->res).ec = 0;
+ }
+}
+
+
+
+#if DK3_HAVE_BZLIB_H
+
+/** Open a stream for an existing BZFILE.
+ @param b BZFILE already opened.
+ @param fl Read/write flags.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new stream on success, NULL on error.
+*/
+dk3_stream_t *
+dk3stream_open_bz2_app(BZFILE *b, int fl, dk3_app_t *app)
+{
+ dk3_stream_t *back = NULL;
+ if(b) {
+ back = dk3stream_open_app((void *)b, dk3stream_bz_fct_no_close, fl, app);
+ }
+ return back;
+}
+
+#endif
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dk3strmb.ctr b/support/dktools/dk3strmb.ctr
new file mode 100644
index 0000000000..4bae0cd06c
--- /dev/null
+++ b/support/dktools/dk3strmb.ctr
@@ -0,0 +1,127 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk3all.h"
+
+
+
+$(trace-include)
+
+
+
+/** Low-level stream function to deal with bzip2 compression.
+ Closing the stream also closes the bzip2-file.
+ @param api API structure.
+*/
+static
+void
+dk3stream_bz_fct(dk3_stream_api_t *api)
+{
+#if DK3_HAVE_BZLIB_H
+ BZFILE *b = NULL; /* Low level I/O object. */
+ int res = 0; /* Operation result. */
+#endif
+ api->suc = 0;
+ (api->res).sz = 0;
+ (api->res).ec = DK3_ERROR_NOT_SUPPORTED;
+#if DK3_HAVE_BZLIB_H
+ b = (BZFILE *)((api->arg).d);
+ (api->res).ec = 0;
+ switch(api->cmd) {
+ case DK3_STREAM_API_READ: {
+ if(((api->arg).b) && ((api->arg).sz) && ((api->arg).d)) {
+ res = BZ2_bzread(b, (api->arg).b, (int)((api->arg).sz));
+ if(res > 0) {
+ api->suc = 1; (api->res).ec = 0; (api->res).sz = (size_t)res;
+ }
+ }
+ } break;
+ case DK3_STREAM_API_WRITE: {
+ if(((api->arg).b) && ((api->arg).sz) && ((api->arg).d)) {
+ res = BZ2_bzwrite(b, (api->arg).b, (int)((api->arg).sz));
+ if(res > 0) {
+ (api->res).sz = (size_t)res;
+ if((size_t)res == (api->arg).sz) {
+ api->suc = 1; (api->res).ec = 0;
+ }
+ }
+ }
+ } break;
+ case DK3_STREAM_API_FLUSH: {
+ if((api->arg).d) {
+ BZ2_bzflush(b);
+ api->suc = 1; (api->res).ec = 0;
+ /*
+ As the library manual explains BZ2_bzflush() does nothing.
+ So we always return success.
+ */
+ }
+ } break;
+ case DK3_STREAM_API_AT_END: {
+
+ } break;
+ case DK3_STREAM_API_CLOSE: {
+ if((api->arg).d) {
+ BZ2_bzclose(b);
+ api->suc = 1; (api->res).ec = 0;
+ }
+ } break;
+ case DK3_STREAM_API_ZERO_IS_END: {
+ api->suc = 1; (api->res).ec = 0; /* Correct if necessary */
+ } break;
+ case DK3_STREAM_API_ERROR: {
+ } break;
+ }
+#endif
+}
+
+
+
+/** Low-level stream function to deal with bzip2 compression.
+ Closing the stream does not close the bzip2 file.
+ @param api API structure.
+*/
+static
+void
+dk3stream_bz_fct_no_close(dk3_stream_api_t *api)
+{
+ if(api->cmd != DK3_STREAM_API_CLOSE) {
+ dk3stream_bz_fct(api);
+ } else {
+ api->suc = 1; (api->res).ec = 0;
+ }
+}
+
+
+
+#if DK3_HAVE_BZLIB_H
+
+/** Open a stream for an existing BZFILE.
+ @param b BZFILE already opened.
+ @param fl Read/write flags.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new stream on success, NULL on error.
+*/
+dk3_stream_t *
+dk3stream_open_bz2_app(BZFILE *b, int fl, dk3_app_t *app)
+{
+ dk3_stream_t *back = NULL;
+ if(b) {
+ back = dk3stream_open_app((void *)b, dk3stream_bz_fct_no_close, fl, app);
+ }
+ return back;
+}
+
+#endif
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dk3strmg.c b/support/dktools/dk3strmg.c
new file mode 100644
index 0000000000..4258926c1d
--- /dev/null
+++ b/support/dktools/dk3strmg.c
@@ -0,0 +1,160 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3strmg.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3strmg.c The dk3strmg module.
+*/
+
+
+#line 10 "dk3strmg.ctr"
+
+#include "dk3all.h"
+
+
+
+
+
+
+#line 16 "dk3strmg.ctr"
+
+
+/** Low-level stream function to deal with gzip compression.
+ Closing the stream also closes the gzip-file.
+ @param api API structure.
+*/
+static
+void
+dk3stream_gz_fct(dk3_stream_api_t *api)
+{
+#if DK3_HAVE_ZLIB_H
+ int res = 0; /* Operation result. */
+ gzFile g = NULL; /* Low-level I/O object. */
+#endif
+ api->suc = 0;
+ (api->res).sz = 0;
+ (api->res).ec = DK3_ERROR_NOT_SUPPORTED;
+#if DK3_HAVE_ZLIB_H
+ (api->res).ec = 0;
+ g = (gzFile)((api->arg).d);
+ switch(api->cmd) {
+ case DK3_STREAM_API_READ: {
+ if(((api->arg).b) && ((api->arg).sz) && ((api->arg).d)) {
+ res = gzread(g, (api->arg).b, (int)((api->arg).sz));
+ if(res > 0) {
+ api->suc = 1; (api->res).ec = 0; (api->res).sz = (size_t)res;
+ }
+ }
+ } break;
+ case DK3_STREAM_API_WRITE: {
+ if(((api->arg).b) && ((api->arg).sz) && ((api->arg).d)) {
+ res = gzwrite(g, (api->arg).b, (int)((api->arg).sz));
+ (api->res).sz = (size_t)res;
+ if((size_t)res == (api->arg).sz) {
+ api->suc = 1; (api->res).ec = 0;
+ }
+ }
+ } break;
+ case DK3_STREAM_API_FLUSH: {
+ if((api->arg).d) {
+ if(gzflush(g, Z_FULL_FLUSH) == Z_OK) {
+ api->suc = 1; (api->res).ec = 0;
+ }
+ }
+ } break;
+ case DK3_STREAM_API_AT_END: {
+ if((api->arg).d) {
+ if(gzeof(g) == 1) {
+ api->suc = 1;
+ }
+ }
+ } break;
+ case DK3_STREAM_API_CLOSE: {
+ if((api->arg).d) {
+ if(gzclose(g) == Z_OK) {
+ api->suc = 1;
+ }
+ }
+ } break;
+ case DK3_STREAM_API_ZERO_IS_END: {
+ api->suc = 0;
+ } break;
+ case DK3_STREAM_API_ERROR: {
+ api->suc = 0;
+ } break;
+ }
+#endif
+}
+
+
+
+/** Low-level stream function to deal with gzip compression.
+ Closing the stream does not close the gzip-file.
+ @param api API structure.
+*/
+static
+void
+dk3stream_gz_fct_no_close(dk3_stream_api_t *api)
+{
+ if(api->cmd != DK3_STREAM_API_CLOSE) {
+ dk3stream_gz_fct(api);
+ } else {
+ api->suc = 1; (api->res).ec = 0;
+ }
+}
+
+
+#if DK3_HAVE_ZLIB_H
+
+/** Open stream for existing gzFile.
+ @param g gzFile already opened.
+ @param fl Read/write flags.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new stream on success, NULL on error.
+*/
+dk3_stream_t *
+dk3stream_open_gz_app(gzFile g, int fl, dk3_app_t *app)
+{
+ dk3_stream_t *back = NULL;
+ if(g) {
+ back = dk3stream_open_app((void *)g, dk3stream_gz_fct_no_close, fl, app);
+ }
+ return back;
+}
+
+#endif
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dk3strmg.ctr b/support/dktools/dk3strmg.ctr
new file mode 100644
index 0000000000..304991c3c5
--- /dev/null
+++ b/support/dktools/dk3strmg.ctr
@@ -0,0 +1,126 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk3all.h"
+
+
+
+$(trace-include)
+
+
+/** Low-level stream function to deal with gzip compression.
+ Closing the stream also closes the gzip-file.
+ @param api API structure.
+*/
+static
+void
+dk3stream_gz_fct(dk3_stream_api_t *api)
+{
+#if DK3_HAVE_ZLIB_H
+ int res = 0; /* Operation result. */
+ gzFile g = NULL; /* Low-level I/O object. */
+#endif
+ api->suc = 0;
+ (api->res).sz = 0;
+ (api->res).ec = DK3_ERROR_NOT_SUPPORTED;
+#if DK3_HAVE_ZLIB_H
+ (api->res).ec = 0;
+ g = (gzFile)((api->arg).d);
+ switch(api->cmd) {
+ case DK3_STREAM_API_READ: {
+ if(((api->arg).b) && ((api->arg).sz) && ((api->arg).d)) {
+ res = gzread(g, (api->arg).b, (int)((api->arg).sz));
+ if(res > 0) {
+ api->suc = 1; (api->res).ec = 0; (api->res).sz = (size_t)res;
+ }
+ }
+ } break;
+ case DK3_STREAM_API_WRITE: {
+ if(((api->arg).b) && ((api->arg).sz) && ((api->arg).d)) {
+ res = gzwrite(g, (api->arg).b, (int)((api->arg).sz));
+ (api->res).sz = (size_t)res;
+ if((size_t)res == (api->arg).sz) {
+ api->suc = 1; (api->res).ec = 0;
+ }
+ }
+ } break;
+ case DK3_STREAM_API_FLUSH: {
+ if((api->arg).d) {
+ if(gzflush(g, Z_FULL_FLUSH) == Z_OK) {
+ api->suc = 1; (api->res).ec = 0;
+ }
+ }
+ } break;
+ case DK3_STREAM_API_AT_END: {
+ if((api->arg).d) {
+ if(gzeof(g) == 1) {
+ api->suc = 1;
+ }
+ }
+ } break;
+ case DK3_STREAM_API_CLOSE: {
+ if((api->arg).d) {
+ if(gzclose(g) == Z_OK) {
+ api->suc = 1;
+ }
+ }
+ } break;
+ case DK3_STREAM_API_ZERO_IS_END: {
+ api->suc = 0;
+ } break;
+ case DK3_STREAM_API_ERROR: {
+ api->suc = 0;
+ } break;
+ }
+#endif
+}
+
+
+
+/** Low-level stream function to deal with gzip compression.
+ Closing the stream does not close the gzip-file.
+ @param api API structure.
+*/
+static
+void
+dk3stream_gz_fct_no_close(dk3_stream_api_t *api)
+{
+ if(api->cmd != DK3_STREAM_API_CLOSE) {
+ dk3stream_gz_fct(api);
+ } else {
+ api->suc = 1; (api->res).ec = 0;
+ }
+}
+
+
+#if DK3_HAVE_ZLIB_H
+
+/** Open stream for existing gzFile.
+ @param g gzFile already opened.
+ @param fl Read/write flags.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new stream on success, NULL on error.
+*/
+dk3_stream_t *
+dk3stream_open_gz_app(gzFile g, int fl, dk3_app_t *app)
+{
+ dk3_stream_t *back = NULL;
+ if(g) {
+ back = dk3stream_open_app((void *)g, dk3stream_gz_fct_no_close, fl, app);
+ }
+ return back;
+}
+
+#endif
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dk3trace.c b/support/dktools/dk3trace.c
new file mode 100644
index 0000000000..6ae5a8112f
--- /dev/null
+++ b/support/dktools/dk3trace.c
@@ -0,0 +1,309 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3trace.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3trace.c The dk3trace module.
+*/
+
+
+#line 164 "dk3trace.ctr"
+
+#include "dk4conf.h"
+
+#ifdef _WIN32
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef STDIO_H_INCLUDED
+#include <stdio.h>
+#define STDIO_H_INCLUDED 1
+#endif
+#ifndef TIME_H_INCLUDED
+#include <time.h>
+#define TIME_H_INCLUDED 1
+#endif
+
+
+
+/** Inside the dk3trace module.
+*/
+#define DK3_TRACE_C 1
+
+#include "dk3trace.h"
+
+
+
+/** Output file.
+*/
+static FILE *trace_file = NULL;
+
+
+/** Timestamp of previous trace message.
+*/
+static time_t dk3trace_last_time = (time_t)0UL;
+
+
+
+void
+dktrace_end(void)
+/* {{{ */
+{
+ if(trace_file) {
+ (void)fclose(trace_file);
+ trace_file = NULL;
+ }
+}
+/* }}} */
+
+
+
+void
+dk_trace_end(void)
+/* {{{*/
+{
+ dktrace_end();
+}
+/* }}} */
+
+
+
+void
+dktrace_init(char const *filename)
+/* {{{ */
+{
+ FILE *x = NULL;
+ if(filename) {
+#ifdef _WIN32
+ if (0 != fopen_s(&x, filename, "w")) {
+ x = NULL;
+ }
+#else
+#if DK4_HAVE_LARGEFILE64_SOURCE && DK4_HAVE_FOPEN64
+ x = fopen64(filename, "w");
+#else
+ x = fopen(filename, "w");
+#endif
+#endif
+ if(x) {
+ dktrace_end();
+ trace_file = x;
+ }
+ }
+}
+/* }}} */
+
+
+
+void
+dk_trace_init(char const *filename)
+/* {{{ */
+{
+ dktrace_init(filename);
+}
+/* }}} */
+
+
+FILE *
+dktrace_file(void)
+/* {{{ */
+{
+ return trace_file;
+}
+/* }}} */
+
+
+
+FILE *
+dk_trace_file(void)
+/* {{{ */
+{
+ FILE *back;
+ back = dktrace_file();
+ return back;
+}
+/* }}} */
+
+
+
+/** Write time to output file.
+ @param f Output file.
+*/
+static
+void
+dk3trace_i_time(FILE *f)
+/* {{{ */
+{
+#ifdef _WIN32
+ SYSTEMTIME st;
+ if (NULL != f) {
+ GetLocalTime(&st);
+ fprintf(
+ f,
+ "%04d/%02d/%02d %02d:%02d:%02d\n",
+ (int)(st.wYear),
+ (int)(st.wMonth),
+ (int)(st.wDay),
+ (int)(st.wHour),
+ (int)(st.wMinute),
+ (int)(st.wSecond)
+ );
+ }
+#else
+#if DK4_HAVE_TIME_H || DK4_HAVE_SYS_TIME_H
+ time_t timer;
+ struct tm *tm;
+ if(NULL != f) {
+ (void)time(&timer);
+ if(dk3trace_last_time != timer) {
+ dk3trace_last_time = timer;
+ tm = localtime(&timer);
+ if(tm) {
+ fprintf(
+ f,
+ "# %04d/%02d/%02d %02d:%02d:%02d\n",
+ (1900 + tm->tm_year),
+ (1 + tm->tm_mon),
+ tm->tm_mday,
+ tm->tm_hour,
+ tm->tm_min,
+ tm->tm_sec
+ );
+ }
+ }
+ }
+#endif
+#endif
+}
+/* }}} */
+
+
+
+#if DK3_ON_WINDOWS
+/** Write time to output file.
+ @param f Output file.
+*/
+static
+void
+dk3trace_i_wtime(FILE *f)
+/* {{{ */
+{
+#if DK4_HAVE_TIME_H || DK4_HAVE_SYS_TIME_H
+ time_t timer;
+ struct tm *tm;
+ if(f) {
+ time(&timer);
+ if(dk3trace_last_time != timer) {
+ dk3trace_last_time = timer;
+ tm = localtime(&timer);
+ if(tm) {
+ fwprintf(f,
+ L"# %04d/%02d/%02d %02d:%02d:%02d\n",
+ (1900 + tm->tm_year),
+ (1 + tm->tm_mon),
+ tm->tm_mday,
+ tm->tm_hour,
+ tm->tm_min,
+ tm->tm_sec
+ );
+ }
+ }
+ }
+#endif
+}
+/* }}} */
+#endif
+
+
+
+void
+dktrace_time(void)
+/* {{{ */
+{
+ if(trace_file) {
+ dk3trace_i_time(trace_file);
+ }
+}
+/* }}} */
+
+
+
+void
+dktrace_stdout_time(void)
+/* {{{ */
+{
+ dk3trace_i_time(stdout);
+}
+/* }}} */
+
+
+
+#if DK3_ON_WINDOWS
+void
+dktrace_wtime(void)
+/* {{{ */
+{
+ if(trace_file) {
+ dk3trace_i_wtime(trace_file);
+ }
+}
+/* }}} */
+
+
+
+void
+dktrace_stdout_wtime(void)
+/* {{{ */
+{
+ dk3trace_i_wtime(stdout);
+}
+/* }}} */
+#endif
+
+
+
+void
+dk_trace_time(void)
+/* {{{ */
+{
+ dktrace_time();
+}
+/* }}} */
+
+
+
+/* vim: set ai sw=2 filetype=c foldmethod=marker foldopen=all : */
+
diff --git a/support/dktools/dk3trace.ctr b/support/dktools/dk3trace.ctr
new file mode 100644
index 0000000000..e0d2ae3968
--- /dev/null
+++ b/support/dktools/dk3trace.ctr
@@ -0,0 +1,432 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% header
+
+
+#ifndef STDIO_H_INCLUDED
+#include <stdio.h>
+#define STDIO_H_INCLUDED 1
+#endif
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+
+/** Close trace output file.
+*/
+void
+dktrace_end(void);
+
+
+
+/** Start tracing.
+ @param filename File name to write trace output
+ or NULL to use standard output.
+*/
+void
+dktrace_init(
+ char const *filename
+);
+
+
+
+/** Get trace file.
+ @return Pointer to open file used for tracing.
+*/
+FILE *
+dktrace_file(void);
+
+
+
+/** Close trace output file.
+*/
+void
+dk_trace_end(void);
+
+
+
+/** Start tracing.
+ @param filename File name to write trace output
+ or NULL to use standard output.
+*/
+void
+dk_trace_init(
+ char const *filename
+);
+
+
+
+/** Get trace file.
+ @return Pointer to open file used for tracing.
+*/
+FILE *
+dk_trace_file(void);
+
+
+
+/** Write time to trace output.
+*/
+void
+dktrace_time(void);
+
+
+
+/** Write time to trace output.
+*/
+void
+dk_trace_time(void);
+
+
+
+/** Write time to standard output.
+*/
+void
+dktrace_stdout_time(void);
+
+
+#if DK4_ON_WINDOWS
+/** Write time to trace output.
+*/
+void
+dk_trace_wtime(void);
+
+/** Write time to standard output.
+*/
+void
+dktrace_stdout_wtime(void);
+
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+/* ifdef __cplusplus */
+
+
+#if TRACE_WIDE
+
+/** Show string. */
+#define TR_STR(x) ((NULL != x) ? (x) : L"(NULL)")
+
+/** Show pointer. */
+#define TR_PTR(x) ((NULL != x) ? L"PTR" : L"(NULL)")
+
+#else
+/* if TRACE_WIDE */
+
+/** Show string. */
+#define TR_STR(x) ((NULL != x) ? (x) : "(NULL)")
+
+/** Show pointer. */
+#define TR_PTR(x) ((NULL != x) ? "PTR" : "(NULL)")
+
+#endif
+/* if TRACE_WIDE */
+
+
+/** Show 8 bit string. */
+#define TR_8STR(x) ((NULL != x) ? (x) : "(NULL)")
+
+/** Show pointer as 8 bit string. */
+#define TR_8PTR(x) ((NULL != x) ? "PTR" : "(NULL)")
+
+/** Show long string. */
+#define TR_LSTR(x) ((NULL != x) ? (x) : L"(NULL)")
+
+/** Show pointer as long string. */
+#define TR_LPTR(x) ((NULL != x) ? L"PTR" : L"(NULL)")
+
+/** Show string as dkChar. */
+#define TR_DKSTR(x) ((NULL != x) ? (x) : dkT("NULL"))
+
+/** Show pointer as dkChar. */
+#define TR_DKPTR(x) ((NULL != x) ? dkT("PTR") : dkT("(NULL)"))
+
+/** Show string as wxChar. */
+#define TR_WXSTR(x) ((NULL != x) ? (x) : wxT("(NULL)"))
+
+/** Show pointer as wxChar. */
+#define TR_WXPTR(x) ((NULL != x) ? wxT("PTR") : wxT("(NULL)"))
+
+/** Show pointer as integer. */
+#define TR_IPTR(x) ((NULL != x) ? 1 : 0)
+
+
+%% module
+
+#include "dk4conf.h"
+
+#ifdef _WIN32
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef STDIO_H_INCLUDED
+#include <stdio.h>
+#define STDIO_H_INCLUDED 1
+#endif
+#ifndef TIME_H_INCLUDED
+#include <time.h>
+#define TIME_H_INCLUDED 1
+#endif
+
+
+
+/** Inside the dk3trace module.
+*/
+#define DK3_TRACE_C 1
+
+#include "dk3trace.h"
+
+
+
+/** Output file.
+*/
+static FILE *trace_file = NULL;
+
+
+/** Timestamp of previous trace message.
+*/
+static time_t dk3trace_last_time = (time_t)0UL;
+
+
+
+void
+dktrace_end(void)
+/* {{{ */
+{
+ if(trace_file) {
+ (void)fclose(trace_file);
+ trace_file = NULL;
+ }
+}
+/* }}} */
+
+
+
+void
+dk_trace_end(void)
+/* {{{*/
+{
+ dktrace_end();
+}
+/* }}} */
+
+
+
+void
+dktrace_init(char const *filename)
+/* {{{ */
+{
+ FILE *x = NULL;
+ if(filename) {
+#ifdef _WIN32
+ if (0 != fopen_s(&x, filename, "w")) {
+ x = NULL;
+ }
+#else
+#if DK4_HAVE_LARGEFILE64_SOURCE && DK4_HAVE_FOPEN64
+ x = fopen64(filename, "w");
+#else
+ x = fopen(filename, "w");
+#endif
+#endif
+ if(x) {
+ dktrace_end();
+ trace_file = x;
+ }
+ }
+}
+/* }}} */
+
+
+
+void
+dk_trace_init(char const *filename)
+/* {{{ */
+{
+ dktrace_init(filename);
+}
+/* }}} */
+
+
+FILE *
+dktrace_file(void)
+/* {{{ */
+{
+ return trace_file;
+}
+/* }}} */
+
+
+
+FILE *
+dk_trace_file(void)
+/* {{{ */
+{
+ FILE *back;
+ back = dktrace_file();
+ return back;
+}
+/* }}} */
+
+
+
+/** Write time to output file.
+ @param f Output file.
+*/
+static
+void
+dk3trace_i_time(FILE *f)
+/* {{{ */
+{
+#ifdef _WIN32
+ SYSTEMTIME st;
+ if (NULL != f) {
+ GetLocalTime(&st);
+ fprintf(
+ f,
+ "%04d/%02d/%02d %02d:%02d:%02d\n",
+ (int)(st.wYear),
+ (int)(st.wMonth),
+ (int)(st.wDay),
+ (int)(st.wHour),
+ (int)(st.wMinute),
+ (int)(st.wSecond)
+ );
+ }
+#else
+#if DK4_HAVE_TIME_H || DK4_HAVE_SYS_TIME_H
+ time_t timer;
+ struct tm *tm;
+ if(NULL != f) {
+ (void)time(&timer);
+ if(dk3trace_last_time != timer) {
+ dk3trace_last_time = timer;
+ tm = localtime(&timer);
+ if(tm) {
+ fprintf(
+ f,
+ "# %04d/%02d/%02d %02d:%02d:%02d\n",
+ (1900 + tm->tm_year),
+ (1 + tm->tm_mon),
+ tm->tm_mday,
+ tm->tm_hour,
+ tm->tm_min,
+ tm->tm_sec
+ );
+ }
+ }
+ }
+#endif
+#endif
+}
+/* }}} */
+
+
+
+#if DK3_ON_WINDOWS
+/** Write time to output file.
+ @param f Output file.
+*/
+static
+void
+dk3trace_i_wtime(FILE *f)
+/* {{{ */
+{
+#if DK4_HAVE_TIME_H || DK4_HAVE_SYS_TIME_H
+ time_t timer;
+ struct tm *tm;
+ if(f) {
+ time(&timer);
+ if(dk3trace_last_time != timer) {
+ dk3trace_last_time = timer;
+ tm = localtime(&timer);
+ if(tm) {
+ fwprintf(f,
+ L"# %04d/%02d/%02d %02d:%02d:%02d\n",
+ (1900 + tm->tm_year),
+ (1 + tm->tm_mon),
+ tm->tm_mday,
+ tm->tm_hour,
+ tm->tm_min,
+ tm->tm_sec
+ );
+ }
+ }
+ }
+#endif
+}
+/* }}} */
+#endif
+
+
+
+void
+dktrace_time(void)
+/* {{{ */
+{
+ if(trace_file) {
+ dk3trace_i_time(trace_file);
+ }
+}
+/* }}} */
+
+
+
+void
+dktrace_stdout_time(void)
+/* {{{ */
+{
+ dk3trace_i_time(stdout);
+}
+/* }}} */
+
+
+
+#if DK3_ON_WINDOWS
+void
+dktrace_wtime(void)
+/* {{{ */
+{
+ if(trace_file) {
+ dk3trace_i_wtime(trace_file);
+ }
+}
+/* }}} */
+
+
+
+void
+dktrace_stdout_wtime(void)
+/* {{{ */
+{
+ dk3trace_i_wtime(stdout);
+}
+/* }}} */
+#endif
+
+
+
+void
+dk_trace_time(void)
+/* {{{ */
+{
+ dktrace_time();
+}
+/* }}} */
+
+
+
+/* vim: set ai sw=2 filetype=c foldmethod=marker foldopen=all : */
+
diff --git a/support/dktools/dk3trace.h b/support/dktools/dk3trace.h
new file mode 100644
index 0000000000..4dd6bd2909
--- /dev/null
+++ b/support/dktools/dk3trace.h
@@ -0,0 +1,199 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3trace.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3trace.h Header file for the dk3trace module.
+*/
+
+#ifndef DK3TRACE_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3TRACE_H_INCLUDED 1
+
+
+#line 10 "dk3trace.ctr"
+
+
+#ifndef STDIO_H_INCLUDED
+#include <stdio.h>
+#define STDIO_H_INCLUDED 1
+#endif
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+
+/** Close trace output file.
+*/
+void
+dktrace_end(void);
+
+
+
+/** Start tracing.
+ @param filename File name to write trace output
+ or NULL to use standard output.
+*/
+void
+dktrace_init(
+ char const *filename
+);
+
+
+
+/** Get trace file.
+ @return Pointer to open file used for tracing.
+*/
+FILE *
+dktrace_file(void);
+
+
+
+/** Close trace output file.
+*/
+void
+dk_trace_end(void);
+
+
+
+/** Start tracing.
+ @param filename File name to write trace output
+ or NULL to use standard output.
+*/
+void
+dk_trace_init(
+ char const *filename
+);
+
+
+
+/** Get trace file.
+ @return Pointer to open file used for tracing.
+*/
+FILE *
+dk_trace_file(void);
+
+
+
+/** Write time to trace output.
+*/
+void
+dktrace_time(void);
+
+
+
+/** Write time to trace output.
+*/
+void
+dk_trace_time(void);
+
+
+
+/** Write time to standard output.
+*/
+void
+dktrace_stdout_time(void);
+
+
+#if DK4_ON_WINDOWS
+/** Write time to trace output.
+*/
+void
+dk_trace_wtime(void);
+
+/** Write time to standard output.
+*/
+void
+dktrace_stdout_wtime(void);
+
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+/* ifdef __cplusplus */
+
+
+#if TRACE_WIDE
+
+/** Show string. */
+#define TR_STR(x) ((NULL != x) ? (x) : L"(NULL)")
+
+/** Show pointer. */
+#define TR_PTR(x) ((NULL != x) ? L"PTR" : L"(NULL)")
+
+#else
+/* if TRACE_WIDE */
+
+/** Show string. */
+#define TR_STR(x) ((NULL != x) ? (x) : "(NULL)")
+
+/** Show pointer. */
+#define TR_PTR(x) ((NULL != x) ? "PTR" : "(NULL)")
+
+#endif
+/* if TRACE_WIDE */
+
+
+/** Show 8 bit string. */
+#define TR_8STR(x) ((NULL != x) ? (x) : "(NULL)")
+
+/** Show pointer as 8 bit string. */
+#define TR_8PTR(x) ((NULL != x) ? "PTR" : "(NULL)")
+
+/** Show long string. */
+#define TR_LSTR(x) ((NULL != x) ? (x) : L"(NULL)")
+
+/** Show pointer as long string. */
+#define TR_LPTR(x) ((NULL != x) ? L"PTR" : L"(NULL)")
+
+/** Show string as dkChar. */
+#define TR_DKSTR(x) ((NULL != x) ? (x) : dkT("NULL"))
+
+/** Show pointer as dkChar. */
+#define TR_DKPTR(x) ((NULL != x) ? dkT("PTR") : dkT("(NULL)"))
+
+/** Show string as wxChar. */
+#define TR_WXSTR(x) ((NULL != x) ? (x) : wxT("(NULL)"))
+
+/** Show pointer as wxChar. */
+#define TR_WXPTR(x) ((NULL != x) ? wxT("PTR") : wxT("(NULL)"))
+
+/** Show pointer as integer. */
+#define TR_IPTR(x) ((NULL != x) ? 1 : 0)
+
+
+
+#endif
diff --git a/support/dktools/dk3types.h b/support/dktools/dk3types.h
new file mode 100644
index 0000000000..1e2a80816c
--- /dev/null
+++ b/support/dktools/dk3types.h
@@ -0,0 +1,2702 @@
+
+/** @file dk3types.h Type definitions for the dk3 library.
+ */
+
+#ifndef DK3_TYPES_H_INCLUDED
+/** Avoid multiple file inclusions. */
+#define DK3_TYPES_H_INCLUDED 1
+
+#include <dk3conf.h>
+
+#if DK3_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if DK3_HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#if DK3_HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if DK3_HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+#if DK3_HAVE_WCHAR_H
+#include <wchar.h>
+#endif
+#if DK3_HAVE_TERMIOS_H
+#include <termios.h>
+#endif
+#if DK3_HAVE_SYS_TERMIOS_H
+#include <sys/termios.h>
+#endif
+#if DK3_HAVE_SYS_TTOLD_H
+#include <sys/ttold.h>
+#endif
+#if DK3_HAVE_ZLIB_H
+#include <zlib.h>
+#endif
+
+#ifndef DK3_CHAR_SIZE
+#if DK3_ON_WINDOWS && (defined(_UNICODE))
+/** Specify default character size 16 bit.
+*/
+#define DK3_CHAR_SIZE 2
+#else
+/** Specify default character size 8 bit.
+*/
+#define DK3_CHAR_SIZE 1
+#endif
+#endif
+
+
+/*
+ Simple data types.
+*/
+
+/** A 8-bit unsigned int type.
+*/
+typedef unsigned char dk3_u8_t;
+
+/** An 8-bit signed int type.
+*/
+typedef signed char dk3_i8_t;
+
+/** A 8-bit character type.
+*/
+typedef char /*^unsignedintegraltype^*/ dk3_c8_t;
+
+/** A 16-bit unsigned int type.
+*/
+typedef unsigned short dk3_u16_t;
+
+/** A 16-bit signed int type.
+*/
+typedef short dk3_i16_t;
+
+/** A 16 bit character type (used on Windows).
+*/
+#if DK3_SIZEOF_WCHAR_T == 2
+typedef wchar_t /*^unsignedintegraltype^*/ dk3_c16_t;
+#else
+typedef unsigned short /*^unsignedintegraltype^*/ dk3_c16_t;
+#endif
+
+/** A 32-bit character/unsigned int type (wchar_t on UNIX, not used).
+*/
+typedef unsigned long dk3_u32_t;
+
+/** A 32-bit signed int type.
+*/
+typedef long dk3_i32_t;
+
+/** A 32-bit character type (used i.e. by X11).
+*/
+#if DK3_SIZEOF_WCHAR_T == 4
+typedef wchar_t /*^unsignedintegraltype^*/ dk3_c32_t;
+#else
+#if DK3_SIZEOF_INT >= 4
+typedef unsigned /*^unsignedintegraltype^*/ dk3_c32_t;
+#else
+typedef unsigned long /*^unsignedintegraltype^*/ dk3_c32_t;
+#endif
+#endif
+
+
+
+#if DK3_CHAR_SIZE > 1
+#if defined(DK3_SIZEOF_WCHAR_T)
+#if DK3_CHAR_SIZE == DK3_SIZEOF_WCHAR_T
+/** Text character type.
+*/
+typedef wchar_t /*^unsignedintegraltype^*/ dkChar;
+/** Macro to switch text literals between 8-bit and 16-bit text.
+*/
+#define dkT(s) L ## s
+/** Macro to switch the main function between 8 and 16 bit.
+*/
+#define DK3_MAIN int wmain(int argc, wchar_t *argv[])
+#else
+/* if DK3_CHAR_SIZE == DK3_SIZEOF_WCHAR_T */
+#if DK3_CHAR_SIZE > 2
+/** Text character type.
+*/
+typedef dk3_c32_t /*^unsignedintegraltype^*/ dkChar;
+#error "Can not use prefix L to specify dkChar string literals!"
+#error "Can not define DK3_MAIN to dkChar!"
+#else
+/* if DK3_CHAR_SIZE > 2 */
+/** Text character type.
+*/
+typedef dk3_c16_t /*^unsignedintegraltype^*/ dkChar;
+#error "Can not use prefix L to specify dkChar string literals!"
+#error "Can not define DK3_MAIN to dkChar!"
+#endif
+/* if DK3_CHAR_SIZE > 2 */
+#endif
+/* if DK3_CHAR_SIZE == DK3_SIZEOF_WCHAR_T */
+#else
+/* if defined(DK3_SIZEOF_WCHAR_T) */
+#error "Missing definition for DK3_SIZEOF_WCHAR_T!"
+#endif
+/* if defined(DK3_SIZEOF_WCHAR_T) */
+#if !DK3_ON_WINDOWS
+#error "Usable support for UNICODE/MBCS is available on Windows platforms only!"
+#endif
+/* if !DK3_ON_WINDOWS */
+#else
+/* if DK3_CHAR_SIZE > 1 */
+/* +++ DK3_CHAR_SIZE == 1 */
+/** Text character type.
+*/
+typedef char /*^unsignedintegraltype^*/ dkChar;
+/** Macro to switch the main function between 8 and 16 bit.
+*/
+#define dkT(s) s
+/** Macro to switch the main function between 8 and 16 bit.
+*/
+#define DK3_MAIN int main(int argc, char *argv[])
+/* --- DK3_CHAR_SIZE == 1 */
+#endif
+/* if DK3_CHAR_SIZE > 1 */
+
+
+
+#if DK3_HAVE_INTMAX_T
+
+/** Maximum size integer type.
+*/
+typedef intmax_t dk3_im_t;
+
+/** Maximum size unsigned integer type.
+*/
+typedef uintmax_t dk3_um_t;
+
+#else
+
+#if DK3_HAVE_LONG_LONG
+
+/** Maximum size integer type.
+*/
+typedef long long int dk3_im_t;
+
+/** Maximum size unsigned integer type.
+*/
+typedef long long unsigned dk3_um_t;
+
+#else
+
+/** Maximum size integer type.
+*/
+typedef long int dk3_im_t;
+
+/** Maximum size unsigned integer type.
+*/
+typedef long unsigned dk3_um_t;
+
+#endif
+#endif
+
+
+/** Timer.
+*/
+
+#if DK3_ON_WINDOWS
+/** Portable type to save a timestamp.
+*/
+typedef __time64_t dk3_time_t;
+#else
+#if (defined(DK3_HAVE_SYS_TIME_H) || defined(DK3_HAVE_TIME_H)) && defined(DK3_HAVE_TIME)
+/** Portable type to save a timestamp.
+*/
+typedef time_t dk3_time_t;
+#else
+#error "No mechanism known to obtain current time!"
+#endif
+#endif
+
+
+
+#if DK3_HAVE_LONG_DOUBLE && (DK3_SIZEOF_LONG_DOUBLE > DK3_SIZEOF_DOUBLE)
+/** Most precise double type.
+*/
+typedef long double dk3_double_t;
+#else
+/** Most precise double type.
+*/
+typedef double dk3_double_t;
+#endif
+
+
+#if DK3_ON_WINDOWS
+/** Number of bytes successfully read/written by read()/write().
+*/
+#define dk3_rw_res_t int
+#else
+#if DK3_HAVE_SSIZE_T
+/** Number of bytes successfully read/written by read()/write().
+*/
+#define dk3_rw_res_t ssize_t
+#else
+/** Number of bytes successfully read/written by read()/write().
+*/
+#define dk3_rw_res_t int
+#endif
+#endif
+
+#if DK3_ON_WINDOWS
+/** Buffer size in read()/write().
+*/
+#define dk3_rw_arg_t unsigned int
+#else
+/** Buffer size in read()/write().
+*/
+#define dk3_rw_arg_t size_t
+#endif
+
+
+/*
+ Structured data types.
+*/
+
+
+
+/** Timestamp.
+*/
+typedef struct _dk3_time_t_ {
+ /** Year.
+ */
+ int Y;
+
+ /** Month.
+ */
+ int M;
+
+ /** Day in month.
+ */
+ int D;
+
+ /** Hours.
+ */
+ int h;
+
+ /** Minutes.
+ */
+ int m;
+
+ /** Seconds.
+ */
+ int s;
+} dk3_tm_t;
+
+
+
+/** File information.
+ When retrieving information about a symbolic link the dk3sf_stat()
+ function retrieves information about both the link destination and
+ the link itself.
+*/
+typedef struct {
+
+ /** Creation timestamp.
+ */
+ dk3_time_t cre;
+
+ /** Modification timestamp.
+ */
+ dk3_time_t mod;
+
+ /** Last access timestamp.
+ */
+ dk3_time_t acc;
+
+ /** Link creation timestamp.
+ */
+ dk3_time_t lcre;
+
+ /** Link modification timestamp.
+ */
+ dk3_time_t lmod;
+
+ /** Link last access timestamp.
+ */
+ dk3_time_t lacc;
+
+ /** User ID.
+ */
+ dk3_um_t u;
+
+ /** Group ID.
+ */
+ dk3_um_t g;
+
+ /** Device number.
+ */
+ dk3_um_t device;
+
+ /** Relative device number.
+ */
+ dk3_um_t rdev;
+
+ /** Inode number.
+ */
+ dk3_um_t inode;
+
+ /** Number of hard links to inode.
+ */
+ dk3_um_t nlink;
+
+ /** File size in bytes.
+ */
+ dk3_um_t sz;
+
+ /** Link user ID.
+ */
+ dk3_um_t lu;
+
+ /** Link group ID.
+ */
+ dk3_um_t lg;
+
+ /** Link device number.
+ */
+ dk3_um_t ldevice;
+
+ /** Link relative device number.
+ */
+ dk3_um_t lrdev;
+
+ /** Link inode number.
+ */
+ dk3_um_t linode;
+
+ /** Number of hard links to the link.
+ */
+ dk3_um_t lnlink;
+
+#if DK3_ON_WINDOWS
+ long dwReparse;
+#endif
+
+ /** File type, see @ref filetypes.
+ */
+ int ft;
+
+ /** Permissions, see @ref filepermissions.
+ */
+ int perm;
+
+ /** Link file type.
+ */
+ int lft;
+
+ /** Link permissions.
+ */
+ int lperm;
+
+ /** Link file size.
+ */
+ dk3_um_t lsz;
+
+ /** Additional information about file, see @ref statadditional.
+ */
+ unsigned char ai;
+
+#if DK3_ON_WINDOWS
+ /** Reparse point information.
+ */
+ char cReparse;
+#endif
+} dk3_stat_t;
+
+
+
+
+/** Evaluation result for an object.
+*/
+typedef union {
+
+ /** Evaluation to double.
+ */
+ double d;
+
+ /** Evaluation to float.
+ */
+ float f;
+
+ /** Evaluation to long.
+ */
+ long l;
+
+ /** Evaluation to unsigned long.
+ */
+ unsigned long ul;
+
+ /** Evaluation to int.
+ */
+ int i;
+
+ /** Evaluation to unsigned int.
+ */
+ unsigned int ui;
+
+ /** Evaluation to short.
+ */
+ short s;
+
+ /** Evaluation to unsigned short.
+ */
+ unsigned short us;
+
+ /** Evaluation to char.
+ */
+ char c;
+
+ /** Evaluation to unsigned char.
+ */
+ unsigned char uc;
+} dk3_object_eval_res_t;
+
+
+/** Internal node for dk3_sto_t.
+ This structure is used internally by the dksto module.
+*/
+struct _dk3_sto_node_ {
+
+ /** Object evaluation of @a o.
+ */
+ dk3_object_eval_res_t v;
+
+ /** Parent node in tree.
+ */
+ struct _dk3_sto_node_ *p;
+
+ /** Left child node (tree) or preceeding node (list).
+ */
+ struct _dk3_sto_node_ *l;
+
+ /** Right child node (tree) or following node (list).
+ */
+ struct _dk3_sto_node_ *r;
+
+ /** Object to store.
+ */
+ void *o;
+
+ /** Balance flag (used in trees only).
+ */
+ short b;
+
+ /** Direction to walk in tree.
+ */
+ short w; /**< Direction to walk. */
+};
+
+/** Internal node for dk3_sto_t.
+*/
+typedef struct _dk3_sto_node_ dk3_sto_node_t;
+
+/** Pointer to internal node for dk3_sto_t.
+*/
+typedef dk3_sto_node_t *dk3_sto_node_p;
+
+
+
+/** Evaluation functions.
+ These function type are used to evaluate and compare objects
+ stored in a sorted dk3_sto_t.
+*/
+
+/** Object evaluation function for sorted storage.
+*/
+typedef char dk3_fct_eval_c_t(void const *obj, int crit) /*^*/ ;
+
+/** Object evaluation function for sorted storage.
+*/
+typedef unsigned char dk3_fct_eval_uc_t(void const *obj, int crit) /*^*/ ;
+
+/** Object evaluation function for sorted storage.
+*/
+typedef short dk3_fct_eval_s_t(void const *obj, int crit) /*^*/ ;
+
+/** Object evaluation function for sorted storage.
+*/
+typedef unsigned short dk3_fct_eval_us_t(void const *obj, int crit) /*^*/ ;
+
+/** Object evaluation function for sorted storage.
+*/
+typedef int dk3_fct_eval_i_t(void const *obj, int crit) /*^*/ ;
+
+/** Object evaluation function for sorted storage.
+*/
+typedef unsigned int dk3_fct_eval_ui_t(void const *obj, int crit) /*^*/ ;
+
+/** Object evaluation function for sorted storage.
+*/
+typedef long dk3_fct_eval_l_t(void const *obj, int crit) /*^*/ ;
+
+/** Object evaluation function for sorted storage.
+*/
+typedef unsigned long dk3_fct_eval_ul_t(void const *obj, int crit) /*^*/ ;
+
+/** Object evaluation function for sorted storage.
+*/
+typedef float dk3_fct_eval_f_t(void const *obj, int crit) /*^*/ ;
+
+/** Object evaluation function for sorted storage.
+*/
+typedef double dk3_fct_eval_d_t(void const *obj, int crit) /*^*/ ;
+
+/** Object comparison function for sorted storage.
+ When comparing to objects while inserting a new object into
+ a storage both @a o1 and @a o2 are object pointers.
+ When this function is called from dk3sto_it_find_like() the
+ @a o1 argument is an object pointer from the storage,
+ @a o2 is the pointer passed to dk3sto_it_find_like().
+*/
+typedef int dk3_fct_comp_t(
+ /*^null^*/ void const *o1,
+ /*^null^*/ void const *o2,
+ int crit
+) /*^*/ ;
+
+
+
+/** Choice for object evaluation function.
+*/
+typedef union {
+
+ /** Evaluation function returning a char value.
+ */
+ dk3_fct_eval_c_t *c;
+
+ /** Evaluation function returning an unsigned char value.
+ */
+ dk3_fct_eval_uc_t *uc;
+
+ /** Evaluation function returning a short value.
+ */
+ dk3_fct_eval_s_t *s;
+
+ /** Evaluation function returning an unsigned short value.
+ */
+ dk3_fct_eval_us_t *us;
+
+ /** Evaluation function returning an int value.
+ */
+ dk3_fct_eval_i_t *i;
+
+ /** Evaluation function returning an unsigned int value.
+ */
+ dk3_fct_eval_ui_t *ui;
+
+ /** Evaluation function returning a long value.
+ */
+ dk3_fct_eval_l_t *l;
+
+ /** Evaluation function returning an unsigned long value.
+ */
+ dk3_fct_eval_ul_t*ul;
+
+ /** Evaluation function returning a float value.
+ */
+ dk3_fct_eval_f_t *f;
+
+ /** Evaluation function returning a double value.
+ */
+ dk3_fct_eval_d_t *d;
+
+ /** Function to compare two objects.
+ */
+ dk3_fct_comp_t *comp;
+} dk3_object_eval_fct_t;
+
+
+
+/** Object storage.
+ A storage can be used to store pointers to objects.
+*/
+typedef struct _dk3_sto_t_ {
+
+ /** Comparison or evaluation function.
+ */
+ dk3_object_eval_fct_t e;
+
+ /** Application structure for diagnostics.
+ */
+ void *app;
+
+ /** Critical path for delete operations.
+ */
+ dk3_sto_node_p *d;
+
+ /** Root element (tree) or left element (list).
+ */
+ dk3_sto_node_t *r;
+
+ /** Double-linked list of iterators.
+ */
+ void *i;
+
+ /** Algorithm selection for comparison or evaluation.
+ */
+ int h;
+
+ /** Criteria for comparison or evaluation.
+ */
+ int c;
+
+ /** Flag: Use tree, 1=tree, 0=list.
+ */
+ int t;
+
+ /** Path length of critical path (number of elements).
+ */
+ short l;
+} dk3_sto_t;
+
+
+
+/** Storage iterator.
+ This structure can be used to iterate through a dk3_sto_t.
+*/
+struct _dk3_sto_iterator_ {
+
+ /** Preceeding iterator in iterator linked list.
+ */
+ struct _dk3_sto_iterator_ *l;
+
+ /** Following iterator in iterator linked list.
+ */
+ struct _dk3_sto_iterator_ *r;
+
+ /** Storage owning this iterator.
+ */
+ dk3_sto_t *s;
+
+ /** Current node.
+ */
+ dk3_sto_node_t *c;
+};
+/** Storage iterator. Can be used to iterate through a dk3_sto_t. */
+typedef struct _dk3_sto_iterator_ dk3_sto_it_t;
+
+
+
+/** Key value pair.
+*/
+typedef struct {
+ dkChar *key; /**< Key. */
+ dkChar *val; /**< Value. */
+} dk3_key_value_t;
+
+
+
+/** Directory contents.
+*/
+typedef struct _dk3_dir_t_ {
+
+ /** Stat buffer for current entry to process.
+ */
+ dk3_stat_t stb;
+
+ /** Storage containing the directory names.
+ */
+ dk3_sto_t *sdi;
+
+ /** Iterator for directory names storage.
+ */
+ dk3_sto_it_t *idi;
+
+ /** Storage containing file names.
+ */
+ dk3_sto_t *sfi;
+
+ /** Iterator for file names storage.
+ */
+ dk3_sto_it_t *ifi;
+
+ /** Directory name.
+ */
+ dkChar const *dirname;
+
+ /** Full path of current entry to process.
+ */
+ dkChar *fullname;
+
+ /** Short name of current entry to process.
+ */
+ dkChar *shortname;
+
+ /** Application used for diagnostics.
+ */
+ void *app;
+
+ /** Number of directories found.
+ */
+ dk3_um_t ndir;
+
+ /** Number of files found.
+ */
+ dk3_um_t nfi;
+} dk3_dir_t;
+
+
+
+/** Arguments in a stream command API call.
+*/
+typedef struct {
+
+ /** Low-level data.
+ */
+ void *d;
+
+ /** Buffer for bytes to read/write.
+ */
+ char *b;
+
+ /** Buffer size (number of bytes to read/write).
+ */
+ size_t sz;
+} dk3_stream_api_arg_t;
+
+
+
+/** Results of a stream command API call.
+*/
+typedef struct {
+
+ /** Number of bytes read.
+ */
+ size_t sz;
+
+ /** Error code DK3_ERROR_xxx, see @ref errorcodes.
+ */
+ int ec;
+} dk3_stream_api_result_t;
+
+
+
+/** Stream command API.
+*/
+typedef struct _dk3_stream_api_t_ {
+
+ /** API call arguments.
+ */
+ dk3_stream_api_arg_t arg;
+
+ /** API call results.
+ */
+ dk3_stream_api_result_t res;
+
+ /** Command to execute, DK3_STREAM_API_xxx, see @ref streamapicommands.
+ */
+ int cmd;
+
+ /** Success flag, 1=success, 0=error.
+ */
+ int suc;
+} dk3_stream_api_t;
+
+/** Stream API function type.
+*/
+typedef void dk3_stream_api_fct_t(dk3_stream_api_t *);
+
+/** Generic I/O stream.
+*/
+typedef struct _dk3_stream_t_ {
+
+ /** Optional application structure for diagnostics.
+ */
+ void *app;
+
+ /** Low-level data.
+ */
+ void *d;
+
+ /** Stream API function.
+ */
+ dk3_stream_api_fct_t *f;
+
+ /** Input buffer.
+ */
+ char *ib;
+
+ /** Output buffer.
+ */
+ char *ob;
+
+ /** Number of bytes written.
+ */
+ dk3_um_t wr;
+
+ /** Size of input buffer.
+ */
+ size_t sz_ib;
+
+ /** Bytes available in input buffer.
+ */
+ size_t av_ib;
+
+ /** Number of bytes already used from input buffer.
+ */
+ size_t us_ib;
+
+ /** Size of output buffer.
+ */
+ size_t sz_ob;
+
+ /** Number of bytes already placed in output buffer.
+ */
+ size_t us_ob;
+
+ /** Output encoding, see @ref fileenc.
+ */
+ int oe;
+
+ /** Usage flags, see @ref streamuseflags.
+ */
+ int fl;
+
+ /** Flag: End of input found.
+ */
+ int fe;
+
+ /** Flag: Reading 0 bytex indicates end of input.
+ */
+ int ze;
+
+ /** Flag: Flush output buffer at end of line.
+ */
+ int lf;
+
+ /** Flag: Error occured.
+ */
+ int er;
+
+ /** Last error occured, see @ref errorcodes.
+ */
+ int ec;
+} dk3_stream_t;
+
+
+
+/** Application structure.
+*/
+typedef struct _dk3_app_t_ {
+
+ /** Messages array, either localized messages or default texts.
+ */
+ dkChar const * const *msg;
+
+ /** Input file name currently processed (used in error messages).
+ */
+ dkChar const *n_sourcefile;
+
+ /** Command line arguments.
+ */
+ dkChar const * *argv;
+
+ /** Application name.
+ */
+ dkChar const *n_app;
+
+ /** Name of executable file for process.
+ */
+ dkChar const *n_execfile;
+
+ /** Directory bin (directory for binaries - bindir).
+ */
+ dkChar const *n_bindir;
+
+ /** Directory etc (system configuration directory - sysconfdir).
+ */
+ dkChar const *n_etcdir;
+
+ /** Directory share (data root directory - datarootdir).
+ */
+ dkChar const *n_sharedir;
+
+ /** Directory var (local state directory - vardir).
+ */
+ dkChar const *n_vardir;
+
+ /** Login name of process owner.
+ */
+ dkChar const *n_logname;
+
+ /** Home directory of process owner.
+ */
+ dkChar const *n_homedir;
+
+ /** Aplication group name.
+ */
+ dkChar const *n_appgroup;
+
+ /** File name for log file.
+ */
+ dkChar const *n_logfilename;
+
+ /** Directory for temporary files.
+ */
+ dkChar const *n_tmpdir;
+
+ /** Users language.
+ */
+ dkChar const *n_language;
+
+ /** Users region.
+ */
+ dkChar const *n_region;
+
+ /** Language/region setting string from environment or registry.
+ */
+ dkChar const *n_langstr;
+
+ /** Host name.
+ */
+ dkChar const *n_hostname;
+
+ /** Container for message catalogs.
+ */
+ dk3_sto_t *s_mc;
+
+ /** Iterator through message catalogs container.
+ */
+ dk3_sto_it_t *i_mc;
+
+ /** Container for preferences read from command line.
+ */
+ dk3_sto_t *s_cmdprefs;
+
+ /** Iterator through command line preferences container.
+ */
+ dk3_sto_it_t *i_cmdprefs;
+
+ /** Container for self-set preferences.
+ */
+ dk3_sto_t *s_selfprefs;
+
+ /** Iterator through self-set preferences container.
+ */
+ dk3_sto_it_t *i_selfprefs;
+
+ /** Container for system-wide preferences.
+ */
+ dk3_sto_t *s_sysprefs;
+
+ /** Iterator through system-wide preferences container.
+ */
+ dk3_sto_it_t *i_sysprefs;
+
+ /** Container for users constant preferences.
+ */
+ dk3_sto_t *s_constprefs;
+
+ /** Iterator through users constant preferences container.
+ */
+ dk3_sto_it_t *i_constprefs;
+
+ /** Container for users variable preferences.
+ */
+ dk3_sto_t *s_varprefs;
+
+ /** Iterator through users variable preferences container.
+ */
+ dk3_sto_it_t *i_varprefs;
+
+ /** Timestamp: Last logging to stderr.
+ */
+ dk3_time_t t_last_log_stderr;
+
+ /** Timestamp: Last logging to file.
+ */
+ dk3_time_t t_last_log_file;
+
+ /** Line number in current input file (used in error messages).
+ */
+ unsigned long sourceline;
+
+ /** Name part of next temporary file name.
+ */
+ unsigned long ul_tmpname;
+
+ /** Suffix part of next temporary file name.
+ */
+ unsigned u_tmpsuffix;
+
+ /** Application type, see @ref apptypes.
+ */
+ int app_type;
+
+ /** Error code, report delayed after finishing application initialization.
+ */
+ int de;
+
+ /** Log level required for reporting to stderr, see @ref loglevels.
+ */
+ int ll_stderr;
+
+ /** Log level required for reporting to file, see @ref loglevels.
+ */
+ int ll_file;
+
+ /** Log level required to keep log file, see @ref loglevels.
+ */
+ int ll_file_keep;
+
+ /** Log level required to keep temporary files, see @ref loglevels.
+ */
+ int ll_tmp_keep;
+
+ /** Most relevant log level found, see @ref loglevels.
+ */
+ int ll_highest;
+
+ /** Carry flag, too many temporary file names requested.
+ */
+ int i_tmpcarry;
+
+ /** Number of command line arguments.
+ */
+ int argc;
+
+ /** Internal encoding, used for strings in memory, see @ref stringenc.
+ */
+ int i_encoding;
+
+ /** Encoding for output files, see @ref fileenc.
+ */
+ int i_output_encoding;
+
+ /** Encoding expected on stdin, see @ref fileenc.
+ */
+ int i_stdin_input_encoding;
+
+ /** Encoding expected when reading from files, see @ref fileenc.
+ */
+ int i_file_input_encoding;
+
+ /** Flag: Unconfigure application (delete users variable preferences)
+ when finishing the application.
+ */
+ int f_unconfigure;
+
+ /** Flag: Changes applied to preferences, need to save when finishing
+ the application.
+ */
+ int f_prefschanged;
+
+ /** Flag: Setup completed, we can write log messages.
+ */
+ int f_readytolog;
+
+ /** Flag: First attempt to log to file.
+ */
+ int f_first_file_log;
+
+ /** Flag: Already attempted to initialize PRNG.
+ */
+ int f_rand_initialized;
+
+ /** Flag: PRNG was initialized successfully.
+ */
+ int f_rand_success;
+
+ /** PRNG type to use, see @ref rndtypes.
+ */
+ int rand_type;
+
+ /** Flag: ${HOME}/log created.
+ */
+ int cr_log;
+
+ /** Flag: ${HOME}/tmp/xxx created.
+ */
+ int cr_tmp;
+
+} dk3_app_t;
+
+
+
+/** File search result.
+*/
+typedef struct _dk3_search_t_ {
+
+ /** Container for all file names found.
+ */
+ dk3_sto_t *s_fn;
+
+ /** Iterator for all file names container.
+ */
+ dk3_sto_it_t *i_fn;
+
+ /** Application structure, used for diagnostics.
+ */
+ dk3_app_t *app;
+
+ /** Number of next file to add.
+ */
+ unsigned long nf;
+
+ /** Flag: Inverted search order (most relevant files first).
+ */
+ int inverted;
+} dk3_search_t;
+
+
+
+/** Bit field.
+*/
+typedef struct _dk3_bf_t_ {
+
+ /** Data bytes to store the bits.
+ */
+ unsigned char *data;
+
+ /** Optional application structure for diagnostics.
+ */
+ dk3_app_t *app;
+
+ /** Number of bits to save.
+ */
+ size_t nbits;
+} dk3_bf_t;
+
+
+
+/** Bit matrix.
+*/
+typedef struct _dk3_bm_t_ {
+
+ /** Data bytes to store the bits.
+ */
+ unsigned char **data;
+
+ /** Optional application structure for diagnostics.
+ */
+ dk3_app_t *app;
+
+ /** Size of available cache for dk3bm_expand.
+ */
+ size_t cachesize;
+
+ /** Number of bits per row.
+ */
+ size_t columns;
+
+ /** Number of rows.
+ */
+ size_t rows;
+} dk3_bm_t;
+
+
+
+/** LaTeX font encoding information.
+*/
+typedef unsigned char dk3_font_encoding_t;
+
+
+/** Information about one package needed for an encoding.
+*/
+typedef struct {
+ char const *name; /**< Package name. */
+ char used; /**< Flag: Package used. */
+} dk3_uc2lat_pkg_t;
+
+
+/** Pointer to a package information.
+*/
+typedef dk3_uc2lat_pkg_t *dk3_uc2lat_pkg_ptr;
+
+/** Pointer to pointer to a package information.
+*/
+typedef dk3_uc2lat_pkg_ptr *dk3_uc2lat_pkg_pptr;
+
+
+/** Directory entry for UC to LaTeX, represents one input file.
+*/
+typedef struct {
+
+ /** Container to store ranges.
+ */
+ dk3_sto_t *s_ran;
+
+ /** Iterator through ranges container.
+ */
+ dk3_sto_it_t *i_ran;
+
+ /** Short file name containing data for this directory entry.
+ */
+ dkChar const *sn;
+
+ /** Flag: Data was loaded.
+ */
+ unsigned char loaded;
+} dk3_uc2lat_dir_t;
+
+
+
+/** Range of UC characters.
+*/
+typedef struct {
+
+ /** LaTeX encodings for both text and math mode.
+ */
+ char const **a;
+
+ /** LaTeX encodings for text mode only.
+ */
+ char const **t;
+
+ /** LaTeX encodings for math mode only.
+ */
+ char const **m;
+
+ /** Descriptions texts for character.
+ */
+ dkChar const **dsc;
+
+ /** Package collections required for character.
+ NOT USED IN itadmin.
+ */
+ dk3_uc2lat_pkg_t ***p;
+
+ /** Information about font encodings required by characters.
+ */
+ dk3_font_encoding_t *f;
+
+ /** Directory entry responsible for this range.
+ */
+ dk3_uc2lat_dir_t *dir;
+
+ /** First character in range.
+ */
+ dk3_c32_t start;
+
+ /** Last character in range.
+ */
+ dk3_c32_t end;
+
+ /** Flag: Initialization of range attempted, no second attempt.
+ */
+ unsigned char ia;
+} dk3_uc2lat_range_t;
+
+
+
+/** Data for U32 to LaTeX conversion.
+*/
+typedef struct {
+
+ /** Application structure for diagnostics and file search.
+ */
+ dk3_app_t *app;
+
+ /** Name of data directory containing the LaTeX encodings.
+ */
+ dkChar const *dir;
+
+ /** Allocated buffer for characters directly passed through.
+ */
+ char *buf;
+
+ /** Container for ranges.
+ */
+ dk3_sto_t *s_ran;
+
+ /** Iterator through ranges container.
+ */
+ dk3_sto_it_t *i_ran;
+
+ /** Container for directories.
+ */
+ dk3_sto_t *s_dir;
+
+ /** Iterator for directories container.
+ */
+ dk3_sto_it_t *i_dir;
+
+ /** Container for packages.
+ */
+ dk3_sto_t *s_pkg;
+
+ /** Iterator through packages container.
+ */
+ dk3_sto_it_t *i_pkg;
+
+ /** Cache: Last range used.
+ */
+ dk3_uc2lat_range_t *rca;
+
+ /** Size of buffer @a buf.
+ */
+ size_t szbuf;
+
+ /** Flag: Load descriptions for characters too (normally the
+ descriptions are ignored).
+ */
+ int f_dsc;
+
+ /** Flag: Generate UTF-8 output.
+ */
+ int f_utf8;
+
+ /** Font encoding information.
+ */
+ dk3_font_encoding_t fe;
+} dk3_uc2lat_t;
+
+
+
+/** Handler function for one line.
+ @param obj Object to modify using the line.
+ @param il Input line to process.
+ @return 1=OK, 0=error, can continue, -1=error, abort processing.
+*/
+typedef
+int
+dk3_line_handler_t(
+ void *obj,
+ dkChar *il
+);
+
+
+
+/** Struct for processing a file line by line.
+*/
+typedef struct {
+ /** Application structure for diagnostics.
+ */
+ dk3_app_t *app;
+ /** Data object to modify while processing input lines.
+ */
+ void *obj;
+ /** Handler function.
+ */
+ dk3_line_handler_t *hf;
+ /** Buffer for input lines.
+ */
+ dkChar *buf;
+ /** Current insertion position for next character to add.
+ */
+ dkChar *cp;
+ /** Size of input buffer @a buf.
+ */
+ size_t szbuf;
+ /** Number of characters used in @a buf.
+ */
+ size_t bufus;
+ /** System encoding, see @ref stringenc.
+ */
+ int se;
+} dk3_line_handler_data_t;
+
+
+
+/** One option.
+*/
+typedef struct {
+ /** Short option character.
+ */
+ dkChar so;
+ /** Long option text.
+ */
+ dkChar const *lo;
+ /** Flag: Option needs an argument.
+ */
+ int na;
+} dk3_option_t;
+
+
+
+/** Options set.
+*/
+typedef struct {
+ /** Application structure for diagnostics.
+ */
+ dk3_app_t *app;
+ /** Options to find in command line arguments.
+ */
+ dk3_option_t const *options;
+ /** Array of flags, one for each options, whether or not the option was
+ found.
+ */
+ int *found;
+ /** Array for option arguments.
+ */
+ dkChar const **optargs;
+ /** Array of normal arguments (no options and no option arguments).
+ */
+ dkChar const **args;
+ /** Further options.
+ */
+ dkChar const **fo;
+ /** Short option to introduce further options.
+ */
+ dkChar foc;
+ /** Long option to introduce further options.
+ */
+ dkChar const *focl;
+ /** Number of elements in @a options.
+ */
+ size_t szoptions;
+ /** Number of normal arguments available.
+ */
+ int argsav;
+ /** Number of normal arguments used (found).
+ */
+ int argsused;
+ /** Number of further options available.
+ */
+ int foav;
+ /** Number of further options found.
+ */
+ int fou;
+ /** Error code of last error occured, see @ref errorcodes.
+ */
+ int ec;
+} dk3_option_set_t;
+
+
+
+/** Output filter cell details for ASCII/Hex encoding.
+*/
+typedef struct {
+ /** Number of characters already printed in current line.
+ */
+ size_t nl;
+} dk3_of_cell_ah_details_t;
+
+/** Output filter cell details for ASCII85 encoding.
+*/
+typedef struct {
+ /** 32-bit value built up by for bytes.
+ */
+ unsigned long val;
+ /** Number of characters merged into @a val.
+ */
+ size_t nc;
+ /** Number of characters already printed in current line.
+ */
+ size_t nl;
+} dk3_of_cell_a85_details_t;
+
+
+
+/** Output filter cell details for run-length compression.
+*/
+typedef struct {
+ /** Data buffer.
+ */
+ unsigned char *bu;
+ /** Number of bytes used in buffer @a bu.
+ */
+ size_t used;
+ /** Number of same bytes repeated.
+ */
+ size_t same;
+ /** Previous character processed.
+ */
+ unsigned char pc;
+ /** Flag: Have a previous character.
+ */
+ unsigned char hc;
+ /** Flag: In a run.
+ */
+ unsigned char run;
+} dk3_of_cell_rl_details_t;
+
+
+
+#if DK3_HAVE_ZLIB_H
+/** Output filter cell details for flate compression.
+*/
+typedef struct {
+ /** zlib stream.
+ */
+ z_stream *zs;
+ /** Input buffer.
+ */
+ Bytef *ibu;
+ /** Output buffer.
+ */
+ Bytef *obu;
+ /** Number of input bytes used.
+ */
+ uLong iused;
+ /** Flag: Everything ok, no errors yet.
+ */
+ int ok;
+} dk3_of_cell_flate_details_t;
+#endif
+
+
+/** Output filter cell details.
+*/
+typedef union {
+#if DK3_HAVE_ZLIB_H
+ /** Flate compression data.
+ */
+ dk3_of_cell_flate_details_t flate;
+#endif
+ /** Run-length compression data.
+ */
+ dk3_of_cell_rl_details_t psrl;
+ /** ASCII85 encoding data.
+ */
+ dk3_of_cell_a85_details_t a85;
+ /** ASCII-Hex encoding data.
+ */
+ dk3_of_cell_ah_details_t ah;
+} dk3_of_cell_details_t;
+
+
+
+/** Output filter cell.
+*/
+typedef struct _dk3_of_cell_t_ {
+ /** Compression/encoding algorithm-specific data.
+ */
+ dk3_of_cell_details_t data;
+ /** Next cell downwards.
+ */
+ struct _dk3_of_cell_t_ *down;
+ /** Next cell upwards.
+ */
+ struct _dk3_of_cell_t_ *up;
+ /** Output filter owning this cell.
+ */
+ void *of; /**< Output filter. */
+ /** Output filter cell type DK3_OF_CELL_TYPE_xxx,
+ see @ref outputfiltercelltypes.
+ */
+ int type;
+} dk3_of_cell_t;
+
+
+
+/** Output filter on top of a stream.
+*/
+typedef struct {
+ /** Application structure for diagnostics.
+ */
+ dk3_app_t *app;
+ /** Output stream to receive the filtered data.
+ */
+ dk3_stream_t *os;
+ /** Bottom filter cell (next to the stream).
+ */
+ dk3_of_cell_t *bottom;
+ /** Top filter cell (input goes to here).
+ */
+ dk3_of_cell_t *top;
+ /** Number of cells.
+ */
+ size_t nCells;
+ /** Number of bits used in the @a bits variable.
+ */
+ size_t nBits;
+ /** The bits stored so far.
+ */
+ unsigned char bits;
+ /** Flag set for output filter.
+ */
+ unsigned char flags;
+} dk3_of_t;
+
+
+
+#if 0
+
+/** One datum stored in the in-memory database.
+*/
+typedef struct {
+ /** Start address of data.
+ */
+ void *data;
+ /** Data size (number of bytes).
+ */
+ size_t size;
+} dk3_memdb_datum_t;
+
+
+
+/** In-memory database.
+*/
+typedef struct {
+ /** Container for the key/value pairs.
+ */
+ dk3_sto_t *st;
+ /** Iterator through key/value pair container.
+ */
+ dk3_sto_it_t *it;
+ /** Application structure for diagnostics.
+ */
+ dk3_app_t *app;
+ /** File name of database on disk.
+ */
+ dkChar const *fn;
+ /** Start of key.
+ */
+ char *kb;
+ /** Start of value.
+ */
+ char *vb;
+ /** Input line buffer.
+ */
+ char *il;
+ /** Binary key size.
+ */
+ size_t szkb;
+ /** Text key size.
+ */
+ size_t szkt;
+ /** Binary value size.
+ */
+ size_t szvb;
+ /** Text value size.
+ */
+ size_t szvt;
+ /** Text line size.
+ */
+ size_t szl;
+ /** Error code of last error occured, see @ref errorcodes.
+ */
+ int ec;
+ /** Flag: Dirty (synchronization needed).
+ */
+ int f_dt;
+} dk3_memdb_t;
+
+#endif
+
+
+
+/** Data to store in a database as key or value.
+*/
+typedef struct {
+ /** Data bytes.
+ */
+ void *dt;
+ /** Number of bytes.
+ */
+ size_t sz;
+} dk3_datum_t;
+
+
+
+/** Details for a memory database.
+*/
+typedef struct {
+ /** Container for key/value pairs.
+ */
+ dk3_sto_t *s_mem;
+ /** Container iterator.
+ */
+ dk3_sto_it_t *i_mem;
+} dk3_dbi_mem_details_t;
+
+
+
+/** Details for Berkeley DB database.
+*/
+typedef struct {
+ /** The BDB database.
+ */
+ void *dbptr;
+} dk3_dbi_bdb_details_t;
+
+
+
+/** Details for NDBM database.
+*/
+typedef struct {
+ /** 8-bit character file name, only used if dkChar is 16 bit or above.
+ */
+ void *dbptr;
+} dk3_dbi_ndbm_details_t;
+
+
+
+/** Database type specific details.
+*/
+typedef union {
+ /** Memory database.
+ */
+ dk3_dbi_mem_details_t mem;
+ /** Berkeley database details.
+ */
+ dk3_dbi_bdb_details_t bdb;
+ /** NDBM database details.
+ */
+ dk3_dbi_ndbm_details_t ndbm;
+} dk3_dbi_details_t;
+
+
+
+/** Database interface.
+*/
+typedef struct {
+ /** Database type specific details.
+ */
+ dk3_dbi_details_t details;
+ /** Application structure for diagnostics.
+ */
+ dk3_app_t *app;
+ /** File name for database on disk.
+ */
+ dkChar const *fn;
+ /** Database type, DK3_DB_TYPE_xxx, see @ref databasetypes.
+ */
+ int tp;
+ /** Flag: Database opened for writing.
+ */
+ int wr;
+ /** Flag: Database modified, sync to file necessary.
+ */
+ int mod;
+ /** Flag: Write error messages for keys not found.
+ */
+ int rfk;
+ /** Error code for last error occured.
+ */
+ int ec;
+} dk3_dbi_t;
+
+
+
+/** BIF coordinates type.
+ Must include negative values as predictor operators may
+ try to obtain values in row and column -1.
+*/
+typedef long dk3_bif_coord_t;
+
+
+
+/** BIF pixel value type.
+*/
+typedef unsigned short dk3_bif_pixel_t;
+
+/** Size of BIF pixel value.
+*/
+#define DK3_SIZEOF_BIF_PIXEL_T DK3_SIZEOF_SHORT
+
+/** Pixel resample information.
+*/
+typedef struct {
+ size_t iw; /**< Input width. */
+ size_t ow; /**< Output width. */
+ dk3_bif_pixel_t im; /**< Input maximum. */
+ dk3_bif_pixel_t om; /**< Output maximum. */
+ dk3_bif_pixel_t im2; /**< Half of input minimum. */
+} dk3_pixel_resample_t;
+
+
+
+/** One frame in bitmap image file.
+*/
+typedef struct {
+ /** X resolution.
+ */
+ double xres;
+ /** Y resolution.
+ */
+ double yres;
+ /** Bitmap type specific data per frame.
+ */
+ void *implspec;
+ /** Frame width.
+ */
+ dk3_bif_coord_t w;
+ /** Frame height.
+ */
+ dk3_bif_coord_t h;
+ /** Bits per component for frame found in file.
+ */
+ size_t bits;
+ /** Number of non-redundant bits in @ bits.
+ */
+ size_t realbits;
+ /** Frame number.
+ */
+ size_t n; /**< Frame number. */
+ /** Color space, DK3_COLOR_SPACE_xxx, see @ref colorspaces.
+ */
+ int cs;
+ /** Flag: Really colored, 1=colored, 0=gray.
+ */
+ int realcolor;
+ /** Flag: Really found alpha data.
+ */
+ int realalpha;
+ /** Flag: Background color defined for frame.
+ */
+ int bg;
+ /** Background red found in file.
+ */
+ dk3_bif_pixel_t bgr;
+ /** Background green found in file.
+ */
+ dk3_bif_pixel_t bgg;
+ /** Background blue found in file.
+ */
+ dk3_bif_pixel_t bgb;
+ /** Background gray found in file.
+ */
+ dk3_bif_pixel_t bggr;
+} dk3_bif_frame_t;
+
+
+
+/** Bitmap image file.
+*/
+typedef struct {
+ /** Structure to upsample or downsample pixel values.
+ */
+ dk3_pixel_resample_t pr;
+ /** Application structure for diagnostics.
+ */
+ dk3_app_t *app;
+ /** Container for frames.
+ */
+ dk3_sto_t *s_frames;
+ /** Iterator through frames container.
+ */
+ dk3_sto_it_t *i_frames;
+ /** Current frame to process.
+ */
+ dk3_bif_frame_t *cf;
+ /** Bitmap image type specific data per file.
+ */
+ void *implspec;
+ /** Name of temporary file (if any), may be NULL.
+ */
+ char const *tmpfn;
+ /** Temporary file (if any), may be NULL.
+ */
+ FILE *tmpfipo;
+ /** Number of bitmap image file within process.
+ */
+ unsigned long n;
+ /** Number of frames available.
+ */
+ size_t n_frames;
+ /** Bits per component requested for output.
+ */
+ size_t bits;
+ /** BIF image type DK3_BIF_IMAGE_TYPE_xxx, see @ref bifimagetypes.
+ */
+ int bt;
+ /** Flag: Force use of requested background over bg found in file.
+ */
+ int bg;
+ /** Flag: Remove temporary file when closing the structure.
+ */
+ int remtmpf;
+ /** Background red requested.
+ */
+ dk3_bif_pixel_t bgr;
+ /** Background green requested.
+ */
+ dk3_bif_pixel_t bgg;
+ /** Background blue requested.
+ */
+ dk3_bif_pixel_t bgb;
+} dk3_bif_t;
+
+
+
+/** Paper size description. All sizes are specified in PS points.
+*/
+typedef struct {
+ /** Width.
+ */
+ double w;
+ /** Height.
+ */
+ double h;
+ /** Left border (inner border for duplex without tumble).
+ */
+ double i;
+ /** Right border (outer border for duplex without tumble).
+ */
+ double o;
+ /** Top border (inner border for duplex with tumble).
+ */
+ double t;
+ /** Bottom bofder (outer border for duplex with tumble).
+ */
+ double b;
+} dk3_paper_size_t;
+
+
+
+/** Named paper size.
+*/
+typedef struct {
+ /** Size.
+ */
+ dk3_paper_size_t size;
+ /** Size name.
+ */
+ dkChar const *name;
+} dk3_named_paper_size_t;
+
+
+
+/** Collection of multiple named paper sizes.
+*/
+typedef struct {
+ /** Application structure for diagnostics and file search.
+ */
+ dk3_app_t *app;
+ /** Container of named paper sizes.
+ */
+ dk3_sto_t *s_sizes;
+ /** Iterator through named paper sizes container.
+ */
+ dk3_sto_it_t *i_sizes;
+} dk3_paper_size_collection_t;
+
+
+
+
+
+
+/** Area to place an image.
+*/
+typedef struct {
+ /** Left x.
+ */
+ double xl;
+ /** Right x.
+ */
+ double xr;
+ /** Top y.
+ */
+ double yt;
+ /** Bottom y.
+ */
+ double yb;
+} dk3_image_area_t;
+
+
+
+/** Area to place a PS/PDF image.
+*/
+typedef union {
+ /** Paper size for creating a document.
+ */
+ dk3_paper_size_t ps;
+ /** Image area to use when converting Fig to PS.
+ */
+ dk3_image_area_t ia;
+} dk3_bm_eps_area_t;
+
+
+
+/** Object start position.
+*/
+typedef struct {
+ /** Object number.
+ */
+ unsigned long objno;
+
+ /** Start position in file.
+ */
+ dk3_um_t startpos;
+} dk3_pdf_position_t;
+
+
+
+/** XObject representing one image or alpha mask.
+*/
+typedef struct {
+ /** Name of temporary file with contents.
+ */
+ dkChar const *tempfilename;
+
+ /** Xobject for alpha mask.
+ */
+ void *mask;
+
+ /** Stream length.
+ */
+ dk3_um_t slgt;
+
+ /** Image width (number of pixels).
+ */
+ dk3_bif_coord_t width;
+
+ /** Image height (number of pixels).
+ */
+ dk3_bif_coord_t height;
+
+ /** Object number for XObject.
+ */
+ unsigned long objno;
+
+ /** XObject type DK3_PDF_XO_TYPE_xxx, see @ref pdfxobjecttype.
+ */
+ int xot;
+
+ /** Procedure for object, DK3_BMEPS_xxx, see @ref bmepscompression.
+ */
+ int procedure;
+
+ /** Bits per component.
+ */
+ int bpc;
+
+ /** Flag: Stream is DCT (1) or flate (0).
+ */
+ int dct;
+
+ /** Predictor DK3_COMPRESSIONPREDICTOR_xxx, see @ref flatepredictors.
+ */
+ int pred;
+
+ /** Flag: Adobe marker was found in CMYK DCT file.
+ */
+ int adobe_marker_found;
+
+ /** Flag: Used by current page.
+ */
+ int used;
+
+ /** Flag: Interpolate this object.
+ */
+ int interpolate;
+} dk3_pdf_xobject_t;
+
+
+
+/** One PDF page.
+*/
+typedef struct {
+ /** Name of temporary file for page description stream.
+ */
+ dkChar const *tempfilename;
+
+ /** Temporary file.
+ */
+ FILE *tempfile;
+
+ /** Stream to write to temporary file.
+ */
+ dk3_stream_t *tempstream;
+
+ /** Output filter, used to write to temporary file.
+ */
+ dk3_of_t *tempof;
+
+ /** Collection of all XObjects used by this page.
+ */
+ dk3_sto_t *s_xobjects;
+
+ /** Iterator through XObjects collection.
+ */
+ dk3_sto_it_t *i_xobjects;
+
+ /** Stream length.
+ */
+ dk3_um_t slgt;
+
+ /** PDF object number.
+ */
+ unsigned long objno;
+
+ /** Page number.
+ */
+ unsigned long pageno;
+
+ /** Media box x0.
+ */
+ long mbx0;
+
+ /** Media box x1.
+ */
+ long mbx1;
+
+ /** Media box y0.
+ */
+ long mby0;
+
+ /** Media box y1.
+ */
+ long mby1;
+} dk3_pdf_page_t;
+
+
+
+/** Structure used to write a PDF file.
+*/
+typedef struct {
+ /** Application structure, used to find temporary file names.
+ */
+ dk3_app_t *app;
+
+ /** XObject storage (bitmaps).
+ */
+ dk3_sto_t *s_xobjects;
+
+ /** Iterator through XObject storage.
+ */
+ dk3_sto_it_t *i_xobjects;
+
+ /** Pages storage.
+ */
+ dk3_sto_t *s_pages;
+
+ /** Iterator through pages storage.
+ */
+ dk3_sto_it_t *i_pages;
+
+ /** Current page.
+ */
+ dk3_pdf_page_t *cp;
+
+ /** Next XObject object number.
+ First Xobject is object number 4 as we have info object,
+ root object and pages collection object as 1, 2, and 3.
+ */
+ unsigned long nextobject;
+
+ /** Next page number.
+ */
+ unsigned long nextpage;
+
+ /** Media box x0 for next page.
+ */
+ long mbx0;
+
+ /** Media box x1 for next page.
+ */
+ long mbx1;
+
+ /** Media box y0 for next page.
+ */
+ long mby0;
+
+ /** Media box y1 for next page.
+ */
+ long mby1;
+
+ /** Flag: Document mode (1) or image/object (0).
+ */
+ int documentMode;
+
+} dk3_pdf_t;
+
+
+/** Options to convert a bitmap image to PS/PDF.
+*/
+typedef struct {
+ /** Image area.
+ */
+ dk3_bm_eps_area_t ima;
+
+ /** Resolution in dpi.
+ */
+ double resolution;
+
+ /** Application structure for diagnostics, may be NULL.
+ */
+ dk3_app_t *app;
+
+ /** Output driver DK3_BMEPS_DRIVER_xxx, see @ref bmepsdrivers.
+ */
+ int dr;
+
+ /** Run mode DK3_BMEPS_MODE_xxx, see @ref dkbmmodes.
+ */
+ int mode;
+
+ /** Size conversion mode.
+ */
+ int szmode;
+
+ /** Compression predictor for flate compression,
+ DK3_COMPRESSION_PREDICTOR_xxx, see @ref flatepredictors.
+ */
+ int pred;
+
+ /** Image origin position DK3_IMAGE_ORIGIN, see @ref imageorigin.
+ */
+ int io;
+
+ /** Flag: Draft mode.
+ */
+ int draft;
+
+ /** Flag: Printout in duplex.
+ */
+ int duplex;
+
+ /** Flag: Printout in tumble mode (like a calendar).
+ */
+ int tumble;
+
+ /** PS level (2 or 3).
+ */
+ int psl;
+
+ /** Flag: Write DSC comments.
+ */
+ int dsc;
+
+ /** Flag: Allow direct DCT data transfer.
+ */
+ int dct;
+
+ /** Flag: Keep aspect ratio.
+ */
+ int kar;
+
+ /** Requested/suggested background red, 8 bits per pixel.
+ */
+ int bgr;
+
+ /** Requested/suggested background green, 8 bits per pixel.
+ */
+ int bgg;
+
+ /** Requested/suggested background blue, 8 bits per pixel.
+ */
+ int bgb;
+
+ /** Flag: Enforce this background over bg color found in file.
+ */
+ int fbg;
+
+ /** Flag: Image interpolation enabled.
+ */
+ int ip;
+
+ /** Flag: Image interpolation enabled for JPEG files too.
+ */
+ int jip;
+
+ /** Flag: Make mode.
+ */
+ int make;
+
+ /** Write colored output.
+ */
+ int color;
+
+ /** Flag: Reduce bits per component.
+ */
+ int rbpc;
+
+ /** Flag: Write to stdout.
+ */
+ int to_stdout;
+} dk3_bm_eps_options_t;
+
+
+
+/** Internal conversion job structure.
+*/
+typedef struct {
+
+ /** Conversion option set.
+ */
+ dk3_bm_eps_options_t *opt;
+
+ /** Localized message texts.
+ */
+ dkChar const * const *msg;
+
+ /** Source file name.
+ */
+ dkChar const *sfn;
+
+ /** Destination file name.
+ */
+ dkChar const *dfn;
+
+ /** Destination file.
+ */
+ FILE *dfile;
+
+ /** PDF writer structure.
+ */
+ dk3_pdf_t *pdf;
+
+ /** Bitmap image file.
+ */
+ dk3_bif_t *bif;
+
+ /** Communication object.
+ */
+ void *pComm;
+
+ /** Translation x.
+ */
+ double x_translate;
+
+ /** Translation y.
+ */
+ double y_translate;
+
+ /** Scale x.
+ */
+ double x_scale;
+
+ /** Scale y.
+ */
+ double y_scale;
+
+ /** Left x coordinate (used for the draft).
+ */
+ double x_0;
+
+ /** Right x coordinate (used for the draft).
+ */
+ double x_1;
+
+ /** Lower y coordinate (used for the draft).
+ */
+ double y_0;
+
+ /** Upper y coordinate (used for the draft).
+ */
+ double y_1;
+
+ /** Image width (bounding box).
+ */
+ long x_size;
+
+ /** Image width (bounding box).
+ */
+ long y_size;
+
+ /** Number of bits per component.
+ */
+ size_t bpc;
+
+ /** Number of pages to produce.
+ */
+ size_t nPages;
+
+ /** Number of current page.
+ */
+ size_t currentPage;
+
+ /** Minimum value for progress bar.
+ */
+ int minpb;
+
+ /** Maximum value for progress bar.
+ */
+ int maxpb;
+
+ /** Image file type.
+ */
+ int biftype;
+
+ /** Flag: Must translate coordinates.
+ */
+ int do_translate;
+
+ /** Rotation (multiples of 90 degree).
+ */
+ int do_rotate;
+
+ /** Use floating point numbers for scaling.
+ */
+ int do_float_scale;
+
+ /** Flag: Must do header and footer.
+ */
+ int do_header_footer;
+
+ /** Output procedure DK3_BMEPS_xxx, see @ref bmepscompression.
+ */
+ int procedure;
+
+} dk3_bm_conversion_job_t;
+
+
+
+/** Information about one font.
+*/
+typedef struct {
+ char const *psFontName; /**< PS font name. */
+ char const *texFontName; /**< LaTeX font name. */
+ char const *texFamilyName; /**< LaTeX font family name. */
+ char const *gsFontName; /**< GhostScript font name. */
+ char const *gsFileOld; /**< Old GhostScript font file name. */
+ char const *gsFileNew; /**< New GhostScript font file name. */
+ char const *psFamilyName; /**< PS font family name. */
+ char const *svgFamilyName; /**< SVG font family name. */
+ char const *svgFontId; /**< SVG font identifier. */
+ char const * const *replacements; /**< Replacement family names. */
+ int features; /**< Font features (bold/italic). */
+ int svgFeatures; /**< Font features when used in SVG. */
+ int svgFontWeight; /**< Font weight. */
+} dk3_font_t;
+
+
+
+/** Bounding box data.
+*/
+typedef struct {
+ double xmin; /**< Minimum x. */
+ double xmax; /**< Maximum x. */
+ double ymin; /**< Minimum y. */
+ double ymax; /**< Maximum y. */
+ int xused; /**< Flag: x-value specified. */
+ int yused; /**< Flag: y-value specified. */
+} dk3_bb_t;
+
+
+
+/** Coordinates transformation-
+*/
+typedef struct {
+ double mx; /**< X factor. */
+ double nx; /**< X summand. */
+ double my; /**< Y factor. */
+ double ny; /**< Y summand. */
+} dk3_ct_2d_t;
+
+
+
+/** Color specified as RGB.
+*/
+typedef struct {
+ double r; /**< Red. */
+ double g; /**< Green. */
+ double b; /**< Blue. */
+} dk3_rgb_color_t;
+
+
+
+/** Coordinates system transformation to place an image.
+ Order of operations is translate, rotate, scale.
+*/
+typedef struct {
+ double x_translate; /**< X translation. */
+ double y_translate; /**< Y translation. */
+ double x_scale; /**< X scale factor. */
+ double y_scale; /**< Y scale factor. */
+ int rot; /**< Rotation angle, multiple of 90 degrees. */
+} dk3_coordinates_transformation_t;
+
+
+
+/** Details for a Windows printer.
+*/
+typedef struct {
+ int dummy; /**< No details for Windows. */
+} dk3_printer_windows_details_t;
+
+
+
+/** Details for LPRng/LPD queue.
+*/
+typedef struct {
+ dkChar const *hostname; /**< Destination host name. */
+ dkChar const *queuename; /**< Destination queue name. */
+ double to_c; /**< Timeout for connect. */
+ double to_r; /**< Timeout for receive. */
+ double to_s; /**< Timeout for send. */
+} dk3_printer_lprng_details_t;
+
+
+
+/** Details for a socket connected printer.
+*/
+typedef struct {
+ dkChar const *hostname; /**< Destination host or address. */
+ unsigned short portno; /**< Port no, host representation. */
+ unsigned char ordrel; /**< Flag: Orderly release. */
+ double to_c; /**< Timeout for connect. */
+ double to_r; /**< Timeout for receive. */
+ double to_s; /**< Timeout for send. */
+} dk3_printer_socket_t;
+
+
+
+/** Details for a printer.
+*/
+typedef union {
+ dk3_printer_windows_details_t win; /**< Windows printer details. */
+ dk3_printer_lprng_details_t lprng; /**< LPRng printer details. */
+ dk3_printer_socket_t sock; /**< Socket printer details. */
+} dk3_printer_details_t;
+
+
+
+/** Printer.
+ Windows printer ports can be a connection to a remote
+ raw socket or LPD/LPRng queue. In these cases t_p and det_p
+ indicate "Windows printer" and the t_s and det_s contain
+ information about the backend.
+ For the "clean" and "status" commands we need to access
+ the backend, other operations only access the Windows printer.
+
+*/
+typedef struct {
+ dk3_printer_details_t det_p; /**< Primary type printer details. */
+ dk3_printer_details_t det_s; /**< Secondary type printer details. */
+ dkChar const *name; /**< Printer name. */
+ dkChar const *h_snmp; /**< Host to access for SNMP. */
+ dkChar const *c_snmp; /**< SNMP community. */
+ int t_p; /**< Primary type,see @ref printertypes. */
+ int t_s; /**< Secondard type, see @ref printertypes. */
+ int v_snmp; /**< SNMP version. */
+ int ps; /**< Flag: PS printer. */
+} dk3_printer_t;
+
+
+
+/** Queue name alias.
+*/
+typedef struct {
+ dkChar const *name; /**< Alias name. */
+ dk3_printer_t *printer; /**< Alias destination. */
+} dk3_printer_alias_t;
+
+
+
+/** Print host.
+*/
+typedef struct {
+ dkChar const *name; /**< Host name. */
+ double to_c; /**< Timeout for connect. */
+ double to_r; /**< Timeout for receive. */
+ double to_s; /**< Timeout for send. */
+ int enc; /**< Host encoding (plain or UTF-8). */
+} dk3_print_host_t;
+
+
+
+/** Print host alias.
+*/
+typedef struct {
+ dkChar const *name; /**< Alias name. */
+ dk3_print_host_t *host; /**< Destination host. */
+} dk3_print_host_alias_t;
+
+
+
+/** Print configuration for a computer system.
+*/
+typedef struct {
+ dk3_app_t *app; /**< Application structure. */
+ dkChar const * const *msg; /**< Localized message texts. */
+ dk3_sto_t *sPrinters; /**< Printers storage. */
+ dk3_sto_it_t *iPrinters; /**< Iterator through printers. */
+ dk3_sto_t *sPrintAliases; /**< Printer aliases storage. */
+ dk3_sto_it_t *iPrintAliases; /**< Iterator through print aliases. */
+ dk3_sto_t *sPrintHosts; /**< Print hosts storage. */
+ dk3_sto_it_t *iPrintHosts; /**< Iterator through hosts. */
+ dk3_sto_t *sHostAliases; /**< Print host aliases storage. */
+ dk3_sto_it_t *iHostAliases; /**< Iterator through host aliases. */
+ dk3_printer_t *defPrinter; /**< Default printer. */
+ dk3_print_host_t *defHost; /**< Default host. */
+ int defPsl; /**< Default PS level. */
+} dk3_print_conf_t;
+
+
+
+#if DK3_HAVE_VOLATILE
+/** The volatile keyword can be used.
+*/
+#define DK3_VOLATILE volatile
+#else
+/** The volatile keyword can not be used.
+*/
+#define DK3_VOLATILE /* NIX */
+#endif
+
+typedef
+#if DK3_HAVE_SIG_ATOMIC_T
+/** Atomic type for signal handlers.
+*/
+sig_atomic_t
+#else
+/** Atomic type or int for signal handlers.
+*/
+int
+#endif
+dk3_sig_atomic_t;
+
+/** Pointer to dkChar.
+*/
+typedef dkChar *DK3_PDKCHAR;
+
+/** Pointer to const dkChar.
+*/
+typedef dkChar const *DK3_PCDKCHAR;
+
+/** Pointer to unsigned char.
+*/
+typedef unsigned char *DK3_PUCHAR;
+
+/** Pointer to char.
+*/
+typedef char *DK3_PCHAR;
+
+/** Pointer to char const.
+*/
+typedef char const *DK3_PCCHAR;
+
+/** Return type for signal handlers.
+*/
+typedef void dk3_signal_ret_t;
+
+/** Signal handler function prototype.
+*/
+typedef
+dk3_signal_ret_t
+dk3_signal_fct_t(int)
+/*^modifies internalState^*/
+;
+
+/** Signal disposition (handler function address).
+*/
+typedef dk3_signal_fct_t *dk3_signal_disp_t;
+
+/** Handler function for one character.
+ @param obj Object to modify using the line.
+ @param ch Character to process.
+ @return 1=OK, 0=error, can continue, -1=error, abort processing.
+*/
+typedef
+int
+dk3_char_handler_t(
+ void *obj,
+ dk3_c32_t ch
+);
+
+/** Function to traverse a simple database.
+ @param obj Object to modify while traversing the database.
+ @param key Key data.
+ @param val Value data.
+ @return 1 on success, 0 on error (can continue), -1 on error (abort).
+*/
+typedef
+int
+dk3_db_traverse_fct_t(
+ void *obj,
+ dk3_datum_t *key,
+ dk3_datum_t *val
+)
+/*^modifies *obj,*key,*val^*/
+;
+
+/** Position in a text stream.
+*/
+typedef struct {
+ dk3_um_t bytes; /**< Number of bytes successfully proceeded. */
+ dk3_um_t chars; /**< Number of current character. */
+ dk3_um_t lineno; /**< Current line number. */
+ dk3_um_t charil; /**< Current character position in line. */
+} dk3_text_stream_position_t;
+
+#endif
+
diff --git a/support/dktools/dk3uc2l.c b/support/dktools/dk3uc2l.c
new file mode 100644
index 0000000000..56236d21c6
--- /dev/null
+++ b/support/dktools/dk3uc2l.c
@@ -0,0 +1,2223 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3uc2l.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3uc2l.c The dk3uc2l module.
+*/
+
+
+#line 162 "dk3uc2l.ctr"
+
+/** Enable or disable support for dk3_uc2l_pkg_t.
+*/
+#define HAVE_PACKAGES 1
+
+
+#include "dk3all.h"
+#include "dk3maih8.h"
+
+
+
+
+#line 173 "dk3uc2l.ctr"
+
+
+
+/** LaTeX commands to start and end math mode.
+*/
+static char const * const dk3uc2lat_mm[] = {
+"\\(",
+"\\)",
+"% font encodings:",
+"% package: ",
+"\n",
+};
+
+
+
+#if 0
+/** Font encoding names.
+*/
+static char const * const dk3uc2lat_font_encodings[] = {
+"ot1",
+"!ot1",
+"t1",
+"!t1",
+"t4",
+"!t4",
+"t5",
+"!t5",
+NULL
+};
+#endif
+
+
+
+/** Font encoding names, used in error messages.
+*/
+static dkChar const * const dk3uc2l_font_encoding_names[] = {
+dkT("OT1"),
+dkT("T1"),
+dkT("T4"),
+dkT("T5"),
+NULL
+};
+
+
+
+/** Font encoding names written at end of output file.
+*/
+static const char * const dk3uc2l_c8_font_encoding_names[] = {
+/* 0 */
+" OT1",
+
+/* 1 */
+" T1",
+
+/* 2 */
+" T4",
+
+/* 3 */
+" T5",
+
+NULL
+
+
+#line 227 "dk3uc2l.ctr"
+};
+
+
+
+/** Allowed suffixes for conversion data files.
+*/
+static dkChar const * const dk3uc2l_suffixes[] = {
+dkT(".t2l"),
+#if DK3_HAVE_ZLIB_H && (DK3_CHAR_SIZE == 1)
+dkT(".t2l.gz"),
+#endif
+#if DK3_HAVE_BZLIB_H && (DK3_CHAR_SIZE == 1)
+dkT(".t2l.bz2"),
+#endif
+NULL
+};
+
+
+
+/** Compression suffixes.
+*/
+static dkChar const * const dk3uc2l_co_suf[] = {
+/* 0 */
+dkT(".gz"),
+
+/* 1 */
+dkT(".bz2"),
+
+NULL
+
+
+#line 253 "dk3uc2l.ctr"
+};
+
+
+
+/** Attribute keywords.
+*/
+static const char * const dk3uc2l_kw[] = {
+/* 0 */
+"b$oth",
+
+/* 1 */
+"t$ext",
+
+/* 2 */
+"m$ath",
+
+/* 3 */
+"e$ncoding",
+
+/* 4 */
+"p$ackages",
+
+NULL
+
+
+#line 267 "dk3uc2l.ctr"
+};
+
+
+
+/** Encoding names, used for reporting.
+*/
+static const char * const dk3uc2l_enco[] = {
+/* 0 */
+"ot1",
+
+/* 1 */
+"t1",
+
+/* 2 */
+"t4",
+
+/* 3 */
+"t5",
+
+NULL
+
+
+#line 280 "dk3uc2l.ctr"
+};
+
+
+
+/** Release an array of string pointers.
+ @param ap Array base address.
+ @param ns Number of strings.
+*/
+static
+void
+dk3uc2lat_release_pointer_array(char const **ap, size_t ns)
+{
+ char const **ptr; /* Current string in array. */
+ size_t i; /* Current string index in array. */
+
+
+#line 295 "dk3uc2l.ctr"
+ ptr = ap; i = ns;
+ while(i--) {
+ dk3_release(*ptr);
+ ptr++;
+ }
+
+#line 300 "dk3uc2l.ctr"
+ dk3_delete(ap);
+}
+
+
+
+/** Destroy range structure, release memory.
+ @param rp Structure to destroy.
+*/
+static
+void
+dk3uc2lat_range_delete(dk3_uc2lat_range_t *rp)
+{
+ size_t numchar; /* Number of characters in this range. */
+ dkChar const **ptr; /* Release all descriptions. */
+ dk3_uc2lat_pkg_t ***pkgppp;
+ size_t i; /* Number of descriptions to release. */
+
+
+#line 317 "dk3uc2l.ctr"
+ if(rp) {
+ numchar = (size_t)(rp->end - rp->start + 1);
+ if(numchar > 0) {
+ rp->dir = NULL;
+ if(rp->f) {
+ dk3_release(rp->f);
+ } rp->f = NULL;
+ if(rp->dsc) {
+ ptr = rp->dsc;
+ i = (size_t)(rp->end - rp->start + 1);
+ while(i--) {
+ dk3_release(*ptr);
+ ptr++;
+ }
+ } rp->dsc = NULL;
+ if(rp->a) {
+ dk3uc2lat_release_pointer_array(rp->a, numchar);
+ } rp->a = NULL;
+ if(rp->t) {
+ dk3uc2lat_release_pointer_array(rp->t, numchar);
+ } rp->t = NULL;
+ if(rp->m) {
+ dk3uc2lat_release_pointer_array(rp->m, numchar);
+ } rp->m = NULL;
+ if(rp->p) {
+ pkgppp = rp->p;
+ i = (size_t)(rp->end - rp->start + 1);
+ while (i--) {
+ dk3_release(*pkgppp);
+ pkgppp++;
+ }
+ dk3_delete(rp->p);
+ } rp->p = NULL;
+ rp->start = (dk3_c32_t)0UL; rp->end = (dk3_c32_t)0UL;
+ rp->ia = 0x00;
+ }
+ dk3_delete(rp);
+ }
+
+#line 355 "dk3uc2l.ctr"
+}
+
+
+#if HAVE_PACKAGES
+
+/** Destroy package structure, release memory.
+ @param pp Structure to release.
+*/
+static
+void
+dk3uc2lat_pkg_delete(dk3_uc2lat_pkg_t *pp)
+{
+
+
+#line 368 "dk3uc2l.ctr"
+ if(pp) {
+
+#line 369 "dk3uc2l.ctr"
+ dk3_release(pp->name);
+ pp->used = 0x00;
+ dk3_delete(pp);
+ }
+
+#line 373 "dk3uc2l.ctr"
+}
+
+#endif
+
+
+/** Destroy UC to LaTeX directory structure, release memory.
+ @param dp Structure to destroy.
+*/
+static
+void
+dk3uc2lat_dir_delete(dk3_uc2lat_dir_t *dp)
+{
+
+
+#line 386 "dk3uc2l.ctr"
+ if(dp) {
+ if(dp->s_ran) {
+ if(dp->i_ran) {
+ dk3sto_it_close(dp->i_ran);
+ } dp->i_ran = NULL;
+ dk3sto_close(dp->s_ran);
+ } dp->s_ran = NULL;
+ dk3_release(dp->sn);
+ dp->loaded = 0x00;
+ dk3_delete(dp);
+ }
+
+#line 397 "dk3uc2l.ctr"
+}
+
+
+
+#if HAVE_PACKAGES
+
+/** Compare two package records.
+ @param l Left record.
+ @param r Right record or name.
+ @param cr Comparison criteria (0=record/record, 1=record/name).
+ @return Comparison result.
+*/
+static
+int
+dk3uc2lat_pkg_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3_uc2lat_pkg_t const *pl; /* Left pointer. */
+ dk3_uc2lat_pkg_t const *pr; /* Right pointer. */
+
+ pl = (dk3_uc2lat_pkg_t const *)l;
+ pr = (dk3_uc2lat_pkg_t const *)r;
+ if(l) {
+ if(r) {
+ switch(cr) {
+ case 1: {
+ if(pl->name) {
+ back = dk3str_c8_cmp(pl->name, (char const *)r);
+ } else { back = -1; }
+ } break;
+ default: {
+ if(pl->name) {
+ if(pr->name) {
+ back = dk3str_c8_cmp(pl->name, pr->name);
+ } else { back = 1; }
+ } else {
+ if(pr->name) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ if(back < -1) { back = -1; }
+ if(back > 1) { back = 1; }
+ return back;
+}
+
+#endif
+
+
+
+/** Compare two range structures by start and end character.
+ @param l Left structure.
+ @param r Right structure/UC character.
+ @param cr Comparison criteria (0=struct/struct, 1=struct/char).
+ @return Comparison result.
+*/
+static
+int
+dk3uc2lat_range_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3_uc2lat_range_t const *pl; /* Left pointer. */
+ dk3_uc2lat_range_t const *pr; /* Right pointer. */
+ dk3_c32_t *ucptr; /* Right pointer is a character pointer. */
+
+ pl = (dk3_uc2lat_range_t const *)l;
+ pr = (dk3_uc2lat_range_t const *)r;
+ if(l) {
+ if(r) {
+ switch(cr) {
+ case 1: {
+ ucptr = (dk3_c32_t *)r;
+ if(pl->start > (*ucptr)) {
+ back = 1;
+ } else {
+ if(pl->end < (*ucptr)) {
+ back = -1;
+ }
+ }
+ } break;
+ default: {
+ if(pl->start > pr->end) {
+ back = 1;
+ } else {
+ if(pl->end < pr->start) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+/** Compare two UC to LaTeX directory structures.
+ @param l Left structure.
+ @param r Right structure/name.
+ @param cr Comparison criteria (0=struct/struct, 1=struct/name).
+ @return Comparison result.
+*/
+static
+int
+dk3uc2lat_dir_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3_uc2lat_dir_t const *pl; /* Left pointer. */
+ dk3_uc2lat_dir_t const *pr; /* Right pointer. */
+
+ pl = (dk3_uc2lat_dir_t const *)l;
+ pr = (dk3_uc2lat_dir_t const *)r;
+ if(l) {
+ if(r) {
+ switch(cr) {
+ case 1: {
+ if(pl->sn) {
+ back = dk3str_fncmp(pl->sn, (dkChar const *)r);
+ } else { back = -1; }
+ } break;
+ default: {
+ if(pl->sn) {
+ if(pr->sn) {
+ back = dk3str_fncmp(pl->sn, pr->sn);
+ } else { back = 1; }
+ } else {
+ if(pr->sn) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+void
+dk3uc2lat_close(dk3_uc2lat_t *u)
+{
+#if HAVE_PACKAGES
+ dk3_uc2lat_pkg_t *ppkg;
+#endif
+ dk3_uc2lat_dir_t *pdir;
+ dk3_uc2lat_range_t *pran;
+
+
+#line 551 "dk3uc2l.ctr"
+ if (NULL != u) {
+ u->app = NULL;
+ dk3_release(u->dir);
+ dk3_release(u->buf);
+ if (NULL != u->s_ran) {
+ if (NULL != u->i_ran) {
+ dk3sto_it_reset(u->i_ran);
+ do {
+ pran = (dk3_uc2lat_range_t *)dk3sto_it_next(u->i_ran);
+ if (NULL != pran) {
+ dk3uc2lat_range_delete(pran);
+ }
+ } while (NULL != pran);
+ dk3sto_it_close(u->i_ran);
+ }
+ dk3sto_close(u->s_ran);
+ }
+ u->s_ran = NULL; u->i_ran = NULL;
+ if (NULL != u->s_dir) {
+ if (NULL != u->i_dir) {
+ dk3sto_it_reset(u->i_dir);
+ do {
+ pdir = (dk3_uc2lat_dir_t *)dk3sto_it_next(u->i_dir);
+ if (NULL != pdir) {
+ dk3uc2lat_dir_delete(pdir);
+ }
+ } while (NULL != pdir);
+ dk3sto_it_close(u->i_dir);
+ }
+ dk3sto_close(u->s_dir);
+ }
+ u->s_dir = NULL; u->i_dir = NULL;
+#if HAVE_PACKAGES
+ if (NULL != u->s_pkg) {
+ if (NULL != u->i_pkg) {
+ dk3sto_it_reset(u->i_pkg);
+ do {
+ ppkg = (dk3_uc2lat_pkg_t *)dk3sto_it_next(u->i_pkg);
+ if (NULL != ppkg) {
+ dk3uc2lat_pkg_delete(ppkg);
+ }
+ } while (NULL != ppkg);
+ dk3sto_it_close(u->i_pkg);
+ }
+ dk3sto_close(u->s_pkg);
+ }
+ u->s_pkg = NULL; u->i_pkg = NULL;
+#endif
+ u->rca = NULL;
+ u->szbuf = 0;
+ u->f_dsc = 0;
+ u->f_utf8 = 0;
+ u->fe = 0;
+ dk3_delete(u);
+ }
+
+
+#line 607 "dk3uc2l.ctr"
+}
+
+
+
+#if HAVE_PACKAGES
+
+/** Create package structure, allocate memory.
+ @param pn Package name.
+ @param app Application structure for diagnostics.
+ @return Pointer to new structure on success, NULL on error.
+*/
+static
+dk3_uc2lat_pkg_t *
+dk3uc2lat_pkg_new(char const *pn, dk3_app_t *app)
+{
+ dk3_uc2lat_pkg_t *back = NULL;
+
+
+#line 624 "dk3uc2l.ctr"
+ back = dk3_new_app(dk3_uc2lat_pkg_t,1,app);
+ if(back) {
+ back->used = 0x00;
+ back->name = dk3str_c8_dup_app(pn,app);
+ if(!(back->name)) {
+ dk3uc2lat_pkg_delete(back);
+ back = NULL;
+ }
+ }
+
+#line 633 "dk3uc2l.ctr"
+ return back;
+}
+
+#endif
+
+
+/** Create range structure, allocate memory.
+ @param start Start character of range.
+ @param end End character of range.
+ @param dir Directory structure (parent of this range).
+ @param app Application structure for diagnostics.
+ @return Pointer to new range structure on success, NULL on error.
+*/
+static
+dk3_uc2lat_range_t *
+dk3uc2lat_range_new(
+ dk3_c32_t start, dk3_c32_t end, dk3_uc2lat_dir_t *dir, dk3_app_t *app
+)
+{
+ dk3_uc2lat_range_t *back = NULL;
+ char range_text[32]; /* Buffer for number range. */
+ dkChar dk_range_text[32]; /* Buffer for number range. */
+
+
+#line 656 "dk3uc2l.ctr"
+ if(dk3app_max_log_level(app) >= DK3_LL_DEBUG) {
+ sprintf(range_text, "%lx-%lx", (long)start, (long)end);
+ (void)dk3str_c8_to_str_simple_app(dk_range_text, 32, range_text, app);
+ dk3app_log_i3(app, DK3_LL_DEBUG, 238, 239, dk_range_text);
+ }
+ if(end >= start) {
+ back = dk3_new_app(dk3_uc2lat_range_t,1,app);
+ if(back) {
+ back->dir = dir;
+ back->dsc = NULL;
+ back->a = NULL;
+ back->t = NULL;
+ back->m = NULL;
+#if HAVE_PACKAGES
+ back->p = NULL;
+#endif
+ back->f = NULL;
+ back->start = start;
+ back->end = end;
+ back->ia = 0x00;
+ }
+ } else {
+ if(app) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 220);
+ }
+ }
+
+#line 682 "dk3uc2l.ctr"
+ return back;
+}
+
+
+
+/** Create UC to LaTeX directory structure, allocate memory.
+ @param sn Short directory file name.
+ @param app Application structure for diagnostics.
+ @return Pointer to new directory structure on success, NULL on error.
+*/
+static
+dk3_uc2lat_dir_t *
+dk3uc2lat_dir_new(dkChar const *sn, dk3_app_t *app)
+{
+ dk3_uc2lat_dir_t *back = NULL;
+
+
+#line 698 "dk3uc2l.ctr"
+ back = dk3_new_app(dk3_uc2lat_dir_t,1,app);
+ if(back) {
+ back->s_ran = NULL; back->i_ran = NULL; back->sn = NULL;
+ back->loaded = 0x00;
+ back->s_ran = dk3sto_open_app(app);
+ if(back->s_ran) {
+ dk3sto_set_comp(back->s_ran, dk3uc2lat_range_compare, 0);
+ back->i_ran = dk3sto_it_open(back->s_ran);
+ if(back->i_ran) {
+ back->sn = dk3str_dup_app(sn,app);
+ }
+ }
+ if(!((back->s_ran) && (back->i_ran) && (back->sn))) {
+ dk3uc2lat_dir_delete(back); back = NULL;
+ }
+ }
+
+#line 714 "dk3uc2l.ctr"
+ return back;
+}
+
+
+
+/** Create new LaTeX encoder.
+ @param dn Directory containing the data files.
+ @param f_utf8 Flag: Allowed to write UTF-8 output.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new encoder on success, NULL on error.
+*/
+static
+dk3_uc2lat_t *
+dk3uc2lat_t_new(
+ const dkChar *dn,
+ int f_utf8,
+ dk3_app_t *app
+)
+{
+ dk3_uc2lat_t *back = NULL;
+ int ok = 0;
+
+
+#line 736 "dk3uc2l.ctr"
+ back = dk3_new_app(dk3_uc2lat_t,1,app);
+ if (NULL != back) {
+ back->app = app;
+ back->dir = NULL;
+ back->buf = NULL;
+ back->s_ran = NULL;
+ back->i_ran = NULL;
+ back->s_dir = NULL;
+ back->i_dir = NULL;
+#if HAVE_PACKAGES
+ back->s_pkg = NULL;
+ back->i_pkg = NULL;
+#endif
+ back->rca = NULL;
+ back->szbuf = 0;
+ back->f_dsc = 0;
+ back->f_utf8 = f_utf8;
+ back->fe =
+ DK3_FONT_ENCODING_OT1 + DK3_FONT_ENCODING_T1
+ + DK3_FONT_ENCODING_T4 + DK3_FONT_ENCODING_T5;
+ back->dir = dk3str_dup_app(dn, app);
+ back->buf = dk3_new_app(char,16,app);
+ if (NULL != back->buf) { back->szbuf = 16; }
+ if ((NULL != back->dir) && (NULL != back->buf)) {
+ back->s_ran = dk3sto_open_app(app);
+ if (NULL != back->s_ran) {
+ dk3sto_set_comp(back->s_ran, dk3uc2lat_range_compare, 0);
+ back->s_dir = dk3sto_open_app(app);
+ if (NULL != back->s_dir) {
+ dk3sto_set_comp(back->s_dir, dk3uc2lat_dir_compare, 0);
+#if HAVE_PACKAGES
+ back->s_pkg = dk3sto_open_app(app);
+ if (NULL != back->s_pkg) {
+ dk3sto_set_comp(back->s_pkg, dk3uc2lat_pkg_compare, 0);
+#endif
+ back->i_ran = dk3sto_it_open(back->s_ran);
+ if (NULL != back->i_ran) {
+ back->i_dir = dk3sto_it_open(back->s_dir);
+ if (NULL != back->i_dir) {
+#if HAVE_PACKAGES
+ back->i_pkg = dk3sto_it_open(back->s_pkg);
+ if (NULL != back->i_pkg) {
+#endif
+ ok = 1;
+#if HAVE_PACKAGES
+ }
+#endif
+ }
+ }
+#if HAVE_PACKAGES
+ }
+#endif
+ }
+ }
+ }
+ if (0 == ok) {
+ dk3uc2lat_close(back);
+ back = NULL;
+ }
+ }
+
+#line 796 "dk3uc2l.ctr"
+ return back;
+}
+
+
+
+/** Check the file name whether it contains LaTeX conversion data
+ and can be processed.
+ @param fn File name to check.
+ @return 1 if yes, 0 otherwise.
+*/
+static
+int
+dk3uc2lat_is_suitable_file(const dkChar *fn)
+{
+ const dkChar * const *ptr; /* Traverse allowed suffixes array */
+ size_t szfn = 0; /* File name size */
+ size_t szsu = 0; /* Allowed suffix size */
+ int back = 0;
+
+
+#line 815 "dk3uc2l.ctr"
+ szfn = dk3str_len(fn);
+ ptr = dk3uc2l_suffixes;
+ while ((NULL != *ptr) && (0 == back)) {
+ szsu = dk3str_len(*ptr);
+ if (szfn > szsu) {
+ if (0 == dk3str_fncmp(&(fn[szfn - szsu]), *ptr)) {
+ back = 1;
+ }
+ }
+ ptr++;
+ }
+
+#line 826 "dk3uc2l.ctr"
+ return back;
+}
+
+
+
+/** Add one character to the range descriptions of a file directory.
+ @param uptr Conversion structure to set up.
+ @param pdir File directory to set up.
+ @param chr Character to add.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3uc2l_add_char_to_dir(
+ dk3_uc2lat_t *uptr,
+ dk3_uc2lat_dir_t *pdir,
+ dk3_c32_t chr,
+ dk3_app_t *app
+)
+{
+ dkChar cbuf[64];
+ dk3_uc2lat_range_t *prange;
+ dk3_uc2lat_range_t *pr2;
+ size_t szcbuf = DK3_SIZEOF(cbuf,dkChar);
+ dk3_c32_t tchr;
+ int back = 0;
+
+
+#line 854 "dk3uc2l.ctr"
+ prange = dk3sto_it_find_like(uptr->i_ran, &chr, 1);
+ if (NULL == prange) {
+ prange = dk3sto_it_find_like(pdir->i_ran, &chr, 1);
+ if (NULL == prange) {
+ if ((dk3_c32_t)0UL < chr) {
+
+#line 859 "dk3uc2l.ctr"
+ tchr = chr - 1;
+ prange = dk3sto_it_find_like(pdir->i_ran, &tchr, 1);
+ if (NULL != prange) {
+
+#line 862 "dk3uc2l.ctr"
+ prange->end = chr;
+ back = 1;
+
+#line 864 "dk3uc2l.ctr"
+ if (0xFFFFFFFFUL > (unsigned long)chr) {
+ tchr = chr + (dk3_c32_t)1UL;
+ pr2 = dk3sto_it_find_like(pdir->i_ran, &tchr, 1);
+ if (NULL != pr2) {
+
+#line 868 "dk3uc2l.ctr"
+ tchr = pr2->end;
+ dk3sto_remove(pdir->s_ran, pr2);
+ dk3uc2lat_range_delete(pr2);
+ prange->end = tchr;
+
+
+#line 873 "dk3uc2l.ctr"
+ }
+ }
+ }
+ }
+ if (0 == back) {
+
+#line 878 "dk3uc2l.ctr"
+ if (0xFFFFFFFFUL > (unsigned long)chr) {
+
+#line 879 "dk3uc2l.ctr"
+ tchr = chr + (dk3_c32_t)1UL;
+ prange = dk3sto_it_find_like(pdir->i_ran, &tchr, 1);
+ if (NULL != prange) {
+
+#line 882 "dk3uc2l.ctr"
+ prange->start = chr;
+ back = 1;
+
+#line 884 "dk3uc2l.ctr"
+ }
+ }
+ }
+ if (0 == back) {
+
+#line 888 "dk3uc2l.ctr"
+ prange = dk3uc2lat_range_new(chr, chr, pdir, app);
+ if (NULL != prange) {
+ if (dk3sto_add(pdir->s_ran, prange)) {
+ back = 1;
+
+#line 892 "dk3uc2l.ctr"
+ } else {
+ dk3uc2lat_range_delete(prange);
+ }
+ }
+ }
+ } else {
+
+#line 898 "dk3uc2l.ctr"
+ /* ERROR: Already found! */
+ if (0 != dk3ma_um_to_hex_string(cbuf, szcbuf, (dk3_um_t)chr, 8)) {
+ dk3app_log_i3(uptr->app, DK3_LL_ERROR, 395, 396, cbuf);
+ } else {
+ dk3app_log_i1(uptr->app, DK3_LL_ERROR, 397);
+ }
+ }
+ } else {
+
+#line 906 "dk3uc2l.ctr"
+ /* ERROR: Already found ! */
+ if (0 != dk3ma_um_to_hex_string(cbuf, szcbuf, (dk3_um_t)chr, 8)) {
+ dk3app_log_i3(uptr->app, DK3_LL_ERROR, 395, 396, cbuf);
+ } else {
+ dk3app_log_i1(uptr->app, DK3_LL_ERROR, 397);
+ }
+ }
+
+#line 913 "dk3uc2l.ctr"
+ return back;
+}
+
+
+
+/** Apply data from stream to directory information for one file.
+ @param uptr Conversion structure to set up.
+ @param pdir File directory entry to configure.
+ @param istrm Input stream for file (normal or compressed).
+ @param fn Full path name.
+ @param sn Short file name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3uc2l_apply_1(
+ dk3_uc2lat_t *uptr,
+ dk3_uc2lat_dir_t *pdir,
+ dk3_stream_t *istrm,
+ const dkChar *fn,
+ const dkChar *sn,
+ dk3_app_t *app
+)
+{
+ char buf[512];
+ char *p1;
+ char *p2;
+ dk3_uc2lat_range_t *prange;
+ unsigned long lineno = 0UL;
+ unsigned long chr;
+ int back = 1;
+
+
+#line 946 "dk3uc2l.ctr"
+ while ((1 == back) && (1 == dk3stream_c8_fgets(istrm, buf, sizeof(buf)))) {
+ dk3app_set_source_line(app, ++lineno);
+ buf[sizeof(buf) - 1] = '\0';
+
+
+#line 950 "dk3uc2l.ctr"
+ p1 = dk3str_c8_start(buf, NULL);
+ if (NULL != p1) {
+ if ('#' != *p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ if (NULL != p2) {
+ if (0 != dk3ma_ul_from_c8_hex_string(&chr, p1, NULL)) {
+ if (0 == dk3uc2l_add_char_to_dir(uptr, pdir, chr, app)) {
+ back = 0;
+
+#line 958 "dk3uc2l.ctr"
+ }
+ } else {
+ /* ERROR: Syntax error, not a hexadecimal number */
+ dk3app_log_i1(uptr->app, DK3_LL_ERROR, 398);
+ }
+ } else {
+ /* ERROR: Syntax error, missing configuration */
+ dk3app_log_i1(uptr->app, DK3_LL_ERROR, 400);
+ }
+ }
+ }
+ }
+ if (1 == back) {
+
+#line 971 "dk3uc2l.ctr"
+ dk3sto_it_reset(pdir->i_ran);
+ do {
+ prange = dk3sto_it_next(pdir->i_ran);
+ if (NULL != prange) {
+
+#line 975 "dk3uc2l.ctr"
+ if (0 == dk3sto_add(uptr->s_ran, prange)) {
+ dk3uc2lat_range_delete(prange);
+ back = 0;
+
+#line 978 "dk3uc2l.ctr"
+ }
+ }
+ } while (NULL != prange);
+ } else {
+
+#line 982 "dk3uc2l.ctr"
+ dk3sto_it_reset(pdir->i_ran);
+ do {
+ prange = dk3sto_it_next(pdir->i_ran);
+ if (NULL != prange) {
+ dk3uc2lat_range_delete(prange);
+ }
+ } while (NULL != prange);
+ }
+
+#line 990 "dk3uc2l.ctr"
+ return back;
+}
+
+
+
+/** Apply directory information for a file.
+ @param uptr Conversion structure to set up.
+ @param fn File name containing conversion data.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3uc2lat_pass_1(
+ dk3_uc2lat_t *uptr, const dkChar *fn, const dkChar *sn, dk3_app_t *app
+)
+{
+ dk3_uc2lat_dir_t *pdir = NULL;
+ dk3_stream_t *istrm = NULL;
+ FILE *fipo = NULL;
+ const dkChar *oldsrc = NULL;
+ const dkChar *fsuf = NULL;
+#if DK3_HAVE_ZLIB_H && (DK3_CHAR_SIZE == 1)
+ gzFile gzf = NULL;
+#endif
+#if DK3_HAVE_BZLIB_H && (DK3_CHAR_SIZE == 1)
+ BZFILE *bzf = NULL;
+#endif
+ unsigned long oldln = 0UL;
+#if DK3_HAVE_FNCASEINS
+ int fncs = 0;
+#else
+ int fncs = 1;
+#endif
+ int back = 0;
+
+
+#line 1026 "dk3uc2l.ctr"
+ pdir = dk3uc2lat_dir_new(sn, app);
+ if (NULL != pdir) {
+ oldsrc = dk3app_get_source_file(app);
+ oldln = dk3app_get_source_line(app);
+ dk3app_set_source_file(app, fn);
+ dk3app_set_source_line(app, 0UL);
+ if (0 != dk3sto_add(uptr->s_dir, pdir)) {
+ fsuf = dk3str_get_suffix(fn);
+ switch (dk3str_array_index(dk3uc2l_co_suf, fsuf, fncs)) {
+ case 0: { /* gz */
+#if DK3_HAVE_ZLIB_H && (DK3_CHAR_SIZE == 1)
+ gzf = gzopen(fn, "r");
+ if (NULL != gzf) {
+ istrm = dk3stream_open_gz_app(gzf, DK3_STREAM_FLAG_READ, app);
+ if (NULL != istrm) {
+ back = dk3uc2l_apply_1(uptr, pdir, istrm, fn, sn, app);
+ (void)dk3stream_close(istrm);
+ }
+ gzclose(gzf);
+ } else {
+ /* ERROR: Failed to open file */
+ dk3app_log_i3(uptr->app, DK3_LL_ERROR, 143, 144, fn);
+ }
+#else
+ /* ERROR: No zlib support */
+ dk3app_log_i1(uptr->app, DK3_LL_ERROR, 401);
+#endif
+ } break;
+ case 1: { /* bz2 */
+#if DK3_HAVE_BZLIB_H && (DK3_CHAR_SIZE == 1)
+ bzf = BZ2_bzopen(fn, "r");
+ if (NULL != bzf) {
+ istrm = dk3stream_open_bz2_app(bzf, DK3_STREAM_FLAG_READ, app);
+ if (NULL != istrm) {
+ back = dk3uc2l_apply_1(uptr, pdir, istrm, fn, sn, app);
+ (void)dk3stream_close(istrm);
+ }
+ BZ2_bzclose(bzf);
+ } else {
+ /* ERROR: Failed to open file */
+ dk3app_log_i3(uptr->app, DK3_LL_ERROR, 143, 144, fn);
+ }
+#else
+ /* ERROR: No bzip2 support */
+ dk3app_log_i1(uptr->app, DK3_LL_ERROR, 402);
+#endif
+ } break;
+ default : { /* normal file */
+ fipo = dk3sf_fopen_app(fn, dkT("r"), app);
+ if (NULL != fipo) {
+ istrm = dk3stream_open_file_app(fipo, DK3_STREAM_FLAG_READ, app);
+ if (NULL != istrm) {
+ back = dk3uc2l_apply_1(uptr, pdir, istrm, fn, sn, app);
+ (void)dk3stream_close(istrm);
+ }
+ fclose(fipo);
+ }
+ } break;
+ }
+ } else {
+ dk3uc2lat_dir_delete(pdir);
+ }
+ dk3app_set_source_file(app, oldsrc);
+ dk3app_set_source_line(app, oldln);
+ }
+
+#line 1091 "dk3uc2l.ctr"
+ return back;
+}
+
+
+
+/** Read directory information (check existing data files, retrieve ranges.
+ @param d Directory containing the data files.
+ @param uptr Conversion structure to initialize.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3uc2lat_read_dir_info(dk3_uc2lat_t *uptr, dk3_app_t *app)
+{
+ dk3_dir_t *dir = NULL;
+ const dkChar *fn = NULL;
+ const dkChar *sn = NULL;
+ int back = 0;
+ int found = 0;
+
+
+#line 1112 "dk3uc2l.ctr"
+ dir = dk3dir_open_app(uptr->dir, uptr->app);
+ if (NULL != dir) {
+ back = 1;
+ while (0 != dk3dir_get_next_file(dir)) {
+ sn = dk3dir_get_shortname(dir);
+ fn = dk3dir_get_fullname(dir);
+ if ((NULL != sn) && (NULL != fn)) {
+ if (0 != dk3uc2lat_is_suitable_file(fn)) {
+ found = 1;
+ if (0 == dk3uc2lat_pass_1(uptr, fn, sn, app)) {
+ back = 0;
+ }
+ }
+ }
+ }
+ dk3dir_close(dir);
+ if (0 == found) {
+ back = 0;
+ /* ERROR: No suitable files found */
+ dk3app_log_i1(uptr->app, DK3_LL_ERROR, 403);
+ }
+ }
+
+
+#line 1135 "dk3uc2l.ctr"
+ return back;
+}
+
+
+
+/** Allocate memory for all ranges details for a file directory.
+ @param uptr Conversion structure to set up.
+ @param pdir Directory information to set up.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3uc2l_allocate_memory(
+ dk3_uc2lat_t *uptr,
+ dk3_uc2lat_dir_t *pdir
+)
+{
+ dk3_uc2lat_range_t *prange;
+ size_t sz;
+ size_t i;
+ int back = 1;
+ int allenc = 0;
+
+ dk3sto_it_reset(pdir->i_ran);
+ allenc = DK3_FONT_ENCODING_OT1
+ + DK3_FONT_ENCODING_T1
+ + DK3_FONT_ENCODING_T4
+ + DK3_FONT_ENCODING_T5;
+ do {
+ prange = (dk3_uc2lat_range_t *)dk3sto_it_next(pdir->i_ran);
+ if (NULL != prange) {
+ sz = (size_t)(prange->end - prange->start) + 1;
+ if (NULL == prange->a) {
+ prange->a = dk3_new_app(DK3_PCCHAR,sz,uptr->app);
+ if (NULL != prange->a) {
+ for (i = 0; i < sz; i++) { (prange->a)[i] = NULL; }
+ } else {
+ back = 0;
+ }
+ }
+ if (NULL == prange->t) {
+ prange->t = dk3_new_app(DK3_PCCHAR,sz,uptr->app);
+ if (NULL != prange->t) {
+ for (i = 0; i < sz; i++) { (prange->t)[i] = NULL; }
+ } else {
+ back = 0;
+ }
+ }
+ if (NULL == prange->m) {
+ prange->m = dk3_new_app(DK3_PCCHAR,sz,uptr->app);
+ if (NULL != prange->m) {
+ for (i = 0; i < sz; i++) { (prange->m)[i] = NULL; }
+ } else {
+ back = 0;
+ }
+ }
+#if HAVE_PACKAGES
+ if (NULL == prange->p) {
+ prange->p = dk3_new_app(dk3_uc2lat_pkg_pptr,sz,uptr->app);
+ if (NULL != prange->p) {
+ for (i = 0; i < sz; i++) { (prange->p)[i] = NULL; }
+ } else {
+ back = 0;
+ }
+ }
+#endif
+ if (NULL == prange->f) {
+ prange->f = dk3_new_app(dk3_font_encoding_t,sz,uptr->app);
+ if (NULL != prange->f) {
+ for(i = 0; i < sz; i++) { (prange->f)[i] = allenc; }
+ } else {
+ back = 0;
+ }
+ }
+ }
+ } while (NULL != prange);
+ return back;
+}
+
+
+
+static
+void
+dk3uc2l_apply_2(
+ dk3_uc2lat_t *uptr,
+ dk3_uc2lat_dir_t *pdir,
+ dk3_stream_t *istrm,
+ const dkChar *filename
+)
+{
+ char buf[512]; /* Input line buffer */
+#if HAVE_PACKAGES
+ char *parts[16]; /* Package names */
+#endif
+ char *p1; /* Hex value or next item */
+ char *p2; /* Current item key */
+ char *p3; /* Current item value */
+ char *p4; /* Dynamic value copy */
+ dk3_uc2lat_range_t *prange; /* Current range */
+#if HAVE_PACKAGES
+ dk3_uc2lat_pkg_t *ppkg; /* Current package */
+#endif
+ unsigned long lineno = 0UL; /* Current line number */
+ unsigned long chr; /* Current character */
+ size_t ind; /* Index of chr in range */
+#if HAVE_PACKAGES
+ size_t nparts; /* Number of packages */
+ size_t i; /* Traverse */
+ size_t j; /* Add new packages */
+#endif
+ int cc = 1; /* Flag: Can continue */
+ int action; /* Action to take */
+ int isneg; /* Flag: Deny encodings */
+ int encod; /* Encodings selection */
+
+
+#line 1250 "dk3uc2l.ctr"
+ while ((1 == cc) && (1 == dk3stream_c8_fgets(istrm, buf, sizeof(buf)))) {
+ dk3app_set_source_line(uptr->app, ++lineno);
+ buf[sizeof(buf) - 1] = '\0';
+
+
+#line 1254 "dk3uc2l.ctr"
+ p1 = dk3str_c8_start(buf, NULL);
+ if (NULL != p1) {
+
+#line 1256 "dk3uc2l.ctr"
+ if ('#' != *p1) {
+
+#line 1257 "dk3uc2l.ctr"
+ p2 = dk3str_c8_next(p1, NULL);
+ if (NULL != p2) {
+
+#line 1259 "dk3uc2l.ctr"
+ if (0 != dk3ma_ul_from_c8_hex_string(&chr, p1, NULL)) {
+ prange =
+ (dk3_uc2lat_range_t *)dk3sto_it_find_like(pdir->i_ran, &chr, 1);
+ if (NULL != prange) {
+
+#line 1263 "dk3uc2l.ctr"
+ ind = (size_t)(chr - prange->start);
+ while (NULL != p2) {
+ p1 = dk3str_c8_next(p2, NULL);
+ p3 = dk3str_c8_chr(p2, '=');
+ if (NULL != p3) {
+ *(p3++) = '\0';
+#if 0
+ /* 2015-08-10 Bugfix: Must be start */
+ p3 = dk3str_c8_next(p3, NULL);
+#endif
+ p3 = dk3str_c8_start(p3, NULL);
+ if (NULL != p3) {
+
+#line 1275 "dk3uc2l.ctr"
+ action = dk3str_c8_array_abbr(dk3uc2l_kw, p2, '$', 0);
+
+
+#line 1277 "dk3uc2l.ctr"
+ switch (action) {
+ case 0: { /* both */
+
+#line 1279 "dk3uc2l.ctr"
+ if (NULL != prange->a) {
+ p4 = dk3str_c8_dup_app(p3, uptr->app);
+ if (NULL != p4) {
+ dk3_release((prange->a)[ind]);
+ (prange->a)[ind] = p4;
+ }
+ }
+ } break;
+ case 1: { /* text */
+
+#line 1288 "dk3uc2l.ctr"
+ if (NULL != prange->t) {
+ p4 = dk3str_c8_dup_app(p3, uptr->app);
+ if (NULL != p4) {
+ dk3_release((prange->t)[ind]);
+ (prange->t)[ind] = p4;
+ }
+ }
+ } break;
+ case 2: { /* math */
+
+#line 1297 "dk3uc2l.ctr"
+ if (NULL != prange->m) {
+ p4 = dk3str_c8_dup_app(p3, uptr->app);
+ if (NULL != p4) {
+ dk3_release((prange->m)[ind]);
+ (prange->m)[ind] = p4;
+ }
+ }
+ } break;
+ case 3: { /* encoding */
+
+#line 1306 "dk3uc2l.ctr"
+ if (NULL != prange->f) {
+ isneg = 0; encod = 0;
+ if ('!' == *p3) {
+ isneg = 1; p3++;
+ }
+ while (NULL != p3) {
+ p4 = dk3str_c8_chr(p3, ',');
+ if (NULL != p4) {
+ *(p4++) = '\0';
+ p4 = dk3str_c8_start(p4, NULL);
+ }
+ switch (dk3str_c8_array_index(dk3uc2l_enco, p3, 0))
+ {
+ case 0: { /* OT1 */
+ encod |= DK3_FONT_ENCODING_OT1;
+ } break;
+ case 1: { /* T1 */
+ encod |= DK3_FONT_ENCODING_T1;
+ } break;
+ case 2: { /* T4 */
+ encod |= DK3_FONT_ENCODING_T4;
+ } break;
+ case 3: { /* T5 */
+ encod |= DK3_FONT_ENCODING_T5;
+ } break;
+ default : {
+ /* Syntax error, unknown encoding */
+ dk3app_log_i1(uptr->app, DK3_LL_DEBUG, 404);
+ } break;
+ }
+ p3 = p4;
+ }
+ if (0 != isneg) { encod = (~(encod)); }
+ (prange->f)[ind] = encod;
+ }
+ } break;
+ case 4: { /* packages */
+
+#line 1343 "dk3uc2l.ctr"
+#if HAVE_PACKAGES
+ if (NULL != prange->p) {
+ nparts = dk3str_c8_explode(parts, 15, p3, ",");
+ if (0 < nparts) {
+ dk3_release((prange->p)[ind]);
+ (prange->p)[ind] =
+ dk3_new_app(dk3_uc2lat_pkg_ptr,(nparts+1),uptr->app);
+ if (NULL != (prange->p)[ind]) {
+ for (i = 0; i < (nparts+1); i++) {
+ ((prange->p)[ind])[i] = NULL;
+ }
+ j = 0;
+ for (i = 0; i < nparts; i++) {
+ ppkg = (dk3_uc2lat_pkg_t *)dk3sto_it_find_like(
+ uptr->i_pkg, parts[i], 1
+ );
+ if (NULL != ppkg) {
+ ((prange->p)[ind])[j++] = ppkg;
+ } else {
+ ppkg = dk3uc2lat_pkg_new(parts[i], uptr->app);
+ if (NULL != ppkg) {
+ if (dk3sto_add(uptr->s_pkg, ppkg)) {
+ ((prange->p)[ind])[j++] = ppkg;
+ } else {
+ dk3uc2lat_pkg_delete(ppkg);
+ }
+ }
+ }
+ }
+ }
+ } else {
+ /* ERROR: Syntax, no packages */
+ dk3app_log_i1(uptr->app, DK3_LL_DEBUG, 405);
+ }
+ }
+#endif
+ } break;
+ default: {
+
+#line 1381 "dk3uc2l.ctr"
+ } break;
+ }
+ } else {
+
+#line 1384 "dk3uc2l.ctr"
+ /* ERROR: Value missing */
+ dk3app_log_i1(uptr->app, DK3_LL_DEBUG, 406);
+ }
+ } else {
+
+#line 1388 "dk3uc2l.ctr"
+ /* ERROR: Syntax, not a key value pair */
+ dk3app_log_i1(uptr->app, DK3_LL_DEBUG, 406);
+ }
+ p2 = p1;
+ }
+ } else {
+
+#line 1394 "dk3uc2l.ctr"
+ /* BUG or file changed */
+ }
+ } else {
+ /* ERROR: Syntax error, not a hexadecimal number */
+ dk3app_log_i1(uptr->app, DK3_LL_ERROR, 398);
+ }
+ } else {
+
+#line 1401 "dk3uc2l.ctr"
+ /* ERROR: Syntax error, missing configuration */
+ dk3app_log_i1(uptr->app, DK3_LL_ERROR, 401);
+ }
+ } else {
+
+#line 1405 "dk3uc2l.ctr"
+ }
+ } else {
+
+#line 1407 "dk3uc2l.ctr"
+ }
+ }
+
+#line 1409 "dk3uc2l.ctr"
+}
+
+
+
+static
+void
+dk3uc2lat_load_file(dk3_uc2lat_t *u, dk3_uc2lat_dir_t *pdir)
+{
+ dkChar fnb[DK3_MAX_PATH];
+ dk3_stream_t *istrm = NULL;
+ FILE *fipo = NULL;
+ const dkChar *oldsrc = NULL;
+ const dkChar *fsuf = NULL;
+#if DK3_HAVE_ZLIB_H && (DK3_CHAR_SIZE == 1)
+ gzFile gzf = NULL;
+#endif
+#if DK3_HAVE_BZLIB_H && (DK3_CHAR_SIZE == 1)
+ BZFILE *bzf = NULL;
+#endif
+ unsigned long oldln = 0UL;
+#if DK3_HAVE_FNCASEINS
+ int fncs = 0;
+#else
+ int fncs = 1;
+#endif
+ size_t sz;
+
+
+#line 1436 "dk3uc2l.ctr"
+ sz = dk3str_len(u->dir);
+ sz += dk3str_len(pdir->sn);
+ sz += 1;
+ if (sizeof(fnb) > sz) {
+
+#line 1440 "dk3uc2l.ctr"
+ dk3str_cpy(fnb, u->dir);
+ dk3str_cat(fnb, dk3app_not_localized(20));
+ dk3str_cat(fnb, pdir->sn);
+ dk3str_correct_filename(fnb);
+ oldsrc = dk3app_get_source_file(u->app);
+ oldln = dk3app_get_source_line(u->app);
+ dk3app_set_source_file(u->app, fnb);
+ dk3app_set_source_line(u->app, 0UL);
+ if (0 != dk3uc2l_allocate_memory(u, pdir)) {
+
+#line 1449 "dk3uc2l.ctr"
+ fsuf = dk3str_get_suffix(fnb);
+ switch (dk3str_array_index(dk3uc2l_co_suf, fsuf, fncs)) {
+ case 0: {
+
+#line 1452 "dk3uc2l.ctr"
+#if DK3_HAVE_ZLIB_H && (DK3_CHAR_SIZE == 1)
+ gzf = gzopen(fnb, "r");
+ if (NULL != gzf) {
+ istrm = dk3stream_open_gz_app(gzf, DK3_STREAM_FLAG_READ, u->app);
+ if (NULL != istrm) {
+ dk3uc2l_apply_2(u, pdir, istrm, fnb);
+ (void)dk3stream_close(istrm);
+ }
+ gzclose(gzf);
+ } else {
+ /* ERROR: Failed to open file */
+ dk3app_log_i3(u->app, DK3_LL_ERROR, 143, 144, fnb);
+ }
+#else
+ /* ERROR: No zlib support */
+ dk3app_log_i1(u->app, DK3_LL_ERROR, 401);
+#endif
+ } break;
+ case 1: {
+
+#line 1471 "dk3uc2l.ctr"
+#if DK3_HAVE_BZLIB_H && (DK3_CHAR_SIZE == 1)
+ bzf = BZ2_bzopen(fnb, "r");
+ if (NULL != bzf) {
+ istrm = dk3stream_open_bz2_app(bzf, DK3_STREAM_FLAG_READ, u->app);
+ if (NULL != istrm) {
+ dk3uc2l_apply_2(u, pdir, istrm, fnb);
+ (void)dk3stream_close(istrm);
+ }
+ BZ2_bzclose(bzf);
+ } else {
+ /* ERROR: Failed to open file */
+ dk3app_log_i3(u->app, DK3_LL_ERROR, 143, 144, fnb);
+ }
+#else
+ /* ERROR: No bzip2 support */
+ dk3app_log_i1(u->app, DK3_LL_ERROR, 402);
+#endif
+ } break;
+ default: {
+
+#line 1490 "dk3uc2l.ctr"
+ fipo = dk3sf_fopen_app(fnb, dkT("r"), u->app);
+ if (NULL != fipo) {
+ istrm = dk3stream_open_file_app(fipo, DK3_STREAM_FLAG_READ, u->app);
+ if (NULL != istrm) {
+ dk3uc2l_apply_2(u, pdir, istrm, fnb);
+ (void)dk3stream_close(istrm);
+ }
+ fclose(fipo);
+ }
+ } break;
+ }
+ } else {
+
+#line 1502 "dk3uc2l.ctr"
+ }
+ dk3app_set_source_file(u->app, oldsrc);
+ dk3app_set_source_line(u->app, oldln);
+ } else {
+
+#line 1506 "dk3uc2l.ctr"
+ /* ERROR: Name too long */
+ dk3app_log_i3(u->app, DK3_LL_ERROR, 65, 66, pdir->sn);
+ }
+ pdir->loaded = 0x01;
+
+
+#line 1511 "dk3uc2l.ctr"
+}
+
+
+
+/** Open conversion structure for a given directory.
+ @param d Directory containing conversion files.
+ @param f_desc Flag: Load glyph descriptions (ignored).
+ @param f_utf8 Flag: UTF-8 output allowed.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new structure on success, NULL on error.
+*/
+static
+dk3_uc2lat_t *
+dk3uc2lat_i_open_app(const dkChar *d, int f_desc, int f_utf8, dk3_app_t *app)
+{
+ dk3_uc2lat_t *back = NULL;
+
+
+#line 1528 "dk3uc2l.ctr"
+ if (0 != dk3sf_is_dir_app(d, NULL)) {
+ back = dk3uc2lat_t_new(d, f_utf8, app);
+ if (NULL != back) {
+ if (0 == dk3uc2lat_read_dir_info(back, app)) {
+ dk3uc2lat_close(back);
+ back = NULL;
+ }
+ }
+ } else {
+ /* ERROR: Not a directory ... */
+ dk3app_log_i3(app, DK3_LL_ERROR, 202, 203, d);
+ }
+
+
+#line 1541 "dk3uc2l.ctr"
+ return back;
+}
+
+
+
+dk3_uc2lat_t *
+dk3uc2lat_open_app(dkChar const *d, int f_desc, int f_utf8, dk3_app_t *app)
+{
+ dkChar fnb[DK3_MAX_PATH];
+ dk3_uc2lat_t *back = NULL;
+ const dkChar *shd = NULL;
+ const dkChar *dirn = NULL;
+ size_t szfnb = DK3_SIZEOF(fnb,dkChar);
+ size_t szshd = 0;
+
+
+#line 1556 "dk3uc2l.ctr"
+ if (NULL != d) {
+ back = dk3uc2lat_i_open_app(d, f_desc, f_utf8, app);
+ } else {
+ if (NULL != app) {
+ if (dk3app_get_dir_from_pref(app,dk3app_not_localized(48),fnb,szfnb,1))
+ {
+ dk3str_correct_filename(fnb);
+ back = dk3uc2lat_i_open_app(fnb, f_desc, f_utf8, app);
+ } else
+ {
+ shd = dk3app_get_sharedir(app);
+ if (NULL != shd) {
+ szshd = dk3str_len(shd);
+ if (szfnb > szshd) {
+ dk3str_cpy_not_overlapped(fnb, shd);
+ dirn = dk3app_not_localized(49);
+ if (szfnb > (szshd + dk3str_len(dirn))) {
+ dk3str_cat(fnb, dirn);
+ dk3str_correct_filename(fnb);
+ back = dk3uc2lat_i_open_app(fnb, f_desc, f_utf8, app);
+ } else {
+ /* ERROR: Directory name too long! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 64, 66, dirn);
+ }
+ } else {
+ /* ERROR: Share directory name too long! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 64, 66, shd);
+ }
+ } else {
+ /* ERROR: Missing share directory */
+ dk3app_log_i1(app, DK3_LL_ERROR, 407);
+ }
+ }
+ }
+ }
+
+#line 1591 "dk3uc2l.ctr"
+ return back;
+}
+
+
+
+char const *
+dk3uc2lat_get(dk3_uc2lat_t *u, dk3_c32_t c32, int ismath)
+{
+ dkChar cbuf[64];
+ dk3_uc2lat_range_t *prange = NULL;
+ dk3_uc2lat_pkg_t **pkgpp;
+ const char *back = NULL;
+ size_t szcbuf = DK3_SIZEOF(cbuf,dkChar);
+
+
+#line 1605 "dk3uc2l.ctr"
+ if (NULL != u) {
+ if (NULL != u->rca) {
+
+#line 1607 "dk3uc2l.ctr"
+ if ((u->rca)->start <= c32) {
+
+#line 1608 "dk3uc2l.ctr"
+ if ((u->rca)->end >= c32) {
+
+#line 1609 "dk3uc2l.ctr"
+ prange = u->rca;
+
+#line 1610 "dk3uc2l.ctr"
+ }
+ }
+ }
+ if (NULL == prange) {
+
+#line 1614 "dk3uc2l.ctr"
+ prange = dk3sto_it_find_like(u->i_ran, &c32, 1);
+ if (NULL != prange) {
+
+#line 1616 "dk3uc2l.ctr"
+ u->rca = prange;
+ if (NULL != prange->p) {
+
+#line 1618 "dk3uc2l.ctr"
+ pkgpp = (prange->p)[(size_t)(c32 - prange->start)];
+ if (NULL != pkgpp) {
+ while (NULL != *pkgpp) {
+ (*(pkgpp++))->used = 0x01;
+ }
+
+#line 1623 "dk3uc2l.ctr"
+ }
+ }
+ } else {
+
+#line 1626 "dk3uc2l.ctr"
+ }
+ }
+ if (NULL != prange) {
+
+#line 1629 "dk3uc2l.ctr"
+ if (NULL != prange->dir) {
+
+#line 1630 "dk3uc2l.ctr"
+ if (0x00 == (prange->dir)->loaded) {
+
+#line 1631 "dk3uc2l.ctr"
+ dk3uc2lat_load_file(u, prange->dir);
+ }
+ }
+ if (0 != ismath) {
+
+#line 1635 "dk3uc2l.ctr"
+ if (NULL != prange->m) {
+
+#line 1636 "dk3uc2l.ctr"
+ back = (prange->m)[(size_t)(c32 - prange->start)];
+ }
+ if (NULL == back) {
+ if (NULL != prange->a) {
+
+#line 1640 "dk3uc2l.ctr"
+ back = (prange->a)[(size_t)(c32 - prange->start)];
+ }
+ }
+ } else {
+
+#line 1644 "dk3uc2l.ctr"
+ if (NULL != prange->t) {
+
+#line 1645 "dk3uc2l.ctr"
+ back = (prange->t)[(size_t)(c32 - prange->start)];
+ }
+ if (NULL == back) {
+
+#line 1648 "dk3uc2l.ctr"
+ if (NULL != prange->a) {
+ back = (prange->a)[(size_t)(c32 - prange->start)];
+ }
+ }
+ }
+ if (NULL != prange->f) {
+ u->fe &= ((prange->f)[(size_t)(c32 - prange->start)]);
+ }
+ } else {
+ /* ERROR: Not found */
+ if (0 != dk3ma_um_to_hex_string(cbuf, szcbuf, (dk3_um_t)c32, 8)) {
+ dk3app_log_i3(u->app, DK3_LL_ERROR, 409, 410, cbuf);
+ } else {
+ dk3app_log_i1(u->app, DK3_LL_ERROR, 408);
+ }
+ }
+ }
+
+#line 1665 "dk3uc2l.ctr"
+ return back;
+}
+
+
+
+#if HAVE_PACKAGES
+
+void
+dk3uc2lat_package_reset(dk3_uc2lat_t *u)
+{
+ if (NULL != u) {
+ dk3sto_it_reset(u->i_pkg);
+ }
+}
+
+
+
+dk3_uc2lat_pkg_t *
+dk3uc2lat_package_next(dk3_uc2lat_t *u)
+{
+ dk3_uc2lat_pkg_t *back = NULL;
+ if (NULL != u) {
+ back = (dk3_uc2lat_pkg_t *)dk3sto_it_next(u->i_pkg);
+ }
+ return back;
+}
+
+#endif
+
+
+
+void
+dk3uc2lat_font_encoding_reset(dk3_uc2lat_t *u)
+{
+ /* UNUSED */
+}
+
+
+
+int
+dk3uc2lat_font_encoding_conflict(dk3_uc2lat_t *u)
+{
+ int back = 0;
+ /* UNUSED */
+ return back;
+}
+
+
+
+void
+dk3uc2lat_font_encoding_report_conflict(dk3_uc2lat_t *u)
+{
+ if (0x00 == u->fe) {
+ /* Error */
+ dk3app_log_i1(u->app, DK3_LL_ERROR, 411);
+ }
+}
+
+
+
+static
+void
+dk3uc2lat_report_for_encoding(dk3_uc2lat_t *u, const char *eptr)
+{
+#if DK3_CHAR_SIZE > 1
+ dkChar buffer[32];
+ dkChar *dkptr = NULL;
+ size_t szbu = DK3_SIZEOF(buffer,dkChar);
+ if (szbu > strlen(eptr)) {
+ dkptr = buffer;
+ while ('\0' != *eptr) {
+ *(dkptr++) = (dkChar)(*(eptr++));
+ }
+ *dkptr = dkT('\0');
+ dk3app_log_i3(u->app, DK3_LL_INFO, 381, 382, buffer);
+ }
+#else
+ dk3app_log_i3(u->app, DK3_LL_INFO, 381, 382, eptr);
+#endif
+}
+
+
+
+void
+dk3uc2lat_font_encoding_report(dk3_uc2lat_t *u)
+{
+ if (0 != ((u->fe) & DK3_FONT_ENCODING_OT1)) {
+ dk3uc2lat_report_for_encoding(u, dk3uc2l_enco[0]);
+ }
+ if (0 != ((u->fe) & DK3_FONT_ENCODING_T1)) {
+ dk3uc2lat_report_for_encoding(u, dk3uc2l_enco[1]);
+ }
+ if (0 != ((u->fe) & DK3_FONT_ENCODING_T4)) {
+ dk3uc2lat_report_for_encoding(u, dk3uc2l_enco[2]);
+ }
+ if (0 != ((u->fe) & DK3_FONT_ENCODING_T5)) {
+ dk3uc2lat_report_for_encoding(u, dk3uc2l_enco[3]);
+ }
+}
+
+
+
+int
+dk3uc2lat_direct(dk3_c32_t c32)
+{
+ int back = 0;
+ char c; /* 8-bit character version of c32. */
+
+
+#line 1773 "dk3uc2l.ctr"
+ if((unsigned long)c32 < 128UL) {
+ c = (char)c32;
+ switch(c) {
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
+ case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
+ case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u':
+ case 'v': case 'w': case 'x': case 'y': case 'z': case 'A': case 'B':
+ case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I':
+ case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P':
+ case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W':
+ case 'X': case 'Y': case 'Z': case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7': case '8': case '9': case ',':
+ case '.': case ':': case ';': case '+': case '-': case '?': case '!':
+ case '|': case '@': case '(': case ')': case '/': case '=': case ' ':
+ case '\t':
+ {
+ back = 1;
+ }
+ break;
+ }
+ }
+
+#line 1794 "dk3uc2l.ctr"
+ return back;
+}
+
+
+
+static
+int
+dk3uc2lat_stputc(dk3_uc2lat_t *u, dk3_stream_t *st, dk3_c32_t ul, int *mmptr)
+{
+ char buf[16];
+ const char *ptr;
+ size_t sz;
+ int back = 0;
+
+ if (0 != dk3uc2lat_direct(ul)) {
+ if (0 != *mmptr) {
+ dk3stream_c8_fputs(st, dk3uc2lat_mm[1]);
+ *mmptr = 0;
+ }
+ if (u->f_utf8) {
+ sz = dk3enc_uc2utf8(ul, (unsigned char *)buf, sizeof(buf));
+ buf[sz] = '\0';
+ } else {
+ buf[0] = (char)ul;
+ buf[1] = '\0';
+ }
+ dk3stream_c8_fputs(st, buf);
+ back = 1;
+ } else {
+ ptr = dk3uc2lat_get(u, ul, 0);
+ if (NULL != ptr) {
+ if (0 != *mmptr) {
+ dk3stream_c8_fputs(st, dk3uc2lat_mm[1]);
+ *mmptr = 0;
+ }
+ dk3stream_c8_fputs(st, ptr);
+ } else {
+ ptr = dk3uc2lat_get(u, ul, 1);
+ if (NULL != ptr) {
+ if (0 == *mmptr) {
+ dk3stream_c8_fputs(st, dk3uc2lat_mm[0]);
+ *mmptr = 1;
+ }
+ dk3stream_c8_fputs(st, ptr);
+ } else {
+ /* ERROR: Not found, already reported */
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3uc2lat_c8_plain_stputs(dk3_uc2lat_t *u, dk3_stream_t *st, char const *t)
+{
+ int back = 0;
+ int mm = 0; /* Flag: In math mode. */
+ char const *ptr; /* Current position. */
+ dk3_c32_t ul; /* Output character. */
+ char c; /* Current character. */
+
+
+#line 1857 "dk3uc2l.ctr"
+ if((u) && (st) && (t)) {
+ ptr = t; back = 1;
+ while(*ptr) {
+ c = *ptr;
+ ul = (unsigned long)c;
+ ul &= 0x000000FFUL;
+ if(!dk3uc2lat_stputc(u, st, ul, &mm)) { back = 0; }
+ ptr++;
+ }
+ if(mm) {
+ dk3stream_c8_fputs(st, dk3uc2lat_mm[1]);
+ }
+ }
+
+
+#line 1871 "dk3uc2l.ctr"
+ return back;
+}
+
+
+
+int
+dk3uc2lat_c8_utf8_stputs(dk3_uc2lat_t *u, dk3_stream_t *st, char const *t)
+{
+ int back = 0;
+ int mm = 0; /* Flag: Math mode. */
+ unsigned char const *sp; /* String pointer, current pos. */
+ size_t sl; /* Remaining bytes. */
+ size_t used; /* Bytes used for current c32. */
+ dk3_c32_t c32; /* Current character. */
+
+
+#line 1886 "dk3uc2l.ctr"
+ if((u) && (st) && (t)) {
+ sp = (unsigned char const *)t; sl = dk3str_c8_len(t); back = 1;
+ while(sl) {
+ used = 0;
+ if(dk3enc_utf82uc(&c32, sp, sl, &used)) {
+ if(!dk3uc2lat_stputc(u, st, c32, &mm)) {
+ back = 0;
+ }
+ if(used) {
+ if(sl >= used) {
+ sl = sl - used;
+ sp = &(sp[used]);
+ } else {
+ sl = 0; back = 0;
+ }
+ } else {
+ sl = 0; back = 0; /* No byte used, will appear again and again. */
+ }
+ } else {
+ sl = 0; back = 0;
+ if(u->app) {
+ /* ERROR: Decoding failed! */
+ dk3app_log_i1(u->app, DK3_LL_ERROR, 118);
+ }
+ }
+ }
+ if(mm) {
+ dk3stream_c8_fputs(st, dk3uc2lat_mm[1]);
+ }
+ }
+
+
+#line 1917 "dk3uc2l.ctr"
+ return back;
+}
+
+
+
+int
+dk3uc2lat_c16_stputs(dk3_uc2lat_t *u, dk3_stream_t *st, dk3_c16_t const *t)
+{
+ int back = 0;
+ int mm = 0; /* Flag: Math mode. */
+ dk3_c16_t const *sp; /* Current position. */
+ size_t sl; /* Number of 16-bit characters remaining. */
+ size_t used; /* Number of 16-bit characters used. */
+ dk3_c32_t c32; /* Current output character. */
+
+
+#line 1932 "dk3uc2l.ctr"
+ if((u) && (st) && (t)) {
+ sp = t; sl = dk3str_c16_len(t); back = 1;
+ while(sl) {
+ used = 0;
+ if(dk3enc_utf162uc(&c32, sp, sl, &used)) {
+ if(used) {
+ if(!dk3uc2lat_stputc(u, st, c32, &mm)) { back = 0; }
+ if(sl >= used) {
+ sl = sl - used;
+ sp = &(sp[used]);
+ } else {
+ sl = 0;
+ }
+ } else {
+ back = 0; sl = 0;
+ if(u->app) {
+ /* ERROR: Decoding */
+ dk3app_log_i1(u->app, DK3_LL_ERROR, 119);
+ }
+ }
+ } else {
+ sl = 0; back = 0;
+ if(u->app) {
+ /* Decoding error */
+ dk3app_log_i1(u->app, DK3_LL_ERROR, 119);
+ }
+ }
+ }
+ if(mm) {
+ dk3stream_c8_fputs(st, dk3uc2lat_mm[1]);
+ }
+ }
+
+
+#line 1965 "dk3uc2l.ctr"
+ return back;
+}
+
+
+
+int
+dk3uc2lat_c32_stputs(dk3_uc2lat_t *u, dk3_stream_t *st, dk3_c32_t const *t)
+{
+ int back = 0;
+ int mm = 0; /* Flag: Math mode. */
+ dk3_c32_t const *ptr; /* Current position. */
+
+
+#line 1977 "dk3uc2l.ctr"
+ if((u) && (st) && (t)) {
+ back = 1;
+ ptr = t;
+ while(*ptr) {
+ if(!dk3uc2lat_stputc(u, st, *(ptr++), &mm)) {
+ back = 0;
+ }
+ }
+ if(mm) {
+ dk3stream_c8_fputs(st, dk3uc2lat_mm[1]);
+ }
+ }
+
+
+#line 1990 "dk3uc2l.ctr"
+ return back;
+}
+
+
+
+int
+dk3uc2lat_stputs(dk3_uc2lat_t *u, dk3_stream_t *st, dkChar const *t, int e)
+{
+ int back = 0;
+
+
+#line 2000 "dk3uc2l.ctr"
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ back = dk3uc2lat_c32_stputs(u, st, t);
+#else
+ back = dk3uc2lat_c16_stputs(u, st, t);
+#endif
+#else
+ switch(e) {
+ case DK3_ENCODING_UTF8: {
+ back = dk3uc2lat_c8_utf8_stputs(u, st, t);
+ } break;
+ default: {
+ back = dk3uc2lat_c8_plain_stputs(u, st, t);
+ } break;
+ }
+#endif
+
+
+#line 2017 "dk3uc2l.ctr"
+ return back;
+}
+
+
+
+void
+dk3uc2lat_final_report(dk3_uc2lat_t *u, dk3_stream_t *st)
+{
+ dk3_uc2lat_pkg_t *pkgp;
+ dk3stream_c8_fputs(st, dk3uc2lat_mm[2]);
+ if (0 != ((u->fe) & DK3_FONT_ENCODING_OT1)) {
+ dk3stream_c8_fputs(st, dk3uc2l_c8_font_encoding_names[0]);
+ }
+ if (0 != ((u->fe) & DK3_FONT_ENCODING_T1)) {
+ dk3stream_c8_fputs(st, dk3uc2l_c8_font_encoding_names[1]);
+ }
+ if (0 != ((u->fe) & DK3_FONT_ENCODING_T4)) {
+ dk3stream_c8_fputs(st, dk3uc2l_c8_font_encoding_names[2]);
+ }
+ if (0 != ((u->fe) & DK3_FONT_ENCODING_T5)) {
+ dk3stream_c8_fputs(st, dk3uc2l_c8_font_encoding_names[3]);
+ }
+ dk3stream_c8_fputs(st, dk3uc2lat_mm[4]);
+ dk3uc2lat_package_reset(u);
+ do {
+ pkgp = dk3uc2lat_package_next(u);
+ if (NULL != pkgp) {
+
+
+#line 2045 "dk3uc2l.ctr"
+
+
+#line 2046 "dk3uc2l.ctr"
+
+
+#line 2047 "dk3uc2l.ctr"
+
+
+#line 2048 "dk3uc2l.ctr"
+
+
+#line 2049 "dk3uc2l.ctr"
+
+
+#line 2050 "dk3uc2l.ctr"
+
+
+#line 2051 "dk3uc2l.ctr"
+ if ((0x00 != pkgp->used) && (NULL != pkgp->name)) {
+ dk3stream_c8_fputs(st, dk3uc2lat_mm[3]);
+ dk3stream_c8_fputs(st, pkgp->name);
+ dk3stream_c8_fputs(st, dk3uc2lat_mm[4]);
+ }
+ }
+ } while (NULL != pkgp);
+}
+
+
+
+/* vim: set ai sw=2 : */
diff --git a/support/dktools/dk3uc2l.ctr b/support/dktools/dk3uc2l.ctr
new file mode 100644
index 0000000000..772373aa4a
--- /dev/null
+++ b/support/dktools/dk3uc2l.ctr
@@ -0,0 +1,2062 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk3uc2l.h 32-bit character to LaTeX conversion.
+
+This module was rewritten in August 2015, so it uses the same *.t2l files
+as the dk4uc2l module.
+During this rewrite the functionality was stripped down to those functions
+used by the itadmin program.
+
+*/
+
+#include "dk3conf.h"
+#include "dk3types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open LaTeX encoder.
+ @param d Directory containing the tables.
+ @param f_desc Flag: Attempt to load glyph descriptions.
+ @param f_utf8 Flag: UTF-8 output encoding.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new encoder on success, NULL on error.
+*/
+dk3_uc2lat_t *
+dk3uc2lat_open_app(dkChar const *d, int f_desc, int f_utf8, dk3_app_t *app);
+
+/** Close LaTeX encoder.
+ @param u Encoder to close.
+*/
+void
+dk3uc2lat_close(dk3_uc2lat_t *u);
+
+/** Retrieve LaTeX encoding for one 32-bit character.
+ @param u LaTeX encoder.
+ @param c32 Character to obtain LaTeX encoding for.
+ @param ismath Flag: In math mode.
+ @return Pointer to encoding on success, NULL on error.
+*/
+char const *
+dk3uc2lat_get(dk3_uc2lat_t *u, dk3_c32_t c32, int ismath);
+
+/** Check whether a character can be written to a LaTeX file directly.
+ @param c32 Character to check.
+ @return 1 for yes, 0 for no.
+*/
+int
+dk3uc2lat_direct(dk3_c32_t c32);
+
+/** Write LaTeX encoding for a string to a stream.
+ @param u LaTeX encoder.
+ @param st Stream to write to.
+ @param t Text to write (ASCII/ISO-LATIN-1 encoded).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3uc2lat_c8_plain_stputs(dk3_uc2lat_t *u, dk3_stream_t *st, char const *t);
+
+/** Write LaTeX encoding for a string to a stream.
+ @param u LaTeX encoder.
+ @param st Stream to write to.
+ @param t Text to write (UTF-8 encoded).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3uc2lat_c8_utf8_stputs(dk3_uc2lat_t *u, dk3_stream_t *st, char const *t);
+
+/** Write LaTeX encoding for a string to a stream.
+ @param u LaTeX encoder.
+ @param st Stream to write to.
+ @param t Text to write (UTF-16 encoded).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3uc2lat_c16_stputs(dk3_uc2lat_t *u, dk3_stream_t *st, dk3_c16_t const *t);
+
+/** Write LaTeX encoding for a string to a stream.
+ @param u LaTeX encoder.
+ @param st Stream to write to.
+ @param t Text to write (32-bit characters).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3uc2lat_c32_stputs(dk3_uc2lat_t *u, dk3_stream_t *st, dk3_c32_t const *t);
+
+/** Write LaTeX encoding for a string to a stream.
+ @param u LaTeX encoder.
+ @param st Stream to write to.
+ @param t Text to write (dkChar characters).
+ @param e Encoding (only used for 8-bit characters).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3uc2lat_stputs(dk3_uc2lat_t *u, dk3_stream_t *st, dkChar const *t, int e);
+
+#if HAVE_PACKAGES
+
+/** Prepare LaTeX encoder to retrieve package information.
+ @param u LaTeX encoder.
+*/
+void
+dk3uc2lat_package_reset(dk3_uc2lat_t *u);
+
+/** Retrieve next package information from LaTeX encoder.
+ @param u LaTeX encoder.
+ @return Pointer to next package information or NULL.
+*/
+dk3_uc2lat_pkg_t *
+dk3uc2lat_package_next(dk3_uc2lat_t *u);
+
+#endif
+
+/** Reset font encoding information.
+ @param u LaTeX encoder.
+*/
+void
+dk3uc2lat_font_encoding_reset(dk3_uc2lat_t *u);
+
+/** Check for font encoding conflicts.
+ @param u LaTeX encoder.
+ @return 1 on conflicts, 0 otherwise (no problems).
+*/
+int
+dk3uc2lat_font_encoding_conflict(dk3_uc2lat_t *u);
+
+/** Report font encoding requirement conflicts.
+ @param u LaTeX encoder.
+*/
+void
+dk3uc2lat_font_encoding_report_conflict(dk3_uc2lat_t *u);
+
+/** Report font encoding requirement conflicts.
+ @param u LaTeX encoder.
+*/
+void
+dk3uc2lat_font_encoding_report(dk3_uc2lat_t *u);
+
+/** Write some final comments to output stream about
+ usable encdings and required packages.
+ @param u LaTeX encoder.
+ @param st Output stream.
+*/
+void
+dk3uc2lat_final_report(dk3_uc2lat_t *u, dk3_stream_t *st);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+/** Enable or disable support for dk3_uc2l_pkg_t.
+*/
+#define HAVE_PACKAGES 1
+
+
+#include "dk3all.h"
+#include "dk3maih8.h"
+
+
+$!trace-include
+
+
+
+/** LaTeX commands to start and end math mode.
+*/
+static char const * const dk3uc2lat_mm[] = {
+"\\(",
+"\\)",
+"% font encodings:",
+"% package: ",
+"\n",
+};
+
+
+
+#if 0
+/** Font encoding names.
+*/
+static char const * const dk3uc2lat_font_encodings[] = {
+"ot1",
+"!ot1",
+"t1",
+"!t1",
+"t4",
+"!t4",
+"t5",
+"!t5",
+NULL
+};
+#endif
+
+
+
+/** Font encoding names, used in error messages.
+*/
+static dkChar const * const dk3uc2l_font_encoding_names[] = {
+dkT("OT1"),
+dkT("T1"),
+dkT("T4"),
+dkT("T5"),
+NULL
+};
+
+
+
+/** Font encoding names written at end of output file.
+*/
+static const char * const dk3uc2l_c8_font_encoding_names[] = {
+$!string-table
+ OT1
+ T1
+ T4
+ T5
+$!end
+};
+
+
+
+/** Allowed suffixes for conversion data files.
+*/
+static dkChar const * const dk3uc2l_suffixes[] = {
+dkT(".t2l"),
+#if DK3_HAVE_ZLIB_H && (DK3_CHAR_SIZE == 1)
+dkT(".t2l.gz"),
+#endif
+#if DK3_HAVE_BZLIB_H && (DK3_CHAR_SIZE == 1)
+dkT(".t2l.bz2"),
+#endif
+NULL
+};
+
+
+
+/** Compression suffixes.
+*/
+static dkChar const * const dk3uc2l_co_suf[] = {
+$!string-table macro=dkT
+.gz
+.bz2
+$!end
+};
+
+
+
+/** Attribute keywords.
+*/
+static const char * const dk3uc2l_kw[] = {
+$!string-table
+b$oth
+t$ext
+m$ath
+e$ncoding
+p$ackages
+$!end
+};
+
+
+
+/** Encoding names, used for reporting.
+*/
+static const char * const dk3uc2l_enco[] = {
+$!string-table
+ot1
+t1
+t4
+t5
+$!end
+};
+
+
+
+/** Release an array of string pointers.
+ @param ap Array base address.
+ @param ns Number of strings.
+*/
+static
+void
+dk3uc2lat_release_pointer_array(char const **ap, size_t ns)
+{
+ char const **ptr; /* Current string in array. */
+ size_t i; /* Current string index in array. */
+ $? "+ dk3uc2lat_release_pointer_array %lu", (unsigned long)ns
+ ptr = ap; i = ns;
+ while(i--) {
+ dk3_release(*ptr);
+ ptr++;
+ } $? "- dk3uc2lat_release_pointer_array"
+ dk3_delete(ap);
+}
+
+
+
+/** Destroy range structure, release memory.
+ @param rp Structure to destroy.
+*/
+static
+void
+dk3uc2lat_range_delete(dk3_uc2lat_range_t *rp)
+{
+ size_t numchar; /* Number of characters in this range. */
+ dkChar const **ptr; /* Release all descriptions. */
+ dk3_uc2lat_pkg_t ***pkgppp;
+ size_t i; /* Number of descriptions to release. */
+ $? "+ dk3uc2lat_range_delete %lx %lx", (unsigned long)(rp->start), (unsigned long)(rp->end)
+ if(rp) {
+ numchar = (size_t)(rp->end - rp->start + 1);
+ if(numchar > 0) {
+ rp->dir = NULL;
+ if(rp->f) {
+ dk3_release(rp->f);
+ } rp->f = NULL;
+ if(rp->dsc) {
+ ptr = rp->dsc;
+ i = (size_t)(rp->end - rp->start + 1);
+ while(i--) {
+ dk3_release(*ptr);
+ ptr++;
+ }
+ } rp->dsc = NULL;
+ if(rp->a) {
+ dk3uc2lat_release_pointer_array(rp->a, numchar);
+ } rp->a = NULL;
+ if(rp->t) {
+ dk3uc2lat_release_pointer_array(rp->t, numchar);
+ } rp->t = NULL;
+ if(rp->m) {
+ dk3uc2lat_release_pointer_array(rp->m, numchar);
+ } rp->m = NULL;
+ if(rp->p) {
+ pkgppp = rp->p;
+ i = (size_t)(rp->end - rp->start + 1);
+ while (i--) {
+ dk3_release(*pkgppp);
+ pkgppp++;
+ }
+ dk3_delete(rp->p);
+ } rp->p = NULL;
+ rp->start = (dk3_c32_t)0UL; rp->end = (dk3_c32_t)0UL;
+ rp->ia = 0x00;
+ }
+ dk3_delete(rp);
+ } $? "- dk3uc2lat_range_delete"
+}
+
+
+#if HAVE_PACKAGES
+
+/** Destroy package structure, release memory.
+ @param pp Structure to release.
+*/
+static
+void
+dk3uc2lat_pkg_delete(dk3_uc2lat_pkg_t *pp)
+{
+ $? "+ dk3uc2lat_pkg_delete %!8s", TR_8PTR(pp)
+ if(pp) { $? ". pkg name = \"%!8s\"", TR_8STR(pp->name)
+ dk3_release(pp->name);
+ pp->used = 0x00;
+ dk3_delete(pp);
+ } $? "- dk3uc2lat_pkg_delete"
+}
+
+#endif
+
+
+/** Destroy UC to LaTeX directory structure, release memory.
+ @param dp Structure to destroy.
+*/
+static
+void
+dk3uc2lat_dir_delete(dk3_uc2lat_dir_t *dp)
+{
+ $? "+ dk3uc2lat_dir_delete %!8s", TR_8PTR(dp)
+ if(dp) {
+ if(dp->s_ran) {
+ if(dp->i_ran) {
+ dk3sto_it_close(dp->i_ran);
+ } dp->i_ran = NULL;
+ dk3sto_close(dp->s_ran);
+ } dp->s_ran = NULL;
+ dk3_release(dp->sn);
+ dp->loaded = 0x00;
+ dk3_delete(dp);
+ } $? "- dk3uc2lat_dir_delete"
+}
+
+
+
+#if HAVE_PACKAGES
+
+/** Compare two package records.
+ @param l Left record.
+ @param r Right record or name.
+ @param cr Comparison criteria (0=record/record, 1=record/name).
+ @return Comparison result.
+*/
+static
+int
+dk3uc2lat_pkg_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3_uc2lat_pkg_t const *pl; /* Left pointer. */
+ dk3_uc2lat_pkg_t const *pr; /* Right pointer. */
+
+ pl = (dk3_uc2lat_pkg_t const *)l;
+ pr = (dk3_uc2lat_pkg_t const *)r;
+ if(l) {
+ if(r) {
+ switch(cr) {
+ case 1: {
+ if(pl->name) {
+ back = dk3str_c8_cmp(pl->name, (char const *)r);
+ } else { back = -1; }
+ } break;
+ default: {
+ if(pl->name) {
+ if(pr->name) {
+ back = dk3str_c8_cmp(pl->name, pr->name);
+ } else { back = 1; }
+ } else {
+ if(pr->name) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ if(back < -1) { back = -1; }
+ if(back > 1) { back = 1; }
+ return back;
+}
+
+#endif
+
+
+
+/** Compare two range structures by start and end character.
+ @param l Left structure.
+ @param r Right structure/UC character.
+ @param cr Comparison criteria (0=struct/struct, 1=struct/char).
+ @return Comparison result.
+*/
+static
+int
+dk3uc2lat_range_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3_uc2lat_range_t const *pl; /* Left pointer. */
+ dk3_uc2lat_range_t const *pr; /* Right pointer. */
+ dk3_c32_t *ucptr; /* Right pointer is a character pointer. */
+
+ pl = (dk3_uc2lat_range_t const *)l;
+ pr = (dk3_uc2lat_range_t const *)r;
+ if(l) {
+ if(r) {
+ switch(cr) {
+ case 1: {
+ ucptr = (dk3_c32_t *)r;
+ if(pl->start > (*ucptr)) {
+ back = 1;
+ } else {
+ if(pl->end < (*ucptr)) {
+ back = -1;
+ }
+ }
+ } break;
+ default: {
+ if(pl->start > pr->end) {
+ back = 1;
+ } else {
+ if(pl->end < pr->start) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+/** Compare two UC to LaTeX directory structures.
+ @param l Left structure.
+ @param r Right structure/name.
+ @param cr Comparison criteria (0=struct/struct, 1=struct/name).
+ @return Comparison result.
+*/
+static
+int
+dk3uc2lat_dir_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3_uc2lat_dir_t const *pl; /* Left pointer. */
+ dk3_uc2lat_dir_t const *pr; /* Right pointer. */
+
+ pl = (dk3_uc2lat_dir_t const *)l;
+ pr = (dk3_uc2lat_dir_t const *)r;
+ if(l) {
+ if(r) {
+ switch(cr) {
+ case 1: {
+ if(pl->sn) {
+ back = dk3str_fncmp(pl->sn, (dkChar const *)r);
+ } else { back = -1; }
+ } break;
+ default: {
+ if(pl->sn) {
+ if(pr->sn) {
+ back = dk3str_fncmp(pl->sn, pr->sn);
+ } else { back = 1; }
+ } else {
+ if(pr->sn) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+void
+dk3uc2lat_close(dk3_uc2lat_t *u)
+{
+#if HAVE_PACKAGES
+ dk3_uc2lat_pkg_t *ppkg;
+#endif
+ dk3_uc2lat_dir_t *pdir;
+ dk3_uc2lat_range_t *pran;
+ $? "+ dk3uc2lat_close"
+ if (NULL != u) {
+ u->app = NULL;
+ dk3_release(u->dir);
+ dk3_release(u->buf);
+ if (NULL != u->s_ran) {
+ if (NULL != u->i_ran) {
+ dk3sto_it_reset(u->i_ran);
+ do {
+ pran = (dk3_uc2lat_range_t *)dk3sto_it_next(u->i_ran);
+ if (NULL != pran) {
+ dk3uc2lat_range_delete(pran);
+ }
+ } while (NULL != pran);
+ dk3sto_it_close(u->i_ran);
+ }
+ dk3sto_close(u->s_ran);
+ }
+ u->s_ran = NULL; u->i_ran = NULL;
+ if (NULL != u->s_dir) {
+ if (NULL != u->i_dir) {
+ dk3sto_it_reset(u->i_dir);
+ do {
+ pdir = (dk3_uc2lat_dir_t *)dk3sto_it_next(u->i_dir);
+ if (NULL != pdir) {
+ dk3uc2lat_dir_delete(pdir);
+ }
+ } while (NULL != pdir);
+ dk3sto_it_close(u->i_dir);
+ }
+ dk3sto_close(u->s_dir);
+ }
+ u->s_dir = NULL; u->i_dir = NULL;
+#if HAVE_PACKAGES
+ if (NULL != u->s_pkg) {
+ if (NULL != u->i_pkg) {
+ dk3sto_it_reset(u->i_pkg);
+ do {
+ ppkg = (dk3_uc2lat_pkg_t *)dk3sto_it_next(u->i_pkg);
+ if (NULL != ppkg) {
+ dk3uc2lat_pkg_delete(ppkg);
+ }
+ } while (NULL != ppkg);
+ dk3sto_it_close(u->i_pkg);
+ }
+ dk3sto_close(u->s_pkg);
+ }
+ u->s_pkg = NULL; u->i_pkg = NULL;
+#endif
+ u->rca = NULL;
+ u->szbuf = 0;
+ u->f_dsc = 0;
+ u->f_utf8 = 0;
+ u->fe = 0;
+ dk3_delete(u);
+ }
+ $? "- dk3uc2lat_close"
+}
+
+
+
+#if HAVE_PACKAGES
+
+/** Create package structure, allocate memory.
+ @param pn Package name.
+ @param app Application structure for diagnostics.
+ @return Pointer to new structure on success, NULL on error.
+*/
+static
+dk3_uc2lat_pkg_t *
+dk3uc2lat_pkg_new(char const *pn, dk3_app_t *app)
+{
+ dk3_uc2lat_pkg_t *back = NULL;
+ $? "+ dk3uc2lat_pkg_new \"%!8s\"", TR_8STR(pn)
+ back = dk3_new_app(dk3_uc2lat_pkg_t,1,app);
+ if(back) {
+ back->used = 0x00;
+ back->name = dk3str_c8_dup_app(pn,app);
+ if(!(back->name)) {
+ dk3uc2lat_pkg_delete(back);
+ back = NULL;
+ }
+ } $? "- dk3uc2lat_pkg_new %!8s", TR_8PTR(back)
+ return back;
+}
+
+#endif
+
+
+/** Create range structure, allocate memory.
+ @param start Start character of range.
+ @param end End character of range.
+ @param dir Directory structure (parent of this range).
+ @param app Application structure for diagnostics.
+ @return Pointer to new range structure on success, NULL on error.
+*/
+static
+dk3_uc2lat_range_t *
+dk3uc2lat_range_new(
+ dk3_c32_t start, dk3_c32_t end, dk3_uc2lat_dir_t *dir, dk3_app_t *app
+)
+{
+ dk3_uc2lat_range_t *back = NULL;
+ char range_text[32]; /* Buffer for number range. */
+ dkChar dk_range_text[32]; /* Buffer for number range. */
+ $? "+ dk3uc2lat_range_new %lx %lx", (unsigned long)(start), (unsigned long)(end)
+ if(dk3app_max_log_level(app) >= DK3_LL_DEBUG) {
+ sprintf(range_text, "%lx-%lx", (long)start, (long)end);
+ (void)dk3str_c8_to_str_simple_app(dk_range_text, 32, range_text, app);
+ dk3app_log_i3(app, DK3_LL_DEBUG, 238, 239, dk_range_text);
+ }
+ if(end >= start) {
+ back = dk3_new_app(dk3_uc2lat_range_t,1,app);
+ if(back) {
+ back->dir = dir;
+ back->dsc = NULL;
+ back->a = NULL;
+ back->t = NULL;
+ back->m = NULL;
+#if HAVE_PACKAGES
+ back->p = NULL;
+#endif
+ back->f = NULL;
+ back->start = start;
+ back->end = end;
+ back->ia = 0x00;
+ }
+ } else {
+ if(app) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 220);
+ }
+ } $? "- dk3uc2lat_range_new %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+/** Create UC to LaTeX directory structure, allocate memory.
+ @param sn Short directory file name.
+ @param app Application structure for diagnostics.
+ @return Pointer to new directory structure on success, NULL on error.
+*/
+static
+dk3_uc2lat_dir_t *
+dk3uc2lat_dir_new(dkChar const *sn, dk3_app_t *app)
+{
+ dk3_uc2lat_dir_t *back = NULL;
+ $? "+ dk3uc2lat_dir_new \"%!ds\"", TR_STR(sn)
+ back = dk3_new_app(dk3_uc2lat_dir_t,1,app);
+ if(back) {
+ back->s_ran = NULL; back->i_ran = NULL; back->sn = NULL;
+ back->loaded = 0x00;
+ back->s_ran = dk3sto_open_app(app);
+ if(back->s_ran) {
+ dk3sto_set_comp(back->s_ran, dk3uc2lat_range_compare, 0);
+ back->i_ran = dk3sto_it_open(back->s_ran);
+ if(back->i_ran) {
+ back->sn = dk3str_dup_app(sn,app);
+ }
+ }
+ if(!((back->s_ran) && (back->i_ran) && (back->sn))) {
+ dk3uc2lat_dir_delete(back); back = NULL;
+ }
+ } $? "- dk3uc2lat_dir_new PTR:%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/** Create new LaTeX encoder.
+ @param dn Directory containing the data files.
+ @param f_utf8 Flag: Allowed to write UTF-8 output.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new encoder on success, NULL on error.
+*/
+static
+dk3_uc2lat_t *
+dk3uc2lat_t_new(
+ const dkChar *dn,
+ int f_utf8,
+ dk3_app_t *app
+)
+{
+ dk3_uc2lat_t *back = NULL;
+ int ok = 0;
+ $? "+ dk3uc2lat_t_new %!ds", dn
+ back = dk3_new_app(dk3_uc2lat_t,1,app);
+ if (NULL != back) {
+ back->app = app;
+ back->dir = NULL;
+ back->buf = NULL;
+ back->s_ran = NULL;
+ back->i_ran = NULL;
+ back->s_dir = NULL;
+ back->i_dir = NULL;
+#if HAVE_PACKAGES
+ back->s_pkg = NULL;
+ back->i_pkg = NULL;
+#endif
+ back->rca = NULL;
+ back->szbuf = 0;
+ back->f_dsc = 0;
+ back->f_utf8 = f_utf8;
+ back->fe =
+ DK3_FONT_ENCODING_OT1 + DK3_FONT_ENCODING_T1
+ + DK3_FONT_ENCODING_T4 + DK3_FONT_ENCODING_T5;
+ back->dir = dk3str_dup_app(dn, app);
+ back->buf = dk3_new_app(char,16,app);
+ if (NULL != back->buf) { back->szbuf = 16; }
+ if ((NULL != back->dir) && (NULL != back->buf)) {
+ back->s_ran = dk3sto_open_app(app);
+ if (NULL != back->s_ran) {
+ dk3sto_set_comp(back->s_ran, dk3uc2lat_range_compare, 0);
+ back->s_dir = dk3sto_open_app(app);
+ if (NULL != back->s_dir) {
+ dk3sto_set_comp(back->s_dir, dk3uc2lat_dir_compare, 0);
+#if HAVE_PACKAGES
+ back->s_pkg = dk3sto_open_app(app);
+ if (NULL != back->s_pkg) {
+ dk3sto_set_comp(back->s_pkg, dk3uc2lat_pkg_compare, 0);
+#endif
+ back->i_ran = dk3sto_it_open(back->s_ran);
+ if (NULL != back->i_ran) {
+ back->i_dir = dk3sto_it_open(back->s_dir);
+ if (NULL != back->i_dir) {
+#if HAVE_PACKAGES
+ back->i_pkg = dk3sto_it_open(back->s_pkg);
+ if (NULL != back->i_pkg) {
+#endif
+ ok = 1;
+#if HAVE_PACKAGES
+ }
+#endif
+ }
+ }
+#if HAVE_PACKAGES
+ }
+#endif
+ }
+ }
+ }
+ if (0 == ok) {
+ dk3uc2lat_close(back);
+ back = NULL;
+ }
+ } $? "- dk3uc2lat_t_new PTR:%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/** Check the file name whether it contains LaTeX conversion data
+ and can be processed.
+ @param fn File name to check.
+ @return 1 if yes, 0 otherwise.
+*/
+static
+int
+dk3uc2lat_is_suitable_file(const dkChar *fn)
+{
+ const dkChar * const *ptr; /* Traverse allowed suffixes array */
+ size_t szfn = 0; /* File name size */
+ size_t szsu = 0; /* Allowed suffix size */
+ int back = 0;
+ $? "+ dk3uc2lat_is_suitable_file %!ds", fn
+ szfn = dk3str_len(fn);
+ ptr = dk3uc2l_suffixes;
+ while ((NULL != *ptr) && (0 == back)) {
+ szsu = dk3str_len(*ptr);
+ if (szfn > szsu) {
+ if (0 == dk3str_fncmp(&(fn[szfn - szsu]), *ptr)) {
+ back = 1;
+ }
+ }
+ ptr++;
+ } $? "- dk3uc2lat_is_suitable_file %d", back
+ return back;
+}
+
+
+
+/** Add one character to the range descriptions of a file directory.
+ @param uptr Conversion structure to set up.
+ @param pdir File directory to set up.
+ @param chr Character to add.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3uc2l_add_char_to_dir(
+ dk3_uc2lat_t *uptr,
+ dk3_uc2lat_dir_t *pdir,
+ dk3_c32_t chr,
+ dk3_app_t *app
+)
+{
+ dkChar cbuf[64];
+ dk3_uc2lat_range_t *prange;
+ dk3_uc2lat_range_t *pr2;
+ size_t szcbuf = DK3_SIZEOF(cbuf,dkChar);
+ dk3_c32_t tchr;
+ int back = 0;
+ $? "+ dk3uc2l_add_char_to_dir %lx", (unsigned long)chr
+ prange = dk3sto_it_find_like(uptr->i_ran, &chr, 1);
+ if (NULL == prange) {
+ prange = dk3sto_it_find_like(pdir->i_ran, &chr, 1);
+ if (NULL == prange) {
+ if ((dk3_c32_t)0UL < chr) { $? ". try to append"
+ tchr = chr - 1;
+ prange = dk3sto_it_find_like(pdir->i_ran, &tchr, 1);
+ if (NULL != prange) { $? ". found %lx-%lx", (unsigned long)(prange->start), (unsigned long)(prange->end)
+ prange->end = chr;
+ back = 1; $? ". changed to %lx-%lx", (unsigned long)(prange->start), (unsigned long)(prange->end)
+ if (0xFFFFFFFFUL > (unsigned long)chr) {
+ tchr = chr + (dk3_c32_t)1UL;
+ pr2 = dk3sto_it_find_like(pdir->i_ran, &tchr, 1);
+ if (NULL != pr2) { $? ". found %lx-%lx", (unsigned long)(pr2->start), (unsigned long)(pr2->end)
+ tchr = pr2->end;
+ dk3sto_remove(pdir->s_ran, pr2);
+ dk3uc2lat_range_delete(pr2);
+ prange->end = tchr;
+ $? ". changed %lx-%lx", (unsigned long)(prange->start), (unsigned long)(prange->end)
+ }
+ }
+ }
+ }
+ if (0 == back) { $? ". try to prepend"
+ if (0xFFFFFFFFUL > (unsigned long)chr) { $? ". can"
+ tchr = chr + (dk3_c32_t)1UL;
+ prange = dk3sto_it_find_like(pdir->i_ran, &tchr, 1);
+ if (NULL != prange) { $? ". found %lx-%lx", (unsigned long)(prange->start), (unsigned long)(prange->end)
+ prange->start = chr;
+ back = 1; $? ". changed to %lx-%lx", (unsigned long)(prange->start), (unsigned long)(prange->end)
+ }
+ }
+ }
+ if (0 == back) { $? ". try to add"
+ prange = dk3uc2lat_range_new(chr, chr, pdir, app);
+ if (NULL != prange) {
+ if (dk3sto_add(pdir->s_ran, prange)) {
+ back = 1; $? ". added %lx-%lx", (unsigned long)(prange->start), (unsigned long)(prange->end)
+ } else {
+ dk3uc2lat_range_delete(prange);
+ }
+ }
+ }
+ } else { $? "! already found"
+ /* ERROR: Already found! */
+ if (0 != dk3ma_um_to_hex_string(cbuf, szcbuf, (dk3_um_t)chr, 8)) {
+ dk3app_log_i3(uptr->app, DK3_LL_ERROR, 395, 396, cbuf);
+ } else {
+ dk3app_log_i1(uptr->app, DK3_LL_ERROR, 397);
+ }
+ }
+ } else { $? "! already found"
+ /* ERROR: Already found ! */
+ if (0 != dk3ma_um_to_hex_string(cbuf, szcbuf, (dk3_um_t)chr, 8)) {
+ dk3app_log_i3(uptr->app, DK3_LL_ERROR, 395, 396, cbuf);
+ } else {
+ dk3app_log_i1(uptr->app, DK3_LL_ERROR, 397);
+ }
+ } $? "- dk3uc2l_add_char_to_dir %d", back
+ return back;
+}
+
+
+
+/** Apply data from stream to directory information for one file.
+ @param uptr Conversion structure to set up.
+ @param pdir File directory entry to configure.
+ @param istrm Input stream for file (normal or compressed).
+ @param fn Full path name.
+ @param sn Short file name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3uc2l_apply_1(
+ dk3_uc2lat_t *uptr,
+ dk3_uc2lat_dir_t *pdir,
+ dk3_stream_t *istrm,
+ const dkChar *fn,
+ const dkChar *sn,
+ dk3_app_t *app
+)
+{
+ char buf[512];
+ char *p1;
+ char *p2;
+ dk3_uc2lat_range_t *prange;
+ unsigned long lineno = 0UL;
+ unsigned long chr;
+ int back = 1;
+ $? "+ dk3uc2l_apply_1"
+ while ((1 == back) && (1 == dk3stream_c8_fgets(istrm, buf, sizeof(buf)))) {
+ dk3app_set_source_line(app, ++lineno);
+ buf[sizeof(buf) - 1] = '\0';
+ $? ". processing line %lu: %s", lineno, buf
+ p1 = dk3str_c8_start(buf, NULL);
+ if (NULL != p1) {
+ if ('#' != *p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ if (NULL != p2) {
+ if (0 != dk3ma_ul_from_c8_hex_string(&chr, p1, NULL)) {
+ if (0 == dk3uc2l_add_char_to_dir(uptr, pdir, chr, app)) {
+ back = 0; $? "! failed to add %lx", chr
+ }
+ } else {
+ /* ERROR: Syntax error, not a hexadecimal number */
+ dk3app_log_i1(uptr->app, DK3_LL_ERROR, 398);
+ }
+ } else {
+ /* ERROR: Syntax error, missing configuration */
+ dk3app_log_i1(uptr->app, DK3_LL_ERROR, 400);
+ }
+ }
+ }
+ }
+ if (1 == back) { $? ". copying ranges to global container"
+ dk3sto_it_reset(pdir->i_ran);
+ do {
+ prange = dk3sto_it_next(pdir->i_ran);
+ if (NULL != prange) { $? ". range %lx-%lx", (unsigned long)(prange->start), (unsigned long)(prange->end)
+ if (0 == dk3sto_add(uptr->s_ran, prange)) {
+ dk3uc2lat_range_delete(prange);
+ back = 0; $? "! failed to copy range"
+ }
+ }
+ } while (NULL != prange);
+ } else { $? "! deleting ranges due to error"
+ dk3sto_it_reset(pdir->i_ran);
+ do {
+ prange = dk3sto_it_next(pdir->i_ran);
+ if (NULL != prange) {
+ dk3uc2lat_range_delete(prange);
+ }
+ } while (NULL != prange);
+ } $? "- dk3uc2l_apply_1 %d", back
+ return back;
+}
+
+
+
+/** Apply directory information for a file.
+ @param uptr Conversion structure to set up.
+ @param fn File name containing conversion data.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3uc2lat_pass_1(
+ dk3_uc2lat_t *uptr, const dkChar *fn, const dkChar *sn, dk3_app_t *app
+)
+{
+ dk3_uc2lat_dir_t *pdir = NULL;
+ dk3_stream_t *istrm = NULL;
+ FILE *fipo = NULL;
+ const dkChar *oldsrc = NULL;
+ const dkChar *fsuf = NULL;
+#if DK3_HAVE_ZLIB_H && (DK3_CHAR_SIZE == 1)
+ gzFile gzf = NULL;
+#endif
+#if DK3_HAVE_BZLIB_H && (DK3_CHAR_SIZE == 1)
+ BZFILE *bzf = NULL;
+#endif
+ unsigned long oldln = 0UL;
+#if DK3_HAVE_FNCASEINS
+ int fncs = 0;
+#else
+ int fncs = 1;
+#endif
+ int back = 0;
+ $? ". dk3uc2lat_pass_1 %!ds", fn
+ pdir = dk3uc2lat_dir_new(sn, app);
+ if (NULL != pdir) {
+ oldsrc = dk3app_get_source_file(app);
+ oldln = dk3app_get_source_line(app);
+ dk3app_set_source_file(app, fn);
+ dk3app_set_source_line(app, 0UL);
+ if (0 != dk3sto_add(uptr->s_dir, pdir)) {
+ fsuf = dk3str_get_suffix(fn);
+ switch (dk3str_array_index(dk3uc2l_co_suf, fsuf, fncs)) {
+ case 0: { /* gz */
+#if DK3_HAVE_ZLIB_H && (DK3_CHAR_SIZE == 1)
+ gzf = gzopen(fn, "r");
+ if (NULL != gzf) {
+ istrm = dk3stream_open_gz_app(gzf, DK3_STREAM_FLAG_READ, app);
+ if (NULL != istrm) {
+ back = dk3uc2l_apply_1(uptr, pdir, istrm, fn, sn, app);
+ (void)dk3stream_close(istrm);
+ }
+ gzclose(gzf);
+ } else {
+ /* ERROR: Failed to open file */
+ dk3app_log_i3(uptr->app, DK3_LL_ERROR, 143, 144, fn);
+ }
+#else
+ /* ERROR: No zlib support */
+ dk3app_log_i1(uptr->app, DK3_LL_ERROR, 401);
+#endif
+ } break;
+ case 1: { /* bz2 */
+#if DK3_HAVE_BZLIB_H && (DK3_CHAR_SIZE == 1)
+ bzf = BZ2_bzopen(fn, "r");
+ if (NULL != bzf) {
+ istrm = dk3stream_open_bz2_app(bzf, DK3_STREAM_FLAG_READ, app);
+ if (NULL != istrm) {
+ back = dk3uc2l_apply_1(uptr, pdir, istrm, fn, sn, app);
+ (void)dk3stream_close(istrm);
+ }
+ BZ2_bzclose(bzf);
+ } else {
+ /* ERROR: Failed to open file */
+ dk3app_log_i3(uptr->app, DK3_LL_ERROR, 143, 144, fn);
+ }
+#else
+ /* ERROR: No bzip2 support */
+ dk3app_log_i1(uptr->app, DK3_LL_ERROR, 402);
+#endif
+ } break;
+ default : { /* normal file */
+ fipo = dk3sf_fopen_app(fn, dkT("r"), app);
+ if (NULL != fipo) {
+ istrm = dk3stream_open_file_app(fipo, DK3_STREAM_FLAG_READ, app);
+ if (NULL != istrm) {
+ back = dk3uc2l_apply_1(uptr, pdir, istrm, fn, sn, app);
+ (void)dk3stream_close(istrm);
+ }
+ fclose(fipo);
+ }
+ } break;
+ }
+ } else {
+ dk3uc2lat_dir_delete(pdir);
+ }
+ dk3app_set_source_file(app, oldsrc);
+ dk3app_set_source_line(app, oldln);
+ } $? "- dk3uc2lat_pass_1 %d", back
+ return back;
+}
+
+
+
+/** Read directory information (check existing data files, retrieve ranges.
+ @param d Directory containing the data files.
+ @param uptr Conversion structure to initialize.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3uc2lat_read_dir_info(dk3_uc2lat_t *uptr, dk3_app_t *app)
+{
+ dk3_dir_t *dir = NULL;
+ const dkChar *fn = NULL;
+ const dkChar *sn = NULL;
+ int back = 0;
+ int found = 0;
+ $? "+ dk3uc2lat_read_dir_info"
+ dir = dk3dir_open_app(uptr->dir, uptr->app);
+ if (NULL != dir) {
+ back = 1;
+ while (0 != dk3dir_get_next_file(dir)) {
+ sn = dk3dir_get_shortname(dir);
+ fn = dk3dir_get_fullname(dir);
+ if ((NULL != sn) && (NULL != fn)) {
+ if (0 != dk3uc2lat_is_suitable_file(fn)) {
+ found = 1;
+ if (0 == dk3uc2lat_pass_1(uptr, fn, sn, app)) {
+ back = 0;
+ }
+ }
+ }
+ }
+ dk3dir_close(dir);
+ if (0 == found) {
+ back = 0;
+ /* ERROR: No suitable files found */
+ dk3app_log_i1(uptr->app, DK3_LL_ERROR, 403);
+ }
+ }
+ $? "- dk3uc2lat_read_dir_info %d", back
+ return back;
+}
+
+
+
+/** Allocate memory for all ranges details for a file directory.
+ @param uptr Conversion structure to set up.
+ @param pdir Directory information to set up.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3uc2l_allocate_memory(
+ dk3_uc2lat_t *uptr,
+ dk3_uc2lat_dir_t *pdir
+)
+{
+ dk3_uc2lat_range_t *prange;
+ size_t sz;
+ size_t i;
+ int back = 1;
+ int allenc = 0;
+
+ dk3sto_it_reset(pdir->i_ran);
+ allenc = DK3_FONT_ENCODING_OT1
+ + DK3_FONT_ENCODING_T1
+ + DK3_FONT_ENCODING_T4
+ + DK3_FONT_ENCODING_T5;
+ do {
+ prange = (dk3_uc2lat_range_t *)dk3sto_it_next(pdir->i_ran);
+ if (NULL != prange) {
+ sz = (size_t)(prange->end - prange->start) + 1;
+ if (NULL == prange->a) {
+ prange->a = dk3_new_app(DK3_PCCHAR,sz,uptr->app);
+ if (NULL != prange->a) {
+ for (i = 0; i < sz; i++) { (prange->a)[i] = NULL; }
+ } else {
+ back = 0;
+ }
+ }
+ if (NULL == prange->t) {
+ prange->t = dk3_new_app(DK3_PCCHAR,sz,uptr->app);
+ if (NULL != prange->t) {
+ for (i = 0; i < sz; i++) { (prange->t)[i] = NULL; }
+ } else {
+ back = 0;
+ }
+ }
+ if (NULL == prange->m) {
+ prange->m = dk3_new_app(DK3_PCCHAR,sz,uptr->app);
+ if (NULL != prange->m) {
+ for (i = 0; i < sz; i++) { (prange->m)[i] = NULL; }
+ } else {
+ back = 0;
+ }
+ }
+#if HAVE_PACKAGES
+ if (NULL == prange->p) {
+ prange->p = dk3_new_app(dk3_uc2lat_pkg_pptr,sz,uptr->app);
+ if (NULL != prange->p) {
+ for (i = 0; i < sz; i++) { (prange->p)[i] = NULL; }
+ } else {
+ back = 0;
+ }
+ }
+#endif
+ if (NULL == prange->f) {
+ prange->f = dk3_new_app(dk3_font_encoding_t,sz,uptr->app);
+ if (NULL != prange->f) {
+ for(i = 0; i < sz; i++) { (prange->f)[i] = allenc; }
+ } else {
+ back = 0;
+ }
+ }
+ }
+ } while (NULL != prange);
+ return back;
+}
+
+
+
+static
+void
+dk3uc2l_apply_2(
+ dk3_uc2lat_t *uptr,
+ dk3_uc2lat_dir_t *pdir,
+ dk3_stream_t *istrm,
+ const dkChar *filename
+)
+{
+ char buf[512]; /* Input line buffer */
+#if HAVE_PACKAGES
+ char *parts[16]; /* Package names */
+#endif
+ char *p1; /* Hex value or next item */
+ char *p2; /* Current item key */
+ char *p3; /* Current item value */
+ char *p4; /* Dynamic value copy */
+ dk3_uc2lat_range_t *prange; /* Current range */
+#if HAVE_PACKAGES
+ dk3_uc2lat_pkg_t *ppkg; /* Current package */
+#endif
+ unsigned long lineno = 0UL; /* Current line number */
+ unsigned long chr; /* Current character */
+ size_t ind; /* Index of chr in range */
+#if HAVE_PACKAGES
+ size_t nparts; /* Number of packages */
+ size_t i; /* Traverse */
+ size_t j; /* Add new packages */
+#endif
+ int cc = 1; /* Flag: Can continue */
+ int action; /* Action to take */
+ int isneg; /* Flag: Deny encodings */
+ int encod; /* Encodings selection */
+ $? "+ dk3uc2l_apply_2"
+ while ((1 == cc) && (1 == dk3stream_c8_fgets(istrm, buf, sizeof(buf)))) {
+ dk3app_set_source_line(uptr->app, ++lineno);
+ buf[sizeof(buf) - 1] = '\0';
+ $? ". processing line %lu: %s", lineno, buf
+ p1 = dk3str_c8_start(buf, NULL);
+ if (NULL != p1) { $? ". p1=\"%!8s\"", p1
+ if ('#' != *p1) { $? ". normal line"
+ p2 = dk3str_c8_next(p1, NULL);
+ if (NULL != p2) { $? ". attributes=\"%!8s\"", p2
+ if (0 != dk3ma_ul_from_c8_hex_string(&chr, p1, NULL)) {
+ prange =
+ (dk3_uc2lat_range_t *)dk3sto_it_find_like(pdir->i_ran, &chr, 1);
+ if (NULL != prange) { $? ". range found"
+ ind = (size_t)(chr - prange->start);
+ while (NULL != p2) {
+ p1 = dk3str_c8_next(p2, NULL);
+ p3 = dk3str_c8_chr(p2, '=');
+ if (NULL != p3) {
+ *(p3++) = '\0';
+#if 0
+ /* 2015-08-10 Bugfix: Must be start */
+ p3 = dk3str_c8_next(p3, NULL);
+#endif
+ p3 = dk3str_c8_start(p3, NULL);
+ if (NULL != p3) { $? ". \"%!8s\"=\"%!8s\"", p2, p3
+ action = dk3str_c8_array_abbr(dk3uc2l_kw, p2, '$', 0);
+ $? ". action = %d", action
+ switch (action) {
+ case 0: { /* both */ $? ". both"
+ if (NULL != prange->a) {
+ p4 = dk3str_c8_dup_app(p3, uptr->app);
+ if (NULL != p4) {
+ dk3_release((prange->a)[ind]);
+ (prange->a)[ind] = p4;
+ }
+ }
+ } break;
+ case 1: { /* text */ $? ". text"
+ if (NULL != prange->t) {
+ p4 = dk3str_c8_dup_app(p3, uptr->app);
+ if (NULL != p4) {
+ dk3_release((prange->t)[ind]);
+ (prange->t)[ind] = p4;
+ }
+ }
+ } break;
+ case 2: { /* math */ $? ". math"
+ if (NULL != prange->m) {
+ p4 = dk3str_c8_dup_app(p3, uptr->app);
+ if (NULL != p4) {
+ dk3_release((prange->m)[ind]);
+ (prange->m)[ind] = p4;
+ }
+ }
+ } break;
+ case 3: { /* encoding */ $? ". encoding"
+ if (NULL != prange->f) {
+ isneg = 0; encod = 0;
+ if ('!' == *p3) {
+ isneg = 1; p3++;
+ }
+ while (NULL != p3) {
+ p4 = dk3str_c8_chr(p3, ',');
+ if (NULL != p4) {
+ *(p4++) = '\0';
+ p4 = dk3str_c8_start(p4, NULL);
+ }
+ switch (dk3str_c8_array_index(dk3uc2l_enco, p3, 0))
+ {
+ case 0: { /* OT1 */
+ encod |= DK3_FONT_ENCODING_OT1;
+ } break;
+ case 1: { /* T1 */
+ encod |= DK3_FONT_ENCODING_T1;
+ } break;
+ case 2: { /* T4 */
+ encod |= DK3_FONT_ENCODING_T4;
+ } break;
+ case 3: { /* T5 */
+ encod |= DK3_FONT_ENCODING_T5;
+ } break;
+ default : {
+ /* Syntax error, unknown encoding */
+ dk3app_log_i1(uptr->app, DK3_LL_DEBUG, 404);
+ } break;
+ }
+ p3 = p4;
+ }
+ if (0 != isneg) { encod = (~(encod)); }
+ (prange->f)[ind] = encod;
+ }
+ } break;
+ case 4: { /* packages */ $? ". packages"
+#if HAVE_PACKAGES
+ if (NULL != prange->p) {
+ nparts = dk3str_c8_explode(parts, 15, p3, ",");
+ if (0 < nparts) {
+ dk3_release((prange->p)[ind]);
+ (prange->p)[ind] =
+ dk3_new_app(dk3_uc2lat_pkg_ptr,(nparts+1),uptr->app);
+ if (NULL != (prange->p)[ind]) {
+ for (i = 0; i < (nparts+1); i++) {
+ ((prange->p)[ind])[i] = NULL;
+ }
+ j = 0;
+ for (i = 0; i < nparts; i++) {
+ ppkg = (dk3_uc2lat_pkg_t *)dk3sto_it_find_like(
+ uptr->i_pkg, parts[i], 1
+ );
+ if (NULL != ppkg) {
+ ((prange->p)[ind])[j++] = ppkg;
+ } else {
+ ppkg = dk3uc2lat_pkg_new(parts[i], uptr->app);
+ if (NULL != ppkg) {
+ if (dk3sto_add(uptr->s_pkg, ppkg)) {
+ ((prange->p)[ind])[j++] = ppkg;
+ } else {
+ dk3uc2lat_pkg_delete(ppkg);
+ }
+ }
+ }
+ }
+ }
+ } else {
+ /* ERROR: Syntax, no packages */
+ dk3app_log_i1(uptr->app, DK3_LL_DEBUG, 405);
+ }
+ }
+#endif
+ } break;
+ default: { $? "! unknown key"
+ } break;
+ }
+ } else { $? "! missing attribute value"
+ /* ERROR: Value missing */
+ dk3app_log_i1(uptr->app, DK3_LL_DEBUG, 406);
+ }
+ } else { $? "! missing attribute value"
+ /* ERROR: Syntax, not a key value pair */
+ dk3app_log_i1(uptr->app, DK3_LL_DEBUG, 406);
+ }
+ p2 = p1;
+ }
+ } else { $? "! bug: range not found"
+ /* BUG or file changed */
+ }
+ } else {
+ /* ERROR: Syntax error, not a hexadecimal number */
+ dk3app_log_i1(uptr->app, DK3_LL_ERROR, 398);
+ }
+ } else { $? "! missing attributes"
+ /* ERROR: Syntax error, missing configuration */
+ dk3app_log_i1(uptr->app, DK3_LL_ERROR, 401);
+ }
+ } else { $? ". ignore comment line"
+ }
+ } else { $? ". ignore empty line"
+ }
+ } $? "- dk3uc2l_apply_2"
+}
+
+
+
+static
+void
+dk3uc2lat_load_file(dk3_uc2lat_t *u, dk3_uc2lat_dir_t *pdir)
+{
+ dkChar fnb[DK3_MAX_PATH];
+ dk3_stream_t *istrm = NULL;
+ FILE *fipo = NULL;
+ const dkChar *oldsrc = NULL;
+ const dkChar *fsuf = NULL;
+#if DK3_HAVE_ZLIB_H && (DK3_CHAR_SIZE == 1)
+ gzFile gzf = NULL;
+#endif
+#if DK3_HAVE_BZLIB_H && (DK3_CHAR_SIZE == 1)
+ BZFILE *bzf = NULL;
+#endif
+ unsigned long oldln = 0UL;
+#if DK3_HAVE_FNCASEINS
+ int fncs = 0;
+#else
+ int fncs = 1;
+#endif
+ size_t sz;
+ $? "+ dk3uc2lat_load_file"
+ sz = dk3str_len(u->dir);
+ sz += dk3str_len(pdir->sn);
+ sz += 1;
+ if (sizeof(fnb) > sz) { $? ". file name length ok"
+ dk3str_cpy(fnb, u->dir);
+ dk3str_cat(fnb, dk3app_not_localized(20));
+ dk3str_cat(fnb, pdir->sn);
+ dk3str_correct_filename(fnb);
+ oldsrc = dk3app_get_source_file(u->app);
+ oldln = dk3app_get_source_line(u->app);
+ dk3app_set_source_file(u->app, fnb);
+ dk3app_set_source_line(u->app, 0UL);
+ if (0 != dk3uc2l_allocate_memory(u, pdir)) { $? ". memory allocated"
+ fsuf = dk3str_get_suffix(fnb);
+ switch (dk3str_array_index(dk3uc2l_co_suf, fsuf, fncs)) {
+ case 0: { $? ". zlib compressed"
+#if DK3_HAVE_ZLIB_H && (DK3_CHAR_SIZE == 1)
+ gzf = gzopen(fnb, "r");
+ if (NULL != gzf) {
+ istrm = dk3stream_open_gz_app(gzf, DK3_STREAM_FLAG_READ, u->app);
+ if (NULL != istrm) {
+ dk3uc2l_apply_2(u, pdir, istrm, fnb);
+ (void)dk3stream_close(istrm);
+ }
+ gzclose(gzf);
+ } else {
+ /* ERROR: Failed to open file */
+ dk3app_log_i3(u->app, DK3_LL_ERROR, 143, 144, fnb);
+ }
+#else
+ /* ERROR: No zlib support */
+ dk3app_log_i1(u->app, DK3_LL_ERROR, 401);
+#endif
+ } break;
+ case 1: { $? ". bzip2 compressed"
+#if DK3_HAVE_BZLIB_H && (DK3_CHAR_SIZE == 1)
+ bzf = BZ2_bzopen(fnb, "r");
+ if (NULL != bzf) {
+ istrm = dk3stream_open_bz2_app(bzf, DK3_STREAM_FLAG_READ, u->app);
+ if (NULL != istrm) {
+ dk3uc2l_apply_2(u, pdir, istrm, fnb);
+ (void)dk3stream_close(istrm);
+ }
+ BZ2_bzclose(bzf);
+ } else {
+ /* ERROR: Failed to open file */
+ dk3app_log_i3(u->app, DK3_LL_ERROR, 143, 144, fnb);
+ }
+#else
+ /* ERROR: No bzip2 support */
+ dk3app_log_i1(u->app, DK3_LL_ERROR, 402);
+#endif
+ } break;
+ default: { $? ". normal file"
+ fipo = dk3sf_fopen_app(fnb, dkT("r"), u->app);
+ if (NULL != fipo) {
+ istrm = dk3stream_open_file_app(fipo, DK3_STREAM_FLAG_READ, u->app);
+ if (NULL != istrm) {
+ dk3uc2l_apply_2(u, pdir, istrm, fnb);
+ (void)dk3stream_close(istrm);
+ }
+ fclose(fipo);
+ }
+ } break;
+ }
+ } else { $? "! memory allocation error"
+ }
+ dk3app_set_source_file(u->app, oldsrc);
+ dk3app_set_source_line(u->app, oldln);
+ } else { $? "! file name too long"
+ /* ERROR: Name too long */
+ dk3app_log_i3(u->app, DK3_LL_ERROR, 65, 66, pdir->sn);
+ }
+ pdir->loaded = 0x01;
+ $? "- dk3uc2lat_load_file"
+}
+
+
+
+/** Open conversion structure for a given directory.
+ @param d Directory containing conversion files.
+ @param f_desc Flag: Load glyph descriptions (ignored).
+ @param f_utf8 Flag: UTF-8 output allowed.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new structure on success, NULL on error.
+*/
+static
+dk3_uc2lat_t *
+dk3uc2lat_i_open_app(const dkChar *d, int f_desc, int f_utf8, dk3_app_t *app)
+{
+ dk3_uc2lat_t *back = NULL;
+ $? "+ dk3uc2lat_i_open_app %!ds", d
+ if (0 != dk3sf_is_dir_app(d, NULL)) {
+ back = dk3uc2lat_t_new(d, f_utf8, app);
+ if (NULL != back) {
+ if (0 == dk3uc2lat_read_dir_info(back, app)) {
+ dk3uc2lat_close(back);
+ back = NULL;
+ }
+ }
+ } else {
+ /* ERROR: Not a directory ... */
+ dk3app_log_i3(app, DK3_LL_ERROR, 202, 203, d);
+ }
+ $? "- dk3uc2lat_i_open_app PTR:%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+dk3_uc2lat_t *
+dk3uc2lat_open_app(dkChar const *d, int f_desc, int f_utf8, dk3_app_t *app)
+{
+ dkChar fnb[DK3_MAX_PATH];
+ dk3_uc2lat_t *back = NULL;
+ const dkChar *shd = NULL;
+ const dkChar *dirn = NULL;
+ size_t szfnb = DK3_SIZEOF(fnb,dkChar);
+ size_t szshd = 0;
+ $? "+ dk3uc2lat_open_app %!ds", TR_DKSTR(d)
+ if (NULL != d) {
+ back = dk3uc2lat_i_open_app(d, f_desc, f_utf8, app);
+ } else {
+ if (NULL != app) {
+ if (dk3app_get_dir_from_pref(app,dk3app_not_localized(48),fnb,szfnb,1))
+ {
+ dk3str_correct_filename(fnb);
+ back = dk3uc2lat_i_open_app(fnb, f_desc, f_utf8, app);
+ } else
+ {
+ shd = dk3app_get_sharedir(app);
+ if (NULL != shd) {
+ szshd = dk3str_len(shd);
+ if (szfnb > szshd) {
+ dk3str_cpy_not_overlapped(fnb, shd);
+ dirn = dk3app_not_localized(49);
+ if (szfnb > (szshd + dk3str_len(dirn))) {
+ dk3str_cat(fnb, dirn);
+ dk3str_correct_filename(fnb);
+ back = dk3uc2lat_i_open_app(fnb, f_desc, f_utf8, app);
+ } else {
+ /* ERROR: Directory name too long! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 64, 66, dirn);
+ }
+ } else {
+ /* ERROR: Share directory name too long! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 64, 66, shd);
+ }
+ } else {
+ /* ERROR: Missing share directory */
+ dk3app_log_i1(app, DK3_LL_ERROR, 407);
+ }
+ }
+ }
+ } $? "- dk3uc2lat_open_app %d", TR_IPTR(back)
+ return back;
+}
+
+
+
+char const *
+dk3uc2lat_get(dk3_uc2lat_t *u, dk3_c32_t c32, int ismath)
+{
+ dkChar cbuf[64];
+ dk3_uc2lat_range_t *prange = NULL;
+ dk3_uc2lat_pkg_t **pkgpp;
+ const char *back = NULL;
+ size_t szcbuf = DK3_SIZEOF(cbuf,dkChar);
+ $? "+ dk3uc2lat_get"
+ if (NULL != u) {
+ if (NULL != u->rca) { $? ". range cache available"
+ if ((u->rca)->start <= c32) { $? ". start ok"
+ if ((u->rca)->end >= c32) { $? ". end ok"
+ prange = u->rca; $? ". use range cache"
+ }
+ }
+ }
+ if (NULL == prange) { $? ". find character"
+ prange = dk3sto_it_find_like(u->i_ran, &c32, 1);
+ if (NULL != prange) { $? ". range found"
+ u->rca = prange;
+ if (NULL != prange->p) { $? ". range->package"
+ pkgpp = (prange->p)[(size_t)(c32 - prange->start)];
+ if (NULL != pkgpp) {
+ while (NULL != *pkgpp) {
+ (*(pkgpp++))->used = 0x01;
+ } $? ". packages marked as used"
+ }
+ }
+ } else { $? "! no range found"
+ }
+ }
+ if (NULL != prange) { $? ". range found"
+ if (NULL != prange->dir) { $? ". range has dir entry"
+ if (0x00 == (prange->dir)->loaded) { $? ". must load"
+ dk3uc2lat_load_file(u, prange->dir);
+ }
+ }
+ if (0 != ismath) { $? ". math mode"
+ if (NULL != prange->m) { $? ". math"
+ back = (prange->m)[(size_t)(c32 - prange->start)];
+ }
+ if (NULL == back) {
+ if (NULL != prange->a) { $? ". all"
+ back = (prange->a)[(size_t)(c32 - prange->start)];
+ }
+ }
+ } else { $? ". normal mode"
+ if (NULL != prange->t) { $? ". text"
+ back = (prange->t)[(size_t)(c32 - prange->start)];
+ }
+ if (NULL == back) { $? ". all"
+ if (NULL != prange->a) {
+ back = (prange->a)[(size_t)(c32 - prange->start)];
+ }
+ }
+ }
+ if (NULL != prange->f) {
+ u->fe &= ((prange->f)[(size_t)(c32 - prange->start)]);
+ }
+ } else {
+ /* ERROR: Not found */
+ if (0 != dk3ma_um_to_hex_string(cbuf, szcbuf, (dk3_um_t)c32, 8)) {
+ dk3app_log_i3(u->app, DK3_LL_ERROR, 409, 410, cbuf);
+ } else {
+ dk3app_log_i1(u->app, DK3_LL_ERROR, 408);
+ }
+ }
+ } $? "- dk3uc2lat_get PTR:%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+#if HAVE_PACKAGES
+
+void
+dk3uc2lat_package_reset(dk3_uc2lat_t *u)
+{
+ if (NULL != u) {
+ dk3sto_it_reset(u->i_pkg);
+ }
+}
+
+
+
+dk3_uc2lat_pkg_t *
+dk3uc2lat_package_next(dk3_uc2lat_t *u)
+{
+ dk3_uc2lat_pkg_t *back = NULL;
+ if (NULL != u) {
+ back = (dk3_uc2lat_pkg_t *)dk3sto_it_next(u->i_pkg);
+ }
+ return back;
+}
+
+#endif
+
+
+
+void
+dk3uc2lat_font_encoding_reset(dk3_uc2lat_t *u)
+{
+ /* UNUSED */
+}
+
+
+
+int
+dk3uc2lat_font_encoding_conflict(dk3_uc2lat_t *u)
+{
+ int back = 0;
+ /* UNUSED */
+ return back;
+}
+
+
+
+void
+dk3uc2lat_font_encoding_report_conflict(dk3_uc2lat_t *u)
+{
+ if (0x00 == u->fe) {
+ /* Error */
+ dk3app_log_i1(u->app, DK3_LL_ERROR, 411);
+ }
+}
+
+
+
+static
+void
+dk3uc2lat_report_for_encoding(dk3_uc2lat_t *u, const char *eptr)
+{
+#if DK3_CHAR_SIZE > 1
+ dkChar buffer[32];
+ dkChar *dkptr = NULL;
+ size_t szbu = DK3_SIZEOF(buffer,dkChar);
+ if (szbu > strlen(eptr)) {
+ dkptr = buffer;
+ while ('\0' != *eptr) {
+ *(dkptr++) = (dkChar)(*(eptr++));
+ }
+ *dkptr = dkT('\0');
+ dk3app_log_i3(u->app, DK3_LL_INFO, 381, 382, buffer);
+ }
+#else
+ dk3app_log_i3(u->app, DK3_LL_INFO, 381, 382, eptr);
+#endif
+}
+
+
+
+void
+dk3uc2lat_font_encoding_report(dk3_uc2lat_t *u)
+{
+ if (0 != ((u->fe) & DK3_FONT_ENCODING_OT1)) {
+ dk3uc2lat_report_for_encoding(u, dk3uc2l_enco[0]);
+ }
+ if (0 != ((u->fe) & DK3_FONT_ENCODING_T1)) {
+ dk3uc2lat_report_for_encoding(u, dk3uc2l_enco[1]);
+ }
+ if (0 != ((u->fe) & DK3_FONT_ENCODING_T4)) {
+ dk3uc2lat_report_for_encoding(u, dk3uc2l_enco[2]);
+ }
+ if (0 != ((u->fe) & DK3_FONT_ENCODING_T5)) {
+ dk3uc2lat_report_for_encoding(u, dk3uc2l_enco[3]);
+ }
+}
+
+
+
+int
+dk3uc2lat_direct(dk3_c32_t c32)
+{
+ int back = 0;
+ char c; /* 8-bit character version of c32. */
+ $? "+ dk3uc2lat_direct %lx", (unsigned long)c32
+ if((unsigned long)c32 < 128UL) {
+ c = (char)c32;
+ switch(c) {
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
+ case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
+ case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u':
+ case 'v': case 'w': case 'x': case 'y': case 'z': case 'A': case 'B':
+ case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I':
+ case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P':
+ case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W':
+ case 'X': case 'Y': case 'Z': case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7': case '8': case '9': case ',':
+ case '.': case ':': case ';': case '+': case '-': case '?': case '!':
+ case '|': case '@': case '(': case ')': case '/': case '=': case ' ':
+ case '\t':
+ {
+ back = 1;
+ }
+ break;
+ }
+ } $? "- dk3uc2lat_direct %d", back
+ return back;
+}
+
+
+
+static
+int
+dk3uc2lat_stputc(dk3_uc2lat_t *u, dk3_stream_t *st, dk3_c32_t ul, int *mmptr)
+{
+ char buf[16];
+ const char *ptr;
+ size_t sz;
+ int back = 0;
+
+ if (0 != dk3uc2lat_direct(ul)) {
+ if (0 != *mmptr) {
+ dk3stream_c8_fputs(st, dk3uc2lat_mm[1]);
+ *mmptr = 0;
+ }
+ if (u->f_utf8) {
+ sz = dk3enc_uc2utf8(ul, (unsigned char *)buf, sizeof(buf));
+ buf[sz] = '\0';
+ } else {
+ buf[0] = (char)ul;
+ buf[1] = '\0';
+ }
+ dk3stream_c8_fputs(st, buf);
+ back = 1;
+ } else {
+ ptr = dk3uc2lat_get(u, ul, 0);
+ if (NULL != ptr) {
+ if (0 != *mmptr) {
+ dk3stream_c8_fputs(st, dk3uc2lat_mm[1]);
+ *mmptr = 0;
+ }
+ dk3stream_c8_fputs(st, ptr);
+ } else {
+ ptr = dk3uc2lat_get(u, ul, 1);
+ if (NULL != ptr) {
+ if (0 == *mmptr) {
+ dk3stream_c8_fputs(st, dk3uc2lat_mm[0]);
+ *mmptr = 1;
+ }
+ dk3stream_c8_fputs(st, ptr);
+ } else {
+ /* ERROR: Not found, already reported */
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3uc2lat_c8_plain_stputs(dk3_uc2lat_t *u, dk3_stream_t *st, char const *t)
+{
+ int back = 0;
+ int mm = 0; /* Flag: In math mode. */
+ char const *ptr; /* Current position. */
+ dk3_c32_t ul; /* Output character. */
+ char c; /* Current character. */
+ $? "+ dk3uc2lat_c8_plain_stputs \"%!8s\"", TR_8STR(t)
+ if((u) && (st) && (t)) {
+ ptr = t; back = 1;
+ while(*ptr) {
+ c = *ptr;
+ ul = (unsigned long)c;
+ ul &= 0x000000FFUL;
+ if(!dk3uc2lat_stputc(u, st, ul, &mm)) { back = 0; }
+ ptr++;
+ }
+ if(mm) {
+ dk3stream_c8_fputs(st, dk3uc2lat_mm[1]);
+ }
+ }
+ $? "- dk3uc2lat_c8_plain_stputs %d", back
+ return back;
+}
+
+
+
+int
+dk3uc2lat_c8_utf8_stputs(dk3_uc2lat_t *u, dk3_stream_t *st, char const *t)
+{
+ int back = 0;
+ int mm = 0; /* Flag: Math mode. */
+ unsigned char const *sp; /* String pointer, current pos. */
+ size_t sl; /* Remaining bytes. */
+ size_t used; /* Bytes used for current c32. */
+ dk3_c32_t c32; /* Current character. */
+ $? "+ dk3uc2lat_c8_utf8_stputs \"%!8s\"", TR_8STR(t)
+ if((u) && (st) && (t)) {
+ sp = (unsigned char const *)t; sl = dk3str_c8_len(t); back = 1;
+ while(sl) {
+ used = 0;
+ if(dk3enc_utf82uc(&c32, sp, sl, &used)) {
+ if(!dk3uc2lat_stputc(u, st, c32, &mm)) {
+ back = 0;
+ }
+ if(used) {
+ if(sl >= used) {
+ sl = sl - used;
+ sp = &(sp[used]);
+ } else {
+ sl = 0; back = 0;
+ }
+ } else {
+ sl = 0; back = 0; /* No byte used, will appear again and again. */
+ }
+ } else {
+ sl = 0; back = 0;
+ if(u->app) {
+ /* ERROR: Decoding failed! */
+ dk3app_log_i1(u->app, DK3_LL_ERROR, 118);
+ }
+ }
+ }
+ if(mm) {
+ dk3stream_c8_fputs(st, dk3uc2lat_mm[1]);
+ }
+ }
+ $? "- dk3uc2lat_c8_utf8_stputs %d", back
+ return back;
+}
+
+
+
+int
+dk3uc2lat_c16_stputs(dk3_uc2lat_t *u, dk3_stream_t *st, dk3_c16_t const *t)
+{
+ int back = 0;
+ int mm = 0; /* Flag: Math mode. */
+ dk3_c16_t const *sp; /* Current position. */
+ size_t sl; /* Number of 16-bit characters remaining. */
+ size_t used; /* Number of 16-bit characters used. */
+ dk3_c32_t c32; /* Current output character. */
+ $? "+ dk3uc2lat_c16_stputs %!8s", TR_8PTR(t)
+ if((u) && (st) && (t)) {
+ sp = t; sl = dk3str_c16_len(t); back = 1;
+ while(sl) {
+ used = 0;
+ if(dk3enc_utf162uc(&c32, sp, sl, &used)) {
+ if(used) {
+ if(!dk3uc2lat_stputc(u, st, c32, &mm)) { back = 0; }
+ if(sl >= used) {
+ sl = sl - used;
+ sp = &(sp[used]);
+ } else {
+ sl = 0;
+ }
+ } else {
+ back = 0; sl = 0;
+ if(u->app) {
+ /* ERROR: Decoding */
+ dk3app_log_i1(u->app, DK3_LL_ERROR, 119);
+ }
+ }
+ } else {
+ sl = 0; back = 0;
+ if(u->app) {
+ /* Decoding error */
+ dk3app_log_i1(u->app, DK3_LL_ERROR, 119);
+ }
+ }
+ }
+ if(mm) {
+ dk3stream_c8_fputs(st, dk3uc2lat_mm[1]);
+ }
+ }
+ $? "- dk3uc2lat_c16_stputs %d", back
+ return back;
+}
+
+
+
+int
+dk3uc2lat_c32_stputs(dk3_uc2lat_t *u, dk3_stream_t *st, dk3_c32_t const *t)
+{
+ int back = 0;
+ int mm = 0; /* Flag: Math mode. */
+ dk3_c32_t const *ptr; /* Current position. */
+ $? "+ dk3uc2lat_c32_stputs %!8s", TR_8PTR(t)
+ if((u) && (st) && (t)) {
+ back = 1;
+ ptr = t;
+ while(*ptr) {
+ if(!dk3uc2lat_stputc(u, st, *(ptr++), &mm)) {
+ back = 0;
+ }
+ }
+ if(mm) {
+ dk3stream_c8_fputs(st, dk3uc2lat_mm[1]);
+ }
+ }
+ $? "- dk3uc2lat_c32_stputs %d", back
+ return back;
+}
+
+
+
+int
+dk3uc2lat_stputs(dk3_uc2lat_t *u, dk3_stream_t *st, dkChar const *t, int e)
+{
+ int back = 0;
+ $? "+ dk3uc2lat_stputs \"%!ds\"", TR_STR(t)
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ back = dk3uc2lat_c32_stputs(u, st, t);
+#else
+ back = dk3uc2lat_c16_stputs(u, st, t);
+#endif
+#else
+ switch(e) {
+ case DK3_ENCODING_UTF8: {
+ back = dk3uc2lat_c8_utf8_stputs(u, st, t);
+ } break;
+ default: {
+ back = dk3uc2lat_c8_plain_stputs(u, st, t);
+ } break;
+ }
+#endif
+ $? "- dk3uc2lat_stputs %d", back
+ return back;
+}
+
+
+
+void
+dk3uc2lat_final_report(dk3_uc2lat_t *u, dk3_stream_t *st)
+{
+ dk3_uc2lat_pkg_t *pkgp;
+ dk3stream_c8_fputs(st, dk3uc2lat_mm[2]);
+ if (0 != ((u->fe) & DK3_FONT_ENCODING_OT1)) {
+ dk3stream_c8_fputs(st, dk3uc2l_c8_font_encoding_names[0]);
+ }
+ if (0 != ((u->fe) & DK3_FONT_ENCODING_T1)) {
+ dk3stream_c8_fputs(st, dk3uc2l_c8_font_encoding_names[1]);
+ }
+ if (0 != ((u->fe) & DK3_FONT_ENCODING_T4)) {
+ dk3stream_c8_fputs(st, dk3uc2l_c8_font_encoding_names[2]);
+ }
+ if (0 != ((u->fe) & DK3_FONT_ENCODING_T5)) {
+ dk3stream_c8_fputs(st, dk3uc2l_c8_font_encoding_names[3]);
+ }
+ dk3stream_c8_fputs(st, dk3uc2lat_mm[4]);
+ dk3uc2lat_package_reset(u);
+ do {
+ pkgp = dk3uc2lat_package_next(u);
+ if (NULL != pkgp) {
+ $!trace-code if (NULL != pkgp->name) {
+ $!trace-code if (0x00 != pkgp->used) {
+ $? ". pkg used %!8s", pkgp->name
+ $!trace-code } else {
+ $? ". pkg not used %!8s", pkgp->name
+ $!trace-code }
+ $!trace-code }
+ if ((0x00 != pkgp->used) && (NULL != pkgp->name)) {
+ dk3stream_c8_fputs(st, dk3uc2lat_mm[3]);
+ dk3stream_c8_fputs(st, pkgp->name);
+ dk3stream_c8_fputs(st, dk3uc2lat_mm[4]);
+ }
+ }
+ } while (NULL != pkgp);
+}
+
+
+
+/* vim: set ai sw=2 : */
diff --git a/support/dktools/dk3uc2l.h b/support/dktools/dk3uc2l.h
new file mode 100644
index 0000000000..2331e88d66
--- /dev/null
+++ b/support/dktools/dk3uc2l.h
@@ -0,0 +1,194 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3uc2l.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK3UC2L_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3UC2L_H_INCLUDED 1
+
+
+#line 10 "dk3uc2l.ctr"
+
+/** @file dk3uc2l.h 32-bit character to LaTeX conversion.
+
+This module was rewritten in August 2015, so it uses the same *.t2l files
+as the dk4uc2l module.
+During this rewrite the functionality was stripped down to those functions
+used by the itadmin program.
+
+*/
+
+#include "dk3conf.h"
+#include "dk3types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open LaTeX encoder.
+ @param d Directory containing the tables.
+ @param f_desc Flag: Attempt to load glyph descriptions.
+ @param f_utf8 Flag: UTF-8 output encoding.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new encoder on success, NULL on error.
+*/
+dk3_uc2lat_t *
+dk3uc2lat_open_app(dkChar const *d, int f_desc, int f_utf8, dk3_app_t *app);
+
+/** Close LaTeX encoder.
+ @param u Encoder to close.
+*/
+void
+dk3uc2lat_close(dk3_uc2lat_t *u);
+
+/** Retrieve LaTeX encoding for one 32-bit character.
+ @param u LaTeX encoder.
+ @param c32 Character to obtain LaTeX encoding for.
+ @param ismath Flag: In math mode.
+ @return Pointer to encoding on success, NULL on error.
+*/
+char const *
+dk3uc2lat_get(dk3_uc2lat_t *u, dk3_c32_t c32, int ismath);
+
+/** Check whether a character can be written to a LaTeX file directly.
+ @param c32 Character to check.
+ @return 1 for yes, 0 for no.
+*/
+int
+dk3uc2lat_direct(dk3_c32_t c32);
+
+/** Write LaTeX encoding for a string to a stream.
+ @param u LaTeX encoder.
+ @param st Stream to write to.
+ @param t Text to write (ASCII/ISO-LATIN-1 encoded).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3uc2lat_c8_plain_stputs(dk3_uc2lat_t *u, dk3_stream_t *st, char const *t);
+
+/** Write LaTeX encoding for a string to a stream.
+ @param u LaTeX encoder.
+ @param st Stream to write to.
+ @param t Text to write (UTF-8 encoded).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3uc2lat_c8_utf8_stputs(dk3_uc2lat_t *u, dk3_stream_t *st, char const *t);
+
+/** Write LaTeX encoding for a string to a stream.
+ @param u LaTeX encoder.
+ @param st Stream to write to.
+ @param t Text to write (UTF-16 encoded).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3uc2lat_c16_stputs(dk3_uc2lat_t *u, dk3_stream_t *st, dk3_c16_t const *t);
+
+/** Write LaTeX encoding for a string to a stream.
+ @param u LaTeX encoder.
+ @param st Stream to write to.
+ @param t Text to write (32-bit characters).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3uc2lat_c32_stputs(dk3_uc2lat_t *u, dk3_stream_t *st, dk3_c32_t const *t);
+
+/** Write LaTeX encoding for a string to a stream.
+ @param u LaTeX encoder.
+ @param st Stream to write to.
+ @param t Text to write (dkChar characters).
+ @param e Encoding (only used for 8-bit characters).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3uc2lat_stputs(dk3_uc2lat_t *u, dk3_stream_t *st, dkChar const *t, int e);
+
+#if HAVE_PACKAGES
+
+/** Prepare LaTeX encoder to retrieve package information.
+ @param u LaTeX encoder.
+*/
+void
+dk3uc2lat_package_reset(dk3_uc2lat_t *u);
+
+/** Retrieve next package information from LaTeX encoder.
+ @param u LaTeX encoder.
+ @return Pointer to next package information or NULL.
+*/
+dk3_uc2lat_pkg_t *
+dk3uc2lat_package_next(dk3_uc2lat_t *u);
+
+#endif
+
+/** Reset font encoding information.
+ @param u LaTeX encoder.
+*/
+void
+dk3uc2lat_font_encoding_reset(dk3_uc2lat_t *u);
+
+/** Check for font encoding conflicts.
+ @param u LaTeX encoder.
+ @return 1 on conflicts, 0 otherwise (no problems).
+*/
+int
+dk3uc2lat_font_encoding_conflict(dk3_uc2lat_t *u);
+
+/** Report font encoding requirement conflicts.
+ @param u LaTeX encoder.
+*/
+void
+dk3uc2lat_font_encoding_report_conflict(dk3_uc2lat_t *u);
+
+/** Report font encoding requirement conflicts.
+ @param u LaTeX encoder.
+*/
+void
+dk3uc2lat_font_encoding_report(dk3_uc2lat_t *u);
+
+/** Write some final comments to output stream about
+ usable encdings and required packages.
+ @param u LaTeX encoder.
+ @param st Output stream.
+*/
+void
+dk3uc2lat_final_report(dk3_uc2lat_t *u, dk3_stream_t *st);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3ufi.c b/support/dktools/dk3ufi.c
new file mode 100644
index 0000000000..9ece4051a9
--- /dev/null
+++ b/support/dktools/dk3ufi.c
@@ -0,0 +1,438 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3ufi.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3ufi.c The dk3ufi module.
+*/
+
+
+#line 82 "dk3ufi.ctr"
+
+#include "dk3all.h"
+#include "dk3ufi.h"
+
+
+
+
+
+#line 89 "dk3ufi.ctr"
+
+
+
+int
+dk3ufi_get_app(dk3_ufi_t *pd, dkChar const *fn, dk3_app_t *app)
+{
+#if DK3_ON_WINDOWS
+ BY_HANDLE_FILE_INFORMATION bhfi;
+#endif
+ dk3_stat_t stb;
+#if DK3_ON_WINDOWS
+ HANDLE hFile;
+ int i;
+#endif
+ int back = 0;
+
+
+#line 105 "dk3ufi.ctr"
+ if((pd) && (fn)) {
+ if(dk3sf_stat_app(&stb, fn, app)) {
+ switch(stb.ft & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_REGULAR: {
+#if DK3_ON_WINDOWS
+ for(i = 0; ((i < 2) && (0 == back)); i++) {
+#if DK3_CHAR_SIZE > 2
+ hFile = INVALID_HANDLE_VALUE;
+#else
+#if DK3_CHAR_SIZE > 1
+
+
+#line 116 "dk3ufi.ctr"
+ hFile = CreateFileW(
+ fn,
+ ((0 == i) ? (FILE_READ_ATTRIBUTES) : 0),
+ (FILE_SHARE_READ),
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL
+ );
+#else
+
+
+#line 127 "dk3ufi.ctr"
+ hFile = CreateFileA(
+ fn,
+ ((0 == i) ? (FILE_READ_ATTRIBUTES) : 0),
+ (FILE_SHARE_READ),
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL
+ );
+#endif
+#endif
+ if(INVALID_HANDLE_VALUE != hFile) {
+ if(GetFileInformationByHandle(hFile, &bhfi)) {
+ back = 1;
+
+#line 141 "dk3ufi.ctr"
+ i = 2;
+ pd->volser = bhfi.dwVolumeSerialNumber;
+ pd->indhigh = bhfi.nFileIndexHigh;
+ pd->indlow = bhfi.nFileIndexLow;
+ } else {
+ /* ERROR: Failed to obtain file information! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 366, 367, fn);
+ }
+ CloseHandle(hFile); hFile = INVALID_HANDLE_VALUE;
+ } else {
+ /* ERROR: Failed to obtain file information! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 366, 367, fn);
+ }
+ }
+#else
+ pd->device = stb.device;
+ pd->inode = stb.inode;
+ back = 1;
+#endif
+ } break;
+ case DK3_FT_DIRECTORY: {
+
+#line 162 "dk3ufi.ctr"
+#if DK3_ON_WINDOWS
+ for(i = 0; ((i < 2) && (0 == back)); i++) {
+#if DK3_CHAR_SIZE > 2
+ hFile = INVALID_HANDLE_VALUE;
+#else
+#if DK3_CHAR_SIZE > 1
+
+
+#line 169 "dk3ufi.ctr"
+ hFile = CreateFileW(
+ fn,
+ ((0 == i) ? (FILE_READ_ATTRIBUTES) : 0),
+ (FILE_SHARE_READ),
+ NULL,
+ OPEN_EXISTING,
+ (FILE_ATTRIBUTE_DIRECTORY | FILE_FLAG_BACKUP_SEMANTICS),
+ NULL
+ );
+#else
+
+
+#line 180 "dk3ufi.ctr"
+ hFile = CreateFileA(
+ fn,
+ ((0 == i) ? (FILE_READ_ATTRIBUTES) : 0),
+ (FILE_SHARE_READ),
+ NULL,
+ OPEN_EXISTING,
+ (FILE_ATTRIBUTE_DIRECTORY | FILE_FLAG_BACKUP_SEMANTICS),
+ NULL
+ );
+#endif
+#endif
+ if(INVALID_HANDLE_VALUE != hFile) {
+ if(GetFileInformationByHandle(hFile, &bhfi)) {
+ back = 1;
+
+#line 194 "dk3ufi.ctr"
+ i = 2;
+ pd->volser = bhfi.dwVolumeSerialNumber;
+ pd->indhigh = bhfi.nFileIndexHigh;
+ pd->indlow = bhfi.nFileIndexLow;
+ } else {
+
+#line 199 "dk3ufi.ctr"
+ /* ERROR: Failed to obtain file information! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 366, 367, fn);
+ }
+ CloseHandle(hFile); hFile = INVALID_HANDLE_VALUE;
+ } else {
+
+#line 204 "dk3ufi.ctr"
+ /* ERROR: Failed to obtain file information */
+ dk3app_log_i3(app, DK3_LL_ERROR, 366, 367, fn);
+ }
+ }
+#else
+ pd->device = stb.device;
+ pd->inode = stb.inode;
+ back = 1;
+#endif
+ } break;
+ default: {
+
+#line 215 "dk3ufi.ctr"
+ } break;
+ }
+ } else {
+
+#line 218 "dk3ufi.ctr"
+ }
+ } else {
+
+#line 220 "dk3ufi.ctr"
+ }
+
+#line 221 "dk3ufi.ctr"
+ return back;
+}
+
+
+
+int
+dk3ufi_c8_get_app(dk3_ufi_t *pd, char const *fn, dk3_app_t *app)
+{
+#if DK3_ON_WINDOWS
+ BY_HANDLE_FILE_INFORMATION bhfi;
+#endif
+ dk3_stat_t stb;
+#if DK3_ON_WINDOWS
+ HANDLE hFile;
+ int i;
+#endif
+ int back = 0;
+
+
+#line 239 "dk3ufi.ctr"
+ if((pd) && (fn)) {
+ if(dk3sf_c8_stat_app(&stb, fn, app)) {
+ switch(stb.ft & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_REGULAR: {
+#if DK3_ON_WINDOWS
+ for(i = 0; ((i < 2) && (0 == back)); i++) {
+
+
+#line 246 "dk3ufi.ctr"
+ hFile = CreateFileA(
+ fn,
+ ((0 == i) ? (FILE_READ_ATTRIBUTES) : 0),
+ (FILE_SHARE_READ),
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL
+ );
+ if(INVALID_HANDLE_VALUE != hFile) {
+ if(GetFileInformationByHandle(hFile, &bhfi)) {
+ back = 1;
+
+#line 258 "dk3ufi.ctr"
+ i = 2;
+ pd->volser = bhfi.dwVolumeSerialNumber;
+ pd->indhigh = bhfi.nFileIndexHigh;
+ pd->indlow = bhfi.nFileIndexLow;
+ } else {
+ /* ERROR: Failed to obtain file information! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 366, 367, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 368);
+#endif
+ }
+ CloseHandle(hFile); hFile = INVALID_HANDLE_VALUE;
+ } else {
+ /* ERROR: Failed to obtain file information! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 366, 367, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 368);
+#endif
+ }
+ }
+#else
+ pd->device = stb.device;
+ pd->inode = stb.inode;
+ back = 1;
+#endif
+ } break;
+ case DK3_FT_DIRECTORY: {
+
+#line 287 "dk3ufi.ctr"
+#if DK3_ON_WINDOWS
+ for(i = 0; ((i < 2) && (0 == back)); i++) {
+
+
+#line 290 "dk3ufi.ctr"
+ hFile = CreateFileA(
+ fn,
+ ((0 == i) ? (FILE_READ_ATTRIBUTES) : 0),
+ (FILE_SHARE_READ),
+ NULL,
+ OPEN_EXISTING,
+ (FILE_ATTRIBUTE_DIRECTORY | FILE_FLAG_BACKUP_SEMANTICS),
+ NULL
+ );
+ if(INVALID_HANDLE_VALUE != hFile) {
+ if(GetFileInformationByHandle(hFile, &bhfi)) {
+ back = 1;
+
+#line 302 "dk3ufi.ctr"
+ i = 2;
+ pd->volser = bhfi.dwVolumeSerialNumber;
+ pd->indhigh = bhfi.nFileIndexHigh;
+ pd->indlow = bhfi.nFileIndexLow;
+ } else {
+
+#line 307 "dk3ufi.ctr"
+ /* ERROR: Failed to obtain file information! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 366, 367, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 368);
+#endif
+ }
+ CloseHandle(hFile); hFile = INVALID_HANDLE_VALUE;
+ } else {
+
+#line 316 "dk3ufi.ctr"
+ /* ERROR: Failed to obtain file information! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 366, 367, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 368);
+#endif
+ }
+ }
+#else
+ pd->device = stb.device;
+ pd->inode = stb.inode;
+ back = 1;
+#endif
+ } break;
+ default: {
+
+#line 331 "dk3ufi.ctr"
+ } break;
+ }
+ } else {
+
+#line 334 "dk3ufi.ctr"
+ }
+ } else {
+
+#line 336 "dk3ufi.ctr"
+ }
+
+#line 337 "dk3ufi.ctr"
+
+
+#line 338 "dk3ufi.ctr"
+ return back;
+}
+
+
+
+int
+dk3ufi_get(dk3_ufi_t *pd, dkChar const *fn)
+{
+ int back;
+ back = dk3ufi_get_app(pd, fn, NULL);
+ return back;
+}
+
+
+
+int
+dk3ufi_c8_get(dk3_ufi_t *pd, char const *fn)
+{
+ int back;
+ back = dk3ufi_c8_get_app(pd, fn, NULL);
+ return back;
+}
+
+
+
+int
+dk3ufi_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3_ufi_t const *pl;
+ dk3_ufi_t const *pr;
+ if(l) {
+ if(r) {
+ pl = (dk3_ufi_t const *)l; pr = (dk3_ufi_t const *)r;
+#if DK3_ON_WINDOWS
+ if(pl->volser < pr->volser) {
+ back = -1;
+ } else {
+ if(pl->volser > pr->volser) {
+ back = 1;
+ }
+ }
+ if(0 == back) {
+ if(pl->indhigh < pr->indhigh) {
+ back = -1;
+ } else {
+ if(pl->indhigh > pr->indhigh) {
+ back = 1;
+ }
+ }
+ }
+ if(0 == back) {
+ if(pl->indlow < pr->indlow) {
+ back = -1;
+ } else {
+ if(pl->indlow > pr->indlow) {
+ back = 1;
+ }
+ }
+ }
+#else
+ if(pl->device < pr->device) {
+ back = -1;
+ } else {
+ if(pl->device > pr->device) {
+ back = 1;
+ }
+ }
+ if(0 == back) {
+ if(pl->inode < pr->inode) {
+ back = -1;
+ } else {
+ if(pl->inode > pr->inode) {
+ back = 1;
+ }
+ }
+ }
+#endif
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk3ufi.ctr b/support/dktools/dk3ufi.ctr
new file mode 100644
index 0000000000..fad652192e
--- /dev/null
+++ b/support/dktools/dk3ufi.ctr
@@ -0,0 +1,423 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+
+%% header
+
+#include "dk3types.h"
+
+/** Unique file identifier.
+ If two files produce the same UFI they are both links
+ to the same file or different file name notations
+ pointing to the same file, i.e. "x.txt" and "./x.txt".
+*/
+typedef struct {
+#if DK3_ON_WINDOWS
+ DWORD volser; /**< Volume serial number. */
+ DWORD indhigh; /**< Higner index part. */
+ DWORD indlow; /**< Lower index part. */
+#else
+ dk3_um_t device; /**< Device number. */
+ dk3_um_t inode; /**< Inode number. */
+#endif
+} dk3_ufi_t;
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Obtain unique identifier for file.
+ @param pd Result buffer pointer.
+ @param fn File name to check.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3ufi_get_app(dk3_ufi_t *pd, dkChar const *fn, dk3_app_t *app);
+
+/** Obtain unique identifier for file.
+ @param pd Result buffer pointer.
+ @param fn File name to check (8-bit character string).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3ufi_c8_get_app(dk3_ufi_t *pd, char const *fn, dk3_app_t *app);
+
+/** Obtain unique identifier for file.
+ @param pd Result buffer pointer.
+ @param fn File name to check.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3ufi_get(dk3_ufi_t *pd, dkChar const *fn);
+
+/** Obtain unique identifier for file.
+ @param pd Result buffer pointer.
+ @param fn File name to check (8-bit character string).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3ufi_c8_get(dk3_ufi_t *pd, char const *fn);
+
+/** Compare two file identifiers.
+ @param l Left identifier.
+ @param r Right identifier.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+int
+dk3ufi_compare(void const *l, void const *r, int cr);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk3all.h"
+#include "dk3ufi.h"
+
+
+
+$!trace-include
+
+
+
+int
+dk3ufi_get_app(dk3_ufi_t *pd, dkChar const *fn, dk3_app_t *app)
+{
+#if DK3_ON_WINDOWS
+ BY_HANDLE_FILE_INFORMATION bhfi;
+#endif
+ dk3_stat_t stb;
+#if DK3_ON_WINDOWS
+ HANDLE hFile;
+ int i;
+#endif
+ int back = 0;
+ $? "+ dk3ufi_get_app \"%!ds\"", TR_STR(fn)
+ if((pd) && (fn)) {
+ if(dk3sf_stat_app(&stb, fn, app)) {
+ switch(stb.ft & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_REGULAR: {
+#if DK3_ON_WINDOWS
+ for(i = 0; ((i < 2) && (0 == back)); i++) {
+#if DK3_CHAR_SIZE > 2
+ hFile = INVALID_HANDLE_VALUE;
+#else
+#if DK3_CHAR_SIZE > 1
+ $? ". wide \"%ls\"", fn
+ hFile = CreateFileW(
+ fn,
+ ((0 == i) ? (FILE_READ_ATTRIBUTES) : 0),
+ (FILE_SHARE_READ),
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL
+ );
+#else
+ $? ". ascii"
+ hFile = CreateFileA(
+ fn,
+ ((0 == i) ? (FILE_READ_ATTRIBUTES) : 0),
+ (FILE_SHARE_READ),
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL
+ );
+#endif
+#endif
+ if(INVALID_HANDLE_VALUE != hFile) {
+ if(GetFileInformationByHandle(hFile, &bhfi)) {
+ back = 1; $? ". success %d", i
+ i = 2;
+ pd->volser = bhfi.dwVolumeSerialNumber;
+ pd->indhigh = bhfi.nFileIndexHigh;
+ pd->indlow = bhfi.nFileIndexLow;
+ } else {
+ /* ERROR: Failed to obtain file information! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 366, 367, fn);
+ }
+ CloseHandle(hFile); hFile = INVALID_HANDLE_VALUE;
+ } else {
+ /* ERROR: Failed to obtain file information! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 366, 367, fn);
+ }
+ }
+#else
+ pd->device = stb.device;
+ pd->inode = stb.inode;
+ back = 1;
+#endif
+ } break;
+ case DK3_FT_DIRECTORY: { $? ". directory"
+#if DK3_ON_WINDOWS
+ for(i = 0; ((i < 2) && (0 == back)); i++) {
+#if DK3_CHAR_SIZE > 2
+ hFile = INVALID_HANDLE_VALUE;
+#else
+#if DK3_CHAR_SIZE > 1
+ $? ". wide \"%ls\"", fn
+ hFile = CreateFileW(
+ fn,
+ ((0 == i) ? (FILE_READ_ATTRIBUTES) : 0),
+ (FILE_SHARE_READ),
+ NULL,
+ OPEN_EXISTING,
+ (FILE_ATTRIBUTE_DIRECTORY | FILE_FLAG_BACKUP_SEMANTICS),
+ NULL
+ );
+#else
+ $? ". ascii"
+ hFile = CreateFileA(
+ fn,
+ ((0 == i) ? (FILE_READ_ATTRIBUTES) : 0),
+ (FILE_SHARE_READ),
+ NULL,
+ OPEN_EXISTING,
+ (FILE_ATTRIBUTE_DIRECTORY | FILE_FLAG_BACKUP_SEMANTICS),
+ NULL
+ );
+#endif
+#endif
+ if(INVALID_HANDLE_VALUE != hFile) {
+ if(GetFileInformationByHandle(hFile, &bhfi)) {
+ back = 1; $? ". success %d", i
+ i = 2;
+ pd->volser = bhfi.dwVolumeSerialNumber;
+ pd->indhigh = bhfi.nFileIndexHigh;
+ pd->indlow = bhfi.nFileIndexLow;
+ } else { $? "! GetFile... %ld", (long)GetLastError()
+ /* ERROR: Failed to obtain file information! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 366, 367, fn);
+ }
+ CloseHandle(hFile); hFile = INVALID_HANDLE_VALUE;
+ } else { $? "! CreateFile %ld", (long)GetLastError()
+ /* ERROR: Failed to obtain file information */
+ dk3app_log_i3(app, DK3_LL_ERROR, 366, 367, fn);
+ }
+ }
+#else
+ pd->device = stb.device;
+ pd->inode = stb.inode;
+ back = 1;
+#endif
+ } break;
+ default: { $? "! not a regular file"
+ } break;
+ }
+ } else { $? "! stat"
+ }
+ } else { $? "! arguments"
+ } $? "- dk3ufi_get_app %d", back
+ return back;
+}
+
+
+
+int
+dk3ufi_c8_get_app(dk3_ufi_t *pd, char const *fn, dk3_app_t *app)
+{
+#if DK3_ON_WINDOWS
+ BY_HANDLE_FILE_INFORMATION bhfi;
+#endif
+ dk3_stat_t stb;
+#if DK3_ON_WINDOWS
+ HANDLE hFile;
+ int i;
+#endif
+ int back = 0;
+ $? "+ dk3ufi_c8_get_app %!8s", TR_8STR(fn)
+ if((pd) && (fn)) {
+ if(dk3sf_c8_stat_app(&stb, fn, app)) {
+ switch(stb.ft & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_REGULAR: {
+#if DK3_ON_WINDOWS
+ for(i = 0; ((i < 2) && (0 == back)); i++) {
+ $? ". ascii"
+ hFile = CreateFileA(
+ fn,
+ ((0 == i) ? (FILE_READ_ATTRIBUTES) : 0),
+ (FILE_SHARE_READ),
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL
+ );
+ if(INVALID_HANDLE_VALUE != hFile) {
+ if(GetFileInformationByHandle(hFile, &bhfi)) {
+ back = 1; $? ". success %d", i
+ i = 2;
+ pd->volser = bhfi.dwVolumeSerialNumber;
+ pd->indhigh = bhfi.nFileIndexHigh;
+ pd->indlow = bhfi.nFileIndexLow;
+ } else {
+ /* ERROR: Failed to obtain file information! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 366, 367, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 368);
+#endif
+ }
+ CloseHandle(hFile); hFile = INVALID_HANDLE_VALUE;
+ } else {
+ /* ERROR: Failed to obtain file information! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 366, 367, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 368);
+#endif
+ }
+ }
+#else
+ pd->device = stb.device;
+ pd->inode = stb.inode;
+ back = 1;
+#endif
+ } break;
+ case DK3_FT_DIRECTORY: { $? ". directory"
+#if DK3_ON_WINDOWS
+ for(i = 0; ((i < 2) && (0 == back)); i++) {
+ $? ". ascii"
+ hFile = CreateFileA(
+ fn,
+ ((0 == i) ? (FILE_READ_ATTRIBUTES) : 0),
+ (FILE_SHARE_READ),
+ NULL,
+ OPEN_EXISTING,
+ (FILE_ATTRIBUTE_DIRECTORY | FILE_FLAG_BACKUP_SEMANTICS),
+ NULL
+ );
+ if(INVALID_HANDLE_VALUE != hFile) {
+ if(GetFileInformationByHandle(hFile, &bhfi)) {
+ back = 1; $? ". success %d", i
+ i = 2;
+ pd->volser = bhfi.dwVolumeSerialNumber;
+ pd->indhigh = bhfi.nFileIndexHigh;
+ pd->indlow = bhfi.nFileIndexLow;
+ } else { $? "! GetFile... %ld", (long)GetLastError()
+ /* ERROR: Failed to obtain file information! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 366, 367, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 368);
+#endif
+ }
+ CloseHandle(hFile); hFile = INVALID_HANDLE_VALUE;
+ } else { $? "! CreateFile %ld", (long)GetLastError()
+ /* ERROR: Failed to obtain file information! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 366, 367, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 368);
+#endif
+ }
+ }
+#else
+ pd->device = stb.device;
+ pd->inode = stb.inode;
+ back = 1;
+#endif
+ } break;
+ default: { $? "! not a regular file"
+ } break;
+ }
+ } else { $? "! stat"
+ }
+ } else { $? "! arguments"
+ } $? "- dk3ufi_get_app %d", back
+ $? "- dk3ufi_c8_get_app %d", back
+ return back;
+}
+
+
+
+int
+dk3ufi_get(dk3_ufi_t *pd, dkChar const *fn)
+{
+ int back;
+ back = dk3ufi_get_app(pd, fn, NULL);
+ return back;
+}
+
+
+
+int
+dk3ufi_c8_get(dk3_ufi_t *pd, char const *fn)
+{
+ int back;
+ back = dk3ufi_c8_get_app(pd, fn, NULL);
+ return back;
+}
+
+
+
+int
+dk3ufi_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dk3_ufi_t const *pl;
+ dk3_ufi_t const *pr;
+ if(l) {
+ if(r) {
+ pl = (dk3_ufi_t const *)l; pr = (dk3_ufi_t const *)r;
+#if DK3_ON_WINDOWS
+ if(pl->volser < pr->volser) {
+ back = -1;
+ } else {
+ if(pl->volser > pr->volser) {
+ back = 1;
+ }
+ }
+ if(0 == back) {
+ if(pl->indhigh < pr->indhigh) {
+ back = -1;
+ } else {
+ if(pl->indhigh > pr->indhigh) {
+ back = 1;
+ }
+ }
+ }
+ if(0 == back) {
+ if(pl->indlow < pr->indlow) {
+ back = -1;
+ } else {
+ if(pl->indlow > pr->indlow) {
+ back = 1;
+ }
+ }
+ }
+#else
+ if(pl->device < pr->device) {
+ back = -1;
+ } else {
+ if(pl->device > pr->device) {
+ back = 1;
+ }
+ }
+ if(0 == back) {
+ if(pl->inode < pr->inode) {
+ back = -1;
+ } else {
+ if(pl->inode > pr->inode) {
+ back = 1;
+ }
+ }
+ }
+#endif
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk3ufi.h b/support/dktools/dk3ufi.h
new file mode 100644
index 0000000000..527914391d
--- /dev/null
+++ b/support/dktools/dk3ufi.h
@@ -0,0 +1,118 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3ufi.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3ufi.h Header file for the dk3ufi module.
+*/
+
+#ifndef DK3UFI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3UFI_H_INCLUDED 1
+
+
+#line 9 "dk3ufi.ctr"
+
+#include "dk3types.h"
+
+/** Unique file identifier.
+ If two files produce the same UFI they are both links
+ to the same file or different file name notations
+ pointing to the same file, i.e. "x.txt" and "./x.txt".
+*/
+typedef struct {
+#if DK3_ON_WINDOWS
+ DWORD volser; /**< Volume serial number. */
+ DWORD indhigh; /**< Higner index part. */
+ DWORD indlow; /**< Lower index part. */
+#else
+ dk3_um_t device; /**< Device number. */
+ dk3_um_t inode; /**< Inode number. */
+#endif
+} dk3_ufi_t;
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Obtain unique identifier for file.
+ @param pd Result buffer pointer.
+ @param fn File name to check.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3ufi_get_app(dk3_ufi_t *pd, dkChar const *fn, dk3_app_t *app);
+
+/** Obtain unique identifier for file.
+ @param pd Result buffer pointer.
+ @param fn File name to check (8-bit character string).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3ufi_c8_get_app(dk3_ufi_t *pd, char const *fn, dk3_app_t *app);
+
+/** Obtain unique identifier for file.
+ @param pd Result buffer pointer.
+ @param fn File name to check.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3ufi_get(dk3_ufi_t *pd, dkChar const *fn);
+
+/** Obtain unique identifier for file.
+ @param pd Result buffer pointer.
+ @param fn File name to check (8-bit character string).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3ufi_c8_get(dk3_ufi_t *pd, char const *fn);
+
+/** Compare two file identifiers.
+ @param l Left identifier.
+ @param r Right identifier.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+int
+dk3ufi_compare(void const *l, void const *r, int cr);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk3usewx.c b/support/dktools/dk3usewx.c
new file mode 100644
index 0000000000..56740b9e3b
--- /dev/null
+++ b/support/dktools/dk3usewx.c
@@ -0,0 +1,7 @@
+#ifdef DK3_USE_WX
+#undef DK3_USE_WX
+#endif
+/** Use wxWidgets libraries to build GUI programs.
+*/
+#define DK3_USE_WX 1
+
diff --git a/support/dktools/dk3wreg.c b/support/dktools/dk3wreg.c
new file mode 100644
index 0000000000..7dd8ee7d28
--- /dev/null
+++ b/support/dktools/dk3wreg.c
@@ -0,0 +1,782 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3wreg.ctr
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3wreg.c The dk3wreg module.
+*/
+
+
+#line 201 "dk3wreg.ctr"
+
+#include "dk3all.h"
+#include "dk3wreg.h"
+
+
+
+
+
+#line 208 "dk3wreg.ctr"
+
+
+
+#if DK3_ON_WINDOWS && ((2 == DK3_CHAR_SIZE) || (1 == DK3_CHAR_SIZE))
+
+
+
+static dkChar const * const dk3wreg_default_texts[] = {
+/* 0 */
+dkT("dk3wreg.str"),
+
+/* 1 */
+dkT("Failed to open registry key!"),
+
+/* 2 */
+dkT("Failed to open registry key:\n\""),
+
+/* 3 */
+dkT("\"!"),
+
+/* 4 */
+dkT("Failed to open or create registry key!"),
+
+/* 5 */
+dkT("Failed to open or create registry key:\n\""),
+
+/* 6 */
+dkT("\"!"),
+
+/* 7 */
+dkT("Failed to close registry key!"),
+
+/* 8 */
+dkT("Failed to close registry key:\n\""),
+
+/* 9 */
+dkT("\"!"),
+
+/* 10 */
+dkT("Failed to write registry entry!"),
+
+/* 11 */
+dkT("Failed to write registry entry:\n\""),
+
+/* 12 */
+dkT("\"!"),
+
+/* 13 */
+dkT("Failed to retrieve registry entry!"),
+
+/* 14 */
+dkT("Failed to retrieve registry entry:\n\""),
+
+/* 15 */
+dkT("\"!"),
+
+/* 16 */
+dkT("Registry entry is not a string!"),
+
+/* 17 */
+dkT("Registry entry is not a string:\n\""),
+
+/* 18 */
+dkT("\"!"),
+
+/* 19 */
+dkT("Registry entry is not a DWORD!"),
+
+/* 20 */
+dkT("Registry entry is not a DWORD:\n\""),
+
+/* 21 */
+dkT("\"!"),
+
+/* 22 */
+dkT("Registry entry is an incomplete DWORD!"),
+
+/* 23 */
+dkT("Registry entry is an incomplete DWORD:\n\""),
+
+/* 24 */
+dkT("\"!"),
+
+/* 25 */
+dkT("Failed to delete registry key tree!"),
+
+/* 26 */
+dkT("Failed to delete registry key tree:\n\""),
+
+/* 27 */
+dkT("\"!"),
+
+/* 28 */
+dkT("Failed to delete registry entry!"),
+
+/* 29 */
+dkT("Failed to delete registry entry:\n\""),
+
+/* 30 */
+dkT("\"!"),
+
+/* 31 */
+dkT("String to long for result buffer!"),
+
+/* 32 */
+dkT("Environment variable expansion failed!"),
+
+/* 33 */
+dkT("Can not delete registry keys when compiled for legacy versions!"),
+
+NULL
+
+
+#line 297 "dk3wreg.ctr"
+};
+
+
+
+static
+void
+dk3wreg_report_error(
+ dk3_app_t *app, dkChar const *n, size_t m1, size_t m2, size_t o
+)
+{
+ dkChar const * const *lmsg; /* Localized messages. */
+
+
+#line 309 "dk3wreg.ctr"
+ if(app) {
+ lmsg = dk3app_messages(
+ app, dk3wreg_default_texts[0], (dkChar const **)dk3wreg_default_texts
+ );
+ if(lmsg) {
+ if(n) {
+ dk3app_log_3(app, DK3_LL_ERROR, lmsg, m1, m2, n);
+ } else {
+ dk3app_log_1(app, DK3_LL_ERROR, lmsg, o);
+ }
+ }
+ }
+
+#line 321 "dk3wreg.ctr"
+}
+
+
+int
+dk3wreg_key_open_perms(
+ HKEY b, dkChar const *n, REGSAM p, HKEY *r, dk3_app_t *app
+)
+{
+ int back = 0;
+ long res;
+
+
+#line 332 "dk3wreg.ctr"
+ if((n) && (r)) {
+#if 2 == DK3_CHAR_SIZE
+ res = RegOpenKeyExW(
+ b, /* Base key. */
+ n, /* Subkey name. */
+ (DWORD)0UL, /* Reserviced. */
+ p, /* Required access. */
+ r /* Result pointer. */
+ );
+#else
+ res = RegOpenKeyExA(
+ b, /* Base key. */
+ n, /* Subkey name. */
+ (DWORD)0UL, /* Reserviced. */
+ p, /* Required access. */
+ r /* Result pointer. */
+ );
+#endif
+ if(ERROR_SUCCESS == res) {
+ back = 1;
+ } else {
+ /* ERROR: Failed to open key! */
+ dk3wreg_report_error(app, n, 2, 3, 1);
+ }
+ }
+
+#line 357 "dk3wreg.ctr"
+ return back;
+}
+
+
+
+int
+dk3wreg_key_open_read(HKEY b, dkChar const *n, HKEY *r, dk3_app_t *app)
+{
+ int back = 0;
+
+
+#line 367 "dk3wreg.ctr"
+ back = dk3wreg_key_open_perms(b, n, KEY_QUERY_VALUE, r, app);
+
+
+#line 369 "dk3wreg.ctr"
+ return back;
+}
+
+
+
+int
+dk3wreg_key_open_modify(HKEY b, dkChar const *n, HKEY *r, dk3_app_t *app)
+{
+ int back = 0;
+
+
+#line 379 "dk3wreg.ctr"
+ back = dk3wreg_key_open_perms(b, n, KEY_ALL_ACCESS, r, app);
+
+
+#line 381 "dk3wreg.ctr"
+ return back;
+}
+
+
+
+int
+dk3wreg_key_create_perms(HKEY b,dkChar const *n,REGSAM p,HKEY *r,dk3_app_t *app)
+{
+ int back = 0;
+ long res;
+ DWORD disp = (DWORD)0UL;
+
+
+#line 393 "dk3wreg.ctr"
+ if((n) && (r)) {
+#if 2 == DK3_CHAR_SIZE
+ res = RegCreateKeyExW(
+ b, /* Base key. */
+ n, /* Key name. */
+ (DWORD)0UL, /* Reserved. */
+ NULL, /* Key class. */
+ REG_OPTION_NON_VOLATILE, /* Options. */
+ p, /* SAM desired. */
+ NULL, /* Security descriptor. */
+ r, /* Result pointer. */
+ &disp /* Disposition. */
+ );
+#else
+ res = RegCreateKeyExA(
+ b, /* Base key. */
+ n, /* Key name. */
+ (DWORD)0UL, /* Reserved. */
+ NULL, /* Key class. */
+ REG_OPTION_NON_VOLATILE, /* Options. */
+ p, /* SAM desired. */
+ NULL, /* Security descriptor. */
+ r, /* Result pointer. */
+ &disp /* Disposition. */
+ );
+#endif
+ if(ERROR_SUCCESS == res) {
+ back = 1;
+ } else {
+ /* ERROR: Failed to open/create registry key! */
+ dk3wreg_report_error(app, n, 5, 6, 4);
+ }
+ }
+
+#line 426 "dk3wreg.ctr"
+ return back;
+}
+
+
+
+int
+dk3wreg_key_create_read(HKEY b, dkChar const *n, HKEY *r, dk3_app_t *app)
+{
+ int back = 0;
+
+
+#line 436 "dk3wreg.ctr"
+ back = dk3wreg_key_create_perms(b, n, KEY_QUERY_VALUE, r, app);
+
+
+#line 438 "dk3wreg.ctr"
+ return back;
+}
+
+
+
+int
+dk3wreg_key_create_modify(HKEY b, dkChar const *n, HKEY *r, dk3_app_t *app)
+{
+ int back = 0;
+
+
+#line 448 "dk3wreg.ctr"
+ back = dk3wreg_key_create_perms(b, n, KEY_ALL_ACCESS, r, app);
+
+
+#line 450 "dk3wreg.ctr"
+ return back;
+}
+
+
+
+int
+dk3wreg_key_close(HKEY k, dkChar const *n, dk3_app_t *app)
+{
+ int back = 0;
+ long res;
+
+
+#line 461 "dk3wreg.ctr"
+ res = RegCloseKey(k);
+ if(ERROR_SUCCESS == res) {
+ back = 1;
+ } else {
+ /* ERROR: Failed to close registry key!. */
+ dk3wreg_report_error(app, n, 8, 9, 7);
+ }
+
+#line 468 "dk3wreg.ctr"
+ return back;
+}
+
+
+
+int
+dk3wreg_key_delete(HKEY b, dkChar const *n, dk3_app_t *app)
+{
+ int back = 0;
+#if _MSC_VER >= 1700 && (!(DK4_WINDOWS_LEGACY))
+ long res;
+
+
+#line 480 "dk3wreg.ctr"
+ if(n) {
+#if 2 == DK3_CHAR_SIZE
+ res = RegDeleteTreeW(b, n);
+#else
+ res = RegDeleteTreeA(b, n);
+#endif
+ if(ERROR_SUCCESS == res) {
+ back = 1;
+ } else {
+ dk3wreg_report_error(app, n, 26, 27, 25);
+ }
+ }
+
+#line 492 "dk3wreg.ctr"
+#else
+ dk3wreg_report_error(app, n, 26, 27, 25);
+ dk3wreg_report_error(app, NULL, 0, 0, 33);
+#endif
+ return back;
+}
+
+
+
+int
+dk3wreg_set_sz(HKEY k, dkChar const *n, dkChar const *v, dk3_app_t *app)
+{
+ int back = 0;
+ DWORD dwt = REG_SZ;
+ DWORD dw0 = (DWORD)0UL;
+ DWORD sz;
+ long res;
+
+
+#line 510 "dk3wreg.ctr"
+ if(v) {
+ sz = (DWORD)(1 + dk3str_len(v));
+ sz *= DK3_CHAR_SIZE;
+#if 2 == DK3_CHAR_SIZE
+ res = RegSetValueExW(
+ k, /* Key. */
+ n, /* Entry name. */
+ dw0, /* Reserved. */
+ dwt, /* Type. */
+ (const BYTE *)v, /* Data. */
+ sz /* Number of bytes. */
+ );
+#else
+ res = RegSetValueExA(
+ k, /* Key. */
+ n, /* Entry name. */
+ dw0, /* Reserved. */
+ dwt, /* Type. */
+ (const BYTE *)v, /* Data. */
+ sz /* Number of bytes. */
+ );
+#endif
+ if(ERROR_SUCCESS == res) {
+ back = 1;
+ } else {
+ /* ERROR: Failed to save registry entry. */
+ dk3wreg_report_error(app, n, 11, 12, 10);
+ }
+ }
+
+#line 539 "dk3wreg.ctr"
+ return back;
+}
+
+
+
+int
+dk3wreg_set_expand_sz(HKEY k, dkChar const *n, dkChar const *v, dk3_app_t *app)
+{
+ int back = 0;
+ DWORD dwt = REG_EXPAND_SZ;
+ DWORD dw0 = (DWORD)0UL;
+ DWORD sz;
+ long res;
+
+
+#line 553 "dk3wreg.ctr"
+ if(v) {
+ sz = (DWORD)(1 + dk3str_len(v));
+ sz *= DK3_CHAR_SIZE;
+#if 2 == DK3_CHAR_SIZE
+ res = RegSetValueExW(
+ k, /* Key. */
+ n, /* Entry name. */
+ dw0, /* Reserved. */
+ dwt, /* Type. */
+ (const BYTE *)v, /* Data. */
+ sz /* Number of bytes. */
+ );
+#else
+ res = RegSetValueExA(
+ k, /* Key. */
+ n, /* Entry name. */
+ dw0, /* Reserved. */
+ dwt, /* Type. */
+ (const BYTE *)v, /* Data. */
+ sz /* Number of bytes. */
+ );
+#endif
+ if(ERROR_SUCCESS == res) {
+ back = 1;
+ } else {
+ /* ERROR: Failed to save registry entry. */
+ dk3wreg_report_error(app, n, 11, 12, 10);
+ }
+ }
+
+#line 582 "dk3wreg.ctr"
+ return back;
+}
+
+
+
+int
+dk3wreg_set_dword(HKEY k, dkChar const *n, DWORD v, dk3_app_t *app)
+{
+ int back = 0;
+ DWORD dwt = REG_DWORD;
+ DWORD dw0 = (DWORD)0UL;
+ DWORD sz;
+ long res;
+
+
+#line 596 "dk3wreg.ctr"
+ if((n) && (v)) {
+ sz = (DWORD)sizeof(DWORD);
+#if 2 == DK3_CHAR_SIZE
+ res = RegSetValueExW(
+ k, /* Key. */
+ n, /* Entry name. */
+ dw0, /* Reserved. */
+ dwt, /* Type. */
+ (const BYTE *)(&v), /* Data. */
+ sz /* Number of bytes. */
+ );
+#else
+ res = RegSetValueExA(
+ k, /* Key. */
+ n, /* Entry name. */
+ dw0, /* Reserved. */
+ dwt, /* Type. */
+ (const BYTE *)(&v), /* Data. */
+ sz /* Number of bytes. */
+ );
+#endif
+ if(ERROR_SUCCESS == res) {
+ back = 1;
+ } else {
+ /* ERROR: Failed to save registry entry. */
+ dk3wreg_report_error(app, n, 11, 12, 10);
+ }
+ }
+
+#line 624 "dk3wreg.ctr"
+ return back;
+}
+
+
+
+int
+dk3wreg_get_expand_sz(
+ HKEY k, dkChar const *n, dkChar *b, size_t s, DWORD *e, dk3_app_t *app
+)
+{
+ int back = 0;
+ DWORD dwt = REG_SZ;
+ DWORD dws;
+ long res;
+
+
+#line 639 "dk3wreg.ctr"
+ if((b) && (s)) {
+ dws = (DWORD)(s * DK3_CHAR_SIZE);
+#if 2 == DK3_CHAR_SIZE
+ res = RegQueryValueExW(
+ k, /* Key. */
+ n, /* Entry name. */
+ NULL, /* Reserved. */
+ &dwt, /* Type. */
+ (BYTE *)b, /* Result buffer. */
+ &dws /* Size (number of bytes). */
+ );
+#else
+ res = RegQueryValueExA(
+ k, /* Key. */
+ n, /* Entry name. */
+ NULL, /* Reserved. */
+ &dwt, /* Type. */
+ (BYTE *)b, /* Result buffer. */
+ &dws /* Size (number of bytes). */
+ );
+#endif
+ if(ERROR_SUCCESS == res) {
+ switch(dwt) {
+ case REG_SZ: case REG_EXPAND_SZ: {
+ if(e) { *e = dwt; }
+ back = 1;
+ if(0UL < dws) {
+#if 1 < DK3_CHAR_SIZE
+ dws = dws / DK3_CHAR_SIZE;
+#endif
+ if(0UL < dws) {
+ if(dws < (DWORD)s) {
+ b[dws] = dkT('\0');
+ } else {
+ b[s - 1] = dkT('\0');
+ }
+ } else {
+ *b = dkT('\0');
+ }
+ } else {
+ *b = dkT('\0');
+ }
+ } break;
+ default: {
+ *b = dkT('\0');
+ /* ERROR: Not a string value! */
+ dk3wreg_report_error(app, n, 17, 18, 16);
+ } break;
+ }
+ } else {
+ *b = dkT('\0');
+ /* ERROR: Failed to retrieve value! */
+ dk3wreg_report_error(app, n, 14, 15, 13);
+ }
+ }
+
+
+#line 695 "dk3wreg.ctr"
+
+
+#line 696 "dk3wreg.ctr"
+
+
+#line 697 "dk3wreg.ctr"
+
+
+#line 698 "dk3wreg.ctr"
+ return back;
+}
+
+
+
+int
+dk3wreg_get_sz(HKEY k, dkChar const *n, dkChar *b, size_t s, dk3_app_t *app)
+{
+ int back = 0;
+
+
+#line 708 "dk3wreg.ctr"
+ back = dk3wreg_get_expand_sz(k, n, b, s, NULL, app);
+
+
+#line 710 "dk3wreg.ctr"
+ return back;
+}
+
+
+
+int
+dk3wreg_get_expanded_sz(
+ HKEY k, dkChar const * n, dkChar *dp, size_t ds, dkChar *tp, size_t ts,
+ dk3_app_t *app
+)
+{
+ DWORD fe; /* Flag: Expand. */
+ DWORD res; /* Result from expand function. */
+ int back = 0;
+
+
+#line 725 "dk3wreg.ctr"
+ if((n) && (dp) && (ds) && (tp) && (ts)) {
+ dp[0] = dkT('\0');
+ fe = REG_SZ;
+ if(dk3wreg_get_expand_sz(k, n, tp, ts, &fe, app)) {
+ if(REG_EXPAND_SZ == fe) {
+ res = ExpandEnvironmentStrings(tp, dp, (DWORD)ds);
+ if(0 < res) {
+ if((size_t)res < ds) {
+ back = 1;
+ } else {
+ /* ERROR: String too long for final buffer! */
+ dk3wreg_report_error(app, NULL, 0, 0, 31);
+ }
+ } else {
+ /* ERROR: Expansion failed! */
+ dk3wreg_report_error(app, NULL, 0, 0, 32);
+ }
+ } else {
+ if(dk3str_len(tp) < ds) {
+ dk3str_cpy(dp, tp);
+ back = 1;
+ } else {
+ /* ERROR: String too long for final buffer! */
+ dk3wreg_report_error(app, NULL, 0, 0, 31);
+ }
+ }
+ }
+ }
+
+
+#line 754 "dk3wreg.ctr"
+
+
+#line 755 "dk3wreg.ctr"
+
+
+#line 756 "dk3wreg.ctr"
+
+
+#line 757 "dk3wreg.ctr"
+ return back;
+}
+
+
+
+int
+dk3wreg_get_dword(HKEY k, dkChar const *n, DWORD *b, dk3_app_t *app)
+{
+ int back = 0;
+ DWORD dwt = REG_DWORD;
+ DWORD dws;
+ DWORD dwres;
+ long res;
+
+
+#line 771 "dk3wreg.ctr"
+ if((n) && (b)) {
+ dws = (DWORD)sizeof(DWORD);
+ dwres = (DWORD)0UL;
+#if 2 == DK3_CHAR_SIZE
+ res = RegQueryValueExW(
+ k, n, NULL, &dwt, (BYTE *)(&dwres), &dws
+ );
+#else
+ res = RegQueryValueExA(
+ k, n, NULL, &dwt, (BYTE *)(&dwres), &dws
+ );
+#endif
+ if(ERROR_SUCCESS == res) {
+ switch(dwt) {
+ case REG_DWORD: {
+ if((DWORD)sizeof(DWORD) == dws) {
+ *b = dwres;
+ back = 1;
+ } else {
+ /* ERROR: Incomplete value! */
+ dk3wreg_report_error(app, n, 23, 24, 22);
+ }
+ } break;
+ default: {
+ /* ERROR: Not a DWORD entry! */
+ dk3wreg_report_error(app, n, 20, 21, 19);
+ } break;
+ }
+ } else {
+ /* ERROR: Failed to retrieve value! */
+ dk3wreg_report_error(app, n, 14, 15, 13);
+ }
+ }
+
+#line 804 "dk3wreg.ctr"
+ return back;
+}
+
+
+
+int
+dk3wreg_entry_delete(HKEY k, dkChar const *n, dk3_app_t *app)
+{
+ int back = 0;
+ long res;
+
+
+#line 815 "dk3wreg.ctr"
+ if(n) {
+#if 2 == DK3_CHAR_SIZE
+ res = RegDeleteValueW(k, n);
+#else
+ res = RegDeleteValueA(k, n);
+#endif
+ if(ERROR_SUCCESS == res) {
+ back = 1;
+ } else {
+ dk3wreg_report_error(app, n, 29, 30, 28);
+ }
+ }
+
+#line 827 "dk3wreg.ctr"
+ return back;
+}
+
+
+
+#else
+
+#endif
+
diff --git a/support/dktools/dk3wreg.ctr b/support/dktools/dk3wreg.ctr
new file mode 100644
index 0000000000..ee587daf07
--- /dev/null
+++ b/support/dktools/dk3wreg.ctr
@@ -0,0 +1,835 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2013-xxxx
+license = bsd
+
+
+%% header
+
+#include <dk3all.h>
+
+
+#if DK3_ON_WINDOWS && ((2 == DK3_CHAR_SIZE) || (1 == DK3_CHAR_SIZE))
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open registry key for access as specified.
+ @param b Base key.
+ @param n Key name.
+ @param p Required access permissions.
+ @param r Pointer to result variable.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3wreg_key_open_perms(
+ HKEY b, dkChar const *n, REGSAM p, HKEY *r, dk3_app_t *app
+);
+
+/** Open registry key for read-only access.
+ @param b Base key.
+ @param n Key name.
+ @param r Pointer to result variable.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3wreg_key_open_read(HKEY b, dkChar const *n, HKEY *r, dk3_app_t *app);
+
+/** Open registry key for modification.
+ @param b Base key.
+ @param n Key name.
+ @param r Pointer to result variable.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3wreg_key_open_modify(HKEY b, dkChar const *n, HKEY *r, dk3_app_t *app);
+
+/** Open registry key for access as specified, create if necessary.
+ @param b Base key.
+ @param n Key name.
+ @param p Permissions for access.
+ @param r Pointer to result variable.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3wreg_key_create_perms(
+ HKEY b,dkChar const *n,REGSAM p,HKEY *r,dk3_app_t *app
+);
+
+/** Open registry key for read-only access, create if necessary.
+ @param b Base key.
+ @param n Key name.
+ @param r Pointer to result variable.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3wreg_key_create_read(HKEY b, dkChar const *n, HKEY *r, dk3_app_t *app);
+
+/** Open registry key for modification, create if necessary.
+ @param b Base key.
+ @param n Key name.
+ @param r Pointer to result variable.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3wreg_key_create_modify(HKEY b, dkChar const *n, HKEY *r, dk3_app_t *app);
+
+/** Close registry key.
+ @param k Key to close.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3wreg_key_close(HKEY k, dkChar const *n, dk3_app_t *app);
+
+/** Remove registry key including all contents.
+ @param b Base key.
+ @param n Key name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3wreg_key_delete(HKEY b, dkChar const *n, dk3_app_t *app);
+
+/** Set REG_EXPAND_SZ entry.
+ @param k Registry key.
+ @param n Entry name.
+ @param v Value.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3wreg_set_sz(HKEY k, dkChar const *n, dkChar const *v, dk3_app_t *app);
+
+/** Set REG_EXPAND_SZ entry.
+ @param k Registry key.
+ @param n Entry name.
+ @param v Value.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3wreg_set_expand_sz(HKEY k, dkChar const *n, dkChar const *v, dk3_app_t *app);
+
+/** Set DWORD entry.
+ @param k Registry key.
+ @param n Entry name.
+ @param v Value to set.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3wreg_set_dword(HKEY k, dkChar const *n, DWORD v, dk3_app_t *app);
+
+/** Get string entry (REG_EXPAND_SZ or REG_SZ).
+ @param k Registry key.
+ @param n Entry name.
+ @param b Pointer to result buffer.
+ @param s Result buffer size (number of dkChar).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3wreg_get_sz(HKEY k, dkChar const *n, dkChar *b, size_t s, dk3_app_t *app);
+
+/** Get string entry (REG_EXPAND_SZ or REG_SZ), save type.
+ @param k Registry key.
+ @param n Entry name.
+ @param b Pointer to result buffer.
+ @param s Result buffer size (number of dkChar).
+ @param e Pointer to type variable.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3wreg_get_expand_sz(
+ HKEY k, dkChar const *n, dkChar *b, size_t s, DWORD *e, dk3_app_t *app
+);
+
+/** Get string entry, expand if necessary.
+ @param k Registry key.
+ @param n Entry name.
+ @param dp Destination buffer.
+ @param ds Destination buffer size (number of dkChar).
+ @param tp Temporary buffer for unexpanded string.
+ @param ts Size of temporary buffer (number of dkChar).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3wreg_get_expanded_sz(
+ HKEY k, dkChar const * n, dkChar *dp, size_t ds, dkChar *tp, size_t ts,
+ dk3_app_t *app
+);
+
+/** Get DWORD registry entry.
+ @param k Registry key.
+ @param n Entry name.
+ @param b Pointer to result buffer.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3wreg_get_dword(HKEY k, dkChar const *n, DWORD *b, dk3_app_t *app);
+
+/** Delete registry entry.
+ @param k Registry key.
+ @param n Entry name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3wreg_entry_delete(HKEY k, dkChar const *n, dk3_app_t *app);
+
+#ifdef __cplusplus
+}
+#endif
+
+#else
+
+#endif
+
+%% module
+
+#include "dk3all.h"
+#include "dk3wreg.h"
+
+
+
+$!trace-include
+
+
+
+#if DK3_ON_WINDOWS && ((2 == DK3_CHAR_SIZE) || (1 == DK3_CHAR_SIZE))
+
+
+
+static dkChar const * const dk3wreg_default_texts[] = {
+$!string-table macro=dkT
+#
+# 0
+#
+dk3wreg.str
+#
+# 1
+#
+Failed to open registry key!
+#
+# 2, 3
+#
+Failed to open registry key:\n"
+"!
+#
+# 4, 5, 6
+#
+Failed to open or create registry key!
+Failed to open or create registry key:\n"
+"!
+#
+# 7, 8, 9
+#
+Failed to close registry key!
+Failed to close registry key:\n"
+"!
+#
+# 10, 11, 12
+#
+Failed to write registry entry!
+Failed to write registry entry:\n"
+"!
+#
+# 13, 14, 15
+#
+Failed to retrieve registry entry!
+Failed to retrieve registry entry:\n"
+"!
+#
+# 16, 17, 18
+#
+Registry entry is not a string!
+Registry entry is not a string:\n"
+"!
+#
+# 19, 20, 21
+#
+Registry entry is not a DWORD!
+Registry entry is not a DWORD:\n"
+"!
+#
+# 22, 23, 24
+#
+Registry entry is an incomplete DWORD!
+Registry entry is an incomplete DWORD:\n"
+"!
+#
+# 25, 26, 27
+#
+Failed to delete registry key tree!
+Failed to delete registry key tree:\n"
+"!
+#
+# 28, 29, 30
+#
+Failed to delete registry entry!
+Failed to delete registry entry:\n"
+"!
+#
+# 31
+#
+String to long for result buffer!
+#
+# 32
+#
+Environment variable expansion failed!
+#
+# 33
+#
+Can not delete registry keys when compiled for legacy versions!
+$!end
+};
+
+
+
+static
+void
+dk3wreg_report_error(
+ dk3_app_t *app, dkChar const *n, size_t m1, size_t m2, size_t o
+)
+{
+ dkChar const * const *lmsg; /* Localized messages. */
+ $? "+ dk3wreg_report_error"
+ if(app) {
+ lmsg = dk3app_messages(
+ app, dk3wreg_default_texts[0], (dkChar const **)dk3wreg_default_texts
+ );
+ if(lmsg) {
+ if(n) {
+ dk3app_log_3(app, DK3_LL_ERROR, lmsg, m1, m2, n);
+ } else {
+ dk3app_log_1(app, DK3_LL_ERROR, lmsg, o);
+ }
+ }
+ } $? "- dk3wreg_report_error"
+}
+
+
+int
+dk3wreg_key_open_perms(
+ HKEY b, dkChar const *n, REGSAM p, HKEY *r, dk3_app_t *app
+)
+{
+ int back = 0;
+ long res;
+ $? "+ dk3wreg_key_open_perms \"%!ds\"", TR_STR(n)
+ if((n) && (r)) {
+#if 2 == DK3_CHAR_SIZE
+ res = RegOpenKeyExW(
+ b, /* Base key. */
+ n, /* Subkey name. */
+ (DWORD)0UL, /* Reserviced. */
+ p, /* Required access. */
+ r /* Result pointer. */
+ );
+#else
+ res = RegOpenKeyExA(
+ b, /* Base key. */
+ n, /* Subkey name. */
+ (DWORD)0UL, /* Reserviced. */
+ p, /* Required access. */
+ r /* Result pointer. */
+ );
+#endif
+ if(ERROR_SUCCESS == res) {
+ back = 1;
+ } else {
+ /* ERROR: Failed to open key! */
+ dk3wreg_report_error(app, n, 2, 3, 1);
+ }
+ } $? "- dk3wreg_key_open_perms %d", back
+ return back;
+}
+
+
+
+int
+dk3wreg_key_open_read(HKEY b, dkChar const *n, HKEY *r, dk3_app_t *app)
+{
+ int back = 0;
+ $? "+ dk3wreg_key_open_read \"%!ds\"", TR_STR(n)
+ back = dk3wreg_key_open_perms(b, n, KEY_QUERY_VALUE, r, app);
+ $? "- dk3wreg_key_open_read %d", back
+ return back;
+}
+
+
+
+int
+dk3wreg_key_open_modify(HKEY b, dkChar const *n, HKEY *r, dk3_app_t *app)
+{
+ int back = 0;
+ $? "+ dk3wreg_key_open_modify \"%!ds\"", TR_STR(n)
+ back = dk3wreg_key_open_perms(b, n, KEY_ALL_ACCESS, r, app);
+ $? "- dk3wreg_key_open_modify %d", back
+ return back;
+}
+
+
+
+int
+dk3wreg_key_create_perms(HKEY b,dkChar const *n,REGSAM p,HKEY *r,dk3_app_t *app)
+{
+ int back = 0;
+ long res;
+ DWORD disp = (DWORD)0UL;
+ $? "+ dk3wreg_key_create_perms \"%!ds\"", TR_STR(n)
+ if((n) && (r)) {
+#if 2 == DK3_CHAR_SIZE
+ res = RegCreateKeyExW(
+ b, /* Base key. */
+ n, /* Key name. */
+ (DWORD)0UL, /* Reserved. */
+ NULL, /* Key class. */
+ REG_OPTION_NON_VOLATILE, /* Options. */
+ p, /* SAM desired. */
+ NULL, /* Security descriptor. */
+ r, /* Result pointer. */
+ &disp /* Disposition. */
+ );
+#else
+ res = RegCreateKeyExA(
+ b, /* Base key. */
+ n, /* Key name. */
+ (DWORD)0UL, /* Reserved. */
+ NULL, /* Key class. */
+ REG_OPTION_NON_VOLATILE, /* Options. */
+ p, /* SAM desired. */
+ NULL, /* Security descriptor. */
+ r, /* Result pointer. */
+ &disp /* Disposition. */
+ );
+#endif
+ if(ERROR_SUCCESS == res) {
+ back = 1;
+ } else {
+ /* ERROR: Failed to open/create registry key! */
+ dk3wreg_report_error(app, n, 5, 6, 4);
+ }
+ } $? "- dk3wreg_key_create_perms %d", back
+ return back;
+}
+
+
+
+int
+dk3wreg_key_create_read(HKEY b, dkChar const *n, HKEY *r, dk3_app_t *app)
+{
+ int back = 0;
+ $? "+ dk3wreg_key_create_read \"%!ds\"", TR_STR(n)
+ back = dk3wreg_key_create_perms(b, n, KEY_QUERY_VALUE, r, app);
+ $? "- dk3wreg_key_create_read %d", back
+ return back;
+}
+
+
+
+int
+dk3wreg_key_create_modify(HKEY b, dkChar const *n, HKEY *r, dk3_app_t *app)
+{
+ int back = 0;
+ $? "+ dk3wreg_key_create_modify \"%!ds\"", TR_STR(n)
+ back = dk3wreg_key_create_perms(b, n, KEY_ALL_ACCESS, r, app);
+ $? "- dk3wreg_key_create_modify %d", back
+ return back;
+}
+
+
+
+int
+dk3wreg_key_close(HKEY k, dkChar const *n, dk3_app_t *app)
+{
+ int back = 0;
+ long res;
+ $? "+ dk3wreg_key_close"
+ res = RegCloseKey(k);
+ if(ERROR_SUCCESS == res) {
+ back = 1;
+ } else {
+ /* ERROR: Failed to close registry key!. */
+ dk3wreg_report_error(app, n, 8, 9, 7);
+ } $? "- dk3wreg_key_close %d", back
+ return back;
+}
+
+
+
+int
+dk3wreg_key_delete(HKEY b, dkChar const *n, dk3_app_t *app)
+{
+ int back = 0;
+#if _MSC_VER >= 1700 && (!(DK4_WINDOWS_LEGACY))
+ long res;
+ $? "+ dk3wreg_key_delete \"%!ds\"", TR_STR(n)
+ if(n) {
+#if 2 == DK3_CHAR_SIZE
+ res = RegDeleteTreeW(b, n);
+#else
+ res = RegDeleteTreeA(b, n);
+#endif
+ if(ERROR_SUCCESS == res) {
+ back = 1;
+ } else {
+ dk3wreg_report_error(app, n, 26, 27, 25);
+ }
+ } $? "- dk3wreg_key_delete %d", back
+#else
+ dk3wreg_report_error(app, n, 26, 27, 25);
+ dk3wreg_report_error(app, NULL, 0, 0, 33);
+#endif
+ return back;
+}
+
+
+
+int
+dk3wreg_set_sz(HKEY k, dkChar const *n, dkChar const *v, dk3_app_t *app)
+{
+ int back = 0;
+ DWORD dwt = REG_SZ;
+ DWORD dw0 = (DWORD)0UL;
+ DWORD sz;
+ long res;
+ $? "+ dk3wreg_set_sz \"%!ds\"=\"%!ds\"", TR_STR(n), TR_STR(v)
+ if(v) {
+ sz = (DWORD)(1 + dk3str_len(v));
+ sz *= DK3_CHAR_SIZE;
+#if 2 == DK3_CHAR_SIZE
+ res = RegSetValueExW(
+ k, /* Key. */
+ n, /* Entry name. */
+ dw0, /* Reserved. */
+ dwt, /* Type. */
+ (const BYTE *)v, /* Data. */
+ sz /* Number of bytes. */
+ );
+#else
+ res = RegSetValueExA(
+ k, /* Key. */
+ n, /* Entry name. */
+ dw0, /* Reserved. */
+ dwt, /* Type. */
+ (const BYTE *)v, /* Data. */
+ sz /* Number of bytes. */
+ );
+#endif
+ if(ERROR_SUCCESS == res) {
+ back = 1;
+ } else {
+ /* ERROR: Failed to save registry entry. */
+ dk3wreg_report_error(app, n, 11, 12, 10);
+ }
+ } $? "- dk3wreg_set_sz %d", back
+ return back;
+}
+
+
+
+int
+dk3wreg_set_expand_sz(HKEY k, dkChar const *n, dkChar const *v, dk3_app_t *app)
+{
+ int back = 0;
+ DWORD dwt = REG_EXPAND_SZ;
+ DWORD dw0 = (DWORD)0UL;
+ DWORD sz;
+ long res;
+ $? "+ dk3wreg_set_expand_sz \"%!ds\"=\"%!ds\"", TR_STR(n), TR_STR(v)
+ if(v) {
+ sz = (DWORD)(1 + dk3str_len(v));
+ sz *= DK3_CHAR_SIZE;
+#if 2 == DK3_CHAR_SIZE
+ res = RegSetValueExW(
+ k, /* Key. */
+ n, /* Entry name. */
+ dw0, /* Reserved. */
+ dwt, /* Type. */
+ (const BYTE *)v, /* Data. */
+ sz /* Number of bytes. */
+ );
+#else
+ res = RegSetValueExA(
+ k, /* Key. */
+ n, /* Entry name. */
+ dw0, /* Reserved. */
+ dwt, /* Type. */
+ (const BYTE *)v, /* Data. */
+ sz /* Number of bytes. */
+ );
+#endif
+ if(ERROR_SUCCESS == res) {
+ back = 1;
+ } else {
+ /* ERROR: Failed to save registry entry. */
+ dk3wreg_report_error(app, n, 11, 12, 10);
+ }
+ } $? "- dk3wreg_set_expand_sz %d", back
+ return back;
+}
+
+
+
+int
+dk3wreg_set_dword(HKEY k, dkChar const *n, DWORD v, dk3_app_t *app)
+{
+ int back = 0;
+ DWORD dwt = REG_DWORD;
+ DWORD dw0 = (DWORD)0UL;
+ DWORD sz;
+ long res;
+ $? "+ dk3wreg_set_dword \"%!ds\" %lx", TR_STR(n), (unsigned long)v
+ if((n) && (v)) {
+ sz = (DWORD)sizeof(DWORD);
+#if 2 == DK3_CHAR_SIZE
+ res = RegSetValueExW(
+ k, /* Key. */
+ n, /* Entry name. */
+ dw0, /* Reserved. */
+ dwt, /* Type. */
+ (const BYTE *)(&v), /* Data. */
+ sz /* Number of bytes. */
+ );
+#else
+ res = RegSetValueExA(
+ k, /* Key. */
+ n, /* Entry name. */
+ dw0, /* Reserved. */
+ dwt, /* Type. */
+ (const BYTE *)(&v), /* Data. */
+ sz /* Number of bytes. */
+ );
+#endif
+ if(ERROR_SUCCESS == res) {
+ back = 1;
+ } else {
+ /* ERROR: Failed to save registry entry. */
+ dk3wreg_report_error(app, n, 11, 12, 10);
+ }
+ } $? "- dk3wreg_set_dword %d", back
+ return back;
+}
+
+
+
+int
+dk3wreg_get_expand_sz(
+ HKEY k, dkChar const *n, dkChar *b, size_t s, DWORD *e, dk3_app_t *app
+)
+{
+ int back = 0;
+ DWORD dwt = REG_SZ;
+ DWORD dws;
+ long res;
+ $? "+ dk3wreg_get_expand_sz \"%!ds\"", TR_STR(n)
+ if((b) && (s)) {
+ dws = (DWORD)(s * DK3_CHAR_SIZE);
+#if 2 == DK3_CHAR_SIZE
+ res = RegQueryValueExW(
+ k, /* Key. */
+ n, /* Entry name. */
+ NULL, /* Reserved. */
+ &dwt, /* Type. */
+ (BYTE *)b, /* Result buffer. */
+ &dws /* Size (number of bytes). */
+ );
+#else
+ res = RegQueryValueExA(
+ k, /* Key. */
+ n, /* Entry name. */
+ NULL, /* Reserved. */
+ &dwt, /* Type. */
+ (BYTE *)b, /* Result buffer. */
+ &dws /* Size (number of bytes). */
+ );
+#endif
+ if(ERROR_SUCCESS == res) {
+ switch(dwt) {
+ case REG_SZ: case REG_EXPAND_SZ: {
+ if(e) { *e = dwt; }
+ back = 1;
+ if(0UL < dws) {
+#if 1 < DK3_CHAR_SIZE
+ dws = dws / DK3_CHAR_SIZE;
+#endif
+ if(0UL < dws) {
+ if(dws < (DWORD)s) {
+ b[dws] = dkT('\0');
+ } else {
+ b[s - 1] = dkT('\0');
+ }
+ } else {
+ *b = dkT('\0');
+ }
+ } else {
+ *b = dkT('\0');
+ }
+ } break;
+ default: {
+ *b = dkT('\0');
+ /* ERROR: Not a string value! */
+ dk3wreg_report_error(app, n, 17, 18, 16);
+ } break;
+ }
+ } else {
+ *b = dkT('\0');
+ /* ERROR: Failed to retrieve value! */
+ dk3wreg_report_error(app, n, 14, 15, 13);
+ }
+ }
+ $!trace-code if(back) {
+ $? ". text = \"%!ds\"", b
+ $!trace-code }
+ $? "- dk3wreg_get_expand_sz %d", back
+ return back;
+}
+
+
+
+int
+dk3wreg_get_sz(HKEY k, dkChar const *n, dkChar *b, size_t s, dk3_app_t *app)
+{
+ int back = 0;
+ $? "+ dk3wreg_get_sz \"%!ds\"", TR_STR(n)
+ back = dk3wreg_get_expand_sz(k, n, b, s, NULL, app);
+ $? "- dk3wreg_get_sz %d", back
+ return back;
+}
+
+
+
+int
+dk3wreg_get_expanded_sz(
+ HKEY k, dkChar const * n, dkChar *dp, size_t ds, dkChar *tp, size_t ts,
+ dk3_app_t *app
+)
+{
+ DWORD fe; /* Flag: Expand. */
+ DWORD res; /* Result from expand function. */
+ int back = 0;
+ $? "+ dk3wreg_get_expanded_sz \"%!ds\"", TR_STR(n)
+ if((n) && (dp) && (ds) && (tp) && (ts)) {
+ dp[0] = dkT('\0');
+ fe = REG_SZ;
+ if(dk3wreg_get_expand_sz(k, n, tp, ts, &fe, app)) {
+ if(REG_EXPAND_SZ == fe) {
+ res = ExpandEnvironmentStrings(tp, dp, (DWORD)ds);
+ if(0 < res) {
+ if((size_t)res < ds) {
+ back = 1;
+ } else {
+ /* ERROR: String too long for final buffer! */
+ dk3wreg_report_error(app, NULL, 0, 0, 31);
+ }
+ } else {
+ /* ERROR: Expansion failed! */
+ dk3wreg_report_error(app, NULL, 0, 0, 32);
+ }
+ } else {
+ if(dk3str_len(tp) < ds) {
+ dk3str_cpy(dp, tp);
+ back = 1;
+ } else {
+ /* ERROR: String too long for final buffer! */
+ dk3wreg_report_error(app, NULL, 0, 0, 31);
+ }
+ }
+ }
+ }
+ $!trace-code if(back) {
+ $? ". text = \"%!ds\"", dp
+ $!trace-code }
+ $? "- dk3wreg_get_expanded_sz %d", back
+ return back;
+}
+
+
+
+int
+dk3wreg_get_dword(HKEY k, dkChar const *n, DWORD *b, dk3_app_t *app)
+{
+ int back = 0;
+ DWORD dwt = REG_DWORD;
+ DWORD dws;
+ DWORD dwres;
+ long res;
+ $? "+ dk3wreg_get_dword \"%!ds\"", TR_STR(n)
+ if((n) && (b)) {
+ dws = (DWORD)sizeof(DWORD);
+ dwres = (DWORD)0UL;
+#if 2 == DK3_CHAR_SIZE
+ res = RegQueryValueExW(
+ k, n, NULL, &dwt, (BYTE *)(&dwres), &dws
+ );
+#else
+ res = RegQueryValueExA(
+ k, n, NULL, &dwt, (BYTE *)(&dwres), &dws
+ );
+#endif
+ if(ERROR_SUCCESS == res) {
+ switch(dwt) {
+ case REG_DWORD: {
+ if((DWORD)sizeof(DWORD) == dws) {
+ *b = dwres;
+ back = 1;
+ } else {
+ /* ERROR: Incomplete value! */
+ dk3wreg_report_error(app, n, 23, 24, 22);
+ }
+ } break;
+ default: {
+ /* ERROR: Not a DWORD entry! */
+ dk3wreg_report_error(app, n, 20, 21, 19);
+ } break;
+ }
+ } else {
+ /* ERROR: Failed to retrieve value! */
+ dk3wreg_report_error(app, n, 14, 15, 13);
+ }
+ } $? "- dk3wreg_get_dword %d %lx", back, (unsigned long)dwres
+ return back;
+}
+
+
+
+int
+dk3wreg_entry_delete(HKEY k, dkChar const *n, dk3_app_t *app)
+{
+ int back = 0;
+ long res;
+ $? "+ dk3wreg_entry_delete \"%!ds\"", TR_STR(n)
+ if(n) {
+#if 2 == DK3_CHAR_SIZE
+ res = RegDeleteValueW(k, n);
+#else
+ res = RegDeleteValueA(k, n);
+#endif
+ if(ERROR_SUCCESS == res) {
+ back = 1;
+ } else {
+ dk3wreg_report_error(app, n, 29, 30, 28);
+ }
+ } $? "- dk3wreg_entry_delete %d", back
+ return back;
+}
+
+
+
+#else
+
+#endif
+
diff --git a/support/dktools/dk3wreg.h b/support/dktools/dk3wreg.h
new file mode 100644
index 0000000000..d3f0bf2bcf
--- /dev/null
+++ b/support/dktools/dk3wreg.h
@@ -0,0 +1,237 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3wreg.ctr
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3wreg.h Header file for the dk3wreg module.
+*/
+
+#ifndef DK3WREG_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3WREG_H_INCLUDED 1
+
+
+#line 9 "dk3wreg.ctr"
+
+#include <dk3all.h>
+
+
+#if DK3_ON_WINDOWS && ((2 == DK3_CHAR_SIZE) || (1 == DK3_CHAR_SIZE))
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open registry key for access as specified.
+ @param b Base key.
+ @param n Key name.
+ @param p Required access permissions.
+ @param r Pointer to result variable.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3wreg_key_open_perms(
+ HKEY b, dkChar const *n, REGSAM p, HKEY *r, dk3_app_t *app
+);
+
+/** Open registry key for read-only access.
+ @param b Base key.
+ @param n Key name.
+ @param r Pointer to result variable.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3wreg_key_open_read(HKEY b, dkChar const *n, HKEY *r, dk3_app_t *app);
+
+/** Open registry key for modification.
+ @param b Base key.
+ @param n Key name.
+ @param r Pointer to result variable.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3wreg_key_open_modify(HKEY b, dkChar const *n, HKEY *r, dk3_app_t *app);
+
+/** Open registry key for access as specified, create if necessary.
+ @param b Base key.
+ @param n Key name.
+ @param p Permissions for access.
+ @param r Pointer to result variable.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3wreg_key_create_perms(
+ HKEY b,dkChar const *n,REGSAM p,HKEY *r,dk3_app_t *app
+);
+
+/** Open registry key for read-only access, create if necessary.
+ @param b Base key.
+ @param n Key name.
+ @param r Pointer to result variable.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3wreg_key_create_read(HKEY b, dkChar const *n, HKEY *r, dk3_app_t *app);
+
+/** Open registry key for modification, create if necessary.
+ @param b Base key.
+ @param n Key name.
+ @param r Pointer to result variable.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3wreg_key_create_modify(HKEY b, dkChar const *n, HKEY *r, dk3_app_t *app);
+
+/** Close registry key.
+ @param k Key to close.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3wreg_key_close(HKEY k, dkChar const *n, dk3_app_t *app);
+
+/** Remove registry key including all contents.
+ @param b Base key.
+ @param n Key name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3wreg_key_delete(HKEY b, dkChar const *n, dk3_app_t *app);
+
+/** Set REG_EXPAND_SZ entry.
+ @param k Registry key.
+ @param n Entry name.
+ @param v Value.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3wreg_set_sz(HKEY k, dkChar const *n, dkChar const *v, dk3_app_t *app);
+
+/** Set REG_EXPAND_SZ entry.
+ @param k Registry key.
+ @param n Entry name.
+ @param v Value.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3wreg_set_expand_sz(HKEY k, dkChar const *n, dkChar const *v, dk3_app_t *app);
+
+/** Set DWORD entry.
+ @param k Registry key.
+ @param n Entry name.
+ @param v Value to set.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3wreg_set_dword(HKEY k, dkChar const *n, DWORD v, dk3_app_t *app);
+
+/** Get string entry (REG_EXPAND_SZ or REG_SZ).
+ @param k Registry key.
+ @param n Entry name.
+ @param b Pointer to result buffer.
+ @param s Result buffer size (number of dkChar).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3wreg_get_sz(HKEY k, dkChar const *n, dkChar *b, size_t s, dk3_app_t *app);
+
+/** Get string entry (REG_EXPAND_SZ or REG_SZ), save type.
+ @param k Registry key.
+ @param n Entry name.
+ @param b Pointer to result buffer.
+ @param s Result buffer size (number of dkChar).
+ @param e Pointer to type variable.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3wreg_get_expand_sz(
+ HKEY k, dkChar const *n, dkChar *b, size_t s, DWORD *e, dk3_app_t *app
+);
+
+/** Get string entry, expand if necessary.
+ @param k Registry key.
+ @param n Entry name.
+ @param dp Destination buffer.
+ @param ds Destination buffer size (number of dkChar).
+ @param tp Temporary buffer for unexpanded string.
+ @param ts Size of temporary buffer (number of dkChar).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3wreg_get_expanded_sz(
+ HKEY k, dkChar const * n, dkChar *dp, size_t ds, dkChar *tp, size_t ts,
+ dk3_app_t *app
+);
+
+/** Get DWORD registry entry.
+ @param k Registry key.
+ @param n Entry name.
+ @param b Pointer to result buffer.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3wreg_get_dword(HKEY k, dkChar const *n, DWORD *b, dk3_app_t *app);
+
+/** Delete registry entry.
+ @param k Registry key.
+ @param n Entry name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3wreg_entry_delete(HKEY k, dkChar const *n, dk3_app_t *app);
+
+#ifdef __cplusplus
+}
+#endif
+
+#else
+
+#endif
+
+
+#endif
diff --git a/support/dktools/dk3wxcs.h b/support/dktools/dk3wxcs.h
new file mode 100644
index 0000000000..d00580c3d0
--- /dev/null
+++ b/support/dktools/dk3wxcs.h
@@ -0,0 +1,12 @@
+/** @file dk4wxcs.h Configure size of wide characters.
+*/
+
+#ifndef DK3WXCSZ_H_INCLUDED
+/** Protection against multiple inclusions. */
+#define DK3WXCSZ_H_INCLUDED 1
+
+/** Size of wxChar.
+*/
+#define DK3_SIZEOF_WXCHAR 4
+
+#endif
diff --git a/support/dktools/dk3wxs.cpp b/support/dktools/dk3wxs.cpp
new file mode 100644
index 0000000000..4b7e429a44
--- /dev/null
+++ b/support/dktools/dk3wxs.cpp
@@ -0,0 +1,934 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3wxs.cpt
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3wxs.cpp The dk3wxs module.
+*/
+
+
+#line 333 "dk3wxs.cpt"
+
+#ifdef DK3_USE_WX
+#undef DK3_USE_WX
+#endif
+/** Use wxWidgets libraries to build GUI programs.
+*/
+#define DK3_USE_WX 1
+
+#include <dk3all.h>
+#include "dk3wxs.h"
+#include "dk3wxcs.h"
+
+
+
+
+
+#line 348 "dk3wxs.cpt"
+
+
+void
+dk3wxs_cpy(wxChar *d, wxChar const *s)
+{
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ dk3str_c32_cpy((dk3_c32_t *)d, (const dk3_c32_t *)s);
+#else
+ dk3str_c16_cpy((dk3_c16_t *)d, (const dk3_c16_t *)s);
+#endif
+#else
+ dk3str_c8_cpy((char *)d, (const char *)s);
+#endif
+}
+
+wxChar *
+dk3wxs_get_suffix(wxChar const *s)
+{
+ wxChar *back = NULL;
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = (wxChar *)dk3str_c32_get_suffix((const dk3_c32_t *)s);
+#else
+ back = (wxChar *)dk3str_c16_get_suffix((const dk3_c16_t *)s);
+#endif
+#else
+ back = (wxChar *)dk3str_c8_get_suffix((const char *)s);
+#endif
+ return back;
+}
+
+void
+dk3wxs_ncpy(wxChar *d, wxChar const *s, size_t n)
+{
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ dk3str_c32_ncpy((dk3_c32_t *)d, (const dk3_c32_t *)s, n);
+#else
+ dk3str_c16_ncpy((dk3_c16_t *)d, (const dk3_c16_t *)s, n);
+#endif
+#else
+ dk3str_c8_ncpy((char *)d, (const char *)s, n);
+#endif
+}
+
+void
+dk3wxs_cat(wxChar *d, wxChar const *s)
+{
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ dk3str_c32_cat((dk3_c32_t *)d, (const dk3_c32_t *)s);
+#else
+ dk3str_c16_cat((dk3_c16_t *)d, (const dk3_c16_t *)s);
+#endif
+#else
+ dk3str_c8_cat((char *)d, (const char *)s);
+#endif
+}
+
+wxChar
+dk3wxs_tolower(wxChar c)
+{
+ wxChar back;
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = dk3str_c32_tolower((dk3_c32_t)c);
+#else
+ back = dk3str_c16_tolower((dk3_c16_t)c);
+#endif
+#else
+ back = dk3str_c8_tolower((char)c);
+#endif
+ return back;
+}
+
+wxChar
+dk3wxs_toupper(wxChar c)
+{
+ wxChar back;
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = dk3str_c32_toupper((dk3_c32_t)c);
+#else
+ back = dk3str_c16_toupper((dk3_c16_t)c);
+#endif
+#else
+ back = dk3str_c8_toupper((char)c);
+#endif
+ return back;
+}
+
+wxChar *
+dk3wxs_chr(wxChar const *s, wxChar c)
+{
+ wxChar *back = NULL;
+ if(s) {
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = (wxChar *)dk3str_c32_chr((const dk3_c32_t *)s, (dk3_c32_t)c);
+#else
+ back = (wxChar *)dk3str_c16_chr((const dk3_c16_t *)s, (dk3_c16_t)c);
+#endif
+#else
+ back = (wxChar *)dk3str_c8_chr((const char *)s, (char)c);
+#endif
+ }
+ return back;
+}
+
+wxChar *
+dk3wxs_rchr(wxChar const *s, wxChar c)
+{
+ wxChar *back = NULL;
+ if(s) {
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = (wxChar *)dk3str_c32_rchr((const dk3_c32_t *)s, (dk3_c32_t)c);
+#else
+ back = (wxChar *)dk3str_c16_rchr((const dk3_c16_t *)s, (dk3_c16_t)c);
+#endif
+#else
+ back = (wxChar *)dk3str_c8_rchr((const char *)s, (char)c);
+#endif
+ }
+ return back;
+}
+
+size_t
+dk3wxs_len(wxChar const *s)
+{
+ size_t back = 0;
+ if(s) {
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = dk3str_c32_len((const dk3_c32_t *)s);
+#else
+ back = dk3str_c16_len((const dk3_c16_t *)s);
+#endif
+#else
+ back = dk3str_c8_len((const char *)s);
+#endif
+ }
+ return back;
+}
+
+wxChar *
+dk3wxs_dup_app(wxChar const *s, dk3_app_t *app)
+{
+ wxChar *back = NULL;
+ if(s) {
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = (wxChar *)dk3str_c32_dup_app((const dk3_c32_t *)s, app);
+#else
+ back = (wxChar *)dk3str_c16_dup_app((const dk3_c16_t *)s, app);
+#endif
+#else
+ back = (wxChar *)dk3str_c8_dup_app((const char *)s, app);
+#endif
+ }
+ return back;
+}
+
+wxChar *
+dk3wxs_dup(wxChar const *s)
+{
+ wxChar *back = NULL;
+ if(s) {
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = (wxChar *)dk3str_c32_dup_app((const dk3_c32_t *)s, NULL);
+#else
+ back = (wxChar *)dk3str_c16_dup_app((const dk3_c16_t *)s, NULL);
+#endif
+#else
+ back = (wxChar *)dk3str_c8_dup_app((const char *)s, NULL);
+#endif
+ }
+ return back;
+}
+
+int
+dk3wxs_ncmp(wxChar const *l, wxChar const *r, size_t n)
+{
+ int back = 0;
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = dk3str_c32_ncmp((const dk3_c32_t *)l, (const dk3_c32_t *)r, n);
+#else
+ back = dk3str_c16_ncmp((const dk3_c16_t *)l, (const dk3_c16_t *)r, n);
+#endif
+#else
+ back = dk3str_c8_ncmp((const char *)l, (const char *)r, n);
+#endif
+ return back;
+}
+
+int
+dk3wxs_cmp(wxChar const *l, wxChar const *r)
+{
+ int back = 0;
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = dk3str_c32_cmp((const dk3_c32_t *)l, (const dk3_c32_t *)r);
+#else
+ back = dk3str_c16_cmp((const dk3_c16_t *)l, (const dk3_c16_t *)r);
+#endif
+#else
+ back = dk3str_c8_cmp((const char *)l, (const char *)r);
+#endif
+ return back;
+}
+
+int
+dk3wxs_casecmp(wxChar const *l, wxChar const *r)
+{
+ int back = 0;
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = dk3str_c32_casecmp((const dk3_c32_t *)l, (const dk3_c32_t *)r);
+#else
+ back = dk3str_c16_casecmp((const dk3_c16_t *)l, (const dk3_c16_t *)r);
+#endif
+#else
+ back = dk3str_c8_casecmp((const char *)l, (const char *)r);
+#endif
+ return back;
+}
+
+int
+dk3wxs_array_index(wxChar const * const *a, wxChar const *s, int c)
+{
+ int back = -1;
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = dk3str_c32_array_index(
+ (const dk3_c32_t * const *)a, (const dk3_c32_t *)s, c
+ );
+#else
+ back = dk3str_c16_array_index(
+ (const dk3_c16_t * const *)a, (const dk3_c16_t *)s, c
+ );
+#endif
+#else
+ back = dk3str_c8_array_index((const char * const *)a, (const char *)s, c);
+#endif
+ return back;
+}
+
+wxChar *
+dk3wxs_start(wxChar *s, wxChar const *whsp)
+{
+ wxChar *back = NULL;
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = (wxChar *)dk3str_c32_start((dk3_c32_t *)s, (const dk3_c32_t *)whsp);
+#else
+ back = (wxChar *)dk3str_c16_start((dk3_c16_t *)s, (const dk3_c16_t *)whsp);
+#endif
+#else
+ back = (wxChar *)dk3str_c8_start((char *)s, (const char *)whsp);
+#endif
+ return back;
+}
+
+wxChar *
+dk3wxs_next(wxChar *s, wxChar const *whsp)
+{
+ wxChar *back = NULL;
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = (wxChar *)dk3str_c32_next((dk3_c32_t *)s, (const dk3_c32_t *)whsp);
+#else
+ back = (wxChar *)dk3str_c16_next((dk3_c16_t *)s, (const dk3_c16_t *)whsp);
+#endif
+#else
+ back = (wxChar *)dk3str_c8_next((char *)s, (const char *)whsp);
+#endif
+ return back;
+}
+
+int
+dk3wxs_is_bool(wxChar const *s)
+{
+ int back = 0;
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = dk3str_c32_is_bool((const dk3_c32_t *)s);
+#else
+ back = dk3str_c16_is_bool((const dk3_c16_t *)s);
+#endif
+#else
+ back = dk3str_c8_is_bool((const char *)s);
+#endif
+ return back;
+}
+
+int
+dk3wxs_is_on(wxChar const *s)
+{
+ int back = 0;
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = dk3str_c32_is_on((const dk3_c32_t *)s);
+#else
+ back = dk3str_c16_is_on((const dk3_c16_t *)s);
+#endif
+#else
+ back = dk3str_c8_is_on((const char *)s);
+#endif
+ return back;
+}
+
+size_t
+dk3wxs_explode(wxChar **array, size_t sz, wxChar *s, wxChar const *whsp)
+{
+ size_t back;
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = dk3str_c32_explode(
+ (dk3_c32_t **)array, sz, (dk3_c32_t *)s, (const dk3_c32_t *)whsp
+ );
+#else
+ back = dk3str_c16_explode(
+ (dk3_c16_t **)array, sz, (dk3_c16_t *)s, (const dk3_c16_t *)whsp
+ );
+#endif
+#else
+ back = dk3str_c8_explode(
+ (char **)array, sz, (char *)s, (const char *)whsp
+ );
+#endif
+ return back;
+}
+
+void
+dk3wxs_normalize(wxChar *l, wxChar const *w, wxChar c)
+{
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ dk3str_c32_normalize((dk3_c32_t *)l, (const dk3_c32_t *)w, (dk3_c32_t)c);
+#else
+ dk3str_c16_normalize((dk3_c16_t *)l, (const dk3_c16_t *)w, (dk3_c16_t)c);
+#endif
+#else
+ dk3str_c8_normalize((char *)l, (const char *)w, (char)c);
+#endif
+}
+
+
+int
+dk3wxs_is_abs_path(wxChar const *n)
+{
+ int back = 0;
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = dk3str_c32_is_abs_path((const dk3_c32_t *)n);
+#else
+ back = dk3str_c16_is_abs_path((const dk3_c16_t *)n);
+#endif
+#else
+ back = dk3str_c8_is_abs_path((const char *)n);
+#endif
+ return back;
+}
+
+int
+dk3wxs_append_path(wxChar *d, size_t sz, wxChar const *n)
+{
+ int back = 0;
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = dk3str_c32_append_path_app(
+ (dk3_c32_t *)d, sz, (const dk3_c32_t *)n, NULL
+ );
+#else
+ back = dk3str_c16_append_path_app(
+ (dk3_c16_t *)d, sz, (const dk3_c16_t *)n, NULL
+ );
+#endif
+#else
+ back = dk3str_c8_append_path_app((char *)d, sz, (const char *)n, NULL);
+#endif
+ return back;
+}
+
+void
+dk3wxs_correct_filename(wxChar *n)
+{
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ dk3str_c32_correct_filename((dk3_c32_t *)n);
+#else
+ dk3str_c16_correct_filename((dk3_c16_t *)n);
+#endif
+#else
+ dk3str_c8_correct_filename((char *)n);
+#endif
+}
+
+
+int
+dk3wxs_from_utf8(wxChar *d, size_t sz, char const *s)
+{
+ int back = 0;
+
+
+#line 755 "dk3wxs.cpt"
+ if((d) && (sz) && (s)) {
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+
+
+#line 759 "dk3wxs.cpt"
+ if(sz >= dk3str_cnvsz_c8u_to_c32_app(s, NULL)) {
+
+
+#line 761 "dk3wxs.cpt"
+ back = dk3str_cnv_c8u_to_c32_app( (dk3_c32_t *)d, sz, s, NULL);
+ }
+#else
+
+
+#line 765 "dk3wxs.cpt"
+ if(sz >= dk3str_cnvsz_c8u_to_c16_app(s, NULL)) {
+
+
+#line 767 "dk3wxs.cpt"
+ back = dk3str_cnv_c8u_to_c16_app( (dk3_c16_t *)d, sz, s, NULL);
+ }
+#endif
+#else
+
+
+#line 772 "dk3wxs.cpt"
+ if(sz >= dk3str_cnvsz_c8u_to_c8p_app(s, NULL)) {
+
+
+#line 774 "dk3wxs.cpt"
+ back = dk3str_cnv_c8u_to_c8p_app((char *)d, sz, s, NULL);
+ }
+#endif
+ }
+
+#line 778 "dk3wxs.cpt"
+ return back;
+}
+
+
+int
+dk3wxs_from_plain(wxChar *d, size_t sz, char const *s)
+{
+ int back = 0;
+ if((d) && (sz) && (s)) {
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ if(sz >= dk3str_cnvsz_c8p_to_c32_app(s, NULL)) {
+ back = dk3str_cnv_c8p_to_c32_app((dk3_c32_t *)d, sz, s, NULL);
+ }
+#else
+ if(sz >= dk3str_cnvsz_c8p_to_c16_app(s, NULL)) {
+ back = dk3str_cnv_c8p_to_c16_app((dk3_c16_t *)d, sz, s, NULL);
+ }
+#endif
+#else
+ if(sz >= dk3str_c8_len(s)) {
+ dk3str_c8_cpy((char *)d, s);
+ back = 1;
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+
+int
+dk3wxs_from_utf16(wxChar *d, size_t sz, dk3_c16_t const *s)
+{
+ int back = 0;
+ if((d) && (sz) && (s)) {
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ if(sz >= dk3str_cnvsz_c16_to_c32_app(s, NULL)) {
+ back = dk3str_cnv_c16_to_c32_app((dk3_c32_t *)d, sz, s, NULL);
+ }
+#else
+ if(sz >= dk3str_c16_len(s)) {
+ dk3str_c16_cpy((dk3_c16_t *)d, s);
+ back = 1;
+ }
+#endif
+#else
+ if(sz >= dk3str_cnvsz_c16_to_c8p_app(s, NULL)) {
+ back = dk3str_cnv_c16_to_c8p_app((char *)d, sz, s, NULL);
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3wxs_from_dkstr(wxChar *dp, size_t sz, int wxe, dkChar const *src, int dke)
+{
+ int back = 0;
+ if((dp) && (sz) && (src)) {
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ /* + wxChar 4 */
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ /* + dkChar 4 */
+ if(dk3str_c32_len((const dk3_c32_t *)src) < sz) {
+ dk3str_c32_cpy((dk3_c32_t *)dp, (const dk3_c32_t *)src);
+ back = 1;
+ }
+ /* - dkChar 4 */
+#else
+ /* + dkChar 2 */
+ if(sz >= dk3str_cnvsz_c16_to_c32_app((const dk3_c16_t *)src, NULL)) {
+ back = dk3str_cnv_c16_to_c32_app(
+ (dk3_c32_t *)dp, sz, (const dk3_c16_t *)src, NULL
+ );
+ }
+ /* - dkChar 2 */
+#endif
+#else
+ /* + dkChar 1 */
+ if(dke == DK3_ENCODING_PLAIN) {
+ if(sz >= dk3str_cnvsz_c8p_to_c32_app((const char *)src, NULL)) {
+ back = dk3str_cnv_c8p_to_c32_app(
+ (dk3_c32_t *)dp, sz, (const char *)src, NULL
+ );
+ }
+ } else {
+ if(sz >= dk3str_cnvsz_c8u_to_c32_app(src, NULL)) {
+ back = dk3str_cnv_c8u_to_c32_app(dp, sz, src, NULL);
+ }
+ }
+ /* - dkChar 1 */
+#endif
+ /* - wxChar 4 */
+#else
+ /* + wxChar 2 */
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ /* + dkChar 4 */
+ if(sz >= dk3str_cnvsz_c32_to_c16_app((const dk3_c32_t *)src, NULL)) {
+ back = dk3str_cnv_c32_to_c16_app(
+ (dk3_c16_t *)dp, sz, (const dk3_c32_t *)src, NULL
+ );
+ }
+ /* - dkChar 4 */
+#else
+ /* + dkChar 2 */
+ if(dk3str_c16_len((const dk3_c16_t *)src) < sz) {
+ dk3str_c16_cpy((dk3_c16_t *)dp, (const dk3_c16_t *)src);
+ back = 1;
+ }
+ /* - dkChar 2 */
+#endif
+#else
+ /* + dkChar 1 */
+ if(dke == DK3_ENCODING_PLAIN) {
+ if(sz >= dk3str_cnvsz_c8p_to_c16_app((const char *)src, NULL)) {
+ back = dk3str_cnv_c8p_to_c16_app(
+ (dk3_c16_t *)dp, sz, (const char *)src, NULL
+ );
+ }
+ } else {
+ if(sz >= dk3str_cnvsz_c8u_to_c16_app((const char *)src, NULL)) {
+ back = dk3str_cnv_c8u_to_c16_app(
+ (dk3_c16_t *)dp, sz, (const char *)src, NULL
+ );
+ }
+ }
+ /* - dkChar 1 */
+#endif
+ /* - wxChar 2 */
+#endif
+#else
+ /* + wxChar 1 */
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ /* + dkChar 4 */
+ if(wxe == DK3_ENCODING_PLAIN) {
+ if(sz >= dk3str_cnvsz_c8p_to_c32_app((const dk3_c32_t *)src, NULL)) {
+ back = dk3str_cnv_c8p_to_c32_app(
+ (char *)dp, sz, (const dk3_c32_t *)src, NULL
+ );
+ }
+ } else {
+ if(sz >= dk3str_cnvsz_c8u_to_c32_app((const dk3_c32_t *)src, NULL)) {
+ back = dk3str_cnv_c8u_to_c32_app(
+ (char *)dp, sz, (const dk3_c32_t *)src, NULL
+ );
+ }
+ }
+ /* - dkChar 4 */
+#else
+ /* + dkChar 2 */
+ if(wxe == DK3_ENCODING_PLAIN) {
+ if(sz >= dk3str_cnvsz_c8p_to_c16_app((const dk3_c16_t *)src, NULL)) {
+ back =dk3str_cnv_c8p_to_c16_app(
+ (char *)dp, sz, (const dk3_c16_t *)src, NULL
+ );
+ }
+ } else {
+ if(sz >= dk3str_cnvsz_c8u_to_c16_app((const dk3_c16_t *)src, NULL)) {
+ back =dk3str_cnv_c8u_to_c16_app(
+ (char *)dp, sz, (const dk3_c16_t *)src, NULL
+ );
+ }
+ }
+ /* - dkChar 2 */
+#endif
+#else
+ /* + dkChar 1 */
+ if(wxe == dke) {
+ if(dk3str_c8_len((const char *)src) < sz) {
+ dk3str_c8_cpy((char *)dp, (const char *)src);
+ back = 1;
+ }
+ } else {
+ if(wxe == DK3_ENCODING_PLAIN) {
+ if(sz >= dk3str_cnvsz_c8u_to_c8p_app((const char *)src, NULL)) {
+ back = dk3str_cnv_c8u_to_c8p_app(
+ (char *)dp, sz, (const char *)src, NULL
+ );
+ }
+ } else {
+ if(sz >= dk3str_cnvsz_c8p_to_c8u_app((const char *)src, NULL)) {
+ back = dk3str_cnv_c8p_to_c8u_app(
+ (char *)dp, sz, (const char *)src, NULL
+ );
+ }
+ }
+ }
+ /* - dkChar 1 */
+#endif
+ /* - wxChar 1 */
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3wxs_to_dkstr(dkChar *dp, size_t sz, int dke, wxChar const *src, int wxe)
+{
+ int back = 0;
+ if((dp) && (sz) && (src)) {
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ /* + dkChar 4 */
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ /* + wxChar 4 */
+ if(dk3str_c32_len((const dk3_c32_t *)src) < sz) {
+ dk3str_c32_cpy((dk3_c32_t *)dp, (const dk3_c32_t *)src);
+ back = 1;
+ }
+ /* - wxChar 4 */
+#else
+ /* + wxChar 2 */
+ if(sz >= dk3str_cnvsz_c16_to_c32_app((const dk3_c16_t *)src, NULL)) {
+ back = dk3str_cnv_c16_to_c32_app(
+ (dk3_c32_t *)dp, sz, (const dk3_c16_t *)src, NULL
+ );
+ }
+ /* - wxChar 2 */
+#endif
+#else
+ /* + wxChar 1 */
+ if(wxe == DK3_ENCODING_PLAIN) {
+ if(sz >= dk3str_cnvsz_c8p_to_c32_app((const char *)src, NULL)) {
+ back = dk3str_cnv_c8p_to_c32_app(
+ (dk3_c32_t *)dp, sz, (const char *)src, NULL
+ );
+ }
+ } else {
+ if(sz >= dk3str_cnvsz_c8u_to_c32_app((const char *)src, NULL)) {
+ back = dk3str_cnv_c8u_to_c32_app(
+ (dk3_c32_t *)dp, sz, (const char *)src, NULL
+ );
+ }
+ }
+ /* - wxChar 1 */
+#endif
+ /* - dkChar 4 */
+#else
+ /* + dkChar 2 */
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ /* + wxChar 4 */
+ if(sz >= dk3str_cnvsz_c32_to_c16_app((const dk3_c32_t *)src, NULL)) {
+ back = dk3str_cnv_c32_to_c16_app(
+ (dk3_c16_t *)dp, sz, (const dk3_c32_t *)src, NULL
+ );
+ }
+ /* - wxChar 4 */
+#else
+ /* + wxChar 2 */
+ if(sz > dk3str_c16_len((const dk3_c16_t *)src)) {
+ dk3str_c16_cpy((dk3_c16_t *)dp, (const dk3_c16_t *)src);
+ back = 1;
+ }
+ /* - wxChar 2 */
+#endif
+#else
+ /* + wxChar 1 */
+ if(wxe == DK3_ENCODING_PLAIN) {
+ if(sz >= dk3str_cnvsz_c8p_to_c16_app((const char *)src, NULL)) {
+ back = dk3str_cnv_c8p_to_c16_app(
+ (dk3_c16_t *)dp, sz, (const char *)src, NULL
+ );
+ }
+ } else {
+ if(sz >= dk3str_cnvsz_c8u_to_c16_app((const char *)src, NULL)) {
+ back = dk3str_cnv_c8u_to_c16_app(
+ (dk3_c16_t *)dp, sz, (const char *)src, NULL
+ );
+ }
+ }
+ /* - wxChar 1 */
+#endif
+ /* - dkChar 2 */
+#endif
+#else
+ /* + dkChar 1 */
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ /* + wxChar 4 */
+ if(dke == DK3_ENCODING_PLAIN) {
+ if(sz >= dk3str_cnvsz_c32_to_c8p_app((const dk3_c32_t *)src, NULL)) {
+ back = dk3str_cnv_c32_to_c8p_app(
+ (char *)dp, sz, (const dk3_c32_t *)src, NULL
+ );
+ }
+ } else {
+ if(sz >= dk3str_cnvsz_c32_to_c8u_app((const dk3_c32_t *)src, NULL)) {
+ back = dk3str_cnv_c32_to_c8u_app(
+ (char *)dp, sz, (const dk3_c32_t *)src, NULL
+ );
+ }
+ }
+ /* - wxChar 4 */
+#else
+ /* + wxChar 2 */
+ if(dke == DK3_ENCODING_PLAIN) {
+ if(sz >= dk3str_cnvsz_c16_to_c8p_app((const dk3_c16_t *)src, NULL)) {
+ back = dk3str_cnv_c16_to_c8p_app(
+ (char *)dp, sz, (const dk3_c16_t *)src, NULL
+ );
+ }
+ } else {
+ if(sz >= dk3str_cnvsz_c16_to_c8u_app((const dk3_c16_t *)src, NULL)) {
+ back = dk3str_cnv_c16_to_c8u_app(
+ (char *)dp, sz, (const dk3_c16_t *)src, NULL
+ );
+ }
+ }
+ /* - wxChar 2 */
+#endif
+#else
+ /* + wxChar 1 */
+ if(dke == wxe) {
+ if(sz > dk3str_c8_len((const char *)src)) {
+ dk3str_c8_cpy((char *)dp, (const char *)src);
+ back = 1;
+ }
+ } else {
+ if(dke == DK3_ENCODING_PLAIN) {
+ if(sz >= dk3str_cnvsz_c8u_to_c8p_app((const char *)src, NULL)) {
+ back = dk3str_cnv_c8u_to_c8p_app(
+ (char *)dp, sz, (const char *)src, NULL
+ );
+ }
+ } else {
+ if(sz >= dk3str_cnvsz_c8p_to_c8u_app((const char *)src, NULL)) {
+ back = dk3str_cnv_c8p_to_c8u_app(
+ (char *)dp, sz, (const char *)src, NULL
+ );
+ }
+ }
+ }
+ /* - wxChar 1 */
+#endif
+ /* - dkChar 1 */
+#endif
+ }
+ return back;
+}
+
+
+int
+dk3wxs_to_c8(char *dp, size_t sz, int c8e, wxChar const *src, int wxe)
+{
+ int back = 0;
+
+
+#line 1137 "dk3wxs.cpt"
+ if((dp) && (sz) && (src)) {
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ if(DK3_ENCODING_UTF8 == c8e) {
+
+#line 1141 "dk3wxs.cpt"
+ if(sz >= dk3str_cnvsz_c32_to_c8u_app((const dk3_c32_t *)src, NULL)) {
+ back = dk3str_cnv_c32_to_c8u_app(
+ dp, sz, (const dk3_c32_t *)src, NULL
+ );
+ }
+ } else {
+
+#line 1147 "dk3wxs.cpt"
+ if(sz >= dk3str_cnvsz_c32_to_c8p_app((const dk3_c32_t *)src, NULL)) {
+ back = dk3str_cnv_c32_to_c8p_app(
+ dp, sz, (const dk3_c32_t *)src, NULL
+ );
+ }
+ }
+#else
+ if(DK3_ENCODING_UTF8 == c8e) {
+
+#line 1155 "dk3wxs.cpt"
+ if(sz >= dk3str_cnvsz_c16_to_c8u_app((const dk3_c16_t *)src, NULL)) {
+ back = dk3str_cnv_c16_to_c8u_app(
+ dp, sz, (const dk3_c16_t *)src, NULL
+ );
+ }
+ } else {
+
+#line 1161 "dk3wxs.cpt"
+ if(sz >= dk3str_cnvsz_c16_to_c8p_app((const dk3_c16_t *)src, NULL)) {
+ back = dk3str_cnv_c16_to_c8p_app(
+ dp, sz, (const dk3_c16_t *)src, NULL
+ );
+ }
+ }
+#endif
+#else
+ if(c8e == wxe) {
+
+#line 1170 "dk3wxs.cpt"
+ if(sz > strlen((const char *)src)) {
+ strcpy(dp, (const char *)src);
+ }
+ } else {
+ if(DK3_ENCODING_UTF8 == c8e) {
+
+#line 1175 "dk3wxs.cpt"
+ if(sz >= dk3str_cnvsz_c8p_to_c8u_app((const char *)src, NULL)) {
+ back = dk3str_cnv_c8p_to_c8u_app(dp, sz, (const char *)src, NULL);
+ }
+ } else {
+
+#line 1179 "dk3wxs.cpt"
+ if(sz >= dk3str_cnvsz_c8u_to_c8p_app((const char *)src, NULL)) {
+ back = dk3str_cnv_c8u_to_c8p_app(dp, sz, (const char *)src, NULL);
+ }
+ }
+ }
+#endif
+ }
+
+#line 1186 "dk3wxs.cpt"
+ return back;
+}
+
+
+
diff --git a/support/dktools/dk3wxs.cpt b/support/dktools/dk3wxs.cpt
new file mode 100644
index 0000000000..e0781471a9
--- /dev/null
+++ b/support/dktools/dk3wxs.cpt
@@ -0,0 +1,1190 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+%% header
+
+#ifdef DK3_USE_WX
+#undef DK3_USE_WX
+#endif
+/** Use wxWidgets libraries to build GUI programs.
+*/
+#define DK3_USE_WX 1
+
+
+#if 0
+#include <dk3all.h>
+#else
+#include <dk3conf.h>
+#include <dk3types.h>
+#include <dk3const.h>
+#endif
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+
+/** Pointer to wxChar string.
+*/
+typedef wxChar *DK3_PWXCHAR;
+
+/** Pointer to constant wxChar string.
+*/
+typedef wxChar const *DK3_PCWXCHAR;
+
+
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+/** File name separator.
+*/
+#define DK3_WX_CHAR_SEP wxT('\\')
+#else
+/** File name separator.
+*/
+#define DK3_WX_CHAR_SEP wxT('/')
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Copy string.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ */
+void
+dk3wxs_cpy(wxChar *d, wxChar const *s);
+
+/** Copy string, cut to buffer size if necessary.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ * @param n Size of \a d (number of characters).
+ */
+void
+dk3wxs_ncpy(wxChar *d, wxChar const *s, size_t n);
+
+/** Concatenate two strings.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ */
+void
+dk3wxs_cat(wxChar *d, wxChar const *s);
+
+/** Convert to lower-case character.
+ * @param c Character to convert.
+ * @return Conversion result.
+ */
+wxChar
+dk3wxs_tolower(wxChar c);
+
+/** Convert to upper-case character.
+ * @param c Character to convert.
+ * @return Conversion result.
+ */
+wxChar
+dk3wxs_toupper(wxChar c);
+
+/** Find left-most orrucance of character in string.
+ * @param s String probably containing the character.
+ * @param c Character to search for.
+ * @return Pointer to character position on success, NULL on error.
+ */
+wxChar *
+dk3wxs_chr(wxChar const *s, wxChar c);
+
+/** Find right-most orrucance of character in string.
+ * @param s String probably containing the character.
+ * @param c Character to search for.
+ * @return Pointer to character position on success, NULL on error.
+ */
+wxChar *
+dk3wxs_rchr(wxChar const *s, wxChar c);
+
+/** Calculate string length.
+ * @param s String to process.
+ * @return String length (number of characters).
+ */
+size_t
+dk3wxs_len(wxChar const *s);
+
+/** Duplicate string into dynamically allocated memory.
+ * Use dk3_delete() to release the memory when done.
+ * @param s String to duplicate.
+ * @return Pointer to new string on success, NULL on error.
+ */
+wxChar *
+dk3wxs_dup(wxChar const *s);
+
+/** Duplicate string into dynamically allocated memory.
+ * Use dk3_delete() to release the memory when done.
+ * @param s String to duplicate.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Pointer to new string on success, NULL on error.
+ */
+wxChar *
+dk3wxs_dup_app(wxChar const *s, dk3_app_t *app);
+
+/** Compare two strings, use only the first \a n characters.
+ * @param l Left side string.
+ * @param r Right side string.
+ * @param n Number of characters to use in comparison.
+ * @return 1 for l>r, 0 for l=r, -1 for l<r.
+ */
+int
+dk3wxs_ncmp(wxChar const *l, wxChar const *r, size_t n);
+
+/** Compare two strings.
+ * @param l Left side string.
+ * @param r Right side string.
+ * @return 1 for l>r, 0 for l=r, -1 for l<r.
+ */
+int
+dk3wxs_cmp(wxChar const *l, wxChar const *r);
+
+/** Case-insensitve string comparison.
+ * @param l Left side string.
+ * @param r Right side string.
+ * @return 1 for l>r, 0 for l=r, -1 for l<r.
+ */
+int
+dk3wxs_casecmp(wxChar const *l, wxChar const *r);
+
+/** Find index of a string in an array of patterns.
+ * @param a Patterns array.
+ * @param s String to find.
+ * @param c Flag: Case-sensitive (1) or not (0).
+ * @return Index of \a s in \a a on success, -1 on error (not found).
+ */
+int
+dk3wxs_array_index(wxChar const * const *a, wxChar const *s, int c);
+
+/** Find file name suffix.
+ @param s File name.
+ @return Pointer to suffix (pointer to the dot) or NULL.
+*/
+wxChar *
+dk3wxs_get_suffix(wxChar const *s);
+
+/** Find start of string (first non-whitespace).
+ * @param s String to process.
+ * @param whsp Whitespaces set (use NULL for default whitespace set).
+ * @return Pointer to first non-whitespace on success, NULL on error.
+ */
+wxChar *
+dk3wxs_start(wxChar *s, wxChar const *whsp);
+
+/** Find start of second text
+ * @param s String to process.
+ * @param whsp Whitespaces set (use NULL for default whitespace set).
+ * @return Pointer to second non-whitespace sequence on success, or NULL.
+ */
+wxChar *
+dk3wxs_next(wxChar *s, wxChar const *whsp);
+
+/** Check whether the text represents a boolean value.
+ * @param s Text to process.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3wxs_is_bool(wxChar const *s);
+
+/** Check whether the text represents the boolean value "true".
+ * @param s Text to process.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3wxs_is_on(wxChar const *s);
+
+/** Explode a string (split string into array of text words).
+ @param array Destination pointers array.
+ @param sz Size of \a array (number of elements).
+ @param s String to process.
+ @param whsp Whitespaces set (may be NULL).
+ @return Number of elements set in \a array, 0 on error.
+*/
+size_t
+dk3wxs_explode(wxChar **array, size_t sz, wxChar *s, wxChar const *whsp);
+
+/** Normalize text line.
+ @param l Text line to modify.
+ @param w Whitespaces set (may be NULL).
+ @param c Separator character.
+*/
+void
+dk3wxs_normalize(wxChar *l, wxChar const *w, wxChar c);
+
+/** Check whether a file/directory name is an absolute path.
+ * @param n Name to check.
+ * @return 1 for absolute path, 0 otherwise.
+ */
+int
+dk3wxs_is_abs_path(wxChar const *n);
+
+/** Append path to a given directory.
+ * @param d In: directory, out: modified path.
+ * @param sz Destination buffer size (number of characters).
+ * @param n Path name to append.
+ * @return 1 on success, 0 on errors.
+ */
+int
+dk3wxs_append_path(wxChar *d, size_t sz, wxChar const *n);
+
+/** Correct file name.
+ * @param n File name to correct.
+ */
+void
+dk3wxs_correct_filename(wxChar *n);
+
+/** Convert UTF-8 string to wxChar string.
+ * @param d Destination buffer.
+ * @param sz Size of \a d (number of wxChar).
+ * @param s Source string.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3wxs_from_utf8(wxChar *d, size_t sz, char const *s);
+
+/** Convert ASCII string to wxChar string.
+ * @param d Destination buffer.
+ * @param sz Size of \a d (number of wxChar).
+ * @param s Source string.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3wxs_from_plain(wxChar *d, size_t sz, char const *s);
+
+/** Convert UTF-16 string to wxChar string.
+ * @param d Destination buffer.
+ * @param sz Size of \a d (number of wxChar).
+ * @param s Source string.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3wxs_from_utf16(wxChar *d, size_t sz, dk3_c16_t const *s);
+
+/** Convert dkChar string to wxChar string.
+ * @param dp Destination buffer pointer.
+ * @param sz Size of \a dp (number of wxChar).
+ * @param wxe Encoding for wxChar string (for 8-bit wxChar only).
+ * @param src Source string.
+ * @param dke Encoding for dkChar string (for 8-bit dkChar only).
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3wxs_from_dkstr(wxChar *dp, size_t sz, int wxe, dkChar const *src, int dke);
+
+/** Convert wxChar string to dkChar string.
+ * @param dp Destination buffer pointer.
+ * @param sz Size of \a dp (number of dkChar).
+ * @param dke Encoding for dkChar string (used for 8-bit dkChar only).
+ * @param src Source string.
+ * @param wxe Encoding for wxChar string (used for 8-bit wxChar only).
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3wxs_to_dkstr(dkChar *dp, size_t sz, int dke, wxChar const *src, int wxe);
+
+/** Convert wxChar string to 8-bit char string.
+ * @param dp Destination buffer pointer.
+ * @param sz Size of \a dp.
+ * @param c8e Encoding for char string.
+ * @param src Source string.
+ * @param wxe Encoding for wxChar string (used for 8-bit wxChar only).
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3wxs_to_c8(char *dp, size_t sz, int c8e, wxChar const *src, int wxe);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#ifdef DK3_USE_WX
+#undef DK3_USE_WX
+#endif
+/** Use wxWidgets libraries to build GUI programs.
+*/
+#define DK3_USE_WX 1
+
+#include <dk3all.h>
+#include "dk3wxs.h"
+#include "dk3wxcs.h"
+
+
+
+$!trace-include
+
+
+void
+dk3wxs_cpy(wxChar *d, wxChar const *s)
+{
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ dk3str_c32_cpy((dk3_c32_t *)d, (const dk3_c32_t *)s);
+#else
+ dk3str_c16_cpy((dk3_c16_t *)d, (const dk3_c16_t *)s);
+#endif
+#else
+ dk3str_c8_cpy((char *)d, (const char *)s);
+#endif
+}
+
+wxChar *
+dk3wxs_get_suffix(wxChar const *s)
+{
+ wxChar *back = NULL;
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = (wxChar *)dk3str_c32_get_suffix((const dk3_c32_t *)s);
+#else
+ back = (wxChar *)dk3str_c16_get_suffix((const dk3_c16_t *)s);
+#endif
+#else
+ back = (wxChar *)dk3str_c8_get_suffix((const char *)s);
+#endif
+ return back;
+}
+
+void
+dk3wxs_ncpy(wxChar *d, wxChar const *s, size_t n)
+{
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ dk3str_c32_ncpy((dk3_c32_t *)d, (const dk3_c32_t *)s, n);
+#else
+ dk3str_c16_ncpy((dk3_c16_t *)d, (const dk3_c16_t *)s, n);
+#endif
+#else
+ dk3str_c8_ncpy((char *)d, (const char *)s, n);
+#endif
+}
+
+void
+dk3wxs_cat(wxChar *d, wxChar const *s)
+{
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ dk3str_c32_cat((dk3_c32_t *)d, (const dk3_c32_t *)s);
+#else
+ dk3str_c16_cat((dk3_c16_t *)d, (const dk3_c16_t *)s);
+#endif
+#else
+ dk3str_c8_cat((char *)d, (const char *)s);
+#endif
+}
+
+wxChar
+dk3wxs_tolower(wxChar c)
+{
+ wxChar back;
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = dk3str_c32_tolower((dk3_c32_t)c);
+#else
+ back = dk3str_c16_tolower((dk3_c16_t)c);
+#endif
+#else
+ back = dk3str_c8_tolower((char)c);
+#endif
+ return back;
+}
+
+wxChar
+dk3wxs_toupper(wxChar c)
+{
+ wxChar back;
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = dk3str_c32_toupper((dk3_c32_t)c);
+#else
+ back = dk3str_c16_toupper((dk3_c16_t)c);
+#endif
+#else
+ back = dk3str_c8_toupper((char)c);
+#endif
+ return back;
+}
+
+wxChar *
+dk3wxs_chr(wxChar const *s, wxChar c)
+{
+ wxChar *back = NULL;
+ if(s) {
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = (wxChar *)dk3str_c32_chr((const dk3_c32_t *)s, (dk3_c32_t)c);
+#else
+ back = (wxChar *)dk3str_c16_chr((const dk3_c16_t *)s, (dk3_c16_t)c);
+#endif
+#else
+ back = (wxChar *)dk3str_c8_chr((const char *)s, (char)c);
+#endif
+ }
+ return back;
+}
+
+wxChar *
+dk3wxs_rchr(wxChar const *s, wxChar c)
+{
+ wxChar *back = NULL;
+ if(s) {
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = (wxChar *)dk3str_c32_rchr((const dk3_c32_t *)s, (dk3_c32_t)c);
+#else
+ back = (wxChar *)dk3str_c16_rchr((const dk3_c16_t *)s, (dk3_c16_t)c);
+#endif
+#else
+ back = (wxChar *)dk3str_c8_rchr((const char *)s, (char)c);
+#endif
+ }
+ return back;
+}
+
+size_t
+dk3wxs_len(wxChar const *s)
+{
+ size_t back = 0;
+ if(s) {
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = dk3str_c32_len((const dk3_c32_t *)s);
+#else
+ back = dk3str_c16_len((const dk3_c16_t *)s);
+#endif
+#else
+ back = dk3str_c8_len((const char *)s);
+#endif
+ }
+ return back;
+}
+
+wxChar *
+dk3wxs_dup_app(wxChar const *s, dk3_app_t *app)
+{
+ wxChar *back = NULL;
+ if(s) {
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = (wxChar *)dk3str_c32_dup_app((const dk3_c32_t *)s, app);
+#else
+ back = (wxChar *)dk3str_c16_dup_app((const dk3_c16_t *)s, app);
+#endif
+#else
+ back = (wxChar *)dk3str_c8_dup_app((const char *)s, app);
+#endif
+ }
+ return back;
+}
+
+wxChar *
+dk3wxs_dup(wxChar const *s)
+{
+ wxChar *back = NULL;
+ if(s) {
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = (wxChar *)dk3str_c32_dup_app((const dk3_c32_t *)s, NULL);
+#else
+ back = (wxChar *)dk3str_c16_dup_app((const dk3_c16_t *)s, NULL);
+#endif
+#else
+ back = (wxChar *)dk3str_c8_dup_app((const char *)s, NULL);
+#endif
+ }
+ return back;
+}
+
+int
+dk3wxs_ncmp(wxChar const *l, wxChar const *r, size_t n)
+{
+ int back = 0;
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = dk3str_c32_ncmp((const dk3_c32_t *)l, (const dk3_c32_t *)r, n);
+#else
+ back = dk3str_c16_ncmp((const dk3_c16_t *)l, (const dk3_c16_t *)r, n);
+#endif
+#else
+ back = dk3str_c8_ncmp((const char *)l, (const char *)r, n);
+#endif
+ return back;
+}
+
+int
+dk3wxs_cmp(wxChar const *l, wxChar const *r)
+{
+ int back = 0;
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = dk3str_c32_cmp((const dk3_c32_t *)l, (const dk3_c32_t *)r);
+#else
+ back = dk3str_c16_cmp((const dk3_c16_t *)l, (const dk3_c16_t *)r);
+#endif
+#else
+ back = dk3str_c8_cmp((const char *)l, (const char *)r);
+#endif
+ return back;
+}
+
+int
+dk3wxs_casecmp(wxChar const *l, wxChar const *r)
+{
+ int back = 0;
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = dk3str_c32_casecmp((const dk3_c32_t *)l, (const dk3_c32_t *)r);
+#else
+ back = dk3str_c16_casecmp((const dk3_c16_t *)l, (const dk3_c16_t *)r);
+#endif
+#else
+ back = dk3str_c8_casecmp((const char *)l, (const char *)r);
+#endif
+ return back;
+}
+
+int
+dk3wxs_array_index(wxChar const * const *a, wxChar const *s, int c)
+{
+ int back = -1;
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = dk3str_c32_array_index(
+ (const dk3_c32_t * const *)a, (const dk3_c32_t *)s, c
+ );
+#else
+ back = dk3str_c16_array_index(
+ (const dk3_c16_t * const *)a, (const dk3_c16_t *)s, c
+ );
+#endif
+#else
+ back = dk3str_c8_array_index((const char * const *)a, (const char *)s, c);
+#endif
+ return back;
+}
+
+wxChar *
+dk3wxs_start(wxChar *s, wxChar const *whsp)
+{
+ wxChar *back = NULL;
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = (wxChar *)dk3str_c32_start((dk3_c32_t *)s, (const dk3_c32_t *)whsp);
+#else
+ back = (wxChar *)dk3str_c16_start((dk3_c16_t *)s, (const dk3_c16_t *)whsp);
+#endif
+#else
+ back = (wxChar *)dk3str_c8_start((char *)s, (const char *)whsp);
+#endif
+ return back;
+}
+
+wxChar *
+dk3wxs_next(wxChar *s, wxChar const *whsp)
+{
+ wxChar *back = NULL;
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = (wxChar *)dk3str_c32_next((dk3_c32_t *)s, (const dk3_c32_t *)whsp);
+#else
+ back = (wxChar *)dk3str_c16_next((dk3_c16_t *)s, (const dk3_c16_t *)whsp);
+#endif
+#else
+ back = (wxChar *)dk3str_c8_next((char *)s, (const char *)whsp);
+#endif
+ return back;
+}
+
+int
+dk3wxs_is_bool(wxChar const *s)
+{
+ int back = 0;
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = dk3str_c32_is_bool((const dk3_c32_t *)s);
+#else
+ back = dk3str_c16_is_bool((const dk3_c16_t *)s);
+#endif
+#else
+ back = dk3str_c8_is_bool((const char *)s);
+#endif
+ return back;
+}
+
+int
+dk3wxs_is_on(wxChar const *s)
+{
+ int back = 0;
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = dk3str_c32_is_on((const dk3_c32_t *)s);
+#else
+ back = dk3str_c16_is_on((const dk3_c16_t *)s);
+#endif
+#else
+ back = dk3str_c8_is_on((const char *)s);
+#endif
+ return back;
+}
+
+size_t
+dk3wxs_explode(wxChar **array, size_t sz, wxChar *s, wxChar const *whsp)
+{
+ size_t back;
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = dk3str_c32_explode(
+ (dk3_c32_t **)array, sz, (dk3_c32_t *)s, (const dk3_c32_t *)whsp
+ );
+#else
+ back = dk3str_c16_explode(
+ (dk3_c16_t **)array, sz, (dk3_c16_t *)s, (const dk3_c16_t *)whsp
+ );
+#endif
+#else
+ back = dk3str_c8_explode(
+ (char **)array, sz, (char *)s, (const char *)whsp
+ );
+#endif
+ return back;
+}
+
+void
+dk3wxs_normalize(wxChar *l, wxChar const *w, wxChar c)
+{
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ dk3str_c32_normalize((dk3_c32_t *)l, (const dk3_c32_t *)w, (dk3_c32_t)c);
+#else
+ dk3str_c16_normalize((dk3_c16_t *)l, (const dk3_c16_t *)w, (dk3_c16_t)c);
+#endif
+#else
+ dk3str_c8_normalize((char *)l, (const char *)w, (char)c);
+#endif
+}
+
+
+int
+dk3wxs_is_abs_path(wxChar const *n)
+{
+ int back = 0;
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = dk3str_c32_is_abs_path((const dk3_c32_t *)n);
+#else
+ back = dk3str_c16_is_abs_path((const dk3_c16_t *)n);
+#endif
+#else
+ back = dk3str_c8_is_abs_path((const char *)n);
+#endif
+ return back;
+}
+
+int
+dk3wxs_append_path(wxChar *d, size_t sz, wxChar const *n)
+{
+ int back = 0;
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ back = dk3str_c32_append_path_app(
+ (dk3_c32_t *)d, sz, (const dk3_c32_t *)n, NULL
+ );
+#else
+ back = dk3str_c16_append_path_app(
+ (dk3_c16_t *)d, sz, (const dk3_c16_t *)n, NULL
+ );
+#endif
+#else
+ back = dk3str_c8_append_path_app((char *)d, sz, (const char *)n, NULL);
+#endif
+ return back;
+}
+
+void
+dk3wxs_correct_filename(wxChar *n)
+{
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ dk3str_c32_correct_filename((dk3_c32_t *)n);
+#else
+ dk3str_c16_correct_filename((dk3_c16_t *)n);
+#endif
+#else
+ dk3str_c8_correct_filename((char *)n);
+#endif
+}
+
+
+int
+dk3wxs_from_utf8(wxChar *d, size_t sz, char const *s)
+{
+ int back = 0;
+ $? "+ dk3wxs_from_utf8 %u \"%!8s\"", (unsigned)sz, s
+ if((d) && (sz) && (s)) {
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ $? ". 32 bit"
+ if(sz >= dk3str_cnvsz_c8u_to_c32_app(s, NULL)) {
+ $? ". size ok"
+ back = dk3str_cnv_c8u_to_c32_app( (dk3_c32_t *)d, sz, s, NULL);
+ }
+#else
+ $? ". 16 bit"
+ if(sz >= dk3str_cnvsz_c8u_to_c16_app(s, NULL)) {
+ $? ". size ok"
+ back = dk3str_cnv_c8u_to_c16_app( (dk3_c16_t *)d, sz, s, NULL);
+ }
+#endif
+#else
+ $? ". 8 bit"
+ if(sz >= dk3str_cnvsz_c8u_to_c8p_app(s, NULL)) {
+ $? ". size ok"
+ back = dk3str_cnv_c8u_to_c8p_app((char *)d, sz, s, NULL);
+ }
+#endif
+ } $? "- dk3wxs_from_utf8 %d", back
+ return back;
+}
+
+
+int
+dk3wxs_from_plain(wxChar *d, size_t sz, char const *s)
+{
+ int back = 0;
+ if((d) && (sz) && (s)) {
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ if(sz >= dk3str_cnvsz_c8p_to_c32_app(s, NULL)) {
+ back = dk3str_cnv_c8p_to_c32_app((dk3_c32_t *)d, sz, s, NULL);
+ }
+#else
+ if(sz >= dk3str_cnvsz_c8p_to_c16_app(s, NULL)) {
+ back = dk3str_cnv_c8p_to_c16_app((dk3_c16_t *)d, sz, s, NULL);
+ }
+#endif
+#else
+ if(sz >= dk3str_c8_len(s)) {
+ dk3str_c8_cpy((char *)d, s);
+ back = 1;
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+
+int
+dk3wxs_from_utf16(wxChar *d, size_t sz, dk3_c16_t const *s)
+{
+ int back = 0;
+ if((d) && (sz) && (s)) {
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ if(sz >= dk3str_cnvsz_c16_to_c32_app(s, NULL)) {
+ back = dk3str_cnv_c16_to_c32_app((dk3_c32_t *)d, sz, s, NULL);
+ }
+#else
+ if(sz >= dk3str_c16_len(s)) {
+ dk3str_c16_cpy((dk3_c16_t *)d, s);
+ back = 1;
+ }
+#endif
+#else
+ if(sz >= dk3str_cnvsz_c16_to_c8p_app(s, NULL)) {
+ back = dk3str_cnv_c16_to_c8p_app((char *)d, sz, s, NULL);
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3wxs_from_dkstr(wxChar *dp, size_t sz, int wxe, dkChar const *src, int dke)
+{
+ int back = 0;
+ if((dp) && (sz) && (src)) {
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ /* + wxChar 4 */
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ /* + dkChar 4 */
+ if(dk3str_c32_len((const dk3_c32_t *)src) < sz) {
+ dk3str_c32_cpy((dk3_c32_t *)dp, (const dk3_c32_t *)src);
+ back = 1;
+ }
+ /* - dkChar 4 */
+#else
+ /* + dkChar 2 */
+ if(sz >= dk3str_cnvsz_c16_to_c32_app((const dk3_c16_t *)src, NULL)) {
+ back = dk3str_cnv_c16_to_c32_app(
+ (dk3_c32_t *)dp, sz, (const dk3_c16_t *)src, NULL
+ );
+ }
+ /* - dkChar 2 */
+#endif
+#else
+ /* + dkChar 1 */
+ if(dke == DK3_ENCODING_PLAIN) {
+ if(sz >= dk3str_cnvsz_c8p_to_c32_app((const char *)src, NULL)) {
+ back = dk3str_cnv_c8p_to_c32_app(
+ (dk3_c32_t *)dp, sz, (const char *)src, NULL
+ );
+ }
+ } else {
+ if(sz >= dk3str_cnvsz_c8u_to_c32_app(src, NULL)) {
+ back = dk3str_cnv_c8u_to_c32_app(dp, sz, src, NULL);
+ }
+ }
+ /* - dkChar 1 */
+#endif
+ /* - wxChar 4 */
+#else
+ /* + wxChar 2 */
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ /* + dkChar 4 */
+ if(sz >= dk3str_cnvsz_c32_to_c16_app((const dk3_c32_t *)src, NULL)) {
+ back = dk3str_cnv_c32_to_c16_app(
+ (dk3_c16_t *)dp, sz, (const dk3_c32_t *)src, NULL
+ );
+ }
+ /* - dkChar 4 */
+#else
+ /* + dkChar 2 */
+ if(dk3str_c16_len((const dk3_c16_t *)src) < sz) {
+ dk3str_c16_cpy((dk3_c16_t *)dp, (const dk3_c16_t *)src);
+ back = 1;
+ }
+ /* - dkChar 2 */
+#endif
+#else
+ /* + dkChar 1 */
+ if(dke == DK3_ENCODING_PLAIN) {
+ if(sz >= dk3str_cnvsz_c8p_to_c16_app((const char *)src, NULL)) {
+ back = dk3str_cnv_c8p_to_c16_app(
+ (dk3_c16_t *)dp, sz, (const char *)src, NULL
+ );
+ }
+ } else {
+ if(sz >= dk3str_cnvsz_c8u_to_c16_app((const char *)src, NULL)) {
+ back = dk3str_cnv_c8u_to_c16_app(
+ (dk3_c16_t *)dp, sz, (const char *)src, NULL
+ );
+ }
+ }
+ /* - dkChar 1 */
+#endif
+ /* - wxChar 2 */
+#endif
+#else
+ /* + wxChar 1 */
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ /* + dkChar 4 */
+ if(wxe == DK3_ENCODING_PLAIN) {
+ if(sz >= dk3str_cnvsz_c8p_to_c32_app((const dk3_c32_t *)src, NULL)) {
+ back = dk3str_cnv_c8p_to_c32_app(
+ (char *)dp, sz, (const dk3_c32_t *)src, NULL
+ );
+ }
+ } else {
+ if(sz >= dk3str_cnvsz_c8u_to_c32_app((const dk3_c32_t *)src, NULL)) {
+ back = dk3str_cnv_c8u_to_c32_app(
+ (char *)dp, sz, (const dk3_c32_t *)src, NULL
+ );
+ }
+ }
+ /* - dkChar 4 */
+#else
+ /* + dkChar 2 */
+ if(wxe == DK3_ENCODING_PLAIN) {
+ if(sz >= dk3str_cnvsz_c8p_to_c16_app((const dk3_c16_t *)src, NULL)) {
+ back =dk3str_cnv_c8p_to_c16_app(
+ (char *)dp, sz, (const dk3_c16_t *)src, NULL
+ );
+ }
+ } else {
+ if(sz >= dk3str_cnvsz_c8u_to_c16_app((const dk3_c16_t *)src, NULL)) {
+ back =dk3str_cnv_c8u_to_c16_app(
+ (char *)dp, sz, (const dk3_c16_t *)src, NULL
+ );
+ }
+ }
+ /* - dkChar 2 */
+#endif
+#else
+ /* + dkChar 1 */
+ if(wxe == dke) {
+ if(dk3str_c8_len((const char *)src) < sz) {
+ dk3str_c8_cpy((char *)dp, (const char *)src);
+ back = 1;
+ }
+ } else {
+ if(wxe == DK3_ENCODING_PLAIN) {
+ if(sz >= dk3str_cnvsz_c8u_to_c8p_app((const char *)src, NULL)) {
+ back = dk3str_cnv_c8u_to_c8p_app(
+ (char *)dp, sz, (const char *)src, NULL
+ );
+ }
+ } else {
+ if(sz >= dk3str_cnvsz_c8p_to_c8u_app((const char *)src, NULL)) {
+ back = dk3str_cnv_c8p_to_c8u_app(
+ (char *)dp, sz, (const char *)src, NULL
+ );
+ }
+ }
+ }
+ /* - dkChar 1 */
+#endif
+ /* - wxChar 1 */
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3wxs_to_dkstr(dkChar *dp, size_t sz, int dke, wxChar const *src, int wxe)
+{
+ int back = 0;
+ if((dp) && (sz) && (src)) {
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ /* + dkChar 4 */
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ /* + wxChar 4 */
+ if(dk3str_c32_len((const dk3_c32_t *)src) < sz) {
+ dk3str_c32_cpy((dk3_c32_t *)dp, (const dk3_c32_t *)src);
+ back = 1;
+ }
+ /* - wxChar 4 */
+#else
+ /* + wxChar 2 */
+ if(sz >= dk3str_cnvsz_c16_to_c32_app((const dk3_c16_t *)src, NULL)) {
+ back = dk3str_cnv_c16_to_c32_app(
+ (dk3_c32_t *)dp, sz, (const dk3_c16_t *)src, NULL
+ );
+ }
+ /* - wxChar 2 */
+#endif
+#else
+ /* + wxChar 1 */
+ if(wxe == DK3_ENCODING_PLAIN) {
+ if(sz >= dk3str_cnvsz_c8p_to_c32_app((const char *)src, NULL)) {
+ back = dk3str_cnv_c8p_to_c32_app(
+ (dk3_c32_t *)dp, sz, (const char *)src, NULL
+ );
+ }
+ } else {
+ if(sz >= dk3str_cnvsz_c8u_to_c32_app((const char *)src, NULL)) {
+ back = dk3str_cnv_c8u_to_c32_app(
+ (dk3_c32_t *)dp, sz, (const char *)src, NULL
+ );
+ }
+ }
+ /* - wxChar 1 */
+#endif
+ /* - dkChar 4 */
+#else
+ /* + dkChar 2 */
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ /* + wxChar 4 */
+ if(sz >= dk3str_cnvsz_c32_to_c16_app((const dk3_c32_t *)src, NULL)) {
+ back = dk3str_cnv_c32_to_c16_app(
+ (dk3_c16_t *)dp, sz, (const dk3_c32_t *)src, NULL
+ );
+ }
+ /* - wxChar 4 */
+#else
+ /* + wxChar 2 */
+ if(sz > dk3str_c16_len((const dk3_c16_t *)src)) {
+ dk3str_c16_cpy((dk3_c16_t *)dp, (const dk3_c16_t *)src);
+ back = 1;
+ }
+ /* - wxChar 2 */
+#endif
+#else
+ /* + wxChar 1 */
+ if(wxe == DK3_ENCODING_PLAIN) {
+ if(sz >= dk3str_cnvsz_c8p_to_c16_app((const char *)src, NULL)) {
+ back = dk3str_cnv_c8p_to_c16_app(
+ (dk3_c16_t *)dp, sz, (const char *)src, NULL
+ );
+ }
+ } else {
+ if(sz >= dk3str_cnvsz_c8u_to_c16_app((const char *)src, NULL)) {
+ back = dk3str_cnv_c8u_to_c16_app(
+ (dk3_c16_t *)dp, sz, (const char *)src, NULL
+ );
+ }
+ }
+ /* - wxChar 1 */
+#endif
+ /* - dkChar 2 */
+#endif
+#else
+ /* + dkChar 1 */
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ /* + wxChar 4 */
+ if(dke == DK3_ENCODING_PLAIN) {
+ if(sz >= dk3str_cnvsz_c32_to_c8p_app((const dk3_c32_t *)src, NULL)) {
+ back = dk3str_cnv_c32_to_c8p_app(
+ (char *)dp, sz, (const dk3_c32_t *)src, NULL
+ );
+ }
+ } else {
+ if(sz >= dk3str_cnvsz_c32_to_c8u_app((const dk3_c32_t *)src, NULL)) {
+ back = dk3str_cnv_c32_to_c8u_app(
+ (char *)dp, sz, (const dk3_c32_t *)src, NULL
+ );
+ }
+ }
+ /* - wxChar 4 */
+#else
+ /* + wxChar 2 */
+ if(dke == DK3_ENCODING_PLAIN) {
+ if(sz >= dk3str_cnvsz_c16_to_c8p_app((const dk3_c16_t *)src, NULL)) {
+ back = dk3str_cnv_c16_to_c8p_app(
+ (char *)dp, sz, (const dk3_c16_t *)src, NULL
+ );
+ }
+ } else {
+ if(sz >= dk3str_cnvsz_c16_to_c8u_app((const dk3_c16_t *)src, NULL)) {
+ back = dk3str_cnv_c16_to_c8u_app(
+ (char *)dp, sz, (const dk3_c16_t *)src, NULL
+ );
+ }
+ }
+ /* - wxChar 2 */
+#endif
+#else
+ /* + wxChar 1 */
+ if(dke == wxe) {
+ if(sz > dk3str_c8_len((const char *)src)) {
+ dk3str_c8_cpy((char *)dp, (const char *)src);
+ back = 1;
+ }
+ } else {
+ if(dke == DK3_ENCODING_PLAIN) {
+ if(sz >= dk3str_cnvsz_c8u_to_c8p_app((const char *)src, NULL)) {
+ back = dk3str_cnv_c8u_to_c8p_app(
+ (char *)dp, sz, (const char *)src, NULL
+ );
+ }
+ } else {
+ if(sz >= dk3str_cnvsz_c8p_to_c8u_app((const char *)src, NULL)) {
+ back = dk3str_cnv_c8p_to_c8u_app(
+ (char *)dp, sz, (const char *)src, NULL
+ );
+ }
+ }
+ }
+ /* - wxChar 1 */
+#endif
+ /* - dkChar 1 */
+#endif
+ }
+ return back;
+}
+
+
+int
+dk3wxs_to_c8(char *dp, size_t sz, int c8e, wxChar const *src, int wxe)
+{
+ int back = 0;
+ $? "+ dk3wxs_to_c8str"
+ if((dp) && (sz) && (src)) {
+#if DK3_SIZEOF_WXCHAR > 1
+#if DK3_SIZEOF_WXCHAR > 2
+ if(DK3_ENCODING_UTF8 == c8e) { $? ". 32 bit to UTF-8"
+ if(sz >= dk3str_cnvsz_c32_to_c8u_app((const dk3_c32_t *)src, NULL)) {
+ back = dk3str_cnv_c32_to_c8u_app(
+ dp, sz, (const dk3_c32_t *)src, NULL
+ );
+ }
+ } else { $? ". 32 bit to plain"
+ if(sz >= dk3str_cnvsz_c32_to_c8p_app((const dk3_c32_t *)src, NULL)) {
+ back = dk3str_cnv_c32_to_c8p_app(
+ dp, sz, (const dk3_c32_t *)src, NULL
+ );
+ }
+ }
+#else
+ if(DK3_ENCODING_UTF8 == c8e) { $? ". 16 bit to UTF-8"
+ if(sz >= dk3str_cnvsz_c16_to_c8u_app((const dk3_c16_t *)src, NULL)) {
+ back = dk3str_cnv_c16_to_c8u_app(
+ dp, sz, (const dk3_c16_t *)src, NULL
+ );
+ }
+ } else { $? ". 16 bit to plain"
+ if(sz >= dk3str_cnvsz_c16_to_c8p_app((const dk3_c16_t *)src, NULL)) {
+ back = dk3str_cnv_c16_to_c8p_app(
+ dp, sz, (const dk3_c16_t *)src, NULL
+ );
+ }
+ }
+#endif
+#else
+ if(c8e == wxe) { $? ". 8 bit copy"
+ if(sz > strlen((const char *)src)) {
+ strcpy(dp, (const char *)src);
+ }
+ } else {
+ if(DK3_ENCODING_UTF8 == c8e) { $? ". 8 bit to UTF-8"
+ if(sz >= dk3str_cnvsz_c8p_to_c8u_app((const char *)src, NULL)) {
+ back = dk3str_cnv_c8p_to_c8u_app(dp, sz, (const char *)src, NULL);
+ }
+ } else { $? ". 8 bit to plain"
+ if(sz >= dk3str_cnvsz_c8u_to_c8p_app((const char *)src, NULL)) {
+ back = dk3str_cnv_c8u_to_c8p_app(dp, sz, (const char *)src, NULL);
+ }
+ }
+ }
+#endif
+ } $? "- dk3wxs_to_c8str %d", back
+ return back;
+}
+
+
+
diff --git a/support/dktools/dk3wxs.h b/support/dktools/dk3wxs.h
new file mode 100644
index 0000000000..f1768d4398
--- /dev/null
+++ b/support/dktools/dk3wxs.h
@@ -0,0 +1,369 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3wxs.cpt
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3wxs.h Header file for the dk3wxs module.
+*/
+
+#ifndef DK3WXS_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3WXS_H_INCLUDED 1
+
+
+#line 9 "dk3wxs.cpt"
+
+#ifdef DK3_USE_WX
+#undef DK3_USE_WX
+#endif
+/** Use wxWidgets libraries to build GUI programs.
+*/
+#define DK3_USE_WX 1
+
+
+#if 0
+#include <dk3all.h>
+#else
+#include <dk3conf.h>
+#include <dk3types.h>
+#include <dk3const.h>
+#endif
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+
+/** Pointer to wxChar string.
+*/
+typedef wxChar *DK3_PWXCHAR;
+
+/** Pointer to constant wxChar string.
+*/
+typedef wxChar const *DK3_PCWXCHAR;
+
+
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+/** File name separator.
+*/
+#define DK3_WX_CHAR_SEP wxT('\\')
+#else
+/** File name separator.
+*/
+#define DK3_WX_CHAR_SEP wxT('/')
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Copy string.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ */
+void
+dk3wxs_cpy(wxChar *d, wxChar const *s);
+
+/** Copy string, cut to buffer size if necessary.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ * @param n Size of \a d (number of characters).
+ */
+void
+dk3wxs_ncpy(wxChar *d, wxChar const *s, size_t n);
+
+/** Concatenate two strings.
+ * @param d Destination pointer.
+ * @param s Source pointer.
+ */
+void
+dk3wxs_cat(wxChar *d, wxChar const *s);
+
+/** Convert to lower-case character.
+ * @param c Character to convert.
+ * @return Conversion result.
+ */
+wxChar
+dk3wxs_tolower(wxChar c);
+
+/** Convert to upper-case character.
+ * @param c Character to convert.
+ * @return Conversion result.
+ */
+wxChar
+dk3wxs_toupper(wxChar c);
+
+/** Find left-most orrucance of character in string.
+ * @param s String probably containing the character.
+ * @param c Character to search for.
+ * @return Pointer to character position on success, NULL on error.
+ */
+wxChar *
+dk3wxs_chr(wxChar const *s, wxChar c);
+
+/** Find right-most orrucance of character in string.
+ * @param s String probably containing the character.
+ * @param c Character to search for.
+ * @return Pointer to character position on success, NULL on error.
+ */
+wxChar *
+dk3wxs_rchr(wxChar const *s, wxChar c);
+
+/** Calculate string length.
+ * @param s String to process.
+ * @return String length (number of characters).
+ */
+size_t
+dk3wxs_len(wxChar const *s);
+
+/** Duplicate string into dynamically allocated memory.
+ * Use dk3_delete() to release the memory when done.
+ * @param s String to duplicate.
+ * @return Pointer to new string on success, NULL on error.
+ */
+wxChar *
+dk3wxs_dup(wxChar const *s);
+
+/** Duplicate string into dynamically allocated memory.
+ * Use dk3_delete() to release the memory when done.
+ * @param s String to duplicate.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return Pointer to new string on success, NULL on error.
+ */
+wxChar *
+dk3wxs_dup_app(wxChar const *s, dk3_app_t *app);
+
+/** Compare two strings, use only the first \a n characters.
+ * @param l Left side string.
+ * @param r Right side string.
+ * @param n Number of characters to use in comparison.
+ * @return 1 for l>r, 0 for l=r, -1 for l<r.
+ */
+int
+dk3wxs_ncmp(wxChar const *l, wxChar const *r, size_t n);
+
+/** Compare two strings.
+ * @param l Left side string.
+ * @param r Right side string.
+ * @return 1 for l>r, 0 for l=r, -1 for l<r.
+ */
+int
+dk3wxs_cmp(wxChar const *l, wxChar const *r);
+
+/** Case-insensitve string comparison.
+ * @param l Left side string.
+ * @param r Right side string.
+ * @return 1 for l>r, 0 for l=r, -1 for l<r.
+ */
+int
+dk3wxs_casecmp(wxChar const *l, wxChar const *r);
+
+/** Find index of a string in an array of patterns.
+ * @param a Patterns array.
+ * @param s String to find.
+ * @param c Flag: Case-sensitive (1) or not (0).
+ * @return Index of \a s in \a a on success, -1 on error (not found).
+ */
+int
+dk3wxs_array_index(wxChar const * const *a, wxChar const *s, int c);
+
+/** Find file name suffix.
+ @param s File name.
+ @return Pointer to suffix (pointer to the dot) or NULL.
+*/
+wxChar *
+dk3wxs_get_suffix(wxChar const *s);
+
+/** Find start of string (first non-whitespace).
+ * @param s String to process.
+ * @param whsp Whitespaces set (use NULL for default whitespace set).
+ * @return Pointer to first non-whitespace on success, NULL on error.
+ */
+wxChar *
+dk3wxs_start(wxChar *s, wxChar const *whsp);
+
+/** Find start of second text
+ * @param s String to process.
+ * @param whsp Whitespaces set (use NULL for default whitespace set).
+ * @return Pointer to second non-whitespace sequence on success, or NULL.
+ */
+wxChar *
+dk3wxs_next(wxChar *s, wxChar const *whsp);
+
+/** Check whether the text represents a boolean value.
+ * @param s Text to process.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3wxs_is_bool(wxChar const *s);
+
+/** Check whether the text represents the boolean value "true".
+ * @param s Text to process.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3wxs_is_on(wxChar const *s);
+
+/** Explode a string (split string into array of text words).
+ @param array Destination pointers array.
+ @param sz Size of \a array (number of elements).
+ @param s String to process.
+ @param whsp Whitespaces set (may be NULL).
+ @return Number of elements set in \a array, 0 on error.
+*/
+size_t
+dk3wxs_explode(wxChar **array, size_t sz, wxChar *s, wxChar const *whsp);
+
+/** Normalize text line.
+ @param l Text line to modify.
+ @param w Whitespaces set (may be NULL).
+ @param c Separator character.
+*/
+void
+dk3wxs_normalize(wxChar *l, wxChar const *w, wxChar c);
+
+/** Check whether a file/directory name is an absolute path.
+ * @param n Name to check.
+ * @return 1 for absolute path, 0 otherwise.
+ */
+int
+dk3wxs_is_abs_path(wxChar const *n);
+
+/** Append path to a given directory.
+ * @param d In: directory, out: modified path.
+ * @param sz Destination buffer size (number of characters).
+ * @param n Path name to append.
+ * @return 1 on success, 0 on errors.
+ */
+int
+dk3wxs_append_path(wxChar *d, size_t sz, wxChar const *n);
+
+/** Correct file name.
+ * @param n File name to correct.
+ */
+void
+dk3wxs_correct_filename(wxChar *n);
+
+/** Convert UTF-8 string to wxChar string.
+ * @param d Destination buffer.
+ * @param sz Size of \a d (number of wxChar).
+ * @param s Source string.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3wxs_from_utf8(wxChar *d, size_t sz, char const *s);
+
+/** Convert ASCII string to wxChar string.
+ * @param d Destination buffer.
+ * @param sz Size of \a d (number of wxChar).
+ * @param s Source string.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3wxs_from_plain(wxChar *d, size_t sz, char const *s);
+
+/** Convert UTF-16 string to wxChar string.
+ * @param d Destination buffer.
+ * @param sz Size of \a d (number of wxChar).
+ * @param s Source string.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3wxs_from_utf16(wxChar *d, size_t sz, dk3_c16_t const *s);
+
+/** Convert dkChar string to wxChar string.
+ * @param dp Destination buffer pointer.
+ * @param sz Size of \a dp (number of wxChar).
+ * @param wxe Encoding for wxChar string (for 8-bit wxChar only).
+ * @param src Source string.
+ * @param dke Encoding for dkChar string (for 8-bit dkChar only).
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3wxs_from_dkstr(wxChar *dp, size_t sz, int wxe, dkChar const *src, int dke);
+
+/** Convert wxChar string to dkChar string.
+ * @param dp Destination buffer pointer.
+ * @param sz Size of \a dp (number of dkChar).
+ * @param dke Encoding for dkChar string (used for 8-bit dkChar only).
+ * @param src Source string.
+ * @param wxe Encoding for wxChar string (used for 8-bit wxChar only).
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3wxs_to_dkstr(dkChar *dp, size_t sz, int dke, wxChar const *src, int wxe);
+
+/** Convert wxChar string to 8-bit char string.
+ * @param dp Destination buffer pointer.
+ * @param sz Size of \a dp.
+ * @param c8e Encoding for char string.
+ * @param src Source string.
+ * @param wxe Encoding for wxChar string (used for 8-bit wxChar only).
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3wxs_to_c8(char *dp, size_t sz, int c8e, wxChar const *src, int wxe);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk3xsp.c b/support/dktools/dk3xsp.c
new file mode 100644
index 0000000000..8d731aeb32
--- /dev/null
+++ b/support/dktools/dk3xsp.c
@@ -0,0 +1,1722 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3xsp.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3xsp.c The dk3xsp module.
+*/
+
+
+#line 260 "dk3xsp.ctr"
+
+#include "dk3all.h"
+#include "dk3fig.h"
+#include "dk3xsp.h"
+
+
+
+#line 266 "dk3xsp.ctr"
+
+
+
+/* ************************************************************************ */
+/* * * */
+/* * Basic X-spline functions. * */
+/* * * */
+/* ************************************************************************ */
+
+
+#line 272 "dk3xsp.ctr"
+
+
+
+
+
+#line 276 "dk3xsp.ctr"
+
+
+
+/** Initialize spline point (set all components to 0.0).
+ @param ppt Point to initialize.
+*/
+static
+void
+dk3xsp_init_spline_point(dk3_fig_spline_point_t *ppt)
+{
+ ppt->x = 0.0; ppt->y = 0.0; ppt->s = 0.0;
+}
+
+
+
+/** Copy spline point or initialize a destination point.
+ @param pd Destination pointer.
+ @param ps Source pointer, may be NULL.
+*/
+static
+void
+dk3xsp_copy_spline_point(
+ dk3_fig_spline_point_t *pd, dk3_fig_spline_point_t const *ps
+)
+{
+ if(pd) {
+ if(ps) {
+ pd->x = ps->x; pd->y = ps->y; pd->s = ps->s;
+ } else {
+ dk3xsp_init_spline_point(pd);
+ }
+ }
+}
+
+
+
+void
+dk3xsp_reset(dk3_xspline_segment_t *pseg)
+{
+ if(pseg) {
+ dk3mem_res((void *)pseg, sizeof(dk3_xspline_segment_t));
+ dk3xsp_init_spline_point(&(pseg->a));
+ dk3xsp_init_spline_point(&(pseg->b));
+ dk3xsp_init_spline_point(&(pseg->c));
+ dk3xsp_init_spline_point(&(pseg->d));
+ pseg->pa = pseg->pb = pseg->pc = pseg->pd = 2.0;
+ pseg->qa = pseg->qb = pseg->qc = pseg->qd = 0.0;
+ pseg->x = pseg->y = pseg->dxdt = pseg->dydt = 0.0;
+ pseg->duadt = pseg->dubdt = pseg->ducdt = pseg->duddt = 0.0;
+ pseg->cb = 0;
+ }
+}
+
+
+
+void
+dk3xsp_set_cb(dk3_xspline_segment_t *pseg, int v)
+{
+ if(pseg) {
+ pseg->cb = ((v) ? 1 : 0);
+ }
+}
+
+
+
+/** The f(u) function.
+ @param u The u argument.
+ @param p The p parameter.
+ @return Function result.
+*/
+static
+double
+dk3xsp_f(double u, double p)
+{
+ double back;
+ back = u * u * u *(10.0 - p + u * (2.0 * p - 15.0 + u * (6.0 - p)));
+
+
+#line 353 "dk3xsp.ctr"
+ return back;
+}
+
+
+
+/** The f(u) function derived.
+ @param u The u argument.
+ @param p The p parameter.
+ @return Function result.
+*/
+static
+double
+dk3xsp_dfdu(double u, double p)
+{
+ double back;
+ back = u * u * (30.0 - 3.0*p + u * (8.0*p - 60.0 + u * (30.0 - 5.0*p)));
+
+
+#line 370 "dk3xsp.ctr"
+ return back;
+}
+
+
+
+/** The g(u) function.
+ @param u Argument u.
+ @param p Parameter p.
+ @param q Parameter q.
+ @return Function result.
+*/
+static
+double
+dk3xsp_g(double u, double p, double q)
+{
+ double back;
+ back = u*(q+u*(2.0*q+u*(10.0-12.0*q-p+u*(2.0*p+14.0*q-15+u*(6.0-5.0*q-p)))));
+
+
+#line 388 "dk3xsp.ctr"
+ return back;
+}
+
+
+
+/** The g(u) function derived.
+ @param u Argument u.
+ @param p Parameter p.
+ @param q Parameter q.
+ @return Function result.
+*/
+static
+double
+dk3xsp_dgdu(double u, double p, double q)
+{
+ double back;
+ back =
+ q+u*(4.0*q+u*(30.0-3.0*p-36.0*q+u*(56.0*q+8.0*p-60.0+u*(30.0-5.0*p-25.0*q))));
+
+
+#line 407 "dk3xsp.ctr"
+ return back;
+}
+
+
+
+/** The h(u) function.
+ @param u Argument u.
+ @param q Parameter q.
+ @return Function result.
+*/
+static
+double
+dk3xsp_h(double u, double q)
+{
+ double back;
+ back = u*(q+u*(2.0*q-u*u*(q*(u+2.0))));
+
+
+#line 424 "dk3xsp.ctr"
+ return back;
+}
+
+
+
+/** The h(u) function derived.
+ @param u Argument u.
+ @param q Parameter q.
+ @return Function result.
+*/
+static
+double
+dk3xsp_dhdu(double u, double q)
+{
+ double back;
+ back = q+u*(4.0*q-u*u*(q*(8.0+5.0*u)));
+
+
+#line 441 "dk3xsp.ctr"
+ return back;
+}
+
+
+
+double
+dk3xsp_get_x(dk3_xspline_segment_t const *pseg)
+{
+ double back = 0.0;
+ if(pseg) {
+ back = pseg->x;
+ }
+ return back;
+}
+
+
+
+double
+dk3xsp_get_y(dk3_xspline_segment_t const *pseg)
+{
+ double back = 0.0;
+ if(pseg) {
+ back = pseg->y;
+ }
+ return back;
+}
+
+
+
+double
+dk3xsp_get_dxdt(dk3_xspline_segment_t const *pseg)
+{
+ double back = 0.0;
+ if(pseg) {
+ back = pseg->dxdt;
+ }
+ return back;
+}
+
+
+
+double
+dk3xsp_get_dydt(dk3_xspline_segment_t const *pseg)
+{
+ double back = 0.0;
+ if(pseg) {
+ back = pseg->dydt;
+ }
+ return back;
+}
+
+
+
+void
+dk3xsp_set(
+ dk3_xspline_segment_t *pseg,
+ dk3_fig_spline_point_t const *a,
+ dk3_fig_spline_point_t const *b,
+ dk3_fig_spline_point_t const *c,
+ dk3_fig_spline_point_t const *d
+)
+{
+
+
+#line 504 "dk3xsp.ctr"
+ if(pseg) {
+ pseg->ha = ((a) ? 1 : 0);
+ pseg->hd = ((d) ? 1 : 0);
+ dk3xsp_copy_spline_point(&(pseg->a), a);
+ dk3xsp_copy_spline_point(&(pseg->b), b);
+ dk3xsp_copy_spline_point(&(pseg->c), c);
+ dk3xsp_copy_spline_point(&(pseg->d), d);
+ pseg->pa = pseg->pb = pseg->pc = pseg->pd = 0.0;
+ pseg->qa = pseg->qb = pseg->qc = pseg->qd = 0.0;
+ pseg->duadt = pseg->dubdt = pseg->ducdt = pseg->duddt = 0.0;
+ if((pseg->b).s < 0.0) {
+ if(pseg->cb) {
+ pseg->qa = pseg->qc = 0.0 - ((pseg->b).s);
+ } else {
+ pseg->qa = pseg->qc = -0.5 * ((pseg->b).s);
+ }
+ pseg->duadt = -1.0; pseg->ducdt = 1.0;
+ } else {
+ pseg->pa = pseg->pc = 2.0 * (1.0 + (pseg->b).s) * (1.0 + (pseg->b).s);
+ pseg->ducdt = 1.0 / (1.0 + (pseg->b).s);
+ pseg->duadt = -1.0 * pseg->ducdt;
+ }
+ if((pseg->c).s < 0.0) {
+ if(pseg->cb) {
+ pseg->qb = pseg->qd = 0.0 - ((pseg->c).s);
+ } else {
+ pseg->qb = pseg->qd = -0.5 * ((pseg->c).s);
+ }
+ pseg->dubdt = -1.0; pseg->duddt = 1.0;
+ } else {
+ pseg->pb = pseg->pd = 2.0 * (1.0 + (pseg->c).s) * (1.0 + (pseg->c).s);
+ pseg->duddt = 1.0 / (1.0 + (pseg->c).s);
+ pseg->dubdt = -1.0 * pseg->duddt;
+ }
+
+
+#line 539 "dk3xsp.ctr"
+
+
+#line 540 "dk3xsp.ctr"
+
+
+#line 541 "dk3xsp.ctr"
+
+
+#line 542 "dk3xsp.ctr"
+ }
+
+#line 543 "dk3xsp.ctr"
+}
+
+
+
+int
+dk3xsp_calculate(
+ dk3_xspline_segment_t *pseg,
+ double t,
+ int fder
+)
+{
+ double ua = 0.0; /* Argument u for blending function from point A. */
+ double ub = 0.0; /* = B. */
+ double uc = 0.0; /* = C. */
+ double ud = 0.0; /* = D. */
+ double fa = 0.0; /* Result from blending function from point A. */
+ double fb = 0.0; /* = B. */
+ double fc = 0.0; /* = C. */
+ double fd = 0.0; /* = D. */
+ double zx = 0.0; /* Counter in fraction to calculate x. */
+ double zy = 0.0; /* Counter in fraction to calculate y. */
+ double n = 0.0; /* Denominator in both fractions. */
+ double dfadt = 0.0; /* Derivative result for point A blending function. */
+ double dfbdt = 0.0; /* = B. */
+ double dfcdt = 0.0; /* = C. */
+ double dfddt = 0.0; /* = D. */
+ double nder = 0.0; /* Derivative of fraction denominator. */
+ double zxder = 0.0; /* Derivative of x fraction counter. */
+ double zyder = 0.0; /* Derivative of y fraction counter. */
+ double nsq = 0.0; /* Denominator square value. */
+ int ec = 0; /* Error code for mathematical operations. */
+ int back = 0;
+
+
+#line 576 "dk3xsp.ctr"
+ if(pseg) {
+ back = 1;
+ /*
+ Initialize variables.
+ */
+#if VERSION_BEFORE_20150821
+ ua = ub = uc = ud = fa = fb = fc = fd = zx = zy = n = 0.0;
+#endif
+ /*
+ Set ua, ub, uc, ud.
+ */
+ if((pseg->b).s < 0.0) {
+ ua = -1.0 * t;
+ uc = t;
+ } else {
+ ua = ((pseg->b).s - t) / (1.0 + (pseg->b).s);
+ uc = ((pseg->b).s + t) / (1.0 + (pseg->b).s);
+ }
+ if((pseg->c).s < 0.0) {
+ ub = 1.0 - t;
+ ud = t - 1.0;
+ } else {
+ ub = (1.0 + (pseg->c).s - t) / (1.0 + (pseg->c).s);
+ ud = (t + (pseg->c).s - 1.0) / (1.0 + (pseg->c).s);
+ }
+
+
+#line 602 "dk3xsp.ctr"
+
+
+#line 603 "dk3xsp.ctr"
+
+
+#line 604 "dk3xsp.ctr"
+
+
+#line 605 "dk3xsp.ctr"
+ /*
+ Calculate fa, fb, fc, fd.
+ */
+ if((pseg->b).s < 0.0) {
+ fa = dk3xsp_h(ua, pseg->qa);
+ fc = dk3xsp_g(uc, pseg->pc, pseg->qc);
+ } else {
+ if(t < (pseg->b).s) {
+ fa = dk3xsp_f(ua, pseg->pa);
+ }
+ fc = dk3xsp_f(uc, pseg->pc);
+ }
+ if((pseg->c).s < 0.0) {
+ fb = dk3xsp_g(ub, pseg->pb, pseg->qb);
+ fd = dk3xsp_h(ud, pseg->qd);
+ } else {
+ fb = dk3xsp_f(ub, pseg->pb);
+ if(t > (1.0 - (pseg->c).s)) {
+ fd = dk3xsp_f(ud, pseg->pd);
+ }
+ }
+
+
+#line 627 "dk3xsp.ctr"
+
+
+#line 628 "dk3xsp.ctr"
+
+
+#line 629 "dk3xsp.ctr"
+
+
+#line 630 "dk3xsp.ctr"
+ /*
+ Calculate counters and denominator.
+ */
+ zx = dk3ma_d_add_ok(
+ dk3ma_d_add_ok(
+ ((pseg->ha) ? (fa * (pseg->a).x) : 0.0),
+ (fb * (pseg->b).x),
+ &ec
+ ),
+ dk3ma_d_add_ok(
+ (fc * (pseg->c).x),
+ ((pseg->hd) ? (fd * (pseg->d).x) : 0.0),
+ &ec
+ ),
+ &ec
+ );
+ zy = dk3ma_d_add_ok(
+ dk3ma_d_add_ok(
+ ((pseg->ha) ? (fa * (pseg->a).y) : 0.0),
+ (fb * (pseg->b).y),
+ &ec
+ ),
+ dk3ma_d_add_ok(
+ (fc * (pseg->c).y),
+ ((pseg->hd) ? (fd * (pseg->d).y) : 0.0),
+ &ec
+ ),
+ &ec
+ );
+ n = dk3ma_d_add_ok(
+ dk3ma_d_add_ok(((pseg->ha) ? fa : 0.0), fb, &ec),
+ dk3ma_d_add_ok(fc, ((pseg->hd) ? fd : 0.0), &ec),
+ &ec
+ );
+
+
+#line 665 "dk3xsp.ctr"
+
+
+#line 666 "dk3xsp.ctr"
+
+
+#line 667 "dk3xsp.ctr"
+ /*
+ Calculate x and y value.
+ */
+ pseg->x = dk3ma_d_div_ok(zx, n, &ec);
+ pseg->y = dk3ma_d_div_ok(zy, n, &ec);
+
+
+#line 673 "dk3xsp.ctr"
+
+
+#line 674 "dk3xsp.ctr"
+ /*
+ Calculate derivatives if required.
+ */
+ if(fder) {
+ /*
+ Initialize variables.
+ */
+ dfadt = dfbdt = dfcdt = dfddt = nder = zxder = zyder = 0.0;
+ /*
+ Calculate dfadt, dfbdt, dfcdt, dfddt.
+ */
+ if((pseg->b).s < 0.0) {
+ dfadt = dk3ma_d_mul_ok(dk3xsp_dhdu(ua, pseg->qa), pseg->duadt, &ec);
+ dfcdt = dk3ma_d_mul_ok(
+ dk3xsp_dgdu(uc, pseg->pc, pseg->qc),
+ pseg->ducdt,
+ &ec
+ );
+ } else {
+ if(t < (pseg->b).s) {
+ dfadt = dk3ma_d_mul_ok(dk3xsp_dfdu(ua, pseg->pa), pseg->duadt, &ec);
+ }
+ dfcdt = dk3ma_d_mul_ok(dk3xsp_dfdu(uc, pseg->pc), pseg->ducdt, &ec);
+ }
+ if((pseg->c).s < 0.0) {
+ dfbdt = dk3ma_d_mul_ok(
+ dk3xsp_dgdu(ub, pseg->pb, pseg->qb),
+ pseg->dubdt,
+ &ec
+ );
+ dfddt = dk3ma_d_mul_ok(dk3xsp_dhdu(ud, pseg->qd), pseg->duddt, &ec);
+ } else {
+ dfbdt = dk3ma_d_mul_ok(dk3xsp_dfdu(ub, pseg->pb), pseg->dubdt, &ec);
+ if(t > (1.0 - (pseg->c).s)) {
+ dfddt = dk3ma_d_mul_ok(dk3xsp_dfdu(ud, pseg->pd), pseg->duddt, &ec);
+ }
+ }
+
+
+#line 712 "dk3xsp.ctr"
+
+
+#line 713 "dk3xsp.ctr"
+
+
+#line 714 "dk3xsp.ctr"
+
+
+#line 715 "dk3xsp.ctr"
+ /*
+ Calculate counters and denominator.
+ */
+ zxder = dk3ma_d_add_ok(
+ dk3ma_d_add_ok(
+ ((pseg->ha) ? dk3ma_d_mul_ok(dfadt, (pseg->a).x, &ec) : 0.0),
+ dk3ma_d_mul_ok(dfbdt, (pseg->b).x, &ec),
+ &ec
+ ),
+ dk3ma_d_add_ok(
+ dk3ma_d_mul_ok(dfcdt, (pseg->c).x, &ec),
+ ((pseg->hd) ? dk3ma_d_mul_ok(dfddt, (pseg->d).x, &ec) : 0.0),
+ &ec
+ ),
+ &ec
+ );
+ zyder = dk3ma_d_add_ok(
+ dk3ma_d_add_ok(
+ ((pseg->ha) ? dk3ma_d_mul_ok(dfadt, (pseg->a).y, &ec) : 0.0),
+ dk3ma_d_mul_ok(dfbdt, (pseg->b).y, &ec),
+ &ec
+ ),
+ dk3ma_d_add_ok(
+ dk3ma_d_mul_ok(dfcdt, (pseg->c).y, &ec),
+ ((pseg->hd) ? dk3ma_d_mul_ok(dfddt, (pseg->d).y, &ec) : 0.0),
+ &ec
+ ),
+ &ec
+ );
+ nder = dk3ma_d_add_ok(
+ dk3ma_d_add_ok(((pseg->ha) ? dfadt : 0.0), dfbdt, &ec),
+ dk3ma_d_add_ok(dfcdt, ((pseg->hd) ? dfddt : 0.0), &ec),
+ &ec
+ );
+ nsq = n * n;
+
+
+#line 751 "dk3xsp.ctr"
+
+
+#line 752 "dk3xsp.ctr"
+
+
+#line 753 "dk3xsp.ctr"
+
+
+#line 754 "dk3xsp.ctr"
+ pseg->dxdt = dk3ma_d_div_ok(
+ dk3ma_d_sub_ok(
+ dk3ma_d_mul_ok(n, zxder, &ec),
+ dk3ma_d_mul_ok(zx, nder, &ec),
+ &ec
+ ),
+ nsq,
+ &ec
+ );
+ pseg->dydt = dk3ma_d_div_ok(
+ dk3ma_d_sub_ok(
+ dk3ma_d_mul_ok(n, zyder, &ec),
+ dk3ma_d_mul_ok(zy, nder, &ec),
+ &ec
+ ),
+ nsq,
+ &ec
+ );
+
+
+#line 773 "dk3xsp.ctr"
+
+
+#line 774 "dk3xsp.ctr"
+ }
+ if(ec) {
+ back = 0;
+ }
+ }
+
+#line 779 "dk3xsp.ctr"
+ return back;
+}
+
+
+
+/* ************************************************************************ */
+/* * * */
+/* * Length calculations for single segments. * */
+/* * * */
+/* ************************************************************************ */
+
+
+#line 787 "dk3xsp.ctr"
+
+
+
+int
+dk3xsp_is_null(double s)
+{
+ int back = 0;
+ if(fabs(s) < 1.0e-6) {
+ back = 1;
+ }
+ return back;
+}
+
+
+
+
+
+#line 803 "dk3xsp.ctr"
+
+
+
+/** Convert long to double.
+ @param l Long value to convert.
+ @return Conversion result.
+*/
+static
+double
+dk3xsp_l_to_d(long l)
+{
+ return ((double)l);
+}
+
+double
+dk3xsp_segment_length(
+ dk3_xspline_segment_t *pseg,
+ double prec,
+ int *ec
+)
+{
+ double back = -1.0;
+ double lastpassres; /* Result of previous pass. */
+ double passres; /* Result of current pass. */
+ double deltax; /* Delta x between points. */
+ double deltay; /* Delta y between points. */
+ double lastx; /* Previous x. */
+ double lasty; /* Previous y. */
+ double x = 0.0; /* Current x. */
+ double y = 0.0; /* Current y. */
+ double t; /* Current t. */
+ double dsegs; /* Double value of segs. */
+ long segs = 64L; /* Number of segments. */
+ long i; /* Current segment. */
+ int mec = 0; /* Mathematical error code. */
+ int mc = 1; /* Flag: Must continue. */
+ int cc = 1; /* Flag: Can continue. */
+
+
+#line 841 "dk3xsp.ctr"
+ if((pseg) && (prec > 0.0)) {
+ if(dk3xsp_is_null((pseg->b).s) && dk3xsp_is_null((pseg->c).s)) {
+ /*
+ Simple line.
+ */
+ deltax = dk3ma_d_sub_ok((pseg->c).x, (pseg->b).x, &mec);
+ deltay = dk3ma_d_sub_ok((pseg->c).y, (pseg->b).y, &mec);
+ back = sqrt(
+ dk3ma_d_add_ok(
+ dk3ma_d_mul_ok(deltax, deltax, &mec),
+ dk3ma_d_mul_ok(deltay, deltay, &mec),
+ &mec
+ )
+ );
+
+#line 855 "dk3xsp.ctr"
+ } else {
+
+#line 856 "dk3xsp.ctr"
+ /*
+ Spline calculation really necessary.
+ */
+ lastpassres = 0.0 - 2.0 * prec;
+ if(lastpassres > -1.0) { lastpassres = -1.0; }
+ while((cc) && (mc) && (!(mec))) {
+
+#line 862 "dk3xsp.ctr"
+ passres = 0.0;
+ if(dk3xsp_calculate(pseg, 0.0, 0)) {
+ lastx = dk3xsp_get_x(pseg);
+ lasty = dk3xsp_get_y(pseg);
+ dsegs = dk3xsp_l_to_d(segs);
+ for(i = 1L; i <= segs; i++) {
+ if(i == segs) {
+ t = 1.0;
+ } else {
+ t = dk3xsp_l_to_d(i) / dsegs;
+ }
+ if(dk3xsp_calculate(pseg, t, 0)) {
+ x = dk3xsp_get_x(pseg);
+ y = dk3xsp_get_y(pseg);
+ } else {
+ cc = 0;
+ mec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ if(cc) {
+ deltax = dk3ma_d_sub_ok(x, lastx, &mec);
+ deltay = dk3ma_d_sub_ok(y, lasty, &mec);
+ passres = dk3ma_d_add_ok(
+ passres,
+ sqrt(
+ dk3ma_d_add_ok(
+ dk3ma_d_mul_ok(deltax, deltax, &mec),
+ dk3ma_d_mul_ok(deltay, deltay, &mec),
+ &mec
+ )
+ ),
+ &mec
+ );
+ lastx = x; lasty = y;
+ }
+ }
+
+#line 897 "dk3xsp.ctr"
+ if(fabs(passres - lastpassres) < prec) {
+
+#line 898 "dk3xsp.ctr"
+ mc = 0; /* Finished successfully. */
+ back = passres;
+ } else {
+
+#line 901 "dk3xsp.ctr"
+ lastpassres = passres;
+ segs = segs * 2L;
+ if(segs > DK3XSP_MAX_ITERATION_SEGMENTS) {
+
+#line 904 "dk3xsp.ctr"
+ cc = 0;
+ if(ec) { *ec = DK3_ERROR_ITERATION; }
+ }
+ }
+ } else {
+ cc = 0;
+ mec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ }
+ if(mec) { back = -1.0; if(ec) { *ec = mec; } }
+ } else {
+ if(ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+
+#line 918 "dk3xsp.ctr"
+ return back;
+}
+
+
+
+double
+dk3xsp_segment_partial_length(
+ dk3_xspline_segment_t *pseg,
+ double tstart,
+ int dir,
+ double prec,
+ int *ec
+)
+{
+ double back = -1.0;
+ double lastpassres; /* Result of previous pass. */
+ double passres; /* Result of current pass. */
+ double deltax; /* Delta x between points. */
+ double deltay; /* Delta y between points. */
+ double lastx; /* Previous x. */
+ double lasty; /* Previous y. */
+ double x = 0.0; /* Current x. */
+ double y = 0.0; /* Current y. */
+ double t; /* Current t. */
+ double dsegs; /* Double value of segs. */
+ double tdiff; /* 1.0 - tstart. */
+ long segs = 64L; /* Number of segments. */
+ long i; /* Current segment. */
+ int mec = 0; /* Mathematical error code. */
+ int mc = 1; /* Flag: Must continue. */
+ int cc = 1; /* Flag: Can continue. */
+
+
+#line 950 "dk3xsp.ctr"
+ if((pseg) && (prec > 0.0) && (tstart >= 0.0) && (tstart<= 1.0)) {
+
+#line 951 "dk3xsp.ctr"
+ if(dk3xsp_is_null((pseg->b).s) && dk3xsp_is_null((pseg->c).s)) {
+ /*
+ Simple line.
+ */
+
+
+#line 956 "dk3xsp.ctr"
+ if(dk3xsp_calculate(pseg, tstart, 0)) {
+ x = dk3xsp_get_x(pseg);
+ y = dk3xsp_get_y(pseg);
+ } else {
+#if VERSION_BEFORE_20150821
+ cc = 0;
+#endif
+ mec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ if(dir) {
+ deltax = dk3ma_d_sub_ok((pseg->b).x, x, &mec);
+ deltay = dk3ma_d_sub_ok((pseg->b).y, y, &mec);
+ } else {
+ deltax = dk3ma_d_sub_ok((pseg->c).x, x, &mec);
+ deltay = dk3ma_d_sub_ok((pseg->c).y, y, &mec);
+ }
+ back = sqrt(
+ dk3ma_d_add_ok(
+ dk3ma_d_mul_ok(deltax, deltax, &mec),
+ dk3ma_d_mul_ok(deltay, deltay, &mec),
+ &mec
+ )
+ );
+ } else {
+ /*
+ Spline calculations really necessary.
+ */
+
+
+#line 984 "dk3xsp.ctr"
+ if(dir) {
+
+#line 985 "dk3xsp.ctr"
+ lastpassres = 0.0 - 2.0 * prec;
+ if(lastpassres > -1.0) { lastpassres = -1.0; }
+ while((cc) && (mc) && (!(mec))) {
+ passres = 0.0;
+ dsegs = dk3xsp_l_to_d(segs);
+ if(dk3xsp_calculate(pseg, 0.0, 0)) {
+ lastx = dk3xsp_get_x(pseg);
+ lasty = dk3xsp_get_y(pseg);
+ for(i = 1L; i <= segs; i++) {
+ if(i == segs) {
+ t = tstart;
+ } else {
+ t = (tstart * dk3xsp_l_to_d(i)) / dsegs;
+ }
+
+#line 999 "dk3xsp.ctr"
+ if(dk3xsp_calculate(pseg, t, 0)) {
+
+
+#line 1001 "dk3xsp.ctr"
+
+
+#line 1002 "dk3xsp.ctr"
+ x = dk3xsp_get_x(pseg);
+
+#line 1003 "dk3xsp.ctr"
+ y = dk3xsp_get_y(pseg);
+
+#line 1004 "dk3xsp.ctr"
+ deltax = dk3ma_d_sub_ok(x, lastx, &mec);
+
+#line 1005 "dk3xsp.ctr"
+ deltay = dk3ma_d_sub_ok(y, lasty, &mec);
+
+#line 1006 "dk3xsp.ctr"
+
+
+#line 1007 "dk3xsp.ctr"
+ passres = dk3ma_d_add_ok(
+ passres,
+ sqrt(
+ dk3ma_d_add_ok(
+ dk3ma_d_mul_ok(deltax, deltax, &mec),
+ dk3ma_d_mul_ok(deltay, deltay, &mec),
+ &mec
+ )
+ ),
+ &mec
+ );
+
+#line 1018 "dk3xsp.ctr"
+ lastx = x; lasty = y;
+ } else {
+ cc = 0;
+ mec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ if(fabs(passres - lastpassres) < prec) {
+ mc = 0;
+ back = passres;
+ } else {
+ lastpassres = passres;
+ segs = segs * 2L;
+ if(segs > DK3XSP_MAX_ITERATION_SEGMENTS) {
+ cc = 0;
+ if(ec) { *ec = DK3_ERROR_ITERATION; }
+ }
+ }
+ } else {
+ cc = 0;
+ mec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ } else {
+
+#line 1041 "dk3xsp.ctr"
+ tdiff = 1.0 - tstart;
+ lastpassres = 0.0 - 2.0 * prec;
+ if(lastpassres > -1.0) { lastpassres = -1.0; }
+ while((cc) && (mc) && (!(mec))) {
+ passres = 0.0;
+ dsegs = dk3xsp_l_to_d(segs);
+ if(dk3xsp_calculate(pseg, tstart, 0)) {
+ lastx = dk3xsp_get_x(pseg);
+ lasty = dk3xsp_get_y(pseg);
+ for(i = 1L; i <= segs; i++) {
+ if(i == segs) {
+
+#line 1052 "dk3xsp.ctr"
+ t = 1.0;
+ } else {
+ t = tstart + ((tdiff * dk3xsp_l_to_d(i)) / dsegs);
+ }
+
+
+#line 1057 "dk3xsp.ctr"
+ if(dk3xsp_calculate(pseg, t, 0)) {
+ x = dk3xsp_get_x(pseg);
+ y = dk3xsp_get_y(pseg);
+ } else {
+
+#line 1061 "dk3xsp.ctr"
+ cc = 0;
+ mec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ if(cc) {
+
+
+#line 1066 "dk3xsp.ctr"
+
+
+#line 1067 "dk3xsp.ctr"
+
+
+#line 1068 "dk3xsp.ctr"
+
+
+#line 1069 "dk3xsp.ctr"
+ deltax = dk3ma_d_sub_ok(x, lastx, &mec);
+ deltay = dk3ma_d_sub_ok(y, lasty, &mec);
+
+
+#line 1072 "dk3xsp.ctr"
+
+
+#line 1073 "dk3xsp.ctr"
+
+
+#line 1074 "dk3xsp.ctr"
+ passres = dk3ma_d_add_ok(
+ passres,
+ sqrt(
+ dk3ma_d_add_ok(
+ dk3ma_d_mul_ok(deltax, deltax, &mec),
+ dk3ma_d_mul_ok(deltay, deltay, &mec),
+ &mec
+ )
+ ),
+ &mec
+ );
+
+#line 1085 "dk3xsp.ctr"
+ lastx = x; lasty = y;
+ }
+ }
+ } else {
+ cc = 0;
+ mec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ if(fabs(passres - lastpassres) < prec) {
+ mc = 0;
+ back = passres;
+ } else {
+ lastpassres = passres;
+ segs = segs * 2L;
+ if(segs > DK3XSP_MAX_ITERATION_SEGMENTS) {
+ cc = 0;
+ if(ec) { *ec = DK3_ERROR_ITERATION; }
+ }
+ }
+ }
+ }
+ }
+ if(mec) { back = -1.0; if(ec) { *ec = mec; } }
+ } else {
+ if(ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+
+
+#line 1111 "dk3xsp.ctr"
+ return back;
+}
+
+
+
+/* ************************************************************************ */
+/* * * */
+/* * Length calculations for entire splines. * */
+/* * * */
+/* ************************************************************************ */
+
+
+#line 1119 "dk3xsp.ctr"
+
+
+
+double
+dk3xsp_open_spline_length(
+ dk3_fig_spline_point_t const *points,
+ size_t np,
+ double prec,
+ double *fslc,
+ int cb,
+ int *ec
+)
+{
+ dk3_xspline_segment_t seg;
+ double val;
+ double back = 0.0;
+ size_t i;
+ int mec = 0;
+
+
+#line 1138 "dk3xsp.ctr"
+ if((points) && (1 < np) && (prec > 0.0)) {
+ dk3xsp_reset(&seg);
+ if(cb) { dk3xsp_set_cb(&seg, 1); }
+ for(i = 0; ((i < (np - 1)) && (back > -1.0)); i++) {
+
+
+#line 1143 "dk3xsp.ctr"
+ val = -1.0;
+ if(fslc) {
+ val = fslc[i];
+ }
+ if(val < -0.5) {
+ dk3xsp_set(
+ &seg,
+ ((i > 1) ? (&(points[i-1])) : NULL),
+ &(points[i]),
+ &(points[i+1]),
+ ((i < (np - 2)) ? &(points[i+2]) : NULL)
+ );
+ val = dk3xsp_segment_length(&seg, (prec / (double)(np - 1)), ec);
+ if(val >= 0.0) {
+ if(fslc) {
+ fslc[i] = val;
+ }
+ }
+ }
+ if(val < 0.0) {
+ back = -1.0; i = np - 1;
+ } else {
+ back = dk3ma_d_add_ok(back, val, &mec);
+ if(mec) {
+ back = -1.0; i = np - 1;
+ if(ec) { *ec = mec; }
+ }
+ }
+ }
+ } else {
+ if(ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+
+#line 1175 "dk3xsp.ctr"
+ return back;
+}
+
+
+
+/** Find Index of segment start point.
+ @param tstart Parameter t.
+ @param ec Pointer to error code variable, required.
+ @return Start segment index.
+*/
+static
+size_t
+dk3xsp_find_segment_start(double tstart, int *ec)
+{
+#if VERSION_BEFORE_20140809
+ unsigned long ul;
+ size_t back = 0;
+ int mec = 0;
+
+
+#line 1194 "dk3xsp.ctr"
+ ul = dk3ma_d_to_ul_ok(floor(tstart), &mec);
+ if(mec) {
+ *ec = mec;
+ } else {
+ back = (size_t)ul;
+ if((unsigned long)back != ul) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+
+#line 1203 "dk3xsp.ctr"
+ return back;
+#else
+ size_t back = 0;
+ int mec = 0;
+
+
+#line 1208 "dk3xsp.ctr"
+ back = dk3ma_d_to_sz_ok(floor(tstart), &mec);
+ if (mec) { if (ec) { *ec = mec; } }
+
+
+#line 1211 "dk3xsp.ctr"
+ return back;
+#endif
+}
+
+
+
+int
+dk3xsp_calculate_position(
+ dk3_xspline_segment_t *pseg,
+ dk3_fig_spline_point_t const *points,
+ size_t np,
+ double t,
+ int cb,
+ int der,
+ int *ec
+)
+{
+ size_t i = 0;
+ int back = 0;
+ int mec = 0;
+ if((pseg) && (points) && (np > 1) && ((t >= 0.0) && (t <= (double)(np - 1))))
+ {
+ i = dk3xsp_find_segment_start(t, &mec);
+ if(!(mec)) {
+ dk3xsp_reset(pseg);
+ dk3xsp_set_cb(pseg, cb);
+ if(i <= (np - 2)) {
+ /* Not final point */
+ dk3xsp_set(
+ pseg,
+ ((i > 0) ? &(points[i - 1]) : NULL),
+ &(points[i]),
+ &(points[i+1]),
+ ((i < (np - 2)) ? &(points[i + 2]) : NULL)
+ );
+ back = dk3xsp_calculate(pseg, (t - (double)i), der);
+ } else {
+ /* In final point */
+ dk3xsp_set(
+ pseg,
+ ((np > 2) ? &(points[np - 3]): NULL),
+ &(points[np - 2]),
+ &(points[np - 1]),
+ NULL
+ );
+ back = dk3xsp_calculate(pseg, 1.0, der);
+ }
+ } else {
+ if(ec) { *ec = mec; }
+ }
+ }
+ else
+ {
+ if(ec) { *ec = DK3_ERROR_INVALID_ARGS;}
+ }
+ return back;
+}
+
+
+
+double
+dk3xsp_open_spline_partial_length(
+ dk3_fig_spline_point_t const *points,
+ size_t np,
+ double prec,
+ double tstart,
+ double *fslc,
+ int dir,
+ int cb,
+ int *ec
+)
+{
+ dk3_xspline_segment_t seg;
+ double back = -1.0;
+ double val;
+ size_t startseg;
+ size_t i;
+ int mec = 0;
+
+
+#line 1290 "dk3xsp.ctr"
+ if((points) && (1 < np) && (prec > 0.0)) {
+ if((tstart >= 0.0) && (tstart <= ((double)(np - 1)))) {
+ dk3xsp_reset(&seg);
+ if(cb) { dk3xsp_set_cb(&seg, 1); }
+ startseg = dk3xsp_find_segment_start(tstart, &mec);
+ if(mec) {
+
+#line 1296 "dk3xsp.ctr"
+ if(ec) { *ec = mec; }
+ } else {
+
+#line 1298 "dk3xsp.ctr"
+ if(startseg == (np - 1)) {
+
+#line 1299 "dk3xsp.ctr"
+ /*
+ tstart points to the final point.
+ So we have 0 for forward length or the full
+ spline length for backward length.
+ */
+ if(dir) {
+
+#line 1305 "dk3xsp.ctr"
+ back = dk3xsp_open_spline_length(points, np, prec, fslc, cb, ec);
+ } else {
+
+#line 1307 "dk3xsp.ctr"
+ back = 0.0;
+ }
+ } else {
+
+#line 1310 "dk3xsp.ctr"
+ if(tstart > 0.0) {
+
+#line 1311 "dk3xsp.ctr"
+ /*
+ tstart points to somewhere in the spline.
+ We have to calculate one segment partially, all other
+ segments completely.
+ */
+ dk3xsp_set(
+ &seg,
+ ((startseg > 0) ? &(points[startseg-1]) : NULL),
+ &(points[startseg]),
+ &(points[startseg+1]),
+ ((startseg < (np - 2)) ? &(points[startseg+2]) : NULL)
+ );
+ val = dk3xsp_segment_partial_length(
+ &seg,(tstart - (double)startseg),dir,(prec / (double)(np - 1)),ec
+ );
+ if(val >= 0.0) {
+
+#line 1327 "dk3xsp.ctr"
+ back = val;
+ /*
+ Partial segment calculated successfully.
+ Now calculate other segments.
+ */
+ if(dir) {
+
+#line 1333 "dk3xsp.ctr"
+ /*
+ Calculate all segments before the partial one.
+ */
+ for(i = 0; ((i < startseg) && (back > -1.0)); i++) {
+ val = -1.0;
+
+#line 1338 "dk3xsp.ctr"
+ if(fslc) {
+ val = fslc[i];
+ }
+ if(val < -0.5) {
+ dk3xsp_set(
+ &seg,
+ ((i > 0) ? &(points[i-1]) : NULL),
+ &(points[i]),
+ &(points[i+1]),
+ ((i < (np - 2)) ? &(points[i+2]) : NULL)
+ );
+ val = dk3xsp_segment_length(
+ &seg, (prec / (double)(np - 1)), ec
+ );
+ if(val >= 0.0) {
+ if(fslc) {
+ fslc[i] = val;
+ }
+ }
+ }
+ if(val >= 0.0) {
+
+#line 1359 "dk3xsp.ctr"
+ back = dk3ma_d_add_ok(back, val, &mec);
+ if(mec) {
+ back = -1.0; i = np;
+ if(ec) { *ec = mec; }
+ }
+ } else {
+ back = -1.0; i = np;
+ }
+ }
+ } else {
+
+#line 1369 "dk3xsp.ctr"
+ /*
+ Calculate all segments after the partial one.
+ */
+ for(i = (startseg + 1); ((i < (np - 1)) && (back > -1)); i++) {
+ val = -1.0;
+
+#line 1374 "dk3xsp.ctr"
+ if(fslc) {
+ val = fslc[i];
+ }
+ if(val < -0.5) {
+ dk3xsp_set(
+ &seg,
+ ((i > 0) ? &(points[i-1]) : NULL),
+ &(points[i]),
+ &(points[i+1]),
+ ((i < (np - 2)) ? &(points[i+2]) : NULL)
+ );
+ val = dk3xsp_segment_length(
+ &seg, (prec / (double)(np - 1)), ec
+ );
+ if(val >= 0.0) {
+ if(fslc) {
+ fslc[i] = val;
+ }
+ }
+ }
+ if(val >= 0.0) {
+
+#line 1395 "dk3xsp.ctr"
+ back = dk3ma_d_add_ok(back, val, &mec);
+ if(mec) {
+ back = -1.0; i = np;
+ if(ec) { *ec = mec; }
+ }
+ } else {
+
+#line 1401 "dk3xsp.ctr"
+ back = -1.0; i = np;
+ }
+ }
+ }
+
+#line 1405 "dk3xsp.ctr"
+ } else {
+
+#line 1406 "dk3xsp.ctr"
+ }
+ } else {
+
+#line 1408 "dk3xsp.ctr"
+ /*
+ tstart points to the start point.
+ So we have the full spline length for forward length,
+ 0 for backward length.
+ */
+ if(0 == dir) {
+
+#line 1414 "dk3xsp.ctr"
+ back = dk3xsp_open_spline_length(points, np, prec, fslc, cb, ec);
+ } else {
+
+#line 1416 "dk3xsp.ctr"
+ back = 0.0;
+ }
+ }
+ }
+ }
+ } else {
+ if(ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ } else {
+ if(ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+
+#line 1427 "dk3xsp.ctr"
+ return back;
+}
+
+
+
+double
+dk3xsp_get_t_for_distance(
+ dk3_fig_spline_point_t const *points,
+ size_t np,
+ double dist,
+ double prec,
+ double *fslc,
+ int dir,
+ int cb,
+ int *ec
+)
+{
+ double back = -1.0;
+ double xl; /* Left x. */
+ double xr; /* Right x. */
+ double xc; /* Center x. */
+ double yl; /* Left y. */
+ double yr; /* Right y. */
+ double yc; /* Center y. */
+ double l; /* Spline length. */
+ double fprec; /* factor * precision. */
+ double ayl = 0.0; /* abs yl. */
+ double ayr = 0.0; /* abs yr. */
+ unsigned long passno = 0UL; /* Current pass. */
+ int mec = 0; /* Error code variable. */
+ int cc = 1; /* Flag: Can continue. */
+ int mc = 1; /* Flag: Must continue. */
+
+
+#line 1460 "dk3xsp.ctr"
+ fprec = 0.2 * prec;
+ if((points) && (1 < np) && (prec > 0.0) && (dist >= 0.0)) {
+ l = dk3xsp_open_spline_length(points, np, fprec, fslc, cb, &mec);
+
+
+#line 1464 "dk3xsp.ctr"
+ if(l > dist) {
+ xl = 0.0;
+ xr = (double)(np - 1);
+ if(dir) {
+ yl = 0.0 - dist;
+ yr = dk3ma_d_sub_ok(l, dist, &mec);
+
+#line 1470 "dk3xsp.ctr"
+ } else {
+ yl = dk3ma_d_sub_ok(l, dist, &mec);
+
+#line 1472 "dk3xsp.ctr"
+ yr = 0.0 - dist;
+ }
+ while((cc) && (mc) && (!(mec))) {
+ xc = 0.5 * dk3ma_d_add_ok(xl, xr, &mec);
+
+
+#line 1477 "dk3xsp.ctr"
+ yc = dk3ma_d_sub_ok(
+ dk3xsp_open_spline_partial_length(
+ points, np, fprec, xc, fslc, dir, cb, ec
+ ),
+ dist,
+ &mec
+ );
+
+#line 1484 "dk3xsp.ctr"
+
+
+#line 1485 "dk3xsp.ctr"
+
+
+#line 1486 "dk3xsp.ctr"
+
+
+#line 1487 "dk3xsp.ctr"
+ if(dir) {
+ if(yc > 0.0) {
+ xr = xc; yr = yc;
+ } else {
+ xl = xc; yl = yc;
+ }
+ } else {
+ if(yc > 0.0) {
+ xl = xc; yl = yc;
+ } else {
+ xr = xc; yr = yc;
+ }
+ }
+ ayl = fabs(yl);
+ ayr = fabs(yr);
+ if((ayl < prec) && (ayr < prec)) {
+ mc = 0;
+ } else {
+ passno++;
+
+#line 1506 "dk3xsp.ctr"
+ if(passno > 1000UL) {
+
+#line 1507 "dk3xsp.ctr"
+ mec = DK3_ERROR_ITERATION;
+ } else {
+ }
+ }
+ }
+ if((cc) && (!(mec))) {
+
+#line 1513 "dk3xsp.ctr"
+ back = xl + ((xr - xl) * ayl)/(ayl + ayr);
+ }
+ if(mec) {
+
+#line 1516 "dk3xsp.ctr"
+ back = -1.0;
+ if(ec) { *ec = mec; }
+ }
+ } else {
+ if(ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ } else {
+ if(ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+
+#line 1525 "dk3xsp.ctr"
+ return back;
+}
+
+
+
+double
+dk3xsp_direction(
+ dk3_fig_spline_point_t const *points,
+ size_t np,
+ double t,
+ int cb,
+ int *ec
+)
+{
+ dk3_xspline_segment_t seg;
+ double back = -10.0 * M_PI;
+ double dxdt;
+ double dydt;
+ double delta;
+ double tleft;
+ double tright;
+ double xleft;
+ double xright;
+ double yleft;
+ double yright;
+ int mec = 0;
+
+
+#line 1552 "dk3xsp.ctr"
+ if((points) && (1 < np)) {
+ if((t >= 0.0) && (t <= ((double)(np - 1)))) {
+ dk3xsp_reset(&seg);
+ dk3xsp_set_cb(&seg, ((cb) ? 1 : 0));
+ if(dk3xsp_calculate_position(&seg, points, np, t, cb, 1, &mec)) {
+ dxdt = dk3xsp_get_dxdt(&seg);
+ dydt = dk3xsp_get_dydt(&seg);
+ if((fabs(dxdt) > 1.0e-6) || (fabs(dydt) > 1.0e-6)) {
+ back = dk3ma_d_atan2(dydt, dxdt);
+ } else {
+
+#line 1562 "dk3xsp.ctr"
+ delta = 0.001;
+ tleft = tright = t;
+ if(t > delta) { tleft = t - delta; }
+ if(t < (((double)(np - 1)) - delta)) { tright = t + delta; }
+ if(dk3xsp_calculate_position(&seg, points, np, tleft, cb, 0, &mec)) {
+ xleft = dk3xsp_get_x(&seg);
+ yleft = dk3xsp_get_y(&seg);
+ if(dk3xsp_calculate_position(&seg, points, np, tright, cb, 0, &mec)) {
+ xright = dk3xsp_get_x(&seg);
+ yright = dk3xsp_get_y(&seg);
+ dxdt = dk3ma_d_sub_ok(xright, xleft, &mec);
+ dydt = dk3ma_d_sub_ok(yright, yleft, &mec);
+ back = dk3ma_d_atan2(dydt, dxdt);
+ } else {
+
+#line 1576 "dk3xsp.ctr"
+ }
+ } else {
+
+#line 1578 "dk3xsp.ctr"
+ }
+ }
+ } else {
+
+#line 1581 "dk3xsp.ctr"
+ }
+ if(mec) { if(ec) { *ec = mec; } }
+ } else {
+ if(ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ } else {
+ if(ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+
+#line 1589 "dk3xsp.ctr"
+ return back;
+}
+
+
+
+double
+dk3xsp_direction_and_position(
+ double *xpos,
+ double *ypos,
+ dk3_fig_spline_point_t const *points,
+ size_t np,
+ double t,
+ int cb,
+ int *ec
+)
+{
+ dk3_xspline_segment_t seg;
+ double back = -10.0 * M_PI;
+ double dxdt;
+ double dydt;
+ double delta;
+ double tleft;
+ double tright;
+ double xleft;
+ double xright;
+ double yleft;
+ double yright;
+ int mec = 0;
+
+
+#line 1618 "dk3xsp.ctr"
+ if((points) && (1 < np) && (xpos) && (ypos)) {
+ if((t >= 0.0) && (t <= ((double)(np - 1)))) {
+ dk3xsp_reset(&seg);
+ dk3xsp_set_cb(&seg, ((cb) ? 1 : 0));
+ if(dk3xsp_calculate_position(&seg, points, np, t, cb, 1, &mec)) {
+ *xpos = dk3xsp_get_x(&seg);
+ *ypos = dk3xsp_get_y(&seg);
+ dxdt = dk3xsp_get_dxdt(&seg);
+ dydt = dk3xsp_get_dydt(&seg);
+
+#line 1627 "dk3xsp.ctr"
+ if((fabs(dxdt) > 1.0e-6) || (fabs(dydt) > 1.0e-6)) {
+ back = dk3ma_d_atan2(dydt, dxdt);
+
+#line 1629 "dk3xsp.ctr"
+ } else {
+
+#line 1630 "dk3xsp.ctr"
+ delta = 0.001;
+ tleft = tright = t;
+ if(t > delta) { tleft = t - delta; }
+ if(t < (((double)(np - 1)) - delta)) { tright = t + delta; }
+ if(dk3xsp_calculate_position(&seg, points, np, tleft, cb, 0, &mec)) {
+ xleft = dk3xsp_get_x(&seg);
+ yleft = dk3xsp_get_y(&seg);
+ if(dk3xsp_calculate_position(&seg, points, np, tright, cb, 0, &mec)) {
+ xright = dk3xsp_get_x(&seg);
+ yright = dk3xsp_get_y(&seg);
+ dxdt = dk3ma_d_sub_ok(xright, xleft, &mec);
+ dydt = dk3ma_d_sub_ok(yright, yleft, &mec);
+ back = dk3ma_d_atan2(dydt, dxdt);
+ } else {
+
+#line 1644 "dk3xsp.ctr"
+ }
+ } else {
+
+#line 1646 "dk3xsp.ctr"
+ }
+ }
+ } else {
+
+#line 1649 "dk3xsp.ctr"
+ }
+ if(mec) { if(ec) { *ec = mec; } }
+ } else {
+ if(ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ } else {
+ if(ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+
+#line 1657 "dk3xsp.ctr"
+ return back;
+}
+
+
diff --git a/support/dktools/dk3xsp.ctr b/support/dktools/dk3xsp.ctr
new file mode 100644
index 0000000000..fbaafb8738
--- /dev/null
+++ b/support/dktools/dk3xsp.ctr
@@ -0,0 +1,1660 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+%% header
+
+#include "dk3all.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Reset spline segment data.
+ All components - including cb - are reset.
+ @param pseg Spline segment data to reset.
+*/
+void
+dk3xsp_reset(dk3_xspline_segment_t *pseg);
+
+/** Set compatility bug flag.
+ @param pseg Spline segment data to modify.
+ @param v New flag value (1 or 0).
+*/
+void
+dk3xsp_set_cb(dk3_xspline_segment_t *pseg, int v);
+
+/** Set control points.
+ @param pseg Spline segment data to modify.
+ @param a Control point A (may be NULL).
+ @param b Control point B.
+ @param c Control point C.
+ @param d Control point D (may be NULL).
+*/
+void
+dk3xsp_set(
+ dk3_xspline_segment_t *pseg,
+ dk3_fig_spline_point_t const *a,
+ dk3_fig_spline_point_t const *b,
+ dk3_fig_spline_point_t const *c,
+ dk3_fig_spline_point_t const *d
+);
+
+/** Run calculation for a given t.
+ @param pseg Spline segment.
+ @param t The t parameter.
+ @param fder Flag: Calculate derivatives (1=yes, 0=no).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3xsp_calculate(
+ dk3_xspline_segment_t *pseg,
+ double t,
+ int fder
+);
+
+/** Retrieve calculation result.
+ @param pseg Spline segment.
+ @return Calculation result: x value.
+*/
+double
+dk3xsp_get_x(dk3_xspline_segment_t const *pseg);
+
+/** Retrieve calculation result.
+ @param pseg Spline segment.
+ @return Calculation result: y value.
+*/
+double
+dk3xsp_get_y(dk3_xspline_segment_t const *pseg);
+
+/** Retrieve calculation result.
+ @param pseg Spline segment.
+ @return Calculation result: dx/dt value.
+*/
+double
+dk3xsp_get_dxdt(dk3_xspline_segment_t const *pseg);
+
+/** Retrieve calculation result.
+ @param pseg Spline segment.
+ @return Calculation result: dy/dt value.
+*/
+double
+dk3xsp_get_dydt(dk3_xspline_segment_t const *pseg);
+
+/** Calculate X-spline segment interval length.
+ @param pseg Segment to calculate the length for.
+ @param prec Precision.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Length (positive value) on success, negative value on error.
+*/
+double
+dk3xsp_segment_length(
+ dk3_xspline_segment_t *pseg,
+ double prec,
+ int *ec
+);
+
+/** Calculate X-spline partial segment length.
+ @param pseg Segment to calculate the length for.
+ @param tstart Parameter t for start.
+ @param dir Direction (0=forward t to 1, 1=backward 0 to t).
+ @param prec Precision.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Length (positive value) on success, negative value on error.
+*/
+double
+dk3xsp_segment_partial_length(
+ dk3_xspline_segment_t *pseg,
+ double tstart,
+ int dir,
+ double prec,
+ int *ec
+);
+
+/** Check whether an s value is very close to 0.
+ @param s Value to check.
+ @return 1 if s==0, 0 otherwise.
+*/
+int
+dk3xsp_is_null(double s);
+
+/** Calculate length of open X-spline.
+ @param points Array of spline points.
+ @param np Number of points in array.
+ @param prec Numeric precision.
+ @param fslc Full segment length cache (np - 1) elements.
+ @param cb Flag: Compatibility bug.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Length (positive value) on success, negative value on error.
+*/
+double
+dk3xsp_open_spline_length(
+ dk3_fig_spline_point_t const *points,
+ size_t np,
+ double prec,
+ double *fslc,
+ int cb,
+ int *ec
+);
+
+/** Calculate length of open X-spline.
+ @param points Array of spline points.
+ @param np Number of points in array.
+ @param prec Numeric precision.
+ @param tstart Start/end t parameter.
+ @param fslc Full segment length cache, (np-1) elements.
+ @param dir Direction (0=forward t to 1, 1=backward 0 to t).
+ @param cb Flag: Compatibility bug.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Length (positive value) on success, negative value on error.
+*/
+double
+dk3xsp_open_spline_partial_length(
+ dk3_fig_spline_point_t const *points,
+ size_t np,
+ double prec,
+ double tstart,
+ double *fslc,
+ int dir,
+ int cb,
+ int *ec
+);
+
+/** Calculate t value for given distance to end point.
+ @param points X-spline points.
+ @param np Number of x-spline points.
+ @param dist Distance to endpoint.
+ @param prec Precision.
+ @param fslc Cache for full segment lengths.
+ @param dir End-point type: 0=end of spline, 1=start of spline.
+ @param cb Flag: Compatibility with spline bug.
+ @param ec Pointer to error code variable.
+ @return Non-negative value on success, negative value on error.
+*/
+double
+dk3xsp_get_t_for_distance(
+ dk3_fig_spline_point_t const *points,
+ size_t np,
+ double dist,
+ double prec,
+ double *fslc,
+ int dir,
+ int cb,
+ int *ec
+);
+
+/** Run calculations for a given t value in the range 0<=t<=(np-1).
+ @param pseg Segment to use for calculation.
+ @param points Spline points.
+ @param np Number of points.
+ @param t Parameter t.
+ @param cb Flag: Compatibility for spline bug.
+ @param der Flag: Calculate derivatives dx/dt and dy/dt too.
+ @param ec Pointer to error code variable.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3xsp_calculate_position(
+ dk3_xspline_segment_t *pseg,
+ dk3_fig_spline_point_t const *points,
+ size_t np,
+ double t,
+ int cb,
+ int der,
+ int *ec
+);
+
+/** Find movement direction for a specified t value.
+ @param points X-spline points.
+ @param np Number of points.
+ @param t The t parameter 0<=t<=(np-1).
+ @param cb Flag: Compatibility for spline bug.
+ @param ec Pointer to error code variable.
+ @return Non-negative value 0<=res<=2*pi on success,
+ negative value on error.
+*/
+double
+dk3xsp_direction(
+ dk3_fig_spline_point_t const *points,
+ size_t np,
+ double t,
+ int cb,
+ int *ec
+);
+
+/** Find position and movement direction for a specified t value.
+ @param xpos Pointer to variable for x position.
+ @param ypos Pointer to variable for y position.
+ @param points X-spline points.
+ @param np Number of points.
+ @param t The t parameter 0<=t<=(np-1).
+ @param cb Flag: Compatibility for spline bug.
+ @param ec Pointer to error code variable.
+ @return Non-negative value 0<=res<=2*pi on success,
+ negative value on error.
+*/
+double
+dk3xsp_direction_and_position(
+ double *xpos,
+ double *ypos,
+ dk3_fig_spline_point_t const *points,
+ size_t np,
+ double t,
+ int cb,
+ int *ec
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#ifndef DK3XSP_MAX_ITERATION_SEGMENTS
+/** Maximum number of sub-segments in segment length iteration.
+*/
+#define DK3XSP_MAX_ITERATION_SEGMENTS 1073741824L
+#endif
+
+%% module
+
+#include "dk3all.h"
+#include "dk3fig.h"
+#include "dk3xsp.h"
+
+$!trace-include
+
+
+
+$*
+Basic X-spline functions.
+$*
+
+
+
+$!trace-off
+
+
+
+/** Initialize spline point (set all components to 0.0).
+ @param ppt Point to initialize.
+*/
+static
+void
+dk3xsp_init_spline_point(dk3_fig_spline_point_t *ppt)
+{
+ ppt->x = 0.0; ppt->y = 0.0; ppt->s = 0.0;
+}
+
+
+
+/** Copy spline point or initialize a destination point.
+ @param pd Destination pointer.
+ @param ps Source pointer, may be NULL.
+*/
+static
+void
+dk3xsp_copy_spline_point(
+ dk3_fig_spline_point_t *pd, dk3_fig_spline_point_t const *ps
+)
+{
+ if(pd) {
+ if(ps) {
+ pd->x = ps->x; pd->y = ps->y; pd->s = ps->s;
+ } else {
+ dk3xsp_init_spline_point(pd);
+ }
+ }
+}
+
+
+
+void
+dk3xsp_reset(dk3_xspline_segment_t *pseg)
+{
+ if(pseg) {
+ dk3mem_res((void *)pseg, sizeof(dk3_xspline_segment_t));
+ dk3xsp_init_spline_point(&(pseg->a));
+ dk3xsp_init_spline_point(&(pseg->b));
+ dk3xsp_init_spline_point(&(pseg->c));
+ dk3xsp_init_spline_point(&(pseg->d));
+ pseg->pa = pseg->pb = pseg->pc = pseg->pd = 2.0;
+ pseg->qa = pseg->qb = pseg->qc = pseg->qd = 0.0;
+ pseg->x = pseg->y = pseg->dxdt = pseg->dydt = 0.0;
+ pseg->duadt = pseg->dubdt = pseg->ducdt = pseg->duddt = 0.0;
+ pseg->cb = 0;
+ }
+}
+
+
+
+void
+dk3xsp_set_cb(dk3_xspline_segment_t *pseg, int v)
+{
+ if(pseg) {
+ pseg->cb = ((v) ? 1 : 0);
+ }
+}
+
+
+
+/** The f(u) function.
+ @param u The u argument.
+ @param p The p parameter.
+ @return Function result.
+*/
+static
+double
+dk3xsp_f(double u, double p)
+{
+ double back;
+ back = u * u * u *(10.0 - p + u * (2.0 * p - 15.0 + u * (6.0 - p)));
+ $? "= f(%lg, %lg) = %lg", u, p, back
+ return back;
+}
+
+
+
+/** The f(u) function derived.
+ @param u The u argument.
+ @param p The p parameter.
+ @return Function result.
+*/
+static
+double
+dk3xsp_dfdu(double u, double p)
+{
+ double back;
+ back = u * u * (30.0 - 3.0*p + u * (8.0*p - 60.0 + u * (30.0 - 5.0*p)));
+ $? "= df/dt (%lg, %lg) = %lg", u, p, back
+ return back;
+}
+
+
+
+/** The g(u) function.
+ @param u Argument u.
+ @param p Parameter p.
+ @param q Parameter q.
+ @return Function result.
+*/
+static
+double
+dk3xsp_g(double u, double p, double q)
+{
+ double back;
+ back = u*(q+u*(2.0*q+u*(10.0-12.0*q-p+u*(2.0*p+14.0*q-15+u*(6.0-5.0*q-p)))));
+ $? "= g(%lg, %lg, %lg) = %lg", u, p, q, back
+ return back;
+}
+
+
+
+/** The g(u) function derived.
+ @param u Argument u.
+ @param p Parameter p.
+ @param q Parameter q.
+ @return Function result.
+*/
+static
+double
+dk3xsp_dgdu(double u, double p, double q)
+{
+ double back;
+ back =
+ q+u*(4.0*q+u*(30.0-3.0*p-36.0*q+u*(56.0*q+8.0*p-60.0+u*(30.0-5.0*p-25.0*q))));
+ $? "= dg/dt (%lg, %lg, %lg) = %lg", u, p, q, back
+ return back;
+}
+
+
+
+/** The h(u) function.
+ @param u Argument u.
+ @param q Parameter q.
+ @return Function result.
+*/
+static
+double
+dk3xsp_h(double u, double q)
+{
+ double back;
+ back = u*(q+u*(2.0*q-u*u*(q*(u+2.0))));
+ $? "= h(%lg, %lg) = %lg", u, q, back
+ return back;
+}
+
+
+
+/** The h(u) function derived.
+ @param u Argument u.
+ @param q Parameter q.
+ @return Function result.
+*/
+static
+double
+dk3xsp_dhdu(double u, double q)
+{
+ double back;
+ back = q+u*(4.0*q-u*u*(q*(8.0+5.0*u)));
+ $? "= dh/dt (%lg, %lg) = %lg", u, q, back
+ return back;
+}
+
+
+
+double
+dk3xsp_get_x(dk3_xspline_segment_t const *pseg)
+{
+ double back = 0.0;
+ if(pseg) {
+ back = pseg->x;
+ }
+ return back;
+}
+
+
+
+double
+dk3xsp_get_y(dk3_xspline_segment_t const *pseg)
+{
+ double back = 0.0;
+ if(pseg) {
+ back = pseg->y;
+ }
+ return back;
+}
+
+
+
+double
+dk3xsp_get_dxdt(dk3_xspline_segment_t const *pseg)
+{
+ double back = 0.0;
+ if(pseg) {
+ back = pseg->dxdt;
+ }
+ return back;
+}
+
+
+
+double
+dk3xsp_get_dydt(dk3_xspline_segment_t const *pseg)
+{
+ double back = 0.0;
+ if(pseg) {
+ back = pseg->dydt;
+ }
+ return back;
+}
+
+
+
+void
+dk3xsp_set(
+ dk3_xspline_segment_t *pseg,
+ dk3_fig_spline_point_t const *a,
+ dk3_fig_spline_point_t const *b,
+ dk3_fig_spline_point_t const *c,
+ dk3_fig_spline_point_t const *d
+)
+{
+ $? "+ dk3xsp_set"
+ if(pseg) {
+ pseg->ha = ((a) ? 1 : 0);
+ pseg->hd = ((d) ? 1 : 0);
+ dk3xsp_copy_spline_point(&(pseg->a), a);
+ dk3xsp_copy_spline_point(&(pseg->b), b);
+ dk3xsp_copy_spline_point(&(pseg->c), c);
+ dk3xsp_copy_spline_point(&(pseg->d), d);
+ pseg->pa = pseg->pb = pseg->pc = pseg->pd = 0.0;
+ pseg->qa = pseg->qb = pseg->qc = pseg->qd = 0.0;
+ pseg->duadt = pseg->dubdt = pseg->ducdt = pseg->duddt = 0.0;
+ if((pseg->b).s < 0.0) {
+ if(pseg->cb) {
+ pseg->qa = pseg->qc = 0.0 - ((pseg->b).s);
+ } else {
+ pseg->qa = pseg->qc = -0.5 * ((pseg->b).s);
+ }
+ pseg->duadt = -1.0; pseg->ducdt = 1.0;
+ } else {
+ pseg->pa = pseg->pc = 2.0 * (1.0 + (pseg->b).s) * (1.0 + (pseg->b).s);
+ pseg->ducdt = 1.0 / (1.0 + (pseg->b).s);
+ pseg->duadt = -1.0 * pseg->ducdt;
+ }
+ if((pseg->c).s < 0.0) {
+ if(pseg->cb) {
+ pseg->qb = pseg->qd = 0.0 - ((pseg->c).s);
+ } else {
+ pseg->qb = pseg->qd = -0.5 * ((pseg->c).s);
+ }
+ pseg->dubdt = -1.0; pseg->duddt = 1.0;
+ } else {
+ pseg->pb = pseg->pd = 2.0 * (1.0 + (pseg->c).s) * (1.0 + (pseg->c).s);
+ pseg->duddt = 1.0 / (1.0 + (pseg->c).s);
+ pseg->dubdt = -1.0 * pseg->duddt;
+ }
+ $? ". pa = %lg\tqa = %lg\tdua/dt = %lg", pseg->pa, pseg->qa, pseg->duadt
+ $? ". pb = %lg\tqb = %lg\tdub/dt = %lg", pseg->pb, pseg->qb, pseg->dubdt
+ $? ". pc = %lg\tqc = %lg\tduc/dt = %lg", pseg->pc, pseg->qc, pseg->ducdt
+ $? ". pd = %lg\tqd = %lg\tdud/dt = %lg", pseg->pd, pseg->qd, pseg->duddt
+ } $? "- dk3xsp_set"
+}
+
+
+
+int
+dk3xsp_calculate(
+ dk3_xspline_segment_t *pseg,
+ double t,
+ int fder
+)
+{
+ double ua = 0.0; /* Argument u for blending function from point A. */
+ double ub = 0.0; /* = B. */
+ double uc = 0.0; /* = C. */
+ double ud = 0.0; /* = D. */
+ double fa = 0.0; /* Result from blending function from point A. */
+ double fb = 0.0; /* = B. */
+ double fc = 0.0; /* = C. */
+ double fd = 0.0; /* = D. */
+ double zx = 0.0; /* Counter in fraction to calculate x. */
+ double zy = 0.0; /* Counter in fraction to calculate y. */
+ double n = 0.0; /* Denominator in both fractions. */
+ double dfadt = 0.0; /* Derivative result for point A blending function. */
+ double dfbdt = 0.0; /* = B. */
+ double dfcdt = 0.0; /* = C. */
+ double dfddt = 0.0; /* = D. */
+ double nder = 0.0; /* Derivative of fraction denominator. */
+ double zxder = 0.0; /* Derivative of x fraction counter. */
+ double zyder = 0.0; /* Derivative of y fraction counter. */
+ double nsq = 0.0; /* Denominator square value. */
+ int ec = 0; /* Error code for mathematical operations. */
+ int back = 0;
+ $? "+ dk3xsp_calculate %lg (fder=%d)", t, fder
+ if(pseg) {
+ back = 1;
+ /*
+ Initialize variables.
+ */
+#if VERSION_BEFORE_20150821
+ ua = ub = uc = ud = fa = fb = fc = fd = zx = zy = n = 0.0;
+#endif
+ /*
+ Set ua, ub, uc, ud.
+ */
+ if((pseg->b).s < 0.0) {
+ ua = -1.0 * t;
+ uc = t;
+ } else {
+ ua = ((pseg->b).s - t) / (1.0 + (pseg->b).s);
+ uc = ((pseg->b).s + t) / (1.0 + (pseg->b).s);
+ }
+ if((pseg->c).s < 0.0) {
+ ub = 1.0 - t;
+ ud = t - 1.0;
+ } else {
+ ub = (1.0 + (pseg->c).s - t) / (1.0 + (pseg->c).s);
+ ud = (t + (pseg->c).s - 1.0) / (1.0 + (pseg->c).s);
+ }
+ $? ". ua = %lg", ua
+ $? ". ub = %lg", ub
+ $? ". uc = %lg", uc
+ $? ". ud = %lg", ud
+ /*
+ Calculate fa, fb, fc, fd.
+ */
+ if((pseg->b).s < 0.0) {
+ fa = dk3xsp_h(ua, pseg->qa);
+ fc = dk3xsp_g(uc, pseg->pc, pseg->qc);
+ } else {
+ if(t < (pseg->b).s) {
+ fa = dk3xsp_f(ua, pseg->pa);
+ }
+ fc = dk3xsp_f(uc, pseg->pc);
+ }
+ if((pseg->c).s < 0.0) {
+ fb = dk3xsp_g(ub, pseg->pb, pseg->qb);
+ fd = dk3xsp_h(ud, pseg->qd);
+ } else {
+ fb = dk3xsp_f(ub, pseg->pb);
+ if(t > (1.0 - (pseg->c).s)) {
+ fd = dk3xsp_f(ud, pseg->pd);
+ }
+ }
+ $? ". fa = %lg", fa
+ $? ". fb = %lg", fb
+ $? ". fc = %lg", fc
+ $? ". fd = %lg", fd
+ /*
+ Calculate counters and denominator.
+ */
+ zx = dk3ma_d_add_ok(
+ dk3ma_d_add_ok(
+ ((pseg->ha) ? (fa * (pseg->a).x) : 0.0),
+ (fb * (pseg->b).x),
+ &ec
+ ),
+ dk3ma_d_add_ok(
+ (fc * (pseg->c).x),
+ ((pseg->hd) ? (fd * (pseg->d).x) : 0.0),
+ &ec
+ ),
+ &ec
+ );
+ zy = dk3ma_d_add_ok(
+ dk3ma_d_add_ok(
+ ((pseg->ha) ? (fa * (pseg->a).y) : 0.0),
+ (fb * (pseg->b).y),
+ &ec
+ ),
+ dk3ma_d_add_ok(
+ (fc * (pseg->c).y),
+ ((pseg->hd) ? (fd * (pseg->d).y) : 0.0),
+ &ec
+ ),
+ &ec
+ );
+ n = dk3ma_d_add_ok(
+ dk3ma_d_add_ok(((pseg->ha) ? fa : 0.0), fb, &ec),
+ dk3ma_d_add_ok(fc, ((pseg->hd) ? fd : 0.0), &ec),
+ &ec
+ );
+ $? ". zx = %lg", zx
+ $? ". zy = %lg", zy
+ $? ". n = %lg", n
+ /*
+ Calculate x and y value.
+ */
+ pseg->x = dk3ma_d_div_ok(zx, n, &ec);
+ pseg->y = dk3ma_d_div_ok(zy, n, &ec);
+ $? ". x = %lg", pseg->x
+ $? ". y = %lg", pseg->y
+ /*
+ Calculate derivatives if required.
+ */
+ if(fder) {
+ /*
+ Initialize variables.
+ */
+ dfadt = dfbdt = dfcdt = dfddt = nder = zxder = zyder = 0.0;
+ /*
+ Calculate dfadt, dfbdt, dfcdt, dfddt.
+ */
+ if((pseg->b).s < 0.0) {
+ dfadt = dk3ma_d_mul_ok(dk3xsp_dhdu(ua, pseg->qa), pseg->duadt, &ec);
+ dfcdt = dk3ma_d_mul_ok(
+ dk3xsp_dgdu(uc, pseg->pc, pseg->qc),
+ pseg->ducdt,
+ &ec
+ );
+ } else {
+ if(t < (pseg->b).s) {
+ dfadt = dk3ma_d_mul_ok(dk3xsp_dfdu(ua, pseg->pa), pseg->duadt, &ec);
+ }
+ dfcdt = dk3ma_d_mul_ok(dk3xsp_dfdu(uc, pseg->pc), pseg->ducdt, &ec);
+ }
+ if((pseg->c).s < 0.0) {
+ dfbdt = dk3ma_d_mul_ok(
+ dk3xsp_dgdu(ub, pseg->pb, pseg->qb),
+ pseg->dubdt,
+ &ec
+ );
+ dfddt = dk3ma_d_mul_ok(dk3xsp_dhdu(ud, pseg->qd), pseg->duddt, &ec);
+ } else {
+ dfbdt = dk3ma_d_mul_ok(dk3xsp_dfdu(ub, pseg->pb), pseg->dubdt, &ec);
+ if(t > (1.0 - (pseg->c).s)) {
+ dfddt = dk3ma_d_mul_ok(dk3xsp_dfdu(ud, pseg->pd), pseg->duddt, &ec);
+ }
+ }
+ $? ". dfadt = %lg", dfadt
+ $? ". dfbdt = %lg", dfbdt
+ $? ". dfcdt = %lg", dfcdt
+ $? ". dfddt = %lg", dfddt
+ /*
+ Calculate counters and denominator.
+ */
+ zxder = dk3ma_d_add_ok(
+ dk3ma_d_add_ok(
+ ((pseg->ha) ? dk3ma_d_mul_ok(dfadt, (pseg->a).x, &ec) : 0.0),
+ dk3ma_d_mul_ok(dfbdt, (pseg->b).x, &ec),
+ &ec
+ ),
+ dk3ma_d_add_ok(
+ dk3ma_d_mul_ok(dfcdt, (pseg->c).x, &ec),
+ ((pseg->hd) ? dk3ma_d_mul_ok(dfddt, (pseg->d).x, &ec) : 0.0),
+ &ec
+ ),
+ &ec
+ );
+ zyder = dk3ma_d_add_ok(
+ dk3ma_d_add_ok(
+ ((pseg->ha) ? dk3ma_d_mul_ok(dfadt, (pseg->a).y, &ec) : 0.0),
+ dk3ma_d_mul_ok(dfbdt, (pseg->b).y, &ec),
+ &ec
+ ),
+ dk3ma_d_add_ok(
+ dk3ma_d_mul_ok(dfcdt, (pseg->c).y, &ec),
+ ((pseg->hd) ? dk3ma_d_mul_ok(dfddt, (pseg->d).y, &ec) : 0.0),
+ &ec
+ ),
+ &ec
+ );
+ nder = dk3ma_d_add_ok(
+ dk3ma_d_add_ok(((pseg->ha) ? dfadt : 0.0), dfbdt, &ec),
+ dk3ma_d_add_ok(dfcdt, ((pseg->hd) ? dfddt : 0.0), &ec),
+ &ec
+ );
+ nsq = n * n;
+ $? ". zxder = %lg", zxder
+ $? ". zyder = %lg", zyder
+ $? ". nder = %lg", nder
+ $? ". n^2 = %lg", nsq
+ pseg->dxdt = dk3ma_d_div_ok(
+ dk3ma_d_sub_ok(
+ dk3ma_d_mul_ok(n, zxder, &ec),
+ dk3ma_d_mul_ok(zx, nder, &ec),
+ &ec
+ ),
+ nsq,
+ &ec
+ );
+ pseg->dydt = dk3ma_d_div_ok(
+ dk3ma_d_sub_ok(
+ dk3ma_d_mul_ok(n, zyder, &ec),
+ dk3ma_d_mul_ok(zy, nder, &ec),
+ &ec
+ ),
+ nsq,
+ &ec
+ );
+ $? ". dx/dt = %lg", pseg->dxdt
+ $? ". dy/dt = %lg", pseg->dydt
+ }
+ if(ec) {
+ back = 0;
+ }
+ } $? "- dk3xsp_calculate %d", back
+ return back;
+}
+
+
+
+$*
+Length calculations for single segments.
+$*
+
+
+
+int
+dk3xsp_is_null(double s)
+{
+ int back = 0;
+ if(fabs(s) < 1.0e-6) {
+ back = 1;
+ }
+ return back;
+}
+
+
+
+$!trace-on
+
+
+
+/** Convert long to double.
+ @param l Long value to convert.
+ @return Conversion result.
+*/
+static
+double
+dk3xsp_l_to_d(long l)
+{
+ return ((double)l);
+}
+
+double
+dk3xsp_segment_length(
+ dk3_xspline_segment_t *pseg,
+ double prec,
+ int *ec
+)
+{
+ double back = -1.0;
+ double lastpassres; /* Result of previous pass. */
+ double passres; /* Result of current pass. */
+ double deltax; /* Delta x between points. */
+ double deltay; /* Delta y between points. */
+ double lastx; /* Previous x. */
+ double lasty; /* Previous y. */
+ double x = 0.0; /* Current x. */
+ double y = 0.0; /* Current y. */
+ double t; /* Current t. */
+ double dsegs; /* Double value of segs. */
+ long segs = 64L; /* Number of segments. */
+ long i; /* Current segment. */
+ int mec = 0; /* Mathematical error code. */
+ int mc = 1; /* Flag: Must continue. */
+ int cc = 1; /* Flag: Can continue. */
+ $? "+ dk3xsp_segment_length prec=%lg", prec
+ if((pseg) && (prec > 0.0)) {
+ if(dk3xsp_is_null((pseg->b).s) && dk3xsp_is_null((pseg->c).s)) {
+ /*
+ Simple line.
+ */
+ deltax = dk3ma_d_sub_ok((pseg->c).x, (pseg->b).x, &mec);
+ deltay = dk3ma_d_sub_ok((pseg->c).y, (pseg->b).y, &mec);
+ back = sqrt(
+ dk3ma_d_add_ok(
+ dk3ma_d_mul_ok(deltax, deltax, &mec),
+ dk3ma_d_mul_ok(deltay, deltay, &mec),
+ &mec
+ )
+ ); $? ". straight-forward line"
+ } else { $? ". real spline"
+ /*
+ Spline calculation really necessary.
+ */
+ lastpassres = 0.0 - 2.0 * prec;
+ if(lastpassres > -1.0) { lastpassres = -1.0; }
+ while((cc) && (mc) && (!(mec))) { $? ". segs = %ld", segs
+ passres = 0.0;
+ if(dk3xsp_calculate(pseg, 0.0, 0)) {
+ lastx = dk3xsp_get_x(pseg);
+ lasty = dk3xsp_get_y(pseg);
+ dsegs = dk3xsp_l_to_d(segs);
+ for(i = 1L; i <= segs; i++) {
+ if(i == segs) {
+ t = 1.0;
+ } else {
+ t = dk3xsp_l_to_d(i) / dsegs;
+ }
+ if(dk3xsp_calculate(pseg, t, 0)) {
+ x = dk3xsp_get_x(pseg);
+ y = dk3xsp_get_y(pseg);
+ } else {
+ cc = 0;
+ mec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ if(cc) {
+ deltax = dk3ma_d_sub_ok(x, lastx, &mec);
+ deltay = dk3ma_d_sub_ok(y, lasty, &mec);
+ passres = dk3ma_d_add_ok(
+ passres,
+ sqrt(
+ dk3ma_d_add_ok(
+ dk3ma_d_mul_ok(deltax, deltax, &mec),
+ dk3ma_d_mul_ok(deltay, deltay, &mec),
+ &mec
+ )
+ ),
+ &mec
+ );
+ lastx = x; lasty = y;
+ }
+ } $? ". passres = %lg", passres
+ if(fabs(passres - lastpassres) < prec) { $? ". success"
+ mc = 0; /* Finished successfully. */
+ back = passres;
+ } else { $? ". diff = %lg", fabs(passres - lastpassres)
+ lastpassres = passres;
+ segs = segs * 2L;
+ if(segs > DK3XSP_MAX_ITERATION_SEGMENTS) { $? ". too many passes"
+ cc = 0;
+ if(ec) { *ec = DK3_ERROR_ITERATION; }
+ }
+ }
+ } else {
+ cc = 0;
+ mec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ }
+ if(mec) { back = -1.0; if(ec) { *ec = mec; } }
+ } else {
+ if(ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ } $? "- dk3xsp_segment_length %lg", back
+ return back;
+}
+
+
+
+double
+dk3xsp_segment_partial_length(
+ dk3_xspline_segment_t *pseg,
+ double tstart,
+ int dir,
+ double prec,
+ int *ec
+)
+{
+ double back = -1.0;
+ double lastpassres; /* Result of previous pass. */
+ double passres; /* Result of current pass. */
+ double deltax; /* Delta x between points. */
+ double deltay; /* Delta y between points. */
+ double lastx; /* Previous x. */
+ double lasty; /* Previous y. */
+ double x = 0.0; /* Current x. */
+ double y = 0.0; /* Current y. */
+ double t; /* Current t. */
+ double dsegs; /* Double value of segs. */
+ double tdiff; /* 1.0 - tstart. */
+ long segs = 64L; /* Number of segments. */
+ long i; /* Current segment. */
+ int mec = 0; /* Mathematical error code. */
+ int mc = 1; /* Flag: Must continue. */
+ int cc = 1; /* Flag: Can continue. */
+ $? "+ dk3xsp_segment_partial_length t=%lg prec=%lg dir=%d", tstart, prec,dir
+ if((pseg) && (prec > 0.0) && (tstart >= 0.0) && (tstart<= 1.0)) { $? ". args"
+ if(dk3xsp_is_null((pseg->b).s) && dk3xsp_is_null((pseg->c).s)) {
+ /*
+ Simple line.
+ */
+ $? ". simple line"
+ if(dk3xsp_calculate(pseg, tstart, 0)) {
+ x = dk3xsp_get_x(pseg);
+ y = dk3xsp_get_y(pseg);
+ } else {
+#if VERSION_BEFORE_20150821
+ cc = 0;
+#endif
+ mec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ if(dir) {
+ deltax = dk3ma_d_sub_ok((pseg->b).x, x, &mec);
+ deltay = dk3ma_d_sub_ok((pseg->b).y, y, &mec);
+ } else {
+ deltax = dk3ma_d_sub_ok((pseg->c).x, x, &mec);
+ deltay = dk3ma_d_sub_ok((pseg->c).y, y, &mec);
+ }
+ back = sqrt(
+ dk3ma_d_add_ok(
+ dk3ma_d_mul_ok(deltax, deltax, &mec),
+ dk3ma_d_mul_ok(deltay, deltay, &mec),
+ &mec
+ )
+ );
+ } else {
+ /*
+ Spline calculations really necessary.
+ */
+ $? ". real spline"
+ if(dir) { $? ". from 0 to t"
+ lastpassres = 0.0 - 2.0 * prec;
+ if(lastpassres > -1.0) { lastpassres = -1.0; }
+ while((cc) && (mc) && (!(mec))) {
+ passres = 0.0;
+ dsegs = dk3xsp_l_to_d(segs);
+ if(dk3xsp_calculate(pseg, 0.0, 0)) {
+ lastx = dk3xsp_get_x(pseg);
+ lasty = dk3xsp_get_y(pseg);
+ for(i = 1L; i <= segs; i++) {
+ if(i == segs) {
+ t = tstart;
+ } else {
+ t = (tstart * dk3xsp_l_to_d(i)) / dsegs;
+ } $? ". t=%lg (%ld/%ld)", t, i, segs
+ if(dk3xsp_calculate(pseg, t, 0)) {
+ $? ". lastx = %lg", lastx
+ $? ". lasty = %lg", lasty
+ x = dk3xsp_get_x(pseg); $? ". x = %lg", x
+ y = dk3xsp_get_y(pseg); $? ". y = %lg", y
+ deltax = dk3ma_d_sub_ok(x, lastx, &mec); $? ". deltax = %lg", deltax
+ deltay = dk3ma_d_sub_ok(y, lasty, &mec); $? ". deltay = %lg", deltay
+ $? ". passres = %lg", passres
+ passres = dk3ma_d_add_ok(
+ passres,
+ sqrt(
+ dk3ma_d_add_ok(
+ dk3ma_d_mul_ok(deltax, deltax, &mec),
+ dk3ma_d_mul_ok(deltay, deltay, &mec),
+ &mec
+ )
+ ),
+ &mec
+ ); $? ". passres = %lg", passres
+ lastx = x; lasty = y;
+ } else {
+ cc = 0;
+ mec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ if(fabs(passres - lastpassres) < prec) {
+ mc = 0;
+ back = passres;
+ } else {
+ lastpassres = passres;
+ segs = segs * 2L;
+ if(segs > DK3XSP_MAX_ITERATION_SEGMENTS) {
+ cc = 0;
+ if(ec) { *ec = DK3_ERROR_ITERATION; }
+ }
+ }
+ } else {
+ cc = 0;
+ mec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ } else { $? ". from t to 1"
+ tdiff = 1.0 - tstart;
+ lastpassres = 0.0 - 2.0 * prec;
+ if(lastpassres > -1.0) { lastpassres = -1.0; }
+ while((cc) && (mc) && (!(mec))) {
+ passres = 0.0;
+ dsegs = dk3xsp_l_to_d(segs);
+ if(dk3xsp_calculate(pseg, tstart, 0)) {
+ lastx = dk3xsp_get_x(pseg);
+ lasty = dk3xsp_get_y(pseg);
+ for(i = 1L; i <= segs; i++) {
+ if(i == segs) { $? ". t = 1"
+ t = 1.0;
+ } else {
+ t = tstart + ((tdiff * dk3xsp_l_to_d(i)) / dsegs);
+ }
+ $? ". t = %lg", t
+ if(dk3xsp_calculate(pseg, t, 0)) {
+ x = dk3xsp_get_x(pseg);
+ y = dk3xsp_get_y(pseg);
+ } else { $? "! calculation"
+ cc = 0;
+ mec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ if(cc) {
+ $? ". lastx = %lg", lastx
+ $? ". lasty = %lg", lasty
+ $? ". x = %lg", x
+ $? ". y = %lg", y
+ deltax = dk3ma_d_sub_ok(x, lastx, &mec);
+ deltay = dk3ma_d_sub_ok(y, lasty, &mec);
+ $? ". deltax = %lg", deltax
+ $? ". deltay = %lg", deltay
+ $? ". passres = %lg", passres
+ passres = dk3ma_d_add_ok(
+ passres,
+ sqrt(
+ dk3ma_d_add_ok(
+ dk3ma_d_mul_ok(deltax, deltax, &mec),
+ dk3ma_d_mul_ok(deltay, deltay, &mec),
+ &mec
+ )
+ ),
+ &mec
+ ); $? ". passres = %lg", passres
+ lastx = x; lasty = y;
+ }
+ }
+ } else {
+ cc = 0;
+ mec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ if(fabs(passres - lastpassres) < prec) {
+ mc = 0;
+ back = passres;
+ } else {
+ lastpassres = passres;
+ segs = segs * 2L;
+ if(segs > DK3XSP_MAX_ITERATION_SEGMENTS) {
+ cc = 0;
+ if(ec) { *ec = DK3_ERROR_ITERATION; }
+ }
+ }
+ }
+ }
+ }
+ if(mec) { back = -1.0; if(ec) { *ec = mec; } }
+ } else {
+ if(ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ $? "- dk3xsp_segment_partial_length %lg", back
+ return back;
+}
+
+
+
+$*
+Length calculations for entire splines.
+$*
+
+
+
+double
+dk3xsp_open_spline_length(
+ dk3_fig_spline_point_t const *points,
+ size_t np,
+ double prec,
+ double *fslc,
+ int cb,
+ int *ec
+)
+{
+ dk3_xspline_segment_t seg;
+ double val;
+ double back = 0.0;
+ size_t i;
+ int mec = 0;
+ $? "+ dk3xsp_open_spline_length prec=%lg", prec
+ if((points) && (1 < np) && (prec > 0.0)) {
+ dk3xsp_reset(&seg);
+ if(cb) { dk3xsp_set_cb(&seg, 1); }
+ for(i = 0; ((i < (np - 1)) && (back > -1.0)); i++) {
+ $? ". segment %u (%u points)", (unsigned)i, (unsigned)np
+ val = -1.0;
+ if(fslc) {
+ val = fslc[i];
+ }
+ if(val < -0.5) {
+ dk3xsp_set(
+ &seg,
+ ((i > 1) ? (&(points[i-1])) : NULL),
+ &(points[i]),
+ &(points[i+1]),
+ ((i < (np - 2)) ? &(points[i+2]) : NULL)
+ );
+ val = dk3xsp_segment_length(&seg, (prec / (double)(np - 1)), ec);
+ if(val >= 0.0) {
+ if(fslc) {
+ fslc[i] = val;
+ }
+ }
+ }
+ if(val < 0.0) {
+ back = -1.0; i = np - 1;
+ } else {
+ back = dk3ma_d_add_ok(back, val, &mec);
+ if(mec) {
+ back = -1.0; i = np - 1;
+ if(ec) { *ec = mec; }
+ }
+ }
+ }
+ } else {
+ if(ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ } $? "- dk3xsp_open_spline_length %lg", back
+ return back;
+}
+
+
+
+/** Find Index of segment start point.
+ @param tstart Parameter t.
+ @param ec Pointer to error code variable, required.
+ @return Start segment index.
+*/
+static
+size_t
+dk3xsp_find_segment_start(double tstart, int *ec)
+{
+#if VERSION_BEFORE_20140809
+ unsigned long ul;
+ size_t back = 0;
+ int mec = 0;
+ $? "+ dk3xsp_find_segment_start %lg", tstart
+ ul = dk3ma_d_to_ul_ok(floor(tstart), &mec);
+ if(mec) {
+ *ec = mec;
+ } else {
+ back = (size_t)ul;
+ if((unsigned long)back != ul) {
+ *ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } $? "- dk3xsp_find_segment_start %u", (unsigned)back
+ return back;
+#else
+ size_t back = 0;
+ int mec = 0;
+ $? "+ dk3xsp_find_segment_start %lg", tstart
+ back = dk3ma_d_to_sz_ok(floor(tstart), &mec);
+ if (mec) { if (ec) { *ec = mec; } }
+ $? "- dk3xsp_find_segment_start %u (ec=%d)", (unsigned)back, mec
+ return back;
+#endif
+}
+
+
+
+int
+dk3xsp_calculate_position(
+ dk3_xspline_segment_t *pseg,
+ dk3_fig_spline_point_t const *points,
+ size_t np,
+ double t,
+ int cb,
+ int der,
+ int *ec
+)
+{
+ size_t i = 0;
+ int back = 0;
+ int mec = 0;
+ if((pseg) && (points) && (np > 1) && ((t >= 0.0) && (t <= (double)(np - 1))))
+ {
+ i = dk3xsp_find_segment_start(t, &mec);
+ if(!(mec)) {
+ dk3xsp_reset(pseg);
+ dk3xsp_set_cb(pseg, cb);
+ if(i <= (np - 2)) {
+ /* Not final point */
+ dk3xsp_set(
+ pseg,
+ ((i > 0) ? &(points[i - 1]) : NULL),
+ &(points[i]),
+ &(points[i+1]),
+ ((i < (np - 2)) ? &(points[i + 2]) : NULL)
+ );
+ back = dk3xsp_calculate(pseg, (t - (double)i), der);
+ } else {
+ /* In final point */
+ dk3xsp_set(
+ pseg,
+ ((np > 2) ? &(points[np - 3]): NULL),
+ &(points[np - 2]),
+ &(points[np - 1]),
+ NULL
+ );
+ back = dk3xsp_calculate(pseg, 1.0, der);
+ }
+ } else {
+ if(ec) { *ec = mec; }
+ }
+ }
+ else
+ {
+ if(ec) { *ec = DK3_ERROR_INVALID_ARGS;}
+ }
+ return back;
+}
+
+
+
+double
+dk3xsp_open_spline_partial_length(
+ dk3_fig_spline_point_t const *points,
+ size_t np,
+ double prec,
+ double tstart,
+ double *fslc,
+ int dir,
+ int cb,
+ int *ec
+)
+{
+ dk3_xspline_segment_t seg;
+ double back = -1.0;
+ double val;
+ size_t startseg;
+ size_t i;
+ int mec = 0;
+ $? "+ dk3xsp_open_spline_partial_length t=%lg prec=%lg", tstart, prec
+ if((points) && (1 < np) && (prec > 0.0)) {
+ if((tstart >= 0.0) && (tstart <= ((double)(np - 1)))) {
+ dk3xsp_reset(&seg);
+ if(cb) { dk3xsp_set_cb(&seg, 1); }
+ startseg = dk3xsp_find_segment_start(tstart, &mec);
+ if(mec) { $? "! mec"
+ if(ec) { *ec = mec; }
+ } else { $? ". startseg = %u", (unsigned)startseg
+ if(startseg == (np - 1)) { $? ". calculation for final point"
+ /*
+ tstart points to the final point.
+ So we have 0 for forward length or the full
+ spline length for backward length.
+ */
+ if(dir) { $? ". full length for left side of end point"
+ back = dk3xsp_open_spline_length(points, np, prec, fslc, cb, ec);
+ } else { $? ". zero for end to end"
+ back = 0.0;
+ }
+ } else { $? ". not final point"
+ if(tstart > 0.0) { $? ". point within the spline"
+ /*
+ tstart points to somewhere in the spline.
+ We have to calculate one segment partially, all other
+ segments completely.
+ */
+ dk3xsp_set(
+ &seg,
+ ((startseg > 0) ? &(points[startseg-1]) : NULL),
+ &(points[startseg]),
+ &(points[startseg+1]),
+ ((startseg < (np - 2)) ? &(points[startseg+2]) : NULL)
+ );
+ val = dk3xsp_segment_partial_length(
+ &seg,(tstart - (double)startseg),dir,(prec / (double)(np - 1)),ec
+ );
+ if(val >= 0.0) { $? ". partial segment length: %lg", val
+ back = val;
+ /*
+ Partial segment calculated successfully.
+ Now calculate other segments.
+ */
+ if(dir) { $? ". full segments before partial one"
+ /*
+ Calculate all segments before the partial one.
+ */
+ for(i = 0; ((i < startseg) && (back > -1.0)); i++) {
+ val = -1.0; $? ". segment %u", (unsigned)i
+ if(fslc) {
+ val = fslc[i];
+ }
+ if(val < -0.5) {
+ dk3xsp_set(
+ &seg,
+ ((i > 0) ? &(points[i-1]) : NULL),
+ &(points[i]),
+ &(points[i+1]),
+ ((i < (np - 2)) ? &(points[i+2]) : NULL)
+ );
+ val = dk3xsp_segment_length(
+ &seg, (prec / (double)(np - 1)), ec
+ );
+ if(val >= 0.0) {
+ if(fslc) {
+ fslc[i] = val;
+ }
+ }
+ }
+ if(val >= 0.0) { $? ". segment %u length %lg",(unsigned)i,val
+ back = dk3ma_d_add_ok(back, val, &mec);
+ if(mec) {
+ back = -1.0; i = np;
+ if(ec) { *ec = mec; }
+ }
+ } else {
+ back = -1.0; i = np;
+ }
+ }
+ } else { $? ". full segments after partial one"
+ /*
+ Calculate all segments after the partial one.
+ */
+ for(i = (startseg + 1); ((i < (np - 1)) && (back > -1)); i++) {
+ val = -1.0; $? ". segment %u", (unsigned)i
+ if(fslc) {
+ val = fslc[i];
+ }
+ if(val < -0.5) {
+ dk3xsp_set(
+ &seg,
+ ((i > 0) ? &(points[i-1]) : NULL),
+ &(points[i]),
+ &(points[i+1]),
+ ((i < (np - 2)) ? &(points[i+2]) : NULL)
+ );
+ val = dk3xsp_segment_length(
+ &seg, (prec / (double)(np - 1)), ec
+ );
+ if(val >= 0.0) {
+ if(fslc) {
+ fslc[i] = val;
+ }
+ }
+ }
+ if(val >= 0.0) { $? ". segment %u length %lg",(unsigned)i,val
+ back = dk3ma_d_add_ok(back, val, &mec);
+ if(mec) {
+ back = -1.0; i = np;
+ if(ec) { *ec = mec; }
+ }
+ } else { $? "! val"
+ back = -1.0; i = np;
+ }
+ }
+ } $? ". full segments done"
+ } else { $? "! val"
+ }
+ } else { $? ". start point"
+ /*
+ tstart points to the start point.
+ So we have the full spline length for forward length,
+ 0 for backward length.
+ */
+ if(0 == dir) { $? ". full length if right from start"
+ back = dk3xsp_open_spline_length(points, np, prec, fslc, cb, ec);
+ } else { $? ". zero from start to start"
+ back = 0.0;
+ }
+ }
+ }
+ }
+ } else {
+ if(ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ } else {
+ if(ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ } $? "- dk3xsp_open_spline_partial_length %lg", back
+ return back;
+}
+
+
+
+double
+dk3xsp_get_t_for_distance(
+ dk3_fig_spline_point_t const *points,
+ size_t np,
+ double dist,
+ double prec,
+ double *fslc,
+ int dir,
+ int cb,
+ int *ec
+)
+{
+ double back = -1.0;
+ double xl; /* Left x. */
+ double xr; /* Right x. */
+ double xc; /* Center x. */
+ double yl; /* Left y. */
+ double yr; /* Right y. */
+ double yc; /* Center y. */
+ double l; /* Spline length. */
+ double fprec; /* factor * precision. */
+ double ayl = 0.0; /* abs yl. */
+ double ayr = 0.0; /* abs yr. */
+ unsigned long passno = 0UL; /* Current pass. */
+ int mec = 0; /* Error code variable. */
+ int cc = 1; /* Flag: Can continue. */
+ int mc = 1; /* Flag: Must continue. */
+ $? "+ dk3xsp_get_t_for_distance d=%lg prec=%lg", dist, prec
+ fprec = 0.2 * prec;
+ if((points) && (1 < np) && (prec > 0.0) && (dist >= 0.0)) {
+ l = dk3xsp_open_spline_length(points, np, fprec, fslc, cb, &mec);
+ $? ". mec = %d", mec
+ if(l > dist) {
+ xl = 0.0;
+ xr = (double)(np - 1);
+ if(dir) {
+ yl = 0.0 - dist;
+ yr = dk3ma_d_sub_ok(l, dist, &mec); $? ". mec = %d", mec
+ } else {
+ yl = dk3ma_d_sub_ok(l, dist, &mec); $? ". mec = %d", mec
+ yr = 0.0 - dist;
+ }
+ while((cc) && (mc) && (!(mec))) {
+ xc = 0.5 * dk3ma_d_add_ok(xl, xr, &mec);
+ $? ". mec = %d", mec
+ yc = dk3ma_d_sub_ok(
+ dk3xsp_open_spline_partial_length(
+ points, np, fprec, xc, fslc, dir, cb, ec
+ ),
+ dist,
+ &mec
+ ); $? ". mec = %d", mec
+ $? ". xl = %lg yl = %lg", xl, yl
+ $? ". xr = %lg yr = %lg", xr, yr
+ $? ". xc = %lg yc = %lg", xc, yc
+ if(dir) {
+ if(yc > 0.0) {
+ xr = xc; yr = yc;
+ } else {
+ xl = xc; yl = yc;
+ }
+ } else {
+ if(yc > 0.0) {
+ xl = xc; yl = yc;
+ } else {
+ xr = xc; yr = yc;
+ }
+ }
+ ayl = fabs(yl);
+ ayr = fabs(yr);
+ if((ayl < prec) && (ayr < prec)) {
+ mc = 0;
+ } else {
+ passno++; $? ". pass %lu", passno
+ if(passno > 1000UL) { $? "! iterations"
+ mec = DK3_ERROR_ITERATION;
+ } else {
+ }
+ }
+ }
+ if((cc) && (!(mec))) { $? ". SUCCESS %lu", passno
+ back = xl + ((xr - xl) * ayl)/(ayl + ayr);
+ }
+ if(mec) { $? "! mec = %d", mec
+ back = -1.0;
+ if(ec) { *ec = mec; }
+ }
+ } else {
+ if(ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ } else {
+ if(ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ } $? "- dk3xsp_get_t_for_distance %lg mec=%d", back, mec
+ return back;
+}
+
+
+
+double
+dk3xsp_direction(
+ dk3_fig_spline_point_t const *points,
+ size_t np,
+ double t,
+ int cb,
+ int *ec
+)
+{
+ dk3_xspline_segment_t seg;
+ double back = -10.0 * M_PI;
+ double dxdt;
+ double dydt;
+ double delta;
+ double tleft;
+ double tright;
+ double xleft;
+ double xright;
+ double yleft;
+ double yright;
+ int mec = 0;
+ $? "+ dk3xsp_direction %lg (%u)", t, (unsigned)(np - 1)
+ if((points) && (1 < np)) {
+ if((t >= 0.0) && (t <= ((double)(np - 1)))) {
+ dk3xsp_reset(&seg);
+ dk3xsp_set_cb(&seg, ((cb) ? 1 : 0));
+ if(dk3xsp_calculate_position(&seg, points, np, t, cb, 1, &mec)) {
+ dxdt = dk3xsp_get_dxdt(&seg);
+ dydt = dk3xsp_get_dydt(&seg);
+ if((fabs(dxdt) > 1.0e-6) || (fabs(dydt) > 1.0e-6)) {
+ back = dk3ma_d_atan2(dydt, dxdt);
+ } else { $? ". must iterate"
+ delta = 0.001;
+ tleft = tright = t;
+ if(t > delta) { tleft = t - delta; }
+ if(t < (((double)(np - 1)) - delta)) { tright = t + delta; }
+ if(dk3xsp_calculate_position(&seg, points, np, tleft, cb, 0, &mec)) {
+ xleft = dk3xsp_get_x(&seg);
+ yleft = dk3xsp_get_y(&seg);
+ if(dk3xsp_calculate_position(&seg, points, np, tright, cb, 0, &mec)) {
+ xright = dk3xsp_get_x(&seg);
+ yright = dk3xsp_get_y(&seg);
+ dxdt = dk3ma_d_sub_ok(xright, xleft, &mec);
+ dydt = dk3ma_d_sub_ok(yright, yleft, &mec);
+ back = dk3ma_d_atan2(dydt, dxdt);
+ } else { $? "! calculation"
+ }
+ } else { $? "! calculation"
+ }
+ }
+ } else { $? "! calculation failed"
+ }
+ if(mec) { if(ec) { *ec = mec; } }
+ } else {
+ if(ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ } else {
+ if(ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ } $? "- dk3xsp_direction %lg", back
+ return back;
+}
+
+
+
+double
+dk3xsp_direction_and_position(
+ double *xpos,
+ double *ypos,
+ dk3_fig_spline_point_t const *points,
+ size_t np,
+ double t,
+ int cb,
+ int *ec
+)
+{
+ dk3_xspline_segment_t seg;
+ double back = -10.0 * M_PI;
+ double dxdt;
+ double dydt;
+ double delta;
+ double tleft;
+ double tright;
+ double xleft;
+ double xright;
+ double yleft;
+ double yright;
+ int mec = 0;
+ $? "+ dk3xsp_direction %lg (%u)", t, (unsigned)(np - 1)
+ if((points) && (1 < np) && (xpos) && (ypos)) {
+ if((t >= 0.0) && (t <= ((double)(np - 1)))) {
+ dk3xsp_reset(&seg);
+ dk3xsp_set_cb(&seg, ((cb) ? 1 : 0));
+ if(dk3xsp_calculate_position(&seg, points, np, t, cb, 1, &mec)) {
+ *xpos = dk3xsp_get_x(&seg);
+ *ypos = dk3xsp_get_y(&seg);
+ dxdt = dk3xsp_get_dxdt(&seg);
+ dydt = dk3xsp_get_dydt(&seg); $? ". dxdt=%lg dydt=%lg", dxdt, dydt
+ if((fabs(dxdt) > 1.0e-6) || (fabs(dydt) > 1.0e-6)) {
+ back = dk3ma_d_atan2(dydt, dxdt); $? ". back = %lg", back
+ } else { $? ". must iterate"
+ delta = 0.001;
+ tleft = tright = t;
+ if(t > delta) { tleft = t - delta; }
+ if(t < (((double)(np - 1)) - delta)) { tright = t + delta; }
+ if(dk3xsp_calculate_position(&seg, points, np, tleft, cb, 0, &mec)) {
+ xleft = dk3xsp_get_x(&seg);
+ yleft = dk3xsp_get_y(&seg);
+ if(dk3xsp_calculate_position(&seg, points, np, tright, cb, 0, &mec)) {
+ xright = dk3xsp_get_x(&seg);
+ yright = dk3xsp_get_y(&seg);
+ dxdt = dk3ma_d_sub_ok(xright, xleft, &mec);
+ dydt = dk3ma_d_sub_ok(yright, yleft, &mec);
+ back = dk3ma_d_atan2(dydt, dxdt);
+ } else { $? "! calculation"
+ }
+ } else { $? "! calculation"
+ }
+ }
+ } else { $? "! calculation failed"
+ }
+ if(mec) { if(ec) { *ec = mec; } }
+ } else {
+ if(ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ }
+ } else {
+ if(ec) { *ec = DK3_ERROR_INVALID_ARGS; }
+ } $? "- dk3xsp_direction %lg", ((180.0 * back)/M_PI)
+ return back;
+}
+
+
diff --git a/support/dktools/dk3xsp.h b/support/dktools/dk3xsp.h
new file mode 100644
index 0000000000..0b87888137
--- /dev/null
+++ b/support/dktools/dk3xsp.h
@@ -0,0 +1,297 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk3xsp.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk3xsp.h Header file for the dk3xsp module.
+*/
+
+#ifndef DK3XSP_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3XSP_H_INCLUDED 1
+
+
+#line 8 "dk3xsp.ctr"
+
+#include "dk3all.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Reset spline segment data.
+ All components - including cb - are reset.
+ @param pseg Spline segment data to reset.
+*/
+void
+dk3xsp_reset(dk3_xspline_segment_t *pseg);
+
+/** Set compatility bug flag.
+ @param pseg Spline segment data to modify.
+ @param v New flag value (1 or 0).
+*/
+void
+dk3xsp_set_cb(dk3_xspline_segment_t *pseg, int v);
+
+/** Set control points.
+ @param pseg Spline segment data to modify.
+ @param a Control point A (may be NULL).
+ @param b Control point B.
+ @param c Control point C.
+ @param d Control point D (may be NULL).
+*/
+void
+dk3xsp_set(
+ dk3_xspline_segment_t *pseg,
+ dk3_fig_spline_point_t const *a,
+ dk3_fig_spline_point_t const *b,
+ dk3_fig_spline_point_t const *c,
+ dk3_fig_spline_point_t const *d
+);
+
+/** Run calculation for a given t.
+ @param pseg Spline segment.
+ @param t The t parameter.
+ @param fder Flag: Calculate derivatives (1=yes, 0=no).
+ @return 1 on success, 0 on error.
+*/
+int
+dk3xsp_calculate(
+ dk3_xspline_segment_t *pseg,
+ double t,
+ int fder
+);
+
+/** Retrieve calculation result.
+ @param pseg Spline segment.
+ @return Calculation result: x value.
+*/
+double
+dk3xsp_get_x(dk3_xspline_segment_t const *pseg);
+
+/** Retrieve calculation result.
+ @param pseg Spline segment.
+ @return Calculation result: y value.
+*/
+double
+dk3xsp_get_y(dk3_xspline_segment_t const *pseg);
+
+/** Retrieve calculation result.
+ @param pseg Spline segment.
+ @return Calculation result: dx/dt value.
+*/
+double
+dk3xsp_get_dxdt(dk3_xspline_segment_t const *pseg);
+
+/** Retrieve calculation result.
+ @param pseg Spline segment.
+ @return Calculation result: dy/dt value.
+*/
+double
+dk3xsp_get_dydt(dk3_xspline_segment_t const *pseg);
+
+/** Calculate X-spline segment interval length.
+ @param pseg Segment to calculate the length for.
+ @param prec Precision.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Length (positive value) on success, negative value on error.
+*/
+double
+dk3xsp_segment_length(
+ dk3_xspline_segment_t *pseg,
+ double prec,
+ int *ec
+);
+
+/** Calculate X-spline partial segment length.
+ @param pseg Segment to calculate the length for.
+ @param tstart Parameter t for start.
+ @param dir Direction (0=forward t to 1, 1=backward 0 to t).
+ @param prec Precision.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Length (positive value) on success, negative value on error.
+*/
+double
+dk3xsp_segment_partial_length(
+ dk3_xspline_segment_t *pseg,
+ double tstart,
+ int dir,
+ double prec,
+ int *ec
+);
+
+/** Check whether an s value is very close to 0.
+ @param s Value to check.
+ @return 1 if s==0, 0 otherwise.
+*/
+int
+dk3xsp_is_null(double s);
+
+/** Calculate length of open X-spline.
+ @param points Array of spline points.
+ @param np Number of points in array.
+ @param prec Numeric precision.
+ @param fslc Full segment length cache (np - 1) elements.
+ @param cb Flag: Compatibility bug.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Length (positive value) on success, negative value on error.
+*/
+double
+dk3xsp_open_spline_length(
+ dk3_fig_spline_point_t const *points,
+ size_t np,
+ double prec,
+ double *fslc,
+ int cb,
+ int *ec
+);
+
+/** Calculate length of open X-spline.
+ @param points Array of spline points.
+ @param np Number of points in array.
+ @param prec Numeric precision.
+ @param tstart Start/end t parameter.
+ @param fslc Full segment length cache, (np-1) elements.
+ @param dir Direction (0=forward t to 1, 1=backward 0 to t).
+ @param cb Flag: Compatibility bug.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Length (positive value) on success, negative value on error.
+*/
+double
+dk3xsp_open_spline_partial_length(
+ dk3_fig_spline_point_t const *points,
+ size_t np,
+ double prec,
+ double tstart,
+ double *fslc,
+ int dir,
+ int cb,
+ int *ec
+);
+
+/** Calculate t value for given distance to end point.
+ @param points X-spline points.
+ @param np Number of x-spline points.
+ @param dist Distance to endpoint.
+ @param prec Precision.
+ @param fslc Cache for full segment lengths.
+ @param dir End-point type: 0=end of spline, 1=start of spline.
+ @param cb Flag: Compatibility with spline bug.
+ @param ec Pointer to error code variable.
+ @return Non-negative value on success, negative value on error.
+*/
+double
+dk3xsp_get_t_for_distance(
+ dk3_fig_spline_point_t const *points,
+ size_t np,
+ double dist,
+ double prec,
+ double *fslc,
+ int dir,
+ int cb,
+ int *ec
+);
+
+/** Run calculations for a given t value in the range 0<=t<=(np-1).
+ @param pseg Segment to use for calculation.
+ @param points Spline points.
+ @param np Number of points.
+ @param t Parameter t.
+ @param cb Flag: Compatibility for spline bug.
+ @param der Flag: Calculate derivatives dx/dt and dy/dt too.
+ @param ec Pointer to error code variable.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3xsp_calculate_position(
+ dk3_xspline_segment_t *pseg,
+ dk3_fig_spline_point_t const *points,
+ size_t np,
+ double t,
+ int cb,
+ int der,
+ int *ec
+);
+
+/** Find movement direction for a specified t value.
+ @param points X-spline points.
+ @param np Number of points.
+ @param t The t parameter 0<=t<=(np-1).
+ @param cb Flag: Compatibility for spline bug.
+ @param ec Pointer to error code variable.
+ @return Non-negative value 0<=res<=2*pi on success,
+ negative value on error.
+*/
+double
+dk3xsp_direction(
+ dk3_fig_spline_point_t const *points,
+ size_t np,
+ double t,
+ int cb,
+ int *ec
+);
+
+/** Find position and movement direction for a specified t value.
+ @param xpos Pointer to variable for x position.
+ @param ypos Pointer to variable for y position.
+ @param points X-spline points.
+ @param np Number of points.
+ @param t The t parameter 0<=t<=(np-1).
+ @param cb Flag: Compatibility for spline bug.
+ @param ec Pointer to error code variable.
+ @return Non-negative value 0<=res<=2*pi on success,
+ negative value on error.
+*/
+double
+dk3xsp_direction_and_position(
+ double *xpos,
+ double *ypos,
+ dk3_fig_spline_point_t const *points,
+ size_t np,
+ double t,
+ int cb,
+ int *ec
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#ifndef DK3XSP_MAX_ITERATION_SEGMENTS
+/** Maximum number of sub-segments in segment length iteration.
+*/
+#define DK3XSP_MAX_ITERATION_SEGMENTS 1073741824L
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4.dox b/support/dktools/dk4.dox
new file mode 100644
index 0000000000..18f4a8fb9d
--- /dev/null
+++ b/support/dktools/dk4.dox
@@ -0,0 +1,127 @@
+/** @mainpage Dirk Krause's libraries.
+
+The dklib project consists of a set of libraries.
+
+The @ref changes
+page lists the changes from 3.x.x to 4.x.x.
+
+Before going into the details I recommend to read the
+@ref conceptions
+page.
+
+The following libraries are available:
+
+@section seclibdk4base libdk4base
+
+The @ref libdk4base library contains
+basic functionality, i.e. for the following purposes:<br>
+- Configuration of the library set
+- Data types, numeric constants
+- Error reporting from called function to caller
+- Memory management
+- String functions for char, wchar_t and dkChar strings.
+
+@section seclibdk4ma Mathematical library
+
+The @ref libdk4ma library contains arithmetic operations on integers of
+different bit width and comparison operations. The arithmetic operations
+check for overflow and prevent divisions by zero.
+The comparison operations can compare signed and unsigned integers
+properly.
+
+@section seclibdk4maio Number I/O libraries
+
+These libraries convert integer and double numbers to text and vice versa.
+Data types char, wchar_t and dkChar are supported, use either decimal
+or hexadecimal notation.
+
+Data type | Notation | Library
+:-------: | :------: | :-----:
+char | decimal | @ref libdk4maio8d
+char | hexadecimal | @ref libdk4maio8h
+wchar_t | decimal | @ref libdk4maiowd
+wchar_t | hexadecimal | @ref libdk4maiowh
+dkChar | decimal | @ref libdk4maiodd
+dkChar | hexadecimal | @ref libdk4maiodh
+
+@section seclibdk4c libdk4c
+
+The @ref libdk4c library contains modules
+for various purposes, including:
+- Information retrieval
+ - Current users name, home directory, language, region, encoding
+ - Host name, executable name, process ID
+- Information storage
+ - Sorted and unsorted storage in AVL trees or double linked lists
+ - Preferences handling
+- File and directory processing
+ - String operations on path names
+ - Information about files
+ - Traverse, create and delete directories
+ - File search
+ - Unique file IDs
+ - Open files with additional security checks
+ - File operations using file descriptors
+- Generic I/O
+ - Generic API to read or write single bytes or byte buffers
+ - Text output with recoding to a specified output encoding
+ - Plain files, gzip or bzip2 compressed files supported
+- Text processing and recoding
+ - Recoding of characters and strings from and to ASCII, ANSI,
+ UTF-8, UTF-16 and 32 bit characters.
+ - Search for byte order marker (BOM) at beginning of data stream
+ - Read byte input stream, convert to ASCII, ANSI, UTF-8, UTF-16
+ or 32 bit characters, process character by character or line
+ by line
+ - String tables to support internationalization
+ - File search for configuration and data files, i.e. for string tables.
+ - Command line option handling
+- Data encoding (run-length, ASCII-hex, ASCII-85) and decoding.
+- Bit handling (bit shifting, bit fields, bit matrices).
+- Timestamp handling and conversion to text.
+- Command line option handling.
+- Tool functions for daemons.
+
+@section seclibdk4dbi libdk4dbi
+
+The @ref libdk4dbi library provides a generic
+interface to Berkeley DB, NDBM and in-memory databases and allows
+to store text in these databases.
+
+
+@section seclibdk4mdrnd libdk4mdrnd
+
+The @ref libdk4mdrnd library generates message digests and random
+numbers.
+
+@section seclibdk4sock libdk4sock
+
+The @ref libdk4sock library contains functions for socket operations
+both for networking and local UNIX domain sockets.
+
+@section seclibdk4app libdk4app
+
+The @ref libdk4app library provides some equivalents for libdk4c functions
+with included localized diagnostics and other application support.
+
+@section seclibdk4lab libdk4lat
+
+The @ref libdk4lat library contains code to
+find LaTeX representations for 32 bit characters.
+
+@section seclibdk4dbia libdk4dbia
+
+The @ref libdk4dbia provides some equivalents for libdk4dbi functions with
+included localized diagnostics.
+
+@section seclibdk4socka libdk4socka
+
+The @ref libdk4socka library provides some equivalents for libdk4sock functions
+with included localized diagnostics.
+
+@section seclibdk4wx libdk4wx
+
+The @ref libdk4wx library provides helper classes to build
+wxWidgets base GUI applications.
+
+*/
diff --git a/support/dktools/dk4.h b/support/dktools/dk4.h
new file mode 100644
index 0000000000..2e8f26d3b5
--- /dev/null
+++ b/support/dktools/dk4.h
@@ -0,0 +1,16 @@
+#ifndef DK4_H_INCLUDED
+#define DK4_H_INCLUDED 1
+
+/** @file dk4.h Include configuration and types.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include <dk4conf.h>
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include <dk4types.h>
+#endif
+
+#endif
+/* ifndef DK4_H_INCLUDED */
diff --git a/support/dktools/dk4a85d.c b/support/dktools/dk4a85d.c
new file mode 100644
index 0000000000..611255b73f
--- /dev/null
+++ b/support/dktools/dk4a85d.c
@@ -0,0 +1,348 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4a85d.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4a85d.c The dk4a85d module.
+*/
+
+
+#line 119 "dk4a85d.ctr"
+
+#include "dk4a85d.h"
+#include "dk4mem.h"
+#include "dk4edstm.h"
+
+
+
+
+
+#line 127 "dk4a85d.ctr"
+
+
+
+/** Powers of 85.
+*/
+static const unsigned long dk4a85e_pow_85[] = {
+ (85UL * 85UL * 85UL * 85UL),
+ (85UL * 85UL * 85UL),
+ (85UL * 85UL),
+ 85UL
+};
+
+
+
+void
+dk4a85_dec_init(dk4_a85_dec_t *dec, dk4_er_t *erp)
+{
+ if (NULL != dec) {
+ DK4_MEMRES(dec, sizeof(dk4_a85_dec_t));
+ dec->os = 0;
+ dec->is = 0;
+ dec->tf = 0;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+}
+
+
+
+int
+dk4a85_dec_add(dk4_a85_dec_t *dec, char input, dk4_er_t *erp)
+{
+ unsigned long val;
+ int back = DK4_EDSTM_ERROR;
+ if (NULL != dec) {
+ if (0 != dec->tf) {
+ if ('>' == input) {
+ back = DK4_EDSTM_STOP;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ switch (input) {
+ case ' ' : case '\t' : case '\r' : case '\n' : case 0x00 : case 0x0C : {
+ back = DK4_EDSTM_ACCEPT;
+ } break;
+ case '~' : {
+ back = DK4_EDSTM_ACCEPT;
+ dec->tf = 1;
+ } break;
+ case 'z' : {
+ if (0 == dec->is) {
+ dec->ob[0] = 0x00;
+ dec->ob[1] = 0x00;
+ dec->ob[2] = 0x00;
+ dec->ob[3] = 0x00;
+ dec->os = 4;
+ back = DK4_EDSTM_FINISHED;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ default : {
+ if (((char)32 < input) && ((char)118 > input)) {
+ dec->ib[dec->is] = input;
+ dec->is += 1;
+ back = DK4_EDSTM_ACCEPT;
+ if (5 <= dec->is) {
+ val =
+ dk4a85e_pow_85[0] *
+ ((unsigned long)((unsigned char)(dec->ib[0] - (char)33)) & 0xFFUL)
+ +
+ dk4a85e_pow_85[1] *
+ ((unsigned long)((unsigned char)(dec->ib[1] - (char)33)) & 0xFFUL)
+ +
+ dk4a85e_pow_85[2] *
+ ((unsigned long)((unsigned char)(dec->ib[2] - (char)33)) & 0xFFUL)
+ +
+ dk4a85e_pow_85[3] *
+ ((unsigned long)((unsigned char)(dec->ib[3] - (char)33)) & 0xFFUL)
+ +
+ ((unsigned long)((unsigned char)(dec->ib[4] - (char)33)) & 0xFFUL)
+ ;
+ dec->ob[0] = (unsigned char)((val >> 24) & 0xFFUL);
+ dec->ob[1] = (unsigned char)((val >> 16) & 0xFFUL);
+ dec->ob[2] = (unsigned char)((val >> 8) & 0xFFUL);
+ dec->ob[3] = (unsigned char)((val ) & 0xFFUL);
+ dec->is = 0;
+ dec->os = 4;
+ back = DK4_EDSTM_FINISHED;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+/*
+ During encoding sequences of 4 binary bytes b1, b2, b3, and b4
+ are converted to five base-85 values a1, a2, a3, a4, and a5
+ fullfilling the equation
+ v=b1*256^3+b2*256^2+b3*256+b4=a1*85^4+a2*85^3+a3*85^2+a4*85+a5
+
+ For complete sequences encoding and decoding are straightforward.
+
+ For an incomplete final sequence of n binary bytes (1<=n<=3),
+ only n+1 a values are encoded.
+ In the example we assume a 2 byte sequence b1 and b2.
+ The value v is calculated as
+ v=b1*256^3+b2*256^2+0*256+0=a1*85^4+a2*85^3+a3*85^2+a4*85+a5.
+ As we have 2 binary bytes, 3 text coefficients a1, a2, and a3
+ are written to encoded output, a4 and a5 are skipped.
+ From these 3 coefficients the decoder can calculate
+ v'=a1*85^4+a2*85^3+a3*85^2+0*85+0
+ which we can split into
+ v'=b1'*256^3+b2'*256^2+b3'*256+b4'
+ Obviously v' is less than or equal to v because v'=v-a4*85-a5.
+ We have v=v' only if a4=0 and a5=0, this results in
+ b3=0 and b4=0. Otherwise we have v>v'.
+ As the final 2 bytes of v are zero, decreasing v to v' results
+ in a non-zero value in the final 2 bytes and a decrease by
+ 1 in the first 2 bytes.
+ So if v' & 0x0000FFFF is nonzero we have to calculate
+ v = v' + 0x00010000 before splitting v into b1, b2, b3, and b4.
+*/
+
+
+
+int
+dk4a85_dec_finish(dk4_a85_dec_t *dec, dk4_er_t *erp)
+{
+ unsigned long val; /* 32 bit value */
+ int back = DK4_EDSTM_ERROR;
+
+
+#line 269 "dk4a85d.ctr"
+ if (NULL != dec) {
+ if (0 == dec->is) {
+ back = DK4_EDSTM_ACCEPT;
+ } else {
+ switch (dec->is) {
+ case 4: {
+
+#line 275 "dk4a85d.ctr"
+ /* Calculate 32 bit value from encoded values.
+ */
+ val =
+ dk4a85e_pow_85[0] *
+ ((unsigned long)((unsigned char)(dec->ib[0] - (char)33)) & 0xFFUL)
+ +
+ dk4a85e_pow_85[1] *
+ ((unsigned long)((unsigned char)(dec->ib[1] - (char)33)) & 0xFFUL)
+ +
+ dk4a85e_pow_85[2] *
+ ((unsigned long)((unsigned char)(dec->ib[2] - (char)33)) & 0xFFUL)
+ +
+ dk4a85e_pow_85[3] *
+ ((unsigned long)((unsigned char)(dec->ib[3] - (char)33)) & 0xFFUL)
+ ;
+
+
+#line 291 "dk4a85d.ctr"
+ /* Check whether truncation of a5 modified the 32 bit
+ value, correct least significant used byte if necessary.
+ */
+ if (0UL != (val & 0x000000FFUL)) {
+ val += 0x00000100UL;
+ }
+ /* Split 32 bit value into bytes.
+ */
+
+
+#line 300 "dk4a85d.ctr"
+ dec->ob[0] = (unsigned char)((val >> 24) & 0xFFUL);
+ dec->ob[1] = (unsigned char)((val >> 16) & 0xFFUL);
+ dec->ob[2] = (unsigned char)((val >> 8) & 0xFFUL);
+ /* Set input size, output size and result.
+ */
+ dec->is = 0;
+ dec->os = 3;
+ back = DK4_EDSTM_FINISHED;
+ } break;
+ case 3: {
+
+#line 310 "dk4a85d.ctr"
+ /* Calculate 32 bit value from encoded values.
+ */
+ val =
+ dk4a85e_pow_85[0] *
+ ((unsigned long)((unsigned char)(dec->ib[0] - (char)33)) & 0xFFUL)
+ +
+ dk4a85e_pow_85[1] *
+ ((unsigned long)((unsigned char)(dec->ib[1] - (char)33)) & 0xFFUL)
+ +
+ dk4a85e_pow_85[2] *
+ ((unsigned long)((unsigned char)(dec->ib[2] - (char)33)) & 0xFFUL)
+ ;
+
+
+#line 323 "dk4a85d.ctr"
+ /* Check whether truncation of a4 and a5 modified the 32 bit
+ value, correct least significant used byte if necessary.
+ */
+ if (0UL != (val & 0x0000FFFFUL)) {
+ val += 0x00010000UL;
+ }
+
+
+#line 330 "dk4a85d.ctr"
+ /* Split 32 bit value into bytes.
+ */
+ dec->ob[0] = (unsigned char)((val >> 24) & 0xFFUL);
+ dec->ob[1] = (unsigned char)((val >> 16) & 0xFFUL);
+ /* Set input size, output size and result.
+ */
+ dec->is = 0;
+ dec->os = 2;
+ back = DK4_EDSTM_FINISHED;
+ } break;
+ case 2: {
+
+#line 341 "dk4a85d.ctr"
+ /* Calculate 32 bit value from encoded values.
+ */
+ val =
+ dk4a85e_pow_85[0] *
+ ((unsigned long)((unsigned char)(dec->ib[0] - (char)33)) & 0xFFUL)
+ +
+ dk4a85e_pow_85[1] *
+ ((unsigned long)((unsigned char)(dec->ib[1] - (char)33)) & 0xFFUL)
+ ;
+
+
+#line 351 "dk4a85d.ctr"
+ /* Check whether truncation of a3, a4, and a5 modified the 32 bit
+ value, correct least significant used byte if necessary.
+ */
+ if (0UL != (val & 0x00FFFFFFUL)) {
+ val += 0x01000000UL;
+ }
+
+
+#line 358 "dk4a85d.ctr"
+ /* Split 32 bit value into bytes.
+ */
+ dec->ob[0] = (unsigned char)((val >> 24) & 0xFFUL);
+ /* Set input size, output size and result.
+ */
+ dec->is = 0;
+ dec->os = 1;
+ back = DK4_EDSTM_FINISHED;
+ } break;
+ default: {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 375 "dk4a85d.ctr"
+ return back;
+}
+
+
+
+int
+dk4a85_dec_output(
+ const unsigned char **dptr, size_t *szptr, dk4_a85_dec_t *dec, dk4_er_t *erp
+)
+{
+ int back = 0;
+ if ((NULL != dec) && (NULL != dptr) && (NULL != szptr)) {
+ if (0 < dec->os) {
+ *dptr = &(dec->ob[0]);
+ *szptr = dec->os;
+ back = 1;
+ } else {
+ *dptr = NULL;
+ *szptr = 0;
+ back = 0;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4a85d.ctr b/support/dktools/dk4a85d.ctr
new file mode 100644
index 0000000000..ac17417f27
--- /dev/null
+++ b/support/dktools/dk4a85d.ctr
@@ -0,0 +1,402 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk4a85d.h ASCII-85 decoder.
+
+First initialize the decoder structure, use the dk4a85_dec_init() function.
+
+Add bytes to the decoder using the dk4a85_dec_add() function
+as long as adding results in DK4_EDSTM_ACCEPT or
+DK4_EDSTM_FINISHED. On DK4_EDSTM_FINISHED use dk4a85_dec_output() to obtain
+the binary bytes.
+
+A return value DK4_EDSTM_STOP indicates that the end of data (EOD) marker
+was found in the data stream, you must not add further characters to the
+decoder.
+
+After adding all bytes use dk4a85_dec_finish() to check whether there
+is data for a final incomplete sequence stored in the decoder. If the test
+results in DK4_EDSTM_FINISHED, use dk4a85_dec_output() to obtain
+the binary bytes.
+
+The dk4a85_dec_finish() is also necessary if you stopped
+feeding input due to a DK4_EDSTM_STOP result from dk4a85_dec_add().
+
+Note: You can not directly call dk4a85_dec_output() after receiving
+DK4_EDSTM_STOP from dk4a85_dec_add(), the call to dk4a85_dec_finish()
+is required.
+*/
+
+#include "dk4conf.h"
+#include "dk4error.h"
+
+/** ASCII 85 decoder.
+*/
+typedef struct {
+ char ib[6]; /**< Input bytes, ASCII. */
+ unsigned char ob[4]; /**< Output bytes, binary. */
+ size_t os; /**< Output buffer size. */
+ size_t is; /**< Index of next input byte to receive. */
+ int tf; /**< Flag: Tilde found */
+} dk4_a85_dec_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Initialize decoder before using it.
+ @param dec Decoder to initialize.
+ @param erp Error report, may be NULL.
+*/
+void
+dk4a85_dec_init(dk4_a85_dec_t *dec, dk4_er_t *erp);
+
+/** Add one text character to the decoder.
+ @param dec Decoder to use.
+ @param input Input text character.
+ @param erp Error report, may be NULL.
+ @return Action to take, one from:
+ - DK4_EDSTM_ACCEPT<br>
+ if the input was accepted and stored in the decoder, no action
+ necessary.
+ - DK4_EDSTM_FINISHED<br>
+ if a sequence of 5 input text characters was completed, use
+ dk4a85_dec_output() to obtain the corresponding binary 4 bytes.
+ - DK4_EDSTM_STOP<br>
+ if an EOD (end of data) marker was found. Use
+ dk4a85_dec_finish() and take appropriate action to process
+ the final byte sequence.
+ - DK4_EDSTM_ERROR<br>
+ if an error occured.
+*/
+int
+dk4a85_dec_add(dk4_a85_dec_t *dec, char input, dk4_er_t *erp);
+
+/** Check whether final bytes are stored in the decoder.
+ @param dec Decoder to use.
+ @param erp Error report, may be NULL.
+ @return Action to take, one from:
+ - DK4_EDSTM_ACCEPT<br>
+ if there are no final bytes in the decoder, no action necessary.
+ - DK4_EDSTM_FINISHED<br>
+ if there are final bytes in the decoder, use dk4a85_dec_output()
+ to retrieve them.
+ - DK4_EDSTM_ERROR<br>
+ if an error occured.
+*/
+int
+dk4a85_dec_finish(dk4_a85_dec_t *dec, dk4_er_t *erp);
+
+/** Retrieve final bytes.
+ @param dptr Address of buffer pointer to set, should be
+ initialized to NULL.
+ @param szptr Address of size variable to set, should be
+ initialized to 0.
+ @param dec Decoder to use.
+ @param erp Error report, may be NULL.
+ @return 1 on success (bytes available, 0 otherwise).
+*/
+int
+dk4a85_dec_output(
+ const unsigned char **dptr, size_t *szptr, dk4_a85_dec_t *dec, dk4_er_t *erp
+);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4a85d.h"
+#include "dk4mem.h"
+#include "dk4edstm.h"
+
+
+
+$!trace-include
+
+
+
+/** Powers of 85.
+*/
+static const unsigned long dk4a85e_pow_85[] = {
+ (85UL * 85UL * 85UL * 85UL),
+ (85UL * 85UL * 85UL),
+ (85UL * 85UL),
+ 85UL
+};
+
+
+
+void
+dk4a85_dec_init(dk4_a85_dec_t *dec, dk4_er_t *erp)
+{
+ if (NULL != dec) {
+ DK4_MEMRES(dec, sizeof(dk4_a85_dec_t));
+ dec->os = 0;
+ dec->is = 0;
+ dec->tf = 0;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+}
+
+
+
+int
+dk4a85_dec_add(dk4_a85_dec_t *dec, char input, dk4_er_t *erp)
+{
+ unsigned long val;
+ int back = DK4_EDSTM_ERROR;
+ if (NULL != dec) {
+ if (0 != dec->tf) {
+ if ('>' == input) {
+ back = DK4_EDSTM_STOP;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ switch (input) {
+ case ' ' : case '\t' : case '\r' : case '\n' : case 0x00 : case 0x0C : {
+ back = DK4_EDSTM_ACCEPT;
+ } break;
+ case '~' : {
+ back = DK4_EDSTM_ACCEPT;
+ dec->tf = 1;
+ } break;
+ case 'z' : {
+ if (0 == dec->is) {
+ dec->ob[0] = 0x00;
+ dec->ob[1] = 0x00;
+ dec->ob[2] = 0x00;
+ dec->ob[3] = 0x00;
+ dec->os = 4;
+ back = DK4_EDSTM_FINISHED;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ default : {
+ if (((char)32 < input) && ((char)118 > input)) {
+ dec->ib[dec->is] = input;
+ dec->is += 1;
+ back = DK4_EDSTM_ACCEPT;
+ if (5 <= dec->is) {
+ val =
+ dk4a85e_pow_85[0] *
+ ((unsigned long)((unsigned char)(dec->ib[0] - (char)33)) & 0xFFUL)
+ +
+ dk4a85e_pow_85[1] *
+ ((unsigned long)((unsigned char)(dec->ib[1] - (char)33)) & 0xFFUL)
+ +
+ dk4a85e_pow_85[2] *
+ ((unsigned long)((unsigned char)(dec->ib[2] - (char)33)) & 0xFFUL)
+ +
+ dk4a85e_pow_85[3] *
+ ((unsigned long)((unsigned char)(dec->ib[3] - (char)33)) & 0xFFUL)
+ +
+ ((unsigned long)((unsigned char)(dec->ib[4] - (char)33)) & 0xFFUL)
+ ;
+ dec->ob[0] = (unsigned char)((val >> 24) & 0xFFUL);
+ dec->ob[1] = (unsigned char)((val >> 16) & 0xFFUL);
+ dec->ob[2] = (unsigned char)((val >> 8) & 0xFFUL);
+ dec->ob[3] = (unsigned char)((val ) & 0xFFUL);
+ dec->is = 0;
+ dec->os = 4;
+ back = DK4_EDSTM_FINISHED;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+/*
+ During encoding sequences of 4 binary bytes b1, b2, b3, and b4
+ are converted to five base-85 values a1, a2, a3, a4, and a5
+ fullfilling the equation
+ v=b1*256^3+b2*256^2+b3*256+b4=a1*85^4+a2*85^3+a3*85^2+a4*85+a5
+
+ For complete sequences encoding and decoding are straightforward.
+
+ For an incomplete final sequence of n binary bytes (1<=n<=3),
+ only n+1 a values are encoded.
+ In the example we assume a 2 byte sequence b1 and b2.
+ The value v is calculated as
+ v=b1*256^3+b2*256^2+0*256+0=a1*85^4+a2*85^3+a3*85^2+a4*85+a5.
+ As we have 2 binary bytes, 3 text coefficients a1, a2, and a3
+ are written to encoded output, a4 and a5 are skipped.
+ From these 3 coefficients the decoder can calculate
+ v'=a1*85^4+a2*85^3+a3*85^2+0*85+0
+ which we can split into
+ v'=b1'*256^3+b2'*256^2+b3'*256+b4'
+ Obviously v' is less than or equal to v because v'=v-a4*85-a5.
+ We have v=v' only if a4=0 and a5=0, this results in
+ b3=0 and b4=0. Otherwise we have v>v'.
+ As the final 2 bytes of v are zero, decreasing v to v' results
+ in a non-zero value in the final 2 bytes and a decrease by
+ 1 in the first 2 bytes.
+ So if v' & 0x0000FFFF is nonzero we have to calculate
+ v = v' + 0x00010000 before splitting v into b1, b2, b3, and b4.
+*/
+
+
+
+int
+dk4a85_dec_finish(dk4_a85_dec_t *dec, dk4_er_t *erp)
+{
+ unsigned long val; /* 32 bit value */
+ int back = DK4_EDSTM_ERROR;
+ $? "+ dk4a85_dec_finish"
+ if (NULL != dec) {
+ if (0 == dec->is) {
+ back = DK4_EDSTM_ACCEPT;
+ } else {
+ switch (dec->is) {
+ case 4: { $? ". 4 unused input bytes"
+ /* Calculate 32 bit value from encoded values.
+ */
+ val =
+ dk4a85e_pow_85[0] *
+ ((unsigned long)((unsigned char)(dec->ib[0] - (char)33)) & 0xFFUL)
+ +
+ dk4a85e_pow_85[1] *
+ ((unsigned long)((unsigned char)(dec->ib[1] - (char)33)) & 0xFFUL)
+ +
+ dk4a85e_pow_85[2] *
+ ((unsigned long)((unsigned char)(dec->ib[2] - (char)33)) & 0xFFUL)
+ +
+ dk4a85e_pow_85[3] *
+ ((unsigned long)((unsigned char)(dec->ib[3] - (char)33)) & 0xFFUL)
+ ;
+ $? ". val = %lu %lx", val, val
+ /* Check whether truncation of a5 modified the 32 bit
+ value, correct least significant used byte if necessary.
+ */
+ if (0UL != (val & 0x000000FFUL)) {
+ val += 0x00000100UL;
+ }
+ /* Split 32 bit value into bytes.
+ */
+ $? ". val = %lu %lx", val, val
+ dec->ob[0] = (unsigned char)((val >> 24) & 0xFFUL);
+ dec->ob[1] = (unsigned char)((val >> 16) & 0xFFUL);
+ dec->ob[2] = (unsigned char)((val >> 8) & 0xFFUL);
+ /* Set input size, output size and result.
+ */
+ dec->is = 0;
+ dec->os = 3;
+ back = DK4_EDSTM_FINISHED;
+ } break;
+ case 3: { $? ". 3 unused input bytes"
+ /* Calculate 32 bit value from encoded values.
+ */
+ val =
+ dk4a85e_pow_85[0] *
+ ((unsigned long)((unsigned char)(dec->ib[0] - (char)33)) & 0xFFUL)
+ +
+ dk4a85e_pow_85[1] *
+ ((unsigned long)((unsigned char)(dec->ib[1] - (char)33)) & 0xFFUL)
+ +
+ dk4a85e_pow_85[2] *
+ ((unsigned long)((unsigned char)(dec->ib[2] - (char)33)) & 0xFFUL)
+ ;
+ $? ". val = %lu %lx", val, val
+ /* Check whether truncation of a4 and a5 modified the 32 bit
+ value, correct least significant used byte if necessary.
+ */
+ if (0UL != (val & 0x0000FFFFUL)) {
+ val += 0x00010000UL;
+ }
+ $? ". val = %lu %lx", val, val
+ /* Split 32 bit value into bytes.
+ */
+ dec->ob[0] = (unsigned char)((val >> 24) & 0xFFUL);
+ dec->ob[1] = (unsigned char)((val >> 16) & 0xFFUL);
+ /* Set input size, output size and result.
+ */
+ dec->is = 0;
+ dec->os = 2;
+ back = DK4_EDSTM_FINISHED;
+ } break;
+ case 2: { $? ". 2 unused input bytes"
+ /* Calculate 32 bit value from encoded values.
+ */
+ val =
+ dk4a85e_pow_85[0] *
+ ((unsigned long)((unsigned char)(dec->ib[0] - (char)33)) & 0xFFUL)
+ +
+ dk4a85e_pow_85[1] *
+ ((unsigned long)((unsigned char)(dec->ib[1] - (char)33)) & 0xFFUL)
+ ;
+ $? ". val = %lu %lx", val, val
+ /* Check whether truncation of a3, a4, and a5 modified the 32 bit
+ value, correct least significant used byte if necessary.
+ */
+ if (0UL != (val & 0x00FFFFFFUL)) {
+ val += 0x01000000UL;
+ }
+ $? ". val = %lu %lx", val, val
+ /* Split 32 bit value into bytes.
+ */
+ dec->ob[0] = (unsigned char)((val >> 24) & 0xFFUL);
+ /* Set input size, output size and result.
+ */
+ dec->is = 0;
+ dec->os = 1;
+ back = DK4_EDSTM_FINISHED;
+ } break;
+ default: {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4a85_dec_finish"
+ return back;
+}
+
+
+
+int
+dk4a85_dec_output(
+ const unsigned char **dptr, size_t *szptr, dk4_a85_dec_t *dec, dk4_er_t *erp
+)
+{
+ int back = 0;
+ if ((NULL != dec) && (NULL != dptr) && (NULL != szptr)) {
+ if (0 < dec->os) {
+ *dptr = &(dec->ob[0]);
+ *szptr = dec->os;
+ back = 1;
+ } else {
+ *dptr = NULL;
+ *szptr = 0;
+ back = 0;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4a85d.h b/support/dktools/dk4a85d.h
new file mode 100644
index 0000000000..0ab7ceadf9
--- /dev/null
+++ b/support/dktools/dk4a85d.h
@@ -0,0 +1,151 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4a85d.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4A85D_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4A85D_H_INCLUDED 1
+
+
+#line 10 "dk4a85d.ctr"
+
+/** @file dk4a85d.h ASCII-85 decoder.
+
+First initialize the decoder structure, use the dk4a85_dec_init() function.
+
+Add bytes to the decoder using the dk4a85_dec_add() function
+as long as adding results in DK4_EDSTM_ACCEPT or
+DK4_EDSTM_FINISHED. On DK4_EDSTM_FINISHED use dk4a85_dec_output() to obtain
+the binary bytes.
+
+A return value DK4_EDSTM_STOP indicates that the end of data (EOD) marker
+was found in the data stream, you must not add further characters to the
+decoder.
+
+After adding all bytes use dk4a85_dec_finish() to check whether there
+is data for a final incomplete sequence stored in the decoder. If the test
+results in DK4_EDSTM_FINISHED, use dk4a85_dec_output() to obtain
+the binary bytes.
+
+The dk4a85_dec_finish() is also necessary if you stopped
+feeding input due to a DK4_EDSTM_STOP result from dk4a85_dec_add().
+
+Note: You can not directly call dk4a85_dec_output() after receiving
+DK4_EDSTM_STOP from dk4a85_dec_add(), the call to dk4a85_dec_finish()
+is required.
+*/
+
+#include "dk4conf.h"
+#include "dk4error.h"
+
+/** ASCII 85 decoder.
+*/
+typedef struct {
+ char ib[6]; /**< Input bytes, ASCII. */
+ unsigned char ob[4]; /**< Output bytes, binary. */
+ size_t os; /**< Output buffer size. */
+ size_t is; /**< Index of next input byte to receive. */
+ int tf; /**< Flag: Tilde found */
+} dk4_a85_dec_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Initialize decoder before using it.
+ @param dec Decoder to initialize.
+ @param erp Error report, may be NULL.
+*/
+void
+dk4a85_dec_init(dk4_a85_dec_t *dec, dk4_er_t *erp);
+
+/** Add one text character to the decoder.
+ @param dec Decoder to use.
+ @param input Input text character.
+ @param erp Error report, may be NULL.
+ @return Action to take, one from:
+ - DK4_EDSTM_ACCEPT<br>
+ if the input was accepted and stored in the decoder, no action
+ necessary.
+ - DK4_EDSTM_FINISHED<br>
+ if a sequence of 5 input text characters was completed, use
+ dk4a85_dec_output() to obtain the corresponding binary 4 bytes.
+ - DK4_EDSTM_STOP<br>
+ if an EOD (end of data) marker was found. Use
+ dk4a85_dec_finish() and take appropriate action to process
+ the final byte sequence.
+ - DK4_EDSTM_ERROR<br>
+ if an error occured.
+*/
+int
+dk4a85_dec_add(dk4_a85_dec_t *dec, char input, dk4_er_t *erp);
+
+/** Check whether final bytes are stored in the decoder.
+ @param dec Decoder to use.
+ @param erp Error report, may be NULL.
+ @return Action to take, one from:
+ - DK4_EDSTM_ACCEPT<br>
+ if there are no final bytes in the decoder, no action necessary.
+ - DK4_EDSTM_FINISHED<br>
+ if there are final bytes in the decoder, use dk4a85_dec_output()
+ to retrieve them.
+ - DK4_EDSTM_ERROR<br>
+ if an error occured.
+*/
+int
+dk4a85_dec_finish(dk4_a85_dec_t *dec, dk4_er_t *erp);
+
+/** Retrieve final bytes.
+ @param dptr Address of buffer pointer to set, should be
+ initialized to NULL.
+ @param szptr Address of size variable to set, should be
+ initialized to 0.
+ @param dec Decoder to use.
+ @param erp Error report, may be NULL.
+ @return 1 on success (bytes available, 0 otherwise).
+*/
+int
+dk4a85_dec_output(
+ const unsigned char **dptr, size_t *szptr, dk4_a85_dec_t *dec, dk4_er_t *erp
+);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4a85e.c b/support/dktools/dk4a85e.c
new file mode 100644
index 0000000000..93580db8a7
--- /dev/null
+++ b/support/dktools/dk4a85e.c
@@ -0,0 +1,309 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4a85e.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4a85e.c The dk4a85e module.
+*/
+
+
+#line 127 "dk4a85e.ctr"
+
+#include "dk4a85e.h"
+#include "dk4edstm.h"
+#include "dk4mem.h"
+
+
+
+
+
+#line 135 "dk4a85e.ctr"
+
+
+
+static const unsigned long dk4a85e_pow_85[] = {
+ (85UL * 85UL * 85UL * 85UL),
+ (85UL * 85UL * 85UL),
+ (85UL * 85UL),
+ 85UL
+};
+
+
+
+void
+dk4a85_enc_init(dk4_a85_enc_t *enc, int az, dk4_er_t *erp)
+{
+ if (NULL != enc) {
+ DK4_MEMRES(enc, sizeof(dk4_a85_enc_t));
+ enc->ob[5] = '\0';
+ enc->ci = 0;
+ enc->os = 0;
+ enc->az = ((0 != az) ? 1 : 0);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+}
+
+
+
+int
+dk4a85_enc_add(dk4_a85_enc_t *enc, unsigned char input, dk4_er_t *erp)
+{
+ unsigned long val;
+ unsigned long v1;
+ int back = DK4_EDSTM_ERROR;
+ if (NULL != enc) {
+ back = DK4_EDSTM_ACCEPT;
+ enc->ib[enc->ci] = input;
+ enc->ci += 1;
+ if (4 <= enc->ci) {
+ back = DK4_EDSTM_FINISHED;
+ val = (((unsigned long)(enc->ib[0]) << 24) & 0xFF000000UL)
+ | (((unsigned long)(enc->ib[1]) << 16) & 0x00FF0000UL)
+ | (((unsigned long)(enc->ib[2]) << 8) & 0x0000FF00UL)
+ | (((unsigned long)(enc->ib[3]) ) & 0x000000FFUL);
+ if ((0UL == val) && (0 != enc->az)) {
+ enc->ob[0] = 'z';
+ enc->ob[1] = '\0';
+ enc->os = 1;
+ } else {
+ v1 = val / dk4a85e_pow_85[0];
+ enc->ob[0] = (char)33 + (char)v1;
+ val = val % dk4a85e_pow_85[0];
+ v1 = val / dk4a85e_pow_85[1];
+ enc->ob[1] = (char)33 + (char)v1;
+ val = val % dk4a85e_pow_85[1];
+ v1 = val / dk4a85e_pow_85[2];
+ enc->ob[2] = (char)33 + (char)v1;
+ val = val % dk4a85e_pow_85[2];
+ v1 = val / dk4a85e_pow_85[3];
+ enc->ob[3] = (char)33 + (char)v1;
+ val = val % dk4a85e_pow_85[3];
+ enc->ob[4] = (char)33 + (char)val;
+ enc->os = 5;
+ }
+ enc->ci = 0;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4a85_enc_finish(dk4_a85_enc_t *enc, dk4_er_t *erp)
+{
+ unsigned long val;
+ unsigned long v1;
+ int back = DK4_EDSTM_ERROR;
+
+
+#line 216 "dk4a85e.ctr"
+ if (NULL != enc) {
+ if (0 == enc->ci) {
+ back = DK4_EDSTM_ACCEPT;
+ enc->ob[0] = '\0';
+ enc->os = 0;
+ } else {
+ switch (enc->ci) {
+ case 1: {
+
+
+#line 225 "dk4a85e.ctr"
+ back = DK4_EDSTM_FINISHED;
+ val = (((unsigned long)(enc->ib[0]) << 24) & 0xFF000000UL);
+
+
+#line 228 "dk4a85e.ctr"
+ v1 = val / dk4a85e_pow_85[0];
+ enc->ob[0] = (char)33 + (char)v1;
+
+
+#line 231 "dk4a85e.ctr"
+ val = val % dk4a85e_pow_85[0];
+ v1 = val / dk4a85e_pow_85[1];
+ enc->ob[1] = (char)33 + (char)v1;
+
+
+#line 235 "dk4a85e.ctr"
+ enc->os = 2;
+ enc->ci = 0;
+ } break;
+ case 2: {
+
+
+#line 240 "dk4a85e.ctr"
+ back = DK4_EDSTM_FINISHED;
+ val = (((unsigned long)(enc->ib[0]) << 24) & 0xFF000000UL)
+ | (((unsigned long)(enc->ib[1]) << 16) & 0x00FF0000UL);
+
+
+#line 244 "dk4a85e.ctr"
+ v1 = val / dk4a85e_pow_85[0];
+ enc->ob[0] = (char)33 + (char)v1;
+
+
+#line 247 "dk4a85e.ctr"
+ val = val % dk4a85e_pow_85[0];
+ v1 = val / dk4a85e_pow_85[1];
+ enc->ob[1] = (char)33 + (char)v1;
+
+
+#line 251 "dk4a85e.ctr"
+ val = val % dk4a85e_pow_85[1];
+ v1 = val / dk4a85e_pow_85[2];
+ enc->ob[2] = (char)33 + (char)v1;
+
+
+#line 255 "dk4a85e.ctr"
+ enc->os = 3;
+ enc->ci = 0;
+ } break;
+ case 3: {
+
+
+#line 260 "dk4a85e.ctr"
+ back = DK4_EDSTM_FINISHED;
+ val = (((unsigned long)(enc->ib[0]) << 24) & 0xFF000000UL)
+ | (((unsigned long)(enc->ib[1]) << 16) & 0x00FF0000UL)
+ | (((unsigned long)(enc->ib[2]) << 8) & 0x0000FF00UL);
+
+
+#line 265 "dk4a85e.ctr"
+ v1 = val / dk4a85e_pow_85[0];
+ enc->ob[0] = (char)33 + (char)v1;
+
+
+#line 268 "dk4a85e.ctr"
+ val = val % dk4a85e_pow_85[0];
+ v1 = val / dk4a85e_pow_85[1];
+ enc->ob[1] = (char)33 + (char)v1;
+
+
+#line 272 "dk4a85e.ctr"
+ val = val % dk4a85e_pow_85[1];
+ v1 = val / dk4a85e_pow_85[2];
+ enc->ob[2] = (char)33 + (char)v1;
+
+
+#line 276 "dk4a85e.ctr"
+ val = val % dk4a85e_pow_85[2];
+ v1 = val / dk4a85e_pow_85[3];
+ enc->ob[3] = (char)33 + (char)v1;
+
+
+#line 280 "dk4a85e.ctr"
+ enc->os = 4;
+ enc->ci = 0;
+ } break;
+ default: {
+
+
+#line 285 "dk4a85e.ctr"
+ back = DK4_EDSTM_FINISHED;
+ val = (((unsigned long)(enc->ib[0]) << 24) & 0xFF000000UL)
+ | (((unsigned long)(enc->ib[1]) << 16) & 0x00FF0000UL)
+ | (((unsigned long)(enc->ib[2]) << 8) & 0x0000FF00UL)
+ | (((unsigned long)(enc->ib[3]) ) & 0x000000FFUL);
+
+
+#line 291 "dk4a85e.ctr"
+ if ((0UL == val) && (0 != enc->az)) {
+ enc->ob[0] = 'z';
+ enc->ob[1] = '\0';
+ enc->os = 1;
+ } else {
+ v1 = val / dk4a85e_pow_85[0];
+ enc->ob[0] = (char)33 + (char)v1;
+
+
+#line 299 "dk4a85e.ctr"
+ val = val % dk4a85e_pow_85[0];
+ v1 = val / dk4a85e_pow_85[1];
+ enc->ob[1] = (char)33 + (char)v1;
+
+
+#line 303 "dk4a85e.ctr"
+ val = val % dk4a85e_pow_85[1];
+ v1 = val / dk4a85e_pow_85[2];
+ enc->ob[2] = (char)33 + (char)v1;
+
+
+#line 307 "dk4a85e.ctr"
+ val = val % dk4a85e_pow_85[2];
+ v1 = val / dk4a85e_pow_85[3];
+ enc->ob[3] = (char)33 + (char)v1;
+
+
+#line 311 "dk4a85e.ctr"
+ val = val % dk4a85e_pow_85[3];
+ enc->ob[4] = (char)33 + (char)val;
+
+
+#line 314 "dk4a85e.ctr"
+ enc->os = 5;
+ }
+ enc->ci = 0;
+ } break;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 323 "dk4a85e.ctr"
+ return back;
+}
+
+
+
+int
+dk4a85_enc_output(
+ const char **dptr, size_t *szptr, dk4_a85_enc_t *enc, dk4_er_t *erp
+)
+{
+ int back = 0;
+ if ((NULL != dptr) && (NULL != szptr) && (NULL != enc)) {
+ *dptr = &(enc->ob[0]);
+ *szptr = enc->os;
+ if (0 < enc->os) {
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4a85e.ctr b/support/dktools/dk4a85e.ctr
new file mode 100644
index 0000000000..82421cc1d8
--- /dev/null
+++ b/support/dktools/dk4a85e.ctr
@@ -0,0 +1,345 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk4a85e.h ASCII-85 encoder.
+
+First initialize the encoder using the dk4a85_enc_init().
+
+Now add the binary bytes one by one using the dk4a85_enc_add() function, as
+long as you have bytes available and the function returns DK4_EDSTM_ACCEPT
+or DK4_EDSTM_FINISHED.
+
+If the function returns DK4_EDSTM_ACCEPT, no further action is required,
+the byte was successfully stored in the internal data structures.
+
+If dk4a85_enc_add() returns DK4_EDSTM_FINISHED, a sequence of 4 binary
+bytes was processed successfully, a 1 character or 5 character sequence
+was produced. Use dk4a85_enc_output() to obtain the characters.
+
+Input data length is not necessarily a multiple of 4, so after feeding
+all binary bytes some values might still be stored in the encoder.
+Use dk4a85_enc_finish() to check whether an incomplete final sequence
+is available. If the function returns DK4_EDSTM_FINISHED, use
+dk4a85_enc_output() to obtain the text characters for the final bytes.
+
+*/
+
+#include "dk4conf.h"
+#include "dk4error.h"
+#include "dk4edstm.h"
+
+
+
+/** ASCII 85 encoder.
+*/
+typedef struct {
+ char ob[6]; /**< Output bytes, 5 + finalizer */
+ unsigned char ib[4]; /**< Input bytes to process. */
+ size_t ci; /**< Index of current input byte. */
+ size_t os; /**< Number of outupt bytes available */
+ short az; /**< Allow z encoding */
+} dk4_a85_enc_t;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Initialize ASCII 85 encoder before adding data.
+ @param enc Encoder to initialize.
+ @param az Flag: Allow 'z' output character.
+ @param erp Error report, may be NULL.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS if enc is NULL.
+*/
+void
+dk4a85_enc_init(dk4_a85_enc_t *enc, int az, dk4_er_t *erp);
+
+/** Add one byte to encoder.
+ @param enc Encoder to use.
+ @param input Input byte to add.
+ @param erp Error report, may be NULL.
+ @return Action to take, one from:
+ - DK4_EDSTM_ACCEPT<br>
+ if input was accepted, no further action necessary at the moment.
+ - DK4_EDSTM_FINISHED<br>
+ if a sequence of 4 input bytes was completed, use
+ dk4a85_enc_output() to obtain the text characters.
+ - DK4_EDSTM_ERROR<br>
+ if an error occured.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS if enc is NULL.
+*/
+int
+dk4a85_enc_add(dk4_a85_enc_t *enc, unsigned char input, dk4_er_t *erp);
+
+/** Check for incomplete sequence in state machine after processing
+ all input bytes.
+ @param enc Encoder to use.
+ @param erp Error report, may be NULL.
+ @return Action to take, one from:
+ - DK4_EDSTM_ACCEPT<br>
+ if there is no incomplete sequence in the state machine,
+ no further action necessary.
+ - DK4_EDSTM_FINISHED<br>
+ if an incomplete final sequence is available, use
+ dk4a85_enc_output() to obtain the text characters.
+ - DK4_EDSTM_ERROR<br>
+ if an error occured.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS if enc is NULL.
+*/
+int
+dk4a85_enc_finish(dk4_a85_enc_t *enc, dk4_er_t *erp);
+
+/** Retrieve text sequence.
+ @param dptr Address of destination pointer to set, should be
+ initialized to NULL.
+ @param szptr Address of size variable to set, should be
+ initialized to 0.
+ @param enc Encoder to use.
+ @param erp Error report, may be NULL.
+ @return 1 on success (text available), 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS if enc, dptr, or szptr is NULL.
+*/
+int
+dk4a85_enc_output(
+ const char **dptr, size_t *szptr, dk4_a85_enc_t *enc, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4a85e.h"
+#include "dk4edstm.h"
+#include "dk4mem.h"
+
+
+
+$!trace-include
+
+
+
+static const unsigned long dk4a85e_pow_85[] = {
+ (85UL * 85UL * 85UL * 85UL),
+ (85UL * 85UL * 85UL),
+ (85UL * 85UL),
+ 85UL
+};
+
+
+
+void
+dk4a85_enc_init(dk4_a85_enc_t *enc, int az, dk4_er_t *erp)
+{
+ if (NULL != enc) {
+ DK4_MEMRES(enc, sizeof(dk4_a85_enc_t));
+ enc->ob[5] = '\0';
+ enc->ci = 0;
+ enc->os = 0;
+ enc->az = ((0 != az) ? 1 : 0);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+}
+
+
+
+int
+dk4a85_enc_add(dk4_a85_enc_t *enc, unsigned char input, dk4_er_t *erp)
+{
+ unsigned long val;
+ unsigned long v1;
+ int back = DK4_EDSTM_ERROR;
+ if (NULL != enc) {
+ back = DK4_EDSTM_ACCEPT;
+ enc->ib[enc->ci] = input;
+ enc->ci += 1;
+ if (4 <= enc->ci) {
+ back = DK4_EDSTM_FINISHED;
+ val = (((unsigned long)(enc->ib[0]) << 24) & 0xFF000000UL)
+ | (((unsigned long)(enc->ib[1]) << 16) & 0x00FF0000UL)
+ | (((unsigned long)(enc->ib[2]) << 8) & 0x0000FF00UL)
+ | (((unsigned long)(enc->ib[3]) ) & 0x000000FFUL);
+ if ((0UL == val) && (0 != enc->az)) {
+ enc->ob[0] = 'z';
+ enc->ob[1] = '\0';
+ enc->os = 1;
+ } else {
+ v1 = val / dk4a85e_pow_85[0];
+ enc->ob[0] = (char)33 + (char)v1;
+ val = val % dk4a85e_pow_85[0];
+ v1 = val / dk4a85e_pow_85[1];
+ enc->ob[1] = (char)33 + (char)v1;
+ val = val % dk4a85e_pow_85[1];
+ v1 = val / dk4a85e_pow_85[2];
+ enc->ob[2] = (char)33 + (char)v1;
+ val = val % dk4a85e_pow_85[2];
+ v1 = val / dk4a85e_pow_85[3];
+ enc->ob[3] = (char)33 + (char)v1;
+ val = val % dk4a85e_pow_85[3];
+ enc->ob[4] = (char)33 + (char)val;
+ enc->os = 5;
+ }
+ enc->ci = 0;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4a85_enc_finish(dk4_a85_enc_t *enc, dk4_er_t *erp)
+{
+ unsigned long val;
+ unsigned long v1;
+ int back = DK4_EDSTM_ERROR;
+ $? "+ dk4a85_enc_finish"
+ if (NULL != enc) {
+ if (0 == enc->ci) {
+ back = DK4_EDSTM_ACCEPT;
+ enc->ob[0] = '\0';
+ enc->os = 0;
+ } else {
+ switch (enc->ci) {
+ case 1: {
+ $? ". 1 input byte %02x", (int)(enc->ib[0])
+ back = DK4_EDSTM_FINISHED;
+ val = (((unsigned long)(enc->ib[0]) << 24) & 0xFF000000UL);
+ $? ". val = %lu %lx", val, val
+ v1 = val / dk4a85e_pow_85[0];
+ enc->ob[0] = (char)33 + (char)v1;
+ $? ". a1 = %lu", v1
+ val = val % dk4a85e_pow_85[0];
+ v1 = val / dk4a85e_pow_85[1];
+ enc->ob[1] = (char)33 + (char)v1;
+ $? ". a2 = %lu", v1
+ enc->os = 2;
+ enc->ci = 0;
+ } break;
+ case 2: {
+ $? ". 2 input bytes %02x %02x", (int)(enc->ib[0]), (int)(enc->ib[1])
+ back = DK4_EDSTM_FINISHED;
+ val = (((unsigned long)(enc->ib[0]) << 24) & 0xFF000000UL)
+ | (((unsigned long)(enc->ib[1]) << 16) & 0x00FF0000UL);
+ $? ". val = %lu %lx", val, val
+ v1 = val / dk4a85e_pow_85[0];
+ enc->ob[0] = (char)33 + (char)v1;
+ $? ". a1 = %lu", v1
+ val = val % dk4a85e_pow_85[0];
+ v1 = val / dk4a85e_pow_85[1];
+ enc->ob[1] = (char)33 + (char)v1;
+ $? ". a2 = %lu", v1
+ val = val % dk4a85e_pow_85[1];
+ v1 = val / dk4a85e_pow_85[2];
+ enc->ob[2] = (char)33 + (char)v1;
+ $? ". a3 = %lu", v1
+ enc->os = 3;
+ enc->ci = 0;
+ } break;
+ case 3: {
+ $? ". 3 input bytes %02x %02x %02x", (int)(enc->ib[0]), (int)(enc->ib[1]), (int)(enc->ib[2])
+ back = DK4_EDSTM_FINISHED;
+ val = (((unsigned long)(enc->ib[0]) << 24) & 0xFF000000UL)
+ | (((unsigned long)(enc->ib[1]) << 16) & 0x00FF0000UL)
+ | (((unsigned long)(enc->ib[2]) << 8) & 0x0000FF00UL);
+ $? ". val = %lu %lx", val, val
+ v1 = val / dk4a85e_pow_85[0];
+ enc->ob[0] = (char)33 + (char)v1;
+ $? ". a1 = %lu", v1
+ val = val % dk4a85e_pow_85[0];
+ v1 = val / dk4a85e_pow_85[1];
+ enc->ob[1] = (char)33 + (char)v1;
+ $? ". a2 = %lu", v1
+ val = val % dk4a85e_pow_85[1];
+ v1 = val / dk4a85e_pow_85[2];
+ enc->ob[2] = (char)33 + (char)v1;
+ $? ". a3 = %lu", v1
+ val = val % dk4a85e_pow_85[2];
+ v1 = val / dk4a85e_pow_85[3];
+ enc->ob[3] = (char)33 + (char)v1;
+ $? ". a4 = %lu", v1
+ enc->os = 4;
+ enc->ci = 0;
+ } break;
+ default: {
+ $? ". 4 input bytes %02x %02x %02x %02x", (int)(enc->ib[0]), (int)(enc->ib[1]), (int)(enc->ib[2]), (int)(enc->ib[3])
+ back = DK4_EDSTM_FINISHED;
+ val = (((unsigned long)(enc->ib[0]) << 24) & 0xFF000000UL)
+ | (((unsigned long)(enc->ib[1]) << 16) & 0x00FF0000UL)
+ | (((unsigned long)(enc->ib[2]) << 8) & 0x0000FF00UL)
+ | (((unsigned long)(enc->ib[3]) ) & 0x000000FFUL);
+ $? ". val = %lu %lx", val, val
+ if ((0UL == val) && (0 != enc->az)) {
+ enc->ob[0] = 'z';
+ enc->ob[1] = '\0';
+ enc->os = 1;
+ } else {
+ v1 = val / dk4a85e_pow_85[0];
+ enc->ob[0] = (char)33 + (char)v1;
+ $? ". a1 = %lu", v1
+ val = val % dk4a85e_pow_85[0];
+ v1 = val / dk4a85e_pow_85[1];
+ enc->ob[1] = (char)33 + (char)v1;
+ $? ". a2 = %lu", v1
+ val = val % dk4a85e_pow_85[1];
+ v1 = val / dk4a85e_pow_85[2];
+ enc->ob[2] = (char)33 + (char)v1;
+ $? ". a3 = %lu", v1
+ val = val % dk4a85e_pow_85[2];
+ v1 = val / dk4a85e_pow_85[3];
+ enc->ob[3] = (char)33 + (char)v1;
+ $? ". a4 = %lu", v1
+ val = val % dk4a85e_pow_85[3];
+ enc->ob[4] = (char)33 + (char)val;
+ $? ". a5 = %lu", val
+ enc->os = 5;
+ }
+ enc->ci = 0;
+ } break;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4a85_enc_finish"
+ return back;
+}
+
+
+
+int
+dk4a85_enc_output(
+ const char **dptr, size_t *szptr, dk4_a85_enc_t *enc, dk4_er_t *erp
+)
+{
+ int back = 0;
+ if ((NULL != dptr) && (NULL != szptr) && (NULL != enc)) {
+ *dptr = &(enc->ob[0]);
+ *szptr = enc->os;
+ if (0 < enc->os) {
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4a85e.h b/support/dktools/dk4a85e.h
new file mode 100644
index 0000000000..372a0d1ad6
--- /dev/null
+++ b/support/dktools/dk4a85e.h
@@ -0,0 +1,159 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4a85e.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4A85E_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4A85E_H_INCLUDED 1
+
+
+#line 10 "dk4a85e.ctr"
+
+/** @file dk4a85e.h ASCII-85 encoder.
+
+First initialize the encoder using the dk4a85_enc_init().
+
+Now add the binary bytes one by one using the dk4a85_enc_add() function, as
+long as you have bytes available and the function returns DK4_EDSTM_ACCEPT
+or DK4_EDSTM_FINISHED.
+
+If the function returns DK4_EDSTM_ACCEPT, no further action is required,
+the byte was successfully stored in the internal data structures.
+
+If dk4a85_enc_add() returns DK4_EDSTM_FINISHED, a sequence of 4 binary
+bytes was processed successfully, a 1 character or 5 character sequence
+was produced. Use dk4a85_enc_output() to obtain the characters.
+
+Input data length is not necessarily a multiple of 4, so after feeding
+all binary bytes some values might still be stored in the encoder.
+Use dk4a85_enc_finish() to check whether an incomplete final sequence
+is available. If the function returns DK4_EDSTM_FINISHED, use
+dk4a85_enc_output() to obtain the text characters for the final bytes.
+
+*/
+
+#include "dk4conf.h"
+#include "dk4error.h"
+#include "dk4edstm.h"
+
+
+
+/** ASCII 85 encoder.
+*/
+typedef struct {
+ char ob[6]; /**< Output bytes, 5 + finalizer */
+ unsigned char ib[4]; /**< Input bytes to process. */
+ size_t ci; /**< Index of current input byte. */
+ size_t os; /**< Number of outupt bytes available */
+ short az; /**< Allow z encoding */
+} dk4_a85_enc_t;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Initialize ASCII 85 encoder before adding data.
+ @param enc Encoder to initialize.
+ @param az Flag: Allow 'z' output character.
+ @param erp Error report, may be NULL.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS if enc is NULL.
+*/
+void
+dk4a85_enc_init(dk4_a85_enc_t *enc, int az, dk4_er_t *erp);
+
+/** Add one byte to encoder.
+ @param enc Encoder to use.
+ @param input Input byte to add.
+ @param erp Error report, may be NULL.
+ @return Action to take, one from:
+ - DK4_EDSTM_ACCEPT<br>
+ if input was accepted, no further action necessary at the moment.
+ - DK4_EDSTM_FINISHED<br>
+ if a sequence of 4 input bytes was completed, use
+ dk4a85_enc_output() to obtain the text characters.
+ - DK4_EDSTM_ERROR<br>
+ if an error occured.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS if enc is NULL.
+*/
+int
+dk4a85_enc_add(dk4_a85_enc_t *enc, unsigned char input, dk4_er_t *erp);
+
+/** Check for incomplete sequence in state machine after processing
+ all input bytes.
+ @param enc Encoder to use.
+ @param erp Error report, may be NULL.
+ @return Action to take, one from:
+ - DK4_EDSTM_ACCEPT<br>
+ if there is no incomplete sequence in the state machine,
+ no further action necessary.
+ - DK4_EDSTM_FINISHED<br>
+ if an incomplete final sequence is available, use
+ dk4a85_enc_output() to obtain the text characters.
+ - DK4_EDSTM_ERROR<br>
+ if an error occured.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS if enc is NULL.
+*/
+int
+dk4a85_enc_finish(dk4_a85_enc_t *enc, dk4_er_t *erp);
+
+/** Retrieve text sequence.
+ @param dptr Address of destination pointer to set, should be
+ initialized to NULL.
+ @param szptr Address of size variable to set, should be
+ initialized to 0.
+ @param enc Encoder to use.
+ @param erp Error report, may be NULL.
+ @return 1 on success (text available), 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS if enc, dptr, or szptr is NULL.
+*/
+int
+dk4a85_enc_output(
+ const char **dptr, size_t *szptr, dk4_a85_enc_t *enc, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4ahd.c b/support/dktools/dk4ahd.c
new file mode 100644
index 0000000000..d3684e16af
--- /dev/null
+++ b/support/dktools/dk4ahd.c
@@ -0,0 +1,239 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4ahd.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4ahd.c The dk4ahd module.
+*/
+
+
+#line 102 "dk4ahd.ctr"
+
+
+#include "dk4ahd.h"
+#include "dk4mem.h"
+#include "dk4edstm.h"
+
+
+
+
+
+#line 111 "dk4ahd.ctr"
+
+
+
+void
+dk4ahex_dec_init(dk4_ahex_dec_t *dec, dk4_er_t *erp)
+{
+ if (NULL != dec) {
+ DK4_MEMRES(dec, sizeof(dk4_ahex_dec_t));
+ dec->cpos = 0;
+ dec->obyte = 0x00;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+}
+
+
+
+int
+dk4ahex_dec_add(dk4_ahex_dec_t *dec, char tc, dk4_er_t *erp)
+{
+ int back = DK4_EDSTM_ERROR;
+ if (NULL != dec) {
+ switch (tc) {
+ case ' ' : case '\t' : case '\r' : case '\n' : case 0x00 : case 0x0C : {
+ back = DK4_EDSTM_ACCEPT;
+ } break;
+ case '>' : {
+ back = DK4_EDSTM_STOP;
+ } break;
+ case '0' : {
+ if (0 != dec->cpos) {
+ dec->cpos = 2;
+ } else {
+ dec->obyte = 0x00;
+ dec->cpos = 1;
+ }
+ } break;
+ case '1' : {
+ if (0 != dec->cpos) {
+ dec->obyte |= 0x01; dec->cpos = 2;
+ } else {
+ dec->obyte = 0x10; dec->cpos = 1;
+ }
+ } break;
+ case '2' : {
+ if (0 != dec->cpos) {
+ dec->obyte |= 0x02; dec->cpos = 2;
+ } else {
+ dec->obyte = 0x20; dec->cpos = 1;
+ }
+ } break;
+ case '3' : {
+ if (0 != dec->cpos) {
+ dec->obyte |= 0x03; dec->cpos = 2;
+ } else {
+ dec->obyte = 0x30; dec->cpos = 1;
+ }
+ } break;
+ case '4' : {
+ if (0 != dec->cpos) {
+ dec->obyte |= 0x04; dec->cpos = 2;
+ } else {
+ dec->obyte = 0x40; dec->cpos = 1;
+ }
+ } break;
+ case '5' : {
+ if (0 != dec->cpos) {
+ dec->obyte |= 0x05; dec->cpos = 2;
+ } else {
+ dec->obyte = 0x50; dec->cpos = 1;
+ }
+ } break;
+ case '6' : {
+ if (0 != dec->cpos) {
+ dec->obyte |= 0x06; dec->cpos = 2;
+ } else {
+ dec->obyte = 0x60; dec->cpos = 1;
+ }
+ } break;
+ case '7' : {
+ if (0 != dec->cpos) {
+ dec->obyte |= 0x07; dec->cpos = 2;
+ } else {
+ dec->obyte = 0x70; dec->cpos = 1;
+ }
+ } break;
+ case '8' : {
+ if (0 != dec->cpos) {
+ dec->obyte |= 0x08; dec->cpos = 2;
+ } else {
+ dec->obyte = 0x80; dec->cpos = 1;
+ }
+ } break;
+ case '9' : {
+ if (0 != dec->cpos) {
+ dec->obyte |= 0x09; dec->cpos = 2;
+ } else {
+ dec->obyte = 0x90; dec->cpos = 1;
+ }
+ } break;
+ case 'a' : case 'A' : {
+ if (0 != dec->cpos) {
+ dec->obyte |= 0x0A; dec->cpos = 2;
+ } else {
+ dec->obyte = 0xA0; dec->cpos = 1;
+ }
+ } break;
+ case 'b' : case 'B' : {
+ if (0 != dec->cpos) {
+ dec->obyte |= 0x0B; dec->cpos = 2;
+ } else {
+ dec->obyte = 0xB0; dec->cpos = 1;
+ }
+ } break;
+ case 'c' : case 'C' : {
+ if (0 != dec->cpos) {
+ dec->obyte |= 0x0C; dec->cpos = 2;
+ } else {
+ dec->obyte = 0xC0; dec->cpos = 1;
+ }
+ } break;
+ case 'd' : case 'D' : {
+ if (0 != dec->cpos) {
+ dec->obyte |= 0x0D; dec->cpos = 2;
+ } else {
+ dec->obyte = 0xD0; dec->cpos = 1;
+ }
+ } break;
+ case 'e' : case 'E' : {
+ if (0 != dec->cpos) {
+ dec->obyte |= 0x0E; dec->cpos = 2;
+ } else {
+ dec->obyte = 0xE0; dec->cpos = 1;
+ }
+ } break;
+ case 'f' : case 'F' : {
+ if (0 != dec->cpos) {
+ dec->obyte |= 0x0F; dec->cpos = 2;
+ } else {
+ dec->obyte = 0xF0; dec->cpos = 1;
+ }
+ } break;
+ }
+ if (2 == dec->cpos) {
+ dec->cpos = 0;
+ back = DK4_EDSTM_FINISHED;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4ahex_finish(dk4_ahex_dec_t *dec, dk4_er_t *erp)
+{
+ int back = DK4_EDSTM_ERROR;
+ if (NULL != dec) {
+ switch (dec->cpos) {
+ case 1: {
+ back = DK4_EDSTM_FINISHED;
+ } break;
+ default : {
+ back = DK4_EDSTM_ACCEPT;
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+unsigned char
+dk4ahex_output(dk4_ahex_dec_t *dec, dk4_er_t *erp)
+{
+ unsigned char back = 0x00;
+ if (NULL != dec) {
+ back = dec->obyte;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4ahd.ctr b/support/dktools/dk4ahd.ctr
new file mode 100644
index 0000000000..1fdef1ad24
--- /dev/null
+++ b/support/dktools/dk4ahd.ctr
@@ -0,0 +1,298 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk4ahd.h ASCIIHex decoder.
+
+First initialize the decoder using the dk4ahex_dec_init() function.
+
+Add text characters using the dk4ahex_dec_add() function.
+The function returns DK4_EDSTM_ACCEPT if the text character was successfully
+stored in the decoder without completing a byte.
+The DK4_EDSTM_FINISHED return code indicates that a byte was finished, use
+dk4ahex_output() to retrieve it.
+The DK4_EDSTM_STOP return code indicates that an end of data (EOD) marker
+was found.
+
+After feeding all text characters into the decoder use dk4ahex_finish()
+to check whether there is an unprocessed half-byte stored.
+If the function returns DK4_EDSTM_FINISHED, use dk4ahex_output() to
+retrieve the final byte.
+
+Note: The call to dk4ahex_finish() is also necessary after
+obtaining DK4_EDSTM_STOP from dk4ahex_dec_add().
+
+*/
+
+#include "dk4conf.h"
+#include "dk4error.h"
+
+/** ASCII-Hex decoder.
+*/
+typedef struct {
+ int cpos; /**< Current position. */
+ unsigned char obyte; /**< Output byte. */
+} dk4_ahex_dec_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Initialize decoder.
+ @param dec Decoder to initialize.
+ @param erp Error report, may be NULL.
+*/
+void
+dk4ahex_dec_init(dk4_ahex_dec_t *dec, dk4_er_t *erp);
+
+/** Add text character to decoder.
+ @param dec Decoder.
+ @param tc Text character to add.
+ @param erp Error report, may be NULL.
+ @return Action to take:
+ - DK4_EDSTM_ACCEPT<br>
+ if the text was saved in the decoder, no action necessary.
+ - DK4_EDSTM_FINISHED<br>
+ if a byte was completed, use dk4ahex_dec_output() to retrieve
+ the byte.
+ - DK4_EDSTM_STOP<br>
+ if the end of data (EOD) marker was detected.
+ Use dk4ahex_finish() to check whether there is still data
+ in the decoder.
+ - DK4_EDSTM_ERROR<br>
+ if an error occured.
+*/
+int
+dk4ahex_dec_add(dk4_ahex_dec_t *dec, char tc, dk4_er_t *erp);
+
+/** Check for final byte.
+ @param dec Decoder.
+ @param erp Error report, may be NULL.
+ @return Action to take, one from:
+ - DK4_EDSTM_ACCEPT<br>
+ if there is no action necessary.
+ - DK4_EDSTM_FINISHED<br>
+ if there is data available, use dk4ahex_dec_output() to retrieve
+ the byte.
+ - DK4_EDSTM_ERROR<br>
+ if an error occured.
+*/
+int
+dk4ahex_finish(dk4_ahex_dec_t *dec, dk4_er_t *erp);
+
+/** Retrieve current decoder content.
+ @param dec Decoder.
+ @param erp Error report, may be NULL.
+ @return The current byte stored in the decoder.
+*/
+unsigned char
+dk4ahex_output(dk4_ahex_dec_t *dec, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+
+#include "dk4ahd.h"
+#include "dk4mem.h"
+#include "dk4edstm.h"
+
+
+
+$!trace-include
+
+
+
+void
+dk4ahex_dec_init(dk4_ahex_dec_t *dec, dk4_er_t *erp)
+{
+ if (NULL != dec) {
+ DK4_MEMRES(dec, sizeof(dk4_ahex_dec_t));
+ dec->cpos = 0;
+ dec->obyte = 0x00;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+}
+
+
+
+int
+dk4ahex_dec_add(dk4_ahex_dec_t *dec, char tc, dk4_er_t *erp)
+{
+ int back = DK4_EDSTM_ERROR;
+ if (NULL != dec) {
+ switch (tc) {
+ case ' ' : case '\t' : case '\r' : case '\n' : case 0x00 : case 0x0C : {
+ back = DK4_EDSTM_ACCEPT;
+ } break;
+ case '>' : {
+ back = DK4_EDSTM_STOP;
+ } break;
+ case '0' : {
+ if (0 != dec->cpos) {
+ dec->cpos = 2;
+ } else {
+ dec->obyte = 0x00;
+ dec->cpos = 1;
+ }
+ } break;
+ case '1' : {
+ if (0 != dec->cpos) {
+ dec->obyte |= 0x01; dec->cpos = 2;
+ } else {
+ dec->obyte = 0x10; dec->cpos = 1;
+ }
+ } break;
+ case '2' : {
+ if (0 != dec->cpos) {
+ dec->obyte |= 0x02; dec->cpos = 2;
+ } else {
+ dec->obyte = 0x20; dec->cpos = 1;
+ }
+ } break;
+ case '3' : {
+ if (0 != dec->cpos) {
+ dec->obyte |= 0x03; dec->cpos = 2;
+ } else {
+ dec->obyte = 0x30; dec->cpos = 1;
+ }
+ } break;
+ case '4' : {
+ if (0 != dec->cpos) {
+ dec->obyte |= 0x04; dec->cpos = 2;
+ } else {
+ dec->obyte = 0x40; dec->cpos = 1;
+ }
+ } break;
+ case '5' : {
+ if (0 != dec->cpos) {
+ dec->obyte |= 0x05; dec->cpos = 2;
+ } else {
+ dec->obyte = 0x50; dec->cpos = 1;
+ }
+ } break;
+ case '6' : {
+ if (0 != dec->cpos) {
+ dec->obyte |= 0x06; dec->cpos = 2;
+ } else {
+ dec->obyte = 0x60; dec->cpos = 1;
+ }
+ } break;
+ case '7' : {
+ if (0 != dec->cpos) {
+ dec->obyte |= 0x07; dec->cpos = 2;
+ } else {
+ dec->obyte = 0x70; dec->cpos = 1;
+ }
+ } break;
+ case '8' : {
+ if (0 != dec->cpos) {
+ dec->obyte |= 0x08; dec->cpos = 2;
+ } else {
+ dec->obyte = 0x80; dec->cpos = 1;
+ }
+ } break;
+ case '9' : {
+ if (0 != dec->cpos) {
+ dec->obyte |= 0x09; dec->cpos = 2;
+ } else {
+ dec->obyte = 0x90; dec->cpos = 1;
+ }
+ } break;
+ case 'a' : case 'A' : {
+ if (0 != dec->cpos) {
+ dec->obyte |= 0x0A; dec->cpos = 2;
+ } else {
+ dec->obyte = 0xA0; dec->cpos = 1;
+ }
+ } break;
+ case 'b' : case 'B' : {
+ if (0 != dec->cpos) {
+ dec->obyte |= 0x0B; dec->cpos = 2;
+ } else {
+ dec->obyte = 0xB0; dec->cpos = 1;
+ }
+ } break;
+ case 'c' : case 'C' : {
+ if (0 != dec->cpos) {
+ dec->obyte |= 0x0C; dec->cpos = 2;
+ } else {
+ dec->obyte = 0xC0; dec->cpos = 1;
+ }
+ } break;
+ case 'd' : case 'D' : {
+ if (0 != dec->cpos) {
+ dec->obyte |= 0x0D; dec->cpos = 2;
+ } else {
+ dec->obyte = 0xD0; dec->cpos = 1;
+ }
+ } break;
+ case 'e' : case 'E' : {
+ if (0 != dec->cpos) {
+ dec->obyte |= 0x0E; dec->cpos = 2;
+ } else {
+ dec->obyte = 0xE0; dec->cpos = 1;
+ }
+ } break;
+ case 'f' : case 'F' : {
+ if (0 != dec->cpos) {
+ dec->obyte |= 0x0F; dec->cpos = 2;
+ } else {
+ dec->obyte = 0xF0; dec->cpos = 1;
+ }
+ } break;
+ }
+ if (2 == dec->cpos) {
+ dec->cpos = 0;
+ back = DK4_EDSTM_FINISHED;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4ahex_finish(dk4_ahex_dec_t *dec, dk4_er_t *erp)
+{
+ int back = DK4_EDSTM_ERROR;
+ if (NULL != dec) {
+ switch (dec->cpos) {
+ case 1: {
+ back = DK4_EDSTM_FINISHED;
+ } break;
+ default : {
+ back = DK4_EDSTM_ACCEPT;
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+unsigned char
+dk4ahex_output(dk4_ahex_dec_t *dec, dk4_er_t *erp)
+{
+ unsigned char back = 0x00;
+ if (NULL != dec) {
+ back = dec->obyte;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4ahd.h b/support/dktools/dk4ahd.h
new file mode 100644
index 0000000000..78923cae73
--- /dev/null
+++ b/support/dktools/dk4ahd.h
@@ -0,0 +1,134 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4ahd.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4AHD_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4AHD_H_INCLUDED 1
+
+
+#line 10 "dk4ahd.ctr"
+
+/** @file dk4ahd.h ASCIIHex decoder.
+
+First initialize the decoder using the dk4ahex_dec_init() function.
+
+Add text characters using the dk4ahex_dec_add() function.
+The function returns DK4_EDSTM_ACCEPT if the text character was successfully
+stored in the decoder without completing a byte.
+The DK4_EDSTM_FINISHED return code indicates that a byte was finished, use
+dk4ahex_output() to retrieve it.
+The DK4_EDSTM_STOP return code indicates that an end of data (EOD) marker
+was found.
+
+After feeding all text characters into the decoder use dk4ahex_finish()
+to check whether there is an unprocessed half-byte stored.
+If the function returns DK4_EDSTM_FINISHED, use dk4ahex_output() to
+retrieve the final byte.
+
+Note: The call to dk4ahex_finish() is also necessary after
+obtaining DK4_EDSTM_STOP from dk4ahex_dec_add().
+
+*/
+
+#include "dk4conf.h"
+#include "dk4error.h"
+
+/** ASCII-Hex decoder.
+*/
+typedef struct {
+ int cpos; /**< Current position. */
+ unsigned char obyte; /**< Output byte. */
+} dk4_ahex_dec_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Initialize decoder.
+ @param dec Decoder to initialize.
+ @param erp Error report, may be NULL.
+*/
+void
+dk4ahex_dec_init(dk4_ahex_dec_t *dec, dk4_er_t *erp);
+
+/** Add text character to decoder.
+ @param dec Decoder.
+ @param tc Text character to add.
+ @param erp Error report, may be NULL.
+ @return Action to take:
+ - DK4_EDSTM_ACCEPT<br>
+ if the text was saved in the decoder, no action necessary.
+ - DK4_EDSTM_FINISHED<br>
+ if a byte was completed, use dk4ahex_dec_output() to retrieve
+ the byte.
+ - DK4_EDSTM_STOP<br>
+ if the end of data (EOD) marker was detected.
+ Use dk4ahex_finish() to check whether there is still data
+ in the decoder.
+ - DK4_EDSTM_ERROR<br>
+ if an error occured.
+*/
+int
+dk4ahex_dec_add(dk4_ahex_dec_t *dec, char tc, dk4_er_t *erp);
+
+/** Check for final byte.
+ @param dec Decoder.
+ @param erp Error report, may be NULL.
+ @return Action to take, one from:
+ - DK4_EDSTM_ACCEPT<br>
+ if there is no action necessary.
+ - DK4_EDSTM_FINISHED<br>
+ if there is data available, use dk4ahex_dec_output() to retrieve
+ the byte.
+ - DK4_EDSTM_ERROR<br>
+ if an error occured.
+*/
+int
+dk4ahex_finish(dk4_ahex_dec_t *dec, dk4_er_t *erp);
+
+/** Retrieve current decoder content.
+ @param dec Decoder.
+ @param erp Error report, may be NULL.
+ @return The current byte stored in the decoder.
+*/
+unsigned char
+dk4ahex_output(dk4_ahex_dec_t *dec, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4align.h b/support/dktools/dk4align.h
new file mode 100644
index 0000000000..6b8e71c5a3
--- /dev/null
+++ b/support/dktools/dk4align.h
@@ -0,0 +1,53 @@
+#ifndef DK4ALIGN_H_INCLUDED
+/** Protection against multiple inclusions. */
+#define DK4ALIGN_H_INCLUDED 1
+
+/** How to align an object horizontally in the available room.
+*/
+typedef enum {
+ /** Horizontal alignment: align object left in room.
+ */
+ DK4_ALIGN_H_LEFT = 0,
+
+ /** Horizontal alignment: align object centered in room.
+ */
+ DK4_ALIGN_H_CENTERED ,
+
+ /** Horizontal alignment: align object right in room.
+ */
+ DK4_ALIGN_H_RIGHT ,
+
+ /** Horizontal alignment: stretch object to use
+ available room completely.
+ */
+ DK4_ALIGN_H_STRETCH
+
+} dk4_align_h_t;
+
+
+/** How to align an object vertically in the available room.
+*/
+typedef enum {
+ /** Vertical alignment: align object on top of room.
+ */
+ DK4_ALIGN_V_TOP = 0,
+
+ /** Vertical alignment: align object centered in room.
+ */
+ DK4_ALIGN_V_CENTERED ,
+
+ /** Vertical alignment: align object on bottom.
+ */
+ DK4_ALIGN_V_BOTTOM ,
+
+ /** Vertical alignment: stretch object to use available
+ room completely.
+ */
+ DK4_ALIGN_V_STRETCH
+} dk4_align_v_t;
+
+
+/* vim: set ai sw=4 ts=4 : */
+
+#endif
+
diff --git a/support/dktools/dk4ansi.c b/support/dktools/dk4ansi.c
new file mode 100644
index 0000000000..436d16a98e
--- /dev/null
+++ b/support/dktools/dk4ansi.c
@@ -0,0 +1,156 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4ansi.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4ansi.c The dk4ansi module.
+*/
+
+
+#line 57 "dk4ansi.ctr"
+
+#include "dk4ansi.h"
+#include "dk4numco.h"
+
+
+int
+dk4ansi_encode(unsigned char *dptr, dk4_c32_t c32)
+{
+ int back = 0;
+ if (NULL != dptr) {
+ if ((dk4_c32_t)0x80 > c32) {
+ *dptr = (unsigned char)c32;
+ back = 1;
+ } else {
+ if (((dk4_c32_t)0x9F < c32) && ((dk4_c32_t)0x0100 > c32)) {
+ *dptr = (unsigned char)c32;
+ back = 1;
+ } else {
+ if ((dk4_c32_t)INT_MAX > c32) {
+ switch ((int)c32) {
+ case 0x20AC: { *dptr = (unsigned char)0x80; back = 1; } break;
+ case 0x0081: { *dptr = (unsigned char)0x81; back = 1; } break;
+ case 0x201A: { *dptr = (unsigned char)0x82; back = 1; } break;
+ case 0x0192: { *dptr = (unsigned char)0x83; back = 1; } break;
+ case 0x201E: { *dptr = (unsigned char)0x84; back = 1; } break;
+ case 0x2026: { *dptr = (unsigned char)0x85; back = 1; } break;
+ case 0x2020: { *dptr = (unsigned char)0x86; back = 1; } break;
+ case 0x2021: { *dptr = (unsigned char)0x87; back = 1; } break;
+ case 0x02C6: { *dptr = (unsigned char)0x88; back = 1; } break;
+ case 0x2030: { *dptr = (unsigned char)0x89; back = 1; } break;
+ case 0x0160: { *dptr = (unsigned char)0x8A; back = 1; } break;
+ case 0x2039: { *dptr = (unsigned char)0x8B; back = 1; } break;
+ case 0x0152: { *dptr = (unsigned char)0x8C; back = 1; } break;
+ case 0x008D: { *dptr = (unsigned char)0x8D; back = 1; } break;
+ case 0x017D: { *dptr = (unsigned char)0x8E; back = 1; } break;
+ case 0x008F: { *dptr = (unsigned char)0x8F; back = 1; } break;
+ case 0x0090: { *dptr = (unsigned char)0x90; back = 1; } break;
+ case 0x2018: { *dptr = (unsigned char)0x91; back = 1; } break;
+ case 0x2019: { *dptr = (unsigned char)0x92; back = 1; } break;
+ case 0x201C: { *dptr = (unsigned char)0x93; back = 1; } break;
+ case 0x201D: { *dptr = (unsigned char)0x94; back = 1; } break;
+ case 0x2022: { *dptr = (unsigned char)0x95; back = 1; } break;
+ case 0x2013: { *dptr = (unsigned char)0x96; back = 1; } break;
+ case 0x2014: { *dptr = (unsigned char)0x97; back = 1; } break;
+ case 0x02DC: { *dptr = (unsigned char)0x98; back = 1; } break;
+ case 0x2122: { *dptr = (unsigned char)0x99; back = 1; } break;
+ case 0x0161: { *dptr = (unsigned char)0x9A; back = 1; } break;
+ case 0x203A: { *dptr = (unsigned char)0x9B; back = 1; } break;
+ case 0x0153: { *dptr = (unsigned char)0x9C; back = 1; } break;
+ case 0x009D: { *dptr = (unsigned char)0x9D; back = 1; } break;
+ case 0x017E: { *dptr = (unsigned char)0x9E; back = 1; } break;
+ case 0x0178: { *dptr = (unsigned char)0x9F; back = 1; } break;
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4ansi_decode(dk4_c32_t *dptr, unsigned char uc)
+{
+ int back = 0;
+ if (NULL != dptr) {
+ if (0x80 > uc) {
+ *dptr = (dk4_c32_t)uc;
+ back = 1;
+ } else {
+ if (0x9F < uc) {
+ *dptr = (dk4_c32_t)uc;
+ back = 1;
+ } else {
+ switch ((int)uc) {
+ case 0x80: { *dptr = (dk4_c32_t)0x20AC; back = 1; } break;
+ case 0x81: { *dptr = (dk4_c32_t)0x0081; back = 1; } break;
+ case 0x82: { *dptr = (dk4_c32_t)0x201A; back = 1; } break;
+ case 0x83: { *dptr = (dk4_c32_t)0x0192; back = 1; } break;
+ case 0x84: { *dptr = (dk4_c32_t)0x201E; back = 1; } break;
+ case 0x85: { *dptr = (dk4_c32_t)0x2026; back = 1; } break;
+ case 0x86: { *dptr = (dk4_c32_t)0x2020; back = 1; } break;
+ case 0x87: { *dptr = (dk4_c32_t)0x2021; back = 1; } break;
+ case 0x88: { *dptr = (dk4_c32_t)0x02C6; back = 1; } break;
+ case 0x89: { *dptr = (dk4_c32_t)0x2030; back = 1; } break;
+ case 0x8A: { *dptr = (dk4_c32_t)0x0160; back = 1; } break;
+ case 0x8B: { *dptr = (dk4_c32_t)0x2039; back = 1; } break;
+ case 0x8C: { *dptr = (dk4_c32_t)0x0152; back = 1; } break;
+ case 0x8D: { *dptr = (dk4_c32_t)0x008D; back = 1; } break;
+ case 0x8E: { *dptr = (dk4_c32_t)0x017D; back = 1; } break;
+ case 0x8F: { *dptr = (dk4_c32_t)0x008F; back = 1; } break;
+ case 0x90: { *dptr = (dk4_c32_t)0x0090; back = 1; } break;
+ case 0x91: { *dptr = (dk4_c32_t)0x2018; back = 1; } break;
+ case 0x92: { *dptr = (dk4_c32_t)0x2019; back = 1; } break;
+ case 0x93: { *dptr = (dk4_c32_t)0x201C; back = 1; } break;
+ case 0x94: { *dptr = (dk4_c32_t)0x201D; back = 1; } break;
+ case 0x95: { *dptr = (dk4_c32_t)0x2022; back = 1; } break;
+ case 0x96: { *dptr = (dk4_c32_t)0x2013; back = 1; } break;
+ case 0x97: { *dptr = (dk4_c32_t)0x2014; back = 1; } break;
+ case 0x98: { *dptr = (dk4_c32_t)0x02DC; back = 1; } break;
+ case 0x99: { *dptr = (dk4_c32_t)0x2122; back = 1; } break;
+ case 0x9A: { *dptr = (dk4_c32_t)0x0161; back = 1; } break;
+ case 0x9B: { *dptr = (dk4_c32_t)0x203A; back = 1; } break;
+ case 0x9C: { *dptr = (dk4_c32_t)0x0153; back = 1; } break;
+ case 0x9D: { *dptr = (dk4_c32_t)0x009D; back = 1; } break;
+ case 0x9E: { *dptr = (dk4_c32_t)0x017E; back = 1; } break;
+ case 0x9F: { *dptr = (dk4_c32_t)0x0178; back = 1; } break;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4ansi.ctr b/support/dktools/dk4ansi.ctr
new file mode 100644
index 0000000000..552a5769a8
--- /dev/null
+++ b/support/dktools/dk4ansi.ctr
@@ -0,0 +1,172 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Character conversion from ANSI to UNICODE
+ and vice versa.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Encode 32 bit character as ANSI character if possible.
+ @param dptr Pointer to result variable.
+ @param c32 Character to convert.
+ @return 1 on success, 0 on error (character c32 out of range).
+*/
+int
+dk4ansi_encode(unsigned char *dptr, dk4_c32_t c32);
+
+/** Retrieve 32 bit character from ANSI encoded character.
+ @param dptr Pointer to result variable.
+ @param uc ANSI character to convert.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4ansi_decode(dk4_c32_t *dptr, unsigned char uc);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4ansi.h"
+#include "dk4numco.h"
+
+
+int
+dk4ansi_encode(unsigned char *dptr, dk4_c32_t c32)
+{
+ int back = 0;
+ if (NULL != dptr) {
+ if ((dk4_c32_t)0x80 > c32) {
+ *dptr = (unsigned char)c32;
+ back = 1;
+ } else {
+ if (((dk4_c32_t)0x9F < c32) && ((dk4_c32_t)0x0100 > c32)) {
+ *dptr = (unsigned char)c32;
+ back = 1;
+ } else {
+ if ((dk4_c32_t)INT_MAX > c32) {
+ switch ((int)c32) {
+ case 0x20AC: { *dptr = (unsigned char)0x80; back = 1; } break;
+ case 0x0081: { *dptr = (unsigned char)0x81; back = 1; } break;
+ case 0x201A: { *dptr = (unsigned char)0x82; back = 1; } break;
+ case 0x0192: { *dptr = (unsigned char)0x83; back = 1; } break;
+ case 0x201E: { *dptr = (unsigned char)0x84; back = 1; } break;
+ case 0x2026: { *dptr = (unsigned char)0x85; back = 1; } break;
+ case 0x2020: { *dptr = (unsigned char)0x86; back = 1; } break;
+ case 0x2021: { *dptr = (unsigned char)0x87; back = 1; } break;
+ case 0x02C6: { *dptr = (unsigned char)0x88; back = 1; } break;
+ case 0x2030: { *dptr = (unsigned char)0x89; back = 1; } break;
+ case 0x0160: { *dptr = (unsigned char)0x8A; back = 1; } break;
+ case 0x2039: { *dptr = (unsigned char)0x8B; back = 1; } break;
+ case 0x0152: { *dptr = (unsigned char)0x8C; back = 1; } break;
+ case 0x008D: { *dptr = (unsigned char)0x8D; back = 1; } break;
+ case 0x017D: { *dptr = (unsigned char)0x8E; back = 1; } break;
+ case 0x008F: { *dptr = (unsigned char)0x8F; back = 1; } break;
+ case 0x0090: { *dptr = (unsigned char)0x90; back = 1; } break;
+ case 0x2018: { *dptr = (unsigned char)0x91; back = 1; } break;
+ case 0x2019: { *dptr = (unsigned char)0x92; back = 1; } break;
+ case 0x201C: { *dptr = (unsigned char)0x93; back = 1; } break;
+ case 0x201D: { *dptr = (unsigned char)0x94; back = 1; } break;
+ case 0x2022: { *dptr = (unsigned char)0x95; back = 1; } break;
+ case 0x2013: { *dptr = (unsigned char)0x96; back = 1; } break;
+ case 0x2014: { *dptr = (unsigned char)0x97; back = 1; } break;
+ case 0x02DC: { *dptr = (unsigned char)0x98; back = 1; } break;
+ case 0x2122: { *dptr = (unsigned char)0x99; back = 1; } break;
+ case 0x0161: { *dptr = (unsigned char)0x9A; back = 1; } break;
+ case 0x203A: { *dptr = (unsigned char)0x9B; back = 1; } break;
+ case 0x0153: { *dptr = (unsigned char)0x9C; back = 1; } break;
+ case 0x009D: { *dptr = (unsigned char)0x9D; back = 1; } break;
+ case 0x017E: { *dptr = (unsigned char)0x9E; back = 1; } break;
+ case 0x0178: { *dptr = (unsigned char)0x9F; back = 1; } break;
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4ansi_decode(dk4_c32_t *dptr, unsigned char uc)
+{
+ int back = 0;
+ if (NULL != dptr) {
+ if (0x80 > uc) {
+ *dptr = (dk4_c32_t)uc;
+ back = 1;
+ } else {
+ if (0x9F < uc) {
+ *dptr = (dk4_c32_t)uc;
+ back = 1;
+ } else {
+ switch ((int)uc) {
+ case 0x80: { *dptr = (dk4_c32_t)0x20AC; back = 1; } break;
+ case 0x81: { *dptr = (dk4_c32_t)0x0081; back = 1; } break;
+ case 0x82: { *dptr = (dk4_c32_t)0x201A; back = 1; } break;
+ case 0x83: { *dptr = (dk4_c32_t)0x0192; back = 1; } break;
+ case 0x84: { *dptr = (dk4_c32_t)0x201E; back = 1; } break;
+ case 0x85: { *dptr = (dk4_c32_t)0x2026; back = 1; } break;
+ case 0x86: { *dptr = (dk4_c32_t)0x2020; back = 1; } break;
+ case 0x87: { *dptr = (dk4_c32_t)0x2021; back = 1; } break;
+ case 0x88: { *dptr = (dk4_c32_t)0x02C6; back = 1; } break;
+ case 0x89: { *dptr = (dk4_c32_t)0x2030; back = 1; } break;
+ case 0x8A: { *dptr = (dk4_c32_t)0x0160; back = 1; } break;
+ case 0x8B: { *dptr = (dk4_c32_t)0x2039; back = 1; } break;
+ case 0x8C: { *dptr = (dk4_c32_t)0x0152; back = 1; } break;
+ case 0x8D: { *dptr = (dk4_c32_t)0x008D; back = 1; } break;
+ case 0x8E: { *dptr = (dk4_c32_t)0x017D; back = 1; } break;
+ case 0x8F: { *dptr = (dk4_c32_t)0x008F; back = 1; } break;
+ case 0x90: { *dptr = (dk4_c32_t)0x0090; back = 1; } break;
+ case 0x91: { *dptr = (dk4_c32_t)0x2018; back = 1; } break;
+ case 0x92: { *dptr = (dk4_c32_t)0x2019; back = 1; } break;
+ case 0x93: { *dptr = (dk4_c32_t)0x201C; back = 1; } break;
+ case 0x94: { *dptr = (dk4_c32_t)0x201D; back = 1; } break;
+ case 0x95: { *dptr = (dk4_c32_t)0x2022; back = 1; } break;
+ case 0x96: { *dptr = (dk4_c32_t)0x2013; back = 1; } break;
+ case 0x97: { *dptr = (dk4_c32_t)0x2014; back = 1; } break;
+ case 0x98: { *dptr = (dk4_c32_t)0x02DC; back = 1; } break;
+ case 0x99: { *dptr = (dk4_c32_t)0x2122; back = 1; } break;
+ case 0x9A: { *dptr = (dk4_c32_t)0x0161; back = 1; } break;
+ case 0x9B: { *dptr = (dk4_c32_t)0x203A; back = 1; } break;
+ case 0x9C: { *dptr = (dk4_c32_t)0x0153; back = 1; } break;
+ case 0x9D: { *dptr = (dk4_c32_t)0x009D; back = 1; } break;
+ case 0x9E: { *dptr = (dk4_c32_t)0x017E; back = 1; } break;
+ case 0x9F: { *dptr = (dk4_c32_t)0x0178; back = 1; } break;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4ansi.h b/support/dktools/dk4ansi.h
new file mode 100644
index 0000000000..4943002e30
--- /dev/null
+++ b/support/dktools/dk4ansi.h
@@ -0,0 +1,89 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4ansi.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4ANSI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4ANSI_H_INCLUDED 1
+
+
+#line 10 "dk4ansi.ctr"
+
+/** @file
+ Character conversion from ANSI to UNICODE
+ and vice versa.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Encode 32 bit character as ANSI character if possible.
+ @param dptr Pointer to result variable.
+ @param c32 Character to convert.
+ @return 1 on success, 0 on error (character c32 out of range).
+*/
+int
+dk4ansi_encode(unsigned char *dptr, dk4_c32_t c32);
+
+/** Retrieve 32 bit character from ANSI encoded character.
+ @param dptr Pointer to result variable.
+ @param uc ANSI character to convert.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4ansi_decode(dk4_c32_t *dptr, unsigned char uc);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4aopt.h b/support/dktools/dk4aopt.h
new file mode 100644
index 0000000000..ada76714e5
--- /dev/null
+++ b/support/dktools/dk4aopt.h
@@ -0,0 +1,482 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4aopt.ctr
+*/
+
+/*
+Copyright (C) 2014, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4AOPT_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4AOPT_H_INCLUDED 1
+
+/** @file dk4aopt.h Command line options with dk4_app_t support.
+
+The dk4app_opt_is_set_short() and dk4app_opt_is_set_long() only return
+success, if the specified option was allowed in the option specification
+and found on the command line.
+
+The dk4app_opt_get_string_short(), dk4app_opt_get_string_long(),
+dk4app_opt_get_double_short(), dk4app_opt_get_double_long(),
+dk4app_opt_get_int_short(), dk4app_opt_get_int_long(),
+dk4app_opt_get_unsigned_short(), dk4app_opt_get_unsigned_long(),
+dk4app_opt_get_size_short(), dk4app_opt_get_size_long(),
+dk4app_opt_get_bool_short(), and dk4app_opt_get_bool_long()
+functions only return success, if the specified option was allowed/configured
+in the option specifications with the correct data type and the option
+was found on the command line.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4APP_H_INCLUDED
+#include "dk4app.h"
+#endif
+
+#ifndef DK4OPT_H_INCLUDED
+#include "dk4opt.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Check whether a short option is set.
+ @param app Application structure.
+ @param c Short option character.
+ @param erp Error report, may be NULL.
+ @return 1 if option is set, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if rp or app is NULL or the application is not configured for
+ preferences retrieval,
+ - DK4_E_SYNTAX<br>
+ if an invalid option was specified,
+ - DK4_E_NOT_FOUND<br>
+ if the option was not used on the command line.
+*/
+int
+dk4app_opt_is_set_short(dk4_app_t *app, dkChar c, dk4_er_t *erp);
+
+/** Check whether a long option is set.
+ @param app Application structure.
+ @param n Long option name.
+ @param erp Error report, may be NULL.
+ @return 1 if option is set, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if rp, app, or n is NULL or the application is not configured
+ for preferences retrieval,
+ - DK4_E_SYNTAX<br>
+ if an invalid option was specified,
+ - DK4_E_NOT_FOUND<br>
+ if the option was not used on the command line.
+*/
+int
+dk4app_opt_is_set_long(dk4_app_t *app, const dkChar *n, dk4_er_t *erp);
+
+/** Get string argument for short option.
+ @param dptr Address of result buffer.
+ @param szdptr Size of result buffer (number of dkChar).
+ @param app Application structure.
+ @param c Short option character.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if rp or app is NULL or the application is not configured for
+ preferences retrieval,
+ - DK4_E_SYNTAX<br>
+ if an invalid option was specified or the option was configured for
+ an incompatible data type,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the destination buffer is too small to hold the text,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the destination buffer is too small to hold a conversion result,
+ - DK4_E_NOT_FOUND<br>
+ if the option was not used on the command line.
+*/
+int
+dk4app_opt_get_string_short(
+ dkChar *dptr,
+ size_t szdptr,
+ dk4_app_t *app,
+ dkChar c,
+ dk4_er_t *erp
+);
+
+/** Get string argument for long option.
+ @param dptr Address of result buffer.
+ @param szdptr Size of result buffer (number of dkChar).
+ @param app Application structure.
+ @param n Long option name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if rp or app is NULL or the application is not configured for
+ preferences retrieval,
+ - DK4_E_SYNTAX<br>
+ if an invalid option was specified or the option was configured for
+ an incompatible data type,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the destination buffer is too small to hold the text,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the destination buffer is too small to hold a conversion result,
+ - DK4_E_NOT_FOUND<br>
+ if the option was not used on the command line.
+*/
+int
+dk4app_opt_get_string_long(
+ dkChar *dptr,
+ size_t szdptr,
+ dk4_app_t *app,
+ const dkChar *n,
+ dk4_er_t *erp
+);
+
+/** Get pointer to string argument for short option.
+ @param app Application structure.
+ @param c Short option character.
+ @param erp Error report, may be NULL.
+ @return Pointer to string argument on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if app is NULL or there is no option storage in app,
+ - DK4_E_SYNTAX<br>
+ if c is not in the list of accepted options or does not
+ accept a string argument,
+ - DK4_E_NOT_FOUND<br>
+ if the option was not specified on the command line.
+*/
+const dkChar *
+dk4app_opt_get_string_ptr_short(dk4_app_t *app, dkChar c, dk4_er_t *erp);
+
+/** Get pointer to string argument for long option.
+ @param app Application structure.
+ @param n Long option character.
+ @param erp Error report, may be NULL.
+ @return Pointer to string argument on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if app is NULL or there is no option storage in app,
+ - DK4_E_SYNTAX<br>
+ if n is not in the list of accepted options or does not
+ accept a string argument,
+ - DK4_E_NOT_FOUND<br>
+ if the option was not specified on the command line.
+*/
+const dkChar *
+dk4app_opt_get_string_ptr_long(dk4_app_t *app, const dkChar *n, dk4_er_t *erp);
+
+/** Get double argument for short option.
+ @param rp Address of result variable.
+ @param app Application structure.
+ @param c Short option character.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if rp or app is NULL or the application is not configured
+ for preferences retrieval,
+ - DK4_E_SYNTAX<br>
+ if an invalid option was specified or the option was configured for
+ an incompatible data type,
+ - DK4_E_NOT_FOUND<br>
+ if the option was not used on the command line.
+*/
+int
+dk4app_opt_get_double_short(
+ double *rp,
+ dk4_app_t *app,
+ dkChar c,
+ dk4_er_t *erp
+);
+
+/** Get double argument for long option.
+ @param rp Address of result variable.
+ @param app Application structure.
+ @param n Long option name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if rp, app, or n is NULL or the application is not configured for
+ preferences retrieval,
+ - DK4_E_SYNTAX<br>
+ if an invalid option was specified,
+ - DK4_E_NOT_FOUND<br>
+ if the option was not used on the command line.
+*/
+int
+dk4app_opt_get_double_long(
+ double *rp,
+ dk4_app_t *app,
+ const dkChar *n,
+ dk4_er_t *erp
+);
+
+/** Get integer argument for short option.
+ @param rp Address of result variable.
+ @param app Application structure.
+ @param c Short option character.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if rp or app is NULL or the application is not configured for
+ preferences retrieval,
+ - DK4_E_SYNTAX<br>
+ if an invalid option was specified or the option was configured for
+ an incompatible type or the option argument string does not
+ represent an integer number,
+ - DK4_E_MATH_OVERFLOW<br>
+ if the option was configured for another numeric type and conversion
+ results in an overflow,
+ - DK4_E_NOT_FOUND<br>
+ if the option was not used on the command line.
+*/
+int
+dk4app_opt_get_int_short(dk4_im_t *rp, dk4_app_t *app, dkChar c, dk4_er_t *erp);
+
+/** Get integer argument for long option.
+ @param rp Address of result variable.
+ @param app Application structure.
+ @param n Long option name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if rp or app is NULL or the application is not configured for
+ preferences retrieval,
+ - DK4_E_SYNTAX<br>
+ if an invalid option was specified or the option was configured for
+ an incompatible type or the option argument string does not
+ represent an integer number,
+ - DK4_E_MATH_OVERFLOW<br>
+ if the option was configured for another numeric type and conversion
+ results in an overflow,
+ - DK4_E_NOT_FOUND<br>
+ if the option was not used on the command line.
+*/
+int
+dk4app_opt_get_int_long(
+ dk4_im_t *rp,
+ dk4_app_t *app,
+ const dkChar *n,
+ dk4_er_t *erp
+);
+
+/** Get unsigned integer argument for short option.
+ @param rp Address of result variable.
+ @param app Application structure.
+ @param c Short option character.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if rp or app is NULL or the application is not configured for
+ preferences retrieval,
+ - DK4_E_SYNTAX<br>
+ if an invalid option was specified or the option was configured for
+ an incompatible data type or the option argument string does not
+ represent an integer number,
+ - DK4_E_MATH_OVERFLOW<br>
+ if the option was configured for an incompatible numeric type and a
+ negative value is stored,
+ - DK4_E_NOT_FOUND<br>
+ if the option was not used on the command line.
+*/
+int
+dk4app_opt_get_unsigned_short(
+ dk4_um_t *rp,
+ dk4_app_t *app,
+ dkChar c,
+ dk4_er_t *erp
+);
+
+/** Get unsigned integer argument for long option.
+ @param rp Address of result variable.
+ @param app Application structure.
+ @param n Long option name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if rp or app is NULL or the application is not configured for
+ preferences retrieval,
+ - DK4_E_SYNTAX<br>
+ if an invalid option was specified or the option was configured for
+ an incompatible data type or the option argument string does not
+ represent an integer number,
+ - DK4_E_MATH_OVERFLOW<br>
+ if the option was configured for an incompatible numeric type and a
+ negative value is stored,
+ - DK4_E_NOT_FOUND<br>
+ if the option was not used on the command line.
+*/
+int
+dk4app_opt_get_unsigned_long(
+ dk4_um_t *rp,
+ dk4_app_t *app,
+ const dkChar *n,
+ dk4_er_t *erp
+);
+
+/** Get size_t argument for short option.
+ @param rp Address of result variable.
+ @param app Application structure.
+ @param c Short option character.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if rp or app is NULL or the application is not configured for
+ preferences retrieval,
+ - DK4_E_SYNTAX<br>
+ if an invalid option was specified or the option was configured for
+ an incompatible type or the option argument string can not be
+ converted to size_t,
+ - DK4_E_MATH_OVERFLOW<br>
+ if the option was configured for another numeric type and conversion
+ results in an overflow.
+ - DK4_E_NOT_FOUND<br>
+ if the option was not used on the command line.
+*/
+int
+dk4app_opt_get_size_short(size_t *rp, dk4_app_t *app, dkChar c, dk4_er_t *erp);
+
+/** Get size_t argument for long option.
+ @param rp Address of result variable.
+ @param app Application structure.
+ @param n Long option name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if rp or app is NULL or the application is not configured for
+ preferences retrieval,
+ - DK4_E_SYNTAX<br>
+ if an invalid option was specified or the option was configured for
+ an incompatible type or the option argument string can not be
+ converted to size_t,
+ - DK4_E_MATH_OVERFLOW<br>
+ if the option was configured for another numeric type and conversion
+ results in an overflow.
+ - DK4_E_NOT_FOUND<br>
+ if the option was not used on the command line.
+*/
+int
+dk4app_opt_get_size_long(
+ size_t *rp,
+ dk4_app_t *app,
+ const dkChar *n,
+ dk4_er_t *erp
+);
+
+/** Get boolean argument for short option.
+ @param rp Address of result variable.
+ @param app Application structure.
+ @param c Short option character.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if rp, app, or n is NULL or the application is not configured for
+ preferences retrieval,
+ - DK4_E_SYNTAX<br>
+ if an invalid option was specified or the option was configured for
+ an incompatible data type,
+ - DK4_E_NOT_FOUND<br>
+ if the option was not used on the command line.
+*/
+int
+dk4app_opt_get_bool_short(int *rp, dk4_app_t *app, dkChar c, dk4_er_t *erp);
+
+/** Get boolean argument for long option.
+ @param rp Address of result variable.
+ @param app Application structure.
+ @param n Long option name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if rp, app, or n is NULL or the application is not configured for
+ preferences retrieval,
+ - DK4_E_SYNTAX<br>
+ if an invalid option was specified or the option was configured for
+ an incompatible data type,
+ - DK4_E_NOT_FOUND<br>
+ if the option was not used on the command line.
+*/
+int
+dk4app_opt_get_bool_long(
+ int *rp,
+ dk4_app_t *app,
+ const dkChar *n,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4aopt01.c b/support/dktools/dk4aopt01.c
new file mode 100644
index 0000000000..daaca33eb2
--- /dev/null
+++ b/support/dktools/dk4aopt01.c
@@ -0,0 +1,72 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4aopt01.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4aopt01.c The dk4aopt01 module.
+*/
+
+
+#line 10 "dk4aopt01.ctr"
+
+#include "dk4opt.h"
+#include "dk4aopt.h"
+
+
+
+int
+dk4app_opt_is_set_short(dk4_app_t *app, dkChar c, dk4_er_t *erp)
+{
+ dk4_option_t *optr;
+ int back = 0;
+ if (NULL != app) {
+ if (NULL != app->i_opt_short) {
+ optr = (dk4_option_t *)dk4sto_it_find_like(app->i_opt_short, &c, 1);
+ if (NULL != optr) {
+ if (0 != optr->found) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4aopt01.ctr b/support/dktools/dk4aopt01.ctr
new file mode 100644
index 0000000000..e12a28fe0a
--- /dev/null
+++ b/support/dktools/dk4aopt01.ctr
@@ -0,0 +1,41 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4opt.h"
+#include "dk4aopt.h"
+
+
+
+int
+dk4app_opt_is_set_short(dk4_app_t *app, dkChar c, dk4_er_t *erp)
+{
+ dk4_option_t *optr;
+ int back = 0;
+ if (NULL != app) {
+ if (NULL != app->i_opt_short) {
+ optr = (dk4_option_t *)dk4sto_it_find_like(app->i_opt_short, &c, 1);
+ if (NULL != optr) {
+ if (0 != optr->found) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4aopt02.c b/support/dktools/dk4aopt02.c
new file mode 100644
index 0000000000..d24ca25365
--- /dev/null
+++ b/support/dktools/dk4aopt02.c
@@ -0,0 +1,72 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4aopt02.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4aopt02.c The dk4aopt02 module.
+*/
+
+
+#line 10 "dk4aopt02.ctr"
+
+#include "dk4opt.h"
+#include "dk4aopt.h"
+
+
+
+int
+dk4app_opt_is_set_long(dk4_app_t *app, const dkChar *n, dk4_er_t *erp)
+{
+ dk4_option_t *optr;
+ int back = 0;
+ if ((NULL != app) && (NULL != n)) {
+ if (NULL != app->i_opt_long) {
+ optr = (dk4_option_t *)dk4sto_it_find_like(app->i_opt_long, n, 3);
+ if (NULL != optr) {
+ if (0 != optr->found) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4aopt02.ctr b/support/dktools/dk4aopt02.ctr
new file mode 100644
index 0000000000..2dea13ae66
--- /dev/null
+++ b/support/dktools/dk4aopt02.ctr
@@ -0,0 +1,41 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4opt.h"
+#include "dk4aopt.h"
+
+
+
+int
+dk4app_opt_is_set_long(dk4_app_t *app, const dkChar *n, dk4_er_t *erp)
+{
+ dk4_option_t *optr;
+ int back = 0;
+ if ((NULL != app) && (NULL != n)) {
+ if (NULL != app->i_opt_long) {
+ optr = (dk4_option_t *)dk4sto_it_find_like(app->i_opt_long, n, 3);
+ if (NULL != optr) {
+ if (0 != optr->found) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4aopt03.c b/support/dktools/dk4aopt03.c
new file mode 100644
index 0000000000..401a642979
--- /dev/null
+++ b/support/dktools/dk4aopt03.c
@@ -0,0 +1,74 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4aopt03.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4aopt03.c The dk4aopt03 module.
+*/
+
+
+#line 10 "dk4aopt03.ctr"
+
+#include "dk4opt.h"
+#include "dk4aopt.h"
+
+
+
+int
+dk4app_opt_get_string_short(
+ dkChar *dptr, size_t szdptr, dk4_app_t *app, dkChar c, dk4_er_t *erp
+)
+{
+ dk4_option_t *optr;
+ int back = 0;
+ if ((NULL != dptr) && (0 < szdptr) && (NULL != app)) {
+ if (NULL != app->i_opt_short) {
+ optr = (dk4_option_t *)dk4sto_it_find_like(app->i_opt_short, &c, 1);
+ if (NULL != optr) {
+ if (0 != optr->found) {
+ back = dk4opt_get_string(dptr, szdptr, optr, NULL);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4aopt03.ctr b/support/dktools/dk4aopt03.ctr
new file mode 100644
index 0000000000..cc7c4110c9
--- /dev/null
+++ b/support/dktools/dk4aopt03.ctr
@@ -0,0 +1,43 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4opt.h"
+#include "dk4aopt.h"
+
+
+
+int
+dk4app_opt_get_string_short(
+ dkChar *dptr, size_t szdptr, dk4_app_t *app, dkChar c, dk4_er_t *erp
+)
+{
+ dk4_option_t *optr;
+ int back = 0;
+ if ((NULL != dptr) && (0 < szdptr) && (NULL != app)) {
+ if (NULL != app->i_opt_short) {
+ optr = (dk4_option_t *)dk4sto_it_find_like(app->i_opt_short, &c, 1);
+ if (NULL != optr) {
+ if (0 != optr->found) {
+ back = dk4opt_get_string(dptr, szdptr, optr, NULL);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4aopt04.c b/support/dktools/dk4aopt04.c
new file mode 100644
index 0000000000..400d951be0
--- /dev/null
+++ b/support/dktools/dk4aopt04.c
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4aopt04.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4aopt04.c The dk4aopt04 module.
+*/
+
+
+#line 10 "dk4aopt04.ctr"
+
+#include "dk4opt.h"
+#include "dk4aopt.h"
+
+
+
+
+
+#line 17 "dk4aopt04.ctr"
+
+
+
+int
+dk4app_opt_get_string_long(
+ dkChar *dptr, size_t szdptr, dk4_app_t *app, const dkChar *n, dk4_er_t *erp
+)
+{
+ dk4_option_t *optr;
+ int back = 0;
+
+
+#line 28 "dk4aopt04.ctr"
+ if ((NULL != dptr) && (0 < szdptr) && (NULL != app) && (NULL != n)) {
+
+
+#line 30 "dk4aopt04.ctr"
+ if (NULL != app->i_opt_long) {
+
+#line 31 "dk4aopt04.ctr"
+ optr = (dk4_option_t *)dk4sto_it_find_like(app->i_opt_long, n, 3);
+ if (NULL != optr) {
+
+#line 33 "dk4aopt04.ctr"
+ if (0 != optr->found) {
+
+#line 34 "dk4aopt04.ctr"
+ back = dk4opt_get_string(dptr, szdptr, optr, NULL);
+ } else {
+
+#line 36 "dk4aopt04.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+
+#line 39 "dk4aopt04.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+
+#line 42 "dk4aopt04.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+
+#line 45 "dk4aopt04.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 47 "dk4aopt04.ctr"
+ return back;
+}
+
diff --git a/support/dktools/dk4aopt04.ctr b/support/dktools/dk4aopt04.ctr
new file mode 100644
index 0000000000..69eb8c805a
--- /dev/null
+++ b/support/dktools/dk4aopt04.ctr
@@ -0,0 +1,49 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4opt.h"
+#include "dk4aopt.h"
+
+
+
+$!trace-include
+
+
+
+int
+dk4app_opt_get_string_long(
+ dkChar *dptr, size_t szdptr, dk4_app_t *app, const dkChar *n, dk4_er_t *erp
+)
+{
+ dk4_option_t *optr;
+ int back = 0;
+ $? "+ dk4app_opt_get_string_long"
+ if ((NULL != dptr) && (0 < szdptr) && (NULL != app) && (NULL != n)) {
+ $? ". args ok"
+ if (NULL != app->i_opt_long) { $? ". long opt iterator ok"
+ optr = (dk4_option_t *)dk4sto_it_find_like(app->i_opt_long, n, 3);
+ if (NULL != optr) { $? ". option found"
+ if (0 != optr->found) { $? ". option used on cmd line"
+ back = dk4opt_get_string(dptr, szdptr, optr, NULL);
+ } else { $? "! option not used"
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else { $? "! no such option"
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else { $? "! long opt iterator"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else { $? "! args"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4app_opt_get_string_long %d", back
+ return back;
+}
+
diff --git a/support/dktools/dk4aopt05.c b/support/dktools/dk4aopt05.c
new file mode 100644
index 0000000000..87bdd3f39b
--- /dev/null
+++ b/support/dktools/dk4aopt05.c
@@ -0,0 +1,72 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4aopt05.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4aopt05.c The dk4aopt05 module.
+*/
+
+
+#line 10 "dk4aopt05.ctr"
+
+#include "dk4opt.h"
+#include "dk4aopt.h"
+
+
+
+int
+dk4app_opt_get_double_short(double *rp, dk4_app_t *app, dkChar c, dk4_er_t *erp)
+{
+ dk4_option_t *optr;
+ int back = 0;
+ if ((NULL != rp) && (NULL != app)) {
+ if (NULL != app->i_opt_short) {
+ optr = (dk4_option_t *)dk4sto_it_find_like(app->i_opt_short, &c, 1);
+ if (NULL != optr) {
+ if (0 != optr->found) {
+ back = dk4opt_get_double(rp, optr, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4aopt05.ctr b/support/dktools/dk4aopt05.ctr
new file mode 100644
index 0000000000..48302a94f8
--- /dev/null
+++ b/support/dktools/dk4aopt05.ctr
@@ -0,0 +1,41 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4opt.h"
+#include "dk4aopt.h"
+
+
+
+int
+dk4app_opt_get_double_short(double *rp, dk4_app_t *app, dkChar c, dk4_er_t *erp)
+{
+ dk4_option_t *optr;
+ int back = 0;
+ if ((NULL != rp) && (NULL != app)) {
+ if (NULL != app->i_opt_short) {
+ optr = (dk4_option_t *)dk4sto_it_find_like(app->i_opt_short, &c, 1);
+ if (NULL != optr) {
+ if (0 != optr->found) {
+ back = dk4opt_get_double(rp, optr, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4aopt06.c b/support/dktools/dk4aopt06.c
new file mode 100644
index 0000000000..a7712effca
--- /dev/null
+++ b/support/dktools/dk4aopt06.c
@@ -0,0 +1,74 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4aopt06.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4aopt06.c The dk4aopt06 module.
+*/
+
+
+#line 10 "dk4aopt06.ctr"
+
+#include "dk4opt.h"
+#include "dk4aopt.h"
+
+
+
+int
+dk4app_opt_get_double_long(
+ double *rp, dk4_app_t *app, const dkChar *n, dk4_er_t *erp
+)
+{
+ dk4_option_t *optr;
+ int back = 0;
+ if ((NULL != rp) && (NULL != app) && (NULL != n)) {
+ if (NULL != app->i_opt_long) {
+ optr = (dk4_option_t *)dk4sto_it_find_like(app->i_opt_long, n, 3);
+ if (NULL != optr) {
+ if (0 != optr->found) {
+ back = dk4opt_get_double(rp, optr, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4aopt06.ctr b/support/dktools/dk4aopt06.ctr
new file mode 100644
index 0000000000..f3eae95095
--- /dev/null
+++ b/support/dktools/dk4aopt06.ctr
@@ -0,0 +1,43 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4opt.h"
+#include "dk4aopt.h"
+
+
+
+int
+dk4app_opt_get_double_long(
+ double *rp, dk4_app_t *app, const dkChar *n, dk4_er_t *erp
+)
+{
+ dk4_option_t *optr;
+ int back = 0;
+ if ((NULL != rp) && (NULL != app) && (NULL != n)) {
+ if (NULL != app->i_opt_long) {
+ optr = (dk4_option_t *)dk4sto_it_find_like(app->i_opt_long, n, 3);
+ if (NULL != optr) {
+ if (0 != optr->found) {
+ back = dk4opt_get_double(rp, optr, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4aopt07.c b/support/dktools/dk4aopt07.c
new file mode 100644
index 0000000000..45d6ff54ff
--- /dev/null
+++ b/support/dktools/dk4aopt07.c
@@ -0,0 +1,73 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4aopt07.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4aopt07.c The dk4aopt07 module.
+*/
+
+
+#line 10 "dk4aopt07.ctr"
+
+#include "dk4opt.h"
+#include "dk4aopt.h"
+
+
+
+int
+dk4app_opt_get_int_short(dk4_im_t *rp, dk4_app_t *app, dkChar c, dk4_er_t *erp)
+{
+ dk4_option_t *optr;
+ int back = 0;
+ if ((NULL != rp) && (NULL != app)) {
+ if (NULL != app->i_opt_short) {
+ optr = (dk4_option_t *)dk4sto_it_find_like(app->i_opt_short, &c, 1);
+ if (NULL != optr) {
+ if (0 != optr->found) {
+ back = dk4opt_get_int(rp, optr, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4aopt07.ctr b/support/dktools/dk4aopt07.ctr
new file mode 100644
index 0000000000..8685316131
--- /dev/null
+++ b/support/dktools/dk4aopt07.ctr
@@ -0,0 +1,42 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4opt.h"
+#include "dk4aopt.h"
+
+
+
+int
+dk4app_opt_get_int_short(dk4_im_t *rp, dk4_app_t *app, dkChar c, dk4_er_t *erp)
+{
+ dk4_option_t *optr;
+ int back = 0;
+ if ((NULL != rp) && (NULL != app)) {
+ if (NULL != app->i_opt_short) {
+ optr = (dk4_option_t *)dk4sto_it_find_like(app->i_opt_short, &c, 1);
+ if (NULL != optr) {
+ if (0 != optr->found) {
+ back = dk4opt_get_int(rp, optr, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4aopt08.c b/support/dktools/dk4aopt08.c
new file mode 100644
index 0000000000..62bea0ee2a
--- /dev/null
+++ b/support/dktools/dk4aopt08.c
@@ -0,0 +1,74 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4aopt08.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4aopt08.c The dk4aopt08 module.
+*/
+
+
+#line 10 "dk4aopt08.ctr"
+
+#include "dk4opt.h"
+#include "dk4aopt.h"
+
+
+
+int
+dk4app_opt_get_int_long(
+ dk4_im_t *rp, dk4_app_t *app, const dkChar *n, dk4_er_t *erp
+)
+{
+ dk4_option_t *optr;
+ int back = 0;
+ if ((NULL != rp) && (NULL != app) && (NULL != n)) {
+ if (NULL != app->i_opt_long) {
+ optr = (dk4_option_t *)dk4sto_it_find_like(app->i_opt_long, n, 3);
+ if (NULL != optr) {
+ if (0 != optr->found) {
+ back = dk4opt_get_int(rp, optr, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4aopt08.ctr b/support/dktools/dk4aopt08.ctr
new file mode 100644
index 0000000000..9b1813e935
--- /dev/null
+++ b/support/dktools/dk4aopt08.ctr
@@ -0,0 +1,43 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4opt.h"
+#include "dk4aopt.h"
+
+
+
+int
+dk4app_opt_get_int_long(
+ dk4_im_t *rp, dk4_app_t *app, const dkChar *n, dk4_er_t *erp
+)
+{
+ dk4_option_t *optr;
+ int back = 0;
+ if ((NULL != rp) && (NULL != app) && (NULL != n)) {
+ if (NULL != app->i_opt_long) {
+ optr = (dk4_option_t *)dk4sto_it_find_like(app->i_opt_long, n, 3);
+ if (NULL != optr) {
+ if (0 != optr->found) {
+ back = dk4opt_get_int(rp, optr, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4aopt09.c b/support/dktools/dk4aopt09.c
new file mode 100644
index 0000000000..91ffd32f94
--- /dev/null
+++ b/support/dktools/dk4aopt09.c
@@ -0,0 +1,74 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4aopt09.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4aopt09.c The dk4aopt09 module.
+*/
+
+
+#line 10 "dk4aopt09.ctr"
+
+#include "dk4opt.h"
+#include "dk4aopt.h"
+
+
+
+int
+dk4app_opt_get_unsigned_short(
+ dk4_um_t *rp, dk4_app_t *app, dkChar c, dk4_er_t *erp
+)
+{
+ dk4_option_t *optr;
+ int back = 0;
+ if ((NULL != rp) && (NULL != app)) {
+ if (NULL != app->i_opt_short) {
+ optr = (dk4_option_t *)dk4sto_it_find_like(app->i_opt_short, &c, 1);
+ if (NULL != optr) {
+ if (0 != optr->found) {
+ back = dk4opt_get_unsigned(rp, optr, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4aopt09.ctr b/support/dktools/dk4aopt09.ctr
new file mode 100644
index 0000000000..01f60e8813
--- /dev/null
+++ b/support/dktools/dk4aopt09.ctr
@@ -0,0 +1,43 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4opt.h"
+#include "dk4aopt.h"
+
+
+
+int
+dk4app_opt_get_unsigned_short(
+ dk4_um_t *rp, dk4_app_t *app, dkChar c, dk4_er_t *erp
+)
+{
+ dk4_option_t *optr;
+ int back = 0;
+ if ((NULL != rp) && (NULL != app)) {
+ if (NULL != app->i_opt_short) {
+ optr = (dk4_option_t *)dk4sto_it_find_like(app->i_opt_short, &c, 1);
+ if (NULL != optr) {
+ if (0 != optr->found) {
+ back = dk4opt_get_unsigned(rp, optr, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4aopt10.c b/support/dktools/dk4aopt10.c
new file mode 100644
index 0000000000..b0c6abea09
--- /dev/null
+++ b/support/dktools/dk4aopt10.c
@@ -0,0 +1,74 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4aopt10.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4aopt10.c The dk4aopt10 module.
+*/
+
+
+#line 10 "dk4aopt10.ctr"
+
+#include "dk4opt.h"
+#include "dk4aopt.h"
+
+
+
+int
+dk4app_opt_get_unsigned_long(
+ dk4_um_t *rp, dk4_app_t *app, const dkChar *n, dk4_er_t *erp
+)
+{
+ dk4_option_t *optr;
+ int back = 0;
+ if ((NULL != rp) && (NULL != app) && (NULL != n)) {
+ if (NULL != app->i_opt_long) {
+ optr = (dk4_option_t *)dk4sto_it_find_like(app->i_opt_long, n, 3);
+ if (NULL != optr) {
+ if (0 != optr->found) {
+ back = dk4opt_get_unsigned(rp, optr, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4aopt10.ctr b/support/dktools/dk4aopt10.ctr
new file mode 100644
index 0000000000..ba7a89811b
--- /dev/null
+++ b/support/dktools/dk4aopt10.ctr
@@ -0,0 +1,43 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4opt.h"
+#include "dk4aopt.h"
+
+
+
+int
+dk4app_opt_get_unsigned_long(
+ dk4_um_t *rp, dk4_app_t *app, const dkChar *n, dk4_er_t *erp
+)
+{
+ dk4_option_t *optr;
+ int back = 0;
+ if ((NULL != rp) && (NULL != app) && (NULL != n)) {
+ if (NULL != app->i_opt_long) {
+ optr = (dk4_option_t *)dk4sto_it_find_like(app->i_opt_long, n, 3);
+ if (NULL != optr) {
+ if (0 != optr->found) {
+ back = dk4opt_get_unsigned(rp, optr, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4aopt11.c b/support/dktools/dk4aopt11.c
new file mode 100644
index 0000000000..0e676e1278
--- /dev/null
+++ b/support/dktools/dk4aopt11.c
@@ -0,0 +1,72 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4aopt11.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4aopt11.c The dk4aopt11 module.
+*/
+
+
+#line 10 "dk4aopt11.ctr"
+
+#include "dk4opt.h"
+#include "dk4aopt.h"
+
+
+
+int
+dk4app_opt_get_size_short(size_t *rp, dk4_app_t *app, dkChar c, dk4_er_t *erp)
+{
+ dk4_option_t *optr;
+ int back = 0;
+ if ((NULL != rp) && (NULL != app)) {
+ if (NULL != app->i_opt_short) {
+ optr = (dk4_option_t *)dk4sto_it_find_like(app->i_opt_short, &c, 1);
+ if (NULL != optr) {
+ if (0 != optr->found) {
+ back = dk4opt_get_size(rp, optr, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4aopt11.ctr b/support/dktools/dk4aopt11.ctr
new file mode 100644
index 0000000000..0265af2cd6
--- /dev/null
+++ b/support/dktools/dk4aopt11.ctr
@@ -0,0 +1,41 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4opt.h"
+#include "dk4aopt.h"
+
+
+
+int
+dk4app_opt_get_size_short(size_t *rp, dk4_app_t *app, dkChar c, dk4_er_t *erp)
+{
+ dk4_option_t *optr;
+ int back = 0;
+ if ((NULL != rp) && (NULL != app)) {
+ if (NULL != app->i_opt_short) {
+ optr = (dk4_option_t *)dk4sto_it_find_like(app->i_opt_short, &c, 1);
+ if (NULL != optr) {
+ if (0 != optr->found) {
+ back = dk4opt_get_size(rp, optr, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4aopt12.c b/support/dktools/dk4aopt12.c
new file mode 100644
index 0000000000..6c35031502
--- /dev/null
+++ b/support/dktools/dk4aopt12.c
@@ -0,0 +1,74 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4aopt12.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4aopt12.c The dk4aopt12 module.
+*/
+
+
+#line 10 "dk4aopt12.ctr"
+
+#include "dk4opt.h"
+#include "dk4aopt.h"
+
+
+
+int
+dk4app_opt_get_size_long(
+ size_t *rp, dk4_app_t *app, const dkChar *n, dk4_er_t *erp
+)
+{
+ dk4_option_t *optr;
+ int back = 0;
+ if ((NULL != rp) && (NULL != app) && (NULL != n)) {
+ if (NULL != app->i_opt_long) {
+ optr = (dk4_option_t *)dk4sto_it_find_like(app->i_opt_long, n, 3);
+ if (NULL != optr) {
+ if (0 != optr->found) {
+ back = dk4opt_get_size(rp, optr, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4aopt12.ctr b/support/dktools/dk4aopt12.ctr
new file mode 100644
index 0000000000..0d7f62d89b
--- /dev/null
+++ b/support/dktools/dk4aopt12.ctr
@@ -0,0 +1,43 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4opt.h"
+#include "dk4aopt.h"
+
+
+
+int
+dk4app_opt_get_size_long(
+ size_t *rp, dk4_app_t *app, const dkChar *n, dk4_er_t *erp
+)
+{
+ dk4_option_t *optr;
+ int back = 0;
+ if ((NULL != rp) && (NULL != app) && (NULL != n)) {
+ if (NULL != app->i_opt_long) {
+ optr = (dk4_option_t *)dk4sto_it_find_like(app->i_opt_long, n, 3);
+ if (NULL != optr) {
+ if (0 != optr->found) {
+ back = dk4opt_get_size(rp, optr, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4aopt13.c b/support/dktools/dk4aopt13.c
new file mode 100644
index 0000000000..18c6098912
--- /dev/null
+++ b/support/dktools/dk4aopt13.c
@@ -0,0 +1,72 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4aopt13.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4aopt13.c The dk4aopt13 module.
+*/
+
+
+#line 10 "dk4aopt13.ctr"
+
+#include "dk4opt.h"
+#include "dk4aopt.h"
+
+
+
+int
+dk4app_opt_get_bool_short(int *rp, dk4_app_t *app, dkChar c, dk4_er_t *erp)
+{
+ dk4_option_t *optr;
+ int back = 0;
+ if ((NULL != rp) && (NULL != app)) {
+ if (NULL != app->i_opt_short) {
+ optr = (dk4_option_t *)dk4sto_it_find_like(app->i_opt_short, &c, 1);
+ if (NULL != optr) {
+ if (0 != optr->found) {
+ back = dk4opt_get_bool(rp, optr, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4aopt13.ctr b/support/dktools/dk4aopt13.ctr
new file mode 100644
index 0000000000..945dc65b65
--- /dev/null
+++ b/support/dktools/dk4aopt13.ctr
@@ -0,0 +1,41 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4opt.h"
+#include "dk4aopt.h"
+
+
+
+int
+dk4app_opt_get_bool_short(int *rp, dk4_app_t *app, dkChar c, dk4_er_t *erp)
+{
+ dk4_option_t *optr;
+ int back = 0;
+ if ((NULL != rp) && (NULL != app)) {
+ if (NULL != app->i_opt_short) {
+ optr = (dk4_option_t *)dk4sto_it_find_like(app->i_opt_short, &c, 1);
+ if (NULL != optr) {
+ if (0 != optr->found) {
+ back = dk4opt_get_bool(rp, optr, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4aopt14.c b/support/dktools/dk4aopt14.c
new file mode 100644
index 0000000000..04c4325d4b
--- /dev/null
+++ b/support/dktools/dk4aopt14.c
@@ -0,0 +1,74 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4aopt14.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4aopt14.c The dk4aopt14 module.
+*/
+
+
+#line 10 "dk4aopt14.ctr"
+
+#include "dk4opt.h"
+#include "dk4aopt.h"
+
+
+
+int
+dk4app_opt_get_bool_long(
+ int *rp, dk4_app_t *app, const dkChar *n, dk4_er_t *erp
+)
+{
+ dk4_option_t *optr;
+ int back = 0;
+ if ((NULL != rp) && (NULL != app) && (NULL != n)) {
+ if (NULL != app->i_opt_long) {
+ optr = (dk4_option_t *)dk4sto_it_find_like(app->i_opt_long, n, 3);
+ if (NULL != optr) {
+ if (0 != optr->found) {
+ back = dk4opt_get_bool(rp, optr, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4aopt14.ctr b/support/dktools/dk4aopt14.ctr
new file mode 100644
index 0000000000..e06bc511e4
--- /dev/null
+++ b/support/dktools/dk4aopt14.ctr
@@ -0,0 +1,43 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4opt.h"
+#include "dk4aopt.h"
+
+
+
+int
+dk4app_opt_get_bool_long(
+ int *rp, dk4_app_t *app, const dkChar *n, dk4_er_t *erp
+)
+{
+ dk4_option_t *optr;
+ int back = 0;
+ if ((NULL != rp) && (NULL != app) && (NULL != n)) {
+ if (NULL != app->i_opt_long) {
+ optr = (dk4_option_t *)dk4sto_it_find_like(app->i_opt_long, n, 3);
+ if (NULL != optr) {
+ if (0 != optr->found) {
+ back = dk4opt_get_bool(rp, optr, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4aopt15.c b/support/dktools/dk4aopt15.c
new file mode 100644
index 0000000000..0f29ce15e9
--- /dev/null
+++ b/support/dktools/dk4aopt15.c
@@ -0,0 +1,94 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4aopt15.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4aopt15.c The dk4aopt15 module.
+*/
+
+
+#line 8 "dk4aopt15.ctr"
+
+#include "dk4opt.h"
+#include "dk4aopt.h"
+
+
+
+
+
+#line 15 "dk4aopt15.ctr"
+
+
+
+const dkChar *
+dk4app_opt_get_string_ptr_short(dk4_app_t *app, dkChar c, dk4_er_t *erp)
+{
+ const dkChar *back = NULL;
+ dk4_option_t *optr = NULL;
+
+
+#line 24 "dk4aopt15.ctr"
+ if (NULL != app) {
+ if (NULL != app->i_opt_short) {
+ optr = (dk4_option_t *)dk4sto_it_find_like(app->i_opt_short, &c, 1);
+ if (NULL != optr) {
+ if (0 != optr->found) {
+ switch ((optr->spec).argtype) {
+ case DK4_OPT_ARG_STRING : {
+ if (NULL != (optr->val).t) {
+ back = (optr->val).t;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } break;
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 53 "dk4aopt15.ctr"
+ return back;
+}
+
diff --git a/support/dktools/dk4aopt15.ctr b/support/dktools/dk4aopt15.ctr
new file mode 100644
index 0000000000..b01134d0e2
--- /dev/null
+++ b/support/dktools/dk4aopt15.ctr
@@ -0,0 +1,55 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+%% module
+
+#include "dk4opt.h"
+#include "dk4aopt.h"
+
+
+
+$!trace-include
+
+
+
+const dkChar *
+dk4app_opt_get_string_ptr_short(dk4_app_t *app, dkChar c, dk4_er_t *erp)
+{
+ const dkChar *back = NULL;
+ dk4_option_t *optr = NULL;
+ $? "+ dk4app_opt_get_string_ptr_short"
+ if (NULL != app) {
+ if (NULL != app->i_opt_short) {
+ optr = (dk4_option_t *)dk4sto_it_find_like(app->i_opt_short, &c, 1);
+ if (NULL != optr) {
+ if (0 != optr->found) {
+ switch ((optr->spec).argtype) {
+ case DK4_OPT_ARG_STRING : {
+ if (NULL != (optr->val).t) {
+ back = (optr->val).t;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } break;
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4app_opt_get_string_ptr_short PTR=%d", TR_IPTR(back)
+ return back;
+}
+
diff --git a/support/dktools/dk4aopt16.c b/support/dktools/dk4aopt16.c
new file mode 100644
index 0000000000..eae933ad09
--- /dev/null
+++ b/support/dktools/dk4aopt16.c
@@ -0,0 +1,95 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4aopt16.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4aopt16.c The dk4aopt16 module.
+*/
+
+
+#line 8 "dk4aopt16.ctr"
+
+#include "dk4opt.h"
+#include "dk4aopt.h"
+
+
+
+
+
+
+#line 16 "dk4aopt16.ctr"
+
+
+
+const dkChar *
+dk4app_opt_get_string_ptr_long(dk4_app_t *app, const dkChar *n, dk4_er_t *erp)
+{
+ const dkChar *back = NULL;
+ dk4_option_t *optr = NULL;
+
+
+#line 25 "dk4aopt16.ctr"
+ if ((NULL != app) && (NULL != n)) {
+ if (NULL != app->i_opt_short) {
+ optr = (dk4_option_t *)dk4sto_it_find_like(app->i_opt_short, n, 3);
+ if (NULL != optr) {
+ if (0 != optr->found) {
+ switch ((optr->spec).argtype) {
+ case DK4_OPT_ARG_STRING : {
+ if (NULL != (optr->val).t) {
+ back = (optr->val).t;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } break;
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 54 "dk4aopt16.ctr"
+ return back;
+}
+
diff --git a/support/dktools/dk4aopt16.ctr b/support/dktools/dk4aopt16.ctr
new file mode 100644
index 0000000000..353fc52bb7
--- /dev/null
+++ b/support/dktools/dk4aopt16.ctr
@@ -0,0 +1,56 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+%% module
+
+#include "dk4opt.h"
+#include "dk4aopt.h"
+
+
+
+
+$!trace-include
+
+
+
+const dkChar *
+dk4app_opt_get_string_ptr_long(dk4_app_t *app, const dkChar *n, dk4_er_t *erp)
+{
+ const dkChar *back = NULL;
+ dk4_option_t *optr = NULL;
+ $? "+ dk4app_opt_get_string_ptr_long"
+ if ((NULL != app) && (NULL != n)) {
+ if (NULL != app->i_opt_short) {
+ optr = (dk4_option_t *)dk4sto_it_find_like(app->i_opt_short, n, 3);
+ if (NULL != optr) {
+ if (0 != optr->found) {
+ switch ((optr->spec).argtype) {
+ case DK4_OPT_ARG_STRING : {
+ if (NULL != (optr->val).t) {
+ back = (optr->val).t;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } break;
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4app_opt_get_string_ptr_long PTR=%d", TR_IPTR(back)
+ return back;
+}
+
diff --git a/support/dktools/dk4app.h b/support/dktools/dk4app.h
new file mode 100644
index 0000000000..98d04c387d
--- /dev/null
+++ b/support/dktools/dk4app.h
@@ -0,0 +1,1351 @@
+/*
+Copyright (C) 2014, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4app.h Header file for the dk4app module.
+*/
+
+#ifndef DK4APP_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4APP_H_INCLUDED 1
+
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4CONST_H_INCLUDED
+#include "dk4const.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4OPT_H_INCLUDED
+#include "dk4opt.h"
+#endif
+
+#ifndef DK4STO_H_INCLUDED
+#include "dk4sto.h"
+#endif
+
+#ifndef DK4DIR_H_INCLUDED
+#include "dk4dir.h"
+#endif
+
+#ifndef DK4TIME_H_INCLUDED
+#include "dk4time.h"
+#endif
+
+/** Application structure.
+*/
+typedef struct {
+
+ /** Storage containing all options.
+ */
+ dk4_sto_t *s_opt_all;
+
+ /** Iterator for storage containing all options.
+ */
+ dk4_sto_it_t *i_opt_all;
+
+ /** Storage containing only short options.
+ */
+ dk4_sto_t *s_opt_short;
+
+ /** Iterator for storage containing short options.
+ */
+ dk4_sto_it_t *i_opt_short;
+
+ /** Storage containing only long options.
+ */
+ dk4_sto_t *s_opt_long;
+
+ /** Storage for self-set preferences.
+ */
+ dk4_sto_t *s_pref_self;
+
+ /** Storage for preferences on the command line.
+ */
+ dk4_sto_t *s_pref_cmd;
+
+ /** Storage for user preferences.
+ */
+ dk4_sto_t *s_pref_user;
+
+ /** Storage for system preferences.
+ */
+ dk4_sto_t *s_pref_sys;
+
+ /** Storage for string tables.
+ */
+ dk4_sto_t *s_stt;
+
+ /** Storage iterator for self-set preferences.
+ */
+ dk4_sto_it_t *i_pref_self;
+
+ /** Storage iterator for preferences on the command line.
+ */
+ dk4_sto_it_t *i_pref_cmd;
+
+ /** Storage iterator for user preferences.
+ */
+ dk4_sto_it_t *i_pref_user;
+
+ /** Storage iterator for system preferences.
+ */
+ dk4_sto_it_t *i_pref_sys;
+
+ /** Iterator for storage containing only long options.
+ */
+ dk4_sto_it_t *i_opt_long;
+
+ /** Iterator for string table storage.
+ */
+ dk4_sto_it_t *i_stt;
+
+ /** Message texts for the base log domain.
+ */
+ const dkChar * const *msg_base;
+
+ /** Message texts for debug logging.
+ */
+ const dkChar * const *msg_debug;
+
+ /** Help text shown if no help file found.
+ */
+ const dkChar * const *help_text;
+
+ /** License text.
+ */
+ const dkChar * const *lic_text;
+
+ /** Unprocessed command line arguments, my_argc below is the number.
+ */
+ dkChar **my_argv;
+
+ /** Text to show as version information.
+ */
+ dkChar *vers_text;
+
+ /** Help file name.
+ */
+ dkChar *help_file_name;
+
+ /** Users login name.
+ */
+ dkChar *user_name;
+
+ /** Users home directory.
+ */
+ dkChar *user_home;
+
+ /** Host name.
+ */
+ dkChar *host_name;
+
+ /** Users preferred language or NULL (dynamically allocated).
+ */
+ dkChar *language;
+
+ /** Users region or NULL (dynamically allocated).
+ */
+ dkChar *region;
+
+ /** Program name (dynamically allocated).
+ */
+ dkChar *prog_name;
+
+ /** Program group name (dynamically allocated).
+ */
+ dkChar *group_name;
+
+ /** Directory in which the executable file resides (dynamically allocated).
+ */
+ dkChar *dir_bin;
+
+ /** System configuration directory (dynamically allocated).
+ */
+ dkChar *dir_etc;
+
+ /** Data directory (dynamically allocated).
+ */
+ dkChar *dir_share;
+
+ /** Library directory (dynamically allocated).
+ */
+ dkChar *dir_lib;
+
+ /** Local state directory (dynamically allocated).
+ */
+ dkChar *dir_var;
+
+ /** Directory for temporary files.
+ */
+ dkChar *dir_tmp;
+
+ /** Log file name (dynamically allocated).
+ */
+ dkChar *log_file_name;
+
+ /** Current source file name, used in diagnostic messages.
+ */
+ const dkChar *source_file_name;
+
+ /** Current source line number, used in diagnostic messages.
+ */
+ dk4_um_t source_file_line;
+
+ /** Timestamp: Previous message to stderr.
+ */
+ dk4_time_t timer_stderr;
+
+ /** Timestamp: Previous message to file.
+ */
+ dk4_time_t timer_file;
+
+ /** Number of message texts for the base log domain.
+ */
+ size_t sz_msg_base;
+
+ /** Number of message texts for the debug log domain.
+ */
+ size_t sz_msg_debug;
+
+ /** Flag: Have timestamp in timer_stderr.
+ */
+ int have_stderr_time;
+
+ /** Flag: Have timestamp in timer_file.
+ */
+ int have_file_time;
+
+ /** Flag: The log file was already opened at least once.
+ */
+ int have_file_opened;
+
+ /** Flag: stderr was initialized for logging.
+ */
+ int have_stderr_init;
+
+ /** Number of unprocessed command line arguments.
+ */
+ int my_argc;
+
+ /** Required log level for stderr logging.
+ */
+ int ll_stderr;
+
+ /** Required log level for file logging.
+ */
+ int ll_file;
+
+ /** Log level required to keep the log file after closing the application.
+ */
+ int ll_file_keep;
+
+ /** Worst log level found so far.
+ */
+ int ll_found;
+
+ /** Flag: Write timestamp when logging to stderr.
+ */
+ int log_stderr_time;
+
+ /** Flag: Write timestamp when logging to file.
+ */
+ int log_file_time;
+
+ /** Flag: Logging possible at this time.
+ This flag is turned on after bringing up the application
+ completely and turned off before shutting down the application.
+ */
+ int log_enabled;
+
+ /** Encoding used in memory and for dk4fputs() and dk4fputc().
+ */
+ int encoding;
+
+ /** Expected encoding on standard input.
+ */
+ int enc_in_std;
+
+ /** Expected encoding on file input.
+ */
+ int enc_in_file;
+
+ /** Encoding to use when writing to standard output.
+ */
+ int enc_out_std;
+
+ /** Encoding to use when writing to file.
+ */
+ int enc_out_file;
+
+ /** Help, version or license.
+ */
+ int hvl_cmd;
+
+ /** Flag: Have self-set preferences to save.
+ */
+ int have_self_pref;
+
+ /** Flag: Fast application shutdown required due to signal.
+ */
+ int fast_close;
+
+ /** Flag: dir_tmp was used.
+ */
+ int tmp_dir_used;
+
+} dk4_app_t;
+
+
+
+/** Errors found during application startup.
+*/
+typedef struct {
+ /** Errors occured during opening the application.
+ */
+ int error_found;
+
+ /** Error with long option.
+ */
+ const dkChar *longopt;
+
+ /** Short option.
+ */
+ dkChar shortopt;
+} dk4_app_error_t;
+
+
+
+/** Command line options for help, version, and license.
+*/
+enum {
+ /** The --help option was used or there were
+ wrong options. Show help text.
+ */
+ DK4_APP_CMD_HELP = 1,
+
+ /** The --version option was used, show version.
+ */
+ DK4_APP_CMD_VERSION = 2,
+
+ /** The --license option was used, show license.
+ */
+ DK4_APP_CMD_LICENSE = 4,
+
+ /** Show full manual instead of short help text.
+ */
+ DK4_APP_CMD_MANUAL = 8,
+
+ /** Help text shown due to wrong options.
+ */
+ DK4_APP_CMD_ERROR = 16,
+
+};
+
+
+
+/** Preferences sources.
+*/
+enum {
+
+ DK4_APP_PREF_SRC_SYSTEM = 1, /**< System preferences. */
+
+ DK4_APP_PREF_SRC_USER = 2, /**< User preferences. */
+
+ DK4_APP_PREF_SRC_CMD = 4, /**< Preferences from command line. */
+
+ DK4_APP_PREF_SRC_SELF = 8 /**< Self-set preferences. */
+};
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open an application structure for a command line program.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @param optspec Option specification, may be NULL.
+ @param szoptspec Number of elements in optspec.
+ @param groupname Program group name.
+ @param version Version number string.
+ @param helpfile Help file name.
+ @param helptext Default help text.
+ @param lictext License conditions text.
+ @return Pointer to dk4_app_t structure on success, NULL on error.
+*/
+dk4_app_t *
+dk4app_open_cmd(
+ int argc,
+ dkChar **argv,
+ const dk4_option_specification_t *optspec,
+ size_t szoptspec,
+ const dkChar *groupname,
+ const dkChar *version,
+ const dkChar *helpfile,
+ const dkChar * const *helptext,
+ const dkChar * const *lictext
+);
+
+/** Open an application structure for a silent command line program.
+ No logging to stderr or log file.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @param optspec Option specification, may be NULL.
+ @param szoptspec Number of elements in optspec.
+ @param groupname Program group name.
+ @param version Version number string.
+ @param helpfile Help file name.
+ @param helptext Default help text.
+ @param lictext License conditions text.
+ @return Pointer to dk4_app_t structure on success, NULL on error.
+*/
+dk4_app_t *
+dk4app_open_silent(
+ int argc,
+ dkChar **argv,
+ const dk4_option_specification_t *optspec,
+ size_t szoptspec,
+ const dkChar *groupname,
+ const dkChar *version,
+ const dkChar *helpfile,
+ const dkChar * const *helptext,
+ const dkChar * const *lictext
+);
+
+/** Close an application structure.
+ @param app Application structure to close.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4app_close(dk4_app_t *app);
+
+/** Set flag for fast application shutdown.
+ @param app Application structure.
+*/
+void
+dk4app_set_fast_close(dk4_app_t *app);
+
+/** Check whether the application can run normally
+ (help, version, license not required).
+ CRT on Windows: Not used.
+ @param app Application to check.
+ @return 1 for normal run, 0 if dk4app_can_run_normally() should be run.
+*/
+int
+dk4app_can_run_normally(dk4_app_t *app);
+
+/** Respond to --help, --version, or --license.
+ CRT on Windows: Required.
+ @param app Application structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4app_help_version_license(dk4_app_t *app);
+
+/** Check whether or not to produce log output for a given log level.
+ CRT on Windows: Not used.
+ Disabling CRT use on Windows disables logging completely.
+ @param app Application to check.
+ @param ll Log level.
+ @return 1 if the log level requires processing, 0 otherwise.
+*/
+int
+dk4app_log_do(dk4_app_t *app, int ll);
+
+/** Log multi part message.
+ CRT on Windows: Optional,
+ disabling CRT use on Windows disables logging completely.
+ @param app Application structure, may be NULL.
+ @param priority Log priority.
+ @param msg Pointer to message parts array.
+ @param sz Number of message parts.
+*/
+void
+dk4app_log_msg(
+ dk4_app_t *app,
+ int priority,
+ const dkChar * const *msg,
+ size_t sz
+);
+
+/** Write log message from a log-domain-specific message text array.
+ CRT on Windows: Optional,
+ disabling CRT use on Windows disables logging completely.
+ @param app Application structure.
+ @param msg Pointer to array of message texts.
+ @param sz_msg Array size (number of elements).
+ @param priority Log priority.
+ @param msgind Index of text in array.
+*/
+void
+dk4app_log_1(
+ dk4_app_t *app,
+ const dkChar * const *msg,
+ size_t sz_msg,
+ int priority,
+ size_t msgind
+);
+
+/** Write log message from a log-domain-specific message text array.
+ CRT on Windows: Optional,
+ disabling CRT use on Windows disables logging completely.
+ @param app Application structure.
+ @param msg Pointer to array of message texts.
+ @param sz_msg Array size (number of elements).
+ @param priority Log priority.
+ @param i1 Index of text in array.
+ @param t1 Variable text surrounded by fixed texts.
+*/
+void
+dk4app_log_2(
+ dk4_app_t *app,
+ const dkChar * const *msg,
+ size_t sz_msg,
+ int priority,
+ size_t i1,
+ const dkChar *t1
+);
+
+/** Write log message from a log-domain-specific message text array.
+ CRT on Windows: Optional,
+ disabling CRT use on Windows disables logging completely.
+ @param app Application structure.
+ @param msg Pointer to array of message texts.
+ @param sz_msg Array size (number of elements).
+ @param priority Log priority.
+ @param i1 Index of text in array.
+ @param i2 Index of trailing fixed text.
+ @param t1 Variable text surrounded by fixed texts.
+*/
+void
+dk4app_log_3(
+ dk4_app_t *app,
+ const dkChar * const *msg,
+ size_t sz_msg,
+ int priority,
+ size_t i1,
+ size_t i2,
+ const dkChar *t1
+);
+
+/** Write log message from a log-domain-specific message text array.
+ CRT on Windows: Optional,
+ disabling CRT use on Windows disables logging completely.
+ @param app Application structure.
+ @param msg Pointer to array of message texts.
+ @param sz_msg Array size (number of elements).
+ @param priority Log priority.
+ @param i1 Index of text in array.
+ @param i2 Index of second fixed text.
+ @param i3 Index of third fixed text.
+ @param t1 First variable text.
+ @param t2 Second variable text.
+*/
+void
+dk4app_log_5(
+ dk4_app_t *app,
+ const dkChar * const *msg,
+ size_t sz_msg,
+ int priority,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ const dkChar *t1,
+ const dkChar *t2
+);
+
+/** Write log message from a log-domain-specific message text array.
+ CRT on Windows: Optional,
+ disabling CRT use on Windows disables logging completely.
+ @param app Application structure.
+ @param msg Pointer to array of message texts.
+ @param sz_msg Array size (number of elements).
+ @param priority Log priority.
+ @param i1 Index of text in array.
+ @param i2 Index of second fixed text.
+ @param i3 Index of third fixed text.
+ @param i4 Index of fourth fixed text.
+ @param t1 First variable text.
+ @param t2 Second variable text.
+ @param t3 Third variable text.
+*/
+void
+dk4app_log_7(
+ dk4_app_t *app,
+ const dkChar * const *msg,
+ size_t sz_msg,
+ int priority,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ size_t i4,
+ const dkChar *t1,
+ const dkChar *t2,
+ const dkChar *t3
+);
+
+/** Write a one string log message.
+ CRT on Windows: Optional,
+ disabling CRT use on Windows disables logging completely.
+ @param app Application structure, may be NULL.
+ @param priority Priority (ie DK4_LL_ERROR).
+ @param msgind Index of message text within the domain.
+*/
+void
+dk4app_log_base1(
+ dk4_app_t *app,
+ int priority,
+ size_t msgind
+);
+
+/** Write a two string log message (one constant and one variable part).
+ CRT on Windows: Optional,
+ disabling CRT use on Windows disables logging completely.
+ @param app Application structure, may be NULL.
+ @param priority Priority (ie DK4_LL_ERROR).
+ @param i1 Index of message text within the domain.
+ @param t1 First variable text.
+*/
+void
+dk4app_log_base2(
+ dk4_app_t *app,
+ int priority,
+ size_t i1,
+ const dkChar *t1
+);
+
+/** Write a two string log message (two constant parts).
+ CRT on Windows: Optional,
+ disabling CRT use on Windows disables logging completely.
+ @param app Application structure, may be NULL.
+ @param priority Priority (ie DK4_LL_ERROR).
+ @param i1 Index of message text within the domain.
+ @param i2 Second texts index.
+*/
+void
+dk4app_log_base2c(
+ dk4_app_t *app,
+ int priority,
+ size_t i1,
+ size_t i2
+);
+
+/** Write a three string log message.
+ CRT on Windows: Optional,
+ disabling CRT use on Windows disables logging completely.
+ @param app Application structure, may be NULL.
+ @param priority Priority (ie DK4_LL_ERROR).
+ @param i1 Index of message text within the domain.
+ @param i2 Index of second fixed text.
+ @param t1 First variable text.
+*/
+void
+dk4app_log_base3(
+ dk4_app_t *app,
+ int priority,
+ size_t i1,
+ size_t i2,
+ const dkChar *t1
+);
+
+/** Write a one string log message.
+ CRT on Windows: Optional,
+ disabling CRT use on Windows disables logging completely.
+ @param app Application structure, may be NULL.
+ @param priority Priority (ie DK4_LL_ERROR).
+ @param i1 Index of message text within the domain.
+ @param i2 Index of second fixed text.
+ @param i3 Index of third fixed text.
+ @param t1 First variable text.
+ @param t2 Second variable text.
+*/
+void
+dk4app_log_base5(
+ dk4_app_t *app,
+ int priority,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ const dkChar *t1,
+ const dkChar *t2
+);
+
+/** Write a one string log message.
+ CRT on Windows: Optional,
+ disabling CRT use on Windows disables logging completely.
+ @param app Application structure, may be NULL.
+ @param priority Priority (ie DK4_LL_ERROR).
+ @param i1 Index of message text within the domain.
+ @param i2 Index of second fixed text.
+ @param i3 Index of third fixed text.
+ @param i4 Index of fourth fixed text.
+ @param t1 First variable text.
+ @param t2 Second variable text.
+ @param t3 Third variable text.
+*/
+void
+dk4app_log_base7(
+ dk4_app_t *app,
+ int priority,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ size_t i4,
+ const dkChar *t1,
+ const dkChar *t2,
+ const dkChar *t3
+);
+
+/** Log a message, attempt to print errno value.
+ CRT on Windows: Optional,
+ disabling CRT use on Windows disables logging completely.
+ @param app Application structure, may be NULL.
+ @param priority Priority (ie DK4_LL_ERROR).
+ @param i1 Index of fixed text 1 with errno.
+ @param i2 Index of fixed text 2 with errno.
+ @param i3 Index of fixed text 3 with errno.
+ @param i4 Index of fixed text 1 without errno.
+ @param i5 Index of fixed text 2 without errno.
+ @param t1 Variable text.
+ @param errn Value from errno.
+*/
+void
+dk4app_log_with_errno(
+ dk4_app_t *app,
+ int priority,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ size_t i4,
+ size_t i5,
+ const dkChar *t1,
+ int errn
+);
+
+/** Apply a preference.
+ @param app Application structure to set up.
+ @param ae Application open error structure.
+ @param pn Preference name.
+ @param pv Preference value.
+*/
+void
+dk4app_pref_apply(
+ dk4_app_t *app,
+ dk4_app_error_t *ae,
+ const dkChar *pn,
+ const dkChar *pv
+);
+
+/** Retrieve preference value.
+ @param dptr Destionation buffer.
+ @param szdptr Size of destination buffer (number of dkChar).
+ @param app Application structure.
+ @param name Preference name.
+ @param excl Sources to exclude.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4app_pref_get(
+ dkChar *dptr,
+ size_t szdptr,
+ dk4_app_t *app,
+ const dkChar *name,
+ int excl
+);
+
+/** Retrieve integer value from preferences.
+ @param dptr Destination pointer (address of result variable).
+ @param app Application structure.
+ @param name Preference name.
+ @param excl Preference sources to exclude.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4app_pref_get_int(
+ dk4_im_t *dptr,
+ dk4_app_t *app,
+ const dkChar *name,
+ int excl
+);
+
+/** Retrieve unsigned integer value from preferences.
+ @param dptr Destination pointer (address of result variable).
+ @param app Application structure.
+ @param name Preference name.
+ @param excl Preference sources to exclude.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4app_pref_get_unsigned(
+ dk4_um_t *dptr,
+ dk4_app_t *app,
+ const dkChar *name,
+ int excl
+);
+
+/** Retrieve boolean value from preferences.
+ @param dptr Destination pointer (address of result variable).
+ @param app Application structure.
+ @param name Preference name.
+ @param excl Preference sources to exclude.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4app_pref_get_bool(
+ int *dptr,
+ dk4_app_t *app,
+ const dkChar *name,
+ int excl
+);
+
+/** Retrieve size_t value from preferences.
+ @param dptr Destination pointer (address of result variable).
+ @param app Application structure.
+ @param name Preference name.
+ @param excl Preference sources to exclude.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4app_pref_get_size(
+ size_t *dptr,
+ dk4_app_t *app,
+ const dkChar *name,
+ int excl
+);
+
+/** Set one preference value.
+ @param app Application structure.
+ @param name Preference name.
+ @param value Preference value.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4app_pref_set(
+ dk4_app_t *app,
+ const dkChar *name,
+ const dkChar *value
+);
+
+/** Save integer value to preference.
+ @param app Application structure.
+ @param name Preference name.
+ @param value Value to save.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4app_pref_set_int(dk4_app_t *app, const dkChar *name, dk4_im_t value);
+
+/** Save unsigned integer value to preference.
+ @param app Application structure.
+ @param name Preference name.
+ @param value Value to save.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4app_pref_set_unsigned(dk4_app_t *app, const dkChar *name, dk4_um_t value);
+
+/** Search for one configuration file.
+ @param dptr Destination file name buffer.
+ @param szdptr Size of dptr (number of dkChar).
+ @param app Application structure.
+ @param shortname Short file name (without leading directory).
+ @param passno Pass number (0 to DK4_FS_CONF_SYS_MAX).
+ @param compressed Flag: Allow compressed file versions.
+ @param erp Error report, may be NULL.
+ @return 1 on success (file found), 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or shortname is NULL or szdptr is 0 or passno is an invalid
+ number or one of the used strings (dir_share, dir_etc, dir_home,
+ name_prog, or name_group) is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the dptr buffer is too small,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow happened during a size calculation,
+ - DK4_E_SYSTEM<br>
+ with iDetails1 set to errno if stat() fails.
+*/
+int
+dk4app_search_one_config_file(
+ dkChar *dptr,
+ size_t szdptr,
+ dk4_app_t *app,
+ const dkChar *shortname,
+ int passno,
+ int compressed,
+ dk4_er_t *erp
+);
+
+/** Search for one data file.
+ @param dptr Destination file name buffer.
+ @param szdptr Size of dptr (number of dkChar).
+ @param app Application structure.
+ @param shortname Short file name (without leading directory).
+ @param passno Pass number (0 to DK4_FS_DATA_MAX).
+ @param compressed Flag: Allow compressed file versions.
+ @param erp Error report, may be NULL.
+ @return 1 on success (file found), 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or shortname is NULL or szdptr is 0 or passno is an invalid
+ number or one of the used strings (dir_share, dir_etc, dir_home,
+ name_prog, or name_group) is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the dptr buffer is too small,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow happened during a size calculation,
+ - DK4_E_SYSTEM<br>
+ with iDetails1 set to errno if stat() fails.
+*/
+int
+dk4app_search_one_data_file(
+ dkChar *dptr,
+ size_t szdptr,
+ dk4_app_t *app,
+ const dkChar *shortname,
+ int passno,
+ int compressed,
+ dk4_er_t *erp
+);
+
+/** Search for configuration file.
+ @param dptr Destination file name buffer.
+ @param szdptr Size of dptr (number of dkChar).
+ @param app Application structure.
+ @param shortname Short file name (without leading directory).
+ @param maxpass Maximum pass number.
+ @param compressed Flag: Allow compressed file versions.
+ @param erp Error report, may be NULL.
+ @return 1 on success (file found), 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or shortname is NULL or szdptr is 0 or passno is an invalid
+ number or one of the used strings (dir_share, dir_etc, dir_home,
+ name_prog, or name_group) is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the dptr buffer is too small,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow happened during a size calculation,
+ - DK4_E_SYSTEM<br>
+ with iDetails1 set to errno if stat() fails.
+*/
+int
+dk4app_search_config_file(
+ dkChar *dptr,
+ size_t szdptr,
+ dk4_app_t *app,
+ const dkChar *shortname,
+ int maxpass,
+ int compressed,
+ dk4_er_t *erp
+);
+
+/** Search for data file.
+ @param dptr Destination file name buffer.
+ @param szdptr Size of dptr (number of dkChar).
+ @param app Application structure.
+ @param shortname Short file name (without leading directory).
+ @param maxpass Pass number (0 to DK4_FS_DATA_MAX).
+ @param compressed Flag: Allow compressed file versions.
+ @param erp Error report, may be NULL.
+ @return 1 on success (file found), 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or shortname is NULL or szdptr is 0 or passno is an invalid
+ number or one of the used strings (dir_share, dir_etc, dir_home,
+ name_prog, or name_group) is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the dptr buffer is too small,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow happened during a size calculation,
+ - DK4_E_SYSTEM<br>
+ with iDetails1 set to errno if stat() fails.
+*/
+int
+dk4app_search_data_file(
+ dkChar *dptr,
+ size_t szdptr,
+ dk4_app_t *app,
+ const dkChar *shortname,
+ int maxpass,
+ int compressed,
+ dk4_er_t *erp
+);
+
+/** Find text array size.
+ @param texts Array of texts, NULL pointer used as finalizer.
+ @return Number of array elements without NULL finalizer.
+*/
+size_t
+dk4app_string_table_size(const dkChar * const *texts);
+
+/** Read text array from string table.
+ @param app Application structure.
+ @param shortname Short file name (without leading directory).
+ @param deftexts Default texts (used if no file found or file
+ unusable.
+ @return Pointer to array of texts, either obtained from file
+ or the default texts.
+*/
+const dkChar * const *
+dk4app_string_table(
+ dk4_app_t *app,
+ const dkChar *shortname,
+ const dkChar * const *deftexts
+);
+
+/** Retrieve internal encoding.
+ @param app Application structure.
+ @return Encoding used in memory and by the dk4fputs() and
+ dk4fputc() functions.
+*/
+int
+dk4app_get_encoding(dk4_app_t *app);
+
+/** Retrieve encoding expected on stdin.
+ @param app Application structure.
+ @return Encoding expected on stdin.
+*/
+int
+dk4app_get_stdin_encoding(dk4_app_t *app);
+
+/** Retrieve encoding expected when reading files.
+ @param app Application structure.
+ @return Encoding expected when reading files.
+*/
+int
+dk4app_get_file_in_encoding(dk4_app_t *app);
+
+/** Retrieve encoding to use on stdout.
+ @param app Application structure.
+ @return Encoding to use when writing to stdout.
+*/
+int
+dk4app_get_stdout_encoding(dk4_app_t *app);
+
+/** Retrieve encoding to use when writing to files.
+ @param app Application structure.
+ @return Encoding to use when writing to files.
+*/
+int
+dk4app_get_file_out_encoding(dk4_app_t *app);
+
+/** Retrieve number of command line arguments.
+ @param app Application structure.
+ @return Number of command line arguments (program name not included).
+*/
+int
+dk4app_get_argc(dk4_app_t *app);
+
+/** Retrieve n-th command line argument.
+ @param app Application structure.
+ @param n Index of command line argument (0 for the first
+ argument after program name).
+ @return Pointer to command line argument on succes,
+ NULL on error.
+*/
+const dkChar *
+dk4app_get_argv(dk4_app_t *app, int n);
+
+/** Remove file.
+ CRT on Windows: Optional,
+ disabling CRT use on Windows disables logging completely.
+ @param fn File name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4app_del_file(const dkChar *fn, dk4_app_t *app);
+
+/** Report problems from deleting a file.
+ CRT on Windows: Optional,
+ disabling CRT use on Windows disables logging completely.
+ @param fn File name.
+ @param erp Error report, filled by dk4delete_file().
+ @param app Application structure for diagnostics, may be NULL.
+*/
+void
+dk4app_del_file_report(const dkChar *fn, const dk4_er_t *erp, dk4_app_t *app);
+
+/** Remove empty directory.
+ @param fn File name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4app_del_dir(const dkChar *fn, dk4_app_t *app);
+
+/** Report problems from deleting a directory.
+ CRT on Windows: Optional,
+ disabling CRT use on Windows disables logging completely.
+ @param fn File name.
+ @param erp Error report, filled by dk4delete_directory().
+ @param app Application structure for diagnostics, may be NULL.
+*/
+void
+dk4app_del_dir_report(const dkChar *fn, const dk4_er_t *erp, dk4_app_t *app);
+
+/** Remove directory with all contents.
+ CRT on Windows: Optional,
+ disabling CRT use on Windows disables logging completely.
+ @param fn File name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4app_del_tree(const dkChar *fn, dk4_app_t *app);
+
+/** Open file name expander for pattern.
+ @param pattern Pattern to match.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new file name expander on success, NULL on error.
+*/
+dk4_dir_t *
+dk4app_fne_open(const dkChar *pattern, dk4_app_t *app);
+
+/** Retrieve exactly one file name from file name expander.
+ @param dptr Buffer for file name.
+ @param szdptr Size of dptr (number of dkChar).
+ @param fne File name expander.
+ @param pattern Pattern for file name expander.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4app_fne_one_file(
+ dkChar *dptr,
+ size_t szdptr,
+ dk4_dir_t *fne,
+ const dkChar *pattern,
+ dk4_app_t *app
+);
+
+/** Retrieve preference value.
+ CRT on Windows: Optional.
+ @param dptr Result buffer address.
+ @param szdptr Buffer size (number of dkChar).
+ @param app Application structure.
+ @param name Preference name.
+ @param excl Preference sources to exclude, one
+ from DK4_APP_PREF_SRC_SELF,
+ DK4_APP_PREF_SRC_CMD,
+ DK4_APP_PREF_SRC_USER,
+ DK4_APP_PREF_SRC_SYSTEM
+ or bitwise or-combination.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4app_pref_get(
+ dkChar *dptr,
+ size_t szdptr,
+ dk4_app_t *app,
+ const dkChar *name,
+ int excl
+);
+
+/** Retrieve integer value from preferences.
+ CRT on Windows: Optional.
+ @param dptr Pointer to result variable.
+ @param app Application structure.
+ @param name Preference name.
+ @param excl Preference sources to exclude, one
+ from DK4_APP_PREF_SRC_SELF,
+ DK4_APP_PREF_SRC_CMD,
+ DK4_APP_PREF_SRC_USER,
+ DK4_APP_PREF_SRC_SYSTEM
+ or bitwise or-combination.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4app_pref_get_int(
+ dk4_im_t *dptr,
+ dk4_app_t *app,
+ const dkChar *name,
+ int excl
+);
+
+/** Retrieve unsigned integer value from preferences.
+ CRT on Windows: Optional.
+ @param dptr Pointer to result variable.
+ @param app Application structure.
+ @param name Preference name.
+ @param excl Preference sources to exclude, one
+ from DK4_APP_PREF_SRC_SELF,
+ DK4_APP_PREF_SRC_CMD,
+ DK4_APP_PREF_SRC_USER,
+ DK4_APP_PREF_SRC_SYSTEM
+ or bitwise or-combination.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4app_pref_get_unsigned(
+ dk4_um_t *dptr,
+ dk4_app_t *app,
+ const dkChar *name,
+ int excl
+);
+
+/** Retrieve boolean value from preferences.
+ CRT on Windows: Optional.
+ @param dptr Pointer to result variable.
+ @param app Application structure.
+ @param name Preference name.
+ @param excl Preference sources to exclude, one
+ from DK4_APP_PREF_SRC_SELF,
+ DK4_APP_PREF_SRC_CMD,
+ DK4_APP_PREF_SRC_USER,
+ DK4_APP_PREF_SRC_SYSTEM
+ or bitwise or-combination.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4app_pref_get_bool(
+ int *dptr,
+ dk4_app_t *app,
+ const dkChar *name,
+ int excl
+);
+
+/** Retrieve size value from preferences.
+ CRT on Windows: Optional.
+ @param dptr Pointer to result variable.
+ @param app Application structure.
+ @param name Preference name.
+ @param excl Preference sources to exclude, one
+ from DK4_APP_PREF_SRC_SELF,
+ DK4_APP_PREF_SRC_CMD,
+ DK4_APP_PREF_SRC_USER,
+ DK4_APP_PREF_SRC_SYSTEM
+ or bitwise or-combination.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4app_pref_get_size(
+ size_t *dptr,
+ dk4_app_t *app,
+ const dkChar *name,
+ int excl
+);
+
+/** Set preferences value.
+ CRT on Windows: Optional.
+ @param app Application structure.
+ @param name Preference name.
+ @param value Preference value.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4app_pref_set(
+ dk4_app_t *app,
+ const dkChar *name,
+ const dkChar *value
+);
+
+/** Set preferences integer value.
+ CRT on Windows: Optional.
+ @param app Application structure.
+ @param name Preference name.
+ @param value Preference value.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4app_pref_set_int(dk4_app_t *app, const dkChar *name, dk4_im_t value);
+
+/** Set preferences unsigned integer value.
+ CRT on Windows: Optional.
+ @param app Application structure.
+ @param name Preference name.
+ @param value Preference value.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4app_pref_set_unsigned(dk4_app_t *app, const dkChar *name, dk4_um_t value);
+
+/** Retrieve source file name.
+ @param app Application structure.
+ @return Source file name if defined, NULL otherwise.
+*/
+const dkChar *
+dk4app_get_log_source_file(dk4_app_t *app);
+
+/** Retrieve source line number.
+ @param app Application structure.
+ @return Source line number if defined, 0 otherwise.
+*/
+dk4_um_t
+dk4app_get_log_source_line(dk4_app_t *app);
+
+/** Set source file name, reported in diagnostic messages.
+ The structure does not keep a private copy of the name,
+ it just stores the pointer provided. Make sure not to modify
+ the file name afterwards.
+ @param app Application structure.
+ @param fn File name, may be NULL.
+*/
+void
+dk4app_set_log_source_file(dk4_app_t *app, const dkChar *fn);
+
+/** Set source line number, reported in diagnostic messages.
+ @param app Application structure.
+ @param lineno Line number, may be 0.
+*/
+void
+dk4app_set_log_source_line(dk4_app_t *app, dk4_um_t lineno);
+
+/** Retrieve localized texts for debug messages.
+ @param app Application structure.
+ @param szptr Address of variable to store array size,
+ may be NULL.
+ @return Pointer to localized texts on success, non-localized
+ texts on error.
+*/
+const dkChar * const *
+dk4app_log_debug_texts(dk4_app_t *app, size_t *szptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4app/de/dk4base.str b/support/dktools/dk4app/de/dk4base.str
new file mode 100644
index 0000000000..e7bfd58dda
--- /dev/null
+++ b/support/dktools/dk4app/de/dk4base.str
@@ -0,0 +1,444 @@
+#
+# 0 Log level: Never reached.
+#
+NONE
+#
+# 1 Log level: Panic - Should shut down computer
+#
+Panik
+#
+# 2 Log level: Fatal error - Should abort program
+#
+Fatal
+#
+# 3 Log level: Error
+#
+Fehler
+#
+# 4 Log level: Warning
+#
+Warnung
+#
+# 5 Log level: Information
+#
+Info
+#
+# 6 Log level: Progress message
+#
+Fortschritt
+#
+# 7 Log level: Debug message
+#
+Debug
+#
+# 8 Log level: Ignore message, do not write text
+#
+Ignore
+#
+# 9 10 ERROR: Illegal option!
+#
+Unzulässige Option: "
+"!
+#
+# 11 12 ERROR: Option requires argument!
+#
+Option "
+" erfordert ein Argument!
+#
+# 13 14 15 ERROR: Option requires boolean argument...
+#
+Option "
+" Erfordert ein Boolean-Argument!\n\tNicht verwertbarer Text: "
+"!
+#
+# 16 17 18 ERROR: Option requires size argument...
+#
+Option "
+" erfordert eine Größe als Argument!\n\tNicht verwertbarer Text: "
+"!
+#
+# 19 20 21 ERROR: Option requires integer argument...
+#
+Option "
+" erfordert ein Ganzzahl-Argument!\n\tNicht verwertbarer Text: "
+"!
+#
+# 22 23 24 ERROR: Option requires unsigned integer argument...
+#
+Option "
+" erfordert ein nichtnegatives Ganzzahl-Argument!\n\tNicht verwertbarer Text: "
+"!
+#
+# 25 26 27 ERROR: Option requires double argument...
+#
+Option "
+" erfordert Gleitkommazahl-Argument!\n\tNicht verwertbarer Text: "
+"!
+#
+# 28 ERROR: Long option requires argument
+#
+Option "--
+#
+# 29 ERROR: Long option requires double argument
+#
+Option "--
+#
+# 30 ERROR: Long option requires unsigned integer argument
+#
+Option "--
+#
+# 31 ERROR: Long option requires integer argument
+#
+Option "--
+#
+# 32 ERROR: Long option requires size specification
+#
+Option "--
+#
+# 33 ERROR: Long option requires boolean argument
+#
+Option "--
+#
+# 34 35 36 ERROR: Failed to save preference value
+#
+Einstellung konnte nicht gespeichert werden:\n\t"
+"="
+"!
+#
+# 37 38 ERROR: Value required for preference.
+#
+Kommandozeilen-Präferenz "
+" erfordert Wertangabe!
+#
+# 39 40 ERROR: Option too long
+#
+Option zu lang:\n\t"
+"!
+#
+# 41
+#
+Datei konnte nicht gelöscht werden:\n\t"
+#
+# 42 Reason for error
+#
+"!\n\tPfad zu lang.
+#
+# 43 44 45
+#
+Verzeichnis konnte nicht angelegt werden:\n\t"
+"!\n\tPfad existiert bereits, ist aber kein Verzeichnis!
+_UNUSED_
+#
+# 46 47
+#
+Verzeichnis konnte nicht angelegt werden:\n\t"
+"!\n\tUnzulässiger Pfad.
+#
+# 48 Reason for error
+#
+"!\n\tDatei oder Verzeichnis wird zur Zeit benutzt.
+#
+# 49 Reason for error
+#
+"!\n\tDer Pfad existiert bereits.
+#
+# 50 Reason for error
+#
+"!\n\tDer Pfad zeigt nach außerhalb des adressierbaren Bereiches.
+#
+# 51 Reason for error.
+#
+"!\n\tPfad nicht gefunden (eine Pfad-Komponente existiert nicht).
+#
+# 52 Reason for error
+#
+"!\n\tDer Pfad verweist auf ein Verzeichnis.
+#
+# 53 Reason for error
+#
+"!\n\tKeine Funktion zum Verzeichnis-Anlegen verfügbar für wchar_t-Namen.
+#
+# 54 55
+#
+Keine Funktion zum Löschen von Dateien für wchar_t verfügbar.
+"!\n\tBerechtigungen reichen nicht aus.
+#
+# 56 57
+#
+"!\n\tDas Dateisystem ist nur zum Lesen verfügbar.
+"!\n\tKonflikt mit erweiterten Attributen.
+#
+# 58 59
+#
+"!\n\tOperation für diesen Dateisystem-Typ nicht erlaubt.
+"!\n\tEin-/Ausgabefehler am Gerät.
+#
+# 60 61
+#
+"!\n\tZu wenig Festplattenplatz verfügbar bzw. Quota erreicht.
+"!\n\tZu viele symbolische Links im Pfad (evtl. Symlink-Schleife).
+#
+# 62 63
+#
+"!\n\tZu wenig Kernel-RAM.
+"!\n\tZu viele Einträge im Eltern-Verzeichnis.
+#
+# 64 65
+#
+"!\n\tFile-Server ist nicht verfügbar.
+"!\n\tDer Name ist zu lang.
+#
+# 66 67
+#
+Verzeichnis konnte nicht gelöscht werden:\n\t"
+"!\n\tDas Verzeichnis ist nicht leer.
+#
+# 68 69
+#
+"!\n\tInvalid path name.
+"!\n\tWindows error code:
+#
+# 70 71
+#
+ (0x
+).
+#
+# 72 73
+#
+"!
+"!\n\tEltern-Verzeichnis nicht gefunden (Gerät oder Server-Freigabe)!
+#
+# 74 75
+#
+"!\n\tNetzwerk-Resourcen-Name fehlerhaft (Freigabe-Name)!
+"!\n\tNetzwerk-Resourcen-Name fehlerhaft (Server-Name)!
+#
+# 76 77
+#
+_UNUSED_
+"!
+#
+# 78 79 80
+#
+_UNUSED_
+"!\n\tFehler-Code:
+.
+#
+# 81
+#
+Die Optionen --help, --version, und --license schließen sich gegenseitig aus!
+#
+# 82 83 84 85
+#
+Zahlenbereichs-Überlauf in Größenberechnung!
+Zahlenbereichs-Überlauf in Größenberechnung!\n\t
+ Elemente mit jeweils
+ Bytes.
+#
+# 86 87 88 89
+#
+Speicheranforderung fehlgeschlagen! Fehlerhafte Größe(n).
+Speicheranforderung fehlgeschlagen! Fehlerhafte Größe(n).\n\tElemente:
+, Element-Größe:
+.
+#
+# 90 91 92 93
+#
+Zu wenig Hauptspeicher!
+Zu wenig Hauptspeicher! Anforderung fehlgeschlagen.\n\tElemente:
+, Element-Größe:
+.
+#
+# 94 95
+#
+Weitere Löschungen von Dateien fehlgeschlagen in Verzeichnis:\n\t"
+"!
+#
+# 96 97
+#
+Weitere Löschungen von Unterverzeichnissen fehlgeschlagen in Verzeichnis:\n\t"
+"!
+#
+# 98 99
+#
+Datei- oder Verzeichnisname zu lang:\n\t"
+"!
+#
+# 100 101 102 103 104 105 106 107
+#
+Dateiname konnte nicht expandiert werden:\n\t"
+"!
+"!\n\tKeine Funktion zum Durchsuchen von Verzeichnissen vorhanden!
+"!\n\tSpeicheranforderung fehlgeschlagen!
+"!\n\tVerzeichnis konnte nicht zum Durchsuchen geöffnet werden!
+"!\n\tVerzeichnis- oder Dateiname zu lang!
+"!\n\tMehrere passende Dateien gefunden!
+"!\n\tKeine passende Datei gefunden!
+#
+# 108 ERROR: Failed to open file...
+#
+Datei konnte nicht geöffnet werden:\n\t"
+#
+# 109 110 111 112 113 114 115 116 117 Error: Not a regular file
+#
+"!\n\tKeine reguläre Datei!
+"!\n\tPfad enthält symbolische Links!
+"!\n\tPfad ist ein symbolischer Link!
+"!\n\tEigentümer unterschiedlich für symbolischen Link und Link-Ziel!
+"!\n\tSignal erhalten!
+"!\n\tZu viele offene Dateien im Prozess!
+"!\n\tZu viele offene Dateien im System!
+"!\n\tGerät für special file existiert nicht!
+"!\n\tDateigröße zu groß für off_t-Datentyp!
+#
+# 118 119 120 Read operation failed
+#
+Lesen fehlgeschlagen!
+Lesen fehlgeschlagen, Fehlercode:
+.
+#
+# 121 EAGAIN / EWOULDBLOCK
+#
+\n\tOperation würde blockieren!
+#
+# 122 EBADF
+#
+\n\tUngeeigneter File-Deskriptor (Bug)!
+#
+# 123 EFAULT
+#
+\n\tPuffer ist nicht adressierbar (Bug)!
+#
+# 124 EINTR
+#
+\n\tSignal empfangen!
+#
+# 125 EINVAL
+#
+\n\tFile-Deskriptor ist mit ungeeignetem Objekt verbunden (Bug)!
+#
+# 126 EIO
+#
+\n\tI/O-Fehler!
+#
+# 127 EISDIR
+#
+\n\tFile-Deskriptor ist mit Verzeichnis verbunden (Bug)!
+#
+# 128 - 130 Error: Write operation failed
+#
+Schreiben fehlgeschlagen!
+Schreiben fehlgeschlagen, Fehlercode:
+.
+#
+# 131 ENOSPC
+#
+\n\tKein Platz mehr verfügbar!
+#
+# 132 EFBIG
+#
+\n\tDateigröße würde Limit überschreiten!
+#
+# 133 EPIPE
+#
+\n\tVon Pipe oder Socket wird nicht gelesen!
+#
+# 134 ECONNRESET
+#
+\n\tSocket nicht verbunden!
+#
+# 135 ERANGE
+#
+\n\tPuffergröße liegt nicht im vorgesehenen Bereich!
+#
+# 136 ENOBUFS
+#
+\n\tSystemresourcen nicht ausreichend!
+#
+# 137 ENXIO
+#
+\n\tGerät nicht vorhanden oder nicht benutzbar!
+#
+# 138 EACCES
+#
+\n\tBerechtigungen reichen nicht aus!
+#
+# 139 EBADMSG
+#
+\n\tUnerwarteter Steuer-Text in Daten!
+#
+# 140 ECONNRESET
+#
+\n\tVerbindung wurde durch Gegenstelle beendet!
+#
+# 141 ETIMEDOUT
+#
+\n\tTime-Out!
+#
+# 142 ENOMEM
+#
+\n\tNicht ausreichend Hauptspeicher verfügbar!
+#
+# 143 ESPIPE
+#
+\n\tFile-Deskriptor ist Socket bzw. FIFO!
+#
+# 144 Failed to open directory!
+#
+Verzeichnis konnte nicht geöffnet werden:\n\t"
+#
+# 145 146 147 148 DK4_E_NOT_SUPPORTED
+#
+"!\n\tKeine Funktion zum Durchsuchen von Verzeichnissen vorhanden!
+"!\n\tZahlenbereichsüberlauf in Größenberechnung!
+"!\n\tPfad nicht gefunden!
+"!\n\tVerzeichnis existiert nicht!
+#
+# 149 Failed to obtain information about file or directory
+#
+Keine Informationen über Datei/Verzeichnis gefunden:\n\t"
+#
+# 150 ENOTDIR
+#
+"!\n\tEine Pfad-Komponente ist kein Verzeichnis.
+#
+# 151 ERROR_SHARING_VIOLATION
+#
+"!\n\tWird momentan durch anderen Prozess benutzt.
+#
+# 152 153 ERROR: Not a directory
+#
+Kein Verzeichnis:\n\t"
+"!
+#
+# 154 Error text ... in ...
+#
+" in "
+#
+# 155 156 157 158
+#
+Setzen eines Datei-Puffers fehlgeschlagen!
+Der Datei-Puffer konnte nicht gesetzt werden für\n"
+"!
+Weder setvbuf()- noch setbuffer()-Funktion verfügbar!
+#
+# 159
+#
+Syntax-Fehler, erwartete Zeile:\n"Name = Breite Höhe [Rand-Links Rand-Rechts Rand-Oben Rand-Unten]"
+#
+#
+#
+Präferenz gefunden: "
+"="
+".
+#
+#
+#
+Präferenz-Wert zu lang: "
+"="
+"!
+#
+# 166 167
+#
+Präferenz nicht gefunden: "
+"!
diff --git a/support/dktools/dk4app/de/dk4debug.str b/support/dktools/dk4app/de/dk4debug.str
new file mode 100644
index 0000000000..693c2cd7af
--- /dev/null
+++ b/support/dktools/dk4app/de/dk4debug.str
@@ -0,0 +1,89 @@
+#
+# 0 ... 20 Log texts to show at startup
+#
+Host-Name:
+Nutzer-Name:
+Home-Verzeichnis:
+Sprache:
+Region:
+Encoding:
+Erwartetes Encoding für Standardeingabe:
+Erwartetes Encoding für Dateien:
+Programm-Name:
+Programm-Gruppe:
+Directory etc:
+Directory bin:
+Directory share:
+Directory lib:
+Directory var:
+Directory tmp:
+Logging erlaubt:
+Log-Datei:
+Log-Level für Logging auf Standardfehlerausgabe:
+Log-Level für Logging in Datei:
+Log-Level um Log-Datei aufzuheben:
+#
+# 21 22 23 24 Debug messages for file search
+#
+Suche nach Resourcen-Datei "
+" fehlgeschlagen.
+" erfolgreich.\n\t
+Suche nach Konfigurationsdatei "
+#
+# 25 26 27
+#
+Lösche Verzeichnis:
+Lösche Datei:
+Lösche Datei oder Verzeichnis:
+#
+# 28 29 (Preferences files, empty string)
+#
+Präferenzen-Dateien:
+UNUSED
+#
+# 30 31
+#
++
+-
+#
+# 32 33 34 35
+#
+Suche Resourcen-Datei "
+Suche Konfigurations-Datei "
+" (auch komprimiert).
+" (nicht komprimiert).
+#
+# 36 Collecting paper size data
+#
+Suche Papiergrößen.
+#
+# 37 38 39 Details abort supported compressions
+#
+" (gzip-Komprimierung erlaubt):
+" (bzip2-Komprimierung erlaubt):
+" (gzip/bzip2-Komprimierung erlaubt:
+#
+# 40 41
+#
+String-Kopie alloziert: "
+".
+#
+# 42 43
+#
+Erfolgreich zu Ganzzahl konvertiert.
+Keine Ganzzahl-Angabe!
+#
+# 44 45
+#
+Erfolgreich zu vorzeichenloser Ganzzahl konvertiert.
+Keine vorzeichenlose Ganzzahl-Angabe!
+#
+# 46 47
+#
+Erfolgreich zu Boolean konvertiert.
+Keine Boolean-Angabe!
+#
+# 48 49
+#
+Erfolgreich zu Größenangabe konvertiert.
+Keine Größenangabe!
diff --git a/support/dktools/dk4app/de/dk4sock.str b/support/dktools/dk4app/de/dk4sock.str
new file mode 100644
index 0000000000..96654fbe38
--- /dev/null
+++ b/support/dktools/dk4app/de/dk4sock.str
@@ -0,0 +1,506 @@
+#
+# 0 Error: Failed to initialize Winsock subsystem!
+#
+Winsock konnte nicht initialisiert werden!
+#
+# 1 Error: Failed to shut down Winsock subsystem!
+#
+Winsock konnte nicht heruntergefahren werden!
+#
+# 2 Error: Failed to create socket!
+#
+Socket konnte nicht erzeugt werden!
+#
+# 3 Error: Failed to close socket!
+#
+Socket konnte nicht geschlossen werden!
+#
+# 4 Error: Failed to bind local address!
+#
+Lokale Adresse konnte nicht gebunden werden!
+#
+# 5 Error: Failed to listen for incoming connection requests!
+#
+Warten auf Verbindungsanfragen fehlgeschlagen!
+#
+# 6 Error: Failed to accept incoming connection request!
+#
+Akzeptieren einer Verbindungsanfrage fehlgeschlagen!
+#
+# 7 Error: Failed to connect to remote address!
+#
+Verbindung zu Remote-Host konnte nicht hergestellt werden!
+#
+# 8 Error: Failed to set reusable flag for socket!
+#
+Attribut "reusable" konnte für Socket nicht gesetzt werden!
+#
+# 9 Error: Failed to modify ``non-blocking'' option for socket!
+#
+Attribut "non-blocking" konnte für Socket nicht gesetzt werden!
+#
+# 10 Error: Failed to retrieve remote address(es)!
+#
+Remote-Adresse(n) nicht gefunden!
+#
+# 11 Error: Failed to retrieve local address(es)!
+#
+Lokale Adresse(n) nicht gefunden!
+#
+# 12 Error: Failed to retrieve remote host address!
+#
+Remote-Adresse nicht gefunden!
+#
+# 13 Error: Failed to retrieve port number for remote service!
+#
+Port-Nummer für Remote-Service-Namen nicht gefunden!
+#
+# 14 Error: Failed to retrieve port number for local service!
+#
+Port-Nummer für lokalen Service-Namen nicht gefunden!
+#
+# 15 16 17 Error: Failed to convert text to ASCII!
+#
+Text konnte nicht zu ASCII konvertiert werden!
+"
+"!
+#
+# 18 19 Error: Failed to obtain local addresses ...
+#
+Lokale Adresse(n) konnte(n) nicht ermittelt werden!
+Port/Service:
+#
+# 20 21 22 Error: Failed to obtain remote address(es)!
+#
+Remote-Adresse(n) konnte(n) nicht ermittelt werden!
+Host:
+Port/Service:
+#
+# 23 24 Error: Service/port not found
+#
+Service/Port nicht gefunden: "
+"!
+#
+# 25 26 Error: Failed to convert service/port to ASCII
+#
+Service/Port ist kein ASCII-Text: "
+"!
+#
+# 27 Error: No matching pair of local/remote addresses found!
+#
+Kein passendes Adress-Paar (Lokal/Remote) gefunden!
+#
+# 28 Error: Illegal local port number!
+#
+Unzulässige lokale Port-Nummer!
+#
+# 29 Error: Illegal remote port number!
+#
+Unzulässige Remote-Port-Nummer!
+#
+# 30 Debug: Connection established.
+#
+Verbindung hergestellt.
+#
+# 31 Error: Illegal address length in getservbyname() result!
+#
+Unzulässige Adresslänge im Ergebnis von getservbyname()!
+#
+# 32 Error: Illegal address family in gethostbyname() result!
+#
+Unzulässige Adressfamilie im Ergebnis von gethostbyname()!
+#
+# 33 34 Error: Remote host not found: "..."!
+#
+Remote-Host nicht gefunden: "
+"!
+#
+# 35 36 Error: Failed to convert host name to ASCII: ...
+#
+Nicht-ASCII-Zeichen in Hostnamen: \n\t"
+"!
+#
+# 37 38 39 40 Texts to show error code
+#
+errno=
+ (0x
+)
+WSAGetLastError()=
+#
+# 41 42 43
+#
+TCP-Verbindung konnte nicht hergestellt werden!
+Lokal:
+Remote:
+#
+# 44
+#
+Zeitüberschreitung bei Verbindungsversuch!
+#
+# 45
+#
+Unzulässige Argumente für Funktion, evtl. Bug!
+#
+# 46
+#
+Kein passendes Adresspaar (Lokal/Remote) verfügbar!
+#
+# 47 WSASYSNOTREADY
+#
+Netzwerk-Subsystem noch nicht bereit!
+#
+# 48 WSAVERNOTSUPPORTED
+#
+Winsock-Version wird nicht unterstützt!
+#
+# 49 WSAEINPROGRESS
+#
+Winsock-Operation läuft noch!
+#
+# 50 WSAEPROCLIM
+#
+Prozess-Limit für Winsock erreicht!
+#
+# 51 WSAEFAULT WSAEINVAL / EFAULT
+#
+Ungültige Parameter an Funktion übergeben!
+#
+# 52 WSANOTINITIALIZED
+#
+Winsock wurde noch nicht initialisiert!
+#
+# 53 WSAENETDOWN
+#
+Fehler im Netzwerk-Subsystem!
+#
+# 54 WSAEAFNOSUPPORT / EAFNOSUPPORT
+#
+Adressfamilie wird nicht unterstützt!
+#
+# 55 WSAEMFILE
+#
+Keine Filedeskriptoren mehr verfügbar!
+#
+# 56 WSAENOBUFS
+#
+Kein Puffer-Speicher mehr verfügbar!
+#
+# 57 WSAEPROTONOSUPPORT
+#
+Protokoll wird nicht unterstützt!
+#
+# 58 WSAEPROTOTYPE
+#
+Falsches Protokoll für Socket!
+#
+# 59 WSAEPROVIDERFAILEDINIT
+#
+Service-Provider konnte nicht initialisiert werden!
+#
+# 60 WSAESOCKTNOSUPPORT
+#
+Socket-Typ wird von Adressfamilie nicht unterstützt!
+#
+# 61 WSAINVALIDPROVIDER
+#
+Service-Provider-Version nicht verwendbar!
+#
+# 62 WSAINVALIDPROCTABLE
+#
+Unvollständige/defekte Prozedurtabelle vom Service-Provider!
+#
+# 63 WSAEACCES / EACCES
+#
+Unzureichende Berechtigungen!
+#
+# 64 WSAEADDRINUSE / EADDRINUSE
+#
+Adresse wird bereits benutzt!
+#
+# 65 WSAEADDRNOTAVAIL / EADDRNOTAVAIL
+#
+Adresse ist nicht verfügbar!
+#
+# 66 WSAENOTSOCK
+#
+Filedeskriptor ist kein Socket!
+#
+# 67 EAI_ADDRFAMILY
+#
+Host hat keine Adressen in dieser Adressfamilie!
+#
+# 68 EAI_AGAIN / TRY_AGAIN
+#
+Zeitweiliges DNS-Problem, evtl. später wieder versuchen!
+#
+# 69 EAI_BADFLAGS
+#
+Unzulässige Flag-Kombination!
+#
+# 70 EAI_FAIL
+#
+DNS-Server-Fehler!
+#
+# 71 EAI_FAMILY
+#
+Adressfamilie wird nicht unterstützt!
+#
+# 72 EAI_MEMORY
+#
+Zu wenig Speicher (RAM)!
+#
+# 73 EAI_NODATA / NO_DATA
+#
+Keine Netzwerkadresse für Host gefunden!
+#
+# 74 EAI_NONAME
+#
+Name oder Nummer falsch!
+#
+# 75 EAI_SERVICE
+#
+Service ist über diesen Socket-Typ nicht erreichbar!
+#
+# 76 EAI_SOCKTYPE
+#
+Unzulässiger Socket-Typ oder fehlerhafte Argumente!
+#
+# 77 EAI_SYSTEM
+#
+System-Fehler, siehe errno!
+#
+# 78 EAI_OVERFLOW
+#
+Argument-Puffer-Ãœberlauf!
+#
+# 79 EAGAIN
+#
+Zeitweiliges Resourcen-Problem, evtl. später nochmals probieren!
+#
+# 80 EALREADY
+#
+Versuch wird bereits unternommen!
+#
+# 81 EBADF
+#
+Kein Dateideskriptor!
+#
+# 82 ECONNREFUSED
+#
+Niemand wartet dort auf Verbindunganfrage!
+#
+# 83 ECONNRESET
+#
+Verbindung von Gegenstelle abgelehnt/beendet!
+#
+# 84 EDEADLK
+#
+Operation würde zu Deadlock führen!
+#
+# 85 EDESTADDRREQ / EISDIR
+#
+Zieladresse muss angegeben werden!
+#
+# 86 EDOM
+#
+Zu hohe Werte für Timeout!
+#
+# 87 EINPROGRESS
+#
+Operation wird durchgeführt!
+#
+# 88 EINTR
+#
+Operation abgebrochen durch Signal!
+#
+# 89 EISCONN
+#
+Socket ist bereits verbunden!
+#
+# 90 EIO
+#
+Ein-/Ausgabefehler!
+#
+# 91 ELOOP
+#
+Schleife in symbolischen Links!
+#
+# 92 EMFILE
+#
+Keine Filedeskriptoren für Prozess verfügbar!
+#
+# 93 ENAMETOOLONG
+#
+Adresse oder Pfadname zu lang!
+#
+# 94 ENETUNREACH
+#
+Netzwerk nicht erreichbar!
+#
+# 95 ENFILE
+#
+Keine Filedeskriptoren mehr auf System verfügbar!
+#
+# 96 ENOENT
+#
+Datei oder Pfadkomponente existiert nicht oder kein Verzeichnis!
+#
+# 97 ENOLCK
+#
+Setzen eines Lock fehlgeschlagen!
+#
+# 98 ENOPROTOOPT
+#
+Versuch, unzulässige Option zu bearbeiten!
+#
+# 99 ENOTDIR
+#
+Pfadkomponente ist kein Verzeichnis!
+#
+# 100 ENOSPC
+#
+Puffer ist zu klein!
+#
+# 101 EOPNOTSUPP
+#
+Operation unzulässig für Protokoll oder Socket-Typ!
+#
+# 102 EROFS
+#
+Dateisystem ist nur-lesbar eingebunden!
+#
+# 103 ETIMEDOUT
+#
+Zeitüberschreitung (Timeout)!
+#
+# 104 EOVERFLOW
+#
+Numerischer Überlauf in Größenberechnung!
+#
+# 105 WSAECONNABORTED
+#
+Verbindung geschlossen wegen Timeout oder Fehler!
+#
+# 106 WSAEHOSTUNREACH
+#
+Host nicht erreichbar!
+#
+# 107 WSAEINTR
+#
+Winsock-Operation wurde abgebrochen!
+#
+# 108 109 110 111 WSAEINVAL
+#
+Socket wartet auf Verbindungsanfragen!
+Keine lokale Adresse gebunden!
+Socket wartet nicht auf Verbindungsanfragen!
+Ungültiger Socket-Shutdown-Parameter!
+#
+# 112 WSAEMSGSIZE
+#
+Message zu groß!
+#
+# 113 WSAENETRESET
+#
+Verbindung geschlossen, Keep-Alive-Test fehlgeschlagen!
+#
+# 114 WSAENOTCONN
+#
+Nicht verbunden!
+#
+# 115 WSAEPROVIDERFAILEDINIT
+#
+Socket-Provider konnte nicht initialisiert werden!
+#
+# 116 WSAESHUTDOWN
+#
+Socket wurde bereits heruntergefahren!
+#
+# 117 WSAEWOULDBLOCK
+#
+Operation würde blockieren!
+#
+# 118 WSAHOST_NOT_FOUND
+#
+Host nicht gefunden (authorative Antwort)!
+#
+# 119 WSAINVALIDPROCTABLE
+#
+Unvollständige/defekte Prozedurtabelle vom Service-Provider!
+#
+# 120 WSAINVALIDPROVIDER
+#
+Service-Provider-Version nicht verwendbar!
+#
+# 121 EPROTO
+#
+Protokoll-Fehler!
+#
+# 122 ENOSR
+#
+Unzureichende Stream-Resourcen!
+#
+# 123 EPFNOSUPPORT
+#
+Protokollfamilie wird nicht unterstützt!
+#
+# 124 ENOLINK
+#
+Verbindung nicht länger aktiv!
+#
+# 125 ENXIO
+#
+Server wurde vor Verbindungsherstellung beendet!
+#
+# 126 ENODEV
+#
+Protokollfamilie oder -typ nicht in Konfiguration gefunden!
+#
+# 127 ESTALE
+#
+Gestohlener NFS-Datei-Handle!
+#
+# 128
+#
+Socket konnte nicht heruntergefahren werden!
+#
+# 129 130
+#
+Lokale Adresse konnte nicht gebunden werden:\n\t"
+"!
+#
+# 131 132
+#
+Verbindung zur Remote-Adresse nicht möglich:\n\t"
+"!
+#
+# 133 134 135
+#
+Senden gelang nur teilweise, lediglich
+ von
+ Bytes gesendet!
+#
+# 136
+#
+Senden gelang nur teilweise!
+#
+# 137
+#
+Senden fehlgeschlagen!
+#
+# 138
+#
+Daten-Empfang fehlgeschlagen!
+#
+# 139
+#
+Verbindungsaufbau-Sockets konnten nicht angelegt werden!
+#
+# 140
+#
+Warte auf Verbindungsanfrage:
+#
+# 141 142
+#
+Erlaubte Adresse für Gegenstelle nicht gefunden in Text:\n\t"
+"!
diff --git a/support/dktools/dk4app/de/dk4wxbase.str b/support/dktools/dk4app/de/dk4wxbase.str
new file mode 100644
index 0000000000..df9cad6443
--- /dev/null
+++ b/support/dktools/dk4app/de/dk4wxbase.str
@@ -0,0 +1,24 @@
+#
+# 0 Dialog box title: Help file not found
+#
+Hilfe-Datei nicht gefunden
+#
+# 1 Dialog box text: Help file not found!
+#
+Die Datei für die Online-Hilfe wurde auf Ihrem Computer nicht gefunden!
+#
+# 2 Progress dialog title
+#
+Verarbeitung läuft
+#
+# 3 4 5 Progress dialog cancel button, tooltip and response
+#
+Abbrechen
+Aktuelle Operation abbrechen
+Abbruch eingeleitet, bitte warten.
+#
+# 6 7 8 Further error messages from Dk4WxHelpController
+#
+Fehler
+Zu wenig Speicher (RAM)!
+Fehlerhafte Argumente im Konstruktor von Dk4WxHelpController (Bug)!
diff --git a/support/dktools/dk4appargs.c b/support/dktools/dk4appargs.c
new file mode 100644
index 0000000000..1342c76ed5
--- /dev/null
+++ b/support/dktools/dk4appargs.c
@@ -0,0 +1,69 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4appargs.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4appargs.c The dk4appargs module.
+*/
+
+
+#line 11 "dk4appargs.ctr"
+
+#include "dk4app.h"
+
+
+
+int
+dk4app_get_argc(dk4_app_t *app)
+{
+ int back = 0;
+ if (NULL != app) {
+ back = app->my_argc;
+ }
+ return back;
+}
+
+
+
+const dkChar *
+dk4app_get_argv(dk4_app_t *app, int n)
+{
+ const dkChar *back = NULL;
+ if (NULL != app) {
+ if (n < app->my_argc) {
+ back = (app->my_argv)[n];
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4appargs.ctr b/support/dktools/dk4appargs.ctr
new file mode 100644
index 0000000000..8dd2b259c8
--- /dev/null
+++ b/support/dktools/dk4appargs.ctr
@@ -0,0 +1,39 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+
+%% module
+
+#include "dk4app.h"
+
+
+
+int
+dk4app_get_argc(dk4_app_t *app)
+{
+ int back = 0;
+ if (NULL != app) {
+ back = app->my_argc;
+ }
+ return back;
+}
+
+
+
+const dkChar *
+dk4app_get_argv(dk4_app_t *app, int n)
+{
+ const dkChar *back = NULL;
+ if (NULL != app) {
+ if (n < app->my_argc) {
+ back = (app->my_argv)[n];
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4appdeldir.c b/support/dktools/dk4appdeldir.c
new file mode 100644
index 0000000000..108a977496
--- /dev/null
+++ b/support/dktools/dk4appdeldir.c
@@ -0,0 +1,259 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4appdeldir.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4appdeldir.c The dk4appdeldir module.
+*/
+
+
+#line 10 "dk4appdeldir.ctr"
+
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4APP_H_INCLUDED
+#include "dk4app.h"
+#endif
+
+#ifndef DK4DELDIR_H_INCLUDED
+#include "dk4deldir.h"
+#endif
+
+#ifndef DK4CONST_H_INCLUDED
+#include "dk4const.h"
+#endif
+
+#ifndef DK4STATD_H_INCLUDED
+#include "dk4statd.h"
+#endif
+
+#ifndef DK4FILED_H_INCLUDED
+#include "dk4filed.h"
+#endif
+
+#ifndef DK4MAODD_H_INCLUDED
+#include "dk4maodd.h"
+#endif
+
+#ifndef DK4MAODH_H_INCLUDED
+#include "dk4maodh.h"
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+
+
+
+
+#line 64 "dk4appdeldir.ctr"
+
+
+
+void
+dk4app_del_dir_report(const dkChar *fn, const dk4_er_t *erp, dk4_app_t *app)
+{
+#if DK4_ON_WINDOWS
+ dkChar eb1[8 * sizeof(DWORD)];
+ dkChar eb2[8 * sizeof(DWORD)];
+ int res;
+#endif
+ switch (erp->ec) {
+ case DK4_E_NOT_SUPPORTED: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 66, 54, fn);
+ } break;
+#if DK4_ON_WINDOWS
+ case DK4_E_REMOVE_DIRECTORY_FAILED : {
+ res = dk4ma_write_decimal_unsigned(
+ eb1, DK4_SIZEOF(eb1,dkChar), (dk4_um_t)((erp->dt).lDetails1), 0, NULL
+ );
+ if (0 != res) {
+ res = dk4ma_write_hex_unsigned(
+ eb2, DK4_SIZEOF(eb2,dkChar),
+ (dk4_um_t)((erp->dt).lDetails1), 0, NULL
+ );
+ }
+ if (0 != res) {
+ dk4app_log_base7(app,DK4_LL_ERROR,66,69,70,71,fn,eb1,eb2);
+ } else {
+ dk4app_log_base3(app, DK4_LL_ERROR, 66, 77, fn);
+ }
+ } break;
+#endif
+ case DK4_E_RMDIR_FAILED: {
+ switch ((erp->dt).iDetails1) {
+#ifdef EACCES
+ case EACCES: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 66, 55, fn);
+ } break;
+#endif
+#ifdef EBUSY
+ case EBUSY: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 66, 49, fn);
+ } break;
+#endif
+#ifdef EIO
+ case EIO: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 66, 59, fn);
+ } break;
+#endif
+#ifdef EFAULT
+ case EFAULT: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 66, 50, fn);
+ } break;
+#endif
+#ifdef EINVAL
+ case EINVAL: {
+ /* ERROR: Invalid path name */
+ dk4app_log_base3(app, DK4_LL_ERROR, 66, 68, fn);
+ } break;
+#endif
+#ifdef ELOOP
+ case ELOOP: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 66, 61, fn);
+ } break;
+#endif
+#ifdef ENAMETOOLONG
+ case ENAMETOOLONG: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 66, 65, fn);
+ } break;
+#endif
+#ifdef ENOENT
+ case ENOENT: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 66, 51, fn);
+ } break;
+#endif
+#ifdef ENOMEM
+ case ENOMEM: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 66, 62, fn);
+ } break;
+#endif
+#ifdef ENOTDIR
+ case ENOTDIR: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 66, 150, fn);
+ } break;
+#endif
+#ifdef ENOTEMPTY
+ case ENOTEMPTY: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 66, 67, fn);
+ } break;
+#endif
+#if defined(EEXIST) && (EEXIST != ENOTEMPTY)
+ case EEXIST: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 66, 67, fn);
+ } break;
+#endif
+#ifdef EPERM
+ case EPERM: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 66, 58, fn);
+ } break;
+#endif
+#ifdef EROFS
+ case EROFS: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 66, 56, fn);
+ } break;
+#endif
+ default: {
+ dk4app_log_with_errno(
+ app, DK4_LL_ERROR, 66, 79, 80, 66, 77, fn, (erp->dt).iDetails1
+ );
+ } break;
+ }
+ } break;
+ default: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 66, 77, fn);
+ } break;
+ }
+}
+
+
+
+int
+dk4app_del_dir(const dkChar *fn, dk4_app_t *app)
+{
+ const dkChar *msg[3];
+ dk4_er_t er;
+ int back = 0;
+
+
+#line 192 "dk4appdeldir.ctr"
+ if (NULL != fn) {
+
+#line 193 "dk4appdeldir.ctr"
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ if ((NULL != app->msg_debug) && (25 < app->sz_msg_debug)) {
+ msg[0] = (app->msg_debug)[25];
+ msg[1] = fn;
+ msg[2] = NULL;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 2);
+ }
+ }
+ }
+ dk4error_init(&er);
+ back = dk4delete_directory(fn, &er);
+ if (0 == back) {
+
+#line 206 "dk4appdeldir.ctr"
+ if (0 != dk4file_exists(fn, NULL)) {
+ dk4app_del_dir_report(fn, &er, app);
+ } else {
+
+#line 209 "dk4appdeldir.ctr"
+ back = 1; /* File does not exist */
+ }
+ }
+ }
+
+
+#line 214 "dk4appdeldir.ctr"
+ return back;
+}
+
diff --git a/support/dktools/dk4appdeldir.ctr b/support/dktools/dk4appdeldir.ctr
new file mode 100644
index 0000000000..fb442fa168
--- /dev/null
+++ b/support/dktools/dk4appdeldir.ctr
@@ -0,0 +1,216 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4APP_H_INCLUDED
+#include "dk4app.h"
+#endif
+
+#ifndef DK4DELDIR_H_INCLUDED
+#include "dk4deldir.h"
+#endif
+
+#ifndef DK4CONST_H_INCLUDED
+#include "dk4const.h"
+#endif
+
+#ifndef DK4STATD_H_INCLUDED
+#include "dk4statd.h"
+#endif
+
+#ifndef DK4FILED_H_INCLUDED
+#include "dk4filed.h"
+#endif
+
+#ifndef DK4MAODD_H_INCLUDED
+#include "dk4maodd.h"
+#endif
+
+#ifndef DK4MAODH_H_INCLUDED
+#include "dk4maodh.h"
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+
+
+$!trace-include
+
+
+
+void
+dk4app_del_dir_report(const dkChar *fn, const dk4_er_t *erp, dk4_app_t *app)
+{
+#if DK4_ON_WINDOWS
+ dkChar eb1[8 * sizeof(DWORD)];
+ dkChar eb2[8 * sizeof(DWORD)];
+ int res;
+#endif
+ switch (erp->ec) {
+ case DK4_E_NOT_SUPPORTED: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 66, 54, fn);
+ } break;
+#if DK4_ON_WINDOWS
+ case DK4_E_REMOVE_DIRECTORY_FAILED : {
+ res = dk4ma_write_decimal_unsigned(
+ eb1, DK4_SIZEOF(eb1,dkChar), (dk4_um_t)((erp->dt).lDetails1), 0, NULL
+ );
+ if (0 != res) {
+ res = dk4ma_write_hex_unsigned(
+ eb2, DK4_SIZEOF(eb2,dkChar),
+ (dk4_um_t)((erp->dt).lDetails1), 0, NULL
+ );
+ }
+ if (0 != res) {
+ dk4app_log_base7(app,DK4_LL_ERROR,66,69,70,71,fn,eb1,eb2);
+ } else {
+ dk4app_log_base3(app, DK4_LL_ERROR, 66, 77, fn);
+ }
+ } break;
+#endif
+ case DK4_E_RMDIR_FAILED: {
+ switch ((erp->dt).iDetails1) {
+#ifdef EACCES
+ case EACCES: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 66, 55, fn);
+ } break;
+#endif
+#ifdef EBUSY
+ case EBUSY: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 66, 49, fn);
+ } break;
+#endif
+#ifdef EIO
+ case EIO: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 66, 59, fn);
+ } break;
+#endif
+#ifdef EFAULT
+ case EFAULT: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 66, 50, fn);
+ } break;
+#endif
+#ifdef EINVAL
+ case EINVAL: {
+ /* ERROR: Invalid path name */
+ dk4app_log_base3(app, DK4_LL_ERROR, 66, 68, fn);
+ } break;
+#endif
+#ifdef ELOOP
+ case ELOOP: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 66, 61, fn);
+ } break;
+#endif
+#ifdef ENAMETOOLONG
+ case ENAMETOOLONG: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 66, 65, fn);
+ } break;
+#endif
+#ifdef ENOENT
+ case ENOENT: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 66, 51, fn);
+ } break;
+#endif
+#ifdef ENOMEM
+ case ENOMEM: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 66, 62, fn);
+ } break;
+#endif
+#ifdef ENOTDIR
+ case ENOTDIR: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 66, 150, fn);
+ } break;
+#endif
+#ifdef ENOTEMPTY
+ case ENOTEMPTY: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 66, 67, fn);
+ } break;
+#endif
+#if defined(EEXIST) && (EEXIST != ENOTEMPTY)
+ case EEXIST: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 66, 67, fn);
+ } break;
+#endif
+#ifdef EPERM
+ case EPERM: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 66, 58, fn);
+ } break;
+#endif
+#ifdef EROFS
+ case EROFS: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 66, 56, fn);
+ } break;
+#endif
+ default: {
+ dk4app_log_with_errno(
+ app, DK4_LL_ERROR, 66, 79, 80, 66, 77, fn, (erp->dt).iDetails1
+ );
+ } break;
+ }
+ } break;
+ default: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 66, 77, fn);
+ } break;
+ }
+}
+
+
+
+int
+dk4app_del_dir(const dkChar *fn, dk4_app_t *app)
+{
+ const dkChar *msg[3];
+ dk4_er_t er;
+ int back = 0;
+ $? "+ dk4app_del_dir %!ds", TR_STR(fn)
+ if (NULL != fn) { $? ". arg ok"
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ if ((NULL != app->msg_debug) && (25 < app->sz_msg_debug)) {
+ msg[0] = (app->msg_debug)[25];
+ msg[1] = fn;
+ msg[2] = NULL;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 2);
+ }
+ }
+ }
+ dk4error_init(&er);
+ back = dk4delete_directory(fn, &er);
+ if (0 == back) { $? "! problem"
+ if (0 != dk4file_exists(fn, NULL)) {
+ dk4app_del_dir_report(fn, &er, app);
+ } else { $? ". not found"
+ back = 1; /* File does not exist */
+ }
+ }
+ }
+ $? "- dk4app_del_dir %d", back
+ return back;
+}
+
diff --git a/support/dktools/dk4appdelfile.c b/support/dktools/dk4appdelfile.c
new file mode 100644
index 0000000000..26b14ecf1c
--- /dev/null
+++ b/support/dktools/dk4appdelfile.c
@@ -0,0 +1,243 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4appdelfile.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4appdelfile.c The dk4appdelfile module.
+*/
+
+
+#line 10 "dk4appdelfile.ctr"
+
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4APP_H_INCLUDED
+#include "dk4app.h"
+#endif
+
+#ifndef DK4DELFILE_H_INCLUDED
+#include "dk4delfile.h"
+#endif
+
+#ifndef DK4STATD_H_INCLUDED
+#include "dk4statd.h"
+#endif
+
+#ifndef DK4CONST_H_INCLUDED
+#include "dk4const.h"
+#endif
+
+#ifndef DK4FILED_H_INCLUDED
+#include "dk4filed.h"
+#endif
+
+#ifndef DK4MAODD_H_INCLUDED
+#include "dk4maodd.h"
+#endif
+
+#ifndef DK4MAODH_H_INCLUDED
+#include "dk4maodh.h"
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+
+
+void
+dk4app_del_file_report(const dkChar *fn, const dk4_er_t *erp, dk4_app_t *app)
+{
+#if DK4_ON_WINDOWS
+ dkChar eb1[8 * sizeof(DWORD)];
+ dkChar eb2[8 * sizeof(DWORD)];
+ int res;
+#endif
+ switch (erp->ec) {
+ case DK4_E_NOT_SUPPORTED: {
+ /* ERROR: Failed to delete file, no function available */
+ dk4app_log_base3(app, DK4_LL_ERROR, 41, 54, fn);
+ } break;
+#if DK4_ON_WINDOWS
+ case DK4_E_DELETE_FILE_FAILED : {
+ if (ERROR_FILE_NOT_FOUND == (erp->dt).lDetails1) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 41, 51, fn);
+ goto finished;
+ }
+ if (ERROR_ACCESS_DENIED == (erp->dt).lDetails1) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 41, 55, fn);
+ goto finished;
+ }
+ res = dk4ma_write_decimal_unsigned(
+ eb1, DK4_SIZEOF(eb1,dkChar), (dk4_um_t)((erp->dt).lDetails1), 0, NULL
+ );
+ if (0 != res) {
+ res = dk4ma_write_hex_unsigned(
+ eb2, DK4_SIZEOF(eb2,dkChar),
+ (dk4_um_t)((erp->dt).lDetails1), 0, NULL
+ );
+ }
+ if (0 != res) {
+ dk4app_log_base7(app,DK4_LL_ERROR,41,69,70,71,fn,eb1,eb2);
+ } else {
+ dk4app_log_base3(app, DK4_LL_ERROR, 41, 77, fn);
+ }
+ goto finished;
+ } break;
+#endif
+ case DK4_E_UNLINK_FAILED: {
+ switch ((erp->dt).iDetails1) {
+#ifdef EACCES
+ case EACCES: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 41, 55, fn);
+ } break;
+#endif
+#ifdef EBUSY
+ case EBUSY: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 41, 49, fn);
+ } break;
+#endif
+#ifdef EFAULT
+ case EFAULT: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 41, 50, fn);
+ } break;
+#endif
+#ifdef EIO
+ case EIO: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 41, 59, fn);
+ } break;
+#endif
+#ifdef EISDIR
+ case EISDIR: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 41, 52, fn);
+ } break;
+#endif
+#ifdef ELOOP
+ case ELOOP: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 41, 61, fn);
+ } break;
+#endif
+#ifdef ENAMETOOLONG
+ case ENAMETOOLONG: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 41, 65, fn);
+ } break;
+#endif
+#ifdef ENOENT
+ case ENOENT: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 41, 51, fn);
+ } break;
+#endif
+#ifdef ENOMEM
+ case ENOMEM: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 41, 62, fn);
+ } break;
+#endif
+#ifdef ENOTDIR
+ case ENOTDIR: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 41, 150, fn);
+ } break;
+#endif
+#ifdef EPERM
+ case EPERM: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 41, 58, fn);
+ } break;
+#endif
+#ifdef EROFS
+ case EROFS: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 41, 56, fn);
+ } break;
+#endif
+ default: {
+ dk4app_log_with_errno(
+ app, DK4_LL_ERROR, 41, 79, 80, 41, 77, fn, (erp->dt).iDetails1
+ );
+ } break;
+ }
+ } break;
+ default: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 41, 77, fn);
+ } break;
+ }
+#if DK4_ON_WINDOWS
+ finished: ;
+#endif
+}
+
+
+
+int
+dk4app_del_file(const dkChar *fn, dk4_app_t *app)
+{
+ const dkChar *msg[3];
+ dk4_er_t er;
+ int back = 0;
+ if (NULL != fn) {
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ if ((NULL != app->msg_debug) && (26 < app->sz_msg_debug)) {
+ msg[0] = (app->msg_debug)[26];
+ msg[1] = fn;
+ msg[2] = NULL;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 2);
+ }
+ }
+ }
+ dk4error_init(&er);
+ back = dk4delete_file(fn, &er);
+ if (0 == back) {
+ if (0 != dk4file_exists(fn, NULL)) {
+ dk4app_del_file_report(fn, &er, app);
+ } else {
+ back = 1; /* File does not exist */
+ }
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4appdelfile.ctr b/support/dktools/dk4appdelfile.ctr
new file mode 100644
index 0000000000..f99564b0aa
--- /dev/null
+++ b/support/dktools/dk4appdelfile.ctr
@@ -0,0 +1,212 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4APP_H_INCLUDED
+#include "dk4app.h"
+#endif
+
+#ifndef DK4DELFILE_H_INCLUDED
+#include "dk4delfile.h"
+#endif
+
+#ifndef DK4STATD_H_INCLUDED
+#include "dk4statd.h"
+#endif
+
+#ifndef DK4CONST_H_INCLUDED
+#include "dk4const.h"
+#endif
+
+#ifndef DK4FILED_H_INCLUDED
+#include "dk4filed.h"
+#endif
+
+#ifndef DK4MAODD_H_INCLUDED
+#include "dk4maodd.h"
+#endif
+
+#ifndef DK4MAODH_H_INCLUDED
+#include "dk4maodh.h"
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+
+
+void
+dk4app_del_file_report(const dkChar *fn, const dk4_er_t *erp, dk4_app_t *app)
+{
+#if DK4_ON_WINDOWS
+ dkChar eb1[8 * sizeof(DWORD)];
+ dkChar eb2[8 * sizeof(DWORD)];
+ int res;
+#endif
+ switch (erp->ec) {
+ case DK4_E_NOT_SUPPORTED: {
+ /* ERROR: Failed to delete file, no function available */
+ dk4app_log_base3(app, DK4_LL_ERROR, 41, 54, fn);
+ } break;
+#if DK4_ON_WINDOWS
+ case DK4_E_DELETE_FILE_FAILED : {
+ if (ERROR_FILE_NOT_FOUND == (erp->dt).lDetails1) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 41, 51, fn);
+ goto finished;
+ }
+ if (ERROR_ACCESS_DENIED == (erp->dt).lDetails1) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 41, 55, fn);
+ goto finished;
+ }
+ res = dk4ma_write_decimal_unsigned(
+ eb1, DK4_SIZEOF(eb1,dkChar), (dk4_um_t)((erp->dt).lDetails1), 0, NULL
+ );
+ if (0 != res) {
+ res = dk4ma_write_hex_unsigned(
+ eb2, DK4_SIZEOF(eb2,dkChar),
+ (dk4_um_t)((erp->dt).lDetails1), 0, NULL
+ );
+ }
+ if (0 != res) {
+ dk4app_log_base7(app,DK4_LL_ERROR,41,69,70,71,fn,eb1,eb2);
+ } else {
+ dk4app_log_base3(app, DK4_LL_ERROR, 41, 77, fn);
+ }
+ goto finished;
+ } break;
+#endif
+ case DK4_E_UNLINK_FAILED: {
+ switch ((erp->dt).iDetails1) {
+#ifdef EACCES
+ case EACCES: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 41, 55, fn);
+ } break;
+#endif
+#ifdef EBUSY
+ case EBUSY: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 41, 49, fn);
+ } break;
+#endif
+#ifdef EFAULT
+ case EFAULT: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 41, 50, fn);
+ } break;
+#endif
+#ifdef EIO
+ case EIO: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 41, 59, fn);
+ } break;
+#endif
+#ifdef EISDIR
+ case EISDIR: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 41, 52, fn);
+ } break;
+#endif
+#ifdef ELOOP
+ case ELOOP: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 41, 61, fn);
+ } break;
+#endif
+#ifdef ENAMETOOLONG
+ case ENAMETOOLONG: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 41, 65, fn);
+ } break;
+#endif
+#ifdef ENOENT
+ case ENOENT: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 41, 51, fn);
+ } break;
+#endif
+#ifdef ENOMEM
+ case ENOMEM: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 41, 62, fn);
+ } break;
+#endif
+#ifdef ENOTDIR
+ case ENOTDIR: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 41, 150, fn);
+ } break;
+#endif
+#ifdef EPERM
+ case EPERM: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 41, 58, fn);
+ } break;
+#endif
+#ifdef EROFS
+ case EROFS: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 41, 56, fn);
+ } break;
+#endif
+ default: {
+ dk4app_log_with_errno(
+ app, DK4_LL_ERROR, 41, 79, 80, 41, 77, fn, (erp->dt).iDetails1
+ );
+ } break;
+ }
+ } break;
+ default: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 41, 77, fn);
+ } break;
+ }
+#if DK4_ON_WINDOWS
+ finished: ;
+#endif
+}
+
+
+
+int
+dk4app_del_file(const dkChar *fn, dk4_app_t *app)
+{
+ const dkChar *msg[3];
+ dk4_er_t er;
+ int back = 0;
+ if (NULL != fn) {
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ if ((NULL != app->msg_debug) && (26 < app->sz_msg_debug)) {
+ msg[0] = (app->msg_debug)[26];
+ msg[1] = fn;
+ msg[2] = NULL;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 2);
+ }
+ }
+ }
+ dk4error_init(&er);
+ back = dk4delete_file(fn, &er);
+ if (0 == back) {
+ if (0 != dk4file_exists(fn, NULL)) {
+ dk4app_del_file_report(fn, &er, app);
+ } else {
+ back = 1; /* File does not exist */
+ }
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4appdeltree.c b/support/dktools/dk4appdeltree.c
new file mode 100644
index 0000000000..5a38b49b0e
--- /dev/null
+++ b/support/dktools/dk4appdeltree.c
@@ -0,0 +1,716 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4appdeltree.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4appdeltree.c The dk4appdeltree module.
+*/
+
+
+#line 10 "dk4appdeltree.ctr"
+
+#include "dk4conf.h"
+
+#include "dk4types.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef DK4APP_H_INCLUDED
+#include "dk4app.h"
+#endif
+
+#ifndef DK4CONST_H_INCLUDED
+#include "dk4const.h"
+#endif
+
+#ifndef DK4STATD_H_INCLUDED
+#include "dk4statd.h"
+#endif
+
+#ifndef DK4STAT_H_INCLUDED
+#include "dk4stat.h"
+#endif
+
+#ifndef DK4DIR_H_INCLUDED
+#include "dk4dir.h"
+#endif
+
+#ifndef DK4DIRA_H_INCLUDED
+#include "dk4dira.h"
+#endif
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4MEMA_H_INCLUDED
+#include "dk4mema.h"
+#endif
+
+#ifndef DK4MPL_H_INCLUDED
+#include "dk4mpl.h"
+#endif
+
+#ifndef DK4STR_H_INCLUDED
+#include "dk4strd.h"
+#endif
+
+#ifndef DK4MAASZ_H_INCLUDED
+#include "dk4maasz.h"
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_DIRENT_H
+#ifndef DIRENT_H_INCLUDED
+#include <dirent.h>
+#define DIRENT_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_HAVE_WCHAR_H
+#ifndef WCHAR_H_INCLUDED
+#include <wchar.h>
+#define WCHAR_H_INCLUDED 1
+#endif
+#endif
+#endif
+
+
+
+
+#line 91 "dk4appdeltree.ctr"
+
+
+
+/** Information about failed removals of files or directories.
+*/
+enum {
+ /** No errors yet.
+ */
+ NE_NO_ERROR = 0,
+
+ /** Failed to remove one file.
+ */
+ NE_ONE_FILE_REMOVAL_FAILED ,
+
+ /** Failed to remove multiple files.
+ */
+ NE_MULTIPLE_FILE_REMOVALS_FAILED ,
+
+ /** Failed to remove one directory.
+ */
+ NE_ONE_DIRECTORY_REMOVAL_FAILED ,
+
+ /** Failed to remove multiple dirs.
+ */
+ NE_MULTIPLE_DIRECTORY_REMOVALS_FAILED
+};
+
+
+
+/** One node in tree to delete.
+*/
+typedef struct _dk4_del_tree_node_t_ {
+ struct _dk4_del_tree_node_t_ *parent; /**< Parent node. */
+ dk4_dir_t *dir; /**< Directory contents. */
+ size_t dplen; /**< Directory path length. */
+ int ne; /**< Flag: Not empty. */
+} dk4_del_tree_node_t;
+
+
+
+/** Job structure (information passed downwards).
+*/
+typedef struct {
+ dkChar *sbptr; /**< Static buffer. */
+ dkChar *dbptr; /**< Dynamic buffer, may be NULL. */
+ size_t sbsz; /**< Static buffer size. */
+ size_t dbsz; /**< Dynamic buffer size. */
+ int result; /**< Suggested function result. */
+} dk4_del_tree_job_t;
+
+
+
+#if DK4_ON_WINDOWS
+/* +++ Windows */
+#if DK4_CHAR_SIZE > 1
+/* +++ Windows, wchar_t */
+
+/* --- Windows, wchar_t */
+#else
+/* +++ Windows, char */
+
+/* --- Windows, char */
+#endif
+
+static
+int
+dk4app_del_tree_process_dir(const dkChar *dirname)
+{
+#if DK4_CHAR_SIZE > 1
+ WIN32_FIND_DATAW ff;
+#else
+ WIN32_FIND_DATAA ff;
+#endif
+ DWORD dwFileAttributes;
+ HANDLE ha;
+ int back = 1;
+
+#if DK4_CHAR_SIZE > 1
+ dwFileAttributes = GetFileAttributesW(dirname);
+#else
+ dwFileAttributes = GetFileAttributesA(dirname);
+#endif
+ if (INVALID_FILE_ATTRIBUTES == dwFileAttributes) {
+#if DK4_CHAR_SIZE > 1
+ ha = FindFirstFileW(dirname, &ff);
+#else
+ ha = FindFirstFileA(dirname, &ff);
+#endif
+ if (INVALID_HANDLE_VALUE != ha) {
+ dwFileAttributes = ff.dwFileAttributes;
+ FindClose(ha);
+ }
+ }
+ if (INVALID_FILE_ATTRIBUTES != dwFileAttributes) {
+ if (0 != (FILE_ATTRIBUTE_REPARSE_POINT & dwFileAttributes)) {
+#if DK4_CHAR_SIZE > 1
+ ha = FindFirstFileW(dirname, &ff);
+#else
+ ha = FindFirstFileA(dirname, &ff);
+#endif
+ if (INVALID_HANDLE_VALUE != ha) {
+ if (0 != (FILE_ATTRIBUTE_REPARSE_POINT & ff.dwFileAttributes)) {
+ if (IO_REPARSE_TAG_MOUNT_POINT == ff.dwReserved0) {
+ back = 0;
+ }
+ if (IO_REPARSE_TAG_SYMLINK == ff.dwReserved0) {
+ back = 0;
+ }
+ }
+ FindClose(ha);
+ } else {
+ back = 0;
+ }
+ }
+ }
+ return back;
+}
+
+/* --- Windows */
+#else
+/* +++ non-Windows */
+#if DK4_CHAR_SIZE > 1
+/* +++ non-Windows, wchar_t */
+
+/* --- non-Windows, wchar_t */
+#else
+/* +++ non-Windows, char */
+
+/* --- non-Windows, char */
+#endif
+/* --- non-Windows */
+#endif
+
+
+
+#if DK4_HAVE_BACKSLASH_AS_SEP
+static const dkChar dk4appdeltree_fnsep[] = { dkT("\\") };
+#else
+static const dkChar dk4appdeltree_fnsep[] = { dkT("/") };
+#endif
+
+
+
+static
+void
+dk4app_del_tree_node_close(dk4_del_tree_node_t *ptr)
+{
+ if (NULL != ptr) {
+ ptr->parent = NULL;
+ if (NULL != ptr->dir) {
+ dk4dir_close(ptr->dir);
+ ptr->dir = NULL;
+ }
+ ptr->dplen = 0;
+ ptr->ne = 0;
+ dk4mem_free(ptr);
+ }
+}
+
+
+
+static
+dk4_del_tree_node_t *
+dk4app_del_tree_node_open(
+ const dkChar *dn,
+ dk4_del_tree_node_t *par,
+ dk4_del_tree_job_t *job,
+ dk4_app_t *app
+)
+{
+ dk4_er_t er; /* Error report */
+ const dkChar *fn; /* File name to process */
+ dkChar *nbptr; /* Buffer pointer */
+ dk4_del_tree_node_t *back = NULL;
+ size_t lgt; /* Length of buffer */
+#if VERSION_BEFORE_20150821 || TRACE_DEBUG
+ int dfres; /* Result from file deletion */
+#endif
+
+
+#line 270 "dk4appdeltree.ctr"
+ back = dk4mem_new_app(dk4_del_tree_node_t,1,app);
+ if (NULL != back) {
+
+#line 272 "dk4appdeltree.ctr"
+ back->parent = par;
+ back->ne = NE_NO_ERROR;
+ back->dplen = dk4str_len(dn);
+ dk4error_init(&er);
+ back->dir = dk4dir_open_app(dn, DK4_DIR_OPEN_DELTREE, app);
+ if (NULL != back->dir) {
+
+#line 278 "dk4appdeltree.ctr"
+ dk4error_init(&er);
+ lgt = dk4ma_size_t_add(
+ dk4ma_size_t_add(
+ back->dplen, dk4dir_get_max_entry_length(back->dir), &er
+ ),
+ 2,
+ &er
+ );
+ if (DK4_E_NONE == er.ec) {
+
+#line 287 "dk4appdeltree.ctr"
+ if ((lgt > job->sbsz) && (lgt > job->dbsz)) {
+
+
+#line 289 "dk4appdeltree.ctr"
+ nbptr = dk4mem_new_app(dkChar,lgt,app);
+ if (NULL != nbptr) {
+
+#line 291 "dk4appdeltree.ctr"
+ if (job->dbptr) {
+ dk4mem_free(job->dbptr);
+
+#line 293 "dk4appdeltree.ctr"
+ }
+ job->dbptr = nbptr; job->dbsz = lgt;
+
+#line 295 "dk4appdeltree.ctr"
+ } else {
+
+#line 296 "dk4appdeltree.ctr"
+ dk4app_del_tree_node_close(back);
+ back = NULL;
+ job->result = 0;
+ }
+ }
+ if (NULL != back) {
+ if ((NULL != job->dbptr) && (0 < job->dbsz)) {
+ nbptr = job->dbptr;
+
+#line 304 "dk4appdeltree.ctr"
+ lgt = job->dbsz;
+ } else {
+
+#line 306 "dk4appdeltree.ctr"
+ nbptr = job->sbptr;
+ lgt = job->sbsz;
+ }
+
+#line 309 "dk4appdeltree.ctr"
+ do {
+ fn = dk4dir_next_file(back->dir);
+ if (NULL != fn) {
+
+#line 312 "dk4appdeltree.ctr"
+ if (dk4str_cpy_s(nbptr,lgt,dk4dir_get_path(back->dir),NULL)) {
+
+
+#line 314 "dk4appdeltree.ctr"
+ if (dk4str_cat_s(nbptr, lgt, dk4appdeltree_fnsep, NULL)) {
+
+
+#line 316 "dk4appdeltree.ctr"
+ if (dk4str_cat_s(nbptr, lgt, fn, NULL)) {
+
+
+#line 318 "dk4appdeltree.ctr"
+
+
+#line 319 "dk4appdeltree.ctr"
+ switch (back->ne) {
+ case NE_NO_ERROR : {
+ if (0 == dk4app_del_file(nbptr, app)) {
+ back->ne = NE_ONE_FILE_REMOVAL_FAILED;
+ job->result = 0;
+
+
+#line 325 "dk4appdeltree.ctr"
+ }
+ } break;
+ case NE_ONE_FILE_REMOVAL_FAILED : {
+ if (0 == dk4app_del_file(nbptr, NULL)) {
+ back->ne = NE_MULTIPLE_FILE_REMOVALS_FAILED;
+ /* ERROR: Further file removals failed */
+ dk4app_log_base3(
+ app,DK4_LL_ERROR,94,95,dk4dir_get_path(back->dir)
+ );
+
+
+#line 335 "dk4appdeltree.ctr"
+ }
+ } break;
+ default : {
+#if TRACE_DEBUG
+ dfres = dk4app_del_file(nbptr, NULL);
+ if (0 == dfres) {
+
+#line 341 "dk4appdeltree.ctr"
+ }
+#else
+ dk4app_del_file(nbptr, NULL);
+#endif
+ } break;
+ }
+ } else {
+
+#line 348 "dk4appdeltree.ctr"
+ if (NE_ONE_FILE_REMOVAL_FAILED < back->ne) {
+ back->ne = NE_ONE_FILE_REMOVAL_FAILED;
+ }
+ /* ERROR: Directory name too long */
+ dk4app_log_base3(
+ app, DK4_LL_ERROR, 98, 99, dk4dir_get_path(back->dir)
+ );
+ }
+ } else {
+
+#line 357 "dk4appdeltree.ctr"
+ if (NE_ONE_FILE_REMOVAL_FAILED < back->ne) {
+ back->ne = NE_ONE_FILE_REMOVAL_FAILED;
+ }
+ /* ERROR: Directory name too long */
+ dk4app_log_base3(
+ app, DK4_LL_ERROR, 98, 99, dk4dir_get_path(back->dir)
+ );
+ }
+ } else {
+
+#line 366 "dk4appdeltree.ctr"
+ if (NE_ONE_FILE_REMOVAL_FAILED < back->ne) {
+ back->ne = NE_ONE_FILE_REMOVAL_FAILED;
+ }
+ /* ERROR: Directory name too long */
+ dk4app_log_base3(
+ app, DK4_LL_ERROR, 98, 99, dk4dir_get_path(back->dir)
+ );
+ }
+ }
+ } while(NULL != fn);
+ dk4dir_skip_files(back->dir);
+ } else {
+
+#line 378 "dk4appdeltree.ctr"
+ }
+ } else {
+
+#line 380 "dk4appdeltree.ctr"
+ /* ERROR: Math error in size calculation */
+ dk4app_log_base1(app, DK4_LL_ERROR, 82);
+ dk4app_del_tree_node_close(back);
+ back = NULL;
+ job->result = 0;
+ }
+ } else {
+
+#line 387 "dk4appdeltree.ctr"
+ dk4app_del_tree_node_close(back);
+ back = NULL;
+ job->result = 0;
+ /* ERROR: Failed to open directory, already reported */
+ /* !!!!! TODO: Attempt to remove directory or file */
+ }
+ } else {
+
+#line 394 "dk4appdeltree.ctr"
+ }
+
+
+#line 396 "dk4appdeltree.ctr"
+ return back;
+}
+
+
+
+static
+void
+dk4app_del_tree_debug_file_or_dir(
+ dk4_app_t *app,
+ const dkChar *fn,
+ size_t ind
+)
+{
+ const dkChar *msg[3];
+ if ((NULL != app) && (NULL != fn)) {
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ if ((NULL != app->msg_debug) && (ind < app->sz_msg_debug)) {
+ msg[0] = (app->msg_debug)[ind];
+ msg[1] = fn;
+ msg[2] = NULL;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 2);
+ }
+ }
+ }
+}
+
+
+
+int
+dk4app_del_tree(const dkChar *fn, dk4_app_t *app)
+{
+ dkChar sb[DK4_MAX_PATH];
+ dk4_del_tree_job_t job; /* Buffers */
+ dk4_del_tree_node_t *cn; /* Current node */
+ dk4_del_tree_node_t *nn; /* Next node */
+ dkChar *fnb; /* File name buffer */
+ const dkChar *dn; /* Directory name */
+ size_t fnbsz; /* File name buffer size */
+ int res; /* Operation result */
+#if VERSION_BEFORE_20150821 || TRACE_DEBUG
+ int dfres; /* Delete file result */
+#endif
+ int back = 0;
+
+
+
+#line 441 "dk4appdeltree.ctr"
+ job.sbptr = sb;
+ job.sbsz = DK4_SIZEOF(sb,dkChar);
+ job.dbptr = NULL;
+ job.dbsz = 0;
+ job.result = 1;
+ if (NULL != fn) {
+
+#line 447 "dk4appdeltree.ctr"
+ cn = dk4app_del_tree_node_open(fn, NULL, &job, app);
+ if (NULL != cn) {
+
+#line 449 "dk4appdeltree.ctr"
+ while (NULL != cn) {
+
+#line 450 "dk4appdeltree.ctr"
+ if ((NULL != job.dbptr) && (0 < job.dbsz)) {
+ fnb = job.dbptr; fnbsz = job.dbsz;
+
+#line 452 "dk4appdeltree.ctr"
+ } else {
+
+#line 453 "dk4appdeltree.ctr"
+ fnb = job.sbptr; fnbsz = job.sbsz;
+ }
+ dn = dk4dir_next_dir(cn->dir);
+ if (NULL != dn) {
+
+#line 457 "dk4appdeltree.ctr"
+ if (0 != dk4str_cpy_s(fnb, fnbsz, dk4dir_get_path(cn->dir), NULL)) {
+ if (0 != dk4str_cat_s(fnb, fnbsz, dk4appdeltree_fnsep, NULL)) {
+ if (0 != dk4str_cat_s(fnb, fnbsz, dn, NULL)) {
+
+#line 460 "dk4appdeltree.ctr"
+#if DK4_ON_WINDOWS
+ res = dk4app_del_tree_process_dir(fnb);
+#else
+ res = 1;
+#endif
+ if (0 != res) {
+
+#line 466 "dk4appdeltree.ctr"
+ nn = dk4app_del_tree_node_open(fnb, cn, &job, app);
+ if (NULL != nn) {
+ cn = nn;
+ } else {
+ job.result = 0;
+ }
+ } else {
+
+#line 473 "dk4appdeltree.ctr"
+ switch (cn->ne) {
+ case NE_NO_ERROR:
+ case NE_ONE_FILE_REMOVAL_FAILED:
+ case NE_MULTIPLE_FILE_REMOVALS_FAILED: {
+ dk4app_del_tree_debug_file_or_dir(app, fnb, 27);
+ if (0 == dk4app_del_dir(fnb, NULL)) {
+ if (0 == dk4app_del_file(fnb, NULL)) {
+ job.result = 0;
+ cn->ne = NE_ONE_DIRECTORY_REMOVAL_FAILED;
+ dk4app_log_base3(app, DK4_LL_ERROR, 66, 77, fnb);
+
+
+#line 484 "dk4appdeltree.ctr"
+ }
+ }
+ } break;
+ case NE_ONE_DIRECTORY_REMOVAL_FAILED: {
+ dk4app_del_tree_debug_file_or_dir(app, fnb, 27);
+ if (0 == dk4app_del_dir(fnb, NULL)) {
+ if (0 == dk4app_del_file(fnb, NULL)) {
+ job.result = 0;
+ cn->ne = NE_MULTIPLE_DIRECTORY_REMOVALS_FAILED;
+ dk4app_log_base3(
+ app, DK4_LL_ERROR, 96, 97, dk4dir_get_path(cn->dir)
+ );
+
+
+#line 497 "dk4appdeltree.ctr"
+ }
+ }
+ } break;
+ default: {
+ dk4app_del_tree_debug_file_or_dir(app, fnb, 27);
+ if (0 == dk4app_del_dir(fnb, NULL)) {
+#if TRACE_DEBUG
+ dfres = dk4app_del_file(fnb, NULL);
+ if (0 == dfres) {
+
+#line 506 "dk4appdeltree.ctr"
+ }
+#else
+ dk4app_del_file(fnb, NULL);
+#endif
+ }
+ } break;
+ }
+ }
+ } else {
+
+#line 515 "dk4appdeltree.ctr"
+ /* ERROR: Directory name too long! */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, dn);
+ job.result = 0;
+ }
+ } else {
+
+#line 520 "dk4appdeltree.ctr"
+ /* ERROR: Directory name too long! */
+ dk4app_log_base3(app,DK4_LL_ERROR,98,99,dk4dir_get_path(cn->dir));
+ job.result = 0;
+ }
+ } else {
+
+#line 525 "dk4appdeltree.ctr"
+ /* ERROR: Directory name too long! */
+ dk4app_log_base3(app,DK4_LL_ERROR,98,99,dk4dir_get_path(cn->dir));
+ job.result = 0;
+ }
+ } else {
+
+#line 530 "dk4appdeltree.ctr"
+ nn = cn->parent;
+ if (NULL != nn) {
+
+#line 532 "dk4appdeltree.ctr"
+ switch (nn->ne) {
+ case NE_NO_ERROR:
+ case NE_ONE_FILE_REMOVAL_FAILED:
+ case NE_MULTIPLE_FILE_REMOVALS_FAILED: {
+ if (0 == dk4app_del_dir(dk4dir_get_path(cn->dir), app)) {
+ job.result = 0;
+ nn->ne = NE_ONE_DIRECTORY_REMOVAL_FAILED;
+ }
+ } break;
+ case NE_ONE_DIRECTORY_REMOVAL_FAILED: {
+ dk4app_del_tree_debug_file_or_dir(
+ app, dk4dir_get_path(cn->dir), 25
+ );
+ if (0 == dk4app_del_dir(dk4dir_get_path(cn->dir), NULL)) {
+ job.result = 0;
+ nn->ne = NE_MULTIPLE_DIRECTORY_REMOVALS_FAILED;
+ dk4app_log_base3(
+ app, DK4_LL_ERROR, 96, 97, dk4dir_get_path(nn->dir)
+ );
+ }
+ } break;
+ default: {
+ dk4app_del_tree_debug_file_or_dir(
+ app, dk4dir_get_path(cn->dir), 25
+ );
+ (void)dk4app_del_dir(dk4dir_get_path(cn->dir), NULL);
+ } break;
+ }
+ } else {
+
+#line 561 "dk4appdeltree.ctr"
+ if (0 == dk4app_del_dir(dk4dir_get_path(cn->dir), app)) {
+ job.result = 0;
+ }
+ }
+ dk4app_del_tree_node_close(cn);
+ cn = nn;
+ }
+ }
+ } else {
+
+#line 570 "dk4appdeltree.ctr"
+ }
+ } else {
+
+#line 572 "dk4appdeltree.ctr"
+ }
+ if ((NULL != job.dbptr) && (0 < job.dbsz)) {
+ dk4mem_free(job.dbptr);
+
+#line 575 "dk4appdeltree.ctr"
+ }
+ back = job.result;
+
+
+#line 578 "dk4appdeltree.ctr"
+ return back;
+}
+
+
diff --git a/support/dktools/dk4appdeltree.ctr b/support/dktools/dk4appdeltree.ctr
new file mode 100644
index 0000000000..a9d65c42c3
--- /dev/null
+++ b/support/dktools/dk4appdeltree.ctr
@@ -0,0 +1,581 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4conf.h"
+
+#include "dk4types.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef DK4APP_H_INCLUDED
+#include "dk4app.h"
+#endif
+
+#ifndef DK4CONST_H_INCLUDED
+#include "dk4const.h"
+#endif
+
+#ifndef DK4STATD_H_INCLUDED
+#include "dk4statd.h"
+#endif
+
+#ifndef DK4STAT_H_INCLUDED
+#include "dk4stat.h"
+#endif
+
+#ifndef DK4DIR_H_INCLUDED
+#include "dk4dir.h"
+#endif
+
+#ifndef DK4DIRA_H_INCLUDED
+#include "dk4dira.h"
+#endif
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4MEMA_H_INCLUDED
+#include "dk4mema.h"
+#endif
+
+#ifndef DK4MPL_H_INCLUDED
+#include "dk4mpl.h"
+#endif
+
+#ifndef DK4STR_H_INCLUDED
+#include "dk4strd.h"
+#endif
+
+#ifndef DK4MAASZ_H_INCLUDED
+#include "dk4maasz.h"
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_DIRENT_H
+#ifndef DIRENT_H_INCLUDED
+#include <dirent.h>
+#define DIRENT_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_HAVE_WCHAR_H
+#ifndef WCHAR_H_INCLUDED
+#include <wchar.h>
+#define WCHAR_H_INCLUDED 1
+#endif
+#endif
+#endif
+
+
+$!trace-include
+
+
+
+/** Information about failed removals of files or directories.
+*/
+enum {
+ /** No errors yet.
+ */
+ NE_NO_ERROR = 0,
+
+ /** Failed to remove one file.
+ */
+ NE_ONE_FILE_REMOVAL_FAILED ,
+
+ /** Failed to remove multiple files.
+ */
+ NE_MULTIPLE_FILE_REMOVALS_FAILED ,
+
+ /** Failed to remove one directory.
+ */
+ NE_ONE_DIRECTORY_REMOVAL_FAILED ,
+
+ /** Failed to remove multiple dirs.
+ */
+ NE_MULTIPLE_DIRECTORY_REMOVALS_FAILED
+};
+
+
+
+/** One node in tree to delete.
+*/
+typedef struct _dk4_del_tree_node_t_ {
+ struct _dk4_del_tree_node_t_ *parent; /**< Parent node. */
+ dk4_dir_t *dir; /**< Directory contents. */
+ size_t dplen; /**< Directory path length. */
+ int ne; /**< Flag: Not empty. */
+} dk4_del_tree_node_t;
+
+
+
+/** Job structure (information passed downwards).
+*/
+typedef struct {
+ dkChar *sbptr; /**< Static buffer. */
+ dkChar *dbptr; /**< Dynamic buffer, may be NULL. */
+ size_t sbsz; /**< Static buffer size. */
+ size_t dbsz; /**< Dynamic buffer size. */
+ int result; /**< Suggested function result. */
+} dk4_del_tree_job_t;
+
+
+
+#if DK4_ON_WINDOWS
+/* +++ Windows */
+#if DK4_CHAR_SIZE > 1
+/* +++ Windows, wchar_t */
+
+/* --- Windows, wchar_t */
+#else
+/* +++ Windows, char */
+
+/* --- Windows, char */
+#endif
+
+static
+int
+dk4app_del_tree_process_dir(const dkChar *dirname)
+{
+#if DK4_CHAR_SIZE > 1
+ WIN32_FIND_DATAW ff;
+#else
+ WIN32_FIND_DATAA ff;
+#endif
+ DWORD dwFileAttributes;
+ HANDLE ha;
+ int back = 1;
+
+#if DK4_CHAR_SIZE > 1
+ dwFileAttributes = GetFileAttributesW(dirname);
+#else
+ dwFileAttributes = GetFileAttributesA(dirname);
+#endif
+ if (INVALID_FILE_ATTRIBUTES == dwFileAttributes) {
+#if DK4_CHAR_SIZE > 1
+ ha = FindFirstFileW(dirname, &ff);
+#else
+ ha = FindFirstFileA(dirname, &ff);
+#endif
+ if (INVALID_HANDLE_VALUE != ha) {
+ dwFileAttributes = ff.dwFileAttributes;
+ FindClose(ha);
+ }
+ }
+ if (INVALID_FILE_ATTRIBUTES != dwFileAttributes) {
+ if (0 != (FILE_ATTRIBUTE_REPARSE_POINT & dwFileAttributes)) {
+#if DK4_CHAR_SIZE > 1
+ ha = FindFirstFileW(dirname, &ff);
+#else
+ ha = FindFirstFileA(dirname, &ff);
+#endif
+ if (INVALID_HANDLE_VALUE != ha) {
+ if (0 != (FILE_ATTRIBUTE_REPARSE_POINT & ff.dwFileAttributes)) {
+ if (IO_REPARSE_TAG_MOUNT_POINT == ff.dwReserved0) {
+ back = 0;
+ }
+ if (IO_REPARSE_TAG_SYMLINK == ff.dwReserved0) {
+ back = 0;
+ }
+ }
+ FindClose(ha);
+ } else {
+ back = 0;
+ }
+ }
+ }
+ return back;
+}
+
+/* --- Windows */
+#else
+/* +++ non-Windows */
+#if DK4_CHAR_SIZE > 1
+/* +++ non-Windows, wchar_t */
+
+/* --- non-Windows, wchar_t */
+#else
+/* +++ non-Windows, char */
+
+/* --- non-Windows, char */
+#endif
+/* --- non-Windows */
+#endif
+
+
+
+#if DK4_HAVE_BACKSLASH_AS_SEP
+static const dkChar dk4appdeltree_fnsep[] = { dkT("\\") };
+#else
+static const dkChar dk4appdeltree_fnsep[] = { dkT("/") };
+#endif
+
+
+
+static
+void
+dk4app_del_tree_node_close(dk4_del_tree_node_t *ptr)
+{
+ if (NULL != ptr) {
+ ptr->parent = NULL;
+ if (NULL != ptr->dir) {
+ dk4dir_close(ptr->dir);
+ ptr->dir = NULL;
+ }
+ ptr->dplen = 0;
+ ptr->ne = 0;
+ dk4mem_free(ptr);
+ }
+}
+
+
+
+static
+dk4_del_tree_node_t *
+dk4app_del_tree_node_open(
+ const dkChar *dn,
+ dk4_del_tree_node_t *par,
+ dk4_del_tree_job_t *job,
+ dk4_app_t *app
+)
+{
+ dk4_er_t er; /* Error report */
+ const dkChar *fn; /* File name to process */
+ dkChar *nbptr; /* Buffer pointer */
+ dk4_del_tree_node_t *back = NULL;
+ size_t lgt; /* Length of buffer */
+#if VERSION_BEFORE_20150821 || TRACE_DEBUG
+ int dfres; /* Result from file deletion */
+#endif
+ $? "+ dk4_del_tree_node_t \"%!ds\"", dn
+ back = dk4mem_new_app(dk4_del_tree_node_t,1,app);
+ if (NULL != back) { $? ". memory ok"
+ back->parent = par;
+ back->ne = NE_NO_ERROR;
+ back->dplen = dk4str_len(dn);
+ dk4error_init(&er);
+ back->dir = dk4dir_open_app(dn, DK4_DIR_OPEN_DELTREE, app);
+ if (NULL != back->dir) { $? ". dir open ok"
+ dk4error_init(&er);
+ lgt = dk4ma_size_t_add(
+ dk4ma_size_t_add(
+ back->dplen, dk4dir_get_max_entry_length(back->dir), &er
+ ),
+ 2,
+ &er
+ );
+ if (DK4_E_NONE == er.ec) { $? ". buffer length calculated"
+ if ((lgt > job->sbsz) && (lgt > job->dbsz)) {
+ $? ". NEED %u", (unsigned)lgt
+ nbptr = dk4mem_new_app(dkChar,lgt,app);
+ if (NULL != nbptr) { $? ". new buffer allocated"
+ if (job->dbptr) {
+ dk4mem_free(job->dbptr); $? ". RELEASE dbptr"
+ }
+ job->dbptr = nbptr; job->dbsz = lgt; $? ". ALLOC dbptr"
+ } else { $? "! allocation"
+ dk4app_del_tree_node_close(back);
+ back = NULL;
+ job->result = 0;
+ }
+ }
+ if (NULL != back) {
+ if ((NULL != job->dbptr) && (0 < job->dbsz)) {
+ nbptr = job->dbptr; $? ". use dynamic buffer"
+ lgt = job->dbsz;
+ } else { $? ". use static buffer"
+ nbptr = job->sbptr;
+ lgt = job->sbsz;
+ } $? ". process files"
+ do {
+ fn = dk4dir_next_file(back->dir);
+ if (NULL != fn) { $? ". processing file \"%!ds\" \"%!ds\"", dn, fn
+ if (dk4str_cpy_s(nbptr,lgt,dk4dir_get_path(back->dir),NULL)) {
+ $? ". nbptr=\"%!ds\" dn=\"%!ds\"", nbptr, dk4dir_get_path(back->dir)
+ if (dk4str_cat_s(nbptr, lgt, dk4appdeltree_fnsep, NULL)) {
+ $? ". nbptr=\"%!ds\" dn=\"%!ds\"",nbptr,dk4dir_get_path(back->dir)
+ if (dk4str_cat_s(nbptr, lgt, fn, NULL)) {
+ $? ". nbptr=\"%!ds\" dn=\"%!ds\"",nbptr,dk4dir_get_path(back->dir)
+ $? ". full path name \"%!ds\"", nbptr
+ switch (back->ne) {
+ case NE_NO_ERROR : {
+ if (0 == dk4app_del_file(nbptr, app)) {
+ back->ne = NE_ONE_FILE_REMOVAL_FAILED;
+ job->result = 0;
+ $? "! file deletion failed"
+ }
+ } break;
+ case NE_ONE_FILE_REMOVAL_FAILED : {
+ if (0 == dk4app_del_file(nbptr, NULL)) {
+ back->ne = NE_MULTIPLE_FILE_REMOVALS_FAILED;
+ /* ERROR: Further file removals failed */
+ dk4app_log_base3(
+ app,DK4_LL_ERROR,94,95,dk4dir_get_path(back->dir)
+ );
+ $? "! file deletion failed"
+ }
+ } break;
+ default : {
+#if TRACE_DEBUG
+ dfres = dk4app_del_file(nbptr, NULL);
+ if (0 == dfres) { $? "! file deletion failed"
+ }
+#else
+ dk4app_del_file(nbptr, NULL);
+#endif
+ } break;
+ }
+ } else { $? "! buffer too short"
+ if (NE_ONE_FILE_REMOVAL_FAILED < back->ne) {
+ back->ne = NE_ONE_FILE_REMOVAL_FAILED;
+ }
+ /* ERROR: Directory name too long */
+ dk4app_log_base3(
+ app, DK4_LL_ERROR, 98, 99, dk4dir_get_path(back->dir)
+ );
+ }
+ } else { $? "! buffer too short"
+ if (NE_ONE_FILE_REMOVAL_FAILED < back->ne) {
+ back->ne = NE_ONE_FILE_REMOVAL_FAILED;
+ }
+ /* ERROR: Directory name too long */
+ dk4app_log_base3(
+ app, DK4_LL_ERROR, 98, 99, dk4dir_get_path(back->dir)
+ );
+ }
+ } else { $? "! buffer too short"
+ if (NE_ONE_FILE_REMOVAL_FAILED < back->ne) {
+ back->ne = NE_ONE_FILE_REMOVAL_FAILED;
+ }
+ /* ERROR: Directory name too long */
+ dk4app_log_base3(
+ app, DK4_LL_ERROR, 98, 99, dk4dir_get_path(back->dir)
+ );
+ }
+ }
+ } while(NULL != fn);
+ dk4dir_skip_files(back->dir);
+ } else { $? "! allocation"
+ }
+ } else { $? "! overflow in buffer length calc"
+ /* ERROR: Math error in size calculation */
+ dk4app_log_base1(app, DK4_LL_ERROR, 82);
+ dk4app_del_tree_node_close(back);
+ back = NULL;
+ job->result = 0;
+ }
+ } else { $? "! dir open"
+ dk4app_del_tree_node_close(back);
+ back = NULL;
+ job->result = 0;
+ /* ERROR: Failed to open directory, already reported */
+ /* !!!!! TODO: Attempt to remove directory or file */
+ }
+ } else { $? "! memory"
+ }
+ $? "- dk4_del_tree_node_t PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+static
+void
+dk4app_del_tree_debug_file_or_dir(
+ dk4_app_t *app,
+ const dkChar *fn,
+ size_t ind
+)
+{
+ const dkChar *msg[3];
+ if ((NULL != app) && (NULL != fn)) {
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ if ((NULL != app->msg_debug) && (ind < app->sz_msg_debug)) {
+ msg[0] = (app->msg_debug)[ind];
+ msg[1] = fn;
+ msg[2] = NULL;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 2);
+ }
+ }
+ }
+}
+
+
+
+int
+dk4app_del_tree(const dkChar *fn, dk4_app_t *app)
+{
+ dkChar sb[DK4_MAX_PATH];
+ dk4_del_tree_job_t job; /* Buffers */
+ dk4_del_tree_node_t *cn; /* Current node */
+ dk4_del_tree_node_t *nn; /* Next node */
+ dkChar *fnb; /* File name buffer */
+ const dkChar *dn; /* Directory name */
+ size_t fnbsz; /* File name buffer size */
+ int res; /* Operation result */
+#if VERSION_BEFORE_20150821 || TRACE_DEBUG
+ int dfres; /* Delete file result */
+#endif
+ int back = 0;
+
+ $? "+ dk4app_del_tree \"%!ds\"", TR_DKSTR(fn)
+ job.sbptr = sb;
+ job.sbsz = DK4_SIZEOF(sb,dkChar);
+ job.dbptr = NULL;
+ job.dbsz = 0;
+ job.result = 1;
+ if (NULL != fn) { $? ". directory name ok"
+ cn = dk4app_del_tree_node_open(fn, NULL, &job, app);
+ if (NULL != cn) { $? ". node ok"
+ while (NULL != cn) { $? ". start of loop"
+ if ((NULL != job.dbptr) && (0 < job.dbsz)) {
+ fnb = job.dbptr; fnbsz = job.dbsz; $? ". use dynamic buffer"
+ } else { $? ". use static buffer"
+ fnb = job.sbptr; fnbsz = job.sbsz;
+ }
+ dn = dk4dir_next_dir(cn->dir);
+ if (NULL != dn) { $? ". subdirectory found"
+ if (0 != dk4str_cpy_s(fnb, fnbsz, dk4dir_get_path(cn->dir), NULL)) {
+ if (0 != dk4str_cat_s(fnb, fnbsz, dk4appdeltree_fnsep, NULL)) {
+ if (0 != dk4str_cat_s(fnb, fnbsz, dn, NULL)) { $? ". fnb=%!ds",fnb
+#if DK4_ON_WINDOWS
+ res = dk4app_del_tree_process_dir(fnb);
+#else
+ res = 1;
+#endif
+ if (0 != res) { $? ". directory processing"
+ nn = dk4app_del_tree_node_open(fnb, cn, &job, app);
+ if (NULL != nn) {
+ cn = nn;
+ } else {
+ job.result = 0;
+ }
+ } else { $? ". no directory processing"
+ switch (cn->ne) {
+ case NE_NO_ERROR:
+ case NE_ONE_FILE_REMOVAL_FAILED:
+ case NE_MULTIPLE_FILE_REMOVALS_FAILED: {
+ dk4app_del_tree_debug_file_or_dir(app, fnb, 27);
+ if (0 == dk4app_del_dir(fnb, NULL)) {
+ if (0 == dk4app_del_file(fnb, NULL)) {
+ job.result = 0;
+ cn->ne = NE_ONE_DIRECTORY_REMOVAL_FAILED;
+ dk4app_log_base3(app, DK4_LL_ERROR, 66, 77, fnb);
+ $? "! file deletion failed"
+ }
+ }
+ } break;
+ case NE_ONE_DIRECTORY_REMOVAL_FAILED: {
+ dk4app_del_tree_debug_file_or_dir(app, fnb, 27);
+ if (0 == dk4app_del_dir(fnb, NULL)) {
+ if (0 == dk4app_del_file(fnb, NULL)) {
+ job.result = 0;
+ cn->ne = NE_MULTIPLE_DIRECTORY_REMOVALS_FAILED;
+ dk4app_log_base3(
+ app, DK4_LL_ERROR, 96, 97, dk4dir_get_path(cn->dir)
+ );
+ $? "! file deletion failed"
+ }
+ }
+ } break;
+ default: {
+ dk4app_del_tree_debug_file_or_dir(app, fnb, 27);
+ if (0 == dk4app_del_dir(fnb, NULL)) {
+#if TRACE_DEBUG
+ dfres = dk4app_del_file(fnb, NULL);
+ if (0 == dfres) { $? "! file deletion failed"
+ }
+#else
+ dk4app_del_file(fnb, NULL);
+#endif
+ }
+ } break;
+ }
+ }
+ } else { $? "! buffer too small"
+ /* ERROR: Directory name too long! */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, dn);
+ job.result = 0;
+ }
+ } else { $? "! buffer too small"
+ /* ERROR: Directory name too long! */
+ dk4app_log_base3(app,DK4_LL_ERROR,98,99,dk4dir_get_path(cn->dir));
+ job.result = 0;
+ }
+ } else { $? "! buffer too small"
+ /* ERROR: Directory name too long! */
+ dk4app_log_base3(app,DK4_LL_ERROR,98,99,dk4dir_get_path(cn->dir));
+ job.result = 0;
+ }
+ } else { $? ". no more subdirectories"
+ nn = cn->parent;
+ if (NULL != nn) { $? ". propagate errors"
+ switch (nn->ne) {
+ case NE_NO_ERROR:
+ case NE_ONE_FILE_REMOVAL_FAILED:
+ case NE_MULTIPLE_FILE_REMOVALS_FAILED: {
+ if (0 == dk4app_del_dir(dk4dir_get_path(cn->dir), app)) {
+ job.result = 0;
+ nn->ne = NE_ONE_DIRECTORY_REMOVAL_FAILED;
+ }
+ } break;
+ case NE_ONE_DIRECTORY_REMOVAL_FAILED: {
+ dk4app_del_tree_debug_file_or_dir(
+ app, dk4dir_get_path(cn->dir), 25
+ );
+ if (0 == dk4app_del_dir(dk4dir_get_path(cn->dir), NULL)) {
+ job.result = 0;
+ nn->ne = NE_MULTIPLE_DIRECTORY_REMOVALS_FAILED;
+ dk4app_log_base3(
+ app, DK4_LL_ERROR, 96, 97, dk4dir_get_path(nn->dir)
+ );
+ }
+ } break;
+ default: {
+ dk4app_del_tree_debug_file_or_dir(
+ app, dk4dir_get_path(cn->dir), 25
+ );
+ (void)dk4app_del_dir(dk4dir_get_path(cn->dir), NULL);
+ } break;
+ }
+ } else { $? ". no parent directory"
+ if (0 == dk4app_del_dir(dk4dir_get_path(cn->dir), app)) {
+ job.result = 0;
+ }
+ }
+ dk4app_del_tree_node_close(cn);
+ cn = nn;
+ }
+ }
+ } else { $? "! node"
+ }
+ } else { $? "! directory name"
+ }
+ if ((NULL != job.dbptr) && (0 < job.dbsz)) {
+ dk4mem_free(job.dbptr); $? ". RELEASE dbptr"
+ }
+ back = job.result;
+ $? "- dk4app_del_tree %d", back
+ return back;
+}
+
+
diff --git a/support/dktools/dk4appenc.c b/support/dktools/dk4appenc.c
new file mode 100644
index 0000000000..466ab4e08d
--- /dev/null
+++ b/support/dktools/dk4appenc.c
@@ -0,0 +1,156 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4appenc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4appenc.c The dk4appenc module.
+*/
+
+
+#line 10 "dk4appenc.ctr"
+
+#include "dk4app.h"
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4ENC_H_INCLUDED
+#include "dk4enc.h"
+#endif
+
+#ifndef DK4LOC_H_INCLUDED
+#include "dk4loc.h"
+#endif
+
+
+
+
+
+#line 28 "dk4appenc.ctr"
+
+
+
+static
+int
+dk4app_get_encoding_without_app(int *dptr)
+{
+ dkChar l[64];
+ dkChar r[64];
+ return (
+ dk4loc_get_settings(l,DK4_SIZEOF(l,dkChar),r,DK4_SIZEOF(r,dkChar),dptr,NULL)
+ );
+}
+
+
+
+
+int
+dk4app_get_encoding(dk4_app_t *app)
+{
+ int back;
+ if (NULL != app) {
+ back = app->encoding;
+ } else {
+ if (0 == dk4app_get_encoding_without_app(&back)) {
+ back = DK4_FILE_ENCODING_ASCII;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4app_get_stdin_encoding(dk4_app_t *app)
+{
+ int back;
+ if (NULL != app) {
+ back = app->enc_in_std;
+ } else {
+ if (0 == dk4app_get_encoding_without_app(&back)) {
+ back = DK4_FILE_ENCODING_ASCII;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4app_get_file_in_encoding(dk4_app_t *app)
+{
+ int back;
+ if (NULL != app) {
+ back = app->enc_in_file;
+ } else {
+ if (0 == dk4app_get_encoding_without_app(&back)) {
+ back = DK4_FILE_ENCODING_ASCII;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4app_get_stdout_encoding(dk4_app_t *app)
+{
+ int back;
+ if (NULL != app) {
+ back = app->enc_out_std;
+ } else {
+ if (0 == dk4app_get_encoding_without_app(&back)) {
+ back = DK4_FILE_ENCODING_ASCII;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4app_get_file_out_encoding(dk4_app_t *app)
+{
+ int back;
+ if (NULL != app) {
+ back = app->enc_out_file;
+ } else {
+ if (0 == dk4app_get_encoding_without_app(&back)) {
+ back = DK4_FILE_ENCODING_ASCII;
+ }
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4appenc.ctr b/support/dktools/dk4appenc.ctr
new file mode 100644
index 0000000000..99314a5930
--- /dev/null
+++ b/support/dktools/dk4appenc.ctr
@@ -0,0 +1,123 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4app.h"
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4ENC_H_INCLUDED
+#include "dk4enc.h"
+#endif
+
+#ifndef DK4LOC_H_INCLUDED
+#include "dk4loc.h"
+#endif
+
+
+
+$!trace-include
+
+
+
+static
+int
+dk4app_get_encoding_without_app(int *dptr)
+{
+ dkChar l[64];
+ dkChar r[64];
+ return (
+ dk4loc_get_settings(l,DK4_SIZEOF(l,dkChar),r,DK4_SIZEOF(r,dkChar),dptr,NULL)
+ );
+}
+
+
+
+
+int
+dk4app_get_encoding(dk4_app_t *app)
+{
+ int back;
+ if (NULL != app) {
+ back = app->encoding;
+ } else {
+ if (0 == dk4app_get_encoding_without_app(&back)) {
+ back = DK4_FILE_ENCODING_ASCII;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4app_get_stdin_encoding(dk4_app_t *app)
+{
+ int back;
+ if (NULL != app) {
+ back = app->enc_in_std;
+ } else {
+ if (0 == dk4app_get_encoding_without_app(&back)) {
+ back = DK4_FILE_ENCODING_ASCII;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4app_get_file_in_encoding(dk4_app_t *app)
+{
+ int back;
+ if (NULL != app) {
+ back = app->enc_in_file;
+ } else {
+ if (0 == dk4app_get_encoding_without_app(&back)) {
+ back = DK4_FILE_ENCODING_ASCII;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4app_get_stdout_encoding(dk4_app_t *app)
+{
+ int back;
+ if (NULL != app) {
+ back = app->enc_out_std;
+ } else {
+ if (0 == dk4app_get_encoding_without_app(&back)) {
+ back = DK4_FILE_ENCODING_ASCII;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4app_get_file_out_encoding(dk4_app_t *app)
+{
+ int back;
+ if (NULL != app) {
+ back = app->enc_out_file;
+ } else {
+ if (0 == dk4app_get_encoding_without_app(&back)) {
+ back = DK4_FILE_ENCODING_ASCII;
+ }
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4appfne.c b/support/dktools/dk4appfne.c
new file mode 100644
index 0000000000..a8853505af
--- /dev/null
+++ b/support/dktools/dk4appfne.c
@@ -0,0 +1,144 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4appfne.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4appfne.c The dk4appfne module.
+*/
+
+
+#line 10 "dk4appfne.ctr"
+
+#include "dk4app.h"
+
+#ifndef DK4CONST_H_INCLUDED
+#include "dk4const.h"
+#endif
+
+#ifndef DK4FNE_H_INCLUDED
+#include "dk4fne.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4STRD_H_INCLUDED
+#include "dk4strd.h"
+#endif
+
+
+
+dk4_dir_t *
+dk4app_fne_open(const dkChar *pattern, dk4_app_t *app)
+{
+ dk4_er_t er;
+ dk4_dir_t *back = NULL;
+ if (NULL != pattern) {
+ dk4error_init(&er);
+ back = dk4fne_open(pattern, &er);
+ if (NULL == back) {
+ switch (er.ec) {
+ case DK4_E_NOT_SUPPORTED: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 102, pattern);
+ } break;
+ case DK4_E_MEMORY_ALLOCATION_FAILED: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 103, pattern);
+ } break;
+ case DK4_E_BUFFER_TOO_SMALL: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 105, pattern);
+ } break;
+ case DK4_E_OPENDIR_FAILED:
+ case DK4_E_FINDFIRSTFILE_FAILED: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 104, pattern);
+ } break;
+ default: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 101, pattern);
+ } break;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4app_fne_one_file(
+ dkChar *dptr,
+ size_t szdptr,
+ dk4_dir_t *fne,
+ const dkChar *pattern,
+ dk4_app_t *app
+)
+{
+ const dkChar *dirname;
+ const dkChar *filename;
+ int back = 0;
+ if ((NULL != dptr) && (NULL != fne) && (0 < szdptr)) {
+ dirname = dk4dir_get_path(fne);
+ filename = dk4dir_next_file(fne);
+ if (NULL != filename) {
+ if (NULL != dirname) {
+ if (0 != dk4str_cpy_s(dptr, szdptr, dirname, NULL)) {
+ if (0 != dk4str_cat_s(dptr, szdptr, dkT("\\"), NULL)) {
+ back = dk4str_cat_s(dptr, szdptr, filename, NULL);
+ if (0 == back) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 105, pattern);
+ }
+ } else {
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 105, pattern);
+ }
+ } else {
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 105, pattern);
+ }
+ } else {
+ back = dk4str_cpy_s(dptr, szdptr, filename, NULL);
+ if (0 == back) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 105, pattern);
+ }
+ }
+ if (0 != back) {
+ filename = dk4dir_next_file(fne);
+ if (NULL != filename) {
+ back = 0;
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 106, pattern);
+ }
+ }
+ } else {
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 107, pattern);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4appfne.ctr b/support/dktools/dk4appfne.ctr
new file mode 100644
index 0000000000..afb9538690
--- /dev/null
+++ b/support/dktools/dk4appfne.ctr
@@ -0,0 +1,113 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4app.h"
+
+#ifndef DK4CONST_H_INCLUDED
+#include "dk4const.h"
+#endif
+
+#ifndef DK4FNE_H_INCLUDED
+#include "dk4fne.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4STRD_H_INCLUDED
+#include "dk4strd.h"
+#endif
+
+
+
+dk4_dir_t *
+dk4app_fne_open(const dkChar *pattern, dk4_app_t *app)
+{
+ dk4_er_t er;
+ dk4_dir_t *back = NULL;
+ if (NULL != pattern) {
+ dk4error_init(&er);
+ back = dk4fne_open(pattern, &er);
+ if (NULL == back) {
+ switch (er.ec) {
+ case DK4_E_NOT_SUPPORTED: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 102, pattern);
+ } break;
+ case DK4_E_MEMORY_ALLOCATION_FAILED: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 103, pattern);
+ } break;
+ case DK4_E_BUFFER_TOO_SMALL: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 105, pattern);
+ } break;
+ case DK4_E_OPENDIR_FAILED:
+ case DK4_E_FINDFIRSTFILE_FAILED: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 104, pattern);
+ } break;
+ default: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 101, pattern);
+ } break;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4app_fne_one_file(
+ dkChar *dptr,
+ size_t szdptr,
+ dk4_dir_t *fne,
+ const dkChar *pattern,
+ dk4_app_t *app
+)
+{
+ const dkChar *dirname;
+ const dkChar *filename;
+ int back = 0;
+ if ((NULL != dptr) && (NULL != fne) && (0 < szdptr)) {
+ dirname = dk4dir_get_path(fne);
+ filename = dk4dir_next_file(fne);
+ if (NULL != filename) {
+ if (NULL != dirname) {
+ if (0 != dk4str_cpy_s(dptr, szdptr, dirname, NULL)) {
+ if (0 != dk4str_cat_s(dptr, szdptr, dkT("\\"), NULL)) {
+ back = dk4str_cat_s(dptr, szdptr, filename, NULL);
+ if (0 == back) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 105, pattern);
+ }
+ } else {
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 105, pattern);
+ }
+ } else {
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 105, pattern);
+ }
+ } else {
+ back = dk4str_cpy_s(dptr, szdptr, filename, NULL);
+ if (0 == back) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 105, pattern);
+ }
+ }
+ if (0 != back) {
+ filename = dk4dir_next_file(fne);
+ if (NULL != filename) {
+ back = 0;
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 106, pattern);
+ }
+ }
+ } else {
+ dk4app_log_base3(app, DK4_LL_ERROR, 100, 107, pattern);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4appfs01.c b/support/dktools/dk4appfs01.c
new file mode 100644
index 0000000000..17fe53ba04
--- /dev/null
+++ b/support/dktools/dk4appfs01.c
@@ -0,0 +1,113 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4appfs01.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4appfs01.c The dk4appfs01 module.
+*/
+
+
+#line 10 "dk4appfs01.ctr"
+
+#ifndef DK4APP_H_INCLUDED
+#include "dk4app.h"
+#endif
+
+#ifndef DK4FS_H_INCLUDED
+#include "dk4fs.h"
+#endif
+
+
+
+int
+dk4app_search_one_config_file(
+ dkChar *dptr,
+ size_t szdptr,
+ dk4_app_t *app,
+ const dkChar *shortname,
+ int passno,
+ int compressed,
+ dk4_er_t *erp
+)
+{
+#if VERSION_BEFORE_2017_03_09
+ int back = 0;
+ if ((NULL != dptr) && (0 < szdptr) && (NULL != app) && (NULL != shortname)) {
+ back = dk4fs_config_one(
+ dptr, szdptr, shortname,
+ app->dir_share, app->dir_etc, app->user_home,
+ app->prog_name, app->group_name, passno, compressed, erp
+ );
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ const char *msg[3];
+ int back = 0;
+ if ((NULL != dptr) && (0 < szdptr) && (NULL != app) && (NULL != shortname)) {
+ back = dk4fs_config_construct_compat_one(
+ dptr, szdptr, shortname,
+ app->dir_share, app->dir_etc, app->user_home,
+ app->prog_name, app->group_name,
+ passno, 0, erp
+ );
+ if (0 != back) {
+ back = dk4fs_attempt_file_name(dptr, szdptr, compressed, erp);
+ if (0 != back) {
+ /* Success */
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ if ((NULL != app->msg_debug) && (30 < app->sz_msg_debug)) {
+ msg[0] = (app->msg_debug)[30];
+ msg[1] = dptr;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 2);
+ }
+ }
+ } else {
+ /* Failed */
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ if ((NULL != app->msg_debug) && (31 < app->sz_msg_debug)) {
+ msg[0] = (app->msg_debug)[31];
+ msg[1] = dptr;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 2);
+ }
+ }
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#endif
+}
+
diff --git a/support/dktools/dk4appfs01.ctr b/support/dktools/dk4appfs01.ctr
new file mode 100644
index 0000000000..388d495215
--- /dev/null
+++ b/support/dktools/dk4appfs01.ctr
@@ -0,0 +1,82 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#ifndef DK4APP_H_INCLUDED
+#include "dk4app.h"
+#endif
+
+#ifndef DK4FS_H_INCLUDED
+#include "dk4fs.h"
+#endif
+
+
+
+int
+dk4app_search_one_config_file(
+ dkChar *dptr,
+ size_t szdptr,
+ dk4_app_t *app,
+ const dkChar *shortname,
+ int passno,
+ int compressed,
+ dk4_er_t *erp
+)
+{
+#if VERSION_BEFORE_2017_03_09
+ int back = 0;
+ if ((NULL != dptr) && (0 < szdptr) && (NULL != app) && (NULL != shortname)) {
+ back = dk4fs_config_one(
+ dptr, szdptr, shortname,
+ app->dir_share, app->dir_etc, app->user_home,
+ app->prog_name, app->group_name, passno, compressed, erp
+ );
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ const char *msg[3];
+ int back = 0;
+ if ((NULL != dptr) && (0 < szdptr) && (NULL != app) && (NULL != shortname)) {
+ back = dk4fs_config_construct_compat_one(
+ dptr, szdptr, shortname,
+ app->dir_share, app->dir_etc, app->user_home,
+ app->prog_name, app->group_name,
+ passno, 0, erp
+ );
+ if (0 != back) {
+ back = dk4fs_attempt_file_name(dptr, szdptr, compressed, erp);
+ if (0 != back) {
+ /* Success */
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ if ((NULL != app->msg_debug) && (30 < app->sz_msg_debug)) {
+ msg[0] = (app->msg_debug)[30];
+ msg[1] = dptr;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 2);
+ }
+ }
+ } else {
+ /* Failed */
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ if ((NULL != app->msg_debug) && (31 < app->sz_msg_debug)) {
+ msg[0] = (app->msg_debug)[31];
+ msg[1] = dptr;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 2);
+ }
+ }
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#endif
+}
+
diff --git a/support/dktools/dk4appfs02.c b/support/dktools/dk4appfs02.c
new file mode 100644
index 0000000000..442e5abc1d
--- /dev/null
+++ b/support/dktools/dk4appfs02.c
@@ -0,0 +1,143 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4appfs02.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4appfs02.c The dk4appfs02 module.
+*/
+
+
+#line 10 "dk4appfs02.ctr"
+
+#ifndef DK4APP_H_INCLUDED
+#include "dk4app.h"
+#endif
+
+#ifndef DK4FS_H_INCLUDED
+#include "dk4fs.h"
+#endif
+
+
+
+
+
+#line 22 "dk4appfs02.ctr"
+
+
+
+int
+dk4app_search_one_data_file(
+ dkChar *dptr,
+ size_t szdptr,
+ dk4_app_t *app,
+ const dkChar *shortname,
+ int passno,
+ int compressed,
+ dk4_er_t *erp
+)
+{
+#if VERSION_BEFORE_2017_03_09
+ int back = 0;
+
+
+#line 39 "dk4appfs02.ctr"
+ if ((NULL != dptr) && (0 < szdptr) && (NULL != app) && (NULL != shortname)) {
+
+
+#line 41 "dk4appfs02.ctr"
+
+
+#line 42 "dk4appfs02.ctr"
+ back = dk4fs_data_one(
+ dptr, szdptr, shortname,
+ app->dir_share, app->user_home,
+ app->prog_name, app->group_name, app->language, app->region,
+ passno, compressed, erp
+ );
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 52 "dk4appfs02.ctr"
+ return back;
+#else
+ const char *msg[3];
+ int back = 0;
+
+
+#line 57 "dk4appfs02.ctr"
+ if ((NULL != dptr) && (0 < szdptr) && (NULL != app) && (NULL != shortname)) {
+
+
+#line 59 "dk4appfs02.ctr"
+
+
+#line 60 "dk4appfs02.ctr"
+ back = dk4fs_data_construct_one(
+ dptr, szdptr, shortname,
+ app->dir_share, app->language, app->region, app->user_home,
+ app->prog_name, app->group_name, passno, erp
+ );
+ if (0 != back) {
+ back = dk4fs_attempt_file_name(dptr, szdptr, compressed, erp);
+ if (0 != back) {
+ /* Success */
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ if ((NULL != app->msg_debug) && (30 < app->sz_msg_debug)) {
+ msg[0] = (app->msg_debug)[30];
+ msg[1] = dptr;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 2);
+ }
+ }
+ } else {
+ /* Failed */
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ if ((NULL != app->msg_debug) && (31 < app->sz_msg_debug)) {
+ msg[0] = (app->msg_debug)[31];
+ msg[1] = dptr;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 2);
+ }
+ }
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 91 "dk4appfs02.ctr"
+ return back;
+#endif
+}
+
diff --git a/support/dktools/dk4appfs02.ctr b/support/dktools/dk4appfs02.ctr
new file mode 100644
index 0000000000..4ef2443c3e
--- /dev/null
+++ b/support/dktools/dk4appfs02.ctr
@@ -0,0 +1,94 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#ifndef DK4APP_H_INCLUDED
+#include "dk4app.h"
+#endif
+
+#ifndef DK4FS_H_INCLUDED
+#include "dk4fs.h"
+#endif
+
+
+
+$!trace-include
+
+
+
+int
+dk4app_search_one_data_file(
+ dkChar *dptr,
+ size_t szdptr,
+ dk4_app_t *app,
+ const dkChar *shortname,
+ int passno,
+ int compressed,
+ dk4_er_t *erp
+)
+{
+#if VERSION_BEFORE_2017_03_09
+ int back = 0;
+ $? "+ dk4app_search_one_data_file \"%!ds\"", TR_DKSTR(shortname)
+ if ((NULL != dptr) && (0 < szdptr) && (NULL != app) && (NULL != shortname)) {
+ $? ". language = \"%!ds\"", app->language
+ $? ". region = \"%!ds\"", app->region
+ back = dk4fs_data_one(
+ dptr, szdptr, shortname,
+ app->dir_share, app->user_home,
+ app->prog_name, app->group_name, app->language, app->region,
+ passno, compressed, erp
+ );
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4app_search_one_data_file %d", back
+ return back;
+#else
+ const char *msg[3];
+ int back = 0;
+ $? "+ dk4app_search_one_data_file \"%!ds\"", TR_DKSTR(shortname)
+ if ((NULL != dptr) && (0 < szdptr) && (NULL != app) && (NULL != shortname)) {
+ $? ". language = \"%!ds\"", app->language
+ $? ". region = \"%!ds\"", app->region
+ back = dk4fs_data_construct_one(
+ dptr, szdptr, shortname,
+ app->dir_share, app->language, app->region, app->user_home,
+ app->prog_name, app->group_name, passno, erp
+ );
+ if (0 != back) {
+ back = dk4fs_attempt_file_name(dptr, szdptr, compressed, erp);
+ if (0 != back) {
+ /* Success */
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ if ((NULL != app->msg_debug) && (30 < app->sz_msg_debug)) {
+ msg[0] = (app->msg_debug)[30];
+ msg[1] = dptr;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 2);
+ }
+ }
+ } else {
+ /* Failed */
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ if ((NULL != app->msg_debug) && (31 < app->sz_msg_debug)) {
+ msg[0] = (app->msg_debug)[31];
+ msg[1] = dptr;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 2);
+ }
+ }
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4app_search_one_data_file %d", back
+ return back;
+#endif
+}
+
diff --git a/support/dktools/dk4appfs03.c b/support/dktools/dk4appfs03.c
new file mode 100644
index 0000000000..0e93541847
--- /dev/null
+++ b/support/dktools/dk4appfs03.c
@@ -0,0 +1,176 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4appfs03.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4appfs03.c The dk4appfs03 module.
+*/
+
+
+#line 10 "dk4appfs03.ctr"
+
+#ifndef DK4APP_H_INCLUDED
+#include "dk4app.h"
+#endif
+
+#ifndef DK4FS_H_INCLUDED
+#include "dk4fs.h"
+#endif
+
+#ifndef DK4CONST_H_INCLUDED
+#include "dk4const.h"
+#endif
+
+
+
+
+
+#line 26 "dk4appfs03.ctr"
+
+
+
+static
+int
+dk4app_search_i_data_file(
+ dkChar *dptr,
+ size_t szdptr,
+ dk4_app_t *app,
+ const dkChar *shortname,
+ int maxpass,
+ int compressed,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+ int nPasses;
+ int i;
+ if ((NULL != dptr) && (0 < szdptr) && (NULL != app) && (NULL != shortname)) {
+ nPasses = maxpass;
+ for (i = 0; ((0 == back) && (i <= nPasses)); i++) {
+ back = dk4app_search_one_data_file(
+ dptr, szdptr, app, shortname, maxpass--, compressed, erp
+ );
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4app_search_data_file(
+ dkChar *dptr,
+ size_t szdptr,
+ dk4_app_t *app,
+ const dkChar *shortname,
+ int maxpass,
+ int compressed,
+ dk4_er_t *erp
+)
+{
+ const dkChar *msg[5];
+ int do_log = 0;
+ int back = 0;
+
+
+#line 74 "dk4appfs03.ctr"
+ if (NULL != app) {
+ if ((NULL != app->msg_debug) && (39 < app->sz_msg_debug)) {
+ do_log = dk4app_log_do(app, DK4_LL_DEBUG);
+ }
+ }
+ if (0 != do_log) {
+
+#line 80 "dk4appfs03.ctr"
+
+
+#line 81 "dk4appfs03.ctr"
+ msg[0] = (app->msg_debug)[32];
+ msg[1] = shortname;
+ msg[2] = (app->msg_debug)[35];
+ if (0 != compressed) {
+#if DK4_HAVE_ZLIB_H
+#if DK4_HAVE_BZLIB_H
+ msg[2] = (app->msg_debug)[39];
+#else
+ msg[2] = (app->msg_debug)[37];
+#endif
+#else
+#if DK4_HAVE_BZLIB_H
+ msg[2] = (app->msg_debug)[38];
+#else
+ msg[2] = (app->msg_debug)[34];
+#endif
+#endif
+ } else {
+ msg[2] = (app->msg_debug)[35];
+ }
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 3);
+ back = dk4app_search_i_data_file(
+ dptr, szdptr, app, shortname, maxpass, compressed, erp
+ );
+
+#line 105 "dk4appfs03.ctr"
+ if (0 != back) {
+
+#line 106 "dk4appfs03.ctr"
+ msg[0] = (app->msg_debug)[21];
+ msg[1] = shortname;
+ msg[2] = (app->msg_debug)[23];
+ msg[3] = dptr;
+ msg[4] = NULL;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 4);
+ } else {
+
+#line 113 "dk4appfs03.ctr"
+ msg[0] = (app->msg_debug)[21];
+ msg[1] = shortname;
+ msg[2] = (app->msg_debug)[22];
+ msg[3] = NULL;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 3);
+ }
+ } else {
+
+#line 120 "dk4appfs03.ctr"
+ back = dk4app_search_i_data_file(
+ dptr, szdptr, app, shortname, maxpass, compressed, erp
+ );
+ }
+
+#line 124 "dk4appfs03.ctr"
+ return back;
+}
+
+
diff --git a/support/dktools/dk4appfs03.ctr b/support/dktools/dk4appfs03.ctr
new file mode 100644
index 0000000000..1fd8d26a74
--- /dev/null
+++ b/support/dktools/dk4appfs03.ctr
@@ -0,0 +1,127 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#ifndef DK4APP_H_INCLUDED
+#include "dk4app.h"
+#endif
+
+#ifndef DK4FS_H_INCLUDED
+#include "dk4fs.h"
+#endif
+
+#ifndef DK4CONST_H_INCLUDED
+#include "dk4const.h"
+#endif
+
+
+
+$!trace-include
+
+
+
+static
+int
+dk4app_search_i_data_file(
+ dkChar *dptr,
+ size_t szdptr,
+ dk4_app_t *app,
+ const dkChar *shortname,
+ int maxpass,
+ int compressed,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+ int nPasses;
+ int i;
+ if ((NULL != dptr) && (0 < szdptr) && (NULL != app) && (NULL != shortname)) {
+ nPasses = maxpass;
+ for (i = 0; ((0 == back) && (i <= nPasses)); i++) {
+ back = dk4app_search_one_data_file(
+ dptr, szdptr, app, shortname, maxpass--, compressed, erp
+ );
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4app_search_data_file(
+ dkChar *dptr,
+ size_t szdptr,
+ dk4_app_t *app,
+ const dkChar *shortname,
+ int maxpass,
+ int compressed,
+ dk4_er_t *erp
+)
+{
+ const dkChar *msg[5];
+ int do_log = 0;
+ int back = 0;
+ $? "+ dk4app_search_data_file"
+ if (NULL != app) {
+ if ((NULL != app->msg_debug) && (39 < app->sz_msg_debug)) {
+ do_log = dk4app_log_do(app, DK4_LL_DEBUG);
+ }
+ }
+ if (0 != do_log) { $? ". with log"
+ $? ". debug texts found"
+ msg[0] = (app->msg_debug)[32];
+ msg[1] = shortname;
+ msg[2] = (app->msg_debug)[35];
+ if (0 != compressed) {
+#if DK4_HAVE_ZLIB_H
+#if DK4_HAVE_BZLIB_H
+ msg[2] = (app->msg_debug)[39];
+#else
+ msg[2] = (app->msg_debug)[37];
+#endif
+#else
+#if DK4_HAVE_BZLIB_H
+ msg[2] = (app->msg_debug)[38];
+#else
+ msg[2] = (app->msg_debug)[34];
+#endif
+#endif
+ } else {
+ msg[2] = (app->msg_debug)[35];
+ }
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 3);
+ back = dk4app_search_i_data_file(
+ dptr, szdptr, app, shortname, maxpass, compressed, erp
+ ); $? ". search done %d", back
+ if (0 != back) { $? ". log success"
+ msg[0] = (app->msg_debug)[21];
+ msg[1] = shortname;
+ msg[2] = (app->msg_debug)[23];
+ msg[3] = dptr;
+ msg[4] = NULL;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 4);
+ } else { $? ". log failure"
+ msg[0] = (app->msg_debug)[21];
+ msg[1] = shortname;
+ msg[2] = (app->msg_debug)[22];
+ msg[3] = NULL;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 3);
+ }
+ } else { $? ". no log"
+ back = dk4app_search_i_data_file(
+ dptr, szdptr, app, shortname, maxpass, compressed, erp
+ );
+ } $? "- dk4app_search_data_file %d", back
+ return back;
+}
+
+
diff --git a/support/dktools/dk4appfs04.c b/support/dktools/dk4appfs04.c
new file mode 100644
index 0000000000..26a372621c
--- /dev/null
+++ b/support/dktools/dk4appfs04.c
@@ -0,0 +1,156 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4appfs04.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4appfs04.c The dk4appfs04 module.
+*/
+
+
+#line 10 "dk4appfs04.ctr"
+
+#ifndef DK4APP_H_INCLUDED
+#include "dk4app.h"
+#endif
+
+#ifndef DK4FS_H_INCLUDED
+#include "dk4fs.h"
+#endif
+
+#ifndef DK4CONST_H_INCLUDED
+#include "dk4const.h"
+#endif
+
+
+
+
+
+#line 26 "dk4appfs04.ctr"
+
+
+
+int
+dk4app_search_i_config_file(
+ dkChar *dptr,
+ size_t szdptr,
+ dk4_app_t *app,
+ const dkChar *shortname,
+ int maxpass,
+ int compressed,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+ int nPasses;
+ int i;
+ if ((NULL != dptr) && (0 < szdptr) && (NULL != app) && (NULL != shortname)) {
+ nPasses = maxpass;
+ for (i = 0; ((0 == back) && (i <= nPasses)); i++) {
+ back = dk4app_search_one_config_file(
+ dptr, szdptr, app, shortname, maxpass--, compressed, erp
+ );
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4app_search_config_file(
+ dkChar *dptr,
+ size_t szdptr,
+ dk4_app_t *app,
+ const dkChar *shortname,
+ int maxpass,
+ int compressed,
+ dk4_er_t *erp
+)
+{
+ const dkChar *msg[5];
+ int do_log = 0;
+ int back = 0;
+ if (NULL != app) {
+ if ((NULL != app->msg_debug) && (39 < app->sz_msg_debug)) {
+ do_log = dk4app_log_do(app, DK4_LL_DEBUG);
+ }
+ }
+ if (0 != do_log) {
+ msg[0] = (app->msg_debug)[33];
+ msg[1] = shortname;
+ msg[2] = (app->msg_debug)[35];
+ if (0 != compressed) {
+#if DK4_HAVE_ZLIB_H
+#if DK4_HAVE_BZLIB_H
+ msg[2] = (app->msg_debug)[39];
+#else
+ msg[2] = (app->msg_debug)[37];
+#endif
+#else
+#if DK4_HAVE_BZLIB_H
+ msg[2] = (app->msg_debug)[38];
+#else
+ msg[2] = (app->msg_debug)[34];
+#endif
+#endif
+ } else {
+ msg[2] = (app->msg_debug)[35];
+ }
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 3);
+ back = dk4app_search_i_config_file(
+ dptr, szdptr, app, shortname, maxpass, compressed, erp
+ );
+ if (0 != back) {
+ msg[0] = (app->msg_debug)[24];
+ msg[1] = shortname;
+ msg[2] = (app->msg_debug)[23];
+ msg[3] = dptr;
+ msg[4] = NULL;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 4);
+ } else {
+ msg[0] = (app->msg_debug)[21];
+ msg[1] = shortname;
+ msg[0] = (app->msg_debug)[22];
+ msg[3] = NULL;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 3);
+ }
+ } else {
+ back = dk4app_search_i_config_file(
+ dptr, szdptr, app, shortname, maxpass, compressed, erp
+ );
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4appfs04.ctr b/support/dktools/dk4appfs04.ctr
new file mode 100644
index 0000000000..d0b58d58a1
--- /dev/null
+++ b/support/dktools/dk4appfs04.ctr
@@ -0,0 +1,123 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#ifndef DK4APP_H_INCLUDED
+#include "dk4app.h"
+#endif
+
+#ifndef DK4FS_H_INCLUDED
+#include "dk4fs.h"
+#endif
+
+#ifndef DK4CONST_H_INCLUDED
+#include "dk4const.h"
+#endif
+
+
+
+$!trace-include
+
+
+
+int
+dk4app_search_i_config_file(
+ dkChar *dptr,
+ size_t szdptr,
+ dk4_app_t *app,
+ const dkChar *shortname,
+ int maxpass,
+ int compressed,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+ int nPasses;
+ int i;
+ if ((NULL != dptr) && (0 < szdptr) && (NULL != app) && (NULL != shortname)) {
+ nPasses = maxpass;
+ for (i = 0; ((0 == back) && (i <= nPasses)); i++) {
+ back = dk4app_search_one_config_file(
+ dptr, szdptr, app, shortname, maxpass--, compressed, erp
+ );
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4app_search_config_file(
+ dkChar *dptr,
+ size_t szdptr,
+ dk4_app_t *app,
+ const dkChar *shortname,
+ int maxpass,
+ int compressed,
+ dk4_er_t *erp
+)
+{
+ const dkChar *msg[5];
+ int do_log = 0;
+ int back = 0;
+ if (NULL != app) {
+ if ((NULL != app->msg_debug) && (39 < app->sz_msg_debug)) {
+ do_log = dk4app_log_do(app, DK4_LL_DEBUG);
+ }
+ }
+ if (0 != do_log) {
+ msg[0] = (app->msg_debug)[33];
+ msg[1] = shortname;
+ msg[2] = (app->msg_debug)[35];
+ if (0 != compressed) {
+#if DK4_HAVE_ZLIB_H
+#if DK4_HAVE_BZLIB_H
+ msg[2] = (app->msg_debug)[39];
+#else
+ msg[2] = (app->msg_debug)[37];
+#endif
+#else
+#if DK4_HAVE_BZLIB_H
+ msg[2] = (app->msg_debug)[38];
+#else
+ msg[2] = (app->msg_debug)[34];
+#endif
+#endif
+ } else {
+ msg[2] = (app->msg_debug)[35];
+ }
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 3);
+ back = dk4app_search_i_config_file(
+ dptr, szdptr, app, shortname, maxpass, compressed, erp
+ );
+ if (0 != back) {
+ msg[0] = (app->msg_debug)[24];
+ msg[1] = shortname;
+ msg[2] = (app->msg_debug)[23];
+ msg[3] = dptr;
+ msg[4] = NULL;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 4);
+ } else {
+ msg[0] = (app->msg_debug)[21];
+ msg[1] = shortname;
+ msg[0] = (app->msg_debug)[22];
+ msg[3] = NULL;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 3);
+ }
+ } else {
+ back = dk4app_search_i_config_file(
+ dptr, szdptr, app, shortname, maxpass, compressed, erp
+ );
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4apphlv.c b/support/dktools/dk4apphlv.c
new file mode 100644
index 0000000000..054fbb96cf
--- /dev/null
+++ b/support/dktools/dk4apphlv.c
@@ -0,0 +1,281 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4apphlv.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4apphlv.c The dk4apphlv module.
+*/
+
+
+#line 10 "dk4apphlv.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4mpl.h"
+#include "dk4app.h"
+#include "dk4fs.h"
+#include "dk4tspdk.h"
+#include "dk4fput.h"
+#include "dk4mem.h"
+#include "dk4strm.h"
+#include "dk4strmr.h"
+#include "dk4enc.h"
+#include "dk4const.h"
+
+
+
+
+
+#line 27 "dk4apphlv.ctr"
+
+
+
+int
+dk4app_can_run_normally(dk4_app_t *app)
+{
+ int back = 0;
+ if (NULL != app) {
+ back = 1;
+ if (0 != app->hvl_cmd) {
+ back = 0;
+ }
+ }
+ return back;
+}
+
+
+
+/** Show all strings in a text array, line by line.
+ CRT on Windows: Required.
+ @param app Application structure.
+ @param array Array containing texts to show.
+*/
+static
+void
+dk4app_show_text_array(dk4_app_t *app, const dkChar * const *array)
+{
+ while(*array) {
+ dk4fputs(*(array++), stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ }
+}
+
+
+
+/** Object used to show help.
+*/
+typedef struct {
+ FILE *outfile; /**< Output file. */
+} dk4_help_shower_t;
+
+
+
+/** Handler function for single characters.
+ CRT on Windows: Required.
+ @param obj Object to modify while processing the character.
+ @param c Character to process.
+ @param pos Current position in file or data stream.
+ @param erp Error report, may be NULL.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+dk4app_help_show_char_handler(
+ void *obj,
+ dkChar c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+)
+{
+ dk4_help_shower_t *helpshow;
+ if (dkT('\r') != c) {
+ helpshow = (dk4_help_shower_t *)obj;
+ dk4fputc(c, helpshow->outfile, NULL);
+ if (dkT('\n') == c) {
+ fflush(helpshow->outfile);
+ }
+ }
+ return (DK4_TSP_RES_OK);
+}
+
+
+
+/** Show short built-in help text.
+ CRT on Windows: Required.
+ @param app Application structure.
+*/
+static
+void
+dk4app_show_help(dk4_app_t *app)
+{
+ const dkChar * const *ptr;
+
+ if (NULL != app->help_text) {
+ ptr = app->help_text;
+ if (0 != (DK4_APP_CMD_ERROR & (app->hvl_cmd))) {
+ dk4fput_initialize_stderr();
+ } else {
+ dk4fput_initialize_stdout();
+ }
+ while (NULL != *ptr) {
+ dk4fputs(
+ *(ptr++),
+ ((DK4_APP_CMD_ERROR & (app->hvl_cmd)) ? stderr : stdout),
+ NULL
+ );
+ dk4fputc(
+ dkT('\n'),
+ ((DK4_APP_CMD_ERROR & (app->hvl_cmd)) ? stderr : stdout),
+ NULL
+ );
+ }
+ }
+}
+
+
+
+/** Show help text (full manual if available, short help text otherwise).
+ CRT on Windows: Required.
+ @param app Application structure.
+*/
+static
+void
+dk4app_show_manual(dk4_app_t *app)
+{
+ unsigned char inb[4096];
+ dkChar fnb[DK4_MAX_PATH];
+ dk4_tspdk_t tspdk;
+ dk4_stream_t *istrm;
+ dk4_help_shower_t helpshow;
+ size_t sz;
+ int res;
+ int done = 0;
+
+ if (NULL != app->help_file_name) {
+ res = dk4app_search_data_file(
+ fnb, DK4_SIZEOF(fnb,dkChar), app, app->help_file_name,
+ DK4_FS_DATA_MAX_SYS, 1, NULL
+ );
+ if (0 != res) {
+ istrm = dk4stream_open_file_reader(fnb, NULL);
+ if (NULL != istrm) {
+ if (0 != (DK4_APP_CMD_ERROR & (app->hvl_cmd))) {
+ dk4fput_initialize_stderr();
+ helpshow.outfile = stderr;
+ } else {
+ dk4fput_initialize_stdout();
+ helpshow.outfile = stdout;
+ }
+ res = dk4tspdk_setup_char(
+ &tspdk, (void *)(&helpshow), dk4app_help_show_char_handler,
+ app->encoding, DK4_FILE_ENCODING_UTF8, NULL
+ );
+ if (0 != res) {
+ do {
+ sz = sizeof(inb);
+ if (0 < dk4stream_read(inb, &sz, istrm, NULL)) {
+ if (0 < sz) {
+ (void)dk4tspdk_add_bytes(&tspdk, inb, sz);
+ done = 1;
+ }
+ } else {
+ sz = 0;
+ }
+ } while (0 < sz);
+ (void)dk4tspdk_finish(&tspdk);
+ }
+ dk4stream_close(istrm, NULL);
+ }
+ }
+ }
+ if (0 == done) {
+ dk4app_show_help(app);
+ }
+}
+
+
+
+int
+dk4app_help_version_license(dk4_app_t *app)
+{
+ int back = 0;
+ if (NULL != app) {
+ back = 1;
+ if (0 != app->hvl_cmd) {
+ if (DK4_APP_CMD_ERROR & (app->hvl_cmd)) {
+ dk4app_show_manual(app);
+ back = 0;
+ } else {
+ switch (app->hvl_cmd) {
+ case DK4_APP_CMD_MANUAL: {
+ dk4app_show_manual(app);
+ } break;
+ case DK4_APP_CMD_HELP: {
+ dk4app_show_help(app);
+ } break;
+ case DK4_APP_CMD_VERSION: {
+ if (NULL != app->vers_text) {
+ dk4fput_initialize_stdout();
+ dk4fputs(app->vers_text, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ }
+ } break;
+ case DK4_APP_CMD_LICENSE: {
+ if (NULL != app->lic_text) {
+ dk4fput_initialize_stdout();
+ dk4app_show_text_array(app, app->lic_text);
+ }
+ } break;
+ default: {
+ /* ERROR: --help, --version, --license mutually exclusive! */
+ dk4app_log_base1(app, DK4_LL_ERROR, 81);
+ app->hvl_cmd |= DK4_APP_CMD_ERROR;
+ dk4app_show_manual(app);
+ back = 0;
+ } break;
+ }
+ }
+ } else {
+ /* BUG: None of the options found in command line */
+ back = 0;
+ }
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4apphlv.ctr b/support/dktools/dk4apphlv.ctr
new file mode 100644
index 0000000000..aec00122f8
--- /dev/null
+++ b/support/dktools/dk4apphlv.ctr
@@ -0,0 +1,248 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4mpl.h"
+#include "dk4app.h"
+#include "dk4fs.h"
+#include "dk4tspdk.h"
+#include "dk4fput.h"
+#include "dk4mem.h"
+#include "dk4strm.h"
+#include "dk4strmr.h"
+#include "dk4enc.h"
+#include "dk4const.h"
+
+
+
+$!trace-include
+
+
+
+int
+dk4app_can_run_normally(dk4_app_t *app)
+{
+ int back = 0;
+ if (NULL != app) {
+ back = 1;
+ if (0 != app->hvl_cmd) {
+ back = 0;
+ }
+ }
+ return back;
+}
+
+
+
+/** Show all strings in a text array, line by line.
+ CRT on Windows: Required.
+ @param app Application structure.
+ @param array Array containing texts to show.
+*/
+static
+void
+dk4app_show_text_array(dk4_app_t *app, const dkChar * const *array)
+{
+ while(*array) {
+ dk4fputs(*(array++), stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ }
+}
+
+
+
+/** Object used to show help.
+*/
+typedef struct {
+ FILE *outfile; /**< Output file. */
+} dk4_help_shower_t;
+
+
+
+/** Handler function for single characters.
+ CRT on Windows: Required.
+ @param obj Object to modify while processing the character.
+ @param c Character to process.
+ @param pos Current position in file or data stream.
+ @param erp Error report, may be NULL.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+dk4app_help_show_char_handler(
+ void *obj,
+ dkChar c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+)
+{
+ dk4_help_shower_t *helpshow;
+ if (dkT('\r') != c) {
+ helpshow = (dk4_help_shower_t *)obj;
+ dk4fputc(c, helpshow->outfile, NULL);
+ if (dkT('\n') == c) {
+ fflush(helpshow->outfile);
+ }
+ }
+ return (DK4_TSP_RES_OK);
+}
+
+
+
+/** Show short built-in help text.
+ CRT on Windows: Required.
+ @param app Application structure.
+*/
+static
+void
+dk4app_show_help(dk4_app_t *app)
+{
+ const dkChar * const *ptr;
+
+ if (NULL != app->help_text) {
+ ptr = app->help_text;
+ if (0 != (DK4_APP_CMD_ERROR & (app->hvl_cmd))) {
+ dk4fput_initialize_stderr();
+ } else {
+ dk4fput_initialize_stdout();
+ }
+ while (NULL != *ptr) {
+ dk4fputs(
+ *(ptr++),
+ ((DK4_APP_CMD_ERROR & (app->hvl_cmd)) ? stderr : stdout),
+ NULL
+ );
+ dk4fputc(
+ dkT('\n'),
+ ((DK4_APP_CMD_ERROR & (app->hvl_cmd)) ? stderr : stdout),
+ NULL
+ );
+ }
+ }
+}
+
+
+
+/** Show help text (full manual if available, short help text otherwise).
+ CRT on Windows: Required.
+ @param app Application structure.
+*/
+static
+void
+dk4app_show_manual(dk4_app_t *app)
+{
+ unsigned char inb[4096];
+ dkChar fnb[DK4_MAX_PATH];
+ dk4_tspdk_t tspdk;
+ dk4_stream_t *istrm;
+ dk4_help_shower_t helpshow;
+ size_t sz;
+ int res;
+ int done = 0;
+
+ if (NULL != app->help_file_name) {
+ res = dk4app_search_data_file(
+ fnb, DK4_SIZEOF(fnb,dkChar), app, app->help_file_name,
+ DK4_FS_DATA_MAX_SYS, 1, NULL
+ );
+ if (0 != res) {
+ istrm = dk4stream_open_file_reader(fnb, NULL);
+ if (NULL != istrm) {
+ if (0 != (DK4_APP_CMD_ERROR & (app->hvl_cmd))) {
+ dk4fput_initialize_stderr();
+ helpshow.outfile = stderr;
+ } else {
+ dk4fput_initialize_stdout();
+ helpshow.outfile = stdout;
+ }
+ res = dk4tspdk_setup_char(
+ &tspdk, (void *)(&helpshow), dk4app_help_show_char_handler,
+ app->encoding, DK4_FILE_ENCODING_UTF8, NULL
+ );
+ if (0 != res) {
+ do {
+ sz = sizeof(inb);
+ if (0 < dk4stream_read(inb, &sz, istrm, NULL)) {
+ if (0 < sz) {
+ (void)dk4tspdk_add_bytes(&tspdk, inb, sz);
+ done = 1;
+ }
+ } else {
+ sz = 0;
+ }
+ } while (0 < sz);
+ (void)dk4tspdk_finish(&tspdk);
+ }
+ dk4stream_close(istrm, NULL);
+ }
+ }
+ }
+ if (0 == done) {
+ dk4app_show_help(app);
+ }
+}
+
+
+
+int
+dk4app_help_version_license(dk4_app_t *app)
+{
+ int back = 0;
+ if (NULL != app) {
+ back = 1;
+ if (0 != app->hvl_cmd) {
+ if (DK4_APP_CMD_ERROR & (app->hvl_cmd)) {
+ dk4app_show_manual(app);
+ back = 0;
+ } else {
+ switch (app->hvl_cmd) {
+ case DK4_APP_CMD_MANUAL: {
+ dk4app_show_manual(app);
+ } break;
+ case DK4_APP_CMD_HELP: {
+ dk4app_show_help(app);
+ } break;
+ case DK4_APP_CMD_VERSION: {
+ if (NULL != app->vers_text) {
+ dk4fput_initialize_stdout();
+ dk4fputs(app->vers_text, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ }
+ } break;
+ case DK4_APP_CMD_LICENSE: {
+ if (NULL != app->lic_text) {
+ dk4fput_initialize_stdout();
+ dk4app_show_text_array(app, app->lic_text);
+ }
+ } break;
+ default: {
+ /* ERROR: --help, --version, --license mutually exclusive! */
+ dk4app_log_base1(app, DK4_LL_ERROR, 81);
+ app->hvl_cmd |= DK4_APP_CMD_ERROR;
+ dk4app_show_manual(app);
+ back = 0;
+ } break;
+ }
+ }
+ } else {
+ /* BUG: None of the options found in command line */
+ back = 0;
+ }
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4appi.c b/support/dktools/dk4appi.c
new file mode 100644
index 0000000000..5310f92a33
--- /dev/null
+++ b/support/dktools/dk4appi.c
@@ -0,0 +1,92 @@
+
+#ifndef DK4APPI_C_INCLUDED
+#define DK4APPI_C_INCLUDED 1
+
+/** Errors found but not immediately reported.
+*/
+enum {
+
+ /** Failed to find language, region and encoding.
+ */
+ E_LOCALE = 1,
+
+ /** Memory allocation failed.
+ */
+ E_MEMORY ,
+
+ /** Failed to find name of executable file.
+ */
+ E_EXEFILE ,
+
+ /** File or directory name of executable file path
+ name too long for buffer.
+ */
+ E_EXECNAME_TOO_LONG ,
+
+ /** No directory part in executable file path.
+ */
+ E_NO_DIR_IN_EXENAME ,
+
+ /** Empty option specification.
+ BUG!
+ */
+ E_EMPTY_OPTION_SPEC ,
+
+ /** Long option specified multiple times.
+ BUG!
+ */
+ E_OPTION_LONG_SPEC_MULT ,
+
+ /** Short option specified multiple times.
+ BUG!
+ */
+ E_OPTION_SHORT_SPEC_MULT ,
+
+ /** Failed to find user name.
+ */
+ E_USER_NAME_NOT_FOUND ,
+
+ /** Failed to find user home directory.
+ */
+ E_USER_HOME_NOT_FOUND ,
+
+ /** Failed to find host name.
+ */
+ E_HOST_NAME_NOT_FOUND ,
+
+ /** Failed to open a preferences file.
+ */
+ E_PREF_FILE_OPEN ,
+
+ /** Number of command line arguments is NULL.
+ */
+ E_ARGC ,
+
+ /** Option requires an argument.
+ */
+ E_OPT_REQUIRES_ARG ,
+
+ /** Unexpected option found.
+ */
+ E_UNEXPECTED_OPTION ,
+
+ /** Invalid argument to option.
+ */
+ E_INVALID_OPTION_ARG ,
+
+ /** Option too long.
+ */
+ E_OPTION_TOO_LONG ,
+
+ /** A required argument was not specified.
+ This is a program bug.
+ */
+ E_BUG_ARGUMENTS ,
+ /** Failed to construct log file name.
+ */
+ E_LOG_FILE_NAME ,
+};
+
+
+#endif
+
diff --git a/support/dktools/dk4applog.c b/support/dktools/dk4applog.c
new file mode 100644
index 0000000000..c066252d0e
--- /dev/null
+++ b/support/dktools/dk4applog.c
@@ -0,0 +1,1666 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4applog.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4applog.c The dk4applog module.
+*/
+
+
+#line 9 "dk4applog.ctr"
+
+
+#ifndef DK4APP_H_INCLUDED
+#include "dk4app.h"
+#endif
+
+#ifndef DK4CONST_H_INCLUDED
+#include "dk4const.h"
+#endif
+
+#ifndef DK4TIME_H_INCLUDED
+#include "dk4time.h"
+#endif
+
+#ifndef DK4TIMEDK_H_INCLUDED
+#include "dk4timedk.h"
+#endif
+
+#ifndef DK4MAODD_H_INCLUDED
+#include "dk4maodd.h"
+#endif
+
+#ifndef DK4FPUT_H_INCLUDED
+#include "dk4fput.h"
+#endif
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4FOP8_H_INCLUDED
+#include "dk4fopc8.h"
+#endif
+
+#ifndef DK4FOPD_H_INCLUDED
+#include "dk4fopd.h"
+#endif
+
+#ifndef DK4MAODD_H_INCLUDED
+#include "dk4maodd.h"
+#endif
+
+#ifndef DK4ENC_H_INCLUDED
+#include "dk4enc.h"
+#endif
+
+#ifndef DK4APPMKDH_H_INCLUDED
+#include "dk4appmkdh.h"
+#endif
+
+#ifndef DK4MPL_H_INCLUDED
+#include "dk4mpl.h"
+#endif
+
+#ifndef DK4FS_H_INCLUDED
+#include "dk4fs.h"
+#endif
+
+
+
+
+
+#line 70 "dk4applog.ctr"
+
+
+
+/** Constant char texts used by the module, not localized.
+*/
+static const dkChar * const dk4app_log_kwnl[] = {
+/* 0 */
+dkT("w"),
+
+/* 1 */
+dkT("a"),
+
+/* 2 */
+dkT("dk4debug.str"),
+
+/* 3 */
+dkT("-"),
+
+/* 4 */
+dkT("+"),
+
+/* 5 */
+dkT("ascii"),
+
+/* 6 */
+dkT("ansi"),
+
+/* 7 */
+dkT("utf-8"),
+
+/* 8 */
+dkT("utf-16"),
+
+/* 9 */
+dkT("utf-16-le"),
+
+/* 10 */
+dkT("utf-16-be"),
+
+/* 11 */
+dkT("c32"),
+
+/* 12 */
+dkT("c32-le"),
+
+/* 13 */
+dkT("c32-be"),
+
+/* 14 */
+dkT("dk3pref.conf"),
+
+/* 15 */
+dkT("dk4pref.conf"),
+
+NULL
+
+
+#line 109 "dk4applog.ctr"
+};
+
+
+
+/** The message texts for the base log domain, nearly always loaded.
+*/
+static const dkChar * const dk4app_def_msg_base[] = {
+/* 0 */
+dkT("NONE"),
+
+/* 1 */
+dkT("Panic"),
+
+/* 2 */
+dkT("Fatal"),
+
+/* 3 */
+dkT("Error"),
+
+/* 4 */
+dkT("Warning"),
+
+/* 5 */
+dkT("Info"),
+
+/* 6 */
+dkT("Progress"),
+
+/* 7 */
+dkT("Debug"),
+
+/* 8 */
+dkT("Ignore"),
+
+/* 9 */
+dkT("Illegal option: \""),
+
+/* 10 */
+dkT("\"!"),
+
+/* 11 */
+dkT("Option \""),
+
+/* 12 */
+dkT("\" requires argument!"),
+
+/* 13 */
+dkT("Option \""),
+
+/* 14 */
+dkT("\" requires a boolean argument!\n\tRejected text: \""),
+
+/* 15 */
+dkT("\"!"),
+
+/* 16 */
+dkT("Option \""),
+
+/* 17 */
+dkT("\" requires a size argument!\n\tRejected text: \""),
+
+/* 18 */
+dkT("\"!"),
+
+/* 19 */
+dkT("Option \""),
+
+/* 20 */
+dkT("\" requires integer argument!\n\tRejected text: \""),
+
+/* 21 */
+dkT("\"!"),
+
+/* 22 */
+dkT("Option \""),
+
+/* 23 */
+dkT("\" requires unsigned integer argument!\n\tRejected text: \""),
+
+/* 24 */
+dkT("\"!"),
+
+/* 25 */
+dkT("Option \""),
+
+/* 26 */
+dkT("\" requires floating point (double) argument!\n\tRejected text: \""),
+
+/* 27 */
+dkT("\"!"),
+
+/* 28 */
+dkT("Option \"--"),
+
+/* 29 */
+dkT("Option \"--"),
+
+/* 30 */
+dkT("Option \"--"),
+
+/* 31 */
+dkT("Option \"--"),
+
+/* 32 */
+dkT("Option \"--"),
+
+/* 33 */
+dkT("Option \"--"),
+
+/* 34 */
+dkT("Failed to save preference value!\n\t\""),
+
+/* 35 */
+dkT("\"=\""),
+
+/* 36 */
+dkT("\"!"),
+
+/* 37 */
+dkT("Value required for command line preference \""),
+
+/* 38 */
+dkT("\"!"),
+
+/* 39 */
+dkT("Option too long!\n\t\""),
+
+/* 40 */
+dkT("\"!"),
+
+/* 41 */
+dkT("Failed to remove file:\n\t\""),
+
+/* 42 */
+dkT("\"!\n\tPath name too long."),
+
+/* 43 */
+dkT("Failed to create directory:\n\t\""),
+
+/* 44 */
+dkT("\"!\n\tPath exists, but is not a directory!"),
+
+/* 45 */
+dkT("\n\tLocal network interface is down!"),
+
+/* 46 */
+dkT("Failed to create directory:\n\t\""),
+
+/* 47 */
+dkT("\"!\n\tIllegal path."),
+
+/* 48 */
+dkT("\"!\n\tFile or directory in use."),
+
+/* 49 */
+dkT("\"!\n\tPath already exists."),
+
+/* 50 */
+dkT("\"!\n\tPath name points outside accessible address space."),
+
+/* 51 */
+dkT("\"!\n\tPath not found (one path component does not exist)."),
+
+/* 52 */
+dkT("\"!\n\tPath specifies a directory."),
+
+/* 53 */
+dkT("\"!\n\tNo function for wide-char mkdir available."),
+
+/* 54 */
+dkT("No wide-char function to remove files available."),
+
+/* 55 */
+dkT("\"!\n\tInsufficient permissions."),
+
+/* 56 */
+dkT("\"!\n\tFile system is mounted read-only."),
+
+/* 57 */
+dkT("\"!\n\tConflict with extended attribute."),
+
+/* 58 */
+dkT("\"!\n\tNot allowed for this file system type."),
+
+/* 59 */
+dkT("\"!\n\tI/O error on device."),
+
+/* 60 */
+dkT("\"!\n\tDisk space or quota problem."),
+
+/* 61 */
+dkT("\"!\n\tToo many symbolic links in path (probably symlink loop)."),
+
+/* 62 */
+dkT("\"!\n\tInsufficient kernel memory."),
+
+/* 63 */
+dkT("\"!\n\tToo many entries in parent directory."),
+
+/* 64 */
+dkT("\"!\n\tFile server not available."),
+
+/* 65 */
+dkT("\"!\n\tName too long."),
+
+/* 66 */
+dkT("Failed to remove directory:\n\t\""),
+
+/* 67 */
+dkT("\"!\n\tDirectory not empty."),
+
+/* 68 */
+dkT("\"!\n\tInvalid path name."),
+
+/* 69 */
+dkT("\"!\n\tWindows error code: "),
+
+/* 70 */
+dkT(" (0x"),
+
+/* 71 */
+dkT(")."),
+
+/* 72 */
+dkT("\"!"),
+
+/* 73 */
+dkT("\"!\n\tParent directory not found (device or server share)!"),
+
+/* 74 */
+dkT("\"!\n\tBad network resource name (share name)!"),
+
+/* 75 */
+dkT("\"!\n\tBad network resource name (server name)!"),
+
+/* 76 */
+dkT("\n\tNo route to network destination available!"),
+
+/* 77 */
+dkT("\"!"),
+
+/* 78 */
+dkT("\n\tAttempt to read from outside file!"),
+
+/* 79 */
+dkT("\"!\n\tError code: "),
+
+/* 80 */
+dkT("."),
+
+/* 81 */
+dkT("Options --help, --version, and --license are mutually exclusive!"),
+
+/* 82 */
+dkT("Numeric overflow in size calculation!"),
+
+/* 83 */
+dkT("Numeric overflow in size calculation!\n\t"),
+
+/* 84 */
+dkT(" elements of "),
+
+/* 85 */
+dkT(" bytes."),
+
+/* 86 */
+dkT("Memory allocation failed! Invalid size(s) specified."),
+
+/* 87 */
+dkT("Memory allocation failed! Invalid size(s) specified.\n\tNumber of elements: "),
+
+/* 88 */
+dkT(", element size: "),
+
+/* 89 */
+dkT("."),
+
+/* 90 */
+dkT("Not enough memory! Allcation failed."),
+
+/* 91 */
+dkT("Not enough memory! Allcation failed.\n\tNumber of elements: "),
+
+/* 92 */
+dkT(", element size: "),
+
+/* 93 */
+dkT("."),
+
+/* 94 */
+dkT("Further file removal attempts failed in:\n\t\""),
+
+/* 95 */
+dkT("\"!"),
+
+/* 96 */
+dkT("Further subdirectory removal attempts failed in:\n\t\""),
+
+/* 97 */
+dkT("\"!"),
+
+/* 98 */
+dkT("File or directory name too long:\n\t\""),
+
+/* 99 */
+dkT("\"!"),
+
+/* 100 */
+dkT("Failed to expand file name:\n\t\""),
+
+/* 101 */
+dkT("\"!"),
+
+/* 102 */
+dkT("\"!\n\tNo function for directory traversal available!"),
+
+/* 103 */
+dkT("\"!\n\tMemory allocation failed!"),
+
+/* 104 */
+dkT("\"!\n\tFailed to open directory for traversal!"),
+
+/* 105 */
+dkT("\"!\n\tDirectory or file name too large!"),
+
+/* 106 */
+dkT("\"!\n\tMultiple matching files!"),
+
+/* 107 */
+dkT("\"!\n\tNo matching file!"),
+
+/* 108 */
+dkT("Failed to open file:\n\t\""),
+
+/* 109 */
+dkT("\"!\n\tNot a regular file!"),
+
+/* 110 */
+dkT("\"!\n\tPath contains symbolic links!"),
+
+/* 111 */
+dkT("\"!\n\tPath is a symbolic link!"),
+
+/* 112 */
+dkT("\"!\n\tSymbolic link owner is not target owner!"),
+
+/* 113 */
+dkT("\"!\n\tSignal received!"),
+
+/* 114 */
+dkT("\"!\n\tToo many open files in process!"),
+
+/* 115 */
+dkT("\"!\n\tToo many open files on system!"),
+
+/* 116 */
+dkT("\"!\n\tDevice for special file does not exist!"),
+
+/* 117 */
+dkT("\"!\n\tFile size too large for off_t data type!"),
+
+/* 118 */
+dkT("Read operation failed!"),
+
+/* 119 */
+dkT("Read operation failed, error code:"),
+
+/* 120 */
+dkT("."),
+
+/* 121 */
+dkT("\n\tOperation would block!"),
+
+/* 122 */
+dkT("\n\tBad file descriptor (bug)!"),
+
+/* 123 */
+dkT("\n\tBuffer is outside usable address space (bug)!"),
+
+/* 124 */
+dkT("\n\tSignal received!"),
+
+/* 125 */
+dkT("\n\tFile descriptor attached to unsuitable object (bug)!"),
+
+/* 126 */
+dkT("\n\tI/O error!"),
+
+/* 127 */
+dkT("\n\tFile descriptor attachted to directory (bug)!"),
+
+/* 128 */
+dkT("Write operation failed!"),
+
+/* 129 */
+dkT("Write operation failed, error code:"),
+
+/* 130 */
+dkT("."),
+
+/* 131 */
+dkT("\n\tNo space left on device!"),
+
+/* 132 */
+dkT("\n\tFile size would exceed limits!"),
+
+/* 133 */
+dkT("\n\tNo reader attached to pipe or socket!"),
+
+/* 134 */
+dkT("\n\tSocket not connected!"),
+
+/* 135 */
+dkT("\n\tBuffer size outside supported range!"),
+
+/* 136 */
+dkT("\n\tInsufficient system resources available!"),
+
+/* 137 */
+dkT("\n\tNonexistent or incapable device!"),
+
+/* 138 */
+dkT("\n\tInsufficient permissions!"),
+
+/* 139 */
+dkT("\n\tUnexpected control part in normal-mode message!"),
+
+/* 140 */
+dkT("\n\tConnection reset by peer!"),
+
+/* 141 */
+dkT("\n\tTimed out!"),
+
+/* 142 */
+dkT("\n\tInsufficient memory available!"),
+
+/* 143 */
+dkT("\n\tFile descriptor is socket or FIFO!"),
+
+/* 144 */
+dkT("Failed to open directory:\n\t\""),
+
+/* 145 */
+dkT("\"!\n\tNo function found for directory traversal!"),
+
+/* 146 */
+dkT("\"!\n\tNumeric overflow in size calculation!"),
+
+/* 147 */
+dkT("\"!\n\tPath not found!"),
+
+/* 148 */
+dkT("\"!\n\tDirectory does not exist!"),
+
+/* 149 */
+dkT("Failed to obtain information about file/directory:\n\t\""),
+
+/* 150 */
+dkT("\"!\n\tOne path component is not a directory."),
+
+/* 151 */
+dkT("\"!\n\tCurrently used by another process."),
+
+/* 152 */
+dkT("Not a directory:\n\t\""),
+
+/* 153 */
+dkT("\"!"),
+
+/* 154 */
+dkT("\" in \""),
+
+/* 155 */
+dkT("Failed to change file buffering!"),
+
+/* 156 */
+dkT("Failed to change buffering for file\n\""),
+
+/* 157 */
+dkT("\"!"),
+
+/* 158 */
+dkT("Neither setvbuf() nor setbuffer() function available!"),
+
+/* 159 */
+dkT("Syntax error, expected line:\n\"name = width height [border-left border-right border-top border-bottom]\""),
+
+/* 160 */
+dkT("Preference value found: \""),
+
+/* 161 */
+dkT("\"=\""),
+
+/* 162 */
+dkT("\"."),
+
+/* 163 */
+dkT("Preference value too long: \""),
+
+/* 164 */
+dkT("\"=\""),
+
+/* 165 */
+dkT("\"!"),
+
+/* 166 */
+dkT("Preference value not found: \""),
+
+/* 167 */
+dkT("\"!"),
+
+NULL
+
+
+#line 574 "dk4applog.ctr"
+};
+
+
+
+static const dkChar * const dk4app_def_msg_debug[] = {
+/* 0 */
+dkT("Host name: "),
+
+/* 1 */
+dkT("User name: "),
+
+/* 2 */
+dkT("Home directory: "),
+
+/* 3 */
+dkT("Language: "),
+
+/* 4 */
+dkT("Region: "),
+
+/* 5 */
+dkT("Encoding: "),
+
+/* 6 */
+dkT("Encoding expected on standard input: "),
+
+/* 7 */
+dkT("Encoding expected on files: "),
+
+/* 8 */
+dkT("Program name: "),
+
+/* 9 */
+dkT("Program group: "),
+
+/* 10 */
+dkT("Directory etc: "),
+
+/* 11 */
+dkT("Directory bin: "),
+
+/* 12 */
+dkT("Directory share: "),
+
+/* 13 */
+dkT("Directory lib: "),
+
+/* 14 */
+dkT("Directory var: "),
+
+/* 15 */
+dkT("Directory tmp: "),
+
+/* 16 */
+dkT("Logging enabled: "),
+
+/* 17 */
+dkT("Log file: "),
+
+/* 18 */
+dkT("Log level to log on stderr: "),
+
+/* 19 */
+dkT("Log level to log to file: "),
+
+/* 20 */
+dkT("Log level to keep log file: "),
+
+/* 21 */
+dkT("Data file search for \""),
+
+/* 22 */
+dkT("\" failed."),
+
+/* 23 */
+dkT("\" succeeded.\n\t"),
+
+/* 24 */
+dkT("Configuration file search for \""),
+
+/* 25 */
+dkT("Delete directory: "),
+
+/* 26 */
+dkT("Delete file: "),
+
+/* 27 */
+dkT("Delete file or directory: "),
+
+/* 28 */
+dkT("Preference files:"),
+
+/* 29 */
+dkT("UNUSED"),
+
+/* 30 */
+dkT("+ "),
+
+/* 31 */
+dkT("- "),
+
+/* 32 */
+dkT("Search for data file \""),
+
+/* 33 */
+dkT("Search for configuration file \""),
+
+/* 34 */
+dkT("\" (compression allowed):"),
+
+/* 35 */
+dkT("\" (no compression allowed):"),
+
+/* 36 */
+dkT("Collecting paper size data."),
+
+/* 37 */
+dkT("\" (gzip compression allowed):"),
+
+/* 38 */
+dkT("\" (bzip2 compression allowed):"),
+
+/* 39 */
+dkT("\" (gzip/bzip2 compression allowed):"),
+
+/* 40 */
+dkT("String copy allocated: \""),
+
+/* 41 */
+dkT("\"."),
+
+/* 42 */
+dkT("Successfully converted to integer."),
+
+/* 43 */
+dkT("Not an integer!"),
+
+/* 44 */
+dkT("Successfully converted to unsigned integer."),
+
+/* 45 */
+dkT("Not an unsigned integer!"),
+
+/* 46 */
+dkT("Successfully converted to boolean."),
+
+/* 47 */
+dkT("Not a boolean!"),
+
+/* 48 */
+dkT("Successfully converted to size specification."),
+
+/* 49 */
+dkT("Not a size specification!"),
+
+NULL
+
+
+#line 673 "dk4applog.ctr"
+};
+
+
+
+/** Ensure the messages texts for the base log domain are loaded.
+ @param app Application structure.
+ @param logdom Log text domain.
+*/
+static
+void
+dk4app_log_load_base_texts(dk4_app_t *app)
+{
+
+
+#line 686 "dk4applog.ctr"
+ if (NULL != app) {
+
+#line 687 "dk4applog.ctr"
+ if ((NULL == app->msg_base) || (0 == app->sz_msg_base)) {
+
+
+#line 689 "dk4applog.ctr"
+ app->sz_msg_base = dk4app_string_table_size(dk4app_def_msg_base);
+ app->msg_base = dk4app_string_table(
+ app, dkT("dk4base.str"), dk4app_def_msg_base
+ );
+ } else {
+
+#line 694 "dk4applog.ctr"
+ }
+ } else {
+
+#line 696 "dk4applog.ctr"
+ }
+
+#line 697 "dk4applog.ctr"
+}
+
+
+
+/** Check whether there is at least one non-NULL pointer in array.
+ CRT on Windows: Not used.
+ @param msg Array to check.
+ @param sz Size of array.
+ @return 1 if any valid pointer was found, 0 otherwise.
+*/
+static
+int
+dk4app_log_any_non_null(const dkChar * const *msg, size_t sz)
+{
+ size_t i;
+ int back = 0;
+ for (i = 0; ((i < sz) && (0 == back)); i++) {
+ if (NULL != msg[i]) { back = 1; }
+ }
+ return back;
+}
+
+
+
+int
+dk4app_log_do(dk4_app_t *app, int ll)
+{
+ int back = 0;
+ if (NULL != app) {
+#if (!(DK4_ON_WINDOWS && DK4_WIN_DENY_CRT))
+ if (0 != app->log_enabled) {
+ if (app->ll_stderr >= ll) {
+ back = 1;
+ }
+ if (app->ll_file >= ll) {
+ back = 1;
+ }
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+/** Log multi part message to one file.
+ CRT on Windows: Required.
+ @param app Application structure, may be NULL.
+ @param priority Log priority.
+ @param msg Pointer to message parts array.
+ @param sz Number of message parts.
+ @param outfile Output file
+ @param showtime Flag: Show timestamp.
+ @param timer Timestamp of previous log message if any.
+ @param havetime Flag: Timer already contains a value.
+*/
+static
+void
+dk4app_log_msg_to_file(
+ dk4_app_t *app,
+ int priority,
+ const dkChar * const *msg,
+ size_t sz,
+ FILE *outfile,
+ int showtime,
+ dk4_time_t *timer,
+ int *havetime
+)
+{
+#if (!(DK4_ON_WINDOWS && DK4_WIN_DENY_CRT))
+ dkChar lnb[64];
+ dkChar buf[64];
+ size_t i;
+ dk4_time_t ct;
+ int res;
+
+ dk4time_get(&ct);
+ /* Print timestamp */
+ if ((0 != showtime) && ((0 == *havetime) || (ct != *timer))) {
+ *havetime = 1;
+ *timer = ct;
+ if (0 != dk4time_as_text(buf, DK4_SIZEOF(buf,dkChar), &ct, NULL)) {
+ dk4fputs(dkT("# "), outfile, NULL);
+ dk4fputs(buf, outfile, NULL);
+ dk4fputc(dkT('\n'), outfile, NULL);
+ }
+ }
+ /* Print error position */
+ if (NULL != app->source_file_name) {
+ dk4fputs(app->source_file_name, outfile, NULL);
+ dk4fputc(dkT(':'), outfile, NULL);
+ if ((dk4_um_t)0UL != app->source_file_line) {
+ res = dk4ma_write_decimal_unsigned(
+ lnb, DK4_SIZEOF(lnb,dkChar), app->source_file_line, 0, NULL
+ );
+ if (0 != res) {
+ dk4fputs(lnb, outfile, NULL);
+ dk4fputc(dkT(':'), outfile, NULL);
+ }
+ }
+ dk4fputc(dkT(' '), outfile, NULL);
+ }
+ /* Print message */
+ switch (priority) {
+ case DK4_LL_PANIC:
+ case DK4_LL_FATAL:
+ case DK4_LL_ERROR:
+ case DK4_LL_WARNING:
+ {
+ dk4fputs((app->msg_base)[priority], outfile, NULL);
+ dk4fputs(dkT(": "), outfile, NULL);
+ } break;
+ }
+ for (i = 0; i < sz; i++) {
+ dk4fputs(msg[i], outfile, NULL);
+ }
+ dk4fputc(dkT('\n'), outfile, NULL);
+ fflush(outfile);
+#endif
+}
+
+
+
+void
+dk4app_log_msg(
+ dk4_app_t *app,
+ int priority,
+ const dkChar * const *msg,
+ size_t sz
+)
+{
+ FILE *fipo;
+
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, priority)) {
+ dk4app_log_load_base_texts(app);
+ if (0 != dk4app_log_any_non_null(msg, sz)) {
+#if (!(DK4_ON_WINDOWS && DK4_WIN_DENY_CRT))
+ if (app->ll_stderr >= priority) {
+ if (0 == app->have_stderr_init) {
+ dk4fput_initialize_stderr();
+ app->have_stderr_init = 1;
+ }
+ dk4app_log_msg_to_file(
+ app, priority, msg, sz, stderr,
+ app->log_stderr_time, &(app->timer_stderr), &(app->have_stderr_time)
+ );
+ }
+ if (app->ll_file >= priority) {
+ if (NULL != app->log_file_name) {
+#if VERSION_BEFORE_20160127
+#else
+ if (0 == app->have_file_opened) {
+ (void)dk4app_mkdir_hierarchy(app->log_file_name, 0, NULL);
+ }
+#endif
+ fipo = dk4fopen(
+ app->log_file_name,
+ dk4app_log_kwnl[(0 != app->have_file_opened) ? 1 : 0],
+ (DK4_FOPEN_SC_WR_SYMLINK_OWNER | DK4_FOPEN_SC_IS_REGULAR),
+ NULL
+ );
+ app->have_file_opened = 1;
+ if (NULL != fipo) {
+ dk4app_log_msg_to_file(
+ app, priority, msg, sz, fipo,
+ app->log_stderr_time, &(app->timer_file), &(app->have_file_time)
+ );
+ fclose(fipo);
+ }
+ }
+ }
+ if (priority < app->ll_found) {
+ app->ll_found = priority;
+ }
+#endif
+ }
+ }
+ }
+}
+
+
+
+void
+dk4app_log_1(
+ dk4_app_t *app,
+ const dkChar * const *msg,
+ size_t sz_msg,
+ int priority,
+ size_t msgind
+)
+{
+ const dkChar *msgtext;
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, priority)) {
+ dk4app_log_load_base_texts(app);
+ if ((NULL != msg) && (0 < sz_msg) && (msgind < sz_msg)) {
+ msgtext = msg[msgind];
+ dk4app_log_msg(app, priority, &msgtext, 1);
+ }
+ }
+ }
+}
+
+
+
+void
+dk4app_log_2(
+ dk4_app_t *app,
+ const dkChar * const *msg,
+ size_t sz_msg,
+ int priority,
+ size_t i1,
+ const dkChar *t1
+)
+{
+ const dkChar *msgtext[3];
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, priority)) {
+ dk4app_log_load_base_texts(app);
+ if ((NULL != msg) && (0 < sz_msg) && (i1 < sz_msg)) {
+ msgtext[0] = msg[i1];
+ msgtext[1] = t1;
+ dk4app_log_msg(app, priority, msgtext, 2);
+ }
+ }
+ }
+}
+
+
+
+void
+dk4app_log_3(
+ dk4_app_t *app,
+ const dkChar * const *msg,
+ size_t sz_msg,
+ int priority,
+ size_t i1,
+ size_t i2,
+ const dkChar *t1
+)
+{
+ const dkChar *msgtext[3];
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, priority)) {
+ dk4app_log_load_base_texts(app);
+ if ((NULL != msg) && (0 < sz_msg) && (i1 < sz_msg) && (i2 < sz_msg)) {
+ msgtext[0] = msg[i1];
+ msgtext[1] = t1;
+ msgtext[2] = msg[i2];
+ dk4app_log_msg(app, priority, msgtext, 3);
+ }
+ }
+ }
+}
+
+
+
+void
+dk4app_log_5(
+ dk4_app_t *app,
+ const dkChar * const *msg,
+ size_t sz_msg,
+ int priority,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ const dkChar *t1,
+ const dkChar *t2
+)
+{
+ const dkChar *msgtext[5];
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, priority)) {
+ dk4app_log_load_base_texts(app);
+ if ((NULL != msg) && (0 < sz_msg) && (i1 < sz_msg) && (i2 < sz_msg)) {
+ msgtext[0] = msg[i1];
+ msgtext[1] = t1;
+ msgtext[2] = msg[i2];
+ msgtext[3] = t2;
+ msgtext[4] = msg[i3];
+ dk4app_log_msg(app, priority, msgtext, 5);
+ }
+ }
+ }
+}
+
+
+
+void
+dk4app_log_7(
+ dk4_app_t *app,
+ const dkChar * const *msg,
+ size_t sz_msg,
+ int priority,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ size_t i4,
+ const dkChar *t1,
+ const dkChar *t2,
+ const dkChar *t3
+)
+{
+ const dkChar *msgtext[7];
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, priority)) {
+ dk4app_log_load_base_texts(app);
+ if (
+ (NULL != msg)
+ && (0 < sz_msg) && (i1 < sz_msg) && (i2 < sz_msg) && (i3 < sz_msg)
+ )
+ {
+ msgtext[0] = msg[i1];
+ msgtext[1] = t1;
+ msgtext[2] = msg[i2];
+ msgtext[3] = t2;
+ msgtext[4] = msg[i3];
+ msgtext[5] = t3;
+ msgtext[6] = msg[i4];
+ dk4app_log_msg(app, priority, msgtext, 7);
+ }
+ }
+ }
+}
+
+
+
+void
+dk4app_log_base1(
+ dk4_app_t *app,
+ int priority,
+ size_t msgind
+)
+{
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, priority)) {
+ dk4app_log_load_base_texts(app);
+ dk4app_log_1(app, app->msg_base, app->sz_msg_base, priority, msgind);
+ }
+ }
+}
+
+
+
+void
+dk4app_log_base2(
+ dk4_app_t *app,
+ int priority,
+ size_t i1,
+ const dkChar *t1
+)
+{
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, priority)) {
+ dk4app_log_load_base_texts(app);
+ dk4app_log_2(app,app->msg_base,app->sz_msg_base,priority,i1,t1);
+ }
+ }
+}
+
+
+
+void
+dk4app_log_base2c(
+ dk4_app_t *app,
+ int priority,
+ size_t i1,
+ size_t i2
+)
+{
+ const dkChar *msgptr[2];
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, priority)) {
+ if ((app->sz_msg_base > i1) && (app->sz_msg_base > i2)) {
+ dk4app_log_load_base_texts(app);
+ msgptr[0] = (app->msg_base)[i1];
+ msgptr[1] = (app->msg_base)[i2];
+ dk4app_log_msg(app, priority, msgptr, 2);
+ }
+ }
+ }
+}
+
+
+
+void
+dk4app_log_base3(
+ dk4_app_t *app,
+ int priority,
+ size_t i1,
+ size_t i2,
+ const dkChar *t1
+)
+{
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, priority)) {
+ dk4app_log_load_base_texts(app);
+ dk4app_log_3(app,app->msg_base,app->sz_msg_base,priority,i1,i2,t1);
+ }
+ }
+}
+
+
+
+void
+dk4app_log_base5(
+ dk4_app_t *app,
+ int priority,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ const dkChar *t1,
+ const dkChar *t2
+)
+{
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, priority)) {
+ dk4app_log_load_base_texts(app);
+ dk4app_log_5(app,app->msg_base,app->sz_msg_base,priority,i1,i2,i3,t1,t2);
+ }
+ }
+}
+
+
+
+void
+dk4app_log_base7(
+ dk4_app_t *app,
+ int priority,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ size_t i4,
+ const dkChar *t1,
+ const dkChar *t2,
+ const dkChar *t3
+)
+{
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, priority)) {
+ dk4app_log_load_base_texts(app);
+ dk4app_log_7(
+ app,app->msg_base,app->sz_msg_base,priority,i1,i2,i3,i4,t1,t2,t3
+ );
+ }
+ }
+}
+
+
+
+void
+dk4app_log_with_errno(
+ dk4_app_t *app,
+ int priority,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ size_t i4,
+ size_t i5,
+ const dkChar *t1,
+ int errn
+)
+{
+ dkChar enb[64];
+ int res;
+ if (NULL != app) {
+ res = dk4ma_write_decimal_signed(
+ enb, DK4_SIZEOF(enb,dkChar), (dk4_im_t)errn, 0, NULL
+ );
+ if (0 != res) {
+ dk4app_log_base5(app, priority, i1, i2, i3, t1, enb);
+ } else {
+ dk4app_log_base3(app, priority, i4, i5, t1);
+ }
+ }
+}
+
+
+
+const dkChar *
+dk4app_get_log_source_file(dk4_app_t *app)
+{
+ const dkChar *back = NULL;
+ if (NULL != app) {
+ back = app->source_file_name;
+ }
+ return back;
+}
+
+
+
+dk4_um_t
+dk4app_get_log_source_line(dk4_app_t *app)
+{
+ dk4_um_t back = (dk4_um_t)0UL;
+ if (NULL != app) {
+ back = app->source_file_line;
+ }
+ return back;
+}
+
+
+
+void
+dk4app_set_log_source_file(dk4_app_t *app, const dkChar *fn)
+{
+ if (NULL != app) {
+ app->source_file_name = fn;
+ }
+}
+
+
+
+void
+dk4app_set_log_source_line(dk4_app_t *app, dk4_um_t lineno)
+{
+ if (NULL != app) {
+ app->source_file_line = lineno;
+ }
+}
+
+
+
+const dkChar * const *
+dk4app_log_debug_texts(dk4_app_t *app, size_t *szptr)
+{
+ const dkChar * const *back = NULL;
+
+
+#line 1226 "dk4applog.ctr"
+ if (NULL != app) {
+
+#line 1227 "dk4applog.ctr"
+ dk4app_log_load_base_texts(app);
+ if ((NULL != app->msg_debug) && (0 < app->sz_msg_debug)) {
+ back = app->msg_debug;
+
+#line 1230 "dk4applog.ctr"
+ } else {
+
+#line 1231 "dk4applog.ctr"
+ app->msg_debug = dk4app_string_table(
+ app, dk4app_log_kwnl[2], dk4app_def_msg_debug
+ );
+ app->sz_msg_debug = dk4app_string_table_size(app->msg_debug);
+ back = app->msg_debug;
+ }
+ } else {
+
+#line 1238 "dk4applog.ctr"
+ back = dk4app_def_msg_debug;
+ }
+ if (NULL != szptr) {
+ *szptr = dk4app_string_table_size(dk4app_def_msg_debug);
+ }
+
+
+#line 1244 "dk4applog.ctr"
+ return back;
+}
+
+
+
+static
+void
+dk4app_log_two_strings_at_startup(
+ dk4_app_t *app,
+ const dkChar *title,
+ const dkChar *value
+)
+{
+ const dkChar *msg[3];
+ msg[0] = title;
+ msg[1] = value;
+ if (NULL == value) {
+ msg[1] = dk4app_log_kwnl[3];
+ }
+ msg[2] = NULL;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 2);
+}
+
+
+
+static
+void
+dk4app_log_startup_log_level(
+ dk4_app_t *app,
+ const dkChar *title,
+ int ll
+)
+{
+ const dkChar *llstr = NULL;
+ if ((DK4_LL_NONE <= ll) && (DK4_LL_IGNORE >= ll)) {
+ llstr = (app->msg_base)[(size_t)ll];
+ }
+ dk4app_log_two_strings_at_startup(app, title, llstr);
+}
+
+
+
+static
+void
+dk4app_log_startup_encoding(
+ dk4_app_t *app,
+ const dkChar *title,
+ int enc,
+ int isfileenc
+)
+{
+ const dkChar *encstr = NULL;
+ if (0 != isfileenc) {
+ switch (enc) {
+ case DK4_FILE_ENCODING_ASCII : {
+ encstr = dk4app_log_kwnl[5];
+ } break;
+ case DK4_FILE_ENCODING_ANSI : {
+ encstr = dk4app_log_kwnl[6];
+ } break;
+ case DK4_FILE_ENCODING_UTF8 : {
+ encstr = dk4app_log_kwnl[7];
+ } break;
+ case DK4_FILE_ENCODING_UTF16_LE : {
+ encstr = dk4app_log_kwnl[9];
+ } break;
+ case DK4_FILE_ENCODING_UTF16_BE : {
+ encstr = dk4app_log_kwnl[10];
+ } break;
+ case DK4_FILE_ENCODING_32_LE : {
+ encstr = dk4app_log_kwnl[12];
+ } break;
+ case DK4_FILE_ENCODING_32_BE : {
+ encstr = dk4app_log_kwnl[13];
+ } break;
+ }
+ } else {
+ switch (enc) {
+ case DK4_ENCODING_ASCII : {
+ encstr = dk4app_log_kwnl[5];
+ } break;
+ case DK4_ENCODING_ANSI : {
+ encstr = dk4app_log_kwnl[6];
+ } break;
+ case DK4_ENCODING_UTF8 : {
+ encstr = dk4app_log_kwnl[7];
+ } break;
+ case DK4_ENCODING_UTF16 : {
+ encstr = dk4app_log_kwnl[8];
+ } break;
+ case DK4_ENCODING_32 : {
+ encstr = dk4app_log_kwnl[11];
+ } break;
+ }
+ }
+ dk4app_log_two_strings_at_startup(app, title, encstr);
+}
+
+
+
+void
+dk4app_log_startup_debug(dk4_app_t *app)
+{
+ dkChar fnb[DK4_MAX_PATH];
+ dk4_er_t er;
+ const dkChar *msgtxt[3];
+ const dkChar * const *debmsg = NULL;
+ size_t szdebmsg = 0;
+ int res = 0;
+ int pn = 0;
+
+
+#line 1355 "dk4applog.ctr"
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ /* Obtain localized texts */
+ dk4app_log_load_base_texts(app);
+ debmsg = dk4app_log_debug_texts(app, &szdebmsg);
+
+ /* 0 Host name */
+ dk4app_log_two_strings_at_startup(app, debmsg[0], app->host_name);
+
+ /* 1 User name */
+ dk4app_log_two_strings_at_startup(app, debmsg[1], app->user_name);
+
+ /* 2 Home dir */
+ dk4app_log_two_strings_at_startup(app, debmsg[2], app->user_home);
+
+ /* 3 Language */
+ dk4app_log_two_strings_at_startup(app, debmsg[3], app->language);
+
+ /* 4 Region */
+ dk4app_log_two_strings_at_startup(app, debmsg[4], app->region);
+
+ /* 5 Encoding */
+ dk4app_log_startup_encoding(app, debmsg[5], app->encoding, 0);
+
+ /* 6 Encoding stdin */
+ dk4app_log_startup_encoding(app, debmsg[6], app->enc_in_std, 1);
+
+ /* 7 Encoding files */
+ dk4app_log_startup_encoding(app, debmsg[7], app->enc_in_file, 1);
+
+ /* 8 Program name */
+ dk4app_log_two_strings_at_startup(app, debmsg[8], app->prog_name);
+
+ /* 9 Program group */
+ dk4app_log_two_strings_at_startup(app, debmsg[9], app->group_name);
+
+ /* 10 etc */
+ dk4app_log_two_strings_at_startup(app, debmsg[10], app->dir_etc);
+
+ /* 11 bin */
+ dk4app_log_two_strings_at_startup(app, debmsg[11], app->dir_bin);
+
+ /* 12 share */
+ dk4app_log_two_strings_at_startup(app, debmsg[12], app->dir_share);
+
+ /* 13 lib */
+ dk4app_log_two_strings_at_startup(app, debmsg[13], app->dir_lib);
+
+ /* 14 var */
+ dk4app_log_two_strings_at_startup(app, debmsg[14], app->dir_var);
+
+ /* 15 tmp */
+ dk4app_log_two_strings_at_startup(app, debmsg[15], app->dir_tmp);
+
+ /* 17 Log file */
+ dk4app_log_two_strings_at_startup(app, debmsg[17], app->log_file_name);
+
+ /* 16 Logging enabled */
+ dk4app_log_two_strings_at_startup(
+ app, debmsg[16], dk4app_log_kwnl[(0 != app->log_enabled) ? 4 : 3]
+ );
+
+ /* 18 Log level stderr */
+ dk4app_log_startup_log_level(app, debmsg[18], app->ll_stderr);
+
+ /* 19 Log level file */
+ dk4app_log_startup_log_level(app, debmsg[19], app->ll_file);
+
+ /* 20 Log level keep */
+ dk4app_log_startup_log_level(app, debmsg[20], app->ll_file_keep);
+
+ /* Preferences files */
+ dk4app_log_1(app, debmsg, szdebmsg, DK4_LL_DEBUG, 28);
+ for (pn = 0; (pn <= DK4_FS_CONF_MAX); pn++) {
+#if DK4_HAVE_COMPATDKTOOLS3
+ dk4error_init(&er);
+ res = dk4fs_config_construct_compat_one(
+ fnb, DK4_SIZEOF(fnb,dkChar), dk4app_log_kwnl[14],
+ app->dir_share, app->dir_etc, app->user_home,
+ app->prog_name, app->group_name, pn, 1, &er
+ );
+ if (0 != res) {
+ res = dk4fs_attempt_file_name(fnb, DK4_SIZEOF(fnb,dkChar), 1, NULL);
+ if (0 != res) {
+ msgtxt[0] = debmsg[30];
+ msgtxt[1] = fnb;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msgtxt, 2);
+ } else {
+ msgtxt[0] = debmsg[31];
+ msgtxt[1] = fnb;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msgtxt, 2);
+ }
+ }
+#endif
+ dk4error_init(&er);
+ res = dk4fs_config_construct_compat_one(
+ fnb, DK4_SIZEOF(fnb,dkChar), dk4app_log_kwnl[15],
+ app->dir_share, app->dir_etc, app->user_home,
+ app->prog_name, app->group_name, pn, 0, &er
+ );
+ if (0 != res) {
+ res = dk4fs_attempt_file_name(fnb, DK4_SIZEOF(fnb,dkChar), 1, NULL);
+ if (0 != res) {
+ msgtxt[0] = debmsg[30];
+ msgtxt[1] = fnb;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msgtxt, 2);
+ } else {
+ msgtxt[0] = debmsg[31];
+ msgtxt[1] = fnb;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msgtxt, 2);
+ }
+ }
+ }
+#if VERSION_BEFORE_2017_03_13
+ dk4app_log_1(app, debmsg, szdebmsg, DK4_LL_DEBUG, 29);
+#endif
+ }
+ }
+
+
+#line 1474 "dk4applog.ctr"
+}
+
diff --git a/support/dktools/dk4applog.ctr b/support/dktools/dk4applog.ctr
new file mode 100644
index 0000000000..10c7d32416
--- /dev/null
+++ b/support/dktools/dk4applog.ctr
@@ -0,0 +1,1475 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% module
+
+
+#ifndef DK4APP_H_INCLUDED
+#include "dk4app.h"
+#endif
+
+#ifndef DK4CONST_H_INCLUDED
+#include "dk4const.h"
+#endif
+
+#ifndef DK4TIME_H_INCLUDED
+#include "dk4time.h"
+#endif
+
+#ifndef DK4TIMEDK_H_INCLUDED
+#include "dk4timedk.h"
+#endif
+
+#ifndef DK4MAODD_H_INCLUDED
+#include "dk4maodd.h"
+#endif
+
+#ifndef DK4FPUT_H_INCLUDED
+#include "dk4fput.h"
+#endif
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4FOP8_H_INCLUDED
+#include "dk4fopc8.h"
+#endif
+
+#ifndef DK4FOPD_H_INCLUDED
+#include "dk4fopd.h"
+#endif
+
+#ifndef DK4MAODD_H_INCLUDED
+#include "dk4maodd.h"
+#endif
+
+#ifndef DK4ENC_H_INCLUDED
+#include "dk4enc.h"
+#endif
+
+#ifndef DK4APPMKDH_H_INCLUDED
+#include "dk4appmkdh.h"
+#endif
+
+#ifndef DK4MPL_H_INCLUDED
+#include "dk4mpl.h"
+#endif
+
+#ifndef DK4FS_H_INCLUDED
+#include "dk4fs.h"
+#endif
+
+
+
+$!trace-include
+
+
+
+/** Constant char texts used by the module, not localized.
+*/
+static const dkChar * const dk4app_log_kwnl[] = {
+$!string-table macro=dkT
+#
+# 0 1 File opening modes
+#
+w
+a
+#
+# 2 Name of debug string table file
+#
+dk4debug.str
+#
+# 3 4 Indicator for missing information or deactivated option
+#
+-
++
+#
+# 5 ... 13 Encoding names
+#
+ascii
+ansi
+utf-8
+utf-16
+utf-16-le
+utf-16-be
+c32
+c32-le
+c32-be
+#
+# 14 15
+#
+dk3pref.conf
+dk4pref.conf
+$!end
+};
+
+
+
+/** The message texts for the base log domain, nearly always loaded.
+*/
+static const dkChar * const dk4app_def_msg_base[] = {
+$!string-table macro=dkT
+#
+# 0 Log level: Never reached.
+#
+NONE
+#
+# 1 Log level: Panic - Should shut down computer
+#
+Panic
+#
+# 2 Log level: Fatal error - Should abort program
+#
+Fatal
+#
+# 3 Log level: Error
+#
+Error
+#
+# 4 Log level: Warning
+#
+Warning
+#
+# 5 Log level: Information
+#
+Info
+#
+# 6 Log level: Progress message
+#
+Progress
+#
+# 7 Log level: Debug message
+#
+Debug
+#
+# 8 Log level: Ignore message, do not write text
+#
+Ignore
+#
+# 9 10 ERROR: Illegal option!
+#
+Illegal option: "
+"!
+#
+# 11 12 ERROR: Option requires argument!
+#
+Option "
+" requires argument!
+#
+# 13 14 15 ERROR: Option requires boolean argument...
+#
+Option "
+" requires a boolean argument!\n\tRejected text: "
+"!
+#
+# 16 17 18 ERROR: Option requires size argument...
+#
+Option "
+" requires a size argument!\n\tRejected text: "
+"!
+#
+# 19 20 21 ERROR: Option requires integer argument...
+#
+Option "
+" requires integer argument!\n\tRejected text: "
+"!
+#
+# 22 23 24 ERROR: Option requires unsigned integer argument...
+#
+Option "
+" requires unsigned integer argument!\n\tRejected text: "
+"!
+#
+# 25 26 27 ERROR: Option requires double argument...
+#
+Option "
+" requires floating point (double) argument!\n\tRejected text: "
+"!
+#
+# 28 ERROR: Long option requires argument
+#
+Option "--
+#
+# 29 ERROR: Long option requires double argument
+#
+Option "--
+#
+# 30 ERROR: Long option requires unsigned integer argument
+#
+Option "--
+#
+# 31 ERROR: Long option requires integer argument
+#
+Option "--
+#
+# 32 ERROR: Long option requires size specification
+#
+Option "--
+#
+# 33 ERROR: Long option requires boolean argument
+#
+Option "--
+#
+# 34 35 36 ERROR: Failed to save preference value
+#
+Failed to save preference value!\n\t"
+"="
+"!
+#
+# 37 38 ERROR: Value required for preference.
+#
+Value required for command line preference "
+"!
+#
+# 39 40 ERROR: Option too long
+#
+Option too long!\n\t"
+"!
+#
+# 41
+#
+Failed to remove file:\n\t"
+#
+# 42 ENAMETOOLONG Reason for error
+#
+"!\n\tPath name too long.
+#
+# 43 44 45
+#
+Failed to create directory:\n\t"
+"!\n\tPath exists, but is not a directory!
+\n\tLocal network interface is down!
+#
+# 46 47
+#
+Failed to create directory:\n\t"
+"!\n\tIllegal path.
+#
+# 48 Reason for error
+#
+"!\n\tFile or directory in use.
+#
+# 49 Reason for error
+#
+"!\n\tPath already exists.
+#
+# 50 Reason for error
+#
+"!\n\tPath name points outside accessible address space.
+#
+# 51 ENOENT Reason for error.
+#
+"!\n\tPath not found (one path component does not exist).
+#
+# 52 Reason for error
+#
+"!\n\tPath specifies a directory.
+#
+# 53 Reason for error
+#
+"!\n\tNo function for wide-char mkdir available.
+#
+# 54
+#
+No wide-char function to remove files available.
+#
+# 55 EACCESS ERROR_ACCESS_DENIED
+#
+"!\n\tInsufficient permissions.
+#
+# 56 57
+#
+"!\n\tFile system is mounted read-only.
+"!\n\tConflict with extended attribute.
+#
+# 58 59
+#
+"!\n\tNot allowed for this file system type.
+"!\n\tI/O error on device.
+#
+# 60
+#
+"!\n\tDisk space or quota problem.
+#
+# 61 ELOOP Too many symbolic links in path
+#
+"!\n\tToo many symbolic links in path (probably symlink loop).
+#
+# 62 63
+#
+"!\n\tInsufficient kernel memory.
+"!\n\tToo many entries in parent directory.
+#
+# 64 65
+#
+"!\n\tFile server not available.
+"!\n\tName too long.
+#
+# 66 67
+#
+Failed to remove directory:\n\t"
+"!\n\tDirectory not empty.
+#
+# 68 69
+#
+"!\n\tInvalid path name.
+"!\n\tWindows error code:
+#
+# 70 71
+#
+ (0x
+).
+#
+# 72 73
+#
+"!
+"!\n\tParent directory not found (device or server share)!
+#
+# 74 75
+#
+"!\n\tBad network resource name (share name)!
+"!\n\tBad network resource name (server name)!
+#
+# 76 77
+#
+\n\tNo route to network destination available!
+"!
+#
+# 78 EOVERFLOW
+#
+\n\tAttempt to read from outside file!
+#
+# 79 80
+#
+"!\n\tError code:
+.
+#
+# 81
+#
+Options --help, --version, and --license are mutually exclusive!
+#
+# 82 83 84 85
+#
+Numeric overflow in size calculation!
+Numeric overflow in size calculation!\n\t
+ elements of
+ bytes.
+#
+# 86 87 88 89
+#
+Memory allocation failed! Invalid size(s) specified.
+Memory allocation failed! Invalid size(s) specified.\n\tNumber of elements:
+, element size:
+.
+#
+# 90 91 92 93
+#
+Not enough memory! Allcation failed.
+Not enough memory! Allcation failed.\n\tNumber of elements:
+, element size:
+.
+#
+# 94 95
+#
+Further file removal attempts failed in:\n\t"
+"!
+#
+# 96 97
+#
+Further subdirectory removal attempts failed in:\n\t"
+"!
+#
+# 98 99
+#
+File or directory name too long:\n\t"
+"!
+#
+# 100 101 102 103 104 105 106 107
+#
+Failed to expand file name:\n\t"
+"!
+"!\n\tNo function for directory traversal available!
+"!\n\tMemory allocation failed!
+"!\n\tFailed to open directory for traversal!
+"!\n\tDirectory or file name too large!
+"!\n\tMultiple matching files!
+"!\n\tNo matching file!
+#
+# 108 ERROR: Failed to open file...
+#
+Failed to open file:\n\t"
+#
+# 109 110 111 112 113 114 115 116 Error: Not a regular file
+#
+"!\n\tNot a regular file!
+"!\n\tPath contains symbolic links!
+"!\n\tPath is a symbolic link!
+"!\n\tSymbolic link owner is not target owner!
+"!\n\tSignal received!
+"!\n\tToo many open files in process!
+"!\n\tToo many open files on system!
+"!\n\tDevice for special file does not exist!
+#
+# 117 EOVERFLOW
+#
+"!\n\tFile size too large for off_t data type!
+#
+# 118 119 120 Read operation failed
+#
+Read operation failed!
+Read operation failed, error code:
+.
+#
+# 121 EAGAIN / EWOULDBLOCK
+#
+\n\tOperation would block!
+#
+# 122 EBADF
+#
+\n\tBad file descriptor (bug)!
+#
+# 123 EFAULT
+#
+\n\tBuffer is outside usable address space (bug)!
+#
+# 124 EINTR
+#
+\n\tSignal received!
+#
+# 125 EINVAL
+#
+\n\tFile descriptor attached to unsuitable object (bug)!
+#
+# 126 EIO
+#
+\n\tI/O error!
+#
+# 127 EISDIR
+#
+\n\tFile descriptor attachted to directory (bug)!
+#
+# 128 - 130 Error: Write operation failed
+#
+Write operation failed!
+Write operation failed, error code:
+.
+#
+# 131 ENOSPC
+#
+\n\tNo space left on device!
+#
+# 132 EFBIG
+#
+\n\tFile size would exceed limits!
+#
+# 133 EPIPE
+#
+\n\tNo reader attached to pipe or socket!
+#
+# 134 ECONNRESET
+#
+\n\tSocket not connected!
+#
+# 135 ERANGE
+#
+\n\tBuffer size outside supported range!
+#
+# 136 ENOBUFS
+#
+\n\tInsufficient system resources available!
+#
+# 137 ENXIO
+#
+\n\tNonexistent or incapable device!
+#
+# 138 EACCES
+#
+\n\tInsufficient permissions!
+#
+# 139 EBADMSG
+#
+\n\tUnexpected control part in normal-mode message!
+#
+# 140 ECONNRESET
+#
+\n\tConnection reset by peer!
+#
+# 141 ETIMEDOUT
+#
+\n\tTimed out!
+#
+# 142 ENOMEM
+#
+\n\tInsufficient memory available!
+#
+# 143 ESPIPE
+#
+\n\tFile descriptor is socket or FIFO!
+#
+# 144 Failed to open directory!
+#
+Failed to open directory:\n\t"
+#
+# 145 146 147 148 DK4_E_NOT_SUPPORTED
+#
+"!\n\tNo function found for directory traversal!
+"!\n\tNumeric overflow in size calculation!
+"!\n\tPath not found!
+"!\n\tDirectory does not exist!
+#
+# 149 Failed to obtain information about file or directory
+#
+Failed to obtain information about file/directory:\n\t"
+#
+# 150 ENOTDIR
+#
+"!\n\tOne path component is not a directory.
+#
+# 151 ERROR_SHARING_VIOLATION
+#
+"!\n\tCurrently used by another process.
+#
+# 152 153 ERROR: Not a directory
+#
+Not a directory:\n\t"
+"!
+#
+# 154 ERROR text ... in ...
+#
+" in "
+#
+# 155 156 157 158
+#
+Failed to change file buffering!
+Failed to change buffering for file\n"
+"!
+Neither setvbuf() nor setbuffer() function available!
+#
+# 159
+#
+Syntax error, expected line:\n"name = width height [border-left border-right border-top border-bottom]"
+#
+# 160 161 162
+#
+Preference value found: "
+"="
+".
+#
+# 163 164 165
+#
+Preference value too long: "
+"="
+"!
+#
+# 166 167
+#
+Preference value not found: "
+"!
+$!end
+};
+
+
+
+static const dkChar * const dk4app_def_msg_debug[] = {
+$!string-table macro=dkT
+#
+# 0 ... 20 Log texts to show at startup
+#
+Host name:
+User name:
+Home directory:
+Language:
+Region:
+Encoding:
+Encoding expected on standard input:
+Encoding expected on files:
+Program name:
+Program group:
+Directory etc:
+Directory bin:
+Directory share:
+Directory lib:
+Directory var:
+Directory tmp:
+Logging enabled:
+Log file:
+Log level to log on stderr:
+Log level to log to file:
+Log level to keep log file:
+#
+# 21 22 23 Debug messages for data file search.
+#
+Data file search for "
+" failed.
+" succeeded.\n\t
+#
+# 24 Debug messages for configuration file search.
+#
+Configuration file search for "
+#
+# 25 26 27 Delete directory or file.
+#
+Delete directory:
+Delete file:
+Delete file or directory:
+#
+# 28 29 Preference files: , empty string
+#
+Preference files:
+UNUSED
+#
+# 30 31
+#
++
+-
+#
+# 32 33 34 35
+#
+Search for data file "
+Search for configuration file "
+" (compression allowed):
+" (no compression allowed):
+#
+# 36 Collecting paper size data
+#
+Collecting paper size data.
+#
+# 37 38 39 Compression types allowed
+#
+" (gzip compression allowed):
+" (bzip2 compression allowed):
+" (gzip/bzip2 compression allowed):
+#
+# 40 41
+#
+String copy allocated: "
+".
+#
+# 42 43
+#
+Successfully converted to integer.
+Not an integer!
+#
+# 44 45
+#
+Successfully converted to unsigned integer.
+Not an unsigned integer!
+#
+# 46 47
+#
+Successfully converted to boolean.
+Not a boolean!
+#
+# 48 49
+#
+Successfully converted to size specification.
+Not a size specification!
+$!end
+};
+
+
+
+/** Ensure the messages texts for the base log domain are loaded.
+ @param app Application structure.
+ @param logdom Log text domain.
+*/
+static
+void
+dk4app_log_load_base_texts(dk4_app_t *app)
+{
+ $? "+ dk4app_log_load_base_texts"
+ if (NULL != app) { $? ". app"
+ if ((NULL == app->msg_base) || (0 == app->sz_msg_base)) {
+ $? ". read string table"
+ app->sz_msg_base = dk4app_string_table_size(dk4app_def_msg_base);
+ app->msg_base = dk4app_string_table(
+ app, dkT("dk4base.str"), dk4app_def_msg_base
+ );
+ } else { $? ". already available"
+ }
+ } else { $? "! app"
+ } $? "- dk4app_log_load_base_texts"
+}
+
+
+
+/** Check whether there is at least one non-NULL pointer in array.
+ CRT on Windows: Not used.
+ @param msg Array to check.
+ @param sz Size of array.
+ @return 1 if any valid pointer was found, 0 otherwise.
+*/
+static
+int
+dk4app_log_any_non_null(const dkChar * const *msg, size_t sz)
+{
+ size_t i;
+ int back = 0;
+ for (i = 0; ((i < sz) && (0 == back)); i++) {
+ if (NULL != msg[i]) { back = 1; }
+ }
+ return back;
+}
+
+
+
+int
+dk4app_log_do(dk4_app_t *app, int ll)
+{
+ int back = 0;
+ if (NULL != app) {
+#if (!(DK4_ON_WINDOWS && DK4_WIN_DENY_CRT))
+ if (0 != app->log_enabled) {
+ if (app->ll_stderr >= ll) {
+ back = 1;
+ }
+ if (app->ll_file >= ll) {
+ back = 1;
+ }
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+/** Log multi part message to one file.
+ CRT on Windows: Required.
+ @param app Application structure, may be NULL.
+ @param priority Log priority.
+ @param msg Pointer to message parts array.
+ @param sz Number of message parts.
+ @param outfile Output file
+ @param showtime Flag: Show timestamp.
+ @param timer Timestamp of previous log message if any.
+ @param havetime Flag: Timer already contains a value.
+*/
+static
+void
+dk4app_log_msg_to_file(
+ dk4_app_t *app,
+ int priority,
+ const dkChar * const *msg,
+ size_t sz,
+ FILE *outfile,
+ int showtime,
+ dk4_time_t *timer,
+ int *havetime
+)
+{
+#if (!(DK4_ON_WINDOWS && DK4_WIN_DENY_CRT))
+ dkChar lnb[64];
+ dkChar buf[64];
+ size_t i;
+ dk4_time_t ct;
+ int res;
+
+ dk4time_get(&ct);
+ /* Print timestamp */
+ if ((0 != showtime) && ((0 == *havetime) || (ct != *timer))) {
+ *havetime = 1;
+ *timer = ct;
+ if (0 != dk4time_as_text(buf, DK4_SIZEOF(buf,dkChar), &ct, NULL)) {
+ dk4fputs(dkT("# "), outfile, NULL);
+ dk4fputs(buf, outfile, NULL);
+ dk4fputc(dkT('\n'), outfile, NULL);
+ }
+ }
+ /* Print error position */
+ if (NULL != app->source_file_name) {
+ dk4fputs(app->source_file_name, outfile, NULL);
+ dk4fputc(dkT(':'), outfile, NULL);
+ if ((dk4_um_t)0UL != app->source_file_line) {
+ res = dk4ma_write_decimal_unsigned(
+ lnb, DK4_SIZEOF(lnb,dkChar), app->source_file_line, 0, NULL
+ );
+ if (0 != res) {
+ dk4fputs(lnb, outfile, NULL);
+ dk4fputc(dkT(':'), outfile, NULL);
+ }
+ }
+ dk4fputc(dkT(' '), outfile, NULL);
+ }
+ /* Print message */
+ switch (priority) {
+ case DK4_LL_PANIC:
+ case DK4_LL_FATAL:
+ case DK4_LL_ERROR:
+ case DK4_LL_WARNING:
+ {
+ dk4fputs((app->msg_base)[priority], outfile, NULL);
+ dk4fputs(dkT(": "), outfile, NULL);
+ } break;
+ }
+ for (i = 0; i < sz; i++) {
+ dk4fputs(msg[i], outfile, NULL);
+ }
+ dk4fputc(dkT('\n'), outfile, NULL);
+ fflush(outfile);
+#endif
+}
+
+
+
+void
+dk4app_log_msg(
+ dk4_app_t *app,
+ int priority,
+ const dkChar * const *msg,
+ size_t sz
+)
+{
+ FILE *fipo;
+
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, priority)) {
+ dk4app_log_load_base_texts(app);
+ if (0 != dk4app_log_any_non_null(msg, sz)) {
+#if (!(DK4_ON_WINDOWS && DK4_WIN_DENY_CRT))
+ if (app->ll_stderr >= priority) {
+ if (0 == app->have_stderr_init) {
+ dk4fput_initialize_stderr();
+ app->have_stderr_init = 1;
+ }
+ dk4app_log_msg_to_file(
+ app, priority, msg, sz, stderr,
+ app->log_stderr_time, &(app->timer_stderr), &(app->have_stderr_time)
+ );
+ }
+ if (app->ll_file >= priority) {
+ if (NULL != app->log_file_name) {
+#if VERSION_BEFORE_20160127
+#else
+ if (0 == app->have_file_opened) {
+ (void)dk4app_mkdir_hierarchy(app->log_file_name, 0, NULL);
+ }
+#endif
+ fipo = dk4fopen(
+ app->log_file_name,
+ dk4app_log_kwnl[(0 != app->have_file_opened) ? 1 : 0],
+ (DK4_FOPEN_SC_WR_SYMLINK_OWNER | DK4_FOPEN_SC_IS_REGULAR),
+ NULL
+ );
+ app->have_file_opened = 1;
+ if (NULL != fipo) {
+ dk4app_log_msg_to_file(
+ app, priority, msg, sz, fipo,
+ app->log_stderr_time, &(app->timer_file), &(app->have_file_time)
+ );
+ fclose(fipo);
+ }
+ }
+ }
+ if (priority < app->ll_found) {
+ app->ll_found = priority;
+ }
+#endif
+ }
+ }
+ }
+}
+
+
+
+void
+dk4app_log_1(
+ dk4_app_t *app,
+ const dkChar * const *msg,
+ size_t sz_msg,
+ int priority,
+ size_t msgind
+)
+{
+ const dkChar *msgtext;
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, priority)) {
+ dk4app_log_load_base_texts(app);
+ if ((NULL != msg) && (0 < sz_msg) && (msgind < sz_msg)) {
+ msgtext = msg[msgind];
+ dk4app_log_msg(app, priority, &msgtext, 1);
+ }
+ }
+ }
+}
+
+
+
+void
+dk4app_log_2(
+ dk4_app_t *app,
+ const dkChar * const *msg,
+ size_t sz_msg,
+ int priority,
+ size_t i1,
+ const dkChar *t1
+)
+{
+ const dkChar *msgtext[3];
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, priority)) {
+ dk4app_log_load_base_texts(app);
+ if ((NULL != msg) && (0 < sz_msg) && (i1 < sz_msg)) {
+ msgtext[0] = msg[i1];
+ msgtext[1] = t1;
+ dk4app_log_msg(app, priority, msgtext, 2);
+ }
+ }
+ }
+}
+
+
+
+void
+dk4app_log_3(
+ dk4_app_t *app,
+ const dkChar * const *msg,
+ size_t sz_msg,
+ int priority,
+ size_t i1,
+ size_t i2,
+ const dkChar *t1
+)
+{
+ const dkChar *msgtext[3];
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, priority)) {
+ dk4app_log_load_base_texts(app);
+ if ((NULL != msg) && (0 < sz_msg) && (i1 < sz_msg) && (i2 < sz_msg)) {
+ msgtext[0] = msg[i1];
+ msgtext[1] = t1;
+ msgtext[2] = msg[i2];
+ dk4app_log_msg(app, priority, msgtext, 3);
+ }
+ }
+ }
+}
+
+
+
+void
+dk4app_log_5(
+ dk4_app_t *app,
+ const dkChar * const *msg,
+ size_t sz_msg,
+ int priority,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ const dkChar *t1,
+ const dkChar *t2
+)
+{
+ const dkChar *msgtext[5];
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, priority)) {
+ dk4app_log_load_base_texts(app);
+ if ((NULL != msg) && (0 < sz_msg) && (i1 < sz_msg) && (i2 < sz_msg)) {
+ msgtext[0] = msg[i1];
+ msgtext[1] = t1;
+ msgtext[2] = msg[i2];
+ msgtext[3] = t2;
+ msgtext[4] = msg[i3];
+ dk4app_log_msg(app, priority, msgtext, 5);
+ }
+ }
+ }
+}
+
+
+
+void
+dk4app_log_7(
+ dk4_app_t *app,
+ const dkChar * const *msg,
+ size_t sz_msg,
+ int priority,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ size_t i4,
+ const dkChar *t1,
+ const dkChar *t2,
+ const dkChar *t3
+)
+{
+ const dkChar *msgtext[7];
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, priority)) {
+ dk4app_log_load_base_texts(app);
+ if (
+ (NULL != msg)
+ && (0 < sz_msg) && (i1 < sz_msg) && (i2 < sz_msg) && (i3 < sz_msg)
+ )
+ {
+ msgtext[0] = msg[i1];
+ msgtext[1] = t1;
+ msgtext[2] = msg[i2];
+ msgtext[3] = t2;
+ msgtext[4] = msg[i3];
+ msgtext[5] = t3;
+ msgtext[6] = msg[i4];
+ dk4app_log_msg(app, priority, msgtext, 7);
+ }
+ }
+ }
+}
+
+
+
+void
+dk4app_log_base1(
+ dk4_app_t *app,
+ int priority,
+ size_t msgind
+)
+{
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, priority)) {
+ dk4app_log_load_base_texts(app);
+ dk4app_log_1(app, app->msg_base, app->sz_msg_base, priority, msgind);
+ }
+ }
+}
+
+
+
+void
+dk4app_log_base2(
+ dk4_app_t *app,
+ int priority,
+ size_t i1,
+ const dkChar *t1
+)
+{
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, priority)) {
+ dk4app_log_load_base_texts(app);
+ dk4app_log_2(app,app->msg_base,app->sz_msg_base,priority,i1,t1);
+ }
+ }
+}
+
+
+
+void
+dk4app_log_base2c(
+ dk4_app_t *app,
+ int priority,
+ size_t i1,
+ size_t i2
+)
+{
+ const dkChar *msgptr[2];
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, priority)) {
+ if ((app->sz_msg_base > i1) && (app->sz_msg_base > i2)) {
+ dk4app_log_load_base_texts(app);
+ msgptr[0] = (app->msg_base)[i1];
+ msgptr[1] = (app->msg_base)[i2];
+ dk4app_log_msg(app, priority, msgptr, 2);
+ }
+ }
+ }
+}
+
+
+
+void
+dk4app_log_base3(
+ dk4_app_t *app,
+ int priority,
+ size_t i1,
+ size_t i2,
+ const dkChar *t1
+)
+{
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, priority)) {
+ dk4app_log_load_base_texts(app);
+ dk4app_log_3(app,app->msg_base,app->sz_msg_base,priority,i1,i2,t1);
+ }
+ }
+}
+
+
+
+void
+dk4app_log_base5(
+ dk4_app_t *app,
+ int priority,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ const dkChar *t1,
+ const dkChar *t2
+)
+{
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, priority)) {
+ dk4app_log_load_base_texts(app);
+ dk4app_log_5(app,app->msg_base,app->sz_msg_base,priority,i1,i2,i3,t1,t2);
+ }
+ }
+}
+
+
+
+void
+dk4app_log_base7(
+ dk4_app_t *app,
+ int priority,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ size_t i4,
+ const dkChar *t1,
+ const dkChar *t2,
+ const dkChar *t3
+)
+{
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, priority)) {
+ dk4app_log_load_base_texts(app);
+ dk4app_log_7(
+ app,app->msg_base,app->sz_msg_base,priority,i1,i2,i3,i4,t1,t2,t3
+ );
+ }
+ }
+}
+
+
+
+void
+dk4app_log_with_errno(
+ dk4_app_t *app,
+ int priority,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ size_t i4,
+ size_t i5,
+ const dkChar *t1,
+ int errn
+)
+{
+ dkChar enb[64];
+ int res;
+ if (NULL != app) {
+ res = dk4ma_write_decimal_signed(
+ enb, DK4_SIZEOF(enb,dkChar), (dk4_im_t)errn, 0, NULL
+ );
+ if (0 != res) {
+ dk4app_log_base5(app, priority, i1, i2, i3, t1, enb);
+ } else {
+ dk4app_log_base3(app, priority, i4, i5, t1);
+ }
+ }
+}
+
+
+
+const dkChar *
+dk4app_get_log_source_file(dk4_app_t *app)
+{
+ const dkChar *back = NULL;
+ if (NULL != app) {
+ back = app->source_file_name;
+ }
+ return back;
+}
+
+
+
+dk4_um_t
+dk4app_get_log_source_line(dk4_app_t *app)
+{
+ dk4_um_t back = (dk4_um_t)0UL;
+ if (NULL != app) {
+ back = app->source_file_line;
+ }
+ return back;
+}
+
+
+
+void
+dk4app_set_log_source_file(dk4_app_t *app, const dkChar *fn)
+{
+ if (NULL != app) {
+ app->source_file_name = fn;
+ }
+}
+
+
+
+void
+dk4app_set_log_source_line(dk4_app_t *app, dk4_um_t lineno)
+{
+ if (NULL != app) {
+ app->source_file_line = lineno;
+ }
+}
+
+
+
+const dkChar * const *
+dk4app_log_debug_texts(dk4_app_t *app, size_t *szptr)
+{
+ const dkChar * const *back = NULL;
+ $? "+ dk4app_log_debug_texts"
+ if (NULL != app) { $? ". app"
+ dk4app_log_load_base_texts(app);
+ if ((NULL != app->msg_debug) && (0 < app->sz_msg_debug)) {
+ back = app->msg_debug; $? ". already loaded"
+ } else { $? ". must load"
+ app->msg_debug = dk4app_string_table(
+ app, dk4app_log_kwnl[2], dk4app_def_msg_debug
+ );
+ app->sz_msg_debug = dk4app_string_table_size(app->msg_debug);
+ back = app->msg_debug;
+ }
+ } else { $? "! app"
+ back = dk4app_def_msg_debug;
+ }
+ if (NULL != szptr) {
+ *szptr = dk4app_string_table_size(dk4app_def_msg_debug);
+ }
+ $? "- dk4app_log_debug_texts"
+ return back;
+}
+
+
+
+static
+void
+dk4app_log_two_strings_at_startup(
+ dk4_app_t *app,
+ const dkChar *title,
+ const dkChar *value
+)
+{
+ const dkChar *msg[3];
+ msg[0] = title;
+ msg[1] = value;
+ if (NULL == value) {
+ msg[1] = dk4app_log_kwnl[3];
+ }
+ msg[2] = NULL;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 2);
+}
+
+
+
+static
+void
+dk4app_log_startup_log_level(
+ dk4_app_t *app,
+ const dkChar *title,
+ int ll
+)
+{
+ const dkChar *llstr = NULL;
+ if ((DK4_LL_NONE <= ll) && (DK4_LL_IGNORE >= ll)) {
+ llstr = (app->msg_base)[(size_t)ll];
+ }
+ dk4app_log_two_strings_at_startup(app, title, llstr);
+}
+
+
+
+static
+void
+dk4app_log_startup_encoding(
+ dk4_app_t *app,
+ const dkChar *title,
+ int enc,
+ int isfileenc
+)
+{
+ const dkChar *encstr = NULL;
+ if (0 != isfileenc) {
+ switch (enc) {
+ case DK4_FILE_ENCODING_ASCII : {
+ encstr = dk4app_log_kwnl[5];
+ } break;
+ case DK4_FILE_ENCODING_ANSI : {
+ encstr = dk4app_log_kwnl[6];
+ } break;
+ case DK4_FILE_ENCODING_UTF8 : {
+ encstr = dk4app_log_kwnl[7];
+ } break;
+ case DK4_FILE_ENCODING_UTF16_LE : {
+ encstr = dk4app_log_kwnl[9];
+ } break;
+ case DK4_FILE_ENCODING_UTF16_BE : {
+ encstr = dk4app_log_kwnl[10];
+ } break;
+ case DK4_FILE_ENCODING_32_LE : {
+ encstr = dk4app_log_kwnl[12];
+ } break;
+ case DK4_FILE_ENCODING_32_BE : {
+ encstr = dk4app_log_kwnl[13];
+ } break;
+ }
+ } else {
+ switch (enc) {
+ case DK4_ENCODING_ASCII : {
+ encstr = dk4app_log_kwnl[5];
+ } break;
+ case DK4_ENCODING_ANSI : {
+ encstr = dk4app_log_kwnl[6];
+ } break;
+ case DK4_ENCODING_UTF8 : {
+ encstr = dk4app_log_kwnl[7];
+ } break;
+ case DK4_ENCODING_UTF16 : {
+ encstr = dk4app_log_kwnl[8];
+ } break;
+ case DK4_ENCODING_32 : {
+ encstr = dk4app_log_kwnl[11];
+ } break;
+ }
+ }
+ dk4app_log_two_strings_at_startup(app, title, encstr);
+}
+
+
+
+void
+dk4app_log_startup_debug(dk4_app_t *app)
+{
+ dkChar fnb[DK4_MAX_PATH];
+ dk4_er_t er;
+ const dkChar *msgtxt[3];
+ const dkChar * const *debmsg = NULL;
+ size_t szdebmsg = 0;
+ int res = 0;
+ int pn = 0;
+ $? "+ dk4app_log_startup_debug"
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ /* Obtain localized texts */
+ dk4app_log_load_base_texts(app);
+ debmsg = dk4app_log_debug_texts(app, &szdebmsg);
+
+ /* 0 Host name */
+ dk4app_log_two_strings_at_startup(app, debmsg[0], app->host_name);
+
+ /* 1 User name */
+ dk4app_log_two_strings_at_startup(app, debmsg[1], app->user_name);
+
+ /* 2 Home dir */
+ dk4app_log_two_strings_at_startup(app, debmsg[2], app->user_home);
+
+ /* 3 Language */
+ dk4app_log_two_strings_at_startup(app, debmsg[3], app->language);
+
+ /* 4 Region */
+ dk4app_log_two_strings_at_startup(app, debmsg[4], app->region);
+
+ /* 5 Encoding */
+ dk4app_log_startup_encoding(app, debmsg[5], app->encoding, 0);
+
+ /* 6 Encoding stdin */
+ dk4app_log_startup_encoding(app, debmsg[6], app->enc_in_std, 1);
+
+ /* 7 Encoding files */
+ dk4app_log_startup_encoding(app, debmsg[7], app->enc_in_file, 1);
+
+ /* 8 Program name */
+ dk4app_log_two_strings_at_startup(app, debmsg[8], app->prog_name);
+
+ /* 9 Program group */
+ dk4app_log_two_strings_at_startup(app, debmsg[9], app->group_name);
+
+ /* 10 etc */
+ dk4app_log_two_strings_at_startup(app, debmsg[10], app->dir_etc);
+
+ /* 11 bin */
+ dk4app_log_two_strings_at_startup(app, debmsg[11], app->dir_bin);
+
+ /* 12 share */
+ dk4app_log_two_strings_at_startup(app, debmsg[12], app->dir_share);
+
+ /* 13 lib */
+ dk4app_log_two_strings_at_startup(app, debmsg[13], app->dir_lib);
+
+ /* 14 var */
+ dk4app_log_two_strings_at_startup(app, debmsg[14], app->dir_var);
+
+ /* 15 tmp */
+ dk4app_log_two_strings_at_startup(app, debmsg[15], app->dir_tmp);
+
+ /* 17 Log file */
+ dk4app_log_two_strings_at_startup(app, debmsg[17], app->log_file_name);
+
+ /* 16 Logging enabled */
+ dk4app_log_two_strings_at_startup(
+ app, debmsg[16], dk4app_log_kwnl[(0 != app->log_enabled) ? 4 : 3]
+ );
+
+ /* 18 Log level stderr */
+ dk4app_log_startup_log_level(app, debmsg[18], app->ll_stderr);
+
+ /* 19 Log level file */
+ dk4app_log_startup_log_level(app, debmsg[19], app->ll_file);
+
+ /* 20 Log level keep */
+ dk4app_log_startup_log_level(app, debmsg[20], app->ll_file_keep);
+
+ /* Preferences files */
+ dk4app_log_1(app, debmsg, szdebmsg, DK4_LL_DEBUG, 28);
+ for (pn = 0; (pn <= DK4_FS_CONF_MAX); pn++) {
+#if DK4_HAVE_COMPATDKTOOLS3
+ dk4error_init(&er);
+ res = dk4fs_config_construct_compat_one(
+ fnb, DK4_SIZEOF(fnb,dkChar), dk4app_log_kwnl[14],
+ app->dir_share, app->dir_etc, app->user_home,
+ app->prog_name, app->group_name, pn, 1, &er
+ );
+ if (0 != res) {
+ res = dk4fs_attempt_file_name(fnb, DK4_SIZEOF(fnb,dkChar), 1, NULL);
+ if (0 != res) {
+ msgtxt[0] = debmsg[30];
+ msgtxt[1] = fnb;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msgtxt, 2);
+ } else {
+ msgtxt[0] = debmsg[31];
+ msgtxt[1] = fnb;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msgtxt, 2);
+ }
+ }
+#endif
+ dk4error_init(&er);
+ res = dk4fs_config_construct_compat_one(
+ fnb, DK4_SIZEOF(fnb,dkChar), dk4app_log_kwnl[15],
+ app->dir_share, app->dir_etc, app->user_home,
+ app->prog_name, app->group_name, pn, 0, &er
+ );
+ if (0 != res) {
+ res = dk4fs_attempt_file_name(fnb, DK4_SIZEOF(fnb,dkChar), 1, NULL);
+ if (0 != res) {
+ msgtxt[0] = debmsg[30];
+ msgtxt[1] = fnb;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msgtxt, 2);
+ } else {
+ msgtxt[0] = debmsg[31];
+ msgtxt[1] = fnb;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msgtxt, 2);
+ }
+ }
+ }
+#if VERSION_BEFORE_2017_03_13
+ dk4app_log_1(app, debmsg, szdebmsg, DK4_LL_DEBUG, 29);
+#endif
+ }
+ }
+ $? "- dk4app_log_startup_debug"
+}
+
diff --git a/support/dktools/dk4appmkdh.c b/support/dktools/dk4appmkdh.c
new file mode 100644
index 0000000000..87ecc95aca
--- /dev/null
+++ b/support/dktools/dk4appmkdh.c
@@ -0,0 +1,402 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4appmkdh.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4appmkdh.c The dk4appmkdh module.
+*/
+
+
+#line 54 "dk4appmkdh.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4appmkdh.h"
+
+#if DK4_HAVE_SYS_STAT_H
+#ifndef SYS_STAT_H_INCLUDED
+#include <sys/stat.h>
+#define SYS_STAT_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_DIRECT_H
+#ifndef DIRECT_H_INCLUDED
+#include <direct.h>
+#define DIRECT_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4CONST_H_INCLUDED
+#include "dk4const.h"
+#endif
+
+#ifndef DK4MPL_H_INCLUDED
+#include "dk4mpl.h"
+#endif
+
+#ifndef DK4STR_H_INCLUDED
+#include "dk4strd.h"
+#endif
+
+#ifndef DK4STRDA_H_INCLUDED
+#include "dk4strda.h"
+#endif
+
+#ifndef DK4MAODD_H_INCLUDED
+#include "dk4maodd.h"
+#endif
+
+#ifndef DK4MAODH_H_INCLUDED
+#include "dk4maodh.h"
+#endif
+
+#ifndef DK4STAT_H_INCLUDED
+#include "dk4stat.h"
+#endif
+
+#ifndef DK4PATH_H_INCLUDED
+#include "dk4pathd.h"
+#endif
+
+#if DK4_CHAR_SIZE > 1
+#ifndef DK4MKDHW_H_INCLUDED
+#include "dk4mkdhw.h"
+#endif
+#else
+#ifndef DK4MKDH8_H_INCLUDED
+#include "dk4mkdh8.h"
+#endif
+#endif
+
+
+
+
+
+#line 165 "dk4appmkdh.ctr"
+
+
+
+static
+void
+dk4app_mkdir_hierarchy_report(dk4_app_t *app, const dkChar *fnb, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ dkChar eb1[8 * sizeof(DWORD)];
+ dkChar eb2[8 * sizeof(DWORD)];
+ int res;
+#endif
+
+ switch (erp->ec) {
+ case DK4_E_NON_DIR: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 43, 44, fnb);
+ } break;
+#if DK4_ON_WINDOWS
+ case DK4_E_CREATE_DIR_FAILED: {
+ if (ERROR_ALREADY_EXISTS == (erp->dt).lDetails1) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 43, 44, fnb);
+ goto finished;
+ }
+ if (ERROR_PATH_NOT_FOUND == (erp->dt).lDetails1) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 51, fnb);
+ goto finished;
+ }
+ if (ERROR_ACCESS_DENIED == (erp->dt).lDetails1) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 55, fnb);
+ goto finished;
+ }
+ if (ERROR_BAD_NET_NAME == (erp->dt).lDetails1) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 74, fnb);
+ goto finished;
+ }
+ if (ERROR_BAD_NETPATH == (erp->dt).lDetails1) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 75, fnb);
+ goto finished;
+ }
+ res = dk4ma_write_decimal_unsigned(
+ eb1, DK4_SIZEOF(eb1,dkChar), (dk4_um_t)((erp->dt).lDetails1), 0, NULL
+ );
+ if (0 != res) {
+ res = dk4ma_write_hex_unsigned(
+ eb2, DK4_SIZEOF(eb2,dkChar), (dk4_um_t)((erp->dt).lDetails1), 0, NULL
+ );
+ }
+ if (0 != res) {
+ dk4app_log_base7( app, DK4_LL_ERROR, 46, 69, 70, 71, fnb, eb1, eb2);
+ } else {
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 40, fnb);
+ }
+ } break;
+#endif
+ case DK4_E_MKDIR_FAILED: {
+ switch ((erp->dt).iDetails1) {
+#ifdef EEXIST
+ case EEXIST : { /* Path already exists */
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 49, fnb);
+ } break;
+#endif
+#ifdef ENOENT
+ case ENOENT : { /* Path not found */
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 51, fnb);
+ } break;
+#endif
+#ifdef EACCES
+ case EACCES : { /* Permissions problem */
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 55, fnb);
+ } break;
+#endif
+#ifdef EIO
+ case EIO : { /* I/O error occured */
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 59, fnb);
+ } break;
+#endif
+#ifdef EMLINK
+ case EMLINK : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 63, fnb);
+ } break;
+#endif
+#ifdef ENAMETOOLONG
+ case ENAMETOOLONG : { /* Name too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 65, fnb);
+ } break;
+#endif
+#ifdef ENOMEM
+ case ENOMEM : { /* Insufficient kernel memory */
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 62, fnb);
+ } break;
+#endif
+#ifdef ENOSPC
+ case ENOSPC : { /* Not enough space (space/quota) */
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 60, fnb);
+ } break;
+#endif
+#ifdef EPERM
+ case EPERM : { /* FS does not support dir creation */
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 58, fnb);
+ } break;
+#endif
+#ifdef EROFS
+ case EROFS : { /* Read-only file system */
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 56, fnb);
+ } break;
+#endif
+#ifdef ENOTDIR
+ case ENOTDIR : { /* One component is not a dir */
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 150, fnb);
+ } break;
+#endif
+ default: {
+ dk4app_log_with_errno(
+ app, DK4_LL_ERROR, 46, 79, 80, 46, 77, fnb, errno
+ );
+ } break;
+ }
+ } break;
+ case DK4_E_NOT_FOUND : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 73, fnb);
+ } break;
+ case DK4_E_INVALID_ARGUMENTS : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 47, fnb);
+ } break;
+ default: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 72, fnb);
+ } break;
+ }
+#if DK4_ON_WINDOWS
+ finished: ;
+#endif
+}
+
+
+
+static
+int
+dk4app_mkdir_hierarchy_on_copy(dkChar *fn, int lc, dk4_app_t *app)
+{
+ dk4_er_t er;
+ dkChar *pc = NULL;
+ int back = 0;
+
+ /* Correct path name */
+ dk4path_correct_sep(fn);
+
+ dk4error_init(&er);
+#if DK4_CHAR_SIZE > 1
+ pc = dk4mkdir_hierarchy_wc_first_sep(fn, &back, lc, &er);
+#else
+ pc = dk4mkdir_hierarchy_c8_first_sep(fn, &back, lc, &er);
+#endif
+ if ((NULL != pc) || (0 != back)) {
+ if (NULL != pc) {
+ back = 1;
+ while (NULL != pc) {
+ *pc = dkT('\0');
+ if (0 < dk4str_len(fn)) {
+ dk4error_init(&er);
+#if DK4_CHAR_SIZE > 1
+ if (0 == dk4mkdir_hierarchy_wc_one(fn, 0, &er))
+#else
+ if (0 == dk4mkdir_hierarchy_c8_one(fn, 0, &er))
+#endif
+ {
+ back = 0;
+ dk4app_mkdir_hierarchy_report(app, fn, &er);
+ }
+ }
+#if DK4_HAVE_BACKSLASH_AS_SEP
+ *pc = dkT('\\');
+ pc = dk4str_chr(&(pc[1]), dkT('\\'));
+#else
+ *pc = dkT('/');
+ pc = dk4str_chr(&(pc[1]), dkT('/'));
+#endif
+ }
+ if (0 != lc) {
+ dk4error_init(&er);
+#if DK4_CHAR_SIZE > 1
+ if (0 == dk4mkdir_hierarchy_wc_one(fn, 0, &er))
+#else
+ if (0 == dk4mkdir_hierarchy_c8_one(fn, 0, &er))
+#endif
+ {
+ back = 0;
+ dk4app_mkdir_hierarchy_report(app, fn, &er);
+ }
+ }
+ }
+ } else {
+ dk4app_mkdir_hierarchy_report(app, fn, &er);
+ }
+ return back;
+}
+
+
+
+static
+int
+dk4app_mkdir_hierarchy_local(const dkChar *fn, int lc, dk4_app_t *app)
+{
+ dkChar mycp[DK4_MAX_PATH];
+ int back = 0;
+ if (dk4str_cpy_s(mycp, DK4_SIZEOF(mycp,dkChar), fn, NULL)) {
+ back = dk4app_mkdir_hierarchy_on_copy(mycp, lc, app);
+ } else {
+ /* ERROR: Bug */
+ }
+ return back;
+}
+
+
+
+int
+dk4app_mkdir_hierarchy(const dkChar *fn, int lc, dk4_app_t *app)
+{
+ dkChar *mycp;
+ size_t sz;
+ int back = 0;
+
+
+#line 386 "dk4appmkdh.ctr"
+ if (NULL != fn) {
+#if DK4_ON_WINDOWS || (1 == DK4_CHAR_SIZE)
+ sz = dk4str_len(fn);
+ if (DK4_MAX_PATH > sz) {
+ back = dk4app_mkdir_hierarchy_local(fn, lc, app);
+ } else {
+ mycp = dk4str_dup_app(fn, app);
+ if (NULL != mycp) {
+ back = dk4app_mkdir_hierarchy_on_copy(mycp, lc, app);
+ dk4mem_free(mycp);
+ }
+ }
+#else
+ /* ERROR: Not supported */
+#error "Wide characters are supported on the Windows platform only!"
+#endif
+ } else {
+
+#line 403 "dk4appmkdh.ctr"
+ }
+
+#line 404 "dk4appmkdh.ctr"
+ return back;
+}
+
+
diff --git a/support/dktools/dk4appmkdh.ctr b/support/dktools/dk4appmkdh.ctr
new file mode 100644
index 0000000000..c490b9b119
--- /dev/null
+++ b/support/dktools/dk4appmkdh.ctr
@@ -0,0 +1,407 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Create directory structure.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4APP_H_INCLUDED
+#include "dk4app.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Create directory structure.
+ @param fn File name.
+ @param lc Flag: Last component in fn is directory too.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4app_mkdir_hierarchy(const dkChar *fn, int lc, dk4_app_t *app);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4appmkdh.h"
+
+#if DK4_HAVE_SYS_STAT_H
+#ifndef SYS_STAT_H_INCLUDED
+#include <sys/stat.h>
+#define SYS_STAT_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_DIRECT_H
+#ifndef DIRECT_H_INCLUDED
+#include <direct.h>
+#define DIRECT_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4CONST_H_INCLUDED
+#include "dk4const.h"
+#endif
+
+#ifndef DK4MPL_H_INCLUDED
+#include "dk4mpl.h"
+#endif
+
+#ifndef DK4STR_H_INCLUDED
+#include "dk4strd.h"
+#endif
+
+#ifndef DK4STRDA_H_INCLUDED
+#include "dk4strda.h"
+#endif
+
+#ifndef DK4MAODD_H_INCLUDED
+#include "dk4maodd.h"
+#endif
+
+#ifndef DK4MAODH_H_INCLUDED
+#include "dk4maodh.h"
+#endif
+
+#ifndef DK4STAT_H_INCLUDED
+#include "dk4stat.h"
+#endif
+
+#ifndef DK4PATH_H_INCLUDED
+#include "dk4pathd.h"
+#endif
+
+#if DK4_CHAR_SIZE > 1
+#ifndef DK4MKDHW_H_INCLUDED
+#include "dk4mkdhw.h"
+#endif
+#else
+#ifndef DK4MKDH8_H_INCLUDED
+#include "dk4mkdh8.h"
+#endif
+#endif
+
+
+
+$!trace-include
+
+
+
+static
+void
+dk4app_mkdir_hierarchy_report(dk4_app_t *app, const dkChar *fnb, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ dkChar eb1[8 * sizeof(DWORD)];
+ dkChar eb2[8 * sizeof(DWORD)];
+ int res;
+#endif
+
+ switch (erp->ec) {
+ case DK4_E_NON_DIR: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 43, 44, fnb);
+ } break;
+#if DK4_ON_WINDOWS
+ case DK4_E_CREATE_DIR_FAILED: {
+ if (ERROR_ALREADY_EXISTS == (erp->dt).lDetails1) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 43, 44, fnb);
+ goto finished;
+ }
+ if (ERROR_PATH_NOT_FOUND == (erp->dt).lDetails1) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 51, fnb);
+ goto finished;
+ }
+ if (ERROR_ACCESS_DENIED == (erp->dt).lDetails1) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 55, fnb);
+ goto finished;
+ }
+ if (ERROR_BAD_NET_NAME == (erp->dt).lDetails1) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 74, fnb);
+ goto finished;
+ }
+ if (ERROR_BAD_NETPATH == (erp->dt).lDetails1) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 75, fnb);
+ goto finished;
+ }
+ res = dk4ma_write_decimal_unsigned(
+ eb1, DK4_SIZEOF(eb1,dkChar), (dk4_um_t)((erp->dt).lDetails1), 0, NULL
+ );
+ if (0 != res) {
+ res = dk4ma_write_hex_unsigned(
+ eb2, DK4_SIZEOF(eb2,dkChar), (dk4_um_t)((erp->dt).lDetails1), 0, NULL
+ );
+ }
+ if (0 != res) {
+ dk4app_log_base7( app, DK4_LL_ERROR, 46, 69, 70, 71, fnb, eb1, eb2);
+ } else {
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 40, fnb);
+ }
+ } break;
+#endif
+ case DK4_E_MKDIR_FAILED: {
+ switch ((erp->dt).iDetails1) {
+#ifdef EEXIST
+ case EEXIST : { /* Path already exists */
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 49, fnb);
+ } break;
+#endif
+#ifdef ENOENT
+ case ENOENT : { /* Path not found */
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 51, fnb);
+ } break;
+#endif
+#ifdef EACCES
+ case EACCES : { /* Permissions problem */
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 55, fnb);
+ } break;
+#endif
+#ifdef EIO
+ case EIO : { /* I/O error occured */
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 59, fnb);
+ } break;
+#endif
+#ifdef EMLINK
+ case EMLINK : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 63, fnb);
+ } break;
+#endif
+#ifdef ENAMETOOLONG
+ case ENAMETOOLONG : { /* Name too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 65, fnb);
+ } break;
+#endif
+#ifdef ENOMEM
+ case ENOMEM : { /* Insufficient kernel memory */
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 62, fnb);
+ } break;
+#endif
+#ifdef ENOSPC
+ case ENOSPC : { /* Not enough space (space/quota) */
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 60, fnb);
+ } break;
+#endif
+#ifdef EPERM
+ case EPERM : { /* FS does not support dir creation */
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 58, fnb);
+ } break;
+#endif
+#ifdef EROFS
+ case EROFS : { /* Read-only file system */
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 56, fnb);
+ } break;
+#endif
+#ifdef ENOTDIR
+ case ENOTDIR : { /* One component is not a dir */
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 150, fnb);
+ } break;
+#endif
+ default: {
+ dk4app_log_with_errno(
+ app, DK4_LL_ERROR, 46, 79, 80, 46, 77, fnb, errno
+ );
+ } break;
+ }
+ } break;
+ case DK4_E_NOT_FOUND : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 73, fnb);
+ } break;
+ case DK4_E_INVALID_ARGUMENTS : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 47, fnb);
+ } break;
+ default: {
+ dk4app_log_base3(app, DK4_LL_ERROR, 46, 72, fnb);
+ } break;
+ }
+#if DK4_ON_WINDOWS
+ finished: ;
+#endif
+}
+
+
+
+static
+int
+dk4app_mkdir_hierarchy_on_copy(dkChar *fn, int lc, dk4_app_t *app)
+{
+ dk4_er_t er;
+ dkChar *pc = NULL;
+ int back = 0;
+
+ /* Correct path name */
+ dk4path_correct_sep(fn);
+
+ dk4error_init(&er);
+#if DK4_CHAR_SIZE > 1
+ pc = dk4mkdir_hierarchy_wc_first_sep(fn, &back, lc, &er);
+#else
+ pc = dk4mkdir_hierarchy_c8_first_sep(fn, &back, lc, &er);
+#endif
+ if ((NULL != pc) || (0 != back)) {
+ if (NULL != pc) {
+ back = 1;
+ while (NULL != pc) {
+ *pc = dkT('\0');
+ if (0 < dk4str_len(fn)) {
+ dk4error_init(&er);
+#if DK4_CHAR_SIZE > 1
+ if (0 == dk4mkdir_hierarchy_wc_one(fn, 0, &er))
+#else
+ if (0 == dk4mkdir_hierarchy_c8_one(fn, 0, &er))
+#endif
+ {
+ back = 0;
+ dk4app_mkdir_hierarchy_report(app, fn, &er);
+ }
+ }
+#if DK4_HAVE_BACKSLASH_AS_SEP
+ *pc = dkT('\\');
+ pc = dk4str_chr(&(pc[1]), dkT('\\'));
+#else
+ *pc = dkT('/');
+ pc = dk4str_chr(&(pc[1]), dkT('/'));
+#endif
+ }
+ if (0 != lc) {
+ dk4error_init(&er);
+#if DK4_CHAR_SIZE > 1
+ if (0 == dk4mkdir_hierarchy_wc_one(fn, 0, &er))
+#else
+ if (0 == dk4mkdir_hierarchy_c8_one(fn, 0, &er))
+#endif
+ {
+ back = 0;
+ dk4app_mkdir_hierarchy_report(app, fn, &er);
+ }
+ }
+ }
+ } else {
+ dk4app_mkdir_hierarchy_report(app, fn, &er);
+ }
+ return back;
+}
+
+
+
+static
+int
+dk4app_mkdir_hierarchy_local(const dkChar *fn, int lc, dk4_app_t *app)
+{
+ dkChar mycp[DK4_MAX_PATH];
+ int back = 0;
+ if (dk4str_cpy_s(mycp, DK4_SIZEOF(mycp,dkChar), fn, NULL)) {
+ back = dk4app_mkdir_hierarchy_on_copy(mycp, lc, app);
+ } else {
+ /* ERROR: Bug */
+ }
+ return back;
+}
+
+
+
+int
+dk4app_mkdir_hierarchy(const dkChar *fn, int lc, dk4_app_t *app)
+{
+ dkChar *mycp;
+ size_t sz;
+ int back = 0;
+ $? "+ dk4app_mkdir_hierarchy PTR=%d", TR_IPTR(fn)
+ if (NULL != fn) {
+#if DK4_ON_WINDOWS || (1 == DK4_CHAR_SIZE)
+ sz = dk4str_len(fn);
+ if (DK4_MAX_PATH > sz) {
+ back = dk4app_mkdir_hierarchy_local(fn, lc, app);
+ } else {
+ mycp = dk4str_dup_app(fn, app);
+ if (NULL != mycp) {
+ back = dk4app_mkdir_hierarchy_on_copy(mycp, lc, app);
+ dk4mem_free(mycp);
+ }
+ }
+#else
+ /* ERROR: Not supported */
+#error "Wide characters are supported on the Windows platform only!"
+#endif
+ } else { $? "! fn"
+ } $? "- dk4app_mkdir_hierarchy %d", back
+ return back;
+}
+
+
diff --git a/support/dktools/dk4appmkdh.h b/support/dktools/dk4appmkdh.h
new file mode 100644
index 0000000000..19939599ec
--- /dev/null
+++ b/support/dktools/dk4appmkdh.h
@@ -0,0 +1,86 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4appmkdh.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4APPMKDH_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4APPMKDH_H_INCLUDED 1
+
+
+#line 10 "dk4appmkdh.ctr"
+
+/** @file
+ Create directory structure.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4APP_H_INCLUDED
+#include "dk4app.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Create directory structure.
+ @param fn File name.
+ @param lc Flag: Last component in fn is directory too.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4app_mkdir_hierarchy(const dkChar *fn, int lc, dk4_app_t *app);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+
+#endif
diff --git a/support/dktools/dk4appop.c b/support/dktools/dk4appop.c
new file mode 100644
index 0000000000..a760d2c49d
--- /dev/null
+++ b/support/dktools/dk4appop.c
@@ -0,0 +1,3113 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4appop.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#line 10 "dk4appop.ctr"
+
+/** @file
+ Open and close dk4_app_t structure.
+*/
+
+#ifndef DK4APP_H_INCLUDED
+#include "dk4app.h"
+#endif
+
+#ifndef DK4STT_H_INCLUDED
+#include "dk4stt.h"
+#endif
+
+#ifndef DK4CONST_H_INCLUDED
+#include "dk4const.h"
+#endif
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4STR8_H_INCLUDED
+#include "dk4str8.h"
+#endif
+
+#ifndef DK4STRW_H_INCLUDED
+#include "dk4strw.h"
+#endif
+
+#ifndef DK4STRD_H_INCLUDED
+#include "dk4strd.h"
+#endif
+
+#ifndef DK4ENC_H_INCLUDED
+#include "dk4enc.h"
+#endif
+
+#ifndef DK4LOC_H_INCLUDED
+#include "dk4loc.h"
+#endif
+
+#ifndef DK4MPL_H_INCLUDED
+#include "dk4mpl.h"
+#endif
+
+#ifndef DK4EXEPD_H_INCLUDED
+#include "dk4exepd.h"
+#endif
+
+#ifndef DK4MAO8D_H_INCLUDED
+#include "dk4mao8d.h"
+#endif
+
+#ifndef DK4INST_H_INCLUDED
+#include "dk4inst.h"
+#endif
+
+#ifndef DK4PREF_H_INCLUDED
+#include "dk4pref.h"
+#endif
+
+#ifndef DK4USER_H_INCLUDED
+#include "dk4user.h"
+#endif
+
+#ifndef DK4FS_H_INCLUDED
+#include "dk4fs.h"
+#endif
+
+#ifndef DK4STRMR_H_INCLUDED
+#include "dk4strmr.h"
+#endif
+
+#ifndef DK4TSPDK_H_INCLUDED
+#include "dk4tspdk.h"
+#endif
+
+#ifndef DK4FPUT_H_INCLUDED
+#include "dk4fput.h"
+#endif
+
+#ifndef DK4HNAMED_H_INCLUDED
+#include "dk4hnamed.h"
+#endif
+
+#ifndef DK4MAIDDDI_H_INCLUDED
+#include "dk4maidddi.h"
+#endif
+
+#ifndef DK4MAIDDDU_H_INCLUDED
+#include "dk4maidddu.h"
+#endif
+
+#ifndef DK4MAIDDSZ_H_INCLUDED
+#include "dk4maiddsz.h"
+#endif
+
+#ifndef DK4MAIDDBL_H_INCLUDED
+#include "dk4maiddbl.h"
+#endif
+
+#ifndef DK4MAODD_H_INCLUDED
+#include "dk4maodd.h"
+#endif
+
+#ifndef DK4NUML_H_INCLUDED
+#include "dk4numl.h"
+#endif
+
+#ifndef DK4STO_H_INCLUDED
+#include "dk4sto.h"
+#endif
+
+#ifndef DK4APPI_C_INCLUDED
+#include "dk4appi.c"
+#endif
+
+#ifndef DK4PATHD_H_INCLUDED
+#include "dk4pathd.h"
+#endif
+
+#ifndef DK4STATD_H_INCLUDED
+#include "dk4statd.h"
+#endif
+
+#ifndef DK4STAT_H_INCLUDED
+#include "dk4stat.h"
+#endif
+
+#ifndef DK4REC21_H_INCLUDED
+#include "dk4rec21.h"
+#endif
+
+#ifndef DK4TIME_H_INCLUDED
+#include "dk4time.h"
+#endif
+
+#ifndef DK4TIMEDK_H_INCLUDED
+#include "dk4timedk.h"
+#endif
+
+#ifndef DK4GETPID_H_INCLUDED
+#include "dk4getpid.h"
+#endif
+
+#ifndef DK4APPMKDH_H_INCLUDED
+#include "dk4appmkdh.h"
+#endif
+
+#ifndef DK4DELFILE_H_INCLUDED
+#include "dk4delfile.h"
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Log at application startup.
+ @param app Application structure.
+*/
+void
+dk4app_log_startup_debug(dk4_app_t *app);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+
+#line 181 "dk4appop.ctr"
+
+
+
+static const dkChar * const dk4app_open_long_opt[] = {
+/* 0 */
+dkT("help"),
+
+/* 1 */
+dkT("version"),
+
+/* 2 */
+dkT("license"),
+
+/* 3 */
+dkT("quiet"),
+
+/* 4 */
+dkT("manual"),
+
+NULL
+
+
+#line 207 "dk4appop.ctr"
+};
+
+
+
+static const dkChar * const dk4app_open_scope_names[] = {
+/* 0 */
+dkT("user"),
+
+/* 1 */
+dkT("application"),
+
+/* 2 */
+dkT("application-group"),
+
+/* 3 */
+dkT("host"),
+
+/* 4 */
+dkT("windows"),
+
+/* 5 */
+dkT("non-windows"),
+
+/* 6 */
+dkT("language"),
+
+/* 7 */
+dkT("region"),
+
+NULL
+
+
+#line 246 "dk4appop.ctr"
+};
+
+
+
+/** Non localized 8 bit char keywords used by this module.
+*/
+static const char * const dk4app_open_c8_kw[] = {
+/* 0 */
+"ERROR: Not enough memory!",
+
+/* 1 */
+"ERROR: Not enough memory, failed to allocate ",
+
+/* 2 */
+" bytes!",
+
+NULL
+
+
+#line 258 "dk4appop.ctr"
+};
+
+
+
+/** Non localized dkChar keywords used by this module.
+*/
+static const dkChar * const dk4app_open_kw[] = {
+/* 0 */
+dkT("--quiet"),
+
+/* 1 */
+dkT("bin"),
+
+/* 2 */
+dkT("sbin"),
+
+/* 3 */
+dkT("etc"),
+
+/* 4 */
+dkT("share"),
+
+/* 5 */
+dkT("lib"),
+
+/* 6 */
+dkT("var"),
+
+/* 7 */
+dkT("libexec"),
+
+/* 8 */
+dkT("dk4pref.conf"),
+
+/* 9 */
+dkT("/log"),
+
+/* 10 */
+dkT("/"),
+
+/* 11 */
+dkT("-"),
+
+/* 12 */
+dkT(".log"),
+
+/* 13 */
+dkT("/tmp"),
+
+/* 14 */
+dkT("dk3pref.conf"),
+
+/* 15 */
+dkT("*"),
+
+NULL
+
+
+#line 313 "dk4appop.ctr"
+};
+
+
+
+/** Character used as separator between path name components.
+*/
+static const dkChar dk4app_filename_sep[] =
+#if DK4_HAVE_BACKSLASH_AS_SEP
+dkT("\\")
+#else
+dkT("/")
+#endif
+;
+
+
+
+#if DK4_ON_WINDOWS
+/** File name suffixes for executable files on Windows systems.
+*/
+static const dkChar * const dk4app_exe_file_suffixes[] = {
+/* 0 */
+dkT(".exe"),
+
+/* 1 */
+dkT(".com"),
+
+/* 2 */
+dkT(".dll"),
+
+/* 3 */
+dkT(".sys"),
+
+/* 4 */
+dkT(".cpl"),
+
+NULL
+
+
+#line 340 "dk4appop.ctr"
+};
+#endif
+
+
+
+/** Initialize an application structure after allocating the memory.
+ @param ptr Structure to initialize.
+*/
+static
+void
+dk4app_open_initialize(dk4_app_t *ptr)
+{
+
+
+#line 353 "dk4appop.ctr"
+ ptr->s_opt_all = NULL;
+ ptr->i_opt_all = NULL;
+ ptr->s_opt_short = NULL;
+ ptr->i_opt_short = NULL;
+ ptr->s_opt_long = NULL;
+ ptr->i_opt_long = NULL;
+ ptr->s_pref_self = NULL;
+ ptr->s_pref_cmd = NULL;
+ ptr->s_pref_user = NULL;
+ ptr->s_pref_sys = NULL;
+ ptr->s_stt = NULL;
+ ptr->i_pref_self = NULL;
+ ptr->i_pref_cmd = NULL;
+ ptr->i_pref_user = NULL;
+ ptr->i_pref_sys = NULL;
+ ptr->i_stt = NULL;
+ ptr->msg_base = NULL;
+ ptr->msg_debug = NULL;
+ ptr->help_text = NULL;
+ ptr->lic_text = NULL;
+ ptr->my_argv = NULL;
+ ptr->vers_text = NULL;
+ ptr->help_file_name = NULL;
+ ptr->user_name = NULL;
+ ptr->host_name = NULL;
+ ptr->user_home = NULL;
+ ptr->language = NULL;
+ ptr->region = NULL;
+ ptr->prog_name = NULL;
+ ptr->group_name = NULL;
+ ptr->dir_bin = NULL;
+ ptr->dir_etc = NULL;
+ ptr->dir_share = NULL;
+ ptr->dir_lib = NULL;
+ ptr->dir_var = NULL;
+ ptr->dir_tmp = NULL;
+ ptr->log_file_name = NULL;
+ ptr->source_file_name = NULL;
+ ptr->source_file_line = (dk4_um_t)0UL;
+ ptr->timer_stderr = (dk4_time_t)0UL;
+ ptr->timer_file = (dk4_time_t)0UL;
+ ptr->sz_msg_base = 0;
+ ptr->sz_msg_debug = 0;
+ ptr->have_stderr_time = 0;
+ ptr->have_file_time = 0;
+ ptr->have_file_opened = 0;
+ ptr->have_stderr_init = 0;
+ ptr->my_argc = 0;
+ ptr->ll_stderr = DK4_LL_WARNING;
+ ptr->ll_file = DK4_LL_NONE;
+ ptr->ll_file_keep = DK4_LL_NONE;
+ ptr->ll_found = DK4_LL_IGNORE;
+ ptr->log_stderr_time = 1;
+ ptr->log_file_time = 1;
+ ptr->log_enabled = 0;
+ ptr->encoding =
+ ptr->enc_in_std =
+ ptr->enc_in_file =
+ ptr->enc_out_std =
+ ptr->enc_out_file = DK4_FILE_ENCODING_ASCII;
+ ptr->hvl_cmd = 0;
+ ptr->have_self_pref = 0;
+ ptr->fast_close = 0;
+ ptr->tmp_dir_used = 0;
+
+
+#line 418 "dk4appop.ctr"
+}
+
+
+
+/** Check command line arguments for --quiet option.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 1 if --quiet was found, 0 otherwise.
+*/
+static
+int
+dk4app_open_silence_check(int argc, dkChar **argv)
+{
+ size_t i; /* Traverse arguments list */
+ int back = 0; /* Function result */
+
+
+#line 434 "dk4appop.ctr"
+ for (i = 1; i < (size_t)argc; i++) {
+ if (0 == dk4str_cmp(argv[i], dk4app_open_kw[0])) {
+ back = 1;
+ }
+ }
+
+#line 439 "dk4appop.ctr"
+ return back;
+}
+
+
+
+/** Find language, region, and encoding.
+ Set app->error_found if any error occures.
+ @param app Application structure to set up.
+*/
+static
+void
+dk4app_open_find_language_region(dk4_app_t *app, dk4_app_error_t *ae)
+{
+ dkChar lbuf[16];
+ dkChar rbuf[16];
+ int enc = DK4_ENCODING_ASCII;
+ int res;
+
+
+#line 457 "dk4appop.ctr"
+ lbuf[0] = dkT('\0'); rbuf[0] = dkT('\0');
+ res = dk4loc_get_settings(
+ lbuf, DK4_SIZEOF(lbuf,dkChar),
+ rbuf, DK4_SIZEOF(rbuf,dkChar),
+ &enc, NULL
+ );
+ if (0 != res) {
+
+#line 464 "dk4appop.ctr"
+ if (0 < dk4str_len(lbuf)) {
+ app->language = dk4str_dup(lbuf, NULL);
+ if (NULL == app->language) {
+ ae->error_found = E_MEMORY;
+ }
+ }
+ if (0 < dk4str_len(rbuf)) {
+ app->region = dk4str_dup(rbuf, NULL);
+ if (NULL == app->region) {
+ ae->error_found = E_MEMORY;
+ }
+ }
+ app->encoding =
+ app->enc_in_std =
+ app->enc_in_file =
+ app->enc_out_std =
+ app->enc_out_file = enc;
+#if DK4_CHAR_SIZE > 1
+ /* Multi-byte input (UTF-16, C32) typically has a BOM at start */
+ app->enc_in_std = DK4_FILE_ENCODING_ASCII;
+ app->enc_in_file = DK4_FILE_ENCODING_ASCII;
+#endif
+ } else {
+ ae->error_found = E_LOCALE;
+ }
+
+#line 489 "dk4appop.ctr"
+}
+
+
+
+/** Report errors occured in initialization.
+ @param app Application structure to report errors for.
+*/
+static
+void
+dk4app_open_report_error(dk4_app_t *app, dk4_app_error_t *ae)
+{
+ /* !!!!! */
+ switch (ae->error_found) {
+ case E_LOCALE: {
+ } break;
+ case E_MEMORY: {
+ } break;
+ case E_EXEFILE: {
+ } break;
+ case E_EXECNAME_TOO_LONG: {
+ } break;
+ case E_NO_DIR_IN_EXENAME: {
+ } break;
+ case E_EMPTY_OPTION_SPEC: {
+ } break;
+ case E_OPTION_LONG_SPEC_MULT: {
+ } break;
+ case E_OPTION_SHORT_SPEC_MULT: {
+ } break;
+ case E_USER_NAME_NOT_FOUND: {
+ } break;
+ case E_USER_HOME_NOT_FOUND: {
+ } break;
+ case E_LOG_FILE_NAME: {
+ } break;
+ }
+}
+
+
+
+/** Check whether a dynamically allocated string is not NULL.
+ @param app Application to set up.
+ @param dirname String to test.
+*/
+static
+void
+dk4app_open_check_directory_name(dk4_app_error_t *ae, dkChar *dirname)
+{
+
+
+#line 538 "dk4appop.ctr"
+ if (NULL == dirname) {
+ if (0 == ae->error_found) {
+
+#line 540 "dk4appop.ctr"
+ ae->error_found = E_MEMORY;
+ }
+ }
+
+#line 543 "dk4appop.ctr"
+}
+
+
+
+/** The bin directory is the one compiled into the dk4inst
+ module, so retrieve etc, lib, share and var from the
+ dk4inst module too.
+ @param app Application structure to set up.
+*/
+static
+void
+dk4app_open_find_exec_from_inst(dk4_app_t *app, dk4_app_error_t *ae)
+{
+
+
+#line 557 "dk4appop.ctr"
+ app->dir_etc = dk4str_dup(dk4inst_get_directory(1), NULL);
+ app->dir_share = dk4str_dup(dk4inst_get_directory(2), NULL);
+ app->dir_lib = dk4str_dup(dk4inst_get_directory(6), NULL);
+ app->dir_var = dk4str_dup(dk4inst_get_directory(3), NULL);
+ dk4app_open_check_directory_name(ae, app->dir_etc);
+ dk4app_open_check_directory_name(ae, app->dir_share);
+ dk4app_open_check_directory_name(ae, app->dir_lib);
+ dk4app_open_check_directory_name(ae, app->dir_var);
+
+
+#line 566 "dk4appop.ctr"
+}
+
+
+
+/** Create one new directory name replacing the final path component.
+ @param app Application structure to set up.
+ @param buf Buffer containing old directory name,
+ changed to the new directory name.
+ @param szbuf Size of buffer.
+ @param p1 Pointer to first position to modify in buffer.
+ @param nn New final component name.
+ @return String copy of new directory name in dynamically allocated
+ memory.
+*/
+static
+dkChar *
+dk4app_open_find_exec_replace_one(
+ dk4_app_t *app,
+ dk4_app_error_t *ae,
+ dkChar *buf,
+ size_t szbuf,
+ dkChar *p1,
+ dkChar const *nn
+)
+{
+ dkChar *back = NULL;
+
+
+#line 593 "dk4appop.ctr"
+ *p1 = dkT('\0');
+ if (0 != dk4str_cat_s(buf, szbuf, nn, NULL)) {
+ back = dk4str_dup(buf, NULL);
+ if (NULL == back) {
+ if (0 == ae->error_found) {
+ ae->error_found = E_MEMORY;
+ }
+ }
+ } else {
+ if (0 == ae->error_found) {
+ ae->error_found = E_EXECNAME_TOO_LONG;
+ }
+ }
+
+#line 606 "dk4appop.ctr"
+ return back;
+}
+
+
+
+/** Create directory names by replacing the final
+ bin or sbin component by etc, lib, share and var.
+ @param app Application structure to set up.
+ @param buf Buffer for directory name.
+ @param szbuf Size of buffer.
+ @param p1 Pointer to first character to modify.
+*/
+static
+void
+dk4app_open_find_exec_replace_final(
+ dk4_app_t *app,
+ dk4_app_error_t *ae,
+ dkChar *buf,
+ size_t szbuf,
+ dkChar *p1
+)
+{
+
+
+#line 629 "dk4appop.ctr"
+ app->dir_etc = dk4app_open_find_exec_replace_one(
+ app, ae, buf, szbuf, p1, dk4app_open_kw[3]
+ );
+ app->dir_share = dk4app_open_find_exec_replace_one(
+ app, ae, buf, szbuf, p1, dk4app_open_kw[4]
+ );
+ app->dir_lib = dk4app_open_find_exec_replace_one(
+ app, ae, buf, szbuf, p1, dk4app_open_kw[5]
+ );
+ app->dir_var = dk4app_open_find_exec_replace_one(
+ app, ae, buf, szbuf, p1, dk4app_open_kw[6]
+ );
+
+
+#line 642 "dk4appop.ctr"
+}
+
+
+
+/** Check whether the path is below the libexec directory compiled
+ into the dk4inst module.
+ @param buf Buffer to check.
+ @return 1 if the path is below the libexec directory, 0 otherwise.
+*/
+static
+int
+dk4app_open_is_dkinst_libexec(dkChar *buf)
+{
+ size_t sz;
+ int back = 0;
+
+
+#line 658 "dk4appop.ctr"
+ sz = dk4str_len(dk4inst_get_directory(10));
+ if (0 < sz) {
+ if (dk4str_len(buf) > sz) {
+ if (buf[sz] == dk4app_filename_sep[0]) {
+ buf[sz] = dkT('\0');
+ if (0 == dk4str_pathcmp(buf, dk4inst_get_directory(10))) {
+ back = 1;
+ } else {
+ buf[sz] = dk4app_filename_sep[0];
+ }
+ }
+ }
+ }
+
+#line 671 "dk4appop.ctr"
+ return back;
+}
+
+
+
+/** Check if there is any libexec component in the path.
+ Cut path to part before libexec if found.
+ @param buf Buffer containing the directory.
+ @param szbuf Buffer size.
+ @return 1 on success (libexec found), 0 otherwise.
+*/
+static
+int
+dk4app_open_is_any_libexec(dkChar *buf, size_t szbuf)
+{
+ dkChar mybuf[DK4_MAX_PATH];
+ dkChar *p1;
+ dkChar *p2;
+ int back = 0;
+
+
+#line 691 "dk4appop.ctr"
+ if (0 != dk4str_cpy_s(mybuf, DK4_SIZEOF(mybuf,dkChar), buf, NULL)) {
+ p1 = dk4str_rchr(mybuf, dk4app_filename_sep[0]);
+ while ((0 == back) && (NULL != p1)) {
+ p2 = p1;
+ p2++;
+ if (0 == dk4str_pathcmp(p2, dk4app_open_kw[7])) {
+ back = 1;
+ *p1 = dkT('\0');
+ dk4str_cpy_s(buf, szbuf, mybuf, NULL);
+ p1 = NULL;
+ } else {
+ *p1 = dkT('\0');
+ p1 = dk4str_rchr(mybuf, dk4app_filename_sep[0]);
+ }
+ }
+ }
+
+#line 707 "dk4appop.ctr"
+ return back;
+}
+
+
+
+static
+void
+dk4app_open_find_copy_bindir(dk4_app_t *app, dk4_app_error_t *ae)
+{
+
+
+#line 717 "dk4appop.ctr"
+ if (NULL != app->dir_bin) {
+ app->dir_etc = dk4str_dup(app->dir_bin, NULL);
+ app->dir_share = dk4str_dup(app->dir_bin, NULL);
+ app->dir_lib = dk4str_dup(app->dir_bin, NULL);
+ app->dir_var = dk4str_dup(app->dir_bin, NULL);
+ }
+ dk4app_open_check_directory_name(ae, app->dir_etc);
+ dk4app_open_check_directory_name(ae, app->dir_share);
+ dk4app_open_check_directory_name(ae, app->dir_lib);
+ dk4app_open_check_directory_name(ae, app->dir_var);
+
+
+#line 728 "dk4appop.ctr"
+}
+
+
+
+/** Find executable file for process and derive
+ program name and directories from it.
+ @param app Application structure to set up.
+ @param arg0 First command line word.
+*/
+static
+void
+dk4app_open_find_executable(
+ dk4_app_t *app,
+ dk4_app_error_t *ae,
+ const dkChar *arg0
+)
+{
+ dkChar buf[DK4_MAX_PATH];
+ dkChar *p1;
+ size_t const szbuf = DK4_SIZEOF(buf,dkChar);
+
+
+#line 749 "dk4appop.ctr"
+ if (0 != dk4execpath(buf, szbuf, arg0, NULL)) {
+ p1 = dk4str_rchr(buf, dk4app_filename_sep[0]);
+ if (NULL != p1) {
+ *(p1++) = dkT('\0');
+ if (0 < dk4str_len(buf)) {
+ /* Save program name */
+ app->prog_name = dk4str_dup(p1, NULL);
+ if (NULL == app->prog_name) {
+ ae->error_found = E_MEMORY;
+ } else {
+#if DK4_ON_WINDOWS
+ /* Remove .exe suffix */
+ p1 = dk4path_get_suffix(app->prog_name, NULL);
+ if (NULL != p1) {
+ if (-1 < dk4str_array_index(dk4app_exe_file_suffixes, p1, 0)) {
+ *p1 = dkT('\0');
+ }
+ }
+#endif
+ }
+
+
+#line 770 "dk4appop.ctr"
+ /* Save bindir name */
+ app->dir_bin = dk4str_dup(buf, NULL);
+
+
+#line 773 "dk4appop.ctr"
+ if (NULL == app->dir_bin) { ae->error_found = E_MEMORY; }
+ /* Find other directories */
+ if (0 == dk4str_pathcmp(buf, dk4inst_get_directory(4))) {
+
+
+#line 777 "dk4appop.ctr"
+ /* In .../bin, use directories from dk4inst */
+ dk4app_open_find_exec_from_inst(app, ae);
+ } else {
+ if (0 == dk4str_pathcmp(buf, dk4inst_get_directory(5))) {
+
+
+#line 782 "dk4appop.ctr"
+ /* In .../sbin, use directories from dk4inst */
+ dk4app_open_find_exec_from_inst(app, ae);
+ } else {
+ if (dk4app_open_is_dkinst_libexec(buf)) {
+
+
+#line 787 "dk4appop.ctr"
+ /* In .../libexec/..., use directories from dk4inst */
+ dk4app_open_find_exec_from_inst(app, ae);
+ } else {
+ p1 = dk4str_rchr(buf, dk4app_filename_sep[0]);
+ if (NULL != p1) {
+ p1++;
+ if (0 == dk4str_pathcmp(p1, dk4app_open_kw[1])) {
+
+
+#line 795 "dk4appop.ctr"
+ /* Replace final path component by etc, lib... */
+ dk4app_open_find_exec_replace_final(
+ app, ae, buf, szbuf, p1
+ );
+ } else {
+ if (0 == dk4str_pathcmp(p1, dk4app_open_kw[2])) {
+
+
+#line 802 "dk4appop.ctr"
+ /* Replace final path component by etc, lib... */
+ dk4app_open_find_exec_replace_final(
+ app, ae, buf, szbuf, p1
+ );
+ } else {
+ if (dk4app_open_is_any_libexec(buf,szbuf)) {
+ /*
+ We can securely append the separator and the
+ finalizer as the dk4app_open_is_any_libexec()
+ function cutted a libexec string from the path.
+ */
+
+
+#line 814 "dk4appop.ctr"
+ p1 = buf;
+ while(dkT('\0') != *p1) { p1++; }
+ *(p1++) = dk4app_filename_sep[0];
+ *p1 = dkT('\0');
+ dk4app_open_find_exec_replace_final(
+ app, ae, buf, szbuf, p1
+ );
+ } else {
+
+#line 822 "dk4appop.ctr"
+ dk4app_open_find_copy_bindir(app, ae);
+ }
+ }
+ }
+ } else {
+
+#line 827 "dk4appop.ctr"
+ dk4app_open_find_copy_bindir(app, ae);
+ }
+ }
+ }
+ }
+
+
+#line 833 "dk4appop.ctr"
+
+
+#line 834 "dk4appop.ctr"
+
+
+#line 835 "dk4appop.ctr"
+
+
+#line 836 "dk4appop.ctr"
+ } else {
+
+#line 837 "dk4appop.ctr"
+ ae->error_found = E_EXECNAME_TOO_LONG;
+ }
+ } else {
+
+#line 840 "dk4appop.ctr"
+ ae->error_found = E_NO_DIR_IN_EXENAME;
+ }
+ } else {
+
+#line 843 "dk4appop.ctr"
+ ae->error_found = E_EXEFILE;
+ }
+
+
+#line 846 "dk4appop.ctr"
+}
+
+
+
+static
+void
+dk4app_close_prefeferences(dk4_sto_t *s, dk4_sto_it_t *i)
+{
+ dk4_pref_t *prefptr;
+ if (NULL != i) {
+ dk4sto_it_reset(i);
+ do {
+ prefptr = (dk4_pref_t *)dk4sto_it_next(i);
+ if (NULL != prefptr) {
+ dk4pref_close(prefptr);
+ }
+ } while(NULL != prefptr);
+ dk4sto_it_close(i);
+ }
+ if (NULL != s) {
+ dk4sto_close(s);
+ }
+}
+
+
+
+int
+dk4app_close(dk4_app_t *app)
+{
+ dk4_option_t *optptr;
+ dk4_string_table_t *ptrstt;
+ int back = 0;
+
+
+#line 879 "dk4appop.ctr"
+ if (NULL != app) {
+ /* Remove temporary files */
+ if (0 == app->fast_close) {
+ if ((NULL != app->dir_tmp) && (0 != app->tmp_dir_used)) {
+ (void)dk4app_del_tree(app->dir_tmp, app);
+ }
+ }
+#if 0
+ /* Write preferences back to file */
+ if ((0 != app->have_self_pref) && (0 == app->fast_close)) {
+ /*
+ Originally intended: Write self-set preferences back to file.
+ 2015-04-17: Design decision not to write back.
+ Preferences are read-only in version 4.
+ For GUI programs there are mechanisms in wxWidgets
+ to save configuration changes.
+ */
+ }
+#endif
+ /* The base and debug messages are read from string tables, so the
+ arrays are freed when freeing the string tables.
+ */
+ app->msg_base = NULL;
+ app->msg_debug = NULL;
+ app->source_file_name = NULL;
+ back = 1;
+ /* Disable logging */
+ app->log_enabled = 0;
+
+ /* Delete log file unless there is a reason to keep it */
+ if (NULL != app->log_file_name) {
+ if ((app->ll_found <= app->ll_file) && (0 != app->have_file_opened)) {
+ if (app->ll_file_keep < app->ll_found) {
+ (void)dk4delete_file(app->log_file_name, NULL);
+ }
+ }
+ }
+ /* Release memory for log file */
+ dk4mem_release(app->log_file_name);
+ /* Release memory for directories */
+ app->help_text = NULL;
+ app->lic_text = NULL;
+ dk4mem_release(app->dir_tmp);
+ dk4mem_release(app->dir_var);
+ dk4mem_release(app->dir_lib);
+ dk4mem_release(app->dir_share);
+ dk4mem_release(app->dir_etc);
+ dk4mem_release(app->dir_bin);
+ dk4mem_release(app->group_name);
+ dk4mem_release(app->prog_name);
+ /* Release memory for language and region */
+ dk4mem_release(app->region);
+ dk4mem_release(app->language);
+ dk4mem_release(app->vers_text);
+ dk4mem_release(app->help_file_name);
+ dk4mem_release(app->host_name);
+ dk4mem_release(app->user_home);
+ dk4mem_release(app->user_name);
+#if TRACE_DEBUG
+ {
+ int i;
+ if ((0 < app->my_argc) && (NULL != app->my_argv)) {
+ for (i = 0; i < app->my_argc; i++) {
+
+
+#line 943 "dk4appop.ctr"
+ }
+ }
+ }
+#endif
+ dk4mem_release(app->my_argv);
+ /* Release string tables */
+ if (NULL != app->s_stt) {
+ if (NULL != app->i_stt) {
+ dk4sto_it_reset(app->i_stt);
+ do {
+ ptrstt = (dk4_string_table_t *)dk4sto_it_next(app->i_stt);
+ if (NULL != ptrstt) {
+ dk4stt_close(ptrstt);
+ }
+ } while (NULL != ptrstt);
+ dk4sto_it_close(app->i_stt);
+ }
+ dk4sto_close(app->s_stt);
+ }
+ app->s_stt = NULL;
+ app->i_stt = NULL;
+ /*
+ Release options
+ All options in s_opt_long and s_opt_short are also in s_opt_all.
+ They are deleted later, so we can simply close the storages here.
+ */
+ if (NULL != app->i_opt_long) { dk4sto_it_close(app->i_opt_long); }
+ app->i_opt_long = NULL;
+ if (NULL != app->i_opt_short) { dk4sto_it_close(app->i_opt_short); }
+ app->i_opt_short = NULL;
+ if (NULL != app->s_opt_long) { dk4sto_close(app->s_opt_long); }
+ app->s_opt_long = NULL;
+ if (NULL != app->s_opt_short) { dk4sto_close(app->s_opt_short); }
+ app->s_opt_short = NULL;
+ dk4app_close_prefeferences(app->s_pref_sys, app->i_pref_sys);
+ dk4app_close_prefeferences(app->s_pref_user, app->i_pref_user);
+ dk4app_close_prefeferences(app->s_pref_cmd, app->i_pref_cmd);
+ dk4app_close_prefeferences(app->s_pref_self, app->i_pref_self);
+ app->s_pref_self = NULL;
+ app->s_pref_cmd = NULL;
+ app->s_pref_user = NULL;
+ app->s_pref_sys = NULL;
+ app->i_pref_self = NULL;
+ app->i_pref_cmd = NULL;
+ app->i_pref_user = NULL;
+ app->i_pref_sys = NULL;
+ if (NULL != app->i_opt_all) {
+ dk4sto_it_reset(app->i_opt_all);
+ do {
+ optptr = (dk4_option_t *)dk4sto_it_next(app->i_opt_all);
+ if (NULL != optptr) {
+ dk4opt_close(optptr);
+ }
+ } while(NULL != optptr) ;
+ dk4sto_it_close(app->i_opt_all);
+ }
+ app->i_opt_all = NULL;
+ if (NULL != app->s_opt_all) { dk4sto_close(app->s_opt_all); }
+ app->s_opt_all = NULL;
+ /* Release memory for app structure itself */
+ dk4mem_free(app);
+ }
+
+#line 1005 "dk4appop.ctr"
+ return back;
+}
+
+
+
+/** Process the options specification.
+ @param app Application to set up.
+ @param ae Application error structure.
+ @param optspec The option specification.
+ @param szoptspec Size of the optspec array.
+*/
+static
+void
+dk4app_open_process_optspec(
+ dk4_app_t *app,
+ dk4_app_error_t *ae,
+ const dk4_option_specification_t *optspec,
+ size_t szoptspec
+)
+{
+ dk4_option_t *optptr;
+
+
+#line 1027 "dk4appop.ctr"
+ while(szoptspec--) {
+ if ((NULL != optspec->longopt) || (dkT('\0') != optspec->c)) {
+ optptr = dk4opt_open(optspec, NULL);
+ if (NULL != optptr) {
+ if (0 != dk4sto_add(app->s_opt_all, optptr, NULL)) {
+ if (NULL != optspec->longopt) {
+ if (NULL == dk4sto_it_find_like(app->i_opt_long,optspec->longopt,3))
+ {
+ if (0 == dk4sto_add(app->s_opt_long, optptr, NULL)) {
+ if (0 == ae->error_found) { ae->error_found = E_MEMORY; }
+ szoptspec = 0;
+ }
+ }
+ else
+ {
+
+#line 1042 "dk4appop.ctr"
+ if (0 == ae->error_found) {
+ ae->error_found = E_OPTION_LONG_SPEC_MULT;
+ ae->longopt = optspec->longopt;
+ }
+ szoptspec = 0;
+ }
+ }
+ if (dkT('\0') != optspec->c) {
+ if (NULL == dk4sto_it_find_like(app->i_opt_short,&(optspec->c),1))
+ {
+ if (0 == dk4sto_add(app->s_opt_short, optptr, NULL)) {
+ if (0 == ae->error_found) { ae->error_found = E_MEMORY; }
+ szoptspec = 0;
+ }
+ }
+ else
+ {
+
+#line 1059 "dk4appop.ctr"
+ if (0 == ae->error_found) {
+ ae->error_found = E_OPTION_SHORT_SPEC_MULT;
+ ae->longopt = optspec->longopt;
+ }
+ szoptspec = 0;
+ }
+ }
+ } else {
+
+#line 1067 "dk4appop.ctr"
+ if (0 == ae->error_found) { ae->error_found = E_MEMORY; }
+ szoptspec = 0;
+ dk4opt_close(optptr); optptr = NULL;
+ }
+ } else {
+
+#line 1072 "dk4appop.ctr"
+ if (0 == ae->error_found) { ae->error_found = E_MEMORY; }
+ szoptspec = 0;
+ }
+ } else {
+
+#line 1076 "dk4appop.ctr"
+ if (0 == ae->error_found) { ae->error_found = E_EMPTY_OPTION_SPEC; }
+ szoptspec = 0;
+ }
+ optspec++;
+ }
+
+#line 1081 "dk4appop.ctr"
+}
+
+
+
+/** Create and prepare the storage containers for command line options.
+ @param app Application to set up.
+ @param ae Application error structure.
+ @param optspec The option specification.
+ @param szoptspec Size of the optspec array.
+*/
+static
+void
+dk4app_open_create_options_storages(
+ dk4_app_t *app,
+ dk4_app_error_t *ae,
+ const dk4_option_specification_t *optspec,
+ size_t szoptspec
+)
+{
+
+
+#line 1101 "dk4appop.ctr"
+ if ((NULL != optspec) && (0 < szoptspec)) {
+ app->s_opt_all = dk4sto_open(NULL);
+ if (NULL != app->s_opt_all) {
+ app->s_opt_long = dk4sto_open(NULL);
+ if (NULL != app->s_opt_long) {
+ dk4sto_set_comp(app->s_opt_long, dk4option_compare, 2);
+ app->s_opt_short = dk4sto_open(NULL);
+ if (NULL != app->s_opt_short) {
+ dk4sto_set_comp(app->s_opt_short, dk4option_compare, 0);
+ app->i_opt_all = dk4sto_it_open(app->s_opt_all, NULL);
+ if (NULL != app->i_opt_all) {
+ app->i_opt_long = dk4sto_it_open(app->s_opt_long, NULL);
+ if (NULL != app->i_opt_long) {
+ app->i_opt_short = dk4sto_it_open(app->s_opt_short, NULL);
+ if (NULL != app->i_opt_short) {
+ dk4app_open_process_optspec(app, ae, optspec, szoptspec);
+ } else {
+
+#line 1118 "dk4appop.ctr"
+ ae->error_found = E_MEMORY;
+ }
+ } else {
+
+#line 1121 "dk4appop.ctr"
+ ae->error_found = E_MEMORY;
+ }
+ } else {
+
+#line 1124 "dk4appop.ctr"
+ ae->error_found = E_MEMORY;
+ }
+ } else {
+
+#line 1127 "dk4appop.ctr"
+ ae->error_found = E_MEMORY;
+ }
+ } else {
+
+#line 1130 "dk4appop.ctr"
+ ae->error_found = E_MEMORY;
+ }
+ } else {
+
+#line 1133 "dk4appop.ctr"
+ ae->error_found = E_MEMORY;
+ }
+ }
+
+#line 1136 "dk4appop.ctr"
+}
+
+
+
+/** Create storage containers for preferences.
+ @param app Application to set up.
+ @param ae Error storage for setup.
+*/
+static
+void
+dk4app_open_create_pref_storages(
+ dk4_app_t *app,
+ dk4_app_error_t *ae
+)
+{
+ app->s_pref_sys = dk4sto_open(NULL);
+ if (NULL != app->s_pref_sys) {
+ app->s_pref_user = dk4sto_open(NULL);
+ if (NULL != app->s_pref_user) {
+ app->s_pref_cmd = dk4sto_open(NULL);
+ if (NULL != app->s_pref_cmd) {
+ app->s_pref_self = dk4sto_open(NULL);
+ if (NULL != app->s_pref_self) {
+ dk4sto_set_comp(app->s_pref_sys, dk4pref_compare, 0);
+ dk4sto_set_comp(app->s_pref_user, dk4pref_compare, 0);
+ dk4sto_set_comp(app->s_pref_cmd, dk4pref_compare, 0);
+ dk4sto_set_comp(app->s_pref_self, dk4pref_compare, 0);
+ app->i_pref_sys = dk4sto_it_open(app->s_pref_sys, NULL);
+ app->i_pref_user = dk4sto_it_open(app->s_pref_user, NULL);
+ app->i_pref_cmd = dk4sto_it_open(app->s_pref_cmd, NULL);
+ app->i_pref_self = dk4sto_it_open(app->s_pref_self, NULL);
+ if ((NULL == app->i_pref_sys) || (NULL == app->i_pref_user)) {
+ ae->error_found = E_MEMORY;
+ }
+ if ((NULL == app->i_pref_cmd) || (NULL == app->i_pref_self)) {
+ ae->error_found = E_MEMORY;
+ }
+ } else {
+ ae->error_found = E_MEMORY;
+ }
+ } else {
+ ae->error_found = E_MEMORY;
+ }
+ } else {
+ ae->error_found = E_MEMORY;
+ }
+ } else {
+ ae->error_found = E_MEMORY;
+ }
+}
+
+
+
+/** Create storage container for string tables.
+ @param app Application to set up.
+ @param ae Error storage for setup.
+*/
+static
+void
+dk4app_open_create_stt_storage(
+ dk4_app_t *app,
+ dk4_app_error_t *ae
+)
+{
+ app->s_stt = dk4sto_open(NULL);
+ if (NULL != app->s_stt) {
+ dk4sto_set_comp(app->s_stt, dk4stt_compare, 0);
+ app->i_stt = dk4sto_it_open(app->s_stt, NULL);
+ if (NULL == app->i_stt) {
+ ae->error_found = E_MEMORY;
+ }
+ } else {
+ ae->error_found = E_MEMORY;
+ }
+}
+
+
+
+/** Attempt to find users login name and home directory.
+ On Linux/Unix the effective user name and home directory is searched.
+ @param app Application to set up.
+ @param ae Application opening error structure.
+*/
+static
+void
+dk4app_open_find_user_name_and_home(dk4_app_t *app, dk4_app_error_t *ae)
+{
+ dkChar buf[DK4_MAX_PATH];
+ dk4_er_t er;
+
+
+#line 1226 "dk4appop.ctr"
+ dk4error_init(&er);
+ if (0 != dk4user_get_logname(buf, DK4_SIZEOF(buf,dkChar), 1, &er)) {
+ app->user_name = dk4str_dup(buf, &er);
+ if (NULL != app->user_name) {
+ if (0 != dk4user_get_homedir(buf, DK4_SIZEOF(buf,dkChar), 1, &er)) {
+ app->user_home = dk4str_dup(buf, &er);
+ if (NULL == app->user_home) {
+ ae->error_found = E_MEMORY;
+ }
+ } else {
+ ae->error_found = E_USER_HOME_NOT_FOUND;
+ }
+ } else {
+ ae->error_found = E_MEMORY;
+ }
+ } else {
+ ae->error_found = E_USER_NAME_NOT_FOUND;
+ }
+
+
+#line 1245 "dk4appop.ctr"
+
+
+#line 1246 "dk4appop.ctr"
+
+
+#line 1247 "dk4appop.ctr"
+}
+
+
+
+/** Preference reader structure.
+*/
+typedef struct {
+ dk4_app_t *app; /**< Application to set up. */
+ dk4_app_error_t *ae; /**< Application error structure. */
+ dk4_sto_t *st; /**< Storage for preferences. */
+ dk4_sto_it_t *it; /**< Storage iterator. */
+ int insc; /**< Flag: In current scope. */
+ int lasc; /**< Flag: Previous line was scope line. */
+ int co3; /**< Flag: DK tools 3 compatibility. */
+} dk4_app_pref_rd_t;
+
+
+
+/** Initialize preference reader structure for start of file.
+ @param ptr Preference reader structure.
+*/
+static
+void
+dk4app_open_pref_reader_init_for_one_file(dk4_app_pref_rd_t *ptr)
+{
+ ptr->insc = 1;
+ ptr->lasc = 0;
+ ptr->co3 = 0;
+}
+
+
+
+/** Check one scope line entry.
+ @param app Application.
+ @param ae Application open error structure.
+ @param pn Pointer to entry name.
+ @param pv Pointer to entry value.
+ @return 1 if condition is true, 0 otherwise.
+*/
+static
+int
+dk4app_open_check_one_scope_entry(
+ dk4_app_t *app,
+ dk4_app_error_t *ae,
+ const dkChar *pn,
+ const dkChar *pv
+)
+{
+ int back = 0;
+
+
+#line 1297 "dk4appop.ctr"
+ switch (dk4str_array_index(dk4app_open_scope_names, pn, 0)) {
+ case 0: {
+ if ((NULL != pv) && (NULL != app->user_name)) {
+
+
+#line 1301 "dk4appop.ctr"
+#if DK4_HAVE_CASE_INSENSITIVE_USERNAMES
+ if (0 == dk4str_casecmp(pv, app->user_name))
+#else
+ if (0 == dk4str_cmp(pv, app->user_name))
+#endif
+ {
+ back = 1;
+ }
+ else
+ {
+ if (0 == dk4str_cmp(pv, dk4app_open_kw[15])) {
+ back = 1;
+ }
+ }
+ }
+ } break;
+ case 1: {
+ if ((NULL != pv) && (NULL != app->prog_name)) {
+
+
+#line 1320 "dk4appop.ctr"
+#if DK4_HAVE_CASE_INSENSITIVE_PATHNAMES
+ if (0 == dk4str_casecmp(pv, app->prog_name))
+#else
+ if (0 == dk4str_cmp(pv, app->prog_name))
+#endif
+ {
+ back = 1;
+ }
+ else
+ {
+ if (0 == dk4str_cmp(pv, dk4app_open_kw[15])) {
+ back = 1;
+ }
+ }
+ }
+ } break;
+ case 2: {
+
+#line 1337 "dk4appop.ctr"
+ if ((NULL != pv) && (NULL != app->group_name)) {
+
+
+#line 1339 "dk4appop.ctr"
+#if DK4_HAVE_CASE_INSENSITIVE_PATHNAMES
+ if (0 == dk4str_casecmp(pv, app->group_name))
+#else
+ if (0 == dk4str_cmp(pv, app->group_name))
+#endif
+ {
+ back = 1;
+ }
+ else
+ {
+ if (0 == dk4str_cmp(pv, dk4app_open_kw[15])) {
+ back = 1;
+ }
+ }
+ }
+ } break;
+ case 3: {
+
+#line 1356 "dk4appop.ctr"
+ if ((NULL != pv) && (NULL != app->host_name)) {
+
+
+#line 1358 "dk4appop.ctr"
+ if (0 == dk4str_casecmp(pv, app->host_name)) {
+ back = 1;
+ } else {
+ if (0 == dk4str_cmp(pv, dk4app_open_kw[15])) {
+ back = 1;
+ }
+ }
+ }
+ } break;
+ case 4: {
+
+#line 1368 "dk4appop.ctr"
+ if (NULL != pv) {
+#if DK4_ON_WINDOWS
+ if (0 != dk4str_is_on(pv)) {
+ back = 1;
+ }
+#else
+ if (0 == dk4str_is_on(pv)) {
+ back = 1;
+ }
+#endif
+ } else {
+#if DK4_ON_WINDOWS
+ back = 1;
+#endif
+ }
+ } break;
+ case 5: {
+
+#line 1385 "dk4appop.ctr"
+ if (NULL != pv) {
+#if DK4_ON_WINDOWS
+ if (0 == dk4str_is_on(pv)) {
+ back = 1;
+ }
+#else
+ if (0 != dk4str_is_on(pv)) {
+ back = 1;
+ }
+#endif
+ } else {
+#if DK4_ON_WINDOWS
+ back = 0;
+#else
+ back = 1;
+#endif
+ }
+ } break;
+ case 6 : {
+
+#line 1404 "dk4appop.ctr"
+ if ((NULL != pv) && (NULL != app->language)) {
+ if (0 == dk4str_casecmp(pv, app->language)) {
+ back =1;
+ } else {
+ if (0 == dk4str_cmp(pv, dk4app_open_kw[15])) {
+ back = 1;
+ }
+ }
+ }
+ } break;
+ case 7 : {
+
+#line 1415 "dk4appop.ctr"
+ if ((NULL != pv) && (NULL != app->region)) {
+ if (0 == dk4str_casecmp(pv, app->region)) {
+ back =1;
+ } else {
+ if (0 == dk4str_cmp(pv, dk4app_open_kw[15])) {
+ back = 1;
+ }
+ }
+ }
+ } break;
+ default: {
+
+#line 1426 "dk4appop.ctr"
+ if (0 == dk4str_len(pn)) {
+
+#line 1427 "dk4appop.ctr"
+ back = 1;
+ }
+ } break;
+ }
+
+#line 1431 "dk4appop.ctr"
+ return back;
+}
+
+
+
+/** Add one preference to storages.
+ @param app Application to configure.
+ @param ae Application open error structure.
+ @param st Storage.
+ @param it Iterator for storage.
+ @param pn Preference name.
+ @param pv Preference value.
+*/
+static
+void
+dk4app_open_add_preference(
+ dk4_app_t *app,
+ dk4_app_error_t *ae,
+ dk4_sto_t *st,
+ dk4_sto_it_t *it,
+ const dkChar *pn,
+ const dkChar *pv
+)
+{
+ dk4_pref_t *prefptr;
+ dkChar *npv;
+
+
+#line 1458 "dk4appop.ctr"
+ prefptr = dk4sto_it_find_like(it, pn, 1);
+ if (NULL != prefptr) {
+
+#line 1460 "dk4appop.ctr"
+ npv = dk4str_dup(pv, NULL);
+ if (NULL != npv) {
+#if 0
+ dk4mem_release(prefptr->value);
+#endif
+ /* 2016-12-10 Sanitize memory before releasing it.
+ */
+ dk4str_release_sanitized(prefptr->value);
+ prefptr->value = npv;
+ } else {
+ if (0 == ae->error_found) { ae->error_found = E_MEMORY; }
+ }
+ } else {
+
+#line 1473 "dk4appop.ctr"
+ prefptr = dk4pref_open(pn, pv, NULL);
+ if (NULL != prefptr) {
+ if (0 == dk4sto_add(st, (void *)prefptr, NULL)) {
+ dk4pref_close(prefptr);
+ if (0 == ae->error_found) { ae->error_found = E_MEMORY; }
+ }
+ } else {
+ if (0 == ae->error_found) { ae->error_found = E_MEMORY; }
+ }
+ }
+ dk4app_pref_apply(app, ae, pn, pv);
+
+
+#line 1485 "dk4appop.ctr"
+}
+
+
+
+/** Modify a preference value from DK tools 3 to 4 syntax.
+ Change "/print/ps/level" to "print.ps.level".
+ @param Preference name pointer.
+*/
+static
+void
+dk4app_open_modify_prefname_3_to_4(dkChar *pn)
+{
+ if (NULL != pn) {
+ if (dkT('/') == *pn) {
+ dk4str_cpy_to_left(pn, &(pn[1]));
+ while (dkT('\0') != *pn) {
+ if (dkT('/') == *pn) {
+ *pn = dkT('.');
+ }
+ pn++;
+ }
+ }
+ }
+}
+
+
+
+/** Process one input line.
+ @param obj Preferences reader object.
+ @param line Current line to process.
+ @param lineno Line number.
+ @param erp Error report, may be NULL.
+ @return
+ DK4_TSP_RES_OK if processing succeeded,
+ DK4_TSP_RES_ERROR on errors (can continue),
+ DK4_TSP_RES_FATAL on fatal errors (can not continue).
+
+*/
+static
+int
+dk4app_open_pref_line_handler(
+ void *obj,
+ dkChar *line,
+ dk4_um_t lineno,
+ dk4_er_t *erp
+)
+{
+ dkChar *p1; /* Name text */
+ dkChar *p2; /* Next text */
+ dkChar *pv; /* Value text */
+ dk4_app_pref_rd_t *ptr; /* Reader structure */
+ int back = DK4_TSP_RES_OK; /* Function result */
+ int isneg = 0; /* Flag: Exclude scope */
+ int ok; /* Flag: No test failed yet */
+
+
+#line 1540 "dk4appop.ctr"
+ dk4str_delnl(line);
+ ptr = (dk4_app_pref_rd_t *)obj;
+ p1 = dk4str_start(line, NULL);
+ if (NULL != p1) {
+ if (dkT('#') != *p1) {
+
+#line 1545 "dk4appop.ctr"
+ if (dkT('[' == *p1)) {
+
+#line 1546 "dk4appop.ctr"
+ if (0 == ptr->lasc) {
+
+#line 1547 "dk4appop.ctr"
+ ptr->insc = 0;
+ } else {
+
+#line 1549 "dk4appop.ctr"
+ }
+ p2 = dk4str_chr(p1, dkT(']'));
+ if (NULL != p2) {
+
+#line 1552 "dk4appop.ctr"
+ *p2 = dkT('\0');
+ }
+ p1++;
+ if (dkT('-') == *p1) {
+
+#line 1556 "dk4appop.ctr"
+ isneg = 1;
+ p1++;
+ }
+ ok = 1;
+ while (NULL != p1) {
+ p2 = dk4str_chr(p1, dkT(','));
+ if (NULL != p2) { *(p2++) = dkT('\0'); p2 = dk4str_start(p2, NULL); }
+ pv = dk4str_chr(p1, dkT('='));
+ if (NULL != pv) { *(pv++) = dkT('\0'); pv = dk4str_start(pv, NULL); }
+ dk4str_normalize(p1, NULL);
+ if (NULL != pv) { dk4str_rtwh(pv, NULL); }
+ if (0 == dk4app_open_check_one_scope_entry(ptr->app,ptr->ae,p1,pv)) {
+ ok = 0;
+ }
+ p1 = p2;
+ }
+ if (1 == ok) {
+
+#line 1573 "dk4appop.ctr"
+ if (0 != isneg) {
+ ptr->insc = 0;
+
+#line 1575 "dk4appop.ctr"
+ } else {
+ ptr->insc = 1;
+
+#line 1577 "dk4appop.ctr"
+ }
+ } else {
+
+#line 1579 "dk4appop.ctr"
+ }
+ ptr->lasc = 1;
+ } else {
+
+#line 1582 "dk4appop.ctr"
+ if (ptr->insc) {
+
+#line 1583 "dk4appop.ctr"
+ p2 = dk4str_chr(p1, dkT('='));
+ if (NULL != p2) { *(p2++) = dkT('\0'); p2 = dk4str_start(p2, NULL); }
+ if ((NULL != p1) && (NULL != p2)) {
+ dk4str_normalize(p1, NULL);
+ dk4str_rtwh(p2, NULL);
+ if (0 < ptr->co3) {
+
+#line 1589 "dk4appop.ctr"
+ dk4app_open_modify_prefname_3_to_4(p1);
+
+
+#line 1591 "dk4appop.ctr"
+ } else {
+
+#line 1592 "dk4appop.ctr"
+ }
+ dk4app_open_add_preference(ptr->app,ptr->ae,ptr->st,ptr->it,p1,p2);
+ }
+ } else {
+
+#line 1596 "dk4appop.ctr"
+ }
+ ptr->lasc = 0;
+ }
+ } else {
+
+#line 1600 "dk4appop.ctr"
+ }
+ } else {
+
+#line 1602 "dk4appop.ctr"
+ }
+
+#line 1603 "dk4appop.ctr"
+ return back;
+}
+
+
+
+/** Read all preferences files in increasing order.
+ Cumulative operation, redefinitions possible.
+ @param app Application to configure.
+ @param ae Application opening error structure.
+*/
+static
+void
+dk4app_open_read_preference_files(dk4_app_t *app, dk4_app_error_t *ae)
+{
+ char ib[4096]; /* Input buffer */
+ dkChar il[1024]; /* Input line */
+ dkChar fnb[DK4_MAX_PATH]; /* File name buffer */
+ dk4_tspdk_t tsp; /* Text stream processor */
+ dk4_er_t er; /* Error report */
+ dk4_app_pref_rd_t rdobj; /* Reader object */
+ dk4_stream_t *istrm; /* Input stream */
+ size_t rb; /* Bytes read from stream */
+ int pn; /* Pass number */
+ int res; /* Result from path construct */
+ int cc; /* Flag: Can continue */
+
+
+#line 1629 "dk4appop.ctr"
+ rdobj.app = app;
+ rdobj.ae = ae;
+ for (pn = 0; ((0 == ae->error_found) && (pn <= DK4_FS_CONF_MAX)); pn++) {
+ if (DK4_FS_CONF_SYS_MAX >= pn) {
+ rdobj.st = app->s_pref_sys;
+ rdobj.it = app->i_pref_sys;
+ } else {
+ rdobj.st = app->s_pref_user;
+ rdobj.it = app->i_pref_user;
+ }
+#if DK4_HAVE_COMPATDKTOOLS3
+ dk4error_init(&er);
+ res = dk4fs_config_compat_one(
+ fnb, DK4_SIZEOF(fnb,dkChar), dk4app_open_kw[14],
+ app->dir_share, app->dir_etc, app->user_home,
+ app->prog_name, app->group_name, pn, 1, 1, &er
+ );
+ if (0 != res) {
+
+
+#line 1648 "dk4appop.ctr"
+ istrm = dk4stream_open_file_reader(fnb, &er);
+ if (NULL != istrm) {
+
+#line 1650 "dk4appop.ctr"
+ dk4app_open_pref_reader_init_for_one_file(&rdobj);
+ rdobj.co3 = 1;
+ res = dk4tspdk_setup_line(
+ &tsp, &rdobj, dk4app_open_pref_line_handler,
+ il, DK4_SIZEOF(il,dkChar),
+ app->encoding, app->enc_in_file, &er
+ );
+ if (0 != res) {
+
+#line 1658 "dk4appop.ctr"
+ res = DK4_TSP_RES_OK;
+ do {
+ cc = 0;
+ rb = sizeof(ib);
+ if (0 != dk4stream_read(ib, &rb, istrm, &er)) {
+ if (0 < rb) {
+ cc = 1;
+ res = dk4tspdk_add_bytes(&tsp, (const unsigned char *)ib, rb);
+ if (DK4_TSP_RES_FATAL == res) {
+ cc = 0;
+ }
+ }
+ }
+ } while(0 != cc);
+ if (DK4_TSP_RES_FATAL != res) {
+#if VERSION_BEFORE_20150821
+ res = dk4tspdk_finish(&tsp);
+#else
+ dk4tspdk_finish(&tsp);
+#endif
+ }
+ } else {
+
+#line 1680 "dk4appop.ctr"
+ }
+ dk4stream_close(istrm, NULL);
+ } else {
+
+#line 1683 "dk4appop.ctr"
+ if (0 == ae->error_found) { ae->error_found = E_PREF_FILE_OPEN; }
+ }
+ }
+#endif
+ dk4error_init(&er);
+ res = dk4fs_config_one(
+ fnb, DK4_SIZEOF(fnb,dkChar), dk4app_open_kw[8],
+ app->dir_share, app->dir_etc, app->user_home,
+ app->prog_name, app->group_name, pn, 1, &er
+ );
+ if (0 != res) {
+
+
+#line 1695 "dk4appop.ctr"
+ istrm = dk4stream_open_file_reader(fnb, &er);
+ if (NULL != istrm) {
+
+#line 1697 "dk4appop.ctr"
+ dk4app_open_pref_reader_init_for_one_file(&rdobj);
+ res = dk4tspdk_setup_line(
+ &tsp, &rdobj, dk4app_open_pref_line_handler,
+ il, DK4_SIZEOF(il,dkChar),
+ app->encoding, app->enc_in_file, &er
+ );
+ if (0 != res) {
+
+#line 1704 "dk4appop.ctr"
+ res = DK4_TSP_RES_OK;
+ do {
+ cc = 0;
+ rb = sizeof(ib);
+ if (0 != dk4stream_read(ib, &rb, istrm, &er)) {
+ if (0 < rb) {
+ cc = 1;
+ res = dk4tspdk_add_bytes(&tsp, (const unsigned char *)ib, rb);
+ if (DK4_TSP_RES_FATAL == res) {
+ cc = 0;
+ }
+ }
+ }
+ } while(0 != cc);
+ if (DK4_TSP_RES_FATAL != res) {
+#if VERSION_BEFORE_20150821
+ res = dk4tspdk_finish(&tsp);
+#else
+ dk4tspdk_finish(&tsp);
+#endif
+ }
+ } else {
+
+#line 1726 "dk4appop.ctr"
+ }
+ dk4stream_close(istrm, NULL);
+ } else {
+
+#line 1729 "dk4appop.ctr"
+ if (0 == ae->error_found) { ae->error_found = E_PREF_FILE_OPEN; }
+ }
+ }
+ }
+
+#line 1733 "dk4appop.ctr"
+}
+
+
+
+/** Find host name for computer.
+ @param app Application to set up.
+ @param ae Application opening error structure.
+*/
+static
+void
+dk4app_open_find_host_name(dk4_app_t *app, dk4_app_error_t *ae)
+{
+ dkChar buf[256];
+ if (0 != dk4hostname(buf, DK4_SIZEOF(buf,dkChar), NULL)) {
+ app->host_name = dk4str_dup(buf, NULL);
+ if (NULL == app->host_name) {
+ if (0 == ae->error_found) { ae->error_found = E_MEMORY; }
+ }
+ } else {
+ if (0 == ae->error_found) { ae->error_found = E_HOST_NAME_NOT_FOUND; }
+ }
+}
+
+
+
+/** Check whether an option specification was given and
+ processed successfully.
+ @param app Application to set up.
+ @return 1 if option specification given, 0 otherwise.
+*/
+static
+int
+dk4app_open_options_check(dk4_app_t *app)
+{
+ int back = 0;
+ if ((NULL != app->s_opt_all) && (NULL != app->i_opt_all)) {
+ if ((NULL != app->s_opt_short) && (NULL != app->i_opt_short)) {
+ if ((NULL != app->s_opt_long) && (NULL != app->i_opt_long)) {
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Check for --help --version --license.
+ @param app Application to set up.
+ @param ae Application open error structure.
+ @param arg Argument to process.
+ @return 1 if the option needs no further processing, 0 otherwise.
+*/
+static
+int
+dk4app_open_check_long_opt(dk4_app_t *app, dk4_app_error_t *ae, dkChar *arg)
+{
+ int back = 0;
+ switch (dk4str_array_index(dk4app_open_long_opt, arg, 1)) {
+ case 0: { /* help */
+ app->hvl_cmd |= DK4_APP_CMD_HELP;
+ back = 1;
+ } break;
+ case 1: { /* version */
+ app->hvl_cmd |= DK4_APP_CMD_VERSION;
+ back = 1;
+ } break;
+ case 2: { /* license */
+ app->hvl_cmd = DK4_APP_CMD_LICENSE;
+ back = 1;
+ } break;
+ case 3: {
+ back = 1;
+ } break;
+ case 4: {
+ app->hvl_cmd |= DK4_APP_CMD_MANUAL;
+ back = 1;
+ } break;
+ }
+ return back;
+}
+
+
+
+/** Construct log file name, create log directory.
+ @param app Application to set up.
+ @param ae Application open error structure.
+*/
+static
+void
+dk4app_open_prepare_file_logging(dk4_app_t *app, dk4_app_error_t *ae)
+{
+ dkChar fnb[DK4_MAX_PATH]; /* File name buffer */
+ dkChar dktb[32]; /* Date as dkChar text */
+ dkChar pidb[32]; /* Buffer for PID */
+ dkChar pi2b[32]; /* Buffer for padded PID */
+ dkChar tb[32]; /* Date as text */
+ dkChar *ptr;
+ dk4_time_t timer; /* Current time */
+ dk4_pid_t pid; /* Process ID */
+ size_t sz; /* Size of fnb */
+ size_t szdktb; /* Size of dktb */
+ size_t sl; /* String length */
+ size_t pl; /* Padded length */
+ int ok = 0;
+
+
+#line 1839 "dk4appop.ctr"
+ sz = DK4_SIZEOF(fnb,dkChar);
+ dk4time_get(&timer);
+ if (dk4str_cpy_s(fnb, sz, app->user_home, NULL)) {
+ if (dk4str_cat_s(fnb, sz, dk4app_open_kw[9], NULL)) {
+ dk4path_correct_sep(fnb);
+#if VERSION_BEFORE_20160127
+ ok = dk4app_mkdir_hierarchy(fnb, 1, app);
+#else
+ ok = 1;
+#endif
+ if (0 < ok) {
+ ok = 0;
+ if (dk4str_cat_s(fnb, sz, dk4app_open_kw[10], NULL)) {
+ if (dk4str_cat_s(fnb, sz, app->prog_name, NULL)) {
+ if (dk4time_as_text(tb, DK4_SIZEOF(tb,dkChar), &timer, NULL)) {
+ szdktb = DK4_SIZEOF(dktb,dkChar);
+ if (dk4str_cpy_s(dktb, szdktb, tb, NULL)) {
+ ptr = dktb;
+ while (dkT('\0') != *ptr) {
+ if (dkT(':') == *ptr) { *ptr = dkT('-'); }
+ if (dkT(' ') == *ptr) { *ptr = dkT('-'); }
+ ptr++;
+ }
+ pid = dk4getpid();
+ ok = dk4ma_write_decimal_unsigned(
+ pidb, DK4_SIZEOF(pidb,dkChar), (dk4_um_t)pid, 0,
+ NULL
+ );
+ if (0 != ok) {
+ for (sl = 0; sl < DK4_SIZEOF(pi2b,dkChar); sl++) {
+ pi2b[sl] = dkT('0');
+ }
+ pi2b[DK4_SIZEOF(pi2b,dkChar)-1] = dkT('\0');
+ sl = dk4str_len(pidb);
+ pl = dk4numlength(sizeof(dk4_pid_t), 0);
+ if (sl < pl) {
+ ok = dk4str_cpy_s(
+ &(pi2b[pl - sl]),
+ (DK4_SIZEOF(pi2b,dkChar) - (pl - sl)),
+ pidb, NULL
+ );
+ } else {
+ ok = dk4str_cpy_s(pi2b,DK4_SIZEOF(pi2b,dkChar),pidb,NULL);
+ }
+ if (0 != ok) {
+ ok = 0;
+ if (dk4str_cat_s(fnb, sz, dk4app_open_kw[11], NULL)) {
+ if (dk4str_cat_s(fnb, sz, dktb, NULL)) {
+ if (dk4str_cat_s(fnb, sz, dk4app_open_kw[11], NULL)) {
+ if (dk4str_cat_s(fnb, sz, pi2b, NULL)) {
+ if (dk4str_cat_s(fnb,sz,dk4app_open_kw[12],NULL)) {
+ app->log_file_name = dk4str_dup(fnb,NULL);
+ if (NULL != app->log_file_name) {
+ dk4path_correct_sep(app->log_file_name);
+ ok = 1;
+
+#line 1894 "dk4appop.ctr"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if (0 != ok) {
+ ok = 0;
+ (void)dk4str_cpy_s(fnb, sz, app->user_home, NULL);
+ (void)dk4str_cat_s(fnb, sz, dk4app_open_kw[13], NULL);
+ (void)dk4str_cat_s(fnb, sz, dk4app_open_kw[10], NULL);
+ (void)dk4str_cat_s(fnb, sz, app->prog_name, NULL);
+ (void)dk4str_cat_s(fnb, sz, dk4app_open_kw[11], NULL);
+ (void)dk4str_cat_s(fnb, sz, dktb, NULL);
+ (void)dk4str_cat_s(fnb, sz, dk4app_open_kw[11], NULL);
+ (void)dk4str_cat_s(fnb, sz, pi2b, NULL);
+ dk4path_correct_sep(fnb);
+ app->dir_tmp = dk4str_dup(fnb, NULL);
+ if (NULL != app->dir_tmp) {
+#if VERSION_BEFORE_20160127
+ ok = dk4app_mkdir_hierarchy(app->dir_tmp, 0, app);
+#else
+ ok = 1;
+#endif
+
+
+#line 1920 "dk4appop.ctr"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if (0 == ok) {
+ /* ERROR: Failed to construct log file name */
+ ae->error_found = E_LOG_FILE_NAME;
+ }
+
+
+#line 1935 "dk4appop.ctr"
+}
+
+
+
+/** Process command line arguments.
+ Save all non-option arguments in my_argc and my_argv if
+ an option specification available, all arguments otherwise.
+ @param app Application to set up.
+ @param ae Application open error structure.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+*/
+static
+void
+dk4app_open_process_argc_argv(
+ dk4_app_t *app,
+ dk4_app_error_t *ae,
+ int argc,
+ dkChar **argv
+)
+{
+ dkChar b[DK4_MAX_PATH + 128]; /* Private copy */
+ dkChar *argptr; /* Current option to process. */
+ dkChar *pv; /* Option value pointer */
+ dkChar *opv; /* Original option value pointer */
+ const dkChar *endptr; /* First char after value */
+ dk4_option_t *ospec; /* Option specification */
+ dk4_pref_t *prefptr; /* Preference */
+ double dval; /* Double value */
+ dk4_um_t uval; /* Unsigned integer value */
+ dk4_im_t ival; /* Integer value */
+ size_t szval; /* Size argument */
+ int i; /* Current option index to process */
+ int argsused; /* used elements in my_argv */
+ int res; /* Numeric conversion result */
+ int must_add; /* Flag: Must add to list */
+ int oi; /* Output index */
+
+
+#line 1973 "dk4appop.ctr"
+ if (0 < argc) {
+
+#line 1974 "dk4appop.ctr"
+ app->my_argv = dk4mem_new(DK4_PDKCHAR,argc,NULL);
+ if (NULL != app->my_argv) {
+
+#line 1976 "dk4appop.ctr"
+ for (i = 0; i < argc; i++) { (app->my_argv)[i] = NULL; }
+ if (dk4app_open_options_check(app)) {
+
+#line 1978 "dk4appop.ctr"
+ argsused = 0;
+ for (i = 1; i < argc; i++) {
+ argptr = argv[i];
+
+#line 1981 "dk4appop.ctr"
+ if (dkT('-') == *argptr) {
+
+#line 1982 "dk4appop.ctr"
+ if (dkT('-') == argptr[1]) {
+
+#line 1983 "dk4appop.ctr"
+ if (0 == dk4app_open_check_long_opt(app, ae, &(argptr[2]))) {
+ if (0 != dk4str_cpy_s(b,DK4_SIZEOF(b,dkChar),&(argptr[2]),NULL))
+ {
+
+
+#line 1987 "dk4appop.ctr"
+ opv = NULL;
+ pv = dk4str_chr(b, dkT('='));
+ if (NULL != pv) {
+ *(pv++) = dkT('\0');
+ pv = dk4str_start(pv, NULL);
+ }
+ if (NULL != pv) {
+ opv = dk4str_chr(&(argptr[2]), dkT('='));
+ if (NULL != opv) { opv = dk4str_start(++opv, NULL); }
+ }
+ ospec = dk4sto_it_find_like(
+ app->i_opt_long, (void *)b, 3
+ );
+
+#line 2000 "dk4appop.ctr"
+ if (NULL != ospec) {
+
+#line 2001 "dk4appop.ctr"
+ ospec->found = 1;
+ switch ((ospec->spec).argtype) {
+ case DK4_OPT_ARG_BOOL:
+ case DK4_OPT_ARG_SIZE:
+ case DK4_OPT_ARG_INT:
+ case DK4_OPT_ARG_UNSIGNED:
+ case DK4_OPT_ARG_DOUBLE:
+ case DK4_OPT_ARG_STRING: {
+
+#line 2009 "dk4appop.ctr"
+ if (NULL == opv) {
+
+#line 2010 "dk4appop.ctr"
+ if ((1 + i) < argc) {
+
+#line 2011 "dk4appop.ctr"
+ opv = argv[++i];
+ }
+ }
+ if (NULL != opv) {
+
+#line 2015 "dk4appop.ctr"
+ switch ((ospec->spec).argtype) {
+ case DK4_OPT_ARG_BOOL: {
+ (ospec->val).b = 0;
+ if (dk4str_is_bool(opv)) {
+
+#line 2019 "dk4appop.ctr"
+ (ospec->val).b = dk4str_is_on(opv);
+ } else {
+
+#line 2021 "dk4appop.ctr"
+ /* ERROR: Not a boolean argument */
+ dk4app_log_base5(
+ app, DK4_LL_ERROR, 33, 14, 15,
+ b, opv
+ );
+ if (0 == ae->error_found) {
+ ae->error_found = E_INVALID_OPTION_ARG;
+ }
+ }
+ } break;
+ case DK4_OPT_ARG_SIZE: {
+ (ospec->val).s = 0;
+ szval = 0;
+ endptr = NULL;
+ res = dk4ma_input_dk_dec_size_t(
+ &szval, opv, &endptr, 1, NULL
+ );
+ if (0 != res) {
+
+#line 2039 "dk4appop.ctr"
+ (ospec->val).s = szval;
+ } else {
+
+#line 2041 "dk4appop.ctr"
+ /* ERROR: Not a size specification */
+ dk4app_log_base7(
+ app, DK4_LL_ERROR, 32, 17, 154, 18,
+ b, endptr, opv
+ );
+ if (0 == ae->error_found) {
+ ae->error_found = E_INVALID_OPTION_ARG;
+ }
+ }
+ } break;
+ case DK4_OPT_ARG_INT: {
+ ival = (dk4_im_t)0L;
+ (ospec->val).i = (dk4_im_t)0L;
+ endptr = NULL;
+ res = dk4ma_input_dk_dec_dk4_im_t(
+ &ival, opv, &endptr, 1, NULL
+ );
+ if (0 != res) {
+
+#line 2059 "dk4appop.ctr"
+ (ospec->val).i = ival;
+ } else {
+
+#line 2061 "dk4appop.ctr"
+ /* ERROR: Not an integer value */
+ dk4app_log_base7(
+ app, DK4_LL_ERROR, 31, 20, 154, 21,
+ b, endptr, opv
+ );
+ if (0 == ae->error_found) {
+ ae->error_found = E_INVALID_OPTION_ARG;
+ }
+ }
+ } break;
+ case DK4_OPT_ARG_UNSIGNED: {
+ uval = (dk4_um_t)0UL;
+ (ospec->val).u = (dk4_um_t)0UL;
+ endptr = NULL;
+ res = dk4ma_input_dk_dec_dk4_um_t(
+ &uval, opv, &endptr, 1, NULL
+ );
+ if (0 != res) {
+
+#line 2079 "dk4appop.ctr"
+ (ospec->val).u = uval;
+ } else {
+
+#line 2081 "dk4appop.ctr"
+ /* ERROR: Not an unsigned integer value */
+ dk4app_log_base7(
+ app, DK4_LL_ERROR, 30, 23, 154, 24,
+ b, endptr, opv
+ );
+ if (0 == ae->error_found) {
+ ae->error_found = E_INVALID_OPTION_ARG;
+ }
+ }
+ } break;
+ case DK4_OPT_ARG_DOUBLE: {
+
+#line 2092 "dk4appop.ctr"
+ dval = 0.0;
+ (ospec->val).d = 0.0;
+ endptr = NULL;
+ res = dk4ma_input_dk_double(
+ &dval, opv, &endptr, 1, NULL
+ );
+ if (0 != res) {
+
+#line 2099 "dk4appop.ctr"
+ (ospec->val).d = dval;
+ } else {
+
+#line 2101 "dk4appop.ctr"
+ dk4app_log_base7(
+ app, DK4_LL_ERROR, 29, 26, 154, 27,
+ b, endptr, opv
+ );
+ if (0 == ae->error_found) {
+ ae->error_found = E_INVALID_OPTION_ARG;
+ }
+ }
+ } break;
+ case DK4_OPT_ARG_STRING: {
+
+#line 2111 "dk4appop.ctr"
+ (ospec->val).t = opv;
+ } break;
+ }
+ } else {
+
+#line 2115 "dk4appop.ctr"
+ /* ERROR: Option requires argument */
+ dk4app_log_base3(
+ app, DK4_LL_ERROR, 28, 12, b
+ );
+ if (0 == ae->error_found) {
+ ae->error_found = E_OPT_REQUIRES_ARG;
+ }
+ }
+ } break;
+ }
+ } else {
+
+#line 2126 "dk4appop.ctr"
+ /* Handle preference */
+ if (NULL != pv) {
+
+#line 2128 "dk4appop.ctr"
+ prefptr = dk4sto_it_find_like(app->i_pref_cmd, b, 1);
+ if (NULL != prefptr) {
+
+#line 2130 "dk4appop.ctr"
+ opv = dk4str_dup(pv, NULL);
+ if (NULL != opv) {
+
+#line 2132 "dk4appop.ctr"
+#if 0
+ dk4mem_release(prefptr->value);
+#endif
+ /* 2016-12-10 Sanitize memory.
+ */
+ dk4str_release_sanitized(prefptr->value);
+ prefptr->value = opv;
+ } else {
+
+#line 2140 "dk4appop.ctr"
+ /* ERROR: Failed to save preference value */
+ dk4app_log_base5(
+ app, DK4_LL_ERROR, 34, 35, 36, b, pv
+ );
+ if (0 == ae->error_found) {
+ ae->error_found = E_MEMORY;
+ }
+ }
+ } else {
+
+#line 2149 "dk4appop.ctr"
+ prefptr = dk4pref_open(b, pv, NULL);
+ if (NULL != prefptr) {
+
+#line 2151 "dk4appop.ctr"
+ if (0 != dk4sto_add(app->s_pref_cmd, prefptr, NULL)) {
+
+
+#line 2153 "dk4appop.ctr"
+ } else {
+
+#line 2154 "dk4appop.ctr"
+ /* ERROR: Failed to save preference value */
+ dk4app_log_base5(
+ app, DK4_LL_ERROR, 34, 35, 36,
+ b, pv
+ );
+ dk4pref_close(prefptr);
+ if (0 == ae->error_found) {
+ ae->error_found = E_MEMORY;
+ }
+ }
+ } else {
+
+#line 2165 "dk4appop.ctr"
+ /* ERROR: Failed to save preference value */
+ dk4app_log_base5(
+ app, DK4_LL_ERROR, 34, 35, 36,
+ b, pv
+ );
+ if (0 == ae->error_found) {
+ ae->error_found = E_MEMORY;
+ }
+ }
+ }
+ dk4app_pref_apply(app, ae, b, pv);
+ } else {
+
+#line 2177 "dk4appop.ctr"
+ /* ERROR: Missing preference value */
+ dk4app_log_base3(app, DK4_LL_ERROR, 37, 38, b);
+ if (0 == ae->error_found) {
+ ae->error_found = E_OPT_REQUIRES_ARG;
+ }
+ }
+ }
+ } else {
+
+#line 2185 "dk4appop.ctr"
+ /* ERROR: Option too long! */
+ dk4app_log_base3(app, DK4_LL_ERROR, 39, 40, argptr);
+ if (0 == ae->error_found) {
+ ae->error_found = E_OPTION_TOO_LONG;
+ }
+ }
+ }
+ } else {
+
+#line 2193 "dk4appop.ctr"
+ ospec = dk4sto_it_find_like(
+ app->i_opt_short, (void *)(&(argptr[1])), 1
+ );
+ if (NULL != ospec) {
+
+#line 2197 "dk4appop.ctr"
+ ospec->found = 1;
+ pv = NULL;
+ switch ((ospec->spec).argtype) {
+ case DK4_OPT_ARG_BOOL:
+ case DK4_OPT_ARG_SIZE:
+ case DK4_OPT_ARG_INT:
+ case DK4_OPT_ARG_UNSIGNED:
+ case DK4_OPT_ARG_DOUBLE:
+ case DK4_OPT_ARG_STRING: {
+
+#line 2206 "dk4appop.ctr"
+ pv = dk4str_start(&(argptr[2]), NULL);
+ if (NULL == pv) {
+
+#line 2208 "dk4appop.ctr"
+ if ((1 + i) < argc) {
+
+#line 2209 "dk4appop.ctr"
+ pv = argv[++i];
+ }
+ }
+ if (NULL != pv) {
+ switch ((ospec->spec).argtype) {
+ case DK4_OPT_ARG_BOOL: {
+ (ospec->val).b = 0;
+ if (dk4str_is_bool(pv)) {
+
+#line 2217 "dk4appop.ctr"
+ (ospec->val).b = dk4str_is_on(pv);
+ } else {
+
+#line 2219 "dk4appop.ctr"
+ /* ERROR: Not a boolean argument */
+ dk4app_log_base5(
+ app, DK4_LL_ERROR, 13, 14, 15,
+ argptr, pv
+ );
+ if (0 == ae->error_found) {
+ ae->error_found = E_INVALID_OPTION_ARG;
+ }
+ }
+ } break;
+ case DK4_OPT_ARG_SIZE: {
+ (ospec->val).s = 0;
+ szval = 0;
+ endptr = NULL;
+ res = dk4ma_input_dk_dec_size_t(
+ &szval, pv, &endptr, 1, NULL
+ );
+ if (0 != res) {
+
+#line 2237 "dk4appop.ctr"
+ (ospec->val).s = szval;
+ } else {
+
+#line 2239 "dk4appop.ctr"
+ /* ERROR: Not a size specification */
+ dk4app_log_base7(
+ app, DK4_LL_ERROR, 16, 17, 154, 18,
+ argptr, endptr, pv
+ );
+ if (0 == ae->error_found) {
+ ae->error_found = E_INVALID_OPTION_ARG;
+ }
+ }
+ } break;
+ case DK4_OPT_ARG_INT: {
+ ival = (dk4_im_t)0L;
+ (ospec->val).i = (dk4_im_t)0L;
+ endptr = NULL;
+ res = dk4ma_input_dk_dec_dk4_im_t(
+ &ival, pv, &endptr, 1, NULL
+ );
+ if (0 != res) {
+
+#line 2257 "dk4appop.ctr"
+ (ospec->val).i = ival;
+ } else {
+
+#line 2259 "dk4appop.ctr"
+ /* ERROR: Not an integer value */
+ dk4app_log_base7(
+ app, DK4_LL_ERROR, 19, 20, 154, 21,
+ argptr, endptr, pv
+ );
+ if (0 == ae->error_found) {
+ ae->error_found = E_INVALID_OPTION_ARG;
+ }
+ }
+ } break;
+ case DK4_OPT_ARG_UNSIGNED: {
+ uval = (dk4_um_t)0UL;
+ (ospec->val).u = (dk4_um_t)0UL;
+ endptr = NULL;
+ res = dk4ma_input_dk_dec_dk4_um_t(
+ &uval, pv, &endptr, 1, NULL
+ );
+ if (0 != res) {
+
+#line 2277 "dk4appop.ctr"
+ (ospec->val).u = uval;
+ } else {
+
+#line 2279 "dk4appop.ctr"
+ /* ERROR: Not an unsigned integer value */
+ dk4app_log_base7(
+ app, DK4_LL_ERROR, 22, 23, 154, 24,
+ argptr, endptr, pv
+ );
+ if (0 == ae->error_found) {
+ ae->error_found = E_INVALID_OPTION_ARG;
+ }
+ }
+ } break;
+ case DK4_OPT_ARG_DOUBLE: {
+
+#line 2290 "dk4appop.ctr"
+ dval = 0.0;
+ (ospec->val).d = 0.0;
+ endptr = NULL;
+ res = dk4ma_input_dk_double(
+ &dval, pv, &endptr, 1, NULL
+ );
+ if (0 != res) {
+
+#line 2297 "dk4appop.ctr"
+ (ospec->val).d = dval;
+ } else {
+
+#line 2299 "dk4appop.ctr"
+ dk4app_log_base7(
+ app, DK4_LL_ERROR, 25, 26, 154, 27,
+ argptr, endptr, pv
+ );
+ if (0 == ae->error_found) {
+ ae->error_found = E_INVALID_OPTION_ARG;
+ }
+ }
+ } break;
+ case DK4_OPT_ARG_STRING: {
+
+#line 2309 "dk4appop.ctr"
+ (ospec->val).t = pv;
+ } break;
+ }
+ } else {
+
+#line 2313 "dk4appop.ctr"
+ /* ERROR: Option requires argument */
+ dk4app_log_base3(
+ app, DK4_LL_ERROR, 11, 12, argptr
+ );
+ if (0 == ae->error_found) {
+ ae->error_found = E_OPT_REQUIRES_ARG;
+ }
+ }
+ } break;
+ }
+ } else {
+
+#line 2324 "dk4appop.ctr"
+ /* ERROR: Unexpected option */
+ dk4app_log_base3(app, DK4_LL_ERROR, 9, 10, argptr);
+ if (0 == ae->error_found) {
+ ae->error_found = E_UNEXPECTED_OPTION;
+ }
+ }
+ }
+ } else {
+
+#line 2332 "dk4appop.ctr"
+ (app->my_argv)[argsused++] = argptr;
+ }
+ }
+ app->my_argc = argsused;
+ } else {
+
+#line 2337 "dk4appop.ctr"
+ oi = 0;
+ for (i = 0; (i + 1) < argc; i++) {
+ must_add = 1;
+ if (dkT('-') == (argv[i + 1])[0]) {
+ if (dkT('-') == (argv[i + 1])[1]) {
+ if (0 == dk4app_open_check_long_opt(app, ae, &((argv[i+1])[2]))) {
+ /* Treat all long options as preferences.
+ */
+ must_add = dk4str_cpy_s(
+ b, DK4_SIZEOF(b,dkChar), &((argv[i + 1])[2]), NULL
+ );
+ if (0 != must_add) {
+ opv = NULL;
+ pv = dk4str_chr(b, dkT('='));
+ if (NULL != pv) {
+ *(pv++) = dkT('\0');
+ pv = dk4str_start(pv, NULL);
+ }
+ if (NULL != pv) {
+ opv = dk4str_chr(&((argv[i + 1])[2]), dkT('='));
+ if (NULL != opv) { opv = dk4str_start(++opv, NULL); }
+#ifdef __clang_analyzer__
+ /* 2015-08-21 / 2016-01-20
+ Static code analysis by clang complains
+ opv is set but not used later. Probably true.
+ */
+ (void)opv;
+#endif
+ }
+ if (NULL != pv) {
+ prefptr = dk4sto_it_find_like(app->i_pref_cmd, b, 1);
+ if (NULL != prefptr) {
+ opv = dk4str_dup(pv, NULL);
+ if (NULL != opv) {
+#if 0
+ dk4mem_release(prefptr->value);
+#endif
+ /* 2016-12-10 Sanitize memory.
+ */
+ dk4str_release_sanitized(prefptr->value);
+ prefptr->value = opv;
+ } else {
+ dk4app_log_base5(
+ app, DK4_LL_ERROR, 34, 35, 36, b, pv
+ );
+ if (0 == ae->error_found) {
+ ae->error_found = E_MEMORY;
+ }
+ }
+ } else {
+ prefptr = dk4pref_open(b, pv, NULL);
+ if (NULL != prefptr) {
+ if (0 == dk4sto_add(app->s_pref_cmd, prefptr, NULL)) {
+ dk4app_log_base5(
+ app, DK4_LL_ERROR, 34, 35, 36, b, pv
+ );
+ dk4pref_close(prefptr);
+ if (0 == ae->error_found) {
+ ae->error_found = E_MEMORY;
+ }
+ }
+ } else {
+ dk4app_log_base5(
+ app, DK4_LL_ERROR, 34, 35, 36, b, pv
+ );
+ if (0 == ae->error_found) {
+ ae->error_found = E_MEMORY;
+ }
+ }
+ }
+ dk4app_pref_apply(app, ae, b, pv);
+ } else {
+ dk4app_log_base3(app, DK4_LL_ERROR, 37, 38, b);
+ if (0 == ae->error_found) {
+ ae->error_found = E_OPT_REQUIRES_ARG;
+ }
+ }
+ } else {
+ /* ERROR: Option too long! */
+ dk4app_log_base3(app, DK4_LL_ERROR, 39, 40, argv[i + 1]);
+ if (0 == ae->error_found) {
+ ae->error_found = E_OPTION_TOO_LONG;
+ }
+ }
+ }
+ must_add = 0;
+ }
+ }
+ if (0 != must_add) {
+ (app->my_argv)[oi++] = argv[i + 1];
+ }
+ }
+ app->my_argc = oi;
+
+#line 2430 "dk4appop.ctr"
+ }
+ } else {
+
+#line 2432 "dk4appop.ctr"
+ if (0 == ae->error_found) { ae->error_found = E_MEMORY; }
+ }
+ } else {
+
+#line 2435 "dk4appop.ctr"
+ if (0 == ae->error_found) { ae->error_found = E_ARGC; }
+ }
+
+#line 2437 "dk4appop.ctr"
+}
+
+
+
+/** Keep private copies of version text, help file name, help text
+ and license text.
+ @param app
+ @param ae
+ @param version
+ @param helpfile
+ @param helptext
+ @param lictext
+*/
+static
+void
+dk4app_open_save_names(
+ dk4_app_t *app,
+ dk4_app_error_t *ae,
+ const dkChar *version,
+ const dkChar *helpfile,
+ const dkChar * const *helptext,
+ const dkChar * const *lictext
+)
+{
+ int ok = 0;
+ if (NULL != version) {
+ if (NULL != helpfile) {
+ if (NULL != helptext) {
+ if (NULL != lictext) {
+ ok = 1;
+ app->help_text = helptext;
+ app->lic_text = lictext;
+ app->vers_text = dk4str_dup(version, NULL);
+ app->help_file_name = dk4str_dup(helpfile, NULL);
+ if ((NULL == app->vers_text) || (NULL == app->help_file_name)) {
+ if (0 == ae->error_found) { ae->error_found = E_MEMORY; }
+ }
+ }
+ }
+ }
+ }
+ if (0 == ok) {
+ if (0 == ae->error_found) { ae->error_found = E_BUG_ARGUMENTS; }
+ }
+}
+
+
+
+/** Open an application structure for a command line program.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @param optspec Option specification, may be NULL.
+ @param szoptspec Number of elements in optspec.
+ @param groupname Program group name.
+ @param version Version number string.
+ @param helpfile Help file name.
+ @param helptext Default help text.
+ @param lictext License conditions text.
+ @param enablog Flag: Enable logging.
+ @return Pointer to dk4_app_t structure on success, NULL on error.
+*/
+static
+dk4_app_t *
+dk4app_open_internally(
+ int argc,
+ dkChar **argv,
+ const dk4_option_specification_t *optspec,
+ size_t szoptspec,
+ const dkChar *groupname,
+ const dkChar *version,
+ const dkChar *helpfile,
+ const dkChar * const *helptext,
+ const dkChar * const *lictext,
+ int enablog
+)
+{
+ dk4_app_error_t ae; /* Error during startup */
+ dk4_app_t *back = NULL; /* Function result */
+ int quiet = 0; /* Flag: Run quiet */
+
+
+
+#line 2518 "dk4appop.ctr"
+ DK4_MEMRES(&ae, sizeof(dk4_app_error_t));
+ ae.error_found = 0;
+ if (NULL != groupname) {
+ if ((0 < argc) && (NULL != argv)) {
+ quiet = dk4app_open_silence_check(argc, argv);
+ back = dk4mem_new(dk4_app_t,1,NULL);
+ if (NULL != back) {
+ /* Set all members to reasonable default */
+ dk4app_open_initialize(back);
+
+ back->group_name = dk4str_dup(groupname, NULL);
+ if (NULL == back->group_name) {
+ ae.error_found = E_MEMORY;
+ }
+
+ if (0 == ae.error_found) {
+ dk4app_open_save_names(
+ back, &ae,
+ version, helpfile, helptext, lictext
+ );
+ }
+
+ /* Find host name */
+ if (0 == ae.error_found) {
+ dk4app_open_find_host_name(back, &ae);
+ }
+
+ /* Find user name and home directory */
+ if (0 == ae.error_found) {
+ dk4app_open_find_user_name_and_home(back, &ae);
+ }
+
+ /* Find language and region */
+ if (0 == ae.error_found) {
+ dk4app_open_find_language_region(back, &ae);
+ }
+
+ /* Find executable path name and derive directory names from it */
+ if (0 == ae.error_found) {
+ dk4app_open_find_executable(back, &ae, argv[0]);
+ }
+
+ /* Create option storage from option specification */
+ if (0 == ae.error_found) {
+ dk4app_open_create_options_storages(
+ back, &ae, optspec, szoptspec
+ );
+ }
+
+ /* Create preferences storage */
+ if (0 == ae.error_found) {
+ dk4app_open_create_pref_storages(back, &ae);
+ }
+
+ /* Create string table storage */
+ if (0 == ae.error_found) {
+ dk4app_open_create_stt_storage(back, &ae);
+ }
+
+ /* Read preference files */
+ if (0 == ae.error_found) {
+ dk4app_open_read_preference_files(back, &ae);
+ }
+
+ /* Construct log file name, create log directory */
+ if ((0 != enablog) && (0 == quiet) && (0 == ae.error_found)) {
+ dk4app_open_prepare_file_logging(back, &ae);
+ }
+
+ /* Enable logging if not switched to silent mode */
+ if ((0 != enablog) && (0 == quiet) && (0 == ae.error_found)) {
+ back->log_enabled = 1;
+ }
+
+ /* We must be able to log, if there are errors */
+ if (0 == ae.error_found) {
+ /* Process command line arguments, search for options */
+ dk4app_open_process_argc_argv(back, &ae, argc, argv);
+ }
+
+ /* If there were serious errors, destroy the structure */
+ if (ae.error_found) {
+ dk4app_open_report_error(back, &ae);
+ dk4app_close(back);
+ back = NULL;
+ }
+ } else {
+
+#line 2605 "dk4appop.ctr"
+ if (0 == quiet) {
+ char buf[64];
+ int res;
+ res = dk4ma_write_c8_decimal_unsigned(
+ buf, sizeof(buf), (dk4_um_t)sizeof(dk4_app_t), 0, NULL
+ );
+ if (0 != res) {
+ fputs(dk4app_open_c8_kw[1], stderr);
+ fputs(buf, stderr);
+ fputs(dk4app_open_c8_kw[2], stderr);
+ } else {
+ fputs(dk4app_open_c8_kw[0], stderr);
+ }
+ fputc('\n', stderr);
+ fflush(stderr);
+ }
+ }
+ } else {
+
+#line 2623 "dk4appop.ctr"
+ }
+ } else {
+
+#line 2625 "dk4appop.ctr"
+ }
+ if (NULL != back) {
+
+#line 2627 "dk4appop.ctr"
+ if (0 != dk4app_log_do(back, DK4_LL_DEBUG)) {
+
+#line 2628 "dk4appop.ctr"
+ (void)dk4app_log_debug_texts(back, NULL);
+ dk4app_log_startup_debug(back);
+ }
+ }
+
+#line 2632 "dk4appop.ctr"
+ return back;
+}
+
+
+
+
+dk4_app_t *
+dk4app_open_cmd(
+ int argc,
+ dkChar **argv,
+ const dk4_option_specification_t *optspec,
+ size_t szoptspec,
+ const dkChar *groupname,
+ const dkChar *version,
+ const dkChar *helpfile,
+ const dkChar * const *helptext,
+ const dkChar * const *lictext
+)
+{
+ dk4_app_t *back;
+ back = dk4app_open_internally(
+ argc, argv, optspec, szoptspec, groupname, version,
+ helpfile, helptext, lictext, 1
+ );
+ return back;
+}
+
+
+
+
+dk4_app_t *
+dk4app_open_silent(
+ int argc,
+ dkChar **argv,
+ const dk4_option_specification_t *optspec,
+ size_t szoptspec,
+ const dkChar *groupname,
+ const dkChar *version,
+ const dkChar *helpfile,
+ const dkChar * const *helptext,
+ const dkChar * const *lictext
+)
+{
+ dk4_app_t *back;
+ back = dk4app_open_internally(
+ argc, argv, optspec, szoptspec, groupname, version,
+ helpfile, helptext, lictext, 0
+ );
+ return back;
+}
+
+
+
+void
+dk4app_set_fast_close(dk4_app_t *app)
+{
+ if (NULL != app) {
+ app->fast_close = 1;
+ }
+}
+
diff --git a/support/dktools/dk4appop.ctr b/support/dktools/dk4appop.ctr
new file mode 100644
index 0000000000..a5e523b3df
--- /dev/null
+++ b/support/dktools/dk4appop.ctr
@@ -0,0 +1,2692 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+/** @file
+ Open and close dk4_app_t structure.
+*/
+
+#ifndef DK4APP_H_INCLUDED
+#include "dk4app.h"
+#endif
+
+#ifndef DK4STT_H_INCLUDED
+#include "dk4stt.h"
+#endif
+
+#ifndef DK4CONST_H_INCLUDED
+#include "dk4const.h"
+#endif
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4STR8_H_INCLUDED
+#include "dk4str8.h"
+#endif
+
+#ifndef DK4STRW_H_INCLUDED
+#include "dk4strw.h"
+#endif
+
+#ifndef DK4STRD_H_INCLUDED
+#include "dk4strd.h"
+#endif
+
+#ifndef DK4ENC_H_INCLUDED
+#include "dk4enc.h"
+#endif
+
+#ifndef DK4LOC_H_INCLUDED
+#include "dk4loc.h"
+#endif
+
+#ifndef DK4MPL_H_INCLUDED
+#include "dk4mpl.h"
+#endif
+
+#ifndef DK4EXEPD_H_INCLUDED
+#include "dk4exepd.h"
+#endif
+
+#ifndef DK4MAO8D_H_INCLUDED
+#include "dk4mao8d.h"
+#endif
+
+#ifndef DK4INST_H_INCLUDED
+#include "dk4inst.h"
+#endif
+
+#ifndef DK4PREF_H_INCLUDED
+#include "dk4pref.h"
+#endif
+
+#ifndef DK4USER_H_INCLUDED
+#include "dk4user.h"
+#endif
+
+#ifndef DK4FS_H_INCLUDED
+#include "dk4fs.h"
+#endif
+
+#ifndef DK4STRMR_H_INCLUDED
+#include "dk4strmr.h"
+#endif
+
+#ifndef DK4TSPDK_H_INCLUDED
+#include "dk4tspdk.h"
+#endif
+
+#ifndef DK4FPUT_H_INCLUDED
+#include "dk4fput.h"
+#endif
+
+#ifndef DK4HNAMED_H_INCLUDED
+#include "dk4hnamed.h"
+#endif
+
+#ifndef DK4MAIDDDI_H_INCLUDED
+#include "dk4maidddi.h"
+#endif
+
+#ifndef DK4MAIDDDU_H_INCLUDED
+#include "dk4maidddu.h"
+#endif
+
+#ifndef DK4MAIDDSZ_H_INCLUDED
+#include "dk4maiddsz.h"
+#endif
+
+#ifndef DK4MAIDDBL_H_INCLUDED
+#include "dk4maiddbl.h"
+#endif
+
+#ifndef DK4MAODD_H_INCLUDED
+#include "dk4maodd.h"
+#endif
+
+#ifndef DK4NUML_H_INCLUDED
+#include "dk4numl.h"
+#endif
+
+#ifndef DK4STO_H_INCLUDED
+#include "dk4sto.h"
+#endif
+
+#ifndef DK4APPI_C_INCLUDED
+#include "dk4appi.c"
+#endif
+
+#ifndef DK4PATHD_H_INCLUDED
+#include "dk4pathd.h"
+#endif
+
+#ifndef DK4STATD_H_INCLUDED
+#include "dk4statd.h"
+#endif
+
+#ifndef DK4STAT_H_INCLUDED
+#include "dk4stat.h"
+#endif
+
+#ifndef DK4REC21_H_INCLUDED
+#include "dk4rec21.h"
+#endif
+
+#ifndef DK4TIME_H_INCLUDED
+#include "dk4time.h"
+#endif
+
+#ifndef DK4TIMEDK_H_INCLUDED
+#include "dk4timedk.h"
+#endif
+
+#ifndef DK4GETPID_H_INCLUDED
+#include "dk4getpid.h"
+#endif
+
+#ifndef DK4APPMKDH_H_INCLUDED
+#include "dk4appmkdh.h"
+#endif
+
+#ifndef DK4DELFILE_H_INCLUDED
+#include "dk4delfile.h"
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Log at application startup.
+ @param app Application structure.
+*/
+void
+dk4app_log_startup_debug(dk4_app_t *app);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+$!trace-include
+
+
+
+static const dkChar * const dk4app_open_long_opt[] = {
+$!string-table macro=dkT
+#
+# 0
+#
+help
+#
+# 1
+#
+version
+#
+# 2
+#
+license
+#
+# 3
+#
+quiet
+#
+# 4
+#
+manual
+$!end
+};
+
+
+
+static const dkChar * const dk4app_open_scope_names[] = {
+$!string-table macro=dkT
+#
+# 0
+#
+user
+#
+# 1
+#
+application
+#
+# 2
+#
+application-group
+#
+# 3
+#
+host
+#
+# 4
+#
+windows
+#
+# 5
+#
+non-windows
+#
+# 6
+#
+language
+#
+# 7
+#
+region
+$!end
+};
+
+
+
+/** Non localized 8 bit char keywords used by this module.
+*/
+static const char * const dk4app_open_c8_kw[] = {
+$!string-table
+ERROR: Not enough memory!
+ERROR: Not enough memory, failed to allocate
+ bytes!
+$!end
+};
+
+
+
+/** Non localized dkChar keywords used by this module.
+*/
+static const dkChar * const dk4app_open_kw[] = {
+$!string-table macro=dkT
+#
+# 0 Long option for running silently.
+#
+--quiet
+#
+# 1 Sub directory name for binaries
+#
+bin
+#
+# 2 Sub directory name for binaries
+#
+sbin
+#
+# 3 ... 6 Sub directory names
+#
+etc
+share
+lib
+var
+#
+# 7 Sub directory name
+#
+libexec
+#
+# 8 Preference config file name
+#
+dk4pref.conf
+#
+# 9 10 11 12 Parts to construct log file name.
+#
+/log
+/
+-
+.log
+#
+# 13 Parts to construct temporary directory name
+#
+/tmp
+#
+# 14 Compatible preferences file name
+#
+dk3pref.conf
+#
+# 15 Wildcard matching all hosts, users, programs...
+#
+*
+$!end
+};
+
+
+
+/** Character used as separator between path name components.
+*/
+static const dkChar dk4app_filename_sep[] =
+#if DK4_HAVE_BACKSLASH_AS_SEP
+dkT("\\")
+#else
+dkT("/")
+#endif
+;
+
+
+
+#if DK4_ON_WINDOWS
+/** File name suffixes for executable files on Windows systems.
+*/
+static const dkChar * const dk4app_exe_file_suffixes[] = {
+$!string-table macro=dkT
+.exe
+.com
+.dll
+.sys
+.cpl
+$!end
+};
+#endif
+
+
+
+/** Initialize an application structure after allocating the memory.
+ @param ptr Structure to initialize.
+*/
+static
+void
+dk4app_open_initialize(dk4_app_t *ptr)
+{
+ $? "+ dk4app_open_initialize"
+ ptr->s_opt_all = NULL;
+ ptr->i_opt_all = NULL;
+ ptr->s_opt_short = NULL;
+ ptr->i_opt_short = NULL;
+ ptr->s_opt_long = NULL;
+ ptr->i_opt_long = NULL;
+ ptr->s_pref_self = NULL;
+ ptr->s_pref_cmd = NULL;
+ ptr->s_pref_user = NULL;
+ ptr->s_pref_sys = NULL;
+ ptr->s_stt = NULL;
+ ptr->i_pref_self = NULL;
+ ptr->i_pref_cmd = NULL;
+ ptr->i_pref_user = NULL;
+ ptr->i_pref_sys = NULL;
+ ptr->i_stt = NULL;
+ ptr->msg_base = NULL;
+ ptr->msg_debug = NULL;
+ ptr->help_text = NULL;
+ ptr->lic_text = NULL;
+ ptr->my_argv = NULL;
+ ptr->vers_text = NULL;
+ ptr->help_file_name = NULL;
+ ptr->user_name = NULL;
+ ptr->host_name = NULL;
+ ptr->user_home = NULL;
+ ptr->language = NULL;
+ ptr->region = NULL;
+ ptr->prog_name = NULL;
+ ptr->group_name = NULL;
+ ptr->dir_bin = NULL;
+ ptr->dir_etc = NULL;
+ ptr->dir_share = NULL;
+ ptr->dir_lib = NULL;
+ ptr->dir_var = NULL;
+ ptr->dir_tmp = NULL;
+ ptr->log_file_name = NULL;
+ ptr->source_file_name = NULL;
+ ptr->source_file_line = (dk4_um_t)0UL;
+ ptr->timer_stderr = (dk4_time_t)0UL;
+ ptr->timer_file = (dk4_time_t)0UL;
+ ptr->sz_msg_base = 0;
+ ptr->sz_msg_debug = 0;
+ ptr->have_stderr_time = 0;
+ ptr->have_file_time = 0;
+ ptr->have_file_opened = 0;
+ ptr->have_stderr_init = 0;
+ ptr->my_argc = 0;
+ ptr->ll_stderr = DK4_LL_WARNING;
+ ptr->ll_file = DK4_LL_NONE;
+ ptr->ll_file_keep = DK4_LL_NONE;
+ ptr->ll_found = DK4_LL_IGNORE;
+ ptr->log_stderr_time = 1;
+ ptr->log_file_time = 1;
+ ptr->log_enabled = 0;
+ ptr->encoding =
+ ptr->enc_in_std =
+ ptr->enc_in_file =
+ ptr->enc_out_std =
+ ptr->enc_out_file = DK4_FILE_ENCODING_ASCII;
+ ptr->hvl_cmd = 0;
+ ptr->have_self_pref = 0;
+ ptr->fast_close = 0;
+ ptr->tmp_dir_used = 0;
+ $? "- dk4app_open_initialize"
+}
+
+
+
+/** Check command line arguments for --quiet option.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 1 if --quiet was found, 0 otherwise.
+*/
+static
+int
+dk4app_open_silence_check(int argc, dkChar **argv)
+{
+ size_t i; /* Traverse arguments list */
+ int back = 0; /* Function result */
+ $? "+ dk4app_open_silence_check"
+ for (i = 1; i < (size_t)argc; i++) {
+ if (0 == dk4str_cmp(argv[i], dk4app_open_kw[0])) {
+ back = 1;
+ }
+ } $? "- dk4app_open_silence_check %d", back
+ return back;
+}
+
+
+
+/** Find language, region, and encoding.
+ Set app->error_found if any error occures.
+ @param app Application structure to set up.
+*/
+static
+void
+dk4app_open_find_language_region(dk4_app_t *app, dk4_app_error_t *ae)
+{
+ dkChar lbuf[16];
+ dkChar rbuf[16];
+ int enc = DK4_ENCODING_ASCII;
+ int res;
+ $? "+ dk4app_open_find_language_region"
+ lbuf[0] = dkT('\0'); rbuf[0] = dkT('\0');
+ res = dk4loc_get_settings(
+ lbuf, DK4_SIZEOF(lbuf,dkChar),
+ rbuf, DK4_SIZEOF(rbuf,dkChar),
+ &enc, NULL
+ );
+ if (0 != res) { $? ". language and region obtained"
+ if (0 < dk4str_len(lbuf)) {
+ app->language = dk4str_dup(lbuf, NULL);
+ if (NULL == app->language) {
+ ae->error_found = E_MEMORY;
+ }
+ }
+ if (0 < dk4str_len(rbuf)) {
+ app->region = dk4str_dup(rbuf, NULL);
+ if (NULL == app->region) {
+ ae->error_found = E_MEMORY;
+ }
+ }
+ app->encoding =
+ app->enc_in_std =
+ app->enc_in_file =
+ app->enc_out_std =
+ app->enc_out_file = enc;
+#if DK4_CHAR_SIZE > 1
+ /* Multi-byte input (UTF-16, C32) typically has a BOM at start */
+ app->enc_in_std = DK4_FILE_ENCODING_ASCII;
+ app->enc_in_file = DK4_FILE_ENCODING_ASCII;
+#endif
+ } else {
+ ae->error_found = E_LOCALE;
+ } $? "- dk4app_open_find_language_region"
+}
+
+
+
+/** Report errors occured in initialization.
+ @param app Application structure to report errors for.
+*/
+static
+void
+dk4app_open_report_error(dk4_app_t *app, dk4_app_error_t *ae)
+{
+ /* !!!!! */
+ switch (ae->error_found) {
+ case E_LOCALE: {
+ } break;
+ case E_MEMORY: {
+ } break;
+ case E_EXEFILE: {
+ } break;
+ case E_EXECNAME_TOO_LONG: {
+ } break;
+ case E_NO_DIR_IN_EXENAME: {
+ } break;
+ case E_EMPTY_OPTION_SPEC: {
+ } break;
+ case E_OPTION_LONG_SPEC_MULT: {
+ } break;
+ case E_OPTION_SHORT_SPEC_MULT: {
+ } break;
+ case E_USER_NAME_NOT_FOUND: {
+ } break;
+ case E_USER_HOME_NOT_FOUND: {
+ } break;
+ case E_LOG_FILE_NAME: {
+ } break;
+ }
+}
+
+
+
+/** Check whether a dynamically allocated string is not NULL.
+ @param app Application to set up.
+ @param dirname String to test.
+*/
+static
+void
+dk4app_open_check_directory_name(dk4_app_error_t *ae, dkChar *dirname)
+{
+ $? "+ dk4app_open_check_directory_name"
+ if (NULL == dirname) {
+ if (0 == ae->error_found) { $? "! error"
+ ae->error_found = E_MEMORY;
+ }
+ } $? "- dk4app_open_check_directory_name"
+}
+
+
+
+/** The bin directory is the one compiled into the dk4inst
+ module, so retrieve etc, lib, share and var from the
+ dk4inst module too.
+ @param app Application structure to set up.
+*/
+static
+void
+dk4app_open_find_exec_from_inst(dk4_app_t *app, dk4_app_error_t *ae)
+{
+ $? "+ dk4app_open_find_exec_from_inst"
+ app->dir_etc = dk4str_dup(dk4inst_get_directory(1), NULL);
+ app->dir_share = dk4str_dup(dk4inst_get_directory(2), NULL);
+ app->dir_lib = dk4str_dup(dk4inst_get_directory(6), NULL);
+ app->dir_var = dk4str_dup(dk4inst_get_directory(3), NULL);
+ dk4app_open_check_directory_name(ae, app->dir_etc);
+ dk4app_open_check_directory_name(ae, app->dir_share);
+ dk4app_open_check_directory_name(ae, app->dir_lib);
+ dk4app_open_check_directory_name(ae, app->dir_var);
+ $? "- dk4app_open_find_exec_from_inst"
+}
+
+
+
+/** Create one new directory name replacing the final path component.
+ @param app Application structure to set up.
+ @param buf Buffer containing old directory name,
+ changed to the new directory name.
+ @param szbuf Size of buffer.
+ @param p1 Pointer to first position to modify in buffer.
+ @param nn New final component name.
+ @return String copy of new directory name in dynamically allocated
+ memory.
+*/
+static
+dkChar *
+dk4app_open_find_exec_replace_one(
+ dk4_app_t *app,
+ dk4_app_error_t *ae,
+ dkChar *buf,
+ size_t szbuf,
+ dkChar *p1,
+ dkChar const *nn
+)
+{
+ dkChar *back = NULL;
+ $? "+ dk4app_open_find_exec_replace_one"
+ *p1 = dkT('\0');
+ if (0 != dk4str_cat_s(buf, szbuf, nn, NULL)) {
+ back = dk4str_dup(buf, NULL);
+ if (NULL == back) {
+ if (0 == ae->error_found) {
+ ae->error_found = E_MEMORY;
+ }
+ }
+ } else {
+ if (0 == ae->error_found) {
+ ae->error_found = E_EXECNAME_TOO_LONG;
+ }
+ } $? "- dk4app_open_find_exec_replace_one"
+ return back;
+}
+
+
+
+/** Create directory names by replacing the final
+ bin or sbin component by etc, lib, share and var.
+ @param app Application structure to set up.
+ @param buf Buffer for directory name.
+ @param szbuf Size of buffer.
+ @param p1 Pointer to first character to modify.
+*/
+static
+void
+dk4app_open_find_exec_replace_final(
+ dk4_app_t *app,
+ dk4_app_error_t *ae,
+ dkChar *buf,
+ size_t szbuf,
+ dkChar *p1
+)
+{
+ $? "+ dk4app_open_find_exec_replace_final"
+ app->dir_etc = dk4app_open_find_exec_replace_one(
+ app, ae, buf, szbuf, p1, dk4app_open_kw[3]
+ );
+ app->dir_share = dk4app_open_find_exec_replace_one(
+ app, ae, buf, szbuf, p1, dk4app_open_kw[4]
+ );
+ app->dir_lib = dk4app_open_find_exec_replace_one(
+ app, ae, buf, szbuf, p1, dk4app_open_kw[5]
+ );
+ app->dir_var = dk4app_open_find_exec_replace_one(
+ app, ae, buf, szbuf, p1, dk4app_open_kw[6]
+ );
+ $? "- dk4app_open_find_exec_replace_final"
+}
+
+
+
+/** Check whether the path is below the libexec directory compiled
+ into the dk4inst module.
+ @param buf Buffer to check.
+ @return 1 if the path is below the libexec directory, 0 otherwise.
+*/
+static
+int
+dk4app_open_is_dkinst_libexec(dkChar *buf)
+{
+ size_t sz;
+ int back = 0;
+ $? "+ dk4app_open_is_dkinst_libexec"
+ sz = dk4str_len(dk4inst_get_directory(10));
+ if (0 < sz) {
+ if (dk4str_len(buf) > sz) {
+ if (buf[sz] == dk4app_filename_sep[0]) {
+ buf[sz] = dkT('\0');
+ if (0 == dk4str_pathcmp(buf, dk4inst_get_directory(10))) {
+ back = 1;
+ } else {
+ buf[sz] = dk4app_filename_sep[0];
+ }
+ }
+ }
+ } $? "- dk4app_open_is_dkinst_libexec %d", back
+ return back;
+}
+
+
+
+/** Check if there is any libexec component in the path.
+ Cut path to part before libexec if found.
+ @param buf Buffer containing the directory.
+ @param szbuf Buffer size.
+ @return 1 on success (libexec found), 0 otherwise.
+*/
+static
+int
+dk4app_open_is_any_libexec(dkChar *buf, size_t szbuf)
+{
+ dkChar mybuf[DK4_MAX_PATH];
+ dkChar *p1;
+ dkChar *p2;
+ int back = 0;
+ $? "+ dk4app_open_is_any_libexec"
+ if (0 != dk4str_cpy_s(mybuf, DK4_SIZEOF(mybuf,dkChar), buf, NULL)) {
+ p1 = dk4str_rchr(mybuf, dk4app_filename_sep[0]);
+ while ((0 == back) && (NULL != p1)) {
+ p2 = p1;
+ p2++;
+ if (0 == dk4str_pathcmp(p2, dk4app_open_kw[7])) {
+ back = 1;
+ *p1 = dkT('\0');
+ dk4str_cpy_s(buf, szbuf, mybuf, NULL);
+ p1 = NULL;
+ } else {
+ *p1 = dkT('\0');
+ p1 = dk4str_rchr(mybuf, dk4app_filename_sep[0]);
+ }
+ }
+ } $? "- dk4app_open_is_any_libexec %d", back
+ return back;
+}
+
+
+
+static
+void
+dk4app_open_find_copy_bindir(dk4_app_t *app, dk4_app_error_t *ae)
+{
+ $? "+ dk4app_open_find_copy_bindir"
+ if (NULL != app->dir_bin) {
+ app->dir_etc = dk4str_dup(app->dir_bin, NULL);
+ app->dir_share = dk4str_dup(app->dir_bin, NULL);
+ app->dir_lib = dk4str_dup(app->dir_bin, NULL);
+ app->dir_var = dk4str_dup(app->dir_bin, NULL);
+ }
+ dk4app_open_check_directory_name(ae, app->dir_etc);
+ dk4app_open_check_directory_name(ae, app->dir_share);
+ dk4app_open_check_directory_name(ae, app->dir_lib);
+ dk4app_open_check_directory_name(ae, app->dir_var);
+ $? "- dk4app_open_find_copy_bindir"
+}
+
+
+
+/** Find executable file for process and derive
+ program name and directories from it.
+ @param app Application structure to set up.
+ @param arg0 First command line word.
+*/
+static
+void
+dk4app_open_find_executable(
+ dk4_app_t *app,
+ dk4_app_error_t *ae,
+ const dkChar *arg0
+)
+{
+ dkChar buf[DK4_MAX_PATH];
+ dkChar *p1;
+ size_t const szbuf = DK4_SIZEOF(buf,dkChar);
+ $? "+ dk4app_open_find_executable"
+ if (0 != dk4execpath(buf, szbuf, arg0, NULL)) {
+ p1 = dk4str_rchr(buf, dk4app_filename_sep[0]);
+ if (NULL != p1) {
+ *(p1++) = dkT('\0');
+ if (0 < dk4str_len(buf)) {
+ /* Save program name */
+ app->prog_name = dk4str_dup(p1, NULL);
+ if (NULL == app->prog_name) {
+ ae->error_found = E_MEMORY;
+ } else {
+#if DK4_ON_WINDOWS
+ /* Remove .exe suffix */
+ p1 = dk4path_get_suffix(app->prog_name, NULL);
+ if (NULL != p1) {
+ if (-1 < dk4str_array_index(dk4app_exe_file_suffixes, p1, 0)) {
+ *p1 = dkT('\0');
+ }
+ }
+#endif
+ }
+ $? ". program name: \"%!ds\"", TR_DKSTR(app->prog_name)
+ /* Save bindir name */
+ app->dir_bin = dk4str_dup(buf, NULL);
+ $? ". binary dir: \"%!ds\"", TR_DKSTR(app->dir_bin)
+ if (NULL == app->dir_bin) { ae->error_found = E_MEMORY; }
+ /* Find other directories */
+ if (0 == dk4str_pathcmp(buf, dk4inst_get_directory(4))) {
+ $? ". binary dir as configured (bin)"
+ /* In .../bin, use directories from dk4inst */
+ dk4app_open_find_exec_from_inst(app, ae);
+ } else {
+ if (0 == dk4str_pathcmp(buf, dk4inst_get_directory(5))) {
+ $? ". binary dir as configured (sbin)"
+ /* In .../sbin, use directories from dk4inst */
+ dk4app_open_find_exec_from_inst(app, ae);
+ } else {
+ if (dk4app_open_is_dkinst_libexec(buf)) {
+ $? ". binary dir as configured (libexec)"
+ /* In .../libexec/..., use directories from dk4inst */
+ dk4app_open_find_exec_from_inst(app, ae);
+ } else {
+ p1 = dk4str_rchr(buf, dk4app_filename_sep[0]);
+ if (NULL != p1) {
+ p1++;
+ if (0 == dk4str_pathcmp(p1, dk4app_open_kw[1])) {
+ $? ". binary dir ends in bin"
+ /* Replace final path component by etc, lib... */
+ dk4app_open_find_exec_replace_final(
+ app, ae, buf, szbuf, p1
+ );
+ } else {
+ if (0 == dk4str_pathcmp(p1, dk4app_open_kw[2])) {
+ $? ". binary dir ends in sbin"
+ /* Replace final path component by etc, lib... */
+ dk4app_open_find_exec_replace_final(
+ app, ae, buf, szbuf, p1
+ );
+ } else {
+ if (dk4app_open_is_any_libexec(buf,szbuf)) {
+ /*
+ We can securely append the separator and the
+ finalizer as the dk4app_open_is_any_libexec()
+ function cutted a libexec string from the path.
+ */
+ $? ". binary dir contains a libexec"
+ p1 = buf;
+ while(dkT('\0') != *p1) { p1++; }
+ *(p1++) = dk4app_filename_sep[0];
+ *p1 = dkT('\0');
+ dk4app_open_find_exec_replace_final(
+ app, ae, buf, szbuf, p1
+ );
+ } else { $? ". use binary dir"
+ dk4app_open_find_copy_bindir(app, ae);
+ }
+ }
+ }
+ } else { $? ". dir path is one component"
+ dk4app_open_find_copy_bindir(app, ae);
+ }
+ }
+ }
+ }
+ $? ". etc = \"%!ds\"", TR_DKSTR(app->dir_etc)
+ $? ". share = \"%!ds\"", TR_DKSTR(app->dir_share)
+ $? ". lib = \"%!ds\"", TR_DKSTR(app->dir_lib)
+ $? ". var = \"%!ds\"", TR_DKSTR(app->dir_var)
+ } else { $? "! directory length is 0"
+ ae->error_found = E_EXECNAME_TOO_LONG;
+ }
+ } else { $? "! no dir component in executable"
+ ae->error_found = E_NO_DIR_IN_EXENAME;
+ }
+ } else { $? "! executable not found"
+ ae->error_found = E_EXEFILE;
+ }
+ $? "- dk4app_open_find_executable"
+}
+
+
+
+static
+void
+dk4app_close_prefeferences(dk4_sto_t *s, dk4_sto_it_t *i)
+{
+ dk4_pref_t *prefptr;
+ if (NULL != i) {
+ dk4sto_it_reset(i);
+ do {
+ prefptr = (dk4_pref_t *)dk4sto_it_next(i);
+ if (NULL != prefptr) {
+ dk4pref_close(prefptr);
+ }
+ } while(NULL != prefptr);
+ dk4sto_it_close(i);
+ }
+ if (NULL != s) {
+ dk4sto_close(s);
+ }
+}
+
+
+
+int
+dk4app_close(dk4_app_t *app)
+{
+ dk4_option_t *optptr;
+ dk4_string_table_t *ptrstt;
+ int back = 0;
+ $? "+ dk4app_close PTR=%d", TR_IPTR(app)
+ if (NULL != app) {
+ /* Remove temporary files */
+ if (0 == app->fast_close) {
+ if ((NULL != app->dir_tmp) && (0 != app->tmp_dir_used)) {
+ (void)dk4app_del_tree(app->dir_tmp, app);
+ }
+ }
+#if 0
+ /* Write preferences back to file */
+ if ((0 != app->have_self_pref) && (0 == app->fast_close)) {
+ /*
+ Originally intended: Write self-set preferences back to file.
+ 2015-04-17: Design decision not to write back.
+ Preferences are read-only in version 4.
+ For GUI programs there are mechanisms in wxWidgets
+ to save configuration changes.
+ */
+ }
+#endif
+ /* The base and debug messages are read from string tables, so the
+ arrays are freed when freeing the string tables.
+ */
+ app->msg_base = NULL;
+ app->msg_debug = NULL;
+ app->source_file_name = NULL;
+ back = 1;
+ /* Disable logging */
+ app->log_enabled = 0;
+
+ /* Delete log file unless there is a reason to keep it */
+ if (NULL != app->log_file_name) {
+ if ((app->ll_found <= app->ll_file) && (0 != app->have_file_opened)) {
+ if (app->ll_file_keep < app->ll_found) {
+ (void)dk4delete_file(app->log_file_name, NULL);
+ }
+ }
+ }
+ /* Release memory for log file */
+ dk4mem_release(app->log_file_name);
+ /* Release memory for directories */
+ app->help_text = NULL;
+ app->lic_text = NULL;
+ dk4mem_release(app->dir_tmp);
+ dk4mem_release(app->dir_var);
+ dk4mem_release(app->dir_lib);
+ dk4mem_release(app->dir_share);
+ dk4mem_release(app->dir_etc);
+ dk4mem_release(app->dir_bin);
+ dk4mem_release(app->group_name);
+ dk4mem_release(app->prog_name);
+ /* Release memory for language and region */
+ dk4mem_release(app->region);
+ dk4mem_release(app->language);
+ dk4mem_release(app->vers_text);
+ dk4mem_release(app->help_file_name);
+ dk4mem_release(app->host_name);
+ dk4mem_release(app->user_home);
+ dk4mem_release(app->user_name);
+#if TRACE_DEBUG
+ {
+ int i;
+ if ((0 < app->my_argc) && (NULL != app->my_argv)) {
+ for (i = 0; i < app->my_argc; i++) {
+ $? ". my_argv[%d] = \"%!ds\"", i, TR_DKSTR((app->my_argv)[i])
+ }
+ }
+ }
+#endif
+ dk4mem_release(app->my_argv);
+ /* Release string tables */
+ if (NULL != app->s_stt) {
+ if (NULL != app->i_stt) {
+ dk4sto_it_reset(app->i_stt);
+ do {
+ ptrstt = (dk4_string_table_t *)dk4sto_it_next(app->i_stt);
+ if (NULL != ptrstt) {
+ dk4stt_close(ptrstt);
+ }
+ } while (NULL != ptrstt);
+ dk4sto_it_close(app->i_stt);
+ }
+ dk4sto_close(app->s_stt);
+ }
+ app->s_stt = NULL;
+ app->i_stt = NULL;
+ /*
+ Release options
+ All options in s_opt_long and s_opt_short are also in s_opt_all.
+ They are deleted later, so we can simply close the storages here.
+ */
+ if (NULL != app->i_opt_long) { dk4sto_it_close(app->i_opt_long); }
+ app->i_opt_long = NULL;
+ if (NULL != app->i_opt_short) { dk4sto_it_close(app->i_opt_short); }
+ app->i_opt_short = NULL;
+ if (NULL != app->s_opt_long) { dk4sto_close(app->s_opt_long); }
+ app->s_opt_long = NULL;
+ if (NULL != app->s_opt_short) { dk4sto_close(app->s_opt_short); }
+ app->s_opt_short = NULL;
+ dk4app_close_prefeferences(app->s_pref_sys, app->i_pref_sys);
+ dk4app_close_prefeferences(app->s_pref_user, app->i_pref_user);
+ dk4app_close_prefeferences(app->s_pref_cmd, app->i_pref_cmd);
+ dk4app_close_prefeferences(app->s_pref_self, app->i_pref_self);
+ app->s_pref_self = NULL;
+ app->s_pref_cmd = NULL;
+ app->s_pref_user = NULL;
+ app->s_pref_sys = NULL;
+ app->i_pref_self = NULL;
+ app->i_pref_cmd = NULL;
+ app->i_pref_user = NULL;
+ app->i_pref_sys = NULL;
+ if (NULL != app->i_opt_all) {
+ dk4sto_it_reset(app->i_opt_all);
+ do {
+ optptr = (dk4_option_t *)dk4sto_it_next(app->i_opt_all);
+ if (NULL != optptr) {
+ dk4opt_close(optptr);
+ }
+ } while(NULL != optptr) ;
+ dk4sto_it_close(app->i_opt_all);
+ }
+ app->i_opt_all = NULL;
+ if (NULL != app->s_opt_all) { dk4sto_close(app->s_opt_all); }
+ app->s_opt_all = NULL;
+ /* Release memory for app structure itself */
+ dk4mem_free(app);
+ } $? "- dk4app_close %d", back
+ return back;
+}
+
+
+
+/** Process the options specification.
+ @param app Application to set up.
+ @param ae Application error structure.
+ @param optspec The option specification.
+ @param szoptspec Size of the optspec array.
+*/
+static
+void
+dk4app_open_process_optspec(
+ dk4_app_t *app,
+ dk4_app_error_t *ae,
+ const dk4_option_specification_t *optspec,
+ size_t szoptspec
+)
+{
+ dk4_option_t *optptr;
+ $? "+ dk4app_open_process_optspec"
+ while(szoptspec--) {
+ if ((NULL != optspec->longopt) || (dkT('\0') != optspec->c)) {
+ optptr = dk4opt_open(optspec, NULL);
+ if (NULL != optptr) {
+ if (0 != dk4sto_add(app->s_opt_all, optptr, NULL)) {
+ if (NULL != optspec->longopt) {
+ if (NULL == dk4sto_it_find_like(app->i_opt_long,optspec->longopt,3))
+ {
+ if (0 == dk4sto_add(app->s_opt_long, optptr, NULL)) {
+ if (0 == ae->error_found) { ae->error_found = E_MEMORY; }
+ szoptspec = 0;
+ }
+ }
+ else
+ { $? "! already exists"
+ if (0 == ae->error_found) {
+ ae->error_found = E_OPTION_LONG_SPEC_MULT;
+ ae->longopt = optspec->longopt;
+ }
+ szoptspec = 0;
+ }
+ }
+ if (dkT('\0') != optspec->c) {
+ if (NULL == dk4sto_it_find_like(app->i_opt_short,&(optspec->c),1))
+ {
+ if (0 == dk4sto_add(app->s_opt_short, optptr, NULL)) {
+ if (0 == ae->error_found) { ae->error_found = E_MEMORY; }
+ szoptspec = 0;
+ }
+ }
+ else
+ { $? "! already exists"
+ if (0 == ae->error_found) {
+ ae->error_found = E_OPTION_SHORT_SPEC_MULT;
+ ae->longopt = optspec->longopt;
+ }
+ szoptspec = 0;
+ }
+ }
+ } else { $? "! memory"
+ if (0 == ae->error_found) { ae->error_found = E_MEMORY; }
+ szoptspec = 0;
+ dk4opt_close(optptr); optptr = NULL;
+ }
+ } else { $? "! memory"
+ if (0 == ae->error_found) { ae->error_found = E_MEMORY; }
+ szoptspec = 0;
+ }
+ } else { $? "! invalid spec"
+ if (0 == ae->error_found) { ae->error_found = E_EMPTY_OPTION_SPEC; }
+ szoptspec = 0;
+ }
+ optspec++;
+ } $? "- dk4app_open_process_optspec"
+}
+
+
+
+/** Create and prepare the storage containers for command line options.
+ @param app Application to set up.
+ @param ae Application error structure.
+ @param optspec The option specification.
+ @param szoptspec Size of the optspec array.
+*/
+static
+void
+dk4app_open_create_options_storages(
+ dk4_app_t *app,
+ dk4_app_error_t *ae,
+ const dk4_option_specification_t *optspec,
+ size_t szoptspec
+)
+{
+ $? "+ dk4app_open_create_options_storages"
+ if ((NULL != optspec) && (0 < szoptspec)) {
+ app->s_opt_all = dk4sto_open(NULL);
+ if (NULL != app->s_opt_all) {
+ app->s_opt_long = dk4sto_open(NULL);
+ if (NULL != app->s_opt_long) {
+ dk4sto_set_comp(app->s_opt_long, dk4option_compare, 2);
+ app->s_opt_short = dk4sto_open(NULL);
+ if (NULL != app->s_opt_short) {
+ dk4sto_set_comp(app->s_opt_short, dk4option_compare, 0);
+ app->i_opt_all = dk4sto_it_open(app->s_opt_all, NULL);
+ if (NULL != app->i_opt_all) {
+ app->i_opt_long = dk4sto_it_open(app->s_opt_long, NULL);
+ if (NULL != app->i_opt_long) {
+ app->i_opt_short = dk4sto_it_open(app->s_opt_short, NULL);
+ if (NULL != app->i_opt_short) {
+ dk4app_open_process_optspec(app, ae, optspec, szoptspec);
+ } else { $? "! memory"
+ ae->error_found = E_MEMORY;
+ }
+ } else { $? "! memory"
+ ae->error_found = E_MEMORY;
+ }
+ } else { $? "! memory"
+ ae->error_found = E_MEMORY;
+ }
+ } else { $? "! memory"
+ ae->error_found = E_MEMORY;
+ }
+ } else { $? "! memory"
+ ae->error_found = E_MEMORY;
+ }
+ } else { $? "! memory"
+ ae->error_found = E_MEMORY;
+ }
+ } $? "- dk4app_open_create_options_storages"
+}
+
+
+
+/** Create storage containers for preferences.
+ @param app Application to set up.
+ @param ae Error storage for setup.
+*/
+static
+void
+dk4app_open_create_pref_storages(
+ dk4_app_t *app,
+ dk4_app_error_t *ae
+)
+{
+ app->s_pref_sys = dk4sto_open(NULL);
+ if (NULL != app->s_pref_sys) {
+ app->s_pref_user = dk4sto_open(NULL);
+ if (NULL != app->s_pref_user) {
+ app->s_pref_cmd = dk4sto_open(NULL);
+ if (NULL != app->s_pref_cmd) {
+ app->s_pref_self = dk4sto_open(NULL);
+ if (NULL != app->s_pref_self) {
+ dk4sto_set_comp(app->s_pref_sys, dk4pref_compare, 0);
+ dk4sto_set_comp(app->s_pref_user, dk4pref_compare, 0);
+ dk4sto_set_comp(app->s_pref_cmd, dk4pref_compare, 0);
+ dk4sto_set_comp(app->s_pref_self, dk4pref_compare, 0);
+ app->i_pref_sys = dk4sto_it_open(app->s_pref_sys, NULL);
+ app->i_pref_user = dk4sto_it_open(app->s_pref_user, NULL);
+ app->i_pref_cmd = dk4sto_it_open(app->s_pref_cmd, NULL);
+ app->i_pref_self = dk4sto_it_open(app->s_pref_self, NULL);
+ if ((NULL == app->i_pref_sys) || (NULL == app->i_pref_user)) {
+ ae->error_found = E_MEMORY;
+ }
+ if ((NULL == app->i_pref_cmd) || (NULL == app->i_pref_self)) {
+ ae->error_found = E_MEMORY;
+ }
+ } else {
+ ae->error_found = E_MEMORY;
+ }
+ } else {
+ ae->error_found = E_MEMORY;
+ }
+ } else {
+ ae->error_found = E_MEMORY;
+ }
+ } else {
+ ae->error_found = E_MEMORY;
+ }
+}
+
+
+
+/** Create storage container for string tables.
+ @param app Application to set up.
+ @param ae Error storage for setup.
+*/
+static
+void
+dk4app_open_create_stt_storage(
+ dk4_app_t *app,
+ dk4_app_error_t *ae
+)
+{
+ app->s_stt = dk4sto_open(NULL);
+ if (NULL != app->s_stt) {
+ dk4sto_set_comp(app->s_stt, dk4stt_compare, 0);
+ app->i_stt = dk4sto_it_open(app->s_stt, NULL);
+ if (NULL == app->i_stt) {
+ ae->error_found = E_MEMORY;
+ }
+ } else {
+ ae->error_found = E_MEMORY;
+ }
+}
+
+
+
+/** Attempt to find users login name and home directory.
+ On Linux/Unix the effective user name and home directory is searched.
+ @param app Application to set up.
+ @param ae Application opening error structure.
+*/
+static
+void
+dk4app_open_find_user_name_and_home(dk4_app_t *app, dk4_app_error_t *ae)
+{
+ dkChar buf[DK4_MAX_PATH];
+ dk4_er_t er;
+ $? "+ dk4app_open_find_user_name_and_home"
+ dk4error_init(&er);
+ if (0 != dk4user_get_logname(buf, DK4_SIZEOF(buf,dkChar), 1, &er)) {
+ app->user_name = dk4str_dup(buf, &er);
+ if (NULL != app->user_name) {
+ if (0 != dk4user_get_homedir(buf, DK4_SIZEOF(buf,dkChar), 1, &er)) {
+ app->user_home = dk4str_dup(buf, &er);
+ if (NULL == app->user_home) {
+ ae->error_found = E_MEMORY;
+ }
+ } else {
+ ae->error_found = E_USER_HOME_NOT_FOUND;
+ }
+ } else {
+ ae->error_found = E_MEMORY;
+ }
+ } else {
+ ae->error_found = E_USER_NAME_NOT_FOUND;
+ }
+ $? ". user name = \"%!ds\"", TR_DKSTR(app->user_name)
+ $? ". user home = \"%!ds\"", TR_DKSTR(app->user_home)
+ $? "- dk4app_open_find_user_name_and_home"
+}
+
+
+
+/** Preference reader structure.
+*/
+typedef struct {
+ dk4_app_t *app; /**< Application to set up. */
+ dk4_app_error_t *ae; /**< Application error structure. */
+ dk4_sto_t *st; /**< Storage for preferences. */
+ dk4_sto_it_t *it; /**< Storage iterator. */
+ int insc; /**< Flag: In current scope. */
+ int lasc; /**< Flag: Previous line was scope line. */
+ int co3; /**< Flag: DK tools 3 compatibility. */
+} dk4_app_pref_rd_t;
+
+
+
+/** Initialize preference reader structure for start of file.
+ @param ptr Preference reader structure.
+*/
+static
+void
+dk4app_open_pref_reader_init_for_one_file(dk4_app_pref_rd_t *ptr)
+{
+ ptr->insc = 1;
+ ptr->lasc = 0;
+ ptr->co3 = 0;
+}
+
+
+
+/** Check one scope line entry.
+ @param app Application.
+ @param ae Application open error structure.
+ @param pn Pointer to entry name.
+ @param pv Pointer to entry value.
+ @return 1 if condition is true, 0 otherwise.
+*/
+static
+int
+dk4app_open_check_one_scope_entry(
+ dk4_app_t *app,
+ dk4_app_error_t *ae,
+ const dkChar *pn,
+ const dkChar *pv
+)
+{
+ int back = 0;
+ $? "+ dk4app_open_check_one_scope_entry \"%!ds\"=\"%!ds\"", TR_DKSTR(pn), TR_DKSTR(pv)
+ switch (dk4str_array_index(dk4app_open_scope_names, pn, 0)) {
+ case 0: {
+ if ((NULL != pv) && (NULL != app->user_name)) {
+ $? " user \"%!ds\" == \"%!ds\"", pv, app->user_name
+#if DK4_HAVE_CASE_INSENSITIVE_USERNAMES
+ if (0 == dk4str_casecmp(pv, app->user_name))
+#else
+ if (0 == dk4str_cmp(pv, app->user_name))
+#endif
+ {
+ back = 1;
+ }
+ else
+ {
+ if (0 == dk4str_cmp(pv, dk4app_open_kw[15])) {
+ back = 1;
+ }
+ }
+ }
+ } break;
+ case 1: {
+ if ((NULL != pv) && (NULL != app->prog_name)) {
+ $? ". prog \"%!ds\" == \"%!ds\"", pv, app->prog_name
+#if DK4_HAVE_CASE_INSENSITIVE_PATHNAMES
+ if (0 == dk4str_casecmp(pv, app->prog_name))
+#else
+ if (0 == dk4str_cmp(pv, app->prog_name))
+#endif
+ {
+ back = 1;
+ }
+ else
+ {
+ if (0 == dk4str_cmp(pv, dk4app_open_kw[15])) {
+ back = 1;
+ }
+ }
+ }
+ } break;
+ case 2: { $? ". application group"
+ if ((NULL != pv) && (NULL != app->group_name)) {
+ $? ". prog group \"%!ds\" == \"%!ds\"", pv, app->group_name
+#if DK4_HAVE_CASE_INSENSITIVE_PATHNAMES
+ if (0 == dk4str_casecmp(pv, app->group_name))
+#else
+ if (0 == dk4str_cmp(pv, app->group_name))
+#endif
+ {
+ back = 1;
+ }
+ else
+ {
+ if (0 == dk4str_cmp(pv, dk4app_open_kw[15])) {
+ back = 1;
+ }
+ }
+ }
+ } break;
+ case 3: { $? ". host name"
+ if ((NULL != pv) && (NULL != app->host_name)) {
+ $? ". host \"%!ds\" == \"%!ds\"", pv, app->host_name
+ if (0 == dk4str_casecmp(pv, app->host_name)) {
+ back = 1;
+ } else {
+ if (0 == dk4str_cmp(pv, dk4app_open_kw[15])) {
+ back = 1;
+ }
+ }
+ }
+ } break;
+ case 4: { $? ". test: on Windows"
+ if (NULL != pv) {
+#if DK4_ON_WINDOWS
+ if (0 != dk4str_is_on(pv)) {
+ back = 1;
+ }
+#else
+ if (0 == dk4str_is_on(pv)) {
+ back = 1;
+ }
+#endif
+ } else {
+#if DK4_ON_WINDOWS
+ back = 1;
+#endif
+ }
+ } break;
+ case 5: { $? ". test: non-Windows"
+ if (NULL != pv) {
+#if DK4_ON_WINDOWS
+ if (0 == dk4str_is_on(pv)) {
+ back = 1;
+ }
+#else
+ if (0 != dk4str_is_on(pv)) {
+ back = 1;
+ }
+#endif
+ } else {
+#if DK4_ON_WINDOWS
+ back = 0;
+#else
+ back = 1;
+#endif
+ }
+ } break;
+ case 6 : { $? ". language"
+ if ((NULL != pv) && (NULL != app->language)) {
+ if (0 == dk4str_casecmp(pv, app->language)) {
+ back =1;
+ } else {
+ if (0 == dk4str_cmp(pv, dk4app_open_kw[15])) {
+ back = 1;
+ }
+ }
+ }
+ } break;
+ case 7 : { $? ". region"
+ if ((NULL != pv) && (NULL != app->region)) {
+ if (0 == dk4str_casecmp(pv, app->region)) {
+ back =1;
+ } else {
+ if (0 == dk4str_cmp(pv, dk4app_open_kw[15])) {
+ back = 1;
+ }
+ }
+ }
+ } break;
+ default: { $? ". unknown name"
+ if (0 == dk4str_len(pn)) { $? ". empty name"
+ back = 1;
+ }
+ } break;
+ } $? "- dk4app_open_check_one_scope_entry %d", back
+ return back;
+}
+
+
+
+/** Add one preference to storages.
+ @param app Application to configure.
+ @param ae Application open error structure.
+ @param st Storage.
+ @param it Iterator for storage.
+ @param pn Preference name.
+ @param pv Preference value.
+*/
+static
+void
+dk4app_open_add_preference(
+ dk4_app_t *app,
+ dk4_app_error_t *ae,
+ dk4_sto_t *st,
+ dk4_sto_it_t *it,
+ const dkChar *pn,
+ const dkChar *pv
+)
+{
+ dk4_pref_t *prefptr;
+ dkChar *npv;
+ $? "+ dk4app_open_add_preference \"%!ds\"=\"%!ds\"", TR_DKSTR(pn), TR_DKSTR(pv)
+ prefptr = dk4sto_it_find_like(it, pn, 1);
+ if (NULL != prefptr) { $? ". replace existing value"
+ npv = dk4str_dup(pv, NULL);
+ if (NULL != npv) {
+#if 0
+ dk4mem_release(prefptr->value);
+#endif
+ /* 2016-12-10 Sanitize memory before releasing it.
+ */
+ dk4str_release_sanitized(prefptr->value);
+ prefptr->value = npv;
+ } else {
+ if (0 == ae->error_found) { ae->error_found = E_MEMORY; }
+ }
+ } else { $? ". add new value"
+ prefptr = dk4pref_open(pn, pv, NULL);
+ if (NULL != prefptr) {
+ if (0 == dk4sto_add(st, (void *)prefptr, NULL)) {
+ dk4pref_close(prefptr);
+ if (0 == ae->error_found) { ae->error_found = E_MEMORY; }
+ }
+ } else {
+ if (0 == ae->error_found) { ae->error_found = E_MEMORY; }
+ }
+ }
+ dk4app_pref_apply(app, ae, pn, pv);
+ $? "- dk4app_open_add_preference"
+}
+
+
+
+/** Modify a preference value from DK tools 3 to 4 syntax.
+ Change "/print/ps/level" to "print.ps.level".
+ @param Preference name pointer.
+*/
+static
+void
+dk4app_open_modify_prefname_3_to_4(dkChar *pn)
+{
+ if (NULL != pn) {
+ if (dkT('/') == *pn) {
+ dk4str_cpy_to_left(pn, &(pn[1]));
+ while (dkT('\0') != *pn) {
+ if (dkT('/') == *pn) {
+ *pn = dkT('.');
+ }
+ pn++;
+ }
+ }
+ }
+}
+
+
+
+/** Process one input line.
+ @param obj Preferences reader object.
+ @param line Current line to process.
+ @param lineno Line number.
+ @param erp Error report, may be NULL.
+ @return
+ DK4_TSP_RES_OK if processing succeeded,
+ DK4_TSP_RES_ERROR on errors (can continue),
+ DK4_TSP_RES_FATAL on fatal errors (can not continue).
+
+*/
+static
+int
+dk4app_open_pref_line_handler(
+ void *obj,
+ dkChar *line,
+ dk4_um_t lineno,
+ dk4_er_t *erp
+)
+{
+ dkChar *p1; /* Name text */
+ dkChar *p2; /* Next text */
+ dkChar *pv; /* Value text */
+ dk4_app_pref_rd_t *ptr; /* Reader structure */
+ int back = DK4_TSP_RES_OK; /* Function result */
+ int isneg = 0; /* Flag: Exclude scope */
+ int ok; /* Flag: No test failed yet */
+ $? "+ dk4app_open_pref_line_handler \"%!ds\"", line
+ dk4str_delnl(line);
+ ptr = (dk4_app_pref_rd_t *)obj;
+ p1 = dk4str_start(line, NULL);
+ if (NULL != p1) {
+ if (dkT('#') != *p1) { $? ". data line"
+ if (dkT('[' == *p1)) { $? ". scope line"
+ if (0 == ptr->lasc) { $? ". start of scope section"
+ ptr->insc = 0;
+ } else { $? ". continued scope section"
+ }
+ p2 = dk4str_chr(p1, dkT(']'));
+ if (NULL != p2) { $? ". end of scope found"
+ *p2 = dkT('\0');
+ }
+ p1++;
+ if (dkT('-') == *p1) { $? ". negative scope line"
+ isneg = 1;
+ p1++;
+ }
+ ok = 1;
+ while (NULL != p1) {
+ p2 = dk4str_chr(p1, dkT(','));
+ if (NULL != p2) { *(p2++) = dkT('\0'); p2 = dk4str_start(p2, NULL); }
+ pv = dk4str_chr(p1, dkT('='));
+ if (NULL != pv) { *(pv++) = dkT('\0'); pv = dk4str_start(pv, NULL); }
+ dk4str_normalize(p1, NULL);
+ if (NULL != pv) { dk4str_rtwh(pv, NULL); }
+ if (0 == dk4app_open_check_one_scope_entry(ptr->app,ptr->ae,p1,pv)) {
+ ok = 0;
+ }
+ p1 = p2;
+ }
+ if (1 == ok) { $? ". no test failed"
+ if (0 != isneg) {
+ ptr->insc = 0; $? ". turn scope off"
+ } else {
+ ptr->insc = 1; $? ". turn scope on"
+ }
+ } else { $? ". there were failed tests"
+ }
+ ptr->lasc = 1;
+ } else { $? ". attribute line"
+ if (ptr->insc) { $? ". in scope, process line"
+ p2 = dk4str_chr(p1, dkT('='));
+ if (NULL != p2) { *(p2++) = dkT('\0'); p2 = dk4str_start(p2, NULL); }
+ if ((NULL != p1) && (NULL != p2)) {
+ dk4str_normalize(p1, NULL);
+ dk4str_rtwh(p2, NULL);
+ if (0 < ptr->co3) { $? ". compatibility mode"
+ dk4app_open_modify_prefname_3_to_4(p1);
+ $? ". preference name now \"%!ds\"", p1
+ } else { $? ". no compatibility mode"
+ }
+ dk4app_open_add_preference(ptr->app,ptr->ae,ptr->st,ptr->it,p1,p2);
+ }
+ } else { $? ". out of scope, ignore line"
+ }
+ ptr->lasc = 0;
+ }
+ } else { $? ". comment line, ignore"
+ }
+ } else { $? ". empty line, ignore"
+ } $? "- dk4app_open_pref_line_handler %d", back
+ return back;
+}
+
+
+
+/** Read all preferences files in increasing order.
+ Cumulative operation, redefinitions possible.
+ @param app Application to configure.
+ @param ae Application opening error structure.
+*/
+static
+void
+dk4app_open_read_preference_files(dk4_app_t *app, dk4_app_error_t *ae)
+{
+ char ib[4096]; /* Input buffer */
+ dkChar il[1024]; /* Input line */
+ dkChar fnb[DK4_MAX_PATH]; /* File name buffer */
+ dk4_tspdk_t tsp; /* Text stream processor */
+ dk4_er_t er; /* Error report */
+ dk4_app_pref_rd_t rdobj; /* Reader object */
+ dk4_stream_t *istrm; /* Input stream */
+ size_t rb; /* Bytes read from stream */
+ int pn; /* Pass number */
+ int res; /* Result from path construct */
+ int cc; /* Flag: Can continue */
+ $? "+ dk4app_open_read_preference_files"
+ rdobj.app = app;
+ rdobj.ae = ae;
+ for (pn = 0; ((0 == ae->error_found) && (pn <= DK4_FS_CONF_MAX)); pn++) {
+ if (DK4_FS_CONF_SYS_MAX >= pn) {
+ rdobj.st = app->s_pref_sys;
+ rdobj.it = app->i_pref_sys;
+ } else {
+ rdobj.st = app->s_pref_user;
+ rdobj.it = app->i_pref_user;
+ }
+#if DK4_HAVE_COMPATDKTOOLS3
+ dk4error_init(&er);
+ res = dk4fs_config_compat_one(
+ fnb, DK4_SIZEOF(fnb,dkChar), dk4app_open_kw[14],
+ app->dir_share, app->dir_etc, app->user_home,
+ app->prog_name, app->group_name, pn, 1, 1, &er
+ );
+ if (0 != res) {
+ $? ". file = \"%!ds\"", fnb
+ istrm = dk4stream_open_file_reader(fnb, &er);
+ if (NULL != istrm) { $? ". stream opened"
+ dk4app_open_pref_reader_init_for_one_file(&rdobj);
+ rdobj.co3 = 1;
+ res = dk4tspdk_setup_line(
+ &tsp, &rdobj, dk4app_open_pref_line_handler,
+ il, DK4_SIZEOF(il,dkChar),
+ app->encoding, app->enc_in_file, &er
+ );
+ if (0 != res) { $? ". line processor initialized"
+ res = DK4_TSP_RES_OK;
+ do {
+ cc = 0;
+ rb = sizeof(ib);
+ if (0 != dk4stream_read(ib, &rb, istrm, &er)) {
+ if (0 < rb) {
+ cc = 1;
+ res = dk4tspdk_add_bytes(&tsp, (const unsigned char *)ib, rb);
+ if (DK4_TSP_RES_FATAL == res) {
+ cc = 0;
+ }
+ }
+ }
+ } while(0 != cc);
+ if (DK4_TSP_RES_FATAL != res) {
+#if VERSION_BEFORE_20150821
+ res = dk4tspdk_finish(&tsp);
+#else
+ dk4tspdk_finish(&tsp);
+#endif
+ }
+ } else { $? "! failed to initialize line proc"
+ }
+ dk4stream_close(istrm, NULL);
+ } else { $? "! failed to open stream"
+ if (0 == ae->error_found) { ae->error_found = E_PREF_FILE_OPEN; }
+ }
+ }
+#endif
+ dk4error_init(&er);
+ res = dk4fs_config_one(
+ fnb, DK4_SIZEOF(fnb,dkChar), dk4app_open_kw[8],
+ app->dir_share, app->dir_etc, app->user_home,
+ app->prog_name, app->group_name, pn, 1, &er
+ );
+ if (0 != res) {
+ $? ". file = \"%!ds\"", fnb
+ istrm = dk4stream_open_file_reader(fnb, &er);
+ if (NULL != istrm) { $? ". stream opened"
+ dk4app_open_pref_reader_init_for_one_file(&rdobj);
+ res = dk4tspdk_setup_line(
+ &tsp, &rdobj, dk4app_open_pref_line_handler,
+ il, DK4_SIZEOF(il,dkChar),
+ app->encoding, app->enc_in_file, &er
+ );
+ if (0 != res) { $? ". line processor initialized"
+ res = DK4_TSP_RES_OK;
+ do {
+ cc = 0;
+ rb = sizeof(ib);
+ if (0 != dk4stream_read(ib, &rb, istrm, &er)) {
+ if (0 < rb) {
+ cc = 1;
+ res = dk4tspdk_add_bytes(&tsp, (const unsigned char *)ib, rb);
+ if (DK4_TSP_RES_FATAL == res) {
+ cc = 0;
+ }
+ }
+ }
+ } while(0 != cc);
+ if (DK4_TSP_RES_FATAL != res) {
+#if VERSION_BEFORE_20150821
+ res = dk4tspdk_finish(&tsp);
+#else
+ dk4tspdk_finish(&tsp);
+#endif
+ }
+ } else { $? "! failed to initialize line proc"
+ }
+ dk4stream_close(istrm, NULL);
+ } else { $? "! failed to open stream"
+ if (0 == ae->error_found) { ae->error_found = E_PREF_FILE_OPEN; }
+ }
+ }
+ } $? "- dk4app_open_read_preference_files"
+}
+
+
+
+/** Find host name for computer.
+ @param app Application to set up.
+ @param ae Application opening error structure.
+*/
+static
+void
+dk4app_open_find_host_name(dk4_app_t *app, dk4_app_error_t *ae)
+{
+ dkChar buf[256];
+ if (0 != dk4hostname(buf, DK4_SIZEOF(buf,dkChar), NULL)) {
+ app->host_name = dk4str_dup(buf, NULL);
+ if (NULL == app->host_name) {
+ if (0 == ae->error_found) { ae->error_found = E_MEMORY; }
+ }
+ } else {
+ if (0 == ae->error_found) { ae->error_found = E_HOST_NAME_NOT_FOUND; }
+ }
+}
+
+
+
+/** Check whether an option specification was given and
+ processed successfully.
+ @param app Application to set up.
+ @return 1 if option specification given, 0 otherwise.
+*/
+static
+int
+dk4app_open_options_check(dk4_app_t *app)
+{
+ int back = 0;
+ if ((NULL != app->s_opt_all) && (NULL != app->i_opt_all)) {
+ if ((NULL != app->s_opt_short) && (NULL != app->i_opt_short)) {
+ if ((NULL != app->s_opt_long) && (NULL != app->i_opt_long)) {
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Check for --help --version --license.
+ @param app Application to set up.
+ @param ae Application open error structure.
+ @param arg Argument to process.
+ @return 1 if the option needs no further processing, 0 otherwise.
+*/
+static
+int
+dk4app_open_check_long_opt(dk4_app_t *app, dk4_app_error_t *ae, dkChar *arg)
+{
+ int back = 0;
+ switch (dk4str_array_index(dk4app_open_long_opt, arg, 1)) {
+ case 0: { /* help */
+ app->hvl_cmd |= DK4_APP_CMD_HELP;
+ back = 1;
+ } break;
+ case 1: { /* version */
+ app->hvl_cmd |= DK4_APP_CMD_VERSION;
+ back = 1;
+ } break;
+ case 2: { /* license */
+ app->hvl_cmd = DK4_APP_CMD_LICENSE;
+ back = 1;
+ } break;
+ case 3: {
+ back = 1;
+ } break;
+ case 4: {
+ app->hvl_cmd |= DK4_APP_CMD_MANUAL;
+ back = 1;
+ } break;
+ }
+ return back;
+}
+
+
+
+/** Construct log file name, create log directory.
+ @param app Application to set up.
+ @param ae Application open error structure.
+*/
+static
+void
+dk4app_open_prepare_file_logging(dk4_app_t *app, dk4_app_error_t *ae)
+{
+ dkChar fnb[DK4_MAX_PATH]; /* File name buffer */
+ dkChar dktb[32]; /* Date as dkChar text */
+ dkChar pidb[32]; /* Buffer for PID */
+ dkChar pi2b[32]; /* Buffer for padded PID */
+ dkChar tb[32]; /* Date as text */
+ dkChar *ptr;
+ dk4_time_t timer; /* Current time */
+ dk4_pid_t pid; /* Process ID */
+ size_t sz; /* Size of fnb */
+ size_t szdktb; /* Size of dktb */
+ size_t sl; /* String length */
+ size_t pl; /* Padded length */
+ int ok = 0;
+ $? "+ dk4app_open_prepare_file_logging"
+ sz = DK4_SIZEOF(fnb,dkChar);
+ dk4time_get(&timer);
+ if (dk4str_cpy_s(fnb, sz, app->user_home, NULL)) {
+ if (dk4str_cat_s(fnb, sz, dk4app_open_kw[9], NULL)) {
+ dk4path_correct_sep(fnb);
+#if VERSION_BEFORE_20160127
+ ok = dk4app_mkdir_hierarchy(fnb, 1, app);
+#else
+ ok = 1;
+#endif
+ if (0 < ok) {
+ ok = 0;
+ if (dk4str_cat_s(fnb, sz, dk4app_open_kw[10], NULL)) {
+ if (dk4str_cat_s(fnb, sz, app->prog_name, NULL)) {
+ if (dk4time_as_text(tb, DK4_SIZEOF(tb,dkChar), &timer, NULL)) {
+ szdktb = DK4_SIZEOF(dktb,dkChar);
+ if (dk4str_cpy_s(dktb, szdktb, tb, NULL)) {
+ ptr = dktb;
+ while (dkT('\0') != *ptr) {
+ if (dkT(':') == *ptr) { *ptr = dkT('-'); }
+ if (dkT(' ') == *ptr) { *ptr = dkT('-'); }
+ ptr++;
+ }
+ pid = dk4getpid();
+ ok = dk4ma_write_decimal_unsigned(
+ pidb, DK4_SIZEOF(pidb,dkChar), (dk4_um_t)pid, 0,
+ NULL
+ );
+ if (0 != ok) {
+ for (sl = 0; sl < DK4_SIZEOF(pi2b,dkChar); sl++) {
+ pi2b[sl] = dkT('0');
+ }
+ pi2b[DK4_SIZEOF(pi2b,dkChar)-1] = dkT('\0');
+ sl = dk4str_len(pidb);
+ pl = dk4numlength(sizeof(dk4_pid_t), 0);
+ if (sl < pl) {
+ ok = dk4str_cpy_s(
+ &(pi2b[pl - sl]),
+ (DK4_SIZEOF(pi2b,dkChar) - (pl - sl)),
+ pidb, NULL
+ );
+ } else {
+ ok = dk4str_cpy_s(pi2b,DK4_SIZEOF(pi2b,dkChar),pidb,NULL);
+ }
+ if (0 != ok) {
+ ok = 0;
+ if (dk4str_cat_s(fnb, sz, dk4app_open_kw[11], NULL)) {
+ if (dk4str_cat_s(fnb, sz, dktb, NULL)) {
+ if (dk4str_cat_s(fnb, sz, dk4app_open_kw[11], NULL)) {
+ if (dk4str_cat_s(fnb, sz, pi2b, NULL)) {
+ if (dk4str_cat_s(fnb,sz,dk4app_open_kw[12],NULL)) {
+ app->log_file_name = dk4str_dup(fnb,NULL);
+ if (NULL != app->log_file_name) {
+ dk4path_correct_sep(app->log_file_name);
+ ok = 1; $? ". log file = \"%!ds\"", fnb
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if (0 != ok) {
+ ok = 0;
+ (void)dk4str_cpy_s(fnb, sz, app->user_home, NULL);
+ (void)dk4str_cat_s(fnb, sz, dk4app_open_kw[13], NULL);
+ (void)dk4str_cat_s(fnb, sz, dk4app_open_kw[10], NULL);
+ (void)dk4str_cat_s(fnb, sz, app->prog_name, NULL);
+ (void)dk4str_cat_s(fnb, sz, dk4app_open_kw[11], NULL);
+ (void)dk4str_cat_s(fnb, sz, dktb, NULL);
+ (void)dk4str_cat_s(fnb, sz, dk4app_open_kw[11], NULL);
+ (void)dk4str_cat_s(fnb, sz, pi2b, NULL);
+ dk4path_correct_sep(fnb);
+ app->dir_tmp = dk4str_dup(fnb, NULL);
+ if (NULL != app->dir_tmp) {
+#if VERSION_BEFORE_20160127
+ ok = dk4app_mkdir_hierarchy(app->dir_tmp, 0, app);
+#else
+ ok = 1;
+#endif
+ $? ". tmp dir = \"%!ds\"", fnb
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if (0 == ok) {
+ /* ERROR: Failed to construct log file name */
+ ae->error_found = E_LOG_FILE_NAME;
+ }
+ $? "- dk4app_open_prepare_file_logging %d", ok
+}
+
+
+
+/** Process command line arguments.
+ Save all non-option arguments in my_argc and my_argv if
+ an option specification available, all arguments otherwise.
+ @param app Application to set up.
+ @param ae Application open error structure.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+*/
+static
+void
+dk4app_open_process_argc_argv(
+ dk4_app_t *app,
+ dk4_app_error_t *ae,
+ int argc,
+ dkChar **argv
+)
+{
+ dkChar b[DK4_MAX_PATH + 128]; /* Private copy */
+ dkChar *argptr; /* Current option to process. */
+ dkChar *pv; /* Option value pointer */
+ dkChar *opv; /* Original option value pointer */
+ const dkChar *endptr; /* First char after value */
+ dk4_option_t *ospec; /* Option specification */
+ dk4_pref_t *prefptr; /* Preference */
+ double dval; /* Double value */
+ dk4_um_t uval; /* Unsigned integer value */
+ dk4_im_t ival; /* Integer value */
+ size_t szval; /* Size argument */
+ int i; /* Current option index to process */
+ int argsused; /* used elements in my_argv */
+ int res; /* Numeric conversion result */
+ int must_add; /* Flag: Must add to list */
+ int oi; /* Output index */
+ $? "+ dk4app_open_process_argc_argv"
+ if (0 < argc) { $? ". argc ok"
+ app->my_argv = dk4mem_new(DK4_PDKCHAR,argc,NULL);
+ if (NULL != app->my_argv) { $? ". my_argv ok"
+ for (i = 0; i < argc; i++) { (app->my_argv)[i] = NULL; }
+ if (dk4app_open_options_check(app)) { $? ". have option spec"
+ argsused = 0;
+ for (i = 1; i < argc; i++) {
+ argptr = argv[i]; $? ". processing %d = \"%!ds\"", i, argptr
+ if (dkT('-') == *argptr) { $? ". option"
+ if (dkT('-') == argptr[1]) { $? ". long option"
+ if (0 == dk4app_open_check_long_opt(app, ae, &(argptr[2]))) {
+ if (0 != dk4str_cpy_s(b,DK4_SIZEOF(b,dkChar),&(argptr[2]),NULL))
+ {
+ $? ". copied to private buffer"
+ opv = NULL;
+ pv = dk4str_chr(b, dkT('='));
+ if (NULL != pv) {
+ *(pv++) = dkT('\0');
+ pv = dk4str_start(pv, NULL);
+ }
+ if (NULL != pv) {
+ opv = dk4str_chr(&(argptr[2]), dkT('='));
+ if (NULL != opv) { opv = dk4str_start(++opv, NULL); }
+ }
+ ospec = dk4sto_it_find_like(
+ app->i_opt_long, (void *)b, 3
+ ); $? "b=\"%!ds\" pv=\"%!ds\" opv=\"%!ds\"",b,TR_DKSTR(pv),TR_DKSTR(opv)
+ if (NULL != ospec) { $? ". long option"
+ ospec->found = 1;
+ switch ((ospec->spec).argtype) {
+ case DK4_OPT_ARG_BOOL:
+ case DK4_OPT_ARG_SIZE:
+ case DK4_OPT_ARG_INT:
+ case DK4_OPT_ARG_UNSIGNED:
+ case DK4_OPT_ARG_DOUBLE:
+ case DK4_OPT_ARG_STRING: { $? ". argument required"
+ if (NULL == opv) { $? ". attempt next arg"
+ if ((1 + i) < argc) { $? ". use next arg"
+ opv = argv[++i];
+ }
+ }
+ if (NULL != opv) { $? ". opv argument ok"
+ switch ((ospec->spec).argtype) {
+ case DK4_OPT_ARG_BOOL: {
+ (ospec->val).b = 0;
+ if (dk4str_is_bool(opv)) { $? ". book ok"
+ (ospec->val).b = dk4str_is_on(opv);
+ } else { $? "! bool"
+ /* ERROR: Not a boolean argument */
+ dk4app_log_base5(
+ app, DK4_LL_ERROR, 33, 14, 15,
+ b, opv
+ );
+ if (0 == ae->error_found) {
+ ae->error_found = E_INVALID_OPTION_ARG;
+ }
+ }
+ } break;
+ case DK4_OPT_ARG_SIZE: {
+ (ospec->val).s = 0;
+ szval = 0;
+ endptr = NULL;
+ res = dk4ma_input_dk_dec_size_t(
+ &szval, opv, &endptr, 1, NULL
+ );
+ if (0 != res) { $? ". size ok"
+ (ospec->val).s = szval;
+ } else { $? "! size"
+ /* ERROR: Not a size specification */
+ dk4app_log_base7(
+ app, DK4_LL_ERROR, 32, 17, 154, 18,
+ b, endptr, opv
+ );
+ if (0 == ae->error_found) {
+ ae->error_found = E_INVALID_OPTION_ARG;
+ }
+ }
+ } break;
+ case DK4_OPT_ARG_INT: {
+ ival = (dk4_im_t)0L;
+ (ospec->val).i = (dk4_im_t)0L;
+ endptr = NULL;
+ res = dk4ma_input_dk_dec_dk4_im_t(
+ &ival, opv, &endptr, 1, NULL
+ );
+ if (0 != res) { $? ". int ok"
+ (ospec->val).i = ival;
+ } else { $? "! int"
+ /* ERROR: Not an integer value */
+ dk4app_log_base7(
+ app, DK4_LL_ERROR, 31, 20, 154, 21,
+ b, endptr, opv
+ );
+ if (0 == ae->error_found) {
+ ae->error_found = E_INVALID_OPTION_ARG;
+ }
+ }
+ } break;
+ case DK4_OPT_ARG_UNSIGNED: {
+ uval = (dk4_um_t)0UL;
+ (ospec->val).u = (dk4_um_t)0UL;
+ endptr = NULL;
+ res = dk4ma_input_dk_dec_dk4_um_t(
+ &uval, opv, &endptr, 1, NULL
+ );
+ if (0 != res) { $? ". unsigned ok"
+ (ospec->val).u = uval;
+ } else { $? "! unsigned"
+ /* ERROR: Not an unsigned integer value */
+ dk4app_log_base7(
+ app, DK4_LL_ERROR, 30, 23, 154, 24,
+ b, endptr, opv
+ );
+ if (0 == ae->error_found) {
+ ae->error_found = E_INVALID_OPTION_ARG;
+ }
+ }
+ } break;
+ case DK4_OPT_ARG_DOUBLE: { $? ". double"
+ dval = 0.0;
+ (ospec->val).d = 0.0;
+ endptr = NULL;
+ res = dk4ma_input_dk_double(
+ &dval, opv, &endptr, 1, NULL
+ );
+ if (0 != res) { $? ". double ok"
+ (ospec->val).d = dval;
+ } else { $? "! double"
+ dk4app_log_base7(
+ app, DK4_LL_ERROR, 29, 26, 154, 27,
+ b, endptr, opv
+ );
+ if (0 == ae->error_found) {
+ ae->error_found = E_INVALID_OPTION_ARG;
+ }
+ }
+ } break;
+ case DK4_OPT_ARG_STRING: { $? ". string ok"
+ (ospec->val).t = opv;
+ } break;
+ }
+ } else { $? "! no argument found"
+ /* ERROR: Option requires argument */
+ dk4app_log_base3(
+ app, DK4_LL_ERROR, 28, 12, b
+ );
+ if (0 == ae->error_found) {
+ ae->error_found = E_OPT_REQUIRES_ARG;
+ }
+ }
+ } break;
+ }
+ } else { $? ". preference"
+ /* Handle preference */
+ if (NULL != pv) { $? ". b=\"%!ds\" pv=\"%!ds\"", b, pv
+ prefptr = dk4sto_it_find_like(app->i_pref_cmd, b, 1);
+ if (NULL != prefptr) { $? ". entry already exists"
+ opv = dk4str_dup(pv, NULL);
+ if (NULL != opv) { $? ". new value allocated"
+#if 0
+ dk4mem_release(prefptr->value);
+#endif
+ /* 2016-12-10 Sanitize memory.
+ */
+ dk4str_release_sanitized(prefptr->value);
+ prefptr->value = opv;
+ } else { $? "! new value"
+ /* ERROR: Failed to save preference value */
+ dk4app_log_base5(
+ app, DK4_LL_ERROR, 34, 35, 36, b, pv
+ );
+ if (0 == ae->error_found) {
+ ae->error_found = E_MEMORY;
+ }
+ }
+ } else { $? ". entry not yet found"
+ prefptr = dk4pref_open(b, pv, NULL);
+ if (NULL != prefptr) { $? ". new pref created"
+ if (0 != dk4sto_add(app->s_pref_cmd, prefptr, NULL)) {
+ $? ". new pref added successfully"
+ } else { $? "! failed to add new pref"
+ /* ERROR: Failed to save preference value */
+ dk4app_log_base5(
+ app, DK4_LL_ERROR, 34, 35, 36,
+ b, pv
+ );
+ dk4pref_close(prefptr);
+ if (0 == ae->error_found) {
+ ae->error_found = E_MEMORY;
+ }
+ }
+ } else { $? "! new pref"
+ /* ERROR: Failed to save preference value */
+ dk4app_log_base5(
+ app, DK4_LL_ERROR, 34, 35, 36,
+ b, pv
+ );
+ if (0 == ae->error_found) {
+ ae->error_found = E_MEMORY;
+ }
+ }
+ }
+ dk4app_pref_apply(app, ae, b, pv);
+ } else { $? "! missing pref value"
+ /* ERROR: Missing preference value */
+ dk4app_log_base3(app, DK4_LL_ERROR, 37, 38, b);
+ if (0 == ae->error_found) {
+ ae->error_found = E_OPT_REQUIRES_ARG;
+ }
+ }
+ }
+ } else { $? "! failed to create copy"
+ /* ERROR: Option too long! */
+ dk4app_log_base3(app, DK4_LL_ERROR, 39, 40, argptr);
+ if (0 == ae->error_found) {
+ ae->error_found = E_OPTION_TOO_LONG;
+ }
+ }
+ }
+ } else { $? ". short option"
+ ospec = dk4sto_it_find_like(
+ app->i_opt_short, (void *)(&(argptr[1])), 1
+ );
+ if (NULL != ospec) { $? ". option expected"
+ ospec->found = 1;
+ pv = NULL;
+ switch ((ospec->spec).argtype) {
+ case DK4_OPT_ARG_BOOL:
+ case DK4_OPT_ARG_SIZE:
+ case DK4_OPT_ARG_INT:
+ case DK4_OPT_ARG_UNSIGNED:
+ case DK4_OPT_ARG_DOUBLE:
+ case DK4_OPT_ARG_STRING: { $? ". argument required"
+ pv = dk4str_start(&(argptr[2]), NULL);
+ if (NULL == pv) { $? ". attempt next argv"
+ if ((1 + i) < argc) { $? ". use next argv"
+ pv = argv[++i];
+ }
+ }
+ if (NULL != pv) {
+ switch ((ospec->spec).argtype) {
+ case DK4_OPT_ARG_BOOL: {
+ (ospec->val).b = 0;
+ if (dk4str_is_bool(pv)) { $? ". bool ok"
+ (ospec->val).b = dk4str_is_on(pv);
+ } else { $? "! bool"
+ /* ERROR: Not a boolean argument */
+ dk4app_log_base5(
+ app, DK4_LL_ERROR, 13, 14, 15,
+ argptr, pv
+ );
+ if (0 == ae->error_found) {
+ ae->error_found = E_INVALID_OPTION_ARG;
+ }
+ }
+ } break;
+ case DK4_OPT_ARG_SIZE: {
+ (ospec->val).s = 0;
+ szval = 0;
+ endptr = NULL;
+ res = dk4ma_input_dk_dec_size_t(
+ &szval, pv, &endptr, 1, NULL
+ );
+ if (0 != res) { $? ". size ok"
+ (ospec->val).s = szval;
+ } else { $? "! size"
+ /* ERROR: Not a size specification */
+ dk4app_log_base7(
+ app, DK4_LL_ERROR, 16, 17, 154, 18,
+ argptr, endptr, pv
+ );
+ if (0 == ae->error_found) {
+ ae->error_found = E_INVALID_OPTION_ARG;
+ }
+ }
+ } break;
+ case DK4_OPT_ARG_INT: {
+ ival = (dk4_im_t)0L;
+ (ospec->val).i = (dk4_im_t)0L;
+ endptr = NULL;
+ res = dk4ma_input_dk_dec_dk4_im_t(
+ &ival, pv, &endptr, 1, NULL
+ );
+ if (0 != res) { $? ". int ok"
+ (ospec->val).i = ival;
+ } else { $? "! int"
+ /* ERROR: Not an integer value */
+ dk4app_log_base7(
+ app, DK4_LL_ERROR, 19, 20, 154, 21,
+ argptr, endptr, pv
+ );
+ if (0 == ae->error_found) {
+ ae->error_found = E_INVALID_OPTION_ARG;
+ }
+ }
+ } break;
+ case DK4_OPT_ARG_UNSIGNED: {
+ uval = (dk4_um_t)0UL;
+ (ospec->val).u = (dk4_um_t)0UL;
+ endptr = NULL;
+ res = dk4ma_input_dk_dec_dk4_um_t(
+ &uval, pv, &endptr, 1, NULL
+ );
+ if (0 != res) { $? ". unsigned ok"
+ (ospec->val).u = uval;
+ } else { $? "! unsigned"
+ /* ERROR: Not an unsigned integer value */
+ dk4app_log_base7(
+ app, DK4_LL_ERROR, 22, 23, 154, 24,
+ argptr, endptr, pv
+ );
+ if (0 == ae->error_found) {
+ ae->error_found = E_INVALID_OPTION_ARG;
+ }
+ }
+ } break;
+ case DK4_OPT_ARG_DOUBLE: { $? ". double"
+ dval = 0.0;
+ (ospec->val).d = 0.0;
+ endptr = NULL;
+ res = dk4ma_input_dk_double(
+ &dval, pv, &endptr, 1, NULL
+ );
+ if (0 != res) { $? ". double ok"
+ (ospec->val).d = dval;
+ } else { $? "! double"
+ dk4app_log_base7(
+ app, DK4_LL_ERROR, 25, 26, 154, 27,
+ argptr, endptr, pv
+ );
+ if (0 == ae->error_found) {
+ ae->error_found = E_INVALID_OPTION_ARG;
+ }
+ }
+ } break;
+ case DK4_OPT_ARG_STRING: { $? ". string ok"
+ (ospec->val).t = pv;
+ } break;
+ }
+ } else { $? "! required argument not found"
+ /* ERROR: Option requires argument */
+ dk4app_log_base3(
+ app, DK4_LL_ERROR, 11, 12, argptr
+ );
+ if (0 == ae->error_found) {
+ ae->error_found = E_OPT_REQUIRES_ARG;
+ }
+ }
+ } break;
+ }
+ } else { $? "! unexpected option"
+ /* ERROR: Unexpected option */
+ dk4app_log_base3(app, DK4_LL_ERROR, 9, 10, argptr);
+ if (0 == ae->error_found) {
+ ae->error_found = E_UNEXPECTED_OPTION;
+ }
+ }
+ }
+ } else { $? ". file name"
+ (app->my_argv)[argsused++] = argptr;
+ }
+ }
+ app->my_argc = argsused;
+ } else { $? ". no option spec"
+ oi = 0;
+ for (i = 0; (i + 1) < argc; i++) {
+ must_add = 1;
+ if (dkT('-') == (argv[i + 1])[0]) {
+ if (dkT('-') == (argv[i + 1])[1]) {
+ if (0 == dk4app_open_check_long_opt(app, ae, &((argv[i+1])[2]))) {
+ /* Treat all long options as preferences.
+ */
+ must_add = dk4str_cpy_s(
+ b, DK4_SIZEOF(b,dkChar), &((argv[i + 1])[2]), NULL
+ );
+ if (0 != must_add) {
+ opv = NULL;
+ pv = dk4str_chr(b, dkT('='));
+ if (NULL != pv) {
+ *(pv++) = dkT('\0');
+ pv = dk4str_start(pv, NULL);
+ }
+ if (NULL != pv) {
+ opv = dk4str_chr(&((argv[i + 1])[2]), dkT('='));
+ if (NULL != opv) { opv = dk4str_start(++opv, NULL); }
+#ifdef __clang_analyzer__
+ /* 2015-08-21 / 2016-01-20
+ Static code analysis by clang complains
+ opv is set but not used later. Probably true.
+ */
+ (void)opv;
+#endif
+ }
+ if (NULL != pv) {
+ prefptr = dk4sto_it_find_like(app->i_pref_cmd, b, 1);
+ if (NULL != prefptr) {
+ opv = dk4str_dup(pv, NULL);
+ if (NULL != opv) {
+#if 0
+ dk4mem_release(prefptr->value);
+#endif
+ /* 2016-12-10 Sanitize memory.
+ */
+ dk4str_release_sanitized(prefptr->value);
+ prefptr->value = opv;
+ } else {
+ dk4app_log_base5(
+ app, DK4_LL_ERROR, 34, 35, 36, b, pv
+ );
+ if (0 == ae->error_found) {
+ ae->error_found = E_MEMORY;
+ }
+ }
+ } else {
+ prefptr = dk4pref_open(b, pv, NULL);
+ if (NULL != prefptr) {
+ if (0 == dk4sto_add(app->s_pref_cmd, prefptr, NULL)) {
+ dk4app_log_base5(
+ app, DK4_LL_ERROR, 34, 35, 36, b, pv
+ );
+ dk4pref_close(prefptr);
+ if (0 == ae->error_found) {
+ ae->error_found = E_MEMORY;
+ }
+ }
+ } else {
+ dk4app_log_base5(
+ app, DK4_LL_ERROR, 34, 35, 36, b, pv
+ );
+ if (0 == ae->error_found) {
+ ae->error_found = E_MEMORY;
+ }
+ }
+ }
+ dk4app_pref_apply(app, ae, b, pv);
+ } else {
+ dk4app_log_base3(app, DK4_LL_ERROR, 37, 38, b);
+ if (0 == ae->error_found) {
+ ae->error_found = E_OPT_REQUIRES_ARG;
+ }
+ }
+ } else {
+ /* ERROR: Option too long! */
+ dk4app_log_base3(app, DK4_LL_ERROR, 39, 40, argv[i + 1]);
+ if (0 == ae->error_found) {
+ ae->error_found = E_OPTION_TOO_LONG;
+ }
+ }
+ }
+ must_add = 0;
+ }
+ }
+ if (0 != must_add) {
+ (app->my_argv)[oi++] = argv[i + 1];
+ }
+ }
+ app->my_argc = oi; $? ". argc,argv copied"
+ }
+ } else { $? "! my_argv"
+ if (0 == ae->error_found) { ae->error_found = E_MEMORY; }
+ }
+ } else { $? "! argc"
+ if (0 == ae->error_found) { ae->error_found = E_ARGC; }
+ } $? "- dk4app_open_process_argc_argv"
+}
+
+
+
+/** Keep private copies of version text, help file name, help text
+ and license text.
+ @param app
+ @param ae
+ @param version
+ @param helpfile
+ @param helptext
+ @param lictext
+*/
+static
+void
+dk4app_open_save_names(
+ dk4_app_t *app,
+ dk4_app_error_t *ae,
+ const dkChar *version,
+ const dkChar *helpfile,
+ const dkChar * const *helptext,
+ const dkChar * const *lictext
+)
+{
+ int ok = 0;
+ if (NULL != version) {
+ if (NULL != helpfile) {
+ if (NULL != helptext) {
+ if (NULL != lictext) {
+ ok = 1;
+ app->help_text = helptext;
+ app->lic_text = lictext;
+ app->vers_text = dk4str_dup(version, NULL);
+ app->help_file_name = dk4str_dup(helpfile, NULL);
+ if ((NULL == app->vers_text) || (NULL == app->help_file_name)) {
+ if (0 == ae->error_found) { ae->error_found = E_MEMORY; }
+ }
+ }
+ }
+ }
+ }
+ if (0 == ok) {
+ if (0 == ae->error_found) { ae->error_found = E_BUG_ARGUMENTS; }
+ }
+}
+
+
+
+/** Open an application structure for a command line program.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @param optspec Option specification, may be NULL.
+ @param szoptspec Number of elements in optspec.
+ @param groupname Program group name.
+ @param version Version number string.
+ @param helpfile Help file name.
+ @param helptext Default help text.
+ @param lictext License conditions text.
+ @param enablog Flag: Enable logging.
+ @return Pointer to dk4_app_t structure on success, NULL on error.
+*/
+static
+dk4_app_t *
+dk4app_open_internally(
+ int argc,
+ dkChar **argv,
+ const dk4_option_specification_t *optspec,
+ size_t szoptspec,
+ const dkChar *groupname,
+ const dkChar *version,
+ const dkChar *helpfile,
+ const dkChar * const *helptext,
+ const dkChar * const *lictext,
+ int enablog
+)
+{
+ dk4_app_error_t ae; /* Error during startup */
+ dk4_app_t *back = NULL; /* Function result */
+ int quiet = 0; /* Flag: Run quiet */
+
+ $? "+ dk4app_open_cmd"
+ DK4_MEMRES(&ae, sizeof(dk4_app_error_t));
+ ae.error_found = 0;
+ if (NULL != groupname) {
+ if ((0 < argc) && (NULL != argv)) {
+ quiet = dk4app_open_silence_check(argc, argv);
+ back = dk4mem_new(dk4_app_t,1,NULL);
+ if (NULL != back) {
+ /* Set all members to reasonable default */
+ dk4app_open_initialize(back);
+
+ back->group_name = dk4str_dup(groupname, NULL);
+ if (NULL == back->group_name) {
+ ae.error_found = E_MEMORY;
+ }
+
+ if (0 == ae.error_found) {
+ dk4app_open_save_names(
+ back, &ae,
+ version, helpfile, helptext, lictext
+ );
+ }
+
+ /* Find host name */
+ if (0 == ae.error_found) {
+ dk4app_open_find_host_name(back, &ae);
+ }
+
+ /* Find user name and home directory */
+ if (0 == ae.error_found) {
+ dk4app_open_find_user_name_and_home(back, &ae);
+ }
+
+ /* Find language and region */
+ if (0 == ae.error_found) {
+ dk4app_open_find_language_region(back, &ae);
+ }
+
+ /* Find executable path name and derive directory names from it */
+ if (0 == ae.error_found) {
+ dk4app_open_find_executable(back, &ae, argv[0]);
+ }
+
+ /* Create option storage from option specification */
+ if (0 == ae.error_found) {
+ dk4app_open_create_options_storages(
+ back, &ae, optspec, szoptspec
+ );
+ }
+
+ /* Create preferences storage */
+ if (0 == ae.error_found) {
+ dk4app_open_create_pref_storages(back, &ae);
+ }
+
+ /* Create string table storage */
+ if (0 == ae.error_found) {
+ dk4app_open_create_stt_storage(back, &ae);
+ }
+
+ /* Read preference files */
+ if (0 == ae.error_found) {
+ dk4app_open_read_preference_files(back, &ae);
+ }
+
+ /* Construct log file name, create log directory */
+ if ((0 != enablog) && (0 == quiet) && (0 == ae.error_found)) {
+ dk4app_open_prepare_file_logging(back, &ae);
+ }
+
+ /* Enable logging if not switched to silent mode */
+ if ((0 != enablog) && (0 == quiet) && (0 == ae.error_found)) {
+ back->log_enabled = 1;
+ }
+
+ /* We must be able to log, if there are errors */
+ if (0 == ae.error_found) {
+ /* Process command line arguments, search for options */
+ dk4app_open_process_argc_argv(back, &ae, argc, argv);
+ }
+
+ /* If there were serious errors, destroy the structure */
+ if (ae.error_found) {
+ dk4app_open_report_error(back, &ae);
+ dk4app_close(back);
+ back = NULL;
+ }
+ } else { $? "! allocation failed"
+ if (0 == quiet) {
+ char buf[64];
+ int res;
+ res = dk4ma_write_c8_decimal_unsigned(
+ buf, sizeof(buf), (dk4_um_t)sizeof(dk4_app_t), 0, NULL
+ );
+ if (0 != res) {
+ fputs(dk4app_open_c8_kw[1], stderr);
+ fputs(buf, stderr);
+ fputs(dk4app_open_c8_kw[2], stderr);
+ } else {
+ fputs(dk4app_open_c8_kw[0], stderr);
+ }
+ fputc('\n', stderr);
+ fflush(stderr);
+ }
+ }
+ } else { $? "! argc or argv wrong"
+ }
+ } else { $? "! missing group name"
+ }
+ if (NULL != back) { $? ". result ok"
+ if (0 != dk4app_log_do(back, DK4_LL_DEBUG)) { $? ". log startup"
+ (void)dk4app_log_debug_texts(back, NULL);
+ dk4app_log_startup_debug(back);
+ }
+ } $? "- dk4app_open_cmd PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+
+dk4_app_t *
+dk4app_open_cmd(
+ int argc,
+ dkChar **argv,
+ const dk4_option_specification_t *optspec,
+ size_t szoptspec,
+ const dkChar *groupname,
+ const dkChar *version,
+ const dkChar *helpfile,
+ const dkChar * const *helptext,
+ const dkChar * const *lictext
+)
+{
+ dk4_app_t *back;
+ back = dk4app_open_internally(
+ argc, argv, optspec, szoptspec, groupname, version,
+ helpfile, helptext, lictext, 1
+ );
+ return back;
+}
+
+
+
+
+dk4_app_t *
+dk4app_open_silent(
+ int argc,
+ dkChar **argv,
+ const dk4_option_specification_t *optspec,
+ size_t szoptspec,
+ const dkChar *groupname,
+ const dkChar *version,
+ const dkChar *helpfile,
+ const dkChar * const *helptext,
+ const dkChar * const *lictext
+)
+{
+ dk4_app_t *back;
+ back = dk4app_open_internally(
+ argc, argv, optspec, szoptspec, groupname, version,
+ helpfile, helptext, lictext, 0
+ );
+ return back;
+}
+
+
+
+void
+dk4app_set_fast_close(dk4_app_t *app)
+{
+ if (NULL != app) {
+ app->fast_close = 1;
+ }
+}
+
diff --git a/support/dktools/dk4appstt.c b/support/dktools/dk4appstt.c
new file mode 100644
index 0000000000..5b8cf37ed9
--- /dev/null
+++ b/support/dktools/dk4appstt.c
@@ -0,0 +1,190 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4appstt.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4appstt.c The dk4appstt module.
+*/
+
+
+#line 10 "dk4appstt.ctr"
+
+#include "dk4app.h"
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4MPL_H_INCLUDED
+#include "dk4mpl.h"
+#endif
+
+#ifndef DK4STT_H_INCLUDED
+#include "dk4stt.h"
+#endif
+
+#ifndef DK4STRM_H_INCLUDED
+#include "dk4strm.h"
+#endif
+
+#ifndef DK4STRMR_H_INCLUDED
+#include "dk4strmr.h"
+#endif
+
+#ifndef DK4FS_H_INCLUDED
+#include "dk4fs.h"
+#endif
+
+
+
+
+
+#line 40 "dk4appstt.ctr"
+
+
+
+size_t
+dk4app_string_table_size(const dkChar * const *texts)
+{
+ size_t back = 0;
+
+
+#line 48 "dk4appstt.ctr"
+ if (NULL != texts) {
+ while (NULL != *(texts++)) { back++; }
+ }
+
+#line 51 "dk4appstt.ctr"
+ return back;
+}
+
+
+
+const dkChar * const *
+dk4app_string_table(
+ dk4_app_t *app,
+ const dkChar *shortname,
+ const dkChar * const *deftexts
+)
+{
+ dkChar buffer[DK4_MAX_PATH];
+ dk4_string_table_t *sttptr;
+ dk4_stream_t *istrm;
+ const dkChar * const *back;
+ size_t rqlen;
+ int res;
+ int ok;
+
+
+#line 71 "dk4appstt.ctr"
+ back = deftexts;
+ if ((NULL != app) && (NULL != shortname)) {
+
+#line 73 "dk4appstt.ctr"
+ back = NULL;
+ rqlen = dk4app_string_table_size(deftexts);
+
+#line 75 "dk4appstt.ctr"
+ sttptr = (dk4_string_table_t *)dk4sto_it_find_like(app->i_stt,shortname,1);
+ if (NULL == sttptr) {
+
+#line 77 "dk4appstt.ctr"
+ res = dk4app_search_data_file(
+ buffer, DK4_SIZEOF(buffer,dkChar), app, shortname,
+ DK4_FS_DATA_MAX_SYS, 1, NULL
+ );
+ if (0 < res) {
+
+#line 82 "dk4appstt.ctr"
+ sttptr = dk4stt_open(shortname, rqlen, NULL);
+ if (NULL != sttptr) {
+
+#line 84 "dk4appstt.ctr"
+ ok = 0;
+ istrm = dk4stream_open_file_reader(buffer, NULL);
+ if (NULL != istrm) {
+
+#line 87 "dk4appstt.ctr"
+ res = dk4stt_apply_stream(sttptr, istrm, app->encoding, NULL, NULL);
+ if (0 < res) {
+
+#line 89 "dk4appstt.ctr"
+ if (0 < dk4sto_add(app->s_stt, (void *)sttptr, NULL)) {
+ ok = 1;
+
+#line 91 "dk4appstt.ctr"
+ } else {
+
+#line 92 "dk4appstt.ctr"
+ }
+ } else {
+
+#line 94 "dk4appstt.ctr"
+ }
+ dk4stream_close(istrm, NULL);
+ } else {
+
+#line 97 "dk4appstt.ctr"
+ }
+ if (0 == ok) {
+ dk4stt_close(sttptr);
+ sttptr = NULL;
+ }
+ } else {
+
+#line 103 "dk4appstt.ctr"
+ }
+ } else {
+
+#line 105 "dk4appstt.ctr"
+ }
+ }
+ if (NULL != sttptr) {
+
+#line 108 "dk4appstt.ctr"
+ if (sttptr->nstrings >= rqlen) {
+ back = (const dkChar * const *)(sttptr->strings);
+ }
+ }
+ if (NULL == back) {
+
+#line 113 "dk4appstt.ctr"
+ back = deftexts;
+ }
+ }
+
+#line 116 "dk4appstt.ctr"
+ return back;
+}
+
+
diff --git a/support/dktools/dk4appstt.ctr b/support/dktools/dk4appstt.ctr
new file mode 100644
index 0000000000..17628ea5c4
--- /dev/null
+++ b/support/dktools/dk4appstt.ctr
@@ -0,0 +1,119 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4app.h"
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4MPL_H_INCLUDED
+#include "dk4mpl.h"
+#endif
+
+#ifndef DK4STT_H_INCLUDED
+#include "dk4stt.h"
+#endif
+
+#ifndef DK4STRM_H_INCLUDED
+#include "dk4strm.h"
+#endif
+
+#ifndef DK4STRMR_H_INCLUDED
+#include "dk4strmr.h"
+#endif
+
+#ifndef DK4FS_H_INCLUDED
+#include "dk4fs.h"
+#endif
+
+
+
+$!trace-include
+
+
+
+size_t
+dk4app_string_table_size(const dkChar * const *texts)
+{
+ size_t back = 0;
+ $? "+ dk4app_string_table_size"
+ if (NULL != texts) {
+ while (NULL != *(texts++)) { back++; }
+ } $? "- dk4app_string_table_size %u", (unsigned)back
+ return back;
+}
+
+
+
+const dkChar * const *
+dk4app_string_table(
+ dk4_app_t *app,
+ const dkChar *shortname,
+ const dkChar * const *deftexts
+)
+{
+ dkChar buffer[DK4_MAX_PATH];
+ dk4_string_table_t *sttptr;
+ dk4_stream_t *istrm;
+ const dkChar * const *back;
+ size_t rqlen;
+ int res;
+ int ok;
+ $? "+ dk4app_string_table \"%!ds\"", TR_STR(shortname)
+ back = deftexts;
+ if ((NULL != app) && (NULL != shortname)) { $? ". args ok"
+ back = NULL;
+ rqlen = dk4app_string_table_size(deftexts); $? ". elements %u", (unsigned)rqlen
+ sttptr = (dk4_string_table_t *)dk4sto_it_find_like(app->i_stt,shortname,1);
+ if (NULL == sttptr) { $? ". create new string table"
+ res = dk4app_search_data_file(
+ buffer, DK4_SIZEOF(buffer,dkChar), app, shortname,
+ DK4_FS_DATA_MAX_SYS, 1, NULL
+ );
+ if (0 < res) { $? ". file found"
+ sttptr = dk4stt_open(shortname, rqlen, NULL);
+ if (NULL != sttptr) { $? ". allocated"
+ ok = 0;
+ istrm = dk4stream_open_file_reader(buffer, NULL);
+ if (NULL != istrm) { $? ". input stream ok"
+ res = dk4stt_apply_stream(sttptr, istrm, app->encoding, NULL, NULL);
+ if (0 < res) { $? ". stream applied"
+ if (0 < dk4sto_add(app->s_stt, (void *)sttptr, NULL)) {
+ ok = 1; $? ". added to storage"
+ } else { $? "! memory"
+ }
+ } else { $? "! failed to apply stream"
+ }
+ dk4stream_close(istrm, NULL);
+ } else { $? "! failed to open stream"
+ }
+ if (0 == ok) {
+ dk4stt_close(sttptr);
+ sttptr = NULL;
+ }
+ } else { $? "! memory"
+ }
+ } else { $? "! file not found"
+ }
+ }
+ if (NULL != sttptr) { $? ". have string table"
+ if (sttptr->nstrings >= rqlen) {
+ back = (const dkChar * const *)(sttptr->strings);
+ }
+ }
+ if (NULL == back) { $? ". no string table"
+ back = deftexts;
+ }
+ } $? "- dk4app_string_table PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
diff --git a/support/dktools/dk4apref.c b/support/dktools/dk4apref.c
new file mode 100644
index 0000000000..536d315bdb
--- /dev/null
+++ b/support/dktools/dk4apref.c
@@ -0,0 +1,288 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4apref.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4apref.c The dk4apref module.
+*/
+
+
+#line 9 "dk4apref.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4app.h"
+#include "dk4pref.h"
+#include "dk4strd.h"
+#include "dk4appi.c"
+#include "dk4mem.h"
+#include "dk4enc.h"
+
+
+
+
+
+#line 22 "dk4apref.ctr"
+
+
+
+/** Names of system preferences to process immediately.
+*/
+static const dkChar * const dk4apref_names[] = {
+/* 0 */
+dkT("ui.language"),
+
+/* 1 */
+dkT("ui.region"),
+
+/* 2 */
+dkT("log.stderr.level"),
+
+/* 3 */
+dkT("log.file.level"),
+
+/* 4 */
+dkT("log.file.keep"),
+
+/* 5 */
+dkT("input.encoding"),
+
+/* 6 */
+dkT("input.file.encoding"),
+
+/* 7 */
+dkT("log.stderr.time"),
+
+/* 8 */
+dkT("log.file.time"),
+
+/* 9 */
+dkT("input.encoding.stdin"),
+
+/* 10 */
+dkT("ui.lang"),
+
+NULL
+
+
+#line 71 "dk4apref.ctr"
+};
+
+
+
+/** Log level names.
+*/
+static const dkChar * const dk4apref_log_level_names[] = {
+/* 0 */
+dkT("none"),
+
+/* 1 */
+dkT("panic"),
+
+/* 2 */
+dkT("fatal"),
+
+/* 3 */
+dkT("error"),
+
+/* 4 */
+dkT("warning"),
+
+/* 5 */
+dkT("info"),
+
+/* 6 */
+dkT("progress"),
+
+/* 7 */
+dkT("debug"),
+
+/* 8 */
+dkT("ignore"),
+
+NULL
+
+
+#line 89 "dk4apref.ctr"
+};
+
+
+
+void
+dk4app_pref_apply(
+ dk4_app_t *app,
+ dk4_app_error_t *ae,
+ const dkChar *pn,
+ const dkChar *pv
+)
+{
+ dkChar *newval;
+ int pi;
+ int ll;
+ int bom;
+
+
+#line 106 "dk4apref.ctr"
+ if ((NULL != app) && (NULL != ae) && (NULL != pn) && (NULL != pv)) {
+ pi = dk4str_array_index(dk4apref_names, pn, 1);
+ if (-1 < pi) {
+ switch (pi) {
+ case 0: {
+
+#line 111 "dk4apref.ctr"
+ newval = dk4str_dup(pv, NULL);
+ if (NULL != newval) {
+ dk4mem_release(app->language);
+ app->language = newval;
+ } else {
+ if (0 == ae->error_found) { ae->error_found = E_MEMORY; }
+ }
+ } break;
+ case 1: {
+
+#line 120 "dk4apref.ctr"
+ newval = dk4str_dup(pv, NULL);
+ if (NULL != newval) {
+ dk4mem_release(app->region);
+ app->region = newval;
+ } else {
+ if (0 == ae->error_found) { ae->error_found = E_MEMORY; }
+ }
+ } break;
+ case 2: {
+
+#line 129 "dk4apref.ctr"
+ ll = dk4str_array_index(dk4apref_log_level_names, pv, 0);
+ if (-1 < ll) {
+ app->ll_stderr = ll;
+ }
+ } break;
+ case 3: {
+
+#line 135 "dk4apref.ctr"
+ ll = dk4str_array_index(dk4apref_log_level_names, pv, 0);
+ if (-1 < ll) {
+ app->ll_file = ll;
+ }
+ } break;
+ case 4: {
+
+#line 141 "dk4apref.ctr"
+ ll = dk4str_array_index(dk4apref_log_level_names, pv, 0);
+ if (-1 < ll) {
+ app->ll_file_keep = ll;
+ }
+ } break;
+ case 5: case 9: {
+
+#line 147 "dk4apref.ctr"
+ ll = app->enc_in_std;
+ bom = 0;
+ if (dk4enc_find(&ll, &bom, pv, NULL)) {
+ app->enc_in_std = ll;
+ }
+ } break;
+ case 6: {
+
+#line 154 "dk4apref.ctr"
+ ll = app->enc_in_file;
+ bom = 0;
+ if (dk4enc_find(&ll, &bom, pv, NULL)) {
+ app->enc_in_file = ll;
+ }
+ } break;
+ case 7: {
+
+#line 161 "dk4apref.ctr"
+ if (dk4str_is_on(pv)) {
+ app->log_stderr_time = 1;
+ } else {
+ app->log_stderr_time = 0;
+ }
+ } break;
+ case 8: {
+
+#line 168 "dk4apref.ctr"
+ if (dk4str_is_on(pv)) {
+ app->log_file_time = 1;
+ } else {
+ app->log_file_time = 0;
+ }
+ } break;
+ case 10: {
+
+#line 175 "dk4apref.ctr"
+ if (NULL != pv) {
+ dkChar *plang;
+ dkChar *preg;
+ dkChar *nlang;
+ dkChar *nreg;
+ /* Remove encoding stuff */
+ plang = dk4str_chr(pv, dkT('.'));
+ if (NULL != plang) { *plang = dkT('\0'); }
+ plang = dk4str_start(pv, NULL);
+ if (NULL != plang) {
+ preg = dk4str_chr(plang, dkT('_'));
+ if (NULL != preg) {
+ *(preg++) = dkT('\0');
+ preg = dk4str_start(preg, NULL);
+ }
+ nlang = dk4str_dup(plang, NULL);
+ if (NULL != nlang) {
+ dk4mem_release(app->language);
+ app->language = nlang;
+ } else {
+ if (0 == ae->error_found) { ae->error_found = E_MEMORY; }
+ }
+ if (NULL != preg) {
+ nreg = dk4str_dup(preg, NULL);
+ if (NULL != nreg) {
+ dk4mem_release(app->region);
+ app->region = nreg;
+ } else {
+ if (0 == ae->error_found) { ae->error_found = E_MEMORY; }
+ }
+ }
+ }
+ }
+ } break;
+ }
+ }
+ }
+
+#line 212 "dk4apref.ctr"
+}
+
+
+
+
diff --git a/support/dktools/dk4apref.ctr b/support/dktools/dk4apref.ctr
new file mode 100644
index 0000000000..14a644f132
--- /dev/null
+++ b/support/dktools/dk4apref.ctr
@@ -0,0 +1,216 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4app.h"
+#include "dk4pref.h"
+#include "dk4strd.h"
+#include "dk4appi.c"
+#include "dk4mem.h"
+#include "dk4enc.h"
+
+
+
+$!trace-include
+
+
+
+/** Names of system preferences to process immediately.
+*/
+static const dkChar * const dk4apref_names[] = {
+$!string-table macro=dkT
+#
+# 0 Language
+#
+ui.language
+#
+# 1 Region
+#
+ui.region
+#
+# 2 Log level required for logging to stderr
+#
+log.stderr.level
+#
+# 3 Log level required for logging to file
+#
+log.file.level
+#
+# 4 Log level required to keep log level
+#
+log.file.keep
+#
+# 5 Input encoding expected on stdin
+#
+input.encoding
+#
+# 6 Input encoding expected when reading files.
+#
+input.file.encoding
+#
+# 7 8 Write timestamps before writing log messages.
+#
+log.stderr.time
+log.file.time
+#
+# 9 Alias for [5]
+#
+input.encoding.stdin
+#
+# 10 For backward compatibility
+#
+ui.lang
+$!end
+};
+
+
+
+/** Log level names.
+*/
+static const dkChar * const dk4apref_log_level_names[] = {
+$!string-table macro=dkT
+none
+panic
+fatal
+error
+warning
+info
+progress
+debug
+ignore
+$!end
+};
+
+
+
+void
+dk4app_pref_apply(
+ dk4_app_t *app,
+ dk4_app_error_t *ae,
+ const dkChar *pn,
+ const dkChar *pv
+)
+{
+ dkChar *newval;
+ int pi;
+ int ll;
+ int bom;
+ $? "+ dk4app_pref_apply"
+ if ((NULL != app) && (NULL != ae) && (NULL != pn) && (NULL != pv)) {
+ pi = dk4str_array_index(dk4apref_names, pn, 1);
+ if (-1 < pi) {
+ switch (pi) {
+ case 0: { $? ". language"
+ newval = dk4str_dup(pv, NULL);
+ if (NULL != newval) {
+ dk4mem_release(app->language);
+ app->language = newval;
+ } else {
+ if (0 == ae->error_found) { ae->error_found = E_MEMORY; }
+ }
+ } break;
+ case 1: { $? ". region"
+ newval = dk4str_dup(pv, NULL);
+ if (NULL != newval) {
+ dk4mem_release(app->region);
+ app->region = newval;
+ } else {
+ if (0 == ae->error_found) { ae->error_found = E_MEMORY; }
+ }
+ } break;
+ case 2: { $? ". log level stderr"
+ ll = dk4str_array_index(dk4apref_log_level_names, pv, 0);
+ if (-1 < ll) {
+ app->ll_stderr = ll;
+ }
+ } break;
+ case 3: { $? ". log level file"
+ ll = dk4str_array_index(dk4apref_log_level_names, pv, 0);
+ if (-1 < ll) {
+ app->ll_file = ll;
+ }
+ } break;
+ case 4: { $? ". log keep file"
+ ll = dk4str_array_index(dk4apref_log_level_names, pv, 0);
+ if (-1 < ll) {
+ app->ll_file_keep = ll;
+ }
+ } break;
+ case 5: case 9: { $? ". encoding stdin"
+ ll = app->enc_in_std;
+ bom = 0;
+ if (dk4enc_find(&ll, &bom, pv, NULL)) {
+ app->enc_in_std = ll;
+ }
+ } break;
+ case 6: { $? ". encoding file"
+ ll = app->enc_in_file;
+ bom = 0;
+ if (dk4enc_find(&ll, &bom, pv, NULL)) {
+ app->enc_in_file = ll;
+ }
+ } break;
+ case 7: { $? ". log stderr time"
+ if (dk4str_is_on(pv)) {
+ app->log_stderr_time = 1;
+ } else {
+ app->log_stderr_time = 0;
+ }
+ } break;
+ case 8: { $? ". log file time"
+ if (dk4str_is_on(pv)) {
+ app->log_file_time = 1;
+ } else {
+ app->log_file_time = 0;
+ }
+ } break;
+ case 10: { $? ". ui lang"
+ if (NULL != pv) {
+ dkChar *plang;
+ dkChar *preg;
+ dkChar *nlang;
+ dkChar *nreg;
+ /* Remove encoding stuff */
+ plang = dk4str_chr(pv, dkT('.'));
+ if (NULL != plang) { *plang = dkT('\0'); }
+ plang = dk4str_start(pv, NULL);
+ if (NULL != plang) {
+ preg = dk4str_chr(plang, dkT('_'));
+ if (NULL != preg) {
+ *(preg++) = dkT('\0');
+ preg = dk4str_start(preg, NULL);
+ }
+ nlang = dk4str_dup(plang, NULL);
+ if (NULL != nlang) {
+ dk4mem_release(app->language);
+ app->language = nlang;
+ } else {
+ if (0 == ae->error_found) { ae->error_found = E_MEMORY; }
+ }
+ if (NULL != preg) {
+ nreg = dk4str_dup(preg, NULL);
+ if (NULL != nreg) {
+ dk4mem_release(app->region);
+ app->region = nreg;
+ } else {
+ if (0 == ae->error_found) { ae->error_found = E_MEMORY; }
+ }
+ }
+ }
+ }
+ } break;
+ }
+ }
+ } $? "- dk4app_pref_apply"
+}
+
+
+
+
diff --git a/support/dktools/dk4aprgs.c b/support/dktools/dk4aprgs.c
new file mode 100644
index 0000000000..a101598795
--- /dev/null
+++ b/support/dktools/dk4aprgs.c
@@ -0,0 +1,357 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4aprgs.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4aprgs.c The dk4aprgs module.
+*/
+
+
+#line 10 "dk4aprgs.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4app.h"
+#include "dk4pref.h"
+#include "dk4strd.h"
+#include "dk4appi.c"
+#include "dk4mem.h"
+#include "dk4enc.h"
+#include "dk4maidddi.h"
+#include "dk4maidddu.h"
+#include "dk4maiddsz.h"
+#include "dk4maodd.h"
+
+
+
+
+
+#line 27 "dk4aprgs.ctr"
+
+
+
+int
+dk4app_pref_get(
+ dkChar *dptr,
+ size_t szdptr,
+ dk4_app_t *app,
+ const dkChar *name,
+ int excl
+)
+{
+ dk4_pref_t *pptr = NULL;
+ int back = 0;
+
+
+#line 42 "dk4aprgs.ctr"
+ if ((NULL != dptr) && (0 < szdptr) && (NULL != app) && (NULL != name)) {
+ if (0 == (excl & DK4_APP_PREF_SRC_SELF)) {
+ pptr = dk4sto_it_find_like(app->i_pref_self, name, 1);
+ }
+ if ((NULL == pptr) && (0 == (excl & DK4_APP_PREF_SRC_CMD))) {
+ pptr = dk4sto_it_find_like(app->i_pref_cmd, name, 1);
+ }
+ if ((NULL == pptr) && (0 == (excl & DK4_APP_PREF_SRC_USER))) {
+ pptr = dk4sto_it_find_like(app->i_pref_user, name, 1);
+ }
+ if ((NULL == pptr) && (0 == (excl & DK4_APP_PREF_SRC_SYSTEM))) {
+ pptr = dk4sto_it_find_like(app->i_pref_sys, name, 1);
+ }
+ if (NULL != pptr) {
+ if (0 != dk4str_cpy_s(dptr, szdptr, pptr->value, NULL)) {
+ back = 1;
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ dk4app_log_base5(app,DK4_LL_DEBUG,160,161,162,name,pptr->value);
+ }
+ } else {
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ dk4app_log_base5(app,DK4_LL_DEBUG,163,164,165,name,pptr->value);
+ }
+ }
+ } else {
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ dk4app_log_base3(app, DK4_LL_DEBUG, 166, 167, name);
+ }
+ }
+ }
+
+#line 72 "dk4aprgs.ctr"
+ return back;
+}
+
+
+
+int
+dk4app_pref_get_int(
+ dk4_im_t *dptr,
+ dk4_app_t *app,
+ const dkChar *name,
+ int excl
+)
+{
+ dkChar buf[64];
+ const dkChar *endptr;
+ dk4_im_t val;
+ int back = 0;
+
+
+#line 90 "dk4aprgs.ctr"
+ if (NULL != dptr) {
+ if (0 != dk4app_pref_get(buf, DK4_SIZEOF(buf,dkChar), app, name, excl)) {
+ endptr = NULL;
+ val = (dk4_im_t)0L;
+ back = dk4ma_input_dk_dec_dk4_im_t(&val, buf, &endptr, 1, NULL);
+ if (0 != back) { *dptr = val; }
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ if ((NULL != app->msg_debug) && (43 < app->sz_msg_debug)) {
+ dk4app_log_1(
+ app, app->msg_debug, app->sz_msg_debug, DK4_LL_DEBUG,
+ ((0 != back) ? 42 : 43)
+ );
+ }
+ }
+ }
+ }
+ }
+
+#line 108 "dk4aprgs.ctr"
+ return back;
+}
+
+
+
+int
+dk4app_pref_get_unsigned(
+ dk4_um_t *dptr,
+ dk4_app_t *app,
+ const dkChar *name,
+ int excl
+)
+{
+ dkChar buf[64];
+ const dkChar *endptr;
+ dk4_um_t val;
+ int back = 0;
+
+
+#line 126 "dk4aprgs.ctr"
+ if (NULL != dptr) {
+ if (0 != dk4app_pref_get(buf, DK4_SIZEOF(buf,dkChar), app, name, excl)) {
+ endptr = NULL;
+ val = (dk4_um_t)0UL;
+ back = dk4ma_input_dk_dec_dk4_um_t(&val, buf, &endptr, 1, NULL);
+ if (0 != back) { *dptr = val; }
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ if ((NULL != app->msg_debug) && (45 < app->sz_msg_debug)) {
+ dk4app_log_1(
+ app, app->msg_debug, app->sz_msg_debug, DK4_LL_DEBUG,
+ ((0 != back) ? 44 : 45)
+ );
+ }
+ }
+ }
+
+ }
+ }
+
+#line 145 "dk4aprgs.ctr"
+ return back;
+}
+
+
+
+int
+dk4app_pref_get_bool(
+ int *dptr,
+ dk4_app_t *app,
+ const dkChar *name,
+ int excl
+)
+{
+ dkChar buf[64];
+ int back = 0;
+
+
+#line 161 "dk4aprgs.ctr"
+ if (NULL != dptr) {
+ if (0 != dk4app_pref_get(buf, DK4_SIZEOF(buf,dkChar), app, name, excl)) {
+ if (0 != dk4str_is_bool(buf)) {
+ if (0 != dk4str_is_on(buf)) {
+ *dptr = 1;
+ } else {
+ *dptr = 0;
+ }
+ back = 1;
+ }
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ if ((NULL != app->msg_debug) && (47 < app->sz_msg_debug)) {
+ dk4app_log_1(
+ app, app->msg_debug, app->sz_msg_debug, DK4_LL_DEBUG,
+ ((0 != back) ? 46 : 47)
+ );
+ }
+ }
+ }
+ }
+ }
+
+#line 183 "dk4aprgs.ctr"
+ return back;
+}
+
+
+
+int
+dk4app_pref_get_size(
+ size_t *dptr,
+ dk4_app_t *app,
+ const dkChar *name,
+ int excl
+)
+{
+ dkChar buf[64];
+ const dkChar *endptr;
+ size_t val;
+ int back = 0;
+
+
+#line 201 "dk4aprgs.ctr"
+ if (NULL != dptr) {
+ if (0 != dk4app_pref_get(buf, DK4_SIZEOF(buf,dkChar), app, name, excl)) {
+ endptr = NULL;
+ val = 0;
+ back = dk4ma_input_dk_dec_size_t(&val, buf, &endptr, 1, NULL);
+ if (0 != back) { *dptr = val; }
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ if ((NULL != app->msg_debug) && (49 < app->sz_msg_debug)) {
+ dk4app_log_1(
+ app, app->msg_debug, app->sz_msg_debug, DK4_LL_DEBUG,
+ ((0 != back) ? 48 : 49)
+ );
+ }
+ }
+ }
+ }
+ }
+
+#line 219 "dk4aprgs.ctr"
+ return back;
+}
+
+
+
+int
+dk4app_pref_set(
+ dk4_app_t *app,
+ const dkChar *name,
+ const dkChar *value
+)
+{
+ dk4_pref_t *prefptr;
+ dkChar *newval;
+ int back = 0;
+
+
+#line 235 "dk4aprgs.ctr"
+ if ((NULL != app) && (NULL != name) && (NULL != value)) {
+ prefptr = dk4sto_it_find_like(app->i_pref_self, name, 1);
+ if (NULL != prefptr) {
+ newval = dk4str_dup(value, NULL);
+ if (NULL != newval) {
+ dk4mem_release(prefptr->value);
+ prefptr->value = newval;
+ back = 1;
+ app->have_self_pref = 1;
+ }
+ } else {
+ prefptr = dk4pref_open(name, value, NULL);
+ if (NULL != prefptr) {
+ if (dk4sto_add(app->s_pref_self, prefptr, NULL)) {
+ back = 1;
+ app->have_self_pref = 1;
+ } else {
+ dk4pref_close(prefptr);
+ }
+ }
+ }
+ }
+
+#line 257 "dk4aprgs.ctr"
+ return back;
+}
+
+
+
+int
+dk4app_pref_set_int(dk4_app_t *app, const dkChar *name, dk4_im_t value)
+{
+ dkChar buf[16*sizeof(dk4_im_t)];
+ int back = 0;
+
+
+#line 268 "dk4aprgs.ctr"
+ if ((NULL != app) && (NULL != name)) {
+ if (dk4ma_write_decimal_signed(buf,DK4_SIZEOF(buf,dkChar),value,0,NULL)) {
+ back = dk4app_pref_set(app, name, buf);
+ }
+ }
+
+#line 273 "dk4aprgs.ctr"
+ return back;
+}
+
+
+
+int
+dk4app_pref_set_unsigned(dk4_app_t *app, const dkChar *name, dk4_um_t value)
+{
+ dkChar buf[16*sizeof(dk4_um_t)];
+ int back = 0;
+
+
+#line 284 "dk4aprgs.ctr"
+ if ((NULL != app) && (NULL != name)) {
+ if (dk4ma_write_decimal_unsigned(buf,DK4_SIZEOF(buf,dkChar),value,0,NULL))
+ {
+ back = dk4app_pref_set(app, name, buf);
+ }
+ }
+
+#line 290 "dk4aprgs.ctr"
+ return back;
+}
+
diff --git a/support/dktools/dk4aprgs.ctr b/support/dktools/dk4aprgs.ctr
new file mode 100644
index 0000000000..4224683506
--- /dev/null
+++ b/support/dktools/dk4aprgs.ctr
@@ -0,0 +1,292 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4app.h"
+#include "dk4pref.h"
+#include "dk4strd.h"
+#include "dk4appi.c"
+#include "dk4mem.h"
+#include "dk4enc.h"
+#include "dk4maidddi.h"
+#include "dk4maidddu.h"
+#include "dk4maiddsz.h"
+#include "dk4maodd.h"
+
+
+
+$!trace-include
+
+
+
+int
+dk4app_pref_get(
+ dkChar *dptr,
+ size_t szdptr,
+ dk4_app_t *app,
+ const dkChar *name,
+ int excl
+)
+{
+ dk4_pref_t *pptr = NULL;
+ int back = 0;
+ $? "+ dk4app_pref_get \"%!ds\"", TR_DKSTR(name)
+ if ((NULL != dptr) && (0 < szdptr) && (NULL != app) && (NULL != name)) {
+ if (0 == (excl & DK4_APP_PREF_SRC_SELF)) {
+ pptr = dk4sto_it_find_like(app->i_pref_self, name, 1);
+ }
+ if ((NULL == pptr) && (0 == (excl & DK4_APP_PREF_SRC_CMD))) {
+ pptr = dk4sto_it_find_like(app->i_pref_cmd, name, 1);
+ }
+ if ((NULL == pptr) && (0 == (excl & DK4_APP_PREF_SRC_USER))) {
+ pptr = dk4sto_it_find_like(app->i_pref_user, name, 1);
+ }
+ if ((NULL == pptr) && (0 == (excl & DK4_APP_PREF_SRC_SYSTEM))) {
+ pptr = dk4sto_it_find_like(app->i_pref_sys, name, 1);
+ }
+ if (NULL != pptr) {
+ if (0 != dk4str_cpy_s(dptr, szdptr, pptr->value, NULL)) {
+ back = 1;
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ dk4app_log_base5(app,DK4_LL_DEBUG,160,161,162,name,pptr->value);
+ }
+ } else {
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ dk4app_log_base5(app,DK4_LL_DEBUG,163,164,165,name,pptr->value);
+ }
+ }
+ } else {
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ dk4app_log_base3(app, DK4_LL_DEBUG, 166, 167, name);
+ }
+ }
+ } $? "- dk4app_pref_get %d", back
+ return back;
+}
+
+
+
+int
+dk4app_pref_get_int(
+ dk4_im_t *dptr,
+ dk4_app_t *app,
+ const dkChar *name,
+ int excl
+)
+{
+ dkChar buf[64];
+ const dkChar *endptr;
+ dk4_im_t val;
+ int back = 0;
+ $? "+ dk4app_pref_get_int"
+ if (NULL != dptr) {
+ if (0 != dk4app_pref_get(buf, DK4_SIZEOF(buf,dkChar), app, name, excl)) {
+ endptr = NULL;
+ val = (dk4_im_t)0L;
+ back = dk4ma_input_dk_dec_dk4_im_t(&val, buf, &endptr, 1, NULL);
+ if (0 != back) { *dptr = val; }
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ if ((NULL != app->msg_debug) && (43 < app->sz_msg_debug)) {
+ dk4app_log_1(
+ app, app->msg_debug, app->sz_msg_debug, DK4_LL_DEBUG,
+ ((0 != back) ? 42 : 43)
+ );
+ }
+ }
+ }
+ }
+ } $? "- dk4app_pref_get_int %d", back
+ return back;
+}
+
+
+
+int
+dk4app_pref_get_unsigned(
+ dk4_um_t *dptr,
+ dk4_app_t *app,
+ const dkChar *name,
+ int excl
+)
+{
+ dkChar buf[64];
+ const dkChar *endptr;
+ dk4_um_t val;
+ int back = 0;
+ $? "+ dk4app_pref_get_unsigned"
+ if (NULL != dptr) {
+ if (0 != dk4app_pref_get(buf, DK4_SIZEOF(buf,dkChar), app, name, excl)) {
+ endptr = NULL;
+ val = (dk4_um_t)0UL;
+ back = dk4ma_input_dk_dec_dk4_um_t(&val, buf, &endptr, 1, NULL);
+ if (0 != back) { *dptr = val; }
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ if ((NULL != app->msg_debug) && (45 < app->sz_msg_debug)) {
+ dk4app_log_1(
+ app, app->msg_debug, app->sz_msg_debug, DK4_LL_DEBUG,
+ ((0 != back) ? 44 : 45)
+ );
+ }
+ }
+ }
+
+ }
+ } $? "- dk4app_pref_get_unsigned %d", back
+ return back;
+}
+
+
+
+int
+dk4app_pref_get_bool(
+ int *dptr,
+ dk4_app_t *app,
+ const dkChar *name,
+ int excl
+)
+{
+ dkChar buf[64];
+ int back = 0;
+ $? "+ dk4app_pref_get_bool"
+ if (NULL != dptr) {
+ if (0 != dk4app_pref_get(buf, DK4_SIZEOF(buf,dkChar), app, name, excl)) {
+ if (0 != dk4str_is_bool(buf)) {
+ if (0 != dk4str_is_on(buf)) {
+ *dptr = 1;
+ } else {
+ *dptr = 0;
+ }
+ back = 1;
+ }
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ if ((NULL != app->msg_debug) && (47 < app->sz_msg_debug)) {
+ dk4app_log_1(
+ app, app->msg_debug, app->sz_msg_debug, DK4_LL_DEBUG,
+ ((0 != back) ? 46 : 47)
+ );
+ }
+ }
+ }
+ }
+ } $? "- dk4app_pref_get_bool %d", back
+ return back;
+}
+
+
+
+int
+dk4app_pref_get_size(
+ size_t *dptr,
+ dk4_app_t *app,
+ const dkChar *name,
+ int excl
+)
+{
+ dkChar buf[64];
+ const dkChar *endptr;
+ size_t val;
+ int back = 0;
+ $? "+ dk4app_pref_get_size"
+ if (NULL != dptr) {
+ if (0 != dk4app_pref_get(buf, DK4_SIZEOF(buf,dkChar), app, name, excl)) {
+ endptr = NULL;
+ val = 0;
+ back = dk4ma_input_dk_dec_size_t(&val, buf, &endptr, 1, NULL);
+ if (0 != back) { *dptr = val; }
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ if ((NULL != app->msg_debug) && (49 < app->sz_msg_debug)) {
+ dk4app_log_1(
+ app, app->msg_debug, app->sz_msg_debug, DK4_LL_DEBUG,
+ ((0 != back) ? 48 : 49)
+ );
+ }
+ }
+ }
+ }
+ } $? "- dk4app_pref_get_size %d", back
+ return back;
+}
+
+
+
+int
+dk4app_pref_set(
+ dk4_app_t *app,
+ const dkChar *name,
+ const dkChar *value
+)
+{
+ dk4_pref_t *prefptr;
+ dkChar *newval;
+ int back = 0;
+ $? "+ dk4app_pref_set"
+ if ((NULL != app) && (NULL != name) && (NULL != value)) {
+ prefptr = dk4sto_it_find_like(app->i_pref_self, name, 1);
+ if (NULL != prefptr) {
+ newval = dk4str_dup(value, NULL);
+ if (NULL != newval) {
+ dk4mem_release(prefptr->value);
+ prefptr->value = newval;
+ back = 1;
+ app->have_self_pref = 1;
+ }
+ } else {
+ prefptr = dk4pref_open(name, value, NULL);
+ if (NULL != prefptr) {
+ if (dk4sto_add(app->s_pref_self, prefptr, NULL)) {
+ back = 1;
+ app->have_self_pref = 1;
+ } else {
+ dk4pref_close(prefptr);
+ }
+ }
+ }
+ } $? "- dk4app_pref_set %d", back
+ return back;
+}
+
+
+
+int
+dk4app_pref_set_int(dk4_app_t *app, const dkChar *name, dk4_im_t value)
+{
+ dkChar buf[16*sizeof(dk4_im_t)];
+ int back = 0;
+ $? "+ dk4app_pref_set_int"
+ if ((NULL != app) && (NULL != name)) {
+ if (dk4ma_write_decimal_signed(buf,DK4_SIZEOF(buf,dkChar),value,0,NULL)) {
+ back = dk4app_pref_set(app, name, buf);
+ }
+ } $? "- dk4app_pref_set_int %d", back
+ return back;
+}
+
+
+
+int
+dk4app_pref_set_unsigned(dk4_app_t *app, const dkChar *name, dk4_um_t value)
+{
+ dkChar buf[16*sizeof(dk4_um_t)];
+ int back = 0;
+ $? "+ dk4app_pref_set_unsigned"
+ if ((NULL != app) && (NULL != name)) {
+ if (dk4ma_write_decimal_unsigned(buf,DK4_SIZEOF(buf,dkChar),value,0,NULL))
+ {
+ back = dk4app_pref_set(app, name, buf);
+ }
+ } $? "- dk4app_pref_set_unsigned %d", back
+ return back;
+}
+
diff --git a/support/dktools/dk4bf.c b/support/dktools/dk4bf.c
new file mode 100644
index 0000000000..8fba829e7e
--- /dev/null
+++ b/support/dktools/dk4bf.c
@@ -0,0 +1,151 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4bf.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4bf.c The dk4bf module.
+*/
+
+
+#line 85 "dk4bf.ctr"
+
+
+#include "dk4bf.h"
+#include "dk4mem.h"
+
+
+
+
+
+#line 93 "dk4bf.ctr"
+
+
+
+/** Position of single bits within a byte.
+*/
+static const unsigned char dk4bf_bits_in_byte[] = {
+ 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
+};
+
+
+
+dk4_bit_field_t *
+dk4bf_open(size_t sz, dk4_er_t *erp)
+{
+ dk4_bit_field_t *back = NULL;
+ size_t bsz;
+ if (0 < sz) {
+ back = dk4mem_new(dk4_bit_field_t,1,erp);
+ if (NULL != back) {
+ back->s = sz;
+ bsz = sz / 8;
+ if (0 != (sz % 8)) {
+ bsz++;
+ }
+ back->d = dk4mem_new(unsigned char,bsz,erp);
+ if (NULL == back->d) {
+ dk4bf_close(back);
+ back = NULL;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4bf_set(dk4_bit_field_t *dptr, size_t bitno, int val, dk4_er_t *erp)
+{
+ size_t bytei; /* Byte index */
+ size_t biti; /* Bit index */
+ int back = 0;
+ if (NULL != dptr) {
+ if (bitno < dptr->s) {
+ bytei = bitno / 8;
+ biti = bitno % 8;
+ if (0 != val) {
+ (dptr->d)[bytei] |= dk4bf_bits_in_byte[biti];
+ } else {
+ (dptr->d)[bytei] &= (~(dk4bf_bits_in_byte[biti]));
+ }
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4bf_get(int *dptr, dk4_bit_field_t *bfptr, size_t bitno, dk4_er_t *erp)
+{
+ size_t bytei; /* Byte index */
+ size_t biti; /* Bit index within byte */
+ int back = 0;
+ if ((NULL != dptr) && (NULL != bfptr)) {
+ if (bitno < bfptr->s) {
+ bytei = bitno / 8;
+ biti = bitno % 8;
+ if (0x00 != (((bfptr->d)[bytei]) & (dk4bf_bits_in_byte[biti]))) {
+ *dptr = 1;
+ } else {
+ *dptr = 0;
+ }
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+void
+dk4bf_close(dk4_bit_field_t *ptr)
+{
+ if (NULL != ptr) {
+ dk4mem_release(ptr->d);
+ dk4mem_free(ptr);
+ }
+}
+
diff --git a/support/dktools/dk4bf.ctr b/support/dktools/dk4bf.ctr
new file mode 100644
index 0000000000..917f76185e
--- /dev/null
+++ b/support/dktools/dk4bf.ctr
@@ -0,0 +1,193 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk4bf.h Bit fields.
+*/
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+/** Bit field structure.
+*/
+typedef struct {
+ unsigned char *d; /**< Data buffer. */
+ size_t s; /**< Number of bits in the array. */
+} dk4_bit_field_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open bit field.
+ @param sz Size of the bit field (number of bits).
+ @param erp Error report, may be NULL.
+ @return Pointer to new bit field on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if sz is 0,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if not enough memory was available.
+*/
+dk4_bit_field_t *
+dk4bf_open(size_t sz, dk4_er_t *erp);
+
+/** Set one bit in a bit field.
+ @param dptr Bit field.
+ @param bitno Index of bit to modify.
+ @param val Bit value.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is 0 or bitno is outside the bit field size.
+*/
+int
+dk4bf_set(dk4_bit_field_t *dptr, size_t bitno, int val, dk4_er_t *erp);
+
+/** Retrieve one value from bit field.
+ @param dptr Address of result variable.
+ @param bfptr Bit field.
+ @param bitno Number of bit to obtain.
+ @param erp Error report, may be NULL.
+ @return 1 on success (dptr set), 0 on error (dptr unchanged).
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or bfptr is NULL or bitno is outside the bit field size.
+*/
+int
+dk4bf_get(int *dptr, dk4_bit_field_t *bfptr, size_t bitno, dk4_er_t *erp);
+
+/** Close bit field.
+ @param ptr Pointer to bit field previously opened using
+ dk4bf_open().
+*/
+void
+dk4bf_close(dk4_bit_field_t *ptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+
+#include "dk4bf.h"
+#include "dk4mem.h"
+
+
+
+$!trace-include
+
+
+
+/** Position of single bits within a byte.
+*/
+static const unsigned char dk4bf_bits_in_byte[] = {
+ 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
+};
+
+
+
+dk4_bit_field_t *
+dk4bf_open(size_t sz, dk4_er_t *erp)
+{
+ dk4_bit_field_t *back = NULL;
+ size_t bsz;
+ if (0 < sz) {
+ back = dk4mem_new(dk4_bit_field_t,1,erp);
+ if (NULL != back) {
+ back->s = sz;
+ bsz = sz / 8;
+ if (0 != (sz % 8)) {
+ bsz++;
+ }
+ back->d = dk4mem_new(unsigned char,bsz,erp);
+ if (NULL == back->d) {
+ dk4bf_close(back);
+ back = NULL;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4bf_set(dk4_bit_field_t *dptr, size_t bitno, int val, dk4_er_t *erp)
+{
+ size_t bytei; /* Byte index */
+ size_t biti; /* Bit index */
+ int back = 0;
+ if (NULL != dptr) {
+ if (bitno < dptr->s) {
+ bytei = bitno / 8;
+ biti = bitno % 8;
+ if (0 != val) {
+ (dptr->d)[bytei] |= dk4bf_bits_in_byte[biti];
+ } else {
+ (dptr->d)[bytei] &= (~(dk4bf_bits_in_byte[biti]));
+ }
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4bf_get(int *dptr, dk4_bit_field_t *bfptr, size_t bitno, dk4_er_t *erp)
+{
+ size_t bytei; /* Byte index */
+ size_t biti; /* Bit index within byte */
+ int back = 0;
+ if ((NULL != dptr) && (NULL != bfptr)) {
+ if (bitno < bfptr->s) {
+ bytei = bitno / 8;
+ biti = bitno % 8;
+ if (0x00 != (((bfptr->d)[bytei]) & (dk4bf_bits_in_byte[biti]))) {
+ *dptr = 1;
+ } else {
+ *dptr = 0;
+ }
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+void
+dk4bf_close(dk4_bit_field_t *ptr)
+{
+ if (NULL != ptr) {
+ dk4mem_release(ptr->d);
+ dk4mem_free(ptr);
+ }
+}
+
diff --git a/support/dktools/dk4bf.h b/support/dktools/dk4bf.h
new file mode 100644
index 0000000000..4d96a8adfa
--- /dev/null
+++ b/support/dktools/dk4bf.h
@@ -0,0 +1,117 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4bf.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4BF_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4BF_H_INCLUDED 1
+
+
+#line 10 "dk4bf.ctr"
+
+/** @file dk4bf.h Bit fields.
+*/
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+/** Bit field structure.
+*/
+typedef struct {
+ unsigned char *d; /**< Data buffer. */
+ size_t s; /**< Number of bits in the array. */
+} dk4_bit_field_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open bit field.
+ @param sz Size of the bit field (number of bits).
+ @param erp Error report, may be NULL.
+ @return Pointer to new bit field on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if sz is 0,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if not enough memory was available.
+*/
+dk4_bit_field_t *
+dk4bf_open(size_t sz, dk4_er_t *erp);
+
+/** Set one bit in a bit field.
+ @param dptr Bit field.
+ @param bitno Index of bit to modify.
+ @param val Bit value.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is 0 or bitno is outside the bit field size.
+*/
+int
+dk4bf_set(dk4_bit_field_t *dptr, size_t bitno, int val, dk4_er_t *erp);
+
+/** Retrieve one value from bit field.
+ @param dptr Address of result variable.
+ @param bfptr Bit field.
+ @param bitno Number of bit to obtain.
+ @param erp Error report, may be NULL.
+ @return 1 on success (dptr set), 0 on error (dptr unchanged).
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or bfptr is NULL or bitno is outside the bit field size.
+*/
+int
+dk4bf_get(int *dptr, dk4_bit_field_t *bfptr, size_t bitno, dk4_er_t *erp);
+
+/** Close bit field.
+ @param ptr Pointer to bit field previously opened using
+ dk4bf_open().
+*/
+void
+dk4bf_close(dk4_bit_field_t *ptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4binenc.c b/support/dktools/dk4binenc.c
new file mode 100644
index 0000000000..597dad1eb0
--- /dev/null
+++ b/support/dktools/dk4binenc.c
@@ -0,0 +1,258 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4binenc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4binenc.c The dk4binenc module.
+*/
+
+
+#line 94 "dk4binenc.ctr"
+
+#include "dk4binenc.h"
+#include "dk4mem.h"
+#include "dk4memrs.h"
+#include "dk4a85e.h"
+#include "dk4maasz.h"
+#include "dk4strd.h"
+#include "dk4edstm.h"
+
+
+
+
+
+#line 106 "dk4binenc.ctr"
+
+
+
+/** Hexadecimal digits.
+*/
+static const char dk4binenc_hex_digits[] = { "0123456789abcdef" };
+
+
+
+/** Message digest type names.
+ Order must match the definition order in the enum in dk4md.h.
+*/
+static const dkChar * const dk4binenc_encoding_names[] = {
+/* 0 */
+dkT("bin"),
+
+/* 1 */
+dkT("binary"),
+
+/* 2 */
+dkT("hex"),
+
+/* 3 */
+dkT("hexa"),
+
+/* 4 */
+dkT("hexadecimal"),
+
+/* 5 */
+dkT("ascii-85"),
+
+/* 6 */
+dkT("ascii85"),
+
+/* 7 */
+dkT("a85"),
+
+NULL
+
+
+#line 129 "dk4binenc.ctr"
+};
+
+
+
+int
+dk4binenc(
+ char *dptr,
+ size_t szdptr,
+ const void *sptr,
+ size_t szsptr,
+ int enc,
+ dk4_er_t *erp
+)
+{
+ dk4_a85_enc_t a85;
+ dk4_er_t maerr;
+ const unsigned char *ucptr;
+ const char *resptr;
+ size_t ressize;
+ size_t oused;
+ size_t noused;
+ int back = 0;
+ if ((NULL != dptr) && (NULL != sptr) && (0 < szdptr) && (0 < szsptr)) {
+ switch (enc) {
+ case DK4_BINARY_TO_TEXT_ENCODING_NONE : {
+ if (szdptr >= szsptr) {
+ DK4_MEMCPY(dptr, sptr, szsptr);
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_HEX : {
+ oused = 0;
+ ucptr = (const unsigned char *)sptr;
+ while (szsptr--) {
+ dk4error_init(&maerr);
+ noused = dk4ma_size_t_add(oused, 2, &maerr);
+ if (DK4_E_NONE == maerr.ec) {
+ dptr[oused] =
+ dk4binenc_hex_digits[(size_t)((((unsigned)(*ucptr)) >> 4) & 0x0FU)];
+ dptr[oused+1] =
+ dk4binenc_hex_digits[(size_t)(((unsigned)(*ucptr)) & 0x0FU)];
+ oused = noused;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ goto finished;
+ }
+ ucptr++;
+ }
+ if (oused < szdptr) {
+ dptr[oused] = '\0';
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_A85 : {
+ oused = 0;
+ ucptr = (const unsigned char *)sptr;
+ dk4a85_enc_init(&a85, 0, erp);
+ while(szsptr--) {
+ switch (dk4a85_enc_add(&a85, *(ucptr++), erp)) {
+ case DK4_EDSTM_FINISHED : {
+ resptr = NULL; ressize = 0;
+ (void)dk4a85_enc_output(&resptr, &ressize, &a85, NULL);
+ if ((NULL != resptr) && (0 < ressize)) {
+ dk4error_init(&maerr);
+ noused = dk4ma_size_t_add(oused, ressize, &maerr);
+ if (DK4_E_NONE == maerr.ec) {
+ if (noused < szdptr) {
+ DK4_MEMCPY(&(dptr[oused]), resptr, ressize);
+ oused = noused;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ goto finished;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ goto finished;
+ }
+ }
+ } break;
+ case DK4_EDSTM_ERROR : {
+ dk4error_set_simple_error_code(erp, DK4_E_ENCODING_FAILED);
+ goto finished;
+ } break;
+ }
+ }
+ switch (dk4a85_enc_finish(&a85, erp)) {
+ case DK4_EDSTM_FINISHED : {
+ resptr = NULL; ressize = 0;
+ (void)dk4a85_enc_output(&resptr, &ressize, &a85, NULL);
+ if ((NULL != resptr) && (0 < ressize)) {
+ dk4error_init(&maerr);
+ noused = dk4ma_size_t_add(oused, ressize, &maerr);
+ if (DK4_E_NONE == maerr.ec) {
+ if (noused < szdptr) {
+ DK4_MEMCPY(&(dptr[oused]), resptr, ressize);
+ oused = noused;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ goto finished;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ goto finished;
+ }
+ }
+ } break;
+ case DK4_EDSTM_ERROR : {
+ dk4error_set_simple_error_code(erp, DK4_E_ENCODING_FAILED);
+ goto finished;
+ } break;
+ }
+ if (oused < szdptr) {
+ dptr[oused] = '\0';
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ (void)dk4mem_reset_secure(&a85, sizeof(dk4_a85_enc_t), NULL);
+ } break;
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ finished:
+ if ((NULL != dptr) && (0 == back)) { *dptr = '\0'; }
+ return back;
+}
+
+
+
+int
+dk4binenc_choose_encoding(const dkChar *name, dk4_er_t *erp)
+{
+
+ int back = -1;
+ if (NULL != name) {
+ switch (dk4str_array_index(dk4binenc_encoding_names, name, 0)) {
+ case 0: case 1: {
+ back = DK4_BINARY_TO_TEXT_ENCODING_NONE;
+ } break;
+ case 2: case 3: case 4: {
+ back = DK4_BINARY_TO_TEXT_ENCODING_HEX;
+ } break;
+ case 5: case 6: case 7: {
+ back = DK4_BINARY_TO_TEXT_ENCODING_A85;
+ } break;
+ }
+ if (-1 == back) {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4binenc.ctr b/support/dktools/dk4binenc.ctr
new file mode 100644
index 0000000000..a46470ca4c
--- /dev/null
+++ b/support/dktools/dk4binenc.ctr
@@ -0,0 +1,291 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk4binenc.h Encode binary data to text.
+*/
+
+#include "dk4error.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Encode binary data to text.
+ Data is saved as text string including finalizing 0 byte
+ except for DK4_BINARY_TO_TEXT_ENCODING_NONE.
+ @param dptr Destination buffer address.
+ @param szdptr Destination buffer size.
+ @param sptr Source buffer address.
+ @param szsptr Source buffer size.
+ @param enc Encoding, one from
+ DK4_BINARY_TO_TEXT_ENCODING_NONE,
+ DK4_BINARY_TO_TEXT_ENCODING_HEX,
+ or DK4_BINARY_TO_TEXT_ENCODING_A85.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or sptr is NULL or szdptr or szsptr is 0 or an illegal
+ enc value was specified,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the provided destination buffer is too small,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in size calculation
+ (required destination buffer size too large),
+ - DK4_E_ENCODING_FAILED<br>
+ if encoding failed for a byte.
+*/
+int
+dk4binenc(
+ char *dptr,
+ size_t szdptr,
+ const void *sptr,
+ size_t szsptr,
+ int enc,
+ dk4_er_t *erp
+);
+
+/** Find numeric encoding type for an encoding name.
+ @param name String containing encoding name.
+ @param erp Error report, may be NULL.
+ @return Non-negative numeric encoding type on success, -1 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if name is NULL,
+ - DK4_E_SYNTAX<br>
+ if name is not a valid encoding name.
+*/
+int
+dk4binenc_choose_encoding(const dkChar *name, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** Message digest encodings.
+*/
+enum {
+ /** No encoding, use binary
+ data directly.
+ */
+ DK4_BINARY_TO_TEXT_ENCODING_NONE = 0,
+
+ /** ASCII-Hex encoding.
+ */
+ DK4_BINARY_TO_TEXT_ENCODING_HEX ,
+
+ /** ASCII-85 encoding.
+ */
+ DK4_BINARY_TO_TEXT_ENCODING_A85
+};
+
+
+
+%% module
+
+#include "dk4binenc.h"
+#include "dk4mem.h"
+#include "dk4memrs.h"
+#include "dk4a85e.h"
+#include "dk4maasz.h"
+#include "dk4strd.h"
+#include "dk4edstm.h"
+
+
+
+$!trace-include
+
+
+
+/** Hexadecimal digits.
+*/
+static const char dk4binenc_hex_digits[] = { "0123456789abcdef" };
+
+
+
+/** Message digest type names.
+ Order must match the definition order in the enum in dk4md.h.
+*/
+static const dkChar * const dk4binenc_encoding_names[] = {
+$!string-table macro=dkT
+bin
+binary
+hex
+hexa
+hexadecimal
+ascii-85
+ascii85
+a85
+$!end
+};
+
+
+
+int
+dk4binenc(
+ char *dptr,
+ size_t szdptr,
+ const void *sptr,
+ size_t szsptr,
+ int enc,
+ dk4_er_t *erp
+)
+{
+ dk4_a85_enc_t a85;
+ dk4_er_t maerr;
+ const unsigned char *ucptr;
+ const char *resptr;
+ size_t ressize;
+ size_t oused;
+ size_t noused;
+ int back = 0;
+ if ((NULL != dptr) && (NULL != sptr) && (0 < szdptr) && (0 < szsptr)) {
+ switch (enc) {
+ case DK4_BINARY_TO_TEXT_ENCODING_NONE : {
+ if (szdptr >= szsptr) {
+ DK4_MEMCPY(dptr, sptr, szsptr);
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_HEX : {
+ oused = 0;
+ ucptr = (const unsigned char *)sptr;
+ while (szsptr--) {
+ dk4error_init(&maerr);
+ noused = dk4ma_size_t_add(oused, 2, &maerr);
+ if (DK4_E_NONE == maerr.ec) {
+ dptr[oused] =
+ dk4binenc_hex_digits[(size_t)((((unsigned)(*ucptr)) >> 4) & 0x0FU)];
+ dptr[oused+1] =
+ dk4binenc_hex_digits[(size_t)(((unsigned)(*ucptr)) & 0x0FU)];
+ oused = noused;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ goto finished;
+ }
+ ucptr++;
+ }
+ if (oused < szdptr) {
+ dptr[oused] = '\0';
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_A85 : {
+ oused = 0;
+ ucptr = (const unsigned char *)sptr;
+ dk4a85_enc_init(&a85, 0, erp);
+ while(szsptr--) {
+ switch (dk4a85_enc_add(&a85, *(ucptr++), erp)) {
+ case DK4_EDSTM_FINISHED : {
+ resptr = NULL; ressize = 0;
+ (void)dk4a85_enc_output(&resptr, &ressize, &a85, NULL);
+ if ((NULL != resptr) && (0 < ressize)) {
+ dk4error_init(&maerr);
+ noused = dk4ma_size_t_add(oused, ressize, &maerr);
+ if (DK4_E_NONE == maerr.ec) {
+ if (noused < szdptr) {
+ DK4_MEMCPY(&(dptr[oused]), resptr, ressize);
+ oused = noused;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ goto finished;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ goto finished;
+ }
+ }
+ } break;
+ case DK4_EDSTM_ERROR : {
+ dk4error_set_simple_error_code(erp, DK4_E_ENCODING_FAILED);
+ goto finished;
+ } break;
+ }
+ }
+ switch (dk4a85_enc_finish(&a85, erp)) {
+ case DK4_EDSTM_FINISHED : {
+ resptr = NULL; ressize = 0;
+ (void)dk4a85_enc_output(&resptr, &ressize, &a85, NULL);
+ if ((NULL != resptr) && (0 < ressize)) {
+ dk4error_init(&maerr);
+ noused = dk4ma_size_t_add(oused, ressize, &maerr);
+ if (DK4_E_NONE == maerr.ec) {
+ if (noused < szdptr) {
+ DK4_MEMCPY(&(dptr[oused]), resptr, ressize);
+ oused = noused;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ goto finished;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ goto finished;
+ }
+ }
+ } break;
+ case DK4_EDSTM_ERROR : {
+ dk4error_set_simple_error_code(erp, DK4_E_ENCODING_FAILED);
+ goto finished;
+ } break;
+ }
+ if (oused < szdptr) {
+ dptr[oused] = '\0';
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ (void)dk4mem_reset_secure(&a85, sizeof(dk4_a85_enc_t), NULL);
+ } break;
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ finished:
+ if ((NULL != dptr) && (0 == back)) { *dptr = '\0'; }
+ return back;
+}
+
+
+
+int
+dk4binenc_choose_encoding(const dkChar *name, dk4_er_t *erp)
+{
+
+ int back = -1;
+ if (NULL != name) {
+ switch (dk4str_array_index(dk4binenc_encoding_names, name, 0)) {
+ case 0: case 1: {
+ back = DK4_BINARY_TO_TEXT_ENCODING_NONE;
+ } break;
+ case 2: case 3: case 4: {
+ back = DK4_BINARY_TO_TEXT_ENCODING_HEX;
+ } break;
+ case 5: case 6: case 7: {
+ back = DK4_BINARY_TO_TEXT_ENCODING_A85;
+ } break;
+ }
+ if (-1 == back) {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4binenc.h b/support/dktools/dk4binenc.h
new file mode 100644
index 0000000000..4a2c480436
--- /dev/null
+++ b/support/dktools/dk4binenc.h
@@ -0,0 +1,126 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4binenc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4BINENC_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4BINENC_H_INCLUDED 1
+
+
+#line 10 "dk4binenc.ctr"
+
+/** @file dk4binenc.h Encode binary data to text.
+*/
+
+#include "dk4error.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Encode binary data to text.
+ Data is saved as text string including finalizing 0 byte
+ except for DK4_BINARY_TO_TEXT_ENCODING_NONE.
+ @param dptr Destination buffer address.
+ @param szdptr Destination buffer size.
+ @param sptr Source buffer address.
+ @param szsptr Source buffer size.
+ @param enc Encoding, one from
+ DK4_BINARY_TO_TEXT_ENCODING_NONE,
+ DK4_BINARY_TO_TEXT_ENCODING_HEX,
+ or DK4_BINARY_TO_TEXT_ENCODING_A85.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or sptr is NULL or szdptr or szsptr is 0 or an illegal
+ enc value was specified,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the provided destination buffer is too small,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in size calculation
+ (required destination buffer size too large),
+ - DK4_E_ENCODING_FAILED<br>
+ if encoding failed for a byte.
+*/
+int
+dk4binenc(
+ char *dptr,
+ size_t szdptr,
+ const void *sptr,
+ size_t szsptr,
+ int enc,
+ dk4_er_t *erp
+);
+
+/** Find numeric encoding type for an encoding name.
+ @param name String containing encoding name.
+ @param erp Error report, may be NULL.
+ @return Non-negative numeric encoding type on success, -1 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if name is NULL,
+ - DK4_E_SYNTAX<br>
+ if name is not a valid encoding name.
+*/
+int
+dk4binenc_choose_encoding(const dkChar *name, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** Message digest encodings.
+*/
+enum {
+ /** No encoding, use binary
+ data directly.
+ */
+ DK4_BINARY_TO_TEXT_ENCODING_NONE = 0,
+
+ /** ASCII-Hex encoding.
+ */
+ DK4_BINARY_TO_TEXT_ENCODING_HEX ,
+
+ /** ASCII-85 encoding.
+ */
+ DK4_BINARY_TO_TEXT_ENCODING_A85
+};
+
+
+
+
+#endif
diff --git a/support/dktools/dk4bitsh.c b/support/dktools/dk4bitsh.c
new file mode 100644
index 0000000000..bd3bbe3b05
--- /dev/null
+++ b/support/dktools/dk4bitsh.c
@@ -0,0 +1,149 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4bitsh.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4bitsh.c The dk4bitsh module.
+*/
+
+
+#line 89 "dk4bitsh.ctr"
+
+#include "dk4bitsh.h"
+#include "dk4edstm.h"
+#include "dk4mem.h"
+
+
+
+
+
+#line 97 "dk4bitsh.ctr"
+
+
+
+
+void
+dk4bit_shift_init(dk4_bit_shift_t *bs, dk4_er_t *erp)
+{
+ if (NULL != bs) {
+ DK4_MEMRES(bs, sizeof(dk4_bit_shift_t));
+ bs->pos = 0;
+ bs->obyte = 0x00;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+}
+
+
+
+int
+dk4bit_shift_add(dk4_bit_shift_t *bs, int bit, dk4_er_t *erp)
+{
+ int back = DK4_EDSTM_ERROR;
+ if (NULL != bs) {
+ back = DK4_EDSTM_ACCEPT;
+ switch (bs->pos) {
+ case 0: {
+ if (0 != bit) { bs->obyte = 0x80; } else { bs->obyte = 0x00; }
+ bs->pos = 1;
+ } break;
+ case 1: {
+ if (0 != bit) { bs->obyte |= 0x40; }
+ bs->pos = 2;
+ } break;
+ case 2: {
+ if (0 != bit) { bs->obyte |= 0x20; }
+ bs->pos = 3;
+ } break;
+ case 3: {
+ if (0 != bit) { bs->obyte |= 0x10; }
+ bs->pos = 4;
+ } break;
+ case 4: {
+ if (0 != bit) { bs->obyte |= 0x08; }
+ bs->pos = 5;
+ } break;
+ case 5: {
+ if (0 != bit) { bs->obyte |= 0x04; }
+ bs->pos = 6;
+ } break;
+ case 6: {
+ if (0 != bit) { bs->obyte |= 0x02; }
+ bs->pos = 7;
+ } break;
+ case 7: {
+ if (0 != bit) { bs->obyte |= 0x01; }
+ bs->pos = 0;
+ back = DK4_EDSTM_FINISHED;
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4bit_shift_finish(dk4_bit_shift_t *bs, dk4_er_t *erp)
+{
+ int back = DK4_EDSTM_ERROR;
+ if (NULL != bs) {
+ if (0 != bs->pos) {
+ back = DK4_EDSTM_FINISHED;
+ } else {
+ back = DK4_EDSTM_ACCEPT;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+unsigned char
+dk4bit_shift_output(dk4_bit_shift_t *bs, dk4_er_t *erp)
+{
+ unsigned char back;
+
+ if (NULL != bs) {
+ back = bs->obyte;
+ } else {
+ back = 0x00;
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4bitsh.ctr b/support/dktools/dk4bitsh.ctr
new file mode 100644
index 0000000000..a95b61ef0b
--- /dev/null
+++ b/support/dktools/dk4bitsh.ctr
@@ -0,0 +1,195 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk4bitsh.h Bit shifting.
+*/
+
+#include "dk4error.h"
+
+/** Bit shifter.
+*/
+typedef struct {
+ int pos; /**< Current bit position. */
+ unsigned char obyte; /**< Output byte. */
+} dk4_bit_shift_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Initialize a bit shifter before using it.
+ @param bs Bit shifter to initialize.
+ @param erp Error report, may be NULL.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS if bs is NULL.
+*/
+void
+dk4bit_shift_init(dk4_bit_shift_t *bs, dk4_er_t *erp);
+
+/** Add one byte.
+ @param bs Bit shifter.
+ @param bit Bit value, 0 or non-0.
+ @param erp Error report, may be NULL.
+ @return Action to take, one from:
+ - DK4_EDSTM_ACCEPT<br>
+ if the bit was stored in the bit shifter. No action necessary.
+ - DK4_EDSTM_FINISHED<br>
+ if one byte was completed by adding the bit.
+ Use dk4bit_shift_output() to retrieve the finished byte.
+ - DK4_EDSTM_ERROR<br>
+ if an error occured.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if bs is NULL.
+*/
+int
+dk4bit_shift_add(dk4_bit_shift_t *bs, int bit, dk4_er_t *erp);
+
+/** Check for unused content in the bit shifter after adding all bits.
+ @param bs Bit shifter.
+ @param erp Error report, may be NULL.
+ @return Action to take, one from:
+ - DK4_EDSTM_ACCEPT<br>
+ if no action is required.
+ - DK4_EDSTM_FINISHED<br>
+ if significant bits are available for a byte.
+ Use dk4bit_shift_output() to retrieve the byte value.
+ - DK4_EDSTM_ERROR<br>
+ if an error occured.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if bs is NULL.
+*/
+int
+dk4bit_shift_finish(dk4_bit_shift_t *bs, dk4_er_t *erp);
+
+/** Retrieve previous completed byte or final incomplete byte.
+ @param bs Bit shifter.
+ @param erp Error report, may be NULL.
+ @return Byte value consisting of the last bits added.
+*/
+unsigned char
+dk4bit_shift_output(dk4_bit_shift_t *bs, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4bitsh.h"
+#include "dk4edstm.h"
+#include "dk4mem.h"
+
+
+
+$!trace-include
+
+
+
+
+void
+dk4bit_shift_init(dk4_bit_shift_t *bs, dk4_er_t *erp)
+{
+ if (NULL != bs) {
+ DK4_MEMRES(bs, sizeof(dk4_bit_shift_t));
+ bs->pos = 0;
+ bs->obyte = 0x00;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+}
+
+
+
+int
+dk4bit_shift_add(dk4_bit_shift_t *bs, int bit, dk4_er_t *erp)
+{
+ int back = DK4_EDSTM_ERROR;
+ if (NULL != bs) {
+ back = DK4_EDSTM_ACCEPT;
+ switch (bs->pos) {
+ case 0: {
+ if (0 != bit) { bs->obyte = 0x80; } else { bs->obyte = 0x00; }
+ bs->pos = 1;
+ } break;
+ case 1: {
+ if (0 != bit) { bs->obyte |= 0x40; }
+ bs->pos = 2;
+ } break;
+ case 2: {
+ if (0 != bit) { bs->obyte |= 0x20; }
+ bs->pos = 3;
+ } break;
+ case 3: {
+ if (0 != bit) { bs->obyte |= 0x10; }
+ bs->pos = 4;
+ } break;
+ case 4: {
+ if (0 != bit) { bs->obyte |= 0x08; }
+ bs->pos = 5;
+ } break;
+ case 5: {
+ if (0 != bit) { bs->obyte |= 0x04; }
+ bs->pos = 6;
+ } break;
+ case 6: {
+ if (0 != bit) { bs->obyte |= 0x02; }
+ bs->pos = 7;
+ } break;
+ case 7: {
+ if (0 != bit) { bs->obyte |= 0x01; }
+ bs->pos = 0;
+ back = DK4_EDSTM_FINISHED;
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4bit_shift_finish(dk4_bit_shift_t *bs, dk4_er_t *erp)
+{
+ int back = DK4_EDSTM_ERROR;
+ if (NULL != bs) {
+ if (0 != bs->pos) {
+ back = DK4_EDSTM_FINISHED;
+ } else {
+ back = DK4_EDSTM_ACCEPT;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+unsigned char
+dk4bit_shift_output(dk4_bit_shift_t *bs, dk4_er_t *erp)
+{
+ unsigned char back;
+
+ if (NULL != bs) {
+ back = bs->obyte;
+ } else {
+ back = 0x00;
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4bitsh.h b/support/dktools/dk4bitsh.h
new file mode 100644
index 0000000000..5d62fa3148
--- /dev/null
+++ b/support/dktools/dk4bitsh.h
@@ -0,0 +1,121 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4bitsh.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4BITSH_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4BITSH_H_INCLUDED 1
+
+
+#line 10 "dk4bitsh.ctr"
+
+/** @file dk4bitsh.h Bit shifting.
+*/
+
+#include "dk4error.h"
+
+/** Bit shifter.
+*/
+typedef struct {
+ int pos; /**< Current bit position. */
+ unsigned char obyte; /**< Output byte. */
+} dk4_bit_shift_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Initialize a bit shifter before using it.
+ @param bs Bit shifter to initialize.
+ @param erp Error report, may be NULL.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS if bs is NULL.
+*/
+void
+dk4bit_shift_init(dk4_bit_shift_t *bs, dk4_er_t *erp);
+
+/** Add one byte.
+ @param bs Bit shifter.
+ @param bit Bit value, 0 or non-0.
+ @param erp Error report, may be NULL.
+ @return Action to take, one from:
+ - DK4_EDSTM_ACCEPT<br>
+ if the bit was stored in the bit shifter. No action necessary.
+ - DK4_EDSTM_FINISHED<br>
+ if one byte was completed by adding the bit.
+ Use dk4bit_shift_output() to retrieve the finished byte.
+ - DK4_EDSTM_ERROR<br>
+ if an error occured.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if bs is NULL.
+*/
+int
+dk4bit_shift_add(dk4_bit_shift_t *bs, int bit, dk4_er_t *erp);
+
+/** Check for unused content in the bit shifter after adding all bits.
+ @param bs Bit shifter.
+ @param erp Error report, may be NULL.
+ @return Action to take, one from:
+ - DK4_EDSTM_ACCEPT<br>
+ if no action is required.
+ - DK4_EDSTM_FINISHED<br>
+ if significant bits are available for a byte.
+ Use dk4bit_shift_output() to retrieve the byte value.
+ - DK4_EDSTM_ERROR<br>
+ if an error occured.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if bs is NULL.
+*/
+int
+dk4bit_shift_finish(dk4_bit_shift_t *bs, dk4_er_t *erp);
+
+/** Retrieve previous completed byte or final incomplete byte.
+ @param bs Bit shifter.
+ @param erp Error report, may be NULL.
+ @return Byte value consisting of the last bits added.
+*/
+unsigned char
+dk4bit_shift_output(dk4_bit_shift_t *bs, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4bom.c b/support/dktools/dk4bom.c
new file mode 100644
index 0000000000..a2a8477645
--- /dev/null
+++ b/support/dktools/dk4bom.c
@@ -0,0 +1,274 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4bom.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4bom.c The dk4bom module.
+*/
+
+
+#line 152 "dk4bom.ctr"
+
+
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4enc.h"
+#include "dk4bom.h"
+
+
+
+
+
+#line 163 "dk4bom.ctr"
+
+
+
+void
+dk4bom_detect_init(dk4_bom_detector_t *ptr, int defenc)
+{
+ if (NULL != ptr) {
+ ptr->defenc = defenc;
+ ptr->found = defenc;
+ ptr->state = 0;
+ ptr->rjb = 0;
+ ptr->c1 = 0x00;
+ ptr->c2 = 0x00;
+ ptr->c3 = 0x00;
+ }
+}
+
+
+
+/*
+ BOMS and states
+ ---------------
+ UTF-32 LSB: 0xFF (1) 0xFE (2) 0x00 (3) 0x00
+ UTF-32 MSB: 0x00 (4) 0x00 (5) 0xFE (6) 0xFF
+ UTF-16 LSB: 0xFF (1) 0xFE (2)
+ UTF-16 MSB: 0xFE (7) 0xFF
+ UTF-8: 0xEF (8) 0xBB (9) 0xBF
+*/
+
+
+
+int
+dk4bom_detect_add(dk4_bom_detector_t *ptr, unsigned char byte)
+{
+ int back = DK4_EDSTM_ERROR;
+ if (NULL != ptr) {
+ switch (ptr->state) {
+ case 0: {
+ ptr->c1 = byte;
+ ptr->rjb = 1;
+ switch ( (int)byte ) {
+ case 0x00: {
+ ptr->state = 4; back = DK4_EDSTM_ACCEPT;
+ } break;
+ case 0xFF: {
+ ptr->state = 1; back = DK4_EDSTM_ACCEPT;
+ } break;
+ case 0xFE: {
+ ptr->state = 7; back = DK4_EDSTM_ACCEPT;
+ } break;
+ case 0xEF: {
+ ptr->state = 8; back = DK4_EDSTM_ACCEPT;
+ } break;
+ default: {
+ ptr->state = -1; back = DK4_EDSTM_FINISHED_WITH_UNUSED;
+ } break;
+ }
+ } break;
+ case 1: {
+ ptr->c2 = byte;
+ ptr->rjb = 2;
+ if (0xFE == byte) {
+ ptr->state = 2; back = DK4_EDSTM_ACCEPT;
+ ptr->found = DK4_FILE_ENCODING_UTF16_LE;
+ ptr->rjb = 0;
+ } else {
+ ptr->state = -1; back = DK4_EDSTM_FINISHED_WITH_UNUSED;
+ }
+ } break;
+ case 2: {
+ ptr->c1 = byte;
+ ptr->rjb = 1;
+ if (0x00 == byte) {
+ ptr->state = 3; back = DK4_EDSTM_ACCEPT;
+ } else {
+ ptr->state = -1; back = DK4_EDSTM_FINISHED_WITH_UNUSED;
+ ptr->found = DK4_FILE_ENCODING_UTF16_LE;
+ }
+ } break;
+ case 3: {
+ ptr->c2 = byte;
+ ptr->rjb = 2;
+ if (0x00 == byte) {
+ ptr->state = -1; back = DK4_EDSTM_FINISHED;
+ ptr->found = DK4_FILE_ENCODING_32_LE;
+ ptr->rjb = 0;
+ } else {
+ ptr->state = -1; back = DK4_EDSTM_FINISHED_WITH_UNUSED;
+ ptr->found = DK4_FILE_ENCODING_UTF16_LE;
+ }
+ } break;
+ case 4: {
+ ptr->c2 = byte;
+ ptr->rjb = 2;
+ if (0x00 == byte) {
+ ptr->state = 5; back = DK4_EDSTM_ACCEPT;
+ } else {
+ ptr->state = -1; back = DK4_EDSTM_FINISHED_WITH_UNUSED;
+ }
+ } break;
+ case 5: {
+ ptr->c3 = byte;
+ ptr->rjb = 3;
+ if (0xFE == byte) {
+ ptr->state = 6; back = DK4_EDSTM_ACCEPT;
+ } else {
+ ptr->state = -1; back = DK4_EDSTM_FINISHED_WITH_UNUSED;
+ }
+ } break;
+ case 6: {
+ ptr->c4 = byte;
+ ptr->rjb = 4;
+ if (0xFF == byte) {
+ ptr->state = -1; back = DK4_EDSTM_FINISHED;
+ ptr->found = DK4_FILE_ENCODING_32_BE;
+ ptr->rjb = 0;
+ } else {
+ ptr->state = -1; back = DK4_EDSTM_FINISHED_WITH_UNUSED;
+ }
+ } break;
+ case 7: {
+ ptr->c2 = byte;
+ ptr->rjb = 2;
+ if (0xFF == byte) {
+ ptr->state = -1; back = DK4_EDSTM_FINISHED;
+ ptr->found = DK4_FILE_ENCODING_UTF16_BE;
+ ptr->rjb = 0;
+ } else {
+ ptr->state = -1; back = DK4_EDSTM_FINISHED_WITH_UNUSED;
+ }
+ } break;
+ case 8: {
+ ptr->c2 = byte;
+ ptr->rjb = 2;
+ if (0xBB == byte) {
+ ptr->state = 9; back = DK4_EDSTM_ACCEPT;
+ } else {
+ ptr->state = -1; back = DK4_EDSTM_FINISHED_WITH_UNUSED;
+ }
+ } break;
+ case 9: {
+ ptr->c3 = byte;
+ ptr->rjb = 3;
+ if (0xBF == byte) {
+ ptr->state = -1; back = DK4_EDSTM_FINISHED;
+ ptr->found = DK4_FILE_ENCODING_UTF8;
+ ptr->rjb = 0;
+ } else {
+ ptr->state = -1; back = DK4_EDSTM_FINISHED_WITH_UNUSED;
+ }
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4bom_detect_get_encoding(dk4_bom_detector_t *ptr)
+{
+ int back = DK4_ENCODING_ASCII;
+ if (NULL != ptr) {
+ back = ptr->found;
+ }
+ return back;
+}
+
+
+
+size_t
+dk4bom_detect_num_unused_bytes(dk4_bom_detector_t *ptr)
+{
+ size_t back = 0;
+ if (NULL != ptr) {
+ back = ptr->rjb;
+ }
+ return back;
+}
+
+
+
+unsigned char
+dk4bom_detect_unused_byte(dk4_bom_detector_t *ptr, size_t num)
+{
+ unsigned char back = 0x00;
+ if (NULL != ptr) {
+ if (0 == num) {
+ back = ptr->c1;
+ } else {
+ if (1 == num) {
+ back = ptr->c2;
+ } else {
+ if (2 == num) {
+ back = ptr->c3;
+ } else {
+ if (3 == num) {
+ back = ptr->c4;
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4bom_detect_in_detection(dk4_bom_detector_t *ptr)
+{
+ int back = 0;
+ if (NULL != ptr) {
+ if (-1 != ptr->state) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4bom.ctr b/support/dktools/dk4bom.ctr
new file mode 100644
index 0000000000..04442f3141
--- /dev/null
+++ b/support/dktools/dk4bom.ctr
@@ -0,0 +1,383 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Detect BOM (byte order marker) at start
+ of data stream, keep track of unprocessed characters.
+
+ First, use dk4bom_detect_init() to initialize the state machine.
+
+ Now use dk4bom_detect_add() to add the data streams contents
+ byte by byte to the state machine as long as the dk4bom_detect_add()
+ function returns DK4_EDSTM_ACCEPT.
+ If the function returns DK4_EDSTM_ERROR, an error occured, you
+ should stop processing.
+ If the function returns DK4_EDSTM_FINISHED or
+ DK4_EDSTM_FINISHED_WITH_UNUSED a BOM was found or definitely not
+ found. Use dk4bom_detect_get_encoding() to obtain the decoding
+ found and process the remaining data stream in that encoding.
+ If the function returned DK4_EDSTM_FINISHED_WITH_UNUSED, use
+ dk4bom_detect_num_unused_bytes() to find the number of unused
+ bytes saved in the detector and dk4bom_detect_unused_byte()
+ to retrieve and process the unused bytes before processing the
+ remaining bytes from the data stream.
+
+ For a very short data stream, the detection may not be finished
+ at the end of the stream. Use dk4bom_detect_in_detection() to
+ find out whether the detection was not yet finished.
+ If the function returns 1, the detection is not finished and unused
+ bytes are stored in the detector. Use dk4bom_detect_num_unused_bytes()
+ and dk4bom_detect_unused_byte() to obtain the unused bytes.
+
+ CRT on Windows: Not used.
+*/
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4EDSTM_H_INCLUDED
+#include "dk4edstm.h"
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+
+/** State machine to detect a BOM (byte order marker)
+ at the beginning of a data stream.
+*/
+typedef struct {
+ int defenc; /**< Default encoding, used if no BOM detected. */
+ int found; /**< Encoding from the BOM found. */
+ int state; /**< Current state of BOM detection. */
+ size_t rjb; /**< Number of unused bytes. */
+ unsigned char c1; /**< Rejected byte 1. */
+ unsigned char c2; /**< Rejected byte 2. */
+ unsigned char c3; /**< Rejected byte 3. */
+ unsigned char c4; /**< Rejected byte 4. */
+} dk4_bom_detector_t;
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Initialize the BOM detector.
+ @param ptr BOM detector to initialize.
+ @param defenc Encoding to use if not BOM at beginning of data.
+*/
+void
+dk4bom_detect_init(dk4_bom_detector_t *ptr, int defenc);
+
+/** Add one byte to the BOM detector.
+ @param ptr Detector to use.
+ @param byte The data byte to add.
+ @return Operation result, one from:
+ DK4_EDSTM_ACCEPT if you can continue feeding bytes into the
+ detector,
+ DK4_EDSTM_FINISHED if a BOM was detected (do not feed further
+ bytes),
+ DK4_EDSTM_FINISHED_WITH_UNUSED if BOM detection was finished and there
+ are unused bytes stored in the detector), or
+ DK4_EDSTM_ERROR if you attempt to add further bytes after the
+ detection was finished.
+ On DK4_EDSTM_FINISHED and DK4_EDSTM_FINISHED_WITH_UNUSED you can use
+ dk4bom_detect_get_encoding() to retrieve the encoding.
+ On DK4_EDSTM_FINISHED_WITH_UNUSED use dk4bom_detect_num_unused_bytes()
+ and dk4bom_detect_unused_byte() to retrieve the unused
+ bytes from the detector and process them before processing
+ further data from the data stream.
+*/
+int
+dk4bom_detect_add(dk4_bom_detector_t *ptr, unsigned char byte);
+
+/** Retrieve the encoding from the detector.
+ @param ptr Detector to use.
+ @return A file encoding, one from: DK4_FILE_ENCODING_ASCII,
+ DK4_FILE_ENCODING_ANSI, DK4_FILE_ENCODING_UTF8,
+ DK4_FILE_ENCODING_UTF16_LE, DK4_FILE_ENCODING_UTF16_BE,
+ DK4_FILE_ENCODING_32_LE, or DK4_FILE_ENCODING_32_BE.
+*/
+int
+dk4bom_detect_get_encoding(dk4_bom_detector_t *ptr);
+
+/** Retrieve the number of cted bytes stored in the detector.
+ @param ptr Detector to use.
+ @return Number of unused bytes stored in the detector.
+*/
+size_t
+dk4bom_detect_num_unused_bytes(dk4_bom_detector_t *ptr);
+
+/** Retrieve one unused byte stored in the detector.
+ @param ptr Detector to use.
+ @param num Byte number.
+ @return The byte value.
+*/
+unsigned char
+dk4bom_detect_unused_byte(dk4_bom_detector_t *ptr, size_t num);
+
+/** Check if BOM detection is still in progress.
+ @param ptr Detector to check.
+ @return 1 if detection is in progress and bytes are
+ stored in the detector, 0 otherwise.
+*/
+int
+dk4bom_detect_in_detection(dk4_bom_detector_t *ptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4enc.h"
+#include "dk4bom.h"
+
+
+
+$!trace-include
+
+
+
+void
+dk4bom_detect_init(dk4_bom_detector_t *ptr, int defenc)
+{
+ if (NULL != ptr) {
+ ptr->defenc = defenc;
+ ptr->found = defenc;
+ ptr->state = 0;
+ ptr->rjb = 0;
+ ptr->c1 = 0x00;
+ ptr->c2 = 0x00;
+ ptr->c3 = 0x00;
+ }
+}
+
+
+
+/*
+ BOMS and states
+ ---------------
+ UTF-32 LSB: 0xFF (1) 0xFE (2) 0x00 (3) 0x00
+ UTF-32 MSB: 0x00 (4) 0x00 (5) 0xFE (6) 0xFF
+ UTF-16 LSB: 0xFF (1) 0xFE (2)
+ UTF-16 MSB: 0xFE (7) 0xFF
+ UTF-8: 0xEF (8) 0xBB (9) 0xBF
+*/
+
+
+
+int
+dk4bom_detect_add(dk4_bom_detector_t *ptr, unsigned char byte)
+{
+ int back = DK4_EDSTM_ERROR;
+ if (NULL != ptr) {
+ switch (ptr->state) {
+ case 0: {
+ ptr->c1 = byte;
+ ptr->rjb = 1;
+ switch ( (int)byte ) {
+ case 0x00: {
+ ptr->state = 4; back = DK4_EDSTM_ACCEPT;
+ } break;
+ case 0xFF: {
+ ptr->state = 1; back = DK4_EDSTM_ACCEPT;
+ } break;
+ case 0xFE: {
+ ptr->state = 7; back = DK4_EDSTM_ACCEPT;
+ } break;
+ case 0xEF: {
+ ptr->state = 8; back = DK4_EDSTM_ACCEPT;
+ } break;
+ default: {
+ ptr->state = -1; back = DK4_EDSTM_FINISHED_WITH_UNUSED;
+ } break;
+ }
+ } break;
+ case 1: {
+ ptr->c2 = byte;
+ ptr->rjb = 2;
+ if (0xFE == byte) {
+ ptr->state = 2; back = DK4_EDSTM_ACCEPT;
+ ptr->found = DK4_FILE_ENCODING_UTF16_LE;
+ ptr->rjb = 0;
+ } else {
+ ptr->state = -1; back = DK4_EDSTM_FINISHED_WITH_UNUSED;
+ }
+ } break;
+ case 2: {
+ ptr->c1 = byte;
+ ptr->rjb = 1;
+ if (0x00 == byte) {
+ ptr->state = 3; back = DK4_EDSTM_ACCEPT;
+ } else {
+ ptr->state = -1; back = DK4_EDSTM_FINISHED_WITH_UNUSED;
+ ptr->found = DK4_FILE_ENCODING_UTF16_LE;
+ }
+ } break;
+ case 3: {
+ ptr->c2 = byte;
+ ptr->rjb = 2;
+ if (0x00 == byte) {
+ ptr->state = -1; back = DK4_EDSTM_FINISHED;
+ ptr->found = DK4_FILE_ENCODING_32_LE;
+ ptr->rjb = 0;
+ } else {
+ ptr->state = -1; back = DK4_EDSTM_FINISHED_WITH_UNUSED;
+ ptr->found = DK4_FILE_ENCODING_UTF16_LE;
+ }
+ } break;
+ case 4: {
+ ptr->c2 = byte;
+ ptr->rjb = 2;
+ if (0x00 == byte) {
+ ptr->state = 5; back = DK4_EDSTM_ACCEPT;
+ } else {
+ ptr->state = -1; back = DK4_EDSTM_FINISHED_WITH_UNUSED;
+ }
+ } break;
+ case 5: {
+ ptr->c3 = byte;
+ ptr->rjb = 3;
+ if (0xFE == byte) {
+ ptr->state = 6; back = DK4_EDSTM_ACCEPT;
+ } else {
+ ptr->state = -1; back = DK4_EDSTM_FINISHED_WITH_UNUSED;
+ }
+ } break;
+ case 6: {
+ ptr->c4 = byte;
+ ptr->rjb = 4;
+ if (0xFF == byte) {
+ ptr->state = -1; back = DK4_EDSTM_FINISHED;
+ ptr->found = DK4_FILE_ENCODING_32_BE;
+ ptr->rjb = 0;
+ } else {
+ ptr->state = -1; back = DK4_EDSTM_FINISHED_WITH_UNUSED;
+ }
+ } break;
+ case 7: {
+ ptr->c2 = byte;
+ ptr->rjb = 2;
+ if (0xFF == byte) {
+ ptr->state = -1; back = DK4_EDSTM_FINISHED;
+ ptr->found = DK4_FILE_ENCODING_UTF16_BE;
+ ptr->rjb = 0;
+ } else {
+ ptr->state = -1; back = DK4_EDSTM_FINISHED_WITH_UNUSED;
+ }
+ } break;
+ case 8: {
+ ptr->c2 = byte;
+ ptr->rjb = 2;
+ if (0xBB == byte) {
+ ptr->state = 9; back = DK4_EDSTM_ACCEPT;
+ } else {
+ ptr->state = -1; back = DK4_EDSTM_FINISHED_WITH_UNUSED;
+ }
+ } break;
+ case 9: {
+ ptr->c3 = byte;
+ ptr->rjb = 3;
+ if (0xBF == byte) {
+ ptr->state = -1; back = DK4_EDSTM_FINISHED;
+ ptr->found = DK4_FILE_ENCODING_UTF8;
+ ptr->rjb = 0;
+ } else {
+ ptr->state = -1; back = DK4_EDSTM_FINISHED_WITH_UNUSED;
+ }
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4bom_detect_get_encoding(dk4_bom_detector_t *ptr)
+{
+ int back = DK4_ENCODING_ASCII;
+ if (NULL != ptr) {
+ back = ptr->found;
+ }
+ return back;
+}
+
+
+
+size_t
+dk4bom_detect_num_unused_bytes(dk4_bom_detector_t *ptr)
+{
+ size_t back = 0;
+ if (NULL != ptr) {
+ back = ptr->rjb;
+ }
+ return back;
+}
+
+
+
+unsigned char
+dk4bom_detect_unused_byte(dk4_bom_detector_t *ptr, size_t num)
+{
+ unsigned char back = 0x00;
+ if (NULL != ptr) {
+ if (0 == num) {
+ back = ptr->c1;
+ } else {
+ if (1 == num) {
+ back = ptr->c2;
+ } else {
+ if (2 == num) {
+ back = ptr->c3;
+ } else {
+ if (3 == num) {
+ back = ptr->c4;
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4bom_detect_in_detection(dk4_bom_detector_t *ptr)
+{
+ int back = 0;
+ if (NULL != ptr) {
+ if (-1 != ptr->state) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4bom.h b/support/dktools/dk4bom.h
new file mode 100644
index 0000000000..60cc69debe
--- /dev/null
+++ b/support/dktools/dk4bom.h
@@ -0,0 +1,184 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4bom.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4BOM_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4BOM_H_INCLUDED 1
+
+
+#line 10 "dk4bom.ctr"
+
+/** @file
+ Detect BOM (byte order marker) at start
+ of data stream, keep track of unprocessed characters.
+
+ First, use dk4bom_detect_init() to initialize the state machine.
+
+ Now use dk4bom_detect_add() to add the data streams contents
+ byte by byte to the state machine as long as the dk4bom_detect_add()
+ function returns DK4_EDSTM_ACCEPT.
+ If the function returns DK4_EDSTM_ERROR, an error occured, you
+ should stop processing.
+ If the function returns DK4_EDSTM_FINISHED or
+ DK4_EDSTM_FINISHED_WITH_UNUSED a BOM was found or definitely not
+ found. Use dk4bom_detect_get_encoding() to obtain the decoding
+ found and process the remaining data stream in that encoding.
+ If the function returned DK4_EDSTM_FINISHED_WITH_UNUSED, use
+ dk4bom_detect_num_unused_bytes() to find the number of unused
+ bytes saved in the detector and dk4bom_detect_unused_byte()
+ to retrieve and process the unused bytes before processing the
+ remaining bytes from the data stream.
+
+ For a very short data stream, the detection may not be finished
+ at the end of the stream. Use dk4bom_detect_in_detection() to
+ find out whether the detection was not yet finished.
+ If the function returns 1, the detection is not finished and unused
+ bytes are stored in the detector. Use dk4bom_detect_num_unused_bytes()
+ and dk4bom_detect_unused_byte() to obtain the unused bytes.
+
+ CRT on Windows: Not used.
+*/
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4EDSTM_H_INCLUDED
+#include "dk4edstm.h"
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+
+/** State machine to detect a BOM (byte order marker)
+ at the beginning of a data stream.
+*/
+typedef struct {
+ int defenc; /**< Default encoding, used if no BOM detected. */
+ int found; /**< Encoding from the BOM found. */
+ int state; /**< Current state of BOM detection. */
+ size_t rjb; /**< Number of unused bytes. */
+ unsigned char c1; /**< Rejected byte 1. */
+ unsigned char c2; /**< Rejected byte 2. */
+ unsigned char c3; /**< Rejected byte 3. */
+ unsigned char c4; /**< Rejected byte 4. */
+} dk4_bom_detector_t;
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Initialize the BOM detector.
+ @param ptr BOM detector to initialize.
+ @param defenc Encoding to use if not BOM at beginning of data.
+*/
+void
+dk4bom_detect_init(dk4_bom_detector_t *ptr, int defenc);
+
+/** Add one byte to the BOM detector.
+ @param ptr Detector to use.
+ @param byte The data byte to add.
+ @return Operation result, one from:
+ DK4_EDSTM_ACCEPT if you can continue feeding bytes into the
+ detector,
+ DK4_EDSTM_FINISHED if a BOM was detected (do not feed further
+ bytes),
+ DK4_EDSTM_FINISHED_WITH_UNUSED if BOM detection was finished and there
+ are unused bytes stored in the detector), or
+ DK4_EDSTM_ERROR if you attempt to add further bytes after the
+ detection was finished.
+ On DK4_EDSTM_FINISHED and DK4_EDSTM_FINISHED_WITH_UNUSED you can use
+ dk4bom_detect_get_encoding() to retrieve the encoding.
+ On DK4_EDSTM_FINISHED_WITH_UNUSED use dk4bom_detect_num_unused_bytes()
+ and dk4bom_detect_unused_byte() to retrieve the unused
+ bytes from the detector and process them before processing
+ further data from the data stream.
+*/
+int
+dk4bom_detect_add(dk4_bom_detector_t *ptr, unsigned char byte);
+
+/** Retrieve the encoding from the detector.
+ @param ptr Detector to use.
+ @return A file encoding, one from: DK4_FILE_ENCODING_ASCII,
+ DK4_FILE_ENCODING_ANSI, DK4_FILE_ENCODING_UTF8,
+ DK4_FILE_ENCODING_UTF16_LE, DK4_FILE_ENCODING_UTF16_BE,
+ DK4_FILE_ENCODING_32_LE, or DK4_FILE_ENCODING_32_BE.
+*/
+int
+dk4bom_detect_get_encoding(dk4_bom_detector_t *ptr);
+
+/** Retrieve the number of cted bytes stored in the detector.
+ @param ptr Detector to use.
+ @return Number of unused bytes stored in the detector.
+*/
+size_t
+dk4bom_detect_num_unused_bytes(dk4_bom_detector_t *ptr);
+
+/** Retrieve one unused byte stored in the detector.
+ @param ptr Detector to use.
+ @param num Byte number.
+ @return The byte value.
+*/
+unsigned char
+dk4bom_detect_unused_byte(dk4_bom_detector_t *ptr, size_t num);
+
+/** Check if BOM detection is still in progress.
+ @param ptr Detector to check.
+ @return 1 if detection is in progress and bytes are
+ stored in the detector, 0 otherwise.
+*/
+int
+dk4bom_detect_in_detection(dk4_bom_detector_t *ptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4c32.c b/support/dktools/dk4c32.c
new file mode 100644
index 0000000000..a197ad5b80
--- /dev/null
+++ b/support/dktools/dk4c32.c
@@ -0,0 +1,144 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4c32.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4c32.c The dk4c32 module.
+*/
+
+
+#line 77 "dk4c32.ctr"
+
+#include "dk4c32.h"
+
+#ifndef DK4EDSTM_H_INCLUDED
+#include "dk4edstm.h"
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#else
+#ifndef STDIO_H_INCLUDED
+#include <stdio.h>
+#define STDIO_H_INCLUDED 1
+#endif
+#endif
+
+void
+dk4c32_decoder_init(dk4_c32_byte_decoder_t *ptr, int msb)
+{
+ if (NULL != ptr) {
+ ptr->val = (dk4_c32_t)0UL;
+ ptr->msb = msb;
+ ptr->nb = 0;
+ }
+}
+
+
+
+int
+dk4c32_decoder_add(dk4_c32_byte_decoder_t *ptr, unsigned char inbyte)
+{
+ int back = DK4_EDSTM_ERROR;
+ if (NULL != ptr) {
+ switch (ptr->nb) {
+ case 3: {
+ if (ptr->msb) {
+ ptr->val |= (dkC32(0x000000FF) & ((dk4_c32_t)inbyte));
+ } else {
+ ptr->val |= (dkC32(0xFF000000) & (((dk4_c32_t)inbyte) << 24));
+ }
+ ptr->nb = 0;
+ back = DK4_EDSTM_FINISHED;
+ } break;
+ case 2: {
+ if (ptr->msb) {
+ ptr->val |= (dkC32(0x0000FF00) & (((dk4_c32_t)inbyte) << 8));
+ } else {
+ ptr->val |= (dkC32(0x00FF0000) & (((dk4_c32_t)inbyte) << 16));
+ }
+ ptr->nb = 3;
+ back = DK4_EDSTM_ACCEPT;
+ } break;
+ case 1: {
+ if (ptr->msb) {
+ ptr->val |= (dkC32(0x00FF0000) & (((dk4_c32_t)inbyte) << 16));
+ } else {
+ ptr->val |= (dkC32(0x0000FF00) & (((dk4_c32_t)inbyte) << 8));
+ }
+ ptr->nb = 2;
+ back = DK4_EDSTM_ACCEPT;
+ } break;
+ default: {
+ if (ptr->msb) {
+ ptr->val = (dkC32(0xFF000000) & (((dk4_c32_t)inbyte) << 24));
+ } else {
+ ptr->val = (dkC32(0x000000FF) & ((dk4_c32_t)inbyte));
+ }
+ ptr->nb = 1;
+ back = DK4_EDSTM_ACCEPT;
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+dk4_c32_t
+dk4c32_decoder_get(dk4_c32_byte_decoder_t *ptr)
+{
+ dk4_c32_t back = (dk4_c32_t)0UL;
+ if (NULL != ptr) {
+ back = ptr->val;
+ }
+ return back;
+}
+
+
+
+int
+dk4c32_decoder_is_empty(dk4_c32_byte_decoder_t *ptr)
+{
+ int back = 0;
+ if (NULL != ptr) {
+ if (0 == ptr->nb) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4c32.ctr b/support/dktools/dk4c32.ctr
new file mode 100644
index 0000000000..f3e2e35ede
--- /dev/null
+++ b/support/dktools/dk4c32.ctr
@@ -0,0 +1,180 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ 32 bit character decoding.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+/** Decoder structure to build a 32 bit character from 4 4 4 4 bytes.
+*/
+typedef struct {
+ dk4_c32_t val; /**< Value constructed from the bytes. */
+ int msb; /**< Flag: First byte is MSB. */
+ int nb; /**< Number of next byte. */
+} dk4_c32_byte_decoder_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Initialize the decoder.
+ @param ptr Decoder to initialize.
+ @param msb Flag: Most significant byte first.
+*/
+void
+dk4c32_decoder_init(dk4_c32_byte_decoder_t *ptr, int msb);
+
+/** Add one byte to the decoder.
+ @param ptr
+ @param inbyte
+ @return DK4_EDSTM_ACCEPT if the byte was added to the internal
+ decoder state (no action necessary) or
+ DK4_EDSTM_FINISHED if one output was finished (use
+ dk4c32_decoder_get() to obtain the value).
+*/
+int
+dk4c32_decoder_add(dk4_c32_byte_decoder_t *ptr, unsigned char inbyte);
+
+/** Retrieve output value.
+ @param ptr Decoder to retrieve value from.
+ @return Output produced by the decoder.
+*/
+dk4_c32_t
+dk4c32_decoder_get(dk4_c32_byte_decoder_t *ptr);
+
+/** Check whether the decoder is empty (nothing is stored in the
+ internal state).
+ @param ptr Decoder to check.
+ @return 1 on success (decoder empty), 0 otherwise.
+*/
+int
+dk4c32_decoder_is_empty(dk4_c32_byte_decoder_t *ptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4c32.h"
+
+#ifndef DK4EDSTM_H_INCLUDED
+#include "dk4edstm.h"
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#else
+#ifndef STDIO_H_INCLUDED
+#include <stdio.h>
+#define STDIO_H_INCLUDED 1
+#endif
+#endif
+
+void
+dk4c32_decoder_init(dk4_c32_byte_decoder_t *ptr, int msb)
+{
+ if (NULL != ptr) {
+ ptr->val = (dk4_c32_t)0UL;
+ ptr->msb = msb;
+ ptr->nb = 0;
+ }
+}
+
+
+
+int
+dk4c32_decoder_add(dk4_c32_byte_decoder_t *ptr, unsigned char inbyte)
+{
+ int back = DK4_EDSTM_ERROR;
+ if (NULL != ptr) {
+ switch (ptr->nb) {
+ case 3: {
+ if (ptr->msb) {
+ ptr->val |= (dkC32(0x000000FF) & ((dk4_c32_t)inbyte));
+ } else {
+ ptr->val |= (dkC32(0xFF000000) & (((dk4_c32_t)inbyte) << 24));
+ }
+ ptr->nb = 0;
+ back = DK4_EDSTM_FINISHED;
+ } break;
+ case 2: {
+ if (ptr->msb) {
+ ptr->val |= (dkC32(0x0000FF00) & (((dk4_c32_t)inbyte) << 8));
+ } else {
+ ptr->val |= (dkC32(0x00FF0000) & (((dk4_c32_t)inbyte) << 16));
+ }
+ ptr->nb = 3;
+ back = DK4_EDSTM_ACCEPT;
+ } break;
+ case 1: {
+ if (ptr->msb) {
+ ptr->val |= (dkC32(0x00FF0000) & (((dk4_c32_t)inbyte) << 16));
+ } else {
+ ptr->val |= (dkC32(0x0000FF00) & (((dk4_c32_t)inbyte) << 8));
+ }
+ ptr->nb = 2;
+ back = DK4_EDSTM_ACCEPT;
+ } break;
+ default: {
+ if (ptr->msb) {
+ ptr->val = (dkC32(0xFF000000) & (((dk4_c32_t)inbyte) << 24));
+ } else {
+ ptr->val = (dkC32(0x000000FF) & ((dk4_c32_t)inbyte));
+ }
+ ptr->nb = 1;
+ back = DK4_EDSTM_ACCEPT;
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+dk4_c32_t
+dk4c32_decoder_get(dk4_c32_byte_decoder_t *ptr)
+{
+ dk4_c32_t back = (dk4_c32_t)0UL;
+ if (NULL != ptr) {
+ back = ptr->val;
+ }
+ return back;
+}
+
+
+
+int
+dk4c32_decoder_is_empty(dk4_c32_byte_decoder_t *ptr)
+{
+ int back = 0;
+ if (NULL != ptr) {
+ if (0 == ptr->nb) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4c32.h b/support/dktools/dk4c32.h
new file mode 100644
index 0000000000..90b6223a84
--- /dev/null
+++ b/support/dktools/dk4c32.h
@@ -0,0 +1,109 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4c32.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4C32_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4C32_H_INCLUDED 1
+
+
+#line 10 "dk4c32.ctr"
+
+/** @file
+ 32 bit character decoding.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+/** Decoder structure to build a 32 bit character from 4 4 4 4 bytes.
+*/
+typedef struct {
+ dk4_c32_t val; /**< Value constructed from the bytes. */
+ int msb; /**< Flag: First byte is MSB. */
+ int nb; /**< Number of next byte. */
+} dk4_c32_byte_decoder_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Initialize the decoder.
+ @param ptr Decoder to initialize.
+ @param msb Flag: Most significant byte first.
+*/
+void
+dk4c32_decoder_init(dk4_c32_byte_decoder_t *ptr, int msb);
+
+/** Add one byte to the decoder.
+ @param ptr
+ @param inbyte
+ @return DK4_EDSTM_ACCEPT if the byte was added to the internal
+ decoder state (no action necessary) or
+ DK4_EDSTM_FINISHED if one output was finished (use
+ dk4c32_decoder_get() to obtain the value).
+*/
+int
+dk4c32_decoder_add(dk4_c32_byte_decoder_t *ptr, unsigned char inbyte);
+
+/** Retrieve output value.
+ @param ptr Decoder to retrieve value from.
+ @return Output produced by the decoder.
+*/
+dk4_c32_t
+dk4c32_decoder_get(dk4_c32_byte_decoder_t *ptr);
+
+/** Check whether the decoder is empty (nothing is stored in the
+ internal state).
+ @param ptr Decoder to check.
+ @return 1 on success (decoder empty), 0 otherwise.
+*/
+int
+dk4c32_decoder_is_empty(dk4_c32_byte_decoder_t *ptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4c8dbl.c b/support/dktools/dk4c8dbl.c
new file mode 100644
index 0000000000..bb224d4c00
--- /dev/null
+++ b/support/dktools/dk4c8dbl.c
@@ -0,0 +1,455 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4c8dbl.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4c8dbl.c The dk4c8dbl module.
+*/
+
+
+#line 99 "dk4c8dbl.ctr"
+
+#include "dk4c8dbl.h"
+
+#if DK4_HAVE_STRING_H
+#include <string.h>
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#include "dk4mao8dbl.h"
+#include "dk4mai8ddi.h"
+#include "dk4str8.h"
+
+
+
+
+
+#line 117 "dk4c8dbl.ctr"
+
+
+
+/** Write character to stream or file.
+ @param dptr Destination for write operations.
+ @param dtp Type of dptr: 0=FILE, 1=dk4_stream_t.
+ @param c Character to write.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is NULL or not opened for writing,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flusing data downwards failed.
+*/
+static
+int
+dk4c8dbl_i_byte_to_void(
+ void *dptr,
+ int dtp,
+ char c,
+ dk4_er_t *erp
+)
+{
+ int back;
+ switch (dtp) {
+ case 1: {
+ back = dk4stream_write_byte((dk4_stream_t*)dptr, c, erp);
+ } break;
+ default: {
+ if (EOF != fputc(c, (FILE *)dptr)) {
+ back = 1;
+ }
+ else {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED);
+ }
+ } break;
+ }
+ return back;
+}
+
+
+
+static
+void
+dk4c8dbl_i_cut_trailing_zeroes(char *str)
+{
+ char *cutpos = NULL;
+
+
+#line 170 "dk4c8dbl.ctr"
+ while ('\0' != *str) {
+
+#line 171 "dk4c8dbl.ctr"
+ if ('0' == *str) {
+
+#line 172 "dk4c8dbl.ctr"
+ if (NULL == cutpos) {
+
+#line 173 "dk4c8dbl.ctr"
+ cutpos = str;
+ }
+ }
+ else {
+
+#line 177 "dk4c8dbl.ctr"
+ cutpos = NULL;
+
+#line 178 "dk4c8dbl.ctr"
+ }
+ str++;
+ }
+ if (NULL != cutpos) {
+
+#line 182 "dk4c8dbl.ctr"
+ *cutpos = '\0';
+ }
+
+
+#line 185 "dk4c8dbl.ctr"
+}
+
+
+
+/** Write double value to stream or file, avoid scientific notation.
+ @param dptr Destination for write operations.
+ @param dtp Type of dptr: 0=FILE, 1=dk4_stream_t.
+ @param str String representation of double.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the internal destination buffer is too small to store the string,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flusing data downwards failed.
+*/
+static
+int
+dk4c8dbl_i_str_to_void(
+ void *dptr,
+ int dtp,
+ char *str,
+ dk4_er_t *erp
+)
+{
+ char *eptr; /* Position of 'e' */
+ char *ddptr; /* Position of decimal dot */
+ char *p1; /* Traverse string */
+ const char *endptr = NULL; /* End of processed data exponent */
+ dk4_im_t expo = (dk4_im_t)0L; /* Exponent value */
+ size_t dotpos; /* Position of decimal dot */
+ int isneg = 0; /* Flag: Negative number */
+ int back = 0; /* Function result */
+ int res; /* Conversion result */
+
+
+#line 225 "dk4c8dbl.ctr"
+ /*
+ Check for scientific notation
+ */
+ eptr = strchr(str, 'e');
+ if (NULL == eptr) { eptr = strchr(str, 'E'); }
+ if (NULL != eptr) {
+
+#line 231 "dk4c8dbl.ctr"
+ /*
+ Scientific notation found, analyse string first
+ -----------------------------------------------
+ */
+ /*
+ Check for negative value (unary minus)
+ */
+ if ('-' == *str) {
+ isneg = 1;
+ str++;
+ }
+ /*
+ Retrieve exponent value
+ */
+ *(eptr++) = '\0';
+ res = dk4ma_input_c8_dec_dk4_im_t( &expo, eptr, &endptr, 1, erp);
+ if (0 == res) {
+ expo = (dk4_im_t)0L;
+ }
+
+
+#line 251 "dk4c8dbl.ctr"
+ /*
+ Find position of decimal dot and convert string digit sequence
+ */
+ ddptr = strchr(str, '.');
+ if (NULL != ddptr) {
+ *ddptr = '\0';
+ dotpos = strlen(str);
+ dk4str8_cpy_to_left(ddptr, &(ddptr[1]));
+ dk4c8dbl_i_cut_trailing_zeroes(&(ddptr[1]));
+ }
+ else {
+ dotpos = strlen(str);
+ }
+ /*
+ Calculate real position of decimal dot.
+ */
+ expo += (dk4_im_t)dotpos;
+ /*
+ Remove leading zeroes
+ */
+ while (('0' == *str) && ('\0' != str[1])) {
+ str++;
+ expo--;
+ }
+ /*
+ Now write the number
+ --------------------
+ */
+ back = 1;
+ /*
+ Write unary minus for negative numbers
+ */
+ if (0 != isneg) {
+ if (0 == dk4c8dbl_i_byte_to_void(dptr, dtp, '-', erp)) {
+ back = 0;
+ }
+ }
+ if ((dk4_im_t)0L >= expo) {
+ /*
+ Decimal dot is before first digit in string
+ */
+ if (0 == dk4c8dbl_i_byte_to_void(dptr, dtp, '0', erp)) {
+ back = 0;
+ }
+ if (0 == dk4c8dbl_i_byte_to_void(dptr, dtp, '.', erp)) {
+ back = 0;
+ }
+ while ((dk4_im_t)0L > expo++) {
+ if (0 == dk4c8dbl_i_byte_to_void(dptr, dtp, '0', erp)) {
+ back = 0;
+ }
+ }
+ p1 = str;
+ while ('\0' != *p1) {
+ if (0 == dk4c8dbl_i_byte_to_void(dptr, dtp, *(p1++), erp)) {
+ back = 0;
+ }
+ }
+ }
+ else {
+ /*
+ Decimal dot is in string or after string
+ */
+ p1 = str;
+ while ('\0' != *p1) {
+ if (0 == dk4c8dbl_i_byte_to_void(dptr, dtp, *p1, erp)) {
+ back = 0;
+ }
+ expo--;
+ p1++;
+ if ((dk4_im_t)0L == expo) {
+ if ('\0' != *p1) {
+ if (0 == dk4c8dbl_i_byte_to_void(dptr, dtp, '.', erp)) {
+ back = 0;
+ }
+ }
+ }
+ }
+ while ((dk4_im_t)0L < expo--) {
+ if (0 == dk4c8dbl_i_byte_to_void(dptr, dtp, '0', erp)) {
+ back = 0;
+ }
+ }
+ }
+ }
+ else {
+
+#line 337 "dk4c8dbl.ctr"
+ /*
+ No exponent, can ship out string as is
+ --------------------------------------
+ */
+ /*
+ Remove leading zeroes
+ */
+ while (('0' == *str) && ('\0' != str[1])) {
+ str++;
+ }
+ /*
+ Remove trailing zeroes
+ */
+ ddptr = strchr(str, '.');
+ if (NULL != ddptr) {
+ ddptr++;
+ ddptr++;
+ dk4c8dbl_i_cut_trailing_zeroes(ddptr);
+
+
+#line 356 "dk4c8dbl.ctr"
+ }
+ /*
+ Write output
+ */
+ back = 1;
+ p1 = str;
+ if ('.' == *str) {
+ if (0 == dk4c8dbl_i_byte_to_void(dptr, dtp, '0', erp)) {
+ back = 0;
+ }
+ }
+ while ('\0' != *p1) {
+ if (0 == dk4c8dbl_i_byte_to_void(dptr, dtp, *(p1++), erp)) {
+ back = 0;
+ }
+ }
+ }
+
+
+#line 374 "dk4c8dbl.ctr"
+ return back;
+}
+
+
+
+/** Write double value to stream or file, avoid scientific notation.
+ @param dptr Destination for write operations.
+ @param dtp Type of dptr: 0=FILE, 1=dk4_stream_t.
+ @param v Value to write.
+ @param exact Flag: Exact representation.
+ @param minim Flag: Minimize an exact representation.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the internal destination buffer is too small to store the string,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flusing data downwards failed.
+*/
+static
+int
+dk4c8dbl_i_double_to_void(
+ void *dptr,
+ int dtp,
+ double v,
+ int exact,
+ int minim,
+ dk4_er_t *erp
+)
+{
+ char buf[16*sizeof(double)];
+ size_t szbuf = sizeof(buf);
+ int res = 0;
+ int back = 0;
+
+ if (NULL != dptr) {
+ res = dk4ma_write_c8_double(buf, szbuf, v, exact, minim, erp);
+ if (0 != res) {
+ back = dk4c8dbl_i_str_to_void(dptr, dtp, buf, erp);
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4c8dbl_double_to_stream(
+ dk4_stream_t *strm,
+ double v,
+ int exact,
+ int minim,
+ dk4_er_t *erp
+)
+{
+ return (dk4c8dbl_i_double_to_void((void *)strm, 1, v, exact, minim, erp));
+}
+
+
+
+int
+dk4c8dbl_double_to_file(
+ FILE *fipo,
+ double v,
+ int exact,
+ int minim,
+ dk4_er_t *erp
+)
+{
+ return (dk4c8dbl_i_double_to_void((void *)fipo, 0, v, exact, minim, erp));
+}
+
+
+
+int
+dk4c8dbl_str_double_to_file(
+ FILE *fipo,
+ const char *str,
+ dk4_er_t *erp
+)
+{
+ char buf[16*sizeof(double)];
+ int back = 0;
+
+ if ((NULL != fipo) && (NULL != str)) {
+ if (strlen(str) < sizeof(buf)) {
+ strcpy(buf, str);
+ back = dk4c8dbl_i_str_to_void((void *)fipo, 0, buf, erp);
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+/* vim: set ai sw=4 ts=4 : */
diff --git a/support/dktools/dk4c8dbl.ctr b/support/dktools/dk4c8dbl.ctr
new file mode 100644
index 0000000000..6dc89b1e19
--- /dev/null
+++ b/support/dktools/dk4c8dbl.ctr
@@ -0,0 +1,483 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+%% header
+
+/** @file dk4c8dbl.h Write double value to file or stream
+ without scientific notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include <dk4conf.h>
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include <dk4types.h>
+#endif
+
+#ifndef STDIO_H_INCLUDED
+#include <stdio.h>
+#define STDIO_H_INCLUDED 1
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include <dk4error.h>
+#endif
+
+#ifndef DK4STRM_H_INCLUDED
+#include <dk4strm.h>
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Write double value to stream, avoid scientific notation.
+ @param strm Stream to write to.
+ @param v Value to write.
+ @param exact Flag: Exact representation.
+ @param minim Flag: Minimize an exact representation.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+
+int
+dk4c8dbl_double_to_stream(
+ dk4_stream_t *strm,
+ double v,
+ int exact,
+ int minim,
+ dk4_er_t *erp
+);
+
+
+/** Write double value to stream, avoid scientific notation.
+ @param fipo File to write to.
+ @param v Value to write.
+ @param exact Flag: Exact representation.
+ @param minim Flag: Minimize an exact representation.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+
+int
+dk4c8dbl_double_to_file(
+ FILE *fipo,
+ double v,
+ int exact,
+ int minim,
+ dk4_er_t *erp
+);
+
+
+/** Write double string to stream, avoid scientific notation.
+ @param fipo File to write to.
+ @param str String containing the value.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+
+int
+dk4c8dbl_str_double_to_file(
+ FILE *fipo,
+ const char *str,
+ dk4_er_t *erp
+);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/* vim: set ai sw=4 ts=4 : */
+%% module
+
+#include "dk4c8dbl.h"
+
+#if DK4_HAVE_STRING_H
+#include <string.h>
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#include "dk4mao8dbl.h"
+#include "dk4mai8ddi.h"
+#include "dk4str8.h"
+
+
+
+$!trace-include
+
+
+
+/** Write character to stream or file.
+ @param dptr Destination for write operations.
+ @param dtp Type of dptr: 0=FILE, 1=dk4_stream_t.
+ @param c Character to write.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is NULL or not opened for writing,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flusing data downwards failed.
+*/
+static
+int
+dk4c8dbl_i_byte_to_void(
+ void *dptr,
+ int dtp,
+ char c,
+ dk4_er_t *erp
+)
+{
+ int back;
+ switch (dtp) {
+ case 1: {
+ back = dk4stream_write_byte((dk4_stream_t*)dptr, c, erp);
+ } break;
+ default: {
+ if (EOF != fputc(c, (FILE *)dptr)) {
+ back = 1;
+ }
+ else {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED);
+ }
+ } break;
+ }
+ return back;
+}
+
+
+
+static
+void
+dk4c8dbl_i_cut_trailing_zeroes(char *str)
+{
+ char *cutpos = NULL;
+ $? "+ dk4c8dbl_i_cut_trailing_zeroes \"%!8s\"", str
+ while ('\0' != *str) { $? ". c = \"%c\"", *str
+ if ('0' == *str) { $? ". 0"
+ if (NULL == cutpos) { $? ". new cut position"
+ cutpos = str;
+ }
+ }
+ else { $? ". not 0"
+ cutpos = NULL; $? ". can not cut"
+ }
+ str++;
+ }
+ if (NULL != cutpos) { $? ". can cut"
+ *cutpos = '\0';
+ }
+ $? "- dk4c8dbl_i_cut_trailing_zeroes"
+}
+
+
+
+/** Write double value to stream or file, avoid scientific notation.
+ @param dptr Destination for write operations.
+ @param dtp Type of dptr: 0=FILE, 1=dk4_stream_t.
+ @param str String representation of double.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the internal destination buffer is too small to store the string,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flusing data downwards failed.
+*/
+static
+int
+dk4c8dbl_i_str_to_void(
+ void *dptr,
+ int dtp,
+ char *str,
+ dk4_er_t *erp
+)
+{
+ char *eptr; /* Position of 'e' */
+ char *ddptr; /* Position of decimal dot */
+ char *p1; /* Traverse string */
+ const char *endptr = NULL; /* End of processed data exponent */
+ dk4_im_t expo = (dk4_im_t)0L; /* Exponent value */
+ size_t dotpos; /* Position of decimal dot */
+ int isneg = 0; /* Flag: Negative number */
+ int back = 0; /* Function result */
+ int res; /* Conversion result */
+ $? "+ dk4c8dbl_i_str_to_void \"%!8s\"", str
+ /*
+ Check for scientific notation
+ */
+ eptr = strchr(str, 'e');
+ if (NULL == eptr) { eptr = strchr(str, 'E'); }
+ if (NULL != eptr) { $? ". exponent found"
+ /*
+ Scientific notation found, analyse string first
+ -----------------------------------------------
+ */
+ /*
+ Check for negative value (unary minus)
+ */
+ if ('-' == *str) {
+ isneg = 1;
+ str++;
+ }
+ /*
+ Retrieve exponent value
+ */
+ *(eptr++) = '\0';
+ res = dk4ma_input_c8_dec_dk4_im_t( &expo, eptr, &endptr, 1, erp);
+ if (0 == res) {
+ expo = (dk4_im_t)0L;
+ }
+ $? ". expo = %ld", (long)expo
+ /*
+ Find position of decimal dot and convert string digit sequence
+ */
+ ddptr = strchr(str, '.');
+ if (NULL != ddptr) {
+ *ddptr = '\0';
+ dotpos = strlen(str);
+ dk4str8_cpy_to_left(ddptr, &(ddptr[1]));
+ dk4c8dbl_i_cut_trailing_zeroes(&(ddptr[1]));
+ }
+ else {
+ dotpos = strlen(str);
+ }
+ /*
+ Calculate real position of decimal dot.
+ */
+ expo += (dk4_im_t)dotpos;
+ /*
+ Remove leading zeroes
+ */
+ while (('0' == *str) && ('\0' != str[1])) {
+ str++;
+ expo--;
+ }
+ /*
+ Now write the number
+ --------------------
+ */
+ back = 1;
+ /*
+ Write unary minus for negative numbers
+ */
+ if (0 != isneg) {
+ if (0 == dk4c8dbl_i_byte_to_void(dptr, dtp, '-', erp)) {
+ back = 0;
+ }
+ }
+ if ((dk4_im_t)0L >= expo) {
+ /*
+ Decimal dot is before first digit in string
+ */
+ if (0 == dk4c8dbl_i_byte_to_void(dptr, dtp, '0', erp)) {
+ back = 0;
+ }
+ if (0 == dk4c8dbl_i_byte_to_void(dptr, dtp, '.', erp)) {
+ back = 0;
+ }
+ while ((dk4_im_t)0L > expo++) {
+ if (0 == dk4c8dbl_i_byte_to_void(dptr, dtp, '0', erp)) {
+ back = 0;
+ }
+ }
+ p1 = str;
+ while ('\0' != *p1) {
+ if (0 == dk4c8dbl_i_byte_to_void(dptr, dtp, *(p1++), erp)) {
+ back = 0;
+ }
+ }
+ }
+ else {
+ /*
+ Decimal dot is in string or after string
+ */
+ p1 = str;
+ while ('\0' != *p1) {
+ if (0 == dk4c8dbl_i_byte_to_void(dptr, dtp, *p1, erp)) {
+ back = 0;
+ }
+ expo--;
+ p1++;
+ if ((dk4_im_t)0L == expo) {
+ if ('\0' != *p1) {
+ if (0 == dk4c8dbl_i_byte_to_void(dptr, dtp, '.', erp)) {
+ back = 0;
+ }
+ }
+ }
+ }
+ while ((dk4_im_t)0L < expo--) {
+ if (0 == dk4c8dbl_i_byte_to_void(dptr, dtp, '0', erp)) {
+ back = 0;
+ }
+ }
+ }
+ }
+ else { $? ". no exponent"
+ /*
+ No exponent, can ship out string as is
+ --------------------------------------
+ */
+ /*
+ Remove leading zeroes
+ */
+ while (('0' == *str) && ('\0' != str[1])) {
+ str++;
+ }
+ /*
+ Remove trailing zeroes
+ */
+ ddptr = strchr(str, '.');
+ if (NULL != ddptr) {
+ ddptr++;
+ ddptr++;
+ dk4c8dbl_i_cut_trailing_zeroes(ddptr);
+ $? ". str = \"%!8s\"", str
+ }
+ /*
+ Write output
+ */
+ back = 1;
+ p1 = str;
+ if ('.' == *str) {
+ if (0 == dk4c8dbl_i_byte_to_void(dptr, dtp, '0', erp)) {
+ back = 0;
+ }
+ }
+ while ('\0' != *p1) {
+ if (0 == dk4c8dbl_i_byte_to_void(dptr, dtp, *(p1++), erp)) {
+ back = 0;
+ }
+ }
+ }
+ $? "- dk4c8dbl_i_str_to_void"
+ return back;
+}
+
+
+
+/** Write double value to stream or file, avoid scientific notation.
+ @param dptr Destination for write operations.
+ @param dtp Type of dptr: 0=FILE, 1=dk4_stream_t.
+ @param v Value to write.
+ @param exact Flag: Exact representation.
+ @param minim Flag: Minimize an exact representation.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the internal destination buffer is too small to store the string,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flusing data downwards failed.
+*/
+static
+int
+dk4c8dbl_i_double_to_void(
+ void *dptr,
+ int dtp,
+ double v,
+ int exact,
+ int minim,
+ dk4_er_t *erp
+)
+{
+ char buf[16*sizeof(double)];
+ size_t szbuf = sizeof(buf);
+ int res = 0;
+ int back = 0;
+
+ if (NULL != dptr) {
+ res = dk4ma_write_c8_double(buf, szbuf, v, exact, minim, erp);
+ if (0 != res) {
+ back = dk4c8dbl_i_str_to_void(dptr, dtp, buf, erp);
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4c8dbl_double_to_stream(
+ dk4_stream_t *strm,
+ double v,
+ int exact,
+ int minim,
+ dk4_er_t *erp
+)
+{
+ return (dk4c8dbl_i_double_to_void((void *)strm, 1, v, exact, minim, erp));
+}
+
+
+
+int
+dk4c8dbl_double_to_file(
+ FILE *fipo,
+ double v,
+ int exact,
+ int minim,
+ dk4_er_t *erp
+)
+{
+ return (dk4c8dbl_i_double_to_void((void *)fipo, 0, v, exact, minim, erp));
+}
+
+
+
+int
+dk4c8dbl_str_double_to_file(
+ FILE *fipo,
+ const char *str,
+ dk4_er_t *erp
+)
+{
+ char buf[16*sizeof(double)];
+ int back = 0;
+
+ if ((NULL != fipo) && (NULL != str)) {
+ if (strlen(str) < sizeof(buf)) {
+ strcpy(buf, str);
+ back = dk4c8dbl_i_str_to_void((void *)fipo, 0, buf, erp);
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+/* vim: set ai sw=4 ts=4 : */
diff --git a/support/dktools/dk4c8dbl.h b/support/dktools/dk4c8dbl.h
new file mode 100644
index 0000000000..7f86bc812d
--- /dev/null
+++ b/support/dktools/dk4c8dbl.h
@@ -0,0 +1,133 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4c8dbl.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4C8DBL_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4C8DBL_H_INCLUDED 1
+
+
+#line 8 "dk4c8dbl.ctr"
+
+/** @file dk4c8dbl.h Write double value to file or stream
+ without scientific notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include <dk4conf.h>
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include <dk4types.h>
+#endif
+
+#ifndef STDIO_H_INCLUDED
+#include <stdio.h>
+#define STDIO_H_INCLUDED 1
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include <dk4error.h>
+#endif
+
+#ifndef DK4STRM_H_INCLUDED
+#include <dk4strm.h>
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Write double value to stream, avoid scientific notation.
+ @param strm Stream to write to.
+ @param v Value to write.
+ @param exact Flag: Exact representation.
+ @param minim Flag: Minimize an exact representation.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+
+int
+dk4c8dbl_double_to_stream(
+ dk4_stream_t *strm,
+ double v,
+ int exact,
+ int minim,
+ dk4_er_t *erp
+);
+
+
+/** Write double value to stream, avoid scientific notation.
+ @param fipo File to write to.
+ @param v Value to write.
+ @param exact Flag: Exact representation.
+ @param minim Flag: Minimize an exact representation.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+
+int
+dk4c8dbl_double_to_file(
+ FILE *fipo,
+ double v,
+ int exact,
+ int minim,
+ dk4_er_t *erp
+);
+
+
+/** Write double string to stream, avoid scientific notation.
+ @param fipo File to write to.
+ @param str String containing the value.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+
+int
+dk4c8dbl_str_double_to_file(
+ FILE *fipo,
+ const char *str,
+ dk4_er_t *erp
+);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/* vim: set ai sw=4 ts=4 : */
+
+#endif
diff --git a/support/dktools/dk4conf.cross b/support/dktools/dk4conf.cross
new file mode 100644
index 0000000000..019f4d96c8
--- /dev/null
+++ b/support/dktools/dk4conf.cross
@@ -0,0 +1,3410 @@
+#ifndef DK4CONF_H_INCLUDED
+
+/** Protection against multiple inclusions. */
+#define DK4CONF_H_INCLUDED 1
+
+#include "config.h"
+
+#ifndef DK4_ON_WINDOWS
+#ifdef _WIN32
+#define DK4_ON_WINDOWS 1
+#ifndef HAVE_BACKSLASH_AS_SEP
+#define HAVE_BACKSLASH_AS_SEPŧ1
+#endif
+#else
+#define DK4_ON_WINDOWS 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_ALLOC_H
+#if HAVE_ALLOC_H
+/** DK4 version of HAVE_ALLOC_H, available.
+*/
+#define DK4_HAVE_ALLOC_H 1
+#else
+/** DK4 version of HAVE_ALLOC_H, not available.
+*/
+#define DK4_HAVE_ALLOC_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_ARPA_INET_H
+#if HAVE_ARPA_INET_H
+/** DK4 version of HAVE_ARPA_INET_H, available.
+*/
+#define DK4_HAVE_ARPA_INET_H 1
+#else
+/** DK4 version of HAVE_ARPA_INET_H, not available.
+*/
+#define DK4_HAVE_ARPA_INET_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_ASSERT_H
+#if HAVE_ASSERT_H
+/** DK4 version of HAVE_ASSERT_H, available.
+*/
+#define DK4_HAVE_ASSERT_H 1
+#else
+/** DK4 version of HAVE_ASSERT_H, not available.
+*/
+#define DK4_HAVE_ASSERT_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_BACKSLASH_AS_SEP
+#if HAVE_BACKSLASH_AS_SEP
+/** DK4 version of HAVE_BACKSLASH_AS_SEP, available.
+*/
+#define DK4_HAVE_BACKSLASH_AS_SEP 1
+#else
+/** DK4 version of HAVE_BACKSLASH_AS_SEP, not available.
+*/
+#define DK4_HAVE_BACKSLASH_AS_SEP 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_BCMP
+#if HAVE_BCMP
+/** DK4 version of HAVE_BCMP, available.
+*/
+#define DK4_HAVE_BCMP 1
+#else
+/** DK4 version of HAVE_BCMP, not available.
+*/
+#define DK4_HAVE_BCMP 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_BCOPY
+#if HAVE_BCOPY
+/** DK4 version of HAVE_BCOPY, available.
+*/
+#define DK4_HAVE_BCOPY 1
+#else
+/** DK4 version of HAVE_BCOPY, not available.
+*/
+#define DK4_HAVE_BCOPY 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_BIOS_H
+#if HAVE_BIOS_H
+/** DK4 version of HAVE_BIOS_H, available.
+*/
+#define DK4_HAVE_BIOS_H 1
+#else
+/** DK4 version of HAVE_BIOS_H, not available.
+*/
+#define DK4_HAVE_BIOS_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_BLKCNT_T
+#if HAVE_BLKCNT_T
+/** DK4 version of HAVE_BLKCNT_T, available.
+*/
+#define DK4_HAVE_BLKCNT_T 1
+#else
+/** DK4 version of HAVE_BLKCNT_T, not available.
+*/
+#define DK4_HAVE_BLKCNT_T 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_BLKSIZE_T
+#if HAVE_BLKSIZE_T
+/** DK4 version of HAVE_BLKSIZE_T, available.
+*/
+#define DK4_HAVE_BLKSIZE_T 1
+#else
+/** DK4 version of HAVE_BLKSIZE_T, not available.
+*/
+#define DK4_HAVE_BLKSIZE_T 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_BZERO
+#if HAVE_BZERO
+/** DK4 version of HAVE_BZERO, available.
+*/
+#define DK4_HAVE_BZERO 1
+#else
+/** DK4 version of HAVE_BZERO, not available.
+*/
+#define DK4_HAVE_BZERO 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_BZLIB_H
+#if HAVE_BZLIB_H
+/** DK4 version of HAVE_BZLIB_H, available.
+*/
+#define DK4_HAVE_BZLIB_H 1
+#else
+/** DK4 version of HAVE_BZLIB_H, not available.
+*/
+#define DK4_HAVE_BZLIB_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_CALLOC
+#if HAVE_CALLOC
+/** DK4 version of HAVE_CALLOC, available.
+*/
+#define DK4_HAVE_CALLOC 1
+#else
+/** DK4 version of HAVE_CALLOC, not available.
+*/
+#define DK4_HAVE_CALLOC 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_CASE_INSENSITIVE_PATHNAMES
+#if HAVE_CASE_INSENSITIVE_PATHNAMES
+/** DK4 version of HAVE_CASE_INSENSITIVE_PATHNAMES, available.
+*/
+#define DK4_HAVE_CASE_INSENSITIVE_PATHNAMES 1
+#else
+/** DK4 version of HAVE_CASE_INSENSITIVE_PATHNAMES, not available.
+*/
+#define DK4_HAVE_CASE_INSENSITIVE_PATHNAMES 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_CASE_INSENSITIVE_USERNAMES
+#if HAVE_CASE_INSENSITIVE_USERNAMES
+/** DK4 version of HAVE_CASE_INSENSITIVE_USERNAMES, available.
+*/
+#define DK4_HAVE_CASE_INSENSITIVE_USERNAMES 1
+#else
+/** DK4 version of HAVE_CASE_INSENSITIVE_USERNAMES, not available.
+*/
+#define DK4_HAVE_CASE_INSENSITIVE_USERNAMES 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_CHMOD
+#if HAVE_CHMOD
+/** DK4 version of HAVE_CHMOD, available.
+*/
+#define DK4_HAVE_CHMOD 1
+#else
+/** DK4 version of HAVE_CHMOD, not available.
+*/
+#define DK4_HAVE_CHMOD 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_CHOWN
+#if HAVE_CHOWN
+/** DK4 version of HAVE_CHOWN, available.
+*/
+#define DK4_HAVE_CHOWN 1
+#else
+/** DK4 version of HAVE_CHOWN, not available.
+*/
+#define DK4_HAVE_CHOWN 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_COMPATDKTOOLS3
+#if HAVE_COMPATDKTOOLS3
+/** DK4 version of HAVE_COMPATDKTOOLS3, available.
+*/
+#define DK4_HAVE_COMPATDKTOOLS3 1
+#else
+/** DK4 version of HAVE_COMPATDKTOOLS3, not available.
+*/
+#define DK4_HAVE_COMPATDKTOOLS3 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_COMPLEX_H
+#if HAVE_COMPLEX_H
+/** DK4 version of HAVE_COMPLEX_H, available.
+*/
+#define DK4_HAVE_COMPLEX_H 1
+#else
+/** DK4 version of HAVE_COMPLEX_H, not available.
+*/
+#define DK4_HAVE_COMPLEX_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_CTYPE_H
+#if HAVE_CTYPE_H
+/** DK4 version of HAVE_CTYPE_H, available.
+*/
+#define DK4_HAVE_CTYPE_H 1
+#else
+/** DK4 version of HAVE_CTYPE_H, not available.
+*/
+#define DK4_HAVE_CTYPE_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_DB_CURSOR_C_GET
+#if HAVE_DB_CURSOR_C_GET
+/** DK4 version of HAVE_DB_CURSOR_C_GET, available.
+*/
+#define DK4_HAVE_DB_CURSOR_C_GET 1
+#else
+/** DK4 version of HAVE_DB_CURSOR_C_GET, not available.
+*/
+#define DK4_HAVE_DB_CURSOR_C_GET 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_DB_H
+#if HAVE_DB_H
+/** DK4 version of HAVE_DB_H, available.
+*/
+#define DK4_HAVE_DB_H 1
+#else
+/** DK4 version of HAVE_DB_H, not available.
+*/
+#define DK4_HAVE_DB_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_DEV_T
+#if HAVE_DEV_T
+/** DK4 version of HAVE_DEV_T, available.
+*/
+#define DK4_HAVE_DEV_T 1
+#else
+/** DK4 version of HAVE_DEV_T, not available.
+*/
+#define DK4_HAVE_DEV_T 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_DIRECT_H
+#if HAVE_DIRECT_H
+/** DK4 version of HAVE_DIRECT_H, available.
+*/
+#define DK4_HAVE_DIRECT_H 1
+#else
+/** DK4 version of HAVE_DIRECT_H, not available.
+*/
+#define DK4_HAVE_DIRECT_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_DIRENT_H
+#if HAVE_DIRENT_H
+/** DK4 version of HAVE_DIRENT_H, available.
+*/
+#define DK4_HAVE_DIRENT_H 1
+#else
+/** DK4 version of HAVE_DIRENT_H, not available.
+*/
+#define DK4_HAVE_DIRENT_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_DOS_H
+#if HAVE_DOS_H
+/** DK4 version of HAVE_DOS_H, available.
+*/
+#define DK4_HAVE_DOS_H 1
+#else
+/** DK4 version of HAVE_DOS_H, not available.
+*/
+#define DK4_HAVE_DOS_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_ENDGRENT
+#if HAVE_ENDGRENT
+/** DK4 version of HAVE_ENDGRENT, available.
+*/
+#define DK4_HAVE_ENDGRENT 1
+#else
+/** DK4 version of HAVE_ENDGRENT, not available.
+*/
+#define DK4_HAVE_ENDGRENT 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_ENDPWENT
+#if HAVE_ENDPWENT
+/** DK4 version of HAVE_ENDPWENT, available.
+*/
+#define DK4_HAVE_ENDPWENT 1
+#else
+/** DK4 version of HAVE_ENDPWENT, not available.
+*/
+#define DK4_HAVE_ENDPWENT 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_ERRNO_H
+#if HAVE_ERRNO_H
+/** DK4 version of HAVE_ERRNO_H, available.
+*/
+#define DK4_HAVE_ERRNO_H 1
+#else
+/** DK4 version of HAVE_ERRNO_H, not available.
+*/
+#define DK4_HAVE_ERRNO_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_FCNTL_H
+#if HAVE_FCNTL_H
+/** DK4 version of HAVE_FCNTL_H, available.
+*/
+#define DK4_HAVE_FCNTL_H 1
+#else
+/** DK4 version of HAVE_FCNTL_H, not available.
+*/
+#define DK4_HAVE_FCNTL_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_FENV_H
+#if HAVE_FENV_H
+/** DK4 version of HAVE_FENV_H, available.
+*/
+#define DK4_HAVE_FENV_H 1
+#else
+/** DK4 version of HAVE_FENV_H, not available.
+*/
+#define DK4_HAVE_FENV_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_FILEMODE_BINARY
+#if HAVE_FILEMODE_BINARY
+/** DK4 version of HAVE_FILEMODE_BINARY, available.
+*/
+#define DK4_HAVE_FILEMODE_BINARY 1
+#else
+/** DK4 version of HAVE_FILEMODE_BINARY, not available.
+*/
+#define DK4_HAVE_FILEMODE_BINARY 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_FILENO
+#if HAVE_FILENO
+/** DK4 version of HAVE_FILENO, available.
+*/
+#define DK4_HAVE_FILENO 1
+#else
+/** DK4 version of HAVE_FILENO, not available.
+*/
+#define DK4_HAVE_FILENO 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_FILE_ATIMECTIME
+#if HAVE_FILE_ATIMECTIME
+/** DK4 version of HAVE_FILE_ATIMECTIME, available.
+*/
+#define DK4_HAVE_FILE_ATIMECTIME 1
+#else
+/** DK4 version of HAVE_FILE_ATIMECTIME, not available.
+*/
+#define DK4_HAVE_FILE_ATIMECTIME 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_FILE_BLKSIZECNT
+#if HAVE_FILE_BLKSIZECNT
+/** DK4 version of HAVE_FILE_BLKSIZECNT, available.
+*/
+#define DK4_HAVE_FILE_BLKSIZECNT 1
+#else
+/** DK4 version of HAVE_FILE_BLKSIZECNT, not available.
+*/
+#define DK4_HAVE_FILE_BLKSIZECNT 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_FILE_DEVINO
+#if HAVE_FILE_DEVINO
+/** DK4 version of HAVE_FILE_DEVINO, available.
+*/
+#define DK4_HAVE_FILE_DEVINO 1
+#else
+/** DK4 version of HAVE_FILE_DEVINO, not available.
+*/
+#define DK4_HAVE_FILE_DEVINO 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_FILE_UIDGID
+#if HAVE_FILE_UIDGID
+/** DK4 version of HAVE_FILE_UIDGID, available.
+*/
+#define DK4_HAVE_FILE_UIDGID 1
+#else
+/** DK4 version of HAVE_FILE_UIDGID, not available.
+*/
+#define DK4_HAVE_FILE_UIDGID 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_FLOAT_H
+#if HAVE_FLOAT_H
+/** DK4 version of HAVE_FLOAT_H, available.
+*/
+#define DK4_HAVE_FLOAT_H 1
+#else
+/** DK4 version of HAVE_FLOAT_H, not available.
+*/
+#define DK4_HAVE_FLOAT_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_FOPEN64
+#if HAVE_FOPEN64
+/** DK4 version of HAVE_FOPEN64, available.
+*/
+#define DK4_HAVE_FOPEN64 1
+#else
+/** DK4 version of HAVE_FOPEN64, not available.
+*/
+#define DK4_HAVE_FOPEN64 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_FOPEN_S
+#if HAVE_FOPEN_S
+/** DK4 version of HAVE_FOPEN_S, available.
+*/
+#define DK4_HAVE_FOPEN_S 1
+#else
+/** DK4 version of HAVE_FOPEN_S, not available.
+*/
+#define DK4_HAVE_FOPEN_S 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_FPOS_T
+#if HAVE_FPOS_T
+/** DK4 version of HAVE_FPOS_T, available.
+*/
+#define DK4_HAVE_FPOS_T 1
+#else
+/** DK4 version of HAVE_FPOS_T, not available.
+*/
+#define DK4_HAVE_FPOS_T 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_FPUTWC
+#if HAVE_FPUTWC
+/** DK4 version of HAVE_FPUTWC, available.
+*/
+#define DK4_HAVE_FPUTWC 1
+#else
+/** DK4 version of HAVE_FPUTWC, not available.
+*/
+#define DK4_HAVE_FPUTWC 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_FPUTWS
+#if HAVE_FPUTWS
+/** DK4 version of HAVE_FPUTWS, available.
+*/
+#define DK4_HAVE_FPUTWS 1
+#else
+/** DK4 version of HAVE_FPUTWS, not available.
+*/
+#define DK4_HAVE_FPUTWS 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_FREE
+#if HAVE_FREE
+/** DK4 version of HAVE_FREE, available.
+*/
+#define DK4_HAVE_FREE 1
+#else
+/** DK4 version of HAVE_FREE, not available.
+*/
+#define DK4_HAVE_FREE 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_GETADDRINFO
+#if HAVE_GETADDRINFO
+/** DK4 version of HAVE_GETADDRINFO, available.
+*/
+#define DK4_HAVE_GETADDRINFO 1
+#else
+/** DK4 version of HAVE_GETADDRINFO, not available.
+*/
+#define DK4_HAVE_GETADDRINFO 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_GETCWD
+#if HAVE_GETCWD
+/** DK4 version of HAVE_GETCWD, available.
+*/
+#define DK4_HAVE_GETCWD 1
+#else
+/** DK4 version of HAVE_GETCWD, not available.
+*/
+#define DK4_HAVE_GETCWD 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_GETENV
+#if HAVE_GETENV
+/** DK4 version of HAVE_GETENV, available.
+*/
+#define DK4_HAVE_GETENV 1
+#else
+/** DK4 version of HAVE_GETENV, not available.
+*/
+#define DK4_HAVE_GETENV 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_GETENV_S
+#if HAVE_GETENV_S
+/** DK4 version of HAVE_GETENV_S, available.
+*/
+#define DK4_HAVE_GETENV_S 1
+#else
+/** DK4 version of HAVE_GETENV_S, not available.
+*/
+#define DK4_HAVE_GETENV_S 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_GETEUID
+#if HAVE_GETEUID
+/** DK4 version of HAVE_GETEUID, available.
+*/
+#define DK4_HAVE_GETEUID 1
+#else
+/** DK4 version of HAVE_GETEUID, not available.
+*/
+#define DK4_HAVE_GETEUID 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_GETEXECNAME
+#if HAVE_GETEXECNAME
+/** DK4 version of HAVE_GETEXECNAME, available.
+*/
+#define DK4_HAVE_GETEXECNAME 1
+#else
+/** DK4 version of HAVE_GETEXECNAME, not available.
+*/
+#define DK4_HAVE_GETEXECNAME 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_GETFINALPATHNAMEBYHANDLE
+#if HAVE_GETFINALPATHNAMEBYHANDLE
+/** DK4 version of HAVE_GETFINALPATHNAMEBYHANDLE, available.
+*/
+#define DK4_HAVE_GETFINALPATHNAMEBYHANDLE 1
+#else
+/** DK4 version of HAVE_GETFINALPATHNAMEBYHANDLE, not available.
+*/
+#define DK4_HAVE_GETFINALPATHNAMEBYHANDLE 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_GETGRENT
+#if HAVE_GETGRENT
+/** DK4 version of HAVE_GETGRENT, available.
+*/
+#define DK4_HAVE_GETGRENT 1
+#else
+/** DK4 version of HAVE_GETGRENT, not available.
+*/
+#define DK4_HAVE_GETGRENT 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_GETGRGID
+#if HAVE_GETGRGID
+/** DK4 version of HAVE_GETGRGID, available.
+*/
+#define DK4_HAVE_GETGRGID 1
+#else
+/** DK4 version of HAVE_GETGRGID, not available.
+*/
+#define DK4_HAVE_GETGRGID 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_GETGRNAM
+#if HAVE_GETGRNAM
+/** DK4 version of HAVE_GETGRNAM, available.
+*/
+#define DK4_HAVE_GETGRNAM 1
+#else
+/** DK4 version of HAVE_GETGRNAM, not available.
+*/
+#define DK4_HAVE_GETGRNAM 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_GETHOSTBYNAME
+#if HAVE_GETHOSTBYNAME
+/** DK4 version of HAVE_GETHOSTBYNAME, available.
+*/
+#define DK4_HAVE_GETHOSTBYNAME 1
+#else
+/** DK4 version of HAVE_GETHOSTBYNAME, not available.
+*/
+#define DK4_HAVE_GETHOSTBYNAME 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_GETNAMEINFO
+#if HAVE_GETNAMEINFO
+/** DK4 version of HAVE_GETNAMEINFO, available.
+*/
+#define DK4_HAVE_GETNAMEINFO 1
+#else
+/** DK4 version of HAVE_GETNAMEINFO, not available.
+*/
+#define DK4_HAVE_GETNAMEINFO 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_GETPID
+#if HAVE_GETPID
+/** DK4 version of HAVE_GETPID, available.
+*/
+#define DK4_HAVE_GETPID 1
+#else
+/** DK4 version of HAVE_GETPID, not available.
+*/
+#define DK4_HAVE_GETPID 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_GETPWENT
+#if HAVE_GETPWENT
+/** DK4 version of HAVE_GETPWENT, available.
+*/
+#define DK4_HAVE_GETPWENT 1
+#else
+/** DK4 version of HAVE_GETPWENT, not available.
+*/
+#define DK4_HAVE_GETPWENT 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_GETPWNAM
+#if HAVE_GETPWNAM
+/** DK4 version of HAVE_GETPWNAM, available.
+*/
+#define DK4_HAVE_GETPWNAM 1
+#else
+/** DK4 version of HAVE_GETPWNAM, not available.
+*/
+#define DK4_HAVE_GETPWNAM 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_GETPWUID
+#if HAVE_GETPWUID
+/** DK4 version of HAVE_GETPWUID, available.
+*/
+#define DK4_HAVE_GETPWUID 1
+#else
+/** DK4 version of HAVE_GETPWUID, not available.
+*/
+#define DK4_HAVE_GETPWUID 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_GETRLIMIT
+#if HAVE_GETRLIMIT
+/** DK4 version of HAVE_GETRLIMIT, available.
+*/
+#define DK4_HAVE_GETRLIMIT 1
+#else
+/** DK4 version of HAVE_GETRLIMIT, not available.
+*/
+#define DK4_HAVE_GETRLIMIT 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_GID_T
+#if HAVE_GID_T
+/** DK4 version of HAVE_GID_T, available.
+*/
+#define DK4_HAVE_GID_T 1
+#else
+/** DK4 version of HAVE_GID_T, not available.
+*/
+#define DK4_HAVE_GID_T 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_GRP_H
+#if HAVE_GRP_H
+/** DK4 version of HAVE_GRP_H, available.
+*/
+#define DK4_HAVE_GRP_H 1
+#else
+/** DK4 version of HAVE_GRP_H, not available.
+*/
+#define DK4_HAVE_GRP_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_HTONL
+#if HAVE_HTONL
+/** DK4 version of HAVE_HTONL, available.
+*/
+#define DK4_HAVE_HTONL 1
+#else
+/** DK4 version of HAVE_HTONL, not available.
+*/
+#define DK4_HAVE_HTONL 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_HTONS
+#if HAVE_HTONS
+/** DK4 version of HAVE_HTONS, available.
+*/
+#define DK4_HAVE_HTONS 1
+#else
+/** DK4 version of HAVE_HTONS, not available.
+*/
+#define DK4_HAVE_HTONS 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_IN6_ADDR
+#if HAVE_IN6_ADDR
+/** DK4 version of HAVE_IN6_ADDR, available.
+*/
+#define DK4_HAVE_IN6_ADDR 1
+#else
+/** DK4 version of HAVE_IN6_ADDR, not available.
+*/
+#define DK4_HAVE_IN6_ADDR 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_INET_ADDR
+#if HAVE_INET_ADDR
+/** DK4 version of HAVE_INET_ADDR, available.
+*/
+#define DK4_HAVE_INET_ADDR 1
+#else
+/** DK4 version of HAVE_INET_ADDR, not available.
+*/
+#define DK4_HAVE_INET_ADDR 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_INET_ATON
+#if HAVE_INET_ATON
+/** DK4 version of HAVE_INET_ATON, available.
+*/
+#define DK4_HAVE_INET_ATON 1
+#else
+/** DK4 version of HAVE_INET_ATON, not available.
+*/
+#define DK4_HAVE_INET_ATON 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_INET_NTOP
+#if HAVE_INET_NTOP
+/** DK4 version of HAVE_INET_NTOP, available.
+*/
+#define DK4_HAVE_INET_NTOP 1
+#else
+/** DK4 version of HAVE_INET_NTOP, not available.
+*/
+#define DK4_HAVE_INET_NTOP 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_INET_PTON
+#if HAVE_INET_PTON
+/** DK4 version of HAVE_INET_PTON, available.
+*/
+#define DK4_HAVE_INET_PTON 1
+#else
+/** DK4 version of HAVE_INET_PTON, not available.
+*/
+#define DK4_HAVE_INET_PTON 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_INITSTATE
+#if HAVE_INITSTATE
+/** DK4 version of HAVE_INITSTATE, available.
+*/
+#define DK4_HAVE_INITSTATE 1
+#else
+/** DK4 version of HAVE_INITSTATE, not available.
+*/
+#define DK4_HAVE_INITSTATE 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_INLINE
+#if HAVE_INLINE
+/** DK4 version of HAVE_INLINE, available.
+*/
+#define DK4_HAVE_INLINE 1
+#else
+/** DK4 version of HAVE_INLINE, not available.
+*/
+#define DK4_HAVE_INLINE 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_INO64_T
+#if HAVE_INO64_T
+/** DK4 version of HAVE_INO64_T, available.
+*/
+#define DK4_HAVE_INO64_T 1
+#else
+/** DK4 version of HAVE_INO64_T, not available.
+*/
+#define DK4_HAVE_INO64_T 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_INO_T
+#if HAVE_INO_T
+/** DK4 version of HAVE_INO_T, available.
+*/
+#define DK4_HAVE_INO_T 1
+#else
+/** DK4 version of HAVE_INO_T, not available.
+*/
+#define DK4_HAVE_INO_T 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_INT16_T
+#if HAVE_INT16_T
+/** DK4 version of HAVE_INT16_T, available.
+*/
+#define DK4_HAVE_INT16_T 1
+#else
+/** DK4 version of HAVE_INT16_T, not available.
+*/
+#define DK4_HAVE_INT16_T 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_INT32_T
+#if HAVE_INT32_T
+/** DK4 version of HAVE_INT32_T, available.
+*/
+#define DK4_HAVE_INT32_T 1
+#else
+/** DK4 version of HAVE_INT32_T, not available.
+*/
+#define DK4_HAVE_INT32_T 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_INT8_T
+#if HAVE_INT8_T
+/** DK4 version of HAVE_INT8_T, available.
+*/
+#define DK4_HAVE_INT8_T 1
+#else
+/** DK4 version of HAVE_INT8_T, not available.
+*/
+#define DK4_HAVE_INT8_T 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_INTMAX_T
+#if HAVE_INTMAX_T
+/** DK4 version of HAVE_INTMAX_T, available.
+*/
+#define DK4_HAVE_INTMAX_T 1
+#else
+/** DK4 version of HAVE_INTMAX_T, not available.
+*/
+#define DK4_HAVE_INTMAX_T 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_INTTYPES_H
+#if HAVE_INTTYPES_H
+/** DK4 version of HAVE_INTTYPES_H, available.
+*/
+#define DK4_HAVE_INTTYPES_H 1
+#else
+/** DK4 version of HAVE_INTTYPES_H, not available.
+*/
+#define DK4_HAVE_INTTYPES_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_IN_ADDR
+#if HAVE_IN_ADDR
+/** DK4 version of HAVE_IN_ADDR, available.
+*/
+#define DK4_HAVE_IN_ADDR 1
+#else
+/** DK4 version of HAVE_IN_ADDR, not available.
+*/
+#define DK4_HAVE_IN_ADDR 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_IO_H
+#if HAVE_IO_H
+/** DK4 version of HAVE_IO_H, available.
+*/
+#define DK4_HAVE_IO_H 1
+#else
+/** DK4 version of HAVE_IO_H, not available.
+*/
+#define DK4_HAVE_IO_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_ISATTY
+#if HAVE_ISATTY
+/** DK4 version of HAVE_ISATTY, available.
+*/
+#define DK4_HAVE_ISATTY 1
+#else
+/** DK4 version of HAVE_ISATTY, not available.
+*/
+#define DK4_HAVE_ISATTY 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_ISFINITE
+#if HAVE_ISFINITE
+/** DK4 version of HAVE_ISFINITE, available.
+*/
+#define DK4_HAVE_ISFINITE 1
+#else
+/** DK4 version of HAVE_ISFINITE, not available.
+*/
+#define DK4_HAVE_ISFINITE 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_ISNORMAL
+#if HAVE_ISNORMAL
+/** DK4 version of HAVE_ISNORMAL, available.
+*/
+#define DK4_HAVE_ISNORMAL 1
+#else
+/** DK4 version of HAVE_ISNORMAL, not available.
+*/
+#define DK4_HAVE_ISNORMAL 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_ISO646_H
+#if HAVE_ISO646_H
+/** DK4 version of HAVE_ISO646_H, available.
+*/
+#define DK4_HAVE_ISO646_H 1
+#else
+/** DK4 version of HAVE_ISO646_H, not available.
+*/
+#define DK4_HAVE_ISO646_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_JPEGLIB_H
+#if HAVE_JPEGLIB_H
+/** DK4 version of HAVE_JPEGLIB_H, available.
+*/
+#define DK4_HAVE_JPEGLIB_H 1
+#else
+/** DK4 version of HAVE_JPEGLIB_H, not available.
+*/
+#define DK4_HAVE_JPEGLIB_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_LARGEFILE64_SOURCE
+#if HAVE_LARGEFILE64_SOURCE
+/** DK4 version of HAVE_LARGEFILE64_SOURCE, available.
+*/
+#define DK4_HAVE_LARGEFILE64_SOURCE 1
+#else
+/** DK4 version of HAVE_LARGEFILE64_SOURCE, not available.
+*/
+#define DK4_HAVE_LARGEFILE64_SOURCE 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_LIBNETSNMP
+#if HAVE_LIBNETSNMP
+/** DK4 version of HAVE_LIBNETSNMP, available.
+*/
+#define DK4_HAVE_LIBNETSNMP 1
+#else
+/** DK4 version of HAVE_LIBNETSNMP, not available.
+*/
+#define DK4_HAVE_LIBNETSNMP 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_LIMITS_H
+#if HAVE_LIMITS_H
+/** DK4 version of HAVE_LIMITS_H, available.
+*/
+#define DK4_HAVE_LIMITS_H 1
+#else
+/** DK4 version of HAVE_LIMITS_H, not available.
+*/
+#define DK4_HAVE_LIMITS_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_LINE_END_CR_NL
+#if HAVE_LINE_END_CR_NL
+/** DK4 version of HAVE_LINE_END_CR_NL, available.
+*/
+#define DK4_HAVE_LINE_END_CR_NL 1
+#else
+/** DK4 version of HAVE_LINE_END_CR_NL, not available.
+*/
+#define DK4_HAVE_LINE_END_CR_NL 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_LOCALE_H
+#if HAVE_LOCALE_H
+/** DK4 version of HAVE_LOCALE_H, available.
+*/
+#define DK4_HAVE_LOCALE_H 1
+#else
+/** DK4 version of HAVE_LOCALE_H, not available.
+*/
+#define DK4_HAVE_LOCALE_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_LOCALTIME_R
+#if HAVE_LOCALTIME_R
+/** DK4 version of HAVE_LOCALTIME_R, available.
+*/
+#define DK4_HAVE_LOCALTIME_R 1
+#else
+/** DK4 version of HAVE_LOCALTIME_R, not available.
+*/
+#define DK4_HAVE_LOCALTIME_R 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_LONG_DOUBLE
+#if HAVE_LONG_DOUBLE
+/** DK4 version of HAVE_LONG_DOUBLE, available.
+*/
+#define DK4_HAVE_LONG_DOUBLE 1
+#else
+/** DK4 version of HAVE_LONG_DOUBLE, not available.
+*/
+#define DK4_HAVE_LONG_DOUBLE 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_LONG_LONG
+#if HAVE_LONG_LONG
+/** DK4 version of HAVE_LONG_LONG, available.
+*/
+#define DK4_HAVE_LONG_LONG 1
+#else
+/** DK4 version of HAVE_LONG_LONG, not available.
+*/
+#define DK4_HAVE_LONG_LONG 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_LRAND48
+#if HAVE_LRAND48
+/** DK4 version of HAVE_LRAND48, available.
+*/
+#define DK4_HAVE_LRAND48 1
+#else
+/** DK4 version of HAVE_LRAND48, not available.
+*/
+#define DK4_HAVE_LRAND48 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_LSTAT
+#if HAVE_LSTAT
+/** DK4 version of HAVE_LSTAT, available.
+*/
+#define DK4_HAVE_LSTAT 1
+#else
+/** DK4 version of HAVE_LSTAT, not available.
+*/
+#define DK4_HAVE_LSTAT 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_LSTAT64
+#if HAVE_LSTAT64
+/** DK4 version of HAVE_LSTAT64, available.
+*/
+#define DK4_HAVE_LSTAT64 1
+#else
+/** DK4 version of HAVE_LSTAT64, not available.
+*/
+#define DK4_HAVE_LSTAT64 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_MALLOC
+#if HAVE_MALLOC
+/** DK4 version of HAVE_MALLOC, available.
+*/
+#define DK4_HAVE_MALLOC 1
+#else
+/** DK4 version of HAVE_MALLOC, not available.
+*/
+#define DK4_HAVE_MALLOC 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_MALLOC_H
+#if HAVE_MALLOC_H
+/** DK4 version of HAVE_MALLOC_H, available.
+*/
+#define DK4_HAVE_MALLOC_H 1
+#else
+/** DK4 version of HAVE_MALLOC_H, not available.
+*/
+#define DK4_HAVE_MALLOC_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_MATH_H
+#if HAVE_MATH_H
+/** DK4 version of HAVE_MATH_H, available.
+*/
+#define DK4_HAVE_MATH_H 1
+#else
+/** DK4 version of HAVE_MATH_H, not available.
+*/
+#define DK4_HAVE_MATH_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_MEMCMP
+#if HAVE_MEMCMP
+/** DK4 version of HAVE_MEMCMP, available.
+*/
+#define DK4_HAVE_MEMCMP 1
+#else
+/** DK4 version of HAVE_MEMCMP, not available.
+*/
+#define DK4_HAVE_MEMCMP 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_MEMCPY
+#if HAVE_MEMCPY
+/** DK4 version of HAVE_MEMCPY, available.
+*/
+#define DK4_HAVE_MEMCPY 1
+#else
+/** DK4 version of HAVE_MEMCPY, not available.
+*/
+#define DK4_HAVE_MEMCPY 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_MEMSET
+#if HAVE_MEMSET
+/** DK4 version of HAVE_MEMSET, available.
+*/
+#define DK4_HAVE_MEMSET 1
+#else
+/** DK4 version of HAVE_MEMSET, not available.
+*/
+#define DK4_HAVE_MEMSET 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_MKDIR
+#if HAVE_MKDIR
+/** DK4 version of HAVE_MKDIR, available.
+*/
+#define DK4_HAVE_MKDIR 1
+#else
+/** DK4 version of HAVE_MKDIR, not available.
+*/
+#define DK4_HAVE_MKDIR 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_MODE_T
+#if HAVE_MODE_T
+/** DK4 version of HAVE_MODE_T, available.
+*/
+#define DK4_HAVE_MODE_T 1
+#else
+/** DK4 version of HAVE_MODE_T, not available.
+*/
+#define DK4_HAVE_MODE_T 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_NDBM_H
+#if HAVE_NDBM_H
+/** DK4 version of HAVE_NDBM_H, available.
+*/
+#define DK4_HAVE_NDBM_H 1
+#else
+/** DK4 version of HAVE_NDBM_H, not available.
+*/
+#define DK4_HAVE_NDBM_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_NETDB_H
+#if HAVE_NETDB_H
+/** DK4 version of HAVE_NETDB_H, available.
+*/
+#define DK4_HAVE_NETDB_H 1
+#else
+/** DK4 version of HAVE_NETDB_H, not available.
+*/
+#define DK4_HAVE_NETDB_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_NETINET_IN6_H
+#if HAVE_NETINET_IN6_H
+/** DK4 version of HAVE_NETINET_IN6_H, available.
+*/
+#define DK4_HAVE_NETINET_IN6_H 1
+#else
+/** DK4 version of HAVE_NETINET_IN6_H, not available.
+*/
+#define DK4_HAVE_NETINET_IN6_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_NETINET_IN_H
+#if HAVE_NETINET_IN_H
+/** DK4 version of HAVE_NETINET_IN_H, available.
+*/
+#define DK4_HAVE_NETINET_IN_H 1
+#else
+/** DK4 version of HAVE_NETINET_IN_H, not available.
+*/
+#define DK4_HAVE_NETINET_IN_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_NLINK_T
+#if HAVE_NLINK_T
+/** DK4 version of HAVE_NLINK_T, available.
+*/
+#define DK4_HAVE_NLINK_T 1
+#else
+/** DK4 version of HAVE_NLINK_T, not available.
+*/
+#define DK4_HAVE_NLINK_T 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_NRAND48
+#if HAVE_NRAND48
+/** DK4 version of HAVE_NRAND48, available.
+*/
+#define DK4_HAVE_NRAND48 1
+#else
+/** DK4 version of HAVE_NRAND48, not available.
+*/
+#define DK4_HAVE_NRAND48 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_NTIFS_H
+#if HAVE_NTIFS_H
+/** DK4 version of HAVE_NTIFS_H, available.
+*/
+#define DK4_HAVE_NTIFS_H 1
+#else
+/** DK4 version of HAVE_NTIFS_H, not available.
+*/
+#define DK4_HAVE_NTIFS_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_NTOHL
+#if HAVE_NTOHL
+/** DK4 version of HAVE_NTOHL, available.
+*/
+#define DK4_HAVE_NTOHL 1
+#else
+/** DK4 version of HAVE_NTOHL, not available.
+*/
+#define DK4_HAVE_NTOHL 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_NTOHS
+#if HAVE_NTOHS
+/** DK4 version of HAVE_NTOHS, available.
+*/
+#define DK4_HAVE_NTOHS 1
+#else
+/** DK4 version of HAVE_NTOHS, not available.
+*/
+#define DK4_HAVE_NTOHS 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_OFF64_T
+#if HAVE_OFF64_T
+/** DK4 version of HAVE_OFF64_T, available.
+*/
+#define DK4_HAVE_OFF64_T 1
+#else
+/** DK4 version of HAVE_OFF64_T, not available.
+*/
+#define DK4_HAVE_OFF64_T 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_OFF_T
+#if HAVE_OFF_T
+/** DK4 version of HAVE_OFF_T, available.
+*/
+#define DK4_HAVE_OFF_T 1
+#else
+/** DK4 version of HAVE_OFF_T, not available.
+*/
+#define DK4_HAVE_OFF_T 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_OPENSSL_MD5_H
+#if HAVE_OPENSSL_MD5_H
+/** DK4 version of HAVE_OPENSSL_MD5_H, available.
+*/
+#define DK4_HAVE_OPENSSL_MD5_H 1
+#else
+/** DK4 version of HAVE_OPENSSL_MD5_H, not available.
+*/
+#define DK4_HAVE_OPENSSL_MD5_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_OPENSSL_RAND_H
+#if HAVE_OPENSSL_RAND_H
+/** DK4 version of HAVE_OPENSSL_RAND_H, available.
+*/
+#define DK4_HAVE_OPENSSL_RAND_H 1
+#else
+/** DK4 version of HAVE_OPENSSL_RAND_H, not available.
+*/
+#define DK4_HAVE_OPENSSL_RAND_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_OPENSSL_RIPEMD_H
+#if HAVE_OPENSSL_RIPEMD_H
+/** DK4 version of HAVE_OPENSSL_RIPEMD_H, available.
+*/
+#define DK4_HAVE_OPENSSL_RIPEMD_H 1
+#else
+/** DK4 version of HAVE_OPENSSL_RIPEMD_H, not available.
+*/
+#define DK4_HAVE_OPENSSL_RIPEMD_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_OPENSSL_SHA_H
+#if HAVE_OPENSSL_SHA_H
+/** DK4 version of HAVE_OPENSSL_SHA_H, available.
+*/
+#define DK4_HAVE_OPENSSL_SHA_H 1
+#else
+/** DK4 version of HAVE_OPENSSL_SHA_H, not available.
+*/
+#define DK4_HAVE_OPENSSL_SHA_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_PNG_GET_PIXELS_PER_INCH
+#if HAVE_PNG_GET_PIXELS_PER_INCH
+/** DK4 version of HAVE_PNG_GET_PIXELS_PER_INCH, available.
+*/
+#define DK4_HAVE_PNG_GET_PIXELS_PER_INCH 1
+#else
+/** DK4 version of HAVE_PNG_GET_PIXELS_PER_INCH, not available.
+*/
+#define DK4_HAVE_PNG_GET_PIXELS_PER_INCH 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_PNG_H
+#if HAVE_PNG_H
+/** DK4 version of HAVE_PNG_H, available.
+*/
+#define DK4_HAVE_PNG_H 1
+#else
+/** DK4 version of HAVE_PNG_H, not available.
+*/
+#define DK4_HAVE_PNG_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_PROCESS_H
+#if HAVE_PROCESS_H
+/** DK4 version of HAVE_PROCESS_H, available.
+*/
+#define DK4_HAVE_PROCESS_H 1
+#else
+/** DK4 version of HAVE_PROCESS_H, not available.
+*/
+#define DK4_HAVE_PROCESS_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_PROC_PID_EXE
+#if HAVE_PROC_PID_EXE
+/** DK4 version of HAVE_PROC_PID_EXE, available.
+*/
+#define DK4_HAVE_PROC_PID_EXE 1
+#else
+/** DK4 version of HAVE_PROC_PID_EXE, not available.
+*/
+#define DK4_HAVE_PROC_PID_EXE 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_PWD_H
+#if HAVE_PWD_H
+/** DK4 version of HAVE_PWD_H, available.
+*/
+#define DK4_HAVE_PWD_H 1
+#else
+/** DK4 version of HAVE_PWD_H, not available.
+*/
+#define DK4_HAVE_PWD_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_RAND
+#if HAVE_RAND
+/** DK4 version of HAVE_RAND, available.
+*/
+#define DK4_HAVE_RAND 1
+#else
+/** DK4 version of HAVE_RAND, not available.
+*/
+#define DK4_HAVE_RAND 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_RANDOM
+#if HAVE_RANDOM
+/** DK4 version of HAVE_RANDOM, available.
+*/
+#define DK4_HAVE_RANDOM 1
+#else
+/** DK4 version of HAVE_RANDOM, not available.
+*/
+#define DK4_HAVE_RANDOM 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_RAND_EGD
+#if HAVE_RAND_EGD
+/** DK4 version of HAVE_RAND_EGD, available.
+*/
+#define DK4_HAVE_RAND_EGD 1
+#else
+/** DK4 version of HAVE_RAND_EGD, not available.
+*/
+#define DK4_HAVE_RAND_EGD 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_READ
+#if HAVE_READ
+/** DK4 version of HAVE_READ, available.
+*/
+#define DK4_HAVE_READ 1
+#else
+/** DK4 version of HAVE_READ, not available.
+*/
+#define DK4_HAVE_READ 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_READLINK
+#if HAVE_READLINK
+/** DK4 version of HAVE_READLINK, available.
+*/
+#define DK4_HAVE_READLINK 1
+#else
+/** DK4 version of HAVE_READLINK, not available.
+*/
+#define DK4_HAVE_READLINK 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_RMDIR
+#if HAVE_RMDIR
+/** DK4 version of HAVE_RMDIR, available.
+*/
+#define DK4_HAVE_RMDIR 1
+#else
+/** DK4 version of HAVE_RMDIR, not available.
+*/
+#define DK4_HAVE_RMDIR 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SELECT
+#if HAVE_SELECT
+/** DK4 version of HAVE_SELECT, available.
+*/
+#define DK4_HAVE_SELECT 1
+#else
+/** DK4 version of HAVE_SELECT, not available.
+*/
+#define DK4_HAVE_SELECT 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SETBUF
+#if HAVE_SETBUF
+/** DK4 version of HAVE_SETBUF, available.
+*/
+#define DK4_HAVE_SETBUF 1
+#else
+/** DK4 version of HAVE_SETBUF, not available.
+*/
+#define DK4_HAVE_SETBUF 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SETBUFFER
+#if HAVE_SETBUFFER
+/** DK4 version of HAVE_SETBUFFER, available.
+*/
+#define DK4_HAVE_SETBUFFER 1
+#else
+/** DK4 version of HAVE_SETBUFFER, not available.
+*/
+#define DK4_HAVE_SETBUFFER 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SETGID
+#if HAVE_SETGID
+/** DK4 version of HAVE_SETGID, available.
+*/
+#define DK4_HAVE_SETGID 1
+#else
+/** DK4 version of HAVE_SETGID, not available.
+*/
+#define DK4_HAVE_SETGID 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SETGRENT
+#if HAVE_SETGRENT
+/** DK4 version of HAVE_SETGRENT, available.
+*/
+#define DK4_HAVE_SETGRENT 1
+#else
+/** DK4 version of HAVE_SETGRENT, not available.
+*/
+#define DK4_HAVE_SETGRENT 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SETJMP_H
+#if HAVE_SETJMP_H
+/** DK4 version of HAVE_SETJMP_H, available.
+*/
+#define DK4_HAVE_SETJMP_H 1
+#else
+/** DK4 version of HAVE_SETJMP_H, not available.
+*/
+#define DK4_HAVE_SETJMP_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SETLOCALE
+#if HAVE_SETLOCALE
+/** DK4 version of HAVE_SETLOCALE, available.
+*/
+#define DK4_HAVE_SETLOCALE 1
+#else
+/** DK4 version of HAVE_SETLOCALE, not available.
+*/
+#define DK4_HAVE_SETLOCALE 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SETMODE
+#if HAVE_SETMODE
+/** DK4 version of HAVE_SETMODE, available.
+*/
+#define DK4_HAVE_SETMODE 1
+#else
+/** DK4 version of HAVE_SETMODE, not available.
+*/
+#define DK4_HAVE_SETMODE 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SETPGRP
+#if HAVE_SETPGRP
+/** DK4 version of HAVE_SETPGRP, available.
+*/
+#define DK4_HAVE_SETPGRP 1
+#else
+/** DK4 version of HAVE_SETPGRP, not available.
+*/
+#define DK4_HAVE_SETPGRP 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SETPWENT
+#if HAVE_SETPWENT
+/** DK4 version of HAVE_SETPWENT, available.
+*/
+#define DK4_HAVE_SETPWENT 1
+#else
+/** DK4 version of HAVE_SETPWENT, not available.
+*/
+#define DK4_HAVE_SETPWENT 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SETSID
+#if HAVE_SETSID
+/** DK4 version of HAVE_SETSID, available.
+*/
+#define DK4_HAVE_SETSID 1
+#else
+/** DK4 version of HAVE_SETSID, not available.
+*/
+#define DK4_HAVE_SETSID 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SETSOCKOPT
+#if HAVE_SETSOCKOPT
+/** DK4 version of HAVE_SETSOCKOPT, available.
+*/
+#define DK4_HAVE_SETSOCKOPT 1
+#else
+/** DK4 version of HAVE_SETSOCKOPT, not available.
+*/
+#define DK4_HAVE_SETSOCKOPT 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SETSTATE
+#if HAVE_SETSTATE
+/** DK4 version of HAVE_SETSTATE, available.
+*/
+#define DK4_HAVE_SETSTATE 1
+#else
+/** DK4 version of HAVE_SETSTATE, not available.
+*/
+#define DK4_HAVE_SETSTATE 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SETUID
+#if HAVE_SETUID
+/** DK4 version of HAVE_SETUID, available.
+*/
+#define DK4_HAVE_SETUID 1
+#else
+/** DK4 version of HAVE_SETUID, not available.
+*/
+#define DK4_HAVE_SETUID 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SETVBUF
+#if HAVE_SETVBUF
+/** DK4 version of HAVE_SETVBUF, available.
+*/
+#define DK4_HAVE_SETVBUF 1
+#else
+/** DK4 version of HAVE_SETVBUF, not available.
+*/
+#define DK4_HAVE_SETVBUF 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SHA224
+#if HAVE_SHA224
+/** DK4 version of HAVE_SHA224, available.
+*/
+#define DK4_HAVE_SHA224 1
+#else
+/** DK4 version of HAVE_SHA224, not available.
+*/
+#define DK4_HAVE_SHA224 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SHA256
+#if HAVE_SHA256
+/** DK4 version of HAVE_SHA256, available.
+*/
+#define DK4_HAVE_SHA256 1
+#else
+/** DK4 version of HAVE_SHA256, not available.
+*/
+#define DK4_HAVE_SHA256 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SHA384
+#if HAVE_SHA384
+/** DK4 version of HAVE_SHA384, available.
+*/
+#define DK4_HAVE_SHA384 1
+#else
+/** DK4 version of HAVE_SHA384, not available.
+*/
+#define DK4_HAVE_SHA384 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SHA512
+#if HAVE_SHA512
+/** DK4 version of HAVE_SHA512, available.
+*/
+#define DK4_HAVE_SHA512 1
+#else
+/** DK4 version of HAVE_SHA512, not available.
+*/
+#define DK4_HAVE_SHA512 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SHARE_H
+#if HAVE_SHARE_H
+/** DK4 version of HAVE_SHARE_H, available.
+*/
+#define DK4_HAVE_SHARE_H 1
+#else
+/** DK4 version of HAVE_SHARE_H, not available.
+*/
+#define DK4_HAVE_SHARE_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SIGACTION
+#if HAVE_SIGACTION
+/** DK4 version of HAVE_SIGACTION, available.
+*/
+#define DK4_HAVE_SIGACTION 1
+#else
+/** DK4 version of HAVE_SIGACTION, not available.
+*/
+#define DK4_HAVE_SIGACTION 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SIGEMPTYSET
+#if HAVE_SIGEMPTYSET
+/** DK4 version of HAVE_SIGEMPTYSET, available.
+*/
+#define DK4_HAVE_SIGEMPTYSET 1
+#else
+/** DK4 version of HAVE_SIGEMPTYSET, not available.
+*/
+#define DK4_HAVE_SIGEMPTYSET 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SIGNAL
+#if HAVE_SIGNAL
+/** DK4 version of HAVE_SIGNAL, available.
+*/
+#define DK4_HAVE_SIGNAL 1
+#else
+/** DK4 version of HAVE_SIGNAL, not available.
+*/
+#define DK4_HAVE_SIGNAL 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SIGNAL_H
+#if HAVE_SIGNAL_H
+/** DK4 version of HAVE_SIGNAL_H, available.
+*/
+#define DK4_HAVE_SIGNAL_H 1
+#else
+/** DK4 version of HAVE_SIGNAL_H, not available.
+*/
+#define DK4_HAVE_SIGNAL_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SIGPROCMASK
+#if HAVE_SIGPROCMASK
+/** DK4 version of HAVE_SIGPROCMASK, available.
+*/
+#define DK4_HAVE_SIGPROCMASK 1
+#else
+/** DK4 version of HAVE_SIGPROCMASK, not available.
+*/
+#define DK4_HAVE_SIGPROCMASK 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SIGSET
+#if HAVE_SIGSET
+/** DK4 version of HAVE_SIGSET, available.
+*/
+#define DK4_HAVE_SIGSET 1
+#else
+/** DK4 version of HAVE_SIGSET, not available.
+*/
+#define DK4_HAVE_SIGSET 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SIG_ATOMIC_T
+#if HAVE_SIG_ATOMIC_T
+/** DK4 version of HAVE_SIG_ATOMIC_T, available.
+*/
+#define DK4_HAVE_SIG_ATOMIC_T 1
+#else
+/** DK4 version of HAVE_SIG_ATOMIC_T, not available.
+*/
+#define DK4_HAVE_SIG_ATOMIC_T 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SNMP_DISABLE_FILELOG
+#if HAVE_SNMP_DISABLE_FILELOG
+/** DK4 version of HAVE_SNMP_DISABLE_FILELOG, available.
+*/
+#define DK4_HAVE_SNMP_DISABLE_FILELOG 1
+#else
+/** DK4 version of HAVE_SNMP_DISABLE_FILELOG, not available.
+*/
+#define DK4_HAVE_SNMP_DISABLE_FILELOG 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SNMP_DISABLE_STDERRLOG
+#if HAVE_SNMP_DISABLE_STDERRLOG
+/** DK4 version of HAVE_SNMP_DISABLE_STDERRLOG, available.
+*/
+#define DK4_HAVE_SNMP_DISABLE_STDERRLOG 1
+#else
+/** DK4 version of HAVE_SNMP_DISABLE_STDERRLOG, not available.
+*/
+#define DK4_HAVE_SNMP_DISABLE_STDERRLOG 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SNMP_DISABLE_SYSLOG
+#if HAVE_SNMP_DISABLE_SYSLOG
+/** DK4 version of HAVE_SNMP_DISABLE_SYSLOG, available.
+*/
+#define DK4_HAVE_SNMP_DISABLE_SYSLOG 1
+#else
+/** DK4 version of HAVE_SNMP_DISABLE_SYSLOG, not available.
+*/
+#define DK4_HAVE_SNMP_DISABLE_SYSLOG 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SNMP_ENABLE_FILELOG
+#if HAVE_SNMP_ENABLE_FILELOG
+/** DK4 version of HAVE_SNMP_ENABLE_FILELOG, available.
+*/
+#define DK4_HAVE_SNMP_ENABLE_FILELOG 1
+#else
+/** DK4 version of HAVE_SNMP_ENABLE_FILELOG, not available.
+*/
+#define DK4_HAVE_SNMP_ENABLE_FILELOG 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SNPRINTF
+#if HAVE_SNPRINTF
+/** DK4 version of HAVE_SNPRINTF, available.
+*/
+#define DK4_HAVE_SNPRINTF 1
+#else
+/** DK4 version of HAVE_SNPRINTF, not available.
+*/
+#define DK4_HAVE_SNPRINTF 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SNWPRINTF
+#if HAVE_SNWPRINTF
+/** DK4 version of HAVE_SNWPRINTF, available.
+*/
+#define DK4_HAVE_SNWPRINTF 1
+#else
+/** DK4 version of HAVE_SNWPRINTF, not available.
+*/
+#define DK4_HAVE_SNWPRINTF 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SOCKET
+#if HAVE_SOCKET
+/** DK4 version of HAVE_SOCKET, available.
+*/
+#define DK4_HAVE_SOCKET 1
+#else
+/** DK4 version of HAVE_SOCKET, not available.
+*/
+#define DK4_HAVE_SOCKET 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SOCKLEN_T
+#if HAVE_SOCKLEN_T
+/** DK4 version of HAVE_SOCKLEN_T, available.
+*/
+#define DK4_HAVE_SOCKLEN_T 1
+#else
+/** DK4 version of HAVE_SOCKLEN_T, not available.
+*/
+#define DK4_HAVE_SOCKLEN_T 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SRAND
+#if HAVE_SRAND
+/** DK4 version of HAVE_SRAND, available.
+*/
+#define DK4_HAVE_SRAND 1
+#else
+/** DK4 version of HAVE_SRAND, not available.
+*/
+#define DK4_HAVE_SRAND 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SSIZE_T
+#if HAVE_SSIZE_T
+/** DK4 version of HAVE_SSIZE_T, available.
+*/
+#define DK4_HAVE_SSIZE_T 1
+#else
+/** DK4 version of HAVE_SSIZE_T, not available.
+*/
+#define DK4_HAVE_SSIZE_T 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_STAT64
+#if HAVE_STAT64
+/** DK4 version of HAVE_STAT64, available.
+*/
+#define DK4_HAVE_STAT64 1
+#else
+/** DK4 version of HAVE_STAT64, not available.
+*/
+#define DK4_HAVE_STAT64 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_STDALIGN_H
+#if HAVE_STDALIGN_H
+/** DK4 version of HAVE_STDALIGN_H, available.
+*/
+#define DK4_HAVE_STDALIGN_H 1
+#else
+/** DK4 version of HAVE_STDALIGN_H, not available.
+*/
+#define DK4_HAVE_STDALIGN_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_STDARG_H
+#if HAVE_STDARG_H
+/** DK4 version of HAVE_STDARG_H, available.
+*/
+#define DK4_HAVE_STDARG_H 1
+#else
+/** DK4 version of HAVE_STDARG_H, not available.
+*/
+#define DK4_HAVE_STDARG_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_STDATOMIC_H
+#if HAVE_STDATOMIC_H
+/** DK4 version of HAVE_STDATOMIC_H, available.
+*/
+#define DK4_HAVE_STDATOMIC_H 1
+#else
+/** DK4 version of HAVE_STDATOMIC_H, not available.
+*/
+#define DK4_HAVE_STDATOMIC_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_STDBOOL_H
+#if HAVE_STDBOOL_H
+/** DK4 version of HAVE_STDBOOL_H, available.
+*/
+#define DK4_HAVE_STDBOOL_H 1
+#else
+/** DK4 version of HAVE_STDBOOL_H, not available.
+*/
+#define DK4_HAVE_STDBOOL_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_STDDEF_H
+#if HAVE_STDDEF_H
+/** DK4 version of HAVE_STDDEF_H, available.
+*/
+#define DK4_HAVE_STDDEF_H 1
+#else
+/** DK4 version of HAVE_STDDEF_H, not available.
+*/
+#define DK4_HAVE_STDDEF_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_STDINT_H
+#if HAVE_STDINT_H
+/** DK4 version of HAVE_STDINT_H, available.
+*/
+#define DK4_HAVE_STDINT_H 1
+#else
+/** DK4 version of HAVE_STDINT_H, not available.
+*/
+#define DK4_HAVE_STDINT_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_STDLIB_H
+#if HAVE_STDLIB_H
+/** DK4 version of HAVE_STDLIB_H, available.
+*/
+#define DK4_HAVE_STDLIB_H 1
+#else
+/** DK4 version of HAVE_STDLIB_H, not available.
+*/
+#define DK4_HAVE_STDLIB_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_STDNORETURN_H
+#if HAVE_STDNORETURN_H
+/** DK4 version of HAVE_STDNORETURN_H, available.
+*/
+#define DK4_HAVE_STDNORETURN_H 1
+#else
+/** DK4 version of HAVE_STDNORETURN_H, not available.
+*/
+#define DK4_HAVE_STDNORETURN_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_STRCASECMP
+#if HAVE_STRCASECMP
+/** DK4 version of HAVE_STRCASECMP, available.
+*/
+#define DK4_HAVE_STRCASECMP 1
+#else
+/** DK4 version of HAVE_STRCASECMP, not available.
+*/
+#define DK4_HAVE_STRCASECMP 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_STRCAT_S
+#if HAVE_STRCAT_S
+/** DK4 version of HAVE_STRCAT_S, available.
+*/
+#define DK4_HAVE_STRCAT_S 1
+#else
+/** DK4 version of HAVE_STRCAT_S, not available.
+*/
+#define DK4_HAVE_STRCAT_S 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_STRCPY_S
+#if HAVE_STRCPY_S
+/** DK4 version of HAVE_STRCPY_S, available.
+*/
+#define DK4_HAVE_STRCPY_S 1
+#else
+/** DK4 version of HAVE_STRCPY_S, not available.
+*/
+#define DK4_HAVE_STRCPY_S 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_STRERROR
+#if HAVE_STRERROR
+/** DK4 version of HAVE_STRERROR, available.
+*/
+#define DK4_HAVE_STRERROR 1
+#else
+/** DK4 version of HAVE_STRERROR, not available.
+*/
+#define DK4_HAVE_STRERROR 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_STRERROR_R
+#if HAVE_STRERROR_R
+/** DK4 version of HAVE_STRERROR_R, available.
+*/
+#define DK4_HAVE_STRERROR_R 1
+#else
+/** DK4 version of HAVE_STRERROR_R, not available.
+*/
+#define DK4_HAVE_STRERROR_R 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_STRICMP
+#if HAVE_STRICMP
+/** DK4 version of HAVE_STRICMP, available.
+*/
+#define DK4_HAVE_STRICMP 1
+#else
+/** DK4 version of HAVE_STRICMP, not available.
+*/
+#define DK4_HAVE_STRICMP 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_STRINGS_H
+#if HAVE_STRINGS_H
+/** DK4 version of HAVE_STRINGS_H, available.
+*/
+#define DK4_HAVE_STRINGS_H 1
+#else
+/** DK4 version of HAVE_STRINGS_H, not available.
+*/
+#define DK4_HAVE_STRINGS_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_STRING_H
+#if HAVE_STRING_H
+/** DK4 version of HAVE_STRING_H, available.
+*/
+#define DK4_HAVE_STRING_H 1
+#else
+/** DK4 version of HAVE_STRING_H, not available.
+*/
+#define DK4_HAVE_STRING_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_STRTOD
+#if HAVE_STRTOD
+/** DK4 version of HAVE_STRTOD, available.
+*/
+#define DK4_HAVE_STRTOD 1
+#else
+/** DK4 version of HAVE_STRTOD, not available.
+*/
+#define DK4_HAVE_STRTOD 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_STRUCT_ADDRINFO
+#if HAVE_STRUCT_ADDRINFO
+/** DK4 version of HAVE_STRUCT_ADDRINFO, available.
+*/
+#define DK4_HAVE_STRUCT_ADDRINFO 1
+#else
+/** DK4 version of HAVE_STRUCT_ADDRINFO, not available.
+*/
+#define DK4_HAVE_STRUCT_ADDRINFO 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_STRUCT_SOCKADDR_IN
+#if HAVE_STRUCT_SOCKADDR_IN
+/** DK4 version of HAVE_STRUCT_SOCKADDR_IN, available.
+*/
+#define DK4_HAVE_STRUCT_SOCKADDR_IN 1
+#else
+/** DK4 version of HAVE_STRUCT_SOCKADDR_IN, not available.
+*/
+#define DK4_HAVE_STRUCT_SOCKADDR_IN 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_STRUCT_SOCKADDR_IN6
+#if HAVE_STRUCT_SOCKADDR_IN6
+/** DK4 version of HAVE_STRUCT_SOCKADDR_IN6, available.
+*/
+#define DK4_HAVE_STRUCT_SOCKADDR_IN6 1
+#else
+/** DK4 version of HAVE_STRUCT_SOCKADDR_IN6, not available.
+*/
+#define DK4_HAVE_STRUCT_SOCKADDR_IN6 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_STRUCT_SOCKADDR_STORAGE
+#if HAVE_STRUCT_SOCKADDR_STORAGE
+/** DK4 version of HAVE_STRUCT_SOCKADDR_STORAGE, available.
+*/
+#define DK4_HAVE_STRUCT_SOCKADDR_STORAGE 1
+#else
+/** DK4 version of HAVE_STRUCT_SOCKADDR_STORAGE, not available.
+*/
+#define DK4_HAVE_STRUCT_SOCKADDR_STORAGE 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_STRUCT_SOCKADDR_UN
+#if HAVE_STRUCT_SOCKADDR_UN
+/** DK4 version of HAVE_STRUCT_SOCKADDR_UN, available.
+*/
+#define DK4_HAVE_STRUCT_SOCKADDR_UN 1
+#else
+/** DK4 version of HAVE_STRUCT_SOCKADDR_UN, not available.
+*/
+#define DK4_HAVE_STRUCT_SOCKADDR_UN 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SWPRINTF
+#if HAVE_SWPRINTF
+/** DK4 version of HAVE_SWPRINTF, available.
+*/
+#define DK4_HAVE_SWPRINTF 1
+#else
+/** DK4 version of HAVE_SWPRINTF, not available.
+*/
+#define DK4_HAVE_SWPRINTF 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SYSLOG
+#if HAVE_SYSLOG
+/** DK4 version of HAVE_SYSLOG, available.
+*/
+#define DK4_HAVE_SYSLOG 1
+#else
+/** DK4 version of HAVE_SYSLOG, not available.
+*/
+#define DK4_HAVE_SYSLOG 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SYSLOG_H
+#if HAVE_SYSLOG_H
+/** DK4 version of HAVE_SYSLOG_H, available.
+*/
+#define DK4_HAVE_SYSLOG_H 1
+#else
+/** DK4 version of HAVE_SYSLOG_H, not available.
+*/
+#define DK4_HAVE_SYSLOG_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SYS_PARAM_H
+#if HAVE_SYS_PARAM_H
+/** DK4 version of HAVE_SYS_PARAM_H, available.
+*/
+#define DK4_HAVE_SYS_PARAM_H 1
+#else
+/** DK4 version of HAVE_SYS_PARAM_H, not available.
+*/
+#define DK4_HAVE_SYS_PARAM_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SYS_RESOURCE_H
+#if HAVE_SYS_RESOURCE_H
+/** DK4 version of HAVE_SYS_RESOURCE_H, available.
+*/
+#define DK4_HAVE_SYS_RESOURCE_H 1
+#else
+/** DK4 version of HAVE_SYS_RESOURCE_H, not available.
+*/
+#define DK4_HAVE_SYS_RESOURCE_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SYS_SELECT_H
+#if HAVE_SYS_SELECT_H
+/** DK4 version of HAVE_SYS_SELECT_H, available.
+*/
+#define DK4_HAVE_SYS_SELECT_H 1
+#else
+/** DK4 version of HAVE_SYS_SELECT_H, not available.
+*/
+#define DK4_HAVE_SYS_SELECT_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SYS_SOCKET_H
+#if HAVE_SYS_SOCKET_H
+/** DK4 version of HAVE_SYS_SOCKET_H, available.
+*/
+#define DK4_HAVE_SYS_SOCKET_H 1
+#else
+/** DK4 version of HAVE_SYS_SOCKET_H, not available.
+*/
+#define DK4_HAVE_SYS_SOCKET_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SYS_STAT_H
+#if HAVE_SYS_STAT_H
+/** DK4 version of HAVE_SYS_STAT_H, available.
+*/
+#define DK4_HAVE_SYS_STAT_H 1
+#else
+/** DK4 version of HAVE_SYS_STAT_H, not available.
+*/
+#define DK4_HAVE_SYS_STAT_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SYS_TIME_H
+#if HAVE_SYS_TIME_H
+/** DK4 version of HAVE_SYS_TIME_H, available.
+*/
+#define DK4_HAVE_SYS_TIME_H 1
+#else
+/** DK4 version of HAVE_SYS_TIME_H, not available.
+*/
+#define DK4_HAVE_SYS_TIME_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SYS_TYPES_H
+#if HAVE_SYS_TYPES_H
+/** DK4 version of HAVE_SYS_TYPES_H, available.
+*/
+#define DK4_HAVE_SYS_TYPES_H 1
+#else
+/** DK4 version of HAVE_SYS_TYPES_H, not available.
+*/
+#define DK4_HAVE_SYS_TYPES_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SYS_UN_H
+#if HAVE_SYS_UN_H
+/** DK4 version of HAVE_SYS_UN_H, available.
+*/
+#define DK4_HAVE_SYS_UN_H 1
+#else
+/** DK4 version of HAVE_SYS_UN_H, not available.
+*/
+#define DK4_HAVE_SYS_UN_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_TGMATH_H
+#if HAVE_TGMATH_H
+/** DK4 version of HAVE_TGMATH_H, available.
+*/
+#define DK4_HAVE_TGMATH_H 1
+#else
+/** DK4 version of HAVE_TGMATH_H, not available.
+*/
+#define DK4_HAVE_TGMATH_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_THREADS_H
+#if HAVE_THREADS_H
+/** DK4 version of HAVE_THREADS_H, available.
+*/
+#define DK4_HAVE_THREADS_H 1
+#else
+/** DK4 version of HAVE_THREADS_H, not available.
+*/
+#define DK4_HAVE_THREADS_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_TIFF_H
+#if HAVE_TIFF_H
+/** DK4 version of HAVE_TIFF_H, available.
+*/
+#define DK4_HAVE_TIFF_H 1
+#else
+/** DK4 version of HAVE_TIFF_H, not available.
+*/
+#define DK4_HAVE_TIFF_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_TIME_H
+#if HAVE_TIME_H
+/** DK4 version of HAVE_TIME_H, available.
+*/
+#define DK4_HAVE_TIME_H 1
+#else
+/** DK4 version of HAVE_TIME_H, not available.
+*/
+#define DK4_HAVE_TIME_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_TYPE_STAT64
+#if HAVE_TYPE_STAT64
+/** DK4 version of HAVE_TYPE_STAT64, available.
+*/
+#define DK4_HAVE_TYPE_STAT64 1
+#else
+/** DK4 version of HAVE_TYPE_STAT64, not available.
+*/
+#define DK4_HAVE_TYPE_STAT64 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_UCHAR_H
+#if HAVE_UCHAR_H
+/** DK4 version of HAVE_UCHAR_H, available.
+*/
+#define DK4_HAVE_UCHAR_H 1
+#else
+/** DK4 version of HAVE_UCHAR_H, not available.
+*/
+#define DK4_HAVE_UCHAR_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_UID_T
+#if HAVE_UID_T
+/** DK4 version of HAVE_UID_T, available.
+*/
+#define DK4_HAVE_UID_T 1
+#else
+/** DK4 version of HAVE_UID_T, not available.
+*/
+#define DK4_HAVE_UID_T 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_UINT16_T
+#if HAVE_UINT16_T
+/** DK4 version of HAVE_UINT16_T, available.
+*/
+#define DK4_HAVE_UINT16_T 1
+#else
+/** DK4 version of HAVE_UINT16_T, not available.
+*/
+#define DK4_HAVE_UINT16_T 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_UINT32_T
+#if HAVE_UINT32_T
+/** DK4 version of HAVE_UINT32_T, available.
+*/
+#define DK4_HAVE_UINT32_T 1
+#else
+/** DK4 version of HAVE_UINT32_T, not available.
+*/
+#define DK4_HAVE_UINT32_T 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_UINT8_T
+#if HAVE_UINT8_T
+/** DK4 version of HAVE_UINT8_T, available.
+*/
+#define DK4_HAVE_UINT8_T 1
+#else
+/** DK4 version of HAVE_UINT8_T, not available.
+*/
+#define DK4_HAVE_UINT8_T 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_UNISTD_H
+#if HAVE_UNISTD_H
+/** DK4 version of HAVE_UNISTD_H, available.
+*/
+#define DK4_HAVE_UNISTD_H 1
+#else
+/** DK4 version of HAVE_UNISTD_H, not available.
+*/
+#define DK4_HAVE_UNISTD_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_UNLINK
+#if HAVE_UNLINK
+/** DK4 version of HAVE_UNLINK, available.
+*/
+#define DK4_HAVE_UNLINK 1
+#else
+/** DK4 version of HAVE_UNLINK, not available.
+*/
+#define DK4_HAVE_UNLINK 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_VOLATILE
+#if HAVE_VOLATILE
+/** DK4 version of HAVE_VOLATILE, available.
+*/
+#define DK4_HAVE_VOLATILE 1
+#else
+/** DK4 version of HAVE_VOLATILE, not available.
+*/
+#define DK4_HAVE_VOLATILE 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_WCHAR_H
+#if HAVE_WCHAR_H
+/** DK4 version of HAVE_WCHAR_H, available.
+*/
+#define DK4_HAVE_WCHAR_H 1
+#else
+/** DK4 version of HAVE_WCHAR_H, not available.
+*/
+#define DK4_HAVE_WCHAR_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_WCSCASECMP
+#if HAVE_WCSCASECMP
+/** DK4 version of HAVE_WCSCASECMP, available.
+*/
+#define DK4_HAVE_WCSCASECMP 1
+#else
+/** DK4 version of HAVE_WCSCASECMP, not available.
+*/
+#define DK4_HAVE_WCSCASECMP 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_WCSCAT
+#if HAVE_WCSCAT
+/** DK4 version of HAVE_WCSCAT, available.
+*/
+#define DK4_HAVE_WCSCAT 1
+#else
+/** DK4 version of HAVE_WCSCAT, not available.
+*/
+#define DK4_HAVE_WCSCAT 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_WCSCAT_S
+#if HAVE_WCSCAT_S
+/** DK4 version of HAVE_WCSCAT_S, available.
+*/
+#define DK4_HAVE_WCSCAT_S 1
+#else
+/** DK4 version of HAVE_WCSCAT_S, not available.
+*/
+#define DK4_HAVE_WCSCAT_S 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_WCSCHR
+#if HAVE_WCSCHR
+/** DK4 version of HAVE_WCSCHR, available.
+*/
+#define DK4_HAVE_WCSCHR 1
+#else
+/** DK4 version of HAVE_WCSCHR, not available.
+*/
+#define DK4_HAVE_WCSCHR 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_WCSCMP
+#if HAVE_WCSCMP
+/** DK4 version of HAVE_WCSCMP, available.
+*/
+#define DK4_HAVE_WCSCMP 1
+#else
+/** DK4 version of HAVE_WCSCMP, not available.
+*/
+#define DK4_HAVE_WCSCMP 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_WCSCPY
+#if HAVE_WCSCPY
+/** DK4 version of HAVE_WCSCPY, available.
+*/
+#define DK4_HAVE_WCSCPY 1
+#else
+/** DK4 version of HAVE_WCSCPY, not available.
+*/
+#define DK4_HAVE_WCSCPY 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_WCSCPY_S
+#if HAVE_WCSCPY_S
+/** DK4 version of HAVE_WCSCPY_S, available.
+*/
+#define DK4_HAVE_WCSCPY_S 1
+#else
+/** DK4 version of HAVE_WCSCPY_S, not available.
+*/
+#define DK4_HAVE_WCSCPY_S 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_WCSICMP
+#if HAVE_WCSICMP
+/** DK4 version of HAVE_WCSICMP, available.
+*/
+#define DK4_HAVE_WCSICMP 1
+#else
+/** DK4 version of HAVE_WCSICMP, not available.
+*/
+#define DK4_HAVE_WCSICMP 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_WCSLEN
+#if HAVE_WCSLEN
+/** DK4 version of HAVE_WCSLEN, available.
+*/
+#define DK4_HAVE_WCSLEN 1
+#else
+/** DK4 version of HAVE_WCSLEN, not available.
+*/
+#define DK4_HAVE_WCSLEN 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_WCSNCMP
+#if HAVE_WCSNCMP
+/** DK4 version of HAVE_WCSNCMP, available.
+*/
+#define DK4_HAVE_WCSNCMP 1
+#else
+/** DK4 version of HAVE_WCSNCMP, not available.
+*/
+#define DK4_HAVE_WCSNCMP 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_WCSRCHR
+#if HAVE_WCSRCHR
+/** DK4 version of HAVE_WCSRCHR, available.
+*/
+#define DK4_HAVE_WCSRCHR 1
+#else
+/** DK4 version of HAVE_WCSRCHR, not available.
+*/
+#define DK4_HAVE_WCSRCHR 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_WCSTOD
+#if HAVE_WCSTOD
+/** DK4 version of HAVE_WCSTOD, available.
+*/
+#define DK4_HAVE_WCSTOD 1
+#else
+/** DK4 version of HAVE_WCSTOD, not available.
+*/
+#define DK4_HAVE_WCSTOD 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_WCTYPE_H
+#if HAVE_WCTYPE_H
+/** DK4 version of HAVE_WCTYPE_H, available.
+*/
+#define DK4_HAVE_WCTYPE_H 1
+#else
+/** DK4 version of HAVE_WCTYPE_H, not available.
+*/
+#define DK4_HAVE_WCTYPE_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_WINDOWS_H
+#if HAVE_WINDOWS_H
+/** DK4 version of HAVE_WINDOWS_H, available.
+*/
+#define DK4_HAVE_WINDOWS_H 1
+#else
+/** DK4 version of HAVE_WINDOWS_H, not available.
+*/
+#define DK4_HAVE_WINDOWS_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_WINSOCK2_H
+#if HAVE_WINSOCK2_H
+/** DK4 version of HAVE_WINSOCK2_H, available.
+*/
+#define DK4_HAVE_WINSOCK2_H 1
+#else
+/** DK4 version of HAVE_WINSOCK2_H, not available.
+*/
+#define DK4_HAVE_WINSOCK2_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_WMKDIR
+#if HAVE_WMKDIR
+/** DK4 version of HAVE_WMKDIR, available.
+*/
+#define DK4_HAVE_WMKDIR 1
+#else
+/** DK4 version of HAVE_WMKDIR, not available.
+*/
+#define DK4_HAVE_WMKDIR 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_WRITE
+#if HAVE_WRITE
+/** DK4 version of HAVE_WRITE, available.
+*/
+#define DK4_HAVE_WRITE 1
+#else
+/** DK4 version of HAVE_WRITE, not available.
+*/
+#define DK4_HAVE_WRITE 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_WRMDIR
+#if HAVE_WRMDIR
+/** DK4 version of HAVE_WRMDIR, available.
+*/
+#define DK4_HAVE_WRMDIR 1
+#else
+/** DK4 version of HAVE_WRMDIR, not available.
+*/
+#define DK4_HAVE_WRMDIR 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_WS2TCPIP_H
+#if HAVE_WS2TCPIP_H
+/** DK4 version of HAVE_WS2TCPIP_H, available.
+*/
+#define DK4_HAVE_WS2TCPIP_H 1
+#else
+/** DK4 version of HAVE_WS2TCPIP_H, not available.
+*/
+#define DK4_HAVE_WS2TCPIP_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_WUNLINK
+#if HAVE_WUNLINK
+/** DK4 version of HAVE_WUNLINK, available.
+*/
+#define DK4_HAVE_WUNLINK 1
+#else
+/** DK4 version of HAVE_WUNLINK, not available.
+*/
+#define DK4_HAVE_WUNLINK 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_WXWIDGETS
+#if HAVE_WXWIDGETS
+/** DK4 version of HAVE_WXWIDGETS, available.
+*/
+#define DK4_HAVE_WXWIDGETS 1
+#else
+/** DK4 version of HAVE_WXWIDGETS, not available.
+*/
+#define DK4_HAVE_WXWIDGETS 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_ZLIB_H
+#if HAVE_ZLIB_H
+/** DK4 version of HAVE_ZLIB_H, available.
+*/
+#define DK4_HAVE_ZLIB_H 1
+#else
+/** DK4 version of HAVE_ZLIB_H, not available.
+*/
+#define DK4_HAVE_ZLIB_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__DEV_T
+#if HAVE__DEV_T
+/** DK4 version of HAVE__DEV_T, available.
+*/
+#define DK4_HAVE__DEV_T 1
+#else
+/** DK4 version of HAVE__DEV_T, not available.
+*/
+#define DK4_HAVE__DEV_T 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__FILENO
+#if HAVE__FILENO
+/** DK4 version of HAVE__FILENO, available.
+*/
+#define DK4_HAVE__FILENO 1
+#else
+/** DK4 version of HAVE__FILENO, not available.
+*/
+#define DK4_HAVE__FILENO 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__FINITE
+#if HAVE__FINITE
+/** DK4 version of HAVE__FINITE, available.
+*/
+#define DK4_HAVE__FINITE 1
+#else
+/** DK4 version of HAVE__FINITE, not available.
+*/
+#define DK4_HAVE__FINITE 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__FPOS_T
+#if HAVE__FPOS_T
+/** DK4 version of HAVE__FPOS_T, available.
+*/
+#define DK4_HAVE__FPOS_T 1
+#else
+/** DK4 version of HAVE__FPOS_T, not available.
+*/
+#define DK4_HAVE__FPOS_T 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__GETCWD
+#if HAVE__GETCWD
+/** DK4 version of HAVE__GETCWD, available.
+*/
+#define DK4_HAVE__GETCWD 1
+#else
+/** DK4 version of HAVE__GETCWD, not available.
+*/
+#define DK4_HAVE__GETCWD 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__INO64_T
+#if HAVE__INO64_T
+/** DK4 version of HAVE__INO64_T, available.
+*/
+#define DK4_HAVE__INO64_T 1
+#else
+/** DK4 version of HAVE__INO64_T, not available.
+*/
+#define DK4_HAVE__INO64_T 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__INO_T
+#if HAVE__INO_T
+/** DK4 version of HAVE__INO_T, available.
+*/
+#define DK4_HAVE__INO_T 1
+#else
+/** DK4 version of HAVE__INO_T, not available.
+*/
+#define DK4_HAVE__INO_T 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__ISATTY
+#if HAVE__ISATTY
+/** DK4 version of HAVE__ISATTY, available.
+*/
+#define DK4_HAVE__ISATTY 1
+#else
+/** DK4 version of HAVE__ISATTY, not available.
+*/
+#define DK4_HAVE__ISATTY 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__MKDIR
+#if HAVE__MKDIR
+/** DK4 version of HAVE__MKDIR, available.
+*/
+#define DK4_HAVE__MKDIR 1
+#else
+/** DK4 version of HAVE__MKDIR, not available.
+*/
+#define DK4_HAVE__MKDIR 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__OFF64_T
+#if HAVE__OFF64_T
+/** DK4 version of HAVE__OFF64_T, available.
+*/
+#define DK4_HAVE__OFF64_T 1
+#else
+/** DK4 version of HAVE__OFF64_T, not available.
+*/
+#define DK4_HAVE__OFF64_T 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__OFF_T
+#if HAVE__OFF_T
+/** DK4 version of HAVE__OFF_T, available.
+*/
+#define DK4_HAVE__OFF_T 1
+#else
+/** DK4 version of HAVE__OFF_T, not available.
+*/
+#define DK4_HAVE__OFF_T 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__READ
+#if HAVE__READ
+/** DK4 version of HAVE__READ, available.
+*/
+#define DK4_HAVE__READ 1
+#else
+/** DK4 version of HAVE__READ, not available.
+*/
+#define DK4_HAVE__READ 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__RMDIR
+#if HAVE__RMDIR
+/** DK4 version of HAVE__RMDIR, available.
+*/
+#define DK4_HAVE__RMDIR 1
+#else
+/** DK4 version of HAVE__RMDIR, not available.
+*/
+#define DK4_HAVE__RMDIR 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__SETMODE
+#if HAVE__SETMODE
+/** DK4 version of HAVE__SETMODE, available.
+*/
+#define DK4_HAVE__SETMODE 1
+#else
+/** DK4 version of HAVE__SETMODE, not available.
+*/
+#define DK4_HAVE__SETMODE 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__SNPRINTF
+#if HAVE__SNPRINTF
+/** DK4 version of HAVE__SNPRINTF, available.
+*/
+#define DK4_HAVE__SNPRINTF 1
+#else
+/** DK4 version of HAVE__SNPRINTF, not available.
+*/
+#define DK4_HAVE__SNPRINTF 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__SNPRINTF_S
+#if HAVE__SNPRINTF_S
+/** DK4 version of HAVE__SNPRINTF_S, available.
+*/
+#define DK4_HAVE__SNPRINTF_S 1
+#else
+/** DK4 version of HAVE__SNPRINTF_S, not available.
+*/
+#define DK4_HAVE__SNPRINTF_S 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__SNWPRINTF
+#if HAVE__SNWPRINTF
+/** DK4 version of HAVE__SNWPRINTF, available.
+*/
+#define DK4_HAVE__SNWPRINTF 1
+#else
+/** DK4 version of HAVE__SNWPRINTF, not available.
+*/
+#define DK4_HAVE__SNWPRINTF 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__SNWPRINTF_S
+#if HAVE__SNWPRINTF_S
+/** DK4 version of HAVE__SNWPRINTF_S, available.
+*/
+#define DK4_HAVE__SNWPRINTF_S 1
+#else
+/** DK4 version of HAVE__SNWPRINTF_S, not available.
+*/
+#define DK4_HAVE__SNWPRINTF_S 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__STRICMP
+#if HAVE__STRICMP
+/** DK4 version of HAVE__STRICMP, available.
+*/
+#define DK4_HAVE__STRICMP 1
+#else
+/** DK4 version of HAVE__STRICMP, not available.
+*/
+#define DK4_HAVE__STRICMP 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__STRTOD
+#if HAVE__STRTOD
+/** DK4 version of HAVE__STRTOD, available.
+*/
+#define DK4_HAVE__STRTOD 1
+#else
+/** DK4 version of HAVE__STRTOD, not available.
+*/
+#define DK4_HAVE__STRTOD 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__UNLINK
+#if HAVE__UNLINK
+/** DK4 version of HAVE__UNLINK, available.
+*/
+#define DK4_HAVE__UNLINK 1
+#else
+/** DK4 version of HAVE__UNLINK, not available.
+*/
+#define DK4_HAVE__UNLINK 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__WCSCASECMP
+#if HAVE__WCSCASECMP
+/** DK4 version of HAVE__WCSCASECMP, available.
+*/
+#define DK4_HAVE__WCSCASECMP 1
+#else
+/** DK4 version of HAVE__WCSCASECMP, not available.
+*/
+#define DK4_HAVE__WCSCASECMP 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__WCSCMP
+#if HAVE__WCSCMP
+/** DK4 version of HAVE__WCSCMP, available.
+*/
+#define DK4_HAVE__WCSCMP 1
+#else
+/** DK4 version of HAVE__WCSCMP, not available.
+*/
+#define DK4_HAVE__WCSCMP 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__WCSICMP
+#if HAVE__WCSICMP
+/** DK4 version of HAVE__WCSICMP, available.
+*/
+#define DK4_HAVE__WCSICMP 1
+#else
+/** DK4 version of HAVE__WCSICMP, not available.
+*/
+#define DK4_HAVE__WCSICMP 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__WCSNCMP
+#if HAVE__WCSNCMP
+/** DK4 version of HAVE__WCSNCMP, available.
+*/
+#define DK4_HAVE__WCSNCMP 1
+#else
+/** DK4 version of HAVE__WCSNCMP, not available.
+*/
+#define DK4_HAVE__WCSNCMP 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__WCSTOD
+#if HAVE__WCSTOD
+/** DK4 version of HAVE__WCSTOD, available.
+*/
+#define DK4_HAVE__WCSTOD 1
+#else
+/** DK4 version of HAVE__WCSTOD, not available.
+*/
+#define DK4_HAVE__WCSTOD 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__WFOPEN
+#if HAVE__WFOPEN
+/** DK4 version of HAVE__WFOPEN, available.
+*/
+#define DK4_HAVE__WFOPEN 1
+#else
+/** DK4 version of HAVE__WFOPEN, not available.
+*/
+#define DK4_HAVE__WFOPEN 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__WFOPEN64
+#if HAVE__WFOPEN64
+/** DK4 version of HAVE__WFOPEN64, available.
+*/
+#define DK4_HAVE__WFOPEN64 1
+#else
+/** DK4 version of HAVE__WFOPEN64, not available.
+*/
+#define DK4_HAVE__WFOPEN64 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__WFOPEN_S
+#if HAVE__WFOPEN_S
+/** DK4 version of HAVE__WFOPEN_S, available.
+*/
+#define DK4_HAVE__WFOPEN_S 1
+#else
+/** DK4 version of HAVE__WFOPEN_S, not available.
+*/
+#define DK4_HAVE__WFOPEN_S 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__WGETCWD
+#if HAVE__WGETCWD
+/** DK4 version of HAVE__WGETCWD, available.
+*/
+#define DK4_HAVE__WGETCWD 1
+#else
+/** DK4 version of HAVE__WGETCWD, not available.
+*/
+#define DK4_HAVE__WGETCWD 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__WMKDIR
+#if HAVE__WMKDIR
+/** DK4 version of HAVE__WMKDIR, available.
+*/
+#define DK4_HAVE__WMKDIR 1
+#else
+/** DK4 version of HAVE__WMKDIR, not available.
+*/
+#define DK4_HAVE__WMKDIR 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__WRITE
+#if HAVE__WRITE
+/** DK4 version of HAVE__WRITE, available.
+*/
+#define DK4_HAVE__WRITE 1
+#else
+/** DK4 version of HAVE__WRITE, not available.
+*/
+#define DK4_HAVE__WRITE 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__WRMDIR
+#if HAVE__WRMDIR
+/** DK4 version of HAVE__WRMDIR, available.
+*/
+#define DK4_HAVE__WRMDIR 1
+#else
+/** DK4 version of HAVE__WRMDIR, not available.
+*/
+#define DK4_HAVE__WRMDIR 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__WUNLINK
+#if HAVE__WUNLINK
+/** DK4 version of HAVE__WUNLINK, available.
+*/
+#define DK4_HAVE__WUNLINK 1
+#else
+/** DK4 version of HAVE__WUNLINK, not available.
+*/
+#define DK4_HAVE__WUNLINK 0
+#endif
+#endif
+
+#ifndef DK4_SIZEOF_DOUBLE
+/** DK4 version of SIZEOF_DOUBLE.
+*/
+#define DK4_SIZEOF_DOUBLE SIZEOF_DOUBLE
+#endif
+
+#ifndef DK4_SIZEOF_INO64_T
+/** DK4 version of SIZEOF_INO64_T.
+*/
+#define DK4_SIZEOF_INO64_T SIZEOF_INO64_T
+#endif
+
+#ifndef DK4_SIZEOF_INO_T
+/** DK4 version of SIZEOF_INO_T.
+*/
+#define DK4_SIZEOF_INO_T SIZEOF_INO_T
+#endif
+
+#ifndef DK4_SIZEOF_INT
+/** DK4 version of SIZEOF_INT.
+*/
+#define DK4_SIZEOF_INT SIZEOF_INT
+#endif
+
+#ifndef DK4_SIZEOF_INTMAX_T
+/** DK4 version of SIZEOF_INTMAX_T.
+*/
+#define DK4_SIZEOF_INTMAX_T SIZEOF_INTMAX_T
+#endif
+
+#ifndef DK4_SIZEOF_LONG
+/** DK4 version of SIZEOF_LONG.
+*/
+#define DK4_SIZEOF_LONG SIZEOF_LONG
+#endif
+
+#ifndef DK4_SIZEOF_LONG_DOUBLE
+/** DK4 version of SIZEOF_LONG_DOUBLE.
+*/
+#define DK4_SIZEOF_LONG_DOUBLE SIZEOF_LONG_DOUBLE
+#endif
+
+#ifndef DK4_SIZEOF_LONG_LONG
+/** DK4 version of SIZEOF_LONG_LONG.
+*/
+#define DK4_SIZEOF_LONG_LONG SIZEOF_LONG_LONG
+#endif
+
+#ifndef DK4_SIZEOF_OFF64_T
+/** DK4 version of SIZEOF_OFF64_T.
+*/
+#define DK4_SIZEOF_OFF64_T SIZEOF_OFF64_T
+#endif
+
+#ifndef DK4_SIZEOF_OFF_T
+/** DK4 version of SIZEOF_OFF_T.
+*/
+#define DK4_SIZEOF_OFF_T SIZEOF_OFF_T
+#endif
+
+#ifndef DK4_SIZEOF_SHORT
+/** DK4 version of SIZEOF_SHORT.
+*/
+#define DK4_SIZEOF_SHORT SIZEOF_SHORT
+#endif
+
+#ifndef DK4_SIZEOF_SIZE_T
+/** DK4 version of SIZEOF_SIZE_T.
+*/
+#define DK4_SIZEOF_SIZE_T SIZEOF_SIZE_T
+#endif
+
+#ifndef DK4_SIZEOF_WCHAR_T
+/** DK4 version of SIZEOF_WCHAR_T.
+*/
+#define DK4_SIZEOF_WCHAR_T SIZEOF_WCHAR_T
+#endif
+
+#ifndef DK4_TIME_WITH_SYS_TIME
+#if TIME_WITH_SYS_TIME
+/** DK4 version of TIME_WITH_SYS_TIME, available.
+*/
+#define DK4_TIME_WITH_SYS_TIME TIME_WITH_SYS_TIME
+#else
+/** DK4 version of TIME_WITH_SYS_TIME, not available.
+*/
+#define DK4_TIME_WITH_SYS_TIME 0
+#endif
+#endif
+
+#ifndef DK4_USE_FALLBACK_NUMERIC_LIMITS
+#if USE_FALLBACK_NUMERIC_LIMITS
+/** DK4 version of USE_FALLBACK_NUMERIC_LIMITS, available.
+*/
+#define DK4_USE_FALLBACK_NUMERIC_LIMITS USE_FALLBACK_NUMERIC_LIMITS
+#else
+/** DK4 version of USE_FALLBACK_NUMERIC_LIMITS, not available.
+*/
+#define DK4_USE_FALLBACK_NUMERIC_LIMITS 0
+#endif
+#endif
+
+#ifndef DK4_USE_PRINTF_SCANF
+#if USE_PRINTF_SCANF
+/** DK4 version of USE_PRINTF_SCANF, available.
+*/
+#define DK4_USE_PRINTF_SCANF USE_PRINTF_SCANF
+#else
+/** DK4 version of USE_PRINTF_SCANF, not available.
+*/
+#define DK4_USE_PRINTF_SCANF 0
+#endif
+#endif
+
+#ifndef DK4_USE_WINDOWS_LOCAL_ALLOC
+#if USE_WINDOWS_LOCAL_ALLOC
+/** DK4 version of USE_WINDOWS_LOCAL_ALLOC, available.
+*/
+#define DK4_USE_WINDOWS_LOCAL_ALLOC USE_WINDOWS_LOCAL_ALLOC
+#else
+/** DK4 version of USE_WINDOWS_LOCAL_ALLOC, not available.
+*/
+#define DK4_USE_WINDOWS_LOCAL_ALLOC 0
+#endif
+#endif
+
+#ifndef DK4_WORDS_BIGENDIAN
+#if WORDS_BIGENDIAN
+/** DK4 version of WORDS_BIGENDIAN, available.
+*/
+#define DK4_WORDS_BIGENDIAN WORDS_BIGENDIAN
+#else
+/** DK4 version of WORDS_BIGENDIAN, not available.
+*/
+#define DK4_WORDS_BIGENDIAN 0
+#endif
+#endif
+
+#endif
+/* if DK4CONF_H_INCLUDED */
diff --git a/support/dktools/dk4conf.h b/support/dktools/dk4conf.h
new file mode 100644
index 0000000000..9108015c69
--- /dev/null
+++ b/support/dktools/dk4conf.h
@@ -0,0 +1,1170 @@
+/** @file dk4conf.h Fixed configure results.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+/** Protection against multiple inclusion.
+*/
+#define DK4CONF_H_INCLUDED 1
+
+/** DK4 version of HAVE_ALLOC_H.
+*/
+#define DK4_HAVE_ALLOC_H 0
+
+/** DK4 version of HAVE_ARPA_INET_H.
+*/
+#define DK4_HAVE_ARPA_INET_H 1
+
+/** DK4 version of HAVE_ASSERT_H.
+*/
+#define DK4_HAVE_ASSERT_H 1
+
+/** DK4 version of HAVE_BACKSLASH_AS_SEP.
+*/
+#define DK4_HAVE_BACKSLASH_AS_SEP 0
+
+/** DK4 version of HAVE_BCMP.
+*/
+#define DK4_HAVE_BCMP 1
+
+/** DK4 version of HAVE_BCOPY.
+*/
+#define DK4_HAVE_BCOPY 1
+
+/** DK4 version of HAVE_BIOS_H.
+*/
+#define DK4_HAVE_BIOS_H 0
+
+/** DK4 version of HAVE_BLKCNT_T.
+*/
+#define DK4_HAVE_BLKCNT_T 1
+
+/** DK4 version of HAVE_BLKSIZE_T.
+*/
+#define DK4_HAVE_BLKSIZE_T 1
+
+/** DK4 version of HAVE_BZERO.
+*/
+#define DK4_HAVE_BZERO 1
+
+/** DK4 version of HAVE_BZLIB_H.
+*/
+#define DK4_HAVE_BZLIB_H 1
+
+/** DK4 version of HAVE_CALLOC.
+*/
+#define DK4_HAVE_CALLOC 1
+
+/** DK4 version of HAVE_CASE_INSENSITIVE_PATHNAMES.
+*/
+#define DK4_HAVE_CASE_INSENSITIVE_PATHNAMES 0
+
+/** DK4 version of HAVE_CASE_INSENSITIVE_USERNAMES.
+*/
+#define DK4_HAVE_CASE_INSENSITIVE_USERNAMES 0
+
+/** DK4 version of HAVE_CHMOD.
+*/
+#define DK4_HAVE_CHMOD 1
+
+/** DK4 version of HAVE_CHOWN.
+*/
+#define DK4_HAVE_CHOWN 1
+
+/** DK4 version of HAVE_COMPATDKTOOLS3.
+*/
+#define DK4_HAVE_COMPATDKTOOLS3 1
+
+/** DK4 version of HAVE_COMPLEX_H.
+*/
+#define DK4_HAVE_COMPLEX_H 1
+
+/** DK4 version of HAVE_CTYPE_H.
+*/
+#define DK4_HAVE_CTYPE_H 1
+
+/** DK4 version of HAVE_DB_CURSOR_C_GET.
+*/
+#define DK4_HAVE_DB_CURSOR_C_GET 1
+
+/** DK4 version of HAVE_DB_H.
+*/
+#define DK4_HAVE_DB_H 1
+
+/** DK4 version of HAVE_DEV_T.
+*/
+#define DK4_HAVE_DEV_T 1
+
+/** DK4 version of HAVE_DIRECT_H.
+*/
+#define DK4_HAVE_DIRECT_H 0
+
+/** DK4 version of HAVE_DIRENT_H.
+*/
+#define DK4_HAVE_DIRENT_H 1
+
+/** DK4 version of HAVE_DOS_H.
+*/
+#define DK4_HAVE_DOS_H 0
+
+/** DK4 version of HAVE_ENDGRENT.
+*/
+#define DK4_HAVE_ENDGRENT 1
+
+/** DK4 version of HAVE_ENDPWENT.
+*/
+#define DK4_HAVE_ENDPWENT 1
+
+/** DK4 version of HAVE_ERRNO_H.
+*/
+#define DK4_HAVE_ERRNO_H 1
+
+/** DK4 version of HAVE_FCNTL_H.
+*/
+#define DK4_HAVE_FCNTL_H 1
+
+/** DK4 version of HAVE_FENV_H.
+*/
+#define DK4_HAVE_FENV_H 1
+
+/** DK4 version of HAVE_FILEMODE_BINARY.
+*/
+#define DK4_HAVE_FILEMODE_BINARY 0
+
+/** DK4 version of HAVE_FILENO.
+*/
+#define DK4_HAVE_FILENO 1
+
+/** DK4 version of HAVE_FILE_ATIMECTIME.
+*/
+#define DK4_HAVE_FILE_ATIMECTIME 1
+
+/** DK4 version of HAVE_FILE_BLKSIZECNT.
+*/
+#define DK4_HAVE_FILE_BLKSIZECNT 1
+
+/** DK4 version of HAVE_FILE_DEVINO.
+*/
+#define DK4_HAVE_FILE_DEVINO 1
+
+/** DK4 version of HAVE_FILE_UIDGID.
+*/
+#define DK4_HAVE_FILE_UIDGID 1
+
+/** DK4 version of HAVE_FLOAT_H.
+*/
+#define DK4_HAVE_FLOAT_H 1
+
+/** DK4 version of HAVE_FOPEN64.
+*/
+#define DK4_HAVE_FOPEN64 1
+
+/** DK4 version of HAVE_FOPEN_S.
+*/
+#define DK4_HAVE_FOPEN_S 0
+
+/** DK4 version of HAVE_FPOS_T.
+*/
+#define DK4_HAVE_FPOS_T 1
+
+/** DK4 version of HAVE_FPUTWC.
+*/
+#define DK4_HAVE_FPUTWC 1
+
+/** DK4 version of HAVE_FPUTWS.
+*/
+#define DK4_HAVE_FPUTWS 1
+
+/** DK4 version of HAVE_FREE.
+*/
+#define DK4_HAVE_FREE 1
+
+/** DK4 version of HAVE_GETADDRINFO.
+*/
+#define DK4_HAVE_GETADDRINFO 1
+
+/** DK4 version of HAVE_GETCWD.
+*/
+#define DK4_HAVE_GETCWD 1
+
+/** DK4 version of HAVE_GETENV.
+*/
+#define DK4_HAVE_GETENV 1
+
+/** DK4 version of HAVE_GETENV_S.
+*/
+#define DK4_HAVE_GETENV_S 0
+
+/** DK4 version of HAVE_GETEUID.
+*/
+#define DK4_HAVE_GETEUID 1
+
+/** DK4 version of HAVE_GETEXECNAME.
+*/
+#define DK4_HAVE_GETEXECNAME 0
+
+/** DK4 version of HAVE_GETFINALPATHNAMEBYHANDLE.
+*/
+#define DK4_HAVE_GETFINALPATHNAMEBYHANDLE 0
+
+/** DK4 version of HAVE_GETGRENT.
+*/
+#define DK4_HAVE_GETGRENT 1
+
+/** DK4 version of HAVE_GETGRGID.
+*/
+#define DK4_HAVE_GETGRGID 1
+
+/** DK4 version of HAVE_GETGRNAM.
+*/
+#define DK4_HAVE_GETGRNAM 1
+
+/** DK4 version of HAVE_GETHOSTBYNAME.
+*/
+#define DK4_HAVE_GETHOSTBYNAME 1
+
+/** DK4 version of HAVE_GETNAMEINFO.
+*/
+#define DK4_HAVE_GETNAMEINFO 1
+
+/** DK4 version of HAVE_GETPID.
+*/
+#define DK4_HAVE_GETPID 1
+
+/** DK4 version of HAVE_GETPWENT.
+*/
+#define DK4_HAVE_GETPWENT 1
+
+/** DK4 version of HAVE_GETPWNAM.
+*/
+#define DK4_HAVE_GETPWNAM 1
+
+/** DK4 version of HAVE_GETPWUID.
+*/
+#define DK4_HAVE_GETPWUID 1
+
+/** DK4 version of HAVE_GETRLIMIT.
+*/
+#define DK4_HAVE_GETRLIMIT 1
+
+/** DK4 version of HAVE_GID_T.
+*/
+#define DK4_HAVE_GID_T 1
+
+/** DK4 version of HAVE_GRP_H.
+*/
+#define DK4_HAVE_GRP_H 1
+
+/** DK4 version of HAVE_HTONL.
+*/
+#define DK4_HAVE_HTONL 1
+
+/** DK4 version of HAVE_HTONS.
+*/
+#define DK4_HAVE_HTONS 1
+
+/** DK4 version of HAVE_IN6_ADDR.
+*/
+#define DK4_HAVE_IN6_ADDR 0
+
+/** DK4 version of HAVE_INET_ADDR.
+*/
+#define DK4_HAVE_INET_ADDR 1
+
+/** DK4 version of HAVE_INET_ATON.
+*/
+#define DK4_HAVE_INET_ATON 1
+
+/** DK4 version of HAVE_INET_NTOP.
+*/
+#define DK4_HAVE_INET_NTOP 1
+
+/** DK4 version of HAVE_INET_PTON.
+*/
+#define DK4_HAVE_INET_PTON 1
+
+/** DK4 version of HAVE_INITSTATE.
+*/
+#define DK4_HAVE_INITSTATE 1
+
+/** DK4 version of HAVE_INLINE.
+*/
+#define DK4_HAVE_INLINE 0
+
+/** DK4 version of HAVE_INO64_T.
+*/
+#define DK4_HAVE_INO64_T 1
+
+/** DK4 version of HAVE_INO_T.
+*/
+#define DK4_HAVE_INO_T 1
+
+/** DK4 version of HAVE_INT16_T.
+*/
+#define DK4_HAVE_INT16_T 1
+
+/** DK4 version of HAVE_INT32_T.
+*/
+#define DK4_HAVE_INT32_T 1
+
+/** DK4 version of HAVE_INT8_T.
+*/
+#define DK4_HAVE_INT8_T 1
+
+/** DK4 version of HAVE_INTMAX_T.
+*/
+#define DK4_HAVE_INTMAX_T 1
+
+/** DK4 version of HAVE_INTTYPES_H.
+*/
+#define DK4_HAVE_INTTYPES_H 1
+
+/** DK4 version of HAVE_IN_ADDR.
+*/
+#define DK4_HAVE_IN_ADDR 0
+
+/** DK4 version of HAVE_IO_H.
+*/
+#define DK4_HAVE_IO_H 0
+
+/** DK4 version of HAVE_ISATTY.
+*/
+#define DK4_HAVE_ISATTY 1
+
+/** DK4 version of HAVE_ISFINITE.
+*/
+#define DK4_HAVE_ISFINITE 1
+
+/** DK4 version of HAVE_ISNORMAL.
+*/
+#define DK4_HAVE_ISNORMAL 1
+
+/** DK4 version of HAVE_ISO646_H.
+*/
+#define DK4_HAVE_ISO646_H 1
+
+/** DK4 version of HAVE_JPEGLIB_H.
+*/
+#define DK4_HAVE_JPEGLIB_H 1
+
+/** DK4 version of HAVE_LARGEFILE64_SOURCE.
+*/
+#define DK4_HAVE_LARGEFILE64_SOURCE 1
+
+/** DK4 version of HAVE_LIBNETSNMP.
+*/
+#define DK4_HAVE_LIBNETSNMP 1
+
+/** DK4 version of HAVE_LIMITS_H.
+*/
+#define DK4_HAVE_LIMITS_H 1
+
+/** DK4 version of HAVE_LINE_END_CR_NL.
+*/
+#define DK4_HAVE_LINE_END_CR_NL 0
+
+/** DK4 version of HAVE_LOCALE_H.
+*/
+#define DK4_HAVE_LOCALE_H 1
+
+/** DK4 version of HAVE_LOCALTIME_R.
+*/
+#define DK4_HAVE_LOCALTIME_R 1
+
+/** DK4 version of HAVE_LONG_DOUBLE.
+*/
+#define DK4_HAVE_LONG_DOUBLE 1
+
+/** DK4 version of HAVE_LONG_LONG.
+*/
+#define DK4_HAVE_LONG_LONG 1
+
+/** DK4 version of HAVE_LRAND48.
+*/
+#define DK4_HAVE_LRAND48 1
+
+/** DK4 version of HAVE_LSTAT.
+*/
+#define DK4_HAVE_LSTAT 1
+
+/** DK4 version of HAVE_LSTAT64.
+*/
+#define DK4_HAVE_LSTAT64 1
+
+/** DK4 version of HAVE_MALLOC.
+*/
+#define DK4_HAVE_MALLOC 1
+
+/** DK4 version of HAVE_MALLOC_H.
+*/
+#define DK4_HAVE_MALLOC_H 1
+
+/** DK4 version of HAVE_MATH_H.
+*/
+#define DK4_HAVE_MATH_H 1
+
+/** DK4 version of HAVE_MEMCMP.
+*/
+#define DK4_HAVE_MEMCMP 1
+
+/** DK4 version of HAVE_MEMCPY.
+*/
+#define DK4_HAVE_MEMCPY 1
+
+/** DK4 version of HAVE_MEMSET.
+*/
+#define DK4_HAVE_MEMSET 1
+
+/** DK4 version of HAVE_MKDIR.
+*/
+#define DK4_HAVE_MKDIR 1
+
+/** DK4 version of HAVE_MODE_T.
+*/
+#define DK4_HAVE_MODE_T 1
+
+/** DK4 version of HAVE_NDBM_H.
+*/
+#define DK4_HAVE_NDBM_H 0
+
+/** DK4 version of HAVE_NETDB_H.
+*/
+#define DK4_HAVE_NETDB_H 1
+
+/** DK4 version of HAVE_NETINET_IN6_H.
+*/
+#define DK4_HAVE_NETINET_IN6_H 0
+
+/** DK4 version of HAVE_NETINET_IN_H.
+*/
+#define DK4_HAVE_NETINET_IN_H 1
+
+/** DK4 version of HAVE_NLINK_T.
+*/
+#define DK4_HAVE_NLINK_T 1
+
+/** DK4 version of HAVE_NRAND48.
+*/
+#define DK4_HAVE_NRAND48 1
+
+/** DK4 version of HAVE_NTIFS_H.
+*/
+#define DK4_HAVE_NTIFS_H 0
+
+/** DK4 version of HAVE_NTOHL.
+*/
+#define DK4_HAVE_NTOHL 1
+
+/** DK4 version of HAVE_NTOHS.
+*/
+#define DK4_HAVE_NTOHS 1
+
+/** DK4 version of HAVE_OFF64_T.
+*/
+#define DK4_HAVE_OFF64_T 1
+
+/** DK4 version of HAVE_OFF_T.
+*/
+#define DK4_HAVE_OFF_T 1
+
+/** DK4 version of HAVE_OPENSSL_MD5_H.
+*/
+#define DK4_HAVE_OPENSSL_MD5_H 1
+
+/** DK4 version of HAVE_OPENSSL_RAND_H.
+*/
+#define DK4_HAVE_OPENSSL_RAND_H 1
+
+/** DK4 version of HAVE_OPENSSL_RIPEMD_H.
+*/
+#define DK4_HAVE_OPENSSL_RIPEMD_H 1
+
+/** DK4 version of HAVE_OPENSSL_SHA_H.
+*/
+#define DK4_HAVE_OPENSSL_SHA_H 1
+
+/** DK4 version of HAVE_PNG_GET_PIXELS_PER_INCH.
+*/
+#define DK4_HAVE_PNG_GET_PIXELS_PER_INCH 0
+
+/** DK4 version of HAVE_PNG_H.
+*/
+#define DK4_HAVE_PNG_H 1
+
+/** DK4 version of HAVE_PROCESS_H.
+*/
+#define DK4_HAVE_PROCESS_H 0
+
+/** DK4 version of HAVE_PROC_PID_EXE.
+*/
+#define DK4_HAVE_PROC_PID_EXE 1
+
+/** DK4 version of HAVE_PWD_H.
+*/
+#define DK4_HAVE_PWD_H 1
+
+/** DK4 version of HAVE_RAND.
+*/
+#define DK4_HAVE_RAND 1
+
+/** DK4 version of HAVE_RANDOM.
+*/
+#define DK4_HAVE_RANDOM 1
+
+/** DK4 version of HAVE_RAND_EGD.
+*/
+#define DK4_HAVE_RAND_EGD 1
+
+/** DK4 version of HAVE_READ.
+*/
+#define DK4_HAVE_READ 1
+
+/** DK4 version of HAVE_READLINK.
+*/
+#define DK4_HAVE_READLINK 1
+
+/** DK4 version of HAVE_RMDIR.
+*/
+#define DK4_HAVE_RMDIR 1
+
+/** DK4 version of HAVE_SELECT.
+*/
+#define DK4_HAVE_SELECT 1
+
+/** DK4 version of HAVE_SETBUF.
+*/
+#define DK4_HAVE_SETBUF 1
+
+/** DK4 version of HAVE_SETBUFFER.
+*/
+#define DK4_HAVE_SETBUFFER 1
+
+/** DK4 version of HAVE_SETGID.
+*/
+#define DK4_HAVE_SETGID 1
+
+/** DK4 version of HAVE_SETGRENT.
+*/
+#define DK4_HAVE_SETGRENT 1
+
+/** DK4 version of HAVE_SETJMP_H.
+*/
+#define DK4_HAVE_SETJMP_H 1
+
+/** DK4 version of HAVE_SETLOCALE.
+*/
+#define DK4_HAVE_SETLOCALE 1
+
+/** DK4 version of HAVE_SETMODE.
+*/
+#define DK4_HAVE_SETMODE 0
+
+/** DK4 version of HAVE_SETPGRP.
+*/
+#define DK4_HAVE_SETPGRP 1
+
+/** DK4 version of HAVE_SETPWENT.
+*/
+#define DK4_HAVE_SETPWENT 1
+
+/** DK4 version of HAVE_SETSID.
+*/
+#define DK4_HAVE_SETSID 1
+
+/** DK4 version of HAVE_SETSOCKOPT.
+*/
+#define DK4_HAVE_SETSOCKOPT 1
+
+/** DK4 version of HAVE_SETSTATE.
+*/
+#define DK4_HAVE_SETSTATE 1
+
+/** DK4 version of HAVE_SETUID.
+*/
+#define DK4_HAVE_SETUID 1
+
+/** DK4 version of HAVE_SETVBUF.
+*/
+#define DK4_HAVE_SETVBUF 1
+
+/** DK4 version of HAVE_SHA224.
+*/
+#define DK4_HAVE_SHA224 1
+
+/** DK4 version of HAVE_SHA256.
+*/
+#define DK4_HAVE_SHA256 1
+
+/** DK4 version of HAVE_SHA384.
+*/
+#define DK4_HAVE_SHA384 1
+
+/** DK4 version of HAVE_SHA512.
+*/
+#define DK4_HAVE_SHA512 1
+
+/** DK4 version of HAVE_SHARE_H.
+*/
+#define DK4_HAVE_SHARE_H 0
+
+/** DK4 version of HAVE_SIGACTION.
+*/
+#define DK4_HAVE_SIGACTION 1
+
+/** DK4 version of HAVE_SIGEMPTYSET.
+*/
+#define DK4_HAVE_SIGEMPTYSET 1
+
+/** DK4 version of HAVE_SIGNAL.
+*/
+#define DK4_HAVE_SIGNAL 1
+
+/** DK4 version of HAVE_SIGNAL_H.
+*/
+#define DK4_HAVE_SIGNAL_H 1
+
+/** DK4 version of HAVE_SIGPROCMASK.
+*/
+#define DK4_HAVE_SIGPROCMASK 1
+
+/** DK4 version of HAVE_SIGSET.
+*/
+#define DK4_HAVE_SIGSET 1
+
+/** DK4 version of HAVE_SIG_ATOMIC_T.
+*/
+#define DK4_HAVE_SIG_ATOMIC_T 1
+
+/** DK4 version of HAVE_SNMP_DISABLE_FILELOG.
+*/
+#define DK4_HAVE_SNMP_DISABLE_FILELOG 1
+
+/** DK4 version of HAVE_SNMP_DISABLE_STDERRLOG.
+*/
+#define DK4_HAVE_SNMP_DISABLE_STDERRLOG 1
+
+/** DK4 version of HAVE_SNMP_DISABLE_SYSLOG.
+*/
+#define DK4_HAVE_SNMP_DISABLE_SYSLOG 1
+
+/** DK4 version of HAVE_SNMP_ENABLE_FILELOG.
+*/
+#define DK4_HAVE_SNMP_ENABLE_FILELOG 1
+
+/** DK4 version of HAVE_SNPRINTF.
+*/
+#define DK4_HAVE_SNPRINTF 1
+
+/** DK4 version of HAVE_SNWPRINTF.
+*/
+#define DK4_HAVE_SNWPRINTF 0
+
+/** DK4 version of HAVE_SOCKET.
+*/
+#define DK4_HAVE_SOCKET 1
+
+/** DK4 version of HAVE_SOCKLEN_T.
+*/
+#define DK4_HAVE_SOCKLEN_T 1
+
+/** DK4 version of HAVE_SRAND.
+*/
+#define DK4_HAVE_SRAND 1
+
+/** DK4 version of HAVE_SSIZE_T.
+*/
+#define DK4_HAVE_SSIZE_T 1
+
+/** DK4 version of HAVE_STAT64.
+*/
+#define DK4_HAVE_STAT64 1
+
+/** DK4 version of HAVE_STDALIGN_H.
+*/
+#define DK4_HAVE_STDALIGN_H 1
+
+/** DK4 version of HAVE_STDARG_H.
+*/
+#define DK4_HAVE_STDARG_H 1
+
+/** DK4 version of HAVE_STDATOMIC_H.
+*/
+#define DK4_HAVE_STDATOMIC_H 1
+
+/** DK4 version of HAVE_STDBOOL_H.
+*/
+#define DK4_HAVE_STDBOOL_H 1
+
+/** DK4 version of HAVE_STDDEF_H.
+*/
+#define DK4_HAVE_STDDEF_H 1
+
+/** DK4 version of HAVE_STDINT_H.
+*/
+#define DK4_HAVE_STDINT_H 1
+
+/** DK4 version of HAVE_STDLIB_H.
+*/
+#define DK4_HAVE_STDLIB_H 1
+
+/** DK4 version of HAVE_STDNORETURN_H.
+*/
+#define DK4_HAVE_STDNORETURN_H 1
+
+/** DK4 version of HAVE_STRCASECMP.
+*/
+#define DK4_HAVE_STRCASECMP 1
+
+/** DK4 version of HAVE_STRCAT_S.
+*/
+#define DK4_HAVE_STRCAT_S 0
+
+/** DK4 version of HAVE_STRCPY_S.
+*/
+#define DK4_HAVE_STRCPY_S 0
+
+/** DK4 version of HAVE_STRERROR.
+*/
+#define DK4_HAVE_STRERROR 1
+
+/** DK4 version of HAVE_STRERROR_R.
+*/
+#define DK4_HAVE_STRERROR_R 1
+
+/** DK4 version of HAVE_STRICMP.
+*/
+#define DK4_HAVE_STRICMP 0
+
+/** DK4 version of HAVE_STRINGS_H.
+*/
+#define DK4_HAVE_STRINGS_H 1
+
+/** DK4 version of HAVE_STRING_H.
+*/
+#define DK4_HAVE_STRING_H 1
+
+/** DK4 version of HAVE_STRTOD.
+*/
+#define DK4_HAVE_STRTOD 1
+
+/** DK4 version of HAVE_STRUCT_ADDRINFO.
+*/
+#define DK4_HAVE_STRUCT_ADDRINFO 1
+
+/** DK4 version of HAVE_STRUCT_SOCKADDR_IN.
+*/
+#define DK4_HAVE_STRUCT_SOCKADDR_IN 1
+
+/** DK4 version of HAVE_STRUCT_SOCKADDR_IN6.
+*/
+#define DK4_HAVE_STRUCT_SOCKADDR_IN6 1
+
+/** DK4 version of HAVE_STRUCT_SOCKADDR_STORAGE.
+*/
+#define DK4_HAVE_STRUCT_SOCKADDR_STORAGE 1
+
+/** DK4 version of HAVE_STRUCT_SOCKADDR_UN.
+*/
+#define DK4_HAVE_STRUCT_SOCKADDR_UN 1
+
+/** DK4 version of HAVE_SWPRINTF.
+*/
+#define DK4_HAVE_SWPRINTF 1
+
+/** DK4 version of HAVE_SYSLOG.
+*/
+#define DK4_HAVE_SYSLOG 1
+
+/** DK4 version of HAVE_SYSLOG_H.
+*/
+#define DK4_HAVE_SYSLOG_H 1
+
+/** DK4 version of HAVE_SYS_PARAM_H.
+*/
+#define DK4_HAVE_SYS_PARAM_H 1
+
+/** DK4 version of HAVE_SYS_RESOURCE_H.
+*/
+#define DK4_HAVE_SYS_RESOURCE_H 1
+
+/** DK4 version of HAVE_SYS_SELECT_H.
+*/
+#define DK4_HAVE_SYS_SELECT_H 1
+
+/** DK4 version of HAVE_SYS_SOCKET_H.
+*/
+#define DK4_HAVE_SYS_SOCKET_H 1
+
+/** DK4 version of HAVE_SYS_STAT_H.
+*/
+#define DK4_HAVE_SYS_STAT_H 1
+
+/** DK4 version of HAVE_SYS_TIME_H.
+*/
+#define DK4_HAVE_SYS_TIME_H 1
+
+/** DK4 version of HAVE_SYS_TYPES_H.
+*/
+#define DK4_HAVE_SYS_TYPES_H 1
+
+/** DK4 version of HAVE_SYS_UN_H.
+*/
+#define DK4_HAVE_SYS_UN_H 1
+
+/** DK4 version of HAVE_TGMATH_H.
+*/
+#define DK4_HAVE_TGMATH_H 1
+
+/** DK4 version of HAVE_THREADS_H.
+*/
+#define DK4_HAVE_THREADS_H 0
+
+/** DK4 version of HAVE_TIFF_H.
+*/
+#define DK4_HAVE_TIFF_H 1
+
+/** DK4 version of HAVE_TIME_H.
+*/
+#define DK4_HAVE_TIME_H 1
+
+/** DK4 version of HAVE_TYPE_STAT64.
+*/
+#define DK4_HAVE_TYPE_STAT64 1
+
+/** DK4 version of HAVE_UCHAR_H.
+*/
+#define DK4_HAVE_UCHAR_H 1
+
+/** DK4 version of HAVE_UID_T.
+*/
+#define DK4_HAVE_UID_T 1
+
+/** DK4 version of HAVE_UINT16_T.
+*/
+#define DK4_HAVE_UINT16_T 1
+
+/** DK4 version of HAVE_UINT32_T.
+*/
+#define DK4_HAVE_UINT32_T 1
+
+/** DK4 version of HAVE_UINT8_T.
+*/
+#define DK4_HAVE_UINT8_T 1
+
+/** DK4 version of HAVE_UNISTD_H.
+*/
+#define DK4_HAVE_UNISTD_H 1
+
+/** DK4 version of HAVE_UNLINK.
+*/
+#define DK4_HAVE_UNLINK 1
+
+/** DK4 version of HAVE_VOLATILE.
+*/
+#define DK4_HAVE_VOLATILE 1
+
+/** DK4 version of HAVE_WCHAR_H.
+*/
+#define DK4_HAVE_WCHAR_H 1
+
+/** DK4 version of HAVE_WCSCASECMP.
+*/
+#define DK4_HAVE_WCSCASECMP 1
+
+/** DK4 version of HAVE_WCSCAT.
+*/
+#define DK4_HAVE_WCSCAT 1
+
+/** DK4 version of HAVE_WCSCAT_S.
+*/
+#define DK4_HAVE_WCSCAT_S 0
+
+/** DK4 version of HAVE_WCSCHR.
+*/
+#define DK4_HAVE_WCSCHR 1
+
+/** DK4 version of HAVE_WCSCMP.
+*/
+#define DK4_HAVE_WCSCMP 1
+
+/** DK4 version of HAVE_WCSCPY.
+*/
+#define DK4_HAVE_WCSCPY 1
+
+/** DK4 version of HAVE_WCSCPY_S.
+*/
+#define DK4_HAVE_WCSCPY_S 0
+
+/** DK4 version of HAVE_WCSICMP.
+*/
+#define DK4_HAVE_WCSICMP 0
+
+/** DK4 version of HAVE_WCSLEN.
+*/
+#define DK4_HAVE_WCSLEN 1
+
+/** DK4 version of HAVE_WCSNCMP.
+*/
+#define DK4_HAVE_WCSNCMP 1
+
+/** DK4 version of HAVE_WCSRCHR.
+*/
+#define DK4_HAVE_WCSRCHR 1
+
+/** DK4 version of HAVE_WCSTOD.
+*/
+#define DK4_HAVE_WCSTOD 1
+
+/** DK4 version of HAVE_WCTYPE_H.
+*/
+#define DK4_HAVE_WCTYPE_H 1
+
+/** DK4 version of HAVE_WINDOWS_H.
+*/
+#define DK4_HAVE_WINDOWS_H 0
+
+/** DK4 version of HAVE_WINSOCK2_H.
+*/
+#define DK4_HAVE_WINSOCK2_H 0
+
+/** DK4 version of HAVE_WMKDIR.
+*/
+#define DK4_HAVE_WMKDIR 0
+
+/** DK4 version of HAVE_WRITE.
+*/
+#define DK4_HAVE_WRITE 1
+
+/** DK4 version of HAVE_WRMDIR.
+*/
+#define DK4_HAVE_WRMDIR 0
+
+/** DK4 version of HAVE_WS2TCPIP_H.
+*/
+#define DK4_HAVE_WS2TCPIP_H 0
+
+/** DK4 version of HAVE_WUNLINK.
+*/
+#define DK4_HAVE_WUNLINK 0
+
+/** DK4 version of HAVE_WXWIDGETS.
+*/
+#define DK4_HAVE_WXWIDGETS 1
+
+/** DK4 version of HAVE_ZLIB_H.
+*/
+#define DK4_HAVE_ZLIB_H 1
+
+/** DK4 version of HAVE__DEV_T.
+*/
+#define DK4_HAVE__DEV_T 0
+
+/** DK4 version of HAVE__FILENO.
+*/
+#define DK4_HAVE__FILENO 0
+
+/** DK4 version of HAVE__FINITE.
+*/
+#define DK4_HAVE__FINITE 0
+
+/** DK4 version of HAVE__FPOS_T.
+*/
+#define DK4_HAVE__FPOS_T 0
+
+/** DK4 version of HAVE__GETCWD.
+*/
+#define DK4_HAVE__GETCWD 0
+
+/** DK4 version of HAVE__INO64_T.
+*/
+#define DK4_HAVE__INO64_T 0
+
+/** DK4 version of HAVE__INO_T.
+*/
+#define DK4_HAVE__INO_T 0
+
+/** DK4 version of HAVE__ISATTY.
+*/
+#define DK4_HAVE__ISATTY 0
+
+/** DK4 version of HAVE__MKDIR.
+*/
+#define DK4_HAVE__MKDIR 0
+
+/** DK4 version of HAVE__OFF64_T.
+*/
+#define DK4_HAVE__OFF64_T 0
+
+/** DK4 version of HAVE__OFF_T.
+*/
+#define DK4_HAVE__OFF_T 0
+
+/** DK4 version of HAVE__READ.
+*/
+#define DK4_HAVE__READ 0
+
+/** DK4 version of HAVE__RMDIR.
+*/
+#define DK4_HAVE__RMDIR 0
+
+/** DK4 version of HAVE__SETMODE.
+*/
+#define DK4_HAVE__SETMODE 0
+
+/** DK4 version of HAVE__SNPRINTF.
+*/
+#define DK4_HAVE__SNPRINTF 0
+
+/** DK4 version of HAVE__SNPRINTF_S.
+*/
+#define DK4_HAVE__SNPRINTF_S 0
+
+/** DK4 version of HAVE__SNWPRINTF.
+*/
+#define DK4_HAVE__SNWPRINTF 0
+
+/** DK4 version of HAVE__SNWPRINTF_S.
+*/
+#define DK4_HAVE__SNWPRINTF_S 0
+
+/** DK4 version of HAVE__STRICMP.
+*/
+#define DK4_HAVE__STRICMP 0
+
+/** DK4 version of HAVE__STRTOD.
+*/
+#define DK4_HAVE__STRTOD 0
+
+/** DK4 version of HAVE__UNLINK.
+*/
+#define DK4_HAVE__UNLINK 0
+
+/** DK4 version of HAVE__WCSCASECMP.
+*/
+#define DK4_HAVE__WCSCASECMP 0
+
+/** DK4 version of HAVE__WCSCMP.
+*/
+#define DK4_HAVE__WCSCMP 0
+
+/** DK4 version of HAVE__WCSICMP.
+*/
+#define DK4_HAVE__WCSICMP 0
+
+/** DK4 version of HAVE__WCSNCMP.
+*/
+#define DK4_HAVE__WCSNCMP 0
+
+/** DK4 version of HAVE__WCSTOD.
+*/
+#define DK4_HAVE__WCSTOD 0
+
+/** DK4 version of HAVE__WFOPEN.
+*/
+#define DK4_HAVE__WFOPEN 0
+
+/** DK4 version of HAVE__WFOPEN64.
+*/
+#define DK4_HAVE__WFOPEN64 0
+
+/** DK4 version of HAVE__WFOPEN_S.
+*/
+#define DK4_HAVE__WFOPEN_S 0
+
+/** DK4 version of HAVE__WGETCWD.
+*/
+#define DK4_HAVE__WGETCWD 0
+
+/** DK4 version of HAVE__WMKDIR.
+*/
+#define DK4_HAVE__WMKDIR 0
+
+/** DK4 version of HAVE__WRITE.
+*/
+#define DK4_HAVE__WRITE 0
+
+/** DK4 version of HAVE__WRMDIR.
+*/
+#define DK4_HAVE__WRMDIR 0
+
+/** DK4 version of HAVE__WUNLINK.
+*/
+#define DK4_HAVE__WUNLINK 0
+
+/** DK4 version of SIZEOF_DOUBLE.
+*/
+#define DK4_SIZEOF_DOUBLE 8
+
+/** DK4 version of SIZEOF_INO64_T.
+*/
+#define DK4_SIZEOF_INO64_T 0
+
+/** DK4 version of SIZEOF_INO_T.
+*/
+#define DK4_SIZEOF_INO_T 8
+
+/** DK4 version of SIZEOF_INT.
+*/
+#define DK4_SIZEOF_INT 4
+
+/** DK4 version of SIZEOF_INTMAX_T.
+*/
+#define DK4_SIZEOF_INTMAX_T 8
+
+/** DK4 version of SIZEOF_LONG.
+*/
+#define DK4_SIZEOF_LONG 8
+
+/** DK4 version of SIZEOF_LONG_DOUBLE.
+*/
+#define DK4_SIZEOF_LONG_DOUBLE 16
+
+/** DK4 version of SIZEOF_LONG_LONG.
+*/
+#define DK4_SIZEOF_LONG_LONG 8
+
+/** DK4 version of SIZEOF_OFF64_T.
+*/
+#define DK4_SIZEOF_OFF64_T 0
+
+/** DK4 version of SIZEOF_OFF_T.
+*/
+#define DK4_SIZEOF_OFF_T 8
+
+/** DK4 version of SIZEOF_SHORT.
+*/
+#define DK4_SIZEOF_SHORT 2
+
+/** DK4 version of SIZEOF_SIZE_T.
+*/
+#define DK4_SIZEOF_SIZE_T 8
+
+/** DK4 version of SIZEOF_WCHAR_T.
+*/
+#define DK4_SIZEOF_WCHAR_T 4
+
+/** DK4 version of TIME_WITH_SYS_TIME.
+*/
+#define DK4_TIME_WITH_SYS_TIME 1
+
+/** DK4 version of USE_FALLBACK_NUMERIC_LIMITS.
+*/
+#define DK4_USE_FALLBACK_NUMERIC_LIMITS 0
+
+/** DK4 version of USE_PRINTF_SCANF.
+*/
+#define DK4_USE_PRINTF_SCANF 1
+
+/** DK4 version of USE_WINDOWS_LOCAL_ALLOC.
+*/
+#define DK4_USE_WINDOWS_LOCAL_ALLOC 0
+
+/** DK4 version of WORDS_BIGENDIAN.
+*/
+#define DK4_WORDS_BIGENDIAN 0
+
+/** Size of wchar_t.
+*/
+#define DK4_SIZEOF_WXCHAR 4
+
+#endif
+/* ifndef DK4CONF_H_INCLUDED */
diff --git a/support/dktools/dk4config.cpp b/support/dktools/dk4config.cpp
new file mode 100644
index 0000000000..fb0ac4c502
--- /dev/null
+++ b/support/dktools/dk4config.cpp
@@ -0,0 +1,2372 @@
+/** @file dk4config.cpp Fix configure results.
+ Redirect output from this program to the dk4conf.h file.
+*/
+
+#include <stdio.h>
+#include "config.h"
+
+/* wxWidgets_header_start */
+#if HAVE_WXWIDGETS
+#include <wx/wxprec.h>
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED 1
+#endif
+#endif
+#endif
+#endif
+#endif
+/* wxWidgets_header_end*/
+
+#include <dk3trace.h>
+#ifndef TRACE_DEBUG
+#define TRACE_DEBUG 1
+#endif
+int main(void)
+{
+
+ fputs("/**\t@file dk4conf.h Fixed configure results.\n*/\n\n", stdout);
+ fputs("#ifndef DK4CONF_H_INCLUDED\n", stdout);
+ fputs("/**\tProtection against multiple inclusion.\n*/\n", stdout);
+ fputs("#define DK4CONF_H_INCLUDED 1\n\n", stdout);
+#if HAVE_ALLOC_H
+ fputs("/** DK4 version of HAVE_ALLOC_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ALLOC_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_ALLOC_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ALLOC_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_ARPA_INET_H
+ fputs("/** DK4 version of HAVE_ARPA_INET_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ARPA_INET_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_ARPA_INET_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ARPA_INET_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_ASSERT_H
+ fputs("/** DK4 version of HAVE_ASSERT_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ASSERT_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_ASSERT_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ASSERT_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_BACKSLASH_AS_SEP
+ fputs("/** DK4 version of HAVE_BACKSLASH_AS_SEP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_BACKSLASH_AS_SEP 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_BACKSLASH_AS_SEP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_BACKSLASH_AS_SEP 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_BCMP
+ fputs("/** DK4 version of HAVE_BCMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_BCMP 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_BCMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_BCMP 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_BCOPY
+ fputs("/** DK4 version of HAVE_BCOPY.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_BCOPY 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_BCOPY.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_BCOPY 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_BIOS_H
+ fputs("/** DK4 version of HAVE_BIOS_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_BIOS_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_BIOS_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_BIOS_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_BLKCNT_T
+ fputs("/** DK4 version of HAVE_BLKCNT_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_BLKCNT_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_BLKCNT_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_BLKCNT_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_BLKSIZE_T
+ fputs("/** DK4 version of HAVE_BLKSIZE_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_BLKSIZE_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_BLKSIZE_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_BLKSIZE_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_BZERO
+ fputs("/** DK4 version of HAVE_BZERO.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_BZERO 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_BZERO.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_BZERO 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_BZLIB_H
+ fputs("/** DK4 version of HAVE_BZLIB_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_BZLIB_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_BZLIB_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_BZLIB_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_CALLOC
+ fputs("/** DK4 version of HAVE_CALLOC.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_CALLOC 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_CALLOC.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_CALLOC 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_CASE_INSENSITIVE_PATHNAMES
+ fputs("/** DK4 version of HAVE_CASE_INSENSITIVE_PATHNAMES.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_CASE_INSENSITIVE_PATHNAMES 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_CASE_INSENSITIVE_PATHNAMES.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_CASE_INSENSITIVE_PATHNAMES 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_CASE_INSENSITIVE_USERNAMES
+ fputs("/** DK4 version of HAVE_CASE_INSENSITIVE_USERNAMES.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_CASE_INSENSITIVE_USERNAMES 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_CASE_INSENSITIVE_USERNAMES.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_CASE_INSENSITIVE_USERNAMES 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_CHMOD
+ fputs("/** DK4 version of HAVE_CHMOD.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_CHMOD 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_CHMOD.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_CHMOD 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_CHOWN
+ fputs("/** DK4 version of HAVE_CHOWN.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_CHOWN 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_CHOWN.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_CHOWN 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_COMPATDKTOOLS3
+ fputs("/** DK4 version of HAVE_COMPATDKTOOLS3.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_COMPATDKTOOLS3 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_COMPATDKTOOLS3.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_COMPATDKTOOLS3 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_COMPLEX_H
+ fputs("/** DK4 version of HAVE_COMPLEX_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_COMPLEX_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_COMPLEX_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_COMPLEX_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_CTYPE_H
+ fputs("/** DK4 version of HAVE_CTYPE_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_CTYPE_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_CTYPE_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_CTYPE_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_DB_CURSOR_C_GET
+ fputs("/** DK4 version of HAVE_DB_CURSOR_C_GET.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_DB_CURSOR_C_GET 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_DB_CURSOR_C_GET.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_DB_CURSOR_C_GET 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_DB_H
+ fputs("/** DK4 version of HAVE_DB_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_DB_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_DB_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_DB_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_DEV_T
+ fputs("/** DK4 version of HAVE_DEV_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_DEV_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_DEV_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_DEV_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_DIRECT_H
+ fputs("/** DK4 version of HAVE_DIRECT_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_DIRECT_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_DIRECT_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_DIRECT_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_DIRENT_H
+ fputs("/** DK4 version of HAVE_DIRENT_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_DIRENT_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_DIRENT_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_DIRENT_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_DOS_H
+ fputs("/** DK4 version of HAVE_DOS_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_DOS_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_DOS_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_DOS_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_ENDGRENT
+ fputs("/** DK4 version of HAVE_ENDGRENT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ENDGRENT 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_ENDGRENT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ENDGRENT 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_ENDPWENT
+ fputs("/** DK4 version of HAVE_ENDPWENT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ENDPWENT 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_ENDPWENT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ENDPWENT 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_ERRNO_H
+ fputs("/** DK4 version of HAVE_ERRNO_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ERRNO_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_ERRNO_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ERRNO_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_FCNTL_H
+ fputs("/** DK4 version of HAVE_FCNTL_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FCNTL_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_FCNTL_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FCNTL_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_FENV_H
+ fputs("/** DK4 version of HAVE_FENV_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FENV_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_FENV_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FENV_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_FILEMODE_BINARY
+ fputs("/** DK4 version of HAVE_FILEMODE_BINARY.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FILEMODE_BINARY 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_FILEMODE_BINARY.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FILEMODE_BINARY 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_FILENO
+ fputs("/** DK4 version of HAVE_FILENO.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FILENO 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_FILENO.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FILENO 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_FILE_ATIMECTIME
+ fputs("/** DK4 version of HAVE_FILE_ATIMECTIME.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FILE_ATIMECTIME 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_FILE_ATIMECTIME.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FILE_ATIMECTIME 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_FILE_BLKSIZECNT
+ fputs("/** DK4 version of HAVE_FILE_BLKSIZECNT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FILE_BLKSIZECNT 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_FILE_BLKSIZECNT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FILE_BLKSIZECNT 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_FILE_DEVINO
+ fputs("/** DK4 version of HAVE_FILE_DEVINO.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FILE_DEVINO 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_FILE_DEVINO.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FILE_DEVINO 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_FILE_UIDGID
+ fputs("/** DK4 version of HAVE_FILE_UIDGID.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FILE_UIDGID 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_FILE_UIDGID.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FILE_UIDGID 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_FLOAT_H
+ fputs("/** DK4 version of HAVE_FLOAT_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FLOAT_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_FLOAT_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FLOAT_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_FOPEN64
+ fputs("/** DK4 version of HAVE_FOPEN64.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FOPEN64 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_FOPEN64.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FOPEN64 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_FOPEN_S
+ fputs("/** DK4 version of HAVE_FOPEN_S.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FOPEN_S 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_FOPEN_S.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FOPEN_S 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_FPOS_T
+ fputs("/** DK4 version of HAVE_FPOS_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FPOS_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_FPOS_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FPOS_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_FPUTWC
+ fputs("/** DK4 version of HAVE_FPUTWC.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FPUTWC 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_FPUTWC.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FPUTWC 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_FPUTWS
+ fputs("/** DK4 version of HAVE_FPUTWS.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FPUTWS 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_FPUTWS.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FPUTWS 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_FREE
+ fputs("/** DK4 version of HAVE_FREE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FREE 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_FREE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FREE 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_GETADDRINFO
+ fputs("/** DK4 version of HAVE_GETADDRINFO.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETADDRINFO 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_GETADDRINFO.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETADDRINFO 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_GETCWD
+ fputs("/** DK4 version of HAVE_GETCWD.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETCWD 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_GETCWD.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETCWD 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_GETENV
+ fputs("/** DK4 version of HAVE_GETENV.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETENV 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_GETENV.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETENV 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_GETENV_S
+ fputs("/** DK4 version of HAVE_GETENV_S.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETENV_S 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_GETENV_S.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETENV_S 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_GETEUID
+ fputs("/** DK4 version of HAVE_GETEUID.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETEUID 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_GETEUID.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETEUID 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_GETEXECNAME
+ fputs("/** DK4 version of HAVE_GETEXECNAME.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETEXECNAME 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_GETEXECNAME.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETEXECNAME 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_GETFINALPATHNAMEBYHANDLE
+ fputs("/** DK4 version of HAVE_GETFINALPATHNAMEBYHANDLE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETFINALPATHNAMEBYHANDLE 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_GETFINALPATHNAMEBYHANDLE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETFINALPATHNAMEBYHANDLE 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_GETGRENT
+ fputs("/** DK4 version of HAVE_GETGRENT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETGRENT 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_GETGRENT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETGRENT 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_GETGRGID
+ fputs("/** DK4 version of HAVE_GETGRGID.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETGRGID 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_GETGRGID.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETGRGID 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_GETGRNAM
+ fputs("/** DK4 version of HAVE_GETGRNAM.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETGRNAM 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_GETGRNAM.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETGRNAM 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_GETHOSTBYNAME
+ fputs("/** DK4 version of HAVE_GETHOSTBYNAME.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETHOSTBYNAME 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_GETHOSTBYNAME.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETHOSTBYNAME 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_GETNAMEINFO
+ fputs("/** DK4 version of HAVE_GETNAMEINFO.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETNAMEINFO 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_GETNAMEINFO.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETNAMEINFO 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_GETPID
+ fputs("/** DK4 version of HAVE_GETPID.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETPID 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_GETPID.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETPID 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_GETPWENT
+ fputs("/** DK4 version of HAVE_GETPWENT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETPWENT 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_GETPWENT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETPWENT 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_GETPWNAM
+ fputs("/** DK4 version of HAVE_GETPWNAM.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETPWNAM 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_GETPWNAM.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETPWNAM 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_GETPWUID
+ fputs("/** DK4 version of HAVE_GETPWUID.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETPWUID 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_GETPWUID.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETPWUID 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_GETRLIMIT
+ fputs("/** DK4 version of HAVE_GETRLIMIT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETRLIMIT 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_GETRLIMIT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETRLIMIT 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_GID_T
+ fputs("/** DK4 version of HAVE_GID_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GID_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_GID_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GID_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_GRP_H
+ fputs("/** DK4 version of HAVE_GRP_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GRP_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_GRP_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GRP_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_HTONL
+ fputs("/** DK4 version of HAVE_HTONL.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_HTONL 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_HTONL.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_HTONL 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_HTONS
+ fputs("/** DK4 version of HAVE_HTONS.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_HTONS 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_HTONS.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_HTONS 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_IN6_ADDR
+ fputs("/** DK4 version of HAVE_IN6_ADDR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_IN6_ADDR 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_IN6_ADDR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_IN6_ADDR 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_INET_ADDR
+ fputs("/** DK4 version of HAVE_INET_ADDR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INET_ADDR 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_INET_ADDR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INET_ADDR 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_INET_ATON
+ fputs("/** DK4 version of HAVE_INET_ATON.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INET_ATON 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_INET_ATON.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INET_ATON 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_INET_NTOP
+ fputs("/** DK4 version of HAVE_INET_NTOP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INET_NTOP 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_INET_NTOP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INET_NTOP 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_INET_PTON
+ fputs("/** DK4 version of HAVE_INET_PTON.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INET_PTON 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_INET_PTON.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INET_PTON 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_INITSTATE
+ fputs("/** DK4 version of HAVE_INITSTATE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INITSTATE 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_INITSTATE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INITSTATE 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_INLINE
+ fputs("/** DK4 version of HAVE_INLINE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INLINE 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_INLINE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INLINE 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_INO64_T
+ fputs("/** DK4 version of HAVE_INO64_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INO64_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_INO64_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INO64_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_INO_T
+ fputs("/** DK4 version of HAVE_INO_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INO_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_INO_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INO_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_INT16_T
+ fputs("/** DK4 version of HAVE_INT16_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INT16_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_INT16_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INT16_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_INT32_T
+ fputs("/** DK4 version of HAVE_INT32_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INT32_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_INT32_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INT32_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_INT8_T
+ fputs("/** DK4 version of HAVE_INT8_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INT8_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_INT8_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INT8_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_INTMAX_T
+ fputs("/** DK4 version of HAVE_INTMAX_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INTMAX_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_INTMAX_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INTMAX_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_INTTYPES_H
+ fputs("/** DK4 version of HAVE_INTTYPES_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INTTYPES_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_INTTYPES_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INTTYPES_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_IN_ADDR
+ fputs("/** DK4 version of HAVE_IN_ADDR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_IN_ADDR 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_IN_ADDR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_IN_ADDR 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_IO_H
+ fputs("/** DK4 version of HAVE_IO_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_IO_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_IO_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_IO_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_ISATTY
+ fputs("/** DK4 version of HAVE_ISATTY.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ISATTY 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_ISATTY.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ISATTY 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_ISFINITE
+ fputs("/** DK4 version of HAVE_ISFINITE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ISFINITE 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_ISFINITE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ISFINITE 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_ISNORMAL
+ fputs("/** DK4 version of HAVE_ISNORMAL.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ISNORMAL 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_ISNORMAL.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ISNORMAL 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_ISO646_H
+ fputs("/** DK4 version of HAVE_ISO646_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ISO646_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_ISO646_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ISO646_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_JPEGLIB_H
+ fputs("/** DK4 version of HAVE_JPEGLIB_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_JPEGLIB_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_JPEGLIB_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_JPEGLIB_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_LARGEFILE64_SOURCE
+ fputs("/** DK4 version of HAVE_LARGEFILE64_SOURCE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LARGEFILE64_SOURCE 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_LARGEFILE64_SOURCE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LARGEFILE64_SOURCE 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_LIBNETSNMP
+ fputs("/** DK4 version of HAVE_LIBNETSNMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LIBNETSNMP 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_LIBNETSNMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LIBNETSNMP 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_LIMITS_H
+ fputs("/** DK4 version of HAVE_LIMITS_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LIMITS_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_LIMITS_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LIMITS_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_LINE_END_CR_NL
+ fputs("/** DK4 version of HAVE_LINE_END_CR_NL.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LINE_END_CR_NL 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_LINE_END_CR_NL.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LINE_END_CR_NL 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_LOCALE_H
+ fputs("/** DK4 version of HAVE_LOCALE_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LOCALE_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_LOCALE_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LOCALE_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_LOCALTIME_R
+ fputs("/** DK4 version of HAVE_LOCALTIME_R.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LOCALTIME_R 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_LOCALTIME_R.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LOCALTIME_R 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_LONG_DOUBLE
+ fputs("/** DK4 version of HAVE_LONG_DOUBLE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LONG_DOUBLE 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_LONG_DOUBLE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LONG_DOUBLE 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_LONG_LONG
+ fputs("/** DK4 version of HAVE_LONG_LONG.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LONG_LONG 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_LONG_LONG.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LONG_LONG 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_LRAND48
+ fputs("/** DK4 version of HAVE_LRAND48.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LRAND48 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_LRAND48.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LRAND48 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_LSTAT
+ fputs("/** DK4 version of HAVE_LSTAT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LSTAT 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_LSTAT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LSTAT 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_LSTAT64
+ fputs("/** DK4 version of HAVE_LSTAT64.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LSTAT64 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_LSTAT64.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LSTAT64 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_MALLOC
+ fputs("/** DK4 version of HAVE_MALLOC.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_MALLOC 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_MALLOC.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_MALLOC 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_MALLOC_H
+ fputs("/** DK4 version of HAVE_MALLOC_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_MALLOC_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_MALLOC_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_MALLOC_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_MATH_H
+ fputs("/** DK4 version of HAVE_MATH_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_MATH_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_MATH_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_MATH_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_MEMCMP
+ fputs("/** DK4 version of HAVE_MEMCMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_MEMCMP 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_MEMCMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_MEMCMP 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_MEMCPY
+ fputs("/** DK4 version of HAVE_MEMCPY.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_MEMCPY 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_MEMCPY.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_MEMCPY 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_MEMSET
+ fputs("/** DK4 version of HAVE_MEMSET.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_MEMSET 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_MEMSET.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_MEMSET 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_MKDIR
+ fputs("/** DK4 version of HAVE_MKDIR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_MKDIR 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_MKDIR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_MKDIR 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_MODE_T
+ fputs("/** DK4 version of HAVE_MODE_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_MODE_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_MODE_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_MODE_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_NDBM_H
+ fputs("/** DK4 version of HAVE_NDBM_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_NDBM_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_NDBM_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_NDBM_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_NETDB_H
+ fputs("/** DK4 version of HAVE_NETDB_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_NETDB_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_NETDB_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_NETDB_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_NETINET_IN6_H
+ fputs("/** DK4 version of HAVE_NETINET_IN6_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_NETINET_IN6_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_NETINET_IN6_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_NETINET_IN6_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_NETINET_IN_H
+ fputs("/** DK4 version of HAVE_NETINET_IN_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_NETINET_IN_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_NETINET_IN_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_NETINET_IN_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_NLINK_T
+ fputs("/** DK4 version of HAVE_NLINK_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_NLINK_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_NLINK_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_NLINK_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_NRAND48
+ fputs("/** DK4 version of HAVE_NRAND48.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_NRAND48 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_NRAND48.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_NRAND48 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_NTIFS_H
+ fputs("/** DK4 version of HAVE_NTIFS_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_NTIFS_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_NTIFS_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_NTIFS_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_NTOHL
+ fputs("/** DK4 version of HAVE_NTOHL.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_NTOHL 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_NTOHL.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_NTOHL 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_NTOHS
+ fputs("/** DK4 version of HAVE_NTOHS.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_NTOHS 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_NTOHS.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_NTOHS 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_OFF64_T
+ fputs("/** DK4 version of HAVE_OFF64_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_OFF64_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_OFF64_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_OFF64_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_OFF_T
+ fputs("/** DK4 version of HAVE_OFF_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_OFF_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_OFF_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_OFF_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_OPENSSL_MD5_H
+ fputs("/** DK4 version of HAVE_OPENSSL_MD5_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_OPENSSL_MD5_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_OPENSSL_MD5_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_OPENSSL_MD5_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_OPENSSL_RAND_H
+ fputs("/** DK4 version of HAVE_OPENSSL_RAND_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_OPENSSL_RAND_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_OPENSSL_RAND_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_OPENSSL_RAND_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_OPENSSL_RIPEMD_H
+ fputs("/** DK4 version of HAVE_OPENSSL_RIPEMD_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_OPENSSL_RIPEMD_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_OPENSSL_RIPEMD_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_OPENSSL_RIPEMD_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_OPENSSL_SHA_H
+ fputs("/** DK4 version of HAVE_OPENSSL_SHA_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_OPENSSL_SHA_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_OPENSSL_SHA_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_OPENSSL_SHA_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_PNG_GET_PIXELS_PER_INCH
+ fputs("/** DK4 version of HAVE_PNG_GET_PIXELS_PER_INCH.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_PNG_GET_PIXELS_PER_INCH 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_PNG_GET_PIXELS_PER_INCH.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_PNG_GET_PIXELS_PER_INCH 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_PNG_H
+ fputs("/** DK4 version of HAVE_PNG_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_PNG_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_PNG_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_PNG_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_PROCESS_H
+ fputs("/** DK4 version of HAVE_PROCESS_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_PROCESS_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_PROCESS_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_PROCESS_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_PROC_PID_EXE
+ fputs("/** DK4 version of HAVE_PROC_PID_EXE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_PROC_PID_EXE 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_PROC_PID_EXE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_PROC_PID_EXE 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_PWD_H
+ fputs("/** DK4 version of HAVE_PWD_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_PWD_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_PWD_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_PWD_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_RAND
+ fputs("/** DK4 version of HAVE_RAND.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_RAND 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_RAND.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_RAND 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_RANDOM
+ fputs("/** DK4 version of HAVE_RANDOM.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_RANDOM 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_RANDOM.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_RANDOM 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_RAND_EGD
+ fputs("/** DK4 version of HAVE_RAND_EGD.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_RAND_EGD 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_RAND_EGD.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_RAND_EGD 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_READ
+ fputs("/** DK4 version of HAVE_READ.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_READ 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_READ.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_READ 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_READLINK
+ fputs("/** DK4 version of HAVE_READLINK.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_READLINK 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_READLINK.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_READLINK 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_RMDIR
+ fputs("/** DK4 version of HAVE_RMDIR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_RMDIR 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_RMDIR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_RMDIR 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SELECT
+ fputs("/** DK4 version of HAVE_SELECT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SELECT 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SELECT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SELECT 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SETBUF
+ fputs("/** DK4 version of HAVE_SETBUF.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETBUF 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SETBUF.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETBUF 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SETBUFFER
+ fputs("/** DK4 version of HAVE_SETBUFFER.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETBUFFER 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SETBUFFER.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETBUFFER 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SETGID
+ fputs("/** DK4 version of HAVE_SETGID.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETGID 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SETGID.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETGID 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SETGRENT
+ fputs("/** DK4 version of HAVE_SETGRENT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETGRENT 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SETGRENT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETGRENT 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SETJMP_H
+ fputs("/** DK4 version of HAVE_SETJMP_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETJMP_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SETJMP_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETJMP_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SETLOCALE
+ fputs("/** DK4 version of HAVE_SETLOCALE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETLOCALE 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SETLOCALE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETLOCALE 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SETMODE
+ fputs("/** DK4 version of HAVE_SETMODE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETMODE 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SETMODE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETMODE 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SETPGRP
+ fputs("/** DK4 version of HAVE_SETPGRP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETPGRP 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SETPGRP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETPGRP 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SETPWENT
+ fputs("/** DK4 version of HAVE_SETPWENT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETPWENT 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SETPWENT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETPWENT 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SETSID
+ fputs("/** DK4 version of HAVE_SETSID.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETSID 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SETSID.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETSID 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SETSOCKOPT
+ fputs("/** DK4 version of HAVE_SETSOCKOPT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETSOCKOPT 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SETSOCKOPT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETSOCKOPT 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SETSTATE
+ fputs("/** DK4 version of HAVE_SETSTATE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETSTATE 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SETSTATE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETSTATE 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SETUID
+ fputs("/** DK4 version of HAVE_SETUID.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETUID 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SETUID.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETUID 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SETVBUF
+ fputs("/** DK4 version of HAVE_SETVBUF.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETVBUF 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SETVBUF.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETVBUF 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SHA224
+ fputs("/** DK4 version of HAVE_SHA224.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SHA224 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SHA224.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SHA224 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SHA256
+ fputs("/** DK4 version of HAVE_SHA256.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SHA256 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SHA256.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SHA256 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SHA384
+ fputs("/** DK4 version of HAVE_SHA384.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SHA384 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SHA384.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SHA384 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SHA512
+ fputs("/** DK4 version of HAVE_SHA512.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SHA512 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SHA512.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SHA512 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SHARE_H
+ fputs("/** DK4 version of HAVE_SHARE_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SHARE_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SHARE_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SHARE_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SIGACTION
+ fputs("/** DK4 version of HAVE_SIGACTION.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SIGACTION 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SIGACTION.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SIGACTION 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SIGEMPTYSET
+ fputs("/** DK4 version of HAVE_SIGEMPTYSET.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SIGEMPTYSET 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SIGEMPTYSET.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SIGEMPTYSET 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SIGNAL
+ fputs("/** DK4 version of HAVE_SIGNAL.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SIGNAL 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SIGNAL.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SIGNAL 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SIGNAL_H
+ fputs("/** DK4 version of HAVE_SIGNAL_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SIGNAL_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SIGNAL_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SIGNAL_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SIGPROCMASK
+ fputs("/** DK4 version of HAVE_SIGPROCMASK.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SIGPROCMASK 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SIGPROCMASK.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SIGPROCMASK 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SIGSET
+ fputs("/** DK4 version of HAVE_SIGSET.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SIGSET 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SIGSET.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SIGSET 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SIG_ATOMIC_T
+ fputs("/** DK4 version of HAVE_SIG_ATOMIC_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SIG_ATOMIC_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SIG_ATOMIC_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SIG_ATOMIC_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SNMP_DISABLE_FILELOG
+ fputs("/** DK4 version of HAVE_SNMP_DISABLE_FILELOG.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SNMP_DISABLE_FILELOG 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SNMP_DISABLE_FILELOG.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SNMP_DISABLE_FILELOG 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SNMP_DISABLE_STDERRLOG
+ fputs("/** DK4 version of HAVE_SNMP_DISABLE_STDERRLOG.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SNMP_DISABLE_STDERRLOG 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SNMP_DISABLE_STDERRLOG.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SNMP_DISABLE_STDERRLOG 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SNMP_DISABLE_SYSLOG
+ fputs("/** DK4 version of HAVE_SNMP_DISABLE_SYSLOG.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SNMP_DISABLE_SYSLOG 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SNMP_DISABLE_SYSLOG.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SNMP_DISABLE_SYSLOG 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SNMP_ENABLE_FILELOG
+ fputs("/** DK4 version of HAVE_SNMP_ENABLE_FILELOG.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SNMP_ENABLE_FILELOG 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SNMP_ENABLE_FILELOG.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SNMP_ENABLE_FILELOG 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SNPRINTF
+ fputs("/** DK4 version of HAVE_SNPRINTF.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SNPRINTF 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SNPRINTF.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SNPRINTF 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SNWPRINTF
+ fputs("/** DK4 version of HAVE_SNWPRINTF.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SNWPRINTF 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SNWPRINTF.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SNWPRINTF 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SOCKET
+ fputs("/** DK4 version of HAVE_SOCKET.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SOCKET 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SOCKET.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SOCKET 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SOCKLEN_T
+ fputs("/** DK4 version of HAVE_SOCKLEN_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SOCKLEN_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SOCKLEN_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SOCKLEN_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SRAND
+ fputs("/** DK4 version of HAVE_SRAND.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SRAND 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SRAND.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SRAND 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SSIZE_T
+ fputs("/** DK4 version of HAVE_SSIZE_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SSIZE_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SSIZE_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SSIZE_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STAT64
+ fputs("/** DK4 version of HAVE_STAT64.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STAT64 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STAT64.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STAT64 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STDALIGN_H
+ fputs("/** DK4 version of HAVE_STDALIGN_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STDALIGN_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STDALIGN_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STDALIGN_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STDARG_H
+ fputs("/** DK4 version of HAVE_STDARG_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STDARG_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STDARG_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STDARG_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STDATOMIC_H
+ fputs("/** DK4 version of HAVE_STDATOMIC_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STDATOMIC_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STDATOMIC_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STDATOMIC_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STDBOOL_H
+ fputs("/** DK4 version of HAVE_STDBOOL_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STDBOOL_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STDBOOL_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STDBOOL_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STDDEF_H
+ fputs("/** DK4 version of HAVE_STDDEF_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STDDEF_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STDDEF_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STDDEF_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STDINT_H
+ fputs("/** DK4 version of HAVE_STDINT_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STDINT_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STDINT_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STDINT_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STDLIB_H
+ fputs("/** DK4 version of HAVE_STDLIB_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STDLIB_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STDLIB_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STDLIB_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STDNORETURN_H
+ fputs("/** DK4 version of HAVE_STDNORETURN_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STDNORETURN_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STDNORETURN_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STDNORETURN_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STRCASECMP
+ fputs("/** DK4 version of HAVE_STRCASECMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRCASECMP 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STRCASECMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRCASECMP 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STRCAT_S
+ fputs("/** DK4 version of HAVE_STRCAT_S.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRCAT_S 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STRCAT_S.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRCAT_S 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STRCPY_S
+ fputs("/** DK4 version of HAVE_STRCPY_S.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRCPY_S 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STRCPY_S.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRCPY_S 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STRERROR
+ fputs("/** DK4 version of HAVE_STRERROR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRERROR 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STRERROR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRERROR 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STRERROR_R
+ fputs("/** DK4 version of HAVE_STRERROR_R.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRERROR_R 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STRERROR_R.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRERROR_R 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STRICMP
+ fputs("/** DK4 version of HAVE_STRICMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRICMP 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STRICMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRICMP 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STRINGS_H
+ fputs("/** DK4 version of HAVE_STRINGS_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRINGS_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STRINGS_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRINGS_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STRING_H
+ fputs("/** DK4 version of HAVE_STRING_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRING_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STRING_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRING_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STRTOD
+ fputs("/** DK4 version of HAVE_STRTOD.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRTOD 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STRTOD.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRTOD 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STRUCT_ADDRINFO
+ fputs("/** DK4 version of HAVE_STRUCT_ADDRINFO.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRUCT_ADDRINFO 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STRUCT_ADDRINFO.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRUCT_ADDRINFO 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STRUCT_SOCKADDR_IN
+ fputs("/** DK4 version of HAVE_STRUCT_SOCKADDR_IN.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRUCT_SOCKADDR_IN 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STRUCT_SOCKADDR_IN.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRUCT_SOCKADDR_IN 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STRUCT_SOCKADDR_IN6
+ fputs("/** DK4 version of HAVE_STRUCT_SOCKADDR_IN6.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRUCT_SOCKADDR_IN6 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STRUCT_SOCKADDR_IN6.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRUCT_SOCKADDR_IN6 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STRUCT_SOCKADDR_STORAGE
+ fputs("/** DK4 version of HAVE_STRUCT_SOCKADDR_STORAGE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRUCT_SOCKADDR_STORAGE 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STRUCT_SOCKADDR_STORAGE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRUCT_SOCKADDR_STORAGE 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STRUCT_SOCKADDR_UN
+ fputs("/** DK4 version of HAVE_STRUCT_SOCKADDR_UN.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRUCT_SOCKADDR_UN 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STRUCT_SOCKADDR_UN.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRUCT_SOCKADDR_UN 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SWPRINTF
+ fputs("/** DK4 version of HAVE_SWPRINTF.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SWPRINTF 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SWPRINTF.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SWPRINTF 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SYSLOG
+ fputs("/** DK4 version of HAVE_SYSLOG.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SYSLOG 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SYSLOG.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SYSLOG 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SYSLOG_H
+ fputs("/** DK4 version of HAVE_SYSLOG_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SYSLOG_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SYSLOG_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SYSLOG_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SYS_PARAM_H
+ fputs("/** DK4 version of HAVE_SYS_PARAM_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SYS_PARAM_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SYS_PARAM_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SYS_PARAM_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SYS_RESOURCE_H
+ fputs("/** DK4 version of HAVE_SYS_RESOURCE_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SYS_RESOURCE_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SYS_RESOURCE_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SYS_RESOURCE_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SYS_SELECT_H
+ fputs("/** DK4 version of HAVE_SYS_SELECT_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SYS_SELECT_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SYS_SELECT_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SYS_SELECT_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SYS_SOCKET_H
+ fputs("/** DK4 version of HAVE_SYS_SOCKET_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SYS_SOCKET_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SYS_SOCKET_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SYS_SOCKET_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SYS_STAT_H
+ fputs("/** DK4 version of HAVE_SYS_STAT_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SYS_STAT_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SYS_STAT_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SYS_STAT_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SYS_TIME_H
+ fputs("/** DK4 version of HAVE_SYS_TIME_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SYS_TIME_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SYS_TIME_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SYS_TIME_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SYS_TYPES_H
+ fputs("/** DK4 version of HAVE_SYS_TYPES_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SYS_TYPES_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SYS_TYPES_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SYS_TYPES_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SYS_UN_H
+ fputs("/** DK4 version of HAVE_SYS_UN_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SYS_UN_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SYS_UN_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SYS_UN_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_TGMATH_H
+ fputs("/** DK4 version of HAVE_TGMATH_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_TGMATH_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_TGMATH_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_TGMATH_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_THREADS_H
+ fputs("/** DK4 version of HAVE_THREADS_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_THREADS_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_THREADS_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_THREADS_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_TIFF_H
+ fputs("/** DK4 version of HAVE_TIFF_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_TIFF_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_TIFF_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_TIFF_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_TIME_H
+ fputs("/** DK4 version of HAVE_TIME_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_TIME_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_TIME_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_TIME_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_TYPE_STAT64
+ fputs("/** DK4 version of HAVE_TYPE_STAT64.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_TYPE_STAT64 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_TYPE_STAT64.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_TYPE_STAT64 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_UCHAR_H
+ fputs("/** DK4 version of HAVE_UCHAR_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_UCHAR_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_UCHAR_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_UCHAR_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_UID_T
+ fputs("/** DK4 version of HAVE_UID_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_UID_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_UID_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_UID_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_UINT16_T
+ fputs("/** DK4 version of HAVE_UINT16_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_UINT16_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_UINT16_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_UINT16_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_UINT32_T
+ fputs("/** DK4 version of HAVE_UINT32_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_UINT32_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_UINT32_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_UINT32_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_UINT8_T
+ fputs("/** DK4 version of HAVE_UINT8_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_UINT8_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_UINT8_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_UINT8_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_UNISTD_H
+ fputs("/** DK4 version of HAVE_UNISTD_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_UNISTD_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_UNISTD_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_UNISTD_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_UNLINK
+ fputs("/** DK4 version of HAVE_UNLINK.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_UNLINK 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_UNLINK.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_UNLINK 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_VOLATILE
+ fputs("/** DK4 version of HAVE_VOLATILE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_VOLATILE 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_VOLATILE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_VOLATILE 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WCHAR_H
+ fputs("/** DK4 version of HAVE_WCHAR_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCHAR_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WCHAR_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCHAR_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WCSCASECMP
+ fputs("/** DK4 version of HAVE_WCSCASECMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSCASECMP 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WCSCASECMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSCASECMP 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WCSCAT
+ fputs("/** DK4 version of HAVE_WCSCAT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSCAT 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WCSCAT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSCAT 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WCSCAT_S
+ fputs("/** DK4 version of HAVE_WCSCAT_S.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSCAT_S 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WCSCAT_S.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSCAT_S 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WCSCHR
+ fputs("/** DK4 version of HAVE_WCSCHR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSCHR 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WCSCHR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSCHR 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WCSCMP
+ fputs("/** DK4 version of HAVE_WCSCMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSCMP 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WCSCMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSCMP 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WCSCPY
+ fputs("/** DK4 version of HAVE_WCSCPY.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSCPY 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WCSCPY.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSCPY 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WCSCPY_S
+ fputs("/** DK4 version of HAVE_WCSCPY_S.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSCPY_S 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WCSCPY_S.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSCPY_S 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WCSICMP
+ fputs("/** DK4 version of HAVE_WCSICMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSICMP 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WCSICMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSICMP 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WCSLEN
+ fputs("/** DK4 version of HAVE_WCSLEN.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSLEN 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WCSLEN.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSLEN 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WCSNCMP
+ fputs("/** DK4 version of HAVE_WCSNCMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSNCMP 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WCSNCMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSNCMP 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WCSRCHR
+ fputs("/** DK4 version of HAVE_WCSRCHR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSRCHR 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WCSRCHR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSRCHR 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WCSTOD
+ fputs("/** DK4 version of HAVE_WCSTOD.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSTOD 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WCSTOD.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSTOD 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WCTYPE_H
+ fputs("/** DK4 version of HAVE_WCTYPE_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCTYPE_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WCTYPE_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCTYPE_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WINDOWS_H
+ fputs("/** DK4 version of HAVE_WINDOWS_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WINDOWS_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WINDOWS_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WINDOWS_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WINSOCK2_H
+ fputs("/** DK4 version of HAVE_WINSOCK2_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WINSOCK2_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WINSOCK2_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WINSOCK2_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WMKDIR
+ fputs("/** DK4 version of HAVE_WMKDIR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WMKDIR 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WMKDIR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WMKDIR 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WRITE
+ fputs("/** DK4 version of HAVE_WRITE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WRITE 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WRITE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WRITE 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WRMDIR
+ fputs("/** DK4 version of HAVE_WRMDIR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WRMDIR 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WRMDIR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WRMDIR 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WS2TCPIP_H
+ fputs("/** DK4 version of HAVE_WS2TCPIP_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WS2TCPIP_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WS2TCPIP_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WS2TCPIP_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WUNLINK
+ fputs("/** DK4 version of HAVE_WUNLINK.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WUNLINK 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WUNLINK.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WUNLINK 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WXWIDGETS
+ fputs("/** DK4 version of HAVE_WXWIDGETS.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WXWIDGETS 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WXWIDGETS.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WXWIDGETS 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_ZLIB_H
+ fputs("/** DK4 version of HAVE_ZLIB_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ZLIB_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_ZLIB_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ZLIB_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__DEV_T
+ fputs("/** DK4 version of HAVE__DEV_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__DEV_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__DEV_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__DEV_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__FILENO
+ fputs("/** DK4 version of HAVE__FILENO.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__FILENO 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__FILENO.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__FILENO 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__FINITE
+ fputs("/** DK4 version of HAVE__FINITE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__FINITE 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__FINITE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__FINITE 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__FPOS_T
+ fputs("/** DK4 version of HAVE__FPOS_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__FPOS_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__FPOS_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__FPOS_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__GETCWD
+ fputs("/** DK4 version of HAVE__GETCWD.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__GETCWD 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__GETCWD.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__GETCWD 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__INO64_T
+ fputs("/** DK4 version of HAVE__INO64_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__INO64_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__INO64_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__INO64_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__INO_T
+ fputs("/** DK4 version of HAVE__INO_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__INO_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__INO_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__INO_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__ISATTY
+ fputs("/** DK4 version of HAVE__ISATTY.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__ISATTY 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__ISATTY.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__ISATTY 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__MKDIR
+ fputs("/** DK4 version of HAVE__MKDIR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__MKDIR 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__MKDIR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__MKDIR 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__OFF64_T
+ fputs("/** DK4 version of HAVE__OFF64_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__OFF64_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__OFF64_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__OFF64_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__OFF_T
+ fputs("/** DK4 version of HAVE__OFF_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__OFF_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__OFF_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__OFF_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__READ
+ fputs("/** DK4 version of HAVE__READ.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__READ 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__READ.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__READ 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__RMDIR
+ fputs("/** DK4 version of HAVE__RMDIR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__RMDIR 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__RMDIR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__RMDIR 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__SETMODE
+ fputs("/** DK4 version of HAVE__SETMODE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__SETMODE 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__SETMODE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__SETMODE 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__SNPRINTF
+ fputs("/** DK4 version of HAVE__SNPRINTF.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__SNPRINTF 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__SNPRINTF.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__SNPRINTF 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__SNPRINTF_S
+ fputs("/** DK4 version of HAVE__SNPRINTF_S.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__SNPRINTF_S 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__SNPRINTF_S.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__SNPRINTF_S 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__SNWPRINTF
+ fputs("/** DK4 version of HAVE__SNWPRINTF.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__SNWPRINTF 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__SNWPRINTF.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__SNWPRINTF 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__SNWPRINTF_S
+ fputs("/** DK4 version of HAVE__SNWPRINTF_S.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__SNWPRINTF_S 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__SNWPRINTF_S.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__SNWPRINTF_S 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__STRICMP
+ fputs("/** DK4 version of HAVE__STRICMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__STRICMP 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__STRICMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__STRICMP 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__STRTOD
+ fputs("/** DK4 version of HAVE__STRTOD.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__STRTOD 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__STRTOD.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__STRTOD 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__UNLINK
+ fputs("/** DK4 version of HAVE__UNLINK.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__UNLINK 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__UNLINK.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__UNLINK 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__WCSCASECMP
+ fputs("/** DK4 version of HAVE__WCSCASECMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WCSCASECMP 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__WCSCASECMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WCSCASECMP 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__WCSCMP
+ fputs("/** DK4 version of HAVE__WCSCMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WCSCMP 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__WCSCMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WCSCMP 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__WCSICMP
+ fputs("/** DK4 version of HAVE__WCSICMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WCSICMP 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__WCSICMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WCSICMP 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__WCSNCMP
+ fputs("/** DK4 version of HAVE__WCSNCMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WCSNCMP 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__WCSNCMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WCSNCMP 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__WCSTOD
+ fputs("/** DK4 version of HAVE__WCSTOD.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WCSTOD 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__WCSTOD.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WCSTOD 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__WFOPEN
+ fputs("/** DK4 version of HAVE__WFOPEN.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WFOPEN 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__WFOPEN.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WFOPEN 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__WFOPEN64
+ fputs("/** DK4 version of HAVE__WFOPEN64.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WFOPEN64 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__WFOPEN64.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WFOPEN64 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__WFOPEN_S
+ fputs("/** DK4 version of HAVE__WFOPEN_S.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WFOPEN_S 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__WFOPEN_S.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WFOPEN_S 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__WGETCWD
+ fputs("/** DK4 version of HAVE__WGETCWD.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WGETCWD 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__WGETCWD.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WGETCWD 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__WMKDIR
+ fputs("/** DK4 version of HAVE__WMKDIR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WMKDIR 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__WMKDIR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WMKDIR 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__WRITE
+ fputs("/** DK4 version of HAVE__WRITE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WRITE 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__WRITE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WRITE 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__WRMDIR
+ fputs("/** DK4 version of HAVE__WRMDIR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WRMDIR 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__WRMDIR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WRMDIR 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__WUNLINK
+ fputs("/** DK4 version of HAVE__WUNLINK.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WUNLINK 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__WUNLINK.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WUNLINK 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if SIZEOF_DOUBLE
+ fputs("/** DK4 version of SIZEOF_DOUBLE.\n*/\n", stdout);
+ printf("#define DK4_SIZEOF_DOUBLE %u\n", (unsigned)SIZEOF_DOUBLE);
+#else
+ fputs("/** DK4 version of SIZEOF_DOUBLE.\n*/\n", stdout);
+ fputs("#define DK4_SIZEOF_DOUBLE 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if SIZEOF_INO64_T
+ fputs("/** DK4 version of SIZEOF_INO64_T.\n*/\n", stdout);
+ printf("#define DK4_SIZEOF_INO64_T %u\n", (unsigned)SIZEOF_INO64_T);
+#else
+ fputs("/** DK4 version of SIZEOF_INO64_T.\n*/\n", stdout);
+ fputs("#define DK4_SIZEOF_INO64_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if SIZEOF_INO_T
+ fputs("/** DK4 version of SIZEOF_INO_T.\n*/\n", stdout);
+ printf("#define DK4_SIZEOF_INO_T %u\n", (unsigned)SIZEOF_INO_T);
+#else
+ fputs("/** DK4 version of SIZEOF_INO_T.\n*/\n", stdout);
+ fputs("#define DK4_SIZEOF_INO_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if SIZEOF_INT
+ fputs("/** DK4 version of SIZEOF_INT.\n*/\n", stdout);
+ printf("#define DK4_SIZEOF_INT %u\n", (unsigned)SIZEOF_INT);
+#else
+ fputs("/** DK4 version of SIZEOF_INT.\n*/\n", stdout);
+ fputs("#define DK4_SIZEOF_INT 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if SIZEOF_INTMAX_T
+ fputs("/** DK4 version of SIZEOF_INTMAX_T.\n*/\n", stdout);
+ printf("#define DK4_SIZEOF_INTMAX_T %u\n", (unsigned)SIZEOF_INTMAX_T);
+#else
+ fputs("/** DK4 version of SIZEOF_INTMAX_T.\n*/\n", stdout);
+ fputs("#define DK4_SIZEOF_INTMAX_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if SIZEOF_LONG
+ fputs("/** DK4 version of SIZEOF_LONG.\n*/\n", stdout);
+ printf("#define DK4_SIZEOF_LONG %u\n", (unsigned)SIZEOF_LONG);
+#else
+ fputs("/** DK4 version of SIZEOF_LONG.\n*/\n", stdout);
+ fputs("#define DK4_SIZEOF_LONG 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if SIZEOF_LONG_DOUBLE
+ fputs("/** DK4 version of SIZEOF_LONG_DOUBLE.\n*/\n", stdout);
+ printf("#define DK4_SIZEOF_LONG_DOUBLE %u\n", (unsigned)SIZEOF_LONG_DOUBLE);
+#else
+ fputs("/** DK4 version of SIZEOF_LONG_DOUBLE.\n*/\n", stdout);
+ fputs("#define DK4_SIZEOF_LONG_DOUBLE 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if SIZEOF_LONG_LONG
+ fputs("/** DK4 version of SIZEOF_LONG_LONG.\n*/\n", stdout);
+ printf("#define DK4_SIZEOF_LONG_LONG %u\n", (unsigned)SIZEOF_LONG_LONG);
+#else
+ fputs("/** DK4 version of SIZEOF_LONG_LONG.\n*/\n", stdout);
+ fputs("#define DK4_SIZEOF_LONG_LONG 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if SIZEOF_OFF64_T
+ fputs("/** DK4 version of SIZEOF_OFF64_T.\n*/\n", stdout);
+ printf("#define DK4_SIZEOF_OFF64_T %u\n", (unsigned)SIZEOF_OFF64_T);
+#else
+ fputs("/** DK4 version of SIZEOF_OFF64_T.\n*/\n", stdout);
+ fputs("#define DK4_SIZEOF_OFF64_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if SIZEOF_OFF_T
+ fputs("/** DK4 version of SIZEOF_OFF_T.\n*/\n", stdout);
+ printf("#define DK4_SIZEOF_OFF_T %u\n", (unsigned)SIZEOF_OFF_T);
+#else
+ fputs("/** DK4 version of SIZEOF_OFF_T.\n*/\n", stdout);
+ fputs("#define DK4_SIZEOF_OFF_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if SIZEOF_SHORT
+ fputs("/** DK4 version of SIZEOF_SHORT.\n*/\n", stdout);
+ printf("#define DK4_SIZEOF_SHORT %u\n", (unsigned)SIZEOF_SHORT);
+#else
+ fputs("/** DK4 version of SIZEOF_SHORT.\n*/\n", stdout);
+ fputs("#define DK4_SIZEOF_SHORT 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if SIZEOF_SIZE_T
+ fputs("/** DK4 version of SIZEOF_SIZE_T.\n*/\n", stdout);
+ printf("#define DK4_SIZEOF_SIZE_T %u\n", (unsigned)SIZEOF_SIZE_T);
+#else
+ fputs("/** DK4 version of SIZEOF_SIZE_T.\n*/\n", stdout);
+ fputs("#define DK4_SIZEOF_SIZE_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if SIZEOF_WCHAR_T
+ fputs("/** DK4 version of SIZEOF_WCHAR_T.\n*/\n", stdout);
+ printf("#define DK4_SIZEOF_WCHAR_T %u\n", (unsigned)SIZEOF_WCHAR_T);
+#else
+ fputs("/** DK4 version of SIZEOF_WCHAR_T.\n*/\n", stdout);
+ fputs("#define DK4_SIZEOF_WCHAR_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if TIME_WITH_SYS_TIME
+ fputs("/** DK4 version of TIME_WITH_SYS_TIME.\n*/\n", stdout);
+ printf("#define DK4_TIME_WITH_SYS_TIME %u\n", (unsigned)TIME_WITH_SYS_TIME);
+#else
+ fputs("/** DK4 version of TIME_WITH_SYS_TIME.\n*/\n", stdout);
+ fputs("#define DK4_TIME_WITH_SYS_TIME 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if USE_FALLBACK_NUMERIC_LIMITS
+ fputs("/** DK4 version of USE_FALLBACK_NUMERIC_LIMITS.\n*/\n", stdout);
+ printf("#define DK4_USE_FALLBACK_NUMERIC_LIMITS %u\n", (unsigned)USE_FALLBACK_NUMERIC_LIMITS);
+#else
+ fputs("/** DK4 version of USE_FALLBACK_NUMERIC_LIMITS.\n*/\n", stdout);
+ fputs("#define DK4_USE_FALLBACK_NUMERIC_LIMITS 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if USE_PRINTF_SCANF
+ fputs("/** DK4 version of USE_PRINTF_SCANF.\n*/\n", stdout);
+ printf("#define DK4_USE_PRINTF_SCANF %u\n", (unsigned)USE_PRINTF_SCANF);
+#else
+ fputs("/** DK4 version of USE_PRINTF_SCANF.\n*/\n", stdout);
+ fputs("#define DK4_USE_PRINTF_SCANF 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if USE_WINDOWS_LOCAL_ALLOC
+ fputs("/** DK4 version of USE_WINDOWS_LOCAL_ALLOC.\n*/\n", stdout);
+ printf("#define DK4_USE_WINDOWS_LOCAL_ALLOC %u\n", (unsigned)USE_WINDOWS_LOCAL_ALLOC);
+#else
+ fputs("/** DK4 version of USE_WINDOWS_LOCAL_ALLOC.\n*/\n", stdout);
+ fputs("#define DK4_USE_WINDOWS_LOCAL_ALLOC 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if WORDS_BIGENDIAN
+ fputs("/** DK4 version of WORDS_BIGENDIAN.\n*/\n", stdout);
+ printf("#define DK4_WORDS_BIGENDIAN %u\n", (unsigned)WORDS_BIGENDIAN);
+#else
+ fputs("/** DK4 version of WORDS_BIGENDIAN.\n*/\n", stdout);
+ fputs("#define DK4_WORDS_BIGENDIAN 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+/* wxWidgets_body_start */
+#if HAVE_WXWIDGETS
+ fputs("/** Size of wchar_t.\n*/\n", stdout);
+ printf("#define DK4_SIZEOF_WXCHAR %u\n\n", (unsigned)sizeof(wxChar));
+#else
+ fputs("/** Size of wchar_t.\n*/\n", stdout);
+ fputs("#define DK4_SIZEOF_WXCHAR 0\n\n", stdout);
+#endif
+/* wxWidgets_body_end */
+
+ fputs("#endif\n/* ifndef DK4CONF_H_INCLUDED */\n", stdout);
+ return 0;
+}
diff --git a/support/dktools/dk4const.h b/support/dktools/dk4const.h
new file mode 100644
index 0000000000..f1a0285391
--- /dev/null
+++ b/support/dktools/dk4const.h
@@ -0,0 +1,60 @@
+/** @file dk4const.h Numeric constants
+for log level and string table entry length.
+
+*/
+#ifndef DK4CONST_H_INCLUDED
+/** Protection against multiple inclusion.
+*/
+#define DK4CONST_H_INCLUDED 1
+
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+
+
+/** Log levels, higher numeric values correspond to lower priorities.
+*/
+enum {
+ /** This message priority never occurs. */
+DK4_LL_NONE = 0,
+
+ /** Panic message. */
+DK4_LL_PANIC,
+
+ /** Fatal error message. */
+DK4_LL_FATAL,
+
+ /** Error message. */
+DK4_LL_ERROR,
+
+ /** Warning message. */
+DK4_LL_WARNING,
+
+ /** Informational message. */
+DK4_LL_INFO,
+
+ /** Progress message. */
+DK4_LL_PROGRESS,
+
+ /** Debug message. */
+DK4_LL_DEBUG,
+
+ /** Message can be ignored. */
+DK4_LL_IGNORE
+};
+
+
+
+/** Maximum string table line width.
+*/
+enum {
+ /** Maximum string table line width.
+ */
+ DK4_MAX_STRING_TABLE_LINE_LENGTH = 1024
+};
+
+#endif
+/* ifndef DK4CONST_H_INCLUDED */
diff --git a/support/dktools/dk4ctime.c b/support/dktools/dk4ctime.c
new file mode 100644
index 0000000000..6d05522a3d
--- /dev/null
+++ b/support/dktools/dk4ctime.c
@@ -0,0 +1,199 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4ctime.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4ctime.c The dk4ctime module.
+*/
+
+
+#line 131 "dk4ctime.ctr"
+
+#include "dk4conf.h"
+
+#include "dk4types.h"
+
+#include "dk4ctime.h"
+
+#ifndef DK4REC22_H_INCLUDED
+#include "dk4rec22.h"
+#endif
+
+#ifndef DK4TIME_H_INCLUDED
+#include "dk4time.h"
+#endif
+
+#ifndef DK4TIMEDK_H_INCLUDED
+#include "dk4timedk.h"
+#endif
+
+#ifndef DK4TIME08_H_INCLUDED
+#include "dk4time08.h"
+#endif
+
+
+
+int
+dk4clocktime_get(dk4_clock_time_t *dptr)
+{
+ if (NULL != dptr) {
+#if DK4_ON_WINDOWS && (DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT)
+ GetLocalTime(dptr);
+ return 1;
+#else
+ dk4time_get(dptr);
+ return 1;
+#endif
+ } else {
+ return 0;
+ }
+}
+
+
+
+int
+dk4clocktime_compare(const dk4_clock_time_t *l, const dk4_clock_time_t *r)
+{
+ int back = 0;
+ if (NULL != l) {
+ if (NULL != r) {
+#if DK4_ON_WINDOWS && (DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT)
+ if (l->wYear > r->wYear) {
+ back = 1;
+ } else {
+ if (l->wYear < r->wYear) {
+ back = -1;
+ }
+ }
+ if (0 == back) {
+ if (l->wMonth > r->wMonth) {
+ back = 1;
+ } else {
+ if (l->wMonth < r->wMonth) {
+ back = -1;
+ }
+ }
+ }
+ if (0 == back) {
+ if (l->wDay > r->wDay) {
+ back = 1;
+ } else {
+ if (l->wDay < r->wDay) {
+ back = -1;
+ }
+ }
+ }
+ if (0 == back) {
+ if (l->wHour > r->wHour) {
+ back = 1;
+ } else {
+ if (l->wHour < r->wHour) {
+ back = -1;
+ }
+ }
+ }
+ if (0 == back) {
+ if (l->wMinute > r->wMinute) {
+ back = 1;
+ } else {
+ if (l->wMinute < r->wMinute) {
+ back = -1;
+ }
+ }
+ }
+ if (0 == back) {
+ if (l->wSecond > r->wSecond) {
+ back = 1;
+ } else {
+ if (l->wSecond < r->wSecond) {
+ back = -1;
+ }
+ }
+ }
+#else
+ if (*l > *r) {
+ back = 1;
+ } else {
+ if (*l < *r) {
+ back = -1;
+ }
+ }
+#endif
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != r) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Convert timestamp to text ``yyyy-mm-dd hh:mm:ss''.
+ @param dptr Result buffer address.
+ @param dsz Result buffer size (number of dkChar).
+ @param clt Timestamp to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4clocktime_to_text(
+ dkChar *dptr,
+ size_t dsz,
+ const dk4_clock_time_t *clt,
+ dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS && (DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT)
+ back = dk4time_to_text(
+ dptr, dsz, DK4_TIMEFORMAT_DATE_TIME,
+ clt->wYear, clt->wMonth, clt->wDay, clt->wHour, clt->wMinute, clt->wSecond,
+ erp
+ );
+#else
+#if DK4_CHAR_SIZE > 1
+ char buf[32];
+ int back = 0;
+ if (0 != dk4time_as_text_c8(buf, sizeof(buf), clt, erp)) {
+ back = dk4recode_char_to_dk(dptr, dsz, buf, erp);
+ }
+ return back;
+#else
+ return (dk4time_as_text(dptr, dsz, clt, erp));
+#endif
+#endif
+}
+
diff --git a/support/dktools/dk4ctime.ctr b/support/dktools/dk4ctime.ctr
new file mode 100644
index 0000000000..6ea7135296
--- /dev/null
+++ b/support/dktools/dk4ctime.ctr
@@ -0,0 +1,289 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve current timestamp (time as visible on the clock),
+ compare timestamps, convert to text.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_ON_WINDOWS && (DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT)
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+#if DK4_TIME_WITH_SYS_TIME
+#ifndef SYS_TIME_H_INCLUDED
+#include <sys/time.h>
+#define SYS_TIME_H_INCLUDED 1
+#endif
+#ifndef TIME_H_INCLUDED
+#include <time.h>
+#define TIME_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_TIME_H
+#ifndef TIME_H_INCLUDED
+#include <time.h>
+#define TIME_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_SYS_TIME_H
+#ifndef SYS_TIME_H_INCLUDED
+#include <sys/time.h>
+#define SYS_TIME_H_INCLUDED 1
+#endif
+#endif
+#endif
+#endif
+#ifndef DK4TIME_H_INCLUDED
+#include "dk4time.h"
+#endif
+#endif
+
+#if DK4_ON_WINDOWS && (DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT)
+/** Time as shown on the clock.
+*/
+typedef SYSTEMTIME dk4_clock_time_t;
+#else
+/** Time as shown on the clock.
+*/
+typedef dk4_time_t dk4_clock_time_t;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve current date and time.
+ CRT on Windows: Optional.
+ @param dptr Result buffer.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4clocktime_get(dk4_clock_time_t *dptr);
+
+/** Compare two timestamps.
+ CRT on Windows: Optional.
+ @param l Left timestamp.
+ @param r Right timestamp.
+ @return 1 if l>r, 0 if l=r, -1 if l<r.
+*/
+int
+dk4clocktime_compare(const dk4_clock_time_t *l, const dk4_clock_time_t *r);
+
+/** Convert timestamp to text ``yyyy-mm-dd hh:mm:ss''.
+ CRT on Windows: Optional.
+ @param dptr Result buffer address.
+ @param dsz Result buffer size (number of dkChar).
+ @param clt Timestamp to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or dsz is 0,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occures in a size calculation,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the buffer is too small.
+*/
+int
+dk4clocktime_to_text(
+ dkChar *dptr,
+ size_t dsz,
+ const dk4_clock_time_t *clt,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4conf.h"
+
+#include "dk4types.h"
+
+#include "dk4ctime.h"
+
+#ifndef DK4REC22_H_INCLUDED
+#include "dk4rec22.h"
+#endif
+
+#ifndef DK4TIME_H_INCLUDED
+#include "dk4time.h"
+#endif
+
+#ifndef DK4TIMEDK_H_INCLUDED
+#include "dk4timedk.h"
+#endif
+
+#ifndef DK4TIME08_H_INCLUDED
+#include "dk4time08.h"
+#endif
+
+
+
+int
+dk4clocktime_get(dk4_clock_time_t *dptr)
+{
+ if (NULL != dptr) {
+#if DK4_ON_WINDOWS && (DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT)
+ GetLocalTime(dptr);
+ return 1;
+#else
+ dk4time_get(dptr);
+ return 1;
+#endif
+ } else {
+ return 0;
+ }
+}
+
+
+
+int
+dk4clocktime_compare(const dk4_clock_time_t *l, const dk4_clock_time_t *r)
+{
+ int back = 0;
+ if (NULL != l) {
+ if (NULL != r) {
+#if DK4_ON_WINDOWS && (DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT)
+ if (l->wYear > r->wYear) {
+ back = 1;
+ } else {
+ if (l->wYear < r->wYear) {
+ back = -1;
+ }
+ }
+ if (0 == back) {
+ if (l->wMonth > r->wMonth) {
+ back = 1;
+ } else {
+ if (l->wMonth < r->wMonth) {
+ back = -1;
+ }
+ }
+ }
+ if (0 == back) {
+ if (l->wDay > r->wDay) {
+ back = 1;
+ } else {
+ if (l->wDay < r->wDay) {
+ back = -1;
+ }
+ }
+ }
+ if (0 == back) {
+ if (l->wHour > r->wHour) {
+ back = 1;
+ } else {
+ if (l->wHour < r->wHour) {
+ back = -1;
+ }
+ }
+ }
+ if (0 == back) {
+ if (l->wMinute > r->wMinute) {
+ back = 1;
+ } else {
+ if (l->wMinute < r->wMinute) {
+ back = -1;
+ }
+ }
+ }
+ if (0 == back) {
+ if (l->wSecond > r->wSecond) {
+ back = 1;
+ } else {
+ if (l->wSecond < r->wSecond) {
+ back = -1;
+ }
+ }
+ }
+#else
+ if (*l > *r) {
+ back = 1;
+ } else {
+ if (*l < *r) {
+ back = -1;
+ }
+ }
+#endif
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != r) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Convert timestamp to text ``yyyy-mm-dd hh:mm:ss''.
+ @param dptr Result buffer address.
+ @param dsz Result buffer size (number of dkChar).
+ @param clt Timestamp to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4clocktime_to_text(
+ dkChar *dptr,
+ size_t dsz,
+ const dk4_clock_time_t *clt,
+ dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS && (DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT)
+ back = dk4time_to_text(
+ dptr, dsz, DK4_TIMEFORMAT_DATE_TIME,
+ clt->wYear, clt->wMonth, clt->wDay, clt->wHour, clt->wMinute, clt->wSecond,
+ erp
+ );
+#else
+#if DK4_CHAR_SIZE > 1
+ char buf[32];
+ int back = 0;
+ if (0 != dk4time_as_text_c8(buf, sizeof(buf), clt, erp)) {
+ back = dk4recode_char_to_dk(dptr, dsz, buf, erp);
+ }
+ return back;
+#else
+ return (dk4time_as_text(dptr, dsz, clt, erp));
+#endif
+#endif
+}
+
diff --git a/support/dktools/dk4ctime.h b/support/dktools/dk4ctime.h
new file mode 100644
index 0000000000..a31167b242
--- /dev/null
+++ b/support/dktools/dk4ctime.h
@@ -0,0 +1,163 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4ctime.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4CTIME_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4CTIME_H_INCLUDED 1
+
+
+#line 10 "dk4ctime.ctr"
+
+/** @file
+ Retrieve current timestamp (time as visible on the clock),
+ compare timestamps, convert to text.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_ON_WINDOWS && (DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT)
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+#if DK4_TIME_WITH_SYS_TIME
+#ifndef SYS_TIME_H_INCLUDED
+#include <sys/time.h>
+#define SYS_TIME_H_INCLUDED 1
+#endif
+#ifndef TIME_H_INCLUDED
+#include <time.h>
+#define TIME_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_TIME_H
+#ifndef TIME_H_INCLUDED
+#include <time.h>
+#define TIME_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_SYS_TIME_H
+#ifndef SYS_TIME_H_INCLUDED
+#include <sys/time.h>
+#define SYS_TIME_H_INCLUDED 1
+#endif
+#endif
+#endif
+#endif
+#ifndef DK4TIME_H_INCLUDED
+#include "dk4time.h"
+#endif
+#endif
+
+#if DK4_ON_WINDOWS && (DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT)
+/** Time as shown on the clock.
+*/
+typedef SYSTEMTIME dk4_clock_time_t;
+#else
+/** Time as shown on the clock.
+*/
+typedef dk4_time_t dk4_clock_time_t;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve current date and time.
+ CRT on Windows: Optional.
+ @param dptr Result buffer.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4clocktime_get(dk4_clock_time_t *dptr);
+
+/** Compare two timestamps.
+ CRT on Windows: Optional.
+ @param l Left timestamp.
+ @param r Right timestamp.
+ @return 1 if l>r, 0 if l=r, -1 if l<r.
+*/
+int
+dk4clocktime_compare(const dk4_clock_time_t *l, const dk4_clock_time_t *r);
+
+/** Convert timestamp to text ``yyyy-mm-dd hh:mm:ss''.
+ CRT on Windows: Optional.
+ @param dptr Result buffer address.
+ @param dsz Result buffer size (number of dkChar).
+ @param clt Timestamp to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or dsz is 0,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occures in a size calculation,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the buffer is too small.
+*/
+int
+dk4clocktime_to_text(
+ dkChar *dptr,
+ size_t dsz,
+ const dk4_clock_time_t *clt,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4dbi.c b/support/dktools/dk4dbi.c
new file mode 100644
index 0000000000..f7c3a349ad
--- /dev/null
+++ b/support/dktools/dk4dbi.c
@@ -0,0 +1,1983 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4dbi.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4dbi.c The dk4dbi module.
+*/
+
+
+#line 556 "dk4dbi.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_STAT_H
+#ifndef SYS_STAT_H_INCLUDED
+#include <sys/stat.h>
+#define SYS_STAT_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4dbi.h"
+#include "dk4mem.h"
+#include "dk4memrs.h"
+#include "dk4strd.h"
+#include "dk4fopd.h"
+#include "dk4numco.h"
+#include "dk4isadm.h"
+#include "dk4fopt.h"
+#include "dk4mpl.h"
+#include "dk4delfile.h"
+#include "dk4stat.h"
+#include "dk4statd.h"
+
+
+
+
+
+#line 589 "dk4dbi.ctr"
+
+
+
+/** One storage entry.
+*/
+typedef struct {
+ void *kd; /**< Key data. */
+ void *vd; /**< Value data. */
+ size_t ks; /**< Key size. */
+ size_t vs; /**< Value size. */
+} dk4_dbi_datum_t;
+
+
+
+/** Backend type names.
+*/
+static const dkChar *dk4dbi_type_names[] = {
+/* 0 */
+dkT("mem"),
+
+/* 1 */
+dkT("bdb"),
+
+/* 2 */
+dkT("ndbm"),
+
+NULL
+
+
+#line 611 "dk4dbi.ctr"
+};
+
+
+
+/** File name suffixes for NDBM files.
+*/
+static const dkChar *dk4dbi_ndbm_suffixes[] = {
+dkT(".dir"), dkT(".pag")
+};
+
+
+
+/** Maximum size of key or value.
+*/
+static const unsigned long dk4dbi_max_size = 4294967295UL;
+
+
+
+/** Delete one record from an in-memory database,
+ release resources.
+ @param ptr Record to delete
+ @param options The database options.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4dbi_datum_delete(dk4_dbi_datum_t *ptr, int options)
+{
+ int back = 0;
+
+
+#line 641 "dk4dbi.ctr"
+ if (NULL != ptr) {
+ back = 1;
+ if (0 != (DK4_DB_OPT_RESET_KEY & options)) {
+ if ((NULL != ptr->kd) && ((size_t)0UL < ptr->ks)) {
+
+
+#line 646 "dk4dbi.ctr"
+ if (0 == dk4mem_reset_secure(ptr->kd, ptr->ks, NULL)) {
+ back = 0;
+ }
+ }
+ }
+ if (0 != (DK4_DB_OPT_RESET_VALUE & options)) {
+ if ((NULL != ptr->vd) && ((size_t)0UL < ptr->vs)) {
+
+
+#line 654 "dk4dbi.ctr"
+ if (0 == dk4mem_reset_secure(ptr->vd, ptr->vs, NULL)) {
+ back = 0;
+ }
+ }
+ }
+ dk4mem_release(ptr->kd);
+ dk4mem_release(ptr->vd);
+ ptr->ks = ptr->vs = (size_t)0UL;
+ dk4mem_free(ptr);
+ }
+
+
+#line 665 "dk4dbi.ctr"
+ return back;
+}
+
+
+
+/** Allocate memory for a new record.
+ @param ks
+ @param vs
+ @param erp
+ @return Pointer to new record structure on success, NULL on error.
+
+ Error codes:
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available.
+*/
+static
+dk4_dbi_datum_t *
+dk4dbi_datum_new(
+ size_t ks,
+ size_t vs,
+ dk4_er_t *erp
+)
+{
+ dk4_dbi_datum_t *back = NULL;
+
+
+#line 691 "dk4dbi.ctr"
+ back = dk4mem_new(dk4_dbi_datum_t,1,erp);
+ if (NULL != back) {
+ back->kd = back->vd = NULL;
+ back->ks = back->vs = (size_t)0UL;
+ back->kd = dk4mem_new(char,ks,erp);
+ back->vd = dk4mem_new(char,vs,erp);
+ if ((NULL != back->kd) && (NULL != back->vd)) {
+ back->ks = ks; back->vs = vs;
+ } else {
+ dk4mem_release(back->kd);
+ dk4mem_release(back->vd);
+ dk4mem_free(back);
+ back = NULL;
+ }
+ }
+
+#line 706 "dk4dbi.ctr"
+ return back;
+}
+
+
+
+
+/** Write in-memory database contents back to file.
+ @param db Database to save.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_SYNTAX<br>
+ if the database file name does not refer to a regular file,
+ - DK4_E_SEC_CHECK<br>
+ with failed check id in iDetails1 if access is denied by additional
+ security checks,
+ - DK4_E_OPEN_WRITE_FAILED<br>
+ with errno value in iDetails1 if fopen() or fwrite() failed,
+ - DK4_E_CLOSE_FAILED<br>
+ with errno value in iDetails1 if fclose() failed,
+ - DK4_E_WRITE_FAILD<br>
+ if fwrite() failed.
+*/
+static
+int
+dk4dbi_mem_to_file(
+ dk4_dbi_t *db,
+ dk4_er_t *erp
+)
+{
+ FILE *fipo = NULL; /* Write text ile */
+ dk4_dbi_datum_t *rp = NULL; /* Current record */
+ unsigned char uc[8]; /* Sizes byte array */
+ size_t nbw = 0; /* Number of bytes */
+ int tests = DK4_FOPEN_SC_USER; /* Security checks */
+ int back = 0;
+
+
+
+#line 745 "dk4dbi.ctr"
+ if (dk4isadmin()) { tests = DK4_FOPEN_SC_PRIVILEGED; }
+ fipo = dk4fopen(db->fn, dkT("wb"), tests, erp);
+ if (NULL != fipo) {
+
+#line 748 "dk4dbi.ctr"
+ back = 1;
+ dk4sto_it_reset((db->dt).mem.i);
+ do {
+ rp = (dk4_dbi_datum_t *)dk4sto_it_next((db->dt).mem.i);
+ if (NULL != rp) {
+
+#line 753 "dk4dbi.ctr"
+ uc[0] = (unsigned char)(((unsigned long)(rp->ks) >> 24) & 0x000000FFUL);
+ uc[1] = (unsigned char)(((unsigned long)(rp->ks) >> 16) & 0x000000FFUL);
+ uc[2] = (unsigned char)(((unsigned long)(rp->ks) >> 8) & 0x000000FFUL);
+ uc[3] = (unsigned char)(((unsigned long)(rp->ks) ) & 0x000000FFUL);
+ uc[4] = (unsigned char)(((unsigned long)(rp->vs) >> 24) & 0x000000FFUL);
+ uc[5] = (unsigned char)(((unsigned long)(rp->vs) >> 16) & 0x000000FFUL);
+ uc[6] = (unsigned char)(((unsigned long)(rp->vs) >> 8) & 0x000000FFUL);
+ uc[7] = (unsigned char)(((unsigned long)(rp->vs) ) & 0x000000FFUL);
+ nbw = fwrite(uc, 1, 8, fipo);
+ if (8 == nbw) {
+
+#line 763 "dk4dbi.ctr"
+ nbw = fwrite(rp->kd, 1, rp->ks, fipo);
+ if (rp->ks == nbw) {
+
+#line 765 "dk4dbi.ctr"
+ nbw = fwrite(rp->vd, 1, rp->vs, fipo);
+ if (rp->vs == nbw) {
+
+#line 767 "dk4dbi.ctr"
+ } else {
+ back = 0;
+
+#line 769 "dk4dbi.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED);
+ }
+ } else {
+
+#line 772 "dk4dbi.ctr"
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED);
+ }
+ } else {
+
+#line 776 "dk4dbi.ctr"
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED);
+ }
+ }
+ } while (NULL != rp);
+ if (0 != fclose(fipo)) {
+
+#line 782 "dk4dbi.ctr"
+ back = 0;
+ dk4error_set_idetails(erp, DK4_E_CLOSE_FAILED, errno);
+ }
+ } else {
+
+#line 786 "dk4dbi.ctr"
+ }
+ if (0 != back) {
+ db->uc = 0;
+ }
+
+
+#line 791 "dk4dbi.ctr"
+ return back;
+}
+
+
+
+/** Read in-memory database contents back from file.
+ @param db Database to restore.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_SYNTAX<br>
+ if
+ - the database file name does not refer to a regular file
+ - or the file contents is not an in-memory database
+ - or key/value sizes in the file are in conflict with size restrictions,
+ - DK4_E_SEC_CHECK<br>
+ with failed check id in iDetails1 if access is denied by additional
+ security checks,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available,
+ - DK4_E_OPEN_READ_FAILED with errno value in iDetails1 if fopen()
+ or fread() failed.
+*/
+static
+int
+dk4dbi_mem_from_file(
+ dk4_dbi_t *db,
+ dk4_er_t *erp
+)
+{
+ dk4_stat_t stb; /* File stat buffer */
+ FILE *fipo = NULL; /* Input file */
+ dk4_dbi_datum_t *rp = NULL; /* Current record to process */
+ unsigned char uc[8]; /* Buffer to read sizes */
+ size_t nbr = 0; /* Number of bytes read */
+ size_t ks = 0; /* Key size */
+ size_t vs = 0; /* Value size */
+ unsigned long ul1 = 0UL; /* Key size */
+ unsigned long ul2 = 0UL; /* Value size */
+ int back = 0; /* Result */
+ int cc = 1; /* Flag: Can continue */
+
+
+#line 835 "dk4dbi.ctr"
+ fipo = dk4fopen(db->fn, dkT("rb"), 0, erp);
+ if (NULL != fipo) {
+ back = 1;
+ do {
+ nbr = fread(uc, 1, 8, fipo);
+ if (8 == nbr) {
+
+#line 841 "dk4dbi.ctr"
+ ul1 = ((((unsigned long)(uc[0])) << 24) & 0xFF000000UL)
+ | ((((unsigned long)(uc[1])) << 16) & 0x00FF0000UL)
+ | ((((unsigned long)(uc[2])) << 8) & 0x0000FF00UL)
+ | ((((unsigned long)(uc[3])) ) & 0x000000FFUL);
+ ul2 = ((((unsigned long)(uc[4])) << 24) & 0xFF000000UL)
+ | ((((unsigned long)(uc[5])) << 16) & 0x00FF0000UL)
+ | ((((unsigned long)(uc[6])) << 8) & 0x0000FF00UL)
+ | ((((unsigned long)(uc[7])) ) & 0x000000FFUL);
+ if ((dk4_um_t)(SIZE_MAX) >= (dk4_um_t)ul1) {
+ if ((dk4_um_t)(SIZE_MAX) >= (dk4_um_t)ul2) {
+ ks = (size_t)ul1; vs = (size_t)ul2;
+ if (
+ (((size_t)0UL == db->km) || (db->km >= ks))
+ && (((size_t)0UL == db->vm) || (db->vm >= vs))
+ && ((size_t)0UL < ks) && ((size_t)0UL < vs)
+ )
+ {
+ rp = dk4dbi_datum_new(ks, vs, erp);
+ if (NULL != rp) {
+
+#line 860 "dk4dbi.ctr"
+ nbr = fread(rp->kd, 1, rp->ks, fipo);
+ if (nbr == rp->ks) {
+ nbr = fread(rp->vd, 1, rp->vs, fipo);
+ if (nbr == rp->vs) {
+ if (0 == dk4sto_add((db->dt).mem.s, rp, erp)) {
+ cc = 0;
+
+#line 866 "dk4dbi.ctr"
+ back = 0;
+ dk4dbi_datum_delete(rp, 0);
+ }
+ } else {
+
+#line 870 "dk4dbi.ctr"
+ cc = 0;
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ dk4dbi_datum_delete(rp, 0);
+ }
+ } else {
+
+#line 876 "dk4dbi.ctr"
+ cc = 0;
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ dk4dbi_datum_delete(rp, 0);
+ }
+ } else {
+
+#line 882 "dk4dbi.ctr"
+ cc = 0;
+ back = 0;
+ }
+ }
+ else
+ {
+
+#line 888 "dk4dbi.ctr"
+ cc = 0;
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+
+#line 893 "dk4dbi.ctr"
+ cc = 0;
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+
+#line 898 "dk4dbi.ctr"
+ cc = 0;
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+
+#line 903 "dk4dbi.ctr"
+ cc = 0;
+ if (0 != nbr) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ }
+ } while (0 != cc);
+ (void)fclose(fipo);
+ } else {
+
+#line 912 "dk4dbi.ctr"
+ if (0 == dk4stat(&stb, db->fn, NULL)) {
+ back = 1;
+
+#line 914 "dk4dbi.ctr"
+ }
+ }
+
+
+#line 917 "dk4dbi.ctr"
+ return back;
+}
+
+
+
+/** Compare two entries.
+ @param l Left record.
+ @param r Right record.
+ @param cr Comparison criteria, ignored.
+ @return 1 if l>r, 0 if l==r, -1 if l<r.
+*/
+static
+int
+dk4dbi_datum_compare(const void *l, const void *r, int cr)
+{
+ dk4_dbi_datum_t *pl; /* Left pointer */
+ dk4_dbi_datum_t *pr; /* Right pointer */
+ int back = 0;
+
+
+#line 936 "dk4dbi.ctr"
+ if (NULL != l) {
+ if (NULL != r) {
+ pl = (dk4_dbi_datum_t *)l;
+ pr = (dk4_dbi_datum_t *)r;
+ if (NULL != pl->kd) {
+ if (NULL != pr->kd) {
+ if (pl->ks > pr->ks) {
+ back = 1;
+ } else {
+ if (pl->ks < pr->ks) {
+ back = -1;
+ } else {
+ if (0 < pl->ks) {
+ back = DK4_MEMCMP(pl->kd, pr->kd, pl->ks);
+ if (-1 > back) back = -1;
+ if ( 1 < back) back = 1;
+ }
+ }
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != pr->kd) { back = -1; }
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != r) { back = -1; }
+ }
+
+
+#line 968 "dk4dbi.ctr"
+ return back;
+}
+
+
+
+/** Delete base database structure, release resources.
+ @param ptr Database structure to release.
+*/
+static
+void
+dk4dbi_delete_base(dk4_dbi_t *ptr)
+{
+
+
+#line 981 "dk4dbi.ctr"
+ if (NULL != ptr) {
+ dk4mem_release(ptr->fn);
+ dk4mem_free(ptr);
+ }
+
+
+#line 986 "dk4dbi.ctr"
+}
+
+
+
+/** Allocate memory for a database.
+ @param fn File name.
+ @param tp Backend type.
+ @param wa Flag: Write access required.
+ @param erp Error report, may be NULL.
+ @return Pointer to memory on success, NULL on error.
+
+ Error codes:
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow when calculating size,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available.
+*/
+static
+dk4_dbi_t *
+dk4dbi_new_base(
+ const dkChar *fn,
+ int tp,
+ int wa,
+ size_t km,
+ size_t vm,
+ dk4_er_t *erp
+)
+{
+ dk4_dbi_t *back = NULL;
+
+
+#line 1017 "dk4dbi.ctr"
+ back = dk4mem_new(dk4_dbi_t,1,erp);
+ if (NULL != back) {
+ back->tp = tp;
+ back->wa = wa;
+ back->op = 0;
+ back->uc = 0;
+ back->km = km;
+ back->vm = vm;
+ switch (tp) {
+ case DK4_DB_BE_MEMORY : {
+ (back->dt).mem.s = NULL;
+ (back->dt).mem.i = NULL;
+ } break;
+ case DK4_DB_BE_BDB : {
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+ (back->dt).bdb.db = NULL;
+#endif
+ } break;
+ case DK4_DB_BE_NDBM : {
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+ (back->dt).ndbm.dbm = NULL;
+#endif
+ } break;
+ }
+ back->fn = dk4str_dup(fn, erp);
+ if (NULL == back->fn) {
+
+#line 1043 "dk4dbi.ctr"
+ dk4mem_free(back);
+ back = NULL;
+ }
+ }
+
+
+#line 1048 "dk4dbi.ctr"
+ return back;
+}
+
+
+
+/** Close database, release resources.
+ NOTE: Only release in-memory specific things, the
+ dk4dbi_close() function calls dk4dbi_delete_base()
+ to release the base components.
+ @param db Database to close.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_SYNTAX<br>
+ if the database file name does not refer to a regular file,
+ - DK4_E_SEC_CHECK<br>
+ with failed check id in iDetails1 if access is denied by additional
+ security checks,
+ - DK4_E_OPEN_WRITE_FAILED<br>
+ with errno value in iDetails1 if fopen() or fwrite() failed,
+ - DK4_E_CLOSE_FAILED<br>
+ with errno value in iDetails1 if fclose() failed,
+ - DK4_E_WRITE_FAILD<br>
+ if fwrite() failed.
+*/
+static
+int
+dk4dbi_close_mem(
+ dk4_dbi_t *db,
+ dk4_er_t *erp
+)
+{
+ dk4_dbi_datum_t *rp; /* Current record */
+ int back = 1;
+
+
+#line 1084 "dk4dbi.ctr"
+ if ((NULL != (db->dt).mem.s) && (NULL != (db->dt).mem.i)) {
+ /*
+ Write records to file if there are unsaved changes.
+ */
+
+
+#line 1089 "dk4dbi.ctr"
+ if ((0 != db->wa) && (0 != db->uc)) {
+ if (0 == dk4dbi_mem_to_file(db, erp)) {
+ back = 0;
+ }
+ }
+ /*
+ Release memory used for the records.
+ */
+ dk4sto_it_reset((db->dt).mem.i);
+ do {
+ rp = (dk4_dbi_datum_t *)dk4sto_it_next((db->dt).mem.i);
+ if (NULL != rp) {
+ if (0 == dk4dbi_datum_delete(rp, db->op)) {
+ back = 0;
+ }
+ }
+ } while (NULL != rp);
+ }
+ if (NULL != (db->dt).mem.i) {
+ dk4sto_it_close((db->dt).mem.i);
+ }
+ if (NULL != (db->dt).mem.s) {
+ dk4sto_close((db->dt).mem.s);
+ }
+
+#line 1113 "dk4dbi.ctr"
+ return back;
+}
+
+
+
+/** Open in-memory database.
+ @param fn File name.
+ @param wa Flag: Write access required.
+ @param tr Flag: Truncate existing database.
+ @param km Maximum key size.
+ @param vm Maximum value size.
+ @param erp Error report, may be NULL.
+ @return Pointer to new database structure on success, NULL on error.
+
+ Error codes:
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow when calculating size,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available,
+ - DK4_E_SYNTAX<br>
+ if
+ - the database file name does not refer to a regular file
+ - or the file contents is not an in-memory database
+ - or key/value sizes in the file are in conflict with size restrictions,
+ - DK4_E_SEC_CHECK<br>
+ with failed check id in iDetails1 if access is denied by additional
+ security checks,
+ - DK4_E_OPEN_READ_FAILED with errno value in iDetails1 if fopen()
+ or fread() failed,
+ - DK4_E_OPEN_WRITE_FAILED<br>
+ with errno value in iDetails1 if fopen() or fwrite() failed,
+ - DK4_E_CLOSE_FAILED<br>
+ with errno value in iDetails1 if fclose() failed.
+*/
+static
+dk4_dbi_t *
+dk4dbi_open_mem(
+ const dkChar *fn,
+ int wa,
+ int tr,
+ size_t km,
+ size_t vm,
+ dk4_er_t *erp
+)
+{
+ dk4_dbi_t *back = NULL;
+
+
+#line 1161 "dk4dbi.ctr"
+ if (0 != tr) {
+ (void)dk4delete_file(fn, NULL);
+ }
+ back = dk4dbi_new_base(fn, DK4_DB_BE_MEMORY, wa, km, vm, erp);
+ if (NULL != back) {
+ (back->dt).mem.s = NULL;
+ (back->dt).mem.i = NULL;
+ (back->dt).mem.s = dk4sto_open(erp);
+ if (NULL != (back->dt).mem.s) {
+ dk4sto_set_comp((back->dt).mem.s, dk4dbi_datum_compare, 0);
+ (back->dt).mem.i = dk4sto_it_open((back->dt).mem.s, erp);
+ }
+ if ((NULL != (back->dt).mem.s) && (NULL != (back->dt).mem.i)) {
+ if (0 == tr) { /* Do not truncate */
+ if (0 == dk4dbi_mem_from_file(back, erp)) {
+ (void)dk4dbi_close_mem(back, NULL);
+ back = NULL;
+ }
+ } else { /* Truncate */
+ if (0 == dk4dbi_mem_to_file(back, erp)) {
+ (void)dk4dbi_close_mem(back, NULL);
+ back = NULL;
+ }
+ }
+ } else {
+ (void)dk4dbi_close_mem(back, NULL);
+ back = NULL;
+ }
+ }
+
+
+#line 1191 "dk4dbi.ctr"
+ return back;
+}
+
+
+
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+
+
+/** Close database, release resources.
+ NOTE: Only release in-memory specific things, the
+ dk4dbi_close() function calls dk4dbi_delete_base()
+ to release the base components.
+ @param db Database to close.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_SYNTAX<br>
+ if the database file name does not refer to a regular file,
+ - DK4_E_SEC_CHECK<br>
+ with failed check id in iDetails1 if access is denied by additional
+ security checks,
+ - DK4_E_OPEN_WRITE_FAILED<br>
+ with errno value in iDetails1 if fopen() or fwrite() failed,
+ - DK4_E_CLOSE_FAILED<br>
+ with errno value in iDetails1 if fclose() failed,
+ - DK4_E_WRITE_FAILD<br>
+ if fwrite() failed.
+*/
+static
+int
+dk4dbi_close_bdb(
+ dk4_dbi_t *db,
+ dk4_er_t *erp
+)
+{
+ int back = 1;
+ if (NULL != (db->dt).bdb.db) {
+ if ((0 != db->wa) && (0 != db->uc)) {
+ if (0 != ((db->dt).bdb.db)->sync((db->dt).bdb.db, 0)) {
+ back = 0;
+ }
+ }
+ ((db->dt).bdb.db)->close((db->dt).bdb.db, 0);
+ (db->dt).bdb.db = NULL;
+ }
+ return back;
+}
+
+
+
+/** Open BDB database.
+ @param fn File name.
+ @param wa Flag: Write access required.
+ @param tr Flag: Truncate existing database.
+ @param km Maximum key size.
+ @param vm Maximum value size.
+ @param erp Error report, may be NULL.
+ @return Pointer to new database structure on success, NULL on error.
+
+ Error codes:
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow when calculating size,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available,
+ - DK4_E_OPEN_WRITE_FAILED<br>
+ if the database can not be opened for writing,
+ - DK4_E_OPEN_READ_FAILED<br>
+ if the database can not be opened or reading,
+ - DK4_E_NOT_SUPPORTED<br>
+ when attempting to provide a wchar_t file name on
+ non-Windows systems.
+*/
+static
+dk4_dbi_t *
+dk4dbi_open_bdb(
+ const dkChar *fn,
+ int wa,
+ int tr,
+ size_t km,
+ size_t vm,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+#if DK4_ON_WINDOWS
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return NULL;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return NULL;
+#endif
+#else
+ dk4_dbi_t *back = NULL;
+ int res = 0;
+ int flags = 0;
+
+
+#line 1289 "dk4dbi.ctr"
+ back = dk4dbi_new_base(fn, DK4_DB_BE_BDB, wa, km, vm, erp);
+ if (NULL != back) {
+ if (0 != tr) {
+ (void)dk4delete_file(fn, NULL);
+ }
+ res = db_create(&((back->dt).bdb.db), NULL, 0);
+ if (0 == res) {
+ ((back->dt).bdb.db)->set_errfile((back->dt).bdb.db, NULL);
+ flags = ((0 != wa)
+ ? ((0 != tr) ? ((DB_CREATE) || (DB_TRUNCATE)) : (DB_CREATE))
+ : (DB_RDONLY));
+ res = ((back->dt).bdb.db)->open(
+ (back->dt).bdb.db, NULL, back->fn, NULL, DB_BTREE, flags, 0600
+ );
+ if (0 != res) {
+ ((back->dt).bdb.db)->close((back->dt).bdb.db, 0);
+ (back->dt).bdb.db = NULL;
+ dk4dbi_delete_base(back);
+ back = NULL;
+ dk4error_set_simple_error_code(
+ erp,
+ ((0 != wa) ? (DK4_E_OPEN_WRITE_FAILED) : (DK4_E_OPEN_READ_FAILED))
+ );
+ }
+ } else {
+ (back->dt).bdb.db = NULL;
+ dk4dbi_delete_base(back);
+ back = NULL;
+ dk4error_set_simple_error_code(
+ erp,
+ ((0 != wa) ? (DK4_E_OPEN_WRITE_FAILED) : (DK4_E_OPEN_READ_FAILED))
+ );
+ }
+ }
+
+
+#line 1324 "dk4dbi.ctr"
+ return back;
+#endif
+}
+
+#endif
+/* if DK4_HAVE_DB_H */
+
+
+
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+
+
+
+/** Close database, release resources.
+ NOTE: Only release in-memory specific things, the
+ dk4dbi_close() function calls dk4dbi_delete_base()
+ to release the base components.
+ @param db Database to close.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_SYNTAX<br>
+ if the database file name does not refer to a regular file,
+ - DK4_E_SEC_CHECK<br>
+ with failed check id in iDetails1 if access is denied by additional
+ security checks,
+ - DK4_E_OPEN_WRITE_FAILED<br>
+ with errno value in iDetails1 if fopen() or fwrite() failed,
+ - DK4_E_CLOSE_FAILED<br>
+ with errno value in iDetails1 if fclose() failed,
+ - DK4_E_WRITE_FAILD<br>
+ if fwrite() failed.
+*/
+static
+int
+dk4dbi_close_ndbm(
+ dk4_dbi_t *db,
+ dk4_er_t *erp
+)
+{
+ int back = 1;
+ if (NULL != (db->dt).ndbm.dbm) {
+ dbm_close((db->dt).ndbm.dbm);
+ (db->dt).ndbm.dbm = NULL;
+ }
+ return back;
+}
+
+
+
+static
+void
+dk4dbi_truncate_ndbm(const dkChar *fn)
+{
+ dkChar buf[DK4_MAX_PATH];
+ const size_t szbuf = DK4_SIZEOF(buf,dkChar);
+
+ if (0 != dk4str_cpy_s(buf, szbuf, fn, NULL)) {
+ if (0 != dk4str_cat_s(buf, szbuf, dk4dbi_ndbm_suffixes[0], NULL)) {
+ (void)dk4delete_file(buf, NULL);
+ }
+ }
+ if (0 != dk4str_cpy_s(buf, szbuf, fn, NULL)) {
+ if (0 != dk4str_cat_s(buf, szbuf, dk4dbi_ndbm_suffixes[1], NULL)) {
+ (void)dk4delete_file(buf, NULL);
+ }
+ }
+}
+
+
+
+/** Open NDBM database.
+ @param fn File name.
+ @param wa Flag: Write access required.
+ @param tr Flag: Truncate existing database.
+ @param km Maximum key size.
+ @param vm Maximum value size.
+ @param erp Error report, may be NULL.
+ @return Pointer to new database structure on success, NULL on error.
+*/
+static
+dk4_dbi_t *
+dk4dbi_open_ndbm(
+ const dkChar *fn,
+ int wa,
+ int tr,
+ size_t km,
+ size_t vm,
+ dk4_er_t *erp
+)
+{
+ dk4_dbi_t *back = NULL;
+ int flags = 0; /* Flags for opening the DB */
+
+
+
+#line 1420 "dk4dbi.ctr"
+
+ if (0 != tr) {
+ dk4dbi_truncate_ndbm(fn);
+ }
+ back = dk4dbi_new_base(fn, DK4_DB_BE_NDBM, wa, km, vm, erp);
+ if (NULL != back) {
+ flags = O_CREAT
+ | ((0 != wa)
+ ? ((0 != tr) ? (O_RDWR | O_TRUNC) : (O_RDWR))
+ : (O_RDONLY));
+ (back->dt).ndbm.dbm = dbm_open(fn, flags, 0600);
+ if (NULL == (back->dt).ndbm.dbm) {
+ dk4dbi_delete_base(back);
+ back = NULL;
+ dk4error_set_simple_error_code(
+ erp,
+ ((0 != wa) ? (DK4_E_OPEN_WRITE_FAILED) : (DK4_E_OPEN_READ_FAILED))
+ );
+ }
+ }
+
+
+#line 1441 "dk4dbi.ctr"
+ return back;
+}
+
+#endif
+/* if DK4_HAVE_NDBM_H */
+
+
+
+dk4_dbi_t *
+dk4dbi_open_with_type(
+ const dkChar *fn,
+ int tp,
+ int wa,
+ int tr,
+ size_t km,
+ size_t vm,
+ dk4_er_t *erp
+)
+{
+ dk4_dbi_t *back = NULL;
+
+
+#line 1462 "dk4dbi.ctr"
+ if (NULL != fn) {
+ switch (tp) {
+ case DK4_DB_BE_MEMORY : {
+ back = dk4dbi_open_mem(fn, wa, tr, km, vm, erp);
+ } break;
+ case DK4_DB_BE_BDB : {
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+ back = dk4dbi_open_bdb(fn, wa, tr, km, vm, erp);
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_DB_BE_NDBM : {
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+ back = dk4dbi_open_ndbm(fn, wa, tr, km, vm, erp);
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 1489 "dk4dbi.ctr"
+ return back;
+}
+
+
+
+dk4_dbi_t *
+dk4dbi_open(
+ const dkChar *fn,
+ int wa,
+ int tr,
+ size_t km,
+ size_t vm,
+ dk4_er_t *erp
+)
+{
+ dk4_dbi_t *back = NULL;
+ dkChar *mycopy = NULL; /* Private copy of fn */
+ dkChar *colon = NULL; /* First colon in mycopy */
+ const dkChar *fnp = NULL; /* File name pointer */
+ int tp = DK4_DB_BE_MEMORY ; /* Database type */
+
+
+
+#line 1511 "dk4dbi.ctr"
+ if (NULL != fn) {
+ mycopy = dk4str_dup(fn, erp);
+ if (NULL != mycopy) {
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+ tp = DK4_DB_BE_NDBM;
+#endif
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+ tp = DK4_DB_BE_BDB;
+#endif
+ fnp = fn;
+ colon = dk4str_chr(mycopy, dkT(':'));
+ if (NULL != colon) {
+ if (dkT(':') == colon[1]) {
+ fnp = &(colon[2]);
+ *colon = dkT('\0');
+ tp = dk4str_array_index(dk4dbi_type_names, mycopy, 0);
+ if (DK4_DB_BE_UNKNOWN == tp) {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ }
+ }
+ if (DK4_DB_BE_UNKNOWN != tp) {
+ back = dk4dbi_open_with_type(fnp, tp, wa, tr, km, vm, erp);
+ }
+ dk4mem_free(mycopy);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 1541 "dk4dbi.ctr"
+ return back;
+}
+
+
+
+const dkChar *
+dk4dbi_filename_part(const dkChar *filename)
+{
+ const dkChar *back = NULL;
+ if (NULL != filename) {
+ back = dk4str_chr(filename, dkT(':'));
+ if (NULL != back) {
+ back++;
+ if (dkT(':') == *back) {
+ back++;
+ } else {
+ back = filename;
+ }
+ } else {
+ back = filename;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4dbi_close(
+ dk4_dbi_t *db,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+
+
+#line 1576 "dk4dbi.ctr"
+ if (NULL != db) {
+ switch (db->tp) {
+ case DK4_DB_BE_MEMORY : {
+ back = dk4dbi_close_mem(db, erp);
+ } break;
+ case DK4_DB_BE_BDB : {
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+ back = dk4dbi_close_bdb(db, erp);
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_DB_BE_NDBM : {
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+ back = dk4dbi_close_ndbm(db, erp);
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ }
+ dk4dbi_delete_base(db);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 1601 "dk4dbi.ctr"
+ return back;
+}
+
+
+
+int
+dk4dbi_set_option(
+ dk4_dbi_t *db,
+ int opt,
+ int val
+)
+{
+ int back = 0;
+ if (NULL != db) {
+ switch (opt) {
+ case DK4_DB_OPT_RESET_KEY :
+ case DK4_DB_OPT_RESET_VALUE :
+ {
+ if (0 != val) {
+ db->op |= opt;
+ } else {
+ db->op &= (~(opt));
+ }
+ back = 1;
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4dbi_delete(
+ dk4_dbi_t *db,
+ const void *kp,
+ size_t ks,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+ DBT k; /* Key */
+#endif
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+ datum datk; /* Key */
+#endif
+ dk4_dbi_datum_t dat; /* Key for comparison */
+ dk4_dbi_datum_t *rp; /* Result found in db */
+
+
+
+#line 1652 "dk4dbi.ctr"
+ if ((NULL != db) && (NULL != kp) && ((size_t)0UL < ks)) {
+ if ((0 != db->wa) && (((size_t)0UL == db->km) || (db->km >= ks))) {
+ switch (db->tp) {
+ case DK4_DB_BE_MEMORY : {
+ db->uc = 1;
+ dat.kd = (void *)kp; dat.ks = ks;
+ rp = (dk4_dbi_datum_t *)dk4sto_it_find_like(
+ (db->dt).mem.i, &dat, 0
+ );
+ if (NULL != rp) {
+ back = dk4sto_remove((db->dt).mem.s, rp, erp);
+ if (0 != back) {
+ if (0 == dk4dbi_datum_delete(rp, db->op)) {
+ back = 0;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } break;
+ case DK4_DB_BE_BDB : {
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+ if (NULL != (db->dt).bdb.db) {
+ db->uc = 1;
+ DK4_MEMRES(&k, sizeof(DBT));
+ k.data = (void *)kp; k.size = ks;
+ if (0 == ((db->dt).bdb.db)->del((db->dt).bdb.db, NULL, &k, 0)) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_DB_BE_NDBM : {
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+ if (NULL != (db->dt).ndbm.dbm) {
+ db->uc = 1;
+ DK4_MEMRES(&datk, sizeof(datum));
+ datk.dptr = (char *)kp; datk.dsize = ks;
+ if (0 == dbm_delete((db->dt).ndbm.dbm, datk)) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 1718 "dk4dbi.ctr"
+ return back;
+}
+
+
+
+int
+dk4dbi_set(
+ dk4_dbi_t *db,
+ const void *kp,
+ size_t ks,
+ const void *vp,
+ size_t vs,
+ dk4_er_t *erp
+)
+{
+ dk4_dbi_datum_t dat; /* Key for comparison */
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+ DBT k; /* Key */
+ DBT v; /* Value */
+#endif
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+ datum datk; /* Key */
+ datum datv; /* Value */
+#endif
+ dk4_dbi_datum_t *rp = NULL; /* Result record */
+ char *nb = NULL; /* New value buffer */
+ int back = 0;
+
+
+
+#line 1747 "dk4dbi.ctr"
+ if ((NULL != db) && (NULL != kp) && ((size_t)0UL < ks)) {
+
+#line 1748 "dk4dbi.ctr"
+ if ((NULL != vp) && ((size_t)0UL < vs)) {
+
+#line 1749 "dk4dbi.ctr"
+ if(
+ (((size_t)0UL == db->km) || (db->km >= ks))
+ && (((size_t)0UL == db->vm) || (db->vm >= vs))
+ && (0 != db->wa)
+ )
+ {
+
+#line 1755 "dk4dbi.ctr"
+ switch (db->tp) {
+ case DK4_DB_BE_MEMORY : {
+
+#line 1757 "dk4dbi.ctr"
+ db->uc = 1;
+ dat.kd = (void *)kp; dat.ks = ks;
+ rp = (dk4_dbi_datum_t *)dk4sto_it_find_like(
+ (db->dt).mem.i, &dat, 0
+ );
+ if (NULL != rp) {
+ nb = dk4mem_new(char,vs,erp);
+ if (NULL != nb) {
+ back = 1;
+ if (NULL != rp->vd) {
+ if (0 != (DK4_DB_OPT_RESET_VALUE & (db->op))) {
+ if ((size_t)0UL < rp->vs) {
+ back = dk4mem_reset_secure(rp->vd, rp->vs, NULL);
+ }
+ }
+ dk4mem_free(rp->vd);
+ }
+ rp->vd = nb;
+ DK4_MEMCPY(rp->vd,vp,vs);
+ rp->vs = vs;
+ }
+ } else {
+ rp = dk4dbi_datum_new(ks, vs, erp);
+ if (NULL != rp) {
+ DK4_MEMCPY(rp->kd,kp,ks);
+ DK4_MEMCPY(rp->vd,vp,vs);
+ if (0 != dk4sto_add((db->dt).mem.s, rp, erp)) {
+ back = 1;
+ } else {
+ dk4dbi_datum_delete(rp, db->op);
+ }
+ }
+ }
+ } break;
+ case DK4_DB_BE_BDB : {
+
+#line 1792 "dk4dbi.ctr"
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+
+
+#line 1794 "dk4dbi.ctr"
+ if (NULL != (db->dt).bdb.db) {
+
+#line 1795 "dk4dbi.ctr"
+ db->uc = 1;
+ DK4_MEMRES(&k, sizeof(DBT));
+ DK4_MEMRES(&v, sizeof(DBT));
+ k.data = (void *)kp; v.data = (void *)vp;
+ k.size = ks; v.size = vs;
+
+
+#line 1801 "dk4dbi.ctr"
+ ((db->dt).bdb.db)->del((db->dt).bdb.db, NULL, &k, 0);
+ DK4_MEMRES(&k, sizeof(DBT));
+ k.data = (void *)kp; k.size = ks;
+
+
+#line 1805 "dk4dbi.ctr"
+ if (0 == ((db->dt).bdb.db)->put((db->dt).bdb.db,NULL,&k,&v,0)) {
+ back = 1;
+
+#line 1807 "dk4dbi.ctr"
+ } else {
+
+#line 1808 "dk4dbi.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED);
+ }
+ } else {
+
+#line 1811 "dk4dbi.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_DB_BE_NDBM : {
+
+#line 1818 "dk4dbi.ctr"
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+ if (NULL != (db->dt).ndbm.dbm) {
+ db->uc = 1;
+ DK4_MEMRES(&datk, sizeof(datum));
+ DK4_MEMRES(&datv, sizeof(datum));
+ datk.dptr = (char *)kp; datk.dsize = ks;
+ datv.dptr = (char *)vp; datv.dsize = vs;
+ if (0 == dbm_store((db->dt).ndbm.dbm, datk, datv, DBM_INSERT)) {
+ back = 1;
+ } else {
+ DK4_MEMRES(&datk, sizeof(datum));
+ DK4_MEMRES(&datv, sizeof(datum));
+ datk.dptr = (char *)kp; datk.dsize = ks;
+ datv.dptr = (char *)vp; datv.dsize = vs;
+ if (0 == dbm_store((db->dt).ndbm.dbm,datk,datv,DBM_REPLACE)) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ }
+ }
+ else
+ {
+
+#line 1849 "dk4dbi.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+
+#line 1852 "dk4dbi.ctr"
+ back = dk4dbi_delete(db, kp, ks, erp);
+ }
+ } else {
+
+#line 1855 "dk4dbi.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 1858 "dk4dbi.ctr"
+ return back;
+}
+
+
+
+int
+dk4dbi_sync(
+ dk4_dbi_t *db,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+
+
+#line 1871 "dk4dbi.ctr"
+ if (NULL != db) {
+ switch (db->tp) {
+ case DK4_DB_BE_MEMORY : {
+ if ((0 != db->wa) && (0 != db->uc)) {
+ back = dk4dbi_mem_to_file(db, erp);
+ } else {
+ back = 1;
+ }
+ } break;
+ case DK4_DB_BE_BDB : {
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+ if (NULL != (db->dt).bdb.db) {
+ if ((0 != db->wa) && (0 != db->uc)) {
+ if (0 == ((db->dt).bdb.db)->sync((db->dt).bdb.db, 0)) {
+ back = 1;
+ db->uc = 0;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED);
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_DB_BE_NDBM : {
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+ if (NULL != (db->dt).ndbm.dbm) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 1916 "dk4dbi.ctr"
+ return back;
+}
+
+
+
+int
+dk4dbi_get(
+ dk4_dbi_t *db,
+ const void *kp,
+ size_t ks,
+ void *vp,
+ size_t *vs,
+ dk4_er_t *erp
+)
+{
+ dk4_dbi_datum_t dat; /* Key for comparison */
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+ DBT k; /* Key */
+ DBT v; /* Value */
+#endif
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+ datum datk; /* Key */
+ datum datv; /* Value */
+#endif
+ dk4_dbi_datum_t *rp; /* Search result pointer */
+ int back = 0;
+
+
+
+#line 1944 "dk4dbi.ctr"
+ if (
+ (NULL != db) && (NULL != kp) && ((size_t)0 < ks)
+ && (NULL != vp) && (NULL != vs)
+ )
+ {
+ if ((size_t)0UL < *vs) {
+ if (((size_t)0UL == db->km) || (db->km >= ks)) {
+ switch (db->tp) {
+ case DK4_DB_BE_MEMORY : {
+
+#line 1953 "dk4dbi.ctr"
+ dat.kd = (void *)kp; dat.ks = ks;
+ rp = (dk4_dbi_datum_t *)dk4sto_it_find_like(
+ (db->dt).mem.i, &dat, 0
+ );
+ if (NULL != rp) {
+ if ((NULL != rp->vd) && ((size_t)0UL < rp->vs)) {
+ if (*vs >= rp->vs) {
+ DK4_MEMCPY(vp,rp->vd,rp->vs);
+ *vs = rp->vs;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } break;
+ case DK4_DB_BE_BDB : {
+
+#line 1974 "dk4dbi.ctr"
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+
+
+#line 1976 "dk4dbi.ctr"
+ if (NULL != (db->dt).bdb.db) {
+
+#line 1977 "dk4dbi.ctr"
+ DK4_MEMRES(&k, sizeof(DBT));
+ DK4_MEMRES(&v, sizeof(DBT));
+ k.data = (void *)kp; k.size = ks;
+ v.data = (void *)vp; v.ulen = *vs; v.flags = DB_DBT_USERMEM;
+ if (0 == ((db->dt).bdb.db)->get((db->dt).bdb.db,NULL,&k,&v,0)) {
+ *vs = v.size;
+
+#line 1983 "dk4dbi.ctr"
+ back = 1;
+ } else {
+
+#line 1985 "dk4dbi.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+
+#line 1988 "dk4dbi.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+#else
+
+
+#line 1992 "dk4dbi.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_DB_BE_NDBM : {
+
+#line 1996 "dk4dbi.ctr"
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+ if (NULL != (db->dt).ndbm.dbm) {
+ DK4_MEMRES(&datk, sizeof(datum));
+ DK4_MEMRES(&datv, sizeof(datum));
+ datk.dptr = (char *)kp; datk.dsize = ks;
+ datv = dbm_fetch((db->dt).ndbm.dbm, datk);
+ if ((NULL != datv.dptr) && (0 < datv.dsize)) {
+ if (*vs >= datv.dsize) {
+ DK4_MEMCPY(vp,datv.dptr,datv.dsize);
+ *vs = datv.dsize;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ }
+ } else {
+
+#line 2022 "dk4dbi.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+
+#line 2025 "dk4dbi.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+
+#line 2028 "dk4dbi.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 2031 "dk4dbi.ctr"
+ return back;
+}
+
+
+
+int
+dk4dbi_traverse(
+ dk4_dbi_t *db,
+ void *obj,
+ dk4dbi_traverse_fct_t *fct
+)
+{
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+ DBT dbtk; /* Key */
+ DBT dbtv; /* Value */
+ DBC *cp = NULL; /* Cursor for traversal */
+#endif
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+ datum datk; /* Key */
+ datum datv; /* Value */
+#endif
+ dk4_dbi_datum_t *dddt = NULL; /* Pointer for traversal */
+ int res = 0; /* Operation result */
+ int first = 1; /* Flag: Retrieving first record */
+ int back = -1;
+
+
+
+#line 2058 "dk4dbi.ctr"
+ if ((NULL != db) && (NULL != fct)) {
+ switch (db->tp) {
+ case DK4_DB_BE_MEMORY : {
+ back = 1;
+ dk4sto_it_reset((db->dt).mem.i);
+ do {
+ dddt = dk4sto_it_next((db->dt).mem.i);
+ if (NULL != dddt) {
+ res = (*fct)(obj, dddt->kd, dddt->ks, dddt->vd, dddt->vs);
+ if (res < back) { back = res; }
+ }
+ } while((NULL != dddt) && (-1 < back));
+ } break;
+ case DK4_DB_BE_BDB : {
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+ res = ((db->dt).bdb.db)->cursor((db->dt).bdb.db, NULL, &cp, 0);
+ if (0 == res) {
+ if (NULL != cp) {
+ back = 1;
+ DK4_MEMRES(&dbtk, sizeof(DBT));
+ DK4_MEMRES(&dbtv, sizeof(DBT));
+ do {
+#if DK4_HAVE_DB_CURSOR_C_GET
+ res = cp->c_get(
+ cp, &dbtk, &dbtv, ((0 != first) ? (DB_FIRST) : (DB_NEXT))
+ );
+#else
+ res = cp->get(
+ cp, &dbtk, &dbtv, ((0 != first) ? (DB_FIRST) : (DB_NEXT))
+ );
+#endif
+ first = 0;
+ if (0 == res) {
+ res = (*fct)(obj, dbtk.data, dbtk.size, dbtv.data, dbtv.size);
+ if (res < back) { back = res; }
+ } else {
+ res = -1; /* Failed to obtain a record, stop */
+ }
+ } while((-1 < res) && (-1 < back));
+ cp->c_close(cp);
+ } else {
+
+#line 2099 "dk4dbi.ctr"
+ }
+ } else {
+
+#line 2101 "dk4dbi.ctr"
+ }
+#endif
+ } break;
+ case DK4_DB_BE_NDBM : {
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+ back = 1;
+ do {
+ if (0 != first) {
+ datk = dbm_firstkey((db->dt).ndbm.dbm);
+ first = 0;
+ } else {
+ datk = dbm_nextkey((db->dt).ndbm.dbm);
+ }
+ if ((NULL != datk.dptr) && (0 < datk.dsize)) {
+ datv = dbm_fetch((db->dt).ndbm.dbm, datk);
+ if ((NULL != datv.dptr) && (0 < datv.dsize)) {
+ res = (*fct)(obj, datk.dptr, datk.dsize, datv.dptr, datv.dsize);
+ if (res < back) { back = res; }
+ } else {
+ res = -1;
+ }
+ } else {
+ res = -1;
+ }
+ } while((-1 < res) && (-1 < back));
+#endif
+ } break;
+ }
+ }
+
+#line 2130 "dk4dbi.ctr"
+ return back;
+}
+
+
+
+
+#if !DK4_ON_WINDOWS
+#if DK4_CHAR_SIZE == 1
+#if DK4_HAVE_CHOWN && DK4_HAVE_CHMOD
+
+/** Change ownership and mode for a file.
+ @param fn File name.
+ @param user New owner.
+ @param group New owner group.
+ @param mode New file permissions.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_SYSTEM<br>
+ with errno value in iDetails1 if chown
+ or chmod failed.
+*/
+static
+int
+dk4dbi_change_file_owner_and_mode(
+ const dkChar *fn,
+ uid_t user,
+ gid_t group,
+ mode_t mode,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+
+
+
+#line 2166 "dk4dbi.ctr"
+ errno = 0;
+ if (0 == chown(fn, user, group)) {
+ errno = 0;
+ if (0 == chmod(fn, mode)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_SYSTEM, errno);
+ }
+ } else {
+ dk4error_set_idetails(erp, DK4_E_SYSTEM, errno);
+ }
+
+#line 2177 "dk4dbi.ctr"
+ return back;
+}
+
+
+int
+dk4dbi_change_owner_and_mode(
+ dk4_dbi_t *db,
+ uid_t user,
+ gid_t group,
+ mode_t mode,
+ dk4_er_t *erp
+)
+{
+ dkChar buf[DK4_MAX_PATH]; /* File names construction */
+ const size_t szbuf = DK4_SIZEOF(buf,dkChar); /* Buffer size */
+ int back = 0;
+
+
+
+#line 2195 "dk4dbi.ctr"
+ if (NULL != db) {
+ switch (db->tp) {
+ case DK4_DB_BE_MEMORY :
+ case DK4_DB_BE_BDB :
+ {
+ back = dk4dbi_change_file_owner_and_mode(
+ db->fn, user, group, mode, erp
+ );
+ } break;
+ case DK4_DB_BE_NDBM : {
+ if (0 != dk4str_cpy_s(buf, szbuf, db->fn, erp)) {
+ if (0 != dk4str_cat_s(buf, szbuf, dk4dbi_ndbm_suffixes[0], erp)) {
+ back = dk4dbi_change_file_owner_and_mode(buf,user,group,mode,erp);
+ (void)dk4str_cpy_s(buf, szbuf, db->fn, erp);
+ if (0 != dk4str_cat_s(buf, szbuf, dk4dbi_ndbm_suffixes[1], erp)) {
+ if (0 ==
+ dk4dbi_change_file_owner_and_mode(buf,user,group,mode,erp)
+ )
+ {
+ back = 0;
+ }
+ }
+ }
+ }
+ } break;
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 2227 "dk4dbi.ctr"
+ return back;
+}
+
+#endif
+/* if DK4_HAVE_CHOWN && DK4_HAVE_CHMOD */
+#endif
+/* if DK4_CHAR_SIZE == 1 */
+#endif
+/* if !DK4_ON_WINDOWS */
+
+
+
+size_t
+dk4dbi_get_key_max(
+ const dk4_dbi_t *db,
+ dk4_er_t *erp
+)
+{
+ size_t back = 0;
+
+
+#line 2247 "dk4dbi.ctr"
+ if (NULL != db) {
+ back = db->km;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 2252 "dk4dbi.ctr"
+ return back;
+}
+
+
+
+size_t
+dk4dbi_get_val_max(
+ const dk4_dbi_t *db,
+ dk4_er_t *erp
+)
+{
+ size_t back = 0;
+
+
+#line 2265 "dk4dbi.ctr"
+ if (NULL != db) {
+ back = db->vm;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 2270 "dk4dbi.ctr"
+ return back;
+}
+
+
+
+int
+dk4dbi_get_type(const dk4_dbi_t *db)
+{
+ int back = DK4_DB_BE_UNKNOWN;
+ if (NULL != db) {
+ back = db->tp;
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4dbi.ctr b/support/dktools/dk4dbi.ctr
new file mode 100644
index 0000000000..eb1ef2f9cd
--- /dev/null
+++ b/support/dktools/dk4dbi.ctr
@@ -0,0 +1,2284 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk4dbi.h Interface to databases.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+#include <db.h>
+#endif
+
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+#ifndef NDBM_H_INCLUDED
+#include <ndbm.h>
+#define NDBM_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4STO_H_INCLUDED
+#include "dk4sto.h"
+#endif
+
+
+
+/** Backend types.
+*/
+enum {
+ /** No backend specified yet.
+ */
+ DK4_DB_BE_UNKNOWN = -1 ,
+
+ /** In-memory database.
+ */
+ DK4_DB_BE_MEMORY = 0 ,
+
+ /** Berkeley DB.
+ */
+ DK4_DB_BE_BDB = 1 ,
+
+ /** NDBM.
+ */
+ DK4_DB_BE_NDBM = 2
+};
+
+
+
+/** Options.
+*/
+enum {
+ /** Reset key data before releasing
+ memory.
+ */
+ DK4_DB_OPT_RESET_KEY = 1 ,
+
+ /** Reset value data before releasing
+ memory.
+ */
+ DK4_DB_OPT_RESET_VALUE = 2 ,
+};
+
+
+
+/** Details for an in-memory database.
+*/
+typedef struct {
+ dk4_sto_t *s; /**< Storage container. */
+ dk4_sto_it_t *i; /**< Storage iterator. */
+} dk4_dbi_mem_t;
+
+
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+/** Details for a Berkeley DB database.
+*/
+typedef struct {
+ DB *db; /**< DB structure. */
+} dk4_dbi_bdb_t;
+#endif
+
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+/** Details for an NDBM database.
+*/
+typedef struct {
+ DBM *dbm; /**< NDBM structure. */
+} dk4_dbi_ndbm_t;
+#endif
+
+/** Details for one backend.
+*/
+typedef union {
+ dk4_dbi_mem_t mem; /**< Details for in-memory database. */
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+ dk4_dbi_bdb_t bdb; /**< Details for Berkeley DB. */
+#endif
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+ dk4_dbi_ndbm_t ndbm; /**< Details for NDBM. */
+#endif
+ int dummy; /**< Just to have a second component. */
+} dk4_dbi_det_t;
+
+/** Database structure.
+*/
+typedef struct {
+ dk4_dbi_det_t dt; /**< Backend-specific details. */
+ dkChar *fn; /**< File name. */
+ size_t km; /**< Maximum key size. */
+ size_t vm; /**< Maximum value size. */
+ int tp; /**< Backend type. */
+ int op; /**< Options. */
+ int wa; /**< Flag: Write access. */
+ int uc; /**< Flag: Have unsynchronized changes. */
+} dk4_dbi_t;
+
+/** Function to traverse a simple database.
+ The function must check the kb, ks, vb and vs arguments
+ for validity, they are passed as found by the backend
+ functions (this means pointers may be NULL, sizes may be 0).
+ @param Object modified during traversal, may be NULL.
+ @param kb Key data.
+ @param ks Key size.
+ @param vb Value data.
+ @param vs Value size.
+ @return 1 on success, 0 on error (can continue), -1 on error (abort).
+*/
+typedef
+int
+dk4dbi_traverse_fct_t(
+ void *obj,
+ const void *kb,
+ size_t ks,
+ const void *vb,
+ size_t vs
+);
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open database.
+ @param fn File name.
+ @param tp Backend type.
+ @param wa Flag: Write access required.
+ @param tr Flag: Truncate existing database
+ (only in conjunction with wa).
+ @param km Maximum key size (0 for unlimited).
+ @param vm Maximum value size (0 for unlimited).
+ The limits are used on all backends for writing,
+ on in-memory databases also for reading.
+ @param erp Error report, may be NULL.
+ @return Pointer to new database structure on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL or tp contains an invalid type number,
+ - DK4_E_NOT_SUPPORTED<br>
+ if the database type is not supported,
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow when calculating size,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available,
+ - DK4_E_SYNTAX<br>
+ if
+ - the database file name does not refer to a regular file
+ - or the file contents is not an in-memory database
+ - or key/value sizes in the file are in conflict with restrictions,
+ - DK4_E_SEC_CHECK<br>
+ with failed check id in iDetails1 if access is denied by additional
+ security checks,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available,
+ - DK4_E_OPEN_READ_FAILED<br>
+ if fopen() or fread() failed,
+ - DK4_E_OPEN_WRITE_FAILED<br>
+ if fopen() or fwrite() failed,
+ - DK4_E_CLOSE_FAILED<br>
+ with errno value in iDetails1 if fclose() failed.
+
+*/
+dk4_dbi_t *
+dk4dbi_open_with_type(
+ const dkChar *fn,
+ int tp,
+ int wa,
+ int tr,
+ size_t km,
+ size_t vm,
+ dk4_er_t *erp
+);
+
+/** Open database.
+ @param fn Database type and file name.
+ The database type is one from "mem", "bdb" or "ndbm".
+ Database type and file name are separated by two
+ colons "::".
+ @param wa Flag: Write access required.
+ @param tr Flag: Truncate existing database
+ (only in conjunction with wa).
+ @param km Maximum key size (0 for unlimited).
+ @param vm Maximum value size (0 for unlimited).
+ @param erp Error report, may be NULL.
+ @return Pointer to new database structure on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL or tp contains an invalid type number,
+ - DK4_E_NOT_SUPPORTED<br>
+ if the database type is not supported,
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow when calculating size,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available,
+ - DK4_E_SYNTAX<br>
+ if
+ - the specification contains an invalid backend type
+ - the database file name does not refer to a regular file
+ - or the file contents is not an in-memory database
+ - or key/value sizes in the file are in conflict with restrictions
+ - or an invalid database type was specified,
+ - DK4_E_SEC_CHECK<br>
+ with failed check id in iDetails1 if access is denied by additional
+ security checks,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available,
+ - DK4_E_OPEN_READ_FAILED<br>
+ if fopen() or fread() failed,
+ - DK4_E_OPEN_WRITE_FAILED<br>
+ if fopen() or fwrite() failed,
+ - DK4_E_CLOSE_FAILED<br>
+ with errno value in iDetails1 if fclose() failed.
+*/
+dk4_dbi_t *
+dk4dbi_open(
+ const dkChar *fn,
+ int wa,
+ int tr,
+ size_t km,
+ size_t vm,
+ dk4_er_t *erp
+);
+
+/** Find file name part from combined type/name.
+ @param filename Combined database type and file name.
+ @return Valid pointer to file name part on success, NULL on error.
+*/
+const dkChar *
+dk4dbi_filename_part(const dkChar *filename);
+
+/** Close database, release resources.
+ @param db Database to close.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if db is NULL,
+ - DK4_E_NOT_SUPPORTED<br>
+ if db indicates an unsupported backend type,
+ - DK4_E_SYNTAX<br>
+ if the database file name does not refer to a regular file,
+ - DK4_E_SEC_CHECK<br>
+ with failed check id in iDetails1 if access is denied by additional
+ security checks,
+ - DK4_E_OPEN_WRITE_FAILED<br>
+ with errno value in iDetails1 if fopen() or fwrite() failed,
+ - DK4_E_CLOSE_FAILED<br>
+ with errno value in iDetails1 if fclose() failed.
+*/
+int
+dk4dbi_close(
+ dk4_dbi_t *db,
+ dk4_er_t *erp
+);
+
+/** Set or reset option.
+ @param db Database.
+ @param opt Option.
+ @param val New value (1 or 0).
+ @return 1 on success, 0 on error (unknown option).
+*/
+int
+dk4dbi_set_option(
+ dk4_dbi_t *db,
+ int opt,
+ int val
+);
+
+/** Retrieve maximum key size.
+ @param db Database to query.
+ @param erp Error report, may be NULL.
+ @return Value on success (0 means unlimited),
+ 0 with erp set on error.
+
+ Error code:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if db is NULL.
+*/
+size_t
+dk4dbi_get_key_max(
+ const dk4_dbi_t *db,
+ dk4_er_t *erp
+);
+
+/** Retrieve maximum value size.
+ @param db Database to query.
+ @param erp Error report, may be NULL.
+ @return Value on success (0 means unlimited),
+ 0 with erp set on error.
+
+
+ Error code:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if db is NULL.
+*/
+size_t
+dk4dbi_get_val_max(
+ const dk4_dbi_t *db,
+ dk4_er_t *erp
+);
+
+/** Set or overwrite record.
+ @param db Database.
+ @param kp Pointer to key data.
+ @param ks Key data size (number of bytes).
+ @param vp Pointer to value data. Use NULL to delete a record.
+ @param vs Value data size (number of bytes).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if db or kp is NULL or ks is 0,
+ - DK4_E_SYNTAX<br>
+ if the database was opened read-only or ks or vs
+ exceeds a size limit,
+ - DK4_E_NOT_SUPPORTED<br>
+ if db indicates an unsupported backend,
+ - DK4_E_NOT_FOUND<br>
+ if no record to delete was found,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available,
+ - DK4_E_WRITE_FAILED<br>
+ if modification of the database failed.
+*/
+int
+dk4dbi_set(
+ dk4_dbi_t *db,
+ const void *kp,
+ size_t ks,
+ const void *vp,
+ size_t vs,
+ dk4_er_t *erp
+);
+
+/** Synchronize changes to file if supported by backend.
+ @param db Database.
+ @param erp error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if db or a backend component is NULL,
+ - DK4_E_NOT_SUPPORTED<br>
+ if db indicates an unsupported backend,
+ - DK4_E_SYNTAX<br>
+ if the database file name does not refer to a regular file,
+ - DK4_E_SEC_CHECK<br>
+ with failed check id in iDetails1 if access is denied by additional
+ security checks,
+ - DK4_E_OPEN_WRITE_FAILED<br>
+ with errno value in iDetails1 if fopen() or fwrite() failed,
+ - DK4_E_WRITE_FAILED<br>
+ if the backend failed to write to a database,
+ - DK4_E_CLOSE_FAILED<br>
+ with errno value in iDetails1 if fclose() failed.
+*/
+int
+dk4dbi_sync(
+ dk4_dbi_t *db,
+ dk4_er_t *erp
+);
+
+/** Retrieve record.
+ @param db Database.
+ @param kp Pointer to key data.
+ @param ks Key data size (number of bytes).
+ @param vp Address of result buffer.
+ @param vs Pointer to buffer size variable (in: size, out: used).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if db, kp, vp or vs is NULL or ks is 0 or *vs is 0
+ or ks exceeds the key size limit,
+ - DK4_E_NOT_SUPPORTED<br>
+ if db indicates an unsupported backend,
+ - DK4_E_NOT_FOUND<br>
+ if no record was found for the key,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the destination buffer is too small.
+*/
+int
+dk4dbi_get(
+ dk4_dbi_t *db,
+ const void *kp,
+ size_t ks,
+ void *vp,
+ size_t *vs,
+ dk4_er_t *erp
+);
+
+/** Delete one record.
+ @param db Database.
+ @param kp Pointer to key data.
+ @param ks Key data size (number of bytes).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if db or kp is NULL or ks is 0,
+ - DK4_E_SYNTAX<br>
+ if the database is opened read-only or ks exceeds the
+ key size limit,
+ - DK4_E_NOT_SUPPORTED<br>
+ if db indicates an unsupported backend,
+ - DK4_E_WRITE_FAILED<br>
+ if modification of the database failed,
+ - DK4_E_NOT_FOUND<br>
+ if no record for the specified key is in the database.
+*/
+int
+dk4dbi_delete(
+ dk4_dbi_t *db,
+ const void *kp,
+ size_t ks,
+ dk4_er_t *erp
+);
+
+/** Traverse database.
+ @param db Database to traverse.
+ @param obj Object to modify during traversal, may be NULL.
+ @param fct Function to execute for all records.
+ @return 1 on success, 0 on error (database traversed),
+ -1 on error (traversal aborted).
+*/
+int
+dk4dbi_traverse(
+ dk4_dbi_t *db,
+ void *obj,
+ dk4dbi_traverse_fct_t *fct
+);
+
+/** Retrieve backend type.
+ @param db Database to check.
+ @return Backend type.
+*/
+int
+dk4dbi_get_type(const dk4_dbi_t *db);
+
+#if !DK4_ON_WINDOWS
+#if DK4_CHAR_SIZE == 1
+#if DK4_HAVE_CHOWN && DK4_HAVE_CHMOD
+
+/** Change owner and mode for a database.
+ @param db Database to modify.
+ @param user New owner.
+ @param group New owner group.
+ @param mode New file permissions.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if db is NULL,
+ - DK4_E_NOT_SUPPORTED<br>
+ if db indicates an unsupported backend,
+ - DK4_E_SYSTEM<br>
+ with errno value in iDetails1 if a chown or chmod
+ system call failed,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in size calculation,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the file name is too large for an internal buffer.
+*/
+int
+dk4dbi_change_owner_and_mode(
+ dk4_dbi_t *db,
+ uid_t user,
+ gid_t group,
+ mode_t mode,
+ dk4_er_t *erp
+);
+
+#endif
+/* if DK4_HAVE_CHOWN && DK4_HAVE_CHMOD */
+#endif
+/* if DK4_CHAR_SIZE == 1 */
+#endif
+/* if !DK4_ON_WINDOWS */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_STAT_H
+#ifndef SYS_STAT_H_INCLUDED
+#include <sys/stat.h>
+#define SYS_STAT_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4dbi.h"
+#include "dk4mem.h"
+#include "dk4memrs.h"
+#include "dk4strd.h"
+#include "dk4fopd.h"
+#include "dk4numco.h"
+#include "dk4isadm.h"
+#include "dk4fopt.h"
+#include "dk4mpl.h"
+#include "dk4delfile.h"
+#include "dk4stat.h"
+#include "dk4statd.h"
+
+
+
+$!trace-include
+
+
+
+/** One storage entry.
+*/
+typedef struct {
+ void *kd; /**< Key data. */
+ void *vd; /**< Value data. */
+ size_t ks; /**< Key size. */
+ size_t vs; /**< Value size. */
+} dk4_dbi_datum_t;
+
+
+
+/** Backend type names.
+*/
+static const dkChar *dk4dbi_type_names[] = {
+$!string-table macro=dkT
+mem
+bdb
+ndbm
+$!end
+};
+
+
+
+/** File name suffixes for NDBM files.
+*/
+static const dkChar *dk4dbi_ndbm_suffixes[] = {
+dkT(".dir"), dkT(".pag")
+};
+
+
+
+/** Maximum size of key or value.
+*/
+static const unsigned long dk4dbi_max_size = 4294967295UL;
+
+
+
+/** Delete one record from an in-memory database,
+ release resources.
+ @param ptr Record to delete
+ @param options The database options.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4dbi_datum_delete(dk4_dbi_datum_t *ptr, int options)
+{
+ int back = 0;
+ $? "+ dk4dbi_datum_delete %!8s", TR_8PTR(ptr)
+ if (NULL != ptr) {
+ back = 1;
+ if (0 != (DK4_DB_OPT_RESET_KEY & options)) {
+ if ((NULL != ptr->kd) && ((size_t)0UL < ptr->ks)) {
+ $? ". clean up key memory"
+ if (0 == dk4mem_reset_secure(ptr->kd, ptr->ks, NULL)) {
+ back = 0;
+ }
+ }
+ }
+ if (0 != (DK4_DB_OPT_RESET_VALUE & options)) {
+ if ((NULL != ptr->vd) && ((size_t)0UL < ptr->vs)) {
+ $? ". clean up value memory"
+ if (0 == dk4mem_reset_secure(ptr->vd, ptr->vs, NULL)) {
+ back = 0;
+ }
+ }
+ }
+ dk4mem_release(ptr->kd);
+ dk4mem_release(ptr->vd);
+ ptr->ks = ptr->vs = (size_t)0UL;
+ dk4mem_free(ptr);
+ }
+ $? "- dk4dbi_datum_delete %d", back
+ return back;
+}
+
+
+
+/** Allocate memory for a new record.
+ @param ks
+ @param vs
+ @param erp
+ @return Pointer to new record structure on success, NULL on error.
+
+ Error codes:
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available.
+*/
+static
+dk4_dbi_datum_t *
+dk4dbi_datum_new(
+ size_t ks,
+ size_t vs,
+ dk4_er_t *erp
+)
+{
+ dk4_dbi_datum_t *back = NULL;
+ $? "+ dk4dbi_datum_new %lu %lu", (unsigned long)ks, (unsigned long)vs
+ back = dk4mem_new(dk4_dbi_datum_t,1,erp);
+ if (NULL != back) {
+ back->kd = back->vd = NULL;
+ back->ks = back->vs = (size_t)0UL;
+ back->kd = dk4mem_new(char,ks,erp);
+ back->vd = dk4mem_new(char,vs,erp);
+ if ((NULL != back->kd) && (NULL != back->vd)) {
+ back->ks = ks; back->vs = vs;
+ } else {
+ dk4mem_release(back->kd);
+ dk4mem_release(back->vd);
+ dk4mem_free(back);
+ back = NULL;
+ }
+ } $? "- dk4dbi_datum_new %d", TR_IPTR(back)
+ return back;
+}
+
+
+
+
+/** Write in-memory database contents back to file.
+ @param db Database to save.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_SYNTAX<br>
+ if the database file name does not refer to a regular file,
+ - DK4_E_SEC_CHECK<br>
+ with failed check id in iDetails1 if access is denied by additional
+ security checks,
+ - DK4_E_OPEN_WRITE_FAILED<br>
+ with errno value in iDetails1 if fopen() or fwrite() failed,
+ - DK4_E_CLOSE_FAILED<br>
+ with errno value in iDetails1 if fclose() failed,
+ - DK4_E_WRITE_FAILD<br>
+ if fwrite() failed.
+*/
+static
+int
+dk4dbi_mem_to_file(
+ dk4_dbi_t *db,
+ dk4_er_t *erp
+)
+{
+ FILE *fipo = NULL; /* Write text ile */
+ dk4_dbi_datum_t *rp = NULL; /* Current record */
+ unsigned char uc[8]; /* Sizes byte array */
+ size_t nbw = 0; /* Number of bytes */
+ int tests = DK4_FOPEN_SC_USER; /* Security checks */
+ int back = 0;
+
+ $? "+ dk4dbi_mem_to_file %!8s", TR_8PTR(db)
+ if (dk4isadmin()) { tests = DK4_FOPEN_SC_PRIVILEGED; }
+ fipo = dk4fopen(db->fn, dkT("wb"), tests, erp);
+ if (NULL != fipo) { $? ". fopen"
+ back = 1;
+ dk4sto_it_reset((db->dt).mem.i);
+ do {
+ rp = (dk4_dbi_datum_t *)dk4sto_it_next((db->dt).mem.i);
+ if (NULL != rp) { $? ". record"
+ uc[0] = (unsigned char)(((unsigned long)(rp->ks) >> 24) & 0x000000FFUL);
+ uc[1] = (unsigned char)(((unsigned long)(rp->ks) >> 16) & 0x000000FFUL);
+ uc[2] = (unsigned char)(((unsigned long)(rp->ks) >> 8) & 0x000000FFUL);
+ uc[3] = (unsigned char)(((unsigned long)(rp->ks) ) & 0x000000FFUL);
+ uc[4] = (unsigned char)(((unsigned long)(rp->vs) >> 24) & 0x000000FFUL);
+ uc[5] = (unsigned char)(((unsigned long)(rp->vs) >> 16) & 0x000000FFUL);
+ uc[6] = (unsigned char)(((unsigned long)(rp->vs) >> 8) & 0x000000FFUL);
+ uc[7] = (unsigned char)(((unsigned long)(rp->vs) ) & 0x000000FFUL);
+ nbw = fwrite(uc, 1, 8, fipo);
+ if (8 == nbw) { $? ". sizes written"
+ nbw = fwrite(rp->kd, 1, rp->ks, fipo);
+ if (rp->ks == nbw) { $? ". key written"
+ nbw = fwrite(rp->vd, 1, rp->vs, fipo);
+ if (rp->vs == nbw) { $? ". value written"
+ } else {
+ back = 0; $? "! fwrite value"
+ dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED);
+ }
+ } else { $? "! fwrite key"
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED);
+ }
+ } else { $? "! fwrite sizes"
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED);
+ }
+ }
+ } while (NULL != rp);
+ if (0 != fclose(fipo)) { $? "! fclose"
+ back = 0;
+ dk4error_set_idetails(erp, DK4_E_CLOSE_FAILED, errno);
+ }
+ } else { $? "! fopen"
+ }
+ if (0 != back) {
+ db->uc = 0;
+ }
+ $? "- dk4dbi_mem_to_file %d", back
+ return back;
+}
+
+
+
+/** Read in-memory database contents back from file.
+ @param db Database to restore.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_SYNTAX<br>
+ if
+ - the database file name does not refer to a regular file
+ - or the file contents is not an in-memory database
+ - or key/value sizes in the file are in conflict with size restrictions,
+ - DK4_E_SEC_CHECK<br>
+ with failed check id in iDetails1 if access is denied by additional
+ security checks,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available,
+ - DK4_E_OPEN_READ_FAILED with errno value in iDetails1 if fopen()
+ or fread() failed.
+*/
+static
+int
+dk4dbi_mem_from_file(
+ dk4_dbi_t *db,
+ dk4_er_t *erp
+)
+{
+ dk4_stat_t stb; /* File stat buffer */
+ FILE *fipo = NULL; /* Input file */
+ dk4_dbi_datum_t *rp = NULL; /* Current record to process */
+ unsigned char uc[8]; /* Buffer to read sizes */
+ size_t nbr = 0; /* Number of bytes read */
+ size_t ks = 0; /* Key size */
+ size_t vs = 0; /* Value size */
+ unsigned long ul1 = 0UL; /* Key size */
+ unsigned long ul2 = 0UL; /* Value size */
+ int back = 0; /* Result */
+ int cc = 1; /* Flag: Can continue */
+ $? "+ dk4dbi_mem_from_file %!8s", TR_8PTR(db)
+ fipo = dk4fopen(db->fn, dkT("rb"), 0, erp);
+ if (NULL != fipo) {
+ back = 1;
+ do {
+ nbr = fread(uc, 1, 8, fipo);
+ if (8 == nbr) { $? ". sizes read"
+ ul1 = ((((unsigned long)(uc[0])) << 24) & 0xFF000000UL)
+ | ((((unsigned long)(uc[1])) << 16) & 0x00FF0000UL)
+ | ((((unsigned long)(uc[2])) << 8) & 0x0000FF00UL)
+ | ((((unsigned long)(uc[3])) ) & 0x000000FFUL);
+ ul2 = ((((unsigned long)(uc[4])) << 24) & 0xFF000000UL)
+ | ((((unsigned long)(uc[5])) << 16) & 0x00FF0000UL)
+ | ((((unsigned long)(uc[6])) << 8) & 0x0000FF00UL)
+ | ((((unsigned long)(uc[7])) ) & 0x000000FFUL);
+ if ((dk4_um_t)(SIZE_MAX) >= (dk4_um_t)ul1) {
+ if ((dk4_um_t)(SIZE_MAX) >= (dk4_um_t)ul2) {
+ ks = (size_t)ul1; vs = (size_t)ul2;
+ if (
+ (((size_t)0UL == db->km) || (db->km >= ks))
+ && (((size_t)0UL == db->vm) || (db->vm >= vs))
+ && ((size_t)0UL < ks) && ((size_t)0UL < vs)
+ )
+ {
+ rp = dk4dbi_datum_new(ks, vs, erp);
+ if (NULL != rp) { $? ". memory allocated"
+ nbr = fread(rp->kd, 1, rp->ks, fipo);
+ if (nbr == rp->ks) {
+ nbr = fread(rp->vd, 1, rp->vs, fipo);
+ if (nbr == rp->vs) {
+ if (0 == dk4sto_add((db->dt).mem.s, rp, erp)) {
+ cc = 0; $? "! storage add"
+ back = 0;
+ dk4dbi_datum_delete(rp, 0);
+ }
+ } else { $? "! fread value data"
+ cc = 0;
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ dk4dbi_datum_delete(rp, 0);
+ }
+ } else { $? "! fread key data"
+ cc = 0;
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ dk4dbi_datum_delete(rp, 0);
+ }
+ } else { $? "! memory allocation"
+ cc = 0;
+ back = 0;
+ }
+ }
+ else
+ { $? "! size 0 or too large"
+ cc = 0;
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else { $? "! ul2 > SIZE_MAX"
+ cc = 0;
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else { $? "! ul1 > SIZE_MAX"
+ cc = 0;
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else { $? "! fread sizes"
+ cc = 0;
+ if (0 != nbr) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ }
+ } while (0 != cc);
+ (void)fclose(fipo);
+ } else { $? "! fopen"
+ if (0 == dk4stat(&stb, db->fn, NULL)) {
+ back = 1; $? ". no file found yet"
+ }
+ }
+ $? "- dk4dbi_mem_from_file %d", back
+ return back;
+}
+
+
+
+/** Compare two entries.
+ @param l Left record.
+ @param r Right record.
+ @param cr Comparison criteria, ignored.
+ @return 1 if l>r, 0 if l==r, -1 if l<r.
+*/
+static
+int
+dk4dbi_datum_compare(const void *l, const void *r, int cr)
+{
+ dk4_dbi_datum_t *pl; /* Left pointer */
+ dk4_dbi_datum_t *pr; /* Right pointer */
+ int back = 0;
+ $? "+ dk4dbi_datum_compare %!8s %!8s", TR_8PTR(l), TR_8PTR(r)
+ if (NULL != l) {
+ if (NULL != r) {
+ pl = (dk4_dbi_datum_t *)l;
+ pr = (dk4_dbi_datum_t *)r;
+ if (NULL != pl->kd) {
+ if (NULL != pr->kd) {
+ if (pl->ks > pr->ks) {
+ back = 1;
+ } else {
+ if (pl->ks < pr->ks) {
+ back = -1;
+ } else {
+ if (0 < pl->ks) {
+ back = DK4_MEMCMP(pl->kd, pr->kd, pl->ks);
+ if (-1 > back) back = -1;
+ if ( 1 < back) back = 1;
+ }
+ }
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != pr->kd) { back = -1; }
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != r) { back = -1; }
+ }
+ $? "- dk4dbi_datum_compare %d", back
+ return back;
+}
+
+
+
+/** Delete base database structure, release resources.
+ @param ptr Database structure to release.
+*/
+static
+void
+dk4dbi_delete_base(dk4_dbi_t *ptr)
+{
+ $? "+ dk4dbi_delete_base %!8s", TR_8PTR(ptr)
+ if (NULL != ptr) {
+ dk4mem_release(ptr->fn);
+ dk4mem_free(ptr);
+ }
+ $? "- dk4dbi_delete_base"
+}
+
+
+
+/** Allocate memory for a database.
+ @param fn File name.
+ @param tp Backend type.
+ @param wa Flag: Write access required.
+ @param erp Error report, may be NULL.
+ @return Pointer to memory on success, NULL on error.
+
+ Error codes:
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow when calculating size,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available.
+*/
+static
+dk4_dbi_t *
+dk4dbi_new_base(
+ const dkChar *fn,
+ int tp,
+ int wa,
+ size_t km,
+ size_t vm,
+ dk4_er_t *erp
+)
+{
+ dk4_dbi_t *back = NULL;
+ $? "+ dk4dbi_new_base \"%!ds\" %d %d", TR_STR(fn), tp, wa
+ back = dk4mem_new(dk4_dbi_t,1,erp);
+ if (NULL != back) {
+ back->tp = tp;
+ back->wa = wa;
+ back->op = 0;
+ back->uc = 0;
+ back->km = km;
+ back->vm = vm;
+ switch (tp) {
+ case DK4_DB_BE_MEMORY : {
+ (back->dt).mem.s = NULL;
+ (back->dt).mem.i = NULL;
+ } break;
+ case DK4_DB_BE_BDB : {
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+ (back->dt).bdb.db = NULL;
+#endif
+ } break;
+ case DK4_DB_BE_NDBM : {
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+ (back->dt).ndbm.dbm = NULL;
+#endif
+ } break;
+ }
+ back->fn = dk4str_dup(fn, erp);
+ if (NULL == back->fn) { $? "! dk4str_dup"
+ dk4mem_free(back);
+ back = NULL;
+ }
+ }
+ $? "- dk4dbi_new_base %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+/** Close database, release resources.
+ NOTE: Only release in-memory specific things, the
+ dk4dbi_close() function calls dk4dbi_delete_base()
+ to release the base components.
+ @param db Database to close.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_SYNTAX<br>
+ if the database file name does not refer to a regular file,
+ - DK4_E_SEC_CHECK<br>
+ with failed check id in iDetails1 if access is denied by additional
+ security checks,
+ - DK4_E_OPEN_WRITE_FAILED<br>
+ with errno value in iDetails1 if fopen() or fwrite() failed,
+ - DK4_E_CLOSE_FAILED<br>
+ with errno value in iDetails1 if fclose() failed,
+ - DK4_E_WRITE_FAILD<br>
+ if fwrite() failed.
+*/
+static
+int
+dk4dbi_close_mem(
+ dk4_dbi_t *db,
+ dk4_er_t *erp
+)
+{
+ dk4_dbi_datum_t *rp; /* Current record */
+ int back = 1;
+ $? "+ dk4dbi_close_mem"
+ if ((NULL != (db->dt).mem.s) && (NULL != (db->dt).mem.i)) {
+ /*
+ Write records to file if there are unsaved changes.
+ */
+ $? ". wa=%d uc=%d", db->wa, db->uc
+ if ((0 != db->wa) && (0 != db->uc)) {
+ if (0 == dk4dbi_mem_to_file(db, erp)) {
+ back = 0;
+ }
+ }
+ /*
+ Release memory used for the records.
+ */
+ dk4sto_it_reset((db->dt).mem.i);
+ do {
+ rp = (dk4_dbi_datum_t *)dk4sto_it_next((db->dt).mem.i);
+ if (NULL != rp) {
+ if (0 == dk4dbi_datum_delete(rp, db->op)) {
+ back = 0;
+ }
+ }
+ } while (NULL != rp);
+ }
+ if (NULL != (db->dt).mem.i) {
+ dk4sto_it_close((db->dt).mem.i);
+ }
+ if (NULL != (db->dt).mem.s) {
+ dk4sto_close((db->dt).mem.s);
+ } $? "- dk4dbi_close_mem %d", back
+ return back;
+}
+
+
+
+/** Open in-memory database.
+ @param fn File name.
+ @param wa Flag: Write access required.
+ @param tr Flag: Truncate existing database.
+ @param km Maximum key size.
+ @param vm Maximum value size.
+ @param erp Error report, may be NULL.
+ @return Pointer to new database structure on success, NULL on error.
+
+ Error codes:
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow when calculating size,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available,
+ - DK4_E_SYNTAX<br>
+ if
+ - the database file name does not refer to a regular file
+ - or the file contents is not an in-memory database
+ - or key/value sizes in the file are in conflict with size restrictions,
+ - DK4_E_SEC_CHECK<br>
+ with failed check id in iDetails1 if access is denied by additional
+ security checks,
+ - DK4_E_OPEN_READ_FAILED with errno value in iDetails1 if fopen()
+ or fread() failed,
+ - DK4_E_OPEN_WRITE_FAILED<br>
+ with errno value in iDetails1 if fopen() or fwrite() failed,
+ - DK4_E_CLOSE_FAILED<br>
+ with errno value in iDetails1 if fclose() failed.
+*/
+static
+dk4_dbi_t *
+dk4dbi_open_mem(
+ const dkChar *fn,
+ int wa,
+ int tr,
+ size_t km,
+ size_t vm,
+ dk4_er_t *erp
+)
+{
+ dk4_dbi_t *back = NULL;
+ $? "+ dk4dbi_open_mem \"%!ds\" %d %d", TR_STR(fn), wa, tr
+ if (0 != tr) {
+ (void)dk4delete_file(fn, NULL);
+ }
+ back = dk4dbi_new_base(fn, DK4_DB_BE_MEMORY, wa, km, vm, erp);
+ if (NULL != back) {
+ (back->dt).mem.s = NULL;
+ (back->dt).mem.i = NULL;
+ (back->dt).mem.s = dk4sto_open(erp);
+ if (NULL != (back->dt).mem.s) {
+ dk4sto_set_comp((back->dt).mem.s, dk4dbi_datum_compare, 0);
+ (back->dt).mem.i = dk4sto_it_open((back->dt).mem.s, erp);
+ }
+ if ((NULL != (back->dt).mem.s) && (NULL != (back->dt).mem.i)) {
+ if (0 == tr) { /* Do not truncate */
+ if (0 == dk4dbi_mem_from_file(back, erp)) {
+ (void)dk4dbi_close_mem(back, NULL);
+ back = NULL;
+ }
+ } else { /* Truncate */
+ if (0 == dk4dbi_mem_to_file(back, erp)) {
+ (void)dk4dbi_close_mem(back, NULL);
+ back = NULL;
+ }
+ }
+ } else {
+ (void)dk4dbi_close_mem(back, NULL);
+ back = NULL;
+ }
+ }
+ $? "- dk4dbi_open_mem %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+
+
+/** Close database, release resources.
+ NOTE: Only release in-memory specific things, the
+ dk4dbi_close() function calls dk4dbi_delete_base()
+ to release the base components.
+ @param db Database to close.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_SYNTAX<br>
+ if the database file name does not refer to a regular file,
+ - DK4_E_SEC_CHECK<br>
+ with failed check id in iDetails1 if access is denied by additional
+ security checks,
+ - DK4_E_OPEN_WRITE_FAILED<br>
+ with errno value in iDetails1 if fopen() or fwrite() failed,
+ - DK4_E_CLOSE_FAILED<br>
+ with errno value in iDetails1 if fclose() failed,
+ - DK4_E_WRITE_FAILD<br>
+ if fwrite() failed.
+*/
+static
+int
+dk4dbi_close_bdb(
+ dk4_dbi_t *db,
+ dk4_er_t *erp
+)
+{
+ int back = 1;
+ if (NULL != (db->dt).bdb.db) {
+ if ((0 != db->wa) && (0 != db->uc)) {
+ if (0 != ((db->dt).bdb.db)->sync((db->dt).bdb.db, 0)) {
+ back = 0;
+ }
+ }
+ ((db->dt).bdb.db)->close((db->dt).bdb.db, 0);
+ (db->dt).bdb.db = NULL;
+ }
+ return back;
+}
+
+
+
+/** Open BDB database.
+ @param fn File name.
+ @param wa Flag: Write access required.
+ @param tr Flag: Truncate existing database.
+ @param km Maximum key size.
+ @param vm Maximum value size.
+ @param erp Error report, may be NULL.
+ @return Pointer to new database structure on success, NULL on error.
+
+ Error codes:
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow when calculating size,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available,
+ - DK4_E_OPEN_WRITE_FAILED<br>
+ if the database can not be opened for writing,
+ - DK4_E_OPEN_READ_FAILED<br>
+ if the database can not be opened or reading,
+ - DK4_E_NOT_SUPPORTED<br>
+ when attempting to provide a wchar_t file name on
+ non-Windows systems.
+*/
+static
+dk4_dbi_t *
+dk4dbi_open_bdb(
+ const dkChar *fn,
+ int wa,
+ int tr,
+ size_t km,
+ size_t vm,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+#if DK4_ON_WINDOWS
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return NULL;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return NULL;
+#endif
+#else
+ dk4_dbi_t *back = NULL;
+ int res = 0;
+ int flags = 0;
+ $? "+ dk4dbi_open_bdb (char) \"%!ds\" %d %d", TR_STR(fn), wa, tr
+ back = dk4dbi_new_base(fn, DK4_DB_BE_BDB, wa, km, vm, erp);
+ if (NULL != back) {
+ if (0 != tr) {
+ (void)dk4delete_file(fn, NULL);
+ }
+ res = db_create(&((back->dt).bdb.db), NULL, 0);
+ if (0 == res) {
+ ((back->dt).bdb.db)->set_errfile((back->dt).bdb.db, NULL);
+ flags = ((0 != wa)
+ ? ((0 != tr) ? ((DB_CREATE) || (DB_TRUNCATE)) : (DB_CREATE))
+ : (DB_RDONLY));
+ res = ((back->dt).bdb.db)->open(
+ (back->dt).bdb.db, NULL, back->fn, NULL, DB_BTREE, flags, 0600
+ );
+ if (0 != res) {
+ ((back->dt).bdb.db)->close((back->dt).bdb.db, 0);
+ (back->dt).bdb.db = NULL;
+ dk4dbi_delete_base(back);
+ back = NULL;
+ dk4error_set_simple_error_code(
+ erp,
+ ((0 != wa) ? (DK4_E_OPEN_WRITE_FAILED) : (DK4_E_OPEN_READ_FAILED))
+ );
+ }
+ } else {
+ (back->dt).bdb.db = NULL;
+ dk4dbi_delete_base(back);
+ back = NULL;
+ dk4error_set_simple_error_code(
+ erp,
+ ((0 != wa) ? (DK4_E_OPEN_WRITE_FAILED) : (DK4_E_OPEN_READ_FAILED))
+ );
+ }
+ }
+ $? "- dk4dbi_open_bdb (char) %d", TR_IPTR(back)
+ return back;
+#endif
+}
+
+#endif
+/* if DK4_HAVE_DB_H */
+
+
+
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+
+
+
+/** Close database, release resources.
+ NOTE: Only release in-memory specific things, the
+ dk4dbi_close() function calls dk4dbi_delete_base()
+ to release the base components.
+ @param db Database to close.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_SYNTAX<br>
+ if the database file name does not refer to a regular file,
+ - DK4_E_SEC_CHECK<br>
+ with failed check id in iDetails1 if access is denied by additional
+ security checks,
+ - DK4_E_OPEN_WRITE_FAILED<br>
+ with errno value in iDetails1 if fopen() or fwrite() failed,
+ - DK4_E_CLOSE_FAILED<br>
+ with errno value in iDetails1 if fclose() failed,
+ - DK4_E_WRITE_FAILD<br>
+ if fwrite() failed.
+*/
+static
+int
+dk4dbi_close_ndbm(
+ dk4_dbi_t *db,
+ dk4_er_t *erp
+)
+{
+ int back = 1;
+ if (NULL != (db->dt).ndbm.dbm) {
+ dbm_close((db->dt).ndbm.dbm);
+ (db->dt).ndbm.dbm = NULL;
+ }
+ return back;
+}
+
+
+
+static
+void
+dk4dbi_truncate_ndbm(const dkChar *fn)
+{
+ dkChar buf[DK4_MAX_PATH];
+ const size_t szbuf = DK4_SIZEOF(buf,dkChar);
+
+ if (0 != dk4str_cpy_s(buf, szbuf, fn, NULL)) {
+ if (0 != dk4str_cat_s(buf, szbuf, dk4dbi_ndbm_suffixes[0], NULL)) {
+ (void)dk4delete_file(buf, NULL);
+ }
+ }
+ if (0 != dk4str_cpy_s(buf, szbuf, fn, NULL)) {
+ if (0 != dk4str_cat_s(buf, szbuf, dk4dbi_ndbm_suffixes[1], NULL)) {
+ (void)dk4delete_file(buf, NULL);
+ }
+ }
+}
+
+
+
+/** Open NDBM database.
+ @param fn File name.
+ @param wa Flag: Write access required.
+ @param tr Flag: Truncate existing database.
+ @param km Maximum key size.
+ @param vm Maximum value size.
+ @param erp Error report, may be NULL.
+ @return Pointer to new database structure on success, NULL on error.
+*/
+static
+dk4_dbi_t *
+dk4dbi_open_ndbm(
+ const dkChar *fn,
+ int wa,
+ int tr,
+ size_t km,
+ size_t vm,
+ dk4_er_t *erp
+)
+{
+ dk4_dbi_t *back = NULL;
+ int flags = 0; /* Flags for opening the DB */
+
+ $? "+ dk4dbi_open_ndbm \"%!ds\" %d %d", TR_STR(fn), wa, tr
+
+ if (0 != tr) {
+ dk4dbi_truncate_ndbm(fn);
+ }
+ back = dk4dbi_new_base(fn, DK4_DB_BE_NDBM, wa, km, vm, erp);
+ if (NULL != back) {
+ flags = O_CREAT
+ | ((0 != wa)
+ ? ((0 != tr) ? (O_RDWR | O_TRUNC) : (O_RDWR))
+ : (O_RDONLY));
+ (back->dt).ndbm.dbm = dbm_open(fn, flags, 0600);
+ if (NULL == (back->dt).ndbm.dbm) {
+ dk4dbi_delete_base(back);
+ back = NULL;
+ dk4error_set_simple_error_code(
+ erp,
+ ((0 != wa) ? (DK4_E_OPEN_WRITE_FAILED) : (DK4_E_OPEN_READ_FAILED))
+ );
+ }
+ }
+ $? "- dk4dbi_open_ndbm %!8s", TR_8PTR(back)
+ return back;
+}
+
+#endif
+/* if DK4_HAVE_NDBM_H */
+
+
+
+dk4_dbi_t *
+dk4dbi_open_with_type(
+ const dkChar *fn,
+ int tp,
+ int wa,
+ int tr,
+ size_t km,
+ size_t vm,
+ dk4_er_t *erp
+)
+{
+ dk4_dbi_t *back = NULL;
+ $? "+ dk4dbi_open_with_type \"%!ds\" tp=%d wa=%d tr=%d", TR_STR(fn), tp, wa, tr
+ if (NULL != fn) {
+ switch (tp) {
+ case DK4_DB_BE_MEMORY : {
+ back = dk4dbi_open_mem(fn, wa, tr, km, vm, erp);
+ } break;
+ case DK4_DB_BE_BDB : {
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+ back = dk4dbi_open_bdb(fn, wa, tr, km, vm, erp);
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_DB_BE_NDBM : {
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+ back = dk4dbi_open_ndbm(fn, wa, tr, km, vm, erp);
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4dbi_open_with_type %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+dk4_dbi_t *
+dk4dbi_open(
+ const dkChar *fn,
+ int wa,
+ int tr,
+ size_t km,
+ size_t vm,
+ dk4_er_t *erp
+)
+{
+ dk4_dbi_t *back = NULL;
+ dkChar *mycopy = NULL; /* Private copy of fn */
+ dkChar *colon = NULL; /* First colon in mycopy */
+ const dkChar *fnp = NULL; /* File name pointer */
+ int tp = DK4_DB_BE_MEMORY ; /* Database type */
+
+ $? "+ dk4dbi_open \"%!ds\" %d %d", TR_STR(fn), wa, tr
+ if (NULL != fn) {
+ mycopy = dk4str_dup(fn, erp);
+ if (NULL != mycopy) {
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+ tp = DK4_DB_BE_NDBM;
+#endif
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+ tp = DK4_DB_BE_BDB;
+#endif
+ fnp = fn;
+ colon = dk4str_chr(mycopy, dkT(':'));
+ if (NULL != colon) {
+ if (dkT(':') == colon[1]) {
+ fnp = &(colon[2]);
+ *colon = dkT('\0');
+ tp = dk4str_array_index(dk4dbi_type_names, mycopy, 0);
+ if (DK4_DB_BE_UNKNOWN == tp) {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ }
+ }
+ if (DK4_DB_BE_UNKNOWN != tp) {
+ back = dk4dbi_open_with_type(fnp, tp, wa, tr, km, vm, erp);
+ }
+ dk4mem_free(mycopy);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4dbi_open %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+const dkChar *
+dk4dbi_filename_part(const dkChar *filename)
+{
+ const dkChar *back = NULL;
+ if (NULL != filename) {
+ back = dk4str_chr(filename, dkT(':'));
+ if (NULL != back) {
+ back++;
+ if (dkT(':') == *back) {
+ back++;
+ } else {
+ back = filename;
+ }
+ } else {
+ back = filename;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4dbi_close(
+ dk4_dbi_t *db,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+ $? "+ dk4dbi_close %!8s", TR_8PTR(db)
+ if (NULL != db) {
+ switch (db->tp) {
+ case DK4_DB_BE_MEMORY : {
+ back = dk4dbi_close_mem(db, erp);
+ } break;
+ case DK4_DB_BE_BDB : {
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+ back = dk4dbi_close_bdb(db, erp);
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_DB_BE_NDBM : {
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+ back = dk4dbi_close_ndbm(db, erp);
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ }
+ dk4dbi_delete_base(db);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4dbi_close"
+ return back;
+}
+
+
+
+int
+dk4dbi_set_option(
+ dk4_dbi_t *db,
+ int opt,
+ int val
+)
+{
+ int back = 0;
+ if (NULL != db) {
+ switch (opt) {
+ case DK4_DB_OPT_RESET_KEY :
+ case DK4_DB_OPT_RESET_VALUE :
+ {
+ if (0 != val) {
+ db->op |= opt;
+ } else {
+ db->op &= (~(opt));
+ }
+ back = 1;
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4dbi_delete(
+ dk4_dbi_t *db,
+ const void *kp,
+ size_t ks,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+ DBT k; /* Key */
+#endif
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+ datum datk; /* Key */
+#endif
+ dk4_dbi_datum_t dat; /* Key for comparison */
+ dk4_dbi_datum_t *rp; /* Result found in db */
+
+ $? "+ dk4dbi_delete %!8s %!8s %lu", TR_8PTR(db), TR_8PTR(kp), (unsigned long)ks
+ if ((NULL != db) && (NULL != kp) && ((size_t)0UL < ks)) {
+ if ((0 != db->wa) && (((size_t)0UL == db->km) || (db->km >= ks))) {
+ switch (db->tp) {
+ case DK4_DB_BE_MEMORY : {
+ db->uc = 1;
+ dat.kd = (void *)kp; dat.ks = ks;
+ rp = (dk4_dbi_datum_t *)dk4sto_it_find_like(
+ (db->dt).mem.i, &dat, 0
+ );
+ if (NULL != rp) {
+ back = dk4sto_remove((db->dt).mem.s, rp, erp);
+ if (0 != back) {
+ if (0 == dk4dbi_datum_delete(rp, db->op)) {
+ back = 0;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } break;
+ case DK4_DB_BE_BDB : {
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+ if (NULL != (db->dt).bdb.db) {
+ db->uc = 1;
+ DK4_MEMRES(&k, sizeof(DBT));
+ k.data = (void *)kp; k.size = ks;
+ if (0 == ((db->dt).bdb.db)->del((db->dt).bdb.db, NULL, &k, 0)) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_DB_BE_NDBM : {
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+ if (NULL != (db->dt).ndbm.dbm) {
+ db->uc = 1;
+ DK4_MEMRES(&datk, sizeof(datum));
+ datk.dptr = (char *)kp; datk.dsize = ks;
+ if (0 == dbm_delete((db->dt).ndbm.dbm, datk)) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4dbi_delete %d", back
+ return back;
+}
+
+
+
+int
+dk4dbi_set(
+ dk4_dbi_t *db,
+ const void *kp,
+ size_t ks,
+ const void *vp,
+ size_t vs,
+ dk4_er_t *erp
+)
+{
+ dk4_dbi_datum_t dat; /* Key for comparison */
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+ DBT k; /* Key */
+ DBT v; /* Value */
+#endif
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+ datum datk; /* Key */
+ datum datv; /* Value */
+#endif
+ dk4_dbi_datum_t *rp = NULL; /* Result record */
+ char *nb = NULL; /* New value buffer */
+ int back = 0;
+
+ $? "+ dk4dbi_set %!8s %!8s %lu %!8s %lu", TR_8PTR(db), TR_8PTR(kp), (unsigned long)ks, TR_8PTR(vp), (unsigned long)vs
+ if ((NULL != db) && (NULL != kp) && ((size_t)0UL < ks)) { $? ". key ok"
+ if ((NULL != vp) && ((size_t)0UL < vs)) { $? ". set value"
+ if(
+ (((size_t)0UL == db->km) || (db->km >= ks))
+ && (((size_t)0UL == db->vm) || (db->vm >= vs))
+ && (0 != db->wa)
+ )
+ { $? ". key/value size ok"
+ switch (db->tp) {
+ case DK4_DB_BE_MEMORY : { $? ". type memory"
+ db->uc = 1;
+ dat.kd = (void *)kp; dat.ks = ks;
+ rp = (dk4_dbi_datum_t *)dk4sto_it_find_like(
+ (db->dt).mem.i, &dat, 0
+ );
+ if (NULL != rp) {
+ nb = dk4mem_new(char,vs,erp);
+ if (NULL != nb) {
+ back = 1;
+ if (NULL != rp->vd) {
+ if (0 != (DK4_DB_OPT_RESET_VALUE & (db->op))) {
+ if ((size_t)0UL < rp->vs) {
+ back = dk4mem_reset_secure(rp->vd, rp->vs, NULL);
+ }
+ }
+ dk4mem_free(rp->vd);
+ }
+ rp->vd = nb;
+ DK4_MEMCPY(rp->vd,vp,vs);
+ rp->vs = vs;
+ }
+ } else {
+ rp = dk4dbi_datum_new(ks, vs, erp);
+ if (NULL != rp) {
+ DK4_MEMCPY(rp->kd,kp,ks);
+ DK4_MEMCPY(rp->vd,vp,vs);
+ if (0 != dk4sto_add((db->dt).mem.s, rp, erp)) {
+ back = 1;
+ } else {
+ dk4dbi_datum_delete(rp, db->op);
+ }
+ }
+ }
+ } break;
+ case DK4_DB_BE_BDB : { $? ". type bdb"
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+ $? ". BDB supported"
+ if (NULL != (db->dt).bdb.db) { $? ". db open"
+ db->uc = 1;
+ DK4_MEMRES(&k, sizeof(DBT));
+ DK4_MEMRES(&v, sizeof(DBT));
+ k.data = (void *)kp; v.data = (void *)vp;
+ k.size = ks; v.size = vs;
+ $? ". delete existing entry, if exists"
+ ((db->dt).bdb.db)->del((db->dt).bdb.db, NULL, &k, 0);
+ DK4_MEMRES(&k, sizeof(DBT));
+ k.data = (void *)kp; k.size = ks;
+ $? ". set new entry"
+ if (0 == ((db->dt).bdb.db)->put((db->dt).bdb.db,NULL,&k,&v,0)) {
+ back = 1; $? ". success"
+ } else { $? "! put"
+ dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED);
+ }
+ } else { $? "! db not opened"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_DB_BE_NDBM : { $? ". type ndbm"
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+ if (NULL != (db->dt).ndbm.dbm) {
+ db->uc = 1;
+ DK4_MEMRES(&datk, sizeof(datum));
+ DK4_MEMRES(&datv, sizeof(datum));
+ datk.dptr = (char *)kp; datk.dsize = ks;
+ datv.dptr = (char *)vp; datv.dsize = vs;
+ if (0 == dbm_store((db->dt).ndbm.dbm, datk, datv, DBM_INSERT)) {
+ back = 1;
+ } else {
+ DK4_MEMRES(&datk, sizeof(datum));
+ DK4_MEMRES(&datv, sizeof(datum));
+ datk.dptr = (char *)kp; datk.dsize = ks;
+ datv.dptr = (char *)vp; datv.dsize = vs;
+ if (0 == dbm_store((db->dt).ndbm.dbm,datk,datv,DBM_REPLACE)) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ }
+ }
+ else
+ { $? "! key/value size too large"
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else { $? ". delete"
+ back = dk4dbi_delete(db, kp, ks, erp);
+ }
+ } else { $? "! arguments"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4dbi_set %d", back
+ return back;
+}
+
+
+
+int
+dk4dbi_sync(
+ dk4_dbi_t *db,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+ $? "+ dk4dbi_sync %!8s", TR_8PTR(db)
+ if (NULL != db) {
+ switch (db->tp) {
+ case DK4_DB_BE_MEMORY : {
+ if ((0 != db->wa) && (0 != db->uc)) {
+ back = dk4dbi_mem_to_file(db, erp);
+ } else {
+ back = 1;
+ }
+ } break;
+ case DK4_DB_BE_BDB : {
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+ if (NULL != (db->dt).bdb.db) {
+ if ((0 != db->wa) && (0 != db->uc)) {
+ if (0 == ((db->dt).bdb.db)->sync((db->dt).bdb.db, 0)) {
+ back = 1;
+ db->uc = 0;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED);
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_DB_BE_NDBM : {
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+ if (NULL != (db->dt).ndbm.dbm) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4dbi_sync %d", back
+ return back;
+}
+
+
+
+int
+dk4dbi_get(
+ dk4_dbi_t *db,
+ const void *kp,
+ size_t ks,
+ void *vp,
+ size_t *vs,
+ dk4_er_t *erp
+)
+{
+ dk4_dbi_datum_t dat; /* Key for comparison */
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+ DBT k; /* Key */
+ DBT v; /* Value */
+#endif
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+ datum datk; /* Key */
+ datum datv; /* Value */
+#endif
+ dk4_dbi_datum_t *rp; /* Search result pointer */
+ int back = 0;
+
+ $? "+ dk4dbi_get %!8s %!8s %lu %!8s %!8s", TR_8PTR(db), TR_8PTR(kp), (unsigned long)ks, TR_8PTR(vp), TR_8PTR(vs)
+ if (
+ (NULL != db) && (NULL != kp) && ((size_t)0 < ks)
+ && (NULL != vp) && (NULL != vs)
+ )
+ {
+ if ((size_t)0UL < *vs) {
+ if (((size_t)0UL == db->km) || (db->km >= ks)) {
+ switch (db->tp) {
+ case DK4_DB_BE_MEMORY : { $? ". type memory"
+ dat.kd = (void *)kp; dat.ks = ks;
+ rp = (dk4_dbi_datum_t *)dk4sto_it_find_like(
+ (db->dt).mem.i, &dat, 0
+ );
+ if (NULL != rp) {
+ if ((NULL != rp->vd) && ((size_t)0UL < rp->vs)) {
+ if (*vs >= rp->vs) {
+ DK4_MEMCPY(vp,rp->vd,rp->vs);
+ *vs = rp->vs;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } break;
+ case DK4_DB_BE_BDB : { $? ". type bdb"
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+ $? ". bdb supported"
+ if (NULL != (db->dt).bdb.db) { $? ". db open"
+ DK4_MEMRES(&k, sizeof(DBT));
+ DK4_MEMRES(&v, sizeof(DBT));
+ k.data = (void *)kp; k.size = ks;
+ v.data = (void *)vp; v.ulen = *vs; v.flags = DB_DBT_USERMEM;
+ if (0 == ((db->dt).bdb.db)->get((db->dt).bdb.db,NULL,&k,&v,0)) {
+ *vs = v.size; $? ". found"
+ back = 1;
+ } else { $? "! not found"
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else { $? "! db not opened"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+#else
+ $? "! bdb not supported"
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_DB_BE_NDBM : { $? ". type ndbm"
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+ if (NULL != (db->dt).ndbm.dbm) {
+ DK4_MEMRES(&datk, sizeof(datum));
+ DK4_MEMRES(&datv, sizeof(datum));
+ datk.dptr = (char *)kp; datk.dsize = ks;
+ datv = dbm_fetch((db->dt).ndbm.dbm, datk);
+ if ((NULL != datv.dptr) && (0 < datv.dsize)) {
+ if (*vs >= datv.dsize) {
+ DK4_MEMCPY(vp,datv.dptr,datv.dsize);
+ *vs = datv.dsize;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ }
+ } else { $? "! key size too long"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else { $? "! args (2)"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else { $? "! args (1)"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4dbi_get %d", back
+ return back;
+}
+
+
+
+int
+dk4dbi_traverse(
+ dk4_dbi_t *db,
+ void *obj,
+ dk4dbi_traverse_fct_t *fct
+)
+{
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+ DBT dbtk; /* Key */
+ DBT dbtv; /* Value */
+ DBC *cp = NULL; /* Cursor for traversal */
+#endif
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+ datum datk; /* Key */
+ datum datv; /* Value */
+#endif
+ dk4_dbi_datum_t *dddt = NULL; /* Pointer for traversal */
+ int res = 0; /* Operation result */
+ int first = 1; /* Flag: Retrieving first record */
+ int back = -1;
+
+ $? "+ dk4dbi_traverse db=%d obj=%d", TR_IPTR(db), TR_IPTR(obj)
+ if ((NULL != db) && (NULL != fct)) {
+ switch (db->tp) {
+ case DK4_DB_BE_MEMORY : {
+ back = 1;
+ dk4sto_it_reset((db->dt).mem.i);
+ do {
+ dddt = dk4sto_it_next((db->dt).mem.i);
+ if (NULL != dddt) {
+ res = (*fct)(obj, dddt->kd, dddt->ks, dddt->vd, dddt->vs);
+ if (res < back) { back = res; }
+ }
+ } while((NULL != dddt) && (-1 < back));
+ } break;
+ case DK4_DB_BE_BDB : {
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+ res = ((db->dt).bdb.db)->cursor((db->dt).bdb.db, NULL, &cp, 0);
+ if (0 == res) {
+ if (NULL != cp) {
+ back = 1;
+ DK4_MEMRES(&dbtk, sizeof(DBT));
+ DK4_MEMRES(&dbtv, sizeof(DBT));
+ do {
+#if DK4_HAVE_DB_CURSOR_C_GET
+ res = cp->c_get(
+ cp, &dbtk, &dbtv, ((0 != first) ? (DB_FIRST) : (DB_NEXT))
+ );
+#else
+ res = cp->get(
+ cp, &dbtk, &dbtv, ((0 != first) ? (DB_FIRST) : (DB_NEXT))
+ );
+#endif
+ first = 0;
+ if (0 == res) {
+ res = (*fct)(obj, dbtk.data, dbtk.size, dbtv.data, dbtv.size);
+ if (res < back) { back = res; }
+ } else {
+ res = -1; /* Failed to obtain a record, stop */
+ }
+ } while((-1 < res) && (-1 < back));
+ cp->c_close(cp);
+ } else { $? "! failed to create cursor"
+ }
+ } else { $? "! failed to create cursor"
+ }
+#endif
+ } break;
+ case DK4_DB_BE_NDBM : {
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+ back = 1;
+ do {
+ if (0 != first) {
+ datk = dbm_firstkey((db->dt).ndbm.dbm);
+ first = 0;
+ } else {
+ datk = dbm_nextkey((db->dt).ndbm.dbm);
+ }
+ if ((NULL != datk.dptr) && (0 < datk.dsize)) {
+ datv = dbm_fetch((db->dt).ndbm.dbm, datk);
+ if ((NULL != datv.dptr) && (0 < datv.dsize)) {
+ res = (*fct)(obj, datk.dptr, datk.dsize, datv.dptr, datv.dsize);
+ if (res < back) { back = res; }
+ } else {
+ res = -1;
+ }
+ } else {
+ res = -1;
+ }
+ } while((-1 < res) && (-1 < back));
+#endif
+ } break;
+ }
+ } $? "- dk4dbi_traverse %d", back
+ return back;
+}
+
+
+
+
+#if !DK4_ON_WINDOWS
+#if DK4_CHAR_SIZE == 1
+#if DK4_HAVE_CHOWN && DK4_HAVE_CHMOD
+
+/** Change ownership and mode for a file.
+ @param fn File name.
+ @param user New owner.
+ @param group New owner group.
+ @param mode New file permissions.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_SYSTEM<br>
+ with errno value in iDetails1 if chown
+ or chmod failed.
+*/
+static
+int
+dk4dbi_change_file_owner_and_mode(
+ const dkChar *fn,
+ uid_t user,
+ gid_t group,
+ mode_t mode,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+
+ $? "+ dk4dbi_change_file_owner_and_mode"
+ errno = 0;
+ if (0 == chown(fn, user, group)) {
+ errno = 0;
+ if (0 == chmod(fn, mode)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_SYSTEM, errno);
+ }
+ } else {
+ dk4error_set_idetails(erp, DK4_E_SYSTEM, errno);
+ } $? "- dk4dbi_change_file_owner_and_mode %d", back
+ return back;
+}
+
+
+int
+dk4dbi_change_owner_and_mode(
+ dk4_dbi_t *db,
+ uid_t user,
+ gid_t group,
+ mode_t mode,
+ dk4_er_t *erp
+)
+{
+ dkChar buf[DK4_MAX_PATH]; /* File names construction */
+ const size_t szbuf = DK4_SIZEOF(buf,dkChar); /* Buffer size */
+ int back = 0;
+
+ $? "+ dk4dbi_change_owner_and_mode"
+ if (NULL != db) {
+ switch (db->tp) {
+ case DK4_DB_BE_MEMORY :
+ case DK4_DB_BE_BDB :
+ {
+ back = dk4dbi_change_file_owner_and_mode(
+ db->fn, user, group, mode, erp
+ );
+ } break;
+ case DK4_DB_BE_NDBM : {
+ if (0 != dk4str_cpy_s(buf, szbuf, db->fn, erp)) {
+ if (0 != dk4str_cat_s(buf, szbuf, dk4dbi_ndbm_suffixes[0], erp)) {
+ back = dk4dbi_change_file_owner_and_mode(buf,user,group,mode,erp);
+ (void)dk4str_cpy_s(buf, szbuf, db->fn, erp);
+ if (0 != dk4str_cat_s(buf, szbuf, dk4dbi_ndbm_suffixes[1], erp)) {
+ if (0 ==
+ dk4dbi_change_file_owner_and_mode(buf,user,group,mode,erp)
+ )
+ {
+ back = 0;
+ }
+ }
+ }
+ }
+ } break;
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4dbi_change_owner_and_mode %d", back
+ return back;
+}
+
+#endif
+/* if DK4_HAVE_CHOWN && DK4_HAVE_CHMOD */
+#endif
+/* if DK4_CHAR_SIZE == 1 */
+#endif
+/* if !DK4_ON_WINDOWS */
+
+
+
+size_t
+dk4dbi_get_key_max(
+ const dk4_dbi_t *db,
+ dk4_er_t *erp
+)
+{
+ size_t back = 0;
+ $? "+ dk4dbi_get_key_max"
+ if (NULL != db) {
+ back = db->km;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4dbi_get_key_max %u", (unsigned)back
+ return back;
+}
+
+
+
+size_t
+dk4dbi_get_val_max(
+ const dk4_dbi_t *db,
+ dk4_er_t *erp
+)
+{
+ size_t back = 0;
+ $? "+ dk4dbi_get_val_max"
+ if (NULL != db) {
+ back = db->vm;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4dbi_get_val_max %u", (unsigned)back
+ return back;
+}
+
+
+
+int
+dk4dbi_get_type(const dk4_dbi_t *db)
+{
+ int back = DK4_DB_BE_UNKNOWN;
+ if (NULL != db) {
+ back = db->tp;
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4dbi.h b/support/dktools/dk4dbi.h
new file mode 100644
index 0000000000..2c1dd43d6a
--- /dev/null
+++ b/support/dktools/dk4dbi.h
@@ -0,0 +1,588 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4dbi.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4DBI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4DBI_H_INCLUDED 1
+
+
+#line 10 "dk4dbi.ctr"
+
+/** @file dk4dbi.h Interface to databases.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+#include <db.h>
+#endif
+
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+#ifndef NDBM_H_INCLUDED
+#include <ndbm.h>
+#define NDBM_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4STO_H_INCLUDED
+#include "dk4sto.h"
+#endif
+
+
+
+/** Backend types.
+*/
+enum {
+ /** No backend specified yet.
+ */
+ DK4_DB_BE_UNKNOWN = -1 ,
+
+ /** In-memory database.
+ */
+ DK4_DB_BE_MEMORY = 0 ,
+
+ /** Berkeley DB.
+ */
+ DK4_DB_BE_BDB = 1 ,
+
+ /** NDBM.
+ */
+ DK4_DB_BE_NDBM = 2
+};
+
+
+
+/** Options.
+*/
+enum {
+ /** Reset key data before releasing
+ memory.
+ */
+ DK4_DB_OPT_RESET_KEY = 1 ,
+
+ /** Reset value data before releasing
+ memory.
+ */
+ DK4_DB_OPT_RESET_VALUE = 2 ,
+};
+
+
+
+/** Details for an in-memory database.
+*/
+typedef struct {
+ dk4_sto_t *s; /**< Storage container. */
+ dk4_sto_it_t *i; /**< Storage iterator. */
+} dk4_dbi_mem_t;
+
+
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+/** Details for a Berkeley DB database.
+*/
+typedef struct {
+ DB *db; /**< DB structure. */
+} dk4_dbi_bdb_t;
+#endif
+
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+/** Details for an NDBM database.
+*/
+typedef struct {
+ DBM *dbm; /**< NDBM structure. */
+} dk4_dbi_ndbm_t;
+#endif
+
+/** Details for one backend.
+*/
+typedef union {
+ dk4_dbi_mem_t mem; /**< Details for in-memory database. */
+#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1)
+ dk4_dbi_bdb_t bdb; /**< Details for Berkeley DB. */
+#endif
+#if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1)
+ dk4_dbi_ndbm_t ndbm; /**< Details for NDBM. */
+#endif
+ int dummy; /**< Just to have a second component. */
+} dk4_dbi_det_t;
+
+/** Database structure.
+*/
+typedef struct {
+ dk4_dbi_det_t dt; /**< Backend-specific details. */
+ dkChar *fn; /**< File name. */
+ size_t km; /**< Maximum key size. */
+ size_t vm; /**< Maximum value size. */
+ int tp; /**< Backend type. */
+ int op; /**< Options. */
+ int wa; /**< Flag: Write access. */
+ int uc; /**< Flag: Have unsynchronized changes. */
+} dk4_dbi_t;
+
+/** Function to traverse a simple database.
+ The function must check the kb, ks, vb and vs arguments
+ for validity, they are passed as found by the backend
+ functions (this means pointers may be NULL, sizes may be 0).
+ @param Object modified during traversal, may be NULL.
+ @param kb Key data.
+ @param ks Key size.
+ @param vb Value data.
+ @param vs Value size.
+ @return 1 on success, 0 on error (can continue), -1 on error (abort).
+*/
+typedef
+int
+dk4dbi_traverse_fct_t(
+ void *obj,
+ const void *kb,
+ size_t ks,
+ const void *vb,
+ size_t vs
+);
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open database.
+ @param fn File name.
+ @param tp Backend type.
+ @param wa Flag: Write access required.
+ @param tr Flag: Truncate existing database
+ (only in conjunction with wa).
+ @param km Maximum key size (0 for unlimited).
+ @param vm Maximum value size (0 for unlimited).
+ The limits are used on all backends for writing,
+ on in-memory databases also for reading.
+ @param erp Error report, may be NULL.
+ @return Pointer to new database structure on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL or tp contains an invalid type number,
+ - DK4_E_NOT_SUPPORTED<br>
+ if the database type is not supported,
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow when calculating size,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available,
+ - DK4_E_SYNTAX<br>
+ if
+ - the database file name does not refer to a regular file
+ - or the file contents is not an in-memory database
+ - or key/value sizes in the file are in conflict with restrictions,
+ - DK4_E_SEC_CHECK<br>
+ with failed check id in iDetails1 if access is denied by additional
+ security checks,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available,
+ - DK4_E_OPEN_READ_FAILED<br>
+ if fopen() or fread() failed,
+ - DK4_E_OPEN_WRITE_FAILED<br>
+ if fopen() or fwrite() failed,
+ - DK4_E_CLOSE_FAILED<br>
+ with errno value in iDetails1 if fclose() failed.
+
+*/
+dk4_dbi_t *
+dk4dbi_open_with_type(
+ const dkChar *fn,
+ int tp,
+ int wa,
+ int tr,
+ size_t km,
+ size_t vm,
+ dk4_er_t *erp
+);
+
+/** Open database.
+ @param fn Database type and file name.
+ The database type is one from "mem", "bdb" or "ndbm".
+ Database type and file name are separated by two
+ colons "::".
+ @param wa Flag: Write access required.
+ @param tr Flag: Truncate existing database
+ (only in conjunction with wa).
+ @param km Maximum key size (0 for unlimited).
+ @param vm Maximum value size (0 for unlimited).
+ @param erp Error report, may be NULL.
+ @return Pointer to new database structure on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL or tp contains an invalid type number,
+ - DK4_E_NOT_SUPPORTED<br>
+ if the database type is not supported,
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow when calculating size,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available,
+ - DK4_E_SYNTAX<br>
+ if
+ - the specification contains an invalid backend type
+ - the database file name does not refer to a regular file
+ - or the file contents is not an in-memory database
+ - or key/value sizes in the file are in conflict with restrictions
+ - or an invalid database type was specified,
+ - DK4_E_SEC_CHECK<br>
+ with failed check id in iDetails1 if access is denied by additional
+ security checks,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available,
+ - DK4_E_OPEN_READ_FAILED<br>
+ if fopen() or fread() failed,
+ - DK4_E_OPEN_WRITE_FAILED<br>
+ if fopen() or fwrite() failed,
+ - DK4_E_CLOSE_FAILED<br>
+ with errno value in iDetails1 if fclose() failed.
+*/
+dk4_dbi_t *
+dk4dbi_open(
+ const dkChar *fn,
+ int wa,
+ int tr,
+ size_t km,
+ size_t vm,
+ dk4_er_t *erp
+);
+
+/** Find file name part from combined type/name.
+ @param filename Combined database type and file name.
+ @return Valid pointer to file name part on success, NULL on error.
+*/
+const dkChar *
+dk4dbi_filename_part(const dkChar *filename);
+
+/** Close database, release resources.
+ @param db Database to close.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if db is NULL,
+ - DK4_E_NOT_SUPPORTED<br>
+ if db indicates an unsupported backend type,
+ - DK4_E_SYNTAX<br>
+ if the database file name does not refer to a regular file,
+ - DK4_E_SEC_CHECK<br>
+ with failed check id in iDetails1 if access is denied by additional
+ security checks,
+ - DK4_E_OPEN_WRITE_FAILED<br>
+ with errno value in iDetails1 if fopen() or fwrite() failed,
+ - DK4_E_CLOSE_FAILED<br>
+ with errno value in iDetails1 if fclose() failed.
+*/
+int
+dk4dbi_close(
+ dk4_dbi_t *db,
+ dk4_er_t *erp
+);
+
+/** Set or reset option.
+ @param db Database.
+ @param opt Option.
+ @param val New value (1 or 0).
+ @return 1 on success, 0 on error (unknown option).
+*/
+int
+dk4dbi_set_option(
+ dk4_dbi_t *db,
+ int opt,
+ int val
+);
+
+/** Retrieve maximum key size.
+ @param db Database to query.
+ @param erp Error report, may be NULL.
+ @return Value on success (0 means unlimited),
+ 0 with erp set on error.
+
+ Error code:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if db is NULL.
+*/
+size_t
+dk4dbi_get_key_max(
+ const dk4_dbi_t *db,
+ dk4_er_t *erp
+);
+
+/** Retrieve maximum value size.
+ @param db Database to query.
+ @param erp Error report, may be NULL.
+ @return Value on success (0 means unlimited),
+ 0 with erp set on error.
+
+
+ Error code:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if db is NULL.
+*/
+size_t
+dk4dbi_get_val_max(
+ const dk4_dbi_t *db,
+ dk4_er_t *erp
+);
+
+/** Set or overwrite record.
+ @param db Database.
+ @param kp Pointer to key data.
+ @param ks Key data size (number of bytes).
+ @param vp Pointer to value data. Use NULL to delete a record.
+ @param vs Value data size (number of bytes).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if db or kp is NULL or ks is 0,
+ - DK4_E_SYNTAX<br>
+ if the database was opened read-only or ks or vs
+ exceeds a size limit,
+ - DK4_E_NOT_SUPPORTED<br>
+ if db indicates an unsupported backend,
+ - DK4_E_NOT_FOUND<br>
+ if no record to delete was found,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available,
+ - DK4_E_WRITE_FAILED<br>
+ if modification of the database failed.
+*/
+int
+dk4dbi_set(
+ dk4_dbi_t *db,
+ const void *kp,
+ size_t ks,
+ const void *vp,
+ size_t vs,
+ dk4_er_t *erp
+);
+
+/** Synchronize changes to file if supported by backend.
+ @param db Database.
+ @param erp error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if db or a backend component is NULL,
+ - DK4_E_NOT_SUPPORTED<br>
+ if db indicates an unsupported backend,
+ - DK4_E_SYNTAX<br>
+ if the database file name does not refer to a regular file,
+ - DK4_E_SEC_CHECK<br>
+ with failed check id in iDetails1 if access is denied by additional
+ security checks,
+ - DK4_E_OPEN_WRITE_FAILED<br>
+ with errno value in iDetails1 if fopen() or fwrite() failed,
+ - DK4_E_WRITE_FAILED<br>
+ if the backend failed to write to a database,
+ - DK4_E_CLOSE_FAILED<br>
+ with errno value in iDetails1 if fclose() failed.
+*/
+int
+dk4dbi_sync(
+ dk4_dbi_t *db,
+ dk4_er_t *erp
+);
+
+/** Retrieve record.
+ @param db Database.
+ @param kp Pointer to key data.
+ @param ks Key data size (number of bytes).
+ @param vp Address of result buffer.
+ @param vs Pointer to buffer size variable (in: size, out: used).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if db, kp, vp or vs is NULL or ks is 0 or *vs is 0
+ or ks exceeds the key size limit,
+ - DK4_E_NOT_SUPPORTED<br>
+ if db indicates an unsupported backend,
+ - DK4_E_NOT_FOUND<br>
+ if no record was found for the key,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the destination buffer is too small.
+*/
+int
+dk4dbi_get(
+ dk4_dbi_t *db,
+ const void *kp,
+ size_t ks,
+ void *vp,
+ size_t *vs,
+ dk4_er_t *erp
+);
+
+/** Delete one record.
+ @param db Database.
+ @param kp Pointer to key data.
+ @param ks Key data size (number of bytes).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if db or kp is NULL or ks is 0,
+ - DK4_E_SYNTAX<br>
+ if the database is opened read-only or ks exceeds the
+ key size limit,
+ - DK4_E_NOT_SUPPORTED<br>
+ if db indicates an unsupported backend,
+ - DK4_E_WRITE_FAILED<br>
+ if modification of the database failed,
+ - DK4_E_NOT_FOUND<br>
+ if no record for the specified key is in the database.
+*/
+int
+dk4dbi_delete(
+ dk4_dbi_t *db,
+ const void *kp,
+ size_t ks,
+ dk4_er_t *erp
+);
+
+/** Traverse database.
+ @param db Database to traverse.
+ @param obj Object to modify during traversal, may be NULL.
+ @param fct Function to execute for all records.
+ @return 1 on success, 0 on error (database traversed),
+ -1 on error (traversal aborted).
+*/
+int
+dk4dbi_traverse(
+ dk4_dbi_t *db,
+ void *obj,
+ dk4dbi_traverse_fct_t *fct
+);
+
+/** Retrieve backend type.
+ @param db Database to check.
+ @return Backend type.
+*/
+int
+dk4dbi_get_type(const dk4_dbi_t *db);
+
+#if !DK4_ON_WINDOWS
+#if DK4_CHAR_SIZE == 1
+#if DK4_HAVE_CHOWN && DK4_HAVE_CHMOD
+
+/** Change owner and mode for a database.
+ @param db Database to modify.
+ @param user New owner.
+ @param group New owner group.
+ @param mode New file permissions.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if db is NULL,
+ - DK4_E_NOT_SUPPORTED<br>
+ if db indicates an unsupported backend,
+ - DK4_E_SYSTEM<br>
+ with errno value in iDetails1 if a chown or chmod
+ system call failed,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in size calculation,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the file name is too large for an internal buffer.
+*/
+int
+dk4dbi_change_owner_and_mode(
+ dk4_dbi_t *db,
+ uid_t user,
+ gid_t group,
+ mode_t mode,
+ dk4_er_t *erp
+);
+
+#endif
+/* if DK4_HAVE_CHOWN && DK4_HAVE_CHMOD */
+#endif
+/* if DK4_CHAR_SIZE == 1 */
+#endif
+/* if !DK4_ON_WINDOWS */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4dbia.c b/support/dktools/dk4dbia.c
new file mode 100644
index 0000000000..e3cd6149a2
--- /dev/null
+++ b/support/dktools/dk4dbia.c
@@ -0,0 +1,231 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4dbia.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4dbia.c The dk4dbia module.
+*/
+
+
+#line 128 "dk4dbia.ctr"
+
+
+
+#include "dk4dbia.h"
+#include "dk4const.h"
+
+
+
+
+#line 136 "dk4dbia.ctr"
+
+
+
+/** Preference names we are using here.
+*/
+static const dkChar * const dk4dbi_pref_names[] = {
+/* 0 */
+dkT("db.key.max-size"),
+
+/* 1 */
+dkT("db.value.max-size"),
+
+NULL
+
+
+#line 146 "dk4dbia.ctr"
+};
+
+
+
+/** Constant texts used by the module, not localized.
+*/
+static const dkChar * const dk4dbia_kwnl[] = {
+/* 0 */
+dkT("dk4dbia.str"),
+
+NULL
+
+
+#line 159 "dk4dbia.ctr"
+};
+
+
+
+/** Constant texts used by the module, localized
+ texts are used if available.
+*/
+static const dkChar * const dk4dbia_kw_def[] = {
+/* 0 */
+dkT("Failed to open database!"),
+
+/* 1 */
+dkT("\nInvalid arguments were provided to the DB opening function."),
+
+/* 2 */
+dkT("\nThe database type is not supported."),
+
+/* 3 */
+dkT("\nMathematical overflow in size calculation."),
+
+/* 4 */
+dkT("\nInsufficient memory available."),
+
+/* 5 */
+dkT("\nSyntax error (database name, file type or file contents)."),
+
+/* 6 */
+dkT("\nInsufficient permissions."),
+
+/* 7 */
+dkT("\nFailed to open the file for read access."),
+
+/* 8 */
+dkT("\nFailed to open the file for write access."),
+
+/* 9 */
+dkT("\nFailed to close the file."),
+
+NULL
+
+
+#line 209 "dk4dbia.ctr"
+};
+
+
+
+dk4_dbi_t *
+dk4dbi_open_sizes_app(
+ const dkChar *fn,
+ int wa,
+ int tr,
+ size_t km,
+ size_t vm,
+ dk4_er_t *erp,
+ dk4_app_t *app
+)
+{
+ dk4_er_t er; /* Error report from dk4dbi_open */
+ const dkChar * parts[4]; /* Message parts array */
+ const dkChar * const *msg = NULL; /* Localized messages */
+ dk4_dbi_t *back = NULL; /* Result */
+ size_t szpts = 0; /* Number of elements in parts */
+
+ dk4error_init(&er);
+ back = dk4dbi_open(fn, wa, tr, km, vm, &er);
+ if (NULL == back) {
+ dk4error_copy(erp, &er);
+ if (NULL != app) {
+ msg = dk4app_string_table(app, dk4dbia_kwnl[0], dk4dbia_kw_def);
+ parts[0] = msg[0];
+ parts[1] = NULL;
+ szpts = 1;
+ switch (er.ec) {
+ case DK4_E_INVALID_ARGUMENTS : {
+ parts[1] = msg[1];
+ parts[2] = NULL;
+ szpts = 2;
+ } break;
+ case DK4_E_NOT_SUPPORTED : {
+ parts[1] = msg[2];
+ parts[2] = NULL;
+ szpts = 2;
+ } break;
+ case DK4_E_MATH_OVERFLOW : {
+ parts[1] = msg[3];
+ parts[2] = NULL;
+ szpts = 2;
+ } break;
+ case DK4_E_MEMORY_ALLOCATION_FAILED : {
+ parts[1] = msg[4];
+ parts[2] = NULL;
+ szpts = 2;
+ } break;
+ case DK4_E_SYNTAX : {
+ parts[1] = msg[5];
+ parts[2] = NULL;
+ szpts = 2;
+ } break;
+ case DK4_E_SEC_CHECK : {
+ parts[1] = msg[6];
+ parts[2] = NULL;
+ szpts = 2;
+ } break;
+ case DK4_E_OPEN_READ_FAILED : {
+ parts[1] = msg[7];
+ parts[2] = NULL;
+ szpts = 2;
+ } break;
+ case DK4_E_OPEN_WRITE_FAILED : {
+ parts[1] = msg[8];
+ parts[2] = NULL;
+ szpts = 2;
+ } break;
+ case DK4_E_CLOSE_FAILED : {
+ parts[1] = msg[9];
+ parts[2] = NULL;
+ szpts = 2;
+ } break;
+ }
+ if (0 < szpts) {
+ dk4app_log_msg(app, DK4_LL_ERROR, parts, szpts);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+dk4_dbi_t *
+dk4dbi_open_app(
+ const dkChar *fn,
+ int wa,
+ int tr,
+ dk4_er_t *erp,
+ dk4_app_t *app
+)
+{
+ size_t km = 0;
+ size_t vm = 0;
+
+ if (0 == dk4app_pref_get_size(&km, app, dk4dbi_pref_names[0], 0)) {
+ km = 0;
+ }
+ if (0 == dk4app_pref_get_size(&vm, app, dk4dbi_pref_names[1], 0)) {
+ vm = 0;
+ }
+ return (dk4dbi_open_sizes_app(fn, wa, tr, km, vm, erp, app));
+}
+
+
diff --git a/support/dktools/dk4dbia.ctr b/support/dktools/dk4dbia.ctr
new file mode 100644
index 0000000000..056ff0bb8f
--- /dev/null
+++ b/support/dktools/dk4dbia.ctr
@@ -0,0 +1,317 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+#ifndef DK4DBI_H_INCLUDED
+#include "dk4dbi.h"
+#endif
+
+#ifndef DK4APP_H_INCLUDED
+#include "dk4app.h"
+#endif
+
+/** Open database.
+ @param fn Database type and file name.
+ The database type is one from "mem", "bdb" or "ndbm".
+ Database type and file name are separated by two
+ colons "::".
+ @param wa Flag: Write access required.
+ @param tr Flag: Truncate existing database (only in conjunction
+ with wa).
+ @param erp Error report, may be NULL.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new database structure on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL or tp contains an invalid type number,
+ - DK4_E_NOT_SUPPORTED<br>
+ if the database type is not supported,
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow when calculating size,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available,
+ - DK4_E_SYNTAX<br>
+ if
+ - the specification contains an invalid backend type
+ - the database file name does not refer to a regular file
+ - or the file contents is not an in-memory database
+ - or key/value sizes in the file are in conflict with
+ size restrictions
+ - or an invalid database type was specified,
+ - DK4_E_SEC_CHECK<br>
+ with failed check id in iDetails1 if access is denied by additional
+ security checks,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available,
+ - DK4_E_OPEN_READ_FAILED<br>
+ if fopen() or fread() failed,
+ - DK4_E_OPEN_WRITE_FAILED<br>
+ if fopen() or fwrite() failed,
+ - DK4_E_CLOSE_FAILED<br>
+ with errno value in iDetails1 if fclose() failed.
+*/
+dk4_dbi_t *
+dk4dbi_open_app(
+ const dkChar *fn,
+ int wa,
+ int tr,
+ dk4_er_t *erp,
+ dk4_app_t *app
+);
+
+/** Open database.
+ @param fn Database type and file name.
+ The database type is one from "mem", "bdb" or "ndbm".
+ Database type and file name are separated by two
+ colons "::".
+ @param wa Flag: Write access required.
+ @param tr Flag: Truncate existing database (only in conjunction
+ with wa).
+ @param km Maximum key size.
+ @param vm Maximum value size.
+ @param erp Error report, may be NULL.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new database structure on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL or tp contains an invalid type number,
+ - DK4_E_NOT_SUPPORTED<br>
+ if the database type is not supported,
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow when calculating size,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available,
+ - DK4_E_SYNTAX<br>
+ if
+ - the specification contains an invalid backend type
+ - the database file name does not refer to a regular file
+ - or the file contents is not an in-memory database
+ - or key/value sizes in the file are in conflict with
+ size restrictions
+ - or an invalid database type was specified,
+ - DK4_E_SEC_CHECK<br>
+ with failed check id in iDetails1 if access is denied by additional
+ security checks,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available,
+ - DK4_E_OPEN_READ_FAILED<br>
+ if fopen() or fread() failed,
+ - DK4_E_OPEN_WRITE_FAILED<br>
+ if fopen() or fwrite() failed,
+ - DK4_E_CLOSE_FAILED<br>
+ with errno value in iDetails1 if fclose() failed.
+*/
+dk4_dbi_t *
+dk4dbi_open_sizes_app(
+ const dkChar *fn,
+ int wa,
+ int tr,
+ size_t km,
+ size_t vm,
+ dk4_er_t *erp,
+ dk4_app_t *app
+);
+
+%% module
+
+
+
+#include "dk4dbia.h"
+#include "dk4const.h"
+
+
+$!trace-include
+
+
+
+/** Preference names we are using here.
+*/
+static const dkChar * const dk4dbi_pref_names[] = {
+$!string-table macro=dkT
+db.key.max-size
+db.value.max-size
+$!end
+};
+
+
+
+/** Constant texts used by the module, not localized.
+*/
+static const dkChar * const dk4dbia_kwnl[] = {
+$!string-table macro=dkT
+#
+# 0 String table file name.
+#
+dk4dbia.str
+$!end
+};
+
+
+
+/** Constant texts used by the module, localized
+ texts are used if available.
+*/
+static const dkChar * const dk4dbia_kw_def[] = {
+$!string-table macro=dkT
+#
+# 0 Error: Failed to open database
+#
+Failed to open database!
+#
+# 1
+#
+\nInvalid arguments were provided to the DB opening function.
+#
+# 2
+#
+\nThe database type is not supported.
+#
+# 3
+#
+\nMathematical overflow in size calculation.
+#
+# 4
+#
+\nInsufficient memory available.
+#
+# 5
+#
+\nSyntax error (database name, file type or file contents).
+#
+# 6
+#
+\nInsufficient permissions.
+#
+# 7
+#
+\nFailed to open the file for read access.
+#
+# 8
+#
+\nFailed to open the file for write access.
+#
+# 9
+#
+\nFailed to close the file.
+$!end
+};
+
+
+
+dk4_dbi_t *
+dk4dbi_open_sizes_app(
+ const dkChar *fn,
+ int wa,
+ int tr,
+ size_t km,
+ size_t vm,
+ dk4_er_t *erp,
+ dk4_app_t *app
+)
+{
+ dk4_er_t er; /* Error report from dk4dbi_open */
+ const dkChar * parts[4]; /* Message parts array */
+ const dkChar * const *msg = NULL; /* Localized messages */
+ dk4_dbi_t *back = NULL; /* Result */
+ size_t szpts = 0; /* Number of elements in parts */
+
+ dk4error_init(&er);
+ back = dk4dbi_open(fn, wa, tr, km, vm, &er);
+ if (NULL == back) {
+ dk4error_copy(erp, &er);
+ if (NULL != app) {
+ msg = dk4app_string_table(app, dk4dbia_kwnl[0], dk4dbia_kw_def);
+ parts[0] = msg[0];
+ parts[1] = NULL;
+ szpts = 1;
+ switch (er.ec) {
+ case DK4_E_INVALID_ARGUMENTS : {
+ parts[1] = msg[1];
+ parts[2] = NULL;
+ szpts = 2;
+ } break;
+ case DK4_E_NOT_SUPPORTED : {
+ parts[1] = msg[2];
+ parts[2] = NULL;
+ szpts = 2;
+ } break;
+ case DK4_E_MATH_OVERFLOW : {
+ parts[1] = msg[3];
+ parts[2] = NULL;
+ szpts = 2;
+ } break;
+ case DK4_E_MEMORY_ALLOCATION_FAILED : {
+ parts[1] = msg[4];
+ parts[2] = NULL;
+ szpts = 2;
+ } break;
+ case DK4_E_SYNTAX : {
+ parts[1] = msg[5];
+ parts[2] = NULL;
+ szpts = 2;
+ } break;
+ case DK4_E_SEC_CHECK : {
+ parts[1] = msg[6];
+ parts[2] = NULL;
+ szpts = 2;
+ } break;
+ case DK4_E_OPEN_READ_FAILED : {
+ parts[1] = msg[7];
+ parts[2] = NULL;
+ szpts = 2;
+ } break;
+ case DK4_E_OPEN_WRITE_FAILED : {
+ parts[1] = msg[8];
+ parts[2] = NULL;
+ szpts = 2;
+ } break;
+ case DK4_E_CLOSE_FAILED : {
+ parts[1] = msg[9];
+ parts[2] = NULL;
+ szpts = 2;
+ } break;
+ }
+ if (0 < szpts) {
+ dk4app_log_msg(app, DK4_LL_ERROR, parts, szpts);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+dk4_dbi_t *
+dk4dbi_open_app(
+ const dkChar *fn,
+ int wa,
+ int tr,
+ dk4_er_t *erp,
+ dk4_app_t *app
+)
+{
+ size_t km = 0;
+ size_t vm = 0;
+
+ if (0 == dk4app_pref_get_size(&km, app, dk4dbi_pref_names[0], 0)) {
+ km = 0;
+ }
+ if (0 == dk4app_pref_get_size(&vm, app, dk4dbi_pref_names[1], 0)) {
+ vm = 0;
+ }
+ return (dk4dbi_open_sizes_app(fn, wa, tr, km, vm, erp, app));
+}
+
+
diff --git a/support/dktools/dk4dbia.h b/support/dktools/dk4dbia.h
new file mode 100644
index 0000000000..40e3cdec0e
--- /dev/null
+++ b/support/dktools/dk4dbia.h
@@ -0,0 +1,163 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4dbia.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4dbia.h Header file for the dk4dbia module.
+*/
+
+#ifndef DK4DBIA_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4DBIA_H_INCLUDED 1
+
+
+#line 10 "dk4dbia.ctr"
+
+#ifndef DK4DBI_H_INCLUDED
+#include "dk4dbi.h"
+#endif
+
+#ifndef DK4APP_H_INCLUDED
+#include "dk4app.h"
+#endif
+
+/** Open database.
+ @param fn Database type and file name.
+ The database type is one from "mem", "bdb" or "ndbm".
+ Database type and file name are separated by two
+ colons "::".
+ @param wa Flag: Write access required.
+ @param tr Flag: Truncate existing database (only in conjunction
+ with wa).
+ @param erp Error report, may be NULL.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new database structure on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL or tp contains an invalid type number,
+ - DK4_E_NOT_SUPPORTED<br>
+ if the database type is not supported,
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow when calculating size,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available,
+ - DK4_E_SYNTAX<br>
+ if
+ - the specification contains an invalid backend type
+ - the database file name does not refer to a regular file
+ - or the file contents is not an in-memory database
+ - or key/value sizes in the file are in conflict with
+ size restrictions
+ - or an invalid database type was specified,
+ - DK4_E_SEC_CHECK<br>
+ with failed check id in iDetails1 if access is denied by additional
+ security checks,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available,
+ - DK4_E_OPEN_READ_FAILED<br>
+ if fopen() or fread() failed,
+ - DK4_E_OPEN_WRITE_FAILED<br>
+ if fopen() or fwrite() failed,
+ - DK4_E_CLOSE_FAILED<br>
+ with errno value in iDetails1 if fclose() failed.
+*/
+dk4_dbi_t *
+dk4dbi_open_app(
+ const dkChar *fn,
+ int wa,
+ int tr,
+ dk4_er_t *erp,
+ dk4_app_t *app
+);
+
+/** Open database.
+ @param fn Database type and file name.
+ The database type is one from "mem", "bdb" or "ndbm".
+ Database type and file name are separated by two
+ colons "::".
+ @param wa Flag: Write access required.
+ @param tr Flag: Truncate existing database (only in conjunction
+ with wa).
+ @param km Maximum key size.
+ @param vm Maximum value size.
+ @param erp Error report, may be NULL.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new database structure on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL or tp contains an invalid type number,
+ - DK4_E_NOT_SUPPORTED<br>
+ if the database type is not supported,
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow when calculating size,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available,
+ - DK4_E_SYNTAX<br>
+ if
+ - the specification contains an invalid backend type
+ - the database file name does not refer to a regular file
+ - or the file contents is not an in-memory database
+ - or key/value sizes in the file are in conflict with
+ size restrictions
+ - or an invalid database type was specified,
+ - DK4_E_SEC_CHECK<br>
+ with failed check id in iDetails1 if access is denied by additional
+ security checks,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available,
+ - DK4_E_OPEN_READ_FAILED<br>
+ if fopen() or fread() failed,
+ - DK4_E_OPEN_WRITE_FAILED<br>
+ if fopen() or fwrite() failed,
+ - DK4_E_CLOSE_FAILED<br>
+ with errno value in iDetails1 if fclose() failed.
+*/
+dk4_dbi_t *
+dk4dbi_open_sizes_app(
+ const dkChar *fn,
+ int wa,
+ int tr,
+ size_t km,
+ size_t vm,
+ dk4_er_t *erp,
+ dk4_app_t *app
+);
+
+
+#endif
diff --git a/support/dktools/dk4dbit.c b/support/dktools/dk4dbit.c
new file mode 100644
index 0000000000..77cab17514
--- /dev/null
+++ b/support/dktools/dk4dbit.c
@@ -0,0 +1,121 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4dbit.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4dbit.c The dk4dbit module.
+*/
+
+
+#line 152 "dk4dbit.ctr"
+
+#include "dk4conf.h"
+
+#include "dk4dbit8.h"
+#include "dk4dbitw.h"
+#include "dk4dbit.h"
+
+
+
+
+
+
+#line 163 "dk4dbit.ctr"
+
+
+int
+dk4dbi_text_set(
+ dk4_dbi_t *db,
+ const dkChar *k,
+ const dkChar *v,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4dbi_wc_set(db, k, v, erp));
+#else
+ return (dk4dbi_c8_set(db, k, v, erp));
+#endif
+}
+
+
+
+int
+dk4dbi_text_get(
+ dk4_dbi_t *db,
+ const dkChar *k,
+ dkChar *vbuf,
+ size_t vsz,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4dbi_wc_get(db, k, vbuf, vsz, erp));
+#else
+ return (dk4dbi_c8_get(db, k, vbuf, vsz, erp));
+#endif
+}
+
+
+
+int
+dk4dbi_text_del(
+ dk4_dbi_t *db,
+ const dkChar *k,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4dbi_wc_del(db, k, erp));
+#else
+ return (dk4dbi_c8_del(db, k, erp));
+#endif
+}
+
+
+
+int
+dk4dbi_text_traverse(
+ dk4_dbi_t *db,
+ void *obj,
+ dk4dbi_text_traverse_fct *fct
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4dbi_wc_traverse(db, obj, fct));
+#else
+ return (dk4dbi_c8_traverse(db, obj, fct));
+#endif
+}
+
+
diff --git a/support/dktools/dk4dbit.ctr b/support/dktools/dk4dbit.ctr
new file mode 100644
index 0000000000..bc248ee309
--- /dev/null
+++ b/support/dktools/dk4dbit.ctr
@@ -0,0 +1,230 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk4dbit.h Text (dkChar) in database.
+*/
+
+#ifndef DK4DBI_H_INCLUDED
+#include <dk4dbi.h>
+#endif
+
+#ifndef DK4DBIT8_H_INCLUDED
+#include <dk4dbit8.h>
+#endif
+
+#ifndef DK4DBITW_H_INCLUDED
+#include <dk4dbitw.h>
+#endif
+
+#if DK4_CHAR_SIZE > 1
+/** Function to traverse text database.
+*/
+typedef dk4dbi_wc_traverse_fct_t dk4dbi_text_traverse_fct;
+#else
+/** Function to traverse text database.
+*/
+typedef dk4dbi_c8_traverse_fct_t dk4dbi_text_traverse_fct;
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Set text entry.
+ @param db Database to modify.
+ @param k Key text.
+ @param v Value text.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if db, k or vis NULL,
+ - DK4_E_SYNTAX<br>
+ if the database was opened read-only or k or v
+ is too long.
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow in size calculation,
+ - DK4_E_NOT_SUPPORTED<br>
+ if db indicates an unsupported backend,
+ - DK4_E_NOT_FOUND<br>
+ if no record to delete was found,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available,
+ - DK4_E_WRITE_FAILED<br>
+ if modification of the database failed.
+*/
+int
+dk4dbi_text_set(
+ dk4_dbi_t *db,
+ const dkChar *k,
+ const dkChar *v,
+ dk4_er_t *erp
+);
+
+/** Retrieve text entry.
+ @param db Database to query.
+ @param k Key text.
+ @param vbuf Result buffer address.
+ @param vsz Pointer to size variable (in: size, out: used),
+ number of dkChar.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if db, k or vbufis NULL or vsz is 0,
+ or the length of k exceeds the key size limit,
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow in size calculation,
+ - DK4_E_NOT_SUPPORTED<br>
+ if db indicates an unsupported backend,
+ - DK4_E_NOT_FOUND<br>
+ if no record was found for the key,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the destination buffer is too small.
+*/
+int
+dk4dbi_text_get(
+ dk4_dbi_t *db,
+ const dkChar *k,
+ dkChar *vbuf,
+ size_t vsz,
+ dk4_er_t *erp
+);
+
+/** Delete text entry.
+ @param db Database to modify.
+ @param k Key text.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if db or k is NULL,
+ - DK4_E_SYNTAX<br>
+ if the database is opened read-only or the length of
+ k exceeds the key size limit,
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow in size calculation,
+ - DK4_E_NOT_SUPPORTED<br>
+ if db indicates an unsupported backend,
+ - DK4_E_WRITE_FAILED<br>
+ if modification of the database failed,
+ - DK4_E_NOT_FOUND<br>
+ if no record for the specified key is in the database.
+*/
+int
+dk4dbi_text_del(
+ dk4_dbi_t *db,
+ const dkChar *k,
+ dk4_er_t *erp
+);
+
+/** Traverse database, apply function to all text entries.
+ @param db Database to traverse.
+ @param obj Object to modify during traversal.
+ @param fct Function to apply to all text entries.
+ @return 1 on success, 0 on error (database traversed),
+ -1 on error (traversal aborted).
+*/
+int
+dk4dbi_text_traverse(
+ dk4_dbi_t *db,
+ void *obj,
+ dk4dbi_text_traverse_fct *fct
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4conf.h"
+
+#include "dk4dbit8.h"
+#include "dk4dbitw.h"
+#include "dk4dbit.h"
+
+
+
+
+$!trace-include
+
+
+int
+dk4dbi_text_set(
+ dk4_dbi_t *db,
+ const dkChar *k,
+ const dkChar *v,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4dbi_wc_set(db, k, v, erp));
+#else
+ return (dk4dbi_c8_set(db, k, v, erp));
+#endif
+}
+
+
+
+int
+dk4dbi_text_get(
+ dk4_dbi_t *db,
+ const dkChar *k,
+ dkChar *vbuf,
+ size_t vsz,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4dbi_wc_get(db, k, vbuf, vsz, erp));
+#else
+ return (dk4dbi_c8_get(db, k, vbuf, vsz, erp));
+#endif
+}
+
+
+
+int
+dk4dbi_text_del(
+ dk4_dbi_t *db,
+ const dkChar *k,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4dbi_wc_del(db, k, erp));
+#else
+ return (dk4dbi_c8_del(db, k, erp));
+#endif
+}
+
+
+
+int
+dk4dbi_text_traverse(
+ dk4_dbi_t *db,
+ void *obj,
+ dk4dbi_text_traverse_fct *fct
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4dbi_wc_traverse(db, obj, fct));
+#else
+ return (dk4dbi_c8_traverse(db, obj, fct));
+#endif
+}
+
+
diff --git a/support/dktools/dk4dbit.h b/support/dktools/dk4dbit.h
new file mode 100644
index 0000000000..dd2f44d808
--- /dev/null
+++ b/support/dktools/dk4dbit.h
@@ -0,0 +1,184 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4dbit.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4DBIT_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4DBIT_H_INCLUDED 1
+
+
+#line 10 "dk4dbit.ctr"
+
+/** @file dk4dbit.h Text (dkChar) in database.
+*/
+
+#ifndef DK4DBI_H_INCLUDED
+#include <dk4dbi.h>
+#endif
+
+#ifndef DK4DBIT8_H_INCLUDED
+#include <dk4dbit8.h>
+#endif
+
+#ifndef DK4DBITW_H_INCLUDED
+#include <dk4dbitw.h>
+#endif
+
+#if DK4_CHAR_SIZE > 1
+/** Function to traverse text database.
+*/
+typedef dk4dbi_wc_traverse_fct_t dk4dbi_text_traverse_fct;
+#else
+/** Function to traverse text database.
+*/
+typedef dk4dbi_c8_traverse_fct_t dk4dbi_text_traverse_fct;
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Set text entry.
+ @param db Database to modify.
+ @param k Key text.
+ @param v Value text.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if db, k or vis NULL,
+ - DK4_E_SYNTAX<br>
+ if the database was opened read-only or k or v
+ is too long.
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow in size calculation,
+ - DK4_E_NOT_SUPPORTED<br>
+ if db indicates an unsupported backend,
+ - DK4_E_NOT_FOUND<br>
+ if no record to delete was found,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available,
+ - DK4_E_WRITE_FAILED<br>
+ if modification of the database failed.
+*/
+int
+dk4dbi_text_set(
+ dk4_dbi_t *db,
+ const dkChar *k,
+ const dkChar *v,
+ dk4_er_t *erp
+);
+
+/** Retrieve text entry.
+ @param db Database to query.
+ @param k Key text.
+ @param vbuf Result buffer address.
+ @param vsz Pointer to size variable (in: size, out: used),
+ number of dkChar.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if db, k or vbufis NULL or vsz is 0,
+ or the length of k exceeds the key size limit,
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow in size calculation,
+ - DK4_E_NOT_SUPPORTED<br>
+ if db indicates an unsupported backend,
+ - DK4_E_NOT_FOUND<br>
+ if no record was found for the key,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the destination buffer is too small.
+*/
+int
+dk4dbi_text_get(
+ dk4_dbi_t *db,
+ const dkChar *k,
+ dkChar *vbuf,
+ size_t vsz,
+ dk4_er_t *erp
+);
+
+/** Delete text entry.
+ @param db Database to modify.
+ @param k Key text.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if db or k is NULL,
+ - DK4_E_SYNTAX<br>
+ if the database is opened read-only or the length of
+ k exceeds the key size limit,
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow in size calculation,
+ - DK4_E_NOT_SUPPORTED<br>
+ if db indicates an unsupported backend,
+ - DK4_E_WRITE_FAILED<br>
+ if modification of the database failed,
+ - DK4_E_NOT_FOUND<br>
+ if no record for the specified key is in the database.
+*/
+int
+dk4dbi_text_del(
+ dk4_dbi_t *db,
+ const dkChar *k,
+ dk4_er_t *erp
+);
+
+/** Traverse database, apply function to all text entries.
+ @param db Database to traverse.
+ @param obj Object to modify during traversal.
+ @param fct Function to apply to all text entries.
+ @return 1 on success, 0 on error (database traversed),
+ -1 on error (traversal aborted).
+*/
+int
+dk4dbi_text_traverse(
+ dk4_dbi_t *db,
+ void *obj,
+ dk4dbi_text_traverse_fct *fct
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4dbit8.c b/support/dktools/dk4dbit8.c
new file mode 100644
index 0000000000..db5cf12602
--- /dev/null
+++ b/support/dktools/dk4dbit8.c
@@ -0,0 +1,292 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4dbit8.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4dbit8.c The dk4dbit8 module.
+*/
+
+
+#line 147 "dk4dbit8.ctr"
+
+#include "dk4conf.h"
+
+#include "dk4str8.h"
+#include "dk4dbit8.h"
+#include "dk4maasz.h"
+
+
+
+
+
+#line 157 "dk4dbit8.ctr"
+
+
+
+/** Object for database traversal.
+*/
+typedef struct {
+ void *obj; /**< Object for string traversal. */
+ dk4dbi_c8_traverse_fct_t *fct; /**< String traversal function. */
+} dk4dbi_c8_traversal_object_t;
+
+
+
+int
+dk4dbi_c8_del(
+ dk4_dbi_t *db,
+ const char *k,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er; /* Internal error report for size calc */
+ size_t ks = 0; /* Key size */
+ int back = 0;
+
+
+#line 180 "dk4dbit8.ctr"
+ if ((NULL != db) && (NULL != k)) {
+ dk4error_init(&er);
+ ks = dk4ma_size_t_add(1, dk4str8_len(k), &er);
+ if (DK4_E_NONE == er.ec) {
+ back = dk4dbi_delete(db, k, ks, erp);
+ } else {
+ dk4error_copy(erp, &er);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 191 "dk4dbit8.ctr"
+ return back;
+}
+
+
+
+int
+dk4dbi_c8_set(
+ dk4_dbi_t *db,
+ const char *k,
+ const char *v,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er; /* Internal error report for size calc */
+ size_t ks = 0; /* Key size */
+ size_t vs = 0; /* Value size */
+ int back = 0;
+
+
+#line 209 "dk4dbit8.ctr"
+ if ((NULL != db) && (NULL != k)) {
+
+#line 210 "dk4dbit8.ctr"
+ if (NULL != v) {
+
+#line 211 "dk4dbit8.ctr"
+ dk4error_init(&er);
+ ks = dk4ma_size_t_add(1, dk4str8_len(k), &er);
+ vs = dk4ma_size_t_add(1, dk4str8_len(v), &er);
+ if (DK4_E_NONE == er.ec) {
+
+#line 215 "dk4dbit8.ctr"
+ back = dk4dbi_set(db, k, ks, v, vs, erp);
+ } else {
+
+#line 217 "dk4dbit8.ctr"
+ dk4error_copy(erp, &er);
+ }
+ } else {
+
+#line 220 "dk4dbit8.ctr"
+ back = dk4dbi_c8_del(db, k, erp);
+ }
+ } else {
+
+#line 223 "dk4dbit8.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 225 "dk4dbit8.ctr"
+ return back;
+}
+
+
+
+int
+dk4dbi_c8_get(
+ dk4_dbi_t *db,
+ const char *k,
+ char *vbuf,
+ size_t vsz,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er; /* Internal error report for size calc */
+ size_t ks = 0; /* Key size */
+ size_t ressz = 0; /* Result size */
+ int back = 0;
+
+
+
+#line 245 "dk4dbit8.ctr"
+ if ((NULL != vbuf) && (0 < vsz)) { *vbuf = '\0'; }
+ if ((NULL != db) && (NULL != k) && (NULL != vbuf) && (0 < vsz)) {
+ dk4error_init(&er);
+
+#line 248 "dk4dbit8.ctr"
+ ressz = vsz;
+ ks = dk4ma_size_t_add(1, dk4str8_len(k), &er);
+ if (DK4_E_NONE == er.ec) {
+
+#line 251 "dk4dbit8.ctr"
+ if (0 != dk4dbi_get(db, k, ks, vbuf, &ressz, erp)) {
+
+#line 252 "dk4dbit8.ctr"
+ if (0 < ressz) {
+
+#line 253 "dk4dbit8.ctr"
+ if ('\0' == vbuf[ressz - 1]) {
+ back = 1;
+
+#line 255 "dk4dbit8.ctr"
+ } else {
+ if (ressz < vsz) {
+ vbuf[ressz] = '\0';
+ back = 1;
+
+#line 259 "dk4dbit8.ctr"
+ } else {
+
+#line 260 "dk4dbit8.ctr"
+ *vbuf = '\0';
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ }
+ } else {
+
+#line 265 "dk4dbit8.ctr"
+ *vbuf = '\0';
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 271 "dk4dbit8.ctr"
+ }
+#endif
+ } else {
+
+#line 274 "dk4dbit8.ctr"
+ dk4error_copy(erp, &er);
+ }
+ } else {
+
+#line 277 "dk4dbit8.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 279 "dk4dbit8.ctr"
+ return back;
+}
+
+
+
+/** Function to traverse a simple database.
+ The function must check the kb, ks, vb and vs arguments
+ for validity, they are passed as found by the backend
+ functions (this means pointers may be NULL, sizes may be 0).
+ @param Object modified during traversal, may be NULL.
+ @param kb Key data.
+ @param ks Key size.
+ @param vb Value data.
+ @param vs Value size.
+ @return 1 on success, 0 on error (can continue), -1 on error (abort).
+*/
+static
+int
+dk4dbi_c8_internal_traverse(
+ void *obj,
+ const void *kb,
+ size_t ks,
+ const void *vb,
+ size_t vs
+)
+{
+ dk4dbi_c8_traversal_object_t *myobj; /* Passed from dk4dbi_traverse() */
+ const char *pk; /* Key pointer */
+ const char *pv; /* Value pointer */
+ int back = 0;
+
+
+#line 310 "dk4dbit8.ctr"
+ if ((NULL != obj) && (NULL != kb) && (NULL != vb) && (0 < ks) && (0 < vs)) {
+ pk = (const char *)kb;
+ pv = (const char *)vb;
+ if (('\0' == pk[ks - 1]) && ('\0' == pv[vs - 1])) {
+ myobj = (dk4dbi_c8_traversal_object_t *)obj;
+ back = (*(myobj->fct))(myobj->obj, pk, pv);
+ }
+ }
+
+#line 318 "dk4dbit8.ctr"
+ return back;
+}
+
+
+
+int
+dk4dbi_c8_traverse(
+ dk4_dbi_t *db,
+ void *obj,
+ dk4dbi_c8_traverse_fct_t *fct
+)
+{
+ dk4dbi_c8_traversal_object_t myobj; /* Passed to dk4dbi_traverse */
+ int back = -1;
+
+
+
+#line 334 "dk4dbit8.ctr"
+ if ((NULL != db) && (NULL != fct)) {
+ myobj.obj = obj;
+ myobj.fct = fct;
+ back = dk4dbi_traverse(db, &myobj, dk4dbi_c8_internal_traverse);
+ }
+
+#line 339 "dk4dbit8.ctr"
+ return back;
+}
+
+
diff --git a/support/dktools/dk4dbit8.ctr b/support/dktools/dk4dbit8.ctr
new file mode 100644
index 0000000000..2b51c1a52f
--- /dev/null
+++ b/support/dktools/dk4dbit8.ctr
@@ -0,0 +1,342 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk4dbit8.h Text in database.
+*/
+
+#ifndef DK4DBI_H_INCLUDED
+#include <dk4dbi.h>
+#endif
+
+/** Traverse simple database containing text.
+ @param obj Object to modify during traversal.
+ @param k Key text.
+ @param v Value text.
+ @return 1 on success, 0 on error (continue traversal),
+ -1 on error (abort).
+*/
+typedef
+int
+dk4dbi_c8_traverse_fct_t(
+ void *obj,
+ const char *k,
+ const char *v
+);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Set text entry.
+ @param db Database to modify.
+ @param k Key text.
+ @param v Value text.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if db, k or vis NULL,
+ - DK4_E_SYNTAX<br>
+ if the database was opened read-only or k or v
+ is too long.
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow in size calculation,
+ - DK4_E_NOT_SUPPORTED<br>
+ if db indicates an unsupported backend,
+ - DK4_E_NOT_FOUND<br>
+ if no record to delete was found,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available,
+ - DK4_E_WRITE_FAILED<br>
+ if modification of the database failed.
+*/
+int
+dk4dbi_c8_set(
+ dk4_dbi_t *db,
+ const char *k,
+ const char *v,
+ dk4_er_t *erp
+);
+
+/** Retrieve text entry.
+ @param db Database to query.
+ @param k Key text.
+ @param vbuf Result buffer address.
+ @param vsz Pointer to size variable (in: size, out: used).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if db, k or vbufis NULL or vsz is 0,
+ or the length of k exceeds the key size limit,
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow in size calculation,
+ - DK4_E_NOT_SUPPORTED<br>
+ if db indicates an unsupported backend,
+ - DK4_E_NOT_FOUND<br>
+ if no record was found for the key,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the destination buffer is too small.
+*/
+int
+dk4dbi_c8_get(
+ dk4_dbi_t *db,
+ const char *k,
+ char *vbuf,
+ size_t vsz,
+ dk4_er_t *erp
+);
+
+/** Delete text entry.
+ @param db Database to modify.
+ @param k Key text.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if db or k is NULL,
+ - DK4_E_SYNTAX<br>
+ if the database is opened read-only or the length of
+ k exceeds the key size limit,
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow in size calculation,
+ - DK4_E_NOT_SUPPORTED<br>
+ if db indicates an unsupported backend,
+ - DK4_E_WRITE_FAILED<br>
+ if modification of the database failed,
+ - DK4_E_NOT_FOUND<br>
+ if no record for the specified key is in the database.
+*/
+int
+dk4dbi_c8_del(
+ dk4_dbi_t *db,
+ const char *k,
+ dk4_er_t *erp
+);
+
+/** Traverse database, apply function to all text entries.
+ @param db Database to traverse.
+ @param obj Object to modify during traversal.
+ @param fct Function to apply to all text entries.
+ @return 1 on success, 0 on error (database traversed),
+ -1 on error (traversal aborted).
+*/
+int
+dk4dbi_c8_traverse(
+ dk4_dbi_t *db,
+ void *obj,
+ dk4dbi_c8_traverse_fct_t *fct
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4conf.h"
+
+#include "dk4str8.h"
+#include "dk4dbit8.h"
+#include "dk4maasz.h"
+
+
+
+$!trace-include
+
+
+
+/** Object for database traversal.
+*/
+typedef struct {
+ void *obj; /**< Object for string traversal. */
+ dk4dbi_c8_traverse_fct_t *fct; /**< String traversal function. */
+} dk4dbi_c8_traversal_object_t;
+
+
+
+int
+dk4dbi_c8_del(
+ dk4_dbi_t *db,
+ const char *k,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er; /* Internal error report for size calc */
+ size_t ks = 0; /* Key size */
+ int back = 0;
+ $? "+ dk4dbi_c8_del \"%!8s\"", TR_8STR(k)
+ if ((NULL != db) && (NULL != k)) {
+ dk4error_init(&er);
+ ks = dk4ma_size_t_add(1, dk4str8_len(k), &er);
+ if (DK4_E_NONE == er.ec) {
+ back = dk4dbi_delete(db, k, ks, erp);
+ } else {
+ dk4error_copy(erp, &er);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4dbi_c8_del %d", back
+ return back;
+}
+
+
+
+int
+dk4dbi_c8_set(
+ dk4_dbi_t *db,
+ const char *k,
+ const char *v,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er; /* Internal error report for size calc */
+ size_t ks = 0; /* Key size */
+ size_t vs = 0; /* Value size */
+ int back = 0;
+ $? "+ dk4dbi_c8_set \"%!8s\"=\"%!8s\"", TR_8STR(k), TR_8STR(v)
+ if ((NULL != db) && (NULL != k)) { $? ". args ok"
+ if (NULL != v) { $? ". new value"
+ dk4error_init(&er);
+ ks = dk4ma_size_t_add(1, dk4str8_len(k), &er);
+ vs = dk4ma_size_t_add(1, dk4str8_len(v), &er);
+ if (DK4_E_NONE == er.ec) { $? ". lengths ok"
+ back = dk4dbi_set(db, k, ks, v, vs, erp);
+ } else { $? "! key or value too long"
+ dk4error_copy(erp, &er);
+ }
+ } else { $? ". delete"
+ back = dk4dbi_c8_del(db, k, erp);
+ }
+ } else { $? "! args"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4dbi_c8_set %d", back
+ return back;
+}
+
+
+
+int
+dk4dbi_c8_get(
+ dk4_dbi_t *db,
+ const char *k,
+ char *vbuf,
+ size_t vsz,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er; /* Internal error report for size calc */
+ size_t ks = 0; /* Key size */
+ size_t ressz = 0; /* Result size */
+ int back = 0;
+
+ $? "+ dk4dbi_c8_get \"%!8s\"", TR_8STR(k)
+ if ((NULL != vbuf) && (0 < vsz)) { *vbuf = '\0'; }
+ if ((NULL != db) && (NULL != k) && (NULL != vbuf) && (0 < vsz)) {
+ dk4error_init(&er); $? ". args ok"
+ ressz = vsz;
+ ks = dk4ma_size_t_add(1, dk4str8_len(k), &er);
+ if (DK4_E_NONE == er.ec) { $? ". name length ok"
+ if (0 != dk4dbi_get(db, k, ks, vbuf, &ressz, erp)) { $? ". found"
+ if (0 < ressz) { $? ". length ok"
+ if ('\0' == vbuf[ressz - 1]) {
+ back = 1; $? ". result=\"%!8s\"", vbuf
+ } else {
+ if (ressz < vsz) {
+ vbuf[ressz] = '\0';
+ back = 1; $? ". result=\"%!8s\"", vbuf
+ } else { $? "! not terminated, too long"
+ *vbuf = '\0';
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ }
+ } else { $? "! zero length"
+ *vbuf = '\0';
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ }
+#if TRACE_DEBUG
+ else { $? "! not found"
+ }
+#endif
+ } else { $? "! name too long"
+ dk4error_copy(erp, &er);
+ }
+ } else { $? "! args"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4dbi_c8_get %d", back
+ return back;
+}
+
+
+
+/** Function to traverse a simple database.
+ The function must check the kb, ks, vb and vs arguments
+ for validity, they are passed as found by the backend
+ functions (this means pointers may be NULL, sizes may be 0).
+ @param Object modified during traversal, may be NULL.
+ @param kb Key data.
+ @param ks Key size.
+ @param vb Value data.
+ @param vs Value size.
+ @return 1 on success, 0 on error (can continue), -1 on error (abort).
+*/
+static
+int
+dk4dbi_c8_internal_traverse(
+ void *obj,
+ const void *kb,
+ size_t ks,
+ const void *vb,
+ size_t vs
+)
+{
+ dk4dbi_c8_traversal_object_t *myobj; /* Passed from dk4dbi_traverse() */
+ const char *pk; /* Key pointer */
+ const char *pv; /* Value pointer */
+ int back = 0;
+ $? "+ dk4dbi_c8_internal_traverse"
+ if ((NULL != obj) && (NULL != kb) && (NULL != vb) && (0 < ks) && (0 < vs)) {
+ pk = (const char *)kb;
+ pv = (const char *)vb;
+ if (('\0' == pk[ks - 1]) && ('\0' == pv[vs - 1])) {
+ myobj = (dk4dbi_c8_traversal_object_t *)obj;
+ back = (*(myobj->fct))(myobj->obj, pk, pv);
+ }
+ } $? "- dk4dbi_c8_internal_traverse %d", back
+ return back;
+}
+
+
+
+int
+dk4dbi_c8_traverse(
+ dk4_dbi_t *db,
+ void *obj,
+ dk4dbi_c8_traverse_fct_t *fct
+)
+{
+ dk4dbi_c8_traversal_object_t myobj; /* Passed to dk4dbi_traverse */
+ int back = -1;
+
+ $? "+ dk4dbi_c8_traverse db=%d obj=%d", TR_IPTR(db), TR_IPTR(obj)
+ if ((NULL != db) && (NULL != fct)) {
+ myobj.obj = obj;
+ myobj.fct = fct;
+ back = dk4dbi_traverse(db, &myobj, dk4dbi_c8_internal_traverse);
+ } $? "- dk4dbi_c8_traverse %d", back
+ return back;
+}
+
+
diff --git a/support/dktools/dk4dbit8.h b/support/dktools/dk4dbit8.h
new file mode 100644
index 0000000000..e24e1b449e
--- /dev/null
+++ b/support/dktools/dk4dbit8.h
@@ -0,0 +1,179 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4dbit8.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4DBIT8_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4DBIT8_H_INCLUDED 1
+
+
+#line 10 "dk4dbit8.ctr"
+
+/** @file dk4dbit8.h Text in database.
+*/
+
+#ifndef DK4DBI_H_INCLUDED
+#include <dk4dbi.h>
+#endif
+
+/** Traverse simple database containing text.
+ @param obj Object to modify during traversal.
+ @param k Key text.
+ @param v Value text.
+ @return 1 on success, 0 on error (continue traversal),
+ -1 on error (abort).
+*/
+typedef
+int
+dk4dbi_c8_traverse_fct_t(
+ void *obj,
+ const char *k,
+ const char *v
+);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Set text entry.
+ @param db Database to modify.
+ @param k Key text.
+ @param v Value text.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if db, k or vis NULL,
+ - DK4_E_SYNTAX<br>
+ if the database was opened read-only or k or v
+ is too long.
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow in size calculation,
+ - DK4_E_NOT_SUPPORTED<br>
+ if db indicates an unsupported backend,
+ - DK4_E_NOT_FOUND<br>
+ if no record to delete was found,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available,
+ - DK4_E_WRITE_FAILED<br>
+ if modification of the database failed.
+*/
+int
+dk4dbi_c8_set(
+ dk4_dbi_t *db,
+ const char *k,
+ const char *v,
+ dk4_er_t *erp
+);
+
+/** Retrieve text entry.
+ @param db Database to query.
+ @param k Key text.
+ @param vbuf Result buffer address.
+ @param vsz Pointer to size variable (in: size, out: used).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if db, k or vbufis NULL or vsz is 0,
+ or the length of k exceeds the key size limit,
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow in size calculation,
+ - DK4_E_NOT_SUPPORTED<br>
+ if db indicates an unsupported backend,
+ - DK4_E_NOT_FOUND<br>
+ if no record was found for the key,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the destination buffer is too small.
+*/
+int
+dk4dbi_c8_get(
+ dk4_dbi_t *db,
+ const char *k,
+ char *vbuf,
+ size_t vsz,
+ dk4_er_t *erp
+);
+
+/** Delete text entry.
+ @param db Database to modify.
+ @param k Key text.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if db or k is NULL,
+ - DK4_E_SYNTAX<br>
+ if the database is opened read-only or the length of
+ k exceeds the key size limit,
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow in size calculation,
+ - DK4_E_NOT_SUPPORTED<br>
+ if db indicates an unsupported backend,
+ - DK4_E_WRITE_FAILED<br>
+ if modification of the database failed,
+ - DK4_E_NOT_FOUND<br>
+ if no record for the specified key is in the database.
+*/
+int
+dk4dbi_c8_del(
+ dk4_dbi_t *db,
+ const char *k,
+ dk4_er_t *erp
+);
+
+/** Traverse database, apply function to all text entries.
+ @param db Database to traverse.
+ @param obj Object to modify during traversal.
+ @param fct Function to apply to all text entries.
+ @return 1 on success, 0 on error (database traversed),
+ -1 on error (traversal aborted).
+*/
+int
+dk4dbi_c8_traverse(
+ dk4_dbi_t *db,
+ void *obj,
+ dk4dbi_c8_traverse_fct_t *fct
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4dbitw.c b/support/dktools/dk4dbitw.c
new file mode 100644
index 0000000000..3490dbc20a
--- /dev/null
+++ b/support/dktools/dk4dbitw.c
@@ -0,0 +1,256 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4dbitw.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4dbitw.c The dk4dbitw module.
+*/
+
+
+#line 153 "dk4dbitw.ctr"
+
+#include "dk4conf.h"
+
+#include "dk4strw.h"
+#include "dk4dbitw.h"
+#include "dk4maasz.h"
+
+
+
+
+
+#line 163 "dk4dbitw.ctr"
+
+
+
+/** Object for database traversal.
+*/
+typedef struct {
+ void *obj; /**< Object for string traversal. */
+ dk4dbi_wc_traverse_fct_t *fct; /**< String traversal function. */
+} dk4dbi_wc_traversal_object_t;
+
+
+
+int
+dk4dbi_wc_del(
+ dk4_dbi_t *db,
+ const wchar_t *k,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er;
+ size_t ks = 0;
+ int back = 0;
+ if ((NULL != db) && (NULL != k)) {
+ dk4error_init(&er);
+ ks = dk4ma_size_t_mul(
+ sizeof(wchar_t),
+ dk4ma_size_t_add(1, dk4strw_len(k), &er),
+ &er
+ );
+ if (DK4_E_NONE == er.ec) {
+ back = dk4dbi_delete(db, k, ks, erp);
+ } else {
+ dk4error_copy(erp, &er);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4dbi_wc_set(
+ dk4_dbi_t *db,
+ const wchar_t *k,
+ const wchar_t *v,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er;
+ size_t ks = 0;
+ size_t vs = 0;
+ int back = 0;
+
+ if ((NULL != db) && (NULL != k)) {
+ if (NULL != v) {
+ dk4error_init(&er);
+ ks = dk4ma_size_t_mul(
+ sizeof(wchar_t),
+ dk4ma_size_t_add(1, dk4strw_len(k), &er),
+ &er
+ );
+ vs = dk4ma_size_t_mul(
+ sizeof(wchar_t),
+ dk4ma_size_t_add(1, dk4strw_len(v), &er),
+ &er
+ );
+ if (DK4_E_NONE == er.ec) {
+ back = dk4dbi_set(db, k, ks, v, vs, erp);
+ } else {
+ dk4error_copy(erp, &er);
+ }
+ } else {
+ back = dk4dbi_wc_del(db, k, erp);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4dbi_wc_get(
+ dk4_dbi_t *db,
+ const wchar_t *k,
+ wchar_t *vbuf,
+ size_t vsz,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er;
+ size_t ks = 0;
+ size_t ressz = 0;
+ int back = 0;
+ if ((NULL != vbuf) && (0 < vsz)) { *vbuf = L'\0'; }
+ if ((NULL != db) && (NULL != k) && (NULL != vbuf) && (0 < vsz)) {
+ dk4error_init(&er);
+ ressz = dk4ma_size_t_mul(sizeof(wchar_t), vsz, &er);
+ ks = dk4ma_size_t_mul(
+ sizeof(wchar_t),
+ dk4ma_size_t_add(1, dk4strw_len(k), &er),
+ &er
+ );
+ if (DK4_E_NONE == er.ec) {
+ if (0 != dk4dbi_get(db, k, ks, vbuf, &ressz, erp)) {
+ if (0 == (ressz % sizeof(wchar_t))) {
+ ressz = ressz / sizeof(wchar_t);
+ if (0 < ressz) {
+ if (L'\0' == vbuf[ressz - 1]) {
+ back = 1;
+ } else {
+ if (ressz < vsz) {
+ vbuf[ressz] = L'\0';
+ back = 1;
+ } else {
+ *vbuf = L'\0';
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ }
+ } else {
+ *vbuf = L'\0';
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ *vbuf = L'\0';
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ }
+ } else {
+ dk4error_copy(erp, &er);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+/** Function to traverse a simple database.
+ The function must check the kb, ks, vb and vs arguments
+ for validity, they are passed as found by the backend
+ functions (this means pointers may be NULL, sizes may be 0).
+ @param Object modified during traversal, may be NULL.
+ @param kb Key data.
+ @param ks Key size.
+ @param vb Value data.
+ @param vs Value size.
+ @return 1 on success, 0 on error (can continue), -1 on error (abort).
+*/
+static
+int
+dk4dbi_wc_internal_traverse(
+ void *obj,
+ const void *kb,
+ size_t ks,
+ const void *vb,
+ size_t vs
+)
+{
+ dk4dbi_wc_traversal_object_t *myobj; /* Passed from dk4dbi_traverse() */
+ const wchar_t *pk; /* Key pointer */
+ const wchar_t *pv; /* Value pointer */
+ int back = 0;
+
+ if ((NULL != obj) && (NULL != kb) && (NULL != vb)) {
+ if ((0 == (ks % sizeof(wchar_t))) && (0 == (vs % sizeof(wchar_t)))) {
+ ks = ks / sizeof(wchar_t);
+ vs = vs / sizeof(wchar_t);
+ if ((0 < ks) && (0 < vs)) {
+ pk = (const wchar_t *)kb;
+ pv = (const wchar_t *)vb;
+ if (('\0' == pk[ks - 1]) && ('\0' == pv[vs - 1])) {
+ myobj = (dk4dbi_wc_traversal_object_t *)obj;
+ back = (*(myobj->fct))(myobj->obj, pk, pv);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+int
+dk4dbi_wc_traverse(
+ dk4_dbi_t *db,
+ void *obj,
+ dk4dbi_wc_traverse_fct_t *fct
+)
+{
+ dk4dbi_wc_traversal_object_t myobj; /* Passed to dk4dbi_traverse */
+ int back = -1;
+
+ if ((NULL != db) && (NULL != fct)) {
+ myobj.obj = obj;
+ myobj.fct = fct;
+ back = dk4dbi_traverse(db, &myobj, dk4dbi_wc_internal_traverse);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4dbitw.ctr b/support/dktools/dk4dbitw.ctr
new file mode 100644
index 0000000000..5da31311ed
--- /dev/null
+++ b/support/dktools/dk4dbitw.ctr
@@ -0,0 +1,366 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk4dbitw.h Text (wchar_t) in database.
+*/
+
+#ifndef DK4DBI_H_INCLUDED
+#include <dk4dbi.h>
+#endif
+
+#if DK4_HAVE_WCHAR_H
+#ifndef WCHAR_H_INCLUDED
+#include <wchar.h>
+#define WCHAR_H_INCLUDED 1
+#endif
+#endif
+
+/** Function used when traversing a simple database.
+ @param obj Object to modify during traversal.
+ @param k Current key.
+ @param v Current value.
+*/
+typedef
+int
+dk4dbi_wc_traverse_fct_t(
+ void *obj,
+ const wchar_t *k,
+ const wchar_t *v
+);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Set text entry.
+ @param db Database to modify.
+ @param k Key text.
+ @param v Value text.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if db, k or vis NULL,
+ - DK4_E_SYNTAX<br>
+ if the database was opened read-only or k or v
+ is too long.
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow in size calculation,
+ - DK4_E_NOT_SUPPORTED<br>
+ if db indicates an unsupported backend,
+ - DK4_E_NOT_FOUND<br>
+ if no record to delete was found,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available,
+ - DK4_E_WRITE_FAILED<br>
+ if modification of the database failed.
+*/
+int
+dk4dbi_wc_set(
+ dk4_dbi_t *db,
+ const wchar_t *k,
+ const wchar_t *v,
+ dk4_er_t *erp
+);
+
+/** Retrieve text entry.
+ @param db Database to query.
+ @param k Key text.
+ @param vbuf Result buffer address.
+ @param vsz Pointer to size variable (in: size, out: used),
+ number of wchar_t.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if db, k or vbufis NULL or vsz is 0,
+ or the length of k exceeds the key size limit,
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow in size calculation,
+ - DK4_E_NOT_SUPPORTED<br>
+ if db indicates an unsupported backend,
+ - DK4_E_NOT_FOUND<br>
+ if no record was found for the key,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the destination buffer is too small.
+*/
+int
+dk4dbi_wc_get(
+ dk4_dbi_t *db,
+ const wchar_t *k,
+ wchar_t *vbuf,
+ size_t vsz,
+ dk4_er_t *erp
+);
+
+/** Delete text entry.
+ @param db Database to modify.
+ @param k Key text.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if db or k is NULL,
+ - DK4_E_SYNTAX<br>
+ if the database is opened read-only or the length of
+ k exceeds the key size limit,
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow in size calculation,
+ - DK4_E_NOT_SUPPORTED<br>
+ if db indicates an unsupported backend,
+ - DK4_E_WRITE_FAILED<br>
+ if modification of the database failed,
+ - DK4_E_NOT_FOUND<br>
+ if no record for the specified key is in the database.
+*/
+int
+dk4dbi_wc_del(
+ dk4_dbi_t *db,
+ const wchar_t *k,
+ dk4_er_t *erp
+);
+
+/** Traverse database, apply function to all text entries.
+ @param db Database to traverse.
+ @param obj Object to modify during traversal.
+ @param fct Function to apply to all text entries.
+ @return 1 on success, 0 on error (database traversed),
+ -1 on error (traversal aborted).
+*/
+int
+dk4dbi_wc_traverse(
+ dk4_dbi_t *db,
+ void *obj,
+ dk4dbi_wc_traverse_fct_t *fct
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4conf.h"
+
+#include "dk4strw.h"
+#include "dk4dbitw.h"
+#include "dk4maasz.h"
+
+
+
+$!trace-include
+
+
+
+/** Object for database traversal.
+*/
+typedef struct {
+ void *obj; /**< Object for string traversal. */
+ dk4dbi_wc_traverse_fct_t *fct; /**< String traversal function. */
+} dk4dbi_wc_traversal_object_t;
+
+
+
+int
+dk4dbi_wc_del(
+ dk4_dbi_t *db,
+ const wchar_t *k,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er;
+ size_t ks = 0;
+ int back = 0;
+ if ((NULL != db) && (NULL != k)) {
+ dk4error_init(&er);
+ ks = dk4ma_size_t_mul(
+ sizeof(wchar_t),
+ dk4ma_size_t_add(1, dk4strw_len(k), &er),
+ &er
+ );
+ if (DK4_E_NONE == er.ec) {
+ back = dk4dbi_delete(db, k, ks, erp);
+ } else {
+ dk4error_copy(erp, &er);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4dbi_wc_set(
+ dk4_dbi_t *db,
+ const wchar_t *k,
+ const wchar_t *v,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er;
+ size_t ks = 0;
+ size_t vs = 0;
+ int back = 0;
+
+ if ((NULL != db) && (NULL != k)) {
+ if (NULL != v) {
+ dk4error_init(&er);
+ ks = dk4ma_size_t_mul(
+ sizeof(wchar_t),
+ dk4ma_size_t_add(1, dk4strw_len(k), &er),
+ &er
+ );
+ vs = dk4ma_size_t_mul(
+ sizeof(wchar_t),
+ dk4ma_size_t_add(1, dk4strw_len(v), &er),
+ &er
+ );
+ if (DK4_E_NONE == er.ec) {
+ back = dk4dbi_set(db, k, ks, v, vs, erp);
+ } else {
+ dk4error_copy(erp, &er);
+ }
+ } else {
+ back = dk4dbi_wc_del(db, k, erp);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4dbi_wc_get(
+ dk4_dbi_t *db,
+ const wchar_t *k,
+ wchar_t *vbuf,
+ size_t vsz,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er;
+ size_t ks = 0;
+ size_t ressz = 0;
+ int back = 0;
+ if ((NULL != vbuf) && (0 < vsz)) { *vbuf = L'\0'; }
+ if ((NULL != db) && (NULL != k) && (NULL != vbuf) && (0 < vsz)) {
+ dk4error_init(&er);
+ ressz = dk4ma_size_t_mul(sizeof(wchar_t), vsz, &er);
+ ks = dk4ma_size_t_mul(
+ sizeof(wchar_t),
+ dk4ma_size_t_add(1, dk4strw_len(k), &er),
+ &er
+ );
+ if (DK4_E_NONE == er.ec) {
+ if (0 != dk4dbi_get(db, k, ks, vbuf, &ressz, erp)) {
+ if (0 == (ressz % sizeof(wchar_t))) {
+ ressz = ressz / sizeof(wchar_t);
+ if (0 < ressz) {
+ if (L'\0' == vbuf[ressz - 1]) {
+ back = 1;
+ } else {
+ if (ressz < vsz) {
+ vbuf[ressz] = L'\0';
+ back = 1;
+ } else {
+ *vbuf = L'\0';
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ }
+ } else {
+ *vbuf = L'\0';
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ *vbuf = L'\0';
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ }
+ } else {
+ dk4error_copy(erp, &er);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+/** Function to traverse a simple database.
+ The function must check the kb, ks, vb and vs arguments
+ for validity, they are passed as found by the backend
+ functions (this means pointers may be NULL, sizes may be 0).
+ @param Object modified during traversal, may be NULL.
+ @param kb Key data.
+ @param ks Key size.
+ @param vb Value data.
+ @param vs Value size.
+ @return 1 on success, 0 on error (can continue), -1 on error (abort).
+*/
+static
+int
+dk4dbi_wc_internal_traverse(
+ void *obj,
+ const void *kb,
+ size_t ks,
+ const void *vb,
+ size_t vs
+)
+{
+ dk4dbi_wc_traversal_object_t *myobj; /* Passed from dk4dbi_traverse() */
+ const wchar_t *pk; /* Key pointer */
+ const wchar_t *pv; /* Value pointer */
+ int back = 0;
+
+ if ((NULL != obj) && (NULL != kb) && (NULL != vb)) {
+ if ((0 == (ks % sizeof(wchar_t))) && (0 == (vs % sizeof(wchar_t)))) {
+ ks = ks / sizeof(wchar_t);
+ vs = vs / sizeof(wchar_t);
+ if ((0 < ks) && (0 < vs)) {
+ pk = (const wchar_t *)kb;
+ pv = (const wchar_t *)vb;
+ if (('\0' == pk[ks - 1]) && ('\0' == pv[vs - 1])) {
+ myobj = (dk4dbi_wc_traversal_object_t *)obj;
+ back = (*(myobj->fct))(myobj->obj, pk, pv);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+int
+dk4dbi_wc_traverse(
+ dk4_dbi_t *db,
+ void *obj,
+ dk4dbi_wc_traverse_fct_t *fct
+)
+{
+ dk4dbi_wc_traversal_object_t myobj; /* Passed to dk4dbi_traverse */
+ int back = -1;
+
+ if ((NULL != db) && (NULL != fct)) {
+ myobj.obj = obj;
+ myobj.fct = fct;
+ back = dk4dbi_traverse(db, &myobj, dk4dbi_wc_internal_traverse);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4dbitw.h b/support/dktools/dk4dbitw.h
new file mode 100644
index 0000000000..1568146950
--- /dev/null
+++ b/support/dktools/dk4dbitw.h
@@ -0,0 +1,185 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4dbitw.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4DBITW_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4DBITW_H_INCLUDED 1
+
+
+#line 10 "dk4dbitw.ctr"
+
+/** @file dk4dbitw.h Text (wchar_t) in database.
+*/
+
+#ifndef DK4DBI_H_INCLUDED
+#include <dk4dbi.h>
+#endif
+
+#if DK4_HAVE_WCHAR_H
+#ifndef WCHAR_H_INCLUDED
+#include <wchar.h>
+#define WCHAR_H_INCLUDED 1
+#endif
+#endif
+
+/** Function used when traversing a simple database.
+ @param obj Object to modify during traversal.
+ @param k Current key.
+ @param v Current value.
+*/
+typedef
+int
+dk4dbi_wc_traverse_fct_t(
+ void *obj,
+ const wchar_t *k,
+ const wchar_t *v
+);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Set text entry.
+ @param db Database to modify.
+ @param k Key text.
+ @param v Value text.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if db, k or vis NULL,
+ - DK4_E_SYNTAX<br>
+ if the database was opened read-only or k or v
+ is too long.
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow in size calculation,
+ - DK4_E_NOT_SUPPORTED<br>
+ if db indicates an unsupported backend,
+ - DK4_E_NOT_FOUND<br>
+ if no record to delete was found,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available,
+ - DK4_E_WRITE_FAILED<br>
+ if modification of the database failed.
+*/
+int
+dk4dbi_wc_set(
+ dk4_dbi_t *db,
+ const wchar_t *k,
+ const wchar_t *v,
+ dk4_er_t *erp
+);
+
+/** Retrieve text entry.
+ @param db Database to query.
+ @param k Key text.
+ @param vbuf Result buffer address.
+ @param vsz Pointer to size variable (in: size, out: used),
+ number of wchar_t.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if db, k or vbufis NULL or vsz is 0,
+ or the length of k exceeds the key size limit,
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow in size calculation,
+ - DK4_E_NOT_SUPPORTED<br>
+ if db indicates an unsupported backend,
+ - DK4_E_NOT_FOUND<br>
+ if no record was found for the key,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the destination buffer is too small.
+*/
+int
+dk4dbi_wc_get(
+ dk4_dbi_t *db,
+ const wchar_t *k,
+ wchar_t *vbuf,
+ size_t vsz,
+ dk4_er_t *erp
+);
+
+/** Delete text entry.
+ @param db Database to modify.
+ @param k Key text.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if db or k is NULL,
+ - DK4_E_SYNTAX<br>
+ if the database is opened read-only or the length of
+ k exceeds the key size limit,
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow in size calculation,
+ - DK4_E_NOT_SUPPORTED<br>
+ if db indicates an unsupported backend,
+ - DK4_E_WRITE_FAILED<br>
+ if modification of the database failed,
+ - DK4_E_NOT_FOUND<br>
+ if no record for the specified key is in the database.
+*/
+int
+dk4dbi_wc_del(
+ dk4_dbi_t *db,
+ const wchar_t *k,
+ dk4_er_t *erp
+);
+
+/** Traverse database, apply function to all text entries.
+ @param db Database to traverse.
+ @param obj Object to modify during traversal.
+ @param fct Function to apply to all text entries.
+ @return 1 on success, 0 on error (database traversed),
+ -1 on error (traversal aborted).
+*/
+int
+dk4dbi_wc_traverse(
+ dk4_dbi_t *db,
+ void *obj,
+ dk4dbi_wc_traverse_fct_t *fct
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4dblc8.c b/support/dktools/dk4dblc8.c
new file mode 100644
index 0000000000..7126f37df0
--- /dev/null
+++ b/support/dktools/dk4dblc8.c
@@ -0,0 +1,126 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4dblc8.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4dblc8.c The dk4dblc8 module.
+*/
+
+
+#line 62 "dk4dblc8.ctr"
+
+#include "dk4dblc8.h"
+#include "dk4str8.h"
+
+
+int
+dk4double_to_string_c8(char *dptr, size_t szdptr, double v, dk4_er_t *erp)
+{
+#if DK4_HAVE__SNPRINTF_S
+ /* +++ _snprintf_s */
+ char buf[64];
+ int back = 0;
+ int res = 0;
+ if (NULL != dptr) { *dptr = '\0'; }
+ if ((NULL != dptr) && (1 < szdptr)) {
+ res = _snprintf_s(buf, sizeof(buf), (sizeof(buf)-1), "%lg", v);
+ if ((0 < res) && ((size_t)res < sizeof(buf))) {
+ buf[res] = '\0';
+ back = dk4str8_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* --- _snprintf_s */
+#else
+#if DK4_HAVE__SNPRINTF
+ /* +++ _snprintf */
+ char buf[64];
+ int back = 0;
+ int res = 0;
+ if (NULL != dptr) { *dptr = '\0'; }
+ if ((NULL != dptr) && (1 < szdptr)) {
+ res = _snprintf(buf, sizeof(buf), "%lg", v);
+ if ((0 < res) && ((size_t)res < sizeof(buf))) {
+ buf[res] = '\0';
+ back = dk4str8_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* --- _snprintf */
+#else
+#if DK4_HAVE_SNPRINTF
+ /* +++ snprintf */
+ char buf[64];
+ int back = 0;
+ int res = 0;
+ if (NULL != dptr) { *dptr = '\0'; }
+ if ((NULL != dptr) && (1 < szdptr)) {
+ res = snprintf(buf, sizeof(buf), "%lg", v);
+ if ((0 < res) && ((size_t)res < sizeof(buf))) {
+ buf[res] = '\0';
+ back = dk4str8_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* --- snprintf */
+#else
+ /* +++ sprintf */
+ char buf[64];
+ int back = 0;
+ int res = 0;
+ if (NULL != dptr) { *dptr = '\0'; }
+ if ((NULL != dptr) && (1 < szdptr)) {
+ sprintf(buf, "%lg", v);
+ back = dk4str8_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* --- sprintf */
+#endif
+#endif
+#endif
+}
+
diff --git a/support/dktools/dk4dblc8.ctr b/support/dktools/dk4dblc8.ctr
new file mode 100644
index 0000000000..ca3dec91b0
--- /dev/null
+++ b/support/dktools/dk4dblc8.ctr
@@ -0,0 +1,147 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ Double to char text conversion using the more secure functions
+ _snprintf_s(), _snprintf() or snprintf() instead of sprintf()
+ if available.
+
+ CRT on Windows: Required.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert double value to string.
+ @param dptr Destination buffer pointer.
+ @param szdptr Size of destination buffer.
+ @param v Value to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or szdptr is less than 2,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the destination buffer is too small to store the string.
+*/
+int
+dk4double_to_string_c8(char *dptr, size_t szdptr, double v, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4dblc8.h"
+#include "dk4str8.h"
+
+
+int
+dk4double_to_string_c8(char *dptr, size_t szdptr, double v, dk4_er_t *erp)
+{
+#if DK4_HAVE__SNPRINTF_S
+ /* +++ _snprintf_s */
+ char buf[64];
+ int back = 0;
+ int res = 0;
+ if (NULL != dptr) { *dptr = '\0'; }
+ if ((NULL != dptr) && (1 < szdptr)) {
+ res = _snprintf_s(buf, sizeof(buf), (sizeof(buf)-1), "%lg", v);
+ if ((0 < res) && ((size_t)res < sizeof(buf))) {
+ buf[res] = '\0';
+ back = dk4str8_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* --- _snprintf_s */
+#else
+#if DK4_HAVE__SNPRINTF
+ /* +++ _snprintf */
+ char buf[64];
+ int back = 0;
+ int res = 0;
+ if (NULL != dptr) { *dptr = '\0'; }
+ if ((NULL != dptr) && (1 < szdptr)) {
+ res = _snprintf(buf, sizeof(buf), "%lg", v);
+ if ((0 < res) && ((size_t)res < sizeof(buf))) {
+ buf[res] = '\0';
+ back = dk4str8_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* --- _snprintf */
+#else
+#if DK4_HAVE_SNPRINTF
+ /* +++ snprintf */
+ char buf[64];
+ int back = 0;
+ int res = 0;
+ if (NULL != dptr) { *dptr = '\0'; }
+ if ((NULL != dptr) && (1 < szdptr)) {
+ res = snprintf(buf, sizeof(buf), "%lg", v);
+ if ((0 < res) && ((size_t)res < sizeof(buf))) {
+ buf[res] = '\0';
+ back = dk4str8_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* --- snprintf */
+#else
+ /* +++ sprintf */
+ char buf[64];
+ int back = 0;
+ int res = 0;
+ if (NULL != dptr) { *dptr = '\0'; }
+ if ((NULL != dptr) && (1 < szdptr)) {
+ sprintf(buf, "%lg", v);
+ back = dk4str8_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* --- sprintf */
+#endif
+#endif
+#endif
+}
+
diff --git a/support/dktools/dk4dblc8.h b/support/dktools/dk4dblc8.h
new file mode 100644
index 0000000000..82131e4580
--- /dev/null
+++ b/support/dktools/dk4dblc8.h
@@ -0,0 +1,95 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4dblc8.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4DBLC8_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4DBLC8_H_INCLUDED 1
+
+
+#line 9 "dk4dblc8.ctr"
+
+/** @file
+ Double to char text conversion using the more secure functions
+ _snprintf_s(), _snprintf() or snprintf() instead of sprintf()
+ if available.
+
+ CRT on Windows: Required.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert double value to string.
+ @param dptr Destination buffer pointer.
+ @param szdptr Size of destination buffer.
+ @param v Value to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or szdptr is less than 2,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the destination buffer is too small to store the string.
+*/
+int
+dk4double_to_string_c8(char *dptr, size_t szdptr, double v, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4dbldk.c b/support/dktools/dk4dbldk.c
new file mode 100644
index 0000000000..7a7aecd952
--- /dev/null
+++ b/support/dktools/dk4dbldk.c
@@ -0,0 +1,61 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4dbldk.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4dbldk.c The dk4dbldk module.
+*/
+
+
+#line 56 "dk4dbldk.ctr"
+
+#include "dk4dbldk.h"
+
+#if DK4_CHAR_SIZE > 1
+#include "dk4dblwc.h"
+#else
+#include "dk4dblc8.h"
+#endif
+
+
+int
+dk4double_to_string(dkChar *dptr, size_t szdptr, double v, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4double_to_string_wc(dptr, szdptr, v, erp));
+#else
+ return (dk4double_to_string_c8(dptr, szdptr, v, erp));
+#endif
+}
+
+
diff --git a/support/dktools/dk4dbldk.ctr b/support/dktools/dk4dbldk.ctr
new file mode 100644
index 0000000000..62f8628311
--- /dev/null
+++ b/support/dktools/dk4dbldk.ctr
@@ -0,0 +1,76 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+%% header
+
+/** @file
+ Double to dkChar text conversion using more secure functions than
+ swprintf() or sprintf() if available.
+
+ CRT on Windows: Required.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert double value to string.
+ @param dptr Destination buffer pointer.
+ @param szdptr Size of destination buffer (number of dkChar).
+ @param v Value to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or szdptr is less than 2,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the destination buffer is too small to store the string.
+*/
+int
+dk4double_to_string(dkChar *dptr, size_t szdptr, double v, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4dbldk.h"
+
+#if DK4_CHAR_SIZE > 1
+#include "dk4dblwc.h"
+#else
+#include "dk4dblc8.h"
+#endif
+
+
+int
+dk4double_to_string(dkChar *dptr, size_t szdptr, double v, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4double_to_string_wc(dptr, szdptr, v, erp));
+#else
+ return (dk4double_to_string_c8(dptr, szdptr, v, erp));
+#endif
+}
+
+
diff --git a/support/dktools/dk4dbldk.h b/support/dktools/dk4dbldk.h
new file mode 100644
index 0000000000..e9f18d6455
--- /dev/null
+++ b/support/dktools/dk4dbldk.h
@@ -0,0 +1,90 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4dbldk.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4DBLDK_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4DBLDK_H_INCLUDED 1
+
+
+#line 8 "dk4dbldk.ctr"
+
+/** @file
+ Double to dkChar text conversion using more secure functions than
+ swprintf() or sprintf() if available.
+
+ CRT on Windows: Required.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert double value to string.
+ @param dptr Destination buffer pointer.
+ @param szdptr Size of destination buffer (number of dkChar).
+ @param v Value to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or szdptr is less than 2,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the destination buffer is too small to store the string.
+*/
+int
+dk4double_to_string(dkChar *dptr, size_t szdptr, double v, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4dblwc.c b/support/dktools/dk4dblwc.c
new file mode 100644
index 0000000000..3ba64a52f3
--- /dev/null
+++ b/support/dktools/dk4dblwc.c
@@ -0,0 +1,168 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4dblwc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4dblwc.c The dk4dblwc module.
+*/
+
+
+#line 69 "dk4dblwc.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4mem.h"
+#include "dk4dblc8.h"
+#include "dk4dblwc.h"
+#include "dk4str8.h"
+#include "dk4strw.h"
+
+
+
+int
+dk4double_to_string_wc(wchar_t *dptr, size_t szdptr, double v, dk4_er_t *erp)
+{
+#if DK4_HAVE__SNWPRINTF_S
+ /* +++ _snwprintf_s */
+ wchar_t buf[64];
+ int back = 0;
+ int res = 0;
+ if (NULL != dptr) { *dptr = L'\0'; }
+ if ((NULL != dptr) && (1 < szdptr)) {
+ res = _snwprintf_s(
+ buf, DK4_SIZEOF(buf,dkChar), (DK4_SIZEOF(buf,dkChar) - 1), L"%lg", v
+ );
+ if ((0 < res) && (res < DK4_SIZEOF(buf,dkChar))) {
+ buf[res] = L'\0';
+ back = dk4strw_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* --- _snwprintf_s */
+#else
+#if DK4_HAVE__SNWPRINTF
+ /* +++ _snwprintf */
+ wchar_t buf[64];
+ int back = 0;
+ int res = 0;
+ if (NULL != dptr) { *dptr = L'\0'; }
+ if ((NULL != dptr) && (1 < szdptr)) {
+ 0 = _snwprintf(
+ buf, DK4_SIZEOF(buf,dkChar), L"%lg", v
+ );
+ if ((0 < res) && (res < DK4_SIZEOF(buf,dkChar))) {
+ buf[res] = L'\0';
+ back = dk4strw_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* --- _snwprintf */
+#else
+#if DK4_HAVE_SNWPRINTF
+ wchar_t buf[64];
+ int back = 0;
+ int res = 0;
+ if (NULL != dptr) { *dptr = L'\0'; }
+ if ((NULL != dptr) && (1 < szdptr)) {
+ 0 = snwprintf(
+ buf, DK4_SIZEOF(buf,dkChar), L"%lg", v
+ );
+ if ((0 < res) && (res < DK4_SIZEOF(buf,dkChar))) {
+ buf[res] = L'\0';
+ back = dk4strw_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+#if DK4_HAVE_SWPRINTF
+ /* +++ swprintf */
+ wchar_t buf[64];
+ int back = 0;
+ int res = 0;
+ if (NULL != dptr) { *dptr = L'\0'; }
+ if ((NULL != dptr) && (1 < szdptr)) {
+ res = swprintf(
+ buf, DK4_SIZEOF(buf,dkChar), L"%lg", v
+ );
+ if ((0 < res) && (res < DK4_SIZEOF(buf,dkChar))) {
+ buf[res] = L'\0';
+ back = dk4strw_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* --- swprintf */
+#else
+ char buf[64];
+ char *p1;
+ wchar_t *p2;
+ int back = 0;
+ if ((NULL != dptr) && (1 < szdptr)) {
+ if (0 != dk4double_to_string_c8(buf, sizeof(buf), v, erp)) {
+ if (dk4str8_len(buf) < szdptr) {
+ p2 = dptr; p1 = buf;
+ while ('\0' != *p1) {
+ *(p2++) = (wchar_t)(*(p1++));
+ }
+ *p2 = L'\0';
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#endif
+#endif
+#endif
+#endif
+}
+
+
diff --git a/support/dktools/dk4dblwc.ctr b/support/dktools/dk4dblwc.ctr
new file mode 100644
index 0000000000..2b2100527d
--- /dev/null
+++ b/support/dktools/dk4dblwc.ctr
@@ -0,0 +1,196 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Double to wchar_t text conversion using the more secure
+ _snwprintf_s(), _snwprintf() or snwprintf() functions instead
+ of swprintf() if available.
+
+ CRT on Windows: Required.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_HAVE_WCHAR_H
+#ifndef WCHAR_H_INCLUDED
+#include <wchar.h>
+#define WCHAR_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert double value to string.
+ @param dptr Destination buffer pointer.
+ @param szdptr Size of destination buffer (number of wchar_t).
+ @param v Value to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or szdptr is less than 2,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the destination buffer is too small to store the string.
+*/
+int
+dk4double_to_string_wc(wchar_t *dptr, size_t szdptr, double v, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4mem.h"
+#include "dk4dblc8.h"
+#include "dk4dblwc.h"
+#include "dk4str8.h"
+#include "dk4strw.h"
+
+
+
+int
+dk4double_to_string_wc(wchar_t *dptr, size_t szdptr, double v, dk4_er_t *erp)
+{
+#if DK4_HAVE__SNWPRINTF_S
+ /* +++ _snwprintf_s */
+ wchar_t buf[64];
+ int back = 0;
+ int res = 0;
+ if (NULL != dptr) { *dptr = L'\0'; }
+ if ((NULL != dptr) && (1 < szdptr)) {
+ res = _snwprintf_s(
+ buf, DK4_SIZEOF(buf,dkChar), (DK4_SIZEOF(buf,dkChar) - 1), L"%lg", v
+ );
+ if ((0 < res) && (res < DK4_SIZEOF(buf,dkChar))) {
+ buf[res] = L'\0';
+ back = dk4strw_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* --- _snwprintf_s */
+#else
+#if DK4_HAVE__SNWPRINTF
+ /* +++ _snwprintf */
+ wchar_t buf[64];
+ int back = 0;
+ int res = 0;
+ if (NULL != dptr) { *dptr = L'\0'; }
+ if ((NULL != dptr) && (1 < szdptr)) {
+ 0 = _snwprintf(
+ buf, DK4_SIZEOF(buf,dkChar), L"%lg", v
+ );
+ if ((0 < res) && (res < DK4_SIZEOF(buf,dkChar))) {
+ buf[res] = L'\0';
+ back = dk4strw_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* --- _snwprintf */
+#else
+#if DK4_HAVE_SNWPRINTF
+ wchar_t buf[64];
+ int back = 0;
+ int res = 0;
+ if (NULL != dptr) { *dptr = L'\0'; }
+ if ((NULL != dptr) && (1 < szdptr)) {
+ 0 = snwprintf(
+ buf, DK4_SIZEOF(buf,dkChar), L"%lg", v
+ );
+ if ((0 < res) && (res < DK4_SIZEOF(buf,dkChar))) {
+ buf[res] = L'\0';
+ back = dk4strw_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+#if DK4_HAVE_SWPRINTF
+ /* +++ swprintf */
+ wchar_t buf[64];
+ int back = 0;
+ int res = 0;
+ if (NULL != dptr) { *dptr = L'\0'; }
+ if ((NULL != dptr) && (1 < szdptr)) {
+ res = swprintf(
+ buf, DK4_SIZEOF(buf,dkChar), L"%lg", v
+ );
+ if ((0 < res) && (res < DK4_SIZEOF(buf,dkChar))) {
+ buf[res] = L'\0';
+ back = dk4strw_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* --- swprintf */
+#else
+ char buf[64];
+ char *p1;
+ wchar_t *p2;
+ int back = 0;
+ if ((NULL != dptr) && (1 < szdptr)) {
+ if (0 != dk4double_to_string_c8(buf, sizeof(buf), v, erp)) {
+ if (dk4str8_len(buf) < szdptr) {
+ p2 = dptr; p1 = buf;
+ while ('\0' != *p1) {
+ *(p2++) = (wchar_t)(*(p1++));
+ }
+ *p2 = L'\0';
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#endif
+#endif
+#endif
+#endif
+}
+
+
diff --git a/support/dktools/dk4dblwc.h b/support/dktools/dk4dblwc.h
new file mode 100644
index 0000000000..3b843b5c58
--- /dev/null
+++ b/support/dktools/dk4dblwc.h
@@ -0,0 +1,101 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4dblwc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4DBLWC_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4DBLWC_H_INCLUDED 1
+
+
+#line 10 "dk4dblwc.ctr"
+
+/** @file
+ Double to wchar_t text conversion using the more secure
+ _snwprintf_s(), _snwprintf() or snwprintf() functions instead
+ of swprintf() if available.
+
+ CRT on Windows: Required.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_HAVE_WCHAR_H
+#ifndef WCHAR_H_INCLUDED
+#include <wchar.h>
+#define WCHAR_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert double value to string.
+ @param dptr Destination buffer pointer.
+ @param szdptr Size of destination buffer (number of wchar_t).
+ @param v Value to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or szdptr is less than 2,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the destination buffer is too small to store the string.
+*/
+int
+dk4double_to_string_wc(wchar_t *dptr, size_t szdptr, double v, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4dec.h b/support/dktools/dk4dec.h
new file mode 100644
index 0000000000..030e42915d
--- /dev/null
+++ b/support/dktools/dk4dec.h
@@ -0,0 +1,27 @@
+#ifndef DK4DEC_H_INCLUDED
+#define DK4DEC_H_INCLUDED 1
+
+/** @file dk4dec.h Result values for adding bytes to a decoder.
+*/
+
+/** Results when adding bytes to a decoder.
+*/
+enum {
+ /** Byte(s) added successfully, stored in
+ the decoders internal state.
+ No further action necessary.
+ */
+ DK4_DECODER_ACCEPT = 0,
+
+ /** Byte(s) added successfully,
+ you can retrieve output.
+ */
+ DK4_DECODER_FINISHED ,
+
+ /** An error occured while adding byte(s).
+ */
+ DK4_DECODER_ERROR
+};
+
+#endif
+
diff --git a/support/dktools/dk4deldir.c b/support/dktools/dk4deldir.c
new file mode 100644
index 0000000000..b40ae60d17
--- /dev/null
+++ b/support/dktools/dk4deldir.c
@@ -0,0 +1,65 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4deldir.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4deldir.c The dk4deldir module.
+*/
+
+
+#line 59 "dk4deldir.ctr"
+
+
+
+#ifndef DK4DELDIR_H_INCLUDED
+#include "dk4deldir.h"
+#endif
+
+#if DK4_CHAR_SIZE > 1
+#include "dk4deldirwc.h"
+#else
+#include "dk4deldir08.h"
+#endif
+
+
+
+int
+dk4delete_directory(const dkChar *fn, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4delete_directory_wc(fn, erp));
+#else
+ return (dk4delete_directory_c8(fn, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4deldir.ctr b/support/dktools/dk4deldir.ctr
new file mode 100644
index 0000000000..e9110c5772
--- /dev/null
+++ b/support/dktools/dk4deldir.ctr
@@ -0,0 +1,83 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Delete directory specified by char name.
+
+ CRT on Windows: Optional.
+*/
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Remove empty directory.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_RMDIR_FAILED<br>
+ with errno value in iDetails1 if the rmdir() function failed,
+ - DK4_E_REMOVE_DIRECTORY_FAILED<br>
+ with GetLastError() value in lDetails1 if the RemoveDirectory()
+ function failed on Windows.
+*/
+int
+dk4delete_directory(const dkChar *fn, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+%% module
+
+
+
+#ifndef DK4DELDIR_H_INCLUDED
+#include "dk4deldir.h"
+#endif
+
+#if DK4_CHAR_SIZE > 1
+#include "dk4deldirwc.h"
+#else
+#include "dk4deldir08.h"
+#endif
+
+
+
+int
+dk4delete_directory(const dkChar *fn, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4delete_directory_wc(fn, erp));
+#else
+ return (dk4delete_directory_c8(fn, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4deldir.h b/support/dktools/dk4deldir.h
new file mode 100644
index 0000000000..9f4e5e5ed8
--- /dev/null
+++ b/support/dktools/dk4deldir.h
@@ -0,0 +1,91 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4deldir.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4DELDIR_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4DELDIR_H_INCLUDED 1
+
+
+#line 10 "dk4deldir.ctr"
+
+/** @file
+ Delete directory specified by char name.
+
+ CRT on Windows: Optional.
+*/
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Remove empty directory.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_RMDIR_FAILED<br>
+ with errno value in iDetails1 if the rmdir() function failed,
+ - DK4_E_REMOVE_DIRECTORY_FAILED<br>
+ with GetLastError() value in lDetails1 if the RemoveDirectory()
+ function failed on Windows.
+*/
+int
+dk4delete_directory(const dkChar *fn, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+
+#endif
diff --git a/support/dktools/dk4deldir08.c b/support/dktools/dk4deldir08.c
new file mode 100644
index 0000000000..a143423d84
--- /dev/null
+++ b/support/dktools/dk4deldir08.c
@@ -0,0 +1,133 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4deldir08.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4deldir08.c The dk4deldir08 module.
+*/
+
+
+#line 59 "dk4deldir08.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4deldir08.h"
+
+
+#if DK4_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#if DK4_HAVE_IO_H
+#include <io.h>
+#endif
+
+#if DK4_HAVE_DIRECT_H
+#include <direct.h>
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+
+
+
+
+#line 91 "dk4deldir08.ctr"
+
+
+
+int
+dk4delete_directory_c8(const char *fn, dk4_er_t *erp)
+{
+ int back = 0;
+
+
+#line 99 "dk4deldir08.ctr"
+ if (NULL != fn) {
+
+#line 100 "dk4deldir08.ctr"
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ if (RemoveDirectoryA(fn)) {
+ back = 1;
+ } else {
+ dk4error_set_ldetails(
+ erp, DK4_E_REMOVE_DIRECTORY_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+#else
+ if (RemoveDirectoryA(fn)) {
+ back = 1;
+ } else {
+ if (NULL != erp) {
+ errno = 0;
+ if (0 == _rmdir(fn)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_RMDIR_FAILED, errno);
+ }
+ }
+ }
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+ errno = 0;
+ if (0 == rmdir(fn)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_RMDIR_FAILED, errno);
+ }
+ /* --- non-Windows */
+#endif
+ } else {
+
+#line 137 "dk4deldir08.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 139 "dk4deldir08.ctr"
+ return back;
+}
+
diff --git a/support/dktools/dk4deldir08.ctr b/support/dktools/dk4deldir08.ctr
new file mode 100644
index 0000000000..c172fbbbb4
--- /dev/null
+++ b/support/dktools/dk4deldir08.ctr
@@ -0,0 +1,141 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Delete directory specified by char name.
+
+ CRT on Windows: Optional.
+*/
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Remove empty directory.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_RMDIR_FAILED<br>
+ with errno value in iDetails1 if the rmdir() function failed,
+ - DK4_E_REMOVE_DIRECTORY_FAILED<br>
+ with GetLastError() value in lDetails1 if the RemoveDirectory()
+ function failed on Windows.
+*/
+int
+dk4delete_directory_c8(const char *fn, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4deldir08.h"
+
+
+#if DK4_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#if DK4_HAVE_IO_H
+#include <io.h>
+#endif
+
+#if DK4_HAVE_DIRECT_H
+#include <direct.h>
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+
+
+$!trace-include
+
+
+
+int
+dk4delete_directory_c8(const char *fn, dk4_er_t *erp)
+{
+ int back = 0;
+ $? "+ dk4delete_directory_c8 \"%!8s\"", TR_8STR(fn)
+ if (NULL != fn) { $? ". fn ok"
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ if (RemoveDirectoryA(fn)) {
+ back = 1;
+ } else {
+ dk4error_set_ldetails(
+ erp, DK4_E_REMOVE_DIRECTORY_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+#else
+ if (RemoveDirectoryA(fn)) {
+ back = 1;
+ } else {
+ if (NULL != erp) {
+ errno = 0;
+ if (0 == _rmdir(fn)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_RMDIR_FAILED, errno);
+ }
+ }
+ }
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+ errno = 0;
+ if (0 == rmdir(fn)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_RMDIR_FAILED, errno);
+ }
+ /* --- non-Windows */
+#endif
+ } else { $? "! fn"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4delete_directory_c8 %d", back
+ return back;
+}
+
diff --git a/support/dktools/dk4deldir08.h b/support/dktools/dk4deldir08.h
new file mode 100644
index 0000000000..5adb8ff7fb
--- /dev/null
+++ b/support/dktools/dk4deldir08.h
@@ -0,0 +1,91 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4deldir08.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4DELDIR08_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4DELDIR08_H_INCLUDED 1
+
+
+#line 10 "dk4deldir08.ctr"
+
+/** @file
+ Delete directory specified by char name.
+
+ CRT on Windows: Optional.
+*/
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Remove empty directory.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_RMDIR_FAILED<br>
+ with errno value in iDetails1 if the rmdir() function failed,
+ - DK4_E_REMOVE_DIRECTORY_FAILED<br>
+ with GetLastError() value in lDetails1 if the RemoveDirectory()
+ function failed on Windows.
+*/
+int
+dk4delete_directory_c8(const char *fn, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+
+#endif
diff --git a/support/dktools/dk4deldirwc.c b/support/dktools/dk4deldirwc.c
new file mode 100644
index 0000000000..78f0e0490a
--- /dev/null
+++ b/support/dktools/dk4deldirwc.c
@@ -0,0 +1,118 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4deldirwc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4deldirwc.c The dk4deldirwc module.
+*/
+
+
+#line 59 "dk4deldirwc.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4deldirwc.h"
+
+
+#if DK4_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#if DK4_HAVE_IO_H
+#include <io.h>
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+
+
+int
+dk4delete_directory_wc(const wchar_t *fn, dk4_er_t *erp)
+{
+ int back = 0;
+ if (NULL != fn) {
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ if (RemoveDirectoryW(fn)) {
+ back = 1;
+ } else {
+ dk4error_set_ldetails(
+ erp, DK4_E_REMOVE_DIRECTORY_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+#else
+ if (RemoveDirectoryW(fn)) {
+ back = 1;
+ } else {
+ if (NULL != erp) {
+ errno = 0;
+ if (0 == _wrmdir(fn)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_RMDIR_FAILED, errno);
+ }
+ }
+ }
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+#if DK4_HAVE_WRMDIR
+ errno = 0;
+ if (0 == wrmdir(fn)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_RMDIR_FAILED, errno);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ /* --- non-Windows */
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4deldirwc.ctr b/support/dktools/dk4deldirwc.ctr
new file mode 100644
index 0000000000..e2ea89d040
--- /dev/null
+++ b/support/dktools/dk4deldirwc.ctr
@@ -0,0 +1,136 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Delete directory specified by wchar_t name.
+
+ CRT on Windows: Optional.
+*/
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Remove empty directory.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_RMDIR_FAILED<br>
+ with errno value in iDetails1 if the rmdir() function failed,
+ - DK4_E_REMOVE_DIRECTORY_FAILED<br>
+ with GetLastError() value in lDetails1 if the RemoveDirectory()
+ function failed on Windows.
+*/
+int
+dk4delete_directory_wc(const wchar_t *fn, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4deldirwc.h"
+
+
+#if DK4_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#if DK4_HAVE_IO_H
+#include <io.h>
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+
+
+int
+dk4delete_directory_wc(const wchar_t *fn, dk4_er_t *erp)
+{
+ int back = 0;
+ if (NULL != fn) {
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ if (RemoveDirectoryW(fn)) {
+ back = 1;
+ } else {
+ dk4error_set_ldetails(
+ erp, DK4_E_REMOVE_DIRECTORY_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+#else
+ if (RemoveDirectoryW(fn)) {
+ back = 1;
+ } else {
+ if (NULL != erp) {
+ errno = 0;
+ if (0 == _wrmdir(fn)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_RMDIR_FAILED, errno);
+ }
+ }
+ }
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+#if DK4_HAVE_WRMDIR
+ errno = 0;
+ if (0 == wrmdir(fn)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_RMDIR_FAILED, errno);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ /* --- non-Windows */
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4deldirwc.h b/support/dktools/dk4deldirwc.h
new file mode 100644
index 0000000000..195bce9a64
--- /dev/null
+++ b/support/dktools/dk4deldirwc.h
@@ -0,0 +1,91 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4deldirwc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4DELDIRWC_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4DELDIRWC_H_INCLUDED 1
+
+
+#line 10 "dk4deldirwc.ctr"
+
+/** @file
+ Delete directory specified by wchar_t name.
+
+ CRT on Windows: Optional.
+*/
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Remove empty directory.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_RMDIR_FAILED<br>
+ with errno value in iDetails1 if the rmdir() function failed,
+ - DK4_E_REMOVE_DIRECTORY_FAILED<br>
+ with GetLastError() value in lDetails1 if the RemoveDirectory()
+ function failed on Windows.
+*/
+int
+dk4delete_directory_wc(const wchar_t *fn, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+
+#endif
diff --git a/support/dktools/dk4delfile.c b/support/dktools/dk4delfile.c
new file mode 100644
index 0000000000..c4e93cab3e
--- /dev/null
+++ b/support/dktools/dk4delfile.c
@@ -0,0 +1,61 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4delfile.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4delfile.c The dk4delfile module.
+*/
+
+
+#line 58 "dk4delfile.ctr"
+
+#include "dk4delfile.h"
+
+#if DK4_CHAR_SIZE > 1
+#include "dk4delfilewc.h"
+#else
+#include "dk4delfile08.h"
+#endif
+
+
+
+int
+dk4delete_file(const dkChar *fn, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4delete_file_wc(fn, erp));
+#else
+ return (dk4delete_file_c8(fn, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4delfile.ctr b/support/dktools/dk4delfile.ctr
new file mode 100644
index 0000000000..f090f35331
--- /dev/null
+++ b/support/dktools/dk4delfile.ctr
@@ -0,0 +1,78 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Remove file specified by dkChar text.
+
+ CRT on Windows: Optional.
+*/
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Remove one file.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_NOT_SUPPORTED<br>
+ if no system function was found to delete files,
+ - DK4_E_UNLINK_FAILED<br>
+ with errno value in idetails if the unlink operation failed,
+ - DK4_E_DELETE_FILE_FAILED<br>
+ with GetLastError() value in lDetails1 if the DeleteFile() function
+ failed on Windows.
+*/
+int
+dk4delete_file(const dkChar *fn, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4delfile.h"
+
+#if DK4_CHAR_SIZE > 1
+#include "dk4delfilewc.h"
+#else
+#include "dk4delfile08.h"
+#endif
+
+
+
+int
+dk4delete_file(const dkChar *fn, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4delete_file_wc(fn, erp));
+#else
+ return (dk4delete_file_c8(fn, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4delfile.h b/support/dktools/dk4delfile.h
new file mode 100644
index 0000000000..e9a0161f22
--- /dev/null
+++ b/support/dktools/dk4delfile.h
@@ -0,0 +1,90 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4delfile.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4DELFILE_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4DELFILE_H_INCLUDED 1
+
+
+#line 10 "dk4delfile.ctr"
+
+/** @file
+ Remove file specified by dkChar text.
+
+ CRT on Windows: Optional.
+*/
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Remove one file.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_NOT_SUPPORTED<br>
+ if no system function was found to delete files,
+ - DK4_E_UNLINK_FAILED<br>
+ with errno value in idetails if the unlink operation failed,
+ - DK4_E_DELETE_FILE_FAILED<br>
+ with GetLastError() value in lDetails1 if the DeleteFile() function
+ failed on Windows.
+*/
+int
+dk4delete_file(const dkChar *fn, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4delfile08.c b/support/dktools/dk4delfile08.c
new file mode 100644
index 0000000000..9d80c63bb2
--- /dev/null
+++ b/support/dktools/dk4delfile08.c
@@ -0,0 +1,137 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4delfile08.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4delfile08.c The dk4delfile08 module.
+*/
+
+
+#line 60 "dk4delfile08.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4delfile08.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+
+
+int
+dk4delete_file_c8(const char *fn, dk4_er_t *erp)
+{
+ int back = 0;
+ if (NULL != fn) {
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ if (DeleteFileA(fn)) {
+ back = 1;
+ } else {
+ dk4error_set_ldetails(
+ erp, DK4_E_DELETE_FILE_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+#else
+ if (DeleteFileA(fn)) {
+ back = 1;
+ } else {
+ if (NULL != erp) {
+ errno = 0;
+ if (0 == _unlink(fn)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_UNLINK_FAILED, errno);
+ }
+ }
+ }
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+#if DK4_HAVE_UNLINK
+ errno = 0;
+ if (0 == unlink(fn)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_UNLINK_FAILED, errno);
+ }
+#else
+#if DK4_HAVE__UNLINK
+ errno = 0;
+ if (0 == _unlink(fn)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_UNLINK_FAILED, errno);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+#endif
+ /* --- non-Windows */
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4delfile08.ctr b/support/dktools/dk4delfile08.ctr
new file mode 100644
index 0000000000..5a81337aa9
--- /dev/null
+++ b/support/dktools/dk4delfile08.ctr
@@ -0,0 +1,156 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Remove file specified by char text.
+
+ CRT on Windows: Optional.
+*/
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Remove one file.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_NOT_SUPPORTED<br>
+ if no system function was found to delete files,
+ - DK4_E_UNLINK_FAILED<br>
+ with errno value in idetails if the unlink operation failed,
+ - DK4_E_DELETE_FILE_FAILED<br>
+ with GetLastError() value in lDetails1 if the DeleteFile() function
+ failed on Windows.
+*/
+int
+dk4delete_file_c8(const char *fn, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4delfile08.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+
+
+int
+dk4delete_file_c8(const char *fn, dk4_er_t *erp)
+{
+ int back = 0;
+ if (NULL != fn) {
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ if (DeleteFileA(fn)) {
+ back = 1;
+ } else {
+ dk4error_set_ldetails(
+ erp, DK4_E_DELETE_FILE_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+#else
+ if (DeleteFileA(fn)) {
+ back = 1;
+ } else {
+ if (NULL != erp) {
+ errno = 0;
+ if (0 == _unlink(fn)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_UNLINK_FAILED, errno);
+ }
+ }
+ }
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+#if DK4_HAVE_UNLINK
+ errno = 0;
+ if (0 == unlink(fn)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_UNLINK_FAILED, errno);
+ }
+#else
+#if DK4_HAVE__UNLINK
+ errno = 0;
+ if (0 == _unlink(fn)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_UNLINK_FAILED, errno);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+#endif
+ /* --- non-Windows */
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4delfile08.h b/support/dktools/dk4delfile08.h
new file mode 100644
index 0000000000..afd3e52cfd
--- /dev/null
+++ b/support/dktools/dk4delfile08.h
@@ -0,0 +1,92 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4delfile08.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4DELFILE08_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4DELFILE08_H_INCLUDED 1
+
+
+#line 10 "dk4delfile08.ctr"
+
+/** @file
+ Remove file specified by char text.
+
+ CRT on Windows: Optional.
+*/
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Remove one file.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_NOT_SUPPORTED<br>
+ if no system function was found to delete files,
+ - DK4_E_UNLINK_FAILED<br>
+ with errno value in idetails if the unlink operation failed,
+ - DK4_E_DELETE_FILE_FAILED<br>
+ with GetLastError() value in lDetails1 if the DeleteFile() function
+ failed on Windows.
+*/
+int
+dk4delete_file_c8(const char *fn, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4delfilewc.c b/support/dktools/dk4delfilewc.c
new file mode 100644
index 0000000000..29bb0b6179
--- /dev/null
+++ b/support/dktools/dk4delfilewc.c
@@ -0,0 +1,144 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4delfilewc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4delfilewc.c The dk4delfilewc module.
+*/
+
+
+#line 60 "dk4delfilewc.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4delfilewc.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_WCHAR_H
+#ifndef WCHAR_H_INCLUDED
+#include <wchar.h>
+#define WCHAR_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+
+
+int
+dk4delete_file_wc(const wchar_t *fn, dk4_er_t *erp)
+{
+ int back = 0;
+ if (NULL != fn) {
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ if (DeleteFileW(fn)) {
+ back = 1;
+ } else {
+ dk4error_set_ldetails(
+ erp, DK4_E_DELETE_FILE_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+#else
+ if (DeleteFileW(fn)) {
+ back = 1;
+ } else {
+ if (NULL != erp) {
+ errno = 0;
+ if (0 == _wunlink(fn)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_UNLINK_FAILED, errno);
+ }
+ }
+ }
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+#if DK4_HAVE_WUNLINK
+ errno = 0;
+ if (0 == wunlink(fn)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_UNLINK_FAILED, errno);
+ }
+#else
+#if DK4_HAVE__WUNLINK
+ errno = 0;
+ if (0 == _wunlink(fn)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_UNLINK_FAILED, errno);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+#endif
+ /* --- non-Windows */
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4delfilewc.ctr b/support/dktools/dk4delfilewc.ctr
new file mode 100644
index 0000000000..4b5d2c5a79
--- /dev/null
+++ b/support/dktools/dk4delfilewc.ctr
@@ -0,0 +1,163 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Remove file specified by wchar_t text.
+
+ CRT on Windows: Optional.
+*/
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Remove one file.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_NOT_SUPPORTED<br>
+ if no system function was found to delete files,
+ - DK4_E_UNLINK_FAILED<br>
+ with errno value in idetails if the wunlink operation failed,
+ - DK4_E_DELETE_FILE_FAILED<br>
+ with GetLastError() value in lDetails1 if the DeleteFile() function
+ failed on Windows.
+*/
+int
+dk4delete_file_wc(const wchar_t *fn, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4delfilewc.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_WCHAR_H
+#ifndef WCHAR_H_INCLUDED
+#include <wchar.h>
+#define WCHAR_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+
+
+int
+dk4delete_file_wc(const wchar_t *fn, dk4_er_t *erp)
+{
+ int back = 0;
+ if (NULL != fn) {
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ if (DeleteFileW(fn)) {
+ back = 1;
+ } else {
+ dk4error_set_ldetails(
+ erp, DK4_E_DELETE_FILE_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+#else
+ if (DeleteFileW(fn)) {
+ back = 1;
+ } else {
+ if (NULL != erp) {
+ errno = 0;
+ if (0 == _wunlink(fn)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_UNLINK_FAILED, errno);
+ }
+ }
+ }
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+#if DK4_HAVE_WUNLINK
+ errno = 0;
+ if (0 == wunlink(fn)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_UNLINK_FAILED, errno);
+ }
+#else
+#if DK4_HAVE__WUNLINK
+ errno = 0;
+ if (0 == _wunlink(fn)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_UNLINK_FAILED, errno);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+#endif
+ /* --- non-Windows */
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4delfilewc.h b/support/dktools/dk4delfilewc.h
new file mode 100644
index 0000000000..c7ef400e40
--- /dev/null
+++ b/support/dktools/dk4delfilewc.h
@@ -0,0 +1,92 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4delfilewc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4DELFILEWC_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4DELFILEWC_H_INCLUDED 1
+
+
+#line 10 "dk4delfilewc.ctr"
+
+/** @file
+ Remove file specified by wchar_t text.
+
+ CRT on Windows: Optional.
+*/
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Remove one file.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_NOT_SUPPORTED<br>
+ if no system function was found to delete files,
+ - DK4_E_UNLINK_FAILED<br>
+ with errno value in idetails if the wunlink operation failed,
+ - DK4_E_DELETE_FILE_FAILED<br>
+ with GetLastError() value in lDetails1 if the DeleteFile() function
+ failed on Windows.
+*/
+int
+dk4delete_file_wc(const wchar_t *fn, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4dir.c b/support/dktools/dk4dir.c
new file mode 100644
index 0000000000..fef2f2508b
--- /dev/null
+++ b/support/dktools/dk4dir.c
@@ -0,0 +1,145 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4dir.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4dir.c The dk4dir module.
+*/
+
+
+#line 166 "dk4dir.ctr"
+
+#include "dk4dir.h"
+#if DK4_CHAR_SIZE > 1
+#include "dk4dirwc.h"
+#else
+#include "dk4dir08.h"
+#endif
+
+
+
+dk4_dir_t *
+dk4dir_open(const dkChar *path, int om, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4dir_wc_open(path, om, erp));
+#else
+ return (dk4dir_c8_open(path, om, erp));
+#endif
+}
+
+
+
+void
+dk4dir_close(dk4_dir_t *dptr)
+{
+#if DK4_CHAR_SIZE > 1
+ dk4dir_wc_close(dptr);
+#else
+ dk4dir_c8_close(dptr);
+#endif
+}
+
+
+
+void
+dk4dir_reset(dk4_dir_t *dptr)
+{
+#if DK4_CHAR_SIZE > 1
+ dk4dir_wc_reset(dptr);
+#else
+ dk4dir_c8_reset(dptr);
+#endif
+}
+
+
+
+const dkChar *
+dk4dir_get_path(dk4_dir_t *dptr)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4dir_wc_get_path(dptr));
+#else
+ return (dk4dir_c8_get_path(dptr));
+#endif
+}
+
+
+
+const dkChar *
+dk4dir_next_dir(dk4_dir_t *dptr)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4dir_wc_next_dir(dptr));
+#else
+ return (dk4dir_c8_next_dir(dptr));
+#endif
+}
+
+
+
+const dkChar *
+dk4dir_next_file(dk4_dir_t *dptr)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4dir_wc_next_file(dptr));
+#else
+ return (dk4dir_c8_next_file(dptr));
+#endif
+}
+
+
+
+
+void
+dk4dir_skip_files(dk4_dir_t *dptr)
+{
+#if DK4_CHAR_SIZE > 1
+ dk4dir_wc_skip_files(dptr);
+#else
+ dk4dir_c8_skip_files(dptr);
+#endif
+}
+
+
+
+size_t
+dk4dir_get_max_entry_length(dk4_dir_t *dptr)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4dir_wc_get_max_entry_length(dptr));
+#else
+ return (dk4dir_c8_get_max_entry_length(dptr));
+#endif
+}
+
diff --git a/support/dktools/dk4dir.ctr b/support/dktools/dk4dir.ctr
new file mode 100644
index 0000000000..b554f6c37b
--- /dev/null
+++ b/support/dktools/dk4dir.ctr
@@ -0,0 +1,270 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Directory traversal using dkChar file names.
+
+ CRT on Windows: Optional.
+*/
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_CHAR_SIZE > 1
+#ifndef DK4DIRWC_H_INCLUDED
+#include "dk4dirwc.h"
+#endif
+#else
+#ifndef DK4DIR08_H_INCLUDED
+#include "dk4dir08.h"
+#endif
+#endif
+
+#if DK4_CHAR_SIZE > 1
+/** Directory listing.
+*/
+typedef dk4_dir_wc_t dk4_dir_t;
+#else
+/** Directory listing.
+*/
+typedef dk4_dir_c8_t dk4_dir_t;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open directory, create directory structure.
+ @param path Directory path name.
+ @param om Opening mode.
+ @param erp Error report, may be NULL.
+ @return Pointer to new directory structure on success, NULL on error.
+ On success use dk4dir_close() to destroy the directory
+ structure.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if path is NULL,
+ - DK4_E_NOT_SUPPORTED<br>
+ if no function to traverse directories was found during build process,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if a memory allocation failed,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in a size calculation,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if one of the involved directory or file names is too long for an
+ internal buffer,
+ - DK4_E_OPENDIR_FAILED<br>
+ with errno value in iDetails1 if the attempt to open the directory
+ failed,
+ - DK4_E_FINDFIRSTFILE_FAILED<br>
+ with GetLastError() value in lDetails1 if the FindFirstFile()
+ function failed on Windows,
+ - DK4_E_SYSTEM<br>
+ if the stat() or lstat() function failed for one of the directory
+ items.
+*/
+dk4_dir_t *
+dk4dir_open(const dkChar *path, int om, dk4_er_t *erp);
+
+/** Destroy directory structure.
+ @param dptr Structure to destroy.
+*/
+void
+dk4dir_close(dk4_dir_t *dptr);
+
+/** Reset directory traversal.
+ @param dptr Directory structure.
+*/
+void
+dk4dir_reset(dk4_dir_t *dptr);
+
+/** Retrieve directory path.
+ @param dptr Directory structure.
+ @return Directory path on success,
+ NULL on error or if no directory was specified for a
+ file name expansion.
+*/
+const dkChar *
+dk4dir_get_path(dk4_dir_t *dptr);
+
+/** Retrieve next directory name.
+ @param dptr Directory structure.
+ @return Pointer to short name on success, NULL if there are no
+ more directories.
+*/
+const dkChar *
+dk4dir_next_dir(dk4_dir_t *dptr);
+
+/** Retrieve next file (non-directory) name.
+ @param dptr Directory structure.
+ @return Pointer to short name on success, NULL if there are no more
+ files.
+*/
+const dkChar *
+dk4dir_next_file(dk4_dir_t *dptr);
+
+/** Skip files (remove information about files, release memory).
+ @param dptr Directory structure.
+*/
+void
+dk4dir_skip_files(dk4_dir_t *dptr);
+
+/** Get maximum entry name length.
+ @param dptr Directory.
+ @return Maximum name length.
+*/
+size_t
+dk4dir_get_max_entry_length(dk4_dir_t *dptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** Open modes for directories.
+*/
+enum {
+
+ /* Value definitions */
+ /** Sort file names.
+ */
+ DK4_DIR_OPEN_SORTED = 1,
+
+ /** Treat symbolic links pointing to
+ directories as files.
+ */
+ DK4_DIR_SYMLINK_DIR_AS_FILE = 2,
+
+ /* Default modes for special purposes */
+
+ /** For deltree we do not follow
+ symbolic links, no need for sorting.
+ */
+ DK4_DIR_OPEN_DELTREE = DK4_DIR_SYMLINK_DIR_AS_FILE
+};
+
+
+
+%% module
+
+#include "dk4dir.h"
+#if DK4_CHAR_SIZE > 1
+#include "dk4dirwc.h"
+#else
+#include "dk4dir08.h"
+#endif
+
+
+
+dk4_dir_t *
+dk4dir_open(const dkChar *path, int om, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4dir_wc_open(path, om, erp));
+#else
+ return (dk4dir_c8_open(path, om, erp));
+#endif
+}
+
+
+
+void
+dk4dir_close(dk4_dir_t *dptr)
+{
+#if DK4_CHAR_SIZE > 1
+ dk4dir_wc_close(dptr);
+#else
+ dk4dir_c8_close(dptr);
+#endif
+}
+
+
+
+void
+dk4dir_reset(dk4_dir_t *dptr)
+{
+#if DK4_CHAR_SIZE > 1
+ dk4dir_wc_reset(dptr);
+#else
+ dk4dir_c8_reset(dptr);
+#endif
+}
+
+
+
+const dkChar *
+dk4dir_get_path(dk4_dir_t *dptr)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4dir_wc_get_path(dptr));
+#else
+ return (dk4dir_c8_get_path(dptr));
+#endif
+}
+
+
+
+const dkChar *
+dk4dir_next_dir(dk4_dir_t *dptr)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4dir_wc_next_dir(dptr));
+#else
+ return (dk4dir_c8_next_dir(dptr));
+#endif
+}
+
+
+
+const dkChar *
+dk4dir_next_file(dk4_dir_t *dptr)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4dir_wc_next_file(dptr));
+#else
+ return (dk4dir_c8_next_file(dptr));
+#endif
+}
+
+
+
+
+void
+dk4dir_skip_files(dk4_dir_t *dptr)
+{
+#if DK4_CHAR_SIZE > 1
+ dk4dir_wc_skip_files(dptr);
+#else
+ dk4dir_c8_skip_files(dptr);
+#endif
+}
+
+
+
+size_t
+dk4dir_get_max_entry_length(dk4_dir_t *dptr)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4dir_wc_get_max_entry_length(dptr));
+#else
+ return (dk4dir_c8_get_max_entry_length(dptr));
+#endif
+}
+
diff --git a/support/dktools/dk4dir.h b/support/dktools/dk4dir.h
new file mode 100644
index 0000000000..b3bb35823b
--- /dev/null
+++ b/support/dktools/dk4dir.h
@@ -0,0 +1,198 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4dir.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4DIR_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4DIR_H_INCLUDED 1
+
+
+#line 10 "dk4dir.ctr"
+
+/** @file
+ Directory traversal using dkChar file names.
+
+ CRT on Windows: Optional.
+*/
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_CHAR_SIZE > 1
+#ifndef DK4DIRWC_H_INCLUDED
+#include "dk4dirwc.h"
+#endif
+#else
+#ifndef DK4DIR08_H_INCLUDED
+#include "dk4dir08.h"
+#endif
+#endif
+
+#if DK4_CHAR_SIZE > 1
+/** Directory listing.
+*/
+typedef dk4_dir_wc_t dk4_dir_t;
+#else
+/** Directory listing.
+*/
+typedef dk4_dir_c8_t dk4_dir_t;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open directory, create directory structure.
+ @param path Directory path name.
+ @param om Opening mode.
+ @param erp Error report, may be NULL.
+ @return Pointer to new directory structure on success, NULL on error.
+ On success use dk4dir_close() to destroy the directory
+ structure.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if path is NULL,
+ - DK4_E_NOT_SUPPORTED<br>
+ if no function to traverse directories was found during build process,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if a memory allocation failed,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in a size calculation,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if one of the involved directory or file names is too long for an
+ internal buffer,
+ - DK4_E_OPENDIR_FAILED<br>
+ with errno value in iDetails1 if the attempt to open the directory
+ failed,
+ - DK4_E_FINDFIRSTFILE_FAILED<br>
+ with GetLastError() value in lDetails1 if the FindFirstFile()
+ function failed on Windows,
+ - DK4_E_SYSTEM<br>
+ if the stat() or lstat() function failed for one of the directory
+ items.
+*/
+dk4_dir_t *
+dk4dir_open(const dkChar *path, int om, dk4_er_t *erp);
+
+/** Destroy directory structure.
+ @param dptr Structure to destroy.
+*/
+void
+dk4dir_close(dk4_dir_t *dptr);
+
+/** Reset directory traversal.
+ @param dptr Directory structure.
+*/
+void
+dk4dir_reset(dk4_dir_t *dptr);
+
+/** Retrieve directory path.
+ @param dptr Directory structure.
+ @return Directory path on success,
+ NULL on error or if no directory was specified for a
+ file name expansion.
+*/
+const dkChar *
+dk4dir_get_path(dk4_dir_t *dptr);
+
+/** Retrieve next directory name.
+ @param dptr Directory structure.
+ @return Pointer to short name on success, NULL if there are no
+ more directories.
+*/
+const dkChar *
+dk4dir_next_dir(dk4_dir_t *dptr);
+
+/** Retrieve next file (non-directory) name.
+ @param dptr Directory structure.
+ @return Pointer to short name on success, NULL if there are no more
+ files.
+*/
+const dkChar *
+dk4dir_next_file(dk4_dir_t *dptr);
+
+/** Skip files (remove information about files, release memory).
+ @param dptr Directory structure.
+*/
+void
+dk4dir_skip_files(dk4_dir_t *dptr);
+
+/** Get maximum entry name length.
+ @param dptr Directory.
+ @return Maximum name length.
+*/
+size_t
+dk4dir_get_max_entry_length(dk4_dir_t *dptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** Open modes for directories.
+*/
+enum {
+
+ /* Value definitions */
+ /** Sort file names.
+ */
+ DK4_DIR_OPEN_SORTED = 1,
+
+ /** Treat symbolic links pointing to
+ directories as files.
+ */
+ DK4_DIR_SYMLINK_DIR_AS_FILE = 2,
+
+ /* Default modes for special purposes */
+
+ /** For deltree we do not follow
+ symbolic links, no need for sorting.
+ */
+ DK4_DIR_OPEN_DELTREE = DK4_DIR_SYMLINK_DIR_AS_FILE
+};
+
+
+
+
+#endif
diff --git a/support/dktools/dk4dir08.c b/support/dktools/dk4dir08.c
new file mode 100644
index 0000000000..3fc428de58
--- /dev/null
+++ b/support/dktools/dk4dir08.c
@@ -0,0 +1,540 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4dir08.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4dir08.c The dk4dir08 module.
+*/
+
+
+#line 146 "dk4dir08.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4dir08.h"
+
+#ifndef DK4DIR_H_INCLUDED
+#include "dk4dir.h"
+#endif
+
+#ifndef DK4STR8_H_INCLUDED
+#include "dk4str8.h"
+#endif
+
+#ifndef DK4STAT_H_INCLUDED
+#include "dk4stat.h"
+#endif
+
+#ifndef DK4STAT8_H_INCLUDED
+#include "dk4stat8.h"
+#endif
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4MPL_H_INCLUDED
+#include "dk4mpl.h"
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_DIRENT_H
+#ifndef DIRENT_H_INCLUDED
+#include <dirent.h>
+#define DIRENT_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+
+
+
+
+#line 206 "dk4dir08.ctr"
+
+
+
+int
+dk4dir_c8_compare(const void *l, const void *r, int cr)
+{
+ int back = 0;
+ if (NULL != l) {
+ if (NULL != r) {
+ back = dk4str8_pathcmp((const char *)l, (const char *)r);
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+static
+void
+dk4dir_c8_clean_storage(dk4_sto_t *s, dk4_sto_it_t *i)
+{
+ char *n;
+ if (NULL != s) {
+ if (NULL != i) {
+ dk4sto_it_reset(i);
+ while (NULL != (n = (char *)dk4sto_it_next(i))) {
+ dk4mem_free(n);
+ }
+ dk4sto_it_close(i);
+ }
+ dk4sto_close(s);
+ }
+}
+
+
+
+void
+dk4dir_c8_close(dk4_dir_c8_t *dptr)
+{
+
+
+#line 250 "dk4dir08.ctr"
+ if (NULL != dptr) {
+ dk4mem_release(dptr->path);
+ dk4dir_c8_clean_storage(dptr->s_dir, dptr->i_dir);
+ dptr->s_dir = NULL; dptr->i_dir = NULL;
+ dk4dir_c8_clean_storage(dptr->s_file, dptr->i_file);
+ dptr->s_file = NULL; dptr->i_file = NULL;
+ dk4mem_free(dptr);
+ }
+
+
+#line 259 "dk4dir08.ctr"
+}
+
+
+
+#if DK4_ON_WINDOWS || DK4_HAVE_DIRENT_H
+/** Fixed texts used by the module.
+*/
+static const char * const dk4dir_c8_kw[] = {
+/* 0 */
+".",
+
+/* 1 */
+"..",
+
+/* 2 */
+"/",
+
+/* 3 */
+"\\",
+
+/* 4 */
+"*",
+
+NULL
+
+
+#line 289 "dk4dir08.ctr"
+};
+
+
+
+static
+int
+dk4dir_c8_fill_directory(dk4_dir_c8_t *dptr, int om, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ char pab[DK4_MAX_PATH]; /* Pattern buffer */
+ WIN32_FIND_DATAA ffdata; /* Find result */
+ HANDLE ffres; /* Result from FindFirstFile */
+ DWORD attr; /* File attributes */
+ char *nn; /* Copy of name, dyn */
+ size_t slen; /* Entry name length */
+ int isdir; /* Flag: Entry is directory */
+ int back = 0;
+
+
+#line 307 "dk4dir08.ctr"
+ if (dk4str8_cpy_s(pab, sizeof(pab), dptr->path, erp)) {
+ if (dk4str8_cat_s(pab, sizeof(pab), dk4dir_c8_kw[3], erp)) {
+ if (dk4str8_cat_s(pab, sizeof(pab), dk4dir_c8_kw[4], erp)) {
+ ffres = FindFirstFileA(pab, &ffdata);
+ if (INVALID_HANDLE_VALUE != ffres) {
+ back = 1;
+ do {
+ if (0 != dk4str8_cmp(dk4dir_c8_kw[0], ffdata.cFileName)) {
+ if (0 != dk4str8_cmp(dk4dir_c8_kw[1], ffdata.cFileName)) {
+ slen = dk4str8_len(ffdata.cFileName);
+ if (slen > dptr->maxlen) { dptr->maxlen = slen; }
+ nn = dk4str8_dup(ffdata.cFileName, erp);
+ if (NULL != nn) {
+ isdir = 0;
+ attr = ffdata.dwFileAttributes;
+ if (0 != (FILE_ATTRIBUTE_DIRECTORY & attr)) {
+ isdir = 1;
+ if (0 != (FILE_ATTRIBUTE_REPARSE_POINT & attr)) {
+ if (0 != (DK4_DIR_SYMLINK_DIR_AS_FILE & om)) {
+ isdir = 0;
+ }
+ }
+ }
+ if (0 != isdir) {
+ if (0 == dk4sto_add(dptr->s_dir, (void *)nn, erp)) {
+ back = 0;
+ dk4mem_free(nn);
+ }
+ } else {
+ if (0 == dk4sto_add(dptr->s_file, (void *)nn, erp)) {
+ back = 0;
+ dk4mem_free(nn);
+ }
+ }
+ } else {
+ back = 0;
+ }
+ }
+ }
+ } while(FindNextFileA(ffres, &ffdata));
+ FindClose(ffres);
+ } else {
+ /* ERROR: FindFirstFile failed */
+ dk4error_set_ldetails(
+ erp, DK4_E_FINDFIRSTFILE_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ }
+ }
+ }
+
+
+#line 359 "dk4dir08.ctr"
+ return back;
+#else
+ char fnb[DK4_MAX_PATH]; /* File name buffer */
+ dk4_stat_t stb; /* Stat buffer */
+ DIR *dir; /* Directory */
+ struct dirent *de; /* Directory entry */
+ char *nn; /* Dynamic copy of file name */
+ size_t slen; /* Entry name length */
+ int isdir = 0; /* Flag: Current item is directory */
+ int back = 0;
+
+
+#line 370 "dk4dir08.ctr"
+ errno = 0;
+ dir = opendir(dptr->path);
+ if (NULL != dir) {
+
+#line 373 "dk4dir08.ctr"
+ back = 1;
+ do {
+ de = readdir(dir);
+ if (NULL != de) {
+ if (0 < (slen = dk4str8_len(de->d_name))) {
+ if (slen > dptr->maxlen) { dptr->maxlen = slen; }
+ if (0 != dk4str8_cmp(dk4dir_c8_kw[0], de->d_name)) {
+ if (0 != dk4str8_cmp(dk4dir_c8_kw[1], de->d_name)) {
+ if (dk4str8_cpy_s(fnb, sizeof(fnb), dptr->path, erp)) {
+ if (dk4str8_cat_s(fnb, sizeof(fnb), dk4dir_c8_kw[2], erp)) {
+ if (dk4str8_cat_s(fnb, sizeof(fnb), de->d_name, erp)) {
+ nn = dk4str8_dup(de->d_name, erp);
+ if (NULL != nn) {
+ isdir = 0;
+ if (0 != dk4stat_c8(&stb, fnb, erp)) {
+ isdir = dk4stat_is_directory(&stb, NULL);
+ if (0 != isdir) {
+ if (0 != (DK4_DIR_SYMLINK_DIR_AS_FILE & om)) {
+ if (0 != dk4stat_l_c8(&stb, fnb, NULL)) {
+ if (dk4stat_is_symlink(&stb, NULL)) {
+ isdir = 0;
+ }
+ }
+ }
+ }
+ } else {
+
+#line 399 "dk4dir08.ctr"
+#if 0
+ /* 2015-04-11 Dangling links are not
+ directories.
+ */
+ back = 0;
+#endif
+ }
+ if (0 != isdir) {
+ if (0 == dk4sto_add(dptr->s_dir, (void *)nn, erp)) {
+ back = 0;
+
+#line 409 "dk4dir08.ctr"
+ dk4mem_free(nn);
+ }
+ } else {
+ if (0 == dk4sto_add(dptr->s_file, (void *)nn, erp)) {
+ back = 0;
+
+#line 414 "dk4dir08.ctr"
+ dk4mem_free(nn);
+ }
+ }
+ } else {
+
+#line 418 "dk4dir08.ctr"
+ back = 0;
+ }
+ } else {
+
+#line 421 "dk4dir08.ctr"
+ back = 0;
+ }
+ } else {
+
+#line 424 "dk4dir08.ctr"
+ back = 0;
+ }
+ } else {
+
+#line 427 "dk4dir08.ctr"
+ back = 0;
+ }
+ }
+ }
+ }
+ }
+ } while(NULL != de);
+ closedir(dir);
+ } else {
+
+#line 436 "dk4dir08.ctr"
+ dk4error_set_idetails(erp, DK4_E_OPENDIR_FAILED, errno);
+ }
+
+#line 438 "dk4dir08.ctr"
+ return back;
+#endif
+}
+#endif
+
+
+
+dk4_dir_c8_t *
+dk4dir_c8_open(const char *path, int om, dk4_er_t *erp)
+{
+ dk4_dir_c8_t *back = NULL;
+ int ok = 0;
+
+
+#line 451 "dk4dir08.ctr"
+ if (NULL != path) {
+#if DK4_ON_WINDOWS || DK4_HAVE_DIRENT_H
+ back = dk4mem_new(dk4_dir_c8_t, 1, erp);
+ if (NULL != back) {
+ back->path = NULL;
+ back->s_dir = NULL;
+ back->i_dir = NULL;
+ back->s_file = NULL;
+ back->i_file = NULL;
+ back->path = dk4str8_dup(path, erp);
+ back->maxlen = 0;
+ if (NULL != back->path) {
+ back->s_dir = dk4sto_open(erp);
+ if (NULL != back->s_dir) {
+ if (0 != (DK4_DIR_OPEN_SORTED & om)) {
+ dk4sto_set_comp(back->s_dir, dk4dir_c8_compare, 0);
+ }
+ back->i_dir = dk4sto_it_open(back->s_dir, erp);
+ if (NULL != back->i_dir) {
+ back->s_file = dk4sto_open(erp);
+ if (NULL != back->s_file) {
+ if (0 != (DK4_DIR_OPEN_SORTED & om)) {
+ dk4sto_set_comp(back->s_file, dk4dir_c8_compare, 0);
+ }
+ back->i_file = dk4sto_it_open(back->s_file, erp);
+ if (NULL != back->i_file) {
+ ok = dk4dir_c8_fill_directory(back, om, erp);
+ }
+ }
+ }
+ }
+ }
+ if (0 == ok) {
+ dk4dir_c8_close(back);
+ back = NULL;
+ }
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 495 "dk4dir08.ctr"
+ return back;
+}
+
+
+
+void
+dk4dir_c8_reset(dk4_dir_c8_t *dptr)
+{
+
+
+#line 504 "dk4dir08.ctr"
+ if (NULL != dptr) {
+ if ((NULL != dptr->s_dir) && (NULL != dptr->i_dir)) {
+ dk4sto_it_reset(dptr->i_dir);
+ }
+ if ((NULL != dptr->s_file) && (NULL != dptr->i_file)) {
+ dk4sto_it_reset(dptr->i_file);
+ }
+ }
+
+
+#line 513 "dk4dir08.ctr"
+}
+
+
+
+const char *
+dk4dir_c8_get_path(dk4_dir_c8_t *dptr)
+{
+ const char *back = NULL;
+
+
+#line 522 "dk4dir08.ctr"
+ if (NULL != dptr) {
+ back = (const char *)(dptr->path);
+ }
+
+
+#line 526 "dk4dir08.ctr"
+ return back;
+}
+
+
+
+const char *
+dk4dir_c8_next_dir(dk4_dir_c8_t *dptr)
+{
+ const char *back = NULL;
+
+
+#line 536 "dk4dir08.ctr"
+ if (NULL != dptr) {
+ if ((NULL != dptr->s_dir) && (NULL != dptr->i_dir)) {
+ back = (const char *)dk4sto_it_next(dptr->i_dir);
+ }
+ }
+
+
+#line 542 "dk4dir08.ctr"
+ return back;
+}
+
+
+
+const char *
+dk4dir_c8_next_file(dk4_dir_c8_t *dptr)
+{
+ const char *back = NULL;
+
+
+#line 552 "dk4dir08.ctr"
+ if (NULL != dptr) {
+ if ((NULL != dptr->s_file) && (NULL != dptr->i_file)) {
+ back = (const char *)dk4sto_it_next(dptr->i_file);
+ }
+ }
+
+
+#line 558 "dk4dir08.ctr"
+ return back;
+}
+
+
+
+void
+dk4dir_c8_skip_files(dk4_dir_c8_t *dptr)
+{
+
+
+#line 567 "dk4dir08.ctr"
+ if (NULL != dptr) {
+ dk4dir_c8_clean_storage(dptr->s_file, dptr->i_file);
+ dptr->s_file = NULL; dptr->i_file = NULL;
+ }
+
+
+#line 572 "dk4dir08.ctr"
+}
+
+
+
+size_t
+dk4dir_c8_get_max_entry_length(dk4_dir_c8_t *dptr)
+{
+ size_t back = 0;
+
+
+#line 581 "dk4dir08.ctr"
+ if (NULL != dptr) {
+ back = dptr->maxlen;
+ }
+
+
+#line 585 "dk4dir08.ctr"
+ return back;
+}
+
+
diff --git a/support/dktools/dk4dir08.ctr b/support/dktools/dk4dir08.ctr
new file mode 100644
index 0000000000..4759371680
--- /dev/null
+++ b/support/dktools/dk4dir08.ctr
@@ -0,0 +1,588 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Directory traversal using char file names.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4STO_H_INCLUDED
+#include "dk4sto.h"
+#endif
+
+
+/** Directory structure.
+*/
+typedef struct {
+ char *path; /**< Directory path. */
+ dk4_sto_t *s_dir; /**< Storage for directories. */
+ dk4_sto_it_t *i_dir; /**< Iterator for directories. */
+ dk4_sto_t *s_file; /**< Storage for non-directories. */
+ dk4_sto_it_t *i_file; /**< Iterator for non-directories. */
+ size_t maxlen; /**< Maximum entry length. */
+} dk4_dir_c8_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open directory, create directory structure.
+ @param path Directory path name.
+ @param om Opening mode.
+ @param erp Error report, may be NULL.
+ @return Pointer to new directory structure on success, NULL on error.
+ On success use dk4dir_c8_close() to destroy the directory
+ structure.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if path is NULL,
+ - DK4_E_NOT_SUPPORTED<br>
+ if no function to traverse directories was found during build process,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if a memory allocation failed,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in a size calculation,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if one of the involved directory or file names is too long for an
+ internal buffer,
+ - DK4_E_OPENDIR_FAILED<br>
+ with errno value in iDetails1 if the attempt to open the directory
+ failed,
+ - DK4_E_FINDFIRSTFILE_FAILED<br>
+ with GetLastError() value in lDetails1 if the FindFirstFile()
+ function failed on Windows,
+ - DK4_E_SYSTEM<br>
+ if the stat() or lstat() function failed for one of the directory
+ items.
+*/
+dk4_dir_c8_t *
+dk4dir_c8_open(const char *path, int om, dk4_er_t *erp);
+
+/** Destroy directory structure.
+ @param dptr Structure to destroy.
+*/
+void
+dk4dir_c8_close(dk4_dir_c8_t *dptr);
+
+/** Reset directory traversal.
+ @param dptr Directory structure.
+*/
+void
+dk4dir_c8_reset(dk4_dir_c8_t *dptr);
+
+/** Retrieve directory path.
+ @param dptr Directory structure.
+ @return Directory path on success,
+ NULL on error or if no directory was specified for a
+ file name expansion.
+*/
+const char *
+dk4dir_c8_get_path(dk4_dir_c8_t *dptr);
+
+/** Retrieve next directory name.
+ @param dptr Directory structure.
+ @return Pointer to short name on success, NULL if there are no
+ more directories.
+*/
+const char *
+dk4dir_c8_next_dir(dk4_dir_c8_t *dptr);
+
+/** Retrieve next file (non-directory) name.
+ @param dptr Directory structure.
+ @return Pointer to short name on success, NULL if there are no more
+ files.
+*/
+const char *
+dk4dir_c8_next_file(dk4_dir_c8_t *dptr);
+
+/** Skip files (remove information about files, release memory).
+ @param dptr Directory structure.
+*/
+void
+dk4dir_c8_skip_files(dk4_dir_c8_t *dptr);
+
+/** Compare two file or directory names.
+ @param l Left name.
+ @param r Right name.
+ @param cr Comparison criteria (ignored).
+ @return 1 if l>r, 0 if l=r, -1 if l<r.
+*/
+int
+dk4dir_c8_compare(const void *l, const void *r, int cr);
+
+/** Get maximum entry name length.
+ @param dptr Directory.
+ @return Maximum name length.
+*/
+size_t
+dk4dir_c8_get_max_entry_length(dk4_dir_c8_t *dptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4dir08.h"
+
+#ifndef DK4DIR_H_INCLUDED
+#include "dk4dir.h"
+#endif
+
+#ifndef DK4STR8_H_INCLUDED
+#include "dk4str8.h"
+#endif
+
+#ifndef DK4STAT_H_INCLUDED
+#include "dk4stat.h"
+#endif
+
+#ifndef DK4STAT8_H_INCLUDED
+#include "dk4stat8.h"
+#endif
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4MPL_H_INCLUDED
+#include "dk4mpl.h"
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_DIRENT_H
+#ifndef DIRENT_H_INCLUDED
+#include <dirent.h>
+#define DIRENT_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+
+
+$!trace-include
+
+
+
+int
+dk4dir_c8_compare(const void *l, const void *r, int cr)
+{
+ int back = 0;
+ if (NULL != l) {
+ if (NULL != r) {
+ back = dk4str8_pathcmp((const char *)l, (const char *)r);
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+static
+void
+dk4dir_c8_clean_storage(dk4_sto_t *s, dk4_sto_it_t *i)
+{
+ char *n;
+ if (NULL != s) {
+ if (NULL != i) {
+ dk4sto_it_reset(i);
+ while (NULL != (n = (char *)dk4sto_it_next(i))) {
+ dk4mem_free(n);
+ }
+ dk4sto_it_close(i);
+ }
+ dk4sto_close(s);
+ }
+}
+
+
+
+void
+dk4dir_c8_close(dk4_dir_c8_t *dptr)
+{
+ $? "+ dk4dir_c8_close"
+ if (NULL != dptr) {
+ dk4mem_release(dptr->path);
+ dk4dir_c8_clean_storage(dptr->s_dir, dptr->i_dir);
+ dptr->s_dir = NULL; dptr->i_dir = NULL;
+ dk4dir_c8_clean_storage(dptr->s_file, dptr->i_file);
+ dptr->s_file = NULL; dptr->i_file = NULL;
+ dk4mem_free(dptr);
+ }
+ $? "- dk4dir_c8_close"
+}
+
+
+
+#if DK4_ON_WINDOWS || DK4_HAVE_DIRENT_H
+/** Fixed texts used by the module.
+*/
+static const char * const dk4dir_c8_kw[] = {
+$!string-table
+#
+# 0 Current directory
+#
+.
+#
+# 1 Parent directory
+#
+..
+#
+# 2 Separator for non-Windows systems
+#
+/
+#
+# 3 Separator for Windows systems
+#
+\\
+#
+# 4 Pattern for all files
+#
+*
+$!end
+};
+
+
+
+static
+int
+dk4dir_c8_fill_directory(dk4_dir_c8_t *dptr, int om, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ char pab[DK4_MAX_PATH]; /* Pattern buffer */
+ WIN32_FIND_DATAA ffdata; /* Find result */
+ HANDLE ffres; /* Result from FindFirstFile */
+ DWORD attr; /* File attributes */
+ char *nn; /* Copy of name, dyn */
+ size_t slen; /* Entry name length */
+ int isdir; /* Flag: Entry is directory */
+ int back = 0;
+ $? "+ dk4dir_c8_fill_directory"
+ if (dk4str8_cpy_s(pab, sizeof(pab), dptr->path, erp)) {
+ if (dk4str8_cat_s(pab, sizeof(pab), dk4dir_c8_kw[3], erp)) {
+ if (dk4str8_cat_s(pab, sizeof(pab), dk4dir_c8_kw[4], erp)) {
+ ffres = FindFirstFileA(pab, &ffdata);
+ if (INVALID_HANDLE_VALUE != ffres) {
+ back = 1;
+ do {
+ if (0 != dk4str8_cmp(dk4dir_c8_kw[0], ffdata.cFileName)) {
+ if (0 != dk4str8_cmp(dk4dir_c8_kw[1], ffdata.cFileName)) {
+ slen = dk4str8_len(ffdata.cFileName);
+ if (slen > dptr->maxlen) { dptr->maxlen = slen; }
+ nn = dk4str8_dup(ffdata.cFileName, erp);
+ if (NULL != nn) {
+ isdir = 0;
+ attr = ffdata.dwFileAttributes;
+ if (0 != (FILE_ATTRIBUTE_DIRECTORY & attr)) {
+ isdir = 1;
+ if (0 != (FILE_ATTRIBUTE_REPARSE_POINT & attr)) {
+ if (0 != (DK4_DIR_SYMLINK_DIR_AS_FILE & om)) {
+ isdir = 0;
+ }
+ }
+ }
+ if (0 != isdir) {
+ if (0 == dk4sto_add(dptr->s_dir, (void *)nn, erp)) {
+ back = 0;
+ dk4mem_free(nn);
+ }
+ } else {
+ if (0 == dk4sto_add(dptr->s_file, (void *)nn, erp)) {
+ back = 0;
+ dk4mem_free(nn);
+ }
+ }
+ } else {
+ back = 0;
+ }
+ }
+ }
+ } while(FindNextFileA(ffres, &ffdata));
+ FindClose(ffres);
+ } else {
+ /* ERROR: FindFirstFile failed */
+ dk4error_set_ldetails(
+ erp, DK4_E_FINDFIRSTFILE_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ }
+ }
+ }
+ $? "- dk4dir_c8_fill_directory %d", back
+ return back;
+#else
+ char fnb[DK4_MAX_PATH]; /* File name buffer */
+ dk4_stat_t stb; /* Stat buffer */
+ DIR *dir; /* Directory */
+ struct dirent *de; /* Directory entry */
+ char *nn; /* Dynamic copy of file name */
+ size_t slen; /* Entry name length */
+ int isdir = 0; /* Flag: Current item is directory */
+ int back = 0;
+ $? "+ dk4dir_c8_fill_directory"
+ errno = 0;
+ dir = opendir(dptr->path);
+ if (NULL != dir) { $? ". opendir"
+ back = 1;
+ do {
+ de = readdir(dir);
+ if (NULL != de) {
+ if (0 < (slen = dk4str8_len(de->d_name))) {
+ if (slen > dptr->maxlen) { dptr->maxlen = slen; }
+ if (0 != dk4str8_cmp(dk4dir_c8_kw[0], de->d_name)) {
+ if (0 != dk4str8_cmp(dk4dir_c8_kw[1], de->d_name)) {
+ if (dk4str8_cpy_s(fnb, sizeof(fnb), dptr->path, erp)) {
+ if (dk4str8_cat_s(fnb, sizeof(fnb), dk4dir_c8_kw[2], erp)) {
+ if (dk4str8_cat_s(fnb, sizeof(fnb), de->d_name, erp)) {
+ nn = dk4str8_dup(de->d_name, erp);
+ if (NULL != nn) {
+ isdir = 0;
+ if (0 != dk4stat_c8(&stb, fnb, erp)) {
+ isdir = dk4stat_is_directory(&stb, NULL);
+ if (0 != isdir) {
+ if (0 != (DK4_DIR_SYMLINK_DIR_AS_FILE & om)) {
+ if (0 != dk4stat_l_c8(&stb, fnb, NULL)) {
+ if (dk4stat_is_symlink(&stb, NULL)) {
+ isdir = 0;
+ }
+ }
+ }
+ }
+ } else { $? "! stat"
+#if 0
+ /* 2015-04-11 Dangling links are not
+ directories.
+ */
+ back = 0;
+#endif
+ }
+ if (0 != isdir) {
+ if (0 == dk4sto_add(dptr->s_dir, (void *)nn, erp)) {
+ back = 0; $? "! memory"
+ dk4mem_free(nn);
+ }
+ } else {
+ if (0 == dk4sto_add(dptr->s_file, (void *)nn, erp)) {
+ back = 0; $? "! memory"
+ dk4mem_free(nn);
+ }
+ }
+ } else { $? "! memory"
+ back = 0;
+ }
+ } else { $? "! buffer too small"
+ back = 0;
+ }
+ } else { $? "! buffer too small"
+ back = 0;
+ }
+ } else { $? "! buffer too small"
+ back = 0;
+ }
+ }
+ }
+ }
+ }
+ } while(NULL != de);
+ closedir(dir);
+ } else { $? "! opendir"
+ dk4error_set_idetails(erp, DK4_E_OPENDIR_FAILED, errno);
+ } $? "- dk4dir_c8_fill_directory %d", back
+ return back;
+#endif
+}
+#endif
+
+
+
+dk4_dir_c8_t *
+dk4dir_c8_open(const char *path, int om, dk4_er_t *erp)
+{
+ dk4_dir_c8_t *back = NULL;
+ int ok = 0;
+ $? "+ dk4dir_c8_open \"%!8s\"", TR_8STR(path)
+ if (NULL != path) {
+#if DK4_ON_WINDOWS || DK4_HAVE_DIRENT_H
+ back = dk4mem_new(dk4_dir_c8_t, 1, erp);
+ if (NULL != back) {
+ back->path = NULL;
+ back->s_dir = NULL;
+ back->i_dir = NULL;
+ back->s_file = NULL;
+ back->i_file = NULL;
+ back->path = dk4str8_dup(path, erp);
+ back->maxlen = 0;
+ if (NULL != back->path) {
+ back->s_dir = dk4sto_open(erp);
+ if (NULL != back->s_dir) {
+ if (0 != (DK4_DIR_OPEN_SORTED & om)) {
+ dk4sto_set_comp(back->s_dir, dk4dir_c8_compare, 0);
+ }
+ back->i_dir = dk4sto_it_open(back->s_dir, erp);
+ if (NULL != back->i_dir) {
+ back->s_file = dk4sto_open(erp);
+ if (NULL != back->s_file) {
+ if (0 != (DK4_DIR_OPEN_SORTED & om)) {
+ dk4sto_set_comp(back->s_file, dk4dir_c8_compare, 0);
+ }
+ back->i_file = dk4sto_it_open(back->s_file, erp);
+ if (NULL != back->i_file) {
+ ok = dk4dir_c8_fill_directory(back, om, erp);
+ }
+ }
+ }
+ }
+ }
+ if (0 == ok) {
+ dk4dir_c8_close(back);
+ back = NULL;
+ }
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4dir_c8_open PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+void
+dk4dir_c8_reset(dk4_dir_c8_t *dptr)
+{
+ $? "+ dk4dir_c8_reset"
+ if (NULL != dptr) {
+ if ((NULL != dptr->s_dir) && (NULL != dptr->i_dir)) {
+ dk4sto_it_reset(dptr->i_dir);
+ }
+ if ((NULL != dptr->s_file) && (NULL != dptr->i_file)) {
+ dk4sto_it_reset(dptr->i_file);
+ }
+ }
+ $? "- dk4dir_c8_reset"
+}
+
+
+
+const char *
+dk4dir_c8_get_path(dk4_dir_c8_t *dptr)
+{
+ const char *back = NULL;
+ $? "+ dk4dir_c8_get_path"
+ if (NULL != dptr) {
+ back = (const char *)(dptr->path);
+ }
+ $? "- dk4dir_c8_get_path \"%!8s\"", TR_8STR(back)
+ return back;
+}
+
+
+
+const char *
+dk4dir_c8_next_dir(dk4_dir_c8_t *dptr)
+{
+ const char *back = NULL;
+ $? "+ dk4dir_c8_next_dir"
+ if (NULL != dptr) {
+ if ((NULL != dptr->s_dir) && (NULL != dptr->i_dir)) {
+ back = (const char *)dk4sto_it_next(dptr->i_dir);
+ }
+ }
+ $? "- dk4dir_c8_next_dir \"%!8s\"", TR_8STR(back)
+ return back;
+}
+
+
+
+const char *
+dk4dir_c8_next_file(dk4_dir_c8_t *dptr)
+{
+ const char *back = NULL;
+ $? "+ dk4dir_c8_next_file"
+ if (NULL != dptr) {
+ if ((NULL != dptr->s_file) && (NULL != dptr->i_file)) {
+ back = (const char *)dk4sto_it_next(dptr->i_file);
+ }
+ }
+ $? "- dk4dir_c8_next_file \"%!8s\"", TR_8STR(back)
+ return back;
+}
+
+
+
+void
+dk4dir_c8_skip_files(dk4_dir_c8_t *dptr)
+{
+ $? "+ dk4dir_c8_skip_files"
+ if (NULL != dptr) {
+ dk4dir_c8_clean_storage(dptr->s_file, dptr->i_file);
+ dptr->s_file = NULL; dptr->i_file = NULL;
+ }
+ $? "- dk4dir_c8_skip_files"
+}
+
+
+
+size_t
+dk4dir_c8_get_max_entry_length(dk4_dir_c8_t *dptr)
+{
+ size_t back = 0;
+ $? "+ dk4dir_c8_get_max_entry_length"
+ if (NULL != dptr) {
+ back = dptr->maxlen;
+ }
+ $? "- dk4dir_c8_get_max_entry_length %lu", (unsigned long)back
+ return back;
+}
+
+
diff --git a/support/dktools/dk4dir08.h b/support/dktools/dk4dir08.h
new file mode 100644
index 0000000000..ff82352e32
--- /dev/null
+++ b/support/dktools/dk4dir08.h
@@ -0,0 +1,178 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4dir08.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4DIR08_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4DIR08_H_INCLUDED 1
+
+
+#line 10 "dk4dir08.ctr"
+
+/** @file
+ Directory traversal using char file names.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4STO_H_INCLUDED
+#include "dk4sto.h"
+#endif
+
+
+/** Directory structure.
+*/
+typedef struct {
+ char *path; /**< Directory path. */
+ dk4_sto_t *s_dir; /**< Storage for directories. */
+ dk4_sto_it_t *i_dir; /**< Iterator for directories. */
+ dk4_sto_t *s_file; /**< Storage for non-directories. */
+ dk4_sto_it_t *i_file; /**< Iterator for non-directories. */
+ size_t maxlen; /**< Maximum entry length. */
+} dk4_dir_c8_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open directory, create directory structure.
+ @param path Directory path name.
+ @param om Opening mode.
+ @param erp Error report, may be NULL.
+ @return Pointer to new directory structure on success, NULL on error.
+ On success use dk4dir_c8_close() to destroy the directory
+ structure.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if path is NULL,
+ - DK4_E_NOT_SUPPORTED<br>
+ if no function to traverse directories was found during build process,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if a memory allocation failed,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in a size calculation,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if one of the involved directory or file names is too long for an
+ internal buffer,
+ - DK4_E_OPENDIR_FAILED<br>
+ with errno value in iDetails1 if the attempt to open the directory
+ failed,
+ - DK4_E_FINDFIRSTFILE_FAILED<br>
+ with GetLastError() value in lDetails1 if the FindFirstFile()
+ function failed on Windows,
+ - DK4_E_SYSTEM<br>
+ if the stat() or lstat() function failed for one of the directory
+ items.
+*/
+dk4_dir_c8_t *
+dk4dir_c8_open(const char *path, int om, dk4_er_t *erp);
+
+/** Destroy directory structure.
+ @param dptr Structure to destroy.
+*/
+void
+dk4dir_c8_close(dk4_dir_c8_t *dptr);
+
+/** Reset directory traversal.
+ @param dptr Directory structure.
+*/
+void
+dk4dir_c8_reset(dk4_dir_c8_t *dptr);
+
+/** Retrieve directory path.
+ @param dptr Directory structure.
+ @return Directory path on success,
+ NULL on error or if no directory was specified for a
+ file name expansion.
+*/
+const char *
+dk4dir_c8_get_path(dk4_dir_c8_t *dptr);
+
+/** Retrieve next directory name.
+ @param dptr Directory structure.
+ @return Pointer to short name on success, NULL if there are no
+ more directories.
+*/
+const char *
+dk4dir_c8_next_dir(dk4_dir_c8_t *dptr);
+
+/** Retrieve next file (non-directory) name.
+ @param dptr Directory structure.
+ @return Pointer to short name on success, NULL if there are no more
+ files.
+*/
+const char *
+dk4dir_c8_next_file(dk4_dir_c8_t *dptr);
+
+/** Skip files (remove information about files, release memory).
+ @param dptr Directory structure.
+*/
+void
+dk4dir_c8_skip_files(dk4_dir_c8_t *dptr);
+
+/** Compare two file or directory names.
+ @param l Left name.
+ @param r Right name.
+ @param cr Comparison criteria (ignored).
+ @return 1 if l>r, 0 if l=r, -1 if l<r.
+*/
+int
+dk4dir_c8_compare(const void *l, const void *r, int cr);
+
+/** Get maximum entry name length.
+ @param dptr Directory.
+ @return Maximum name length.
+*/
+size_t
+dk4dir_c8_get_max_entry_length(dk4_dir_c8_t *dptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4dira.c b/support/dktools/dk4dira.c
new file mode 100644
index 0000000000..b6671838b1
--- /dev/null
+++ b/support/dktools/dk4dira.c
@@ -0,0 +1,212 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4dira.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4dira.c The dk4dira module.
+*/
+
+
+#line 38 "dk4dira.ctr"
+
+
+#include "dk4conf.h"
+#include "dk4const.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4mem.h"
+#include "dk4dira.h"
+#include "dk4error.h"
+#if DK4_ON_WINDOWS
+#include "dk4maodd.h"
+#include "dk4maodh.h"
+#endif
+
+
+
+
+#line 67 "dk4dira.ctr"
+
+
+
+dk4_dir_t *
+dk4dir_open_app(const dkChar *path, int om, dk4_app_t *app)
+{
+#if DK4_ON_WINDOWS
+ dkChar eb1[8 * sizeof(dk4_um_t) + 16];
+ dkChar eb2[8 * sizeof(dk4_um_t) + 16];
+#endif
+ dk4_er_t er;
+ dk4_dir_t *back = NULL;
+#if DK4_ON_WINDOWS
+ DWORD le;
+ int found;
+ int res;
+#endif
+ if (NULL != path) {
+ dk4error_init(&er);
+ back = dk4dir_open(path, om, &er);
+ if (NULL == back) {
+ switch (er.ec) {
+ case DK4_E_NOT_SUPPORTED : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 145, path);
+ } break;
+ case DK4_E_MEMORY_ALLOCATION_FAILED : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 103, path);
+ } break;
+ case DK4_E_MATH_OVERFLOW : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 146, path);
+ } break;
+ case DK4_E_BUFFER_TOO_SMALL : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 42, path);
+ } break;
+#if !DK4_ON_WINDOWS
+ case DK4_E_OPENDIR_FAILED : {
+ switch (er.dt.iDetails1) {
+#ifdef EACCES
+ case EACCES : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 138, path);
+ } break;
+#endif
+#ifdef EBADF
+ case EBADF : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 122, path);
+ } break;
+#endif
+#ifdef EMFILE
+ case EMFILE : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 114, path);
+ } break;
+#endif
+#ifdef ENFILE
+ case ENFILE : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 115, path);
+ } break;
+#endif
+#ifdef ENOENT
+ case ENOENT : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 51, path);
+ } break;
+#endif
+#ifdef ENOMEM
+ case ENOMEM : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 142, path);
+ } break;
+#endif
+#ifdef ENOTDIR
+ case ENOTDIR : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 150, path);
+ } break;
+#endif
+#ifdef ELOOP
+ case ELOOP : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 61, path);
+ } break;
+#endif
+#ifdef ENAMETOOLONG
+ case ENAMETOOLONG : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 65, path);
+ } break;
+#endif
+ default : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 10, path);
+ } break;
+ }
+ } break;
+#endif
+#if DK4_ON_WINDOWS
+ case DK4_E_FINDFIRSTFILE_FAILED : {
+ le = er.dt.lDetails1;
+ found = 0;
+ if (ERROR_FILE_NOT_FOUND == le) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 147, path);
+ found = 1;
+ }
+ if (ERROR_ACCESS_DENIED == le) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 138, path);
+ found = 1;
+ }
+ if (ERROR_PATH_NOT_FOUND == le) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 51, path);
+ found = 1;
+ }
+ if (ERROR_BAD_NET_NAME == le) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 74, path);
+ found = 1;
+ }
+ if (ERROR_BAD_NETPATH == le) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 75, path);
+ found = 1;
+ }
+ if (0 == found) {
+ res = dk4ma_write_decimal_unsigned(
+ eb1,DK4_SIZEOF(eb1,dkChar),(dk4_um_t)le,0,NULL
+ );
+ if (0 != res) {
+ res = dk4ma_write_hex_unsigned(
+ eb2, DK4_SIZEOF(eb2,dkChar), (dk4_um_t)le, 0, NULL
+ );
+ }
+ if (0 != res) {
+ dk4app_log_base7(app,DK4_LL_ERROR,144,69,70,71,path,eb1,eb2);
+ } else {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 77, path);
+ }
+ }
+ } break;
+#endif
+ default : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 10, path);
+ } break;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+
diff --git a/support/dktools/dk4dira.ctr b/support/dktools/dk4dira.ctr
new file mode 100644
index 0000000000..be79d99182
--- /dev/null
+++ b/support/dktools/dk4dira.ctr
@@ -0,0 +1,207 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk4dira.h Directory operations with application support.
+*/
+
+#include "dk4dir.h"
+#include "dk4app.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open directory.
+ @param path Directory path name.
+ @param om Opening mode.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new directory structure on success, NULL on error.
+ On success use dk4dir_close() to destroy the directory
+ structure.
+*/
+dk4_dir_t *
+dk4dir_open_app(const dkChar *path, int om, dk4_app_t *app);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+
+#include "dk4conf.h"
+#include "dk4const.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4mem.h"
+#include "dk4dira.h"
+#include "dk4error.h"
+#if DK4_ON_WINDOWS
+#include "dk4maodd.h"
+#include "dk4maodh.h"
+#endif
+
+
+$!trace-include
+
+
+
+dk4_dir_t *
+dk4dir_open_app(const dkChar *path, int om, dk4_app_t *app)
+{
+#if DK4_ON_WINDOWS
+ dkChar eb1[8 * sizeof(dk4_um_t) + 16];
+ dkChar eb2[8 * sizeof(dk4_um_t) + 16];
+#endif
+ dk4_er_t er;
+ dk4_dir_t *back = NULL;
+#if DK4_ON_WINDOWS
+ DWORD le;
+ int found;
+ int res;
+#endif
+ if (NULL != path) {
+ dk4error_init(&er);
+ back = dk4dir_open(path, om, &er);
+ if (NULL == back) {
+ switch (er.ec) {
+ case DK4_E_NOT_SUPPORTED : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 145, path);
+ } break;
+ case DK4_E_MEMORY_ALLOCATION_FAILED : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 103, path);
+ } break;
+ case DK4_E_MATH_OVERFLOW : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 146, path);
+ } break;
+ case DK4_E_BUFFER_TOO_SMALL : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 42, path);
+ } break;
+#if !DK4_ON_WINDOWS
+ case DK4_E_OPENDIR_FAILED : {
+ switch (er.dt.iDetails1) {
+#ifdef EACCES
+ case EACCES : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 138, path);
+ } break;
+#endif
+#ifdef EBADF
+ case EBADF : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 122, path);
+ } break;
+#endif
+#ifdef EMFILE
+ case EMFILE : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 114, path);
+ } break;
+#endif
+#ifdef ENFILE
+ case ENFILE : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 115, path);
+ } break;
+#endif
+#ifdef ENOENT
+ case ENOENT : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 51, path);
+ } break;
+#endif
+#ifdef ENOMEM
+ case ENOMEM : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 142, path);
+ } break;
+#endif
+#ifdef ENOTDIR
+ case ENOTDIR : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 150, path);
+ } break;
+#endif
+#ifdef ELOOP
+ case ELOOP : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 61, path);
+ } break;
+#endif
+#ifdef ENAMETOOLONG
+ case ENAMETOOLONG : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 65, path);
+ } break;
+#endif
+ default : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 10, path);
+ } break;
+ }
+ } break;
+#endif
+#if DK4_ON_WINDOWS
+ case DK4_E_FINDFIRSTFILE_FAILED : {
+ le = er.dt.lDetails1;
+ found = 0;
+ if (ERROR_FILE_NOT_FOUND == le) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 147, path);
+ found = 1;
+ }
+ if (ERROR_ACCESS_DENIED == le) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 138, path);
+ found = 1;
+ }
+ if (ERROR_PATH_NOT_FOUND == le) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 51, path);
+ found = 1;
+ }
+ if (ERROR_BAD_NET_NAME == le) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 74, path);
+ found = 1;
+ }
+ if (ERROR_BAD_NETPATH == le) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 75, path);
+ found = 1;
+ }
+ if (0 == found) {
+ res = dk4ma_write_decimal_unsigned(
+ eb1,DK4_SIZEOF(eb1,dkChar),(dk4_um_t)le,0,NULL
+ );
+ if (0 != res) {
+ res = dk4ma_write_hex_unsigned(
+ eb2, DK4_SIZEOF(eb2,dkChar), (dk4_um_t)le, 0, NULL
+ );
+ }
+ if (0 != res) {
+ dk4app_log_base7(app,DK4_LL_ERROR,144,69,70,71,path,eb1,eb2);
+ } else {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 77, path);
+ }
+ }
+ } break;
+#endif
+ default : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 144, 10, path);
+ } break;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+
diff --git a/support/dktools/dk4dira.h b/support/dktools/dk4dira.h
new file mode 100644
index 0000000000..db8925a5a5
--- /dev/null
+++ b/support/dktools/dk4dira.h
@@ -0,0 +1,70 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4dira.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4DIRA_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4DIRA_H_INCLUDED 1
+
+
+#line 10 "dk4dira.ctr"
+
+/** @file dk4dira.h Directory operations with application support.
+*/
+
+#include "dk4dir.h"
+#include "dk4app.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open directory.
+ @param path Directory path name.
+ @param om Opening mode.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new directory structure on success, NULL on error.
+ On success use dk4dir_close() to destroy the directory
+ structure.
+*/
+dk4_dir_t *
+dk4dir_open_app(const dkChar *path, int om, dk4_app_t *app);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4dirwc.c b/support/dktools/dk4dirwc.c
new file mode 100644
index 0000000000..48396f8cc6
--- /dev/null
+++ b/support/dktools/dk4dirwc.c
@@ -0,0 +1,457 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4dirwc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4dirwc.c The dk4dirwc module.
+*/
+
+
+#line 146 "dk4dirwc.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4dirwc.h"
+
+#ifndef DK4DIR_H_INCLUDED
+#include "dk4dir.h"
+#endif
+
+#ifndef DK4STR8_H_INCLUDED
+#include "dk4strw.h"
+#endif
+
+#ifndef DK4STAT_H_INCLUDED
+#include "dk4stat.h"
+#endif
+
+#ifndef DK4STAT8_H_INCLUDED
+#include "dk4statw.h"
+#endif
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4MPL_H_INCLUDED
+#include "dk4mpl.h"
+#endif
+
+#ifndef DK4MAASZ_H_INCLUDED
+#include "dk4maasz.h"
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_WCHAR_H
+#ifndef WCHAR_H_INCLUDED
+#include <wchar.h>
+#define WCHAR_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_DIRENT_H
+#ifndef DIRENT_H_INCLUDED
+#include <dirent.h>
+#define DIRENT_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+
+
+
+
+#line 217 "dk4dirwc.ctr"
+
+
+
+#if DK4_ON_WINDOWS
+
+int
+dk4dir_wc_compare(const void *l, const void *r, int cr)
+{
+ int back = 0;
+ if (NULL != l) {
+ if (NULL != r) {
+ back = dk4strw_pathcmp((const wchar_t *)l, (const wchar_t *)r);
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != r) { back = -1; }
+ }
+ return back;
+}
+
+#endif
+
+
+
+static
+void
+dk4dir_wc_clean_storage(dk4_sto_t *s, dk4_sto_it_t *i)
+{
+ wchar_t *n;
+ if (NULL != s) {
+ if (NULL != i) {
+ dk4sto_it_reset(i);
+ while (NULL != (n = (wchar_t *)dk4sto_it_next(i))) {
+ dk4mem_free(n);
+ }
+ dk4sto_it_close(i);
+ }
+ dk4sto_close(s);
+ }
+}
+
+
+
+void
+dk4dir_wc_close(dk4_dir_wc_t *dptr)
+{
+ if (NULL != dptr) {
+ dk4mem_release(dptr->path);
+ dk4dir_wc_clean_storage(dptr->s_dir, dptr->i_dir);
+ dptr->s_dir = NULL; dptr->i_dir = NULL;
+ dk4dir_wc_clean_storage(dptr->s_file, dptr->i_file);
+ dptr->s_file = NULL; dptr->i_file = NULL;
+ dk4mem_free(dptr);
+ }
+}
+
+
+
+#if DK4_ON_WINDOWS
+/** Fixed texts used by the module.
+*/
+static const wchar_t * const dk4dir_wc_kw[] = {
+/* 0 */
+L".",
+
+/* 1 */
+L"..",
+
+/* 2 */
+L"/",
+
+/* 3 */
+L"\\",
+
+/* 4 */
+L"*",
+
+NULL
+
+
+#line 302 "dk4dirwc.ctr"
+};
+
+
+
+static
+int
+dk4dir_wc_fill_with_pab(
+ dk4_dir_wc_t *dptr,
+ int om,
+ wchar_t *pab,
+ size_t szpab,
+ dk4_er_t *erp
+)
+{
+ WIN32_FIND_DATAW ffdata; /* Find result */
+ HANDLE ffres; /* Result from findfirst */
+ dkChar *nn; /* Copy of name, dyn */
+ DWORD attr; /* File attributes */
+ size_t slen; /* Entry name length. */
+ int isdir; /* Flag: Entry is directory */
+ int back = 0;
+
+
+#line 324 "dk4dirwc.ctr"
+ if (dk4strw_cpy_s(pab, szpab, dptr->path, erp)) {
+ if (dk4strw_cat_s(pab, szpab, dk4dir_wc_kw[3], erp)) {
+ if (dk4strw_cat_s(pab, szpab, dk4dir_wc_kw[4], erp)) {
+ ffres = FindFirstFileW(pab, &ffdata);
+ if (INVALID_HANDLE_VALUE != ffres) {
+ back = 1;
+ do {
+ if (0 != dk4strw_cmp(dk4dir_wc_kw[0], ffdata.cFileName)) {
+ if (0 != dk4strw_cmp(dk4dir_wc_kw[1], ffdata.cFileName)) {
+ slen = dk4strw_len(ffdata.cFileName);
+ if (slen > dptr->maxlen) { dptr->maxlen = slen; }
+ nn = dk4strw_dup(ffdata.cFileName, erp);
+ if (NULL != nn) {
+ isdir = 0;
+ attr = ffdata.dwFileAttributes;
+ if (0 != (FILE_ATTRIBUTE_DIRECTORY & attr)) {
+ isdir = 1;
+ if (0 != (FILE_ATTRIBUTE_REPARSE_POINT & attr)) {
+ if (0 != (DK4_DIR_SYMLINK_DIR_AS_FILE & om)) {
+ isdir = 0;
+ }
+ }
+ }
+ if (0 != isdir) {
+ if (0 == dk4sto_add(dptr->s_dir, (void *)nn, erp)) {
+ back = 0;
+ dk4mem_free(nn);
+ }
+ } else {
+ if (0 == dk4sto_add(dptr->s_file, (void *)nn, erp)) {
+ back = 0;
+ dk4mem_free(nn);
+ }
+ }
+ } else {
+ back = 0;
+ }
+ }
+ }
+ } while(FindNextFileW(ffres, &ffdata));
+ FindClose(ffres);
+ } else {
+ /* ERROR: FindFirstFile failed */
+ dk4error_set_ldetails(
+ erp, DK4_E_FINDFIRSTFILE_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ }
+ }
+ }
+
+
+#line 376 "dk4dirwc.ctr"
+ return back;
+}
+
+
+
+static
+int
+dk4dir_wc_fill_with_local(dk4_dir_wc_t *dptr, int om, dk4_er_t *erp)
+{
+ wchar_t pab[DK4_MAX_PATH];
+ return (dk4dir_wc_fill_with_pab(dptr, om, pab, DK4_SIZEOF(pab,wchar_t), erp));
+}
+
+
+
+/** Fill directory structure with data about subdirectories and files.
+ @param dptr Directory structure to fill.
+ @param om Opening mode.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on errors.
+*/
+static
+int
+dk4dir_wc_fill_directory(dk4_dir_wc_t *dptr, int om, dk4_er_t *erp)
+{
+ dk4_er_t er;
+ wchar_t *pab;
+ size_t dptrlgt;
+ int back = 0;
+
+ dptrlgt = dk4strw_len(dptr->path);
+ if ((DK4_MAX_PATH - 2) > dptrlgt) {
+ back = dk4dir_wc_fill_with_local(dptr, om, erp);
+ } else {
+ dk4error_init(&er);
+ dptrlgt = dk4ma_size_t_add(dptrlgt, 3, &er);
+ if (DK4_E_NONE == er.ec) {
+ pab = dk4mem_new(wchar_t, dptrlgt, erp);
+ if (NULL != pab) {
+ back = dk4dir_wc_fill_with_pab(dptr, om, pab, dptrlgt, erp);
+ dk4mem_free(pab);
+ }
+ } else {
+ dk4error_copy(erp, &er);
+ }
+ }
+ return back;
+}
+
+#endif
+
+
+
+dk4_dir_wc_t *
+dk4dir_wc_open(const wchar_t *path, int om, dk4_er_t *erp)
+{
+ dk4_dir_wc_t *back = NULL;
+#if DK4_ON_WINDOWS
+ int ok = 0;
+#endif
+ if (NULL != path) {
+#if DK4_ON_WINDOWS
+ back = dk4mem_new(dk4_dir_wc_t, 1, erp);
+ if (NULL != back) {
+ back->path = NULL;
+ back->s_dir = NULL;
+ back->i_dir = NULL;
+ back->s_file = NULL;
+ back->i_file = NULL;
+ back->path = dk4strw_dup(path, erp);
+ back->maxlen = 0;
+ if (NULL != back->path) {
+ back->s_dir = dk4sto_open(erp);
+ if (NULL != back->s_dir) {
+ if (0 != (DK4_DIR_OPEN_SORTED & om)) {
+ dk4sto_set_comp(back->s_dir, dk4dir_wc_compare, 0);
+ }
+ back->i_dir = dk4sto_it_open(back->s_dir, erp);
+ if (NULL != back->i_dir) {
+ back->s_file = dk4sto_open(erp);
+ if (NULL != back->s_file) {
+ if (0 != (DK4_DIR_OPEN_SORTED & om)) {
+ dk4sto_set_comp(back->s_file, dk4dir_wc_compare, 0);
+ }
+ back->i_file = dk4sto_it_open(back->s_file, erp);
+ if (NULL != back->i_file) {
+ ok = dk4dir_wc_fill_directory(back, om, erp);
+ }
+ }
+ }
+ }
+ }
+ if (0 == ok) {
+ dk4dir_wc_close(back);
+ back = NULL;
+ }
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+void
+dk4dir_wc_reset(dk4_dir_wc_t *dptr)
+{
+ if (NULL != dptr) {
+ if ((NULL != dptr->s_dir) && (NULL != dptr->i_dir)) {
+ dk4sto_it_reset(dptr->i_dir);
+ }
+ if ((NULL != dptr->s_file) && (NULL != dptr->i_file)) {
+ dk4sto_it_reset(dptr->i_file);
+ }
+ }
+}
+
+
+
+const wchar_t *
+dk4dir_wc_get_path(dk4_dir_wc_t *dptr)
+{
+ const wchar_t *back = NULL;
+ if (NULL != dptr) {
+ back = (const wchar_t *)(dptr->path);
+ }
+ return back;
+}
+
+
+
+const wchar_t *
+dk4dir_wc_next_dir(dk4_dir_wc_t *dptr)
+{
+ const wchar_t *back = NULL;
+ if (NULL != dptr) {
+ if ((NULL != dptr->s_dir) && (NULL != dptr->i_dir)) {
+ back = (const wchar_t *)dk4sto_it_next(dptr->i_dir);
+ }
+ }
+ return back;
+}
+
+
+
+const wchar_t *
+dk4dir_wc_next_file(dk4_dir_wc_t *dptr)
+{
+ const wchar_t *back = NULL;
+ if (NULL != dptr) {
+ if ((NULL != dptr->s_file) && (NULL != dptr->i_file)) {
+ back = (const wchar_t *)dk4sto_it_next(dptr->i_file);
+ }
+ }
+ return back;
+}
+
+
+
+void
+dk4dir_wc_skip_files(dk4_dir_wc_t *dptr)
+{
+ if (NULL != dptr) {
+ dk4dir_wc_clean_storage(dptr->s_file, dptr->i_file);
+ dptr->s_file = NULL; dptr->i_file = NULL;
+ }
+}
+
+
+
+size_t
+dk4dir_wc_get_max_entry_length(dk4_dir_wc_t *dptr)
+{
+ size_t back = 0;
+ if (NULL != dptr) {
+ back = dptr->maxlen;
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4dirwc.ctr b/support/dktools/dk4dirwc.ctr
new file mode 100644
index 0000000000..da1c023675
--- /dev/null
+++ b/support/dktools/dk4dirwc.ctr
@@ -0,0 +1,559 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Directory traversal using wchar_t file names.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4STO_H_INCLUDED
+#include "dk4sto.h"
+#endif
+
+
+/** Directory structure.
+*/
+typedef struct {
+ wchar_t *path; /**< Directory path. */
+ dk4_sto_t *s_dir; /**< Storage for directories. */
+ dk4_sto_it_t *i_dir; /**< Iterator for directories. */
+ dk4_sto_t *s_file; /**< Storage for non-directories. */
+ dk4_sto_it_t *i_file; /**< Iterator for non-directories. */
+ size_t maxlen; /**< Maximum entry name length. */
+} dk4_dir_wc_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open directory, create directory structure.
+ @param path Directory path name.
+ @param om Opening mode.
+ @param erp Error report, may be NULL.
+ @return Pointer to new directory structure on success, NULL on error.
+ On success use dk4dir_wc_close() to destroy the directory
+ structure.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if path is NULL,
+ - DK4_E_NOT_SUPPORTED<br>
+ if no function to traverse directories was found during build process,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if a memory allocation failed,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in a size calculation,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if one of the involved directory or file names is too long for an
+ internal buffer,
+ - DK4_E_OPENDIR_FAILED<br>
+ with errno value in iDetails1 if the attempt to open the directory
+ failed,
+ - DK4_E_FINDFIRSTFILE_FAILED<br>
+ with GetLastError() value in lDetails1 if the FindFirstFile()
+ function failed on Windows,
+ - DK4_E_SYSTEM<br>
+ if the stat() or lstat() function failed for one of the directory
+ items.
+*/
+dk4_dir_wc_t *
+dk4dir_wc_open(const wchar_t *path, int om, dk4_er_t *erp);
+
+/** Destroy directory structure.
+ @param dptr Structure to destroy.
+*/
+void
+dk4dir_wc_close(dk4_dir_wc_t *dptr);
+
+/** Reset directory traversal.
+ @param dptr Directory structure.
+*/
+void
+dk4dir_wc_reset(dk4_dir_wc_t *dptr);
+
+/** Retrieve directory path.
+ @param dptr Directory structure.
+ @return Directory path on success,
+ NULL on error or if no directory was specified for a
+ file name expansion.
+*/
+const wchar_t *
+dk4dir_wc_get_path(dk4_dir_wc_t *dptr);
+
+/** Retrieve next directory name.
+ @param dptr Directory structure.
+ @return Pointer to short name on success, NULL if there are no
+ more directories.
+*/
+const wchar_t *
+dk4dir_wc_next_dir(dk4_dir_wc_t *dptr);
+
+/** Retrieve next file (non-directory) name.
+ @param dptr Directory structure.
+ @return Pointer to short name on success, NULL if there are no more
+ files.
+*/
+const wchar_t *
+dk4dir_wc_next_file(dk4_dir_wc_t *dptr);
+
+/** Skip files (remove information about files, release memory).
+ @param dptr Directory structure.
+*/
+void
+dk4dir_wc_skip_files(dk4_dir_wc_t *dptr);
+
+/** Compare two file or directory names.
+ @param l Left name.
+ @param r Right name.
+ @param cr Comparison criteria (ignored).
+ @return 1 if l>r, 0 if l=r, -1 if l<r.
+*/
+int
+dk4dir_wc_compare(const void *l, const void *r, int cr);
+
+/** Get maximum entry name length.
+ @param dptr Directory.
+ @return Maximum name length.
+*/
+size_t
+dk4dir_wc_get_max_entry_length(dk4_dir_wc_t *dptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4dirwc.h"
+
+#ifndef DK4DIR_H_INCLUDED
+#include "dk4dir.h"
+#endif
+
+#ifndef DK4STR8_H_INCLUDED
+#include "dk4strw.h"
+#endif
+
+#ifndef DK4STAT_H_INCLUDED
+#include "dk4stat.h"
+#endif
+
+#ifndef DK4STAT8_H_INCLUDED
+#include "dk4statw.h"
+#endif
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4MPL_H_INCLUDED
+#include "dk4mpl.h"
+#endif
+
+#ifndef DK4MAASZ_H_INCLUDED
+#include "dk4maasz.h"
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_WCHAR_H
+#ifndef WCHAR_H_INCLUDED
+#include <wchar.h>
+#define WCHAR_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_DIRENT_H
+#ifndef DIRENT_H_INCLUDED
+#include <dirent.h>
+#define DIRENT_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+
+
+$!trace-include
+
+
+
+#if DK4_ON_WINDOWS
+
+int
+dk4dir_wc_compare(const void *l, const void *r, int cr)
+{
+ int back = 0;
+ if (NULL != l) {
+ if (NULL != r) {
+ back = dk4strw_pathcmp((const wchar_t *)l, (const wchar_t *)r);
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != r) { back = -1; }
+ }
+ return back;
+}
+
+#endif
+
+
+
+static
+void
+dk4dir_wc_clean_storage(dk4_sto_t *s, dk4_sto_it_t *i)
+{
+ wchar_t *n;
+ if (NULL != s) {
+ if (NULL != i) {
+ dk4sto_it_reset(i);
+ while (NULL != (n = (wchar_t *)dk4sto_it_next(i))) {
+ dk4mem_free(n);
+ }
+ dk4sto_it_close(i);
+ }
+ dk4sto_close(s);
+ }
+}
+
+
+
+void
+dk4dir_wc_close(dk4_dir_wc_t *dptr)
+{
+ if (NULL != dptr) {
+ dk4mem_release(dptr->path);
+ dk4dir_wc_clean_storage(dptr->s_dir, dptr->i_dir);
+ dptr->s_dir = NULL; dptr->i_dir = NULL;
+ dk4dir_wc_clean_storage(dptr->s_file, dptr->i_file);
+ dptr->s_file = NULL; dptr->i_file = NULL;
+ dk4mem_free(dptr);
+ }
+}
+
+
+
+#if DK4_ON_WINDOWS
+/** Fixed texts used by the module.
+*/
+static const wchar_t * const dk4dir_wc_kw[] = {
+$!string-table prefix=L
+#
+# 0 Current directory
+#
+.
+#
+# 1 Parent directory
+#
+..
+#
+# 2 Separator for non-Windows systems
+#
+/
+#
+# 3 Separator for Windows systems
+#
+\\
+#
+# 4 Pattern for all files
+#
+*
+$!end
+};
+
+
+
+static
+int
+dk4dir_wc_fill_with_pab(
+ dk4_dir_wc_t *dptr,
+ int om,
+ wchar_t *pab,
+ size_t szpab,
+ dk4_er_t *erp
+)
+{
+ WIN32_FIND_DATAW ffdata; /* Find result */
+ HANDLE ffres; /* Result from findfirst */
+ dkChar *nn; /* Copy of name, dyn */
+ DWORD attr; /* File attributes */
+ size_t slen; /* Entry name length. */
+ int isdir; /* Flag: Entry is directory */
+ int back = 0;
+ $? "+ dk4dir_wc_fill_directory"
+ if (dk4strw_cpy_s(pab, szpab, dptr->path, erp)) {
+ if (dk4strw_cat_s(pab, szpab, dk4dir_wc_kw[3], erp)) {
+ if (dk4strw_cat_s(pab, szpab, dk4dir_wc_kw[4], erp)) {
+ ffres = FindFirstFileW(pab, &ffdata);
+ if (INVALID_HANDLE_VALUE != ffres) {
+ back = 1;
+ do {
+ if (0 != dk4strw_cmp(dk4dir_wc_kw[0], ffdata.cFileName)) {
+ if (0 != dk4strw_cmp(dk4dir_wc_kw[1], ffdata.cFileName)) {
+ slen = dk4strw_len(ffdata.cFileName);
+ if (slen > dptr->maxlen) { dptr->maxlen = slen; }
+ nn = dk4strw_dup(ffdata.cFileName, erp);
+ if (NULL != nn) {
+ isdir = 0;
+ attr = ffdata.dwFileAttributes;
+ if (0 != (FILE_ATTRIBUTE_DIRECTORY & attr)) {
+ isdir = 1;
+ if (0 != (FILE_ATTRIBUTE_REPARSE_POINT & attr)) {
+ if (0 != (DK4_DIR_SYMLINK_DIR_AS_FILE & om)) {
+ isdir = 0;
+ }
+ }
+ }
+ if (0 != isdir) {
+ if (0 == dk4sto_add(dptr->s_dir, (void *)nn, erp)) {
+ back = 0;
+ dk4mem_free(nn);
+ }
+ } else {
+ if (0 == dk4sto_add(dptr->s_file, (void *)nn, erp)) {
+ back = 0;
+ dk4mem_free(nn);
+ }
+ }
+ } else {
+ back = 0;
+ }
+ }
+ }
+ } while(FindNextFileW(ffres, &ffdata));
+ FindClose(ffres);
+ } else {
+ /* ERROR: FindFirstFile failed */
+ dk4error_set_ldetails(
+ erp, DK4_E_FINDFIRSTFILE_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ }
+ }
+ }
+ $? "- dk4dir_wc_fill_directory %d", back
+ return back;
+}
+
+
+
+static
+int
+dk4dir_wc_fill_with_local(dk4_dir_wc_t *dptr, int om, dk4_er_t *erp)
+{
+ wchar_t pab[DK4_MAX_PATH];
+ return (dk4dir_wc_fill_with_pab(dptr, om, pab, DK4_SIZEOF(pab,wchar_t), erp));
+}
+
+
+
+/** Fill directory structure with data about subdirectories and files.
+ @param dptr Directory structure to fill.
+ @param om Opening mode.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on errors.
+*/
+static
+int
+dk4dir_wc_fill_directory(dk4_dir_wc_t *dptr, int om, dk4_er_t *erp)
+{
+ dk4_er_t er;
+ wchar_t *pab;
+ size_t dptrlgt;
+ int back = 0;
+
+ dptrlgt = dk4strw_len(dptr->path);
+ if ((DK4_MAX_PATH - 2) > dptrlgt) {
+ back = dk4dir_wc_fill_with_local(dptr, om, erp);
+ } else {
+ dk4error_init(&er);
+ dptrlgt = dk4ma_size_t_add(dptrlgt, 3, &er);
+ if (DK4_E_NONE == er.ec) {
+ pab = dk4mem_new(wchar_t, dptrlgt, erp);
+ if (NULL != pab) {
+ back = dk4dir_wc_fill_with_pab(dptr, om, pab, dptrlgt, erp);
+ dk4mem_free(pab);
+ }
+ } else {
+ dk4error_copy(erp, &er);
+ }
+ }
+ return back;
+}
+
+#endif
+
+
+
+dk4_dir_wc_t *
+dk4dir_wc_open(const wchar_t *path, int om, dk4_er_t *erp)
+{
+ dk4_dir_wc_t *back = NULL;
+#if DK4_ON_WINDOWS
+ int ok = 0;
+#endif
+ if (NULL != path) {
+#if DK4_ON_WINDOWS
+ back = dk4mem_new(dk4_dir_wc_t, 1, erp);
+ if (NULL != back) {
+ back->path = NULL;
+ back->s_dir = NULL;
+ back->i_dir = NULL;
+ back->s_file = NULL;
+ back->i_file = NULL;
+ back->path = dk4strw_dup(path, erp);
+ back->maxlen = 0;
+ if (NULL != back->path) {
+ back->s_dir = dk4sto_open(erp);
+ if (NULL != back->s_dir) {
+ if (0 != (DK4_DIR_OPEN_SORTED & om)) {
+ dk4sto_set_comp(back->s_dir, dk4dir_wc_compare, 0);
+ }
+ back->i_dir = dk4sto_it_open(back->s_dir, erp);
+ if (NULL != back->i_dir) {
+ back->s_file = dk4sto_open(erp);
+ if (NULL != back->s_file) {
+ if (0 != (DK4_DIR_OPEN_SORTED & om)) {
+ dk4sto_set_comp(back->s_file, dk4dir_wc_compare, 0);
+ }
+ back->i_file = dk4sto_it_open(back->s_file, erp);
+ if (NULL != back->i_file) {
+ ok = dk4dir_wc_fill_directory(back, om, erp);
+ }
+ }
+ }
+ }
+ }
+ if (0 == ok) {
+ dk4dir_wc_close(back);
+ back = NULL;
+ }
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+void
+dk4dir_wc_reset(dk4_dir_wc_t *dptr)
+{
+ if (NULL != dptr) {
+ if ((NULL != dptr->s_dir) && (NULL != dptr->i_dir)) {
+ dk4sto_it_reset(dptr->i_dir);
+ }
+ if ((NULL != dptr->s_file) && (NULL != dptr->i_file)) {
+ dk4sto_it_reset(dptr->i_file);
+ }
+ }
+}
+
+
+
+const wchar_t *
+dk4dir_wc_get_path(dk4_dir_wc_t *dptr)
+{
+ const wchar_t *back = NULL;
+ if (NULL != dptr) {
+ back = (const wchar_t *)(dptr->path);
+ }
+ return back;
+}
+
+
+
+const wchar_t *
+dk4dir_wc_next_dir(dk4_dir_wc_t *dptr)
+{
+ const wchar_t *back = NULL;
+ if (NULL != dptr) {
+ if ((NULL != dptr->s_dir) && (NULL != dptr->i_dir)) {
+ back = (const wchar_t *)dk4sto_it_next(dptr->i_dir);
+ }
+ }
+ return back;
+}
+
+
+
+const wchar_t *
+dk4dir_wc_next_file(dk4_dir_wc_t *dptr)
+{
+ const wchar_t *back = NULL;
+ if (NULL != dptr) {
+ if ((NULL != dptr->s_file) && (NULL != dptr->i_file)) {
+ back = (const wchar_t *)dk4sto_it_next(dptr->i_file);
+ }
+ }
+ return back;
+}
+
+
+
+void
+dk4dir_wc_skip_files(dk4_dir_wc_t *dptr)
+{
+ if (NULL != dptr) {
+ dk4dir_wc_clean_storage(dptr->s_file, dptr->i_file);
+ dptr->s_file = NULL; dptr->i_file = NULL;
+ }
+}
+
+
+
+size_t
+dk4dir_wc_get_max_entry_length(dk4_dir_wc_t *dptr)
+{
+ size_t back = 0;
+ if (NULL != dptr) {
+ back = dptr->maxlen;
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4dirwc.h b/support/dktools/dk4dirwc.h
new file mode 100644
index 0000000000..1cc56524b5
--- /dev/null
+++ b/support/dktools/dk4dirwc.h
@@ -0,0 +1,178 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4dirwc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4DIRWC_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4DIRWC_H_INCLUDED 1
+
+
+#line 10 "dk4dirwc.ctr"
+
+/** @file
+ Directory traversal using wchar_t file names.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4STO_H_INCLUDED
+#include "dk4sto.h"
+#endif
+
+
+/** Directory structure.
+*/
+typedef struct {
+ wchar_t *path; /**< Directory path. */
+ dk4_sto_t *s_dir; /**< Storage for directories. */
+ dk4_sto_it_t *i_dir; /**< Iterator for directories. */
+ dk4_sto_t *s_file; /**< Storage for non-directories. */
+ dk4_sto_it_t *i_file; /**< Iterator for non-directories. */
+ size_t maxlen; /**< Maximum entry name length. */
+} dk4_dir_wc_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open directory, create directory structure.
+ @param path Directory path name.
+ @param om Opening mode.
+ @param erp Error report, may be NULL.
+ @return Pointer to new directory structure on success, NULL on error.
+ On success use dk4dir_wc_close() to destroy the directory
+ structure.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if path is NULL,
+ - DK4_E_NOT_SUPPORTED<br>
+ if no function to traverse directories was found during build process,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if a memory allocation failed,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in a size calculation,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if one of the involved directory or file names is too long for an
+ internal buffer,
+ - DK4_E_OPENDIR_FAILED<br>
+ with errno value in iDetails1 if the attempt to open the directory
+ failed,
+ - DK4_E_FINDFIRSTFILE_FAILED<br>
+ with GetLastError() value in lDetails1 if the FindFirstFile()
+ function failed on Windows,
+ - DK4_E_SYSTEM<br>
+ if the stat() or lstat() function failed for one of the directory
+ items.
+*/
+dk4_dir_wc_t *
+dk4dir_wc_open(const wchar_t *path, int om, dk4_er_t *erp);
+
+/** Destroy directory structure.
+ @param dptr Structure to destroy.
+*/
+void
+dk4dir_wc_close(dk4_dir_wc_t *dptr);
+
+/** Reset directory traversal.
+ @param dptr Directory structure.
+*/
+void
+dk4dir_wc_reset(dk4_dir_wc_t *dptr);
+
+/** Retrieve directory path.
+ @param dptr Directory structure.
+ @return Directory path on success,
+ NULL on error or if no directory was specified for a
+ file name expansion.
+*/
+const wchar_t *
+dk4dir_wc_get_path(dk4_dir_wc_t *dptr);
+
+/** Retrieve next directory name.
+ @param dptr Directory structure.
+ @return Pointer to short name on success, NULL if there are no
+ more directories.
+*/
+const wchar_t *
+dk4dir_wc_next_dir(dk4_dir_wc_t *dptr);
+
+/** Retrieve next file (non-directory) name.
+ @param dptr Directory structure.
+ @return Pointer to short name on success, NULL if there are no more
+ files.
+*/
+const wchar_t *
+dk4dir_wc_next_file(dk4_dir_wc_t *dptr);
+
+/** Skip files (remove information about files, release memory).
+ @param dptr Directory structure.
+*/
+void
+dk4dir_wc_skip_files(dk4_dir_wc_t *dptr);
+
+/** Compare two file or directory names.
+ @param l Left name.
+ @param r Right name.
+ @param cr Comparison criteria (ignored).
+ @return 1 if l>r, 0 if l=r, -1 if l<r.
+*/
+int
+dk4dir_wc_compare(const void *l, const void *r, int cr);
+
+/** Get maximum entry name length.
+ @param dptr Directory.
+ @return Maximum name length.
+*/
+size_t
+dk4dir_wc_get_max_entry_length(dk4_dir_wc_t *dptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4dmt.c b/support/dktools/dk4dmt.c
new file mode 100644
index 0000000000..5e73c4e75c
--- /dev/null
+++ b/support/dktools/dk4dmt.c
@@ -0,0 +1,608 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4dmt.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4dmt.c The dk4dmt module.
+*/
+
+
+#line 101 "dk4dmt.ctr"
+
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_STAT_H
+#ifndef SYS_STAT_H_INCLUDED
+#include <sys/stat.h>
+#define SYS_STAT_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYSLOG_H
+#ifndef SYSLOG_H_INCLUDED
+#include <syslog.h>
+#define SYSLOG_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4types.h"
+#include "dk4dmt.h"
+#include "dk4mem.h"
+#include "dk4mao8d.h"
+#include "dk4stat8.h"
+#include "dk4str8.h"
+#include "dk4fopc8.h"
+#include "dk4mkdh8.h"
+
+
+
+
+
+#line 175 "dk4dmt.ctr"
+
+
+
+static const char * const dk4dmt_kw[] = {
+/* 0 */
+"\n",
+
+/* 1 */
+": ",
+
+/* 2 */
+"Failed to create background process!",
+
+/* 3 */
+"Failed to detach from terminal (missing setsid()/setpgpr())!",
+
+/* 4 */
+"Failed to detach from terminal (setsid() failed)!",
+
+/* 5 */
+"Failed to create daemon process!",
+
+/* 6 */
+"Failed to reset signal handlers (sigemptyset)!",
+
+/* 7 */
+"Failed to reset signal handlers (sigaction)!",
+
+/* 8 */
+"Neither sigaction() nor sigset() available!",
+
+/* 9 */
+"Failed to unblock signals (sigemptyset)!",
+
+/* 10 */
+"Failed to unblock signals (sigprocmask)!",
+
+/* 11 */
+"PID file already exists:\n\"",
+
+/* 12 */
+"\"!",
+
+/* 13 */
+"Neither setsid() nor setpgrp() available!",
+
+/* 14 */
+"Failed to detach from terminal (setsid)!",
+
+/* 15 */
+"Failed to write PID file: \"",
+
+/* 16 */
+"\"!",
+
+/* 17 */
+"dk4dmt",
+
+/* 18 */
+"Failed to open /dev/null for read access!",
+
+/* 19 */
+"Failed to duplicate /dev/null to standard input!",
+
+/* 20 */
+"Failed to open /dev/null for write access!",
+
+/* 21 */
+"Failed to duplicate /dev/null to standard output!",
+
+/* 22 */
+"Failed to duplicate /dev/null to standard error output!",
+
+/* 23 */
+"Failed to change into root directory!",
+
+/* 24 */
+"Failed to remove PID file \"",
+
+/* 25 */
+"\"!",
+
+NULL
+
+
+#line 273 "dk4dmt.ctr"
+};
+
+
+
+static
+void
+dk4dmt_syslog_1(const char *prgname, int slf, size_t idx)
+{
+#if DK4_HAVE_SYSLOG
+ openlog(((NULL != prgname) ? (prgname) : (dk4dmt_kw[17])), LOG_PID, slf);
+ syslog(LOG_ERR, "%s", dk4dmt_kw[idx]);
+ closelog();
+#endif
+}
+
+
+
+static
+void
+dk4dmt_syslog_3(
+ const char *prgname, int slf, size_t i1, size_t i2, const char *str
+)
+{
+#if DK4_HAVE_SYSLOG
+ openlog(((NULL != prgname) ? (prgname) : (dk4dmt_kw[17])), LOG_PID, slf);
+ if (NULL != str) {
+ syslog(LOG_ERR, "%s%s%s", dk4dmt_kw[i1], str, dk4dmt_kw[i2]);
+ } else {
+ syslog(LOG_ERR, "%s%s", dk4dmt_kw[i1], dk4dmt_kw[i2]);
+ }
+ closelog();
+#endif
+}
+
+
+
+static
+void
+dk4dmt_log_1(const char *prgname, int slf, int lse, size_t i)
+{
+ if (0 != lse) {
+ if (NULL != prgname) {
+ fputs(prgname, stderr);
+ fputs(dk4dmt_kw[1], stderr);
+ }
+ fputs(dk4dmt_kw[i], stderr);
+ fputs(dk4dmt_kw[0], stderr);
+ fflush(stderr);
+ } else {
+ dk4dmt_syslog_1(prgname, slf, i);
+ }
+}
+
+
+
+static
+void
+dk4dmt_log_3(
+ const char *prgname, int slf, int lse, size_t i1, size_t i2, const char *str
+)
+{
+ if (0 != lse) {
+ if (NULL != prgname) {
+ fputs(prgname, stderr);
+ fputs(dk4dmt_kw[1], stderr);
+ }
+ fputs(dk4dmt_kw[i1], stderr);
+ if (NULL != str) { fputs(str, stderr); }
+ fputs(dk4dmt_kw[i2], stderr);
+ fputs(dk4dmt_kw[0], stderr);
+ fflush(stderr);
+ } else {
+ dk4dmt_syslog_3(prgname, slf, i1, i2, str);
+ }
+}
+
+
+
+/** Reset all signals to SIG_DFL.
+ @param reason Address of error code variable
+ (1=sigemptyset failed, 2=sigaction failed, 3=no signal handling).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4dmt_reset_all_signals(int *reason)
+{
+
+
+#line 361 "dk4dmt.ctr"
+#if DK4_HAVE_SIGACTION
+ struct sigaction sigact; /* Signal information for sigaction() */
+#endif
+ int back = 1; /* Function result */
+ int maxsig; /* Maximum signal + 1 */
+ int i; /* Current signal to modify */
+ int go;
+
+#ifdef _NSIG
+ maxsig = _NSIG;
+#else
+ maxsig = 16;
+#endif
+
+ for (i = 1; ((i < maxsig) && (1 == back)); i++) {
+ go = 1;
+#ifdef SIGKILL
+ if (SIGKILL == i) { go = 0; }
+#else
+ if (9 == i) { go = 0; }
+#endif
+#ifdef SIGSTOP
+ if (SIGSTOP == i) { go = 0; }
+#else
+ if (19 == i) { go = 0; }
+#endif
+
+
+#line 388 "dk4dmt.ctr"
+ if (0 != go) {
+#if DK4_HAVE_SIGACTION
+ DK4_MEMRES(&sigact, sizeof(sigact));
+ sigact.sa_handler = SIG_DFL;
+ sigact.sa_flags = 0;
+ if (0 != sigemptyset(&(sigact.sa_mask))) {
+ if (16 > i) {
+ back = 0;
+ if (NULL != reason) {
+
+#line 397 "dk4dmt.ctr"
+ *reason = 1;
+ }
+ }
+ }
+ if (0 != sigaction(i, &sigact, NULL)) {
+ if (16 > i) {
+ back = 0;
+ if (NULL != reason) {
+
+#line 405 "dk4dmt.ctr"
+ *reason = 2;
+ }
+ }
+ }
+#else
+#if DK4_HAVE_SIGSET
+ sigset(i, SIG_DFL);
+#else
+#if DK4_HAVE_SIGNAL
+ signal(i, SIG_DFL);
+#else
+ back = 0;
+ if (NULL != reason) { *reason = 3; }
+#endif
+#endif
+#endif
+ }
+ }
+
+
+#line 424 "dk4dmt.ctr"
+ return back;
+}
+
+
+
+/** Obtain maximum file descriptor number.
+ @return Maximum file descriptor.
+*/
+static
+int
+dk4dmt_max_file_descriptor(void)
+{
+#if DK4_HAVE_SYS_RESOURCE_H && DK4_HAVE_GETRLIMIT && defined(RLIMIT_NOFILE)
+ struct rlimit rl;
+#endif
+ int back = 1024;
+#if DK4_HAVE_SYS_RESOURCE_H && DK4_HAVE_GETRLIMIT && defined(RLIMIT_NOFILE)
+ if (0 == getrlimit(RLIMIT_NOFILE, &rl)) {
+#if defined(RLIM_INFINITY)
+ if (RLIM_INFINITY != rl.rlim_max) {
+#endif
+ back = rl.rlim_max;
+#if defined(RLIM_INFINITY)
+ }
+#endif
+ }
+#endif
+ return back;
+}
+
+
+
+/** Close all file descriptors except 0 (stdin), 1 (stdout) and 2 (stderr).
+*/
+static
+void
+dk4dmt_close_non_std_file_descriptors(void)
+{
+ int maxfd;
+ int fd;
+
+ maxfd = dk4dmt_max_file_descriptor();
+ for (fd = 3; fd < maxfd; fd++) {
+ (void)close(fd);
+ }
+}
+
+
+
+/** Unblock all signals.
+ @param reason Address of error code variable
+ (1=sigemptyset failed, 2=sigprocmask failed).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4dmt_unblock_all_signals(int *reason)
+{
+ sigset_t set;
+ int back = 1;
+ if (0 != sigemptyset(&set)) {
+ back = 0;
+ if (NULL != reason) { *reason = 1; }
+ }
+ if (0 != sigprocmask(SIG_SETMASK, &set, NULL)) {
+ back = 0;
+ if (NULL != reason) { *reason = 2; }
+ }
+ return back;
+}
+
+
+
+int
+dk4dmt_parent_before_fork(
+ const char *prgname, const char *pidfilename, int logstderr, int slf
+)
+{
+ dk4_stat_t stb;
+ int reason = 0;
+ int back = 1;
+
+ /* Close file descriptors except 0, 1 and 2 */
+ dk4dmt_close_non_std_file_descriptors();
+
+ /* Reset all signal actions to default handlers */
+ if (0 == dk4dmt_reset_all_signals(&reason)) {
+ back = 0;
+ if (0 != logstderr) {
+ switch (reason) {
+ case 1: {
+ /* ERROR: sigemptyset() failed */
+ dk4dmt_log_1(prgname, slf, logstderr, 6);
+ } break;
+ case 2: {
+ /* ERROR: sigaction() failed */
+ dk4dmt_log_1(prgname, slf, logstderr, 7);
+ } break;
+ default: {
+ /* ERROR: No sigaction()/sigset()/signal() function */
+ dk4dmt_log_1(prgname, slf, logstderr, 8);
+ } break;
+ }
+ }
+ }
+
+ /* Unblock all signals */
+ if (0 == dk4dmt_unblock_all_signals(&reason)) {
+ back = 0;
+ if (0 != logstderr) {
+ switch (reason) {
+ case 1: {
+ /* ERROR: sigemptyset() failed */
+ dk4dmt_log_1(prgname, slf, logstderr, 9);
+ } break;
+ case 2: {
+ /* ERROR: sigprocmask() failed */
+ dk4dmt_log_1(prgname, slf, logstderr, 10);
+ } break;
+ }
+ }
+ }
+
+ if ((0 != back) && (NULL != pidfilename)) {
+ if (0 != dk4stat_c8(&stb, pidfilename, NULL)) {
+ back = 0;
+ /* ERROR: PID file exists */
+ dk4dmt_log_3(prgname, slf, logstderr, 11, 12, pidfilename);
+ }
+ }
+
+ return back;
+}
+
+
+int
+dk4dmt_intermediate_before_fork(const char *prgname, int slf)
+{
+ int back = 1;
+#if DK4_HAVE_SETSID
+ if ((pid_t)(-1) == setsid()) {
+ back = 0;
+ dk4dmt_syslog_1(prgname, slf, 14);
+ }
+#else
+#if DK4_HAVE_SETPGRP
+ setpgrp();
+#else
+ back = 0;
+ dk4dmt_syslog_1(prgname, slf, 13);
+#endif
+#endif
+ return back;
+}
+
+
+
+int
+dk4dmt_daemon_after_fork(const char *prgname, const char *pidfilename, int slf)
+{
+ char pidbuf[16*sizeof(dk4_um_t)];
+ FILE *fipo;
+ int fdin; /* File descriptor for input */
+ int fdout; /* File descriptor for output */
+ int res; /* Operation result */
+ int back = 1;
+
+ if (NULL != pidfilename) {
+ res = dk4ma_write_c8_decimal_unsigned(
+ pidbuf, sizeof(pidbuf), (dk4_um_t)getpid(), 0, NULL
+ );
+ if (0 != res) {
+ if (0 != dk4str8_cat_s(pidbuf, sizeof(pidbuf), dk4dmt_kw[0], NULL)) {
+ (void)dk4mkdir_hierarchy_c8(pidfilename, 0, NULL);
+ fipo = dk4fopen_c8(pidfilename, "w", DK4_FOPEN_SC_PRIVILEGED, NULL);
+ if (NULL != fipo) {
+ fputs(pidbuf, fipo);
+ fclose(fipo);
+ } else {
+ dk4dmt_syslog_3(prgname, slf, 15, 16, pidfilename);
+ back = 0;
+ }
+ }
+ }
+ }
+
+ /* Connect /dev/null to stdin stout stderr or close them
+ */
+ fdin = open("/dev/null", O_RDONLY);
+ if (-1 < fdin) {
+ if (-1 == dup2(fdin, 0)) {
+ back = 0;
+ dk4dmt_syslog_1(prgname, slf, 19);
+ }
+ close(fdin);
+ } else {
+ back = 0;
+ dk4dmt_syslog_1(prgname, slf, 18);
+ }
+ fdout = open("/dev/null", O_WRONLY);
+ if (-1 < fdout) {
+ if (-1 == dup2(fdout, 1)) {
+ back = 0;
+ dk4dmt_syslog_1(prgname, slf, 21);
+ }
+ if (-1 == dup2(fdout, 2)) {
+ back = 0;
+ dk4dmt_syslog_1(prgname, slf, 22);
+ }
+ close(fdout);
+ } else {
+ back = 0;
+ dk4dmt_syslog_1(prgname, slf, 20);
+ }
+
+ /* Use exact permissions when creating new files or directories.
+ */
+ umask(0);
+
+ /* Change to root directory, so the previous current directory
+ can be unmounted without blocking.
+ */
+ if (0 != chdir("/")) {
+ back = 0;
+ dk4dmt_syslog_1(prgname, slf, 23);
+ }
+
+ /* Indicate success or error.
+ */
+ return back;
+}
+
+
+
+void
+dk4dmt_daemon_end(const char *prgname, const char *pidfilename, int slf)
+{
+ if (NULL != pidfilename) {
+ if (0 != unlink(pidfilename)) {
+ dk4dmt_syslog_3(prgname, slf, 24, 25, pidfilename);
+ }
+ }
+}
+
+
diff --git a/support/dktools/dk4dmt.ctr b/support/dktools/dk4dmt.ctr
new file mode 100644
index 0000000000..ed8f07b487
--- /dev/null
+++ b/support/dktools/dk4dmt.ctr
@@ -0,0 +1,668 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+%% header
+
+/** @file dk4dmt.h Daemon tools.
+
+The functions in this module can be used in standing daemons.
+
+In the original process, call the
+dk4dmt_parent_before_fork() function to close all file descriptors
+above 2, reset all signal handlers to defaults, unblock all signals
+and check whether a PID file already exists.
+If you plan to give up root privileges in the child processes
+(use setgid() and setuid() to change effective user and group),
+do not use /var/run/<i>program</i>.pid as PID file name, better
+use /var/run/<i>program</i>/<i>program</i>.pid instead and make
+sure to set ownership and group on /var/run/<i>program</i>
+to the unprivileged user and group used by the child process.
+User and group need write permission to the directory, so the unprivileged
+child process can remove the PID file when exiting.
+
+In the intermediate process after the first fork call
+dk4dmt_intermediate_before_fork(). Among other things this function
+completely decouples the process from the terminal.
+
+In the final process (after forking again) call
+dk4dmt_daemon_after_fork()
+to set up things before starting service. This function creates the PID
+file, connects file descriptors 0, 1 and 2 to /dev/null, resets
+the umask and changes into the / directory.
+
+After finishing service call
+dk4dmt_daemon_end() before exiting. This function removes the PID
+file.
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Activities in parent process before calling fork().
+ * Close all file descriptors above 2.
+ * Reset all signal actions to default handlers.
+ * Unblock all signals.
+ * Check whether PID file already exists.
+ Use this function to check whether the initial process
+ can run fork().
+ @param prgname Program name.
+ @param pidfilename PID file name.
+ @param logstderr Flag: Logging to stderr allowed.
+ @param slf Syslog feature.
+ @return 1 on success (can call fork), 0 on error (abort).
+*/
+int
+dk4dmt_parent_before_fork(
+ const char *prgname, const char *pidfilename, int logstderr, int slf
+);
+
+
+/** Activities in first child before calling fork() again.
+ * Decouple completely from terminal.
+ Use this function to check whether the first child process
+ can run fork() again.
+ @param prgname Program name.
+ @param slf Syslog feature.
+ @return 1 on success (can call fork), 0 on error (abort).
+*/
+int
+dk4dmt_intermediate_before_fork(const char *prgname, int slf);
+
+/** Activities in final daemon process.
+ * Create PID file.
+ * Connect file descriptors 0, 1 and 2 to /dev/null.
+ * Reset umask.
+ * Change into / directory.
+ @param prgname Program name.
+ @param pidfilename File name for PID file.
+ @param slf Syslog feature.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4dmt_daemon_after_fork(const char *prgname, const char *pidfilename, int slf);
+
+/** End of daemon, remove PID file.
+ @param prgname Program name.
+ @param pidfilename PID file name.
+ @param slf Syslog feature.
+*/
+void
+dk4dmt_daemon_end(const char *prgname, const char *pidfilename, int slf);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_STAT_H
+#ifndef SYS_STAT_H_INCLUDED
+#include <sys/stat.h>
+#define SYS_STAT_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYSLOG_H
+#ifndef SYSLOG_H_INCLUDED
+#include <syslog.h>
+#define SYSLOG_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4types.h"
+#include "dk4dmt.h"
+#include "dk4mem.h"
+#include "dk4mao8d.h"
+#include "dk4stat8.h"
+#include "dk4str8.h"
+#include "dk4fopc8.h"
+#include "dk4mkdh8.h"
+
+
+
+$!trace-include
+
+
+
+static const char * const dk4dmt_kw[] = {
+$!string-table
+#
+# 0 Newline
+#
+\n
+#
+# 1 Separator after program name
+#
+:
+#
+# 2
+#
+Failed to create background process!
+#
+# 3
+#
+Failed to detach from terminal (missing setsid()/setpgpr())!
+#
+# 4
+#
+Failed to detach from terminal (setsid() failed)!
+#
+# 5
+#
+Failed to create daemon process!
+#
+# 6
+#
+Failed to reset signal handlers (sigemptyset)!
+#
+# 7
+#
+Failed to reset signal handlers (sigaction)!
+#
+# 8
+#
+Neither sigaction() nor sigset() available!
+#
+# 9
+#
+Failed to unblock signals (sigemptyset)!
+#
+# 10
+#
+Failed to unblock signals (sigprocmask)!
+#
+# 11 12
+#
+PID file already exists:\n"
+"!
+#
+# 13
+#
+Neither setsid() nor setpgrp() available!
+#
+# 14
+#
+Failed to detach from terminal (setsid)!
+#
+# 15 16
+#
+Failed to write PID file: "
+"!
+#
+# 17
+#
+dk4dmt
+#
+# 18
+#
+Failed to open /dev/null for read access!
+#
+# 19
+#
+Failed to duplicate /dev/null to standard input!
+#
+# 20
+#
+Failed to open /dev/null for write access!
+#
+# 21 22
+#
+Failed to duplicate /dev/null to standard output!
+Failed to duplicate /dev/null to standard error output!
+#
+# 23
+#
+Failed to change into root directory!
+#
+# 24 25
+#
+Failed to remove PID file "
+"!
+$!end
+};
+
+
+
+static
+void
+dk4dmt_syslog_1(const char *prgname, int slf, size_t idx)
+{
+#if DK4_HAVE_SYSLOG
+ openlog(((NULL != prgname) ? (prgname) : (dk4dmt_kw[17])), LOG_PID, slf);
+ syslog(LOG_ERR, "%s", dk4dmt_kw[idx]);
+ closelog();
+#endif
+}
+
+
+
+static
+void
+dk4dmt_syslog_3(
+ const char *prgname, int slf, size_t i1, size_t i2, const char *str
+)
+{
+#if DK4_HAVE_SYSLOG
+ openlog(((NULL != prgname) ? (prgname) : (dk4dmt_kw[17])), LOG_PID, slf);
+ if (NULL != str) {
+ syslog(LOG_ERR, "%s%s%s", dk4dmt_kw[i1], str, dk4dmt_kw[i2]);
+ } else {
+ syslog(LOG_ERR, "%s%s", dk4dmt_kw[i1], dk4dmt_kw[i2]);
+ }
+ closelog();
+#endif
+}
+
+
+
+static
+void
+dk4dmt_log_1(const char *prgname, int slf, int lse, size_t i)
+{
+ if (0 != lse) {
+ if (NULL != prgname) {
+ fputs(prgname, stderr);
+ fputs(dk4dmt_kw[1], stderr);
+ }
+ fputs(dk4dmt_kw[i], stderr);
+ fputs(dk4dmt_kw[0], stderr);
+ fflush(stderr);
+ } else {
+ dk4dmt_syslog_1(prgname, slf, i);
+ }
+}
+
+
+
+static
+void
+dk4dmt_log_3(
+ const char *prgname, int slf, int lse, size_t i1, size_t i2, const char *str
+)
+{
+ if (0 != lse) {
+ if (NULL != prgname) {
+ fputs(prgname, stderr);
+ fputs(dk4dmt_kw[1], stderr);
+ }
+ fputs(dk4dmt_kw[i1], stderr);
+ if (NULL != str) { fputs(str, stderr); }
+ fputs(dk4dmt_kw[i2], stderr);
+ fputs(dk4dmt_kw[0], stderr);
+ fflush(stderr);
+ } else {
+ dk4dmt_syslog_3(prgname, slf, i1, i2, str);
+ }
+}
+
+
+
+/** Reset all signals to SIG_DFL.
+ @param reason Address of error code variable
+ (1=sigemptyset failed, 2=sigaction failed, 3=no signal handling).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4dmt_reset_all_signals(int *reason)
+{
+ $? "+ dk4dmt_reset_all_signals"
+#if DK4_HAVE_SIGACTION
+ struct sigaction sigact; /* Signal information for sigaction() */
+#endif
+ int back = 1; /* Function result */
+ int maxsig; /* Maximum signal + 1 */
+ int i; /* Current signal to modify */
+ int go;
+
+#ifdef _NSIG
+ maxsig = _NSIG;
+#else
+ maxsig = 16;
+#endif
+
+ for (i = 1; ((i < maxsig) && (1 == back)); i++) {
+ go = 1;
+#ifdef SIGKILL
+ if (SIGKILL == i) { go = 0; }
+#else
+ if (9 == i) { go = 0; }
+#endif
+#ifdef SIGSTOP
+ if (SIGSTOP == i) { go = 0; }
+#else
+ if (19 == i) { go = 0; }
+#endif
+ $? ". signo = %d go = %d", i, go
+ if (0 != go) {
+#if DK4_HAVE_SIGACTION
+ DK4_MEMRES(&sigact, sizeof(sigact));
+ sigact.sa_handler = SIG_DFL;
+ sigact.sa_flags = 0;
+ if (0 != sigemptyset(&(sigact.sa_mask))) {
+ if (16 > i) {
+ back = 0;
+ if (NULL != reason) { $? "! sigemptyset"
+ *reason = 1;
+ }
+ }
+ }
+ if (0 != sigaction(i, &sigact, NULL)) {
+ if (16 > i) {
+ back = 0;
+ if (NULL != reason) { $? "! sigaction"
+ *reason = 2;
+ }
+ }
+ }
+#else
+#if DK4_HAVE_SIGSET
+ sigset(i, SIG_DFL);
+#else
+#if DK4_HAVE_SIGNAL
+ signal(i, SIG_DFL);
+#else
+ back = 0;
+ if (NULL != reason) { *reason = 3; }
+#endif
+#endif
+#endif
+ }
+ }
+ $? "- dk4dmt_reset_all_signals %d", back
+ return back;
+}
+
+
+
+/** Obtain maximum file descriptor number.
+ @return Maximum file descriptor.
+*/
+static
+int
+dk4dmt_max_file_descriptor(void)
+{
+#if DK4_HAVE_SYS_RESOURCE_H && DK4_HAVE_GETRLIMIT && defined(RLIMIT_NOFILE)
+ struct rlimit rl;
+#endif
+ int back = 1024;
+#if DK4_HAVE_SYS_RESOURCE_H && DK4_HAVE_GETRLIMIT && defined(RLIMIT_NOFILE)
+ if (0 == getrlimit(RLIMIT_NOFILE, &rl)) {
+#if defined(RLIM_INFINITY)
+ if (RLIM_INFINITY != rl.rlim_max) {
+#endif
+ back = rl.rlim_max;
+#if defined(RLIM_INFINITY)
+ }
+#endif
+ }
+#endif
+ return back;
+}
+
+
+
+/** Close all file descriptors except 0 (stdin), 1 (stdout) and 2 (stderr).
+*/
+static
+void
+dk4dmt_close_non_std_file_descriptors(void)
+{
+ int maxfd;
+ int fd;
+
+ maxfd = dk4dmt_max_file_descriptor();
+ for (fd = 3; fd < maxfd; fd++) {
+ (void)close(fd);
+ }
+}
+
+
+
+/** Unblock all signals.
+ @param reason Address of error code variable
+ (1=sigemptyset failed, 2=sigprocmask failed).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4dmt_unblock_all_signals(int *reason)
+{
+ sigset_t set;
+ int back = 1;
+ if (0 != sigemptyset(&set)) {
+ back = 0;
+ if (NULL != reason) { *reason = 1; }
+ }
+ if (0 != sigprocmask(SIG_SETMASK, &set, NULL)) {
+ back = 0;
+ if (NULL != reason) { *reason = 2; }
+ }
+ return back;
+}
+
+
+
+int
+dk4dmt_parent_before_fork(
+ const char *prgname, const char *pidfilename, int logstderr, int slf
+)
+{
+ dk4_stat_t stb;
+ int reason = 0;
+ int back = 1;
+
+ /* Close file descriptors except 0, 1 and 2 */
+ dk4dmt_close_non_std_file_descriptors();
+
+ /* Reset all signal actions to default handlers */
+ if (0 == dk4dmt_reset_all_signals(&reason)) {
+ back = 0;
+ if (0 != logstderr) {
+ switch (reason) {
+ case 1: {
+ /* ERROR: sigemptyset() failed */
+ dk4dmt_log_1(prgname, slf, logstderr, 6);
+ } break;
+ case 2: {
+ /* ERROR: sigaction() failed */
+ dk4dmt_log_1(prgname, slf, logstderr, 7);
+ } break;
+ default: {
+ /* ERROR: No sigaction()/sigset()/signal() function */
+ dk4dmt_log_1(prgname, slf, logstderr, 8);
+ } break;
+ }
+ }
+ }
+
+ /* Unblock all signals */
+ if (0 == dk4dmt_unblock_all_signals(&reason)) {
+ back = 0;
+ if (0 != logstderr) {
+ switch (reason) {
+ case 1: {
+ /* ERROR: sigemptyset() failed */
+ dk4dmt_log_1(prgname, slf, logstderr, 9);
+ } break;
+ case 2: {
+ /* ERROR: sigprocmask() failed */
+ dk4dmt_log_1(prgname, slf, logstderr, 10);
+ } break;
+ }
+ }
+ }
+
+ if ((0 != back) && (NULL != pidfilename)) {
+ if (0 != dk4stat_c8(&stb, pidfilename, NULL)) {
+ back = 0;
+ /* ERROR: PID file exists */
+ dk4dmt_log_3(prgname, slf, logstderr, 11, 12, pidfilename);
+ }
+ }
+
+ return back;
+}
+
+
+int
+dk4dmt_intermediate_before_fork(const char *prgname, int slf)
+{
+ int back = 1;
+#if DK4_HAVE_SETSID
+ if ((pid_t)(-1) == setsid()) {
+ back = 0;
+ dk4dmt_syslog_1(prgname, slf, 14);
+ }
+#else
+#if DK4_HAVE_SETPGRP
+ setpgrp();
+#else
+ back = 0;
+ dk4dmt_syslog_1(prgname, slf, 13);
+#endif
+#endif
+ return back;
+}
+
+
+
+int
+dk4dmt_daemon_after_fork(const char *prgname, const char *pidfilename, int slf)
+{
+ char pidbuf[16*sizeof(dk4_um_t)];
+ FILE *fipo;
+ int fdin; /* File descriptor for input */
+ int fdout; /* File descriptor for output */
+ int res; /* Operation result */
+ int back = 1;
+
+ if (NULL != pidfilename) {
+ res = dk4ma_write_c8_decimal_unsigned(
+ pidbuf, sizeof(pidbuf), (dk4_um_t)getpid(), 0, NULL
+ );
+ if (0 != res) {
+ if (0 != dk4str8_cat_s(pidbuf, sizeof(pidbuf), dk4dmt_kw[0], NULL)) {
+ (void)dk4mkdir_hierarchy_c8(pidfilename, 0, NULL);
+ fipo = dk4fopen_c8(pidfilename, "w", DK4_FOPEN_SC_PRIVILEGED, NULL);
+ if (NULL != fipo) {
+ fputs(pidbuf, fipo);
+ fclose(fipo);
+ } else {
+ dk4dmt_syslog_3(prgname, slf, 15, 16, pidfilename);
+ back = 0;
+ }
+ }
+ }
+ }
+
+ /* Connect /dev/null to stdin stout stderr or close them
+ */
+ fdin = open("/dev/null", O_RDONLY);
+ if (-1 < fdin) {
+ if (-1 == dup2(fdin, 0)) {
+ back = 0;
+ dk4dmt_syslog_1(prgname, slf, 19);
+ }
+ close(fdin);
+ } else {
+ back = 0;
+ dk4dmt_syslog_1(prgname, slf, 18);
+ }
+ fdout = open("/dev/null", O_WRONLY);
+ if (-1 < fdout) {
+ if (-1 == dup2(fdout, 1)) {
+ back = 0;
+ dk4dmt_syslog_1(prgname, slf, 21);
+ }
+ if (-1 == dup2(fdout, 2)) {
+ back = 0;
+ dk4dmt_syslog_1(prgname, slf, 22);
+ }
+ close(fdout);
+ } else {
+ back = 0;
+ dk4dmt_syslog_1(prgname, slf, 20);
+ }
+
+ /* Use exact permissions when creating new files or directories.
+ */
+ umask(0);
+
+ /* Change to root directory, so the previous current directory
+ can be unmounted without blocking.
+ */
+ if (0 != chdir("/")) {
+ back = 0;
+ dk4dmt_syslog_1(prgname, slf, 23);
+ }
+
+ /* Indicate success or error.
+ */
+ return back;
+}
+
+
+
+void
+dk4dmt_daemon_end(const char *prgname, const char *pidfilename, int slf)
+{
+ if (NULL != pidfilename) {
+ if (0 != unlink(pidfilename)) {
+ dk4dmt_syslog_3(prgname, slf, 24, 25, pidfilename);
+ }
+ }
+}
+
+
diff --git a/support/dktools/dk4dmt.h b/support/dktools/dk4dmt.h
new file mode 100644
index 0000000000..b2a1059b5c
--- /dev/null
+++ b/support/dktools/dk4dmt.h
@@ -0,0 +1,135 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4dmt.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4DMT_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4DMT_H_INCLUDED 1
+
+
+#line 8 "dk4dmt.ctr"
+
+/** @file dk4dmt.h Daemon tools.
+
+The functions in this module can be used in standing daemons.
+
+In the original process, call the
+dk4dmt_parent_before_fork() function to close all file descriptors
+above 2, reset all signal handlers to defaults, unblock all signals
+and check whether a PID file already exists.
+If you plan to give up root privileges in the child processes
+(use setgid() and setuid() to change effective user and group),
+do not use /var/run/<i>program</i>.pid as PID file name, better
+use /var/run/<i>program</i>/<i>program</i>.pid instead and make
+sure to set ownership and group on /var/run/<i>program</i>
+to the unprivileged user and group used by the child process.
+User and group need write permission to the directory, so the unprivileged
+child process can remove the PID file when exiting.
+
+In the intermediate process after the first fork call
+dk4dmt_intermediate_before_fork(). Among other things this function
+completely decouples the process from the terminal.
+
+In the final process (after forking again) call
+dk4dmt_daemon_after_fork()
+to set up things before starting service. This function creates the PID
+file, connects file descriptors 0, 1 and 2 to /dev/null, resets
+the umask and changes into the / directory.
+
+After finishing service call
+dk4dmt_daemon_end() before exiting. This function removes the PID
+file.
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Activities in parent process before calling fork().
+ * Close all file descriptors above 2.
+ * Reset all signal actions to default handlers.
+ * Unblock all signals.
+ * Check whether PID file already exists.
+ Use this function to check whether the initial process
+ can run fork().
+ @param prgname Program name.
+ @param pidfilename PID file name.
+ @param logstderr Flag: Logging to stderr allowed.
+ @param slf Syslog feature.
+ @return 1 on success (can call fork), 0 on error (abort).
+*/
+int
+dk4dmt_parent_before_fork(
+ const char *prgname, const char *pidfilename, int logstderr, int slf
+);
+
+
+/** Activities in first child before calling fork() again.
+ * Decouple completely from terminal.
+ Use this function to check whether the first child process
+ can run fork() again.
+ @param prgname Program name.
+ @param slf Syslog feature.
+ @return 1 on success (can call fork), 0 on error (abort).
+*/
+int
+dk4dmt_intermediate_before_fork(const char *prgname, int slf);
+
+/** Activities in final daemon process.
+ * Create PID file.
+ * Connect file descriptors 0, 1 and 2 to /dev/null.
+ * Reset umask.
+ * Change into / directory.
+ @param prgname Program name.
+ @param pidfilename File name for PID file.
+ @param slf Syslog feature.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4dmt_daemon_after_fork(const char *prgname, const char *pidfilename, int slf);
+
+/** End of daemon, remove PID file.
+ @param prgname Program name.
+ @param pidfilename PID file name.
+ @param slf Syslog feature.
+*/
+void
+dk4dmt_daemon_end(const char *prgname, const char *pidfilename, int slf);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4edstm.h b/support/dktools/dk4edstm.h
new file mode 100644
index 0000000000..b985cf50a5
--- /dev/null
+++ b/support/dktools/dk4edstm.h
@@ -0,0 +1,58 @@
+#ifndef DK4EDSTM_H_INCLUDED
+#define DK4EDSTM_H_INCLUDED 1
+
+/** @file dk4edstm.h Output values for state machines used
+ to encode and decode data or for BOM detection.
+
+ Several tasks in encoding, decoding and BOM detection are implemented
+ using state machines.
+ When using the state machine you pass byte by byte (or word by
+ word in UTF-16 decoding) to the state machine.
+ The state machines response is one from DK4_EDSTM_ACCEPT,
+ DK4_EDSTM_FINISHED, DK4_EDSTM_FINISHED_WITH_UNUSED, or
+ DK4_EDSTM_ERROR.
+ You should perform an adequate action for the response.
+ See the documentation of the specific state machine for possible
+ actions.
+
+*/
+
+/** Results when adding bytes to an encoder, decoder or BOM detector.
+*/
+enum {
+ /** Byte(s) added successfully, stored in
+ the decoders internal state.
+ No further action necessary.
+ */
+ DK4_EDSTM_ACCEPT = 0,
+
+ /** Byte(s) added successfully,
+ you can retrieve output.
+ */
+ DK4_EDSTM_FINISHED ,
+
+ /** Detection/encoding/decoding finished,
+ you can retrieve the result but
+ unused data is is saved in the state
+ machine.
+ You should retrieve and process the
+ unused data before continuing to
+ process the data stream.
+ */
+ DK4_EDSTM_FINISHED_WITH_UNUSED ,
+
+ /** An EOD marker was found during
+ decoding (i.e. when decoding ASCII85
+ data).
+ You should retrieve and process
+ output available in the state machine.
+ */
+ DK4_EDSTM_STOP ,
+
+ /** An error occured while adding byte(s).
+ */
+ DK4_EDSTM_ERROR = -1
+};
+
+#endif
+
diff --git a/support/dktools/dk4enc.c b/support/dktools/dk4enc.c
new file mode 100644
index 0000000000..0659794b1c
--- /dev/null
+++ b/support/dktools/dk4enc.c
@@ -0,0 +1,338 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4enc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4enc.c The dk4enc module.
+*/
+
+
+#line 138 "dk4enc.ctr"
+
+#include "dk4enc.h"
+#include "dk4mem.h"
+#include "dk4strd.h"
+
+
+
+/** Encoding names in variations.
+*/
+static const dkChar * const dk4enc_encoding_names[] = {
+/* 0 */
+dkT("plain"),
+
+/* 1 */
+dkT("ascii"),
+
+/* 2 */
+dkT("ansi"),
+
+/* 3 */
+dkT("utf-8"),
+
+/* 4 */
+dkT("utf8"),
+
+/* 5 */
+dkT("utf-16"),
+
+/* 6 */
+dkT("utf16"),
+
+/* 7 */
+dkT("utf-16-le"),
+
+/* 8 */
+dkT("utf-16le"),
+
+/* 9 */
+dkT("utf16le"),
+
+/* 10 */
+dkT("utf-16-lsb"),
+
+/* 11 */
+dkT("utf-16lsb"),
+
+/* 12 */
+dkT("utf16lsb"),
+
+/* 13 */
+dkT("utf-16-be"),
+
+/* 14 */
+dkT("utf-16be"),
+
+/* 15 */
+dkT("utf16be"),
+
+/* 16 */
+dkT("utf-16-msb"),
+
+/* 17 */
+dkT("utf-16msb"),
+
+/* 18 */
+dkT("utf16msb"),
+
+/* 19 */
+dkT("c32"),
+
+/* 20 */
+dkT("c32-le"),
+
+/* 21 */
+dkT("c32le"),
+
+/* 22 */
+dkT("c32-lsb"),
+
+/* 23 */
+dkT("c32lsb"),
+
+/* 24 */
+dkT("c32-be"),
+
+/* 25 */
+dkT("c32be"),
+
+/* 26 */
+dkT("c32-msb"),
+
+/* 27 */
+dkT("c32msb"),
+
+/* 28 */
+dkT("utf-16.msb"),
+
+/* 29 */
+dkT("utf-16.lsb"),
+
+/* 30 */
+dkT("uc32"),
+
+/* 31 */
+dkT("uc32.msb"),
+
+/* 32 */
+dkT("uc32.lsb"),
+
+/* 33 */
+dkT("iso-latin-1"),
+
+/* 34 */
+dkT("iso-8859-1"),
+
+NULL
+
+
+#line 215 "dk4enc.ctr"
+};
+
+
+
+/** Keywords for further options.
+*/
+static const dkChar * const dk4enc_option_keywords[] = {
+/* 0 */
+dkT("le"),
+
+/* 1 */
+dkT("lsb"),
+
+/* 2 */
+dkT("be"),
+
+/* 3 */
+dkT("msb"),
+
+/* 4 */
+dkT("bom"),
+
+/* 5 */
+dkT("nobom"),
+
+NULL
+
+
+#line 230 "dk4enc.ctr"
+};
+
+
+
+int
+dk4enc_find(int *encptr, int *bomptr, const dkChar *src, dk4_er_t *erp)
+{
+ dkChar buf[64]; /* Private copy for modification */
+ dkChar *p1; /* Start of text */
+ dkChar *p2; /* Start of options */
+ int res = 0; /* Array index */
+ int back = 0; /* Function result */
+ int ae = 0; /* Flag: Allow ending specification */
+ int enc = 0; /* Encoding found */
+ int bom = 0; /* Flag: BOM keyword found */
+ int bom_f = 0; /* Flag: BOM information found */
+
+ if ((NULL != encptr) && (NULL != src)) {
+ if (0 != dk4str_cpy_s(buf, DK4_SIZEOF(buf,dkChar), src, erp)) {
+ p1 = dk4str_start(buf, NULL);
+ if (NULL != p1) {
+ p2 = dk4str_chr(buf, dkT(','));
+ if (NULL == p2) {
+ p2 = dk4str_chr(buf, dkT('.'));
+ }
+ if (NULL != p2) { *(p2++) = dkT('\0'); p2 = dk4str_start(p2, NULL); }
+ dk4str_normalize(p1, NULL);
+ switch (dk4str_array_index(dk4enc_encoding_names, p1, 0)) {
+ case 0: case 1: case 33: case 34: {
+ enc = DK4_FILE_ENCODING_ASCII;
+ back = 1;
+ } break;
+ case 2: {
+ enc = DK4_FILE_ENCODING_ANSI;
+ back = 1;
+ } break;
+ case 3: case 4: {
+ enc = DK4_FILE_ENCODING_UTF8;
+ back = 1;
+ } break;
+ case 5: case 6: {
+ enc = DK4_ENCODING_UTF16;
+ ae = 1;
+ back = 1;
+ bom = 1;
+ } break;
+ case 7: case 8: case 9: case 10: case 11: case 12: case 29: {
+ enc = DK4_FILE_ENCODING_UTF16_LE;
+ back = 1;
+ bom = 1;
+ } break;
+ case 13: case 14: case 15: case 16: case 17: case 18: case 28: {
+ enc = DK4_FILE_ENCODING_UTF16_BE;
+ back = 1;
+ bom = 1;
+ } break;
+ case 19: case 30: {
+ enc = DK4_ENCODING_32;
+ ae = 1;
+ back = 1;
+ bom = 1;
+ } break;
+ case 20: case 21: case 22: case 23: case 32: {
+ enc = DK4_FILE_ENCODING_32_LE;
+ back = 1;
+ bom = 1;
+ } break;
+ case 24: case 25: case 26: case 27: case 31: {
+ enc = DK4_FILE_ENCODING_32_BE;
+ back = 1;
+ bom = 1;
+ } break;
+ default: {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ if (1 == back) {
+ while (NULL != p2) {
+ p1 = dk4str_chr(p2, dkT(','));
+ if (NULL != p1) { *(p1++) = dkT('\0'); p1 = dk4str_start(p1,NULL); }
+ dk4str_normalize(p2, NULL);
+ switch (res = dk4str_array_index(dk4enc_option_keywords, p2, 0)) {
+ case 0: case 1: case 2: case 3: {
+ if (0 != ae) {
+ switch (enc) {
+ case DK4_ENCODING_UTF16: {
+ enc = (
+ ((2 == res) || (3 == res))
+ ? DK4_FILE_ENCODING_UTF16_BE
+ : DK4_FILE_ENCODING_UTF16_LE
+ );
+ } break;
+ case DK4_ENCODING_32: {
+ enc = (
+ ((2 == res) || (3 == res))
+ ? DK4_FILE_ENCODING_32_BE
+ : DK4_FILE_ENCODING_32_LE
+ );
+ } break;
+ }
+ ae = 0;
+ } else {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ case 4: {
+ switch (enc) {
+ case DK4_FILE_ENCODING_UTF8:
+ case DK4_FILE_ENCODING_UTF16_LE:
+ case DK4_FILE_ENCODING_UTF16_BE:
+ case DK4_FILE_ENCODING_32_LE:
+ case DK4_FILE_ENCODING_32_BE: {
+ bom = 1;
+ bom_f = 1;
+ } break;
+ default: {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } break;
+ case 5: {
+ bom = 0;
+ bom_f = 1;
+ } break;
+ default: {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ p2 = p1;
+ }
+ }
+ } else {
+ /* ERROR: Empty string */
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ if (NULL != encptr) { *encptr = enc; }
+ if (0 != bom_f) { if (NULL != bomptr) { *bomptr = bom; } }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4enc.ctr b/support/dktools/dk4enc.ctr
new file mode 100644
index 0000000000..898a825a6e
--- /dev/null
+++ b/support/dktools/dk4enc.ctr
@@ -0,0 +1,379 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ File and memory encodings for characters.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+/** Encodings for text files.
+*/
+enum {
+ /** ASCII character set.
+ */
+ DK4_FILE_ENCODING_ASCII = 0,
+
+ /** ANSII encoding (used ie on Windows).
+ */
+ DK4_FILE_ENCODING_ANSI ,
+
+ /** UTF-8 encoding used on Linux and Unix.
+ */
+ DK4_FILE_ENCODING_UTF8 ,
+
+ /** UTF-16 encoding, least significant
+ byte first.
+ */
+ DK4_FILE_ENCODING_UTF16_LE ,
+
+ /** UTF-16 encoding, most significant
+ byte first.
+ */
+ DK4_FILE_ENCODING_UTF16_BE ,
+
+ /** 32-bit unicode characters, least
+ significant byte first.
+ */
+ DK4_FILE_ENCODING_32_LE ,
+
+ /** 32-bit unicode characters, most
+ significant byte first.
+ */
+ DK4_FILE_ENCODING_32_BE
+};
+
+/** Encoding for characters in memory.
+*/
+enum {
+ /** ASCII character set (0 to 255) in
+ ISO-LATIN-8859-1.
+ */
+ DK4_ENCODING_ASCII = DK4_FILE_ENCODING_ASCII,
+
+ /** ANSII encoding (used ie on Windows).
+ */
+ DK4_ENCODING_ANSI = DK4_FILE_ENCODING_ANSI,
+
+ /** UTF-8 encoding used on Linux and Unix.
+ */
+ DK4_ENCODING_UTF8 = DK4_FILE_ENCODING_UTF8,
+
+#if DK4_WORDS_BIGENDIAN
+
+ /** UTF-16 encoding.
+ */
+ DK4_ENCODING_UTF16 = DK4_FILE_ENCODING_UTF16_BE,
+
+ /** 32-bit unicode characters.
+ */
+ DK4_ENCODING_32 = DK4_FILE_ENCODING_32_BE
+
+#else
+
+ /** UTF-16 encoding.
+ */
+ DK4_ENCODING_UTF16 = DK4_FILE_ENCODING_UTF16_LE,
+
+ /** 32-bit unicode characters.
+ */
+ DK4_ENCODING_32 = DK4_FILE_ENCODING_32_LE
+
+#endif
+};
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Find encoding by name.
+ @param encptr Pointer to result variable for encoding.
+ @param bomptr Pointer to result variable for BOM writing.
+ @param src Source text containing encoding name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if encptr or src is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the text is too long to create a local copy for modification, or
+ - DK4_E_SYNTAX<br>
+ if invalid encoding, options or encoding/option combinations are
+ specified.
+*/
+int
+dk4enc_find(int *encptr, int *bomptr, const dkChar *src, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4enc.h"
+#include "dk4mem.h"
+#include "dk4strd.h"
+
+
+
+/** Encoding names in variations.
+*/
+static const dkChar * const dk4enc_encoding_names[] = {
+$!string-table macro=dkT
+#
+# 0 ... 1 ASCII
+#
+plain
+ascii
+#
+# 2 ANSI, used on Windows systems
+#
+ansi
+#
+# 3 ... 4 UTF-8
+#
+utf-8
+utf8
+#
+# 5 ... 6 UTF-16, systems native endianness
+#
+utf-16
+utf16
+#
+# 7 ... 12 UTF-16LE
+#
+utf-16-le
+utf-16le
+utf16le
+utf-16-lsb
+utf-16lsb
+utf16lsb
+#
+# 13 ... 18 UTF-16BE
+#
+utf-16-be
+utf-16be
+utf16be
+utf-16-msb
+utf-16msb
+utf16msb
+#
+# 19 32 bit in systems native endianness
+#
+c32
+#
+# 20 ... 23 32 bit little endian
+#
+c32-le
+c32le
+c32-lsb
+c32lsb
+#
+# 24 ... 27 32 bit big endian
+#
+c32-be
+c32be
+c32-msb
+c32msb
+#
+# 28 ... 34 Backward compatibility
+#
+utf-16.msb
+utf-16.lsb
+uc32
+uc32.msb
+uc32.lsb
+iso-latin-1
+iso-8859-1
+$!end
+};
+
+
+
+/** Keywords for further options.
+*/
+static const dkChar * const dk4enc_option_keywords[] = {
+$!string-table macro=dkT
+le
+lsb
+be
+msb
+bom
+nobom
+$!end
+};
+
+
+
+int
+dk4enc_find(int *encptr, int *bomptr, const dkChar *src, dk4_er_t *erp)
+{
+ dkChar buf[64]; /* Private copy for modification */
+ dkChar *p1; /* Start of text */
+ dkChar *p2; /* Start of options */
+ int res = 0; /* Array index */
+ int back = 0; /* Function result */
+ int ae = 0; /* Flag: Allow ending specification */
+ int enc = 0; /* Encoding found */
+ int bom = 0; /* Flag: BOM keyword found */
+ int bom_f = 0; /* Flag: BOM information found */
+
+ if ((NULL != encptr) && (NULL != src)) {
+ if (0 != dk4str_cpy_s(buf, DK4_SIZEOF(buf,dkChar), src, erp)) {
+ p1 = dk4str_start(buf, NULL);
+ if (NULL != p1) {
+ p2 = dk4str_chr(buf, dkT(','));
+ if (NULL == p2) {
+ p2 = dk4str_chr(buf, dkT('.'));
+ }
+ if (NULL != p2) { *(p2++) = dkT('\0'); p2 = dk4str_start(p2, NULL); }
+ dk4str_normalize(p1, NULL);
+ switch (dk4str_array_index(dk4enc_encoding_names, p1, 0)) {
+ case 0: case 1: case 33: case 34: {
+ enc = DK4_FILE_ENCODING_ASCII;
+ back = 1;
+ } break;
+ case 2: {
+ enc = DK4_FILE_ENCODING_ANSI;
+ back = 1;
+ } break;
+ case 3: case 4: {
+ enc = DK4_FILE_ENCODING_UTF8;
+ back = 1;
+ } break;
+ case 5: case 6: {
+ enc = DK4_ENCODING_UTF16;
+ ae = 1;
+ back = 1;
+ bom = 1;
+ } break;
+ case 7: case 8: case 9: case 10: case 11: case 12: case 29: {
+ enc = DK4_FILE_ENCODING_UTF16_LE;
+ back = 1;
+ bom = 1;
+ } break;
+ case 13: case 14: case 15: case 16: case 17: case 18: case 28: {
+ enc = DK4_FILE_ENCODING_UTF16_BE;
+ back = 1;
+ bom = 1;
+ } break;
+ case 19: case 30: {
+ enc = DK4_ENCODING_32;
+ ae = 1;
+ back = 1;
+ bom = 1;
+ } break;
+ case 20: case 21: case 22: case 23: case 32: {
+ enc = DK4_FILE_ENCODING_32_LE;
+ back = 1;
+ bom = 1;
+ } break;
+ case 24: case 25: case 26: case 27: case 31: {
+ enc = DK4_FILE_ENCODING_32_BE;
+ back = 1;
+ bom = 1;
+ } break;
+ default: {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ if (1 == back) {
+ while (NULL != p2) {
+ p1 = dk4str_chr(p2, dkT(','));
+ if (NULL != p1) { *(p1++) = dkT('\0'); p1 = dk4str_start(p1,NULL); }
+ dk4str_normalize(p2, NULL);
+ switch (res = dk4str_array_index(dk4enc_option_keywords, p2, 0)) {
+ case 0: case 1: case 2: case 3: {
+ if (0 != ae) {
+ switch (enc) {
+ case DK4_ENCODING_UTF16: {
+ enc = (
+ ((2 == res) || (3 == res))
+ ? DK4_FILE_ENCODING_UTF16_BE
+ : DK4_FILE_ENCODING_UTF16_LE
+ );
+ } break;
+ case DK4_ENCODING_32: {
+ enc = (
+ ((2 == res) || (3 == res))
+ ? DK4_FILE_ENCODING_32_BE
+ : DK4_FILE_ENCODING_32_LE
+ );
+ } break;
+ }
+ ae = 0;
+ } else {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ case 4: {
+ switch (enc) {
+ case DK4_FILE_ENCODING_UTF8:
+ case DK4_FILE_ENCODING_UTF16_LE:
+ case DK4_FILE_ENCODING_UTF16_BE:
+ case DK4_FILE_ENCODING_32_LE:
+ case DK4_FILE_ENCODING_32_BE: {
+ bom = 1;
+ bom_f = 1;
+ } break;
+ default: {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } break;
+ case 5: {
+ bom = 0;
+ bom_f = 1;
+ } break;
+ default: {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ p2 = p1;
+ }
+ }
+ } else {
+ /* ERROR: Empty string */
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ if (NULL != encptr) { *encptr = enc; }
+ if (0 != bom_f) { if (NULL != bomptr) { *bomptr = bom; } }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4enc.h b/support/dktools/dk4enc.h
new file mode 100644
index 0000000000..cdeba4e9a1
--- /dev/null
+++ b/support/dktools/dk4enc.h
@@ -0,0 +1,170 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4enc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4ENC_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4ENC_H_INCLUDED 1
+
+
+#line 10 "dk4enc.ctr"
+
+/** @file
+ File and memory encodings for characters.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+/** Encodings for text files.
+*/
+enum {
+ /** ASCII character set.
+ */
+ DK4_FILE_ENCODING_ASCII = 0,
+
+ /** ANSII encoding (used ie on Windows).
+ */
+ DK4_FILE_ENCODING_ANSI ,
+
+ /** UTF-8 encoding used on Linux and Unix.
+ */
+ DK4_FILE_ENCODING_UTF8 ,
+
+ /** UTF-16 encoding, least significant
+ byte first.
+ */
+ DK4_FILE_ENCODING_UTF16_LE ,
+
+ /** UTF-16 encoding, most significant
+ byte first.
+ */
+ DK4_FILE_ENCODING_UTF16_BE ,
+
+ /** 32-bit unicode characters, least
+ significant byte first.
+ */
+ DK4_FILE_ENCODING_32_LE ,
+
+ /** 32-bit unicode characters, most
+ significant byte first.
+ */
+ DK4_FILE_ENCODING_32_BE
+};
+
+/** Encoding for characters in memory.
+*/
+enum {
+ /** ASCII character set (0 to 255) in
+ ISO-LATIN-8859-1.
+ */
+ DK4_ENCODING_ASCII = DK4_FILE_ENCODING_ASCII,
+
+ /** ANSII encoding (used ie on Windows).
+ */
+ DK4_ENCODING_ANSI = DK4_FILE_ENCODING_ANSI,
+
+ /** UTF-8 encoding used on Linux and Unix.
+ */
+ DK4_ENCODING_UTF8 = DK4_FILE_ENCODING_UTF8,
+
+#if DK4_WORDS_BIGENDIAN
+
+ /** UTF-16 encoding.
+ */
+ DK4_ENCODING_UTF16 = DK4_FILE_ENCODING_UTF16_BE,
+
+ /** 32-bit unicode characters.
+ */
+ DK4_ENCODING_32 = DK4_FILE_ENCODING_32_BE
+
+#else
+
+ /** UTF-16 encoding.
+ */
+ DK4_ENCODING_UTF16 = DK4_FILE_ENCODING_UTF16_LE,
+
+ /** 32-bit unicode characters.
+ */
+ DK4_ENCODING_32 = DK4_FILE_ENCODING_32_LE
+
+#endif
+};
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Find encoding by name.
+ @param encptr Pointer to result variable for encoding.
+ @param bomptr Pointer to result variable for BOM writing.
+ @param src Source text containing encoding name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if encptr or src is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the text is too long to create a local copy for modification, or
+ - DK4_E_SYNTAX<br>
+ if invalid encoding, options or encoding/option combinations are
+ specified.
+*/
+int
+dk4enc_find(int *encptr, int *bomptr, const dkChar *src, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4error.c b/support/dktools/dk4error.c
new file mode 100644
index 0000000000..e1620fa49b
--- /dev/null
+++ b/support/dktools/dk4error.c
@@ -0,0 +1,234 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4error.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4error.c The dk4error module.
+*/
+
+
+#line 514 "dk4error.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS && (DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT)
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4mem.h"
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+
+
+
+
+#line 538 "dk4error.ctr"
+
+
+
+void
+dk4error_init(dk4_er_t *erp)
+{
+
+
+#line 545 "dk4error.ctr"
+ if (NULL != erp) {
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ ZeroMemory(erp, sizeof(dk4_er_t));
+#else
+ memset(erp, 0, sizeof(dk4_er_t));
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+#if DK4_HAVE_MEMSET
+ memset(erp, 0, sizeof(dk4_er_t));
+#else
+#if DK4_HAVE_BZERO
+ bzero(erp, sizeof(dk4_er_t);
+#else
+ {
+ register char *ptr;
+ register size_t sz;
+ ptr = (char *)erp; sz = sizeof(dk4_er_t);
+ while(sz--) { *(ptr++) = '\0'; }
+ }
+#endif
+#endif
+ /* --- non-Windows */
+#endif
+ erp->ec = DK4_E_NONE;
+ }
+
+
+#line 575 "dk4error.ctr"
+}
+
+
+
+void
+dk4error_set_simple_error_code(dk4_er_t *erp, int ec)
+{
+ if (NULL != erp) {
+ if (DK4_E_NONE == erp->ec) {
+ erp->ec = ec;
+ }
+ }
+}
+
+
+
+void
+dk4error_set_elsize_nelem(dk4_er_t *erp, int ec, size_t sz, size_t ne)
+{
+ if (NULL != erp) {
+ if (DK4_E_NONE == erp->ec) {
+ erp->ec = ec;
+ (erp->dt).mem.elsize = sz;
+ (erp->dt).mem.nelem = ne;
+ }
+ }
+}
+
+
+
+void
+dk4error_set_idetails(dk4_er_t *erp, int ec, int errnval)
+{
+ if (NULL != erp) {
+ if (DK4_E_NONE == erp->ec) {
+ erp->ec = ec;
+ (erp->dt).iDetails1 = errnval;
+ }
+ }
+}
+
+
+void
+dk4error_set_ldetails(dk4_er_t *erp, int ec, long errnval)
+{
+ if (NULL != erp) {
+ if (DK4_E_NONE == erp->ec) {
+ erp->ec = ec;
+ (erp->dt).lDetails1 = errnval;
+ }
+ }
+}
+
+
+
+void
+dk4error_set_with_position(
+ dk4_er_t *erp,
+ int ec,
+ dk4_um_t byteno,
+ dk4_um_t lineno,
+ dk4_um_t charno,
+ dk4_um_t charinline
+)
+{
+ if (NULL != erp) {
+ if (DK4_E_NONE == erp->ec) {
+ erp->ec = ec;
+
+
+#line 644 "dk4error.ctr"
+
+
+#line 645 "dk4error.ctr"
+
+
+#line 646 "dk4error.ctr"
+
+
+#line 647 "dk4error.ctr"
+ (erp->dt).fpos.byteno = byteno;
+ (erp->dt).fpos.lineno = lineno;
+ (erp->dt).fpos.charno = charno;
+ (erp->dt).fpos.charinline = charinline;
+ }
+ }
+}
+
+
+
+void
+dk4error_copy(dk4_er_t *dptr, const dk4_er_t *sptr)
+{
+ if ((NULL != dptr) && (NULL != sptr)) {
+ if (DK4_E_NONE == dptr->ec) {
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ CopyMemory(dptr, sptr, sizeof(dk4_er_t));
+#else
+ memcpy(dptr, sptr, sizeof(dk4_er_t));
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+#if DK4_HAVE_MEMCPY
+ memcpy(dptr, sptr, sizeof(dk4_er_t));
+#else
+#if DK4_HAVE_BCOPY
+ bcopy(sptr, dptr, sizeof(dk4_er_t));
+#else
+ register unsigned char *dp; /* Destination pointer */
+ register const unsigned char *sp; /* Source pointer */
+ register size_t xsz; /* Number remaining bytes */
+
+ dp = (unsigned char *)dptr;
+ sp = (const unsigned char *)sptr;
+ xsz = sizeof(dk4_er_t);
+ while(0 < xsz--) { *(dp++) = *(sp++); }
+#endif
+#endif
+ /* --- non-Windows */
+#endif
+ }
+ }
+}
+
diff --git a/support/dktools/dk4error.ctr b/support/dktools/dk4error.ctr
new file mode 100644
index 0000000000..d717a0fb6c
--- /dev/null
+++ b/support/dktools/dk4error.ctr
@@ -0,0 +1,693 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ Return error information from
+ called function to caller, more detailed than just an
+ error code.
+
+ In addition to the error code we can save details, i.e.
+ the errno or GetLastError() value or the element size
+ and number of elements for a failed memory allocation...
+ This allows the caller to produce detailed error messages
+ if necessary.
+
+ Before processing a code section where errors can occur,
+ use dk4error_init() to initialize an error structure.
+ A value indicating ``no error occured'' is set in the structure.
+
+ Depending on the errors occuring, the code section might use
+ one from the dk4error_set_...() functions.
+
+ At the end of the code section, check the error code in the
+ dk4_er_t structure.
+
+
+ The address of one dk4_er_t can be passed to several function
+ calls. Only the first error occured is noted in the structure,
+ it is not overwritten by later errors.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+
+
+/** Error report.
+*/
+typedef struct {
+ /** Details.
+ */
+ union {
+ /** Position within a file or data stream.
+ */
+ struct {
+ dk4_um_t byteno; /**< Byte number. */
+ dk4_um_t lineno; /**< Line number. */
+ dk4_um_t charno; /**< Character number. */
+ dk4_um_t charinline; /**< Character number within the line. */
+ } fpos;
+ /** Failed memory allocation.
+ */
+ struct {
+ size_t elsize; /**< Element size. */
+ size_t nelem; /**< Number of elements. */
+ } mem;
+ int iDetails1; /**< Integer details. */
+ long lDetails1; /**< Long details. */
+ } dt;
+ int ec; /**< Error code. */
+} dk4_er_t;
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Initialize error report.
+
+ CRT on Windows: Optional.
+ @param erp Error report to initialize.
+*/
+void
+dk4error_init(dk4_er_t *erp);
+
+/** Set simple error code.
+
+ CRT on Windows: Not used.
+ @param erp Error report to modify, may be NULL.
+ @param ec New error code.
+*/
+void
+dk4error_set_simple_error_code(dk4_er_t *erp, int ec);
+
+/** Set error code for dealing with a number of elements
+ (memory allocation).
+
+ CRT on Windows: Not used.
+ @param erp Error report to modify, may be NULL.
+ @param ec New error code to set.
+ @param sz Element size.
+ @param ne Number of elements.
+*/
+void
+dk4error_set_elsize_nelem(dk4_er_t *erp, int ec, size_t sz, size_t ne);
+
+/** Set error code for error from a system function, save
+ errno value in details.
+
+ CRT on Windows: Not used.
+ @param erp Error report to modify, may be NULL.
+ @param ec New error code to set.
+ @param errnval Value of errno, stored in iDetails1.
+*/
+void
+dk4error_set_idetails(dk4_er_t *erp, int ec, int errnval);
+
+/** Set long error code for error from a Windows system function,
+ save GetLastError() value in details.
+
+ CRT on Windows: Not used.
+ @param erp Error report to modify, may be NULL.
+ @param ec New error code to set.
+ @param errnval Value obtained from GetLastError().
+*/
+void
+dk4error_set_ldetails(dk4_er_t *erp, int ec, long errnval);
+
+/** Set error code and keep file or data stream position.
+
+ CRT on Windows: Not used.
+ @param erp Error report to modify, may be NULL.
+ @param ec New error code to set.
+ @param byteno Byte position in file.
+ @param lineno Current line number.
+ @param charno Character number in file.
+ @param charinline Character position in line.
+*/
+void
+dk4error_set_with_position(
+ dk4_er_t *erp,
+ int ec,
+ dk4_um_t byteno,
+ dk4_um_t lineno,
+ dk4_um_t charno,
+ dk4_um_t charinline
+);
+
+/** Copy error report if there was an error in the source report
+ and no error yet in the destination report.
+
+ CRT on Windows: Optional.
+ @param dptr Destination report.
+ @param sptr Source report.
+*/
+void
+dk4error_copy(dk4_er_t *dptr, const dk4_er_t *sptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+/** Error codes.
+*/
+enum {
+
+ /** No error occured.
+ */
+ DK4_E_NONE = 0,
+
+ /** System error, the errno value is saved to
+ det,syserr.
+ */
+ DK4_E_SYSTEM ,
+
+ /** Something failed although it should not.
+ */
+ DK4_E_BUG ,
+
+ /** Invalid arguments (in example NULL pointers,
+ 0 sizes) were passed to a function.
+ No details are reported.
+ */
+ DK4_E_INVALID_ARGUMENTS ,
+
+ /** A buffer was too small to take a text
+ completely.
+ */
+ DK4_E_BUFFER_TOO_SMALL ,
+
+ /** The requested information was not found.
+ */
+ DK4_E_NOT_FOUND ,
+
+ /** Memory allocation failed. Element size and
+ number of elements are stored in
+ dt,mem,elsize and dt,mem,nelem.
+ */
+ DK4_E_MEMORY_ALLOCATION_FAILED ,
+
+ /** Numeric overflow. For floating point numbers
+ the absolute value exceeded DBL_MAX.
+ For integer numbers the result is outside
+ the range MIN...MAX.
+ No details are reported.
+ */
+ DK4_E_MATH_OVERFLOW ,
+
+ /** Numeric underflow.
+ The underflow is reported if the absolute
+ value of a floating point operation is too
+ small.
+ For integer numbers only overflow is reported
+ even if the result is smaller than MIN.
+ No details are reported.
+ */
+ DK4_E_MATH_UNDERFLOW ,
+
+ /** Division by zero. No details are reported.
+ */
+ DK4_E_MATH_DIVZERO ,
+
+ /** An invalid argument was passed to a
+ mathematical function.
+ */
+ DK4_E_MATH_INVALID ,
+
+ /** Mathematical result is inexact, cutting bits.
+ */
+ DK4_E_MATH_INEXACT ,
+
+ /** Syntax error when processing text, illegal
+ character when decoding or encoding.
+ */
+ DK4_E_SYNTAX ,
+
+ /** Functionality not supported on this system.
+ */
+ DK4_E_NOT_SUPPORTED ,
+
+ /** A write operation failed.
+ */
+ DK4_E_WRITE_FAILED ,
+
+ /** A data flush operation failed.
+ */
+ DK4_E_FLUSH_FAILED ,
+
+ /** Failed to read data.
+ */
+ DK4_E_READ_FAILED ,
+ /** A file or other stream close operation failed.
+ */
+ DK4_E_CLOSE_FAILED ,
+
+ /** Additional security checks before opening a
+ file failed.
+ */
+ DK4_E_SEC_CHECK ,
+
+ /** Attempt to open a file failed.
+ */
+ DK4_E_OPEN_FAILED ,
+
+ /** Failed to open file for reading.
+ */
+ DK4_E_OPEN_READ_FAILED ,
+
+ /** Failed to open file for writing.
+ */
+ DK4_E_OPEN_WRITE_FAILED ,
+
+ /** Failed to encode 32 bit character to
+ output encoding.
+ */
+ DK4_E_ENCODING_FAILED ,
+
+ /** Failed to decode 32 bit character from
+ input encoding.
+ */
+ DK4_E_DECODING_FAILED ,
+
+ /** Failed to create a directory.
+ */
+ DK4_E_MKDIR_FAILED ,
+
+ /** Failed to change file or directory ownership.
+ */
+ DK4_E_CHOWN_FAILED ,
+
+ /** Failed to change file or directory permissions.
+ */
+ DK4_E_CHMOD_FAILED ,
+
+ /** Non-directory component in path name.
+ */
+ DK4_E_NON_DIR ,
+
+ /** File exists, but is not a socket.
+ */
+ DK4_E_NON_SOCKET ,
+
+ /** An unlink operation failed.
+ */
+ DK4_E_UNLINK_FAILED ,
+
+ /** The DeleteFile() function on Windows failed.
+ */
+ DK4_E_DELETE_FILE_FAILED ,
+
+ /** An rmdir operation failed.
+ */
+ DK4_E_RMDIR_FAILED ,
+
+ /** The RemoveDirectory() function failed
+ on Windows.
+ */
+ DK4_E_REMOVE_DIRECTORY_FAILED ,
+
+ /** Opendir failed.
+ */
+ DK4_E_OPENDIR_FAILED ,
+
+ /** The CreateFile() function failed on Windows.
+ The result of GetLastError() is stored
+ in dt.lDetails1.
+ */
+ DK4_E_CREATE_FILE_FAILED ,
+
+ /** The CreateDirectory() function failed on
+ Windows. The result of GetLastError() is
+ stored in dt.lDetails1.
+ */
+ DK4_E_CREATE_DIR_FAILED ,
+
+ /** The GetFileInformationByHandle() function
+ failed on Windows. The result of
+ GetLastError() is stored in dt.lDetails1.
+ */
+ DK4_E_FILE_INFORMATION_FAILED ,
+
+ /** The FindFirstFile() function on Windows failed.
+ The GetLastError() value is stored in lDetails1.
+ */
+ DK4_E_FINDFIRSTFILE_FAILED ,
+
+ /** Timeout occured in socket operation,
+ no details in iDetails1.
+ */
+ DK4_E_SOCKET_TIMEOUT ,
+
+ /** The getaddrinfo() function failed to
+ find the remote address.
+ The function result is stored in iDetails1.
+ */
+ DK4_E_SOCKET_GETADDRINFO ,
+
+ /** The getaddrinfo() function failed to
+ find the local address.
+ The function result is stored in iDetails1.
+ */
+ DK4_E_SOCKET_GETADDRLOC ,
+
+ /** Failed to start up Windows sockets.
+ The error code from WSAGetLastError() on
+ Windows / errno on non-Windows is stored
+ in iDetails1.
+ */
+ DK4_E_SOCKET_UP ,
+
+ /** Failed to shut down Windows sockets.
+ The error code from WSAGetLastError() on
+ Windows / errno on non-Windows is stored
+ in iDetails1.
+ */
+ DK4_E_SOCKET_DOWN ,
+
+ /** The socket() function failed.
+ The error code from WSAGetLastError() on
+ Windows / errno on non-Windows is stored
+ in iDetails1.
+ */
+ DK4_E_SOCKET_SOCKET ,
+
+ /** The close() or closesocket() function failed.
+ The error code from WSAGetLastError() on
+ Windows / errno on non-Windows is stored
+ in iDetails1.
+ */
+ DK4_E_SOCKET_CLOSE ,
+
+ /** The bind() function failed.
+ The error code from WSAGetLastError() on
+ Windows / errno on non-Windows is stored
+ in iDetails1.
+ */
+ DK4_E_SOCKET_BIND ,
+
+ /** The connect() function failed.
+ The error code from WSAGetLastError() on
+ Windows / errno on non-Windows is stored
+ in iDetails1.
+ */
+ DK4_E_SOCKET_CONNECT ,
+
+ /** The listen() function failed.
+ The error code from WSAGetLastError() on
+ Windows / errno on non-Windows is stored
+ in iDetails1.
+ */
+ DK4_E_SOCKET_LISTEN ,
+
+ /** The accept() function failed.
+ The error code from WSAGetLastError() on
+ Windows / errno on non-Windows is stored
+ in iDetails1.
+ */
+ DK4_E_SOCKET_ACCEPT ,
+
+ /** The select() function failed.
+ The error code from WSAGetLastError() on
+ Windows / errno on non-Windows is stored
+ in iDetails1.
+ */
+ DK4_E_SOCKET_SELECT ,
+
+ /** The setsockopt() function failed.
+ The error code from WSAGetLastError() on
+ Windows / errno on non-Windows is stored
+ in iDetails1.
+ */
+ DK4_E_SOCKET_SETSOCKOPT ,
+
+ /** The getsockopt() function failed.
+ The error code from WSAGetLastError() on
+ Windows / errno on non-Windows is stored
+ in iDetails1.
+ */
+ DK4_E_SOCKET_GETSOCKOPT ,
+
+ /** The shutdown() function failed.
+ The error code from WSAGetLastError() on
+ Windows / errno on non-Windows is stored
+ in iDetails1.
+ */
+ DK4_E_SOCKET_SHUTDOWN ,
+
+ /** The send()/sendto() function failed.
+ The error code from WSAGetLastError() on
+ Windows / errno on non-Windows is stored
+ in iDetails1.
+ */
+ DK4_E_SOCKET_SEND ,
+
+ /** The recv()/recvfrom() function failed.
+ The error code from WSAGetLastError() on
+ Windows / errno on non-Windows is stored
+ in iDetails1.
+ */
+ DK4_E_SOCKET_RECV ,
+
+ /** The ioctlsocket() function failed.
+ The error code from WSAGetLastError() on
+ Windows is stored in iDetails1.
+ On Windows only.
+ */
+ DK4_E_SOCKET_IOCTLSOCKET ,
+
+ /** The fcntl() function failed.
+ The error code from
+ errno on non-Windows is stored
+ in iDetails1.
+ Not on Windows systems (ioctlsocket
+ is used to switch between blocking
+ and non-blocking).
+ */
+ DK4_E_SOCKET_FCNTL ,
+
+ /** The getservbyname() function failed.
+ The error code from WSAGetLastError() on
+ Windows / errno on non-Windows is stored
+ in iDetails1.
+ */
+ DK4_E_SOCKET_GETSERVBYNAME ,
+
+ /** The gethostbyname() function failed.
+ The error code from WSAGetLastError() on
+ Windows / errno on non-Windows is stored
+ in iDetails1.
+ */
+ DK4_E_SOCKET_GETHOSTBYNAME ,
+
+ /** The inet_ntop() function failed.
+ The error code from WSAGetLastError() on
+ Windows / errno on non-Windows is stored
+ in iDetails1.
+ */
+ DK4_E_SOCKET_INET_NTOP ,
+
+ /** The inet_pton() function failed.
+ The error code from WSAGetLastError() on
+ Windows / errno on non-Windows is stored
+ in iDetails1.
+ */
+ DK4_E_SOCKET_INET_PTON ,
+};
+
+
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS && (DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT)
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4mem.h"
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+
+
+$!trace-include
+
+
+
+void
+dk4error_init(dk4_er_t *erp)
+{
+ $? "+ dk4error_init"
+ if (NULL != erp) {
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ ZeroMemory(erp, sizeof(dk4_er_t));
+#else
+ memset(erp, 0, sizeof(dk4_er_t));
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+#if DK4_HAVE_MEMSET
+ memset(erp, 0, sizeof(dk4_er_t));
+#else
+#if DK4_HAVE_BZERO
+ bzero(erp, sizeof(dk4_er_t);
+#else
+ {
+ register char *ptr;
+ register size_t sz;
+ ptr = (char *)erp; sz = sizeof(dk4_er_t);
+ while(sz--) { *(ptr++) = '\0'; }
+ }
+#endif
+#endif
+ /* --- non-Windows */
+#endif
+ erp->ec = DK4_E_NONE;
+ }
+ $? "- dk4error_init"
+}
+
+
+
+void
+dk4error_set_simple_error_code(dk4_er_t *erp, int ec)
+{
+ if (NULL != erp) {
+ if (DK4_E_NONE == erp->ec) {
+ erp->ec = ec;
+ }
+ }
+}
+
+
+
+void
+dk4error_set_elsize_nelem(dk4_er_t *erp, int ec, size_t sz, size_t ne)
+{
+ if (NULL != erp) {
+ if (DK4_E_NONE == erp->ec) {
+ erp->ec = ec;
+ (erp->dt).mem.elsize = sz;
+ (erp->dt).mem.nelem = ne;
+ }
+ }
+}
+
+
+
+void
+dk4error_set_idetails(dk4_er_t *erp, int ec, int errnval)
+{
+ if (NULL != erp) {
+ if (DK4_E_NONE == erp->ec) {
+ erp->ec = ec;
+ (erp->dt).iDetails1 = errnval;
+ }
+ }
+}
+
+
+void
+dk4error_set_ldetails(dk4_er_t *erp, int ec, long errnval)
+{
+ if (NULL != erp) {
+ if (DK4_E_NONE == erp->ec) {
+ erp->ec = ec;
+ (erp->dt).lDetails1 = errnval;
+ }
+ }
+}
+
+
+
+void
+dk4error_set_with_position(
+ dk4_er_t *erp,
+ int ec,
+ dk4_um_t byteno,
+ dk4_um_t lineno,
+ dk4_um_t charno,
+ dk4_um_t charinline
+)
+{
+ if (NULL != erp) {
+ if (DK4_E_NONE == erp->ec) {
+ erp->ec = ec;
+ $? ". byteno = %lu", (unsigned long)byteno
+ $? ". lineno = %lu", (unsigned long)lineno
+ $? ". charno = %lu", (unsigned long)charno
+ $? ". charinline = %lu", (unsigned long)charinline
+ (erp->dt).fpos.byteno = byteno;
+ (erp->dt).fpos.lineno = lineno;
+ (erp->dt).fpos.charno = charno;
+ (erp->dt).fpos.charinline = charinline;
+ }
+ }
+}
+
+
+
+void
+dk4error_copy(dk4_er_t *dptr, const dk4_er_t *sptr)
+{
+ if ((NULL != dptr) && (NULL != sptr)) {
+ if (DK4_E_NONE == dptr->ec) {
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ CopyMemory(dptr, sptr, sizeof(dk4_er_t));
+#else
+ memcpy(dptr, sptr, sizeof(dk4_er_t));
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+#if DK4_HAVE_MEMCPY
+ memcpy(dptr, sptr, sizeof(dk4_er_t));
+#else
+#if DK4_HAVE_BCOPY
+ bcopy(sptr, dptr, sizeof(dk4_er_t));
+#else
+ register unsigned char *dp; /* Destination pointer */
+ register const unsigned char *sp; /* Source pointer */
+ register size_t xsz; /* Number remaining bytes */
+
+ dp = (unsigned char *)dptr;
+ sp = (const unsigned char *)sptr;
+ xsz = sizeof(dk4_er_t);
+ while(0 < xsz--) { *(dp++) = *(sp++); }
+#endif
+#endif
+ /* --- non-Windows */
+#endif
+ }
+ }
+}
+
diff --git a/support/dktools/dk4error.h b/support/dktools/dk4error.h
new file mode 100644
index 0000000000..cb64f2ab04
--- /dev/null
+++ b/support/dktools/dk4error.h
@@ -0,0 +1,547 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4error.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4ERROR_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4ERROR_H_INCLUDED 1
+
+
+#line 9 "dk4error.ctr"
+
+/** @file
+ Return error information from
+ called function to caller, more detailed than just an
+ error code.
+
+ In addition to the error code we can save details, i.e.
+ the errno or GetLastError() value or the element size
+ and number of elements for a failed memory allocation...
+ This allows the caller to produce detailed error messages
+ if necessary.
+
+ Before processing a code section where errors can occur,
+ use dk4error_init() to initialize an error structure.
+ A value indicating ``no error occured'' is set in the structure.
+
+ Depending on the errors occuring, the code section might use
+ one from the dk4error_set_...() functions.
+
+ At the end of the code section, check the error code in the
+ dk4_er_t structure.
+
+
+ The address of one dk4_er_t can be passed to several function
+ calls. Only the first error occured is noted in the structure,
+ it is not overwritten by later errors.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+
+
+/** Error report.
+*/
+typedef struct {
+ /** Details.
+ */
+ union {
+ /** Position within a file or data stream.
+ */
+ struct {
+ dk4_um_t byteno; /**< Byte number. */
+ dk4_um_t lineno; /**< Line number. */
+ dk4_um_t charno; /**< Character number. */
+ dk4_um_t charinline; /**< Character number within the line. */
+ } fpos;
+ /** Failed memory allocation.
+ */
+ struct {
+ size_t elsize; /**< Element size. */
+ size_t nelem; /**< Number of elements. */
+ } mem;
+ int iDetails1; /**< Integer details. */
+ long lDetails1; /**< Long details. */
+ } dt;
+ int ec; /**< Error code. */
+} dk4_er_t;
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Initialize error report.
+
+ CRT on Windows: Optional.
+ @param erp Error report to initialize.
+*/
+void
+dk4error_init(dk4_er_t *erp);
+
+/** Set simple error code.
+
+ CRT on Windows: Not used.
+ @param erp Error report to modify, may be NULL.
+ @param ec New error code.
+*/
+void
+dk4error_set_simple_error_code(dk4_er_t *erp, int ec);
+
+/** Set error code for dealing with a number of elements
+ (memory allocation).
+
+ CRT on Windows: Not used.
+ @param erp Error report to modify, may be NULL.
+ @param ec New error code to set.
+ @param sz Element size.
+ @param ne Number of elements.
+*/
+void
+dk4error_set_elsize_nelem(dk4_er_t *erp, int ec, size_t sz, size_t ne);
+
+/** Set error code for error from a system function, save
+ errno value in details.
+
+ CRT on Windows: Not used.
+ @param erp Error report to modify, may be NULL.
+ @param ec New error code to set.
+ @param errnval Value of errno, stored in iDetails1.
+*/
+void
+dk4error_set_idetails(dk4_er_t *erp, int ec, int errnval);
+
+/** Set long error code for error from a Windows system function,
+ save GetLastError() value in details.
+
+ CRT on Windows: Not used.
+ @param erp Error report to modify, may be NULL.
+ @param ec New error code to set.
+ @param errnval Value obtained from GetLastError().
+*/
+void
+dk4error_set_ldetails(dk4_er_t *erp, int ec, long errnval);
+
+/** Set error code and keep file or data stream position.
+
+ CRT on Windows: Not used.
+ @param erp Error report to modify, may be NULL.
+ @param ec New error code to set.
+ @param byteno Byte position in file.
+ @param lineno Current line number.
+ @param charno Character number in file.
+ @param charinline Character position in line.
+*/
+void
+dk4error_set_with_position(
+ dk4_er_t *erp,
+ int ec,
+ dk4_um_t byteno,
+ dk4_um_t lineno,
+ dk4_um_t charno,
+ dk4_um_t charinline
+);
+
+/** Copy error report if there was an error in the source report
+ and no error yet in the destination report.
+
+ CRT on Windows: Optional.
+ @param dptr Destination report.
+ @param sptr Source report.
+*/
+void
+dk4error_copy(dk4_er_t *dptr, const dk4_er_t *sptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+/** Error codes.
+*/
+enum {
+
+ /** No error occured.
+ */
+ DK4_E_NONE = 0,
+
+ /** System error, the errno value is saved to
+ det,syserr.
+ */
+ DK4_E_SYSTEM ,
+
+ /** Something failed although it should not.
+ */
+ DK4_E_BUG ,
+
+ /** Invalid arguments (in example NULL pointers,
+ 0 sizes) were passed to a function.
+ No details are reported.
+ */
+ DK4_E_INVALID_ARGUMENTS ,
+
+ /** A buffer was too small to take a text
+ completely.
+ */
+ DK4_E_BUFFER_TOO_SMALL ,
+
+ /** The requested information was not found.
+ */
+ DK4_E_NOT_FOUND ,
+
+ /** Memory allocation failed. Element size and
+ number of elements are stored in
+ dt,mem,elsize and dt,mem,nelem.
+ */
+ DK4_E_MEMORY_ALLOCATION_FAILED ,
+
+ /** Numeric overflow. For floating point numbers
+ the absolute value exceeded DBL_MAX.
+ For integer numbers the result is outside
+ the range MIN...MAX.
+ No details are reported.
+ */
+ DK4_E_MATH_OVERFLOW ,
+
+ /** Numeric underflow.
+ The underflow is reported if the absolute
+ value of a floating point operation is too
+ small.
+ For integer numbers only overflow is reported
+ even if the result is smaller than MIN.
+ No details are reported.
+ */
+ DK4_E_MATH_UNDERFLOW ,
+
+ /** Division by zero. No details are reported.
+ */
+ DK4_E_MATH_DIVZERO ,
+
+ /** An invalid argument was passed to a
+ mathematical function.
+ */
+ DK4_E_MATH_INVALID ,
+
+ /** Mathematical result is inexact, cutting bits.
+ */
+ DK4_E_MATH_INEXACT ,
+
+ /** Syntax error when processing text, illegal
+ character when decoding or encoding.
+ */
+ DK4_E_SYNTAX ,
+
+ /** Functionality not supported on this system.
+ */
+ DK4_E_NOT_SUPPORTED ,
+
+ /** A write operation failed.
+ */
+ DK4_E_WRITE_FAILED ,
+
+ /** A data flush operation failed.
+ */
+ DK4_E_FLUSH_FAILED ,
+
+ /** Failed to read data.
+ */
+ DK4_E_READ_FAILED ,
+ /** A file or other stream close operation failed.
+ */
+ DK4_E_CLOSE_FAILED ,
+
+ /** Additional security checks before opening a
+ file failed.
+ */
+ DK4_E_SEC_CHECK ,
+
+ /** Attempt to open a file failed.
+ */
+ DK4_E_OPEN_FAILED ,
+
+ /** Failed to open file for reading.
+ */
+ DK4_E_OPEN_READ_FAILED ,
+
+ /** Failed to open file for writing.
+ */
+ DK4_E_OPEN_WRITE_FAILED ,
+
+ /** Failed to encode 32 bit character to
+ output encoding.
+ */
+ DK4_E_ENCODING_FAILED ,
+
+ /** Failed to decode 32 bit character from
+ input encoding.
+ */
+ DK4_E_DECODING_FAILED ,
+
+ /** Failed to create a directory.
+ */
+ DK4_E_MKDIR_FAILED ,
+
+ /** Failed to change file or directory ownership.
+ */
+ DK4_E_CHOWN_FAILED ,
+
+ /** Failed to change file or directory permissions.
+ */
+ DK4_E_CHMOD_FAILED ,
+
+ /** Non-directory component in path name.
+ */
+ DK4_E_NON_DIR ,
+
+ /** File exists, but is not a socket.
+ */
+ DK4_E_NON_SOCKET ,
+
+ /** An unlink operation failed.
+ */
+ DK4_E_UNLINK_FAILED ,
+
+ /** The DeleteFile() function on Windows failed.
+ */
+ DK4_E_DELETE_FILE_FAILED ,
+
+ /** An rmdir operation failed.
+ */
+ DK4_E_RMDIR_FAILED ,
+
+ /** The RemoveDirectory() function failed
+ on Windows.
+ */
+ DK4_E_REMOVE_DIRECTORY_FAILED ,
+
+ /** Opendir failed.
+ */
+ DK4_E_OPENDIR_FAILED ,
+
+ /** The CreateFile() function failed on Windows.
+ The result of GetLastError() is stored
+ in dt.lDetails1.
+ */
+ DK4_E_CREATE_FILE_FAILED ,
+
+ /** The CreateDirectory() function failed on
+ Windows. The result of GetLastError() is
+ stored in dt.lDetails1.
+ */
+ DK4_E_CREATE_DIR_FAILED ,
+
+ /** The GetFileInformationByHandle() function
+ failed on Windows. The result of
+ GetLastError() is stored in dt.lDetails1.
+ */
+ DK4_E_FILE_INFORMATION_FAILED ,
+
+ /** The FindFirstFile() function on Windows failed.
+ The GetLastError() value is stored in lDetails1.
+ */
+ DK4_E_FINDFIRSTFILE_FAILED ,
+
+ /** Timeout occured in socket operation,
+ no details in iDetails1.
+ */
+ DK4_E_SOCKET_TIMEOUT ,
+
+ /** The getaddrinfo() function failed to
+ find the remote address.
+ The function result is stored in iDetails1.
+ */
+ DK4_E_SOCKET_GETADDRINFO ,
+
+ /** The getaddrinfo() function failed to
+ find the local address.
+ The function result is stored in iDetails1.
+ */
+ DK4_E_SOCKET_GETADDRLOC ,
+
+ /** Failed to start up Windows sockets.
+ The error code from WSAGetLastError() on
+ Windows / errno on non-Windows is stored
+ in iDetails1.
+ */
+ DK4_E_SOCKET_UP ,
+
+ /** Failed to shut down Windows sockets.
+ The error code from WSAGetLastError() on
+ Windows / errno on non-Windows is stored
+ in iDetails1.
+ */
+ DK4_E_SOCKET_DOWN ,
+
+ /** The socket() function failed.
+ The error code from WSAGetLastError() on
+ Windows / errno on non-Windows is stored
+ in iDetails1.
+ */
+ DK4_E_SOCKET_SOCKET ,
+
+ /** The close() or closesocket() function failed.
+ The error code from WSAGetLastError() on
+ Windows / errno on non-Windows is stored
+ in iDetails1.
+ */
+ DK4_E_SOCKET_CLOSE ,
+
+ /** The bind() function failed.
+ The error code from WSAGetLastError() on
+ Windows / errno on non-Windows is stored
+ in iDetails1.
+ */
+ DK4_E_SOCKET_BIND ,
+
+ /** The connect() function failed.
+ The error code from WSAGetLastError() on
+ Windows / errno on non-Windows is stored
+ in iDetails1.
+ */
+ DK4_E_SOCKET_CONNECT ,
+
+ /** The listen() function failed.
+ The error code from WSAGetLastError() on
+ Windows / errno on non-Windows is stored
+ in iDetails1.
+ */
+ DK4_E_SOCKET_LISTEN ,
+
+ /** The accept() function failed.
+ The error code from WSAGetLastError() on
+ Windows / errno on non-Windows is stored
+ in iDetails1.
+ */
+ DK4_E_SOCKET_ACCEPT ,
+
+ /** The select() function failed.
+ The error code from WSAGetLastError() on
+ Windows / errno on non-Windows is stored
+ in iDetails1.
+ */
+ DK4_E_SOCKET_SELECT ,
+
+ /** The setsockopt() function failed.
+ The error code from WSAGetLastError() on
+ Windows / errno on non-Windows is stored
+ in iDetails1.
+ */
+ DK4_E_SOCKET_SETSOCKOPT ,
+
+ /** The getsockopt() function failed.
+ The error code from WSAGetLastError() on
+ Windows / errno on non-Windows is stored
+ in iDetails1.
+ */
+ DK4_E_SOCKET_GETSOCKOPT ,
+
+ /** The shutdown() function failed.
+ The error code from WSAGetLastError() on
+ Windows / errno on non-Windows is stored
+ in iDetails1.
+ */
+ DK4_E_SOCKET_SHUTDOWN ,
+
+ /** The send()/sendto() function failed.
+ The error code from WSAGetLastError() on
+ Windows / errno on non-Windows is stored
+ in iDetails1.
+ */
+ DK4_E_SOCKET_SEND ,
+
+ /** The recv()/recvfrom() function failed.
+ The error code from WSAGetLastError() on
+ Windows / errno on non-Windows is stored
+ in iDetails1.
+ */
+ DK4_E_SOCKET_RECV ,
+
+ /** The ioctlsocket() function failed.
+ The error code from WSAGetLastError() on
+ Windows is stored in iDetails1.
+ On Windows only.
+ */
+ DK4_E_SOCKET_IOCTLSOCKET ,
+
+ /** The fcntl() function failed.
+ The error code from
+ errno on non-Windows is stored
+ in iDetails1.
+ Not on Windows systems (ioctlsocket
+ is used to switch between blocking
+ and non-blocking).
+ */
+ DK4_E_SOCKET_FCNTL ,
+
+ /** The getservbyname() function failed.
+ The error code from WSAGetLastError() on
+ Windows / errno on non-Windows is stored
+ in iDetails1.
+ */
+ DK4_E_SOCKET_GETSERVBYNAME ,
+
+ /** The gethostbyname() function failed.
+ The error code from WSAGetLastError() on
+ Windows / errno on non-Windows is stored
+ in iDetails1.
+ */
+ DK4_E_SOCKET_GETHOSTBYNAME ,
+
+ /** The inet_ntop() function failed.
+ The error code from WSAGetLastError() on
+ Windows / errno on non-Windows is stored
+ in iDetails1.
+ */
+ DK4_E_SOCKET_INET_NTOP ,
+
+ /** The inet_pton() function failed.
+ The error code from WSAGetLastError() on
+ Windows / errno on non-Windows is stored
+ in iDetails1.
+ */
+ DK4_E_SOCKET_INET_PTON ,
+};
+
+
+
+
+#endif
diff --git a/support/dktools/dk4exep.c b/support/dktools/dk4exep.c
new file mode 100644
index 0000000000..32293f0d85
--- /dev/null
+++ b/support/dktools/dk4exep.c
@@ -0,0 +1,58 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4exep.ctr
+*/
+
+/*
+Copyright (C) 2014, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4exep.c The dk4exep module.
+*/
+
+
+#line 43 "dk4exep.ctr"
+
+#include "dk4exep.h"
+#if DK4_CHAR_SIZE > 1
+#include "dk4exepw.h"
+#else
+#include "dk4exep8.h"
+#endif
+
+int
+dk4execpath(dkChar *buffer, size_t sz, const dkChar *argv0, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4execpath_wc(buffer, sz, argv0, erp));
+#else
+ return (dk4execpath_c8(buffer, sz, argv0, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4exep8.c b/support/dktools/dk4exep8.c
new file mode 100644
index 0000000000..e4368a621d
--- /dev/null
+++ b/support/dktools/dk4exep8.c
@@ -0,0 +1,381 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4exep8.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4exep8.c The dk4exep8 module.
+*/
+
+
+#line 57 "dk4exep8.ctr"
+
+#include "dk4exep8.h"
+
+#ifndef DK4STR8_H_INCLUDED
+#include "dk4str8.h"
+#endif
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4PATH8_H_INCLUDED
+#include "dk4path8.h"
+#endif
+
+#ifndef DK4STAT8_H_INCLUDED
+#include "dk4stat8.h"
+#endif
+
+#ifndef DK4STAT_H_INCLUDED
+#include "dk4stat.h"
+#endif
+
+#ifndef DK4MAO8D_H_INCLUDED
+#include "dk4mao8d.h"
+#endif
+
+#ifndef DK4MPL_H_INCLUDED
+#include "dk4mpl.h"
+#endif
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#ifndef WINBASE_H_INCLUDED
+#include <winbase.h>
+#define WINBASE_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_STAT_H
+#ifndef SYS_STAT_H_INCLUDED
+#include <sys/stat.h>
+#define SYS_STAT_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+
+
+
+
+#line 142 "dk4exep8.ctr"
+
+
+
+static const char * const dk4execpath_c8_kw[] = {
+/* 0 */ "PATH",
+#if DK4_HAVE_BACKSLASH_AS_SEP
+/* 1 */ "\\",
+#else
+/* 1 */ "/",
+#endif
+NULL
+};
+
+
+
+#if !DK4_ON_WINDOWS
+
+/** Retrieve name of executable file by PATH environment variable
+ inspection.
+ @param buffer Buffer to store result.
+ @param sz Size of buffer.
+ @param argv0 First command line word.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4execpath_c8_inspect_path(
+ char *buffer, size_t sz, const char * argv0, dk4_er_t *erp
+)
+{
+ dk4_stat_t stbuf;
+ char *envpath;
+ char *mycopy;
+ char *p1;
+ char *p2;
+ int back = 0;
+ int cc = 1;
+
+ envpath = getenv(dk4execpath_c8_kw[0]);
+ if (NULL != envpath) {
+ mycopy = dk4str8_dup(envpath, erp);
+ if (NULL != mycopy) {
+ p1 = mycopy;
+ while ((NULL != p1) && (0 != cc) && (0 == back)) {
+ p2 = dk4str8_chr(p1, ':');
+ if (NULL != p2) { *(p2++) = '\0'; }
+ if (0 != dk4str8_cpy_s(buffer, sz, p1, erp)) {
+ if (0 != dk4str8_cat_s(buffer, sz, dk4execpath_c8_kw[1], erp)) {
+ if (0 != dk4str8_cat_s(buffer, sz, argv0, erp)) {
+ if (0 != dk4stat_c8(&stbuf, buffer, NULL)) {
+ if (0 != dk4stat_is_regular(&stbuf, NULL)) {
+ back = 1;
+ }
+ } else {
+
+#line 197 "dk4exep8.ctr"
+ }
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = 0;
+ }
+ p1 = p2;
+ }
+ dk4mem_free(mycopy);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ return back;
+}
+
+#endif
+
+
+
+#if !DK4_ON_WINDOWS
+#if DK4_HAVE_PROC_PID_EXE
+static const char * const dk4exep8_kw[] = {
+/* 0 */ "/proc/",
+/* 1 */ "/exe"
+};
+#endif
+#endif
+
+
+#if DK4_ON_WINDOWS
+#pragma warning (disable:4100)
+#endif
+
+int
+dk4execpath_c8(char *buffer, size_t sz, const char *argv0, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ DWORD res;
+ DWORD dwsz;
+#else
+#if DK4_HAVE_GETEXECNAME
+ char cwd[DK4_MAX_PATH];
+ const char *enptr;
+#endif
+#if DK4_HAVE_PROC_PID_EXE
+ char numbuf[64];
+ char fnbuf[sizeof(numbuf)+11];
+ ssize_t rlres;
+ int res;
+#endif
+#endif
+ int back = 0;
+
+
+#line 255 "dk4exep8.ctr"
+ if ((NULL != buffer) && (0 < sz)) {
+#if DK4_ON_WINDOWS
+ if ((dk4_um_t)0xFFFFFFFFUL >= (dk4_um_t)sz) {
+ dwsz = (DWORD)sz;
+ } else {
+ dwsz = 0xFFFFFFFFUL;
+ }
+ res = GetModuleFileNameA(GetModuleHandle(NULL), buffer, dwsz);
+ if (0 < res) {
+ if ((dk4_um_t)res < (dk4_um_t)sz) {
+ buffer[res] = '\0';
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ /* ERROR: Failed to find executable file name */
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+#else
+#if DK4_HAVE_GETEXECNAME
+
+
+#line 277 "dk4exep8.ctr"
+
+#if 0
+ /* Prototype is const char *getexecname(void);
+ */
+ if (0 == getexecname(buffer, sz)) {
+ back = 1;
+
+#line 283 "dk4exep8.ctr"
+ }
+#endif
+
+ enptr = getexecname();
+ if (NULL != enptr) {
+ if ('/' == *enptr) {
+ if (strlen(enptr) < sz) {
+ strcpy(buffer, enptr);
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ errno = 0;
+ if (NULL != getcwd(cwd, sizeof(cwd))) {
+ if ((strlen(cwd) + strlen(dk4execpath_c8_kw[1]) + strlen(enptr)) < sz)
+ {
+ strcpy(buffer, cwd);
+ strcat(buffer, dk4execpath_c8_kw[1]);
+ strcat(buffer, enptr);
+ back = 1;
+ }
+ else
+ {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ /* ERROR: Current directory not found */
+ dk4error_set_idetails(erp, DK4_E_SYSTEM, errno);
+ }
+ }
+ }
+#endif
+#if DK4_HAVE_PROC_PID_EXE
+ if (0 == back) {
+
+#line 318 "dk4exep8.ctr"
+ res = dk4ma_write_c8_decimal_unsigned(
+ numbuf, sizeof(numbuf), (dk4_um_t)getpid(), 0, NULL
+ );
+ if (0 != res) {
+
+#line 322 "dk4exep8.ctr"
+ if (0 != dk4str8_cpy_s(fnbuf, sizeof(fnbuf), dk4exep8_kw[0], NULL)) {
+
+
+#line 324 "dk4exep8.ctr"
+ if (0 != dk4str8_cat_s(fnbuf, sizeof(fnbuf), numbuf, NULL)) {
+
+
+#line 326 "dk4exep8.ctr"
+ if (0 != dk4str8_cat_s(fnbuf,sizeof(fnbuf),dk4exep8_kw[1],NULL)) {
+
+
+#line 328 "dk4exep8.ctr"
+ rlres = readlink(fnbuf, buffer, sz);
+
+
+#line 330 "dk4exep8.ctr"
+ if (0 < rlres) {
+
+#line 331 "dk4exep8.ctr"
+ if (rlres < sz) {
+
+#line 332 "dk4exep8.ctr"
+ buffer[rlres] = '\0';
+
+#line 333 "dk4exep8.ctr"
+ back = 1;
+
+#line 334 "dk4exep8.ctr"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+#endif
+ if (0 == back) {
+
+#line 343 "dk4exep8.ctr"
+ if (NULL != argv0) {
+ back = dk4execpath_c8_inspect_path(buffer, sz, argv0, erp);
+ if (0 != back) {
+
+#line 346 "dk4exep8.ctr"
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ }
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 355 "dk4exep8.ctr"
+ return back;
+}
+
+#if DK4_ON_WINDOWS
+#pragma warning (default:4100)
+#endif
+
diff --git a/support/dktools/dk4exep8.ctr b/support/dktools/dk4exep8.ctr
new file mode 100644
index 0000000000..067e0c1e1a
--- /dev/null
+++ b/support/dktools/dk4exep8.ctr
@@ -0,0 +1,361 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Find name of executed file.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve path to executable file.
+ CRT on Windows: Not used.
+ @param buffer Buffer to store the file name.
+ @param sz Buffer size.
+ @param argv0 First command line word.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if buffer is NULL or sz is 0,
+ - DK4_E_NOT_FOUND<br>
+ if the system function(s) failed to find the name,
+ - DK4_E_SYSTEM<br>
+ if the function failed to find the current working directory,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the buffer is too small to hold the file name.
+*/
+int
+dk4execpath_c8(char *buffer, size_t sz, const char *argv0, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4exep8.h"
+
+#ifndef DK4STR8_H_INCLUDED
+#include "dk4str8.h"
+#endif
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4PATH8_H_INCLUDED
+#include "dk4path8.h"
+#endif
+
+#ifndef DK4STAT8_H_INCLUDED
+#include "dk4stat8.h"
+#endif
+
+#ifndef DK4STAT_H_INCLUDED
+#include "dk4stat.h"
+#endif
+
+#ifndef DK4MAO8D_H_INCLUDED
+#include "dk4mao8d.h"
+#endif
+
+#ifndef DK4MPL_H_INCLUDED
+#include "dk4mpl.h"
+#endif
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#ifndef WINBASE_H_INCLUDED
+#include <winbase.h>
+#define WINBASE_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_STAT_H
+#ifndef SYS_STAT_H_INCLUDED
+#include <sys/stat.h>
+#define SYS_STAT_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+
+
+$!trace-include
+
+
+
+static const char * const dk4execpath_c8_kw[] = {
+/* 0 */ "PATH",
+#if DK4_HAVE_BACKSLASH_AS_SEP
+/* 1 */ "\\",
+#else
+/* 1 */ "/",
+#endif
+NULL
+};
+
+
+
+#if !DK4_ON_WINDOWS
+
+/** Retrieve name of executable file by PATH environment variable
+ inspection.
+ @param buffer Buffer to store result.
+ @param sz Size of buffer.
+ @param argv0 First command line word.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4execpath_c8_inspect_path(
+ char *buffer, size_t sz, const char * argv0, dk4_er_t *erp
+)
+{
+ dk4_stat_t stbuf;
+ char *envpath;
+ char *mycopy;
+ char *p1;
+ char *p2;
+ int back = 0;
+ int cc = 1;
+
+ envpath = getenv(dk4execpath_c8_kw[0]);
+ if (NULL != envpath) {
+ mycopy = dk4str8_dup(envpath, erp);
+ if (NULL != mycopy) {
+ p1 = mycopy;
+ while ((NULL != p1) && (0 != cc) && (0 == back)) {
+ p2 = dk4str8_chr(p1, ':');
+ if (NULL != p2) { *(p2++) = '\0'; }
+ if (0 != dk4str8_cpy_s(buffer, sz, p1, erp)) {
+ if (0 != dk4str8_cat_s(buffer, sz, dk4execpath_c8_kw[1], erp)) {
+ if (0 != dk4str8_cat_s(buffer, sz, argv0, erp)) {
+ if (0 != dk4stat_c8(&stbuf, buffer, NULL)) {
+ if (0 != dk4stat_is_regular(&stbuf, NULL)) {
+ back = 1;
+ }
+ } else { $? "! no such file"
+ }
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = 0;
+ }
+ p1 = p2;
+ }
+ dk4mem_free(mycopy);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ return back;
+}
+
+#endif
+
+
+
+#if !DK4_ON_WINDOWS
+#if DK4_HAVE_PROC_PID_EXE
+static const char * const dk4exep8_kw[] = {
+/* 0 */ "/proc/",
+/* 1 */ "/exe"
+};
+#endif
+#endif
+
+
+#if DK4_ON_WINDOWS
+#pragma warning (disable:4100)
+#endif
+
+int
+dk4execpath_c8(char *buffer, size_t sz, const char *argv0, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ DWORD res;
+ DWORD dwsz;
+#else
+#if DK4_HAVE_GETEXECNAME
+ char cwd[DK4_MAX_PATH];
+ const char *enptr;
+#endif
+#if DK4_HAVE_PROC_PID_EXE
+ char numbuf[64];
+ char fnbuf[sizeof(numbuf)+11];
+ ssize_t rlres;
+ int res;
+#endif
+#endif
+ int back = 0;
+ $? "+ dk4execpath_c8"
+ if ((NULL != buffer) && (0 < sz)) {
+#if DK4_ON_WINDOWS
+ if ((dk4_um_t)0xFFFFFFFFUL >= (dk4_um_t)sz) {
+ dwsz = (DWORD)sz;
+ } else {
+ dwsz = 0xFFFFFFFFUL;
+ }
+ res = GetModuleFileNameA(GetModuleHandle(NULL), buffer, dwsz);
+ if (0 < res) {
+ if ((dk4_um_t)res < (dk4_um_t)sz) {
+ buffer[res] = '\0';
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ /* ERROR: Failed to find executable file name */
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+#else
+#if DK4_HAVE_GETEXECNAME
+ $? ". attempt getexecname"
+
+#if 0
+ /* Prototype is const char *getexecname(void);
+ */
+ if (0 == getexecname(buffer, sz)) {
+ back = 1; $? ". ok getexecname"
+ }
+#endif
+
+ enptr = getexecname();
+ if (NULL != enptr) {
+ if ('/' == *enptr) {
+ if (strlen(enptr) < sz) {
+ strcpy(buffer, enptr);
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ errno = 0;
+ if (NULL != getcwd(cwd, sizeof(cwd))) {
+ if ((strlen(cwd) + strlen(dk4execpath_c8_kw[1]) + strlen(enptr)) < sz)
+ {
+ strcpy(buffer, cwd);
+ strcat(buffer, dk4execpath_c8_kw[1]);
+ strcat(buffer, enptr);
+ back = 1;
+ }
+ else
+ {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ /* ERROR: Current directory not found */
+ dk4error_set_idetails(erp, DK4_E_SYSTEM, errno);
+ }
+ }
+ }
+#endif
+#if DK4_HAVE_PROC_PID_EXE
+ if (0 == back) { $? ". inspect /proc/pid/exe"
+ res = dk4ma_write_c8_decimal_unsigned(
+ numbuf, sizeof(numbuf), (dk4_um_t)getpid(), 0, NULL
+ );
+ if (0 != res) { $? ". number"
+ if (0 != dk4str8_cpy_s(fnbuf, sizeof(fnbuf), dk4exep8_kw[0], NULL)) {
+ $? ". cpy ok"
+ if (0 != dk4str8_cat_s(fnbuf, sizeof(fnbuf), numbuf, NULL)) {
+ $? ". cat ok"
+ if (0 != dk4str8_cat_s(fnbuf,sizeof(fnbuf),dk4exep8_kw[1],NULL)) {
+ $? ". cat ok \"%!8s\"", fnbuf
+ rlres = readlink(fnbuf, buffer, sz);
+ $? ". readlink -> %d", (int)rlres
+ if (0 < rlres) { $? ". readlink ok"
+ if (rlres < sz) { $? ". path size ok"
+ buffer[rlres] = '\0'; $? ". ok /proc/pid/exe"
+ back = 1; $? ". file \"%!8s\"", buffer
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+#endif
+ if (0 == back) { $? ". inspect PATH"
+ if (NULL != argv0) {
+ back = dk4execpath_c8_inspect_path(buffer, sz, argv0, erp);
+ if (0 != back) { $? ". ok PATH"
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ }
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4execpath_c8 %d", back
+ return back;
+}
+
+#if DK4_ON_WINDOWS
+#pragma warning (default:4100)
+#endif
+
diff --git a/support/dktools/dk4exep8.h b/support/dktools/dk4exep8.h
new file mode 100644
index 0000000000..d5cb72c395
--- /dev/null
+++ b/support/dktools/dk4exep8.h
@@ -0,0 +1,89 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4exep8.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4EXEP8_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4EXEP8_H_INCLUDED 1
+
+
+#line 10 "dk4exep8.ctr"
+
+/** @file
+ Find name of executed file.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve path to executable file.
+ CRT on Windows: Not used.
+ @param buffer Buffer to store the file name.
+ @param sz Buffer size.
+ @param argv0 First command line word.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if buffer is NULL or sz is 0,
+ - DK4_E_NOT_FOUND<br>
+ if the system function(s) failed to find the name,
+ - DK4_E_SYSTEM<br>
+ if the function failed to find the current working directory,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the buffer is too small to hold the file name.
+*/
+int
+dk4execpath_c8(char *buffer, size_t sz, const char *argv0, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4exepd.c b/support/dktools/dk4exepd.c
new file mode 100644
index 0000000000..72d35e801e
--- /dev/null
+++ b/support/dktools/dk4exepd.c
@@ -0,0 +1,58 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4exepd.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4exepd.c The dk4exepd module.
+*/
+
+
+#line 48 "dk4exepd.ctr"
+
+#include "dk4exepd.h"
+#if DK4_CHAR_SIZE > 1
+#include "dk4exepw.h"
+#else
+#include "dk4exep8.h"
+#endif
+
+int
+dk4execpath(dkChar *buffer, size_t sz, const dkChar *argv0, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4execpath_wc(buffer, sz, argv0, erp));
+#else
+ return (dk4execpath_c8(buffer, sz, argv0, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4exepd.ctr b/support/dktools/dk4exepd.ctr
new file mode 100644
index 0000000000..793df856b6
--- /dev/null
+++ b/support/dktools/dk4exepd.ctr
@@ -0,0 +1,65 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Find name of executed file.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve path to executable file.
+ CRT on Windows: Not used.
+ @param buffer Buffer to store the file name.
+ @param sz Buffer size.
+ @param argv0 First command line word.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4execpath(dkChar *buffer, size_t sz, const dkChar *argv0, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4exepd.h"
+#if DK4_CHAR_SIZE > 1
+#include "dk4exepw.h"
+#else
+#include "dk4exep8.h"
+#endif
+
+int
+dk4execpath(dkChar *buffer, size_t sz, const dkChar *argv0, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4execpath_wc(buffer, sz, argv0, erp));
+#else
+ return (dk4execpath_c8(buffer, sz, argv0, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4exepd.h b/support/dktools/dk4exepd.h
new file mode 100644
index 0000000000..d2edac04e6
--- /dev/null
+++ b/support/dktools/dk4exepd.h
@@ -0,0 +1,80 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4exepd.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4EXEPD_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4EXEPD_H_INCLUDED 1
+
+
+#line 10 "dk4exepd.ctr"
+
+/** @file
+ Find name of executed file.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve path to executable file.
+ CRT on Windows: Not used.
+ @param buffer Buffer to store the file name.
+ @param sz Buffer size.
+ @param argv0 First command line word.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4execpath(dkChar *buffer, size_t sz, const dkChar *argv0, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4exepw.c b/support/dktools/dk4exepw.c
new file mode 100644
index 0000000000..9d73eac997
--- /dev/null
+++ b/support/dktools/dk4exepw.c
@@ -0,0 +1,190 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4exepw.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4exepw.c The dk4exepw module.
+*/
+
+
+#line 54 "dk4exepw.ctr"
+
+#include "dk4exepw.h"
+
+#ifndef DK4STRW_H_INCLUDED
+#include "dk4strw.h"
+#endif
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4PATHW_H_INCLUDED
+#include "dk4pathw.h"
+#endif
+
+#ifndef DK4STATW_H_INCLUDED
+#include "dk4statw.h"
+#endif
+
+#ifndef DK4STAT_H_INCLUDED
+#include "dk4stat.h"
+#endif
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#ifndef WINBASE_H_INCLUDED
+#include <winbase.h>
+#define WINBASE_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_STAT_H
+#ifndef SYS_STAT_H_INCLUDED
+#include <sys/stat.h>
+#define SYS_STAT_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+
+
+
+
+#line 124 "dk4exepw.ctr"
+
+
+
+#if 0
+static const wchar_t * const dk4execpath_wc_kw[] = {
+/* 0 */ L"PATH",
+#if DK4_HAVE_BACKSLASH_AS_SEP
+/* 1 */ L"\\",
+#else
+/* 1 */ L"/",
+#endif
+NULL
+};
+#endif
+
+
+
+#if DK4_ON_WINDOWS
+#pragma warning (disable:4100)
+#endif
+
+int
+dk4execpath_wc(wchar_t *buffer, size_t sz, const wchar_t *argv0, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ DWORD res;
+ DWORD dwsz;
+#endif
+ int back = 0;
+#if DK4_ON_WINDOWS
+
+
+#line 155 "dk4exepw.ctr"
+ if ((NULL != buffer) && (0 < sz)) {
+ if ((dk4_um_t)0xFFFFFFFFUL >= (dk4_um_t)sz) {
+ dwsz = (DWORD)sz;
+ } else {
+ dwsz = (DWORD)0xFFFFFFFFUL;
+ }
+ res = GetModuleFileNameW(GetModuleHandle(NULL), buffer, dwsz);
+ if (0 < res) {
+ if ((dk4_um_t)res < (dk4_um_t)sz) {
+ back = 1;
+
+#line 165 "dk4exepw.ctr"
+ buffer[res] = L'\0';
+ } else {
+
+#line 167 "dk4exepw.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+
+#line 170 "dk4exepw.ctr"
+ /* ERROR: Not found */
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+
+#line 174 "dk4exepw.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+#else
+
+
+#line 178 "dk4exepw.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+
+
+#line 181 "dk4exepw.ctr"
+ return back;
+}
+
+#if DK4_ON_WINDOWS
+#pragma warning (default:4100)
+#endif
+
diff --git a/support/dktools/dk4exepw.ctr b/support/dktools/dk4exepw.ctr
new file mode 100644
index 0000000000..fab30cc3ca
--- /dev/null
+++ b/support/dktools/dk4exepw.ctr
@@ -0,0 +1,187 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Find name of executed file.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_HAVE_WCHAR_H
+#ifndef WCHAR_H_INCLUDED
+#include <wchar.h>
+#define WCHAR_H_INCLUDED 1
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve path to executable file.
+ CRT on Windows: Not used.
+ @param buffer Buffer to store the file name.
+ @param sz Buffer size (number of wchar_t).
+ @param argv0 First command line word.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4execpath_wc(wchar_t *buffer, size_t sz, const wchar_t *argv0, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4exepw.h"
+
+#ifndef DK4STRW_H_INCLUDED
+#include "dk4strw.h"
+#endif
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4PATHW_H_INCLUDED
+#include "dk4pathw.h"
+#endif
+
+#ifndef DK4STATW_H_INCLUDED
+#include "dk4statw.h"
+#endif
+
+#ifndef DK4STAT_H_INCLUDED
+#include "dk4stat.h"
+#endif
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#ifndef WINBASE_H_INCLUDED
+#include <winbase.h>
+#define WINBASE_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_STAT_H
+#ifndef SYS_STAT_H_INCLUDED
+#include <sys/stat.h>
+#define SYS_STAT_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+
+
+$!trace-include
+
+
+
+#if 0
+static const wchar_t * const dk4execpath_wc_kw[] = {
+/* 0 */ L"PATH",
+#if DK4_HAVE_BACKSLASH_AS_SEP
+/* 1 */ L"\\",
+#else
+/* 1 */ L"/",
+#endif
+NULL
+};
+#endif
+
+
+
+#if DK4_ON_WINDOWS
+#pragma warning (disable:4100)
+#endif
+
+int
+dk4execpath_wc(wchar_t *buffer, size_t sz, const wchar_t *argv0, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ DWORD res;
+ DWORD dwsz;
+#endif
+ int back = 0;
+#if DK4_ON_WINDOWS
+ $? "+ dk4execpath_wc"
+ if ((NULL != buffer) && (0 < sz)) {
+ if ((dk4_um_t)0xFFFFFFFFUL >= (dk4_um_t)sz) {
+ dwsz = (DWORD)sz;
+ } else {
+ dwsz = (DWORD)0xFFFFFFFFUL;
+ }
+ res = GetModuleFileNameW(GetModuleHandle(NULL), buffer, dwsz);
+ if (0 < res) {
+ if ((dk4_um_t)res < (dk4_um_t)sz) {
+ back = 1; $? ". success"
+ buffer[res] = L'\0';
+ } else { $? "! buffer too small"
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else { $? "! GetModuleFileNameW"
+ /* ERROR: Not found */
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else { $? "! invalid arguments"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+#else
+ $? "! not supported"
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ $? "- dk4execpath_wc %d", back
+ return back;
+}
+
+#if DK4_ON_WINDOWS
+#pragma warning (default:4100)
+#endif
+
diff --git a/support/dktools/dk4exepw.h b/support/dktools/dk4exepw.h
new file mode 100644
index 0000000000..8f6848c03b
--- /dev/null
+++ b/support/dktools/dk4exepw.h
@@ -0,0 +1,86 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4exepw.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4EXEPW_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4EXEPW_H_INCLUDED 1
+
+
+#line 10 "dk4exepw.ctr"
+
+/** @file
+ Find name of executed file.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_HAVE_WCHAR_H
+#ifndef WCHAR_H_INCLUDED
+#include <wchar.h>
+#define WCHAR_H_INCLUDED 1
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve path to executable file.
+ CRT on Windows: Not used.
+ @param buffer Buffer to store the file name.
+ @param sz Buffer size (number of wchar_t).
+ @param argv0 First command line word.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4execpath_wc(wchar_t *buffer, size_t sz, const wchar_t *argv0, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4fd.c b/support/dktools/dk4fd.c
new file mode 100644
index 0000000000..8e3d168fb8
--- /dev/null
+++ b/support/dktools/dk4fd.c
@@ -0,0 +1,313 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fd.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4fd.c The dk4fd module.
+*/
+
+
+#line 260 "dk4fd.ctr"
+
+
+#include "dk4fd.h"
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SHARE_H
+#ifndef SHARE_H_INCLUDED
+#include <share.h>
+#define SHARE_H_INCLUDED 1
+#endif
+#endif
+
+
+
+
+#line 287 "dk4fd.ctr"
+
+
+
+int
+dk4fd_c8_open(const char *path, int flags, dk4_er_t *erp)
+{
+ int back = -1;
+ if (NULL != path) {
+#if DK4_ON_WINDOWS
+#if _MSC_VER >= 1700
+ int res;
+ if (0 != (res = _sopen_s(&back,path,flags,_SH_DENYNO,(_S_IREAD|_S_IWRITE))))
+ {
+ if (-1 != back) {
+ _close(back);
+ back = -1;
+ }
+ dk4error_set_idetails(erp, DK4_E_OPEN_FAILED, res);
+ }
+#else
+ errno = 0;
+ back = _open(path, flags, (_S_IREAD | _S_IWRITE));
+ if (-1 == back) {
+ dk4error_set_idetails(erp, DK4_E_OPEN_FAILED, errno);
+ }
+#endif
+#else
+ errno = 0;
+ back = open(path, flags, 0600);
+ if (-1 == back) {
+ dk4error_set_idetails(erp, DK4_E_OPEN_FAILED, errno);
+ }
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4fd_wc_open(const wchar_t *path, int flags, dk4_er_t *erp)
+{
+ int back = -1;
+ if (NULL != path) {
+#if DK4_ON_WINDOWS
+#if _MSC_VER >= 1700
+ int res;
+ if (0 != (res=_wsopen_s(&back,path,flags,_SH_DENYNO,(_S_IREAD|_S_IWRITE))))
+ {
+ if (-1 != back) {
+ _close(back);
+ back = -1;
+ }
+ dk4error_set_idetails(erp, DK4_E_OPEN_FAILED, res);
+ }
+#else
+ errno = 0;
+ back = _wopen(path, flags, (_S_IREAD | _S_IWRITE));
+ if (-1 == back) {
+ dk4error_set_idetails(erp, DK4_E_OPEN_FAILED, errno);
+ }
+#endif
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4fd_open(const dkChar *path, int flags, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4fd_wc_open(path, flags, erp));
+#else
+ return (dk4fd_c8_open(path, flags, erp));
+#endif
+}
+
+
+
+int
+dk4fd_close(int fd, dk4_er_t *erp)
+{
+ int back = 0;
+#if DK4_ON_WINDOWS
+ errno = 0;
+ if (0 == _close(fd)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_CLOSE_FAILED, errno);
+ }
+#else
+ errno = 0;
+ if (0 == close(fd)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_CLOSE_FAILED, errno);
+ }
+#endif
+ return back;
+}
+
+
+
+#if !DK4_ON_WINDOWS
+#ifndef SSIZE_MAX
+/** Maximum value for ssize_t.
+*/
+#define SSIZE_MAX ((SIZE_MAX) / 2U)
+#endif
+#endif
+
+
+
+int
+dk4fd_write(int fd, const void *buffer, size_t sz, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ int back = 0;
+ int res;
+ if ((NULL != buffer) && (0 < sz)) {
+ if ((dk4_um_t)INT_MAX >= (dk4_um_t)sz) {
+ errno = 0;
+ res = _write(fd, buffer, (unsigned)sz);
+ if ((unsigned)res == (unsigned)sz) {
+ back = 1;
+ } else {
+ if (0 <= res) {
+ dk4error_set_elsize_nelem(erp, DK4_E_WRITE_FAILED, 1, (size_t)res);
+ } else {
+ dk4error_set_elsize_nelem(erp, DK4_E_WRITE_FAILED, 1, 0);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ ssize_t res;
+ int back = 0;
+ if ((NULL != buffer) && (0 < sz)) {
+ if ((dk4_um_t)SSIZE_MAX >= (dk4_um_t)sz) {
+ errno = 0;
+ res = write(fd, buffer, sz);
+ if ((size_t)res == sz) {
+ back = 1;
+ } else {
+ if (0 <= res) {
+ dk4error_set_elsize_nelem(erp, DK4_E_WRITE_FAILED, 1, res);
+ } else {
+ dk4error_set_elsize_nelem(erp, DK4_E_WRITE_FAILED, 1, 0);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#endif
+}
+
+
+
+int
+dk4fd_read(int fd, void *buffer, size_t *psz, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ int res = 0; /* Result from read operation */
+ int back = 0;
+ if ((NULL != buffer) && (NULL != psz)) {
+ if (0 < *psz) {
+ if ((dk4_um_t)INT_MAX >= (dk4_um_t)(*psz)) {
+ errno = 0;
+ res = _read(fd, buffer, (unsigned)(*psz));
+ if (0 < res) {
+ back = 1;
+ *psz = (size_t)res;
+ } else {
+ if (0 > res) {
+ back = 0;
+ *psz = 0;
+ dk4error_set_idetails(erp, DK4_E_READ_FAILED, errno);
+ } else {
+ back = 1;
+ *psz = 0;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ int back = 0;
+ ssize_t res;
+ if ((NULL != buffer) && (NULL != psz)) {
+ if (0 < *psz) {
+ if ((dk4_um_t)SSIZE_MAX >= (dk4_um_t)(*psz)) {
+ errno = 0;
+ res = read(fd, buffer, *psz);
+ if (0 < res) {
+ back = 1;
+ *psz = (size_t)res;
+ } else {
+ if (0 > res) {
+ back = 0;
+ *psz = 0;
+ dk4error_set_idetails(erp, DK4_E_READ_FAILED, errno);
+ } else {
+ back = 1;
+ *psz = 0;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#endif
+}
+
+
diff --git a/support/dktools/dk4fd.ctr b/support/dktools/dk4fd.ctr
new file mode 100644
index 0000000000..1ba43ae7bb
--- /dev/null
+++ b/support/dktools/dk4fd.ctr
@@ -0,0 +1,530 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ File descriptors, open and close a file, read and write.
+
+ Portable use of file descriptor.
+
+ CRT on Windows: Required.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_STAT_H
+#ifndef SYS_STAT_H_INCLUDED
+#include <sys/stat.h>
+#define SYS_STAT_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_WCHAR_H
+#ifndef WCHAR_H_INCLUDED
+#include <wchar.h>
+#define WCHAR_H_INCLUDED 1
+#endif
+#endif
+
+
+
+#if DK4_ON_WINDOWS
+/** File open flags.
+*/
+enum {
+ /** Read only access.
+ */
+ DK4_O_RDONLY = _O_RDONLY,
+
+ /** Write only access.
+ */
+ DK4_O_WRONLY = _O_WRONLY,
+
+ /** Read and write access.
+ */
+ DK4_O_RDWR = _O_RDWR,
+
+ /** Create file if it does
+ not yet exist.
+ */
+ DK4_O_CREAT = _O_CREAT,
+
+ /** Combined with DK4_O_CREAT,
+ create error if file already
+ exists.
+ */
+ DK4_O_EXCL = _O_EXCL,
+
+ /** Truncate existing file.
+ */
+ DK4_O_TRUNC = _O_TRUNC,
+
+ /** Append to existing file.
+ */
+ DK4_O_APPEND = _O_APPEND,
+
+ /** Open file in binary mode.
+ */
+ DK4_O_BINARY = _O_BINARY,
+};
+#else
+/** File open flags.
+*/
+enum {
+ /** Read only access.
+ */
+ DK4_O_RDONLY = O_RDONLY,
+
+ /** Write only access.
+ */
+ DK4_O_WRONLY = O_WRONLY,
+
+ /** Read and write access.
+ */
+ DK4_O_RDWR = O_RDWR,
+
+ /** Create file if it does
+ not yet exist.
+ */
+ DK4_O_CREAT = O_CREAT,
+
+ /** Combined with DK4_O_CREAT,
+ create error if file already
+ exists.
+ */
+ DK4_O_EXCL = O_EXCL,
+
+ /** Truncate existing file.
+ */
+ DK4_O_TRUNC = O_TRUNC,
+
+ /** Append to existing file.
+ */
+ DK4_O_APPEND = O_APPEND,
+
+ /** Open file in binary mode.
+ */
+ DK4_O_BINARY = 0,
+};
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open a file, return file descriptor.
+ @param path File name.
+ @param flags Flags how to open the file.
+ @param erp Error report, may be NULL.
+ @return Non-negative file descriptor on success, -1 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if path is NULL,
+ - DK4_E_OPEN_FAILED<br>
+ with iDetails set to errno value if the open() function indicated
+ an error.
+*/
+int
+dk4fd_c8_open(const char *path, int flags, dk4_er_t *erp);
+
+/** Open a file, return file descriptor.
+ @param path File name.
+ @param flags Flags how to open the file.
+ @param erp Error report, may be NULL.
+ @return Non-negative file descriptor on success, -1 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ if there is no function available to open files by wchar_t file name,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if path is NULL,
+ - DK4_E_OPEN_FAILED<br>
+ with iDetails set to errno value if the open() function indicated
+ an error.
+*/
+int
+dk4fd_wc_open(const wchar_t *path, int flags, dk4_er_t *erp);
+
+/** Open a file, return file descriptor.
+ @param path File name.
+ @param flags Flags how to open the file.
+ @param erp Error report, may be NULL.
+ @return Non-negative file descriptor on success, -1 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ if there is no function available to open files by wchar_t file name,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if path is NULL,
+ - DK4_E_OPEN_FAILED<br>
+ with iDetails set to errno value if the open() function indicated
+ an error.
+*/
+int
+dk4fd_open(const dkChar *path, int flags, dk4_er_t *erp);
+
+/** Close file descriptor.
+ @param fd File descriptor to close.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_CLOSE_FAILED<br>
+ with iDetails set to errno if the close() function indicates an error.
+*/
+int
+dk4fd_close(int fd, dk4_er_t *erp);
+
+/** Write data to a file descriptor.
+ @param fd File descriptor.
+ @param buffer Buffer start address.
+ @param sz Size of buffer.
+ @param erp Error report, may be NULL.
+ @return 1 on success (all bytes written), 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if buffer is NULL or sz is 0 or sz is too large,
+ - DK4_E_WRITE_FAILED<br>
+ with mem.nelem set to the number of bytes written if
+ the write attempt failed.
+*/
+int
+dk4fd_write(int fd, const void *buffer, size_t sz, dk4_er_t *erp);
+
+/** Read data from a file descriptor.
+ @param fd File descriptor.
+ @param buffer Buffer start address.
+ @param psz Pointer to size variable,
+ in: Size of buffer,
+ out: Number of bytes read.
+ @param erp Error report, may be NULL.
+ @return 1 on success (at least one byte read), 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if buffer or psz is NULL or *psz is 0 or *psz is too large,
+ - DK4_E_READ_FAILED<br>
+ with iDetails set to errno if the read() function indicated an error.
+*/
+int
+dk4fd_read(int fd, void *buffer, size_t *psz, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+
+#include "dk4fd.h"
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SHARE_H
+#ifndef SHARE_H_INCLUDED
+#include <share.h>
+#define SHARE_H_INCLUDED 1
+#endif
+#endif
+
+
+$!trace-include
+
+
+
+int
+dk4fd_c8_open(const char *path, int flags, dk4_er_t *erp)
+{
+ int back = -1;
+ if (NULL != path) {
+#if DK4_ON_WINDOWS
+#if _MSC_VER >= 1700
+ int res;
+ if (0 != (res = _sopen_s(&back,path,flags,_SH_DENYNO,(_S_IREAD|_S_IWRITE))))
+ {
+ if (-1 != back) {
+ _close(back);
+ back = -1;
+ }
+ dk4error_set_idetails(erp, DK4_E_OPEN_FAILED, res);
+ }
+#else
+ errno = 0;
+ back = _open(path, flags, (_S_IREAD | _S_IWRITE));
+ if (-1 == back) {
+ dk4error_set_idetails(erp, DK4_E_OPEN_FAILED, errno);
+ }
+#endif
+#else
+ errno = 0;
+ back = open(path, flags, 0600);
+ if (-1 == back) {
+ dk4error_set_idetails(erp, DK4_E_OPEN_FAILED, errno);
+ }
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4fd_wc_open(const wchar_t *path, int flags, dk4_er_t *erp)
+{
+ int back = -1;
+ if (NULL != path) {
+#if DK4_ON_WINDOWS
+#if _MSC_VER >= 1700
+ int res;
+ if (0 != (res=_wsopen_s(&back,path,flags,_SH_DENYNO,(_S_IREAD|_S_IWRITE))))
+ {
+ if (-1 != back) {
+ _close(back);
+ back = -1;
+ }
+ dk4error_set_idetails(erp, DK4_E_OPEN_FAILED, res);
+ }
+#else
+ errno = 0;
+ back = _wopen(path, flags, (_S_IREAD | _S_IWRITE));
+ if (-1 == back) {
+ dk4error_set_idetails(erp, DK4_E_OPEN_FAILED, errno);
+ }
+#endif
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4fd_open(const dkChar *path, int flags, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4fd_wc_open(path, flags, erp));
+#else
+ return (dk4fd_c8_open(path, flags, erp));
+#endif
+}
+
+
+
+int
+dk4fd_close(int fd, dk4_er_t *erp)
+{
+ int back = 0;
+#if DK4_ON_WINDOWS
+ errno = 0;
+ if (0 == _close(fd)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_CLOSE_FAILED, errno);
+ }
+#else
+ errno = 0;
+ if (0 == close(fd)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_CLOSE_FAILED, errno);
+ }
+#endif
+ return back;
+}
+
+
+
+#if !DK4_ON_WINDOWS
+#ifndef SSIZE_MAX
+/** Maximum value for ssize_t.
+*/
+#define SSIZE_MAX ((SIZE_MAX) / 2U)
+#endif
+#endif
+
+
+
+int
+dk4fd_write(int fd, const void *buffer, size_t sz, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ int back = 0;
+ int res;
+ if ((NULL != buffer) && (0 < sz)) {
+ if ((dk4_um_t)INT_MAX >= (dk4_um_t)sz) {
+ errno = 0;
+ res = _write(fd, buffer, (unsigned)sz);
+ if ((unsigned)res == (unsigned)sz) {
+ back = 1;
+ } else {
+ if (0 <= res) {
+ dk4error_set_elsize_nelem(erp, DK4_E_WRITE_FAILED, 1, (size_t)res);
+ } else {
+ dk4error_set_elsize_nelem(erp, DK4_E_WRITE_FAILED, 1, 0);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ ssize_t res;
+ int back = 0;
+ if ((NULL != buffer) && (0 < sz)) {
+ if ((dk4_um_t)SSIZE_MAX >= (dk4_um_t)sz) {
+ errno = 0;
+ res = write(fd, buffer, sz);
+ if ((size_t)res == sz) {
+ back = 1;
+ } else {
+ if (0 <= res) {
+ dk4error_set_elsize_nelem(erp, DK4_E_WRITE_FAILED, 1, res);
+ } else {
+ dk4error_set_elsize_nelem(erp, DK4_E_WRITE_FAILED, 1, 0);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#endif
+}
+
+
+
+int
+dk4fd_read(int fd, void *buffer, size_t *psz, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ int res = 0; /* Result from read operation */
+ int back = 0;
+ if ((NULL != buffer) && (NULL != psz)) {
+ if (0 < *psz) {
+ if ((dk4_um_t)INT_MAX >= (dk4_um_t)(*psz)) {
+ errno = 0;
+ res = _read(fd, buffer, (unsigned)(*psz));
+ if (0 < res) {
+ back = 1;
+ *psz = (size_t)res;
+ } else {
+ if (0 > res) {
+ back = 0;
+ *psz = 0;
+ dk4error_set_idetails(erp, DK4_E_READ_FAILED, errno);
+ } else {
+ back = 1;
+ *psz = 0;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ int back = 0;
+ ssize_t res;
+ if ((NULL != buffer) && (NULL != psz)) {
+ if (0 < *psz) {
+ if ((dk4_um_t)SSIZE_MAX >= (dk4_um_t)(*psz)) {
+ errno = 0;
+ res = read(fd, buffer, *psz);
+ if (0 < res) {
+ back = 1;
+ *psz = (size_t)res;
+ } else {
+ if (0 > res) {
+ back = 0;
+ *psz = 0;
+ dk4error_set_idetails(erp, DK4_E_READ_FAILED, errno);
+ } else {
+ back = 1;
+ *psz = 0;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#endif
+}
+
+
diff --git a/support/dktools/dk4fd.h b/support/dktools/dk4fd.h
new file mode 100644
index 0000000000..8706d7de3e
--- /dev/null
+++ b/support/dktools/dk4fd.h
@@ -0,0 +1,292 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fd.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4FD_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4FD_H_INCLUDED 1
+
+
+#line 10 "dk4fd.ctr"
+
+/** @file
+ File descriptors, open and close a file, read and write.
+
+ Portable use of file descriptor.
+
+ CRT on Windows: Required.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_STAT_H
+#ifndef SYS_STAT_H_INCLUDED
+#include <sys/stat.h>
+#define SYS_STAT_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_WCHAR_H
+#ifndef WCHAR_H_INCLUDED
+#include <wchar.h>
+#define WCHAR_H_INCLUDED 1
+#endif
+#endif
+
+
+
+#if DK4_ON_WINDOWS
+/** File open flags.
+*/
+enum {
+ /** Read only access.
+ */
+ DK4_O_RDONLY = _O_RDONLY,
+
+ /** Write only access.
+ */
+ DK4_O_WRONLY = _O_WRONLY,
+
+ /** Read and write access.
+ */
+ DK4_O_RDWR = _O_RDWR,
+
+ /** Create file if it does
+ not yet exist.
+ */
+ DK4_O_CREAT = _O_CREAT,
+
+ /** Combined with DK4_O_CREAT,
+ create error if file already
+ exists.
+ */
+ DK4_O_EXCL = _O_EXCL,
+
+ /** Truncate existing file.
+ */
+ DK4_O_TRUNC = _O_TRUNC,
+
+ /** Append to existing file.
+ */
+ DK4_O_APPEND = _O_APPEND,
+
+ /** Open file in binary mode.
+ */
+ DK4_O_BINARY = _O_BINARY,
+};
+#else
+/** File open flags.
+*/
+enum {
+ /** Read only access.
+ */
+ DK4_O_RDONLY = O_RDONLY,
+
+ /** Write only access.
+ */
+ DK4_O_WRONLY = O_WRONLY,
+
+ /** Read and write access.
+ */
+ DK4_O_RDWR = O_RDWR,
+
+ /** Create file if it does
+ not yet exist.
+ */
+ DK4_O_CREAT = O_CREAT,
+
+ /** Combined with DK4_O_CREAT,
+ create error if file already
+ exists.
+ */
+ DK4_O_EXCL = O_EXCL,
+
+ /** Truncate existing file.
+ */
+ DK4_O_TRUNC = O_TRUNC,
+
+ /** Append to existing file.
+ */
+ DK4_O_APPEND = O_APPEND,
+
+ /** Open file in binary mode.
+ */
+ DK4_O_BINARY = 0,
+};
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open a file, return file descriptor.
+ @param path File name.
+ @param flags Flags how to open the file.
+ @param erp Error report, may be NULL.
+ @return Non-negative file descriptor on success, -1 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if path is NULL,
+ - DK4_E_OPEN_FAILED<br>
+ with iDetails set to errno value if the open() function indicated
+ an error.
+*/
+int
+dk4fd_c8_open(const char *path, int flags, dk4_er_t *erp);
+
+/** Open a file, return file descriptor.
+ @param path File name.
+ @param flags Flags how to open the file.
+ @param erp Error report, may be NULL.
+ @return Non-negative file descriptor on success, -1 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ if there is no function available to open files by wchar_t file name,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if path is NULL,
+ - DK4_E_OPEN_FAILED<br>
+ with iDetails set to errno value if the open() function indicated
+ an error.
+*/
+int
+dk4fd_wc_open(const wchar_t *path, int flags, dk4_er_t *erp);
+
+/** Open a file, return file descriptor.
+ @param path File name.
+ @param flags Flags how to open the file.
+ @param erp Error report, may be NULL.
+ @return Non-negative file descriptor on success, -1 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ if there is no function available to open files by wchar_t file name,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if path is NULL,
+ - DK4_E_OPEN_FAILED<br>
+ with iDetails set to errno value if the open() function indicated
+ an error.
+*/
+int
+dk4fd_open(const dkChar *path, int flags, dk4_er_t *erp);
+
+/** Close file descriptor.
+ @param fd File descriptor to close.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_CLOSE_FAILED<br>
+ with iDetails set to errno if the close() function indicates an error.
+*/
+int
+dk4fd_close(int fd, dk4_er_t *erp);
+
+/** Write data to a file descriptor.
+ @param fd File descriptor.
+ @param buffer Buffer start address.
+ @param sz Size of buffer.
+ @param erp Error report, may be NULL.
+ @return 1 on success (all bytes written), 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if buffer is NULL or sz is 0 or sz is too large,
+ - DK4_E_WRITE_FAILED<br>
+ with mem.nelem set to the number of bytes written if
+ the write attempt failed.
+*/
+int
+dk4fd_write(int fd, const void *buffer, size_t sz, dk4_er_t *erp);
+
+/** Read data from a file descriptor.
+ @param fd File descriptor.
+ @param buffer Buffer start address.
+ @param psz Pointer to size variable,
+ in: Size of buffer,
+ out: Number of bytes read.
+ @param erp Error report, may be NULL.
+ @return 1 on success (at least one byte read), 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if buffer or psz is NULL or *psz is 0 or *psz is too large,
+ - DK4_E_READ_FAILED<br>
+ with iDetails set to errno if the read() function indicated an error.
+*/
+int
+dk4fd_read(int fd, void *buffer, size_t *psz, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4fdrda.c b/support/dktools/dk4fdrda.c
new file mode 100644
index 0000000000..22d636488a
--- /dev/null
+++ b/support/dktools/dk4fdrda.c
@@ -0,0 +1,142 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fdrda.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4fdrda.c The dk4fdrda module.
+*/
+
+
+#line 40 "dk4fdrda.ctr"
+
+#include "dk4fdrda.h"
+#include "dk4fdrde.h"
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+
+
+
+
+#line 68 "dk4fdrda.ctr"
+
+
+
+#ifdef RW_MAX
+#undef RW_MAX
+#endif
+#if DK4_ON_WINDOWS
+/** Maximum number of bytes for read or write operation.
+*/
+#define RW_MAX (INT_MAX)
+#else
+/** Maximum number of bytes for read or write operation.
+*/
+#define RW_MAX ((SIZE_MAX) / 2U)
+#endif
+
+
+int
+dk4fd_read_app(
+ int fd, void *buffer, size_t *psz, const dkChar *fn, dk4_app_t *app
+)
+{
+#if DK4_ON_WINDOWS
+ int res;
+#else
+ ssize_t res;
+#endif
+ int back = 0;
+
+
+
+#line 98 "dk4fdrda.ctr"
+ if ((-1 != fd) && (NULL != buffer) && (NULL != psz)) {
+ if (0 < *psz) {
+ if ((dk4_um_t)RW_MAX >= (dk4_um_t)(*psz)) {
+ errno = 0;
+#if DK4_ON_WINDOWS
+ res = _read(fd, buffer, (unsigned)(*psz));
+#else
+ res = read(fd, buffer, *psz);
+#endif
+ if (0 <= res) {
+ if (0 < res) {
+
+#line 109 "dk4fdrda.ctr"
+ back = 1;
+ *psz = (size_t)res;
+ } else {
+
+#line 112 "dk4fdrda.ctr"
+ back = 1;
+ *psz = (size_t)0;
+ }
+ } else {
+
+#line 116 "dk4fdrda.ctr"
+ dk4fd_read_error_msg(app, fn, errno);
+ }
+ }
+ } else {
+
+#line 120 "dk4fdrda.ctr"
+ }
+ } else {
+
+#line 122 "dk4fdrda.ctr"
+ }
+
+#line 123 "dk4fdrda.ctr"
+ return back;
+}
+
diff --git a/support/dktools/dk4fdrda.ctr b/support/dktools/dk4fdrda.ctr
new file mode 100644
index 0000000000..3395cbd1bf
--- /dev/null
+++ b/support/dktools/dk4fdrda.ctr
@@ -0,0 +1,125 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file dk4fdrda.h Read from file descriptor.
+*/
+
+#include "dk4conf.h"
+#include "dk4app.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Read from file descriptor.
+ @param fd File descriptor to read from.
+ @param buffer Destination buffer address.
+ @param psz Pointer to buffer size (number of bytes),
+ in: bytes available, out: bytes used.
+ @param fn File name, may be NULL.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4fd_read_app(
+ int fd, void *buffer, size_t *psz, const dkChar *fn, dk4_app_t *app
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4fdrda.h"
+#include "dk4fdrde.h"
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+
+
+$!trace-include
+
+
+
+#ifdef RW_MAX
+#undef RW_MAX
+#endif
+#if DK4_ON_WINDOWS
+/** Maximum number of bytes for read or write operation.
+*/
+#define RW_MAX (INT_MAX)
+#else
+/** Maximum number of bytes for read or write operation.
+*/
+#define RW_MAX ((SIZE_MAX) / 2U)
+#endif
+
+
+int
+dk4fd_read_app(
+ int fd, void *buffer, size_t *psz, const dkChar *fn, dk4_app_t *app
+)
+{
+#if DK4_ON_WINDOWS
+ int res;
+#else
+ ssize_t res;
+#endif
+ int back = 0;
+
+ $? "+ dk4fd_read_app"
+ if ((-1 != fd) && (NULL != buffer) && (NULL != psz)) {
+ if (0 < *psz) {
+ if ((dk4_um_t)RW_MAX >= (dk4_um_t)(*psz)) {
+ errno = 0;
+#if DK4_ON_WINDOWS
+ res = _read(fd, buffer, (unsigned)(*psz));
+#else
+ res = read(fd, buffer, *psz);
+#endif
+ if (0 <= res) {
+ if (0 < res) { $? ". bytes found"
+ back = 1;
+ *psz = (size_t)res;
+ } else { $? ". EOF"
+ back = 1;
+ *psz = (size_t)0;
+ }
+ } else { $? "! error"
+ dk4fd_read_error_msg(app, fn, errno);
+ }
+ }
+ } else { $? "! BUG buffer size 0"
+ }
+ } else { $? "! BUG arguments"
+ } $? "- dk4fd_read_app %d", back
+ return back;
+}
+
diff --git a/support/dktools/dk4fdrda.h b/support/dktools/dk4fdrda.h
new file mode 100644
index 0000000000..3bd61d3f48
--- /dev/null
+++ b/support/dktools/dk4fdrda.h
@@ -0,0 +1,73 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fdrda.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4FDRDA_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4FDRDA_H_INCLUDED 1
+
+
+#line 9 "dk4fdrda.ctr"
+
+/** @file dk4fdrda.h Read from file descriptor.
+*/
+
+#include "dk4conf.h"
+#include "dk4app.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Read from file descriptor.
+ @param fd File descriptor to read from.
+ @param buffer Destination buffer address.
+ @param psz Pointer to buffer size (number of bytes),
+ in: bytes available, out: bytes used.
+ @param fn File name, may be NULL.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4fd_read_app(
+ int fd, void *buffer, size_t *psz, const dkChar *fn, dk4_app_t *app
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4fdrde.c b/support/dktools/dk4fdrde.c
new file mode 100644
index 0000000000..05311e0b85
--- /dev/null
+++ b/support/dktools/dk4fdrde.c
@@ -0,0 +1,168 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fdrde.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4fdrde.c The dk4fdrde module.
+*/
+
+
+#line 34 "dk4fdrde.ctr"
+
+#include "dk4fdrde.h"
+#include "dk4const.h"
+#include "dk4mem.h"
+#include "dk4maodd.h"
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+void
+dk4fd_read_error_msg(dk4_app_t *app, const dkChar *fn, int errc)
+{
+ dkChar buf[64];
+ const dkChar *oldsourcefile = NULL;
+ size_t oldsourceline = (dk4_um_t)0UL;
+ int res;
+
+ if (NULL != app) {
+ oldsourcefile = dk4app_get_log_source_file(app);
+ oldsourceline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_file(app, fn);
+ dk4app_set_log_source_line(app, (dk4_um_t)0UL);
+ switch (errc){
+#ifdef EAGAIN
+ case EAGAIN : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 118, 121);
+ } break;
+#endif
+#if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN)
+ case EWOULDBLOCK : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 118, 121);
+ } break;
+#endif
+#ifdef EBADF
+ case EBADF : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 118, 122);
+ } break;
+#endif
+#ifdef EBADMSG
+ case EBADMSG : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 118, 139);
+ } break;
+#endif
+#ifdef EFAULT
+ case EFAULT : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 118, 123);
+ } break;
+#endif
+#ifdef EINTR
+ case EINTR : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 118, 124);
+ } break;
+#endif
+#ifdef EINVAL
+ case EINVAL : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 118, 125);
+ } break;
+#endif
+#ifdef EIO
+ case EIO : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 118, 126);
+ } break;
+#endif
+#ifdef EISDIR
+ case EISDIR : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 118, 127);
+ } break;
+#endif
+#ifdef EOVERFLOW
+ case EOVERFLOW : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 118, 78);
+ } break;
+#endif
+#ifdef ECONNRESET
+ case ECONNRESET : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 118, 140);
+ } break;
+#endif
+#ifdef ENOTCON
+ case ENOTCON : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 118, 134);
+ } break;
+#endif
+#ifdef ETIMEDOUT
+ case ETIMEDOUT : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 118, 141);
+ } break;
+#endif
+#ifdef ENOBUFS
+ case ENOBUFS : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 118, 136);
+ } break;
+#endif
+#ifdef ENOMEM
+ case ENOMEM : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 118, 142);
+ } break;
+#endif
+#ifdef ENXIO
+ case ENXIO : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 118, 137);
+ } break;
+#endif
+#ifdef ESPIPE
+ case ESPIPE : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 118, 143);
+ } break;
+#endif
+ default : {
+ res = dk4ma_write_decimal_signed(
+ buf, DK4_SIZEOF(buf,dkChar), (dk4_im_t)errc, 0, NULL
+ );
+ if (0 != res) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 119, 120, buf);
+ } else {
+ dk4app_log_base1(app, DK4_LL_ERROR, 118);
+ }
+ } break;
+ }
+ dk4app_set_log_source_file(app, oldsourcefile);
+ dk4app_set_log_source_line(app, oldsourceline);
+ }
+}
+
diff --git a/support/dktools/dk4fdrde.ctr b/support/dktools/dk4fdrde.ctr
new file mode 100644
index 0000000000..07ab799070
--- /dev/null
+++ b/support/dktools/dk4fdrde.ctr
@@ -0,0 +1,161 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk4fdrde.h Error message for errors while reading.
+*/
+
+#include "dk4conf.h"
+#include "dk4app.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Report error from read attempt on file descriptr.
+ @param app Application structure.
+ @param fn File name, may be NULL.
+ @param errc Error code from errno.
+*/
+void
+dk4fd_read_error_msg(dk4_app_t *app, const dkChar *fn, int errc);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4fdrde.h"
+#include "dk4const.h"
+#include "dk4mem.h"
+#include "dk4maodd.h"
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+void
+dk4fd_read_error_msg(dk4_app_t *app, const dkChar *fn, int errc)
+{
+ dkChar buf[64];
+ const dkChar *oldsourcefile = NULL;
+ size_t oldsourceline = (dk4_um_t)0UL;
+ int res;
+
+ if (NULL != app) {
+ oldsourcefile = dk4app_get_log_source_file(app);
+ oldsourceline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_file(app, fn);
+ dk4app_set_log_source_line(app, (dk4_um_t)0UL);
+ switch (errc){
+#ifdef EAGAIN
+ case EAGAIN : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 118, 121);
+ } break;
+#endif
+#if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN)
+ case EWOULDBLOCK : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 118, 121);
+ } break;
+#endif
+#ifdef EBADF
+ case EBADF : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 118, 122);
+ } break;
+#endif
+#ifdef EBADMSG
+ case EBADMSG : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 118, 139);
+ } break;
+#endif
+#ifdef EFAULT
+ case EFAULT : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 118, 123);
+ } break;
+#endif
+#ifdef EINTR
+ case EINTR : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 118, 124);
+ } break;
+#endif
+#ifdef EINVAL
+ case EINVAL : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 118, 125);
+ } break;
+#endif
+#ifdef EIO
+ case EIO : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 118, 126);
+ } break;
+#endif
+#ifdef EISDIR
+ case EISDIR : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 118, 127);
+ } break;
+#endif
+#ifdef EOVERFLOW
+ case EOVERFLOW : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 118, 78);
+ } break;
+#endif
+#ifdef ECONNRESET
+ case ECONNRESET : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 118, 140);
+ } break;
+#endif
+#ifdef ENOTCON
+ case ENOTCON : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 118, 134);
+ } break;
+#endif
+#ifdef ETIMEDOUT
+ case ETIMEDOUT : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 118, 141);
+ } break;
+#endif
+#ifdef ENOBUFS
+ case ENOBUFS : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 118, 136);
+ } break;
+#endif
+#ifdef ENOMEM
+ case ENOMEM : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 118, 142);
+ } break;
+#endif
+#ifdef ENXIO
+ case ENXIO : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 118, 137);
+ } break;
+#endif
+#ifdef ESPIPE
+ case ESPIPE : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 118, 143);
+ } break;
+#endif
+ default : {
+ res = dk4ma_write_decimal_signed(
+ buf, DK4_SIZEOF(buf,dkChar), (dk4_im_t)errc, 0, NULL
+ );
+ if (0 != res) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 119, 120, buf);
+ } else {
+ dk4app_log_base1(app, DK4_LL_ERROR, 118);
+ }
+ } break;
+ }
+ dk4app_set_log_source_file(app, oldsourcefile);
+ dk4app_set_log_source_line(app, oldsourceline);
+ }
+}
+
diff --git a/support/dktools/dk4fdrde.h b/support/dktools/dk4fdrde.h
new file mode 100644
index 0000000000..07ec103472
--- /dev/null
+++ b/support/dktools/dk4fdrde.h
@@ -0,0 +1,66 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fdrde.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4FDRDE_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4FDRDE_H_INCLUDED 1
+
+
+#line 10 "dk4fdrde.ctr"
+
+/** @file dk4fdrde.h Error message for errors while reading.
+*/
+
+#include "dk4conf.h"
+#include "dk4app.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Report error from read attempt on file descriptr.
+ @param app Application structure.
+ @param fn File name, may be NULL.
+ @param errc Error code from errno.
+*/
+void
+dk4fd_read_error_msg(dk4_app_t *app, const dkChar *fn, int errc);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4fdwre.c b/support/dktools/dk4fdwre.c
new file mode 100644
index 0000000000..e846016c5e
--- /dev/null
+++ b/support/dktools/dk4fdwre.c
@@ -0,0 +1,181 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fdwre.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4fdwre.c The dk4fdwre module.
+*/
+
+
+#line 36 "dk4fdwre.ctr"
+
+#include "dk4fdwre.h"
+#include "dk4const.h"
+#include "dk4mem.h"
+#include "dk4maodd.h"
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+
+
+
+#line 51 "dk4fdwre.ctr"
+
+
+
+void
+dk4fd_write_error_msg(dk4_app_t *app, const dkChar *fn, int errc)
+{
+ dkChar buf[64];
+ const dkChar *oldsourcefile = NULL;
+ size_t oldsourceline = (dk4_um_t)0UL;
+ int res;
+
+ if (NULL != app) {
+ oldsourcefile = dk4app_get_log_source_file(app);
+ oldsourceline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_file(app, fn);
+ dk4app_set_log_source_line(app, (dk4_um_t)0UL);
+ switch (errc){
+#ifdef EAGAIN
+ case EAGAIN : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 128, 121);
+ } break;
+#endif
+#if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN)
+ case EWOULDBLOCK : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 128, 121);
+ } break;
+#endif
+#ifdef EBADF
+ case EBADF : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 128, 122);
+ } break;
+#endif
+#ifdef EFAULT
+ case EFAULT : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 128, 122);
+ } break;
+#endif
+#ifdef EFBIG
+ case EFBIG : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 128, 132);
+ } break;
+#endif
+#ifdef EINTR
+ case EINTR : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 128, 124);
+ } break;
+#endif
+#ifdef EINVAL
+ case EINVAL : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 128, 125);
+ } break;
+#endif
+#ifdef EIO
+ case EIO : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 128, 126);
+ } break;
+#endif
+#ifdef ENOSPC
+ case ENOSPC : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 128, 131);
+ } break;
+#endif
+#ifdef EPIPE
+ case EPIPE : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 128, 133);
+ } break;
+#endif
+#ifdef EISDIR
+ case EISDIR : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 128, 127);
+ } break;
+#endif
+#ifdef ECONNRESET
+ case ECONNRESET : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 128, 134);
+ } break;
+#endif
+#ifdef ERANGE
+ case ERANGE : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 128, 135);
+ } break;
+#endif
+#ifdef ENOBUFS
+ case ENOBUFS : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 128, 136);
+ } break;
+#endif
+#ifdef ENXIO
+ case ENXIO : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 128, 137);
+ } break;
+#endif
+#ifdef EACCES
+ case EACCES : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 128, 138);
+ } break;
+#endif
+#ifdef ENETDOWN
+ case ENETDOWN : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 128, 45);
+ } break;
+#endif
+#ifdef ENETUNREACH
+ case ENETUNREACH : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 128, 76);
+ } break;
+#endif
+ default : {
+ res = dk4ma_write_decimal_signed(
+ buf, DK4_SIZEOF(buf,dkChar), (dk4_im_t)errc, 0, NULL
+ );
+ if (0 != res) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 129, 130, buf);
+ } else {
+ dk4app_log_base1(app, DK4_LL_ERROR, 128);
+ }
+ } break;
+ }
+ dk4app_set_log_source_file(app, oldsourcefile);
+ dk4app_set_log_source_line(app, oldsourceline);
+ }
+}
+
+
diff --git a/support/dktools/dk4fdwre.ctr b/support/dktools/dk4fdwre.ctr
new file mode 100644
index 0000000000..7a13390a59
--- /dev/null
+++ b/support/dktools/dk4fdwre.ctr
@@ -0,0 +1,174 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk4fdwre.h Report errors for write operations.
+*/
+
+#include "dk4conf.h"
+#include "dk4app.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Report error from read attempt on file descriptr.
+ @param app Application structure.
+ @param fn File name, may be NULL.
+ @param errc Error code from errno.
+*/
+void
+dk4fd_write_error_msg(dk4_app_t *app, const dkChar *fn, int errc);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4fdwre.h"
+#include "dk4const.h"
+#include "dk4mem.h"
+#include "dk4maodd.h"
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+
+$!trace-include
+
+
+
+void
+dk4fd_write_error_msg(dk4_app_t *app, const dkChar *fn, int errc)
+{
+ dkChar buf[64];
+ const dkChar *oldsourcefile = NULL;
+ size_t oldsourceline = (dk4_um_t)0UL;
+ int res;
+
+ if (NULL != app) {
+ oldsourcefile = dk4app_get_log_source_file(app);
+ oldsourceline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_file(app, fn);
+ dk4app_set_log_source_line(app, (dk4_um_t)0UL);
+ switch (errc){
+#ifdef EAGAIN
+ case EAGAIN : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 128, 121);
+ } break;
+#endif
+#if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN)
+ case EWOULDBLOCK : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 128, 121);
+ } break;
+#endif
+#ifdef EBADF
+ case EBADF : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 128, 122);
+ } break;
+#endif
+#ifdef EFAULT
+ case EFAULT : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 128, 122);
+ } break;
+#endif
+#ifdef EFBIG
+ case EFBIG : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 128, 132);
+ } break;
+#endif
+#ifdef EINTR
+ case EINTR : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 128, 124);
+ } break;
+#endif
+#ifdef EINVAL
+ case EINVAL : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 128, 125);
+ } break;
+#endif
+#ifdef EIO
+ case EIO : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 128, 126);
+ } break;
+#endif
+#ifdef ENOSPC
+ case ENOSPC : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 128, 131);
+ } break;
+#endif
+#ifdef EPIPE
+ case EPIPE : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 128, 133);
+ } break;
+#endif
+#ifdef EISDIR
+ case EISDIR : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 128, 127);
+ } break;
+#endif
+#ifdef ECONNRESET
+ case ECONNRESET : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 128, 134);
+ } break;
+#endif
+#ifdef ERANGE
+ case ERANGE : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 128, 135);
+ } break;
+#endif
+#ifdef ENOBUFS
+ case ENOBUFS : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 128, 136);
+ } break;
+#endif
+#ifdef ENXIO
+ case ENXIO : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 128, 137);
+ } break;
+#endif
+#ifdef EACCES
+ case EACCES : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 128, 138);
+ } break;
+#endif
+#ifdef ENETDOWN
+ case ENETDOWN : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 128, 45);
+ } break;
+#endif
+#ifdef ENETUNREACH
+ case ENETUNREACH : {
+ dk4app_log_base2c(app, DK4_LL_ERROR, 128, 76);
+ } break;
+#endif
+ default : {
+ res = dk4ma_write_decimal_signed(
+ buf, DK4_SIZEOF(buf,dkChar), (dk4_im_t)errc, 0, NULL
+ );
+ if (0 != res) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 129, 130, buf);
+ } else {
+ dk4app_log_base1(app, DK4_LL_ERROR, 128);
+ }
+ } break;
+ }
+ dk4app_set_log_source_file(app, oldsourcefile);
+ dk4app_set_log_source_line(app, oldsourceline);
+ }
+}
+
+
diff --git a/support/dktools/dk4fdwre.h b/support/dktools/dk4fdwre.h
new file mode 100644
index 0000000000..17fc4354f5
--- /dev/null
+++ b/support/dktools/dk4fdwre.h
@@ -0,0 +1,68 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fdwre.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4FDWRE_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4FDWRE_H_INCLUDED 1
+
+
+#line 10 "dk4fdwre.ctr"
+
+/** @file dk4fdwre.h Report errors for write operations.
+*/
+
+#include "dk4conf.h"
+#include "dk4app.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Report error from read attempt on file descriptr.
+ @param app Application structure.
+ @param fn File name, may be NULL.
+ @param errc Error code from errno.
+*/
+void
+dk4fd_write_error_msg(dk4_app_t *app, const dkChar *fn, int errc);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4file8.c b/support/dktools/dk4file8.c
new file mode 100644
index 0000000000..b40d457e16
--- /dev/null
+++ b/support/dktools/dk4file8.c
@@ -0,0 +1,205 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4file8.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4file8.c The dk4file8 module.
+*/
+
+
+#line 91 "dk4file8.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#else
+#ifndef DK4STAT8_H_INCLUDED
+#include "dk4stat8.h"
+#endif
+#ifndef DK4STAT_H_INCLUDED
+#include "dk4stat.h"
+#endif
+#endif
+
+#include "dk4file8.h"
+
+
+
+int
+dk4file_c8_exists(const char *fn, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ DWORD dwattr;
+ HANDLE ha;
+ WIN32_FIND_DATAA ffdata;
+#else
+ dk4_stat_t stb;
+ dk4_stat_t lstb;
+#endif
+ int back = 0;
+ if (NULL != fn) {
+#if DK4_ON_WINDOWS
+ dwattr = GetFileAttributesA(fn);
+ if (INVALID_FILE_ATTRIBUTES != dwattr) {
+ back = 1;
+ } else {
+ ha = FindFirstFileA(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != ha) {
+ back = 1;
+ FindClose(ha);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ }
+#else
+ if (0 != dk4stat_c8(&stb, fn, NULL)) {
+ back = 1;
+ } else {
+ if (0 != dk4stat_l_c8(&lstb, fn, NULL)) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ }
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4file_c8_is_regular(const char *fn, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ DWORD dwattr;
+ HANDLE ha;
+ WIN32_FIND_DATAA ffdata;
+#else
+ dk4_stat_t stb;
+#endif
+ int back = 0;
+ if (NULL != fn) {
+#if DK4_ON_WINDOWS
+ dwattr = GetFileAttributesA(fn);
+ if (INVALID_FILE_ATTRIBUTES != dwattr) {
+ if ((DWORD)0UL == (FILE_ATTRIBUTE_DIRECTORY & dwattr)) {
+ if ((DWORD)0UL == (FILE_ATTRIBUTE_DEVICE & dwattr)) {
+ back = 1;
+ }
+ }
+ } else {
+ ha = FindFirstFileA(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != ha) {
+ dwattr = ffdata.dwFileAttributes;
+ if ((DWORD)0UL == (FILE_ATTRIBUTE_DIRECTORY & dwattr)) {
+ if ((DWORD)0UL == (FILE_ATTRIBUTE_DEVICE & dwattr)) {
+ back = 1;
+ }
+ }
+ FindClose(ha);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ }
+#else
+ if (0 != dk4stat_c8(&stb, fn, NULL)) {
+ if (0 != dk4stat_is_regular(&stb, erp)) {
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4file_c8_is_directory(const char *fn, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ DWORD dwattr;
+ HANDLE ha;
+ WIN32_FIND_DATAA ffdata;
+#else
+ dk4_stat_t stb;
+#endif
+ int back = 0;
+ if (NULL != fn) {
+#if DK4_ON_WINDOWS
+ dwattr = GetFileAttributesA(fn);
+ if (INVALID_FILE_ATTRIBUTES != dwattr) {
+ if ((DWORD)0UL != (FILE_ATTRIBUTE_DIRECTORY & dwattr)) {
+ back = 1;
+ }
+ } else {
+ ha = FindFirstFileA(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != ha) {
+ dwattr = ffdata.dwFileAttributes;
+ if ((DWORD)0UL!=(FILE_ATTRIBUTE_DIRECTORY & dwattr))
+ {
+ back = 1;
+ }
+ FindClose(ha);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ }
+#else
+ if (0 != dk4stat_c8(&stb, fn, NULL)) {
+ if (0 != dk4stat_is_directory(&stb, erp)) {
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4file8.ctr b/support/dktools/dk4file8.ctr
new file mode 100644
index 0000000000..1330ef6966
--- /dev/null
+++ b/support/dktools/dk4file8.ctr
@@ -0,0 +1,255 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ File checks.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Check whether a path exists.
+ CRT on Windows: Not used.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 if file exists, 0 otherwise.
+ Note: The function also returns 0 if it fails to obtain information
+ about a file, i.e. due to missing permissions...
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_NOT_FOUND<br>
+ if the specified file was not found or retrieving information
+ failed for other reasons.
+*/
+int
+dk4file_c8_exists(const char *fn, dk4_er_t *erp);
+
+/** Check whether a path name specifies a regular file.
+ CRT on Windows: Not used.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 for existing regular file, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_NOT_FOUND<br>
+ if the file does not exist or retrieving the information failed
+ for some reason,
+ - none<br>
+ if the path exists but is not a regular file.
+*/
+int
+dk4file_c8_is_regular(const char *fn, dk4_er_t *erp);
+
+/** Check whether a path name specifies a directory.
+ CRT on Windows: Not used.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 for existing directory, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_NOT_FOUND<br>
+ if the file does not exist or retrieving the information failed
+ for some reason,
+ - none<br>
+ if the path exists but is not a directory.
+*/
+int
+dk4file_c8_is_directory(const char *fn, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#else
+#ifndef DK4STAT8_H_INCLUDED
+#include "dk4stat8.h"
+#endif
+#ifndef DK4STAT_H_INCLUDED
+#include "dk4stat.h"
+#endif
+#endif
+
+#include "dk4file8.h"
+
+
+
+int
+dk4file_c8_exists(const char *fn, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ DWORD dwattr;
+ HANDLE ha;
+ WIN32_FIND_DATAA ffdata;
+#else
+ dk4_stat_t stb;
+ dk4_stat_t lstb;
+#endif
+ int back = 0;
+ if (NULL != fn) {
+#if DK4_ON_WINDOWS
+ dwattr = GetFileAttributesA(fn);
+ if (INVALID_FILE_ATTRIBUTES != dwattr) {
+ back = 1;
+ } else {
+ ha = FindFirstFileA(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != ha) {
+ back = 1;
+ FindClose(ha);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ }
+#else
+ if (0 != dk4stat_c8(&stb, fn, NULL)) {
+ back = 1;
+ } else {
+ if (0 != dk4stat_l_c8(&lstb, fn, NULL)) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ }
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4file_c8_is_regular(const char *fn, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ DWORD dwattr;
+ HANDLE ha;
+ WIN32_FIND_DATAA ffdata;
+#else
+ dk4_stat_t stb;
+#endif
+ int back = 0;
+ if (NULL != fn) {
+#if DK4_ON_WINDOWS
+ dwattr = GetFileAttributesA(fn);
+ if (INVALID_FILE_ATTRIBUTES != dwattr) {
+ if ((DWORD)0UL == (FILE_ATTRIBUTE_DIRECTORY & dwattr)) {
+ if ((DWORD)0UL == (FILE_ATTRIBUTE_DEVICE & dwattr)) {
+ back = 1;
+ }
+ }
+ } else {
+ ha = FindFirstFileA(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != ha) {
+ dwattr = ffdata.dwFileAttributes;
+ if ((DWORD)0UL == (FILE_ATTRIBUTE_DIRECTORY & dwattr)) {
+ if ((DWORD)0UL == (FILE_ATTRIBUTE_DEVICE & dwattr)) {
+ back = 1;
+ }
+ }
+ FindClose(ha);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ }
+#else
+ if (0 != dk4stat_c8(&stb, fn, NULL)) {
+ if (0 != dk4stat_is_regular(&stb, erp)) {
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4file_c8_is_directory(const char *fn, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ DWORD dwattr;
+ HANDLE ha;
+ WIN32_FIND_DATAA ffdata;
+#else
+ dk4_stat_t stb;
+#endif
+ int back = 0;
+ if (NULL != fn) {
+#if DK4_ON_WINDOWS
+ dwattr = GetFileAttributesA(fn);
+ if (INVALID_FILE_ATTRIBUTES != dwattr) {
+ if ((DWORD)0UL != (FILE_ATTRIBUTE_DIRECTORY & dwattr)) {
+ back = 1;
+ }
+ } else {
+ ha = FindFirstFileA(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != ha) {
+ dwattr = ffdata.dwFileAttributes;
+ if ((DWORD)0UL!=(FILE_ATTRIBUTE_DIRECTORY & dwattr))
+ {
+ back = 1;
+ }
+ FindClose(ha);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ }
+#else
+ if (0 != dk4stat_c8(&stb, fn, NULL)) {
+ if (0 != dk4stat_is_directory(&stb, erp)) {
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4file8.h b/support/dktools/dk4file8.h
new file mode 100644
index 0000000000..1be6335fdc
--- /dev/null
+++ b/support/dktools/dk4file8.h
@@ -0,0 +1,123 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4file8.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4FILE8_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4FILE8_H_INCLUDED 1
+
+
+#line 10 "dk4file8.ctr"
+
+/** @file
+ File checks.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Check whether a path exists.
+ CRT on Windows: Not used.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 if file exists, 0 otherwise.
+ Note: The function also returns 0 if it fails to obtain information
+ about a file, i.e. due to missing permissions...
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_NOT_FOUND<br>
+ if the specified file was not found or retrieving information
+ failed for other reasons.
+*/
+int
+dk4file_c8_exists(const char *fn, dk4_er_t *erp);
+
+/** Check whether a path name specifies a regular file.
+ CRT on Windows: Not used.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 for existing regular file, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_NOT_FOUND<br>
+ if the file does not exist or retrieving the information failed
+ for some reason,
+ - none<br>
+ if the path exists but is not a regular file.
+*/
+int
+dk4file_c8_is_regular(const char *fn, dk4_er_t *erp);
+
+/** Check whether a path name specifies a directory.
+ CRT on Windows: Not used.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 for existing directory, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_NOT_FOUND<br>
+ if the file does not exist or retrieving the information failed
+ for some reason,
+ - none<br>
+ if the path exists but is not a directory.
+*/
+int
+dk4file_c8_is_directory(const char *fn, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4filed.c b/support/dktools/dk4filed.c
new file mode 100644
index 0000000000..e9df3aca39
--- /dev/null
+++ b/support/dktools/dk4filed.c
@@ -0,0 +1,86 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4filed.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4filed.c The dk4filed module.
+*/
+
+
+#line 92 "dk4filed.ctr"
+
+#include "dk4filed.h"
+
+#if DK4_CHAR_SIZE > 1
+#include "dk4filew.h"
+#else
+#include "dk4file8.h"
+#endif
+
+
+
+int
+dk4file_exists(const dkChar *fn, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4file_wc_exists(fn, erp));
+#else
+ return (dk4file_c8_exists(fn, erp));
+#endif
+}
+
+
+
+int
+dk4file_is_regular(const dkChar *fn, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4file_wc_is_regular(fn, erp));
+#else
+ return (dk4file_c8_is_regular(fn, erp));
+#endif
+}
+
+
+
+int
+dk4file_is_directory(const dkChar *fn, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4file_wc_is_directory(fn, erp));
+#else
+ return (dk4file_c8_is_directory(fn, erp));
+#endif
+}
+
+
diff --git a/support/dktools/dk4filed.ctr b/support/dktools/dk4filed.ctr
new file mode 100644
index 0000000000..7de2ffe466
--- /dev/null
+++ b/support/dktools/dk4filed.ctr
@@ -0,0 +1,137 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ File checks.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Check whether a path exists.
+ CRT on Windows: Not used.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 if file exists, 0 otherwise.
+ Note: The function also returns 0 if it fails to obtain information
+ about a file, i.e. due to missing permissions...
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ if wchar_t are used on non-Windows systems,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_NOT_FOUND<br>
+ if the specified file was not found or retrieving information failed
+ for other reasons.
+*/
+int
+dk4file_exists(const dkChar *fn, dk4_er_t *erp);
+
+/** Check whether a path name specifies a regular file.
+ CRT on Windows: Not used.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 for existing regular file, 0 otherwise.
+
+ Error codes:
+ DK4_E_NOT_SUPPORTED if wchar_t are used on non-Windows systems,
+ DK4_E_INVALID_ARGUMENTS if fn is NULL,
+ DK4_E_NOT_FOUND if the file does not exist or retrieving
+ the information failed for some reason,
+ none if the path exists but is not a regular file.
+*/
+int
+dk4file_is_regular(const dkChar *fn, dk4_er_t *erp);
+
+/** Check whether a path name specifies a directory.
+ CRT on Windows: Not used.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 for existing directory, 0 otherwise.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ on non-Windows systems,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_NOT_FOUND<br>
+ if the file does not exist or retrieving the information failed
+ for some reason,
+ - none<br>
+ if the path exists but is not a directory.
+*/
+int
+dk4file_is_directory(const dkChar *fn, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4filed.h"
+
+#if DK4_CHAR_SIZE > 1
+#include "dk4filew.h"
+#else
+#include "dk4file8.h"
+#endif
+
+
+
+int
+dk4file_exists(const dkChar *fn, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4file_wc_exists(fn, erp));
+#else
+ return (dk4file_c8_exists(fn, erp));
+#endif
+}
+
+
+
+int
+dk4file_is_regular(const dkChar *fn, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4file_wc_is_regular(fn, erp));
+#else
+ return (dk4file_c8_is_regular(fn, erp));
+#endif
+}
+
+
+
+int
+dk4file_is_directory(const dkChar *fn, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4file_wc_is_directory(fn, erp));
+#else
+ return (dk4file_c8_is_directory(fn, erp));
+#endif
+}
+
+
diff --git a/support/dktools/dk4filed.h b/support/dktools/dk4filed.h
new file mode 100644
index 0000000000..6f448e1519
--- /dev/null
+++ b/support/dktools/dk4filed.h
@@ -0,0 +1,124 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4filed.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4FILED_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4FILED_H_INCLUDED 1
+
+
+#line 10 "dk4filed.ctr"
+
+/** @file
+ File checks.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Check whether a path exists.
+ CRT on Windows: Not used.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 if file exists, 0 otherwise.
+ Note: The function also returns 0 if it fails to obtain information
+ about a file, i.e. due to missing permissions...
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ if wchar_t are used on non-Windows systems,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_NOT_FOUND<br>
+ if the specified file was not found or retrieving information failed
+ for other reasons.
+*/
+int
+dk4file_exists(const dkChar *fn, dk4_er_t *erp);
+
+/** Check whether a path name specifies a regular file.
+ CRT on Windows: Not used.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 for existing regular file, 0 otherwise.
+
+ Error codes:
+ DK4_E_NOT_SUPPORTED if wchar_t are used on non-Windows systems,
+ DK4_E_INVALID_ARGUMENTS if fn is NULL,
+ DK4_E_NOT_FOUND if the file does not exist or retrieving
+ the information failed for some reason,
+ none if the path exists but is not a regular file.
+*/
+int
+dk4file_is_regular(const dkChar *fn, dk4_er_t *erp);
+
+/** Check whether a path name specifies a directory.
+ CRT on Windows: Not used.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 for existing directory, 0 otherwise.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ on non-Windows systems,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_NOT_FOUND<br>
+ if the file does not exist or retrieving the information failed
+ for some reason,
+ - none<br>
+ if the path exists but is not a directory.
+*/
+int
+dk4file_is_directory(const dkChar *fn, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4filei.c b/support/dktools/dk4filei.c
new file mode 100644
index 0000000000..e6273c9239
--- /dev/null
+++ b/support/dktools/dk4filei.c
@@ -0,0 +1,270 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4filei.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4filei.c The dk4filei module.
+*/
+
+
+#line 379 "dk4filei.ctr"
+
+#include "dk4filei.h"
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4MAADU_H_INCLUDED
+#include "dk4maadu.h"
+#endif
+
+
+
+
+
+#line 393 "dk4filei.ctr"
+
+
+
+void
+dk4fileinfo_init(dk4_file_info_t *dptr)
+{
+ if (NULL != dptr) {
+ DK4_MEMRES(dptr, sizeof(dk4_file_info_t));
+ dptr->contents = 0;
+ }
+}
+
+
+
+int
+dk4fileinfo_is_symlink(const dk4_file_info_t *dptr)
+{
+ int back = 0;
+ if (NULL != dptr) {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & (dptr->contents))) {
+#if DK4_ON_WINDOWS
+ if (0 != (FILE_ATTRIBUTE_REPARSE_POINT & (dptr->fattr))) {
+ if (IO_REPARSE_TAG_MOUNT_POINT == dptr->rppnt) {
+ back = 1;
+ }
+ if (IO_REPARSE_TAG_SYMLINK == dptr->rppnt) {
+ back = 1;
+ }
+ }
+#else
+#if defined(S_IFMT) && defined (S_IFLNK)
+ if (S_IFLNK == (S_IFMT & ((dptr->lstb).st_mode))) {
+ back = 1;
+ }
+#endif
+#endif
+ }
+ }
+ return back;
+}
+
+
+
+#if DK4_ON_WINDOWS
+static
+int
+dk4fileinfo_copy_size(
+ dk4_um_t *dptr,
+ const BY_HANDLE_FILE_INFORMATION *bhfi,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er;
+ dk4_um_t val;
+ int back = 0;
+
+
+#line 449 "dk4filei.ctr"
+ dk4error_init(&er);
+
+
+#line 451 "dk4filei.ctr"
+
+
+#line 452 "dk4filei.ctr"
+ if ((DWORD)0UL != bhfi->nFileSizeHigh) {
+ val = dk4ma_um_add(
+ dk4ma_um_mul(
+ dk4ma_um_add(
+ (dk4_um_t)0xFFFFFFFFUL,
+ (dk4_um_t)1UL,
+ &er
+ ),
+ (dk4_um_t)(bhfi->nFileSizeHigh),
+ &er
+ ),
+ (dk4_um_t)(bhfi->nFileSizeLow),
+ &er
+ );
+ } else {
+ val = (dk4_um_t)(bhfi->nFileSizeLow);
+ }
+ if (DK4_E_NONE == er.ec) {
+
+#line 470 "dk4filei.ctr"
+ back = 1;
+ *dptr = val;
+ } else {
+
+#line 473 "dk4filei.ctr"
+ dk4error_copy(erp, &er);
+ }
+
+
+#line 476 "dk4filei.ctr"
+ return back;
+}
+#else
+static
+int
+dk4fileinfo_copy_size(
+ dk4_um_t *dptr,
+ const dk4_stat_t *stb,
+ dk4_er_t *erp
+)
+{
+ *dptr = (dk4_um_t)(stb->st_size);
+ return 1;
+}
+#endif
+
+
+int
+dk4fileinfo_size(
+ dk4_um_t *dptr,
+ const dk4_file_info_t *fi,
+ int ch,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er;
+ int back = 0;
+
+
+#line 504 "dk4filei.ctr"
+ if ((NULL != dptr) && (NULL != fi)) {
+
+#line 505 "dk4filei.ctr"
+ dk4error_init(&er);
+ switch (ch) {
+ case DK4_FILE_INFO_CONTENTS_DATA_LINK: {
+
+
+#line 509 "dk4filei.ctr"
+ if (0 != ((fi->contents) & DK4_FILE_INFO_CONTENTS_DATA_LINK)) {
+#if DK4_ON_WINDOWS
+
+
+#line 512 "dk4filei.ctr"
+ back = dk4fileinfo_copy_size(dptr, &(fi->linfo), &er);
+#else
+
+
+#line 515 "dk4filei.ctr"
+ back = dk4fileinfo_copy_size(dptr, &(fi->lstb), &er);
+#endif
+ } else {
+
+#line 518 "dk4filei.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } break;
+ default: {
+
+
+#line 523 "dk4filei.ctr"
+ if (0 != ((fi->contents) & DK4_FILE_INFO_CONTENTS_DATA_TARGET)) {
+#if DK4_ON_WINDOWS
+
+
+#line 526 "dk4filei.ctr"
+ back = dk4fileinfo_copy_size(dptr, &(fi->tinfo), &er);
+#else
+
+
+#line 529 "dk4filei.ctr"
+ back = dk4fileinfo_copy_size(dptr, &(fi->tstb), &er);
+#endif
+ } else {
+
+#line 532 "dk4filei.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } break;
+ }
+ if (0 != back) {
+ dk4error_copy(erp, &er);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 542 "dk4filei.ctr"
+ return back;
+}
+
+
+
+int
+dk4fileinfo_exists_and_is_regular(const dk4_file_info_t *fi, dk4_er_t *erp)
+{
+ int back = 0;
+ if (NULL != fi) {
+#if DK4_ON_WINDOWS
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & (fi->contents))) {
+ if ((DWORD)0UL == (FILE_ATTRIBUTE_DIRECTORY & fi->fattr)) {
+ if ((DWORD)0UL == (FILE_ATTRIBUTE_DEVICE & fi->fattr)) {
+ back = 1;
+ }
+ }
+ }
+#else
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & (fi->contents))) {
+ if (S_IFREG == (S_IFMT & ((fi->tstb).st_mode))) {
+ back = 1;
+ }
+ }
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4filei.ctr b/support/dktools/dk4filei.ctr
new file mode 100644
index 0000000000..f03a4b4735
--- /dev/null
+++ b/support/dktools/dk4filei.ctr
@@ -0,0 +1,572 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ Functions for file information.
+*/
+
+#ifndef DK4FILEIT_H_INCLUDED
+#include "dk4fileit.h"
+#endif
+
+#ifndef DK4UFI_H_INCLUDED
+#include "dk4ufi.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Initialize a file information structure.
+ @param dptr File information structure to initialize.
+*/
+void
+dk4fileinfo_init(dk4_file_info_t *dptr);
+
+/** Retrieve full information for a path name.
+ For symbolic links attempt to retrieve information both
+ about the link and about the link target.
+
+ CRT on Windows: Not used.
+ @param dptr Pointer to result structure.
+ @param fn File path name.
+ @param erp Error report, may be NULL.
+ @return 1 if information is found, 0 otherwise.
+ If information about the link is found and no information about
+ the target, the function returns 1 as we can recognize the
+ directory item as a dangling link (link with non-existing target).
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or fn is NULL,
+ - DK4_E_SYSTEM<br>
+ with errno value stored in iDetails1 if the stat() function
+ fails on non-Windows systems.
+ - DK4_E_SYSTEM<br>
+ with GetLastError() value stored in lDetails1 if the
+ GetFileAttributes() function failed,
+ - DK4_E_CREATE_FILE_FAILED<br>
+ with GetLastError() value stored in lDetails1 if the
+ CreateFile() function failed on Windows systems,
+ - DK4_E_FILE_INFORMATION_FAILED<br>
+ with GetLastError() value stored in lDetails1 if the
+ GetFileInformationByHandle() function failed on Windows systems,
+ - DK4_E_FINDFIRSTFILE_FAILED<br>
+ with GetLastError() value stored in lDetails1 if the
+ FindFirstFile() function failed on Windows systems.
+*/
+int
+dk4fileinfo_c8(dk4_file_info_t *dptr, const char *fn, dk4_er_t *erp);
+
+/** Retrieve full information for a path name.
+ For symbolic links attempt to retrieve information both
+ about the link and about the link target.
+
+ CRT on Windows: Not used.
+ @param dptr Pointer to result structure.
+ @param fn File path name.
+ @param erp Error report, may be NULL.
+ @return 1 if information is found, 0 otherwise.
+ If information about the link is found and no information about
+ the target, the function returns 1 as we can recognize the
+ directory item as a dangling link (link with non-existing target).
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or fn is NULL,
+ - DK4_E_SYSTEM<br>
+ with errno value stored in iDetails1 if the stat() function
+ fails on non-Windows systems.
+ - DK4_E_SYSTEM<br>
+ with GetLastError() value stored in lDetails1 if the
+ GetFileAttributes() function failed,
+ - DK4_E_CREATE_FILE_FAILED<br>
+ with GetLastError() value stored in lDetails1 if the
+ CreateFile() function failed on Windows systems,
+ - DK4_E_FILE_INFORMATION_FAILED<br>
+ with GetLastError() value stored in lDetails1 if the
+ GetFileInformationByHandle() function failed on Windows systems,
+ - DK4_E_FINDFIRSTFILE_FAILED<br>
+ with GetLastError() value stored in lDetails1 if the
+ FindFirstFile() function failed on Windows systems.
+*/
+int
+dk4fileinfo_wc(dk4_file_info_t *dptr, const wchar_t *fn, dk4_er_t *erp);
+
+/** Retrieve full information for a path name.
+ For symbolic links attempt to retrieve information both
+ about the link and about the link target.
+
+ CRT on Windows: Not used.
+ @param dptr Pointer to result structure.
+ @param fn File path name.
+ @param erp Error report, may be NULL.
+ @return 1 if information is found, 0 otherwise.
+ If information about the link is found and no information about
+ the target, the function returns 1 as we can recognize the
+ directory item as a dangling link (link with non-existing target).
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or fn is NULL,
+ - DK4_E_SYSTEM<br>
+ with errno value stored in iDetails1 if the stat() function
+ fails on non-Windows systems.
+ - DK4_E_SYSTEM<br>
+ with GetLastError() value stored in lDetails1 if the
+ GetFileAttributes() function failed,
+ - DK4_E_CREATE_FILE_FAILED<br>
+ with GetLastError() value stored in lDetails1 if the
+ CreateFile() function failed on Windows systems,
+ - DK4_E_FILE_INFORMATION_FAILED<br>
+ with GetLastError() value stored in lDetails1 if the
+ GetFileInformationByHandle() function failed on Windows systems,
+ - DK4_E_FINDFIRSTFILE_FAILED<br>
+ with GetLastError() value stored in lDetails1 if the
+ FindFirstFile() function failed on Windows systems.
+*/
+int
+dk4fileinfo(dk4_file_info_t *dptr, const dkChar *fn, dk4_er_t *erp);
+
+/** Retrieve timestamp from file information structure.
+ @param dptr Destination buffer pointer.
+ @param szdptr Destination buffer size.
+ @param fi File information structure.
+ @param chfile For symolic links, choose information source:
+ DK4_FILE_INFO_CONTENTS_DATA_LINK for the link
+ itself,
+ DK4_FILE_INFO_CONTENTS_DATA_TARGET for the link target.
+ @param chtime Choose timestamp:
+ DK4_FILE_INFO_TIME_CREATE for creation time,
+ DK4_FILE_INFO_TIME_MODIFY for modification time,
+ DK4_FILE_INFO_TIME_ACCESS for last access time.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or fi is NULL or szdptr is 0,
+ - DK4_E_NOT_FOUND<br>
+ if the required information is not found in the file information
+ structure.
+*/
+int
+dk4fileinfo_timestamp_c8(
+ char *dptr,
+ size_t szdptr,
+ const dk4_file_info_t *fi,
+ int chfile,
+ int chtime,
+ dk4_er_t *erp
+);
+
+/** Retrieve timestamp from file information structure.
+ @param dptr Destination buffer pointer.
+ @param szdptr Destination buffer size (number of wchar_t).
+ @param fi File information structure.
+ @param chfile For symolic links, choose information source:
+ DK4_FILE_INFO_CONTENTS_DATA_LINK for the link
+ itself,
+ DK4_FILE_INFO_CONTENTS_DATA_TARGET for the link target.
+ @param chtime Choose timestamp:
+ DK4_FILE_INFO_TIME_CREATE for creation time,
+ DK4_FILE_INFO_TIME_MODIFY for modification time,
+ DK4_FILE_INFO_TIME_ACCESS for last access time.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or fi is NULL or szdptr is 0,
+ - DK4_E_NOT_FOUND<br>
+ if the required information is not found in the file information
+ structure.
+*/
+int
+dk4fileinfo_timestamp_wc(
+ wchar_t *dptr,
+ size_t szdptr,
+ const dk4_file_info_t *fi,
+ int chfile,
+ int chtime,
+ dk4_er_t *erp
+);
+
+/** Retrieve timestamp from file information structure.
+ @param dptr Destination buffer pointer.
+ @param szdptr Destination buffer size (number of dkChar).
+ @param fi File information structure.
+ @param chfile For symolic links, choose information source:
+ DK4_FILE_INFO_CONTENTS_DATA_LINK for the link
+ itself,
+ DK4_FILE_INFO_CONTENTS_DATA_TARGET for the link target.
+ @param chtime Choose timestamp:
+ DK4_FILE_INFO_TIME_CREATE for creation time,
+ DK4_FILE_INFO_TIME_MODIFY for modification time,
+ DK4_FILE_INFO_TIME_ACCESS for last access time.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or fi is NULL or szdptr is 0,
+ - DK4_E_NOT_FOUND<br>
+ if the required information is not found in the file information
+ structure.
+*/
+int
+dk4fileinfo_timestamp(
+ dkChar *dptr,
+ size_t szdptr,
+ const dk4_file_info_t *fi,
+ int chfile,
+ int chtime,
+ dk4_er_t *erp
+);
+
+/** Retrieve file type and attributes (file attributes on Windows,
+ permissions on other systems).
+ @param dptr Destination buffer address.
+ @param szdptr Destination buffer size.
+ @param fi File information structure.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or fi is NULL or szdptr is 0,
+ - DK4_E_NOT_FOUND<br>
+ if the required information is not available in the file information.
+*/
+int
+dk4fileinfo_type_attributes_c8(
+ char *dptr,
+ size_t szdptr,
+ dk4_file_info_t *fi,
+ dk4_er_t *erp
+);
+
+/** Retrieve file type and attributes (file attributes on Windows,
+ permissions on other systems).
+ @param dptr Destination buffer address.
+ @param szdptr Destination buffer size (number of wchar_t).
+ @param fi File information structure.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or fi is NULL or szdptr is 0,
+ - DK4_E_NOT_FOUND<br>
+ if the required information is not available in the file information.
+*/
+int
+dk4fileinfo_type_attributes_wc(
+ wchar_t *dptr,
+ size_t szdptr,
+ dk4_file_info_t *fi,
+ dk4_er_t *erp
+);
+
+/** Retrieve file type and attributes (file attributes on Windows,
+ permissions on other systems).
+ @param dptr Destination buffer address.
+ @param szdptr Destination buffer size (number of dkChar).
+ @param fi File information structure.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or fi is NULL or szdptr is 0,
+ - DK4_E_NOT_FOUND<br>
+ if the required information is not available in the file information.
+*/
+int
+dk4fileinfo_type_attributes(
+ dkChar *dptr,
+ size_t szdptr,
+ dk4_file_info_t *fi,
+ dk4_er_t *erp
+);
+
+/** Retrieve unique file identifier from file information structure.
+ @param dptr Pointer to destination variable.
+ @param src File information structure to retrieve information from.
+ @param ch For symbolic links choose between information
+ for link itself (DK4_FILE_INFO_CONTENTS_DATA_LINK)
+ or link target (DK4_FILE_INFO_CONTENTS_DATA_TARGET).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or src is NULL,
+ - DK4_E_NOT_FOUND<br>
+ if the information is not present in the file information structure.
+*/
+int
+dk4fileinfo_ufi(
+ dk4_ufi_t *dptr, const dk4_file_info_t *src, int ch, dk4_er_t *erp
+);
+
+/** Check whether the file information structure represents a
+ symbolic link.
+ @param dptr File information structure to check.
+ @return 1 for symbolic links, 0 otherwise.
+*/
+int
+dk4fileinfo_is_symlink(const dk4_file_info_t *dptr);
+
+/** Retrieve file size.
+ @param dptr Pointer to result variable.
+ @param fi File information structure.
+ @param ch Choose information source for symbolic links:
+ DK4_FILE_INFO_CONTENTS_DATA_LINK for the size
+ of the link itself,
+ DK4_FILE_INFO_CONTENTS_DATA_TARGET for the size
+ of the link target.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or fi is NULL,
+ - DK4_E_NOT_FOUND<br>
+ if the required information is not available in the file
+ information structure,
+ - DK4_E_MATH_OVERFLOW<br>
+ if the size calculation results in a numeric overflow.
+*/
+int
+dk4fileinfo_size(
+ dk4_um_t *dptr,
+ const dk4_file_info_t *fi,
+ int ch,
+ dk4_er_t *erp
+);
+
+/** Check whether the file exists and is a regular file.
+ For a symbolic link, the target must exist and be a regular file.
+ @param fi File information already obtained for the file.
+ @param erp Error report, may be NULL.
+ @return 1 if the file exists and is a regular file.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fi is NULL.
+*/
+int
+dk4fileinfo_exists_and_is_regular(const dk4_file_info_t *fi, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4filei.h"
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4MAADU_H_INCLUDED
+#include "dk4maadu.h"
+#endif
+
+
+
+$!trace-include
+
+
+
+void
+dk4fileinfo_init(dk4_file_info_t *dptr)
+{
+ if (NULL != dptr) {
+ DK4_MEMRES(dptr, sizeof(dk4_file_info_t));
+ dptr->contents = 0;
+ }
+}
+
+
+
+int
+dk4fileinfo_is_symlink(const dk4_file_info_t *dptr)
+{
+ int back = 0;
+ if (NULL != dptr) {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & (dptr->contents))) {
+#if DK4_ON_WINDOWS
+ if (0 != (FILE_ATTRIBUTE_REPARSE_POINT & (dptr->fattr))) {
+ if (IO_REPARSE_TAG_MOUNT_POINT == dptr->rppnt) {
+ back = 1;
+ }
+ if (IO_REPARSE_TAG_SYMLINK == dptr->rppnt) {
+ back = 1;
+ }
+ }
+#else
+#if defined(S_IFMT) && defined (S_IFLNK)
+ if (S_IFLNK == (S_IFMT & ((dptr->lstb).st_mode))) {
+ back = 1;
+ }
+#endif
+#endif
+ }
+ }
+ return back;
+}
+
+
+
+#if DK4_ON_WINDOWS
+static
+int
+dk4fileinfo_copy_size(
+ dk4_um_t *dptr,
+ const BY_HANDLE_FILE_INFORMATION *bhfi,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er;
+ dk4_um_t val;
+ int back = 0;
+ $? "+ dk4fileinfo_copy_size"
+ dk4error_init(&er);
+ $? ". high %lu", (unsigned long)(bhfi->nFileSizeHigh)
+ $? ". low %lu", (unsigned long)(bhfi->nFileSizeLow)
+ if ((DWORD)0UL != bhfi->nFileSizeHigh) {
+ val = dk4ma_um_add(
+ dk4ma_um_mul(
+ dk4ma_um_add(
+ (dk4_um_t)0xFFFFFFFFUL,
+ (dk4_um_t)1UL,
+ &er
+ ),
+ (dk4_um_t)(bhfi->nFileSizeHigh),
+ &er
+ ),
+ (dk4_um_t)(bhfi->nFileSizeLow),
+ &er
+ );
+ } else {
+ val = (dk4_um_t)(bhfi->nFileSizeLow);
+ }
+ if (DK4_E_NONE == er.ec) { $? ". no overflow"
+ back = 1;
+ *dptr = val;
+ } else { $? "! overflow"
+ dk4error_copy(erp, &er);
+ }
+ $? "- dk4fileinfo_copy_size %d", back
+ return back;
+}
+#else
+static
+int
+dk4fileinfo_copy_size(
+ dk4_um_t *dptr,
+ const dk4_stat_t *stb,
+ dk4_er_t *erp
+)
+{
+ *dptr = (dk4_um_t)(stb->st_size);
+ return 1;
+}
+#endif
+
+
+int
+dk4fileinfo_size(
+ dk4_um_t *dptr,
+ const dk4_file_info_t *fi,
+ int ch,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er;
+ int back = 0;
+ $? "+ dk4fileinfo_size"
+ if ((NULL != dptr) && (NULL != fi)) { $? ". args ok"
+ dk4error_init(&er);
+ switch (ch) {
+ case DK4_FILE_INFO_CONTENTS_DATA_LINK: {
+ $? ". link"
+ if (0 != ((fi->contents) & DK4_FILE_INFO_CONTENTS_DATA_LINK)) {
+#if DK4_ON_WINDOWS
+ $? ". windows"
+ back = dk4fileinfo_copy_size(dptr, &(fi->linfo), &er);
+#else
+ $? ". non-Windows"
+ back = dk4fileinfo_copy_size(dptr, &(fi->lstb), &er);
+#endif
+ } else { $? "! no data stored"
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } break;
+ default: {
+ $? ". link target"
+ if (0 != ((fi->contents) & DK4_FILE_INFO_CONTENTS_DATA_TARGET)) {
+#if DK4_ON_WINDOWS
+ $? ". Windows"
+ back = dk4fileinfo_copy_size(dptr, &(fi->tinfo), &er);
+#else
+ $? ". non-Windows"
+ back = dk4fileinfo_copy_size(dptr, &(fi->tstb), &er);
+#endif
+ } else { $? "! no data stored"
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } break;
+ }
+ if (0 != back) {
+ dk4error_copy(erp, &er);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4fileinfo_size %d", back
+ return back;
+}
+
+
+
+int
+dk4fileinfo_exists_and_is_regular(const dk4_file_info_t *fi, dk4_er_t *erp)
+{
+ int back = 0;
+ if (NULL != fi) {
+#if DK4_ON_WINDOWS
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & (fi->contents))) {
+ if ((DWORD)0UL == (FILE_ATTRIBUTE_DIRECTORY & fi->fattr)) {
+ if ((DWORD)0UL == (FILE_ATTRIBUTE_DEVICE & fi->fattr)) {
+ back = 1;
+ }
+ }
+ }
+#else
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & (fi->contents))) {
+ if (S_IFREG == (S_IFMT & ((fi->tstb).st_mode))) {
+ back = 1;
+ }
+ }
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4filei.h b/support/dktools/dk4filei.h
new file mode 100644
index 0000000000..9437cc67c0
--- /dev/null
+++ b/support/dktools/dk4filei.h
@@ -0,0 +1,412 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4filei.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4FILEI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4FILEI_H_INCLUDED 1
+
+
+#line 9 "dk4filei.ctr"
+
+/** @file
+ Functions for file information.
+*/
+
+#ifndef DK4FILEIT_H_INCLUDED
+#include "dk4fileit.h"
+#endif
+
+#ifndef DK4UFI_H_INCLUDED
+#include "dk4ufi.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Initialize a file information structure.
+ @param dptr File information structure to initialize.
+*/
+void
+dk4fileinfo_init(dk4_file_info_t *dptr);
+
+/** Retrieve full information for a path name.
+ For symbolic links attempt to retrieve information both
+ about the link and about the link target.
+
+ CRT on Windows: Not used.
+ @param dptr Pointer to result structure.
+ @param fn File path name.
+ @param erp Error report, may be NULL.
+ @return 1 if information is found, 0 otherwise.
+ If information about the link is found and no information about
+ the target, the function returns 1 as we can recognize the
+ directory item as a dangling link (link with non-existing target).
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or fn is NULL,
+ - DK4_E_SYSTEM<br>
+ with errno value stored in iDetails1 if the stat() function
+ fails on non-Windows systems.
+ - DK4_E_SYSTEM<br>
+ with GetLastError() value stored in lDetails1 if the
+ GetFileAttributes() function failed,
+ - DK4_E_CREATE_FILE_FAILED<br>
+ with GetLastError() value stored in lDetails1 if the
+ CreateFile() function failed on Windows systems,
+ - DK4_E_FILE_INFORMATION_FAILED<br>
+ with GetLastError() value stored in lDetails1 if the
+ GetFileInformationByHandle() function failed on Windows systems,
+ - DK4_E_FINDFIRSTFILE_FAILED<br>
+ with GetLastError() value stored in lDetails1 if the
+ FindFirstFile() function failed on Windows systems.
+*/
+int
+dk4fileinfo_c8(dk4_file_info_t *dptr, const char *fn, dk4_er_t *erp);
+
+/** Retrieve full information for a path name.
+ For symbolic links attempt to retrieve information both
+ about the link and about the link target.
+
+ CRT on Windows: Not used.
+ @param dptr Pointer to result structure.
+ @param fn File path name.
+ @param erp Error report, may be NULL.
+ @return 1 if information is found, 0 otherwise.
+ If information about the link is found and no information about
+ the target, the function returns 1 as we can recognize the
+ directory item as a dangling link (link with non-existing target).
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or fn is NULL,
+ - DK4_E_SYSTEM<br>
+ with errno value stored in iDetails1 if the stat() function
+ fails on non-Windows systems.
+ - DK4_E_SYSTEM<br>
+ with GetLastError() value stored in lDetails1 if the
+ GetFileAttributes() function failed,
+ - DK4_E_CREATE_FILE_FAILED<br>
+ with GetLastError() value stored in lDetails1 if the
+ CreateFile() function failed on Windows systems,
+ - DK4_E_FILE_INFORMATION_FAILED<br>
+ with GetLastError() value stored in lDetails1 if the
+ GetFileInformationByHandle() function failed on Windows systems,
+ - DK4_E_FINDFIRSTFILE_FAILED<br>
+ with GetLastError() value stored in lDetails1 if the
+ FindFirstFile() function failed on Windows systems.
+*/
+int
+dk4fileinfo_wc(dk4_file_info_t *dptr, const wchar_t *fn, dk4_er_t *erp);
+
+/** Retrieve full information for a path name.
+ For symbolic links attempt to retrieve information both
+ about the link and about the link target.
+
+ CRT on Windows: Not used.
+ @param dptr Pointer to result structure.
+ @param fn File path name.
+ @param erp Error report, may be NULL.
+ @return 1 if information is found, 0 otherwise.
+ If information about the link is found and no information about
+ the target, the function returns 1 as we can recognize the
+ directory item as a dangling link (link with non-existing target).
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or fn is NULL,
+ - DK4_E_SYSTEM<br>
+ with errno value stored in iDetails1 if the stat() function
+ fails on non-Windows systems.
+ - DK4_E_SYSTEM<br>
+ with GetLastError() value stored in lDetails1 if the
+ GetFileAttributes() function failed,
+ - DK4_E_CREATE_FILE_FAILED<br>
+ with GetLastError() value stored in lDetails1 if the
+ CreateFile() function failed on Windows systems,
+ - DK4_E_FILE_INFORMATION_FAILED<br>
+ with GetLastError() value stored in lDetails1 if the
+ GetFileInformationByHandle() function failed on Windows systems,
+ - DK4_E_FINDFIRSTFILE_FAILED<br>
+ with GetLastError() value stored in lDetails1 if the
+ FindFirstFile() function failed on Windows systems.
+*/
+int
+dk4fileinfo(dk4_file_info_t *dptr, const dkChar *fn, dk4_er_t *erp);
+
+/** Retrieve timestamp from file information structure.
+ @param dptr Destination buffer pointer.
+ @param szdptr Destination buffer size.
+ @param fi File information structure.
+ @param chfile For symolic links, choose information source:
+ DK4_FILE_INFO_CONTENTS_DATA_LINK for the link
+ itself,
+ DK4_FILE_INFO_CONTENTS_DATA_TARGET for the link target.
+ @param chtime Choose timestamp:
+ DK4_FILE_INFO_TIME_CREATE for creation time,
+ DK4_FILE_INFO_TIME_MODIFY for modification time,
+ DK4_FILE_INFO_TIME_ACCESS for last access time.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or fi is NULL or szdptr is 0,
+ - DK4_E_NOT_FOUND<br>
+ if the required information is not found in the file information
+ structure.
+*/
+int
+dk4fileinfo_timestamp_c8(
+ char *dptr,
+ size_t szdptr,
+ const dk4_file_info_t *fi,
+ int chfile,
+ int chtime,
+ dk4_er_t *erp
+);
+
+/** Retrieve timestamp from file information structure.
+ @param dptr Destination buffer pointer.
+ @param szdptr Destination buffer size (number of wchar_t).
+ @param fi File information structure.
+ @param chfile For symolic links, choose information source:
+ DK4_FILE_INFO_CONTENTS_DATA_LINK for the link
+ itself,
+ DK4_FILE_INFO_CONTENTS_DATA_TARGET for the link target.
+ @param chtime Choose timestamp:
+ DK4_FILE_INFO_TIME_CREATE for creation time,
+ DK4_FILE_INFO_TIME_MODIFY for modification time,
+ DK4_FILE_INFO_TIME_ACCESS for last access time.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or fi is NULL or szdptr is 0,
+ - DK4_E_NOT_FOUND<br>
+ if the required information is not found in the file information
+ structure.
+*/
+int
+dk4fileinfo_timestamp_wc(
+ wchar_t *dptr,
+ size_t szdptr,
+ const dk4_file_info_t *fi,
+ int chfile,
+ int chtime,
+ dk4_er_t *erp
+);
+
+/** Retrieve timestamp from file information structure.
+ @param dptr Destination buffer pointer.
+ @param szdptr Destination buffer size (number of dkChar).
+ @param fi File information structure.
+ @param chfile For symolic links, choose information source:
+ DK4_FILE_INFO_CONTENTS_DATA_LINK for the link
+ itself,
+ DK4_FILE_INFO_CONTENTS_DATA_TARGET for the link target.
+ @param chtime Choose timestamp:
+ DK4_FILE_INFO_TIME_CREATE for creation time,
+ DK4_FILE_INFO_TIME_MODIFY for modification time,
+ DK4_FILE_INFO_TIME_ACCESS for last access time.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or fi is NULL or szdptr is 0,
+ - DK4_E_NOT_FOUND<br>
+ if the required information is not found in the file information
+ structure.
+*/
+int
+dk4fileinfo_timestamp(
+ dkChar *dptr,
+ size_t szdptr,
+ const dk4_file_info_t *fi,
+ int chfile,
+ int chtime,
+ dk4_er_t *erp
+);
+
+/** Retrieve file type and attributes (file attributes on Windows,
+ permissions on other systems).
+ @param dptr Destination buffer address.
+ @param szdptr Destination buffer size.
+ @param fi File information structure.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or fi is NULL or szdptr is 0,
+ - DK4_E_NOT_FOUND<br>
+ if the required information is not available in the file information.
+*/
+int
+dk4fileinfo_type_attributes_c8(
+ char *dptr,
+ size_t szdptr,
+ dk4_file_info_t *fi,
+ dk4_er_t *erp
+);
+
+/** Retrieve file type and attributes (file attributes on Windows,
+ permissions on other systems).
+ @param dptr Destination buffer address.
+ @param szdptr Destination buffer size (number of wchar_t).
+ @param fi File information structure.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or fi is NULL or szdptr is 0,
+ - DK4_E_NOT_FOUND<br>
+ if the required information is not available in the file information.
+*/
+int
+dk4fileinfo_type_attributes_wc(
+ wchar_t *dptr,
+ size_t szdptr,
+ dk4_file_info_t *fi,
+ dk4_er_t *erp
+);
+
+/** Retrieve file type and attributes (file attributes on Windows,
+ permissions on other systems).
+ @param dptr Destination buffer address.
+ @param szdptr Destination buffer size (number of dkChar).
+ @param fi File information structure.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or fi is NULL or szdptr is 0,
+ - DK4_E_NOT_FOUND<br>
+ if the required information is not available in the file information.
+*/
+int
+dk4fileinfo_type_attributes(
+ dkChar *dptr,
+ size_t szdptr,
+ dk4_file_info_t *fi,
+ dk4_er_t *erp
+);
+
+/** Retrieve unique file identifier from file information structure.
+ @param dptr Pointer to destination variable.
+ @param src File information structure to retrieve information from.
+ @param ch For symbolic links choose between information
+ for link itself (DK4_FILE_INFO_CONTENTS_DATA_LINK)
+ or link target (DK4_FILE_INFO_CONTENTS_DATA_TARGET).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or src is NULL,
+ - DK4_E_NOT_FOUND<br>
+ if the information is not present in the file information structure.
+*/
+int
+dk4fileinfo_ufi(
+ dk4_ufi_t *dptr, const dk4_file_info_t *src, int ch, dk4_er_t *erp
+);
+
+/** Check whether the file information structure represents a
+ symbolic link.
+ @param dptr File information structure to check.
+ @return 1 for symbolic links, 0 otherwise.
+*/
+int
+dk4fileinfo_is_symlink(const dk4_file_info_t *dptr);
+
+/** Retrieve file size.
+ @param dptr Pointer to result variable.
+ @param fi File information structure.
+ @param ch Choose information source for symbolic links:
+ DK4_FILE_INFO_CONTENTS_DATA_LINK for the size
+ of the link itself,
+ DK4_FILE_INFO_CONTENTS_DATA_TARGET for the size
+ of the link target.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or fi is NULL,
+ - DK4_E_NOT_FOUND<br>
+ if the required information is not available in the file
+ information structure,
+ - DK4_E_MATH_OVERFLOW<br>
+ if the size calculation results in a numeric overflow.
+*/
+int
+dk4fileinfo_size(
+ dk4_um_t *dptr,
+ const dk4_file_info_t *fi,
+ int ch,
+ dk4_er_t *erp
+);
+
+/** Check whether the file exists and is a regular file.
+ For a symbolic link, the target must exist and be a regular file.
+ @param fi File information already obtained for the file.
+ @param erp Error report, may be NULL.
+ @return 1 if the file exists and is a regular file.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fi is NULL.
+*/
+int
+dk4fileinfo_exists_and_is_regular(const dk4_file_info_t *fi, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4filei8.c b/support/dktools/dk4filei8.c
new file mode 100644
index 0000000000..5c1cccdd48
--- /dev/null
+++ b/support/dktools/dk4filei8.c
@@ -0,0 +1,228 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4filei8.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4filei8.c The dk4filei8 module.
+*/
+
+
+#line 10 "dk4filei8.ctr"
+
+#include "dk4filei.h"
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4STAT8_H_INCLUDED
+#include "dk4stat8.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+int
+dk4fileinfo_c8(dk4_file_info_t *dptr, const char *fn, dk4_er_t *erp)
+{
+ dk4_er_t er;
+#if DK4_ON_WINDOWS
+ WIN32_FIND_DATAA ffdata;
+ HANDLE ha;
+ DWORD dwatt;
+ int i;
+ int found;
+ int isdir;
+#endif
+ int back = 0;
+ if ((NULL != dptr) && (NULL != fn)) {
+ dk4error_init(&er);
+ DK4_MEMRES(dptr, sizeof(dk4_file_info_t));
+ dptr->contents = 0;
+#if DK4_ON_WINDOWS
+ dptr->rppnt = (DWORD)0UL;
+ dptr->fattr = GetFileAttributesA(fn);
+ dptr->resio = 0UL;
+ if (INVALID_FILE_ATTRIBUTES == dptr->fattr) {
+ ha = FindFirstFileA(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != ha) {
+ dptr->fattr = ffdata.dwFileAttributes;
+ FindClose(ha);
+ }
+ }
+ if (INVALID_FILE_ATTRIBUTES != dptr->fattr) {
+ isdir = 0;
+ if (0 != (FILE_ATTRIBUTE_DIRECTORY & (dptr->fattr))) { isdir = 1; }
+ /* Symlink */
+ found = 0;
+ for (i = 0; ((3 > i) && (0 == found)); i++) {
+ dwatt = dptr->fattr;
+ dwatt |= FILE_FLAG_OPEN_REPARSE_POINT;
+ if (0 != isdir) { dwatt |= FILE_FLAG_BACKUP_SEMANTICS; }
+ ha = CreateFileA(
+ fn,
+ (
+ (0 == i)
+ ? (0) : ((1 == i) ? (FILE_READ_ATTRIBUTES) : (GENERIC_READ))
+ ),
+ (FILE_SHARE_READ | FILE_SHARE_WRITE),
+ NULL,
+ OPEN_EXISTING,
+ dwatt,
+ NULL
+ );
+ if (INVALID_HANDLE_VALUE != ha) {
+ if (GetFileInformationByHandle(ha, &(dptr->linfo))) {
+ found = 1;
+ back = 1;
+ dptr->contents |= DK4_FILE_INFO_CONTENTS_DATA_LINK;
+ } else {
+ if (1 == i) {
+ dk4error_set_ldetails(
+ &er, DK4_E_FILE_INFORMATION_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ }
+ CloseHandle(ha);
+ } else {
+ if (1 == i) {
+ dk4error_set_ldetails(
+ &er, DK4_E_CREATE_FILE_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ }
+ }
+ /* Target */
+ found = 0;
+ for (i = 0; ((3 > i) && (0 == found)); i++) {
+ dwatt = dptr->fattr;
+ if (0 != isdir) { dwatt |= FILE_FLAG_BACKUP_SEMANTICS; }
+ ha = CreateFileA(
+ fn,
+ (
+ (0 == i)
+ ? (0)
+ : ((1 == i) ? (FILE_READ_ATTRIBUTES) : (GENERIC_READ))
+ ),
+ (FILE_SHARE_READ | FILE_SHARE_WRITE),
+ NULL,
+ OPEN_EXISTING,
+ dwatt,
+ NULL
+ );
+ if (INVALID_HANDLE_VALUE != ha) {
+ if (GetFileInformationByHandle(ha, &(dptr->tinfo))) {
+ found = 1;
+ back = 1;
+ dptr->contents |= DK4_FILE_INFO_CONTENTS_DATA_TARGET;
+ } else {
+ if (1 == i) {
+ dk4error_set_ldetails(
+ &er, DK4_E_FILE_INFORMATION_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ }
+ CloseHandle(ha);
+ } else {
+ if (1 == i) {
+ dk4error_set_ldetails(
+ &er, DK4_E_CREATE_FILE_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ }
+ }
+ /* FindFirstFile */
+ if (0 != back) {
+ ha = FindFirstFileA(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != ha) {
+ back = 1;
+ dptr->fattr = ffdata.dwFileAttributes;
+ dptr->rppnt = ffdata.dwReserved0;
+ FindClose(ha);
+ }
+ } else {
+ ha = FindFirstFileA(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != ha) {
+ back = 1;
+ dptr->fattr = ffdata.dwFileAttributes;
+ dptr->rppnt = ffdata.dwReserved0;
+ dptr->resio = 1UL;
+ (dptr->linfo).dwFileAttributes = ffdata.dwFileAttributes;
+ (dptr->linfo).ftCreationTime = ffdata.ftCreationTime;
+ (dptr->linfo).ftLastAccessTime = ffdata.ftLastAccessTime;
+ (dptr->linfo).ftLastWriteTime = ffdata.ftLastWriteTime;
+ (dptr->linfo).nFileSizeHigh = ffdata.nFileSizeHigh;
+ (dptr->linfo).nFileSizeLow = ffdata.nFileSizeLow;
+ (dptr->tinfo).dwFileAttributes = ffdata.dwFileAttributes;
+ (dptr->tinfo).ftCreationTime = ffdata.ftCreationTime;
+ (dptr->tinfo).ftLastAccessTime = ffdata.ftLastAccessTime;
+ (dptr->tinfo).ftLastWriteTime = ffdata.ftLastWriteTime;
+ (dptr->tinfo).nFileSizeHigh = ffdata.nFileSizeHigh;
+ (dptr->tinfo).nFileSizeLow = ffdata.nFileSizeLow;
+ dptr->contents |= DK4_FILE_INFO_CONTENTS_DATA_TARGET;
+ dptr->contents |= DK4_FILE_INFO_CONTENTS_DATA_LINK;
+ FindClose(ha);
+ }
+ }
+ } else {
+ dk4error_set_ldetails(
+ &er, DK4_E_SYSTEM,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+#else
+ if (0 != dk4stat_l_c8(&(dptr->lstb), fn, &er)) {
+ back = 1;
+ dptr->contents |= DK4_FILE_INFO_CONTENTS_DATA_LINK;
+ }
+ if (0 != dk4stat_c8(&(dptr->tstb), fn, &er)) {
+ back = 1;
+ dptr->contents |= DK4_FILE_INFO_CONTENTS_DATA_TARGET;
+ }
+#endif
+ if (0 == back) {
+ dk4error_copy(erp, &er);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4filei8.ctr b/support/dktools/dk4filei8.ctr
new file mode 100644
index 0000000000..4cb6c4a86b
--- /dev/null
+++ b/support/dktools/dk4filei8.ctr
@@ -0,0 +1,197 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4filei.h"
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4STAT8_H_INCLUDED
+#include "dk4stat8.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+int
+dk4fileinfo_c8(dk4_file_info_t *dptr, const char *fn, dk4_er_t *erp)
+{
+ dk4_er_t er;
+#if DK4_ON_WINDOWS
+ WIN32_FIND_DATAA ffdata;
+ HANDLE ha;
+ DWORD dwatt;
+ int i;
+ int found;
+ int isdir;
+#endif
+ int back = 0;
+ if ((NULL != dptr) && (NULL != fn)) {
+ dk4error_init(&er);
+ DK4_MEMRES(dptr, sizeof(dk4_file_info_t));
+ dptr->contents = 0;
+#if DK4_ON_WINDOWS
+ dptr->rppnt = (DWORD)0UL;
+ dptr->fattr = GetFileAttributesA(fn);
+ dptr->resio = 0UL;
+ if (INVALID_FILE_ATTRIBUTES == dptr->fattr) {
+ ha = FindFirstFileA(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != ha) {
+ dptr->fattr = ffdata.dwFileAttributes;
+ FindClose(ha);
+ }
+ }
+ if (INVALID_FILE_ATTRIBUTES != dptr->fattr) {
+ isdir = 0;
+ if (0 != (FILE_ATTRIBUTE_DIRECTORY & (dptr->fattr))) { isdir = 1; }
+ /* Symlink */
+ found = 0;
+ for (i = 0; ((3 > i) && (0 == found)); i++) {
+ dwatt = dptr->fattr;
+ dwatt |= FILE_FLAG_OPEN_REPARSE_POINT;
+ if (0 != isdir) { dwatt |= FILE_FLAG_BACKUP_SEMANTICS; }
+ ha = CreateFileA(
+ fn,
+ (
+ (0 == i)
+ ? (0) : ((1 == i) ? (FILE_READ_ATTRIBUTES) : (GENERIC_READ))
+ ),
+ (FILE_SHARE_READ | FILE_SHARE_WRITE),
+ NULL,
+ OPEN_EXISTING,
+ dwatt,
+ NULL
+ );
+ if (INVALID_HANDLE_VALUE != ha) {
+ if (GetFileInformationByHandle(ha, &(dptr->linfo))) {
+ found = 1;
+ back = 1;
+ dptr->contents |= DK4_FILE_INFO_CONTENTS_DATA_LINK;
+ } else {
+ if (1 == i) {
+ dk4error_set_ldetails(
+ &er, DK4_E_FILE_INFORMATION_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ }
+ CloseHandle(ha);
+ } else {
+ if (1 == i) {
+ dk4error_set_ldetails(
+ &er, DK4_E_CREATE_FILE_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ }
+ }
+ /* Target */
+ found = 0;
+ for (i = 0; ((3 > i) && (0 == found)); i++) {
+ dwatt = dptr->fattr;
+ if (0 != isdir) { dwatt |= FILE_FLAG_BACKUP_SEMANTICS; }
+ ha = CreateFileA(
+ fn,
+ (
+ (0 == i)
+ ? (0)
+ : ((1 == i) ? (FILE_READ_ATTRIBUTES) : (GENERIC_READ))
+ ),
+ (FILE_SHARE_READ | FILE_SHARE_WRITE),
+ NULL,
+ OPEN_EXISTING,
+ dwatt,
+ NULL
+ );
+ if (INVALID_HANDLE_VALUE != ha) {
+ if (GetFileInformationByHandle(ha, &(dptr->tinfo))) {
+ found = 1;
+ back = 1;
+ dptr->contents |= DK4_FILE_INFO_CONTENTS_DATA_TARGET;
+ } else {
+ if (1 == i) {
+ dk4error_set_ldetails(
+ &er, DK4_E_FILE_INFORMATION_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ }
+ CloseHandle(ha);
+ } else {
+ if (1 == i) {
+ dk4error_set_ldetails(
+ &er, DK4_E_CREATE_FILE_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ }
+ }
+ /* FindFirstFile */
+ if (0 != back) {
+ ha = FindFirstFileA(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != ha) {
+ back = 1;
+ dptr->fattr = ffdata.dwFileAttributes;
+ dptr->rppnt = ffdata.dwReserved0;
+ FindClose(ha);
+ }
+ } else {
+ ha = FindFirstFileA(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != ha) {
+ back = 1;
+ dptr->fattr = ffdata.dwFileAttributes;
+ dptr->rppnt = ffdata.dwReserved0;
+ dptr->resio = 1UL;
+ (dptr->linfo).dwFileAttributes = ffdata.dwFileAttributes;
+ (dptr->linfo).ftCreationTime = ffdata.ftCreationTime;
+ (dptr->linfo).ftLastAccessTime = ffdata.ftLastAccessTime;
+ (dptr->linfo).ftLastWriteTime = ffdata.ftLastWriteTime;
+ (dptr->linfo).nFileSizeHigh = ffdata.nFileSizeHigh;
+ (dptr->linfo).nFileSizeLow = ffdata.nFileSizeLow;
+ (dptr->tinfo).dwFileAttributes = ffdata.dwFileAttributes;
+ (dptr->tinfo).ftCreationTime = ffdata.ftCreationTime;
+ (dptr->tinfo).ftLastAccessTime = ffdata.ftLastAccessTime;
+ (dptr->tinfo).ftLastWriteTime = ffdata.ftLastWriteTime;
+ (dptr->tinfo).nFileSizeHigh = ffdata.nFileSizeHigh;
+ (dptr->tinfo).nFileSizeLow = ffdata.nFileSizeLow;
+ dptr->contents |= DK4_FILE_INFO_CONTENTS_DATA_TARGET;
+ dptr->contents |= DK4_FILE_INFO_CONTENTS_DATA_LINK;
+ FindClose(ha);
+ }
+ }
+ } else {
+ dk4error_set_ldetails(
+ &er, DK4_E_SYSTEM,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+#else
+ if (0 != dk4stat_l_c8(&(dptr->lstb), fn, &er)) {
+ back = 1;
+ dptr->contents |= DK4_FILE_INFO_CONTENTS_DATA_LINK;
+ }
+ if (0 != dk4stat_c8(&(dptr->tstb), fn, &er)) {
+ back = 1;
+ dptr->contents |= DK4_FILE_INFO_CONTENTS_DATA_TARGET;
+ }
+#endif
+ if (0 == back) {
+ dk4error_copy(erp, &er);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4filei8.h b/support/dktools/dk4filei8.h
new file mode 100644
index 0000000000..89b738b838
--- /dev/null
+++ b/support/dktools/dk4filei8.h
@@ -0,0 +1,78 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4filei8.ctr
+*/
+
+/*
+Copyright (C) 2015, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4FILEI8_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4FILEI8_H_INCLUDED 1
+
+
+#line 10 "dk4filei8.ctr"
+
+/** @file dk4filei8.h File information for files specified
+ by char path name.
+*/
+
+#ifndef DK4FILEIT_H_INCLUDED
+#include "dk4fileit.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve full information for a path name.
+ For symbolic links attempt to retrieve information both
+ about the link and about the link target.
+ @param dptr Pointer to result structure.
+ @param fn File path name.
+ @param erp Error report, may be NULL.
+ @return 1 if information is found, 0 otherwise.
+ If information about the link is found and no information about
+ the target, the function returns 1 as we can recognize the
+ directory item as a dangling link (link with non-existing target).
+*/
+int
+dk4fileinfo_c8(dk4_file_info_t *dptr, const char *fn, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4fileia.c b/support/dktools/dk4fileia.c
new file mode 100644
index 0000000000..d48617702d
--- /dev/null
+++ b/support/dktools/dk4fileia.c
@@ -0,0 +1,228 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fileia.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4fileia.c The dk4fileia module.
+*/
+
+
+#line 59 "dk4fileia.ctr"
+
+#include "dk4conf.h"
+#include "dk4const.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4filei.h"
+#include "dk4fileia.h"
+#include "dk4error.h"
+#include "dk4mem.h"
+
+#if DK4_ON_WINDOWS
+#include "dk4maodd.h"
+#include "dk4maodh.h"
+#endif
+
+
+
+
+
+#line 90 "dk4fileia.ctr"
+
+
+
+#if DK4_ON_WINDOWS
+void
+dk4fileinfo_report_win_failed(dk4_app_t *app, const dkChar *path, long errc)
+{
+ dkChar eb1[8 * sizeof(DWORD) + 16];
+ dkChar eb2[8 * sizeof(DWORD) + 16];
+ int res = 0;
+ int found = 0;
+
+ if (ERROR_FILE_NOT_FOUND == errc) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 149, 51, path);
+ found = 1;
+ goto finished;
+ }
+ if (ERROR_PATH_NOT_FOUND == errc) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 149, 51, path);
+ found = 1;
+ goto finished;
+ }
+ if (ERROR_ACCESS_DENIED == errc) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 149, 55, path);
+ found = 1;
+ goto finished;
+ }
+ if (ERROR_BAD_NET_NAME == errc) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 149, 74, path);
+ found = 1;
+ goto finished;
+ }
+ if (ERROR_BAD_NETPATH == errc) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 149, 75, path);
+ found = 1;
+ goto finished;
+ }
+ if (ERROR_SHARING_VIOLATION == errc) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 149, 151, path);
+ found = 1;
+ goto finished;
+ }
+ if (0 == found) {
+ res = dk4ma_write_decimal_unsigned(
+ eb1, DK4_SIZEOF(eb1,dkChar), (dk4_um_t)(errc), 0, NULL
+ );
+ if (0 != res) {
+ res = dk4ma_write_hex_unsigned(
+ eb2, DK4_SIZEOF(eb2,dkChar), (dk4_um_t)(errc),
+ 0, NULL
+ );
+ }
+ if (0 != res) {
+ dk4app_log_base7(app,DK4_LL_ERROR,149,69,70,71,path,eb1,eb2);
+ } else {
+ dk4app_log_base3(app, DK4_LL_ERROR, 149, 40, path);
+ }
+ }
+ finished: ;
+}
+#endif
+
+
+
+void
+dk4fileinfo_report_stat_failed(dk4_app_t *app, const dkChar *path, int errc)
+{
+
+
+#line 158 "dk4fileia.ctr"
+ switch (errc) {
+#ifdef EACCES
+ case EACCES : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 149, 138, path);
+ } break;
+#endif
+#ifdef EFAULT
+ case EFAULT : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 149, 123, path);
+ } break;
+#endif
+#ifdef ELOOP
+ case ELOOP : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 149, 61, path);
+ } break;
+#endif
+#ifdef ENAMETOOLONG
+ case ENAMETOOLONG : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 149, 42, path);
+ } break;
+#endif
+#ifdef ENOENT
+ case ENOENT : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 149, 51, path);
+ } break;
+#endif
+#ifdef ENOMEM
+ case ENOMEM : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 149, 142, path);
+ } break;
+#endif
+#ifdef ENOTDIR
+ case ENOTDIR : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 149, 150, path);
+ } break;
+#endif
+#ifdef EOVERFLOW
+ case EOVERFLOW : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 149, 117, path);
+ } break;
+#endif
+#ifdef EIO
+ case EIO : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 149, 126, path);
+ } break;
+#endif
+ default : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 149, 101, path);
+ } break;
+ }
+
+
+#line 209 "dk4fileia.ctr"
+}
+
+
+
+int
+dk4fileinfo_app(dk4_file_info_t *dptr, const dkChar *fn, dk4_app_t *app)
+{
+ dk4_er_t er;
+ int back = 0;
+ if ((NULL != dptr) && (NULL != fn)) {
+ dk4error_init(&er);
+ back = dk4fileinfo(dptr, fn, &er);
+ if (0 == back) {
+ switch (er.ec) {
+#if DK4_ON_WINDOWS
+ case DK4_E_CREATE_FILE_FAILED :
+ case DK4_E_FILE_INFORMATION_FAILED :
+ case DK4_E_FINDFIRSTFILE_FAILED :
+ case DK4_E_SYSTEM : {
+ dk4fileinfo_report_win_failed(app, fn, er.dt.lDetails1);
+ } break;
+#else
+ case DK4_E_SYSTEM : {
+ dk4fileinfo_report_stat_failed(app, fn, er.dt.iDetails1);
+ } break;
+#endif
+ }
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4fileia.ctr b/support/dktools/dk4fileia.ctr
new file mode 100644
index 0000000000..d796540986
--- /dev/null
+++ b/support/dktools/dk4fileia.ctr
@@ -0,0 +1,240 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk4fileia.h File information with application support.
+*/
+
+#include "dk4fileit.h"
+#include "dk4app.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve full information for a path name.
+ For symbolic links attempt to retrieve information both
+ about the link and about the link target.
+ @param dptr Pointer to result structure.
+ @param fn File path name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 if information is found, 0 otherwise.
+ If information about the link is found and no information about
+ the target, the function returns 1 as we can recognize the
+ directory item as a dangling link (link with non-existing target).
+*/
+int
+dk4fileinfo_app(dk4_file_info_t *dptr, const dkChar *fn, dk4_app_t *app);
+
+/** Report errors from the stat() function.
+ @param app Application structure.
+ @param path Path name for which stat failed.
+ @param errc Error code from errno variable.
+*/
+void
+dk4fileinfo_report_stat_failed(dk4_app_t *app, const dkChar *path, int errc);
+
+#if DK4_ON_WINDOWS
+/** Report errors from Windows functions.
+ @param app Application structure.
+ @param path Path name for which the functions failed.
+ @param errc Error code from GetLastError().
+*/
+void
+dk4fileinfo_report_win_failed(dk4_app_t *app, const dkChar *path, long errc);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4const.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4filei.h"
+#include "dk4fileia.h"
+#include "dk4error.h"
+#include "dk4mem.h"
+
+#if DK4_ON_WINDOWS
+#include "dk4maodd.h"
+#include "dk4maodh.h"
+#endif
+
+
+
+$!trace-include
+
+
+
+#if DK4_ON_WINDOWS
+void
+dk4fileinfo_report_win_failed(dk4_app_t *app, const dkChar *path, long errc)
+{
+ dkChar eb1[8 * sizeof(DWORD) + 16];
+ dkChar eb2[8 * sizeof(DWORD) + 16];
+ int res = 0;
+ int found = 0;
+
+ if (ERROR_FILE_NOT_FOUND == errc) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 149, 51, path);
+ found = 1;
+ goto finished;
+ }
+ if (ERROR_PATH_NOT_FOUND == errc) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 149, 51, path);
+ found = 1;
+ goto finished;
+ }
+ if (ERROR_ACCESS_DENIED == errc) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 149, 55, path);
+ found = 1;
+ goto finished;
+ }
+ if (ERROR_BAD_NET_NAME == errc) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 149, 74, path);
+ found = 1;
+ goto finished;
+ }
+ if (ERROR_BAD_NETPATH == errc) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 149, 75, path);
+ found = 1;
+ goto finished;
+ }
+ if (ERROR_SHARING_VIOLATION == errc) {
+ dk4app_log_base3(app, DK4_LL_ERROR, 149, 151, path);
+ found = 1;
+ goto finished;
+ }
+ if (0 == found) {
+ res = dk4ma_write_decimal_unsigned(
+ eb1, DK4_SIZEOF(eb1,dkChar), (dk4_um_t)(errc), 0, NULL
+ );
+ if (0 != res) {
+ res = dk4ma_write_hex_unsigned(
+ eb2, DK4_SIZEOF(eb2,dkChar), (dk4_um_t)(errc),
+ 0, NULL
+ );
+ }
+ if (0 != res) {
+ dk4app_log_base7(app,DK4_LL_ERROR,149,69,70,71,path,eb1,eb2);
+ } else {
+ dk4app_log_base3(app, DK4_LL_ERROR, 149, 40, path);
+ }
+ }
+ finished: ;
+}
+#endif
+
+
+
+void
+dk4fileinfo_report_stat_failed(dk4_app_t *app, const dkChar *path, int errc)
+{
+ $? "+ dk4fileinfo_report_stat_failed \"%!ds\"", path
+ switch (errc) {
+#ifdef EACCES
+ case EACCES : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 149, 138, path);
+ } break;
+#endif
+#ifdef EFAULT
+ case EFAULT : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 149, 123, path);
+ } break;
+#endif
+#ifdef ELOOP
+ case ELOOP : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 149, 61, path);
+ } break;
+#endif
+#ifdef ENAMETOOLONG
+ case ENAMETOOLONG : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 149, 42, path);
+ } break;
+#endif
+#ifdef ENOENT
+ case ENOENT : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 149, 51, path);
+ } break;
+#endif
+#ifdef ENOMEM
+ case ENOMEM : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 149, 142, path);
+ } break;
+#endif
+#ifdef ENOTDIR
+ case ENOTDIR : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 149, 150, path);
+ } break;
+#endif
+#ifdef EOVERFLOW
+ case EOVERFLOW : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 149, 117, path);
+ } break;
+#endif
+#ifdef EIO
+ case EIO : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 149, 126, path);
+ } break;
+#endif
+ default : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 149, 101, path);
+ } break;
+ }
+ $? "- dk4fileinfo_report_stat_failed"
+}
+
+
+
+int
+dk4fileinfo_app(dk4_file_info_t *dptr, const dkChar *fn, dk4_app_t *app)
+{
+ dk4_er_t er;
+ int back = 0;
+ if ((NULL != dptr) && (NULL != fn)) {
+ dk4error_init(&er);
+ back = dk4fileinfo(dptr, fn, &er);
+ if (0 == back) {
+ switch (er.ec) {
+#if DK4_ON_WINDOWS
+ case DK4_E_CREATE_FILE_FAILED :
+ case DK4_E_FILE_INFORMATION_FAILED :
+ case DK4_E_FINDFIRSTFILE_FAILED :
+ case DK4_E_SYSTEM : {
+ dk4fileinfo_report_win_failed(app, fn, er.dt.lDetails1);
+ } break;
+#else
+ case DK4_E_SYSTEM : {
+ dk4fileinfo_report_stat_failed(app, fn, er.dt.iDetails1);
+ } break;
+#endif
+ }
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4fileia.h b/support/dktools/dk4fileia.h
new file mode 100644
index 0000000000..bd38ea67db
--- /dev/null
+++ b/support/dktools/dk4fileia.h
@@ -0,0 +1,91 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fileia.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4FILEIA_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4FILEIA_H_INCLUDED 1
+
+
+#line 10 "dk4fileia.ctr"
+
+/** @file dk4fileia.h File information with application support.
+*/
+
+#include "dk4fileit.h"
+#include "dk4app.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve full information for a path name.
+ For symbolic links attempt to retrieve information both
+ about the link and about the link target.
+ @param dptr Pointer to result structure.
+ @param fn File path name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 if information is found, 0 otherwise.
+ If information about the link is found and no information about
+ the target, the function returns 1 as we can recognize the
+ directory item as a dangling link (link with non-existing target).
+*/
+int
+dk4fileinfo_app(dk4_file_info_t *dptr, const dkChar *fn, dk4_app_t *app);
+
+/** Report errors from the stat() function.
+ @param app Application structure.
+ @param path Path name for which stat failed.
+ @param errc Error code from errno variable.
+*/
+void
+dk4fileinfo_report_stat_failed(dk4_app_t *app, const dkChar *path, int errc);
+
+#if DK4_ON_WINDOWS
+/** Report errors from Windows functions.
+ @param app Application structure.
+ @param path Path name for which the functions failed.
+ @param errc Error code from GetLastError().
+*/
+void
+dk4fileinfo_report_win_failed(dk4_app_t *app, const dkChar *path, long errc);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4fileid.c b/support/dktools/dk4fileid.c
new file mode 100644
index 0000000000..5b4b785d7e
--- /dev/null
+++ b/support/dktools/dk4fileid.c
@@ -0,0 +1,61 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fileid.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4fileid.c The dk4fileid module.
+*/
+
+
+#line 10 "dk4fileid.ctr"
+
+#include "dk4filei.h"
+
+#if DK4_CHAR_SIZE > 1
+#include "dk4fileiw.h"
+#else
+#include "dk4filei8.h"
+#endif
+
+
+
+int
+dk4fileinfo(dk4_file_info_t *dptr, const dkChar *fn, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4fileinfo_wc(dptr, fn, erp));
+#else
+ return (dk4fileinfo_c8(dptr, fn, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4fileid.ctr b/support/dktools/dk4fileid.ctr
new file mode 100644
index 0000000000..27aa6d3a07
--- /dev/null
+++ b/support/dktools/dk4fileid.ctr
@@ -0,0 +1,30 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4filei.h"
+
+#if DK4_CHAR_SIZE > 1
+#include "dk4fileiw.h"
+#else
+#include "dk4filei8.h"
+#endif
+
+
+
+int
+dk4fileinfo(dk4_file_info_t *dptr, const dkChar *fn, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4fileinfo_wc(dptr, fn, erp));
+#else
+ return (dk4fileinfo_c8(dptr, fn, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4fileid.h b/support/dktools/dk4fileid.h
new file mode 100644
index 0000000000..38d7372be2
--- /dev/null
+++ b/support/dktools/dk4fileid.h
@@ -0,0 +1,80 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fileid.ctr
+*/
+
+/*
+Copyright (C) 2015, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4FILEID_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4FILEID_H_INCLUDED 1
+
+
+#line 10 "dk4fileid.ctr"
+
+/** @file dk4fileid.h File information for files specified
+ by dkChar path name.
+*/
+
+#ifndef DK4FILEIT_H_INCLUDED
+#include "dk4fileit.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+/** Retrieve full information for a path name.
+ For symbolic links attempt to retrieve information both
+ about the link and about the link target.
+ @param dptr Pointer to result structure.
+ @param fn File path name.
+ @param erp Error report, may be NULL.
+ @return 1 if information is found, 0 otherwise.
+ If information about the link is found and no information about
+ the target, the function returns 1 as we can recognize the
+ directory item as a dangling link (link with non-existing target).
+*/
+int
+dk4fileinfo(dk4_file_info_t *dptr, const dkChar *fn, dk4_er_t *erp);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4fileig8.c b/support/dktools/dk4fileig8.c
new file mode 100644
index 0000000000..3aca331727
--- /dev/null
+++ b/support/dktools/dk4fileig8.c
@@ -0,0 +1,530 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fileig8.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4fileig8.c The dk4fileig8 module.
+*/
+
+
+#line 10 "dk4fileig8.ctr"
+
+#include "dk4filei.h"
+
+#ifndef DK4TIME_H_INCLUDED
+#include "dk4time.h"
+#endif
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4TIME08_H_INCLUDED
+#include "dk4time08.h"
+#endif
+
+#if DK4_TIME_WITH_SYS_TIME
+#ifndef SYS_TIME_H_INCLUDED
+#include <sys/time.h>
+#define SYS_TIME_H_INCLUDED 1
+#endif
+#ifndef TIME_H_INCLUDED
+#include <time.h>
+#define TIME_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_TIME_H
+#ifndef TIME_H_INCLUDED
+#include <time.h>
+#define TIME_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_SYS_TIME_H
+#ifndef SYS_TIME_H_INCLUDED
+#include <sys/time.h>
+#define SYS_TIME_H_INCLUDED 1
+#endif
+#endif
+#endif
+#endif
+
+
+
+
+
+#line 53 "dk4fileig8.ctr"
+
+
+
+#if DK4_ON_WINDOWS
+/* +++++ Windows +++++ */
+
+static
+int
+dk4fileinfo_c8_filetime_timestamp(
+ char *dptr,
+ size_t szdptr,
+ const FILETIME *timer,
+ dk4_er_t *erp
+)
+{
+ SYSTEMTIME st;
+ SYSTEMTIME lt;
+ int back = 0;
+ if (FileTimeToSystemTime(timer, &st)) {
+ if (SystemTimeToTzSpecificLocalTime(NULL, &st, &lt)) {
+ back = dk4time_to_text_c8(
+ dptr, szdptr, DK4_TIMEFORMAT_DATE_TIME,
+ lt.wYear, lt.wMonth, lt.wDay,
+ lt.wHour, lt.wMinute, lt.wSecond,
+ erp
+ );
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ return back;
+}
+
+static
+int
+dk4fileinfo_c8_win_timestamp(
+ char *dptr,
+ size_t szdptr,
+ const BY_HANDLE_FILE_INFORMATION *pbhfi,
+ int chtime,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+ switch (chtime) {
+ case DK4_FILE_INFO_TIME_ACCESS: {
+ back = dk4fileinfo_c8_filetime_timestamp(
+ dptr, szdptr, &(pbhfi->ftLastAccessTime), erp
+ );
+ } break;
+ case DK4_FILE_INFO_TIME_CREATE: {
+ back = dk4fileinfo_c8_filetime_timestamp(
+ dptr, szdptr, &(pbhfi->ftCreationTime), erp
+ );
+ } break;
+ default: {
+ back = dk4fileinfo_c8_filetime_timestamp(
+ dptr, szdptr, &(pbhfi->ftLastWriteTime), erp
+ );
+ } break;
+ }
+ return back;
+}
+
+/* ----- Windows ----- */
+#else
+/* +++++ non-Windows +++++ */
+
+
+static
+int
+dk4fileinfo_c8_stat_time_timestamp(
+ char *dptr,
+ size_t szdptr,
+ const time_t *timer,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_LOCALTIME_R
+ struct tm lct;
+ int back = 0;
+ if (NULL != localtime_r(timer, &lct)) {
+ back = dk4time_convert_to_text_c8(dptr, szdptr, &lct, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+}
+
+static
+int
+dk4fileinfo_c8_nonwin_timestamp(
+ char *dptr,
+ size_t szdptr,
+ const dk4_stat_t *stb,
+ int chtime,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+ switch (chtime) {
+ case DK4_FILE_INFO_TIME_ACCESS: {
+ back = dk4fileinfo_c8_stat_time_timestamp(
+ dptr, szdptr, &(stb->st_atime), erp
+ );
+ } break;
+ case DK4_FILE_INFO_TIME_CREATE: {
+ back = dk4fileinfo_c8_stat_time_timestamp(
+ dptr, szdptr, &(stb->st_ctime), erp
+ );
+ } break;
+ default: {
+ back = dk4fileinfo_c8_stat_time_timestamp(
+ dptr, szdptr, &(stb->st_mtime), erp
+ );
+ } break;
+ }
+ return back;
+}
+
+/* ----- non-Windows ----- */
+#endif
+
+
+
+int
+dk4fileinfo_timestamp_c8(
+ char *dptr,
+ size_t szdptr,
+ const dk4_file_info_t *fi,
+ int chfile,
+ int chtime,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+ if ((NULL != dptr) && (NULL != fi) && (0 < szdptr)) {
+ switch (chfile) {
+ case DK4_FILE_INFO_CONTENTS_DATA_LINK: {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & (fi->contents))) {
+#if DK4_ON_WINDOWS
+ back = dk4fileinfo_c8_win_timestamp(
+ dptr, szdptr, &(fi->linfo), chtime, erp
+ );
+#else
+ back = dk4fileinfo_c8_nonwin_timestamp(
+ dptr, szdptr, &(fi->lstb), chtime, erp
+ );
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } break;
+ default: {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & (fi->contents))) {
+#if DK4_ON_WINDOWS
+ back = dk4fileinfo_c8_win_timestamp(
+ dptr, szdptr, &(fi->tinfo), chtime, erp
+ );
+#else
+ back = dk4fileinfo_c8_nonwin_timestamp(
+ dptr, szdptr, &(fi->tstb), chtime, erp
+ );
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4fileinfo_type_attributes_c8(
+ char *dptr,
+ size_t szdptr,
+ dk4_file_info_t *fi,
+ dk4_er_t *erp
+)
+{
+ size_t i;
+ int back = 0;
+ if ((NULL != dptr) && (NULL != fi) && (0 < szdptr)) {
+ DK4_MEMRES(dptr, szdptr);
+#if DK4_ON_WINDOWS
+ if (14 < szdptr) {
+ back = 1;
+ for (i = 0; i < 12; i++) { dptr[i] = '-'; }
+ /* 0 reparse point or symlink */
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & (fi->contents))) {
+ if (0 != (FILE_ATTRIBUTE_REPARSE_POINT & (fi->fattr))) {
+ dptr[0] = 'r';
+ if (IO_REPARSE_TAG_MOUNT_POINT == fi->rppnt) {
+ dptr[0] = 'm';
+ } else {
+ if (IO_REPARSE_TAG_SYMLINK == fi->rppnt) {
+ dptr[0] = 'l';
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & (fi->contents))) {
+ if (
+ (fi->linfo).dwVolumeSerialNumber
+ != (fi->tinfo).dwVolumeSerialNumber
+ ) {
+ dptr[0] = 'L';
+ }
+ } else {
+ dptr[0] = '!';
+ }
+ } else {
+ if (IO_REPARSE_TAG_WIM == fi->rppnt) {
+ dptr[0] = 'w';
+ } else {
+ if (IO_REPARSE_TAG_SIS == fi->rppnt) {
+ dptr[0] = 's';
+ } else {
+#ifdef IO_REPARSE_TAG_NFS
+ /* Not available in VS2008+PSDK7
+ */
+ if (IO_REPARSE_TAG_NFS == fi->rppnt) {
+ dptr[0] = 'n';
+ } else {
+#endif
+ if (IO_REPARSE_TAG_CSV == fi->rppnt) {
+ dptr[0] = 'c';
+ } else {
+ if (IO_REPARSE_TAG_DFS == fi->rppnt) {
+ dptr[0] = 'd';
+ } else {
+ if (IO_REPARSE_TAG_DFSR == fi->rppnt) {
+ dptr[0] = 'f';
+ } else {
+#ifdef IO_REPARSE_TAG_DEDUP
+ /* Not available in VS2008+PSDK7
+ */
+ if (IO_REPARSE_TAG_DEDUP == fi->rppnt) {
+ dptr[0] = 'u';
+ } else {
+#endif
+ if (IO_REPARSE_TAG_HSM == fi->rppnt) {
+ dptr[0] = 'h';
+ } else {
+ if (IO_REPARSE_TAG_HSM2 == fi->rppnt) {
+ dptr[0] = '2';
+ }
+ }
+#ifdef IO_REPARSE_TAG_DEDUP
+ }
+#endif
+ }
+ }
+ }
+#ifdef IO_REPARSE_TAG_NFS
+ }
+#endif
+ }
+ }
+ }
+ }
+ }
+ }
+ /* 1 file type */
+ if (0 != (FILE_ATTRIBUTE_DIRECTORY & fi->fattr)) {
+ dptr[1] = 'd';
+ } else {
+ if (0 != (FILE_ATTRIBUTE_DEVICE & fi->fattr)) {
+ dptr[1] = 'b';
+ }
+ }
+ /* 2 read-only */
+ if (0 != (FILE_ATTRIBUTE_READONLY & fi->fattr)) {
+ dptr[2] = 'R';
+ }
+ /* 3 system file */
+ if (0 != (FILE_ATTRIBUTE_SYSTEM & fi->fattr)) {
+ dptr[3] = 'S';
+ }
+ /* 4 hidden */
+ if (0 != (FILE_ATTRIBUTE_HIDDEN & fi->fattr)) {
+ dptr[4] = 'H';
+ }
+ /* 5 not indexed */
+ if (0 != (FILE_ATTRIBUTE_NOT_CONTENT_INDEXED & fi->fattr)) {
+ dptr[5] = 'I';
+ }
+ /* 6 compressed */
+ if (0 != (FILE_ATTRIBUTE_COMPRESSED & fi->fattr)) {
+ dptr[6] = 'C';
+ }
+ /* 7 encrypted */
+ if (0 != (FILE_ATTRIBUTE_ENCRYPTED & fi->fattr)) {
+ dptr[7] = 'E';
+ }
+ /* 8 offline */
+ if (0 != (FILE_ATTRIBUTE_OFFLINE & fi->fattr)) {
+ dptr[8] = 'O';
+ }
+ /* 9 sparse file */
+ if (0 != (FILE_ATTRIBUTE_SPARSE_FILE & fi->fattr)) {
+ dptr[9] = 'P';
+ }
+ /* 10 temporary file */
+ if (0 != (FILE_ATTRIBUTE_TEMPORARY & fi->fattr)) {
+ dptr[10] = 'T';
+ }
+ /* 11 virtual file */
+ if (0 != (FILE_ATTRIBUTE_VIRTUAL & fi->fattr)) {
+ dptr[11] = 'V';
+ }
+ } else {
+
+#line 372 "dk4fileig8.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+#else
+ if (12 < szdptr) {
+ back = 1;
+ for (i = 0; i < 11; i++) { dptr[i] = '-'; }
+ /* 0 symlink */
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & (fi->contents))) {
+#if defined(S_IFMT) && defined(S_IFLNK)
+ if (S_IFLNK == (S_IFMT & ((fi->lstb).st_mode))) {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & (fi->contents))) {
+ if ((fi->tstb).st_dev == (fi->lstb).st_dev) {
+ dptr[0] = 'l';
+ } else {
+ dptr[0] = 'L';
+ }
+ } else {
+ dptr[0] = '!';
+ }
+ }
+#endif
+ }
+ /* 1 file type */
+ dptr[1] = '?';
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & (fi->contents))) {
+ switch (S_IFMT & ((fi->tstb).st_mode)) {
+ case S_IFIFO: { dptr[1] = 'p'; } break;
+ case S_IFCHR: { dptr[1] = 'c'; } break;
+ case S_IFDIR: { dptr[1] = 'd'; } break;
+ case S_IFBLK: { dptr[1] = 'b'; } break;
+ case S_IFREG: { dptr[1] = '-'; } break;
+ case S_IFSOCK: { dptr[1] = 's'; } break;
+#ifdef S_IFMPC
+ case S_IFMPC: { dptr[1] = 'C'; } break;
+#endif
+#ifdef S_IFNAM
+ case S_IFNAM: { dptr[1] = 'O'; } break;
+#endif
+#ifdef S_INSEM
+ case S_INSEM: { dptr[1] = 'N'; } break;
+#endif
+#ifdef S_INSHD
+ case S_INSHD: { dptr[1] = 'M'; } break;
+#endif
+#ifdef S_IFMPB
+ case S_IFMPB: { dptr[1] = 'B'; } break;
+#endif
+#ifdef S_IFCMP
+ case S_IFCMP: { dptr[1] = 'v'; } break;
+#endif
+#ifdef S_IFNWK
+ case S_IFNWK: { dptr[1] = 'n'; } break;
+#endif
+#ifdef S_IFSHAD
+ case S_IFSHAD: { dptr[1] = 'a'; } break;
+#endif
+#ifdef S_IFDOOR
+ case S_IFDOOR: { dptr[1] = 'D'; } break;
+#endif
+#ifdef S_IFWHT
+ case S_IFWHT: { dptr[1] = 'w'; } break;
+#endif
+ }
+ /* 2 user read */
+ if (0 != (S_IRUSR & ((fi->tstb).st_mode))) {
+ dptr[2] = 'r';
+ }
+ /* 3 user write */
+ if (0 != (S_IWUSR & ((fi->tstb).st_mode))) {
+ dptr[3] = 'w';
+ }
+ /* 4 user execute */
+ if (0 != (S_IXUSR & ((fi->tstb).st_mode))) {
+ dptr[4] = 'x';
+ }
+ /* 4 user sticky */
+ if (0 != (S_ISUID & ((fi->tstb).st_mode))) {
+ dptr[4] = (('x' == dptr[4]) ? ('s') : ('S'));
+ }
+ /* 5 group read */
+ if (0 != (S_IRGRP & ((fi->tstb).st_mode))) {
+ dptr[5] = 'r';
+ }
+ /* 6 group write */
+ if (0 != (S_IWGRP & ((fi->tstb).st_mode))) {
+ dptr[6] = 'w';
+ }
+ /* 7 group execute */
+ if (0 != (S_IXGRP & ((fi->tstb).st_mode))) {
+ dptr[7] = 'x';
+ }
+ /* 7 group sticky */
+ if (0 != (S_ISGID & ((fi->tstb).st_mode))) {
+ dptr[7] = (('x' == dptr[7]) ? ('s') : ('S'));
+ }
+ /* 8 other read */
+ if (0 != (S_IROTH & ((fi->tstb).st_mode))) {
+ dptr[8] = 'r';
+ }
+ /* 9 other write */
+ if (0 != (S_IWOTH & ((fi->tstb).st_mode))) {
+ dptr[9] = 'w';
+ }
+ /* 10 other execute */
+ if (0 != (S_IXOTH & ((fi->tstb).st_mode))) {
+ dptr[10] = 'x';
+ }
+ /* 10 dir sticky */
+ if (0 != (S_ISVTX & ((fi->tstb).st_mode))) {
+ dptr[10] = (('x' == dptr[10]) ? ('t') : ('T'));
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4fileig8.ctr b/support/dktools/dk4fileig8.ctr
new file mode 100644
index 0000000000..cf4d9ae3fd
--- /dev/null
+++ b/support/dktools/dk4fileig8.ctr
@@ -0,0 +1,495 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4filei.h"
+
+#ifndef DK4TIME_H_INCLUDED
+#include "dk4time.h"
+#endif
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4TIME08_H_INCLUDED
+#include "dk4time08.h"
+#endif
+
+#if DK4_TIME_WITH_SYS_TIME
+#ifndef SYS_TIME_H_INCLUDED
+#include <sys/time.h>
+#define SYS_TIME_H_INCLUDED 1
+#endif
+#ifndef TIME_H_INCLUDED
+#include <time.h>
+#define TIME_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_TIME_H
+#ifndef TIME_H_INCLUDED
+#include <time.h>
+#define TIME_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_SYS_TIME_H
+#ifndef SYS_TIME_H_INCLUDED
+#include <sys/time.h>
+#define SYS_TIME_H_INCLUDED 1
+#endif
+#endif
+#endif
+#endif
+
+
+
+$!trace-include
+
+
+
+#if DK4_ON_WINDOWS
+/* +++++ Windows +++++ */
+
+static
+int
+dk4fileinfo_c8_filetime_timestamp(
+ char *dptr,
+ size_t szdptr,
+ const FILETIME *timer,
+ dk4_er_t *erp
+)
+{
+ SYSTEMTIME st;
+ SYSTEMTIME lt;
+ int back = 0;
+ if (FileTimeToSystemTime(timer, &st)) {
+ if (SystemTimeToTzSpecificLocalTime(NULL, &st, &lt)) {
+ back = dk4time_to_text_c8(
+ dptr, szdptr, DK4_TIMEFORMAT_DATE_TIME,
+ lt.wYear, lt.wMonth, lt.wDay,
+ lt.wHour, lt.wMinute, lt.wSecond,
+ erp
+ );
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ return back;
+}
+
+static
+int
+dk4fileinfo_c8_win_timestamp(
+ char *dptr,
+ size_t szdptr,
+ const BY_HANDLE_FILE_INFORMATION *pbhfi,
+ int chtime,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+ switch (chtime) {
+ case DK4_FILE_INFO_TIME_ACCESS: {
+ back = dk4fileinfo_c8_filetime_timestamp(
+ dptr, szdptr, &(pbhfi->ftLastAccessTime), erp
+ );
+ } break;
+ case DK4_FILE_INFO_TIME_CREATE: {
+ back = dk4fileinfo_c8_filetime_timestamp(
+ dptr, szdptr, &(pbhfi->ftCreationTime), erp
+ );
+ } break;
+ default: {
+ back = dk4fileinfo_c8_filetime_timestamp(
+ dptr, szdptr, &(pbhfi->ftLastWriteTime), erp
+ );
+ } break;
+ }
+ return back;
+}
+
+/* ----- Windows ----- */
+#else
+/* +++++ non-Windows +++++ */
+
+
+static
+int
+dk4fileinfo_c8_stat_time_timestamp(
+ char *dptr,
+ size_t szdptr,
+ const time_t *timer,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_LOCALTIME_R
+ struct tm lct;
+ int back = 0;
+ if (NULL != localtime_r(timer, &lct)) {
+ back = dk4time_convert_to_text_c8(dptr, szdptr, &lct, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+}
+
+static
+int
+dk4fileinfo_c8_nonwin_timestamp(
+ char *dptr,
+ size_t szdptr,
+ const dk4_stat_t *stb,
+ int chtime,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+ switch (chtime) {
+ case DK4_FILE_INFO_TIME_ACCESS: {
+ back = dk4fileinfo_c8_stat_time_timestamp(
+ dptr, szdptr, &(stb->st_atime), erp
+ );
+ } break;
+ case DK4_FILE_INFO_TIME_CREATE: {
+ back = dk4fileinfo_c8_stat_time_timestamp(
+ dptr, szdptr, &(stb->st_ctime), erp
+ );
+ } break;
+ default: {
+ back = dk4fileinfo_c8_stat_time_timestamp(
+ dptr, szdptr, &(stb->st_mtime), erp
+ );
+ } break;
+ }
+ return back;
+}
+
+/* ----- non-Windows ----- */
+#endif
+
+
+
+int
+dk4fileinfo_timestamp_c8(
+ char *dptr,
+ size_t szdptr,
+ const dk4_file_info_t *fi,
+ int chfile,
+ int chtime,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+ if ((NULL != dptr) && (NULL != fi) && (0 < szdptr)) {
+ switch (chfile) {
+ case DK4_FILE_INFO_CONTENTS_DATA_LINK: {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & (fi->contents))) {
+#if DK4_ON_WINDOWS
+ back = dk4fileinfo_c8_win_timestamp(
+ dptr, szdptr, &(fi->linfo), chtime, erp
+ );
+#else
+ back = dk4fileinfo_c8_nonwin_timestamp(
+ dptr, szdptr, &(fi->lstb), chtime, erp
+ );
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } break;
+ default: {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & (fi->contents))) {
+#if DK4_ON_WINDOWS
+ back = dk4fileinfo_c8_win_timestamp(
+ dptr, szdptr, &(fi->tinfo), chtime, erp
+ );
+#else
+ back = dk4fileinfo_c8_nonwin_timestamp(
+ dptr, szdptr, &(fi->tstb), chtime, erp
+ );
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4fileinfo_type_attributes_c8(
+ char *dptr,
+ size_t szdptr,
+ dk4_file_info_t *fi,
+ dk4_er_t *erp
+)
+{
+ size_t i;
+ int back = 0;
+ if ((NULL != dptr) && (NULL != fi) && (0 < szdptr)) {
+ DK4_MEMRES(dptr, szdptr);
+#if DK4_ON_WINDOWS
+ if (14 < szdptr) {
+ back = 1;
+ for (i = 0; i < 12; i++) { dptr[i] = '-'; }
+ /* 0 reparse point or symlink */
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & (fi->contents))) {
+ if (0 != (FILE_ATTRIBUTE_REPARSE_POINT & (fi->fattr))) {
+ dptr[0] = 'r';
+ if (IO_REPARSE_TAG_MOUNT_POINT == fi->rppnt) {
+ dptr[0] = 'm';
+ } else {
+ if (IO_REPARSE_TAG_SYMLINK == fi->rppnt) {
+ dptr[0] = 'l';
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & (fi->contents))) {
+ if (
+ (fi->linfo).dwVolumeSerialNumber
+ != (fi->tinfo).dwVolumeSerialNumber
+ ) {
+ dptr[0] = 'L';
+ }
+ } else {
+ dptr[0] = '!';
+ }
+ } else {
+ if (IO_REPARSE_TAG_WIM == fi->rppnt) {
+ dptr[0] = 'w';
+ } else {
+ if (IO_REPARSE_TAG_SIS == fi->rppnt) {
+ dptr[0] = 's';
+ } else {
+#ifdef IO_REPARSE_TAG_NFS
+ /* Not available in VS2008+PSDK7
+ */
+ if (IO_REPARSE_TAG_NFS == fi->rppnt) {
+ dptr[0] = 'n';
+ } else {
+#endif
+ if (IO_REPARSE_TAG_CSV == fi->rppnt) {
+ dptr[0] = 'c';
+ } else {
+ if (IO_REPARSE_TAG_DFS == fi->rppnt) {
+ dptr[0] = 'd';
+ } else {
+ if (IO_REPARSE_TAG_DFSR == fi->rppnt) {
+ dptr[0] = 'f';
+ } else {
+#ifdef IO_REPARSE_TAG_DEDUP
+ /* Not available in VS2008+PSDK7
+ */
+ if (IO_REPARSE_TAG_DEDUP == fi->rppnt) {
+ dptr[0] = 'u';
+ } else {
+#endif
+ if (IO_REPARSE_TAG_HSM == fi->rppnt) {
+ dptr[0] = 'h';
+ } else {
+ if (IO_REPARSE_TAG_HSM2 == fi->rppnt) {
+ dptr[0] = '2';
+ }
+ }
+#ifdef IO_REPARSE_TAG_DEDUP
+ }
+#endif
+ }
+ }
+ }
+#ifdef IO_REPARSE_TAG_NFS
+ }
+#endif
+ }
+ }
+ }
+ }
+ }
+ }
+ /* 1 file type */
+ if (0 != (FILE_ATTRIBUTE_DIRECTORY & fi->fattr)) {
+ dptr[1] = 'd';
+ } else {
+ if (0 != (FILE_ATTRIBUTE_DEVICE & fi->fattr)) {
+ dptr[1] = 'b';
+ }
+ }
+ /* 2 read-only */
+ if (0 != (FILE_ATTRIBUTE_READONLY & fi->fattr)) {
+ dptr[2] = 'R';
+ }
+ /* 3 system file */
+ if (0 != (FILE_ATTRIBUTE_SYSTEM & fi->fattr)) {
+ dptr[3] = 'S';
+ }
+ /* 4 hidden */
+ if (0 != (FILE_ATTRIBUTE_HIDDEN & fi->fattr)) {
+ dptr[4] = 'H';
+ }
+ /* 5 not indexed */
+ if (0 != (FILE_ATTRIBUTE_NOT_CONTENT_INDEXED & fi->fattr)) {
+ dptr[5] = 'I';
+ }
+ /* 6 compressed */
+ if (0 != (FILE_ATTRIBUTE_COMPRESSED & fi->fattr)) {
+ dptr[6] = 'C';
+ }
+ /* 7 encrypted */
+ if (0 != (FILE_ATTRIBUTE_ENCRYPTED & fi->fattr)) {
+ dptr[7] = 'E';
+ }
+ /* 8 offline */
+ if (0 != (FILE_ATTRIBUTE_OFFLINE & fi->fattr)) {
+ dptr[8] = 'O';
+ }
+ /* 9 sparse file */
+ if (0 != (FILE_ATTRIBUTE_SPARSE_FILE & fi->fattr)) {
+ dptr[9] = 'P';
+ }
+ /* 10 temporary file */
+ if (0 != (FILE_ATTRIBUTE_TEMPORARY & fi->fattr)) {
+ dptr[10] = 'T';
+ }
+ /* 11 virtual file */
+ if (0 != (FILE_ATTRIBUTE_VIRTUAL & fi->fattr)) {
+ dptr[11] = 'V';
+ }
+ } else { $? "! buffer too small"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+#else
+ if (12 < szdptr) {
+ back = 1;
+ for (i = 0; i < 11; i++) { dptr[i] = '-'; }
+ /* 0 symlink */
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & (fi->contents))) {
+#if defined(S_IFMT) && defined(S_IFLNK)
+ if (S_IFLNK == (S_IFMT & ((fi->lstb).st_mode))) {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & (fi->contents))) {
+ if ((fi->tstb).st_dev == (fi->lstb).st_dev) {
+ dptr[0] = 'l';
+ } else {
+ dptr[0] = 'L';
+ }
+ } else {
+ dptr[0] = '!';
+ }
+ }
+#endif
+ }
+ /* 1 file type */
+ dptr[1] = '?';
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & (fi->contents))) {
+ switch (S_IFMT & ((fi->tstb).st_mode)) {
+ case S_IFIFO: { dptr[1] = 'p'; } break;
+ case S_IFCHR: { dptr[1] = 'c'; } break;
+ case S_IFDIR: { dptr[1] = 'd'; } break;
+ case S_IFBLK: { dptr[1] = 'b'; } break;
+ case S_IFREG: { dptr[1] = '-'; } break;
+ case S_IFSOCK: { dptr[1] = 's'; } break;
+#ifdef S_IFMPC
+ case S_IFMPC: { dptr[1] = 'C'; } break;
+#endif
+#ifdef S_IFNAM
+ case S_IFNAM: { dptr[1] = 'O'; } break;
+#endif
+#ifdef S_INSEM
+ case S_INSEM: { dptr[1] = 'N'; } break;
+#endif
+#ifdef S_INSHD
+ case S_INSHD: { dptr[1] = 'M'; } break;
+#endif
+#ifdef S_IFMPB
+ case S_IFMPB: { dptr[1] = 'B'; } break;
+#endif
+#ifdef S_IFCMP
+ case S_IFCMP: { dptr[1] = 'v'; } break;
+#endif
+#ifdef S_IFNWK
+ case S_IFNWK: { dptr[1] = 'n'; } break;
+#endif
+#ifdef S_IFSHAD
+ case S_IFSHAD: { dptr[1] = 'a'; } break;
+#endif
+#ifdef S_IFDOOR
+ case S_IFDOOR: { dptr[1] = 'D'; } break;
+#endif
+#ifdef S_IFWHT
+ case S_IFWHT: { dptr[1] = 'w'; } break;
+#endif
+ }
+ /* 2 user read */
+ if (0 != (S_IRUSR & ((fi->tstb).st_mode))) {
+ dptr[2] = 'r';
+ }
+ /* 3 user write */
+ if (0 != (S_IWUSR & ((fi->tstb).st_mode))) {
+ dptr[3] = 'w';
+ }
+ /* 4 user execute */
+ if (0 != (S_IXUSR & ((fi->tstb).st_mode))) {
+ dptr[4] = 'x';
+ }
+ /* 4 user sticky */
+ if (0 != (S_ISUID & ((fi->tstb).st_mode))) {
+ dptr[4] = (('x' == dptr[4]) ? ('s') : ('S'));
+ }
+ /* 5 group read */
+ if (0 != (S_IRGRP & ((fi->tstb).st_mode))) {
+ dptr[5] = 'r';
+ }
+ /* 6 group write */
+ if (0 != (S_IWGRP & ((fi->tstb).st_mode))) {
+ dptr[6] = 'w';
+ }
+ /* 7 group execute */
+ if (0 != (S_IXGRP & ((fi->tstb).st_mode))) {
+ dptr[7] = 'x';
+ }
+ /* 7 group sticky */
+ if (0 != (S_ISGID & ((fi->tstb).st_mode))) {
+ dptr[7] = (('x' == dptr[7]) ? ('s') : ('S'));
+ }
+ /* 8 other read */
+ if (0 != (S_IROTH & ((fi->tstb).st_mode))) {
+ dptr[8] = 'r';
+ }
+ /* 9 other write */
+ if (0 != (S_IWOTH & ((fi->tstb).st_mode))) {
+ dptr[9] = 'w';
+ }
+ /* 10 other execute */
+ if (0 != (S_IXOTH & ((fi->tstb).st_mode))) {
+ dptr[10] = 'x';
+ }
+ /* 10 dir sticky */
+ if (0 != (S_ISVTX & ((fi->tstb).st_mode))) {
+ dptr[10] = (('x' == dptr[10]) ? ('t') : ('T'));
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4fileig8.h b/support/dktools/dk4fileig8.h
new file mode 100644
index 0000000000..4c802bde05
--- /dev/null
+++ b/support/dktools/dk4fileig8.h
@@ -0,0 +1,89 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fileig8.ctr
+*/
+
+/*
+Copyright (C) 2015, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4FILEIG8_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4FILEIG8_H_INCLUDED 1
+
+
+#line 10 "dk4fileig8.ctr"
+
+/** @file dk4fileig8.h Retrieve file information from
+ file information structure.
+*/
+
+#ifndef DK4FILEIT_H_INCLUDED
+#include "dk4fileit.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Write file related timestamp to string.
+ @param dptr Destination buffer pointer.
+ @param szdptr Destination buffer size.
+ @param fi File information.
+ @param chfile Choose file (either DK4_FILE_INFO_CONTENTS_DATA_LINK
+ or DK4_FILE_INFO_CONTENTS_DATA_TARGET).
+ @param chtime Choose timestamp, one from:
+ DK4_FILE_INFO_TIME_CREATE,
+ DK4_FILE_INFO_TIME_MODIFY or
+ DK4_FILE_INFO_TIME_ACCESS.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4fileinfo_timestamp_c8(
+ char *dptr,
+ size_t szdptr,
+ const dk4_file_info_t *fi,
+ int chfile,
+ int chtime,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4fileigd.c b/support/dktools/dk4fileigd.c
new file mode 100644
index 0000000000..9c62359772
--- /dev/null
+++ b/support/dktools/dk4fileigd.c
@@ -0,0 +1,75 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fileigd.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4fileigd.c The dk4fileigd module.
+*/
+
+
+#line 10 "dk4fileigd.ctr"
+
+#include "dk4filei.h"
+
+int
+dk4fileinfo_timestamp(
+ dkChar *dptr,
+ size_t szdptr,
+ const dk4_file_info_t *fi,
+ int chfile,
+ int chtime,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4fileinfo_timestamp_wc(dptr, szdptr, fi, chfile, chtime, erp));
+#else
+ return (dk4fileinfo_timestamp_c8(dptr, szdptr, fi, chfile, chtime, erp));
+#endif
+}
+
+int
+dk4fileinfo_type_attributes(
+ dkChar *dptr,
+ size_t szdptr,
+ dk4_file_info_t *fi,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4fileinfo_type_attributes_wc(dptr, szdptr, fi, erp));
+#else
+ return (dk4fileinfo_type_attributes_c8(dptr, szdptr, fi, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4fileigd.ctr b/support/dktools/dk4fileigd.ctr
new file mode 100644
index 0000000000..51adbfbc78
--- /dev/null
+++ b/support/dktools/dk4fileigd.ctr
@@ -0,0 +1,44 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4filei.h"
+
+int
+dk4fileinfo_timestamp(
+ dkChar *dptr,
+ size_t szdptr,
+ const dk4_file_info_t *fi,
+ int chfile,
+ int chtime,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4fileinfo_timestamp_wc(dptr, szdptr, fi, chfile, chtime, erp));
+#else
+ return (dk4fileinfo_timestamp_c8(dptr, szdptr, fi, chfile, chtime, erp));
+#endif
+}
+
+int
+dk4fileinfo_type_attributes(
+ dkChar *dptr,
+ size_t szdptr,
+ dk4_file_info_t *fi,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4fileinfo_type_attributes_wc(dptr, szdptr, fi, erp));
+#else
+ return (dk4fileinfo_type_attributes_c8(dptr, szdptr, fi, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4fileigw.c b/support/dktools/dk4fileigw.c
new file mode 100644
index 0000000000..bc838a0ccb
--- /dev/null
+++ b/support/dktools/dk4fileigw.c
@@ -0,0 +1,79 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fileigw.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4fileigw.c The dk4fileigw module.
+*/
+
+
+#line 10 "dk4fileigw.ctr"
+
+#include "dk4filei.h"
+
+#include "dk4rec23.h"
+
+int
+dk4fileinfo_timestamp_wc(
+ wchar_t *dptr,
+ size_t szdptr,
+ const dk4_file_info_t *fi,
+ int chfile,
+ int chtime,
+ dk4_er_t *erp
+)
+{
+ char buf[64];
+ int back = 0;
+ if (0 != dk4fileinfo_timestamp_c8(buf,sizeof(buf),fi,chfile,chtime,erp)) {
+ back = dk4recode_char_to_wchar_t(dptr, szdptr, buf, erp);
+ }
+ return back;
+}
+
+int
+dk4fileinfo_type_attributes_wc(
+ wchar_t *dptr,
+ size_t szdptr,
+ dk4_file_info_t *fi,
+ dk4_er_t *erp
+)
+{
+ char buf[64];
+ int back = 0;
+ if (0 != dk4fileinfo_type_attributes_c8(buf, sizeof(buf), fi, erp)) {
+ back = dk4recode_char_to_wchar_t(dptr, szdptr, buf, erp);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4fileigw.ctr b/support/dktools/dk4fileigw.ctr
new file mode 100644
index 0000000000..f810320433
--- /dev/null
+++ b/support/dktools/dk4fileigw.ctr
@@ -0,0 +1,48 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4filei.h"
+
+#include "dk4rec23.h"
+
+int
+dk4fileinfo_timestamp_wc(
+ wchar_t *dptr,
+ size_t szdptr,
+ const dk4_file_info_t *fi,
+ int chfile,
+ int chtime,
+ dk4_er_t *erp
+)
+{
+ char buf[64];
+ int back = 0;
+ if (0 != dk4fileinfo_timestamp_c8(buf,sizeof(buf),fi,chfile,chtime,erp)) {
+ back = dk4recode_char_to_wchar_t(dptr, szdptr, buf, erp);
+ }
+ return back;
+}
+
+int
+dk4fileinfo_type_attributes_wc(
+ wchar_t *dptr,
+ size_t szdptr,
+ dk4_file_info_t *fi,
+ dk4_er_t *erp
+)
+{
+ char buf[64];
+ int back = 0;
+ if (0 != dk4fileinfo_type_attributes_c8(buf, sizeof(buf), fi, erp)) {
+ back = dk4recode_char_to_wchar_t(dptr, szdptr, buf, erp);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4fileit.h b/support/dktools/dk4fileit.h
new file mode 100644
index 0000000000..a809e4d4d0
--- /dev/null
+++ b/support/dktools/dk4fileit.h
@@ -0,0 +1,107 @@
+#ifndef DK4FILEIT_H_INCLUDED
+/** Protection against multiple inclusions. */
+#define DK4FILEIT_H_INCLUDED 1
+
+/** @file dk4fileit.h File information data type.
+
+ The dk4_file_info_t data type and related functions allow to
+ properly identify a path name as symbolic link on both non-Windows
+ and Windows systems.
+
+ On non-Windows systems calls to stat() and lstat() are used to
+ retrieve the information.
+
+ On Windows systems calls to GetFileAttributes(),
+ CreateFile()/GetFileInformationByHandle()
+ and FindFirstFile() are used.
+ As the involved data types are Windows-specific the windows.h
+ header file is pulled in by this header.
+
+ The Windows functions to retrieve information about files differ:
+ - GetFileAttributes() returns a DWORD containing bits for
+ file attributes only.
+ - From CreateFile()/GetFileInformationByHandle() we can receive
+ very detailed information.
+ - From FindFirstFile() we can retrieve some of the information
+ also provided by CreateFile()/GetFileInformationByHandle(), but
+ number of links, volume serial number, and file index are not
+ available.
+ Unfortunately the functions behave differently: While FindFirstFile()
+ succeeds for c:/pagefile.sys and other files in the root directory,
+ GetFileAttributes() and CreateFile()/GetFileInformationByHandle()
+ fail in non-privileged processes. Some forum messages state that
+ FindFirstFile() is significantly faster than
+ CreateFile()/GetFileInformationByHandle(), at least for files on servers.
+ When called for a symbolic link, FindFirstFile() always returns information
+ about the link. For CreateFile()/GetFileInformationByHandle() one can
+ choose whether to obtain information about the or about the target.
+
+ So the dk4fileinfo() function attempts GetFileAttributes() and
+ CreateFile()/GetFileInformationByHandle() first to obtain detailed
+ information. If these functions fail, the FindFirstFile() function is
+ used. If only FindFirstFile() returned successfully, the resio
+ component is set to a non-zero value to indicate that only restricted
+ information (without number of links, volume serial number, and
+ file index) is available.
+*/
+
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4statt.h"
+
+/** File information contents found.
+*/
+enum {
+ /** Information about the link
+ from lstat().
+ */
+ DK4_FILE_INFO_CONTENTS_DATA_LINK = 1,
+
+ /** Information about the link
+ target from stat().
+ */
+ DK4_FILE_INFO_CONTENTS_DATA_TARGET = 2
+};
+
+/** Choose timestamp to convert to text.
+*/
+enum {
+ /** Creation time.
+ */
+ DK4_FILE_INFO_TIME_CREATE = 1,
+
+ /** Modification time.
+ */
+ DK4_FILE_INFO_TIME_MODIFY ,
+
+ /** Last access time.
+ */
+ DK4_FILE_INFO_TIME_ACCESS
+};
+
+/** File information data type.
+*/
+typedef struct {
+ int contents; /**< The available contents. */
+#if DK4_ON_WINDOWS
+ BY_HANDLE_FILE_INFORMATION linfo; /**< Information about link. */
+ BY_HANDLE_FILE_INFORMATION tinfo; /**< Information about target. */
+ DWORD fattr; /**< Link file attributes. */
+ DWORD rppnt; /**< Link reparse point tag. */
+ DWORD resio; /**< Flag: Restricted information. */
+#else
+ dk4_stat_t lstb; /**< Buffer for lstat(). */
+ dk4_stat_t tstb; /**< Buffer for stat(). */
+#endif
+} dk4_file_info_t;
+
+#endif
+
diff --git a/support/dktools/dk4fileiu.c b/support/dktools/dk4fileiu.c
new file mode 100644
index 0000000000..0152a0380e
--- /dev/null
+++ b/support/dktools/dk4fileiu.c
@@ -0,0 +1,128 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fileiu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4fileiu.c The dk4fileiu module.
+*/
+
+
+#line 10 "dk4fileiu.ctr"
+
+#include "dk4filei.h"
+
+
+
+
+#line 15 "dk4fileiu.ctr"
+
+
+#if DK4_ON_WINDOWS
+
+static
+void
+dk4fileinfo_copy_ufi(
+ dk4_ufi_t *uptr,
+ const BY_HANDLE_FILE_INFORMATION *bhfi
+)
+{
+ uptr->ser = bhfi->dwVolumeSerialNumber;
+ uptr->inh = bhfi->nFileIndexHigh;
+ uptr->inl = bhfi->nFileIndexLow;
+}
+
+#else
+
+static
+void
+dk4fileinfo_copy_ufi(
+ dk4_ufi_t *uptr,
+ const dk4_stat_t *stb
+)
+{
+ uptr->dev = stb->st_dev;
+ uptr->ino = stb->st_ino;
+}
+
+#endif
+
+
+int
+dk4fileinfo_ufi(
+ dk4_ufi_t *dptr, const dk4_file_info_t *src, int ch, dk4_er_t *erp
+)
+{
+ int back = 0;
+ if ((NULL != dptr) && (NULL != src)) {
+ switch (ch) {
+ case DK4_FILE_INFO_CONTENTS_DATA_LINK: {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & (src->contents))) {
+ back = 1;
+#if DK4_ON_WINDOWS
+ if ((DWORD)0UL == src->resio) {
+ dk4fileinfo_copy_ufi(dptr, &(src->linfo));
+ } else {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+#else
+ dk4fileinfo_copy_ufi(dptr, &(src->lstb));
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } break;
+ default: {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & (src->contents))) {
+ back = 1;
+#if DK4_ON_WINDOWS
+ if ((DWORD)0UL == src->resio) {
+ dk4fileinfo_copy_ufi(dptr, &(src->tinfo));
+ } else {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+#else
+ dk4fileinfo_copy_ufi(dptr, &(src->tstb));
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4fileiu.ctr b/support/dktools/dk4fileiu.ctr
new file mode 100644
index 0000000000..18c4bb2760
--- /dev/null
+++ b/support/dktools/dk4fileiu.ctr
@@ -0,0 +1,95 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4filei.h"
+
+
+$!trace-include
+
+
+#if DK4_ON_WINDOWS
+
+static
+void
+dk4fileinfo_copy_ufi(
+ dk4_ufi_t *uptr,
+ const BY_HANDLE_FILE_INFORMATION *bhfi
+)
+{
+ uptr->ser = bhfi->dwVolumeSerialNumber;
+ uptr->inh = bhfi->nFileIndexHigh;
+ uptr->inl = bhfi->nFileIndexLow;
+}
+
+#else
+
+static
+void
+dk4fileinfo_copy_ufi(
+ dk4_ufi_t *uptr,
+ const dk4_stat_t *stb
+)
+{
+ uptr->dev = stb->st_dev;
+ uptr->ino = stb->st_ino;
+}
+
+#endif
+
+
+int
+dk4fileinfo_ufi(
+ dk4_ufi_t *dptr, const dk4_file_info_t *src, int ch, dk4_er_t *erp
+)
+{
+ int back = 0;
+ if ((NULL != dptr) && (NULL != src)) {
+ switch (ch) {
+ case DK4_FILE_INFO_CONTENTS_DATA_LINK: {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_LINK & (src->contents))) {
+ back = 1;
+#if DK4_ON_WINDOWS
+ if ((DWORD)0UL == src->resio) {
+ dk4fileinfo_copy_ufi(dptr, &(src->linfo));
+ } else {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+#else
+ dk4fileinfo_copy_ufi(dptr, &(src->lstb));
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } break;
+ default: {
+ if (0 != (DK4_FILE_INFO_CONTENTS_DATA_TARGET & (src->contents))) {
+ back = 1;
+#if DK4_ON_WINDOWS
+ if ((DWORD)0UL == src->resio) {
+ dk4fileinfo_copy_ufi(dptr, &(src->tinfo));
+ } else {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+#else
+ dk4fileinfo_copy_ufi(dptr, &(src->tstb));
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4fileiu.h b/support/dktools/dk4fileiu.h
new file mode 100644
index 0000000000..ca6a6413a6
--- /dev/null
+++ b/support/dktools/dk4fileiu.h
@@ -0,0 +1,88 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fileiu.ctr
+*/
+
+/*
+Copyright (C) 2015, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4FILEIU_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4FILEIU_H_INCLUDED 1
+
+
+#line 10 "dk4fileiu.ctr"
+
+/** @file dk4fileiu.h Retrieve unique file identifier from
+ file information structure.
+*/
+
+#ifndef DK4FILEIT_H_INCLUDED
+#include "dk4fileit.h"
+#endif
+
+#ifndef DK4UFI_H_INCLUDED
+#include "dk4ufi.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve unique file identifier from file information structure.
+ @param dptr Pointer to destination variable.
+ @param src File information structure to retrieve information from.
+ @param ch For symbolic links choose between information
+ for link itself (DK4_FILE_INFO_CONTENTS_DATA_LINK)
+ or link target (DK4_FILE_INFO_CONTENTS_DATA_TARGET).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if dptr or src is NULL,
+ DK4_E_NOT_FOUND if the information is not present in the
+ file information structure.
+*/
+int
+dk4fileinfo_ufi(
+ dk4_ufi_t *dptr, const dk4_file_info_t *src, int ch, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4fileiw.c b/support/dktools/dk4fileiw.c
new file mode 100644
index 0000000000..8e614dc6be
--- /dev/null
+++ b/support/dktools/dk4fileiw.c
@@ -0,0 +1,273 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fileiw.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4fileiw.c The dk4fileiw module.
+*/
+
+
+#line 10 "dk4fileiw.ctr"
+
+#include "dk4filei.h"
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4STAT8_H_INCLUDED
+#include "dk4statw.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+
+
+#line 28 "dk4fileiw.ctr"
+
+
+
+int
+dk4fileinfo_wc(dk4_file_info_t *dptr, const wchar_t *fn, dk4_er_t *erp)
+{
+ dk4_er_t er;
+#if DK4_ON_WINDOWS
+ WIN32_FIND_DATAW ffdata;
+ HANDLE ha;
+ DWORD dwatt;
+ int i;
+ int found;
+ int isdir;
+#endif
+ int back = 0;
+
+
+#line 45 "dk4fileiw.ctr"
+ if ((NULL != dptr) && (NULL != fn)) {
+
+#line 46 "dk4fileiw.ctr"
+ dk4error_init(&er);
+ DK4_MEMRES(dptr, sizeof(dk4_file_info_t));
+ dptr->contents = 0;
+#if DK4_ON_WINDOWS
+ dptr->rppnt = (DWORD)0UL;
+ dptr->fattr = GetFileAttributesW(fn);
+ dptr->resio = 0UL;
+ if (INVALID_FILE_ATTRIBUTES == dptr->fattr) {
+ ha = FindFirstFileW(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != ha) {
+ dptr->fattr = ffdata.dwFileAttributes;
+ FindClose(ha);
+ }
+ }
+ if (INVALID_FILE_ATTRIBUTES != dptr->fattr) {
+ isdir = 0;
+ if (0 != (FILE_ATTRIBUTE_DIRECTORY & (dptr->fattr))) { isdir = 1; }
+ /* Symlink */
+ found = 0;
+
+#line 65 "dk4fileiw.ctr"
+ for (i = 0; ((3 > i) && (0 == found)); i++) {
+
+#line 66 "dk4fileiw.ctr"
+ dwatt = dptr->fattr;
+ dwatt |= FILE_FLAG_OPEN_REPARSE_POINT;
+ if (0 != isdir) { dwatt |= FILE_FLAG_BACKUP_SEMANTICS; }
+ ha = CreateFileW(
+ fn,
+ (
+ (0 == i)
+ ? (0) :
+ ((1 == i) ? (FILE_READ_ATTRIBUTES) : (GENERIC_READ))
+ ),
+ (FILE_SHARE_READ | FILE_SHARE_WRITE),
+ NULL,
+ OPEN_EXISTING,
+ dwatt,
+ NULL
+ );
+ if (INVALID_HANDLE_VALUE != ha) {
+
+#line 83 "dk4fileiw.ctr"
+ if (GetFileInformationByHandle(ha, &(dptr->linfo))) {
+ found = 1;
+
+#line 85 "dk4fileiw.ctr"
+ back = 1;
+ dptr->contents |= DK4_FILE_INFO_CONTENTS_DATA_LINK;
+ } else {
+
+#line 88 "dk4fileiw.ctr"
+ if (1 == i) {
+ dk4error_set_ldetails(
+ &er, DK4_E_FILE_INFORMATION_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ }
+ CloseHandle(ha);
+ } else {
+
+#line 97 "dk4fileiw.ctr"
+ if (1 == i) {
+ dk4error_set_ldetails(
+ &er, DK4_E_CREATE_FILE_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ }
+ }
+ /* Target */
+ found = 0;
+
+#line 107 "dk4fileiw.ctr"
+ for (i = 0; ((3 > i) && (0 == found)); i++) {
+
+#line 108 "dk4fileiw.ctr"
+ dwatt = dptr->fattr;
+ if (0 != isdir) { dwatt |= FILE_FLAG_BACKUP_SEMANTICS; }
+ ha = CreateFileW(
+ fn,
+ (
+ (0 == i)
+ ? (0)
+ : ((1 == i) ? (FILE_READ_ATTRIBUTES) : (GENERIC_READ))
+ ),
+ (FILE_SHARE_READ | FILE_SHARE_WRITE),
+ NULL,
+ OPEN_EXISTING,
+ dwatt,
+ NULL
+ );
+ if (INVALID_HANDLE_VALUE != ha) {
+
+#line 124 "dk4fileiw.ctr"
+ if (GetFileInformationByHandle(ha, &(dptr->tinfo))) {
+ found = 1;
+
+#line 126 "dk4fileiw.ctr"
+ back = 1;
+ dptr->contents |= DK4_FILE_INFO_CONTENTS_DATA_TARGET;
+ } else {
+
+#line 129 "dk4fileiw.ctr"
+ if (1 == i) {
+ dk4error_set_ldetails(
+ &er, DK4_E_FILE_INFORMATION_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ }
+ CloseHandle(ha);
+ } else {
+
+#line 138 "dk4fileiw.ctr"
+ if (1 == i) {
+ dk4error_set_ldetails(
+ &er, DK4_E_CREATE_FILE_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ }
+ }
+ /* FindFirstFile */
+ if (0 != back) {
+
+#line 148 "dk4fileiw.ctr"
+ ha = FindFirstFileW(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != ha) {
+
+#line 150 "dk4fileiw.ctr"
+ dptr->fattr = ffdata.dwFileAttributes;
+ dptr->rppnt = ffdata.dwReserved0;
+ FindClose(ha);
+ }
+ } else {
+
+#line 155 "dk4fileiw.ctr"
+ ha = FindFirstFileW(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != ha) {
+
+#line 157 "dk4fileiw.ctr"
+ back = 1;
+ dptr->fattr = ffdata.dwFileAttributes;
+ dptr->rppnt = ffdata.dwReserved0;
+ dptr->resio = 1UL;
+ (dptr->linfo).dwFileAttributes = ffdata.dwFileAttributes;
+ (dptr->linfo).ftCreationTime = ffdata.ftCreationTime;
+ (dptr->linfo).ftLastAccessTime = ffdata.ftLastAccessTime;
+ (dptr->linfo).ftLastWriteTime = ffdata.ftLastWriteTime;
+ (dptr->linfo).nFileSizeHigh = ffdata.nFileSizeHigh;
+ (dptr->linfo).nFileSizeLow = ffdata.nFileSizeLow;
+ (dptr->tinfo).dwFileAttributes = ffdata.dwFileAttributes;
+ (dptr->tinfo).ftCreationTime = ffdata.ftCreationTime;
+ (dptr->tinfo).ftLastAccessTime = ffdata.ftLastAccessTime;
+ (dptr->tinfo).ftLastWriteTime = ffdata.ftLastWriteTime;
+ (dptr->tinfo).nFileSizeHigh = ffdata.nFileSizeHigh;
+ (dptr->tinfo).nFileSizeLow = ffdata.nFileSizeLow;
+ dptr->contents |= DK4_FILE_INFO_CONTENTS_DATA_TARGET;
+ dptr->contents |= DK4_FILE_INFO_CONTENTS_DATA_LINK;
+ FindClose(ha);
+ } else {
+
+#line 177 "dk4fileiw.ctr"
+ }
+ }
+ } else {
+ /* ERROR: GetFileAttributes failed! */
+ dk4error_set_ldetails(
+ &er, DK4_E_SYSTEM,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+#else
+ dk4error_set_simple_error_code(&er, DK4_E_NOT_SUPPORTED);
+#endif
+ if (0 == back) {
+ dk4error_copy(erp, &er);
+ }
+ } else {
+
+#line 193 "dk4fileiw.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 195 "dk4fileiw.ctr"
+ return back;
+}
+
+
diff --git a/support/dktools/dk4fileiw.ctr b/support/dktools/dk4fileiw.ctr
new file mode 100644
index 0000000000..2e3c880ce1
--- /dev/null
+++ b/support/dktools/dk4fileiw.ctr
@@ -0,0 +1,198 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4filei.h"
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4STAT8_H_INCLUDED
+#include "dk4statw.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+$!trace-include
+
+
+
+int
+dk4fileinfo_wc(dk4_file_info_t *dptr, const wchar_t *fn, dk4_er_t *erp)
+{
+ dk4_er_t er;
+#if DK4_ON_WINDOWS
+ WIN32_FIND_DATAW ffdata;
+ HANDLE ha;
+ DWORD dwatt;
+ int i;
+ int found;
+ int isdir;
+#endif
+ int back = 0;
+ $? "+ dk4fileinfo_wc"
+ if ((NULL != dptr) && (NULL != fn)) { $? ". args ok"
+ dk4error_init(&er);
+ DK4_MEMRES(dptr, sizeof(dk4_file_info_t));
+ dptr->contents = 0;
+#if DK4_ON_WINDOWS
+ dptr->rppnt = (DWORD)0UL;
+ dptr->fattr = GetFileAttributesW(fn);
+ dptr->resio = 0UL;
+ if (INVALID_FILE_ATTRIBUTES == dptr->fattr) {
+ ha = FindFirstFileW(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != ha) {
+ dptr->fattr = ffdata.dwFileAttributes;
+ FindClose(ha);
+ }
+ }
+ if (INVALID_FILE_ATTRIBUTES != dptr->fattr) {
+ isdir = 0;
+ if (0 != (FILE_ATTRIBUTE_DIRECTORY & (dptr->fattr))) { isdir = 1; }
+ /* Symlink */
+ found = 0; $? ". symlink"
+ for (i = 0; ((3 > i) && (0 == found)); i++) { $? ". pass %d", i
+ dwatt = dptr->fattr;
+ dwatt |= FILE_FLAG_OPEN_REPARSE_POINT;
+ if (0 != isdir) { dwatt |= FILE_FLAG_BACKUP_SEMANTICS; }
+ ha = CreateFileW(
+ fn,
+ (
+ (0 == i)
+ ? (0) :
+ ((1 == i) ? (FILE_READ_ATTRIBUTES) : (GENERIC_READ))
+ ),
+ (FILE_SHARE_READ | FILE_SHARE_WRITE),
+ NULL,
+ OPEN_EXISTING,
+ dwatt,
+ NULL
+ );
+ if (INVALID_HANDLE_VALUE != ha) { $? ". handle"
+ if (GetFileInformationByHandle(ha, &(dptr->linfo))) {
+ found = 1; $? ". file information"
+ back = 1;
+ dptr->contents |= DK4_FILE_INFO_CONTENTS_DATA_LINK;
+ } else { $? "! file information"
+ if (1 == i) {
+ dk4error_set_ldetails(
+ &er, DK4_E_FILE_INFORMATION_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ }
+ CloseHandle(ha);
+ } else { $? "! CreateFile"
+ if (1 == i) {
+ dk4error_set_ldetails(
+ &er, DK4_E_CREATE_FILE_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ }
+ }
+ /* Target */
+ found = 0; $? ". target"
+ for (i = 0; ((3 > i) && (0 == found)); i++) { $? ". pass %d", i
+ dwatt = dptr->fattr;
+ if (0 != isdir) { dwatt |= FILE_FLAG_BACKUP_SEMANTICS; }
+ ha = CreateFileW(
+ fn,
+ (
+ (0 == i)
+ ? (0)
+ : ((1 == i) ? (FILE_READ_ATTRIBUTES) : (GENERIC_READ))
+ ),
+ (FILE_SHARE_READ | FILE_SHARE_WRITE),
+ NULL,
+ OPEN_EXISTING,
+ dwatt,
+ NULL
+ );
+ if (INVALID_HANDLE_VALUE != ha) { $? ". CreateFile"
+ if (GetFileInformationByHandle(ha, &(dptr->tinfo))) {
+ found = 1; $? ". file info"
+ back = 1;
+ dptr->contents |= DK4_FILE_INFO_CONTENTS_DATA_TARGET;
+ } else { $? "! file info"
+ if (1 == i) {
+ dk4error_set_ldetails(
+ &er, DK4_E_FILE_INFORMATION_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ }
+ CloseHandle(ha);
+ } else { $? "! CreateFile"
+ if (1 == i) {
+ dk4error_set_ldetails(
+ &er, DK4_E_CREATE_FILE_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ }
+ }
+ /* FindFirstFile */
+ if (0 != back) { $? ". information already found"
+ ha = FindFirstFileW(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != ha) { $? ". FindFirstFile"
+ dptr->fattr = ffdata.dwFileAttributes;
+ dptr->rppnt = ffdata.dwReserved0;
+ FindClose(ha);
+ }
+ } else { $? ". no information yet"
+ ha = FindFirstFileW(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != ha) { $? ". FindFirstFileW"
+ back = 1;
+ dptr->fattr = ffdata.dwFileAttributes;
+ dptr->rppnt = ffdata.dwReserved0;
+ dptr->resio = 1UL;
+ (dptr->linfo).dwFileAttributes = ffdata.dwFileAttributes;
+ (dptr->linfo).ftCreationTime = ffdata.ftCreationTime;
+ (dptr->linfo).ftLastAccessTime = ffdata.ftLastAccessTime;
+ (dptr->linfo).ftLastWriteTime = ffdata.ftLastWriteTime;
+ (dptr->linfo).nFileSizeHigh = ffdata.nFileSizeHigh;
+ (dptr->linfo).nFileSizeLow = ffdata.nFileSizeLow;
+ (dptr->tinfo).dwFileAttributes = ffdata.dwFileAttributes;
+ (dptr->tinfo).ftCreationTime = ffdata.ftCreationTime;
+ (dptr->tinfo).ftLastAccessTime = ffdata.ftLastAccessTime;
+ (dptr->tinfo).ftLastWriteTime = ffdata.ftLastWriteTime;
+ (dptr->tinfo).nFileSizeHigh = ffdata.nFileSizeHigh;
+ (dptr->tinfo).nFileSizeLow = ffdata.nFileSizeLow;
+ dptr->contents |= DK4_FILE_INFO_CONTENTS_DATA_TARGET;
+ dptr->contents |= DK4_FILE_INFO_CONTENTS_DATA_LINK;
+ FindClose(ha);
+ } else { $? "! FindFirstFileW"
+ }
+ }
+ } else {
+ /* ERROR: GetFileAttributes failed! */
+ dk4error_set_ldetails(
+ &er, DK4_E_SYSTEM,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+#else
+ dk4error_set_simple_error_code(&er, DK4_E_NOT_SUPPORTED);
+#endif
+ if (0 == back) {
+ dk4error_copy(erp, &er);
+ }
+ } else { $? "! args"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4fileinfo_wc %d", back
+ return back;
+}
+
+
diff --git a/support/dktools/dk4fileiw.h b/support/dktools/dk4fileiw.h
new file mode 100644
index 0000000000..43a31c4c0d
--- /dev/null
+++ b/support/dktools/dk4fileiw.h
@@ -0,0 +1,81 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fileiw.ctr
+*/
+
+/*
+Copyright (C) 2015, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4fileiw.h File information for wide-character file names.
+*/
+
+#ifndef DK4FILEIW_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4FILEIW_H_INCLUDED 1
+
+
+#line 10 "dk4fileiw.ctr"
+
+/** @file dk4filei8.h File information for files specified
+ by char path name.
+*/
+
+#ifndef DK4FILEIT_H_INCLUDED
+#include "dk4fileit.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve full information for a path name.
+ For symbolic links attempt to retrieve information both
+ about the link and about the link target.
+ @param dptr Pointer to result structure.
+ @param fn File path name.
+ @param erp Error report, may be NULL.
+ @return 1 if information is found, 0 otherwise.
+ If information about the link is found and no information about
+ the target, the function returns 1 as we can recognize the
+ directory item as a dangling link (link with non-existing target).
+*/
+int
+dk4fileinfo_wc(dk4_file_info_t *dptr, const wchar_t *fn, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4filew.c b/support/dktools/dk4filew.c
new file mode 100644
index 0000000000..cfb464e284
--- /dev/null
+++ b/support/dktools/dk4filew.c
@@ -0,0 +1,172 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4filew.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4filew.c The dk4filew module.
+*/
+
+
+#line 97 "dk4filew.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#else
+#ifndef DK4STATW_H_INCLUDED
+#include "dk4statw.h"
+#endif
+#endif
+
+#include "dk4filew.h"
+
+
+int
+dk4file_wc_exists(const wchar_t *fn, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ DWORD dwattr;
+ HANDLE ha;
+ WIN32_FIND_DATAW ffdata;
+#endif
+ int back = 0;
+#if DK4_ON_WINDOWS
+ if (NULL != fn) {
+ dwattr = GetFileAttributesW(fn);
+ if (INVALID_FILE_ATTRIBUTES != dwattr) {
+ back = 1;
+ } else {
+ ha = FindFirstFileW(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != ha) {
+ back = 1;
+ FindClose(ha);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ return back;
+}
+
+
+
+int
+dk4file_wc_is_regular(const wchar_t *fn, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ DWORD dwattr;
+ HANDLE ha;
+ WIN32_FIND_DATAW ffdata;
+ int back = 0;
+ if (NULL != fn) {
+ dwattr = GetFileAttributesW(fn);
+ if (INVALID_FILE_ATTRIBUTES != dwattr) {
+ if ((DWORD)0UL == (FILE_ATTRIBUTE_DIRECTORY & dwattr)) {
+ if ((DWORD)0UL == (FILE_ATTRIBUTE_DEVICE & dwattr)) {
+ back = 1;
+ }
+ }
+ } else {
+ ha = FindFirstFileW(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != ha) {
+ dwattr = ffdata.dwFileAttributes;
+ if ((DWORD)0UL == (FILE_ATTRIBUTE_DIRECTORY & dwattr)) {
+ if ((DWORD)0UL == (FILE_ATTRIBUTE_DEVICE & dwattr)) {
+ back = 1;
+ }
+ }
+ FindClose(ha);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+}
+
+
+
+int
+dk4file_wc_is_directory(const wchar_t *fn, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ WIN32_FIND_DATAW ffdata;
+ DWORD dwattr;
+ HANDLE ha;
+ int back = 0;
+ if (NULL != fn) {
+ dwattr = GetFileAttributesW(fn);
+ if (INVALID_FILE_ATTRIBUTES != dwattr) {
+ if ((DWORD)0UL != (FILE_ATTRIBUTE_DIRECTORY & dwattr)) {
+ back = 1;
+ }
+ } else {
+ ha = FindFirstFileW(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != ha) {
+ dwattr = ffdata.dwFileAttributes;
+ if ((DWORD)0UL != (FILE_ATTRIBUTE_DIRECTORY & dwattr)) {
+ back = 1;
+ }
+ FindClose(ha);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+}
+
+
+
diff --git a/support/dktools/dk4filew.ctr b/support/dktools/dk4filew.ctr
new file mode 100644
index 0000000000..53f5d3f20e
--- /dev/null
+++ b/support/dktools/dk4filew.ctr
@@ -0,0 +1,228 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ File checks.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Check whether a path exists.
+ CRT on Windows: Not used.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 if file exists, 0 otherwise.
+ Note: The function also returns 0 if it fails to obtain information
+ about a file, i.e. due to missing permissions...
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ on non-Windows systems,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_NOT_FOUND<br>
+ if the specified file was not found or retrieving information
+ failed for other reasons.
+*/
+int
+dk4file_wc_exists(const wchar_t *fn, dk4_er_t *erp);
+
+/** Check whether a path name specifies a regular file.
+ CRT on Windows: Not used.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 for existing regular file, 0 otherwise.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ on non-Windows systems,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_NOT_FOUND<br>
+ if the file does not exist or retrieving the information failed
+ for some reason,
+ - none<br>
+ if the path exists but is not a regular file.
+*/
+int
+dk4file_wc_is_regular(const wchar_t *fn, dk4_er_t *erp);
+
+/** Check whether a path name specifies a directory.
+ CRT on Windows: Not used.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 for existing directory, 0 otherwise.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ on non-Windows systems,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_NOT_FOUND<br>
+ if the file does not exist or retrieving the information failed for
+ some reason,
+ - none if the path exists but is not a directory.
+*/
+int
+dk4file_wc_is_directory(const wchar_t *fn, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#else
+#ifndef DK4STATW_H_INCLUDED
+#include "dk4statw.h"
+#endif
+#endif
+
+#include "dk4filew.h"
+
+
+int
+dk4file_wc_exists(const wchar_t *fn, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ DWORD dwattr;
+ HANDLE ha;
+ WIN32_FIND_DATAW ffdata;
+#endif
+ int back = 0;
+#if DK4_ON_WINDOWS
+ if (NULL != fn) {
+ dwattr = GetFileAttributesW(fn);
+ if (INVALID_FILE_ATTRIBUTES != dwattr) {
+ back = 1;
+ } else {
+ ha = FindFirstFileW(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != ha) {
+ back = 1;
+ FindClose(ha);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ return back;
+}
+
+
+
+int
+dk4file_wc_is_regular(const wchar_t *fn, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ DWORD dwattr;
+ HANDLE ha;
+ WIN32_FIND_DATAW ffdata;
+ int back = 0;
+ if (NULL != fn) {
+ dwattr = GetFileAttributesW(fn);
+ if (INVALID_FILE_ATTRIBUTES != dwattr) {
+ if ((DWORD)0UL == (FILE_ATTRIBUTE_DIRECTORY & dwattr)) {
+ if ((DWORD)0UL == (FILE_ATTRIBUTE_DEVICE & dwattr)) {
+ back = 1;
+ }
+ }
+ } else {
+ ha = FindFirstFileW(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != ha) {
+ dwattr = ffdata.dwFileAttributes;
+ if ((DWORD)0UL == (FILE_ATTRIBUTE_DIRECTORY & dwattr)) {
+ if ((DWORD)0UL == (FILE_ATTRIBUTE_DEVICE & dwattr)) {
+ back = 1;
+ }
+ }
+ FindClose(ha);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+}
+
+
+
+int
+dk4file_wc_is_directory(const wchar_t *fn, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ WIN32_FIND_DATAW ffdata;
+ DWORD dwattr;
+ HANDLE ha;
+ int back = 0;
+ if (NULL != fn) {
+ dwattr = GetFileAttributesW(fn);
+ if (INVALID_FILE_ATTRIBUTES != dwattr) {
+ if ((DWORD)0UL != (FILE_ATTRIBUTE_DIRECTORY & dwattr)) {
+ back = 1;
+ }
+ } else {
+ ha = FindFirstFileW(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != ha) {
+ dwattr = ffdata.dwFileAttributes;
+ if ((DWORD)0UL != (FILE_ATTRIBUTE_DIRECTORY & dwattr)) {
+ back = 1;
+ }
+ FindClose(ha);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+}
+
+
+
diff --git a/support/dktools/dk4filew.h b/support/dktools/dk4filew.h
new file mode 100644
index 0000000000..ac3d97df6b
--- /dev/null
+++ b/support/dktools/dk4filew.h
@@ -0,0 +1,129 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4filew.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4FILEW_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4FILEW_H_INCLUDED 1
+
+
+#line 10 "dk4filew.ctr"
+
+/** @file
+ File checks.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Check whether a path exists.
+ CRT on Windows: Not used.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 if file exists, 0 otherwise.
+ Note: The function also returns 0 if it fails to obtain information
+ about a file, i.e. due to missing permissions...
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ on non-Windows systems,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_NOT_FOUND<br>
+ if the specified file was not found or retrieving information
+ failed for other reasons.
+*/
+int
+dk4file_wc_exists(const wchar_t *fn, dk4_er_t *erp);
+
+/** Check whether a path name specifies a regular file.
+ CRT on Windows: Not used.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 for existing regular file, 0 otherwise.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ on non-Windows systems,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_NOT_FOUND<br>
+ if the file does not exist or retrieving the information failed
+ for some reason,
+ - none<br>
+ if the path exists but is not a regular file.
+*/
+int
+dk4file_wc_is_regular(const wchar_t *fn, dk4_er_t *erp);
+
+/** Check whether a path name specifies a directory.
+ CRT on Windows: Not used.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 for existing directory, 0 otherwise.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ on non-Windows systems,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_NOT_FOUND<br>
+ if the file does not exist or retrieving the information failed for
+ some reason,
+ - none if the path exists but is not a directory.
+*/
+int
+dk4file_wc_is_directory(const wchar_t *fn, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4fne.c b/support/dktools/dk4fne.c
new file mode 100644
index 0000000000..1b28761d14
--- /dev/null
+++ b/support/dktools/dk4fne.c
@@ -0,0 +1,65 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fne.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4fne.c The dk4fne module.
+*/
+
+
+#line 70 "dk4fne.ctr"
+
+#include "dk4fne.h"
+
+#if DK4_CHAR_SIZE > 1
+#ifndef DK4FNEWC_H_INCLUDED
+#include "dk4fnewc.h"
+#endif
+#else
+#ifndef DK4FNE08_H_INCLUDED
+#include "dk4fne08.h"
+#endif
+#endif
+
+
+
+dk4_dir_t *
+dk4fne_open(const dkChar *pattern, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4fne_open_wc(pattern, erp));
+#else
+ return (dk4fne_open_c8(pattern, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4fne.ctr b/support/dktools/dk4fne.ctr
new file mode 100644
index 0000000000..93c37489f3
--- /dev/null
+++ b/support/dktools/dk4fne.ctr
@@ -0,0 +1,94 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ File name expander.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4DIR_H_INCLUDED
+#include "dk4dir.h"
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Expand a file name.
+ @param pattern File name pattern, may optionally include
+ a directory part.
+ @param erp Error report, may be NULL.
+ @return Directory structure on success, NULL on error.
+ On success the path component in the returned directory structure
+ is NULL if the pattern did not contain a directory part.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if path is NULL,
+ - DK4_E_NOT_SUPPORTED<br>
+ if no function to traverse directories was found during build
+ process or the function is called on a non-Windows system,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if a memory allocation failed,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in a size calculation,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if one of the involved directory or file names is too long for an
+ internal buffer,
+ - DK4_E_OPENDIR_FAILED<br>
+ with errno value in iDetails1 if the attempt to open the directory
+ failed,
+ - DK4_E_FINDFIRSTFILE_FAILED<br>
+ with GetLastError() value in lDetails1 if the FindFirstFile()
+ function failed on Windows,
+ - DK4_E_SYSTEM<br>
+ if the stat() or lstat() function failed for one of the directory
+ items.
+*/
+dk4_dir_t *
+dk4fne_open(const dkChar *pattern, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4fne.h"
+
+#if DK4_CHAR_SIZE > 1
+#ifndef DK4FNEWC_H_INCLUDED
+#include "dk4fnewc.h"
+#endif
+#else
+#ifndef DK4FNE08_H_INCLUDED
+#include "dk4fne08.h"
+#endif
+#endif
+
+
+
+dk4_dir_t *
+dk4fne_open(const dkChar *pattern, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4fne_open_wc(pattern, erp));
+#else
+ return (dk4fne_open_c8(pattern, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4fne.h b/support/dktools/dk4fne.h
new file mode 100644
index 0000000000..55de1709cd
--- /dev/null
+++ b/support/dktools/dk4fne.h
@@ -0,0 +1,103 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fne.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4FNE_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4FNE_H_INCLUDED 1
+
+
+#line 9 "dk4fne.ctr"
+
+/** @file
+ File name expander.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4DIR_H_INCLUDED
+#include "dk4dir.h"
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Expand a file name.
+ @param pattern File name pattern, may optionally include
+ a directory part.
+ @param erp Error report, may be NULL.
+ @return Directory structure on success, NULL on error.
+ On success the path component in the returned directory structure
+ is NULL if the pattern did not contain a directory part.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if path is NULL,
+ - DK4_E_NOT_SUPPORTED<br>
+ if no function to traverse directories was found during build
+ process or the function is called on a non-Windows system,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if a memory allocation failed,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in a size calculation,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if one of the involved directory or file names is too long for an
+ internal buffer,
+ - DK4_E_OPENDIR_FAILED<br>
+ with errno value in iDetails1 if the attempt to open the directory
+ failed,
+ - DK4_E_FINDFIRSTFILE_FAILED<br>
+ with GetLastError() value in lDetails1 if the FindFirstFile()
+ function failed on Windows,
+ - DK4_E_SYSTEM<br>
+ if the stat() or lstat() function failed for one of the directory
+ items.
+*/
+dk4_dir_t *
+dk4fne_open(const dkChar *pattern, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4fne08.c b/support/dktools/dk4fne08.c
new file mode 100644
index 0000000000..379fb0ab28
--- /dev/null
+++ b/support/dktools/dk4fne08.c
@@ -0,0 +1,184 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fne08.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4fne08.c The dk4fne08 module.
+*/
+
+
+#line 64 "dk4fne08.ctr"
+
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4fne08.h"
+#include "dk4str8.h"
+#include "dk4mem.h"
+
+
+
+
+
+#line 82 "dk4fne08.ctr"
+
+
+
+/** Constant texts used by the module.
+*/
+static const char * const dk4fne_c8_kw[] = {
+/* 0 */
+".",
+
+/* 1 */
+"..",
+
+NULL
+
+
+#line 92 "dk4fne08.ctr"
+};
+
+
+#if DK4_ON_WINDOWS
+static
+int
+dk4fne_c8_fill_directory(dk4_dir_c8_t *ptr, const char *fn, dk4_er_t *erp)
+{
+ WIN32_FIND_DATAA ffdata;
+ char *nn;
+ HANDLE ffres;
+ int back = 0;
+
+ ffres = FindFirstFileA(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != ffres) {
+ back = 1;
+ do {
+ if (0 != dk4str8_cmp(dk4fne_c8_kw[0], ffdata.cFileName)) {
+ if (0 != dk4str8_cmp(dk4fne_c8_kw[1], ffdata.cFileName)) {
+ nn = dk4str8_dup(ffdata.cFileName, erp);
+ if (NULL != nn) {
+ if (0 != (FILE_ATTRIBUTE_DIRECTORY & (ffdata.dwFileAttributes))) {
+ if (0 == dk4sto_add(ptr->s_dir, (void *)nn, erp)) {
+ back = 0;
+ dk4mem_free(nn);
+ }
+ } else {
+ if (0 == dk4sto_add(ptr->s_file, (void *)nn, erp)) {
+ back = 0;
+ dk4mem_free(nn);
+ }
+ }
+ } else {
+ back = 0;
+ }
+ }
+ }
+ } while (FindNextFileA(ffres, &ffdata));
+ FindClose(ffres);
+ } else {
+ /* ERROR: FindFirstFile failed */
+ dk4error_set_ldetails(
+ erp, DK4_E_FINDFIRSTFILE_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ return back;
+}
+#endif
+
+
+
+dk4_dir_c8_t *
+dk4fne_open_c8(const char *fn, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ dk4_dir_c8_t *back = NULL;
+ char *p1 = NULL;
+ int ok = 0;
+ if (NULL != fn) {
+
+ back = dk4mem_new(dk4_dir_c8_t, 1, erp);
+ if (NULL != back) {
+ back->path = NULL;
+ back->s_dir = NULL;
+ back->i_dir = NULL;
+ back->s_file = NULL;
+ back->i_file = NULL;
+ back->path = dk4str8_dup(fn, erp);
+ if (NULL != back->path) {
+ p1 = dk4str8_rchr(back->path, '\\');
+ if (NULL != p1) {
+ *p1 = '\0';
+ } else {
+ dk4mem_free(back->path);
+ back->path = NULL;
+ }
+ back->s_dir = dk4sto_open(erp);
+ if (NULL != back->s_dir) {
+ dk4sto_set_comp(back->s_dir, dk4dir_c8_compare, 0);
+ back->i_dir = dk4sto_it_open(back->s_dir, erp);
+ if (NULL != back->i_dir) {
+ back->s_file = dk4sto_open(erp);
+ if (NULL != back->s_file) {
+ dk4sto_set_comp(back->s_file, dk4dir_c8_compare, 0);
+ back->i_file = dk4sto_it_open(back->s_file, erp);
+ if (NULL != back->i_file) {
+ ok = dk4fne_c8_fill_directory(back, fn, erp);
+ }
+ }
+ }
+ }
+ }
+ if (0 == ok) {
+ dk4dir_c8_close(back);
+ back = NULL;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+}
+
diff --git a/support/dktools/dk4fne08.ctr b/support/dktools/dk4fne08.ctr
new file mode 100644
index 0000000000..5f2fb00bf7
--- /dev/null
+++ b/support/dktools/dk4fne08.ctr
@@ -0,0 +1,199 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ File name expander.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4DIR08_H_INCLUDED
+#include "dk4dir08.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Expand a file name.
+ @param pattern File name pattern, may optionally include
+ a directory part.
+ @param erp Error report, may be NULL.
+ @return Directory structure on success, NULL on error.
+ On success the path component in the returned directory structure
+ is NULL if the pattern did not contain a directory part.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if path is NULL,
+ - DK4_E_NOT_SUPPORTED<br>
+ if no function to traverse directories was found during build
+ process or the function is called on a non-Windows system,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if a memory allocation failed,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in a size calculation,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if one of the involved directory or file names is too long for an
+ internal buffer,
+ - DK4_E_OPENDIR_FAILED<br>
+ with errno value in iDetails1 if the attempt to open the directory
+ failed,
+ - DK4_E_FINDFIRSTFILE_FAILED<br>
+ with GetLastError() value in lDetails1 if the FindFirstFile()
+ function failed on Windows,
+ - DK4_E_SYSTEM<br>
+ if the stat() or lstat() function failed for one of the directory
+ items.
+*/
+dk4_dir_c8_t *
+dk4fne_open_c8(const char *pattern, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4fne08.h"
+#include "dk4str8.h"
+#include "dk4mem.h"
+
+
+
+$!trace-include
+
+
+
+/** Constant texts used by the module.
+*/
+static const char * const dk4fne_c8_kw[] = {
+$!string-table
+.
+..
+$!end
+};
+
+
+#if DK4_ON_WINDOWS
+static
+int
+dk4fne_c8_fill_directory(dk4_dir_c8_t *ptr, const char *fn, dk4_er_t *erp)
+{
+ WIN32_FIND_DATAA ffdata;
+ char *nn;
+ HANDLE ffres;
+ int back = 0;
+
+ ffres = FindFirstFileA(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != ffres) {
+ back = 1;
+ do {
+ if (0 != dk4str8_cmp(dk4fne_c8_kw[0], ffdata.cFileName)) {
+ if (0 != dk4str8_cmp(dk4fne_c8_kw[1], ffdata.cFileName)) {
+ nn = dk4str8_dup(ffdata.cFileName, erp);
+ if (NULL != nn) {
+ if (0 != (FILE_ATTRIBUTE_DIRECTORY & (ffdata.dwFileAttributes))) {
+ if (0 == dk4sto_add(ptr->s_dir, (void *)nn, erp)) {
+ back = 0;
+ dk4mem_free(nn);
+ }
+ } else {
+ if (0 == dk4sto_add(ptr->s_file, (void *)nn, erp)) {
+ back = 0;
+ dk4mem_free(nn);
+ }
+ }
+ } else {
+ back = 0;
+ }
+ }
+ }
+ } while (FindNextFileA(ffres, &ffdata));
+ FindClose(ffres);
+ } else {
+ /* ERROR: FindFirstFile failed */
+ dk4error_set_ldetails(
+ erp, DK4_E_FINDFIRSTFILE_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ return back;
+}
+#endif
+
+
+
+dk4_dir_c8_t *
+dk4fne_open_c8(const char *fn, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ dk4_dir_c8_t *back = NULL;
+ char *p1 = NULL;
+ int ok = 0;
+ if (NULL != fn) {
+
+ back = dk4mem_new(dk4_dir_c8_t, 1, erp);
+ if (NULL != back) {
+ back->path = NULL;
+ back->s_dir = NULL;
+ back->i_dir = NULL;
+ back->s_file = NULL;
+ back->i_file = NULL;
+ back->path = dk4str8_dup(fn, erp);
+ if (NULL != back->path) {
+ p1 = dk4str8_rchr(back->path, '\\');
+ if (NULL != p1) {
+ *p1 = '\0';
+ } else {
+ dk4mem_free(back->path);
+ back->path = NULL;
+ }
+ back->s_dir = dk4sto_open(erp);
+ if (NULL != back->s_dir) {
+ dk4sto_set_comp(back->s_dir, dk4dir_c8_compare, 0);
+ back->i_dir = dk4sto_it_open(back->s_dir, erp);
+ if (NULL != back->i_dir) {
+ back->s_file = dk4sto_open(erp);
+ if (NULL != back->s_file) {
+ dk4sto_set_comp(back->s_file, dk4dir_c8_compare, 0);
+ back->i_file = dk4sto_it_open(back->s_file, erp);
+ if (NULL != back->i_file) {
+ ok = dk4fne_c8_fill_directory(back, fn, erp);
+ }
+ }
+ }
+ }
+ }
+ if (0 == ok) {
+ dk4dir_c8_close(back);
+ back = NULL;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+}
+
diff --git a/support/dktools/dk4fne08.h b/support/dktools/dk4fne08.h
new file mode 100644
index 0000000000..62363587c8
--- /dev/null
+++ b/support/dktools/dk4fne08.h
@@ -0,0 +1,96 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fne08.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4FNE08_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4FNE08_H_INCLUDED 1
+
+
+#line 10 "dk4fne08.ctr"
+
+/** @file
+ File name expander.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4DIR08_H_INCLUDED
+#include "dk4dir08.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Expand a file name.
+ @param pattern File name pattern, may optionally include
+ a directory part.
+ @param erp Error report, may be NULL.
+ @return Directory structure on success, NULL on error.
+ On success the path component in the returned directory structure
+ is NULL if the pattern did not contain a directory part.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if path is NULL,
+ - DK4_E_NOT_SUPPORTED<br>
+ if no function to traverse directories was found during build
+ process or the function is called on a non-Windows system,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if a memory allocation failed,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in a size calculation,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if one of the involved directory or file names is too long for an
+ internal buffer,
+ - DK4_E_OPENDIR_FAILED<br>
+ with errno value in iDetails1 if the attempt to open the directory
+ failed,
+ - DK4_E_FINDFIRSTFILE_FAILED<br>
+ with GetLastError() value in lDetails1 if the FindFirstFile()
+ function failed on Windows,
+ - DK4_E_SYSTEM<br>
+ if the stat() or lstat() function failed for one of the directory
+ items.
+*/
+dk4_dir_c8_t *
+dk4fne_open_c8(const char *pattern, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4fnewc.c b/support/dktools/dk4fnewc.c
new file mode 100644
index 0000000000..9c64846d3b
--- /dev/null
+++ b/support/dktools/dk4fnewc.c
@@ -0,0 +1,227 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fnewc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4fnewc.c The dk4fnewc module.
+*/
+
+
+#line 64 "dk4fnewc.ctr"
+
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4fnewc.h"
+#include "dk4strw.h"
+#include "dk4mem.h"
+
+#if DK4_HAVE_WCHAR_H
+#ifndef WCHAR_H_INCLUDED
+#include <wchar.h>
+#define WCHAR_H_INCLUDED 1
+#endif
+#endif
+
+
+
+#line 87 "dk4fnewc.ctr"
+
+
+
+#if DK4_ON_WINDOWS
+
+
+
+/** Constant texts used by the module.
+*/
+static const wchar_t * const dk4fne_wc_kw[] = {
+/* 0 */
+L".",
+
+/* 1 */
+L"..",
+
+NULL
+
+
+#line 101 "dk4fnewc.ctr"
+};
+
+
+
+static
+int
+dk4fne_wc_fill_directory(dk4_dir_wc_t *ptr, const wchar_t *fn, dk4_er_t *erp)
+{
+ WIN32_FIND_DATAW ffdata;
+ wchar_t *nn;
+ HANDLE ffres;
+ int back = 0;
+
+
+#line 114 "dk4fnewc.ctr"
+ ffres = FindFirstFileW(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != ffres) {
+ back = 1;
+ do {
+ if (0 != dk4strw_cmp(dk4fne_wc_kw[0], ffdata.cFileName)) {
+ if (0 != dk4strw_cmp(dk4fne_wc_kw[1], ffdata.cFileName)) {
+ nn = dk4strw_dup(ffdata.cFileName, erp);
+ if (NULL != nn) {
+ if (0 != (FILE_ATTRIBUTE_DIRECTORY & (ffdata.dwFileAttributes))) {
+ if (0 == dk4sto_add(ptr->s_dir, (void *)nn, erp)) {
+ back = 0;
+ dk4mem_free(nn);
+ }
+ } else {
+ if (0 == dk4sto_add(ptr->s_file, (void *)nn, erp)) {
+ back = 0;
+ dk4mem_free(nn);
+ }
+ }
+ } else {
+ back = 0;
+ }
+ }
+ }
+ } while (FindNextFileW(ffres, &ffdata));
+ FindClose(ffres);
+ } else {
+
+#line 141 "dk4fnewc.ctr"
+ /* ERROR: FindFirstFile failed */
+ dk4error_set_ldetails(
+ erp, DK4_E_FINDFIRSTFILE_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+
+#line 147 "dk4fnewc.ctr"
+ return back;
+}
+#endif
+
+
+
+dk4_dir_wc_t *
+dk4fne_open_wc(const wchar_t *fn, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ dk4_dir_wc_t *back = NULL;
+ wchar_t *p1 = NULL;
+ int ok = 0;
+
+
+#line 161 "dk4fnewc.ctr"
+ if (NULL != fn) {
+ back = dk4mem_new(dk4_dir_wc_t, 1, erp);
+ if (NULL != back) {
+
+#line 164 "dk4fnewc.ctr"
+ back->path = NULL;
+ back->s_dir = NULL;
+ back->i_dir = NULL;
+ back->s_file = NULL;
+ back->i_file = NULL;
+ back->path = dk4strw_dup(fn, erp);
+ if (NULL != back->path) {
+
+#line 171 "dk4fnewc.ctr"
+ p1 = dk4strw_rchr(back->path, L'\\');
+ if (NULL != p1) {
+ *p1 = L'\0';
+ } else {
+ dk4mem_free(back->path);
+ back->path = NULL;
+ }
+ back->s_dir = dk4sto_open(erp);
+ if (NULL != back->s_dir) {
+ dk4sto_set_comp(back->s_dir, dk4dir_wc_compare, 0);
+ back->i_dir = dk4sto_it_open(back->s_dir, erp);
+ if (NULL != back->i_dir) {
+ back->s_file = dk4sto_open(erp);
+ if (NULL != back->s_file) {
+ dk4sto_set_comp(back->s_file, dk4dir_wc_compare, 0);
+ back->i_file = dk4sto_it_open(back->s_file, erp);
+ if (NULL != back->i_file) {
+
+#line 188 "dk4fnewc.ctr"
+ ok = dk4fne_wc_fill_directory(back, fn, erp);
+ } else {
+
+#line 190 "dk4fnewc.ctr"
+ }
+ } else {
+
+#line 192 "dk4fnewc.ctr"
+ }
+ } else {
+
+#line 194 "dk4fnewc.ctr"
+ }
+ } else {
+
+#line 196 "dk4fnewc.ctr"
+ }
+ } else {
+
+#line 198 "dk4fnewc.ctr"
+ }
+ if (0 == ok) {
+ dk4dir_wc_close(back);
+ back = NULL;
+ }
+ } else {
+
+#line 204 "dk4fnewc.ctr"
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 208 "dk4fnewc.ctr"
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+}
+
diff --git a/support/dktools/dk4fnewc.ctr b/support/dktools/dk4fnewc.ctr
new file mode 100644
index 0000000000..d1559586b3
--- /dev/null
+++ b/support/dktools/dk4fnewc.ctr
@@ -0,0 +1,214 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ File name expander.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4DIRWC_H_INCLUDED
+#include "dk4dirwc.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Expand a file name.
+ @param pattern File name pattern, may optionally include
+ a directory part.
+ @param erp Error report, may be NULL.
+ @return Directory structure on success, NULL on error.
+ On success the path component in the returned directory structure
+ is NULL if the pattern did not contain a directory part.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if path is NULL,
+ - DK4_E_NOT_SUPPORTED<br>
+ if no function to traverse directories was found during build
+ process or the function is called on a non-Windows system,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if a memory allocation failed,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in a size calculation,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if one of the involved directory or file names is too long for an
+ internal buffer,
+ - DK4_E_OPENDIR_FAILED<br>
+ with errno value in iDetails1 if the attempt to open the directory
+ failed,
+ - DK4_E_FINDFIRSTFILE_FAILED<br>
+ with GetLastError() value in lDetails1 if the FindFirstFile()
+ function failed on Windows,
+ - DK4_E_SYSTEM<br>
+ if the stat() or lstat() function failed for one of the directory
+ items.
+*/
+dk4_dir_wc_t *
+dk4fne_open_wc(const wchar_t *pattern, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4fnewc.h"
+#include "dk4strw.h"
+#include "dk4mem.h"
+
+#if DK4_HAVE_WCHAR_H
+#ifndef WCHAR_H_INCLUDED
+#include <wchar.h>
+#define WCHAR_H_INCLUDED 1
+#endif
+#endif
+
+$!trace-include
+
+
+
+#if DK4_ON_WINDOWS
+
+
+
+/** Constant texts used by the module.
+*/
+static const wchar_t * const dk4fne_wc_kw[] = {
+$!string-table prefix=L
+.
+..
+$!end
+};
+
+
+
+static
+int
+dk4fne_wc_fill_directory(dk4_dir_wc_t *ptr, const wchar_t *fn, dk4_er_t *erp)
+{
+ WIN32_FIND_DATAW ffdata;
+ wchar_t *nn;
+ HANDLE ffres;
+ int back = 0;
+ $? "+ dk4fne_wc_fill_directory"
+ ffres = FindFirstFileW(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != ffres) {
+ back = 1;
+ do {
+ if (0 != dk4strw_cmp(dk4fne_wc_kw[0], ffdata.cFileName)) {
+ if (0 != dk4strw_cmp(dk4fne_wc_kw[1], ffdata.cFileName)) {
+ nn = dk4strw_dup(ffdata.cFileName, erp);
+ if (NULL != nn) {
+ if (0 != (FILE_ATTRIBUTE_DIRECTORY & (ffdata.dwFileAttributes))) {
+ if (0 == dk4sto_add(ptr->s_dir, (void *)nn, erp)) {
+ back = 0;
+ dk4mem_free(nn);
+ }
+ } else {
+ if (0 == dk4sto_add(ptr->s_file, (void *)nn, erp)) {
+ back = 0;
+ dk4mem_free(nn);
+ }
+ }
+ } else {
+ back = 0;
+ }
+ }
+ }
+ } while (FindNextFileW(ffres, &ffdata));
+ FindClose(ffres);
+ } else { $? "! FindFirstFileW"
+ /* ERROR: FindFirstFile failed */
+ dk4error_set_ldetails(
+ erp, DK4_E_FINDFIRSTFILE_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ } $? "- dk4fne_wc_fill_directory"
+ return back;
+}
+#endif
+
+
+
+dk4_dir_wc_t *
+dk4fne_open_wc(const wchar_t *fn, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ dk4_dir_wc_t *back = NULL;
+ wchar_t *p1 = NULL;
+ int ok = 0;
+ $? "+ dk4fne_open_wc"
+ if (NULL != fn) {
+ back = dk4mem_new(dk4_dir_wc_t, 1, erp);
+ if (NULL != back) { $? ". memory"
+ back->path = NULL;
+ back->s_dir = NULL;
+ back->i_dir = NULL;
+ back->s_file = NULL;
+ back->i_file = NULL;
+ back->path = dk4strw_dup(fn, erp);
+ if (NULL != back->path) { $? ". strdup"
+ p1 = dk4strw_rchr(back->path, L'\\');
+ if (NULL != p1) {
+ *p1 = L'\0';
+ } else {
+ dk4mem_free(back->path);
+ back->path = NULL;
+ }
+ back->s_dir = dk4sto_open(erp);
+ if (NULL != back->s_dir) {
+ dk4sto_set_comp(back->s_dir, dk4dir_wc_compare, 0);
+ back->i_dir = dk4sto_it_open(back->s_dir, erp);
+ if (NULL != back->i_dir) {
+ back->s_file = dk4sto_open(erp);
+ if (NULL != back->s_file) {
+ dk4sto_set_comp(back->s_file, dk4dir_wc_compare, 0);
+ back->i_file = dk4sto_it_open(back->s_file, erp);
+ if (NULL != back->i_file) { $? ". storages/iterators ok"
+ ok = dk4fne_wc_fill_directory(back, fn, erp);
+ } else { $? "! i_file"
+ }
+ } else { $? "! s_file"
+ }
+ } else { $? "! i_dir"
+ }
+ } else { $? "! s_dir"
+ }
+ } else { $? "! strdup"
+ }
+ if (0 == ok) {
+ dk4dir_wc_close(back);
+ back = NULL;
+ }
+ } else { $? "! memory"
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4fne_open_wc PTR=%d", TR_IPTR(back)
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+}
+
diff --git a/support/dktools/dk4fnewc.h b/support/dktools/dk4fnewc.h
new file mode 100644
index 0000000000..ff4f4ce0f0
--- /dev/null
+++ b/support/dktools/dk4fnewc.h
@@ -0,0 +1,96 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fnewc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4FNEWC_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4FNEWC_H_INCLUDED 1
+
+
+#line 10 "dk4fnewc.ctr"
+
+/** @file
+ File name expander.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4DIRWC_H_INCLUDED
+#include "dk4dirwc.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Expand a file name.
+ @param pattern File name pattern, may optionally include
+ a directory part.
+ @param erp Error report, may be NULL.
+ @return Directory structure on success, NULL on error.
+ On success the path component in the returned directory structure
+ is NULL if the pattern did not contain a directory part.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if path is NULL,
+ - DK4_E_NOT_SUPPORTED<br>
+ if no function to traverse directories was found during build
+ process or the function is called on a non-Windows system,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if a memory allocation failed,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in a size calculation,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if one of the involved directory or file names is too long for an
+ internal buffer,
+ - DK4_E_OPENDIR_FAILED<br>
+ with errno value in iDetails1 if the attempt to open the directory
+ failed,
+ - DK4_E_FINDFIRSTFILE_FAILED<br>
+ with GetLastError() value in lDetails1 if the FindFirstFile()
+ function failed on Windows,
+ - DK4_E_SYSTEM<br>
+ if the stat() or lstat() function failed for one of the directory
+ items.
+*/
+dk4_dir_wc_t *
+dk4fne_open_wc(const wchar_t *pattern, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4font.c b/support/dktools/dk4font.c
new file mode 100644
index 0000000000..55c760616b
--- /dev/null
+++ b/support/dktools/dk4font.c
@@ -0,0 +1,493 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4font.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4font.c The dk4font module.
+*/
+
+
+#line 130 "dk4font.ctr"
+
+
+#include "dk4font.h"
+
+
+#include <stdio.h>
+
+#if DK4_HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+
+
+#line 146 "dk4font.ctr"
+
+
+
+static const char * const dk4font_ps_names[] = {
+/* 0 */
+"Times-Roman",
+
+/* 1 */
+"Times-Italic",
+
+/* 2 */
+"Times-Bold",
+
+/* 3 */
+"Times-BoldItalic",
+
+/* 4 */
+"AvantGarde-Book",
+
+/* 5 */
+"AvantGarde-BookOblique",
+
+/* 6 */
+"AvantGarde-Demi",
+
+/* 7 */
+"AvantGarde-DemiOblique",
+
+/* 8 */
+"Bookman-Light",
+
+/* 9 */
+"Bookman-LightItalic",
+
+/* 10 */
+"Bookman-Demi",
+
+/* 11 */
+"Bookman-DemiItalic",
+
+/* 12 */
+"Courier",
+
+/* 13 */
+"Courier-Oblique",
+
+/* 14 */
+"Courier-Bold",
+
+/* 15 */
+"Courier-BoldOblique",
+
+/* 16 */
+"Helvetica",
+
+/* 17 */
+"Helvetica-Oblique",
+
+/* 18 */
+"Helvetica-Bold",
+
+/* 19 */
+"Helvetica-BoldOblique",
+
+/* 20 */
+"Helvetica-Narrow",
+
+/* 21 */
+"Helvetica-Narrow-Oblique",
+
+/* 22 */
+"Helvetica-Narrow-Bold",
+
+/* 23 */
+"Helvetica-Narrow-BoldOblique",
+
+/* 24 */
+"NewCenturySchlbk-Roman",
+
+/* 25 */
+"NewCenturySchlbk-Italic",
+
+/* 26 */
+"NewCenturySchlbk-Bold",
+
+/* 27 */
+"NewCenturySchlbk-BoldItalic",
+
+/* 28 */
+"Palatino-Roman",
+
+/* 29 */
+"Palatino-Italic",
+
+/* 30 */
+"Palatino-Bold",
+
+/* 31 */
+"Palatino-BoldItalic",
+
+/* 32 */
+"Symbol",
+
+/* 33 */
+"ZapfChancery-MediumItalic",
+
+/* 34 */
+"ZapfDingbats",
+
+NULL
+
+
+#line 187 "dk4font.ctr"
+};
+
+
+
+static const char * const dk4font_tex_family_names[] = {
+/* 0 */
+"ptm",
+
+/* 1 */
+"ptm",
+
+/* 2 */
+"ptm",
+
+/* 3 */
+"ptm",
+
+/* 4 */
+"pag",
+
+/* 5 */
+"pag",
+
+/* 6 */
+"pag",
+
+/* 7 */
+"pag",
+
+/* 8 */
+"pbk",
+
+/* 9 */
+"pbk",
+
+/* 10 */
+"pbk",
+
+/* 11 */
+"pbk",
+
+/* 12 */
+"pcr",
+
+/* 13 */
+"pcr",
+
+/* 14 */
+"pcr",
+
+/* 15 */
+"pcr",
+
+/* 16 */
+"phv",
+
+/* 17 */
+"phv",
+
+/* 18 */
+"phv",
+
+/* 19 */
+"phv",
+
+/* 20 */
+"phv",
+
+/* 21 */
+"phv",
+
+/* 22 */
+"phv",
+
+/* 23 */
+"phv",
+
+/* 24 */
+"pnc",
+
+/* 25 */
+"pnc",
+
+/* 26 */
+"pnc",
+
+/* 27 */
+"pnc",
+
+/* 28 */
+"ppl",
+
+/* 29 */
+"ppl",
+
+/* 30 */
+"ppl",
+
+/* 31 */
+"ppl",
+
+/* 32 */
+"psy",
+
+/* 33 */
+"pzc",
+
+/* 34 */
+"pzd",
+
+NULL
+
+
+#line 229 "dk4font.ctr"
+};
+
+
+
+static const char * const dk4font_tex_names[] = {
+/* 0 */
+"ptmr",
+
+/* 1 */
+"ptmri",
+
+/* 2 */
+"ptmb",
+
+/* 3 */
+"ptmbi",
+
+/* 4 */
+"pagk",
+
+/* 5 */
+"pagko",
+
+/* 6 */
+"pagd",
+
+/* 7 */
+"pagdo",
+
+/* 8 */
+"pbkl",
+
+/* 9 */
+"pbkli",
+
+/* 10 */
+"pbkd",
+
+/* 11 */
+"pbkdi",
+
+/* 12 */
+"pcrr",
+
+/* 13 */
+"pcrro",
+
+/* 14 */
+"pcrb",
+
+/* 15 */
+"pcrbo",
+
+/* 16 */
+"phvr",
+
+/* 17 */
+"phvro",
+
+/* 18 */
+"phvb",
+
+/* 19 */
+"phvbo",
+
+/* 20 */
+"phvrrn",
+
+/* 21 */
+"phvron",
+
+/* 22 */
+"phvbrn",
+
+/* 23 */
+"phvbon",
+
+/* 24 */
+"pncr",
+
+/* 25 */
+"pncri",
+
+/* 26 */
+"pncb",
+
+/* 27 */
+"pncbi",
+
+/* 28 */
+"pplr",
+
+/* 29 */
+"pplri",
+
+/* 30 */
+"pplb",
+
+/* 31 */
+"pplbi",
+
+/* 32 */
+"psyr",
+
+/* 33 */
+"pzcmi",
+
+/* 34 */
+"pzdr",
+
+NULL
+
+
+#line 271 "dk4font.ctr"
+};
+
+
+
+const int dk4font_features[] = {
+0,
+DK4_FONT_FEATURE_ITALIC,
+DK4_FONT_FEATURE_BOLD,
+(DK4_FONT_FEATURE_ITALIC | DK4_FONT_FEATURE_BOLD),
+DK4_FONT_FEATURE_SANS_SERIF,
+(DK4_FONT_FEATURE_SANS_SERIF | DK4_FONT_FEATURE_OBLIQUE),
+(DK4_FONT_FEATURE_SANS_SERIF | DK4_FONT_FEATURE_BOLD),
+(DK4_FONT_FEATURE_SANS_SERIF | DK4_FONT_FEATURE_BOLD | DK4_FONT_FEATURE_OBLIQUE),
+0,
+DK4_FONT_FEATURE_ITALIC,
+DK4_FONT_FEATURE_BOLD,
+(DK4_FONT_FEATURE_BOLD | DK4_FONT_FEATURE_ITALIC),
+DK4_FONT_FEATURE_TTY,
+(DK4_FONT_FEATURE_TTY | DK4_FONT_FEATURE_OBLIQUE),
+(DK4_FONT_FEATURE_TTY | DK4_FONT_FEATURE_BOLD),
+(DK4_FONT_FEATURE_TTY | DK4_FONT_FEATURE_BOLD | DK4_FONT_FEATURE_OBLIQUE),
+DK4_FONT_FEATURE_SANS_SERIF,
+(DK4_FONT_FEATURE_SANS_SERIF | DK4_FONT_FEATURE_OBLIQUE),
+(DK4_FONT_FEATURE_SANS_SERIF | DK4_FONT_FEATURE_BOLD),
+(DK4_FONT_FEATURE_SANS_SERIF | DK4_FONT_FEATURE_BOLD | DK4_FONT_FEATURE_OBLIQUE),
+(DK4_FONT_FEATURE_SANS_SERIF | DK4_FONT_FEATURE_NARROW),
+(
+ DK4_FONT_FEATURE_SANS_SERIF | DK4_FONT_FEATURE_NARROW
+ | DK4_FONT_FEATURE_OBLIQUE
+),
+(DK4_FONT_FEATURE_SANS_SERIF | DK4_FONT_FEATURE_NARROW | DK4_FONT_FEATURE_BOLD),
+(
+ DK4_FONT_FEATURE_SANS_SERIF | DK4_FONT_FEATURE_NARROW
+ | DK4_FONT_FEATURE_BOLD | DK4_FONT_FEATURE_OBLIQUE
+),
+0,
+DK4_FONT_FEATURE_ITALIC,
+DK4_FONT_FEATURE_BOLD,
+(DK4_FONT_FEATURE_BOLD | DK4_FONT_FEATURE_ITALIC),
+0,
+DK4_FONT_FEATURE_ITALIC,
+DK4_FONT_FEATURE_BOLD,
+(DK4_FONT_FEATURE_BOLD | DK4_FONT_FEATURE_ITALIC),
+DK4_FONT_FEATURE_SYMBOL,
+DK4_FONT_FEATURE_ITALIC,
+DK4_FONT_FEATURE_SYMBOL
+};
+
+
+const char *
+dk4font_get_ps_name(dk4_font_number_t fno)
+{
+ if (DK4_FONT_PS_MAX >= fno) {
+ return (dk4font_ps_names[fno]);
+ }
+ return NULL;
+}
+
+
+
+const char *
+dk4font_get_latex_family_name(dk4_font_number_t fno)
+{
+ if (DK4_FONT_PS_MAX >= fno) {
+ return (dk4font_tex_family_names[fno]);
+ }
+ return NULL;
+}
+
+
+
+const char *
+dk4font_get_latex_font_name(dk4_font_number_t fno)
+{
+ if (DK4_FONT_PS_MAX >= fno) {
+ return (dk4font_tex_names[fno]);
+ }
+ return NULL;
+}
+
+
+
+int
+dk4font_get_features(dk4_font_number_t fno)
+{
+ if (DK4_FONT_PS_MAX >= fno) {
+ return (dk4font_features[fno]);
+ }
+ return 0;
+}
+
+
+
+/* vim: set ai sw=4 ts=4 : */
diff --git a/support/dktools/dk4font.ctr b/support/dktools/dk4font.ctr
new file mode 100644
index 0000000000..ca7a60d7a8
--- /dev/null
+++ b/support/dktools/dk4font.ctr
@@ -0,0 +1,364 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+
+%% header
+
+
+/** Font numbers the module can handle.
+*/
+typedef enum {
+ DK4_FONT_TIMES_ROMAN = 0,
+ DK4_FONT_TIMES_ITALIC ,
+ DK4_FONT_TIMES_BOLD ,
+ DK4_FONT_TIMES_BOLD_ITALIC ,
+ DK4_FONT_AVANTGARDE_BOOK ,
+ DK4_FONT_AVANTGARDE_BOOK_OBLIQUE ,
+ DK4_FONT_AVANTGARDE_DEMI ,
+ DK4_FONT_AVANTGARDE_DEMI_OBLIQUE ,
+ DK4_FONT_BOOKMAN_LIGHT ,
+ DK4_FONT_BOOKMAN_LIGHT_ITALIC ,
+ DK4_FONT_BOOKMAN_DEMI ,
+ DK4_FONT_BOOKMAN_DEMI_ITALIC ,
+ DK4_FONT_COURIER ,
+ DK4_FONT_COURIER_OBLIQUE ,
+ DK4_FONT_COURIER_BOLD ,
+ DK4_FONT_COURIER_BOLD_OBLIQUE ,
+ DK4_FONT_HELVETICA ,
+ DK4_FONT_HELVETICA_OBLIQUE ,
+ DK4_FONT_HELVETICA_BOLD ,
+ DK4_FONT_HELVETICA_BOLD_OBLIQUE ,
+ DK4_FONT_HELVETICA_NARROW ,
+ DK4_FONT_HELVETICA_NARROW_OBLIQUE ,
+ DK4_FONT_HELVETICA_NARROW_BOLD ,
+ DK4_FONT_HELVETICA_NARROW_BOLD_OBLIQUE ,
+ DK4_FONT_NEW_CENTURY_SCHOOLBOOK_ROMAN ,
+ DK4_FONT_NEW_CENTURY_SCHOOLBOOK_ITALIC ,
+ DK4_FONT_NEW_CENTURY_SCHOOLBOOK_BOLD ,
+ DK4_FONT_NEW_CENTURY_SCHOOLBOOK_BOLD_ITALIC ,
+ DK4_FONT_PALATINO_ROMAN ,
+ DK4_FONT_PALATINO_ITALIC ,
+ DK4_FONT_PALATINO_BOLD ,
+ DK4_FONT_PALATINO_BOLD_ITALIC ,
+ DK4_FONT_SYMBOL ,
+ DK4_FONT_ZAPF_CHANCERY ,
+ DK4_FONT_ZAPF_DINGBATS ,
+
+ /* We might want to add further LaTeX fonts here but no PS font name is
+ available for fonts after this point.
+ Remember to add corresponding entries to the dk4font_tex_family_names,
+ dk4font_tex_names and dk4font_features arrays in the module section.
+ Order of fonts here must correspond to the order of information
+ in these arrays!
+ */
+
+ /* Finally we set some constants for comparisons.
+ */
+
+ DK4_FONT_PS_MAX = DK4_FONT_ZAPF_DINGBATS, /**< Maximum for PS. */
+ DK4_FONT_MAX = DK4_FONT_ZAPF_DINGBATS /**< Maximum value. */
+} dk4_font_number_t;
+
+
+/** Font features.
+*/
+enum {
+ DK4_FONT_FEATURE_SANS_SERIF = 1, /**< Sans-serif font. */
+ DK4_FONT_FEATURE_TTY = 2, /**< Typewriter style font. */
+ DK4_FONT_FEATURE_SYMBOL = 3, /**< Symbol font. */
+ DK4_FONT_FEATURE_BOLD = 4, /**< Bold font. */
+ DK4_FONT_FEATURE_ITALIC = 8, /**< Italic font. */
+ DK4_FONT_FEATURE_OBLIQUE = 16, /**< Oblique font. */
+ DK4_FONT_FEATURE_NARROW = 32, /**< Narrow or condensed font. */
+
+ DK4_FONT_FEATURE_FT_MASK = 3, /**< Mask to retrieve sf or tty. */
+ DK4_FONT_FEATURE_ITOB_MASK = 24, /**< Mask for italic or oblique. */
+};
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** Retrieve font name (without leading slash) for a PS font.
+ @param fno Font number.
+ @return Valid pointer on success (fno refers to a PS font), NULL otherwise.
+*/
+
+const char *
+dk4font_get_ps_name(dk4_font_number_t fno);
+
+
+/** Retrieve LaTeX font family name for a font.
+ @param fno Font number.
+ @return Valid pointer on success, NULL on error.
+*/
+
+const char *
+dk4font_get_latex_family_name(dk4_font_number_t fno);
+
+
+/** Retrieve LaTeX font name for a font.
+ @param fno Font number.
+ @return Valid pointer on success, NULL on error.
+*/
+
+const char *
+dk4font_get_latex_font_name(dk4_font_number_t fno);
+
+
+/** Retrieve font feature set for a font.
+ @param fno Font number.
+ @return Font feature set.
+*/
+
+int
+dk4font_get_features(dk4_font_number_t fno);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+/* vim: set ai sw=4 ts=4 : */
+%% module
+
+
+#include "dk4font.h"
+
+
+#include <stdio.h>
+
+#if DK4_HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+$!trace-include
+
+
+
+static const char * const dk4font_ps_names[] = {
+$!string-table
+Times-Roman
+Times-Italic
+Times-Bold
+Times-BoldItalic
+AvantGarde-Book
+AvantGarde-BookOblique
+AvantGarde-Demi
+AvantGarde-DemiOblique
+Bookman-Light
+Bookman-LightItalic
+Bookman-Demi
+Bookman-DemiItalic
+Courier
+Courier-Oblique
+Courier-Bold
+Courier-BoldOblique
+Helvetica
+Helvetica-Oblique
+Helvetica-Bold
+Helvetica-BoldOblique
+Helvetica-Narrow
+Helvetica-Narrow-Oblique
+Helvetica-Narrow-Bold
+Helvetica-Narrow-BoldOblique
+NewCenturySchlbk-Roman
+NewCenturySchlbk-Italic
+NewCenturySchlbk-Bold
+NewCenturySchlbk-BoldItalic
+Palatino-Roman
+Palatino-Italic
+Palatino-Bold
+Palatino-BoldItalic
+Symbol
+ZapfChancery-MediumItalic
+ZapfDingbats
+$!end
+};
+
+
+
+static const char * const dk4font_tex_family_names[] = {
+$!string-table
+ptm
+ptm
+ptm
+ptm
+pag
+pag
+pag
+pag
+pbk
+pbk
+pbk
+pbk
+pcr
+pcr
+pcr
+pcr
+phv
+phv
+phv
+phv
+phv
+phv
+phv
+phv
+pnc
+pnc
+pnc
+pnc
+ppl
+ppl
+ppl
+ppl
+psy
+pzc
+pzd
+$!end
+};
+
+
+
+static const char * const dk4font_tex_names[] = {
+$!string-table
+ptmr
+ptmri
+ptmb
+ptmbi
+pagk
+pagko
+pagd
+pagdo
+pbkl
+pbkli
+pbkd
+pbkdi
+pcrr
+pcrro
+pcrb
+pcrbo
+phvr
+phvro
+phvb
+phvbo
+phvrrn
+phvron
+phvbrn
+phvbon
+pncr
+pncri
+pncb
+pncbi
+pplr
+pplri
+pplb
+pplbi
+psyr
+pzcmi
+pzdr
+$!end
+};
+
+
+
+const int dk4font_features[] = {
+0,
+DK4_FONT_FEATURE_ITALIC,
+DK4_FONT_FEATURE_BOLD,
+(DK4_FONT_FEATURE_ITALIC | DK4_FONT_FEATURE_BOLD),
+DK4_FONT_FEATURE_SANS_SERIF,
+(DK4_FONT_FEATURE_SANS_SERIF | DK4_FONT_FEATURE_OBLIQUE),
+(DK4_FONT_FEATURE_SANS_SERIF | DK4_FONT_FEATURE_BOLD),
+(DK4_FONT_FEATURE_SANS_SERIF | DK4_FONT_FEATURE_BOLD | DK4_FONT_FEATURE_OBLIQUE),
+0,
+DK4_FONT_FEATURE_ITALIC,
+DK4_FONT_FEATURE_BOLD,
+(DK4_FONT_FEATURE_BOLD | DK4_FONT_FEATURE_ITALIC),
+DK4_FONT_FEATURE_TTY,
+(DK4_FONT_FEATURE_TTY | DK4_FONT_FEATURE_OBLIQUE),
+(DK4_FONT_FEATURE_TTY | DK4_FONT_FEATURE_BOLD),
+(DK4_FONT_FEATURE_TTY | DK4_FONT_FEATURE_BOLD | DK4_FONT_FEATURE_OBLIQUE),
+DK4_FONT_FEATURE_SANS_SERIF,
+(DK4_FONT_FEATURE_SANS_SERIF | DK4_FONT_FEATURE_OBLIQUE),
+(DK4_FONT_FEATURE_SANS_SERIF | DK4_FONT_FEATURE_BOLD),
+(DK4_FONT_FEATURE_SANS_SERIF | DK4_FONT_FEATURE_BOLD | DK4_FONT_FEATURE_OBLIQUE),
+(DK4_FONT_FEATURE_SANS_SERIF | DK4_FONT_FEATURE_NARROW),
+(
+ DK4_FONT_FEATURE_SANS_SERIF | DK4_FONT_FEATURE_NARROW
+ | DK4_FONT_FEATURE_OBLIQUE
+),
+(DK4_FONT_FEATURE_SANS_SERIF | DK4_FONT_FEATURE_NARROW | DK4_FONT_FEATURE_BOLD),
+(
+ DK4_FONT_FEATURE_SANS_SERIF | DK4_FONT_FEATURE_NARROW
+ | DK4_FONT_FEATURE_BOLD | DK4_FONT_FEATURE_OBLIQUE
+),
+0,
+DK4_FONT_FEATURE_ITALIC,
+DK4_FONT_FEATURE_BOLD,
+(DK4_FONT_FEATURE_BOLD | DK4_FONT_FEATURE_ITALIC),
+0,
+DK4_FONT_FEATURE_ITALIC,
+DK4_FONT_FEATURE_BOLD,
+(DK4_FONT_FEATURE_BOLD | DK4_FONT_FEATURE_ITALIC),
+DK4_FONT_FEATURE_SYMBOL,
+DK4_FONT_FEATURE_ITALIC,
+DK4_FONT_FEATURE_SYMBOL
+};
+
+
+const char *
+dk4font_get_ps_name(dk4_font_number_t fno)
+{
+ if (DK4_FONT_PS_MAX >= fno) {
+ return (dk4font_ps_names[fno]);
+ }
+ return NULL;
+}
+
+
+
+const char *
+dk4font_get_latex_family_name(dk4_font_number_t fno)
+{
+ if (DK4_FONT_PS_MAX >= fno) {
+ return (dk4font_tex_family_names[fno]);
+ }
+ return NULL;
+}
+
+
+
+const char *
+dk4font_get_latex_font_name(dk4_font_number_t fno)
+{
+ if (DK4_FONT_PS_MAX >= fno) {
+ return (dk4font_tex_names[fno]);
+ }
+ return NULL;
+}
+
+
+
+int
+dk4font_get_features(dk4_font_number_t fno)
+{
+ if (DK4_FONT_PS_MAX >= fno) {
+ return (dk4font_features[fno]);
+ }
+ return 0;
+}
+
+
+
+/* vim: set ai sw=4 ts=4 : */
diff --git a/support/dktools/dk4font.h b/support/dktools/dk4font.h
new file mode 100644
index 0000000000..a7556bc655
--- /dev/null
+++ b/support/dktools/dk4font.h
@@ -0,0 +1,166 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4font.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4font.h Header file for the dk4font module.
+*/
+
+#ifndef DK4FONT_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4FONT_H_INCLUDED 1
+
+
+#line 9 "dk4font.ctr"
+
+
+/** Font numbers the module can handle.
+*/
+typedef enum {
+ DK4_FONT_TIMES_ROMAN = 0,
+ DK4_FONT_TIMES_ITALIC ,
+ DK4_FONT_TIMES_BOLD ,
+ DK4_FONT_TIMES_BOLD_ITALIC ,
+ DK4_FONT_AVANTGARDE_BOOK ,
+ DK4_FONT_AVANTGARDE_BOOK_OBLIQUE ,
+ DK4_FONT_AVANTGARDE_DEMI ,
+ DK4_FONT_AVANTGARDE_DEMI_OBLIQUE ,
+ DK4_FONT_BOOKMAN_LIGHT ,
+ DK4_FONT_BOOKMAN_LIGHT_ITALIC ,
+ DK4_FONT_BOOKMAN_DEMI ,
+ DK4_FONT_BOOKMAN_DEMI_ITALIC ,
+ DK4_FONT_COURIER ,
+ DK4_FONT_COURIER_OBLIQUE ,
+ DK4_FONT_COURIER_BOLD ,
+ DK4_FONT_COURIER_BOLD_OBLIQUE ,
+ DK4_FONT_HELVETICA ,
+ DK4_FONT_HELVETICA_OBLIQUE ,
+ DK4_FONT_HELVETICA_BOLD ,
+ DK4_FONT_HELVETICA_BOLD_OBLIQUE ,
+ DK4_FONT_HELVETICA_NARROW ,
+ DK4_FONT_HELVETICA_NARROW_OBLIQUE ,
+ DK4_FONT_HELVETICA_NARROW_BOLD ,
+ DK4_FONT_HELVETICA_NARROW_BOLD_OBLIQUE ,
+ DK4_FONT_NEW_CENTURY_SCHOOLBOOK_ROMAN ,
+ DK4_FONT_NEW_CENTURY_SCHOOLBOOK_ITALIC ,
+ DK4_FONT_NEW_CENTURY_SCHOOLBOOK_BOLD ,
+ DK4_FONT_NEW_CENTURY_SCHOOLBOOK_BOLD_ITALIC ,
+ DK4_FONT_PALATINO_ROMAN ,
+ DK4_FONT_PALATINO_ITALIC ,
+ DK4_FONT_PALATINO_BOLD ,
+ DK4_FONT_PALATINO_BOLD_ITALIC ,
+ DK4_FONT_SYMBOL ,
+ DK4_FONT_ZAPF_CHANCERY ,
+ DK4_FONT_ZAPF_DINGBATS ,
+
+ /* We might want to add further LaTeX fonts here but no PS font name is
+ available for fonts after this point.
+ Remember to add corresponding entries to the dk4font_tex_family_names,
+ dk4font_tex_names and dk4font_features arrays in the module section.
+ Order of fonts here must correspond to the order of information
+ in these arrays!
+ */
+
+ /* Finally we set some constants for comparisons.
+ */
+
+ DK4_FONT_PS_MAX = DK4_FONT_ZAPF_DINGBATS, /**< Maximum for PS. */
+ DK4_FONT_MAX = DK4_FONT_ZAPF_DINGBATS /**< Maximum value. */
+} dk4_font_number_t;
+
+
+/** Font features.
+*/
+enum {
+ DK4_FONT_FEATURE_SANS_SERIF = 1, /**< Sans-serif font. */
+ DK4_FONT_FEATURE_TTY = 2, /**< Typewriter style font. */
+ DK4_FONT_FEATURE_SYMBOL = 3, /**< Symbol font. */
+ DK4_FONT_FEATURE_BOLD = 4, /**< Bold font. */
+ DK4_FONT_FEATURE_ITALIC = 8, /**< Italic font. */
+ DK4_FONT_FEATURE_OBLIQUE = 16, /**< Oblique font. */
+ DK4_FONT_FEATURE_NARROW = 32, /**< Narrow or condensed font. */
+
+ DK4_FONT_FEATURE_FT_MASK = 3, /**< Mask to retrieve sf or tty. */
+ DK4_FONT_FEATURE_ITOB_MASK = 24, /**< Mask for italic or oblique. */
+};
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** Retrieve font name (without leading slash) for a PS font.
+ @param fno Font number.
+ @return Valid pointer on success (fno refers to a PS font), NULL otherwise.
+*/
+
+const char *
+dk4font_get_ps_name(dk4_font_number_t fno);
+
+
+/** Retrieve LaTeX font family name for a font.
+ @param fno Font number.
+ @return Valid pointer on success, NULL on error.
+*/
+
+const char *
+dk4font_get_latex_family_name(dk4_font_number_t fno);
+
+
+/** Retrieve LaTeX font name for a font.
+ @param fno Font number.
+ @return Valid pointer on success, NULL on error.
+*/
+
+const char *
+dk4font_get_latex_font_name(dk4_font_number_t fno);
+
+
+/** Retrieve font feature set for a font.
+ @param fno Font number.
+ @return Font feature set.
+*/
+
+int
+dk4font_get_features(dk4_font_number_t fno);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+/* vim: set ai sw=4 ts=4 : */
+
+#endif
diff --git a/support/dktools/dk4fopc8.c b/support/dktools/dk4fopc8.c
new file mode 100644
index 0000000000..f4d90d7b47
--- /dev/null
+++ b/support/dktools/dk4fopc8.c
@@ -0,0 +1,350 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fopc8.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4fopc8.c The dk4fopc8 module.
+*/
+
+
+#line 111 "dk4fopc8.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4fopc8.h"
+
+#ifndef DK4STAT8_H_INCLUDED
+#include "dk4stat8.h"
+#endif
+
+#ifndef DK4STAT_H_INCLUDED
+#include "dk4stat.h"
+#endif
+
+#ifndef DK4MPL_H_INCLUDED
+#include "dk4mpl.h"
+#endif
+
+#ifndef DK4STR8_H_INCLUDED
+#include "dk4str8.h"
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+
+
+
+
+#line 163 "dk4fopc8.ctr"
+
+
+
+#if !DK4_ON_WINDOWS
+#if DK4_HAVE_BACKSLASH_AS_SEP
+/** Path component separator. */
+static const unsigned char sep = '\\';
+#else
+/** Path component separator. */
+static const unsigned char sep = '/';
+#endif
+/** Check whether one of the components in the path is a
+ symbolic link.
+ @param name Path name to check.
+ @return 1 if there is no symlink in the path, 0 otherwise.
+*/
+static
+int
+dk4fopen_check_no_symlink_in_path(const char *name)
+{
+ char buf[DK4_MAX_PATH];
+ dk4_stat_t lstb;
+ char *p1;
+ int back = 0;
+ if (sizeof(buf) > dk4str8_len(name)) {
+ back = 1;
+ dk4str8_cpy_s(buf, sizeof(buf), name, NULL);
+ p1 = dk4str8_chr(buf, sep);
+ while ((NULL != p1) && (1 == back)) {
+ *p1 = '\0';
+ if (0 < dk4str8_len(buf)) {
+ if (0 != dk4stat_l_c8(&lstb, buf, NULL)) {
+ if (0 != dk4stat_is_symlink(&lstb, NULL)) {
+ back = 0;
+ }
+ }
+ }
+ *(p1++) = sep;
+ p1 = dk4str8_chr(p1, sep);
+ }
+ }
+ return back;
+}
+#endif
+
+
+
+int
+dk4fopen_check_c8(const char *name, int ww, int tests, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ WIN32_FIND_DATAA ffdata;
+ HANDLE ha;
+ DWORD dwattr;
+ int back = 1;
+
+
+#line 219 "dk4fopc8.ctr"
+ /* Check name
+ */
+ if (NULL == name) {
+
+#line 222 "dk4fopc8.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ back = 0;
+ goto finished;
+ }
+ /* Retrieve attributes.
+ */
+ dwattr = GetFileAttributesA(name);
+ if (INVALID_FILE_ATTRIBUTES == dwattr) {
+ ha = FindFirstFileA(name, &ffdata);
+ if (INVALID_HANDLE_VALUE != ha) {
+ dwattr = ffdata.dwFileAttributes;
+ FindClose(ha);
+ }
+ }
+ if (INVALID_FILE_ATTRIBUTES == dwattr) {
+
+#line 237 "dk4fopc8.ctr"
+ goto finished;
+ }
+ /* Check directory
+ */
+ if ((DWORD)0UL != (FILE_ATTRIBUTE_DIRECTORY & dwattr)) {
+
+#line 242 "dk4fopc8.ctr"
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ goto finished;
+ }
+ /* Check device
+ */
+ if ((DWORD)0UL != (FILE_ATTRIBUTE_DEVICE & dwattr)) {
+
+#line 249 "dk4fopc8.ctr"
+ back = 0;
+ dk4error_set_idetails(erp, DK4_E_SEC_CHECK, DK4_FOPEN_SC_IS_REGULAR);
+ }
+ finished:
+
+
+#line 254 "dk4fopc8.ctr"
+ return back;
+#else
+ dk4_stat_t stb;
+ dk4_stat_t lstb;
+ int back = 1;
+
+
+#line 260 "dk4fopc8.ctr"
+
+ /* Check name argument.
+ */
+ if (NULL == name) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ back = 0;
+ goto finished;
+ }
+ /* Check existing path.
+ */
+ if (0 == dk4stat_c8(&stb, name, NULL)) {
+
+
+#line 272 "dk4fopc8.ctr"
+ goto finished;
+ }
+ /* Check directory.
+ */
+ if (0 != dk4stat_is_directory(&stb, NULL)) {
+
+
+#line 278 "dk4fopc8.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ back = 0;
+ goto finished;
+ }
+ /* Write regular files only.
+ */
+ if ((0 != ww) && (0 != (tests & DK4_FOPEN_SC_IS_REGULAR))) {
+ if (0 == dk4stat_is_regular(&stb, NULL)) {
+
+
+#line 287 "dk4fopc8.ctr"
+ dk4error_set_idetails(erp, DK4_E_SEC_CHECK, DK4_FOPEN_SC_IS_REGULAR);
+ back = 0;
+ goto finished;
+ }
+ }
+ /* Do not write if any path element is a symbolic link.
+ */
+ if ((0 != ww) && (0 != (tests & DK4_FOPEN_SC_WR_SYMLINK_IN_PATH))) {
+ if (0 == dk4fopen_check_no_symlink_in_path(name)) {
+
+
+#line 297 "dk4fopc8.ctr"
+ dk4error_set_idetails(erp, DK4_E_SEC_CHECK, DK4_FOPEN_SC_WR_SYMLINK_IN_PATH);
+ back = 0;
+ goto finished;
+ }
+ }
+ /* Obtain symbolic link information.
+ */
+ if (0 == dk4stat_l_c8(&lstb, name, NULL)) {
+
+
+#line 306 "dk4fopc8.ctr"
+ goto finished;
+ }
+ /* Do not write to file via link.
+ */
+ if ((0 != ww) && (0 != (tests & DK4_FOPEN_SC_WR_PATH_IS_SYMLINK))) {
+ if (0 != dk4stat_is_symlink(&lstb, NULL)) {
+
+
+#line 313 "dk4fopc8.ctr"
+ dk4error_set_idetails(erp, DK4_E_SEC_CHECK, DK4_FOPEN_SC_WR_PATH_IS_SYMLINK);
+ back = 0;
+ goto finished;
+ }
+ }
+ /* Do not write file via link if file owner differs from link owner.
+ */
+#if DK4_HAVE_FILE_UIDGID
+ if ((0 != ww) && (0 != (tests & DK4_FOPEN_SC_WR_SYMLINK_OWNER))) {
+ if (lstb.st_uid != stb.st_uid) {
+
+
+#line 324 "dk4fopc8.ctr"
+ dk4error_set_idetails(erp, DK4_E_SEC_CHECK, DK4_FOPEN_SC_WR_SYMLINK_OWNER);
+ back = 0;
+ goto finished;
+ }
+ }
+#endif
+ finished:
+
+
+#line 332 "dk4fopc8.ctr"
+ return back;
+#endif
+}
+
+
+
+FILE *
+dk4fopen_c8(const char *name, const char *mode, int tests, dk4_er_t *erp)
+{
+ FILE *back = NULL; /* Result */
+ const char *cptr; /* Traverse mode */
+ int ww = 0; /* Flag: Want to write */
+#if DK4_HAVE_FOPEN_S
+ errno_t errn;
+#endif
+
+ if ((NULL != name) && (NULL != mode)) {
+ cptr = mode;
+ while (*cptr) {
+ switch (*cptr) { case 'w': case 'a': case '+': { ww = 1; } break; }
+ cptr++;
+ }
+ if (0 != dk4fopen_check_c8(name, ww, tests, erp)) {
+#if DK4_HAVE_FOPEN_S
+ errn = fopen_s(&back, name, mode);
+ if (0 != errn) {
+ back = NULL;
+ dk4error_set_idetails(
+ erp, ((ww) ? DK4_E_OPEN_WRITE_FAILED : DK4_E_OPEN_READ_FAILED), errn
+ );
+ }
+#else
+#if DK4_HAVE_FOPEN64
+ errno = 0;
+ back = fopen64(name, mode);
+ if (NULL == back) {
+ dk4error_set_idetails(
+ erp, ((ww) ? DK4_E_OPEN_WRITE_FAILED : DK4_E_OPEN_READ_FAILED), errno
+ );
+ }
+#else
+ errno = 0;
+ back = fopen(name, mode);
+ if (NULL == back) {
+ dk4error_set_idetails(
+ erp, ((ww) ? DK4_E_OPEN_WRITE_FAILED : DK4_E_OPEN_READ_FAILED), errno
+ );
+ }
+#endif
+#endif
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4fopc8.ctr b/support/dktools/dk4fopc8.ctr
new file mode 100644
index 0000000000..c75a63e5bb
--- /dev/null
+++ b/support/dktools/dk4fopc8.ctr
@@ -0,0 +1,388 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Open file, apply additional security
+ checks before attempting to open the file.
+
+ Attempts to open a directory as a file are rejected.
+
+ Further optional checks can be applied to avoid:
+ - writing to non-regular files,
+ - writing to files with any symbolic link component in the path,
+ - writing to files via symbolic link,
+ - writing to files via symbolic link if link owner differs
+ from file owner.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4NUMCO_H_INCLUDED
+#include "dk4numco.h"
+#endif
+
+#ifndef DK4FOPT_H_INCLUDED
+#include "dk4fopt.h"
+#endif
+
+#ifndef STDIO_H_INCLUDED
+#include <stdio.h>
+#define STDIO_H_INCLUDED 1
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open a file after doing security checks.
+ CRT on Windows: Required.
+ @param name File name to open.
+ @param mode Opening mode.
+ @param tests Set of tests.
+ @param erp Error report, may be NULL.
+ @return Pointer to open file on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if name is NULL,
+ - DK4_E_SYNTAX<br>
+ if name does not refer to a regular file,
+ - DK4_E_SEC_CHECK<br>
+ with failed echek id (DK4_FOPEN_SC_WR_PATH_IS_SYMLINK or
+ DK4_FOPEN_SC_WR_SYMLINK_OWNER) in iDetails1 if access is denied by
+ additional security checks,
+ - DK4_E_OPEN_WRITE_FAILED<br>
+ or DK4_E_OPEN_READ_FAILED with errno value in iDetails1 if fopen()
+ failed.
+
+*/
+FILE *
+dk4fopen_c8(const char *name, const char *mode, int tests, dk4_er_t *erp);
+
+/** Check whether we can allow to open the file.
+ The file must be a regular file.
+ Only POSIX: For root we deny opening for writing via symlink.
+ For all users we deny opening for writing via symlink
+ if the link owner is not the real file owner.
+
+ CRT on Windows: Required.
+ @param name File name to check.
+ @param ww Flag: Write access wanted.
+ @param tests Set of tests.
+ @param erp Error report, may be NULL.
+ @return 1 if opening the file is allowed, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if name is NULL,
+ - DK4_E_SYNTAX<br>
+ if name is not a regular file,
+ - DK4_E_SEC_CHECK<br>
+ if access to a symlink target is denied symlink owner and target
+ owner differ.
+
+*/
+int
+dk4fopen_check_c8(const char *name, int ww, int tests, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4fopc8.h"
+
+#ifndef DK4STAT8_H_INCLUDED
+#include "dk4stat8.h"
+#endif
+
+#ifndef DK4STAT_H_INCLUDED
+#include "dk4stat.h"
+#endif
+
+#ifndef DK4MPL_H_INCLUDED
+#include "dk4mpl.h"
+#endif
+
+#ifndef DK4STR8_H_INCLUDED
+#include "dk4str8.h"
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+
+
+$!trace-include
+
+
+
+#if !DK4_ON_WINDOWS
+#if DK4_HAVE_BACKSLASH_AS_SEP
+/** Path component separator. */
+static const unsigned char sep = '\\';
+#else
+/** Path component separator. */
+static const unsigned char sep = '/';
+#endif
+/** Check whether one of the components in the path is a
+ symbolic link.
+ @param name Path name to check.
+ @return 1 if there is no symlink in the path, 0 otherwise.
+*/
+static
+int
+dk4fopen_check_no_symlink_in_path(const char *name)
+{
+ char buf[DK4_MAX_PATH];
+ dk4_stat_t lstb;
+ char *p1;
+ int back = 0;
+ if (sizeof(buf) > dk4str8_len(name)) {
+ back = 1;
+ dk4str8_cpy_s(buf, sizeof(buf), name, NULL);
+ p1 = dk4str8_chr(buf, sep);
+ while ((NULL != p1) && (1 == back)) {
+ *p1 = '\0';
+ if (0 < dk4str8_len(buf)) {
+ if (0 != dk4stat_l_c8(&lstb, buf, NULL)) {
+ if (0 != dk4stat_is_symlink(&lstb, NULL)) {
+ back = 0;
+ }
+ }
+ }
+ *(p1++) = sep;
+ p1 = dk4str8_chr(p1, sep);
+ }
+ }
+ return back;
+}
+#endif
+
+
+
+int
+dk4fopen_check_c8(const char *name, int ww, int tests, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ WIN32_FIND_DATAA ffdata;
+ HANDLE ha;
+ DWORD dwattr;
+ int back = 1;
+ $? "+ dk4fopen_check_c8 \"%!8s\" wr=%d tests=%d", TR_8STR(name), ww, tests
+ /* Check name
+ */
+ if (NULL == name) { $? "! illegal name"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ back = 0;
+ goto finished;
+ }
+ /* Retrieve attributes.
+ */
+ dwattr = GetFileAttributesA(name);
+ if (INVALID_FILE_ATTRIBUTES == dwattr) {
+ ha = FindFirstFileA(name, &ffdata);
+ if (INVALID_HANDLE_VALUE != ha) {
+ dwattr = ffdata.dwFileAttributes;
+ FindClose(ha);
+ }
+ }
+ if (INVALID_FILE_ATTRIBUTES == dwattr) { $? "! path does not exist"
+ goto finished;
+ }
+ /* Check directory
+ */
+ if ((DWORD)0UL != (FILE_ATTRIBUTE_DIRECTORY & dwattr)) { $? "! dir"
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ goto finished;
+ }
+ /* Check device
+ */
+ if ((DWORD)0UL != (FILE_ATTRIBUTE_DEVICE & dwattr)) { $? "! device"
+ back = 0;
+ dk4error_set_idetails(erp, DK4_E_SEC_CHECK, DK4_FOPEN_SC_IS_REGULAR);
+ }
+ finished:
+ $? "- dk4fopen_check_c8 %d", back
+ return back;
+#else
+ dk4_stat_t stb;
+ dk4_stat_t lstb;
+ int back = 1;
+ $? "+ dk4fopen_check_c8 \"%!8s\" wr=%d tests=%d", TR_8STR(name), ww, tests
+
+ /* Check name argument.
+ */
+ if (NULL == name) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ back = 0;
+ goto finished;
+ }
+ /* Check existing path.
+ */
+ if (0 == dk4stat_c8(&stb, name, NULL)) {
+ $? ". path does not yet exist"
+ goto finished;
+ }
+ /* Check directory.
+ */
+ if (0 != dk4stat_is_directory(&stb, NULL)) {
+ $? "! path is a directory"
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ back = 0;
+ goto finished;
+ }
+ /* Write regular files only.
+ */
+ if ((0 != ww) && (0 != (tests & DK4_FOPEN_SC_IS_REGULAR))) {
+ if (0 == dk4stat_is_regular(&stb, NULL)) {
+ $? "! not a regular file"
+ dk4error_set_idetails(erp, DK4_E_SEC_CHECK, DK4_FOPEN_SC_IS_REGULAR);
+ back = 0;
+ goto finished;
+ }
+ }
+ /* Do not write if any path element is a symbolic link.
+ */
+ if ((0 != ww) && (0 != (tests & DK4_FOPEN_SC_WR_SYMLINK_IN_PATH))) {
+ if (0 == dk4fopen_check_no_symlink_in_path(name)) {
+ $? "! symblic link in path"
+ dk4error_set_idetails(erp, DK4_E_SEC_CHECK, DK4_FOPEN_SC_WR_SYMLINK_IN_PATH);
+ back = 0;
+ goto finished;
+ }
+ }
+ /* Obtain symbolic link information.
+ */
+ if (0 == dk4stat_l_c8(&lstb, name, NULL)) {
+ $? ". path does not yet exist or lstat() failed"
+ goto finished;
+ }
+ /* Do not write to file via link.
+ */
+ if ((0 != ww) && (0 != (tests & DK4_FOPEN_SC_WR_PATH_IS_SYMLINK))) {
+ if (0 != dk4stat_is_symlink(&lstb, NULL)) {
+ $? "! path target is symbolic link"
+ dk4error_set_idetails(erp, DK4_E_SEC_CHECK, DK4_FOPEN_SC_WR_PATH_IS_SYMLINK);
+ back = 0;
+ goto finished;
+ }
+ }
+ /* Do not write file via link if file owner differs from link owner.
+ */
+#if DK4_HAVE_FILE_UIDGID
+ if ((0 != ww) && (0 != (tests & DK4_FOPEN_SC_WR_SYMLINK_OWNER))) {
+ if (lstb.st_uid != stb.st_uid) {
+ $? "! link owner is not file owner"
+ dk4error_set_idetails(erp, DK4_E_SEC_CHECK, DK4_FOPEN_SC_WR_SYMLINK_OWNER);
+ back = 0;
+ goto finished;
+ }
+ }
+#endif
+ finished:
+ $? "- dk4fopen_check_c8 %d", back
+ return back;
+#endif
+}
+
+
+
+FILE *
+dk4fopen_c8(const char *name, const char *mode, int tests, dk4_er_t *erp)
+{
+ FILE *back = NULL; /* Result */
+ const char *cptr; /* Traverse mode */
+ int ww = 0; /* Flag: Want to write */
+#if DK4_HAVE_FOPEN_S
+ errno_t errn;
+#endif
+
+ if ((NULL != name) && (NULL != mode)) {
+ cptr = mode;
+ while (*cptr) {
+ switch (*cptr) { case 'w': case 'a': case '+': { ww = 1; } break; }
+ cptr++;
+ }
+ if (0 != dk4fopen_check_c8(name, ww, tests, erp)) {
+#if DK4_HAVE_FOPEN_S
+ errn = fopen_s(&back, name, mode);
+ if (0 != errn) {
+ back = NULL;
+ dk4error_set_idetails(
+ erp, ((ww) ? DK4_E_OPEN_WRITE_FAILED : DK4_E_OPEN_READ_FAILED), errn
+ );
+ }
+#else
+#if DK4_HAVE_FOPEN64
+ errno = 0;
+ back = fopen64(name, mode);
+ if (NULL == back) {
+ dk4error_set_idetails(
+ erp, ((ww) ? DK4_E_OPEN_WRITE_FAILED : DK4_E_OPEN_READ_FAILED), errno
+ );
+ }
+#else
+ errno = 0;
+ back = fopen(name, mode);
+ if (NULL == back) {
+ dk4error_set_idetails(
+ erp, ((ww) ? DK4_E_OPEN_WRITE_FAILED : DK4_E_OPEN_READ_FAILED), errno
+ );
+ }
+#endif
+#endif
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4fopc8.h b/support/dktools/dk4fopc8.h
new file mode 100644
index 0000000000..dbe333dcca
--- /dev/null
+++ b/support/dktools/dk4fopc8.h
@@ -0,0 +1,143 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fopc8.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4FOPC8_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4FOPC8_H_INCLUDED 1
+
+
+#line 10 "dk4fopc8.ctr"
+
+/** @file
+ Open file, apply additional security
+ checks before attempting to open the file.
+
+ Attempts to open a directory as a file are rejected.
+
+ Further optional checks can be applied to avoid:
+ - writing to non-regular files,
+ - writing to files with any symbolic link component in the path,
+ - writing to files via symbolic link,
+ - writing to files via symbolic link if link owner differs
+ from file owner.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4NUMCO_H_INCLUDED
+#include "dk4numco.h"
+#endif
+
+#ifndef DK4FOPT_H_INCLUDED
+#include "dk4fopt.h"
+#endif
+
+#ifndef STDIO_H_INCLUDED
+#include <stdio.h>
+#define STDIO_H_INCLUDED 1
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open a file after doing security checks.
+ CRT on Windows: Required.
+ @param name File name to open.
+ @param mode Opening mode.
+ @param tests Set of tests.
+ @param erp Error report, may be NULL.
+ @return Pointer to open file on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if name is NULL,
+ - DK4_E_SYNTAX<br>
+ if name does not refer to a regular file,
+ - DK4_E_SEC_CHECK<br>
+ with failed echek id (DK4_FOPEN_SC_WR_PATH_IS_SYMLINK or
+ DK4_FOPEN_SC_WR_SYMLINK_OWNER) in iDetails1 if access is denied by
+ additional security checks,
+ - DK4_E_OPEN_WRITE_FAILED<br>
+ or DK4_E_OPEN_READ_FAILED with errno value in iDetails1 if fopen()
+ failed.
+
+*/
+FILE *
+dk4fopen_c8(const char *name, const char *mode, int tests, dk4_er_t *erp);
+
+/** Check whether we can allow to open the file.
+ The file must be a regular file.
+ Only POSIX: For root we deny opening for writing via symlink.
+ For all users we deny opening for writing via symlink
+ if the link owner is not the real file owner.
+
+ CRT on Windows: Required.
+ @param name File name to check.
+ @param ww Flag: Write access wanted.
+ @param tests Set of tests.
+ @param erp Error report, may be NULL.
+ @return 1 if opening the file is allowed, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if name is NULL,
+ - DK4_E_SYNTAX<br>
+ if name is not a regular file,
+ - DK4_E_SEC_CHECK<br>
+ if access to a symlink target is denied symlink owner and target
+ owner differ.
+
+*/
+int
+dk4fopen_check_c8(const char *name, int ww, int tests, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4fopd.c b/support/dktools/dk4fopd.c
new file mode 100644
index 0000000000..513a389b05
--- /dev/null
+++ b/support/dktools/dk4fopd.c
@@ -0,0 +1,64 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fopd.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4fopd.c The dk4fopd module.
+*/
+
+
+#line 83 "dk4fopd.ctr"
+
+#include "dk4conf.h"
+#include "dk4fopd.h"
+
+FILE *
+dk4fopen(const dkChar *name, const dkChar *mode, int tests, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4fopen_wc(name, mode, tests, erp));
+#else
+ return (dk4fopen_c8(name, mode, tests, erp));
+#endif
+}
+
+int
+dk4fopen_check(const dkChar *name, int ww, int tests, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4fopen_check_wc(name, ww, tests, erp));
+#else
+ return (dk4fopen_check_c8(name, ww, tests, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4fopd.ctr b/support/dktools/dk4fopd.ctr
new file mode 100644
index 0000000000..38493dcd93
--- /dev/null
+++ b/support/dktools/dk4fopd.ctr
@@ -0,0 +1,106 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Open file with additional security
+ checks, file name is specified in dkChar characters.
+*/
+
+#include "dk4conf.h"
+#include "dk4fopc8.h"
+
+#if DK4_CHAR_SIZE > 1
+#include "dk4fopwc.h"
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open a file after doing security checks.
+ CRT on Windows: Required.
+ @param name File name to open.
+ @param mode Opening mode.
+ @param tests Set of tests, see dk4fopc8.h.
+ @param erp Error report, may be NULL.
+ @return Pointer to open file on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if name is NULL,
+ - DK4_E_SYNTAX<br>
+ if name does not refer to a regular file,
+ - DK4_E_SEC_CHECK<br>
+ with failed check id in iDetails1 if access is denied by additional
+ security checks,
+ - DK4_E_OPEN_WRITE_FAILED<br>
+ or DK4_E_OPEN_READ_FAILED with errno value in iDetails1 if fopen()
+ failed.
+
+*/
+FILE *
+dk4fopen(const dkChar *name, const dkChar *mode, int tests, dk4_er_t *erp);
+
+/** Check whether we can allow to open the file.
+ The file must be a regular file.
+ Only POSIX: For root we deny opening for writing via symlink.
+ For all users we deny opening for writing via symlink
+ if the link owner is not the real file owner.
+
+ CRT on Windows: Required.
+ @param name File name to check.
+ @param ww Flag: Write access wanted.
+ @param tests Set of tests.
+ @param erp Error report, may be NULL.
+ @return 1 if opening the file is allowed, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if name is NULL,
+ - DK4_E_SYNTAX<br>
+ if name is not a regular file,
+ - DK4_E_SEC_CHECK<br>
+ if access to a symlink target is denied symlink owner and target
+ owner differ.
+
+*/
+int
+dk4fopen_check(const dkChar *name, int ww, int tests, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4fopd.h"
+
+FILE *
+dk4fopen(const dkChar *name, const dkChar *mode, int tests, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4fopen_wc(name, mode, tests, erp));
+#else
+ return (dk4fopen_c8(name, mode, tests, erp));
+#endif
+}
+
+int
+dk4fopen_check(const dkChar *name, int ww, int tests, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4fopen_check_wc(name, ww, tests, erp));
+#else
+ return (dk4fopen_check_c8(name, ww, tests, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4fopd.h b/support/dktools/dk4fopd.h
new file mode 100644
index 0000000000..ffdcd30e53
--- /dev/null
+++ b/support/dktools/dk4fopd.h
@@ -0,0 +1,115 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fopd.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4FOPD_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4FOPD_H_INCLUDED 1
+
+
+#line 10 "dk4fopd.ctr"
+
+/** @file
+ Open file with additional security
+ checks, file name is specified in dkChar characters.
+*/
+
+#include "dk4conf.h"
+#include "dk4fopc8.h"
+
+#if DK4_CHAR_SIZE > 1
+#include "dk4fopwc.h"
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open a file after doing security checks.
+ CRT on Windows: Required.
+ @param name File name to open.
+ @param mode Opening mode.
+ @param tests Set of tests, see dk4fopc8.h.
+ @param erp Error report, may be NULL.
+ @return Pointer to open file on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if name is NULL,
+ - DK4_E_SYNTAX<br>
+ if name does not refer to a regular file,
+ - DK4_E_SEC_CHECK<br>
+ with failed check id in iDetails1 if access is denied by additional
+ security checks,
+ - DK4_E_OPEN_WRITE_FAILED<br>
+ or DK4_E_OPEN_READ_FAILED with errno value in iDetails1 if fopen()
+ failed.
+
+*/
+FILE *
+dk4fopen(const dkChar *name, const dkChar *mode, int tests, dk4_er_t *erp);
+
+/** Check whether we can allow to open the file.
+ The file must be a regular file.
+ Only POSIX: For root we deny opening for writing via symlink.
+ For all users we deny opening for writing via symlink
+ if the link owner is not the real file owner.
+
+ CRT on Windows: Required.
+ @param name File name to check.
+ @param ww Flag: Write access wanted.
+ @param tests Set of tests.
+ @param erp Error report, may be NULL.
+ @return 1 if opening the file is allowed, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if name is NULL,
+ - DK4_E_SYNTAX<br>
+ if name is not a regular file,
+ - DK4_E_SEC_CHECK<br>
+ if access to a symlink target is denied symlink owner and target
+ owner differ.
+
+*/
+int
+dk4fopen_check(const dkChar *name, int ww, int tests, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4fopda.c b/support/dktools/dk4fopda.c
new file mode 100644
index 0000000000..925d79676e
--- /dev/null
+++ b/support/dktools/dk4fopda.c
@@ -0,0 +1,186 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fopda.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4fopda.c The dk4fopda module.
+*/
+
+
+#line 38 "dk4fopda.ctr"
+
+
+#if 0
+#define _POSIX_C_SOURCE 200112L
+#define _XOPEN_SOURCE 600
+#ifdef _GNU_SOURCE
+#undef _GNU_SOURCE
+#endif
+#endif
+
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_STRING_H
+#include <string.h>
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include "dk4const.h"
+#include "dk4fopd.h"
+#include "dk4fopda.h"
+#include "dk4error.h"
+
+
+
+FILE *
+dk4fopen_app(const dkChar *name, const dkChar *mode, int tests, dk4_app_t *app)
+{
+ dk4_er_t er;
+ FILE *back = NULL;
+ if ((NULL != name) && (NULL != mode)) {
+ dk4error_init(&er);
+ back = dk4fopen(name, mode, tests, &er);
+ if (NULL == back) {
+ switch (er.ec) {
+ case DK4_E_INVALID_ARGUMENTS: {
+ /* Bug, this function should not be called with name or mode NULL */
+ } break;
+ case DK4_E_SYNTAX: {
+ /* ERROR: File name does not refer to regular file */
+ dk4app_log_base3(app, DK4_LL_ERROR, 108, 109, name);
+ } break;
+ case DK4_E_SEC_CHECK: {
+ if (0 != (DK4_FOPEN_SC_IS_REGULAR & er.dt.iDetails1)) {
+ /* ERROR: Not a regular file */
+ dk4app_log_base3(app, DK4_LL_ERROR, 108, 109, name);
+ }
+ if (0 != (DK4_FOPEN_SC_WR_SYMLINK_IN_PATH & er.dt.iDetails1)) {
+ /* ERROR: Path contains symbolic link */
+ dk4app_log_base3(app, DK4_LL_ERROR, 108, 110, name);
+ }
+ if (0 != (DK4_FOPEN_SC_WR_PATH_IS_SYMLINK & er.dt.iDetails1)) {
+ /* ERROR: Path is a symbolic link */
+ dk4app_log_base3(app, DK4_LL_ERROR, 108, 111, name);
+ }
+ if (0 != (DK4_FOPEN_SC_WR_SYMLINK_OWNER & er.dt.iDetails1)) {
+ /* ERROR: Symbolic link owner is not file owner */
+ dk4app_log_base3(app, DK4_LL_ERROR, 108, 112, name);
+ }
+ } break;
+ case DK4_E_OPEN_WRITE_FAILED: case DK4_E_OPEN_READ_FAILED: {
+ switch (er.dt.iDetails1) {
+#ifdef EACCES
+ case EACCES : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 108, 55, name);
+ } break;
+#endif
+#ifdef EINTR
+ case EINTR : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 108, 113, name);
+ } break;
+#endif
+#ifdef EISDIR
+ case EISDIR : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 108, 52, name);
+ } break;
+#endif
+#ifdef ELOOP
+ case ELOOP : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 108, 61, name);
+ } break;
+#endif
+#ifdef EMFILE
+ case EMFILE : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 108, 114, name);
+ } break;
+#endif
+#ifdef ENAMETOOLONG
+ case ENAMETOOLONG : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 108, 65, name);
+ } break;
+#endif
+#ifdef ENFILE
+ case ENFILE : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 108, 115, name);
+ } break;
+#endif
+#ifdef ENOENT
+ case ENOENT : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 108, 51, name);
+ } break;
+#endif
+#ifdef ENOSPC
+ case ENOSPC : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 108, 60, name);
+ } break;
+#endif
+#ifdef ENOTDIR
+ case ENOTDIR : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 108, 150, name);
+ } break;
+#endif
+#ifdef ENXIO
+ case ENXIO : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 108, 116, name);
+ } break;
+#endif
+#ifdef EOVERFLOW
+ case EOVERFLOW : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 108, 117, name);
+ } break;
+#endif
+#ifdef EROFS
+ case EROFS : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 108, 56, name);
+ } break;
+#endif
+ default: {
+ dk4app_log_with_errno(
+ app, DK4_LL_ERROR, 108, 79, 80, 108, 77,
+ name, er.dt.iDetails1
+ );
+ } break;
+ }
+ } break;
+ }
+ }
+ }
+ return back;
+}
+
+
+
diff --git a/support/dktools/dk4fopda.ctr b/support/dktools/dk4fopda.ctr
new file mode 100644
index 0000000000..da1715eca6
--- /dev/null
+++ b/support/dktools/dk4fopda.ctr
@@ -0,0 +1,183 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+%% header
+
+/** @file dk4fopda.h File open.
+*/
+
+#include "dk4app.h"
+#include "dk4fopc8.h"
+
+#ifndef DK4FOPT_H_INCLUDED
+#include "dk4fopt.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open a file after doing security checks.
+ CRT on Windows: Required.
+ @param name File name.
+ @param mode Opening mode.
+ @param tests Set of tests, see dk4fopc8.h.
+ @param app Application structure for diagnostics, may be NULL.
+*/
+FILE *
+dk4fopen_app(const dkChar *name, const dkChar *mode, int tests, dk4_app_t *app);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+
+#if 0
+#define _POSIX_C_SOURCE 200112L
+#define _XOPEN_SOURCE 600
+#ifdef _GNU_SOURCE
+#undef _GNU_SOURCE
+#endif
+#endif
+
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_STRING_H
+#include <string.h>
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include "dk4const.h"
+#include "dk4fopd.h"
+#include "dk4fopda.h"
+#include "dk4error.h"
+
+
+
+FILE *
+dk4fopen_app(const dkChar *name, const dkChar *mode, int tests, dk4_app_t *app)
+{
+ dk4_er_t er;
+ FILE *back = NULL;
+ if ((NULL != name) && (NULL != mode)) {
+ dk4error_init(&er);
+ back = dk4fopen(name, mode, tests, &er);
+ if (NULL == back) {
+ switch (er.ec) {
+ case DK4_E_INVALID_ARGUMENTS: {
+ /* Bug, this function should not be called with name or mode NULL */
+ } break;
+ case DK4_E_SYNTAX: {
+ /* ERROR: File name does not refer to regular file */
+ dk4app_log_base3(app, DK4_LL_ERROR, 108, 109, name);
+ } break;
+ case DK4_E_SEC_CHECK: {
+ if (0 != (DK4_FOPEN_SC_IS_REGULAR & er.dt.iDetails1)) {
+ /* ERROR: Not a regular file */
+ dk4app_log_base3(app, DK4_LL_ERROR, 108, 109, name);
+ }
+ if (0 != (DK4_FOPEN_SC_WR_SYMLINK_IN_PATH & er.dt.iDetails1)) {
+ /* ERROR: Path contains symbolic link */
+ dk4app_log_base3(app, DK4_LL_ERROR, 108, 110, name);
+ }
+ if (0 != (DK4_FOPEN_SC_WR_PATH_IS_SYMLINK & er.dt.iDetails1)) {
+ /* ERROR: Path is a symbolic link */
+ dk4app_log_base3(app, DK4_LL_ERROR, 108, 111, name);
+ }
+ if (0 != (DK4_FOPEN_SC_WR_SYMLINK_OWNER & er.dt.iDetails1)) {
+ /* ERROR: Symbolic link owner is not file owner */
+ dk4app_log_base3(app, DK4_LL_ERROR, 108, 112, name);
+ }
+ } break;
+ case DK4_E_OPEN_WRITE_FAILED: case DK4_E_OPEN_READ_FAILED: {
+ switch (er.dt.iDetails1) {
+#ifdef EACCES
+ case EACCES : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 108, 55, name);
+ } break;
+#endif
+#ifdef EINTR
+ case EINTR : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 108, 113, name);
+ } break;
+#endif
+#ifdef EISDIR
+ case EISDIR : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 108, 52, name);
+ } break;
+#endif
+#ifdef ELOOP
+ case ELOOP : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 108, 61, name);
+ } break;
+#endif
+#ifdef EMFILE
+ case EMFILE : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 108, 114, name);
+ } break;
+#endif
+#ifdef ENAMETOOLONG
+ case ENAMETOOLONG : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 108, 65, name);
+ } break;
+#endif
+#ifdef ENFILE
+ case ENFILE : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 108, 115, name);
+ } break;
+#endif
+#ifdef ENOENT
+ case ENOENT : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 108, 51, name);
+ } break;
+#endif
+#ifdef ENOSPC
+ case ENOSPC : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 108, 60, name);
+ } break;
+#endif
+#ifdef ENOTDIR
+ case ENOTDIR : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 108, 150, name);
+ } break;
+#endif
+#ifdef ENXIO
+ case ENXIO : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 108, 116, name);
+ } break;
+#endif
+#ifdef EOVERFLOW
+ case EOVERFLOW : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 108, 117, name);
+ } break;
+#endif
+#ifdef EROFS
+ case EROFS : {
+ dk4app_log_base3(app, DK4_LL_ERROR, 108, 56, name);
+ } break;
+#endif
+ default: {
+ dk4app_log_with_errno(
+ app, DK4_LL_ERROR, 108, 79, 80, 108, 77,
+ name, er.dt.iDetails1
+ );
+ } break;
+ }
+ } break;
+ }
+ }
+ }
+ return back;
+}
+
+
+
diff --git a/support/dktools/dk4fopda.h b/support/dktools/dk4fopda.h
new file mode 100644
index 0000000000..f594c5d9f9
--- /dev/null
+++ b/support/dktools/dk4fopda.h
@@ -0,0 +1,72 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fopda.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4FOPDA_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4FOPDA_H_INCLUDED 1
+
+
+#line 8 "dk4fopda.ctr"
+
+/** @file dk4fopda.h File open.
+*/
+
+#include "dk4app.h"
+#include "dk4fopc8.h"
+
+#ifndef DK4FOPT_H_INCLUDED
+#include "dk4fopt.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open a file after doing security checks.
+ CRT on Windows: Required.
+ @param name File name.
+ @param mode Opening mode.
+ @param tests Set of tests, see dk4fopc8.h.
+ @param app Application structure for diagnostics, may be NULL.
+*/
+FILE *
+dk4fopen_app(const dkChar *name, const dkChar *mode, int tests, dk4_app_t *app);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4fopt.h b/support/dktools/dk4fopt.h
new file mode 100644
index 0000000000..14d9b58dc9
--- /dev/null
+++ b/support/dktools/dk4fopt.h
@@ -0,0 +1,71 @@
+
+#ifndef DK4FOPT_H_INCLUDED
+#define DK4FOPT_H_INCLUDED 1
+
+/** @file dk4fopt.h File open tests.
+*/
+
+#ifndef DK4NUMCO_H_INCLUDED
+#include "dk4numco.h"
+#endif
+
+/** Skip one ore more security checks when opening files.
+*/
+enum {
+ /** Deny write operation if the path does
+ not refer to a regular file.
+ */
+ DK4_FOPEN_SC_IS_REGULAR = 1,
+
+ /** Deny write operation if any path
+ component is a symbolic link.
+ Ignored on Windows and on systems
+ without symbolic links.
+ */
+ DK4_FOPEN_SC_WR_SYMLINK_IN_PATH = 2,
+
+ /** Deny write operation if the path
+ is a symbolic link (complete path).
+ Ignored on Windows and on systems
+ without symbolic links.
+ */
+ DK4_FOPEN_SC_WR_PATH_IS_SYMLINK = 4,
+
+ /** Deny write operation if the path is
+ a symbolic link and the link owner
+ is not the link destination owner.
+ Ignored on Windows, on systems without
+ symbolic links and on systems where
+ the st_uid member of the
+ stat structure has no meaning.
+ */
+ DK4_FOPEN_SC_WR_SYMLINK_OWNER = 8,
+
+
+ /** Apply security checks recommended
+ for non-privileged users.
+ */
+ DK4_FOPEN_SC_USER = (
+ DK4_FOPEN_SC_IS_REGULAR
+ | DK4_FOPEN_SC_WR_SYMLINK_OWNER
+ ),
+
+ /** Apply security checks recommended
+ for privileged users.
+ */
+ DK4_FOPEN_SC_PRIVILEGED = (
+ DK4_FOPEN_SC_IS_REGULAR
+ | DK4_FOPEN_SC_WR_SYMLINK_IN_PATH
+ | DK4_FOPEN_SC_WR_PATH_IS_SYMLINK
+ | DK4_FOPEN_SC_WR_SYMLINK_OWNER
+ ),
+
+ /** Apply all security checks
+ (recommended if process is running
+ with administrative privileges).
+ */
+ DK4_FOPEN_SC_ALL = INT_MAX
+};
+
+#endif
+
diff --git a/support/dktools/dk4fopwc.c b/support/dktools/dk4fopwc.c
new file mode 100644
index 0000000000..cc2e21d77a
--- /dev/null
+++ b/support/dktools/dk4fopwc.c
@@ -0,0 +1,309 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fopwc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4fopwc.c The dk4fopwc module.
+*/
+
+
+#line 113 "dk4fopwc.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4fopc8.h"
+#include "dk4fopwc.h"
+
+#ifndef DK4STAT8_H_INCLUDED
+#include "dk4statw.h"
+#endif
+
+#ifndef DK4STAT_H_INCLUDED
+#include "dk4stat.h"
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+
+
+
+
+#line 165 "dk4fopwc.ctr"
+
+
+
+FILE *
+dk4fopen_wc(const wchar_t *name, const wchar_t *mode, int tests, dk4_er_t *erp)
+{
+ FILE *back = NULL;
+ const wchar_t *cptr;
+ int ww = 0;
+#if DK4_HAVE__WFOPEN_S
+ errno_t errn;
+#endif
+
+ if ((NULL != name) && (NULL != mode)) {
+ cptr = mode;
+ while(*cptr) {
+ if (L'w' == *cptr) { ww = 1; }
+ if (L'a' == *cptr) { ww = 1; }
+ if (L'+' == *cptr) { ww = 1; }
+ cptr++;
+ }
+ if (0 != dk4fopen_check_wc(name, ww, tests, erp)) {
+#if DK4_HAVE__WFOPEN_S
+ errn = _wfopen_s(&back, name, mode);
+ if (0 != errn) {
+ back = NULL;
+ dk4error_set_idetails(
+ erp, ((ww) ? DK4_E_OPEN_WRITE_FAILED : DK4_E_OPEN_READ_FAILED), errn
+ );
+ }
+#else
+#if DK4_HAVE__WFOPEN64
+ errno = 0;
+ back = _wfopen64(name, mode);
+ if (NULL == back) {
+ dk4error_set_idetails(
+ erp, ((ww) ? DK4_E_OPEN_WRITE_FAILED : DK4_E_OPEN_READ_FAILED), errno
+ );
+ }
+#else
+#if DK4_HAVE__WFOPEN
+ errno = 0;
+ back = _wfopen(name, mode);
+ if (NULL == back) {
+ dk4error_set_idetails(
+ erp, ((ww) ? DK4_E_OPEN_WRITE_FAILED : DK4_E_OPEN_READ_FAILED), errn
+ );
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+#endif
+#endif
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4fopen_check_wc(const wchar_t *name, int ww, int tests, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ WIN32_FIND_DATAW ffdata;
+ HANDLE ha;
+ DWORD dwattr;
+ int back = 1;
+
+
+#line 236 "dk4fopwc.ctr"
+ /* Check name
+ */
+ if (NULL == name) {
+
+#line 239 "dk4fopwc.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ back = 0;
+ goto finished;
+ }
+ /* Retrieve attributes.
+ */
+ dwattr = GetFileAttributesW(name);
+ if (INVALID_FILE_ATTRIBUTES == dwattr) {
+ ha = FindFirstFileW(name, &ffdata);
+ if (INVALID_HANDLE_VALUE != ha) {
+ dwattr = ffdata.dwFileAttributes;
+ FindClose(ha);
+ }
+ }
+ if (INVALID_FILE_ATTRIBUTES == dwattr) {
+
+#line 254 "dk4fopwc.ctr"
+ goto finished;
+ }
+ /* Check directory
+ */
+ if ((DWORD)0UL != (FILE_ATTRIBUTE_DIRECTORY & dwattr)) {
+
+#line 259 "dk4fopwc.ctr"
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ goto finished;
+ }
+ /* Check device
+ */
+ if ((DWORD)0UL != (FILE_ATTRIBUTE_DEVICE & dwattr)) {
+
+#line 266 "dk4fopwc.ctr"
+ back = 0;
+ dk4error_set_idetails(erp, DK4_E_SEC_CHECK, DK4_FOPEN_SC_IS_REGULAR);
+ }
+ finished:
+
+
+#line 271 "dk4fopwc.ctr"
+ return back;
+#else
+ dk4_stat_t stb;
+ dk4_stat_t lstb;
+ int back = 1;
+
+ /* Check arguments.
+ */
+ if (NULL == name) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ back = 0;
+ goto finished;
+ }
+ /* Check existing path.
+ */
+ if (0 == dk4stat_wc(&stb, name, NULL)) {
+
+
+#line 288 "dk4fopwc.ctr"
+ goto finished;
+ }
+ /* Check directory.
+ */
+ if (0 != dk4stat_is_directory(&stb, NULL)) {
+
+
+#line 294 "dk4fopwc.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ back = 0;
+ goto finished;
+ }
+ /* Write regular files only.
+ */
+ if ((0 != ww) && (0 != (tests & DK4_FOPEN_SC_IS_REGULAR))) {
+ if (0 == dk4stat_is_regular(&stb, NULL)) {
+
+
+#line 303 "dk4fopwc.ctr"
+ dk4error_set_idetails(erp, DK4_E_SEC_CHECK, DK4_FOPEN_SC_IS_REGULAR);
+ back = 0;
+ goto finished;
+ }
+ }
+#if 0
+ /* Do not write if any path element is a symbolic link.
+ NO SUCH FUNCTIONS KNOWN FOR wchar_t DATA TYPE!
+ */
+ if ((0 != ww) && (0 != (tests & DK4_FOPEN_SC_WR_SYMLINK_IN_PATH))) {
+ if (0 == dk4fopen_check_no_symlink_in_path(name)) {
+
+
+#line 315 "dk4fopwc.ctr"
+ dk4error_set_idetails(erp, DK4_E_SEC_CHECK, DK4_FOPEN_SC_WR_SYMLINK_IN_PATH);
+ back = 0;
+ goto finished;
+ }
+ }
+#endif
+ /* Obtain symbolic link information.
+ */
+ if (0 == dk4stat_l_wc(&lstb, name, NULL)) {
+
+
+#line 325 "dk4fopwc.ctr"
+ goto finished;
+ }
+ /* Do not write to file via link.
+ */
+ if ((0 != ww) && (0 != (tests & DK4_FOPEN_SC_WR_PATH_IS_SYMLINK))) {
+ if (0 != dk4stat_is_symlink(&lstb, NULL)) {
+
+
+#line 332 "dk4fopwc.ctr"
+ dk4error_set_idetails(erp, DK4_E_SEC_CHECK, DK4_FOPEN_SC_WR_PATH_IS_SYMLINK);
+ back = 0;
+ goto finished;
+ }
+ }
+ /* Do not write file via link if file owner differs from link owner.
+ */
+#if DK4_HAVE_FILE_UIDGID
+ if ((0 != ww) && (0 != (tests & DK4_FOPEN_SC_WR_SYMLINK_OWNER))) {
+ if (lstb.st_uid != stb.st_uid) {
+
+
+#line 343 "dk4fopwc.ctr"
+ dk4error_set_idetails(erp, DK4_E_SEC_CHECK, DK4_FOPEN_SC_WR_SYMLINK_OWNER);
+ back = 0;
+ goto finished;
+ }
+ }
+#endif
+ finished:
+ return back;
+#endif
+}
+
diff --git a/support/dktools/dk4fopwc.ctr b/support/dktools/dk4fopwc.ctr
new file mode 100644
index 0000000000..210587e60d
--- /dev/null
+++ b/support/dktools/dk4fopwc.ctr
@@ -0,0 +1,353 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Open file, apply additional security
+ checks before attempting to open the file.
+
+ Attempts to open a directory as a file are rejected.
+
+ Further optional checks can be applied to avoid:
+ - writing to non-regular files,
+ - writing to files with any symbolic link component in the path,
+ - writing to files via symbolic link,
+ - writing to files via symbolic link if link owner differs
+ from file owner.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4NUMCO_H_INCLUDED
+#include "dk4numco.h"
+#endif
+
+#ifndef DK4FOPT_H_INCLUDED
+#include "dk4fopt.h"
+#endif
+
+#ifndef STDIO_H_INCLUDED
+#include <stdio.h>
+#define STDIO_H_INCLUDED 1
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open a file after doing security checks.
+ CRT on Windows: Required.
+ @param name File name to open.
+ @param mode Opening mode.
+ @param tests Set of tests.
+ @param erp Error report, may be NULL.
+ @return Pointer to open file on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if name is NULL,
+ - DK4_E_SYNTAX<br>
+ if name does not refer to a regular file,
+ - DK4_E_NOT_SUPPORTED<br>
+ if no functions for wchar_t file names are available,
+ - DK4_E_SEC_CHECK<br>
+ with failed check id in iDetails1 if access is denied by additional
+ security checks,
+ - DK4_E_OPEN_WRITE_FAILED<br>
+ or DK4_E_OPEN_READ_FAILED with errno value in iDetails1 if fopen()
+ failed.
+
+*/
+FILE *
+dk4fopen_wc(const wchar_t *name, const wchar_t *mode, int tests, dk4_er_t *erp);
+
+/** Check whether we can allow to open the file.
+ The file must be a regular file.
+ Only POSIX: For root we deny opening for writing via symlink.
+ For all users we deny opening for writing via symlink
+ if the link owner is not the real file owner.
+
+ CRT on Windows: Required.
+ @param name File name to check.
+ @param ww Flag: Write access wanted.
+ @param tests Set of tests.
+ @param erp Error report, may be NULL.
+ @return 1 if opening the file is allowed, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if name is NULL,
+ - DK4_E_SYNTAX<br>
+ if name is not a regular file,
+ - DK4_E_SEC_CHECK<br>
+ if access to a symlink target is denied symlink owner and target
+ owner differ.
+
+*/
+int
+dk4fopen_check_wc(const wchar_t *name, int ww, int tests, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4fopc8.h"
+#include "dk4fopwc.h"
+
+#ifndef DK4STAT8_H_INCLUDED
+#include "dk4statw.h"
+#endif
+
+#ifndef DK4STAT_H_INCLUDED
+#include "dk4stat.h"
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+
+
+$!trace-include
+
+
+
+FILE *
+dk4fopen_wc(const wchar_t *name, const wchar_t *mode, int tests, dk4_er_t *erp)
+{
+ FILE *back = NULL;
+ const wchar_t *cptr;
+ int ww = 0;
+#if DK4_HAVE__WFOPEN_S
+ errno_t errn;
+#endif
+
+ if ((NULL != name) && (NULL != mode)) {
+ cptr = mode;
+ while(*cptr) {
+ if (L'w' == *cptr) { ww = 1; }
+ if (L'a' == *cptr) { ww = 1; }
+ if (L'+' == *cptr) { ww = 1; }
+ cptr++;
+ }
+ if (0 != dk4fopen_check_wc(name, ww, tests, erp)) {
+#if DK4_HAVE__WFOPEN_S
+ errn = _wfopen_s(&back, name, mode);
+ if (0 != errn) {
+ back = NULL;
+ dk4error_set_idetails(
+ erp, ((ww) ? DK4_E_OPEN_WRITE_FAILED : DK4_E_OPEN_READ_FAILED), errn
+ );
+ }
+#else
+#if DK4_HAVE__WFOPEN64
+ errno = 0;
+ back = _wfopen64(name, mode);
+ if (NULL == back) {
+ dk4error_set_idetails(
+ erp, ((ww) ? DK4_E_OPEN_WRITE_FAILED : DK4_E_OPEN_READ_FAILED), errno
+ );
+ }
+#else
+#if DK4_HAVE__WFOPEN
+ errno = 0;
+ back = _wfopen(name, mode);
+ if (NULL == back) {
+ dk4error_set_idetails(
+ erp, ((ww) ? DK4_E_OPEN_WRITE_FAILED : DK4_E_OPEN_READ_FAILED), errn
+ );
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+#endif
+#endif
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4fopen_check_wc(const wchar_t *name, int ww, int tests, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ WIN32_FIND_DATAW ffdata;
+ HANDLE ha;
+ DWORD dwattr;
+ int back = 1;
+ $? "+ dk4fopen_check_wc \"%ls\" wr=%d tests=%d", TR_LSTR(name), ww, tests
+ /* Check name
+ */
+ if (NULL == name) { $? "! illegal name"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ back = 0;
+ goto finished;
+ }
+ /* Retrieve attributes.
+ */
+ dwattr = GetFileAttributesW(name);
+ if (INVALID_FILE_ATTRIBUTES == dwattr) {
+ ha = FindFirstFileW(name, &ffdata);
+ if (INVALID_HANDLE_VALUE != ha) {
+ dwattr = ffdata.dwFileAttributes;
+ FindClose(ha);
+ }
+ }
+ if (INVALID_FILE_ATTRIBUTES == dwattr) { $? "! path does not exist"
+ goto finished;
+ }
+ /* Check directory
+ */
+ if ((DWORD)0UL != (FILE_ATTRIBUTE_DIRECTORY & dwattr)) { $? "! dir"
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ goto finished;
+ }
+ /* Check device
+ */
+ if ((DWORD)0UL != (FILE_ATTRIBUTE_DEVICE & dwattr)) { $? "! device"
+ back = 0;
+ dk4error_set_idetails(erp, DK4_E_SEC_CHECK, DK4_FOPEN_SC_IS_REGULAR);
+ }
+ finished:
+ $? "- dk4fopen_check_wc %d", back
+ return back;
+#else
+ dk4_stat_t stb;
+ dk4_stat_t lstb;
+ int back = 1;
+
+ /* Check arguments.
+ */
+ if (NULL == name) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ back = 0;
+ goto finished;
+ }
+ /* Check existing path.
+ */
+ if (0 == dk4stat_wc(&stb, name, NULL)) {
+ $? ". path does not yet exist"
+ goto finished;
+ }
+ /* Check directory.
+ */
+ if (0 != dk4stat_is_directory(&stb, NULL)) {
+ $? "! path is a directory"
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ back = 0;
+ goto finished;
+ }
+ /* Write regular files only.
+ */
+ if ((0 != ww) && (0 != (tests & DK4_FOPEN_SC_IS_REGULAR))) {
+ if (0 == dk4stat_is_regular(&stb, NULL)) {
+ $? "! not a regular file"
+ dk4error_set_idetails(erp, DK4_E_SEC_CHECK, DK4_FOPEN_SC_IS_REGULAR);
+ back = 0;
+ goto finished;
+ }
+ }
+#if 0
+ /* Do not write if any path element is a symbolic link.
+ NO SUCH FUNCTIONS KNOWN FOR wchar_t DATA TYPE!
+ */
+ if ((0 != ww) && (0 != (tests & DK4_FOPEN_SC_WR_SYMLINK_IN_PATH))) {
+ if (0 == dk4fopen_check_no_symlink_in_path(name)) {
+ $? "! symblic link in path"
+ dk4error_set_idetails(erp, DK4_E_SEC_CHECK, DK4_FOPEN_SC_WR_SYMLINK_IN_PATH);
+ back = 0;
+ goto finished;
+ }
+ }
+#endif
+ /* Obtain symbolic link information.
+ */
+ if (0 == dk4stat_l_wc(&lstb, name, NULL)) {
+ $? ". path does not yet exist or lstat() failed"
+ goto finished;
+ }
+ /* Do not write to file via link.
+ */
+ if ((0 != ww) && (0 != (tests & DK4_FOPEN_SC_WR_PATH_IS_SYMLINK))) {
+ if (0 != dk4stat_is_symlink(&lstb, NULL)) {
+ $? "! path target is symbolic link"
+ dk4error_set_idetails(erp, DK4_E_SEC_CHECK, DK4_FOPEN_SC_WR_PATH_IS_SYMLINK);
+ back = 0;
+ goto finished;
+ }
+ }
+ /* Do not write file via link if file owner differs from link owner.
+ */
+#if DK4_HAVE_FILE_UIDGID
+ if ((0 != ww) && (0 != (tests & DK4_FOPEN_SC_WR_SYMLINK_OWNER))) {
+ if (lstb.st_uid != stb.st_uid) {
+ $? "! link owner is not file owner"
+ dk4error_set_idetails(erp, DK4_E_SEC_CHECK, DK4_FOPEN_SC_WR_SYMLINK_OWNER);
+ back = 0;
+ goto finished;
+ }
+ }
+#endif
+ finished:
+ return back;
+#endif
+}
+
diff --git a/support/dktools/dk4fopwc.h b/support/dktools/dk4fopwc.h
new file mode 100644
index 0000000000..bb9f71aed1
--- /dev/null
+++ b/support/dktools/dk4fopwc.h
@@ -0,0 +1,145 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fopwc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4FOPWC_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4FOPWC_H_INCLUDED 1
+
+
+#line 10 "dk4fopwc.ctr"
+
+/** @file
+ Open file, apply additional security
+ checks before attempting to open the file.
+
+ Attempts to open a directory as a file are rejected.
+
+ Further optional checks can be applied to avoid:
+ - writing to non-regular files,
+ - writing to files with any symbolic link component in the path,
+ - writing to files via symbolic link,
+ - writing to files via symbolic link if link owner differs
+ from file owner.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4NUMCO_H_INCLUDED
+#include "dk4numco.h"
+#endif
+
+#ifndef DK4FOPT_H_INCLUDED
+#include "dk4fopt.h"
+#endif
+
+#ifndef STDIO_H_INCLUDED
+#include <stdio.h>
+#define STDIO_H_INCLUDED 1
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open a file after doing security checks.
+ CRT on Windows: Required.
+ @param name File name to open.
+ @param mode Opening mode.
+ @param tests Set of tests.
+ @param erp Error report, may be NULL.
+ @return Pointer to open file on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if name is NULL,
+ - DK4_E_SYNTAX<br>
+ if name does not refer to a regular file,
+ - DK4_E_NOT_SUPPORTED<br>
+ if no functions for wchar_t file names are available,
+ - DK4_E_SEC_CHECK<br>
+ with failed check id in iDetails1 if access is denied by additional
+ security checks,
+ - DK4_E_OPEN_WRITE_FAILED<br>
+ or DK4_E_OPEN_READ_FAILED with errno value in iDetails1 if fopen()
+ failed.
+
+*/
+FILE *
+dk4fopen_wc(const wchar_t *name, const wchar_t *mode, int tests, dk4_er_t *erp);
+
+/** Check whether we can allow to open the file.
+ The file must be a regular file.
+ Only POSIX: For root we deny opening for writing via symlink.
+ For all users we deny opening for writing via symlink
+ if the link owner is not the real file owner.
+
+ CRT on Windows: Required.
+ @param name File name to check.
+ @param ww Flag: Write access wanted.
+ @param tests Set of tests.
+ @param erp Error report, may be NULL.
+ @return 1 if opening the file is allowed, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if name is NULL,
+ - DK4_E_SYNTAX<br>
+ if name is not a regular file,
+ - DK4_E_SEC_CHECK<br>
+ if access to a symlink target is denied symlink owner and target
+ owner differ.
+
+*/
+int
+dk4fopen_check_wc(const wchar_t *name, int ww, int tests, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4fpe.c b/support/dktools/dk4fpe.c
new file mode 100644
index 0000000000..c1c392ac1f
--- /dev/null
+++ b/support/dktools/dk4fpe.c
@@ -0,0 +1,224 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fpe.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4fpe.c The dk4fpe module.
+*/
+
+
+#line 200 "dk4fpe.ctr"
+
+#include "dk4fpe.h"
+
+
+
+#ifdef _WIN32
+
+/** Exception set for errors.
+*/
+static const unsigned int dk4fpe_errors =
+_SW_ZERODIVIDE | _SW_INVALID | _SW_OVERFLOW | _SW_UNDERFLOW;
+
+#else
+
+/** Exception set for errors.
+*/
+static const int dk4fpe_errors =
+FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW;
+
+#endif
+
+
+
+
+int
+dk4fpe_check_error(dk4_fpe_t fpe, dk4_er_t *erp)
+{
+ int back = 0;
+ if ((dk4_fpe_t)0 != (dk4fpe_errors & fpe)) {
+ back = 1;
+#ifdef _WIN32
+ if ((dk4_fpe_t)0 != (_SW_INVALID & fpe))
+#else
+ if ((dk4_fpe_t)0 != (FE_INVALID & fpe))
+#endif
+ {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_INVALID);
+ }
+ else
+ {
+#ifdef _WIN32
+ if ((dk4_fpe_t)0 != (_SW_ZERODIVIDE & fpe))
+#else
+ if ((dk4_fpe_t)0 != (FE_DIVBYZERO & fpe))
+#endif
+ {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_DIVZERO);
+ }
+ else
+ {
+#ifdef _WIN32
+ if ((dk4_fpe_t)0 != (_SW_OVERFLOW & fpe))
+#else
+ if ((dk4_fpe_t)0 != (FE_OVERFLOW & fpe))
+#endif
+ {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ else
+ {
+#ifdef _WIN32
+ if ((dk4_fpe_t)0 != (_SW_UNDERFLOW & fpe))
+#else
+ if ((dk4_fpe_t)0 != (FE_UNDERFLOW & fpe))
+#endif
+ {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_UNDERFLOW);
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+int
+dk4fpe_clear(dk4_er_t *erp)
+{
+#ifdef _WIN32
+ _clearfp();
+ return 1;
+#else
+#if DK4_HAVE_FETESTEXCEPT
+ int back = 0;
+ if (0 == feclearexcept(FE_ALL_EXCEPT)) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+#endif
+}
+
+
+
+int
+dk4fpe_get(dk4_fpe_t *dptr, dk4_er_t *erp)
+{
+ int back = 0;
+ if (NULL != dptr) {
+#ifdef _WIN32
+ *dptr = (dk4_fpe_t)_statusfp();
+ back = 1;
+#else
+#if DK4_HAVE_FETESTEXCEPT
+ *dptr = (dk4_fpe_t)fetestexcept(FE_ALL_EXCEPT);
+ back = 1;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4fpe_get_clear(dk4_fpe_t *dptr, dk4_er_t *erp)
+{
+ int back = 0;
+ if (NULL != dptr) {
+#ifdef _WIN32
+ *dptr = _clearfp();
+ back = 1;
+#else
+#if DK4_HAVE_FETESTEXCEPT
+ *dptr = (dk4_fpe_t)fetestexcept(FE_ALL_EXCEPT);
+ if (0 == feclearexcept(FE_ALL_EXCEPT)) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4fpe_is_finite(double d)
+{
+ int back = 0;
+#ifdef _WIN32
+ back = ((0 != _finite(d)) ? 1 : 0);
+#else
+ back = ((0 != isfinite(d)) ? 1 : 0);
+#endif
+ return back;
+}
+
+
+
+int
+dk4fpe_is_normal(double d)
+{
+ int back = 0;
+#ifdef _WIN32
+ switch (_fpclass(d)) {
+ case _FPCLASS_NN : case _FPCLASS_NZ :
+ case _FPCLASS_PZ : case _FPCLASS_PN :
+ {
+ back = 1;
+ } break;
+ }
+#else
+ back = ((0 != isnormal(d)) ? 1 : 0);
+#endif
+ return back;
+}
+
diff --git a/support/dktools/dk4fpe.ctr b/support/dktools/dk4fpe.ctr
new file mode 100644
index 0000000000..55ccf4f21a
--- /dev/null
+++ b/support/dktools/dk4fpe.ctr
@@ -0,0 +1,383 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+
+%% header
+
+/** @file dk4fpe.h Floating point exceptions.
+
+ Note: Including this file disables optimization of
+ floating point operations by use of compiler pragma directives.
+
+ Use only in those modules in which you want to check for
+ floating point exceptions.
+
+ This header file should be the last file included by a module.
+*/
+
+
+
+/* Pragmas differ on Windows and Unix/Linux to prevent optimization
+ of floating point operations.
+ At least one compiler bails out with error message for unknown
+ pragma directives.
+*/
+
+#ifndef _WIN32
+/* +++ !Windows */
+#ifdef __SUNPRO_C
+/* +++ !Windows, SUN workshop compiler */
+#if __SUNPRO_C > 0x570
+#pragma STDC FENV_ACCESS on
+#endif
+/* --- !Windows, SUN workshop compiler */
+#else
+/* +++ !Windows, ! SUN workshop compiler */
+#pragma STDC FENV_ACCESS on
+/* --- !Windows, ! SUN workshop compiler */
+#endif
+/* --- !Windows */
+#endif
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#if DK4_HAVE_MATH_H
+#ifndef MATH_H_INCLUDED
+#ifdef _WIN32
+#define _USE_MATH_DEFINES 1
+#endif
+#include <math.h>
+#define MATH_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FLOAT_H
+#ifndef FLOAT_H_INCLUDED
+#include <float.h>
+#define FLOAT_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef _WIN32
+#if DK4_HAVE_FENV_H
+#ifndef FENV_H_INCLUDED
+#include <fenv.h>
+#define FENV_H_INCLUDED 1
+#endif
+#endif
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef _WIN32
+/* +++ Windows */
+#pragma fenv_access (on)
+/* --- Windows */
+#endif
+
+#ifdef _WIN32
+/** Floating point exception set.
+*/
+typedef unsigned int dk4_fpe_t;
+#else
+/** Floating point exception set.
+*/
+typedef int dk4_fpe_t;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** Check floating point exception set for errors occured.
+ @param fpe Floating point exception set.
+ @param erp Error report, may be NULL.
+ @return 1 if error exceptions are set, 0 if there is no
+ error condition.
+
+ Error codes:
+ * DK4_E_MATH_INVALID<br>
+ if an invalid operation was performed,
+ * DK4_E_MATH_DIVZERO<br>
+ if a division by zero (or small denominator) occured,
+ * DK4_E_MATH_OVERFLOW<br>
+ if a range overflow occured (result too large),
+ * DK4_E_MATH_UNDERFLOW<br>
+ if a range underflow occured (result too small).
+*/
+
+int
+dk4fpe_check_error(dk4_fpe_t fpe, dk4_er_t *erp);
+
+
+/** Clear floating point exceptions.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ * DK4_E_NOT_SUPPORTED<br>
+ if no functions for floating point exceptions are available,
+ * DK4_E_SYSTEM<br>
+ if the feclearexcept() function indicated an error.
+*/
+
+int
+dk4fpe_clear(dk4_er_t *erp);
+
+
+/** Obtain floating point exceptions.
+ @param dptr Address of destination variable to store result.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ * DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL,
+ * DK4_E_NOT_SUPPORTED<br>
+ if no functions for floating point exceptions are available.
+*/
+
+int
+dk4fpe_get(dk4_fpe_t *dptr, dk4_er_t *erp);
+
+
+/** Obtain and clear floating point exceptions.
+ @param dptr Address of destination variable to store result.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ * DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL,
+ * DK4_E_NOT_SUPPORTED<br>
+ if no functions for floating point exceptions are available,
+ * DK4_E_SYSTEM<br>
+ if the feclearexcept() function indicated an error.
+*/
+
+int
+dk4fpe_get_clear(dk4_fpe_t *dptr, dk4_er_t *erp);
+
+
+/** Check a double value whether or not it is a finite number
+ (not +/- INF, not NaN).
+ @param d Value to check.
+ @return 1 on success, 0 on error.
+*/
+
+int
+dk4fpe_is_finite(double d) ;
+
+
+/** Check a double value whether or not it is a normalized number
+ (not +/- INF, not NaN, not denormalized).
+ @param d Value to check.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4fpe_is_normal(double d);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4fpe.h"
+
+
+
+#ifdef _WIN32
+
+/** Exception set for errors.
+*/
+static const unsigned int dk4fpe_errors =
+_SW_ZERODIVIDE | _SW_INVALID | _SW_OVERFLOW | _SW_UNDERFLOW;
+
+#else
+
+/** Exception set for errors.
+*/
+static const int dk4fpe_errors =
+FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW;
+
+#endif
+
+
+
+
+int
+dk4fpe_check_error(dk4_fpe_t fpe, dk4_er_t *erp)
+{
+ int back = 0;
+ if ((dk4_fpe_t)0 != (dk4fpe_errors & fpe)) {
+ back = 1;
+#ifdef _WIN32
+ if ((dk4_fpe_t)0 != (_SW_INVALID & fpe))
+#else
+ if ((dk4_fpe_t)0 != (FE_INVALID & fpe))
+#endif
+ {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_INVALID);
+ }
+ else
+ {
+#ifdef _WIN32
+ if ((dk4_fpe_t)0 != (_SW_ZERODIVIDE & fpe))
+#else
+ if ((dk4_fpe_t)0 != (FE_DIVBYZERO & fpe))
+#endif
+ {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_DIVZERO);
+ }
+ else
+ {
+#ifdef _WIN32
+ if ((dk4_fpe_t)0 != (_SW_OVERFLOW & fpe))
+#else
+ if ((dk4_fpe_t)0 != (FE_OVERFLOW & fpe))
+#endif
+ {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ else
+ {
+#ifdef _WIN32
+ if ((dk4_fpe_t)0 != (_SW_UNDERFLOW & fpe))
+#else
+ if ((dk4_fpe_t)0 != (FE_UNDERFLOW & fpe))
+#endif
+ {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_UNDERFLOW);
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+int
+dk4fpe_clear(dk4_er_t *erp)
+{
+#ifdef _WIN32
+ _clearfp();
+ return 1;
+#else
+#if DK4_HAVE_FETESTEXCEPT
+ int back = 0;
+ if (0 == feclearexcept(FE_ALL_EXCEPT)) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+#endif
+}
+
+
+
+int
+dk4fpe_get(dk4_fpe_t *dptr, dk4_er_t *erp)
+{
+ int back = 0;
+ if (NULL != dptr) {
+#ifdef _WIN32
+ *dptr = (dk4_fpe_t)_statusfp();
+ back = 1;
+#else
+#if DK4_HAVE_FETESTEXCEPT
+ *dptr = (dk4_fpe_t)fetestexcept(FE_ALL_EXCEPT);
+ back = 1;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4fpe_get_clear(dk4_fpe_t *dptr, dk4_er_t *erp)
+{
+ int back = 0;
+ if (NULL != dptr) {
+#ifdef _WIN32
+ *dptr = _clearfp();
+ back = 1;
+#else
+#if DK4_HAVE_FETESTEXCEPT
+ *dptr = (dk4_fpe_t)fetestexcept(FE_ALL_EXCEPT);
+ if (0 == feclearexcept(FE_ALL_EXCEPT)) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4fpe_is_finite(double d)
+{
+ int back = 0;
+#ifdef _WIN32
+ back = ((0 != _finite(d)) ? 1 : 0);
+#else
+ back = ((0 != isfinite(d)) ? 1 : 0);
+#endif
+ return back;
+}
+
+
+
+int
+dk4fpe_is_normal(double d)
+{
+ int back = 0;
+#ifdef _WIN32
+ switch (_fpclass(d)) {
+ case _FPCLASS_NN : case _FPCLASS_NZ :
+ case _FPCLASS_PZ : case _FPCLASS_PN :
+ {
+ back = 1;
+ } break;
+ }
+#else
+ back = ((0 != isnormal(d)) ? 1 : 0);
+#endif
+ return back;
+}
+
diff --git a/support/dktools/dk4fpe.h b/support/dktools/dk4fpe.h
new file mode 100644
index 0000000000..553c6b2c76
--- /dev/null
+++ b/support/dktools/dk4fpe.h
@@ -0,0 +1,233 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fpe.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4FPE_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4FPE_H_INCLUDED 1
+
+
+#line 9 "dk4fpe.ctr"
+
+/** @file dk4fpe.h Floating point exceptions.
+
+ Note: Including this file disables optimization of
+ floating point operations by use of compiler pragma directives.
+
+ Use only in those modules in which you want to check for
+ floating point exceptions.
+
+ This header file should be the last file included by a module.
+*/
+
+
+
+/* Pragmas differ on Windows and Unix/Linux to prevent optimization
+ of floating point operations.
+ At least one compiler bails out with error message for unknown
+ pragma directives.
+*/
+
+#ifndef _WIN32
+/* +++ !Windows */
+#ifdef __SUNPRO_C
+/* +++ !Windows, SUN workshop compiler */
+#if __SUNPRO_C > 0x570
+#pragma STDC FENV_ACCESS on
+#endif
+/* --- !Windows, SUN workshop compiler */
+#else
+/* +++ !Windows, ! SUN workshop compiler */
+#pragma STDC FENV_ACCESS on
+/* --- !Windows, ! SUN workshop compiler */
+#endif
+/* --- !Windows */
+#endif
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#if DK4_HAVE_MATH_H
+#ifndef MATH_H_INCLUDED
+#ifdef _WIN32
+#define _USE_MATH_DEFINES 1
+#endif
+#include <math.h>
+#define MATH_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FLOAT_H
+#ifndef FLOAT_H_INCLUDED
+#include <float.h>
+#define FLOAT_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef _WIN32
+#if DK4_HAVE_FENV_H
+#ifndef FENV_H_INCLUDED
+#include <fenv.h>
+#define FENV_H_INCLUDED 1
+#endif
+#endif
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef _WIN32
+/* +++ Windows */
+#pragma fenv_access (on)
+/* --- Windows */
+#endif
+
+#ifdef _WIN32
+/** Floating point exception set.
+*/
+typedef unsigned int dk4_fpe_t;
+#else
+/** Floating point exception set.
+*/
+typedef int dk4_fpe_t;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** Check floating point exception set for errors occured.
+ @param fpe Floating point exception set.
+ @param erp Error report, may be NULL.
+ @return 1 if error exceptions are set, 0 if there is no
+ error condition.
+
+ Error codes:
+ * DK4_E_MATH_INVALID<br>
+ if an invalid operation was performed,
+ * DK4_E_MATH_DIVZERO<br>
+ if a division by zero (or small denominator) occured,
+ * DK4_E_MATH_OVERFLOW<br>
+ if a range overflow occured (result too large),
+ * DK4_E_MATH_UNDERFLOW<br>
+ if a range underflow occured (result too small).
+*/
+
+int
+dk4fpe_check_error(dk4_fpe_t fpe, dk4_er_t *erp);
+
+
+/** Clear floating point exceptions.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ * DK4_E_NOT_SUPPORTED<br>
+ if no functions for floating point exceptions are available,
+ * DK4_E_SYSTEM<br>
+ if the feclearexcept() function indicated an error.
+*/
+
+int
+dk4fpe_clear(dk4_er_t *erp);
+
+
+/** Obtain floating point exceptions.
+ @param dptr Address of destination variable to store result.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ * DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL,
+ * DK4_E_NOT_SUPPORTED<br>
+ if no functions for floating point exceptions are available.
+*/
+
+int
+dk4fpe_get(dk4_fpe_t *dptr, dk4_er_t *erp);
+
+
+/** Obtain and clear floating point exceptions.
+ @param dptr Address of destination variable to store result.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ * DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL,
+ * DK4_E_NOT_SUPPORTED<br>
+ if no functions for floating point exceptions are available,
+ * DK4_E_SYSTEM<br>
+ if the feclearexcept() function indicated an error.
+*/
+
+int
+dk4fpe_get_clear(dk4_fpe_t *dptr, dk4_er_t *erp);
+
+
+/** Check a double value whether or not it is a finite number
+ (not +/- INF, not NaN).
+ @param d Value to check.
+ @return 1 on success, 0 on error.
+*/
+
+int
+dk4fpe_is_finite(double d) ;
+
+
+/** Check a double value whether or not it is a normalized number
+ (not +/- INF, not NaN, not denormalized).
+ @param d Value to check.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4fpe_is_normal(double d);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4fput.c b/support/dktools/dk4fput.c
new file mode 100644
index 0000000000..6719b4c362
--- /dev/null
+++ b/support/dktools/dk4fput.c
@@ -0,0 +1,285 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fput.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4fput.c The dk4fput module.
+*/
+
+
+#line 129 "dk4fput.ctr"
+
+#include "dk4fput.h"
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+
+
+
+
+#line 149 "dk4fput.ctr"
+
+
+
+#if DK4_ON_WINDOWS && (DK4_CHAR_SIZE > 1)
+
+/** Flag: Standard output initialized to write dkChar.
+*/
+static int dk4fput_stdout_initialized = 0;
+
+/** Standard output mode at startup (should be restored before exiting).
+*/
+static int dk4fput_stdout_oldmode = _O_TEXT;
+
+/** Flag: Standard error output initialized to write dkChar.
+*/
+static int dk4fput_stderr_initialized = 0;
+
+/** Standard error mode at startup (should be restored before exiting).
+*/
+static int dk4fput_stderr_oldmode = _O_TEXT;
+
+#endif
+
+
+
+void
+dk4fput_initialize_stdout(void)
+{
+#if DK4_ON_WINDOWS && (DK4_CHAR_SIZE > 1)
+ if (0 == dk4fput_stdout_initialized) {
+ dk4fput_stdout_oldmode = _setmode(_fileno(stdout), _O_U16TEXT);
+ if (0 == _isatty(_fileno(stdout))) {
+ fputwc((wchar_t)0xFEFF, stdout);
+ }
+ dk4fput_stdout_initialized = 1;
+ }
+#endif
+}
+
+
+
+void
+dk4fput_initialize_stdout_no_bom(void)
+{
+#if DK4_ON_WINDOWS && (DK4_CHAR_SIZE > 1)
+ if (0 == dk4fput_stdout_initialized) {
+ dk4fput_stdout_oldmode = _setmode(_fileno(stdout), _O_U16TEXT);
+ dk4fput_stdout_initialized = 1;
+ }
+#endif
+}
+
+
+void
+dk4fput_cleanup_stdout(void)
+{
+#if DK4_ON_WINDOWS && (DK4_CHAR_SIZE > 1)
+ if (0 != dk4fput_stdout_initialized) {
+ fflush(stdout);
+ (void)_setmode(_fileno(stdout), dk4fput_stdout_oldmode);
+ }
+#endif
+}
+
+
+
+void
+dk4fput_initialize_stderr(void)
+{
+#if DK4_ON_WINDOWS && (DK4_CHAR_SIZE > 1)
+ if (0 == dk4fput_stderr_initialized) {
+ dk4fput_stderr_oldmode = _setmode(_fileno(stderr), _O_U16TEXT);
+ if (0 == _isatty(_fileno(stderr))) {
+ fputwc((wchar_t)0xFEFF, stderr);
+ }
+ dk4fput_stderr_initialized = 1;
+ }
+#endif
+}
+
+
+
+void
+dk4fput_initialize_stderr_no_bom(void)
+{
+#if DK4_ON_WINDOWS && (DK4_CHAR_SIZE > 1)
+ if (0 == dk4fput_stderr_initialized) {
+ dk4fput_stderr_oldmode = _setmode(_fileno(stderr), _O_U16TEXT);
+ dk4fput_stderr_initialized = 1;
+ }
+#endif
+}
+
+
+
+void
+dk4fput_cleanup_stderr(void)
+{
+#if DK4_ON_WINDOWS && (DK4_CHAR_SIZE > 1)
+ if (0 != dk4fput_stderr_initialized) {
+ fflush(stderr);
+ (void)_setmode(_fileno(stdout), dk4fput_stderr_oldmode);
+ }
+#endif
+}
+
+
+void
+dk4fput_initialize_file(FILE *fipo)
+{
+#if DK4_ON_WINDOWS && (DK4_CHAR_SIZE > 1)
+ if (NULL != fipo) {
+ (void)_setmode(_fileno(fipo), _O_U16TEXT);
+ fputwc(0xFEFF, fipo);
+ }
+#endif
+}
+
+
+
+void
+dk4fput_initialize_file_no_bom(FILE *fipo)
+{
+#if DK4_ON_WINDOWS && (DK4_CHAR_SIZE > 1)
+ if (NULL != fipo) {
+ (void)_setmode(_fileno(fipo), _O_U16TEXT);
+ }
+#endif
+}
+
+
+
+int
+dk4fputc(dkChar c, FILE *fipo, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#if DK4_HAVE_FPUTWC
+ int back = 0;
+
+
+#line 289 "dk4fput.ctr"
+ if (NULL != fipo) {
+ errno = 0;
+ if (WEOF != fputwc(c, fipo)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_WRITE_FAILED, errno);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 299 "dk4fput.ctr"
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+#else
+ int back = 0;
+ if (NULL != fipo) {
+ errno = 0;
+ if (EOF != fputc(c, fipo)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_WRITE_FAILED, errno);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#endif
+}
+
+
+
+int
+dk4fputs(const dkChar *s, FILE *fipo, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#if DK4_HAVE_FPUTWS
+ int back = 0;
+ if ((NULL != s) && (NULL != fipo)) {
+ errno = 0;
+ if (WEOF != fputws(s, fipo)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_WRITE_FAILED, errno);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+#else
+ int back = 0;
+ if ((NULL != s) && (NULL != fipo)) {
+ errno = 0;
+ if (EOF != fputs(s, fipo)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_WRITE_FAILED, errno);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#endif
+}
+
diff --git a/support/dktools/dk4fput.ctr b/support/dktools/dk4fput.ctr
new file mode 100644
index 0000000000..648b244cb4
--- /dev/null
+++ b/support/dktools/dk4fput.ctr
@@ -0,0 +1,367 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ File functions for dkChar characters
+ and strings.
+
+ CRT on Windows: Required.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef STDIO_H_INCLUDED
+#include <stdio.h>
+#define STDIO_H_INCLUDED 1
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** On Windows, initialize stdout to write dkChar and write a BOM.
+*/
+void
+dk4fput_initialize_stdout(void);
+
+/** On Windows, initialize stdout to write dkChar.
+*/
+void
+dk4fput_initialize_stdout_no_bom(void);
+
+/** On Windows, initialize stderr to write dkChar and write a BOM.
+*/
+void
+dk4fput_initialize_stderr(void);
+
+/** On Windows, initialize stderr to write dkChar.
+*/
+void
+dk4fput_initialize_stderr_no_bom(void);
+
+/** On Windows, initialize file to write dkChar and write a BOM.
+ @param fipo File to set up.
+*/
+void
+dk4fput_initialize_file(FILE *fipo);
+
+/** On Windows, initialize file to write dkChar.
+ @param fipo File to set up.
+*/
+void
+dk4fput_initialize_file_no_bom(FILE *fipo);
+
+/** On Windows, return to the default file encoding for stdout.
+*/
+void
+dk4fput_cleanup_stdout(void);
+
+/** On Windows, return to the default file encoding for stderr.
+*/
+void
+dk4fput_cleanup_stderr(void);
+
+/** Write one character to file.
+ @param c Character to write.
+ @param fipo File to write to.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ if writing wide characters is not supported on the system,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fipo is NULL,
+ - DK4_E_WRITE_FAILED<br>
+ with errno value in iDetails1 if the write attempt failed.
+*/
+int
+dk4fputc(dkChar c, FILE *fipo, dk4_er_t *erp);
+
+/** Write one string to file.
+ @param s String to write.
+ @param fipo File to write to.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ if writing wide character strings is not supported on the system,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fipo is NULL,
+ - DK4_E_WRITE_FAILED<br>
+ with errno in iDetails1 if the write attempt failed.
+*/
+int
+dk4fputs(const dkChar *s, FILE *fipo, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4fput.h"
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+
+
+$!trace-include
+
+
+
+#if DK4_ON_WINDOWS && (DK4_CHAR_SIZE > 1)
+
+/** Flag: Standard output initialized to write dkChar.
+*/
+static int dk4fput_stdout_initialized = 0;
+
+/** Standard output mode at startup (should be restored before exiting).
+*/
+static int dk4fput_stdout_oldmode = _O_TEXT;
+
+/** Flag: Standard error output initialized to write dkChar.
+*/
+static int dk4fput_stderr_initialized = 0;
+
+/** Standard error mode at startup (should be restored before exiting).
+*/
+static int dk4fput_stderr_oldmode = _O_TEXT;
+
+#endif
+
+
+
+void
+dk4fput_initialize_stdout(void)
+{
+#if DK4_ON_WINDOWS && (DK4_CHAR_SIZE > 1)
+ if (0 == dk4fput_stdout_initialized) {
+ dk4fput_stdout_oldmode = _setmode(_fileno(stdout), _O_U16TEXT);
+ if (0 == _isatty(_fileno(stdout))) {
+ fputwc((wchar_t)0xFEFF, stdout);
+ }
+ dk4fput_stdout_initialized = 1;
+ }
+#endif
+}
+
+
+
+void
+dk4fput_initialize_stdout_no_bom(void)
+{
+#if DK4_ON_WINDOWS && (DK4_CHAR_SIZE > 1)
+ if (0 == dk4fput_stdout_initialized) {
+ dk4fput_stdout_oldmode = _setmode(_fileno(stdout), _O_U16TEXT);
+ dk4fput_stdout_initialized = 1;
+ }
+#endif
+}
+
+
+void
+dk4fput_cleanup_stdout(void)
+{
+#if DK4_ON_WINDOWS && (DK4_CHAR_SIZE > 1)
+ if (0 != dk4fput_stdout_initialized) {
+ fflush(stdout);
+ (void)_setmode(_fileno(stdout), dk4fput_stdout_oldmode);
+ }
+#endif
+}
+
+
+
+void
+dk4fput_initialize_stderr(void)
+{
+#if DK4_ON_WINDOWS && (DK4_CHAR_SIZE > 1)
+ if (0 == dk4fput_stderr_initialized) {
+ dk4fput_stderr_oldmode = _setmode(_fileno(stderr), _O_U16TEXT);
+ if (0 == _isatty(_fileno(stderr))) {
+ fputwc((wchar_t)0xFEFF, stderr);
+ }
+ dk4fput_stderr_initialized = 1;
+ }
+#endif
+}
+
+
+
+void
+dk4fput_initialize_stderr_no_bom(void)
+{
+#if DK4_ON_WINDOWS && (DK4_CHAR_SIZE > 1)
+ if (0 == dk4fput_stderr_initialized) {
+ dk4fput_stderr_oldmode = _setmode(_fileno(stderr), _O_U16TEXT);
+ dk4fput_stderr_initialized = 1;
+ }
+#endif
+}
+
+
+
+void
+dk4fput_cleanup_stderr(void)
+{
+#if DK4_ON_WINDOWS && (DK4_CHAR_SIZE > 1)
+ if (0 != dk4fput_stderr_initialized) {
+ fflush(stderr);
+ (void)_setmode(_fileno(stdout), dk4fput_stderr_oldmode);
+ }
+#endif
+}
+
+
+void
+dk4fput_initialize_file(FILE *fipo)
+{
+#if DK4_ON_WINDOWS && (DK4_CHAR_SIZE > 1)
+ if (NULL != fipo) {
+ (void)_setmode(_fileno(fipo), _O_U16TEXT);
+ fputwc(0xFEFF, fipo);
+ }
+#endif
+}
+
+
+
+void
+dk4fput_initialize_file_no_bom(FILE *fipo)
+{
+#if DK4_ON_WINDOWS && (DK4_CHAR_SIZE > 1)
+ if (NULL != fipo) {
+ (void)_setmode(_fileno(fipo), _O_U16TEXT);
+ }
+#endif
+}
+
+
+
+int
+dk4fputc(dkChar c, FILE *fipo, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#if DK4_HAVE_FPUTWC
+ int back = 0;
+ $? "+ dk4fputc (wide) %lx", (unsigned long)c
+ if (NULL != fipo) {
+ errno = 0;
+ if (WEOF != fputwc(c, fipo)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_WRITE_FAILED, errno);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4fputc (wide) %d", back
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+#else
+ int back = 0;
+ if (NULL != fipo) {
+ errno = 0;
+ if (EOF != fputc(c, fipo)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_WRITE_FAILED, errno);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#endif
+}
+
+
+
+int
+dk4fputs(const dkChar *s, FILE *fipo, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#if DK4_HAVE_FPUTWS
+ int back = 0;
+ if ((NULL != s) && (NULL != fipo)) {
+ errno = 0;
+ if (WEOF != fputws(s, fipo)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_WRITE_FAILED, errno);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+#else
+ int back = 0;
+ if ((NULL != s) && (NULL != fipo)) {
+ errno = 0;
+ if (EOF != fputs(s, fipo)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_WRITE_FAILED, errno);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#endif
+}
+
diff --git a/support/dktools/dk4fput.h b/support/dktools/dk4fput.h
new file mode 100644
index 0000000000..a43a96cfae
--- /dev/null
+++ b/support/dktools/dk4fput.h
@@ -0,0 +1,161 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fput.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4FPUT_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4FPUT_H_INCLUDED 1
+
+
+#line 10 "dk4fput.ctr"
+
+/** @file
+ File functions for dkChar characters
+ and strings.
+
+ CRT on Windows: Required.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef STDIO_H_INCLUDED
+#include <stdio.h>
+#define STDIO_H_INCLUDED 1
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** On Windows, initialize stdout to write dkChar and write a BOM.
+*/
+void
+dk4fput_initialize_stdout(void);
+
+/** On Windows, initialize stdout to write dkChar.
+*/
+void
+dk4fput_initialize_stdout_no_bom(void);
+
+/** On Windows, initialize stderr to write dkChar and write a BOM.
+*/
+void
+dk4fput_initialize_stderr(void);
+
+/** On Windows, initialize stderr to write dkChar.
+*/
+void
+dk4fput_initialize_stderr_no_bom(void);
+
+/** On Windows, initialize file to write dkChar and write a BOM.
+ @param fipo File to set up.
+*/
+void
+dk4fput_initialize_file(FILE *fipo);
+
+/** On Windows, initialize file to write dkChar.
+ @param fipo File to set up.
+*/
+void
+dk4fput_initialize_file_no_bom(FILE *fipo);
+
+/** On Windows, return to the default file encoding for stdout.
+*/
+void
+dk4fput_cleanup_stdout(void);
+
+/** On Windows, return to the default file encoding for stderr.
+*/
+void
+dk4fput_cleanup_stderr(void);
+
+/** Write one character to file.
+ @param c Character to write.
+ @param fipo File to write to.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ if writing wide characters is not supported on the system,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fipo is NULL,
+ - DK4_E_WRITE_FAILED<br>
+ with errno value in iDetails1 if the write attempt failed.
+*/
+int
+dk4fputc(dkChar c, FILE *fipo, dk4_er_t *erp);
+
+/** Write one string to file.
+ @param s String to write.
+ @param fipo File to write to.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ if writing wide character strings is not supported on the system,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fipo is NULL,
+ - DK4_E_WRITE_FAILED<br>
+ with errno in iDetails1 if the write attempt failed.
+*/
+int
+dk4fputs(const dkChar *s, FILE *fipo, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4fs.c b/support/dktools/dk4fs.c
new file mode 100644
index 0000000000..afaa7920af
--- /dev/null
+++ b/support/dktools/dk4fs.c
@@ -0,0 +1,982 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fs.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4fs.c The dk4fs module.
+*/
+
+
+#line 493 "dk4fs.ctr"
+
+#include "dk4fs.h"
+
+#if 0
+
+#ifndef DK4STAT_H_INCLUDED
+#include "dk4stat.h"
+#endif
+
+#ifndef DK4STATD_H_INCLUDED
+#include "dk4statd.h"
+#endif
+
+#endif
+
+#ifndef DK4FILED_H_INCLUDED
+#include "dk4filed.h"
+#endif
+
+#ifndef DK4STRD_H_INCLUDED
+#include "dk4strd.h"
+#endif
+
+
+
+
+
+
+#line 520 "dk4fs.ctr"
+
+
+
+/** Constant strings used by this module.
+*/
+static const dkChar * const dk4fs_kw[] = {
+/* 0 */
+dkT("dk4app"),
+
+/* 1 */
+dkT(".dk4app"),
+
+/* 2 */
+dkT("-site"),
+
+/* 3 */
+dkT(".gz"),
+
+/* 4 */
+dkT(".bz2"),
+
+/* 5 */
+dkT("no-language"),
+
+/* 6 */
+dkT("dk3app"),
+
+/* 7 */
+dkT(".dk3app"),
+
+NULL
+
+
+#line 551 "dk4fs.ctr"
+};
+
+
+
+#if DK4_HAVE_BACKSLASH_AS_SEP
+/** Path name separator.
+*/
+static const dkChar dk4fs_sep[] = { dkT("\\") };
+#else
+/** Path name separator.
+*/
+static const dkChar dk4fs_sep[] = { dkT("/") };
+#endif
+
+
+
+#if 0
+/** Check presence of regular file.
+ CRT on Windows: Optional.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success (file exists and is a regular file), 0 otherwise.
+*/
+static
+int
+dk4fs_check_regular_file(
+ const dkChar *fn,
+ dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS && (DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT)
+#if DK4_CHAR_SIZE > 1
+ WIN32_FIND_DATAW ffdata;
+#els
+ WIN32_FIND_DATAA ffdata;
+#endif
+ HANDLE ha;
+ DWORD dwattr;
+ int back = 0;
+#if DK4_CHAR_SIZE > 1
+ dwattr = GetFileAttributesW(fn);
+#else
+ dwattr = GetFileAttributesA(fn);
+#endif
+ if (INVALID_FILE_ATTRIBUTES == dwattr) {
+#if DK4_CHAR_SIZE > 1
+ ha = FindFirstFileW(fn, &ffdata);
+#else
+ ha = FindFirstFileA(fn, &ffdata);
+#endif
+ if (INVALID_HANDLE_VALUE != ha) {
+ dwattr = ffdata.dwFileAttributes;
+ FindClose(ha);
+ }
+ }
+ if (INVALID_FILE_ATTRIBUTES != dwattr) {
+ if ((DWORD)0UL == (FILE_ATTRIBUTE_DIRECTORY & dwattr)) {
+ if ((DWORD)0UL == (FILE_ATTRIBUTE_DEVICE & dwattr)) {
+ back = 1;
+ }
+ }
+ }
+ return back;
+#else
+ dk4_stat_t stb;
+ int back = 0;
+ if (0 != dk4stat(&stb, fn, erp)) {
+ if (0 != dk4stat_is_regular(&stb, erp)) {
+ back = 1;
+ }
+ }
+ return back;
+#endif
+}
+#endif
+
+
+
+int
+dk4fs_attempt_file_name(
+ dkChar *dptr,
+ size_t szdptr,
+ int compressed,
+ dk4_er_t *erp
+)
+{
+ dkChar *eptr; /* End of name */
+ int back = 0;
+
+
+#line 640 "dk4fs.ctr"
+ if ((NULL != dptr) && (0 < szdptr)) {
+#if DK4_ON_WINDOWS && DK4_WIN_DENY_CRT
+ /* Compression/decompression libraries depend on CRT.
+ */
+ compressed = 0;
+#endif
+
+
+#line 647 "dk4fs.ctr"
+ back = dk4file_is_regular(dptr, erp);
+
+
+#line 649 "dk4fs.ctr"
+ if ((0 == back) && (0 != compressed)) {
+ eptr = dptr;
+ while (dkT('\0') != *eptr) { eptr++; }
+#if DK4_HAVE_ZLIB_H
+ if (0 != dk4str_cat_s(dptr, szdptr, dk4fs_kw[3], erp)) {
+
+
+#line 655 "dk4fs.ctr"
+ back = dk4file_is_regular(dptr, erp);
+
+
+#line 657 "dk4fs.ctr"
+ }
+#endif
+#if DK4_HAVE_BZLIB_H
+ if (0 == back) {
+ *eptr = dkT('\0');
+ if (0 != dk4str_cat_s(dptr, szdptr, dk4fs_kw[4], erp)) {
+
+
+#line 664 "dk4fs.ctr"
+ back = dk4file_is_regular(dptr, erp);
+
+
+#line 666 "dk4fs.ctr"
+ }
+ if (0 == back) {
+ *eptr = dkT('\0');
+ }
+ }
+#endif
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 676 "dk4fs.ctr"
+ return back;
+}
+
+
+
+int
+dk4fs_construct_from_parts(
+ dkChar *dptr,
+ size_t szdptr,
+ const dkChar **comp,
+ size_t ncomp,
+ int site,
+ dk4_er_t *erp
+)
+{
+ size_t i; /* Traverse comp */
+ int back = 0; /* Function result */
+
+
+#line 694 "dk4fs.ctr"
+ if ((NULL != dptr) && (0 < szdptr) && (NULL != comp) && (0 < ncomp)) {
+ for (i = 0; i < ncomp; i++) {
+ if (0 == i) {
+ if (0 == dk4str_cpy_s(dptr, szdptr, comp[0], erp)) {
+ goto finished;
+ }
+ } else {
+ if (0 != dk4str_cat_s(dptr, szdptr, dk4fs_sep, erp)) {
+ if (0 != dk4str_cat_s(dptr, szdptr, comp[i], erp)) {
+ if ((1 == i) && (0 != site)) {
+ if (0 == dk4str_cat_s(dptr, szdptr, dk4fs_kw[2], erp)) {
+ goto finished;
+ }
+ }
+ } else {
+ goto finished;
+ }
+ } else {
+ goto finished;
+ }
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ back = 1;
+ finished:
+ if (0 == back) { *dptr = dkT('\0'); }
+
+
+#line 723 "dk4fs.ctr"
+ return back;
+}
+
+
+
+int
+dk4fs_config_construct_compat_one(
+ dkChar *dptr,
+ size_t szdptr,
+ const dkChar *shortname,
+ const dkChar *dir_share,
+ const dkChar *dir_etc,
+ const dkChar *dir_home,
+ const dkChar *name_prog,
+ const dkChar *name_group,
+ int passno,
+ int co3,
+ dk4_er_t *erp
+)
+{
+ const dkChar *ptrs[8];
+ int back = 0;
+
+
+#line 746 "dk4fs.ctr"
+ if ((NULL != dptr) && (0 < szdptr) && (NULL != shortname)) {
+ switch (passno) {
+ case DK4_FS_CONF_SHARE_LIB: {
+ if (NULL != dir_share) {
+ ptrs[0] = dir_share;
+ ptrs[1] = dk4fs_kw[(co3) ? (6) : (0)];
+ ptrs[2] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,3,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_CONF_ETC_LIB: {
+ if (NULL != dir_etc) {
+ ptrs[0] = dir_etc;
+ ptrs[1] = dk4fs_kw[(co3) ? (6) : (0)];
+ ptrs[2] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,3,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_CONF_SHARE_LIB_SITE: {
+ if (NULL != dir_share) {
+ ptrs[0] = dir_share;
+ ptrs[1] = dk4fs_kw[(co3) ? (6) : (0)];
+ ptrs[2] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,3,1,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_CONF_ETC_LIB_SITE: {
+ if (NULL != dir_etc) {
+ ptrs[0] = dir_etc;
+ ptrs[1] = dk4fs_kw[(co3) ? (6) : (0)];
+ ptrs[2] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,3,1,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_CONF_SHARE_GROUP: {
+ if ((NULL != dir_share) && (NULL != name_group)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = name_group;
+ ptrs[2] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,3,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_CONF_ETC_GROUP: {
+ if ((NULL != dir_etc) && (NULL != name_group)) {
+ ptrs[0] = dir_etc;
+ ptrs[1] = name_group;
+ ptrs[2] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,3,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_CONF_SHARE_GROUP_SITE: {
+ if ((NULL != dir_share) && (NULL != name_group)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = name_group;
+ ptrs[2] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,3,1,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_CONF_ETC_GROUP_SITE: {
+ if ((NULL != dir_etc) && (NULL != name_group)) {
+ ptrs[0] = dir_etc;
+ ptrs[1] = name_group;
+ ptrs[2] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,3,1,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_CONF_SHARE_APP: {
+ if ((NULL != dir_share) && (NULL != name_prog)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = name_prog;
+ ptrs[2] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,3,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_CONF_ETC_APP: {
+ if ((NULL != dir_etc) && (NULL != name_prog)) {
+ ptrs[0] = dir_etc;
+ ptrs[1] = name_prog;
+ ptrs[2] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,3,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_CONF_SHARE_APP_SITE: {
+ if ((NULL != dir_share) && (NULL != name_prog)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = name_prog;
+ ptrs[2] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,3,1,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_CONF_ETC_APP_SITE: {
+ if ((NULL != dir_etc) && (NULL != name_prog)) {
+ ptrs[0] = dir_etc;
+ ptrs[1] = name_prog;
+ ptrs[2] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,3,1,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_CONF_HOME_LIB: {
+ if (NULL != dir_home) {
+ ptrs[0] = dir_home;
+ ptrs[1] = dk4fs_kw[(co3) ? (7) : (1)];
+ ptrs[2] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,3,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_CONF_HOME_GROUP: {
+ if ((NULL != dir_home) && (NULL != name_group)) {
+ ptrs[0] = dir_home;
+ ptrs[1] = dk4fs_kw[(co3) ? (7) : (1)];
+ ptrs[2] = name_group;
+ ptrs[3] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,4,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_CONF_HOME_APP: {
+ if ((NULL != dir_home) && (NULL != name_prog)) {
+ ptrs[0] = dir_home;
+ ptrs[1] = dk4fs_kw[(co3) ? (7) : (1)];
+ ptrs[2] = name_prog;
+ ptrs[3] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,4,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_CONF_CURRENT_DIR: {
+ ptrs[0] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,1,0,erp);
+ } break;
+ default: {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 912 "dk4fs.ctr"
+ return back;
+}
+
+
+
+int
+dk4fs_config_construct_one(
+ dkChar *dptr,
+ size_t szdptr,
+ const dkChar *shortname,
+ const dkChar *dir_share,
+ const dkChar *dir_etc,
+ const dkChar *dir_home,
+ const dkChar *name_prog,
+ const dkChar *name_group,
+ int passno,
+ dk4_er_t *erp
+)
+{
+ return(
+ dk4fs_config_construct_compat_one(
+ dptr, szdptr, shortname, dir_share, dir_etc, dir_home,
+ name_prog, name_group, passno, 0, erp
+ )
+ );
+}
+
+
+
+int
+dk4fs_config_compat_one(
+ dkChar *dptr,
+ size_t szdptr,
+ const dkChar *shortname,
+ const dkChar *dir_share,
+ const dkChar *dir_etc,
+ const dkChar *dir_home,
+ const dkChar *name_prog,
+ const dkChar *name_group,
+ int passno,
+ int co3,
+ int compressed,
+ dk4_er_t *erp
+)
+{
+ int back;
+
+
+#line 959 "dk4fs.ctr"
+ back = dk4fs_config_construct_compat_one(
+ dptr, szdptr, shortname,
+ dir_share, dir_etc, dir_home,
+ name_prog, name_group, passno, co3, erp
+ );
+ if (0 != back) {
+
+
+#line 966 "dk4fs.ctr"
+ back = dk4fs_attempt_file_name(dptr, szdptr, compressed, erp);
+ if (0 != back) {
+
+#line 968 "dk4fs.ctr"
+ }
+ }
+
+#line 970 "dk4fs.ctr"
+ return back;
+}
+
+
+
+int
+dk4fs_config_one(
+ dkChar *dptr,
+ size_t szdptr,
+ const dkChar *shortname,
+ const dkChar *dir_share,
+ const dkChar *dir_etc,
+ const dkChar *dir_home,
+ const dkChar *name_prog,
+ const dkChar *name_group,
+ int passno,
+ int compressed,
+ dk4_er_t *erp
+)
+{
+ return (
+ dk4fs_config_compat_one(
+ dptr, szdptr, shortname,
+ dir_share, dir_etc, dir_home, name_prog, name_group,
+ passno, 0, compressed, erp
+ )
+ );
+}
+
+
+
+int
+dk4fs_data_construct_one(
+ dkChar *dptr,
+ size_t szdptr,
+ const dkChar *shortname,
+ const dkChar *dir_share,
+ const dkChar *language,
+ const dkChar *region,
+ const dkChar *dir_home,
+ const dkChar *name_prog,
+ const dkChar *name_group,
+ int passno,
+ dk4_er_t *erp
+)
+{
+ const dkChar *ptrs[8];
+ int back = 0;
+
+
+#line 1019 "dk4fs.ctr"
+
+
+#line 1020 "dk4fs.ctr"
+
+
+#line 1021 "dk4fs.ctr"
+
+
+#line 1022 "dk4fs.ctr"
+
+
+#line 1023 "dk4fs.ctr"
+
+
+#line 1024 "dk4fs.ctr"
+
+
+#line 1025 "dk4fs.ctr"
+
+
+#line 1026 "dk4fs.ctr"
+
+
+#line 1027 "dk4fs.ctr"
+ if ((NULL != dptr) && (0 < szdptr) && (NULL != shortname)) {
+ switch (passno) {
+
+ case DK4_FS_DATA_SHARE_LIB: {
+ back = dk4fs_config_construct_one(
+ dptr, szdptr, shortname,
+ dir_share, NULL, dir_home,
+ name_prog, name_group, DK4_FS_CONF_SHARE_LIB, erp
+ );
+ } break;
+ case DK4_FS_DATA_SHARE_LIB_SITE: {
+ back = dk4fs_config_construct_one(
+ dptr, szdptr, shortname,
+ dir_share, NULL, dir_home,
+ name_prog, name_group, DK4_FS_CONF_SHARE_LIB_SITE, erp
+ );
+ } break;
+ case DK4_FS_DATA_SHARE_GROUP: {
+ back = dk4fs_config_construct_one(
+ dptr, szdptr, shortname,
+ dir_share, NULL, dir_home,
+ name_prog, name_group, DK4_FS_CONF_SHARE_GROUP, erp
+ );
+ } break;
+ case DK4_FS_DATA_SHARE_GROUP_SITE: {
+ back = dk4fs_config_construct_one(
+ dptr, szdptr, shortname,
+ dir_share, NULL, dir_home,
+ name_prog, name_group, DK4_FS_CONF_SHARE_GROUP_SITE, erp
+ );
+ } break;
+ case DK4_FS_DATA_SHARE_APP: {
+ back = dk4fs_config_construct_one(
+ dptr, szdptr, shortname,
+ dir_share, NULL, dir_home,
+ name_prog, name_group, DK4_FS_CONF_SHARE_APP, erp
+ );
+ } break;
+ case DK4_FS_DATA_SHARE_APP_SITE: {
+ back = dk4fs_config_construct_one(
+ dptr, szdptr, shortname,
+ dir_share, NULL, dir_home,
+ name_prog, name_group, DK4_FS_CONF_SHARE_APP_SITE, erp
+ );
+ } break;
+ case DK4_FS_DATA_SHARE_LIB_LANG: {
+ if ((NULL != dir_share) && (NULL != language)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = dk4fs_kw[0];
+ ptrs[2] = language;
+ ptrs[3] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,4,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_SHARE_LIB_SITE_LANG: {
+ if ((NULL != dir_share) && (NULL != language)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = dk4fs_kw[0];
+ ptrs[2] = language;
+ ptrs[3] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,4,1,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_SHARE_GROUP_LANG: {
+ if ((NULL != dir_share) && (NULL != language) && (NULL != name_group)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = name_group;
+ ptrs[2] = language;
+ ptrs[3] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,4,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_SHARE_GROUP_SITE_LANG: {
+ if ((NULL != dir_share) && (NULL != language) && (NULL != name_group)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = name_group;
+ ptrs[2] = language;
+ ptrs[3] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,4,1,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_SHARE_APP_LANG: {
+ if ((NULL != dir_share) && (NULL != language) && (NULL != name_prog)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = name_prog;
+ ptrs[2] = language;
+ ptrs[3] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,4,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_SHARE_APP_SITE_LANG: {
+ if ((NULL != dir_share) && (NULL != language) && (NULL != name_prog)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = name_prog;
+ ptrs[2] = language;
+ ptrs[3] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,4,1,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_SHARE_LIB_REG: {
+ if ((NULL != dir_share) && (NULL != region)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = dk4fs_kw[0];
+ ptrs[2] = dk4fs_kw[5];
+ ptrs[3] = region;
+ ptrs[4] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,5,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_SHARE_LIB_SITE_REG: {
+ if ((NULL != dir_share) && (NULL != region)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = dk4fs_kw[0];
+ ptrs[2] = dk4fs_kw[5];
+ ptrs[3] = region;
+ ptrs[4] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,5,1,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_SHARE_GROUP_REG: {
+ if ((NULL != dir_share) && (NULL != name_group) && (NULL != region)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = name_group;
+ ptrs[2] = dk4fs_kw[5];
+ ptrs[3] = region;
+ ptrs[4] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,5,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_SHARE_GROUP_SITE_REG: {
+ if ((NULL != dir_share) && (NULL != name_group) && (NULL != region)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = name_group;
+ ptrs[2] = dk4fs_kw[5];
+ ptrs[3] = region;
+ ptrs[4] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,5,1,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_SHARE_APP_REG: {
+ if ((NULL != dir_share) && (NULL != name_prog) && (NULL != region)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = name_prog;
+ ptrs[2] = dk4fs_kw[5];
+ ptrs[3] = region;
+ ptrs[4] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,5,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_SHARE_APP_SITE_REG: {
+ if ((NULL != dir_share) && (NULL != name_prog) && (NULL != region)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = name_prog;
+ ptrs[2] = dk4fs_kw[5];
+ ptrs[3] = region;
+ ptrs[4] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,5,1,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_SHARE_LIB_LANG_REG: {
+ if ((NULL != dir_share) && (NULL != language) && (NULL != region)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = dk4fs_kw[0];
+ ptrs[2] = language;
+ ptrs[3] = region;
+ ptrs[4] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,5,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_SHARE_LIB_SITE_LANG_REG: {
+ if ((NULL != dir_share) && (NULL != language) && (NULL != region)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = dk4fs_kw[0];
+ ptrs[2] = language;
+ ptrs[3] = region;
+ ptrs[4] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,5,1,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_SHARE_GROUP_LANG_REG: {
+ if ((NULL != dir_share) && (NULL != language)) {
+ if ((NULL != region) && (NULL != name_group)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = name_group;
+ ptrs[2] = language;
+ ptrs[3] = region;
+ ptrs[4] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,5,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_SHARE_GROUP_SITE_LANG_REG: {
+ if ((NULL != dir_share) && (NULL != language)) {
+ if ((NULL != region) && (NULL != name_group)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = name_group;
+ ptrs[2] = language;
+ ptrs[3] = region;
+ ptrs[4] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,5,1,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_SHARE_APP_LANG_REG: {
+ if ((NULL != dir_share) && (NULL != language)) {
+ if ((NULL != region) && (NULL != name_prog)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = name_prog;
+ ptrs[2] = language;
+ ptrs[3] = region;
+ ptrs[4] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,5,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_SHARE_APP_SITE_LANG_REG: {
+ if ((NULL != dir_share) && (NULL != language)) {
+ if ((NULL != region) && (NULL != name_prog)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = name_prog;
+ ptrs[2] = language;
+ ptrs[3] = region;
+ ptrs[4] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,5,1,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_HOME_LIB: {
+ if (NULL != dir_home) {
+ ptrs[0] = dir_home;
+ ptrs[1] = dk4fs_kw[1];
+ ptrs[2] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,3,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_HOME_GROUP: {
+ if ((NULL != dir_home) && (NULL != name_group)) {
+ ptrs[0] = dir_home;
+ ptrs[1] = dk4fs_kw[1];
+ ptrs[2] = name_group;
+ ptrs[3] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,4,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_HOME_APP: {
+ if ((NULL != dir_home) && (NULL != name_prog)) {
+ ptrs[0] = dir_home;
+ ptrs[1] = dk4fs_kw[1];
+ ptrs[2] = name_prog;
+ ptrs[3] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,4,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_CURRENT_DIR: {
+ back = dk4str_cpy_s(dptr, szdptr, shortname, erp);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 1338 "dk4fs.ctr"
+ return back;
+}
+
+
+
+int
+dk4fs_data_one(
+ dkChar *dptr,
+ size_t szdptr,
+ const dkChar *shortname,
+ const dkChar *dir_share,
+ const dkChar *dir_home,
+ const dkChar *name_prog,
+ const dkChar *name_group,
+ const dkChar *language,
+ const dkChar *region,
+ int passno,
+ int compressed,
+ dk4_er_t *erp
+)
+{
+ int back;
+
+
+#line 1361 "dk4fs.ctr"
+ back = dk4fs_data_construct_one(
+ dptr, szdptr, shortname,
+ dir_share, language, region, dir_home,
+ name_prog, name_group, passno, erp
+ );
+ if (0 != back) {
+
+#line 1367 "dk4fs.ctr"
+ back = dk4fs_attempt_file_name(dptr, szdptr, compressed, erp);
+ }
+
+#line 1369 "dk4fs.ctr"
+ return back;
+}
+
diff --git a/support/dktools/dk4fs.ctr b/support/dktools/dk4fs.ctr
new file mode 100644
index 0000000000..75f0dc75cd
--- /dev/null
+++ b/support/dktools/dk4fs.ctr
@@ -0,0 +1,1371 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ File search for configuration and data files.
+ Specify short file name and a number of directories:
+ - shared data directory (i.e. /usr/share) or system
+ configuration directory (i.e. /etc),
+ - users home directory,
+ - program name,
+ - program group name,
+ - language,
+ - region
+
+ Use dk4fs_config_one() or dk4fs_data_one() multiple times to
+ find the file best matching
+ program name, group name, language and region. See below.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+/** Pass numbers for configuration file search.
+
+ The group name passed as name_group is used instead of group,
+ the program name passed as name_prog is used instead of prog.
+*/
+enum {
+ DK4_FS_CONF_SHARE_LIB = 0, /**< /usr/share/dk4app */
+ DK4_FS_CONF_ETC_LIB , /**< /etc/dk4app */
+ DK4_FS_CONF_SHARE_LIB_SITE , /**< /usr/share/dk4app-site */
+ DK4_FS_CONF_ETC_LIB_SITE , /**< /etc/dk4app-site */
+ DK4_FS_CONF_SHARE_GROUP , /**< /usr/share/group */
+ DK4_FS_CONF_ETC_GROUP , /**< /etc/group */
+ DK4_FS_CONF_SHARE_GROUP_SITE , /**< /usr/share/group-site */
+ DK4_FS_CONF_ETC_GROUP_SITE , /**< /etc/group-site */
+ DK4_FS_CONF_SHARE_APP , /**< /usr/share/prog */
+ DK4_FS_CONF_ETC_APP , /**< /etc/prog */
+ DK4_FS_CONF_SHARE_APP_SITE , /**< /usr/share/prog-site */
+ DK4_FS_CONF_ETC_APP_SITE , /**< /etc/prog-site */
+ DK4_FS_CONF_HOME_LIB , /**< HOME/.dk4app */
+ DK4_FS_CONF_HOME_GROUP , /**< HOME/.dk4app/group */
+ DK4_FS_CONF_HOME_APP , /**< HOME/.dk4app/prog */
+ DK4_FS_CONF_CURRENT_DIR , /**< Current directory */
+
+ /** Maximum value.
+ */
+ DK4_FS_CONF_MAX = DK4_FS_CONF_CURRENT_DIR ,
+
+ /** Maximum value to search
+ system directories only.
+ */
+ DK4_FS_CONF_SYS_MAX = DK4_FS_CONF_ETC_APP_SITE
+};
+
+
+
+/** Pass numbers for data file search.
+
+ The group name passed as name_group is used instead of group,
+ the program name passed as name_prog is used instead of prog.
+*/
+enum {
+ DK4_FS_DATA_SHARE_LIB = 0, /**< /usr/share/dk4app */
+ DK4_FS_DATA_SHARE_LIB_SITE , /**< /usr/share/dk4app-site */
+ DK4_FS_DATA_SHARE_GROUP , /**< /usr/share/group */
+ DK4_FS_DATA_SHARE_GROUP_SITE , /**< /usr/share/group-site */
+ DK4_FS_DATA_SHARE_APP , /**< /usr/share/prog */
+ DK4_FS_DATA_SHARE_APP_SITE , /**< /usr/share/prog-site */
+ DK4_FS_DATA_SHARE_LIB_LANG , /**< /usr/share/dk4app/l */
+ DK4_FS_DATA_SHARE_LIB_SITE_LANG , /**< /usr/share/dk4app-site/l */
+ DK4_FS_DATA_SHARE_GROUP_LANG , /**< /usr/share/group/l */
+ DK4_FS_DATA_SHARE_GROUP_SITE_LANG , /**< /usr/share/group-site/l */
+ DK4_FS_DATA_SHARE_APP_LANG , /**< /usr/share/prog/l */
+ DK4_FS_DATA_SHARE_APP_SITE_LANG , /**< /usr/share/prog-site/l */
+ DK4_FS_DATA_SHARE_LIB_REG , /**< /usr/share/dk4app */
+ DK4_FS_DATA_SHARE_LIB_SITE_REG , /**< /usr/share/dk4app-site */
+ DK4_FS_DATA_SHARE_GROUP_REG , /**< /usr/share/group */
+ DK4_FS_DATA_SHARE_GROUP_SITE_REG , /**< /usr/share/group-site */
+ DK4_FS_DATA_SHARE_APP_REG , /**< /usr/share/prog/no-language/r */
+ DK4_FS_DATA_SHARE_APP_SITE_REG , /**< /usr/share/prog-site/no-language/r */
+ DK4_FS_DATA_SHARE_LIB_LANG_REG , /**< /usr/share/dk4app/l/r */
+ DK4_FS_DATA_SHARE_LIB_SITE_LANG_REG , /**< /usr/share/dk4app-site/l/r */
+ DK4_FS_DATA_SHARE_GROUP_LANG_REG , /**< /usr/share/group/l/r */
+ DK4_FS_DATA_SHARE_GROUP_SITE_LANG_REG , /**< /usr/share/group-site/l/r */
+ DK4_FS_DATA_SHARE_APP_LANG_REG , /**< /usr/share/prog/l/r */
+ DK4_FS_DATA_SHARE_APP_SITE_LANG_REG , /**< /usr/share/prog-site/l/r */
+ DK4_FS_DATA_HOME_LIB , /**< HOME/.dk4app */
+ DK4_FS_DATA_HOME_GROUP , /**< HOME/.dk4app/group */
+ DK4_FS_DATA_HOME_APP , /**< HOME/.dk4app/prog */
+ DK4_FS_DATA_CURRENT_DIR , /**< Current directory */
+
+ /** Maximum system data file.
+ */
+ DK4_FS_DATA_MAX_SYS = DK4_FS_DATA_SHARE_APP_SITE_LANG_REG,
+
+ /** Maximum data file.
+ */
+ DK4_FS_DATA_MAX = DK4_FS_DATA_CURRENT_DIR
+};
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Check presence of one file, optionally with compression suffixes.
+ CRT on Windows: Optional.
+ @param dptr Buffer containing file name.
+ @param szdptr Buffer size.
+ @param compressed Flag: Search for compressed files too.
+ @param erp Error report, may be NULL.
+ @return 1 if file or optionally compressed file found, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or szdptr is 0,
+ - DK4_E_NOT_SUPPORTED<br>
+ if wchar_t are used as dkChar on non-Windows systems,
+ - DK4_E_NOT_FOUND<br>
+ if the file was not found.
+*/
+int
+dk4fs_attempt_file_name(
+ dkChar *dptr,
+ size_t szdptr,
+ int compressed,
+ dk4_er_t *erp
+);
+
+/** Attempt to construct one file name from multiple parts.
+ CRT on Windows: Optional.
+ @param dptr Destination buffer address.
+ @param szdptr Destination buffer size (number of dkChar).
+ @param comp Components array.
+ @param ncomp Number of components.
+ @param site Flag: Add -site after second component.
+ @param erp Error report, may be NULL.
+ @return 1 on success (path constructed and file exists), 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or comp is NULL or szdptr or ncomp is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the dptr buffer is too small,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow happened during
+ a size calculation.
+*/
+int
+dk4fs_construct_from_parts(
+ dkChar *dptr,
+ size_t szdptr,
+ const dkChar **comp,
+ size_t ncomp,
+ int site,
+ dk4_er_t *erp
+);
+
+/** Attempt to construct one path name for a configuration file.
+ CRT on Windows: Optional.
+ @param dptr Buffer for result file name.
+ @param szdptr Size of buffer (number of dkChar).
+ @param shortname Short configuration file name.
+ @param dir_share The data directory.
+ @param dir_etc The system configuration directory.
+ @param dir_home Users home directory.
+ @param name_prog Application name.
+ @param name_group Application group name.
+ @param passno Number of current pass.
+ @param co3 Flag: Compatible to DK tools 3.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or shortname is NULL or szdptr is 0 or passno is an invalid
+ number or one of the used strings (dir_share, dir_etc, dir_home,
+ name_prog, or name_group) is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the dptr buffer is too small,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow happened during a size calculation.
+*/
+int
+dk4fs_config_construct_compat_one(
+ dkChar *dptr,
+ size_t szdptr,
+ const dkChar *shortname,
+ const dkChar *dir_share,
+ const dkChar *dir_etc,
+ const dkChar *dir_home,
+ const dkChar *name_prog,
+ const dkChar *name_group,
+ int passno,
+ int co3,
+ dk4_er_t *erp
+);
+
+/** Attempt to construct one path name for a configuration file.
+ CRT on Windows: Optional.
+ @param dptr Buffer for result file name.
+ @param szdptr Size of buffer (number of dkChar).
+ @param shortname Short configuration file name.
+ @param dir_share The data directory.
+ @param dir_etc The system configuration directory.
+ @param dir_home Users home directory.
+ @param name_prog Application name.
+ @param name_group Application group name.
+ @param passno Number of current pass.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or shortname is NULL or szdptr is 0 or passno is an invalid
+ number or one of the used strings (dir_share, dir_etc, dir_home,
+ name_prog, or name_group) is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the dptr buffer is too small,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow happened during a size calculation.
+*/
+int
+dk4fs_config_construct_one(
+ dkChar *dptr,
+ size_t szdptr,
+ const dkChar *shortname,
+ const dkChar *dir_share,
+ const dkChar *dir_etc,
+ const dkChar *dir_home,
+ const dkChar *name_prog,
+ const dkChar *name_group,
+ int passno,
+ dk4_er_t *erp
+);
+
+/** Check one path candidate for configuration file name
+ (construct name and check presence of file).
+
+ To search for a file matching your needs run this function
+ multiple times with differenct passno values.
+ - To search for one file best matching:
+ - Start with pass number DK4_FS_CONF_MAX or DK4_FS_CONF_SYS_MAX
+ and decrease the number down to DK4_FS_CONF_SHARE_LIB,
+ use the first file found.
+ - Start with pass number DK4_FS_CONF_MAX to allow both user
+ and system configuration files.
+ - Start with pass number DK4_FS_CONF_SYS_MAX to process system
+ configuration files only.
+ - To process multiple files, each file may overwrite settings
+ made by previous files:
+ - Start with pass number DK4_FS_CONF_SHARE_LIB (0) and increase
+ the pass number up to DK4_FS_CONF_SYS_MAX or DK4_FS_CONF_MAX.
+ - Stopping after DK4_FS_CONF_SYS_MAX will process system
+ configuration files only, stopping after DK4_FS_CONF_MAX
+ processes both system and user configuration files.
+
+ CRT on Windows: Optional.
+ @param dptr Buffer for result file name.
+ @param szdptr Size of buffer (number of dkChar).
+ @param shortname Short configuration file name.
+ @param dir_share The data directory.
+ @param dir_etc The system configuration directory.
+ @param dir_home Users home directory.
+ @param name_prog Application name.
+ @param name_group Application group name.
+ @param passno Number of current pass.
+ @param co3 Flag: Compatible mode to DK tools 3.
+ @param compressed Flag: Allow gzip and bzip2 compressed files
+ too, if the library was build with gzip
+ and/or bzip2 support.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or shortname is NULL or szdptr is 0 or passno is an invalid
+ number or one of the used strings (dir_share, dir_etc, dir_home,
+ name_prog, or name_group) is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the dptr buffer is too small,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow happened during a size calculation,
+ - DK4_E_NOT_FOUND<br>
+ if no file was found,
+ - DK4_E_NOT_SUPPORTED<br>
+ if wchar_t are used as dkChar on non-Windows systems.
+*/
+int
+dk4fs_config_compat_one(
+ dkChar *dptr,
+ size_t szdptr,
+ const dkChar *shortname,
+ const dkChar *dir_share,
+ const dkChar *dir_etc,
+ const dkChar *dir_home,
+ const dkChar *name_prog,
+ const dkChar *name_group,
+ int passno,
+ int co3,
+ int compressed,
+ dk4_er_t *erp
+);
+
+/** Check one path candidate for configuration file name
+ (construct name and check presence of file).
+
+ To search for a file matching your needs run this function
+ multiple times with differenct passno values.
+ - To search for one file best matching:
+ - Start with pass number DK4_FS_CONF_MAX or DK4_FS_CONF_SYS_MAX
+ and decrease the number down to DK4_FS_CONF_SHARE_LIB,
+ use the first file found.
+ - Start with pass number DK4_FS_CONF_MAX to allow both user
+ and system configuration files.
+ - Start with pass number DK4_FS_CONF_SYS_MAX to process system
+ configuration files only.
+ - To process multiple files, each file may overwrite settings
+ made by previous files:
+ - Start with pass number DK4_FS_CONF_SHARE_LIB (0) and increase
+ the pass number up to DK4_FS_CONF_SYS_MAX or DK4_FS_CONF_MAX.
+ - Stopping after DK4_FS_CONF_SYS_MAX will process system
+ configuration files only, stopping after DK4_FS_CONF_MAX
+ processes both system and user configuration files.
+
+ CRT on Windows: Optional.
+ @param dptr Buffer for result file name.
+ @param szdptr Size of buffer (number of dkChar).
+ @param shortname Short configuration file name.
+ @param dir_share The data directory.
+ @param dir_etc The system configuration directory.
+ @param dir_home Users home directory.
+ @param name_prog Application name.
+ @param name_group Application group name.
+ @param passno Number of current pass.
+ @param compressed Flag: Allow gzip and bzip2 compressed files
+ too, if the library was build with gzip
+ and/or bzip2 support.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or shortname is NULL or szdptr is 0 or passno is an invalid
+ number or one of the used strings (dir_share, dir_etc, dir_home,
+ name_prog, or name_group) is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the dptr buffer is too small,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow happened during a size calculation,
+ - DK4_E_NOT_FOUND<br>
+ if no file was found,
+ - DK4_E_NOT_SUPPORTED<br>
+ if wchar_t are used as dkChar on non-Windows systems.
+*/
+int
+dk4fs_config_one(
+ dkChar *dptr,
+ size_t szdptr,
+ const dkChar *shortname,
+ const dkChar *dir_share,
+ const dkChar *dir_etc,
+ const dkChar *dir_home,
+ const dkChar *name_prog,
+ const dkChar *name_group,
+ int passno,
+ int compressed,
+ dk4_er_t *erp
+);
+
+/** Attempt to construct one path name for a data file.
+ CRT on Windows: Optional.
+ @param dptr Buffer for result file name.
+ @param szdptr Size of buffer (number of dkChar).
+ @param shortname Short configuration file name.
+ @param dir_share The data directory.
+ @param language Users language.
+ @param region Users region.
+ @param dir_home Users home directory.
+ @param name_prog Application name.
+ @param name_group Application group name.
+ @param passno Number of current pass.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or shortname is NULL or szdptr is 0 or passno is an invalid
+ number or one of the used strings (dir_share, dir_home, language,
+ region, name_prog, or name_group) is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the dptr buffer is too small,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow happened during a size calculation.
+*/
+int
+dk4fs_data_construct_one(
+ dkChar *dptr,
+ size_t szdptr,
+ const dkChar *shortname,
+ const dkChar *dir_share,
+ const dkChar *language,
+ const dkChar *region,
+ const dkChar *dir_home,
+ const dkChar *name_prog,
+ const dkChar *name_group,
+ int passno,
+ dk4_er_t *erp
+);
+
+/** Check one path candidate for data file name
+ (construct file name and check presence).
+
+ To search for a file, use this function multiple times with different
+ passno values:
+ - Start with DK4_F_DATA_MAX, DK4_FS_DATA_CURRENT_DIR,
+ DK4_FS_DATA_HOME_APP or DK4_FS_DATA_MAX_SYS.
+ - Decrease the pass number down to DK4_FS_DATA_SHARE_LIB.
+ - Use the first file found.
+
+ CRT on Windows: Optional.
+ @param dptr Buffer for result file name.
+ @param szdptr Size of buffer (number of dkChar).
+ @param shortname Short configuration file name.
+ @param dir_share The data directory.
+ @param dir_home Users home directory.
+ @param name_prog Application name.
+ @param name_group Application group name.
+ @param language Users preferred language.
+ @param region Users region (country code).
+ @param passno Number of current pass.
+ @param compressed Flag: Allow compressed files too.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or shortname is NULL or szdptr is 0 or passno is an invalid
+ number or one of the used strings (dir_share, dir_home, language,
+ region, name_prog, or name_group) is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the dptr buffer is too small,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow happened during a size calculation,
+ - DK4_E_NOT_FOUND<br>
+ if no file was found,
+ - DK4_E_NOT_SUPPORTED<br>
+ if wchar_t are used as dkChar on non-Windows systems.
+*/
+int
+dk4fs_data_one(
+ dkChar *dptr,
+ size_t szdptr,
+ const dkChar *shortname,
+ const dkChar *dir_share,
+ const dkChar *dir_home,
+ const dkChar *name_prog,
+ const dkChar *name_group,
+ const dkChar *language,
+ const dkChar *region,
+ int passno,
+ int compressed,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4fs.h"
+
+#if 0
+
+#ifndef DK4STAT_H_INCLUDED
+#include "dk4stat.h"
+#endif
+
+#ifndef DK4STATD_H_INCLUDED
+#include "dk4statd.h"
+#endif
+
+#endif
+
+#ifndef DK4FILED_H_INCLUDED
+#include "dk4filed.h"
+#endif
+
+#ifndef DK4STRD_H_INCLUDED
+#include "dk4strd.h"
+#endif
+
+
+
+
+$!trace-include
+
+
+
+/** Constant strings used by this module.
+*/
+static const dkChar * const dk4fs_kw[] = {
+$!string-table macro=dkT
+#
+# 0 ... 1 Directory names
+#
+dk4app
+.dk4app
+#
+# 2 Directory name appendix for site-specific directories
+#
+-site
+#
+# 3 ... 4 Compression suffixes
+#
+.gz
+.bz2
+#
+# 5 Language: No language
+#
+no-language
+#
+# 6 ... 7 Directory names for compatibility mode.
+#
+dk3app
+.dk3app
+$!end
+};
+
+
+
+#if DK4_HAVE_BACKSLASH_AS_SEP
+/** Path name separator.
+*/
+static const dkChar dk4fs_sep[] = { dkT("\\") };
+#else
+/** Path name separator.
+*/
+static const dkChar dk4fs_sep[] = { dkT("/") };
+#endif
+
+
+
+#if 0
+/** Check presence of regular file.
+ CRT on Windows: Optional.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success (file exists and is a regular file), 0 otherwise.
+*/
+static
+int
+dk4fs_check_regular_file(
+ const dkChar *fn,
+ dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS && (DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT)
+#if DK4_CHAR_SIZE > 1
+ WIN32_FIND_DATAW ffdata;
+#els
+ WIN32_FIND_DATAA ffdata;
+#endif
+ HANDLE ha;
+ DWORD dwattr;
+ int back = 0;
+#if DK4_CHAR_SIZE > 1
+ dwattr = GetFileAttributesW(fn);
+#else
+ dwattr = GetFileAttributesA(fn);
+#endif
+ if (INVALID_FILE_ATTRIBUTES == dwattr) {
+#if DK4_CHAR_SIZE > 1
+ ha = FindFirstFileW(fn, &ffdata);
+#else
+ ha = FindFirstFileA(fn, &ffdata);
+#endif
+ if (INVALID_HANDLE_VALUE != ha) {
+ dwattr = ffdata.dwFileAttributes;
+ FindClose(ha);
+ }
+ }
+ if (INVALID_FILE_ATTRIBUTES != dwattr) {
+ if ((DWORD)0UL == (FILE_ATTRIBUTE_DIRECTORY & dwattr)) {
+ if ((DWORD)0UL == (FILE_ATTRIBUTE_DEVICE & dwattr)) {
+ back = 1;
+ }
+ }
+ }
+ return back;
+#else
+ dk4_stat_t stb;
+ int back = 0;
+ if (0 != dk4stat(&stb, fn, erp)) {
+ if (0 != dk4stat_is_regular(&stb, erp)) {
+ back = 1;
+ }
+ }
+ return back;
+#endif
+}
+#endif
+
+
+
+int
+dk4fs_attempt_file_name(
+ dkChar *dptr,
+ size_t szdptr,
+ int compressed,
+ dk4_er_t *erp
+)
+{
+ dkChar *eptr; /* End of name */
+ int back = 0;
+ $? "+ dk4fs_attempt_file_name"
+ if ((NULL != dptr) && (0 < szdptr)) {
+#if DK4_ON_WINDOWS && DK4_WIN_DENY_CRT
+ /* Compression/decompression libraries depend on CRT.
+ */
+ compressed = 0;
+#endif
+ $? ". checking \"%!ds\"", dptr
+ back = dk4file_is_regular(dptr, erp);
+ $? ". result %d", back
+ if ((0 == back) && (0 != compressed)) {
+ eptr = dptr;
+ while (dkT('\0') != *eptr) { eptr++; }
+#if DK4_HAVE_ZLIB_H
+ if (0 != dk4str_cat_s(dptr, szdptr, dk4fs_kw[3], erp)) {
+ $? ". checking \"%!ds\"", dptr
+ back = dk4file_is_regular(dptr, erp);
+ $? ". result %d", back
+ }
+#endif
+#if DK4_HAVE_BZLIB_H
+ if (0 == back) {
+ *eptr = dkT('\0');
+ if (0 != dk4str_cat_s(dptr, szdptr, dk4fs_kw[4], erp)) {
+ $? ". checking \"%!ds\"", dptr
+ back = dk4file_is_regular(dptr, erp);
+ $? ". result %d", back
+ }
+ if (0 == back) {
+ *eptr = dkT('\0');
+ }
+ }
+#endif
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4fs_attempt_file_name %d", back
+ return back;
+}
+
+
+
+int
+dk4fs_construct_from_parts(
+ dkChar *dptr,
+ size_t szdptr,
+ const dkChar **comp,
+ size_t ncomp,
+ int site,
+ dk4_er_t *erp
+)
+{
+ size_t i; /* Traverse comp */
+ int back = 0; /* Function result */
+ $? "+ dk4fs_construct_from_parts"
+ if ((NULL != dptr) && (0 < szdptr) && (NULL != comp) && (0 < ncomp)) {
+ for (i = 0; i < ncomp; i++) {
+ if (0 == i) {
+ if (0 == dk4str_cpy_s(dptr, szdptr, comp[0], erp)) {
+ goto finished;
+ }
+ } else {
+ if (0 != dk4str_cat_s(dptr, szdptr, dk4fs_sep, erp)) {
+ if (0 != dk4str_cat_s(dptr, szdptr, comp[i], erp)) {
+ if ((1 == i) && (0 != site)) {
+ if (0 == dk4str_cat_s(dptr, szdptr, dk4fs_kw[2], erp)) {
+ goto finished;
+ }
+ }
+ } else {
+ goto finished;
+ }
+ } else {
+ goto finished;
+ }
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ back = 1;
+ finished:
+ if (0 == back) { *dptr = dkT('\0'); }
+ $? "- dk4fs_construct_from_parts %d", back
+ return back;
+}
+
+
+
+int
+dk4fs_config_construct_compat_one(
+ dkChar *dptr,
+ size_t szdptr,
+ const dkChar *shortname,
+ const dkChar *dir_share,
+ const dkChar *dir_etc,
+ const dkChar *dir_home,
+ const dkChar *name_prog,
+ const dkChar *name_group,
+ int passno,
+ int co3,
+ dk4_er_t *erp
+)
+{
+ const dkChar *ptrs[8];
+ int back = 0;
+ $? "+ dk4fs_config_construct_compact_one"
+ if ((NULL != dptr) && (0 < szdptr) && (NULL != shortname)) {
+ switch (passno) {
+ case DK4_FS_CONF_SHARE_LIB: {
+ if (NULL != dir_share) {
+ ptrs[0] = dir_share;
+ ptrs[1] = dk4fs_kw[(co3) ? (6) : (0)];
+ ptrs[2] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,3,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_CONF_ETC_LIB: {
+ if (NULL != dir_etc) {
+ ptrs[0] = dir_etc;
+ ptrs[1] = dk4fs_kw[(co3) ? (6) : (0)];
+ ptrs[2] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,3,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_CONF_SHARE_LIB_SITE: {
+ if (NULL != dir_share) {
+ ptrs[0] = dir_share;
+ ptrs[1] = dk4fs_kw[(co3) ? (6) : (0)];
+ ptrs[2] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,3,1,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_CONF_ETC_LIB_SITE: {
+ if (NULL != dir_etc) {
+ ptrs[0] = dir_etc;
+ ptrs[1] = dk4fs_kw[(co3) ? (6) : (0)];
+ ptrs[2] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,3,1,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_CONF_SHARE_GROUP: {
+ if ((NULL != dir_share) && (NULL != name_group)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = name_group;
+ ptrs[2] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,3,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_CONF_ETC_GROUP: {
+ if ((NULL != dir_etc) && (NULL != name_group)) {
+ ptrs[0] = dir_etc;
+ ptrs[1] = name_group;
+ ptrs[2] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,3,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_CONF_SHARE_GROUP_SITE: {
+ if ((NULL != dir_share) && (NULL != name_group)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = name_group;
+ ptrs[2] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,3,1,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_CONF_ETC_GROUP_SITE: {
+ if ((NULL != dir_etc) && (NULL != name_group)) {
+ ptrs[0] = dir_etc;
+ ptrs[1] = name_group;
+ ptrs[2] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,3,1,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_CONF_SHARE_APP: {
+ if ((NULL != dir_share) && (NULL != name_prog)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = name_prog;
+ ptrs[2] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,3,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_CONF_ETC_APP: {
+ if ((NULL != dir_etc) && (NULL != name_prog)) {
+ ptrs[0] = dir_etc;
+ ptrs[1] = name_prog;
+ ptrs[2] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,3,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_CONF_SHARE_APP_SITE: {
+ if ((NULL != dir_share) && (NULL != name_prog)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = name_prog;
+ ptrs[2] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,3,1,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_CONF_ETC_APP_SITE: {
+ if ((NULL != dir_etc) && (NULL != name_prog)) {
+ ptrs[0] = dir_etc;
+ ptrs[1] = name_prog;
+ ptrs[2] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,3,1,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_CONF_HOME_LIB: {
+ if (NULL != dir_home) {
+ ptrs[0] = dir_home;
+ ptrs[1] = dk4fs_kw[(co3) ? (7) : (1)];
+ ptrs[2] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,3,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_CONF_HOME_GROUP: {
+ if ((NULL != dir_home) && (NULL != name_group)) {
+ ptrs[0] = dir_home;
+ ptrs[1] = dk4fs_kw[(co3) ? (7) : (1)];
+ ptrs[2] = name_group;
+ ptrs[3] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,4,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_CONF_HOME_APP: {
+ if ((NULL != dir_home) && (NULL != name_prog)) {
+ ptrs[0] = dir_home;
+ ptrs[1] = dk4fs_kw[(co3) ? (7) : (1)];
+ ptrs[2] = name_prog;
+ ptrs[3] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,4,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_CONF_CURRENT_DIR: {
+ ptrs[0] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,1,0,erp);
+ } break;
+ default: {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4fs_config_construct_compact_one %d", back
+ return back;
+}
+
+
+
+int
+dk4fs_config_construct_one(
+ dkChar *dptr,
+ size_t szdptr,
+ const dkChar *shortname,
+ const dkChar *dir_share,
+ const dkChar *dir_etc,
+ const dkChar *dir_home,
+ const dkChar *name_prog,
+ const dkChar *name_group,
+ int passno,
+ dk4_er_t *erp
+)
+{
+ return(
+ dk4fs_config_construct_compat_one(
+ dptr, szdptr, shortname, dir_share, dir_etc, dir_home,
+ name_prog, name_group, passno, 0, erp
+ )
+ );
+}
+
+
+
+int
+dk4fs_config_compat_one(
+ dkChar *dptr,
+ size_t szdptr,
+ const dkChar *shortname,
+ const dkChar *dir_share,
+ const dkChar *dir_etc,
+ const dkChar *dir_home,
+ const dkChar *name_prog,
+ const dkChar *name_group,
+ int passno,
+ int co3,
+ int compressed,
+ dk4_er_t *erp
+)
+{
+ int back;
+ $? "+ dk4fs_config_compat_one \"%!ds\" %d", shortname, passno
+ back = dk4fs_config_construct_compat_one(
+ dptr, szdptr, shortname,
+ dir_share, dir_etc, dir_home,
+ name_prog, name_group, passno, co3, erp
+ );
+ if (0 != back) {
+ $? ". file name = \"%!ds\"", TR_DKSTR(dptr)
+ back = dk4fs_attempt_file_name(dptr, szdptr, compressed, erp);
+ if (0 != back) { $? ". file found = \"%!ds\"", TR_DKSTR(dptr)
+ }
+ } $? "- dk4fs_config_compat_one %d", back
+ return back;
+}
+
+
+
+int
+dk4fs_config_one(
+ dkChar *dptr,
+ size_t szdptr,
+ const dkChar *shortname,
+ const dkChar *dir_share,
+ const dkChar *dir_etc,
+ const dkChar *dir_home,
+ const dkChar *name_prog,
+ const dkChar *name_group,
+ int passno,
+ int compressed,
+ dk4_er_t *erp
+)
+{
+ return (
+ dk4fs_config_compat_one(
+ dptr, szdptr, shortname,
+ dir_share, dir_etc, dir_home, name_prog, name_group,
+ passno, 0, compressed, erp
+ )
+ );
+}
+
+
+
+int
+dk4fs_data_construct_one(
+ dkChar *dptr,
+ size_t szdptr,
+ const dkChar *shortname,
+ const dkChar *dir_share,
+ const dkChar *language,
+ const dkChar *region,
+ const dkChar *dir_home,
+ const dkChar *name_prog,
+ const dkChar *name_group,
+ int passno,
+ dk4_er_t *erp
+)
+{
+ const dkChar *ptrs[8];
+ int back = 0;
+ $? "+ dk4fs_data_construct_one"
+ $? ". short name = \"%!ds\"", TR_DKSTR(shortname)
+ $? ". /.../share = \"%!ds\"", TR_DKSTR(dir_share)
+ $? ". language = \"%!ds\"", TR_DKSTR(language)
+ $? ". region = \"%!ds\"", TR_DKSTR(region)
+ $? ". HOME = \"%!ds\"", TR_DKSTR(dir_home)
+ $? ". prog name = \"%!ds\"", TR_DKSTR(name_prog)
+ $? ". prog group = \"%!ds\"", TR_DKSTR(name_group)
+ $? ". pass no = %d", passno
+ if ((NULL != dptr) && (0 < szdptr) && (NULL != shortname)) {
+ switch (passno) {
+
+ case DK4_FS_DATA_SHARE_LIB: {
+ back = dk4fs_config_construct_one(
+ dptr, szdptr, shortname,
+ dir_share, NULL, dir_home,
+ name_prog, name_group, DK4_FS_CONF_SHARE_LIB, erp
+ );
+ } break;
+ case DK4_FS_DATA_SHARE_LIB_SITE: {
+ back = dk4fs_config_construct_one(
+ dptr, szdptr, shortname,
+ dir_share, NULL, dir_home,
+ name_prog, name_group, DK4_FS_CONF_SHARE_LIB_SITE, erp
+ );
+ } break;
+ case DK4_FS_DATA_SHARE_GROUP: {
+ back = dk4fs_config_construct_one(
+ dptr, szdptr, shortname,
+ dir_share, NULL, dir_home,
+ name_prog, name_group, DK4_FS_CONF_SHARE_GROUP, erp
+ );
+ } break;
+ case DK4_FS_DATA_SHARE_GROUP_SITE: {
+ back = dk4fs_config_construct_one(
+ dptr, szdptr, shortname,
+ dir_share, NULL, dir_home,
+ name_prog, name_group, DK4_FS_CONF_SHARE_GROUP_SITE, erp
+ );
+ } break;
+ case DK4_FS_DATA_SHARE_APP: {
+ back = dk4fs_config_construct_one(
+ dptr, szdptr, shortname,
+ dir_share, NULL, dir_home,
+ name_prog, name_group, DK4_FS_CONF_SHARE_APP, erp
+ );
+ } break;
+ case DK4_FS_DATA_SHARE_APP_SITE: {
+ back = dk4fs_config_construct_one(
+ dptr, szdptr, shortname,
+ dir_share, NULL, dir_home,
+ name_prog, name_group, DK4_FS_CONF_SHARE_APP_SITE, erp
+ );
+ } break;
+ case DK4_FS_DATA_SHARE_LIB_LANG: {
+ if ((NULL != dir_share) && (NULL != language)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = dk4fs_kw[0];
+ ptrs[2] = language;
+ ptrs[3] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,4,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_SHARE_LIB_SITE_LANG: {
+ if ((NULL != dir_share) && (NULL != language)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = dk4fs_kw[0];
+ ptrs[2] = language;
+ ptrs[3] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,4,1,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_SHARE_GROUP_LANG: {
+ if ((NULL != dir_share) && (NULL != language) && (NULL != name_group)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = name_group;
+ ptrs[2] = language;
+ ptrs[3] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,4,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_SHARE_GROUP_SITE_LANG: {
+ if ((NULL != dir_share) && (NULL != language) && (NULL != name_group)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = name_group;
+ ptrs[2] = language;
+ ptrs[3] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,4,1,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_SHARE_APP_LANG: {
+ if ((NULL != dir_share) && (NULL != language) && (NULL != name_prog)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = name_prog;
+ ptrs[2] = language;
+ ptrs[3] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,4,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_SHARE_APP_SITE_LANG: {
+ if ((NULL != dir_share) && (NULL != language) && (NULL != name_prog)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = name_prog;
+ ptrs[2] = language;
+ ptrs[3] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,4,1,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_SHARE_LIB_REG: {
+ if ((NULL != dir_share) && (NULL != region)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = dk4fs_kw[0];
+ ptrs[2] = dk4fs_kw[5];
+ ptrs[3] = region;
+ ptrs[4] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,5,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_SHARE_LIB_SITE_REG: {
+ if ((NULL != dir_share) && (NULL != region)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = dk4fs_kw[0];
+ ptrs[2] = dk4fs_kw[5];
+ ptrs[3] = region;
+ ptrs[4] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,5,1,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_SHARE_GROUP_REG: {
+ if ((NULL != dir_share) && (NULL != name_group) && (NULL != region)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = name_group;
+ ptrs[2] = dk4fs_kw[5];
+ ptrs[3] = region;
+ ptrs[4] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,5,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_SHARE_GROUP_SITE_REG: {
+ if ((NULL != dir_share) && (NULL != name_group) && (NULL != region)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = name_group;
+ ptrs[2] = dk4fs_kw[5];
+ ptrs[3] = region;
+ ptrs[4] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,5,1,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_SHARE_APP_REG: {
+ if ((NULL != dir_share) && (NULL != name_prog) && (NULL != region)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = name_prog;
+ ptrs[2] = dk4fs_kw[5];
+ ptrs[3] = region;
+ ptrs[4] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,5,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_SHARE_APP_SITE_REG: {
+ if ((NULL != dir_share) && (NULL != name_prog) && (NULL != region)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = name_prog;
+ ptrs[2] = dk4fs_kw[5];
+ ptrs[3] = region;
+ ptrs[4] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,5,1,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_SHARE_LIB_LANG_REG: {
+ if ((NULL != dir_share) && (NULL != language) && (NULL != region)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = dk4fs_kw[0];
+ ptrs[2] = language;
+ ptrs[3] = region;
+ ptrs[4] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,5,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_SHARE_LIB_SITE_LANG_REG: {
+ if ((NULL != dir_share) && (NULL != language) && (NULL != region)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = dk4fs_kw[0];
+ ptrs[2] = language;
+ ptrs[3] = region;
+ ptrs[4] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,5,1,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_SHARE_GROUP_LANG_REG: {
+ if ((NULL != dir_share) && (NULL != language)) {
+ if ((NULL != region) && (NULL != name_group)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = name_group;
+ ptrs[2] = language;
+ ptrs[3] = region;
+ ptrs[4] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,5,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_SHARE_GROUP_SITE_LANG_REG: {
+ if ((NULL != dir_share) && (NULL != language)) {
+ if ((NULL != region) && (NULL != name_group)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = name_group;
+ ptrs[2] = language;
+ ptrs[3] = region;
+ ptrs[4] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,5,1,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_SHARE_APP_LANG_REG: {
+ if ((NULL != dir_share) && (NULL != language)) {
+ if ((NULL != region) && (NULL != name_prog)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = name_prog;
+ ptrs[2] = language;
+ ptrs[3] = region;
+ ptrs[4] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,5,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_SHARE_APP_SITE_LANG_REG: {
+ if ((NULL != dir_share) && (NULL != language)) {
+ if ((NULL != region) && (NULL != name_prog)) {
+ ptrs[0] = dir_share;
+ ptrs[1] = name_prog;
+ ptrs[2] = language;
+ ptrs[3] = region;
+ ptrs[4] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,5,1,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_HOME_LIB: {
+ if (NULL != dir_home) {
+ ptrs[0] = dir_home;
+ ptrs[1] = dk4fs_kw[1];
+ ptrs[2] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,3,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_HOME_GROUP: {
+ if ((NULL != dir_home) && (NULL != name_group)) {
+ ptrs[0] = dir_home;
+ ptrs[1] = dk4fs_kw[1];
+ ptrs[2] = name_group;
+ ptrs[3] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,4,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_HOME_APP: {
+ if ((NULL != dir_home) && (NULL != name_prog)) {
+ ptrs[0] = dir_home;
+ ptrs[1] = dk4fs_kw[1];
+ ptrs[2] = name_prog;
+ ptrs[3] = shortname;
+ back = dk4fs_construct_from_parts(dptr,szdptr,ptrs,4,0,erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } break;
+ case DK4_FS_DATA_CURRENT_DIR: {
+ back = dk4str_cpy_s(dptr, szdptr, shortname, erp);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4fs_data_construct_one %d", back
+ return back;
+}
+
+
+
+int
+dk4fs_data_one(
+ dkChar *dptr,
+ size_t szdptr,
+ const dkChar *shortname,
+ const dkChar *dir_share,
+ const dkChar *dir_home,
+ const dkChar *name_prog,
+ const dkChar *name_group,
+ const dkChar *language,
+ const dkChar *region,
+ int passno,
+ int compressed,
+ dk4_er_t *erp
+)
+{
+ int back;
+ $? "+ dk4fs_data_one %!ds %d", shortname, passno
+ back = dk4fs_data_construct_one(
+ dptr, szdptr, shortname,
+ dir_share, language, region, dir_home,
+ name_prog, name_group, passno, erp
+ );
+ if (0 != back) { $? ". test \"%!ds\"", TR_DKSTR(dptr)
+ back = dk4fs_attempt_file_name(dptr, szdptr, compressed, erp);
+ } $? "- dk4fs_data_one %d", back
+ return back;
+}
+
diff --git a/support/dktools/dk4fs.h b/support/dktools/dk4fs.h
new file mode 100644
index 0000000000..fa8c90b136
--- /dev/null
+++ b/support/dktools/dk4fs.h
@@ -0,0 +1,526 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fs.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4FS_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4FS_H_INCLUDED 1
+
+
+#line 9 "dk4fs.ctr"
+
+/** @file
+ File search for configuration and data files.
+ Specify short file name and a number of directories:
+ - shared data directory (i.e. /usr/share) or system
+ configuration directory (i.e. /etc),
+ - users home directory,
+ - program name,
+ - program group name,
+ - language,
+ - region
+
+ Use dk4fs_config_one() or dk4fs_data_one() multiple times to
+ find the file best matching
+ program name, group name, language and region. See below.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+/** Pass numbers for configuration file search.
+
+ The group name passed as name_group is used instead of group,
+ the program name passed as name_prog is used instead of prog.
+*/
+enum {
+ DK4_FS_CONF_SHARE_LIB = 0, /**< /usr/share/dk4app */
+ DK4_FS_CONF_ETC_LIB , /**< /etc/dk4app */
+ DK4_FS_CONF_SHARE_LIB_SITE , /**< /usr/share/dk4app-site */
+ DK4_FS_CONF_ETC_LIB_SITE , /**< /etc/dk4app-site */
+ DK4_FS_CONF_SHARE_GROUP , /**< /usr/share/group */
+ DK4_FS_CONF_ETC_GROUP , /**< /etc/group */
+ DK4_FS_CONF_SHARE_GROUP_SITE , /**< /usr/share/group-site */
+ DK4_FS_CONF_ETC_GROUP_SITE , /**< /etc/group-site */
+ DK4_FS_CONF_SHARE_APP , /**< /usr/share/prog */
+ DK4_FS_CONF_ETC_APP , /**< /etc/prog */
+ DK4_FS_CONF_SHARE_APP_SITE , /**< /usr/share/prog-site */
+ DK4_FS_CONF_ETC_APP_SITE , /**< /etc/prog-site */
+ DK4_FS_CONF_HOME_LIB , /**< HOME/.dk4app */
+ DK4_FS_CONF_HOME_GROUP , /**< HOME/.dk4app/group */
+ DK4_FS_CONF_HOME_APP , /**< HOME/.dk4app/prog */
+ DK4_FS_CONF_CURRENT_DIR , /**< Current directory */
+
+ /** Maximum value.
+ */
+ DK4_FS_CONF_MAX = DK4_FS_CONF_CURRENT_DIR ,
+
+ /** Maximum value to search
+ system directories only.
+ */
+ DK4_FS_CONF_SYS_MAX = DK4_FS_CONF_ETC_APP_SITE
+};
+
+
+
+/** Pass numbers for data file search.
+
+ The group name passed as name_group is used instead of group,
+ the program name passed as name_prog is used instead of prog.
+*/
+enum {
+ DK4_FS_DATA_SHARE_LIB = 0, /**< /usr/share/dk4app */
+ DK4_FS_DATA_SHARE_LIB_SITE , /**< /usr/share/dk4app-site */
+ DK4_FS_DATA_SHARE_GROUP , /**< /usr/share/group */
+ DK4_FS_DATA_SHARE_GROUP_SITE , /**< /usr/share/group-site */
+ DK4_FS_DATA_SHARE_APP , /**< /usr/share/prog */
+ DK4_FS_DATA_SHARE_APP_SITE , /**< /usr/share/prog-site */
+ DK4_FS_DATA_SHARE_LIB_LANG , /**< /usr/share/dk4app/l */
+ DK4_FS_DATA_SHARE_LIB_SITE_LANG , /**< /usr/share/dk4app-site/l */
+ DK4_FS_DATA_SHARE_GROUP_LANG , /**< /usr/share/group/l */
+ DK4_FS_DATA_SHARE_GROUP_SITE_LANG , /**< /usr/share/group-site/l */
+ DK4_FS_DATA_SHARE_APP_LANG , /**< /usr/share/prog/l */
+ DK4_FS_DATA_SHARE_APP_SITE_LANG , /**< /usr/share/prog-site/l */
+ DK4_FS_DATA_SHARE_LIB_REG , /**< /usr/share/dk4app */
+ DK4_FS_DATA_SHARE_LIB_SITE_REG , /**< /usr/share/dk4app-site */
+ DK4_FS_DATA_SHARE_GROUP_REG , /**< /usr/share/group */
+ DK4_FS_DATA_SHARE_GROUP_SITE_REG , /**< /usr/share/group-site */
+ DK4_FS_DATA_SHARE_APP_REG , /**< /usr/share/prog/no-language/r */
+ DK4_FS_DATA_SHARE_APP_SITE_REG , /**< /usr/share/prog-site/no-language/r */
+ DK4_FS_DATA_SHARE_LIB_LANG_REG , /**< /usr/share/dk4app/l/r */
+ DK4_FS_DATA_SHARE_LIB_SITE_LANG_REG , /**< /usr/share/dk4app-site/l/r */
+ DK4_FS_DATA_SHARE_GROUP_LANG_REG , /**< /usr/share/group/l/r */
+ DK4_FS_DATA_SHARE_GROUP_SITE_LANG_REG , /**< /usr/share/group-site/l/r */
+ DK4_FS_DATA_SHARE_APP_LANG_REG , /**< /usr/share/prog/l/r */
+ DK4_FS_DATA_SHARE_APP_SITE_LANG_REG , /**< /usr/share/prog-site/l/r */
+ DK4_FS_DATA_HOME_LIB , /**< HOME/.dk4app */
+ DK4_FS_DATA_HOME_GROUP , /**< HOME/.dk4app/group */
+ DK4_FS_DATA_HOME_APP , /**< HOME/.dk4app/prog */
+ DK4_FS_DATA_CURRENT_DIR , /**< Current directory */
+
+ /** Maximum system data file.
+ */
+ DK4_FS_DATA_MAX_SYS = DK4_FS_DATA_SHARE_APP_SITE_LANG_REG,
+
+ /** Maximum data file.
+ */
+ DK4_FS_DATA_MAX = DK4_FS_DATA_CURRENT_DIR
+};
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Check presence of one file, optionally with compression suffixes.
+ CRT on Windows: Optional.
+ @param dptr Buffer containing file name.
+ @param szdptr Buffer size.
+ @param compressed Flag: Search for compressed files too.
+ @param erp Error report, may be NULL.
+ @return 1 if file or optionally compressed file found, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or szdptr is 0,
+ - DK4_E_NOT_SUPPORTED<br>
+ if wchar_t are used as dkChar on non-Windows systems,
+ - DK4_E_NOT_FOUND<br>
+ if the file was not found.
+*/
+int
+dk4fs_attempt_file_name(
+ dkChar *dptr,
+ size_t szdptr,
+ int compressed,
+ dk4_er_t *erp
+);
+
+/** Attempt to construct one file name from multiple parts.
+ CRT on Windows: Optional.
+ @param dptr Destination buffer address.
+ @param szdptr Destination buffer size (number of dkChar).
+ @param comp Components array.
+ @param ncomp Number of components.
+ @param site Flag: Add -site after second component.
+ @param erp Error report, may be NULL.
+ @return 1 on success (path constructed and file exists), 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or comp is NULL or szdptr or ncomp is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the dptr buffer is too small,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow happened during
+ a size calculation.
+*/
+int
+dk4fs_construct_from_parts(
+ dkChar *dptr,
+ size_t szdptr,
+ const dkChar **comp,
+ size_t ncomp,
+ int site,
+ dk4_er_t *erp
+);
+
+/** Attempt to construct one path name for a configuration file.
+ CRT on Windows: Optional.
+ @param dptr Buffer for result file name.
+ @param szdptr Size of buffer (number of dkChar).
+ @param shortname Short configuration file name.
+ @param dir_share The data directory.
+ @param dir_etc The system configuration directory.
+ @param dir_home Users home directory.
+ @param name_prog Application name.
+ @param name_group Application group name.
+ @param passno Number of current pass.
+ @param co3 Flag: Compatible to DK tools 3.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or shortname is NULL or szdptr is 0 or passno is an invalid
+ number or one of the used strings (dir_share, dir_etc, dir_home,
+ name_prog, or name_group) is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the dptr buffer is too small,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow happened during a size calculation.
+*/
+int
+dk4fs_config_construct_compat_one(
+ dkChar *dptr,
+ size_t szdptr,
+ const dkChar *shortname,
+ const dkChar *dir_share,
+ const dkChar *dir_etc,
+ const dkChar *dir_home,
+ const dkChar *name_prog,
+ const dkChar *name_group,
+ int passno,
+ int co3,
+ dk4_er_t *erp
+);
+
+/** Attempt to construct one path name for a configuration file.
+ CRT on Windows: Optional.
+ @param dptr Buffer for result file name.
+ @param szdptr Size of buffer (number of dkChar).
+ @param shortname Short configuration file name.
+ @param dir_share The data directory.
+ @param dir_etc The system configuration directory.
+ @param dir_home Users home directory.
+ @param name_prog Application name.
+ @param name_group Application group name.
+ @param passno Number of current pass.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or shortname is NULL or szdptr is 0 or passno is an invalid
+ number or one of the used strings (dir_share, dir_etc, dir_home,
+ name_prog, or name_group) is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the dptr buffer is too small,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow happened during a size calculation.
+*/
+int
+dk4fs_config_construct_one(
+ dkChar *dptr,
+ size_t szdptr,
+ const dkChar *shortname,
+ const dkChar *dir_share,
+ const dkChar *dir_etc,
+ const dkChar *dir_home,
+ const dkChar *name_prog,
+ const dkChar *name_group,
+ int passno,
+ dk4_er_t *erp
+);
+
+/** Check one path candidate for configuration file name
+ (construct name and check presence of file).
+
+ To search for a file matching your needs run this function
+ multiple times with differenct passno values.
+ - To search for one file best matching:
+ - Start with pass number DK4_FS_CONF_MAX or DK4_FS_CONF_SYS_MAX
+ and decrease the number down to DK4_FS_CONF_SHARE_LIB,
+ use the first file found.
+ - Start with pass number DK4_FS_CONF_MAX to allow both user
+ and system configuration files.
+ - Start with pass number DK4_FS_CONF_SYS_MAX to process system
+ configuration files only.
+ - To process multiple files, each file may overwrite settings
+ made by previous files:
+ - Start with pass number DK4_FS_CONF_SHARE_LIB (0) and increase
+ the pass number up to DK4_FS_CONF_SYS_MAX or DK4_FS_CONF_MAX.
+ - Stopping after DK4_FS_CONF_SYS_MAX will process system
+ configuration files only, stopping after DK4_FS_CONF_MAX
+ processes both system and user configuration files.
+
+ CRT on Windows: Optional.
+ @param dptr Buffer for result file name.
+ @param szdptr Size of buffer (number of dkChar).
+ @param shortname Short configuration file name.
+ @param dir_share The data directory.
+ @param dir_etc The system configuration directory.
+ @param dir_home Users home directory.
+ @param name_prog Application name.
+ @param name_group Application group name.
+ @param passno Number of current pass.
+ @param co3 Flag: Compatible mode to DK tools 3.
+ @param compressed Flag: Allow gzip and bzip2 compressed files
+ too, if the library was build with gzip
+ and/or bzip2 support.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or shortname is NULL or szdptr is 0 or passno is an invalid
+ number or one of the used strings (dir_share, dir_etc, dir_home,
+ name_prog, or name_group) is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the dptr buffer is too small,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow happened during a size calculation,
+ - DK4_E_NOT_FOUND<br>
+ if no file was found,
+ - DK4_E_NOT_SUPPORTED<br>
+ if wchar_t are used as dkChar on non-Windows systems.
+*/
+int
+dk4fs_config_compat_one(
+ dkChar *dptr,
+ size_t szdptr,
+ const dkChar *shortname,
+ const dkChar *dir_share,
+ const dkChar *dir_etc,
+ const dkChar *dir_home,
+ const dkChar *name_prog,
+ const dkChar *name_group,
+ int passno,
+ int co3,
+ int compressed,
+ dk4_er_t *erp
+);
+
+/** Check one path candidate for configuration file name
+ (construct name and check presence of file).
+
+ To search for a file matching your needs run this function
+ multiple times with differenct passno values.
+ - To search for one file best matching:
+ - Start with pass number DK4_FS_CONF_MAX or DK4_FS_CONF_SYS_MAX
+ and decrease the number down to DK4_FS_CONF_SHARE_LIB,
+ use the first file found.
+ - Start with pass number DK4_FS_CONF_MAX to allow both user
+ and system configuration files.
+ - Start with pass number DK4_FS_CONF_SYS_MAX to process system
+ configuration files only.
+ - To process multiple files, each file may overwrite settings
+ made by previous files:
+ - Start with pass number DK4_FS_CONF_SHARE_LIB (0) and increase
+ the pass number up to DK4_FS_CONF_SYS_MAX or DK4_FS_CONF_MAX.
+ - Stopping after DK4_FS_CONF_SYS_MAX will process system
+ configuration files only, stopping after DK4_FS_CONF_MAX
+ processes both system and user configuration files.
+
+ CRT on Windows: Optional.
+ @param dptr Buffer for result file name.
+ @param szdptr Size of buffer (number of dkChar).
+ @param shortname Short configuration file name.
+ @param dir_share The data directory.
+ @param dir_etc The system configuration directory.
+ @param dir_home Users home directory.
+ @param name_prog Application name.
+ @param name_group Application group name.
+ @param passno Number of current pass.
+ @param compressed Flag: Allow gzip and bzip2 compressed files
+ too, if the library was build with gzip
+ and/or bzip2 support.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or shortname is NULL or szdptr is 0 or passno is an invalid
+ number or one of the used strings (dir_share, dir_etc, dir_home,
+ name_prog, or name_group) is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the dptr buffer is too small,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow happened during a size calculation,
+ - DK4_E_NOT_FOUND<br>
+ if no file was found,
+ - DK4_E_NOT_SUPPORTED<br>
+ if wchar_t are used as dkChar on non-Windows systems.
+*/
+int
+dk4fs_config_one(
+ dkChar *dptr,
+ size_t szdptr,
+ const dkChar *shortname,
+ const dkChar *dir_share,
+ const dkChar *dir_etc,
+ const dkChar *dir_home,
+ const dkChar *name_prog,
+ const dkChar *name_group,
+ int passno,
+ int compressed,
+ dk4_er_t *erp
+);
+
+/** Attempt to construct one path name for a data file.
+ CRT on Windows: Optional.
+ @param dptr Buffer for result file name.
+ @param szdptr Size of buffer (number of dkChar).
+ @param shortname Short configuration file name.
+ @param dir_share The data directory.
+ @param language Users language.
+ @param region Users region.
+ @param dir_home Users home directory.
+ @param name_prog Application name.
+ @param name_group Application group name.
+ @param passno Number of current pass.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or shortname is NULL or szdptr is 0 or passno is an invalid
+ number or one of the used strings (dir_share, dir_home, language,
+ region, name_prog, or name_group) is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the dptr buffer is too small,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow happened during a size calculation.
+*/
+int
+dk4fs_data_construct_one(
+ dkChar *dptr,
+ size_t szdptr,
+ const dkChar *shortname,
+ const dkChar *dir_share,
+ const dkChar *language,
+ const dkChar *region,
+ const dkChar *dir_home,
+ const dkChar *name_prog,
+ const dkChar *name_group,
+ int passno,
+ dk4_er_t *erp
+);
+
+/** Check one path candidate for data file name
+ (construct file name and check presence).
+
+ To search for a file, use this function multiple times with different
+ passno values:
+ - Start with DK4_F_DATA_MAX, DK4_FS_DATA_CURRENT_DIR,
+ DK4_FS_DATA_HOME_APP or DK4_FS_DATA_MAX_SYS.
+ - Decrease the pass number down to DK4_FS_DATA_SHARE_LIB.
+ - Use the first file found.
+
+ CRT on Windows: Optional.
+ @param dptr Buffer for result file name.
+ @param szdptr Size of buffer (number of dkChar).
+ @param shortname Short configuration file name.
+ @param dir_share The data directory.
+ @param dir_home Users home directory.
+ @param name_prog Application name.
+ @param name_group Application group name.
+ @param language Users preferred language.
+ @param region Users region (country code).
+ @param passno Number of current pass.
+ @param compressed Flag: Allow compressed files too.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or shortname is NULL or szdptr is 0 or passno is an invalid
+ number or one of the used strings (dir_share, dir_home, language,
+ region, name_prog, or name_group) is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the dptr buffer is too small,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow happened during a size calculation,
+ - DK4_E_NOT_FOUND<br>
+ if no file was found,
+ - DK4_E_NOT_SUPPORTED<br>
+ if wchar_t are used as dkChar on non-Windows systems.
+*/
+int
+dk4fs_data_one(
+ dkChar *dptr,
+ size_t szdptr,
+ const dkChar *shortname,
+ const dkChar *dir_share,
+ const dkChar *dir_home,
+ const dkChar *name_prog,
+ const dkChar *name_group,
+ const dkChar *language,
+ const dkChar *region,
+ int passno,
+ int compressed,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4ft.h b/support/dktools/dk4ft.h
new file mode 100644
index 0000000000..3968c7de38
--- /dev/null
+++ b/support/dktools/dk4ft.h
@@ -0,0 +1,99 @@
+
+#ifndef DK4FT_H_INCLUDED
+#define DK4FT_H_INCLUDED 1
+
+/** @file dk4ft.h File type constants.
+*/
+
+/** File types.
+*/
+enum {
+
+ /** File type not found.
+ */
+ DK4_FT_UNKNOWN = 0,
+
+ /** Regular file.
+ */
+ DK4_FT_REGULAR,
+
+ /** Directory.
+ */
+ DK4_FT_DIRECTORY,
+
+ /** Character device (special file).
+ */
+ DK4_FT_SPECIAL_CHAR,
+
+ /** Pipe (first in, first out).
+ */
+ DK4_FT_FIFO,
+
+ /** Block device (special file).
+ */
+ DK4_FT_SPECIAL_BLOCK,
+
+ /** Socket.
+ */
+ DK4_FT_SOCKET,
+
+ /** Symlink (near symblink, referenced inode on same file system).
+ */
+ DK4_FT_SYMLINK,
+
+ /** Far symlink (referenced inode on another file system).
+ */
+ DK4_FT_FAR_SYMLINK,
+
+ /** Bad symblink (referenced inode not found).
+ */
+ DK4_FT_BAD_SYMLINK,
+
+ /** Door.
+ */
+ DK4_FT_DOOR,
+
+ /** Event port.
+ */
+ DK4_FT_EVENT_PORT,
+
+ /** Xenix special file.
+ */
+ DK4_FT_XENIX_SPECIAL,
+
+ /** Xenix semaphore.
+ */
+ DK4_FT_XENIX_SEMAPHORE,
+
+ /** Xenix shared data.
+ */
+ DK4_FT_XENIX_SHARED_DATA,
+
+ /** Multiplexed character device.
+ */
+ DK4_FT_MULTIPLEXED_CHAR,
+
+ /** Multiplexed block device.
+ */
+ DK4_FT_MULTIPLEXED_BLOCK,
+
+ /** VxFS compressed file.
+ */
+ DK4_FT_VXFS_COMPRESSED,
+
+ /** Network special file.
+ */
+ DK4_FT_NETWORK_SPECIAL,
+
+ /** Whiteout (not used for inode).
+ */
+ DK4_FT_WHITEOUT,
+
+ /** ACL shadow inode.
+ */
+ DK4_FT_ACL_SHADOW
+
+};
+
+#endif
+
diff --git a/support/dktools/dk4ftime.c b/support/dktools/dk4ftime.c
new file mode 100644
index 0000000000..a2fc9bef38
--- /dev/null
+++ b/support/dktools/dk4ftime.c
@@ -0,0 +1,89 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4ftime.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4ftime.c The dk4ftime module.
+*/
+
+
+#line 187 "dk4ftime.ctr"
+
+#include "dk4ftime.h"
+
+#if !DK4_ON_WINDOWS
+#include "dk4timedk.h"
+#endif
+
+int
+dk4filetime_compare(const dk4_file_time_t *l, const dk4_file_time_t *r)
+{
+ int back = 0;
+ if (NULL != l) {
+ if (NULL != r) {
+#if DK4_ON_WINDOWS
+ if (l->dwHighDateTime > r->dwHighDateTime) {
+ back = 1;
+ } else {
+ if (l->dwHighDateTime < r->dwHighDateTime) {
+ back = -1;
+ } else {
+ if (l->dwLowDateTime > r->dwLowDateTime) {
+ back = 1;
+ } else {
+ if (l->dwLowDateTime < r->dwLowDateTime) {
+ back = -1;
+ }
+ }
+ }
+ }
+#else
+ if (*l > *r) {
+ back = 1;
+ } else {
+ if (*l < *r) {
+ back = -1;
+ }
+ }
+#endif
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != r) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4ftime.ctr b/support/dktools/dk4ftime.ctr
new file mode 100644
index 0000000000..949011fe93
--- /dev/null
+++ b/support/dktools/dk4ftime.ctr
@@ -0,0 +1,235 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ File related timestamps (timestamp comparison, converstion to text.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4TIMEC_H_INCLUDED
+#include "dk4timec.h"
+#endif
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+#if DK4_TIME_WITH_SYS_TIME
+#ifndef SYS_TIME_H_INCLUDED
+#include <sys/time.h>
+#define SYS_TIME_H_INCLUDED 1
+#endif
+#ifndef TIME_H_INCLUDED
+#include <time.h>
+#define TIME_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_TIME_H
+#ifndef TIME_H_INCLUDED
+#include <time.h>
+#define TIME_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_SYS_TIME_H
+#ifndef SYS_TIME_H_INCLUDED
+#include <sys/time.h>
+#define SYS_TIME_H_INCLUDED 1
+#endif
+#endif
+#endif
+#endif
+#ifndef DK4TIME_H_INCLUDED
+#include "dk4time.h"
+#endif
+#endif
+
+
+
+#if DK4_ON_WINDOWS
+/** File related timestamp.
+*/
+typedef FILETIME dk4_file_time_t;
+#else
+/** File related timestamp.
+*/
+typedef dk4_time_t dk4_file_time_t;
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Compare two timestamps.
+ CRT on Windows: Not used.
+ @param l Left timestamp.
+ @param r Right timestamp.
+ @return 1 if l>r, 0 if l=r, -1 if l<r.
+*/
+int
+dk4filetime_compare(const dk4_file_time_t *l, const dk4_file_time_t *r);
+
+/** Convert timestamp to text ``yyyy-mm-dd hh:mm:ss''.
+ CRT on Windows: Optional.
+ @param dptr Result buffer address.
+ @param dsz Result buffer size (number of dkChar).
+ @param fit Timestamp to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or fit is NULL or dsz is 0,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occures in a size calculation,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the buffer is too small,
+ - DK4_E_BUG<br>
+ if CRT or Windows API functions failed to convert the timestamp to
+ local time information.
+*/
+int
+dk4filetime_to_text_c8(
+ char *dptr,
+ size_t dsz,
+ const dk4_file_time_t *fit,
+ dk4_er_t *erp
+);
+
+/** Convert timestamp to text ``yyyy-mm-dd hh:mm:ss''.
+ CRT on Windows: Optional.
+ @param dptr Result buffer address.
+ @param dsz Result buffer size (number of dkChar).
+ @param fit Timestamp to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or fit is NULL or dsz is 0,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occures in a size calculation,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the buffer is too small,
+ - DK4_E_BUG<br>
+ if CRT or Windows API functions failed to convert the timestamp to
+ local time information.
+*/
+int
+dk4filetime_to_text_wc(
+ wchar_t *dptr,
+ size_t dsz,
+ const dk4_file_time_t *fit,
+ dk4_er_t *erp
+);
+
+/** Convert timestamp to text ``yyyy-mm-dd hh:mm:ss''.
+ CRT on Windows: Optional.
+ @param dptr Result buffer address.
+ @param dsz Result buffer size (number of dkChar).
+ @param fit Timestamp to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or fit is NULL or dsz is 0,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occures in a size calculation,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the buffer is too small,
+ - DK4_E_BUG<br>
+ if CRT or Windows API functions failed to convert the timestamp to
+ local time information.
+*/
+int
+dk4filetime_to_text(
+ dkChar *dptr,
+ size_t dsz,
+ const dk4_file_time_t *fit,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4ftime.h"
+
+#if !DK4_ON_WINDOWS
+#include "dk4timedk.h"
+#endif
+
+int
+dk4filetime_compare(const dk4_file_time_t *l, const dk4_file_time_t *r)
+{
+ int back = 0;
+ if (NULL != l) {
+ if (NULL != r) {
+#if DK4_ON_WINDOWS
+ if (l->dwHighDateTime > r->dwHighDateTime) {
+ back = 1;
+ } else {
+ if (l->dwHighDateTime < r->dwHighDateTime) {
+ back = -1;
+ } else {
+ if (l->dwLowDateTime > r->dwLowDateTime) {
+ back = 1;
+ } else {
+ if (l->dwLowDateTime < r->dwLowDateTime) {
+ back = -1;
+ }
+ }
+ }
+ }
+#else
+ if (*l > *r) {
+ back = 1;
+ } else {
+ if (*l < *r) {
+ back = -1;
+ }
+ }
+#endif
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != r) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4ftime.h b/support/dktools/dk4ftime.h
new file mode 100644
index 0000000000..00b12fcb97
--- /dev/null
+++ b/support/dktools/dk4ftime.h
@@ -0,0 +1,219 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4ftime.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4FTIME_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4FTIME_H_INCLUDED 1
+
+
+#line 10 "dk4ftime.ctr"
+
+/** @file
+ File related timestamps (timestamp comparison, converstion to text.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4TIMEC_H_INCLUDED
+#include "dk4timec.h"
+#endif
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+#if DK4_TIME_WITH_SYS_TIME
+#ifndef SYS_TIME_H_INCLUDED
+#include <sys/time.h>
+#define SYS_TIME_H_INCLUDED 1
+#endif
+#ifndef TIME_H_INCLUDED
+#include <time.h>
+#define TIME_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_TIME_H
+#ifndef TIME_H_INCLUDED
+#include <time.h>
+#define TIME_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_SYS_TIME_H
+#ifndef SYS_TIME_H_INCLUDED
+#include <sys/time.h>
+#define SYS_TIME_H_INCLUDED 1
+#endif
+#endif
+#endif
+#endif
+#ifndef DK4TIME_H_INCLUDED
+#include "dk4time.h"
+#endif
+#endif
+
+
+
+#if DK4_ON_WINDOWS
+/** File related timestamp.
+*/
+typedef FILETIME dk4_file_time_t;
+#else
+/** File related timestamp.
+*/
+typedef dk4_time_t dk4_file_time_t;
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Compare two timestamps.
+ CRT on Windows: Not used.
+ @param l Left timestamp.
+ @param r Right timestamp.
+ @return 1 if l>r, 0 if l=r, -1 if l<r.
+*/
+int
+dk4filetime_compare(const dk4_file_time_t *l, const dk4_file_time_t *r);
+
+/** Convert timestamp to text ``yyyy-mm-dd hh:mm:ss''.
+ CRT on Windows: Optional.
+ @param dptr Result buffer address.
+ @param dsz Result buffer size (number of dkChar).
+ @param fit Timestamp to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or fit is NULL or dsz is 0,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occures in a size calculation,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the buffer is too small,
+ - DK4_E_BUG<br>
+ if CRT or Windows API functions failed to convert the timestamp to
+ local time information.
+*/
+int
+dk4filetime_to_text_c8(
+ char *dptr,
+ size_t dsz,
+ const dk4_file_time_t *fit,
+ dk4_er_t *erp
+);
+
+/** Convert timestamp to text ``yyyy-mm-dd hh:mm:ss''.
+ CRT on Windows: Optional.
+ @param dptr Result buffer address.
+ @param dsz Result buffer size (number of dkChar).
+ @param fit Timestamp to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or fit is NULL or dsz is 0,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occures in a size calculation,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the buffer is too small,
+ - DK4_E_BUG<br>
+ if CRT or Windows API functions failed to convert the timestamp to
+ local time information.
+*/
+int
+dk4filetime_to_text_wc(
+ wchar_t *dptr,
+ size_t dsz,
+ const dk4_file_time_t *fit,
+ dk4_er_t *erp
+);
+
+/** Convert timestamp to text ``yyyy-mm-dd hh:mm:ss''.
+ CRT on Windows: Optional.
+ @param dptr Result buffer address.
+ @param dsz Result buffer size (number of dkChar).
+ @param fit Timestamp to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or fit is NULL or dsz is 0,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occures in a size calculation,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the buffer is too small,
+ - DK4_E_BUG<br>
+ if CRT or Windows API functions failed to convert the timestamp to
+ local time information.
+*/
+int
+dk4filetime_to_text(
+ dkChar *dptr,
+ size_t dsz,
+ const dk4_file_time_t *fit,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4ftime08.c b/support/dktools/dk4ftime08.c
new file mode 100644
index 0000000000..38904b53e2
--- /dev/null
+++ b/support/dktools/dk4ftime08.c
@@ -0,0 +1,87 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4ftime08.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4ftime08.c The dk4ftime08 module.
+*/
+
+
+#line 10 "dk4ftime08.ctr"
+
+#include "dk4ftime.h"
+
+#ifndef DK4TIME08_H_INCLUDED
+#include "dk4time08.h"
+#endif
+
+
+
+int
+dk4filetime_to_text_c8(
+ char *dptr,
+ size_t dsz,
+ const dk4_file_time_t *fit,
+ dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+ SYSTEMTIME st1;
+ SYSTEMTIME st2;
+ int back = 0;
+ if ((NULL != dptr) && (NULL != fit) && (0 < dsz)) {
+ if (FileTimeToSystemTime(fit, &st1)) {
+ if (SystemTimeToTzSpecificLocalTime(NULL, &st1, &st2)) {
+ back = dk4time_to_text_c8(
+ dptr, dsz, DK4_TIMEFORMAT_DATE_TIME,
+ st2.wYear, st2.wMonth, st2.wDay,
+ st2.wHour, st2.wMinute, st2.wSecond,
+ erp
+ );
+ } else {
+ /* Error: Conversion to local time failed */
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ } else {
+ /* Error: Time conversion failed */
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ return (dk4time_as_text_c8(dptr, dsz, fit, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4ftime08.ctr b/support/dktools/dk4ftime08.ctr
new file mode 100644
index 0000000000..e191a73614
--- /dev/null
+++ b/support/dktools/dk4ftime08.ctr
@@ -0,0 +1,56 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4ftime.h"
+
+#ifndef DK4TIME08_H_INCLUDED
+#include "dk4time08.h"
+#endif
+
+
+
+int
+dk4filetime_to_text_c8(
+ char *dptr,
+ size_t dsz,
+ const dk4_file_time_t *fit,
+ dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+ SYSTEMTIME st1;
+ SYSTEMTIME st2;
+ int back = 0;
+ if ((NULL != dptr) && (NULL != fit) && (0 < dsz)) {
+ if (FileTimeToSystemTime(fit, &st1)) {
+ if (SystemTimeToTzSpecificLocalTime(NULL, &st1, &st2)) {
+ back = dk4time_to_text_c8(
+ dptr, dsz, DK4_TIMEFORMAT_DATE_TIME,
+ st2.wYear, st2.wMonth, st2.wDay,
+ st2.wHour, st2.wMinute, st2.wSecond,
+ erp
+ );
+ } else {
+ /* Error: Conversion to local time failed */
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ } else {
+ /* Error: Time conversion failed */
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ return (dk4time_as_text_c8(dptr, dsz, fit, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4ftimedk.c b/support/dktools/dk4ftimedk.c
new file mode 100644
index 0000000000..1f3084f70a
--- /dev/null
+++ b/support/dktools/dk4ftimedk.c
@@ -0,0 +1,65 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4ftimedk.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4ftimedk.c The dk4ftimedk module.
+*/
+
+
+#line 10 "dk4ftimedk.ctr"
+
+#include "dk4ftime.h"
+
+#ifndef DK4TIMEWC_H_INCLUDED
+#include "dk4timewc.h"
+#endif
+
+#include "dk4ftime.h"
+
+
+int
+dk4filetime_to_text(
+ dkChar *dptr,
+ size_t dsz,
+ const dk4_file_time_t *fit,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4filetime_to_text_wc(dptr, dsz, fit, erp));
+#else
+ return (dk4filetime_to_text_c8(dptr, dsz, fit, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4ftimedk.ctr b/support/dktools/dk4ftimedk.ctr
new file mode 100644
index 0000000000..d9a82b4059
--- /dev/null
+++ b/support/dktools/dk4ftimedk.ctr
@@ -0,0 +1,34 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4ftime.h"
+
+#ifndef DK4TIMEWC_H_INCLUDED
+#include "dk4timewc.h"
+#endif
+
+#include "dk4ftime.h"
+
+
+int
+dk4filetime_to_text(
+ dkChar *dptr,
+ size_t dsz,
+ const dk4_file_time_t *fit,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4filetime_to_text_wc(dptr, dsz, fit, erp));
+#else
+ return (dk4filetime_to_text_c8(dptr, dsz, fit, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4ftimewc.c b/support/dktools/dk4ftimewc.c
new file mode 100644
index 0000000000..aa81d52e0f
--- /dev/null
+++ b/support/dktools/dk4ftimewc.c
@@ -0,0 +1,87 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4ftimewc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4ftimewc.c The dk4ftimewc module.
+*/
+
+
+#line 10 "dk4ftimewc.ctr"
+
+#include "dk4ftime.h"
+
+#ifndef DK4TIMEWC_H_INCLUDED
+#include "dk4timewc.h"
+#endif
+
+
+
+int
+dk4filetime_to_text_wc(
+ wchar_t *dptr,
+ size_t dsz,
+ const dk4_file_time_t *fit,
+ dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+ SYSTEMTIME st1;
+ SYSTEMTIME st2;
+ int back = 0;
+ if ((NULL != dptr) && (NULL != fit) && (0 < dsz)) {
+ if (FileTimeToSystemTime(fit, &st1)) {
+ if (SystemTimeToTzSpecificLocalTime(NULL, &st1, &st2)) {
+ back = dk4time_to_text_wc(
+ dptr, dsz, DK4_TIMEFORMAT_DATE_TIME,
+ st2.wYear, st2.wMonth, st2.wDay,
+ st2.wHour, st2.wMinute, st2.wSecond,
+ erp
+ );
+ } else {
+ /* Error: Conversion to local time failed */
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ } else {
+ /* Error: Time conversion failed */
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ return (dk4time_as_text_wc(dptr, dsz, fit, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4ftimewc.ctr b/support/dktools/dk4ftimewc.ctr
new file mode 100644
index 0000000000..e526aa9ea7
--- /dev/null
+++ b/support/dktools/dk4ftimewc.ctr
@@ -0,0 +1,56 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4ftime.h"
+
+#ifndef DK4TIMEWC_H_INCLUDED
+#include "dk4timewc.h"
+#endif
+
+
+
+int
+dk4filetime_to_text_wc(
+ wchar_t *dptr,
+ size_t dsz,
+ const dk4_file_time_t *fit,
+ dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+ SYSTEMTIME st1;
+ SYSTEMTIME st2;
+ int back = 0;
+ if ((NULL != dptr) && (NULL != fit) && (0 < dsz)) {
+ if (FileTimeToSystemTime(fit, &st1)) {
+ if (SystemTimeToTzSpecificLocalTime(NULL, &st1, &st2)) {
+ back = dk4time_to_text_wc(
+ dptr, dsz, DK4_TIMEFORMAT_DATE_TIME,
+ st2.wYear, st2.wMonth, st2.wDay,
+ st2.wHour, st2.wMinute, st2.wSecond,
+ erp
+ );
+ } else {
+ /* Error: Conversion to local time failed */
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ } else {
+ /* Error: Time conversion failed */
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ return (dk4time_as_text_wc(dptr, dsz, fit, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4fwra.c b/support/dktools/dk4fwra.c
new file mode 100644
index 0000000000..396985c361
--- /dev/null
+++ b/support/dktools/dk4fwra.c
@@ -0,0 +1,81 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fwra.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4fwra.c The dk4fwra module.
+*/
+
+
+#line 55 "dk4fwra.ctr"
+
+#include "dk4fwra.h"
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+
+
+int
+dk4fwrite_app(
+ const dkChar *filename,
+ const void *ptr,
+ size_t elsize,
+ size_t nelem,
+ FILE *fipo,
+ dk4_app_t *app
+)
+{
+ size_t wrb;
+ int back = 0;
+ int errc;
+ if ((NULL != ptr) && (NULL != fipo) && (0 < elsize) && (0 < nelem)) {
+ errno = 0;
+ wrb = fwrite(ptr, elsize, nelem, fipo);
+ if (wrb == nelem) {
+ back = 1;
+ } else {
+ errc = errno;
+ dk4fd_write_error_msg(app, filename, errc);
+ }
+ } else {
+
+#line 90 "dk4fwra.ctr"
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4fwra.ctr b/support/dktools/dk4fwra.ctr
new file mode 100644
index 0000000000..b5fd7b57e6
--- /dev/null
+++ b/support/dktools/dk4fwra.ctr
@@ -0,0 +1,93 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Write to file using fwrite(), report errors immediately.
+*/
+
+#ifndef STDIO_H_INCLUDED
+#include <stdio.h>
+#define STDIO_H_INCLUDED 1
+#endif
+
+#ifndef DK4APP_H_INCLUDED
+#include "dk4app.h"
+#define DK4APP_H_INCLUDED 1
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Write to file, report errors immediately.
+ @param filename File name to write to.
+ @param ptr Start address of buffer.
+ @param elsize Size of each element.
+ @param nelem Number of elements.
+ @param fipo File to write to.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success (all elements written completely), 0 on error.
+*/
+int
+dk4fwrite_app(
+ const dkChar *filename,
+ const void *ptr,
+ size_t elsize,
+ size_t nelem,
+ FILE *fipo,
+ dk4_app_t *app
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4fwra.h"
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+
+
+int
+dk4fwrite_app(
+ const dkChar *filename,
+ const void *ptr,
+ size_t elsize,
+ size_t nelem,
+ FILE *fipo,
+ dk4_app_t *app
+)
+{
+ size_t wrb;
+ int back = 0;
+ int errc;
+ if ((NULL != ptr) && (NULL != fipo) && (0 < elsize) && (0 < nelem)) {
+ errno = 0;
+ wrb = fwrite(ptr, elsize, nelem, fipo);
+ if (wrb == nelem) {
+ back = 1;
+ } else {
+ errc = errno;
+ dk4fd_write_error_msg(app, filename, errc);
+ }
+ } else { $? "! invalid arguments"
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4fwra.h b/support/dktools/dk4fwra.h
new file mode 100644
index 0000000000..d30548a696
--- /dev/null
+++ b/support/dktools/dk4fwra.h
@@ -0,0 +1,87 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4fwra.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4FWRA_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4FWRA_H_INCLUDED 1
+
+
+#line 10 "dk4fwra.ctr"
+
+/** @file
+ Write to file using fwrite(), report errors immediately.
+*/
+
+#ifndef STDIO_H_INCLUDED
+#include <stdio.h>
+#define STDIO_H_INCLUDED 1
+#endif
+
+#ifndef DK4APP_H_INCLUDED
+#include "dk4app.h"
+#define DK4APP_H_INCLUDED 1
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Write to file, report errors immediately.
+ @param filename File name to write to.
+ @param ptr Start address of buffer.
+ @param elsize Size of each element.
+ @param nelem Number of elements.
+ @param fipo File to write to.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success (all elements written completely), 0 on error.
+*/
+int
+dk4fwrite_app(
+ const dkChar *filename,
+ const void *ptr,
+ size_t elsize,
+ size_t nelem,
+ FILE *fipo,
+ dk4_app_t *app
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4getcwd8.c b/support/dktools/dk4getcwd8.c
new file mode 100644
index 0000000000..4787348a7f
--- /dev/null
+++ b/support/dktools/dk4getcwd8.c
@@ -0,0 +1,155 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4getcwd8.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4getcwd8.c The dk4getcwd8 module.
+*/
+
+
+#line 36 "dk4getcwd8.ctr"
+
+
+#include "dk4getcwd8.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_DIRECT_H
+#ifndef DIRECT_H_INCLUDED
+#include <direct.h>
+#define DIRECT_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+
+
+int
+dk4getcwd_c8(char *dptr, size_t sz, dk4_er_t *erp)
+{
+ int back = 0;
+ if ((NULL != dptr) && (0 < sz)) { *dptr = '\0'; }
+ if ((NULL != dptr) && (0 < sz)) {
+#if DK4_ON_WINDOWS
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ DWORD dwSz;
+ DWORD dwRes;
+ dwSz = (DWORD)sz;
+ if ((dk4_um_t)sz > (dk4_um_t)0xFFFFFFUL) { dwSz = (DWORD)0xFFFFFFFFUL; }
+ dwRes = GetCurrentDirectoryA(dwSz, dptr);
+ if (0 < dwRes) {
+ if (dwRes < dwSz) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_ldetails(erp, DK4_E_SYSTEM, GetLastError());
+ }
+#else
+#if DK4_HAVE__GETCWD
+ int isz;
+ errno = 0;
+ isz = (int)sz;
+ if((dk4_um_t)sz > (dk4_um_t)(INT_MAX)) { isz = INT_MAX; }
+ if (NULL != _getcwd(dptr, isz)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_SYSTEM, errno);
+ }
+#else
+#if DK4_HAVE_GETCWD
+ errno = 0;
+ if (NULL != getcwd(dptr, sz)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_SYSTEM, errno);
+ }
+#else
+ DWORD dwSz;
+ DWORD dwRes;
+ dwSz = (DWORD)sz;
+ if ((dk4_um_t)sz > (dk4_um_t)0xFFFFFFUL) { dwSz = (DWORD)0xFFFFFFFFUL; }
+ dwRes = GetCurrentDirectoryA(dwSz, dptr);
+ if (0 < dwRes) {
+ if (dwRes < dwSz) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_ldetails(erp, DK4_E_SYSTEM, GetLastError());
+ }
+#endif
+#endif
+#endif
+#else
+ errno = 0;
+ if (NULL != getcwd(dptr, sz)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_SYSTEM, errno);
+ }
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4getcwd8.ctr b/support/dktools/dk4getcwd8.ctr
new file mode 100644
index 0000000000..9ecc01097b
--- /dev/null
+++ b/support/dktools/dk4getcwd8.ctr
@@ -0,0 +1,150 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk4getcwd8.h Get current working directory as char string.
+*/
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Find current working directory.
+ @param dptr Destination buffer pointer.
+ @param sz Buffer size.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4getcwd_c8(char *dptr, size_t sz, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+
+#include "dk4getcwd8.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_DIRECT_H
+#ifndef DIRECT_H_INCLUDED
+#include <direct.h>
+#define DIRECT_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+
+
+int
+dk4getcwd_c8(char *dptr, size_t sz, dk4_er_t *erp)
+{
+ int back = 0;
+ if ((NULL != dptr) && (0 < sz)) { *dptr = '\0'; }
+ if ((NULL != dptr) && (0 < sz)) {
+#if DK4_ON_WINDOWS
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ DWORD dwSz;
+ DWORD dwRes;
+ dwSz = (DWORD)sz;
+ if ((dk4_um_t)sz > (dk4_um_t)0xFFFFFFUL) { dwSz = (DWORD)0xFFFFFFFFUL; }
+ dwRes = GetCurrentDirectoryA(dwSz, dptr);
+ if (0 < dwRes) {
+ if (dwRes < dwSz) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_ldetails(erp, DK4_E_SYSTEM, GetLastError());
+ }
+#else
+#if DK4_HAVE__GETCWD
+ int isz;
+ errno = 0;
+ isz = (int)sz;
+ if((dk4_um_t)sz > (dk4_um_t)(INT_MAX)) { isz = INT_MAX; }
+ if (NULL != _getcwd(dptr, isz)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_SYSTEM, errno);
+ }
+#else
+#if DK4_HAVE_GETCWD
+ errno = 0;
+ if (NULL != getcwd(dptr, sz)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_SYSTEM, errno);
+ }
+#else
+ DWORD dwSz;
+ DWORD dwRes;
+ dwSz = (DWORD)sz;
+ if ((dk4_um_t)sz > (dk4_um_t)0xFFFFFFUL) { dwSz = (DWORD)0xFFFFFFFFUL; }
+ dwRes = GetCurrentDirectoryA(dwSz, dptr);
+ if (0 < dwRes) {
+ if (dwRes < dwSz) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_ldetails(erp, DK4_E_SYSTEM, GetLastError());
+ }
+#endif
+#endif
+#endif
+#else
+ errno = 0;
+ if (NULL != getcwd(dptr, sz)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_SYSTEM, errno);
+ }
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4getcwd8.h b/support/dktools/dk4getcwd8.h
new file mode 100644
index 0000000000..d801eaf458
--- /dev/null
+++ b/support/dktools/dk4getcwd8.h
@@ -0,0 +1,68 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4getcwd8.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4GETCWD8_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4GETCWD8_H_INCLUDED 1
+
+
+#line 10 "dk4getcwd8.ctr"
+
+/** @file dk4getcwd8.h Get current working directory as char string.
+*/
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Find current working directory.
+ @param dptr Destination buffer pointer.
+ @param sz Buffer size.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4getcwd_c8(char *dptr, size_t sz, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4getcwdd.c b/support/dktools/dk4getcwdd.c
new file mode 100644
index 0000000000..f785fc47db
--- /dev/null
+++ b/support/dktools/dk4getcwdd.c
@@ -0,0 +1,73 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4getcwdd.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4getcwdd.c The dk4getcwdd module.
+*/
+
+
+#line 38 "dk4getcwdd.ctr"
+
+
+#include "dk4getcwdd.h"
+
+#if DK4_CHAR_SIZE > 1
+#include "dk4getcwdw.h"
+#else
+#include "dk4getcwd8.h"
+#endif
+
+
+
+
+
+#line 51 "dk4getcwdd.ctr"
+
+
+
+int
+dk4getcwd(dkChar *dptr, size_t sz, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (
+ dk4getcwd_wc(dptr, sz, erp)
+ );
+#else
+ return (
+ dk4getcwd_c8(dptr, sz, erp)
+ );
+#endif
+}
+
+
diff --git a/support/dktools/dk4getcwdd.ctr b/support/dktools/dk4getcwdd.ctr
new file mode 100644
index 0000000000..e7b6eba7cf
--- /dev/null
+++ b/support/dktools/dk4getcwdd.ctr
@@ -0,0 +1,68 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk4getcwdd.h Get current working directoy in dkChar.
+*/
+
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Find current working directory.
+ @param dptr Destination buffer pointer.
+ @param sz Buffer size.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4getcwd(dkChar *dptr, size_t sz, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+
+#include "dk4getcwdd.h"
+
+#if DK4_CHAR_SIZE > 1
+#include "dk4getcwdw.h"
+#else
+#include "dk4getcwd8.h"
+#endif
+
+
+
+$!trace-include
+
+
+
+int
+dk4getcwd(dkChar *dptr, size_t sz, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (
+ dk4getcwd_wc(dptr, sz, erp)
+ );
+#else
+ return (
+ dk4getcwd_c8(dptr, sz, erp)
+ );
+#endif
+}
+
+
diff --git a/support/dktools/dk4getcwdd.h b/support/dktools/dk4getcwdd.h
new file mode 100644
index 0000000000..b05f26989b
--- /dev/null
+++ b/support/dktools/dk4getcwdd.h
@@ -0,0 +1,70 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4getcwdd.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4GETCWDD_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4GETCWDD_H_INCLUDED 1
+
+
+#line 10 "dk4getcwdd.ctr"
+
+/** @file dk4getcwdd.h Get current working directoy in dkChar.
+*/
+
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Find current working directory.
+ @param dptr Destination buffer pointer.
+ @param sz Buffer size.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4getcwd(dkChar *dptr, size_t sz, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4getcwdw.c b/support/dktools/dk4getcwdw.c
new file mode 100644
index 0000000000..6cabefb9da
--- /dev/null
+++ b/support/dktools/dk4getcwdw.c
@@ -0,0 +1,143 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4getcwdw.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4getcwdw.c The dk4getcwdw module.
+*/
+
+
+#line 40 "dk4getcwdw.ctr"
+
+#include "dk4getcwd8.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_DIRECT_H
+#ifndef DIRECT_H_INCLUDED
+#include <direct.h>
+#define DIRECT_H_INCLUDED 1
+#endif
+#endif
+
+
+
+
+
+#line 81 "dk4getcwdw.ctr"
+
+
+int
+dk4getcwd_wc(wchar_t *dptr, size_t sz, dk4_er_t *erp)
+{
+ int back = 0;
+ if ((NULL != dptr) && (0 < sz)) {
+#if DK4_ON_WINDOWS
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ DWORD dwSz;
+ DWORD dwRes;
+ dwSz = (DWORD)sz;
+ if ((dk4_um_t)sz > (dk4_um_t)0xFFFFFFUL) { dwSz = (DWORD)0xFFFFFFFFUL; }
+ dwRes = GetCurrentDirectoryW(dwSz, dptr);
+ if (0 < dwRes) {
+ if (dwRes < dwSz) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_ldetails(erp, DK4_E_SYSTEM, GetLastError());
+ }
+#else
+#if DK4_HAVE__WGETCWD
+ int isz;
+ errno = 0;
+ isz = (int)sz;
+ if ((dk4_um_t)sz > (dk4_um_t)(INT_MAX)) { isz = INT_MAX; }
+ if (NULL != _wgetcwd(dptr, isz)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_SYSTEM, errno);
+ }
+#else
+ DWORD dwSz;
+ DWORD dwRes;
+ dwSz = (DWORD)sz;
+ if ((dk4_um_t)sz > (dk4_um_t)0xFFFFFFUL) { dwSz = (DWORD)0xFFFFFFFFUL; }
+ dwRes = GetCurrentDirectoryW(dwSz, dptr);
+ if (0 < dwRes) {
+ if (dwRes < dwSz) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_ldetails(erp, DK4_E_SYSTEM, GetLastError());
+ }
+#endif
+#endif
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4getcwdw.ctr b/support/dktools/dk4getcwdw.ctr
new file mode 100644
index 0000000000..1cce43f1e7
--- /dev/null
+++ b/support/dktools/dk4getcwdw.ctr
@@ -0,0 +1,140 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk4getcwdw.h Get working directroy in wchar_t.
+*/
+
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** Find current working directory.
+ @param dptr Destination buffer pointer.
+ @param sz Buffer size (Number of wchar_t).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4getcwd_wc(wchar_t *dptr, size_t sz, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4getcwd8.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_DIRECT_H
+#ifndef DIRECT_H_INCLUDED
+#include <direct.h>
+#define DIRECT_H_INCLUDED 1
+#endif
+#endif
+
+
+
+$!trace-include
+
+
+int
+dk4getcwd_wc(wchar_t *dptr, size_t sz, dk4_er_t *erp)
+{
+ int back = 0;
+ if ((NULL != dptr) && (0 < sz)) {
+#if DK4_ON_WINDOWS
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ DWORD dwSz;
+ DWORD dwRes;
+ dwSz = (DWORD)sz;
+ if ((dk4_um_t)sz > (dk4_um_t)0xFFFFFFUL) { dwSz = (DWORD)0xFFFFFFFFUL; }
+ dwRes = GetCurrentDirectoryW(dwSz, dptr);
+ if (0 < dwRes) {
+ if (dwRes < dwSz) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_ldetails(erp, DK4_E_SYSTEM, GetLastError());
+ }
+#else
+#if DK4_HAVE__WGETCWD
+ int isz;
+ errno = 0;
+ isz = (int)sz;
+ if ((dk4_um_t)sz > (dk4_um_t)(INT_MAX)) { isz = INT_MAX; }
+ if (NULL != _wgetcwd(dptr, isz)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_SYSTEM, errno);
+ }
+#else
+ DWORD dwSz;
+ DWORD dwRes;
+ dwSz = (DWORD)sz;
+ if ((dk4_um_t)sz > (dk4_um_t)0xFFFFFFUL) { dwSz = (DWORD)0xFFFFFFFFUL; }
+ dwRes = GetCurrentDirectoryW(dwSz, dptr);
+ if (0 < dwRes) {
+ if (dwRes < dwSz) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_ldetails(erp, DK4_E_SYSTEM, GetLastError());
+ }
+#endif
+#endif
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4getcwdw.h b/support/dktools/dk4getcwdw.h
new file mode 100644
index 0000000000..af8813b04c
--- /dev/null
+++ b/support/dktools/dk4getcwdw.h
@@ -0,0 +1,72 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4getcwdw.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4GETCWDW_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4GETCWDW_H_INCLUDED 1
+
+
+#line 10 "dk4getcwdw.ctr"
+
+/** @file dk4getcwdw.h Get working directroy in wchar_t.
+*/
+
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** Find current working directory.
+ @param dptr Destination buffer pointer.
+ @param sz Buffer size (Number of wchar_t).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4getcwd_wc(wchar_t *dptr, size_t sz, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4getpid.c b/support/dktools/dk4getpid.c
new file mode 100644
index 0000000000..23969b441c
--- /dev/null
+++ b/support/dktools/dk4getpid.c
@@ -0,0 +1,70 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4getpid.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4getpid.c The dk4getpid module.
+*/
+
+
+#line 68 "dk4getpid.ctr"
+
+
+#include "dk4getpid.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+
+
+dk4_pid_t
+dk4getpid(void)
+{
+#if DK4_ON_WINDOWS
+ return ((dk4_pid_t)GetCurrentProcessId());
+#else
+ return (getpid());
+#endif
+}
+
diff --git a/support/dktools/dk4getpid.ctr b/support/dktools/dk4getpid.ctr
new file mode 100644
index 0000000000..63ff591a48
--- /dev/null
+++ b/support/dktools/dk4getpid.ctr
@@ -0,0 +1,97 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Get process ID.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+
+#if DK4_ON_WINDOWS
+/** Process ID is a DWORD on Windows.
+*/
+typedef unsigned long dk4_pid_t;
+#else
+/** Use existing pid_t on other systems.
+*/
+typedef pid_t dk4_pid_t;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Get current process ID.
+ @return Process ID.
+*/
+dk4_pid_t
+dk4getpid(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+
+#include "dk4getpid.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+
+
+dk4_pid_t
+dk4getpid(void)
+{
+#if DK4_ON_WINDOWS
+ return ((dk4_pid_t)GetCurrentProcessId());
+#else
+ return (getpid());
+#endif
+}
+
diff --git a/support/dktools/dk4getpid.h b/support/dktools/dk4getpid.h
new file mode 100644
index 0000000000..190bf438b2
--- /dev/null
+++ b/support/dktools/dk4getpid.h
@@ -0,0 +1,100 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4getpid.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4GETPID_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4GETPID_H_INCLUDED 1
+
+
+#line 10 "dk4getpid.ctr"
+
+/** @file
+ Get process ID.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+
+#if DK4_ON_WINDOWS
+/** Process ID is a DWORD on Windows.
+*/
+typedef unsigned long dk4_pid_t;
+#else
+/** Use existing pid_t on other systems.
+*/
+typedef pid_t dk4_pid_t;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Get current process ID.
+ @return Process ID.
+*/
+dk4_pid_t
+dk4getpid(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4hname8.c b/support/dktools/dk4hname8.c
new file mode 100644
index 0000000000..835570886d
--- /dev/null
+++ b/support/dktools/dk4hname8.c
@@ -0,0 +1,108 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4hname8.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4hname8.c The dk4hname8 module.
+*/
+
+
+#line 55 "dk4hname8.ctr"
+
+
+#include "dk4hname8.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+
+
+int
+dk4hostname_c8(char *buffer, size_t sz, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ DWORD s;
+#endif
+ int back = 0;
+ if ((NULL != buffer) && (0 < sz)) {
+#if DK4_ON_WINDOWS
+ if ((dk4_um_t)sz <= (dk4_um_t)0xFFFFFFFFUL) {
+ s = (DWORD)sz;
+ if (GetComputerNameExA(ComputerNameNetBIOS, buffer, &s)) {
+ if ((size_t)s < sz) {
+ buffer[(size_t)s] = '\0';
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+#else
+ if (0 == gethostname(buffer, sz)) {
+ buffer[sz - 1] = '\0';
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+#endif
+ if (0 != back) {
+ /* Strip domain part (if any) */
+ while('\0' != *buffer) {
+ if ('.' == *buffer) {
+ *buffer = '\0';
+ }
+ buffer++;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4hname8.ctr b/support/dktools/dk4hname8.ctr
new file mode 100644
index 0000000000..7aa2385ba4
--- /dev/null
+++ b/support/dktools/dk4hname8.ctr
@@ -0,0 +1,122 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve host name.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve host name (short host name without any domain).
+ @param buffer Result buffer.
+ @param sz Result buffer size.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if buffer is NULL or sz is 0 or sz is too large,
+ - DK4_E_NOT_FOUND<br>
+ if the system function to retrieve the host name failed, or,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the result buffer is too small.
+*/
+int
+dk4hostname_c8(char *buffer, size_t sz, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+
+#include "dk4hname8.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+
+
+int
+dk4hostname_c8(char *buffer, size_t sz, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ DWORD s;
+#endif
+ int back = 0;
+ if ((NULL != buffer) && (0 < sz)) {
+#if DK4_ON_WINDOWS
+ if ((dk4_um_t)sz <= (dk4_um_t)0xFFFFFFFFUL) {
+ s = (DWORD)sz;
+ if (GetComputerNameExA(ComputerNameNetBIOS, buffer, &s)) {
+ if ((size_t)s < sz) {
+ buffer[(size_t)s] = '\0';
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+#else
+ if (0 == gethostname(buffer, sz)) {
+ buffer[sz - 1] = '\0';
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+#endif
+ if (0 != back) {
+ /* Strip domain part (if any) */
+ while('\0' != *buffer) {
+ if ('.' == *buffer) {
+ *buffer = '\0';
+ }
+ buffer++;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4hname8.h b/support/dktools/dk4hname8.h
new file mode 100644
index 0000000000..b773353ae7
--- /dev/null
+++ b/support/dktools/dk4hname8.h
@@ -0,0 +1,87 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4hname8.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4HNAME8_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4HNAME8_H_INCLUDED 1
+
+
+#line 10 "dk4hname8.ctr"
+
+/** @file
+ Retrieve host name.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve host name (short host name without any domain).
+ @param buffer Result buffer.
+ @param sz Result buffer size.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if buffer is NULL or sz is 0 or sz is too large,
+ - DK4_E_NOT_FOUND<br>
+ if the system function to retrieve the host name failed, or,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the result buffer is too small.
+*/
+int
+dk4hostname_c8(char *buffer, size_t sz, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4hnamed.c b/support/dktools/dk4hnamed.c
new file mode 100644
index 0000000000..9e9a78262c
--- /dev/null
+++ b/support/dktools/dk4hnamed.c
@@ -0,0 +1,54 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4hnamed.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4hnamed.c The dk4hnamed module.
+*/
+
+
+#line 64 "dk4hnamed.ctr"
+
+#include "dk4hnamed.h"
+
+
+int
+dk4hostname(dkChar *buffer, size_t sz, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4hostname_wc(buffer, sz, erp));
+#else
+ return (dk4hostname_c8(buffer, sz, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4hnamed.ctr b/support/dktools/dk4hnamed.ctr
new file mode 100644
index 0000000000..69039548b8
--- /dev/null
+++ b/support/dktools/dk4hnamed.ctr
@@ -0,0 +1,77 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+%% header
+
+/** @file
+ Retrieve host name in dkChar characters.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_CHAR_SIZE > 1
+#ifndef DK4HNAMEW_H_INCLUDED
+#include "dk4hnamew.h"
+#endif
+#else
+#ifndef DK4HNAME8_H_INCLUDED
+#include "dk4hname8.h"
+#endif
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve host name (short host name without any domain).
+ @param buffer Result buffer.
+ @param sz Result buffer size (number of dkChar).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if buffer is NULL or sz is 0 or sz is too large,
+ - DK4_E_NOT_FOUND<br>
+ if the system function to retrieve the host name failed,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the result buffer is too small.
+*/
+int
+dk4hostname(dkChar *buffer, size_t sz, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4hnamed.h"
+
+
+int
+dk4hostname(dkChar *buffer, size_t sz, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4hostname_wc(buffer, sz, erp));
+#else
+ return (dk4hostname_c8(buffer, sz, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4hnamed.h b/support/dktools/dk4hnamed.h
new file mode 100644
index 0000000000..7f0aca5b50
--- /dev/null
+++ b/support/dktools/dk4hnamed.h
@@ -0,0 +1,98 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4hnamed.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4HNAMED_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4HNAMED_H_INCLUDED 1
+
+
+#line 8 "dk4hnamed.ctr"
+
+/** @file
+ Retrieve host name in dkChar characters.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_CHAR_SIZE > 1
+#ifndef DK4HNAMEW_H_INCLUDED
+#include "dk4hnamew.h"
+#endif
+#else
+#ifndef DK4HNAME8_H_INCLUDED
+#include "dk4hname8.h"
+#endif
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve host name (short host name without any domain).
+ @param buffer Result buffer.
+ @param sz Result buffer size (number of dkChar).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if buffer is NULL or sz is 0 or sz is too large,
+ - DK4_E_NOT_FOUND<br>
+ if the system function to retrieve the host name failed,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the result buffer is too small.
+*/
+int
+dk4hostname(dkChar *buffer, size_t sz, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4hnamew.c b/support/dktools/dk4hnamew.c
new file mode 100644
index 0000000000..6d0d530a6d
--- /dev/null
+++ b/support/dktools/dk4hnamew.c
@@ -0,0 +1,93 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4hnamew.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4hnamew.c The dk4hnamew module.
+*/
+
+
+#line 57 "dk4hnamew.ctr"
+
+#include "dk4hnamew.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+
+
+int
+dk4hostname_wc(wchar_t *buffer, size_t sz, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ DWORD s;
+#endif
+ int back = 0;
+ if ((NULL != buffer) && (0 < sz)) {
+#if DK4_ON_WINDOWS
+ if ((dk4_um_t)sz <= (dk4_um_t)0xFFFFFFFFUL) {
+ s = (DWORD)sz;
+ if (GetComputerNameExW(ComputerNameNetBIOS, buffer, &s)) {
+ if ((size_t)s < sz) {
+ buffer[(size_t)s] = L'\0';
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4hnamew.ctr b/support/dktools/dk4hnamew.ctr
new file mode 100644
index 0000000000..b7e1efceb0
--- /dev/null
+++ b/support/dktools/dk4hnamew.ctr
@@ -0,0 +1,109 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve host name in wchar_t characters.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve host name (short host name without any domain).
+ @param buffer Result buffer.
+ @param sz Result buffer size (number of wchar_t).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if buffer is NULL or sz is 0 or sz is too large,
+ - DK4_E_NOT_FOUND<br>
+ if the system function to retrieve the host name failed,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the result buffer is too small.
+*/
+int
+dk4hostname_wc(wchar_t *buffer, size_t sz, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4hnamew.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+
+
+int
+dk4hostname_wc(wchar_t *buffer, size_t sz, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ DWORD s;
+#endif
+ int back = 0;
+ if ((NULL != buffer) && (0 < sz)) {
+#if DK4_ON_WINDOWS
+ if ((dk4_um_t)sz <= (dk4_um_t)0xFFFFFFFFUL) {
+ s = (DWORD)sz;
+ if (GetComputerNameExW(ComputerNameNetBIOS, buffer, &s)) {
+ if ((size_t)s < sz) {
+ buffer[(size_t)s] = L'\0';
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4hnamew.h b/support/dktools/dk4hnamew.h
new file mode 100644
index 0000000000..2349298ad0
--- /dev/null
+++ b/support/dktools/dk4hnamew.h
@@ -0,0 +1,89 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4hnamew.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4HNAMEW_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4HNAMEW_H_INCLUDED 1
+
+
+#line 10 "dk4hnamew.ctr"
+
+/** @file
+ Retrieve host name in wchar_t characters.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve host name (short host name without any domain).
+ @param buffer Result buffer.
+ @param sz Result buffer size (number of wchar_t).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if buffer is NULL or sz is 0 or sz is too large,
+ - DK4_E_NOT_FOUND<br>
+ if the system function to retrieve the host name failed,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the result buffer is too small.
+*/
+int
+dk4hostname_wc(wchar_t *buffer, size_t sz, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4info.c b/support/dktools/dk4info.c
new file mode 100644
index 0000000000..b2e68dd8db
--- /dev/null
+++ b/support/dktools/dk4info.c
@@ -0,0 +1,521 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4info.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4info.c The dk4info module.
+*/
+
+
+#line 10 "dk4info.ctr"
+
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4app.h"
+#include "dk4aopt.h"
+#include "dk4maodd.h"
+#include "dk4mem.h"
+#include "dk4fput.h"
+#include "dk4vers.h"
+#include "dk4inst.h"
+#include "dk4strd.h"
+
+
+
+
+
+#line 33 "dk4info.ctr"
+
+
+
+#include "dk4info1.c"
+
+
+
+/** Short help text.
+*/
+static const dkChar * const dk_info_help_text[] = {
+dkT(""),
+dkT("Show installation details"),
+dkT(""),
+dkT("dk4info [<options>]"),
+dkT(""),
+dkT("Options:"),
+dkT(""),
+dkT("-l\t\tLong output."),
+dkT(""),
+dkT("--help\t\tShow this short help text."),
+dkT("--manual\t*** SHOW FULL MANUAL. ***"),
+dkT("--version\tShow version information."),
+dkT("--license\tShow license information."),
+dkT(""),
+NULL
+
+
+#line 59 "dk4info.ctr"
+};
+
+
+
+/** License text.
+*/
+static const dkChar * const dk_info_license_text[] = {
+dkT(""),
+dkT("This software uses code from the following projects, either directly or as"),
+dkT("a library:"),
+dkT(""),
+dkT("dktools\t\tDirk Krause's tools and libraries."),
+dkT("\t\tSee http://dktools.sourceforge.net/ for more information."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT("zlib\t\tData compression library."),
+dkT("\t\tSee http://www.zlib.net/ for more information."),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT("bzip2\t\tData compression program and library."),
+dkT("\t\tSee http://www.bzip.org/ for more information."),
+#endif
+dkT(""),
+dkT("All the licenses below apply to the program."),
+dkT("Licenses for used libraries are shown as found on my Scientific Linux 6.x"),
+dkT("computer in the /usr/share/doc directory on 2015-04-01. Check the project"),
+dkT("homepages of the used libraries for additional information and/or updated"),
+dkT("license terms."),
+dkT(""),
+dkT(""),
+dkT("DK tools and libraries license"),
+dkT("=============================="),
+dkT("Copyright (c) 2015-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above copyright notice,"),
+dkT(" this list of conditions and the following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("* Neither the name of the Dirk Krause nor the names of contributors may be"),
+dkT(" used to endorse or promote products derived from this software without"),
+dkT(" specific prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\""),
+dkT("AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED."),
+dkT(""),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,"),
+dkT("INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,"),
+dkT("BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,"),
+dkT("DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY"),
+dkT("OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,"),
+dkT("EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT(""),
+dkT("Zlib license"),
+dkT("============"),
+dkT("(C) 1995-2004 Jean-loup Gailly and Mark Adler"),
+dkT(""),
+dkT("This software is provided 'as-is', without any express or implied"),
+dkT("warranty. In no event will the authors be held liable for any damages"),
+dkT("arising from the use of this software."),
+dkT(""),
+dkT("Permission is granted to anyone to use this software for any purpose,"),
+dkT("including commercial applications, and to alter it and redistribute it"),
+dkT("freely, subject to the following restrictions:"),
+dkT(""),
+dkT("1. The origin of this software must not be misrepresented; you must not"),
+dkT(" claim that you wrote the original software. If you use this software"),
+dkT(" in a product, an acknowledgment in the product documentation would be"),
+dkT(" appreciated but is not required."),
+dkT("2. Altered source versions must be plainly marked as such, and must not be"),
+dkT(" misrepresented as being the original software."),
+dkT("3. This notice may not be removed or altered from any source distribution."),
+dkT(""),
+dkT("Jean-loup Gailly Mark Adler"),
+dkT("jloup@gzip.org madler@alumni.caltech.edu"),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT(""),
+dkT("Bzip2 and libbzip2 library license"),
+dkT("=================================="),
+dkT("This program, \"bzip2\", the associated library \"libbzip2\", and all"),
+dkT("documentation, are copyright (C) 1996-2007 Julian R Seward. All"),
+dkT("rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions"),
+dkT("are met:"),
+dkT(""),
+dkT("1. Redistributions of source code must retain the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer."),
+dkT(""),
+dkT("2. The origin of this software must not be misrepresented; you must "),
+dkT(" not claim that you wrote the original software. If you use this "),
+dkT(" software in a product, an acknowledgment in the product "),
+dkT(" documentation would be appreciated but is not required."),
+dkT(""),
+dkT("3. Altered source versions must be plainly marked as such, and must"),
+dkT(" not be misrepresented as being the original software."),
+dkT(""),
+dkT("4. The name of the author may not be used to endorse or promote "),
+dkT(" products derived from this software without specific prior written "),
+dkT(" permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS"),
+dkT("OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED"),
+dkT("WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE"),
+dkT("GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS"),
+dkT("INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,"),
+dkT("WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS"),
+dkT("SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+dkT(""),
+dkT("Julian Seward, jseward@bzip.org"),
+dkT("bzip2/libbzip2 version 1.0.5 of 10 December 2007"),
+#endif
+dkT(""),
+NULL
+
+
+#line 191 "dk4info.ctr"
+};
+
+
+
+/** Constant texts used by the module, not localized.
+*/
+static const dkChar * const dk_info_kwnl[] = {
+/* 0 */
+dkT("dktools"),
+
+/* 1 */
+dkT("dk4info.txt"),
+
+/* 2 */
+dkT("dk4info.str"),
+
+NULL
+
+
+#line 212 "dk4info.ctr"
+};
+
+
+
+/** Program options.
+*/
+static const dk4_option_specification_t dk_info_options[] = {
+ { dkT('l'), dkT("long"), DK4_OPT_ARG_NONE }
+};
+
+
+
+/** Constant texts used by the program, replaced by localized texts.
+*/
+static const dkChar * const dk_info_kw_def[] = {
+/* 0 */
+dkT("Used directories:"),
+
+/* 1 */
+dkT("-----------------"),
+
+/* 2 */
+dkT("Configured at build time:"),
+
+/* 3 */
+dkT("-------------------------"),
+
+/* 4 */
+dkT("Definitions:"),
+
+/* 5 */
+dkT("------------"),
+
+NULL
+
+
+#line 244 "dk4info.ctr"
+};
+
+
+
+/** Option names for configure.
+*/
+static dkChar const *option_names[] = {
+/* 0 */
+dkT("--prefix="),
+
+/* 1 */
+dkT("--sysconfdir="),
+
+/* 2 */
+dkT("--datarootdir="),
+
+/* 3 */
+dkT("--localstatedir="),
+
+/* 4 */
+dkT("--bindir="),
+
+/* 5 */
+dkT("--sbindir="),
+
+/* 6 */
+dkT("--libdir="),
+
+/* 7 */
+dkT("--includedir="),
+
+/* 8 */
+dkT("--mandir="),
+
+/* 9 */
+dkT("--execprefix="),
+
+/* 10 */
+dkT("--libexecdir="),
+
+NULL
+
+
+#line 264 "dk4info.ctr"
+};
+
+
+
+/** Options order.
+*/
+static size_t option_order[] = {
+ 0, 1, 3, 2, 4, 5, 6, 7, 8, 10
+};
+
+
+
+static const size_t szoo = sizeof(option_order)/sizeof(size_t);
+
+/** Replaced by localized texts if found.
+*/
+static const dkChar * const *dk_info_msg = dk_info_kw_def;
+
+
+
+
+/** Number of elements in dk_info_msg.
+*/
+static size_t dk_info_sz_msg =
+sizeof(dk_info_kw_def)/sizeof(DK4_PDKCHAR) - 1;
+
+
+
+/** Number of elements in the options array.
+*/
+static const size_t dk_info_sz_options =
+sizeof(dk_info_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Exit status code returned by the program.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+static
+void
+show_one_directory(size_t ind, size_t maxl)
+{
+ const dkChar *val;
+ size_t lgt;
+
+ val = dk4inst_get_directory(ind);
+ if (NULL != val) {
+ lgt = dk4str_len(option_names[ind]);
+ while (lgt++ < maxl) { dk4fputc(dkT(' '), stdout, NULL); }
+ dk4fputs(option_names[ind], stdout, NULL);
+ dk4fputs(val, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ }
+}
+
+
+
+static
+void
+show_one_used_directory(size_t ind, size_t maxl, const dkChar *dn)
+{
+ size_t lgt;
+ if (NULL != dn) {
+ lgt = dk4str_len(option_names[ind]);
+ while (lgt++ < maxl) { dk4fputc(dkT(' '), stdout, NULL); }
+ dk4fputs(option_names[ind], stdout, NULL);
+ dk4fputs(dn, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ }
+}
+
+
+
+/** Produce output.
+*/
+static
+void
+dk_info_run_with_app(void)
+{
+ size_t i;
+ size_t maxl = 0;
+ size_t lgt;
+
+ /* Find longest option name length.
+ */
+ for (i = 0; i < 11; i++) {
+ lgt = dk4str_len(option_names[i]);
+ if (lgt > maxl) { maxl = lgt; }
+ }
+
+ /* Show used values.
+ */
+ dk4fputs(dk_info_kw_def[0], stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ dk4fputs(dk_info_kw_def[1], stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ show_one_used_directory(1, maxl, app->dir_etc);
+ show_one_used_directory(4, maxl, app->dir_bin);
+ show_one_used_directory(6, maxl, app->dir_lib);
+ show_one_used_directory(2, maxl, app->dir_share);
+ show_one_used_directory(3, maxl, app->dir_var);
+ dk4fputc(dkT('\n'), stdout, NULL);
+
+ /* Show compiled values.
+ */
+ dk4fputs(dk_info_kw_def[2], stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ dk4fputs(dk_info_kw_def[3], stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ for (i = 0; i < szoo; i++) {
+ lgt = option_order[i];
+ show_one_directory(lgt, maxl);
+ }
+
+ /* Show complete list of defines if required.
+ */
+ if (0 != dk4app_opt_is_set_short(app, dkT('l'), NULL)) {
+ dk4fputc(dkT('\n'), stdout, NULL);
+ dk4fputs(dk_info_kw_def[4], stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ dk4fputs(dk_info_kw_def[5], stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ showdefines();
+ }
+
+}
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+
+
+#line 414 "dk4info.ctr"
+
+
+#line 415 "dk4info.ctr"
+
+
+#line 416 "dk4info.ctr"
+
+
+#line 417 "dk4info.ctr"
+ dk4fput_initialize_stdout();
+ dk4fput_initialize_stderr();
+ app = dk4app_open_cmd(
+ argc, argv, dk_info_options, dk_info_sz_options,
+ dk_info_kwnl[0], DKT_VERSION_DK,
+ dk_info_kwnl[1], dk_info_help_text, dk_info_license_text
+ );
+ if (NULL != app) {
+ dk_info_sz_msg = dk4app_string_table_size(dk_info_kw_def);
+ dk_info_msg = dk4app_string_table(app, dk_info_kwnl[2], dk_info_kw_def);
+ if (0 != dk4app_can_run_normally(app)) {
+ dk_info_run_with_app();
+ } else {
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ dk4app_close(app);
+ }
+ fflush(stdout);
+ fflush(stderr);
+ dk4fput_cleanup_stderr();
+ dk4fput_cleanup_stdout();
+
+
+#line 441 "dk4info.ctr"
+
+
+#line 442 "dk4info.ctr"
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/dk4info.ctr b/support/dktools/dk4info.ctr
new file mode 100644
index 0000000000..28adafcef1
--- /dev/null
+++ b/support/dktools/dk4info.ctr
@@ -0,0 +1,444 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4app.h"
+#include "dk4aopt.h"
+#include "dk4maodd.h"
+#include "dk4mem.h"
+#include "dk4fput.h"
+#include "dk4vers.h"
+#include "dk4inst.h"
+#include "dk4strd.h"
+
+
+
+$!trace-include
+
+
+
+#include "dk4info1.c"
+
+
+
+/** Short help text.
+*/
+static const dkChar * const dk_info_help_text[] = {
+$!text macro=dkT
+
+Show installation details
+
+dk4info [<options>]
+
+Options:
+
+-l Long output.
+
+--help Show this short help text.
+--manual *** SHOW FULL MANUAL. ***
+--version Show version information.
+--license Show license information.
+
+$!end
+};
+
+
+
+/** License text.
+*/
+static const dkChar * const dk_info_license_text[] = {
+$!text macro=dkT,preprocessor
+
+This software uses code from the following projects, either directly or as
+a library:
+
+dktools Dirk Krause's tools and libraries.
+ See http://dktools.sourceforge.net/ for more information.
+#if DK4_HAVE_ZLIB_H
+
+zlib Data compression library.
+ See http://www.zlib.net/ for more information.
+#endif
+#if DK4_HAVE_BZLIB_H
+
+bzip2 Data compression program and library.
+ See http://www.bzip.org/ for more information.
+#endif
+
+All the licenses below apply to the program.
+Licenses for used libraries are shown as found on my Scientific Linux 6.x
+computer in the /usr/share/doc directory on 2015-04-01. Check the project
+homepages of the used libraries for additional information and/or updated
+license terms.
+
+
+DK tools and libraries license
+==============================
+Copyright (c) 2015-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#if DK4_HAVE_ZLIB_H
+
+
+Zlib license
+============
+(C) 1995-2004 Jean-loup Gailly and Mark Adler
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+
+Jean-loup Gailly Mark Adler
+jloup@gzip.org madler@alumni.caltech.edu
+#endif
+#if DK4_HAVE_BZLIB_H
+
+
+Bzip2 and libbzip2 library license
+==================================
+This program, "bzip2", the associated library "libbzip2", and all
+documentation, are copyright (C) 1996-2007 Julian R Seward. All
+rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+3. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Julian Seward, jseward@bzip.org
+bzip2/libbzip2 version 1.0.5 of 10 December 2007
+#endif
+
+$!end
+};
+
+
+
+/** Constant texts used by the module, not localized.
+*/
+static const dkChar * const dk_info_kwnl[] = {
+$!string-table macro=dkT
+#
+# 0 Program group name
+#
+dktools
+#
+# 1 Help text file name
+#
+dk4info.txt
+#
+# 2 String table file
+#
+dk4info.str
+$!end
+};
+
+
+
+/** Program options.
+*/
+static const dk4_option_specification_t dk_info_options[] = {
+ { dkT('l'), dkT("long"), DK4_OPT_ARG_NONE }
+};
+
+
+
+/** Constant texts used by the program, replaced by localized texts.
+*/
+static const dkChar * const dk_info_kw_def[] = {
+$!string-table macro=dkT
+#
+# 0 1 Used directories:
+#
+Used directories:
+-----------------
+#
+# 2 3 Configured at build time:
+#
+Configured at build time:
+-------------------------
+#
+# 4 5 Definitions
+#
+Definitions:
+------------
+$!end
+};
+
+
+
+/** Option names for configure.
+*/
+static dkChar const *option_names[] = {
+$!string-table macro=dkT
+--prefix=
+--sysconfdir=
+--datarootdir=
+--localstatedir=
+--bindir=
+--sbindir=
+--libdir=
+--includedir=
+--mandir=
+--execprefix=
+--libexecdir=
+$!end
+};
+
+
+
+/** Options order.
+*/
+static size_t option_order[] = {
+ 0, 1, 3, 2, 4, 5, 6, 7, 8, 10
+};
+
+
+
+static const size_t szoo = sizeof(option_order)/sizeof(size_t);
+
+/** Replaced by localized texts if found.
+*/
+static const dkChar * const *dk_info_msg = dk_info_kw_def;
+
+
+
+
+/** Number of elements in dk_info_msg.
+*/
+static size_t dk_info_sz_msg =
+sizeof(dk_info_kw_def)/sizeof(DK4_PDKCHAR) - 1;
+
+
+
+/** Number of elements in the options array.
+*/
+static const size_t dk_info_sz_options =
+sizeof(dk_info_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Exit status code returned by the program.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+static
+void
+show_one_directory(size_t ind, size_t maxl)
+{
+ const dkChar *val;
+ size_t lgt;
+
+ val = dk4inst_get_directory(ind);
+ if (NULL != val) {
+ lgt = dk4str_len(option_names[ind]);
+ while (lgt++ < maxl) { dk4fputc(dkT(' '), stdout, NULL); }
+ dk4fputs(option_names[ind], stdout, NULL);
+ dk4fputs(val, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ }
+}
+
+
+
+static
+void
+show_one_used_directory(size_t ind, size_t maxl, const dkChar *dn)
+{
+ size_t lgt;
+ if (NULL != dn) {
+ lgt = dk4str_len(option_names[ind]);
+ while (lgt++ < maxl) { dk4fputc(dkT(' '), stdout, NULL); }
+ dk4fputs(option_names[ind], stdout, NULL);
+ dk4fputs(dn, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ }
+}
+
+
+
+/** Produce output.
+*/
+static
+void
+dk_info_run_with_app(void)
+{
+ size_t i;
+ size_t maxl = 0;
+ size_t lgt;
+
+ /* Find longest option name length.
+ */
+ for (i = 0; i < 11; i++) {
+ lgt = dk4str_len(option_names[i]);
+ if (lgt > maxl) { maxl = lgt; }
+ }
+
+ /* Show used values.
+ */
+ dk4fputs(dk_info_kw_def[0], stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ dk4fputs(dk_info_kw_def[1], stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ show_one_used_directory(1, maxl, app->dir_etc);
+ show_one_used_directory(4, maxl, app->dir_bin);
+ show_one_used_directory(6, maxl, app->dir_lib);
+ show_one_used_directory(2, maxl, app->dir_share);
+ show_one_used_directory(3, maxl, app->dir_var);
+ dk4fputc(dkT('\n'), stdout, NULL);
+
+ /* Show compiled values.
+ */
+ dk4fputs(dk_info_kw_def[2], stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ dk4fputs(dk_info_kw_def[3], stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ for (i = 0; i < szoo; i++) {
+ lgt = option_order[i];
+ show_one_directory(lgt, maxl);
+ }
+
+ /* Show complete list of defines if required.
+ */
+ if (0 != dk4app_opt_is_set_short(app, dkT('l'), NULL)) {
+ dk4fputc(dkT('\n'), stdout, NULL);
+ dk4fputs(dk_info_kw_def[4], stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ dk4fputs(dk_info_kw_def[5], stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ showdefines();
+ }
+
+}
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ $!trace-init dk4info.deb
+ $? "+ main"
+ $? ". sizeof dkChar %u", (unsigned)(DK4_CHAR_SIZE)
+ $? ". sizeof wchar_t %u", (unsigned)sizeof(wchar_t)
+ dk4fput_initialize_stdout();
+ dk4fput_initialize_stderr();
+ app = dk4app_open_cmd(
+ argc, argv, dk_info_options, dk_info_sz_options,
+ dk_info_kwnl[0], DKT_VERSION_DK,
+ dk_info_kwnl[1], dk_info_help_text, dk_info_license_text
+ );
+ if (NULL != app) {
+ dk_info_sz_msg = dk4app_string_table_size(dk_info_kw_def);
+ dk_info_msg = dk4app_string_table(app, dk_info_kwnl[2], dk_info_kw_def);
+ if (0 != dk4app_can_run_normally(app)) {
+ dk_info_run_with_app();
+ } else {
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ dk4app_close(app);
+ }
+ fflush(stdout);
+ fflush(stderr);
+ dk4fput_cleanup_stderr();
+ dk4fput_cleanup_stdout();
+ $? "- main %d", exval
+ $!trace-end
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/dk4info.rc b/support/dktools/dk4info.rc
new file mode 100644
index 0000000000..a165fc2dcf
--- /dev/null
+++ b/support/dktools/dk4info.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Show setup information\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "Show setup information\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "dk4info\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/dk4info1.c b/support/dktools/dk4info1.c
new file mode 100644
index 0000000000..abc651914c
--- /dev/null
+++ b/support/dktools/dk4info1.c
@@ -0,0 +1,1795 @@
+static
+void
+showdefines(void)
+{
+ dkChar buf[64];
+
+#if DK4_HAVE_ALLOC_H
+ dk4fputs(dkT("DK4_HAVE_ALLOC_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_ALLOC_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_ARPA_INET_H
+ dk4fputs(dkT("DK4_HAVE_ARPA_INET_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_ARPA_INET_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_ASSERT_H
+ dk4fputs(dkT("DK4_HAVE_ASSERT_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_ASSERT_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_BACKSLASH_AS_SEP
+ dk4fputs(dkT("DK4_HAVE_BACKSLASH_AS_SEP = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_BACKSLASH_AS_SEP = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_BCMP
+ dk4fputs(dkT("DK4_HAVE_BCMP = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_BCMP = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_BCOPY
+ dk4fputs(dkT("DK4_HAVE_BCOPY = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_BCOPY = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_BIOS_H
+ dk4fputs(dkT("DK4_HAVE_BIOS_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_BIOS_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_BLKCNT_T
+ dk4fputs(dkT("DK4_HAVE_BLKCNT_T = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_BLKCNT_T = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_BLKSIZE_T
+ dk4fputs(dkT("DK4_HAVE_BLKSIZE_T = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_BLKSIZE_T = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_BZERO
+ dk4fputs(dkT("DK4_HAVE_BZERO = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_BZERO = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_BZLIB_H
+ dk4fputs(dkT("DK4_HAVE_BZLIB_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_BZLIB_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_CALLOC
+ dk4fputs(dkT("DK4_HAVE_CALLOC = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_CALLOC = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_CASE_INSENSITIVE_PATHNAMES
+ dk4fputs(dkT("DK4_HAVE_CASE_INSENSITIVE_PATHNAMES = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_CASE_INSENSITIVE_PATHNAMES = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_CASE_INSENSITIVE_USERNAMES
+ dk4fputs(dkT("DK4_HAVE_CASE_INSENSITIVE_USERNAMES = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_CASE_INSENSITIVE_USERNAMES = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_CHMOD
+ dk4fputs(dkT("DK4_HAVE_CHMOD = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_CHMOD = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_CHOWN
+ dk4fputs(dkT("DK4_HAVE_CHOWN = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_CHOWN = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_COMPATDKTOOLS3
+ dk4fputs(dkT("DK4_HAVE_COMPATDKTOOLS3 = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_COMPATDKTOOLS3 = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_COMPLEX_H
+ dk4fputs(dkT("DK4_HAVE_COMPLEX_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_COMPLEX_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_CTYPE_H
+ dk4fputs(dkT("DK4_HAVE_CTYPE_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_CTYPE_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_DB_CURSOR_C_GET
+ dk4fputs(dkT("DK4_HAVE_DB_CURSOR_C_GET = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_DB_CURSOR_C_GET = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_DB_H
+ dk4fputs(dkT("DK4_HAVE_DB_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_DB_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_DEV_T
+ dk4fputs(dkT("DK4_HAVE_DEV_T = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_DEV_T = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_DIRECT_H
+ dk4fputs(dkT("DK4_HAVE_DIRECT_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_DIRECT_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_DIRENT_H
+ dk4fputs(dkT("DK4_HAVE_DIRENT_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_DIRENT_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_DOS_H
+ dk4fputs(dkT("DK4_HAVE_DOS_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_DOS_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_ENDGRENT
+ dk4fputs(dkT("DK4_HAVE_ENDGRENT = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_ENDGRENT = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_ENDPWENT
+ dk4fputs(dkT("DK4_HAVE_ENDPWENT = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_ENDPWENT = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_ERRNO_H
+ dk4fputs(dkT("DK4_HAVE_ERRNO_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_ERRNO_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_FCNTL_H
+ dk4fputs(dkT("DK4_HAVE_FCNTL_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_FCNTL_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_FENV_H
+ dk4fputs(dkT("DK4_HAVE_FENV_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_FENV_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_FILEMODE_BINARY
+ dk4fputs(dkT("DK4_HAVE_FILEMODE_BINARY = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_FILEMODE_BINARY = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_FILENO
+ dk4fputs(dkT("DK4_HAVE_FILENO = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_FILENO = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_FILE_ATIMECTIME
+ dk4fputs(dkT("DK4_HAVE_FILE_ATIMECTIME = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_FILE_ATIMECTIME = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_FILE_BLKSIZECNT
+ dk4fputs(dkT("DK4_HAVE_FILE_BLKSIZECNT = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_FILE_BLKSIZECNT = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_FILE_DEVINO
+ dk4fputs(dkT("DK4_HAVE_FILE_DEVINO = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_FILE_DEVINO = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_FILE_UIDGID
+ dk4fputs(dkT("DK4_HAVE_FILE_UIDGID = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_FILE_UIDGID = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_FLOAT_H
+ dk4fputs(dkT("DK4_HAVE_FLOAT_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_FLOAT_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_FOPEN64
+ dk4fputs(dkT("DK4_HAVE_FOPEN64 = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_FOPEN64 = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_FOPEN_S
+ dk4fputs(dkT("DK4_HAVE_FOPEN_S = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_FOPEN_S = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_FPOS_T
+ dk4fputs(dkT("DK4_HAVE_FPOS_T = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_FPOS_T = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_FPUTWC
+ dk4fputs(dkT("DK4_HAVE_FPUTWC = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_FPUTWC = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_FPUTWS
+ dk4fputs(dkT("DK4_HAVE_FPUTWS = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_FPUTWS = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_FREE
+ dk4fputs(dkT("DK4_HAVE_FREE = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_FREE = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_GETADDRINFO
+ dk4fputs(dkT("DK4_HAVE_GETADDRINFO = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_GETADDRINFO = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_GETCWD
+ dk4fputs(dkT("DK4_HAVE_GETCWD = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_GETCWD = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_GETENV
+ dk4fputs(dkT("DK4_HAVE_GETENV = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_GETENV = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_GETENV_S
+ dk4fputs(dkT("DK4_HAVE_GETENV_S = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_GETENV_S = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_GETEUID
+ dk4fputs(dkT("DK4_HAVE_GETEUID = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_GETEUID = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_GETEXECNAME
+ dk4fputs(dkT("DK4_HAVE_GETEXECNAME = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_GETEXECNAME = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_GETFINALPATHNAMEBYHANDLE
+ dk4fputs(dkT("DK4_HAVE_GETFINALPATHNAMEBYHANDLE = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_GETFINALPATHNAMEBYHANDLE = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_GETGRENT
+ dk4fputs(dkT("DK4_HAVE_GETGRENT = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_GETGRENT = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_GETGRGID
+ dk4fputs(dkT("DK4_HAVE_GETGRGID = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_GETGRGID = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_GETGRNAM
+ dk4fputs(dkT("DK4_HAVE_GETGRNAM = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_GETGRNAM = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_GETHOSTBYNAME
+ dk4fputs(dkT("DK4_HAVE_GETHOSTBYNAME = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_GETHOSTBYNAME = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_GETNAMEINFO
+ dk4fputs(dkT("DK4_HAVE_GETNAMEINFO = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_GETNAMEINFO = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_GETPID
+ dk4fputs(dkT("DK4_HAVE_GETPID = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_GETPID = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_GETPWENT
+ dk4fputs(dkT("DK4_HAVE_GETPWENT = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_GETPWENT = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_GETPWNAM
+ dk4fputs(dkT("DK4_HAVE_GETPWNAM = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_GETPWNAM = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_GETPWUID
+ dk4fputs(dkT("DK4_HAVE_GETPWUID = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_GETPWUID = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_GETRLIMIT
+ dk4fputs(dkT("DK4_HAVE_GETRLIMIT = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_GETRLIMIT = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_GID_T
+ dk4fputs(dkT("DK4_HAVE_GID_T = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_GID_T = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_GRP_H
+ dk4fputs(dkT("DK4_HAVE_GRP_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_GRP_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_HTONL
+ dk4fputs(dkT("DK4_HAVE_HTONL = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_HTONL = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_HTONS
+ dk4fputs(dkT("DK4_HAVE_HTONS = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_HTONS = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_IN6_ADDR
+ dk4fputs(dkT("DK4_HAVE_IN6_ADDR = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_IN6_ADDR = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_INET_ADDR
+ dk4fputs(dkT("DK4_HAVE_INET_ADDR = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_INET_ADDR = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_INET_ATON
+ dk4fputs(dkT("DK4_HAVE_INET_ATON = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_INET_ATON = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_INET_NTOP
+ dk4fputs(dkT("DK4_HAVE_INET_NTOP = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_INET_NTOP = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_INET_PTON
+ dk4fputs(dkT("DK4_HAVE_INET_PTON = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_INET_PTON = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_INITSTATE
+ dk4fputs(dkT("DK4_HAVE_INITSTATE = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_INITSTATE = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_INLINE
+ dk4fputs(dkT("DK4_HAVE_INLINE = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_INLINE = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_INO64_T
+ dk4fputs(dkT("DK4_HAVE_INO64_T = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_INO64_T = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_INO_T
+ dk4fputs(dkT("DK4_HAVE_INO_T = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_INO_T = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_INT16_T
+ dk4fputs(dkT("DK4_HAVE_INT16_T = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_INT16_T = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_INT32_T
+ dk4fputs(dkT("DK4_HAVE_INT32_T = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_INT32_T = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_INT8_T
+ dk4fputs(dkT("DK4_HAVE_INT8_T = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_INT8_T = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_INTMAX_T
+ dk4fputs(dkT("DK4_HAVE_INTMAX_T = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_INTMAX_T = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_INTTYPES_H
+ dk4fputs(dkT("DK4_HAVE_INTTYPES_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_INTTYPES_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_IN_ADDR
+ dk4fputs(dkT("DK4_HAVE_IN_ADDR = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_IN_ADDR = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_IO_H
+ dk4fputs(dkT("DK4_HAVE_IO_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_IO_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_ISATTY
+ dk4fputs(dkT("DK4_HAVE_ISATTY = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_ISATTY = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_ISFINITE
+ dk4fputs(dkT("DK4_HAVE_ISFINITE = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_ISFINITE = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_ISNORMAL
+ dk4fputs(dkT("DK4_HAVE_ISNORMAL = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_ISNORMAL = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_ISO646_H
+ dk4fputs(dkT("DK4_HAVE_ISO646_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_ISO646_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_JPEGLIB_H
+ dk4fputs(dkT("DK4_HAVE_JPEGLIB_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_JPEGLIB_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_LARGEFILE64_SOURCE
+ dk4fputs(dkT("DK4_HAVE_LARGEFILE64_SOURCE = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_LARGEFILE64_SOURCE = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_LIBNETSNMP
+ dk4fputs(dkT("DK4_HAVE_LIBNETSNMP = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_LIBNETSNMP = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_LIMITS_H
+ dk4fputs(dkT("DK4_HAVE_LIMITS_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_LIMITS_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_LINE_END_CR_NL
+ dk4fputs(dkT("DK4_HAVE_LINE_END_CR_NL = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_LINE_END_CR_NL = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_LOCALE_H
+ dk4fputs(dkT("DK4_HAVE_LOCALE_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_LOCALE_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_LOCALTIME_R
+ dk4fputs(dkT("DK4_HAVE_LOCALTIME_R = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_LOCALTIME_R = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_LONG_DOUBLE
+ dk4fputs(dkT("DK4_HAVE_LONG_DOUBLE = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_LONG_DOUBLE = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_LONG_LONG
+ dk4fputs(dkT("DK4_HAVE_LONG_LONG = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_LONG_LONG = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_LRAND48
+ dk4fputs(dkT("DK4_HAVE_LRAND48 = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_LRAND48 = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_LSTAT
+ dk4fputs(dkT("DK4_HAVE_LSTAT = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_LSTAT = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_LSTAT64
+ dk4fputs(dkT("DK4_HAVE_LSTAT64 = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_LSTAT64 = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_MALLOC
+ dk4fputs(dkT("DK4_HAVE_MALLOC = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_MALLOC = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_MALLOC_H
+ dk4fputs(dkT("DK4_HAVE_MALLOC_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_MALLOC_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_MATH_H
+ dk4fputs(dkT("DK4_HAVE_MATH_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_MATH_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_MEMCMP
+ dk4fputs(dkT("DK4_HAVE_MEMCMP = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_MEMCMP = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_MEMCPY
+ dk4fputs(dkT("DK4_HAVE_MEMCPY = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_MEMCPY = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_MEMSET
+ dk4fputs(dkT("DK4_HAVE_MEMSET = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_MEMSET = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_MKDIR
+ dk4fputs(dkT("DK4_HAVE_MKDIR = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_MKDIR = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_MODE_T
+ dk4fputs(dkT("DK4_HAVE_MODE_T = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_MODE_T = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_NDBM_H
+ dk4fputs(dkT("DK4_HAVE_NDBM_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_NDBM_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_NETDB_H
+ dk4fputs(dkT("DK4_HAVE_NETDB_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_NETDB_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_NETINET_IN6_H
+ dk4fputs(dkT("DK4_HAVE_NETINET_IN6_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_NETINET_IN6_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_NETINET_IN_H
+ dk4fputs(dkT("DK4_HAVE_NETINET_IN_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_NETINET_IN_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_NLINK_T
+ dk4fputs(dkT("DK4_HAVE_NLINK_T = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_NLINK_T = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_NRAND48
+ dk4fputs(dkT("DK4_HAVE_NRAND48 = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_NRAND48 = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_NTIFS_H
+ dk4fputs(dkT("DK4_HAVE_NTIFS_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_NTIFS_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_NTOHL
+ dk4fputs(dkT("DK4_HAVE_NTOHL = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_NTOHL = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_NTOHS
+ dk4fputs(dkT("DK4_HAVE_NTOHS = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_NTOHS = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_OFF64_T
+ dk4fputs(dkT("DK4_HAVE_OFF64_T = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_OFF64_T = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_OFF_T
+ dk4fputs(dkT("DK4_HAVE_OFF_T = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_OFF_T = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_OPENSSL_MD5_H
+ dk4fputs(dkT("DK4_HAVE_OPENSSL_MD5_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_OPENSSL_MD5_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_OPENSSL_RAND_H
+ dk4fputs(dkT("DK4_HAVE_OPENSSL_RAND_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_OPENSSL_RAND_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_OPENSSL_RIPEMD_H
+ dk4fputs(dkT("DK4_HAVE_OPENSSL_RIPEMD_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_OPENSSL_RIPEMD_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_OPENSSL_SHA_H
+ dk4fputs(dkT("DK4_HAVE_OPENSSL_SHA_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_OPENSSL_SHA_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_PNG_GET_PIXELS_PER_INCH
+ dk4fputs(dkT("DK4_HAVE_PNG_GET_PIXELS_PER_INCH = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_PNG_GET_PIXELS_PER_INCH = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_PNG_H
+ dk4fputs(dkT("DK4_HAVE_PNG_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_PNG_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_PROCESS_H
+ dk4fputs(dkT("DK4_HAVE_PROCESS_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_PROCESS_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_PROC_PID_EXE
+ dk4fputs(dkT("DK4_HAVE_PROC_PID_EXE = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_PROC_PID_EXE = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_PWD_H
+ dk4fputs(dkT("DK4_HAVE_PWD_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_PWD_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_RAND
+ dk4fputs(dkT("DK4_HAVE_RAND = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_RAND = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_RANDOM
+ dk4fputs(dkT("DK4_HAVE_RANDOM = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_RANDOM = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_RAND_EGD
+ dk4fputs(dkT("DK4_HAVE_RAND_EGD = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_RAND_EGD = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_READ
+ dk4fputs(dkT("DK4_HAVE_READ = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_READ = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_READLINK
+ dk4fputs(dkT("DK4_HAVE_READLINK = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_READLINK = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_RMDIR
+ dk4fputs(dkT("DK4_HAVE_RMDIR = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_RMDIR = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SELECT
+ dk4fputs(dkT("DK4_HAVE_SELECT = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SELECT = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SETBUF
+ dk4fputs(dkT("DK4_HAVE_SETBUF = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SETBUF = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SETBUFFER
+ dk4fputs(dkT("DK4_HAVE_SETBUFFER = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SETBUFFER = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SETGID
+ dk4fputs(dkT("DK4_HAVE_SETGID = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SETGID = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SETGRENT
+ dk4fputs(dkT("DK4_HAVE_SETGRENT = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SETGRENT = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SETJMP_H
+ dk4fputs(dkT("DK4_HAVE_SETJMP_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SETJMP_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SETLOCALE
+ dk4fputs(dkT("DK4_HAVE_SETLOCALE = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SETLOCALE = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SETMODE
+ dk4fputs(dkT("DK4_HAVE_SETMODE = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SETMODE = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SETPGRP
+ dk4fputs(dkT("DK4_HAVE_SETPGRP = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SETPGRP = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SETPWENT
+ dk4fputs(dkT("DK4_HAVE_SETPWENT = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SETPWENT = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SETSID
+ dk4fputs(dkT("DK4_HAVE_SETSID = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SETSID = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SETSOCKOPT
+ dk4fputs(dkT("DK4_HAVE_SETSOCKOPT = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SETSOCKOPT = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SETSTATE
+ dk4fputs(dkT("DK4_HAVE_SETSTATE = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SETSTATE = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SETUID
+ dk4fputs(dkT("DK4_HAVE_SETUID = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SETUID = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SETVBUF
+ dk4fputs(dkT("DK4_HAVE_SETVBUF = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SETVBUF = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SHA224
+ dk4fputs(dkT("DK4_HAVE_SHA224 = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SHA224 = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SHA256
+ dk4fputs(dkT("DK4_HAVE_SHA256 = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SHA256 = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SHA384
+ dk4fputs(dkT("DK4_HAVE_SHA384 = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SHA384 = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SHA512
+ dk4fputs(dkT("DK4_HAVE_SHA512 = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SHA512 = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SHARE_H
+ dk4fputs(dkT("DK4_HAVE_SHARE_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SHARE_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SIGACTION
+ dk4fputs(dkT("DK4_HAVE_SIGACTION = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SIGACTION = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SIGEMPTYSET
+ dk4fputs(dkT("DK4_HAVE_SIGEMPTYSET = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SIGEMPTYSET = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SIGNAL
+ dk4fputs(dkT("DK4_HAVE_SIGNAL = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SIGNAL = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+ dk4fputs(dkT("DK4_HAVE_SIGNAL_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SIGNAL_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SIGPROCMASK
+ dk4fputs(dkT("DK4_HAVE_SIGPROCMASK = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SIGPROCMASK = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SIGSET
+ dk4fputs(dkT("DK4_HAVE_SIGSET = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SIGSET = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SIG_ATOMIC_T
+ dk4fputs(dkT("DK4_HAVE_SIG_ATOMIC_T = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SIG_ATOMIC_T = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SNMP_DISABLE_FILELOG
+ dk4fputs(dkT("DK4_HAVE_SNMP_DISABLE_FILELOG = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SNMP_DISABLE_FILELOG = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SNMP_DISABLE_STDERRLOG
+ dk4fputs(dkT("DK4_HAVE_SNMP_DISABLE_STDERRLOG = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SNMP_DISABLE_STDERRLOG = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SNMP_DISABLE_SYSLOG
+ dk4fputs(dkT("DK4_HAVE_SNMP_DISABLE_SYSLOG = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SNMP_DISABLE_SYSLOG = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SNMP_ENABLE_FILELOG
+ dk4fputs(dkT("DK4_HAVE_SNMP_ENABLE_FILELOG = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SNMP_ENABLE_FILELOG = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SNPRINTF
+ dk4fputs(dkT("DK4_HAVE_SNPRINTF = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SNPRINTF = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SNWPRINTF
+ dk4fputs(dkT("DK4_HAVE_SNWPRINTF = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SNWPRINTF = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SOCKET
+ dk4fputs(dkT("DK4_HAVE_SOCKET = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SOCKET = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SOCKLEN_T
+ dk4fputs(dkT("DK4_HAVE_SOCKLEN_T = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SOCKLEN_T = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SRAND
+ dk4fputs(dkT("DK4_HAVE_SRAND = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SRAND = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SSIZE_T
+ dk4fputs(dkT("DK4_HAVE_SSIZE_T = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SSIZE_T = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_STAT64
+ dk4fputs(dkT("DK4_HAVE_STAT64 = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_STAT64 = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_STDALIGN_H
+ dk4fputs(dkT("DK4_HAVE_STDALIGN_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_STDALIGN_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_STDARG_H
+ dk4fputs(dkT("DK4_HAVE_STDARG_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_STDARG_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_STDATOMIC_H
+ dk4fputs(dkT("DK4_HAVE_STDATOMIC_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_STDATOMIC_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_STDBOOL_H
+ dk4fputs(dkT("DK4_HAVE_STDBOOL_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_STDBOOL_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_STDDEF_H
+ dk4fputs(dkT("DK4_HAVE_STDDEF_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_STDDEF_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_STDINT_H
+ dk4fputs(dkT("DK4_HAVE_STDINT_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_STDINT_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_STDLIB_H
+ dk4fputs(dkT("DK4_HAVE_STDLIB_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_STDLIB_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_STDNORETURN_H
+ dk4fputs(dkT("DK4_HAVE_STDNORETURN_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_STDNORETURN_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_STRCASECMP
+ dk4fputs(dkT("DK4_HAVE_STRCASECMP = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_STRCASECMP = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_STRCAT_S
+ dk4fputs(dkT("DK4_HAVE_STRCAT_S = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_STRCAT_S = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_STRCPY_S
+ dk4fputs(dkT("DK4_HAVE_STRCPY_S = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_STRCPY_S = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_STRERROR
+ dk4fputs(dkT("DK4_HAVE_STRERROR = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_STRERROR = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_STRERROR_R
+ dk4fputs(dkT("DK4_HAVE_STRERROR_R = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_STRERROR_R = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_STRICMP
+ dk4fputs(dkT("DK4_HAVE_STRICMP = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_STRICMP = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_STRINGS_H
+ dk4fputs(dkT("DK4_HAVE_STRINGS_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_STRINGS_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_STRING_H
+ dk4fputs(dkT("DK4_HAVE_STRING_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_STRING_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_STRTOD
+ dk4fputs(dkT("DK4_HAVE_STRTOD = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_STRTOD = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_STRUCT_ADDRINFO
+ dk4fputs(dkT("DK4_HAVE_STRUCT_ADDRINFO = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_STRUCT_ADDRINFO = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_STRUCT_SOCKADDR_IN
+ dk4fputs(dkT("DK4_HAVE_STRUCT_SOCKADDR_IN = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_STRUCT_SOCKADDR_IN = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ dk4fputs(dkT("DK4_HAVE_STRUCT_SOCKADDR_IN6 = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_STRUCT_SOCKADDR_IN6 = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_STRUCT_SOCKADDR_STORAGE
+ dk4fputs(dkT("DK4_HAVE_STRUCT_SOCKADDR_STORAGE = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_STRUCT_SOCKADDR_STORAGE = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_STRUCT_SOCKADDR_UN
+ dk4fputs(dkT("DK4_HAVE_STRUCT_SOCKADDR_UN = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_STRUCT_SOCKADDR_UN = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SWPRINTF
+ dk4fputs(dkT("DK4_HAVE_SWPRINTF = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SWPRINTF = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SYSLOG
+ dk4fputs(dkT("DK4_HAVE_SYSLOG = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SYSLOG = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SYSLOG_H
+ dk4fputs(dkT("DK4_HAVE_SYSLOG_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SYSLOG_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SYS_PARAM_H
+ dk4fputs(dkT("DK4_HAVE_SYS_PARAM_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SYS_PARAM_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SYS_RESOURCE_H
+ dk4fputs(dkT("DK4_HAVE_SYS_RESOURCE_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SYS_RESOURCE_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SYS_SELECT_H
+ dk4fputs(dkT("DK4_HAVE_SYS_SELECT_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SYS_SELECT_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SYS_SOCKET_H
+ dk4fputs(dkT("DK4_HAVE_SYS_SOCKET_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SYS_SOCKET_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SYS_STAT_H
+ dk4fputs(dkT("DK4_HAVE_SYS_STAT_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SYS_STAT_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SYS_TIME_H
+ dk4fputs(dkT("DK4_HAVE_SYS_TIME_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SYS_TIME_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+ dk4fputs(dkT("DK4_HAVE_SYS_TYPES_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SYS_TYPES_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_SYS_UN_H
+ dk4fputs(dkT("DK4_HAVE_SYS_UN_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_SYS_UN_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_TGMATH_H
+ dk4fputs(dkT("DK4_HAVE_TGMATH_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_TGMATH_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_THREADS_H
+ dk4fputs(dkT("DK4_HAVE_THREADS_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_THREADS_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_TIFF_H
+ dk4fputs(dkT("DK4_HAVE_TIFF_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_TIFF_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_TIME_H
+ dk4fputs(dkT("DK4_HAVE_TIME_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_TIME_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_TYPE_STAT64
+ dk4fputs(dkT("DK4_HAVE_TYPE_STAT64 = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_TYPE_STAT64 = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_UCHAR_H
+ dk4fputs(dkT("DK4_HAVE_UCHAR_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_UCHAR_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_UID_T
+ dk4fputs(dkT("DK4_HAVE_UID_T = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_UID_T = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_UINT16_T
+ dk4fputs(dkT("DK4_HAVE_UINT16_T = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_UINT16_T = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_UINT32_T
+ dk4fputs(dkT("DK4_HAVE_UINT32_T = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_UINT32_T = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_UINT8_T
+ dk4fputs(dkT("DK4_HAVE_UINT8_T = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_UINT8_T = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_UNISTD_H
+ dk4fputs(dkT("DK4_HAVE_UNISTD_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_UNISTD_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_UNLINK
+ dk4fputs(dkT("DK4_HAVE_UNLINK = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_UNLINK = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_VOLATILE
+ dk4fputs(dkT("DK4_HAVE_VOLATILE = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_VOLATILE = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_WCHAR_H
+ dk4fputs(dkT("DK4_HAVE_WCHAR_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_WCHAR_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_WCSCASECMP
+ dk4fputs(dkT("DK4_HAVE_WCSCASECMP = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_WCSCASECMP = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_WCSCAT
+ dk4fputs(dkT("DK4_HAVE_WCSCAT = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_WCSCAT = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_WCSCAT_S
+ dk4fputs(dkT("DK4_HAVE_WCSCAT_S = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_WCSCAT_S = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_WCSCHR
+ dk4fputs(dkT("DK4_HAVE_WCSCHR = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_WCSCHR = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_WCSCMP
+ dk4fputs(dkT("DK4_HAVE_WCSCMP = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_WCSCMP = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_WCSCPY
+ dk4fputs(dkT("DK4_HAVE_WCSCPY = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_WCSCPY = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_WCSCPY_S
+ dk4fputs(dkT("DK4_HAVE_WCSCPY_S = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_WCSCPY_S = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_WCSICMP
+ dk4fputs(dkT("DK4_HAVE_WCSICMP = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_WCSICMP = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_WCSLEN
+ dk4fputs(dkT("DK4_HAVE_WCSLEN = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_WCSLEN = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_WCSNCMP
+ dk4fputs(dkT("DK4_HAVE_WCSNCMP = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_WCSNCMP = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_WCSRCHR
+ dk4fputs(dkT("DK4_HAVE_WCSRCHR = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_WCSRCHR = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_WCSTOD
+ dk4fputs(dkT("DK4_HAVE_WCSTOD = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_WCSTOD = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_WCTYPE_H
+ dk4fputs(dkT("DK4_HAVE_WCTYPE_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_WCTYPE_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_WINDOWS_H
+ dk4fputs(dkT("DK4_HAVE_WINDOWS_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_WINDOWS_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_WINSOCK2_H
+ dk4fputs(dkT("DK4_HAVE_WINSOCK2_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_WINSOCK2_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_WMKDIR
+ dk4fputs(dkT("DK4_HAVE_WMKDIR = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_WMKDIR = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_WRITE
+ dk4fputs(dkT("DK4_HAVE_WRITE = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_WRITE = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_WRMDIR
+ dk4fputs(dkT("DK4_HAVE_WRMDIR = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_WRMDIR = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_WS2TCPIP_H
+ dk4fputs(dkT("DK4_HAVE_WS2TCPIP_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_WS2TCPIP_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_WUNLINK
+ dk4fputs(dkT("DK4_HAVE_WUNLINK = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_WUNLINK = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_WXWIDGETS
+ dk4fputs(dkT("DK4_HAVE_WXWIDGETS = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_WXWIDGETS = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE_ZLIB_H
+ dk4fputs(dkT("DK4_HAVE_ZLIB_H = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE_ZLIB_H = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE__DEV_T
+ dk4fputs(dkT("DK4_HAVE__DEV_T = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE__DEV_T = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE__FILENO
+ dk4fputs(dkT("DK4_HAVE__FILENO = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE__FILENO = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE__FINITE
+ dk4fputs(dkT("DK4_HAVE__FINITE = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE__FINITE = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE__FPOS_T
+ dk4fputs(dkT("DK4_HAVE__FPOS_T = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE__FPOS_T = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE__GETCWD
+ dk4fputs(dkT("DK4_HAVE__GETCWD = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE__GETCWD = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE__INO64_T
+ dk4fputs(dkT("DK4_HAVE__INO64_T = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE__INO64_T = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE__INO_T
+ dk4fputs(dkT("DK4_HAVE__INO_T = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE__INO_T = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE__ISATTY
+ dk4fputs(dkT("DK4_HAVE__ISATTY = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE__ISATTY = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE__MKDIR
+ dk4fputs(dkT("DK4_HAVE__MKDIR = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE__MKDIR = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE__OFF64_T
+ dk4fputs(dkT("DK4_HAVE__OFF64_T = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE__OFF64_T = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE__OFF_T
+ dk4fputs(dkT("DK4_HAVE__OFF_T = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE__OFF_T = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE__READ
+ dk4fputs(dkT("DK4_HAVE__READ = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE__READ = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE__RMDIR
+ dk4fputs(dkT("DK4_HAVE__RMDIR = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE__RMDIR = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE__SETMODE
+ dk4fputs(dkT("DK4_HAVE__SETMODE = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE__SETMODE = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE__SNPRINTF
+ dk4fputs(dkT("DK4_HAVE__SNPRINTF = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE__SNPRINTF = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE__SNPRINTF_S
+ dk4fputs(dkT("DK4_HAVE__SNPRINTF_S = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE__SNPRINTF_S = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE__SNWPRINTF
+ dk4fputs(dkT("DK4_HAVE__SNWPRINTF = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE__SNWPRINTF = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE__SNWPRINTF_S
+ dk4fputs(dkT("DK4_HAVE__SNWPRINTF_S = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE__SNWPRINTF_S = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE__STRICMP
+ dk4fputs(dkT("DK4_HAVE__STRICMP = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE__STRICMP = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE__STRTOD
+ dk4fputs(dkT("DK4_HAVE__STRTOD = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE__STRTOD = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE__UNLINK
+ dk4fputs(dkT("DK4_HAVE__UNLINK = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE__UNLINK = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE__WCSCASECMP
+ dk4fputs(dkT("DK4_HAVE__WCSCASECMP = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE__WCSCASECMP = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE__WCSCMP
+ dk4fputs(dkT("DK4_HAVE__WCSCMP = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE__WCSCMP = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE__WCSICMP
+ dk4fputs(dkT("DK4_HAVE__WCSICMP = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE__WCSICMP = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE__WCSNCMP
+ dk4fputs(dkT("DK4_HAVE__WCSNCMP = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE__WCSNCMP = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE__WCSTOD
+ dk4fputs(dkT("DK4_HAVE__WCSTOD = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE__WCSTOD = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE__WFOPEN
+ dk4fputs(dkT("DK4_HAVE__WFOPEN = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE__WFOPEN = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE__WFOPEN64
+ dk4fputs(dkT("DK4_HAVE__WFOPEN64 = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE__WFOPEN64 = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE__WFOPEN_S
+ dk4fputs(dkT("DK4_HAVE__WFOPEN_S = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE__WFOPEN_S = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE__WGETCWD
+ dk4fputs(dkT("DK4_HAVE__WGETCWD = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE__WGETCWD = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE__WMKDIR
+ dk4fputs(dkT("DK4_HAVE__WMKDIR = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE__WMKDIR = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE__WRITE
+ dk4fputs(dkT("DK4_HAVE__WRITE = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE__WRITE = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE__WRMDIR
+ dk4fputs(dkT("DK4_HAVE__WRMDIR = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE__WRMDIR = 0\n"), stdout, NULL);
+#endif
+
+#if DK4_HAVE__WUNLINK
+ dk4fputs(dkT("DK4_HAVE__WUNLINK = 1\n"), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_HAVE__WUNLINK = 0\n"), stdout, NULL);
+#endif
+
+#ifdef DK4_SIZEOF_DOUBLE
+ dk4ma_write_decimal_unsigned(buf, DK4_SIZEOF(buf, dkChar), (dk4_um_t)DK4_SIZEOF_DOUBLE, 0, NULL);
+ dk4fputs(dkT("DK4_SIZEOF_DOUBLE = "), stdout, NULL);
+ dk4fputs(buf, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_SIZEOF_DOUBLE = 0\n"), stdout, NULL);
+#endif
+
+#ifdef DK4_SIZEOF_INO64_T
+ dk4ma_write_decimal_unsigned(buf, DK4_SIZEOF(buf, dkChar), (dk4_um_t)DK4_SIZEOF_INO64_T, 0, NULL);
+ dk4fputs(dkT("DK4_SIZEOF_INO64_T = "), stdout, NULL);
+ dk4fputs(buf, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_SIZEOF_INO64_T = 0\n"), stdout, NULL);
+#endif
+
+#ifdef DK4_SIZEOF_INO_T
+ dk4ma_write_decimal_unsigned(buf, DK4_SIZEOF(buf, dkChar), (dk4_um_t)DK4_SIZEOF_INO_T, 0, NULL);
+ dk4fputs(dkT("DK4_SIZEOF_INO_T = "), stdout, NULL);
+ dk4fputs(buf, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_SIZEOF_INO_T = 0\n"), stdout, NULL);
+#endif
+
+#ifdef DK4_SIZEOF_INT
+ dk4ma_write_decimal_unsigned(buf, DK4_SIZEOF(buf, dkChar), (dk4_um_t)DK4_SIZEOF_INT, 0, NULL);
+ dk4fputs(dkT("DK4_SIZEOF_INT = "), stdout, NULL);
+ dk4fputs(buf, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_SIZEOF_INT = 0\n"), stdout, NULL);
+#endif
+
+#ifdef DK4_SIZEOF_INTMAX_T
+ dk4ma_write_decimal_unsigned(buf, DK4_SIZEOF(buf, dkChar), (dk4_um_t)DK4_SIZEOF_INTMAX_T, 0, NULL);
+ dk4fputs(dkT("DK4_SIZEOF_INTMAX_T = "), stdout, NULL);
+ dk4fputs(buf, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_SIZEOF_INTMAX_T = 0\n"), stdout, NULL);
+#endif
+
+#ifdef DK4_SIZEOF_LONG
+ dk4ma_write_decimal_unsigned(buf, DK4_SIZEOF(buf, dkChar), (dk4_um_t)DK4_SIZEOF_LONG, 0, NULL);
+ dk4fputs(dkT("DK4_SIZEOF_LONG = "), stdout, NULL);
+ dk4fputs(buf, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_SIZEOF_LONG = 0\n"), stdout, NULL);
+#endif
+
+#ifdef DK4_SIZEOF_LONG_DOUBLE
+ dk4ma_write_decimal_unsigned(buf, DK4_SIZEOF(buf, dkChar), (dk4_um_t)DK4_SIZEOF_LONG_DOUBLE, 0, NULL);
+ dk4fputs(dkT("DK4_SIZEOF_LONG_DOUBLE = "), stdout, NULL);
+ dk4fputs(buf, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_SIZEOF_LONG_DOUBLE = 0\n"), stdout, NULL);
+#endif
+
+#ifdef DK4_SIZEOF_LONG_LONG
+ dk4ma_write_decimal_unsigned(buf, DK4_SIZEOF(buf, dkChar), (dk4_um_t)DK4_SIZEOF_LONG_LONG, 0, NULL);
+ dk4fputs(dkT("DK4_SIZEOF_LONG_LONG = "), stdout, NULL);
+ dk4fputs(buf, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_SIZEOF_LONG_LONG = 0\n"), stdout, NULL);
+#endif
+
+#ifdef DK4_SIZEOF_OFF64_T
+ dk4ma_write_decimal_unsigned(buf, DK4_SIZEOF(buf, dkChar), (dk4_um_t)DK4_SIZEOF_OFF64_T, 0, NULL);
+ dk4fputs(dkT("DK4_SIZEOF_OFF64_T = "), stdout, NULL);
+ dk4fputs(buf, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_SIZEOF_OFF64_T = 0\n"), stdout, NULL);
+#endif
+
+#ifdef DK4_SIZEOF_OFF_T
+ dk4ma_write_decimal_unsigned(buf, DK4_SIZEOF(buf, dkChar), (dk4_um_t)DK4_SIZEOF_OFF_T, 0, NULL);
+ dk4fputs(dkT("DK4_SIZEOF_OFF_T = "), stdout, NULL);
+ dk4fputs(buf, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_SIZEOF_OFF_T = 0\n"), stdout, NULL);
+#endif
+
+#ifdef DK4_SIZEOF_SHORT
+ dk4ma_write_decimal_unsigned(buf, DK4_SIZEOF(buf, dkChar), (dk4_um_t)DK4_SIZEOF_SHORT, 0, NULL);
+ dk4fputs(dkT("DK4_SIZEOF_SHORT = "), stdout, NULL);
+ dk4fputs(buf, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_SIZEOF_SHORT = 0\n"), stdout, NULL);
+#endif
+
+#ifdef DK4_SIZEOF_SIZE_T
+ dk4ma_write_decimal_unsigned(buf, DK4_SIZEOF(buf, dkChar), (dk4_um_t)DK4_SIZEOF_SIZE_T, 0, NULL);
+ dk4fputs(dkT("DK4_SIZEOF_SIZE_T = "), stdout, NULL);
+ dk4fputs(buf, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_SIZEOF_SIZE_T = 0\n"), stdout, NULL);
+#endif
+
+#ifdef DK4_SIZEOF_WCHAR_T
+ dk4ma_write_decimal_unsigned(buf, DK4_SIZEOF(buf, dkChar), (dk4_um_t)DK4_SIZEOF_WCHAR_T, 0, NULL);
+ dk4fputs(dkT("DK4_SIZEOF_WCHAR_T = "), stdout, NULL);
+ dk4fputs(buf, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_SIZEOF_WCHAR_T = 0\n"), stdout, NULL);
+#endif
+
+#ifdef DK4_TIME_WITH_SYS_TIME
+ dk4ma_write_decimal_unsigned(buf, DK4_SIZEOF(buf, dkChar), (dk4_um_t)DK4_TIME_WITH_SYS_TIME, 0, NULL);
+ dk4fputs(dkT("DK4_TIME_WITH_SYS_TIME = "), stdout, NULL);
+ dk4fputs(buf, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_TIME_WITH_SYS_TIME = 0\n"), stdout, NULL);
+#endif
+
+#ifdef DK4_USE_FALLBACK_NUMERIC_LIMITS
+ dk4ma_write_decimal_unsigned(buf, DK4_SIZEOF(buf, dkChar), (dk4_um_t)DK4_USE_FALLBACK_NUMERIC_LIMITS, 0, NULL);
+ dk4fputs(dkT("DK4_USE_FALLBACK_NUMERIC_LIMITS = "), stdout, NULL);
+ dk4fputs(buf, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_USE_FALLBACK_NUMERIC_LIMITS = 0\n"), stdout, NULL);
+#endif
+
+#ifdef DK4_USE_PRINTF_SCANF
+ dk4ma_write_decimal_unsigned(buf, DK4_SIZEOF(buf, dkChar), (dk4_um_t)DK4_USE_PRINTF_SCANF, 0, NULL);
+ dk4fputs(dkT("DK4_USE_PRINTF_SCANF = "), stdout, NULL);
+ dk4fputs(buf, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_USE_PRINTF_SCANF = 0\n"), stdout, NULL);
+#endif
+
+#ifdef DK4_USE_WINDOWS_LOCAL_ALLOC
+ dk4ma_write_decimal_unsigned(buf, DK4_SIZEOF(buf, dkChar), (dk4_um_t)DK4_USE_WINDOWS_LOCAL_ALLOC, 0, NULL);
+ dk4fputs(dkT("DK4_USE_WINDOWS_LOCAL_ALLOC = "), stdout, NULL);
+ dk4fputs(buf, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_USE_WINDOWS_LOCAL_ALLOC = 0\n"), stdout, NULL);
+#endif
+
+#ifdef DK4_WORDS_BIGENDIAN
+ dk4ma_write_decimal_unsigned(buf, DK4_SIZEOF(buf, dkChar), (dk4_um_t)DK4_WORDS_BIGENDIAN, 0, NULL);
+ dk4fputs(dkT("DK4_WORDS_BIGENDIAN = "), stdout, NULL);
+ dk4fputs(buf, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+#else
+ dk4fputs(dkT("DK4_WORDS_BIGENDIAN = 0\n"), stdout, NULL);
+#endif
+
+}
diff --git a/support/dktools/dk4inst.c b/support/dktools/dk4inst.c
new file mode 100644
index 0000000000..bead5e5b82
--- /dev/null
+++ b/support/dktools/dk4inst.c
@@ -0,0 +1,62 @@
+/** @file dk4inst.c Installation directories.
+ Produced by configure, 2017-03-28 22:19:29.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4INST_H_INCLUDED
+#include "dk4inst.h"
+#endif
+
+
+
+/** Directory names.
+*/
+const dkChar * const dk4inst_directories[] = {
+#if DK4_ON_WINDOWS || DK4_HAVE_BACKSLASH_AS_SEP
+ /* 0 */ dkT("C:\\Program Files\\Krause"),
+ /* 1 */ dkT("C:\\Program Files\\Krause\\etc"),
+ /* 2 */ dkT("C:\\Program Files\\Krause\\share"),
+ /* 3 */ dkT("C:\\Program Files\\Krause\\var"),
+ /* 4 */ dkT("C:\\Program Files\\Krause\\bin"),
+ /* 5 */ dkT("C:\\Program Files\\Krause\\sbin"),
+ /* 6 */ dkT("C:\\Program Files\\Krause\\lib"),
+ /* 7 */ dkT("C:\\Program Files\\Krause\\include"),
+ /* 8 */ dkT("C:\\Program Files\\Krause\\man"),
+ /* 9 */ dkT("C:\\Program Files\\Krause"),
+ /* 10 */ dkT("C:\\Program Files\\Krause\\libexec"),
+#else
+ /* 0 */ dkT("/usr/local"),
+ /* 1 */ dkT("/usr/local/etc"),
+ /* 2 */ dkT("/usr/local/share"),
+ /* 3 */ dkT("/usr/local/var"),
+ /* 4 */ dkT("/usr/local/bin"),
+ /* 5 */ dkT("/usr/local/sbin"),
+ /* 6 */ dkT("/usr/local/lib"),
+ /* 7 */ dkT("/usr/local/include"),
+ /* 8 */ dkT("/usr/local/share/man"),
+ /* 9 */ dkT("/usr/local"),
+ /* 10 */ dkT("/usr/local/libexec"),
+#endif
+};
+
+
+
+const dkChar *
+dk4inst_get_directory(size_t i)
+{
+ const dkChar *back = NULL;
+ if(i <= 10) { back = dk4inst_directories[i]; }
+ return back;
+}
+
+
+
+/* vim: set ai sw=2 filetype=c : */
+
diff --git a/support/dktools/dk4inst.h b/support/dktools/dk4inst.h
new file mode 100644
index 0000000000..89fb845312
--- /dev/null
+++ b/support/dktools/dk4inst.h
@@ -0,0 +1,151 @@
+#ifndef DK4INST_H_INCLUDED
+#define DK4INST_H_INCLUDED 1
+
+/** @file dk4inst.h Installation directories.
+
+ Obtain installation prefix, system configuration directory,
+ data directory, local state directory, binary directory,
+ root binary directory, library directory, include directory,
+ man page directory, executable files prefix and libexec
+ directory is configured during build process.
+
+ CRT on Windows: Not used.
+
+ Produced by configure, 2017-03-28 22:19:29.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve one installation directory.
+ @param i Directory index:
+ 0 = prefix,
+ 1 = system configuration directory,
+ 2 = data directory,
+ 3 = local state directory,
+ 4 = binary directory,
+ 5 = root binary directory,
+ 6 = library directory,
+ 7 = include directory,
+ 8 = man page directory,
+ 9 = executable files prefix,
+ 10 = libexec directory.
+ @return Pointer to directory name on success, NULL on error.
+*/
+const dkChar *
+dk4inst_get_directory(size_t i);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @defgroup instdirs Installation directories. */
+/**@{*/
+#ifdef _WIN32
+
+/** Installation prefix, typlically /usr or /usr/local.
+*/
+#define DK4_INST_DIR_PREFIX "C:\\Program Files\\Krause"
+
+/** System configuration directory, typically /etc or /usr/local/etc.
+*/
+#define DK4_INST_DIR_ETC "C:\\Program Files\\Krause\\etc"
+
+/** Data directory, typically /usr/share or /usr/local/share.
+*/
+#define DK4_INST_DIR_SHARE "C:\\Program Files\\Krause\\share"
+
+/** Local state directory, typically /var or /usr/local/var.
+*/
+#define DK4_INST_DIR_VAR "C:\\Program Files\\Krause\\var"
+
+/** Binaries directory, typically /usr/bin or /usr/local/bin.
+*/
+#define DK4_INST_DIR_BIN "C:\\Program Files\\Krause\\bin"
+
+/** System binaries directory, typically /usr/sbin or /usr/local/sbin.
+*/
+#define DK4_INST_DIR_SBIN "C:\\Program Files\\Krause\\sbin"
+
+/** Libraries directory, typically /usr/lib or /usr/local/lib.
+*/
+#define DK4_INST_DIR_LIB "C:\\Program Files\\Krause\\lib"
+
+/** Include files directory, typically /usr/include or /usr/local/include.
+*/
+#define DK4_INST_DIR_INCLUDE "C:\\Program Files\\Krause\\include"
+
+/** Man pages directory, typically /usr/share/man or /usr/local/share/man.
+*/
+#define DK4_INST_DIR_MAN "C:\\Program Files\\Krause\\man"
+
+/** Prefix directory for executables.
+*/
+#define DK4_INST_DIR_EXECPRE "C:\\Program Files\\Krause"
+
+/** Libexec directory, typically /usr/libexec or /usr/local/libexec.
+*/
+#define DK4_INST_DIR_LIBEXEC "C:\\Program Files\\Krause\\libexec"
+
+#else
+
+/** Installation prefix, typlically /usr or /usr/local.
+*/
+#define DK4_INST_DIR_PREFIX "/usr/local"
+
+/** System configuration directory, typically /etc or /usr/local/etc.
+*/
+#define DK4_INST_DIR_ETC "/usr/local/etc"
+
+/** Data directory, typically /usr/share or /usr/local/share.
+*/
+#define DK4_INST_DIR_SHARE "/usr/local/share"
+
+/** Local state directory, typically /var or /usr/local/var.
+*/
+#define DK4_INST_DIR_VAR "/usr/local/var"
+
+/** Binaries directory, typically /usr/bin or /usr/local/bin.
+*/
+#define DK4_INST_DIR_BIN "/usr/local/bin"
+
+/** System binaries directory, typically /usr/sbin or /usr/local/sbin.
+*/
+#define DK4_INST_DIR_SBIN "/usr/local/sbin"
+
+/** Libraries directory, typically /usr/lib or /usr/local/lib.
+*/
+#define DK4_INST_DIR_LIB "/usr/local/lib"
+
+/** Include files directory, typically /usr/include or /usr/local/include.
+*/
+#define DK4_INST_DIR_INCLUDE "/usr/local/include"
+
+/** Man pages directory, typically /usr/share/man or /usr/local/share/man.
+*/
+#define DK4_INST_DIR_MAN "/usr/local/share/man"
+
+/** Prefix directory for executables.
+*/
+#define DK4_INST_DIR_EXECPRE "/usr/local"
+
+/** Libexec directory, typically /usr/libexec or /usr/local/libexec.
+*/
+#define DK4_INST_DIR_LIBEXEC "/usr/local/libexec"
+
+#endif
+/**@}*/
+
+#endif
+
+/* vim: set ai sw=2 filetype=c : */
+
diff --git a/support/dktools/dk4isadm.c b/support/dktools/dk4isadm.c
new file mode 100644
index 0000000000..fdb30fd60d
--- /dev/null
+++ b/support/dktools/dk4isadm.c
@@ -0,0 +1,111 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4isadm.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4isadm.c The dk4isadm module.
+*/
+
+
+#line 29 "dk4isadm.ctr"
+
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4types.h"
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+int
+dk4isadmin(void)
+{
+#if DK4_ON_WINDOWS
+ PSID pAdmGroup = NULL;
+ SID_IDENTIFIER_AUTHORITY ntAuthority = SECURITY_NT_AUTHORITY;
+ BOOL bres = FALSE;
+ BOOL isadm = FALSE;
+#endif
+ int back = 0;
+#if DK4_ON_WINDOWS
+ back = -1;
+ bres = AllocateAndInitializeSid(
+ &ntAuthority, 2,
+ SECURITY_BUILTIN_DOMAIN_RID, /* sub-authority 0 */
+ DOMAIN_ALIAS_RID_ADMINS, /* sub-authority 1 */
+ (DWORD)0, /* sub-authority 2 */
+ (DWORD)0, /* sub-authority 3 */
+ (DWORD)0, /* sub-authority 4 */
+ (DWORD)0, /* sub-authority 5 */
+ (DWORD)0, /* sub-authority 6 */
+ (DWORD)0, /* sub-authority 7 */
+ &pAdmGroup
+ );
+ if (bres) {
+ if (CheckTokenMembership(NULL, pAdmGroup, &isadm)) {
+ if (isadm) {
+ back = 1;
+ } else {
+ back = 0;
+ }
+ }
+ }
+ if (NULL != pAdmGroup) {
+ FreeSid(pAdmGroup);
+ }
+#else
+ if (0 == geteuid()) {
+ back = 1;
+ }
+#endif
+ return back;
+}
+
diff --git a/support/dktools/dk4isadm.ctr b/support/dktools/dk4isadm.ctr
new file mode 100644
index 0000000000..bdd7573763
--- /dev/null
+++ b/support/dktools/dk4isadm.ctr
@@ -0,0 +1,99 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file dk4isadm.h Check whether process runs with
+ admin privileges.
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Check whether the current process runs with administrative privileges.
+ @return 1 if administrative, 0 if user process, -1 if failed to check.
+*/
+int
+dk4isadmin(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4types.h"
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+int
+dk4isadmin(void)
+{
+#if DK4_ON_WINDOWS
+ PSID pAdmGroup = NULL;
+ SID_IDENTIFIER_AUTHORITY ntAuthority = SECURITY_NT_AUTHORITY;
+ BOOL bres = FALSE;
+ BOOL isadm = FALSE;
+#endif
+ int back = 0;
+#if DK4_ON_WINDOWS
+ back = -1;
+ bres = AllocateAndInitializeSid(
+ &ntAuthority, 2,
+ SECURITY_BUILTIN_DOMAIN_RID, /* sub-authority 0 */
+ DOMAIN_ALIAS_RID_ADMINS, /* sub-authority 1 */
+ (DWORD)0, /* sub-authority 2 */
+ (DWORD)0, /* sub-authority 3 */
+ (DWORD)0, /* sub-authority 4 */
+ (DWORD)0, /* sub-authority 5 */
+ (DWORD)0, /* sub-authority 6 */
+ (DWORD)0, /* sub-authority 7 */
+ &pAdmGroup
+ );
+ if (bres) {
+ if (CheckTokenMembership(NULL, pAdmGroup, &isadm)) {
+ if (isadm) {
+ back = 1;
+ } else {
+ back = 0;
+ }
+ }
+ }
+ if (NULL != pAdmGroup) {
+ FreeSid(pAdmGroup);
+ }
+#else
+ if (0 == geteuid()) {
+ back = 1;
+ }
+#endif
+ return back;
+}
+
diff --git a/support/dktools/dk4isadm.h b/support/dktools/dk4isadm.h
new file mode 100644
index 0000000000..039ca746c2
--- /dev/null
+++ b/support/dktools/dk4isadm.h
@@ -0,0 +1,62 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4isadm.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4ISADM_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4ISADM_H_INCLUDED 1
+
+
+#line 9 "dk4isadm.ctr"
+
+/** @file dk4isadm.h Check whether process runs with
+ admin privileges.
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Check whether the current process runs with administrative privileges.
+ @return 1 if administrative, 0 if user process, -1 if failed to check.
+*/
+int
+dk4isadmin(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4istty.c b/support/dktools/dk4istty.c
new file mode 100644
index 0000000000..0248705a51
--- /dev/null
+++ b/support/dktools/dk4istty.c
@@ -0,0 +1,104 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4istty.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4istty.c The dk4istty module.
+*/
+
+
+#line 69 "dk4istty.ctr"
+
+#include "dk4istty.h"
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+int
+dk4istty(int fd, dk4_er_t *erp)
+{
+ int back = -1;
+#if DK4_HAVE_ISATTY
+ if ( 0 != isatty(fd) ) {
+ back = 1;
+ } else {
+ back = 0;
+ }
+#else
+#if DK4_HAVE__ISATTY
+ if ( 0 != _isatty(fd) ) {
+ back = 1;
+ } else {
+ back = 0;
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+#endif
+ return back;
+}
+
+
+
+int
+dk4istty_file(FILE *fipo, dk4_er_t *erp)
+{
+ int back = -1;
+ if (NULL != fipo) {
+#if DK4_HAVE_FILENO
+ back = dk4istty(fileno(fipo), erp);
+#else
+#if DK4_HAVE__FILENO
+ back = dk4istty(_fileno(fipo), erp);
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4istty.ctr b/support/dktools/dk4istty.ctr
new file mode 100644
index 0000000000..e4032c5ad2
--- /dev/null
+++ b/support/dktools/dk4istty.ctr
@@ -0,0 +1,132 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Check whether a file pointer
+ is connected to a terminal.
+
+ CRT on Windows: Required.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef STDIO_H_INCLUDED
+#include <stdio.h>
+#define STDIO_H_INCLUDED 1
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Check whether the file descriptor is connected to a
+ tty (terminal, printer, serial line).
+ @param fd File descriptor to check.
+ @param erp Error report, may be NULL.
+ @return 1 for tty, 0 for other file descriptor, -1 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ if not isatty() or _isatty() function available on the system.
+*/
+int
+dk4istty(int fd, dk4_er_t *erp);
+
+/** Check whether a FILE pointer is connected to a tty
+ (terminal, printer, serial line).
+ @param fipo FILE to check.
+ @param erp Error report, may be NULL.
+ @return 1 for tty, 0 for other file descriptor, -1 on error.
+*/
+int
+dk4istty_file(FILE *fipo, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4istty.h"
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+int
+dk4istty(int fd, dk4_er_t *erp)
+{
+ int back = -1;
+#if DK4_HAVE_ISATTY
+ if ( 0 != isatty(fd) ) {
+ back = 1;
+ } else {
+ back = 0;
+ }
+#else
+#if DK4_HAVE__ISATTY
+ if ( 0 != _isatty(fd) ) {
+ back = 1;
+ } else {
+ back = 0;
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+#endif
+ return back;
+}
+
+
+
+int
+dk4istty_file(FILE *fipo, dk4_er_t *erp)
+{
+ int back = -1;
+ if (NULL != fipo) {
+#if DK4_HAVE_FILENO
+ back = dk4istty(fileno(fipo), erp);
+#else
+#if DK4_HAVE__FILENO
+ back = dk4istty(_fileno(fipo), erp);
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4istty.h b/support/dktools/dk4istty.h
new file mode 100644
index 0000000000..b7280d331a
--- /dev/null
+++ b/support/dktools/dk4istty.h
@@ -0,0 +1,101 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4istty.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4ISTTY_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4ISTTY_H_INCLUDED 1
+
+
+#line 10 "dk4istty.ctr"
+
+/** @file
+ Check whether a file pointer
+ is connected to a terminal.
+
+ CRT on Windows: Required.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef STDIO_H_INCLUDED
+#include <stdio.h>
+#define STDIO_H_INCLUDED 1
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Check whether the file descriptor is connected to a
+ tty (terminal, printer, serial line).
+ @param fd File descriptor to check.
+ @param erp Error report, may be NULL.
+ @return 1 for tty, 0 for other file descriptor, -1 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ if not isatty() or _isatty() function available on the system.
+*/
+int
+dk4istty(int fd, dk4_er_t *erp);
+
+/** Check whether a FILE pointer is connected to a tty
+ (terminal, printer, serial line).
+ @param fipo FILE to check.
+ @param erp Error report, may be NULL.
+ @return 1 for tty, 0 for other file descriptor, -1 on error.
+*/
+int
+dk4istty_file(FILE *fipo, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4loc.c b/support/dktools/dk4loc.c
new file mode 100644
index 0000000000..df93e3a331
--- /dev/null
+++ b/support/dktools/dk4loc.c
@@ -0,0 +1,374 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4loc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4loc.c The dk4loc module.
+*/
+
+
+#line 67 "dk4loc.ctr"
+
+#include "dk4loc.h"
+
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_CTYPE_H
+#ifndef CTYPE_H_INCLUDED
+#include <ctype.h>
+#define CTYPE_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef DK4ENC_H_INCLUDED
+#include "dk4enc.h"
+#endif
+
+#ifndef DK4STR8_H_INCLUDED
+#include "dk4str8.h"
+#endif
+
+#if DK4_ON_WINDOWS
+
+#ifndef DK4WREG8_H_INCLUDED
+#include "dk4wreg8.h"
+#endif
+#ifndef DK4WREGC_H_INCLUDED
+#include "dk4wregc.h"
+#endif
+
+#endif
+
+
+
+
+#line 110 "dk4loc.ctr"
+
+
+
+/** Keywords used by the module.
+*/
+static const char * const dk4loc_mod_kw_8[] = {
+/* 0 */
+"LANG",
+
+/* 1 */
+"utf8",
+
+/* 2 */
+"UTF-8",
+
+/* 3 */
+"Control Panel\\International",
+
+/* 4 */
+"LocaleName",
+
+/* 5 */
+"sLanguage",
+
+NULL
+
+
+#line 133 "dk4loc.ctr"
+};
+
+
+
+static
+int
+dk4loc_use_default(dkChar *lptr, size_t szl, dk4_er_t *erp)
+{
+ int back = 0;
+ if ((NULL != lptr) && (2 < szl)) {
+ lptr[0] = dkT('e');
+ lptr[1] = dkT('n');
+ lptr[2] = dkT('\0');
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ return back;
+}
+
+
+int
+dk4loc_get_settings(
+ dkChar *lang,
+ size_t szlang,
+ dkChar *reg,
+ size_t szreg,
+ int *enc,
+ dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+ char buf[64]; /* Buffer to process getenv result */
+ void *kptr; /* Registry key pointer */
+ dkChar *pd; /* Copy string */
+ char *p3; /* Region */
+ char *p4; /* Copy string */
+ size_t sz; /* String length */
+ int res; /* Result from RegQueryValueEx() */
+ int expand = 0; /* Flag: Expansion necessary. */
+#else
+ char buf[64]; /* Buffer to process getenv result */
+ dkChar *pd; /* Copy string */
+ char *p1; /* Result from getenv */
+ char *p2; /* Encoding */
+ char *p3; /* Region */
+ char *p4; /* Copy string */
+ size_t sz; /* String length */
+#endif
+ int back = 0;
+
+
+#line 184 "dk4loc.ctr"
+ if ((NULL != lang) && (0 < szlang)) { *lang = dkT('\0'); }
+ if ((NULL != reg ) && (0 < szreg )) { *reg = dkT('\0'); }
+ if (NULL != enc) { *enc = DK4_ENCODING_ASCII; }
+ if ((NULL != lang) && (NULL != reg) && (NULL != enc)) {
+ if ((0 < szlang) && (0 < szreg)) {
+#if DK4_ON_WINDOWS
+#if DK4_CHAR_SIZE > 1
+ *enc = DK4_ENCODING_UTF16;
+#else
+ *enc = DK4_ENCODING_ASCII;
+#endif
+ kptr = dk4wreg_open_key_c8(DK4_WREGKEY_HKCU, dk4loc_mod_kw_8[3], 0, erp);
+ if (NULL != kptr) {
+ res = dk4wreg_get_string_c8(
+ kptr, dk4loc_mod_kw_8[4], buf, sizeof(buf), &expand, erp
+ );
+ if (0 != res) {
+ p3 = dk4str8_chr(buf, '-');
+ if (NULL != p3) { *(p3++) = '\0'; }
+ dk4str8_normalize(buf, NULL);
+ if (NULL != p3) { dk4str8_normalize(p3, NULL); }
+ sz = dk4str8_len(buf);
+ if (0 < sz) {
+ if (szlang > sz) {
+ /* strcpy(lang, buf); */
+ pd = lang; p4 = buf;
+ while('\0' != *p4) {
+ *(pd++) = (dkChar)dk4str8_tolower(*(p4++));
+ }
+ *pd = dkT('\0');
+ back = 1;
+ sz = dk4str8_len(p3);
+ if (0 < sz) {
+ if (szreg > sz) {
+ /* strcpy(reg, p3); */
+ pd = reg; p4 = p3;
+ while('\0' != *p4) {
+#if 0
+ *(pd++) = (dkChar)(tolower((unsigned char)(*(p4++))));
+#endif
+ *(pd++) = (dkChar)dk4str8_tolower(*(p4++));
+ }
+ *pd = dkT('\0');
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ back = 0;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ back = dk4loc_use_default(lang, szlang, erp);
+ }
+ } else {
+ res = dk4wreg_get_string_c8(
+ kptr, dk4loc_mod_kw_8[5], buf, sizeof(buf), &expand, erp
+ );
+ if (0 != res) {
+ dk4str8_normalize(buf, NULL);
+ sz = dk4str8_len(buf);
+ if (2 < sz) { buf[2] = '\0'; }
+ sz = dk4str8_len(buf);
+ if (0 < sz) {
+ if (szlang > sz) {
+ pd = lang; p4 = buf;
+ while ('\0' != *p4) {
+ *(pd++) = (dkChar)(tolower((unsigned char)(*(p4++))));
+ }
+ *pd = dkT('\0');
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ back = dk4loc_use_default(lang, szlang, erp);
+ }
+ } else {
+ back = dk4loc_use_default(lang, szlang, erp);
+ }
+ }
+ dk4wreg_close_key(kptr);
+ } else {
+ back = dk4loc_use_default(lang, szlang, erp);
+ }
+#else
+ p1 = getenv(dk4loc_mod_kw_8[0]);
+ if (NULL != p1) {
+
+#line 272 "dk4loc.ctr"
+ if (sizeof(buf) > dk4str8_len(p1)) {
+
+#line 273 "dk4loc.ctr"
+ dk4str8_cpy_s(buf, sizeof(buf), p1, NULL);
+ p2 = dk4str8_chr(buf, '.');
+ if (NULL != p2) {
+
+#line 276 "dk4loc.ctr"
+ *(p2++) = '\0';
+
+#line 277 "dk4loc.ctr"
+ }
+ p3 = dk4str8_chr(buf, '_');
+ if (NULL != p3) {
+
+#line 280 "dk4loc.ctr"
+ *(p3++) = '\0';
+
+#line 281 "dk4loc.ctr"
+ }
+
+#line 282 "dk4loc.ctr"
+ dk4str8_normalize(buf, NULL);
+
+#line 283 "dk4loc.ctr"
+ if (NULL != p2) { dk4str8_normalize(p2, NULL); }
+ if (NULL != p3) { dk4str8_normalize(p3, NULL); }
+ sz = dk4str8_len(buf);
+
+#line 286 "dk4loc.ctr"
+ if (0 < sz) {
+ if (szlang > sz) {
+ /* strcpy(lang, buf); */
+ pd = lang; p4 = buf;
+ while('\0' != *p4) {
+ *(pd++) = (dkChar)(tolower((unsigned char)(*(p4++))));
+ }
+ *pd = dkT('\0');
+ back = 1;
+ if (NULL != p3) {
+ sz = dk4str8_len(p3);
+ if (0 < sz) {
+ if (szreg > sz) {
+ /* strcpy(reg, p3); */
+ pd = reg; p4 = p3;
+ while('\0' != *p4) {
+ *(pd++) = (dkChar)(tolower((unsigned char)(*(p4++))));
+ }
+ *pd = dkT('\0');
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ back = 0;
+ }
+ }
+ }
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+
+
+#line 314 "dk4loc.ctr"
+ *enc = DK4_ENCODING_32;
+#else
+
+
+#line 317 "dk4loc.ctr"
+ *enc = DK4_ENCODING_UTF16;
+#endif
+#else
+
+
+#line 321 "dk4loc.ctr"
+ *enc = DK4_ENCODING_ASCII;
+ if (NULL != p2) {
+ if (0 == dk4str8_casecmp(p2, dk4loc_mod_kw_8[1])) {
+ *enc = DK4_ENCODING_UTF8;
+ } else {
+ if (0 == dk4str8_casecmp(p2, dk4loc_mod_kw_8[2])) {
+ *enc = DK4_ENCODING_UTF8;
+ }
+ }
+ }
+#endif
+ } else {
+
+#line 333 "dk4loc.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+
+#line 336 "dk4loc.ctr"
+ back = dk4loc_use_default(lang, szlang, erp);
+ }
+ } else {
+
+#line 339 "dk4loc.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+
+#line 342 "dk4loc.ctr"
+ back = dk4loc_use_default(lang, szlang, erp);
+ }
+#endif
+ } else {
+
+#line 346 "dk4loc.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+
+#line 349 "dk4loc.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 351 "dk4loc.ctr"
+ return back;
+}
+
diff --git a/support/dktools/dk4loc.ctr b/support/dktools/dk4loc.ctr
new file mode 100644
index 0000000000..ea7ec2ede5
--- /dev/null
+++ b/support/dktools/dk4loc.ctr
@@ -0,0 +1,353 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Get language, region and encoding.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve localization settings.
+ @param lang Result buffer for language name.
+ @param szlang Size of result buffer (number of dkChar).
+ @param reg Result buffer for region or country name.
+ @param szreg Size of result buffer (number of dkChar).
+ @param enc Address of result variable for encoding.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if one of lang, reg or enc is NULL or szlang or szreg is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if one of the involved buffers is too small,
+*/
+int
+dk4loc_get_settings(
+ dkChar *lang,
+ size_t szlang,
+ dkChar *reg,
+ size_t szreg,
+ int *enc,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4loc.h"
+
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_CTYPE_H
+#ifndef CTYPE_H_INCLUDED
+#include <ctype.h>
+#define CTYPE_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef DK4ENC_H_INCLUDED
+#include "dk4enc.h"
+#endif
+
+#ifndef DK4STR8_H_INCLUDED
+#include "dk4str8.h"
+#endif
+
+#if DK4_ON_WINDOWS
+
+#ifndef DK4WREG8_H_INCLUDED
+#include "dk4wreg8.h"
+#endif
+#ifndef DK4WREGC_H_INCLUDED
+#include "dk4wregc.h"
+#endif
+
+#endif
+
+
+$!trace-include
+
+
+
+/** Keywords used by the module.
+*/
+static const char * const dk4loc_mod_kw_8[] = {
+$!string-table
+#
+# 0 Environment variable name for Linux/Unix.
+#
+LANG
+#
+# 1 2 Encoding names for UTF-8
+#
+utf8
+UTF-8
+#
+# 3 4 5 Registry key and entry for localization
+#
+Control Panel\\International
+LocaleName
+sLanguage
+$!end
+};
+
+
+
+static
+int
+dk4loc_use_default(dkChar *lptr, size_t szl, dk4_er_t *erp)
+{
+ int back = 0;
+ if ((NULL != lptr) && (2 < szl)) {
+ lptr[0] = dkT('e');
+ lptr[1] = dkT('n');
+ lptr[2] = dkT('\0');
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ return back;
+}
+
+
+int
+dk4loc_get_settings(
+ dkChar *lang,
+ size_t szlang,
+ dkChar *reg,
+ size_t szreg,
+ int *enc,
+ dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+ char buf[64]; /* Buffer to process getenv result */
+ void *kptr; /* Registry key pointer */
+ dkChar *pd; /* Copy string */
+ char *p3; /* Region */
+ char *p4; /* Copy string */
+ size_t sz; /* String length */
+ int res; /* Result from RegQueryValueEx() */
+ int expand = 0; /* Flag: Expansion necessary. */
+#else
+ char buf[64]; /* Buffer to process getenv result */
+ dkChar *pd; /* Copy string */
+ char *p1; /* Result from getenv */
+ char *p2; /* Encoding */
+ char *p3; /* Region */
+ char *p4; /* Copy string */
+ size_t sz; /* String length */
+#endif
+ int back = 0;
+ $? "+ dk4loc_get_settings %d %u %d %u %d %d", TR_IPTR(lang), (unsigned)szlang, TR_IPTR(reg), (unsigned)szreg, TR_IPTR(enc), TR_IPTR(erp)
+ if ((NULL != lang) && (0 < szlang)) { *lang = dkT('\0'); }
+ if ((NULL != reg ) && (0 < szreg )) { *reg = dkT('\0'); }
+ if (NULL != enc) { *enc = DK4_ENCODING_ASCII; }
+ if ((NULL != lang) && (NULL != reg) && (NULL != enc)) {
+ if ((0 < szlang) && (0 < szreg)) {
+#if DK4_ON_WINDOWS
+#if DK4_CHAR_SIZE > 1
+ *enc = DK4_ENCODING_UTF16;
+#else
+ *enc = DK4_ENCODING_ASCII;
+#endif
+ kptr = dk4wreg_open_key_c8(DK4_WREGKEY_HKCU, dk4loc_mod_kw_8[3], 0, erp);
+ if (NULL != kptr) {
+ res = dk4wreg_get_string_c8(
+ kptr, dk4loc_mod_kw_8[4], buf, sizeof(buf), &expand, erp
+ );
+ if (0 != res) {
+ p3 = dk4str8_chr(buf, '-');
+ if (NULL != p3) { *(p3++) = '\0'; }
+ dk4str8_normalize(buf, NULL);
+ if (NULL != p3) { dk4str8_normalize(p3, NULL); }
+ sz = dk4str8_len(buf);
+ if (0 < sz) {
+ if (szlang > sz) {
+ /* strcpy(lang, buf); */
+ pd = lang; p4 = buf;
+ while('\0' != *p4) {
+ *(pd++) = (dkChar)dk4str8_tolower(*(p4++));
+ }
+ *pd = dkT('\0');
+ back = 1;
+ sz = dk4str8_len(p3);
+ if (0 < sz) {
+ if (szreg > sz) {
+ /* strcpy(reg, p3); */
+ pd = reg; p4 = p3;
+ while('\0' != *p4) {
+#if 0
+ *(pd++) = (dkChar)(tolower((unsigned char)(*(p4++))));
+#endif
+ *(pd++) = (dkChar)dk4str8_tolower(*(p4++));
+ }
+ *pd = dkT('\0');
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ back = 0;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ back = dk4loc_use_default(lang, szlang, erp);
+ }
+ } else {
+ res = dk4wreg_get_string_c8(
+ kptr, dk4loc_mod_kw_8[5], buf, sizeof(buf), &expand, erp
+ );
+ if (0 != res) {
+ dk4str8_normalize(buf, NULL);
+ sz = dk4str8_len(buf);
+ if (2 < sz) { buf[2] = '\0'; }
+ sz = dk4str8_len(buf);
+ if (0 < sz) {
+ if (szlang > sz) {
+ pd = lang; p4 = buf;
+ while ('\0' != *p4) {
+ *(pd++) = (dkChar)(tolower((unsigned char)(*(p4++))));
+ }
+ *pd = dkT('\0');
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ back = dk4loc_use_default(lang, szlang, erp);
+ }
+ } else {
+ back = dk4loc_use_default(lang, szlang, erp);
+ }
+ }
+ dk4wreg_close_key(kptr);
+ } else {
+ back = dk4loc_use_default(lang, szlang, erp);
+ }
+#else
+ p1 = getenv(dk4loc_mod_kw_8[0]);
+ if (NULL != p1) { $? ". getenv ok"
+ if (sizeof(buf) > dk4str8_len(p1)) { $? ". length ok"
+ dk4str8_cpy_s(buf, sizeof(buf), p1, NULL);
+ p2 = dk4str8_chr(buf, '.');
+ if (NULL != p2) { $? ". p2 has encoding"
+ *(p2++) = '\0'; $? ". encoding \"%!8s\"", p2
+ }
+ p3 = dk4str8_chr(buf, '_');
+ if (NULL != p3) { $? ". p3 has region"
+ *(p3++) = '\0'; $? ". region \"%!8s\"", p3
+ } $? ". language \"%!8s\"", buf
+ dk4str8_normalize(buf, NULL); $? ". normalized"
+ if (NULL != p2) { dk4str8_normalize(p2, NULL); }
+ if (NULL != p3) { dk4str8_normalize(p3, NULL); }
+ sz = dk4str8_len(buf); $? ". buf lgt %u", (unsigned)sz
+ if (0 < sz) {
+ if (szlang > sz) {
+ /* strcpy(lang, buf); */
+ pd = lang; p4 = buf;
+ while('\0' != *p4) {
+ *(pd++) = (dkChar)(tolower((unsigned char)(*(p4++))));
+ }
+ *pd = dkT('\0');
+ back = 1;
+ if (NULL != p3) {
+ sz = dk4str8_len(p3);
+ if (0 < sz) {
+ if (szreg > sz) {
+ /* strcpy(reg, p3); */
+ pd = reg; p4 = p3;
+ while('\0' != *p4) {
+ *(pd++) = (dkChar)(tolower((unsigned char)(*(p4++))));
+ }
+ *pd = dkT('\0');
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ back = 0;
+ }
+ }
+ }
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ $? ". 32 bit"
+ *enc = DK4_ENCODING_32;
+#else
+ $? ". 16 bit"
+ *enc = DK4_ENCODING_UTF16;
+#endif
+#else
+ $? ". 8 bit"
+ *enc = DK4_ENCODING_ASCII;
+ if (NULL != p2) {
+ if (0 == dk4str8_casecmp(p2, dk4loc_mod_kw_8[1])) {
+ *enc = DK4_ENCODING_UTF8;
+ } else {
+ if (0 == dk4str8_casecmp(p2, dk4loc_mod_kw_8[2])) {
+ *enc = DK4_ENCODING_UTF8;
+ }
+ }
+ }
+#endif
+ } else { $? "! LANG too long"
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else { $? "! zero length LANG"
+ back = dk4loc_use_default(lang, szlang, erp);
+ }
+ } else { $? "! LANG env too long"
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else { $? "! getenv"
+ back = dk4loc_use_default(lang, szlang, erp);
+ }
+#endif
+ } else { $? "! invalid args"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else { $? "! invalid args"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4loc_get_settings %d", back
+ return back;
+}
+
diff --git a/support/dktools/dk4loc.h b/support/dktools/dk4loc.h
new file mode 100644
index 0000000000..5731463edc
--- /dev/null
+++ b/support/dktools/dk4loc.h
@@ -0,0 +1,99 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4loc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4LOC_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4LOC_H_INCLUDED 1
+
+
+#line 10 "dk4loc.ctr"
+
+/** @file
+ Get language, region and encoding.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve localization settings.
+ @param lang Result buffer for language name.
+ @param szlang Size of result buffer (number of dkChar).
+ @param reg Result buffer for region or country name.
+ @param szreg Size of result buffer (number of dkChar).
+ @param enc Address of result variable for encoding.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if one of lang, reg or enc is NULL or szlang or szreg is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if one of the involved buffers is too small,
+*/
+int
+dk4loc_get_settings(
+ dkChar *lang,
+ size_t szlang,
+ dkChar *reg,
+ size_t szreg,
+ int *enc,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4lprng.h b/support/dktools/dk4lprng.h
new file mode 100644
index 0000000000..02d94a798b
--- /dev/null
+++ b/support/dktools/dk4lprng.h
@@ -0,0 +1,63 @@
+#ifndef DK4LPRNG_H_INCLUDED
+/** Protection against multiple inclusion.
+*/
+#define DK4LPRNG_H_INCLUDED 1
+
+/** @file dk4lprng.h Constant values related to LPRng.
+*/
+
+/** Exit status codes defined by the LPRng print system.
+*/
+enum {
+ /** Success.
+ */
+ LPRNG_EXIT_SUCCESS = 0 ,
+
+ /** Transient error condition, retry later.
+ */
+ LPRNG_EXIT_FAILURE = 1 , /* alternative: 32 */
+
+ /** Abort, terminate queue processing.
+ Unprocessable print data found, remove
+ job from queue.
+ */
+ LPRNG_EXIT_ABORT = 2 , /* alternative: 33 */
+
+ /** Unrecoverable error, remove job from queue.
+ Use for permission and quota problems.
+ */
+ LPRNG_EXIT_REMOVE = 3 , /* alternative: 34 */
+
+ /** Hold job for later processing.
+ Typically used if resources are not available.
+ */
+ LPRNG_EXIT_HOLD = 6 , /* alternative: 37 */
+
+ /** No spooling to this queue.
+ Used by load balancing.
+ */
+ LPRNG_EXIT_NOSPOOL = 7 , /* alternative: 38 */
+
+ /** No printing from this queue.
+ Used by load balancing.
+ */
+ LPRNG_EXIT_NOPRINT = 8 , /* alternative: 39 */
+
+ /** Interrupted by signal.
+ Signal or non-restartable system failure.
+ */
+ LPRNG_EXIT_SIGNAL = 9 , /* alternative: 40 */
+
+ /** Failed, do not retry.
+ */
+ LPRNG_EXIT_FAILNOR = 10, /* alternative: 41 */
+};
+
+
+/** As long as we have not changed printqd we need the job name
+ in accounting.
+*/
+#define ACCOUNTING_WITH_JOB_NAME 1
+
+
+#endif
diff --git a/support/dktools/dk4lzwe.c b/support/dktools/dk4lzwe.c
new file mode 100644
index 0000000000..6946a4f81e
--- /dev/null
+++ b/support/dktools/dk4lzwe.c
@@ -0,0 +1,580 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4lzwe.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4lzwe.c The dk4lzwe module.
+*/
+
+
+#line 179 "dk4lzwe.ctr"
+
+
+#include "dk4lzwe.h"
+#include "dk4mem.h"
+#include "dk4edstm.h"
+
+
+
+
+
+#line 188 "dk4lzwe.ctr"
+
+
+
+/** Code to clear tables.
+*/
+#define LZW_CLT ((unsigned short)256U)
+
+
+
+/** Code to indicate end of data.
+*/
+#define LZW_EOD ((unsigned short)257U)
+
+
+
+/** First user-made state.
+*/
+#define LZW_START ((unsigned short)258U)
+
+
+
+/** Bitmask values.
+*/
+static const unsigned short bit_values[] = {
+ 0x0001U, 0x0002U, 0x0004U, 0x0008U, 0x0010U, 0x0020U, 0x0040U, 0x0080U,
+ 0x0100U, 0x0200U, 0x0400U, 0x0800U, 0x1000U, 0x2000U, 0x4000U, 0x8000U
+};
+
+
+
+/** Write bit sequence to output buffer.
+ @param lzwptr LZW compression structure.
+ @param val Bit sequence to write.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the output buffer is full before finishing,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ should not happen.
+*/
+static
+int
+dk4lzwe_shipout(
+ dk4_lzwe_t *lzwptr,
+ unsigned short val,
+ dk4_er_t *erp
+)
+{
+ int back = 1;
+ int res;
+ unsigned short i;
+ unsigned char uc;
+
+
+
+#line 244 "dk4lzwe.ctr"
+ i = lzwptr->bits;
+ while (0 < i--) {
+ res = dk4bit_shift_add(
+ &(lzwptr->bs),
+ ((((unsigned short)0) != (val & bit_values[i])) ? (1) : (0)),
+ NULL
+ );
+ switch (res) {
+ case DK4_EDSTM_ERROR : {
+
+#line 253 "dk4lzwe.ctr"
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ } break;
+ case DK4_EDSTM_FINISHED : {
+
+#line 257 "dk4lzwe.ctr"
+ uc = dk4bit_shift_output(&(lzwptr->bs), NULL);
+ if (8 > lzwptr->obu) {
+
+#line 259 "dk4lzwe.ctr"
+ lzwptr->ob[lzwptr->obu] = uc;
+ lzwptr->obu += 1;
+ }
+ else {
+
+#line 263 "dk4lzwe.ctr"
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } break;
+ }
+ }
+
+
+#line 270 "dk4lzwe.ctr"
+ return back;
+}
+
+
+
+/** Clear all table entries.
+ @param lzwptr Encoder to clean up.
+*/
+static
+void
+dk4lzwe_clear_table_entries(
+ dk4_lzwe_t *lzwptr
+)
+{
+ dk4_lzw_cell_t *cptr;
+ size_t i;
+
+
+#line 287 "dk4lzwe.ctr"
+ cptr = lzwptr->p_tbl;
+ for (i = 0; i < LZW_TABLE_SIZE; i++) {
+ cptr[i].os = (unsigned short)0U;
+ cptr[i].ns = (unsigned short)0U;
+ cptr[i].in = (unsigned char)0x00;
+ }
+
+
+#line 294 "dk4lzwe.ctr"
+}
+
+
+
+int
+dk4lzwe_init(
+ dk4_lzwe_t *lzwptr,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+
+
+#line 306 "dk4lzwe.ctr"
+ if (NULL != lzwptr) {
+
+#line 307 "dk4lzwe.ctr"
+ /*
+ Default values for al components
+ */
+ dk4mem_reset(lzwptr, sizeof(dk4_lzwe_t), NULL);
+ lzwptr->p_tbl = NULL;
+ lzwptr->obu = 0;
+ lzwptr->mret = 0;
+ lzwptr->hst = 0;
+ lzwptr->bits = 9;
+ lzwptr->cs = 0U;
+ lzwptr->ns = LZW_START;
+ dk4bit_shift_init(&(lzwptr->bs), NULL);
+ /*
+ Allocate memory for state transition table
+ */
+ lzwptr->p_tbl = dk4mem_new(dk4_lzw_cell_t,LZW_TABLE_SIZE,erp);
+ /*
+ On success ship out initial clear table marker
+ */
+ if (NULL != lzwptr->p_tbl) {
+
+#line 327 "dk4lzwe.ctr"
+ dk4lzwe_clear_table_entries(lzwptr);
+ back = dk4lzwe_shipout(lzwptr, LZW_CLT, erp);
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 332 "dk4lzwe.ctr"
+ }
+#endif
+ }
+ else {
+
+#line 336 "dk4lzwe.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 339 "dk4lzwe.ctr"
+ return back;
+}
+
+
+
+static
+int
+dk4lzwe_i_add(
+ dk4_lzwe_t *lzwptr,
+ unsigned char uc,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_EDSTM_ERROR;
+#if TRACE_DEBUG
+ int passno = 0;
+#endif
+ int cc;
+ int found;
+ unsigned short ind;
+ unsigned short offs;
+
+
+#line 361 "dk4lzwe.ctr"
+ if (0 != lzwptr->hst) {
+
+#line 362 "dk4lzwe.ctr"
+ /*
+ Already input available, so we have to check the table
+ for a matching rule
+ */
+ ind = (lzwptr->cs)
+ ^ ((((unsigned short)uc) << 4) & ((unsigned short)0x0FF0U));
+#if 0
+ ind = ind % LZW_TABLE_SIZE;
+#endif
+ offs = ((((unsigned short)0U) != ind) ? (LZW_TABLE_SIZE - ind) : (1));
+ cc = 1;
+ found = 0;
+
+#line 374 "dk4lzwe.ctr"
+ do {
+
+#line 375 "dk4lzwe.ctr"
+ if ((unsigned short)0U != (lzwptr->p_tbl)[ind].ns) {
+
+#line 376 "dk4lzwe.ctr"
+ if (lzwptr->cs == (lzwptr->p_tbl)[ind].os) {
+ if (uc == (lzwptr->p_tbl)[ind].in) {
+ found = 1;
+
+#line 379 "dk4lzwe.ctr"
+ }
+ }
+ if (0 != found) {
+ cc = 0;
+ }
+ else {
+
+#line 385 "dk4lzwe.ctr"
+ ind += offs;
+ ind = (ind % LZW_TABLE_SIZE);
+ }
+ }
+ else {
+
+#line 390 "dk4lzwe.ctr"
+ cc = 0;
+ }
+#if TRACE_DEBUG
+ passno++;
+#endif
+ } while (0 < cc);
+
+#line 396 "dk4lzwe.ctr"
+#if TRACE_DEBUG
+
+
+#line 398 "dk4lzwe.ctr"
+#endif
+ if (0 != found) {
+
+#line 400 "dk4lzwe.ctr"
+ /*
+ A matching rule was found, so we just change state.
+ */
+ lzwptr->cs = (lzwptr->p_tbl)[ind].ns;
+ back = DK4_EDSTM_ACCEPT;
+ }
+ else {
+
+#line 407 "dk4lzwe.ctr"
+ /* No matching rule was found.
+ We check whether or not we can add further entries to
+ the table.
+ */
+ if ((unsigned short)4094U <= lzwptr->ns) {
+
+#line 412 "dk4lzwe.ctr"
+ /*
+ Table is full, so we ship out the current state,
+ clean we table and keep the input as new current state.
+ */
+ if (0 != dk4lzwe_shipout(lzwptr, lzwptr->cs, erp)) {
+ if (0 != dk4lzwe_shipout(lzwptr, LZW_CLT, erp)) {
+ back = DK4_EDSTM_FINISHED;
+
+#line 419 "dk4lzwe.ctr"
+ lzwptr->mret = 1;
+ }
+ }
+ lzwptr->cs = (((unsigned short)0x00FFU) & ((unsigned short)uc));
+ lzwptr->bits = 9;
+ lzwptr->ns = LZW_START;
+ dk4lzwe_clear_table_entries(lzwptr);
+ }
+ else {
+
+#line 428 "dk4lzwe.ctr"
+ /* There is still room in the table.
+ Ship out current state, create new rule in the
+ table and keep input as new current state.
+ */
+ if (0 != dk4lzwe_shipout(lzwptr, lzwptr->cs, erp)) {
+ back = DK4_EDSTM_FINISHED;
+
+#line 434 "dk4lzwe.ctr"
+ lzwptr->mret = 1;
+ }
+ (lzwptr->p_tbl)[ind].os = lzwptr->cs;
+ (lzwptr->p_tbl)[ind].ns = lzwptr->ns;
+ (lzwptr->p_tbl)[ind].in = uc;
+
+
+#line 440 "dk4lzwe.ctr"
+ /*
+ Increase number of bits if necessary.
+ */
+ switch ( (int)(lzwptr->ns) ) {
+ case 511 : {
+
+#line 445 "dk4lzwe.ctr"
+ lzwptr->bits = 10;
+ } break;
+ case 1023 : {
+ lzwptr->bits = 11;
+
+#line 449 "dk4lzwe.ctr"
+ } break;
+ case 2047 : {
+ lzwptr->bits = 12;
+
+#line 452 "dk4lzwe.ctr"
+ } break;
+ }
+ lzwptr->ns += 1U;
+ lzwptr->cs = (((unsigned short)0x00FFU) & ((unsigned short)uc));
+ }
+ }
+ }
+ else {
+
+#line 460 "dk4lzwe.ctr"
+ /* No current state yet (no input yet).
+ Just store the input as current state.
+ */
+ lzwptr->cs = (((unsigned short)0x00FFU) & ((unsigned short)uc));
+ lzwptr->hst = 1;
+ back = DK4_EDSTM_ACCEPT;
+ }
+
+
+#line 468 "dk4lzwe.ctr"
+ return back;
+}
+
+
+
+int
+dk4lzwe_add(
+ dk4_lzwe_t *lzwptr,
+ unsigned char uc,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_EDSTM_ERROR;
+
+
+#line 482 "dk4lzwe.ctr"
+ if (NULL != lzwptr) {
+ if (NULL != lzwptr->p_tbl) {
+ if (0 == lzwptr->mret) {
+ back = dk4lzwe_i_add(lzwptr, uc, erp);
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 499 "dk4lzwe.ctr"
+ return back;
+}
+
+
+
+int
+dk4lzwe_finish(
+ dk4_lzwe_t *lzwptr,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_EDSTM_ERROR;
+ unsigned char uc;
+
+
+#line 513 "dk4lzwe.ctr"
+ if (NULL != lzwptr) {
+ if (NULL != lzwptr->p_tbl) {
+ if (0 == lzwptr->mret) {
+ back = DK4_EDSTM_ACCEPT;
+ /*
+ Ship out current state, if any.
+ */
+ if (0 != lzwptr->hst) {
+
+#line 521 "dk4lzwe.ctr"
+ if (0 == dk4lzwe_shipout(lzwptr, lzwptr->cs, erp)) {
+ back = DK4_EDSTM_ERROR;
+
+#line 523 "dk4lzwe.ctr"
+ }
+ }
+ /* Ship out end of data marker.
+ */
+ if (0 == dk4lzwe_shipout(lzwptr, LZW_EOD, erp)) {
+ back = DK4_EDSTM_ERROR;
+
+#line 529 "dk4lzwe.ctr"
+ }
+ /* Apply final byte from bit shifter to output.
+ */
+ switch ( dk4bit_shift_finish(&(lzwptr->bs), erp)) {
+ case DK4_EDSTM_ERROR : {
+ back = DK4_EDSTM_ERROR;
+
+#line 535 "dk4lzwe.ctr"
+ } break;
+ case DK4_EDSTM_FINISHED : {
+ uc = dk4bit_shift_output(&(lzwptr->bs), NULL);
+ if (8 > lzwptr->obu) {
+
+#line 539 "dk4lzwe.ctr"
+ lzwptr->ob[lzwptr->obu] = uc;
+ lzwptr->obu += 1;
+ }
+ else {
+
+#line 543 "dk4lzwe.ctr"
+ back = DK4_EDSTM_ERROR;
+ dk4error_set_simple_error_code(
+ erp, DK4_E_BUFFER_TOO_SMALL
+ );
+ }
+ } break;
+ }
+ /* Check whether the caller must retrieve final output.
+ */
+ if ((DK4_EDSTM_ACCEPT == back) && (0 < lzwptr->obu)) {
+ back = DK4_EDSTM_FINISHED;
+
+#line 554 "dk4lzwe.ctr"
+ lzwptr->mret = 1;
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ dk4mem_free(lzwptr->p_tbl);
+ lzwptr->p_tbl = NULL;
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 571 "dk4lzwe.ctr"
+ return back;
+}
+
+
+
+int
+dk4lzwe_output(
+ const unsigned char **dptr,
+ size_t *szptr,
+ dk4_lzwe_t *lzwptr,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+
+
+#line 586 "dk4lzwe.ctr"
+ if ((NULL != dptr) && (NULL != szptr) && (NULL != lzwptr)) {
+ /*
+ All arguments ok, do normal output operation.
+ */
+ *dptr = &(lzwptr->ob[0]);
+ *szptr = lzwptr->obu;
+ back = ((0 < lzwptr->obu) ? (1) : (0));
+ lzwptr->mret = 0;
+
+#line 594 "dk4lzwe.ctr"
+ lzwptr->obu = 0;
+ }
+ else {
+
+#line 597 "dk4lzwe.ctr"
+ /*
+ Argument error, indicate no data available.
+ */
+ if (NULL != dptr) {
+ *dptr = NULL;
+ }
+ if (NULL != szptr) {
+ *szptr = 0;
+ }
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 609 "dk4lzwe.ctr"
+ return back;
+}
+
+
+/* vim: set ai sw=4 ts=4 : */
+
diff --git a/support/dktools/dk4lzwe.ctr b/support/dktools/dk4lzwe.ctr
new file mode 100644
index 0000000000..d38a83fbd8
--- /dev/null
+++ b/support/dktools/dk4lzwe.ctr
@@ -0,0 +1,614 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+%% header
+
+/** @file dk4lzwe.h LZW encoder to produce PS level 2 output.
+
+- The unit length (input data length) is 8 bits.
+- Code 256 is used for table cleanup, 257 is the end of data marker.
+- EarlyChange is in use: the number of bits per code is increased after
+ creating table entries for codes 511, 1023 and 2047.
+- Table entries are created for codes up to 4093. Instead of generating
+ an entry for 4094, the table is cleared.
+*/
+
+#ifndef DK4ERROR_H_INCLUDED
+#include <dk4error.h>
+#endif
+
+#ifndef DK4BITSH_H_INCLUDED
+#include <dk4bitsh.h>
+#endif
+
+
+
+/** Table size.
+ The table must be large enough to keep 4096 entries. Adding
+ 25 percent size significantly decreases the number of lookups.
+ A prime number is required to ensure traversal of the entire
+ table if necessary.
+*/
+enum {
+ LZW_TABLE_SIZE = 5147 /**< Size of LZW compression table. */
+};
+
+
+
+/** One table entry for LZW compression.
+*/
+typedef struct {
+ unsigned short os; /**< Current (old) state or code. */
+ unsigned short ns; /**< New state after applying input. */
+ unsigned char in; /**< Input byte. */
+} dk4_lzw_cell_t;
+
+
+
+/** LZW encoder structure.
+*/
+typedef struct {
+ unsigned char ob[8]; /**< Output buffer. */
+ dk4_bit_shift_t bs; /**< Bit shifter. */
+ dk4_lzw_cell_t *p_tbl; /**< Pointer to dynamically allocated table. */
+ size_t obu; /**< Used bytes in output buffer. */
+ int mret; /**< Flag: Must retrieve output data. */
+ int hst; /**< Flag: Have internal state. */
+ unsigned short bits; /**< Number of bits to use for output. */
+ unsigned short cs; /**< Current state. */
+ unsigned short ns; /**< Next state for new table entry. */
+} dk4_lzwe_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** Initialize LZW encoder, allocate memory for resources.
+ @param lzwptr Encoder to initialize.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if lzwptr is NULL,
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow when calculating the
+ product of elsize and nelem,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available,
+ - DK4_E_BUG<br>
+ if the dk4bit_shift_add() call indicates an error
+ (should not happen as we provide a valid address to the function),
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the output buffer is already full. Typically this means
+ that output was not retrieved as expected by the library.
+*/
+
+int
+dk4lzwe_init(
+ dk4_lzwe_t *lzwptr,
+ dk4_er_t *erp
+);
+
+
+/** Add one byte to the encoder.
+ @param lzwptr Encoder to use.
+ @param uc Byte to add.
+ @param erp Error report, may be NULL.
+ @return Operation result, one from:
+ - DK4_EDSTM_ACCEPT<br>
+ if the input byte was successfully stored in the internal data
+ structures without completing a run. No further action
+ necessary.
+ - DK4_EDSTM_FINISHED<br>
+ if output was created. Use dk4lzwe_output() to obtain the
+ output data.
+ - DK4_EDSTM_ERROR<br>
+ if an error occured.
+*/
+
+int
+dk4lzwe_add(
+ dk4_lzwe_t *lzwptr,
+ unsigned char uc,
+ dk4_er_t *erp
+);
+
+
+/** Finish encoded data stream, flush internal state and bits from
+ the bit shifter to output buffer and release dynamic memory.
+ @param lzwptr Encoder to use.
+ @param erp Error report, may be NULL.
+ @return Operation result, one from:
+ - DK4_EDSTM_ACCEPT<br>
+ if the input byte was successfully stored in the internal data
+ structures without completing a run. No further action
+ necessary.
+ - DK4_EDSTM_FINISHED<br>
+ if output was created. Use dk4lzwe_output() to obtain the
+ output data.
+ - DK4_EDSTM_ERROR<br>
+ if an error occured.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if lzwptr is NULL or lzwptr->s_tbl or lzwptr->i_tbl is NULL,
+ - DK4_E_BUG<br>
+ if the dk4bit_shift_add() call indicates an error
+ (should not happen as we provide a valid address to the function),
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the output buffer is already full. Typically this means
+ that output was not retrieved as expected by the library.
+*/
+
+int
+dk4lzwe_finish(
+ dk4_lzwe_t *lzwptr,
+ dk4_er_t *erp
+);
+
+
+/** Retrieve output from encoder.
+ @param dptr Address of result pointer.
+ @param szptr Address of result size variable.
+ @param lzwptr Encoder to use.
+ @param erp Error report, may be NULL.
+ @return 1 if data available, 0 otherwise.
+*/
+
+int
+dk4lzwe_output(
+ const unsigned char **dptr,
+ size_t *szptr,
+ dk4_lzwe_t *lzwptr,
+ dk4_er_t *erp
+);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/* vim: set ai sw=4 ts=4 : */
+%% module
+
+
+#include "dk4lzwe.h"
+#include "dk4mem.h"
+#include "dk4edstm.h"
+
+
+
+$!trace-include
+
+
+
+/** Code to clear tables.
+*/
+#define LZW_CLT ((unsigned short)256U)
+
+
+
+/** Code to indicate end of data.
+*/
+#define LZW_EOD ((unsigned short)257U)
+
+
+
+/** First user-made state.
+*/
+#define LZW_START ((unsigned short)258U)
+
+
+
+/** Bitmask values.
+*/
+static const unsigned short bit_values[] = {
+ 0x0001U, 0x0002U, 0x0004U, 0x0008U, 0x0010U, 0x0020U, 0x0040U, 0x0080U,
+ 0x0100U, 0x0200U, 0x0400U, 0x0800U, 0x1000U, 0x2000U, 0x4000U, 0x8000U
+};
+
+
+
+/** Write bit sequence to output buffer.
+ @param lzwptr LZW compression structure.
+ @param val Bit sequence to write.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the output buffer is full before finishing,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ should not happen.
+*/
+static
+int
+dk4lzwe_shipout(
+ dk4_lzwe_t *lzwptr,
+ unsigned short val,
+ dk4_er_t *erp
+)
+{
+ int back = 1;
+ int res;
+ unsigned short i;
+ unsigned char uc;
+
+ $? "+ dk4lzwe_shipout %u/%u", (unsigned)val, (unsigned)(lzwptr->bits)
+ i = lzwptr->bits;
+ while (0 < i--) {
+ res = dk4bit_shift_add(
+ &(lzwptr->bs),
+ ((((unsigned short)0) != (val & bit_values[i])) ? (1) : (0)),
+ NULL
+ );
+ switch (res) {
+ case DK4_EDSTM_ERROR : { $? "! dk4bit_shift_add"
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ } break;
+ case DK4_EDSTM_FINISHED : { $? ". byte completed"
+ uc = dk4bit_shift_output(&(lzwptr->bs), NULL);
+ if (8 > lzwptr->obu) { $? ". saved to buffer"
+ lzwptr->ob[lzwptr->obu] = uc;
+ lzwptr->obu += 1;
+ }
+ else { $? "! buffer full"
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } break;
+ }
+ }
+ $? "- dk4lzwe_shipout %d", back
+ return back;
+}
+
+
+
+/** Clear all table entries.
+ @param lzwptr Encoder to clean up.
+*/
+static
+void
+dk4lzwe_clear_table_entries(
+ dk4_lzwe_t *lzwptr
+)
+{
+ dk4_lzw_cell_t *cptr;
+ size_t i;
+ $? "+ dk4lzwe_clear_table_entries"
+ cptr = lzwptr->p_tbl;
+ for (i = 0; i < LZW_TABLE_SIZE; i++) {
+ cptr[i].os = (unsigned short)0U;
+ cptr[i].ns = (unsigned short)0U;
+ cptr[i].in = (unsigned char)0x00;
+ }
+ $? "- dk4lzwe_clear_table_entries"
+}
+
+
+
+int
+dk4lzwe_init(
+ dk4_lzwe_t *lzwptr,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+ $? "+ dk4lzwe_init %d", TR_IPTR(lzwptr)
+ if (NULL != lzwptr) { $? ". lzwptr"
+ /*
+ Default values for al components
+ */
+ dk4mem_reset(lzwptr, sizeof(dk4_lzwe_t), NULL);
+ lzwptr->p_tbl = NULL;
+ lzwptr->obu = 0;
+ lzwptr->mret = 0;
+ lzwptr->hst = 0;
+ lzwptr->bits = 9;
+ lzwptr->cs = 0U;
+ lzwptr->ns = LZW_START;
+ dk4bit_shift_init(&(lzwptr->bs), NULL);
+ /*
+ Allocate memory for state transition table
+ */
+ lzwptr->p_tbl = dk4mem_new(dk4_lzw_cell_t,LZW_TABLE_SIZE,erp);
+ /*
+ On success ship out initial clear table marker
+ */
+ if (NULL != lzwptr->p_tbl) { $? ". p_tbl"
+ dk4lzwe_clear_table_entries(lzwptr);
+ back = dk4lzwe_shipout(lzwptr, LZW_CLT, erp);
+ }
+#if TRACE_DEBUG
+ else { $? "! p_tbl"
+ }
+#endif
+ }
+ else { $? "! lzwptr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4lzwe_init %d", back
+ return back;
+}
+
+
+
+static
+int
+dk4lzwe_i_add(
+ dk4_lzwe_t *lzwptr,
+ unsigned char uc,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_EDSTM_ERROR;
+#if TRACE_DEBUG
+ int passno = 0;
+#endif
+ int cc;
+ int found;
+ unsigned short ind;
+ unsigned short offs;
+ $? "+ dk4lzwe_i_add"
+ if (0 != lzwptr->hst) { $? ". already input"
+ /*
+ Already input available, so we have to check the table
+ for a matching rule
+ */
+ ind = (lzwptr->cs)
+ ^ ((((unsigned short)uc) << 4) & ((unsigned short)0x0FF0U));
+#if 0
+ ind = ind % LZW_TABLE_SIZE;
+#endif
+ offs = ((((unsigned short)0U) != ind) ? (LZW_TABLE_SIZE - ind) : (1));
+ cc = 1;
+ found = 0; $? ". start loop"
+ do { $? ". new pass"
+ if ((unsigned short)0U != (lzwptr->p_tbl)[ind].ns) { $? ". rule"
+ if (lzwptr->cs == (lzwptr->p_tbl)[ind].os) {
+ if (uc == (lzwptr->p_tbl)[ind].in) {
+ found = 1; $? ". matching rule"
+ }
+ }
+ if (0 != found) {
+ cc = 0;
+ }
+ else { $? ". next rule"
+ ind += offs;
+ ind = (ind % LZW_TABLE_SIZE);
+ }
+ }
+ else { $? ". empty rule"
+ cc = 0;
+ }
+#if TRACE_DEBUG
+ passno++;
+#endif
+ } while (0 < cc); $? ". loop finished"
+#if TRACE_DEBUG
+ $? ". passes=%d", passno
+#endif
+ if (0 != found) { $? ". rule found"
+ /*
+ A matching rule was found, so we just change state.
+ */
+ lzwptr->cs = (lzwptr->p_tbl)[ind].ns;
+ back = DK4_EDSTM_ACCEPT;
+ }
+ else { $? ". no rule found"
+ /* No matching rule was found.
+ We check whether or not we can add further entries to
+ the table.
+ */
+ if ((unsigned short)4094U <= lzwptr->ns) { $? ". table full, clean"
+ /*
+ Table is full, so we ship out the current state,
+ clean we table and keep the input as new current state.
+ */
+ if (0 != dk4lzwe_shipout(lzwptr, lzwptr->cs, erp)) {
+ if (0 != dk4lzwe_shipout(lzwptr, LZW_CLT, erp)) {
+ back = DK4_EDSTM_FINISHED; $? ". shipout ok"
+ lzwptr->mret = 1;
+ }
+ }
+ lzwptr->cs = (((unsigned short)0x00FFU) & ((unsigned short)uc));
+ lzwptr->bits = 9;
+ lzwptr->ns = LZW_START;
+ dk4lzwe_clear_table_entries(lzwptr);
+ }
+ else { $? ". add rule"
+ /* There is still room in the table.
+ Ship out current state, create new rule in the
+ table and keep input as new current state.
+ */
+ if (0 != dk4lzwe_shipout(lzwptr, lzwptr->cs, erp)) {
+ back = DK4_EDSTM_FINISHED; $? ". shipout ok"
+ lzwptr->mret = 1;
+ }
+ (lzwptr->p_tbl)[ind].os = lzwptr->cs;
+ (lzwptr->p_tbl)[ind].ns = lzwptr->ns;
+ (lzwptr->p_tbl)[ind].in = uc;
+ $? ". rule %u, %u => %u", (unsigned)((lzwptr->p_tbl)[ind].os), (unsigned)((lzwptr->p_tbl)[ind].in), (unsigned)((lzwptr->p_tbl)[ind].ns)
+ /*
+ Increase number of bits if necessary.
+ */
+ switch ( (int)(lzwptr->ns) ) {
+ case 511 : { $? ". bits=10"
+ lzwptr->bits = 10;
+ } break;
+ case 1023 : {
+ lzwptr->bits = 11; $? ". bits=11"
+ } break;
+ case 2047 : {
+ lzwptr->bits = 12; $? ". bits=12"
+ } break;
+ }
+ lzwptr->ns += 1U;
+ lzwptr->cs = (((unsigned short)0x00FFU) & ((unsigned short)uc));
+ }
+ }
+ }
+ else { $? ". no input yet"
+ /* No current state yet (no input yet).
+ Just store the input as current state.
+ */
+ lzwptr->cs = (((unsigned short)0x00FFU) & ((unsigned short)uc));
+ lzwptr->hst = 1;
+ back = DK4_EDSTM_ACCEPT;
+ }
+ $? "- dk4lzwe_i_add %d", back
+ return back;
+}
+
+
+
+int
+dk4lzwe_add(
+ dk4_lzwe_t *lzwptr,
+ unsigned char uc,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_EDSTM_ERROR;
+ $? "+ dk4lzwe_add"
+ if (NULL != lzwptr) {
+ if (NULL != lzwptr->p_tbl) {
+ if (0 == lzwptr->mret) {
+ back = dk4lzwe_i_add(lzwptr, uc, erp);
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4lzwe_add %d", back
+ return back;
+}
+
+
+
+int
+dk4lzwe_finish(
+ dk4_lzwe_t *lzwptr,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_EDSTM_ERROR;
+ unsigned char uc;
+ $? "+ dk4lzwe_finish"
+ if (NULL != lzwptr) {
+ if (NULL != lzwptr->p_tbl) {
+ if (0 == lzwptr->mret) {
+ back = DK4_EDSTM_ACCEPT;
+ /*
+ Ship out current state, if any.
+ */
+ if (0 != lzwptr->hst) { $? ". have input"
+ if (0 == dk4lzwe_shipout(lzwptr, lzwptr->cs, erp)) {
+ back = DK4_EDSTM_ERROR; $? "! shipout"
+ }
+ }
+ /* Ship out end of data marker.
+ */
+ if (0 == dk4lzwe_shipout(lzwptr, LZW_EOD, erp)) {
+ back = DK4_EDSTM_ERROR; $? "! shipout"
+ }
+ /* Apply final byte from bit shifter to output.
+ */
+ switch ( dk4bit_shift_finish(&(lzwptr->bs), erp)) {
+ case DK4_EDSTM_ERROR : {
+ back = DK4_EDSTM_ERROR; $? "! bug"
+ } break;
+ case DK4_EDSTM_FINISHED : {
+ uc = dk4bit_shift_output(&(lzwptr->bs), NULL);
+ if (8 > lzwptr->obu) { $? ". shipout"
+ lzwptr->ob[lzwptr->obu] = uc;
+ lzwptr->obu += 1;
+ }
+ else { $? "! shipout"
+ back = DK4_EDSTM_ERROR;
+ dk4error_set_simple_error_code(
+ erp, DK4_E_BUFFER_TOO_SMALL
+ );
+ }
+ } break;
+ }
+ /* Check whether the caller must retrieve final output.
+ */
+ if ((DK4_EDSTM_ACCEPT == back) && (0 < lzwptr->obu)) {
+ back = DK4_EDSTM_FINISHED; $? ". output available"
+ lzwptr->mret = 1;
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ dk4mem_free(lzwptr->p_tbl);
+ lzwptr->p_tbl = NULL;
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4lzwe_finish %d", back
+ return back;
+}
+
+
+
+int
+dk4lzwe_output(
+ const unsigned char **dptr,
+ size_t *szptr,
+ dk4_lzwe_t *lzwptr,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+ $? "+ dk4lzwe_output"
+ if ((NULL != dptr) && (NULL != szptr) && (NULL != lzwptr)) {
+ /*
+ All arguments ok, do normal output operation.
+ */
+ *dptr = &(lzwptr->ob[0]);
+ *szptr = lzwptr->obu;
+ back = ((0 < lzwptr->obu) ? (1) : (0));
+ lzwptr->mret = 0; $? ". args"
+ lzwptr->obu = 0;
+ }
+ else { $? "! args"
+ /*
+ Argument error, indicate no data available.
+ */
+ if (NULL != dptr) {
+ *dptr = NULL;
+ }
+ if (NULL != szptr) {
+ *szptr = 0;
+ }
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4lzwe_output %d", back
+ return back;
+}
+
+
+/* vim: set ai sw=4 ts=4 : */
+
diff --git a/support/dktools/dk4lzwe.h b/support/dktools/dk4lzwe.h
new file mode 100644
index 0000000000..7afc458065
--- /dev/null
+++ b/support/dktools/dk4lzwe.h
@@ -0,0 +1,213 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4lzwe.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4LZWE_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4LZWE_H_INCLUDED 1
+
+
+#line 8 "dk4lzwe.ctr"
+
+/** @file dk4lzwe.h LZW encoder to produce PS level 2 output.
+
+- The unit length (input data length) is 8 bits.
+- Code 256 is used for table cleanup, 257 is the end of data marker.
+- EarlyChange is in use: the number of bits per code is increased after
+ creating table entries for codes 511, 1023 and 2047.
+- Table entries are created for codes up to 4093. Instead of generating
+ an entry for 4094, the table is cleared.
+*/
+
+#ifndef DK4ERROR_H_INCLUDED
+#include <dk4error.h>
+#endif
+
+#ifndef DK4BITSH_H_INCLUDED
+#include <dk4bitsh.h>
+#endif
+
+
+
+/** Table size.
+ The table must be large enough to keep 4096 entries. Adding
+ 25 percent size significantly decreases the number of lookups.
+ A prime number is required to ensure traversal of the entire
+ table if necessary.
+*/
+enum {
+ LZW_TABLE_SIZE = 5147 /**< Size of LZW compression table. */
+};
+
+
+
+/** One table entry for LZW compression.
+*/
+typedef struct {
+ unsigned short os; /**< Current (old) state or code. */
+ unsigned short ns; /**< New state after applying input. */
+ unsigned char in; /**< Input byte. */
+} dk4_lzw_cell_t;
+
+
+
+/** LZW encoder structure.
+*/
+typedef struct {
+ unsigned char ob[8]; /**< Output buffer. */
+ dk4_bit_shift_t bs; /**< Bit shifter. */
+ dk4_lzw_cell_t *p_tbl; /**< Pointer to dynamically allocated table. */
+ size_t obu; /**< Used bytes in output buffer. */
+ int mret; /**< Flag: Must retrieve output data. */
+ int hst; /**< Flag: Have internal state. */
+ unsigned short bits; /**< Number of bits to use for output. */
+ unsigned short cs; /**< Current state. */
+ unsigned short ns; /**< Next state for new table entry. */
+} dk4_lzwe_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** Initialize LZW encoder, allocate memory for resources.
+ @param lzwptr Encoder to initialize.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if lzwptr is NULL,
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow when calculating the
+ product of elsize and nelem,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available,
+ - DK4_E_BUG<br>
+ if the dk4bit_shift_add() call indicates an error
+ (should not happen as we provide a valid address to the function),
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the output buffer is already full. Typically this means
+ that output was not retrieved as expected by the library.
+*/
+
+int
+dk4lzwe_init(
+ dk4_lzwe_t *lzwptr,
+ dk4_er_t *erp
+);
+
+
+/** Add one byte to the encoder.
+ @param lzwptr Encoder to use.
+ @param uc Byte to add.
+ @param erp Error report, may be NULL.
+ @return Operation result, one from:
+ - DK4_EDSTM_ACCEPT<br>
+ if the input byte was successfully stored in the internal data
+ structures without completing a run. No further action
+ necessary.
+ - DK4_EDSTM_FINISHED<br>
+ if output was created. Use dk4lzwe_output() to obtain the
+ output data.
+ - DK4_EDSTM_ERROR<br>
+ if an error occured.
+*/
+
+int
+dk4lzwe_add(
+ dk4_lzwe_t *lzwptr,
+ unsigned char uc,
+ dk4_er_t *erp
+);
+
+
+/** Finish encoded data stream, flush internal state and bits from
+ the bit shifter to output buffer and release dynamic memory.
+ @param lzwptr Encoder to use.
+ @param erp Error report, may be NULL.
+ @return Operation result, one from:
+ - DK4_EDSTM_ACCEPT<br>
+ if the input byte was successfully stored in the internal data
+ structures without completing a run. No further action
+ necessary.
+ - DK4_EDSTM_FINISHED<br>
+ if output was created. Use dk4lzwe_output() to obtain the
+ output data.
+ - DK4_EDSTM_ERROR<br>
+ if an error occured.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if lzwptr is NULL or lzwptr->s_tbl or lzwptr->i_tbl is NULL,
+ - DK4_E_BUG<br>
+ if the dk4bit_shift_add() call indicates an error
+ (should not happen as we provide a valid address to the function),
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the output buffer is already full. Typically this means
+ that output was not retrieved as expected by the library.
+*/
+
+int
+dk4lzwe_finish(
+ dk4_lzwe_t *lzwptr,
+ dk4_er_t *erp
+);
+
+
+/** Retrieve output from encoder.
+ @param dptr Address of result pointer.
+ @param szptr Address of result size variable.
+ @param lzwptr Encoder to use.
+ @param erp Error report, may be NULL.
+ @return 1 if data available, 0 otherwise.
+*/
+
+int
+dk4lzwe_output(
+ const unsigned char **dptr,
+ size_t *szptr,
+ dk4_lzwe_t *lzwptr,
+ dk4_er_t *erp
+);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/* vim: set ai sw=4 ts=4 : */
+
+#endif
diff --git a/support/dktools/dk4ma.h b/support/dktools/dk4ma.h
new file mode 100644
index 0000000000..4d23a60de8
--- /dev/null
+++ b/support/dktools/dk4ma.h
@@ -0,0 +1,715 @@
+/** @file dk4ma.h Header file to include all dk4maxxxxx related headers.
+
+@section operations dk4maa*.h - Arithmetic operations on different types
+ Data type | Header
+ :-------: | :----:
+ signed char | dk4maac.h
+ unsigned char | dk4maauc.h
+ short | dk4maas.h
+ unsigned short | dk4maaus.h
+ int | dk4maai.h
+ unsigned int | dk4maaui.h
+ long | dk4maal.h
+ unsigned long | dk4maaul.h
+ long long | dk4maall.h
+ unsigned long long | dk4maalu.h
+ intmax_t | dk4maami.h
+ uintmax_t | dk4maamu.h
+ dk4_im_t | dk4maadi.h
+ dk4_um_t | dk4maadu.h
+ 16 bit signed integer | dk4maai16.h
+ 16 bit unsigned integer | dk4maau16.h
+ 32 bit signed integer | dk4maai32.h
+ 32 bit unsigned integer | dk4maau32.h
+
+@section comparison dk4mac*.h - Comparison between signed and unsigned integer:
+ Data type | Header
+ :-------: | :----:
+ char | dk4macc.h
+ short | dk4macs.h
+ int | dk4maci.h
+ long | dk4macl.h
+ long long | dk4macll.h
+ intmax_t | dk4macm.h
+ dk4_im_t | dk4macd.h
+ 16 bit integer | dk4maci16.h
+ 32 bit integer | dk4maci32.h
+
+@section readnum Read integer data from string
+
+@subsection readnumd8 Read numbers from 8-bit strings in decimal notation
+Data type | Header | Function
+:-------: | :----: | :-------
+char | dk4mai8dic.h | dk4ma_input_c8_dec_char()
+unsigned char | dk4mai8duc.h | dk4ma_input_c8_dec_uchar()
+short | dk4mai8dis.h | dk4ma_input_c8_dec_short()
+unsigned short | dk4mai8dus.h | dk4ma_input_c8_dec_ushort()
+int | dk4mai8dii.h | dk4ma_input_c8_dec_int()
+unsigned | dk4mai8dui.h | dk4ma_input_c8_dec_uint()
+long | dk4mai8dil.h | dk4ma_input_c8_dec_long()
+unsigned long | dk4mai8dul.h | dk4ma_input_c8_dec_ulong()
+size_t | dk4mai8dsz.h | dk4ma_input_c8_dec_size_t()
+long long | dk4mai8dli.h | dk4ma_input_c8_dec_ll()
+unsigned long long | dk4mai8dlu.h | dk4ma_input_c8_dec_ull()
+intmax_t | dk4mai8dmi.h | dk4ma_input_c8_dec_intmax_t()
+uintmax_t | dk4mai8dmu.h | dk4ma_input_c8_dec_uintmax_t()
+dk4_im_t | dk4mai8ddi.h | dk4ma_input_c8_dec_dk4_im_t()
+dk4_um_t | dk4mai8ddu.h | dk4ma_input_c8_dec_dk4_um_t()
+double | dk4mai8dbl.h | dk4ma_input_c8_double()
+
+@subsection readnumh8 Read numbers from 8-bit strings in hexadecimal notation
+
+Data type | Header | Function
+:-------: | :----: | :-------
+char | dk4mai8hic.h | dk4ma_input_c8_hex_char()
+unsigned char | dk4mai8huc.h | dk4ma_input_c8_hex_uchar()
+short | dk4mai8his.h | dk4ma_input_c8_hex_short()
+unsigned short | dk4mai8hus.h | dk4ma_input_c8_hex_ushort()
+int | dk4mai8hii.h | dk4ma_input_c8_hex_int()
+unsigned | dk4mai8hui.h | dk4ma_input_c8_hex_uint()
+long | dk4mai8hil.h | dk4ma_input_c8_hex_long()
+unsigned long | dk4mai8hul.h | dk4ma_input_c8_hex_ulong()
+long long | dk4mai8hli.h | dk4ma_input_c8_hex_ll()
+unsigned long long | dk4mai8hlu.h | dk4ma_input_c8_hex_ull()
+intmax_t | dk4mai8hmi.h | dk4ma_input_c8_hex_intmax_t()
+uintmax_t | dk4mai8hmu.h | dk4ma_input_c8_hex_uintmax_t()
+dk4_im_t | dk4mai8hdi.h | dk4ma_input_c8_hex_dk4_im_t()
+dk4_um_t | dk4mai8hdu.h | dk4ma_input_c8_hex_dk4_um_t()
+
+@subsection readnumw8d Read numbers from wchar_t strings in decimal notation
+
+Data type | Header | Function
+:-------: | :----: | :-------
+char | dk4maiwdic.h | dk4ma_input_wc_dec_char()
+unsigned char | dk4maiwduc.h | dk4ma_input_wc_dec_uchar()
+short | dk4maiwdis.h | dk4ma_input_wc_dec_short()
+unsigned short | dk4maiwdus.h | dk4ma_input_wc_dec_ushort()
+int | dk4maiwdii.h | dk4ma_input_wc_dec_int()
+unsigned | dk4maiwdui.h | dk4ma_input_wc_dec_uint()
+long | dk4maiwdil.h | dk4ma_input_wc_dec_long()
+unsigned long | dk4maiwdul.h | dk4ma_input_wc_dec_ulong()
+size_t | dk4maiwdsz.h | dk4ma_input_wc_dec_size_t()
+long long | dk4maiwdli.h | dk4ma_input_wc_dec_ll()
+unsigned long long | dk4maiwdlu.h | dk4ma_input_wc_dec_ull()
+intmax_t | dk4maiwdmi.h | dk4ma_input_wc_dec_intmax_t()
+uintmax_t | dk4maiwdmu.h | dk4ma_input_wc_dec_uintmax_t()
+dk4_im_t | dk4maiwddi.h | dk4ma_input_wc_dec_dk4_im_t()
+dk4_um_t | dk4maiwddu.h | dk4ma_input_wc_dec_dk4_um_t()
+double | dk4maiwdbl.h | dk4ma_input_wc_double()
+
+@subsection readnumw8h Read numbers from wchar_t strings in hexadecimal notation
+
+Data type | Header | Function
+:-------: | :----: | :-------
+char | dk4maiwhic.h | dk4ma_input_wc_hex_char()
+unsigned char | dk4maiwhuc.h | dk4ma_input_wc_hex_uchar()
+short | dk4maiwhis.h | dk4ma_input_wc_hex_short()
+unsigned short | dk4maiwhus.h | dk4ma_input_wc_hex_ushort()
+int | dk4maiwhii.h | dk4ma_input_wc_hex_int()
+unsigned | dk4maiwhui.h | dk4ma_input_wc_hex_uint()
+long | dk4maiwhil.h | dk4ma_input_wc_hex_long()
+unsigned long | dk4maiwhul.h | dk4ma_input_wc_hex_ulong()
+long long | dk4maiwhli.h | dk4ma_input_wc_hex_ll()
+unsigned long long | dk4maiwhlu.h | dk4ma_input_wc_hex_ull()
+intmax_t | dk4maiwhmi.h | dk4ma_input_wc_hex_intmax_t()
+uintmax_t | dk4maiwhmu.h | dk4ma_input_wc_hex_uintmax_t()
+dk4_im_t | dk4maiwhdi.h | dk4ma_input_wc_hex_dk4_im_t()
+dk4_um_t | dk4maiwhdu.h | dk4ma_input_wc_hex_dk4_um_t()
+
+@subsection readnumdd Read numbers from dkChar strings in decimal notation
+
+Data type | Header | Function
+:-------: | :----: | :-------
+char | dk4maiddic.h | dk4ma_input_dk_dec_char()
+unsigned char | dk4maidduc.h | dk4ma_input_dk_dec_uchar()
+short | dk4maiddis.h | dk4ma_input_dk_dec_short()
+unsigned short | dk4maiddus.h | dk4ma_input_dk_dec_ushort()
+int | dk4maiddii.h | dk4ma_input_dk_dec_int()
+unsigned | dk4maiddui.h | dk4ma_input_dk_dec_uint()
+long | dk4maiddil.h | dk4ma_input_dk_dec_long()
+unsigned long | dk4maiddul.h | dk4ma_input_dk_dec_ulong()
+size_t | dk4maiddsz.h | dk4ma_input_dk_dec_size_t()
+long long | dk4maiddli.h | dk4ma_input_dk_dec_ll()
+unsigned long long | dk4maiddlu.h | dk4ma_input_dk_dec_ull()
+intmax_t | dk4maiddmi.h | dk4ma_input_dk_dec_intmax_t()
+uintmax_t | dk4maiddmu.h | dk4ma_input_dk_dec_uintmax_t()
+dk4_im_t | dk4maidddi.h | dk4ma_input_dk_dec_dk4_im_t()
+dk4_um_t | dk4maidddu.h | dk4ma_input_dk_dec_dk4_um_t()
+double | dk4maiddbl.h | dk4ma_input_dk_double()
+
+@subsection readnumdh Read numbers from dkChar strings in hexadecimal notation
+
+Data type | Header | Function
+:-------: | :----: | :-------
+char | dk4maidhic.h | dk4ma_input_dk_hex_char()
+unsigned char | dk4maidhuc.h | dk4ma_input_dk_hex_uchar()
+short | dk4maidhis.h | dk4ma_input_dk_hex_short()
+unsigned short | dk4maidhus.h | dk4ma_input_dk_hex_ushort()
+int | dk4maidhii.h | dk4ma_input_dk_hex_int()
+unsigned | dk4maidhui.h | dk4ma_input_dk_hex_uint()
+long | dk4maidhil.h | dk4ma_input_dk_hex_long()
+unsigned long | dk4maidhul.h | dk4ma_input_dk_hex_ulong()
+long long | dk4maidhli.h | dk4ma_input_dk_hex_ll()
+unsigned long long | dk4maidhlu.h | dk4ma_input_dk_hex_ull()
+intmax_t | dk4maidhmi.h | dk4ma_input_dk_hex_intmax_t()
+uintmax_t | dk4maidhmu.h | dk4ma_input_dk_hex_uintmax_t()
+dk4_im_t | dk4maidhdi.h | dk4ma_input_dk_hex_dk4_im_t()
+dk4_um_t | dk4maidhdu.h | dk4ma_input_dk_hex_dk4_um_t()
+
+@section writenum Write integer values to string
+
+@subsection wrnumd8 Write integer value to 8-bit string in decimal notation
+
+Data type | Header | Function
+:-------: | :----: | :-------
+dk4_im_t | dk4mao8d.h | dk4ma_write_c8_decimal_unsigned()
+dk4_um_t | dk4mao8d.h | dk4ma_write_c8_decimal_signed()
+double | dk4mao8dbl.h | dk4ma_write_c8_double()
+
+You can cast all other signed integer values to dk4_im_t and all other
+unsigned integer values to dk4_um_t without loss.
+
+@subsection wrnumh8 Write integer value to 8-bit string in hexadecimal notation
+
+Data type | Header | Function
+:-------: | :----: | :-------
+dk4_im_t | dk4mao8h.h | dk4ma_write_c8_hex_unsigned()
+dk4_um_t | dk4mao8h.h | dk4ma_write_c8_hex_signed()
+
+@subsection wrnumw8d Write integer value to wchar_t string in decimal notation
+
+Data type | Header | Function
+:-------: | :----: | :-------
+dk4_im_t | dk4maowd.h | dk4ma_write_wc_decimal_unsigned()
+dk4_um_t | dk4maowd.h | dk4ma_write_wc_decimal_signed()
+double | dk4maowdbl.h | dk4ma_write_wc_double()
+
+@subsection wrnumw8h Write integer value to wchar_t string in hexadecimal notation
+
+Data type | Header | Function
+:-------: | :----: | :-------
+dk4_im_t | dk4maowh.h | dk4ma_write_wc_hex_unsigned()
+dk4_um_t | dk4maowh.h | dk4ma_write_wc_hex_signed()
+
+@subsection wrnumdd Write integer value to dkChar string in decimal notation
+
+Data type | Header | Function
+:-------: | :----: | :-------
+dk4_im_t | dk4maodd.h | dk4ma_write_decimal_unsigned()
+dk4_um_t | dk4maodd.h | dk4ma_write_decimal_signed()
+double | dk4maoddbl.h | dk4ma_write_double()
+
+@subsection wrnumdh Write integer value to dkChar string in hexadecimal notation
+
+Data type | Header | Function
+:-------: | :----: | :-------
+dk4_im_t | dk4maodh.h | dk4ma_write_hex_unsigned()
+dk4_um_t | dk4maodh.h | dk4ma_write_hex_signed()
+
+*/
+#ifndef DK4MA_H_INCLUDED
+
+/** Protection against multiple inclusion.
+*/
+#define DK4MA_H_INCLUDED 1
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4NUMCO_H_INCLUDED
+#include "dk4numco.h"
+#endif
+
+#ifndef DK4MAAC_H_INCLUDED
+#include "dk4maac.h"
+#endif
+
+#ifndef DK4MAAUC_H_INCLUDED
+#include "dk4maauc.h"
+#endif
+
+#ifndef DK4MAAS_H_INCLUDED
+#include "dk4maas.h"
+#endif
+
+#ifndef DK4MAAUS_H_INCLUDED
+#include "dk4maaus.h"
+#endif
+
+#ifndef DK4MAAI_H_INCLUDED
+#include "dk4maai.h"
+#endif
+
+#ifndef DK4MAAUI_H_INCLUDED
+#include "dk4maaui.h"
+#endif
+
+#ifndef DK4MAAL_H_INCLUDED
+#include "dk4maal.h"
+#endif
+
+#ifndef DK4MAAUL_H_INCLUDED
+#include "dk4maaul.h"
+#endif
+
+#ifndef DK4MAALL_H_INCLUDED
+#include "dk4maall.h"
+#endif
+
+#ifndef DK4MAALU_H_INCLUDED
+#include "dk4maalu.h"
+#endif
+
+#ifndef DK4MAAMI_H_INCLUDED
+#include "dk4maami.h"
+#endif
+
+#ifndef DK4MAAMU_H_INCLUDED
+#include "dk4maamu.h"
+#endif
+
+#ifndef DK4MAADI_H_INCLUDED
+#include "dk4maadi.h"
+#endif
+
+#ifndef DK4MAADU_H_INCLUDED
+#include "dk4maadu.h"
+#endif
+
+#ifndef DK4MASZ_H_INCLUDED
+#include "dk4maasz.h"
+#endif
+
+#ifndef DK4MACC_H_INCLUDED
+#include "dk4macc.h"
+#endif
+
+#ifndef DK4MACS_H_INCLUDED
+#include "dk4macs.h"
+#endif
+
+#ifndef DK4MACI_H_INCLUDED
+#include "dk4maci.h"
+#endif
+
+#ifndef DK4MACL_H_INCLUDED
+#include "dk4macl.h"
+#endif
+
+#ifndef DK4MACLL_H_INCLUDED
+#include "dk4macll.h"
+#endif
+
+#ifndef DK4MACM_H_INCLUDED
+#include "dk4macm.h"
+#endif
+
+#ifndef DK4MACD_H_INCLUDED
+#include "dk4macd.h"
+#endif
+
+#ifndef DK4MAO8D_H_INCLUDED
+#include "dk4mao8d.h"
+#endif
+
+#ifndef DK4MAO8H_H_INCLUDED
+#include "dk4mao8h.h"
+#endif
+
+#ifndef DK4MAOWD_H_INCLUDED
+#include "dk4maowd.h"
+#endif
+
+#ifndef DK4MAOWH_H_INCLUDED
+#include "dk4maowh.h"
+#endif
+
+#ifndef DK4MAODD_H_INCLUDED
+#include "dk4maodd.h"
+#endif
+
+#ifndef DK4MAODH_H_INCLUDED
+#include "dk4maodh.h"
+#endif
+
+#ifndef DK4MAI8DDI_H_INCLUDED
+#include "dk4mai8ddi.h"
+#endif
+
+#ifndef DK4MAI8DDU_H_INCLUDED
+#include "dk4mai8ddu.h"
+#endif
+
+#ifndef DK4MAI8DIC_H_INCLUDED
+#include "dk4mai8dic.h"
+#endif
+
+#ifndef DK4MAI8DII_H_INCLUDED
+#include "dk4mai8dii.h"
+#endif
+
+#ifndef DK4MAI8DIL_H_INCLUDED
+#include "dk4mai8dil.h"
+#endif
+
+#ifndef DK4MAI8DIS_H_INCLUDED
+#include "dk4mai8dis.h"
+#endif
+
+#ifndef DK4MAI8DLI_H_INCLUDED
+#include "dk4mai8dli.h"
+#endif
+
+#ifndef DK4MAI8DLU_H_INCLUDED
+#include "dk4mai8dlu.h"
+#endif
+
+#ifndef DK4MAI8DMI_H_INCLUDED
+#include "dk4mai8dmi.h"
+#endif
+
+#ifndef DK4MAI8DMU_H_INCLUDED
+#include "dk4mai8dmu.h"
+#endif
+
+#ifndef DK4MAI8DSZ_H_INCLUDED
+#include "dk4mai8dsz.h"
+#endif
+
+#ifndef DK4MAI8DUC_H_INCLUDED
+#include "dk4mai8duc.h"
+#endif
+
+#ifndef DK4MAI8DUI_H_INCLUDED
+#include "dk4mai8dui.h"
+#endif
+
+#ifndef DK4MAI8DUL_H_INCLUDED
+#include "dk4mai8dul.h"
+#endif
+
+#ifndef DK4MAI8DUS_H_INCLUDED
+#include "dk4mai8dus.h"
+#endif
+
+#ifndef DK4MAI8HDI_H_INCLUDED
+#include "dk4mai8hdi.h"
+#endif
+
+#ifndef DK4MAI8HDU_H_INCLUDED
+#include "dk4mai8hdu.h"
+#endif
+
+#ifndef DK4MAI8HIC_H_INCLUDED
+#include "dk4mai8hic.h"
+#endif
+
+#ifndef DK4MAI8HII_H_INCLUDED
+#include "dk4mai8hii.h"
+#endif
+
+#ifndef DK4MAI8HIL_H_INCLUDED
+#include "dk4mai8hil.h"
+#endif
+
+#ifndef DK4MAI8HIS_H_INCLUDED
+#include "dk4mai8his.h"
+#endif
+
+#ifndef DK4MAI8HLI_H_INCLUDED
+#include "dk4mai8hli.h"
+#endif
+
+#ifndef DK4MAI8HLU_H_INCLUDED
+#include "dk4mai8hlu.h"
+#endif
+
+#ifndef DK4MAI8HMI_H_INCLUDED
+#include "dk4mai8hmi.h"
+#endif
+
+#ifndef DK4MAI8HMU_H_INCLUDED
+#include "dk4mai8hmu.h"
+#endif
+
+#ifndef DK4MAI8HUC_H_INCLUDED
+#include "dk4mai8huc.h"
+#endif
+
+#ifndef DK4MAI8HUI_H_INCLUDED
+#include "dk4mai8hui.h"
+#endif
+
+#ifndef DK4MAI8HUL_H_INCLUDED
+#include "dk4mai8hul.h"
+#endif
+
+#ifndef DK4MAI8HUS_H_INCLUDED
+#include "dk4mai8hus.h"
+#endif
+
+#ifndef DK4MAIDDDI_H_INCLUDED
+#include "dk4maidddi.h"
+#endif
+
+#ifndef DK4MAIDDDU_H_INCLUDED
+#include "dk4maidddu.h"
+#endif
+
+#ifndef DK4MAIDDIC_H_INCLUDED
+#include "dk4maiddic.h"
+#endif
+
+#ifndef DK4MAIDDII_H_INCLUDED
+#include "dk4maiddii.h"
+#endif
+
+#ifndef DK4MAIDDIL_H_INCLUDED
+#include "dk4maiddil.h"
+#endif
+
+#ifndef DK4MAIDDIS_H_INCLUDED
+#include "dk4maiddis.h"
+#endif
+
+#ifndef DK4MAIDDLI_H_INCLUDED
+#include "dk4maiddli.h"
+#endif
+
+#ifndef DK4MAIDDLU_H_INCLUDED
+#include "dk4maiddlu.h"
+#endif
+
+#ifndef DK4MAIDDMI_H_INCLUDED
+#include "dk4maiddmi.h"
+#endif
+
+#ifndef DK4MAIDDMU_H_INCLUDED
+#include "dk4maiddmu.h"
+#endif
+
+#ifndef DK4MAIDDSZ_H_INCLUDED
+#include "dk4maiddsz.h"
+#endif
+
+#ifndef DK4MAIDDUC_H_INCLUDED
+#include "dk4maidduc.h"
+#endif
+
+#ifndef DK4MAIDDUI_H_INCLUDED
+#include "dk4maiddui.h"
+#endif
+
+#ifndef DK4MAIDDUL_H_INCLUDED
+#include "dk4maiddul.h"
+#endif
+
+#ifndef DK4MAIDDUS_H_INCLUDED
+#include "dk4maiddus.h"
+#endif
+
+#ifndef DK4MAIDHDI_H_INCLUDED
+#include "dk4maidhdi.h"
+#endif
+
+#ifndef DK4MAIDHDU_H_INCLUDED
+#include "dk4maidhdu.h"
+#endif
+
+#ifndef DK4MAIDHIC_H_INCLUDED
+#include "dk4maidhic.h"
+#endif
+
+#ifndef DK4MAIDHII_H_INCLUDED
+#include "dk4maidhii.h"
+#endif
+
+#ifndef DK4MAIDHIL_H_INCLUDED
+#include "dk4maidhil.h"
+#endif
+
+#ifndef DK4MAIDHIS_H_INCLUDED
+#include "dk4maidhis.h"
+#endif
+
+#ifndef DK4MAIDHLI_H_INCLUDED
+#include "dk4maidhli.h"
+#endif
+
+#ifndef DK4MAIDHLU_H_INCLUDED
+#include "dk4maidhlu.h"
+#endif
+
+#ifndef DK4MAIDHMI_H_INCLUDED
+#include "dk4maidhmi.h"
+#endif
+
+#ifndef DK4MAIDHMU_H_INCLUDED
+#include "dk4maidhmu.h"
+#endif
+
+#ifndef DK4MAIDHUC_H_INCLUDED
+#include "dk4maidhuc.h"
+#endif
+
+#ifndef DK4MAIDHUI_H_INCLUDED
+#include "dk4maidhui.h"
+#endif
+
+#ifndef DK4MAIDHUL_H_INCLUDED
+#include "dk4maidhul.h"
+#endif
+
+#ifndef DK4MAIDHUS_H_INCLUDED
+#include "dk4maidhus.h"
+#endif
+
+#ifndef DK4MAIWDDI_H_INCLUDED
+#include "dk4maiwddi.h"
+#endif
+
+#ifndef DK4MAIWDDU_H_INCLUDED
+#include "dk4maiwddu.h"
+#endif
+
+#ifndef DK4MAIWDIC_H_INCLUDED
+#include "dk4maiwdic.h"
+#endif
+
+#ifndef DK4MAIWDII_H_INCLUDED
+#include "dk4maiwdii.h"
+#endif
+
+#ifndef DK4MAIWDIL_H_INCLUDED
+#include "dk4maiwdil.h"
+#endif
+
+#ifndef DK4MAIWDIS_H_INCLUDED
+#include "dk4maiwdis.h"
+#endif
+
+#ifndef DK4MAIWDLI_H_INCLUDED
+#include "dk4maiwdli.h"
+#endif
+
+#ifndef DK4MAIWDLU_H_INCLUDED
+#include "dk4maiwdlu.h"
+#endif
+
+#ifndef DK4MAIWDMI_H_INCLUDED
+#include "dk4maiwdmi.h"
+#endif
+
+#ifndef DK4MAIWDMU_H_INCLUDED
+#include "dk4maiwdmu.h"
+#endif
+
+#ifndef DK4MAIWDSZ_H_INCLUDED
+#include "dk4maiwdsz.h"
+#endif
+
+#ifndef DK4MAIWDUC_H_INCLUDED
+#include "dk4maiwduc.h"
+#endif
+
+#ifndef DK4MAIWDUI_H_INCLUDED
+#include "dk4maiwdui.h"
+#endif
+
+#ifndef DK4MAIWDUL_H_INCLUDED
+#include "dk4maiwdul.h"
+#endif
+
+#ifndef DK4MAIWDUS_H_INCLUDED
+#include "dk4maiwdus.h"
+#endif
+
+#ifndef DK4MAIWHDI_H_INCLUDED
+#include "dk4maiwhdi.h"
+#endif
+
+#ifndef Dk4MAIWHDU_H_INCLUDED
+#include "dk4maiwhdu.h"
+#endif
+
+#ifndef DK4MAIWHIC_H_INCLUDED
+#include "dk4maiwhic.h"
+#endif
+
+#ifndef DK4MAIWHII_H_INCLUDED
+#include "dk4maiwhii.h"
+#endif
+
+#ifndef DK4MAIWHIL_H_INCLUDED
+#include "dk4maiwhil.h"
+#endif
+
+#ifndef DK4MAIWHIS_H_INCLUDED
+#include "dk4maiwhis.h"
+#endif
+
+#ifndef DK4MAIWHLI_H_INCLUDED
+#include "dk4maiwhli.h"
+#endif
+
+#ifndef DK4MAIWHLU_H_INCLUDED
+#include "dk4maiwhlu.h"
+#endif
+
+#ifndef DK4MAIWHMI_H_INCLUDED
+#include "dk4maiwhmi.h"
+#endif
+
+#ifndef DK4MAIWHMU_H_INCLUDED
+#include "dk4maiwhmu.h"
+#endif
+
+#ifndef DK4MAIWHUC_H_INCLUDED
+#include "dk4maiwhuc.h"
+#endif
+
+#ifndef DK4MAIWHUI_H_INCLUDED
+#include "dk4maiwhui.h"
+#endif
+
+
+#ifndef DK4MAIWHUL_H_INCLUDED
+#include "dk4maiwhul.h"
+#endif
+
+
+#ifndef DK4MAIWHUS_H_INCLUDED
+#include "dk4maiwhus.h"
+#endif
+
+#ifndef DK4MAAI16_H_INCLUDED
+#include "dk4maai16.h"
+#endif
+
+#ifndef DK4MAAU16_H_INCLUDED
+#include "dk4maau16.h"
+#endif
+
+#ifndef DK4MAAI32_H_INCLUDED
+#include "dk4maai32.h"
+#endif
+
+#ifndef DK4MAAU32_H_INCLUDED
+#include "dk4maau32.h"
+#endif
+
+#ifndef DK4MACI16_H_INCLUDED
+#include "dk4maci16.h"
+#endif
+
+#ifndef DK4MACI32_H_INCLUDED
+#include "dk4maci32.h"
+#endif
+
+#endif
+/* ifndef DK4MA_H_INCLUDED */
diff --git a/support/dktools/dk4maac.c b/support/dktools/dk4maac.c
new file mode 100644
index 0000000000..1092c27f00
--- /dev/null
+++ b/support/dktools/dk4maac.c
@@ -0,0 +1,177 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maac.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maac.c The dk4maac module.
+*/
+
+
+#line 98 "dk4maac.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4numco.h"
+#include "dk4maac.h"
+
+
+
+
+
+#line 108 "dk4maac.ctr"
+
+
+
+signed char
+dk4ma_char_abs(signed char a, dk4_er_t *erp)
+{
+ if (SCHAR_MIN == a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return (signed char)((0 <= a) ? a : ((SCHAR_MIN == a) ? SCHAR_MAX : (0 - a)));
+}
+
+
+
+signed char
+dk4ma_char_add(signed char a, signed char b, dk4_er_t *erp)
+{
+ if ((0 < a) && (0 < b)) {
+ if ((SCHAR_MAX - a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((0 > a) && (0 > b)) {
+ if (SCHAR_MIN == a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ if ((SCHAR_MIN - a) > b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ }
+ return (signed char)(a + b);
+}
+
+
+
+signed char
+dk4ma_char_sub(signed char a, signed char b, dk4_er_t *erp)
+{
+
+ if ((0 < a) && (0 > b)) {
+ if ((SCHAR_MAX + b) < a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((0 > a) && (0 < b)) {
+ if ((SCHAR_MIN + b) > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ return (signed char)(a - b);
+}
+
+
+
+signed char
+dk4ma_char_mul(signed char a, signed char b, dk4_er_t *erp)
+{
+
+
+#line 169 "dk4maac.ctr"
+ if ((0 != a) && (0 != b)) {
+ if (SCHAR_MIN == a) {
+ if ((signed char)1 != b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if (SCHAR_MIN == b) {
+ if ((signed char)1 != a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if (0 < a) {
+ if (0 < b) {
+ if ((SCHAR_MAX / a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((SCHAR_MIN / a) > b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ } else {
+ if (0 < b) {
+ if ((SCHAR_MIN / b) > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((SCHAR_MAX / (0 - a)) < (0 - b)) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+#line 205 "dk4maac.ctr"
+ return (signed char)(a * b);
+}
+
+
+
+signed char
+dk4ma_char_div(signed char a, signed char b, dk4_er_t *erp)
+{
+ signed char back = 0;
+ if (0 != b) {
+ if ((SCHAR_MIN == a) && (-1 == b)) {
+ back = SCHAR_MAX;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ back = a / b;
+ }
+ } else {
+ if (0 < a) back = SCHAR_MAX;
+ if (0 > b) back = SCHAR_MIN;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_DIVZERO);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4maac.ctr b/support/dktools/dk4maac.ctr
new file mode 100644
index 0000000000..3cffc828e2
--- /dev/null
+++ b/support/dktools/dk4maac.ctr
@@ -0,0 +1,228 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+%% header
+
+/** @file
+ Arithmetic operations on signed char.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Absolute value.
+ @param a Operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, SCHAR_MAX if a is SCHAR_MIN
+ (overflow is reported in erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+signed char
+dk4ma_char_abs(signed char a, dk4_er_t *erp);
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+signed char
+dk4ma_char_add(signed char a, signed char b, dk4_er_t *erp);
+
+/** Subtraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+signed char
+dk4ma_char_sub(signed char a, signed char b, dk4_er_t *erp);
+
+/** Multiplication.
+ @param a Left factor.
+ @param b right factor.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant
+ bits on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+signed char
+dk4ma_char_mul(signed char a, signed char b, dk4_er_t *erp);
+
+/** Division.
+ @param a Counter (left operand).
+ @param b Denominator (right operand).
+ @param erp Error report, may be NULL.
+ @return Division result on success,
+ SCHAR_MIN, SCHAR_MAX, or 0 on division by zero or overflow
+ (see the ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW, DK4_E_DIVZERO.
+*/
+signed char
+dk4ma_char_div(signed char a, signed char b, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4numco.h"
+#include "dk4maac.h"
+
+
+
+$!trace-include
+
+
+
+signed char
+dk4ma_char_abs(signed char a, dk4_er_t *erp)
+{
+ if (SCHAR_MIN == a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return (signed char)((0 <= a) ? a : ((SCHAR_MIN == a) ? SCHAR_MAX : (0 - a)));
+}
+
+
+
+signed char
+dk4ma_char_add(signed char a, signed char b, dk4_er_t *erp)
+{
+ if ((0 < a) && (0 < b)) {
+ if ((SCHAR_MAX - a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((0 > a) && (0 > b)) {
+ if (SCHAR_MIN == a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ if ((SCHAR_MIN - a) > b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ }
+ return (signed char)(a + b);
+}
+
+
+
+signed char
+dk4ma_char_sub(signed char a, signed char b, dk4_er_t *erp)
+{
+
+ if ((0 < a) && (0 > b)) {
+ if ((SCHAR_MAX + b) < a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((0 > a) && (0 < b)) {
+ if ((SCHAR_MIN + b) > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ return (signed char)(a - b);
+}
+
+
+
+signed char
+dk4ma_char_mul(signed char a, signed char b, dk4_er_t *erp)
+{
+ $? "+ dk4ma_char_mul %d %d", (int)a, (int)b
+ if ((0 != a) && (0 != b)) {
+ if (SCHAR_MIN == a) {
+ if ((signed char)1 != b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if (SCHAR_MIN == b) {
+ if ((signed char)1 != a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if (0 < a) {
+ if (0 < b) {
+ if ((SCHAR_MAX / a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((SCHAR_MIN / a) > b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ } else {
+ if (0 < b) {
+ if ((SCHAR_MIN / b) > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((SCHAR_MAX / (0 - a)) < (0 - b)) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ }
+ }
+ }
+ $? "- dk4ma_char_mul %d", (int)((signed char)(a * b))
+ return (signed char)(a * b);
+}
+
+
+
+signed char
+dk4ma_char_div(signed char a, signed char b, dk4_er_t *erp)
+{
+ signed char back = 0;
+ if (0 != b) {
+ if ((SCHAR_MIN == a) && (-1 == b)) {
+ back = SCHAR_MAX;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ back = a / b;
+ }
+ } else {
+ if (0 < a) back = SCHAR_MAX;
+ if (0 > b) back = SCHAR_MIN;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_DIVZERO);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4maac.h b/support/dktools/dk4maac.h
new file mode 100644
index 0000000000..3a46013888
--- /dev/null
+++ b/support/dktools/dk4maac.h
@@ -0,0 +1,132 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maac.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAAC_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAAC_H_INCLUDED 1
+
+
+#line 8 "dk4maac.ctr"
+
+/** @file
+ Arithmetic operations on signed char.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Absolute value.
+ @param a Operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, SCHAR_MAX if a is SCHAR_MIN
+ (overflow is reported in erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+signed char
+dk4ma_char_abs(signed char a, dk4_er_t *erp);
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+signed char
+dk4ma_char_add(signed char a, signed char b, dk4_er_t *erp);
+
+/** Subtraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+signed char
+dk4ma_char_sub(signed char a, signed char b, dk4_er_t *erp);
+
+/** Multiplication.
+ @param a Left factor.
+ @param b right factor.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant
+ bits on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+signed char
+dk4ma_char_mul(signed char a, signed char b, dk4_er_t *erp);
+
+/** Division.
+ @param a Counter (left operand).
+ @param b Denominator (right operand).
+ @param erp Error report, may be NULL.
+ @return Division result on success,
+ SCHAR_MIN, SCHAR_MAX, or 0 on division by zero or overflow
+ (see the ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW, DK4_E_DIVZERO.
+*/
+signed char
+dk4ma_char_div(signed char a, signed char b, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4maadi.c b/support/dktools/dk4maadi.c
new file mode 100644
index 0000000000..0ae674bd14
--- /dev/null
+++ b/support/dktools/dk4maadi.c
@@ -0,0 +1,139 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maadi.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maadi.c The dk4maadi module.
+*/
+
+
+#line 100 "dk4maadi.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4numco.h"
+
+#if DK4_HAVE_INTMAX_T
+#include "dk4maami.h"
+#else
+#if DK4_HAVE_LONG_LONG
+#include "dk4maall.h"
+#else
+#include "dk4maal.h"
+#endif
+#endif
+
+#include "dk4maadi.h"
+
+
+
+dk4_im_t
+dk4ma_im_abs(dk4_im_t a, dk4_er_t *erp)
+{
+#if DK4_HAVE_INTMAX_T
+ return (dk4ma_intmax_t_abs(a, erp));
+#else
+#if DK4_HAVE_LONG_LONG
+ return (dk4ma_ll_abs(a, erp));
+#else
+ return (dk4ma_long_abs(a, erp));
+#endif
+#endif
+}
+
+
+
+dk4_im_t
+dk4ma_im_add(dk4_im_t a, dk4_im_t b, dk4_er_t *erp)
+{
+#if DK4_HAVE_INTMAX_T
+ return (dk4ma_intmax_t_add(a, b, erp));
+#else
+#if DK4_HAVE_LONG_LONG
+ return (dk4ma_ll_add(a, b, erp));
+#else
+ return (dk4ma_long_add(a, b, erp));
+#endif
+#endif
+}
+
+
+
+dk4_im_t
+dk4ma_im_sub(dk4_im_t a, dk4_im_t b, dk4_er_t *erp)
+{
+#if DK4_HAVE_INTMAX_T
+ return (dk4ma_intmax_t_sub(a, b, erp));
+#else
+#if DK4_HAVE_LONG_LONG
+ return (dk4ma_ll_sub(a, b, erp));
+#else
+ return (dk4ma_long_sub(a, b, erp));
+#endif
+#endif
+}
+
+
+
+dk4_im_t
+dk4ma_im_mul(dk4_im_t a, dk4_im_t b, dk4_er_t *erp)
+{
+#if DK4_HAVE_INTMAX_T
+ return (dk4ma_intmax_t_mul(a, b, erp));
+#else
+#if DK4_HAVE_LONG_LONG
+ return (dk4ma_ll_mul(a, b, erp));
+#else
+ return (dk4ma_long_mul(a, b, erp));
+#endif
+#endif
+}
+
+
+
+dk4_im_t
+dk4ma_im_div(dk4_im_t a, dk4_im_t b, dk4_er_t *erp)
+{
+#if DK4_HAVE_INTMAX_T
+ return (dk4ma_intmax_t_div(a, b, erp));
+#else
+#if DK4_HAVE_LONG_LONG
+ return (dk4ma_ll_div(a, b, erp));
+#else
+ return (dk4ma_long_div(a, b, erp));
+#endif
+#endif
+}
+
+
diff --git a/support/dktools/dk4maadi.ctr b/support/dktools/dk4maadi.ctr
new file mode 100644
index 0000000000..64cac42ab3
--- /dev/null
+++ b/support/dktools/dk4maadi.ctr
@@ -0,0 +1,198 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ Arithmetic operations on dk4_im_t.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Absolute value.
+ @param a Operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, DK4_IM_MAX if a is DK4_IM_MIN
+ (overflow is reported in erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+dk4_im_t
+dk4ma_im_abs(dk4_im_t a, dk4_er_t *erp);
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+dk4_im_t
+dk4ma_im_add(dk4_im_t a, dk4_im_t b, dk4_er_t *erp);
+
+/** Subtraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+dk4_im_t
+dk4ma_im_sub(dk4_im_t a, dk4_im_t b, dk4_er_t *erp);
+
+/** Multiplication.
+ @param a Left factor.
+ @param b right factor.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant
+ bits on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+dk4_im_t
+dk4ma_im_mul(dk4_im_t a, dk4_im_t b, dk4_er_t *erp);
+
+/** Division.
+ @param a Counter (left operand).
+ @param b Denominator (right operand).
+ @param erp Error report, may be NULL.
+ @return Division result on success,
+ DK4_IM_MIN, DK4_IM_MAX, or 0 on division by zero or overflow
+ (see the ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW, DK4_E_DIVZERO.
+*/
+dk4_im_t
+dk4ma_im_div(dk4_im_t a, dk4_im_t b, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4numco.h"
+
+#if DK4_HAVE_INTMAX_T
+#include "dk4maami.h"
+#else
+#if DK4_HAVE_LONG_LONG
+#include "dk4maall.h"
+#else
+#include "dk4maal.h"
+#endif
+#endif
+
+#include "dk4maadi.h"
+
+
+
+dk4_im_t
+dk4ma_im_abs(dk4_im_t a, dk4_er_t *erp)
+{
+#if DK4_HAVE_INTMAX_T
+ return (dk4ma_intmax_t_abs(a, erp));
+#else
+#if DK4_HAVE_LONG_LONG
+ return (dk4ma_ll_abs(a, erp));
+#else
+ return (dk4ma_long_abs(a, erp));
+#endif
+#endif
+}
+
+
+
+dk4_im_t
+dk4ma_im_add(dk4_im_t a, dk4_im_t b, dk4_er_t *erp)
+{
+#if DK4_HAVE_INTMAX_T
+ return (dk4ma_intmax_t_add(a, b, erp));
+#else
+#if DK4_HAVE_LONG_LONG
+ return (dk4ma_ll_add(a, b, erp));
+#else
+ return (dk4ma_long_add(a, b, erp));
+#endif
+#endif
+}
+
+
+
+dk4_im_t
+dk4ma_im_sub(dk4_im_t a, dk4_im_t b, dk4_er_t *erp)
+{
+#if DK4_HAVE_INTMAX_T
+ return (dk4ma_intmax_t_sub(a, b, erp));
+#else
+#if DK4_HAVE_LONG_LONG
+ return (dk4ma_ll_sub(a, b, erp));
+#else
+ return (dk4ma_long_sub(a, b, erp));
+#endif
+#endif
+}
+
+
+
+dk4_im_t
+dk4ma_im_mul(dk4_im_t a, dk4_im_t b, dk4_er_t *erp)
+{
+#if DK4_HAVE_INTMAX_T
+ return (dk4ma_intmax_t_mul(a, b, erp));
+#else
+#if DK4_HAVE_LONG_LONG
+ return (dk4ma_ll_mul(a, b, erp));
+#else
+ return (dk4ma_long_mul(a, b, erp));
+#endif
+#endif
+}
+
+
+
+dk4_im_t
+dk4ma_im_div(dk4_im_t a, dk4_im_t b, dk4_er_t *erp)
+{
+#if DK4_HAVE_INTMAX_T
+ return (dk4ma_intmax_t_div(a, b, erp));
+#else
+#if DK4_HAVE_LONG_LONG
+ return (dk4ma_ll_div(a, b, erp));
+#else
+ return (dk4ma_long_div(a, b, erp));
+#endif
+#endif
+}
+
+
diff --git a/support/dktools/dk4maadi.h b/support/dktools/dk4maadi.h
new file mode 100644
index 0000000000..6413d0f2fa
--- /dev/null
+++ b/support/dktools/dk4maadi.h
@@ -0,0 +1,133 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maadi.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAADI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAADI_H_INCLUDED 1
+
+
+#line 9 "dk4maadi.ctr"
+
+/** @file
+ Arithmetic operations on dk4_im_t.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Absolute value.
+ @param a Operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, DK4_IM_MAX if a is DK4_IM_MIN
+ (overflow is reported in erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+dk4_im_t
+dk4ma_im_abs(dk4_im_t a, dk4_er_t *erp);
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+dk4_im_t
+dk4ma_im_add(dk4_im_t a, dk4_im_t b, dk4_er_t *erp);
+
+/** Subtraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+dk4_im_t
+dk4ma_im_sub(dk4_im_t a, dk4_im_t b, dk4_er_t *erp);
+
+/** Multiplication.
+ @param a Left factor.
+ @param b right factor.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant
+ bits on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+dk4_im_t
+dk4ma_im_mul(dk4_im_t a, dk4_im_t b, dk4_er_t *erp);
+
+/** Division.
+ @param a Counter (left operand).
+ @param b Denominator (right operand).
+ @param erp Error report, may be NULL.
+ @return Division result on success,
+ DK4_IM_MIN, DK4_IM_MAX, or 0 on division by zero or overflow
+ (see the ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW, DK4_E_DIVZERO.
+*/
+dk4_im_t
+dk4ma_im_div(dk4_im_t a, dk4_im_t b, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4maadu.c b/support/dktools/dk4maadu.c
new file mode 100644
index 0000000000..7f7bfc7c29
--- /dev/null
+++ b/support/dktools/dk4maadu.c
@@ -0,0 +1,121 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maadu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maadu.c The dk4maadu module.
+*/
+
+
+#line 90 "dk4maadu.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4numco.h"
+
+#if DK4_HAVE_INTMAX_T
+#include "dk4maamu.h"
+#else
+#if DK4_HAVE_LONG_LONG
+#include "dk4maalu.h"
+#else
+#include "dk4maaul.h"
+#endif
+#endif
+
+#include "dk4maadu.h"
+
+
+dk4_um_t
+dk4ma_um_add(dk4_um_t a, dk4_um_t b, dk4_er_t *erp)
+{
+#if DK4_HAVE_INTMAX_T
+ return (dk4ma_uintmax_t_add(a, b, erp));
+#else
+#if DK4_HAVE_LONG_LONG
+ return (dk4ma_ull_add(a, b, erp));
+#else
+ return (dk4ma_ulong_add(a, b, erp));
+#endif
+#endif
+}
+
+
+
+dk4_um_t
+dk4ma_um_sub(dk4_um_t a, dk4_um_t b, dk4_er_t *erp)
+{
+#if DK4_HAVE_INTMAX_T
+ return (dk4ma_uintmax_t_sub(a, b, erp));
+#else
+#if DK4_HAVE_LONG_LONG
+ return (dk4ma_ull_sub(a, b, erp));
+#else
+ return (dk4ma_ulong_sub(a, b, erp));
+#endif
+#endif
+}
+
+
+
+dk4_um_t
+dk4ma_um_mul(dk4_um_t a, dk4_um_t b, dk4_er_t *erp)
+{
+#if DK4_HAVE_INTMAX_T
+ return (dk4ma_uintmax_t_mul(a, b, erp));
+#else
+#if DK4_HAVE_LONG_LONG
+ return (dk4ma_ull_mul(a, b, erp));
+#else
+ return (dk4ma_ulong_mul(a, b, erp));
+#endif
+#endif
+}
+
+
+
+dk4_um_t
+dk4ma_um_div(dk4_um_t a, dk4_um_t b, dk4_er_t *erp)
+{
+#if DK4_HAVE_INTMAX_T
+ return (dk4ma_uintmax_t_div(a, b,erp));
+#else
+#if DK4_HAVE_LONG_LONG
+ return (dk4ma_ull_div(a, b, erp));
+#else
+ return (dk4ma_ulong_div(a, b, erp));
+#endif
+#endif
+}
+
diff --git a/support/dktools/dk4maadu.ctr b/support/dktools/dk4maadu.ctr
new file mode 100644
index 0000000000..c54adb8401
--- /dev/null
+++ b/support/dktools/dk4maadu.ctr
@@ -0,0 +1,170 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Arithmetic operations on dk4_um_t.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+dk4_um_t
+dk4ma_um_add(dk4_um_t a, dk4_um_t b, dk4_er_t *erp);
+
+/** Subtraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+dk4_um_t
+dk4ma_um_sub(dk4_um_t a, dk4_um_t b, dk4_er_t *erp);
+
+/** Multiplication.
+ @param a Left factor.
+ @param b right factor.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant
+ bits on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+dk4_um_t
+dk4ma_um_mul(dk4_um_t a, dk4_um_t b, dk4_er_t *erp);
+
+/** Division.
+ @param a Counter (left operand).
+ @param b Denominator (right operand).
+ @param erp Error report, may be NULL.
+ @return Division result on success,
+ DK4_UM_MAX on division by zero
+ (see the ec component of erp).
+
+ Error codes: DK4_E_DIVZERO.
+*/
+dk4_um_t
+dk4ma_um_div(dk4_um_t a, dk4_um_t b, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4numco.h"
+
+#if DK4_HAVE_INTMAX_T
+#include "dk4maamu.h"
+#else
+#if DK4_HAVE_LONG_LONG
+#include "dk4maalu.h"
+#else
+#include "dk4maaul.h"
+#endif
+#endif
+
+#include "dk4maadu.h"
+
+
+dk4_um_t
+dk4ma_um_add(dk4_um_t a, dk4_um_t b, dk4_er_t *erp)
+{
+#if DK4_HAVE_INTMAX_T
+ return (dk4ma_uintmax_t_add(a, b, erp));
+#else
+#if DK4_HAVE_LONG_LONG
+ return (dk4ma_ull_add(a, b, erp));
+#else
+ return (dk4ma_ulong_add(a, b, erp));
+#endif
+#endif
+}
+
+
+
+dk4_um_t
+dk4ma_um_sub(dk4_um_t a, dk4_um_t b, dk4_er_t *erp)
+{
+#if DK4_HAVE_INTMAX_T
+ return (dk4ma_uintmax_t_sub(a, b, erp));
+#else
+#if DK4_HAVE_LONG_LONG
+ return (dk4ma_ull_sub(a, b, erp));
+#else
+ return (dk4ma_ulong_sub(a, b, erp));
+#endif
+#endif
+}
+
+
+
+dk4_um_t
+dk4ma_um_mul(dk4_um_t a, dk4_um_t b, dk4_er_t *erp)
+{
+#if DK4_HAVE_INTMAX_T
+ return (dk4ma_uintmax_t_mul(a, b, erp));
+#else
+#if DK4_HAVE_LONG_LONG
+ return (dk4ma_ull_mul(a, b, erp));
+#else
+ return (dk4ma_ulong_mul(a, b, erp));
+#endif
+#endif
+}
+
+
+
+dk4_um_t
+dk4ma_um_div(dk4_um_t a, dk4_um_t b, dk4_er_t *erp)
+{
+#if DK4_HAVE_INTMAX_T
+ return (dk4ma_uintmax_t_div(a, b,erp));
+#else
+#if DK4_HAVE_LONG_LONG
+ return (dk4ma_ull_div(a, b, erp));
+#else
+ return (dk4ma_ulong_div(a, b, erp));
+#endif
+#endif
+}
+
diff --git a/support/dktools/dk4maadu.h b/support/dktools/dk4maadu.h
new file mode 100644
index 0000000000..4f26c44ac6
--- /dev/null
+++ b/support/dktools/dk4maadu.h
@@ -0,0 +1,122 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maadu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAADU_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAADU_H_INCLUDED 1
+
+
+#line 10 "dk4maadu.ctr"
+
+/** @file
+ Arithmetic operations on dk4_um_t.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+dk4_um_t
+dk4ma_um_add(dk4_um_t a, dk4_um_t b, dk4_er_t *erp);
+
+/** Subtraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+dk4_um_t
+dk4ma_um_sub(dk4_um_t a, dk4_um_t b, dk4_er_t *erp);
+
+/** Multiplication.
+ @param a Left factor.
+ @param b right factor.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant
+ bits on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+dk4_um_t
+dk4ma_um_mul(dk4_um_t a, dk4_um_t b, dk4_er_t *erp);
+
+/** Division.
+ @param a Counter (left operand).
+ @param b Denominator (right operand).
+ @param erp Error report, may be NULL.
+ @return Division result on success,
+ DK4_UM_MAX on division by zero
+ (see the ec component of erp).
+
+ Error codes: DK4_E_DIVZERO.
+*/
+dk4_um_t
+dk4ma_um_div(dk4_um_t a, dk4_um_t b, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4maai.c b/support/dktools/dk4maai.c
new file mode 100644
index 0000000000..c584f84cee
--- /dev/null
+++ b/support/dktools/dk4maai.c
@@ -0,0 +1,170 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maai.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maai.c The dk4maai module.
+*/
+
+
+#line 100 "dk4maai.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4numco.h"
+#include "dk4maai.h"
+
+
+
+int
+dk4ma_int_abs(int a, dk4_er_t *erp)
+{
+ if (INT_MIN == a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return ((0 <= a) ? a : ((INT_MIN == a) ? INT_MAX : (0 - a)));
+}
+
+
+
+int
+dk4ma_int_add(int a, int b, dk4_er_t *erp)
+{
+ if ((0 < a) && (0 < b)) {
+ if ((INT_MAX - a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((0 > a) && (0 > b)) {
+ if (INT_MIN == a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ if ((INT_MIN - a) > b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ }
+ return (a + b);
+}
+
+
+
+int
+dk4ma_int_sub(int a, int b, dk4_er_t *erp)
+{
+ if ((0 < a) && (0 > b)) {
+ if ((INT_MAX + b) < a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((0 > a) && (0 < b)) {
+ if ((INT_MIN + b) > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ return (a - b);
+}
+
+
+
+int
+dk4ma_int_mul(int a, int b, dk4_er_t *erp)
+{
+ if ((0 != a) && (0 != b)) {
+ if (INT_MIN == a) {
+ if (1 != b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if (INT_MIN == b) {
+ if (1 != a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if (0 < a) {
+ if (0 < b) {
+ if ((INT_MAX / a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((INT_MIN / a) > b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ } else {
+ if (0 < b) {
+ if ((INT_MIN / b) > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((INT_MAX / (0 - a)) < (0 - b)) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ }
+ }
+ }
+ return (a * b);
+}
+
+
+
+int
+dk4ma_int_div(int a, int b, dk4_er_t *erp)
+{
+ int back = 0;
+ if (0 != b) {
+ if ((INT_MIN == a) && (-1 == b)) {
+ back = INT_MAX;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ back = a / b;
+ }
+ } else {
+ if (0 < a) {
+ back = INT_MAX;
+ } else {
+ if (0 > a) {
+ back = INT_MIN;
+ }
+ }
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_DIVZERO);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4maai.ctr b/support/dktools/dk4maai.ctr
new file mode 100644
index 0000000000..bdbcc285ae
--- /dev/null
+++ b/support/dktools/dk4maai.ctr
@@ -0,0 +1,229 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ Arithmetic operations on int.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Absolute value.
+ @param a Operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, INT_MAX if a is INT_MIN
+ (overflow is reported in erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+int
+dk4ma_int_abs(int a, dk4_er_t *erp);
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+int
+dk4ma_int_add(int a, int b, dk4_er_t *erp);
+
+/** Subtraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+int
+dk4ma_int_sub(int a, int b, dk4_er_t *erp);
+
+/** Multiplication.
+ @param a Left factor.
+ @param b right factor.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant
+ bits on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+int
+dk4ma_int_mul(int a, int b, dk4_er_t *erp);
+
+/** Division.
+ @param a Counter (left operand).
+ @param b Denominator (right operand).
+ @param erp Error report, may be NULL.
+ @return Division result on success,
+ INT_MIN, INT_MAX, or 0 on division by zero or overflow
+ (see the ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW, DK4_E_DIVZERO.
+*/
+int
+dk4ma_int_div(int a, int b, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4numco.h"
+#include "dk4maai.h"
+
+
+
+int
+dk4ma_int_abs(int a, dk4_er_t *erp)
+{
+ if (INT_MIN == a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return ((0 <= a) ? a : ((INT_MIN == a) ? INT_MAX : (0 - a)));
+}
+
+
+
+int
+dk4ma_int_add(int a, int b, dk4_er_t *erp)
+{
+ if ((0 < a) && (0 < b)) {
+ if ((INT_MAX - a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((0 > a) && (0 > b)) {
+ if (INT_MIN == a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ if ((INT_MIN - a) > b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ }
+ return (a + b);
+}
+
+
+
+int
+dk4ma_int_sub(int a, int b, dk4_er_t *erp)
+{
+ if ((0 < a) && (0 > b)) {
+ if ((INT_MAX + b) < a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((0 > a) && (0 < b)) {
+ if ((INT_MIN + b) > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ return (a - b);
+}
+
+
+
+int
+dk4ma_int_mul(int a, int b, dk4_er_t *erp)
+{
+ if ((0 != a) && (0 != b)) {
+ if (INT_MIN == a) {
+ if (1 != b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if (INT_MIN == b) {
+ if (1 != a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if (0 < a) {
+ if (0 < b) {
+ if ((INT_MAX / a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((INT_MIN / a) > b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ } else {
+ if (0 < b) {
+ if ((INT_MIN / b) > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((INT_MAX / (0 - a)) < (0 - b)) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ }
+ }
+ }
+ return (a * b);
+}
+
+
+
+int
+dk4ma_int_div(int a, int b, dk4_er_t *erp)
+{
+ int back = 0;
+ if (0 != b) {
+ if ((INT_MIN == a) && (-1 == b)) {
+ back = INT_MAX;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ back = a / b;
+ }
+ } else {
+ if (0 < a) {
+ back = INT_MAX;
+ } else {
+ if (0 > a) {
+ back = INT_MIN;
+ }
+ }
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_DIVZERO);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4maai.h b/support/dktools/dk4maai.h
new file mode 100644
index 0000000000..5008a675f6
--- /dev/null
+++ b/support/dktools/dk4maai.h
@@ -0,0 +1,133 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maai.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAAI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAAI_H_INCLUDED 1
+
+
+#line 9 "dk4maai.ctr"
+
+/** @file
+ Arithmetic operations on int.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Absolute value.
+ @param a Operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, INT_MAX if a is INT_MIN
+ (overflow is reported in erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+int
+dk4ma_int_abs(int a, dk4_er_t *erp);
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+int
+dk4ma_int_add(int a, int b, dk4_er_t *erp);
+
+/** Subtraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+int
+dk4ma_int_sub(int a, int b, dk4_er_t *erp);
+
+/** Multiplication.
+ @param a Left factor.
+ @param b right factor.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant
+ bits on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+int
+dk4ma_int_mul(int a, int b, dk4_er_t *erp);
+
+/** Division.
+ @param a Counter (left operand).
+ @param b Denominator (right operand).
+ @param erp Error report, may be NULL.
+ @return Division result on success,
+ INT_MIN, INT_MAX, or 0 on division by zero or overflow
+ (see the ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW, DK4_E_DIVZERO.
+*/
+int
+dk4ma_int_div(int a, int b, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4maai16.c b/support/dktools/dk4maai16.c
new file mode 100644
index 0000000000..48859d6b63
--- /dev/null
+++ b/support/dktools/dk4maai16.c
@@ -0,0 +1,209 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maai16.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maai16.c The dk4maai16 module.
+*/
+
+
+#line 133 "dk4maai16.ctr"
+
+#include "dk4maai16.h"
+
+
+
+
+
+#line 139 "dk4maai16.ctr"
+
+
+
+int16_t
+dk4ma_int16_t_add(int16_t a, int16_t b, dk4_er_t *erp)
+{
+ if ((DK4_I16_MAX < a) || (DK4_I16_MIN > a)) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if ((DK4_I16_MAX < b) || (DK4_I16_MIN > b)) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if ((0 < a) && (0 < b)) {
+ if ((DK4_I16_MAX - a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((0 > a) && (0 > b)) {
+ if (DK4_I16_MIN == a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ if ((DK4_I16_MIN - a) > b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ }
+finished:
+ return (a + b);
+}
+
+
+
+int16_t
+dk4ma_int16_t_sub(int16_t a, int16_t b, dk4_er_t *erp)
+{
+ if ((DK4_I16_MAX < a) || (DK4_I16_MIN > a)) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if ((DK4_I16_MAX < b) || (DK4_I16_MIN > b)) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if ((0 < a) && (0 > b)) {
+ if ((DK4_I16_MAX + b) < a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((0 > a) && (0 < b)) {
+ if ((DK4_I16_MIN + b) > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+finished:
+ return (a - b);
+}
+
+
+
+int16_t
+dk4ma_int16_t_mul(int16_t a, int16_t b, dk4_er_t *erp)
+{
+ if ((DK4_I16_MAX < a) || (DK4_I16_MIN > a)) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if ((DK4_I16_MAX < b) || (DK4_I16_MIN > b)) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if ((0 != a) && (0 != b)) {
+ if (DK4_I16_MIN == b) {
+ if (1 != a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if (DK4_I16_MIN == a) {
+ if (1 != b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if (0 < a) {
+ if (0 < b) {
+ if ((DK4_I16_MAX / a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((DK4_I16_MIN / a) > b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ } else {
+ if (0 < b) {
+ if ((DK4_I16_MIN / b) > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((DK4_I16_MAX / (0 - a)) < (0 - b)) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ }
+ }
+ }
+finished:
+ return (a * b);
+}
+
+
+
+int16_t
+dk4ma_int16_t_div(int16_t a, int16_t b, dk4_er_t *erp)
+{
+ int16_t back = 0;
+ if ((DK4_I16_MAX < a) || (DK4_I16_MIN > a)) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if ((DK4_I16_MAX < b) || (DK4_I16_MIN > b)) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+finished:
+ if (0 != b) {
+ if ((DK4_I16_MIN == a) && (-1 == b)) {
+ back = DK4_I16_MAX;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ back = a / b;
+ }
+ } else {
+ if (0 < a) {
+ back = DK4_I16_MAX;
+ } else {
+ if (0 > a) {
+ back = DK4_I16_MIN;
+ }
+ }
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_DIVZERO);
+ }
+ return back;
+}
+
+
+
+int16_t
+dk4ma_int16_t_abs(int16_t a, dk4_er_t *erp)
+{
+ if (DK4_I16_MIN != a) {
+ return (0 - a);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ return (DK4_I16_MAX);
+ }
+}
+
diff --git a/support/dktools/dk4maai16.ctr b/support/dktools/dk4maai16.ctr
new file mode 100644
index 0000000000..d8aef32f4b
--- /dev/null
+++ b/support/dktools/dk4maai16.ctr
@@ -0,0 +1,299 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+
+%% header
+
+/** @file dk4maai16.h Operations on int16_t data.
+*/
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef DK4_STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define DK4_STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef DK4_SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define DK4_SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDINT_H
+#ifndef DK4_STDINT_H_INCLUDED
+#include <stdint.h>
+#define DK4_STDINT_H_INCLUDED 1
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Addition of int16_t.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Operation result.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if a or b is out of range
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overfow occured.
+*/
+int16_t
+dk4ma_int16_t_add(int16_t a, int16_t b, dk4_er_t *erp);
+
+/** Substraction of int16_t.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Operation result.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if a or b is out of range
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overfow occured.
+*/
+int16_t
+dk4ma_int16_t_sub(int16_t a, int16_t b, dk4_er_t *erp);
+
+/** Multiplication of int16_t.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Operation result.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if a or b is out of range
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overfow occured.
+*/
+int16_t
+dk4ma_int16_t_mul(int16_t a, int16_t b, dk4_er_t *erp);
+
+/** Division of int16_t.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Operation result.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if a or b is out of range
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overfow occured,
+ - DK4_E_MATH_DIVZERO<br>
+ if b is 0.
+*/
+int16_t
+dk4ma_int16_t_div(int16_t a, int16_t b, dk4_er_t *erp);
+
+/** Absolute value.
+ @param a Argument.
+ @param erp Error report, may be NULL.
+ @return Absolute value of a.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if a or b is out of range
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overfow occured.
+*/
+int16_t
+dk4ma_int16_t_abs(int16_t a, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4maai16.h"
+
+
+
+$!trace-include
+
+
+
+int16_t
+dk4ma_int16_t_add(int16_t a, int16_t b, dk4_er_t *erp)
+{
+ if ((DK4_I16_MAX < a) || (DK4_I16_MIN > a)) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if ((DK4_I16_MAX < b) || (DK4_I16_MIN > b)) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if ((0 < a) && (0 < b)) {
+ if ((DK4_I16_MAX - a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((0 > a) && (0 > b)) {
+ if (DK4_I16_MIN == a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ if ((DK4_I16_MIN - a) > b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ }
+finished:
+ return (a + b);
+}
+
+
+
+int16_t
+dk4ma_int16_t_sub(int16_t a, int16_t b, dk4_er_t *erp)
+{
+ if ((DK4_I16_MAX < a) || (DK4_I16_MIN > a)) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if ((DK4_I16_MAX < b) || (DK4_I16_MIN > b)) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if ((0 < a) && (0 > b)) {
+ if ((DK4_I16_MAX + b) < a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((0 > a) && (0 < b)) {
+ if ((DK4_I16_MIN + b) > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+finished:
+ return (a - b);
+}
+
+
+
+int16_t
+dk4ma_int16_t_mul(int16_t a, int16_t b, dk4_er_t *erp)
+{
+ if ((DK4_I16_MAX < a) || (DK4_I16_MIN > a)) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if ((DK4_I16_MAX < b) || (DK4_I16_MIN > b)) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if ((0 != a) && (0 != b)) {
+ if (DK4_I16_MIN == b) {
+ if (1 != a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if (DK4_I16_MIN == a) {
+ if (1 != b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if (0 < a) {
+ if (0 < b) {
+ if ((DK4_I16_MAX / a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((DK4_I16_MIN / a) > b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ } else {
+ if (0 < b) {
+ if ((DK4_I16_MIN / b) > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((DK4_I16_MAX / (0 - a)) < (0 - b)) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ }
+ }
+ }
+finished:
+ return (a * b);
+}
+
+
+
+int16_t
+dk4ma_int16_t_div(int16_t a, int16_t b, dk4_er_t *erp)
+{
+ int16_t back = 0;
+ if ((DK4_I16_MAX < a) || (DK4_I16_MIN > a)) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if ((DK4_I16_MAX < b) || (DK4_I16_MIN > b)) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+finished:
+ if (0 != b) {
+ if ((DK4_I16_MIN == a) && (-1 == b)) {
+ back = DK4_I16_MAX;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ back = a / b;
+ }
+ } else {
+ if (0 < a) {
+ back = DK4_I16_MAX;
+ } else {
+ if (0 > a) {
+ back = DK4_I16_MIN;
+ }
+ }
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_DIVZERO);
+ }
+ return back;
+}
+
+
+
+int16_t
+dk4ma_int16_t_abs(int16_t a, dk4_er_t *erp)
+{
+ if (DK4_I16_MIN != a) {
+ return (0 - a);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ return (DK4_I16_MAX);
+ }
+}
+
diff --git a/support/dktools/dk4maai16.h b/support/dktools/dk4maai16.h
new file mode 100644
index 0000000000..34da557eee
--- /dev/null
+++ b/support/dktools/dk4maai16.h
@@ -0,0 +1,166 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maai16.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAAI16_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAAI16_H_INCLUDED 1
+
+
+#line 9 "dk4maai16.ctr"
+
+/** @file dk4maai16.h Operations on int16_t data.
+*/
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef DK4_STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define DK4_STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef DK4_SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define DK4_SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDINT_H
+#ifndef DK4_STDINT_H_INCLUDED
+#include <stdint.h>
+#define DK4_STDINT_H_INCLUDED 1
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Addition of int16_t.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Operation result.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if a or b is out of range
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overfow occured.
+*/
+int16_t
+dk4ma_int16_t_add(int16_t a, int16_t b, dk4_er_t *erp);
+
+/** Substraction of int16_t.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Operation result.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if a or b is out of range
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overfow occured.
+*/
+int16_t
+dk4ma_int16_t_sub(int16_t a, int16_t b, dk4_er_t *erp);
+
+/** Multiplication of int16_t.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Operation result.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if a or b is out of range
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overfow occured.
+*/
+int16_t
+dk4ma_int16_t_mul(int16_t a, int16_t b, dk4_er_t *erp);
+
+/** Division of int16_t.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Operation result.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if a or b is out of range
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overfow occured,
+ - DK4_E_MATH_DIVZERO<br>
+ if b is 0.
+*/
+int16_t
+dk4ma_int16_t_div(int16_t a, int16_t b, dk4_er_t *erp);
+
+/** Absolute value.
+ @param a Argument.
+ @param erp Error report, may be NULL.
+ @return Absolute value of a.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if a or b is out of range
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overfow occured.
+*/
+int16_t
+dk4ma_int16_t_abs(int16_t a, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4maai32.c b/support/dktools/dk4maai32.c
new file mode 100644
index 0000000000..244829534a
--- /dev/null
+++ b/support/dktools/dk4maai32.c
@@ -0,0 +1,209 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maai32.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maai32.c The dk4maai32 module.
+*/
+
+
+#line 133 "dk4maai32.ctr"
+
+#include "dk4maai32.h"
+
+
+
+
+
+#line 139 "dk4maai32.ctr"
+
+
+
+int32_t
+dk4ma_int32_t_add(int32_t a, int32_t b, dk4_er_t *erp)
+{
+ if ((DK4_I32_MAX < a) || (DK4_I32_MIN > a)) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if ((DK4_I32_MAX < b) || (DK4_I32_MIN > b)) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if ((0L < a) && (0L < b)) {
+ if ((DK4_I32_MAX - a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((0L > a) && (0L > b)) {
+ if (DK4_I32_MIN == a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ if ((DK4_I32_MIN - a) > b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ }
+finished:
+ return (a + b);
+}
+
+
+
+int32_t
+dk4ma_int32_t_sub(int32_t a, int32_t b, dk4_er_t *erp)
+{
+ if ((DK4_I32_MAX < a) || (DK4_I32_MIN > a)) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if ((DK4_I32_MAX < b) || (DK4_I32_MIN > b)) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if ((0L < a) && (0L > b)) {
+ if ((DK4_I32_MAX + b) < a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((0L > a) && (0L < b)) {
+ if ((DK4_I32_MIN + b) > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+finished:
+ return (a - b);
+}
+
+
+
+int32_t
+dk4ma_int32_t_mul(int32_t a, int32_t b, dk4_er_t *erp)
+{
+ if ((DK4_I32_MAX < a) || (DK4_I32_MIN > a)) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if ((DK4_I32_MAX < b) || (DK4_I32_MIN > b)) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if ((0L != a) && (0L != b)) {
+ if (DK4_I32_MIN == b) {
+ if (1L != a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if (DK4_I32_MIN == a) {
+ if (1L != b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if (0L < a) {
+ if (0L < b) {
+ if ((DK4_I32_MAX / a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((DK4_I32_MIN / a) > b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ } else {
+ if (0L < b) {
+ if ((DK4_I32_MIN / b) > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((DK4_I32_MAX / (0L - a)) < (0L - b)) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ }
+ }
+ }
+finished:
+ return (a * b);
+}
+
+
+
+int32_t
+dk4ma_int32_t_div(int32_t a, int32_t b, dk4_er_t *erp)
+{
+ int32_t back = 0L;
+ if ((DK4_I32_MAX < a) || (DK4_I32_MIN > a)) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if ((DK4_I32_MAX < b) || (DK4_I32_MIN > b)) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+finished:
+ if (0L != b) {
+ if ((DK4_I32_MIN == a) && (-1L == b)) {
+ back = DK4_I32_MAX;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ back = a / b;
+ }
+ } else {
+ if (0L < a) {
+ back = DK4_I32_MAX;
+ } else {
+ if (0L > a) {
+ back = DK4_I32_MIN;
+ }
+ }
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_DIVZERO);
+ }
+ return back;
+}
+
+
+
+int32_t
+dk4ma_int32_t_abs(int32_t a, dk4_er_t *erp)
+{
+ if (DK4_I32_MIN != a) {
+ return (0L - a);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ return (DK4_I32_MAX);
+ }
+}
+
diff --git a/support/dktools/dk4maai32.ctr b/support/dktools/dk4maai32.ctr
new file mode 100644
index 0000000000..d03cd997bd
--- /dev/null
+++ b/support/dktools/dk4maai32.ctr
@@ -0,0 +1,299 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+
+%% header
+
+/** @file dk4maai32.h Operations on int32_t data.
+*/
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef DK4_STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define DK4_STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef DK4_SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define DK4_SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDINT_H
+#ifndef DK4_STDINT_H_INCLUDED
+#include <stdint.h>
+#define DK4_STDINT_H_INCLUDED 1
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Addition of int32_t.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Operation result.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if a or b is out of range
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overfow occured.
+*/
+int32_t
+dk4ma_int32_t_add(int32_t a, int32_t b, dk4_er_t *erp);
+
+/** Substraction of int32_t.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Operation result.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if a or b is out of range
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overfow occured.
+*/
+int32_t
+dk4ma_int32_t_sub(int32_t a, int32_t b, dk4_er_t *erp);
+
+/** Multiplication of int32_t.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Operation result.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if a or b is out of range
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overfow occured.
+*/
+int32_t
+dk4ma_int32_t_mul(int32_t a, int32_t b, dk4_er_t *erp);
+
+/** Division of int32_t.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Operation result.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if a or b is out of range
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overfow occured,
+ - DK4_E_MATH_DIVZERO<br>
+ if b is 0.
+*/
+int32_t
+dk4ma_int32_t_div(int32_t a, int32_t b, dk4_er_t *erp);
+
+/** Absolute value.
+ @param a Argument.
+ @param erp Error report, may be NULL.
+ @return Absolute value of a.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if a or b is out of range
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overfow occured.
+*/
+int32_t
+dk4ma_int32_t_abs(int32_t a, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4maai32.h"
+
+
+
+$!trace-include
+
+
+
+int32_t
+dk4ma_int32_t_add(int32_t a, int32_t b, dk4_er_t *erp)
+{
+ if ((DK4_I32_MAX < a) || (DK4_I32_MIN > a)) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if ((DK4_I32_MAX < b) || (DK4_I32_MIN > b)) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if ((0L < a) && (0L < b)) {
+ if ((DK4_I32_MAX - a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((0L > a) && (0L > b)) {
+ if (DK4_I32_MIN == a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ if ((DK4_I32_MIN - a) > b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ }
+finished:
+ return (a + b);
+}
+
+
+
+int32_t
+dk4ma_int32_t_sub(int32_t a, int32_t b, dk4_er_t *erp)
+{
+ if ((DK4_I32_MAX < a) || (DK4_I32_MIN > a)) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if ((DK4_I32_MAX < b) || (DK4_I32_MIN > b)) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if ((0L < a) && (0L > b)) {
+ if ((DK4_I32_MAX + b) < a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((0L > a) && (0L < b)) {
+ if ((DK4_I32_MIN + b) > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+finished:
+ return (a - b);
+}
+
+
+
+int32_t
+dk4ma_int32_t_mul(int32_t a, int32_t b, dk4_er_t *erp)
+{
+ if ((DK4_I32_MAX < a) || (DK4_I32_MIN > a)) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if ((DK4_I32_MAX < b) || (DK4_I32_MIN > b)) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if ((0L != a) && (0L != b)) {
+ if (DK4_I32_MIN == b) {
+ if (1L != a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if (DK4_I32_MIN == a) {
+ if (1L != b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if (0L < a) {
+ if (0L < b) {
+ if ((DK4_I32_MAX / a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((DK4_I32_MIN / a) > b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ } else {
+ if (0L < b) {
+ if ((DK4_I32_MIN / b) > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((DK4_I32_MAX / (0L - a)) < (0L - b)) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ }
+ }
+ }
+finished:
+ return (a * b);
+}
+
+
+
+int32_t
+dk4ma_int32_t_div(int32_t a, int32_t b, dk4_er_t *erp)
+{
+ int32_t back = 0L;
+ if ((DK4_I32_MAX < a) || (DK4_I32_MIN > a)) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if ((DK4_I32_MAX < b) || (DK4_I32_MIN > b)) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+finished:
+ if (0L != b) {
+ if ((DK4_I32_MIN == a) && (-1L == b)) {
+ back = DK4_I32_MAX;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ back = a / b;
+ }
+ } else {
+ if (0L < a) {
+ back = DK4_I32_MAX;
+ } else {
+ if (0L > a) {
+ back = DK4_I32_MIN;
+ }
+ }
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_DIVZERO);
+ }
+ return back;
+}
+
+
+
+int32_t
+dk4ma_int32_t_abs(int32_t a, dk4_er_t *erp)
+{
+ if (DK4_I32_MIN != a) {
+ return (0L - a);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ return (DK4_I32_MAX);
+ }
+}
+
diff --git a/support/dktools/dk4maai32.h b/support/dktools/dk4maai32.h
new file mode 100644
index 0000000000..98ff723f54
--- /dev/null
+++ b/support/dktools/dk4maai32.h
@@ -0,0 +1,166 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maai32.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAAI32_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAAI32_H_INCLUDED 1
+
+
+#line 9 "dk4maai32.ctr"
+
+/** @file dk4maai32.h Operations on int32_t data.
+*/
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef DK4_STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define DK4_STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef DK4_SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define DK4_SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDINT_H
+#ifndef DK4_STDINT_H_INCLUDED
+#include <stdint.h>
+#define DK4_STDINT_H_INCLUDED 1
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Addition of int32_t.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Operation result.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if a or b is out of range
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overfow occured.
+*/
+int32_t
+dk4ma_int32_t_add(int32_t a, int32_t b, dk4_er_t *erp);
+
+/** Substraction of int32_t.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Operation result.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if a or b is out of range
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overfow occured.
+*/
+int32_t
+dk4ma_int32_t_sub(int32_t a, int32_t b, dk4_er_t *erp);
+
+/** Multiplication of int32_t.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Operation result.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if a or b is out of range
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overfow occured.
+*/
+int32_t
+dk4ma_int32_t_mul(int32_t a, int32_t b, dk4_er_t *erp);
+
+/** Division of int32_t.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Operation result.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if a or b is out of range
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overfow occured,
+ - DK4_E_MATH_DIVZERO<br>
+ if b is 0.
+*/
+int32_t
+dk4ma_int32_t_div(int32_t a, int32_t b, dk4_er_t *erp);
+
+/** Absolute value.
+ @param a Argument.
+ @param erp Error report, may be NULL.
+ @return Absolute value of a.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if a or b is out of range
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overfow occured.
+*/
+int32_t
+dk4ma_int32_t_abs(int32_t a, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4maal.c b/support/dktools/dk4maal.c
new file mode 100644
index 0000000000..58eba88c6b
--- /dev/null
+++ b/support/dktools/dk4maal.c
@@ -0,0 +1,170 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maal.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maal.c The dk4maal module.
+*/
+
+
+#line 100 "dk4maal.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4numco.h"
+#include "dk4maal.h"
+
+
+
+long
+dk4ma_long_abs(long a, dk4_er_t *erp)
+{
+ if (LONG_MIN == a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return ((0L <= a) ? a : ((LONG_MIN == a) ? LONG_MAX : (0L - a)));
+}
+
+
+
+long
+dk4ma_long_add(long a, long b, dk4_er_t *erp)
+{
+ if ((0L < a) && (0L < b)) {
+ if ((LONG_MAX - a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((0L > a) && (0L > b)) {
+ if (LONG_MIN == a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ if ((LONG_MIN - a) > b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ }
+ return (a + b);
+}
+
+
+
+long
+dk4ma_long_sub(long a, long b, dk4_er_t *erp)
+{
+ if ((0L < a) && (0L > b)) {
+ if ((LONG_MAX + b) < a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((0L > a) && (0L < b)) {
+ if ((LONG_MIN + b) > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ return (a - b);
+}
+
+
+
+long
+dk4ma_long_mul(long a, long b, dk4_er_t *erp)
+{
+ if ((0L != a) && (0L != b)) {
+ if (LONG_MIN == a) {
+ if (1L != b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if (LONG_MIN == b) {
+ if (1L != a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if (0L < a) {
+ if (0L < b) {
+ if ((LONG_MAX / a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((LONG_MIN / a) > b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ } else {
+ if (0L < b) {
+ if ((LONG_MIN / b) > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((LONG_MAX / (0L - a)) < (0L - b)) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ }
+ }
+ }
+ return (a * b);
+}
+
+
+
+long
+dk4ma_long_div(long a, long b, dk4_er_t *erp)
+{
+ long back = 0;
+ if (0L != b) {
+ if ((LONG_MIN == a) && (-1L == b)) {
+ back = LONG_MAX;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ back = a / b;
+ }
+ } else {
+ if (0L < a) {
+ back = LONG_MAX;
+ } else {
+ if (0L > a) {
+ back = LONG_MIN;
+ }
+ }
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_DIVZERO);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4maal.ctr b/support/dktools/dk4maal.ctr
new file mode 100644
index 0000000000..601524b322
--- /dev/null
+++ b/support/dktools/dk4maal.ctr
@@ -0,0 +1,229 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ Arithmetic operations on long.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Absolute value.
+ @param a Operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, LONG_MAX if a is LONG_MIN
+ (overflow is reported in erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+long
+dk4ma_long_abs(long a, dk4_er_t *erp);
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+long
+dk4ma_long_add(long a, long b, dk4_er_t *erp);
+
+/** Subtraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+long
+dk4ma_long_sub(long a, long b, dk4_er_t *erp);
+
+/** Multiplication.
+ @param a Left factor.
+ @param b right factor.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant
+ bits on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+long
+dk4ma_long_mul(long a, long b, dk4_er_t *erp);
+
+/** Division.
+ @param a Counter (left operand).
+ @param b Denominator (right operand).
+ @param erp Error report, may be NULL.
+ @return Division result on success,
+ LONG_MIN, LONG_MAX, or 0 on division by zero or overflow
+ (see the ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW, DK4_E_DIVZERO.
+*/
+long
+dk4ma_long_div(long a, long b, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4numco.h"
+#include "dk4maal.h"
+
+
+
+long
+dk4ma_long_abs(long a, dk4_er_t *erp)
+{
+ if (LONG_MIN == a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return ((0L <= a) ? a : ((LONG_MIN == a) ? LONG_MAX : (0L - a)));
+}
+
+
+
+long
+dk4ma_long_add(long a, long b, dk4_er_t *erp)
+{
+ if ((0L < a) && (0L < b)) {
+ if ((LONG_MAX - a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((0L > a) && (0L > b)) {
+ if (LONG_MIN == a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ if ((LONG_MIN - a) > b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ }
+ return (a + b);
+}
+
+
+
+long
+dk4ma_long_sub(long a, long b, dk4_er_t *erp)
+{
+ if ((0L < a) && (0L > b)) {
+ if ((LONG_MAX + b) < a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((0L > a) && (0L < b)) {
+ if ((LONG_MIN + b) > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ return (a - b);
+}
+
+
+
+long
+dk4ma_long_mul(long a, long b, dk4_er_t *erp)
+{
+ if ((0L != a) && (0L != b)) {
+ if (LONG_MIN == a) {
+ if (1L != b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if (LONG_MIN == b) {
+ if (1L != a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if (0L < a) {
+ if (0L < b) {
+ if ((LONG_MAX / a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((LONG_MIN / a) > b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ } else {
+ if (0L < b) {
+ if ((LONG_MIN / b) > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((LONG_MAX / (0L - a)) < (0L - b)) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ }
+ }
+ }
+ return (a * b);
+}
+
+
+
+long
+dk4ma_long_div(long a, long b, dk4_er_t *erp)
+{
+ long back = 0;
+ if (0L != b) {
+ if ((LONG_MIN == a) && (-1L == b)) {
+ back = LONG_MAX;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ back = a / b;
+ }
+ } else {
+ if (0L < a) {
+ back = LONG_MAX;
+ } else {
+ if (0L > a) {
+ back = LONG_MIN;
+ }
+ }
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_DIVZERO);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4maal.h b/support/dktools/dk4maal.h
new file mode 100644
index 0000000000..9ad122aef6
--- /dev/null
+++ b/support/dktools/dk4maal.h
@@ -0,0 +1,133 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maal.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAAL_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAAL_H_INCLUDED 1
+
+
+#line 9 "dk4maal.ctr"
+
+/** @file
+ Arithmetic operations on long.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Absolute value.
+ @param a Operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, LONG_MAX if a is LONG_MIN
+ (overflow is reported in erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+long
+dk4ma_long_abs(long a, dk4_er_t *erp);
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+long
+dk4ma_long_add(long a, long b, dk4_er_t *erp);
+
+/** Subtraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+long
+dk4ma_long_sub(long a, long b, dk4_er_t *erp);
+
+/** Multiplication.
+ @param a Left factor.
+ @param b right factor.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant
+ bits on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+long
+dk4ma_long_mul(long a, long b, dk4_er_t *erp);
+
+/** Division.
+ @param a Counter (left operand).
+ @param b Denominator (right operand).
+ @param erp Error report, may be NULL.
+ @return Division result on success,
+ LONG_MIN, LONG_MAX, or 0 on division by zero or overflow
+ (see the ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW, DK4_E_DIVZERO.
+*/
+long
+dk4ma_long_div(long a, long b, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4maall.c b/support/dktools/dk4maall.c
new file mode 100644
index 0000000000..0aa0625610
--- /dev/null
+++ b/support/dktools/dk4maall.c
@@ -0,0 +1,173 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maall.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maall.c The dk4maall module.
+*/
+
+
+#line 104 "dk4maall.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4numco.h"
+#include "dk4maall.h"
+
+
+#if DK4_HAVE_LONG_LONG
+
+long long
+dk4ma_ll_abs(long long a, dk4_er_t *erp)
+{
+ if (LLONG_MIN == a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return ((0LL <= a) ? a : ((LLONG_MIN == a) ? LLONG_MAX : (0LL - a)));
+}
+
+
+
+long long
+dk4ma_ll_add(long long a, long long b, dk4_er_t *erp)
+{
+ if ((0LL < a) && (0LL < b)) {
+ if ((LLONG_MAX - a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((0LL > a) && (0LL > b)) {
+ if (LLONG_MIN == a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ if ((LLONG_MIN - a) > b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ }
+ return (a + b);
+}
+
+
+
+long long
+dk4ma_ll_sub(long long a, long long b, dk4_er_t *erp)
+{
+ if ((0LL < a) && (0LL > b)) {
+ if ((LLONG_MAX + b) < a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((0LL > a) && (0LL < b)) {
+ if ((LLONG_MIN + b) > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ return (a - b);
+}
+
+
+
+long long
+dk4ma_ll_mul(long long a, long long b, dk4_er_t *erp)
+{
+ if ((0LL != a) && (0LL != b)) {
+ if (LLONG_MIN == a) {
+ if (1LL != b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if (LLONG_MIN == b) {
+ if (1LL != a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if (0LL < a) {
+ if (0LL < b) {
+ if ((LLONG_MAX / a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((LLONG_MIN / a) > b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ } else {
+ if (0LL < b) {
+ if ((LLONG_MIN / b) > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((LLONG_MAX / (0LL - a)) < (0LL - b)) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ }
+ }
+ }
+ return (a * b);
+}
+
+
+
+long long
+dk4ma_ll_div(long long a, long long b, dk4_er_t *erp)
+{
+ long long back = 0;
+ if (0LL != b) {
+ if ((LLONG_MIN == a) && (-1LL == b)) {
+ back = LLONG_MAX;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ back = a / b;
+ }
+ } else {
+ if (0LL < a) {
+ back = LLONG_MAX;
+ } else {
+ if (0LL > a) {
+ back = LLONG_MIN;
+ }
+ }
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_DIVZERO);
+ }
+ return back;
+}
+
+
+#endif
+
diff --git a/support/dktools/dk4maall.ctr b/support/dktools/dk4maall.ctr
new file mode 100644
index 0000000000..35694bb4de
--- /dev/null
+++ b/support/dktools/dk4maall.ctr
@@ -0,0 +1,236 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ Arithmetic operations on long long.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if DK4_HAVE_LONG_LONG
+
+/** Absolute value.
+ @param a Operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, LLONG_MAX if a is LLONG_MIN
+ (overflow is reported in erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+long long
+dk4ma_ll_abs(long long a, dk4_er_t *erp);
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+long long
+dk4ma_ll_add(long long a, long long b, dk4_er_t *erp);
+
+/** Subtraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+long long
+dk4ma_ll_sub(long long a, long long b, dk4_er_t *erp);
+
+/** Multiplication.
+ @param a Left factor.
+ @param b right factor.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant
+ bits on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+long long
+dk4ma_ll_mul(long long a, long long b, dk4_er_t *erp);
+
+/** Division.
+ @param a Counter (left operand).
+ @param b Denominator (right operand).
+ @param erp Error report, may be NULL.
+ @return Division result on success,
+ LLONG_MIN, LLONG_MAX, or 0 on division by zero or overflow
+ (see the ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW, DK4_E_DIVZERO.
+*/
+long long
+dk4ma_ll_div(long long a, long long b, dk4_er_t *erp);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4numco.h"
+#include "dk4maall.h"
+
+
+#if DK4_HAVE_LONG_LONG
+
+long long
+dk4ma_ll_abs(long long a, dk4_er_t *erp)
+{
+ if (LLONG_MIN == a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return ((0LL <= a) ? a : ((LLONG_MIN == a) ? LLONG_MAX : (0LL - a)));
+}
+
+
+
+long long
+dk4ma_ll_add(long long a, long long b, dk4_er_t *erp)
+{
+ if ((0LL < a) && (0LL < b)) {
+ if ((LLONG_MAX - a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((0LL > a) && (0LL > b)) {
+ if (LLONG_MIN == a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ if ((LLONG_MIN - a) > b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ }
+ return (a + b);
+}
+
+
+
+long long
+dk4ma_ll_sub(long long a, long long b, dk4_er_t *erp)
+{
+ if ((0LL < a) && (0LL > b)) {
+ if ((LLONG_MAX + b) < a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((0LL > a) && (0LL < b)) {
+ if ((LLONG_MIN + b) > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ return (a - b);
+}
+
+
+
+long long
+dk4ma_ll_mul(long long a, long long b, dk4_er_t *erp)
+{
+ if ((0LL != a) && (0LL != b)) {
+ if (LLONG_MIN == a) {
+ if (1LL != b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if (LLONG_MIN == b) {
+ if (1LL != a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if (0LL < a) {
+ if (0LL < b) {
+ if ((LLONG_MAX / a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((LLONG_MIN / a) > b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ } else {
+ if (0LL < b) {
+ if ((LLONG_MIN / b) > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((LLONG_MAX / (0LL - a)) < (0LL - b)) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ }
+ }
+ }
+ return (a * b);
+}
+
+
+
+long long
+dk4ma_ll_div(long long a, long long b, dk4_er_t *erp)
+{
+ long long back = 0;
+ if (0LL != b) {
+ if ((LLONG_MIN == a) && (-1LL == b)) {
+ back = LLONG_MAX;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ back = a / b;
+ }
+ } else {
+ if (0LL < a) {
+ back = LLONG_MAX;
+ } else {
+ if (0LL > a) {
+ back = LLONG_MIN;
+ }
+ }
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_DIVZERO);
+ }
+ return back;
+}
+
+
+#endif
+
diff --git a/support/dktools/dk4maall.h b/support/dktools/dk4maall.h
new file mode 100644
index 0000000000..d00e019284
--- /dev/null
+++ b/support/dktools/dk4maall.h
@@ -0,0 +1,137 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maall.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAALL_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAALL_H_INCLUDED 1
+
+
+#line 9 "dk4maall.ctr"
+
+/** @file
+ Arithmetic operations on long long.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if DK4_HAVE_LONG_LONG
+
+/** Absolute value.
+ @param a Operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, LLONG_MAX if a is LLONG_MIN
+ (overflow is reported in erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+long long
+dk4ma_ll_abs(long long a, dk4_er_t *erp);
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+long long
+dk4ma_ll_add(long long a, long long b, dk4_er_t *erp);
+
+/** Subtraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+long long
+dk4ma_ll_sub(long long a, long long b, dk4_er_t *erp);
+
+/** Multiplication.
+ @param a Left factor.
+ @param b right factor.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant
+ bits on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+long long
+dk4ma_ll_mul(long long a, long long b, dk4_er_t *erp);
+
+/** Division.
+ @param a Counter (left operand).
+ @param b Denominator (right operand).
+ @param erp Error report, may be NULL.
+ @return Division result on success,
+ LLONG_MIN, LLONG_MAX, or 0 on division by zero or overflow
+ (see the ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW, DK4_E_DIVZERO.
+*/
+long long
+dk4ma_ll_div(long long a, long long b, dk4_er_t *erp);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4maalu.c b/support/dktools/dk4maalu.c
new file mode 100644
index 0000000000..67348ec9ce
--- /dev/null
+++ b/support/dktools/dk4maalu.c
@@ -0,0 +1,114 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maalu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maalu.c The dk4maalu module.
+*/
+
+
+#line 94 "dk4maalu.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4numco.h"
+#include "dk4maalu.h"
+
+
+
+
+
+#line 104 "dk4maalu.ctr"
+
+
+
+#if DK4_HAVE_LONG_LONG
+
+unsigned long long
+dk4ma_ull_add(unsigned long long a, unsigned long long b, dk4_er_t *erp)
+{
+ if ((ULLONG_MAX - a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return (unsigned long long)(a + b);
+}
+
+
+
+unsigned long long
+dk4ma_ull_sub(unsigned long long a, unsigned long long b, dk4_er_t *erp)
+{
+ if (b > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return (unsigned long long)(a - b);
+}
+
+
+
+unsigned long long
+dk4ma_ull_mul(unsigned long long a, unsigned long long b, dk4_er_t *erp)
+{
+ if (0ULL < a) {
+ if ((ULLONG_MAX / a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return (unsigned long long)(a * b);
+}
+
+
+
+unsigned long long
+dk4ma_ull_div(unsigned long long a, unsigned long long b, dk4_er_t *erp)
+{
+
+
+#line 148 "dk4maalu.ctr"
+ if (0ULL < b) {
+
+
+#line 150 "dk4maalu.ctr"
+ return (unsigned long long)(a / b);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_DIVZERO);
+
+
+#line 154 "dk4maalu.ctr"
+ return (unsigned long long)(ULLONG_MAX);
+ }
+}
+
+#endif
+
diff --git a/support/dktools/dk4maalu.ctr b/support/dktools/dk4maalu.ctr
new file mode 100644
index 0000000000..073bf6a19d
--- /dev/null
+++ b/support/dktools/dk4maalu.ctr
@@ -0,0 +1,159 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Arithmetic operations on unsigned long long.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if DK4_HAVE_LONG_LONG
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+unsigned long long
+dk4ma_ull_add(unsigned long long a, unsigned long long b, dk4_er_t *erp);
+
+/** Subtraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+unsigned long long
+dk4ma_ull_sub(unsigned long long a, unsigned long long b, dk4_er_t *erp);
+
+/** Multiplication.
+ @param a Left factor.
+ @param b right factor.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant
+ bits on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+unsigned long long
+dk4ma_ull_mul(unsigned long long a, unsigned long long b, dk4_er_t *erp);
+
+/** Division.
+ @param a Counter (left operand).
+ @param b Denominator (right operand).
+ @param erp Error report, may be NULL.
+ @return Division result on success,
+ ULLONG_MAX on division by zero
+ (see the ec component of erp).
+
+ Error codes: DK4_E_DIVZERO.
+*/
+unsigned long long
+dk4ma_ull_div(unsigned long long a, unsigned long long b, dk4_er_t *erp);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4numco.h"
+#include "dk4maalu.h"
+
+
+
+$!trace-include
+
+
+
+#if DK4_HAVE_LONG_LONG
+
+unsigned long long
+dk4ma_ull_add(unsigned long long a, unsigned long long b, dk4_er_t *erp)
+{
+ if ((ULLONG_MAX - a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return (unsigned long long)(a + b);
+}
+
+
+
+unsigned long long
+dk4ma_ull_sub(unsigned long long a, unsigned long long b, dk4_er_t *erp)
+{
+ if (b > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return (unsigned long long)(a - b);
+}
+
+
+
+unsigned long long
+dk4ma_ull_mul(unsigned long long a, unsigned long long b, dk4_er_t *erp)
+{
+ if (0ULL < a) {
+ if ((ULLONG_MAX / a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return (unsigned long long)(a * b);
+}
+
+
+
+unsigned long long
+dk4ma_ull_div(unsigned long long a, unsigned long long b, dk4_er_t *erp)
+{
+ $? "+ dk4ma_ull_div %llu %llu", a, b
+ if (0ULL < b) {
+ $? "- dk4ma_ull_div (normal) %llu", (a / b)
+ return (unsigned long long)(a / b);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_DIVZERO);
+ $? "- dk4ma_ull_div (divzero) %llu", ULLONG_MAX
+ return (unsigned long long)(ULLONG_MAX);
+ }
+}
+
+#endif
+
diff --git a/support/dktools/dk4maalu.h b/support/dktools/dk4maalu.h
new file mode 100644
index 0000000000..9070a0a28b
--- /dev/null
+++ b/support/dktools/dk4maalu.h
@@ -0,0 +1,126 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maalu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAALU_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAALU_H_INCLUDED 1
+
+
+#line 10 "dk4maalu.ctr"
+
+/** @file
+ Arithmetic operations on unsigned long long.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if DK4_HAVE_LONG_LONG
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+unsigned long long
+dk4ma_ull_add(unsigned long long a, unsigned long long b, dk4_er_t *erp);
+
+/** Subtraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+unsigned long long
+dk4ma_ull_sub(unsigned long long a, unsigned long long b, dk4_er_t *erp);
+
+/** Multiplication.
+ @param a Left factor.
+ @param b right factor.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant
+ bits on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+unsigned long long
+dk4ma_ull_mul(unsigned long long a, unsigned long long b, dk4_er_t *erp);
+
+/** Division.
+ @param a Counter (left operand).
+ @param b Denominator (right operand).
+ @param erp Error report, may be NULL.
+ @return Division result on success,
+ ULLONG_MAX on division by zero
+ (see the ec component of erp).
+
+ Error codes: DK4_E_DIVZERO.
+*/
+unsigned long long
+dk4ma_ull_div(unsigned long long a, unsigned long long b, dk4_er_t *erp);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4maami.c b/support/dktools/dk4maami.c
new file mode 100644
index 0000000000..f409005a71
--- /dev/null
+++ b/support/dktools/dk4maami.c
@@ -0,0 +1,173 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maami.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maami.c The dk4maami module.
+*/
+
+
+#line 104 "dk4maami.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4numco.h"
+#include "dk4maami.h"
+
+
+
+#if DK4_HAVE_INTMAX_T
+
+intmax_t
+dk4ma_intmax_t_abs(intmax_t a, dk4_er_t *erp)
+{
+ if (INTMAX_MIN == a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return (((intmax_t)0L <= a) ? a : ((INTMAX_MIN == a) ? INTMAX_MAX : ((intmax_t)0L - a)));
+}
+
+
+
+intmax_t
+dk4ma_intmax_t_add(intmax_t a, intmax_t b, dk4_er_t *erp)
+{
+ if (((intmax_t)0L < a) && ((intmax_t)0L < b)) {
+ if ((INTMAX_MAX - a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if (((intmax_t)0L > a) && ((intmax_t)0L > b)) {
+ if (INTMAX_MIN == a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ if ((INTMAX_MIN - a) > b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ }
+ return (a + b);
+}
+
+
+
+intmax_t
+dk4ma_intmax_t_sub(intmax_t a, intmax_t b, dk4_er_t *erp)
+{
+ if (((intmax_t)0L < a) && ((intmax_t)0L > b)) {
+ if ((INTMAX_MAX + b) < a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if (((intmax_t)0L > a) && ((intmax_t)0L < b)) {
+ if ((INTMAX_MIN + b) > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ return (a - b);
+}
+
+
+
+intmax_t
+dk4ma_intmax_t_mul(intmax_t a, intmax_t b, dk4_er_t *erp)
+{
+ if (((intmax_t)0L != a) && ((intmax_t)0L != b)) {
+ if (INTMAX_MIN == a) {
+ if ((intmax_t)1L != b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if (INTMAX_MIN == b) {
+ if ((intmax_t)1L != a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((intmax_t)0L < a) {
+ if ((intmax_t)0L < b) {
+ if ((INTMAX_MAX / a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((INTMAX_MIN / a) > b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ } else {
+ if ((intmax_t)0L < b) {
+ if ((INTMAX_MIN / b) > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((INTMAX_MAX / ((intmax_t)0L - a)) < ((intmax_t)0L - b)) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ }
+ }
+ }
+ return (a * b);
+}
+
+
+
+intmax_t
+dk4ma_intmax_t_div(intmax_t a, intmax_t b, dk4_er_t *erp)
+{
+ intmax_t back = 0;
+ if ((intmax_t)0L != b) {
+ if ((INTMAX_MIN == a) && ((intmax_t)(-1L) == b)) {
+ back = INTMAX_MAX;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ back = a / b;
+ }
+ } else {
+ if ((intmax_t)0L < a) {
+ back = INTMAX_MAX;
+ } else {
+ if ((intmax_t)0L > a) {
+ back = INTMAX_MIN;
+ }
+ }
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_DIVZERO);
+ }
+ return back;
+}
+
+#endif
+
diff --git a/support/dktools/dk4maami.ctr b/support/dktools/dk4maami.ctr
new file mode 100644
index 0000000000..b3bd550267
--- /dev/null
+++ b/support/dktools/dk4maami.ctr
@@ -0,0 +1,236 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ Arithmetic operations on intmax_t.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+/** Absolute value.
+ @param a Operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, INTMAX_MAX if a is INTMAX_MIN
+ (overflow is reported in erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+intmax_t
+dk4ma_intmax_t_abs(intmax_t a, dk4_er_t *erp);
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+intmax_t
+dk4ma_intmax_t_add(intmax_t a, intmax_t b, dk4_er_t *erp);
+
+/** Subtraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+intmax_t
+dk4ma_intmax_t_sub(intmax_t a, intmax_t b, dk4_er_t *erp);
+
+/** Multiplication.
+ @param a Left factor.
+ @param b right factor.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant
+ bits on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+intmax_t
+dk4ma_intmax_t_mul(intmax_t a, intmax_t b, dk4_er_t *erp);
+
+/** Division.
+ @param a Counter (left operand).
+ @param b Denominator (right operand).
+ @param erp Error report, may be NULL.
+ @return Division result on success,
+ INTMAX_MIN, INTMAX_MAX, or 0 on division by zero or overflow
+ (see the ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW, DK4_E_DIVZERO.
+*/
+intmax_t
+dk4ma_intmax_t_div(intmax_t a, intmax_t b, dk4_er_t *erp);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4numco.h"
+#include "dk4maami.h"
+
+
+
+#if DK4_HAVE_INTMAX_T
+
+intmax_t
+dk4ma_intmax_t_abs(intmax_t a, dk4_er_t *erp)
+{
+ if (INTMAX_MIN == a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return (((intmax_t)0L <= a) ? a : ((INTMAX_MIN == a) ? INTMAX_MAX : ((intmax_t)0L - a)));
+}
+
+
+
+intmax_t
+dk4ma_intmax_t_add(intmax_t a, intmax_t b, dk4_er_t *erp)
+{
+ if (((intmax_t)0L < a) && ((intmax_t)0L < b)) {
+ if ((INTMAX_MAX - a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if (((intmax_t)0L > a) && ((intmax_t)0L > b)) {
+ if (INTMAX_MIN == a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ if ((INTMAX_MIN - a) > b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ }
+ return (a + b);
+}
+
+
+
+intmax_t
+dk4ma_intmax_t_sub(intmax_t a, intmax_t b, dk4_er_t *erp)
+{
+ if (((intmax_t)0L < a) && ((intmax_t)0L > b)) {
+ if ((INTMAX_MAX + b) < a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if (((intmax_t)0L > a) && ((intmax_t)0L < b)) {
+ if ((INTMAX_MIN + b) > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ return (a - b);
+}
+
+
+
+intmax_t
+dk4ma_intmax_t_mul(intmax_t a, intmax_t b, dk4_er_t *erp)
+{
+ if (((intmax_t)0L != a) && ((intmax_t)0L != b)) {
+ if (INTMAX_MIN == a) {
+ if ((intmax_t)1L != b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if (INTMAX_MIN == b) {
+ if ((intmax_t)1L != a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((intmax_t)0L < a) {
+ if ((intmax_t)0L < b) {
+ if ((INTMAX_MAX / a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((INTMAX_MIN / a) > b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ } else {
+ if ((intmax_t)0L < b) {
+ if ((INTMAX_MIN / b) > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((INTMAX_MAX / ((intmax_t)0L - a)) < ((intmax_t)0L - b)) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ }
+ }
+ }
+ return (a * b);
+}
+
+
+
+intmax_t
+dk4ma_intmax_t_div(intmax_t a, intmax_t b, dk4_er_t *erp)
+{
+ intmax_t back = 0;
+ if ((intmax_t)0L != b) {
+ if ((INTMAX_MIN == a) && ((intmax_t)(-1L) == b)) {
+ back = INTMAX_MAX;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ back = a / b;
+ }
+ } else {
+ if ((intmax_t)0L < a) {
+ back = INTMAX_MAX;
+ } else {
+ if ((intmax_t)0L > a) {
+ back = INTMAX_MIN;
+ }
+ }
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_DIVZERO);
+ }
+ return back;
+}
+
+#endif
+
diff --git a/support/dktools/dk4maami.h b/support/dktools/dk4maami.h
new file mode 100644
index 0000000000..54f357f7fb
--- /dev/null
+++ b/support/dktools/dk4maami.h
@@ -0,0 +1,137 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maami.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAAMI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAAMI_H_INCLUDED 1
+
+
+#line 9 "dk4maami.ctr"
+
+/** @file
+ Arithmetic operations on intmax_t.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+/** Absolute value.
+ @param a Operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, INTMAX_MAX if a is INTMAX_MIN
+ (overflow is reported in erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+intmax_t
+dk4ma_intmax_t_abs(intmax_t a, dk4_er_t *erp);
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+intmax_t
+dk4ma_intmax_t_add(intmax_t a, intmax_t b, dk4_er_t *erp);
+
+/** Subtraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+intmax_t
+dk4ma_intmax_t_sub(intmax_t a, intmax_t b, dk4_er_t *erp);
+
+/** Multiplication.
+ @param a Left factor.
+ @param b right factor.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant
+ bits on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+intmax_t
+dk4ma_intmax_t_mul(intmax_t a, intmax_t b, dk4_er_t *erp);
+
+/** Division.
+ @param a Counter (left operand).
+ @param b Denominator (right operand).
+ @param erp Error report, may be NULL.
+ @return Division result on success,
+ INTMAX_MIN, INTMAX_MAX, or 0 on division by zero or overflow
+ (see the ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW, DK4_E_DIVZERO.
+*/
+intmax_t
+dk4ma_intmax_t_div(intmax_t a, intmax_t b, dk4_er_t *erp);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4maamu.c b/support/dktools/dk4maamu.c
new file mode 100644
index 0000000000..4a5914fc59
--- /dev/null
+++ b/support/dktools/dk4maamu.c
@@ -0,0 +1,99 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maamu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maamu.c The dk4maamu module.
+*/
+
+
+#line 94 "dk4maamu.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4numco.h"
+#include "dk4maamu.h"
+
+
+
+#if DK4_HAVE_INTMAX_T
+
+uintmax_t
+dk4ma_uintmax_t_add(uintmax_t a, uintmax_t b, dk4_er_t *erp)
+{
+ if ((UINTMAX_MAX - a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return (uintmax_t)(a + b);
+}
+
+
+
+uintmax_t
+dk4ma_uintmax_t_sub(uintmax_t a, uintmax_t b, dk4_er_t *erp)
+{
+ if (b > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return (uintmax_t)(a - b);
+}
+
+
+
+uintmax_t
+dk4ma_uintmax_t_mul(uintmax_t a, uintmax_t b, dk4_er_t *erp)
+{
+ if ((uintmax_t)0UL < a) {
+ if ((UINTMAX_MAX / a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return (uintmax_t)(a * b);
+}
+
+
+
+uintmax_t
+dk4ma_uintmax_t_div(uintmax_t a, uintmax_t b, dk4_er_t *erp)
+{
+ if ((uintmax_t)0UL < b) {
+ return (uintmax_t)(a / b);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_DIVZERO);
+ return (uintmax_t)(UINTMAX_MAX);
+ }
+}
+
+#endif
+
diff --git a/support/dktools/dk4maamu.ctr b/support/dktools/dk4maamu.ctr
new file mode 100644
index 0000000000..92621a52e6
--- /dev/null
+++ b/support/dktools/dk4maamu.ctr
@@ -0,0 +1,152 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Arithmetic operations on uintmax_t.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+uintmax_t
+dk4ma_uintmax_t_add(uintmax_t a, uintmax_t b, dk4_er_t *erp);
+
+/** Subtraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+uintmax_t
+dk4ma_uintmax_t_sub(uintmax_t a, uintmax_t b, dk4_er_t *erp);
+
+/** Multiplication.
+ @param a Left factor.
+ @param b right factor.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant
+ bits on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+uintmax_t
+dk4ma_uintmax_t_mul(uintmax_t a, uintmax_t b, dk4_er_t *erp);
+
+/** Division.
+ @param a Counter (left operand).
+ @param b Denominator (right operand).
+ @param erp Error report, may be NULL.
+ @return Division result on success,
+ UINTMAX_MAX on division by zero
+ (see the ec component of erp).
+
+ Error codes: DK4_E_DIVZERO.
+*/
+uintmax_t
+dk4ma_uintmax_t_div(uintmax_t a, uintmax_t b, dk4_er_t *erp);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4numco.h"
+#include "dk4maamu.h"
+
+
+
+#if DK4_HAVE_INTMAX_T
+
+uintmax_t
+dk4ma_uintmax_t_add(uintmax_t a, uintmax_t b, dk4_er_t *erp)
+{
+ if ((UINTMAX_MAX - a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return (uintmax_t)(a + b);
+}
+
+
+
+uintmax_t
+dk4ma_uintmax_t_sub(uintmax_t a, uintmax_t b, dk4_er_t *erp)
+{
+ if (b > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return (uintmax_t)(a - b);
+}
+
+
+
+uintmax_t
+dk4ma_uintmax_t_mul(uintmax_t a, uintmax_t b, dk4_er_t *erp)
+{
+ if ((uintmax_t)0UL < a) {
+ if ((UINTMAX_MAX / a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return (uintmax_t)(a * b);
+}
+
+
+
+uintmax_t
+dk4ma_uintmax_t_div(uintmax_t a, uintmax_t b, dk4_er_t *erp)
+{
+ if ((uintmax_t)0UL < b) {
+ return (uintmax_t)(a / b);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_DIVZERO);
+ return (uintmax_t)(UINTMAX_MAX);
+ }
+}
+
+#endif
+
diff --git a/support/dktools/dk4maamu.h b/support/dktools/dk4maamu.h
new file mode 100644
index 0000000000..a80361322c
--- /dev/null
+++ b/support/dktools/dk4maamu.h
@@ -0,0 +1,126 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maamu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAAMU_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAAMU_H_INCLUDED 1
+
+
+#line 10 "dk4maamu.ctr"
+
+/** @file
+ Arithmetic operations on uintmax_t.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+uintmax_t
+dk4ma_uintmax_t_add(uintmax_t a, uintmax_t b, dk4_er_t *erp);
+
+/** Subtraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+uintmax_t
+dk4ma_uintmax_t_sub(uintmax_t a, uintmax_t b, dk4_er_t *erp);
+
+/** Multiplication.
+ @param a Left factor.
+ @param b right factor.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant
+ bits on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+uintmax_t
+dk4ma_uintmax_t_mul(uintmax_t a, uintmax_t b, dk4_er_t *erp);
+
+/** Division.
+ @param a Counter (left operand).
+ @param b Denominator (right operand).
+ @param erp Error report, may be NULL.
+ @return Division result on success,
+ UINTMAX_MAX on division by zero
+ (see the ec component of erp).
+
+ Error codes: DK4_E_DIVZERO.
+*/
+uintmax_t
+dk4ma_uintmax_t_div(uintmax_t a, uintmax_t b, dk4_er_t *erp);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4maas.c b/support/dktools/dk4maas.c
new file mode 100644
index 0000000000..168469024e
--- /dev/null
+++ b/support/dktools/dk4maas.c
@@ -0,0 +1,170 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maas.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maas.c The dk4maas module.
+*/
+
+
+#line 100 "dk4maas.ctr"
+
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4numco.h"
+#include "dk4maas.h"
+
+
+
+short
+dk4ma_short_abs(short a, dk4_er_t *erp)
+{
+ if (SHRT_MIN == a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return (short)((0 <= a) ? a : ((SHRT_MIN == a) ? SHRT_MAX : (0 - a)));
+}
+
+
+
+short
+dk4ma_short_add(short a, short b, dk4_er_t *erp)
+{
+ if ((0 < a) && (0 < b)) {
+ if ((SHRT_MAX - a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((0 > a) && (0 > b)) {
+ if (SHRT_MIN == a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ if ((SHRT_MIN - a) > b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ }
+ return (short)(a + b);
+}
+
+
+
+short
+dk4ma_short_sub(short a, short b, dk4_er_t *erp)
+{
+ if ((0 < a) && (0 > b)) {
+ if ((SHRT_MAX + b) < a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if((0 > a) && (0 < b)) {
+ if ((SHRT_MIN + b) > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ return (short)(a - b);
+}
+
+
+
+short
+dk4ma_short_mul(short a, short b, dk4_er_t *erp)
+{
+ if ((0 != a) && (0 != b)) {
+ if (SHRT_MIN == a) {
+ if (1 != b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if (SHRT_MIN == b) {
+ if (1 != a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if (0 < a) {
+ if (0 < b) {
+ if ((SHRT_MAX / a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((SHRT_MIN / a) > b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ } else {
+ if (0 < b) {
+ if ((SHRT_MIN / b) > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((SHRT_MAX / (0 - a)) < (0 - b)) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ }
+ }
+ }
+ return (short)(a * b);
+}
+
+
+
+short
+dk4ma_short_div(short a, short b, dk4_er_t *erp)
+{
+ short back = 0;
+ if (0 != b) {
+ if ((SHRT_MIN == a) && (-1 == b)) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ back = SHRT_MAX;
+ } else {
+ back = a / b;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_DIVZERO);
+ if (0 < a) {
+ back = SHRT_MAX;
+ } else {
+ if (0 > a) {
+ back = SHRT_MIN;
+ }
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4maas.ctr b/support/dktools/dk4maas.ctr
new file mode 100644
index 0000000000..140c720fde
--- /dev/null
+++ b/support/dktools/dk4maas.ctr
@@ -0,0 +1,229 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Arithmetic operations on short.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Absolute value.
+ @param a Operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, SHRT_MAX if a is SHRT_MIN
+ (overflow is reported in erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+short
+dk4ma_short_abs(short a, dk4_er_t *erp);
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+short
+dk4ma_short_add(short a, short b, dk4_er_t *erp);
+
+/** Subtraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+short
+dk4ma_short_sub(short a, short b, dk4_er_t *erp);
+
+/** Multiplication.
+ @param a Left factor.
+ @param b right factor.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant
+ bits on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+short
+dk4ma_short_mul(short a, short b, dk4_er_t *erp);
+
+/** Division.
+ @param a Counter (left operand).
+ @param b Denominator (right operand).
+ @param erp Error report, may be NULL.
+ @return Division result on success,
+ SHRT_MIN, SHRT_MAX, or 0 on division by zero or overflow
+ (see the ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW, DK4_E_DIVZERO.
+*/
+short
+dk4ma_short_div(short a, short b, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4numco.h"
+#include "dk4maas.h"
+
+
+
+short
+dk4ma_short_abs(short a, dk4_er_t *erp)
+{
+ if (SHRT_MIN == a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return (short)((0 <= a) ? a : ((SHRT_MIN == a) ? SHRT_MAX : (0 - a)));
+}
+
+
+
+short
+dk4ma_short_add(short a, short b, dk4_er_t *erp)
+{
+ if ((0 < a) && (0 < b)) {
+ if ((SHRT_MAX - a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((0 > a) && (0 > b)) {
+ if (SHRT_MIN == a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ if ((SHRT_MIN - a) > b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ }
+ return (short)(a + b);
+}
+
+
+
+short
+dk4ma_short_sub(short a, short b, dk4_er_t *erp)
+{
+ if ((0 < a) && (0 > b)) {
+ if ((SHRT_MAX + b) < a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if((0 > a) && (0 < b)) {
+ if ((SHRT_MIN + b) > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ return (short)(a - b);
+}
+
+
+
+short
+dk4ma_short_mul(short a, short b, dk4_er_t *erp)
+{
+ if ((0 != a) && (0 != b)) {
+ if (SHRT_MIN == a) {
+ if (1 != b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if (SHRT_MIN == b) {
+ if (1 != a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if (0 < a) {
+ if (0 < b) {
+ if ((SHRT_MAX / a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((SHRT_MIN / a) > b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ } else {
+ if (0 < b) {
+ if ((SHRT_MIN / b) > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ if ((SHRT_MAX / (0 - a)) < (0 - b)) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ }
+ }
+ }
+ return (short)(a * b);
+}
+
+
+
+short
+dk4ma_short_div(short a, short b, dk4_er_t *erp)
+{
+ short back = 0;
+ if (0 != b) {
+ if ((SHRT_MIN == a) && (-1 == b)) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ back = SHRT_MAX;
+ } else {
+ back = a / b;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_DIVZERO);
+ if (0 < a) {
+ back = SHRT_MAX;
+ } else {
+ if (0 > a) {
+ back = SHRT_MIN;
+ }
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4maas.h b/support/dktools/dk4maas.h
new file mode 100644
index 0000000000..11810e5010
--- /dev/null
+++ b/support/dktools/dk4maas.h
@@ -0,0 +1,132 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maas.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAAS_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAAS_H_INCLUDED 1
+
+
+#line 10 "dk4maas.ctr"
+
+/** @file
+ Arithmetic operations on short.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Absolute value.
+ @param a Operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, SHRT_MAX if a is SHRT_MIN
+ (overflow is reported in erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+short
+dk4ma_short_abs(short a, dk4_er_t *erp);
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+short
+dk4ma_short_add(short a, short b, dk4_er_t *erp);
+
+/** Subtraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+short
+dk4ma_short_sub(short a, short b, dk4_er_t *erp);
+
+/** Multiplication.
+ @param a Left factor.
+ @param b right factor.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant
+ bits on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+short
+dk4ma_short_mul(short a, short b, dk4_er_t *erp);
+
+/** Division.
+ @param a Counter (left operand).
+ @param b Denominator (right operand).
+ @param erp Error report, may be NULL.
+ @return Division result on success,
+ SHRT_MIN, SHRT_MAX, or 0 on division by zero or overflow
+ (see the ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW, DK4_E_DIVZERO.
+*/
+short
+dk4ma_short_div(short a, short b, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4maasz.c b/support/dktools/dk4maasz.c
new file mode 100644
index 0000000000..6b8cbbbe98
--- /dev/null
+++ b/support/dktools/dk4maasz.c
@@ -0,0 +1,103 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maasz.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maasz.c The dk4maasz module.
+*/
+
+
+#line 66 "dk4maasz.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+#if DK4_HAVE_LIMITS_H
+#ifndef LIMITS_H_INCLUDED
+#include <limits.h>
+#define LIMITS_H_INCLUDED 1
+#endif
+#endif
+#if DK4_HAVE_STDINT_H
+#ifndef STDINT_H_INCLUDED
+#if defined(__cplusplus) && (!defined(__STDC_LIMIT_MACROS))
+#define __STDC_LIMIT_MACROS 1
+#endif
+#if defined(__cplusplus) && (!defined(__STDC_CONSTANT_MACROS))
+#define __STDC_CONSTANT_MACROS 1
+#endif
+#include <stdint.h>
+#define STDINT_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4error.h"
+#include "dk4maasz.h"
+#include "dk4error.h"
+#include "dk4numco.h"
+
+
+
+size_t
+dk4ma_size_t_add(size_t a, size_t b, dk4_er_t *erp)
+{
+ if ((SIZE_MAX - b) < a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return (a + b);
+}
+
+
+
+size_t
+dk4ma_size_t_sub(size_t a, size_t b, dk4_er_t *erp)
+{
+ if (b > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return (a - b);
+}
+
+
+
+size_t
+dk4ma_size_t_mul(size_t a, size_t b, dk4_er_t *erp)
+{
+ if ((0 < a) && (0 < b)) {
+ if ((SIZE_MAX / a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return (a * b);
+}
+
diff --git a/support/dktools/dk4maasz.ctr b/support/dktools/dk4maasz.ctr
new file mode 100644
index 0000000000..b96dd28159
--- /dev/null
+++ b/support/dktools/dk4maasz.ctr
@@ -0,0 +1,128 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ Arithmetic operations on size_t.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Addition of size_t values.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result.
+*/
+size_t
+dk4ma_size_t_add(size_t a, size_t b, dk4_er_t *erp);
+
+/** Difference of size_t values.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result.
+*/
+size_t
+dk4ma_size_t_sub(size_t a, size_t b, dk4_er_t *erp);
+
+/** Multiplication of size_t values.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result.
+*/
+size_t
+dk4ma_size_t_mul(size_t a, size_t b, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+#if DK4_HAVE_LIMITS_H
+#ifndef LIMITS_H_INCLUDED
+#include <limits.h>
+#define LIMITS_H_INCLUDED 1
+#endif
+#endif
+#if DK4_HAVE_STDINT_H
+#ifndef STDINT_H_INCLUDED
+#if defined(__cplusplus) && (!defined(__STDC_LIMIT_MACROS))
+#define __STDC_LIMIT_MACROS 1
+#endif
+#if defined(__cplusplus) && (!defined(__STDC_CONSTANT_MACROS))
+#define __STDC_CONSTANT_MACROS 1
+#endif
+#include <stdint.h>
+#define STDINT_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4error.h"
+#include "dk4maasz.h"
+#include "dk4error.h"
+#include "dk4numco.h"
+
+
+
+size_t
+dk4ma_size_t_add(size_t a, size_t b, dk4_er_t *erp)
+{
+ if ((SIZE_MAX - b) < a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return (a + b);
+}
+
+
+
+size_t
+dk4ma_size_t_sub(size_t a, size_t b, dk4_er_t *erp)
+{
+ if (b > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return (a - b);
+}
+
+
+
+size_t
+dk4ma_size_t_mul(size_t a, size_t b, dk4_er_t *erp)
+{
+ if ((0 < a) && (0 < b)) {
+ if ((SIZE_MAX / a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return (a * b);
+}
+
diff --git a/support/dktools/dk4maasz.h b/support/dktools/dk4maasz.h
new file mode 100644
index 0000000000..db4808a827
--- /dev/null
+++ b/support/dktools/dk4maasz.h
@@ -0,0 +1,99 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maasz.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAASZ_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAASZ_H_INCLUDED 1
+
+
+#line 9 "dk4maasz.ctr"
+
+/** @file
+ Arithmetic operations on size_t.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Addition of size_t values.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result.
+*/
+size_t
+dk4ma_size_t_add(size_t a, size_t b, dk4_er_t *erp);
+
+/** Difference of size_t values.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result.
+*/
+size_t
+dk4ma_size_t_sub(size_t a, size_t b, dk4_er_t *erp);
+
+/** Multiplication of size_t values.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result.
+*/
+size_t
+dk4ma_size_t_mul(size_t a, size_t b, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4maau16.c b/support/dktools/dk4maau16.c
new file mode 100644
index 0000000000..04918050ff
--- /dev/null
+++ b/support/dktools/dk4maau16.c
@@ -0,0 +1,136 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maau16.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maau16.c The dk4maau16 module.
+*/
+
+
+#line 119 "dk4maau16.ctr"
+
+#include "dk4maau16.h"
+
+
+
+
+
+#line 125 "dk4maau16.ctr"
+
+
+
+uint16_t
+dk4ma_uint16_t_add(uint16_t a, uint16_t b, dk4_er_t *erp)
+{
+ if (DK4_U16_MAX < a) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if (DK4_U16_MAX < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if ((DK4_U16_MAX - a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+finished:
+ return (a + b);
+}
+
+
+
+uint16_t
+dk4ma_uint16_t_sub(uint16_t a, uint16_t b, dk4_er_t *erp)
+{
+ if (DK4_U16_MAX < a) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if (DK4_U16_MAX < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if (b > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+finished:
+ return (a - b);
+}
+
+
+
+uint16_t
+dk4ma_uint16_t_mul(uint16_t a, uint16_t b, dk4_er_t *erp)
+{
+ if (DK4_U16_MAX < a) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if (DK4_U16_MAX < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if ((0 < a) && (0 < b)) {
+ if ((DK4_U16_MAX / a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+finished:
+ return (a * b);
+}
+
+
+
+uint16_t
+dk4ma_uint16_t_div(uint16_t a, uint16_t b, dk4_er_t *erp)
+{
+ uint16_t back = 0;
+ if (DK4_U16_MAX < a) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if (DK4_U16_MAX < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+finished:
+ if (0 != b) {
+ back = a / b;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_DIVZERO);
+ }
+ return back;
+}
+
+
+
diff --git a/support/dktools/dk4maau16.ctr b/support/dktools/dk4maau16.ctr
new file mode 100644
index 0000000000..cad11e5c79
--- /dev/null
+++ b/support/dktools/dk4maau16.ctr
@@ -0,0 +1,212 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+
+%% header
+
+/** @file dk4maau16.h Operations on uint16_t data.
+*/
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef DK4_STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define DK4_STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef DK4_SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define DK4_SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDINT_H
+#ifndef DK4_STDINT_H_INCLUDED
+#include <stdint.h>
+#define DK4_STDINT_H_INCLUDED 1
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Addition of uint16_t.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Operation result.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if a or b is out of range
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overfow occured.
+*/
+uint16_t
+dk4ma_uint16_t_add(uint16_t a, uint16_t b, dk4_er_t *erp);
+
+/** Substraction of uint16_t.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Operation result.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if a or b is out of range
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overfow occured.
+*/
+uint16_t
+dk4ma_uint16_t_sub(uint16_t a, uint16_t b, dk4_er_t *erp);
+
+/** Multiplication of uint16_t.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Operation result.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if a or b is out of range
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overfow occured.
+*/
+uint16_t
+dk4ma_uint16_t_mul(uint16_t a, uint16_t b, dk4_er_t *erp);
+
+/** Division of uint16_t.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Operation result.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if a or b is out of range
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overfow occured,
+ - DK4_E_MATH_DIVZERO<br>
+ if b is 0.
+*/
+uint16_t
+dk4ma_uint16_t_div(uint16_t a, uint16_t b, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4maau16.h"
+
+
+
+$!trace-include
+
+
+
+uint16_t
+dk4ma_uint16_t_add(uint16_t a, uint16_t b, dk4_er_t *erp)
+{
+ if (DK4_U16_MAX < a) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if (DK4_U16_MAX < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if ((DK4_U16_MAX - a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+finished:
+ return (a + b);
+}
+
+
+
+uint16_t
+dk4ma_uint16_t_sub(uint16_t a, uint16_t b, dk4_er_t *erp)
+{
+ if (DK4_U16_MAX < a) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if (DK4_U16_MAX < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if (b > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+finished:
+ return (a - b);
+}
+
+
+
+uint16_t
+dk4ma_uint16_t_mul(uint16_t a, uint16_t b, dk4_er_t *erp)
+{
+ if (DK4_U16_MAX < a) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if (DK4_U16_MAX < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if ((0 < a) && (0 < b)) {
+ if ((DK4_U16_MAX / a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+finished:
+ return (a * b);
+}
+
+
+
+uint16_t
+dk4ma_uint16_t_div(uint16_t a, uint16_t b, dk4_er_t *erp)
+{
+ uint16_t back = 0;
+ if (DK4_U16_MAX < a) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if (DK4_U16_MAX < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+finished:
+ if (0 != b) {
+ back = a / b;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_DIVZERO);
+ }
+ return back;
+}
+
+
+
diff --git a/support/dktools/dk4maau16.h b/support/dktools/dk4maau16.h
new file mode 100644
index 0000000000..5607e6e7b3
--- /dev/null
+++ b/support/dktools/dk4maau16.h
@@ -0,0 +1,152 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maau16.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAAU16_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAAU16_H_INCLUDED 1
+
+
+#line 9 "dk4maau16.ctr"
+
+/** @file dk4maau16.h Operations on uint16_t data.
+*/
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef DK4_STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define DK4_STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef DK4_SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define DK4_SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDINT_H
+#ifndef DK4_STDINT_H_INCLUDED
+#include <stdint.h>
+#define DK4_STDINT_H_INCLUDED 1
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Addition of uint16_t.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Operation result.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if a or b is out of range
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overfow occured.
+*/
+uint16_t
+dk4ma_uint16_t_add(uint16_t a, uint16_t b, dk4_er_t *erp);
+
+/** Substraction of uint16_t.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Operation result.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if a or b is out of range
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overfow occured.
+*/
+uint16_t
+dk4ma_uint16_t_sub(uint16_t a, uint16_t b, dk4_er_t *erp);
+
+/** Multiplication of uint16_t.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Operation result.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if a or b is out of range
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overfow occured.
+*/
+uint16_t
+dk4ma_uint16_t_mul(uint16_t a, uint16_t b, dk4_er_t *erp);
+
+/** Division of uint16_t.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Operation result.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if a or b is out of range
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overfow occured,
+ - DK4_E_MATH_DIVZERO<br>
+ if b is 0.
+*/
+uint16_t
+dk4ma_uint16_t_div(uint16_t a, uint16_t b, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4maau32.c b/support/dktools/dk4maau32.c
new file mode 100644
index 0000000000..ca19ae6a8c
--- /dev/null
+++ b/support/dktools/dk4maau32.c
@@ -0,0 +1,136 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maau32.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maau32.c The dk4maau32 module.
+*/
+
+
+#line 119 "dk4maau32.ctr"
+
+#include "dk4maau32.h"
+
+
+
+
+
+#line 125 "dk4maau32.ctr"
+
+
+
+uint32_t
+dk4ma_uint32_t_add(uint32_t a, uint32_t b, dk4_er_t *erp)
+{
+ if (DK4_U32_MAX < a) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if (DK4_U32_MAX < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if ((DK4_U32_MAX - a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+finished:
+ return (a + b);
+}
+
+
+
+uint32_t
+dk4ma_uint32_t_sub(uint32_t a, uint32_t b, dk4_er_t *erp)
+{
+ if (DK4_U32_MAX < a) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if (DK4_U32_MAX < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if (b > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+finished:
+ return (a - b);
+}
+
+
+
+uint32_t
+dk4ma_uint32_t_mul(uint32_t a, uint32_t b, dk4_er_t *erp)
+{
+ if (DK4_U32_MAX < a) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if (DK4_U32_MAX < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if ((0L < a) && (0L < b)) {
+ if ((DK4_U32_MAX / a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+finished:
+ return (a * b);
+}
+
+
+
+uint32_t
+dk4ma_uint32_t_div(uint32_t a, uint32_t b, dk4_er_t *erp)
+{
+ uint32_t back = 0;
+ if (DK4_U32_MAX < a) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if (DK4_U32_MAX < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+finished:
+ if (0L != b) {
+ back = a / b;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_DIVZERO);
+ }
+ return back;
+}
+
+
+
diff --git a/support/dktools/dk4maau32.ctr b/support/dktools/dk4maau32.ctr
new file mode 100644
index 0000000000..6665abcb30
--- /dev/null
+++ b/support/dktools/dk4maau32.ctr
@@ -0,0 +1,212 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+
+%% header
+
+/** @file dk4maau32.h Operations on uint32_t data.
+*/
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef DK4_STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define DK4_STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef DK4_SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define DK4_SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDINT_H
+#ifndef DK4_STDINT_H_INCLUDED
+#include <stdint.h>
+#define DK4_STDINT_H_INCLUDED 1
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Addition of uint32_t.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Operation result.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if a or b is out of range
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overfow occured.
+*/
+uint32_t
+dk4ma_uint32_t_add(uint32_t a, uint32_t b, dk4_er_t *erp);
+
+/** Substraction of uint32_t.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Operation result.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if a or b is out of range
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overfow occured.
+*/
+uint32_t
+dk4ma_uint32_t_sub(uint32_t a, uint32_t b, dk4_er_t *erp);
+
+/** Multiplication of uint32_t.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Operation result.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if a or b is out of range
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overfow occured.
+*/
+uint32_t
+dk4ma_uint32_t_mul(uint32_t a, uint32_t b, dk4_er_t *erp);
+
+/** Division of uint32_t.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Operation result.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if a or b is out of range
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overfow occured,
+ - DK4_E_MATH_DIVZERO<br>
+ if b is 0.
+*/
+uint32_t
+dk4ma_uint32_t_div(uint32_t a, uint32_t b, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4maau32.h"
+
+
+
+$!trace-include
+
+
+
+uint32_t
+dk4ma_uint32_t_add(uint32_t a, uint32_t b, dk4_er_t *erp)
+{
+ if (DK4_U32_MAX < a) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if (DK4_U32_MAX < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if ((DK4_U32_MAX - a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+finished:
+ return (a + b);
+}
+
+
+
+uint32_t
+dk4ma_uint32_t_sub(uint32_t a, uint32_t b, dk4_er_t *erp)
+{
+ if (DK4_U32_MAX < a) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if (DK4_U32_MAX < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if (b > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+finished:
+ return (a - b);
+}
+
+
+
+uint32_t
+dk4ma_uint32_t_mul(uint32_t a, uint32_t b, dk4_er_t *erp)
+{
+ if (DK4_U32_MAX < a) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if (DK4_U32_MAX < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if ((0L < a) && (0L < b)) {
+ if ((DK4_U32_MAX / a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+finished:
+ return (a * b);
+}
+
+
+
+uint32_t
+dk4ma_uint32_t_div(uint32_t a, uint32_t b, dk4_er_t *erp)
+{
+ uint32_t back = 0;
+ if (DK4_U32_MAX < a) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if (DK4_U32_MAX < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+finished:
+ if (0L != b) {
+ back = a / b;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_DIVZERO);
+ }
+ return back;
+}
+
+
+
diff --git a/support/dktools/dk4maau32.h b/support/dktools/dk4maau32.h
new file mode 100644
index 0000000000..615a8afaa0
--- /dev/null
+++ b/support/dktools/dk4maau32.h
@@ -0,0 +1,152 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maau32.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAAU32_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAAU32_H_INCLUDED 1
+
+
+#line 9 "dk4maau32.ctr"
+
+/** @file dk4maau32.h Operations on uint32_t data.
+*/
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef DK4_STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define DK4_STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef DK4_SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define DK4_SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDINT_H
+#ifndef DK4_STDINT_H_INCLUDED
+#include <stdint.h>
+#define DK4_STDINT_H_INCLUDED 1
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Addition of uint32_t.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Operation result.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if a or b is out of range
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overfow occured.
+*/
+uint32_t
+dk4ma_uint32_t_add(uint32_t a, uint32_t b, dk4_er_t *erp);
+
+/** Substraction of uint32_t.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Operation result.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if a or b is out of range
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overfow occured.
+*/
+uint32_t
+dk4ma_uint32_t_sub(uint32_t a, uint32_t b, dk4_er_t *erp);
+
+/** Multiplication of uint32_t.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Operation result.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if a or b is out of range
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overfow occured.
+*/
+uint32_t
+dk4ma_uint32_t_mul(uint32_t a, uint32_t b, dk4_er_t *erp);
+
+/** Division of uint32_t.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Operation result.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if a or b is out of range
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overfow occured,
+ - DK4_E_MATH_DIVZERO<br>
+ if b is 0.
+*/
+uint32_t
+dk4ma_uint32_t_div(uint32_t a, uint32_t b, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4maauc.c b/support/dktools/dk4maauc.c
new file mode 100644
index 0000000000..b614ce6b69
--- /dev/null
+++ b/support/dktools/dk4maauc.c
@@ -0,0 +1,94 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maauc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maauc.c The dk4maauc module.
+*/
+
+
+#line 90 "dk4maauc.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4numco.h"
+#include "dk4maauc.h"
+
+
+unsigned char
+dk4ma_uchar_add(unsigned char a, unsigned char b, dk4_er_t *erp)
+{
+ if ((UCHAR_MAX - a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return (unsigned char)(a + b);
+}
+
+
+
+unsigned char
+dk4ma_uchar_sub(unsigned char a, unsigned char b, dk4_er_t *erp)
+{
+ if (b > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return (unsigned char)(a - b);
+}
+
+
+
+unsigned char
+dk4ma_uchar_mul(unsigned char a, unsigned char b, dk4_er_t *erp)
+{
+ if (0 < a) {
+ if ((UCHAR_MAX / a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return (unsigned char)(a * b);
+}
+
+
+
+unsigned char
+dk4ma_uchar_div(unsigned char a, unsigned char b, dk4_er_t *erp)
+{
+ if (0 < b) {
+ return (unsigned char)(a / b);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_DIVZERO);
+ return (unsigned char)(UCHAR_MAX);
+ }
+}
+
diff --git a/support/dktools/dk4maauc.ctr b/support/dktools/dk4maauc.ctr
new file mode 100644
index 0000000000..bb5a14421a
--- /dev/null
+++ b/support/dktools/dk4maauc.ctr
@@ -0,0 +1,143 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Arithmetic operations on unsigned char.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+unsigned char
+dk4ma_uchar_add(unsigned char a, unsigned char b, dk4_er_t *erp);
+
+/** Subtraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+unsigned char
+dk4ma_uchar_sub(unsigned char a, unsigned char b, dk4_er_t *erp);
+
+/** Multiplication.
+ @param a Left factor.
+ @param b right factor.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant
+ bits on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+unsigned char
+dk4ma_uchar_mul(unsigned char a, unsigned char b, dk4_er_t *erp);
+
+/** Division.
+ @param a Counter (left operand).
+ @param b Denominator (right operand).
+ @param erp Error report, may be NULL.
+ @return Division result on success,
+ UCHAR_MAX on division by zero
+ (see the ec component of erp).
+
+ Error codes: DK4_E_DIVZERO.
+*/
+unsigned char
+dk4ma_uchar_div(unsigned char a, unsigned char b, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4numco.h"
+#include "dk4maauc.h"
+
+
+unsigned char
+dk4ma_uchar_add(unsigned char a, unsigned char b, dk4_er_t *erp)
+{
+ if ((UCHAR_MAX - a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return (unsigned char)(a + b);
+}
+
+
+
+unsigned char
+dk4ma_uchar_sub(unsigned char a, unsigned char b, dk4_er_t *erp)
+{
+ if (b > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return (unsigned char)(a - b);
+}
+
+
+
+unsigned char
+dk4ma_uchar_mul(unsigned char a, unsigned char b, dk4_er_t *erp)
+{
+ if (0 < a) {
+ if ((UCHAR_MAX / a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return (unsigned char)(a * b);
+}
+
+
+
+unsigned char
+dk4ma_uchar_div(unsigned char a, unsigned char b, dk4_er_t *erp)
+{
+ if (0 < b) {
+ return (unsigned char)(a / b);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_DIVZERO);
+ return (unsigned char)(UCHAR_MAX);
+ }
+}
+
diff --git a/support/dktools/dk4maauc.h b/support/dktools/dk4maauc.h
new file mode 100644
index 0000000000..e971b8e067
--- /dev/null
+++ b/support/dktools/dk4maauc.h
@@ -0,0 +1,122 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maauc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAAUC_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAAUC_H_INCLUDED 1
+
+
+#line 10 "dk4maauc.ctr"
+
+/** @file
+ Arithmetic operations on unsigned char.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+unsigned char
+dk4ma_uchar_add(unsigned char a, unsigned char b, dk4_er_t *erp);
+
+/** Subtraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+unsigned char
+dk4ma_uchar_sub(unsigned char a, unsigned char b, dk4_er_t *erp);
+
+/** Multiplication.
+ @param a Left factor.
+ @param b right factor.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant
+ bits on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+unsigned char
+dk4ma_uchar_mul(unsigned char a, unsigned char b, dk4_er_t *erp);
+
+/** Division.
+ @param a Counter (left operand).
+ @param b Denominator (right operand).
+ @param erp Error report, may be NULL.
+ @return Division result on success,
+ UCHAR_MAX on division by zero
+ (see the ec component of erp).
+
+ Error codes: DK4_E_DIVZERO.
+*/
+unsigned char
+dk4ma_uchar_div(unsigned char a, unsigned char b, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4maaui.c b/support/dktools/dk4maaui.c
new file mode 100644
index 0000000000..ecb92816ee
--- /dev/null
+++ b/support/dktools/dk4maaui.c
@@ -0,0 +1,94 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maaui.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maaui.c The dk4maaui module.
+*/
+
+
+#line 90 "dk4maaui.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4numco.h"
+#include "dk4maaui.h"
+
+
+unsigned
+dk4ma_uint_add(unsigned a, unsigned b, dk4_er_t *erp)
+{
+ if ((UINT_MAX - a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return (unsigned)(a + b);
+}
+
+
+
+unsigned
+dk4ma_uint_sub(unsigned a, unsigned b, dk4_er_t *erp)
+{
+ if (b > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return (unsigned)(a - b);
+}
+
+
+
+unsigned
+dk4ma_uint_mul(unsigned a, unsigned b, dk4_er_t *erp)
+{
+ if (0U < a) {
+ if ((UINT_MAX / a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return (unsigned)(a * b);
+}
+
+
+
+unsigned
+dk4ma_uint_div(unsigned a, unsigned b, dk4_er_t *erp)
+{
+ if (0U < b) {
+ return (unsigned)(a / b);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_DIVZERO);
+ return (unsigned)(UINT_MAX);
+ }
+}
+
diff --git a/support/dktools/dk4maaui.ctr b/support/dktools/dk4maaui.ctr
new file mode 100644
index 0000000000..35a57ce74b
--- /dev/null
+++ b/support/dktools/dk4maaui.ctr
@@ -0,0 +1,143 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Arithmetic operations on unsigned int.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+unsigned
+dk4ma_uint_add(unsigned a, unsigned b, dk4_er_t *erp);
+
+/** Subtraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+unsigned
+dk4ma_uint_sub(unsigned a, unsigned b, dk4_er_t *erp);
+
+/** Multiplication.
+ @param a Left factor.
+ @param b right factor.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant
+ bits on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+unsigned
+dk4ma_uint_mul(unsigned a, unsigned b, dk4_er_t *erp);
+
+/** Division.
+ @param a Counter (left operand).
+ @param b Denominator (right operand).
+ @param erp Error report, may be NULL.
+ @return Division result on success,
+ UINT_MAX on division by zero
+ (see the ec component of erp).
+
+ Error codes: DK4_E_DIVZERO.
+*/
+unsigned
+dk4ma_uint_div(unsigned a, unsigned b, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4numco.h"
+#include "dk4maaui.h"
+
+
+unsigned
+dk4ma_uint_add(unsigned a, unsigned b, dk4_er_t *erp)
+{
+ if ((UINT_MAX - a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return (unsigned)(a + b);
+}
+
+
+
+unsigned
+dk4ma_uint_sub(unsigned a, unsigned b, dk4_er_t *erp)
+{
+ if (b > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return (unsigned)(a - b);
+}
+
+
+
+unsigned
+dk4ma_uint_mul(unsigned a, unsigned b, dk4_er_t *erp)
+{
+ if (0U < a) {
+ if ((UINT_MAX / a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return (unsigned)(a * b);
+}
+
+
+
+unsigned
+dk4ma_uint_div(unsigned a, unsigned b, dk4_er_t *erp)
+{
+ if (0U < b) {
+ return (unsigned)(a / b);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_DIVZERO);
+ return (unsigned)(UINT_MAX);
+ }
+}
+
diff --git a/support/dktools/dk4maaui.h b/support/dktools/dk4maaui.h
new file mode 100644
index 0000000000..b691eaf29f
--- /dev/null
+++ b/support/dktools/dk4maaui.h
@@ -0,0 +1,122 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maaui.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAAUI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAAUI_H_INCLUDED 1
+
+
+#line 10 "dk4maaui.ctr"
+
+/** @file
+ Arithmetic operations on unsigned int.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+unsigned
+dk4ma_uint_add(unsigned a, unsigned b, dk4_er_t *erp);
+
+/** Subtraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+unsigned
+dk4ma_uint_sub(unsigned a, unsigned b, dk4_er_t *erp);
+
+/** Multiplication.
+ @param a Left factor.
+ @param b right factor.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant
+ bits on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+unsigned
+dk4ma_uint_mul(unsigned a, unsigned b, dk4_er_t *erp);
+
+/** Division.
+ @param a Counter (left operand).
+ @param b Denominator (right operand).
+ @param erp Error report, may be NULL.
+ @return Division result on success,
+ UINT_MAX on division by zero
+ (see the ec component of erp).
+
+ Error codes: DK4_E_DIVZERO.
+*/
+unsigned
+dk4ma_uint_div(unsigned a, unsigned b, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4maaul.c b/support/dktools/dk4maaul.c
new file mode 100644
index 0000000000..c8e2145198
--- /dev/null
+++ b/support/dktools/dk4maaul.c
@@ -0,0 +1,118 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maaul.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maaul.c The dk4maaul module.
+*/
+
+
+#line 90 "dk4maaul.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4numco.h"
+#include "dk4maaul.h"
+
+
+
+
+
+#line 100 "dk4maaul.ctr"
+
+
+
+unsigned long
+dk4ma_ulong_add(unsigned long a, unsigned long b, dk4_er_t *erp)
+{
+
+
+#line 107 "dk4maaul.ctr"
+
+
+#line 108 "dk4maaul.ctr"
+
+
+#line 109 "dk4maaul.ctr"
+
+
+#line 110 "dk4maaul.ctr"
+ if ((ULONG_MAX - a) < b) {
+
+#line 111 "dk4maaul.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+
+
+#line 114 "dk4maaul.ctr"
+ return (unsigned long)(a + b);
+}
+
+
+
+unsigned long
+dk4ma_ulong_sub(unsigned long a, unsigned long b, dk4_er_t *erp)
+{
+ if (b > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return (unsigned long)(a - b);
+}
+
+
+
+unsigned long
+dk4ma_ulong_mul(unsigned long a, unsigned long b, dk4_er_t *erp)
+{
+ if (0UL < a) {
+ if ((ULONG_MAX / a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return (unsigned long)(a * b);
+}
+
+
+
+unsigned long
+dk4ma_ulong_div(unsigned long a, unsigned long b, dk4_er_t *erp)
+{
+ if (0UL < b) {
+ return (unsigned long)(a / b);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_DIVZERO);
+ return (unsigned long)(ULONG_MAX);
+ }
+}
+
diff --git a/support/dktools/dk4maaul.ctr b/support/dktools/dk4maaul.ctr
new file mode 100644
index 0000000000..487c354a29
--- /dev/null
+++ b/support/dktools/dk4maaul.ctr
@@ -0,0 +1,153 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Arithmetic operations on unsigned long.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+unsigned long
+dk4ma_ulong_add(unsigned long a, unsigned long b, dk4_er_t *erp);
+
+/** Subtraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+unsigned long
+dk4ma_ulong_sub(unsigned long a, unsigned long b, dk4_er_t *erp);
+
+/** Multiplication.
+ @param a Left factor.
+ @param b right factor.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant
+ bits on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+unsigned long
+dk4ma_ulong_mul(unsigned long a, unsigned long b, dk4_er_t *erp);
+
+/** Division.
+ @param a Counter (left operand).
+ @param b Denominator (right operand).
+ @param erp Error report, may be NULL.
+ @return Division result on success,
+ ULONG_MAX on division by zero
+ (see the ec component of erp).
+
+ Error codes: DK4_E_DIVZERO.
+*/
+unsigned long
+dk4ma_ulong_div(unsigned long a, unsigned long b, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4numco.h"
+#include "dk4maaul.h"
+
+
+
+$!trace-include
+
+
+
+unsigned long
+dk4ma_ulong_add(unsigned long a, unsigned long b, dk4_er_t *erp)
+{
+ $? "+ dk4ma_ulong_add %lu %lu", a, b
+ $? ". ULONG_MAX = %lu", ULONG_MAX
+ $? ". ULONG_MAX - a = %lu", (ULONG_MAX - a)
+ $? ". b = %lu", b
+ if ((ULONG_MAX - a) < b) { $? "! overflow"
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ $? "- dk4ma_ulong_add %lu", (a+b)
+ return (unsigned long)(a + b);
+}
+
+
+
+unsigned long
+dk4ma_ulong_sub(unsigned long a, unsigned long b, dk4_er_t *erp)
+{
+ if (b > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return (unsigned long)(a - b);
+}
+
+
+
+unsigned long
+dk4ma_ulong_mul(unsigned long a, unsigned long b, dk4_er_t *erp)
+{
+ if (0UL < a) {
+ if ((ULONG_MAX / a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return (unsigned long)(a * b);
+}
+
+
+
+unsigned long
+dk4ma_ulong_div(unsigned long a, unsigned long b, dk4_er_t *erp)
+{
+ if (0UL < b) {
+ return (unsigned long)(a / b);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_DIVZERO);
+ return (unsigned long)(ULONG_MAX);
+ }
+}
+
diff --git a/support/dktools/dk4maaul.h b/support/dktools/dk4maaul.h
new file mode 100644
index 0000000000..f830845422
--- /dev/null
+++ b/support/dktools/dk4maaul.h
@@ -0,0 +1,122 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maaul.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAAUL_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAAUL_H_INCLUDED 1
+
+
+#line 10 "dk4maaul.ctr"
+
+/** @file
+ Arithmetic operations on unsigned long.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+unsigned long
+dk4ma_ulong_add(unsigned long a, unsigned long b, dk4_er_t *erp);
+
+/** Subtraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+unsigned long
+dk4ma_ulong_sub(unsigned long a, unsigned long b, dk4_er_t *erp);
+
+/** Multiplication.
+ @param a Left factor.
+ @param b right factor.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant
+ bits on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+unsigned long
+dk4ma_ulong_mul(unsigned long a, unsigned long b, dk4_er_t *erp);
+
+/** Division.
+ @param a Counter (left operand).
+ @param b Denominator (right operand).
+ @param erp Error report, may be NULL.
+ @return Division result on success,
+ ULONG_MAX on division by zero
+ (see the ec component of erp).
+
+ Error codes: DK4_E_DIVZERO.
+*/
+unsigned long
+dk4ma_ulong_div(unsigned long a, unsigned long b, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4maaus.c b/support/dktools/dk4maaus.c
new file mode 100644
index 0000000000..604714485c
--- /dev/null
+++ b/support/dktools/dk4maaus.c
@@ -0,0 +1,94 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maaus.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maaus.c The dk4maaus module.
+*/
+
+
+#line 90 "dk4maaus.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4numco.h"
+#include "dk4maaus.h"
+
+
+unsigned short
+dk4ma_ushort_add(unsigned short a, unsigned short b, dk4_er_t *erp)
+{
+ if ((USHRT_MAX - a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return (unsigned short)(a + b);
+}
+
+
+
+unsigned short
+dk4ma_ushort_sub(unsigned short a, unsigned short b, dk4_er_t *erp)
+{
+ if (b > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return (unsigned short)(a - b);
+}
+
+
+
+unsigned short
+dk4ma_ushort_mul(unsigned short a, unsigned short b, dk4_er_t *erp)
+{
+ if (0U < a) {
+ if ((USHRT_MAX / a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return (unsigned short)(a * b);
+}
+
+
+
+unsigned short
+dk4ma_ushort_div(unsigned short a, unsigned short b, dk4_er_t *erp)
+{
+ if (0U < b) {
+ return (unsigned short)(a / b);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_DIVZERO);
+ return (unsigned short)(USHRT_MAX);
+ }
+}
+
diff --git a/support/dktools/dk4maaus.ctr b/support/dktools/dk4maaus.ctr
new file mode 100644
index 0000000000..e991c99471
--- /dev/null
+++ b/support/dktools/dk4maaus.ctr
@@ -0,0 +1,143 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Arithmetic operations on unsigned short.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+unsigned short
+dk4ma_ushort_add(unsigned short a, unsigned short b, dk4_er_t *erp);
+
+/** Subtraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+unsigned short
+dk4ma_ushort_sub(unsigned short a, unsigned short b, dk4_er_t *erp);
+
+/** Multiplication.
+ @param a Left factor.
+ @param b right factor.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant
+ bits on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+unsigned short
+dk4ma_ushort_mul(unsigned short a, unsigned short b, dk4_er_t *erp);
+
+/** Division.
+ @param a Counter (left operand).
+ @param b Denominator (right operand).
+ @param erp Error report, may be NULL.
+ @return Division result on success,
+ USHRT_MAX on division by zero
+ (see the ec component of erp).
+
+ Error codes: DK4_E_DIVZERO.
+*/
+unsigned short
+dk4ma_ushort_div(unsigned short a, unsigned short b, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4numco.h"
+#include "dk4maaus.h"
+
+
+unsigned short
+dk4ma_ushort_add(unsigned short a, unsigned short b, dk4_er_t *erp)
+{
+ if ((USHRT_MAX - a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return (unsigned short)(a + b);
+}
+
+
+
+unsigned short
+dk4ma_ushort_sub(unsigned short a, unsigned short b, dk4_er_t *erp)
+{
+ if (b > a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return (unsigned short)(a - b);
+}
+
+
+
+unsigned short
+dk4ma_ushort_mul(unsigned short a, unsigned short b, dk4_er_t *erp)
+{
+ if (0U < a) {
+ if ((USHRT_MAX / a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return (unsigned short)(a * b);
+}
+
+
+
+unsigned short
+dk4ma_ushort_div(unsigned short a, unsigned short b, dk4_er_t *erp)
+{
+ if (0U < b) {
+ return (unsigned short)(a / b);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_DIVZERO);
+ return (unsigned short)(USHRT_MAX);
+ }
+}
+
diff --git a/support/dktools/dk4maaus.h b/support/dktools/dk4maaus.h
new file mode 100644
index 0000000000..e243a6ee23
--- /dev/null
+++ b/support/dktools/dk4maaus.h
@@ -0,0 +1,122 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maaus.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAAUS_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAAUS_H_INCLUDED 1
+
+
+#line 10 "dk4maaus.ctr"
+
+/** @file
+ Arithmetic operations on unsigned short.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Addition.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+unsigned short
+dk4ma_ushort_add(unsigned short a, unsigned short b, dk4_er_t *erp);
+
+/** Subtraction.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant result bits
+ on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+unsigned short
+dk4ma_ushort_sub(unsigned short a, unsigned short b, dk4_er_t *erp);
+
+/** Multiplication.
+ @param a Left factor.
+ @param b right factor.
+ @param erp Error report, may be NULL.
+ @return Result on success, least significant
+ bits on overflow (see ec component of erp).
+
+ Error codes: DK4_E_OVERFLOW.
+*/
+unsigned short
+dk4ma_ushort_mul(unsigned short a, unsigned short b, dk4_er_t *erp);
+
+/** Division.
+ @param a Counter (left operand).
+ @param b Denominator (right operand).
+ @param erp Error report, may be NULL.
+ @return Division result on success,
+ USHRT_MAX on division by zero
+ (see the ec component of erp).
+
+ Error codes: DK4_E_DIVZERO.
+*/
+unsigned short
+dk4ma_ushort_div(unsigned short a, unsigned short b, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4macc.c b/support/dktools/dk4macc.c
new file mode 100644
index 0000000000..474a9f31d7
--- /dev/null
+++ b/support/dktools/dk4macc.c
@@ -0,0 +1,61 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4macc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4macc.c The dk4macc module.
+*/
+
+
+#line 34 "dk4macc.ctr"
+
+#include "dk4macc.h"
+
+int
+dk4ma_char_compare(signed char s, unsigned char u)
+{
+ int back = 0;
+ if (0 > s) {
+ back = -1;
+ } else {
+ if ((unsigned char)s < u) {
+ back = -1;
+ } else {
+ if ((unsigned char)s > u) {
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4macc.ctr b/support/dktools/dk4macc.ctr
new file mode 100644
index 0000000000..4cd01f6587
--- /dev/null
+++ b/support/dktools/dk4macc.ctr
@@ -0,0 +1,54 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ Comparison between signed and unsigned
+ character.
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Compare signed and unsigned char.
+ @param s Signed char.
+ @param u Unsigned char.
+ @return 1 if s>u, 0 if s==u, -1 if s<u.
+*/
+int
+dk4ma_char_compare(signed char s, unsigned char u);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4macc.h"
+
+int
+dk4ma_char_compare(signed char s, unsigned char u)
+{
+ int back = 0;
+ if (0 > s) {
+ back = -1;
+ } else {
+ if ((unsigned char)s < u) {
+ back = -1;
+ } else {
+ if ((unsigned char)s > u) {
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4macc.h b/support/dktools/dk4macc.h
new file mode 100644
index 0000000000..1655e250ff
--- /dev/null
+++ b/support/dktools/dk4macc.h
@@ -0,0 +1,67 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4macc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MACC_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MACC_H_INCLUDED 1
+
+
+#line 9 "dk4macc.ctr"
+
+/** @file
+ Comparison between signed and unsigned
+ character.
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Compare signed and unsigned char.
+ @param s Signed char.
+ @param u Unsigned char.
+ @return 1 if s>u, 0 if s==u, -1 if s<u.
+*/
+int
+dk4ma_char_compare(signed char s, unsigned char u);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4macd.c b/support/dktools/dk4macd.c
new file mode 100644
index 0000000000..18e9bb0fbb
--- /dev/null
+++ b/support/dktools/dk4macd.c
@@ -0,0 +1,70 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4macd.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4macd.c The dk4macd module.
+*/
+
+
+#line 43 "dk4macd.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+#if DK4_HAVE_INTMAX_T
+#include "dk4macm.h"
+#else
+#if DK4_HAVE_LONG_LONG
+#include "dk4macll.h"
+#else
+#include "dk4macl.h"
+#endif
+#endif
+
+#include "dk4macd.h"
+
+int
+dk4ma_im_compare(dk4_im_t s, dk4_um_t u)
+{
+#if DK4_HAVE_INTMAX_T
+ return (dk4ma_intmax_t_compare(s, u));
+#else
+#if DK4_HAVE_LONG_LONG
+ return (dk4ma_long_long_compare(s, u));
+#else
+ return (dk4ma_long_compare(s, u));
+#endif
+#endif
+}
+
diff --git a/support/dktools/dk4macd.ctr b/support/dktools/dk4macd.ctr
new file mode 100644
index 0000000000..19ea859b5d
--- /dev/null
+++ b/support/dktools/dk4macd.ctr
@@ -0,0 +1,72 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Comparison between signed and unsigned
+ number (dk4_im_t and dk4_um_t).
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Compare dk4_im_t and dk4_um_t.
+ @param s dk4_im_t.
+ @param u dk4_um_t.
+ @return 1 if s>u, 0 if s==u, -1 if s<u.
+*/
+int
+dk4ma_im_compare(dk4_im_t s, dk4_um_t u);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+#if DK4_HAVE_INTMAX_T
+#include "dk4macm.h"
+#else
+#if DK4_HAVE_LONG_LONG
+#include "dk4macll.h"
+#else
+#include "dk4macl.h"
+#endif
+#endif
+
+#include "dk4macd.h"
+
+int
+dk4ma_im_compare(dk4_im_t s, dk4_um_t u)
+{
+#if DK4_HAVE_INTMAX_T
+ return (dk4ma_intmax_t_compare(s, u));
+#else
+#if DK4_HAVE_LONG_LONG
+ return (dk4ma_long_long_compare(s, u));
+#else
+ return (dk4ma_long_compare(s, u));
+#endif
+#endif
+}
+
diff --git a/support/dktools/dk4macd.h b/support/dktools/dk4macd.h
new file mode 100644
index 0000000000..14cd7bb660
--- /dev/null
+++ b/support/dktools/dk4macd.h
@@ -0,0 +1,75 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4macd.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MACD_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MACD_H_INCLUDED 1
+
+
+#line 10 "dk4macd.ctr"
+
+/** @file
+ Comparison between signed and unsigned
+ number (dk4_im_t and dk4_um_t).
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Compare dk4_im_t and dk4_um_t.
+ @param s dk4_im_t.
+ @param u dk4_um_t.
+ @return 1 if s>u, 0 if s==u, -1 if s<u.
+*/
+int
+dk4ma_im_compare(dk4_im_t s, dk4_um_t u);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4maci.c b/support/dktools/dk4maci.c
new file mode 100644
index 0000000000..3b8245b723
--- /dev/null
+++ b/support/dktools/dk4maci.c
@@ -0,0 +1,61 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maci.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maci.c The dk4maci module.
+*/
+
+
+#line 35 "dk4maci.ctr"
+
+#include "dk4maci.h"
+
+int
+dk4ma_int_compare(int s, unsigned int u)
+{
+ int back = 0;
+ if (0 > s) {
+ back = -1;
+ } else {
+ if ((unsigned int)s < u) {
+ back = -1;
+ } else {
+ if ((unsigned int)s > u) {
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4maci.ctr b/support/dktools/dk4maci.ctr
new file mode 100644
index 0000000000..49afe41ab2
--- /dev/null
+++ b/support/dktools/dk4maci.ctr
@@ -0,0 +1,55 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Comparison between signed and unsigned
+ int.
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Compare signed and unsigned int.
+ @param s Signed int.
+ @param u Unsigned int.
+ @return 1 if s>u, 0 if s==u, -1 if s<u.
+*/
+int
+dk4ma_int_compare(int s, unsigned int u);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4maci.h"
+
+int
+dk4ma_int_compare(int s, unsigned int u)
+{
+ int back = 0;
+ if (0 > s) {
+ back = -1;
+ } else {
+ if ((unsigned int)s < u) {
+ back = -1;
+ } else {
+ if ((unsigned int)s > u) {
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4maci.h b/support/dktools/dk4maci.h
new file mode 100644
index 0000000000..842da5732c
--- /dev/null
+++ b/support/dktools/dk4maci.h
@@ -0,0 +1,67 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maci.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MACI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MACI_H_INCLUDED 1
+
+
+#line 10 "dk4maci.ctr"
+
+/** @file
+ Comparison between signed and unsigned
+ int.
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Compare signed and unsigned int.
+ @param s Signed int.
+ @param u Unsigned int.
+ @return 1 if s>u, 0 if s==u, -1 if s<u.
+*/
+int
+dk4ma_int_compare(int s, unsigned int u);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maci16.c b/support/dktools/dk4maci16.c
new file mode 100644
index 0000000000..af96f267db
--- /dev/null
+++ b/support/dktools/dk4maci16.c
@@ -0,0 +1,62 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maci16.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maci16.c The dk4maci16 module.
+*/
+
+
+#line 64 "dk4maci16.ctr"
+
+#include "dk4maci16.h"
+
+
+int
+dk4ma_int16_t_compare(int16_t s, uint16_t u)
+{
+ int back = 0;
+ if (0 > s) {
+ back = -1;
+ } else {
+ if ((uint16_t)s > u) {
+ back = 1;
+ } else {
+ if ((uint16_t)s < u) {
+ back = -1;
+ }
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4maci16.ctr b/support/dktools/dk4maci16.ctr
new file mode 100644
index 0000000000..2db11327c7
--- /dev/null
+++ b/support/dktools/dk4maci16.ctr
@@ -0,0 +1,85 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+
+%% header
+
+/** @file dk4maci16.h Signed/unsigned comparison for 16 bit int.
+*/
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef DK4_STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define DK4_STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef DK4_SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define DK4_SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDINT_H
+#ifndef DK4_STDINT_H_INCLUDED
+#include <stdint.h>
+#define DK4_STDINT_H_INCLUDED 1
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Compare signed and unsigned 16 bit int.
+ @param s Signed long.
+ @param u Unsigned long.
+ @return 1 if s>u, 0 if s==u, -1 if s<u.
+*/
+int
+dk4ma_int16_t_compare(int16_t s, uint16_t u);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4maci16.h"
+
+
+int
+dk4ma_int16_t_compare(int16_t s, uint16_t u)
+{
+ int back = 0;
+ if (0 > s) {
+ back = -1;
+ } else {
+ if ((uint16_t)s > u) {
+ back = 1;
+ } else {
+ if ((uint16_t)s < u) {
+ back = -1;
+ }
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4maci16.h b/support/dktools/dk4maci16.h
new file mode 100644
index 0000000000..cecf000cf0
--- /dev/null
+++ b/support/dktools/dk4maci16.h
@@ -0,0 +1,97 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maci16.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MACI16_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MACI16_H_INCLUDED 1
+
+
+#line 9 "dk4maci16.ctr"
+
+/** @file dk4maci16.h Signed/unsigned comparison for 16 bit int.
+*/
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef DK4_STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define DK4_STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef DK4_SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define DK4_SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDINT_H
+#ifndef DK4_STDINT_H_INCLUDED
+#include <stdint.h>
+#define DK4_STDINT_H_INCLUDED 1
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Compare signed and unsigned 16 bit int.
+ @param s Signed long.
+ @param u Unsigned long.
+ @return 1 if s>u, 0 if s==u, -1 if s<u.
+*/
+int
+dk4ma_int16_t_compare(int16_t s, uint16_t u);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4maci32.c b/support/dktools/dk4maci32.c
new file mode 100644
index 0000000000..efef31623b
--- /dev/null
+++ b/support/dktools/dk4maci32.c
@@ -0,0 +1,62 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maci32.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maci32.c The dk4maci32 module.
+*/
+
+
+#line 64 "dk4maci32.ctr"
+
+#include "dk4maci32.h"
+
+
+int
+dk4ma_int32_t_compare(int32_t s, uint32_t u)
+{
+ int back = 0;
+ if (0L > s) {
+ back = -1;
+ } else {
+ if ((uint32_t)s > u) {
+ back = 1;
+ } else {
+ if ((uint32_t)s < u) {
+ back = -1;
+ }
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4maci32.ctr b/support/dktools/dk4maci32.ctr
new file mode 100644
index 0000000000..bf15fc5aff
--- /dev/null
+++ b/support/dktools/dk4maci32.ctr
@@ -0,0 +1,85 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+
+%% header
+
+/** @file dk4maci32.h Signed/unsigned comparison for 32 bit int.
+*/
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef DK4_STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define DK4_STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef DK4_SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define DK4_SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDINT_H
+#ifndef DK4_STDINT_H_INCLUDED
+#include <stdint.h>
+#define DK4_STDINT_H_INCLUDED 1
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Compare signed and unsigned 32 bit int.
+ @param s Signed long.
+ @param u Unsigned long.
+ @return 1 if s>u, 0 if s==u, -1 if s<u.
+*/
+int
+dk4ma_int32_t_compare(int32_t s, uint32_t u);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4maci32.h"
+
+
+int
+dk4ma_int32_t_compare(int32_t s, uint32_t u)
+{
+ int back = 0;
+ if (0L > s) {
+ back = -1;
+ } else {
+ if ((uint32_t)s > u) {
+ back = 1;
+ } else {
+ if ((uint32_t)s < u) {
+ back = -1;
+ }
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4maci32.h b/support/dktools/dk4maci32.h
new file mode 100644
index 0000000000..8ff17f2fe7
--- /dev/null
+++ b/support/dktools/dk4maci32.h
@@ -0,0 +1,97 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maci32.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MACI32_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MACI32_H_INCLUDED 1
+
+
+#line 9 "dk4maci32.ctr"
+
+/** @file dk4maci32.h Signed/unsigned comparison for 32 bit int.
+*/
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef DK4_STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define DK4_STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef DK4_SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define DK4_SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDINT_H
+#ifndef DK4_STDINT_H_INCLUDED
+#include <stdint.h>
+#define DK4_STDINT_H_INCLUDED 1
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Compare signed and unsigned 32 bit int.
+ @param s Signed long.
+ @param u Unsigned long.
+ @return 1 if s>u, 0 if s==u, -1 if s<u.
+*/
+int
+dk4ma_int32_t_compare(int32_t s, uint32_t u);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4macl.c b/support/dktools/dk4macl.c
new file mode 100644
index 0000000000..3731e3fd28
--- /dev/null
+++ b/support/dktools/dk4macl.c
@@ -0,0 +1,61 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4macl.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4macl.c The dk4macl module.
+*/
+
+
+#line 35 "dk4macl.ctr"
+
+#include "dk4macl.h"
+
+int
+dk4ma_long_compare(long s, unsigned long u)
+{
+ int back = 0;
+ if (0L > s) {
+ back = -1;
+ } else {
+ if ((unsigned long)s < u) {
+ back = -1;
+ } else {
+ if ((unsigned long)s > u) {
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4macl.ctr b/support/dktools/dk4macl.ctr
new file mode 100644
index 0000000000..6de05cf886
--- /dev/null
+++ b/support/dktools/dk4macl.ctr
@@ -0,0 +1,55 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Comparison between signed and unsigned
+ long.
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Compare signed and unsigned long.
+ @param s Signed long.
+ @param u Unsigned long.
+ @return 1 if s>u, 0 if s==u, -1 if s<u.
+*/
+int
+dk4ma_long_compare(long s, unsigned long u);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4macl.h"
+
+int
+dk4ma_long_compare(long s, unsigned long u)
+{
+ int back = 0;
+ if (0L > s) {
+ back = -1;
+ } else {
+ if ((unsigned long)s < u) {
+ back = -1;
+ } else {
+ if ((unsigned long)s > u) {
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4macl.h b/support/dktools/dk4macl.h
new file mode 100644
index 0000000000..8c9b38f780
--- /dev/null
+++ b/support/dktools/dk4macl.h
@@ -0,0 +1,67 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4macl.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MACL_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MACL_H_INCLUDED 1
+
+
+#line 10 "dk4macl.ctr"
+
+/** @file
+ Comparison between signed and unsigned
+ long.
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Compare signed and unsigned long.
+ @param s Signed long.
+ @param u Unsigned long.
+ @return 1 if s>u, 0 if s==u, -1 if s<u.
+*/
+int
+dk4ma_long_compare(long s, unsigned long u);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4macll.c b/support/dktools/dk4macll.c
new file mode 100644
index 0000000000..43a482e575
--- /dev/null
+++ b/support/dktools/dk4macll.c
@@ -0,0 +1,65 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4macll.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4macll.c The dk4macll module.
+*/
+
+
+#line 49 "dk4macll.ctr"
+
+#include "dk4macll.h"
+
+#if DK4_HAVE_LONG_LONG
+
+int
+dk4ma_long_long_compare(long long s, unsigned long long u)
+{
+ int back = 0;
+ if (0LL > s) {
+ back = -1;
+ } else {
+ if ((unsigned long long)s < u) {
+ back = -1;
+ } else {
+ if ((unsigned long long)s > u) {
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+
+#endif
+
diff --git a/support/dktools/dk4macll.ctr b/support/dktools/dk4macll.ctr
new file mode 100644
index 0000000000..0432660b48
--- /dev/null
+++ b/support/dktools/dk4macll.ctr
@@ -0,0 +1,73 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Comparison between signed and unsigned
+ long long.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if DK4_HAVE_LONG_LONG
+
+/** Compare signed and unsigned long long.
+ @param s Signed long long.
+ @param u Unsigned long long.
+ @return 1 if s>u, 0 if s==u, -1 if s<u.
+*/
+int
+dk4ma_long_long_compare(long long s, unsigned long long u);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4macll.h"
+
+#if DK4_HAVE_LONG_LONG
+
+int
+dk4ma_long_long_compare(long long s, unsigned long long u)
+{
+ int back = 0;
+ if (0LL > s) {
+ back = -1;
+ } else {
+ if ((unsigned long long)s < u) {
+ back = -1;
+ } else {
+ if ((unsigned long long)s > u) {
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+
+#endif
+
diff --git a/support/dktools/dk4macll.h b/support/dktools/dk4macll.h
new file mode 100644
index 0000000000..18df43b6ac
--- /dev/null
+++ b/support/dktools/dk4macll.h
@@ -0,0 +1,81 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4macll.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MACLL_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MACLL_H_INCLUDED 1
+
+
+#line 10 "dk4macll.ctr"
+
+/** @file
+ Comparison between signed and unsigned
+ long long.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if DK4_HAVE_LONG_LONG
+
+/** Compare signed and unsigned long long.
+ @param s Signed long long.
+ @param u Unsigned long long.
+ @return 1 if s>u, 0 if s==u, -1 if s<u.
+*/
+int
+dk4ma_long_long_compare(long long s, unsigned long long u);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4macm.c b/support/dktools/dk4macm.c
new file mode 100644
index 0000000000..92ce22fa7b
--- /dev/null
+++ b/support/dktools/dk4macm.c
@@ -0,0 +1,67 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4macm.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4macm.c The dk4macm module.
+*/
+
+
+#line 49 "dk4macm.ctr"
+
+#include "dk4macm.h"
+
+
+
+#if DK4_HAVE_INTMAX_T
+
+int
+dk4ma_intmax_t_compare(intmax_t s, uintmax_t u)
+{
+ int back = 0;
+ if ((intmax_t)0L > s) {
+ back = -1;
+ } else {
+ if ((uintmax_t)s < u) {
+ back = -1;
+ } else {
+ if ((uintmax_t)s > u) {
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+
+#endif
+
diff --git a/support/dktools/dk4macm.ctr b/support/dktools/dk4macm.ctr
new file mode 100644
index 0000000000..f0e90842a5
--- /dev/null
+++ b/support/dktools/dk4macm.ctr
@@ -0,0 +1,75 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Comparison between signed and unsigned
+ number (intmax_t and uintmax_t).
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+/** Compare intmax_t and uintmax_t.
+ @param s Signed intmax_t.
+ @param u Unsigned intmax_t.
+ @return 1 if s>u, 0 if s==u, -1 if s<u.
+*/
+int
+dk4ma_intmax_t_compare(intmax_t s, uintmax_t u);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4macm.h"
+
+
+
+#if DK4_HAVE_INTMAX_T
+
+int
+dk4ma_intmax_t_compare(intmax_t s, uintmax_t u)
+{
+ int back = 0;
+ if ((intmax_t)0L > s) {
+ back = -1;
+ } else {
+ if ((uintmax_t)s < u) {
+ back = -1;
+ } else {
+ if ((uintmax_t)s > u) {
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+
+#endif
+
diff --git a/support/dktools/dk4macm.h b/support/dktools/dk4macm.h
new file mode 100644
index 0000000000..92409e3480
--- /dev/null
+++ b/support/dktools/dk4macm.h
@@ -0,0 +1,81 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4macm.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MACM_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MACM_H_INCLUDED 1
+
+
+#line 10 "dk4macm.ctr"
+
+/** @file
+ Comparison between signed and unsigned
+ number (intmax_t and uintmax_t).
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+/** Compare intmax_t and uintmax_t.
+ @param s Signed intmax_t.
+ @param u Unsigned intmax_t.
+ @return 1 if s>u, 0 if s==u, -1 if s<u.
+*/
+int
+dk4ma_intmax_t_compare(intmax_t s, uintmax_t u);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4macs.c b/support/dktools/dk4macs.c
new file mode 100644
index 0000000000..f23d389341
--- /dev/null
+++ b/support/dktools/dk4macs.c
@@ -0,0 +1,61 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4macs.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4macs.c The dk4macs module.
+*/
+
+
+#line 35 "dk4macs.ctr"
+
+#include "dk4macs.h"
+
+int
+dk4ma_short_compare(short s, unsigned short u)
+{
+ int back = 0;
+ if (0 > s) {
+ back = -1;
+ } else {
+ if ((unsigned short)s < u) {
+ back = -1;
+ } else {
+ if ((unsigned short)s > u) {
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4macs.ctr b/support/dktools/dk4macs.ctr
new file mode 100644
index 0000000000..97fab0ddc4
--- /dev/null
+++ b/support/dktools/dk4macs.ctr
@@ -0,0 +1,55 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Comparison between signed and unsigned
+ short.
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Compare signed and unsigned short.
+ @param s Signed short.
+ @param u Unsigned short.
+ @return 1 if s>u, 0 if s==u, -1 if s<u.
+*/
+int
+dk4ma_short_compare(short s, unsigned short u);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4macs.h"
+
+int
+dk4ma_short_compare(short s, unsigned short u)
+{
+ int back = 0;
+ if (0 > s) {
+ back = -1;
+ } else {
+ if ((unsigned short)s < u) {
+ back = -1;
+ } else {
+ if ((unsigned short)s > u) {
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4macs.h b/support/dktools/dk4macs.h
new file mode 100644
index 0000000000..32fad731d9
--- /dev/null
+++ b/support/dktools/dk4macs.h
@@ -0,0 +1,67 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4macs.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MACS_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MACS_H_INCLUDED 1
+
+
+#line 10 "dk4macs.ctr"
+
+/** @file
+ Comparison between signed and unsigned
+ short.
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Compare signed and unsigned short.
+ @param s Signed short.
+ @param u Unsigned short.
+ @return 1 if s>u, 0 if s==u, -1 if s<u.
+*/
+int
+dk4ma_short_compare(short s, unsigned short u);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4mai8dbl.c b/support/dktools/dk4mai8dbl.c
new file mode 100644
index 0000000000..1d9d081907
--- /dev/null
+++ b/support/dktools/dk4mai8dbl.c
@@ -0,0 +1,226 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8dbl.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mai8dbl.c The dk4mai8dbl module.
+*/
+
+
+#line 76 "dk4mai8dbl.ctr"
+
+
+#include "dk4mai8dbl.h"
+
+#include "dk4str8.h"
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_LOCALE_H
+#ifndef LOCALE_H_INCLUDED
+#include <locale.h>
+#define LOCALE_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_MATH_H
+#ifndef MATH_H_INCLUDED
+#include <math.h>
+#define MATH_H_INCLUDED 1
+#endif
+#endif
+
+
+
+/** Default locale to use.
+*/
+static const char locale_kw[] = { "C" };
+
+
+
+/** Read double value from char string.
+ @param rp Address of result variable.
+ @param src String to process.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here. The function may also store
+ a NULL pointer here.
+ The pointer variable is probably left unchanged
+ on errors or if strtod() is not available on your
+ system (the sscanf() function is used as fallback).
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characaters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_SYNTAX if there are unexpected characters in the
+ string,
+ DK4_E_MATH_OVERFLOW if a mathematical overflow occurs,
+ DK4_E_MATH_UNDERFLOW if a mathematical underflow occurs.
+*/
+
+static
+int
+dk4ma_internal_input_c8_double(
+ double *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_STRTOD || DK4_HAVE__STRTOD
+ double val = 0.0;
+ char *myend = NULL;
+ int back = 0;
+ int xerr = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ errno = 0;
+#if DK4_HAVE_STRTOD
+ val = strtod(src, &myend);
+#else
+ val = _strtod(src, &myend);
+#endif
+ xerr = errno;
+ if (NULL != endptr) { *endptr = myend; }
+ if (myend != src) {
+ switch (atg) {
+ case 2: {
+ back = 1;
+ } break;
+ case 1: {
+ if (NULL != dk4str8_start(myend, NULL)) {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } else {
+ back = 1;
+ }
+ } break;
+ default: {
+ if ('\0' == *myend) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ }
+ if (1 == back) {
+ if (ERANGE == xerr) {
+ if (HUGE_VAL == val) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ if ((-HUGE_VAL) == val) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ if (0.0 == val) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_UNDERFLOW);
+ }
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ if (1 == back) {
+ *rp = val;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+#if DK4_USE_PRINTF_SCANF
+ double val = 0.0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (1 == sscanf(src, "%lf", &val)) {
+ *rp = val;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+#endif
+}
+
+
+
+int
+dk4ma_input_c8_double(
+ double *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if (DK4_HAVE_SETLOCALE) && defined(LC_NUMERIC)
+ char *oldloc = NULL;
+#endif
+ int back = 0;
+#if (DK4_HAVE_SETLOCALE) && defined(LC_NUMERIC)
+ oldloc = setlocale(LC_NUMERIC, NULL);
+ (void)setlocale(LC_NUMERIC, locale_kw);
+ back = dk4ma_internal_input_c8_double(rp, src, endptr, atg, erp);
+ (void)setlocale(LC_NUMERIC, oldloc);
+#else
+ back = dk4ma_internal_input_c8_double(rp, src, endptr, atg, erp);
+#endif
+ return back;
+}
+
+
diff --git a/support/dktools/dk4mai8dbl.ctr b/support/dktools/dk4mai8dbl.ctr
new file mode 100644
index 0000000000..934270f057
--- /dev/null
+++ b/support/dktools/dk4mai8dbl.ctr
@@ -0,0 +1,261 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Read double value from char string.
+
+ CRT on Windows: Required.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Read double value from char string.
+ The function temporarily resets the LC_NUMERIC locale setting
+ to "C" to retrieve the number and returns the setting to the
+ original value before returning.
+ @param rp Address of result variable.
+ @param src String to process.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here. The function may also store
+ a NULL pointer here.
+ The pointer variable is probably left unchanged
+ on errors or if strtod() is not available on your
+ system (the sscanf() function is used as fallback).
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characaters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_SYNTAX if there are unexpected characters in the
+ string,
+ DK4_E_MATH_OVERFLOW if a mathematical overflow occurs,
+ DK4_E_MATH_UNDERFLOW if a mathematical underflow occurs.
+*/
+
+int
+dk4ma_input_c8_double(
+ double *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+
+#include "dk4mai8dbl.h"
+
+#include "dk4str8.h"
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_LOCALE_H
+#ifndef LOCALE_H_INCLUDED
+#include <locale.h>
+#define LOCALE_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_MATH_H
+#ifndef MATH_H_INCLUDED
+#include <math.h>
+#define MATH_H_INCLUDED 1
+#endif
+#endif
+
+
+
+/** Default locale to use.
+*/
+static const char locale_kw[] = { "C" };
+
+
+
+/** Read double value from char string.
+ @param rp Address of result variable.
+ @param src String to process.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here. The function may also store
+ a NULL pointer here.
+ The pointer variable is probably left unchanged
+ on errors or if strtod() is not available on your
+ system (the sscanf() function is used as fallback).
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characaters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_SYNTAX if there are unexpected characters in the
+ string,
+ DK4_E_MATH_OVERFLOW if a mathematical overflow occurs,
+ DK4_E_MATH_UNDERFLOW if a mathematical underflow occurs.
+*/
+
+static
+int
+dk4ma_internal_input_c8_double(
+ double *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_STRTOD || DK4_HAVE__STRTOD
+ double val = 0.0;
+ char *myend = NULL;
+ int back = 0;
+ int xerr = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ errno = 0;
+#if DK4_HAVE_STRTOD
+ val = strtod(src, &myend);
+#else
+ val = _strtod(src, &myend);
+#endif
+ xerr = errno;
+ if (NULL != endptr) { *endptr = myend; }
+ if (myend != src) {
+ switch (atg) {
+ case 2: {
+ back = 1;
+ } break;
+ case 1: {
+ if (NULL != dk4str8_start(myend, NULL)) {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } else {
+ back = 1;
+ }
+ } break;
+ default: {
+ if ('\0' == *myend) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ }
+ if (1 == back) {
+ if (ERANGE == xerr) {
+ if (HUGE_VAL == val) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ if ((-HUGE_VAL) == val) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ if (0.0 == val) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_UNDERFLOW);
+ }
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ if (1 == back) {
+ *rp = val;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+#if DK4_USE_PRINTF_SCANF
+ double val = 0.0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (1 == sscanf(src, "%lf", &val)) {
+ *rp = val;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+#endif
+}
+
+
+
+int
+dk4ma_input_c8_double(
+ double *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if (DK4_HAVE_SETLOCALE) && defined(LC_NUMERIC)
+ char *oldloc = NULL;
+#endif
+ int back = 0;
+#if (DK4_HAVE_SETLOCALE) && defined(LC_NUMERIC)
+ oldloc = setlocale(LC_NUMERIC, NULL);
+ (void)setlocale(LC_NUMERIC, locale_kw);
+ back = dk4ma_internal_input_c8_double(rp, src, endptr, atg, erp);
+ (void)setlocale(LC_NUMERIC, oldloc);
+#else
+ back = dk4ma_internal_input_c8_double(rp, src, endptr, atg, erp);
+#endif
+ return back;
+}
+
+
diff --git a/support/dktools/dk4mai8dbl.h b/support/dktools/dk4mai8dbl.h
new file mode 100644
index 0000000000..cc56ba02f3
--- /dev/null
+++ b/support/dktools/dk4mai8dbl.h
@@ -0,0 +1,108 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8dbl.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAI8DBL_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAI8DBL_H_INCLUDED 1
+
+
+#line 10 "dk4mai8dbl.ctr"
+
+/** @file
+ Read double value from char string.
+
+ CRT on Windows: Required.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Read double value from char string.
+ The function temporarily resets the LC_NUMERIC locale setting
+ to "C" to retrieve the number and returns the setting to the
+ original value before returning.
+ @param rp Address of result variable.
+ @param src String to process.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here. The function may also store
+ a NULL pointer here.
+ The pointer variable is probably left unchanged
+ on errors or if strtod() is not available on your
+ system (the sscanf() function is used as fallback).
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characaters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_SYNTAX if there are unexpected characters in the
+ string,
+ DK4_E_MATH_OVERFLOW if a mathematical overflow occurs,
+ DK4_E_MATH_UNDERFLOW if a mathematical underflow occurs.
+*/
+
+int
+dk4ma_input_c8_double(
+ double *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4mai8ddi.c b/support/dktools/dk4mai8ddi.c
new file mode 100644
index 0000000000..8ff0011369
--- /dev/null
+++ b/support/dktools/dk4mai8ddi.c
@@ -0,0 +1,124 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8ddi.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mai8ddi.c The dk4mai8ddi module.
+*/
+
+
+#line 70 "dk4mai8ddi.ctr"
+
+
+#include "dk4mai8ddi.h"
+#include "dk4mai8ddu.h"
+#include "dk4numco.h"
+#include "dk4str8.h"
+
+
+
+
+#line 79 "dk4mai8ddi.ctr"
+
+
+
+int
+dk4ma_input_c8_dec_dk4_im_t(
+ dk4_im_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_um_t res;
+ const char *ep = NULL;
+ int back = 0;
+
+
+#line 95 "dk4mai8ddi.ctr"
+ if ((NULL != rp) && (NULL != src)) {
+ if ('-' == *src) {
+
+#line 97 "dk4mai8ddi.ctr"
+ if (0 != dk4ma_input_c8_dec_dk4_um_t(&res, ++src, &ep, atg, erp)) {
+ if (((dk4_um_t)(DK4_IM_MAX) + (dk4_um_t)1UL) == res) {
+
+#line 99 "dk4mai8ddi.ctr"
+ *rp = DK4_IM_MIN;
+ back = 1;
+ } else {
+ if (((dk4_um_t)(DK4_IM_MAX)) >= res) {
+
+#line 103 "dk4mai8ddi.ctr"
+ *rp = (dk4_im_t)0L - (dk4_im_t)res;
+ back = 1;
+ } else {
+
+#line 106 "dk4mai8ddi.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ } else {
+
+#line 110 "dk4mai8ddi.ctr"
+ }
+ } else {
+
+#line 112 "dk4mai8ddi.ctr"
+ if (0 != dk4ma_input_c8_dec_dk4_um_t(&res, src, &ep, atg, erp)) {
+ if (((dk4_um_t)(DK4_IM_MAX)) >= res) {
+
+#line 114 "dk4mai8ddi.ctr"
+ *rp = (dk4_im_t)res;
+ back = 1;
+ } else {
+
+#line 117 "dk4mai8ddi.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+
+#line 120 "dk4mai8ddi.ctr"
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ if (NULL != endptr) { *endptr = ep; }
+
+
+#line 127 "dk4mai8ddi.ctr"
+ return back;
+}
+
diff --git a/support/dktools/dk4mai8ddi.ctr b/support/dktools/dk4mai8ddi.ctr
new file mode 100644
index 0000000000..c52744cdd2
--- /dev/null
+++ b/support/dktools/dk4mai8ddi.ctr
@@ -0,0 +1,129 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve dk4_im_t value from
+ 8 bit character string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_dec_dk4_im_t(
+ dk4_im_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+
+#include "dk4mai8ddi.h"
+#include "dk4mai8ddu.h"
+#include "dk4numco.h"
+#include "dk4str8.h"
+
+
+$!trace-include
+
+
+
+int
+dk4ma_input_c8_dec_dk4_im_t(
+ dk4_im_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_um_t res;
+ const char *ep = NULL;
+ int back = 0;
+ $? "+ dk4ma_input_c8_dec_dk4_im_t \"%!8s\" %d", src, atg
+ if ((NULL != rp) && (NULL != src)) {
+ if ('-' == *src) { $? ". negative"
+ if (0 != dk4ma_input_c8_dec_dk4_um_t(&res, ++src, &ep, atg, erp)) {
+ if (((dk4_um_t)(DK4_IM_MAX) + (dk4_um_t)1UL) == res) { $? ". ok min"
+ *rp = DK4_IM_MIN;
+ back = 1;
+ } else {
+ if (((dk4_um_t)(DK4_IM_MAX)) >= res) { $? ". ok neg"
+ *rp = (dk4_im_t)0L - (dk4_im_t)res;
+ back = 1;
+ } else { $? "! overflow"
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ } else { $? "! failed"
+ }
+ } else { $? ". not negative"
+ if (0 != dk4ma_input_c8_dec_dk4_um_t(&res, src, &ep, atg, erp)) {
+ if (((dk4_um_t)(DK4_IM_MAX)) >= res) { $? ". ok"
+ *rp = (dk4_im_t)res;
+ back = 1;
+ } else { $? "! overflow"
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else { $? "! failed"
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ if (NULL != endptr) { *endptr = ep; }
+ $? "- dk4ma_input_c8_dec_dk4_im_t %d", back
+ return back;
+}
+
diff --git a/support/dktools/dk4mai8ddi.h b/support/dktools/dk4mai8ddi.h
new file mode 100644
index 0000000000..2d2d486258
--- /dev/null
+++ b/support/dktools/dk4mai8ddi.h
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8ddi.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAI8DDI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAI8DDI_H_INCLUDED 1
+
+
+#line 10 "dk4mai8ddi.ctr"
+
+/** @file
+ Retrieve dk4_im_t value from
+ 8 bit character string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_dec_dk4_im_t(
+ dk4_im_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4mai8ddu.c b/support/dktools/dk4mai8ddu.c
new file mode 100644
index 0000000000..84932b8494
--- /dev/null
+++ b/support/dktools/dk4mai8ddu.c
@@ -0,0 +1,196 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8ddu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mai8ddu.c The dk4mai8ddu module.
+*/
+
+
+#line 70 "dk4mai8ddu.ctr"
+
+#include "dk4mai8ddu.h"
+#include "dk4numco.h"
+#include "dk4str8.h"
+
+
+
+
+
+#line 78 "dk4mai8ddu.ctr"
+
+
+
+int
+dk4ma_input_c8_dec_dk4_um_t(
+ dk4_um_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if VERSION_BEFORE_20141007
+ dk4_er_t er;
+#endif
+ dk4_um_t result= (dk4_um_t)0UL;
+ dk4_um_t op;
+ const char *ep = NULL;
+ int found = 0;
+ int back = 0;
+ int cc = 1;
+
+
+#line 100 "dk4mai8ddu.ctr"
+ if ((NULL != rp) && (NULL != src)) {
+#if VERSION_BEFORE_20141007
+ dk4error_init(&er);
+#endif
+ do {
+
+
+#line 106 "dk4mai8ddu.ctr"
+ op = (dk4_um_t)0UL;
+ switch (*src) {
+ case '0': { op = (dk4_um_t)0UL; } break;
+ case '1': { op = (dk4_um_t)1UL; } break;
+ case '2': { op = (dk4_um_t)2UL; } break;
+ case '3': { op = (dk4_um_t)3UL; } break;
+ case '4': { op = (dk4_um_t)4UL; } break;
+ case '5': { op = (dk4_um_t)5UL; } break;
+ case '6': { op = (dk4_um_t)6UL; } break;
+ case '7': { op = (dk4_um_t)7UL; } break;
+ case '8': { op = (dk4_um_t)8UL; } break;
+ case '9': { op = (dk4_um_t)9UL; } break;
+ case '\0': {
+
+#line 119 "dk4mai8ddu.ctr"
+ cc = 0;
+ if (0 != found) {
+
+#line 121 "dk4mai8ddu.ctr"
+ back = 1;
+ *rp = result;
+ } else {
+
+#line 124 "dk4mai8ddu.ctr"
+ ep = src;
+
+#line 125 "dk4mai8ddu.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ default: {
+ cc = 0;
+
+#line 130 "dk4mai8ddu.ctr"
+ ep = src;
+
+#line 131 "dk4mai8ddu.ctr"
+ if (0 != found) {
+ switch (atg) {
+ case 2: {
+
+#line 134 "dk4mai8ddu.ctr"
+ back = 1;
+ *rp = result;
+ } break;
+ case 1: {
+
+#line 138 "dk4mai8ddu.ctr"
+ if (NULL == dk4str8_start(src, NULL)) {
+ back = 1;
+ *rp = result;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ default: {
+
+#line 146 "dk4mai8ddu.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ }
+ if (0 != cc) {
+
+#line 155 "dk4mai8ddu.ctr"
+ found = 1;
+#if VERSION_BEFORE_20141007
+ result = dk4ma_um_add(
+ dk4ma_um_mul(result, (dk4_um_t)10UL, &er),
+ op, &er
+ );
+ if (DK4_E_NONE != er.ec) {
+ cc = 0;
+
+#line 163 "dk4mai8ddu.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ ep = src;
+ }
+#else
+ if ((DK4_UM_MAX / (dk4_um_t)10UL) >= result) {
+ result *= (dk4_um_t)10UL;
+ if ((DK4_UM_MAX - op) >= result) {
+ result += op;
+ } else {
+ cc = 0;
+ ep = src;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ cc = 0;
+ ep = src;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+#endif
+ }
+ if (0 != cc) {
+ src++;
+ }
+ } while (0 != cc);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ if (NULL != src) { ep = src; }
+ }
+ if (NULL != endptr) { *endptr = ep; }
+
+
+#line 193 "dk4mai8ddu.ctr"
+ return back;
+}
+
diff --git a/support/dktools/dk4mai8ddu.ctr b/support/dktools/dk4mai8ddu.ctr
new file mode 100644
index 0000000000..c5d771bedc
--- /dev/null
+++ b/support/dktools/dk4mai8ddu.ctr
@@ -0,0 +1,195 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve dk4_um_t value from
+ 8 bit character string in decimal notation.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_dec_dk4_um_t(
+ dk4_um_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4mai8ddu.h"
+#include "dk4numco.h"
+#include "dk4str8.h"
+
+
+
+$!trace-include
+
+
+
+int
+dk4ma_input_c8_dec_dk4_um_t(
+ dk4_um_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if VERSION_BEFORE_20141007
+ dk4_er_t er;
+#endif
+ dk4_um_t result= (dk4_um_t)0UL;
+ dk4_um_t op;
+ const char *ep = NULL;
+ int found = 0;
+ int back = 0;
+ int cc = 1;
+ $? "+ dk4ma_input_c8_dec_dk4_um_t \"%!8s\"", src
+ if ((NULL != rp) && (NULL != src)) {
+#if VERSION_BEFORE_20141007
+ dk4error_init(&er);
+#endif
+ do {
+ $? ". src = \"%!8s\"", src
+ op = (dk4_um_t)0UL;
+ switch (*src) {
+ case '0': { op = (dk4_um_t)0UL; } break;
+ case '1': { op = (dk4_um_t)1UL; } break;
+ case '2': { op = (dk4_um_t)2UL; } break;
+ case '3': { op = (dk4_um_t)3UL; } break;
+ case '4': { op = (dk4_um_t)4UL; } break;
+ case '5': { op = (dk4_um_t)5UL; } break;
+ case '6': { op = (dk4_um_t)6UL; } break;
+ case '7': { op = (dk4_um_t)7UL; } break;
+ case '8': { op = (dk4_um_t)8UL; } break;
+ case '9': { op = (dk4_um_t)9UL; } break;
+ case '\0': { $? ". string finished"
+ cc = 0;
+ if (0 != found) { $? ". digits found"
+ back = 1;
+ *rp = result;
+ } else { $? ". no digits found"
+ ep = src; $? ". ep=%!8s", TR_8STR(ep)
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ default: {
+ cc = 0; $? "! unexpected char"
+ ep = src; $? ". ep=%!8s", TR_8STR(ep)
+ if (0 != found) {
+ switch (atg) {
+ case 2: { $? ". trailing garbage allowed"
+ back = 1;
+ *rp = result;
+ } break;
+ case 1: { $? ". trailing whitespace allowed"
+ if (NULL == dk4str8_start(src, NULL)) {
+ back = 1;
+ *rp = result;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ default: { $? ". no trailing chars allowed"
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ }
+ if (0 != cc) { $? ". process number"
+ found = 1;
+#if VERSION_BEFORE_20141007
+ result = dk4ma_um_add(
+ dk4ma_um_mul(result, (dk4_um_t)10UL, &er),
+ op, &er
+ );
+ if (DK4_E_NONE != er.ec) {
+ cc = 0; $? "! overflow"
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ ep = src;
+ }
+#else
+ if ((DK4_UM_MAX / (dk4_um_t)10UL) >= result) {
+ result *= (dk4_um_t)10UL;
+ if ((DK4_UM_MAX - op) >= result) {
+ result += op;
+ } else {
+ cc = 0;
+ ep = src;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ cc = 0;
+ ep = src;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+#endif
+ }
+ if (0 != cc) {
+ src++;
+ }
+ } while (0 != cc);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ if (NULL != src) { ep = src; }
+ }
+ if (NULL != endptr) { *endptr = ep; }
+ $? "- dk4ma_input_c8_dec_dk4_um_t %d", back
+ return back;
+}
+
diff --git a/support/dktools/dk4mai8ddu.h b/support/dktools/dk4mai8ddu.h
new file mode 100644
index 0000000000..48288cf319
--- /dev/null
+++ b/support/dktools/dk4mai8ddu.h
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8ddu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAI8DDU_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAI8DDU_H_INCLUDED 1
+
+
+#line 10 "dk4mai8ddu.ctr"
+
+/** @file
+ Retrieve dk4_um_t value from
+ 8 bit character string in decimal notation.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_dec_dk4_um_t(
+ dk4_um_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4mai8dic.c b/support/dktools/dk4mai8dic.c
new file mode 100644
index 0000000000..674ea6e52a
--- /dev/null
+++ b/support/dktools/dk4mai8dic.c
@@ -0,0 +1,70 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8dic.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mai8dic.c The dk4mai8dic module.
+*/
+
+
+#line 70 "dk4mai8dic.ctr"
+
+#include "dk4mai8dic.h"
+#include "dk4mai8ddi.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_dec_char(
+ signed char *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_dec_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(CHAR_MIN) <= res) && ((dk4_im_t)(CHAR_MAX) >= res)) {
+ *rp = (signed char)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4mai8dic.ctr b/support/dktools/dk4mai8dic.ctr
new file mode 100644
index 0000000000..3672a45682
--- /dev/null
+++ b/support/dktools/dk4mai8dic.ctr
@@ -0,0 +1,99 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ Retrieve signed char value from
+ 8 bit character string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_dec_char(
+ signed char *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4mai8dic.h"
+#include "dk4mai8ddi.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_dec_char(
+ signed char *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_dec_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(CHAR_MIN) <= res) && ((dk4_im_t)(CHAR_MAX) >= res)) {
+ *rp = (signed char)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4mai8dic.h b/support/dktools/dk4mai8dic.h
new file mode 100644
index 0000000000..64eb58e11d
--- /dev/null
+++ b/support/dktools/dk4mai8dic.h
@@ -0,0 +1,103 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8dic.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAI8DIC_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAI8DIC_H_INCLUDED 1
+
+
+#line 9 "dk4mai8dic.ctr"
+
+/** @file
+ Retrieve signed char value from
+ 8 bit character string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_dec_char(
+ signed char *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4mai8dii.c b/support/dktools/dk4mai8dii.c
new file mode 100644
index 0000000000..5435ab45a7
--- /dev/null
+++ b/support/dktools/dk4mai8dii.c
@@ -0,0 +1,69 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8dii.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mai8dii.c The dk4mai8dii module.
+*/
+
+
+#line 70 "dk4mai8dii.ctr"
+
+#include "dk4mai8ddi.h"
+#include "dk4mai8dii.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_dec_int(
+ int *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_dec_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(INT_MIN) <= res) && (((dk4_im_t)(INT_MAX)) >= res)) {
+ *rp = (int)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4mai8dii.ctr b/support/dktools/dk4mai8dii.ctr
new file mode 100644
index 0000000000..1089ce611e
--- /dev/null
+++ b/support/dktools/dk4mai8dii.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve int value from
+ 8 bit character string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_dec_int(
+ int *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4mai8ddi.h"
+#include "dk4mai8dii.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_dec_int(
+ int *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_dec_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(INT_MIN) <= res) && (((dk4_im_t)(INT_MAX)) >= res)) {
+ *rp = (int)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4mai8dii.h b/support/dktools/dk4mai8dii.h
new file mode 100644
index 0000000000..4e42cd8b0d
--- /dev/null
+++ b/support/dktools/dk4mai8dii.h
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8dii.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAI8DII_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAI8DII_H_INCLUDED 1
+
+
+#line 10 "dk4mai8dii.ctr"
+
+/** @file
+ Retrieve int value from
+ 8 bit character string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_dec_int(
+ int *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4mai8dil.c b/support/dktools/dk4mai8dil.c
new file mode 100644
index 0000000000..ba7a64166f
--- /dev/null
+++ b/support/dktools/dk4mai8dil.c
@@ -0,0 +1,73 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8dil.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mai8dil.c The dk4mai8dil module.
+*/
+
+
+#line 70 "dk4mai8dil.ctr"
+
+#include "dk4mai8ddi.h"
+#include "dk4mai8dil.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_dec_long(
+ long *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_INTMAX_T || DK4_HAVE_LONG_LONG
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_dec_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(LONG_MIN) <= res) && (((dk4_im_t)(LONG_MAX)) >= res)) {
+ *rp = (long)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+#else
+ return (dk4ma_input_c8_dec_dk4_im_t(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4mai8dil.ctr b/support/dktools/dk4mai8dil.ctr
new file mode 100644
index 0000000000..4a0fc4c5c5
--- /dev/null
+++ b/support/dktools/dk4mai8dil.ctr
@@ -0,0 +1,102 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve long value from
+ 8 bit character string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_dec_long(
+ long *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4mai8ddi.h"
+#include "dk4mai8dil.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_dec_long(
+ long *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_INTMAX_T || DK4_HAVE_LONG_LONG
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_dec_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(LONG_MIN) <= res) && (((dk4_im_t)(LONG_MAX)) >= res)) {
+ *rp = (long)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+#else
+ return (dk4ma_input_c8_dec_dk4_im_t(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4mai8dil.h b/support/dktools/dk4mai8dil.h
new file mode 100644
index 0000000000..cdd690a6d8
--- /dev/null
+++ b/support/dktools/dk4mai8dil.h
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8dil.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAI8DIL_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAI8DIL_H_INCLUDED 1
+
+
+#line 10 "dk4mai8dil.ctr"
+
+/** @file
+ Retrieve long value from
+ 8 bit character string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_dec_long(
+ long *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4mai8dis.c b/support/dktools/dk4mai8dis.c
new file mode 100644
index 0000000000..13121b9ad5
--- /dev/null
+++ b/support/dktools/dk4mai8dis.c
@@ -0,0 +1,69 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8dis.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mai8dis.c The dk4mai8dis module.
+*/
+
+
+#line 70 "dk4mai8dis.ctr"
+
+#include "dk4mai8ddi.h"
+#include "dk4mai8dis.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_dec_short(
+ short *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_dec_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(SHRT_MIN) <= res) && (((dk4_im_t)(SHRT_MAX)) >= res)) {
+ *rp = (short)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4mai8dis.ctr b/support/dktools/dk4mai8dis.ctr
new file mode 100644
index 0000000000..0010bcace6
--- /dev/null
+++ b/support/dktools/dk4mai8dis.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve short int value from
+ 8 bit character string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_dec_short(
+ short *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4mai8ddi.h"
+#include "dk4mai8dis.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_dec_short(
+ short *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_dec_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(SHRT_MIN) <= res) && (((dk4_im_t)(SHRT_MAX)) >= res)) {
+ *rp = (short)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4mai8dis.h b/support/dktools/dk4mai8dis.h
new file mode 100644
index 0000000000..b6f5916600
--- /dev/null
+++ b/support/dktools/dk4mai8dis.h
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8dis.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAI8DIS_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAI8DIS_H_INCLUDED 1
+
+
+#line 10 "dk4mai8dis.ctr"
+
+/** @file
+ Retrieve short int value from
+ 8 bit character string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_dec_short(
+ short *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4mai8dli.c b/support/dktools/dk4mai8dli.c
new file mode 100644
index 0000000000..54249acde7
--- /dev/null
+++ b/support/dktools/dk4mai8dli.c
@@ -0,0 +1,79 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8dli.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mai8dli.c The dk4mai8dli module.
+*/
+
+
+#line 74 "dk4mai8dli.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_LONG_LONG
+
+#include "dk4mai8ddi.h"
+#include "dk4mai8dli.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_dec_ll(
+ long long *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_INTMAX_T
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_dec_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(LLONG_MIN) <= res) && (((dk4_im_t)(LLONG_MAX)) >= res)) {
+ *rp = (long long)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+#else
+ return (dk4ma_input_c8_dec_dk4_im_t(rp, src, endptr, atg, erp));
+#endif
+}
+
+#endif
+
diff --git a/support/dktools/dk4mai8dli.ctr b/support/dktools/dk4mai8dli.ctr
new file mode 100644
index 0000000000..8c8ccc1652
--- /dev/null
+++ b/support/dktools/dk4mai8dli.ctr
@@ -0,0 +1,112 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve long long value from
+ 8 bit character string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_LONG_LONG
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_dec_ll(
+ long long *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_LONG_LONG
+
+#include "dk4mai8ddi.h"
+#include "dk4mai8dli.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_dec_ll(
+ long long *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_INTMAX_T
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_dec_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(LLONG_MIN) <= res) && (((dk4_im_t)(LLONG_MAX)) >= res)) {
+ *rp = (long long)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+#else
+ return (dk4ma_input_c8_dec_dk4_im_t(rp, src, endptr, atg, erp));
+#endif
+}
+
+#endif
+
diff --git a/support/dktools/dk4mai8dli.h b/support/dktools/dk4mai8dli.h
new file mode 100644
index 0000000000..3d41e97fba
--- /dev/null
+++ b/support/dktools/dk4mai8dli.h
@@ -0,0 +1,106 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8dli.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAI8DLI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAI8DLI_H_INCLUDED 1
+
+
+#line 10 "dk4mai8dli.ctr"
+
+/** @file
+ Retrieve long long value from
+ 8 bit character string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_LONG_LONG
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_dec_ll(
+ long long *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4mai8dlu.c b/support/dktools/dk4mai8dlu.c
new file mode 100644
index 0000000000..9ba88a30e8
--- /dev/null
+++ b/support/dktools/dk4mai8dlu.c
@@ -0,0 +1,79 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8dlu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mai8dlu.c The dk4mai8dlu module.
+*/
+
+
+#line 74 "dk4mai8dlu.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_LONG_LONG
+
+#include "dk4mai8ddu.h"
+#include "dk4mai8dlu.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_dec_ull(
+ unsigned long long *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_INTMAX_T
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_dec_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(ULLONG_MAX)) >= res) {
+ *rp = (unsigned long long)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+#else
+ return (dk4ma_input_c8_dec_dk4_um_t(rp, src, endptr, atg, erp));
+#endif
+}
+
+#endif
+
diff --git a/support/dktools/dk4mai8dlu.ctr b/support/dktools/dk4mai8dlu.ctr
new file mode 100644
index 0000000000..5f1d704610
--- /dev/null
+++ b/support/dktools/dk4mai8dlu.ctr
@@ -0,0 +1,112 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve unsigned long long value from
+ 8 bit character string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_LONG_LONG
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_dec_ull(
+ unsigned long long *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_LONG_LONG
+
+#include "dk4mai8ddu.h"
+#include "dk4mai8dlu.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_dec_ull(
+ unsigned long long *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_INTMAX_T
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_dec_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(ULLONG_MAX)) >= res) {
+ *rp = (unsigned long long)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+#else
+ return (dk4ma_input_c8_dec_dk4_um_t(rp, src, endptr, atg, erp));
+#endif
+}
+
+#endif
+
diff --git a/support/dktools/dk4mai8dlu.h b/support/dktools/dk4mai8dlu.h
new file mode 100644
index 0000000000..7e5e606115
--- /dev/null
+++ b/support/dktools/dk4mai8dlu.h
@@ -0,0 +1,106 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8dlu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAI8DLU_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAI8DLU_H_INCLUDED 1
+
+
+#line 10 "dk4mai8dlu.ctr"
+
+/** @file
+ Retrieve unsigned long long value from
+ 8 bit character string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_LONG_LONG
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_dec_ull(
+ unsigned long long *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4mai8dmi.c b/support/dktools/dk4mai8dmi.c
new file mode 100644
index 0000000000..e2d106e1bd
--- /dev/null
+++ b/support/dktools/dk4mai8dmi.c
@@ -0,0 +1,66 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8dmi.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mai8dmi.c The dk4mai8dmi module.
+*/
+
+
+#line 75 "dk4mai8dmi.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#pragma warning (disable:4206)
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#include "dk4mai8ddi.h"
+#include "dk4mai8dmi.h"
+
+int
+dk4ma_input_c8_dec_intmax_t(
+ intmax_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ return (dk4ma_input_c8_dec_dk4_im_t(rp, src, endptr, atg, erp));
+}
+
+#endif
+
diff --git a/support/dktools/dk4mai8dmi.ctr b/support/dktools/dk4mai8dmi.ctr
new file mode 100644
index 0000000000..162ce086f0
--- /dev/null
+++ b/support/dktools/dk4mai8dmi.ctr
@@ -0,0 +1,100 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve intmax_t value from
+ 8 bit character string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_dec_intmax_t(
+ intmax_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#pragma warning (disable:4206)
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#include "dk4mai8ddi.h"
+#include "dk4mai8dmi.h"
+
+int
+dk4ma_input_c8_dec_intmax_t(
+ intmax_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ return (dk4ma_input_c8_dec_dk4_im_t(rp, src, endptr, atg, erp));
+}
+
+#endif
+
diff --git a/support/dktools/dk4mai8dmi.h b/support/dktools/dk4mai8dmi.h
new file mode 100644
index 0000000000..bfa9f26466
--- /dev/null
+++ b/support/dktools/dk4mai8dmi.h
@@ -0,0 +1,107 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8dmi.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAI8DMI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAI8DMI_H_INCLUDED 1
+
+
+#line 10 "dk4mai8dmi.ctr"
+
+/** @file
+ Retrieve intmax_t value from
+ 8 bit character string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_dec_intmax_t(
+ intmax_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4mai8dmu.c b/support/dktools/dk4mai8dmu.c
new file mode 100644
index 0000000000..877c9353c8
--- /dev/null
+++ b/support/dktools/dk4mai8dmu.c
@@ -0,0 +1,66 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8dmu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mai8dmu.c The dk4mai8dmu module.
+*/
+
+
+#line 75 "dk4mai8dmu.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#pragma warning (disable:4206)
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#include "dk4mai8ddu.h"
+#include "dk4mai8dmu.h"
+
+int
+dk4ma_input_c8_dec_uintmax_t(
+ uintmax_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ return (dk4ma_input_c8_dec_dk4_um_t(rp, src, endptr, atg, erp));
+}
+
+#endif
+
diff --git a/support/dktools/dk4mai8dmu.ctr b/support/dktools/dk4mai8dmu.ctr
new file mode 100644
index 0000000000..9e844b10fe
--- /dev/null
+++ b/support/dktools/dk4mai8dmu.ctr
@@ -0,0 +1,100 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve uintmax_t value from
+ 8 bit character string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_dec_uintmax_t(
+ uintmax_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#pragma warning (disable:4206)
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#include "dk4mai8ddu.h"
+#include "dk4mai8dmu.h"
+
+int
+dk4ma_input_c8_dec_uintmax_t(
+ uintmax_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ return (dk4ma_input_c8_dec_dk4_um_t(rp, src, endptr, atg, erp));
+}
+
+#endif
+
diff --git a/support/dktools/dk4mai8dmu.h b/support/dktools/dk4mai8dmu.h
new file mode 100644
index 0000000000..d7ab9dddd3
--- /dev/null
+++ b/support/dktools/dk4mai8dmu.h
@@ -0,0 +1,107 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8dmu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAI8DMU_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAI8DMU_H_INCLUDED 1
+
+
+#line 10 "dk4mai8dmu.ctr"
+
+/** @file
+ Retrieve uintmax_t value from
+ 8 bit character string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_dec_uintmax_t(
+ uintmax_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4mai8dsz.c b/support/dktools/dk4mai8dsz.c
new file mode 100644
index 0000000000..e90225d627
--- /dev/null
+++ b/support/dktools/dk4mai8dsz.c
@@ -0,0 +1,245 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8dsz.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mai8dsz.c The dk4mai8dsz module.
+*/
+
+
+#line 72 "dk4mai8dsz.ctr"
+
+#include "dk4mai8ddu.h"
+#include "dk4mai8dsz.h"
+#include "dk4maasz.h"
+#include "dk4numco.h"
+#include "dk4str8.h"
+
+
+
+#if VERSION_1
+
+/** Find multiplication factor for size.
+ @param str String probably containing a size specification.
+ @param fp Pointer to factor variable.
+ @param erp Error report, may be NULL.
+ @return Start of string after size specification.
+*/
+static
+const char *
+dk4mai8dsz_find_factor(const char *str, size_t *fp, dk4_er_t *erp)
+{
+ size_t factor = 1;
+ size_t numl = 0;
+ switch (*str) {
+ case 'k': case 'K': { numl = 1; str++; } break;
+ case 'm': case 'M': { numl = 2; str++; } break;
+ case 'g': case 'G': { numl = 3; str++; } break;
+ case 't': case 'T': { numl = 4; str++; } break;
+ }
+ while (0 < numl--) {
+#if VERSION_BEFORE_20141007
+ factor = dk4ma_size_t_mul(factor, 1024, erp);
+#else
+ if ((SIZE_MAX / 1024) >= factor) {
+ factor *= 1024;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+#endif
+ }
+ *fp = factor;
+ return str;
+}
+
+
+
+/* UNTESTED */
+int
+dk4ma_input_c8_dec_size_t(
+ size_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er;
+ const char *myend = NULL;
+ dk4_um_t res;
+ size_t szr;
+ size_t factor = 1;
+ int back = 0;
+ if (0 != dk4ma_input_c8_dec_dk4_um_t(&res, src, &myend, 2, erp)) {
+ if (((dk4_um_t)(SIZE_MAX)) >= res) {
+ szr = (size_t)res;
+ if (NULL != myend) {
+ dk4error_init(&er);
+ myend = dk4mai8dsz_find_factor(myend, &factor, &er);
+ if (DK4_E_MATH_OVERFLOW != er.ec) {
+ dk4error_init(&er);
+#if VERSION_BEFORE_20141107
+ szr = dk4ma_size_t_mul(szr, factor, &er);
+#else
+ if ((SIZE_MAX / factor) >= szr) {
+ szr *= factor;
+ } else {
+ dk4error_set_simple_error_code(&er, DK4_E_MATH_OVERFLOW);
+ }
+#endif
+ if (DK4_E_MATH_OVERFLOW != er.ec) {
+ if ('\0' == *myend) {
+ *rp = szr;
+ back = 1;
+ } else {
+ switch (atg) {
+ case 2: {
+ *rp = szr;
+ back = 1;
+ } break;
+ case 1: {
+ if (NULL == dk4str8_start(myend, NULL)) {
+ *rp = szr;
+ back = 1;
+ } else {
+ *endptr = myend;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ default: {
+ *endptr = myend;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ *rp = szr;
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
+
+#endif
+
+
+
+int
+dk4ma_input_c8_dec_size_t(
+ size_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ const char *myend = NULL;
+ dk4_um_t um = (dk4_um_t)0UL;
+ size_t res = 0;
+ size_t factor = 1;
+ size_t nloop = 0;
+ int back = 0;
+
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk4ma_input_c8_dec_dk4_um_t(&um, src, &myend, 2, erp)) {
+ if (((dk4_um_t)(SIZE_MAX)) >= um) {
+ res = (size_t)um;
+ if (NULL != myend) {
+ back = 1;
+ switch (*myend) {
+ case 'k': case 'K': { nloop = 1; myend++; } break;
+ case 'm': case 'M': { nloop = 2; myend++; } break;
+ case 'g': case 'G': { nloop = 3; myend++; } break;
+ case 't': case 'T': { nloop = 4; myend++; } break;
+ }
+ while (nloop--) {
+ if ((SIZE_MAX / 1024) >= factor) {
+ factor *= 1024;
+ } else {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ if (0 != back) {
+ if ((SIZE_MAX / factor) >= res) {
+ res *= factor;
+ switch (atg) {
+ case 2: {
+ *rp = res;
+ } break;
+ case 1: {
+ myend = dk4str8_start(myend, NULL);
+ if (NULL != myend) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } else {
+ *rp = res;
+ }
+ } break;
+ default: {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ *rp = res;
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ if (NULL != endptr) { *endptr = myend; }
+ return back;
+}
+
diff --git a/support/dktools/dk4mai8dsz.ctr b/support/dktools/dk4mai8dsz.ctr
new file mode 100644
index 0000000000..fd14c2683c
--- /dev/null
+++ b/support/dktools/dk4mai8dsz.ctr
@@ -0,0 +1,276 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve size_t value from
+ 8 bit character string in decimal notation.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_dec_size_t(
+ size_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4mai8ddu.h"
+#include "dk4mai8dsz.h"
+#include "dk4maasz.h"
+#include "dk4numco.h"
+#include "dk4str8.h"
+
+
+
+#if VERSION_1
+
+/** Find multiplication factor for size.
+ @param str String probably containing a size specification.
+ @param fp Pointer to factor variable.
+ @param erp Error report, may be NULL.
+ @return Start of string after size specification.
+*/
+static
+const char *
+dk4mai8dsz_find_factor(const char *str, size_t *fp, dk4_er_t *erp)
+{
+ size_t factor = 1;
+ size_t numl = 0;
+ switch (*str) {
+ case 'k': case 'K': { numl = 1; str++; } break;
+ case 'm': case 'M': { numl = 2; str++; } break;
+ case 'g': case 'G': { numl = 3; str++; } break;
+ case 't': case 'T': { numl = 4; str++; } break;
+ }
+ while (0 < numl--) {
+#if VERSION_BEFORE_20141007
+ factor = dk4ma_size_t_mul(factor, 1024, erp);
+#else
+ if ((SIZE_MAX / 1024) >= factor) {
+ factor *= 1024;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+#endif
+ }
+ *fp = factor;
+ return str;
+}
+
+
+
+/* UNTESTED */
+int
+dk4ma_input_c8_dec_size_t(
+ size_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er;
+ const char *myend = NULL;
+ dk4_um_t res;
+ size_t szr;
+ size_t factor = 1;
+ int back = 0;
+ if (0 != dk4ma_input_c8_dec_dk4_um_t(&res, src, &myend, 2, erp)) {
+ if (((dk4_um_t)(SIZE_MAX)) >= res) {
+ szr = (size_t)res;
+ if (NULL != myend) {
+ dk4error_init(&er);
+ myend = dk4mai8dsz_find_factor(myend, &factor, &er);
+ if (DK4_E_MATH_OVERFLOW != er.ec) {
+ dk4error_init(&er);
+#if VERSION_BEFORE_20141107
+ szr = dk4ma_size_t_mul(szr, factor, &er);
+#else
+ if ((SIZE_MAX / factor) >= szr) {
+ szr *= factor;
+ } else {
+ dk4error_set_simple_error_code(&er, DK4_E_MATH_OVERFLOW);
+ }
+#endif
+ if (DK4_E_MATH_OVERFLOW != er.ec) {
+ if ('\0' == *myend) {
+ *rp = szr;
+ back = 1;
+ } else {
+ switch (atg) {
+ case 2: {
+ *rp = szr;
+ back = 1;
+ } break;
+ case 1: {
+ if (NULL == dk4str8_start(myend, NULL)) {
+ *rp = szr;
+ back = 1;
+ } else {
+ *endptr = myend;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ default: {
+ *endptr = myend;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ *rp = szr;
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
+
+#endif
+
+
+
+int
+dk4ma_input_c8_dec_size_t(
+ size_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ const char *myend = NULL;
+ dk4_um_t um = (dk4_um_t)0UL;
+ size_t res = 0;
+ size_t factor = 1;
+ size_t nloop = 0;
+ int back = 0;
+
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk4ma_input_c8_dec_dk4_um_t(&um, src, &myend, 2, erp)) {
+ if (((dk4_um_t)(SIZE_MAX)) >= um) {
+ res = (size_t)um;
+ if (NULL != myend) {
+ back = 1;
+ switch (*myend) {
+ case 'k': case 'K': { nloop = 1; myend++; } break;
+ case 'm': case 'M': { nloop = 2; myend++; } break;
+ case 'g': case 'G': { nloop = 3; myend++; } break;
+ case 't': case 'T': { nloop = 4; myend++; } break;
+ }
+ while (nloop--) {
+ if ((SIZE_MAX / 1024) >= factor) {
+ factor *= 1024;
+ } else {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ if (0 != back) {
+ if ((SIZE_MAX / factor) >= res) {
+ res *= factor;
+ switch (atg) {
+ case 2: {
+ *rp = res;
+ } break;
+ case 1: {
+ myend = dk4str8_start(myend, NULL);
+ if (NULL != myend) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } else {
+ *rp = res;
+ }
+ } break;
+ default: {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ *rp = res;
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ if (NULL != endptr) { *endptr = myend; }
+ return back;
+}
+
diff --git a/support/dktools/dk4mai8dsz.h b/support/dktools/dk4mai8dsz.h
new file mode 100644
index 0000000000..b4911f261f
--- /dev/null
+++ b/support/dktools/dk4mai8dsz.h
@@ -0,0 +1,104 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8dsz.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAI8DSZ_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAI8DSZ_H_INCLUDED 1
+
+
+#line 10 "dk4mai8dsz.ctr"
+
+/** @file
+ Retrieve size_t value from
+ 8 bit character string in decimal notation.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_dec_size_t(
+ size_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4mai8duc.c b/support/dktools/dk4mai8duc.c
new file mode 100644
index 0000000000..298db369bf
--- /dev/null
+++ b/support/dktools/dk4mai8duc.c
@@ -0,0 +1,69 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8duc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mai8duc.c The dk4mai8duc module.
+*/
+
+
+#line 70 "dk4mai8duc.ctr"
+
+#include "dk4mai8ddu.h"
+#include "dk4mai8duc.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_dec_uchar(
+ unsigned char *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_dec_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(UCHAR_MAX)) >= res) {
+ *rp = (unsigned char)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4mai8duc.ctr b/support/dktools/dk4mai8duc.ctr
new file mode 100644
index 0000000000..c242b054ad
--- /dev/null
+++ b/support/dktools/dk4mai8duc.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve unsigned char value from
+ 8 bit character string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_dec_uchar(
+ unsigned char *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4mai8ddu.h"
+#include "dk4mai8duc.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_dec_uchar(
+ unsigned char *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_dec_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(UCHAR_MAX)) >= res) {
+ *rp = (unsigned char)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4mai8duc.h b/support/dktools/dk4mai8duc.h
new file mode 100644
index 0000000000..072a808dec
--- /dev/null
+++ b/support/dktools/dk4mai8duc.h
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8duc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAI8DUC_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAI8DUC_H_INCLUDED 1
+
+
+#line 10 "dk4mai8duc.ctr"
+
+/** @file
+ Retrieve unsigned char value from
+ 8 bit character string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_dec_uchar(
+ unsigned char *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4mai8dui.c b/support/dktools/dk4mai8dui.c
new file mode 100644
index 0000000000..0a847656c6
--- /dev/null
+++ b/support/dktools/dk4mai8dui.c
@@ -0,0 +1,69 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8dui.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mai8dui.c The dk4mai8dui module.
+*/
+
+
+#line 70 "dk4mai8dui.ctr"
+
+#include "dk4mai8ddu.h"
+#include "dk4mai8dui.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_dec_uint(
+ unsigned *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_dec_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(UINT_MAX)) >= res) {
+ *rp = (unsigned)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4mai8dui.ctr b/support/dktools/dk4mai8dui.ctr
new file mode 100644
index 0000000000..8eef26615e
--- /dev/null
+++ b/support/dktools/dk4mai8dui.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve unsigned int value from
+ 8 bit character string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_dec_uint(
+ unsigned *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4mai8ddu.h"
+#include "dk4mai8dui.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_dec_uint(
+ unsigned *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_dec_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(UINT_MAX)) >= res) {
+ *rp = (unsigned)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4mai8dui.h b/support/dktools/dk4mai8dui.h
new file mode 100644
index 0000000000..604e58e29d
--- /dev/null
+++ b/support/dktools/dk4mai8dui.h
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8dui.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAI8DUI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAI8DUI_H_INCLUDED 1
+
+
+#line 10 "dk4mai8dui.ctr"
+
+/** @file
+ Retrieve unsigned int value from
+ 8 bit character string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_dec_uint(
+ unsigned *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4mai8dul.c b/support/dktools/dk4mai8dul.c
new file mode 100644
index 0000000000..9bfa35383c
--- /dev/null
+++ b/support/dktools/dk4mai8dul.c
@@ -0,0 +1,73 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8dul.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mai8dul.c The dk4mai8dul module.
+*/
+
+
+#line 70 "dk4mai8dul.ctr"
+
+#include "dk4mai8ddu.h"
+#include "dk4mai8dul.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_dec_ulong(
+ unsigned long *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_INTMAX_T || DK4_HAVE_LONG_LONG
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_dec_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(ULONG_MAX)) >= res) {
+ *rp = (unsigned long)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+#else
+ return (dk4ma_input_c8_dec_dk4_um_t(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4mai8dul.ctr b/support/dktools/dk4mai8dul.ctr
new file mode 100644
index 0000000000..4bb0736b5a
--- /dev/null
+++ b/support/dktools/dk4mai8dul.ctr
@@ -0,0 +1,102 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve unsigned long value from
+ 8 bit character string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_dec_ulong(
+ unsigned long *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4mai8ddu.h"
+#include "dk4mai8dul.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_dec_ulong(
+ unsigned long *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_INTMAX_T || DK4_HAVE_LONG_LONG
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_dec_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(ULONG_MAX)) >= res) {
+ *rp = (unsigned long)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+#else
+ return (dk4ma_input_c8_dec_dk4_um_t(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4mai8dul.h b/support/dktools/dk4mai8dul.h
new file mode 100644
index 0000000000..a137dcdafb
--- /dev/null
+++ b/support/dktools/dk4mai8dul.h
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8dul.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAI8DUL_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAI8DUL_H_INCLUDED 1
+
+
+#line 10 "dk4mai8dul.ctr"
+
+/** @file
+ Retrieve unsigned long value from
+ 8 bit character string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_dec_ulong(
+ unsigned long *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4mai8dus.c b/support/dktools/dk4mai8dus.c
new file mode 100644
index 0000000000..6edda6ba1a
--- /dev/null
+++ b/support/dktools/dk4mai8dus.c
@@ -0,0 +1,69 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8dus.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mai8dus.c The dk4mai8dus module.
+*/
+
+
+#line 70 "dk4mai8dus.ctr"
+
+#include "dk4mai8ddu.h"
+#include "dk4mai8dus.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_dec_ushort(
+ unsigned short *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_dec_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(USHRT_MAX)) >= res) {
+ *rp = (unsigned short)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4mai8dus.ctr b/support/dktools/dk4mai8dus.ctr
new file mode 100644
index 0000000000..8155d389ae
--- /dev/null
+++ b/support/dktools/dk4mai8dus.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve unsigned short value from
+ 8 bit character string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_dec_ushort(
+ unsigned short *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4mai8ddu.h"
+#include "dk4mai8dus.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_dec_ushort(
+ unsigned short *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_dec_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(USHRT_MAX)) >= res) {
+ *rp = (unsigned short)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4mai8dus.h b/support/dktools/dk4mai8dus.h
new file mode 100644
index 0000000000..c02a7aecd1
--- /dev/null
+++ b/support/dktools/dk4mai8dus.h
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8dus.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAI8DUS_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAI8DUS_H_INCLUDED 1
+
+
+#line 10 "dk4mai8dus.ctr"
+
+/** @file
+ Retrieve unsigned short value from
+ 8 bit character string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_dec_ushort(
+ unsigned short *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4mai8hdi.c b/support/dktools/dk4mai8hdi.c
new file mode 100644
index 0000000000..b74ae329ad
--- /dev/null
+++ b/support/dktools/dk4mai8hdi.c
@@ -0,0 +1,116 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8hdi.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mai8hdi.c The dk4mai8hdi module.
+*/
+
+
+#line 72 "dk4mai8hdi.ctr"
+
+
+#include "dk4mai8hdu.h"
+#include "dk4mai8hdi.h"
+#include "dk4numco.h"
+#include "dk4str8.h"
+
+
+
+
+#line 81 "dk4mai8hdi.ctr"
+
+
+
+int
+dk4ma_input_c8_hex_dk4_im_t(
+ dk4_im_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_um_t res;
+ const char *ep = NULL;
+ int back = 0;
+
+
+#line 97 "dk4mai8hdi.ctr"
+ if ((NULL != rp) && (NULL != src)) {
+ if ('-' == *src) {
+
+#line 99 "dk4mai8hdi.ctr"
+ if (0 != dk4ma_input_c8_hex_dk4_um_t(&res, ++src, &ep, atg, erp)) {
+ if (((dk4_um_t)(DK4_IM_MAX) + (dk4_um_t)1UL) == res) {
+
+#line 101 "dk4mai8hdi.ctr"
+ *rp = DK4_IM_MIN;
+ back = 1;
+ } else {
+ if (((dk4_um_t)(DK4_IM_MAX)) >= res) {
+
+#line 105 "dk4mai8hdi.ctr"
+ *rp = (dk4_im_t)0L - (dk4_im_t)res;
+ back = 1;
+ } else {
+
+#line 108 "dk4mai8hdi.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ } else {
+
+#line 112 "dk4mai8hdi.ctr"
+ }
+ } else {
+
+#line 114 "dk4mai8hdi.ctr"
+ if (0 != dk4ma_input_c8_hex_dk4_um_t(&res, src, &ep, atg, erp)) {
+ *rp = (dk4_im_t)res;
+ back = 1;
+ } else {
+
+#line 118 "dk4mai8hdi.ctr"
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ if (NULL != endptr) { *endptr = ep; }
+
+
+#line 125 "dk4mai8hdi.ctr"
+ return back;
+}
+
diff --git a/support/dktools/dk4mai8hdi.ctr b/support/dktools/dk4mai8hdi.ctr
new file mode 100644
index 0000000000..7e568572c0
--- /dev/null
+++ b/support/dktools/dk4mai8hdi.ctr
@@ -0,0 +1,127 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve dk4_im_t value from
+ 8 bit character string in hexadecimal notation.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_hex_dk4_im_t(
+ dk4_im_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+
+#include "dk4mai8hdu.h"
+#include "dk4mai8hdi.h"
+#include "dk4numco.h"
+#include "dk4str8.h"
+
+
+$!trace-include
+
+
+
+int
+dk4ma_input_c8_hex_dk4_im_t(
+ dk4_im_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_um_t res;
+ const char *ep = NULL;
+ int back = 0;
+ $? "+ dk4ma_input_c8_hex_dk4_im_t \"%!8s\" %d", src, atg
+ if ((NULL != rp) && (NULL != src)) {
+ if ('-' == *src) { $? ". negative"
+ if (0 != dk4ma_input_c8_hex_dk4_um_t(&res, ++src, &ep, atg, erp)) {
+ if (((dk4_um_t)(DK4_IM_MAX) + (dk4_um_t)1UL) == res) { $? ". ok min"
+ *rp = DK4_IM_MIN;
+ back = 1;
+ } else {
+ if (((dk4_um_t)(DK4_IM_MAX)) >= res) { $? ". ok neg"
+ *rp = (dk4_im_t)0L - (dk4_im_t)res;
+ back = 1;
+ } else { $? "! overflow"
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ } else { $? "! failed"
+ }
+ } else { $? ". not negative"
+ if (0 != dk4ma_input_c8_hex_dk4_um_t(&res, src, &ep, atg, erp)) {
+ *rp = (dk4_im_t)res;
+ back = 1;
+ } else { $? "! failed"
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ if (NULL != endptr) { *endptr = ep; }
+ $? "- dk4ma_input_c8_hex_dk4_im_t %d", back
+ return back;
+}
+
diff --git a/support/dktools/dk4mai8hdi.h b/support/dktools/dk4mai8hdi.h
new file mode 100644
index 0000000000..87ad665181
--- /dev/null
+++ b/support/dktools/dk4mai8hdi.h
@@ -0,0 +1,104 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8hdi.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAI8HDI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAI8HDI_H_INCLUDED 1
+
+
+#line 10 "dk4mai8hdi.ctr"
+
+/** @file
+ Retrieve dk4_im_t value from
+ 8 bit character string in hexadecimal notation.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_hex_dk4_im_t(
+ dk4_im_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4mai8hdu.c b/support/dktools/dk4mai8hdu.c
new file mode 100644
index 0000000000..433341727b
--- /dev/null
+++ b/support/dktools/dk4mai8hdu.c
@@ -0,0 +1,189 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8hdu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mai8hdu.c The dk4mai8hdu module.
+*/
+
+
+#line 72 "dk4mai8hdu.ctr"
+
+#include "dk4mai8hdu.h"
+#include "dk4numco.h"
+#include "dk4str8.h"
+
+
+
+
+
+#line 80 "dk4mai8hdu.ctr"
+
+
+
+int
+dk4ma_input_c8_hex_dk4_um_t(
+ dk4_um_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if VERSION_BEFORE_20141007
+ dk4_er_t er;
+#endif
+ dk4_um_t result= (dk4_um_t)0UL;
+ dk4_um_t op;
+ const char *ep = NULL;
+ int found = 0;
+ int back = 0;
+ int cc = 1;
+
+
+#line 102 "dk4mai8hdu.ctr"
+ if ((NULL != rp) && (NULL != src)) {
+ if ('0' == src[0]) {
+ if (('x' == src[1]) || ('X' == src[1])) { src++; src++; }
+ }
+#if VERSION_BEFORE_20141007
+ dk4error_init(&er);
+#endif
+ do {
+
+
+#line 111 "dk4mai8hdu.ctr"
+ op = (dk4_um_t)0UL;
+ switch (*src) {
+ case '0': { op = (dk4_um_t)0UL; } break;
+ case '1': { op = (dk4_um_t)1UL; } break;
+ case '2': { op = (dk4_um_t)2UL; } break;
+ case '3': { op = (dk4_um_t)3UL; } break;
+ case '4': { op = (dk4_um_t)4UL; } break;
+ case '5': { op = (dk4_um_t)5UL; } break;
+ case '6': { op = (dk4_um_t)6UL; } break;
+ case '7': { op = (dk4_um_t)7UL; } break;
+ case '8': { op = (dk4_um_t)8UL; } break;
+ case '9': { op = (dk4_um_t)9UL; } break;
+ case 'a': case 'A': { op = (dk4_um_t)10UL; } break;
+ case 'b': case 'B': { op = (dk4_um_t)11UL; } break;
+ case 'c': case 'C': { op = (dk4_um_t)12UL; } break;
+ case 'd': case 'D': { op = (dk4_um_t)13UL; } break;
+ case 'e': case 'E': { op = (dk4_um_t)14UL; } break;
+ case 'f': case 'F': { op = (dk4_um_t)15UL; } break;
+ case '\0': {
+
+#line 130 "dk4mai8hdu.ctr"
+ cc = 0;
+ if (0 != found) {
+
+#line 132 "dk4mai8hdu.ctr"
+ back = 1;
+ *rp = result;
+ } else {
+
+#line 135 "dk4mai8hdu.ctr"
+ ep = src;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ default: {
+ cc = 0;
+ ep = src;
+ if (0 != found) {
+ switch (atg) {
+ case 2: {
+ back = 1;
+ *rp = result;
+ } break;
+ case 1: {
+ if (NULL == dk4str8_start(src, NULL)) {
+ back = 1;
+ *rp = result;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ default: {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ }
+ if (0 != cc) {
+ found = 1;
+#if VERSION_BEFORE_20141007
+ result = dk4ma_um_add(
+ dk4ma_um_mul(result, (dk4_um_t)16UL, &er),
+ op, &er
+ );
+ if (DK4_E_NONE != er.ec) {
+ cc = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ ep = src;
+ }
+#else
+ if ((DK4_UM_MAX / (dk4_um_t)16UL) >= result) {
+ result *= (dk4_um_t)16UL;
+ if ((DK4_UM_MAX - op) >= result) {
+ result += op;
+ } else {
+ cc = 0;
+ ep = src;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ cc = 0;
+ ep = src;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+#endif
+ }
+ if (0 != cc) {
+ src++;
+ }
+ } while (0 != cc);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ if (NULL != src) { ep = src; }
+ }
+ if (NULL != endptr) { *endptr = ep; }
+
+
+#line 204 "dk4mai8hdu.ctr"
+ return back;
+}
+
diff --git a/support/dktools/dk4mai8hdu.ctr b/support/dktools/dk4mai8hdu.ctr
new file mode 100644
index 0000000000..186ef9f8e5
--- /dev/null
+++ b/support/dktools/dk4mai8hdu.ctr
@@ -0,0 +1,206 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve dk4_um_t value from
+ 8 bit character string in hexadecimal notation.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_hex_dk4_um_t(
+ dk4_um_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4mai8hdu.h"
+#include "dk4numco.h"
+#include "dk4str8.h"
+
+
+
+$!trace-include
+
+
+
+int
+dk4ma_input_c8_hex_dk4_um_t(
+ dk4_um_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if VERSION_BEFORE_20141007
+ dk4_er_t er;
+#endif
+ dk4_um_t result= (dk4_um_t)0UL;
+ dk4_um_t op;
+ const char *ep = NULL;
+ int found = 0;
+ int back = 0;
+ int cc = 1;
+ $? "+ dk4ma_input_c8_hex_dk4_um_t \"%!8s\"", src
+ if ((NULL != rp) && (NULL != src)) {
+ if ('0' == src[0]) {
+ if (('x' == src[1]) || ('X' == src[1])) { src++; src++; }
+ }
+#if VERSION_BEFORE_20141007
+ dk4error_init(&er);
+#endif
+ do {
+ $? ". src = \"%!8s\"", src
+ op = (dk4_um_t)0UL;
+ switch (*src) {
+ case '0': { op = (dk4_um_t)0UL; } break;
+ case '1': { op = (dk4_um_t)1UL; } break;
+ case '2': { op = (dk4_um_t)2UL; } break;
+ case '3': { op = (dk4_um_t)3UL; } break;
+ case '4': { op = (dk4_um_t)4UL; } break;
+ case '5': { op = (dk4_um_t)5UL; } break;
+ case '6': { op = (dk4_um_t)6UL; } break;
+ case '7': { op = (dk4_um_t)7UL; } break;
+ case '8': { op = (dk4_um_t)8UL; } break;
+ case '9': { op = (dk4_um_t)9UL; } break;
+ case 'a': case 'A': { op = (dk4_um_t)10UL; } break;
+ case 'b': case 'B': { op = (dk4_um_t)11UL; } break;
+ case 'c': case 'C': { op = (dk4_um_t)12UL; } break;
+ case 'd': case 'D': { op = (dk4_um_t)13UL; } break;
+ case 'e': case 'E': { op = (dk4_um_t)14UL; } break;
+ case 'f': case 'F': { op = (dk4_um_t)15UL; } break;
+ case '\0': { $? ". string finished"
+ cc = 0;
+ if (0 != found) { $? ". digits found"
+ back = 1;
+ *rp = result;
+ } else { $? ". no digits found"
+ ep = src;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ default: {
+ cc = 0;
+ ep = src;
+ if (0 != found) {
+ switch (atg) {
+ case 2: {
+ back = 1;
+ *rp = result;
+ } break;
+ case 1: {
+ if (NULL == dk4str8_start(src, NULL)) {
+ back = 1;
+ *rp = result;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ default: {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ }
+ if (0 != cc) {
+ found = 1;
+#if VERSION_BEFORE_20141007
+ result = dk4ma_um_add(
+ dk4ma_um_mul(result, (dk4_um_t)16UL, &er),
+ op, &er
+ );
+ if (DK4_E_NONE != er.ec) {
+ cc = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ ep = src;
+ }
+#else
+ if ((DK4_UM_MAX / (dk4_um_t)16UL) >= result) {
+ result *= (dk4_um_t)16UL;
+ if ((DK4_UM_MAX - op) >= result) {
+ result += op;
+ } else {
+ cc = 0;
+ ep = src;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ cc = 0;
+ ep = src;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+#endif
+ }
+ if (0 != cc) {
+ src++;
+ }
+ } while (0 != cc);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ if (NULL != src) { ep = src; }
+ }
+ if (NULL != endptr) { *endptr = ep; }
+ $? "- dk4ma_input_c8_hex_dk4_um_t %d", back
+ return back;
+}
+
diff --git a/support/dktools/dk4mai8hdu.h b/support/dktools/dk4mai8hdu.h
new file mode 100644
index 0000000000..b22a9a0d0e
--- /dev/null
+++ b/support/dktools/dk4mai8hdu.h
@@ -0,0 +1,104 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8hdu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAI8HDU_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAI8HDU_H_INCLUDED 1
+
+
+#line 10 "dk4mai8hdu.ctr"
+
+/** @file
+ Retrieve dk4_um_t value from
+ 8 bit character string in hexadecimal notation.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_hex_dk4_um_t(
+ dk4_um_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4mai8hic.c b/support/dktools/dk4mai8hic.c
new file mode 100644
index 0000000000..d49fc6ff22
--- /dev/null
+++ b/support/dktools/dk4mai8hic.c
@@ -0,0 +1,70 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8hic.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mai8hic.c The dk4mai8hic module.
+*/
+
+
+#line 70 "dk4mai8hic.ctr"
+
+#include "dk4mai8hic.h"
+#include "dk4mai8hdi.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_hex_char(
+ signed char *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_hex_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(CHAR_MIN) <= res) && ((dk4_im_t)(CHAR_MAX) >= res)) {
+ *rp = (signed char)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4mai8hic.ctr b/support/dktools/dk4mai8hic.ctr
new file mode 100644
index 0000000000..0d988de2f6
--- /dev/null
+++ b/support/dktools/dk4mai8hic.ctr
@@ -0,0 +1,99 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ Retrieve signed char value from
+ 8 bit character string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_hex_char(
+ signed char *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4mai8hic.h"
+#include "dk4mai8hdi.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_hex_char(
+ signed char *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_hex_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(CHAR_MIN) <= res) && ((dk4_im_t)(CHAR_MAX) >= res)) {
+ *rp = (signed char)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4mai8hic.h b/support/dktools/dk4mai8hic.h
new file mode 100644
index 0000000000..e2a8e044df
--- /dev/null
+++ b/support/dktools/dk4mai8hic.h
@@ -0,0 +1,103 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8hic.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAI8HIC_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAI8HIC_H_INCLUDED 1
+
+
+#line 9 "dk4mai8hic.ctr"
+
+/** @file
+ Retrieve signed char value from
+ 8 bit character string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_hex_char(
+ signed char *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4mai8hii.c b/support/dktools/dk4mai8hii.c
new file mode 100644
index 0000000000..09191a0d35
--- /dev/null
+++ b/support/dktools/dk4mai8hii.c
@@ -0,0 +1,69 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8hii.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mai8hii.c The dk4mai8hii module.
+*/
+
+
+#line 70 "dk4mai8hii.ctr"
+
+#include "dk4mai8hdi.h"
+#include "dk4mai8hii.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_hex_int(
+ int *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_hex_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(INT_MIN) <= res) && (((dk4_im_t)(INT_MAX)) >= res)) {
+ *rp = (int)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4mai8hii.ctr b/support/dktools/dk4mai8hii.ctr
new file mode 100644
index 0000000000..62fe02efd1
--- /dev/null
+++ b/support/dktools/dk4mai8hii.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve int value from
+ 8 bit character string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_hex_int(
+ int *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4mai8hdi.h"
+#include "dk4mai8hii.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_hex_int(
+ int *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_hex_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(INT_MIN) <= res) && (((dk4_im_t)(INT_MAX)) >= res)) {
+ *rp = (int)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4mai8hii.h b/support/dktools/dk4mai8hii.h
new file mode 100644
index 0000000000..24178bde5b
--- /dev/null
+++ b/support/dktools/dk4mai8hii.h
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8hii.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAI8HII_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAI8HII_H_INCLUDED 1
+
+
+#line 10 "dk4mai8hii.ctr"
+
+/** @file
+ Retrieve int value from
+ 8 bit character string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_hex_int(
+ int *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4mai8hil.c b/support/dktools/dk4mai8hil.c
new file mode 100644
index 0000000000..3323b55df8
--- /dev/null
+++ b/support/dktools/dk4mai8hil.c
@@ -0,0 +1,73 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8hil.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mai8hil.c The dk4mai8hil module.
+*/
+
+
+#line 70 "dk4mai8hil.ctr"
+
+#include "dk4mai8hdi.h"
+#include "dk4mai8hil.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_hex_long(
+ long *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_INTMAX_T || DK4_HAVE_LONG_LONG
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_hex_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(LONG_MIN) <= res) && (((dk4_im_t)(LONG_MAX)) >= res)) {
+ *rp = (long)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+#else
+ return (dk4ma_input_c8_hex_dk4_im_t(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4mai8hil.ctr b/support/dktools/dk4mai8hil.ctr
new file mode 100644
index 0000000000..cba14b8b6d
--- /dev/null
+++ b/support/dktools/dk4mai8hil.ctr
@@ -0,0 +1,102 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve long value from
+ 8 bit character string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_hex_long(
+ long *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4mai8hdi.h"
+#include "dk4mai8hil.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_hex_long(
+ long *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_INTMAX_T || DK4_HAVE_LONG_LONG
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_hex_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(LONG_MIN) <= res) && (((dk4_im_t)(LONG_MAX)) >= res)) {
+ *rp = (long)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+#else
+ return (dk4ma_input_c8_hex_dk4_im_t(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4mai8hil.h b/support/dktools/dk4mai8hil.h
new file mode 100644
index 0000000000..45734f59a0
--- /dev/null
+++ b/support/dktools/dk4mai8hil.h
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8hil.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAI8HIL_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAI8HIL_H_INCLUDED 1
+
+
+#line 10 "dk4mai8hil.ctr"
+
+/** @file
+ Retrieve long value from
+ 8 bit character string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_hex_long(
+ long *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4mai8his.c b/support/dktools/dk4mai8his.c
new file mode 100644
index 0000000000..d1f7ddec7a
--- /dev/null
+++ b/support/dktools/dk4mai8his.c
@@ -0,0 +1,69 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8his.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mai8his.c The dk4mai8his module.
+*/
+
+
+#line 70 "dk4mai8his.ctr"
+
+#include "dk4mai8hdi.h"
+#include "dk4mai8his.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_hex_short(
+ short *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_hex_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(SHRT_MIN) <= res) && (((dk4_im_t)(SHRT_MAX)) >= res)) {
+ *rp = (short)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4mai8his.ctr b/support/dktools/dk4mai8his.ctr
new file mode 100644
index 0000000000..60377dbb72
--- /dev/null
+++ b/support/dktools/dk4mai8his.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve short int value from
+ 8 bit character string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_hex_short(
+ short *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4mai8hdi.h"
+#include "dk4mai8his.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_hex_short(
+ short *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_hex_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(SHRT_MIN) <= res) && (((dk4_im_t)(SHRT_MAX)) >= res)) {
+ *rp = (short)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4mai8his.h b/support/dktools/dk4mai8his.h
new file mode 100644
index 0000000000..c0d3fb3a2c
--- /dev/null
+++ b/support/dktools/dk4mai8his.h
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8his.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAI8HIS_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAI8HIS_H_INCLUDED 1
+
+
+#line 10 "dk4mai8his.ctr"
+
+/** @file
+ Retrieve short int value from
+ 8 bit character string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_hex_short(
+ short *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4mai8hli.c b/support/dktools/dk4mai8hli.c
new file mode 100644
index 0000000000..17de979c19
--- /dev/null
+++ b/support/dktools/dk4mai8hli.c
@@ -0,0 +1,79 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8hli.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mai8hli.c The dk4mai8hli module.
+*/
+
+
+#line 74 "dk4mai8hli.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_LONG_LONG
+
+#include "dk4mai8hdi.h"
+#include "dk4mai8hli.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_hex_ll(
+ long long *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_INTMAX_T
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_hex_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(LLONG_MIN) <= res) && (((dk4_im_t)(LLONG_MAX)) >= res)) {
+ *rp = (long long)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+#else
+ return (dk4ma_input_c8_hex_dk4_im_t(rp, src, endptr, atg, erp));
+#endif
+}
+
+#endif
+
diff --git a/support/dktools/dk4mai8hli.ctr b/support/dktools/dk4mai8hli.ctr
new file mode 100644
index 0000000000..49aa35a000
--- /dev/null
+++ b/support/dktools/dk4mai8hli.ctr
@@ -0,0 +1,112 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve long long value from
+ 8 bit character string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_LONG_LONG
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_hex_ll(
+ long long *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_LONG_LONG
+
+#include "dk4mai8hdi.h"
+#include "dk4mai8hli.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_hex_ll(
+ long long *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_INTMAX_T
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_hex_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(LLONG_MIN) <= res) && (((dk4_im_t)(LLONG_MAX)) >= res)) {
+ *rp = (long long)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+#else
+ return (dk4ma_input_c8_hex_dk4_im_t(rp, src, endptr, atg, erp));
+#endif
+}
+
+#endif
+
diff --git a/support/dktools/dk4mai8hli.h b/support/dktools/dk4mai8hli.h
new file mode 100644
index 0000000000..02d2066981
--- /dev/null
+++ b/support/dktools/dk4mai8hli.h
@@ -0,0 +1,106 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8hli.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAI8HLI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAI8HLI_H_INCLUDED 1
+
+
+#line 10 "dk4mai8hli.ctr"
+
+/** @file
+ Retrieve long long value from
+ 8 bit character string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_LONG_LONG
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_hex_ll(
+ long long *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4mai8hlu.c b/support/dktools/dk4mai8hlu.c
new file mode 100644
index 0000000000..c915858414
--- /dev/null
+++ b/support/dktools/dk4mai8hlu.c
@@ -0,0 +1,79 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8hlu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mai8hlu.c The dk4mai8hlu module.
+*/
+
+
+#line 74 "dk4mai8hlu.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_LONG_LONG
+
+#include "dk4mai8hdu.h"
+#include "dk4mai8hlu.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_hex_ull(
+ unsigned long long *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_INTMAX_T
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_hex_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(ULLONG_MAX)) >= res) {
+ *rp = (unsigned long long)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+#else
+ return (dk4ma_input_c8_hex_dk4_um_t(rp, src, endptr, atg, erp));
+#endif
+}
+
+#endif
+
diff --git a/support/dktools/dk4mai8hlu.ctr b/support/dktools/dk4mai8hlu.ctr
new file mode 100644
index 0000000000..a718017d92
--- /dev/null
+++ b/support/dktools/dk4mai8hlu.ctr
@@ -0,0 +1,112 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve unsigned long long value from
+ 8 bit character string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_LONG_LONG
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_hex_ull(
+ unsigned long long *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_LONG_LONG
+
+#include "dk4mai8hdu.h"
+#include "dk4mai8hlu.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_hex_ull(
+ unsigned long long *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_INTMAX_T
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_hex_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(ULLONG_MAX)) >= res) {
+ *rp = (unsigned long long)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+#else
+ return (dk4ma_input_c8_hex_dk4_um_t(rp, src, endptr, atg, erp));
+#endif
+}
+
+#endif
+
diff --git a/support/dktools/dk4mai8hlu.h b/support/dktools/dk4mai8hlu.h
new file mode 100644
index 0000000000..4cbd2f5056
--- /dev/null
+++ b/support/dktools/dk4mai8hlu.h
@@ -0,0 +1,106 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8hlu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAI8HLU_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAI8HLU_H_INCLUDED 1
+
+
+#line 10 "dk4mai8hlu.ctr"
+
+/** @file
+ Retrieve unsigned long long value from
+ 8 bit character string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_LONG_LONG
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_hex_ull(
+ unsigned long long *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4mai8hmi.c b/support/dktools/dk4mai8hmi.c
new file mode 100644
index 0000000000..5620935d2c
--- /dev/null
+++ b/support/dktools/dk4mai8hmi.c
@@ -0,0 +1,66 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8hmi.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mai8hmi.c The dk4mai8hmi module.
+*/
+
+
+#line 75 "dk4mai8hmi.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#pragma warning (disable:4206)
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#include "dk4mai8hdi.h"
+#include "dk4mai8hmi.h"
+
+int
+dk4ma_input_c8_hex_intmax_t(
+ intmax_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ return (dk4ma_input_c8_hex_dk4_im_t(rp, src, endptr, atg, erp));
+}
+
+#endif
+
diff --git a/support/dktools/dk4mai8hmi.ctr b/support/dktools/dk4mai8hmi.ctr
new file mode 100644
index 0000000000..82d56c938f
--- /dev/null
+++ b/support/dktools/dk4mai8hmi.ctr
@@ -0,0 +1,100 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve intmax_t value from
+ 8 bit character string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_hex_intmax_t(
+ intmax_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#pragma warning (disable:4206)
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#include "dk4mai8hdi.h"
+#include "dk4mai8hmi.h"
+
+int
+dk4ma_input_c8_hex_intmax_t(
+ intmax_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ return (dk4ma_input_c8_hex_dk4_im_t(rp, src, endptr, atg, erp));
+}
+
+#endif
+
diff --git a/support/dktools/dk4mai8hmi.h b/support/dktools/dk4mai8hmi.h
new file mode 100644
index 0000000000..082284bc43
--- /dev/null
+++ b/support/dktools/dk4mai8hmi.h
@@ -0,0 +1,107 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8hmi.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAI8HMI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAI8HMI_H_INCLUDED 1
+
+
+#line 10 "dk4mai8hmi.ctr"
+
+/** @file
+ Retrieve intmax_t value from
+ 8 bit character string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_hex_intmax_t(
+ intmax_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4mai8hmu.c b/support/dktools/dk4mai8hmu.c
new file mode 100644
index 0000000000..2828d6103d
--- /dev/null
+++ b/support/dktools/dk4mai8hmu.c
@@ -0,0 +1,66 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8hmu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mai8hmu.c The dk4mai8hmu module.
+*/
+
+
+#line 75 "dk4mai8hmu.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#pragma warning (disable:4206)
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#include "dk4mai8hdu.h"
+#include "dk4mai8hmu.h"
+
+int
+dk4ma_input_c8_hex_uintmax_t(
+ uintmax_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ return (dk4ma_input_c8_hex_dk4_um_t(rp, src, endptr, atg, erp));
+}
+
+#endif
+
diff --git a/support/dktools/dk4mai8hmu.ctr b/support/dktools/dk4mai8hmu.ctr
new file mode 100644
index 0000000000..44dd60d2ca
--- /dev/null
+++ b/support/dktools/dk4mai8hmu.ctr
@@ -0,0 +1,100 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve uintmax_t value from
+ 8 bit character string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_hex_uintmax_t(
+ uintmax_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#pragma warning (disable:4206)
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#include "dk4mai8hdu.h"
+#include "dk4mai8hmu.h"
+
+int
+dk4ma_input_c8_hex_uintmax_t(
+ uintmax_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ return (dk4ma_input_c8_hex_dk4_um_t(rp, src, endptr, atg, erp));
+}
+
+#endif
+
diff --git a/support/dktools/dk4mai8hmu.h b/support/dktools/dk4mai8hmu.h
new file mode 100644
index 0000000000..da689b7b79
--- /dev/null
+++ b/support/dktools/dk4mai8hmu.h
@@ -0,0 +1,107 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8hmu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAI8HMU_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAI8HMU_H_INCLUDED 1
+
+
+#line 10 "dk4mai8hmu.ctr"
+
+/** @file
+ Retrieve uintmax_t value from
+ 8 bit character string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_hex_uintmax_t(
+ uintmax_t *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4mai8huc.c b/support/dktools/dk4mai8huc.c
new file mode 100644
index 0000000000..d504abac5a
--- /dev/null
+++ b/support/dktools/dk4mai8huc.c
@@ -0,0 +1,69 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8huc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mai8huc.c The dk4mai8huc module.
+*/
+
+
+#line 70 "dk4mai8huc.ctr"
+
+#include "dk4mai8hdu.h"
+#include "dk4mai8huc.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_hex_uchar(
+ unsigned char *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_hex_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(UCHAR_MAX)) >= res) {
+ *rp = (unsigned char)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4mai8huc.ctr b/support/dktools/dk4mai8huc.ctr
new file mode 100644
index 0000000000..96c2311b02
--- /dev/null
+++ b/support/dktools/dk4mai8huc.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve unsigned char value from
+ 8 bit character string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_hex_uchar(
+ unsigned char *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4mai8hdu.h"
+#include "dk4mai8huc.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_hex_uchar(
+ unsigned char *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_hex_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(UCHAR_MAX)) >= res) {
+ *rp = (unsigned char)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4mai8huc.h b/support/dktools/dk4mai8huc.h
new file mode 100644
index 0000000000..6ce2d4ba03
--- /dev/null
+++ b/support/dktools/dk4mai8huc.h
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8huc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAI8HUC_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAI8HUC_H_INCLUDED 1
+
+
+#line 10 "dk4mai8huc.ctr"
+
+/** @file
+ Retrieve unsigned char value from
+ 8 bit character string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_hex_uchar(
+ unsigned char *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4mai8hui.c b/support/dktools/dk4mai8hui.c
new file mode 100644
index 0000000000..adc6d21d22
--- /dev/null
+++ b/support/dktools/dk4mai8hui.c
@@ -0,0 +1,69 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8hui.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mai8hui.c The dk4mai8hui module.
+*/
+
+
+#line 70 "dk4mai8hui.ctr"
+
+#include "dk4mai8hdu.h"
+#include "dk4mai8hui.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_hex_uint(
+ unsigned *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_hex_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(UINT_MAX)) >= res) {
+ *rp = (unsigned)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4mai8hui.ctr b/support/dktools/dk4mai8hui.ctr
new file mode 100644
index 0000000000..7329956fbd
--- /dev/null
+++ b/support/dktools/dk4mai8hui.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve unsigned int value from
+ 8 bit character string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_hex_uint(
+ unsigned *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4mai8hdu.h"
+#include "dk4mai8hui.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_hex_uint(
+ unsigned *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_hex_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(UINT_MAX)) >= res) {
+ *rp = (unsigned)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4mai8hui.h b/support/dktools/dk4mai8hui.h
new file mode 100644
index 0000000000..ee5e116912
--- /dev/null
+++ b/support/dktools/dk4mai8hui.h
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8hui.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAI8HUI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAI8HUI_H_INCLUDED 1
+
+
+#line 10 "dk4mai8hui.ctr"
+
+/** @file
+ Retrieve unsigned int value from
+ 8 bit character string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_hex_uint(
+ unsigned *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4mai8hul.c b/support/dktools/dk4mai8hul.c
new file mode 100644
index 0000000000..6b9afd3cc9
--- /dev/null
+++ b/support/dktools/dk4mai8hul.c
@@ -0,0 +1,73 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8hul.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mai8hul.c The dk4mai8hul module.
+*/
+
+
+#line 70 "dk4mai8hul.ctr"
+
+#include "dk4mai8hdu.h"
+#include "dk4mai8hul.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_hex_ulong(
+ unsigned long *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_INTMAX_T || DK4_HAVE_LONG_LONG
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_hex_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(ULONG_MAX)) >= res) {
+ *rp = (unsigned long)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+#else
+ return (dk4ma_input_c8_hex_dk4_um_t(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4mai8hul.ctr b/support/dktools/dk4mai8hul.ctr
new file mode 100644
index 0000000000..2acd9f2e6c
--- /dev/null
+++ b/support/dktools/dk4mai8hul.ctr
@@ -0,0 +1,102 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve unsigned long value from
+ 8 bit character string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_hex_ulong(
+ unsigned long *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4mai8hdu.h"
+#include "dk4mai8hul.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_hex_ulong(
+ unsigned long *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_INTMAX_T || DK4_HAVE_LONG_LONG
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_hex_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(ULONG_MAX)) >= res) {
+ *rp = (unsigned long)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+#else
+ return (dk4ma_input_c8_hex_dk4_um_t(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4mai8hul.h b/support/dktools/dk4mai8hul.h
new file mode 100644
index 0000000000..51f5424a5d
--- /dev/null
+++ b/support/dktools/dk4mai8hul.h
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8hul.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAI8HUL_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAI8HUL_H_INCLUDED 1
+
+
+#line 10 "dk4mai8hul.ctr"
+
+/** @file
+ Retrieve unsigned long value from
+ 8 bit character string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_hex_ulong(
+ unsigned long *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4mai8hus.c b/support/dktools/dk4mai8hus.c
new file mode 100644
index 0000000000..d13e482357
--- /dev/null
+++ b/support/dktools/dk4mai8hus.c
@@ -0,0 +1,69 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8hus.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mai8hus.c The dk4mai8hus module.
+*/
+
+
+#line 70 "dk4mai8hus.ctr"
+
+#include "dk4mai8hdu.h"
+#include "dk4mai8hus.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_hex_ushort(
+ unsigned short *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_hex_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(USHRT_MAX)) >= res) {
+ *rp = (unsigned short)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4mai8hus.ctr b/support/dktools/dk4mai8hus.ctr
new file mode 100644
index 0000000000..15c60d75b3
--- /dev/null
+++ b/support/dktools/dk4mai8hus.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve unsigned short value from
+ 8 bit character string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_hex_ushort(
+ unsigned short *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4mai8hdu.h"
+#include "dk4mai8hus.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_c8_hex_ushort(
+ unsigned short *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_c8_hex_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(USHRT_MAX)) >= res) {
+ *rp = (unsigned short)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4mai8hus.h b/support/dktools/dk4mai8hus.h
new file mode 100644
index 0000000000..9b3eb556ce
--- /dev/null
+++ b/support/dktools/dk4mai8hus.h
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mai8hus.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAI8HUS_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAI8HUS_H_INCLUDED 1
+
+
+#line 10 "dk4mai8hus.ctr"
+
+/** @file
+ Retrieve unsigned short value from
+ 8 bit character string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_c8_hex_ushort(
+ unsigned short *rp,
+ const char *src,
+ const char **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4maiddbl.c b/support/dktools/dk4maiddbl.c
new file mode 100644
index 0000000000..9a2a7f02ec
--- /dev/null
+++ b/support/dktools/dk4maiddbl.c
@@ -0,0 +1,66 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiddbl.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiddbl.c The dk4maiddbl module.
+*/
+
+
+#line 77 "dk4maiddbl.ctr"
+
+#include "dk4maiddbl.h"
+
+#if DK4_CHAR_SIZE > 1
+#include "dk4maiwdbl.h"
+#else
+#include "dk4mai8dbl.h"
+#endif
+
+int
+dk4ma_input_dk_double(
+ double *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4ma_input_wc_double(rp, src, endptr, atg, erp));
+#else
+ return (dk4ma_input_c8_double(rp, src, endptr, atg, erp));
+#endif
+}
+
+
diff --git a/support/dktools/dk4maiddbl.ctr b/support/dktools/dk4maiddbl.ctr
new file mode 100644
index 0000000000..030b7adfc3
--- /dev/null
+++ b/support/dktools/dk4maiddbl.ctr
@@ -0,0 +1,102 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Read double value from string.
+
+ CRT on Windows: Required.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Read double value from char string.
+ The function temporarily resets the LC_NUMERIC locale setting
+ to "C" to retrieve the number and returns the setting to the
+ original value before returning.
+ @param rp Address of result variable.
+ @param src String to process.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here. The function may also store
+ a NULL pointer here.
+ The pointer variable is probably left unchanged
+ on errors or if strtod()/wcstod() is not available
+ on your system (the sscanf()/swscanf() function is
+ used as fallback).
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characaters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_SYNTAX if there are unexpected characters in the
+ string,
+ DK4_E_MATH_OVERFLOW if a mathematical overflow occurs,
+ DK4_E_MATH_UNDERFLOW if a mathematical underflow occurs.
+*/
+int
+dk4ma_input_dk_double(
+ double *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4maiddbl.h"
+
+#if DK4_CHAR_SIZE > 1
+#include "dk4maiwdbl.h"
+#else
+#include "dk4mai8dbl.h"
+#endif
+
+int
+dk4ma_input_dk_double(
+ double *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4ma_input_wc_double(rp, src, endptr, atg, erp));
+#else
+ return (dk4ma_input_c8_double(rp, src, endptr, atg, erp));
+#endif
+}
+
+
diff --git a/support/dktools/dk4maiddbl.h b/support/dktools/dk4maiddbl.h
new file mode 100644
index 0000000000..5adb784b6e
--- /dev/null
+++ b/support/dktools/dk4maiddbl.h
@@ -0,0 +1,109 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiddbl.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIDDBL_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIDDBL_H_INCLUDED 1
+
+
+#line 10 "dk4maiddbl.ctr"
+
+/** @file
+ Read double value from string.
+
+ CRT on Windows: Required.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Read double value from char string.
+ The function temporarily resets the LC_NUMERIC locale setting
+ to "C" to retrieve the number and returns the setting to the
+ original value before returning.
+ @param rp Address of result variable.
+ @param src String to process.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here. The function may also store
+ a NULL pointer here.
+ The pointer variable is probably left unchanged
+ on errors or if strtod()/wcstod() is not available
+ on your system (the sscanf()/swscanf() function is
+ used as fallback).
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characaters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_SYNTAX if there are unexpected characters in the
+ string,
+ DK4_E_MATH_OVERFLOW if a mathematical overflow occurs,
+ DK4_E_MATH_UNDERFLOW if a mathematical underflow occurs.
+*/
+int
+dk4ma_input_dk_double(
+ double *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maidddi.c b/support/dktools/dk4maidddi.c
new file mode 100644
index 0000000000..107441cf52
--- /dev/null
+++ b/support/dktools/dk4maidddi.c
@@ -0,0 +1,71 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maidddi.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maidddi.c The dk4maidddi module.
+*/
+
+
+#line 68 "dk4maidddi.ctr"
+
+#include "dk4maidddi.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwddi.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8ddi.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_dec_dk4_im_t(
+ dk4_im_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4ma_input_wc_dec_dk4_im_t(rp, src, endptr, atg, erp));
+#else
+ return (dk4ma_input_c8_dec_dk4_im_t(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maidddi.ctr b/support/dktools/dk4maidddi.ctr
new file mode 100644
index 0000000000..c04b3d8655
--- /dev/null
+++ b/support/dktools/dk4maidddi.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve dk4_im_t value from
+ dkChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_dec_dk4_im_t(
+ dk4_im_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4maidddi.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwddi.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8ddi.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_dec_dk4_im_t(
+ dk4_im_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4ma_input_wc_dec_dk4_im_t(rp, src, endptr, atg, erp));
+#else
+ return (dk4ma_input_c8_dec_dk4_im_t(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maidddi.h b/support/dktools/dk4maidddi.h
new file mode 100644
index 0000000000..a5e1c6ba94
--- /dev/null
+++ b/support/dktools/dk4maidddi.h
@@ -0,0 +1,100 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maidddi.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIDDDI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIDDDI_H_INCLUDED 1
+
+
+#line 10 "dk4maidddi.ctr"
+
+/** @file
+ Retrieve dk4_im_t value from
+ dkChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_dec_dk4_im_t(
+ dk4_im_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maidddu.c b/support/dktools/dk4maidddu.c
new file mode 100644
index 0000000000..bf7885999a
--- /dev/null
+++ b/support/dktools/dk4maidddu.c
@@ -0,0 +1,71 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maidddu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maidddu.c The dk4maidddu module.
+*/
+
+
+#line 68 "dk4maidddu.ctr"
+
+#include "dk4maidddu.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwddu.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8ddu.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_dec_dk4_um_t(
+ dk4_um_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_dec_dk4_um_t(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_dk4_um_t(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maidddu.ctr b/support/dktools/dk4maidddu.ctr
new file mode 100644
index 0000000000..9c6a5ac45c
--- /dev/null
+++ b/support/dktools/dk4maidddu.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve dk4_um_t value from
+ dkChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_dec_dk4_um_t(
+ dk4_um_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4maidddu.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwddu.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8ddu.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_dec_dk4_um_t(
+ dk4_um_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_dec_dk4_um_t(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_dk4_um_t(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maidddu.h b/support/dktools/dk4maidddu.h
new file mode 100644
index 0000000000..c6a7f44836
--- /dev/null
+++ b/support/dktools/dk4maidddu.h
@@ -0,0 +1,100 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maidddu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIDDDU_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIDDDU_H_INCLUDED 1
+
+
+#line 10 "dk4maidddu.ctr"
+
+/** @file
+ Retrieve dk4_um_t value from
+ dkChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_dec_dk4_um_t(
+ dk4_um_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maiddic.c b/support/dktools/dk4maiddic.c
new file mode 100644
index 0000000000..fb26d080aa
--- /dev/null
+++ b/support/dktools/dk4maiddic.c
@@ -0,0 +1,71 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiddic.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiddic.c The dk4maiddic module.
+*/
+
+
+#line 68 "dk4maiddic.ctr"
+
+#include "dk4maiddic.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdic.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8dic.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_dec_char(
+ signed char *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_dec_char(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_char(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maiddic.ctr b/support/dktools/dk4maiddic.ctr
new file mode 100644
index 0000000000..88adb8b252
--- /dev/null
+++ b/support/dktools/dk4maiddic.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve signed char value from
+ dkChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_dec_char(
+ signed char *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4maiddic.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdic.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8dic.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_dec_char(
+ signed char *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_dec_char(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_char(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maiddic.h b/support/dktools/dk4maiddic.h
new file mode 100644
index 0000000000..f848167537
--- /dev/null
+++ b/support/dktools/dk4maiddic.h
@@ -0,0 +1,100 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiddic.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIDDIC_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIDDIC_H_INCLUDED 1
+
+
+#line 10 "dk4maiddic.ctr"
+
+/** @file
+ Retrieve signed char value from
+ dkChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_dec_char(
+ signed char *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maiddii.c b/support/dktools/dk4maiddii.c
new file mode 100644
index 0000000000..632fb7c549
--- /dev/null
+++ b/support/dktools/dk4maiddii.c
@@ -0,0 +1,71 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiddii.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiddii.c The dk4maiddii module.
+*/
+
+
+#line 68 "dk4maiddii.ctr"
+
+#include "dk4maiddii.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdii.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8dii.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_dec_int(
+ int *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_dec_int(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_int(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maiddii.ctr b/support/dktools/dk4maiddii.ctr
new file mode 100644
index 0000000000..35b89c182c
--- /dev/null
+++ b/support/dktools/dk4maiddii.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve int value from
+ dkChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_dec_int(
+ int *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4maiddii.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdii.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8dii.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_dec_int(
+ int *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_dec_int(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_int(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maiddii.h b/support/dktools/dk4maiddii.h
new file mode 100644
index 0000000000..a8b54fd3e4
--- /dev/null
+++ b/support/dktools/dk4maiddii.h
@@ -0,0 +1,100 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiddii.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIDDII_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIDDII_H_INCLUDED 1
+
+
+#line 10 "dk4maiddii.ctr"
+
+/** @file
+ Retrieve int value from
+ dkChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_dec_int(
+ int *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maiddil.c b/support/dktools/dk4maiddil.c
new file mode 100644
index 0000000000..4767ef2cc1
--- /dev/null
+++ b/support/dktools/dk4maiddil.c
@@ -0,0 +1,71 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiddil.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiddil.c The dk4maiddil module.
+*/
+
+
+#line 68 "dk4maiddil.ctr"
+
+#include "dk4maiddil.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdil.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8dil.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_dec_long(
+ long *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_dec_long(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_long(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maiddil.ctr b/support/dktools/dk4maiddil.ctr
new file mode 100644
index 0000000000..956a549d22
--- /dev/null
+++ b/support/dktools/dk4maiddil.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve long value from
+ dkChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_dec_long(
+ long *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4maiddil.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdil.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8dil.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_dec_long(
+ long *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_dec_long(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_long(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maiddil.h b/support/dktools/dk4maiddil.h
new file mode 100644
index 0000000000..6795a6b842
--- /dev/null
+++ b/support/dktools/dk4maiddil.h
@@ -0,0 +1,100 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiddil.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIDDIL_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIDDIL_H_INCLUDED 1
+
+
+#line 10 "dk4maiddil.ctr"
+
+/** @file
+ Retrieve long value from
+ dkChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_dec_long(
+ long *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maiddis.c b/support/dktools/dk4maiddis.c
new file mode 100644
index 0000000000..bb28e3b586
--- /dev/null
+++ b/support/dktools/dk4maiddis.c
@@ -0,0 +1,71 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiddis.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiddis.c The dk4maiddis module.
+*/
+
+
+#line 68 "dk4maiddis.ctr"
+
+#include "dk4maiddis.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdis.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8dis.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_dec_short(
+ short *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_dec_short(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_short(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maiddis.ctr b/support/dktools/dk4maiddis.ctr
new file mode 100644
index 0000000000..751df1586f
--- /dev/null
+++ b/support/dktools/dk4maiddis.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve short int value from
+ dkChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_dec_short(
+ short *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4maiddis.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdis.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8dis.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_dec_short(
+ short *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_dec_short(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_short(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maiddis.h b/support/dktools/dk4maiddis.h
new file mode 100644
index 0000000000..3dd73ebe87
--- /dev/null
+++ b/support/dktools/dk4maiddis.h
@@ -0,0 +1,100 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiddis.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIDDIS_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIDDIS_H_INCLUDED 1
+
+
+#line 10 "dk4maiddis.ctr"
+
+/** @file
+ Retrieve short int value from
+ dkChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_dec_short(
+ short *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maiddli.c b/support/dktools/dk4maiddli.c
new file mode 100644
index 0000000000..137daa15f2
--- /dev/null
+++ b/support/dktools/dk4maiddli.c
@@ -0,0 +1,71 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiddli.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiddli.c The dk4maiddli module.
+*/
+
+
+#line 68 "dk4maiddli.ctr"
+
+#include "dk4maiddli.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdli.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8dli.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_dec_ll(
+ long long *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_dec_ll(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_ll(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maiddli.ctr b/support/dktools/dk4maiddli.ctr
new file mode 100644
index 0000000000..2df351cc05
--- /dev/null
+++ b/support/dktools/dk4maiddli.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve long long value from
+ dkChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_dec_ll(
+ long long *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4maiddli.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdli.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8dli.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_dec_ll(
+ long long *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_dec_ll(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_ll(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maiddli.h b/support/dktools/dk4maiddli.h
new file mode 100644
index 0000000000..caa186ec27
--- /dev/null
+++ b/support/dktools/dk4maiddli.h
@@ -0,0 +1,100 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiddli.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIDDLI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIDDLI_H_INCLUDED 1
+
+
+#line 10 "dk4maiddli.ctr"
+
+/** @file
+ Retrieve long long value from
+ dkChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_dec_ll(
+ long long *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maiddlu.c b/support/dktools/dk4maiddlu.c
new file mode 100644
index 0000000000..44b87745f6
--- /dev/null
+++ b/support/dktools/dk4maiddlu.c
@@ -0,0 +1,71 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiddlu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiddlu.c The dk4maiddlu module.
+*/
+
+
+#line 68 "dk4maiddlu.ctr"
+
+#include "dk4maiddlu.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdlu.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8dlu.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_dec_ull(
+ unsigned long long *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_dec_ull(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_ull(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maiddlu.ctr b/support/dktools/dk4maiddlu.ctr
new file mode 100644
index 0000000000..e2f21e70ab
--- /dev/null
+++ b/support/dktools/dk4maiddlu.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve unsigned long long value from
+ dkChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_dec_ull(
+ unsigned long long *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4maiddlu.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdlu.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8dlu.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_dec_ull(
+ unsigned long long *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_dec_ull(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_ull(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maiddlu.h b/support/dktools/dk4maiddlu.h
new file mode 100644
index 0000000000..5488564746
--- /dev/null
+++ b/support/dktools/dk4maiddlu.h
@@ -0,0 +1,100 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiddlu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIDDLU_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIDDLU_H_INCLUDED 1
+
+
+#line 10 "dk4maiddlu.ctr"
+
+/** @file
+ Retrieve unsigned long long value from
+ dkChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_dec_ull(
+ unsigned long long *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maiddmi.c b/support/dktools/dk4maiddmi.c
new file mode 100644
index 0000000000..0df99ed896
--- /dev/null
+++ b/support/dktools/dk4maiddmi.c
@@ -0,0 +1,80 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiddmi.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiddmi.c The dk4maiddmi module.
+*/
+
+
+#line 71 "dk4maiddmi.ctr"
+
+#include "dk4maiddmi.h"
+
+#if DK4_ON_WINDOWS
+#pragma warning (disable:4206)
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdmi.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8dmi.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_dec_intmax_t(
+ intmax_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_dec_intmax_t(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_intmax_t(rp, src, endptr, atg, erp));
+#endif
+}
+
+
+#endif
+
diff --git a/support/dktools/dk4maiddmi.ctr b/support/dktools/dk4maiddmi.ctr
new file mode 100644
index 0000000000..6a38f39640
--- /dev/null
+++ b/support/dktools/dk4maiddmi.ctr
@@ -0,0 +1,110 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve intmax_t value from
+ dkChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_dec_intmax_t(
+ intmax_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+%% module
+
+#include "dk4maiddmi.h"
+
+#if DK4_ON_WINDOWS
+#pragma warning (disable:4206)
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdmi.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8dmi.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_dec_intmax_t(
+ intmax_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_dec_intmax_t(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_intmax_t(rp, src, endptr, atg, erp));
+#endif
+}
+
+
+#endif
+
diff --git a/support/dktools/dk4maiddmi.h b/support/dktools/dk4maiddmi.h
new file mode 100644
index 0000000000..e6b4dc3c16
--- /dev/null
+++ b/support/dktools/dk4maiddmi.h
@@ -0,0 +1,103 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiddmi.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIDDMI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIDDMI_H_INCLUDED 1
+
+
+#line 10 "dk4maiddmi.ctr"
+
+/** @file
+ Retrieve intmax_t value from
+ dkChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_dec_intmax_t(
+ intmax_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4maiddmu.c b/support/dktools/dk4maiddmu.c
new file mode 100644
index 0000000000..55810b3e2f
--- /dev/null
+++ b/support/dktools/dk4maiddmu.c
@@ -0,0 +1,83 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiddmu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiddmu.c The dk4maiddmu module.
+*/
+
+
+#line 72 "dk4maiddmu.ctr"
+
+#include "dk4maiddmu.h"
+
+#if DK4_ON_WINDOWS
+#pragma warning (disable:4206)
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdmu.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8dmu.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_dec_uintmax_t(
+ uintmax_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_dec_uintmax_t(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_uintmax_t(rp, src, endptr, atg, erp));
+#endif
+}
+
+
+
+#endif
+
diff --git a/support/dktools/dk4maiddmu.ctr b/support/dktools/dk4maiddmu.ctr
new file mode 100644
index 0000000000..a4b8577657
--- /dev/null
+++ b/support/dktools/dk4maiddmu.ctr
@@ -0,0 +1,114 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve uintmax_t value from
+ dkChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_dec_uintmax_t(
+ uintmax_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
+%% module
+
+#include "dk4maiddmu.h"
+
+#if DK4_ON_WINDOWS
+#pragma warning (disable:4206)
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdmu.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8dmu.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_dec_uintmax_t(
+ uintmax_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_dec_uintmax_t(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_uintmax_t(rp, src, endptr, atg, erp));
+#endif
+}
+
+
+
+#endif
+
diff --git a/support/dktools/dk4maiddmu.h b/support/dktools/dk4maiddmu.h
new file mode 100644
index 0000000000..c8cd691b0a
--- /dev/null
+++ b/support/dktools/dk4maiddmu.h
@@ -0,0 +1,104 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiddmu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIDDMU_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIDDMU_H_INCLUDED 1
+
+
+#line 10 "dk4maiddmu.ctr"
+
+/** @file
+ Retrieve uintmax_t value from
+ dkChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_dec_uintmax_t(
+ uintmax_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maiddsz.c b/support/dktools/dk4maiddsz.c
new file mode 100644
index 0000000000..098248bc0a
--- /dev/null
+++ b/support/dktools/dk4maiddsz.c
@@ -0,0 +1,71 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiddsz.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiddsz.c The dk4maiddsz module.
+*/
+
+
+#line 68 "dk4maiddsz.ctr"
+
+#include "dk4maiddsz.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdsz.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8dsz.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_dec_size_t(
+ size_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_dec_size_t(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_size_t(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maiddsz.ctr b/support/dktools/dk4maiddsz.ctr
new file mode 100644
index 0000000000..f284ae79c1
--- /dev/null
+++ b/support/dktools/dk4maiddsz.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve size_t value from
+ dkChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_dec_size_t(
+ size_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4maiddsz.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdsz.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8dsz.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_dec_size_t(
+ size_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_dec_size_t(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_size_t(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maiddsz.h b/support/dktools/dk4maiddsz.h
new file mode 100644
index 0000000000..8b367e5bfe
--- /dev/null
+++ b/support/dktools/dk4maiddsz.h
@@ -0,0 +1,100 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiddsz.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIDDSZ_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIDDSZ_H_INCLUDED 1
+
+
+#line 10 "dk4maiddsz.ctr"
+
+/** @file
+ Retrieve size_t value from
+ dkChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_dec_size_t(
+ size_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maidduc.c b/support/dktools/dk4maidduc.c
new file mode 100644
index 0000000000..5a92c86bf4
--- /dev/null
+++ b/support/dktools/dk4maidduc.c
@@ -0,0 +1,71 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maidduc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maidduc.c The dk4maidduc module.
+*/
+
+
+#line 68 "dk4maidduc.ctr"
+
+#include "dk4maidduc.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwduc.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8duc.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_dec_uchar(
+ unsigned char *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_dec_uchar(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_uchar(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maidduc.ctr b/support/dktools/dk4maidduc.ctr
new file mode 100644
index 0000000000..bc369d5227
--- /dev/null
+++ b/support/dktools/dk4maidduc.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve unsigned char value from
+ dkChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_dec_uchar(
+ unsigned char *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4maidduc.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwduc.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8duc.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_dec_uchar(
+ unsigned char *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_dec_uchar(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_uchar(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maidduc.h b/support/dktools/dk4maidduc.h
new file mode 100644
index 0000000000..7d392a3f4c
--- /dev/null
+++ b/support/dktools/dk4maidduc.h
@@ -0,0 +1,100 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maidduc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIDDUC_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIDDUC_H_INCLUDED 1
+
+
+#line 10 "dk4maidduc.ctr"
+
+/** @file
+ Retrieve unsigned char value from
+ dkChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_dec_uchar(
+ unsigned char *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maiddui.c b/support/dktools/dk4maiddui.c
new file mode 100644
index 0000000000..2c358d35db
--- /dev/null
+++ b/support/dktools/dk4maiddui.c
@@ -0,0 +1,71 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiddui.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiddui.c The dk4maiddui module.
+*/
+
+
+#line 68 "dk4maiddui.ctr"
+
+#include "dk4maiddui.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdui.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8dui.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_dec_uint(
+ unsigned *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_dec_uint(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_uint(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maiddui.ctr b/support/dktools/dk4maiddui.ctr
new file mode 100644
index 0000000000..d2a4b65af4
--- /dev/null
+++ b/support/dktools/dk4maiddui.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve unsigned int value from
+ dkChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_dec_uint(
+ unsigned *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4maiddui.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdui.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8dui.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_dec_uint(
+ unsigned *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_dec_uint(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_uint(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maiddui.h b/support/dktools/dk4maiddui.h
new file mode 100644
index 0000000000..8f96a0e67b
--- /dev/null
+++ b/support/dktools/dk4maiddui.h
@@ -0,0 +1,100 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiddui.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIDDUI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIDDUI_H_INCLUDED 1
+
+
+#line 10 "dk4maiddui.ctr"
+
+/** @file
+ Retrieve unsigned int value from
+ dkChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_dec_uint(
+ unsigned *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maiddul.c b/support/dktools/dk4maiddul.c
new file mode 100644
index 0000000000..a3742c6d3e
--- /dev/null
+++ b/support/dktools/dk4maiddul.c
@@ -0,0 +1,71 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiddul.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiddul.c The dk4maiddul module.
+*/
+
+
+#line 68 "dk4maiddul.ctr"
+
+#include "dk4maidddu.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdul.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8dul.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_dec_ulong(
+ unsigned long *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_dec_ulong(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_ulong(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maiddul.ctr b/support/dktools/dk4maiddul.ctr
new file mode 100644
index 0000000000..16c1e465c1
--- /dev/null
+++ b/support/dktools/dk4maiddul.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve unsigned long value from
+ dkChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_dec_ulong(
+ unsigned long *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4maidddu.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdul.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8dul.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_dec_ulong(
+ unsigned long *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_dec_ulong(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_ulong(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maiddul.h b/support/dktools/dk4maiddul.h
new file mode 100644
index 0000000000..f25816c217
--- /dev/null
+++ b/support/dktools/dk4maiddul.h
@@ -0,0 +1,100 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiddul.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIDDUL_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIDDUL_H_INCLUDED 1
+
+
+#line 10 "dk4maiddul.ctr"
+
+/** @file
+ Retrieve unsigned long value from
+ dkChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_dec_ulong(
+ unsigned long *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maiddus.c b/support/dktools/dk4maiddus.c
new file mode 100644
index 0000000000..1b2b0991ed
--- /dev/null
+++ b/support/dktools/dk4maiddus.c
@@ -0,0 +1,71 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiddus.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiddus.c The dk4maiddus module.
+*/
+
+
+#line 68 "dk4maiddus.ctr"
+
+#include "dk4maiddus.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdus.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8dus.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_dec_ushort(
+ unsigned short *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_dec_ushort(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_ushort(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maiddus.ctr b/support/dktools/dk4maiddus.ctr
new file mode 100644
index 0000000000..a36bedbde3
--- /dev/null
+++ b/support/dktools/dk4maiddus.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve unsigned short value from
+ dkChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_dec_ushort(
+ unsigned short *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4maiddus.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdus.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8dus.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_dec_ushort(
+ unsigned short *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_dec_ushort(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_ushort(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maiddus.h b/support/dktools/dk4maiddus.h
new file mode 100644
index 0000000000..a2bd9f1511
--- /dev/null
+++ b/support/dktools/dk4maiddus.h
@@ -0,0 +1,100 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiddus.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIDDUS_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIDDUS_H_INCLUDED 1
+
+
+#line 10 "dk4maiddus.ctr"
+
+/** @file
+ Retrieve unsigned short value from
+ dkChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_dec_ushort(
+ unsigned short *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maidhdi.c b/support/dktools/dk4maidhdi.c
new file mode 100644
index 0000000000..3d6371c0a6
--- /dev/null
+++ b/support/dktools/dk4maidhdi.c
@@ -0,0 +1,71 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maidhdi.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maidhdi.c The dk4maidhdi module.
+*/
+
+
+#line 68 "dk4maidhdi.ctr"
+
+#include "dk4maidhdi.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwhdi.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8hdi.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_hex_dk4_im_t(
+ dk4_im_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_hex_dk4_im_t(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_hex_dk4_im_t(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maidhdi.ctr b/support/dktools/dk4maidhdi.ctr
new file mode 100644
index 0000000000..67554ffac3
--- /dev/null
+++ b/support/dktools/dk4maidhdi.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve dk4_im_t value from
+ dkChar string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_hex_dk4_im_t(
+ dk4_im_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4maidhdi.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwhdi.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8hdi.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_hex_dk4_im_t(
+ dk4_im_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_hex_dk4_im_t(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_hex_dk4_im_t(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maidhdi.h b/support/dktools/dk4maidhdi.h
new file mode 100644
index 0000000000..fd1ab21aca
--- /dev/null
+++ b/support/dktools/dk4maidhdi.h
@@ -0,0 +1,100 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maidhdi.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIDHDI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIDHDI_H_INCLUDED 1
+
+
+#line 10 "dk4maidhdi.ctr"
+
+/** @file
+ Retrieve dk4_im_t value from
+ dkChar string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_hex_dk4_im_t(
+ dk4_im_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maidhdu.c b/support/dktools/dk4maidhdu.c
new file mode 100644
index 0000000000..de890fd0d2
--- /dev/null
+++ b/support/dktools/dk4maidhdu.c
@@ -0,0 +1,71 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maidhdu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maidhdu.c The dk4maidhdu module.
+*/
+
+
+#line 68 "dk4maidhdu.ctr"
+
+#include "dk4maidhdu.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwhdu.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8hdu.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_hex_dk4_um_t(
+ dk4_um_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_hex_dk4_um_t(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_hex_dk4_um_t(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maidhdu.ctr b/support/dktools/dk4maidhdu.ctr
new file mode 100644
index 0000000000..1dd1ac1050
--- /dev/null
+++ b/support/dktools/dk4maidhdu.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve dk4_um_t value from
+ dkChar string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_hex_dk4_um_t(
+ dk4_um_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4maidhdu.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwhdu.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8hdu.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_hex_dk4_um_t(
+ dk4_um_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_hex_dk4_um_t(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_hex_dk4_um_t(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maidhdu.h b/support/dktools/dk4maidhdu.h
new file mode 100644
index 0000000000..cba66b83d9
--- /dev/null
+++ b/support/dktools/dk4maidhdu.h
@@ -0,0 +1,100 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maidhdu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIDHDU_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIDHDU_H_INCLUDED 1
+
+
+#line 10 "dk4maidhdu.ctr"
+
+/** @file
+ Retrieve dk4_um_t value from
+ dkChar string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_hex_dk4_um_t(
+ dk4_um_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maidhic.c b/support/dktools/dk4maidhic.c
new file mode 100644
index 0000000000..4fdd4cf11b
--- /dev/null
+++ b/support/dktools/dk4maidhic.c
@@ -0,0 +1,71 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maidhic.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maidhic.c The dk4maidhic module.
+*/
+
+
+#line 68 "dk4maidhic.ctr"
+
+#include "dk4maidhic.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwhic.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8hic.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_hex_char(
+ signed char *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_hex_char(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_hex_char(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maidhic.ctr b/support/dktools/dk4maidhic.ctr
new file mode 100644
index 0000000000..4ac32518bc
--- /dev/null
+++ b/support/dktools/dk4maidhic.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve signed char value from
+ dkChar string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_hex_char(
+ signed char *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4maidhic.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwhic.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8hic.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_hex_char(
+ signed char *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_hex_char(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_hex_char(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maidhic.h b/support/dktools/dk4maidhic.h
new file mode 100644
index 0000000000..a88e40f100
--- /dev/null
+++ b/support/dktools/dk4maidhic.h
@@ -0,0 +1,100 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maidhic.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIDHIC_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIDHIC_H_INCLUDED 1
+
+
+#line 10 "dk4maidhic.ctr"
+
+/** @file
+ Retrieve signed char value from
+ dkChar string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_hex_char(
+ signed char *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maidhii.c b/support/dktools/dk4maidhii.c
new file mode 100644
index 0000000000..a4f1c31eb4
--- /dev/null
+++ b/support/dktools/dk4maidhii.c
@@ -0,0 +1,71 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maidhii.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maidhii.c The dk4maidhii module.
+*/
+
+
+#line 68 "dk4maidhii.ctr"
+
+#include "dk4maidhii.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwhii.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8hii.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_hex_int(
+ int *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_hex_int(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_hex_int(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maidhii.ctr b/support/dktools/dk4maidhii.ctr
new file mode 100644
index 0000000000..11118357d4
--- /dev/null
+++ b/support/dktools/dk4maidhii.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve int value from
+ dkChar string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_hex_int(
+ int *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4maidhii.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwhii.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8hii.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_hex_int(
+ int *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_hex_int(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_hex_int(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maidhii.h b/support/dktools/dk4maidhii.h
new file mode 100644
index 0000000000..566f66ac76
--- /dev/null
+++ b/support/dktools/dk4maidhii.h
@@ -0,0 +1,100 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maidhii.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIDHII_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIDHII_H_INCLUDED 1
+
+
+#line 10 "dk4maidhii.ctr"
+
+/** @file
+ Retrieve int value from
+ dkChar string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_hex_int(
+ int *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maidhil.c b/support/dktools/dk4maidhil.c
new file mode 100644
index 0000000000..4decc015a8
--- /dev/null
+++ b/support/dktools/dk4maidhil.c
@@ -0,0 +1,71 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maidhil.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maidhil.c The dk4maidhil module.
+*/
+
+
+#line 68 "dk4maidhil.ctr"
+
+#include "dk4maidhil.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwhil.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8hil.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_hex_long(
+ long *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_hex_long(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_hex_long(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maidhil.ctr b/support/dktools/dk4maidhil.ctr
new file mode 100644
index 0000000000..df24d1bb5f
--- /dev/null
+++ b/support/dktools/dk4maidhil.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve long value from
+ dkChar string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_hex_long(
+ long *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4maidhil.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwhil.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8hil.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_hex_long(
+ long *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_hex_long(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_hex_long(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maidhil.h b/support/dktools/dk4maidhil.h
new file mode 100644
index 0000000000..92ddbc6ff5
--- /dev/null
+++ b/support/dktools/dk4maidhil.h
@@ -0,0 +1,100 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maidhil.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIDHIL_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIDHIL_H_INCLUDED 1
+
+
+#line 10 "dk4maidhil.ctr"
+
+/** @file
+ Retrieve long value from
+ dkChar string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_hex_long(
+ long *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maidhis.c b/support/dktools/dk4maidhis.c
new file mode 100644
index 0000000000..82b3886826
--- /dev/null
+++ b/support/dktools/dk4maidhis.c
@@ -0,0 +1,71 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maidhis.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maidhis.c The dk4maidhis module.
+*/
+
+
+#line 68 "dk4maidhis.ctr"
+
+#include "dk4maidhis.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwhis.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8his.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_hex_short(
+ short *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_hex_short(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_hex_short(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maidhis.ctr b/support/dktools/dk4maidhis.ctr
new file mode 100644
index 0000000000..f2810d3823
--- /dev/null
+++ b/support/dktools/dk4maidhis.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve short value from
+ dkChar string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_hex_short(
+ short *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4maidhis.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwhis.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8his.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_hex_short(
+ short *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_hex_short(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_hex_short(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maidhis.h b/support/dktools/dk4maidhis.h
new file mode 100644
index 0000000000..961f124684
--- /dev/null
+++ b/support/dktools/dk4maidhis.h
@@ -0,0 +1,100 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maidhis.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIDHIS_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIDHIS_H_INCLUDED 1
+
+
+#line 10 "dk4maidhis.ctr"
+
+/** @file
+ Retrieve short value from
+ dkChar string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_hex_short(
+ short *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maidhli.c b/support/dktools/dk4maidhli.c
new file mode 100644
index 0000000000..ca342f83e2
--- /dev/null
+++ b/support/dktools/dk4maidhli.c
@@ -0,0 +1,71 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maidhli.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maidhli.c The dk4maidhli module.
+*/
+
+
+#line 68 "dk4maidhli.ctr"
+
+#include "dk4maidhli.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwhli.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8hli.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_hex_ll(
+ long long *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_hex_ll(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_hex_ll(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maidhli.ctr b/support/dktools/dk4maidhli.ctr
new file mode 100644
index 0000000000..e05c88646a
--- /dev/null
+++ b/support/dktools/dk4maidhli.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve long long value from
+ dkChar string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_hex_ll(
+ long long *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4maidhli.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwhli.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8hli.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_hex_ll(
+ long long *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_hex_ll(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_hex_ll(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maidhli.h b/support/dktools/dk4maidhli.h
new file mode 100644
index 0000000000..5f2af0b530
--- /dev/null
+++ b/support/dktools/dk4maidhli.h
@@ -0,0 +1,100 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maidhli.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIDHLI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIDHLI_H_INCLUDED 1
+
+
+#line 10 "dk4maidhli.ctr"
+
+/** @file
+ Retrieve long long value from
+ dkChar string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_hex_ll(
+ long long *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maidhlu.c b/support/dktools/dk4maidhlu.c
new file mode 100644
index 0000000000..a689b80488
--- /dev/null
+++ b/support/dktools/dk4maidhlu.c
@@ -0,0 +1,71 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maidhlu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maidhlu.c The dk4maidhlu module.
+*/
+
+
+#line 68 "dk4maidhlu.ctr"
+
+#include "dk4maidhlu.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwhlu.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8hlu.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_hex_ull(
+ unsigned long long *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_hex_ull(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_hex_ull(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maidhlu.ctr b/support/dktools/dk4maidhlu.ctr
new file mode 100644
index 0000000000..5289f04b1a
--- /dev/null
+++ b/support/dktools/dk4maidhlu.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve unsigned long long value from
+ dkChar string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_hex_ull(
+ unsigned long long *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4maidhlu.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwhlu.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8hlu.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_hex_ull(
+ unsigned long long *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_hex_ull(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_hex_ull(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maidhlu.h b/support/dktools/dk4maidhlu.h
new file mode 100644
index 0000000000..29a8a6ec4b
--- /dev/null
+++ b/support/dktools/dk4maidhlu.h
@@ -0,0 +1,100 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maidhlu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIDHLU_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIDHLU_H_INCLUDED 1
+
+
+#line 10 "dk4maidhlu.ctr"
+
+/** @file
+ Retrieve unsigned long long value from
+ dkChar string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_hex_ull(
+ unsigned long long *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maidhmi.c b/support/dktools/dk4maidhmi.c
new file mode 100644
index 0000000000..0aeca3c951
--- /dev/null
+++ b/support/dktools/dk4maidhmi.c
@@ -0,0 +1,80 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maidhmi.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maidhmi.c The dk4maidhmi module.
+*/
+
+
+#line 71 "dk4maidhmi.ctr"
+
+#include "dk4maidhmi.h"
+
+#if DK4_ON_WINDOWS
+#pragma warning (disable:4206)
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwhmi.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8hmi.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_hex_intmax_t(
+ intmax_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_hex_intmax_t(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_hex_intmax_t(rp, src, endptr, atg, erp));
+#endif
+}
+
+#endif
+
diff --git a/support/dktools/dk4maidhmi.ctr b/support/dktools/dk4maidhmi.ctr
new file mode 100644
index 0000000000..2fc37694ee
--- /dev/null
+++ b/support/dktools/dk4maidhmi.ctr
@@ -0,0 +1,110 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve intmax_t value from
+ dkChar string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_hex_intmax_t(
+ intmax_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+%% module
+
+#include "dk4maidhmi.h"
+
+#if DK4_ON_WINDOWS
+#pragma warning (disable:4206)
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwhmi.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8hmi.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_hex_intmax_t(
+ intmax_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_hex_intmax_t(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_hex_intmax_t(rp, src, endptr, atg, erp));
+#endif
+}
+
+#endif
+
diff --git a/support/dktools/dk4maidhmi.h b/support/dktools/dk4maidhmi.h
new file mode 100644
index 0000000000..bff5a5394a
--- /dev/null
+++ b/support/dktools/dk4maidhmi.h
@@ -0,0 +1,103 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maidhmi.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIDHMI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIDHMI_H_INCLUDED 1
+
+
+#line 10 "dk4maidhmi.ctr"
+
+/** @file
+ Retrieve intmax_t value from
+ dkChar string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_hex_intmax_t(
+ intmax_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4maidhmu.c b/support/dktools/dk4maidhmu.c
new file mode 100644
index 0000000000..8a55f521a6
--- /dev/null
+++ b/support/dktools/dk4maidhmu.c
@@ -0,0 +1,79 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maidhmu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maidhmu.c The dk4maidhmu module.
+*/
+
+
+#line 71 "dk4maidhmu.ctr"
+
+#include "dk4maidhmu.h"
+
+#if DK4_ON_WINDOWS
+#pragma warning (disable:4206)
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwhmu.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8hmu.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_hex_uintmax_t(
+ uintmax_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_hex_uintmax_t(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_hex_uintmax_t(rp, src, endptr, atg, erp));
+#endif
+}
+
+#endif
+
diff --git a/support/dktools/dk4maidhmu.ctr b/support/dktools/dk4maidhmu.ctr
new file mode 100644
index 0000000000..ba00195ec1
--- /dev/null
+++ b/support/dktools/dk4maidhmu.ctr
@@ -0,0 +1,109 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve uintmax_t value from
+ dkChar string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_hex_uintmax_t(
+ uintmax_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+%% module
+
+#include "dk4maidhmu.h"
+
+#if DK4_ON_WINDOWS
+#pragma warning (disable:4206)
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwhmu.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8hmu.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_hex_uintmax_t(
+ uintmax_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_hex_uintmax_t(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_hex_uintmax_t(rp, src, endptr, atg, erp));
+#endif
+}
+
+#endif
+
diff --git a/support/dktools/dk4maidhmu.h b/support/dktools/dk4maidhmu.h
new file mode 100644
index 0000000000..46c15500bc
--- /dev/null
+++ b/support/dktools/dk4maidhmu.h
@@ -0,0 +1,103 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maidhmu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIDHMU_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIDHMU_H_INCLUDED 1
+
+
+#line 10 "dk4maidhmu.ctr"
+
+/** @file
+ Retrieve uintmax_t value from
+ dkChar string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_hex_uintmax_t(
+ uintmax_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4maidhsz.c b/support/dktools/dk4maidhsz.c
new file mode 100644
index 0000000000..a80fad8093
--- /dev/null
+++ b/support/dktools/dk4maidhsz.c
@@ -0,0 +1,71 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maidhsz.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maidhsz.c The dk4maidhsz module.
+*/
+
+
+#line 68 "dk4maidhsz.ctr"
+
+#include "dk4maidhsz.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwhsz.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8hsz.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_hex_size_t(
+ size_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_hex_size_t(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_hex_size_t(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maidhsz.ctr b/support/dktools/dk4maidhsz.ctr
new file mode 100644
index 0000000000..00b49de272
--- /dev/null
+++ b/support/dktools/dk4maidhsz.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve size_t value from
+ dkChar string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_hex_size_t(
+ size_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4maidhsz.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwhsz.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8hsz.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_hex_size_t(
+ size_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_hex_size_t(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_hex_size_t(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maidhsz.h b/support/dktools/dk4maidhsz.h
new file mode 100644
index 0000000000..ae7006385a
--- /dev/null
+++ b/support/dktools/dk4maidhsz.h
@@ -0,0 +1,100 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maidhsz.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIDHSZ_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIDHSZ_H_INCLUDED 1
+
+
+#line 10 "dk4maidhsz.ctr"
+
+/** @file
+ Retrieve size_t value from
+ dkChar string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_hex_size_t(
+ size_t *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maidhuc.c b/support/dktools/dk4maidhuc.c
new file mode 100644
index 0000000000..a1f7d7b66d
--- /dev/null
+++ b/support/dktools/dk4maidhuc.c
@@ -0,0 +1,71 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maidhuc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maidhuc.c The dk4maidhuc module.
+*/
+
+
+#line 68 "dk4maidhuc.ctr"
+
+#include "dk4maidhuc.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwhuc.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8huc.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_hex_uchar(
+ unsigned char *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_hex_uchar(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_hex_uchar(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maidhuc.ctr b/support/dktools/dk4maidhuc.ctr
new file mode 100644
index 0000000000..c6cd9f7e7b
--- /dev/null
+++ b/support/dktools/dk4maidhuc.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve unsigned char value from
+ dkChar string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_hex_uchar(
+ unsigned char *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4maidhuc.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwhuc.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8huc.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_hex_uchar(
+ unsigned char *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_hex_uchar(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_hex_uchar(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maidhuc.h b/support/dktools/dk4maidhuc.h
new file mode 100644
index 0000000000..ab75f758b7
--- /dev/null
+++ b/support/dktools/dk4maidhuc.h
@@ -0,0 +1,100 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maidhuc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIDHUC_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIDHUC_H_INCLUDED 1
+
+
+#line 10 "dk4maidhuc.ctr"
+
+/** @file
+ Retrieve unsigned char value from
+ dkChar string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_hex_uchar(
+ unsigned char *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maidhui.c b/support/dktools/dk4maidhui.c
new file mode 100644
index 0000000000..24ce5b030e
--- /dev/null
+++ b/support/dktools/dk4maidhui.c
@@ -0,0 +1,71 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maidhui.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maidhui.c The dk4maidhui module.
+*/
+
+
+#line 68 "dk4maidhui.ctr"
+
+#include "dk4maidhui.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwhui.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8hui.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_hex_uint(
+ unsigned *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_hex_uint(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_hex_uint(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maidhui.ctr b/support/dktools/dk4maidhui.ctr
new file mode 100644
index 0000000000..9579f1982e
--- /dev/null
+++ b/support/dktools/dk4maidhui.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve unsigned int value from
+ dkChar string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_hex_uint(
+ unsigned *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4maidhui.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwhui.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8hui.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_hex_uint(
+ unsigned *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_hex_uint(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_hex_uint(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maidhui.h b/support/dktools/dk4maidhui.h
new file mode 100644
index 0000000000..f6b8f04beb
--- /dev/null
+++ b/support/dktools/dk4maidhui.h
@@ -0,0 +1,100 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maidhui.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIDHUI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIDHUI_H_INCLUDED 1
+
+
+#line 10 "dk4maidhui.ctr"
+
+/** @file
+ Retrieve unsigned int value from
+ dkChar string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_hex_uint(
+ unsigned *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maidhul.c b/support/dktools/dk4maidhul.c
new file mode 100644
index 0000000000..2532e2418c
--- /dev/null
+++ b/support/dktools/dk4maidhul.c
@@ -0,0 +1,71 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maidhul.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maidhul.c The dk4maidhul module.
+*/
+
+
+#line 68 "dk4maidhul.ctr"
+
+#include "dk4maidhul.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwhul.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8hul.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_hex_ulong(
+ unsigned long *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_hex_ulong(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_hex_ulong(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maidhul.ctr b/support/dktools/dk4maidhul.ctr
new file mode 100644
index 0000000000..a8461f7107
--- /dev/null
+++ b/support/dktools/dk4maidhul.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve unsigned long value from
+ dkChar string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_hex_ulong(
+ unsigned long *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4maidhul.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwhul.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8hul.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_hex_ulong(
+ unsigned long *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_hex_ulong(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_hex_ulong(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maidhul.h b/support/dktools/dk4maidhul.h
new file mode 100644
index 0000000000..2bea1278d4
--- /dev/null
+++ b/support/dktools/dk4maidhul.h
@@ -0,0 +1,100 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maidhul.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIDHUL_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIDHUL_H_INCLUDED 1
+
+
+#line 10 "dk4maidhul.ctr"
+
+/** @file
+ Retrieve unsigned long value from
+ dkChar string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_hex_ulong(
+ unsigned long *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maidhus.c b/support/dktools/dk4maidhus.c
new file mode 100644
index 0000000000..fdb12fdcf8
--- /dev/null
+++ b/support/dktools/dk4maidhus.c
@@ -0,0 +1,71 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maidhus.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maidhus.c The dk4maidhus module.
+*/
+
+
+#line 68 "dk4maidhus.ctr"
+
+#include "dk4maidhus.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwhus.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8hus.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_hex_ushort(
+ unsigned short *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_hex_ushort(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_hex_ushort(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maidhus.ctr b/support/dktools/dk4maidhus.ctr
new file mode 100644
index 0000000000..7c8cf7a66e
--- /dev/null
+++ b/support/dktools/dk4maidhus.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve unsigned short value from
+ dkChar string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_hex_ushort(
+ unsigned short *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4maidhus.h"
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwhus.h"
+#else
+#error "Illegal dkChar size!"
+#endif
+#else
+#include "dk4mai8hus.h"
+#endif
+
+
+
+int
+dk4ma_input_dk_hex_ushort(
+ unsigned short *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return ( dk4ma_input_wc_hex_ushort(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_hex_ushort(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maidhus.h b/support/dktools/dk4maidhus.h
new file mode 100644
index 0000000000..25395d6602
--- /dev/null
+++ b/support/dktools/dk4maidhus.h
@@ -0,0 +1,100 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maidhus.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIDHUS_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIDHUS_H_INCLUDED 1
+
+
+#line 10 "dk4maidhus.ctr"
+
+/** @file
+ Retrieve unsigned short value from
+ dkChar string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_dk_hex_ushort(
+ unsigned short *rp,
+ const dkChar *src,
+ const dkChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maiwdbl.c b/support/dktools/dk4maiwdbl.c
new file mode 100644
index 0000000000..02988bd04b
--- /dev/null
+++ b/support/dktools/dk4maiwdbl.c
@@ -0,0 +1,215 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwdbl.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiwdbl.c The dk4maiwdbl module.
+*/
+
+
+#line 77 "dk4maiwdbl.ctr"
+
+
+#include "dk4maiwdbl.h"
+
+#include "dk4strw.h"
+
+#if DK4_HAVE_WCHAR_H
+#ifndef WCHAR_H_INCLUDED
+#include <wchar.h>
+#define WCHAR_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_LOCALE_H
+#ifndef LOCALE_H_INCLUDED
+#include <locale.h>
+#define LOCALE_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_MATH_H
+#ifndef MATH_H_INCLUDED
+#include <math.h>
+#define MATH_H_INCLUDED 1
+#endif
+#endif
+
+
+
+
+/** Locale setting to use when retrieving number.
+*/
+static const char locale_kw[] = { "C" };
+
+
+
+static
+int
+dk4ma_internal_input_wc_double(
+ double *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_WCSTOD || DK4_HAVE__WCSTOD
+ double val = 0.0;
+ wchar_t *myend = NULL;
+ int back = 0;
+ int xerr = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ errno = 0;
+#if DK4_HAVE_WCSTOD
+ val = wcstod(src, &myend);
+#else
+ val = _wcstod(src, &myend);
+#endif
+ xerr = errno;
+ if (NULL != endptr) { *endptr = myend; }
+ if (myend != src) {
+ switch (atg) {
+ case 2: {
+ back = 1;
+ } break;
+ case 1: {
+ if (NULL != dk4strw_start(myend, NULL)) {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } else {
+ back = 1;
+ }
+ } break;
+ default: {
+ if (L'\0' != *myend) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ }
+ if (1 == back) {
+ if (ERANGE == xerr) {
+ if (HUGE_VAL == val) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ if ((-HUGE_VAL) == val) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ if (0.0 == val) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_UNDERFLOW);
+ }
+ }
+ if (EINVAL == xerr) {
+ if (0.0 == val) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ if (1 == back) {
+ *rp = val;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+#if DK4_USE_PRINTF_SCANF
+ double val = 0.0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (1 == swscanf(src, L"%lf", &val)) {
+ *rp = val;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+#endif
+}
+
+
+
+int
+dk4ma_input_wc_double(
+ double *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if (DK4_HAVE_SETLOCALE) && defined(LC_NUMERIC)
+ char *oldloc = NULL;
+#endif
+ int back = 0;
+
+#if (DK4_HAVE_SETLOCALE) && defined(LC_NUMERIC)
+ oldloc = setlocale(LC_NUMERIC, NULL);
+ (void)setlocale(LC_NUMERIC, locale_kw);
+ back = dk4ma_internal_input_wc_double(rp, src, endptr, atg, erp);
+ (void)setlocale(LC_NUMERIC, oldloc);
+#else
+ back = dk4ma_internal_input_wc_double(rp, src, endptr, atg, erp);
+#endif
+ return back;
+}
+
diff --git a/support/dktools/dk4maiwdbl.ctr b/support/dktools/dk4maiwdbl.ctr
new file mode 100644
index 0000000000..92ec72741a
--- /dev/null
+++ b/support/dktools/dk4maiwdbl.ctr
@@ -0,0 +1,251 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Read double value from wchar_t string.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Read double value from char string.
+ The function temporarily resets the LC_NUMERIC locale setting
+ to "C" to retrieve the number and returns the setting to the
+ original value before returning.
+ @param rp Address of result variable.
+ @param src String to process.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here. The function may also store
+ a NULL pointer here.
+ The pointer variable is probably left unchanged
+ on errors or if wcstod() is not available on your
+ system (the swscanf() function is used as fallback).
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characaters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_SYNTAX if there are unexpected characters in the
+ string,
+ DK4_E_MATH_OVERFLOW if a mathematical overflow occurs,
+ DK4_E_MATH_UNDERFLOW if a mathematical underflow occurs.
+*/
+int
+dk4ma_input_wc_double(
+ double *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+%% module
+
+
+#include "dk4maiwdbl.h"
+
+#include "dk4strw.h"
+
+#if DK4_HAVE_WCHAR_H
+#ifndef WCHAR_H_INCLUDED
+#include <wchar.h>
+#define WCHAR_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_LOCALE_H
+#ifndef LOCALE_H_INCLUDED
+#include <locale.h>
+#define LOCALE_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_MATH_H
+#ifndef MATH_H_INCLUDED
+#include <math.h>
+#define MATH_H_INCLUDED 1
+#endif
+#endif
+
+
+
+
+/** Locale setting to use when retrieving number.
+*/
+static const char locale_kw[] = { "C" };
+
+
+
+static
+int
+dk4ma_internal_input_wc_double(
+ double *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_WCSTOD || DK4_HAVE__WCSTOD
+ double val = 0.0;
+ wchar_t *myend = NULL;
+ int back = 0;
+ int xerr = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ errno = 0;
+#if DK4_HAVE_WCSTOD
+ val = wcstod(src, &myend);
+#else
+ val = _wcstod(src, &myend);
+#endif
+ xerr = errno;
+ if (NULL != endptr) { *endptr = myend; }
+ if (myend != src) {
+ switch (atg) {
+ case 2: {
+ back = 1;
+ } break;
+ case 1: {
+ if (NULL != dk4strw_start(myend, NULL)) {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } else {
+ back = 1;
+ }
+ } break;
+ default: {
+ if (L'\0' != *myend) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ }
+ if (1 == back) {
+ if (ERANGE == xerr) {
+ if (HUGE_VAL == val) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ if ((-HUGE_VAL) == val) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ if (0.0 == val) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_UNDERFLOW);
+ }
+ }
+ if (EINVAL == xerr) {
+ if (0.0 == val) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ if (1 == back) {
+ *rp = val;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+#if DK4_USE_PRINTF_SCANF
+ double val = 0.0;
+ int back = 0;
+ if ((NULL != rp) && (NULL != src)) {
+ if (1 == swscanf(src, L"%lf", &val)) {
+ *rp = val;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+#endif
+}
+
+
+
+int
+dk4ma_input_wc_double(
+ double *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if (DK4_HAVE_SETLOCALE) && defined(LC_NUMERIC)
+ char *oldloc = NULL;
+#endif
+ int back = 0;
+
+#if (DK4_HAVE_SETLOCALE) && defined(LC_NUMERIC)
+ oldloc = setlocale(LC_NUMERIC, NULL);
+ (void)setlocale(LC_NUMERIC, locale_kw);
+ back = dk4ma_internal_input_wc_double(rp, src, endptr, atg, erp);
+ (void)setlocale(LC_NUMERIC, oldloc);
+#else
+ back = dk4ma_internal_input_wc_double(rp, src, endptr, atg, erp);
+#endif
+ return back;
+}
+
diff --git a/support/dktools/dk4maiwdbl.h b/support/dktools/dk4maiwdbl.h
new file mode 100644
index 0000000000..197be831e4
--- /dev/null
+++ b/support/dktools/dk4maiwdbl.h
@@ -0,0 +1,109 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwdbl.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIWDBL_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIWDBL_H_INCLUDED 1
+
+
+#line 10 "dk4maiwdbl.ctr"
+
+/** @file
+ Read double value from wchar_t string.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Read double value from char string.
+ The function temporarily resets the LC_NUMERIC locale setting
+ to "C" to retrieve the number and returns the setting to the
+ original value before returning.
+ @param rp Address of result variable.
+ @param src String to process.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here. The function may also store
+ a NULL pointer here.
+ The pointer variable is probably left unchanged
+ on errors or if wcstod() is not available on your
+ system (the swscanf() function is used as fallback).
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characaters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_SYNTAX if there are unexpected characters in the
+ string,
+ DK4_E_MATH_OVERFLOW if a mathematical overflow occurs,
+ DK4_E_MATH_UNDERFLOW if a mathematical underflow occurs.
+*/
+int
+dk4ma_input_wc_double(
+ double *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maiwddi.c b/support/dktools/dk4maiwddi.c
new file mode 100644
index 0000000000..6760ccbf64
--- /dev/null
+++ b/support/dktools/dk4maiwddi.c
@@ -0,0 +1,92 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwddi.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiwddi.c The dk4maiwddi module.
+*/
+
+
+#line 69 "dk4maiwddi.ctr"
+
+
+#include "dk4maiwddi.h"
+#include "dk4maiwddu.h"
+#include "dk4numco.h"
+
+
+int
+dk4ma_input_wc_dec_dk4_im_t(
+ dk4_im_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ const wchar_t *ep = NULL;
+ dk4_um_t res = (dk4_um_t)0UL;
+ int back = 0;
+
+ if ((NULL != rp) && (NULL != src)) {
+ if (L'-' == *src) {
+ if (0 != dk4ma_input_wc_dec_dk4_um_t(&res, ++src, &ep, atg, erp)) {
+ if (((dk4_um_t)(DK4_IM_MAX) + (dk4_um_t)1UL) == res) {
+ *rp = DK4_IM_MIN;
+ back = 1;
+ } else {
+ if (((dk4_um_t)(DK4_IM_MAX)) >= res) {
+ *rp = (dk4_im_t)0L - (dk4_im_t)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ } else {
+ if (0 != dk4ma_input_wc_dec_dk4_um_t(&res, src, &ep, atg, erp)) {
+ if (((dk4_um_t)(DK4_IM_MAX)) >= res) {
+ *rp = (dk4_im_t)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ if (NULL != endptr) { *endptr = ep; }
+ return back;
+}
+
diff --git a/support/dktools/dk4maiwddi.ctr b/support/dktools/dk4maiwddi.ctr
new file mode 100644
index 0000000000..697b8cd92b
--- /dev/null
+++ b/support/dktools/dk4maiwddi.ctr
@@ -0,0 +1,120 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve dk4_im_t value from
+ wchar_t string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_dec_dk4_im_t(
+ dk4_im_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+
+#include "dk4maiwddi.h"
+#include "dk4maiwddu.h"
+#include "dk4numco.h"
+
+
+int
+dk4ma_input_wc_dec_dk4_im_t(
+ dk4_im_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ const wchar_t *ep = NULL;
+ dk4_um_t res = (dk4_um_t)0UL;
+ int back = 0;
+
+ if ((NULL != rp) && (NULL != src)) {
+ if (L'-' == *src) {
+ if (0 != dk4ma_input_wc_dec_dk4_um_t(&res, ++src, &ep, atg, erp)) {
+ if (((dk4_um_t)(DK4_IM_MAX) + (dk4_um_t)1UL) == res) {
+ *rp = DK4_IM_MIN;
+ back = 1;
+ } else {
+ if (((dk4_um_t)(DK4_IM_MAX)) >= res) {
+ *rp = (dk4_im_t)0L - (dk4_im_t)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ } else {
+ if (0 != dk4ma_input_wc_dec_dk4_um_t(&res, src, &ep, atg, erp)) {
+ if (((dk4_um_t)(DK4_IM_MAX)) >= res) {
+ *rp = (dk4_im_t)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ if (NULL != endptr) { *endptr = ep; }
+ return back;
+}
+
diff --git a/support/dktools/dk4maiwddi.h b/support/dktools/dk4maiwddi.h
new file mode 100644
index 0000000000..7e79102428
--- /dev/null
+++ b/support/dktools/dk4maiwddi.h
@@ -0,0 +1,101 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwddi.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIWDDI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIWDDI_H_INCLUDED 1
+
+
+#line 10 "dk4maiwddi.ctr"
+
+/** @file
+ Retrieve dk4_im_t value from
+ wchar_t string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_dec_dk4_im_t(
+ dk4_im_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4maiwddu.c b/support/dktools/dk4maiwddu.c
new file mode 100644
index 0000000000..bc9f3d858d
--- /dev/null
+++ b/support/dktools/dk4maiwddu.c
@@ -0,0 +1,255 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwddu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiwddu.c The dk4maiwddu module.
+*/
+
+
+#line 70 "dk4maiwddu.ctr"
+
+
+
+#include "dk4maiwddu.h"
+#include "dk4numco.h"
+#include "dk4strw.h"
+
+
+
+
+
+#line 80 "dk4maiwddu.ctr"
+
+
+
+int
+dk4ma_input_wc_dec_dk4_um_t(
+ dk4_um_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_um_t result = (dk4_um_t)0UL;
+ dk4_um_t op;
+ const wchar_t *ep = NULL;
+ int found = 0;
+ int back = 0;
+ int cc = 1;
+
+
+#line 99 "dk4maiwddu.ctr"
+ if ((NULL != rp) && (NULL != src)) {
+ do {
+ op = (dk4_um_t)0UL;
+#if DK4_SIZEOF_WCHAR_T <= DK4_SIZEOF_INT
+ switch (*src) {
+ case L'0': { op = (dk4_um_t)0UL; } break;
+ case L'1': { op = (dk4_um_t)1UL; } break;
+ case L'2': { op = (dk4_um_t)2UL; } break;
+ case L'3': { op = (dk4_um_t)3UL; } break;
+ case L'4': { op = (dk4_um_t)4UL; } break;
+ case L'5': { op = (dk4_um_t)5UL; } break;
+ case L'6': { op = (dk4_um_t)6UL; } break;
+ case L'7': { op = (dk4_um_t)7UL; } break;
+ case L'8': { op = (dk4_um_t)8UL; } break;
+ case L'9': { op = (dk4_um_t)9UL; } break;
+ case L'\0': {
+
+#line 115 "dk4maiwddu.ctr"
+ cc = 0;
+ if (0 != found) {
+
+#line 117 "dk4maiwddu.ctr"
+ back = 1;
+ *rp = result;
+ } else {
+
+#line 120 "dk4maiwddu.ctr"
+ ep = src;
+
+#line 121 "dk4maiwddu.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ default: {
+ cc = 0;
+
+#line 126 "dk4maiwddu.ctr"
+ ep = src;
+
+#line 127 "dk4maiwddu.ctr"
+ if (0 != found) {
+ switch (atg) {
+ case 2: {
+
+#line 130 "dk4maiwddu.ctr"
+ back = 1;
+ *rp = result;
+ } break;
+ case 1: {
+
+#line 134 "dk4maiwddu.ctr"
+ if (NULL == dk4strw_start(src, NULL)) {
+ back = 1;
+ *rp = result;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ default: {
+
+#line 142 "dk4maiwddu.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ }
+#else
+ if (L'0' == *src) {
+ op = (dk4_um_t)0UL;
+ } else {
+ if (L'1' == *src) {
+ op = (dk4_um_t)1UL;
+ } else {
+ if (L'2' == *src) {
+ op = (dk4_um_t)2UL;
+ } else {
+ if (L'3' == *src) {
+ op = (dk4_um_t)3UL;
+ } else {
+ if (L'4' == *src) {
+ op = (dk4_um_t)4UL;
+ } else {
+ if (L'5' == *src) {
+ op = (dk4_um_t)5UL;
+ } else {
+ if (L'6' == *src) {
+ op = (dk4_um_t)6UL;
+ } else {
+ if (L'7' == *src) {
+ op = (dk4_um_t)7UL;
+ } else {
+ if (L'8' == *src) {
+ op = (dk4_um_t)8UL;
+ } else {
+ if (L'9' == *src) {
+ op = (dk4_um_t)9UL;
+ } else {
+ if (L'\0' == *src) { /* finalizer */
+ cc = 0;
+ if (0 != found) {
+ back = 1;
+ *rp = result;
+ } else {
+ ep = src;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else { /* any other */
+ cc = 0;
+ ep = src;
+ if (0 != found) {
+ switch (atg) {
+ case 2: {
+ back = 1;
+ *rp = result;
+ } break;
+ case 1: {
+ if (NULL == dk4strw_start(src, NULL)) {
+ back = 1;
+ *rp = result;
+ } else {
+ dk4error_set_simple_error_code(
+ erp, DK4_E_SYNTAX
+ );
+ }
+ } break;
+ default: {
+ dk4error_set_simple_error_code(
+ erp, DK4_E_SYNTAX
+ );
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+#endif
+ /* after switch */
+ if (0 != cc) {
+ found = 1;
+ if ((DK4_UM_MAX / (dk4_um_t)10UL) >= result) {
+ result *= (dk4_um_t)10UL;
+ if ((DK4_UM_MAX - op) >= result) {
+ result += op;
+ } else {
+ cc = 0;
+ ep = src;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ cc = 0;
+ ep = src;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ if (0 != cc) {
+ src++;
+ }
+ } while (0 != cc);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ if (NULL != src) { ep = src; }
+ }
+ if (NULL != endptr) { *endptr = ep; }
+
+
+#line 258 "dk4maiwddu.ctr"
+ return back;
+}
+
diff --git a/support/dktools/dk4maiwddu.ctr b/support/dktools/dk4maiwddu.ctr
new file mode 100644
index 0000000000..74246ef3c4
--- /dev/null
+++ b/support/dktools/dk4maiwddu.ctr
@@ -0,0 +1,260 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve dk4_um_t value from
+ wchar_t string in decimal notation.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_dec_dk4_um_t(
+ dk4_um_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+
+
+#include "dk4maiwddu.h"
+#include "dk4numco.h"
+#include "dk4strw.h"
+
+
+
+$!trace-include
+
+
+
+int
+dk4ma_input_wc_dec_dk4_um_t(
+ dk4_um_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_um_t result = (dk4_um_t)0UL;
+ dk4_um_t op;
+ const wchar_t *ep = NULL;
+ int found = 0;
+ int back = 0;
+ int cc = 1;
+ $? "+ dk4ma_input_wc_dec_dk4_um_t"
+ if ((NULL != rp) && (NULL != src)) {
+ do {
+ op = (dk4_um_t)0UL;
+#if DK4_SIZEOF_WCHAR_T <= DK4_SIZEOF_INT
+ switch (*src) {
+ case L'0': { op = (dk4_um_t)0UL; } break;
+ case L'1': { op = (dk4_um_t)1UL; } break;
+ case L'2': { op = (dk4_um_t)2UL; } break;
+ case L'3': { op = (dk4_um_t)3UL; } break;
+ case L'4': { op = (dk4_um_t)4UL; } break;
+ case L'5': { op = (dk4_um_t)5UL; } break;
+ case L'6': { op = (dk4_um_t)6UL; } break;
+ case L'7': { op = (dk4_um_t)7UL; } break;
+ case L'8': { op = (dk4_um_t)8UL; } break;
+ case L'9': { op = (dk4_um_t)9UL; } break;
+ case L'\0': { $? ". string finished"
+ cc = 0;
+ if (0 != found) { $? ". digits found"
+ back = 1;
+ *rp = result;
+ } else { $? ". no digits found"
+ ep = src; $? ". ep=%ls", TR_LSTR(ep)
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ default: {
+ cc = 0; $? "! unexpected char"
+ ep = src; $? ". ep=%ls", TR_LSTR(ep)
+ if (0 != found) {
+ switch (atg) {
+ case 2: { $? ". trailing garbage allowed"
+ back = 1;
+ *rp = result;
+ } break;
+ case 1: { $? ". trailing whitespace allowed"
+ if (NULL == dk4strw_start(src, NULL)) {
+ back = 1;
+ *rp = result;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ default: { $? ". no trailing chars allowed"
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ }
+#else
+ if (L'0' == *src) {
+ op = (dk4_um_t)0UL;
+ } else {
+ if (L'1' == *src) {
+ op = (dk4_um_t)1UL;
+ } else {
+ if (L'2' == *src) {
+ op = (dk4_um_t)2UL;
+ } else {
+ if (L'3' == *src) {
+ op = (dk4_um_t)3UL;
+ } else {
+ if (L'4' == *src) {
+ op = (dk4_um_t)4UL;
+ } else {
+ if (L'5' == *src) {
+ op = (dk4_um_t)5UL;
+ } else {
+ if (L'6' == *src) {
+ op = (dk4_um_t)6UL;
+ } else {
+ if (L'7' == *src) {
+ op = (dk4_um_t)7UL;
+ } else {
+ if (L'8' == *src) {
+ op = (dk4_um_t)8UL;
+ } else {
+ if (L'9' == *src) {
+ op = (dk4_um_t)9UL;
+ } else {
+ if (L'\0' == *src) { /* finalizer */
+ cc = 0;
+ if (0 != found) {
+ back = 1;
+ *rp = result;
+ } else {
+ ep = src;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else { /* any other */
+ cc = 0;
+ ep = src;
+ if (0 != found) {
+ switch (atg) {
+ case 2: {
+ back = 1;
+ *rp = result;
+ } break;
+ case 1: {
+ if (NULL == dk4strw_start(src, NULL)) {
+ back = 1;
+ *rp = result;
+ } else {
+ dk4error_set_simple_error_code(
+ erp, DK4_E_SYNTAX
+ );
+ }
+ } break;
+ default: {
+ dk4error_set_simple_error_code(
+ erp, DK4_E_SYNTAX
+ );
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+#endif
+ /* after switch */
+ if (0 != cc) {
+ found = 1;
+ if ((DK4_UM_MAX / (dk4_um_t)10UL) >= result) {
+ result *= (dk4_um_t)10UL;
+ if ((DK4_UM_MAX - op) >= result) {
+ result += op;
+ } else {
+ cc = 0;
+ ep = src;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ cc = 0;
+ ep = src;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ if (0 != cc) {
+ src++;
+ }
+ } while (0 != cc);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ if (NULL != src) { ep = src; }
+ }
+ if (NULL != endptr) { *endptr = ep; }
+ $? "- dk4ma_input_wc_dec_dk4_um_t %d", back
+ return back;
+}
+
diff --git a/support/dktools/dk4maiwddu.h b/support/dktools/dk4maiwddu.h
new file mode 100644
index 0000000000..1634676ccd
--- /dev/null
+++ b/support/dktools/dk4maiwddu.h
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwddu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIWDDU_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIWDDU_H_INCLUDED 1
+
+
+#line 10 "dk4maiwddu.ctr"
+
+/** @file
+ Retrieve dk4_um_t value from
+ wchar_t string in decimal notation.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_dec_dk4_um_t(
+ dk4_um_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maiwdic.c b/support/dktools/dk4maiwdic.c
new file mode 100644
index 0000000000..f16f192be0
--- /dev/null
+++ b/support/dktools/dk4maiwdic.c
@@ -0,0 +1,70 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwdic.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiwdic.c The dk4maiwdic module.
+*/
+
+
+#line 70 "dk4maiwdic.ctr"
+
+#include "dk4maiwdic.h"
+#include "dk4maiwddi.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_dec_char(
+ signed char *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_dec_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(CHAR_MIN) <= res) && ((dk4_im_t)(CHAR_MAX) >= res)) {
+ *rp = (signed char)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4maiwdic.ctr b/support/dktools/dk4maiwdic.ctr
new file mode 100644
index 0000000000..f4a600ef9f
--- /dev/null
+++ b/support/dktools/dk4maiwdic.ctr
@@ -0,0 +1,99 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ Retrieve signed char value from
+ wchar_t string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_dec_char(
+ signed char *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4maiwdic.h"
+#include "dk4maiwddi.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_dec_char(
+ signed char *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_dec_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(CHAR_MIN) <= res) && ((dk4_im_t)(CHAR_MAX) >= res)) {
+ *rp = (signed char)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4maiwdic.h b/support/dktools/dk4maiwdic.h
new file mode 100644
index 0000000000..d1b428da46
--- /dev/null
+++ b/support/dktools/dk4maiwdic.h
@@ -0,0 +1,103 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwdic.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIWDIC_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIWDIC_H_INCLUDED 1
+
+
+#line 9 "dk4maiwdic.ctr"
+
+/** @file
+ Retrieve signed char value from
+ wchar_t string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_dec_char(
+ signed char *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4maiwdii.c b/support/dktools/dk4maiwdii.c
new file mode 100644
index 0000000000..47b52d1333
--- /dev/null
+++ b/support/dktools/dk4maiwdii.c
@@ -0,0 +1,69 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwdii.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiwdii.c The dk4maiwdii module.
+*/
+
+
+#line 70 "dk4maiwdii.ctr"
+
+#include "dk4maiwddi.h"
+#include "dk4maiwdii.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_dec_int(
+ int *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_dec_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(INT_MIN) <= res) && (((dk4_im_t)(INT_MAX)) >= res)) {
+ *rp = (int)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4maiwdii.ctr b/support/dktools/dk4maiwdii.ctr
new file mode 100644
index 0000000000..3ba8789194
--- /dev/null
+++ b/support/dktools/dk4maiwdii.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve int value from
+ wchar_t string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_dec_int(
+ int *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4maiwddi.h"
+#include "dk4maiwdii.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_dec_int(
+ int *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_dec_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(INT_MIN) <= res) && (((dk4_im_t)(INT_MAX)) >= res)) {
+ *rp = (int)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4maiwdii.h b/support/dktools/dk4maiwdii.h
new file mode 100644
index 0000000000..a05f9ed124
--- /dev/null
+++ b/support/dktools/dk4maiwdii.h
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwdii.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIWDII_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIWDII_H_INCLUDED 1
+
+
+#line 10 "dk4maiwdii.ctr"
+
+/** @file
+ Retrieve int value from
+ wchar_t string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_dec_int(
+ int *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4maiwdil.c b/support/dktools/dk4maiwdil.c
new file mode 100644
index 0000000000..1f3a0a5ad2
--- /dev/null
+++ b/support/dktools/dk4maiwdil.c
@@ -0,0 +1,73 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwdil.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiwdil.c The dk4maiwdil module.
+*/
+
+
+#line 70 "dk4maiwdil.ctr"
+
+#include "dk4maiwddi.h"
+#include "dk4maiwdil.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_dec_long(
+ long *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_INTMAX_T || DK4_HAVE_LONG_LONG
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_dec_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(LONG_MIN) <= res) && (((dk4_im_t)(LONG_MAX)) >= res)) {
+ *rp = (long)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+#else
+ return (dk4ma_input_wc_dec_dk4_im_t(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maiwdil.ctr b/support/dktools/dk4maiwdil.ctr
new file mode 100644
index 0000000000..4612141090
--- /dev/null
+++ b/support/dktools/dk4maiwdil.ctr
@@ -0,0 +1,102 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve long value from
+ wchar_t string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_dec_long(
+ long *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4maiwddi.h"
+#include "dk4maiwdil.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_dec_long(
+ long *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_INTMAX_T || DK4_HAVE_LONG_LONG
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_dec_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(LONG_MIN) <= res) && (((dk4_im_t)(LONG_MAX)) >= res)) {
+ *rp = (long)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+#else
+ return (dk4ma_input_wc_dec_dk4_im_t(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maiwdil.h b/support/dktools/dk4maiwdil.h
new file mode 100644
index 0000000000..9978b6e4b2
--- /dev/null
+++ b/support/dktools/dk4maiwdil.h
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwdil.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIWDIL_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIWDIL_H_INCLUDED 1
+
+
+#line 10 "dk4maiwdil.ctr"
+
+/** @file
+ Retrieve long value from
+ wchar_t string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_dec_long(
+ long *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4maiwdis.c b/support/dktools/dk4maiwdis.c
new file mode 100644
index 0000000000..4f563d9ebc
--- /dev/null
+++ b/support/dktools/dk4maiwdis.c
@@ -0,0 +1,69 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwdis.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiwdis.c The dk4maiwdis module.
+*/
+
+
+#line 70 "dk4maiwdis.ctr"
+
+#include "dk4maiwddi.h"
+#include "dk4maiwdis.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_dec_short(
+ short *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_dec_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(SHRT_MIN) <= res) && (((dk4_im_t)(SHRT_MAX)) >= res)) {
+ *rp = (short)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4maiwdis.ctr b/support/dktools/dk4maiwdis.ctr
new file mode 100644
index 0000000000..63ba351479
--- /dev/null
+++ b/support/dktools/dk4maiwdis.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve short int value from
+ wchar_t string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_dec_short(
+ short *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4maiwddi.h"
+#include "dk4maiwdis.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_dec_short(
+ short *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_dec_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(SHRT_MIN) <= res) && (((dk4_im_t)(SHRT_MAX)) >= res)) {
+ *rp = (short)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4maiwdis.h b/support/dktools/dk4maiwdis.h
new file mode 100644
index 0000000000..b6ace41a4c
--- /dev/null
+++ b/support/dktools/dk4maiwdis.h
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwdis.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIWDIS_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIWDIS_H_INCLUDED 1
+
+
+#line 10 "dk4maiwdis.ctr"
+
+/** @file
+ Retrieve short int value from
+ wchar_t string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_dec_short(
+ short *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4maiwdli.c b/support/dktools/dk4maiwdli.c
new file mode 100644
index 0000000000..9a10ae5594
--- /dev/null
+++ b/support/dktools/dk4maiwdli.c
@@ -0,0 +1,79 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwdli.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiwdli.c The dk4maiwdli module.
+*/
+
+
+#line 74 "dk4maiwdli.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_LONG_LONG
+
+#include "dk4maiwddi.h"
+#include "dk4maiwdli.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_dec_ll(
+ long long *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_INTMAX_T
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_dec_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(LLONG_MIN) <= res) && (((dk4_im_t)(LLONG_MAX)) >= res)) {
+ *rp = (long long)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+#else
+ return (dk4ma_input_wc_dec_dk4_im_t(rp, src, endptr, atg, erp));
+#endif
+}
+
+#endif
+
diff --git a/support/dktools/dk4maiwdli.ctr b/support/dktools/dk4maiwdli.ctr
new file mode 100644
index 0000000000..655253c970
--- /dev/null
+++ b/support/dktools/dk4maiwdli.ctr
@@ -0,0 +1,112 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve long long value from
+ wchar_t string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_LONG_LONG
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_dec_ll(
+ long long *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_LONG_LONG
+
+#include "dk4maiwddi.h"
+#include "dk4maiwdli.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_dec_ll(
+ long long *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_INTMAX_T
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_dec_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(LLONG_MIN) <= res) && (((dk4_im_t)(LLONG_MAX)) >= res)) {
+ *rp = (long long)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+#else
+ return (dk4ma_input_wc_dec_dk4_im_t(rp, src, endptr, atg, erp));
+#endif
+}
+
+#endif
+
diff --git a/support/dktools/dk4maiwdli.h b/support/dktools/dk4maiwdli.h
new file mode 100644
index 0000000000..e600695536
--- /dev/null
+++ b/support/dktools/dk4maiwdli.h
@@ -0,0 +1,106 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwdli.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIWDLI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIWDLI_H_INCLUDED 1
+
+
+#line 10 "dk4maiwdli.ctr"
+
+/** @file
+ Retrieve long long value from
+ wchar_t string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_LONG_LONG
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_dec_ll(
+ long long *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4maiwdlu.c b/support/dktools/dk4maiwdlu.c
new file mode 100644
index 0000000000..53988a3b63
--- /dev/null
+++ b/support/dktools/dk4maiwdlu.c
@@ -0,0 +1,79 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwdlu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiwdlu.c The dk4maiwdlu module.
+*/
+
+
+#line 74 "dk4maiwdlu.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_LONG_LONG
+
+#include "dk4maiwddu.h"
+#include "dk4maiwdlu.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_dec_ull(
+ unsigned long long *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_INTMAX_T
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_dec_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(ULLONG_MAX)) >= res) {
+ *rp = (unsigned long long)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+#else
+ return (dk4ma_input_wc_dec_dk4_um_t(rp, src, endptr, atg, erp));
+#endif
+}
+
+#endif
+
diff --git a/support/dktools/dk4maiwdlu.ctr b/support/dktools/dk4maiwdlu.ctr
new file mode 100644
index 0000000000..b307bea4e6
--- /dev/null
+++ b/support/dktools/dk4maiwdlu.ctr
@@ -0,0 +1,112 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve unsigned long long value from
+ wchar_t string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_LONG_LONG
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_dec_ull(
+ unsigned long long *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_LONG_LONG
+
+#include "dk4maiwddu.h"
+#include "dk4maiwdlu.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_dec_ull(
+ unsigned long long *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_INTMAX_T
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_dec_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(ULLONG_MAX)) >= res) {
+ *rp = (unsigned long long)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+#else
+ return (dk4ma_input_wc_dec_dk4_um_t(rp, src, endptr, atg, erp));
+#endif
+}
+
+#endif
+
diff --git a/support/dktools/dk4maiwdlu.h b/support/dktools/dk4maiwdlu.h
new file mode 100644
index 0000000000..6c63a73e2c
--- /dev/null
+++ b/support/dktools/dk4maiwdlu.h
@@ -0,0 +1,106 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwdlu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIWDLU_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIWDLU_H_INCLUDED 1
+
+
+#line 10 "dk4maiwdlu.ctr"
+
+/** @file
+ Retrieve unsigned long long value from
+ wchar_t string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_LONG_LONG
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_dec_ull(
+ unsigned long long *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4maiwdmi.c b/support/dktools/dk4maiwdmi.c
new file mode 100644
index 0000000000..de83a98c7a
--- /dev/null
+++ b/support/dktools/dk4maiwdmi.c
@@ -0,0 +1,66 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwdmi.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiwdmi.c The dk4maiwdmi module.
+*/
+
+
+#line 75 "dk4maiwdmi.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#pragma warning (disable:4206)
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#include "dk4maiwddi.h"
+#include "dk4maiwdmu.h"
+
+int
+dk4ma_input_wc_dec_intmax_t(
+ intmax_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ return (dk4ma_input_wc_dec_dk4_im_t(rp, src, endptr, atg, erp));
+}
+
+#endif
+
diff --git a/support/dktools/dk4maiwdmi.ctr b/support/dktools/dk4maiwdmi.ctr
new file mode 100644
index 0000000000..a6de7688db
--- /dev/null
+++ b/support/dktools/dk4maiwdmi.ctr
@@ -0,0 +1,100 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve intmax_t value from
+ wchar_t string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_dec_intmax_t(
+ intmax_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#pragma warning (disable:4206)
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#include "dk4maiwddi.h"
+#include "dk4maiwdmu.h"
+
+int
+dk4ma_input_wc_dec_intmax_t(
+ intmax_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ return (dk4ma_input_wc_dec_dk4_im_t(rp, src, endptr, atg, erp));
+}
+
+#endif
+
diff --git a/support/dktools/dk4maiwdmi.h b/support/dktools/dk4maiwdmi.h
new file mode 100644
index 0000000000..9fbea4f5f5
--- /dev/null
+++ b/support/dktools/dk4maiwdmi.h
@@ -0,0 +1,107 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwdmi.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIWDMI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIWDMI_H_INCLUDED 1
+
+
+#line 10 "dk4maiwdmi.ctr"
+
+/** @file
+ Retrieve intmax_t value from
+ wchar_t string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_dec_intmax_t(
+ intmax_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4maiwdmu.c b/support/dktools/dk4maiwdmu.c
new file mode 100644
index 0000000000..3622c65f19
--- /dev/null
+++ b/support/dktools/dk4maiwdmu.c
@@ -0,0 +1,66 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwdmu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiwdmu.c The dk4maiwdmu module.
+*/
+
+
+#line 75 "dk4maiwdmu.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#pragma warning (disable:4206)
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#include "dk4maiwddu.h"
+#include "dk4maiwdmu.h"
+
+int
+dk4ma_input_wc_dec_uintmax_t(
+ uintmax_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ return (dk4ma_input_wc_dec_dk4_um_t(rp, src, endptr, atg, erp));
+}
+
+#endif
+
diff --git a/support/dktools/dk4maiwdmu.ctr b/support/dktools/dk4maiwdmu.ctr
new file mode 100644
index 0000000000..9c5747cf78
--- /dev/null
+++ b/support/dktools/dk4maiwdmu.ctr
@@ -0,0 +1,100 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve uintmax_t value from
+ wchar_t string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_dec_uintmax_t(
+ uintmax_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#pragma warning (disable:4206)
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#include "dk4maiwddu.h"
+#include "dk4maiwdmu.h"
+
+int
+dk4ma_input_wc_dec_uintmax_t(
+ uintmax_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ return (dk4ma_input_wc_dec_dk4_um_t(rp, src, endptr, atg, erp));
+}
+
+#endif
+
diff --git a/support/dktools/dk4maiwdmu.h b/support/dktools/dk4maiwdmu.h
new file mode 100644
index 0000000000..411832a569
--- /dev/null
+++ b/support/dktools/dk4maiwdmu.h
@@ -0,0 +1,107 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwdmu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIWDMU_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIWDMU_H_INCLUDED 1
+
+
+#line 10 "dk4maiwdmu.ctr"
+
+/** @file
+ Retrieve uintmax_t value from
+ wchar_t string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_dec_uintmax_t(
+ uintmax_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4maiwdsz.c b/support/dktools/dk4maiwdsz.c
new file mode 100644
index 0000000000..13bec9b5fb
--- /dev/null
+++ b/support/dktools/dk4maiwdsz.c
@@ -0,0 +1,153 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwdsz.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiwdsz.c The dk4maiwdsz module.
+*/
+
+
+#line 70 "dk4maiwdsz.ctr"
+
+#include "dk4maiwddu.h"
+#include "dk4maiwdui.h"
+#include "dk4numco.h"
+#include "dk4strw.h"
+
+
+
+#if 0
+int
+dk4ma_input_wc_dec_size_t(
+ size_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_dec_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(SIZE_MAX)) >= res) {
+ *rp = (size_t)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+#endif
+
+
+
+int
+dk4ma_input_wc_dec_size_t(
+ size_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ const wchar_t *myend = NULL;
+ dk4_um_t um = (dk4_um_t)0UL;
+ size_t res = 0;
+ size_t factor = 1;
+ size_t nloop = 0;
+ int back = 0;
+
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk4ma_input_wc_dec_dk4_um_t(&um, src, &myend, 2, erp)) {
+ if (((dk4_um_t)(SIZE_MAX)) >= um) {
+ res = (size_t)um;
+ if (NULL != myend) {
+ back = 1;
+ switch (*myend) {
+ case 'k': case 'K': { nloop = 1; myend++; } break;
+ case 'm': case 'M': { nloop = 2; myend++; } break;
+ case 'g': case 'G': { nloop = 3; myend++; } break;
+ case 't': case 'T': { nloop = 4; myend++; } break;
+ }
+ while (nloop--) {
+ if ((SIZE_MAX / 1024) >= factor) {
+ factor *= 1024;
+ } else {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ if (0 != back) {
+ if ((SIZE_MAX / factor) >= res) {
+ res *= factor;
+ switch (atg) {
+ case 2: {
+ *rp = res;
+ } break;
+ case 1: {
+ myend = dk4strw_start(myend, NULL);
+ if (NULL != myend) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } else {
+ *rp = res;
+ }
+ } break;
+ default: {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ *rp = res;
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ if (NULL != endptr) { *endptr = myend; }
+ return back;
+}
+
diff --git a/support/dktools/dk4maiwdsz.ctr b/support/dktools/dk4maiwdsz.ctr
new file mode 100644
index 0000000000..5a70963f03
--- /dev/null
+++ b/support/dktools/dk4maiwdsz.ctr
@@ -0,0 +1,182 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve size_t value from
+ wchar_t string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_dec_size_t(
+ size_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4maiwddu.h"
+#include "dk4maiwdui.h"
+#include "dk4numco.h"
+#include "dk4strw.h"
+
+
+
+#if 0
+int
+dk4ma_input_wc_dec_size_t(
+ size_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_dec_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(SIZE_MAX)) >= res) {
+ *rp = (size_t)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+#endif
+
+
+
+int
+dk4ma_input_wc_dec_size_t(
+ size_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ const wchar_t *myend = NULL;
+ dk4_um_t um = (dk4_um_t)0UL;
+ size_t res = 0;
+ size_t factor = 1;
+ size_t nloop = 0;
+ int back = 0;
+
+ if ((NULL != rp) && (NULL != src)) {
+ if (0 != dk4ma_input_wc_dec_dk4_um_t(&um, src, &myend, 2, erp)) {
+ if (((dk4_um_t)(SIZE_MAX)) >= um) {
+ res = (size_t)um;
+ if (NULL != myend) {
+ back = 1;
+ switch (*myend) {
+ case 'k': case 'K': { nloop = 1; myend++; } break;
+ case 'm': case 'M': { nloop = 2; myend++; } break;
+ case 'g': case 'G': { nloop = 3; myend++; } break;
+ case 't': case 'T': { nloop = 4; myend++; } break;
+ }
+ while (nloop--) {
+ if ((SIZE_MAX / 1024) >= factor) {
+ factor *= 1024;
+ } else {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ if (0 != back) {
+ if ((SIZE_MAX / factor) >= res) {
+ res *= factor;
+ switch (atg) {
+ case 2: {
+ *rp = res;
+ } break;
+ case 1: {
+ myend = dk4strw_start(myend, NULL);
+ if (NULL != myend) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } else {
+ *rp = res;
+ }
+ } break;
+ default: {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ *rp = res;
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ if (NULL != endptr) { *endptr = myend; }
+ return back;
+}
+
diff --git a/support/dktools/dk4maiwdsz.h b/support/dktools/dk4maiwdsz.h
new file mode 100644
index 0000000000..ccf595ccc3
--- /dev/null
+++ b/support/dktools/dk4maiwdsz.h
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwdsz.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIWDSZ_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIWDSZ_H_INCLUDED 1
+
+
+#line 10 "dk4maiwdsz.ctr"
+
+/** @file
+ Retrieve size_t value from
+ wchar_t string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_dec_size_t(
+ size_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4maiwduc.c b/support/dktools/dk4maiwduc.c
new file mode 100644
index 0000000000..4a68ca23ef
--- /dev/null
+++ b/support/dktools/dk4maiwduc.c
@@ -0,0 +1,71 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwduc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiwduc.c The dk4maiwduc module.
+*/
+
+
+#line 71 "dk4maiwduc.ctr"
+
+#include "dk4maiwduc.h"
+#include "dk4maiwddu.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_dec_uchar(
+ unsigned char *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_um_t res;
+ int back = 0;
+
+ if (0 != dk4ma_input_wc_dec_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(UCHAR_MAX)) >= res) {
+ *rp = (unsigned char)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4maiwduc.ctr b/support/dktools/dk4maiwduc.ctr
new file mode 100644
index 0000000000..cd2e0803d9
--- /dev/null
+++ b/support/dktools/dk4maiwduc.ctr
@@ -0,0 +1,101 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve unsigned char value from
+ wchar_t string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_dec_uchar(
+ unsigned char *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4maiwduc.h"
+#include "dk4maiwddu.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_dec_uchar(
+ unsigned char *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_um_t res;
+ int back = 0;
+
+ if (0 != dk4ma_input_wc_dec_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(UCHAR_MAX)) >= res) {
+ *rp = (unsigned char)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4maiwduc.h b/support/dktools/dk4maiwduc.h
new file mode 100644
index 0000000000..fd237e07cf
--- /dev/null
+++ b/support/dktools/dk4maiwduc.h
@@ -0,0 +1,103 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwduc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIWDUC_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIWDUC_H_INCLUDED 1
+
+
+#line 10 "dk4maiwduc.ctr"
+
+/** @file
+ Retrieve unsigned char value from
+ wchar_t string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_dec_uchar(
+ unsigned char *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4maiwdui.c b/support/dktools/dk4maiwdui.c
new file mode 100644
index 0000000000..68cca40e8a
--- /dev/null
+++ b/support/dktools/dk4maiwdui.c
@@ -0,0 +1,69 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwdui.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiwdui.c The dk4maiwdui module.
+*/
+
+
+#line 70 "dk4maiwdui.ctr"
+
+#include "dk4maiwddu.h"
+#include "dk4maiwdui.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_dec_uint(
+ unsigned *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_dec_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(UINT_MAX)) >= res) {
+ *rp = (unsigned)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4maiwdui.ctr b/support/dktools/dk4maiwdui.ctr
new file mode 100644
index 0000000000..bcfd84960c
--- /dev/null
+++ b/support/dktools/dk4maiwdui.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve unsigned int value from
+ wchar_t string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_dec_uint(
+ unsigned *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4maiwddu.h"
+#include "dk4maiwdui.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_dec_uint(
+ unsigned *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_dec_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(UINT_MAX)) >= res) {
+ *rp = (unsigned)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4maiwdui.h b/support/dktools/dk4maiwdui.h
new file mode 100644
index 0000000000..142d91030a
--- /dev/null
+++ b/support/dktools/dk4maiwdui.h
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwdui.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIWDUI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIWDUI_H_INCLUDED 1
+
+
+#line 10 "dk4maiwdui.ctr"
+
+/** @file
+ Retrieve unsigned int value from
+ wchar_t string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_dec_uint(
+ unsigned *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4maiwdul.c b/support/dktools/dk4maiwdul.c
new file mode 100644
index 0000000000..f16ee0f715
--- /dev/null
+++ b/support/dktools/dk4maiwdul.c
@@ -0,0 +1,73 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwdul.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiwdul.c The dk4maiwdul module.
+*/
+
+
+#line 70 "dk4maiwdul.ctr"
+
+#include "dk4maiwddu.h"
+#include "dk4maiwdul.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_dec_ulong(
+ unsigned long *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_INTMAX_T || DK4_HAVE_LONG_LONG
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_dec_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(ULONG_MAX)) >= res) {
+ *rp = (unsigned long)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+#else
+ return (dk4ma_input_wc_dec_dk4_um_t(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maiwdul.ctr b/support/dktools/dk4maiwdul.ctr
new file mode 100644
index 0000000000..6b222f11af
--- /dev/null
+++ b/support/dktools/dk4maiwdul.ctr
@@ -0,0 +1,102 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve unsigned long value from
+ wchar_t string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_dec_ulong(
+ unsigned long *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4maiwddu.h"
+#include "dk4maiwdul.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_dec_ulong(
+ unsigned long *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_INTMAX_T || DK4_HAVE_LONG_LONG
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_dec_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(ULONG_MAX)) >= res) {
+ *rp = (unsigned long)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+#else
+ return (dk4ma_input_wc_dec_dk4_um_t(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maiwdul.h b/support/dktools/dk4maiwdul.h
new file mode 100644
index 0000000000..847c75ef11
--- /dev/null
+++ b/support/dktools/dk4maiwdul.h
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwdul.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIWDUL_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIWDUL_H_INCLUDED 1
+
+
+#line 10 "dk4maiwdul.ctr"
+
+/** @file
+ Retrieve unsigned long value from
+ wchar_t string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_dec_ulong(
+ unsigned long *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4maiwdus.c b/support/dktools/dk4maiwdus.c
new file mode 100644
index 0000000000..3cbd96552e
--- /dev/null
+++ b/support/dktools/dk4maiwdus.c
@@ -0,0 +1,69 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwdus.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiwdus.c The dk4maiwdus module.
+*/
+
+
+#line 70 "dk4maiwdus.ctr"
+
+#include "dk4maiwddu.h"
+#include "dk4maiwdus.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_dec_ushort(
+ unsigned short *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_dec_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(USHRT_MAX)) >= res) {
+ *rp = (unsigned short)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4maiwdus.ctr b/support/dktools/dk4maiwdus.ctr
new file mode 100644
index 0000000000..e3cd64c7b6
--- /dev/null
+++ b/support/dktools/dk4maiwdus.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve unsigned short value from
+ wchar_t string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_dec_ushort(
+ unsigned short *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4maiwddu.h"
+#include "dk4maiwdus.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_dec_ushort(
+ unsigned short *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_dec_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(USHRT_MAX)) >= res) {
+ *rp = (unsigned short)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4maiwdus.h b/support/dktools/dk4maiwdus.h
new file mode 100644
index 0000000000..7300371811
--- /dev/null
+++ b/support/dktools/dk4maiwdus.h
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwdus.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIWDUS_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIWDUS_H_INCLUDED 1
+
+
+#line 10 "dk4maiwdus.ctr"
+
+/** @file
+ Retrieve unsigned short value from
+ wchar_t string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_dec_ushort(
+ unsigned short *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4maiwhdi.c b/support/dktools/dk4maiwhdi.c
new file mode 100644
index 0000000000..eeb4b56df3
--- /dev/null
+++ b/support/dktools/dk4maiwhdi.c
@@ -0,0 +1,115 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwhdi.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiwhdi.c The dk4maiwhdi module.
+*/
+
+
+#line 72 "dk4maiwhdi.ctr"
+
+#include "dk4maiwhdu.h"
+#include "dk4maiwhdi.h"
+#include "dk4numco.h"
+#include "dk4str8.h"
+
+
+
+
+#line 80 "dk4maiwhdi.ctr"
+
+
+
+int
+dk4ma_input_wc_hex_dk4_im_t(
+ dk4_im_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_um_t res;
+ const wchar_t *ep = NULL;
+ int back = 0;
+
+
+#line 96 "dk4maiwhdi.ctr"
+ if ((NULL != rp) && (NULL != src)) {
+ if (L'-' == *src) {
+
+#line 98 "dk4maiwhdi.ctr"
+ if (0 != dk4ma_input_wc_hex_dk4_um_t(&res, ++src, &ep, atg, erp)) {
+ if (((dk4_um_t)(DK4_IM_MAX) + (dk4_um_t)1UL) == res) {
+
+#line 100 "dk4maiwhdi.ctr"
+ *rp = DK4_IM_MIN;
+ back = 1;
+ } else {
+ if (((dk4_um_t)(DK4_IM_MAX)) >= res) {
+
+#line 104 "dk4maiwhdi.ctr"
+ *rp = (dk4_im_t)0L - (dk4_im_t)res;
+ back = 1;
+ } else {
+
+#line 107 "dk4maiwhdi.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ } else {
+
+#line 111 "dk4maiwhdi.ctr"
+ }
+ } else {
+
+#line 113 "dk4maiwhdi.ctr"
+ if (0 != dk4ma_input_wc_hex_dk4_um_t(&res, src, &ep, atg, erp)) {
+ *rp = (dk4_im_t)res;
+ back = 1;
+ } else {
+
+#line 117 "dk4maiwhdi.ctr"
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ if (NULL != endptr) { *endptr = ep; }
+
+
+#line 124 "dk4maiwhdi.ctr"
+ return back;
+}
+
diff --git a/support/dktools/dk4maiwhdi.ctr b/support/dktools/dk4maiwhdi.ctr
new file mode 100644
index 0000000000..14d07a1a53
--- /dev/null
+++ b/support/dktools/dk4maiwhdi.ctr
@@ -0,0 +1,126 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve dk4_im_t value from
+ wchar_t string in hexadecimal notation.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_hex_dk4_im_t(
+ dk4_im_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4maiwhdu.h"
+#include "dk4maiwhdi.h"
+#include "dk4numco.h"
+#include "dk4str8.h"
+
+
+$!trace-include
+
+
+
+int
+dk4ma_input_wc_hex_dk4_im_t(
+ dk4_im_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_um_t res;
+ const wchar_t *ep = NULL;
+ int back = 0;
+ $? "+ dk4ma_input_wc_hex_dk4_im_t \"%ls\" %d", src, atg
+ if ((NULL != rp) && (NULL != src)) {
+ if (L'-' == *src) { $? ". negative"
+ if (0 != dk4ma_input_wc_hex_dk4_um_t(&res, ++src, &ep, atg, erp)) {
+ if (((dk4_um_t)(DK4_IM_MAX) + (dk4_um_t)1UL) == res) { $? ". ok min"
+ *rp = DK4_IM_MIN;
+ back = 1;
+ } else {
+ if (((dk4_um_t)(DK4_IM_MAX)) >= res) { $? ". ok neg"
+ *rp = (dk4_im_t)0L - (dk4_im_t)res;
+ back = 1;
+ } else { $? "! overflow"
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ } else { $? "! failed"
+ }
+ } else { $? ". not negative"
+ if (0 != dk4ma_input_wc_hex_dk4_um_t(&res, src, &ep, atg, erp)) {
+ *rp = (dk4_im_t)res;
+ back = 1;
+ } else { $? "! failed"
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ if (NULL != endptr) { *endptr = ep; }
+ $? "- dk4ma_input_wc_hex_dk4_im_t %d", back
+ return back;
+}
+
diff --git a/support/dktools/dk4maiwhdi.h b/support/dktools/dk4maiwhdi.h
new file mode 100644
index 0000000000..c9ab793be8
--- /dev/null
+++ b/support/dktools/dk4maiwhdi.h
@@ -0,0 +1,104 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwhdi.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIWHDI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIWHDI_H_INCLUDED 1
+
+
+#line 10 "dk4maiwhdi.ctr"
+
+/** @file
+ Retrieve dk4_im_t value from
+ wchar_t string in hexadecimal notation.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_hex_dk4_im_t(
+ dk4_im_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maiwhdu.c b/support/dktools/dk4maiwhdu.c
new file mode 100644
index 0000000000..6dfc171ecc
--- /dev/null
+++ b/support/dktools/dk4maiwhdu.c
@@ -0,0 +1,281 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwhdu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiwhdu.c The dk4maiwhdu module.
+*/
+
+
+#line 70 "dk4maiwhdu.ctr"
+
+
+
+#include "dk4maiwhdu.h"
+#include "dk4numco.h"
+#include "dk4strw.h"
+
+
+
+
+
+#line 80 "dk4maiwhdu.ctr"
+
+
+
+/* UNTESTED */
+int
+dk4ma_input_wc_hex_dk4_um_t(
+ dk4_um_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_um_t result = (dk4_um_t)0UL;
+ dk4_um_t op;
+ const wchar_t *ep = NULL;
+ int found = 0;
+ int back = 0;
+ int cc = 1;
+
+
+#line 100 "dk4maiwhdu.ctr"
+ if ((NULL != rp) && (NULL != src)) {
+ if (L'0' == src[0]) {
+ if ((L'x' == src[1]) || (L'X' == src[1])) { src++; src++; }
+ }
+ do {
+ op = (dk4_um_t)0UL;
+#if DK4_SIZEOF_WCHAR_T <= DK4_SIZEOF_INT
+ switch (*src) {
+ case L'0': { op = (dk4_um_t)0UL; } break;
+ case L'1': { op = (dk4_um_t)1UL; } break;
+ case L'2': { op = (dk4_um_t)2UL; } break;
+ case L'3': { op = (dk4_um_t)3UL; } break;
+ case L'4': { op = (dk4_um_t)4UL; } break;
+ case L'5': { op = (dk4_um_t)5UL; } break;
+ case L'6': { op = (dk4_um_t)6UL; } break;
+ case L'7': { op = (dk4_um_t)7UL; } break;
+ case L'8': { op = (dk4_um_t)8UL; } break;
+ case L'9': { op = (dk4_um_t)9UL; } break;
+ case L'a': case L'A': { op = (dk4_um_t)10UL; } break;
+ case L'b': case L'B': { op = (dk4_um_t)11UL; } break;
+ case L'c': case L'C': { op = (dk4_um_t)12UL; } break;
+ case L'd': case L'D': { op = (dk4_um_t)13UL; } break;
+ case L'e': case L'E': { op = (dk4_um_t)14UL; } break;
+ case L'f': case L'F': { op = (dk4_um_t)15UL; } break;
+ case L'\0': {
+
+#line 125 "dk4maiwhdu.ctr"
+ cc = 0;
+ if (0 != found) {
+
+#line 127 "dk4maiwhdu.ctr"
+ back = 1;
+ *rp = result;
+ } else {
+
+#line 130 "dk4maiwhdu.ctr"
+ ep = src;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ default: {
+ cc = 0;
+ ep = src;
+ if (0 != found) {
+ switch (atg) {
+ case 2: {
+ back = 1;
+ *rp = result;
+ } break;
+ case 1: {
+ if (NULL == dk4strw_start(src, NULL)) {
+ back = 1;
+ *rp = result;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ default: {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ }
+#else
+ if (L'0' == *src) {
+ op = (dk4_um_t)0UL;
+ } else {
+ if (L'1' == *src) {
+ op = (dk4_um_t)1UL;
+ } else {
+ if (L'2' == *src) {
+ op = (dk4_um_t)2UL;
+ } else {
+ if (L'3' == *src) {
+ op = (dk4_um_t)3UL;
+ } else {
+ if (L'4' == *src) {
+ op = (dk4_um_t)4UL;
+ } else {
+ if (L'5' == *src) {
+ op = (dk4_um_t)5UL;
+ } else {
+ if (L'6' == *src) {
+ op = (dk4_um_t)6UL;
+ } else {
+ if (L'7' == *src) {
+ op = (dk4_um_t)7UL;
+ } else {
+ if (L'8' == *src) {
+ op = (dk4_um_t)8UL;
+ } else {
+ if (L'9' == *src) {
+ op = (dk4_um_t)9UL;
+ } else {
+ if ((L'A' == *src) || (L'a' == *src)) {
+ op = (dk4_um_t)10UL;
+ } else {
+ if ((L'B' == *src) || (L'b' == *src)) {
+ op = (dk4_um_t)11UL;
+ } else {
+ if ((L'C' == *src) || (L'c' == *src)) {
+ op = (dk4_um_t)12UL;
+ } else {
+ if ((L'D' == *src) || (L'd' == *src)) {
+ op = (dk4_um_t)13UL;
+ } else {
+ if ((L'E' == *src) || (L'e' == *src)) {
+ op = (dk4_um_t)14UL;
+ } else {
+ if ((L'F' == *src) || (L'f' == *src)) {
+ op = (dk4_um_t)15UL;
+ } else {
+ if (L'\0' == *src) { /* finalizer */
+ cc = 0;
+ if (0 != found) {
+ back = 1;
+ *rp = result;
+ } else {
+ ep = src;
+ dk4error_set_simple_error_code(
+ erp, DK4_E_SYNTAX
+ );
+ }
+ } else { /* any other */
+ cc = 0;
+ ep = src;
+ if (0 != found) {
+ switch (atg) {
+ case 2: {
+ back = 1;
+ *rp = result;
+ } break;
+ case 1: {
+ if (dk4strw_start(src, NULL)) {
+ dk4error_set_simple_error_code(
+ erp, DK4_E_SYNTAX
+ );
+ } else {
+ back = 1;
+ *rp = result;
+ }
+ } break;
+ default: {
+ dk4error_set_simple_error_code(
+ erp, DK4_E_SYNTAX
+ );
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(
+ erp, DK4_E_SYNTAX
+ );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+#endif
+ /* after switch */
+ if (0 != cc) {
+ found = 1;
+ if ((DK4_UM_MAX / (dk4_um_t)16UL) >= result) {
+ result *= (dk4_um_t)16UL;
+ if ((DK4_UM_MAX - op) >= result) {
+ result += op;
+ } else {
+ cc = 0;
+ ep = src;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ cc = 0;
+ ep = src;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ if (0 != cc) {
+ src++;
+ }
+ } while (0 != cc);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ if (NULL != src) { ep = src; }
+ }
+ if (NULL != endptr) { *endptr = ep; }
+
+
+#line 296 "dk4maiwhdu.ctr"
+ return back;
+}
+
diff --git a/support/dktools/dk4maiwhdu.ctr b/support/dktools/dk4maiwhdu.ctr
new file mode 100644
index 0000000000..a200767d9a
--- /dev/null
+++ b/support/dktools/dk4maiwhdu.ctr
@@ -0,0 +1,298 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve dk4_um_t value from
+ wchar_t string in hexadecimal notation.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_hex_dk4_um_t(
+ dk4_um_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+
+
+#include "dk4maiwhdu.h"
+#include "dk4numco.h"
+#include "dk4strw.h"
+
+
+
+$!trace-include
+
+
+
+/* UNTESTED */
+int
+dk4ma_input_wc_hex_dk4_um_t(
+ dk4_um_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_um_t result = (dk4_um_t)0UL;
+ dk4_um_t op;
+ const wchar_t *ep = NULL;
+ int found = 0;
+ int back = 0;
+ int cc = 1;
+ $? "+ dk4ma_input_wc_hex_dk4_um_t"
+ if ((NULL != rp) && (NULL != src)) {
+ if (L'0' == src[0]) {
+ if ((L'x' == src[1]) || (L'X' == src[1])) { src++; src++; }
+ }
+ do {
+ op = (dk4_um_t)0UL;
+#if DK4_SIZEOF_WCHAR_T <= DK4_SIZEOF_INT
+ switch (*src) {
+ case L'0': { op = (dk4_um_t)0UL; } break;
+ case L'1': { op = (dk4_um_t)1UL; } break;
+ case L'2': { op = (dk4_um_t)2UL; } break;
+ case L'3': { op = (dk4_um_t)3UL; } break;
+ case L'4': { op = (dk4_um_t)4UL; } break;
+ case L'5': { op = (dk4_um_t)5UL; } break;
+ case L'6': { op = (dk4_um_t)6UL; } break;
+ case L'7': { op = (dk4_um_t)7UL; } break;
+ case L'8': { op = (dk4_um_t)8UL; } break;
+ case L'9': { op = (dk4_um_t)9UL; } break;
+ case L'a': case L'A': { op = (dk4_um_t)10UL; } break;
+ case L'b': case L'B': { op = (dk4_um_t)11UL; } break;
+ case L'c': case L'C': { op = (dk4_um_t)12UL; } break;
+ case L'd': case L'D': { op = (dk4_um_t)13UL; } break;
+ case L'e': case L'E': { op = (dk4_um_t)14UL; } break;
+ case L'f': case L'F': { op = (dk4_um_t)15UL; } break;
+ case L'\0': { $? ". string finished"
+ cc = 0;
+ if (0 != found) { $? ". digits found"
+ back = 1;
+ *rp = result;
+ } else { $? ". no digits found"
+ ep = src;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ default: {
+ cc = 0;
+ ep = src;
+ if (0 != found) {
+ switch (atg) {
+ case 2: {
+ back = 1;
+ *rp = result;
+ } break;
+ case 1: {
+ if (NULL == dk4strw_start(src, NULL)) {
+ back = 1;
+ *rp = result;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ default: {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ }
+#else
+ if (L'0' == *src) {
+ op = (dk4_um_t)0UL;
+ } else {
+ if (L'1' == *src) {
+ op = (dk4_um_t)1UL;
+ } else {
+ if (L'2' == *src) {
+ op = (dk4_um_t)2UL;
+ } else {
+ if (L'3' == *src) {
+ op = (dk4_um_t)3UL;
+ } else {
+ if (L'4' == *src) {
+ op = (dk4_um_t)4UL;
+ } else {
+ if (L'5' == *src) {
+ op = (dk4_um_t)5UL;
+ } else {
+ if (L'6' == *src) {
+ op = (dk4_um_t)6UL;
+ } else {
+ if (L'7' == *src) {
+ op = (dk4_um_t)7UL;
+ } else {
+ if (L'8' == *src) {
+ op = (dk4_um_t)8UL;
+ } else {
+ if (L'9' == *src) {
+ op = (dk4_um_t)9UL;
+ } else {
+ if ((L'A' == *src) || (L'a' == *src)) {
+ op = (dk4_um_t)10UL;
+ } else {
+ if ((L'B' == *src) || (L'b' == *src)) {
+ op = (dk4_um_t)11UL;
+ } else {
+ if ((L'C' == *src) || (L'c' == *src)) {
+ op = (dk4_um_t)12UL;
+ } else {
+ if ((L'D' == *src) || (L'd' == *src)) {
+ op = (dk4_um_t)13UL;
+ } else {
+ if ((L'E' == *src) || (L'e' == *src)) {
+ op = (dk4_um_t)14UL;
+ } else {
+ if ((L'F' == *src) || (L'f' == *src)) {
+ op = (dk4_um_t)15UL;
+ } else {
+ if (L'\0' == *src) { /* finalizer */
+ cc = 0;
+ if (0 != found) {
+ back = 1;
+ *rp = result;
+ } else {
+ ep = src;
+ dk4error_set_simple_error_code(
+ erp, DK4_E_SYNTAX
+ );
+ }
+ } else { /* any other */
+ cc = 0;
+ ep = src;
+ if (0 != found) {
+ switch (atg) {
+ case 2: {
+ back = 1;
+ *rp = result;
+ } break;
+ case 1: {
+ if (dk4strw_start(src, NULL)) {
+ dk4error_set_simple_error_code(
+ erp, DK4_E_SYNTAX
+ );
+ } else {
+ back = 1;
+ *rp = result;
+ }
+ } break;
+ default: {
+ dk4error_set_simple_error_code(
+ erp, DK4_E_SYNTAX
+ );
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(
+ erp, DK4_E_SYNTAX
+ );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+#endif
+ /* after switch */
+ if (0 != cc) {
+ found = 1;
+ if ((DK4_UM_MAX / (dk4_um_t)16UL) >= result) {
+ result *= (dk4_um_t)16UL;
+ if ((DK4_UM_MAX - op) >= result) {
+ result += op;
+ } else {
+ cc = 0;
+ ep = src;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ cc = 0;
+ ep = src;
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ if (0 != cc) {
+ src++;
+ }
+ } while (0 != cc);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ if (NULL != src) { ep = src; }
+ }
+ if (NULL != endptr) { *endptr = ep; }
+ $? "- dk4ma_input_wc_hex_dk4_um_t %d", back
+ return back;
+}
+
diff --git a/support/dktools/dk4maiwhdu.h b/support/dktools/dk4maiwhdu.h
new file mode 100644
index 0000000000..ae3a54d884
--- /dev/null
+++ b/support/dktools/dk4maiwhdu.h
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwhdu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIWHDU_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIWHDU_H_INCLUDED 1
+
+
+#line 10 "dk4maiwhdu.ctr"
+
+/** @file
+ Retrieve dk4_um_t value from
+ wchar_t string in hexadecimal notation.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_hex_dk4_um_t(
+ dk4_um_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maiwhic.c b/support/dktools/dk4maiwhic.c
new file mode 100644
index 0000000000..6e3cf008f7
--- /dev/null
+++ b/support/dktools/dk4maiwhic.c
@@ -0,0 +1,70 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwhic.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiwhic.c The dk4maiwhic module.
+*/
+
+
+#line 70 "dk4maiwhic.ctr"
+
+#include "dk4maiwhic.h"
+#include "dk4maiwhdi.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_hex_char(
+ signed char *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_hex_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(CHAR_MIN) <= res) && ((dk4_im_t)(CHAR_MAX) >= res)) {
+ *rp = (signed char)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4maiwhic.ctr b/support/dktools/dk4maiwhic.ctr
new file mode 100644
index 0000000000..fe30478b64
--- /dev/null
+++ b/support/dktools/dk4maiwhic.ctr
@@ -0,0 +1,99 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ Retrieve signed char value from
+ wchar_t string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_hex_char(
+ signed char *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4maiwhic.h"
+#include "dk4maiwhdi.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_hex_char(
+ signed char *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_hex_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(CHAR_MIN) <= res) && ((dk4_im_t)(CHAR_MAX) >= res)) {
+ *rp = (signed char)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4maiwhic.h b/support/dktools/dk4maiwhic.h
new file mode 100644
index 0000000000..4778105453
--- /dev/null
+++ b/support/dktools/dk4maiwhic.h
@@ -0,0 +1,103 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwhic.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIWHIC_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIWHIC_H_INCLUDED 1
+
+
+#line 9 "dk4maiwhic.ctr"
+
+/** @file
+ Retrieve signed char value from
+ wchar_t string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_hex_char(
+ signed char *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4maiwhii.c b/support/dktools/dk4maiwhii.c
new file mode 100644
index 0000000000..82a71745bf
--- /dev/null
+++ b/support/dktools/dk4maiwhii.c
@@ -0,0 +1,69 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwhii.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiwhii.c The dk4maiwhii module.
+*/
+
+
+#line 70 "dk4maiwhii.ctr"
+
+#include "dk4maiwhdi.h"
+#include "dk4maiwhii.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_hex_int(
+ int *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_hex_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(INT_MIN) <= res) && (((dk4_im_t)(INT_MAX)) >= res)) {
+ *rp = (int)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4maiwhii.ctr b/support/dktools/dk4maiwhii.ctr
new file mode 100644
index 0000000000..dd99a1d631
--- /dev/null
+++ b/support/dktools/dk4maiwhii.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve int value from
+ wchar_t string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_hex_int(
+ int *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4maiwhdi.h"
+#include "dk4maiwhii.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_hex_int(
+ int *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_hex_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(INT_MIN) <= res) && (((dk4_im_t)(INT_MAX)) >= res)) {
+ *rp = (int)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4maiwhii.h b/support/dktools/dk4maiwhii.h
new file mode 100644
index 0000000000..df2b91cbae
--- /dev/null
+++ b/support/dktools/dk4maiwhii.h
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwhii.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIWHII_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIWHII_H_INCLUDED 1
+
+
+#line 10 "dk4maiwhii.ctr"
+
+/** @file
+ Retrieve int value from
+ wchar_t string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_hex_int(
+ int *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4maiwhil.c b/support/dktools/dk4maiwhil.c
new file mode 100644
index 0000000000..d734c386aa
--- /dev/null
+++ b/support/dktools/dk4maiwhil.c
@@ -0,0 +1,73 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwhil.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiwhil.c The dk4maiwhil module.
+*/
+
+
+#line 70 "dk4maiwhil.ctr"
+
+#include "dk4maiwhdi.h"
+#include "dk4maiwhil.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_hex_long(
+ long *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_INTMAX_T || DK4_HAVE_LONG_LONG
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_hex_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(LONG_MIN) <= res) && (((dk4_im_t)(LONG_MAX)) >= res)) {
+ *rp = (long)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+#else
+ return (dk4ma_input_wc_hex_dk4_im_t(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maiwhil.ctr b/support/dktools/dk4maiwhil.ctr
new file mode 100644
index 0000000000..bd65868144
--- /dev/null
+++ b/support/dktools/dk4maiwhil.ctr
@@ -0,0 +1,102 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve long value from
+ wchar_t string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_hex_long(
+ long *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4maiwhdi.h"
+#include "dk4maiwhil.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_hex_long(
+ long *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_INTMAX_T || DK4_HAVE_LONG_LONG
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_hex_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(LONG_MIN) <= res) && (((dk4_im_t)(LONG_MAX)) >= res)) {
+ *rp = (long)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+#else
+ return (dk4ma_input_wc_hex_dk4_im_t(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maiwhil.h b/support/dktools/dk4maiwhil.h
new file mode 100644
index 0000000000..795b5119fc
--- /dev/null
+++ b/support/dktools/dk4maiwhil.h
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwhil.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIWHIL_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIWHIL_H_INCLUDED 1
+
+
+#line 10 "dk4maiwhil.ctr"
+
+/** @file
+ Retrieve long value from
+ wchar_t string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_hex_long(
+ long *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4maiwhis.c b/support/dktools/dk4maiwhis.c
new file mode 100644
index 0000000000..99469a5ce0
--- /dev/null
+++ b/support/dktools/dk4maiwhis.c
@@ -0,0 +1,69 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwhis.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiwhis.c The dk4maiwhis module.
+*/
+
+
+#line 70 "dk4maiwhis.ctr"
+
+#include "dk4maiwhdi.h"
+#include "dk4maiwhis.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_hex_short(
+ short *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_hex_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(SHRT_MIN) <= res) && (((dk4_im_t)(SHRT_MAX)) >= res)) {
+ *rp = (short)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4maiwhis.ctr b/support/dktools/dk4maiwhis.ctr
new file mode 100644
index 0000000000..c1f441bede
--- /dev/null
+++ b/support/dktools/dk4maiwhis.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve short int value from
+ wchar_t string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_hex_short(
+ short *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4maiwhdi.h"
+#include "dk4maiwhis.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_hex_short(
+ short *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_hex_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(SHRT_MIN) <= res) && (((dk4_im_t)(SHRT_MAX)) >= res)) {
+ *rp = (short)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4maiwhis.h b/support/dktools/dk4maiwhis.h
new file mode 100644
index 0000000000..08e884f409
--- /dev/null
+++ b/support/dktools/dk4maiwhis.h
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwhis.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIWHIS_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIWHIS_H_INCLUDED 1
+
+
+#line 10 "dk4maiwhis.ctr"
+
+/** @file
+ Retrieve short int value from
+ wchar_t string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_hex_short(
+ short *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4maiwhli.c b/support/dktools/dk4maiwhli.c
new file mode 100644
index 0000000000..6635e12325
--- /dev/null
+++ b/support/dktools/dk4maiwhli.c
@@ -0,0 +1,79 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwhli.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiwhli.c The dk4maiwhli module.
+*/
+
+
+#line 74 "dk4maiwhli.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_LONG_LONG
+
+#include "dk4maiwhdi.h"
+#include "dk4maiwhli.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_hex_ll(
+ long long *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_INTMAX_T
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_hex_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(LLONG_MIN) <= res) && (((dk4_im_t)(LLONG_MAX)) >= res)) {
+ *rp = (long long)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+#else
+ return (dk4ma_input_wc_hex_dk4_im_t(rp, src, endptr, atg, erp));
+#endif
+}
+
+#endif
+
diff --git a/support/dktools/dk4maiwhli.ctr b/support/dktools/dk4maiwhli.ctr
new file mode 100644
index 0000000000..b78f85064f
--- /dev/null
+++ b/support/dktools/dk4maiwhli.ctr
@@ -0,0 +1,112 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve long long value from
+ wchar_t string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_LONG_LONG
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_hex_ll(
+ long long *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_LONG_LONG
+
+#include "dk4maiwhdi.h"
+#include "dk4maiwhli.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_hex_ll(
+ long long *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_INTMAX_T
+ dk4_im_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_hex_dk4_im_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_im_t)(LLONG_MIN) <= res) && (((dk4_im_t)(LLONG_MAX)) >= res)) {
+ *rp = (long long)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+#else
+ return (dk4ma_input_wc_hex_dk4_im_t(rp, src, endptr, atg, erp));
+#endif
+}
+
+#endif
+
diff --git a/support/dktools/dk4maiwhli.h b/support/dktools/dk4maiwhli.h
new file mode 100644
index 0000000000..d97bcb389b
--- /dev/null
+++ b/support/dktools/dk4maiwhli.h
@@ -0,0 +1,106 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwhli.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIWHLI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIWHLI_H_INCLUDED 1
+
+
+#line 10 "dk4maiwhli.ctr"
+
+/** @file
+ Retrieve long long value from
+ wchar_t string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_LONG_LONG
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_hex_ll(
+ long long *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4maiwhlu.c b/support/dktools/dk4maiwhlu.c
new file mode 100644
index 0000000000..5d07aee5db
--- /dev/null
+++ b/support/dktools/dk4maiwhlu.c
@@ -0,0 +1,79 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwhlu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiwhlu.c The dk4maiwhlu module.
+*/
+
+
+#line 74 "dk4maiwhlu.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_LONG_LONG
+
+#include "dk4maiwhdu.h"
+#include "dk4maiwhlu.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_hex_ull(
+ unsigned long long *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_INTMAX_T
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_hex_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(ULLONG_MAX)) >= res) {
+ *rp = (unsigned long long)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+#else
+ return (dk4ma_input_wc_hex_dk4_um_t(rp, src, endptr, atg, erp));
+#endif
+}
+
+#endif
+
diff --git a/support/dktools/dk4maiwhlu.ctr b/support/dktools/dk4maiwhlu.ctr
new file mode 100644
index 0000000000..082f036f95
--- /dev/null
+++ b/support/dktools/dk4maiwhlu.ctr
@@ -0,0 +1,112 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve unsigned long long value from
+ wchar_t string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_LONG_LONG
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_hex_ull(
+ unsigned long long *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_LONG_LONG
+
+#include "dk4maiwhdu.h"
+#include "dk4maiwhlu.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_hex_ull(
+ unsigned long long *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_INTMAX_T
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_hex_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(ULLONG_MAX)) >= res) {
+ *rp = (unsigned long long)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+#else
+ return (dk4ma_input_wc_hex_dk4_um_t(rp, src, endptr, atg, erp));
+#endif
+}
+
+#endif
+
diff --git a/support/dktools/dk4maiwhlu.h b/support/dktools/dk4maiwhlu.h
new file mode 100644
index 0000000000..39e63e0d9e
--- /dev/null
+++ b/support/dktools/dk4maiwhlu.h
@@ -0,0 +1,106 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwhlu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIWHLU_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIWHLU_H_INCLUDED 1
+
+
+#line 10 "dk4maiwhlu.ctr"
+
+/** @file
+ Retrieve unsigned long long value from
+ wchar_t string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_LONG_LONG
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_hex_ull(
+ unsigned long long *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4maiwhmi.c b/support/dktools/dk4maiwhmi.c
new file mode 100644
index 0000000000..0a1bab88aa
--- /dev/null
+++ b/support/dktools/dk4maiwhmi.c
@@ -0,0 +1,66 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwhmi.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiwhmi.c The dk4maiwhmi module.
+*/
+
+
+#line 75 "dk4maiwhmi.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#pragma warning (disable:4206)
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#include "dk4maiwhdi.h"
+#include "dk4maiwhmi.h"
+
+int
+dk4ma_input_wc_hex_intmax_t(
+ intmax_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ return (dk4ma_input_wc_hex_dk4_im_t(rp, src, endptr, atg, erp));
+}
+
+#endif
+
diff --git a/support/dktools/dk4maiwhmi.ctr b/support/dktools/dk4maiwhmi.ctr
new file mode 100644
index 0000000000..56004e1875
--- /dev/null
+++ b/support/dktools/dk4maiwhmi.ctr
@@ -0,0 +1,100 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve intmax_t value from
+ wchar_t string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_hex_intmax_t(
+ intmax_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#pragma warning (disable:4206)
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#include "dk4maiwhdi.h"
+#include "dk4maiwhmi.h"
+
+int
+dk4ma_input_wc_hex_intmax_t(
+ intmax_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ return (dk4ma_input_wc_hex_dk4_im_t(rp, src, endptr, atg, erp));
+}
+
+#endif
+
diff --git a/support/dktools/dk4maiwhmi.h b/support/dktools/dk4maiwhmi.h
new file mode 100644
index 0000000000..723b1e5f9e
--- /dev/null
+++ b/support/dktools/dk4maiwhmi.h
@@ -0,0 +1,107 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwhmi.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIWHMI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIWHMI_H_INCLUDED 1
+
+
+#line 10 "dk4maiwhmi.ctr"
+
+/** @file
+ Retrieve intmax_t value from
+ wchar_t string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_hex_intmax_t(
+ intmax_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4maiwhmu.c b/support/dktools/dk4maiwhmu.c
new file mode 100644
index 0000000000..fce3e0744e
--- /dev/null
+++ b/support/dktools/dk4maiwhmu.c
@@ -0,0 +1,66 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwhmu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiwhmu.c The dk4maiwhmu module.
+*/
+
+
+#line 75 "dk4maiwhmu.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#pragma warning (disable:4206)
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#include "dk4maiwhdu.h"
+#include "dk4maiwhmu.h"
+
+int
+dk4ma_input_wc_hex_uintmax_t(
+ uintmax_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ return (dk4ma_input_wc_hex_dk4_um_t(rp, src, endptr, atg, erp));
+}
+
+#endif
+
diff --git a/support/dktools/dk4maiwhmu.ctr b/support/dktools/dk4maiwhmu.ctr
new file mode 100644
index 0000000000..cfa93cf68b
--- /dev/null
+++ b/support/dktools/dk4maiwhmu.ctr
@@ -0,0 +1,100 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve uintmax_t value from
+ wchar_t string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_hex_uintmax_t(
+ uintmax_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#pragma warning (disable:4206)
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#include "dk4maiwhdu.h"
+#include "dk4maiwhmu.h"
+
+int
+dk4ma_input_wc_hex_uintmax_t(
+ uintmax_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ return (dk4ma_input_wc_hex_dk4_um_t(rp, src, endptr, atg, erp));
+}
+
+#endif
+
diff --git a/support/dktools/dk4maiwhmu.h b/support/dktools/dk4maiwhmu.h
new file mode 100644
index 0000000000..83042ca22f
--- /dev/null
+++ b/support/dktools/dk4maiwhmu.h
@@ -0,0 +1,107 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwhmu.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIWHMU_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIWHMU_H_INCLUDED 1
+
+
+#line 10 "dk4maiwhmu.ctr"
+
+/** @file
+ Retrieve uintmax_t value from
+ wchar_t string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_hex_uintmax_t(
+ uintmax_t *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4maiwhuc.c b/support/dktools/dk4maiwhuc.c
new file mode 100644
index 0000000000..71bfe28117
--- /dev/null
+++ b/support/dktools/dk4maiwhuc.c
@@ -0,0 +1,71 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwhuc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiwhuc.c The dk4maiwhuc module.
+*/
+
+
+#line 71 "dk4maiwhuc.ctr"
+
+#include "dk4maiwhuc.h"
+#include "dk4maiwhdu.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_hex_uchar(
+ unsigned char *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_um_t res;
+ int back = 0;
+
+ if (0 != dk4ma_input_wc_hex_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(UCHAR_MAX)) >= res) {
+ *rp = (unsigned char)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4maiwhuc.ctr b/support/dktools/dk4maiwhuc.ctr
new file mode 100644
index 0000000000..ec100d5d6d
--- /dev/null
+++ b/support/dktools/dk4maiwhuc.ctr
@@ -0,0 +1,101 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve unsigned char value from
+ wchar_t string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_hex_uchar(
+ unsigned char *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4maiwhuc.h"
+#include "dk4maiwhdu.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_hex_uchar(
+ unsigned char *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_um_t res;
+ int back = 0;
+
+ if (0 != dk4ma_input_wc_hex_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(UCHAR_MAX)) >= res) {
+ *rp = (unsigned char)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4maiwhuc.h b/support/dktools/dk4maiwhuc.h
new file mode 100644
index 0000000000..091b82dbdc
--- /dev/null
+++ b/support/dktools/dk4maiwhuc.h
@@ -0,0 +1,103 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwhuc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIWHUC_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIWHUC_H_INCLUDED 1
+
+
+#line 10 "dk4maiwhuc.ctr"
+
+/** @file
+ Retrieve unsigned char value from
+ wchar_t string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_hex_uchar(
+ unsigned char *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4maiwhui.c b/support/dktools/dk4maiwhui.c
new file mode 100644
index 0000000000..11127b3772
--- /dev/null
+++ b/support/dktools/dk4maiwhui.c
@@ -0,0 +1,69 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwhui.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiwhui.c The dk4maiwhui module.
+*/
+
+
+#line 70 "dk4maiwhui.ctr"
+
+#include "dk4maiwhdu.h"
+#include "dk4maiwhui.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_hex_uint(
+ unsigned *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_hex_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(UINT_MAX)) >= res) {
+ *rp = (unsigned)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4maiwhui.ctr b/support/dktools/dk4maiwhui.ctr
new file mode 100644
index 0000000000..7ebfa4cc4b
--- /dev/null
+++ b/support/dktools/dk4maiwhui.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve unsigned int value from
+ wchar_t string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_hex_uint(
+ unsigned *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4maiwhdu.h"
+#include "dk4maiwhui.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_hex_uint(
+ unsigned *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_hex_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(UINT_MAX)) >= res) {
+ *rp = (unsigned)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4maiwhui.h b/support/dktools/dk4maiwhui.h
new file mode 100644
index 0000000000..e80c479e5c
--- /dev/null
+++ b/support/dktools/dk4maiwhui.h
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwhui.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIWHUI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIWHUI_H_INCLUDED 1
+
+
+#line 10 "dk4maiwhui.ctr"
+
+/** @file
+ Retrieve unsigned int value from
+ wchar_t string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_hex_uint(
+ unsigned *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4maiwhul.c b/support/dktools/dk4maiwhul.c
new file mode 100644
index 0000000000..d3586ebd90
--- /dev/null
+++ b/support/dktools/dk4maiwhul.c
@@ -0,0 +1,73 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwhul.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiwhul.c The dk4maiwhul module.
+*/
+
+
+#line 70 "dk4maiwhul.ctr"
+
+#include "dk4maiwhdu.h"
+#include "dk4maiwhul.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_hex_ulong(
+ unsigned long *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_INTMAX_T || DK4_HAVE_LONG_LONG
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_hex_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(ULONG_MAX)) >= res) {
+ *rp = (unsigned long)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+#else
+ return (dk4ma_input_wc_hex_dk4_um_t(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maiwhul.ctr b/support/dktools/dk4maiwhul.ctr
new file mode 100644
index 0000000000..7dd85ad499
--- /dev/null
+++ b/support/dktools/dk4maiwhul.ctr
@@ -0,0 +1,102 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve unsigned long value from
+ wchar_t string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_hex_ulong(
+ unsigned long *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4maiwhdu.h"
+#include "dk4maiwhul.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_hex_ulong(
+ unsigned long *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_INTMAX_T || DK4_HAVE_LONG_LONG
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_hex_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(ULONG_MAX)) >= res) {
+ *rp = (unsigned long)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+#else
+ return (dk4ma_input_wc_hex_dk4_um_t(rp, src, endptr, atg, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maiwhul.h b/support/dktools/dk4maiwhul.h
new file mode 100644
index 0000000000..1411bde74e
--- /dev/null
+++ b/support/dktools/dk4maiwhul.h
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwhul.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIWHUL_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIWHUL_H_INCLUDED 1
+
+
+#line 10 "dk4maiwhul.ctr"
+
+/** @file
+ Retrieve unsigned long value from
+ wchar_t string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_hex_ulong(
+ unsigned long *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4maiwhus.c b/support/dktools/dk4maiwhus.c
new file mode 100644
index 0000000000..113ddf9838
--- /dev/null
+++ b/support/dktools/dk4maiwhus.c
@@ -0,0 +1,69 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwhus.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maiwhus.c The dk4maiwhus module.
+*/
+
+
+#line 70 "dk4maiwhus.ctr"
+
+#include "dk4maiwhdu.h"
+#include "dk4maiwhus.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_hex_ushort(
+ unsigned short *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_hex_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(USHRT_MAX)) >= res) {
+ *rp = (unsigned short)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4maiwhus.ctr b/support/dktools/dk4maiwhus.ctr
new file mode 100644
index 0000000000..bbd729015c
--- /dev/null
+++ b/support/dktools/dk4maiwhus.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve unsigned short value from
+ wchar_t string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_hex_ushort(
+ unsigned short *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4maiwhdu.h"
+#include "dk4maiwhus.h"
+#include "dk4numco.h"
+
+
+
+int
+dk4ma_input_wc_hex_ushort(
+ unsigned short *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+ dk4_um_t res;
+ int back = 0;
+ if (0 != dk4ma_input_wc_hex_dk4_um_t(&res, src, endptr, atg, erp)) {
+ if (((dk4_um_t)(USHRT_MAX)) >= res) {
+ *rp = (unsigned short)res;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4maiwhus.h b/support/dktools/dk4maiwhus.h
new file mode 100644
index 0000000000..68eb82f82c
--- /dev/null
+++ b/support/dktools/dk4maiwhus.h
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maiwhus.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIWHUS_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIWHUS_H_INCLUDED 1
+
+
+#line 10 "dk4maiwhus.ctr"
+
+/** @file
+ Retrieve unsigned short value from
+ wchar_t string in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve numeric value from string, hexadecimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ The variable points to the correct error position
+ only if er.ec is DK4_E_SYNTAX.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wc_hex_ushort(
+ unsigned short *rp,
+ const wchar_t *src,
+ const wchar_t **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4maixdbl.cpp b/support/dktools/dk4maixdbl.cpp
new file mode 100644
index 0000000000..732897ca33
--- /dev/null
+++ b/support/dktools/dk4maixdbl.cpp
@@ -0,0 +1,82 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maixdbl.cpt
+*/
+
+/*
+Copyright (C) 2017-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maixdbl.cpp The dk4maixdbl module.
+*/
+
+
+#line 106 "dk4maixdbl.cpt"
+
+#include "dk4conf.h"
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#include "dk4maixdbl.h"
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdbl.h"
+#else
+#error "Illegal wxChar size!"
+#endif
+#else
+#include "dk4mai8dbl.h"
+#endif
+
+
+int
+dk4ma_input_wx_double(
+ double *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4ma_input_wc_double(rp, src, endptr, atg, erp));
+#else
+ return (dk4ma_input_c8_double(rp, src, endptr, atg, erp));
+#endif
+}
+
+
+
+#endif
+
diff --git a/support/dktools/dk4maixdbl.cpt b/support/dktools/dk4maixdbl.cpt
new file mode 100644
index 0000000000..688dc69119
--- /dev/null
+++ b/support/dktools/dk4maixdbl.cpt
@@ -0,0 +1,147 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2017-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Read double value from string.
+
+ CRT on Windows: Required.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+extern "C" {
+
+/** Read double value from char string.
+ The function temporarily resets the LC_NUMERIC locale setting
+ to "C" to retrieve the number and returns the setting to the
+ original value before returning.
+ @param rp Address of result variable.
+ @param src String to process.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here. The function may also store
+ a NULL pointer here.
+ The pointer variable is probably left unchanged
+ on errors or if strtod()/wcstod() is not available
+ on your system (the sscanf()/swscanf() function is
+ used as fallback).
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characaters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_SYNTAX if there are unexpected characters in the
+ string,
+ DK4_E_MATH_OVERFLOW if a mathematical overflow occurs,
+ DK4_E_MATH_UNDERFLOW if a mathematical underflow occurs.
+*/
+int
+dk4ma_input_wx_double(
+ double *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+}
+
+#endif
+
+
+%% module
+
+#include "dk4conf.h"
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#include "dk4maixdbl.h"
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdbl.h"
+#else
+#error "Illegal wxChar size!"
+#endif
+#else
+#include "dk4mai8dbl.h"
+#endif
+
+
+int
+dk4ma_input_wx_double(
+ double *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4ma_input_wc_double(rp, src, endptr, atg, erp));
+#else
+ return (dk4ma_input_c8_double(rp, src, endptr, atg, erp));
+#endif
+}
+
+
+
+#endif
+
diff --git a/support/dktools/dk4maixdbl.h b/support/dktools/dk4maixdbl.h
new file mode 100644
index 0000000000..4fd92fccd0
--- /dev/null
+++ b/support/dktools/dk4maixdbl.h
@@ -0,0 +1,138 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maixdbl.cpt
+*/
+
+/*
+Copyright (C) 2017-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIXDBL_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIXDBL_H_INCLUDED 1
+
+
+#line 10 "dk4maixdbl.cpt"
+
+/** @file
+ Read double value from string.
+
+ CRT on Windows: Required.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+extern "C" {
+
+/** Read double value from char string.
+ The function temporarily resets the LC_NUMERIC locale setting
+ to "C" to retrieve the number and returns the setting to the
+ original value before returning.
+ @param rp Address of result variable.
+ @param src String to process.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here. The function may also store
+ a NULL pointer here.
+ The pointer variable is probably left unchanged
+ on errors or if strtod()/wcstod() is not available
+ on your system (the sscanf()/swscanf() function is
+ used as fallback).
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characaters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_SYNTAX if there are unexpected characters in the
+ string,
+ DK4_E_MATH_OVERFLOW if a mathematical overflow occurs,
+ DK4_E_MATH_UNDERFLOW if a mathematical underflow occurs.
+*/
+int
+dk4ma_input_wx_double(
+ double *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+}
+
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4maixddi.cpp b/support/dktools/dk4maixddi.cpp
new file mode 100644
index 0000000000..c662f5844b
--- /dev/null
+++ b/support/dktools/dk4maixddi.cpp
@@ -0,0 +1,84 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maixddi.cpt
+*/
+
+/*
+Copyright (C) 2017-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maixddi.cpp The dk4maixddi module.
+*/
+
+
+#line 96 "dk4maixddi.cpt"
+
+
+#include "dk4conf.h"
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#include "dk4maixddi.h"
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwddi.h"
+#else
+#error "Illegal wxChar size!"
+#endif
+#else
+#include "dk4mai8ddi.h"
+#endif
+
+
+
+int
+dk4ma_input_wx_dec_dk4_im_t(
+ dk4_im_t *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4ma_input_wc_dec_dk4_im_t(rp, src, endptr, atg, erp));
+#else
+ return (dk4ma_input_c8_dec_dk4_im_t(rp, src, endptr, atg, erp));
+#endif
+}
+
+
+
+#endif
+
diff --git a/support/dktools/dk4maixddi.cpt b/support/dktools/dk4maixddi.cpt
new file mode 100644
index 0000000000..abfc349399
--- /dev/null
+++ b/support/dktools/dk4maixddi.cpt
@@ -0,0 +1,139 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2017-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve dk4_im_t value from
+ wxChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+
+extern "C" {
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wx_dec_dk4_im_t(
+ dk4_im_t *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+}
+
+#endif
+
+%% module
+
+
+#include "dk4conf.h"
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#include "dk4maixddi.h"
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwddi.h"
+#else
+#error "Illegal wxChar size!"
+#endif
+#else
+#include "dk4mai8ddi.h"
+#endif
+
+
+
+int
+dk4ma_input_wx_dec_dk4_im_t(
+ dk4_im_t *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4ma_input_wc_dec_dk4_im_t(rp, src, endptr, atg, erp));
+#else
+ return (dk4ma_input_c8_dec_dk4_im_t(rp, src, endptr, atg, erp));
+#endif
+}
+
+
+
+#endif
+
diff --git a/support/dktools/dk4maixddi.h b/support/dktools/dk4maixddi.h
new file mode 100644
index 0000000000..d4e1c944d5
--- /dev/null
+++ b/support/dktools/dk4maixddi.h
@@ -0,0 +1,128 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maixddi.cpt
+*/
+
+/*
+Copyright (C) 2017-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIXDDI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIXDDI_H_INCLUDED 1
+
+
+#line 10 "dk4maixddi.cpt"
+
+/** @file
+ Retrieve dk4_im_t value from
+ wxChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+
+extern "C" {
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wx_dec_dk4_im_t(
+ dk4_im_t *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+}
+
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4maixddu.cpp b/support/dktools/dk4maixddu.cpp
new file mode 100644
index 0000000000..19cb51d863
--- /dev/null
+++ b/support/dktools/dk4maixddu.cpp
@@ -0,0 +1,83 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maixddu.cpt
+*/
+
+/*
+Copyright (C) 2017-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maixddu.cpp The dk4maixddu module.
+*/
+
+
+#line 96 "dk4maixddu.cpt"
+
+#include "dk4conf.h"
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#include "dk4maixddu.h"
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwddu.h"
+#else
+#error "Illegal wxChar size!"
+#endif
+#else
+#include "dk4mai8ddu.h"
+#endif
+
+
+
+int
+dk4ma_input_wx_dec_dk4_um_t(
+ dk4_um_t *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return ( dk4ma_input_wc_dec_dk4_um_t(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_dk4_um_t(rp, src, endptr, atg, erp));
+#endif
+}
+
+
+
+#endif
+
diff --git a/support/dktools/dk4maixddu.cpt b/support/dktools/dk4maixddu.cpt
new file mode 100644
index 0000000000..b1a2dc5178
--- /dev/null
+++ b/support/dktools/dk4maixddu.cpt
@@ -0,0 +1,138 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2017-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve dk4_um_t value from
+ wxChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+extern "C" {
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wx_dec_dk4_um_t(
+ dk4_um_t *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+}
+
+
+#endif
+
+
+%% module
+
+#include "dk4conf.h"
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#include "dk4maixddu.h"
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwddu.h"
+#else
+#error "Illegal wxChar size!"
+#endif
+#else
+#include "dk4mai8ddu.h"
+#endif
+
+
+
+int
+dk4ma_input_wx_dec_dk4_um_t(
+ dk4_um_t *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return ( dk4ma_input_wc_dec_dk4_um_t(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_dk4_um_t(rp, src, endptr, atg, erp));
+#endif
+}
+
+
+
+#endif
+
diff --git a/support/dktools/dk4maixddu.h b/support/dktools/dk4maixddu.h
new file mode 100644
index 0000000000..10ff0999eb
--- /dev/null
+++ b/support/dktools/dk4maixddu.h
@@ -0,0 +1,128 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maixddu.cpt
+*/
+
+/*
+Copyright (C) 2017-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIXDDU_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIXDDU_H_INCLUDED 1
+
+
+#line 10 "dk4maixddu.cpt"
+
+/** @file
+ Retrieve dk4_um_t value from
+ wxChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+extern "C" {
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wx_dec_dk4_um_t(
+ dk4_um_t *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+}
+
+
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4maixdic.cpp b/support/dktools/dk4maixdic.cpp
new file mode 100644
index 0000000000..2183c0fad2
--- /dev/null
+++ b/support/dktools/dk4maixdic.cpp
@@ -0,0 +1,83 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maixdic.cpt
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maixdic.cpp The dk4maixdic module.
+*/
+
+
+#line 99 "dk4maixdic.cpt"
+
+#include "dk4conf.h"
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#include "dk4maixdic.h"
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdic.h"
+#else
+#error "Illegal wxChar size!"
+#endif
+#else
+#include "dk4mai8dic.h"
+#endif
+
+
+
+int
+dk4ma_input_wx_dec_char(
+ signed char *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return ( dk4ma_input_wc_dec_char(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_char(rp, src, endptr, atg, erp));
+#endif
+}
+
+
+
+#endif
+
diff --git a/support/dktools/dk4maixdic.cpt b/support/dktools/dk4maixdic.cpt
new file mode 100644
index 0000000000..961da1f6a1
--- /dev/null
+++ b/support/dktools/dk4maixdic.cpt
@@ -0,0 +1,141 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve signed char value from
+ wxChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+extern "C" {
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wx_dec_char(
+ signed char *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+}
+
+
+
+#endif
+
+
+%% module
+
+#include "dk4conf.h"
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#include "dk4maixdic.h"
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdic.h"
+#else
+#error "Illegal wxChar size!"
+#endif
+#else
+#include "dk4mai8dic.h"
+#endif
+
+
+
+int
+dk4ma_input_wx_dec_char(
+ signed char *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return ( dk4ma_input_wc_dec_char(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_char(rp, src, endptr, atg, erp));
+#endif
+}
+
+
+
+#endif
+
diff --git a/support/dktools/dk4maixdic.h b/support/dktools/dk4maixdic.h
new file mode 100644
index 0000000000..7e6eae86d5
--- /dev/null
+++ b/support/dktools/dk4maixdic.h
@@ -0,0 +1,131 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maixdic.cpt
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIXDIC_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIXDIC_H_INCLUDED 1
+
+
+#line 10 "dk4maixdic.cpt"
+
+/** @file
+ Retrieve signed char value from
+ wxChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+extern "C" {
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wx_dec_char(
+ signed char *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+}
+
+
+
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4maixdii.cpp b/support/dktools/dk4maixdii.cpp
new file mode 100644
index 0000000000..a7a5c55849
--- /dev/null
+++ b/support/dktools/dk4maixdii.cpp
@@ -0,0 +1,83 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maixdii.cpt
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maixdii.cpp The dk4maixdii module.
+*/
+
+
+#line 101 "dk4maixdii.cpt"
+
+#include "dk4conf.h"
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#include "dk4maixdii.h"
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdii.h"
+#else
+#error "Illegal wxChar size!"
+#endif
+#else
+#include "dk4mai8dii.h"
+#endif
+
+
+
+int
+dk4ma_input_wx_dec_int(
+ int *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return ( dk4ma_input_wc_dec_int(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_int(rp, src, endptr, atg, erp));
+#endif
+}
+
+
+
+#endif
+
diff --git a/support/dktools/dk4maixdii.cpt b/support/dktools/dk4maixdii.cpt
new file mode 100644
index 0000000000..5572295433
--- /dev/null
+++ b/support/dktools/dk4maixdii.cpt
@@ -0,0 +1,143 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve int value from
+ wxChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+extern "C" {
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wx_dec_int(
+ int *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+}
+
+
+#endif
+
+
+%% module
+
+#include "dk4conf.h"
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#include "dk4maixdii.h"
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdii.h"
+#else
+#error "Illegal wxChar size!"
+#endif
+#else
+#include "dk4mai8dii.h"
+#endif
+
+
+
+int
+dk4ma_input_wx_dec_int(
+ int *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return ( dk4ma_input_wc_dec_int(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_int(rp, src, endptr, atg, erp));
+#endif
+}
+
+
+
+#endif
+
diff --git a/support/dktools/dk4maixdii.h b/support/dktools/dk4maixdii.h
new file mode 100644
index 0000000000..e061d2ddc5
--- /dev/null
+++ b/support/dktools/dk4maixdii.h
@@ -0,0 +1,133 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maixdii.cpt
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIXDII_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIXDII_H_INCLUDED 1
+
+
+#line 10 "dk4maixdii.cpt"
+
+/** @file
+ Retrieve int value from
+ wxChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+extern "C" {
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wx_dec_int(
+ int *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+}
+
+
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4maixdil.cpp b/support/dktools/dk4maixdil.cpp
new file mode 100644
index 0000000000..00b9452a93
--- /dev/null
+++ b/support/dktools/dk4maixdil.cpp
@@ -0,0 +1,83 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maixdil.cpt
+*/
+
+/*
+Copyright (C) 2017-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maixdil.cpp The dk4maixdil module.
+*/
+
+
+#line 102 "dk4maixdil.cpt"
+
+#include "dk4conf.h"
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#include "dk4maixdil.h"
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdil.h"
+#else
+#error "Illegal wxChar size!"
+#endif
+#else
+#include "dk4mai8dil.h"
+#endif
+
+
+
+int
+dk4ma_input_wx_dec_long(
+ long *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return ( dk4ma_input_wc_dec_long(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_long(rp, src, endptr, atg, erp));
+#endif
+}
+
+
+
+#endif
+
diff --git a/support/dktools/dk4maixdil.cpt b/support/dktools/dk4maixdil.cpt
new file mode 100644
index 0000000000..e90fd711f0
--- /dev/null
+++ b/support/dktools/dk4maixdil.cpt
@@ -0,0 +1,144 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2017-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve long value from
+ wxChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+extern "C" {
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wx_dec_long(
+ long *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+}
+
+
+
+#endif
+
+
+
+%% module
+
+#include "dk4conf.h"
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#include "dk4maixdil.h"
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdil.h"
+#else
+#error "Illegal wxChar size!"
+#endif
+#else
+#include "dk4mai8dil.h"
+#endif
+
+
+
+int
+dk4ma_input_wx_dec_long(
+ long *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return ( dk4ma_input_wc_dec_long(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_long(rp, src, endptr, atg, erp));
+#endif
+}
+
+
+
+#endif
+
diff --git a/support/dktools/dk4maixdil.h b/support/dktools/dk4maixdil.h
new file mode 100644
index 0000000000..e58949e32f
--- /dev/null
+++ b/support/dktools/dk4maixdil.h
@@ -0,0 +1,134 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maixdil.cpt
+*/
+
+/*
+Copyright (C) 2017-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIXDIL_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIXDIL_H_INCLUDED 1
+
+
+#line 10 "dk4maixdil.cpt"
+
+/** @file
+ Retrieve long value from
+ wxChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+extern "C" {
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wx_dec_long(
+ long *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+}
+
+
+
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maixdis.cpp b/support/dktools/dk4maixdis.cpp
new file mode 100644
index 0000000000..d96d4e6e64
--- /dev/null
+++ b/support/dktools/dk4maixdis.cpp
@@ -0,0 +1,83 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maixdis.cpt
+*/
+
+/*
+Copyright (C) 2017-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maixdis.cpp The dk4maixdis module.
+*/
+
+
+#line 103 "dk4maixdis.cpt"
+
+#include "dk4conf.h"
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#include "dk4maixdis.h"
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdis.h"
+#else
+#error "Illegal wxChar size!"
+#endif
+#else
+#include "dk4mai8dis.h"
+#endif
+
+
+
+int
+dk4ma_input_wx_dec_short(
+ short *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return ( dk4ma_input_wc_dec_short(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_short(rp, src, endptr, atg, erp));
+#endif
+}
+
+
+
+#endif
+
diff --git a/support/dktools/dk4maixdis.cpt b/support/dktools/dk4maixdis.cpt
new file mode 100644
index 0000000000..6274eb41af
--- /dev/null
+++ b/support/dktools/dk4maixdis.cpt
@@ -0,0 +1,145 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2017-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve short int value from
+ wxChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+extern "C" {
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wx_dec_short(
+ short *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+}
+
+
+
+#endif
+
+
+
+%% module
+
+#include "dk4conf.h"
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#include "dk4maixdis.h"
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdis.h"
+#else
+#error "Illegal wxChar size!"
+#endif
+#else
+#include "dk4mai8dis.h"
+#endif
+
+
+
+int
+dk4ma_input_wx_dec_short(
+ short *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return ( dk4ma_input_wc_dec_short(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_short(rp, src, endptr, atg, erp));
+#endif
+}
+
+
+
+#endif
+
diff --git a/support/dktools/dk4maixdis.h b/support/dktools/dk4maixdis.h
new file mode 100644
index 0000000000..77a6560c33
--- /dev/null
+++ b/support/dktools/dk4maixdis.h
@@ -0,0 +1,135 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maixdis.cpt
+*/
+
+/*
+Copyright (C) 2017-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIXDIS_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIXDIS_H_INCLUDED 1
+
+
+#line 10 "dk4maixdis.cpt"
+
+/** @file
+ Retrieve short int value from
+ wxChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+extern "C" {
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wx_dec_short(
+ short *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+}
+
+
+
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maixdli.cpp b/support/dktools/dk4maixdli.cpp
new file mode 100644
index 0000000000..de08c58f99
--- /dev/null
+++ b/support/dktools/dk4maixdli.cpp
@@ -0,0 +1,83 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maixdli.cpt
+*/
+
+/*
+Copyright (C) 2017-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maixdli.cpp The dk4maixdli module.
+*/
+
+
+#line 103 "dk4maixdli.cpt"
+
+#include "dk4conf.h"
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#include "dk4maixdli.h"
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdli.h"
+#else
+#error "Illegal wxChar size!"
+#endif
+#else
+#include "dk4mai8dli.h"
+#endif
+
+
+
+int
+dk4ma_input_wx_dec_ll(
+ long long *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return ( dk4ma_input_wc_dec_ll(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_ll(rp, src, endptr, atg, erp));
+#endif
+}
+
+
+
+#endif
+
diff --git a/support/dktools/dk4maixdli.cpt b/support/dktools/dk4maixdli.cpt
new file mode 100644
index 0000000000..1665b0af7e
--- /dev/null
+++ b/support/dktools/dk4maixdli.cpt
@@ -0,0 +1,145 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2017-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve long long value from
+ wxChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+
+extern "C" {
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wx_dec_ll(
+ long long *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+}
+
+
+
+#endif
+
+
+
+%% module
+
+#include "dk4conf.h"
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#include "dk4maixdli.h"
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdli.h"
+#else
+#error "Illegal wxChar size!"
+#endif
+#else
+#include "dk4mai8dli.h"
+#endif
+
+
+
+int
+dk4ma_input_wx_dec_ll(
+ long long *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return ( dk4ma_input_wc_dec_ll(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_ll(rp, src, endptr, atg, erp));
+#endif
+}
+
+
+
+#endif
+
diff --git a/support/dktools/dk4maixdli.h b/support/dktools/dk4maixdli.h
new file mode 100644
index 0000000000..ff0de1cc74
--- /dev/null
+++ b/support/dktools/dk4maixdli.h
@@ -0,0 +1,135 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maixdli.cpt
+*/
+
+/*
+Copyright (C) 2017-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIXDLI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIXDLI_H_INCLUDED 1
+
+
+#line 10 "dk4maixdli.cpt"
+
+/** @file
+ Retrieve long long value from
+ wxChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+
+extern "C" {
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wx_dec_ll(
+ long long *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+}
+
+
+
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maixdlu.cpp b/support/dktools/dk4maixdlu.cpp
new file mode 100644
index 0000000000..2941628d0c
--- /dev/null
+++ b/support/dktools/dk4maixdlu.cpp
@@ -0,0 +1,83 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maixdlu.cpt
+*/
+
+/*
+Copyright (C) 2017-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maixdlu.cpp The dk4maixdlu module.
+*/
+
+
+#line 102 "dk4maixdlu.cpt"
+
+#include "dk4conf.h"
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#include "dk4maixdlu.h"
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdlu.h"
+#else
+#error "Illegal wxChar size!"
+#endif
+#else
+#include "dk4mai8dlu.h"
+#endif
+
+
+
+int
+dk4ma_input_wx_dec_ull(
+ unsigned long long *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return ( dk4ma_input_wc_dec_ull(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_ull(rp, src, endptr, atg, erp));
+#endif
+}
+
+
+
+#endif
+
diff --git a/support/dktools/dk4maixdlu.cpt b/support/dktools/dk4maixdlu.cpt
new file mode 100644
index 0000000000..e793f44cd3
--- /dev/null
+++ b/support/dktools/dk4maixdlu.cpt
@@ -0,0 +1,144 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2017-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve unsigned long long value from
+ wxChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+extern "C" {
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wx_dec_ull(
+ unsigned long long *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+}
+
+
+#endif
+
+
+
+%% module
+
+#include "dk4conf.h"
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#include "dk4maixdlu.h"
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdlu.h"
+#else
+#error "Illegal wxChar size!"
+#endif
+#else
+#include "dk4mai8dlu.h"
+#endif
+
+
+
+int
+dk4ma_input_wx_dec_ull(
+ unsigned long long *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return ( dk4ma_input_wc_dec_ull(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_ull(rp, src, endptr, atg, erp));
+#endif
+}
+
+
+
+#endif
+
diff --git a/support/dktools/dk4maixdlu.h b/support/dktools/dk4maixdlu.h
new file mode 100644
index 0000000000..fdbba8cf57
--- /dev/null
+++ b/support/dktools/dk4maixdlu.h
@@ -0,0 +1,134 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maixdlu.cpt
+*/
+
+/*
+Copyright (C) 2017-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIXDLU_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIXDLU_H_INCLUDED 1
+
+
+#line 10 "dk4maixdlu.cpt"
+
+/** @file
+ Retrieve unsigned long long value from
+ wxChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+extern "C" {
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wx_dec_ull(
+ unsigned long long *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+}
+
+
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maixdmi.cpp b/support/dktools/dk4maixdmi.cpp
new file mode 100644
index 0000000000..481d7b488b
--- /dev/null
+++ b/support/dktools/dk4maixdmi.cpp
@@ -0,0 +1,91 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maixdmi.cpt
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maixdmi.cpp The dk4maixdmi module.
+*/
+
+
+#line 106 "dk4maixdmi.cpt"
+
+#include "dk4conf.h"
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#include "dk4maixdmi.h"
+
+#if DK4_ON_WINDOWS
+#pragma warning (disable:4206)
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdmi.h"
+#else
+#error "Illegal wxChar size!"
+#endif
+#else
+#include "dk4mai8dmi.h"
+#endif
+
+
+
+int
+dk4ma_input_wx_dec_intmax_t(
+ intmax_t *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return ( dk4ma_input_wc_dec_intmax_t(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_intmax_t(rp, src, endptr, atg, erp));
+#endif
+}
+
+
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4maixdmi.cpt b/support/dktools/dk4maixdmi.cpt
new file mode 100644
index 0000000000..e04a34856b
--- /dev/null
+++ b/support/dktools/dk4maixdmi.cpt
@@ -0,0 +1,156 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve intmax_t value from
+ wxChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+extern "C" {
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wx_dec_intmax_t(
+ intmax_t *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+}
+
+
+
+#endif
+
+#endif
+
+
+%% module
+
+#include "dk4conf.h"
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#include "dk4maixdmi.h"
+
+#if DK4_ON_WINDOWS
+#pragma warning (disable:4206)
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdmi.h"
+#else
+#error "Illegal wxChar size!"
+#endif
+#else
+#include "dk4mai8dmi.h"
+#endif
+
+
+
+int
+dk4ma_input_wx_dec_intmax_t(
+ intmax_t *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return ( dk4ma_input_wc_dec_intmax_t(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_intmax_t(rp, src, endptr, atg, erp));
+#endif
+}
+
+
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4maixdmi.h b/support/dktools/dk4maixdmi.h
new file mode 100644
index 0000000000..fc746cd40c
--- /dev/null
+++ b/support/dktools/dk4maixdmi.h
@@ -0,0 +1,138 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maixdmi.cpt
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIXDMI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIXDMI_H_INCLUDED 1
+
+
+#line 10 "dk4maixdmi.cpt"
+
+/** @file
+ Retrieve intmax_t value from
+ wxChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+extern "C" {
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wx_dec_intmax_t(
+ intmax_t *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+}
+
+
+
+#endif
+
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4maixdmu.cpp b/support/dktools/dk4maixdmu.cpp
new file mode 100644
index 0000000000..b76b0d8bd3
--- /dev/null
+++ b/support/dktools/dk4maixdmu.cpp
@@ -0,0 +1,96 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maixdmu.cpt
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maixdmu.cpp The dk4maixdmu module.
+*/
+
+
+#line 108 "dk4maixdmu.cpt"
+
+
+#include "dk4conf.h"
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#include "dk4maixdmu.h"
+
+#if DK4_ON_WINDOWS
+#pragma warning (disable:4206)
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdmu.h"
+#else
+#error "Illegal wxChar size!"
+#endif
+#else
+#include "dk4mai8dmu.h"
+#endif
+
+
+
+int
+dk4ma_input_wx_dec_uintmax_t(
+ uintmax_t *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return ( dk4ma_input_wc_dec_uintmax_t(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_uintmax_t(rp, src, endptr, atg, erp));
+#endif
+}
+
+
+
+#endif
+
+
+
+#endif
+
diff --git a/support/dktools/dk4maixdmu.cpt b/support/dktools/dk4maixdmu.cpt
new file mode 100644
index 0000000000..2668df1bb6
--- /dev/null
+++ b/support/dktools/dk4maixdmu.cpt
@@ -0,0 +1,163 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve uintmax_t value from
+ wxChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+extern "C" {
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wx_dec_uintmax_t(
+ uintmax_t *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+}
+
+
+
+#endif
+
+#endif
+
+
+
+%% module
+
+
+#include "dk4conf.h"
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#include "dk4maixdmu.h"
+
+#if DK4_ON_WINDOWS
+#pragma warning (disable:4206)
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdmu.h"
+#else
+#error "Illegal wxChar size!"
+#endif
+#else
+#include "dk4mai8dmu.h"
+#endif
+
+
+
+int
+dk4ma_input_wx_dec_uintmax_t(
+ uintmax_t *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return ( dk4ma_input_wc_dec_uintmax_t(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_uintmax_t(rp, src, endptr, atg, erp));
+#endif
+}
+
+
+
+#endif
+
+
+
+#endif
+
diff --git a/support/dktools/dk4maixdmu.h b/support/dktools/dk4maixdmu.h
new file mode 100644
index 0000000000..daec3b709d
--- /dev/null
+++ b/support/dktools/dk4maixdmu.h
@@ -0,0 +1,140 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maixdmu.cpt
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIXDMU_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIXDMU_H_INCLUDED 1
+
+
+#line 10 "dk4maixdmu.cpt"
+
+/** @file
+ Retrieve uintmax_t value from
+ wxChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_INTMAX_T
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+extern "C" {
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wx_dec_uintmax_t(
+ uintmax_t *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+}
+
+
+
+#endif
+
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maixdsz.cpp b/support/dktools/dk4maixdsz.cpp
new file mode 100644
index 0000000000..96af7ef6d0
--- /dev/null
+++ b/support/dktools/dk4maixdsz.cpp
@@ -0,0 +1,83 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maixdsz.cpt
+*/
+
+/*
+Copyright (C) 2017-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maixdsz.cpp The dk4maixdsz module.
+*/
+
+
+#line 103 "dk4maixdsz.cpt"
+
+#include "dk4conf.h"
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#include "dk4maixdsz.h"
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdsz.h"
+#else
+#error "Illegal wxChar size!"
+#endif
+#else
+#include "dk4mai8dsz.h"
+#endif
+
+
+
+int
+dk4ma_input_wx_dec_size_t(
+ size_t *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return ( dk4ma_input_wc_dec_size_t(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_size_t(rp, src, endptr, atg, erp));
+#endif
+}
+
+
+
+#endif
+
diff --git a/support/dktools/dk4maixdsz.cpt b/support/dktools/dk4maixdsz.cpt
new file mode 100644
index 0000000000..a005393e83
--- /dev/null
+++ b/support/dktools/dk4maixdsz.cpt
@@ -0,0 +1,145 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2017-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve size_t value from
+ wxChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+extern "C" {
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wx_dec_size_t(
+ size_t *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+}
+
+
+#endif
+
+
+
+%% module
+
+#include "dk4conf.h"
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#include "dk4maixdsz.h"
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdsz.h"
+#else
+#error "Illegal wxChar size!"
+#endif
+#else
+#include "dk4mai8dsz.h"
+#endif
+
+
+
+int
+dk4ma_input_wx_dec_size_t(
+ size_t *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return ( dk4ma_input_wc_dec_size_t(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_size_t(rp, src, endptr, atg, erp));
+#endif
+}
+
+
+
+#endif
+
diff --git a/support/dktools/dk4maixdsz.h b/support/dktools/dk4maixdsz.h
new file mode 100644
index 0000000000..67f3eb09d3
--- /dev/null
+++ b/support/dktools/dk4maixdsz.h
@@ -0,0 +1,135 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maixdsz.cpt
+*/
+
+/*
+Copyright (C) 2017-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIXDSZ_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIXDSZ_H_INCLUDED 1
+
+
+#line 10 "dk4maixdsz.cpt"
+
+/** @file
+ Retrieve size_t value from
+ wxChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+extern "C" {
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wx_dec_size_t(
+ size_t *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+}
+
+
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maixduc.cpp b/support/dktools/dk4maixduc.cpp
new file mode 100644
index 0000000000..201f15d372
--- /dev/null
+++ b/support/dktools/dk4maixduc.cpp
@@ -0,0 +1,83 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maixduc.cpt
+*/
+
+/*
+Copyright (C) 2017-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maixduc.cpp The dk4maixduc module.
+*/
+
+
+#line 102 "dk4maixduc.cpt"
+
+#include "dk4conf.h"
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#include "dk4maixduc.h"
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwduc.h"
+#else
+#error "Illegal wxChar size!"
+#endif
+#else
+#include "dk4mai8duc.h"
+#endif
+
+
+
+int
+dk4ma_input_wx_dec_uchar(
+ unsigned char *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return ( dk4ma_input_wc_dec_uchar(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_uchar(rp, src, endptr, atg, erp));
+#endif
+}
+
+
+
+#endif
+
diff --git a/support/dktools/dk4maixduc.cpt b/support/dktools/dk4maixduc.cpt
new file mode 100644
index 0000000000..a95842db99
--- /dev/null
+++ b/support/dktools/dk4maixduc.cpt
@@ -0,0 +1,144 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2017-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve unsigned char value from
+ wxChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+extern "C" {
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wx_dec_uchar(
+ unsigned char *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+}
+
+
+
+#endif
+
+
+
+%% module
+
+#include "dk4conf.h"
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#include "dk4maixduc.h"
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwduc.h"
+#else
+#error "Illegal wxChar size!"
+#endif
+#else
+#include "dk4mai8duc.h"
+#endif
+
+
+
+int
+dk4ma_input_wx_dec_uchar(
+ unsigned char *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return ( dk4ma_input_wc_dec_uchar(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_uchar(rp, src, endptr, atg, erp));
+#endif
+}
+
+
+
+#endif
+
diff --git a/support/dktools/dk4maixduc.h b/support/dktools/dk4maixduc.h
new file mode 100644
index 0000000000..d4f33662e6
--- /dev/null
+++ b/support/dktools/dk4maixduc.h
@@ -0,0 +1,134 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maixduc.cpt
+*/
+
+/*
+Copyright (C) 2017-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIXDUC_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIXDUC_H_INCLUDED 1
+
+
+#line 10 "dk4maixduc.cpt"
+
+/** @file
+ Retrieve unsigned char value from
+ wxChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+extern "C" {
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wx_dec_uchar(
+ unsigned char *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+}
+
+
+
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maixdui.cpp b/support/dktools/dk4maixdui.cpp
new file mode 100644
index 0000000000..79600d1b09
--- /dev/null
+++ b/support/dktools/dk4maixdui.cpp
@@ -0,0 +1,83 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maixdui.cpt
+*/
+
+/*
+Copyright (C) 2017-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maixdui.cpp The dk4maixdui module.
+*/
+
+
+#line 104 "dk4maixdui.cpt"
+
+#include "dk4conf.h"
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#include "dk4maixdui.h"
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdui.h"
+#else
+#error "Illegal wxChar size!"
+#endif
+#else
+#include "dk4mai8dui.h"
+#endif
+
+
+
+int
+dk4ma_input_wx_dec_uint(
+ unsigned *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return ( dk4ma_input_wc_dec_uint(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_uint(rp, src, endptr, atg, erp));
+#endif
+}
+
+
+
+#endif
+
diff --git a/support/dktools/dk4maixdui.cpt b/support/dktools/dk4maixdui.cpt
new file mode 100644
index 0000000000..f5a4a1bb6c
--- /dev/null
+++ b/support/dktools/dk4maixdui.cpt
@@ -0,0 +1,146 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2017-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve unsigned int value from
+ wxChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+extern "C" {
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wx_dec_uint(
+ unsigned *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+}
+
+
+
+#endif
+
+
+
+%% module
+
+#include "dk4conf.h"
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#include "dk4maixdui.h"
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdui.h"
+#else
+#error "Illegal wxChar size!"
+#endif
+#else
+#include "dk4mai8dui.h"
+#endif
+
+
+
+int
+dk4ma_input_wx_dec_uint(
+ unsigned *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return ( dk4ma_input_wc_dec_uint(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_uint(rp, src, endptr, atg, erp));
+#endif
+}
+
+
+
+#endif
+
diff --git a/support/dktools/dk4maixdui.h b/support/dktools/dk4maixdui.h
new file mode 100644
index 0000000000..fbe3d480ff
--- /dev/null
+++ b/support/dktools/dk4maixdui.h
@@ -0,0 +1,136 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maixdui.cpt
+*/
+
+/*
+Copyright (C) 2017-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIXDUI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIXDUI_H_INCLUDED 1
+
+
+#line 10 "dk4maixdui.cpt"
+
+/** @file
+ Retrieve unsigned int value from
+ wxChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+extern "C" {
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wx_dec_uint(
+ unsigned *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+}
+
+
+
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maixdul.cpp b/support/dktools/dk4maixdul.cpp
new file mode 100644
index 0000000000..ac6c906d31
--- /dev/null
+++ b/support/dktools/dk4maixdul.cpp
@@ -0,0 +1,83 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maixdul.cpt
+*/
+
+/*
+Copyright (C) 2017-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maixdul.cpp The dk4maixdul module.
+*/
+
+
+#line 103 "dk4maixdul.cpt"
+
+#include "dk4conf.h"
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#include "dk4maixdul.h"
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdul.h"
+#else
+#error "Illegal wxChar size!"
+#endif
+#else
+#include "dk4mai8dul.h"
+#endif
+
+
+
+int
+dk4ma_input_wx_dec_ulong(
+ unsigned long *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return ( dk4ma_input_wc_dec_ulong(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_ulong(rp, src, endptr, atg, erp));
+#endif
+}
+
+
+
+#endif
+
diff --git a/support/dktools/dk4maixdul.cpt b/support/dktools/dk4maixdul.cpt
new file mode 100644
index 0000000000..fc2219baa1
--- /dev/null
+++ b/support/dktools/dk4maixdul.cpt
@@ -0,0 +1,145 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2017-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve unsigned long value from
+ wxChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+extern "C" {
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wx_dec_ulong(
+ unsigned long *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+}
+
+
+
+#endif
+
+
+
+%% module
+
+#include "dk4conf.h"
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#include "dk4maixdul.h"
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdul.h"
+#else
+#error "Illegal wxChar size!"
+#endif
+#else
+#include "dk4mai8dul.h"
+#endif
+
+
+
+int
+dk4ma_input_wx_dec_ulong(
+ unsigned long *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return ( dk4ma_input_wc_dec_ulong(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_ulong(rp, src, endptr, atg, erp));
+#endif
+}
+
+
+
+#endif
+
diff --git a/support/dktools/dk4maixdul.h b/support/dktools/dk4maixdul.h
new file mode 100644
index 0000000000..251b13f58e
--- /dev/null
+++ b/support/dktools/dk4maixdul.h
@@ -0,0 +1,135 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maixdul.cpt
+*/
+
+/*
+Copyright (C) 2017-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIXDUL_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIXDUL_H_INCLUDED 1
+
+
+#line 10 "dk4maixdul.cpt"
+
+/** @file
+ Retrieve unsigned long value from
+ wxChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+extern "C" {
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wx_dec_ulong(
+ unsigned long *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+}
+
+
+
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maixdus.cpp b/support/dktools/dk4maixdus.cpp
new file mode 100644
index 0000000000..c0623dd8a8
--- /dev/null
+++ b/support/dktools/dk4maixdus.cpp
@@ -0,0 +1,83 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maixdus.cpt
+*/
+
+/*
+Copyright (C) 2017-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maixdus.cpp The dk4maixdus module.
+*/
+
+
+#line 103 "dk4maixdus.cpt"
+
+#include "dk4conf.h"
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#include "dk4maixdus.h"
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdus.h"
+#else
+#error "Illegal wxChar size!"
+#endif
+#else
+#include "dk4mai8dus.h"
+#endif
+
+
+
+int
+dk4ma_input_wx_dec_ushort(
+ unsigned short *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return ( dk4ma_input_wc_dec_ushort(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_ushort(rp, src, endptr, atg, erp));
+#endif
+}
+
+
+
+#endif
+
diff --git a/support/dktools/dk4maixdus.cpt b/support/dktools/dk4maixdus.cpt
new file mode 100644
index 0000000000..6f8f6f4c36
--- /dev/null
+++ b/support/dktools/dk4maixdus.cpt
@@ -0,0 +1,145 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2017-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve unsigned short value from
+ wxChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+extern "C" {
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wx_dec_ushort(
+ unsigned short *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+}
+
+
+
+#endif
+
+
+
+%% module
+
+#include "dk4conf.h"
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#include "dk4maixdus.h"
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR == DK4_SIZEOF_WCHAR_T
+#include "dk4maiwdus.h"
+#else
+#error "Illegal wxChar size!"
+#endif
+#else
+#include "dk4mai8dus.h"
+#endif
+
+
+
+int
+dk4ma_input_wx_dec_ushort(
+ unsigned short *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return ( dk4ma_input_wc_dec_ushort(rp, src, endptr, atg, erp));
+#else
+ return ( dk4ma_input_c8_dec_ushort(rp, src, endptr, atg, erp));
+#endif
+}
+
+
+
+#endif
+
diff --git a/support/dktools/dk4maixdus.h b/support/dktools/dk4maixdus.h
new file mode 100644
index 0000000000..8bbafca207
--- /dev/null
+++ b/support/dktools/dk4maixdus.h
@@ -0,0 +1,135 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maixdus.cpt
+*/
+
+/*
+Copyright (C) 2017-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAIXDUS_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAIXDUS_H_INCLUDED 1
+
+
+#line 10 "dk4maixdus.cpt"
+
+/** @file
+ Retrieve unsigned short value from
+ wxChar string in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+extern "C" {
+
+/** Retrieve numeric value from string, decimal notation.
+ @param rp Pointer to result variable for the found value.
+ @param src String to check for numeric value.
+ @param endptr Address of pointer variable.
+ A pointer to the first character not processed
+ is stored here.
+ The function may also store a NULL pointer in this
+ variable.
+ @param atg Allow trailing garbage:
+ 0=no unprocessable trailing bytes allowed,
+ 1=trailing whitespaces allowed,
+ 2=any trailing characters allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ DK4_E_INVALID_ARGUMENTS if rp or src is NULL,
+ DK4_E_MATH_OVERFLOW if the number is out of range, or
+ DK4_E_SYNTAX if src contains illegal characters.
+*/
+int
+dk4ma_input_wx_dec_ushort(
+ unsigned short *rp,
+ const wxChar *src,
+ const wxChar **endptr,
+ int atg,
+ dk4_er_t *erp
+);
+
+}
+
+
+
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4mao8d.c b/support/dktools/dk4mao8d.c
new file mode 100644
index 0000000000..f0da4bb96e
--- /dev/null
+++ b/support/dktools/dk4mao8d.c
@@ -0,0 +1,190 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mao8d.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mao8d.c The dk4mao8d module.
+*/
+
+
+#line 67 "dk4mao8d.ctr"
+
+
+#include "dk4mao8d.h"
+#include "dk4numco.h"
+#include "dk4error.h"
+#include "dk4numl.h"
+
+
+
+
+
+#line 77 "dk4mao8d.ctr"
+
+
+
+int
+dk4ma_write_c8_decimal_unsigned(
+ char *dptr, size_t sz, dk4_um_t val, size_t padsz, dk4_er_t *erp
+)
+{
+ char buf[4*sizeof(dk4_um_t) + 16]; /* Buffer */
+ size_t used = 0; /* Number of used characters */
+ size_t i = 0; /* Copy buffer to destination */
+ int cc = 1; /* Flag: Can continue */
+ int err = 0; /* Flag: Error occured */
+ int back = 0; /* Function result */
+
+ if ((NULL != dptr) && (0 < sz)) {
+ *dptr = '\0';
+ }
+ if (1 == padsz) {
+ padsz = dk4numlength(sizeof(dk4_um_t), 0);
+ }
+ if ((NULL != dptr) && (0 < sz) && (padsz < sz)) {
+ do {
+ switch((int)(val % (dk4_um_t)10UL)) {
+ case 0: {
+ if(used < sizeof(buf)) { buf[used++] = '0'; } else { err = 1; }
+ } break;
+ case 1: {
+ if(used < sizeof(buf)) { buf[used++] = '1'; } else { err = 1; }
+ } break;
+ case 2: {
+ if(used < sizeof(buf)) { buf[used++] = '2'; } else { err = 1; }
+ } break;
+ case 3: {
+ if(used < sizeof(buf)) { buf[used++] = '3'; } else { err = 1; }
+ } break;
+ case 4: {
+ if(used < sizeof(buf)) { buf[used++] = '4'; } else { err = 1; }
+ } break;
+ case 5: {
+ if(used < sizeof(buf)) { buf[used++] = '5'; } else { err = 1; }
+ } break;
+ case 6: {
+ if(used < sizeof(buf)) { buf[used++] = '6'; } else { err = 1; }
+ } break;
+ case 7: {
+ if(used < sizeof(buf)) { buf[used++] = '7'; } else { err = 1; }
+ } break;
+ case 8: {
+ if(used < sizeof(buf)) { buf[used++] = '8'; } else { err = 1; }
+ } break;
+ case 9: {
+ if(used < sizeof(buf)) { buf[used++] = '9'; } else { err = 1; }
+ } break;
+ }
+ val = val / (dk4_um_t)10UL;
+ if ((dk4_um_t)0UL == val) { cc = 0; }
+ } while((1 == cc) && (0 == err));
+ if (0 == err) {
+ if (used < sz) {
+ if ((0 < padsz) && (used < padsz)) {
+ for (i = 0; i < (padsz - used); i++) {
+ dptr[i] = '0';
+ }
+ for (i = 0; i < used; i++) {
+ dptr[padsz - 1 - i] = buf[i];
+ }
+ dptr[padsz] = '\0';
+ back = 1;
+ } else {
+ for (i = 0; i < used; i++) {
+ dptr[i] = buf[used - 1 - i];
+ }
+ dptr[used] = '\0';
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4ma_write_c8_decimal_signed(
+ char *dptr, size_t sz, dk4_im_t val, size_t padsz, dk4_er_t *erp
+)
+{
+ int back = 0;
+ if ((NULL != dptr) && (0 < sz)) {
+ *dptr = '\0';
+ }
+ if (1 == padsz) {
+ padsz = dk4numlength(sizeof(dk4_im_t), 1);
+ }
+ if ((NULL != dptr) && (0 < sz) && (padsz < sz)) {
+ if ((dk4_im_t)0L <= val) {
+ back = dk4ma_write_c8_decimal_unsigned(
+ dptr, sz,
+ (dk4_um_t)val,
+ padsz,
+ erp
+ );
+ } else {
+ if (2 < sz) {
+ *(dptr++) = '-'; sz--;
+ if (DK4_IM_MIN == val) {
+ back = dk4ma_write_c8_decimal_unsigned(
+ dptr, sz,
+ ((dk4_um_t)(DK4_IM_MAX) + (dk4_um_t)1UL),
+ ((0 < padsz) ? (padsz - 1) : (0)),
+ erp
+ );
+ } else {
+ back = dk4ma_write_c8_decimal_unsigned(
+ dptr, sz,
+ (dk4_um_t)((dk4_im_t)0L - val),
+ ((0 < padsz) ? (padsz - 1) : 0),
+ erp
+ );
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4mao8d.ctr b/support/dktools/dk4mao8d.ctr
new file mode 100644
index 0000000000..cb7fdf5e13
--- /dev/null
+++ b/support/dktools/dk4mao8d.ctr
@@ -0,0 +1,214 @@
+%% options
+
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ Convert dk4_um_t / dk4_im_t
+ to 8 bit character strings in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Write unsigned number to char string in decimal notation.
+ @param dptr Pointer to buffer for string.
+ @param sz Buffer size (number of char).
+ @param val Value to write.
+ @param padsz Size for padding.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4ma_write_c8_decimal_unsigned(
+ char *dptr, size_t sz, dk4_um_t val, size_t padsz, dk4_er_t *erp
+);
+
+/** Write signed number to char string in decimal notation.
+ @param dptr Pointer to buffer for string.
+ @param sz Buffer size (number of char).
+ @param val Value to write.
+ @param padsz Size for padding.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4ma_write_c8_decimal_signed(
+ char *dptr, size_t sz, dk4_im_t val, size_t padsz, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+
+#include "dk4mao8d.h"
+#include "dk4numco.h"
+#include "dk4error.h"
+#include "dk4numl.h"
+
+
+
+$!trace-include
+
+
+
+int
+dk4ma_write_c8_decimal_unsigned(
+ char *dptr, size_t sz, dk4_um_t val, size_t padsz, dk4_er_t *erp
+)
+{
+ char buf[4*sizeof(dk4_um_t) + 16]; /* Buffer */
+ size_t used = 0; /* Number of used characters */
+ size_t i = 0; /* Copy buffer to destination */
+ int cc = 1; /* Flag: Can continue */
+ int err = 0; /* Flag: Error occured */
+ int back = 0; /* Function result */
+
+ if ((NULL != dptr) && (0 < sz)) {
+ *dptr = '\0';
+ }
+ if (1 == padsz) {
+ padsz = dk4numlength(sizeof(dk4_um_t), 0);
+ }
+ if ((NULL != dptr) && (0 < sz) && (padsz < sz)) {
+ do {
+ switch((int)(val % (dk4_um_t)10UL)) {
+ case 0: {
+ if(used < sizeof(buf)) { buf[used++] = '0'; } else { err = 1; }
+ } break;
+ case 1: {
+ if(used < sizeof(buf)) { buf[used++] = '1'; } else { err = 1; }
+ } break;
+ case 2: {
+ if(used < sizeof(buf)) { buf[used++] = '2'; } else { err = 1; }
+ } break;
+ case 3: {
+ if(used < sizeof(buf)) { buf[used++] = '3'; } else { err = 1; }
+ } break;
+ case 4: {
+ if(used < sizeof(buf)) { buf[used++] = '4'; } else { err = 1; }
+ } break;
+ case 5: {
+ if(used < sizeof(buf)) { buf[used++] = '5'; } else { err = 1; }
+ } break;
+ case 6: {
+ if(used < sizeof(buf)) { buf[used++] = '6'; } else { err = 1; }
+ } break;
+ case 7: {
+ if(used < sizeof(buf)) { buf[used++] = '7'; } else { err = 1; }
+ } break;
+ case 8: {
+ if(used < sizeof(buf)) { buf[used++] = '8'; } else { err = 1; }
+ } break;
+ case 9: {
+ if(used < sizeof(buf)) { buf[used++] = '9'; } else { err = 1; }
+ } break;
+ }
+ val = val / (dk4_um_t)10UL;
+ if ((dk4_um_t)0UL == val) { cc = 0; }
+ } while((1 == cc) && (0 == err));
+ if (0 == err) {
+ if (used < sz) {
+ if ((0 < padsz) && (used < padsz)) {
+ for (i = 0; i < (padsz - used); i++) {
+ dptr[i] = '0';
+ }
+ for (i = 0; i < used; i++) {
+ dptr[padsz - 1 - i] = buf[i];
+ }
+ dptr[padsz] = '\0';
+ back = 1;
+ } else {
+ for (i = 0; i < used; i++) {
+ dptr[i] = buf[used - 1 - i];
+ }
+ dptr[used] = '\0';
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4ma_write_c8_decimal_signed(
+ char *dptr, size_t sz, dk4_im_t val, size_t padsz, dk4_er_t *erp
+)
+{
+ int back = 0;
+ if ((NULL != dptr) && (0 < sz)) {
+ *dptr = '\0';
+ }
+ if (1 == padsz) {
+ padsz = dk4numlength(sizeof(dk4_im_t), 1);
+ }
+ if ((NULL != dptr) && (0 < sz) && (padsz < sz)) {
+ if ((dk4_im_t)0L <= val) {
+ back = dk4ma_write_c8_decimal_unsigned(
+ dptr, sz,
+ (dk4_um_t)val,
+ padsz,
+ erp
+ );
+ } else {
+ if (2 < sz) {
+ *(dptr++) = '-'; sz--;
+ if (DK4_IM_MIN == val) {
+ back = dk4ma_write_c8_decimal_unsigned(
+ dptr, sz,
+ ((dk4_um_t)(DK4_IM_MAX) + (dk4_um_t)1UL),
+ ((0 < padsz) ? (padsz - 1) : (0)),
+ erp
+ );
+ } else {
+ back = dk4ma_write_c8_decimal_unsigned(
+ dptr, sz,
+ (dk4_um_t)((dk4_im_t)0L - val),
+ ((0 < padsz) ? (padsz - 1) : 0),
+ erp
+ );
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4mao8d.h b/support/dktools/dk4mao8d.h
new file mode 100644
index 0000000000..90d6fe573e
--- /dev/null
+++ b/support/dktools/dk4mao8d.h
@@ -0,0 +1,99 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mao8d.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAO8D_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAO8D_H_INCLUDED 1
+
+
+#line 10 "dk4mao8d.ctr"
+
+/** @file
+ Convert dk4_um_t / dk4_im_t
+ to 8 bit character strings in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Write unsigned number to char string in decimal notation.
+ @param dptr Pointer to buffer for string.
+ @param sz Buffer size (number of char).
+ @param val Value to write.
+ @param padsz Size for padding.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4ma_write_c8_decimal_unsigned(
+ char *dptr, size_t sz, dk4_um_t val, size_t padsz, dk4_er_t *erp
+);
+
+/** Write signed number to char string in decimal notation.
+ @param dptr Pointer to buffer for string.
+ @param sz Buffer size (number of char).
+ @param val Value to write.
+ @param padsz Size for padding.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4ma_write_c8_decimal_signed(
+ char *dptr, size_t sz, dk4_im_t val, size_t padsz, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4mao8dbl.c b/support/dktools/dk4mao8dbl.c
new file mode 100644
index 0000000000..fb1ac5804e
--- /dev/null
+++ b/support/dktools/dk4mao8dbl.c
@@ -0,0 +1,359 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mao8dbl.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mao8dbl.c The dk4mao8dbl module.
+*/
+
+
+#line 66 "dk4mao8dbl.ctr"
+
+#include "dk4mao8dbl.h"
+#include "dk4str8.h"
+
+
+#if DK4_HAVE_LOCALE_H
+#ifndef LOCALE_H_INCLUDED
+#include <locale.h>
+#define LOCALE_H_INCLUDED 1
+#endif
+#endif
+
+
+
+
+
+#line 81 "dk4mao8dbl.ctr"
+
+
+
+/** Format strings used for printf family.
+*/
+static const char * const dk4double_format_strings[] = {
+/* 0 */ "%.*e",
+/* 1 */ "%g",
+/* 2 */ "C"
+};
+
+
+
+/** Squeeze a double written to string.
+ @param buf Buffer containing the string.
+*/
+static
+void
+dk4double_squeeze_c8_string(char *buf)
+{
+ char *ptre = NULL;
+ char *ptrdot = NULL;
+ char *ptrcom = NULL;
+ char *ptrcut = NULL;
+ char *ptr;
+ int useexp = 1;
+
+
+#line 108 "dk4mao8dbl.ctr"
+ if (NULL != buf) {
+ ptr = buf;
+ while('\0' != *ptr) {
+ switch (*ptr) {
+ case 'e': case 'E': {
+
+#line 113 "dk4mao8dbl.ctr"
+ if (NULL == ptre) { ptre = ptr; }
+ } break;
+ case '.': {
+
+#line 116 "dk4mao8dbl.ctr"
+ if (NULL == ptrdot) { ptrdot = ptr; }
+ } break;
+ case ',': {
+ if (NULL == ptrcom) { ptrcom = ptr; }
+ } break;
+ }
+ ptr++;
+ }
+ if (NULL != ptre) {
+
+#line 125 "dk4mao8dbl.ctr"
+ *ptre = '\0';
+ ptr = ptre;
+ ptr++;
+
+#line 128 "dk4mao8dbl.ctr"
+ if (('+' == *ptr) || ('0' == *ptr)) {
+
+#line 129 "dk4mao8dbl.ctr"
+ useexp = 0;
+
+#line 130 "dk4mao8dbl.ctr"
+ ptr++;
+ while('\0' != *ptr) {
+
+#line 132 "dk4mao8dbl.ctr"
+ if ('0' != *ptr) {
+
+#line 133 "dk4mao8dbl.ctr"
+ useexp = 1;
+
+#line 134 "dk4mao8dbl.ctr"
+ }
+ ptr++;
+ }
+ }
+ }
+ if (NULL != ptrdot) {
+ ptrdot++;
+ if ('\0' != *ptrdot) {
+
+#line 142 "dk4mao8dbl.ctr"
+ ptrdot++;
+ while('\0' != *ptrdot) {
+
+#line 144 "dk4mao8dbl.ctr"
+ if ('0' == *ptrdot) {
+ if (NULL == ptrcut) {
+ ptrcut = ptrdot;
+
+#line 147 "dk4mao8dbl.ctr"
+ }
+ } else {
+ ptrcut = NULL;
+
+#line 150 "dk4mao8dbl.ctr"
+ }
+ ptrdot++;
+ }
+ }
+ } else {
+ if (NULL != ptrcom) {
+ ptrcom++;
+ if ('\0' != *ptrcom) {
+ ptrcom++;
+ while ('\0' != *ptrcom) {
+ if ('0' == *ptrcom) {
+ if (NULL == ptrcut) {
+ ptrcut = ptrcom;
+ }
+ } else {
+ ptrcut = NULL;
+ }
+ ptrcom++;
+ }
+ }
+ }
+ }
+ if ((NULL != ptre) && (0 != useexp)) {
+ *ptre = 'e';
+ }
+ if (NULL != ptrcut) {
+ if ((NULL != ptre) && (0 != useexp)) {
+ while ('\0' != *ptre) {
+ *(ptrcut++) = *(ptre++);
+ }
+ }
+ *ptrcut = '\0';
+ }
+ }
+
+
+#line 185 "dk4mao8dbl.ctr"
+}
+
+
+
+static
+int
+dk4ma_internal_write_c8_double(
+ char *dptr, size_t szdptr, double v, int exact, int minimize, dk4_er_t *erp
+)
+{
+#if DK4_HAVE__SNPRINTF_S
+ /* +++ _snprintf_s */
+ char buf[64];
+ int back = 0;
+ int res = 0;
+ if (NULL != dptr) { *dptr = '\0'; }
+ if ((NULL != dptr) && (1 < szdptr)) {
+ if (0 != exact) {
+ res = _snprintf_s(
+ buf, sizeof(buf), _TRUNCATE, dk4double_format_strings[0],
+ (int)DK4_DBL_DIGITS, v
+ );
+ if ((0 < res) && ((size_t)res < sizeof(buf))) {
+ buf[res] = '\0';
+ if (0 != minimize) {
+ dk4double_squeeze_c8_string(buf);
+ }
+ back = dk4str8_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ res = _snprintf_s(
+ buf, sizeof(buf), _TRUNCATE, dk4double_format_strings[1], v
+ );
+ if ((0 < res) && ((size_t)res < sizeof(buf))) {
+ buf[res] = '\0';
+ back = dk4str8_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* --- _snprintf_s */
+#else
+#if DK4_HAVE__SNPRINTF
+ /* +++ _snprintf */
+ char buf[64];
+ int back = 0;
+ int res = 0;
+ if (NULL != dptr) { *dptr = '\0'; }
+ if ((NULL != dptr) && (1 < szdptr)) {
+ if (0 != exact) {
+ res = _snprintf(
+ buf, sizeof(buf), dk4double_format_strings[0], (int)DK4_DBL_DIGITS, v
+ );
+ if ((0 < res) && ((size_t)res < sizeof(buf))) {
+ buf[res] = '\0';
+ if (0 != minimize) {
+ dk4double_squeeze_c8_string(buf);
+ }
+ back = dk4str8_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ res = _snprintf(buf, sizeof(buf), dk4double_format_strings[1], v);
+ if ((0 < res) && ((size_t)res < sizeof(buf))) {
+ buf[res] = '\0';
+ back = dk4str8_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* --- _snprintf */
+#else
+#if DK4_HAVE_SNPRINTF
+ /* +++ snprintf */
+ char buf[64];
+ int back = 0;
+ int res = 0;
+ if (NULL != dptr) { *dptr = '\0'; }
+ if ((NULL != dptr) && (1 < szdptr)) {
+ if (0 != exact) {
+ res = snprintf(
+ buf, sizeof(buf), dk4double_format_strings[0], (int)DK4_DBL_DIGITS, v
+ );
+ if ((0 < res) && ((size_t)res < sizeof(buf))) {
+ buf[res] = '\0';
+ if (0 != minimize) {
+ dk4double_squeeze_c8_string(buf);
+ }
+ back = dk4str8_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ res = snprintf(buf, sizeof(buf), dk4double_format_strings[1], v);
+ if ((0 < res) && ((size_t)res < sizeof(buf))) {
+ buf[res] = '\0';
+ back = dk4str8_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* --- snprintf */
+#else
+ /* +++ sprintf */
+ char buf[64];
+ int back = 0;
+ int res = 0;
+ if (NULL != dptr) { *dptr = '\0'; }
+ if ((NULL != dptr) && (1 < szdptr)) {
+ if (0 != exact) {
+ sprintf(buf, dk4double_format_strings[0], (int)DK4_DBL_DIGITS, v);
+ if (0 != minimize) {
+ dk4double_squeeze_c8_string(buf);
+ }
+ back = dk4str8_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ sprintf(buf, dk4double_format_strings[1], v);
+ back = dk4str8_cpy_s(dptr, szdptr, buf, erp);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* --- sprintf */
+#endif
+#endif
+#endif
+}
+
+
+
+int
+dk4ma_write_c8_double(
+ char *dptr, size_t szdptr, double v, int exact, int minimize, dk4_er_t *erp
+)
+{
+#if (DK4_HAVE_SETLOCALE) && defined(LC_NUMERIC)
+ char *oldloc = NULL;
+#endif
+ int back = 0;
+
+#if (DK4_HAVE_SETLOCALE) && defined(LC_NUMERIC)
+ oldloc = setlocale(LC_NUMERIC, NULL);
+ (void)setlocale(LC_NUMERIC, dk4double_format_strings[2]);
+#endif
+ back = dk4ma_internal_write_c8_double(dptr, szdptr, v, exact, minimize, erp);
+#if (DK4_HAVE_SETLOCALE) && defined(LC_NUMERIC)
+ (void)setlocale(LC_NUMERIC, oldloc);
+#endif
+ return back;
+}
+
+
diff --git a/support/dktools/dk4mao8dbl.ctr b/support/dktools/dk4mao8dbl.ctr
new file mode 100644
index 0000000000..f9e7683ac5
--- /dev/null
+++ b/support/dktools/dk4mao8dbl.ctr
@@ -0,0 +1,352 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ Double to char text conversion using the more secure functions
+ _snprintf_s(), _snprintf() or snprintf() instead of sprintf()
+ if available.
+
+ CRT on Windows: Required.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert double value to string.
+ @param dptr Destination buffer pointer.
+ @param szdptr Size of destination buffer.
+ @param v Value to convert.
+ @param exact Flag: Create exact representation.
+ @param minimize Minimize exact representation.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or szdptr is less than 2,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the destination buffer is too small to store the string.
+*/
+int
+dk4ma_write_c8_double(
+ char *dptr, size_t szdptr, double v, int exact, int minimize, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4mao8dbl.h"
+#include "dk4str8.h"
+
+
+#if DK4_HAVE_LOCALE_H
+#ifndef LOCALE_H_INCLUDED
+#include <locale.h>
+#define LOCALE_H_INCLUDED 1
+#endif
+#endif
+
+
+
+$!trace-include
+
+
+
+/** Format strings used for printf family.
+*/
+static const char * const dk4double_format_strings[] = {
+/* 0 */ "%.*e",
+/* 1 */ "%g",
+/* 2 */ "C"
+};
+
+
+
+/** Squeeze a double written to string.
+ @param buf Buffer containing the string.
+*/
+static
+void
+dk4double_squeeze_c8_string(char *buf)
+{
+ char *ptre = NULL;
+ char *ptrdot = NULL;
+ char *ptrcom = NULL;
+ char *ptrcut = NULL;
+ char *ptr;
+ int useexp = 1;
+ $? "+ dk4double_squeeze_c8_string \"%s\"", TR_8STR(buf)
+ if (NULL != buf) {
+ ptr = buf;
+ while('\0' != *ptr) {
+ switch (*ptr) {
+ case 'e': case 'E': { $? ". exponent found"
+ if (NULL == ptre) { ptre = ptr; }
+ } break;
+ case '.': { $? ". dot found"
+ if (NULL == ptrdot) { ptrdot = ptr; }
+ } break;
+ case ',': {
+ if (NULL == ptrcom) { ptrcom = ptr; }
+ } break;
+ }
+ ptr++;
+ }
+ if (NULL != ptre) { $? ". check exponent"
+ *ptre = '\0';
+ ptr = ptre;
+ ptr++; $? ". c=\"%c\"", *ptr
+ if (('+' == *ptr) || ('0' == *ptr)) { $? ". leading + or 0"
+ useexp = 0; $? ". useexp = 0"
+ ptr++;
+ while('\0' != *ptr) { $? ". c=\"%c\"", *ptr
+ if ('0' != *ptr) { $? ". non-0 char \"%c\"", *ptr
+ useexp = 1; $? ". useexp = 1"
+ }
+ ptr++;
+ }
+ }
+ }
+ if (NULL != ptrdot) {
+ ptrdot++;
+ if ('\0' != *ptrdot) { $? ". chars after dot"
+ ptrdot++;
+ while('\0' != *ptrdot) { $? ". check \"%c\"", *ptrdot
+ if ('0' == *ptrdot) {
+ if (NULL == ptrcut) {
+ ptrcut = ptrdot; $? ". cut"
+ }
+ } else {
+ ptrcut = NULL; $? ". no cut"
+ }
+ ptrdot++;
+ }
+ }
+ } else {
+ if (NULL != ptrcom) {
+ ptrcom++;
+ if ('\0' != *ptrcom) {
+ ptrcom++;
+ while ('\0' != *ptrcom) {
+ if ('0' == *ptrcom) {
+ if (NULL == ptrcut) {
+ ptrcut = ptrcom;
+ }
+ } else {
+ ptrcut = NULL;
+ }
+ ptrcom++;
+ }
+ }
+ }
+ }
+ if ((NULL != ptre) && (0 != useexp)) {
+ *ptre = 'e';
+ }
+ if (NULL != ptrcut) {
+ if ((NULL != ptre) && (0 != useexp)) {
+ while ('\0' != *ptre) {
+ *(ptrcut++) = *(ptre++);
+ }
+ }
+ *ptrcut = '\0';
+ }
+ }
+ $? "- dk4double_squeeze_c8_string \"%s\"", TR_8STR(buf)
+}
+
+
+
+static
+int
+dk4ma_internal_write_c8_double(
+ char *dptr, size_t szdptr, double v, int exact, int minimize, dk4_er_t *erp
+)
+{
+#if DK4_HAVE__SNPRINTF_S
+ /* +++ _snprintf_s */
+ char buf[64];
+ int back = 0;
+ int res = 0;
+ if (NULL != dptr) { *dptr = '\0'; }
+ if ((NULL != dptr) && (1 < szdptr)) {
+ if (0 != exact) {
+ res = _snprintf_s(
+ buf, sizeof(buf), _TRUNCATE, dk4double_format_strings[0],
+ (int)DK4_DBL_DIGITS, v
+ );
+ if ((0 < res) && ((size_t)res < sizeof(buf))) {
+ buf[res] = '\0';
+ if (0 != minimize) {
+ dk4double_squeeze_c8_string(buf);
+ }
+ back = dk4str8_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ res = _snprintf_s(
+ buf, sizeof(buf), _TRUNCATE, dk4double_format_strings[1], v
+ );
+ if ((0 < res) && ((size_t)res < sizeof(buf))) {
+ buf[res] = '\0';
+ back = dk4str8_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* --- _snprintf_s */
+#else
+#if DK4_HAVE__SNPRINTF
+ /* +++ _snprintf */
+ char buf[64];
+ int back = 0;
+ int res = 0;
+ if (NULL != dptr) { *dptr = '\0'; }
+ if ((NULL != dptr) && (1 < szdptr)) {
+ if (0 != exact) {
+ res = _snprintf(
+ buf, sizeof(buf), dk4double_format_strings[0], (int)DK4_DBL_DIGITS, v
+ );
+ if ((0 < res) && ((size_t)res < sizeof(buf))) {
+ buf[res] = '\0';
+ if (0 != minimize) {
+ dk4double_squeeze_c8_string(buf);
+ }
+ back = dk4str8_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ res = _snprintf(buf, sizeof(buf), dk4double_format_strings[1], v);
+ if ((0 < res) && ((size_t)res < sizeof(buf))) {
+ buf[res] = '\0';
+ back = dk4str8_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* --- _snprintf */
+#else
+#if DK4_HAVE_SNPRINTF
+ /* +++ snprintf */
+ char buf[64];
+ int back = 0;
+ int res = 0;
+ if (NULL != dptr) { *dptr = '\0'; }
+ if ((NULL != dptr) && (1 < szdptr)) {
+ if (0 != exact) {
+ res = snprintf(
+ buf, sizeof(buf), dk4double_format_strings[0], (int)DK4_DBL_DIGITS, v
+ );
+ if ((0 < res) && ((size_t)res < sizeof(buf))) {
+ buf[res] = '\0';
+ if (0 != minimize) {
+ dk4double_squeeze_c8_string(buf);
+ }
+ back = dk4str8_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ res = snprintf(buf, sizeof(buf), dk4double_format_strings[1], v);
+ if ((0 < res) && ((size_t)res < sizeof(buf))) {
+ buf[res] = '\0';
+ back = dk4str8_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* --- snprintf */
+#else
+ /* +++ sprintf */
+ char buf[64];
+ int back = 0;
+ int res = 0;
+ if (NULL != dptr) { *dptr = '\0'; }
+ if ((NULL != dptr) && (1 < szdptr)) {
+ if (0 != exact) {
+ sprintf(buf, dk4double_format_strings[0], (int)DK4_DBL_DIGITS, v);
+ if (0 != minimize) {
+ dk4double_squeeze_c8_string(buf);
+ }
+ back = dk4str8_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ sprintf(buf, dk4double_format_strings[1], v);
+ back = dk4str8_cpy_s(dptr, szdptr, buf, erp);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* --- sprintf */
+#endif
+#endif
+#endif
+}
+
+
+
+int
+dk4ma_write_c8_double(
+ char *dptr, size_t szdptr, double v, int exact, int minimize, dk4_er_t *erp
+)
+{
+#if (DK4_HAVE_SETLOCALE) && defined(LC_NUMERIC)
+ char *oldloc = NULL;
+#endif
+ int back = 0;
+
+#if (DK4_HAVE_SETLOCALE) && defined(LC_NUMERIC)
+ oldloc = setlocale(LC_NUMERIC, NULL);
+ (void)setlocale(LC_NUMERIC, dk4double_format_strings[2]);
+#endif
+ back = dk4ma_internal_write_c8_double(dptr, szdptr, v, exact, minimize, erp);
+#if (DK4_HAVE_SETLOCALE) && defined(LC_NUMERIC)
+ (void)setlocale(LC_NUMERIC, oldloc);
+#endif
+ return back;
+}
+
+
diff --git a/support/dktools/dk4mao8dbl.h b/support/dktools/dk4mao8dbl.h
new file mode 100644
index 0000000000..ef28840734
--- /dev/null
+++ b/support/dktools/dk4mao8dbl.h
@@ -0,0 +1,99 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mao8dbl.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAO8DBL_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAO8DBL_H_INCLUDED 1
+
+
+#line 9 "dk4mao8dbl.ctr"
+
+/** @file
+ Double to char text conversion using the more secure functions
+ _snprintf_s(), _snprintf() or snprintf() instead of sprintf()
+ if available.
+
+ CRT on Windows: Required.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert double value to string.
+ @param dptr Destination buffer pointer.
+ @param szdptr Size of destination buffer.
+ @param v Value to convert.
+ @param exact Flag: Create exact representation.
+ @param minimize Minimize exact representation.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or szdptr is less than 2,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the destination buffer is too small to store the string.
+*/
+int
+dk4ma_write_c8_double(
+ char *dptr, size_t szdptr, double v, int exact, int minimize, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4mao8h.c b/support/dktools/dk4mao8h.c
new file mode 100644
index 0000000000..5865852fe6
--- /dev/null
+++ b/support/dktools/dk4mao8h.c
@@ -0,0 +1,218 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mao8h.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mao8h.c The dk4mao8h module.
+*/
+
+
+#line 67 "dk4mao8h.ctr"
+
+
+#include "dk4mao8h.h"
+#include "dk4numco.h"
+#include "dk4error.h"
+
+
+
+
+
+#line 76 "dk4mao8h.ctr"
+
+
+
+int
+dk4ma_write_c8_hex_unsigned(
+ char *dptr, size_t sz, dk4_um_t val, size_t padsz, dk4_er_t *erp
+)
+{
+ char buf[4*sizeof(dk4_um_t) + 16]; /* Buffer */
+ size_t used = 0; /* Number of used characters */
+ size_t i = 0; /* Copy buffer to destination */
+ int cc = 1; /* Flag: Can continue */
+ int err = 0; /* Flag: Error occued */
+ int back = 0; /* Function result */
+
+
+#line 91 "dk4mao8h.ctr"
+ if (NULL != dptr) { *dptr = '\0'; }
+ if (1 == padsz) { padsz = 2 * sizeof(dk4_um_t); }
+ if ((NULL != dptr) && (0 < sz) && (padsz < sz)) {
+
+#line 94 "dk4mao8h.ctr"
+ do {
+
+#line 95 "dk4mao8h.ctr"
+ switch((int)(val % (dk4_um_t)16UL)) {
+ case 0: {
+
+#line 97 "dk4mao8h.ctr"
+ if(used < sizeof(buf)) { buf[used++] = '0'; } else { err = 1; }
+ } break;
+ case 1: {
+
+#line 100 "dk4mao8h.ctr"
+ if(used < sizeof(buf)) { buf[used++] = '1'; } else { err = 1; }
+ } break;
+ case 2: {
+
+#line 103 "dk4mao8h.ctr"
+ if(used < sizeof(buf)) { buf[used++] = '2'; } else { err = 1; }
+ } break;
+ case 3: {
+
+#line 106 "dk4mao8h.ctr"
+ if(used < sizeof(buf)) { buf[used++] = '3'; } else { err = 1; }
+ } break;
+ case 4: {
+
+#line 109 "dk4mao8h.ctr"
+ if(used < sizeof(buf)) { buf[used++] = '4'; } else { err = 1; }
+ } break;
+ case 5: {
+
+#line 112 "dk4mao8h.ctr"
+ if(used < sizeof(buf)) { buf[used++] = '5'; } else { err = 1; }
+ } break;
+ case 6: {
+
+#line 115 "dk4mao8h.ctr"
+ if(used < sizeof(buf)) { buf[used++] = '6'; } else { err = 1; }
+ } break;
+ case 7: {
+
+#line 118 "dk4mao8h.ctr"
+ if(used < sizeof(buf)) { buf[used++] = '7'; } else { err = 1; }
+ } break;
+ case 8: {
+
+#line 121 "dk4mao8h.ctr"
+ if(used < sizeof(buf)) { buf[used++] = '8'; } else { err = 1; }
+ } break;
+ case 9: {
+
+#line 124 "dk4mao8h.ctr"
+ if(used < sizeof(buf)) { buf[used++] = '9'; } else { err = 1; }
+ } break;
+ case 10: {
+
+#line 127 "dk4mao8h.ctr"
+ if(used < sizeof(buf)) { buf[used++] = 'A'; } else { err = 1; }
+ } break;
+ case 11: {
+
+#line 130 "dk4mao8h.ctr"
+ if(used < sizeof(buf)) { buf[used++] = 'B'; } else { err = 1; }
+ } break;
+ case 12: {
+
+#line 133 "dk4mao8h.ctr"
+ if(used < sizeof(buf)) { buf[used++] = 'C'; } else { err = 1; }
+ } break;
+ case 13: {
+
+#line 136 "dk4mao8h.ctr"
+ if(used < sizeof(buf)) { buf[used++] = 'D'; } else { err = 1; }
+ } break;
+ case 14: {
+
+#line 139 "dk4mao8h.ctr"
+ if(used < sizeof(buf)) { buf[used++] = 'E'; } else { err = 1; }
+ } break;
+ case 15: {
+
+#line 142 "dk4mao8h.ctr"
+ if(used < sizeof(buf)) { buf[used++] = 'F'; } else { err = 1; }
+ } break;
+ }
+ val = val / (dk4_um_t)16UL;
+ if ((dk4_um_t)0UL == val) { cc = 0; }
+ } while((1 == cc) && (0 == err));
+ if (0 == err) {
+
+#line 149 "dk4mao8h.ctr"
+ if (used < sz) {
+
+#line 150 "dk4mao8h.ctr"
+ if ((0 < padsz) && (used < padsz)) {
+
+#line 151 "dk4mao8h.ctr"
+ for (i = 0; i < (padsz - used); i++) {
+ dptr[i] = '0';
+ }
+ for (i = 0; i < used; i++) {
+ dptr[padsz - 1 - i] = buf[i];
+ }
+ dptr[padsz] = '\0';
+ back = 1;
+ } else {
+
+#line 160 "dk4mao8h.ctr"
+ for (i = 0; i < used; i++) {
+ dptr[i] = buf[used - 1 - i];
+ }
+ dptr[used] = '\0';
+ back = 1;
+ }
+ } else {
+
+#line 167 "dk4mao8h.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+
+#line 170 "dk4mao8h.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ } else {
+
+#line 173 "dk4mao8h.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 176 "dk4mao8h.ctr"
+ return back;
+}
+
+
+
+int
+dk4ma_write_c8_hex_signed(
+ char *dptr, size_t sz, dk4_im_t val, size_t padsz, dk4_er_t *erp
+)
+{
+ return (dk4ma_write_c8_hex_unsigned(dptr, sz, (dk4_um_t)val, padsz, erp));
+}
+
diff --git a/support/dktools/dk4mao8h.ctr b/support/dktools/dk4mao8h.ctr
new file mode 100644
index 0000000000..84e23cd28e
--- /dev/null
+++ b/support/dktools/dk4mao8h.ctr
@@ -0,0 +1,188 @@
+%% options
+
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ Convert dk4_um_t / dk4_im_t
+ to 8 bit character strings in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Write unsigned number to char string in hex notation.
+ @param dptr Pointer to buffer for string.
+ @param sz Buffer size (number of char).
+ @param val Value to write.
+ @param padsz Minimum number of digits, 1 for automatic choice.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4ma_write_c8_hex_unsigned(
+ char *dptr, size_t sz, dk4_um_t val, size_t padsz, dk4_er_t *erp
+);
+
+/** Write signed number to char string in hex notation.
+ @param dptr Pointer to buffer for string.
+ @param sz Buffer size (number of char).
+ @param val Value to write.
+ @param padsz Minimum number of digits, 1 for automatic choice.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4ma_write_c8_hex_signed(
+ char *dptr, size_t sz, dk4_im_t val, size_t padsz, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+
+#include "dk4mao8h.h"
+#include "dk4numco.h"
+#include "dk4error.h"
+
+
+
+$!trace-include
+
+
+
+int
+dk4ma_write_c8_hex_unsigned(
+ char *dptr, size_t sz, dk4_um_t val, size_t padsz, dk4_er_t *erp
+)
+{
+ char buf[4*sizeof(dk4_um_t) + 16]; /* Buffer */
+ size_t used = 0; /* Number of used characters */
+ size_t i = 0; /* Copy buffer to destination */
+ int cc = 1; /* Flag: Can continue */
+ int err = 0; /* Flag: Error occued */
+ int back = 0; /* Function result */
+ $? "+ dk4ma_write_c8_hex_unsigned"
+ if (NULL != dptr) { *dptr = '\0'; }
+ if (1 == padsz) { padsz = 2 * sizeof(dk4_um_t); }
+ if ((NULL != dptr) && (0 < sz) && (padsz < sz)) { $? ". args"
+ do { $? ". loop start"
+ switch((int)(val % (dk4_um_t)16UL)) {
+ case 0: { $? ". 0"
+ if(used < sizeof(buf)) { buf[used++] = '0'; } else { err = 1; }
+ } break;
+ case 1: { $? ". 1"
+ if(used < sizeof(buf)) { buf[used++] = '1'; } else { err = 1; }
+ } break;
+ case 2: { $? ". 2"
+ if(used < sizeof(buf)) { buf[used++] = '2'; } else { err = 1; }
+ } break;
+ case 3: { $? ". 3"
+ if(used < sizeof(buf)) { buf[used++] = '3'; } else { err = 1; }
+ } break;
+ case 4: { $? ". 4"
+ if(used < sizeof(buf)) { buf[used++] = '4'; } else { err = 1; }
+ } break;
+ case 5: { $? ". 5"
+ if(used < sizeof(buf)) { buf[used++] = '5'; } else { err = 1; }
+ } break;
+ case 6: { $? ". 6"
+ if(used < sizeof(buf)) { buf[used++] = '6'; } else { err = 1; }
+ } break;
+ case 7: { $? ". 7"
+ if(used < sizeof(buf)) { buf[used++] = '7'; } else { err = 1; }
+ } break;
+ case 8: { $? ". 8"
+ if(used < sizeof(buf)) { buf[used++] = '8'; } else { err = 1; }
+ } break;
+ case 9: { $? ". 9"
+ if(used < sizeof(buf)) { buf[used++] = '9'; } else { err = 1; }
+ } break;
+ case 10: { $? ". A"
+ if(used < sizeof(buf)) { buf[used++] = 'A'; } else { err = 1; }
+ } break;
+ case 11: { $? ". B"
+ if(used < sizeof(buf)) { buf[used++] = 'B'; } else { err = 1; }
+ } break;
+ case 12: { $? ". C"
+ if(used < sizeof(buf)) { buf[used++] = 'C'; } else { err = 1; }
+ } break;
+ case 13: { $? ". D"
+ if(used < sizeof(buf)) { buf[used++] = 'D'; } else { err = 1; }
+ } break;
+ case 14: { $? ". E"
+ if(used < sizeof(buf)) { buf[used++] = 'E'; } else { err = 1; }
+ } break;
+ case 15: { $? ". F"
+ if(used < sizeof(buf)) { buf[used++] = 'F'; } else { err = 1; }
+ } break;
+ }
+ val = val / (dk4_um_t)16UL;
+ if ((dk4_um_t)0UL == val) { cc = 0; }
+ } while((1 == cc) && (0 == err));
+ if (0 == err) { $? ". no error"
+ if (used < sz) { $? ". sufficient place"
+ if ((0 < padsz) && (used < padsz)) { $? ". padding"
+ for (i = 0; i < (padsz - used); i++) {
+ dptr[i] = '0';
+ }
+ for (i = 0; i < used; i++) {
+ dptr[padsz - 1 - i] = buf[i];
+ }
+ dptr[padsz] = '\0';
+ back = 1;
+ } else { $? ". no padding"
+ for (i = 0; i < used; i++) {
+ dptr[i] = buf[used - 1 - i];
+ }
+ dptr[used] = '\0';
+ back = 1;
+ }
+ } else { $? "! insufficient place"
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else { $? "! error"
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ } else { $? "! args"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4ma_write_c8_hex_unsigned %d", back
+ return back;
+}
+
+
+
+int
+dk4ma_write_c8_hex_signed(
+ char *dptr, size_t sz, dk4_im_t val, size_t padsz, dk4_er_t *erp
+)
+{
+ return (dk4ma_write_c8_hex_unsigned(dptr, sz, (dk4_um_t)val, padsz, erp));
+}
+
diff --git a/support/dktools/dk4mao8h.h b/support/dktools/dk4mao8h.h
new file mode 100644
index 0000000000..c3b158add3
--- /dev/null
+++ b/support/dktools/dk4mao8h.h
@@ -0,0 +1,99 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mao8h.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAO8H_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAO8H_H_INCLUDED 1
+
+
+#line 10 "dk4mao8h.ctr"
+
+/** @file
+ Convert dk4_um_t / dk4_im_t
+ to 8 bit character strings in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Write unsigned number to char string in hex notation.
+ @param dptr Pointer to buffer for string.
+ @param sz Buffer size (number of char).
+ @param val Value to write.
+ @param padsz Minimum number of digits, 1 for automatic choice.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4ma_write_c8_hex_unsigned(
+ char *dptr, size_t sz, dk4_um_t val, size_t padsz, dk4_er_t *erp
+);
+
+/** Write signed number to char string in hex notation.
+ @param dptr Pointer to buffer for string.
+ @param sz Buffer size (number of char).
+ @param val Value to write.
+ @param padsz Minimum number of digits, 1 for automatic choice.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4ma_write_c8_hex_signed(
+ char *dptr, size_t sz, dk4_im_t val, size_t padsz, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maodd.c b/support/dktools/dk4maodd.c
new file mode 100644
index 0000000000..606e610cf3
--- /dev/null
+++ b/support/dktools/dk4maodd.c
@@ -0,0 +1,85 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maodd.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maodd.c The dk4maodd module.
+*/
+
+
+#line 70 "dk4maodd.ctr"
+
+#include "dk4conf.h"
+
+#include "dk4types.h"
+
+
+
+#if DK4_CHAR_SIZE > 1
+#include "dk4maowd.h"
+#else
+#include "dk4mao8d.h"
+#endif
+
+#include "dk4maodd.h"
+#include "dk4error.h"
+
+
+
+int
+dk4ma_write_decimal_unsigned(
+ dkChar *dptr, size_t sz, dk4_um_t val, size_t padsz, dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4ma_write_wc_decimal_unsigned(dptr, sz, val, padsz, erp));
+#else
+ return (dk4ma_write_c8_decimal_unsigned(dptr, sz, val, padsz, erp));
+#endif
+}
+
+
+
+int
+dk4ma_write_decimal_signed(
+ dkChar *dptr, size_t sz, dk4_im_t val, size_t padsz, dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4ma_write_wc_decimal_signed(dptr, sz, val, padsz, erp));
+#else
+ return (dk4ma_write_c8_decimal_signed(dptr, sz, val, padsz, erp));
+#endif
+}
+
+
diff --git a/support/dktools/dk4maodd.ctr b/support/dktools/dk4maodd.ctr
new file mode 100644
index 0000000000..2fdbd4e5d1
--- /dev/null
+++ b/support/dktools/dk4maodd.ctr
@@ -0,0 +1,114 @@
+%% options
+
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ Convert dk4_um_t / dk4_im_t
+ to dkChar strings in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Write unsigned number to char string in decimal notation.
+ @param dptr Pointer to buffer for string.
+ @param sz Buffer size (number of char).
+ @param val Value to write.
+ @param padsz Minimum number of digits.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4ma_write_decimal_unsigned(
+ dkChar *dptr, size_t sz, dk4_um_t val, size_t padsz, dk4_er_t *erp
+);
+
+/** Write signed number to char string in decimal notation.
+ @param dptr Pointer to buffer for string.
+ @param sz Buffer size (number of char).
+ @param val Value to write.
+ @param padsz Minimum number of digits.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4ma_write_decimal_signed(
+ dkChar *dptr, size_t sz, dk4_im_t val, size_t padsz, dk4_er_t *erp
+);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4conf.h"
+
+#include "dk4types.h"
+
+
+
+#if DK4_CHAR_SIZE > 1
+#include "dk4maowd.h"
+#else
+#include "dk4mao8d.h"
+#endif
+
+#include "dk4maodd.h"
+#include "dk4error.h"
+
+
+
+int
+dk4ma_write_decimal_unsigned(
+ dkChar *dptr, size_t sz, dk4_um_t val, size_t padsz, dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4ma_write_wc_decimal_unsigned(dptr, sz, val, padsz, erp));
+#else
+ return (dk4ma_write_c8_decimal_unsigned(dptr, sz, val, padsz, erp));
+#endif
+}
+
+
+
+int
+dk4ma_write_decimal_signed(
+ dkChar *dptr, size_t sz, dk4_im_t val, size_t padsz, dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4ma_write_wc_decimal_signed(dptr, sz, val, padsz, erp));
+#else
+ return (dk4ma_write_c8_decimal_signed(dptr, sz, val, padsz, erp));
+#endif
+}
+
+
diff --git a/support/dktools/dk4maodd.h b/support/dktools/dk4maodd.h
new file mode 100644
index 0000000000..a9c78dd5de
--- /dev/null
+++ b/support/dktools/dk4maodd.h
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maodd.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAODD_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAODD_H_INCLUDED 1
+
+
+#line 10 "dk4maodd.ctr"
+
+/** @file
+ Convert dk4_um_t / dk4_im_t
+ to dkChar strings in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Write unsigned number to char string in decimal notation.
+ @param dptr Pointer to buffer for string.
+ @param sz Buffer size (number of char).
+ @param val Value to write.
+ @param padsz Minimum number of digits.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4ma_write_decimal_unsigned(
+ dkChar *dptr, size_t sz, dk4_um_t val, size_t padsz, dk4_er_t *erp
+);
+
+/** Write signed number to char string in decimal notation.
+ @param dptr Pointer to buffer for string.
+ @param sz Buffer size (number of char).
+ @param val Value to write.
+ @param padsz Minimum number of digits.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4ma_write_decimal_signed(
+ dkChar *dptr, size_t sz, dk4_im_t val, size_t padsz, dk4_er_t *erp
+);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maoddbl.c b/support/dktools/dk4maoddbl.c
new file mode 100644
index 0000000000..a708e83531
--- /dev/null
+++ b/support/dktools/dk4maoddbl.c
@@ -0,0 +1,63 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maoddbl.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maoddbl.c The dk4maoddbl module.
+*/
+
+
+#line 60 "dk4maoddbl.ctr"
+
+#include "dk4maoddbl.h"
+
+#if DK4_CHAR_SIZE > 1
+#include "dk4maowdbl.h"
+#else
+#include "dk4mao8dbl.h"
+#endif
+
+
+int
+dk4ma_write_double(
+ dkChar *dptr, size_t szdptr, double v, int exact, int minimize, dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4ma_write_wc_double(dptr, szdptr, v, exact, minimize, erp));
+#else
+ return (dk4ma_write_c8_double(dptr, szdptr, v, exact, minimize, erp));
+#endif
+}
+
+
diff --git a/support/dktools/dk4maoddbl.ctr b/support/dktools/dk4maoddbl.ctr
new file mode 100644
index 0000000000..8d24f5285b
--- /dev/null
+++ b/support/dktools/dk4maoddbl.ctr
@@ -0,0 +1,82 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+%% header
+
+/** @file
+ Double to dkChar text conversion using more secure functions than
+ swprintf() or sprintf() if available.
+
+ CRT on Windows: Required.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert double value to string.
+ @param dptr Destination buffer pointer.
+ @param szdptr Size of destination buffer (number of dkChar).
+ @param v Value to convert.
+ @param exact Flag: Save exact representation of number.
+ @param minimize Flag: Minimize exact representation.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or szdptr is less than 2,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the destination buffer is too small to store the string.
+*/
+int
+dk4ma_write_double(
+ dkChar *dptr, size_t szdptr, double v, int exact, int minimize, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4maoddbl.h"
+
+#if DK4_CHAR_SIZE > 1
+#include "dk4maowdbl.h"
+#else
+#include "dk4mao8dbl.h"
+#endif
+
+
+int
+dk4ma_write_double(
+ dkChar *dptr, size_t szdptr, double v, int exact, int minimize, dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4ma_write_wc_double(dptr, szdptr, v, exact, minimize, erp));
+#else
+ return (dk4ma_write_c8_double(dptr, szdptr, v, exact, minimize, erp));
+#endif
+}
+
+
diff --git a/support/dktools/dk4maoddbl.h b/support/dktools/dk4maoddbl.h
new file mode 100644
index 0000000000..e7e36b4096
--- /dev/null
+++ b/support/dktools/dk4maoddbl.h
@@ -0,0 +1,94 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maoddbl.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAODDBL_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAODDBL_H_INCLUDED 1
+
+
+#line 8 "dk4maoddbl.ctr"
+
+/** @file
+ Double to dkChar text conversion using more secure functions than
+ swprintf() or sprintf() if available.
+
+ CRT on Windows: Required.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert double value to string.
+ @param dptr Destination buffer pointer.
+ @param szdptr Size of destination buffer (number of dkChar).
+ @param v Value to convert.
+ @param exact Flag: Save exact representation of number.
+ @param minimize Flag: Minimize exact representation.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or szdptr is less than 2,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the destination buffer is too small to store the string.
+*/
+int
+dk4ma_write_double(
+ dkChar *dptr, size_t szdptr, double v, int exact, int minimize, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4maodh.c b/support/dktools/dk4maodh.c
new file mode 100644
index 0000000000..c782d9ec8a
--- /dev/null
+++ b/support/dktools/dk4maodh.c
@@ -0,0 +1,81 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maodh.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maodh.c The dk4maodh module.
+*/
+
+
+#line 1 "dk4maodh.ctr"
+
+
+#include "dk4conf.h"
+#include "dk4error.h"
+
+#if DK4_CHAR_SIZE > 1
+#include "dk4maowh.h"
+#else
+#include "dk4mao8h.h"
+#endif
+
+#include "dk4maodh.h"
+
+
+
+int
+dk4ma_write_hex_unsigned(
+ dkChar *dptr, size_t sz, dk4_um_t val, size_t padsz, dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4ma_write_wc_hex_unsigned(dptr, sz, val, padsz, erp));
+#else
+ return (dk4ma_write_c8_hex_unsigned(dptr, sz, val, padsz, erp));
+#endif
+}
+
+
+
+int
+dk4ma_write_hex_signed(
+ dkChar *dptr, size_t sz, dk4_im_t val, size_t padsz, dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4ma_write_wc_hex_signed(dptr, sz, val, padsz, erp));
+#else
+ return (dk4ma_write_c8_hex_signed(dptr, sz, val, padsz, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maodh.ctr b/support/dktools/dk4maodh.ctr
new file mode 100644
index 0000000000..ca8b7dc510
--- /dev/null
+++ b/support/dktools/dk4maodh.ctr
@@ -0,0 +1,107 @@
+
+%% options
+
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ Convert dk4_um_t / dk4_im_t
+ to dkChar strings in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Write unsigned number to char string in hex notation.
+ @param dptr Pointer to buffer for string.
+ @param sz Buffer size (number of char).
+ @param val Value to write.
+ @param padsz Minimum number of digits, 1 for automatic choice.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4ma_write_hex_unsigned(
+ dkChar *dptr, size_t sz, dk4_um_t val, size_t padsz, dk4_er_t *erp
+);
+
+/** Write signed number to char string in hex notation.
+ @param dptr Pointer to buffer for string.
+ @param sz Buffer size (number of char).
+ @param val Value to write.
+ @param padsz Minimum number of digits, 1 for automatic choice.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4ma_write_hex_signed(
+ dkChar *dptr, size_t sz, dk4_im_t val, size_t padsz, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4error.h"
+
+#if DK4_CHAR_SIZE > 1
+#include "dk4maowh.h"
+#else
+#include "dk4mao8h.h"
+#endif
+
+#include "dk4maodh.h"
+
+
+
+int
+dk4ma_write_hex_unsigned(
+ dkChar *dptr, size_t sz, dk4_um_t val, size_t padsz, dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4ma_write_wc_hex_unsigned(dptr, sz, val, padsz, erp));
+#else
+ return (dk4ma_write_c8_hex_unsigned(dptr, sz, val, padsz, erp));
+#endif
+}
+
+
+
+int
+dk4ma_write_hex_signed(
+ dkChar *dptr, size_t sz, dk4_im_t val, size_t padsz, dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4ma_write_wc_hex_signed(dptr, sz, val, padsz, erp));
+#else
+ return (dk4ma_write_c8_hex_signed(dptr, sz, val, padsz, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4maodh.h b/support/dktools/dk4maodh.h
new file mode 100644
index 0000000000..f9f574aad5
--- /dev/null
+++ b/support/dktools/dk4maodh.h
@@ -0,0 +1,99 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maodh.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAODH_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAODH_H_INCLUDED 1
+
+
+#line 11 "dk4maodh.ctr"
+
+/** @file
+ Convert dk4_um_t / dk4_im_t
+ to dkChar strings in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Write unsigned number to char string in hex notation.
+ @param dptr Pointer to buffer for string.
+ @param sz Buffer size (number of char).
+ @param val Value to write.
+ @param padsz Minimum number of digits, 1 for automatic choice.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4ma_write_hex_unsigned(
+ dkChar *dptr, size_t sz, dk4_um_t val, size_t padsz, dk4_er_t *erp
+);
+
+/** Write signed number to char string in hex notation.
+ @param dptr Pointer to buffer for string.
+ @param sz Buffer size (number of char).
+ @param val Value to write.
+ @param padsz Minimum number of digits, 1 for automatic choice.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4ma_write_hex_signed(
+ dkChar *dptr, size_t sz, dk4_im_t val, size_t padsz, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maodo.c b/support/dktools/dk4maodo.c
new file mode 100644
index 0000000000..d0e1ec7e60
--- /dev/null
+++ b/support/dktools/dk4maodo.c
@@ -0,0 +1,133 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maodo.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maodo.c The dk4maodo module.
+*/
+
+
+#line 49 "dk4maodo.ctr"
+
+#include "dk4maodo.h"
+
+
+
+
+
+#line 55 "dk4maodo.ctr"
+
+
+
+int
+dk4ma_write_octal_unsigned(
+ dkChar *dptr, size_t sz, dk4_um_t val, size_t padsz, dk4_er_t *erp
+)
+{
+ dkChar buf[4*sizeof(dk4_um_t)+16]; /* Buffer */
+ size_t used = 0; /* Number of used chars */
+ size_t i = 0; /* Copy buffer to destination */
+ int cc = 1; /* Flag: Can continue */
+ int err = 0; /* Flag: Error occured */
+ int back = 0; /* Result */
+ if ((NULL != dptr) && (0 < sz)) { *dptr = dkT('\0'); }
+ if (1 == padsz) {
+ padsz = (8 * sizeof(dk4_um_t)) / 3;
+ if (0 != ((8 * sizeof(dk4_um_t)) % 3)) {
+ padsz++;
+ }
+ }
+ if ((NULL != dptr) && (0 < sz) && (padsz < sz)) {
+ do {
+ switch ((int)(val % (dk4_um_t)8UL)) {
+ case 0: {
+ if (used < sizeof(buf)) { buf[used++] = dkT('0'); } else { err = 1; }
+ } break;
+ case 1: {
+ if (used < sizeof(buf)) { buf[used++] = dkT('1'); } else { err = 1; }
+ } break;
+ case 2: {
+ if (used < sizeof(buf)) { buf[used++] = dkT('2'); } else { err = 1; }
+ } break;
+ case 3: {
+ if (used < sizeof(buf)) { buf[used++] = dkT('3'); } else { err = 1; }
+ } break;
+ case 4: {
+ if (used < sizeof(buf)) { buf[used++] = dkT('4'); } else { err = 1; }
+ } break;
+ case 5: {
+ if (used < sizeof(buf)) { buf[used++] = dkT('5'); } else { err = 1; }
+ } break;
+ case 6: {
+ if (used < sizeof(buf)) { buf[used++] = dkT('6'); } else { err = 1; }
+ } break;
+ case 7: {
+ if (used < sizeof(buf)) { buf[used++] = dkT('7'); } else { err = 1; }
+ } break;
+ }
+ val = val / (dk4_um_t)8UL;
+ if ((dk4_um_t) 0UL == val) { cc = 0; }
+ } while ((1 == cc) && (0 == err));
+ if (0 == err) {
+ if (used < sz) {
+ if ((0 < padsz) && (used < padsz)) {
+ for (i = 0; i < (padsz - used); i++) {
+ dptr[i] = dkT('0');
+ }
+ for (i = 0; i < used; i++) {
+ dptr[padsz - 1 -i] = buf[i];
+ }
+ dptr[padsz] = dkT('\0');
+ back = 1;
+ } else {
+ for (i = 0; i < used; i++) {
+ dptr[i] = buf[used - 1 - i];
+ }
+ dptr[used] = dkT('\0');
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+
+#line 129 "dk4maodo.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4maodo.ctr b/support/dktools/dk4maodo.ctr
new file mode 100644
index 0000000000..04a826d1b9
--- /dev/null
+++ b/support/dktools/dk4maodo.ctr
@@ -0,0 +1,137 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk4maodo.h Octal output.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Write unsigned number to char string in octal notation.
+ @param dptr Pointer to buffer for string.
+ @param sz Buffer size (number of char).
+ @param val Value to write.
+ @param padsz Minimum number of digits, 1 for automatic choice.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4ma_write_octal_unsigned(
+ dkChar *dptr, size_t sz, dk4_um_t val, size_t padsz, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4maodo.h"
+
+
+
+$!trace-include
+
+
+
+int
+dk4ma_write_octal_unsigned(
+ dkChar *dptr, size_t sz, dk4_um_t val, size_t padsz, dk4_er_t *erp
+)
+{
+ dkChar buf[4*sizeof(dk4_um_t)+16]; /* Buffer */
+ size_t used = 0; /* Number of used chars */
+ size_t i = 0; /* Copy buffer to destination */
+ int cc = 1; /* Flag: Can continue */
+ int err = 0; /* Flag: Error occured */
+ int back = 0; /* Result */
+ if ((NULL != dptr) && (0 < sz)) { *dptr = dkT('\0'); }
+ if (1 == padsz) {
+ padsz = (8 * sizeof(dk4_um_t)) / 3;
+ if (0 != ((8 * sizeof(dk4_um_t)) % 3)) {
+ padsz++;
+ }
+ }
+ if ((NULL != dptr) && (0 < sz) && (padsz < sz)) {
+ do {
+ switch ((int)(val % (dk4_um_t)8UL)) {
+ case 0: {
+ if (used < sizeof(buf)) { buf[used++] = dkT('0'); } else { err = 1; }
+ } break;
+ case 1: {
+ if (used < sizeof(buf)) { buf[used++] = dkT('1'); } else { err = 1; }
+ } break;
+ case 2: {
+ if (used < sizeof(buf)) { buf[used++] = dkT('2'); } else { err = 1; }
+ } break;
+ case 3: {
+ if (used < sizeof(buf)) { buf[used++] = dkT('3'); } else { err = 1; }
+ } break;
+ case 4: {
+ if (used < sizeof(buf)) { buf[used++] = dkT('4'); } else { err = 1; }
+ } break;
+ case 5: {
+ if (used < sizeof(buf)) { buf[used++] = dkT('5'); } else { err = 1; }
+ } break;
+ case 6: {
+ if (used < sizeof(buf)) { buf[used++] = dkT('6'); } else { err = 1; }
+ } break;
+ case 7: {
+ if (used < sizeof(buf)) { buf[used++] = dkT('7'); } else { err = 1; }
+ } break;
+ }
+ val = val / (dk4_um_t)8UL;
+ if ((dk4_um_t) 0UL == val) { cc = 0; }
+ } while ((1 == cc) && (0 == err));
+ if (0 == err) {
+ if (used < sz) {
+ if ((0 < padsz) && (used < padsz)) {
+ for (i = 0; i < (padsz - used); i++) {
+ dptr[i] = dkT('0');
+ }
+ for (i = 0; i < used; i++) {
+ dptr[padsz - 1 -i] = buf[i];
+ }
+ dptr[padsz] = dkT('\0');
+ back = 1;
+ } else {
+ for (i = 0; i < used; i++) {
+ dptr[i] = buf[used - 1 - i];
+ }
+ dptr[used] = dkT('\0');
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else { $? "! error, bug"
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4maodo.h b/support/dktools/dk4maodo.h
new file mode 100644
index 0000000000..e23438cf7e
--- /dev/null
+++ b/support/dktools/dk4maodo.h
@@ -0,0 +1,81 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maodo.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAODO_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAODO_H_INCLUDED 1
+
+
+#line 10 "dk4maodo.ctr"
+
+/** @file dk4maodo.h Octal output.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Write unsigned number to char string in octal notation.
+ @param dptr Pointer to buffer for string.
+ @param sz Buffer size (number of char).
+ @param val Value to write.
+ @param padsz Minimum number of digits, 1 for automatic choice.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4ma_write_octal_unsigned(
+ dkChar *dptr, size_t sz, dk4_um_t val, size_t padsz, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4maowd.c b/support/dktools/dk4maowd.c
new file mode 100644
index 0000000000..d5c3504891
--- /dev/null
+++ b/support/dktools/dk4maowd.c
@@ -0,0 +1,187 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maowd.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maowd.c The dk4maowd module.
+*/
+
+
+#line 67 "dk4maowd.ctr"
+
+
+#include "dk4maowd.h"
+#include "dk4numco.h"
+#include "dk4numl.h"
+
+
+
+
+
+#line 76 "dk4maowd.ctr"
+
+
+
+int
+dk4ma_write_wc_decimal_unsigned(
+ wchar_t *dptr, size_t sz, dk4_um_t val, size_t padsz, dk4_er_t *erp
+)
+{
+ char buf[4*sizeof(dk4_um_t) + 16]; /* Buffer */
+ size_t used = 0; /* Number of used characters */
+ size_t i = 0; /* Copy buffer to destination */
+ int cc = 1; /* Flag: Can continue */
+ int err = 0; /* Flag: Error occued */
+ int back = 0; /* Function result */
+
+ if ((NULL != dptr) && (0 < sz)) {
+ *dptr = L'\0';
+ }
+ if (1 == padsz) {
+ padsz = dk4numlength(sizeof(dk4_um_t), 0);
+ }
+ if ((NULL != dptr) && (0 < sz) && (padsz < sz)) {
+ do {
+ switch((int)(val % (dk4_um_t)10UL)) {
+ case 0: {
+ if(used < sizeof(buf)) { buf[used++] = '0'; } else { err = 1; }
+ } break;
+ case 1: {
+ if(used < sizeof(buf)) { buf[used++] = '1'; } else { err = 1; }
+ } break;
+ case 2: {
+ if(used < sizeof(buf)) { buf[used++] = '2'; } else { err = 1; }
+ } break;
+ case 3: {
+ if(used < sizeof(buf)) { buf[used++] = '3'; } else { err = 1; }
+ } break;
+ case 4: {
+ if(used < sizeof(buf)) { buf[used++] = '4'; } else { err = 1; }
+ } break;
+ case 5: {
+ if(used < sizeof(buf)) { buf[used++] = '5'; } else { err = 1; }
+ } break;
+ case 6: {
+ if(used < sizeof(buf)) { buf[used++] = '6'; } else { err = 1; }
+ } break;
+ case 7: {
+ if(used < sizeof(buf)) { buf[used++] = '7'; } else { err = 1; }
+ } break;
+ case 8: {
+ if(used < sizeof(buf)) { buf[used++] = '8'; } else { err = 1; }
+ } break;
+ case 9: {
+ if(used < sizeof(buf)) { buf[used++] = '9'; } else { err = 1; }
+ } break;
+ }
+ val = val / (dk4_um_t)10UL;
+ if ((dk4_um_t)0UL == val) { cc = 0; }
+ } while((1 == cc) && (0 == err));
+ if (0 == err) {
+ if (used < sz) {
+ if ((0 < padsz) && (used < padsz)) {
+ for (i = 0; i < (padsz - used); i++) {
+ dptr[i] = L'0';
+ }
+ for (i = 0; i < used; i++) {
+ dptr[padsz - 1 - i] = buf[i];
+ }
+ dptr[padsz] = L'\0';
+ back = 1;
+ } else {
+ for (i = 0; i < used; i++) {
+ dptr[i] = (wchar_t)(buf[used - 1 - i]);
+ }
+ dptr[used] = L'\0';
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4ma_write_wc_decimal_signed(
+ wchar_t *dptr, size_t sz, dk4_im_t val, size_t padsz, dk4_er_t *erp
+)
+{
+ int back = 0;
+
+ if ((NULL != dptr) && (0 < sz)) {
+ *dptr = L'\0';
+ }
+ if (1 == padsz) {
+ padsz = dk4numlength(sizeof(dk4_im_t), 1);
+ }
+ if ((NULL != dptr) && (0 < sz) && (padsz < sz)) {
+ if ((dk4_im_t)0L <= val) {
+ back = dk4ma_write_wc_decimal_unsigned(
+ dptr, sz, (dk4_um_t)val, padsz, erp
+ );
+ } else {
+ if (2 < sz) {
+ *(dptr++) = L'-'; sz--;
+ if (DK4_IM_MIN == val) {
+ back = dk4ma_write_wc_decimal_unsigned(
+ dptr, sz,
+ ((dk4_um_t)(DK4_IM_MAX) + (dk4_um_t)1UL),
+ ((0 < padsz) ? (padsz - 1) : 0),
+ erp
+ );
+ } else {
+ back = dk4ma_write_wc_decimal_unsigned(
+ dptr, sz,
+ (dk4_um_t)((dk4_im_t)0L - val),
+ ((0 < padsz) ? (padsz - 1) : 0),
+ erp
+ );
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4maowd.ctr b/support/dktools/dk4maowd.ctr
new file mode 100644
index 0000000000..4e11d84993
--- /dev/null
+++ b/support/dktools/dk4maowd.ctr
@@ -0,0 +1,211 @@
+%% options
+
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ Convert dk4_um_t / dk4_im_t
+ to wchar_t strings in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Write unsigned number to char string in decimal notation.
+ @param dptr Pointer to buffer for string.
+ @param sz Buffer size (number of char).
+ @param val Value to write.
+ @param padsz Minimum number of digits.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4ma_write_wc_decimal_unsigned(
+ wchar_t *dptr, size_t sz, dk4_um_t val, size_t padsz, dk4_er_t *erp
+);
+
+/** Write signed number to char string in decimal notation.
+ @param dptr Pointer to buffer for string.
+ @param sz Buffer size (number of char).
+ @param val Value to write.
+ @param padsz Minimum number of digits.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4ma_write_wc_decimal_signed(
+ wchar_t *dptr, size_t sz, dk4_im_t val, size_t padsz, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+
+#include "dk4maowd.h"
+#include "dk4numco.h"
+#include "dk4numl.h"
+
+
+
+$!trace-include
+
+
+
+int
+dk4ma_write_wc_decimal_unsigned(
+ wchar_t *dptr, size_t sz, dk4_um_t val, size_t padsz, dk4_er_t *erp
+)
+{
+ char buf[4*sizeof(dk4_um_t) + 16]; /* Buffer */
+ size_t used = 0; /* Number of used characters */
+ size_t i = 0; /* Copy buffer to destination */
+ int cc = 1; /* Flag: Can continue */
+ int err = 0; /* Flag: Error occued */
+ int back = 0; /* Function result */
+
+ if ((NULL != dptr) && (0 < sz)) {
+ *dptr = L'\0';
+ }
+ if (1 == padsz) {
+ padsz = dk4numlength(sizeof(dk4_um_t), 0);
+ }
+ if ((NULL != dptr) && (0 < sz) && (padsz < sz)) {
+ do {
+ switch((int)(val % (dk4_um_t)10UL)) {
+ case 0: {
+ if(used < sizeof(buf)) { buf[used++] = '0'; } else { err = 1; }
+ } break;
+ case 1: {
+ if(used < sizeof(buf)) { buf[used++] = '1'; } else { err = 1; }
+ } break;
+ case 2: {
+ if(used < sizeof(buf)) { buf[used++] = '2'; } else { err = 1; }
+ } break;
+ case 3: {
+ if(used < sizeof(buf)) { buf[used++] = '3'; } else { err = 1; }
+ } break;
+ case 4: {
+ if(used < sizeof(buf)) { buf[used++] = '4'; } else { err = 1; }
+ } break;
+ case 5: {
+ if(used < sizeof(buf)) { buf[used++] = '5'; } else { err = 1; }
+ } break;
+ case 6: {
+ if(used < sizeof(buf)) { buf[used++] = '6'; } else { err = 1; }
+ } break;
+ case 7: {
+ if(used < sizeof(buf)) { buf[used++] = '7'; } else { err = 1; }
+ } break;
+ case 8: {
+ if(used < sizeof(buf)) { buf[used++] = '8'; } else { err = 1; }
+ } break;
+ case 9: {
+ if(used < sizeof(buf)) { buf[used++] = '9'; } else { err = 1; }
+ } break;
+ }
+ val = val / (dk4_um_t)10UL;
+ if ((dk4_um_t)0UL == val) { cc = 0; }
+ } while((1 == cc) && (0 == err));
+ if (0 == err) {
+ if (used < sz) {
+ if ((0 < padsz) && (used < padsz)) {
+ for (i = 0; i < (padsz - used); i++) {
+ dptr[i] = L'0';
+ }
+ for (i = 0; i < used; i++) {
+ dptr[padsz - 1 - i] = buf[i];
+ }
+ dptr[padsz] = L'\0';
+ back = 1;
+ } else {
+ for (i = 0; i < used; i++) {
+ dptr[i] = (wchar_t)(buf[used - 1 - i]);
+ }
+ dptr[used] = L'\0';
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4ma_write_wc_decimal_signed(
+ wchar_t *dptr, size_t sz, dk4_im_t val, size_t padsz, dk4_er_t *erp
+)
+{
+ int back = 0;
+
+ if ((NULL != dptr) && (0 < sz)) {
+ *dptr = L'\0';
+ }
+ if (1 == padsz) {
+ padsz = dk4numlength(sizeof(dk4_im_t), 1);
+ }
+ if ((NULL != dptr) && (0 < sz) && (padsz < sz)) {
+ if ((dk4_im_t)0L <= val) {
+ back = dk4ma_write_wc_decimal_unsigned(
+ dptr, sz, (dk4_um_t)val, padsz, erp
+ );
+ } else {
+ if (2 < sz) {
+ *(dptr++) = L'-'; sz--;
+ if (DK4_IM_MIN == val) {
+ back = dk4ma_write_wc_decimal_unsigned(
+ dptr, sz,
+ ((dk4_um_t)(DK4_IM_MAX) + (dk4_um_t)1UL),
+ ((0 < padsz) ? (padsz - 1) : 0),
+ erp
+ );
+ } else {
+ back = dk4ma_write_wc_decimal_unsigned(
+ dptr, sz,
+ (dk4_um_t)((dk4_im_t)0L - val),
+ ((0 < padsz) ? (padsz - 1) : 0),
+ erp
+ );
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4maowd.h b/support/dktools/dk4maowd.h
new file mode 100644
index 0000000000..36a521a6d3
--- /dev/null
+++ b/support/dktools/dk4maowd.h
@@ -0,0 +1,99 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maowd.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAOWD_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAOWD_H_INCLUDED 1
+
+
+#line 10 "dk4maowd.ctr"
+
+/** @file
+ Convert dk4_um_t / dk4_im_t
+ to wchar_t strings in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Write unsigned number to char string in decimal notation.
+ @param dptr Pointer to buffer for string.
+ @param sz Buffer size (number of char).
+ @param val Value to write.
+ @param padsz Minimum number of digits.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4ma_write_wc_decimal_unsigned(
+ wchar_t *dptr, size_t sz, dk4_um_t val, size_t padsz, dk4_er_t *erp
+);
+
+/** Write signed number to char string in decimal notation.
+ @param dptr Pointer to buffer for string.
+ @param sz Buffer size (number of char).
+ @param val Value to write.
+ @param padsz Minimum number of digits.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4ma_write_wc_decimal_signed(
+ wchar_t *dptr, size_t sz, dk4_im_t val, size_t padsz, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maowdbl.c b/support/dktools/dk4maowdbl.c
new file mode 100644
index 0000000000..09d5c556b0
--- /dev/null
+++ b/support/dktools/dk4maowdbl.c
@@ -0,0 +1,385 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maowdbl.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maowdbl.c The dk4maowdbl module.
+*/
+
+
+#line 74 "dk4maowdbl.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+#if DK4_HAVE_LOCALE_H
+#ifndef LOCALE_H_INCLUDED
+#include <locale.h>
+#define LOCALE_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4mem.h"
+#include "dk4mao8dbl.h"
+#include "dk4maowdbl.h"
+#include "dk4str8.h"
+#include "dk4strw.h"
+
+
+
+/** Locale to user for conversion.
+*/
+static const char locale_kw[] = { "C" };
+
+
+
+/** Convert double value to string.
+ @param dptr Destination buffer pointer.
+ @param szdptr Size of destination buffer (number of wchar_t).
+ @param v Value to convert.
+ @param exact Flag: Write enough digits to allow exact restoration.
+ @param minimize Minimize exact respresentation.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or szdptr is less than 2,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the destination buffer is too small to store the string.
+*/
+static
+void
+dk4double_squeeze_wc_string(wchar_t *buf)
+{
+ wchar_t *ptre = NULL;
+ wchar_t *ptrdot = NULL;
+ wchar_t *ptrcom = NULL;
+ wchar_t *ptrcut = NULL;
+ wchar_t *ptr;
+ int useexp = 1;
+
+
+#line 125 "dk4maowdbl.ctr"
+ if (NULL != buf) {
+ ptr = buf;
+ while(L'\0' != *ptr) {
+ if ((L'e' == *ptr) || (L'E' == *ptr)) {
+ if (NULL == ptre) { ptre = ptr; }
+ } else {
+ if (L'.' == *ptr) {
+ if (NULL == ptrdot) { ptrdot = ptr; }
+ } else {
+ if (L',' == *ptr) {
+ if (NULL == ptrcom) { ptrcom = ptr; }
+ }
+ }
+ }
+ ptr++;
+ }
+ if (NULL != ptre) {
+
+#line 142 "dk4maowdbl.ctr"
+ *ptre = '\0';
+ ptr = ptre;
+ ptr++;
+ if ((L'+' == *ptr) || (L'0' == *ptr)) {
+
+#line 146 "dk4maowdbl.ctr"
+ useexp = 0;
+ ptr++;
+ while(L'\0' != *ptr) {
+ if (L'0' != *ptr) {
+
+#line 150 "dk4maowdbl.ctr"
+ useexp = 1;
+ }
+ ptr++;
+ }
+ }
+ }
+ if (NULL != ptrdot) {
+ ptrdot++;
+ if (L'\0' != *ptrdot) {
+
+#line 159 "dk4maowdbl.ctr"
+ ptrdot++;
+ while(L'\0' != *ptrdot) {
+
+#line 161 "dk4maowdbl.ctr"
+ if (L'0' == *ptrdot) {
+ if (NULL == ptrcut) {
+ ptrcut = ptrdot;
+
+#line 164 "dk4maowdbl.ctr"
+ }
+ } else {
+ ptrcut = NULL;
+
+#line 167 "dk4maowdbl.ctr"
+ }
+ ptrdot++;
+ }
+ }
+ } else {
+ if (NULL != ptrcom) {
+ ptrcom++;
+ if (L'\0' != *ptrcom) {
+ ptrcom++;
+ while (L'\0' != *ptrcom) {
+ if (L'0' == *ptrcom) {
+ if (NULL == ptrcut) {
+ ptrcut = ptrcom;
+ }
+ } else {
+ ptrcut = NULL;
+ }
+ ptrcom++;
+ }
+ }
+ }
+ }
+ if ((NULL != ptre) && (0 != useexp)) {
+ *ptre = L'e';
+ }
+ if (NULL != ptrcut) {
+ if ((NULL != ptre) && (0 != useexp)) {
+ while (L'\0' != *ptre) {
+ *(ptrcut++) = *(ptre++);
+ }
+ }
+ *ptrcut = L'\0';
+ }
+ }
+
+
+#line 202 "dk4maowdbl.ctr"
+}
+
+
+
+static
+int
+dk4ma_internal_write_wc_double(
+ wchar_t *dptr, size_t szdptr, double v, int exact, int minimize, dk4_er_t *erp
+)
+{
+#if DK4_HAVE__SNWPRINTF_S
+ /* +++ _snwprintf_s */
+ wchar_t buf[64];
+ int back = 0;
+ int res = 0;
+ if (NULL != dptr) { *dptr = L'\0'; }
+ if ((NULL != dptr) && (1 < szdptr)) {
+ if (0 != exact) {
+ res = _snwprintf_s(
+ buf, DK4_SIZEOF(buf,dkChar), _TRUNCATE, L"%.*e", (int)DK4_DBL_DIGITS, v
+ );
+ if ((0 < res) && (res < DK4_SIZEOF(buf,dkChar))) {
+ buf[res] = L'\0';
+ if (0 != minimize) {
+ dk4double_squeeze_wc_string(buf);
+ }
+ back = dk4strw_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ res = _snwprintf_s(
+ buf, DK4_SIZEOF(buf,dkChar), _TRUNCATE, L"%g", v
+ );
+ if ((0 < res) && (res < DK4_SIZEOF(buf,dkChar))) {
+ buf[res] = L'\0';
+ back = dk4strw_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* --- _snwprintf_s */
+#else
+#if DK4_HAVE__SNWPRINTF
+ /* +++ _snwprintf */
+ wchar_t buf[64];
+ int back = 0;
+ int res = 0;
+ if (NULL != dptr) { *dptr = L'\0'; }
+ if ((NULL != dptr) && (1 < szdptr)) {
+ if (0 != exact) {
+ 0 = _snwprintf(
+ buf, DK4_SIZEOF(buf,dkChar), L"%.*e", (int)DK4_DBL_DIGITS, v
+ );
+ if ((0 < res) && (res < DK4_SIZEOF(buf,dkChar))) {
+ buf[res] = L'\0';
+ if (0 != minimize) {
+ dk4double_squeeze_wc_string(buf);
+ }
+ back = dk4strw_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ 0 = _snwprintf(
+ buf, DK4_SIZEOF(buf,dkChar), L"%g", v
+ );
+ if ((0 < res) && (res < DK4_SIZEOF(buf,dkChar))) {
+ buf[res] = L'\0';
+ back = dk4strw_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* --- _snwprintf */
+#else
+#if DK4_HAVE_SNWPRINTF
+ wchar_t buf[64];
+ int back = 0;
+ int res = 0;
+ if (NULL != dptr) { *dptr = L'\0'; }
+ if ((NULL != dptr) && (1 < szdptr)) {
+ if (0 != exact) {
+ res = snwprintf(buf,DK4_SIZEOF(buf,dkChar),L"%.*e",(int)DK4_DBL_DIGITS,v);
+ if ((0 < res) && (res < DK4_SIZEOF(buf,dkChar))) {
+ buf[res] = L'\0';
+ if (0 != minimize) {
+ dk4double_squeeze_wc_string(buf);
+ }
+ back = dk4strw_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ res = snwprintf(buf, DK4_SIZEOF(buf,dkChar), L"%g", v);
+ if ((0 < res) && (res < DK4_SIZEOF(buf,dkChar))) {
+ buf[res] = L'\0';
+ back = dk4strw_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+#if DK4_HAVE_SWPRINTF
+ /* +++ swprintf */
+ wchar_t buf[64];
+ int back = 0;
+ int res = 0;
+ if (NULL != dptr) { *dptr = L'\0'; }
+ if ((NULL != dptr) && (1 < szdptr)) {
+ if (0 != exact) {
+ res = swprintf(buf,DK4_SIZEOF(buf,dkChar),L"%.*e",(int)DK4_DBL_DIGITS,v);
+ if ((0 < res) && (res < DK4_SIZEOF(buf,dkChar))) {
+ buf[res] = L'\0';
+ if (0 != minimize) {
+ dk4double_squeeze_wc_string(buf);
+ }
+ back = dk4strw_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ res = swprintf(buf, DK4_SIZEOF(buf,dkChar), L"%g", v);
+ if ((0 < res) && (res < DK4_SIZEOF(buf,dkChar))) {
+ buf[res] = L'\0';
+ back = dk4strw_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* --- swprintf */
+#else
+ char buf[64];
+ char *p1;
+ wchar_t *p2;
+ int back = 0;
+ if ((NULL != dptr) && (1 < szdptr)) {
+ if (0 != dk4ma_write_c8_double(buf,sizeof(buf),v,exact,minimize,erp)) {
+ if (dk4str8_len(buf) < szdptr) {
+ p2 = dptr; p1 = buf;
+ while ('\0' != *p1) {
+ *(p2++) = (wchar_t)(*(p1++));
+ }
+ *p2 = L'\0';
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#endif
+#endif
+#endif
+#endif
+}
+
+
+
+int
+dk4ma_write_wc_double(
+ wchar_t *dptr, size_t szdptr, double v, int exact, int minimize, dk4_er_t *erp
+)
+{
+
+#if (DK4_HAVE_SETLOCALE) && defined(LC_NUMERIC)
+ char *oldloc = NULL;
+#endif
+ int back = 0;
+
+#if (DK4_HAVE_SETLOCALE) && defined(LC_NUMERIC)
+ oldloc = setlocale(LC_NUMERIC, NULL);
+ (void)setlocale(LC_NUMERIC, locale_kw);
+#endif
+ back = dk4ma_internal_write_wc_double(dptr, szdptr, v, exact, minimize, erp);
+#if (DK4_HAVE_SETLOCALE) && defined(LC_NUMERIC)
+ (void)setlocale(LC_NUMERIC, oldloc);
+#endif
+ return back;
+}
+
diff --git a/support/dktools/dk4maowdbl.ctr b/support/dktools/dk4maowdbl.ctr
new file mode 100644
index 0000000000..c48681d1ac
--- /dev/null
+++ b/support/dktools/dk4maowdbl.ctr
@@ -0,0 +1,400 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Double to wchar_t text conversion using the more secure
+ _snwprintf_s(), _snwprintf() or snwprintf() functions instead
+ of swprintf() if available.
+
+ CRT on Windows: Required.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_HAVE_WCHAR_H
+#ifndef WCHAR_H_INCLUDED
+#include <wchar.h>
+#define WCHAR_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert double value to string.
+ @param dptr Destination buffer pointer.
+ @param szdptr Size of destination buffer (number of wchar_t).
+ @param v Value to convert.
+ @param exact Flag: Write enough digits to allow exact restoration.
+ @param minimize Minimize exact respresentation.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or szdptr is less than 2,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the destination buffer is too small to store the string.
+*/
+
+int
+dk4ma_write_wc_double(
+ wchar_t *dptr, size_t szdptr, double v, int exact, int minimize, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+#if DK4_HAVE_LOCALE_H
+#ifndef LOCALE_H_INCLUDED
+#include <locale.h>
+#define LOCALE_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4mem.h"
+#include "dk4mao8dbl.h"
+#include "dk4maowdbl.h"
+#include "dk4str8.h"
+#include "dk4strw.h"
+
+
+
+/** Locale to user for conversion.
+*/
+static const char locale_kw[] = { "C" };
+
+
+
+/** Convert double value to string.
+ @param dptr Destination buffer pointer.
+ @param szdptr Size of destination buffer (number of wchar_t).
+ @param v Value to convert.
+ @param exact Flag: Write enough digits to allow exact restoration.
+ @param minimize Minimize exact respresentation.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or szdptr is less than 2,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the destination buffer is too small to store the string.
+*/
+static
+void
+dk4double_squeeze_wc_string(wchar_t *buf)
+{
+ wchar_t *ptre = NULL;
+ wchar_t *ptrdot = NULL;
+ wchar_t *ptrcom = NULL;
+ wchar_t *ptrcut = NULL;
+ wchar_t *ptr;
+ int useexp = 1;
+ $? "+ dk4double_squeeze_wc_string \"%!ws\"", TR_LSTR(buf)
+ if (NULL != buf) {
+ ptr = buf;
+ while(L'\0' != *ptr) {
+ if ((L'e' == *ptr) || (L'E' == *ptr)) {
+ if (NULL == ptre) { ptre = ptr; }
+ } else {
+ if (L'.' == *ptr) {
+ if (NULL == ptrdot) { ptrdot = ptr; }
+ } else {
+ if (L',' == *ptr) {
+ if (NULL == ptrcom) { ptrcom = ptr; }
+ }
+ }
+ }
+ ptr++;
+ }
+ if (NULL != ptre) { $? ". check exponent"
+ *ptre = '\0';
+ ptr = ptre;
+ ptr++;
+ if ((L'+' == *ptr) || (L'0' == *ptr)) { $? ". leading + or 0"
+ useexp = 0;
+ ptr++;
+ while(L'\0' != *ptr) {
+ if (L'0' != *ptr) { $? ". non-0 char \"%c\"", *ptr
+ useexp = 1;
+ }
+ ptr++;
+ }
+ }
+ }
+ if (NULL != ptrdot) {
+ ptrdot++;
+ if (L'\0' != *ptrdot) { $? ". chars after dot"
+ ptrdot++;
+ while(L'\0' != *ptrdot) { $? ". check \"%c\"", *ptrdot
+ if (L'0' == *ptrdot) {
+ if (NULL == ptrcut) {
+ ptrcut = ptrdot; $? ". cut"
+ }
+ } else {
+ ptrcut = NULL; $? ". no cut"
+ }
+ ptrdot++;
+ }
+ }
+ } else {
+ if (NULL != ptrcom) {
+ ptrcom++;
+ if (L'\0' != *ptrcom) {
+ ptrcom++;
+ while (L'\0' != *ptrcom) {
+ if (L'0' == *ptrcom) {
+ if (NULL == ptrcut) {
+ ptrcut = ptrcom;
+ }
+ } else {
+ ptrcut = NULL;
+ }
+ ptrcom++;
+ }
+ }
+ }
+ }
+ if ((NULL != ptre) && (0 != useexp)) {
+ *ptre = L'e';
+ }
+ if (NULL != ptrcut) {
+ if ((NULL != ptre) && (0 != useexp)) {
+ while (L'\0' != *ptre) {
+ *(ptrcut++) = *(ptre++);
+ }
+ }
+ *ptrcut = L'\0';
+ }
+ }
+ $? "- dk4double_squeeze_wc_string \"%!ws\"", TR_LSTR(buf)
+}
+
+
+
+static
+int
+dk4ma_internal_write_wc_double(
+ wchar_t *dptr, size_t szdptr, double v, int exact, int minimize, dk4_er_t *erp
+)
+{
+#if DK4_HAVE__SNWPRINTF_S
+ /* +++ _snwprintf_s */
+ wchar_t buf[64];
+ int back = 0;
+ int res = 0;
+ if (NULL != dptr) { *dptr = L'\0'; }
+ if ((NULL != dptr) && (1 < szdptr)) {
+ if (0 != exact) {
+ res = _snwprintf_s(
+ buf, DK4_SIZEOF(buf,dkChar), _TRUNCATE, L"%.*e", (int)DK4_DBL_DIGITS, v
+ );
+ if ((0 < res) && (res < DK4_SIZEOF(buf,dkChar))) {
+ buf[res] = L'\0';
+ if (0 != minimize) {
+ dk4double_squeeze_wc_string(buf);
+ }
+ back = dk4strw_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ res = _snwprintf_s(
+ buf, DK4_SIZEOF(buf,dkChar), _TRUNCATE, L"%g", v
+ );
+ if ((0 < res) && (res < DK4_SIZEOF(buf,dkChar))) {
+ buf[res] = L'\0';
+ back = dk4strw_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* --- _snwprintf_s */
+#else
+#if DK4_HAVE__SNWPRINTF
+ /* +++ _snwprintf */
+ wchar_t buf[64];
+ int back = 0;
+ int res = 0;
+ if (NULL != dptr) { *dptr = L'\0'; }
+ if ((NULL != dptr) && (1 < szdptr)) {
+ if (0 != exact) {
+ 0 = _snwprintf(
+ buf, DK4_SIZEOF(buf,dkChar), L"%.*e", (int)DK4_DBL_DIGITS, v
+ );
+ if ((0 < res) && (res < DK4_SIZEOF(buf,dkChar))) {
+ buf[res] = L'\0';
+ if (0 != minimize) {
+ dk4double_squeeze_wc_string(buf);
+ }
+ back = dk4strw_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ 0 = _snwprintf(
+ buf, DK4_SIZEOF(buf,dkChar), L"%g", v
+ );
+ if ((0 < res) && (res < DK4_SIZEOF(buf,dkChar))) {
+ buf[res] = L'\0';
+ back = dk4strw_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* --- _snwprintf */
+#else
+#if DK4_HAVE_SNWPRINTF
+ wchar_t buf[64];
+ int back = 0;
+ int res = 0;
+ if (NULL != dptr) { *dptr = L'\0'; }
+ if ((NULL != dptr) && (1 < szdptr)) {
+ if (0 != exact) {
+ res = snwprintf(buf,DK4_SIZEOF(buf,dkChar),L"%.*e",(int)DK4_DBL_DIGITS,v);
+ if ((0 < res) && (res < DK4_SIZEOF(buf,dkChar))) {
+ buf[res] = L'\0';
+ if (0 != minimize) {
+ dk4double_squeeze_wc_string(buf);
+ }
+ back = dk4strw_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ res = snwprintf(buf, DK4_SIZEOF(buf,dkChar), L"%g", v);
+ if ((0 < res) && (res < DK4_SIZEOF(buf,dkChar))) {
+ buf[res] = L'\0';
+ back = dk4strw_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+#if DK4_HAVE_SWPRINTF
+ /* +++ swprintf */
+ wchar_t buf[64];
+ int back = 0;
+ int res = 0;
+ if (NULL != dptr) { *dptr = L'\0'; }
+ if ((NULL != dptr) && (1 < szdptr)) {
+ if (0 != exact) {
+ res = swprintf(buf,DK4_SIZEOF(buf,dkChar),L"%.*e",(int)DK4_DBL_DIGITS,v);
+ if ((0 < res) && (res < DK4_SIZEOF(buf,dkChar))) {
+ buf[res] = L'\0';
+ if (0 != minimize) {
+ dk4double_squeeze_wc_string(buf);
+ }
+ back = dk4strw_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ res = swprintf(buf, DK4_SIZEOF(buf,dkChar), L"%g", v);
+ if ((0 < res) && (res < DK4_SIZEOF(buf,dkChar))) {
+ buf[res] = L'\0';
+ back = dk4strw_cpy_s(dptr, szdptr, buf, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* --- swprintf */
+#else
+ char buf[64];
+ char *p1;
+ wchar_t *p2;
+ int back = 0;
+ if ((NULL != dptr) && (1 < szdptr)) {
+ if (0 != dk4ma_write_c8_double(buf,sizeof(buf),v,exact,minimize,erp)) {
+ if (dk4str8_len(buf) < szdptr) {
+ p2 = dptr; p1 = buf;
+ while ('\0' != *p1) {
+ *(p2++) = (wchar_t)(*(p1++));
+ }
+ *p2 = L'\0';
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#endif
+#endif
+#endif
+#endif
+}
+
+
+
+int
+dk4ma_write_wc_double(
+ wchar_t *dptr, size_t szdptr, double v, int exact, int minimize, dk4_er_t *erp
+)
+{
+
+#if (DK4_HAVE_SETLOCALE) && defined(LC_NUMERIC)
+ char *oldloc = NULL;
+#endif
+ int back = 0;
+
+#if (DK4_HAVE_SETLOCALE) && defined(LC_NUMERIC)
+ oldloc = setlocale(LC_NUMERIC, NULL);
+ (void)setlocale(LC_NUMERIC, locale_kw);
+#endif
+ back = dk4ma_internal_write_wc_double(dptr, szdptr, v, exact, minimize, erp);
+#if (DK4_HAVE_SETLOCALE) && defined(LC_NUMERIC)
+ (void)setlocale(LC_NUMERIC, oldloc);
+#endif
+ return back;
+}
+
diff --git a/support/dktools/dk4maowdbl.h b/support/dktools/dk4maowdbl.h
new file mode 100644
index 0000000000..8b7526d560
--- /dev/null
+++ b/support/dktools/dk4maowdbl.h
@@ -0,0 +1,106 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maowdbl.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAOWDBL_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAOWDBL_H_INCLUDED 1
+
+
+#line 10 "dk4maowdbl.ctr"
+
+/** @file
+ Double to wchar_t text conversion using the more secure
+ _snwprintf_s(), _snwprintf() or snwprintf() functions instead
+ of swprintf() if available.
+
+ CRT on Windows: Required.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_HAVE_WCHAR_H
+#ifndef WCHAR_H_INCLUDED
+#include <wchar.h>
+#define WCHAR_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert double value to string.
+ @param dptr Destination buffer pointer.
+ @param szdptr Size of destination buffer (number of wchar_t).
+ @param v Value to convert.
+ @param exact Flag: Write enough digits to allow exact restoration.
+ @param minimize Minimize exact respresentation.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or szdptr is less than 2,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the destination buffer is too small to store the string.
+*/
+
+int
+dk4ma_write_wc_double(
+ wchar_t *dptr, size_t szdptr, double v, int exact, int minimize, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4maowh.c b/support/dktools/dk4maowh.c
new file mode 100644
index 0000000000..16db7f8ee8
--- /dev/null
+++ b/support/dktools/dk4maowh.c
@@ -0,0 +1,155 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maowh.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maowh.c The dk4maowh module.
+*/
+
+
+#line 67 "dk4maowh.ctr"
+
+
+#include "dk4maowh.h"
+
+
+
+int
+dk4ma_write_wc_hex_unsigned(
+ wchar_t *dptr, size_t sz, dk4_um_t val, size_t padsz, dk4_er_t *erp
+)
+{
+ char buf[4*sizeof(dk4_um_t) + 16]; /* Buffer */
+ size_t used = 0; /* Number of used characters */
+ size_t i = 0; /* Copy buffer to destination */
+ int cc = 1; /* Flag: Can continue */
+ int err = 0; /* Flag: Error occued */
+ int back = 0; /* Function result */
+
+ if (1 == padsz) { padsz = 2 * sizeof(dk4_um_t); }
+ if ((NULL != dptr) && (0 < sz) && (padsz < sz)) {
+ *dptr = L'\0';
+ do {
+ switch((int)(val % (dk4_um_t)16UL)) {
+ case 0: {
+ if(used < sizeof(buf)) { buf[used++] = '0'; } else { err = 1; }
+ } break;
+ case 1: {
+ if(used < sizeof(buf)) { buf[used++] = '1'; } else { err = 1; }
+ } break;
+ case 2: {
+ if(used < sizeof(buf)) { buf[used++] = '2'; } else { err = 1; }
+ } break;
+ case 3: {
+ if(used < sizeof(buf)) { buf[used++] = '3'; } else { err = 1; }
+ } break;
+ case 4: {
+ if(used < sizeof(buf)) { buf[used++] = '4'; } else { err = 1; }
+ } break;
+ case 5: {
+ if(used < sizeof(buf)) { buf[used++] = '5'; } else { err = 1; }
+ } break;
+ case 6: {
+ if(used < sizeof(buf)) { buf[used++] = '6'; } else { err = 1; }
+ } break;
+ case 7: {
+ if(used < sizeof(buf)) { buf[used++] = '7'; } else { err = 1; }
+ } break;
+ case 8: {
+ if(used < sizeof(buf)) { buf[used++] = '8'; } else { err = 1; }
+ } break;
+ case 9: {
+ if(used < sizeof(buf)) { buf[used++] = '9'; } else { err = 1; }
+ } break;
+ case 10: {
+ if(used < sizeof(buf)) { buf[used++] = 'A'; } else { err = 1; }
+ } break;
+ case 11: {
+ if(used < sizeof(buf)) { buf[used++] = 'B'; } else { err = 1; }
+ } break;
+ case 12: {
+ if(used < sizeof(buf)) { buf[used++] = 'C'; } else { err = 1; }
+ } break;
+ case 13: {
+ if(used < sizeof(buf)) { buf[used++] = 'D'; } else { err = 1; }
+ } break;
+ case 14: {
+ if(used < sizeof(buf)) { buf[used++] = 'E'; } else { err = 1; }
+ } break;
+ case 15: {
+ if(used < sizeof(buf)) { buf[used++] = 'F'; } else { err = 1; }
+ } break;
+ }
+ val = val / (dk4_um_t)16UL;
+ if ((dk4_um_t)0UL == val) { cc = 0; }
+ } while((1 == cc) && (0 == err));
+ if (0 == err) {
+ if (used < sz) {
+ if ((0 < padsz) && (used < padsz)) {
+ for (i = 0; i < (padsz - used); i++) {
+ dptr[i] = L'0';
+ }
+ for (i = 0; i < used; i++) {
+ dptr[padsz - 1 - i] = (wchar_t)(buf[i]);
+ }
+ dptr[padsz] = L'\0';
+ back = 1;
+ } else {
+ for (i = 0; i < used; i++) {
+ dptr[i] = (wchar_t)(buf[used - 1 - i]);
+ }
+ dptr[used] = L'\0';
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4ma_write_wc_hex_signed(
+ wchar_t *dptr, size_t sz, dk4_im_t val, size_t padsz, dk4_er_t *erp
+)
+{
+ return (dk4ma_write_wc_hex_unsigned(dptr, sz, (dk4_um_t)val, padsz, erp));
+}
+
diff --git a/support/dktools/dk4maowh.ctr b/support/dktools/dk4maowh.ctr
new file mode 100644
index 0000000000..ebf0826703
--- /dev/null
+++ b/support/dktools/dk4maowh.ctr
@@ -0,0 +1,181 @@
+%% options
+
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ Convert dk4_um_t / dk4_im_t
+ to wchar_t strings in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Write unsigned number to char string in hex notation.
+ @param dptr Pointer to buffer for string.
+ @param sz Buffer size (number of char).
+ @param val Value to write.
+ @param padsz Minimum number of digits, 1 for automatic choice.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4ma_write_wc_hex_unsigned(
+ wchar_t *dptr, size_t sz, dk4_um_t val, size_t padsz, dk4_er_t *erp
+);
+
+/** Write signed number to char string in hex notation.
+ @param dptr Pointer to buffer for string.
+ @param sz Buffer size (number of char).
+ @param val Value to write.
+ @param padsz Minimum number of digits, 1 for automatic choice.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4ma_write_wc_hex_signed(
+ wchar_t *dptr, size_t sz, dk4_im_t val, size_t padsz, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+
+#include "dk4maowh.h"
+
+
+
+int
+dk4ma_write_wc_hex_unsigned(
+ wchar_t *dptr, size_t sz, dk4_um_t val, size_t padsz, dk4_er_t *erp
+)
+{
+ char buf[4*sizeof(dk4_um_t) + 16]; /* Buffer */
+ size_t used = 0; /* Number of used characters */
+ size_t i = 0; /* Copy buffer to destination */
+ int cc = 1; /* Flag: Can continue */
+ int err = 0; /* Flag: Error occued */
+ int back = 0; /* Function result */
+
+ if (1 == padsz) { padsz = 2 * sizeof(dk4_um_t); }
+ if ((NULL != dptr) && (0 < sz) && (padsz < sz)) {
+ *dptr = L'\0';
+ do {
+ switch((int)(val % (dk4_um_t)16UL)) {
+ case 0: {
+ if(used < sizeof(buf)) { buf[used++] = '0'; } else { err = 1; }
+ } break;
+ case 1: {
+ if(used < sizeof(buf)) { buf[used++] = '1'; } else { err = 1; }
+ } break;
+ case 2: {
+ if(used < sizeof(buf)) { buf[used++] = '2'; } else { err = 1; }
+ } break;
+ case 3: {
+ if(used < sizeof(buf)) { buf[used++] = '3'; } else { err = 1; }
+ } break;
+ case 4: {
+ if(used < sizeof(buf)) { buf[used++] = '4'; } else { err = 1; }
+ } break;
+ case 5: {
+ if(used < sizeof(buf)) { buf[used++] = '5'; } else { err = 1; }
+ } break;
+ case 6: {
+ if(used < sizeof(buf)) { buf[used++] = '6'; } else { err = 1; }
+ } break;
+ case 7: {
+ if(used < sizeof(buf)) { buf[used++] = '7'; } else { err = 1; }
+ } break;
+ case 8: {
+ if(used < sizeof(buf)) { buf[used++] = '8'; } else { err = 1; }
+ } break;
+ case 9: {
+ if(used < sizeof(buf)) { buf[used++] = '9'; } else { err = 1; }
+ } break;
+ case 10: {
+ if(used < sizeof(buf)) { buf[used++] = 'A'; } else { err = 1; }
+ } break;
+ case 11: {
+ if(used < sizeof(buf)) { buf[used++] = 'B'; } else { err = 1; }
+ } break;
+ case 12: {
+ if(used < sizeof(buf)) { buf[used++] = 'C'; } else { err = 1; }
+ } break;
+ case 13: {
+ if(used < sizeof(buf)) { buf[used++] = 'D'; } else { err = 1; }
+ } break;
+ case 14: {
+ if(used < sizeof(buf)) { buf[used++] = 'E'; } else { err = 1; }
+ } break;
+ case 15: {
+ if(used < sizeof(buf)) { buf[used++] = 'F'; } else { err = 1; }
+ } break;
+ }
+ val = val / (dk4_um_t)16UL;
+ if ((dk4_um_t)0UL == val) { cc = 0; }
+ } while((1 == cc) && (0 == err));
+ if (0 == err) {
+ if (used < sz) {
+ if ((0 < padsz) && (used < padsz)) {
+ for (i = 0; i < (padsz - used); i++) {
+ dptr[i] = L'0';
+ }
+ for (i = 0; i < used; i++) {
+ dptr[padsz - 1 - i] = (wchar_t)(buf[i]);
+ }
+ dptr[padsz] = L'\0';
+ back = 1;
+ } else {
+ for (i = 0; i < used; i++) {
+ dptr[i] = (wchar_t)(buf[used - 1 - i]);
+ }
+ dptr[used] = L'\0';
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4ma_write_wc_hex_signed(
+ wchar_t *dptr, size_t sz, dk4_im_t val, size_t padsz, dk4_er_t *erp
+)
+{
+ return (dk4ma_write_wc_hex_unsigned(dptr, sz, (dk4_um_t)val, padsz, erp));
+}
+
diff --git a/support/dktools/dk4maowh.h b/support/dktools/dk4maowh.h
new file mode 100644
index 0000000000..8bfa2550ed
--- /dev/null
+++ b/support/dktools/dk4maowh.h
@@ -0,0 +1,99 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maowh.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAOWH_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAOWH_H_INCLUDED 1
+
+
+#line 10 "dk4maowh.ctr"
+
+/** @file
+ Convert dk4_um_t / dk4_im_t
+ to wchar_t strings in hexadecimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Write unsigned number to char string in hex notation.
+ @param dptr Pointer to buffer for string.
+ @param sz Buffer size (number of char).
+ @param val Value to write.
+ @param padsz Minimum number of digits, 1 for automatic choice.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4ma_write_wc_hex_unsigned(
+ wchar_t *dptr, size_t sz, dk4_um_t val, size_t padsz, dk4_er_t *erp
+);
+
+/** Write signed number to char string in hex notation.
+ @param dptr Pointer to buffer for string.
+ @param sz Buffer size (number of char).
+ @param val Value to write.
+ @param padsz Minimum number of digits, 1 for automatic choice.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4ma_write_wc_hex_signed(
+ wchar_t *dptr, size_t sz, dk4_im_t val, size_t padsz, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maoxd.cpp b/support/dktools/dk4maoxd.cpp
new file mode 100644
index 0000000000..9123e31bdf
--- /dev/null
+++ b/support/dktools/dk4maoxd.cpp
@@ -0,0 +1,96 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maoxd.cpt
+*/
+
+/*
+Copyright (C) 2017-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maoxd.cpp The dk4maoxd module.
+*/
+
+
+#line 104 "dk4maoxd.cpt"
+
+#include "dk4conf.h"
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#include "dk4types.h"
+
+#include "dk4maoxd.h"
+
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR == DK4_SIZEOF_WCHAR_T
+#include "dk4maowd.h"
+#else
+#error "Illegal wxChar size!"
+#endif
+#else
+#include "dk4mao8d.h"
+#endif
+
+
+
+int
+dk4ma_write_wx_decimal_unsigned(
+ wxChar *dptr, size_t sz, dk4_um_t val, size_t padsz, dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4ma_write_wc_decimal_unsigned(dptr, sz, val, padsz, erp));
+#else
+ return (dk4ma_write_c8_decimal_unsigned(dptr, sz, val, padsz, erp));
+#endif
+}
+
+
+
+int
+dk4ma_write_wx_decimal_signed(
+ wxChar *dptr, size_t sz, dk4_im_t val, size_t padsz, dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4ma_write_wc_decimal_signed(dptr, sz, val, padsz, erp));
+#else
+ return (dk4ma_write_c8_decimal_signed(dptr, sz, val, padsz, erp));
+#endif
+}
+
+
+
+#endif
+
diff --git a/support/dktools/dk4maoxd.cpt b/support/dktools/dk4maoxd.cpt
new file mode 100644
index 0000000000..b2e8934397
--- /dev/null
+++ b/support/dktools/dk4maoxd.cpt
@@ -0,0 +1,159 @@
+%% options
+
+
+copyright owner = Dirk Krause
+copyright year = 2017-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ Convert dk4_um_t / dk4_im_t
+ to wxChar strings in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+
+extern "C" {
+
+/** Write unsigned number to char string in decimal notation.
+ @param dptr Pointer to buffer for string.
+ @param sz Buffer size (number of char).
+ @param val Value to write.
+ @param padsz Minimum number of digits.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4ma_write_wx_decimal_unsigned(
+ wxChar *dptr, size_t sz, dk4_um_t val, size_t padsz, dk4_er_t *erp
+);
+
+/** Write signed number to char string in decimal notation.
+ @param dptr Pointer to buffer for string.
+ @param sz Buffer size (number of char).
+ @param val Value to write.
+ @param padsz Minimum number of digits.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4ma_write_wx_decimal_signed(
+ wxChar *dptr, size_t sz, dk4_im_t val, size_t padsz, dk4_er_t *erp
+);
+
+
+}
+
+
+
+#endif
+
+
+
+%% module
+
+#include "dk4conf.h"
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#include "dk4types.h"
+
+#include "dk4maoxd.h"
+
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR == DK4_SIZEOF_WCHAR_T
+#include "dk4maowd.h"
+#else
+#error "Illegal wxChar size!"
+#endif
+#else
+#include "dk4mao8d.h"
+#endif
+
+
+
+int
+dk4ma_write_wx_decimal_unsigned(
+ wxChar *dptr, size_t sz, dk4_um_t val, size_t padsz, dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4ma_write_wc_decimal_unsigned(dptr, sz, val, padsz, erp));
+#else
+ return (dk4ma_write_c8_decimal_unsigned(dptr, sz, val, padsz, erp));
+#endif
+}
+
+
+
+int
+dk4ma_write_wx_decimal_signed(
+ wxChar *dptr, size_t sz, dk4_im_t val, size_t padsz, dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4ma_write_wc_decimal_signed(dptr, sz, val, padsz, erp));
+#else
+ return (dk4ma_write_c8_decimal_signed(dptr, sz, val, padsz, erp));
+#endif
+}
+
+
+
+#endif
+
diff --git a/support/dktools/dk4maoxd.h b/support/dktools/dk4maoxd.h
new file mode 100644
index 0000000000..515797cdee
--- /dev/null
+++ b/support/dktools/dk4maoxd.h
@@ -0,0 +1,136 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maoxd.cpt
+*/
+
+/*
+Copyright (C) 2017-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAOXD_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAOXD_H_INCLUDED 1
+
+
+#line 10 "dk4maoxd.cpt"
+
+/** @file
+ Convert dk4_um_t / dk4_im_t
+ to wxChar strings in decimal notation.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+
+extern "C" {
+
+/** Write unsigned number to char string in decimal notation.
+ @param dptr Pointer to buffer for string.
+ @param sz Buffer size (number of char).
+ @param val Value to write.
+ @param padsz Minimum number of digits.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4ma_write_wx_decimal_unsigned(
+ wxChar *dptr, size_t sz, dk4_um_t val, size_t padsz, dk4_er_t *erp
+);
+
+/** Write signed number to char string in decimal notation.
+ @param dptr Pointer to buffer for string.
+ @param sz Buffer size (number of char).
+ @param val Value to write.
+ @param padsz Minimum number of digits.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4ma_write_wx_decimal_signed(
+ wxChar *dptr, size_t sz, dk4_im_t val, size_t padsz, dk4_er_t *erp
+);
+
+
+}
+
+
+
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4maoxdbl.cpp b/support/dktools/dk4maoxdbl.cpp
new file mode 100644
index 0000000000..1218a31b97
--- /dev/null
+++ b/support/dktools/dk4maoxdbl.cpp
@@ -0,0 +1,78 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maoxdbl.cpt
+*/
+
+/*
+Copyright (C) 2017-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4maoxdbl.cpp The dk4maoxdbl module.
+*/
+
+
+#line 95 "dk4maoxdbl.cpt"
+
+#include "dk4conf.h"
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#include "dk4maoxdbl.h"
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR == DK4_SIZEOF_WCHAR_T
+#include "dk4maowdbl.h"
+#else
+#error "Illegal wxChar size!"
+#endif
+#else
+#include "dk4mao8dbl.h"
+#endif
+
+
+int
+dk4ma_write_wx_double(
+ wxChar *dptr, size_t szdptr, double v, int exact, int minimize, dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4ma_write_wc_double(dptr, szdptr, v, exact, minimize, erp));
+#else
+ return (dk4ma_write_c8_double(dptr, szdptr, v, exact, minimize, erp));
+#endif
+}
+
+
+
+#endif
+
diff --git a/support/dktools/dk4maoxdbl.cpt b/support/dktools/dk4maoxdbl.cpt
new file mode 100644
index 0000000000..bb15b3245c
--- /dev/null
+++ b/support/dktools/dk4maoxdbl.cpt
@@ -0,0 +1,132 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2017-xxxx
+license = bsd
+
+%% header
+
+/** @file
+ Double to dkChar text conversion using more secure functions than
+ swprintf() or sprintf() if available.
+
+ CRT on Windows: Required.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+
+extern "C" {
+
+/** Convert double value to string.
+ @param dptr Destination buffer pointer.
+ @param szdptr Size of destination buffer (number of dkChar).
+ @param v Value to convert.
+ @param exact Flag: Save exact representation of number.
+ @param minimize Flag: Minimize exact representation.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or szdptr is less than 2,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the destination buffer is too small to store the string.
+*/
+int
+dk4ma_write_wx_double(
+ wxChar *dptr, size_t szdptr, double v, int exact, int minimize, dk4_er_t *erp
+);
+
+}
+
+
+
+#endif
+
+
+%% module
+
+#include "dk4conf.h"
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+#include "dk4maoxdbl.h"
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR == DK4_SIZEOF_WCHAR_T
+#include "dk4maowdbl.h"
+#else
+#error "Illegal wxChar size!"
+#endif
+#else
+#include "dk4mao8dbl.h"
+#endif
+
+
+int
+dk4ma_write_wx_double(
+ wxChar *dptr, size_t szdptr, double v, int exact, int minimize, dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4ma_write_wc_double(dptr, szdptr, v, exact, minimize, erp));
+#else
+ return (dk4ma_write_c8_double(dptr, szdptr, v, exact, minimize, erp));
+#endif
+}
+
+
+
+#endif
+
diff --git a/support/dktools/dk4maoxdbl.h b/support/dktools/dk4maoxdbl.h
new file mode 100644
index 0000000000..c912ed94ce
--- /dev/null
+++ b/support/dktools/dk4maoxdbl.h
@@ -0,0 +1,129 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4maoxdbl.cpt
+*/
+
+/*
+Copyright (C) 2017-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MAOXDBL_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MAOXDBL_H_INCLUDED 1
+
+
+#line 8 "dk4maoxdbl.cpt"
+
+/** @file
+ Double to dkChar text conversion using more secure functions than
+ swprintf() or sprintf() if available.
+
+ CRT on Windows: Required.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#if (DK4_HAVE_WXWIDGETS) && (defined(__cplusplus))
+
+
+
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+
+extern "C" {
+
+/** Convert double value to string.
+ @param dptr Destination buffer pointer.
+ @param szdptr Size of destination buffer (number of dkChar).
+ @param v Value to convert.
+ @param exact Flag: Save exact representation of number.
+ @param minimize Flag: Minimize exact representation.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or szdptr is less than 2,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the destination buffer is too small to store the string.
+*/
+int
+dk4ma_write_wx_double(
+ wxChar *dptr, size_t szdptr, double v, int exact, int minimize, dk4_er_t *erp
+);
+
+}
+
+
+
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4masz.c b/support/dktools/dk4masz.c
new file mode 100644
index 0000000000..68aabdc33e
--- /dev/null
+++ b/support/dktools/dk4masz.c
@@ -0,0 +1,92 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4masz.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4masz.c The dk4masz module.
+*/
+
+
+#line 55 "dk4masz.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+#if DK4_HAVE_LIMITS_H
+#ifndef LIMITS_H_INCLUDED
+#include <limits.h>
+#define LIMITS_H_INCLUDED 1
+#endif
+#endif
+#if DK4_HAVE_STDINT_H
+#ifndef STDINT_H_INCLUDED
+#if defined(__cplusplus) && (!defined(__STDC_LIMIT_MACROS))
+#define __STDC_LIMIT_MACROS 1
+#endif
+#if defined(__cplusplus) && (!defined(__STDC_CONSTANT_MACROS))
+#define __STDC_CONSTANT_MACROS 1
+#endif
+#include <stdint.h>
+#define STDINT_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4error.h"
+#include "dk4masz.h"
+#include "dk4error.h"
+#include "dk4numco.h"
+
+
+
+size_t
+dk4ma_size_t_add(size_t a, size_t b, dk4_er_t *erp)
+{
+ if ((SIZE_MAX - b) < a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return (a + b);
+}
+
+
+
+size_t
+dk4ma_size_t_mul(size_t a, size_t b, dk4_er_t *erp)
+{
+ if ((0 < a) && (0 < b)) {
+ if ((SIZE_MAX / a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return (a * b);
+}
+
diff --git a/support/dktools/dk4masz.ctr b/support/dktools/dk4masz.ctr
new file mode 100644
index 0000000000..441c8d70a4
--- /dev/null
+++ b/support/dktools/dk4masz.ctr
@@ -0,0 +1,106 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ Arithmetic operations on size_t.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Addition of size_t values.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result.
+*/
+size_t
+dk4ma_size_t_add(size_t a, size_t b, dk4_er_t *erp);
+
+/** Multiplication of size_t values.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result.
+*/
+size_t
+dk4ma_size_t_mul(size_t a, size_t b, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+#if DK4_HAVE_LIMITS_H
+#ifndef LIMITS_H_INCLUDED
+#include <limits.h>
+#define LIMITS_H_INCLUDED 1
+#endif
+#endif
+#if DK4_HAVE_STDINT_H
+#ifndef STDINT_H_INCLUDED
+#if defined(__cplusplus) && (!defined(__STDC_LIMIT_MACROS))
+#define __STDC_LIMIT_MACROS 1
+#endif
+#if defined(__cplusplus) && (!defined(__STDC_CONSTANT_MACROS))
+#define __STDC_CONSTANT_MACROS 1
+#endif
+#include <stdint.h>
+#define STDINT_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4error.h"
+#include "dk4masz.h"
+#include "dk4error.h"
+#include "dk4numco.h"
+
+
+
+size_t
+dk4ma_size_t_add(size_t a, size_t b, dk4_er_t *erp)
+{
+ if ((SIZE_MAX - b) < a) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ return (a + b);
+}
+
+
+
+size_t
+dk4ma_size_t_mul(size_t a, size_t b, dk4_er_t *erp)
+{
+ if ((0 < a) && (0 < b)) {
+ if ((SIZE_MAX / a) < b) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ return (a * b);
+}
+
diff --git a/support/dktools/dk4masz.h b/support/dktools/dk4masz.h
new file mode 100644
index 0000000000..a3c5dda66d
--- /dev/null
+++ b/support/dktools/dk4masz.h
@@ -0,0 +1,88 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4masz.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MASZ_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MASZ_H_INCLUDED 1
+
+
+#line 9 "dk4masz.ctr"
+
+/** @file
+ Arithmetic operations on size_t.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Addition of size_t values.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result.
+*/
+size_t
+dk4ma_size_t_add(size_t a, size_t b, dk4_er_t *erp);
+
+/** Multiplication of size_t values.
+ @param a Left operand.
+ @param b Right operand.
+ @param erp Error report, may be NULL.
+ @return Result.
+*/
+size_t
+dk4ma_size_t_mul(size_t a, size_t b, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4mbstrm.c b/support/dktools/dk4mbstrm.c
new file mode 100644
index 0000000000..d42b82ce65
--- /dev/null
+++ b/support/dktools/dk4mbstrm.c
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mbstrm.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mbstrm.c The dk4mbstrm module.
+*/
+
+
+#line 45 "dk4mbstrm.ctr"
+
+#include "dk4mbstrm.h"
+
+
+
+static
+void
+dk4stream_membuf_function(dk4_stream_api_t *api)
+{
+ dk4_membuf_t *mb;
+
+ if (NULL != api) {
+ api->res = 0;
+ api->sz_out = 0;
+ mb = (dk4_membuf_t *)(api->d);
+ if (NULL != mb) {
+ switch (api->cmd) {
+ case DK4_STREAM_API_WRITE: {
+ api->res = dk4membuf_store(
+ mb, (const void *)(api->b), api->sz_in, NULL
+ );
+ if (0 != api->res) {
+ api->sz_out = api->sz_in;
+ }
+ } break;
+ case DK4_STREAM_API_FLUSH: {
+ /* Do nothing but indicate success. */
+ api->res = 1;
+ } break;
+ case DK4_STREAM_API_CLOSE: {
+ /* Do nothing but indicate success. */
+ api->res = 1;
+ } break;
+ default : {
+ /* Do nothing, calling this is an error. */
+ } break;
+ }
+ }
+ }
+}
+
+
+
+dk4_stream_t *
+dk4stream_open_membuf_writer(dk4_membuf_t *mb, dk4_er_t *erp)
+{
+ dk4_stream_t *back = NULL;
+ if (NULL != mb) {
+ back = dk4stream_open(
+ mb, dk4stream_membuf_function,
+ DK4_STREAM_WRITE, 0, DK4MEMBUF_CHUNK_SIZE, erp
+ );
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+/* vim: set ai sw=4 ts=4 : */
+
diff --git a/support/dktools/dk4mbstrm.ctr b/support/dktools/dk4mbstrm.ctr
new file mode 100644
index 0000000000..e295336389
--- /dev/null
+++ b/support/dktools/dk4mbstrm.ctr
@@ -0,0 +1,106 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+
+%% header
+
+#ifndef DK4STRM_H_INCLUDED
+#include "dk4strm.h"
+#endif
+
+#ifndef DK4MEMBUF_H_INCLUDED
+#include "dk4membuf.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open stream to write to memory buffer.
+ Closing the resulting stream does not close the memory buffer.
+ @param mb Destination memory buffer.
+ @param erp Error report, may be NULL.
+ @return Valid pointer on success, NULL on error.
+*/
+
+dk4_stream_t *
+dk4stream_open_membuf_writer(dk4_membuf_t *mb, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/* vim: set ai sw=4 ts=4 : */
+%% module
+
+#include "dk4mbstrm.h"
+
+
+
+static
+void
+dk4stream_membuf_function(dk4_stream_api_t *api)
+{
+ dk4_membuf_t *mb;
+
+ if (NULL != api) {
+ api->res = 0;
+ api->sz_out = 0;
+ mb = (dk4_membuf_t *)(api->d);
+ if (NULL != mb) {
+ switch (api->cmd) {
+ case DK4_STREAM_API_WRITE: {
+ api->res = dk4membuf_store(
+ mb, (const void *)(api->b), api->sz_in, NULL
+ );
+ if (0 != api->res) {
+ api->sz_out = api->sz_in;
+ }
+ } break;
+ case DK4_STREAM_API_FLUSH: {
+ /* Do nothing but indicate success. */
+ api->res = 1;
+ } break;
+ case DK4_STREAM_API_CLOSE: {
+ /* Do nothing but indicate success. */
+ api->res = 1;
+ } break;
+ default : {
+ /* Do nothing, calling this is an error. */
+ } break;
+ }
+ }
+ }
+}
+
+
+
+dk4_stream_t *
+dk4stream_open_membuf_writer(dk4_membuf_t *mb, dk4_er_t *erp)
+{
+ dk4_stream_t *back = NULL;
+ if (NULL != mb) {
+ back = dk4stream_open(
+ mb, dk4stream_membuf_function,
+ DK4_STREAM_WRITE, 0, DK4MEMBUF_CHUNK_SIZE, erp
+ );
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+/* vim: set ai sw=4 ts=4 : */
+
diff --git a/support/dktools/dk4mbstrm.h b/support/dktools/dk4mbstrm.h
new file mode 100644
index 0000000000..d1435e358e
--- /dev/null
+++ b/support/dktools/dk4mbstrm.h
@@ -0,0 +1,81 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mbstrm.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mbstrm.h Header file for the dk4mbstrm module.
+*/
+
+#ifndef DK4MBSTRM_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MBSTRM_H_INCLUDED 1
+
+
+#line 9 "dk4mbstrm.ctr"
+
+#ifndef DK4STRM_H_INCLUDED
+#include "dk4strm.h"
+#endif
+
+#ifndef DK4MEMBUF_H_INCLUDED
+#include "dk4membuf.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open stream to write to memory buffer.
+ Closing the resulting stream does not close the memory buffer.
+ @param mb Destination memory buffer.
+ @param erp Error report, may be NULL.
+ @return Valid pointer on success, NULL on error.
+*/
+
+dk4_stream_t *
+dk4stream_open_membuf_writer(dk4_membuf_t *mb, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/* vim: set ai sw=4 ts=4 : */
+
+#endif
diff --git a/support/dktools/dk4md.c b/support/dktools/dk4md.c
new file mode 100644
index 0000000000..0a37fcd0b6
--- /dev/null
+++ b/support/dktools/dk4md.c
@@ -0,0 +1,550 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4md.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4md.c The dk4md module.
+*/
+
+
+#line 252 "dk4md.ctr"
+
+
+#include "dk4md.h"
+#include "dk4mem.h"
+#include "dk4numco.h"
+#include "dk4binenc.h"
+
+
+
+
+
+#line 262 "dk4md.ctr"
+
+
+
+int
+dk4md_ctx_init(dk4_md_ctx_t *ctxptr, int mdt, int mde, dk4_er_t *erp)
+{
+ int back = 0;
+ if (NULL != ctxptr) {
+ DK4_MEMRES(ctxptr, sizeof(dk4_md_ctx_t));
+ ctxptr->mdtype = -1;
+ ctxptr->encoding = -1;
+ switch (mde) {
+ case DK4_BINARY_TO_TEXT_ENCODING_HEX:
+ case DK4_BINARY_TO_TEXT_ENCODING_A85:
+ {
+ ctxptr->encoding = mde;
+ } break;
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ if (-1 != ctxptr->encoding) {
+ switch (mdt) {
+ case DK4_MD_MD5 : {
+#if DK4_HAVE_OPENSSL_MD5_H
+ ctxptr->mdtype = mdt;
+ if (1 == MD5_Init(&((ctxptr->ctx).md5))) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_MD_SHA1 : {
+#if DK4_HAVE_OPENSSL_SHA_H
+ ctxptr->mdtype = mdt;
+ if (1 == SHA1_Init(&((ctxptr->ctx).sha))) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_MD_SHA224 : {
+#if DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_SHA224
+ ctxptr->mdtype = mdt;
+ if (1 == SHA224_Init(&((ctxptr->ctx).sha256))) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_MD_SHA256 : {
+#if DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_SHA256
+ ctxptr->mdtype = mdt;
+ if (1 == SHA256_Init(&((ctxptr->ctx).sha256))) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_MD_SHA384 : {
+#if DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_SHA384
+ ctxptr->mdtype = mdt;
+ if (1 == SHA384_Init(&((ctxptr->ctx).sha512))) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_MD_SHA512 : {
+#if DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_SHA512
+ ctxptr->mdtype = mdt;
+ if (1 == SHA512_Init(&((ctxptr->ctx).sha512))) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_MD_RIPEMD_160 : {
+#if DK4_HAVE_OPENSSL_RIPEMD_H
+ ctxptr->mdtype = mdt;
+ if (1 == RIPEMD160_Init(&((ctxptr->ctx).ripemd160))) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4md_ctx_add(
+ dk4_md_ctx_t *ctxptr, const void *buffer, size_t sz, dk4_er_t *erp
+)
+{
+ int back = 0;
+ if ((NULL != ctxptr) && (NULL != buffer) && (0 < sz)) {
+ if ((dk4_um_t)sz <= (dk4_um_t)ULONG_MAX) {
+ if (-1 != ctxptr->mdtype) {
+ switch (ctxptr->mdtype) {
+ case DK4_MD_MD5 : {
+#if DK4_HAVE_OPENSSL_MD5_H
+ back = MD5_Update(
+ &((ctxptr->ctx).md5), buffer, (unsigned long)sz
+ );
+ if (0 == back) {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_MD_SHA1 : {
+#if DK4_HAVE_OPENSSL_SHA_H
+ back = SHA1_Update(
+ &((ctxptr->ctx).sha), buffer, (unsigned long)sz
+ );
+ if (0 == back) {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_MD_SHA224 : {
+#if DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_SHA224
+ back = SHA224_Update(
+ &((ctxptr->ctx).sha256), buffer, (unsigned long)sz
+ );
+ if (0 == back) {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_MD_SHA256 : {
+#if DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_SHA256
+ back = SHA256_Update(
+ &((ctxptr->ctx).sha256), buffer, (unsigned long)sz
+ );
+ if (0 == back) {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_MD_SHA384 : {
+#if DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_SHA384
+ back = SHA384_Update(
+ &((ctxptr->ctx).sha512), buffer, (unsigned long)sz
+ );
+ if (0 == back) {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_MD_SHA512 : {
+#if DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_SHA512
+ back = SHA512_Update(
+ &((ctxptr->ctx).sha512), buffer, (unsigned long)sz
+ );
+ if (0 == back) {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_MD_RIPEMD_160 : {
+#if DK4_HAVE_OPENSSL_RIPEMD_H
+ back = RIPEMD160_Update(
+ &((ctxptr->ctx).ripemd160), buffer, (unsigned long)sz
+ );
+ if (0 == back) {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4md_ctx_finish(
+ const char **rptr, size_t *rszptr, dk4_md_ctx_t *ctxptr, dk4_er_t *erp
+)
+{
+ int back = 0;
+
+
+#line 498 "dk4md.ctr"
+ if ((NULL != rptr) && (NULL != rszptr) && (NULL != ctxptr)) {
+ if (-1 != ctxptr->mdtype) {
+ switch (ctxptr->mdtype) {
+ case DK4_MD_MD5 : {
+#if DK4_HAVE_OPENSSL_MD5_H
+ back = MD5_Final(&(ctxptr->bbuf[0]), &((ctxptr->ctx).md5));
+ if (0 != back) {
+ back = dk4binenc(
+ &(ctxptr->obuf[0]), DK4MD_BUFFER_SIZE_TEXT,
+ &(ctxptr->bbuf[0]), 16,
+ ctxptr->encoding, erp
+ );
+ if (0 != back) {
+ *rptr = &(ctxptr->obuf[0]);
+ switch (ctxptr->encoding) {
+ case DK4_BINARY_TO_TEXT_ENCODING_NONE : { *rszptr = 16; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_HEX : { *rszptr = 32; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_A85 : { *rszptr = 20; } break;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_MD_SHA1 : {
+#if DK4_HAVE_OPENSSL_SHA_H
+ back = SHA1_Final(&(ctxptr->bbuf[0]), &((ctxptr->ctx).sha));
+ if (0 != back) {
+ back = dk4binenc(
+ &(ctxptr->obuf[0]), DK4MD_BUFFER_SIZE_TEXT,
+ &(ctxptr->bbuf[0]), 20,
+ ctxptr->encoding, erp
+ );
+ if (0 != back) {
+ *rptr = &(ctxptr->obuf[0]);
+ switch (ctxptr->encoding) {
+ case DK4_BINARY_TO_TEXT_ENCODING_NONE : { *rszptr = 20; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_HEX : { *rszptr = 40; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_A85 : { *rszptr = 25; } break;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_MD_SHA224 : {
+#if DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_SHA224
+ back = SHA224_Final(&(ctxptr->bbuf[0]), &((ctxptr->ctx).sha256));
+ if (0 != back) {
+ back = dk4binenc(
+ &(ctxptr->obuf[0]), DK4MD_BUFFER_SIZE_TEXT,
+ &(ctxptr->bbuf[0]), 28,
+ ctxptr->encoding, erp
+ );
+ if (0 != back) {
+ *rptr = &(ctxptr->obuf[0]);
+ switch (ctxptr->encoding) {
+ case DK4_BINARY_TO_TEXT_ENCODING_NONE : { *rszptr = 28; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_HEX : { *rszptr = 56; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_A85 : { *rszptr = 35; } break;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_MD_SHA256 : {
+#if DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_SHA256
+ back = SHA256_Final(&(ctxptr->bbuf[0]), &((ctxptr->ctx).sha256));
+ if (0 != back) {
+ back = dk4binenc(
+ &(ctxptr->obuf[0]), DK4MD_BUFFER_SIZE_TEXT,
+ &(ctxptr->bbuf[0]), 32,
+ ctxptr->encoding, erp
+ );
+ if (0 != back) {
+ *rptr = &(ctxptr->obuf[0]);
+ switch (ctxptr->encoding) {
+ case DK4_BINARY_TO_TEXT_ENCODING_NONE : { *rszptr = 32; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_HEX : { *rszptr = 64; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_A85 : { *rszptr = 40; } break;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_MD_SHA384 : {
+#if DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_SHA384
+ back = SHA384_Final(&(ctxptr->bbuf[0]), &((ctxptr->ctx).sha512));
+ if (0 != back) {
+ back = dk4binenc(
+ &(ctxptr->obuf[0]), DK4MD_BUFFER_SIZE_TEXT,
+ &(ctxptr->bbuf[0]), 48,
+ ctxptr->encoding, erp
+ );
+ if (0 != back) {
+ *rptr = &(ctxptr->obuf[0]);
+ switch (ctxptr->encoding) {
+ case DK4_BINARY_TO_TEXT_ENCODING_NONE : { *rszptr = 48; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_HEX : { *rszptr = 96; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_A85 : { *rszptr = 60; } break;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_MD_SHA512 : {
+
+#line 622 "dk4md.ctr"
+#if DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_SHA512
+
+
+#line 624 "dk4md.ctr"
+ back = SHA512_Final(&(ctxptr->bbuf[0]), &((ctxptr->ctx).sha512));
+ if (0 != back) {
+
+#line 626 "dk4md.ctr"
+ back = dk4binenc(
+ &(ctxptr->obuf[0]), DK4MD_BUFFER_SIZE_TEXT,
+ &(ctxptr->bbuf[0]), 64,
+ ctxptr->encoding, erp
+ );
+ if (0 != back) {
+
+#line 632 "dk4md.ctr"
+ *rptr = &(ctxptr->obuf[0]);
+
+#line 633 "dk4md.ctr"
+ switch (ctxptr->encoding) {
+ case DK4_BINARY_TO_TEXT_ENCODING_NONE : { *rszptr = 64; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_HEX : { *rszptr = 128;} break;
+ case DK4_BINARY_TO_TEXT_ENCODING_A85 : { *rszptr = 80; } break;
+ }
+ } else {
+
+#line 639 "dk4md.ctr"
+ }
+ } else {
+
+#line 641 "dk4md.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_MD_RIPEMD_160 : {
+#if DK4_HAVE_OPENSSL_RIPEMD_H
+ back = RIPEMD160_Final(&(ctxptr->bbuf[0]),&((ctxptr->ctx).ripemd160));
+ if (0 != back) {
+ back = dk4binenc(
+ &(ctxptr->obuf[0]), DK4MD_BUFFER_SIZE_TEXT,
+ &(ctxptr->bbuf[0]), 20,
+ ctxptr->encoding, erp
+ );
+ if (0 != back) {
+ *rptr = &(ctxptr->obuf[0]);
+ switch (ctxptr->encoding) {
+ case DK4_BINARY_TO_TEXT_ENCODING_NONE : { *rszptr = 20; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_HEX : { *rszptr = 40; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_A85 : { *rszptr = 25; } break;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ default : {
+ /* ERROR: Wrong MD type */
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ } break;
+ }
+ } else {
+ /* ERROR Wrong MD type */
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 683 "dk4md.ctr"
+ return back;
+}
+
+
+
+size_t
+dk4md_size(int mdt, int mde, dk4_er_t *erp)
+{
+ size_t back = 0;
+ switch (mdt) {
+ case DK4_MD_MD5 : {
+ switch (mde) {
+ case DK4_BINARY_TO_TEXT_ENCODING_NONE : { back = 16; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_HEX : { back = 32; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_A85 : { back = 20; } break;
+ }
+ } break;
+ case DK4_MD_SHA1 : case DK4_MD_RIPEMD_160 : {
+ switch (mde) {
+ case DK4_BINARY_TO_TEXT_ENCODING_NONE : { back = 20; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_HEX : { back = 40; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_A85 : { back = 25; } break;
+ }
+ } break;
+ case DK4_MD_SHA224 : {
+ switch (mde) {
+ case DK4_BINARY_TO_TEXT_ENCODING_NONE : { back = 28; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_HEX : { back = 56; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_A85 : { back = 35; } break;
+ }
+ } break;
+ case DK4_MD_SHA256 : {
+ switch (mde) {
+ case DK4_BINARY_TO_TEXT_ENCODING_NONE : { back = 32; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_HEX : { back = 64; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_A85 : { back = 40; } break;
+ }
+ } break;
+ case DK4_MD_SHA384 : {
+ switch (mde) {
+ case DK4_BINARY_TO_TEXT_ENCODING_NONE : { back = 48; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_HEX : { back = 96; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_A85 : { back = 60; } break;
+ }
+ } break;
+ case DK4_MD_SHA512 : {
+ switch (mde) {
+ case DK4_BINARY_TO_TEXT_ENCODING_NONE : { back = 64; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_HEX : { back = 128; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_A85 : { back = 80; } break;
+ }
+ } break;
+ }
+ if (0 == back) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4md.ctr b/support/dktools/dk4md.ctr
new file mode 100644
index 0000000000..358c9b097f
--- /dev/null
+++ b/support/dktools/dk4md.ctr
@@ -0,0 +1,741 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file dk4md.h Message digests.
+
+This module provides a simple API to use the message digest routines from
+the OpenSSL library.
+
+This product includes software developed by the OpenSSL Project for use in
+the OpenSSL Toolkit (http://www.openssl.org/).
+This product includes cryptographic software written by
+Eric Young (eay@cryptsoft.com).
+This product includes software written by Tim Hudson (tjh@cryptsoft.com).
+*/
+
+#include "dk4conf.h"
+#include "dk4binenc.h"
+#include "dk4error.h"
+
+
+#if DK4_HAVE_OPENSSL_MD5_H
+#ifndef OPENSSL_MD5_H_INCLUDED
+#include <openssl/md5.h>
+#define OPENSSL_MD5_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_OPENSSL_SHA_H
+#ifndef OPENSSL_SHA_H_INCLUDED
+#include <openssl/sha.h>
+#define OPENSSL_SHA_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_OPENSSL_RIPEMD_H
+#ifndef OPENSSL_RIPEMD_H_INCLUDED
+#include <openssl/ripemd.h>
+#define OPENSSL_RIPEMD_H_INCLUDED 1
+#endif
+#endif
+
+
+/*
+ At the moment the largest supported message digest is SHA-512,
+ producing 512 bit (64 bytes) of binary data.
+*/
+enum { /** Size of largest binary message digest.
+ */
+DK4MD_BUFFER_SIZE_BINARY = 64
+};
+
+enum { /** Size of largest text message digest,
+ 2 * DK4MD_BUFFER_SIZE_BINARY + 16.
+ */
+DK4MD_BUFFER_SIZE_TEXT = 144
+};
+
+
+
+/** Message digest creator.
+*/
+typedef struct {
+ char obuf[DK4MD_BUFFER_SIZE_TEXT]; /**< Result buffer. */
+ unsigned char bbuf[16 + DK4MD_BUFFER_SIZE_BINARY]; /**< Binary buffer. */
+ union {
+#if DK4_HAVE_SHA384 || DK4_HAVE_SHA512
+ SHA512_CTX sha512; /**< SHA-512, SHA-384. */
+#endif
+#if DK4_HAVE_SHA224 || DK4_HAVE_SHA256
+ SHA256_CTX sha256; /**< SHA-256, SHA-224. */
+#endif
+#if DK4_HAVE_OPENSSL_SHA_H
+ SHA_CTX sha; /**< SHA-1. */
+#endif
+#if DK4_HAVE_OPENSSL_RIPEMD_H
+ RIPEMD160_CTX ripemd160; /**< RIPEMD-160. */
+#endif
+#if DK4_HAVE_OPENSSL_MD5_H
+ MD5_CTX md5; /**< MD5. */
+#endif
+ int dummy; /**< If none of the above defined. */
+ } ctx; /**< Message digest context. */
+ int mdtype; /**< Message digest type. */
+ int encoding; /**< Required output encoding. */
+} dk4_md_ctx_t;
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Initialize CTX structure.
+ @param ctxptr Structure to initialize.
+ @param mdt Message digest type, one from:
+ DK4_MD_MD5, DK4_MD_SHA1, DK4_MD_SHA224,
+ DK4_MD_SHA256, DK4_MD_SHA384, DK4_MD_SHA512, or
+ DK4_MD_RIPEMD_160.
+ @param mde Message digest encoding, one from:
+ DK4_BINARY_TO_TEXT_ENCODING_HEX or
+ DK4_BINARY_TO_TEXT_ENCODING_A85.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if ctxptr is NULL,
+ - DK4_E_SYNTAX<br>
+ if an invalid value is specified for mdt or mde,
+ - DK4_E_NOT_SUPPORTED<br>
+ if the specified message digest type is not available.
+ - DK4_E_SYSTEM<br>
+ if the underlaying library indicated an error.<br>
+ Note: iDetails is not set to an errno value.
+*/
+int
+dk4md_ctx_init(dk4_md_ctx_t *ctxptr, int mdt, int mde, dk4_er_t *erp);
+
+/** Add bytes to CTX.
+ @param ctxptr CTX structure.
+ @param buffer Start address of buffer containing bytes to add.
+ @param sz Buffer size.
+ @param erp Error report, may be NULL.
+ @return 1 on success 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if ctxptr or buffer is NULL or sz is 0 or sz exceeds the
+ range for unsigned long,
+ - DK4_E_SYNTAX<br>
+ if an invalid value is specified for mdt.
+ - DK4_E_NOT_SUPPORTED<br>
+ if the specified message digest type is not available.
+ - DK4_E_SYSTEM<br>
+ if the underlaying library indicated an error.<br>
+ Note: iDetails is not set to an errno value.
+*/
+int
+dk4md_ctx_add(
+ dk4_md_ctx_t *ctxptr, const void *buffer, size_t sz, dk4_er_t *erp
+);
+
+/** Finish checksum and create text representation.
+ @param rptr Address of pointer variable for result buffer,
+ the variable should be initialized to NULL.
+ @param rszptr Address of size variable for result buffer, the
+ variable should be initialized to 0.
+ @param ctxptr CTX structure.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if rptr, rszptr, or ctxptr is NULL,
+ - DK4_E_NOT_SUPPORTED<br>
+ if the specified message digest type is not available.
+*/
+int
+dk4md_ctx_finish(
+ const char **rptr, size_t *rszptr, dk4_md_ctx_t *ctxptr, dk4_er_t *erp
+);
+
+/** Find message digest size (number of binary bytes or text characters
+ without finalizing 0 byte).
+ @param mdt Message digest type, one from: DK4_MD_MD5,
+ DK4_MD_SHA1, DK4_MD_SHA224, DK4_MD_SHA256,
+ DK4_MD_SHA384, DK4_MD_SHA512, or DK4_MD_RIPEMD_160.
+ @param mde Message digest encoding, one from:
+ DK4_BINARY_TO_TEXT_ENCODING_NONE,
+ DK4_BINARY_TO_TEXT_ENCODING_HEX, or
+ DK4_BINARY_TO_TEXT_ENCODING_A85.
+ @param erp Error report, may be NULL.
+ @return Number of bytes or text characters on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ for illegal mdt or mde values.
+*/
+size_t
+dk4md_size(int mdt, int mde, dk4_er_t *erp);
+
+/** Find numeric message digest type for string.
+ @param name Message digest type name.
+ @param erp Error report, may be NULL.
+ @return Non-negative message digest type on success, -1 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if name is NULL,
+ - DK4_E_SYNTAX<br>
+ if name is not a valid message digest type name.
+*/
+int
+dk4md_choose_type(const dkChar *name, dk4_er_t *erp);
+
+/** Check whether support for a message type is available.
+ @param mdtype Message type to check for.
+ @return 1 if supported, 0 otherwise.
+*/
+int
+dk4md_check_type(int mdtype);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+/** Message digest types.
+*/
+enum {
+
+ /** MD5.
+ */
+ DK4_MD_MD5 = 0 ,
+
+ /** SHA-1.
+ */
+ DK4_MD_SHA1 ,
+
+ /** SHA-224.
+ */
+ DK4_MD_SHA224 ,
+
+ /** SHA-256.
+ */
+ DK4_MD_SHA256 ,
+
+ /** SHA-384.
+ */
+ DK4_MD_SHA384 ,
+
+ /** SHA-512.
+ */
+ DK4_MD_SHA512 ,
+
+ /** RIPEMD-160.
+ */
+ DK4_MD_RIPEMD_160
+
+};
+
+
+
+%% module
+
+
+#include "dk4md.h"
+#include "dk4mem.h"
+#include "dk4numco.h"
+#include "dk4binenc.h"
+
+
+
+$!trace-include
+
+
+
+int
+dk4md_ctx_init(dk4_md_ctx_t *ctxptr, int mdt, int mde, dk4_er_t *erp)
+{
+ int back = 0;
+ if (NULL != ctxptr) {
+ DK4_MEMRES(ctxptr, sizeof(dk4_md_ctx_t));
+ ctxptr->mdtype = -1;
+ ctxptr->encoding = -1;
+ switch (mde) {
+ case DK4_BINARY_TO_TEXT_ENCODING_HEX:
+ case DK4_BINARY_TO_TEXT_ENCODING_A85:
+ {
+ ctxptr->encoding = mde;
+ } break;
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ if (-1 != ctxptr->encoding) {
+ switch (mdt) {
+ case DK4_MD_MD5 : {
+#if DK4_HAVE_OPENSSL_MD5_H
+ ctxptr->mdtype = mdt;
+ if (1 == MD5_Init(&((ctxptr->ctx).md5))) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_MD_SHA1 : {
+#if DK4_HAVE_OPENSSL_SHA_H
+ ctxptr->mdtype = mdt;
+ if (1 == SHA1_Init(&((ctxptr->ctx).sha))) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_MD_SHA224 : {
+#if DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_SHA224
+ ctxptr->mdtype = mdt;
+ if (1 == SHA224_Init(&((ctxptr->ctx).sha256))) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_MD_SHA256 : {
+#if DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_SHA256
+ ctxptr->mdtype = mdt;
+ if (1 == SHA256_Init(&((ctxptr->ctx).sha256))) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_MD_SHA384 : {
+#if DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_SHA384
+ ctxptr->mdtype = mdt;
+ if (1 == SHA384_Init(&((ctxptr->ctx).sha512))) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_MD_SHA512 : {
+#if DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_SHA512
+ ctxptr->mdtype = mdt;
+ if (1 == SHA512_Init(&((ctxptr->ctx).sha512))) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_MD_RIPEMD_160 : {
+#if DK4_HAVE_OPENSSL_RIPEMD_H
+ ctxptr->mdtype = mdt;
+ if (1 == RIPEMD160_Init(&((ctxptr->ctx).ripemd160))) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4md_ctx_add(
+ dk4_md_ctx_t *ctxptr, const void *buffer, size_t sz, dk4_er_t *erp
+)
+{
+ int back = 0;
+ if ((NULL != ctxptr) && (NULL != buffer) && (0 < sz)) {
+ if ((dk4_um_t)sz <= (dk4_um_t)ULONG_MAX) {
+ if (-1 != ctxptr->mdtype) {
+ switch (ctxptr->mdtype) {
+ case DK4_MD_MD5 : {
+#if DK4_HAVE_OPENSSL_MD5_H
+ back = MD5_Update(
+ &((ctxptr->ctx).md5), buffer, (unsigned long)sz
+ );
+ if (0 == back) {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_MD_SHA1 : {
+#if DK4_HAVE_OPENSSL_SHA_H
+ back = SHA1_Update(
+ &((ctxptr->ctx).sha), buffer, (unsigned long)sz
+ );
+ if (0 == back) {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_MD_SHA224 : {
+#if DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_SHA224
+ back = SHA224_Update(
+ &((ctxptr->ctx).sha256), buffer, (unsigned long)sz
+ );
+ if (0 == back) {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_MD_SHA256 : {
+#if DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_SHA256
+ back = SHA256_Update(
+ &((ctxptr->ctx).sha256), buffer, (unsigned long)sz
+ );
+ if (0 == back) {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_MD_SHA384 : {
+#if DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_SHA384
+ back = SHA384_Update(
+ &((ctxptr->ctx).sha512), buffer, (unsigned long)sz
+ );
+ if (0 == back) {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_MD_SHA512 : {
+#if DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_SHA512
+ back = SHA512_Update(
+ &((ctxptr->ctx).sha512), buffer, (unsigned long)sz
+ );
+ if (0 == back) {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_MD_RIPEMD_160 : {
+#if DK4_HAVE_OPENSSL_RIPEMD_H
+ back = RIPEMD160_Update(
+ &((ctxptr->ctx).ripemd160), buffer, (unsigned long)sz
+ );
+ if (0 == back) {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4md_ctx_finish(
+ const char **rptr, size_t *rszptr, dk4_md_ctx_t *ctxptr, dk4_er_t *erp
+)
+{
+ int back = 0;
+ $? "+ dk4md_ctx_finish"
+ if ((NULL != rptr) && (NULL != rszptr) && (NULL != ctxptr)) {
+ if (-1 != ctxptr->mdtype) {
+ switch (ctxptr->mdtype) {
+ case DK4_MD_MD5 : {
+#if DK4_HAVE_OPENSSL_MD5_H
+ back = MD5_Final(&(ctxptr->bbuf[0]), &((ctxptr->ctx).md5));
+ if (0 != back) {
+ back = dk4binenc(
+ &(ctxptr->obuf[0]), DK4MD_BUFFER_SIZE_TEXT,
+ &(ctxptr->bbuf[0]), 16,
+ ctxptr->encoding, erp
+ );
+ if (0 != back) {
+ *rptr = &(ctxptr->obuf[0]);
+ switch (ctxptr->encoding) {
+ case DK4_BINARY_TO_TEXT_ENCODING_NONE : { *rszptr = 16; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_HEX : { *rszptr = 32; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_A85 : { *rszptr = 20; } break;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_MD_SHA1 : {
+#if DK4_HAVE_OPENSSL_SHA_H
+ back = SHA1_Final(&(ctxptr->bbuf[0]), &((ctxptr->ctx).sha));
+ if (0 != back) {
+ back = dk4binenc(
+ &(ctxptr->obuf[0]), DK4MD_BUFFER_SIZE_TEXT,
+ &(ctxptr->bbuf[0]), 20,
+ ctxptr->encoding, erp
+ );
+ if (0 != back) {
+ *rptr = &(ctxptr->obuf[0]);
+ switch (ctxptr->encoding) {
+ case DK4_BINARY_TO_TEXT_ENCODING_NONE : { *rszptr = 20; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_HEX : { *rszptr = 40; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_A85 : { *rszptr = 25; } break;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_MD_SHA224 : {
+#if DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_SHA224
+ back = SHA224_Final(&(ctxptr->bbuf[0]), &((ctxptr->ctx).sha256));
+ if (0 != back) {
+ back = dk4binenc(
+ &(ctxptr->obuf[0]), DK4MD_BUFFER_SIZE_TEXT,
+ &(ctxptr->bbuf[0]), 28,
+ ctxptr->encoding, erp
+ );
+ if (0 != back) {
+ *rptr = &(ctxptr->obuf[0]);
+ switch (ctxptr->encoding) {
+ case DK4_BINARY_TO_TEXT_ENCODING_NONE : { *rszptr = 28; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_HEX : { *rszptr = 56; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_A85 : { *rszptr = 35; } break;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_MD_SHA256 : {
+#if DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_SHA256
+ back = SHA256_Final(&(ctxptr->bbuf[0]), &((ctxptr->ctx).sha256));
+ if (0 != back) {
+ back = dk4binenc(
+ &(ctxptr->obuf[0]), DK4MD_BUFFER_SIZE_TEXT,
+ &(ctxptr->bbuf[0]), 32,
+ ctxptr->encoding, erp
+ );
+ if (0 != back) {
+ *rptr = &(ctxptr->obuf[0]);
+ switch (ctxptr->encoding) {
+ case DK4_BINARY_TO_TEXT_ENCODING_NONE : { *rszptr = 32; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_HEX : { *rszptr = 64; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_A85 : { *rszptr = 40; } break;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_MD_SHA384 : {
+#if DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_SHA384
+ back = SHA384_Final(&(ctxptr->bbuf[0]), &((ctxptr->ctx).sha512));
+ if (0 != back) {
+ back = dk4binenc(
+ &(ctxptr->obuf[0]), DK4MD_BUFFER_SIZE_TEXT,
+ &(ctxptr->bbuf[0]), 48,
+ ctxptr->encoding, erp
+ );
+ if (0 != back) {
+ *rptr = &(ctxptr->obuf[0]);
+ switch (ctxptr->encoding) {
+ case DK4_BINARY_TO_TEXT_ENCODING_NONE : { *rszptr = 48; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_HEX : { *rszptr = 96; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_A85 : { *rszptr = 60; } break;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_MD_SHA512 : { $? ". sha-512 wanted"
+#if DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_SHA512
+ $? ". sha-512 supported"
+ back = SHA512_Final(&(ctxptr->bbuf[0]), &((ctxptr->ctx).sha512));
+ if (0 != back) { $? ". SHA512_Final()"
+ back = dk4binenc(
+ &(ctxptr->obuf[0]), DK4MD_BUFFER_SIZE_TEXT,
+ &(ctxptr->bbuf[0]), 64,
+ ctxptr->encoding, erp
+ );
+ if (0 != back) { $? ". dk4binenc"
+ *rptr = &(ctxptr->obuf[0]); $? ". setting pointer"
+ switch (ctxptr->encoding) {
+ case DK4_BINARY_TO_TEXT_ENCODING_NONE : { *rszptr = 64; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_HEX : { *rszptr = 128;} break;
+ case DK4_BINARY_TO_TEXT_ENCODING_A85 : { *rszptr = 80; } break;
+ }
+ } else { $? "! dk4binenc"
+ }
+ } else { $? "! SHA512_Final()"
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_MD_RIPEMD_160 : {
+#if DK4_HAVE_OPENSSL_RIPEMD_H
+ back = RIPEMD160_Final(&(ctxptr->bbuf[0]),&((ctxptr->ctx).ripemd160));
+ if (0 != back) {
+ back = dk4binenc(
+ &(ctxptr->obuf[0]), DK4MD_BUFFER_SIZE_TEXT,
+ &(ctxptr->bbuf[0]), 20,
+ ctxptr->encoding, erp
+ );
+ if (0 != back) {
+ *rptr = &(ctxptr->obuf[0]);
+ switch (ctxptr->encoding) {
+ case DK4_BINARY_TO_TEXT_ENCODING_NONE : { *rszptr = 20; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_HEX : { *rszptr = 40; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_A85 : { *rszptr = 25; } break;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ default : {
+ /* ERROR: Wrong MD type */
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ } break;
+ }
+ } else {
+ /* ERROR Wrong MD type */
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4md_ctx_finish %d", back
+ return back;
+}
+
+
+
+size_t
+dk4md_size(int mdt, int mde, dk4_er_t *erp)
+{
+ size_t back = 0;
+ switch (mdt) {
+ case DK4_MD_MD5 : {
+ switch (mde) {
+ case DK4_BINARY_TO_TEXT_ENCODING_NONE : { back = 16; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_HEX : { back = 32; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_A85 : { back = 20; } break;
+ }
+ } break;
+ case DK4_MD_SHA1 : case DK4_MD_RIPEMD_160 : {
+ switch (mde) {
+ case DK4_BINARY_TO_TEXT_ENCODING_NONE : { back = 20; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_HEX : { back = 40; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_A85 : { back = 25; } break;
+ }
+ } break;
+ case DK4_MD_SHA224 : {
+ switch (mde) {
+ case DK4_BINARY_TO_TEXT_ENCODING_NONE : { back = 28; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_HEX : { back = 56; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_A85 : { back = 35; } break;
+ }
+ } break;
+ case DK4_MD_SHA256 : {
+ switch (mde) {
+ case DK4_BINARY_TO_TEXT_ENCODING_NONE : { back = 32; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_HEX : { back = 64; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_A85 : { back = 40; } break;
+ }
+ } break;
+ case DK4_MD_SHA384 : {
+ switch (mde) {
+ case DK4_BINARY_TO_TEXT_ENCODING_NONE : { back = 48; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_HEX : { back = 96; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_A85 : { back = 60; } break;
+ }
+ } break;
+ case DK4_MD_SHA512 : {
+ switch (mde) {
+ case DK4_BINARY_TO_TEXT_ENCODING_NONE : { back = 64; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_HEX : { back = 128; } break;
+ case DK4_BINARY_TO_TEXT_ENCODING_A85 : { back = 80; } break;
+ }
+ } break;
+ }
+ if (0 == back) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4md.h b/support/dktools/dk4md.h
new file mode 100644
index 0000000000..7ae2337133
--- /dev/null
+++ b/support/dktools/dk4md.h
@@ -0,0 +1,285 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4md.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MD_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MD_H_INCLUDED 1
+
+
+#line 9 "dk4md.ctr"
+
+/** @file dk4md.h Message digests.
+
+This module provides a simple API to use the message digest routines from
+the OpenSSL library.
+
+This product includes software developed by the OpenSSL Project for use in
+the OpenSSL Toolkit (http://www.openssl.org/).
+This product includes cryptographic software written by
+Eric Young (eay@cryptsoft.com).
+This product includes software written by Tim Hudson (tjh@cryptsoft.com).
+*/
+
+#include "dk4conf.h"
+#include "dk4binenc.h"
+#include "dk4error.h"
+
+
+#if DK4_HAVE_OPENSSL_MD5_H
+#ifndef OPENSSL_MD5_H_INCLUDED
+#include <openssl/md5.h>
+#define OPENSSL_MD5_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_OPENSSL_SHA_H
+#ifndef OPENSSL_SHA_H_INCLUDED
+#include <openssl/sha.h>
+#define OPENSSL_SHA_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_OPENSSL_RIPEMD_H
+#ifndef OPENSSL_RIPEMD_H_INCLUDED
+#include <openssl/ripemd.h>
+#define OPENSSL_RIPEMD_H_INCLUDED 1
+#endif
+#endif
+
+
+/*
+ At the moment the largest supported message digest is SHA-512,
+ producing 512 bit (64 bytes) of binary data.
+*/
+enum { /** Size of largest binary message digest.
+ */
+DK4MD_BUFFER_SIZE_BINARY = 64
+};
+
+enum { /** Size of largest text message digest,
+ 2 * DK4MD_BUFFER_SIZE_BINARY + 16.
+ */
+DK4MD_BUFFER_SIZE_TEXT = 144
+};
+
+
+
+/** Message digest creator.
+*/
+typedef struct {
+ char obuf[DK4MD_BUFFER_SIZE_TEXT]; /**< Result buffer. */
+ unsigned char bbuf[16 + DK4MD_BUFFER_SIZE_BINARY]; /**< Binary buffer. */
+ union {
+#if DK4_HAVE_SHA384 || DK4_HAVE_SHA512
+ SHA512_CTX sha512; /**< SHA-512, SHA-384. */
+#endif
+#if DK4_HAVE_SHA224 || DK4_HAVE_SHA256
+ SHA256_CTX sha256; /**< SHA-256, SHA-224. */
+#endif
+#if DK4_HAVE_OPENSSL_SHA_H
+ SHA_CTX sha; /**< SHA-1. */
+#endif
+#if DK4_HAVE_OPENSSL_RIPEMD_H
+ RIPEMD160_CTX ripemd160; /**< RIPEMD-160. */
+#endif
+#if DK4_HAVE_OPENSSL_MD5_H
+ MD5_CTX md5; /**< MD5. */
+#endif
+ int dummy; /**< If none of the above defined. */
+ } ctx; /**< Message digest context. */
+ int mdtype; /**< Message digest type. */
+ int encoding; /**< Required output encoding. */
+} dk4_md_ctx_t;
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Initialize CTX structure.
+ @param ctxptr Structure to initialize.
+ @param mdt Message digest type, one from:
+ DK4_MD_MD5, DK4_MD_SHA1, DK4_MD_SHA224,
+ DK4_MD_SHA256, DK4_MD_SHA384, DK4_MD_SHA512, or
+ DK4_MD_RIPEMD_160.
+ @param mde Message digest encoding, one from:
+ DK4_BINARY_TO_TEXT_ENCODING_HEX or
+ DK4_BINARY_TO_TEXT_ENCODING_A85.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if ctxptr is NULL,
+ - DK4_E_SYNTAX<br>
+ if an invalid value is specified for mdt or mde,
+ - DK4_E_NOT_SUPPORTED<br>
+ if the specified message digest type is not available.
+ - DK4_E_SYSTEM<br>
+ if the underlaying library indicated an error.<br>
+ Note: iDetails is not set to an errno value.
+*/
+int
+dk4md_ctx_init(dk4_md_ctx_t *ctxptr, int mdt, int mde, dk4_er_t *erp);
+
+/** Add bytes to CTX.
+ @param ctxptr CTX structure.
+ @param buffer Start address of buffer containing bytes to add.
+ @param sz Buffer size.
+ @param erp Error report, may be NULL.
+ @return 1 on success 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if ctxptr or buffer is NULL or sz is 0 or sz exceeds the
+ range for unsigned long,
+ - DK4_E_SYNTAX<br>
+ if an invalid value is specified for mdt.
+ - DK4_E_NOT_SUPPORTED<br>
+ if the specified message digest type is not available.
+ - DK4_E_SYSTEM<br>
+ if the underlaying library indicated an error.<br>
+ Note: iDetails is not set to an errno value.
+*/
+int
+dk4md_ctx_add(
+ dk4_md_ctx_t *ctxptr, const void *buffer, size_t sz, dk4_er_t *erp
+);
+
+/** Finish checksum and create text representation.
+ @param rptr Address of pointer variable for result buffer,
+ the variable should be initialized to NULL.
+ @param rszptr Address of size variable for result buffer, the
+ variable should be initialized to 0.
+ @param ctxptr CTX structure.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if rptr, rszptr, or ctxptr is NULL,
+ - DK4_E_NOT_SUPPORTED<br>
+ if the specified message digest type is not available.
+*/
+int
+dk4md_ctx_finish(
+ const char **rptr, size_t *rszptr, dk4_md_ctx_t *ctxptr, dk4_er_t *erp
+);
+
+/** Find message digest size (number of binary bytes or text characters
+ without finalizing 0 byte).
+ @param mdt Message digest type, one from: DK4_MD_MD5,
+ DK4_MD_SHA1, DK4_MD_SHA224, DK4_MD_SHA256,
+ DK4_MD_SHA384, DK4_MD_SHA512, or DK4_MD_RIPEMD_160.
+ @param mde Message digest encoding, one from:
+ DK4_BINARY_TO_TEXT_ENCODING_NONE,
+ DK4_BINARY_TO_TEXT_ENCODING_HEX, or
+ DK4_BINARY_TO_TEXT_ENCODING_A85.
+ @param erp Error report, may be NULL.
+ @return Number of bytes or text characters on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ for illegal mdt or mde values.
+*/
+size_t
+dk4md_size(int mdt, int mde, dk4_er_t *erp);
+
+/** Find numeric message digest type for string.
+ @param name Message digest type name.
+ @param erp Error report, may be NULL.
+ @return Non-negative message digest type on success, -1 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if name is NULL,
+ - DK4_E_SYNTAX<br>
+ if name is not a valid message digest type name.
+*/
+int
+dk4md_choose_type(const dkChar *name, dk4_er_t *erp);
+
+/** Check whether support for a message type is available.
+ @param mdtype Message type to check for.
+ @return 1 if supported, 0 otherwise.
+*/
+int
+dk4md_check_type(int mdtype);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+/** Message digest types.
+*/
+enum {
+
+ /** MD5.
+ */
+ DK4_MD_MD5 = 0 ,
+
+ /** SHA-1.
+ */
+ DK4_MD_SHA1 ,
+
+ /** SHA-224.
+ */
+ DK4_MD_SHA224 ,
+
+ /** SHA-256.
+ */
+ DK4_MD_SHA256 ,
+
+ /** SHA-384.
+ */
+ DK4_MD_SHA384 ,
+
+ /** SHA-512.
+ */
+ DK4_MD_SHA512 ,
+
+ /** RIPEMD-160.
+ */
+ DK4_MD_RIPEMD_160
+
+};
+
+
+
+
+#endif
diff --git a/support/dktools/dk4mdch.c b/support/dktools/dk4mdch.c
new file mode 100644
index 0000000000..b70e18990f
--- /dev/null
+++ b/support/dktools/dk4mdch.c
@@ -0,0 +1,159 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mdch.ctr
+*/
+
+/** @file dk4mdch.c The dk4mdch module.
+*/
+
+
+#line 6 "dk4mdch.ctr"
+
+#include "dk4md.h"
+#include "dk4strd.h"
+
+
+
+
+
+#line 13 "dk4mdch.ctr"
+
+
+
+/** Message digest type names.
+ Order must match the definition order in the enum in dk4md.h.
+*/
+static const dkChar * const dk4md_type_names[] = {
+/* 0 */
+dkT("md5"),
+
+/* 1 */
+dkT("sha-1"),
+
+/* 2 */
+dkT("sha-224"),
+
+/* 3 */
+dkT("sha-256"),
+
+/* 4 */
+dkT("sha-384"),
+
+/* 5 */
+dkT("sha-512"),
+
+/* 6 */
+dkT("ripemd-160"),
+
+/* 7 */
+dkT("sha1"),
+
+/* 8 */
+dkT("sha224"),
+
+/* 9 */
+dkT("sha256"),
+
+/* 10 */
+dkT("sha384"),
+
+/* 11 */
+dkT("sha512"),
+
+/* 12 */
+dkT("ripemd160"),
+
+NULL
+
+
+#line 35 "dk4mdch.ctr"
+};
+
+
+
+int
+dk4md_choose_type(const dkChar *name, dk4_er_t *erp)
+{
+ int back = -1;
+ if (NULL != name) {
+ switch (dk4str_array_index(dk4md_type_names, name, 0)) {
+ case 0: {
+ back = DK4_MD_MD5;
+ } break;
+ case 1: case 7: {
+ back = DK4_MD_SHA1;
+ } break;
+ case 2: case 8: {
+ back = DK4_MD_SHA224;
+ } break;
+ case 3: case 9: {
+ back = DK4_MD_SHA256;
+ } break;
+ case 4: case 10: {
+ back = DK4_MD_SHA384;
+ } break;
+ case 5: case 11: {
+ back = DK4_MD_SHA512;
+ } break;
+ case 6: case 12: {
+ back = DK4_MD_RIPEMD_160;
+ } break;
+ }
+ if (-1 == back) {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4md_check_type(int mdtype)
+{
+ int back = 0;
+ switch (mdtype) {
+ case DK4_MD_MD5 : {
+#if DK4_HAVE_OPENSSL_MD5_H
+ back = 1;
+#endif
+ } break;
+ case DK4_MD_SHA1 : {
+#if DK4_HAVE_OPENSSL_SHA_H
+ back = 1;
+#endif
+ } break;
+ case DK4_MD_SHA224 : {
+#if DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_SHA224
+ back = 1;
+#endif
+ } break;
+ case DK4_MD_SHA256 : {
+#if DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_SHA256
+ back = 1;
+#endif
+ } break;
+ case DK4_MD_SHA384 : {
+#if DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_SHA384
+ back = 1;
+#endif
+ } break;
+ case DK4_MD_SHA512 : {
+#if DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_SHA512
+ back = 1;
+#endif
+ } break;
+ case DK4_MD_RIPEMD_160 : {
+#if DK4_HAVE_OPENSSL_RIPEMD_H
+ back = 1;
+#endif
+ } break;
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4mdch.ctr b/support/dktools/dk4mdch.ctr
new file mode 100644
index 0000000000..5d9693c0f7
--- /dev/null
+++ b/support/dktools/dk4mdch.ctr
@@ -0,0 +1,122 @@
+%% options
+
+
+
+%% module
+
+#include "dk4md.h"
+#include "dk4strd.h"
+
+
+
+$!trace-include
+
+
+
+/** Message digest type names.
+ Order must match the definition order in the enum in dk4md.h.
+*/
+static const dkChar * const dk4md_type_names[] = {
+$!string-table macro=dkT
+md5
+sha-1
+sha-224
+sha-256
+sha-384
+sha-512
+ripemd-160
+sha1
+sha224
+sha256
+sha384
+sha512
+ripemd160
+$!end
+};
+
+
+
+int
+dk4md_choose_type(const dkChar *name, dk4_er_t *erp)
+{
+ int back = -1;
+ if (NULL != name) {
+ switch (dk4str_array_index(dk4md_type_names, name, 0)) {
+ case 0: {
+ back = DK4_MD_MD5;
+ } break;
+ case 1: case 7: {
+ back = DK4_MD_SHA1;
+ } break;
+ case 2: case 8: {
+ back = DK4_MD_SHA224;
+ } break;
+ case 3: case 9: {
+ back = DK4_MD_SHA256;
+ } break;
+ case 4: case 10: {
+ back = DK4_MD_SHA384;
+ } break;
+ case 5: case 11: {
+ back = DK4_MD_SHA512;
+ } break;
+ case 6: case 12: {
+ back = DK4_MD_RIPEMD_160;
+ } break;
+ }
+ if (-1 == back) {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4md_check_type(int mdtype)
+{
+ int back = 0;
+ switch (mdtype) {
+ case DK4_MD_MD5 : {
+#if DK4_HAVE_OPENSSL_MD5_H
+ back = 1;
+#endif
+ } break;
+ case DK4_MD_SHA1 : {
+#if DK4_HAVE_OPENSSL_SHA_H
+ back = 1;
+#endif
+ } break;
+ case DK4_MD_SHA224 : {
+#if DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_SHA224
+ back = 1;
+#endif
+ } break;
+ case DK4_MD_SHA256 : {
+#if DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_SHA256
+ back = 1;
+#endif
+ } break;
+ case DK4_MD_SHA384 : {
+#if DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_SHA384
+ back = 1;
+#endif
+ } break;
+ case DK4_MD_SHA512 : {
+#if DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_SHA512
+ back = 1;
+#endif
+ } break;
+ case DK4_MD_RIPEMD_160 : {
+#if DK4_HAVE_OPENSSL_RIPEMD_H
+ back = 1;
+#endif
+ } break;
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4mem.c b/support/dktools/dk4mem.c
new file mode 100644
index 0000000000..a0da0418ae
--- /dev/null
+++ b/support/dktools/dk4mem.c
@@ -0,0 +1,378 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mem.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mem.c The dk4mem module.
+*/
+
+
+#line 699 "dk4mem.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS && (DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT)
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4types.h"
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+#if DK4_HAVE_STRINGS_H
+#ifndef STRINGS_H_INCLUDED
+#include <strings.h>
+#define STRINGS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4mem.h"
+#include "dk4numco.h"
+
+
+
+
+
+#line 730 "dk4mem.ctr"
+
+
+
+static
+void
+dk4mem_fallback_i_reset(unsigned char *bptr, size_t sz)
+{
+ while (0 < sz--) { *(bptr++) = '\0'; }
+}
+
+
+
+void
+dk4mem_fallback_reset(void *bptr, size_t sz)
+{
+ dk4mem_fallback_i_reset((unsigned char *)bptr, sz);
+}
+
+
+
+void
+dk4mem_reset(void *bptr, size_t sz, dk4_er_t *erp)
+{
+
+
+#line 754 "dk4mem.ctr"
+ if ((NULL != bptr) && (0 < sz)) {
+ DK4_MEMRES(bptr, sz);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 760 "dk4mem.ctr"
+}
+
+
+
+void
+dk4mem_set(void *bptr, size_t sz, unsigned char uc, dk4_er_t *erp)
+{
+#if !DK4_HAVE_MEMSET
+ unsigned char *ucptr;
+#endif
+ if ((NULL != bptr) && (0 < sz)) {
+#if DK4_HAVE_MEMSET
+ memset(bptr, (int)uc, sz);
+#else
+ ucptr = (unsigned char *)bptr;
+ while (0 < sz--) { *(ucptr++) = uc; }
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+}
+
+
+
+static
+void
+dk4mem_fallback_i_cpy(unsigned char *dst, const unsigned char *src, size_t sz)
+{
+ while(0 < sz--) { *(dst++) = *(src++); }
+}
+
+
+
+void
+dk4mem_fallback_cpy(void *dst, const void *src, size_t sz)
+{
+ dk4mem_fallback_i_cpy(
+ (unsigned char *)dst,
+ (const unsigned char *)src,
+ sz
+ );
+}
+
+
+
+void
+dk4mem_cpy(void *dst, void const *src, size_t sz, dk4_er_t *erp)
+{
+ if ((NULL != dst) && (NULL != src) && (0 < sz)) {
+ DK4_MEMCPY(dst, src, sz);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+}
+
+
+static
+int
+dk4mem_fallback_i_cmp(
+ const unsigned char *s1,
+ const unsigned char *s2,
+ size_t sz
+)
+{
+ int back = 0;
+ while ((0 < sz--) && (0 == back)) {
+ if (*s1 > *s2) {
+ back = 1;
+ } else {
+ if (*s1 < *s2) {
+ back = -1;
+ }
+ }
+ s1++; s2++;
+ }
+ return back;
+}
+
+
+
+int
+dk4mem_fallback_cmp(const void *s1, const void *s2, size_t sz)
+{
+ return(
+ dk4mem_fallback_i_cmp(
+ (const unsigned char *)s1,
+ (const unsigned char *)s2,
+ sz
+ )
+ );
+}
+
+
+
+int
+dk4mem_cmp(const void *s1, const void *s2, size_t sz, dk4_er_t *erp)
+{
+ int back = 0;
+ if ((NULL != s1) && (NULL != s2) && (0 < sz)) {
+ back = DK4_MEMCMP(s1, s2, sz);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+
+#if (DK4_ON_WINDOWS) || (DK4_HAVE_MALLOC && DK4_HAVE_FREE)
+
+void *
+dk4mem_malloc_bytes(size_t bytes, dk4_er_t *erp)
+{
+ void *back = NULL; /* Function result. */
+ if (0 < bytes) {
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ if ((dk4_um_t)bytes <= (dk4_um_t)0xFFFFFFFFUL) {
+#if DK4_USE_WINDOWS_LOCAL_ALLOC
+ back = (void*)LocalAlloc(LMEM_FIXED, (DWORD)bytes);
+#else
+ back = (void*)GlobalAlloc(GMEM_FIXED, (DWORD)bytes);
+#endif
+ if (NULL == back) {
+ dk4error_set_elsize_nelem(erp,DK4_E_MEMORY_ALLOCATION_FAILED,1,bytes);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+#else
+ back = malloc(bytes);
+ if (NULL == back) {
+ dk4error_set_elsize_nelem(erp, DK4_E_MEMORY_ALLOCATION_FAILED, 1, bytes);
+ }
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+ back = malloc(bytes);
+ if (NULL == back) {
+ dk4error_set_elsize_nelem(erp, DK4_E_MEMORY_ALLOCATION_FAILED, 1, bytes);
+ }
+ /* --- non-Windows */
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+void *
+dk4mem_malloc(size_t elsize, size_t nelem, dk4_er_t *erp)
+{
+ void *back = NULL;
+ size_t bytes;
+ if ((0 < elsize) && (0 < nelem)) {
+ if ((SIZE_MAX / elsize) >= nelem) {
+ bytes = elsize * nelem;
+ back = dk4mem_malloc_bytes(bytes, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+void *
+dk4mem_calloc(size_t elsize, size_t nelem, dk4_er_t *erp)
+{
+ void *back = NULL;
+
+ if ((0 < elsize) && (0 < nelem)) {
+ if ((SIZE_MAX / elsize) >= nelem) {
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ size_t bytes;
+ bytes = elsize * nelem;
+ if ((dk4_um_t)bytes <= (dk4_um_t)0xFFFFFFFFUL) {
+#if DK4_USE_WINDOWS_LOCAL_ALLOC
+ back = (void *)LocalAlloc((LMEM_FIXED | LMEM_ZEROINIT), (DWORD)bytes);
+#else
+ back = (void *)GlobalAlloc((GMEM_FIXED | GMEM_ZEROINIT), (DWORD)bytes);
+#endif
+ if (NULL == back) {
+ dk4error_set_elsize_nelem(
+ erp, DK4_E_MEMORY_ALLOCATION_FAILED, elsize, nelem
+ );
+ }
+
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+#else
+ back = calloc(nelem, elsize);
+ if (NULL == back) {
+ dk4error_set_elsize_nelem(
+ erp, DK4_E_MEMORY_ALLOCATION_FAILED, elsize, nelem
+ );
+ }
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+#if DK4_HAVE_CALLOC
+ back = calloc(nelem, elsize);
+ if (NULL == back) {
+ dk4error_set_elsize_nelem(
+ erp, DK4_E_MEMORY_ALLOCATION_FAILED, elsize, nelem
+ );
+ }
+#else
+ size_t bytes;
+ bytes = elsize * nelem;
+ back = malloc(bytes);
+ if (NULL != back) {
+ dk4mem_reset(back, bytes);
+ } else {
+ dk4error_set_elsize_nelem(
+ erp, DK4_E_MEMORY_ALLOCATION_FAILED, elsize, nelem
+ );
+ }
+#endif
+ /* --- non-Windows */
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+void
+dk4mem_free(void *ptr)
+{
+ if (NULL != ptr) {
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+#if DK4_USE_WINDOWS_LOCAL_ALLOC
+ LocalFree((HLOCAL)ptr);
+#else
+ GlobalFree((HLOCAL)ptr);
+#endif
+#else
+ free(ptr);
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+ free(ptr);
+ /* --- non-Windows */
+#endif
+ }
+}
+
+#endif
+/* if defined(_WIN32) ... */
+
diff --git a/support/dktools/dk4mem.ctr b/support/dktools/dk4mem.ctr
new file mode 100644
index 0000000000..97d26f5b7b
--- /dev/null
+++ b/support/dktools/dk4mem.ctr
@@ -0,0 +1,1030 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ Memory allocation and deallocation;
+ copy, reset and compare memory regions.
+
+ The functions provided by the C runtime libraries are used by
+ default. On Windows you can decide to use Windows API functions
+ instead, define DK4_WIN_AVOID_CRT or DK4_WIN_DENY_CRT to 1.
+
+ When using Windows API functions dynamic memory allocations use
+ the global heap. Define DK4_USE_WINDOWS_LOCAL_ALLOC to 1 to
+ use the local heap instead.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STRINGS_H
+#ifndef STRINGS_H_INCLUDED
+#include <strings.h>
+#define STRINGS_H_INCLUDED 1
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Fallback function to use if no suitable memory copy function is found.
+ This function does not do any error checking.
+ The caller is responsible to provide valid arguments.
+ @param dst Destination buffer address.
+ @param src Source buffer address.
+ @param sz Number of bytes to copy.
+*/
+void
+dk4mem_fallback_cpy(void *dst, const void *src, size_t sz);
+
+/** Fallback function to use if no suitable memory reseet function is found.
+ This function does not do any error checking.
+ The caller is responsible to provide valid arguments.
+ @param bptr Address of buffer to reset.
+ @param sz Number of bytes to reset.
+*/
+void
+dk4mem_fallback_reset(void *bptr, size_t sz);
+
+/** Fallback function to use if no suitable memory comparison function
+ is found.
+ This function does not do any error checking.
+ The caller is responsible to provide valid arguments.
+ @param s1 Address of left buffer in comparison.
+ @param s2 Address of right buffer in comparison.
+ @param sz Buffer size (number of bytes).
+ @return Positive value if s1>s2, 0 for equal buffers, -1 if s1<s2.
+*/
+int
+dk4mem_fallback_cmp(const void *s1, const void *s2, size_t sz);
+
+/** Reset memory range.
+
+ CRT on Windows: Optional.
+ @param bptr Pointer to start of buffer.
+ @param sz Buffer size (number of bytes).
+ @param erp Error report for diagnostics, may be NULL.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if bptr is NULL or sz is 0.
+*/
+void
+dk4mem_reset(void *bptr, size_t sz, dk4_er_t *erp);
+
+/** Set memory range to specified value.
+
+ CRT on Windows: Optional.
+ @param bptr Pointer to start of buffer.
+ @param sz Buffer size (number of bytes).
+ @param uc Byte value to write.
+ @param erp Error report for diagnostics, may be NULL.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if bptr is NULL or sz is 0.
+*/
+void
+dk4mem_set(void *bptr, size_t sz, unsigned char uc, dk4_er_t *erp);
+
+/** Copy memory range.
+
+ CRT on Windows: Optional.
+ @param dst Destination address.
+ @param src Source address.
+ @param sz Range size (number of bytes).
+ @param erp Error report, may be NULL.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dst or src is NULL or sz is 0.
+*/
+void
+dk4mem_cpy(void *dst, void const *src, size_t sz, dk4_er_t *erp);
+
+/** Compare two memory ranges.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param s1 Left memory range.
+ @param s2 Right memory range.
+ @param sz Number of bytes to compare.
+ @param erp Error report, may be NULL.
+ @return 1 if s1>s2, -1 if s1<s2, 0 if s1==s2.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if s1 or s2 is NULL or sz is 0.
+*/
+int
+dk4mem_cmp(const void *s1, const void *s2, size_t sz, dk4_er_t *erp);
+
+#if (DK4_ON_WINDOWS) || (DK4_HAVE_MALLOC && DK4_HAVE_FREE)
+
+/** Dynamically allocate memory. The memory range is not initialized.
+
+ CRT on Windows: Optional.
+ @param bytes Number of bytes to allocate.
+ @param erp Error report, may be NULL.
+ @return Pointer to memory on success, NULL on error.
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if bytes is 0,
+ - DK4_E_MATH_OVERFLOW<br>
+ if the specified size is too large,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory
+ available.
+*/
+void *
+dk4mem_malloc_bytes(size_t bytes, dk4_er_t *erp);
+
+/** Dynamically allocate memory. The memory range is not initialized.
+
+ CRT on Windows: Optional.
+ @param elsize Size of each element.
+ @param nelem Number of elements.
+ @param erp Error report, may be NULL.
+ @return Pointer to memory on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if elsize or nelem is 0,
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow when calculating the
+ product of elsize and nelem,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available.
+*/
+void *
+dk4mem_malloc(size_t elsize, size_t nelem, dk4_er_t *erp);
+
+/** Dynamically allocate memory and initialize memory range.
+
+ CRT on Windows: Optional.
+ @param elsize Size of each element.
+ @param nelem Number of elements.
+ @param erp Error report, may be NULL.
+ @return Pointer to memory on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if elsize or nelem is 0,
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow when calculating the
+ product of elsize and nelem,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available.
+*/
+void *
+dk4mem_calloc(size_t elsize, size_t nelem, dk4_er_t *erp);
+
+/** Release memory allocated by dk4mem_malloc() or dk4mem_calloc().
+ The function checks whether the pointer is NULL and frees
+ the memory only for non-NULL pointers.
+ CRT on Windows: Optional.
+ @param ptr Pointer to start address of memory to release.
+*/
+void
+dk4mem_free(void *ptr);
+
+#endif
+/* if defined(_WIN32) ... */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/** Allocate and initialize memory.
+ @param tp Type to allocate.
+ @param ne Number of elements to allocate.
+ @param er Error report, may be NULL.
+ @return Pointer to a new tp on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if elsize or nelem is 0,
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow when calculating the product of elsize and nelem,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem set if there is not enough memory
+ available.
+*/
+#define dk4mem_new(tp,ne,er) (tp *)dk4mem_calloc(sizeof(tp),ne,er)
+
+
+
+/** Free memory previously allocated.
+ @param ptr Start address of memory range to free.
+*/
+#define dk4mem_release(ptr) \
+do { if (NULL != ptr) { dk4mem_free(ptr); } ptr = NULL; } while (0)
+
+
+/** Find number of elements in array.
+ @param v Variable.
+ @param t Type.
+ @return The size of the variable divided by the size of the type.
+*/
+#define DK4_SIZEOF(v,t) (sizeof(v)/sizeof(t))
+
+
+
+/** Increase byte number to alignment size.
+ @param sz Original byte number.
+ @param al Alignment size, typically 16.
+ @return Size corrected for alignment.
+*/
+#define DK4_MEM_ALIGN(sz,al) ((0 == (sz % al)) ? (sz) : (al * (1 + (sz/al))))
+
+
+#if DK4_HAVE_INLINE
+/* +++ DK4_HAVE_INLINE */
+#if DK4_ON_WINDOWS
+/* +++ DK4_HAVE_INLINE, Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+/* +++ DK4_HAVE_INLINE, Windows, ! crt */
+/** Pure memory copy operation. All arguments must be checked
+ by the caller before calling this function.
+ @param dst Destination buffer address.
+ @param src Source buffer address.
+ @param sz Number of bytes to copy.
+*/
+static
+inline
+void
+DK4_MEMCPY(void *dst, const void *src, size_t sz)
+{
+ CopyMemory(dst, src, sz);
+}
+/** Pure memory reset. All arguments must be checked by the caller
+ before calling this function.
+ @param dst Start address of buffer to reset.
+ @param sz Number of bytes to reset.
+*/
+static
+inline
+void
+DK4_MEMRES(void *dst, size_t sz)
+{
+ ZeroMemory(dst, sz);
+}
+/** Pure memory comparison.
+ All arguments must be checked by the caller before calling this
+ function.
+ @param s1 Address of left buffer in comparison.
+ @param s2 Address of right buffer in comparison.
+ @param sz Number of bytes to compare.
+ @return 1 if s1>s2, 0 for equal buffers, -1 if s1<s2.
+*/
+static
+inline
+int
+DK4_MEMCMP(const void *s1, const void *s2, size_t sz)
+{
+ return ( dk4mem_fallback_cmp(s1, s2, sz) );
+}
+/* --- DK4_HAVE_INLINE, Windows, ! crt */
+#else
+/* +++ DK4_HAVE_INLINE, Windows, crt */
+/** Pure memory copy operation. All arguments must be checked
+ by the caller before calling this function.
+ @param dst Destination buffer address.
+ @param src Source buffer address.
+ @param sz Number of bytes to copy.
+*/
+static
+inline
+void
+DK4_MEMCPY(void *dst, const void *src, size_t sz)
+{
+ memcpy(dst, src, sz);
+}
+/** Pure memory reset. All arguments must be checked by the caller
+ before calling this function.
+ @param dst Start address of buffer to reset.
+ @param sz Number of bytes to reset.
+*/
+static
+inline
+void
+DK4_MEMRES(void *dst, size_t sz)
+{
+ memset(dst, 0, sz);
+}
+/** Pure memory comparison.
+ All arguments must be checked by the caller before calling this
+ function.
+ @param s1 Address of left buffer in comparison.
+ @param s2 Address of right buffer in comparison.
+ @param sz Number of bytes to compare.
+ @return 1 if s1>s2, 0 for equal buffers, -1 if s1<s2.
+*/
+static
+inline
+int
+DK4_MEMCMP(const void *s1, const void *s2, size_t sz)
+{
+ return (memcmp(s1, s2, sz));
+}
+/* --- DK4_HAVE_INLINE, Windows, crt */
+#endif
+/* --- DK4_HAVE_INLINE, Windows */
+#else
+/* +++ DK4_HAVE_INLINE, ! Windows */
+#if DK4_HAVE_MEMSET
+/* +++ DK4_HAVE_INLINE, ! Windows, memset */
+/** Pure memory reset. All arguments must be checked by the caller
+ before calling this function.
+ @param dst Start address of buffer to reset.
+ @param sz Number of bytes to reset.
+*/
+static
+inline
+void
+DK4_MEMRES(void *dst, size_t sz)
+{
+ memset(dst, 0, sz);
+}
+/* --- DK4_HAVE_INLINE, ! Windows, memset */
+#else
+/* +++ DK4_HAVE_INLINE, ! Windows, ! memset */
+#if DK4_HAVE_BZERO
+/* +++ DK4_HAVE_INLINE, ! Windows, ! memset, bzero */
+/** Pure memory reset. All arguments must be checked by the caller
+ before calling this function.
+ @param dst Start address of buffer to reset.
+ @param sz Number of bytes to reset.
+*/
+static
+inline
+void
+DK4_MEMRES(void *dst, size_t sz)
+{
+ bzero(dst, sz);
+}
+/* --- DK4_HAVE_INLINE, ! Windows, ! memset, bzero */
+#else
+/* +++ DK4_HAVE_INLINE, ! Windows, ! memset, ! bzero */
+/** Pure memory reset. All arguments must be checked by the caller
+ before calling this function.
+ @param dst Start address of buffer to reset.
+ @param sz Number of bytes to reset.
+*/
+static
+inline
+void
+DK4_MEMRES(void *dst, size_t sz)
+{
+ dk4mem_fallback_reset(dst, sz);
+}
+/* --- DK4_HAVE_INLINE, ! Windows, ! memset, ! bzero */
+#endif
+/* --- DK4_HAVE_INLINE, ! Windows, ! memset */
+#endif
+#if DK4_HAVE_MEMCPY
+/* +++ DK4_HAVE_INLINE, ! Windows, memcpy */
+/** Pure memory copy operation. All arguments must be checked
+ by the caller before calling this function.
+ @param dst Destination buffer address.
+ @param src Source buffer address.
+ @param sz Number of bytes to copy.
+*/
+static
+inline
+void
+DK4_MEMCPY(void *dst, const void *src, size_t sz)
+{
+ memcpy(dst, src, sz);
+}
+/* --- DK4_HAVE_INLINE, ! Windows, memcpy */
+#else
+/* +++ DK4_HAVE_INLINE, ! Windows, ! memcpy */
+#if DK4_HAVE_BCOPY
+/* +++ DK4_HAVE_INLINE, ! Windows, ! memcpy, bcopy */
+/** Pure memory copy operation. All arguments must be checked
+ by the caller before calling this function.
+ @param dst Destination buffer address.
+ @param src Source buffer address.
+ @param sz Number of bytes to copy.
+*/
+static
+inline
+void
+DK4_MEMCPY(void *dst, const void *src, size_t sz)
+{
+ bcopy(src, dst, sz);
+}
+/* --- DK4_HAVE_INLINE, ! Windows, ! memcpy, bcopy */
+#else
+/* +++ DK4_HAVE_INLINE, ! Windows, ! memcpy, ! bcopy */
+/** Pure memory copy operation. All arguments must be checked
+ by the caller before calling this function.
+ @param dst Destination buffer address.
+ @param src Source buffer address.
+ @param sz Number of bytes to copy.
+*/
+static
+inline
+void
+DK4_MEMCPY(void *dst, const void *src, size_t sz)
+{
+ dk4mem_fallback_cpy(dst, src, sz);
+}
+/* --- DK4_HAVE_INLINE, ! Windows, ! memcpy, ! bcopy */
+#endif
+/* --- DK4_HAVE_INLINE, ! Windows, ! memcpy */
+#endif
+#if DK4_HAVE_MEMCMP
+/* +++ DK4_HAVE_INLINE, ! Windows, memcmp */
+/** Pure memory comparison.
+ All arguments must be checked by the caller before calling this
+ function.
+ @param s1 Address of left buffer in comparison.
+ @param s2 Address of right buffer in comparison.
+ @param sz Number of bytes to compare.
+ @return 1 if s1>s2, 0 for equal buffers, -1 if s1<s2.
+*/
+static
+inline
+int
+DK4_MEMCMP(const void *s1, const void *s2, size_t sz)
+{
+ return (memcmp(s1, s2, sz));
+}
+/* --- DK4_HAVE_INLINE, ! Windows, memcmp */
+#else
+/* +++ DK4_HAVE_INLINE, ! Windows, ! memcmp */
+#if DK4_HAVE_BCMP
+/* +++ DK4_HAVE_INLINE, ! Windows, ! memcmp, bcmp */
+/** Pure memory comparison.
+ All arguments must be checked by the caller before calling this
+ function.
+ @param s1 Address of left buffer in comparison.
+ @param s2 Address of right buffer in comparison.
+ @param sz Number of bytes to compare.
+ @return 1 if s1>s2, 0 for equal buffers, -1 if s1<s2.
+*/
+static
+inline
+int
+DK4_MEMCMP(const void *s1, const void *s2, size_t sz)
+{
+ return (bcmp(s1, s2, sz));
+}
+/* --- DK4_HAVE_INLINE, ! Windows, ! memcmp, bcmp */
+#else
+/* +++ DK4_HAVE_INLINE, ! Windows, ! memcmp, ! bcmp */
+/** Pure memory comparison.
+ All arguments must be checked by the caller before calling this
+ function.
+ @param s1 Address of left buffer in comparison.
+ @param s2 Address of right buffer in comparison.
+ @param sz Number of bytes to compare.
+ @return 1 if s1>s2, 0 for equal buffers, -1 if s1<s2.
+*/
+static
+inline
+int
+DK4_MEMCMP(const void *s1, const void *s2, size_t sz)
+{
+ return ( dk4mem_fallback_cmp(s1, s2, sz) );
+}
+/* --- DK4_HAVE_INLINE, ! Windows, ! memcmp, ! bcmp */
+#endif
+/* --- DK4_HAVE_INLINE, ! Windows, ! memcmp */
+#endif
+/* --- DK4_HAVE_INLINE, ! Windows */
+#endif
+/* --- DK4_HAVE_INLINE */
+#else
+/* +++ ! DK4_HAVE_INLINE */
+#if DK4_ON_WINDOWS
+/* +++ ! DK4_HAVE_INLINE, Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+/* +++ ! DK4_HAVE_INLINE, Windows, ! crt */
+/** Pure memory copy operation. All arguments must be checked
+ by the caller before calling this function.
+ @param dst Destination buffer address.
+ @param src Source buffer address.
+ @param sz Number of bytes to copy.
+*/
+#define DK4_MEMCPY(dst,src,sz) CopyMemory(dst, src, sz)
+/** Pure memory reset. All arguments must be checked by the caller
+ before calling this function.
+ @param dst Start address of buffer to reset.
+ @param sz Number of bytes to reset.
+*/
+#define DK4_MEMRES(dst,sz) ZeroMemory(dst, sz)
+/** Pure memory comparison.
+ All arguments must be checked by the caller before calling this
+ function.
+ @param s1 Address of left buffer in comparison.
+ @param s2 Address of right buffer in comparison.
+ @param sz Number of bytes to compare.
+ @return 1 if s1>s2, 0 for equal buffers, -1 if s1<s2.
+*/
+#define DK4_MEMCMP(s1,s2,sz) dk4mem_fallback_cmp(s1, s2, sz)
+/* --- ! DK4_HAVE_INLINE, Windows, ! crt */
+#else
+/* +++ ! DK4_HAVE_INLINE, Windows, crt */
+/** Pure memory copy operation. All arguments must be checked
+ by the caller before calling this function.
+ @param dst Destination buffer address.
+ @param src Source buffer address.
+ @param sz Number of bytes to copy.
+*/
+#define DK4_MEMCPY(dst,src,sz) memcpy(dst, src, sz)
+/** Pure memory reset. All arguments must be checked by the caller
+ before calling this function.
+ @param dst Start address of buffer to reset.
+ @param sz Number of bytes to reset.
+*/
+#define DK4_MEMRES(dst,sz) memset(dst, 0, sz)
+/** Pure memory comparison.
+ All arguments must be checked by the caller before calling this
+ function.
+ @param s1 Address of left buffer in comparison.
+ @param s2 Address of right buffer in comparison.
+ @param sz Number of bytes to compare.
+ @return 1 if s1>s2, 0 for equal buffers, -1 if s1<s2.
+*/
+#define DK4_MEMCMP(s1,s2,sz) memcmp(s1, s2, sz)
+/* --- ! DK4_HAVE_INLINE, Windows, crt */
+#endif
+/* --- ! DK4_HAVE_INLINE, Windows */
+#else
+/* +++ ! DK4_HAVE_INLINE, ! Windows */
+#if DK4_HAVE_MEMSET
+/* +++ ! DK4_HAVE_INLINE, ! Windows, memset */
+/** Pure memory reset. All arguments must be checked by the caller
+ before calling this function.
+ @param dst Start address of buffer to reset.
+ @param sz Number of bytes to reset.
+*/
+#define DK4_MEMRES(dst,sz) memset(dst, 0, sz)
+/* --- ! DK4_HAVE_INLINE, ! Windows, memset */
+#else
+/* +++ ! DK4_HAVE_INLINE, ! Windows, ! memset */
+#if DK4_HAVE_BZERO
+/* +++ ! DK4_HAVE_INLINE, ! Windows, ! memset, bzero */
+/** Pure memory reset. All arguments must be checked by the caller
+ before calling this function.
+ @param dst Start address of buffer to reset.
+ @param sz Number of bytes to reset.
+*/
+#define DK4_MEMRES(dst,sz) bzero(dst, sz)
+/* --- ! DK4_HAVE_INLINE, ! Windows, ! memset, bzero */
+#else
+/* +++ ! DK4_HAVE_INLINE, ! Windows, ! memset, ! bzero */
+/** Pure memory reset. All arguments must be checked by the caller
+ before calling this function.
+ @param dst Start address of buffer to reset.
+ @param sz Number of bytes to reset.
+*/
+#define DK4_MEMRES(dst,sz) dk4mem_fallback_reset(dst, sz)
+/* --- ! DK4_HAVE_INLINE, ! Windows, ! memset, ! bzero */
+#endif
+/* --- ! DK4_HAVE_INLINE, ! Windows, ! memset */
+#endif
+#if DK4_HAVE_MEMCPY
+/* +++ ! DK4_HAVE_INLINE, ! Windows, memcpy */
+/** Pure memory copy operation. All arguments must be checked
+ by the caller before calling this function.
+ @param dst Destination buffer address.
+ @param src Source buffer address.
+ @param sz Number of bytes to copy.
+*/
+#define DK4_MEMCPY(dst,src,sz) memcpy(dst, src, sz)
+/* --- ! DK4_HAVE_INLINE, ! Windows, memcpy */
+#else
+/* +++ ! DK4_HAVE_INLINE, ! Windows, ! memcpy */
+#if DK4_HAVE_BCOPY
+/* +++ ! DK4_HAVE_INLINE, ! Windows, ! memcpy, bcopy */
+/** Pure memory copy operation. All arguments must be checked
+ by the caller before calling this function.
+ @param dst Destination buffer address.
+ @param src Source buffer address.
+ @param sz Number of bytes to copy.
+*/
+#define DK4_MEMCPY(dst,src,sz) bcopy(src, dst, sz)
+/* --- ! DK4_HAVE_INLINE, ! Windows, ! memcpy, bcopy */
+#else
+/* +++ ! DK4_HAVE_INLINE, ! Windows, ! memcpy, ! bcopy */
+/** Pure memory copy operation. All arguments must be checked
+ by the caller before calling this function.
+ @param dst Destination buffer address.
+ @param src Source buffer address.
+ @param sz Number of bytes to copy.
+*/
+#define DK4_MEMCPY(dst,src,sz) dk4mem_fallback_cpy(dst, src, sz)
+/* --- ! DK4_HAVE_INLINE, ! Windows, ! memcpy, ! bcopy */
+#endif
+/* --- ! DK4_HAVE_INLINE, ! Windows, ! memcpy */
+#endif
+#if DK4_HAVE_MEMCMP
+/* +++ ! DK4_HAVE_INLINE, ! Windows, memcmp */
+/** Pure memory comparison.
+ All arguments must be checked by the caller before calling this
+ function.
+ @param s1 Address of left buffer in comparison.
+ @param s2 Address of right buffer in comparison.
+ @param sz Number of bytes to compare.
+ @return 1 if s1>s2, 0 for equal buffers, -1 if s1<s2.
+*/
+#define DK4_MEMCMP(s1,s2,sz) memcmp(s1, s2, sz)
+/* --- ! DK4_HAVE_INLINE, ! Windows, memcmp */
+#else
+/* +++ ! DK4_HAVE_INLINE, ! Windows, ! memcmp */
+#if DK4_HAVE_BCMP
+/* +++ ! DK4_HAVE_INLINE, ! Windows, ! memcmp, bcmp */
+/** Pure memory comparison.
+ All arguments must be checked by the caller before calling this
+ function.
+ @param s1 Address of left buffer in comparison.
+ @param s2 Address of right buffer in comparison.
+ @param sz Number of bytes to compare.
+ @return 1 if s1>s2, 0 for equal buffers, -1 if s1<s2.
+*/
+#define DK4_MEMCMP(s1,s2,sz) bcmp(s1, s2, sz)
+/* --- ! DK4_HAVE_INLINE, ! Windows, ! memcmp, bcmp */
+#else
+/* +++ ! DK4_HAVE_INLINE, ! Windows, ! memcmp, ! bcmp */
+/** Pure memory comparison.
+ All arguments must be checked by the caller before calling this
+ function.
+ @param s1 Address of left buffer in comparison.
+ @param s2 Address of right buffer in comparison.
+ @param sz Number of bytes to compare.
+ @return 1 if s1>s2, 0 for equal buffers, -1 if s1<s2.
+*/
+#define DK4_MEMCMP(s1,s2,sz) dk4mem_fallback_cmp(s1, s2, sz)
+/* --- ! DK4_HAVE_INLINE, ! Windows, ! memcmp, ! bcmp */
+#endif
+/* --- ! DK4_HAVE_INLINE, ! Windows, ! memcmp */
+#endif
+/* --- ! DK4_HAVE_INLINE, ! Windows */
+#endif
+/* --- ! DK4_HAVE_INLINE */
+#endif
+
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS && (DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT)
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4types.h"
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+#if DK4_HAVE_STRINGS_H
+#ifndef STRINGS_H_INCLUDED
+#include <strings.h>
+#define STRINGS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4mem.h"
+#include "dk4numco.h"
+
+
+
+$!trace-include
+
+
+
+static
+void
+dk4mem_fallback_i_reset(unsigned char *bptr, size_t sz)
+{
+ while (0 < sz--) { *(bptr++) = '\0'; }
+}
+
+
+
+void
+dk4mem_fallback_reset(void *bptr, size_t sz)
+{
+ dk4mem_fallback_i_reset((unsigned char *)bptr, sz);
+}
+
+
+
+void
+dk4mem_reset(void *bptr, size_t sz, dk4_er_t *erp)
+{
+ $? "+ dk4mem_reset"
+ if ((NULL != bptr) && (0 < sz)) {
+ DK4_MEMRES(bptr, sz);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4mem_reset"
+}
+
+
+
+void
+dk4mem_set(void *bptr, size_t sz, unsigned char uc, dk4_er_t *erp)
+{
+#if !DK4_HAVE_MEMSET
+ unsigned char *ucptr;
+#endif
+ if ((NULL != bptr) && (0 < sz)) {
+#if DK4_HAVE_MEMSET
+ memset(bptr, (int)uc, sz);
+#else
+ ucptr = (unsigned char *)bptr;
+ while (0 < sz--) { *(ucptr++) = uc; }
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+}
+
+
+
+static
+void
+dk4mem_fallback_i_cpy(unsigned char *dst, const unsigned char *src, size_t sz)
+{
+ while(0 < sz--) { *(dst++) = *(src++); }
+}
+
+
+
+void
+dk4mem_fallback_cpy(void *dst, const void *src, size_t sz)
+{
+ dk4mem_fallback_i_cpy(
+ (unsigned char *)dst,
+ (const unsigned char *)src,
+ sz
+ );
+}
+
+
+
+void
+dk4mem_cpy(void *dst, void const *src, size_t sz, dk4_er_t *erp)
+{
+ if ((NULL != dst) && (NULL != src) && (0 < sz)) {
+ DK4_MEMCPY(dst, src, sz);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+}
+
+
+static
+int
+dk4mem_fallback_i_cmp(
+ const unsigned char *s1,
+ const unsigned char *s2,
+ size_t sz
+)
+{
+ int back = 0;
+ while ((0 < sz--) && (0 == back)) {
+ if (*s1 > *s2) {
+ back = 1;
+ } else {
+ if (*s1 < *s2) {
+ back = -1;
+ }
+ }
+ s1++; s2++;
+ }
+ return back;
+}
+
+
+
+int
+dk4mem_fallback_cmp(const void *s1, const void *s2, size_t sz)
+{
+ return(
+ dk4mem_fallback_i_cmp(
+ (const unsigned char *)s1,
+ (const unsigned char *)s2,
+ sz
+ )
+ );
+}
+
+
+
+int
+dk4mem_cmp(const void *s1, const void *s2, size_t sz, dk4_er_t *erp)
+{
+ int back = 0;
+ if ((NULL != s1) && (NULL != s2) && (0 < sz)) {
+ back = DK4_MEMCMP(s1, s2, sz);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+
+#if (DK4_ON_WINDOWS) || (DK4_HAVE_MALLOC && DK4_HAVE_FREE)
+
+void *
+dk4mem_malloc_bytes(size_t bytes, dk4_er_t *erp)
+{
+ void *back = NULL; /* Function result. */
+ if (0 < bytes) {
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ if ((dk4_um_t)bytes <= (dk4_um_t)0xFFFFFFFFUL) {
+#if DK4_USE_WINDOWS_LOCAL_ALLOC
+ back = (void*)LocalAlloc(LMEM_FIXED, (DWORD)bytes);
+#else
+ back = (void*)GlobalAlloc(GMEM_FIXED, (DWORD)bytes);
+#endif
+ if (NULL == back) {
+ dk4error_set_elsize_nelem(erp,DK4_E_MEMORY_ALLOCATION_FAILED,1,bytes);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+#else
+ back = malloc(bytes);
+ if (NULL == back) {
+ dk4error_set_elsize_nelem(erp, DK4_E_MEMORY_ALLOCATION_FAILED, 1, bytes);
+ }
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+ back = malloc(bytes);
+ if (NULL == back) {
+ dk4error_set_elsize_nelem(erp, DK4_E_MEMORY_ALLOCATION_FAILED, 1, bytes);
+ }
+ /* --- non-Windows */
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+void *
+dk4mem_malloc(size_t elsize, size_t nelem, dk4_er_t *erp)
+{
+ void *back = NULL;
+ size_t bytes;
+ if ((0 < elsize) && (0 < nelem)) {
+ if ((SIZE_MAX / elsize) >= nelem) {
+ bytes = elsize * nelem;
+ back = dk4mem_malloc_bytes(bytes, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+void *
+dk4mem_calloc(size_t elsize, size_t nelem, dk4_er_t *erp)
+{
+ void *back = NULL;
+
+ if ((0 < elsize) && (0 < nelem)) {
+ if ((SIZE_MAX / elsize) >= nelem) {
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ size_t bytes;
+ bytes = elsize * nelem;
+ if ((dk4_um_t)bytes <= (dk4_um_t)0xFFFFFFFFUL) {
+#if DK4_USE_WINDOWS_LOCAL_ALLOC
+ back = (void *)LocalAlloc((LMEM_FIXED | LMEM_ZEROINIT), (DWORD)bytes);
+#else
+ back = (void *)GlobalAlloc((GMEM_FIXED | GMEM_ZEROINIT), (DWORD)bytes);
+#endif
+ if (NULL == back) {
+ dk4error_set_elsize_nelem(
+ erp, DK4_E_MEMORY_ALLOCATION_FAILED, elsize, nelem
+ );
+ }
+
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+#else
+ back = calloc(nelem, elsize);
+ if (NULL == back) {
+ dk4error_set_elsize_nelem(
+ erp, DK4_E_MEMORY_ALLOCATION_FAILED, elsize, nelem
+ );
+ }
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+#if DK4_HAVE_CALLOC
+ back = calloc(nelem, elsize);
+ if (NULL == back) {
+ dk4error_set_elsize_nelem(
+ erp, DK4_E_MEMORY_ALLOCATION_FAILED, elsize, nelem
+ );
+ }
+#else
+ size_t bytes;
+ bytes = elsize * nelem;
+ back = malloc(bytes);
+ if (NULL != back) {
+ dk4mem_reset(back, bytes);
+ } else {
+ dk4error_set_elsize_nelem(
+ erp, DK4_E_MEMORY_ALLOCATION_FAILED, elsize, nelem
+ );
+ }
+#endif
+ /* --- non-Windows */
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+void
+dk4mem_free(void *ptr)
+{
+ if (NULL != ptr) {
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+#if DK4_USE_WINDOWS_LOCAL_ALLOC
+ LocalFree((HLOCAL)ptr);
+#else
+ GlobalFree((HLOCAL)ptr);
+#endif
+#else
+ free(ptr);
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+ free(ptr);
+ /* --- non-Windows */
+#endif
+ }
+}
+
+#endif
+/* if defined(_WIN32) ... */
+
diff --git a/support/dktools/dk4mem.h b/support/dktools/dk4mem.h
new file mode 100644
index 0000000000..e86408e357
--- /dev/null
+++ b/support/dktools/dk4mem.h
@@ -0,0 +1,732 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mem.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MEM_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MEM_H_INCLUDED 1
+
+
+#line 9 "dk4mem.ctr"
+
+/** @file
+ Memory allocation and deallocation;
+ copy, reset and compare memory regions.
+
+ The functions provided by the C runtime libraries are used by
+ default. On Windows you can decide to use Windows API functions
+ instead, define DK4_WIN_AVOID_CRT or DK4_WIN_DENY_CRT to 1.
+
+ When using Windows API functions dynamic memory allocations use
+ the global heap. Define DK4_USE_WINDOWS_LOCAL_ALLOC to 1 to
+ use the local heap instead.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STRINGS_H
+#ifndef STRINGS_H_INCLUDED
+#include <strings.h>
+#define STRINGS_H_INCLUDED 1
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Fallback function to use if no suitable memory copy function is found.
+ This function does not do any error checking.
+ The caller is responsible to provide valid arguments.
+ @param dst Destination buffer address.
+ @param src Source buffer address.
+ @param sz Number of bytes to copy.
+*/
+void
+dk4mem_fallback_cpy(void *dst, const void *src, size_t sz);
+
+/** Fallback function to use if no suitable memory reseet function is found.
+ This function does not do any error checking.
+ The caller is responsible to provide valid arguments.
+ @param bptr Address of buffer to reset.
+ @param sz Number of bytes to reset.
+*/
+void
+dk4mem_fallback_reset(void *bptr, size_t sz);
+
+/** Fallback function to use if no suitable memory comparison function
+ is found.
+ This function does not do any error checking.
+ The caller is responsible to provide valid arguments.
+ @param s1 Address of left buffer in comparison.
+ @param s2 Address of right buffer in comparison.
+ @param sz Buffer size (number of bytes).
+ @return Positive value if s1>s2, 0 for equal buffers, -1 if s1<s2.
+*/
+int
+dk4mem_fallback_cmp(const void *s1, const void *s2, size_t sz);
+
+/** Reset memory range.
+
+ CRT on Windows: Optional.
+ @param bptr Pointer to start of buffer.
+ @param sz Buffer size (number of bytes).
+ @param erp Error report for diagnostics, may be NULL.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if bptr is NULL or sz is 0.
+*/
+void
+dk4mem_reset(void *bptr, size_t sz, dk4_er_t *erp);
+
+/** Set memory range to specified value.
+
+ CRT on Windows: Optional.
+ @param bptr Pointer to start of buffer.
+ @param sz Buffer size (number of bytes).
+ @param uc Byte value to write.
+ @param erp Error report for diagnostics, may be NULL.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if bptr is NULL or sz is 0.
+*/
+void
+dk4mem_set(void *bptr, size_t sz, unsigned char uc, dk4_er_t *erp);
+
+/** Copy memory range.
+
+ CRT on Windows: Optional.
+ @param dst Destination address.
+ @param src Source address.
+ @param sz Range size (number of bytes).
+ @param erp Error report, may be NULL.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dst or src is NULL or sz is 0.
+*/
+void
+dk4mem_cpy(void *dst, void const *src, size_t sz, dk4_er_t *erp);
+
+/** Compare two memory ranges.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param s1 Left memory range.
+ @param s2 Right memory range.
+ @param sz Number of bytes to compare.
+ @param erp Error report, may be NULL.
+ @return 1 if s1>s2, -1 if s1<s2, 0 if s1==s2.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if s1 or s2 is NULL or sz is 0.
+*/
+int
+dk4mem_cmp(const void *s1, const void *s2, size_t sz, dk4_er_t *erp);
+
+#if (DK4_ON_WINDOWS) || (DK4_HAVE_MALLOC && DK4_HAVE_FREE)
+
+/** Dynamically allocate memory. The memory range is not initialized.
+
+ CRT on Windows: Optional.
+ @param bytes Number of bytes to allocate.
+ @param erp Error report, may be NULL.
+ @return Pointer to memory on success, NULL on error.
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if bytes is 0,
+ - DK4_E_MATH_OVERFLOW<br>
+ if the specified size is too large,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory
+ available.
+*/
+void *
+dk4mem_malloc_bytes(size_t bytes, dk4_er_t *erp);
+
+/** Dynamically allocate memory. The memory range is not initialized.
+
+ CRT on Windows: Optional.
+ @param elsize Size of each element.
+ @param nelem Number of elements.
+ @param erp Error report, may be NULL.
+ @return Pointer to memory on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if elsize or nelem is 0,
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow when calculating the
+ product of elsize and nelem,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available.
+*/
+void *
+dk4mem_malloc(size_t elsize, size_t nelem, dk4_er_t *erp);
+
+/** Dynamically allocate memory and initialize memory range.
+
+ CRT on Windows: Optional.
+ @param elsize Size of each element.
+ @param nelem Number of elements.
+ @param erp Error report, may be NULL.
+ @return Pointer to memory on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if elsize or nelem is 0,
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow when calculating the
+ product of elsize and nelem,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available.
+*/
+void *
+dk4mem_calloc(size_t elsize, size_t nelem, dk4_er_t *erp);
+
+/** Release memory allocated by dk4mem_malloc() or dk4mem_calloc().
+ The function checks whether the pointer is NULL and frees
+ the memory only for non-NULL pointers.
+ CRT on Windows: Optional.
+ @param ptr Pointer to start address of memory to release.
+*/
+void
+dk4mem_free(void *ptr);
+
+#endif
+/* if defined(_WIN32) ... */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/** Allocate and initialize memory.
+ @param tp Type to allocate.
+ @param ne Number of elements to allocate.
+ @param er Error report, may be NULL.
+ @return Pointer to a new tp on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if elsize or nelem is 0,
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow when calculating the product of elsize and nelem,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem set if there is not enough memory
+ available.
+*/
+#define dk4mem_new(tp,ne,er) (tp *)dk4mem_calloc(sizeof(tp),ne,er)
+
+
+
+/** Free memory previously allocated.
+ @param ptr Start address of memory range to free.
+*/
+#define dk4mem_release(ptr) \
+do { if (NULL != ptr) { dk4mem_free(ptr); } ptr = NULL; } while (0)
+
+
+/** Find number of elements in array.
+ @param v Variable.
+ @param t Type.
+ @return The size of the variable divided by the size of the type.
+*/
+#define DK4_SIZEOF(v,t) (sizeof(v)/sizeof(t))
+
+
+
+/** Increase byte number to alignment size.
+ @param sz Original byte number.
+ @param al Alignment size, typically 16.
+ @return Size corrected for alignment.
+*/
+#define DK4_MEM_ALIGN(sz,al) ((0 == (sz % al)) ? (sz) : (al * (1 + (sz/al))))
+
+
+#if DK4_HAVE_INLINE
+/* +++ DK4_HAVE_INLINE */
+#if DK4_ON_WINDOWS
+/* +++ DK4_HAVE_INLINE, Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+/* +++ DK4_HAVE_INLINE, Windows, ! crt */
+/** Pure memory copy operation. All arguments must be checked
+ by the caller before calling this function.
+ @param dst Destination buffer address.
+ @param src Source buffer address.
+ @param sz Number of bytes to copy.
+*/
+static
+inline
+void
+DK4_MEMCPY(void *dst, const void *src, size_t sz)
+{
+ CopyMemory(dst, src, sz);
+}
+/** Pure memory reset. All arguments must be checked by the caller
+ before calling this function.
+ @param dst Start address of buffer to reset.
+ @param sz Number of bytes to reset.
+*/
+static
+inline
+void
+DK4_MEMRES(void *dst, size_t sz)
+{
+ ZeroMemory(dst, sz);
+}
+/** Pure memory comparison.
+ All arguments must be checked by the caller before calling this
+ function.
+ @param s1 Address of left buffer in comparison.
+ @param s2 Address of right buffer in comparison.
+ @param sz Number of bytes to compare.
+ @return 1 if s1>s2, 0 for equal buffers, -1 if s1<s2.
+*/
+static
+inline
+int
+DK4_MEMCMP(const void *s1, const void *s2, size_t sz)
+{
+ return ( dk4mem_fallback_cmp(s1, s2, sz) );
+}
+/* --- DK4_HAVE_INLINE, Windows, ! crt */
+#else
+/* +++ DK4_HAVE_INLINE, Windows, crt */
+/** Pure memory copy operation. All arguments must be checked
+ by the caller before calling this function.
+ @param dst Destination buffer address.
+ @param src Source buffer address.
+ @param sz Number of bytes to copy.
+*/
+static
+inline
+void
+DK4_MEMCPY(void *dst, const void *src, size_t sz)
+{
+ memcpy(dst, src, sz);
+}
+/** Pure memory reset. All arguments must be checked by the caller
+ before calling this function.
+ @param dst Start address of buffer to reset.
+ @param sz Number of bytes to reset.
+*/
+static
+inline
+void
+DK4_MEMRES(void *dst, size_t sz)
+{
+ memset(dst, 0, sz);
+}
+/** Pure memory comparison.
+ All arguments must be checked by the caller before calling this
+ function.
+ @param s1 Address of left buffer in comparison.
+ @param s2 Address of right buffer in comparison.
+ @param sz Number of bytes to compare.
+ @return 1 if s1>s2, 0 for equal buffers, -1 if s1<s2.
+*/
+static
+inline
+int
+DK4_MEMCMP(const void *s1, const void *s2, size_t sz)
+{
+ return (memcmp(s1, s2, sz));
+}
+/* --- DK4_HAVE_INLINE, Windows, crt */
+#endif
+/* --- DK4_HAVE_INLINE, Windows */
+#else
+/* +++ DK4_HAVE_INLINE, ! Windows */
+#if DK4_HAVE_MEMSET
+/* +++ DK4_HAVE_INLINE, ! Windows, memset */
+/** Pure memory reset. All arguments must be checked by the caller
+ before calling this function.
+ @param dst Start address of buffer to reset.
+ @param sz Number of bytes to reset.
+*/
+static
+inline
+void
+DK4_MEMRES(void *dst, size_t sz)
+{
+ memset(dst, 0, sz);
+}
+/* --- DK4_HAVE_INLINE, ! Windows, memset */
+#else
+/* +++ DK4_HAVE_INLINE, ! Windows, ! memset */
+#if DK4_HAVE_BZERO
+/* +++ DK4_HAVE_INLINE, ! Windows, ! memset, bzero */
+/** Pure memory reset. All arguments must be checked by the caller
+ before calling this function.
+ @param dst Start address of buffer to reset.
+ @param sz Number of bytes to reset.
+*/
+static
+inline
+void
+DK4_MEMRES(void *dst, size_t sz)
+{
+ bzero(dst, sz);
+}
+/* --- DK4_HAVE_INLINE, ! Windows, ! memset, bzero */
+#else
+/* +++ DK4_HAVE_INLINE, ! Windows, ! memset, ! bzero */
+/** Pure memory reset. All arguments must be checked by the caller
+ before calling this function.
+ @param dst Start address of buffer to reset.
+ @param sz Number of bytes to reset.
+*/
+static
+inline
+void
+DK4_MEMRES(void *dst, size_t sz)
+{
+ dk4mem_fallback_reset(dst, sz);
+}
+/* --- DK4_HAVE_INLINE, ! Windows, ! memset, ! bzero */
+#endif
+/* --- DK4_HAVE_INLINE, ! Windows, ! memset */
+#endif
+#if DK4_HAVE_MEMCPY
+/* +++ DK4_HAVE_INLINE, ! Windows, memcpy */
+/** Pure memory copy operation. All arguments must be checked
+ by the caller before calling this function.
+ @param dst Destination buffer address.
+ @param src Source buffer address.
+ @param sz Number of bytes to copy.
+*/
+static
+inline
+void
+DK4_MEMCPY(void *dst, const void *src, size_t sz)
+{
+ memcpy(dst, src, sz);
+}
+/* --- DK4_HAVE_INLINE, ! Windows, memcpy */
+#else
+/* +++ DK4_HAVE_INLINE, ! Windows, ! memcpy */
+#if DK4_HAVE_BCOPY
+/* +++ DK4_HAVE_INLINE, ! Windows, ! memcpy, bcopy */
+/** Pure memory copy operation. All arguments must be checked
+ by the caller before calling this function.
+ @param dst Destination buffer address.
+ @param src Source buffer address.
+ @param sz Number of bytes to copy.
+*/
+static
+inline
+void
+DK4_MEMCPY(void *dst, const void *src, size_t sz)
+{
+ bcopy(src, dst, sz);
+}
+/* --- DK4_HAVE_INLINE, ! Windows, ! memcpy, bcopy */
+#else
+/* +++ DK4_HAVE_INLINE, ! Windows, ! memcpy, ! bcopy */
+/** Pure memory copy operation. All arguments must be checked
+ by the caller before calling this function.
+ @param dst Destination buffer address.
+ @param src Source buffer address.
+ @param sz Number of bytes to copy.
+*/
+static
+inline
+void
+DK4_MEMCPY(void *dst, const void *src, size_t sz)
+{
+ dk4mem_fallback_cpy(dst, src, sz);
+}
+/* --- DK4_HAVE_INLINE, ! Windows, ! memcpy, ! bcopy */
+#endif
+/* --- DK4_HAVE_INLINE, ! Windows, ! memcpy */
+#endif
+#if DK4_HAVE_MEMCMP
+/* +++ DK4_HAVE_INLINE, ! Windows, memcmp */
+/** Pure memory comparison.
+ All arguments must be checked by the caller before calling this
+ function.
+ @param s1 Address of left buffer in comparison.
+ @param s2 Address of right buffer in comparison.
+ @param sz Number of bytes to compare.
+ @return 1 if s1>s2, 0 for equal buffers, -1 if s1<s2.
+*/
+static
+inline
+int
+DK4_MEMCMP(const void *s1, const void *s2, size_t sz)
+{
+ return (memcmp(s1, s2, sz));
+}
+/* --- DK4_HAVE_INLINE, ! Windows, memcmp */
+#else
+/* +++ DK4_HAVE_INLINE, ! Windows, ! memcmp */
+#if DK4_HAVE_BCMP
+/* +++ DK4_HAVE_INLINE, ! Windows, ! memcmp, bcmp */
+/** Pure memory comparison.
+ All arguments must be checked by the caller before calling this
+ function.
+ @param s1 Address of left buffer in comparison.
+ @param s2 Address of right buffer in comparison.
+ @param sz Number of bytes to compare.
+ @return 1 if s1>s2, 0 for equal buffers, -1 if s1<s2.
+*/
+static
+inline
+int
+DK4_MEMCMP(const void *s1, const void *s2, size_t sz)
+{
+ return (bcmp(s1, s2, sz));
+}
+/* --- DK4_HAVE_INLINE, ! Windows, ! memcmp, bcmp */
+#else
+/* +++ DK4_HAVE_INLINE, ! Windows, ! memcmp, ! bcmp */
+/** Pure memory comparison.
+ All arguments must be checked by the caller before calling this
+ function.
+ @param s1 Address of left buffer in comparison.
+ @param s2 Address of right buffer in comparison.
+ @param sz Number of bytes to compare.
+ @return 1 if s1>s2, 0 for equal buffers, -1 if s1<s2.
+*/
+static
+inline
+int
+DK4_MEMCMP(const void *s1, const void *s2, size_t sz)
+{
+ return ( dk4mem_fallback_cmp(s1, s2, sz) );
+}
+/* --- DK4_HAVE_INLINE, ! Windows, ! memcmp, ! bcmp */
+#endif
+/* --- DK4_HAVE_INLINE, ! Windows, ! memcmp */
+#endif
+/* --- DK4_HAVE_INLINE, ! Windows */
+#endif
+/* --- DK4_HAVE_INLINE */
+#else
+/* +++ ! DK4_HAVE_INLINE */
+#if DK4_ON_WINDOWS
+/* +++ ! DK4_HAVE_INLINE, Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+/* +++ ! DK4_HAVE_INLINE, Windows, ! crt */
+/** Pure memory copy operation. All arguments must be checked
+ by the caller before calling this function.
+ @param dst Destination buffer address.
+ @param src Source buffer address.
+ @param sz Number of bytes to copy.
+*/
+#define DK4_MEMCPY(dst,src,sz) CopyMemory(dst, src, sz)
+/** Pure memory reset. All arguments must be checked by the caller
+ before calling this function.
+ @param dst Start address of buffer to reset.
+ @param sz Number of bytes to reset.
+*/
+#define DK4_MEMRES(dst,sz) ZeroMemory(dst, sz)
+/** Pure memory comparison.
+ All arguments must be checked by the caller before calling this
+ function.
+ @param s1 Address of left buffer in comparison.
+ @param s2 Address of right buffer in comparison.
+ @param sz Number of bytes to compare.
+ @return 1 if s1>s2, 0 for equal buffers, -1 if s1<s2.
+*/
+#define DK4_MEMCMP(s1,s2,sz) dk4mem_fallback_cmp(s1, s2, sz)
+/* --- ! DK4_HAVE_INLINE, Windows, ! crt */
+#else
+/* +++ ! DK4_HAVE_INLINE, Windows, crt */
+/** Pure memory copy operation. All arguments must be checked
+ by the caller before calling this function.
+ @param dst Destination buffer address.
+ @param src Source buffer address.
+ @param sz Number of bytes to copy.
+*/
+#define DK4_MEMCPY(dst,src,sz) memcpy(dst, src, sz)
+/** Pure memory reset. All arguments must be checked by the caller
+ before calling this function.
+ @param dst Start address of buffer to reset.
+ @param sz Number of bytes to reset.
+*/
+#define DK4_MEMRES(dst,sz) memset(dst, 0, sz)
+/** Pure memory comparison.
+ All arguments must be checked by the caller before calling this
+ function.
+ @param s1 Address of left buffer in comparison.
+ @param s2 Address of right buffer in comparison.
+ @param sz Number of bytes to compare.
+ @return 1 if s1>s2, 0 for equal buffers, -1 if s1<s2.
+*/
+#define DK4_MEMCMP(s1,s2,sz) memcmp(s1, s2, sz)
+/* --- ! DK4_HAVE_INLINE, Windows, crt */
+#endif
+/* --- ! DK4_HAVE_INLINE, Windows */
+#else
+/* +++ ! DK4_HAVE_INLINE, ! Windows */
+#if DK4_HAVE_MEMSET
+/* +++ ! DK4_HAVE_INLINE, ! Windows, memset */
+/** Pure memory reset. All arguments must be checked by the caller
+ before calling this function.
+ @param dst Start address of buffer to reset.
+ @param sz Number of bytes to reset.
+*/
+#define DK4_MEMRES(dst,sz) memset(dst, 0, sz)
+/* --- ! DK4_HAVE_INLINE, ! Windows, memset */
+#else
+/* +++ ! DK4_HAVE_INLINE, ! Windows, ! memset */
+#if DK4_HAVE_BZERO
+/* +++ ! DK4_HAVE_INLINE, ! Windows, ! memset, bzero */
+/** Pure memory reset. All arguments must be checked by the caller
+ before calling this function.
+ @param dst Start address of buffer to reset.
+ @param sz Number of bytes to reset.
+*/
+#define DK4_MEMRES(dst,sz) bzero(dst, sz)
+/* --- ! DK4_HAVE_INLINE, ! Windows, ! memset, bzero */
+#else
+/* +++ ! DK4_HAVE_INLINE, ! Windows, ! memset, ! bzero */
+/** Pure memory reset. All arguments must be checked by the caller
+ before calling this function.
+ @param dst Start address of buffer to reset.
+ @param sz Number of bytes to reset.
+*/
+#define DK4_MEMRES(dst,sz) dk4mem_fallback_reset(dst, sz)
+/* --- ! DK4_HAVE_INLINE, ! Windows, ! memset, ! bzero */
+#endif
+/* --- ! DK4_HAVE_INLINE, ! Windows, ! memset */
+#endif
+#if DK4_HAVE_MEMCPY
+/* +++ ! DK4_HAVE_INLINE, ! Windows, memcpy */
+/** Pure memory copy operation. All arguments must be checked
+ by the caller before calling this function.
+ @param dst Destination buffer address.
+ @param src Source buffer address.
+ @param sz Number of bytes to copy.
+*/
+#define DK4_MEMCPY(dst,src,sz) memcpy(dst, src, sz)
+/* --- ! DK4_HAVE_INLINE, ! Windows, memcpy */
+#else
+/* +++ ! DK4_HAVE_INLINE, ! Windows, ! memcpy */
+#if DK4_HAVE_BCOPY
+/* +++ ! DK4_HAVE_INLINE, ! Windows, ! memcpy, bcopy */
+/** Pure memory copy operation. All arguments must be checked
+ by the caller before calling this function.
+ @param dst Destination buffer address.
+ @param src Source buffer address.
+ @param sz Number of bytes to copy.
+*/
+#define DK4_MEMCPY(dst,src,sz) bcopy(src, dst, sz)
+/* --- ! DK4_HAVE_INLINE, ! Windows, ! memcpy, bcopy */
+#else
+/* +++ ! DK4_HAVE_INLINE, ! Windows, ! memcpy, ! bcopy */
+/** Pure memory copy operation. All arguments must be checked
+ by the caller before calling this function.
+ @param dst Destination buffer address.
+ @param src Source buffer address.
+ @param sz Number of bytes to copy.
+*/
+#define DK4_MEMCPY(dst,src,sz) dk4mem_fallback_cpy(dst, src, sz)
+/* --- ! DK4_HAVE_INLINE, ! Windows, ! memcpy, ! bcopy */
+#endif
+/* --- ! DK4_HAVE_INLINE, ! Windows, ! memcpy */
+#endif
+#if DK4_HAVE_MEMCMP
+/* +++ ! DK4_HAVE_INLINE, ! Windows, memcmp */
+/** Pure memory comparison.
+ All arguments must be checked by the caller before calling this
+ function.
+ @param s1 Address of left buffer in comparison.
+ @param s2 Address of right buffer in comparison.
+ @param sz Number of bytes to compare.
+ @return 1 if s1>s2, 0 for equal buffers, -1 if s1<s2.
+*/
+#define DK4_MEMCMP(s1,s2,sz) memcmp(s1, s2, sz)
+/* --- ! DK4_HAVE_INLINE, ! Windows, memcmp */
+#else
+/* +++ ! DK4_HAVE_INLINE, ! Windows, ! memcmp */
+#if DK4_HAVE_BCMP
+/* +++ ! DK4_HAVE_INLINE, ! Windows, ! memcmp, bcmp */
+/** Pure memory comparison.
+ All arguments must be checked by the caller before calling this
+ function.
+ @param s1 Address of left buffer in comparison.
+ @param s2 Address of right buffer in comparison.
+ @param sz Number of bytes to compare.
+ @return 1 if s1>s2, 0 for equal buffers, -1 if s1<s2.
+*/
+#define DK4_MEMCMP(s1,s2,sz) bcmp(s1, s2, sz)
+/* --- ! DK4_HAVE_INLINE, ! Windows, ! memcmp, bcmp */
+#else
+/* +++ ! DK4_HAVE_INLINE, ! Windows, ! memcmp, ! bcmp */
+/** Pure memory comparison.
+ All arguments must be checked by the caller before calling this
+ function.
+ @param s1 Address of left buffer in comparison.
+ @param s2 Address of right buffer in comparison.
+ @param sz Number of bytes to compare.
+ @return 1 if s1>s2, 0 for equal buffers, -1 if s1<s2.
+*/
+#define DK4_MEMCMP(s1,s2,sz) dk4mem_fallback_cmp(s1, s2, sz)
+/* --- ! DK4_HAVE_INLINE, ! Windows, ! memcmp, ! bcmp */
+#endif
+/* --- ! DK4_HAVE_INLINE, ! Windows, ! memcmp */
+#endif
+/* --- ! DK4_HAVE_INLINE, ! Windows */
+#endif
+/* --- ! DK4_HAVE_INLINE */
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4mema.c b/support/dktools/dk4mema.c
new file mode 100644
index 0000000000..8b9287d373
--- /dev/null
+++ b/support/dktools/dk4mema.c
@@ -0,0 +1,97 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mema.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mema.c The dk4mema module.
+*/
+
+
+#line 60 "dk4mema.ctr"
+
+#include "dk4mema.h"
+#include "dk4mem.h"
+#include "dk4maodd.h"
+#include "dk4const.h"
+
+
+void *
+dk4mem_calloc_app(size_t elsize, size_t nelem, dk4_app_t *app)
+{
+ dkChar elsb[64];
+ dkChar nelb[64];
+ void *back = NULL;
+ dk4_er_t er;
+ int res;
+
+ dk4error_init(&er);
+ back = dk4mem_calloc(elsize, nelem, &er);
+ if (NULL == back) {
+ res = dk4ma_write_decimal_unsigned(
+ elsb, DK4_SIZEOF(elsb,dkChar), (dk4_um_t)elsize, 0, NULL
+ );
+ if (0 != res) {
+ res = dk4ma_write_decimal_unsigned(
+ nelb, DK4_SIZEOF(nelb,dkChar), (dk4_um_t)nelem, 0, NULL
+ );
+ }
+ switch (er.ec) {
+ case DK4_E_MATH_OVERFLOW: {
+ /* ERROR: Numeric overflow in size calculation */
+ if (0 != res) {
+ dk4app_log_base5(app,DK4_LL_ERROR,83,84,85,nelb,elsb);
+ } else {
+ dk4app_log_base1(app, DK4_LL_ERROR, 82);
+ }
+ } break;
+ case DK4_E_INVALID_ARGUMENTS: {
+ /* ERROR: Invalid sizes */
+ if (0 != res) {
+ dk4app_log_base5(app,DK4_LL_ERROR,87,88,89,nelb,elsb);
+ } else {
+ dk4app_log_base1(app, DK4_LL_ERROR, 86);
+ }
+ } break;
+ default: {
+ /* ERROR: Not enough memory */
+ if (0 != res) {
+ dk4app_log_base5(app,DK4_LL_ERROR,91,92,93,nelb,elsb);
+ } else {
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ }
+ } break;
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4mema.ctr b/support/dktools/dk4mema.ctr
new file mode 100644
index 0000000000..dad2c6eaf5
--- /dev/null
+++ b/support/dktools/dk4mema.ctr
@@ -0,0 +1,116 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Memory allocation with included
+ diagnostics.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4APP_H_INCLUDED
+#include "dk4app.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Allocate and initialize memory.
+ @param elsize Element size.
+ @param nelem Number of elements.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new memory on success, NULL on error.
+*/
+void *
+dk4mem_calloc_app(size_t elsize, size_t nelem, dk4_app_t *app);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+/** Allocate and initialize memory.
+ @param tp Type to allocate.
+ @param ne Number of elements to allocate.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to a new tp on success, NULL on error.
+*/
+#define dk4mem_new_app(tp,ne,app) (tp *)dk4mem_calloc_app(sizeof(tp),ne,app)
+
+
+
+%% module
+
+#include "dk4mema.h"
+#include "dk4mem.h"
+#include "dk4maodd.h"
+#include "dk4const.h"
+
+
+void *
+dk4mem_calloc_app(size_t elsize, size_t nelem, dk4_app_t *app)
+{
+ dkChar elsb[64];
+ dkChar nelb[64];
+ void *back = NULL;
+ dk4_er_t er;
+ int res;
+
+ dk4error_init(&er);
+ back = dk4mem_calloc(elsize, nelem, &er);
+ if (NULL == back) {
+ res = dk4ma_write_decimal_unsigned(
+ elsb, DK4_SIZEOF(elsb,dkChar), (dk4_um_t)elsize, 0, NULL
+ );
+ if (0 != res) {
+ res = dk4ma_write_decimal_unsigned(
+ nelb, DK4_SIZEOF(nelb,dkChar), (dk4_um_t)nelem, 0, NULL
+ );
+ }
+ switch (er.ec) {
+ case DK4_E_MATH_OVERFLOW: {
+ /* ERROR: Numeric overflow in size calculation */
+ if (0 != res) {
+ dk4app_log_base5(app,DK4_LL_ERROR,83,84,85,nelb,elsb);
+ } else {
+ dk4app_log_base1(app, DK4_LL_ERROR, 82);
+ }
+ } break;
+ case DK4_E_INVALID_ARGUMENTS: {
+ /* ERROR: Invalid sizes */
+ if (0 != res) {
+ dk4app_log_base5(app,DK4_LL_ERROR,87,88,89,nelb,elsb);
+ } else {
+ dk4app_log_base1(app, DK4_LL_ERROR, 86);
+ }
+ } break;
+ default: {
+ /* ERROR: Not enough memory */
+ if (0 != res) {
+ dk4app_log_base5(app,DK4_LL_ERROR,91,92,93,nelb,elsb);
+ } else {
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ }
+ } break;
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4mema.h b/support/dktools/dk4mema.h
new file mode 100644
index 0000000000..57140cff40
--- /dev/null
+++ b/support/dktools/dk4mema.h
@@ -0,0 +1,92 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mema.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MEMA_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MEMA_H_INCLUDED 1
+
+
+#line 10 "dk4mema.ctr"
+
+/** @file
+ Memory allocation with included
+ diagnostics.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4APP_H_INCLUDED
+#include "dk4app.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Allocate and initialize memory.
+ @param elsize Element size.
+ @param nelem Number of elements.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new memory on success, NULL on error.
+*/
+void *
+dk4mem_calloc_app(size_t elsize, size_t nelem, dk4_app_t *app);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+/** Allocate and initialize memory.
+ @param tp Type to allocate.
+ @param ne Number of elements to allocate.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to a new tp on success, NULL on error.
+*/
+#define dk4mem_new_app(tp,ne,app) (tp *)dk4mem_calloc_app(sizeof(tp),ne,app)
+
+
+
+
+#endif
diff --git a/support/dktools/dk4membf.c b/support/dktools/dk4membf.c
new file mode 100644
index 0000000000..999fcacef0
--- /dev/null
+++ b/support/dktools/dk4membf.c
@@ -0,0 +1,81 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4membf.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4membf.c The dk4membf module.
+*/
+
+
+#line 41 "dk4membf.ctr"
+
+#include "dk4membf.h"
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+
+int
+dk4membuf_to_file(FILE *fipo, dk4_membuf_t *mbptr, dk4_er_t *erp)
+{
+ dk4_membuf_cell_t *pc = NULL;
+ dk4_membuf_cell_t *pn = NULL;
+ size_t wrb = 0;
+ int back = 0;
+
+ if ((NULL != fipo) && (NULL != mbptr)) {
+ back = 1;
+ pc = mbptr->first;
+ while (NULL != pc) {
+ pn = pc->next;
+ if (0 < pc->used) {
+ errno = 0;
+ wrb = fwrite(pc->buf, 1, pc->used, fipo);
+ if (wrb != pc->used) {
+ back = 0;
+ dk4error_set_idetails(erp, DK4_E_WRITE_FAILED, errno);
+ }
+ }
+ pc = pn;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4membf.ctr b/support/dktools/dk4membf.ctr
new file mode 100644
index 0000000000..a00d284ea8
--- /dev/null
+++ b/support/dktools/dk4membf.ctr
@@ -0,0 +1,81 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk4membf.h Save buffer data to file.
+*/
+
+#ifndef STDIO_H_INCLUDED
+#include <stdio.h>
+#define STDIO_H_INCLUDED 1
+#endif
+
+#include "dk4membuf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Save buffer contents to file.
+ @param fipo Output file.
+ @param mbptr Buffer containing data to write.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4membuf_to_file(FILE *fipo, dk4_membuf_t *mbptr, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4membf.h"
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+
+int
+dk4membuf_to_file(FILE *fipo, dk4_membuf_t *mbptr, dk4_er_t *erp)
+{
+ dk4_membuf_cell_t *pc = NULL;
+ dk4_membuf_cell_t *pn = NULL;
+ size_t wrb = 0;
+ int back = 0;
+
+ if ((NULL != fipo) && (NULL != mbptr)) {
+ back = 1;
+ pc = mbptr->first;
+ while (NULL != pc) {
+ pn = pc->next;
+ if (0 < pc->used) {
+ errno = 0;
+ wrb = fwrite(pc->buf, 1, pc->used, fipo);
+ if (wrb != pc->used) {
+ back = 0;
+ dk4error_set_idetails(erp, DK4_E_WRITE_FAILED, errno);
+ }
+ }
+ pc = pn;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4membf.h b/support/dktools/dk4membf.h
new file mode 100644
index 0000000000..43ccac56c3
--- /dev/null
+++ b/support/dktools/dk4membf.h
@@ -0,0 +1,73 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4membf.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MEMBF_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MEMBF_H_INCLUDED 1
+
+
+#line 10 "dk4membf.ctr"
+
+/** @file dk4membf.h Save buffer data to file.
+*/
+
+#ifndef STDIO_H_INCLUDED
+#include <stdio.h>
+#define STDIO_H_INCLUDED 1
+#endif
+
+#include "dk4membuf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Save buffer contents to file.
+ @param fipo Output file.
+ @param mbptr Buffer containing data to write.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4membuf_to_file(FILE *fipo, dk4_membuf_t *mbptr, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4membs.c b/support/dktools/dk4membs.c
new file mode 100644
index 0000000000..70ff054236
--- /dev/null
+++ b/support/dktools/dk4membs.c
@@ -0,0 +1,71 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4membs.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4membs.c The dk4membs module.
+*/
+
+
+#line 37 "dk4membs.ctr"
+
+#include "dk4membs.h"
+
+
+
+int
+dk4membuf_to_stream(dk4_stream_t *strm, dk4_membuf_t *mbptr, dk4_er_t *erp)
+{
+ dk4_membuf_cell_t *pc = NULL;
+ dk4_membuf_cell_t *pn = NULL;
+ int back = 0;
+
+ if ((NULL != strm) && (NULL != mbptr)) {
+ back = 1;
+ pc = mbptr->first;
+ while (NULL != pc) {
+ pn = pc->next;
+ if (0 < pc->used) {
+ if (0 == dk4stream_write(strm, pc->buf, pc->used, erp)) {
+ back = 0;
+ }
+ }
+ pc = pn;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4membs.ctr b/support/dktools/dk4membs.ctr
new file mode 100644
index 0000000000..3931b00a8e
--- /dev/null
+++ b/support/dktools/dk4membs.ctr
@@ -0,0 +1,67 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk4membs.h Save buffer data to stream.
+*/
+
+#include "dk4membuf.h"
+#include "dk4strm.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Save buffer contents to file.
+ @param strm Output stream.
+ @param mbptr Buffer containing data to write.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4membuf_to_stream(dk4_stream_t *strm, dk4_membuf_t *mbptr, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4membs.h"
+
+
+
+int
+dk4membuf_to_stream(dk4_stream_t *strm, dk4_membuf_t *mbptr, dk4_er_t *erp)
+{
+ dk4_membuf_cell_t *pc = NULL;
+ dk4_membuf_cell_t *pn = NULL;
+ int back = 0;
+
+ if ((NULL != strm) && (NULL != mbptr)) {
+ back = 1;
+ pc = mbptr->first;
+ while (NULL != pc) {
+ pn = pc->next;
+ if (0 < pc->used) {
+ if (0 == dk4stream_write(strm, pc->buf, pc->used, erp)) {
+ back = 0;
+ }
+ }
+ pc = pn;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4membs.h b/support/dktools/dk4membs.h
new file mode 100644
index 0000000000..e35e9a6b71
--- /dev/null
+++ b/support/dktools/dk4membs.h
@@ -0,0 +1,69 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4membs.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MEMBS_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MEMBS_H_INCLUDED 1
+
+
+#line 10 "dk4membs.ctr"
+
+/** @file dk4membs.h Save buffer data to stream.
+*/
+
+#include "dk4membuf.h"
+#include "dk4strm.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Save buffer contents to file.
+ @param strm Output stream.
+ @param mbptr Buffer containing data to write.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4membuf_to_stream(dk4_stream_t *strm, dk4_membuf_t *mbptr, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4membuf.c b/support/dktools/dk4membuf.c
new file mode 100644
index 0000000000..fe6931d6a5
--- /dev/null
+++ b/support/dktools/dk4membuf.c
@@ -0,0 +1,216 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4membuf.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4membuf.c The dk4membuf module.
+*/
+
+
+#line 95 "dk4membuf.ctr"
+
+#include "dk4membuf.h"
+#include "dk4mem.h"
+#include "dk4maasz.h"
+
+
+
+
+
+#line 103 "dk4membuf.ctr"
+
+
+
+static
+void
+dk4membuf_cell_close(dk4_membuf_cell_t *mcptr)
+{
+ if (NULL != mcptr) {
+ dk4mem_release(mcptr->buf);
+ mcptr->next = NULL;
+ mcptr->max = mcptr->used = 0;
+ dk4mem_free(mcptr);
+ }
+}
+
+
+
+static
+dk4_membuf_cell_t *
+dk4membuf_cell_open(size_t sz, dk4_er_t *erp)
+{
+ dk4_er_t er;
+ dk4_membuf_cell_t *back = NULL;
+ size_t nb;
+
+ /* Ensure number of bytes is a multiple of the chunk size.
+ */
+ nb = sz / DK4MEMBUF_CHUNK_SIZE;
+ if (0 != (sz % DK4MEMBUF_CHUNK_SIZE)) { nb++; }
+ dk4error_init(&er);
+ nb = dk4ma_size_t_mul(nb, (size_t)(DK4MEMBUF_CHUNK_SIZE), &er);
+ if (0 != er.ec) { nb = sz; }
+
+ /* Allocate
+ */
+ back = dk4mem_new(dk4_membuf_cell_t,1,erp);
+ if (NULL != back) {
+ back->next = NULL;
+ back->max = nb;
+ back->used = 0;
+ back->buf = dk4mem_new(char,nb,erp);
+ if (NULL == back->buf) {
+ dk4mem_free(back);
+ back = NULL;
+ }
+ }
+ return back;
+}
+
+
+
+dk4_membuf_t *
+dk4membuf_open(dk4_er_t *erp)
+{
+ dk4_membuf_t *back = NULL;
+ back = dk4mem_new(dk4_membuf_t,1,erp);
+ if (NULL != back) {
+ back->he = 0;
+ back->last = NULL;
+ back->first = dk4membuf_cell_open(DK4MEMBUF_CHUNK_SIZE, erp);
+ if (NULL != back->first) {
+ back->last = back->first;
+ } else {
+ dk4mem_free(back);
+ back = NULL;
+ }
+ }
+ return back;
+}
+
+
+
+void
+dk4membuf_close(dk4_membuf_t *mbptr)
+{
+ dk4_membuf_cell_t *pc;
+ dk4_membuf_cell_t *pn;
+
+ if (NULL != mbptr) {
+ pc = mbptr->first;
+ while (NULL != pc) {
+ pn = pc->next;
+ dk4membuf_cell_close(pc);
+ pc = pn;
+ }
+ dk4mem_free(mbptr);
+ }
+}
+
+
+
+int
+dk4membuf_store(dk4_membuf_t *mbptr, const void *src, size_t sz, dk4_er_t *erp)
+{
+ dk4_membuf_cell_t *pc = NULL;
+ dk4_membuf_cell_t *pn = NULL;
+ const char *psrc = NULL;
+ size_t bl = 0;
+ int back = 0;
+
+ if ((NULL != mbptr) && (NULL != src) && (0 < sz)) {
+ /* Initialize variables.
+ */
+ back = 1;
+ pc = mbptr->last;
+ psrc = (const char *)src;
+ /* Attempt to fill current cell.
+ */
+ if (pc->max > pc->used) {
+ bl = pc->max - pc->used;
+ if (sz < bl) { bl = sz; }
+ DK4_MEMCPY(&((pc->buf)[pc->used]), psrc, bl);
+ pc->used += bl;
+ sz -= bl;
+ psrc = &(psrc[bl]);
+ }
+ /* Use new cell if necessary.
+ */
+ if (0 < sz) {
+ back = 0;
+ pn = dk4membuf_cell_open(sz, erp);
+ if (NULL != pn) {
+ pc->next = pn;
+ mbptr->last = pn;
+ DK4_MEMCPY(pn->buf, psrc, sz);
+ back = 1;
+ pn->used = sz;
+ } else {
+ mbptr->he = 1;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4membuf_size(size_t *szptr, dk4_membuf_t *mbptr, dk4_er_t *erp)
+{
+ dk4_er_t er;
+ dk4_membuf_cell_t *cp = NULL;
+ size_t result = (size_t)0U;
+ int back = 0;
+
+ if ((NULL != szptr) && (NULL != mbptr)) {
+ back = 1;
+ cp = mbptr->first;
+ dk4error_init(&er);
+ while (NULL != cp) {
+ result = dk4ma_size_t_add(result, cp->used, &er);
+ cp = cp->next;
+ }
+ if (DK4_E_NONE == er.ec) {
+ back = 1;
+ *szptr = result;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4membuf.ctr b/support/dktools/dk4membuf.ctr
new file mode 100644
index 0000000000..ff8561edcf
--- /dev/null
+++ b/support/dktools/dk4membuf.ctr
@@ -0,0 +1,268 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file dk4membuf.h Memory buffer.
+*/
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+/** One cell of a memory buffer.
+*/
+typedef struct _dk4_membuf_cell_t_ {
+ struct _dk4_membuf_cell_t_ *next; /**< Next element in linked list. */
+ char *buf; /**< Buffer for data storage. */
+ size_t max; /**< Number of bytes available. */
+ size_t used; /**< Number of bytes used. */
+} dk4_membuf_cell_t;
+
+/** Memory buffer object.
+*/
+typedef struct {
+ dk4_membuf_cell_t *first; /**< First cell (head of list). */
+ dk4_membuf_cell_t *last; /**< Last cell (end of list). */
+ int he; /**< Flag: Had allocation error. */
+} dk4_membuf_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Create new buffer, allocate initial memory.
+ @param erp Error report, may be NULL.
+ @return Pointer on success, NULL on error.
+*/
+dk4_membuf_t *
+dk4membuf_open(dk4_er_t *erp);
+
+/** Destroy buffer, release memory.
+ @param mbptr Buffer to destroy.
+*/
+void
+dk4membuf_close(dk4_membuf_t *mbptr);
+
+/** Store data in buffer.
+ @param mbptr Buffer object.
+ @param src Address of data to store.
+ @param sz Number of bytes to store.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error code:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if mbptr or src is NULL or sz is 0,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in size calculation,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem set
+ if there is not enough memory available.
+
+*/
+int
+dk4membuf_store(dk4_membuf_t *mbptr, const void *src, size_t sz, dk4_er_t *erp);
+
+/** Retrieve size of data stored in memory buffer.
+ @param szptr Address of result variable.
+ @param mbptr Buffer to find size for.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error code:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if szptr or mbptr is NULL.
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in size calculation.
+*/
+int
+dk4membuf_size(size_t *szptr, dk4_membuf_t *mbptr, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** Default chunk size.
+*/
+#define DK4MEMBUF_CHUNK_SIZE 4096U
+
+%% module
+
+#include "dk4membuf.h"
+#include "dk4mem.h"
+#include "dk4maasz.h"
+
+
+
+$!trace-include
+
+
+
+static
+void
+dk4membuf_cell_close(dk4_membuf_cell_t *mcptr)
+{
+ if (NULL != mcptr) {
+ dk4mem_release(mcptr->buf);
+ mcptr->next = NULL;
+ mcptr->max = mcptr->used = 0;
+ dk4mem_free(mcptr);
+ }
+}
+
+
+
+static
+dk4_membuf_cell_t *
+dk4membuf_cell_open(size_t sz, dk4_er_t *erp)
+{
+ dk4_er_t er;
+ dk4_membuf_cell_t *back = NULL;
+ size_t nb;
+
+ /* Ensure number of bytes is a multiple of the chunk size.
+ */
+ nb = sz / DK4MEMBUF_CHUNK_SIZE;
+ if (0 != (sz % DK4MEMBUF_CHUNK_SIZE)) { nb++; }
+ dk4error_init(&er);
+ nb = dk4ma_size_t_mul(nb, (size_t)(DK4MEMBUF_CHUNK_SIZE), &er);
+ if (0 != er.ec) { nb = sz; }
+
+ /* Allocate
+ */
+ back = dk4mem_new(dk4_membuf_cell_t,1,erp);
+ if (NULL != back) {
+ back->next = NULL;
+ back->max = nb;
+ back->used = 0;
+ back->buf = dk4mem_new(char,nb,erp);
+ if (NULL == back->buf) {
+ dk4mem_free(back);
+ back = NULL;
+ }
+ }
+ return back;
+}
+
+
+
+dk4_membuf_t *
+dk4membuf_open(dk4_er_t *erp)
+{
+ dk4_membuf_t *back = NULL;
+ back = dk4mem_new(dk4_membuf_t,1,erp);
+ if (NULL != back) {
+ back->he = 0;
+ back->last = NULL;
+ back->first = dk4membuf_cell_open(DK4MEMBUF_CHUNK_SIZE, erp);
+ if (NULL != back->first) {
+ back->last = back->first;
+ } else {
+ dk4mem_free(back);
+ back = NULL;
+ }
+ }
+ return back;
+}
+
+
+
+void
+dk4membuf_close(dk4_membuf_t *mbptr)
+{
+ dk4_membuf_cell_t *pc;
+ dk4_membuf_cell_t *pn;
+
+ if (NULL != mbptr) {
+ pc = mbptr->first;
+ while (NULL != pc) {
+ pn = pc->next;
+ dk4membuf_cell_close(pc);
+ pc = pn;
+ }
+ dk4mem_free(mbptr);
+ }
+}
+
+
+
+int
+dk4membuf_store(dk4_membuf_t *mbptr, const void *src, size_t sz, dk4_er_t *erp)
+{
+ dk4_membuf_cell_t *pc = NULL;
+ dk4_membuf_cell_t *pn = NULL;
+ const char *psrc = NULL;
+ size_t bl = 0;
+ int back = 0;
+
+ if ((NULL != mbptr) && (NULL != src) && (0 < sz)) {
+ /* Initialize variables.
+ */
+ back = 1;
+ pc = mbptr->last;
+ psrc = (const char *)src;
+ /* Attempt to fill current cell.
+ */
+ if (pc->max > pc->used) {
+ bl = pc->max - pc->used;
+ if (sz < bl) { bl = sz; }
+ DK4_MEMCPY(&((pc->buf)[pc->used]), psrc, bl);
+ pc->used += bl;
+ sz -= bl;
+ psrc = &(psrc[bl]);
+ }
+ /* Use new cell if necessary.
+ */
+ if (0 < sz) {
+ back = 0;
+ pn = dk4membuf_cell_open(sz, erp);
+ if (NULL != pn) {
+ pc->next = pn;
+ mbptr->last = pn;
+ DK4_MEMCPY(pn->buf, psrc, sz);
+ back = 1;
+ pn->used = sz;
+ } else {
+ mbptr->he = 1;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4membuf_size(size_t *szptr, dk4_membuf_t *mbptr, dk4_er_t *erp)
+{
+ dk4_er_t er;
+ dk4_membuf_cell_t *cp = NULL;
+ size_t result = (size_t)0U;
+ int back = 0;
+
+ if ((NULL != szptr) && (NULL != mbptr)) {
+ back = 1;
+ cp = mbptr->first;
+ dk4error_init(&er);
+ while (NULL != cp) {
+ result = dk4ma_size_t_add(result, cp->used, &er);
+ cp = cp->next;
+ }
+ if (DK4_E_NONE == er.ec) {
+ back = 1;
+ *szptr = result;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4membuf.h b/support/dktools/dk4membuf.h
new file mode 100644
index 0000000000..3e603777ac
--- /dev/null
+++ b/support/dktools/dk4membuf.h
@@ -0,0 +1,128 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4membuf.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MEMBUF_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MEMBUF_H_INCLUDED 1
+
+
+#line 9 "dk4membuf.ctr"
+
+/** @file dk4membuf.h Memory buffer.
+*/
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+/** One cell of a memory buffer.
+*/
+typedef struct _dk4_membuf_cell_t_ {
+ struct _dk4_membuf_cell_t_ *next; /**< Next element in linked list. */
+ char *buf; /**< Buffer for data storage. */
+ size_t max; /**< Number of bytes available. */
+ size_t used; /**< Number of bytes used. */
+} dk4_membuf_cell_t;
+
+/** Memory buffer object.
+*/
+typedef struct {
+ dk4_membuf_cell_t *first; /**< First cell (head of list). */
+ dk4_membuf_cell_t *last; /**< Last cell (end of list). */
+ int he; /**< Flag: Had allocation error. */
+} dk4_membuf_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Create new buffer, allocate initial memory.
+ @param erp Error report, may be NULL.
+ @return Pointer on success, NULL on error.
+*/
+dk4_membuf_t *
+dk4membuf_open(dk4_er_t *erp);
+
+/** Destroy buffer, release memory.
+ @param mbptr Buffer to destroy.
+*/
+void
+dk4membuf_close(dk4_membuf_t *mbptr);
+
+/** Store data in buffer.
+ @param mbptr Buffer object.
+ @param src Address of data to store.
+ @param sz Number of bytes to store.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error code:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if mbptr or src is NULL or sz is 0,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in size calculation,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem set
+ if there is not enough memory available.
+
+*/
+int
+dk4membuf_store(dk4_membuf_t *mbptr, const void *src, size_t sz, dk4_er_t *erp);
+
+/** Retrieve size of data stored in memory buffer.
+ @param szptr Address of result variable.
+ @param mbptr Buffer to find size for.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error code:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if szptr or mbptr is NULL.
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in size calculation.
+*/
+int
+dk4membuf_size(size_t *szptr, dk4_membuf_t *mbptr, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** Default chunk size.
+*/
+#define DK4MEMBUF_CHUNK_SIZE 4096U
+
+
+#endif
diff --git a/support/dktools/dk4memcpl.c b/support/dktools/dk4memcpl.c
new file mode 100644
index 0000000000..85d5b601a9
--- /dev/null
+++ b/support/dktools/dk4memcpl.c
@@ -0,0 +1,59 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4memcpl.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4memcpl.c The dk4memcpl module.
+*/
+
+
+#line 34 "dk4memcpl.ctr"
+
+
+#include "dk4memcpl.h"
+
+
+
+void
+dk4mem_cpy_to_left(void *dst, const void *src, size_t sz, dk4_er_t *erp)
+{
+ unsigned char *dptr;
+ const unsigned char *sptr;
+ if ((NULL != dst) && (NULL != src) && (0 < sz)) {
+ dptr = (unsigned char *)dst; sptr = (const unsigned char *)src;
+ while (0 < sz--) { *(dptr++) = *(sptr++); }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+}
+
diff --git a/support/dktools/dk4memcpl.ctr b/support/dktools/dk4memcpl.ctr
new file mode 100644
index 0000000000..eb217cccc3
--- /dev/null
+++ b/support/dktools/dk4memcpl.ctr
@@ -0,0 +1,52 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file dk4memcpl.h Copy memory within buffer from right to left.
+*/
+
+#include "dk4error.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Copy memory from right to left.
+ @param dst Destination buffer address.
+ @param src Source buffer address.
+ @param sz Number of bytes to copy.
+ @param erp Error report, may be NULL.
+*/
+void
+dk4mem_cpy_to_left(void *dst, const void *src, size_t sz, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+
+#include "dk4memcpl.h"
+
+
+
+void
+dk4mem_cpy_to_left(void *dst, const void *src, size_t sz, dk4_er_t *erp)
+{
+ unsigned char *dptr;
+ const unsigned char *sptr;
+ if ((NULL != dst) && (NULL != src) && (0 < sz)) {
+ dptr = (unsigned char *)dst; sptr = (const unsigned char *)src;
+ while (0 < sz--) { *(dptr++) = *(sptr++); }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+}
+
diff --git a/support/dktools/dk4memcpl.h b/support/dktools/dk4memcpl.h
new file mode 100644
index 0000000000..8dc60e25f7
--- /dev/null
+++ b/support/dktools/dk4memcpl.h
@@ -0,0 +1,67 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4memcpl.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MEMCPL_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MEMCPL_H_INCLUDED 1
+
+
+#line 9 "dk4memcpl.ctr"
+
+/** @file dk4memcpl.h Copy memory within buffer from right to left.
+*/
+
+#include "dk4error.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Copy memory from right to left.
+ @param dst Destination buffer address.
+ @param src Source buffer address.
+ @param sz Number of bytes to copy.
+ @param erp Error report, may be NULL.
+*/
+void
+dk4mem_cpy_to_left(void *dst, const void *src, size_t sz, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4memrs.c b/support/dktools/dk4memrs.c
new file mode 100644
index 0000000000..cad97ca228
--- /dev/null
+++ b/support/dktools/dk4memrs.c
@@ -0,0 +1,111 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4memrs.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4memrs.c The dk4memrs module.
+*/
+
+
+#line 79 "dk4memrs.ctr"
+
+#include "dk4conf.h"
+
+#ifndef STDIO_H_INCLUDED
+#include <stdio.h>
+#define STDIO_H_INCLUDED 1
+#endif
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4mem.h"
+
+int
+dk4mem_reset_secure(void *ptr, size_t sz, dk4_er_t *erp)
+{
+#if !DK4_ON_WINDOWS
+ unsigned char *p1;
+#endif
+ int back = 0;
+
+ if ((NULL != ptr) && (0 < sz)) {
+#if DK4_ON_WINDOWS
+ SecureZeroMemory(ptr, sz);
+ back = 1;
+#else
+ DK4_MEMRES(ptr, sz);
+ p1 = (unsigned char *)ptr;
+ back = 1;
+ while(sz--) {
+ if ('\0' != *(p1++)) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ }
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4mem_free_secure(void *ptr, size_t sz, dk4_er_t *erp)
+{
+ int back = 0;
+
+ if (NULL != ptr) {
+ if (0 < sz) {
+ back = dk4mem_reset_secure(ptr, sz, erp);
+ } else {
+ back = 1;
+ }
+ dk4mem_free(ptr);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
diff --git a/support/dktools/dk4memrs.ctr b/support/dktools/dk4memrs.ctr
new file mode 100644
index 0000000000..735df8db5a
--- /dev/null
+++ b/support/dktools/dk4memrs.ctr
@@ -0,0 +1,149 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ Secure memory reset (reset byte buffer
+ to 0x00 bytes and read the buffer to prevent compilers
+ from optimizing the resetting out).
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Secure memory reset.
+ This function does not just reset the bytes to 0,
+ it also reads each byte to check it.
+ Reading each byte should prevent the compiler from optimizing
+ out.
+ This function has significantly lower performance than
+ dk4mem_reset(), so use it to clear sensitive memory
+ (i.e. used for passwords, keys...) only.
+
+ CRT on Windows: Not used.
+ @param ptr Start address of memory range.
+ @param sz Size of memory range in bytes.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if ptr is NULL or sz is 0,
+ - DK4_E_BUG<br>
+ if one of the bytes in the buffer is not 0 during check.
+*/
+int
+dk4mem_reset_secure(void *ptr, size_t sz, dk4_er_t *erp);
+
+/** Secure memory release.
+ This function does not just reset the bytes to 0 before releasing
+ memory, it also reads each byte to check it.
+ Reading each byte should prevent the compiler from optimizing
+ out.
+ This function has significantly lower performance than
+ dk4mem_free(), so use it to clear sensitive memory
+ (i.e. used for passwords, keys...) only.
+
+ CRT on Windows: Not used.
+ @param ptr Start address of memory range.
+ @param sz Size of memory range in bytes.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if ptr is NULL or sz is 0,
+ - DK4_E_BUG<br>
+ if one of the bytes in the buffer is not 0 during check.
+*/
+int
+dk4mem_free_secure(void *ptr, size_t sz, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** Release memory securely (sanitize memory before releasing it).
+*/
+#define dk4mem_release_secure(ptr,sz,erp) \
+do { if (NULL != ptr) { (void)dk4mem_free_secure(ptr,sz,erp); } ptr = NULL; } while (0)
+
+
+%% module
+
+#include "dk4conf.h"
+
+#ifndef STDIO_H_INCLUDED
+#include <stdio.h>
+#define STDIO_H_INCLUDED 1
+#endif
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4mem.h"
+
+int
+dk4mem_reset_secure(void *ptr, size_t sz, dk4_er_t *erp)
+{
+#if !DK4_ON_WINDOWS
+ unsigned char *p1;
+#endif
+ int back = 0;
+
+ if ((NULL != ptr) && (0 < sz)) {
+#if DK4_ON_WINDOWS
+ SecureZeroMemory(ptr, sz);
+ back = 1;
+#else
+ DK4_MEMRES(ptr, sz);
+ p1 = (unsigned char *)ptr;
+ back = 1;
+ while(sz--) {
+ if ('\0' != *(p1++)) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ }
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4mem_free_secure(void *ptr, size_t sz, dk4_er_t *erp)
+{
+ int back = 0;
+
+ if (NULL != ptr) {
+ if (0 < sz) {
+ back = dk4mem_reset_secure(ptr, sz, erp);
+ } else {
+ back = 1;
+ }
+ dk4mem_free(ptr);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
diff --git a/support/dktools/dk4memrs.h b/support/dktools/dk4memrs.h
new file mode 100644
index 0000000000..2ab64645b0
--- /dev/null
+++ b/support/dktools/dk4memrs.h
@@ -0,0 +1,112 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4memrs.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MEMRS_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MEMRS_H_INCLUDED 1
+
+
+#line 9 "dk4memrs.ctr"
+
+/** @file
+ Secure memory reset (reset byte buffer
+ to 0x00 bytes and read the buffer to prevent compilers
+ from optimizing the resetting out).
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Secure memory reset.
+ This function does not just reset the bytes to 0,
+ it also reads each byte to check it.
+ Reading each byte should prevent the compiler from optimizing
+ out.
+ This function has significantly lower performance than
+ dk4mem_reset(), so use it to clear sensitive memory
+ (i.e. used for passwords, keys...) only.
+
+ CRT on Windows: Not used.
+ @param ptr Start address of memory range.
+ @param sz Size of memory range in bytes.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if ptr is NULL or sz is 0,
+ - DK4_E_BUG<br>
+ if one of the bytes in the buffer is not 0 during check.
+*/
+int
+dk4mem_reset_secure(void *ptr, size_t sz, dk4_er_t *erp);
+
+/** Secure memory release.
+ This function does not just reset the bytes to 0 before releasing
+ memory, it also reads each byte to check it.
+ Reading each byte should prevent the compiler from optimizing
+ out.
+ This function has significantly lower performance than
+ dk4mem_free(), so use it to clear sensitive memory
+ (i.e. used for passwords, keys...) only.
+
+ CRT on Windows: Not used.
+ @param ptr Start address of memory range.
+ @param sz Size of memory range in bytes.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if ptr is NULL or sz is 0,
+ - DK4_E_BUG<br>
+ if one of the bytes in the buffer is not 0 during check.
+*/
+int
+dk4mem_free_secure(void *ptr, size_t sz, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** Release memory securely (sanitize memory before releasing it).
+*/
+#define dk4mem_release_secure(ptr,sz,erp) \
+do { if (NULL != ptr) { (void)dk4mem_free_secure(ptr,sz,erp); } ptr = NULL; } while (0)
+
+
+
+#endif
diff --git a/support/dktools/dk4mkdh.c b/support/dktools/dk4mkdh.c
new file mode 100644
index 0000000000..94ad8382f3
--- /dev/null
+++ b/support/dktools/dk4mkdh.c
@@ -0,0 +1,65 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mkdh.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mkdh.c The dk4mkdh module.
+*/
+
+
+#line 60 "dk4mkdh.ctr"
+
+#include "dk4mkdh.h"
+
+#if DK4_CHAR_SIZE > 1
+#ifndef DK4MKDHW_H_INCLUDED
+#include "dk4mkdhw.h"
+#endif
+#else
+#ifndef DK4MKDH8_H_INCLUDED
+#include "dk4mkdh8.h"
+#endif
+#endif
+
+
+
+int
+dk4mkdir_hierarchy(const dkChar *fn, int lc, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4mkdir_hierarchy_wc(fn, lc, erp));
+#else
+ return (dk4mkdir_hierarchy_c8(fn, lc, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4mkdh.ctr b/support/dktools/dk4mkdh.ctr
new file mode 100644
index 0000000000..a300402206
--- /dev/null
+++ b/support/dktools/dk4mkdh.ctr
@@ -0,0 +1,84 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Make directory hierarchy (create all parent directories for a
+ file or directory and the directory itself if required),
+ the file or directory name is specified as dkChar string.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Create directory structure.
+ @param fn File name.
+ @param lc Flag: Last component in fn is directory too.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if fn is too long,
+ - DK4_E_NON_DIR<br>
+ if one of the components in fn is not a directory,
+ - DK4_E_MKDIR_FAILED<br>
+ with errno in idetails if the function fails to create the directory
+ or a parent directory,
+*/
+int
+dk4mkdir_hierarchy(const dkChar *fn, int lc, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4mkdh.h"
+
+#if DK4_CHAR_SIZE > 1
+#ifndef DK4MKDHW_H_INCLUDED
+#include "dk4mkdhw.h"
+#endif
+#else
+#ifndef DK4MKDH8_H_INCLUDED
+#include "dk4mkdh8.h"
+#endif
+#endif
+
+
+
+int
+dk4mkdir_hierarchy(const dkChar *fn, int lc, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4mkdir_hierarchy_wc(fn, lc, erp));
+#else
+ return (dk4mkdir_hierarchy_c8(fn, lc, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4mkdh.h b/support/dktools/dk4mkdh.h
new file mode 100644
index 0000000000..cbeb3a7b34
--- /dev/null
+++ b/support/dktools/dk4mkdh.h
@@ -0,0 +1,92 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mkdh.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MKDH_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MKDH_H_INCLUDED 1
+
+
+#line 10 "dk4mkdh.ctr"
+
+/** @file
+ Make directory hierarchy (create all parent directories for a
+ file or directory and the directory itself if required),
+ the file or directory name is specified as dkChar string.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Create directory structure.
+ @param fn File name.
+ @param lc Flag: Last component in fn is directory too.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if fn is too long,
+ - DK4_E_NON_DIR<br>
+ if one of the components in fn is not a directory,
+ - DK4_E_MKDIR_FAILED<br>
+ with errno in idetails if the function fails to create the directory
+ or a parent directory,
+*/
+int
+dk4mkdir_hierarchy(const dkChar *fn, int lc, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4mkdh8.c b/support/dktools/dk4mkdh8.c
new file mode 100644
index 0000000000..a8e1c2a0ae
--- /dev/null
+++ b/support/dktools/dk4mkdh8.c
@@ -0,0 +1,887 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mkdh8.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mkdh8.c The dk4mkdh8 module.
+*/
+
+
+#line 156 "dk4mkdh8.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4mkdh8.h"
+
+#if DK4_HAVE_SYS_STAT_H
+#ifndef SYS_STAT_H_INCLUDED
+#include <sys/stat.h>
+#define SYS_STAT_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_DIRECT_H
+#ifndef DIRECT_H_INCLUDED
+#include <direct.h>
+#define DIRECT_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4MPL_H_INCLUDED
+#include "dk4mpl.h"
+#endif
+
+#ifndef DK4STR8_H_INCLUDED
+#include "dk4str8.h"
+#endif
+
+#ifndef DK4PATH8_H_INCLUDED
+#include "dk4path8.h"
+#endif
+
+#ifndef DK4STAT8_H_INCLUDED
+#include "dk4stat8.h"
+#endif
+
+#ifndef DK4STAT_H_INCLUDED
+#include "dk4stat.h"
+#endif
+
+
+
+
+
+#line 238 "dk4mkdh8.ctr"
+
+
+
+#if DK4_ON_WINDOWS
+/* +++ Windows */
+
+
+
+/** Check whether c is a character.
+ @param c Byte to check.
+ @return 1 for characters, 0 for other bytes.
+*/
+static
+int
+dk4mkdir_hierarchy_c8_is_char(char c)
+{
+ int back = 0;
+ if (('a' <= c) && ('z' >= c)) {
+ back = 1;
+ } else {
+ if (('A' <= c) && ('Z' >= c)) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4mkdir_hierarchy_c8_one(const char *fn, int ro, dk4_er_t *erp)
+{
+ BY_HANDLE_FILE_INFORMATION bhfi;
+ WIN32_FIND_DATAA ffdata;
+ HANDLE ha;
+ DWORD dwattr;
+ int found;
+ int i;
+ int back = 0;
+
+
+#line 278 "dk4mkdh8.ctr"
+ if (NULL == fn) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+#if 1
+ dwattr = GetFileAttributesA(fn);
+ if (INVALID_FILE_ATTRIBUTES == dwattr) {
+ ha = FindFirstFileA(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != ha) {
+ dwattr = ffdata.dwFileAttributes;
+ FindClose(ha);
+ }
+ }
+ if (INVALID_FILE_ATTRIBUTES != dwattr) {
+ if (0 != (FILE_ATTRIBUTE_DIRECTORY & dwattr)) {
+ back = 1;
+ } else {
+ if (0 != (FILE_ATTRIBUTE_REPARSE_POINT & dwattr)) {
+ found = 0;
+ for (i = 0; ((3 > i) && (0 == back) && (0 == found)); i++) {
+ ha = CreateFileA(
+ fn,
+ (
+ (0 == i)
+ ? (0)
+ : ((1 == i) ? (FILE_READ_ATTRIBUTES) : (GENERIC_READ))
+ ),
+ (FILE_SHARE_READ | FILE_SHARE_WRITE),
+ NULL,
+ OPEN_EXISTING,
+ (dwattr | FILE_FLAG_BACKUP_SEMANTICS),
+ NULL
+ );
+ if (INVALID_HANDLE_VALUE != ha) {
+ if (GetFileInformationByHandle(ha, &bhfi)) {
+ found = 1;
+ if (0 != (FILE_ATTRIBUTE_DIRECTORY & (bhfi.dwFileAttributes))) {
+ back = 1;
+ }
+ }
+ CloseHandle(ha);
+ }
+ }
+ }
+ if (0 == back) {
+ dk4error_set_simple_error_code(erp, DK4_E_NON_DIR);
+ }
+ }
+ } else {
+ if (0 != ro) {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ } else {
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ if (CreateDirectoryA(fn, NULL)) {
+ back = 1;
+ } else {
+ dk4error_set_ldetails(
+ erp, DK4_E_CREATE_DIR_FAILED ,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+#else
+ if (CreateDirectoryA(fn, NULL)) {
+ back = 1;
+ } else {
+ errno = 0;
+ if (0 == _mkdir(fn)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_MKDIR_FAILED, errno);
+ }
+ }
+#endif
+ }
+ }
+#else
+ back = 1;
+#endif
+
+
+#line 357 "dk4mkdh8.ctr"
+ finished:
+ return back;
+}
+
+
+
+char *
+dk4mkdir_hierarchy_c8_first_sep(char *fn, int *bptr, int lc, dk4_er_t *erp)
+{
+ char *pc = NULL;
+ int back = 0;
+ char sc;
+
+ if (NULL == fn) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+
+ if ('\\' == *fn) { /* leading bs */
+ if ('\\' == fn[1]) { /* server and share */
+ pc = dk4str8_chr(&(fn[2]), '\\');
+ if (NULL != pc) { /* Share name */
+ pc = dk4str8_chr(&(pc[1]), '\\');
+ if (NULL != pc) { /* First dir */
+ *pc = '\0';
+ back = dk4mkdir_hierarchy_c8_one(fn, 1, erp);
+ *pc = '\\';
+ if (0 != back) {
+ back = 0;
+ pc = dk4str8_chr(&(pc[1]), '\\');
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_c8_one(fn, 0, erp);
+ } else {
+ back = 1;
+ }
+ }
+ } else {
+ pc = dk4str8_chr(&(pc[1]), '\\');
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_c8_one(fn, 0, erp);
+ }
+ }
+ }
+ } else { /* Share name but no dir */
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_c8_one(fn, 1, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else { /* abs path, no drive */
+ pc = dk4str8_chr(&(fn[1]), '\\');
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_c8_one(fn, 0, erp);
+ } else {
+ back = 1;
+ }
+ }
+ }
+ } else { /* no leading bs */
+ if (0 != dk4mkdir_hierarchy_c8_is_char(*fn)) { /* leading char */
+ if (':' == fn[1]) { /* drive */
+ if ('\\' == fn[2]) { /* drive, abs path */
+ sc = fn[3];
+ fn[3] = '\0';
+ back = dk4mkdir_hierarchy_c8_one(fn, 1, erp);
+ fn[3] = sc;
+ if (0 != back) {
+ back = 0;
+ pc = dk4str8_chr(&(fn[3]), '\\');
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_c8_one(fn, 0, erp);
+ } else {
+ back = 1;
+ }
+ }
+ }
+ } else { /* drive, rel path */
+ sc = fn[2];
+ fn[2] = '\0';
+ back = dk4mkdir_hierarchy_c8_one(fn, 1, erp);
+ fn[2] = sc;
+ if (0 != back) {
+ back = 0;
+ pc = dk4str8_chr(&(fn[3]), '\\');
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_c8_one(fn, 0, erp);
+ } else {
+ back = 1;
+ }
+ }
+ }
+ }
+ } else { /* no drive */
+ pc = dk4str8_chr(fn, '\\');
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_c8_one(fn, 0, erp);
+ } else {
+ back = 1;
+ }
+ }
+ }
+ } else { /* no leading char */
+ pc = dk4str8_chr(fn, '\\');
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_c8_one(fn, 0, erp);
+ } else {
+ back = 1;
+ }
+ }
+ }
+ }
+
+ finished:
+ if (NULL != bptr) { *bptr = back; }
+ return pc;
+}
+
+
+
+/* --- Windows */
+#else
+/* +++ non-Windows */
+
+
+
+int
+dk4mkdir_hierarchy_c8_one(const char *fn, int ro, dk4_er_t *erp)
+{
+ dk4_stat_t stb;
+ int back = 0;
+
+
+#line 499 "dk4mkdh8.ctr"
+ if (NULL == fn) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+#if 1
+ if (0 != dk4stat_c8(&stb, fn, NULL)) {
+ back = dk4stat_is_directory(&stb, erp);
+ if (0 == back) {
+ dk4error_set_simple_error_code(erp, DK4_E_NON_DIR);
+ }
+ } else {
+ if (0 != ro) {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ } else {
+ errno = 0;
+ if (0 == mkdir(fn, 0700)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_MKDIR_FAILED, errno);
+ }
+ }
+ }
+#else
+ back = 1;
+#endif
+
+
+#line 525 "dk4mkdh8.ctr"
+ finished:
+ return back;
+}
+
+
+
+char *
+dk4mkdir_hierarchy_c8_first_sep(char *fn, int *bptr, int lc, dk4_er_t *erp)
+{
+ char *pc = NULL;
+ int back = 0;
+
+ if (NULL == fn) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+
+ if ('/' == *fn) {
+ pc = dk4str8_chr(&(fn[1]), '/');
+ } else {
+ pc = dk4str8_chr(fn, '/');
+ }
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_c8_one(fn, 0, erp);
+ } else {
+ back = 1;
+ }
+ }
+
+ finished:
+ if (NULL != bptr) { *bptr = back; }
+ return pc;
+}
+
+
+
+/* --- non-Windows */
+#endif
+
+
+
+/** Create directory structure using an editable copy of the path.
+ @param fn File name.
+ @param lc Flag: Last component in fn is directory too.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if fn is too long,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in size allocation,
+ - DK4_E_NOT_FOUND<br>
+ if a server/share combination is not present on Windows,
+ - DK4_E_NON_DIR<br>
+ if one of the components in fn is not a directory,
+ - DK4_E_MKDIR_FAILED<br>
+ with errno in idetails if the function fails to create the directory
+ or a parent directory,
+ - DK4_E_CREATE_DIR_FAILED<br>
+ with GetLastError() result in lDetails1 if the CreateDirectory()
+ function failed on a Windows system.
+*/
+static
+int
+dk4mkdir_hierarchy_c8_on_copy(char *fn, int lc, dk4_er_t *erp)
+{
+ char *pc;
+ int back = 0;
+
+
+
+#line 599 "dk4mkdh8.ctr"
+
+ /* Correct file name */
+ dk4path8_correct_sep(fn);
+
+ /* Find first real separator */
+ pc = dk4mkdir_hierarchy_c8_first_sep(fn, &back, lc, erp);
+
+ /* Process directories */
+ if (NULL != pc) {
+ back = 1;
+ while (NULL != pc) {
+ *pc = '\0';
+ if (0 < dk4str8_len(fn)) {
+ if (0 == dk4mkdir_hierarchy_c8_one(fn, 0, erp)) {
+ back = 0;
+ }
+ }
+#if DK4_HAVE_BACKSLASH_AS_SEP
+ *pc = '\\';
+ pc = dk4str8_chr(&(pc[1]), '\\');
+#else
+ *pc = '/';
+ pc = dk4str8_chr(&(pc[1]), '/');
+#endif
+ }
+ if (0 != lc) {
+ if (0 == dk4mkdir_hierarchy_c8_one(fn, 0, erp)) {
+ back = 0;
+ }
+ }
+ }
+
+
+#line 631 "dk4mkdh8.ctr"
+ return back;
+}
+
+
+
+/** Create directory structure using a local copy of the path.
+ @param fn File name.
+ @param lc Flag: Last component in fn is directory too.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if fn is too long,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in size allocation,
+ - DK4_E_NOT_FOUND<br>
+ if a server/share combination is not present on Windows,
+ - DK4_E_NON_DIR<br>
+ if one of the components in fn is not a directory,
+ - DK4_E_MKDIR_FAILED<br>
+ with errno in idetails if the function fails to create the directory
+ or a parent directory,
+ - DK4_E_CREATE_DIR_FAILED<br>
+ with GetLastError() result in lDetails1 if the CreateDirectory()
+ function failed on a Windows system.
+*/
+static
+int
+dk4mkdir_hierarchy_c8_local(const char *fn, int lc, dk4_er_t *erp)
+{
+ char mycp[DK4_MAX_PATH];
+ int back = 0;
+
+
+#line 667 "dk4mkdh8.ctr"
+ if (0 != dk4str8_cpy_s(mycp, sizeof(mycp), fn, erp)) {
+ back = dk4mkdir_hierarchy_c8_on_copy(mycp, lc, erp);
+ }
+
+#line 670 "dk4mkdh8.ctr"
+ return back;
+}
+
+
+
+int
+dk4mkdir_hierarchy_c8(const char *fn, int lc, dk4_er_t *erp)
+{
+ char *mycp;
+ size_t sz;
+ int back = 0;
+
+
+#line 682 "dk4mkdh8.ctr"
+ if (NULL != fn) {
+ sz = dk4str8_len(fn);
+ if (DK4_MAX_PATH > sz) {
+ back = dk4mkdir_hierarchy_c8_local(fn, lc, erp);
+ } else {
+ mycp = dk4str8_dup(fn, erp);
+ if (NULL != mycp) {
+ back = dk4mkdir_hierarchy_c8_on_copy(mycp, lc, erp);
+ dk4mem_free(mycp);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 696 "dk4mkdh8.ctr"
+ return back;
+}
+
+
+
+#if DK4_HAVE_UID_T && DK4_HAVE_GID_T && DK4_HAVE_MODE_T && (!DK4_ON_WINDOWS)
+
+
+
+/** Check whether directory exists or attempt to create directory.
+ @param fn File name.
+ @param ro Flag: Read only (test directory presence),
+ do not attempt to create the directory.
+ @param uid User ID for new directories.
+ @param gid Group ID for new directories.
+ @param mode Mode for new directories.
+ @param erp Error report, may be NULL.
+ @return 1 if directory is available now, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_NOT_FOUND<br>
+ if a server/share combination is not present on Windows,
+ - DK4_E_NON_DIR<br>
+ if any component in the path is not a directory,
+ - DK4_E_MKDIR_FAILED<br>
+ with errno value in iDetails1 if the mkdir() function failed on a
+ non-Windows system,
+ - DK4_E_CHOWN_FAILED<br>
+ with errno value in iDetails1 if the chown() function failed on a
+ non-Windows system,
+ - DK4_E_CHMOD_FAILED<br>
+ with errno value in iDetails1 if the chmod() function failed on a
+ non-Windows system,
+ - DK4_E_CREATE_DIR_FAILED<br>
+ with GetLastError() result in lDetails1 if the CreateDirectory()
+ function failed on a Windows system.
+*/
+static
+int
+dk4mkdir_hierarchy_ugm_c8_one(
+ const char *fn,
+ int ro,
+ uid_t uid,
+ gid_t gid,
+ mode_t mode,
+ dk4_er_t *erp
+)
+{
+ dk4_stat_t stb;
+ int back = 0;
+
+
+#line 749 "dk4mkdh8.ctr"
+ if (NULL == fn) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+#if 1
+ if (0 != dk4stat_c8(&stb, fn, NULL)) {
+ back = dk4stat_is_directory(&stb, erp);
+ if (0 == back) {
+ dk4error_set_simple_error_code(erp, DK4_E_NON_DIR);
+ }
+ } else {
+ if (0 != ro) {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ } else {
+ errno = 0;
+ if (0 == mkdir(fn, mode)) {
+ errno = 0;
+ if (0 == chown(fn, uid, gid)) {
+ errno = 0;
+ if (0 == chmod(fn, mode)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_CHMOD_FAILED, errno);
+ }
+ } else {
+ dk4error_set_idetails(erp, DK4_E_CHOWN_FAILED, errno);
+ }
+ } else {
+ dk4error_set_idetails(erp, DK4_E_MKDIR_FAILED, errno);
+ }
+ }
+ }
+#else
+ back = 1;
+#endif
+
+
+#line 785 "dk4mkdh8.ctr"
+ finished:
+ return back;
+}
+
+
+
+/** Create directory structure using an editable copy of the path.
+ @param fn File name.
+ @param lc Flag: Last component in fn is directory too.
+ @param uid User ID for new directories.
+ @param gid Group ID for new directories.
+ @param mode Mode for new directories.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if fn is too long,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in size allocation,
+ - DK4_E_NOT_FOUND<br>
+ if a server/share combination is not present on Windows,
+ - DK4_E_NON_DIR<br>
+ if one of the components in fn is not a directory,
+ - DK4_E_MKDIR_FAILED<br>
+ with errno in idetails if the function fails to create the directory
+ or a parent directory,
+ - DK4_E_CHOWN_FAILED<br>
+ with errno value in iDetails1 if the chown() function failed on a
+ non-Windows system,
+ - DK4_E_CHMOD_FAILED<br>
+ with errno value in iDetails1 if the chmod() function failed on a
+ non-Windows system,
+ - DK4_E_CREATE_DIR_FAILED<br>
+ with GetLastError() result in lDetails1 if the CreateDirectory()
+ function failed on a Windows system.
+*/
+static
+int
+dk4mkdir_hierarchy_ugm_c8_on_copy(
+ char *fn,
+ int lc,
+ uid_t uid,
+ gid_t gid,
+ mode_t mode,
+ dk4_er_t *erp
+)
+{
+ char *pc;
+ int back = 0;
+
+
+
+#line 839 "dk4mkdh8.ctr"
+
+ /* Correct file name */
+ dk4path8_correct_sep(fn);
+
+ /* Find first real separator */
+ pc = dk4mkdir_hierarchy_c8_first_sep(fn, &back, lc, erp);
+
+ /* Process directories */
+ if (NULL != pc) {
+ back = 1;
+ while (NULL != pc) {
+ *pc = '\0';
+ if (0 < dk4str8_len(fn)) {
+ if (0 == dk4mkdir_hierarchy_ugm_c8_one(fn, 0, uid, gid, mode, erp)) {
+ back = 0;
+ }
+ }
+#if DK4_HAVE_BACKSLASH_AS_SEP
+ *pc = '\\';
+ pc = dk4str8_chr(&(pc[1]), '\\');
+#else
+ *pc = '/';
+ pc = dk4str8_chr(&(pc[1]), '/');
+#endif
+ }
+ if (0 != lc) {
+ if (0 == dk4mkdir_hierarchy_ugm_c8_one(fn, 0, uid, gid, mode, erp)) {
+ back = 0;
+ }
+ }
+ }
+
+
+#line 871 "dk4mkdh8.ctr"
+ return back;
+}
+
+
+
+/** Create directory structure using a local copy of the path.
+ @param fn File name.
+ @param lc Flag: Last component in fn is directory too.
+ @param uid User ID for new directories.
+ @param gid Group ID for new directories.
+ @param mode Mode for new directories.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if fn is too long,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in size allocation,
+ - DK4_E_NOT_FOUND<br>
+ if a server/share combination is not present on Windows,
+ - DK4_E_NON_DIR<br>
+ if one of the components in fn is not a directory,
+ - DK4_E_MKDIR_FAILED<br>
+ with errno in idetails if the function fails to create the directory
+ or a parent directory,
+ - DK4_E_CHOWN_FAILED<br>
+ with errno value in iDetails1 if the chown() function failed on a
+ non-Windows system,
+ - DK4_E_CHMOD_FAILED<br>
+ with errno value in iDetails1 if the chmod() function failed on a
+ non-Windows system,
+ - DK4_E_CREATE_DIR_FAILED<br>
+ with GetLastError() result in lDetails1 if the CreateDirectory()
+ function failed on a Windows system.
+*/
+static
+int
+dk4mkdir_hierarchy_ugm_c8_local(
+ const char *fn,
+ int lc,
+ uid_t uid,
+ gid_t gid,
+ mode_t mode,
+ dk4_er_t *erp
+)
+{
+ char mycp[DK4_MAX_PATH];
+ int back = 0;
+
+
+#line 923 "dk4mkdh8.ctr"
+ if (0 != dk4str8_cpy_s(mycp, sizeof(mycp), fn, erp)) {
+ back = dk4mkdir_hierarchy_ugm_c8_on_copy(mycp, lc, uid, gid, mode, erp);
+ }
+
+#line 926 "dk4mkdh8.ctr"
+ return back;
+}
+
+
+
+int
+dk4mkdir_hierarchy_ugm_c8(
+ const char *fn,
+ int lc,
+ uid_t uid,
+ gid_t gid,
+ mode_t mode,
+ dk4_er_t *erp
+)
+{
+ char *mycp;
+ size_t sz;
+ int back = 0;
+
+
+#line 945 "dk4mkdh8.ctr"
+ if (NULL != fn) {
+ sz = dk4str8_len(fn);
+ if (DK4_MAX_PATH > sz) {
+ back = dk4mkdir_hierarchy_ugm_c8_local(fn, lc, uid, gid, mode, erp);
+ } else {
+ mycp = dk4str8_dup(fn, erp);
+ if (NULL != mycp) {
+ back = dk4mkdir_hierarchy_ugm_c8_on_copy(mycp, lc, uid, gid, mode, erp);
+ dk4mem_free(mycp);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 959 "dk4mkdh8.ctr"
+ return back;
+}
+
+
+
+#endif
diff --git a/support/dktools/dk4mkdh8.ctr b/support/dktools/dk4mkdh8.ctr
new file mode 100644
index 0000000000..3dc340e135
--- /dev/null
+++ b/support/dktools/dk4mkdh8.ctr
@@ -0,0 +1,964 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Make directory hierarchy (create all parent directories for a
+ file or directory and the directory itself if required),
+ the file or directory name is specified as char string.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Find position of first separator for real directory.
+
+ This function is not intended for use in application programs,
+ it is exported only for use from the dk4appmkdh module.
+
+ The function either returns a value or sets the back variable
+ to 1 or reports an error.
+ @param fn File name.
+ @param bptr Pointer to the back variable.
+ @param lc Flag: Last component in fn is directory too.
+ @param erp Error report, may be NULL.
+ @return First separator after a real directory on success if
+ found, NULL otherwise.
+*/
+char *
+dk4mkdir_hierarchy_c8_first_sep(char *fn, int *bptr, int lc, dk4_er_t *erp);
+
+/** Check whether directory exists or attempt to create directory.
+ @param fn File name.
+ @param ro Flag: Read only (test directory presence),
+ do not attempt to create the directory.
+ @param erp Error report, may be NULL.
+ @return 1 if directory is available now, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_NOT_FOUND<br>
+ if a server/share combination is not present on Windows,
+ - DK4_E_NON_DIR<br>
+ if any component in the path is not a directory,
+ - DK4_E_MKDIR_FAILED<br>
+ with errno value in iDetails1 if the mkdir() function failed on a
+ non-Windows system.
+ - DK4_E_CREATE_DIR_FAILED<br>
+ with GetLastError() result in lDetails1 if the CreateDirectory()
+ function failed on a Windows system.
+*/
+int
+dk4mkdir_hierarchy_c8_one(const char *fn, int ro, dk4_er_t *erp);
+
+/** Create directory structure.
+ @param fn File name.
+ @param lc Flag: Last component in fn is directory too.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if fn is too long,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in size allocation,
+ - DK4_E_NOT_FOUND<br>
+ if a server/share combination is not present on Windows,
+ - DK4_E_NON_DIR<br>
+ if one of the components in fn is not a directory,
+ - DK4_E_MKDIR_FAILED<br>
+ with errno in idetails if the function fails to create the directory
+ or a parent directory,
+ - DK4_E_CREATE_DIR_FAILED<br>
+ with GetLastError() result in lDetails1 if the CreateDirectory()
+ function failed on a Windows system.
+*/
+int
+dk4mkdir_hierarchy_c8(const char *fn, int lc, dk4_er_t *erp);
+
+
+#if DK4_HAVE_UID_T && DK4_HAVE_GID_T && DK4_HAVE_MODE_T && (!DK4_ON_WINDOWS)
+
+/** Create directory structure for a given POSIX user and group.
+ @param fn File name.
+ @param lc Flag: Last component in fn is directory too.
+ @param uid User ID for new directories.
+ @param gid Group ID for new directories.
+ @param mode Permissions to new directories.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if fn is too long,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in size allocation,
+ - DK4_E_NOT_FOUND<br>
+ if a server/share combination is not present on Windows,
+ - DK4_E_NON_DIR<br>
+ if one of the components in fn is not a directory,
+ - DK4_E_MKDIR_FAILED<br>
+ with errno in idetails if the function fails to create the directory
+ or a parent directory,
+ - DK4_E_CHOWN_FAILED<br>
+ with errno value in iDetails1 if the chown() function failed on a
+ non-Windows system,
+ - DK4_E_CHMOD_FAILED<br>
+ with errno value in iDetails1 if the chmod() function failed on a
+ non-Windows system,
+ - DK4_E_CREATE_DIR_FAILED<br>
+ with GetLastError() result in lDetails1 if the CreateDirectory()
+ function failed on a Windows system.
+*/
+int
+dk4mkdir_hierarchy_ugm_c8(
+ const char *fn,
+ int lc,
+ uid_t uid,
+ gid_t gid,
+ mode_t mode,
+ dk4_er_t *erp
+);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4mkdh8.h"
+
+#if DK4_HAVE_SYS_STAT_H
+#ifndef SYS_STAT_H_INCLUDED
+#include <sys/stat.h>
+#define SYS_STAT_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_DIRECT_H
+#ifndef DIRECT_H_INCLUDED
+#include <direct.h>
+#define DIRECT_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4MPL_H_INCLUDED
+#include "dk4mpl.h"
+#endif
+
+#ifndef DK4STR8_H_INCLUDED
+#include "dk4str8.h"
+#endif
+
+#ifndef DK4PATH8_H_INCLUDED
+#include "dk4path8.h"
+#endif
+
+#ifndef DK4STAT8_H_INCLUDED
+#include "dk4stat8.h"
+#endif
+
+#ifndef DK4STAT_H_INCLUDED
+#include "dk4stat.h"
+#endif
+
+
+
+$!trace-include
+
+
+
+#if DK4_ON_WINDOWS
+/* +++ Windows */
+
+
+
+/** Check whether c is a character.
+ @param c Byte to check.
+ @return 1 for characters, 0 for other bytes.
+*/
+static
+int
+dk4mkdir_hierarchy_c8_is_char(char c)
+{
+ int back = 0;
+ if (('a' <= c) && ('z' >= c)) {
+ back = 1;
+ } else {
+ if (('A' <= c) && ('Z' >= c)) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4mkdir_hierarchy_c8_one(const char *fn, int ro, dk4_er_t *erp)
+{
+ BY_HANDLE_FILE_INFORMATION bhfi;
+ WIN32_FIND_DATAA ffdata;
+ HANDLE ha;
+ DWORD dwattr;
+ int found;
+ int i;
+ int back = 0;
+ $? "+ dk4mkdir_hierarchy_c8_one \"%!8s\"", fn
+ if (NULL == fn) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+#if 1
+ dwattr = GetFileAttributesA(fn);
+ if (INVALID_FILE_ATTRIBUTES == dwattr) {
+ ha = FindFirstFileA(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != ha) {
+ dwattr = ffdata.dwFileAttributes;
+ FindClose(ha);
+ }
+ }
+ if (INVALID_FILE_ATTRIBUTES != dwattr) {
+ if (0 != (FILE_ATTRIBUTE_DIRECTORY & dwattr)) {
+ back = 1;
+ } else {
+ if (0 != (FILE_ATTRIBUTE_REPARSE_POINT & dwattr)) {
+ found = 0;
+ for (i = 0; ((3 > i) && (0 == back) && (0 == found)); i++) {
+ ha = CreateFileA(
+ fn,
+ (
+ (0 == i)
+ ? (0)
+ : ((1 == i) ? (FILE_READ_ATTRIBUTES) : (GENERIC_READ))
+ ),
+ (FILE_SHARE_READ | FILE_SHARE_WRITE),
+ NULL,
+ OPEN_EXISTING,
+ (dwattr | FILE_FLAG_BACKUP_SEMANTICS),
+ NULL
+ );
+ if (INVALID_HANDLE_VALUE != ha) {
+ if (GetFileInformationByHandle(ha, &bhfi)) {
+ found = 1;
+ if (0 != (FILE_ATTRIBUTE_DIRECTORY & (bhfi.dwFileAttributes))) {
+ back = 1;
+ }
+ }
+ CloseHandle(ha);
+ }
+ }
+ }
+ if (0 == back) {
+ dk4error_set_simple_error_code(erp, DK4_E_NON_DIR);
+ }
+ }
+ } else {
+ if (0 != ro) {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ } else {
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ if (CreateDirectoryA(fn, NULL)) {
+ back = 1;
+ } else {
+ dk4error_set_ldetails(
+ erp, DK4_E_CREATE_DIR_FAILED ,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+#else
+ if (CreateDirectoryA(fn, NULL)) {
+ back = 1;
+ } else {
+ errno = 0;
+ if (0 == _mkdir(fn)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_MKDIR_FAILED, errno);
+ }
+ }
+#endif
+ }
+ }
+#else
+ back = 1;
+#endif
+ $? "- dk4mkdir_hierarchy_c8_one %d", back
+ finished:
+ return back;
+}
+
+
+
+char *
+dk4mkdir_hierarchy_c8_first_sep(char *fn, int *bptr, int lc, dk4_er_t *erp)
+{
+ char *pc = NULL;
+ int back = 0;
+ char sc;
+
+ if (NULL == fn) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+
+ if ('\\' == *fn) { /* leading bs */
+ if ('\\' == fn[1]) { /* server and share */
+ pc = dk4str8_chr(&(fn[2]), '\\');
+ if (NULL != pc) { /* Share name */
+ pc = dk4str8_chr(&(pc[1]), '\\');
+ if (NULL != pc) { /* First dir */
+ *pc = '\0';
+ back = dk4mkdir_hierarchy_c8_one(fn, 1, erp);
+ *pc = '\\';
+ if (0 != back) {
+ back = 0;
+ pc = dk4str8_chr(&(pc[1]), '\\');
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_c8_one(fn, 0, erp);
+ } else {
+ back = 1;
+ }
+ }
+ } else {
+ pc = dk4str8_chr(&(pc[1]), '\\');
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_c8_one(fn, 0, erp);
+ }
+ }
+ }
+ } else { /* Share name but no dir */
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_c8_one(fn, 1, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else { /* abs path, no drive */
+ pc = dk4str8_chr(&(fn[1]), '\\');
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_c8_one(fn, 0, erp);
+ } else {
+ back = 1;
+ }
+ }
+ }
+ } else { /* no leading bs */
+ if (0 != dk4mkdir_hierarchy_c8_is_char(*fn)) { /* leading char */
+ if (':' == fn[1]) { /* drive */
+ if ('\\' == fn[2]) { /* drive, abs path */
+ sc = fn[3];
+ fn[3] = '\0';
+ back = dk4mkdir_hierarchy_c8_one(fn, 1, erp);
+ fn[3] = sc;
+ if (0 != back) {
+ back = 0;
+ pc = dk4str8_chr(&(fn[3]), '\\');
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_c8_one(fn, 0, erp);
+ } else {
+ back = 1;
+ }
+ }
+ }
+ } else { /* drive, rel path */
+ sc = fn[2];
+ fn[2] = '\0';
+ back = dk4mkdir_hierarchy_c8_one(fn, 1, erp);
+ fn[2] = sc;
+ if (0 != back) {
+ back = 0;
+ pc = dk4str8_chr(&(fn[3]), '\\');
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_c8_one(fn, 0, erp);
+ } else {
+ back = 1;
+ }
+ }
+ }
+ }
+ } else { /* no drive */
+ pc = dk4str8_chr(fn, '\\');
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_c8_one(fn, 0, erp);
+ } else {
+ back = 1;
+ }
+ }
+ }
+ } else { /* no leading char */
+ pc = dk4str8_chr(fn, '\\');
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_c8_one(fn, 0, erp);
+ } else {
+ back = 1;
+ }
+ }
+ }
+ }
+
+ finished:
+ if (NULL != bptr) { *bptr = back; }
+ return pc;
+}
+
+
+
+/* --- Windows */
+#else
+/* +++ non-Windows */
+
+
+
+int
+dk4mkdir_hierarchy_c8_one(const char *fn, int ro, dk4_er_t *erp)
+{
+ dk4_stat_t stb;
+ int back = 0;
+ $? "+ dk4mkdir_hierarchy_c8_one \"%!8s\"", fn
+ if (NULL == fn) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+#if 1
+ if (0 != dk4stat_c8(&stb, fn, NULL)) {
+ back = dk4stat_is_directory(&stb, erp);
+ if (0 == back) {
+ dk4error_set_simple_error_code(erp, DK4_E_NON_DIR);
+ }
+ } else {
+ if (0 != ro) {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ } else {
+ errno = 0;
+ if (0 == mkdir(fn, 0700)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_MKDIR_FAILED, errno);
+ }
+ }
+ }
+#else
+ back = 1;
+#endif
+ $? "- dk4mkdir_hierarchy_c8_one %d", back
+ finished:
+ return back;
+}
+
+
+
+char *
+dk4mkdir_hierarchy_c8_first_sep(char *fn, int *bptr, int lc, dk4_er_t *erp)
+{
+ char *pc = NULL;
+ int back = 0;
+
+ if (NULL == fn) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+
+ if ('/' == *fn) {
+ pc = dk4str8_chr(&(fn[1]), '/');
+ } else {
+ pc = dk4str8_chr(fn, '/');
+ }
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_c8_one(fn, 0, erp);
+ } else {
+ back = 1;
+ }
+ }
+
+ finished:
+ if (NULL != bptr) { *bptr = back; }
+ return pc;
+}
+
+
+
+/* --- non-Windows */
+#endif
+
+
+
+/** Create directory structure using an editable copy of the path.
+ @param fn File name.
+ @param lc Flag: Last component in fn is directory too.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if fn is too long,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in size allocation,
+ - DK4_E_NOT_FOUND<br>
+ if a server/share combination is not present on Windows,
+ - DK4_E_NON_DIR<br>
+ if one of the components in fn is not a directory,
+ - DK4_E_MKDIR_FAILED<br>
+ with errno in idetails if the function fails to create the directory
+ or a parent directory,
+ - DK4_E_CREATE_DIR_FAILED<br>
+ with GetLastError() result in lDetails1 if the CreateDirectory()
+ function failed on a Windows system.
+*/
+static
+int
+dk4mkdir_hierarchy_c8_on_copy(char *fn, int lc, dk4_er_t *erp)
+{
+ char *pc;
+ int back = 0;
+
+ $? "+ dk4mkdir_hierarchy_c8_on_copy \"%!8s\"", fn
+
+ /* Correct file name */
+ dk4path8_correct_sep(fn);
+
+ /* Find first real separator */
+ pc = dk4mkdir_hierarchy_c8_first_sep(fn, &back, lc, erp);
+
+ /* Process directories */
+ if (NULL != pc) {
+ back = 1;
+ while (NULL != pc) {
+ *pc = '\0';
+ if (0 < dk4str8_len(fn)) {
+ if (0 == dk4mkdir_hierarchy_c8_one(fn, 0, erp)) {
+ back = 0;
+ }
+ }
+#if DK4_HAVE_BACKSLASH_AS_SEP
+ *pc = '\\';
+ pc = dk4str8_chr(&(pc[1]), '\\');
+#else
+ *pc = '/';
+ pc = dk4str8_chr(&(pc[1]), '/');
+#endif
+ }
+ if (0 != lc) {
+ if (0 == dk4mkdir_hierarchy_c8_one(fn, 0, erp)) {
+ back = 0;
+ }
+ }
+ }
+ $? "- dk4mkdir_hierarchy_c8_on_copy %d", back
+ return back;
+}
+
+
+
+/** Create directory structure using a local copy of the path.
+ @param fn File name.
+ @param lc Flag: Last component in fn is directory too.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if fn is too long,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in size allocation,
+ - DK4_E_NOT_FOUND<br>
+ if a server/share combination is not present on Windows,
+ - DK4_E_NON_DIR<br>
+ if one of the components in fn is not a directory,
+ - DK4_E_MKDIR_FAILED<br>
+ with errno in idetails if the function fails to create the directory
+ or a parent directory,
+ - DK4_E_CREATE_DIR_FAILED<br>
+ with GetLastError() result in lDetails1 if the CreateDirectory()
+ function failed on a Windows system.
+*/
+static
+int
+dk4mkdir_hierarchy_c8_local(const char *fn, int lc, dk4_er_t *erp)
+{
+ char mycp[DK4_MAX_PATH];
+ int back = 0;
+ $? "+ dk4mkdir_hierarchy_c8_local \"%!8s\"", fn
+ if (0 != dk4str8_cpy_s(mycp, sizeof(mycp), fn, erp)) {
+ back = dk4mkdir_hierarchy_c8_on_copy(mycp, lc, erp);
+ } $? "- dk4mkdir_hierarchy_c8_local %d", back
+ return back;
+}
+
+
+
+int
+dk4mkdir_hierarchy_c8(const char *fn, int lc, dk4_er_t *erp)
+{
+ char *mycp;
+ size_t sz;
+ int back = 0;
+ $? "+ dk4mkdir_hierarchy_c8 \"%!8s\"", TR_8STR(fn)
+ if (NULL != fn) {
+ sz = dk4str8_len(fn);
+ if (DK4_MAX_PATH > sz) {
+ back = dk4mkdir_hierarchy_c8_local(fn, lc, erp);
+ } else {
+ mycp = dk4str8_dup(fn, erp);
+ if (NULL != mycp) {
+ back = dk4mkdir_hierarchy_c8_on_copy(mycp, lc, erp);
+ dk4mem_free(mycp);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4mkdir_hierarchy_c8 %d", back
+ return back;
+}
+
+
+
+#if DK4_HAVE_UID_T && DK4_HAVE_GID_T && DK4_HAVE_MODE_T && (!DK4_ON_WINDOWS)
+
+
+
+/** Check whether directory exists or attempt to create directory.
+ @param fn File name.
+ @param ro Flag: Read only (test directory presence),
+ do not attempt to create the directory.
+ @param uid User ID for new directories.
+ @param gid Group ID for new directories.
+ @param mode Mode for new directories.
+ @param erp Error report, may be NULL.
+ @return 1 if directory is available now, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_NOT_FOUND<br>
+ if a server/share combination is not present on Windows,
+ - DK4_E_NON_DIR<br>
+ if any component in the path is not a directory,
+ - DK4_E_MKDIR_FAILED<br>
+ with errno value in iDetails1 if the mkdir() function failed on a
+ non-Windows system,
+ - DK4_E_CHOWN_FAILED<br>
+ with errno value in iDetails1 if the chown() function failed on a
+ non-Windows system,
+ - DK4_E_CHMOD_FAILED<br>
+ with errno value in iDetails1 if the chmod() function failed on a
+ non-Windows system,
+ - DK4_E_CREATE_DIR_FAILED<br>
+ with GetLastError() result in lDetails1 if the CreateDirectory()
+ function failed on a Windows system.
+*/
+static
+int
+dk4mkdir_hierarchy_ugm_c8_one(
+ const char *fn,
+ int ro,
+ uid_t uid,
+ gid_t gid,
+ mode_t mode,
+ dk4_er_t *erp
+)
+{
+ dk4_stat_t stb;
+ int back = 0;
+ $? "+ dk4mkdir_hierarchy_c8_one \"%!8s\"", fn
+ if (NULL == fn) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+#if 1
+ if (0 != dk4stat_c8(&stb, fn, NULL)) {
+ back = dk4stat_is_directory(&stb, erp);
+ if (0 == back) {
+ dk4error_set_simple_error_code(erp, DK4_E_NON_DIR);
+ }
+ } else {
+ if (0 != ro) {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ } else {
+ errno = 0;
+ if (0 == mkdir(fn, mode)) {
+ errno = 0;
+ if (0 == chown(fn, uid, gid)) {
+ errno = 0;
+ if (0 == chmod(fn, mode)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_CHMOD_FAILED, errno);
+ }
+ } else {
+ dk4error_set_idetails(erp, DK4_E_CHOWN_FAILED, errno);
+ }
+ } else {
+ dk4error_set_idetails(erp, DK4_E_MKDIR_FAILED, errno);
+ }
+ }
+ }
+#else
+ back = 1;
+#endif
+ $? "- dk4mkdir_hierarchy_c8_one %d", back
+ finished:
+ return back;
+}
+
+
+
+/** Create directory structure using an editable copy of the path.
+ @param fn File name.
+ @param lc Flag: Last component in fn is directory too.
+ @param uid User ID for new directories.
+ @param gid Group ID for new directories.
+ @param mode Mode for new directories.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if fn is too long,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in size allocation,
+ - DK4_E_NOT_FOUND<br>
+ if a server/share combination is not present on Windows,
+ - DK4_E_NON_DIR<br>
+ if one of the components in fn is not a directory,
+ - DK4_E_MKDIR_FAILED<br>
+ with errno in idetails if the function fails to create the directory
+ or a parent directory,
+ - DK4_E_CHOWN_FAILED<br>
+ with errno value in iDetails1 if the chown() function failed on a
+ non-Windows system,
+ - DK4_E_CHMOD_FAILED<br>
+ with errno value in iDetails1 if the chmod() function failed on a
+ non-Windows system,
+ - DK4_E_CREATE_DIR_FAILED<br>
+ with GetLastError() result in lDetails1 if the CreateDirectory()
+ function failed on a Windows system.
+*/
+static
+int
+dk4mkdir_hierarchy_ugm_c8_on_copy(
+ char *fn,
+ int lc,
+ uid_t uid,
+ gid_t gid,
+ mode_t mode,
+ dk4_er_t *erp
+)
+{
+ char *pc;
+ int back = 0;
+
+ $? "+ dk4mkdir_hierarchy_c8_on_copy \"%!8s\"", fn
+
+ /* Correct file name */
+ dk4path8_correct_sep(fn);
+
+ /* Find first real separator */
+ pc = dk4mkdir_hierarchy_c8_first_sep(fn, &back, lc, erp);
+
+ /* Process directories */
+ if (NULL != pc) {
+ back = 1;
+ while (NULL != pc) {
+ *pc = '\0';
+ if (0 < dk4str8_len(fn)) {
+ if (0 == dk4mkdir_hierarchy_ugm_c8_one(fn, 0, uid, gid, mode, erp)) {
+ back = 0;
+ }
+ }
+#if DK4_HAVE_BACKSLASH_AS_SEP
+ *pc = '\\';
+ pc = dk4str8_chr(&(pc[1]), '\\');
+#else
+ *pc = '/';
+ pc = dk4str8_chr(&(pc[1]), '/');
+#endif
+ }
+ if (0 != lc) {
+ if (0 == dk4mkdir_hierarchy_ugm_c8_one(fn, 0, uid, gid, mode, erp)) {
+ back = 0;
+ }
+ }
+ }
+ $? "- dk4mkdir_hierarchy_c8_on_copy %d", back
+ return back;
+}
+
+
+
+/** Create directory structure using a local copy of the path.
+ @param fn File name.
+ @param lc Flag: Last component in fn is directory too.
+ @param uid User ID for new directories.
+ @param gid Group ID for new directories.
+ @param mode Mode for new directories.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if fn is too long,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in size allocation,
+ - DK4_E_NOT_FOUND<br>
+ if a server/share combination is not present on Windows,
+ - DK4_E_NON_DIR<br>
+ if one of the components in fn is not a directory,
+ - DK4_E_MKDIR_FAILED<br>
+ with errno in idetails if the function fails to create the directory
+ or a parent directory,
+ - DK4_E_CHOWN_FAILED<br>
+ with errno value in iDetails1 if the chown() function failed on a
+ non-Windows system,
+ - DK4_E_CHMOD_FAILED<br>
+ with errno value in iDetails1 if the chmod() function failed on a
+ non-Windows system,
+ - DK4_E_CREATE_DIR_FAILED<br>
+ with GetLastError() result in lDetails1 if the CreateDirectory()
+ function failed on a Windows system.
+*/
+static
+int
+dk4mkdir_hierarchy_ugm_c8_local(
+ const char *fn,
+ int lc,
+ uid_t uid,
+ gid_t gid,
+ mode_t mode,
+ dk4_er_t *erp
+)
+{
+ char mycp[DK4_MAX_PATH];
+ int back = 0;
+ $? "+ dk4mkdir_hierarchy_c8_local \"%!8s\"", fn
+ if (0 != dk4str8_cpy_s(mycp, sizeof(mycp), fn, erp)) {
+ back = dk4mkdir_hierarchy_ugm_c8_on_copy(mycp, lc, uid, gid, mode, erp);
+ } $? "- dk4mkdir_hierarchy_c8_local %d", back
+ return back;
+}
+
+
+
+int
+dk4mkdir_hierarchy_ugm_c8(
+ const char *fn,
+ int lc,
+ uid_t uid,
+ gid_t gid,
+ mode_t mode,
+ dk4_er_t *erp
+)
+{
+ char *mycp;
+ size_t sz;
+ int back = 0;
+ $? "+ dk4mkdir_hierarchy_c8 \"%!8s\"", TR_8STR(fn)
+ if (NULL != fn) {
+ sz = dk4str8_len(fn);
+ if (DK4_MAX_PATH > sz) {
+ back = dk4mkdir_hierarchy_ugm_c8_local(fn, lc, uid, gid, mode, erp);
+ } else {
+ mycp = dk4str8_dup(fn, erp);
+ if (NULL != mycp) {
+ back = dk4mkdir_hierarchy_ugm_c8_on_copy(mycp, lc, uid, gid, mode, erp);
+ dk4mem_free(mycp);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4mkdir_hierarchy_c8 %d", back
+ return back;
+}
+
+
+
+#endif
diff --git a/support/dktools/dk4mkdh8.h b/support/dktools/dk4mkdh8.h
new file mode 100644
index 0000000000..4e9635a15d
--- /dev/null
+++ b/support/dktools/dk4mkdh8.h
@@ -0,0 +1,188 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mkdh8.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MKDH8_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MKDH8_H_INCLUDED 1
+
+
+#line 10 "dk4mkdh8.ctr"
+
+/** @file
+ Make directory hierarchy (create all parent directories for a
+ file or directory and the directory itself if required),
+ the file or directory name is specified as char string.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Find position of first separator for real directory.
+
+ This function is not intended for use in application programs,
+ it is exported only for use from the dk4appmkdh module.
+
+ The function either returns a value or sets the back variable
+ to 1 or reports an error.
+ @param fn File name.
+ @param bptr Pointer to the back variable.
+ @param lc Flag: Last component in fn is directory too.
+ @param erp Error report, may be NULL.
+ @return First separator after a real directory on success if
+ found, NULL otherwise.
+*/
+char *
+dk4mkdir_hierarchy_c8_first_sep(char *fn, int *bptr, int lc, dk4_er_t *erp);
+
+/** Check whether directory exists or attempt to create directory.
+ @param fn File name.
+ @param ro Flag: Read only (test directory presence),
+ do not attempt to create the directory.
+ @param erp Error report, may be NULL.
+ @return 1 if directory is available now, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_NOT_FOUND<br>
+ if a server/share combination is not present on Windows,
+ - DK4_E_NON_DIR<br>
+ if any component in the path is not a directory,
+ - DK4_E_MKDIR_FAILED<br>
+ with errno value in iDetails1 if the mkdir() function failed on a
+ non-Windows system.
+ - DK4_E_CREATE_DIR_FAILED<br>
+ with GetLastError() result in lDetails1 if the CreateDirectory()
+ function failed on a Windows system.
+*/
+int
+dk4mkdir_hierarchy_c8_one(const char *fn, int ro, dk4_er_t *erp);
+
+/** Create directory structure.
+ @param fn File name.
+ @param lc Flag: Last component in fn is directory too.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if fn is too long,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in size allocation,
+ - DK4_E_NOT_FOUND<br>
+ if a server/share combination is not present on Windows,
+ - DK4_E_NON_DIR<br>
+ if one of the components in fn is not a directory,
+ - DK4_E_MKDIR_FAILED<br>
+ with errno in idetails if the function fails to create the directory
+ or a parent directory,
+ - DK4_E_CREATE_DIR_FAILED<br>
+ with GetLastError() result in lDetails1 if the CreateDirectory()
+ function failed on a Windows system.
+*/
+int
+dk4mkdir_hierarchy_c8(const char *fn, int lc, dk4_er_t *erp);
+
+
+#if DK4_HAVE_UID_T && DK4_HAVE_GID_T && DK4_HAVE_MODE_T && (!DK4_ON_WINDOWS)
+
+/** Create directory structure for a given POSIX user and group.
+ @param fn File name.
+ @param lc Flag: Last component in fn is directory too.
+ @param uid User ID for new directories.
+ @param gid Group ID for new directories.
+ @param mode Permissions to new directories.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if fn is too long,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in size allocation,
+ - DK4_E_NOT_FOUND<br>
+ if a server/share combination is not present on Windows,
+ - DK4_E_NON_DIR<br>
+ if one of the components in fn is not a directory,
+ - DK4_E_MKDIR_FAILED<br>
+ with errno in idetails if the function fails to create the directory
+ or a parent directory,
+ - DK4_E_CHOWN_FAILED<br>
+ with errno value in iDetails1 if the chown() function failed on a
+ non-Windows system,
+ - DK4_E_CHMOD_FAILED<br>
+ with errno value in iDetails1 if the chmod() function failed on a
+ non-Windows system,
+ - DK4_E_CREATE_DIR_FAILED<br>
+ with GetLastError() result in lDetails1 if the CreateDirectory()
+ function failed on a Windows system.
+*/
+int
+dk4mkdir_hierarchy_ugm_c8(
+ const char *fn,
+ int lc,
+ uid_t uid,
+ gid_t gid,
+ mode_t mode,
+ dk4_er_t *erp
+);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4mkdhw.c b/support/dktools/dk4mkdhw.c
new file mode 100644
index 0000000000..28f1d3bdbe
--- /dev/null
+++ b/support/dktools/dk4mkdhw.c
@@ -0,0 +1,602 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mkdhw.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mkdhw.c The dk4mkdhw module.
+*/
+
+
+#line 112 "dk4mkdhw.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4mkdh8.h"
+
+#if DK4_HAVE_SYS_STAT_H
+#ifndef SYS_STAT_H_INCLUDED
+#include <sys/stat.h>
+#define SYS_STAT_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_DIRECT_H
+#ifndef DIRECT_H_INCLUDED
+#include <direct.h>
+#define DIRECT_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4MPL_H_INCLUDED
+#include "dk4mpl.h"
+#endif
+
+#ifndef DK4STRW_H_INCLUDED
+#include "dk4strw.h"
+#endif
+
+#ifndef DK4PATHW_H_INCLUDED
+#include "dk4pathw.h"
+#endif
+
+#ifndef DK4STATW_H_INCLUDED
+#include "dk4statw.h"
+#endif
+
+#ifndef DK4STAT_H_INCLUDED
+#include "dk4stat.h"
+#endif
+
+
+
+
+
+#line 194 "dk4mkdhw.ctr"
+
+
+
+#if DK4_ON_WINDOWS
+static
+int
+dk4mkdir_hierarchy_wc_is_char(wchar_t c)
+{
+ int back = 0;
+ if ((L'a' <= c) && (L'z' >= c)) {
+ back = 1;
+ } else {
+ if ((L'A' <= c) && (L'Z' >= c)) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4mkdir_hierarchy_wc_one(const wchar_t *fn, int ro, dk4_er_t *erp)
+{
+ BY_HANDLE_FILE_INFORMATION bhfi;
+ WIN32_FIND_DATAW ffdata;
+ HANDLE ha;
+ DWORD dwattr;
+ int found;
+ int i;
+ int back = 0;
+
+
+#line 226 "dk4mkdhw.ctr"
+ if (NULL == fn) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+#if 1
+ dwattr = GetFileAttributesW(fn);
+ if (INVALID_FILE_ATTRIBUTES == dwattr) {
+ ha = FindFirstFileW(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != ha) {
+ dwattr = ffdata.dwFileAttributes;
+ FindClose(ha);
+ }
+ }
+ if (INVALID_FILE_ATTRIBUTES != dwattr) {
+
+#line 240 "dk4mkdhw.ctr"
+ if (0 != (FILE_ATTRIBUTE_DIRECTORY & dwattr)) {
+
+#line 241 "dk4mkdhw.ctr"
+ back = 1;
+ } else {
+
+#line 243 "dk4mkdhw.ctr"
+ if (0 != (FILE_ATTRIBUTE_REPARSE_POINT & dwattr)) {
+ found = 0;
+ for (i = 0; ((3 > i) && (0 == back) && (0 == found)); i++) {
+ ha = CreateFileW(
+ fn,
+ (
+ (0 == i)
+ ? (0)
+ : ((1 == i) ? (FILE_READ_ATTRIBUTES) : (GENERIC_READ))
+ ),
+ (FILE_SHARE_READ | FILE_SHARE_WRITE),
+ NULL,
+ OPEN_EXISTING,
+ (dwattr | FILE_FLAG_BACKUP_SEMANTICS),
+ NULL
+ );
+ if (INVALID_HANDLE_VALUE != ha) {
+ if (GetFileInformationByHandle(ha, &bhfi)) {
+ found = 1;
+ if (0 != (FILE_ATTRIBUTE_DIRECTORY & (bhfi.dwFileAttributes))) {
+ back = 1;
+ }
+ }
+ CloseHandle(ha);
+ }
+ }
+ }
+ if (0 == back) {
+ dk4error_set_simple_error_code(erp, DK4_E_NON_DIR);
+ }
+ }
+ } else {
+
+#line 275 "dk4mkdhw.ctr"
+ if (0 != ro) {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ } else {
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ if (CreateDirectoryW(fn, NULL)) {
+
+#line 280 "dk4mkdhw.ctr"
+ back = 1;
+ } else {
+
+#line 282 "dk4mkdhw.ctr"
+ dk4error_set_ldetails(
+ erp, DK4_E_CREATE_DIR_FAILED ,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+#else
+ if (CreateDirectoryW(fn, NULL)) {
+
+#line 289 "dk4mkdhw.ctr"
+ back = 1;
+ } else {
+
+#line 291 "dk4mkdhw.ctr"
+ errno = 0;
+ if (0 == _wmkdir(fn)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_MKDIR_FAILED, errno);
+ }
+ }
+#endif
+ }
+ }
+#else
+ back = 1;
+#endif
+ finished:
+
+
+#line 306 "dk4mkdhw.ctr"
+ return back;
+}
+
+
+
+wchar_t *
+dk4mkdir_hierarchy_wc_first_sep(wchar_t *fn, int *bptr, int lc, dk4_er_t *erp)
+{
+ wchar_t *pc = NULL;
+ wchar_t sc;
+ int back = 0;
+ int isunc = 0;
+
+ if (NULL == fn) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if (L'\\' == fn[0]) { /* One backslash at start */
+ if (L'\\' == fn[1]) { /* Two backslashes */
+ if (L'?' == fn[2]) { /* Probably extended long path */
+ if (L'\\' == fn[3]) { /* Extended path */
+ if (dk4mkdir_hierarchy_wc_is_char(fn[4])) {
+ if (L':' == fn[5]) { /* Extended, drive */
+ if (L'\\' == fn[6]) { /* Extended, drive abs */
+ sc = fn[7];
+ fn[7] = L'\0';
+ back = dk4mkdir_hierarchy_wc_one(fn, 1, erp);
+ fn[7] = sc;
+ if (0 != back) {
+ pc = dk4strw_chr(&(fn[7]), L'\\');
+ if (NULL == pc) {
+ back = dk4mkdir_hierarchy_wc_one(fn, 0, erp);
+ } else {
+ back = 1;
+ }
+ } else {
+ pc = NULL;
+ }
+ } else { /* Extended, drive rel */
+#if 0
+ pc = dk4strw_chr(&(fn[7]), L'\\');
+ if (NULL == pc) { back = 1; }
+#endif
+ /* 2015-02-05 For extended paths we can use
+ full absolute path names only!
+ */
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else { /* Extended, server and share */
+ if ((L'U' == fn[4]) || (L'u' == fn[4])) {
+ if ((L'N' == fn[5]) || (L'n' == fn[5])) {
+ if ((L'C' == fn[6]) || (L'c' == fn[6])) {
+ if (L'\\' == fn[7]) {
+ isunc = 1;
+ }
+ }
+ }
+ }
+ if (0 != isunc) { /* UNC path */
+ pc = dk4strw_chr(&(fn[8]), L'\\');
+ if (NULL != pc) { /* Share */
+ pc = dk4strw_chr(&(pc[1]), L'\\');
+ if (NULL != pc) { /* First real directory */
+ *pc = L'\0';
+ back = dk4mkdir_hierarchy_wc_one(fn, 1, erp);
+ *pc = L'\\';
+ if (0 != back) {
+ back = 0;
+ pc = dk4strw_chr(&(pc[1]), L'\\');
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_wc_one(fn, 0, erp);
+ } else {
+ back = 1;
+ }
+ }
+ } else {
+ pc = dk4strw_chr(&(pc[1]), L'\\');
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_wc_one(fn, 0, erp);
+ }
+ }
+ }
+ } else { /* No real directory after share */
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_wc_one(fn, 1, erp);
+ } else {
+ dk4error_set_simple_error_code(
+ erp, DK4_E_INVALID_ARGUMENTS
+ );
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else { /* Not UNC, normal path */
+ pc = dk4strw_chr(&(fn[4]), L'\\');
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_wc_one(fn, 0, erp);
+ } else {
+ back = 1;
+ }
+ }
+ }
+ }
+ } else { /* Some unknown extended path */
+ pc = dk4strw_chr(&(fn[4]), L'\\');
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_wc_one(fn, 0, erp);
+ } else {
+ back = 1;
+ }
+ }
+ }
+ } else { /* Illegal path */
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else { /* Server and share */
+ pc = dk4strw_chr(&(fn[2]), L'\\');
+ if (NULL != pc) { /* Share */
+ pc = dk4strw_chr(&(pc[1]), L'\\');
+ if (NULL != pc) { /* First dir */
+ *pc = L'\0';
+ back = dk4mkdir_hierarchy_wc_one(fn, 1, erp);
+ *pc = L'\\';
+ if (0 != back) {
+ back = 0;
+ pc = dk4strw_chr(&(pc[1]), L'\\');
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_wc_one(fn, 0, erp);
+ } else {
+ back = 1;
+ }
+ }
+ } else {
+ pc = dk4strw_chr(&(pc[1]), L'\\');
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_wc_one(fn, 0, erp);
+ }
+ }
+ }
+ } else { /* Share name but no dir */
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_wc_one(fn, 1, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ }
+ } else { /* No share */
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ }
+ } else { /* Absolute path wo drive */
+ pc = dk4strw_chr(&(fn[1]), L'\\');
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_wc_one(fn, 0, erp);
+ } else {
+ back = 1;
+ }
+ }
+ }
+ } else { /* No backslash at start */
+ if (dk4mkdir_hierarchy_wc_is_char(fn[0])) {
+ if (L':' == fn[1]) { /* Drive */
+ if (L'\\' == fn[2]) { /* Drive abs */
+ sc = fn[3];
+ fn[3] = L'\0';
+ back = dk4mkdir_hierarchy_wc_one(fn, 1, erp);
+ fn[3] = sc;
+ if (0 != back) {
+ back = 0;
+ pc = dk4strw_chr(&(fn[3]), L'\\');
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_wc_one(fn, 0, erp);
+ } else {
+ back = 1;
+ }
+ }
+ }
+ } else { /* Drive rel */
+ sc = fn[2];
+ fn[2] = L'\0';
+ back = dk4mkdir_hierarchy_wc_one(fn, 1, erp);
+ fn[2] = sc;
+ if (0 != back) {
+ back = 0;
+ pc = dk4strw_chr(&(fn[3]), L'\\');
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_wc_one(fn, 0, erp);
+ } else {
+ back = 1;
+ }
+ }
+ }
+ }
+ } else { /* Normal file name */
+ pc = dk4strw_chr(fn, L'\\');
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_wc_one(fn, 0, erp);
+ } else {
+ back = 1;
+ }
+ }
+ }
+ } else { /* Normal file name */
+ pc = dk4strw_chr(fn, L'\\');
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_wc_one(fn, 0, erp);
+ } else {
+ back = 1;
+ }
+ }
+ }
+ }
+ finished:
+ if (NULL != bptr) { *bptr = back; }
+ return pc;
+}
+
+
+
+/** Run on writable copy of file name.
+ @param fn File name.
+ @param lc Flag: Last component is directory too.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4mkdir_hierarchy_wc_on_copy(wchar_t *fn, int lc, dk4_er_t *erp)
+{
+ wchar_t *pc = NULL;
+ int back = 0;
+
+ /* Correct path name */
+ dk4pathw_correct_sep(fn);
+
+ /* Find first real separator */
+ pc = dk4mkdir_hierarchy_wc_first_sep(fn, &back, lc, erp);
+
+ /* Attempt to create directory, parent directories too if necessary */
+ if (NULL != pc) {
+ back = 1;
+ while (NULL != pc) {
+ *pc = L'\0';
+ if (0 < dk4strw_len(fn)) {
+ if (0 == dk4mkdir_hierarchy_wc_one(fn, 0, erp)) {
+ back = 0;
+ }
+ }
+ *pc = L'\\';
+ pc = dk4strw_chr(&(pc[1]), L'\\');
+ }
+ if (0 != lc) {
+ if (0 == dk4mkdir_hierarchy_wc_one(fn, 0, erp)) {
+ back = 0;
+ }
+ }
+ } else {
+ if (0 != back) {
+ if (0 != lc) {
+ if (0 == dk4mkdir_hierarchy_wc_one(fn, 0, erp)) {
+ back = 0;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Create writable copy in local buffer and run.
+ @param fn Original file name.
+ @param lc Flag: Last component is directory too.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4mkdir_hierarchy_wc_local(const wchar_t *fn, int lc, dk4_er_t *erp)
+{
+ wchar_t mycp[DK4_MAX_PATH];
+ int back = 0;
+ if (dk4strw_cpy_s(mycp, DK4_SIZEOF(mycp,wchar_t), fn, erp)) {
+ back = dk4mkdir_hierarchy_wc_on_copy(mycp, lc, erp);
+ }
+ return back;
+}
+
+
+#endif
+
+
+
+int
+dk4mkdir_hierarchy_wc(const wchar_t *fn, int lc, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ wchar_t *mycp;
+ size_t sz;
+ int back = 0;
+ if (NULL != fn) {
+ sz = dk4strw_len(fn);
+ if (0 < sz) {
+ if (DK4_MAX_PATH > sz) {
+ back = dk4mkdir_hierarchy_wc_local(fn, lc, erp);
+ } else {
+ mycp = dk4strw_dup(fn, erp);
+ if (NULL != mycp) {
+ dk4mkdir_hierarchy_wc_on_copy(mycp, lc, erp);
+ dk4mem_free(mycp);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+
+
+#line 640 "dk4mkdhw.ctr"
+
+
+#line 641 "dk4mkdhw.ctr"
+
+
+#line 642 "dk4mkdhw.ctr"
+ return 0;
+#endif
+}
+
diff --git a/support/dktools/dk4mkdhw.ctr b/support/dktools/dk4mkdhw.ctr
new file mode 100644
index 0000000000..c5703860fb
--- /dev/null
+++ b/support/dktools/dk4mkdhw.ctr
@@ -0,0 +1,645 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Make directory hierarchy (create all parent directories for a
+ file or directory and the directory itself if required),
+ the file or directory name is specified as wchar_t string.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_HAVE_WCHAR_H
+#ifndef WCHAR_H_INCLUDED
+#include <wchar.h>
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Find position of first separator for real directory.
+
+ This function is not intended for use in application programs,
+ it is exported only for use from the dk4appmkdh module.
+
+ The function either returns a value or sets the back variable
+ to 1 or reports an error.
+ @param fn File name.
+ @param bptr Pointer to the back variable.
+ @param lc Flag: Last component in fn is directory too.
+ @param erp Error report, may be NULL.
+ @return First separator after a real directory on success if
+ found, NULL otherwise.
+*/
+wchar_t *
+dk4mkdir_hierarchy_wc_first_sep(wchar_t *fn, int *bptr, int lc, dk4_er_t *erp);
+
+/** Check whether directory exists or attempt to create directory.
+ @param fn File name.
+ @param ro Flag: Read only (test directory presence),
+ do not attempt to create directory.
+ @param erp Error report, may be NULL.
+ @return 1 if directory is available now, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_NOT_FOUND<br>
+ if a server/share combination is not present on Windows,
+ - DK4_E_NON_DIR<br>
+ if any component in the path is not a directory,
+ - DK4_E_CREATE_DIR_FAILED<br>
+ with GetLastError() result in lDetails1 if the CreateDirectory()
+ function failed.
+*/
+int
+dk4mkdir_hierarchy_wc_one(const wchar_t *fn, int ro, dk4_er_t *erp);
+
+/** Create directory structure.
+ CRT on Windows: Optional.
+ @param fn File name.
+ @param lc Flag: Last component in fn is directory too.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if fn is too long,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in size allocation,
+ - DK4_E_NOT_FOUND<br>
+ if a server/share combination is not present on Windows,
+ - DK4_E_NON_DIR<br>
+ if one of the components in fn is not a directory,
+ - DK4_E_MKDIR_FAILED<br>
+ with errno in idetails if the function fails to create the directory
+ or a parent directory,
+ - DK4_E_CREATE_DIR_FAILED<br>
+ with GetLastError() result in lDetails1 if the CreateDirectory()
+ function failed on a Windows system.
+*/
+int
+dk4mkdir_hierarchy_wc(const wchar_t *fn, int lc, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4mkdh8.h"
+
+#if DK4_HAVE_SYS_STAT_H
+#ifndef SYS_STAT_H_INCLUDED
+#include <sys/stat.h>
+#define SYS_STAT_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_DIRECT_H
+#ifndef DIRECT_H_INCLUDED
+#include <direct.h>
+#define DIRECT_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4MPL_H_INCLUDED
+#include "dk4mpl.h"
+#endif
+
+#ifndef DK4STRW_H_INCLUDED
+#include "dk4strw.h"
+#endif
+
+#ifndef DK4PATHW_H_INCLUDED
+#include "dk4pathw.h"
+#endif
+
+#ifndef DK4STATW_H_INCLUDED
+#include "dk4statw.h"
+#endif
+
+#ifndef DK4STAT_H_INCLUDED
+#include "dk4stat.h"
+#endif
+
+
+
+$!trace-include
+
+
+
+#if DK4_ON_WINDOWS
+static
+int
+dk4mkdir_hierarchy_wc_is_char(wchar_t c)
+{
+ int back = 0;
+ if ((L'a' <= c) && (L'z' >= c)) {
+ back = 1;
+ } else {
+ if ((L'A' <= c) && (L'Z' >= c)) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4mkdir_hierarchy_wc_one(const wchar_t *fn, int ro, dk4_er_t *erp)
+{
+ BY_HANDLE_FILE_INFORMATION bhfi;
+ WIN32_FIND_DATAW ffdata;
+ HANDLE ha;
+ DWORD dwattr;
+ int found;
+ int i;
+ int back = 0;
+ $? "+ dk4mkdir_hierarchy_wc_one \"%ls\"", fn
+ if (NULL == fn) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+#if 1
+ dwattr = GetFileAttributesW(fn);
+ if (INVALID_FILE_ATTRIBUTES == dwattr) {
+ ha = FindFirstFileW(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != ha) {
+ dwattr = ffdata.dwFileAttributes;
+ FindClose(ha);
+ }
+ }
+ if (INVALID_FILE_ATTRIBUTES != dwattr) { $? ". exists"
+ if (0 != (FILE_ATTRIBUTE_DIRECTORY & dwattr)) { $? ". dir"
+ back = 1;
+ } else { $? "! not dir"
+ if (0 != (FILE_ATTRIBUTE_REPARSE_POINT & dwattr)) {
+ found = 0;
+ for (i = 0; ((3 > i) && (0 == back) && (0 == found)); i++) {
+ ha = CreateFileW(
+ fn,
+ (
+ (0 == i)
+ ? (0)
+ : ((1 == i) ? (FILE_READ_ATTRIBUTES) : (GENERIC_READ))
+ ),
+ (FILE_SHARE_READ | FILE_SHARE_WRITE),
+ NULL,
+ OPEN_EXISTING,
+ (dwattr | FILE_FLAG_BACKUP_SEMANTICS),
+ NULL
+ );
+ if (INVALID_HANDLE_VALUE != ha) {
+ if (GetFileInformationByHandle(ha, &bhfi)) {
+ found = 1;
+ if (0 != (FILE_ATTRIBUTE_DIRECTORY & (bhfi.dwFileAttributes))) {
+ back = 1;
+ }
+ }
+ CloseHandle(ha);
+ }
+ }
+ }
+ if (0 == back) {
+ dk4error_set_simple_error_code(erp, DK4_E_NON_DIR);
+ }
+ }
+ } else { $? ". not yet"
+ if (0 != ro) {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ } else {
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ if (CreateDirectoryW(fn, NULL)) { $? ". created"
+ back = 1;
+ } else { $? "! CreateDirectoryW"
+ dk4error_set_ldetails(
+ erp, DK4_E_CREATE_DIR_FAILED ,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+#else
+ if (CreateDirectoryW(fn, NULL)) { $? ". created"
+ back = 1;
+ } else { $? "! CreateDirectoryW"
+ errno = 0;
+ if (0 == _wmkdir(fn)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_MKDIR_FAILED, errno);
+ }
+ }
+#endif
+ }
+ }
+#else
+ back = 1;
+#endif
+ finished:
+ $? "- dk4mkdir_hierarchy_wc_one %d", back
+ return back;
+}
+
+
+
+wchar_t *
+dk4mkdir_hierarchy_wc_first_sep(wchar_t *fn, int *bptr, int lc, dk4_er_t *erp)
+{
+ wchar_t *pc = NULL;
+ wchar_t sc;
+ int back = 0;
+ int isunc = 0;
+
+ if (NULL == fn) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ if (L'\\' == fn[0]) { /* One backslash at start */
+ if (L'\\' == fn[1]) { /* Two backslashes */
+ if (L'?' == fn[2]) { /* Probably extended long path */
+ if (L'\\' == fn[3]) { /* Extended path */
+ if (dk4mkdir_hierarchy_wc_is_char(fn[4])) {
+ if (L':' == fn[5]) { /* Extended, drive */
+ if (L'\\' == fn[6]) { /* Extended, drive abs */
+ sc = fn[7];
+ fn[7] = L'\0';
+ back = dk4mkdir_hierarchy_wc_one(fn, 1, erp);
+ fn[7] = sc;
+ if (0 != back) {
+ pc = dk4strw_chr(&(fn[7]), L'\\');
+ if (NULL == pc) {
+ back = dk4mkdir_hierarchy_wc_one(fn, 0, erp);
+ } else {
+ back = 1;
+ }
+ } else {
+ pc = NULL;
+ }
+ } else { /* Extended, drive rel */
+#if 0
+ pc = dk4strw_chr(&(fn[7]), L'\\');
+ if (NULL == pc) { back = 1; }
+#endif
+ /* 2015-02-05 For extended paths we can use
+ full absolute path names only!
+ */
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else { /* Extended, server and share */
+ if ((L'U' == fn[4]) || (L'u' == fn[4])) {
+ if ((L'N' == fn[5]) || (L'n' == fn[5])) {
+ if ((L'C' == fn[6]) || (L'c' == fn[6])) {
+ if (L'\\' == fn[7]) {
+ isunc = 1;
+ }
+ }
+ }
+ }
+ if (0 != isunc) { /* UNC path */
+ pc = dk4strw_chr(&(fn[8]), L'\\');
+ if (NULL != pc) { /* Share */
+ pc = dk4strw_chr(&(pc[1]), L'\\');
+ if (NULL != pc) { /* First real directory */
+ *pc = L'\0';
+ back = dk4mkdir_hierarchy_wc_one(fn, 1, erp);
+ *pc = L'\\';
+ if (0 != back) {
+ back = 0;
+ pc = dk4strw_chr(&(pc[1]), L'\\');
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_wc_one(fn, 0, erp);
+ } else {
+ back = 1;
+ }
+ }
+ } else {
+ pc = dk4strw_chr(&(pc[1]), L'\\');
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_wc_one(fn, 0, erp);
+ }
+ }
+ }
+ } else { /* No real directory after share */
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_wc_one(fn, 1, erp);
+ } else {
+ dk4error_set_simple_error_code(
+ erp, DK4_E_INVALID_ARGUMENTS
+ );
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else { /* Not UNC, normal path */
+ pc = dk4strw_chr(&(fn[4]), L'\\');
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_wc_one(fn, 0, erp);
+ } else {
+ back = 1;
+ }
+ }
+ }
+ }
+ } else { /* Some unknown extended path */
+ pc = dk4strw_chr(&(fn[4]), L'\\');
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_wc_one(fn, 0, erp);
+ } else {
+ back = 1;
+ }
+ }
+ }
+ } else { /* Illegal path */
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else { /* Server and share */
+ pc = dk4strw_chr(&(fn[2]), L'\\');
+ if (NULL != pc) { /* Share */
+ pc = dk4strw_chr(&(pc[1]), L'\\');
+ if (NULL != pc) { /* First dir */
+ *pc = L'\0';
+ back = dk4mkdir_hierarchy_wc_one(fn, 1, erp);
+ *pc = L'\\';
+ if (0 != back) {
+ back = 0;
+ pc = dk4strw_chr(&(pc[1]), L'\\');
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_wc_one(fn, 0, erp);
+ } else {
+ back = 1;
+ }
+ }
+ } else {
+ pc = dk4strw_chr(&(pc[1]), L'\\');
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_wc_one(fn, 0, erp);
+ }
+ }
+ }
+ } else { /* Share name but no dir */
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_wc_one(fn, 1, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ }
+ } else { /* No share */
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ }
+ } else { /* Absolute path wo drive */
+ pc = dk4strw_chr(&(fn[1]), L'\\');
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_wc_one(fn, 0, erp);
+ } else {
+ back = 1;
+ }
+ }
+ }
+ } else { /* No backslash at start */
+ if (dk4mkdir_hierarchy_wc_is_char(fn[0])) {
+ if (L':' == fn[1]) { /* Drive */
+ if (L'\\' == fn[2]) { /* Drive abs */
+ sc = fn[3];
+ fn[3] = L'\0';
+ back = dk4mkdir_hierarchy_wc_one(fn, 1, erp);
+ fn[3] = sc;
+ if (0 != back) {
+ back = 0;
+ pc = dk4strw_chr(&(fn[3]), L'\\');
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_wc_one(fn, 0, erp);
+ } else {
+ back = 1;
+ }
+ }
+ }
+ } else { /* Drive rel */
+ sc = fn[2];
+ fn[2] = L'\0';
+ back = dk4mkdir_hierarchy_wc_one(fn, 1, erp);
+ fn[2] = sc;
+ if (0 != back) {
+ back = 0;
+ pc = dk4strw_chr(&(fn[3]), L'\\');
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_wc_one(fn, 0, erp);
+ } else {
+ back = 1;
+ }
+ }
+ }
+ }
+ } else { /* Normal file name */
+ pc = dk4strw_chr(fn, L'\\');
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_wc_one(fn, 0, erp);
+ } else {
+ back = 1;
+ }
+ }
+ }
+ } else { /* Normal file name */
+ pc = dk4strw_chr(fn, L'\\');
+ if (NULL == pc) {
+ if (0 != lc) {
+ back = dk4mkdir_hierarchy_wc_one(fn, 0, erp);
+ } else {
+ back = 1;
+ }
+ }
+ }
+ }
+ finished:
+ if (NULL != bptr) { *bptr = back; }
+ return pc;
+}
+
+
+
+/** Run on writable copy of file name.
+ @param fn File name.
+ @param lc Flag: Last component is directory too.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4mkdir_hierarchy_wc_on_copy(wchar_t *fn, int lc, dk4_er_t *erp)
+{
+ wchar_t *pc = NULL;
+ int back = 0;
+
+ /* Correct path name */
+ dk4pathw_correct_sep(fn);
+
+ /* Find first real separator */
+ pc = dk4mkdir_hierarchy_wc_first_sep(fn, &back, lc, erp);
+
+ /* Attempt to create directory, parent directories too if necessary */
+ if (NULL != pc) {
+ back = 1;
+ while (NULL != pc) {
+ *pc = L'\0';
+ if (0 < dk4strw_len(fn)) {
+ if (0 == dk4mkdir_hierarchy_wc_one(fn, 0, erp)) {
+ back = 0;
+ }
+ }
+ *pc = L'\\';
+ pc = dk4strw_chr(&(pc[1]), L'\\');
+ }
+ if (0 != lc) {
+ if (0 == dk4mkdir_hierarchy_wc_one(fn, 0, erp)) {
+ back = 0;
+ }
+ }
+ } else {
+ if (0 != back) {
+ if (0 != lc) {
+ if (0 == dk4mkdir_hierarchy_wc_one(fn, 0, erp)) {
+ back = 0;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Create writable copy in local buffer and run.
+ @param fn Original file name.
+ @param lc Flag: Last component is directory too.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4mkdir_hierarchy_wc_local(const wchar_t *fn, int lc, dk4_er_t *erp)
+{
+ wchar_t mycp[DK4_MAX_PATH];
+ int back = 0;
+ if (dk4strw_cpy_s(mycp, DK4_SIZEOF(mycp,wchar_t), fn, erp)) {
+ back = dk4mkdir_hierarchy_wc_on_copy(mycp, lc, erp);
+ }
+ return back;
+}
+
+
+#endif
+
+
+
+int
+dk4mkdir_hierarchy_wc(const wchar_t *fn, int lc, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ wchar_t *mycp;
+ size_t sz;
+ int back = 0;
+ if (NULL != fn) {
+ sz = dk4strw_len(fn);
+ if (0 < sz) {
+ if (DK4_MAX_PATH > sz) {
+ back = dk4mkdir_hierarchy_wc_local(fn, lc, erp);
+ } else {
+ mycp = dk4strw_dup(fn, erp);
+ if (NULL != mycp) {
+ dk4mkdir_hierarchy_wc_on_copy(mycp, lc, erp);
+ dk4mem_free(mycp);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ $? "+ dk4mkdir_hierarchy"
+ $? "! not supported on this platform"
+ $? "- dk4mkdir_hierarchy 0"
+ return 0;
+#endif
+}
+
diff --git a/support/dktools/dk4mkdhw.h b/support/dktools/dk4mkdhw.h
new file mode 100644
index 0000000000..c54a082412
--- /dev/null
+++ b/support/dktools/dk4mkdhw.h
@@ -0,0 +1,144 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mkdhw.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MKDHW_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MKDHW_H_INCLUDED 1
+
+
+#line 10 "dk4mkdhw.ctr"
+
+/** @file
+ Make directory hierarchy (create all parent directories for a
+ file or directory and the directory itself if required),
+ the file or directory name is specified as wchar_t string.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_HAVE_WCHAR_H
+#ifndef WCHAR_H_INCLUDED
+#include <wchar.h>
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Find position of first separator for real directory.
+
+ This function is not intended for use in application programs,
+ it is exported only for use from the dk4appmkdh module.
+
+ The function either returns a value or sets the back variable
+ to 1 or reports an error.
+ @param fn File name.
+ @param bptr Pointer to the back variable.
+ @param lc Flag: Last component in fn is directory too.
+ @param erp Error report, may be NULL.
+ @return First separator after a real directory on success if
+ found, NULL otherwise.
+*/
+wchar_t *
+dk4mkdir_hierarchy_wc_first_sep(wchar_t *fn, int *bptr, int lc, dk4_er_t *erp);
+
+/** Check whether directory exists or attempt to create directory.
+ @param fn File name.
+ @param ro Flag: Read only (test directory presence),
+ do not attempt to create directory.
+ @param erp Error report, may be NULL.
+ @return 1 if directory is available now, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_NOT_FOUND<br>
+ if a server/share combination is not present on Windows,
+ - DK4_E_NON_DIR<br>
+ if any component in the path is not a directory,
+ - DK4_E_CREATE_DIR_FAILED<br>
+ with GetLastError() result in lDetails1 if the CreateDirectory()
+ function failed.
+*/
+int
+dk4mkdir_hierarchy_wc_one(const wchar_t *fn, int ro, dk4_er_t *erp);
+
+/** Create directory structure.
+ CRT on Windows: Optional.
+ @param fn File name.
+ @param lc Flag: Last component in fn is directory too.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if fn is too long,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in size allocation,
+ - DK4_E_NOT_FOUND<br>
+ if a server/share combination is not present on Windows,
+ - DK4_E_NON_DIR<br>
+ if one of the components in fn is not a directory,
+ - DK4_E_MKDIR_FAILED<br>
+ with errno in idetails if the function fails to create the directory
+ or a parent directory,
+ - DK4_E_CREATE_DIR_FAILED<br>
+ with GetLastError() result in lDetails1 if the CreateDirectory()
+ function failed on a Windows system.
+*/
+int
+dk4mkdir_hierarchy_wc(const wchar_t *fn, int lc, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4mm.c b/support/dktools/dk4mm.c
new file mode 100644
index 0000000000..90214b22e8
--- /dev/null
+++ b/support/dktools/dk4mm.c
@@ -0,0 +1,76 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mm.ctr
+*/
+
+/*
+Copyright (C) 2017-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4mm.c The dk4mm module.
+*/
+
+
+#line 39 "dk4mm.ctr"
+
+#include "dk4mm.h"
+#include "dk4statd.h"
+
+
+
+int
+dk4makemode_must_rebuild(const dkChar *dn, const dkChar *sn)
+{
+ dk4_stat_t ds;
+ dk4_stat_t ss;
+ int back = 0;
+ if ((NULL == dn) || (NULL == sn)) {
+ goto finished;
+ }
+ if (0 != dk4stat(&ss, sn, NULL)) {
+ /* Source file exists. */
+ back = 1;
+ if (0 != dk4stat(&ds, dn, NULL)) {
+ /* Destination file exists. */
+ if (ds.st_mtime > ss.st_mtime) {
+ /* Destination file exists and is up to date. */
+ back = 0;
+ }
+ }
+ }
+ else {
+ /* Source file does not exist. */
+ }
+
+ finished:
+ return back;
+}
+
+
+/* vim: set ai sw=4 ts=4 : */
diff --git a/support/dktools/dk4mm.ctr b/support/dktools/dk4mm.ctr
new file mode 100644
index 0000000000..2014e69b35
--- /dev/null
+++ b/support/dktools/dk4mm.ctr
@@ -0,0 +1,74 @@
+%% options
+copyright owner = Dirk Krause
+copyright year = 2017-xxxx
+license = bsd
+
+%% header
+
+/** @file dk4mm.h Make mode: Check if rebuilding destination file
+ is necessary.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include <dk4conf.h>
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include <dk4types.h>
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Check whether or not it is necessary to rebuild a destination file.
+ @param dn Destination file name.
+ @param sn Source file name.
+ @return 0 if the destination file is up to date, any non-0 value otherwise.
+*/
+int
+dk4makemode_must_rebuild(const dkChar *dn, const dkChar *sn);
+
+#ifdef __cplusplus
+}
+#endif
+
+/* vim: set ai sw=4 ts=4 : */
+%% module
+
+#include "dk4mm.h"
+#include "dk4statd.h"
+
+
+
+int
+dk4makemode_must_rebuild(const dkChar *dn, const dkChar *sn)
+{
+ dk4_stat_t ds;
+ dk4_stat_t ss;
+ int back = 0;
+ if ((NULL == dn) || (NULL == sn)) {
+ goto finished;
+ }
+ if (0 != dk4stat(&ss, sn, NULL)) {
+ /* Source file exists. */
+ back = 1;
+ if (0 != dk4stat(&ds, dn, NULL)) {
+ /* Destination file exists. */
+ if (ds.st_mtime > ss.st_mtime) {
+ /* Destination file exists and is up to date. */
+ back = 0;
+ }
+ }
+ }
+ else {
+ /* Source file does not exist. */
+ }
+
+ finished:
+ return back;
+}
+
+
+/* vim: set ai sw=4 ts=4 : */
diff --git a/support/dktools/dk4mm.h b/support/dktools/dk4mm.h
new file mode 100644
index 0000000000..d928177e1c
--- /dev/null
+++ b/support/dktools/dk4mm.h
@@ -0,0 +1,74 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4mm.ctr
+*/
+
+/*
+Copyright (C) 2017-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4MM_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4MM_H_INCLUDED 1
+
+
+#line 7 "dk4mm.ctr"
+
+/** @file dk4mm.h Make mode: Check if rebuilding destination file
+ is necessary.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include <dk4conf.h>
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include <dk4types.h>
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Check whether or not it is necessary to rebuild a destination file.
+ @param dn Destination file name.
+ @param sn Source file name.
+ @return 0 if the destination file is up to date, any non-0 value otherwise.
+*/
+int
+dk4makemode_must_rebuild(const dkChar *dn, const dkChar *sn);
+
+#ifdef __cplusplus
+}
+#endif
+
+/* vim: set ai sw=4 ts=4 : */
+
+#endif
diff --git a/support/dktools/dk4mpl.h b/support/dktools/dk4mpl.h
new file mode 100644
index 0000000000..7e20d707fc
--- /dev/null
+++ b/support/dktools/dk4mpl.h
@@ -0,0 +1,62 @@
+#ifndef DK4MPL_H_INCLUDED
+
+/** @file dk4mpl.h Definition of DK4_MAX_PATH
+ (maximum path length).
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef STDIO_H_INCLUDED
+#include <stdio.h>
+#define STDIO_H_INCLUDED 1
+#endif
+
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+
+#if DK4_HAVE_SYS_PARAM_H
+#ifndef SYS_PARAM_H_INCLUDED
+#include <sys/param.h>
+#define SYS_PARAM_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_LIMITS_H
+#ifndef LIMITS_H_INCLUDED
+#include <limits.h>
+#define LIMITS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_ON_WINDOWS
+/** Maximum path length including terminating character
+ (definition to _MAX_PATH on Windows systems).
+*/
+#define DK4_MAX_PATH _MAX_PATH
+#else
+#ifdef MAXPATHLEN
+/** Maximum path length including terminating character
+ (definition to MAXPATHLEN if defined).
+*/
+#define DK4_MAX_PATH MAXPATHLEN
+#else
+#ifdef PATH_MAX
+/** Maximum path length including terminating character
+ (definition to PATH_MAX on Linux systems).
+*/
+#define DK4_MAX_PATH PATH_MAX
+#else
+/** Maximum path length including terminating character.
+*/
+#define DK4_MAX_PATH 1024
+#endif
+#endif
+#endif
+
+#define DK4MPL_H_INCLUDED 1
+#endif
+
diff --git a/support/dktools/dk4numco.h b/support/dktools/dk4numco.h
new file mode 100644
index 0000000000..bc1fcdef55
--- /dev/null
+++ b/support/dktools/dk4numco.h
@@ -0,0 +1,451 @@
+/** @file dk4numco.h Numeric constants.
+
+ Typically the constants from limits.h and stdint.h are used.
+ This file contains fallback definitions if the files
+ are not available or some definitions are missing.
+*/
+#ifndef DK4NUMCO_H_INCLUDED
+
+/** Protection against multiple inclusion.
+*/
+#define DK4NUMCO_H_INCLUDED 1
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_LIMITS_H
+#ifndef LIMITS_H_INCLUDED
+#include <limits.h>
+#define LIMITS_H_INCLUDED 1
+#endif
+#endif
+#if DK4_HAVE_STDINT_H
+#ifndef STDINT_H_INCLUDED
+#if defined(__cplusplus) && (!defined(__STDC_LIMIT_MACROS))
+/** For legacy compilers, use macros for integer limits.
+*/
+#define __STDC_LIMIT_MACROS 1
+#endif
+#if defined(__cplusplus) && (!defined(__STDC_CONSTANT_MACROS))
+/** For legacy compilers, use macros for constants.
+*/
+#define __STDC_CONSTANT_MACROS 1
+#endif
+#include <stdint.h>
+#define STDINT_H_INCLUDED 1
+#endif
+#endif
+#if DK4_HAVE_INTTYPES_H
+#ifndef INTTYPES_H_INCLUDED
+#include <inttypes.h>
+#define INTTYPES_H_INCLUDED 1
+#endif
+#endif
+
+/** Decision: Use fallback definitions for missing constants.
+ On some systems the minimum/maximum constants are not
+ defined.
+ Here you can choose, whether the compiler should complain
+ and bail out (0) or use a self-made definition (1).
+ The default is to complain and bail out.
+*/
+#ifndef DK4_USE_FALLBACK_NUMERIC_LIMITS
+#define DK4_USE_FALLBACK_NUMERIC_LIMITS 0
+#endif
+
+
+
+#ifndef SIZE_MAX
+#if !DK4_USE_FALLBACK_NUMERIC_LIMITS
+#error "SIZE_MAX undefined! See file dk4numco.h, line 10."
+#endif
+#if DK4_SIZEOF_SIZE_T > 2
+#if DK4_SIZEOF_SIZE_T > 4
+/** Maximum size_t value. */
+#define SIZE_MAX 18446744073709551615ULL
+#else
+/** Maximum size_t value. */
+#define SIZE_MAX 4294967295UL
+#endif
+#else
+/** Maximum size_t value. */
+#define SIZE_MAX 65535U
+#endif
+#endif
+/* ifndef SIZE_MAX */
+
+
+
+#ifndef SCHAR_MIN
+#if !DK4_USE_FALLBACK_NUMERIC_LIMITS
+#error "SCHAR_MIN undefined! See file dk4numco.h, line 10."
+#endif
+/** Minimum signed char value. */
+#define SCHAR_MIN (-128)
+#endif
+/* ifndef SCHAR_MIN */
+
+
+
+#ifndef SCHAR_MAX
+#if !DK4_USE_FALLBACK_NUMERIC_LIMITS
+#error "SCHAR_MAX undefined! See file dk4numco.h, line 10."
+#endif
+/** Maximum signed char value. */
+#define SCHAR_MAX 127
+#endif
+/* ifndef SCHAR_MAX */
+
+
+
+#ifndef UCHAR_MAX
+#if !DK4_USE_FALLBACK_NUMERIC_LIMITS
+#error "UCHAR_MAX undefined! See file dk4numco.h, line 10."
+#endif
+/** Maximum unsigned char value. */
+#define UCHAR_MAX 255
+#endif
+/* ifndef UCHAR_MAX */
+
+
+
+#ifndef SHRT_MIN
+#if !DK4_USE_FALLBACK_NUMERIC_LIMITS
+#error "SHRT_MIN undefined! See file dk4numco.h, line 10."
+#endif
+/** Minimum signed short value. */
+#define SHRT_MIN (-32768)
+#endif
+/* ifndef SHRT_MIN */
+
+
+
+#ifndef SHRT_MAX
+#if !DK4_USE_FALLBACK_NUMERIC_LIMITS
+#error "SHRT_MAX undefined! See file dk4numco.h, line 10."
+#endif
+/** Maximum signed short value. */
+#define SHRT_MAX 32767
+#endif
+/* ifndef SHRT_MAX */
+
+
+
+#ifndef USHRT_MAX
+#if !DK4_USE_FALLBACK_NUMERIC_LIMITS
+#error "USHRT_MAX undefined! See file dk4numco.h, line 10."
+#endif
+/** Maximum unsigned short value. */
+#define USHRT_MAX 65535
+#endif
+/* ifndef USHRT_MAX */
+
+
+
+#ifndef INT_MAX
+#if !DK4_USE_FALLBACK_NUMERIC_LIMITS
+#error "INT_MAX undefined! See file dk4numco.h, line 10."
+#endif
+#if DK4_SIZEOF_INT > 2
+#if DK4_SIZEOF_INT > 4
+#if DK4_SIZEOF_INT > 8
+#error "Not prepared for such large int numbers!"
+#else
+/** Maximum signed int value. */
+#define INT_MAX 9223372036854775807
+#endif
+#else
+/** Maximum signed int value. */
+#define INT_MAX 2147483647
+#endif
+#else
+/** Maximum signed int value. */
+#define INT_MAX 32767
+#endif
+#endif
+/* ifndef INT_MAX */
+
+
+
+#ifndef INT_MIN
+#if !DK4_USE_FALLBACK_NUMERIC_LIMITS
+#error "INT_MIN undefined! See file dk4numco.h, line 10."
+#endif
+/** Minimum signed int value. */
+#define INT_MIN (-INT_MAX - 1)
+#endif
+/* ifndef INT_MIN */
+
+
+
+#ifndef UINT_MAX
+#if !DK4_USE_FALLBACK_NUMERIC_LIMITS
+#error "LONG_MAX undefined! See file dk4numco.h, line 10."
+#endif
+#if DK4_SIZEOF_INT > 2
+#if DK4_SIZEOF_INT > 4
+#if DK4_SIZEOF_INT > 8
+#error "Not prepared for such large int numbers!"
+#else
+/** Maximum unsigned int value. */
+#define UINT_MAX 18446744073709551615U
+#endif
+#else
+/** Maximum unsigned int value. */
+#define UINT_MAX 4294967295U
+#endif
+#else
+/** Maximum unsigned int value. */
+#define UINT_MAX 65535U
+#endif
+#endif
+/* ifndef UINT_MAX */
+
+
+
+#ifndef LONG_MAX
+#if !DK4_USE_FALLBACK_NUMERIC_LIMITS
+#error "LONG_MAX undefined! See file dk4numco.h, line 10."
+#endif
+#if DK4_SIZEOF_LONG > 2
+#if DK4_SIZEOF_LONG > 4
+#if DK4_SIZEOF_LONG > 8
+#error "Not prepared for such large long numbers!"
+#else
+/** Maximum signed long value. */
+#define LONG_MAX 9223372036854775807L
+#endif
+#else
+/** Maximum signed long value. */
+#define LONG_MAX 2147483647L
+#endif
+#else
+/** Maximum signed long value. */
+#define LONG_MAX 32767L
+#endif
+#endif
+/* ifndef LONG_MAX */
+
+
+
+#ifndef LONG_MIN
+#if !DK4_USE_FALLBACK_NUMERIC_LIMITS
+#error "LONG_MIN undefined! See file dk4numco.h, line 10."
+#endif
+/** Minimum signed long value. */
+#define LONG_MIN (-LONG_MAX - 1L)
+#endif
+/* ifndef LONG_MIN */
+
+
+
+#ifndef ULONG_MAX
+#if !DK4_USE_FALLBACK_NUMERIC_LIMITS
+#error "ULONG_MAX undefined! See file dk4numco.h, line 10."
+#endif
+#if DK4_SIZEOF_LONG > 2
+#if DK4_SIZEOF_LONG > 4
+#if DK4_SIZEOF_LONG > 8
+#error "Not prepared for such large long numbers!"
+#else
+/** Maximum unsigned long value. */
+#define ULONG_MAX 18446744073709551615UL
+#endif
+#else
+/** Maximum unsigned long value. */
+#define ULONG_MAX 4294967295UL
+#endif
+#else
+/** Maximum unsigned long value. */
+#define ULONG_MAX 65535UL
+#endif
+#endif
+/* ifndef ULONG_MAX */
+
+
+
+#if DK4_HAVE_LONG_LONG
+
+
+
+#ifndef LLONG_MAX
+#if !DK4_USE_FALLBACK_NUMERIC_LIMITS
+#error "LLONG_MAX undefined! See file dk4numco.h, line 10."
+#endif
+#if DK4_SIZEOF_LONG_LONG > 2
+#if DK4_SIZEOF_LONG_LONG > 4
+#if DK4_SIZEOF_LONG_LONG > 8
+#error "Not prepared for such large long long numbers!"
+#else
+/** Maximum signed long long value. */
+#define LLONG_MAX 9223372036854775807LL
+#endif
+#else
+/** Maximum signed long long value. */
+#define LLONG_MAX 2147483647LL
+#endif
+#else
+/** Maximum signed long long value. */
+#define LLONG_MAX 32767LL
+#endif
+#endif
+/* ifndef LLONG_MAX */
+
+
+#ifndef LLONG_MIN
+#if !DK4_USE_FALLBACK_NUMERIC_LIMITS
+#error "LLONG_MIN undefined! See file dk4numco.h, line 10."
+#endif
+/** Minimum signed long long value. */
+#define LLONG_MIN (-LLONG_MAX - 1LL)
+#endif
+/* ifndef LLONG_MIN */
+
+
+
+#ifndef ULLONG_MAX
+#if !DK4_USE_FALLBACK_NUMERIC_LIMITS
+#error "ULLONG_MAX undefined! See file dk4numco.h, line 10."
+#endif
+#if DK4_SIZEOF_LONG_LONG > 2
+#if DK4_SIZEOF_LONG_LONG > 4
+#if DK4_SIZEOF_LONG_LONG > 8
+#error "Not prepared for such large long long numbers!"
+#else
+/** Maximum unsigned long long value. */
+#define ULLONG_MAX 18446744073709551615ULL
+#endif
+#else
+/** Maximum unsigned long long value. */
+#define ULLONG_MAX 4294967295ULL
+#endif
+#else
+/** Maximum unsigned long long value. */
+#define ULLONG_MAX 65535ULL
+#endif
+#endif
+/* ifndef ULLONG_MAX */
+
+
+
+#endif
+/* if DK4_HAVE_LONG_LONG */
+
+
+
+
+#if DK4_HAVE_INTMAX_T
+
+
+#ifndef INTMAX_MAX
+#if !DK4_USE_FALLBACK_NUMERIC_LIMITS
+#error "INTMAX_MAX undefined! See file dk4numco.h, line 10."
+#endif
+#if DK4_SIZEOF_INTMAX_T == DK4_SIZEOF_INT
+/** Maximum intmax_t value. */
+#define INTMAX_MAX (INT_MAX)
+#else
+#if DK4_SIZEOF_INTMAX_T == DK4_SIZEOF_LONG
+/** Maximum intmax_t value. */
+#define INTMAX_MAX (LONG_MAX)
+#else
+#if DK4_HAVE_LONG_LONG
+#if DK4_SIZEOF_INTMAX_T == DK4_SIZEOF_LONG_LONG
+/** Maximum intmax_t value. */
+#define INTMAX_MAX (LLONG_MAX)
+#else
+#error "Not prepared for such large intmax_t numbers!"
+#endif
+#else
+#error "Not prepared for such large intmax_t numbers!"
+#endif
+#endif
+#endif
+#endif
+/* ifndef INTMAX_MAX */
+
+
+
+#ifndef INTMAX_MIN
+#if !DK4_USE_FALLBACK_NUMERIC_LIMITS
+#error "INTMAX_MIN undefined! See file dk4numco.h, line 10."
+#endif
+/** Minimum intmax_t value. */
+#define INTMAX_MIN (-(INTMAX_MAX) - (intmax_t)1)
+#endif
+/* ifndef INTMAX_MIN */
+
+
+
+#ifndef UINTMAX_MAX
+#if !DK4_USE_FALLBACK_NUMERIC_LIMITS
+#error "UINTMAX_MAX undefined! See file dk4numco.h, line 10."
+#endif
+#if DK4_SIZEOF_INTMAX_T == DK4_SIZEOF_INT
+/** Maximum uintmax_t value. */
+#define UINTMAX_MAX (UINT_MAX)
+#else
+#if DK4_SIZEOF_INTMAX_T == DK4_SIZEOF_LONG
+/** Maximum uintmax_t value. */
+#define UINTMAX_MAX (ULONG_MAX)
+#else
+#if DK4_HAVE_LONG_LONG
+#if DK4_SIZEOF_INTMAX_T == DK4_SIZEOF_LONG_LONG
+/** Maximum uintmax_t value. */
+#define UINTMAX_MAX (ULLONG_MAX)
+#else
+#error "Not prepared for such large uintmax_t numbers!"
+#endif
+#else
+#error "Not prepared for such large uintmax_t numbers!"
+#endif
+#endif
+#endif
+#endif
+/* ifndef UINTMAX_MAX */
+
+
+
+#endif
+/* if DK4_HAVE_INTMAX_T */
+
+
+
+#if DK4_HAVE_INTMAX_T
+/** Maximum dk4_um_t value.
+*/
+#define DK4_UM_MAX (UINTMAX_MAX)
+/** Maximum dk4_im_t value.
+*/
+#define DK4_IM_MAX (INTMAX_MAX)
+/** Minimum dk4_im_t value.
+*/
+#define DK4_IM_MIN (INTMAX_MIN)
+#else
+#if DK4_HAVE_LONG_LONG
+/** Maximum dk4_um_t value.
+*/
+#define DK4_UM_MAX (ULLONG_MAX)
+/** Maximum dk4_im_t value.
+*/
+#define DK4_IM_MAX (LLONG_MAX)
+/** Minimum dk4_im_t value.
+*/
+#define DK4_IM_MIN (LLONG_MIN)
+#else
+/** Maximum dk4_um_t value.
+*/
+#define DK4_UM_MAX (ULONG_MAX)
+/** Maximum dk4_im_t value.
+*/
+#define DK4_IM_MAX (LONG_MAX)
+/** Minimum dk4_im_t value.
+*/
+#define DK4_IM_MIN (LONG_MIN)
+#endif
+#endif
+
+#endif
+/* ifndef DK4NUMCO_H_INCLUDED */
+
diff --git a/support/dktools/dk4numl.c b/support/dktools/dk4numl.c
new file mode 100644
index 0000000000..eb1f46bf75
--- /dev/null
+++ b/support/dktools/dk4numl.c
@@ -0,0 +1,129 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4numl.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4numl.c The dk4numl module.
+*/
+
+
+#line 47 "dk4numl.ctr"
+
+#include "dk4conf.h"
+#include "dk4error.h"
+#include "dk4numl.h"
+#include "dk4maadu.h"
+
+size_t
+dk4numlength(size_t isz, int sgn)
+{
+ dk4_er_t er;
+ dk4_um_t co;
+ size_t back = 0;
+ if (1 < isz) {
+ if (2 < isz) {
+ if (4 < isz) {
+ if (8 < isz) {
+ if (16 < isz) {
+#if VERSION_BEFORE_20141122
+ if (0 != (isz % 2)) { isz++; }
+ back = 5 * (isz / 2);
+ if (0 != sgn) { back++; }
+#else
+ dk4error_init(&er);
+ if (0 != sgn) {
+ co = dk4ma_um_mul(
+ (dk4_um_t)30104UL,
+ dk4ma_um_sub(
+ dk4ma_um_mul((dk4_um_t)8UL, (dk4_um_t)isz, &er),
+ (dk4_um_t)1UL,
+ &er
+ ),
+ &er
+ );
+ if ((dk4_um_t)0UL != (co % (dk4_um_t)100000UL)) {
+ co = co / (dk4_um_t)100000UL;
+ co++;
+ } else {
+ co = co / (dk4_um_t)100000UL;
+ }
+ co++;
+ if ((dk4_um_t)(SIZE_MAX) >= co) {
+ back = (size_t)co;
+ } else {
+ back = (size_t)co;
+ er.ec = DK4_E_MATH_OVERFLOW;
+ }
+ } else {
+ co = dk4ma_um_mul(
+ (dk4_um_t)30104UL,
+ dk4ma_um_mul((dk4_um_t)8UL, (dk4_um_t)isz, &er),
+ &er
+ );
+ if ((dk4_um_t)0UL != (co % (dk4_um_t)100000UL)) {
+ co = co / (dk4_um_t)100000UL;
+ co++;
+ } else {
+ co = co / (dk4_um_t)100000UL;
+ }
+ if ((dk4_um_t)(SIZE_MAX) >= co) {
+ back = (size_t)co;
+ } else {
+ back = (size_t)co;
+ er.ec = DK4_E_MATH_OVERFLOW;
+ }
+ }
+ if (DK4_E_NONE != er.ec) {
+ if (0 != (isz % 2)) { isz++; }
+ back = 5 * (isz / 2);
+ if (0 != sgn) { back++; }
+ }
+#endif
+ } else {
+ back = ((0 != sgn) ? 41 : 40);
+ }
+ } else {
+ back = ((0 != sgn) ? 21 : 20);
+ }
+ } else {
+ back = ((0 != sgn) ? 11 : 10);
+ }
+ } else {
+ back = ((0 != sgn) ? 6 : 5);
+ }
+ } else {
+ back = ((0 != sgn) ? 4 : 3);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4numl.ctr b/support/dktools/dk4numl.ctr
new file mode 100644
index 0000000000..5e97883bca
--- /dev/null
+++ b/support/dktools/dk4numl.ctr
@@ -0,0 +1,135 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Text representation length for numbers.
+ When showing information in a table one needs to know the length
+ of each field.
+ This module provides the dk4numlength() funtion to find the string
+ length needed for an integer value of a given size (number of bytes).
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Find number of digits for data type.
+ @param isz Integer data type size in bytes.
+ @param sgn Flag: Signed data type (0=unsigned, other=signed).
+ @return Maximum string length used when data is shown as text.
+*/
+size_t
+dk4numlength(size_t isz, int sgn);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4error.h"
+#include "dk4numl.h"
+#include "dk4maadu.h"
+
+size_t
+dk4numlength(size_t isz, int sgn)
+{
+ dk4_er_t er;
+ dk4_um_t co;
+ size_t back = 0;
+ if (1 < isz) {
+ if (2 < isz) {
+ if (4 < isz) {
+ if (8 < isz) {
+ if (16 < isz) {
+#if VERSION_BEFORE_20141122
+ if (0 != (isz % 2)) { isz++; }
+ back = 5 * (isz / 2);
+ if (0 != sgn) { back++; }
+#else
+ dk4error_init(&er);
+ if (0 != sgn) {
+ co = dk4ma_um_mul(
+ (dk4_um_t)30104UL,
+ dk4ma_um_sub(
+ dk4ma_um_mul((dk4_um_t)8UL, (dk4_um_t)isz, &er),
+ (dk4_um_t)1UL,
+ &er
+ ),
+ &er
+ );
+ if ((dk4_um_t)0UL != (co % (dk4_um_t)100000UL)) {
+ co = co / (dk4_um_t)100000UL;
+ co++;
+ } else {
+ co = co / (dk4_um_t)100000UL;
+ }
+ co++;
+ if ((dk4_um_t)(SIZE_MAX) >= co) {
+ back = (size_t)co;
+ } else {
+ back = (size_t)co;
+ er.ec = DK4_E_MATH_OVERFLOW;
+ }
+ } else {
+ co = dk4ma_um_mul(
+ (dk4_um_t)30104UL,
+ dk4ma_um_mul((dk4_um_t)8UL, (dk4_um_t)isz, &er),
+ &er
+ );
+ if ((dk4_um_t)0UL != (co % (dk4_um_t)100000UL)) {
+ co = co / (dk4_um_t)100000UL;
+ co++;
+ } else {
+ co = co / (dk4_um_t)100000UL;
+ }
+ if ((dk4_um_t)(SIZE_MAX) >= co) {
+ back = (size_t)co;
+ } else {
+ back = (size_t)co;
+ er.ec = DK4_E_MATH_OVERFLOW;
+ }
+ }
+ if (DK4_E_NONE != er.ec) {
+ if (0 != (isz % 2)) { isz++; }
+ back = 5 * (isz / 2);
+ if (0 != sgn) { back++; }
+ }
+#endif
+ } else {
+ back = ((0 != sgn) ? 41 : 40);
+ }
+ } else {
+ back = ((0 != sgn) ? 21 : 20);
+ }
+ } else {
+ back = ((0 != sgn) ? 11 : 10);
+ }
+ } else {
+ back = ((0 != sgn) ? 6 : 5);
+ }
+ } else {
+ back = ((0 != sgn) ? 4 : 3);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4numl.h b/support/dktools/dk4numl.h
new file mode 100644
index 0000000000..485f76bea6
--- /dev/null
+++ b/support/dktools/dk4numl.h
@@ -0,0 +1,79 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4numl.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4NUML_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4NUML_H_INCLUDED 1
+
+
+#line 10 "dk4numl.ctr"
+
+/** @file
+ Text representation length for numbers.
+ When showing information in a table one needs to know the length
+ of each field.
+ This module provides the dk4numlength() funtion to find the string
+ length needed for an integer value of a given size (number of bytes).
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Find number of digits for data type.
+ @param isz Integer data type size in bytes.
+ @param sgn Flag: Signed data type (0=unsigned, other=signed).
+ @return Maximum string length used when data is shown as text.
+*/
+size_t
+dk4numlength(size_t isz, int sgn);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4opt.c b/support/dktools/dk4opt.c
new file mode 100644
index 0000000000..d625f62430
--- /dev/null
+++ b/support/dktools/dk4opt.c
@@ -0,0 +1,235 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4opt.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4opt.c The dk4opt module.
+*/
+
+
+#line 303 "dk4opt.ctr"
+
+
+
+#include "dk4opt.h"
+#include "dk4strd.h"
+#include "dk4mem.h"
+
+
+
+
+
+#line 313 "dk4opt.ctr"
+
+
+
+/** Compare two options by short option.
+ @param olp Left option structure.
+ @param orp Right option structure.
+ @return Comparison result.
+*/
+static
+int
+dk4option_short_compare(const dk4_option_t *olp, const dk4_option_t *orp)
+{
+ int back = 0;
+ if ((olp->spec).c > (orp->spec).c) {
+ back = 1;
+ } else {
+ if ((olp->spec).c < (orp->spec).c) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Compare two options by long option.
+ @param olp Left option structure.
+ @param orp Right option structure.
+ @return Comparison result.
+*/
+static
+int
+dk4option_long_compare(const dk4_option_t *olp, const dk4_option_t *orp)
+{
+ int back = 0;
+ if (NULL != (olp->spec).longopt) {
+ if (NULL != (orp->spec).longopt) {
+ back = dk4str_cmp((olp->spec).longopt, (orp->spec).longopt);
+ if (-1 > back) back = -1;
+ if ( 1 < back) back = 1;
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != (orp->spec).longopt) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4option_compare(const void *l, const void *r, int cr)
+{
+ const dk4_option_t *olp;
+ const dk4_option_t *orp;
+ const dkChar *cp;
+
+ int back = 0;
+ if (NULL != l) {
+ olp = (const dk4_option_t *)l;
+ if (NULL != r) {
+ switch (cr) {
+ case 3: {
+ cp = (const dkChar *)r;
+ if (NULL != (olp->spec).longopt) {
+ back = dk4str_cmp((olp->spec).longopt, cp);
+ if (-1 > back) back = -1;
+ if ( 1 < back) back = 1;
+ } else {
+ back = -1;
+ }
+ } break;
+ case 2: {
+ orp = (const dk4_option_t *)r;
+ back = dk4option_long_compare(olp, orp);
+ if (0 == back) {
+ back = dk4option_short_compare(olp, orp);
+ }
+ } break;
+ case 1: {
+ cp = (const dkChar *)r;
+ if ((olp->spec).c > *cp) {
+ back = 1;
+ } else {
+ if ((olp->spec).c < *cp) {
+ back = -1;
+ }
+ }
+ } break;
+ default: {
+ orp = (const dk4_option_t *)r;
+ back = dk4option_short_compare(olp, orp);
+ if (0 == back) {
+ back = dk4option_long_compare(olp, orp);
+ }
+ } break;
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != r) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+void
+dk4opt_close(dk4_option_t *optptr)
+{
+
+
+#line 430 "dk4opt.ctr"
+ if (NULL != optptr) {
+
+#line 431 "dk4opt.ctr"
+ /*
+ We can not sanitize the memory for option name and option value
+ as the option name is constant and the option value was provided
+ by the shell and is owned by the shell.
+ */
+ (optptr->spec).longopt = NULL;
+ (optptr->val).t = NULL;
+ dk4mem_free(optptr);
+ }
+
+
+#line 441 "dk4opt.ctr"
+}
+
+
+
+dk4_option_t *
+dk4opt_open(const dk4_option_specification_t *spec, dk4_er_t *erp)
+{
+ dk4_option_t *back = NULL;
+ if (NULL != spec) {
+ if ((NULL != spec->longopt) || (dkT('\0') != spec->c)) {
+ back = dk4mem_new(dk4_option_t,1,NULL);
+ if (NULL != back) {
+ DK4_MEMCPY(&(back->spec),spec,sizeof(dk4_option_specification_t));
+ back->found = 0;
+ switch ((back->spec).argtype) {
+ case DK4_OPT_ARG_BOOL: {
+ (back->val).b = 0;
+ } break;
+ case DK4_OPT_ARG_SIZE: {
+ (back->val).s = 0;
+ } break;
+ case DK4_OPT_ARG_INT: {
+ (back->val).i = (dk4_im_t)0L;
+ } break;
+ case DK4_OPT_ARG_UNSIGNED: {
+ (back->val).u = (dk4_um_t)0UL;
+ } break;
+ case DK4_OPT_ARG_DOUBLE: {
+ (back->val).d = 0.0;
+ } break;
+ case DK4_OPT_ARG_STRING: {
+ (back->val).t = NULL;
+ } break;
+ }
+ } else {
+ dk4error_set_elsize_nelem(
+ erp, DK4_E_MEMORY_ALLOCATION_FAILED, sizeof(dk4_option_t), 1
+ );
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4opt.ctr b/support/dktools/dk4opt.ctr
new file mode 100644
index 0000000000..cca3eae8c4
--- /dev/null
+++ b/support/dktools/dk4opt.ctr
@@ -0,0 +1,489 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Process command line option in simple programs.
+ You can specify a set of allowed options including the option
+ arguments types. After processing command line arguments you
+ can simply check which options were used and obtain option
+ argument values.
+*/
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+/** Option specification for application module.
+*/
+typedef struct {
+ dkChar c; /**< Short option character. */
+ const dkChar *longopt; /**< Long option string. */
+ int argtype; /**< Argument type. */
+} dk4_option_specification_t;
+
+/** Option values can be different types.
+*/
+typedef union {
+ dkChar *t; /**< String value. */
+ double d; /**< Double value. */
+ dk4_im_t i; /**< Integer value. */
+ dk4_um_t u; /**< Unsigned integer value. */
+ size_t s; /**< Size value. */
+ int b; /**< Boolean value. */
+} dk4_option_value_t;
+
+/** Option with value.
+*/
+typedef struct {
+ dk4_option_specification_t spec; /**< Option specification. */
+ dk4_option_value_t val; /**< Option value. */
+ int found; /**< Flag: Option found in cmd line. */
+} dk4_option_t;
+
+
+/** Argument types.
+*/
+enum {
+ /** No argument expected.
+ */
+DK4_OPT_ARG_NONE = 1,
+
+ /** Boolean value expected.
+ */
+DK4_OPT_ARG_BOOL ,
+
+ /** Size specification expected.
+ */
+DK4_OPT_ARG_SIZE ,
+
+ /** Signed integer value expected.
+ */
+DK4_OPT_ARG_INT ,
+
+ /** Unsigned integer value expected.
+ */
+DK4_OPT_ARG_UNSIGNED ,
+
+ /** Double value expected.
+ */
+DK4_OPT_ARG_DOUBLE ,
+
+ /** String value expected.
+ */
+DK4_OPT_ARG_STRING
+};
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Create option object.
+ CRT on Windows: Optional.
+ @param spec Specifications for the option.
+ @param erp Error report, may be NULL.
+ @return Pointer to new option object on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if spec is NULL,
+ - DK4_E_SYNTAX<br>
+ if neither short nor long option is defined in spec,
+ - DK4_E_MEMORY<br>
+ if the memory allocation failed.
+*/
+dk4_option_t *
+dk4opt_open(const dk4_option_specification_t *spec, dk4_er_t *erp);
+
+/** Retrieve boolean value (as int) from option.
+ CRT on Windows: Optional.
+ @param dptr Pointer to destination variable.
+ @param optptr Option to retrieve value from.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or optptr is NULL or optptr is configured for another data
+ type,
+ - DK4_E_NOT_FOUND<br>
+ if the option was not specified on the command line,
+ - DK4_E_SYNTAX<br>
+ if a string is stored not representing a boolean or the option was
+ configured with an incompatible type.
+*/
+int
+dk4opt_get_bool(int *dptr, dk4_option_t *optptr, dk4_er_t *erp);
+
+/** Retrieve size_t value from option.
+ CRT on Windows: Optional.
+ @param dptr Pointer to destination variable.
+ @param optptr Option to retrieve value from.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or optptr is NULL or optptr is configured for another data
+ type,
+ - DK4_E_NOT_FOUND<br>
+ if the option was not specified on the command line,
+ - DK4_E_SYNTAX<br>
+ if the option was configured for an incompatible type or the option
+ argument string can not be converted to a size_t,
+ - DK4_E_MATH_OVERFLOW<br>
+ if the option was configured for another numeric type and conversion
+ results in an overflow.
+*/
+int
+dk4opt_get_size(size_t *dptr, dk4_option_t *optptr, dk4_er_t *erp);
+
+/** Retrieve integer value (dk4_im_t) from option.
+ CRT on Windows: Optional.
+ @param dptr Pointer to destination variable.
+ @param optptr Option to retrieve value from.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or optptr is NULL or optptr is configured for another data
+ type,
+ - DK4_E_NOT_FOUND<br>
+ if the option was not specified on the command line,
+ - DK4_E_SYNTAX<br>
+ if the option was configured for an incompatible type or the option
+ argument string does not represent an integer number,
+ - DK4_E_MATH_OVERFLOW<br>
+ if the option was configured for another numeric type and conversion
+ results in an overflow.
+*/
+int
+dk4opt_get_int(dk4_im_t *dptr, dk4_option_t *optptr, dk4_er_t *erp);
+
+/** Retrieve unsigned integer value (dk4_um_t) from option.
+ CRT on Windows: Optional.
+ @param dptr Pointer to destination variable.
+ @param optptr Option to retrieve value from.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or optptr is NULL or optptr is configured for another data
+ type,
+ - DK4_E_NOT_FOUND<br>
+ if the option was not specified on the command line,
+ - DK4_E_SYNTAX<br>
+ if the option was configured for an incompatible data type or the
+ option string does not represent an integer number,
+ - DK4_E_MATH_OVERFLOW<br>
+ if the option was configured for an incompatible numeric type and a
+ negative value is stored.
+*/
+int
+dk4opt_get_unsigned(dk4_um_t *dptr, dk4_option_t *optptr, dk4_er_t *erp);
+
+/** Retrieve double value from option.
+ CRT on Windows: Optional.
+ @param dptr Pointer to destination variable.
+ @param optptr Option to retrieve value from.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or optptr is NULL or optptr is configured for another data
+ type,
+ - DK4_E_NOT_FOUND<br>
+ if the option was not specified on the command line,
+ - DK4_E_SYNTAX<br>
+ if the option was configured for an incompatible data type or the
+ string stored as option argument does not represent a double number.
+*/
+int
+dk4opt_get_double(double *dptr, dk4_option_t *optptr, dk4_er_t *erp);
+
+/** Retrieve string value from option.
+ CRT on Windows: Optional, disabling CRT reduces functionality
+ as we can not convert double values to strings.
+ @param dptr Pointer to destination buffer.
+ @param szdptr Size of destination buffer (number of dkChar).
+ @param optptr Option to retrieve value from.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or optptr is NULL or optptr is configured for another data
+ type,
+ - DK4_E_NOT_FOUND<br>
+ if the option was not specified on the command line.
+ - DK4_E_SYNTAX<br>
+ if the option was configured for an incompatible data type,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the destination buffer is too small to hold a conversion result,
+ - DK4_E_NOT_SUPPORTED<br>
+ if the option was configured for the double data type and the use of
+ sprintf() was denied during setup.
+*/
+int
+dk4opt_get_string(
+ dkChar *dptr, size_t szdptr, dk4_option_t *optptr, dk4_er_t *erp
+);
+
+/** Destroy option object, release memory.
+ CRT on Windows: Optional.
+ @param optptr Option object to destroy.
+*/
+void
+dk4opt_close(dk4_option_t *optptr);
+
+/** Compare option against other option or char or string.
+ CRT on Windows: Optional.
+ @param l Left pointer, always an option.
+ @param r Right pointer, type depends on cr.
+ @param cr Comparison criteria:
+ 0=option/option by short character,
+ 1=option/character,
+ 2=option/option by long option text,
+ 3=option/text.
+ @return Comparison result.
+*/
+int
+dk4option_compare(const void *l, const void *r, int cr);
+
+/** Process command line options provided to the main function.
+ @param optptr Options array.
+ @param szoptptr Number of elements in array.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @param filenames Pointer array to store file names.
+ @param nfilenames Elements in array (in: size, out: used).
+ @param progname Flag: Argument 0 is program name.
+ @param logstderr Flag: Logging to stderr allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4opt_process_argv(
+ dk4_option_t *optptr,
+ size_t szoptptr,
+ int argc,
+ dkChar *argv[],
+ dkChar **filenames,
+ size_t *nfilenames,
+ int progname,
+ int logstderr,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+
+
+#include "dk4opt.h"
+#include "dk4strd.h"
+#include "dk4mem.h"
+
+
+
+$!trace-include
+
+
+
+/** Compare two options by short option.
+ @param olp Left option structure.
+ @param orp Right option structure.
+ @return Comparison result.
+*/
+static
+int
+dk4option_short_compare(const dk4_option_t *olp, const dk4_option_t *orp)
+{
+ int back = 0;
+ if ((olp->spec).c > (orp->spec).c) {
+ back = 1;
+ } else {
+ if ((olp->spec).c < (orp->spec).c) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Compare two options by long option.
+ @param olp Left option structure.
+ @param orp Right option structure.
+ @return Comparison result.
+*/
+static
+int
+dk4option_long_compare(const dk4_option_t *olp, const dk4_option_t *orp)
+{
+ int back = 0;
+ if (NULL != (olp->spec).longopt) {
+ if (NULL != (orp->spec).longopt) {
+ back = dk4str_cmp((olp->spec).longopt, (orp->spec).longopt);
+ if (-1 > back) back = -1;
+ if ( 1 < back) back = 1;
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != (orp->spec).longopt) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4option_compare(const void *l, const void *r, int cr)
+{
+ const dk4_option_t *olp;
+ const dk4_option_t *orp;
+ const dkChar *cp;
+
+ int back = 0;
+ if (NULL != l) {
+ olp = (const dk4_option_t *)l;
+ if (NULL != r) {
+ switch (cr) {
+ case 3: {
+ cp = (const dkChar *)r;
+ if (NULL != (olp->spec).longopt) {
+ back = dk4str_cmp((olp->spec).longopt, cp);
+ if (-1 > back) back = -1;
+ if ( 1 < back) back = 1;
+ } else {
+ back = -1;
+ }
+ } break;
+ case 2: {
+ orp = (const dk4_option_t *)r;
+ back = dk4option_long_compare(olp, orp);
+ if (0 == back) {
+ back = dk4option_short_compare(olp, orp);
+ }
+ } break;
+ case 1: {
+ cp = (const dkChar *)r;
+ if ((olp->spec).c > *cp) {
+ back = 1;
+ } else {
+ if ((olp->spec).c < *cp) {
+ back = -1;
+ }
+ }
+ } break;
+ default: {
+ orp = (const dk4_option_t *)r;
+ back = dk4option_short_compare(olp, orp);
+ if (0 == back) {
+ back = dk4option_long_compare(olp, orp);
+ }
+ } break;
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != r) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+void
+dk4opt_close(dk4_option_t *optptr)
+{
+ $? "+ dk4opt_close"
+ if (NULL != optptr) { $? ". valid option ptr"
+ /*
+ We can not sanitize the memory for option name and option value
+ as the option name is constant and the option value was provided
+ by the shell and is owned by the shell.
+ */
+ (optptr->spec).longopt = NULL;
+ (optptr->val).t = NULL;
+ dk4mem_free(optptr);
+ }
+ $? "- dk4opt_close"
+}
+
+
+
+dk4_option_t *
+dk4opt_open(const dk4_option_specification_t *spec, dk4_er_t *erp)
+{
+ dk4_option_t *back = NULL;
+ if (NULL != spec) {
+ if ((NULL != spec->longopt) || (dkT('\0') != spec->c)) {
+ back = dk4mem_new(dk4_option_t,1,NULL);
+ if (NULL != back) {
+ DK4_MEMCPY(&(back->spec),spec,sizeof(dk4_option_specification_t));
+ back->found = 0;
+ switch ((back->spec).argtype) {
+ case DK4_OPT_ARG_BOOL: {
+ (back->val).b = 0;
+ } break;
+ case DK4_OPT_ARG_SIZE: {
+ (back->val).s = 0;
+ } break;
+ case DK4_OPT_ARG_INT: {
+ (back->val).i = (dk4_im_t)0L;
+ } break;
+ case DK4_OPT_ARG_UNSIGNED: {
+ (back->val).u = (dk4_um_t)0UL;
+ } break;
+ case DK4_OPT_ARG_DOUBLE: {
+ (back->val).d = 0.0;
+ } break;
+ case DK4_OPT_ARG_STRING: {
+ (back->val).t = NULL;
+ } break;
+ }
+ } else {
+ dk4error_set_elsize_nelem(
+ erp, DK4_E_MEMORY_ALLOCATION_FAILED, sizeof(dk4_option_t), 1
+ );
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4opt.h b/support/dktools/dk4opt.h
new file mode 100644
index 0000000000..ef9dd297f8
--- /dev/null
+++ b/support/dktools/dk4opt.h
@@ -0,0 +1,335 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4opt.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4OPT_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4OPT_H_INCLUDED 1
+
+
+#line 10 "dk4opt.ctr"
+
+/** @file
+ Process command line option in simple programs.
+ You can specify a set of allowed options including the option
+ arguments types. After processing command line arguments you
+ can simply check which options were used and obtain option
+ argument values.
+*/
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+/** Option specification for application module.
+*/
+typedef struct {
+ dkChar c; /**< Short option character. */
+ const dkChar *longopt; /**< Long option string. */
+ int argtype; /**< Argument type. */
+} dk4_option_specification_t;
+
+/** Option values can be different types.
+*/
+typedef union {
+ dkChar *t; /**< String value. */
+ double d; /**< Double value. */
+ dk4_im_t i; /**< Integer value. */
+ dk4_um_t u; /**< Unsigned integer value. */
+ size_t s; /**< Size value. */
+ int b; /**< Boolean value. */
+} dk4_option_value_t;
+
+/** Option with value.
+*/
+typedef struct {
+ dk4_option_specification_t spec; /**< Option specification. */
+ dk4_option_value_t val; /**< Option value. */
+ int found; /**< Flag: Option found in cmd line. */
+} dk4_option_t;
+
+
+/** Argument types.
+*/
+enum {
+ /** No argument expected.
+ */
+DK4_OPT_ARG_NONE = 1,
+
+ /** Boolean value expected.
+ */
+DK4_OPT_ARG_BOOL ,
+
+ /** Size specification expected.
+ */
+DK4_OPT_ARG_SIZE ,
+
+ /** Signed integer value expected.
+ */
+DK4_OPT_ARG_INT ,
+
+ /** Unsigned integer value expected.
+ */
+DK4_OPT_ARG_UNSIGNED ,
+
+ /** Double value expected.
+ */
+DK4_OPT_ARG_DOUBLE ,
+
+ /** String value expected.
+ */
+DK4_OPT_ARG_STRING
+};
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Create option object.
+ CRT on Windows: Optional.
+ @param spec Specifications for the option.
+ @param erp Error report, may be NULL.
+ @return Pointer to new option object on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if spec is NULL,
+ - DK4_E_SYNTAX<br>
+ if neither short nor long option is defined in spec,
+ - DK4_E_MEMORY<br>
+ if the memory allocation failed.
+*/
+dk4_option_t *
+dk4opt_open(const dk4_option_specification_t *spec, dk4_er_t *erp);
+
+/** Retrieve boolean value (as int) from option.
+ CRT on Windows: Optional.
+ @param dptr Pointer to destination variable.
+ @param optptr Option to retrieve value from.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or optptr is NULL or optptr is configured for another data
+ type,
+ - DK4_E_NOT_FOUND<br>
+ if the option was not specified on the command line,
+ - DK4_E_SYNTAX<br>
+ if a string is stored not representing a boolean or the option was
+ configured with an incompatible type.
+*/
+int
+dk4opt_get_bool(int *dptr, dk4_option_t *optptr, dk4_er_t *erp);
+
+/** Retrieve size_t value from option.
+ CRT on Windows: Optional.
+ @param dptr Pointer to destination variable.
+ @param optptr Option to retrieve value from.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or optptr is NULL or optptr is configured for another data
+ type,
+ - DK4_E_NOT_FOUND<br>
+ if the option was not specified on the command line,
+ - DK4_E_SYNTAX<br>
+ if the option was configured for an incompatible type or the option
+ argument string can not be converted to a size_t,
+ - DK4_E_MATH_OVERFLOW<br>
+ if the option was configured for another numeric type and conversion
+ results in an overflow.
+*/
+int
+dk4opt_get_size(size_t *dptr, dk4_option_t *optptr, dk4_er_t *erp);
+
+/** Retrieve integer value (dk4_im_t) from option.
+ CRT on Windows: Optional.
+ @param dptr Pointer to destination variable.
+ @param optptr Option to retrieve value from.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or optptr is NULL or optptr is configured for another data
+ type,
+ - DK4_E_NOT_FOUND<br>
+ if the option was not specified on the command line,
+ - DK4_E_SYNTAX<br>
+ if the option was configured for an incompatible type or the option
+ argument string does not represent an integer number,
+ - DK4_E_MATH_OVERFLOW<br>
+ if the option was configured for another numeric type and conversion
+ results in an overflow.
+*/
+int
+dk4opt_get_int(dk4_im_t *dptr, dk4_option_t *optptr, dk4_er_t *erp);
+
+/** Retrieve unsigned integer value (dk4_um_t) from option.
+ CRT on Windows: Optional.
+ @param dptr Pointer to destination variable.
+ @param optptr Option to retrieve value from.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or optptr is NULL or optptr is configured for another data
+ type,
+ - DK4_E_NOT_FOUND<br>
+ if the option was not specified on the command line,
+ - DK4_E_SYNTAX<br>
+ if the option was configured for an incompatible data type or the
+ option string does not represent an integer number,
+ - DK4_E_MATH_OVERFLOW<br>
+ if the option was configured for an incompatible numeric type and a
+ negative value is stored.
+*/
+int
+dk4opt_get_unsigned(dk4_um_t *dptr, dk4_option_t *optptr, dk4_er_t *erp);
+
+/** Retrieve double value from option.
+ CRT on Windows: Optional.
+ @param dptr Pointer to destination variable.
+ @param optptr Option to retrieve value from.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or optptr is NULL or optptr is configured for another data
+ type,
+ - DK4_E_NOT_FOUND<br>
+ if the option was not specified on the command line,
+ - DK4_E_SYNTAX<br>
+ if the option was configured for an incompatible data type or the
+ string stored as option argument does not represent a double number.
+*/
+int
+dk4opt_get_double(double *dptr, dk4_option_t *optptr, dk4_er_t *erp);
+
+/** Retrieve string value from option.
+ CRT on Windows: Optional, disabling CRT reduces functionality
+ as we can not convert double values to strings.
+ @param dptr Pointer to destination buffer.
+ @param szdptr Size of destination buffer (number of dkChar).
+ @param optptr Option to retrieve value from.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or optptr is NULL or optptr is configured for another data
+ type,
+ - DK4_E_NOT_FOUND<br>
+ if the option was not specified on the command line.
+ - DK4_E_SYNTAX<br>
+ if the option was configured for an incompatible data type,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the destination buffer is too small to hold a conversion result,
+ - DK4_E_NOT_SUPPORTED<br>
+ if the option was configured for the double data type and the use of
+ sprintf() was denied during setup.
+*/
+int
+dk4opt_get_string(
+ dkChar *dptr, size_t szdptr, dk4_option_t *optptr, dk4_er_t *erp
+);
+
+/** Destroy option object, release memory.
+ CRT on Windows: Optional.
+ @param optptr Option object to destroy.
+*/
+void
+dk4opt_close(dk4_option_t *optptr);
+
+/** Compare option against other option or char or string.
+ CRT on Windows: Optional.
+ @param l Left pointer, always an option.
+ @param r Right pointer, type depends on cr.
+ @param cr Comparison criteria:
+ 0=option/option by short character,
+ 1=option/character,
+ 2=option/option by long option text,
+ 3=option/text.
+ @return Comparison result.
+*/
+int
+dk4option_compare(const void *l, const void *r, int cr);
+
+/** Process command line options provided to the main function.
+ @param optptr Options array.
+ @param szoptptr Number of elements in array.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @param filenames Pointer array to store file names.
+ @param nfilenames Elements in array (in: size, out: used).
+ @param progname Flag: Argument 0 is program name.
+ @param logstderr Flag: Logging to stderr allowed.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4opt_process_argv(
+ dk4_option_t *optptr,
+ size_t szoptptr,
+ int argc,
+ dkChar *argv[],
+ dkChar **filenames,
+ size_t *nfilenames,
+ int progname,
+ int logstderr,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4opt01.c b/support/dktools/dk4opt01.c
new file mode 100644
index 0000000000..bb215c8446
--- /dev/null
+++ b/support/dktools/dk4opt01.c
@@ -0,0 +1,117 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4opt01.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4opt01.c The dk4opt01 module.
+*/
+
+
+#line 10 "dk4opt01.ctr"
+
+#include "dk4opt.h"
+#include "dk4strd.h"
+#include "dk4mem.h"
+
+
+
+
+
+#line 18 "dk4opt01.ctr"
+
+
+
+int
+dk4opt_get_bool(int *dptr, dk4_option_t *optptr, dk4_er_t *erp)
+{
+ int back = 0;
+ if ((NULL != dptr) && (NULL != optptr)) {
+ if (0 != optptr->found) {
+ switch ((optptr->spec).argtype) {
+ case DK4_OPT_ARG_BOOL: {
+ *dptr = (optptr->val).b;
+ back = 1;
+ } break;
+ case DK4_OPT_ARG_SIZE: {
+ if (0 < (optptr->val).s) {
+ *dptr = 1;
+ } else {
+ *dptr = 0;
+ }
+ back = 1;
+ } break;
+ case DK4_OPT_ARG_INT: {
+ if ((dk4_im_t)0L != (optptr->val).i) {
+ *dptr = 1;
+ } else {
+ *dptr = 0;
+ }
+ back = 1;
+ } break;
+ case DK4_OPT_ARG_UNSIGNED: {
+ if ((dk4_um_t)0UL < (optptr->val).u) {
+ *dptr = 1;
+ } else {
+ *dptr = 0;
+ }
+ back = 1;
+ } break;
+ case DK4_OPT_ARG_STRING: {
+ if (NULL != (optptr->val).t) {
+ if (dk4str_is_bool((optptr->val).t)) {
+ if (dk4str_is_on((optptr->val).t)) {
+ *dptr = 1;
+ } else {
+ *dptr = 0;
+ }
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } break;
+ default: {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4opt01.ctr b/support/dktools/dk4opt01.ctr
new file mode 100644
index 0000000000..d1f846af5f
--- /dev/null
+++ b/support/dktools/dk4opt01.ctr
@@ -0,0 +1,84 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4opt.h"
+#include "dk4strd.h"
+#include "dk4mem.h"
+
+
+
+$!trace-include
+
+
+
+int
+dk4opt_get_bool(int *dptr, dk4_option_t *optptr, dk4_er_t *erp)
+{
+ int back = 0;
+ if ((NULL != dptr) && (NULL != optptr)) {
+ if (0 != optptr->found) {
+ switch ((optptr->spec).argtype) {
+ case DK4_OPT_ARG_BOOL: {
+ *dptr = (optptr->val).b;
+ back = 1;
+ } break;
+ case DK4_OPT_ARG_SIZE: {
+ if (0 < (optptr->val).s) {
+ *dptr = 1;
+ } else {
+ *dptr = 0;
+ }
+ back = 1;
+ } break;
+ case DK4_OPT_ARG_INT: {
+ if ((dk4_im_t)0L != (optptr->val).i) {
+ *dptr = 1;
+ } else {
+ *dptr = 0;
+ }
+ back = 1;
+ } break;
+ case DK4_OPT_ARG_UNSIGNED: {
+ if ((dk4_um_t)0UL < (optptr->val).u) {
+ *dptr = 1;
+ } else {
+ *dptr = 0;
+ }
+ back = 1;
+ } break;
+ case DK4_OPT_ARG_STRING: {
+ if (NULL != (optptr->val).t) {
+ if (dk4str_is_bool((optptr->val).t)) {
+ if (dk4str_is_on((optptr->val).t)) {
+ *dptr = 1;
+ } else {
+ *dptr = 0;
+ }
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } break;
+ default: {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4opt02.c b/support/dktools/dk4opt02.c
new file mode 100644
index 0000000000..15d6f03963
--- /dev/null
+++ b/support/dktools/dk4opt02.c
@@ -0,0 +1,121 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4opt02.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4opt02.c The dk4opt02 module.
+*/
+
+
+#line 10 "dk4opt02.ctr"
+
+#include "dk4opt.h"
+#include "dk4strd.h"
+#include "dk4mem.h"
+#include "dk4maiddsz.h"
+
+
+
+
+
+#line 19 "dk4opt02.ctr"
+
+
+
+int
+dk4opt_get_size(size_t *dptr, dk4_option_t *optptr, dk4_er_t *erp)
+{
+ size_t val = 0;
+ int back = 0;
+ int res = 0;
+ if ((NULL != dptr) && (NULL != optptr)) {
+ if (0 != optptr->found) {
+ switch ((optptr->spec).argtype) {
+ case DK4_OPT_ARG_BOOL: {
+ if (0 != (optptr->val).b) {
+ *dptr = 1;
+ } else {
+ *dptr = 0;
+ }
+ back = 1;
+ } break;
+ case DK4_OPT_ARG_SIZE: {
+ *dptr = (optptr->val).s;
+ back = 1;
+ } break;
+ case DK4_OPT_ARG_INT: {
+ if (0 > (optptr->val).i) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ if ((dk4_um_t)SIZE_MAX < (dk4_um_t)((optptr->val).i)) {
+ *dptr = (size_t)((optptr->val).i);
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ } break;
+ case DK4_OPT_ARG_UNSIGNED: {
+ if ((dk4_um_t)SIZE_MAX >= (optptr->val).u) {
+ *dptr = (size_t)((optptr->val).u);
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } break;
+ case DK4_OPT_ARG_STRING: {
+ if (NULL != (optptr->val).t) {
+ res = dk4ma_input_dk_dec_size_t(
+ &val, (optptr->val).t, NULL, 1, erp
+ );
+ if (0 != res) {
+ *dptr = val;
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } break;
+ default: {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4opt02.ctr b/support/dktools/dk4opt02.ctr
new file mode 100644
index 0000000000..33e0303df1
--- /dev/null
+++ b/support/dktools/dk4opt02.ctr
@@ -0,0 +1,88 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4opt.h"
+#include "dk4strd.h"
+#include "dk4mem.h"
+#include "dk4maiddsz.h"
+
+
+
+$!trace-include
+
+
+
+int
+dk4opt_get_size(size_t *dptr, dk4_option_t *optptr, dk4_er_t *erp)
+{
+ size_t val = 0;
+ int back = 0;
+ int res = 0;
+ if ((NULL != dptr) && (NULL != optptr)) {
+ if (0 != optptr->found) {
+ switch ((optptr->spec).argtype) {
+ case DK4_OPT_ARG_BOOL: {
+ if (0 != (optptr->val).b) {
+ *dptr = 1;
+ } else {
+ *dptr = 0;
+ }
+ back = 1;
+ } break;
+ case DK4_OPT_ARG_SIZE: {
+ *dptr = (optptr->val).s;
+ back = 1;
+ } break;
+ case DK4_OPT_ARG_INT: {
+ if (0 > (optptr->val).i) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ if ((dk4_um_t)SIZE_MAX < (dk4_um_t)((optptr->val).i)) {
+ *dptr = (size_t)((optptr->val).i);
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ } break;
+ case DK4_OPT_ARG_UNSIGNED: {
+ if ((dk4_um_t)SIZE_MAX >= (optptr->val).u) {
+ *dptr = (size_t)((optptr->val).u);
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } break;
+ case DK4_OPT_ARG_STRING: {
+ if (NULL != (optptr->val).t) {
+ res = dk4ma_input_dk_dec_size_t(
+ &val, (optptr->val).t, NULL, 1, erp
+ );
+ if (0 != res) {
+ *dptr = val;
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } break;
+ default: {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4opt03.c b/support/dktools/dk4opt03.c
new file mode 100644
index 0000000000..96ccff1caa
--- /dev/null
+++ b/support/dktools/dk4opt03.c
@@ -0,0 +1,116 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4opt03.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4opt03.c The dk4opt03 module.
+*/
+
+
+#line 10 "dk4opt03.ctr"
+
+#include "dk4opt.h"
+#include "dk4strd.h"
+#include "dk4mem.h"
+#include "dk4numco.h"
+#include "dk4maidddi.h"
+
+
+
+
+
+#line 20 "dk4opt03.ctr"
+
+
+
+int
+dk4opt_get_int(dk4_im_t *dptr, dk4_option_t *optptr, dk4_er_t *erp)
+{
+ dk4_im_t val = (dk4_im_t)0L;
+ int back = 0;
+ int res = 0;
+ if ((NULL != dptr) && (NULL != optptr)) {
+ if (0 != optptr->found) {
+ switch ((optptr->spec).argtype) {
+ case DK4_OPT_ARG_BOOL: {
+ if (0 != (optptr->val).b) {
+ *dptr = (dk4_im_t)1L;
+ } else {
+ *dptr = (dk4_im_t)0L;
+ }
+ back = 1;
+ } break;
+ case DK4_OPT_ARG_SIZE: {
+ if ((dk4_um_t)DK4_IM_MAX >= (dk4_um_t)((optptr->val).s)) {
+ *dptr = (dk4_im_t)((optptr->val).s);
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } break;
+ case DK4_OPT_ARG_INT: {
+ *dptr = (optptr->val).i;
+ back = 1;
+ } break;
+ case DK4_OPT_ARG_UNSIGNED: {
+ if ((dk4_um_t)DK4_IM_MAX >= (dk4_um_t)((optptr->val).u)) {
+ *dptr = (dk4_im_t)((optptr->val).u);
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } break;
+ case DK4_OPT_ARG_STRING: {
+ if (NULL != (optptr->val).t) {
+ res = dk4ma_input_dk_dec_dk4_im_t(
+ &val, (optptr->val).t, NULL, 1, erp
+ );
+ if (0 != res) {
+ *dptr = val;
+ back = 1;
+ }
+ }
+ } break;
+ default: {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4opt03.ctr b/support/dktools/dk4opt03.ctr
new file mode 100644
index 0000000000..8d85332dc2
--- /dev/null
+++ b/support/dktools/dk4opt03.ctr
@@ -0,0 +1,83 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4opt.h"
+#include "dk4strd.h"
+#include "dk4mem.h"
+#include "dk4numco.h"
+#include "dk4maidddi.h"
+
+
+
+$!trace-include
+
+
+
+int
+dk4opt_get_int(dk4_im_t *dptr, dk4_option_t *optptr, dk4_er_t *erp)
+{
+ dk4_im_t val = (dk4_im_t)0L;
+ int back = 0;
+ int res = 0;
+ if ((NULL != dptr) && (NULL != optptr)) {
+ if (0 != optptr->found) {
+ switch ((optptr->spec).argtype) {
+ case DK4_OPT_ARG_BOOL: {
+ if (0 != (optptr->val).b) {
+ *dptr = (dk4_im_t)1L;
+ } else {
+ *dptr = (dk4_im_t)0L;
+ }
+ back = 1;
+ } break;
+ case DK4_OPT_ARG_SIZE: {
+ if ((dk4_um_t)DK4_IM_MAX >= (dk4_um_t)((optptr->val).s)) {
+ *dptr = (dk4_im_t)((optptr->val).s);
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } break;
+ case DK4_OPT_ARG_INT: {
+ *dptr = (optptr->val).i;
+ back = 1;
+ } break;
+ case DK4_OPT_ARG_UNSIGNED: {
+ if ((dk4_um_t)DK4_IM_MAX >= (dk4_um_t)((optptr->val).u)) {
+ *dptr = (dk4_im_t)((optptr->val).u);
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } break;
+ case DK4_OPT_ARG_STRING: {
+ if (NULL != (optptr->val).t) {
+ res = dk4ma_input_dk_dec_dk4_im_t(
+ &val, (optptr->val).t, NULL, 1, erp
+ );
+ if (0 != res) {
+ *dptr = val;
+ back = 1;
+ }
+ }
+ } break;
+ default: {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4opt04.c b/support/dktools/dk4opt04.c
new file mode 100644
index 0000000000..db3ea28c44
--- /dev/null
+++ b/support/dktools/dk4opt04.c
@@ -0,0 +1,113 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4opt04.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4opt04.c The dk4opt04 module.
+*/
+
+
+#line 10 "dk4opt04.ctr"
+
+#include "dk4opt.h"
+#include "dk4strd.h"
+#include "dk4mem.h"
+#include "dk4maidddu.h"
+
+
+
+
+
+#line 19 "dk4opt04.ctr"
+
+
+
+int
+dk4opt_get_unsigned(dk4_um_t *dptr, dk4_option_t *optptr, dk4_er_t *erp)
+{
+ dk4_um_t val = (dk4_um_t)0UL;
+ int back = 0;
+ int res = 0;
+ if ((NULL != dptr) && (NULL != optptr)) {
+ if (0 != optptr->found) {
+ switch ((optptr->spec).argtype) {
+ case DK4_OPT_ARG_BOOL: {
+ if (0 != (optptr->val).b) {
+ *dptr = (dk4_um_t)1UL;
+ } else {
+ *dptr = (dk4_um_t)0UL;
+ }
+ back = 1;
+ } break;
+ case DK4_OPT_ARG_SIZE: {
+ *dptr = (dk4_um_t)((optptr->val).s);
+ back = 1;
+ } break;
+ case DK4_OPT_ARG_INT: {
+ if (0 <= (optptr->val).i) {
+ *dptr = (dk4_um_t)((optptr->val).i);
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } break;
+ case DK4_OPT_ARG_UNSIGNED: {
+ *dptr = (optptr->val).u;
+ back = 1;
+ } break;
+ case DK4_OPT_ARG_STRING: {
+ if (NULL != (optptr->val).t) {
+ res = dk4ma_input_dk_dec_dk4_um_t(
+ &val, (optptr->val).t, NULL, 1, erp
+ );
+ if (0 != res) {
+ *dptr = val;
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } break;
+ default: {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4opt04.ctr b/support/dktools/dk4opt04.ctr
new file mode 100644
index 0000000000..63c6177dda
--- /dev/null
+++ b/support/dktools/dk4opt04.ctr
@@ -0,0 +1,80 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4opt.h"
+#include "dk4strd.h"
+#include "dk4mem.h"
+#include "dk4maidddu.h"
+
+
+
+$!trace-include
+
+
+
+int
+dk4opt_get_unsigned(dk4_um_t *dptr, dk4_option_t *optptr, dk4_er_t *erp)
+{
+ dk4_um_t val = (dk4_um_t)0UL;
+ int back = 0;
+ int res = 0;
+ if ((NULL != dptr) && (NULL != optptr)) {
+ if (0 != optptr->found) {
+ switch ((optptr->spec).argtype) {
+ case DK4_OPT_ARG_BOOL: {
+ if (0 != (optptr->val).b) {
+ *dptr = (dk4_um_t)1UL;
+ } else {
+ *dptr = (dk4_um_t)0UL;
+ }
+ back = 1;
+ } break;
+ case DK4_OPT_ARG_SIZE: {
+ *dptr = (dk4_um_t)((optptr->val).s);
+ back = 1;
+ } break;
+ case DK4_OPT_ARG_INT: {
+ if (0 <= (optptr->val).i) {
+ *dptr = (dk4_um_t)((optptr->val).i);
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } break;
+ case DK4_OPT_ARG_UNSIGNED: {
+ *dptr = (optptr->val).u;
+ back = 1;
+ } break;
+ case DK4_OPT_ARG_STRING: {
+ if (NULL != (optptr->val).t) {
+ res = dk4ma_input_dk_dec_dk4_um_t(
+ &val, (optptr->val).t, NULL, 1, erp
+ );
+ if (0 != res) {
+ *dptr = val;
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } break;
+ default: {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4opt05.c b/support/dktools/dk4opt05.c
new file mode 100644
index 0000000000..b2ac4db59d
--- /dev/null
+++ b/support/dktools/dk4opt05.c
@@ -0,0 +1,107 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4opt05.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4opt05.c The dk4opt05 module.
+*/
+
+
+#line 10 "dk4opt05.ctr"
+
+#include "dk4opt.h"
+#include "dk4strd.h"
+#include "dk4mem.h"
+#include "dk4maiddbl.h"
+
+
+
+int
+dk4opt_get_double(double *dptr, dk4_option_t *optptr, dk4_er_t *erp)
+{
+ double val = 0.0;
+ int back = 0;
+ int res = 0;
+ if ((NULL != dptr) && (NULL != optptr)) {
+ if (0 != optptr->found) {
+ switch ((optptr->spec).argtype) {
+ case DK4_OPT_ARG_BOOL: {
+ if (0 != (optptr->val).b) {
+ *dptr = 1.0;
+ } else {
+ *dptr = 0.0;
+ }
+ back = 1;
+ } break;
+ case DK4_OPT_ARG_SIZE: {
+ *dptr = (double)((optptr->val).s);
+ back = 1;
+ } break;
+ case DK4_OPT_ARG_INT: {
+ *dptr = (double)((optptr->val).i);
+ back = 1;
+ } break;
+ case DK4_OPT_ARG_UNSIGNED: {
+ *dptr = (double)((optptr->val).u);
+ back = 1;
+ } break;
+ case DK4_OPT_ARG_DOUBLE: {
+ *dptr = (optptr->val).d;
+ back = 1;
+ } break;
+ case DK4_OPT_ARG_STRING: {
+ if (NULL != (optptr->val).t) {
+ res = dk4ma_input_dk_double(
+ &val, (optptr->val).t, NULL, 1, erp
+ );
+ if (0 != res) {
+ *dptr = val;
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } break;
+ default: {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4opt05.ctr b/support/dktools/dk4opt05.ctr
new file mode 100644
index 0000000000..12d1e30734
--- /dev/null
+++ b/support/dktools/dk4opt05.ctr
@@ -0,0 +1,76 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4opt.h"
+#include "dk4strd.h"
+#include "dk4mem.h"
+#include "dk4maiddbl.h"
+
+
+
+int
+dk4opt_get_double(double *dptr, dk4_option_t *optptr, dk4_er_t *erp)
+{
+ double val = 0.0;
+ int back = 0;
+ int res = 0;
+ if ((NULL != dptr) && (NULL != optptr)) {
+ if (0 != optptr->found) {
+ switch ((optptr->spec).argtype) {
+ case DK4_OPT_ARG_BOOL: {
+ if (0 != (optptr->val).b) {
+ *dptr = 1.0;
+ } else {
+ *dptr = 0.0;
+ }
+ back = 1;
+ } break;
+ case DK4_OPT_ARG_SIZE: {
+ *dptr = (double)((optptr->val).s);
+ back = 1;
+ } break;
+ case DK4_OPT_ARG_INT: {
+ *dptr = (double)((optptr->val).i);
+ back = 1;
+ } break;
+ case DK4_OPT_ARG_UNSIGNED: {
+ *dptr = (double)((optptr->val).u);
+ back = 1;
+ } break;
+ case DK4_OPT_ARG_DOUBLE: {
+ *dptr = (optptr->val).d;
+ back = 1;
+ } break;
+ case DK4_OPT_ARG_STRING: {
+ if (NULL != (optptr->val).t) {
+ res = dk4ma_input_dk_double(
+ &val, (optptr->val).t, NULL, 1, erp
+ );
+ if (0 != res) {
+ *dptr = val;
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } break;
+ default: {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4opt06.c b/support/dktools/dk4opt06.c
new file mode 100644
index 0000000000..2c5eb77db8
--- /dev/null
+++ b/support/dktools/dk4opt06.c
@@ -0,0 +1,126 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4opt06.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4opt06.c The dk4opt06 module.
+*/
+
+
+#line 10 "dk4opt06.ctr"
+
+#include "dk4opt.h"
+#include "dk4strd.h"
+#include "dk4mem.h"
+#include "dk4maodd.h"
+#include "dk4mao8dbl.h"
+#include "dk4maoddbl.h"
+
+
+
+
+
+#line 21 "dk4opt06.ctr"
+
+
+
+int
+dk4opt_get_string(
+ dkChar *dptr, size_t szdptr, dk4_option_t *optptr, dk4_er_t *erp
+)
+{
+ dkChar buf[16 * sizeof(dk4_um_t)];
+ int back = 0;
+ int res = 0;
+ if ((NULL != dptr) && (0 < szdptr) && (NULL != optptr)) {
+ if (0 != optptr->found) {
+ switch ((optptr->spec).argtype) {
+ case DK4_OPT_ARG_BOOL: {
+ res = dk4ma_write_decimal_signed(
+ buf, DK4_SIZEOF(buf,dkChar), (dk4_im_t)((optptr->val).b), 0, erp
+ );
+ if (0 != res) {
+ back = dk4str_cpy_s(dptr, szdptr, buf, NULL);
+ }
+ } break;
+ case DK4_OPT_ARG_SIZE: {
+ res = dk4ma_write_decimal_unsigned(
+ buf, DK4_SIZEOF(buf,dkChar), (dk4_um_t)((optptr->val).s), 0, erp
+ );
+ if (0 != res) {
+ back = dk4str_cpy_s(dptr, szdptr, buf, NULL);
+ }
+ } break;
+ case DK4_OPT_ARG_INT: {
+ res = dk4ma_write_decimal_signed(
+ buf, DK4_SIZEOF(buf,dkChar), (optptr->val).i, 0, erp
+ );
+ if (0 != res) {
+ back = dk4str_cpy_s(dptr, szdptr, buf, NULL);
+ }
+ } break;
+ case DK4_OPT_ARG_UNSIGNED: {
+ res = dk4ma_write_decimal_unsigned(
+ buf, DK4_SIZEOF(buf,dkChar), (optptr->val).u, 0, erp
+ );
+ if (0 != res) {
+ back = dk4str_cpy_s(dptr, szdptr, buf, NULL);
+ }
+ } break;
+ case DK4_OPT_ARG_DOUBLE: {
+#if DK4_USE_PRINTF_SCANF && (!(DK4_ON_WINDOWS && DK4_WIN_DENY_CRT))
+ back = dk4ma_write_double(dptr,szdptr,(optptr->val).d,0,0,erp);
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_OPT_ARG_STRING: {
+ if (NULL != (optptr->val).t) {
+ back = dk4str_cpy_s(dptr, szdptr, (optptr->val).t, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } break;
+ default: {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4opt06.ctr b/support/dktools/dk4opt06.ctr
new file mode 100644
index 0000000000..2f21e7dbc8
--- /dev/null
+++ b/support/dktools/dk4opt06.ctr
@@ -0,0 +1,93 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4opt.h"
+#include "dk4strd.h"
+#include "dk4mem.h"
+#include "dk4maodd.h"
+#include "dk4mao8dbl.h"
+#include "dk4maoddbl.h"
+
+
+
+$!trace-include
+
+
+
+int
+dk4opt_get_string(
+ dkChar *dptr, size_t szdptr, dk4_option_t *optptr, dk4_er_t *erp
+)
+{
+ dkChar buf[16 * sizeof(dk4_um_t)];
+ int back = 0;
+ int res = 0;
+ if ((NULL != dptr) && (0 < szdptr) && (NULL != optptr)) {
+ if (0 != optptr->found) {
+ switch ((optptr->spec).argtype) {
+ case DK4_OPT_ARG_BOOL: {
+ res = dk4ma_write_decimal_signed(
+ buf, DK4_SIZEOF(buf,dkChar), (dk4_im_t)((optptr->val).b), 0, erp
+ );
+ if (0 != res) {
+ back = dk4str_cpy_s(dptr, szdptr, buf, NULL);
+ }
+ } break;
+ case DK4_OPT_ARG_SIZE: {
+ res = dk4ma_write_decimal_unsigned(
+ buf, DK4_SIZEOF(buf,dkChar), (dk4_um_t)((optptr->val).s), 0, erp
+ );
+ if (0 != res) {
+ back = dk4str_cpy_s(dptr, szdptr, buf, NULL);
+ }
+ } break;
+ case DK4_OPT_ARG_INT: {
+ res = dk4ma_write_decimal_signed(
+ buf, DK4_SIZEOF(buf,dkChar), (optptr->val).i, 0, erp
+ );
+ if (0 != res) {
+ back = dk4str_cpy_s(dptr, szdptr, buf, NULL);
+ }
+ } break;
+ case DK4_OPT_ARG_UNSIGNED: {
+ res = dk4ma_write_decimal_unsigned(
+ buf, DK4_SIZEOF(buf,dkChar), (optptr->val).u, 0, erp
+ );
+ if (0 != res) {
+ back = dk4str_cpy_s(dptr, szdptr, buf, NULL);
+ }
+ } break;
+ case DK4_OPT_ARG_DOUBLE: {
+#if DK4_USE_PRINTF_SCANF && (!(DK4_ON_WINDOWS && DK4_WIN_DENY_CRT))
+ back = dk4ma_write_double(dptr,szdptr,(optptr->val).d,0,0,erp);
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case DK4_OPT_ARG_STRING: {
+ if (NULL != (optptr->val).t) {
+ back = dk4str_cpy_s(dptr, szdptr, (optptr->val).t, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } break;
+ default: {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4opt07.c b/support/dktools/dk4opt07.c
new file mode 100644
index 0000000000..8f8b206f7b
--- /dev/null
+++ b/support/dktools/dk4opt07.c
@@ -0,0 +1,646 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4opt07.ctr
+*/
+
+/** @file dk4opt07.c The dk4opt07 module.
+*/
+
+
+#line 5 "dk4opt07.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4opt.h"
+#include "dk4maidddi.h"
+#include "dk4maidddu.h"
+#include "dk4maiddsz.h"
+#include "dk4maiddbl.h"
+#include "dk4strd.h"
+#include "dk4fput.h"
+
+
+
+
+
+#line 20 "dk4opt07.ctr"
+
+
+
+static const dkChar * const dk4opt_kwnl[] = {
+/* 0 */
+dkT("\n"),
+
+/* 1 */
+dkT("ERROR: Option "),
+
+/* 2 */
+dkT("-"),
+
+/* 3 */
+dkT("/"),
+
+/* 4 */
+dkT("--"),
+
+/* 5 */
+dkT(" requires "),
+
+/* 6 */
+dkT("boolean "),
+
+/* 7 */
+dkT("size "),
+
+/* 8 */
+dkT("integer "),
+
+/* 9 */
+dkT("unsigned integer "),
+
+/* 10 */
+dkT("double "),
+
+/* 11 */
+dkT("string "),
+
+/* 12 */
+dkT("argument!\n"),
+
+/* 13 */
+dkT("Illegal argument text: \""),
+
+/* 14 */
+dkT("\"!\n"),
+
+/* 15 */
+dkT(": "),
+
+/* 16 */
+dkT("ERROR: No file names expected!\n"),
+
+/* 17 */
+dkT("ERROR: Too many file names!\n"),
+
+/* 18 */
+dkT("ERROR: Illegal option: \""),
+
+/* 19 */
+dkT("\"!\n"),
+
+/* 20 */
+dkT("Warning: Option used multiple times: \""),
+
+/* 21 */
+dkT("\".\n"),
+
+/* 22 */
+dkT("Warning: Unused argument in option: \""),
+
+/* 23 */
+dkT("\".\n"),
+
+NULL
+
+
+#line 80 "dk4opt07.ctr"
+};
+
+
+
+static
+void
+dk4opt_log_1(
+ size_t kwind,
+ const dkChar *progname,
+ int logstderr
+)
+{
+ if (0 != logstderr) {
+ dk4fput_initialize_stderr();
+ if (NULL != progname) {
+ dk4fputs(progname, stderr, NULL);
+ dk4fputs(dk4opt_kwnl[15], stderr, NULL);
+ }
+ dk4fputs(dk4opt_kwnl[kwind], stderr, NULL);
+ fflush(stderr);
+ }
+}
+
+
+
+static
+void
+dk4opt_log_3(
+ size_t kwi1,
+ size_t kwi2,
+ const dkChar *vartext,
+ const dkChar *progname,
+ int logstderr
+)
+{
+ if (0 != logstderr) {
+ dk4fput_initialize_stderr();
+ if (NULL != progname) {
+ dk4fputs(progname, stderr, NULL);
+ dk4fputs(dk4opt_kwnl[15], stderr, NULL);
+ }
+ dk4fputs(dk4opt_kwnl[kwi1], stderr, NULL);
+ if (NULL != vartext) {
+ dk4fputs(vartext, stderr, NULL);
+ }
+ dk4fputs(dk4opt_kwnl[kwi2], stderr, NULL);
+ fflush(stderr);
+ }
+}
+
+
+static
+void
+dk4opt_complain_argument(
+ dk4_option_t *opt,
+ const dkChar *valstr,
+ const dkChar *argv0,
+ int progname,
+ int logstderr
+)
+{
+ if (0 != logstderr) {
+ if ((dkT('\0') != opt->spec.c) || (NULL != opt->spec.longopt)) {
+ dk4fput_initialize_stderr();
+ if ((0 != progname) && (NULL != argv0)) {
+ dk4fputs(argv0, stderr, NULL);
+ dk4fputs(dk4opt_kwnl[15], stderr, NULL);
+ }
+ dk4fputs(dk4opt_kwnl[1], stderr, NULL);
+ if (dkT('\0') != opt->spec.c) {
+ dk4fputs(dk4opt_kwnl[2], stderr, NULL);
+ dk4fputc(opt->spec.c, stderr, NULL);
+ if (NULL != opt->spec.longopt) {
+ dk4fputs(dk4opt_kwnl[3], stderr, NULL);
+ }
+ }
+ if (NULL != opt->spec.longopt) {
+ dk4fputs(dk4opt_kwnl[4], stderr, NULL);
+ dk4fputs(opt->spec.longopt, stderr, NULL);
+ }
+ dk4fputs(dk4opt_kwnl[5], stderr, NULL);
+ switch (opt->spec.argtype) {
+ case DK4_OPT_ARG_BOOL : {
+ dk4fputs(dk4opt_kwnl[6], stderr, NULL);
+ } break;
+ case DK4_OPT_ARG_SIZE : {
+ dk4fputs(dk4opt_kwnl[7], stderr, NULL);
+ } break;
+ case DK4_OPT_ARG_INT : {
+ dk4fputs(dk4opt_kwnl[8], stderr, NULL);
+ } break;
+ case DK4_OPT_ARG_UNSIGNED : {
+ dk4fputs(dk4opt_kwnl[9], stderr, NULL);
+ } break;
+ case DK4_OPT_ARG_DOUBLE : {
+ dk4fputs(dk4opt_kwnl[10], stderr, NULL);
+ } break;
+ }
+ dk4fputs(dk4opt_kwnl[12], stderr, NULL);
+ if (NULL != valstr) {
+ dk4fputs(dk4opt_kwnl[13], stderr, NULL);
+ dk4fputs(valstr, stderr, NULL);
+ dk4fputs(dk4opt_kwnl[14], stderr, NULL);
+ }
+ fflush(stderr);
+ }
+ }
+}
+
+
+
+/** Find first position of equal sign in string.
+ Before calling this function we manuall checked there is no
+ equal sign at position 0.
+ @param str String to check.
+ @return Position of first equal sign on success, 0 on error.
+*/
+static
+size_t
+dk4opt_i_equal_sign_position(const dkChar *str)
+{
+ size_t back = 0;
+ size_t num = 0;
+ while ((dkT('\0') != *str) && (0 == back)) {
+ if (dkT('=') == *str) {
+ back = num;
+ } else {
+ str++; num++;
+ }
+ }
+ return back;
+}
+
+
+
+/** Set argument for one option.
+ @param opt Option to set.
+ @param valstr String containing the value.
+ @param logstderr Flag: Logging to stderr allowed.
+ @param progname Program name or NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4opt_i_set_value(
+ dk4_option_t *opt,
+ dkChar *valstr,
+ int logstderr,
+ const dkChar *progname
+)
+{
+ const dkChar *ep = NULL; /* First unconvertable char */
+ double d = 0.0; /* Default double value */
+ dk4_um_t um = (dk4_um_t)0UL; /* Default unsigned value */
+ dk4_im_t im = (dk4_im_t)0L; /* Default integer value */
+ size_t sz = (size_t)0UL; /* Default size value */
+ int back = 0; /* Result */
+
+
+#line 238 "dk4opt07.ctr"
+ switch (opt->spec.argtype) {
+ case DK4_OPT_ARG_BOOL : {
+
+#line 240 "dk4opt07.ctr"
+ opt->val.b = 0;
+ opt->found = 0;
+ if (0 != dk4str_is_bool(valstr)) {
+ opt->val.b = ((0 != dk4str_is_on(valstr)) ? 1 : 0);
+ opt->found = 1;
+ back = 1;
+ } else {
+ back = dk4ma_input_dk_dec_dk4_im_t(&im, valstr, &ep, 1, NULL);
+ if (0 != back) {
+ opt->val.b = (((dk4_im_t)0L != im) ? 1 : 0);
+ opt->found = 1;
+ } else {
+ /* ERROR: Not a boolean */
+ dk4opt_complain_argument(
+ opt, valstr, progname, ((NULL != progname) ? 1 : 0), logstderr
+ );
+ }
+ }
+ } break;
+ case DK4_OPT_ARG_SIZE : {
+
+#line 260 "dk4opt07.ctr"
+ opt->val.s = (size_t)0UL;
+ opt->found = 0;
+ back = dk4ma_input_dk_dec_size_t(&sz, valstr, &ep, 1, NULL);
+ if (0 != back) {
+ opt->val.s = sz;
+ opt->found = 1;
+ } else {
+ /* ERROR: Not a size */
+ dk4opt_complain_argument(
+ opt, valstr, progname, ((NULL != progname) ? 1 : 0), logstderr
+ );
+ }
+ } break;
+ case DK4_OPT_ARG_INT : {
+
+#line 274 "dk4opt07.ctr"
+ opt->val.i = (dk4_im_t)0L;
+ opt->found = 0;
+ back = dk4ma_input_dk_dec_dk4_im_t(&im, valstr, &ep, 1, NULL);
+ if (0 != back) {
+ opt->val.i = im;
+ opt->found = 1;
+ } else {
+ /* ERROR: Not an int */
+ dk4opt_complain_argument(
+ opt, valstr, progname, ((NULL != progname) ? 1 : 0), logstderr
+ );
+ }
+ } break;
+ case DK4_OPT_ARG_UNSIGNED : {
+
+#line 288 "dk4opt07.ctr"
+ opt->val.u = (dk4_um_t)0UL;
+ opt->found = 0;
+ back = dk4ma_input_dk_dec_dk4_um_t(&um, valstr, &ep, 1, NULL);
+ if (0 != back) {
+ opt->val.u = um;
+ opt->found = 1;
+ } else {
+ /* ERROR: Not an unsigned number */
+ dk4opt_complain_argument(
+ opt, valstr, progname, ((NULL != progname) ? 1 : 0), logstderr
+ );
+ }
+ } break;
+ case DK4_OPT_ARG_DOUBLE : {
+
+#line 302 "dk4opt07.ctr"
+ opt->val.d = 0.0;
+ opt->found = 0;
+ back = dk4ma_input_dk_double(&d, valstr, &ep, 1, NULL);
+ if (0 != back) {
+ opt->val.d = d;
+ opt->found = 1;
+ } else {
+ /* ERROR: Not a double */
+ dk4opt_complain_argument(
+ opt, valstr, progname, ((NULL != progname) ? 1 : 0), logstderr
+ );
+ }
+ } break;
+ case DK4_OPT_ARG_STRING : {
+
+#line 316 "dk4opt07.ctr"
+ opt->val.t = valstr;
+ opt->found = 1;
+ if (NULL != valstr) { back = 1; }
+ } break;
+ }
+
+#line 321 "dk4opt07.ctr"
+ return back;
+}
+
+
+
+int
+dk4opt_process_argv(
+ dk4_option_t *optptr,
+ size_t szoptptr,
+ int argc,
+ dkChar *argv[],
+ dkChar **filenames,
+ size_t *nfilenames,
+ int progname,
+ int logstderr,
+ dk4_er_t *erp
+)
+{
+ dkChar *curptr = NULL; /* Current argument to process */
+ dkChar *ocurptr = NULL; /* Original (complete) argument */
+ size_t fnused = 0; /* Used elements in filenames */
+ size_t j = 0; /* Option index to test */
+ size_t eqpos = 0; /* Equal sign position */
+ int i = 0; /* Current argument index */
+ int found = 0; /* Flag: current opt found in set */
+ int res = 0; /* Operation result */
+ int back = 0;
+
+
+#line 349 "dk4opt07.ctr"
+ if ((NULL != optptr) && (0 < szoptptr)) {
+
+#line 350 "dk4opt07.ctr"
+ for (j = 0; j < szoptptr; j++) {
+ optptr[j].found = 0;
+ optptr[j].val.t = NULL;
+ }
+ if ((0 < argc) && (NULL != argv)) {
+
+#line 355 "dk4opt07.ctr"
+ if ((NULL != filenames) && (NULL != nfilenames)) {
+ for (fnused = 0; fnused < *nfilenames; fnused++) {
+ filenames[fnused] = NULL;
+ }
+ fnused = 0;
+ }
+ back = 1;
+ i = 0;
+ if (0 != progname) { i = 1; }
+ while(i < argc) {
+ ocurptr = curptr = argv[i];
+
+#line 366 "dk4opt07.ctr"
+ if (dkT('-') == *curptr) {
+ curptr++;
+ if (dkT('-') == *curptr) {
+ curptr++;
+ if (dkT('\0' != *curptr)) {
+ if (dkT('=') != *curptr) {
+ eqpos = dk4opt_i_equal_sign_position(curptr);
+ found = 0;
+
+#line 374 "dk4opt07.ctr"
+ for (j = 0; ((j < szoptptr) && (0 == found)); j++) {
+ if (NULL != optptr[j].spec.longopt) {
+ res = 0;
+ if (0 != eqpos) {
+ if (eqpos == dk4str_len(optptr[j].spec.longopt)) {
+ res = dk4str_ncmp(curptr,optptr[j].spec.longopt,eqpos);
+ } else {
+ res = 1;
+ }
+ } else {
+ res = dk4str_cmp(curptr, optptr[j].spec.longopt);
+ }
+ if (0 == res) {
+ if (0 != optptr[j].found) {
+ /* WARNING: Option used multiple times */
+ dk4opt_log_3(
+ 20, 21, ocurptr, ((0 != progname) ? argv[0] : NULL),
+ logstderr
+ );
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ found = 1;
+ switch (optptr[j].spec.argtype) {
+ case DK4_OPT_ARG_BOOL :
+ case DK4_OPT_ARG_SIZE :
+ case DK4_OPT_ARG_INT :
+ case DK4_OPT_ARG_UNSIGNED :
+ case DK4_OPT_ARG_DOUBLE :
+ case DK4_OPT_ARG_STRING : {
+ if (0 < eqpos) {
+ curptr = &(curptr[eqpos+1]);
+ if (dkT('\0') == *curptr) {
+ curptr = NULL;
+ }
+ } else {
+ curptr = NULL;
+ }
+ if (NULL == curptr) {
+ if (++i < argc) {
+ curptr = argv[i];
+ }
+ }
+ if (NULL != curptr) {
+ res = dk4opt_i_set_value(
+ &(optptr[j]), curptr, logstderr,
+ ((0 != progname) ? argv[0] : NULL)
+ );
+ if (0 == res) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ back = 0;
+ /* ERROR: Option required argument */
+ dk4opt_complain_argument(
+ &(optptr[j]), NULL, argv[0], progname, logstderr
+ );
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ default : {
+ optptr[j].found = 1;
+ if (0 < eqpos) {
+ /* WARNING: Option does not use argument */
+ dk4opt_log_3(
+ 22, 23, ocurptr,
+ ((0 != progname) ? argv[0] : NULL), logstderr
+ );
+ }
+ } break;
+ }
+ }
+ }
+ }
+ if (0 == found) {
+ back = 0;
+ /* ERROR: Illegal option */
+ dk4opt_log_3(
+ 18,19,ocurptr,((0 != progname) ? argv[0] : NULL),logstderr
+ );
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ back = 0;
+ /* ERROR: Long option without name */
+ dk4opt_log_3(
+ 18, 19, ocurptr, ((0 != progname) ? argv[0] : NULL), logstderr
+ );
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ if ((NULL != filenames) && (NULL != nfilenames)) {
+ if (fnused < *nfilenames) {
+ filenames[fnused++] = ocurptr;
+ } else {
+ back = 0;
+ /* ERROR: Too many file names */
+ dk4opt_log_1(17,((0 != progname) ? argv[0] : NULL),logstderr);
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ back = 0;
+ /*ERROR: No file names expected */
+ dk4opt_log_1(16, ((0 != progname) ? argv[0] : NULL), logstderr);
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ }
+ } else {
+ if (dkT('\0') != *curptr) {
+ found = 0;
+ for (j = 0; ((j < szoptptr) && (0 == found)); j++) {
+ if (optptr[j].spec.c == *curptr) {
+ if (0 != optptr[j].found) {
+ /* WARNING: Option used multiple times */
+ dk4opt_log_3(
+ 20,21,ocurptr,((0 != progname) ? argv[0] : NULL),logstderr
+ );
+ }
+ found = 1;
+ switch(optptr[j].spec.argtype) {
+ case DK4_OPT_ARG_BOOL :
+ case DK4_OPT_ARG_SIZE :
+ case DK4_OPT_ARG_INT :
+ case DK4_OPT_ARG_UNSIGNED :
+ case DK4_OPT_ARG_DOUBLE :
+ case DK4_OPT_ARG_STRING : {
+ curptr++;
+ if (dkT('\0') == *curptr) {
+ curptr = NULL;
+ if (++i < argc) {
+ curptr = argv[i];
+ }
+ }
+ if (NULL != curptr) {
+ res = dk4opt_i_set_value(
+ &(optptr[j]), curptr, logstderr,
+ ((0 != progname) ? argv[0] : NULL)
+ );
+ if (0 == res) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ back = 0;
+ /* ERROR: Option requires argument */
+ dk4opt_complain_argument(
+ &(optptr[j]), NULL, argv[0], progname, logstderr
+ );
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ default : {
+ optptr[j].found = 1;
+ } break;
+ }
+ }
+ }
+ if (0 == found) {
+ back = 0;
+ /* ERROR: Option not found in specification */
+ dk4opt_log_3(
+ 18, 19, ocurptr, ((0 != progname) ? argv[0] : NULL), logstderr
+ );
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ if ((NULL != filenames) && (NULL != nfilenames)) {
+ if (fnused < *nfilenames) {
+ filenames[fnused++] = ocurptr;
+ } else {
+ back = 0;
+ /* ERROR: Too many file names */
+ dk4opt_log_1(17,((0 != progname) ? argv[0] : NULL),logstderr);
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ back = 0;
+ /* ERROR: No file names expected */
+ dk4opt_log_1(16, ((0 != progname) ? argv[0] : NULL), logstderr);
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ }
+ }
+ } else {
+ if ((NULL != filenames) && (NULL != nfilenames)) {
+ if (fnused < *nfilenames) {
+ filenames[fnused++] = curptr;
+ } else {
+ back = 0;
+ /* ERROR: Too many file names */
+ dk4opt_log_1(17, ((0 != progname) ? argv[0] : NULL), logstderr);
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ back = 0;
+ /* ERROR: No file names expected */
+ dk4opt_log_1(16, ((0 != progname) ? argv[0] : NULL), logstderr);
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ }
+ i++;
+ }
+ } else {
+ /* ERROR: Arguments */
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ /* ERROR: Arguments */
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ if (NULL != nfilenames) { *nfilenames = fnused; }
+
+
+#line 586 "dk4opt07.ctr"
+ return back;
+}
+
diff --git a/support/dktools/dk4opt07.ctr b/support/dktools/dk4opt07.ctr
new file mode 100644
index 0000000000..03c94456c9
--- /dev/null
+++ b/support/dktools/dk4opt07.ctr
@@ -0,0 +1,588 @@
+%% options
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4opt.h"
+#include "dk4maidddi.h"
+#include "dk4maidddu.h"
+#include "dk4maiddsz.h"
+#include "dk4maiddbl.h"
+#include "dk4strd.h"
+#include "dk4fput.h"
+
+
+
+$!trace-include
+
+
+
+static const dkChar * const dk4opt_kwnl[] = {
+$!string-table macro=dkT
+#
+# 0
+#
+\n
+#
+# 1 ... 5
+#
+ERROR: Option
+-
+/
+--
+ requires
+#
+# 6 ... 11
+#
+boolean
+size
+integer
+unsigned integer
+double
+string
+#
+# 12
+#
+argument!\n
+#
+# 13 14
+#
+Illegal argument text: "
+"!\n
+#
+# 15
+#
+:
+#
+# 16 17
+#
+ERROR: No file names expected!\n
+ERROR: Too many file names!\n
+#
+# 18 19
+#
+ERROR: Illegal option: "
+"!\n
+#
+# 20 21
+#
+Warning: Option used multiple times: "
+".\n
+#
+# 22 23
+#
+Warning: Unused argument in option: "
+".\n
+$!end
+};
+
+
+
+static
+void
+dk4opt_log_1(
+ size_t kwind,
+ const dkChar *progname,
+ int logstderr
+)
+{
+ if (0 != logstderr) {
+ dk4fput_initialize_stderr();
+ if (NULL != progname) {
+ dk4fputs(progname, stderr, NULL);
+ dk4fputs(dk4opt_kwnl[15], stderr, NULL);
+ }
+ dk4fputs(dk4opt_kwnl[kwind], stderr, NULL);
+ fflush(stderr);
+ }
+}
+
+
+
+static
+void
+dk4opt_log_3(
+ size_t kwi1,
+ size_t kwi2,
+ const dkChar *vartext,
+ const dkChar *progname,
+ int logstderr
+)
+{
+ if (0 != logstderr) {
+ dk4fput_initialize_stderr();
+ if (NULL != progname) {
+ dk4fputs(progname, stderr, NULL);
+ dk4fputs(dk4opt_kwnl[15], stderr, NULL);
+ }
+ dk4fputs(dk4opt_kwnl[kwi1], stderr, NULL);
+ if (NULL != vartext) {
+ dk4fputs(vartext, stderr, NULL);
+ }
+ dk4fputs(dk4opt_kwnl[kwi2], stderr, NULL);
+ fflush(stderr);
+ }
+}
+
+
+static
+void
+dk4opt_complain_argument(
+ dk4_option_t *opt,
+ const dkChar *valstr,
+ const dkChar *argv0,
+ int progname,
+ int logstderr
+)
+{
+ if (0 != logstderr) {
+ if ((dkT('\0') != opt->spec.c) || (NULL != opt->spec.longopt)) {
+ dk4fput_initialize_stderr();
+ if ((0 != progname) && (NULL != argv0)) {
+ dk4fputs(argv0, stderr, NULL);
+ dk4fputs(dk4opt_kwnl[15], stderr, NULL);
+ }
+ dk4fputs(dk4opt_kwnl[1], stderr, NULL);
+ if (dkT('\0') != opt->spec.c) {
+ dk4fputs(dk4opt_kwnl[2], stderr, NULL);
+ dk4fputc(opt->spec.c, stderr, NULL);
+ if (NULL != opt->spec.longopt) {
+ dk4fputs(dk4opt_kwnl[3], stderr, NULL);
+ }
+ }
+ if (NULL != opt->spec.longopt) {
+ dk4fputs(dk4opt_kwnl[4], stderr, NULL);
+ dk4fputs(opt->spec.longopt, stderr, NULL);
+ }
+ dk4fputs(dk4opt_kwnl[5], stderr, NULL);
+ switch (opt->spec.argtype) {
+ case DK4_OPT_ARG_BOOL : {
+ dk4fputs(dk4opt_kwnl[6], stderr, NULL);
+ } break;
+ case DK4_OPT_ARG_SIZE : {
+ dk4fputs(dk4opt_kwnl[7], stderr, NULL);
+ } break;
+ case DK4_OPT_ARG_INT : {
+ dk4fputs(dk4opt_kwnl[8], stderr, NULL);
+ } break;
+ case DK4_OPT_ARG_UNSIGNED : {
+ dk4fputs(dk4opt_kwnl[9], stderr, NULL);
+ } break;
+ case DK4_OPT_ARG_DOUBLE : {
+ dk4fputs(dk4opt_kwnl[10], stderr, NULL);
+ } break;
+ }
+ dk4fputs(dk4opt_kwnl[12], stderr, NULL);
+ if (NULL != valstr) {
+ dk4fputs(dk4opt_kwnl[13], stderr, NULL);
+ dk4fputs(valstr, stderr, NULL);
+ dk4fputs(dk4opt_kwnl[14], stderr, NULL);
+ }
+ fflush(stderr);
+ }
+ }
+}
+
+
+
+/** Find first position of equal sign in string.
+ Before calling this function we manuall checked there is no
+ equal sign at position 0.
+ @param str String to check.
+ @return Position of first equal sign on success, 0 on error.
+*/
+static
+size_t
+dk4opt_i_equal_sign_position(const dkChar *str)
+{
+ size_t back = 0;
+ size_t num = 0;
+ while ((dkT('\0') != *str) && (0 == back)) {
+ if (dkT('=') == *str) {
+ back = num;
+ } else {
+ str++; num++;
+ }
+ }
+ return back;
+}
+
+
+
+/** Set argument for one option.
+ @param opt Option to set.
+ @param valstr String containing the value.
+ @param logstderr Flag: Logging to stderr allowed.
+ @param progname Program name or NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4opt_i_set_value(
+ dk4_option_t *opt,
+ dkChar *valstr,
+ int logstderr,
+ const dkChar *progname
+)
+{
+ const dkChar *ep = NULL; /* First unconvertable char */
+ double d = 0.0; /* Default double value */
+ dk4_um_t um = (dk4_um_t)0UL; /* Default unsigned value */
+ dk4_im_t im = (dk4_im_t)0L; /* Default integer value */
+ size_t sz = (size_t)0UL; /* Default size value */
+ int back = 0; /* Result */
+ $? "+ dk4opt_i_set_value \"%!ds\"", TR_STR(valstr)
+ switch (opt->spec.argtype) {
+ case DK4_OPT_ARG_BOOL : { $? ". boolean"
+ opt->val.b = 0;
+ opt->found = 0;
+ if (0 != dk4str_is_bool(valstr)) {
+ opt->val.b = ((0 != dk4str_is_on(valstr)) ? 1 : 0);
+ opt->found = 1;
+ back = 1;
+ } else {
+ back = dk4ma_input_dk_dec_dk4_im_t(&im, valstr, &ep, 1, NULL);
+ if (0 != back) {
+ opt->val.b = (((dk4_im_t)0L != im) ? 1 : 0);
+ opt->found = 1;
+ } else {
+ /* ERROR: Not a boolean */
+ dk4opt_complain_argument(
+ opt, valstr, progname, ((NULL != progname) ? 1 : 0), logstderr
+ );
+ }
+ }
+ } break;
+ case DK4_OPT_ARG_SIZE : { $? ". size"
+ opt->val.s = (size_t)0UL;
+ opt->found = 0;
+ back = dk4ma_input_dk_dec_size_t(&sz, valstr, &ep, 1, NULL);
+ if (0 != back) {
+ opt->val.s = sz;
+ opt->found = 1;
+ } else {
+ /* ERROR: Not a size */
+ dk4opt_complain_argument(
+ opt, valstr, progname, ((NULL != progname) ? 1 : 0), logstderr
+ );
+ }
+ } break;
+ case DK4_OPT_ARG_INT : { $? ". int"
+ opt->val.i = (dk4_im_t)0L;
+ opt->found = 0;
+ back = dk4ma_input_dk_dec_dk4_im_t(&im, valstr, &ep, 1, NULL);
+ if (0 != back) {
+ opt->val.i = im;
+ opt->found = 1;
+ } else {
+ /* ERROR: Not an int */
+ dk4opt_complain_argument(
+ opt, valstr, progname, ((NULL != progname) ? 1 : 0), logstderr
+ );
+ }
+ } break;
+ case DK4_OPT_ARG_UNSIGNED : { $? ". unsigned"
+ opt->val.u = (dk4_um_t)0UL;
+ opt->found = 0;
+ back = dk4ma_input_dk_dec_dk4_um_t(&um, valstr, &ep, 1, NULL);
+ if (0 != back) {
+ opt->val.u = um;
+ opt->found = 1;
+ } else {
+ /* ERROR: Not an unsigned number */
+ dk4opt_complain_argument(
+ opt, valstr, progname, ((NULL != progname) ? 1 : 0), logstderr
+ );
+ }
+ } break;
+ case DK4_OPT_ARG_DOUBLE : { $? ". double"
+ opt->val.d = 0.0;
+ opt->found = 0;
+ back = dk4ma_input_dk_double(&d, valstr, &ep, 1, NULL);
+ if (0 != back) {
+ opt->val.d = d;
+ opt->found = 1;
+ } else {
+ /* ERROR: Not a double */
+ dk4opt_complain_argument(
+ opt, valstr, progname, ((NULL != progname) ? 1 : 0), logstderr
+ );
+ }
+ } break;
+ case DK4_OPT_ARG_STRING : { $? ". string"
+ opt->val.t = valstr;
+ opt->found = 1;
+ if (NULL != valstr) { back = 1; }
+ } break;
+ } $? "- dk4opt_i_set_value %d", back
+ return back;
+}
+
+
+
+int
+dk4opt_process_argv(
+ dk4_option_t *optptr,
+ size_t szoptptr,
+ int argc,
+ dkChar *argv[],
+ dkChar **filenames,
+ size_t *nfilenames,
+ int progname,
+ int logstderr,
+ dk4_er_t *erp
+)
+{
+ dkChar *curptr = NULL; /* Current argument to process */
+ dkChar *ocurptr = NULL; /* Original (complete) argument */
+ size_t fnused = 0; /* Used elements in filenames */
+ size_t j = 0; /* Option index to test */
+ size_t eqpos = 0; /* Equal sign position */
+ int i = 0; /* Current argument index */
+ int found = 0; /* Flag: current opt found in set */
+ int res = 0; /* Operation result */
+ int back = 0;
+ $? "+ dk4opt_process_argv"
+ if ((NULL != optptr) && (0 < szoptptr)) { $? ". args ok"
+ for (j = 0; j < szoptptr; j++) {
+ optptr[j].found = 0;
+ optptr[j].val.t = NULL;
+ }
+ if ((0 < argc) && (NULL != argv)) { $? ". args ok"
+ if ((NULL != filenames) && (NULL != nfilenames)) {
+ for (fnused = 0; fnused < *nfilenames; fnused++) {
+ filenames[fnused] = NULL;
+ }
+ fnused = 0;
+ }
+ back = 1;
+ i = 0;
+ if (0 != progname) { i = 1; }
+ while(i < argc) {
+ ocurptr = curptr = argv[i]; $? ". processing \"%s\"", curptr
+ if (dkT('-') == *curptr) {
+ curptr++;
+ if (dkT('-') == *curptr) {
+ curptr++;
+ if (dkT('\0' != *curptr)) {
+ if (dkT('=') != *curptr) {
+ eqpos = dk4opt_i_equal_sign_position(curptr);
+ found = 0; $? ". eqpos = %u", (unsigned)eqpos
+ for (j = 0; ((j < szoptptr) && (0 == found)); j++) {
+ if (NULL != optptr[j].spec.longopt) {
+ res = 0;
+ if (0 != eqpos) {
+ if (eqpos == dk4str_len(optptr[j].spec.longopt)) {
+ res = dk4str_ncmp(curptr,optptr[j].spec.longopt,eqpos);
+ } else {
+ res = 1;
+ }
+ } else {
+ res = dk4str_cmp(curptr, optptr[j].spec.longopt);
+ }
+ if (0 == res) {
+ if (0 != optptr[j].found) {
+ /* WARNING: Option used multiple times */
+ dk4opt_log_3(
+ 20, 21, ocurptr, ((0 != progname) ? argv[0] : NULL),
+ logstderr
+ );
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ found = 1;
+ switch (optptr[j].spec.argtype) {
+ case DK4_OPT_ARG_BOOL :
+ case DK4_OPT_ARG_SIZE :
+ case DK4_OPT_ARG_INT :
+ case DK4_OPT_ARG_UNSIGNED :
+ case DK4_OPT_ARG_DOUBLE :
+ case DK4_OPT_ARG_STRING : {
+ if (0 < eqpos) {
+ curptr = &(curptr[eqpos+1]);
+ if (dkT('\0') == *curptr) {
+ curptr = NULL;
+ }
+ } else {
+ curptr = NULL;
+ }
+ if (NULL == curptr) {
+ if (++i < argc) {
+ curptr = argv[i];
+ }
+ }
+ if (NULL != curptr) {
+ res = dk4opt_i_set_value(
+ &(optptr[j]), curptr, logstderr,
+ ((0 != progname) ? argv[0] : NULL)
+ );
+ if (0 == res) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ back = 0;
+ /* ERROR: Option required argument */
+ dk4opt_complain_argument(
+ &(optptr[j]), NULL, argv[0], progname, logstderr
+ );
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ default : {
+ optptr[j].found = 1;
+ if (0 < eqpos) {
+ /* WARNING: Option does not use argument */
+ dk4opt_log_3(
+ 22, 23, ocurptr,
+ ((0 != progname) ? argv[0] : NULL), logstderr
+ );
+ }
+ } break;
+ }
+ }
+ }
+ }
+ if (0 == found) {
+ back = 0;
+ /* ERROR: Illegal option */
+ dk4opt_log_3(
+ 18,19,ocurptr,((0 != progname) ? argv[0] : NULL),logstderr
+ );
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ back = 0;
+ /* ERROR: Long option without name */
+ dk4opt_log_3(
+ 18, 19, ocurptr, ((0 != progname) ? argv[0] : NULL), logstderr
+ );
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ if ((NULL != filenames) && (NULL != nfilenames)) {
+ if (fnused < *nfilenames) {
+ filenames[fnused++] = ocurptr;
+ } else {
+ back = 0;
+ /* ERROR: Too many file names */
+ dk4opt_log_1(17,((0 != progname) ? argv[0] : NULL),logstderr);
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ back = 0;
+ /*ERROR: No file names expected */
+ dk4opt_log_1(16, ((0 != progname) ? argv[0] : NULL), logstderr);
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ }
+ } else {
+ if (dkT('\0') != *curptr) {
+ found = 0;
+ for (j = 0; ((j < szoptptr) && (0 == found)); j++) {
+ if (optptr[j].spec.c == *curptr) {
+ if (0 != optptr[j].found) {
+ /* WARNING: Option used multiple times */
+ dk4opt_log_3(
+ 20,21,ocurptr,((0 != progname) ? argv[0] : NULL),logstderr
+ );
+ }
+ found = 1;
+ switch(optptr[j].spec.argtype) {
+ case DK4_OPT_ARG_BOOL :
+ case DK4_OPT_ARG_SIZE :
+ case DK4_OPT_ARG_INT :
+ case DK4_OPT_ARG_UNSIGNED :
+ case DK4_OPT_ARG_DOUBLE :
+ case DK4_OPT_ARG_STRING : {
+ curptr++;
+ if (dkT('\0') == *curptr) {
+ curptr = NULL;
+ if (++i < argc) {
+ curptr = argv[i];
+ }
+ }
+ if (NULL != curptr) {
+ res = dk4opt_i_set_value(
+ &(optptr[j]), curptr, logstderr,
+ ((0 != progname) ? argv[0] : NULL)
+ );
+ if (0 == res) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ back = 0;
+ /* ERROR: Option requires argument */
+ dk4opt_complain_argument(
+ &(optptr[j]), NULL, argv[0], progname, logstderr
+ );
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } break;
+ default : {
+ optptr[j].found = 1;
+ } break;
+ }
+ }
+ }
+ if (0 == found) {
+ back = 0;
+ /* ERROR: Option not found in specification */
+ dk4opt_log_3(
+ 18, 19, ocurptr, ((0 != progname) ? argv[0] : NULL), logstderr
+ );
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ if ((NULL != filenames) && (NULL != nfilenames)) {
+ if (fnused < *nfilenames) {
+ filenames[fnused++] = ocurptr;
+ } else {
+ back = 0;
+ /* ERROR: Too many file names */
+ dk4opt_log_1(17,((0 != progname) ? argv[0] : NULL),logstderr);
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ back = 0;
+ /* ERROR: No file names expected */
+ dk4opt_log_1(16, ((0 != progname) ? argv[0] : NULL), logstderr);
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ }
+ }
+ } else {
+ if ((NULL != filenames) && (NULL != nfilenames)) {
+ if (fnused < *nfilenames) {
+ filenames[fnused++] = curptr;
+ } else {
+ back = 0;
+ /* ERROR: Too many file names */
+ dk4opt_log_1(17, ((0 != progname) ? argv[0] : NULL), logstderr);
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ back = 0;
+ /* ERROR: No file names expected */
+ dk4opt_log_1(16, ((0 != progname) ? argv[0] : NULL), logstderr);
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ }
+ i++;
+ }
+ } else {
+ /* ERROR: Arguments */
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ /* ERROR: Arguments */
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ if (NULL != nfilenames) { *nfilenames = fnused; }
+ $? "- dk4opt_process_argv %d", back
+ return back;
+}
+
diff --git a/support/dktools/dk4papea.c b/support/dktools/dk4papea.c
new file mode 100644
index 0000000000..c7c2c23f53
--- /dev/null
+++ b/support/dktools/dk4papea.c
@@ -0,0 +1,576 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4papea.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4papea.c The dk4papea module.
+*/
+
+
+#line 57 "dk4papea.ctr"
+
+
+#include "dk4papea.h"
+#include "dk4strd.h"
+#include "dk4mem.h"
+#include "dk4maiddbl.h"
+#include "dk4tspdk.h"
+#include "dk4fs.h"
+#include "dk4mpl.h"
+#include "dk4strm.h"
+#include "dk4strmr.h"
+
+
+
+
+
+#line 72 "dk4papea.ctr"
+
+
+
+/** Object passed as pointer to the reader function
+*/
+typedef struct {
+ dk4_paper_size_collection_t *pscptr;
+ dk4_app_t *app;
+} reader_obj_t;
+
+
+
+/** Names of files to read.
+*/
+static const dkChar * const conf_file_names[] = {
+ dkT("dk4paper.conf"),
+#if DK4_HAVE_COMPATDKTOOLS3
+ dkT("dk3paper.conf"),
+#endif
+ NULL
+};
+
+
+
+/** Process one input line.
+ @param obj Reader object.
+ @param line Current line to process.
+ @param lineno Line number.
+ @param erp Error report, may be NULL.
+ @return
+ DK4_TSP_RES_OK if processing succeeded,
+ DK4_TSP_RES_ERROR on errors (can continue),
+ DK4_TSP_RES_FATAL on fatal errors (can not continue).
+
+*/
+
+static
+int
+dk4papersize_line_handler(
+ void *obj,
+ dkChar *line,
+ dk4_um_t lineno,
+ dk4_er_t *erp
+)
+{
+ double val[6]; /* w, h, i, o, t, b */
+ dkChar *tok[16]; /* tokens from the value side */
+ dk4_paper_size_collection_t *pscptr; /* collection of paper sizes */
+ dk4_paper_size_t *ps; /* paper size to modify */
+ dkChar *pls; /* line start (size name) */
+ dkChar *pval; /* value side of line */
+ const dkChar *ep; /* end pointer after double value */
+ dk4_app_t *app; /* application structure */
+ reader_obj_t *rdo; /* reader object */
+ size_t ntok; /* number of tokens in value side */
+ size_t i; /* index for traversal */
+ int back = DK4_TSP_RES_OK;
+
+
+#line 130 "dk4papea.ctr"
+ /* Retrieve components from obj pointer
+ */
+ rdo = (reader_obj_t *)obj;
+ pscptr = rdo->pscptr;
+ app = rdo->app;
+ dk4app_set_log_source_line(app, lineno);
+ /*
+ Find start of line
+ */
+ pls = dk4str_start(line, NULL);
+ if (NULL == pls) {
+
+#line 141 "dk4papea.ctr"
+ goto finished;
+ }
+ /*
+ Ignore comment lines
+ */
+ if (dkT('#') == *pls) {
+
+#line 147 "dk4papea.ctr"
+ goto finished;
+ }
+ /*
+ Line must by key = values
+ */
+ pval = dk4str_chr(pls, dkT('='));
+ if (NULL == pval) {
+
+#line 154 "dk4papea.ctr"
+ /* ERROR: Syntax */
+ dk4app_log_base1(app, DK4_LL_WARNING, 159);
+ back = DK4_TSP_RES_ERROR;
+ goto finished;
+ }
+
+#line 159 "dk4papea.ctr"
+ *(pval++) = dkT('\0');
+ dk4str_rtwh(pls, NULL);
+ if (0 == dk4str_len(pls)) {
+
+#line 162 "dk4papea.ctr"
+ /* ERROR: Syntax */
+ dk4app_log_base1(app, DK4_LL_WARNING, 159);
+ back = DK4_TSP_RES_ERROR;
+ goto finished;
+ }
+
+#line 167 "dk4papea.ctr"
+ pval = dk4str_start(pval, NULL);
+ if (NULL == pval) {
+
+#line 169 "dk4papea.ctr"
+ /* ERROR: Syntax */
+ dk4app_log_base1(app, DK4_LL_WARNING, 159);
+ back = DK4_TSP_RES_ERROR;
+ goto finished;
+ }
+
+#line 174 "dk4papea.ctr"
+ /*
+ Tokenize string
+ */
+ ntok = dk4str_tokenize(tok, 16, pval, NULL, NULL);
+ if ((2 > ntok) || (6 < ntok)) {
+
+#line 179 "dk4papea.ctr"
+ /* ERROR: Syntax */
+ dk4app_log_base1(app, DK4_LL_WARNING, 159);
+ back = DK4_TSP_RES_ERROR;
+ goto finished;
+ }
+
+#line 184 "dk4papea.ctr"
+ /*
+ Initialize values
+ */
+ for (i = 0; i < 6; i++) { val[i] = 0.0; }
+ /*
+ Process tokens to values
+ */
+ for (i = 0; i < ntok; i++) {
+ ep = NULL;
+
+#line 193 "dk4papea.ctr"
+ if (0 == dk4ma_input_dk_double(&(val[i]), tok[i], &ep, 1, NULL)) {
+ /* ERROR: Syntax */
+ dk4app_log_base1(app, DK4_LL_WARNING, 159);
+ back = DK4_TSP_RES_ERROR;
+
+#line 197 "dk4papea.ctr"
+ goto finished;
+ }
+ }
+ /*
+ Modify existing or create new papersize
+ */
+ ps = (dk4_paper_size_t *)dk4sto_it_find_like(pscptr->i_ps, pls, 1);
+ if (NULL == ps) {
+
+#line 205 "dk4papea.ctr"
+ ps = dk4papersize_new(pls, NULL);
+ if (NULL != ps) {
+
+#line 207 "dk4papea.ctr"
+ if (0 == dk4sto_add(pscptr->s_ps, ps, NULL)) {
+ dk4papersize_delete(ps);
+
+#line 209 "dk4papea.ctr"
+ ps = NULL;
+ }
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 214 "dk4papea.ctr"
+ }
+#endif
+ }
+ if (NULL == ps) {
+
+#line 218 "dk4papea.ctr"
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_WARNING, 90);
+ back = DK4_TSP_RES_ERROR;
+ goto finished;
+ }
+
+#line 223 "dk4papea.ctr"
+ ps->w = val[0]; ps->h = val[1]; ps->i = val[2];
+ ps->o = val[3]; ps->t = val[4]; ps->b = val[5];
+
+ finished:
+
+
+#line 228 "dk4papea.ctr"
+ return back;
+}
+
+
+
+/** Apply contents of one configuration file to paper size collection.
+ @param pscptr Paper size collection to modify.
+ @param fn File name.
+ @param app Application structure.
+*/
+static
+void
+dk4app_apply_paper_size_file(
+ dk4_paper_size_collection_t *pscptr,
+ const dkChar *fn,
+ dk4_app_t *app
+)
+{
+ char ib[4096]; /* Byte buffer */
+ dkChar il[1024]; /* Text line buffer */
+ dk4_tspdk_t tsp; /* Text stream processor */
+ dk4_er_t er; /* Error report */
+ reader_obj_t rdo; /* Passed to text proc */
+ const dkChar *oldsourcefile = NULL; /* Saved source file name */
+ dk4_stream_t *istrm = NULL; /* Input stream */
+ dk4_um_t oldsourceline = (dk4_um_t)0UL; /* Saved source line */
+ size_t rb = 0; /* Number of bytes read */
+ int cc = 1; /* Flag: Can continue */
+ int res = 0; /* Operation result */
+
+
+#line 258 "dk4papea.ctr"
+ /* Save current file name and file line for logging
+ */
+ oldsourcefile = dk4app_get_log_source_file(app);
+ oldsourceline = dk4app_get_log_source_line(app);
+ /*
+ We will process the specified input file, so set file name for logging
+ */
+ dk4app_set_log_source_file(app, fn);
+ dk4app_set_log_source_line(app, (dk4_um_t)0UL);
+ /*
+ Open stream for read access
+ */
+ dk4error_init(&er);
+ istrm = dk4stream_open_file_reader(fn, &er);
+ if (NULL == istrm) {
+
+#line 273 "dk4papea.ctr"
+ goto finished;
+ }
+
+#line 275 "dk4papea.ctr"
+ /*
+ Set up reader object
+ */
+ rdo.pscptr = pscptr;
+ rdo.app = app;
+ /*
+ Set up text processor
+ */
+ res = dk4tspdk_setup_line(
+ &tsp, &rdo, dk4papersize_line_handler, il, DK4_SIZEOF(il,dkChar),
+ app->encoding, app->enc_in_file, &er
+ );
+ if (0 == res) {
+
+#line 288 "dk4papea.ctr"
+ goto finished;
+ }
+
+#line 290 "dk4papea.ctr"
+ /*
+ Read and process contents from stream
+ */
+ res = DK4_TSP_RES_OK;
+ do {
+
+#line 295 "dk4papea.ctr"
+ cc = 0;
+ rb = sizeof(ib);
+ if (0 != dk4stream_read(ib, &rb, istrm, &er)) {
+
+#line 298 "dk4papea.ctr"
+ if (0 < rb) {
+
+#line 299 "dk4papea.ctr"
+ res = dk4tspdk_add_bytes(&tsp, (const unsigned char *)ib, rb);
+ if (DK4_TSP_RES_FATAL != res) {
+
+#line 301 "dk4papea.ctr"
+ cc = 1;
+ }
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 306 "dk4papea.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 311 "dk4papea.ctr"
+ }
+#endif
+
+
+#line 314 "dk4papea.ctr"
+ } while (1 == cc);
+ if (DK4_TSP_RES_FATAL != res) {
+ dk4tspdk_finish(&tsp);
+ }
+
+ finished:
+ /*
+ Close input stream
+ */
+ if (NULL != istrm) { dk4stream_close(istrm, NULL); }
+ /*
+ Restore file name and file line for logging
+ */
+ dk4app_set_log_source_file(app, oldsourcefile);
+ dk4app_set_log_source_line(app, oldsourceline);
+
+
+#line 330 "dk4papea.ctr"
+}
+
+
+
+dk4_paper_size_collection_t *
+dk4app_get_paper_sizes(dk4_app_t *app)
+{
+ dkChar fnb[DK4_MAX_PATH]; /* File name buffer */
+ dk4_er_t er; /* Error result */
+ const dkChar *msg[3];
+ dk4_paper_size_collection_t *back = NULL; /* Function result */
+ const size_t szfnb = DK4_SIZEOF(fnb,dkChar); /* Size */
+ int res; /* Operation result */
+ int i; /* Index for traversal */
+
+
+#line 345 "dk4papea.ctr"
+ /* Check app pointer
+ */
+ if (NULL == app) {
+
+#line 348 "dk4papea.ctr"
+ goto finished;
+ }
+ /* Allocate new size collection with default sizes
+ */
+ back = dk4papersize_coll_open(NULL);
+ if (NULL == back) {
+
+#line 354 "dk4papea.ctr"
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_WARNING, 90);
+ goto finished;
+ }
+ /* Find all configuration files and apply contents.
+ */
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ if ((NULL != app->msg_debug) && (36 < app->sz_msg_debug)) {
+ msg[0] = (app->msg_debug)[36];
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 1);
+ }
+ }
+ for (i = 0; i <= DK4_FS_CONF_MAX; i++) {
+
+#line 367 "dk4papea.ctr"
+#if DK4_HAVE_COMPATDKTOOLS3
+#if VERSION_BEFORE_2017_03_09
+ dk4error_init(&er);
+ res = dk4fs_config_compat_one(
+ fnb, szfnb, conf_file_names[1],
+ app->dir_share, app->dir_etc, app->user_home,
+ app->prog_name, app->group_name, i, 1, 1, &er
+ );
+ if (0 != res) {
+
+#line 376 "dk4papea.ctr"
+ dk4app_apply_paper_size_file(back, fnb, app);
+ }
+#else
+ dk4error_init(&er);
+ res = dk4fs_config_construct_compat_one(
+ fnb, szfnb, conf_file_names[1],
+ app->dir_share, app->dir_etc, app->user_home,
+ app->prog_name, app->group_name, i, 1, &er
+ );
+ if (0 != res) {
+ res = dk4fs_attempt_file_name(fnb, szfnb, 1, &er);
+ if (0 != res) {
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ if ((NULL != app->msg_debug) && (30 < app->sz_msg_debug)) {
+ msg[0] = (app->msg_debug)[30];
+ msg[1] = fnb;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 2);
+ }
+ }
+ dk4app_apply_paper_size_file(back, fnb, app);
+ } else {
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ if ((NULL != app->msg_debug) && (31 < app->sz_msg_debug)) {
+ msg[0] = (app->msg_debug)[31];
+ msg[1] = fnb;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 2);
+ }
+ }
+ }
+ }
+#endif
+#endif
+
+#if VERSION_BEFORE_2017_03_09
+ dk4error_init(&er);
+ res = dk4fs_config_one(
+ fnb, szfnb, conf_file_names[0],
+ app->dir_share, app->dir_etc, app->user_home,
+ app->prog_name, app->group_name, i, 1, &er
+ );
+ if (0 != res) {
+
+#line 417 "dk4papea.ctr"
+ dk4app_apply_paper_size_file(back, fnb, app);
+ }
+#else
+ dk4error_init(&er);
+ res = dk4fs_config_construct_compat_one(
+ fnb, szfnb, conf_file_names[0],
+ app->dir_share, app->dir_etc, app->user_home,
+ app->prog_name, app->group_name, i, 0, &er
+ );
+ if (0 != res) {
+ res = dk4fs_attempt_file_name(fnb, szfnb, 1, &er);
+ if (0 != res) {
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ if ((NULL != app->msg_debug) && (30 < app->sz_msg_debug)) {
+ msg[0] = (app->msg_debug)[30];
+ msg[1] = fnb;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 2);
+ }
+ }
+ dk4app_apply_paper_size_file(back, fnb, app);
+ } else {
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ if ((NULL != app->msg_debug) && (31 < app->sz_msg_debug)) {
+ msg[0] = (app->msg_debug)[31];
+ msg[1] = fnb;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 2);
+ }
+ }
+ }
+ } else {
+ }
+#endif
+ }
+
+ finished:
+
+
+#line 453 "dk4papea.ctr"
+ return back;
+}
+
+
+
+dk4_paper_size_t *
+dk4app_get_paper_size(dk4_app_t *app, const dkChar *psname)
+{
+ dk4_paper_size_collection_t *coll = NULL; /* Paper sizes collection */
+ dk4_paper_size_t *back = NULL; /* Function result */
+ dk4_paper_size_t *tmp = NULL; /* Temporary found paper size */
+
+
+#line 465 "dk4papea.ctr"
+ /*
+ Check arguments
+ */
+ if ((NULL == app) || (NULL == psname)) {
+ goto finished;
+ }
+ /*
+ Retrieve paper size collection
+ */
+ coll = dk4app_get_paper_sizes(app);
+ if (NULL == coll) {
+ goto finished;
+ }
+ tmp = (dk4_paper_size_t *)dk4sto_it_find_like(coll->i_ps, psname, 1);
+ if (NULL == tmp) {
+ goto finished;
+ }
+ back = dk4mem_new(dk4_paper_size_t,1,NULL);
+ if (NULL == back) {
+ goto finished;
+ }
+ back->name = NULL;
+ back->w = tmp->w;
+ back->h = tmp->h;
+ back->i = tmp->i;
+ back->o = tmp->o;
+ back->t = tmp->t;
+ back->b = tmp->b;
+
+ finished:
+ if (NULL != coll) {
+ dk4papersize_coll_close(coll);
+ }
+
+
+#line 499 "dk4papea.ctr"
+ return back;
+}
+
+
+
+
+/* vim: set ai sw=4 ts=4 : */
+
diff --git a/support/dktools/dk4papea.ctr b/support/dktools/dk4papea.ctr
new file mode 100644
index 0000000000..313cbdf77c
--- /dev/null
+++ b/support/dktools/dk4papea.ctr
@@ -0,0 +1,506 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+
+%% header
+
+/** @file dk4papea.h Paper sizes for applications.
+*/
+
+#ifndef DK4PAPER_H_INCLUDED
+#include "dk4paper.h"
+#endif
+
+#ifndef DK4APP_H_INCLUDED
+#include "dk4app.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** Get paper sizes collection.
+ If the function returns a valid pointer, use
+ dk4papersize_coll_close() to release the paper size collection when
+ done with it.
+ @param app Application structure.
+ @return Valid pointer on success, NULL on error.
+*/
+
+dk4_paper_size_collection_t *
+dk4app_get_paper_sizes(dk4_app_t *app);
+
+
+/** Get one paper size.
+ On success, call dk4mem_free() to release the paper size when done with it.
+ The paper size is returned with values only, empty name.
+ @param app Application structure.
+ @param psname Name of paper size to search for.
+ @return Valid pointer to paper size on success, NULL on error.
+*/
+
+dk4_paper_size_t *
+dk4app_get_paper_size(dk4_app_t *app, const dkChar *psname);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/* vim: set ai sw=4 ts=4 : */
+%% module
+
+
+#include "dk4papea.h"
+#include "dk4strd.h"
+#include "dk4mem.h"
+#include "dk4maiddbl.h"
+#include "dk4tspdk.h"
+#include "dk4fs.h"
+#include "dk4mpl.h"
+#include "dk4strm.h"
+#include "dk4strmr.h"
+
+
+
+$!trace-include
+
+
+
+/** Object passed as pointer to the reader function
+*/
+typedef struct {
+ dk4_paper_size_collection_t *pscptr;
+ dk4_app_t *app;
+} reader_obj_t;
+
+
+
+/** Names of files to read.
+*/
+static const dkChar * const conf_file_names[] = {
+ dkT("dk4paper.conf"),
+#if DK4_HAVE_COMPATDKTOOLS3
+ dkT("dk3paper.conf"),
+#endif
+ NULL
+};
+
+
+
+/** Process one input line.
+ @param obj Reader object.
+ @param line Current line to process.
+ @param lineno Line number.
+ @param erp Error report, may be NULL.
+ @return
+ DK4_TSP_RES_OK if processing succeeded,
+ DK4_TSP_RES_ERROR on errors (can continue),
+ DK4_TSP_RES_FATAL on fatal errors (can not continue).
+
+*/
+
+static
+int
+dk4papersize_line_handler(
+ void *obj,
+ dkChar *line,
+ dk4_um_t lineno,
+ dk4_er_t *erp
+)
+{
+ double val[6]; /* w, h, i, o, t, b */
+ dkChar *tok[16]; /* tokens from the value side */
+ dk4_paper_size_collection_t *pscptr; /* collection of paper sizes */
+ dk4_paper_size_t *ps; /* paper size to modify */
+ dkChar *pls; /* line start (size name) */
+ dkChar *pval; /* value side of line */
+ const dkChar *ep; /* end pointer after double value */
+ dk4_app_t *app; /* application structure */
+ reader_obj_t *rdo; /* reader object */
+ size_t ntok; /* number of tokens in value side */
+ size_t i; /* index for traversal */
+ int back = DK4_TSP_RES_OK;
+ $? "+ dk4papersize_line_handler \"%!ds\"", line
+ /* Retrieve components from obj pointer
+ */
+ rdo = (reader_obj_t *)obj;
+ pscptr = rdo->pscptr;
+ app = rdo->app;
+ dk4app_set_log_source_line(app, lineno);
+ /*
+ Find start of line
+ */
+ pls = dk4str_start(line, NULL);
+ if (NULL == pls) { $? ". empty line"
+ goto finished;
+ }
+ /*
+ Ignore comment lines
+ */
+ if (dkT('#') == *pls) { $? ". comment line"
+ goto finished;
+ }
+ /*
+ Line must by key = values
+ */
+ pval = dk4str_chr(pls, dkT('='));
+ if (NULL == pval) { $? "! no = found"
+ /* ERROR: Syntax */
+ dk4app_log_base1(app, DK4_LL_WARNING, 159);
+ back = DK4_TSP_RES_ERROR;
+ goto finished;
+ } $? ". found ="
+ *(pval++) = dkT('\0');
+ dk4str_rtwh(pls, NULL);
+ if (0 == dk4str_len(pls)) { $? "! 0 name length"
+ /* ERROR: Syntax */
+ dk4app_log_base1(app, DK4_LL_WARNING, 159);
+ back = DK4_TSP_RES_ERROR;
+ goto finished;
+ } $? ". name length ok"
+ pval = dk4str_start(pval, NULL);
+ if (NULL == pval) { $? "! pval"
+ /* ERROR: Syntax */
+ dk4app_log_base1(app, DK4_LL_WARNING, 159);
+ back = DK4_TSP_RES_ERROR;
+ goto finished;
+ } $? ". pval"
+ /*
+ Tokenize string
+ */
+ ntok = dk4str_tokenize(tok, 16, pval, NULL, NULL);
+ if ((2 > ntok) || (6 < ntok)) { $? "! wrong number of tokens"
+ /* ERROR: Syntax */
+ dk4app_log_base1(app, DK4_LL_WARNING, 159);
+ back = DK4_TSP_RES_ERROR;
+ goto finished;
+ } $? ". number of tokens ok"
+ /*
+ Initialize values
+ */
+ for (i = 0; i < 6; i++) { val[i] = 0.0; }
+ /*
+ Process tokens to values
+ */
+ for (i = 0; i < ntok; i++) {
+ ep = NULL; $? ". token=\"%!ds\"", tok[i]
+ if (0 == dk4ma_input_dk_double(&(val[i]), tok[i], &ep, 1, NULL)) {
+ /* ERROR: Syntax */
+ dk4app_log_base1(app, DK4_LL_WARNING, 159);
+ back = DK4_TSP_RES_ERROR; $? "! token=\"%!ds\"", tok[i]
+ goto finished;
+ }
+ }
+ /*
+ Modify existing or create new papersize
+ */
+ ps = (dk4_paper_size_t *)dk4sto_it_find_like(pscptr->i_ps, pls, 1);
+ if (NULL == ps) { $? ". must create new paper size"
+ ps = dk4papersize_new(pls, NULL);
+ if (NULL != ps) { $? ". paper size created"
+ if (0 == dk4sto_add(pscptr->s_ps, ps, NULL)) {
+ dk4papersize_delete(ps); $? "! failed to add"
+ ps = NULL;
+ }
+ }
+#if TRACE_DEBUG
+ else { $? "! memory"
+ }
+#endif
+ }
+ if (NULL == ps) { $? "! no paper size to set up"
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_WARNING, 90);
+ back = DK4_TSP_RES_ERROR;
+ goto finished;
+ } $? ". paper size available"
+ ps->w = val[0]; ps->h = val[1]; ps->i = val[2];
+ ps->o = val[3]; ps->t = val[4]; ps->b = val[5];
+
+ finished:
+ $? "- dk4papersize_line_handler %d", back
+ return back;
+}
+
+
+
+/** Apply contents of one configuration file to paper size collection.
+ @param pscptr Paper size collection to modify.
+ @param fn File name.
+ @param app Application structure.
+*/
+static
+void
+dk4app_apply_paper_size_file(
+ dk4_paper_size_collection_t *pscptr,
+ const dkChar *fn,
+ dk4_app_t *app
+)
+{
+ char ib[4096]; /* Byte buffer */
+ dkChar il[1024]; /* Text line buffer */
+ dk4_tspdk_t tsp; /* Text stream processor */
+ dk4_er_t er; /* Error report */
+ reader_obj_t rdo; /* Passed to text proc */
+ const dkChar *oldsourcefile = NULL; /* Saved source file name */
+ dk4_stream_t *istrm = NULL; /* Input stream */
+ dk4_um_t oldsourceline = (dk4_um_t)0UL; /* Saved source line */
+ size_t rb = 0; /* Number of bytes read */
+ int cc = 1; /* Flag: Can continue */
+ int res = 0; /* Operation result */
+ $? "+ dk4app_apply_paper_size_file \"%!ds\"", fn
+ /* Save current file name and file line for logging
+ */
+ oldsourcefile = dk4app_get_log_source_file(app);
+ oldsourceline = dk4app_get_log_source_line(app);
+ /*
+ We will process the specified input file, so set file name for logging
+ */
+ dk4app_set_log_source_file(app, fn);
+ dk4app_set_log_source_line(app, (dk4_um_t)0UL);
+ /*
+ Open stream for read access
+ */
+ dk4error_init(&er);
+ istrm = dk4stream_open_file_reader(fn, &er);
+ if (NULL == istrm) { $? "! failed to open file"
+ goto finished;
+ } $? ". file opened"
+ /*
+ Set up reader object
+ */
+ rdo.pscptr = pscptr;
+ rdo.app = app;
+ /*
+ Set up text processor
+ */
+ res = dk4tspdk_setup_line(
+ &tsp, &rdo, dk4papersize_line_handler, il, DK4_SIZEOF(il,dkChar),
+ app->encoding, app->enc_in_file, &er
+ );
+ if (0 == res) { $? "! failed to init tsp"
+ goto finished;
+ } $? ". tsp initialized"
+ /*
+ Read and process contents from stream
+ */
+ res = DK4_TSP_RES_OK;
+ do { $? ". start of loop"
+ cc = 0;
+ rb = sizeof(ib);
+ if (0 != dk4stream_read(ib, &rb, istrm, &er)) { $? ". read ok"
+ if (0 < rb) { $? ". bytes found"
+ res = dk4tspdk_add_bytes(&tsp, (const unsigned char *)ib, rb);
+ if (DK4_TSP_RES_FATAL != res) { $? ". byte processing ok"
+ cc = 1;
+ }
+ }
+#if TRACE_DEBUG
+ else { $? ". 0 read"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! read failed"
+ }
+#endif
+ $? ". end of loop cc=%d", cc
+ } while (1 == cc);
+ if (DK4_TSP_RES_FATAL != res) {
+ dk4tspdk_finish(&tsp);
+ }
+
+ finished:
+ /*
+ Close input stream
+ */
+ if (NULL != istrm) { dk4stream_close(istrm, NULL); }
+ /*
+ Restore file name and file line for logging
+ */
+ dk4app_set_log_source_file(app, oldsourcefile);
+ dk4app_set_log_source_line(app, oldsourceline);
+ $? "- dk4app_apply_paper_size_file"
+}
+
+
+
+dk4_paper_size_collection_t *
+dk4app_get_paper_sizes(dk4_app_t *app)
+{
+ dkChar fnb[DK4_MAX_PATH]; /* File name buffer */
+ dk4_er_t er; /* Error result */
+ const dkChar *msg[3];
+ dk4_paper_size_collection_t *back = NULL; /* Function result */
+ const size_t szfnb = DK4_SIZEOF(fnb,dkChar); /* Size */
+ int res; /* Operation result */
+ int i; /* Index for traversal */
+ $? "+ dk4app_get_paper_sizes"
+ /* Check app pointer
+ */
+ if (NULL == app) { $? "! invalid app pointer"
+ goto finished;
+ }
+ /* Allocate new size collection with default sizes
+ */
+ back = dk4papersize_coll_open(NULL);
+ if (NULL == back) { $? "! memory"
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_WARNING, 90);
+ goto finished;
+ }
+ /* Find all configuration files and apply contents.
+ */
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ if ((NULL != app->msg_debug) && (36 < app->sz_msg_debug)) {
+ msg[0] = (app->msg_debug)[36];
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 1);
+ }
+ }
+ for (i = 0; i <= DK4_FS_CONF_MAX; i++) { $? ". pass %u", (unsigned)i
+#if DK4_HAVE_COMPATDKTOOLS3
+#if VERSION_BEFORE_2017_03_09
+ dk4error_init(&er);
+ res = dk4fs_config_compat_one(
+ fnb, szfnb, conf_file_names[1],
+ app->dir_share, app->dir_etc, app->user_home,
+ app->prog_name, app->group_name, i, 1, 1, &er
+ );
+ if (0 != res) { $? ". dk3paper.conf"
+ dk4app_apply_paper_size_file(back, fnb, app);
+ }
+#else
+ dk4error_init(&er);
+ res = dk4fs_config_construct_compat_one(
+ fnb, szfnb, conf_file_names[1],
+ app->dir_share, app->dir_etc, app->user_home,
+ app->prog_name, app->group_name, i, 1, &er
+ );
+ if (0 != res) {
+ res = dk4fs_attempt_file_name(fnb, szfnb, 1, &er);
+ if (0 != res) {
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ if ((NULL != app->msg_debug) && (30 < app->sz_msg_debug)) {
+ msg[0] = (app->msg_debug)[30];
+ msg[1] = fnb;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 2);
+ }
+ }
+ dk4app_apply_paper_size_file(back, fnb, app);
+ } else {
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ if ((NULL != app->msg_debug) && (31 < app->sz_msg_debug)) {
+ msg[0] = (app->msg_debug)[31];
+ msg[1] = fnb;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 2);
+ }
+ }
+ }
+ }
+#endif
+#endif
+
+#if VERSION_BEFORE_2017_03_09
+ dk4error_init(&er);
+ res = dk4fs_config_one(
+ fnb, szfnb, conf_file_names[0],
+ app->dir_share, app->dir_etc, app->user_home,
+ app->prog_name, app->group_name, i, 1, &er
+ );
+ if (0 != res) { $? ". dk4paper.conf"
+ dk4app_apply_paper_size_file(back, fnb, app);
+ }
+#else
+ dk4error_init(&er);
+ res = dk4fs_config_construct_compat_one(
+ fnb, szfnb, conf_file_names[0],
+ app->dir_share, app->dir_etc, app->user_home,
+ app->prog_name, app->group_name, i, 0, &er
+ );
+ if (0 != res) {
+ res = dk4fs_attempt_file_name(fnb, szfnb, 1, &er);
+ if (0 != res) {
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ if ((NULL != app->msg_debug) && (30 < app->sz_msg_debug)) {
+ msg[0] = (app->msg_debug)[30];
+ msg[1] = fnb;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 2);
+ }
+ }
+ dk4app_apply_paper_size_file(back, fnb, app);
+ } else {
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ if ((NULL != app->msg_debug) && (31 < app->sz_msg_debug)) {
+ msg[0] = (app->msg_debug)[31];
+ msg[1] = fnb;
+ dk4app_log_msg(app, DK4_LL_DEBUG, msg, 2);
+ }
+ }
+ }
+ } else {
+ }
+#endif
+ }
+
+ finished:
+ $? "- dk4app_get_paper_sizes %d", TR_IPTR(back)
+ return back;
+}
+
+
+
+dk4_paper_size_t *
+dk4app_get_paper_size(dk4_app_t *app, const dkChar *psname)
+{
+ dk4_paper_size_collection_t *coll = NULL; /* Paper sizes collection */
+ dk4_paper_size_t *back = NULL; /* Function result */
+ dk4_paper_size_t *tmp = NULL; /* Temporary found paper size */
+ $? "+ dk4app_get_paper_size \"%!ds\"", TR_STR(psname)
+ /*
+ Check arguments
+ */
+ if ((NULL == app) || (NULL == psname)) {
+ goto finished;
+ }
+ /*
+ Retrieve paper size collection
+ */
+ coll = dk4app_get_paper_sizes(app);
+ if (NULL == coll) {
+ goto finished;
+ }
+ tmp = (dk4_paper_size_t *)dk4sto_it_find_like(coll->i_ps, psname, 1);
+ if (NULL == tmp) {
+ goto finished;
+ }
+ back = dk4mem_new(dk4_paper_size_t,1,NULL);
+ if (NULL == back) {
+ goto finished;
+ }
+ back->name = NULL;
+ back->w = tmp->w;
+ back->h = tmp->h;
+ back->i = tmp->i;
+ back->o = tmp->o;
+ back->t = tmp->t;
+ back->b = tmp->b;
+
+ finished:
+ if (NULL != coll) {
+ dk4papersize_coll_close(coll);
+ }
+ $? "- dk4app_get_paper_size %d", TR_IPTR(back)
+ return back;
+}
+
+
+
+
+/* vim: set ai sw=4 ts=4 : */
+
diff --git a/support/dktools/dk4papea.h b/support/dktools/dk4papea.h
new file mode 100644
index 0000000000..fb7a926a50
--- /dev/null
+++ b/support/dktools/dk4papea.h
@@ -0,0 +1,90 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4papea.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4PAPEA_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4PAPEA_H_INCLUDED 1
+
+
+#line 9 "dk4papea.ctr"
+
+/** @file dk4papea.h Paper sizes for applications.
+*/
+
+#ifndef DK4PAPER_H_INCLUDED
+#include "dk4paper.h"
+#endif
+
+#ifndef DK4APP_H_INCLUDED
+#include "dk4app.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** Get paper sizes collection.
+ If the function returns a valid pointer, use
+ dk4papersize_coll_close() to release the paper size collection when
+ done with it.
+ @param app Application structure.
+ @return Valid pointer on success, NULL on error.
+*/
+
+dk4_paper_size_collection_t *
+dk4app_get_paper_sizes(dk4_app_t *app);
+
+
+/** Get one paper size.
+ On success, call dk4mem_free() to release the paper size when done with it.
+ The paper size is returned with values only, empty name.
+ @param app Application structure.
+ @param psname Name of paper size to search for.
+ @return Valid pointer to paper size on success, NULL on error.
+*/
+
+dk4_paper_size_t *
+dk4app_get_paper_size(dk4_app_t *app, const dkChar *psname);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/* vim: set ai sw=4 ts=4 : */
+
+#endif
diff --git a/support/dktools/dk4paper.c b/support/dktools/dk4paper.c
new file mode 100644
index 0000000000..0b29e51593
--- /dev/null
+++ b/support/dktools/dk4paper.c
@@ -0,0 +1,948 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4paper.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4paper.c The dk4paper module.
+*/
+
+
+#line 288 "dk4paper.ctr"
+
+#include "dk4mem.h"
+#include "dk4strd.h"
+#include "dk4paper.h"
+#include "dk4maiddbl.h"
+#include "dk4fs.h"
+#include "dk4mpl.h"
+#include "dk4tspdk.h"
+#include "dk4strm.h"
+#include "dk4strmr.h"
+#include "dk4enc.h"
+#include "dk4loc.h"
+#include "dk4user.h"
+#include "dk4inst.h"
+
+
+
+
+
+#line 306 "dk4paper.ctr"
+
+
+
+/** Object passed as pointer to the line handler.
+*/
+typedef struct {
+ dk4_paper_size_collection_t *coll; /**< Collection to modify. */
+} reader_obj_t;
+
+
+
+/** Configuration files to search for.
+*/
+static const dkChar * const conf_file_names[] = {
+ dkT("dk4paper.conf"),
+ dkT("dk3paper.conf")
+};
+
+
+
+/** Default paper size names always defined.
+*/
+static const dkChar *default_paper_sizes[] = {
+/* 0 */
+dkT("A4"),
+
+/* 1 */
+dkT("a4"),
+
+/* 2 */
+dkT("Letter"),
+
+/* 3 */
+dkT("letter"),
+
+NULL
+
+
+#line 335 "dk4paper.ctr"
+};
+
+
+
+void
+dk4papersize_delete(dk4_paper_size_t *pps)
+{
+
+
+#line 343 "dk4paper.ctr"
+ if (NULL != pps) {
+
+#line 344 "dk4paper.ctr"
+ if (NULL != pps->name) {
+
+#line 345 "dk4paper.ctr"
+
+
+#line 346 "dk4paper.ctr"
+ dk4mem_free(pps->name);
+ pps->name = NULL;
+ }
+ dk4mem_free(pps);
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 353 "dk4paper.ctr"
+ }
+#endif
+
+
+#line 356 "dk4paper.ctr"
+}
+
+
+
+dk4_paper_size_t *
+dk4papersize_new(const dkChar *name, dk4_er_t *erp)
+{
+ dk4_paper_size_t *back = NULL;
+
+
+#line 365 "dk4paper.ctr"
+ if (NULL != name) {
+ back = dk4mem_new(dk4_paper_size_t,1,erp);
+ if (NULL != back) {
+ back->w = 0.0;
+ back->h = 0.0;
+ back->i = 0.0;
+ back->o = 0.0;
+ back->t = 0.0;
+ back->b = 0.0;
+ back->name = dk4str_dup(name, erp);
+ if (NULL == back->name) {
+ dk4mem_free(back);
+ back = NULL;
+ }
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 385 "dk4paper.ctr"
+ return back;
+}
+
+
+
+
+void
+dk4papersize_coll_close(dk4_paper_size_collection_t *ptr)
+{
+ dk4_paper_size_t *pps;
+
+
+#line 396 "dk4paper.ctr"
+ if (NULL != ptr) {
+
+#line 397 "dk4paper.ctr"
+ if (NULL != ptr->s_ps) {
+
+#line 398 "dk4paper.ctr"
+ if (NULL != ptr->i_ps) {
+
+#line 399 "dk4paper.ctr"
+ dk4sto_it_reset(ptr->i_ps);
+ do {
+ pps = (dk4_paper_size_t *)dk4sto_it_next(ptr->i_ps);
+ if (NULL != pps) {
+
+#line 403 "dk4paper.ctr"
+ dk4papersize_delete(pps);
+ }
+ } while (NULL != pps);
+ dk4sto_it_close(ptr->i_ps);
+ ptr->i_ps = NULL;
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 411 "dk4paper.ctr"
+ }
+#endif
+ dk4sto_close(ptr->s_ps);
+ ptr->s_ps = NULL;
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 418 "dk4paper.ctr"
+ }
+#endif
+
+
+#line 421 "dk4paper.ctr"
+ dk4mem_free(ptr);
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 425 "dk4paper.ctr"
+ }
+#endif
+
+
+#line 428 "dk4paper.ctr"
+}
+
+
+
+
+int
+dk4papersize_cmp(const void *l, const void *r, int cr)
+{
+ const dk4_paper_size_t *pl = NULL;
+ const dk4_paper_size_t *pr = NULL;
+ const dkChar *nm = NULL;
+ int back = 0;
+
+ if (NULL != l) {
+ if (NULL != r) {
+ pl = (const dk4_paper_size_t *)l;
+ switch (cr) {
+ case 1 : {
+ nm = (const dkChar *)r;
+ back = dk4str_cmp(pl->name, nm);
+ } break;
+ default : {
+ pr = (const dk4_paper_size_t *)r;
+ back = dk4str_cmp(pl->name, pr->name);
+ } break;
+ }
+ }
+ else {
+ back = 1;
+ }
+ }
+ else {
+ if (NULL != r) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+static
+int
+dk4papersize_i_add_one_default_size(
+ dk4_paper_size_collection_t *pscptr,
+ const dkChar *name,
+ double w,
+ double h,
+ double i,
+ double o,
+ double t,
+ double b,
+ dk4_er_t *erp
+)
+{
+ dk4_paper_size_t *ptr;
+ int back = 0;
+
+
+#line 486 "dk4paper.ctr"
+ ptr = dk4papersize_new(name, erp);
+ if (NULL != ptr) {
+
+#line 488 "dk4paper.ctr"
+ ptr->w = w; ptr->h = h; ptr->i = i; ptr->o = o; ptr->t = t; ptr->b = b;
+
+
+#line 490 "dk4paper.ctr"
+
+
+#line 491 "dk4paper.ctr"
+
+
+#line 492 "dk4paper.ctr"
+
+
+#line 493 "dk4paper.ctr"
+
+
+#line 494 "dk4paper.ctr"
+
+
+#line 495 "dk4paper.ctr"
+ if (0 != dk4sto_add(pscptr->s_ps, ptr, erp)) {
+ back = 1;
+
+#line 497 "dk4paper.ctr"
+ }
+ else {
+
+#line 499 "dk4paper.ctr"
+ dk4papersize_delete(ptr);
+ ptr = NULL;
+ }
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 505 "dk4paper.ctr"
+ }
+#endif
+
+
+#line 508 "dk4paper.ctr"
+ return back;
+}
+
+
+
+static
+int
+dk4papersize_i_add_default_sizes(
+ dk4_paper_size_collection_t *pscptr,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+
+
+#line 522 "dk4paper.ctr"
+ back = dk4papersize_i_add_one_default_size(
+ pscptr, default_paper_sizes[0], 595.0, 842.0, 0.0, 0.0, 0.0, 0.0, erp
+ );
+ if (0 == back) { goto finished; }
+
+ back = dk4papersize_i_add_one_default_size(
+ pscptr, default_paper_sizes[1], 595.0, 842.0, 56.0, 28.0, 14.0, 14.0, erp
+ );
+ if (0 == back) { goto finished; }
+
+ back = dk4papersize_i_add_one_default_size(
+ pscptr, default_paper_sizes[2], 612.0, 792.0, 0.0, 0.0, 0.0, 0.0, erp
+ );
+ if (0 == back) { goto finished; }
+
+ back = dk4papersize_i_add_one_default_size(
+ pscptr, default_paper_sizes[3], 612.0, 792.0, 56.0, 28.0, 14.0, 14.0, erp
+ );
+ if (0 == back) { goto finished; }
+
+ back = 1;
+
+ finished:
+
+
+#line 546 "dk4paper.ctr"
+ return back;
+}
+
+
+
+
+dk4_paper_size_collection_t *
+dk4papersize_coll_open(dk4_er_t *erp)
+{
+ dk4_paper_size_collection_t *back = NULL;
+ int ok = 0;
+
+
+#line 558 "dk4paper.ctr"
+ back = dk4mem_new(dk4_paper_size_collection_t,1,erp);
+ if (NULL != back) {
+ back->i_ps = NULL;
+ back->s_ps = dk4sto_open(erp);
+ if (NULL != back->s_ps) {
+ (void)dk4sto_set_comp(back->s_ps, dk4papersize_cmp, 0);
+ back->i_ps = dk4sto_it_open(back->s_ps, erp);
+ if (NULL != back->i_ps) {
+ ok = dk4papersize_i_add_default_sizes(back, erp);
+ }
+ }
+ if (0 == ok) {
+ dk4papersize_coll_close(back);
+ back = NULL;
+ }
+ }
+
+#line 574 "dk4paper.ctr"
+ return back;
+}
+
+
+
+
+const dk4_paper_size_t *
+dk4papersize_coll_find(
+ dk4_paper_size_collection_t *ptr,
+ const dkChar *name,
+ dk4_er_t *erp
+)
+{
+ dk4_paper_size_t *back = NULL;
+
+
+#line 589 "dk4paper.ctr"
+ if ((NULL != ptr) && (NULL != name)) {
+ back = (dk4_paper_size_t *)dk4sto_it_find_like(ptr->i_ps, name, 1);
+ if (NULL == back) {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 598 "dk4paper.ctr"
+ return ((const dk4_paper_size_t *)back);
+}
+
+
+
+double
+dk4papersize_get_width(const dk4_paper_size_t *psptr)
+{
+ double back = -1.0;
+ if (NULL != psptr) {
+ back = psptr->w;
+ }
+ return back;
+}
+
+
+
+double
+dk4papersize_get_height(const dk4_paper_size_t *psptr)
+{
+ double back = -1.0;
+ if (NULL != psptr) {
+ back = psptr->h;
+ }
+ return back;
+}
+
+
+
+double
+dk4papersize_get_left_border(const dk4_paper_size_t *psptr)
+{
+ double back = -1.0;
+ if (NULL != psptr) {
+ back = psptr->i;
+ }
+ return back;
+}
+
+
+
+double
+dk4papersize_get_right_border(const dk4_paper_size_t *psptr)
+{
+ double back = -1.0;
+ if (NULL != psptr) {
+ back = psptr->o;
+ }
+ return back;
+}
+
+
+
+double
+dk4papersize_get_top_border(const dk4_paper_size_t *psptr)
+{
+ double back = -1.0;
+ if (NULL != psptr) {
+ back = psptr->t;
+ }
+ return back;
+}
+
+
+
+double
+dk4papersize_get_bottom_border(const dk4_paper_size_t *psptr)
+{
+ double back = -1.0;
+ if (NULL != psptr) {
+ back = psptr->b;
+ }
+ return back;
+}
+
+
+
+const dkChar *
+dk4papersize_get_name(const dk4_paper_size_t *psptr)
+{
+ const dkChar *back = NULL;
+ if (NULL != psptr) {
+ back = psptr->name;
+ }
+ return back;
+}
+
+
+
+size_t
+dk4papersize_coll_size(dk4_paper_size_collection_t *ptr)
+{
+ size_t back = 0;
+ if (NULL != ptr) {
+ dk4sto_it_reset(ptr->i_ps);
+ while (NULL != dk4sto_it_next(ptr->i_ps)) {
+ back++;
+ }
+ }
+ return back;
+}
+
+
+
+void
+dk4papersize_coll_reset(dk4_paper_size_collection_t *ptr)
+{
+ if (NULL != ptr) {
+ dk4sto_it_reset(ptr->i_ps);
+ }
+}
+
+
+
+const dk4_paper_size_t *
+dk4papersize_coll_next(dk4_paper_size_collection_t *ptr)
+{
+ dk4_paper_size_t *back = NULL;
+ if (NULL != ptr) {
+ back = (dk4_paper_size_t *)dk4sto_it_next(ptr->i_ps);
+ }
+ return ((const dk4_paper_size_t *)back);
+}
+
+
+
+const dk4_paper_size_t *
+dk4papersize_coll_get(dk4_paper_size_collection_t *ptr, size_t n)
+{
+ dk4_paper_size_t *back = NULL;
+ size_t i = 0;
+
+ if (NULL != ptr) {
+ dk4sto_it_reset(ptr->i_ps);
+ do {
+ back = (dk4_paper_size_t *)dk4sto_it_next(ptr->i_ps);
+ } while ((NULL != back) && (++i <= n));
+ }
+ return ((const dk4_paper_size_t *)back);
+}
+
+
+
+/** Process one input line.
+ @param obj Reader object.
+ @param line Current line to process.
+ @param lineno Line number.
+ @param erp Error report, may be NULL.
+ @return
+ DK4_TSP_RES_OK if processing succeeded,
+ DK4_TSP_RES_ERROR on errors (can continue),
+ DK4_TSP_RES_FATAL on fatal errors (can not continue).
+
+*/
+
+static
+int
+dk4papersize_line_handler(
+ void *obj,
+ dkChar *line,
+ dk4_um_t lineno,
+ dk4_er_t *erp
+)
+{
+ double val[6]; /* w, h, i, o, t, b */
+ dkChar *tok[16]; /* tokens from the value side */
+ dk4_paper_size_collection_t *coll; /* collection to complete */
+ dk4_paper_size_t *ps; /* paper size to modify */
+ reader_obj_t *rdo; /* reader object */
+ const dkChar *ep; /* end pointer after double value */
+ dkChar *pls; /* Line start */
+ dkChar *pval; /* Start of value side */
+ size_t ntok; /* number of tokens found */
+ size_t i; /* traverse tokens */
+ int back = DK4_TSP_RES_OK;
+
+
+#line 774 "dk4paper.ctr"
+ /* Retrieve pointers
+ */
+ rdo = (reader_obj_t *)obj;
+ coll = rdo->coll;
+ /*
+ Find start of line, ignore empty lines
+ */
+ pls = dk4str_start(line, NULL);
+ if (NULL == pls) {
+
+#line 783 "dk4paper.ctr"
+ goto finished;
+ }
+ /*
+ Ignore comment lines
+ */
+ if (dkT('#') == *pls) {
+
+#line 789 "dk4paper.ctr"
+ goto finished;
+ }
+ /* Find value side
+ */
+ pval = dk4str_chr(pls, dkT('='));
+ if (NULL == pval) {
+ /* ERROR: Syntax */
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ back = DK4_TSP_RES_ERROR;
+ goto finished;
+ }
+ /* Check whether value side contains text
+ */
+ *(pval++) = dkT('\0');
+ pval = dk4str_start(pval, NULL);
+ if (NULL == pval) {
+ /* ERROR: Syntax */
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ back = DK4_TSP_RES_ERROR;
+ goto finished;
+ }
+ /* Check name length
+ */
+ dk4str_rtwh(pls, NULL);
+ if (0 == dk4str_len(pls)) {
+ /* ERROR: Syntax */
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ back = DK4_TSP_RES_ERROR;
+ goto finished;
+ }
+ /* Tokenize string
+ */
+ ntok = dk4str_tokenize(tok, 16, pval, NULL, NULL);
+ if ((2 > ntok) || (6 < ntok)) {
+ /* ERROR: Syntax */
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ back = DK4_TSP_RES_ERROR;
+ goto finished;
+ }
+ /* Initialize values
+ */
+ for (i = 0; i < 6; i++) { val[i] = 0.0; }
+ /*
+ Process tokens to values
+ */
+ for (i = 0; i < ntok; i++) {
+ ep = NULL;
+ if (0 == dk4ma_input_dk_double(&(val[i]), tok[i], &ep, 1, NULL)) {
+ /* ERROR: Syntax */
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ back = DK4_TSP_RES_ERROR;
+ goto finished;
+ }
+ }
+ /* Modify existing paper size or create a new one
+ */
+ ps = (dk4_paper_size_t *)dk4sto_it_find_like(coll->i_ps, pls, 1);
+ if (NULL == ps) {
+ ps = dk4papersize_new(pls, NULL);
+ if (NULL != ps) {
+ if (0 == dk4sto_add(coll->s_ps, ps, NULL)) {
+ /* ERROR: Memory */
+ dk4error_set_simple_error_code(
+ erp, DK4_E_MEMORY_ALLOCATION_FAILED
+ );
+ dk4papersize_delete(ps);
+ ps = NULL;
+ back = DK4_TSP_RES_FATAL;
+ }
+ }
+ else {
+ /* ERROR: Memory */
+ dk4error_set_simple_error_code(erp, DK4_E_MEMORY_ALLOCATION_FAILED);
+ back = DK4_TSP_RES_FATAL;
+ }
+ }
+ if (NULL == ps) { goto finished; }
+ ps->w = val[0]; ps->h = val[1]; ps->i = val[2];
+ ps->o = val[3]; ps->t = val[4]; ps->b = val[5];
+
+ finished:
+
+
+#line 871 "dk4paper.ctr"
+ return back;
+}
+
+
+
+
+/** Apply a file to a paper size collection.
+ @param coll Collection to modify.
+ @param fn Configuration file name.
+ @param enc Encoding used in memory.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on errors.
+*/
+static
+int
+dk4paper_apply_file(
+ dk4_paper_size_collection_t *coll,
+ const dkChar *fn,
+ int enc,
+ dk4_er_t *erp
+)
+{
+ char ib[4096];
+ dkChar il[1024];
+ dk4_tspdk_t tsp;
+ reader_obj_t rdo;
+ dk4_stream_t *istrm = NULL;
+ size_t rb = 0;
+ int cc = 1;
+ int res = 0;
+ int back = 1;
+
+
+#line 903 "dk4paper.ctr"
+ /* Open input stream
+ */
+ istrm = dk4stream_open_file_reader(fn, erp);
+ if (NULL == istrm) { goto finished; }
+ /*
+ Set up reader structure
+ */
+ rdo.coll = coll;
+ /*
+ Set up text processing
+ */
+ res = dk4tspdk_setup_line(
+ &tsp, &rdo, dk4papersize_line_handler, il, DK4_SIZEOF(il,dkChar),
+ enc,
+ (
+ (DK4_ENCODING_UTF8 == enc) ?
+ (DK4_FILE_ENCODING_UTF8) : (DK4_FILE_ENCODING_ASCII)
+ ),
+ erp
+ );
+ if (0 == res) { goto finished; }
+ /*
+ Process input file
+ */
+ res = DK4_TSP_RES_OK;
+ do {
+
+
+#line 930 "dk4paper.ctr"
+ cc = 0;
+ rb = sizeof(ib);
+ if (0 != dk4stream_read(ib, &rb, istrm, erp)) {
+
+#line 933 "dk4paper.ctr"
+ if (0 < rb) {
+
+#line 934 "dk4paper.ctr"
+ res = dk4tspdk_add_bytes(&tsp, (const unsigned char *)ib, rb);
+ if (DK4_TSP_RES_FATAL == res) {
+
+#line 936 "dk4paper.ctr"
+ back = 0;
+ }
+ else {
+
+#line 939 "dk4paper.ctr"
+ cc = 1;
+ }
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 944 "dk4paper.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 949 "dk4paper.ctr"
+ }
+#endif
+
+
+#line 952 "dk4paper.ctr"
+ } while (1 == cc);
+ /*
+ Finalize text stream processor
+ */
+ if (DK4_TSP_RES_FATAL != res) {
+ if (DK4_TSP_RES_FATAL == dk4tspdk_finish(&tsp)) {
+
+#line 958 "dk4paper.ctr"
+ back = 0;
+ }
+ }
+
+ finished:
+ if (NULL != istrm) { dk4stream_close(istrm, NULL); }
+
+
+#line 965 "dk4paper.ctr"
+ return back;
+}
+
+
+
+dk4_paper_size_collection_t *
+dk4papersize_coll_for_application(
+ const dkChar *progname,
+ const dkChar *grpname,
+ dk4_er_t *erp
+)
+{
+ dkChar fnb[DK4_MAX_PATH]; /* Construct filename */
+ dkChar home[DK4_MAX_PATH]; /* User home dir */
+ dkChar langbuf[16]; /* Language */
+ dkChar regbuf[16]; /* Region */
+ dk4_paper_size_collection_t *back = NULL; /* Result */
+ size_t i; /* File search index */
+ int enc; /* Encoding */
+ int res; /* Operation result */
+ int ok; /* Flag: No error */
+
+
+#line 987 "dk4paper.ctr"
+ /* Create default collection
+ */
+ back = dk4papersize_coll_open(erp);
+ if (NULL == back) {
+
+#line 991 "dk4paper.ctr"
+ goto finished;
+ }
+
+#line 993 "dk4paper.ctr"
+ /* Check program and program group name
+ */
+ if ((NULL == progname) || (NULL == grpname)) {
+
+#line 996 "dk4paper.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+
+#line 999 "dk4paper.ctr"
+ /* Find users home directory.
+ */
+ if (0 == dk4user_get_homedir(home, DK4_SIZEOF(home,dkChar), 0, NULL)) {
+ goto finished;
+ }
+
+#line 1004 "dk4paper.ctr"
+ /* Find encoding
+ */
+ res = dk4loc_get_settings(
+ langbuf, DK4_SIZEOF(langbuf,dkChar), regbuf, DK4_SIZEOF(regbuf,dkChar),
+ &enc, NULL
+ );
+
+#line 1010 "dk4paper.ctr"
+ if (0 == res) {
+ enc = DK4_ENCODING_ASCII;
+ }
+
+#line 1013 "dk4paper.ctr"
+ /* Apply configuration files from build-in directory names
+ */
+ ok = 1;
+ for (i = 0; i <= DK4_FS_CONF_MAX; i++) {
+#if DK4_HAVE_COMPATDKTOOLS3
+ res = dk4fs_config_compat_one(
+ fnb, DK4_SIZEOF(fnb,dkChar), conf_file_names[1],
+ dk4inst_get_directory(2), dk4inst_get_directory(1), home,
+ progname, grpname, i, 1, 1, NULL
+ );
+ if (0 != res) {
+
+#line 1024 "dk4paper.ctr"
+ if (0 == dk4paper_apply_file(back, fnb, enc, erp)) {
+ ok = 0;
+
+#line 1026 "dk4paper.ctr"
+ }
+ }
+#endif
+ res = dk4fs_config_one(
+ fnb, DK4_SIZEOF(fnb,dkChar), conf_file_names[0],
+ dk4inst_get_directory(2), dk4inst_get_directory(1), home,
+ progname, grpname, i, 1, NULL
+ );
+ if (0 != res) {
+
+#line 1035 "dk4paper.ctr"
+ if (0 == dk4paper_apply_file(back, fnb, enc, erp)) {
+ ok = 0;
+
+#line 1037 "dk4paper.ctr"
+ }
+ }
+ }
+ if (0 == ok) {
+
+#line 1041 "dk4paper.ctr"
+ dk4papersize_coll_close(back);
+ back = NULL;
+ }
+
+ finished:
+
+
+#line 1047 "dk4paper.ctr"
+ return back;
+}
+
+
+
+/* vim: set ai sw=4 ts=4 : */
+
diff --git a/support/dktools/dk4paper.ctr b/support/dktools/dk4paper.ctr
new file mode 100644
index 0000000000..81055ba1be
--- /dev/null
+++ b/support/dktools/dk4paper.ctr
@@ -0,0 +1,1053 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+
+%% header
+
+/** @file dk4paper.h Read paper sizes.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4STO_H_INCLUDED
+#include "dk4sto.h"
+#endif
+
+
+/** One paper size.
+*/
+typedef struct {
+ dkChar *name; /**< Paper format name. */
+ double w; /**< Paper width in PS points. */
+ double h; /**< Paper height. */
+ double i; /**< Left or inner border. */
+ double o; /**< Right or outer border. */
+ double t; /**< Top border. */
+ double b; /**< Bottom border. */
+} dk4_paper_size_t;
+
+
+/** Collection of paper sizes read from files.
+*/
+typedef struct {
+ dk4_sto_t *s_ps; /**< Storage for paper sizes. */
+ dk4_sto_it_t *i_ps; /**< Iterator through storage. */
+} dk4_paper_size_collection_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** Open a new paper size collection with minimum entries only.
+ @param erp Error report, may be NULL.
+*/
+
+dk4_paper_size_collection_t *
+dk4papersize_coll_open(dk4_er_t *erp);
+
+
+/** Open a new paper size collection, search for configuration files
+ and apply them.
+ Note: Programs using the dk4_app_t type should use the
+ dk4app_get_paper_sizes() from the dk4papea module instead.
+ @param progname Program name.
+ @param grpname Program group name.
+ @param erp Error report, may be NULL.
+ @return Valid pointer on success, NULL on error.
+*/
+
+dk4_paper_size_collection_t *
+dk4papersize_coll_for_application(
+ const dkChar *progname,
+ const dkChar *grpname,
+ dk4_er_t *erp
+);
+
+
+/** Close paper size collection, release memory.
+ @param ptr Paper size collection to close.
+*/
+
+void
+dk4papersize_coll_close(dk4_paper_size_collection_t *ptr);
+
+
+/** Find a specific paper size in the collection.
+ Note: Do not mix search and traversal mechanism, use exactly
+ one method from the following three:
+ - Find paper size entry by name using dk4papersize_coll_find(),
+ - Get number of paper sizes using dk4papersize_coll_size() and use
+ dk4papersize_coll_get() to get an entry for a given index,
+ - Reset the collection using dk4papersize_coll_reset() and retrieve
+ the next entry using dk4papersize_coll_next(), repeat
+ dk4papersize_coll_next() until it returns NULL.
+ All three methods use and modify the same internal container iterator,
+ so mixing the methods is not a good idea.
+ @param ptr Paper size collection to search for a paper size.
+ @param name Name of paper size to find.
+ @param erp Error report, may be NULL.
+ @return Pointer to paper size on success, NULL on error or not found.
+*/
+
+const dk4_paper_size_t *
+dk4papersize_coll_find(
+ dk4_paper_size_collection_t *ptr,
+ const dkChar *name,
+ dk4_er_t *erp
+);
+
+
+/** Get number of paper sizes stored in the collection.
+ Note: Do not mix search and traversal mechanism, use exactly
+ one method from the following three:
+ - Find paper size entry by name using dk4papersize_coll_find(),
+ - Get number of paper sizes using dk4papersize_coll_size() and use
+ dk4papersize_coll_get() to get an entry for a given index,
+ - Reset the collection using dk4papersize_coll_reset() and retrieve
+ the next entry using dk4papersize_coll_next(), repeat
+ dk4papersize_coll_next() until it returns NULL.
+ All three methods use and modify the same internal container iterator,
+ so mixing the methods is not a good idea.
+ @param ptr Paper size collection to query.
+ @return Positive number of paper sizes on success, 0 on error.
+*/
+
+size_t
+dk4papersize_coll_size(dk4_paper_size_collection_t *ptr);
+
+
+/** Get paper size entry from collection by number.
+ Note: Do not mix search and traversal mechanism, use exactly
+ one method from the following three:
+ - Find paper size entry by name using dk4papersize_coll_find(),
+ - Get number of paper sizes using dk4papersize_coll_size() and use
+ dk4papersize_coll_get() to get an entry for a given index,
+ - Reset the collection using dk4papersize_coll_reset() and retrieve
+ the next entry using dk4papersize_coll_next(), repeat
+ dk4papersize_coll_next() until it returns NULL.
+ All three methods use and modify the same internal container iterator,
+ so mixing the methods is not a good idea.
+ @param ptr Paper size collection to query.
+ @param n Index of paper size entry, 0 for the first.
+ @return Valid pointer on success, NULL on error.
+*/
+
+const dk4_paper_size_t *
+dk4papersize_coll_get(dk4_paper_size_collection_t *ptr, size_t n);
+
+
+/** Reset collection (start traversing at beginning).
+ Note: Do not mix search and traversal mechanism, use exactly
+ one method from the following three:
+ - Find paper size entry by name using dk4papersize_coll_find(),
+ - Get number of paper sizes using dk4papersize_coll_size() and use
+ dk4papersize_coll_get() to get an entry for a given index,
+ - Reset the collection using dk4papersize_coll_reset() and retrieve
+ the next entry using dk4papersize_coll_next(), repeat
+ dk4papersize_coll_next() until it returns NULL.
+ All three methods use and modify the same internal container iterator,
+ so mixing the methods is not a good idea.
+ @param ptr Paper size collection to reset.
+*/
+
+void
+dk4papersize_coll_reset(dk4_paper_size_collection_t *ptr);
+
+
+/** Get next paper size from collection.
+ Note: Do not mix search and traversal mechanism, use exactly
+ one method from the following three:
+ - Find paper size entry by name using dk4papersize_coll_find(),
+ - Get number of paper sizes using dk4papersize_coll_size() and use
+ dk4papersize_coll_get() to get an entry for a given index,
+ - Reset the collection using dk4papersize_coll_reset() and retrieve
+ the next entry using dk4papersize_coll_next(), repeat
+ dk4papersize_coll_next() until it returns NULL.
+ All three methods use and modify the same internal container iterator,
+ so mixing the methods is not a good idea.
+ @param ptr Paper size collection to query.
+ @return Valid pointer on success, NULL on error or end of collection.
+*/
+
+const dk4_paper_size_t *
+dk4papersize_coll_next(dk4_paper_size_collection_t *ptr);
+
+
+/** Create a new paper size structure, allocate memory.
+ @param name Name of paper size.
+ @param erp Error report, may be NULL.
+ @return Pointer to new paper size structure on success, NULL on error.
+*/
+
+dk4_paper_size_t *
+dk4papersize_new(const dkChar *name, dk4_er_t *erp);
+
+
+/** Destroy a paper size structure, release memory.
+ @param pps Paper size structure to destroy.
+*/
+
+void
+dk4papersize_delete(dk4_paper_size_t *pps);
+
+
+/** Compare two paper sizes.
+ @param l Left object pointer.
+ @param r Right object or name pointer.
+ @param cr Comparison criteria: 0=papersize/papersize, 1=papersize/name.
+ @return Comparison result.
+*/
+
+int
+dk4papersize_cmp(const void *l, const void *r, int cr);
+
+
+/** Get paper width from paper size record.
+ @param psptr Paper size record to query.
+ @return Positive result on success, negative value on error.
+*/
+
+double
+dk4papersize_get_width(const dk4_paper_size_t *psptr);
+
+
+/** Get paper height from paper size record.
+ @param psptr Paper size record to query.
+ @return Positive result on success, negative value on error.
+*/
+
+double
+dk4papersize_get_height(const dk4_paper_size_t *psptr);
+
+
+/** Get left (inner) border from paper size record.
+ @param psptr Paper size record to query.
+ @return Non-negative result on success, negative value on error.
+*/
+
+double
+dk4papersize_get_left_border(const dk4_paper_size_t *psptr);
+
+
+/** Get right (outer) border from paper size record.
+ @param psptr Paper size record to query.
+ @return Non-negative result on success, negative value on error.
+*/
+
+double
+dk4papersize_get_right_border(const dk4_paper_size_t *psptr);
+
+
+/** Get top border from paper size record.
+ @param psptr Paper size record to query.
+ @return Non-negative result on success, negative value on error.
+*/
+
+double
+dk4papersize_get_top_border(const dk4_paper_size_t *psptr);
+
+
+/** Get bottom border from paper size record.
+ @param psptr Paper size record to query.
+ @return Non-negative result on success, negative value on error.
+*/
+
+double
+dk4papersize_get_bottom_border(const dk4_paper_size_t *psptr);
+
+
+/** Get name for paper size.
+ @param psptr Paper size record to query.
+ @return Valid pointer on success, NULL on error or empty name.
+*/
+
+const dkChar *
+dk4papersize_get_name(const dk4_paper_size_t *psptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/* vim: set ai sw=4 ts=4 : */
+%% module
+
+#include "dk4mem.h"
+#include "dk4strd.h"
+#include "dk4paper.h"
+#include "dk4maiddbl.h"
+#include "dk4fs.h"
+#include "dk4mpl.h"
+#include "dk4tspdk.h"
+#include "dk4strm.h"
+#include "dk4strmr.h"
+#include "dk4enc.h"
+#include "dk4loc.h"
+#include "dk4user.h"
+#include "dk4inst.h"
+
+
+
+$!trace-include
+
+
+
+/** Object passed as pointer to the line handler.
+*/
+typedef struct {
+ dk4_paper_size_collection_t *coll; /**< Collection to modify. */
+} reader_obj_t;
+
+
+
+/** Configuration files to search for.
+*/
+static const dkChar * const conf_file_names[] = {
+ dkT("dk4paper.conf"),
+ dkT("dk3paper.conf")
+};
+
+
+
+/** Default paper size names always defined.
+*/
+static const dkChar *default_paper_sizes[] = {
+$!string-table macro=dkT
+A4
+a4
+Letter
+letter
+$!end
+};
+
+
+
+void
+dk4papersize_delete(dk4_paper_size_t *pps)
+{
+ $? "+ dk4papersize_delete"
+ if (NULL != pps) { $? ". args ok"
+ if (NULL != pps->name) { $? ". name=\"%!ds\"", pps->name
+ $? ". w=%g h=%g l=%g r=%g t=%g, b=%g", pps->w, pps->h, pps->i, pps->o, pps->t, pps->b
+ dk4mem_free(pps->name);
+ pps->name = NULL;
+ }
+ dk4mem_free(pps);
+ }
+#if TRACE_DEBUG
+ else { $? "! pps"
+ }
+#endif
+ $? "- dk4papersize_delete"
+}
+
+
+
+dk4_paper_size_t *
+dk4papersize_new(const dkChar *name, dk4_er_t *erp)
+{
+ dk4_paper_size_t *back = NULL;
+ $? "+ dk4papersize_new \"%!ds\"", TR_STR(name)
+ if (NULL != name) {
+ back = dk4mem_new(dk4_paper_size_t,1,erp);
+ if (NULL != back) {
+ back->w = 0.0;
+ back->h = 0.0;
+ back->i = 0.0;
+ back->o = 0.0;
+ back->t = 0.0;
+ back->b = 0.0;
+ back->name = dk4str_dup(name, erp);
+ if (NULL == back->name) {
+ dk4mem_free(back);
+ back = NULL;
+ }
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4papersize_new %d", TR_IPTR(back)
+ return back;
+}
+
+
+
+
+void
+dk4papersize_coll_close(dk4_paper_size_collection_t *ptr)
+{
+ dk4_paper_size_t *pps;
+ $? "+ dk4papersize_coll_close %d", TR_IPTR(ptr)
+ if (NULL != ptr) { $? ". ptr ok"
+ if (NULL != ptr->s_ps) { $? ". s_ps ok"
+ if (NULL != ptr->i_ps) { $? ". i_ps ok"
+ dk4sto_it_reset(ptr->i_ps);
+ do {
+ pps = (dk4_paper_size_t *)dk4sto_it_next(ptr->i_ps);
+ if (NULL != pps) { $? ". pps"
+ dk4papersize_delete(pps);
+ }
+ } while (NULL != pps);
+ dk4sto_it_close(ptr->i_ps);
+ ptr->i_ps = NULL;
+ }
+#if TRACE_DEBUG
+ else { $? "! i_ps"
+ }
+#endif
+ dk4sto_close(ptr->s_ps);
+ ptr->s_ps = NULL;
+ }
+#if TRACE_DEBUG
+ else { $? "! s_ps"
+ }
+#endif
+ $? ". release memory"
+ dk4mem_free(ptr);
+ }
+#if TRACE_DEBUG
+ else { $? "! ptr"
+ }
+#endif
+ $? "- dk4papersize_coll_close"
+}
+
+
+
+
+int
+dk4papersize_cmp(const void *l, const void *r, int cr)
+{
+ const dk4_paper_size_t *pl = NULL;
+ const dk4_paper_size_t *pr = NULL;
+ const dkChar *nm = NULL;
+ int back = 0;
+
+ if (NULL != l) {
+ if (NULL != r) {
+ pl = (const dk4_paper_size_t *)l;
+ switch (cr) {
+ case 1 : {
+ nm = (const dkChar *)r;
+ back = dk4str_cmp(pl->name, nm);
+ } break;
+ default : {
+ pr = (const dk4_paper_size_t *)r;
+ back = dk4str_cmp(pl->name, pr->name);
+ } break;
+ }
+ }
+ else {
+ back = 1;
+ }
+ }
+ else {
+ if (NULL != r) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+static
+int
+dk4papersize_i_add_one_default_size(
+ dk4_paper_size_collection_t *pscptr,
+ const dkChar *name,
+ double w,
+ double h,
+ double i,
+ double o,
+ double t,
+ double b,
+ dk4_er_t *erp
+)
+{
+ dk4_paper_size_t *ptr;
+ int back = 0;
+ $? "+ dk4papersize_i_add_one_default_size \"%!ds\"", name
+ ptr = dk4papersize_new(name, erp);
+ if (NULL != ptr) { $? ". ptr"
+ ptr->w = w; ptr->h = h; ptr->i = i; ptr->o = o; ptr->t = t; ptr->b = b;
+ $? ". w = %g", w
+ $? ". h = %g", h
+ $? ". i = %g", i
+ $? ". o = %g", o
+ $? ". t = %g", t
+ $? ". b = %g", b
+ if (0 != dk4sto_add(pscptr->s_ps, ptr, erp)) {
+ back = 1; $? ". add"
+ }
+ else { $? "! add"
+ dk4papersize_delete(ptr);
+ ptr = NULL;
+ }
+ }
+#if TRACE_DEBUG
+ else { $? "! ptr"
+ }
+#endif
+ $? "- dk4papersize_i_add_one_default_size %d", back
+ return back;
+}
+
+
+
+static
+int
+dk4papersize_i_add_default_sizes(
+ dk4_paper_size_collection_t *pscptr,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+ $? "+ dk4papersize_i_add_default_sizes"
+ back = dk4papersize_i_add_one_default_size(
+ pscptr, default_paper_sizes[0], 595.0, 842.0, 0.0, 0.0, 0.0, 0.0, erp
+ );
+ if (0 == back) { goto finished; }
+
+ back = dk4papersize_i_add_one_default_size(
+ pscptr, default_paper_sizes[1], 595.0, 842.0, 56.0, 28.0, 14.0, 14.0, erp
+ );
+ if (0 == back) { goto finished; }
+
+ back = dk4papersize_i_add_one_default_size(
+ pscptr, default_paper_sizes[2], 612.0, 792.0, 0.0, 0.0, 0.0, 0.0, erp
+ );
+ if (0 == back) { goto finished; }
+
+ back = dk4papersize_i_add_one_default_size(
+ pscptr, default_paper_sizes[3], 612.0, 792.0, 56.0, 28.0, 14.0, 14.0, erp
+ );
+ if (0 == back) { goto finished; }
+
+ back = 1;
+
+ finished:
+ $? "- dk4papersize_i_add_default_sizes %d", back
+ return back;
+}
+
+
+
+
+dk4_paper_size_collection_t *
+dk4papersize_coll_open(dk4_er_t *erp)
+{
+ dk4_paper_size_collection_t *back = NULL;
+ int ok = 0;
+ $? "+ dk4papersize_coll_open"
+ back = dk4mem_new(dk4_paper_size_collection_t,1,erp);
+ if (NULL != back) {
+ back->i_ps = NULL;
+ back->s_ps = dk4sto_open(erp);
+ if (NULL != back->s_ps) {
+ (void)dk4sto_set_comp(back->s_ps, dk4papersize_cmp, 0);
+ back->i_ps = dk4sto_it_open(back->s_ps, erp);
+ if (NULL != back->i_ps) {
+ ok = dk4papersize_i_add_default_sizes(back, erp);
+ }
+ }
+ if (0 == ok) {
+ dk4papersize_coll_close(back);
+ back = NULL;
+ }
+ } $? "- dk4papersize_coll_open %d", TR_IPTR(back)
+ return back;
+}
+
+
+
+
+const dk4_paper_size_t *
+dk4papersize_coll_find(
+ dk4_paper_size_collection_t *ptr,
+ const dkChar *name,
+ dk4_er_t *erp
+)
+{
+ dk4_paper_size_t *back = NULL;
+ $? "+ dk4papersize_coll_find %d \"%!ds\"", TR_IPTR(ptr), TR_STR(name)
+ if ((NULL != ptr) && (NULL != name)) {
+ back = (dk4_paper_size_t *)dk4sto_it_find_like(ptr->i_ps, name, 1);
+ if (NULL == back) {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4papersize_coll_find %d", TR_IPTR(back)
+ return ((const dk4_paper_size_t *)back);
+}
+
+
+
+double
+dk4papersize_get_width(const dk4_paper_size_t *psptr)
+{
+ double back = -1.0;
+ if (NULL != psptr) {
+ back = psptr->w;
+ }
+ return back;
+}
+
+
+
+double
+dk4papersize_get_height(const dk4_paper_size_t *psptr)
+{
+ double back = -1.0;
+ if (NULL != psptr) {
+ back = psptr->h;
+ }
+ return back;
+}
+
+
+
+double
+dk4papersize_get_left_border(const dk4_paper_size_t *psptr)
+{
+ double back = -1.0;
+ if (NULL != psptr) {
+ back = psptr->i;
+ }
+ return back;
+}
+
+
+
+double
+dk4papersize_get_right_border(const dk4_paper_size_t *psptr)
+{
+ double back = -1.0;
+ if (NULL != psptr) {
+ back = psptr->o;
+ }
+ return back;
+}
+
+
+
+double
+dk4papersize_get_top_border(const dk4_paper_size_t *psptr)
+{
+ double back = -1.0;
+ if (NULL != psptr) {
+ back = psptr->t;
+ }
+ return back;
+}
+
+
+
+double
+dk4papersize_get_bottom_border(const dk4_paper_size_t *psptr)
+{
+ double back = -1.0;
+ if (NULL != psptr) {
+ back = psptr->b;
+ }
+ return back;
+}
+
+
+
+const dkChar *
+dk4papersize_get_name(const dk4_paper_size_t *psptr)
+{
+ const dkChar *back = NULL;
+ if (NULL != psptr) {
+ back = psptr->name;
+ }
+ return back;
+}
+
+
+
+size_t
+dk4papersize_coll_size(dk4_paper_size_collection_t *ptr)
+{
+ size_t back = 0;
+ if (NULL != ptr) {
+ dk4sto_it_reset(ptr->i_ps);
+ while (NULL != dk4sto_it_next(ptr->i_ps)) {
+ back++;
+ }
+ }
+ return back;
+}
+
+
+
+void
+dk4papersize_coll_reset(dk4_paper_size_collection_t *ptr)
+{
+ if (NULL != ptr) {
+ dk4sto_it_reset(ptr->i_ps);
+ }
+}
+
+
+
+const dk4_paper_size_t *
+dk4papersize_coll_next(dk4_paper_size_collection_t *ptr)
+{
+ dk4_paper_size_t *back = NULL;
+ if (NULL != ptr) {
+ back = (dk4_paper_size_t *)dk4sto_it_next(ptr->i_ps);
+ }
+ return ((const dk4_paper_size_t *)back);
+}
+
+
+
+const dk4_paper_size_t *
+dk4papersize_coll_get(dk4_paper_size_collection_t *ptr, size_t n)
+{
+ dk4_paper_size_t *back = NULL;
+ size_t i = 0;
+
+ if (NULL != ptr) {
+ dk4sto_it_reset(ptr->i_ps);
+ do {
+ back = (dk4_paper_size_t *)dk4sto_it_next(ptr->i_ps);
+ } while ((NULL != back) && (++i <= n));
+ }
+ return ((const dk4_paper_size_t *)back);
+}
+
+
+
+/** Process one input line.
+ @param obj Reader object.
+ @param line Current line to process.
+ @param lineno Line number.
+ @param erp Error report, may be NULL.
+ @return
+ DK4_TSP_RES_OK if processing succeeded,
+ DK4_TSP_RES_ERROR on errors (can continue),
+ DK4_TSP_RES_FATAL on fatal errors (can not continue).
+
+*/
+
+static
+int
+dk4papersize_line_handler(
+ void *obj,
+ dkChar *line,
+ dk4_um_t lineno,
+ dk4_er_t *erp
+)
+{
+ double val[6]; /* w, h, i, o, t, b */
+ dkChar *tok[16]; /* tokens from the value side */
+ dk4_paper_size_collection_t *coll; /* collection to complete */
+ dk4_paper_size_t *ps; /* paper size to modify */
+ reader_obj_t *rdo; /* reader object */
+ const dkChar *ep; /* end pointer after double value */
+ dkChar *pls; /* Line start */
+ dkChar *pval; /* Start of value side */
+ size_t ntok; /* number of tokens found */
+ size_t i; /* traverse tokens */
+ int back = DK4_TSP_RES_OK;
+ $? "+ dk4papersize_line_handler \"%!ds\"", line
+ /* Retrieve pointers
+ */
+ rdo = (reader_obj_t *)obj;
+ coll = rdo->coll;
+ /*
+ Find start of line, ignore empty lines
+ */
+ pls = dk4str_start(line, NULL);
+ if (NULL == pls) { $? ". empty line"
+ goto finished;
+ }
+ /*
+ Ignore comment lines
+ */
+ if (dkT('#') == *pls) { $? ". comment"
+ goto finished;
+ }
+ /* Find value side
+ */
+ pval = dk4str_chr(pls, dkT('='));
+ if (NULL == pval) {
+ /* ERROR: Syntax */
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ back = DK4_TSP_RES_ERROR;
+ goto finished;
+ }
+ /* Check whether value side contains text
+ */
+ *(pval++) = dkT('\0');
+ pval = dk4str_start(pval, NULL);
+ if (NULL == pval) {
+ /* ERROR: Syntax */
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ back = DK4_TSP_RES_ERROR;
+ goto finished;
+ }
+ /* Check name length
+ */
+ dk4str_rtwh(pls, NULL);
+ if (0 == dk4str_len(pls)) {
+ /* ERROR: Syntax */
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ back = DK4_TSP_RES_ERROR;
+ goto finished;
+ }
+ /* Tokenize string
+ */
+ ntok = dk4str_tokenize(tok, 16, pval, NULL, NULL);
+ if ((2 > ntok) || (6 < ntok)) {
+ /* ERROR: Syntax */
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ back = DK4_TSP_RES_ERROR;
+ goto finished;
+ }
+ /* Initialize values
+ */
+ for (i = 0; i < 6; i++) { val[i] = 0.0; }
+ /*
+ Process tokens to values
+ */
+ for (i = 0; i < ntok; i++) {
+ ep = NULL;
+ if (0 == dk4ma_input_dk_double(&(val[i]), tok[i], &ep, 1, NULL)) {
+ /* ERROR: Syntax */
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ back = DK4_TSP_RES_ERROR;
+ goto finished;
+ }
+ }
+ /* Modify existing paper size or create a new one
+ */
+ ps = (dk4_paper_size_t *)dk4sto_it_find_like(coll->i_ps, pls, 1);
+ if (NULL == ps) {
+ ps = dk4papersize_new(pls, NULL);
+ if (NULL != ps) {
+ if (0 == dk4sto_add(coll->s_ps, ps, NULL)) {
+ /* ERROR: Memory */
+ dk4error_set_simple_error_code(
+ erp, DK4_E_MEMORY_ALLOCATION_FAILED
+ );
+ dk4papersize_delete(ps);
+ ps = NULL;
+ back = DK4_TSP_RES_FATAL;
+ }
+ }
+ else {
+ /* ERROR: Memory */
+ dk4error_set_simple_error_code(erp, DK4_E_MEMORY_ALLOCATION_FAILED);
+ back = DK4_TSP_RES_FATAL;
+ }
+ }
+ if (NULL == ps) { goto finished; }
+ ps->w = val[0]; ps->h = val[1]; ps->i = val[2];
+ ps->o = val[3]; ps->t = val[4]; ps->b = val[5];
+
+ finished:
+ $? "- dk4papersize_line_handler %d", back
+ return back;
+}
+
+
+
+
+/** Apply a file to a paper size collection.
+ @param coll Collection to modify.
+ @param fn Configuration file name.
+ @param enc Encoding used in memory.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on errors.
+*/
+static
+int
+dk4paper_apply_file(
+ dk4_paper_size_collection_t *coll,
+ const dkChar *fn,
+ int enc,
+ dk4_er_t *erp
+)
+{
+ char ib[4096];
+ dkChar il[1024];
+ dk4_tspdk_t tsp;
+ reader_obj_t rdo;
+ dk4_stream_t *istrm = NULL;
+ size_t rb = 0;
+ int cc = 1;
+ int res = 0;
+ int back = 1;
+ $? "+ dk4paper_apply_file \"%!ds\"", fn
+ /* Open input stream
+ */
+ istrm = dk4stream_open_file_reader(fn, erp);
+ if (NULL == istrm) { goto finished; }
+ /*
+ Set up reader structure
+ */
+ rdo.coll = coll;
+ /*
+ Set up text processing
+ */
+ res = dk4tspdk_setup_line(
+ &tsp, &rdo, dk4papersize_line_handler, il, DK4_SIZEOF(il,dkChar),
+ enc,
+ (
+ (DK4_ENCODING_UTF8 == enc) ?
+ (DK4_FILE_ENCODING_UTF8) : (DK4_FILE_ENCODING_ASCII)
+ ),
+ erp
+ );
+ if (0 == res) { goto finished; }
+ /*
+ Process input file
+ */
+ res = DK4_TSP_RES_OK;
+ do {
+ $? ". start of loop"
+ cc = 0;
+ rb = sizeof(ib);
+ if (0 != dk4stream_read(ib, &rb, istrm, erp)) { $? ". read ok"
+ if (0 < rb) { $? ". rb ok"
+ res = dk4tspdk_add_bytes(&tsp, (const unsigned char *)ib, rb);
+ if (DK4_TSP_RES_FATAL == res) { $? "! fatal error"
+ back = 0;
+ }
+ else { $? ". processing ok"
+ cc = 1;
+ }
+ }
+#if TRACE_DEBUG
+ else { $? ". rb = 0"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! read"
+ }
+#endif
+ $? ". end of loop"
+ } while (1 == cc);
+ /*
+ Finalize text stream processor
+ */
+ if (DK4_TSP_RES_FATAL != res) {
+ if (DK4_TSP_RES_FATAL == dk4tspdk_finish(&tsp)) { $? "! fatal"
+ back = 0;
+ }
+ }
+
+ finished:
+ if (NULL != istrm) { dk4stream_close(istrm, NULL); }
+ $? "- dk4paper_apply_file %d", back
+ return back;
+}
+
+
+
+dk4_paper_size_collection_t *
+dk4papersize_coll_for_application(
+ const dkChar *progname,
+ const dkChar *grpname,
+ dk4_er_t *erp
+)
+{
+ dkChar fnb[DK4_MAX_PATH]; /* Construct filename */
+ dkChar home[DK4_MAX_PATH]; /* User home dir */
+ dkChar langbuf[16]; /* Language */
+ dkChar regbuf[16]; /* Region */
+ dk4_paper_size_collection_t *back = NULL; /* Result */
+ size_t i; /* File search index */
+ int enc; /* Encoding */
+ int res; /* Operation result */
+ int ok; /* Flag: No error */
+ $? "+ dk4_paper_size_collection_t"
+ /* Create default collection
+ */
+ back = dk4papersize_coll_open(erp);
+ if (NULL == back) { $? "! memory"
+ goto finished;
+ } $? ". collection opened"
+ /* Check program and program group name
+ */
+ if ((NULL == progname) || (NULL == grpname)) { $? "! args"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ } $? ". arguments ok"
+ /* Find users home directory.
+ */
+ if (0 == dk4user_get_homedir(home, DK4_SIZEOF(home,dkChar), 0, NULL)) {
+ goto finished;
+ } $? ". home = \"%!ds\"", home
+ /* Find encoding
+ */
+ res = dk4loc_get_settings(
+ langbuf, DK4_SIZEOF(langbuf,dkChar), regbuf, DK4_SIZEOF(regbuf,dkChar),
+ &enc, NULL
+ ); $? ". enc = %d", enc
+ if (0 == res) {
+ enc = DK4_ENCODING_ASCII;
+ } $? ". enc = %d", enc
+ /* Apply configuration files from build-in directory names
+ */
+ ok = 1;
+ for (i = 0; i <= DK4_FS_CONF_MAX; i++) {
+#if DK4_HAVE_COMPATDKTOOLS3
+ res = dk4fs_config_compat_one(
+ fnb, DK4_SIZEOF(fnb,dkChar), conf_file_names[1],
+ dk4inst_get_directory(2), dk4inst_get_directory(1), home,
+ progname, grpname, i, 1, 1, NULL
+ );
+ if (0 != res) { $? ". apply \"%!ds\"", fnb
+ if (0 == dk4paper_apply_file(back, fnb, enc, erp)) {
+ ok = 0; $? "! failed \"%!ds\"", fnb
+ }
+ }
+#endif
+ res = dk4fs_config_one(
+ fnb, DK4_SIZEOF(fnb,dkChar), conf_file_names[0],
+ dk4inst_get_directory(2), dk4inst_get_directory(1), home,
+ progname, grpname, i, 1, NULL
+ );
+ if (0 != res) { $? ". apply \"%!ds\"", fnb
+ if (0 == dk4paper_apply_file(back, fnb, enc, erp)) {
+ ok = 0; $? "! failed \"%!ds\"", fnb
+ }
+ }
+ }
+ if (0 == ok) { $? "! fatal errors"
+ dk4papersize_coll_close(back);
+ back = NULL;
+ }
+
+ finished:
+ $? "- dk4_paper_size_collection_t %d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/* vim: set ai sw=4 ts=4 : */
+
diff --git a/support/dktools/dk4paper.h b/support/dktools/dk4paper.h
new file mode 100644
index 0000000000..6afcd696ec
--- /dev/null
+++ b/support/dktools/dk4paper.h
@@ -0,0 +1,321 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4paper.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4PAPER_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4PAPER_H_INCLUDED 1
+
+
+#line 9 "dk4paper.ctr"
+
+/** @file dk4paper.h Read paper sizes.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4STO_H_INCLUDED
+#include "dk4sto.h"
+#endif
+
+
+/** One paper size.
+*/
+typedef struct {
+ dkChar *name; /**< Paper format name. */
+ double w; /**< Paper width in PS points. */
+ double h; /**< Paper height. */
+ double i; /**< Left or inner border. */
+ double o; /**< Right or outer border. */
+ double t; /**< Top border. */
+ double b; /**< Bottom border. */
+} dk4_paper_size_t;
+
+
+/** Collection of paper sizes read from files.
+*/
+typedef struct {
+ dk4_sto_t *s_ps; /**< Storage for paper sizes. */
+ dk4_sto_it_t *i_ps; /**< Iterator through storage. */
+} dk4_paper_size_collection_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** Open a new paper size collection with minimum entries only.
+ @param erp Error report, may be NULL.
+*/
+
+dk4_paper_size_collection_t *
+dk4papersize_coll_open(dk4_er_t *erp);
+
+
+/** Open a new paper size collection, search for configuration files
+ and apply them.
+ Note: Programs using the dk4_app_t type should use the
+ dk4app_get_paper_sizes() from the dk4papea module instead.
+ @param progname Program name.
+ @param grpname Program group name.
+ @param erp Error report, may be NULL.
+ @return Valid pointer on success, NULL on error.
+*/
+
+dk4_paper_size_collection_t *
+dk4papersize_coll_for_application(
+ const dkChar *progname,
+ const dkChar *grpname,
+ dk4_er_t *erp
+);
+
+
+/** Close paper size collection, release memory.
+ @param ptr Paper size collection to close.
+*/
+
+void
+dk4papersize_coll_close(dk4_paper_size_collection_t *ptr);
+
+
+/** Find a specific paper size in the collection.
+ Note: Do not mix search and traversal mechanism, use exactly
+ one method from the following three:
+ - Find paper size entry by name using dk4papersize_coll_find(),
+ - Get number of paper sizes using dk4papersize_coll_size() and use
+ dk4papersize_coll_get() to get an entry for a given index,
+ - Reset the collection using dk4papersize_coll_reset() and retrieve
+ the next entry using dk4papersize_coll_next(), repeat
+ dk4papersize_coll_next() until it returns NULL.
+ All three methods use and modify the same internal container iterator,
+ so mixing the methods is not a good idea.
+ @param ptr Paper size collection to search for a paper size.
+ @param name Name of paper size to find.
+ @param erp Error report, may be NULL.
+ @return Pointer to paper size on success, NULL on error or not found.
+*/
+
+const dk4_paper_size_t *
+dk4papersize_coll_find(
+ dk4_paper_size_collection_t *ptr,
+ const dkChar *name,
+ dk4_er_t *erp
+);
+
+
+/** Get number of paper sizes stored in the collection.
+ Note: Do not mix search and traversal mechanism, use exactly
+ one method from the following three:
+ - Find paper size entry by name using dk4papersize_coll_find(),
+ - Get number of paper sizes using dk4papersize_coll_size() and use
+ dk4papersize_coll_get() to get an entry for a given index,
+ - Reset the collection using dk4papersize_coll_reset() and retrieve
+ the next entry using dk4papersize_coll_next(), repeat
+ dk4papersize_coll_next() until it returns NULL.
+ All three methods use and modify the same internal container iterator,
+ so mixing the methods is not a good idea.
+ @param ptr Paper size collection to query.
+ @return Positive number of paper sizes on success, 0 on error.
+*/
+
+size_t
+dk4papersize_coll_size(dk4_paper_size_collection_t *ptr);
+
+
+/** Get paper size entry from collection by number.
+ Note: Do not mix search and traversal mechanism, use exactly
+ one method from the following three:
+ - Find paper size entry by name using dk4papersize_coll_find(),
+ - Get number of paper sizes using dk4papersize_coll_size() and use
+ dk4papersize_coll_get() to get an entry for a given index,
+ - Reset the collection using dk4papersize_coll_reset() and retrieve
+ the next entry using dk4papersize_coll_next(), repeat
+ dk4papersize_coll_next() until it returns NULL.
+ All three methods use and modify the same internal container iterator,
+ so mixing the methods is not a good idea.
+ @param ptr Paper size collection to query.
+ @param n Index of paper size entry, 0 for the first.
+ @return Valid pointer on success, NULL on error.
+*/
+
+const dk4_paper_size_t *
+dk4papersize_coll_get(dk4_paper_size_collection_t *ptr, size_t n);
+
+
+/** Reset collection (start traversing at beginning).
+ Note: Do not mix search and traversal mechanism, use exactly
+ one method from the following three:
+ - Find paper size entry by name using dk4papersize_coll_find(),
+ - Get number of paper sizes using dk4papersize_coll_size() and use
+ dk4papersize_coll_get() to get an entry for a given index,
+ - Reset the collection using dk4papersize_coll_reset() and retrieve
+ the next entry using dk4papersize_coll_next(), repeat
+ dk4papersize_coll_next() until it returns NULL.
+ All three methods use and modify the same internal container iterator,
+ so mixing the methods is not a good idea.
+ @param ptr Paper size collection to reset.
+*/
+
+void
+dk4papersize_coll_reset(dk4_paper_size_collection_t *ptr);
+
+
+/** Get next paper size from collection.
+ Note: Do not mix search and traversal mechanism, use exactly
+ one method from the following three:
+ - Find paper size entry by name using dk4papersize_coll_find(),
+ - Get number of paper sizes using dk4papersize_coll_size() and use
+ dk4papersize_coll_get() to get an entry for a given index,
+ - Reset the collection using dk4papersize_coll_reset() and retrieve
+ the next entry using dk4papersize_coll_next(), repeat
+ dk4papersize_coll_next() until it returns NULL.
+ All three methods use and modify the same internal container iterator,
+ so mixing the methods is not a good idea.
+ @param ptr Paper size collection to query.
+ @return Valid pointer on success, NULL on error or end of collection.
+*/
+
+const dk4_paper_size_t *
+dk4papersize_coll_next(dk4_paper_size_collection_t *ptr);
+
+
+/** Create a new paper size structure, allocate memory.
+ @param name Name of paper size.
+ @param erp Error report, may be NULL.
+ @return Pointer to new paper size structure on success, NULL on error.
+*/
+
+dk4_paper_size_t *
+dk4papersize_new(const dkChar *name, dk4_er_t *erp);
+
+
+/** Destroy a paper size structure, release memory.
+ @param pps Paper size structure to destroy.
+*/
+
+void
+dk4papersize_delete(dk4_paper_size_t *pps);
+
+
+/** Compare two paper sizes.
+ @param l Left object pointer.
+ @param r Right object or name pointer.
+ @param cr Comparison criteria: 0=papersize/papersize, 1=papersize/name.
+ @return Comparison result.
+*/
+
+int
+dk4papersize_cmp(const void *l, const void *r, int cr);
+
+
+/** Get paper width from paper size record.
+ @param psptr Paper size record to query.
+ @return Positive result on success, negative value on error.
+*/
+
+double
+dk4papersize_get_width(const dk4_paper_size_t *psptr);
+
+
+/** Get paper height from paper size record.
+ @param psptr Paper size record to query.
+ @return Positive result on success, negative value on error.
+*/
+
+double
+dk4papersize_get_height(const dk4_paper_size_t *psptr);
+
+
+/** Get left (inner) border from paper size record.
+ @param psptr Paper size record to query.
+ @return Non-negative result on success, negative value on error.
+*/
+
+double
+dk4papersize_get_left_border(const dk4_paper_size_t *psptr);
+
+
+/** Get right (outer) border from paper size record.
+ @param psptr Paper size record to query.
+ @return Non-negative result on success, negative value on error.
+*/
+
+double
+dk4papersize_get_right_border(const dk4_paper_size_t *psptr);
+
+
+/** Get top border from paper size record.
+ @param psptr Paper size record to query.
+ @return Non-negative result on success, negative value on error.
+*/
+
+double
+dk4papersize_get_top_border(const dk4_paper_size_t *psptr);
+
+
+/** Get bottom border from paper size record.
+ @param psptr Paper size record to query.
+ @return Non-negative result on success, negative value on error.
+*/
+
+double
+dk4papersize_get_bottom_border(const dk4_paper_size_t *psptr);
+
+
+/** Get name for paper size.
+ @param psptr Paper size record to query.
+ @return Valid pointer on success, NULL on error or empty name.
+*/
+
+const dkChar *
+dk4papersize_get_name(const dk4_paper_size_t *psptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/* vim: set ai sw=4 ts=4 : */
+
+#endif
diff --git a/support/dktools/dk4path8.c b/support/dktools/dk4path8.c
new file mode 100644
index 0000000000..7507a2ea6f
--- /dev/null
+++ b/support/dktools/dk4path8.c
@@ -0,0 +1,292 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4path8.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4path8.c The dk4path8 module.
+*/
+
+
+#line 109 "dk4path8.ctr"
+
+
+#include "dk4path8.h"
+#include "dk4mem.h"
+#include "dk4str8.h"
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+/** Constant keywords used by the dk4path8 module.
+*/
+static const char * const dk4path8_kw[] = {
+#if DK4_HAVE_BACKSLASH_AS_SEP
+/* 0 */ "\\",
+/* 1 */ "/",
+#else
+/* 0 */ "/",
+/* 1 */ "\\",
+#endif
+/* 2 */ ".",
+/* 3 */ "..",
+/* 4 */ ":"
+};
+
+
+
+/** Get last character from a string.
+
+ CRT on Windows: Not used.
+ @param str String to test.
+ @return Last character from string.
+*/
+static
+char
+dk4path8_lastchar(const char *str)
+{
+ char back = '\0';
+ if (str) { while ('\0' != *str) { back = *(str++); } }
+ return back;
+}
+
+
+
+int
+dk4path8_is_absolute(const char *path)
+{
+ int back = 0;
+#if DK4_ON_WINDOWS
+ char c;
+#endif
+ if (NULL != path) {
+#if DK4_ON_WINDOWS
+ c = *path;
+ if ( *(dk4path8_kw[0]) == c ) {
+ back = 1;
+ } else {
+ if ((('a' <= c) && ('z' >= c)) || (('A' <= c) && ('Z' >= c))) {
+ if ( *(dk4path8_kw[4]) == path[1] ) {
+ c = path[2];
+ if ( ( *(dk4path8_kw[0]) == c ) || ( '\0' == c ) ) {
+ back = 1;
+ }
+ }
+ }
+ }
+#else
+ if ( *(dk4path8_kw[0]) == *path ) {
+ back = 1;
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk4path8_is_relative(const char *path)
+{
+ int back = 0;
+ if (NULL != path) {
+ if (NULL != dk4str8_chr(path, *(dk4path8_kw[0]))) {
+ if (0 == dk4path8_is_absolute(path)) {
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4path8_append(char *buffer, size_t sz, const char *filename, dk4_er_t *erp)
+{
+ char *pc; /* Current path part to append */
+ char *pn; /* Next part to append */
+ char *pd; /* Part to delete */
+ char *mycp = NULL; /* Private copy */
+#if DK4_ON_WINDOWS
+ int ischr;
+#endif
+ int back = 0; /* Function result */
+ int failed = 0; /* Definitely failed */
+ char lch; /* Last character from string */
+
+ if ((NULL != buffer) && (NULL != filename) && (0 < sz)) {
+ mycp = dk4str8_dup(filename, erp);
+ if (NULL != mycp) {
+ pc = mycp;
+ while ((NULL != pc) && (0 == failed)) {
+ pn = dk4str8_chr(pc, *(dk4path8_kw[0]));
+ if (NULL != pn) { *(pn++) = '\0'; }
+ if (0 != dk4str8_cmp(pc, dk4path8_kw[2])) {
+ if (0 == dk4str8_cmp(pc, dk4path8_kw[3])) { /* Remove from buffer */
+ pd = dk4str8_rchr(buffer, *(dk4path8_kw[0]));
+ if (NULL != pd) {
+ *pd = '\0';
+ if (0 < dk4str8_len(&(pd[1]))) {
+#if DK4_ON_WINDOWS
+ if (2 == dk4str8_len(buffer)) {
+ ischr = 0;
+ if (('A' <= buffer[0]) && ('Z' >= buffer[0])) {
+ ischr = 1;
+ }
+ if (('a' <= buffer[0]) && ('z' >= buffer[0])) {
+ ischr = 1;
+ }
+ if (1 == ischr) {
+ if (':' == buffer[1]) {
+ buffer[2] = *(dk4path8_kw[0]);
+ buffer[3] = '\0';
+ }
+ }
+ }
+#else
+ if (0 == dk4str8_len(buffer)) {
+ *pd = *(dk4path8_kw[0]);
+ pd++;
+ *pd = '\0';
+ }
+#endif
+ } else {
+ failed = 1;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ failed = 1;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else { /* Add to buffer */
+ lch = dk4path8_lastchar(buffer);
+ if (lch != *(dk4path8_kw[0])) {
+ if (0 != dk4str8_cat_s(buffer, sz, dk4path8_kw[0], erp)) {
+ if (0 == dk4str8_cat_s(buffer, sz, pc, erp)) {
+ failed = 1;
+ }
+ } else {
+ failed = 1;
+ }
+ } else {
+ if (0 == dk4str8_cat_s(buffer, sz, pc, erp)) {
+ failed = 1;
+ }
+ }
+ }
+ }
+ pc = pn;
+ }
+ if (0 == failed) {
+ back = 1;
+ }
+ dk4mem_release(mycp);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+char *
+dk4path8_get_suffix(const char *filename, dk4_er_t *erp)
+{
+ const char *back = NULL;
+ if (NULL != filename) {
+ while ('\0' != *filename) {
+ if (('\\' == *filename) || ('/' == *filename)) {
+ back = NULL;
+ } else {
+ if ('.' == *filename) {
+ back = filename;
+ }
+ }
+ filename++;
+ }
+ if (NULL == back) {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return ((char *)back);
+}
+
+
+
+void
+dk4path8_correct_sep(char *filename)
+{
+ if (NULL != filename) {
+ while ('\0' != *filename) {
+#if DK4_HAVE_BACKSLASH_AS_SEP
+ if ('/' == *filename) { *filename = '\\'; }
+#else
+ if ('\\' == *filename) { *filename = '/'; }
+#endif
+ filename++;
+ }
+ }
+}
+
+
+
+int
+dk4path8_must_expand(const char *filename)
+{
+#if DK4_ON_WINDOWS
+ int back = 0;
+ if (NULL != filename) {
+ while(('\0' != *filename) && (0 == back)) {
+ switch (*filename) {
+ case '*': case '?': {
+ back = 1;
+ } break;
+ default: {
+ filename++;
+ } break;
+ }
+ }
+ }
+ return back;
+#else
+ return 0;
+#endif
+}
+
diff --git a/support/dktools/dk4path8.ctr b/support/dktools/dk4path8.ctr
new file mode 100644
index 0000000000..d02ca90d65
--- /dev/null
+++ b/support/dktools/dk4path8.ctr
@@ -0,0 +1,360 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ String operations for path names
+ (8 bit characters).
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Check whether a file name is an absolute path.
+ CRT on Windows: Not used.
+ @param path Path name to check.
+ @return 1 for absolute path, 0 for other path.
+*/
+int
+dk4path8_is_absolute(const char *path);
+
+/** Check whether a file name is a relative path.
+ CRT on Windows: Not used.
+ @param path Path name to check.
+ @return 1 for absolute path, 0 for other path.
+*/
+int
+dk4path8_is_relative(const char *path);
+
+/** Append path filename to path name already stored in buffer.
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param buffer Buffer already containing a path.
+ @param sz Buffer size.
+ @param filename Relative file name to append to buffer.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if buffer or filename is NULL or sz is 0,
+ - DK4_E_MATH_OVERFLOW<br>
+ if filename is too long,
+ - DK4_E_MEMORY<br>
+ if allocation of a filename copy fails,
+ - DK4_E_SYNTAX<br>
+ if too many .. in filename,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if buffer size is too small.
+*/
+int
+dk4path8_append(char *buffer, size_t sz, const char *filename, dk4_er_t *erp);
+
+/** Find pointer to suffix.
+ CRT on Windows: Not used.
+ @param filename File name to find suffix for.
+ @param erp Error report, may be NULL.
+ @return Pointer to suffix dot if found, NULL otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if filename is NULL,
+ - DK4_E_NOT_FOUND<br>
+ if the file name does not contain a suffix.
+*/
+char *
+dk4path8_get_suffix(const char *filename, dk4_er_t *erp);
+
+/** Correct file name separators from slash to backslash on Windows,
+ vice versa on other systems.
+ CRT on Windows: Not used.
+ @param filename File name to correct.
+*/
+void
+dk4path8_correct_sep(char *filename);
+
+/** Check whether file name needs expansion on Windows.
+ CRT on Windows: Not used.
+ @param filename File name to check.
+ @return 1 if expansion is necessary, 0 otherwise.
+*/
+int
+dk4path8_must_expand(const char *filename);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+
+#include "dk4path8.h"
+#include "dk4mem.h"
+#include "dk4str8.h"
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+/** Constant keywords used by the dk4path8 module.
+*/
+static const char * const dk4path8_kw[] = {
+#if DK4_HAVE_BACKSLASH_AS_SEP
+/* 0 */ "\\",
+/* 1 */ "/",
+#else
+/* 0 */ "/",
+/* 1 */ "\\",
+#endif
+/* 2 */ ".",
+/* 3 */ "..",
+/* 4 */ ":"
+};
+
+
+
+/** Get last character from a string.
+
+ CRT on Windows: Not used.
+ @param str String to test.
+ @return Last character from string.
+*/
+static
+char
+dk4path8_lastchar(const char *str)
+{
+ char back = '\0';
+ if (str) { while ('\0' != *str) { back = *(str++); } }
+ return back;
+}
+
+
+
+int
+dk4path8_is_absolute(const char *path)
+{
+ int back = 0;
+#if DK4_ON_WINDOWS
+ char c;
+#endif
+ if (NULL != path) {
+#if DK4_ON_WINDOWS
+ c = *path;
+ if ( *(dk4path8_kw[0]) == c ) {
+ back = 1;
+ } else {
+ if ((('a' <= c) && ('z' >= c)) || (('A' <= c) && ('Z' >= c))) {
+ if ( *(dk4path8_kw[4]) == path[1] ) {
+ c = path[2];
+ if ( ( *(dk4path8_kw[0]) == c ) || ( '\0' == c ) ) {
+ back = 1;
+ }
+ }
+ }
+ }
+#else
+ if ( *(dk4path8_kw[0]) == *path ) {
+ back = 1;
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk4path8_is_relative(const char *path)
+{
+ int back = 0;
+ if (NULL != path) {
+ if (NULL != dk4str8_chr(path, *(dk4path8_kw[0]))) {
+ if (0 == dk4path8_is_absolute(path)) {
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4path8_append(char *buffer, size_t sz, const char *filename, dk4_er_t *erp)
+{
+ char *pc; /* Current path part to append */
+ char *pn; /* Next part to append */
+ char *pd; /* Part to delete */
+ char *mycp = NULL; /* Private copy */
+#if DK4_ON_WINDOWS
+ int ischr;
+#endif
+ int back = 0; /* Function result */
+ int failed = 0; /* Definitely failed */
+ char lch; /* Last character from string */
+
+ if ((NULL != buffer) && (NULL != filename) && (0 < sz)) {
+ mycp = dk4str8_dup(filename, erp);
+ if (NULL != mycp) {
+ pc = mycp;
+ while ((NULL != pc) && (0 == failed)) {
+ pn = dk4str8_chr(pc, *(dk4path8_kw[0]));
+ if (NULL != pn) { *(pn++) = '\0'; }
+ if (0 != dk4str8_cmp(pc, dk4path8_kw[2])) {
+ if (0 == dk4str8_cmp(pc, dk4path8_kw[3])) { /* Remove from buffer */
+ pd = dk4str8_rchr(buffer, *(dk4path8_kw[0]));
+ if (NULL != pd) {
+ *pd = '\0';
+ if (0 < dk4str8_len(&(pd[1]))) {
+#if DK4_ON_WINDOWS
+ if (2 == dk4str8_len(buffer)) {
+ ischr = 0;
+ if (('A' <= buffer[0]) && ('Z' >= buffer[0])) {
+ ischr = 1;
+ }
+ if (('a' <= buffer[0]) && ('z' >= buffer[0])) {
+ ischr = 1;
+ }
+ if (1 == ischr) {
+ if (':' == buffer[1]) {
+ buffer[2] = *(dk4path8_kw[0]);
+ buffer[3] = '\0';
+ }
+ }
+ }
+#else
+ if (0 == dk4str8_len(buffer)) {
+ *pd = *(dk4path8_kw[0]);
+ pd++;
+ *pd = '\0';
+ }
+#endif
+ } else {
+ failed = 1;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ failed = 1;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else { /* Add to buffer */
+ lch = dk4path8_lastchar(buffer);
+ if (lch != *(dk4path8_kw[0])) {
+ if (0 != dk4str8_cat_s(buffer, sz, dk4path8_kw[0], erp)) {
+ if (0 == dk4str8_cat_s(buffer, sz, pc, erp)) {
+ failed = 1;
+ }
+ } else {
+ failed = 1;
+ }
+ } else {
+ if (0 == dk4str8_cat_s(buffer, sz, pc, erp)) {
+ failed = 1;
+ }
+ }
+ }
+ }
+ pc = pn;
+ }
+ if (0 == failed) {
+ back = 1;
+ }
+ dk4mem_release(mycp);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+char *
+dk4path8_get_suffix(const char *filename, dk4_er_t *erp)
+{
+ const char *back = NULL;
+ if (NULL != filename) {
+ while ('\0' != *filename) {
+ if (('\\' == *filename) || ('/' == *filename)) {
+ back = NULL;
+ } else {
+ if ('.' == *filename) {
+ back = filename;
+ }
+ }
+ filename++;
+ }
+ if (NULL == back) {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return ((char *)back);
+}
+
+
+
+void
+dk4path8_correct_sep(char *filename)
+{
+ if (NULL != filename) {
+ while ('\0' != *filename) {
+#if DK4_HAVE_BACKSLASH_AS_SEP
+ if ('/' == *filename) { *filename = '\\'; }
+#else
+ if ('\\' == *filename) { *filename = '/'; }
+#endif
+ filename++;
+ }
+ }
+}
+
+
+
+int
+dk4path8_must_expand(const char *filename)
+{
+#if DK4_ON_WINDOWS
+ int back = 0;
+ if (NULL != filename) {
+ while(('\0' != *filename) && (0 == back)) {
+ switch (*filename) {
+ case '*': case '?': {
+ back = 1;
+ } break;
+ default: {
+ filename++;
+ } break;
+ }
+ }
+ }
+ return back;
+#else
+ return 0;
+#endif
+}
+
diff --git a/support/dktools/dk4path8.h b/support/dktools/dk4path8.h
new file mode 100644
index 0000000000..b41b1f2e44
--- /dev/null
+++ b/support/dktools/dk4path8.h
@@ -0,0 +1,142 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4path8.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4PATH8_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4PATH8_H_INCLUDED 1
+
+
+#line 9 "dk4path8.ctr"
+
+/** @file
+ String operations for path names
+ (8 bit characters).
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Check whether a file name is an absolute path.
+ CRT on Windows: Not used.
+ @param path Path name to check.
+ @return 1 for absolute path, 0 for other path.
+*/
+int
+dk4path8_is_absolute(const char *path);
+
+/** Check whether a file name is a relative path.
+ CRT on Windows: Not used.
+ @param path Path name to check.
+ @return 1 for absolute path, 0 for other path.
+*/
+int
+dk4path8_is_relative(const char *path);
+
+/** Append path filename to path name already stored in buffer.
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param buffer Buffer already containing a path.
+ @param sz Buffer size.
+ @param filename Relative file name to append to buffer.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if buffer or filename is NULL or sz is 0,
+ - DK4_E_MATH_OVERFLOW<br>
+ if filename is too long,
+ - DK4_E_MEMORY<br>
+ if allocation of a filename copy fails,
+ - DK4_E_SYNTAX<br>
+ if too many .. in filename,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if buffer size is too small.
+*/
+int
+dk4path8_append(char *buffer, size_t sz, const char *filename, dk4_er_t *erp);
+
+/** Find pointer to suffix.
+ CRT on Windows: Not used.
+ @param filename File name to find suffix for.
+ @param erp Error report, may be NULL.
+ @return Pointer to suffix dot if found, NULL otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if filename is NULL,
+ - DK4_E_NOT_FOUND<br>
+ if the file name does not contain a suffix.
+*/
+char *
+dk4path8_get_suffix(const char *filename, dk4_er_t *erp);
+
+/** Correct file name separators from slash to backslash on Windows,
+ vice versa on other systems.
+ CRT on Windows: Not used.
+ @param filename File name to correct.
+*/
+void
+dk4path8_correct_sep(char *filename);
+
+/** Check whether file name needs expansion on Windows.
+ CRT on Windows: Not used.
+ @param filename File name to check.
+ @return 1 if expansion is necessary, 0 otherwise.
+*/
+int
+dk4path8_must_expand(const char *filename);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4pathd.c b/support/dktools/dk4pathd.c
new file mode 100644
index 0000000000..ba2e722b11
--- /dev/null
+++ b/support/dktools/dk4pathd.c
@@ -0,0 +1,194 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4pathd.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4pathd.c The dk4pathd module.
+*/
+
+
+#line 135 "dk4pathd.ctr"
+
+
+#include "dk4pathd.h"
+#if DK4_CHAR_SIZE > 1
+#include "dk4pathw.h"
+#else
+#include "dk4path8.h"
+#endif
+
+#include "dk4mem.h"
+#include "dk4mpl.h"
+#include "dk4strd.h"
+
+
+
+
+
+#line 151 "dk4pathd.ctr"
+
+
+
+int
+dk4path_is_absolute(const dkChar *path)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4pathw_is_absolute(path));
+#else
+ return (dk4path8_is_absolute(path));
+#endif
+}
+
+
+
+int
+dk4path_is_relative(const dkChar *path)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4pathw_is_relative(path));
+#else
+ return (dk4path8_is_relative(path));
+#endif
+}
+
+
+
+int
+dk4path_append(
+ dkChar *buffer, size_t sz, const dkChar *filename, dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4pathw_append(buffer, sz, filename, erp));
+#else
+ return (dk4path8_append(buffer, sz, filename, erp));
+#endif
+}
+
+
+
+dkChar *
+dk4path_get_suffix(const dkChar *filename, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4pathw_get_suffix(filename, erp));
+#else
+ return (dk4path8_get_suffix(filename, erp));
+#endif
+}
+
+
+
+void
+dk4path_correct_sep(dkChar *filename)
+{
+#if DK4_CHAR_SIZE > 1
+ dk4pathw_correct_sep(filename);
+#else
+ dk4path8_correct_sep(filename);
+#endif
+}
+
+
+
+int
+dk4path_must_expand(const dkChar *filename)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4pathw_must_expand(filename));
+#else
+ return (dk4path8_must_expand(filename));
+#endif
+}
+
+
+
+int
+dk4path_is_in_subdir(const dkChar *filename,const dkChar *parent,dk4_er_t *erp)
+{
+ dkChar buf[DK4_MAX_PATH];
+ size_t szf;
+ size_t szp;
+ int back = 0;
+
+
+#line 236 "dk4pathd.ctr"
+ if ((NULL != filename) && (NULL != parent)) {
+ if (0 != dk4str_cpy_s(buf, DK4_SIZEOF(buf,dkChar), filename, erp)) {
+ szf = dk4str_len(buf);
+ szp = dk4str_len(parent);
+ if (szf > szp) {
+
+#line 241 "dk4pathd.ctr"
+#if DK4_ON_WINDOWS
+ if (buf[szp] == dkT('\\'))
+#else
+ if (buf[szp] == dkT('/'))
+#endif
+ {
+
+#line 247 "dk4pathd.ctr"
+ buf[szp] = dkT('\0');
+ if (0 == dk4str_pathcmp(buf, parent)) {
+ back = 1;
+
+#line 250 "dk4pathd.ctr"
+ }
+#if DK4_ON_WINDOWS
+ buf[szp] = dkT('\\');
+#else
+ buf[szp] = dkT('/');
+#endif
+ }
+ } else {
+ if (szf == szp) {
+
+#line 259 "dk4pathd.ctr"
+ if (0 == dk4str_pathcmp(buf, parent)) {
+ back = 1;
+
+#line 261 "dk4pathd.ctr"
+ }
+ }
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 268 "dk4pathd.ctr"
+ return back;
+}
+
+
+
diff --git a/support/dktools/dk4pathd.ctr b/support/dktools/dk4pathd.ctr
new file mode 100644
index 0000000000..f37cc038a1
--- /dev/null
+++ b/support/dktools/dk4pathd.ctr
@@ -0,0 +1,272 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ String operations for path names
+ (dkChar characters).
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_HAVE_WCHAR_H
+#ifndef WCHAR_H_INCLUDED
+#include <wchar.h>
+#define WCHAR_H_INCLUDED 1
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Check whether a file name is an absolute path.
+ CRT on Windows: Not used.
+ @param path Path name to check.
+ @return 1 for absolute path, 0 for other path.
+*/
+int
+dk4path_is_absolute(const dkChar *path);
+
+/** Check whether a file name is a relative path.
+ CRT on Windows: Not used.
+ @param path Path name to check.
+ @return 1 for absolute path, 0 for other path.
+*/
+int
+dk4path_is_relative(const dkChar *path);
+
+/** Append path filename to path name already stored in buffer.
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param buffer Buffer already containing a path.
+ @param sz Buffer size.
+ @param filename Relative file name to append to buffer.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if buffer or filename is NULL or sz is 0,
+ - DK4_E_MATH_OVERFLOW<br>
+ if filename is too long,
+ - DK4_E_MEMORY<br>
+ if allocation of a filename copy fails,
+ - DK4_E_SYNTAX<br>
+ if too many .. in filename,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if buffer size is too small.
+*/
+int
+dk4path_append(
+ dkChar *buffer, size_t sz, const dkChar *filename, dk4_er_t *erp
+);
+
+
+/** Find pointer to suffix.
+ CRT on Windows: Not used.
+ @param filename File name to find suffix for.
+ @param erp Error report, may be NULL.
+ @return Pointer to suffix dot if found, NULL otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if filename is NULL,
+ - DK4_E_NOT_FOUND<br>
+ if the file name does not contain a suffix.
+*/
+dkChar *
+dk4path_get_suffix(const dkChar *filename, dk4_er_t *erp);
+
+
+/** Correct file name separators from slash to backslash on Windows,
+ vice versa on other systems.
+ CRT on Windows: Not used.
+ @param filename File name to correct.
+*/
+void
+dk4path_correct_sep(dkChar *filename);
+
+/** Check whether file name needs expansion on Windows.
+ CRT on Windows: Not used.
+ @param filename File name to check.
+ @return 1 if expansion is necessary, 0 otherwise.
+*/
+int
+dk4path_must_expand(const dkChar *filename);
+
+/** Check whether filename is in the specified parent directory.
+ It may be equal to parent or below the parent directory.
+ @param filename File or directory name to check.
+ @param parent Parent directory.
+ @param erp Error report, may be NULL.
+ @return 1 for true, 0 for false.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if filename or parent is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if filename is too long for an internal buffer.
+*/
+int
+dk4path_is_in_subdir(const dkChar *filename,const dkChar *parent,dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+
+#include "dk4pathd.h"
+#if DK4_CHAR_SIZE > 1
+#include "dk4pathw.h"
+#else
+#include "dk4path8.h"
+#endif
+
+#include "dk4mem.h"
+#include "dk4mpl.h"
+#include "dk4strd.h"
+
+
+
+$!trace-include
+
+
+
+int
+dk4path_is_absolute(const dkChar *path)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4pathw_is_absolute(path));
+#else
+ return (dk4path8_is_absolute(path));
+#endif
+}
+
+
+
+int
+dk4path_is_relative(const dkChar *path)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4pathw_is_relative(path));
+#else
+ return (dk4path8_is_relative(path));
+#endif
+}
+
+
+
+int
+dk4path_append(
+ dkChar *buffer, size_t sz, const dkChar *filename, dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4pathw_append(buffer, sz, filename, erp));
+#else
+ return (dk4path8_append(buffer, sz, filename, erp));
+#endif
+}
+
+
+
+dkChar *
+dk4path_get_suffix(const dkChar *filename, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4pathw_get_suffix(filename, erp));
+#else
+ return (dk4path8_get_suffix(filename, erp));
+#endif
+}
+
+
+
+void
+dk4path_correct_sep(dkChar *filename)
+{
+#if DK4_CHAR_SIZE > 1
+ dk4pathw_correct_sep(filename);
+#else
+ dk4path8_correct_sep(filename);
+#endif
+}
+
+
+
+int
+dk4path_must_expand(const dkChar *filename)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4pathw_must_expand(filename));
+#else
+ return (dk4path8_must_expand(filename));
+#endif
+}
+
+
+
+int
+dk4path_is_in_subdir(const dkChar *filename,const dkChar *parent,dk4_er_t *erp)
+{
+ dkChar buf[DK4_MAX_PATH];
+ size_t szf;
+ size_t szp;
+ int back = 0;
+ $? "+ dk4path_is_in_subdir f=\"%!ds\" p=\"%!ds\"", filename, parent
+ if ((NULL != filename) && (NULL != parent)) {
+ if (0 != dk4str_cpy_s(buf, DK4_SIZEOF(buf,dkChar), filename, erp)) {
+ szf = dk4str_len(buf);
+ szp = dk4str_len(parent);
+ if (szf > szp) { $? ". filename larger than parent"
+#if DK4_ON_WINDOWS
+ if (buf[szp] == dkT('\\'))
+#else
+ if (buf[szp] == dkT('/'))
+#endif
+ { $? ". separator at right place"
+ buf[szp] = dkT('\0');
+ if (0 == dk4str_pathcmp(buf, parent)) {
+ back = 1; $? ". match"
+ }
+#if DK4_ON_WINDOWS
+ buf[szp] = dkT('\\');
+#else
+ buf[szp] = dkT('/');
+#endif
+ }
+ } else {
+ if (szf == szp) { $? ". equal lengths"
+ if (0 == dk4str_pathcmp(buf, parent)) {
+ back = 1; $? ". match"
+ }
+ }
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4path_is_in_subdir %d", back
+ return back;
+}
+
+
+
diff --git a/support/dktools/dk4pathd.h b/support/dktools/dk4pathd.h
new file mode 100644
index 0000000000..fb80048298
--- /dev/null
+++ b/support/dktools/dk4pathd.h
@@ -0,0 +1,167 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4pathd.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4PATHD_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4PATHD_H_INCLUDED 1
+
+
+#line 10 "dk4pathd.ctr"
+
+/** @file
+ String operations for path names
+ (dkChar characters).
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_HAVE_WCHAR_H
+#ifndef WCHAR_H_INCLUDED
+#include <wchar.h>
+#define WCHAR_H_INCLUDED 1
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Check whether a file name is an absolute path.
+ CRT on Windows: Not used.
+ @param path Path name to check.
+ @return 1 for absolute path, 0 for other path.
+*/
+int
+dk4path_is_absolute(const dkChar *path);
+
+/** Check whether a file name is a relative path.
+ CRT on Windows: Not used.
+ @param path Path name to check.
+ @return 1 for absolute path, 0 for other path.
+*/
+int
+dk4path_is_relative(const dkChar *path);
+
+/** Append path filename to path name already stored in buffer.
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param buffer Buffer already containing a path.
+ @param sz Buffer size.
+ @param filename Relative file name to append to buffer.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if buffer or filename is NULL or sz is 0,
+ - DK4_E_MATH_OVERFLOW<br>
+ if filename is too long,
+ - DK4_E_MEMORY<br>
+ if allocation of a filename copy fails,
+ - DK4_E_SYNTAX<br>
+ if too many .. in filename,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if buffer size is too small.
+*/
+int
+dk4path_append(
+ dkChar *buffer, size_t sz, const dkChar *filename, dk4_er_t *erp
+);
+
+
+/** Find pointer to suffix.
+ CRT on Windows: Not used.
+ @param filename File name to find suffix for.
+ @param erp Error report, may be NULL.
+ @return Pointer to suffix dot if found, NULL otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if filename is NULL,
+ - DK4_E_NOT_FOUND<br>
+ if the file name does not contain a suffix.
+*/
+dkChar *
+dk4path_get_suffix(const dkChar *filename, dk4_er_t *erp);
+
+
+/** Correct file name separators from slash to backslash on Windows,
+ vice versa on other systems.
+ CRT on Windows: Not used.
+ @param filename File name to correct.
+*/
+void
+dk4path_correct_sep(dkChar *filename);
+
+/** Check whether file name needs expansion on Windows.
+ CRT on Windows: Not used.
+ @param filename File name to check.
+ @return 1 if expansion is necessary, 0 otherwise.
+*/
+int
+dk4path_must_expand(const dkChar *filename);
+
+/** Check whether filename is in the specified parent directory.
+ It may be equal to parent or below the parent directory.
+ @param filename File or directory name to check.
+ @param parent Parent directory.
+ @param erp Error report, may be NULL.
+ @return 1 for true, 0 for false.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if filename or parent is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if filename is too long for an internal buffer.
+*/
+int
+dk4path_is_in_subdir(const dkChar *filename,const dkChar *parent,dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4pathw.c b/support/dktools/dk4pathw.c
new file mode 100644
index 0000000000..178c83eeb9
--- /dev/null
+++ b/support/dktools/dk4pathw.c
@@ -0,0 +1,307 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4pathw.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4pathw.c The dk4pathw module.
+*/
+
+
+#line 110 "dk4pathw.ctr"
+
+
+#include "dk4pathw.h"
+#include "dk4mem.h"
+#include "dk4strw.h"
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_WCHAR_H
+#ifndef WCHAR_H_INCLUDED
+#include <wchar.h>
+#define WCHAR_H_INCLUDED 1
+#endif
+#endif
+
+
+/** Constant keywords used by the dk4pathw module.
+*/
+static const wchar_t * const dk4pathw_kw[] = {
+#if DK4_HAVE_BACKSLASH_AS_SEP
+/* 0 */ L"\\",
+/* 1 */ L"/",
+#else
+/* 0 */ L"/",
+/* 1 */ L"\\",
+#endif
+/* 2 */ L".",
+/* 3 */ L"..",
+/* 4 */ L":"
+};
+
+
+
+/** Get last character from a string.
+ @param str String to test.
+ @return Last character from string.
+*/
+static
+wchar_t
+dk4pathw_lastchar(const wchar_t *str)
+{
+ wchar_t back = '\0';
+ if (str) { while (L'\0' != *str) { back = *(str++); } }
+ return back;
+}
+
+
+
+int
+dk4pathw_is_absolute(const wchar_t *path)
+{
+ int back = 0;
+#if DK4_ON_WINDOWS
+ wchar_t c;
+#endif
+ if (NULL != path) {
+#if DK4_ON_WINDOWS
+ c = *path;
+ if ( *(dk4pathw_kw[0]) == c ) {
+ back = 1;
+ } else {
+ if (((L'a' <= c) && (L'z' >= c)) || ((L'A' <= c) && (L'Z' >= c))) {
+ if ( *(dk4pathw_kw[4]) == path[1] ) {
+ c = path[2];
+ if ( ( *(dk4pathw_kw[0]) == c ) || ( L'\0' == c ) ) {
+ back = 1;
+ }
+ }
+ }
+ }
+#else
+ if ( *(dk4pathw_kw[0]) == *path ) {
+ back = 1;
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk4pathw_is_relative(const wchar_t *path)
+{
+ int back = 0;
+ if (NULL != path) {
+ if (NULL != dk4strw_chr(path, *(dk4pathw_kw[0]))) {
+ if (0 == dk4pathw_is_absolute(path)) {
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4pathw_append(
+ wchar_t *buffer, size_t sz, const wchar_t *filename, dk4_er_t *erp
+)
+{
+ wchar_t *pc; /* Current path part to append */
+ wchar_t *pn; /* Next part to append */
+ wchar_t *pd; /* Part to delete */
+ wchar_t *mycp = NULL; /* Private copy */
+#if DK4_ON_WINDOWS
+ int ischr;
+#endif
+ int back = 0; /* Function result */
+ int failed = 0; /* Definitely failed */
+ wchar_t lch; /* Last character from string */
+
+ if ((NULL != buffer) && (NULL != filename) && (0 < sz)) {
+ mycp = dk4strw_dup(filename, erp);
+ if (NULL != mycp) {
+ pc = mycp;
+ while ((NULL != pc) && (0 == failed)) {
+ pn = dk4strw_chr(pc, *(dk4pathw_kw[0]));
+ if (NULL != pn) { *(pn++) = L'\0'; }
+ if (0 != dk4strw_cmp(pc, dk4pathw_kw[2])) {
+ if (0 == dk4strw_cmp(pc, dk4pathw_kw[3])) { /* Remove from buffer */
+ pd = dk4strw_rchr(buffer, *(dk4pathw_kw[0]));
+ if (NULL != pd) {
+ *pd = L'\0';
+ if (0 < dk4strw_len(&(pd[1]))) {
+#if DK4_ON_WINDOWS
+ if (2 == dk4strw_len(buffer)) {
+ ischr = 0;
+ if ((L'A' <= buffer[0]) && (L'Z' >= buffer[0])) {
+ ischr = 1;
+ }
+ if ((L'a' <= buffer[0]) && (L'z' >= buffer[0])) {
+ ischr = 1;
+ }
+ if (1 == ischr) {
+ if (L':' == buffer[1]) {
+ buffer[2] = *(dk4pathw_kw[0]);
+ buffer[3] = L'\0';
+ }
+ }
+ }
+#else
+ if (0 == dk4strw_len(buffer)) {
+ *pd = *(dk4pathw_kw[0]);
+ pd++;
+ *pd = L'\0';
+ }
+#endif
+ } else {
+ failed = 1;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ failed = 1;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else { /* Add to buffer */
+ lch = dk4pathw_lastchar(buffer);
+ if (lch != *(dk4pathw_kw[0])) {
+ if (0 != dk4strw_cat_s(buffer, sz, dk4pathw_kw[0], erp)) {
+ if (0 == dk4strw_cat_s(buffer, sz, pc, erp)) {
+ failed = 1;
+ }
+ } else {
+ failed = 1;
+ }
+ } else {
+ if (0 == dk4strw_cat_s(buffer, sz, pc, erp)) {
+ failed = 1;
+ }
+ }
+ }
+ }
+ pc = pn;
+ }
+ if (0 == failed) {
+ back = 1;
+ }
+ dk4mem_release(mycp);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+wchar_t *
+dk4pathw_get_suffix(const wchar_t *filename, dk4_er_t *erp)
+{
+ const wchar_t *back = NULL;
+ if (NULL != filename) {
+ while (L'\0' != *filename) {
+ if ((L'\\' == *filename) || (L'/' == *filename)) {
+ back = NULL;
+ } else {
+ if (L'.' == *filename) {
+ back = filename;
+ }
+ }
+ filename++;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return ((wchar_t *)back);
+}
+
+
+
+void
+dk4pathw_correct_sep(wchar_t *filename)
+{
+ if (NULL != filename) {
+ while (L'\0' != *filename) {
+#if DK4_HAVE_BACKSLASH_AS_SEP
+ if (L'/' == *filename) { *filename = L'\\'; }
+#else
+ if (L'\\' == *filename) { *filename = L'/'; }
+#endif
+ filename++;
+ }
+ }
+}
+
+
+
+int
+dk4pathw_must_expand(const wchar_t *filename)
+{
+#if DK4_ON_WINDOWS
+ int back = 0;
+ if (NULL != filename) {
+ if (L'\\' == filename[0]) {
+ if (L'\\' == filename[1]) {
+ if (L'?' == filename[2]) {
+ if (L'\\' == filename[3]) {
+ filename = &(filename[4]);
+ }
+ }
+ }
+ }
+ while((L'\0' != *filename) && (0 == back)) {
+ if (L'*' == *filename) {
+ back = 1;
+ } else {
+ if (L'?' == *filename) {
+ back = 1;
+ } else {
+ filename++;
+ }
+ }
+ }
+ }
+ return back;
+#else
+ return 0;
+#endif
+}
+
diff --git a/support/dktools/dk4pathw.ctr b/support/dktools/dk4pathw.ctr
new file mode 100644
index 0000000000..b5299600df
--- /dev/null
+++ b/support/dktools/dk4pathw.ctr
@@ -0,0 +1,376 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ String operations for path names
+ (wchar_t characters).
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Check whether a file name is an absolute path.
+ CRT on Windows: Not used.
+ @param path Path name to check.
+ @return 1 for absolute path, 0 for other path.
+*/
+int
+dk4pathw_is_absolute(const wchar_t *path);
+
+/** Check whether a file name is a relative path.
+ CRT on Windows: Not used.
+ @param path Path name to check.
+ @return 1 for absolute path, 0 for other path.
+*/
+int
+dk4pathw_is_relative(const wchar_t *path);
+
+/** Append path filename to path name already stored in buffer.
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param buffer Buffer already containing a path.
+ @param sz Buffer size.
+ @param filename Relative file name to append to buffer.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if buffer or filename is NULL or sz is 0,
+ - DK4_E_MATH_OVERFLOW<br>
+ if filename is too long,
+ - DK4_E_MEMORY<br>
+ if allocation of a filename copy fails,
+ - DK4_E_SYNTAX<br>
+ if too many .. in filename,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if buffer size is too small.
+*/
+int
+dk4pathw_append(
+ wchar_t *buffer, size_t sz, const wchar_t *filename, dk4_er_t *erp
+);
+
+/** Find pointer to suffix.
+ CRT on Windows: Not used.
+ @param filename File name to find suffix for.
+ @param erp Error report, may be NULL.
+ @return Pointer to suffix dot if found, NULL otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if filename is NULL,
+ - DK4_E_NOT_FOUND<br>
+ if the file name does not contain a suffix.
+*/
+wchar_t *
+dk4pathw_get_suffix(const wchar_t *filename, dk4_er_t *erp);
+
+/** Correct file name separators from slash to backslash on Windows,
+ vice versa on other systems.
+ CRT on Windows: Not used.
+ @param filename File name to correct.
+*/
+void
+dk4pathw_correct_sep(wchar_t *filename);
+
+/** Check whether file name needs expansion on Windows.
+ CRT on Windows: Not used.
+ @param filename File name to check.
+ @return 1 if expansion is necessary, 0 otherwise.
+*/
+int
+dk4pathw_must_expand(const wchar_t *filename);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+
+#include "dk4pathw.h"
+#include "dk4mem.h"
+#include "dk4strw.h"
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_WCHAR_H
+#ifndef WCHAR_H_INCLUDED
+#include <wchar.h>
+#define WCHAR_H_INCLUDED 1
+#endif
+#endif
+
+
+/** Constant keywords used by the dk4pathw module.
+*/
+static const wchar_t * const dk4pathw_kw[] = {
+#if DK4_HAVE_BACKSLASH_AS_SEP
+/* 0 */ L"\\",
+/* 1 */ L"/",
+#else
+/* 0 */ L"/",
+/* 1 */ L"\\",
+#endif
+/* 2 */ L".",
+/* 3 */ L"..",
+/* 4 */ L":"
+};
+
+
+
+/** Get last character from a string.
+ @param str String to test.
+ @return Last character from string.
+*/
+static
+wchar_t
+dk4pathw_lastchar(const wchar_t *str)
+{
+ wchar_t back = '\0';
+ if (str) { while (L'\0' != *str) { back = *(str++); } }
+ return back;
+}
+
+
+
+int
+dk4pathw_is_absolute(const wchar_t *path)
+{
+ int back = 0;
+#if DK4_ON_WINDOWS
+ wchar_t c;
+#endif
+ if (NULL != path) {
+#if DK4_ON_WINDOWS
+ c = *path;
+ if ( *(dk4pathw_kw[0]) == c ) {
+ back = 1;
+ } else {
+ if (((L'a' <= c) && (L'z' >= c)) || ((L'A' <= c) && (L'Z' >= c))) {
+ if ( *(dk4pathw_kw[4]) == path[1] ) {
+ c = path[2];
+ if ( ( *(dk4pathw_kw[0]) == c ) || ( L'\0' == c ) ) {
+ back = 1;
+ }
+ }
+ }
+ }
+#else
+ if ( *(dk4pathw_kw[0]) == *path ) {
+ back = 1;
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk4pathw_is_relative(const wchar_t *path)
+{
+ int back = 0;
+ if (NULL != path) {
+ if (NULL != dk4strw_chr(path, *(dk4pathw_kw[0]))) {
+ if (0 == dk4pathw_is_absolute(path)) {
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4pathw_append(
+ wchar_t *buffer, size_t sz, const wchar_t *filename, dk4_er_t *erp
+)
+{
+ wchar_t *pc; /* Current path part to append */
+ wchar_t *pn; /* Next part to append */
+ wchar_t *pd; /* Part to delete */
+ wchar_t *mycp = NULL; /* Private copy */
+#if DK4_ON_WINDOWS
+ int ischr;
+#endif
+ int back = 0; /* Function result */
+ int failed = 0; /* Definitely failed */
+ wchar_t lch; /* Last character from string */
+
+ if ((NULL != buffer) && (NULL != filename) && (0 < sz)) {
+ mycp = dk4strw_dup(filename, erp);
+ if (NULL != mycp) {
+ pc = mycp;
+ while ((NULL != pc) && (0 == failed)) {
+ pn = dk4strw_chr(pc, *(dk4pathw_kw[0]));
+ if (NULL != pn) { *(pn++) = L'\0'; }
+ if (0 != dk4strw_cmp(pc, dk4pathw_kw[2])) {
+ if (0 == dk4strw_cmp(pc, dk4pathw_kw[3])) { /* Remove from buffer */
+ pd = dk4strw_rchr(buffer, *(dk4pathw_kw[0]));
+ if (NULL != pd) {
+ *pd = L'\0';
+ if (0 < dk4strw_len(&(pd[1]))) {
+#if DK4_ON_WINDOWS
+ if (2 == dk4strw_len(buffer)) {
+ ischr = 0;
+ if ((L'A' <= buffer[0]) && (L'Z' >= buffer[0])) {
+ ischr = 1;
+ }
+ if ((L'a' <= buffer[0]) && (L'z' >= buffer[0])) {
+ ischr = 1;
+ }
+ if (1 == ischr) {
+ if (L':' == buffer[1]) {
+ buffer[2] = *(dk4pathw_kw[0]);
+ buffer[3] = L'\0';
+ }
+ }
+ }
+#else
+ if (0 == dk4strw_len(buffer)) {
+ *pd = *(dk4pathw_kw[0]);
+ pd++;
+ *pd = L'\0';
+ }
+#endif
+ } else {
+ failed = 1;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ failed = 1;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else { /* Add to buffer */
+ lch = dk4pathw_lastchar(buffer);
+ if (lch != *(dk4pathw_kw[0])) {
+ if (0 != dk4strw_cat_s(buffer, sz, dk4pathw_kw[0], erp)) {
+ if (0 == dk4strw_cat_s(buffer, sz, pc, erp)) {
+ failed = 1;
+ }
+ } else {
+ failed = 1;
+ }
+ } else {
+ if (0 == dk4strw_cat_s(buffer, sz, pc, erp)) {
+ failed = 1;
+ }
+ }
+ }
+ }
+ pc = pn;
+ }
+ if (0 == failed) {
+ back = 1;
+ }
+ dk4mem_release(mycp);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+wchar_t *
+dk4pathw_get_suffix(const wchar_t *filename, dk4_er_t *erp)
+{
+ const wchar_t *back = NULL;
+ if (NULL != filename) {
+ while (L'\0' != *filename) {
+ if ((L'\\' == *filename) || (L'/' == *filename)) {
+ back = NULL;
+ } else {
+ if (L'.' == *filename) {
+ back = filename;
+ }
+ }
+ filename++;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return ((wchar_t *)back);
+}
+
+
+
+void
+dk4pathw_correct_sep(wchar_t *filename)
+{
+ if (NULL != filename) {
+ while (L'\0' != *filename) {
+#if DK4_HAVE_BACKSLASH_AS_SEP
+ if (L'/' == *filename) { *filename = L'\\'; }
+#else
+ if (L'\\' == *filename) { *filename = L'/'; }
+#endif
+ filename++;
+ }
+ }
+}
+
+
+
+int
+dk4pathw_must_expand(const wchar_t *filename)
+{
+#if DK4_ON_WINDOWS
+ int back = 0;
+ if (NULL != filename) {
+ if (L'\\' == filename[0]) {
+ if (L'\\' == filename[1]) {
+ if (L'?' == filename[2]) {
+ if (L'\\' == filename[3]) {
+ filename = &(filename[4]);
+ }
+ }
+ }
+ }
+ while((L'\0' != *filename) && (0 == back)) {
+ if (L'*' == *filename) {
+ back = 1;
+ } else {
+ if (L'?' == *filename) {
+ back = 1;
+ } else {
+ filename++;
+ }
+ }
+ }
+ }
+ return back;
+#else
+ return 0;
+#endif
+}
+
diff --git a/support/dktools/dk4pathw.h b/support/dktools/dk4pathw.h
new file mode 100644
index 0000000000..83eba9ed3c
--- /dev/null
+++ b/support/dktools/dk4pathw.h
@@ -0,0 +1,143 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4pathw.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4PATHW_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4PATHW_H_INCLUDED 1
+
+
+#line 9 "dk4pathw.ctr"
+
+/** @file
+ String operations for path names
+ (wchar_t characters).
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Check whether a file name is an absolute path.
+ CRT on Windows: Not used.
+ @param path Path name to check.
+ @return 1 for absolute path, 0 for other path.
+*/
+int
+dk4pathw_is_absolute(const wchar_t *path);
+
+/** Check whether a file name is a relative path.
+ CRT on Windows: Not used.
+ @param path Path name to check.
+ @return 1 for absolute path, 0 for other path.
+*/
+int
+dk4pathw_is_relative(const wchar_t *path);
+
+/** Append path filename to path name already stored in buffer.
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param buffer Buffer already containing a path.
+ @param sz Buffer size.
+ @param filename Relative file name to append to buffer.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if buffer or filename is NULL or sz is 0,
+ - DK4_E_MATH_OVERFLOW<br>
+ if filename is too long,
+ - DK4_E_MEMORY<br>
+ if allocation of a filename copy fails,
+ - DK4_E_SYNTAX<br>
+ if too many .. in filename,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if buffer size is too small.
+*/
+int
+dk4pathw_append(
+ wchar_t *buffer, size_t sz, const wchar_t *filename, dk4_er_t *erp
+);
+
+/** Find pointer to suffix.
+ CRT on Windows: Not used.
+ @param filename File name to find suffix for.
+ @param erp Error report, may be NULL.
+ @return Pointer to suffix dot if found, NULL otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if filename is NULL,
+ - DK4_E_NOT_FOUND<br>
+ if the file name does not contain a suffix.
+*/
+wchar_t *
+dk4pathw_get_suffix(const wchar_t *filename, dk4_er_t *erp);
+
+/** Correct file name separators from slash to backslash on Windows,
+ vice versa on other systems.
+ CRT on Windows: Not used.
+ @param filename File name to correct.
+*/
+void
+dk4pathw_correct_sep(wchar_t *filename);
+
+/** Check whether file name needs expansion on Windows.
+ CRT on Windows: Not used.
+ @param filename File name to check.
+ @return 1 if expansion is necessary, 0 otherwise.
+*/
+int
+dk4pathw_must_expand(const wchar_t *filename);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4pref.c b/support/dktools/dk4pref.c
new file mode 100644
index 0000000000..a8d8d133b5
--- /dev/null
+++ b/support/dktools/dk4pref.c
@@ -0,0 +1,159 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4pref.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4pref.c The dk4pref module.
+*/
+
+
+#line 93 "dk4pref.ctr"
+
+
+#include "dk4pref.h"
+#include "dk4mem.h"
+
+
+
+
+
+#line 101 "dk4pref.ctr"
+
+
+
+dk4_pref_t *
+dk4pref_open(dkChar const *name, dkChar const *value, dk4_er_t *erp)
+{
+ dk4_pref_t *back = NULL;
+
+
+#line 109 "dk4pref.ctr"
+ if ((NULL != name) && (NULL != value)) {
+ back = dk4mem_new(dk4_pref_t,1,erp);
+ if (NULL != back) {
+ back->name = NULL;
+ back->value = NULL;
+ back->name = dk4str_dup(name, erp);
+ back->value = dk4str_dup(value, erp);
+ if ((NULL == back->name) || (NULL == back->value)) {
+ dk4pref_close(back);
+ back = NULL;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 124 "dk4pref.ctr"
+ return back;
+}
+
+
+
+void
+dk4pref_close(dk4_pref_t *ptr)
+{
+
+
+#line 133 "dk4pref.ctr"
+ if (NULL != ptr) {
+
+
+#line 135 "dk4pref.ctr"
+#if 0
+ /* Original stuff.
+ */
+ dk4mem_release(ptr->name);
+ dk4mem_release(ptr->value);
+#endif
+ /* 2016-12-10 Sanitize memory before releasing it.
+ */
+ dk4str_release_sanitized(ptr->name);
+ dk4str_release_sanitized(ptr->value);
+ dk4mem_free(ptr);
+ }
+
+
+#line 148 "dk4pref.ctr"
+}
+
+
+
+int
+dk4pref_compare(const void *l, const void *r, int cr)
+{
+ const dk4_pref_t *pl;
+ const dk4_pref_t *pr;
+ int back = 0;
+
+
+#line 159 "dk4pref.ctr"
+ if (NULL != l) {
+ if (NULL != r) {
+ pl = (const dk4_pref_t *)l;
+ switch (cr) {
+ case 1: {
+ if (NULL != pl->name) {
+ back = dk4str_cmp(pl->name, (const dkChar *)r);
+ } else {
+ back = -1;
+ }
+ } break;
+ default: {
+ pr = (const dk4_pref_t *)r;
+ if (NULL != pl->name) {
+ if (NULL != pr->name) {
+ back = dk4str_cmp(pl->name, pr->name);
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != pr->name) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != r) {
+ back = -1;
+ }
+ }
+
+#line 193 "dk4pref.ctr"
+ return back;
+}
+
diff --git a/support/dktools/dk4pref.conf b/support/dktools/dk4pref.conf
new file mode 100644
index 0000000000..240822bf84
--- /dev/null
+++ b/support/dktools/dk4pref.conf
@@ -0,0 +1,10 @@
+# []
+
+[user=joe]
+ui.language = en
+ui.region = us
+
+# [user=krause,host=dk]
+# ui.language = de
+# ui.region = de
+
diff --git a/support/dktools/dk4pref.ctr b/support/dktools/dk4pref.ctr
new file mode 100644
index 0000000000..cd43353e4b
--- /dev/null
+++ b/support/dktools/dk4pref.ctr
@@ -0,0 +1,195 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Preferences as key/value pairs; the module contains functions
+ to create and destroy a preference structure and to compare
+ preference structures by name or against a given name.
+
+ Typically preferences are stored in a dk4_sto_t structure.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4STR8_H_INCLUDED
+#include "dk4str8.h"
+#endif
+
+#ifndef DK4STRW_H_INCLUDED
+#include "dk4strw.h"
+#endif
+
+#ifndef DK4STRD_H_INCLUDED
+#include "dk4strd.h"
+#endif
+
+
+
+/** Preferences storage.
+*/
+typedef struct {
+ dkChar *name; /**< Preference name. */
+ dkChar *value; /**< Value. */
+} dk4_pref_t;
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Create preferences structure, allocate memory.
+ @param name Preference name.
+ @param value Preference value.
+ @param erp Error report, may be NULL.
+ @return Pointer to new preferences object on success, NULL on error.
+*/
+dk4_pref_t *
+dk4pref_open(dkChar const *name, dkChar const *value, dk4_er_t *erp);
+
+/** Destroy preference structure, release memory.
+ @param ptr Preference structure to destroy.
+*/
+void
+dk4pref_close(dk4_pref_t *ptr);
+
+/** Comparison function.
+ @param l Left pointer.
+ @param r Right pointer.
+ @param cr Comparison criteria:
+ 0=structure/structure,
+ 1=structure/name.
+ @return Comparison result.
+*/
+int
+dk4pref_compare(const void *l, const void *r, int cr);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+
+#include "dk4pref.h"
+#include "dk4mem.h"
+
+
+
+$!trace-include
+
+
+
+dk4_pref_t *
+dk4pref_open(dkChar const *name, dkChar const *value, dk4_er_t *erp)
+{
+ dk4_pref_t *back = NULL;
+ $? "+ dk4pref_open \"%!ds\"=\"%!ds\"", TR_DKSTR(name), TR_DKSTR(value)
+ if ((NULL != name) && (NULL != value)) {
+ back = dk4mem_new(dk4_pref_t,1,erp);
+ if (NULL != back) {
+ back->name = NULL;
+ back->value = NULL;
+ back->name = dk4str_dup(name, erp);
+ back->value = dk4str_dup(value, erp);
+ if ((NULL == back->name) || (NULL == back->value)) {
+ dk4pref_close(back);
+ back = NULL;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4pref_open PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+void
+dk4pref_close(dk4_pref_t *ptr)
+{
+ $? "+ dk4pref_close"
+ if (NULL != ptr) {
+ $? ". \"%!ds\"=\"%!ds\"", TR_DKSTR(ptr->name), TR_DKSTR(ptr->value)
+#if 0
+ /* Original stuff.
+ */
+ dk4mem_release(ptr->name);
+ dk4mem_release(ptr->value);
+#endif
+ /* 2016-12-10 Sanitize memory before releasing it.
+ */
+ dk4str_release_sanitized(ptr->name);
+ dk4str_release_sanitized(ptr->value);
+ dk4mem_free(ptr);
+ }
+ $? "- dk4pref_close"
+}
+
+
+
+int
+dk4pref_compare(const void *l, const void *r, int cr)
+{
+ const dk4_pref_t *pl;
+ const dk4_pref_t *pr;
+ int back = 0;
+ $? "+ dk4pref_compare"
+ if (NULL != l) {
+ if (NULL != r) {
+ pl = (const dk4_pref_t *)l;
+ switch (cr) {
+ case 1: {
+ if (NULL != pl->name) {
+ back = dk4str_cmp(pl->name, (const dkChar *)r);
+ } else {
+ back = -1;
+ }
+ } break;
+ default: {
+ pr = (const dk4_pref_t *)r;
+ if (NULL != pl->name) {
+ if (NULL != pr->name) {
+ back = dk4str_cmp(pl->name, pr->name);
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != pr->name) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != r) {
+ back = -1;
+ }
+ } $? "- dk4pref_compare %d", back
+ return back;
+}
+
diff --git a/support/dktools/dk4pref.h b/support/dktools/dk4pref.h
new file mode 100644
index 0000000000..741ae9c080
--- /dev/null
+++ b/support/dktools/dk4pref.h
@@ -0,0 +1,125 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4pref.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4PREF_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4PREF_H_INCLUDED 1
+
+
+#line 10 "dk4pref.ctr"
+
+/** @file
+ Preferences as key/value pairs; the module contains functions
+ to create and destroy a preference structure and to compare
+ preference structures by name or against a given name.
+
+ Typically preferences are stored in a dk4_sto_t structure.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4STR8_H_INCLUDED
+#include "dk4str8.h"
+#endif
+
+#ifndef DK4STRW_H_INCLUDED
+#include "dk4strw.h"
+#endif
+
+#ifndef DK4STRD_H_INCLUDED
+#include "dk4strd.h"
+#endif
+
+
+
+/** Preferences storage.
+*/
+typedef struct {
+ dkChar *name; /**< Preference name. */
+ dkChar *value; /**< Value. */
+} dk4_pref_t;
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Create preferences structure, allocate memory.
+ @param name Preference name.
+ @param value Preference value.
+ @param erp Error report, may be NULL.
+ @return Pointer to new preferences object on success, NULL on error.
+*/
+dk4_pref_t *
+dk4pref_open(dkChar const *name, dkChar const *value, dk4_er_t *erp);
+
+/** Destroy preference structure, release memory.
+ @param ptr Preference structure to destroy.
+*/
+void
+dk4pref_close(dk4_pref_t *ptr);
+
+/** Comparison function.
+ @param l Left pointer.
+ @param r Right pointer.
+ @param cr Comparison criteria:
+ 0=structure/structure,
+ 1=structure/name.
+ @return Comparison result.
+*/
+int
+dk4pref_compare(const void *l, const void *r, int cr);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4rec.h b/support/dktools/dk4rec.h
new file mode 100644
index 0000000000..6a34458ba1
--- /dev/null
+++ b/support/dktools/dk4rec.h
@@ -0,0 +1,113 @@
+#ifndef DK4REC_H_INCLUDED
+#define DK4REC_H_INCLUDED 1
+
+/** @file dk4rec.h String conversion between various encodings.
+ - ASCII to ANSI: dk4recode_ascii_to_ansi()
+ - ANSI to ASCII: dk4recode_ansi_to_ascii()
+ - ASCII to UTF-8: dk4recode_ascii_to_utf8()
+ - UTF-8 to ASCII: dk4recode_utf8_to_ascii()
+ - ANSI to UTF-8: dk4recode_ansi_to_utf8()
+ - UTF-8 to ANSI: dk4recode_utf8_to_ansi()
+ - ASCII to UTF-16: dk4recode_ascii_to_utf16()
+ - UTF-16 to ASCII: dk4recode_utf16_to_ascii()
+ - ANSI to UTF-16: dk4recode_ansi_to_utf16()
+ - UTF-16 to ANSI: dk4recode_utf16_to_ansi()
+ - UTF-8 to UTF-16: dk4recode_utf8_to_utf16()
+ - UTF-16 to UTF-8: dk4recode_utf16_to_utf8()
+ - ASCII to 32 bit: dk4recode_ascii_to_c32()
+ - 32 bit to ASCII: dk4recode_c32_to_ascii()
+ - ANSI to 32 bit: dk4recode_ansi_to_c32()
+ - 32 bit to ANSI: dk4recode_c32_to_ansi()
+ - UTF-8 to 32 bit: dk4recode_utf8_to_c32()
+ - 32 bit to UTF-8: dk4recode_c32_to_utf8()
+ - UTF-16 to 32 bit: dk4recode_utf16_to_c32()
+ - 32 bit to UTF-16: dk4recode_c32_to_utf16()
+ - ASCII to dkChar: dk4recode_ascii_to_dk()
+ - char to dkChar (simple conversion, 0x00 to 0x7F only):
+ dk4recode_char_to_dk()
+ - char to wchar_t (simple conversion, 0x00 to 0x7F only):
+ dk4recode_char_to_wchar_t()
+ - wchar_t to char (simple conversion, 0x00 to 0x7F only):
+ dk4recode_wchar_t_to_char()
+ - dkChar to ASCII, ANSI, UTF-8, UTF_16, 32 bit:
+ dk4recode_dk_to_any()
+*/
+
+#ifndef DK4REC01_H_INCLUDED
+#include "dk4rec01.h"
+#endif
+#ifndef DK4REC02_H_INCLUDED
+#include "dk4rec02.h"
+#endif
+#ifndef DK4REC03_H_INCLUDED
+#include "dk4rec03.h"
+#endif
+#ifndef DK4REC04_H_INCLUDED
+#include "dk4rec04.h"
+#endif
+#ifndef DK4REC05_H_INCLUDED
+#include "dk4rec05.h"
+#endif
+#ifndef DK4REC06_H_INCLUDED
+#include "dk4rec06.h"
+#endif
+#ifndef DK4REC07_H_INCLUDED
+#include "dk4rec07.h"
+#endif
+#ifndef DK4REC08_H_INCLUDED
+#include "dk4rec08.h"
+#endif
+#ifndef DK4REC09_H_INCLUDED
+#include "dk4rec09.h"
+#endif
+#ifndef DK4REC10_H_INCLUDED
+#include "dk4rec10.h"
+#endif
+#ifndef DK4REC11_H_INCLUDED
+#include "dk4rec11.h"
+#endif
+#ifndef DK4REC12_H_INCLUDED
+#include "dk4rec12.h"
+#endif
+#ifndef DK4REC13_H_INCLUDED
+#include "dk4rec13.h"
+#endif
+#ifndef DK4REC14_H_INCLUDED
+#include "dk4rec14.h"
+#endif
+#ifndef DK4REC15_H_INCLUDED
+#include "dk4rec15.h"
+#endif
+#ifndef DK4REC16_H_INCLUDED
+#include "dk4rec16.h"
+#endif
+#ifndef DK4REC17_H_INCLUDED
+#include "dk4rec17.h"
+#endif
+#ifndef DK4REC18_H_INCLUDED
+#include "dk4rec18.h"
+#endif
+#ifndef DK4REC19_H_INCLUDED
+#include "dk4rec19.h"
+#endif
+#ifndef DK4REC20_H_INCLUDED
+#include "dk4rec20.h"
+#endif
+#ifndef DK4REC21_H_INCLUDED
+#include "dk4rec21.h"
+#endif
+#ifndef DK4REC22_H_INCLUDED
+#include "dk4rec22.h"
+#endif
+#ifndef DK4REC23_H_INCLUDED
+#include "dk4rec23.h"
+#endif
+#ifndef DK4REC24_H_INCLUDED
+#include "dk4rec24.h"
+#endif
+#ifndef DK4REC25_H_INCLUDED
+#include "dk4rec25.h"
+#endif
+
+#endif
+
diff --git a/support/dktools/dk4rec01.c b/support/dktools/dk4rec01.c
new file mode 100644
index 0000000000..eff5a53e46
--- /dev/null
+++ b/support/dktools/dk4rec01.c
@@ -0,0 +1,81 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec01.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4rec01.c The dk4rec01 module.
+*/
+
+
+#line 58 "dk4rec01.ctr"
+
+#include "dk4rec01.h"
+#include "dk4ansi.h"
+
+
+
+int
+dk4recode_ascii_to_ansi(
+ char *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+)
+{
+ size_t used = 0;
+ dk4_c32_t c32 = dkC32(0);
+ int back = 0;
+ unsigned char uc = '\0';
+ if ((NULL != dstb) && (0 < szdstb) && (NULL != src)) {
+ back = 1;
+ while(('\0' != *src) && (1 == back) && (used < szdstb)) {
+ uc = (unsigned char)(*(src++));
+ c32 = (dk4_c32_t)uc;
+ if (0 != dk4ansi_encode(&uc, c32)) {
+ dstb[used++] = (char)uc;
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, used);
+ }
+ }
+ if (used < szdstb) {
+ dstb[used] = '\0';
+ } else {
+ dstb[szdstb - 1] = '\0';
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4rec01.ctr b/support/dktools/dk4rec01.ctr
new file mode 100644
index 0000000000..32ffcbd6cc
--- /dev/null
+++ b/support/dktools/dk4rec01.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ String recoding from ASCII to ANSI.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from ASCII to ANSI.
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of bytes).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_ascii_to_ansi(
+ char *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4rec01.h"
+#include "dk4ansi.h"
+
+
+
+int
+dk4recode_ascii_to_ansi(
+ char *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+)
+{
+ size_t used = 0;
+ dk4_c32_t c32 = dkC32(0);
+ int back = 0;
+ unsigned char uc = '\0';
+ if ((NULL != dstb) && (0 < szdstb) && (NULL != src)) {
+ back = 1;
+ while(('\0' != *src) && (1 == back) && (used < szdstb)) {
+ uc = (unsigned char)(*(src++));
+ c32 = (dk4_c32_t)uc;
+ if (0 != dk4ansi_encode(&uc, c32)) {
+ dstb[used++] = (char)uc;
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, used);
+ }
+ }
+ if (used < szdstb) {
+ dstb[used] = '\0';
+ } else {
+ dstb[szdstb - 1] = '\0';
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4rec01.h b/support/dktools/dk4rec01.h
new file mode 100644
index 0000000000..ef53993c98
--- /dev/null
+++ b/support/dktools/dk4rec01.h
@@ -0,0 +1,91 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec01.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4REC01_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4REC01_H_INCLUDED 1
+
+
+#line 9 "dk4rec01.ctr"
+
+/** @file
+ String recoding from ASCII to ANSI.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from ASCII to ANSI.
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of bytes).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_ascii_to_ansi(
+ char *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4rec02.c b/support/dktools/dk4rec02.c
new file mode 100644
index 0000000000..41cd126f06
--- /dev/null
+++ b/support/dktools/dk4rec02.c
@@ -0,0 +1,83 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec02.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4rec02.c The dk4rec02 module.
+*/
+
+
+#line 58 "dk4rec02.ctr"
+
+#include "dk4rec02.h"
+#include "dk4ansi.h"
+
+int
+dk4recode_ansi_to_ascii(
+ char *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+)
+{
+ size_t used = 0;
+ dk4_c32_t c32 = dkC32(0);
+ int back = 0;
+ unsigned char uc = '\0';
+ if ((NULL != dstb) && (NULL != src) && (0 < szdstb)) {
+ back = 1;
+ while (('\0' != *src) && (1 == back) && (used < szdstb)) {
+ uc = (unsigned char)(*(src++));
+ if (0 != dk4ansi_decode(&c32, uc)) {
+ if (dkC32(0x00000100) > c32) {
+ dstb[used++] = (char)c32;
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, used);
+ }
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, used);
+ }
+ }
+ if (used < szdstb) {
+ dstb[used] = '\0';
+ } else {
+ dstb[szdstb - 1] = '\0';
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4rec02.ctr b/support/dktools/dk4rec02.ctr
new file mode 100644
index 0000000000..bc2ecfad92
--- /dev/null
+++ b/support/dktools/dk4rec02.ctr
@@ -0,0 +1,100 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ String recoding from ANSI to ASCII
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from ANSI to ASCII
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of bytes).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_ansi_to_ascii(
+ char *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4rec02.h"
+#include "dk4ansi.h"
+
+int
+dk4recode_ansi_to_ascii(
+ char *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+)
+{
+ size_t used = 0;
+ dk4_c32_t c32 = dkC32(0);
+ int back = 0;
+ unsigned char uc = '\0';
+ if ((NULL != dstb) && (NULL != src) && (0 < szdstb)) {
+ back = 1;
+ while (('\0' != *src) && (1 == back) && (used < szdstb)) {
+ uc = (unsigned char)(*(src++));
+ if (0 != dk4ansi_decode(&c32, uc)) {
+ if (dkC32(0x00000100) > c32) {
+ dstb[used++] = (char)c32;
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, used);
+ }
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, used);
+ }
+ }
+ if (used < szdstb) {
+ dstb[used] = '\0';
+ } else {
+ dstb[szdstb - 1] = '\0';
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4rec02.h b/support/dktools/dk4rec02.h
new file mode 100644
index 0000000000..46fcc0446e
--- /dev/null
+++ b/support/dktools/dk4rec02.h
@@ -0,0 +1,91 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec02.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4REC02_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4REC02_H_INCLUDED 1
+
+
+#line 9 "dk4rec02.ctr"
+
+/** @file
+ String recoding from ANSI to ASCII
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from ANSI to ASCII
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of bytes).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_ansi_to_ascii(
+ char *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4rec03.c b/support/dktools/dk4rec03.c
new file mode 100644
index 0000000000..124fb4e4d7
--- /dev/null
+++ b/support/dktools/dk4rec03.c
@@ -0,0 +1,133 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec03.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4rec03.c The dk4rec03 module.
+*/
+
+
+#line 75 "dk4rec03.ctr"
+
+#include "dk4rec03.h"
+#include "dk4mem.h"
+#include "dk4utf8.h"
+
+
+
+size_t
+dk4recode_size_ascii_to_utf8(const char *src, dk4_er_t *erp)
+{
+ dk4_er_t er; /* Internal error report */
+ unsigned char buf[8]; /* current character UTF-8 encoded */
+ size_t sz; /* Size of current UTF-8 encoded character */
+ size_t rdb = 0; /* Number of bytes read from input */
+ size_t back = 0; /* Function result */
+ unsigned char uc; /* Currenct character */
+
+ if (NULL != src) {
+ dk4error_init(&er);
+ while ('\0' != *src) {
+ uc = (unsigned char)(*(src++));
+ rdb++;
+ sz = sizeof(buf);
+ if (0 != dk4utf8_encode(buf, &sz, (dk4_c32_t)uc, &er)) {
+ if ((SIZE_MAX - sz) < back) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ back += sz;
+ } else {
+ dk4error_set_elsize_nelem(&er, DK4_E_SYNTAX, 1, rdb);
+ }
+ }
+ if (SIZE_MAX == back) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ back++;
+ if (DK4_E_NONE != er.ec) {
+ dk4error_copy(erp, &er);
+ back = 0;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4recode_ascii_to_utf8(
+ char *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+)
+{
+ unsigned char buf[8];
+ size_t sz;
+ size_t rdb = 0;
+ size_t used = 0;
+ int back = 0;
+ unsigned char uc = '\0';
+
+ if ((NULL != dstb) && (NULL != src) && (0 < szdstb)) {
+ back = 1;
+ while(('\0' != *src) && (1 == back) && (used < szdstb)) {
+ uc = (unsigned char)(*(src++));
+ sz = sizeof(buf);
+ if (0 != dk4utf8_encode(buf, &sz, (dk4_c32_t)uc, erp)) {
+ if ((szdstb - used) > sz) {
+ DK4_MEMCPY(&(dstb[used]),buf,sz);
+ used += sz;
+ } else {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rdb);
+ }
+ if (0 != back) { rdb++; }
+ }
+ if (used < szdstb) {
+ dstb[used] = '\0';
+ } else {
+ dstb[szdstb - 1] = '\0';
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4rec03.ctr b/support/dktools/dk4rec03.ctr
new file mode 100644
index 0000000000..6b89a2232f
--- /dev/null
+++ b/support/dktools/dk4rec03.ctr
@@ -0,0 +1,167 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ String recoding from ASCII to UTF-8.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from ASCII to UTF-8.
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of bytes).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_ascii_to_utf8(
+ char *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+);
+
+/** Calculate required buffer size (including final 0x00 byte)
+ for ASCII to UTF-8 conversion.
+ @param src ASCII encoded string.
+ @param erp Error report, may be NULL.
+ @return Positive value on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src is NULL,
+ - DK4_E_SYNTAX<br>
+ if there are encoding errors,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a numeric overflow occured in size calculation.
+*/
+size_t
+dk4recode_size_ascii_to_utf8(const char *src, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4rec03.h"
+#include "dk4mem.h"
+#include "dk4utf8.h"
+
+
+
+size_t
+dk4recode_size_ascii_to_utf8(const char *src, dk4_er_t *erp)
+{
+ dk4_er_t er; /* Internal error report */
+ unsigned char buf[8]; /* current character UTF-8 encoded */
+ size_t sz; /* Size of current UTF-8 encoded character */
+ size_t rdb = 0; /* Number of bytes read from input */
+ size_t back = 0; /* Function result */
+ unsigned char uc; /* Currenct character */
+
+ if (NULL != src) {
+ dk4error_init(&er);
+ while ('\0' != *src) {
+ uc = (unsigned char)(*(src++));
+ rdb++;
+ sz = sizeof(buf);
+ if (0 != dk4utf8_encode(buf, &sz, (dk4_c32_t)uc, &er)) {
+ if ((SIZE_MAX - sz) < back) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ back += sz;
+ } else {
+ dk4error_set_elsize_nelem(&er, DK4_E_SYNTAX, 1, rdb);
+ }
+ }
+ if (SIZE_MAX == back) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ back++;
+ if (DK4_E_NONE != er.ec) {
+ dk4error_copy(erp, &er);
+ back = 0;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4recode_ascii_to_utf8(
+ char *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+)
+{
+ unsigned char buf[8];
+ size_t sz;
+ size_t rdb = 0;
+ size_t used = 0;
+ int back = 0;
+ unsigned char uc = '\0';
+
+ if ((NULL != dstb) && (NULL != src) && (0 < szdstb)) {
+ back = 1;
+ while(('\0' != *src) && (1 == back) && (used < szdstb)) {
+ uc = (unsigned char)(*(src++));
+ sz = sizeof(buf);
+ if (0 != dk4utf8_encode(buf, &sz, (dk4_c32_t)uc, erp)) {
+ if ((szdstb - used) > sz) {
+ DK4_MEMCPY(&(dstb[used]),buf,sz);
+ used += sz;
+ } else {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rdb);
+ }
+ if (0 != back) { rdb++; }
+ }
+ if (used < szdstb) {
+ dstb[used] = '\0';
+ } else {
+ dstb[szdstb - 1] = '\0';
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4rec03.h b/support/dktools/dk4rec03.h
new file mode 100644
index 0000000000..8a071dabad
--- /dev/null
+++ b/support/dktools/dk4rec03.h
@@ -0,0 +1,108 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec03.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4REC03_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4REC03_H_INCLUDED 1
+
+
+#line 9 "dk4rec03.ctr"
+
+/** @file
+ String recoding from ASCII to UTF-8.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from ASCII to UTF-8.
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of bytes).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_ascii_to_utf8(
+ char *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+);
+
+/** Calculate required buffer size (including final 0x00 byte)
+ for ASCII to UTF-8 conversion.
+ @param src ASCII encoded string.
+ @param erp Error report, may be NULL.
+ @return Positive value on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src is NULL,
+ - DK4_E_SYNTAX<br>
+ if there are encoding errors,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a numeric overflow occured in size calculation.
+*/
+size_t
+dk4recode_size_ascii_to_utf8(const char *src, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4rec04.c b/support/dktools/dk4rec04.c
new file mode 100644
index 0000000000..6ee79d1b8d
--- /dev/null
+++ b/support/dktools/dk4rec04.c
@@ -0,0 +1,156 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec04.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4rec04.c The dk4rec04 module.
+*/
+
+
+#line 75 "dk4rec04.ctr"
+
+#include "dk4rec04.h"
+#include "dk4utf8.h"
+
+size_t
+dk4recode_size_utf8_to_ascii(const char *src, dk4_er_t *erp)
+{
+ dk4_er_t er;
+ dk4_utf8_decoder_t dec;
+ size_t rdb = 0;
+ size_t back = 0;
+ dk4_c32_t c32;
+ if (NULL != src) {
+ /* Initialize data structures.
+ */
+ dk4error_init(&er);
+ dk4utf8_init(&dec);
+ /* Process source string.
+ */
+ while ('\0' != *src) {
+ rdb++;
+ switch(dk4utf8_add(&dec, (unsigned char)(*(src++)))) {
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf8_get(&dec);
+ dk4utf8_init(&dec);
+ if (dkC32(0x00000100) > c32) {
+ if (SIZE_MAX == back) {
+ dk4error_set_simple_error_code(&er, DK4_E_MATH_OVERFLOW);
+ } else {
+ back++;
+ }
+ } else {
+ dk4error_set_elsize_nelem(&er, DK4_E_SYNTAX, 1, rdb);
+ }
+ } break;
+ case DK4_EDSTM_ERROR: {
+ dk4error_set_elsize_nelem(&er, DK4_E_SYNTAX, 1, rdb);
+ } break;
+ }
+ }
+ if (0 == dk4utf8_is_empty(&dec)) {
+ dk4error_set_elsize_nelem(&er, DK4_E_SYNTAX, 1, rdb);
+ }
+ /* Add one for the finalizer.
+ */
+ if (SIZE_MAX == back) {
+ dk4error_set_simple_error_code(&er, DK4_E_MATH_OVERFLOW);
+ } else {
+ back++;
+ }
+ /* On error return 0 and pass error code.
+ */
+ if (DK4_E_NONE != er.ec) {
+ back = 0;
+ dk4error_copy(erp, &er);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4recode_utf8_to_ascii(
+ char *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+)
+{
+ dk4_utf8_decoder_t dec;
+ size_t used = 0;
+ size_t rdb = 0;
+ dk4_c32_t c32 = dkC32(0);
+ int back = 0;
+
+ if ((NULL != dstb) && (NULL != src) && (0 < szdstb)) {
+ back = 1;
+ dk4utf8_init(&dec);
+ while(('\0' != *src) && (1 == back) && (used < szdstb)) {
+ switch(dk4utf8_add(&dec, (unsigned char)(*(src++)))) {
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf8_get(&dec);
+ dk4utf8_init(&dec);
+ if (dkC32(0x00000100) > c32) {
+ dstb[used++] = (char)c32;
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rdb);
+ }
+ } break;
+ case DK4_EDSTM_ERROR: {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rdb);
+ } break;
+ }
+ if(back) { rdb++; }
+ }
+ if (used < szdstb) {
+ dstb[used] = '\0';
+ } else {
+ dstb[szdstb - 1] = '\0';
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ if (0 == dk4utf8_is_empty(&dec)) {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rdb);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
diff --git a/support/dktools/dk4rec04.ctr b/support/dktools/dk4rec04.ctr
new file mode 100644
index 0000000000..c9c87442e7
--- /dev/null
+++ b/support/dktools/dk4rec04.ctr
@@ -0,0 +1,190 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ String recoding from UTF-8 to ASCII.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from UTF-8 to ASCII
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of bytes).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_utf8_to_ascii(
+ char *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+);
+
+/** Calculate required buffer size (including final 0x00 byte)
+ to convert from UTF-8 to ASCII.
+ @param src UTF-8 encoded source string.
+ @param erp Error report, may be NULL.
+ @return Positive required buffer size on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src is NULL,
+ - DK4_E_MATH_OVERFLOW<br>
+ if the required size calculation results in mathematical overflow,
+ - DK4_E_SYNTAX<br>
+ if there are errors while decoding the source string.
+*/
+size_t
+dk4recode_size_utf8_to_ascii(const char *src, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4rec04.h"
+#include "dk4utf8.h"
+
+size_t
+dk4recode_size_utf8_to_ascii(const char *src, dk4_er_t *erp)
+{
+ dk4_er_t er;
+ dk4_utf8_decoder_t dec;
+ size_t rdb = 0;
+ size_t back = 0;
+ dk4_c32_t c32;
+ if (NULL != src) {
+ /* Initialize data structures.
+ */
+ dk4error_init(&er);
+ dk4utf8_init(&dec);
+ /* Process source string.
+ */
+ while ('\0' != *src) {
+ rdb++;
+ switch(dk4utf8_add(&dec, (unsigned char)(*(src++)))) {
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf8_get(&dec);
+ dk4utf8_init(&dec);
+ if (dkC32(0x00000100) > c32) {
+ if (SIZE_MAX == back) {
+ dk4error_set_simple_error_code(&er, DK4_E_MATH_OVERFLOW);
+ } else {
+ back++;
+ }
+ } else {
+ dk4error_set_elsize_nelem(&er, DK4_E_SYNTAX, 1, rdb);
+ }
+ } break;
+ case DK4_EDSTM_ERROR: {
+ dk4error_set_elsize_nelem(&er, DK4_E_SYNTAX, 1, rdb);
+ } break;
+ }
+ }
+ if (0 == dk4utf8_is_empty(&dec)) {
+ dk4error_set_elsize_nelem(&er, DK4_E_SYNTAX, 1, rdb);
+ }
+ /* Add one for the finalizer.
+ */
+ if (SIZE_MAX == back) {
+ dk4error_set_simple_error_code(&er, DK4_E_MATH_OVERFLOW);
+ } else {
+ back++;
+ }
+ /* On error return 0 and pass error code.
+ */
+ if (DK4_E_NONE != er.ec) {
+ back = 0;
+ dk4error_copy(erp, &er);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4recode_utf8_to_ascii(
+ char *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+)
+{
+ dk4_utf8_decoder_t dec;
+ size_t used = 0;
+ size_t rdb = 0;
+ dk4_c32_t c32 = dkC32(0);
+ int back = 0;
+
+ if ((NULL != dstb) && (NULL != src) && (0 < szdstb)) {
+ back = 1;
+ dk4utf8_init(&dec);
+ while(('\0' != *src) && (1 == back) && (used < szdstb)) {
+ switch(dk4utf8_add(&dec, (unsigned char)(*(src++)))) {
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf8_get(&dec);
+ dk4utf8_init(&dec);
+ if (dkC32(0x00000100) > c32) {
+ dstb[used++] = (char)c32;
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rdb);
+ }
+ } break;
+ case DK4_EDSTM_ERROR: {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rdb);
+ } break;
+ }
+ if(back) { rdb++; }
+ }
+ if (used < szdstb) {
+ dstb[used] = '\0';
+ } else {
+ dstb[szdstb - 1] = '\0';
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ if (0 == dk4utf8_is_empty(&dec)) {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rdb);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
diff --git a/support/dktools/dk4rec04.h b/support/dktools/dk4rec04.h
new file mode 100644
index 0000000000..bb996c62b3
--- /dev/null
+++ b/support/dktools/dk4rec04.h
@@ -0,0 +1,108 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec04.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4REC04_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4REC04_H_INCLUDED 1
+
+
+#line 9 "dk4rec04.ctr"
+
+/** @file
+ String recoding from UTF-8 to ASCII.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from UTF-8 to ASCII
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of bytes).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_utf8_to_ascii(
+ char *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+);
+
+/** Calculate required buffer size (including final 0x00 byte)
+ to convert from UTF-8 to ASCII.
+ @param src UTF-8 encoded source string.
+ @param erp Error report, may be NULL.
+ @return Positive required buffer size on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src is NULL,
+ - DK4_E_MATH_OVERFLOW<br>
+ if the required size calculation results in mathematical overflow,
+ - DK4_E_SYNTAX<br>
+ if there are errors while decoding the source string.
+*/
+size_t
+dk4recode_size_utf8_to_ascii(const char *src, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4rec05.c b/support/dktools/dk4rec05.c
new file mode 100644
index 0000000000..0788feedd6
--- /dev/null
+++ b/support/dktools/dk4rec05.c
@@ -0,0 +1,142 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec05.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4rec05.c The dk4rec05 module.
+*/
+
+
+#line 76 "dk4rec05.ctr"
+
+#include "dk4rec05.h"
+#include "dk4mem.h"
+#include "dk4ansi.h"
+#include "dk4utf8.h"
+
+
+
+size_t
+dk4recode_size_ansi_to_utf8(const char *src, dk4_er_t *erp)
+{
+ dk4_er_t er; /* Internal error report */
+ unsigned char buf[8]; /* Current character UTF-8 encoded */
+ size_t rdb = 0; /* Number of bytes read from input */
+ size_t back = 0; /* Function result */
+ size_t sz; /* Size of UTF-8 encoded current character */
+ dk4_c32_t c32; /* Current 32 bit character */
+ unsigned char uc; /* Current source character */
+
+ if (NULL != src) {
+ dk4error_init(&er);
+ while ('\0' != *src) {
+ uc = (unsigned char)(*(src++));
+ rdb++;
+ if (0 != dk4ansi_decode(&c32, uc)) {
+ sz = sizeof(buf);
+ if (0 != dk4utf8_encode(buf, &sz, c32, &er)) {
+ if ((SIZE_MAX - sz) < back) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ back += sz;
+ } else {
+ dk4error_set_elsize_nelem(&er, DK4_E_SYNTAX, 1, rdb);
+ }
+ } else {
+ dk4error_set_elsize_nelem(&er, DK4_E_SYNTAX, 1, rdb);
+ }
+ }
+ if (SIZE_MAX == back) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ back++;
+ if (DK4_E_NONE != er.ec) {
+ back = 0;
+ dk4error_copy(erp, &er);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4recode_ansi_to_utf8(
+ char *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+)
+{
+ unsigned char buf[8];
+ size_t sz;
+ size_t used = 0;
+ size_t rdb = 0;
+ dk4_c32_t c32 = dkC32(0);
+ int back = 0;
+
+ if ((NULL != dstb) && (NULL != src) && (0 < szdstb)) {
+ back = 1;
+ while (('\0' != *src) && (1 == back) && (used < szdstb)) {
+ if (0 != dk4ansi_decode(&c32, (unsigned char)(*(src++)))) {
+ sz = sizeof(buf);
+ if (0 != dk4utf8_encode(buf, &sz, c32, erp)) {
+ if ((szdstb - used) > sz) {
+ DK4_MEMCPY(&(dstb[used]),buf,sz);
+ used += sz;
+ } else {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rdb);
+ }
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rdb);
+ }
+ if (0 != back) { rdb++; }
+ }
+ if (used < szdstb) {
+ dstb[used] = '\0';
+ } else {
+ dstb[szdstb - 1] = '\0';
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4rec05.ctr b/support/dktools/dk4rec05.ctr
new file mode 100644
index 0000000000..e20aff795b
--- /dev/null
+++ b/support/dktools/dk4rec05.ctr
@@ -0,0 +1,177 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ String recoding from ANSI to UTF-8.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from ANSI to UTF-8.
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of bytes).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_ansi_to_utf8(
+ char *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+);
+
+/** Calculate required buffer size (including final 0x00 byte)
+ for ANSI to UTF-8 conversion.
+ @param src ANSI encoded source string.
+ @param erp Error report, may be NULL.
+ @return Positive buffer size on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src is NULL,
+ - DK4_E_SYNTAX<br>
+ if there are encoding errors,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a numeric overflow occured in size calculation.
+*/
+size_t
+dk4recode_size_ansi_to_utf8(const char *src, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4rec05.h"
+#include "dk4mem.h"
+#include "dk4ansi.h"
+#include "dk4utf8.h"
+
+
+
+size_t
+dk4recode_size_ansi_to_utf8(const char *src, dk4_er_t *erp)
+{
+ dk4_er_t er; /* Internal error report */
+ unsigned char buf[8]; /* Current character UTF-8 encoded */
+ size_t rdb = 0; /* Number of bytes read from input */
+ size_t back = 0; /* Function result */
+ size_t sz; /* Size of UTF-8 encoded current character */
+ dk4_c32_t c32; /* Current 32 bit character */
+ unsigned char uc; /* Current source character */
+
+ if (NULL != src) {
+ dk4error_init(&er);
+ while ('\0' != *src) {
+ uc = (unsigned char)(*(src++));
+ rdb++;
+ if (0 != dk4ansi_decode(&c32, uc)) {
+ sz = sizeof(buf);
+ if (0 != dk4utf8_encode(buf, &sz, c32, &er)) {
+ if ((SIZE_MAX - sz) < back) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ back += sz;
+ } else {
+ dk4error_set_elsize_nelem(&er, DK4_E_SYNTAX, 1, rdb);
+ }
+ } else {
+ dk4error_set_elsize_nelem(&er, DK4_E_SYNTAX, 1, rdb);
+ }
+ }
+ if (SIZE_MAX == back) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ back++;
+ if (DK4_E_NONE != er.ec) {
+ back = 0;
+ dk4error_copy(erp, &er);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4recode_ansi_to_utf8(
+ char *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+)
+{
+ unsigned char buf[8];
+ size_t sz;
+ size_t used = 0;
+ size_t rdb = 0;
+ dk4_c32_t c32 = dkC32(0);
+ int back = 0;
+
+ if ((NULL != dstb) && (NULL != src) && (0 < szdstb)) {
+ back = 1;
+ while (('\0' != *src) && (1 == back) && (used < szdstb)) {
+ if (0 != dk4ansi_decode(&c32, (unsigned char)(*(src++)))) {
+ sz = sizeof(buf);
+ if (0 != dk4utf8_encode(buf, &sz, c32, erp)) {
+ if ((szdstb - used) > sz) {
+ DK4_MEMCPY(&(dstb[used]),buf,sz);
+ used += sz;
+ } else {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rdb);
+ }
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rdb);
+ }
+ if (0 != back) { rdb++; }
+ }
+ if (used < szdstb) {
+ dstb[used] = '\0';
+ } else {
+ dstb[szdstb - 1] = '\0';
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4rec05.h b/support/dktools/dk4rec05.h
new file mode 100644
index 0000000000..ce25c3cf4d
--- /dev/null
+++ b/support/dktools/dk4rec05.h
@@ -0,0 +1,109 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec05.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4REC05_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4REC05_H_INCLUDED 1
+
+
+#line 9 "dk4rec05.ctr"
+
+/** @file
+ String recoding from ANSI to UTF-8.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from ANSI to UTF-8.
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of bytes).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_ansi_to_utf8(
+ char *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+);
+
+/** Calculate required buffer size (including final 0x00 byte)
+ for ANSI to UTF-8 conversion.
+ @param src ANSI encoded source string.
+ @param erp Error report, may be NULL.
+ @return Positive buffer size on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src is NULL,
+ - DK4_E_SYNTAX<br>
+ if there are encoding errors,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a numeric overflow occured in size calculation.
+*/
+size_t
+dk4recode_size_ansi_to_utf8(const char *src, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4rec06.c b/support/dktools/dk4rec06.c
new file mode 100644
index 0000000000..096305fc1c
--- /dev/null
+++ b/support/dktools/dk4rec06.c
@@ -0,0 +1,160 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec06.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4rec06.c The dk4rec06 module.
+*/
+
+
+#line 77 "dk4rec06.ctr"
+
+
+#include "dk4rec06.h"
+#include "dk4utf8.h"
+#include "dk4ansi.h"
+
+size_t
+dk4recode_size_utf8_to_ansi(const char *src, dk4_er_t *erp)
+{
+ dk4_er_t er;
+ dk4_utf8_decoder_t dec;
+ size_t rdb = 0;
+ size_t back = 0;
+ dk4_c32_t c32;
+ unsigned char uc;
+
+ if (NULL != src) {
+ /* Initialize data structures.
+ */
+ dk4error_init(&er);
+ dk4utf8_init(&dec);
+ /* Process source string.
+ */
+ while ('\0' != *src) {
+ rdb++;
+ switch(dk4utf8_add(&dec, (unsigned char)(*(src++)))) {
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf8_get(&dec);
+ dk4utf8_init(&dec);
+ if (0 != dk4ansi_encode(&uc, c32)) {
+ if (SIZE_MAX == back) {
+ dk4error_set_simple_error_code(&er, DK4_E_MATH_OVERFLOW);
+ } else {
+ back++;
+ }
+ } else {
+ dk4error_set_elsize_nelem(&er, DK4_E_SYNTAX, 1, rdb);
+ }
+ } break;
+ case DK4_EDSTM_ERROR: {
+ dk4error_set_elsize_nelem(&er, DK4_E_SYNTAX, 1, rdb);
+ } break;
+ }
+ }
+ if (0 == dk4utf8_is_empty(&dec)) {
+ dk4error_set_elsize_nelem(&er, DK4_E_SYNTAX, 1, rdb);
+ }
+ /* Add one for the finalizer.
+ */
+ if (SIZE_MAX == back) {
+ dk4error_set_simple_error_code(&er, DK4_E_MATH_OVERFLOW);
+ } else {
+ back++;
+ }
+ /* On error return 0 and pass error code.
+ */
+ if (DK4_E_NONE != er.ec) {
+ back = 0;
+ dk4error_copy(erp, &er);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4recode_utf8_to_ansi(
+ char *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+)
+{
+ dk4_utf8_decoder_t dec;
+ size_t used = 0;
+ size_t rdb = 0;
+ dk4_c32_t c32 = dkC32(0);
+ int back = 0;
+ unsigned char uc = '\0';
+
+ if ((NULL != dstb) && (NULL != src) && (0 < szdstb)) {
+ back = 1;
+ dk4utf8_init(&dec);
+ while(('\0' != *src) && (1 == back) && (used < szdstb)) {
+ switch(dk4utf8_add(&dec, (unsigned char)(*(src++)))) {
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf8_get(&dec);
+ dk4utf8_init(&dec);
+ if (0 != dk4ansi_encode(&uc, c32)) {
+ dstb[used++] = (char)uc;
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rdb);
+ }
+ } break;
+ case DK4_EDSTM_ERROR: {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rdb);
+ } break;
+ }
+ if(back) { rdb++; }
+ }
+ if (used < szdstb) {
+ dstb[used] = '\0';
+ } else {
+ dstb[szdstb - 1] = '\0';
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ if (0 == dk4utf8_is_empty(&dec)) {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rdb);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4rec06.ctr b/support/dktools/dk4rec06.ctr
new file mode 100644
index 0000000000..c5188a2ed3
--- /dev/null
+++ b/support/dktools/dk4rec06.ctr
@@ -0,0 +1,196 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+
+/** @file
+ String recoding from UTF-8 to ANSI.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from UTF-8 to ANSI.
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of bytes).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_utf8_to_ansi(
+ char *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+);
+
+/** Calculate required buffer size (including final 0x00 byte)
+ for UTF-8 to ANSI conversion.
+ @param src UTF-8 encoded source string.
+ @param erp Error report, may be NULL.
+ @return Positive buffer size on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src is NULL,
+ - DK4_E_MATH_OVERFLOW<br>
+ if the required size calculation results in mathematical overflow,
+ - DK4_E_SYNTAX<br>
+ if there are errors while decoding the source string.
+*/
+size_t
+dk4recode_size_utf8_to_ansi(const char *src, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+
+#include "dk4rec06.h"
+#include "dk4utf8.h"
+#include "dk4ansi.h"
+
+size_t
+dk4recode_size_utf8_to_ansi(const char *src, dk4_er_t *erp)
+{
+ dk4_er_t er;
+ dk4_utf8_decoder_t dec;
+ size_t rdb = 0;
+ size_t back = 0;
+ dk4_c32_t c32;
+ unsigned char uc;
+
+ if (NULL != src) {
+ /* Initialize data structures.
+ */
+ dk4error_init(&er);
+ dk4utf8_init(&dec);
+ /* Process source string.
+ */
+ while ('\0' != *src) {
+ rdb++;
+ switch(dk4utf8_add(&dec, (unsigned char)(*(src++)))) {
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf8_get(&dec);
+ dk4utf8_init(&dec);
+ if (0 != dk4ansi_encode(&uc, c32)) {
+ if (SIZE_MAX == back) {
+ dk4error_set_simple_error_code(&er, DK4_E_MATH_OVERFLOW);
+ } else {
+ back++;
+ }
+ } else {
+ dk4error_set_elsize_nelem(&er, DK4_E_SYNTAX, 1, rdb);
+ }
+ } break;
+ case DK4_EDSTM_ERROR: {
+ dk4error_set_elsize_nelem(&er, DK4_E_SYNTAX, 1, rdb);
+ } break;
+ }
+ }
+ if (0 == dk4utf8_is_empty(&dec)) {
+ dk4error_set_elsize_nelem(&er, DK4_E_SYNTAX, 1, rdb);
+ }
+ /* Add one for the finalizer.
+ */
+ if (SIZE_MAX == back) {
+ dk4error_set_simple_error_code(&er, DK4_E_MATH_OVERFLOW);
+ } else {
+ back++;
+ }
+ /* On error return 0 and pass error code.
+ */
+ if (DK4_E_NONE != er.ec) {
+ back = 0;
+ dk4error_copy(erp, &er);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4recode_utf8_to_ansi(
+ char *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+)
+{
+ dk4_utf8_decoder_t dec;
+ size_t used = 0;
+ size_t rdb = 0;
+ dk4_c32_t c32 = dkC32(0);
+ int back = 0;
+ unsigned char uc = '\0';
+
+ if ((NULL != dstb) && (NULL != src) && (0 < szdstb)) {
+ back = 1;
+ dk4utf8_init(&dec);
+ while(('\0' != *src) && (1 == back) && (used < szdstb)) {
+ switch(dk4utf8_add(&dec, (unsigned char)(*(src++)))) {
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf8_get(&dec);
+ dk4utf8_init(&dec);
+ if (0 != dk4ansi_encode(&uc, c32)) {
+ dstb[used++] = (char)uc;
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rdb);
+ }
+ } break;
+ case DK4_EDSTM_ERROR: {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rdb);
+ } break;
+ }
+ if(back) { rdb++; }
+ }
+ if (used < szdstb) {
+ dstb[used] = '\0';
+ } else {
+ dstb[szdstb - 1] = '\0';
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ if (0 == dk4utf8_is_empty(&dec)) {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rdb);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4rec06.h b/support/dktools/dk4rec06.h
new file mode 100644
index 0000000000..3449032892
--- /dev/null
+++ b/support/dktools/dk4rec06.h
@@ -0,0 +1,110 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec06.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4REC06_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4REC06_H_INCLUDED 1
+
+
+#line 9 "dk4rec06.ctr"
+
+
+/** @file
+ String recoding from UTF-8 to ANSI.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from UTF-8 to ANSI.
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of bytes).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_utf8_to_ansi(
+ char *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+);
+
+/** Calculate required buffer size (including final 0x00 byte)
+ for UTF-8 to ANSI conversion.
+ @param src UTF-8 encoded source string.
+ @param erp Error report, may be NULL.
+ @return Positive buffer size on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src is NULL,
+ - DK4_E_MATH_OVERFLOW<br>
+ if the required size calculation results in mathematical overflow,
+ - DK4_E_SYNTAX<br>
+ if there are errors while decoding the source string.
+*/
+size_t
+dk4recode_size_utf8_to_ansi(const char *src, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4rec07.c b/support/dktools/dk4rec07.c
new file mode 100644
index 0000000000..a76c39d8f8
--- /dev/null
+++ b/support/dktools/dk4rec07.c
@@ -0,0 +1,89 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec07.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4rec07.c The dk4rec07 module.
+*/
+
+
+#line 59 "dk4rec07.ctr"
+
+#include "dk4rec07.h"
+#include "dk4mem.h"
+#include "dk4utf16.h"
+
+int
+dk4recode_ascii_to_utf16(
+ dk4_c16_t *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+)
+{
+ dk4_c16_t buf[4];
+ size_t sz;
+ size_t used = 0;
+ size_t rdb = 0;
+ int back = 0;
+ unsigned char uc = '\0';
+ if ((NULL != dstb) && (NULL != src) && (0 < szdstb)) {
+ back = 1;
+ while(('\0' != *src) && (1 == back) && (used < szdstb)) {
+ uc = (unsigned char)(*(src++));
+ sz = DK4_SIZEOF(buf,dk4_c16_t);
+ if (0 != dk4utf16_encode(buf, &sz, (dk4_c32_t)uc, erp)) {
+ if ((szdstb - used) > sz) {
+ DK4_MEMCPY(&(dstb[used]),buf,(2 * sz));
+ used += sz;
+ } else {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rdb);
+ }
+ if (0 != back) { rdb++; }
+ }
+ if (used < szdstb) {
+ dstb[used] = (dk4_c16_t)0U;
+ } else {
+ dstb[szdstb - 1] = (dk4_c16_t)0U;
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4rec07.ctr b/support/dktools/dk4rec07.ctr
new file mode 100644
index 0000000000..440810dc83
--- /dev/null
+++ b/support/dktools/dk4rec07.ctr
@@ -0,0 +1,107 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ String recoding from ASCII to UTF-16.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from ASCII to UTF-16.
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of dk4_c16_t).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_ascii_to_utf16(
+ dk4_c16_t *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4rec07.h"
+#include "dk4mem.h"
+#include "dk4utf16.h"
+
+int
+dk4recode_ascii_to_utf16(
+ dk4_c16_t *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+)
+{
+ dk4_c16_t buf[4];
+ size_t sz;
+ size_t used = 0;
+ size_t rdb = 0;
+ int back = 0;
+ unsigned char uc = '\0';
+ if ((NULL != dstb) && (NULL != src) && (0 < szdstb)) {
+ back = 1;
+ while(('\0' != *src) && (1 == back) && (used < szdstb)) {
+ uc = (unsigned char)(*(src++));
+ sz = DK4_SIZEOF(buf,dk4_c16_t);
+ if (0 != dk4utf16_encode(buf, &sz, (dk4_c32_t)uc, erp)) {
+ if ((szdstb - used) > sz) {
+ DK4_MEMCPY(&(dstb[used]),buf,(2 * sz));
+ used += sz;
+ } else {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rdb);
+ }
+ if (0 != back) { rdb++; }
+ }
+ if (used < szdstb) {
+ dstb[used] = (dk4_c16_t)0U;
+ } else {
+ dstb[szdstb - 1] = (dk4_c16_t)0U;
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4rec07.h b/support/dktools/dk4rec07.h
new file mode 100644
index 0000000000..a9900b4bf6
--- /dev/null
+++ b/support/dktools/dk4rec07.h
@@ -0,0 +1,92 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec07.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4REC07_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4REC07_H_INCLUDED 1
+
+
+#line 9 "dk4rec07.ctr"
+
+/** @file
+ String recoding from ASCII to UTF-16.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from ASCII to UTF-16.
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of dk4_c16_t).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_ascii_to_utf16(
+ dk4_c16_t *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4rec08.c b/support/dktools/dk4rec08.c
new file mode 100644
index 0000000000..a713a93323
--- /dev/null
+++ b/support/dktools/dk4rec08.c
@@ -0,0 +1,97 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec08.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4rec08.c The dk4rec08 module.
+*/
+
+
+#line 59 "dk4rec08.ctr"
+
+#include "dk4rec08.h"
+#include "dk4mem.h"
+#include "dk4utf16.h"
+
+
+
+int
+dk4recode_utf16_to_ascii(
+ char *dstb, size_t szdstb, const dk4_c16_t *src, dk4_er_t *erp
+)
+{
+ dk4_utf16_decoder_t dec;
+ size_t used = 0;
+ size_t rd = 0;
+ dk4_c32_t c32 = dkC32(0);
+ int back = 0;
+
+ if ((NULL != dstb) && (NULL != src) && (0 < szdstb)) {
+ back = 1;
+ dk4utf16_init(&dec);
+ while(((dk4_c16_t)0U != *src) && (1 == back) && (used < szdstb)) {
+ switch(dk4utf16_add(&dec, *(src++))) {
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf16_get(&dec);
+ dk4utf16_init(&dec);
+ if (dkC32(0x00000100) > c32) {
+ dstb[used++] = (char)c32;
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 2, rd);
+ }
+ } break;
+ case DK4_EDSTM_ERROR: {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 2, rd);
+ } break;
+ }
+ if (0 != back) { rd++; }
+ }
+ if (used < szdstb) {
+ dstb[used] = '\0';
+ } else {
+ dstb[szdstb - 1] = '\0';
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ if (0 == dk4utf16_is_empty(&dec)) {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 2, rd);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4rec08.ctr b/support/dktools/dk4rec08.ctr
new file mode 100644
index 0000000000..fdc22729e7
--- /dev/null
+++ b/support/dktools/dk4rec08.ctr
@@ -0,0 +1,115 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ String recoding from UTF-16 to ASCII.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from UTF-16 to ASCII.
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of bytes).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_utf16_to_ascii(
+ char *dstb, size_t szdstb, const dk4_c16_t *src, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4rec08.h"
+#include "dk4mem.h"
+#include "dk4utf16.h"
+
+
+
+int
+dk4recode_utf16_to_ascii(
+ char *dstb, size_t szdstb, const dk4_c16_t *src, dk4_er_t *erp
+)
+{
+ dk4_utf16_decoder_t dec;
+ size_t used = 0;
+ size_t rd = 0;
+ dk4_c32_t c32 = dkC32(0);
+ int back = 0;
+
+ if ((NULL != dstb) && (NULL != src) && (0 < szdstb)) {
+ back = 1;
+ dk4utf16_init(&dec);
+ while(((dk4_c16_t)0U != *src) && (1 == back) && (used < szdstb)) {
+ switch(dk4utf16_add(&dec, *(src++))) {
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf16_get(&dec);
+ dk4utf16_init(&dec);
+ if (dkC32(0x00000100) > c32) {
+ dstb[used++] = (char)c32;
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 2, rd);
+ }
+ } break;
+ case DK4_EDSTM_ERROR: {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 2, rd);
+ } break;
+ }
+ if (0 != back) { rd++; }
+ }
+ if (used < szdstb) {
+ dstb[used] = '\0';
+ } else {
+ dstb[szdstb - 1] = '\0';
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ if (0 == dk4utf16_is_empty(&dec)) {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 2, rd);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4rec08.h b/support/dktools/dk4rec08.h
new file mode 100644
index 0000000000..aae058398c
--- /dev/null
+++ b/support/dktools/dk4rec08.h
@@ -0,0 +1,92 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec08.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4REC08_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4REC08_H_INCLUDED 1
+
+
+#line 9 "dk4rec08.ctr"
+
+/** @file
+ String recoding from UTF-16 to ASCII.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from UTF-16 to ASCII.
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of bytes).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_utf16_to_ascii(
+ char *dstb, size_t szdstb, const dk4_c16_t *src, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4rec09.c b/support/dktools/dk4rec09.c
new file mode 100644
index 0000000000..c7eaa136c6
--- /dev/null
+++ b/support/dktools/dk4rec09.c
@@ -0,0 +1,97 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec09.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4rec09.c The dk4rec09 module.
+*/
+
+
+#line 59 "dk4rec09.ctr"
+
+#include "dk4rec09.h"
+#include "dk4mem.h"
+#include "dk4ansi.h"
+#include "dk4utf16.h"
+
+
+
+int
+dk4recode_ansi_to_utf16(
+ dk4_c16_t *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+)
+{
+ dk4_c16_t buf[8];
+ size_t sz;
+ size_t rd = 0;
+ size_t used = 0;
+ dk4_c32_t c32 = dkC32(0);
+ int back = 0;
+
+ if ((NULL != dstb) && (NULL != src) && (0 < szdstb)) {
+ back = 1;
+ while(((dk4_c16_t)0U != *src) && (1 == back) && (used < szdstb)) {
+ if (0 != dk4ansi_decode(&c32, (unsigned char)(*(src++)))) {
+ sz = DK4_SIZEOF(buf,dk4_c16_t);
+ if (0 != dk4utf16_encode(buf, &sz, c32, erp)) {
+ if ((szdstb - used) > sz) {
+ DK4_MEMCPY(&(dstb[used]),buf,(2 * sz));
+ used += sz;
+ } else {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rd);
+ }
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rd);
+ }
+ if (0 != back) { rd++; }
+ }
+ if (used < szdstb) {
+ dstb[used] = (dk4_c16_t)0U;
+ } else {
+ dstb[szdstb - 1] = (dk4_c16_t)0U;
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4rec09.ctr b/support/dktools/dk4rec09.ctr
new file mode 100644
index 0000000000..71bf4e3e4e
--- /dev/null
+++ b/support/dktools/dk4rec09.ctr
@@ -0,0 +1,115 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ String recoding from ANSI to UTF-16.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from ANSI to UTF-16.
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of dk4_c16_t).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_ansi_to_utf16(
+ dk4_c16_t *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4rec09.h"
+#include "dk4mem.h"
+#include "dk4ansi.h"
+#include "dk4utf16.h"
+
+
+
+int
+dk4recode_ansi_to_utf16(
+ dk4_c16_t *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+)
+{
+ dk4_c16_t buf[8];
+ size_t sz;
+ size_t rd = 0;
+ size_t used = 0;
+ dk4_c32_t c32 = dkC32(0);
+ int back = 0;
+
+ if ((NULL != dstb) && (NULL != src) && (0 < szdstb)) {
+ back = 1;
+ while(((dk4_c16_t)0U != *src) && (1 == back) && (used < szdstb)) {
+ if (0 != dk4ansi_decode(&c32, (unsigned char)(*(src++)))) {
+ sz = DK4_SIZEOF(buf,dk4_c16_t);
+ if (0 != dk4utf16_encode(buf, &sz, c32, erp)) {
+ if ((szdstb - used) > sz) {
+ DK4_MEMCPY(&(dstb[used]),buf,(2 * sz));
+ used += sz;
+ } else {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rd);
+ }
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rd);
+ }
+ if (0 != back) { rd++; }
+ }
+ if (used < szdstb) {
+ dstb[used] = (dk4_c16_t)0U;
+ } else {
+ dstb[szdstb - 1] = (dk4_c16_t)0U;
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4rec09.h b/support/dktools/dk4rec09.h
new file mode 100644
index 0000000000..8c806e91c4
--- /dev/null
+++ b/support/dktools/dk4rec09.h
@@ -0,0 +1,92 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec09.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4REC09_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4REC09_H_INCLUDED 1
+
+
+#line 9 "dk4rec09.ctr"
+
+/** @file
+ String recoding from ANSI to UTF-16.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from ANSI to UTF-16.
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of dk4_c16_t).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_ansi_to_utf16(
+ dk4_c16_t *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4rec10.c b/support/dktools/dk4rec10.c
new file mode 100644
index 0000000000..fd20c964d6
--- /dev/null
+++ b/support/dktools/dk4rec10.c
@@ -0,0 +1,99 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec10.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4rec10.c The dk4rec10 module.
+*/
+
+
+#line 59 "dk4rec10.ctr"
+
+#include "dk4rec10.h"
+#include "dk4mem.h"
+#include "dk4ansi.h"
+#include "dk4utf16.h"
+
+
+
+int
+dk4recode_utf16_to_ansi(
+ char *dstb, size_t szdstb, const dk4_c16_t *src, dk4_er_t *erp
+)
+{
+ dk4_utf16_decoder_t dec;
+ size_t used = 0;
+ size_t rd = 0;
+ dk4_c32_t c32 = dkC32(0);
+ int back = 0;
+ unsigned char uc = '\0';
+
+ if ((NULL != dstb) && (NULL != src) && (0 < szdstb)) {
+ back = 1;
+ dk4utf16_init(&dec);
+ while(((dk4_c16_t)0U != *src) && (1 == back) && (used < szdstb)) {
+ switch(dk4utf16_add(&dec, *(src++))) {
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf16_get(&dec);
+ dk4utf16_init(&dec);
+ if (0 != dk4ansi_encode(&uc, c32)) {
+ dstb[used++] = (char)c32;
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 2, rd);
+ }
+ } break;
+ case DK4_EDSTM_ERROR: {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 2, rd);
+ } break;
+ }
+ if (0 != back) { rd++; }
+ }
+ if (used < szdstb) {
+ dstb[used] = '\0';
+ } else {
+ dstb[szdstb - 1] = '\0';
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ if (0 == dk4utf16_is_empty(&dec)) {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 2, rd);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4rec10.ctr b/support/dktools/dk4rec10.ctr
new file mode 100644
index 0000000000..869ef2262b
--- /dev/null
+++ b/support/dktools/dk4rec10.ctr
@@ -0,0 +1,117 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ String recoding from UTF-16 to ANSI
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from UTF-16 to ANSI.
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of bytes).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_utf16_to_ansi(
+ char *dstb, size_t szdstb, const dk4_c16_t *src, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4rec10.h"
+#include "dk4mem.h"
+#include "dk4ansi.h"
+#include "dk4utf16.h"
+
+
+
+int
+dk4recode_utf16_to_ansi(
+ char *dstb, size_t szdstb, const dk4_c16_t *src, dk4_er_t *erp
+)
+{
+ dk4_utf16_decoder_t dec;
+ size_t used = 0;
+ size_t rd = 0;
+ dk4_c32_t c32 = dkC32(0);
+ int back = 0;
+ unsigned char uc = '\0';
+
+ if ((NULL != dstb) && (NULL != src) && (0 < szdstb)) {
+ back = 1;
+ dk4utf16_init(&dec);
+ while(((dk4_c16_t)0U != *src) && (1 == back) && (used < szdstb)) {
+ switch(dk4utf16_add(&dec, *(src++))) {
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf16_get(&dec);
+ dk4utf16_init(&dec);
+ if (0 != dk4ansi_encode(&uc, c32)) {
+ dstb[used++] = (char)c32;
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 2, rd);
+ }
+ } break;
+ case DK4_EDSTM_ERROR: {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 2, rd);
+ } break;
+ }
+ if (0 != back) { rd++; }
+ }
+ if (used < szdstb) {
+ dstb[used] = '\0';
+ } else {
+ dstb[szdstb - 1] = '\0';
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ if (0 == dk4utf16_is_empty(&dec)) {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 2, rd);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4rec10.h b/support/dktools/dk4rec10.h
new file mode 100644
index 0000000000..a035c33125
--- /dev/null
+++ b/support/dktools/dk4rec10.h
@@ -0,0 +1,92 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec10.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4REC10_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4REC10_H_INCLUDED 1
+
+
+#line 9 "dk4rec10.ctr"
+
+/** @file
+ String recoding from UTF-16 to ANSI
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from UTF-16 to ANSI.
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of bytes).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_utf16_to_ansi(
+ char *dstb, size_t szdstb, const dk4_c16_t *src, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4rec11.c b/support/dktools/dk4rec11.c
new file mode 100644
index 0000000000..138d58d453
--- /dev/null
+++ b/support/dktools/dk4rec11.c
@@ -0,0 +1,178 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec11.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4rec11.c The dk4rec11 module.
+*/
+
+
+#line 76 "dk4rec11.ctr"
+
+#include "dk4rec11.h"
+#include "dk4mem.h"
+#include "dk4utf8.h"
+#include "dk4utf16.h"
+
+
+
+
+#line 84 "dk4rec11.ctr"
+
+
+
+size_t
+dk4recode_size_utf8_to_utf16(const char *src, dk4_er_t *erp)
+{
+ dk4_er_t er;
+ dk4_utf8_decoder_t dec;
+ dk4_c16_t c16[4];
+ size_t rdb = 0;
+ size_t back = 0;
+ size_t sz;
+ dk4_c32_t c32;
+
+ if (NULL != src) {
+ /* Initialize data structures.
+ */
+ dk4error_init(&er);
+ dk4utf8_init(&dec);
+ /* Process source string.
+ */
+ while ('\0' != *src) {
+ rdb++;
+ switch(dk4utf8_add(&dec, (unsigned char)(*(src++)))) {
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf8_get(&dec);
+ dk4utf8_init(&dec);
+ sz = DK4_SIZEOF(c16,dk4_c16_t);
+ if (0 != dk4utf16_encode(c16, &sz, c32, &er)) {
+ if ((SIZE_MAX - sz) >= back) {
+ back += sz;
+ } else {
+ dk4error_set_simple_error_code(&er, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ dk4error_set_elsize_nelem(&er, DK4_E_SYNTAX, 1, rdb);
+ }
+ } break;
+ case DK4_EDSTM_ERROR: {
+ dk4error_set_elsize_nelem(&er, DK4_E_SYNTAX, 1, rdb);
+ } break;
+ }
+ }
+ if (0 == dk4utf8_is_empty(&dec)) {
+ dk4error_set_elsize_nelem(&er, DK4_E_SYNTAX, 1, rdb);
+ }
+ /* Add one for the finalizer.
+ */
+ if (SIZE_MAX == back) {
+ dk4error_set_simple_error_code(&er, DK4_E_MATH_OVERFLOW);
+ } else {
+ back++;
+ }
+ /* On error return 0 and pass error code.
+ */
+ if (DK4_E_NONE != er.ec) {
+ back = 0;
+ dk4error_copy(erp, &er);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4recode_utf8_to_utf16(
+ dk4_c16_t *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+)
+{
+ dk4_c16_t buf[8];
+ dk4_utf8_decoder_t dec;
+ size_t sz;
+ size_t used = 0;
+ size_t rdb = 0;
+ dk4_c32_t c32 = dkC32(0);
+ int back = 0;
+
+ if ((NULL != dstb) && (NULL != src) && (0 < szdstb)) {
+ back = 1;
+ dk4utf8_init(&dec);
+ while(('\0' != *src) && (1 == back) && (used < szdstb)) {
+ switch(dk4utf8_add(&dec, (unsigned char)(*(src++)))) {
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf8_get(&dec);
+ dk4utf8_init(&dec);
+ sz = DK4_SIZEOF(buf,dk4_c16_t);
+ if (0 != dk4utf16_encode(buf, &sz, c32, erp)) {
+ if ((szdstb - used) > sz) {
+ DK4_MEMCPY(&(dstb[used]),buf,(2 * sz));
+ used += sz;
+ } else {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rdb);
+ }
+ } break;
+ case DK4_EDSTM_ERROR: {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rdb);
+ } break;
+ }
+ if(back) { rdb++; }
+ }
+ if (used < szdstb) {
+ dstb[used] = (dk4_c16_t)0U;
+ } else {
+ dstb[szdstb - 1] = (dk4_c16_t)0U;
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ if (0 == dk4utf8_is_empty(&dec)) {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rdb);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
diff --git a/support/dktools/dk4rec11.ctr b/support/dktools/dk4rec11.ctr
new file mode 100644
index 0000000000..723d86b854
--- /dev/null
+++ b/support/dktools/dk4rec11.ctr
@@ -0,0 +1,211 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ String recoding from UTF-8 to UTF-16.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from UTF-8 to UTF-16.
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of dk_c16-t).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_utf8_to_utf16(
+ dk4_c16_t *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+);
+
+/** Calculate required buffer size (including final 0x0000U word)
+ to convert from UTF-8 to UTF-16.
+ @param src UTF-8 encoded source string.
+ @param erp Error report, may be NULL.
+ @return Positive required buffer size (number of dk4_c16_t) on success,
+ 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src is NULL,
+ - DK4_E_MATH_OVERFLOW<br>
+ if the required size calculation results in mathematical overflow,
+ - DK4_E_SYNTAX<br>
+ if there are errors while decoding the source string.
+*/
+size_t
+dk4recode_size_utf8_to_utf16(const char *src, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4rec11.h"
+#include "dk4mem.h"
+#include "dk4utf8.h"
+#include "dk4utf16.h"
+
+
+$!trace-include
+
+
+
+size_t
+dk4recode_size_utf8_to_utf16(const char *src, dk4_er_t *erp)
+{
+ dk4_er_t er;
+ dk4_utf8_decoder_t dec;
+ dk4_c16_t c16[4];
+ size_t rdb = 0;
+ size_t back = 0;
+ size_t sz;
+ dk4_c32_t c32;
+
+ if (NULL != src) {
+ /* Initialize data structures.
+ */
+ dk4error_init(&er);
+ dk4utf8_init(&dec);
+ /* Process source string.
+ */
+ while ('\0' != *src) {
+ rdb++;
+ switch(dk4utf8_add(&dec, (unsigned char)(*(src++)))) {
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf8_get(&dec);
+ dk4utf8_init(&dec);
+ sz = DK4_SIZEOF(c16,dk4_c16_t);
+ if (0 != dk4utf16_encode(c16, &sz, c32, &er)) {
+ if ((SIZE_MAX - sz) >= back) {
+ back += sz;
+ } else {
+ dk4error_set_simple_error_code(&er, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ dk4error_set_elsize_nelem(&er, DK4_E_SYNTAX, 1, rdb);
+ }
+ } break;
+ case DK4_EDSTM_ERROR: {
+ dk4error_set_elsize_nelem(&er, DK4_E_SYNTAX, 1, rdb);
+ } break;
+ }
+ }
+ if (0 == dk4utf8_is_empty(&dec)) {
+ dk4error_set_elsize_nelem(&er, DK4_E_SYNTAX, 1, rdb);
+ }
+ /* Add one for the finalizer.
+ */
+ if (SIZE_MAX == back) {
+ dk4error_set_simple_error_code(&er, DK4_E_MATH_OVERFLOW);
+ } else {
+ back++;
+ }
+ /* On error return 0 and pass error code.
+ */
+ if (DK4_E_NONE != er.ec) {
+ back = 0;
+ dk4error_copy(erp, &er);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4recode_utf8_to_utf16(
+ dk4_c16_t *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+)
+{
+ dk4_c16_t buf[8];
+ dk4_utf8_decoder_t dec;
+ size_t sz;
+ size_t used = 0;
+ size_t rdb = 0;
+ dk4_c32_t c32 = dkC32(0);
+ int back = 0;
+
+ if ((NULL != dstb) && (NULL != src) && (0 < szdstb)) {
+ back = 1;
+ dk4utf8_init(&dec);
+ while(('\0' != *src) && (1 == back) && (used < szdstb)) {
+ switch(dk4utf8_add(&dec, (unsigned char)(*(src++)))) {
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf8_get(&dec);
+ dk4utf8_init(&dec);
+ sz = DK4_SIZEOF(buf,dk4_c16_t);
+ if (0 != dk4utf16_encode(buf, &sz, c32, erp)) {
+ if ((szdstb - used) > sz) {
+ DK4_MEMCPY(&(dstb[used]),buf,(2 * sz));
+ used += sz;
+ } else {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rdb);
+ }
+ } break;
+ case DK4_EDSTM_ERROR: {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rdb);
+ } break;
+ }
+ if(back) { rdb++; }
+ }
+ if (used < szdstb) {
+ dstb[used] = (dk4_c16_t)0U;
+ } else {
+ dstb[szdstb - 1] = (dk4_c16_t)0U;
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ if (0 == dk4utf8_is_empty(&dec)) {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rdb);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
diff --git a/support/dktools/dk4rec11.h b/support/dktools/dk4rec11.h
new file mode 100644
index 0000000000..da927995bd
--- /dev/null
+++ b/support/dktools/dk4rec11.h
@@ -0,0 +1,109 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec11.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4REC11_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4REC11_H_INCLUDED 1
+
+
+#line 9 "dk4rec11.ctr"
+
+/** @file
+ String recoding from UTF-8 to UTF-16.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from UTF-8 to UTF-16.
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of dk_c16-t).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_utf8_to_utf16(
+ dk4_c16_t *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+);
+
+/** Calculate required buffer size (including final 0x0000U word)
+ to convert from UTF-8 to UTF-16.
+ @param src UTF-8 encoded source string.
+ @param erp Error report, may be NULL.
+ @return Positive required buffer size (number of dk4_c16_t) on success,
+ 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src is NULL,
+ - DK4_E_MATH_OVERFLOW<br>
+ if the required size calculation results in mathematical overflow,
+ - DK4_E_SYNTAX<br>
+ if there are errors while decoding the source string.
+*/
+size_t
+dk4recode_size_utf8_to_utf16(const char *src, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4rec12.c b/support/dktools/dk4rec12.c
new file mode 100644
index 0000000000..94ce3bb7e9
--- /dev/null
+++ b/support/dktools/dk4rec12.c
@@ -0,0 +1,160 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec12.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4rec12.c The dk4rec12 module.
+*/
+
+
+#line 75 "dk4rec12.ctr"
+
+#include "dk4rec12.h"
+#include "dk4mem.h"
+#include "dk4utf8.h"
+#include "dk4utf16.h"
+
+
+
+size_t
+dk4recode_size_utf16_to_utf8(const dk4_c16_t *src, dk4_er_t *erp)
+{
+ dk4_er_t er;
+ unsigned char buf[8];
+ dk4_utf16_decoder_t dec;
+ size_t sz;
+ size_t rd = 0;
+ size_t back = 0;
+ dk4_c32_t c32 = dkC32(0);
+ if (NULL != src) {
+ dk4error_init(&er);
+ dk4utf16_init(&dec);
+ while(((dk4_c16_t)0U != *src) && (DK4_E_NONE == er.ec)) {
+ switch(dk4utf16_add(&dec, *(src++))) {
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf16_get(&dec);
+ dk4utf16_init(&dec);
+ sz = sizeof(buf);
+ if (0 != dk4utf8_encode(buf, &sz, c32, &er)) {
+ if ((SIZE_MAX - sz) >= back) {
+ back += sz;
+ rd++;
+ } else {
+ dk4error_set_simple_error_code(&er, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ } break;
+ case DK4_EDSTM_ERROR: {
+ dk4error_set_elsize_nelem(&er, DK4_E_SYNTAX, 2, rd);
+ } break;
+ }
+ }
+ if (0 == dk4utf16_is_empty(&dec)) {
+ dk4error_set_elsize_nelem(&er, DK4_E_SYNTAX, 2, rd);
+ }
+ if (SIZE_MAX > back) {
+ back++;
+ } else {
+ dk4error_set_simple_error_code(&er, DK4_E_MATH_OVERFLOW);
+ }
+ if (DK4_E_NONE != er.ec) {
+ dk4error_copy(erp, &er);
+ back = 0;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4recode_utf16_to_utf8(
+ char *dstb, size_t szdstb, const dk4_c16_t *src, dk4_er_t *erp
+)
+{
+ unsigned char buf[8];
+ dk4_utf16_decoder_t dec;
+ size_t sz;
+ size_t used = 0;
+ size_t rd = 0;
+ dk4_c32_t c32 = dkC32(0);
+ int back = 0;
+
+ if ((NULL != dstb) && (NULL != src) && (0 < szdstb)) {
+ back = 1;
+ dk4utf16_init(&dec);
+ while(((dk4_c16_t)0U != *src) && (1 == back) && (used < szdstb)) {
+ switch(dk4utf16_add(&dec, *(src++))) {
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf16_get(&dec);
+ dk4utf16_init(&dec);
+ sz = sizeof(buf);
+ if (0 != dk4utf8_encode(buf, &sz, c32, erp)) {
+ if ((szdstb - used) > sz) {
+ DK4_MEMCPY(&(dstb[used]),buf,sz);
+ used += sz;
+ } else {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 2, rd);
+ }
+ } break;
+ case DK4_EDSTM_ERROR: {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 2, rd);
+ } break;
+ }
+ if (0 != back) { rd++; }
+ }
+ if (used < szdstb) {
+ dstb[used] = '\0';
+ } else {
+ dstb[szdstb - 1] = '\0';
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ if (0 == dk4utf16_is_empty(&dec)) {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 2, rd);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4rec12.ctr b/support/dktools/dk4rec12.ctr
new file mode 100644
index 0000000000..2259b75a7e
--- /dev/null
+++ b/support/dktools/dk4rec12.ctr
@@ -0,0 +1,194 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ String recoding from UTF-16 to UTF-8.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from UTF-16 to UTF-8.
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of bytes).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_utf16_to_utf8(
+ char *dstb, size_t szdstb, const dk4_c16_t *src, dk4_er_t *erp
+);
+
+/** Calculate required buffer size (including final 0x00 byte)
+ for UTF-16 to UTF-8 conversion.
+ @param src UTF-16 encoded source string.
+ @param erp Error report, may be NULL.
+ @return Positive buffer size on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+size_t
+dk4recode_size_utf16_to_utf8(const dk4_c16_t *src, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4rec12.h"
+#include "dk4mem.h"
+#include "dk4utf8.h"
+#include "dk4utf16.h"
+
+
+
+size_t
+dk4recode_size_utf16_to_utf8(const dk4_c16_t *src, dk4_er_t *erp)
+{
+ dk4_er_t er;
+ unsigned char buf[8];
+ dk4_utf16_decoder_t dec;
+ size_t sz;
+ size_t rd = 0;
+ size_t back = 0;
+ dk4_c32_t c32 = dkC32(0);
+ if (NULL != src) {
+ dk4error_init(&er);
+ dk4utf16_init(&dec);
+ while(((dk4_c16_t)0U != *src) && (DK4_E_NONE == er.ec)) {
+ switch(dk4utf16_add(&dec, *(src++))) {
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf16_get(&dec);
+ dk4utf16_init(&dec);
+ sz = sizeof(buf);
+ if (0 != dk4utf8_encode(buf, &sz, c32, &er)) {
+ if ((SIZE_MAX - sz) >= back) {
+ back += sz;
+ rd++;
+ } else {
+ dk4error_set_simple_error_code(&er, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ } break;
+ case DK4_EDSTM_ERROR: {
+ dk4error_set_elsize_nelem(&er, DK4_E_SYNTAX, 2, rd);
+ } break;
+ }
+ }
+ if (0 == dk4utf16_is_empty(&dec)) {
+ dk4error_set_elsize_nelem(&er, DK4_E_SYNTAX, 2, rd);
+ }
+ if (SIZE_MAX > back) {
+ back++;
+ } else {
+ dk4error_set_simple_error_code(&er, DK4_E_MATH_OVERFLOW);
+ }
+ if (DK4_E_NONE != er.ec) {
+ dk4error_copy(erp, &er);
+ back = 0;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4recode_utf16_to_utf8(
+ char *dstb, size_t szdstb, const dk4_c16_t *src, dk4_er_t *erp
+)
+{
+ unsigned char buf[8];
+ dk4_utf16_decoder_t dec;
+ size_t sz;
+ size_t used = 0;
+ size_t rd = 0;
+ dk4_c32_t c32 = dkC32(0);
+ int back = 0;
+
+ if ((NULL != dstb) && (NULL != src) && (0 < szdstb)) {
+ back = 1;
+ dk4utf16_init(&dec);
+ while(((dk4_c16_t)0U != *src) && (1 == back) && (used < szdstb)) {
+ switch(dk4utf16_add(&dec, *(src++))) {
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf16_get(&dec);
+ dk4utf16_init(&dec);
+ sz = sizeof(buf);
+ if (0 != dk4utf8_encode(buf, &sz, c32, erp)) {
+ if ((szdstb - used) > sz) {
+ DK4_MEMCPY(&(dstb[used]),buf,sz);
+ used += sz;
+ } else {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 2, rd);
+ }
+ } break;
+ case DK4_EDSTM_ERROR: {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 2, rd);
+ } break;
+ }
+ if (0 != back) { rd++; }
+ }
+ if (used < szdstb) {
+ dstb[used] = '\0';
+ } else {
+ dstb[szdstb - 1] = '\0';
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ if (0 == dk4utf16_is_empty(&dec)) {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 2, rd);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4rec12.h b/support/dktools/dk4rec12.h
new file mode 100644
index 0000000000..72b1683473
--- /dev/null
+++ b/support/dktools/dk4rec12.h
@@ -0,0 +1,108 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec12.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4REC12_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4REC12_H_INCLUDED 1
+
+
+#line 9 "dk4rec12.ctr"
+
+/** @file
+ String recoding from UTF-16 to UTF-8.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from UTF-16 to UTF-8.
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of bytes).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_utf16_to_utf8(
+ char *dstb, size_t szdstb, const dk4_c16_t *src, dk4_er_t *erp
+);
+
+/** Calculate required buffer size (including final 0x00 byte)
+ for UTF-16 to UTF-8 conversion.
+ @param src UTF-16 encoded source string.
+ @param erp Error report, may be NULL.
+ @return Positive buffer size on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+size_t
+dk4recode_size_utf16_to_utf8(const dk4_c16_t *src, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4rec13.c b/support/dktools/dk4rec13.c
new file mode 100644
index 0000000000..ca5af35c6d
--- /dev/null
+++ b/support/dktools/dk4rec13.c
@@ -0,0 +1,73 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec13.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4rec13.c The dk4rec13 module.
+*/
+
+
+#line 58 "dk4rec13.ctr"
+
+#include "dk4rec13.h"
+
+#ifndef DK4STR8_H_INCLUDED
+#include "dk4str8.h"
+#endif
+
+
+
+int
+dk4recode_ascii_to_c32(
+ dk4_c32_t *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+)
+{
+ int back = 0;
+
+ if ((NULL != dstb) && (0 < szdstb) && (NULL != src)) {
+ if (szdstb > dk4str8_len(src)) {
+ while ('\0' != *src) {
+ *(dstb++) = (dk4_c32_t)((unsigned char)(*(src++)));
+ }
+ *dstb = dkC32(0);
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4rec13.ctr b/support/dktools/dk4rec13.ctr
new file mode 100644
index 0000000000..7cd8fe5451
--- /dev/null
+++ b/support/dktools/dk4rec13.ctr
@@ -0,0 +1,90 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ String recoding from ASCII to 32 bit.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from ASCII to 32 bit.
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of bytes).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_ascii_to_c32(
+ dk4_c32_t *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4rec13.h"
+
+#ifndef DK4STR8_H_INCLUDED
+#include "dk4str8.h"
+#endif
+
+
+
+int
+dk4recode_ascii_to_c32(
+ dk4_c32_t *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+)
+{
+ int back = 0;
+
+ if ((NULL != dstb) && (0 < szdstb) && (NULL != src)) {
+ if (szdstb > dk4str8_len(src)) {
+ while ('\0' != *src) {
+ *(dstb++) = (dk4_c32_t)((unsigned char)(*(src++)));
+ }
+ *dstb = dkC32(0);
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4rec13.h b/support/dktools/dk4rec13.h
new file mode 100644
index 0000000000..31464c92ab
--- /dev/null
+++ b/support/dktools/dk4rec13.h
@@ -0,0 +1,91 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec13.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4REC13_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4REC13_H_INCLUDED 1
+
+
+#line 9 "dk4rec13.ctr"
+
+/** @file
+ String recoding from ASCII to 32 bit.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from ASCII to 32 bit.
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of bytes).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_ascii_to_c32(
+ dk4_c32_t *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4rec14.c b/support/dktools/dk4rec14.c
new file mode 100644
index 0000000000..900f80486c
--- /dev/null
+++ b/support/dktools/dk4rec14.c
@@ -0,0 +1,80 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec14.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4rec14.c The dk4rec14 module.
+*/
+
+
+#line 58 "dk4rec14.ctr"
+
+#include "dk4rec14.h"
+
+
+int
+dk4recode_c32_to_ascii(
+ char *dstb, size_t szdstb, const dk4_c32_t *src, dk4_er_t *erp
+)
+{
+ size_t rd = 0;
+ size_t used = 0;
+ dk4_c32_t c32 = dkC32(0);
+ int back = 0;
+
+ if ((NULL != dstb) && (0 < szdstb) && (NULL != src)) {
+ back = 1;
+ while((dkC32(0) != *src) && (1 == back) && (used < szdstb)) {
+ c32 = *(src++);
+ if (dkC32(0x00000100) > c32) {
+ dstb[used++] = (char)c32;
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 4, rd);
+ }
+ if (0 != back) { rd++; }
+ }
+ if (used < szdstb) {
+ dstb[used] = '\0';
+ } else {
+ dstb[szdstb - 1] = '\0';
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4rec14.ctr b/support/dktools/dk4rec14.ctr
new file mode 100644
index 0000000000..685b63f555
--- /dev/null
+++ b/support/dktools/dk4rec14.ctr
@@ -0,0 +1,97 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ String recoding from 32 bit to ASCII.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from 32 bit to ASCII.
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of bytes).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_c32_to_ascii(
+ char *dstb, size_t szdstb, const dk4_c32_t *src, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4rec14.h"
+
+
+int
+dk4recode_c32_to_ascii(
+ char *dstb, size_t szdstb, const dk4_c32_t *src, dk4_er_t *erp
+)
+{
+ size_t rd = 0;
+ size_t used = 0;
+ dk4_c32_t c32 = dkC32(0);
+ int back = 0;
+
+ if ((NULL != dstb) && (0 < szdstb) && (NULL != src)) {
+ back = 1;
+ while((dkC32(0) != *src) && (1 == back) && (used < szdstb)) {
+ c32 = *(src++);
+ if (dkC32(0x00000100) > c32) {
+ dstb[used++] = (char)c32;
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 4, rd);
+ }
+ if (0 != back) { rd++; }
+ }
+ if (used < szdstb) {
+ dstb[used] = '\0';
+ } else {
+ dstb[szdstb - 1] = '\0';
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4rec14.h b/support/dktools/dk4rec14.h
new file mode 100644
index 0000000000..9e21f42a94
--- /dev/null
+++ b/support/dktools/dk4rec14.h
@@ -0,0 +1,91 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec14.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4REC14_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4REC14_H_INCLUDED 1
+
+
+#line 9 "dk4rec14.ctr"
+
+/** @file
+ String recoding from 32 bit to ASCII.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from 32 bit to ASCII.
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of bytes).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_c32_to_ascii(
+ char *dstb, size_t szdstb, const dk4_c32_t *src, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4rec15.c b/support/dktools/dk4rec15.c
new file mode 100644
index 0000000000..5da7a5dc1c
--- /dev/null
+++ b/support/dktools/dk4rec15.c
@@ -0,0 +1,80 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec15.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4rec15.c The dk4rec15 module.
+*/
+
+
+#line 59 "dk4rec15.ctr"
+
+#include "dk4rec15.h"
+#include "dk4ansi.h"
+
+
+
+int
+dk4recode_ansi_to_c32(
+ dk4_c32_t *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+)
+{
+ size_t used = 0;
+ size_t rdb = 0;
+ dk4_c32_t c32 = dkC32(0);
+ int back = 0;
+
+ if ((NULL != dstb) && (NULL != src) && (0 < szdstb)) {
+ back = 1;
+ while (('\0' != *src) && (1 == back) && (used < szdstb)) {
+ if (0 != dk4ansi_decode(&c32, (unsigned char)(*(src++)))) {
+ dstb[used++] = c32;
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rdb);
+ }
+ if (0 != back) { rdb++; }
+ }
+ if (used < szdstb) {
+ dstb[used] = '\0';
+ } else {
+ dstb[szdstb - 1] = '\0';
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4rec15.ctr b/support/dktools/dk4rec15.ctr
new file mode 100644
index 0000000000..eb1e48bacb
--- /dev/null
+++ b/support/dktools/dk4rec15.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ String recoding from ANSI to 32 bit.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from ANSI to 32 bit.
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of bytes).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_ansi_to_c32(
+ dk4_c32_t *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4rec15.h"
+#include "dk4ansi.h"
+
+
+
+int
+dk4recode_ansi_to_c32(
+ dk4_c32_t *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+)
+{
+ size_t used = 0;
+ size_t rdb = 0;
+ dk4_c32_t c32 = dkC32(0);
+ int back = 0;
+
+ if ((NULL != dstb) && (NULL != src) && (0 < szdstb)) {
+ back = 1;
+ while (('\0' != *src) && (1 == back) && (used < szdstb)) {
+ if (0 != dk4ansi_decode(&c32, (unsigned char)(*(src++)))) {
+ dstb[used++] = c32;
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rdb);
+ }
+ if (0 != back) { rdb++; }
+ }
+ if (used < szdstb) {
+ dstb[used] = '\0';
+ } else {
+ dstb[szdstb - 1] = '\0';
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4rec15.h b/support/dktools/dk4rec15.h
new file mode 100644
index 0000000000..691d31f2ee
--- /dev/null
+++ b/support/dktools/dk4rec15.h
@@ -0,0 +1,92 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec15.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4REC15_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4REC15_H_INCLUDED 1
+
+
+#line 9 "dk4rec15.ctr"
+
+/** @file
+ String recoding from ANSI to 32 bit.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from ANSI to 32 bit.
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of bytes).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_ansi_to_c32(
+ dk4_c32_t *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4rec16.c b/support/dktools/dk4rec16.c
new file mode 100644
index 0000000000..bc9ebd4a09
--- /dev/null
+++ b/support/dktools/dk4rec16.c
@@ -0,0 +1,81 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec16.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4rec16.c The dk4rec16 module.
+*/
+
+
+#line 58 "dk4rec16.ctr"
+
+#include "dk4rec16.h"
+#include "dk4ansi.h"
+
+int
+dk4recode_c32_to_ansi(
+ char *dstb, size_t szdstb, const dk4_c32_t *src, dk4_er_t *erp
+)
+{
+ size_t rd = 0;
+ size_t used = 0;
+ dk4_c32_t c32 = dkC32(0);
+ int back = 0;
+ unsigned char uc = '\0';
+
+ if ((NULL != dstb) && (0 < szdstb) && (NULL != src)) {
+ back = 1;
+ while((dkC32(0) != *src) && (1 == back) && (used < szdstb)) {
+ c32 = *(src++);
+ if (0 != dk4ansi_encode(&uc, c32)) {
+ dstb[used++] = (char)uc;
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 4, rd);
+ }
+ if (0 != back) { rd++; }
+ }
+ if (used < szdstb) {
+ dstb[used] = '\0';
+ } else {
+ dstb[szdstb - 1] = '\0';
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4rec16.ctr b/support/dktools/dk4rec16.ctr
new file mode 100644
index 0000000000..d44d9bcbe2
--- /dev/null
+++ b/support/dktools/dk4rec16.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ String recoding from 32 bit to ANSI.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from 32 bit to ANSI.
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of bytes).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_c32_to_ansi(
+ char *dstb, size_t szdstb, const dk4_c32_t *src, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4rec16.h"
+#include "dk4ansi.h"
+
+int
+dk4recode_c32_to_ansi(
+ char *dstb, size_t szdstb, const dk4_c32_t *src, dk4_er_t *erp
+)
+{
+ size_t rd = 0;
+ size_t used = 0;
+ dk4_c32_t c32 = dkC32(0);
+ int back = 0;
+ unsigned char uc = '\0';
+
+ if ((NULL != dstb) && (0 < szdstb) && (NULL != src)) {
+ back = 1;
+ while((dkC32(0) != *src) && (1 == back) && (used < szdstb)) {
+ c32 = *(src++);
+ if (0 != dk4ansi_encode(&uc, c32)) {
+ dstb[used++] = (char)uc;
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 4, rd);
+ }
+ if (0 != back) { rd++; }
+ }
+ if (used < szdstb) {
+ dstb[used] = '\0';
+ } else {
+ dstb[szdstb - 1] = '\0';
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4rec16.h b/support/dktools/dk4rec16.h
new file mode 100644
index 0000000000..1571e11047
--- /dev/null
+++ b/support/dktools/dk4rec16.h
@@ -0,0 +1,91 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec16.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4REC16_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4REC16_H_INCLUDED 1
+
+
+#line 9 "dk4rec16.ctr"
+
+/** @file
+ String recoding from 32 bit to ANSI.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from 32 bit to ANSI.
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of bytes).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_c32_to_ansi(
+ char *dstb, size_t szdstb, const dk4_c32_t *src, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4rec17.c b/support/dktools/dk4rec17.c
new file mode 100644
index 0000000000..cb4585c3dd
--- /dev/null
+++ b/support/dktools/dk4rec17.c
@@ -0,0 +1,151 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec17.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4rec17.c The dk4rec17 module.
+*/
+
+
+#line 76 "dk4rec17.ctr"
+
+#include "dk4rec17.h"
+#include "dk4utf8.h"
+
+
+
+
+#line 82 "dk4rec17.ctr"
+
+
+size_t
+dk4recode_size_utf8_to_c32(const char *src, dk4_er_t *erp)
+{
+ dk4_er_t er;
+ dk4_utf8_decoder_t dec;
+ size_t rdb = 0;
+ size_t back = 0;
+
+ if (NULL != src) {
+ /* Initialize data structures.
+ */
+ dk4error_init(&er);
+ dk4utf8_init(&dec);
+ /* Process source string.
+ */
+ while ('\0' != *src) {
+ rdb++;
+ switch(dk4utf8_add(&dec, (unsigned char)(*(src++)))) {
+ case DK4_EDSTM_FINISHED: {
+ (void)dk4utf8_get(&dec);
+ dk4utf8_init(&dec);
+ if (SIZE_MAX == back) {
+ dk4error_set_simple_error_code(&er, DK4_E_MATH_OVERFLOW);
+ } else {
+ back++;
+ }
+ } break;
+ case DK4_EDSTM_ERROR: {
+ dk4error_set_elsize_nelem(&er, DK4_E_SYNTAX, 1, rdb);
+ } break;
+ }
+ }
+ if (0 == dk4utf8_is_empty(&dec)) {
+ dk4error_set_elsize_nelem(&er, DK4_E_SYNTAX, 1, rdb);
+ }
+ /* Add one for the finalizer.
+ */
+ if (SIZE_MAX == back) {
+ dk4error_set_simple_error_code(&er, DK4_E_MATH_OVERFLOW);
+ } else {
+ back++;
+ }
+ /* On error return 0 and pass error code.
+ */
+ if (DK4_E_NONE != er.ec) {
+ back = 0;
+ dk4error_copy(erp, &er);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+int
+dk4recode_utf8_to_c32(
+ dk4_c32_t *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+)
+{
+ dk4_utf8_decoder_t dec;
+ size_t used = 0;
+ size_t rdb = 0;
+ dk4_c32_t c32 = dkC32(0);
+ int back = 0;
+
+ if ((NULL != dstb) && (NULL != src) && (0 < szdstb)) {
+ back = 1;
+ dk4utf8_init(&dec);
+ while(('\0' != *src) && (1 == back) && (used < szdstb)) {
+ switch(dk4utf8_add(&dec, (unsigned char)(*(src++)))) {
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf8_get(&dec);
+ dk4utf8_init(&dec);
+ dstb[used++] = c32;
+ } break;
+ case DK4_EDSTM_ERROR: {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rdb);
+ } break;
+ }
+ if(back) { rdb++; }
+ }
+ if (used < szdstb) {
+ dstb[used] = (dk4_c16_t)0U;
+ } else {
+ dstb[szdstb - 1] = (dk4_c16_t)0U;
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ if (0 == dk4utf8_is_empty(&dec)) {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rdb);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
diff --git a/support/dktools/dk4rec17.ctr b/support/dktools/dk4rec17.ctr
new file mode 100644
index 0000000000..f9b79e062f
--- /dev/null
+++ b/support/dktools/dk4rec17.ctr
@@ -0,0 +1,184 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ String recoding from UTF-8 to 32 bit.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from UTF-8 to 32 bit.
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of bytes).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_utf8_to_c32(
+ dk4_c32_t *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+);
+
+/** Calculate required buffer size (including final 0x00000000UL character)
+ to convert from UTF-8 to 32 bit characters.
+ @param src UTF-8 encoded source string.
+ @param erp Error report, may be NULL.
+ @return Positive required buffer size (number of dk4_c32_t) on success,
+ 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src is NULL,
+ - DK4_E_MATH_OVERFLOW<br>
+ if the required size calculation results in mathematical overflow,
+ - DK4_E_SYNTAX<br>
+ if there are errors while decoding the source string.
+*/
+size_t
+dk4recode_size_utf8_to_c32(const char *src, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4rec17.h"
+#include "dk4utf8.h"
+
+
+$!trace-include
+
+
+size_t
+dk4recode_size_utf8_to_c32(const char *src, dk4_er_t *erp)
+{
+ dk4_er_t er;
+ dk4_utf8_decoder_t dec;
+ size_t rdb = 0;
+ size_t back = 0;
+
+ if (NULL != src) {
+ /* Initialize data structures.
+ */
+ dk4error_init(&er);
+ dk4utf8_init(&dec);
+ /* Process source string.
+ */
+ while ('\0' != *src) {
+ rdb++;
+ switch(dk4utf8_add(&dec, (unsigned char)(*(src++)))) {
+ case DK4_EDSTM_FINISHED: {
+ (void)dk4utf8_get(&dec);
+ dk4utf8_init(&dec);
+ if (SIZE_MAX == back) {
+ dk4error_set_simple_error_code(&er, DK4_E_MATH_OVERFLOW);
+ } else {
+ back++;
+ }
+ } break;
+ case DK4_EDSTM_ERROR: {
+ dk4error_set_elsize_nelem(&er, DK4_E_SYNTAX, 1, rdb);
+ } break;
+ }
+ }
+ if (0 == dk4utf8_is_empty(&dec)) {
+ dk4error_set_elsize_nelem(&er, DK4_E_SYNTAX, 1, rdb);
+ }
+ /* Add one for the finalizer.
+ */
+ if (SIZE_MAX == back) {
+ dk4error_set_simple_error_code(&er, DK4_E_MATH_OVERFLOW);
+ } else {
+ back++;
+ }
+ /* On error return 0 and pass error code.
+ */
+ if (DK4_E_NONE != er.ec) {
+ back = 0;
+ dk4error_copy(erp, &er);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+int
+dk4recode_utf8_to_c32(
+ dk4_c32_t *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+)
+{
+ dk4_utf8_decoder_t dec;
+ size_t used = 0;
+ size_t rdb = 0;
+ dk4_c32_t c32 = dkC32(0);
+ int back = 0;
+
+ if ((NULL != dstb) && (NULL != src) && (0 < szdstb)) {
+ back = 1;
+ dk4utf8_init(&dec);
+ while(('\0' != *src) && (1 == back) && (used < szdstb)) {
+ switch(dk4utf8_add(&dec, (unsigned char)(*(src++)))) {
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf8_get(&dec);
+ dk4utf8_init(&dec);
+ dstb[used++] = c32;
+ } break;
+ case DK4_EDSTM_ERROR: {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rdb);
+ } break;
+ }
+ if(back) { rdb++; }
+ }
+ if (used < szdstb) {
+ dstb[used] = (dk4_c16_t)0U;
+ } else {
+ dstb[szdstb - 1] = (dk4_c16_t)0U;
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ if (0 == dk4utf8_is_empty(&dec)) {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rdb);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
diff --git a/support/dktools/dk4rec17.h b/support/dktools/dk4rec17.h
new file mode 100644
index 0000000000..53e4888a16
--- /dev/null
+++ b/support/dktools/dk4rec17.h
@@ -0,0 +1,109 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec17.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4REC17_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4REC17_H_INCLUDED 1
+
+
+#line 9 "dk4rec17.ctr"
+
+/** @file
+ String recoding from UTF-8 to 32 bit.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from UTF-8 to 32 bit.
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of bytes).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_utf8_to_c32(
+ dk4_c32_t *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+);
+
+/** Calculate required buffer size (including final 0x00000000UL character)
+ to convert from UTF-8 to 32 bit characters.
+ @param src UTF-8 encoded source string.
+ @param erp Error report, may be NULL.
+ @return Positive required buffer size (number of dk4_c32_t) on success,
+ 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src is NULL,
+ - DK4_E_MATH_OVERFLOW<br>
+ if the required size calculation results in mathematical overflow,
+ - DK4_E_SYNTAX<br>
+ if there are errors while decoding the source string.
+*/
+size_t
+dk4recode_size_utf8_to_c32(const char *src, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4rec18.c b/support/dktools/dk4rec18.c
new file mode 100644
index 0000000000..012ad98404
--- /dev/null
+++ b/support/dktools/dk4rec18.c
@@ -0,0 +1,138 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec18.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4rec18.c The dk4rec18 module.
+*/
+
+
+#line 74 "dk4rec18.ctr"
+
+#include "dk4rec18.h"
+#include "dk4mem.h"
+#include "dk4utf8.h"
+
+
+
+
+
+#line 82 "dk4rec18.ctr"
+
+
+
+size_t
+dk4recode_size_c32_to_utf8(const dk4_c32_t *src, dk4_er_t *erp)
+{
+ dk4_er_t er;
+ unsigned char buf[8];
+ size_t sz;
+ size_t rd = 0;
+ size_t back = 0;
+ dk4_c32_t c32 = dkC32(0);
+
+ if (NULL != src) {
+ dk4error_init(&er);
+ while (dkC32(0) != (c32 = *(src++))) {
+ sz = sizeof(buf);
+ if (0 != dk4utf8_encode(buf, &sz, c32, &er)) {
+ if ((SIZE_MAX - sz) >= back) {
+ back += sz;
+ rd++;
+ } else {
+ dk4error_set_simple_error_code(&er, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ if (SIZE_MAX > back) {
+ back++;
+ } else {
+ dk4error_set_simple_error_code(&er, DK4_E_MATH_OVERFLOW);
+ }
+ if (DK4_E_NONE != er.ec) {
+ back = 0;
+ dk4error_copy(erp, &er);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4recode_c32_to_utf8(
+ char *dstb, size_t szdstb, const dk4_c32_t *src, dk4_er_t *erp
+)
+{
+ unsigned char buf[8];
+ size_t sz;
+ size_t rd = 0;
+ size_t used = 0;
+ dk4_c32_t c32 = dkC32(0);
+ int back = 0;
+
+ if ((NULL != dstb) && (0 < szdstb) && (NULL != src)) {
+ back = 1;
+ while((dkC32(0) != *src) && (1 == back) && (used < szdstb)) {
+ c32 = *(src++);
+ sz = sizeof(buf);
+ if (0 != dk4utf8_encode(buf, &sz, c32, erp)) {
+ if ((szdstb - used) > sz) {
+ DK4_MEMCPY(&(dstb[used]),buf,sz);
+ used += sz;
+ } else {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 4, rd);
+ }
+ if (0 != back) { rd++; }
+ }
+ if (used < szdstb) {
+ dstb[used] = '\0';
+ } else {
+ dstb[szdstb - 1] = '\0';
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4rec18.ctr b/support/dktools/dk4rec18.ctr
new file mode 100644
index 0000000000..2f3bc777ab
--- /dev/null
+++ b/support/dktools/dk4rec18.ctr
@@ -0,0 +1,169 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ String recoding from 32 bit to UTF-8.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from 32 bit to UTF-8.
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of bytes).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_c32_to_utf8(
+ char *dstb, size_t szdstb, const dk4_c32_t *src, dk4_er_t *erp
+);
+
+/** Calculate required buffer size (including final 0x00 byte)
+ for C32 to UTF-8 conversion.
+ @param src C32 source string.
+ @param erp Error report, may be NULL.
+ @return Positive buffer size on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+size_t
+dk4recode_size_c32_to_utf8(const dk4_c32_t *src, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4rec18.h"
+#include "dk4mem.h"
+#include "dk4utf8.h"
+
+
+
+$!trace-include
+
+
+
+size_t
+dk4recode_size_c32_to_utf8(const dk4_c32_t *src, dk4_er_t *erp)
+{
+ dk4_er_t er;
+ unsigned char buf[8];
+ size_t sz;
+ size_t rd = 0;
+ size_t back = 0;
+ dk4_c32_t c32 = dkC32(0);
+
+ if (NULL != src) {
+ dk4error_init(&er);
+ while (dkC32(0) != (c32 = *(src++))) {
+ sz = sizeof(buf);
+ if (0 != dk4utf8_encode(buf, &sz, c32, &er)) {
+ if ((SIZE_MAX - sz) >= back) {
+ back += sz;
+ rd++;
+ } else {
+ dk4error_set_simple_error_code(&er, DK4_E_MATH_OVERFLOW);
+ }
+ }
+ }
+ if (SIZE_MAX > back) {
+ back++;
+ } else {
+ dk4error_set_simple_error_code(&er, DK4_E_MATH_OVERFLOW);
+ }
+ if (DK4_E_NONE != er.ec) {
+ back = 0;
+ dk4error_copy(erp, &er);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4recode_c32_to_utf8(
+ char *dstb, size_t szdstb, const dk4_c32_t *src, dk4_er_t *erp
+)
+{
+ unsigned char buf[8];
+ size_t sz;
+ size_t rd = 0;
+ size_t used = 0;
+ dk4_c32_t c32 = dkC32(0);
+ int back = 0;
+
+ if ((NULL != dstb) && (0 < szdstb) && (NULL != src)) {
+ back = 1;
+ while((dkC32(0) != *src) && (1 == back) && (used < szdstb)) {
+ c32 = *(src++);
+ sz = sizeof(buf);
+ if (0 != dk4utf8_encode(buf, &sz, c32, erp)) {
+ if ((szdstb - used) > sz) {
+ DK4_MEMCPY(&(dstb[used]),buf,sz);
+ used += sz;
+ } else {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 4, rd);
+ }
+ if (0 != back) { rd++; }
+ }
+ if (used < szdstb) {
+ dstb[used] = '\0';
+ } else {
+ dstb[szdstb - 1] = '\0';
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4rec18.h b/support/dktools/dk4rec18.h
new file mode 100644
index 0000000000..cf1095420b
--- /dev/null
+++ b/support/dktools/dk4rec18.h
@@ -0,0 +1,107 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec18.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4REC18_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4REC18_H_INCLUDED 1
+
+
+#line 9 "dk4rec18.ctr"
+
+/** @file
+ String recoding from 32 bit to UTF-8.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from 32 bit to UTF-8.
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of bytes).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_c32_to_utf8(
+ char *dstb, size_t szdstb, const dk4_c32_t *src, dk4_er_t *erp
+);
+
+/** Calculate required buffer size (including final 0x00 byte)
+ for C32 to UTF-8 conversion.
+ @param src C32 source string.
+ @param erp Error report, may be NULL.
+ @return Positive buffer size on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+size_t
+dk4recode_size_c32_to_utf8(const dk4_c32_t *src, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4rec19.c b/support/dktools/dk4rec19.c
new file mode 100644
index 0000000000..2791812282
--- /dev/null
+++ b/support/dktools/dk4rec19.c
@@ -0,0 +1,91 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec19.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4rec19.c The dk4rec19 module.
+*/
+
+
+#line 59 "dk4rec19.ctr"
+
+#include "dk4rec19.h"
+#include "dk4utf16.h"
+
+
+
+int
+dk4recode_utf16_to_c32(
+ dk4_c32_t *dstb, size_t szdstb, const dk4_c16_t *src, dk4_er_t *erp
+)
+{
+ dk4_utf16_decoder_t dec;
+ size_t used = 0;
+ size_t rd = 0;
+ dk4_c32_t c32 = dkC32(0);
+ int back = 0;
+
+ if ((NULL != dstb) && (NULL != src) && (0 < szdstb)) {
+ back = 1;
+ dk4utf16_init(&dec);
+ while(((dk4_c16_t)0U != *src) && (1 == back) && (used < szdstb)) {
+ switch(dk4utf16_add(&dec, *(src++))) {
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf16_get(&dec);
+ dk4utf16_init(&dec);
+ dstb[used++] = c32;
+ } break;
+ case DK4_EDSTM_ERROR: {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 2, rd);
+ } break;
+ }
+ if (0 != back) { rd++; }
+ }
+ if (used < szdstb) {
+ dstb[used] = '\0';
+ } else {
+ dstb[szdstb - 1] = '\0';
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ if (0 == dk4utf16_is_empty(&dec)) {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 2, rd);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4rec19.ctr b/support/dktools/dk4rec19.ctr
new file mode 100644
index 0000000000..d476e1f1c7
--- /dev/null
+++ b/support/dktools/dk4rec19.ctr
@@ -0,0 +1,109 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ String recoding from UTF-16 to 32 bit.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from UTF-16 to 32 bit.
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of bytes).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_utf16_to_c32(
+ dk4_c32_t *dstb, size_t szdstb, const dk4_c16_t *src, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4rec19.h"
+#include "dk4utf16.h"
+
+
+
+int
+dk4recode_utf16_to_c32(
+ dk4_c32_t *dstb, size_t szdstb, const dk4_c16_t *src, dk4_er_t *erp
+)
+{
+ dk4_utf16_decoder_t dec;
+ size_t used = 0;
+ size_t rd = 0;
+ dk4_c32_t c32 = dkC32(0);
+ int back = 0;
+
+ if ((NULL != dstb) && (NULL != src) && (0 < szdstb)) {
+ back = 1;
+ dk4utf16_init(&dec);
+ while(((dk4_c16_t)0U != *src) && (1 == back) && (used < szdstb)) {
+ switch(dk4utf16_add(&dec, *(src++))) {
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf16_get(&dec);
+ dk4utf16_init(&dec);
+ dstb[used++] = c32;
+ } break;
+ case DK4_EDSTM_ERROR: {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 2, rd);
+ } break;
+ }
+ if (0 != back) { rd++; }
+ }
+ if (used < szdstb) {
+ dstb[used] = '\0';
+ } else {
+ dstb[szdstb - 1] = '\0';
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ if (0 == dk4utf16_is_empty(&dec)) {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 2, rd);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4rec19.h b/support/dktools/dk4rec19.h
new file mode 100644
index 0000000000..117df9af28
--- /dev/null
+++ b/support/dktools/dk4rec19.h
@@ -0,0 +1,92 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec19.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4REC19_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4REC19_H_INCLUDED 1
+
+
+#line 9 "dk4rec19.ctr"
+
+/** @file
+ String recoding from UTF-16 to 32 bit.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from UTF-16 to 32 bit.
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of bytes).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_utf16_to_c32(
+ dk4_c32_t *dstb, size_t szdstb, const dk4_c16_t *src, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4rec20.c b/support/dktools/dk4rec20.c
new file mode 100644
index 0000000000..e2ad3e3da9
--- /dev/null
+++ b/support/dktools/dk4rec20.c
@@ -0,0 +1,90 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec20.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4rec20.c The dk4rec20 module.
+*/
+
+
+#line 58 "dk4rec20.ctr"
+
+#include "dk4rec20.h"
+#include "dk4mem.h"
+#include "dk4utf16.h"
+
+int
+dk4recode_c32_to_utf16(
+ dk4_c16_t *dstb, size_t szdstb, const dk4_c32_t *src, dk4_er_t *erp
+)
+{
+ dk4_c16_t buf[4];
+ size_t sz;
+ size_t rd = 0;
+ size_t used = 0;
+ dk4_c32_t c32 = dkC32(0);
+ int back = 0;
+
+ if ((NULL != dstb) && (0 < szdstb) && (NULL != src)) {
+ back = 1;
+ while((dkC32(0) != *src) && (1 == back) && (used < szdstb)) {
+ c32 = *(src++);
+ sz = DK4_SIZEOF(buf,dk4_c16_t);
+ if (0 != dk4utf16_encode(buf, &sz, c32, erp)) {
+ if ((szdstb - used) > sz) {
+ DK4_MEMCPY(&(dstb[used]),buf,(2 * sz));
+ used += sz;
+ } else {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 4, rd);
+ }
+ if (0 != back) { rd++; }
+ }
+ if (used < szdstb) {
+ dstb[used] = '\0';
+ } else {
+ dstb[szdstb - 1] = '\0';
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4rec20.ctr b/support/dktools/dk4rec20.ctr
new file mode 100644
index 0000000000..217bcc1322
--- /dev/null
+++ b/support/dktools/dk4rec20.ctr
@@ -0,0 +1,107 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ String recoding from 32 bit to UTF-16.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from 32 bit to UTF-16.
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of bytes).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_c32_to_utf16(
+ dk4_c16_t *dstb, size_t szdstb, const dk4_c32_t *src, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4rec20.h"
+#include "dk4mem.h"
+#include "dk4utf16.h"
+
+int
+dk4recode_c32_to_utf16(
+ dk4_c16_t *dstb, size_t szdstb, const dk4_c32_t *src, dk4_er_t *erp
+)
+{
+ dk4_c16_t buf[4];
+ size_t sz;
+ size_t rd = 0;
+ size_t used = 0;
+ dk4_c32_t c32 = dkC32(0);
+ int back = 0;
+
+ if ((NULL != dstb) && (0 < szdstb) && (NULL != src)) {
+ back = 1;
+ while((dkC32(0) != *src) && (1 == back) && (used < szdstb)) {
+ c32 = *(src++);
+ sz = DK4_SIZEOF(buf,dk4_c16_t);
+ if (0 != dk4utf16_encode(buf, &sz, c32, erp)) {
+ if ((szdstb - used) > sz) {
+ DK4_MEMCPY(&(dstb[used]),buf,(2 * sz));
+ used += sz;
+ } else {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ back = 0;
+ dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 4, rd);
+ }
+ if (0 != back) { rd++; }
+ }
+ if (used < szdstb) {
+ dstb[used] = '\0';
+ } else {
+ dstb[szdstb - 1] = '\0';
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4rec20.h b/support/dktools/dk4rec20.h
new file mode 100644
index 0000000000..b92ebd791e
--- /dev/null
+++ b/support/dktools/dk4rec20.h
@@ -0,0 +1,91 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec20.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4REC20_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4REC20_H_INCLUDED 1
+
+
+#line 9 "dk4rec20.ctr"
+
+/** @file
+ String recoding from 32 bit to UTF-16.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from 32 bit to UTF-16.
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of bytes).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_c32_to_utf16(
+ dk4_c16_t *dstb, size_t szdstb, const dk4_c32_t *src, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4rec21.c b/support/dktools/dk4rec21.c
new file mode 100644
index 0000000000..e339ca31be
--- /dev/null
+++ b/support/dktools/dk4rec21.c
@@ -0,0 +1,84 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec21.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4rec21.c The dk4rec21 module.
+*/
+
+
+#line 67 "dk4rec21.ctr"
+
+#include "dk4enc.h"
+#include "dk4rec21.h"
+#include "dk4rec01.h"
+#include "dk4rec03.h"
+#include "dk4rec07.h"
+#include "dk4rec13.h"
+#include "dk4str8.h"
+
+
+
+int
+dk4recode_ascii_to_dk(
+ dkChar *dstb, size_t szdstb, int enc, const char *src, dk4_er_t *erp
+)
+{
+ int back = 0;
+ if ((NULL != dstb) && (0 < szdstb) && (NULL != src)) {
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ back = dk4recode_ascii_to_c32(dstb, szdstb, src, erp);
+#else
+ back = dk4recode_ascii_to_utf16(dstb, szdstb, src, erp);
+#endif
+#else
+ switch (enc) {
+ case DK4_ENCODING_UTF8: {
+ back = dk4recode_ascii_to_utf8(dstb, szdstb, src, erp);
+ } break;
+ case DK4_ENCODING_ANSI: {
+ back = dk4recode_ascii_to_ansi(dstb, szdstb, src, erp);
+ } break;
+ default: {
+ back = dk4str8_cpy_s(dstb, szdstb, src, erp);
+ } break;
+ }
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4rec21.ctr b/support/dktools/dk4rec21.ctr
new file mode 100644
index 0000000000..4fb10bde84
--- /dev/null
+++ b/support/dktools/dk4rec21.ctr
@@ -0,0 +1,110 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ String conversion from ASCII to dkChar.
+
+ CRT on Windows: Not used.
+*/
+
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from ASCII to dkChar
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of dkChar).
+ @param enc Encoding for dkChar.
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_ascii_to_dk(
+ dkChar *dstb, size_t szdstb, int enc, const char *src, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4enc.h"
+#include "dk4rec21.h"
+#include "dk4rec01.h"
+#include "dk4rec03.h"
+#include "dk4rec07.h"
+#include "dk4rec13.h"
+#include "dk4str8.h"
+
+
+
+int
+dk4recode_ascii_to_dk(
+ dkChar *dstb, size_t szdstb, int enc, const char *src, dk4_er_t *erp
+)
+{
+ int back = 0;
+ if ((NULL != dstb) && (0 < szdstb) && (NULL != src)) {
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ back = dk4recode_ascii_to_c32(dstb, szdstb, src, erp);
+#else
+ back = dk4recode_ascii_to_utf16(dstb, szdstb, src, erp);
+#endif
+#else
+ switch (enc) {
+ case DK4_ENCODING_UTF8: {
+ back = dk4recode_ascii_to_utf8(dstb, szdstb, src, erp);
+ } break;
+ case DK4_ENCODING_ANSI: {
+ back = dk4recode_ascii_to_ansi(dstb, szdstb, src, erp);
+ } break;
+ default: {
+ back = dk4str8_cpy_s(dstb, szdstb, src, erp);
+ } break;
+ }
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4rec21.h b/support/dktools/dk4rec21.h
new file mode 100644
index 0000000000..eb57aaf125
--- /dev/null
+++ b/support/dktools/dk4rec21.h
@@ -0,0 +1,99 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec21.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4REC21_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4REC21_H_INCLUDED 1
+
+
+#line 10 "dk4rec21.ctr"
+
+/** @file
+ String conversion from ASCII to dkChar.
+
+ CRT on Windows: Not used.
+*/
+
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from ASCII to dkChar
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of dkChar).
+ @param enc Encoding for dkChar.
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_ascii_to_dk(
+ dkChar *dstb, size_t szdstb, int enc, const char *src, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4rec22.c b/support/dktools/dk4rec22.c
new file mode 100644
index 0000000000..4a58644268
--- /dev/null
+++ b/support/dktools/dk4rec22.c
@@ -0,0 +1,79 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec22.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4rec22.c The dk4rec22 module.
+*/
+
+
+#line 60 "dk4rec22.ctr"
+
+#include "dk4rec22.h"
+
+#ifndef DK4STR8_H_INCLUDED
+#include "dk4str8.h"
+#endif
+
+
+
+
+
+#line 70 "dk4rec22.ctr"
+
+
+
+int
+dk4recode_char_to_dk(
+ dkChar *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+)
+{
+ int back = 0;
+ if ((NULL != dstb) && (NULL != src) && (0 < szdstb)) {
+ if (dk4str8_len(src) < szdstb) {
+ while ('\0' != *src) {
+ *(dstb++) = (dkChar)((unsigned char)(*(src++)));
+ }
+ *dstb = dkT('\0');
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
diff --git a/support/dktools/dk4rec22.ctr b/support/dktools/dk4rec22.ctr
new file mode 100644
index 0000000000..b4657abe09
--- /dev/null
+++ b/support/dktools/dk4rec22.ctr
@@ -0,0 +1,96 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Simple conversion from char to dkChar.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from ASCII (0x00 to 0x7F) to dkChar.
+ Use this function only for real ASCII source strings with characters
+ in range 0x00 to 0x7F (i.e. to convert numbers, dates, or
+ english text).
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of dkChar).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dstb or src is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the dstb buffer is too small.
+*/
+int
+dk4recode_char_to_dk(
+ dkChar *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4rec22.h"
+
+#ifndef DK4STR8_H_INCLUDED
+#include "dk4str8.h"
+#endif
+
+
+
+$!trace-include
+
+
+
+int
+dk4recode_char_to_dk(
+ dkChar *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+)
+{
+ int back = 0;
+ if ((NULL != dstb) && (NULL != src) && (0 < szdstb)) {
+ if (dk4str8_len(src) < szdstb) {
+ while ('\0' != *src) {
+ *(dstb++) = (dkChar)((unsigned char)(*(src++)));
+ }
+ *dstb = dkT('\0');
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
diff --git a/support/dktools/dk4rec22.h b/support/dktools/dk4rec22.h
new file mode 100644
index 0000000000..28f89baba1
--- /dev/null
+++ b/support/dktools/dk4rec22.h
@@ -0,0 +1,92 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec22.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4REC22_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4REC22_H_INCLUDED 1
+
+
+#line 10 "dk4rec22.ctr"
+
+/** @file
+ Simple conversion from char to dkChar.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from ASCII (0x00 to 0x7F) to dkChar.
+ Use this function only for real ASCII source strings with characters
+ in range 0x00 to 0x7F (i.e. to convert numbers, dates, or
+ english text).
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of dkChar).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dstb or src is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the dstb buffer is too small.
+*/
+int
+dk4recode_char_to_dk(
+ dkChar *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4rec23.c b/support/dktools/dk4rec23.c
new file mode 100644
index 0000000000..6c60f2c84d
--- /dev/null
+++ b/support/dktools/dk4rec23.c
@@ -0,0 +1,82 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec23.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4rec23.c The dk4rec23 module.
+*/
+
+
+#line 60 "dk4rec23.ctr"
+
+#include "dk4rec23.h"
+#include "dk4str8.h"
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+
+
+
+
+#line 74 "dk4rec23.ctr"
+
+
+int
+dk4recode_char_to_wchar_t(
+ wchar_t *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+)
+{
+ int back = 0;
+ if ((NULL != dstb) && (NULL != src) && (0 < szdstb)) {
+ *dstb = L'\0';
+ if (dk4str8_len(src) < szdstb) {
+ while ('\0' != *src) {
+ *(dstb++) = (wchar_t)((unsigned char)(*(src++)));
+ }
+ *dstb = L'\0';
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4rec23.ctr b/support/dktools/dk4rec23.ctr
new file mode 100644
index 0000000000..ffaa17c08f
--- /dev/null
+++ b/support/dktools/dk4rec23.ctr
@@ -0,0 +1,99 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Simple conversion from char to wchar_t.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from ASCII (0x00 to 0x7F) to wchar_t.
+ Use this function only for real ASCII source strings with characters
+ in range 0x00 to 0x7F (i.e. to convert numbers, dates, or
+ english text).
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of dkChar).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dstb or src is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the dstb buffer is too small.
+*/
+int
+dk4recode_char_to_wchar_t(
+ wchar_t *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4rec23.h"
+#include "dk4str8.h"
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+
+
+$!trace-include
+
+
+int
+dk4recode_char_to_wchar_t(
+ wchar_t *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+)
+{
+ int back = 0;
+ if ((NULL != dstb) && (NULL != src) && (0 < szdstb)) {
+ *dstb = L'\0';
+ if (dk4str8_len(src) < szdstb) {
+ while ('\0' != *src) {
+ *(dstb++) = (wchar_t)((unsigned char)(*(src++)));
+ }
+ *dstb = L'\0';
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4rec23.h b/support/dktools/dk4rec23.h
new file mode 100644
index 0000000000..4ffff926b6
--- /dev/null
+++ b/support/dktools/dk4rec23.h
@@ -0,0 +1,92 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec23.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4REC23_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4REC23_H_INCLUDED 1
+
+
+#line 10 "dk4rec23.ctr"
+
+/** @file
+ Simple conversion from char to wchar_t.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from ASCII (0x00 to 0x7F) to wchar_t.
+ Use this function only for real ASCII source strings with characters
+ in range 0x00 to 0x7F (i.e. to convert numbers, dates, or
+ english text).
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer (number of dkChar).
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dstb or src is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the dstb buffer is too small.
+*/
+int
+dk4recode_char_to_wchar_t(
+ wchar_t *dstb, size_t szdstb, const char *src, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4rec24.c b/support/dktools/dk4rec24.c
new file mode 100644
index 0000000000..14007e448d
--- /dev/null
+++ b/support/dktools/dk4rec24.c
@@ -0,0 +1,75 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec24.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4rec24.c The dk4rec24 module.
+*/
+
+
+#line 63 "dk4rec24.ctr"
+
+#include "dk4rec24.h"
+
+
+int
+dk4recode_wchar_t_to_char(
+ char *dstb, size_t szdstb, const wchar_t *src, dk4_er_t *erp
+)
+{
+ size_t used = 0;
+ int back = 0;
+ if ((NULL != dstb) && (NULL != src) && (0 < szdstb)) {
+ back = 1;
+ while ((L'\0' != *src) && (1 == back)) {
+ if ((wchar_t)128 > *src) {
+ dstb[used++] = (char)(*(src++));
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ back = 0;
+ }
+ }
+ if (used < szdstb) {
+ dstb[used] = '\0';
+ } else {
+ dstb[szdstb-1] = '\0';
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ back = 0;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4rec24.ctr b/support/dktools/dk4rec24.ctr
new file mode 100644
index 0000000000..c25cb0277e
--- /dev/null
+++ b/support/dktools/dk4rec24.ctr
@@ -0,0 +1,97 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Simple conversion from wchar_t to char.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from wchar_t to ASCII (0x00 to 0x7F).
+ Use this function only for real ASCII source strings with characters
+ in range 0x00 to 0x7F (i.e. to convert numbers, dates, or
+ english text).
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer.
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dstb or src is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the dstb buffer is too small,
+ - DK4_E_SYNTAX<br>
+ if the source string contains an illegal character (above 0x7F).
+*/
+int
+dk4recode_wchar_t_to_char(
+ char *dstb, size_t szdstb, const wchar_t *src, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4rec24.h"
+
+
+int
+dk4recode_wchar_t_to_char(
+ char *dstb, size_t szdstb, const wchar_t *src, dk4_er_t *erp
+)
+{
+ size_t used = 0;
+ int back = 0;
+ if ((NULL != dstb) && (NULL != src) && (0 < szdstb)) {
+ back = 1;
+ while ((L'\0' != *src) && (1 == back)) {
+ if ((wchar_t)128 > *src) {
+ dstb[used++] = (char)(*(src++));
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ back = 0;
+ }
+ }
+ if (used < szdstb) {
+ dstb[used] = '\0';
+ } else {
+ dstb[szdstb-1] = '\0';
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ back = 0;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4rec24.h b/support/dktools/dk4rec24.h
new file mode 100644
index 0000000000..8bf21a1ae5
--- /dev/null
+++ b/support/dktools/dk4rec24.h
@@ -0,0 +1,95 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec24.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4REC24_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4REC24_H_INCLUDED 1
+
+
+#line 10 "dk4rec24.ctr"
+
+/** @file
+ Simple conversion from wchar_t to char.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode string from wchar_t to ASCII (0x00 to 0x7F).
+ Use this function only for real ASCII source strings with characters
+ in range 0x00 to 0x7F (i.e. to convert numbers, dates, or
+ english text).
+ @param dstb Destination buffer.
+ @param szdstb Size of destination buffer.
+ @param src Source string to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dstb or src is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the dstb buffer is too small,
+ - DK4_E_SYNTAX<br>
+ if the source string contains an illegal character (above 0x7F).
+*/
+int
+dk4recode_wchar_t_to_char(
+ char *dstb, size_t szdstb, const wchar_t *src, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4rec25.c b/support/dktools/dk4rec25.c
new file mode 100644
index 0000000000..55d91a1569
--- /dev/null
+++ b/support/dktools/dk4rec25.c
@@ -0,0 +1,169 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec25.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4rec25.c The dk4rec25 module.
+*/
+
+
+#line 47 "dk4rec25.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4enc.h"
+#include "dk4rec.h"
+#include "dk4str8.h"
+#include "dk4strw.h"
+
+int
+dk4recode_dk_to_any(
+ void *dstb, size_t szdstb, int de, const dkChar *src, int se, dk4_er_t *erp
+)
+{
+ int back = 0;
+ if ((NULL != dstb) && (NULL != src) && (0 < szdstb)) {
+ switch (de) {
+ case DK4_ENCODING_ASCII : {
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ back = dk4recode_c32_to_ascii(dstb, szdstb, src, erp);
+#else
+ back = dk4recode_utf16_to_ascii(dstb, szdstb, src, erp);
+#endif
+#else
+ switch (se) {
+ case DK4_ENCODING_UTF8 : {
+ back = dk4recode_utf8_to_ascii(dstb, szdstb, src, erp);
+ } break;
+ case DK4_ENCODING_ANSI : {
+ back = dk4recode_ansi_to_ascii(dstb, szdstb, src, erp);
+ } break;
+ default : {
+ back = dk4str8_cpy_s(dstb, szdstb, src, erp);
+ } break;
+ }
+#endif
+ } break;
+ case DK4_ENCODING_ANSI : {
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ back = dk4recode_c32_to_ansi(dstb, szdstb, src, erp);
+#else
+ back = dk4recode_utf16_to_ansi(dstb, szdstb, src, erp);
+#endif
+#else
+ switch (se) {
+ case DK4_ENCODING_UTF8 : {
+ back = dk4recode_utf8_to_ansi(dstb, szdstb, src, erp);
+ } break;
+ case DK4_ENCODING_ANSI : {
+ back = dk4str8_cpy_s(dstb, szdstb, src, erp);
+ } break;
+ default : {
+ back = dk4recode_ascii_to_ansi(dstb, szdstb, src, erp);
+ } break;
+ }
+#endif
+ } break;
+ case DK4_ENCODING_UTF8 : {
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ back = dk4recode_c32_to_utf8(dstb, szdstb, src, erp);
+#else
+ back = dk4recode_utf16_to_utf8(dstb, szdstb, src, erp);
+#endif
+#else
+ switch (se) {
+ case DK4_ENCODING_UTF8 : {
+ back = dk4str8_cpy_s(dstb, szdstb, src, erp);
+ } break;
+ case DK4_ENCODING_ANSI : {
+ back= dk4recode_ansi_to_utf8(dstb, szdstb, src, erp);
+ } break;
+ default : {
+ back = dk4recode_ascii_to_utf8(dstb, szdstb, src, erp);
+ } break;
+ }
+#endif
+ } break;
+ case DK4_ENCODING_UTF16 : {
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ back = dk4recode_c32_to_utf16(dstb, szdstb, src, erp);
+#else
+ back = dk4strw_cpy_s(dstb, szdstb, src, erp);
+#endif
+#else
+ switch (se) {
+ case DK4_ENCODING_UTF8 : {
+ back = dk4recode_utf8_to_utf16(dstb, szdstb, src, erp);
+ } break;
+ case DK4_ENCODING_ANSI : {
+ back = dk4recode_ansi_to_utf16(dstb, szdstb, src, erp);
+ } break;
+ default : {
+ back = dk4recode_ascii_to_utf16(dstb, szdstb, src, erp);
+ } break;
+ }
+#endif
+ } break;
+ case DK4_ENCODING_32 : {
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ back = dk4strw_cpy_s(dstb, szdstb, src, erp);
+#else
+ back = dk4recode_utf16_to_c32(dstb, szdstb, src, erp);
+#endif
+#else
+ switch (se) {
+ case DK4_ENCODING_UTF8 : {
+ back = dk4recode_utf8_to_c32(dstb, szdstb, src, erp);
+ } break;
+ case DK4_ENCODING_ANSI : {
+ back = dk4recode_ansi_to_c32(dstb, szdstb, src, erp);
+ } break;
+ default : {
+ back = dk4recode_ascii_to_c32(dstb, szdstb, src, erp);
+ } break;
+ }
+#endif
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4rec25.ctr b/support/dktools/dk4rec25.ctr
new file mode 100644
index 0000000000..618649cd53
--- /dev/null
+++ b/support/dktools/dk4rec25.ctr
@@ -0,0 +1,175 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+
+%% header
+
+/** @file dk4rec25.h Conversion from dkChar to other character
+ widths.
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode a dkChar string to any encoding.
+ @param dstb Destination buffer.
+ @param szdstb Size of dstb (number of elements).
+ The element size depends on the destination encoding.
+ @param de Destination encoding.
+ @param src Source string.
+ @param se Source encoding, only used if dkChar is 8 bits wide.
+ @param erp Error report, may be NULL.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_dk_to_any(
+ void *dstb, size_t szdstb, int de, const dkChar *src, int se, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4enc.h"
+#include "dk4rec.h"
+#include "dk4str8.h"
+#include "dk4strw.h"
+
+int
+dk4recode_dk_to_any(
+ void *dstb, size_t szdstb, int de, const dkChar *src, int se, dk4_er_t *erp
+)
+{
+ int back = 0;
+ if ((NULL != dstb) && (NULL != src) && (0 < szdstb)) {
+ switch (de) {
+ case DK4_ENCODING_ASCII : {
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ back = dk4recode_c32_to_ascii(dstb, szdstb, src, erp);
+#else
+ back = dk4recode_utf16_to_ascii(dstb, szdstb, src, erp);
+#endif
+#else
+ switch (se) {
+ case DK4_ENCODING_UTF8 : {
+ back = dk4recode_utf8_to_ascii(dstb, szdstb, src, erp);
+ } break;
+ case DK4_ENCODING_ANSI : {
+ back = dk4recode_ansi_to_ascii(dstb, szdstb, src, erp);
+ } break;
+ default : {
+ back = dk4str8_cpy_s(dstb, szdstb, src, erp);
+ } break;
+ }
+#endif
+ } break;
+ case DK4_ENCODING_ANSI : {
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ back = dk4recode_c32_to_ansi(dstb, szdstb, src, erp);
+#else
+ back = dk4recode_utf16_to_ansi(dstb, szdstb, src, erp);
+#endif
+#else
+ switch (se) {
+ case DK4_ENCODING_UTF8 : {
+ back = dk4recode_utf8_to_ansi(dstb, szdstb, src, erp);
+ } break;
+ case DK4_ENCODING_ANSI : {
+ back = dk4str8_cpy_s(dstb, szdstb, src, erp);
+ } break;
+ default : {
+ back = dk4recode_ascii_to_ansi(dstb, szdstb, src, erp);
+ } break;
+ }
+#endif
+ } break;
+ case DK4_ENCODING_UTF8 : {
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ back = dk4recode_c32_to_utf8(dstb, szdstb, src, erp);
+#else
+ back = dk4recode_utf16_to_utf8(dstb, szdstb, src, erp);
+#endif
+#else
+ switch (se) {
+ case DK4_ENCODING_UTF8 : {
+ back = dk4str8_cpy_s(dstb, szdstb, src, erp);
+ } break;
+ case DK4_ENCODING_ANSI : {
+ back= dk4recode_ansi_to_utf8(dstb, szdstb, src, erp);
+ } break;
+ default : {
+ back = dk4recode_ascii_to_utf8(dstb, szdstb, src, erp);
+ } break;
+ }
+#endif
+ } break;
+ case DK4_ENCODING_UTF16 : {
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ back = dk4recode_c32_to_utf16(dstb, szdstb, src, erp);
+#else
+ back = dk4strw_cpy_s(dstb, szdstb, src, erp);
+#endif
+#else
+ switch (se) {
+ case DK4_ENCODING_UTF8 : {
+ back = dk4recode_utf8_to_utf16(dstb, szdstb, src, erp);
+ } break;
+ case DK4_ENCODING_ANSI : {
+ back = dk4recode_ansi_to_utf16(dstb, szdstb, src, erp);
+ } break;
+ default : {
+ back = dk4recode_ascii_to_utf16(dstb, szdstb, src, erp);
+ } break;
+ }
+#endif
+ } break;
+ case DK4_ENCODING_32 : {
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ back = dk4strw_cpy_s(dstb, szdstb, src, erp);
+#else
+ back = dk4recode_utf16_to_c32(dstb, szdstb, src, erp);
+#endif
+#else
+ switch (se) {
+ case DK4_ENCODING_UTF8 : {
+ back = dk4recode_utf8_to_c32(dstb, szdstb, src, erp);
+ } break;
+ case DK4_ENCODING_ANSI : {
+ back = dk4recode_ansi_to_c32(dstb, szdstb, src, erp);
+ } break;
+ default : {
+ back = dk4recode_ascii_to_c32(dstb, szdstb, src, erp);
+ } break;
+ }
+#endif
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4rec25.h b/support/dktools/dk4rec25.h
new file mode 100644
index 0000000000..84a980c72b
--- /dev/null
+++ b/support/dktools/dk4rec25.h
@@ -0,0 +1,80 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rec25.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4REC25_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4REC25_H_INCLUDED 1
+
+
+#line 9 "dk4rec25.ctr"
+
+/** @file dk4rec25.h Conversion from dkChar to other character
+ widths.
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Recode a dkChar string to any encoding.
+ @param dstb Destination buffer.
+ @param szdstb Size of dstb (number of elements).
+ The element size depends on the destination encoding.
+ @param de Destination encoding.
+ @param src Source string.
+ @param se Source encoding, only used if dkChar is 8 bits wide.
+ @param erp Error report, may be NULL.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src or dstb is NULL or szdstb is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if dstb is too small,
+ - DK4_E_SYNTAX<br>
+ with the number of successfully recoded characters in nelem if a
+ non-recodable character was found.
+*/
+int
+dk4recode_dk_to_any(
+ void *dstb, size_t szdstb, int de, const dkChar *src, int se, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4recwx.cpp b/support/dktools/dk4recwx.cpp
new file mode 100644
index 0000000000..f50fec753f
--- /dev/null
+++ b/support/dktools/dk4recwx.cpp
@@ -0,0 +1,471 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4recwx.cpt
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4recwx.cpp The dk4recwx module.
+*/
+
+
+#line 159 "dk4recwx.cpt"
+
+#include "dk4recwx.h"
+#include "dk4rec.h"
+#include "dk4enc.h"
+
+
+
+
+
+#line 167 "dk4recwx.cpt"
+
+
+
+int
+dk4recwx_dkchar_to_wxchar(
+ wxChar *dptr,
+ size_t dsz,
+ int de,
+ const dkChar *sptr,
+ int se,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+ if ((NULL != dptr) && (NULL != sptr) && (0 < dsz)) {
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR > 2
+ /* +++++ wxChar=4 */
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ /* +++++ wxChar=4 dkChar=4 */
+ back = dk4str_cpy_s((dkChar *)dptr, dsz, sptr, erp);
+ /* ----- wxChar=4 dkChar=4 */
+#else
+ /* +++++ wxChar=4 dkChar=2 */
+ back = dk4recode_utf16_to_c32((dk4_c32_t *)dptr, dsz, (dk4_c16_t *)sptr, erp);
+ /* ----- wxChar=4 dkChar=2 */
+#endif
+#else
+ /* +++++ wxChar=4 dkChar=1 */
+ switch (se) {
+ case DK4_ENCODING_UTF8 : {
+ back = dk4recode_utf8_to_c32((dk4_c32_t *)dptr, dsz, sptr, erp);
+ } break;
+ case DK4_ENCODING_ANSI : {
+ back = dk4recode_ansi_to_c32((dk4_c32_t *)dptr, dsz, sptr, erp);
+ } break;
+ default : { /* ASCII */
+ back = dk4recode_ascii_to_c32((dk4_c32_t *)dptr, dsz, sptr, erp);
+ } break;
+ }
+ /* ----- wxChar=4 dkChar=1 */
+#endif
+
+ /* ----- wxChar=4 */
+#else
+ /* +++++ wxChar=2 */
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ /* +++++ wxChar=2 dkChar=4 */
+ back = dk4recode_c32_to_utf16((dk4_c16_t *)dptr, dsz, (dk4_c32_t *)sptr, erp);
+ /* ----- wxChar=2 dkChar=4 */
+#else
+ /* +++++ wxChar=2 dkChar=2 */
+ back = dk4str_cpy_s((dkChar *)dptr, dsz, sptr, erp);
+ /* ----- wxChar=2 dkChar=2 */
+#endif
+#else
+ /* +++++ wxChar=2 dkChar=1 */
+ switch (se) {
+ case DK4_ENCODING_UTF8 : {
+ back = dk4recode_utf8_to_utf16((dk4_c16_t *)dptr, dsz, sptr, erp);
+ } break;
+ case DK4_ENCODING_ANSI : {
+ back = dk4recode_ansi_to_utf16((dk4_c16_t *)dptr, dsz, sptr, erp);
+ } break;
+ default : { /* ASCII */
+ back = dk4recode_ascii_to_utf16((dk4_c16_t *)dptr, dsz, sptr, erp);
+ } break;
+ }
+ /* ----- wxChar=2 dkChar=1 */
+#endif
+
+ /* ----- wxChar=2 */
+#endif
+#else
+ /* +++++ wxChar=1 */
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ /* +++++ wxChar=1 dkChar=4 */
+ switch (de) {
+ case DK4_ENCODING_UTF8 : {
+ back = dk4recode_c32_to_utf8(dptr, dsz, (dk4_c32_t *)sptr, erp);
+ } break;
+ case DK4_ENCODING_ANSI : {
+ back = dk4recode_c32_to_ansi(dptr, dsz, (dk4_c32_t *)sptr, erp);
+ } break;
+ default : { /* ASCII */
+ back = dk4recode_c32_to_ascii(dptr, dsz, (dk4_c32_t *)sptr, erp);
+ } break;
+ }
+ /* ----- wxChar=1 dkChar=4 */
+#else
+ /* +++++ wxChar=1 dkChar=2 */
+ switch (de) {
+ case DK4_ENCODING_UTF8 : {
+ back = dk4recode_utf16_to_utf8(dptr, dsz, (dk4_c16_t *)sptr, erp);
+ } break;
+ case DK4_ENCODING_ANSI : {
+ back = dk4recode_utf16_to_ansi(dptr, dsz, (dk4_c16_t *)sptr, erp);
+ } break;
+ default : { /* ASCII */
+ back = dk4recode_utf16_to_ascii(dptr, dsz, (dk4_c16_t *)sptr, erp);
+ } break;
+ }
+ /* ----- wxChar=1 dkChar=2 */
+#endif
+#else
+ /* +++++ wxChar=1 dkChar=1 */
+ back = dk4str_cpy_s(dptr, dsz, sptr, erp);
+ /* ----- wxChar=1 dkChar=1 */
+#endif
+
+ /* ----- wxChar=1 */
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4recwx_wxchar_to_dkchar(
+ dkChar *dptr,
+ size_t dsz,
+ int de,
+ const wxChar *sptr,
+ int se,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+
+
+#line 305 "dk4recwx.cpt"
+ if ((NULL != dptr) && (NULL != sptr) && (0 < dsz)) {
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR > 2
+ /* +++++ wxChar=4 */
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ /* +++++ wxChar=4 dkChar=4 */
+
+
+#line 314 "dk4recwx.cpt"
+ back = dk4str_cpy_s(dptr, dsz, (dkChar *)sptr, erp);
+ /* ----- wxChar=4 dkChar=4 */
+#else
+ /* +++++ wxChar=4 dkChar=2 */
+
+
+#line 319 "dk4recwx.cpt"
+ back = dk4recode_c32_to_utf16((dk4_c16_t *)dptr, dsz, (dk4_c32_t *)sptr, erp);
+ /* ----- wxChar=4 dkChar=2 */
+#endif
+#else
+ /* +++++ wxChar=4 dkChar=1 */
+
+
+#line 325 "dk4recwx.cpt"
+ switch (de) {
+ case DK4_ENCODING_UTF8 : {
+
+
+#line 328 "dk4recwx.cpt"
+ back = dk4recode_c32_to_utf8(dptr, dsz, (dk4_c32_t *)sptr, erp);
+ } break;
+ case DK4_ENCODING_ANSI : {
+
+
+#line 332 "dk4recwx.cpt"
+ back = dk4recode_c32_to_ansi(dptr, dsz, (dk4_c32_t *)sptr, erp);
+ } break;
+ default : { /* ASCII */
+
+
+#line 336 "dk4recwx.cpt"
+ back = dk4recode_c32_to_ascii(dptr, dsz, (dk4_c32_t *)sptr, erp);
+ } break;
+ }
+ /* ----- wxChar=4 dkChar=1 */
+#endif
+
+ /* ----- wxChar=4 */
+#else
+ /* +++++ wxChar=2 */
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ /* +++++ wxChar=2 dkChar=4 */
+
+
+#line 350 "dk4recwx.cpt"
+ back = dk4recode_utf16_to_c32((dk4_c32_t *)dptr, dsz, (dk4_c16_t *)sptr, erp);
+ /* ----- wxChar=2 dkChar=4 */
+#else
+ /* +++++ wxChar=2 dkChar=2 */
+
+
+#line 355 "dk4recwx.cpt"
+ back = dk4str_cpy_s(dptr, dsz, (dkChar *)sptr, erp);
+ /* ----- wxChar=2 dkChar=2 */
+#endif
+#else
+ /* +++++ wxChar=2 dkChar=1 */
+
+
+#line 361 "dk4recwx.cpt"
+ switch (de) {
+ case DK4_ENCODING_UTF8 : {
+
+
+#line 364 "dk4recwx.cpt"
+ back = dk4recode_utf16_to_utf8(dptr, dsz, (dk4_c16_t *)sptr, erp);
+ } break;
+ case DK4_ENCODING_ANSI : {
+
+
+#line 368 "dk4recwx.cpt"
+ back = dk4recode_utf16_to_ansi(dptr, dsz, (dk4_c16_t *)sptr, erp);
+ } break;
+ default : { /* ASCII */
+
+
+#line 372 "dk4recwx.cpt"
+ back = dk4recode_utf16_to_ascii(dptr, dsz, (dk4_c16_t *)sptr, erp);
+ } break;
+ }
+ /* ----- wxChar=2 dkChar=1 */
+#endif
+
+ /* ----- wxChar=2 */
+#endif
+#else
+ /* +++++ wxChar=1 */
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ /* +++++ wxChar=1 dkChar=4 */
+
+
+#line 387 "dk4recwx.cpt"
+ switch (se) {
+ case DK4_ENCODING_UTF8 : {
+
+
+#line 390 "dk4recwx.cpt"
+ back = dk4recode_utf8_to_c32((dk4_c32_t *)dptr, dsz, sptr, erp);
+ } break;
+ case DK4_ENCODING_ANSI : {
+
+
+#line 394 "dk4recwx.cpt"
+ back = dk4recode_ansi_to_c32((dk4_c32_t *)dptr, dsz, sptr, erp);
+ } break;
+ default : { /* ASCII */
+
+
+#line 398 "dk4recwx.cpt"
+ back = dk4recode_ascii_to_c32((dk4_c32_t *)dptr, dsz, sptr, erp);
+ } break;
+ }
+ /* ----- wxChar=1 dkChar=4 */
+#else
+ /* +++++ wxChar=1 dkChar=2 */
+
+
+#line 405 "dk4recwx.cpt"
+ switch (se) {
+ case DK4_ENCODING_UTF8 : {
+
+
+#line 408 "dk4recwx.cpt"
+ back = dk4recode_utf8_to_utf16((dk4_c16_t *)dptr, dsz, sptr, erp);
+ } break;
+ case DK4_ENCODING_ANSI : {
+
+
+#line 412 "dk4recwx.cpt"
+ back = dk4recode_ansi_to_utf16((dk4_c16_t *)dptr, dsz, sptr, erp);
+ } break;
+ default : { /* ASCII */
+
+
+#line 416 "dk4recwx.cpt"
+ back = dk4recode_ascii_to_utf16((dk4_c16_t *)dptr, dsz, sptr, erp);
+ } break;
+ }
+ /* ----- wxChar=1 dkChar=2 */
+#endif
+#else
+ /* +++++ wxChar=1 dkChar=1 */
+
+
+#line 424 "dk4recwx.cpt"
+ back = dk4str8_cpy_s(dptr, dsz, sptr, erp);
+ /* ----- wxChar=1 dkChar=1 */
+#endif
+
+ /* ----- wxChar=1 */
+#endif
+ } else {
+
+#line 431 "dk4recwx.cpt"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 434 "dk4recwx.cpt"
+ return back;
+}
+
+
+
+int
+dk4recwx_wxchar_to_char(
+ char *dptr,
+ size_t dsz,
+ int de,
+ const wxChar *sptr,
+ int se,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+ if ((NULL != dptr) && (NULL != sptr) && (0 < dsz)) {
+ switch (de) {
+ case DK4_ENCODING_UTF8 : {
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR > 2
+ /* +++ wxChar 4 +++ */
+ back = dk4recode_c32_to_utf8(dptr, dsz, (const dk4_c32_t *)sptr, erp);
+ /* --- wxChar 4 --- */
+#else
+ /* +++ wxChar 2 +++ */
+ back = dk4recode_utf16_to_utf8(dptr, dsz, (const dk4_c16_t *)sptr, erp);
+ /* --- wxChar 2 --- */
+#endif
+#else
+ /* +++ wxChar 1 +++ */
+ switch (se) {
+ case DK4_ENCODING_UTF8 : {
+ back = dk4str8_cpy_s(dptr, dsz, sptr, erp);
+ } break;
+ case DK4_ENCODING_ANSI : {
+ back = dk4recode_ansi_to_utf8(dptr, dsz, sptr, erp);
+ } break;
+ default : {
+ back = dk4recode_ascii_to_utf8(dptr, dsz, sptr, erp);
+ } break;
+ }
+ /* --- wxChar 1 --- */
+#endif
+ } break;
+ case DK4_ENCODING_ANSI : {
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR > 2
+ /* +++ wxChar 4 +++ */
+ back = dk4recode_c32_to_ansi(dptr, dsz, (const dk4_c32_t *)sptr, erp);
+ /* --- wxChar 4 --- */
+#else
+ /* +++ wxChar 2 +++ */
+ back = dk4recode_utf16_to_ansi(dptr, dsz, (const dk4_c16_t *)sptr, erp);
+ /* --- wxChar 2 --- */
+#endif
+#else
+ /* +++ wxChar 1 +++ */
+ switch (se) {
+ case DK4_ENCODING_UTF8 : {
+ back = dk4recode_utf8_to_ansi(dptr, dsz, sptr, erp);
+ } break;
+ case DK4_ENCODING_ANSI : {
+ back = dk4str8_cpy_s(dptr, dsz, sptr, erp);
+ } break;
+ default : {
+ back = dk4recode_ascii_to_ansi(dptr, dsz, sptr, erp);
+ } break;
+ }
+ /* --- wxChar 1 --- */
+#endif
+ } break;
+ default : {
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR > 2
+ /* +++ wxChar 4 +++ */
+ back = dk4recode_c32_to_ascii(dptr, dsz, (const dk4_c32_t *)sptr, erp);
+ /* --- wxChar 4 --- */
+#else
+ /* +++ wxChar 2 +++ */
+ back = dk4recode_utf16_to_ascii(dptr,dsz,(const dk4_c16_t *)sptr,erp);
+ /* --- wxChar 2 --- */
+#endif
+#else
+ /* +++ wxChar 1 +++ */
+ switch (se) {
+ case DK4_ENCODING_UTF8 : {
+ back = dk4recode_utf8_to_ascii(dptr, dsz, sptr, erp);
+ } break;
+ case DK4_ENCODING_ANSI : {
+ back = dk4recode_ansi_to_ascii(dptr, dsz, sptr, erp);
+ } break;
+ default : {
+ back = dk4str8_cpy_s(dptr, dsz, sptr, erp);
+ } break;
+ }
+ /* --- wxChar 1 --- */
+#endif
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4recwx.cpt b/support/dktools/dk4recwx.cpt
new file mode 100644
index 0000000000..75f0378638
--- /dev/null
+++ b/support/dktools/dk4recwx.cpt
@@ -0,0 +1,539 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk4recwx.h Recoding with wxChar.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4CONST_H_INCLUDED
+#include "dk4const.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4WXCS_H_INCLUDED
+#include "dk4wxcs.h"
+#endif
+
+#if DK4_SIZEOF_WXCHAR == DK4_CHAR_SIZE
+#ifndef DK4STRD_H_INCLUDED
+#include "dk4strd.h"
+#endif
+#endif
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert dkChar string to wxChar.
+ @param dptr Destination buffer pointer.
+ @param dsz Size of destination buffer (number of wxChar).
+ @param de Encoding for wxChar strings.
+ @param sptr Source string pointer.
+ @param se Source string encoding.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or sptr is NULL or dsz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the destination buffer is too small,
+ - DK4_E_SYNTAX<br>
+ if the source string can not be decoded properly.
+*/
+int
+dk4recwx_dkchar_to_wxchar(
+ wxChar *dptr,
+ size_t dsz,
+ int de,
+ const dkChar *sptr,
+ int se,
+ dk4_er_t *erp
+);
+
+/** Convert wxChar string to dkChar.
+ @param dptr Destination buffer pointer.
+ @param dsz Size of destination buffer (number of dkChar).
+ @param de Encoding for dkChar strings.
+ @param sptr Source string pointer.
+ @param se Source string encoding.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or sptr is NULL or dsz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the destination buffer is too small,
+ - DK4_E_SYNTAX<br>
+ if the source string can not be decoded properly.
+*/
+int
+dk4recwx_wxchar_to_dkchar(
+ dkChar *dptr,
+ size_t dsz,
+ int de,
+ const wxChar *sptr,
+ int se,
+ dk4_er_t *erp
+);
+
+/** Convert wxChar string to char.
+ @param dptr Destination buffer pointer.
+ @param dsz Size of destination buffer.
+ @param de Encoding for char strings.
+ @param sptr Source string pointer.
+ @param se Source string encoding.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or sptr is NULL or dsz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the destination buffer is too small,
+ - DK4_E_SYNTAX<br>
+ if the source string can not be decoded properly.
+*/
+int
+dk4recwx_wxchar_to_char(
+ char *dptr,
+ size_t dsz,
+ int de,
+ const wxChar *sptr,
+ int se,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4recwx.h"
+#include "dk4rec.h"
+#include "dk4enc.h"
+
+
+
+$!trace-include
+
+
+
+int
+dk4recwx_dkchar_to_wxchar(
+ wxChar *dptr,
+ size_t dsz,
+ int de,
+ const dkChar *sptr,
+ int se,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+ if ((NULL != dptr) && (NULL != sptr) && (0 < dsz)) {
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR > 2
+ /* +++++ wxChar=4 */
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ /* +++++ wxChar=4 dkChar=4 */
+ back = dk4str_cpy_s((dkChar *)dptr, dsz, sptr, erp);
+ /* ----- wxChar=4 dkChar=4 */
+#else
+ /* +++++ wxChar=4 dkChar=2 */
+ back = dk4recode_utf16_to_c32((dk4_c32_t *)dptr, dsz, (dk4_c16_t *)sptr, erp);
+ /* ----- wxChar=4 dkChar=2 */
+#endif
+#else
+ /* +++++ wxChar=4 dkChar=1 */
+ switch (se) {
+ case DK4_ENCODING_UTF8 : {
+ back = dk4recode_utf8_to_c32((dk4_c32_t *)dptr, dsz, sptr, erp);
+ } break;
+ case DK4_ENCODING_ANSI : {
+ back = dk4recode_ansi_to_c32((dk4_c32_t *)dptr, dsz, sptr, erp);
+ } break;
+ default : { /* ASCII */
+ back = dk4recode_ascii_to_c32((dk4_c32_t *)dptr, dsz, sptr, erp);
+ } break;
+ }
+ /* ----- wxChar=4 dkChar=1 */
+#endif
+
+ /* ----- wxChar=4 */
+#else
+ /* +++++ wxChar=2 */
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ /* +++++ wxChar=2 dkChar=4 */
+ back = dk4recode_c32_to_utf16((dk4_c16_t *)dptr, dsz, (dk4_c32_t *)sptr, erp);
+ /* ----- wxChar=2 dkChar=4 */
+#else
+ /* +++++ wxChar=2 dkChar=2 */
+ back = dk4str_cpy_s((dkChar *)dptr, dsz, sptr, erp);
+ /* ----- wxChar=2 dkChar=2 */
+#endif
+#else
+ /* +++++ wxChar=2 dkChar=1 */
+ switch (se) {
+ case DK4_ENCODING_UTF8 : {
+ back = dk4recode_utf8_to_utf16((dk4_c16_t *)dptr, dsz, sptr, erp);
+ } break;
+ case DK4_ENCODING_ANSI : {
+ back = dk4recode_ansi_to_utf16((dk4_c16_t *)dptr, dsz, sptr, erp);
+ } break;
+ default : { /* ASCII */
+ back = dk4recode_ascii_to_utf16((dk4_c16_t *)dptr, dsz, sptr, erp);
+ } break;
+ }
+ /* ----- wxChar=2 dkChar=1 */
+#endif
+
+ /* ----- wxChar=2 */
+#endif
+#else
+ /* +++++ wxChar=1 */
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ /* +++++ wxChar=1 dkChar=4 */
+ switch (de) {
+ case DK4_ENCODING_UTF8 : {
+ back = dk4recode_c32_to_utf8(dptr, dsz, (dk4_c32_t *)sptr, erp);
+ } break;
+ case DK4_ENCODING_ANSI : {
+ back = dk4recode_c32_to_ansi(dptr, dsz, (dk4_c32_t *)sptr, erp);
+ } break;
+ default : { /* ASCII */
+ back = dk4recode_c32_to_ascii(dptr, dsz, (dk4_c32_t *)sptr, erp);
+ } break;
+ }
+ /* ----- wxChar=1 dkChar=4 */
+#else
+ /* +++++ wxChar=1 dkChar=2 */
+ switch (de) {
+ case DK4_ENCODING_UTF8 : {
+ back = dk4recode_utf16_to_utf8(dptr, dsz, (dk4_c16_t *)sptr, erp);
+ } break;
+ case DK4_ENCODING_ANSI : {
+ back = dk4recode_utf16_to_ansi(dptr, dsz, (dk4_c16_t *)sptr, erp);
+ } break;
+ default : { /* ASCII */
+ back = dk4recode_utf16_to_ascii(dptr, dsz, (dk4_c16_t *)sptr, erp);
+ } break;
+ }
+ /* ----- wxChar=1 dkChar=2 */
+#endif
+#else
+ /* +++++ wxChar=1 dkChar=1 */
+ back = dk4str_cpy_s(dptr, dsz, sptr, erp);
+ /* ----- wxChar=1 dkChar=1 */
+#endif
+
+ /* ----- wxChar=1 */
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4recwx_wxchar_to_dkchar(
+ dkChar *dptr,
+ size_t dsz,
+ int de,
+ const wxChar *sptr,
+ int se,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+ $? "+ dk4recwx_wxchar_to_dkchar"
+ if ((NULL != dptr) && (NULL != sptr) && (0 < dsz)) {
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR > 2
+ /* +++++ wxChar=4 */
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ /* +++++ wxChar=4 dkChar=4 */
+ $? ". wx=4 dk=4"
+ back = dk4str_cpy_s(dptr, dsz, (dkChar *)sptr, erp);
+ /* ----- wxChar=4 dkChar=4 */
+#else
+ /* +++++ wxChar=4 dkChar=2 */
+ $? ". wx=4 dk=2"
+ back = dk4recode_c32_to_utf16((dk4_c16_t *)dptr, dsz, (dk4_c32_t *)sptr, erp);
+ /* ----- wxChar=4 dkChar=2 */
+#endif
+#else
+ /* +++++ wxChar=4 dkChar=1 */
+ $? ". wx=4 dk=1"
+ switch (de) {
+ case DK4_ENCODING_UTF8 : {
+ $? ". dk utf-8"
+ back = dk4recode_c32_to_utf8(dptr, dsz, (dk4_c32_t *)sptr, erp);
+ } break;
+ case DK4_ENCODING_ANSI : {
+ $? ". dk ansi"
+ back = dk4recode_c32_to_ansi(dptr, dsz, (dk4_c32_t *)sptr, erp);
+ } break;
+ default : { /* ASCII */
+ $? ". dk ascii"
+ back = dk4recode_c32_to_ascii(dptr, dsz, (dk4_c32_t *)sptr, erp);
+ } break;
+ }
+ /* ----- wxChar=4 dkChar=1 */
+#endif
+
+ /* ----- wxChar=4 */
+#else
+ /* +++++ wxChar=2 */
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ /* +++++ wxChar=2 dkChar=4 */
+ $? ". wx=2 dk=4"
+ back = dk4recode_utf16_to_c32((dk4_c32_t *)dptr, dsz, (dk4_c16_t *)sptr, erp);
+ /* ----- wxChar=2 dkChar=4 */
+#else
+ /* +++++ wxChar=2 dkChar=2 */
+ $? ". wx=2 dk=2"
+ back = dk4str_cpy_s(dptr, dsz, (dkChar *)sptr, erp);
+ /* ----- wxChar=2 dkChar=2 */
+#endif
+#else
+ /* +++++ wxChar=2 dkChar=1 */
+ $? ". wx=2 dk=1"
+ switch (de) {
+ case DK4_ENCODING_UTF8 : {
+ $? ". dk utf-8"
+ back = dk4recode_utf16_to_utf8(dptr, dsz, (dk4_c16_t *)sptr, erp);
+ } break;
+ case DK4_ENCODING_ANSI : {
+ $? ". dk ansi"
+ back = dk4recode_utf16_to_ansi(dptr, dsz, (dk4_c16_t *)sptr, erp);
+ } break;
+ default : { /* ASCII */
+ $? ". dk ascii"
+ back = dk4recode_utf16_to_ascii(dptr, dsz, (dk4_c16_t *)sptr, erp);
+ } break;
+ }
+ /* ----- wxChar=2 dkChar=1 */
+#endif
+
+ /* ----- wxChar=2 */
+#endif
+#else
+ /* +++++ wxChar=1 */
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ /* +++++ wxChar=1 dkChar=4 */
+ $? ". wx=1 dk=4"
+ switch (se) {
+ case DK4_ENCODING_UTF8 : {
+ $? ". wx utf-8"
+ back = dk4recode_utf8_to_c32((dk4_c32_t *)dptr, dsz, sptr, erp);
+ } break;
+ case DK4_ENCODING_ANSI : {
+ $? ". wx ansi"
+ back = dk4recode_ansi_to_c32((dk4_c32_t *)dptr, dsz, sptr, erp);
+ } break;
+ default : { /* ASCII */
+ $? ". wx ascii"
+ back = dk4recode_ascii_to_c32((dk4_c32_t *)dptr, dsz, sptr, erp);
+ } break;
+ }
+ /* ----- wxChar=1 dkChar=4 */
+#else
+ /* +++++ wxChar=1 dkChar=2 */
+ $? ". wx=1 dk=2"
+ switch (se) {
+ case DK4_ENCODING_UTF8 : {
+ $? ". wx utf-8"
+ back = dk4recode_utf8_to_utf16((dk4_c16_t *)dptr, dsz, sptr, erp);
+ } break;
+ case DK4_ENCODING_ANSI : {
+ $? ". wx ansi"
+ back = dk4recode_ansi_to_utf16((dk4_c16_t *)dptr, dsz, sptr, erp);
+ } break;
+ default : { /* ASCII */
+ $? ". wx ascii"
+ back = dk4recode_ascii_to_utf16((dk4_c16_t *)dptr, dsz, sptr, erp);
+ } break;
+ }
+ /* ----- wxChar=1 dkChar=2 */
+#endif
+#else
+ /* +++++ wxChar=1 dkChar=1 */
+ $? ". wx=1 dk=1"
+ back = dk4str8_cpy_s(dptr, dsz, sptr, erp);
+ /* ----- wxChar=1 dkChar=1 */
+#endif
+
+ /* ----- wxChar=1 */
+#endif
+ } else { $? "! invalid arguments"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4recwx_wxchar_to_dkchar %d", back
+ return back;
+}
+
+
+
+int
+dk4recwx_wxchar_to_char(
+ char *dptr,
+ size_t dsz,
+ int de,
+ const wxChar *sptr,
+ int se,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+ if ((NULL != dptr) && (NULL != sptr) && (0 < dsz)) {
+ switch (de) {
+ case DK4_ENCODING_UTF8 : {
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR > 2
+ /* +++ wxChar 4 +++ */
+ back = dk4recode_c32_to_utf8(dptr, dsz, (const dk4_c32_t *)sptr, erp);
+ /* --- wxChar 4 --- */
+#else
+ /* +++ wxChar 2 +++ */
+ back = dk4recode_utf16_to_utf8(dptr, dsz, (const dk4_c16_t *)sptr, erp);
+ /* --- wxChar 2 --- */
+#endif
+#else
+ /* +++ wxChar 1 +++ */
+ switch (se) {
+ case DK4_ENCODING_UTF8 : {
+ back = dk4str8_cpy_s(dptr, dsz, sptr, erp);
+ } break;
+ case DK4_ENCODING_ANSI : {
+ back = dk4recode_ansi_to_utf8(dptr, dsz, sptr, erp);
+ } break;
+ default : {
+ back = dk4recode_ascii_to_utf8(dptr, dsz, sptr, erp);
+ } break;
+ }
+ /* --- wxChar 1 --- */
+#endif
+ } break;
+ case DK4_ENCODING_ANSI : {
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR > 2
+ /* +++ wxChar 4 +++ */
+ back = dk4recode_c32_to_ansi(dptr, dsz, (const dk4_c32_t *)sptr, erp);
+ /* --- wxChar 4 --- */
+#else
+ /* +++ wxChar 2 +++ */
+ back = dk4recode_utf16_to_ansi(dptr, dsz, (const dk4_c16_t *)sptr, erp);
+ /* --- wxChar 2 --- */
+#endif
+#else
+ /* +++ wxChar 1 +++ */
+ switch (se) {
+ case DK4_ENCODING_UTF8 : {
+ back = dk4recode_utf8_to_ansi(dptr, dsz, sptr, erp);
+ } break;
+ case DK4_ENCODING_ANSI : {
+ back = dk4str8_cpy_s(dptr, dsz, sptr, erp);
+ } break;
+ default : {
+ back = dk4recode_ascii_to_ansi(dptr, dsz, sptr, erp);
+ } break;
+ }
+ /* --- wxChar 1 --- */
+#endif
+ } break;
+ default : {
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR > 2
+ /* +++ wxChar 4 +++ */
+ back = dk4recode_c32_to_ascii(dptr, dsz, (const dk4_c32_t *)sptr, erp);
+ /* --- wxChar 4 --- */
+#else
+ /* +++ wxChar 2 +++ */
+ back = dk4recode_utf16_to_ascii(dptr,dsz,(const dk4_c16_t *)sptr,erp);
+ /* --- wxChar 2 --- */
+#endif
+#else
+ /* +++ wxChar 1 +++ */
+ switch (se) {
+ case DK4_ENCODING_UTF8 : {
+ back = dk4recode_utf8_to_ascii(dptr, dsz, sptr, erp);
+ } break;
+ case DK4_ENCODING_ANSI : {
+ back = dk4recode_ansi_to_ascii(dptr, dsz, sptr, erp);
+ } break;
+ default : {
+ back = dk4str8_cpy_s(dptr, dsz, sptr, erp);
+ } break;
+ }
+ /* --- wxChar 1 --- */
+#endif
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4recwx.h b/support/dktools/dk4recwx.h
new file mode 100644
index 0000000000..ab3e877d5b
--- /dev/null
+++ b/support/dktools/dk4recwx.h
@@ -0,0 +1,191 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4recwx.cpt
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4RECWX_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4RECWX_H_INCLUDED 1
+
+
+#line 10 "dk4recwx.cpt"
+
+/** @file dk4recwx.h Recoding with wxChar.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4CONST_H_INCLUDED
+#include "dk4const.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4WXCS_H_INCLUDED
+#include "dk4wxcs.h"
+#endif
+
+#if DK4_SIZEOF_WXCHAR == DK4_CHAR_SIZE
+#ifndef DK4STRD_H_INCLUDED
+#include "dk4strd.h"
+#endif
+#endif
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert dkChar string to wxChar.
+ @param dptr Destination buffer pointer.
+ @param dsz Size of destination buffer (number of wxChar).
+ @param de Encoding for wxChar strings.
+ @param sptr Source string pointer.
+ @param se Source string encoding.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or sptr is NULL or dsz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the destination buffer is too small,
+ - DK4_E_SYNTAX<br>
+ if the source string can not be decoded properly.
+*/
+int
+dk4recwx_dkchar_to_wxchar(
+ wxChar *dptr,
+ size_t dsz,
+ int de,
+ const dkChar *sptr,
+ int se,
+ dk4_er_t *erp
+);
+
+/** Convert wxChar string to dkChar.
+ @param dptr Destination buffer pointer.
+ @param dsz Size of destination buffer (number of dkChar).
+ @param de Encoding for dkChar strings.
+ @param sptr Source string pointer.
+ @param se Source string encoding.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or sptr is NULL or dsz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the destination buffer is too small,
+ - DK4_E_SYNTAX<br>
+ if the source string can not be decoded properly.
+*/
+int
+dk4recwx_wxchar_to_dkchar(
+ dkChar *dptr,
+ size_t dsz,
+ int de,
+ const wxChar *sptr,
+ int se,
+ dk4_er_t *erp
+);
+
+/** Convert wxChar string to char.
+ @param dptr Destination buffer pointer.
+ @param dsz Size of destination buffer.
+ @param de Encoding for char strings.
+ @param sptr Source string pointer.
+ @param se Source string encoding.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or sptr is NULL or dsz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the destination buffer is too small,
+ - DK4_E_SYNTAX<br>
+ if the source string can not be decoded properly.
+*/
+int
+dk4recwx_wxchar_to_char(
+ char *dptr,
+ size_t dsz,
+ int de,
+ const wxChar *sptr,
+ int se,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4rld.c b/support/dktools/dk4rld.c
new file mode 100644
index 0000000000..c1d3756088
--- /dev/null
+++ b/support/dktools/dk4rld.c
@@ -0,0 +1,212 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rld.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4rld.c The dk4rld module.
+*/
+
+
+#line 121 "dk4rld.ctr"
+
+#include "dk4rld.h"
+#include "dk4edstm.h"
+#include "dk4mem.h"
+
+
+
+
+
+#line 129 "dk4rld.ctr"
+
+
+
+/** Decoder states.
+*/
+enum {
+ /** Start state, exepect run length
+ or literal data length.
+ */
+ RLD_ST_EXPECT_KEY_BYTE = 0,
+
+ /** Expect byte value for run.
+ */
+ RLD_ST_EXPECT_RUN_BYTE ,
+
+ /** Expect literal byte.
+ */
+ RLD_ST_EXPECT_LITERAL_BYTE ,
+
+ /** No further input accepted as
+ EOD marker was found.
+ */
+ RLD_ST_EOD_FOUND
+};
+
+
+
+void
+dk4rld_init(dk4_rl_dec_t *dec, dk4_er_t *erp)
+{
+
+
+#line 160 "dk4rld.ctr"
+ if (NULL != dec) {
+ DK4_MEMRES(dec, sizeof(dk4_rl_dec_t));
+ dec->oused = 0;
+ dec->ll = 0;
+ dec->st = RLD_ST_EXPECT_KEY_BYTE;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 168 "dk4rld.ctr"
+}
+
+
+
+int
+dk4rld_add(dk4_rl_dec_t *dec, unsigned char inbyte, dk4_er_t *erp)
+{
+ int back = DK4_EDSTM_ERROR;
+
+
+#line 177 "dk4rld.ctr"
+ if (NULL != dec) {
+ switch (dec->st) {
+ case RLD_ST_EXPECT_KEY_BYTE : {
+ if ((unsigned char)128 > inbyte) {
+ /*
+ Literal byte sequence
+ */
+ dec->st = RLD_ST_EXPECT_LITERAL_BYTE;
+ dec->ll = (size_t)inbyte + 1;
+ back = DK4_EDSTM_ACCEPT;
+ } else {
+ if ((unsigned char)128 < inbyte) {
+ /*
+ Run of equal bytes
+ */
+ dec->st = RLD_ST_EXPECT_RUN_BYTE;
+ dec->ll = (size_t)257 - (size_t)inbyte;
+ back = DK4_EDSTM_ACCEPT;
+ } else {
+ /*
+ EOD marker found
+ */
+ dec->st = RLD_ST_EOD_FOUND;
+ back = DK4_EDSTM_STOP;
+ }
+ }
+ } break;
+ case RLD_ST_EXPECT_RUN_BYTE : {
+ dk4mem_set(&(dec->ob[0]), dec->ll, inbyte, NULL);
+ dec->oused = dec->ll;
+ dec->st = RLD_ST_EXPECT_KEY_BYTE;
+ back = DK4_EDSTM_FINISHED;
+ } break;
+ case RLD_ST_EXPECT_LITERAL_BYTE : {
+ dec->ob[0] = inbyte;
+ dec->oused = 1;
+ dec->ll -= 1;
+ if (0 == dec->ll) {
+ dec->st = RLD_ST_EXPECT_KEY_BYTE;
+ }
+ back = DK4_EDSTM_FINISHED;
+ } break;
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 226 "dk4rld.ctr"
+ return back;
+}
+
+
+
+int
+dk4rld_finish(dk4_rl_dec_t *dec, dk4_er_t *erp)
+{
+ int back = DK4_EDSTM_ERROR;
+
+
+#line 236 "dk4rld.ctr"
+ if (NULL != dec) {
+ switch (dec->st) {
+ case RLD_ST_EXPECT_KEY_BYTE : case RLD_ST_EOD_FOUND : {
+ back = DK4_EDSTM_ACCEPT;
+ } break;
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 248 "dk4rld.ctr"
+ return back;
+}
+
+
+
+int
+dk4rld_output(
+ const unsigned char **dptr, size_t *szptr, dk4_rl_dec_t *dec, dk4_er_t *erp
+)
+{
+ int back = 0;
+
+
+#line 260 "dk4rld.ctr"
+ if (NULL != dec) {
+ if (0 < dec->oused) {
+ *dptr = &(dec->ob[0]);
+ *szptr = dec->oused;
+ back = 1;
+ } else {
+ *dptr = NULL;
+ *szptr = 0;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 272 "dk4rld.ctr"
+ return back;
+}
+
diff --git a/support/dktools/dk4rld.ctr b/support/dktools/dk4rld.ctr
new file mode 100644
index 0000000000..e981d30119
--- /dev/null
+++ b/support/dktools/dk4rld.ctr
@@ -0,0 +1,274 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file dk4rld.h Run-length decoder.
+
+Use dk4rld_init() to initialize the decoder before feeding data to it.
+
+Feed the encoded data into the decoder byte by byte, use the
+dk4rld_add() function.
+If the function returns DK4_EDSTM_ACCEPT, the input was successfully stored
+into the internal data structures, not need for further action.
+If the function returns DK4_EDSTM_FINISHED, an output secquence was
+completed, either a run or a literal byte sequence. Use dk4rld_output()
+to retrieve output data.
+If the dk4rld_add function returns DK4_EDSTM_STOP, an end of data
+(EOD) marker was found; do not feed further bytes into the decoder.
+
+After feeding all input bytes into the decoder, use dk4rld_finish() to check
+syntax. If the function returns DK4_EDSTM_ERROR, the input data stream
+was not properly run-length encoded.
+*/
+
+#include "dk4error.h"
+
+/** Run length decoder.
+*/
+typedef struct {
+ unsigned char ob[128]; /**< Output buffer. */
+ size_t oused; /**< Number of used bytes in ob. */
+ size_t ll; /**< Number of expected bytes. */
+ int st; /**< Current state. */
+} dk4_rl_dec_t;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Initialize decoder.
+ @param dec Decoder to initialize.
+ @param erp Error report, may be NULL.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS if enc is NULL.
+*/
+void
+dk4rld_init(dk4_rl_dec_t *dec, dk4_er_t *erp);
+
+/** Add one encoded byte to decoder.
+ @param dec Decoder.
+ @param inbyte Byte to process.
+ @param erp Error report, may be NULL.
+ @return Action to take, one from:
+ - DK4_EDSTM_ACCEPT<br>
+ if the byte was successfully added
+ to the internal data structures, no further action necessary.
+ - DK4_EDSTM_FINISHED<br>
+ if output is available, use dk4rld_output() to retrieve output.
+ - DK4_EDSTM_STOP<br>
+ if an EOD marker was detected. Do not feed further bytes
+ to the decoder.
+ - DK4_EDSTM_ERROR<br>
+ if an error occured.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS if enc is NULL.
+*/
+int
+dk4rld_add(dk4_rl_dec_t *dec, unsigned char inbyte, dk4_er_t *erp);
+
+/** Finish decoding.
+ @param dec Decoder.
+ @param erp Error report, may be NULL.
+ @return Action to take, one from:
+ - DK4_EDSTM_ACCEPT<br>
+ if no remaining data is stored in the decoder, no further
+ action necessary.
+ - DK4_EDSTM_FINISHED<br>
+ if output is available, use dk4rld_output() to retrieve output.
+ - DK4_EDSTM_ERROR<br>
+ if an error occured.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if enc is NULL.
+ - DK4_E_SYNTAX<br>
+ if data indicated by the run-length byte or literally-length
+ byte is missing.
+*/
+int
+dk4rld_finish(dk4_rl_dec_t *dec, dk4_er_t *erp);
+
+/** Retrieve decoder output.
+ @param dptr Address of pointer to set to decoder output,
+ should be initialized to NULL.
+ @param szptr Address of variable to receive buffer size,
+ should be initialized to 0.
+ @param dec Decoder.
+ @param erp Error report, may be NULL.
+ @return 1 if data is available, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS if enc is NULL.
+*/
+int
+dk4rld_output(
+ const unsigned char **dptr, size_t *szptr, dk4_rl_dec_t *dec, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4rld.h"
+#include "dk4edstm.h"
+#include "dk4mem.h"
+
+
+
+$!trace-include
+
+
+
+/** Decoder states.
+*/
+enum {
+ /** Start state, exepect run length
+ or literal data length.
+ */
+ RLD_ST_EXPECT_KEY_BYTE = 0,
+
+ /** Expect byte value for run.
+ */
+ RLD_ST_EXPECT_RUN_BYTE ,
+
+ /** Expect literal byte.
+ */
+ RLD_ST_EXPECT_LITERAL_BYTE ,
+
+ /** No further input accepted as
+ EOD marker was found.
+ */
+ RLD_ST_EOD_FOUND
+};
+
+
+
+void
+dk4rld_init(dk4_rl_dec_t *dec, dk4_er_t *erp)
+{
+ $? "+ dk4rld_init"
+ if (NULL != dec) {
+ DK4_MEMRES(dec, sizeof(dk4_rl_dec_t));
+ dec->oused = 0;
+ dec->ll = 0;
+ dec->st = RLD_ST_EXPECT_KEY_BYTE;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4rld_init"
+}
+
+
+
+int
+dk4rld_add(dk4_rl_dec_t *dec, unsigned char inbyte, dk4_er_t *erp)
+{
+ int back = DK4_EDSTM_ERROR;
+ $? "+ dk4rld_add"
+ if (NULL != dec) {
+ switch (dec->st) {
+ case RLD_ST_EXPECT_KEY_BYTE : {
+ if ((unsigned char)128 > inbyte) {
+ /*
+ Literal byte sequence
+ */
+ dec->st = RLD_ST_EXPECT_LITERAL_BYTE;
+ dec->ll = (size_t)inbyte + 1;
+ back = DK4_EDSTM_ACCEPT;
+ } else {
+ if ((unsigned char)128 < inbyte) {
+ /*
+ Run of equal bytes
+ */
+ dec->st = RLD_ST_EXPECT_RUN_BYTE;
+ dec->ll = (size_t)257 - (size_t)inbyte;
+ back = DK4_EDSTM_ACCEPT;
+ } else {
+ /*
+ EOD marker found
+ */
+ dec->st = RLD_ST_EOD_FOUND;
+ back = DK4_EDSTM_STOP;
+ }
+ }
+ } break;
+ case RLD_ST_EXPECT_RUN_BYTE : {
+ dk4mem_set(&(dec->ob[0]), dec->ll, inbyte, NULL);
+ dec->oused = dec->ll;
+ dec->st = RLD_ST_EXPECT_KEY_BYTE;
+ back = DK4_EDSTM_FINISHED;
+ } break;
+ case RLD_ST_EXPECT_LITERAL_BYTE : {
+ dec->ob[0] = inbyte;
+ dec->oused = 1;
+ dec->ll -= 1;
+ if (0 == dec->ll) {
+ dec->st = RLD_ST_EXPECT_KEY_BYTE;
+ }
+ back = DK4_EDSTM_FINISHED;
+ } break;
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4rld_add %d", back
+ return back;
+}
+
+
+
+int
+dk4rld_finish(dk4_rl_dec_t *dec, dk4_er_t *erp)
+{
+ int back = DK4_EDSTM_ERROR;
+ $? "+ dk4rld_finish"
+ if (NULL != dec) {
+ switch (dec->st) {
+ case RLD_ST_EXPECT_KEY_BYTE : case RLD_ST_EOD_FOUND : {
+ back = DK4_EDSTM_ACCEPT;
+ } break;
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4rld_finish %d", back
+ return back;
+}
+
+
+
+int
+dk4rld_output(
+ const unsigned char **dptr, size_t *szptr, dk4_rl_dec_t *dec, dk4_er_t *erp
+)
+{
+ int back = 0;
+ $? "+ dk4rld_output"
+ if (NULL != dec) {
+ if (0 < dec->oused) {
+ *dptr = &(dec->ob[0]);
+ *szptr = dec->oused;
+ back = 1;
+ } else {
+ *dptr = NULL;
+ *szptr = 0;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4rld_output %d", back
+ return back;
+}
+
diff --git a/support/dktools/dk4rld.h b/support/dktools/dk4rld.h
new file mode 100644
index 0000000000..32167f9583
--- /dev/null
+++ b/support/dktools/dk4rld.h
@@ -0,0 +1,154 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rld.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4RLD_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4RLD_H_INCLUDED 1
+
+
+#line 9 "dk4rld.ctr"
+
+/** @file dk4rld.h Run-length decoder.
+
+Use dk4rld_init() to initialize the decoder before feeding data to it.
+
+Feed the encoded data into the decoder byte by byte, use the
+dk4rld_add() function.
+If the function returns DK4_EDSTM_ACCEPT, the input was successfully stored
+into the internal data structures, not need for further action.
+If the function returns DK4_EDSTM_FINISHED, an output secquence was
+completed, either a run or a literal byte sequence. Use dk4rld_output()
+to retrieve output data.
+If the dk4rld_add function returns DK4_EDSTM_STOP, an end of data
+(EOD) marker was found; do not feed further bytes into the decoder.
+
+After feeding all input bytes into the decoder, use dk4rld_finish() to check
+syntax. If the function returns DK4_EDSTM_ERROR, the input data stream
+was not properly run-length encoded.
+*/
+
+#include "dk4error.h"
+
+/** Run length decoder.
+*/
+typedef struct {
+ unsigned char ob[128]; /**< Output buffer. */
+ size_t oused; /**< Number of used bytes in ob. */
+ size_t ll; /**< Number of expected bytes. */
+ int st; /**< Current state. */
+} dk4_rl_dec_t;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Initialize decoder.
+ @param dec Decoder to initialize.
+ @param erp Error report, may be NULL.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS if enc is NULL.
+*/
+void
+dk4rld_init(dk4_rl_dec_t *dec, dk4_er_t *erp);
+
+/** Add one encoded byte to decoder.
+ @param dec Decoder.
+ @param inbyte Byte to process.
+ @param erp Error report, may be NULL.
+ @return Action to take, one from:
+ - DK4_EDSTM_ACCEPT<br>
+ if the byte was successfully added
+ to the internal data structures, no further action necessary.
+ - DK4_EDSTM_FINISHED<br>
+ if output is available, use dk4rld_output() to retrieve output.
+ - DK4_EDSTM_STOP<br>
+ if an EOD marker was detected. Do not feed further bytes
+ to the decoder.
+ - DK4_EDSTM_ERROR<br>
+ if an error occured.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS if enc is NULL.
+*/
+int
+dk4rld_add(dk4_rl_dec_t *dec, unsigned char inbyte, dk4_er_t *erp);
+
+/** Finish decoding.
+ @param dec Decoder.
+ @param erp Error report, may be NULL.
+ @return Action to take, one from:
+ - DK4_EDSTM_ACCEPT<br>
+ if no remaining data is stored in the decoder, no further
+ action necessary.
+ - DK4_EDSTM_FINISHED<br>
+ if output is available, use dk4rld_output() to retrieve output.
+ - DK4_EDSTM_ERROR<br>
+ if an error occured.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if enc is NULL.
+ - DK4_E_SYNTAX<br>
+ if data indicated by the run-length byte or literally-length
+ byte is missing.
+*/
+int
+dk4rld_finish(dk4_rl_dec_t *dec, dk4_er_t *erp);
+
+/** Retrieve decoder output.
+ @param dptr Address of pointer to set to decoder output,
+ should be initialized to NULL.
+ @param szptr Address of variable to receive buffer size,
+ should be initialized to 0.
+ @param dec Decoder.
+ @param erp Error report, may be NULL.
+ @return 1 if data is available, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS if enc is NULL.
+*/
+int
+dk4rld_output(
+ const unsigned char **dptr, size_t *szptr, dk4_rl_dec_t *dec, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4rle.c b/support/dktools/dk4rle.c
new file mode 100644
index 0000000000..7f4a89b703
--- /dev/null
+++ b/support/dktools/dk4rle.c
@@ -0,0 +1,835 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rle.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4rle.c The dk4rle module.
+*/
+
+
+#line 127 "dk4rle.ctr"
+
+#include "dk4rle.h"
+#include "dk4edstm.h"
+#include "dk4mem.h"
+#include "dk4memcpl.h"
+
+
+
+
+
+#line 136 "dk4rle.ctr"
+
+
+
+/** Run length encoder state.
+*/
+enum {
+ /** No run detected yet.
+ */
+ RLE_ENC_STATE_NO_RUN = 0,
+
+ /** Currently in a run.
+ */
+ RLE_ENC_STATE_RUN
+};
+
+
+
+/** Calculate byte for a run length.
+ @param sz Length of the run.
+ @return Byte value to indicate length.
+*/
+static
+unsigned char
+dk4rle_run_length_byte(size_t sz)
+{
+ return ((unsigned char)(257 - sz));
+}
+
+
+
+/** Calculate byte for a literal length.
+ @param sz Length of literal data.
+ @return Byte value to indicate the length.
+*/
+static
+unsigned char
+dk4rle_literal_length_byte(size_t sz)
+{
+ return ((unsigned char)(sz - 1));
+}
+
+
+
+
+void
+dk4rle_init(dk4_rl_enc_t *enc, int weod, dk4_er_t *erp)
+{
+ if (NULL != enc) {
+ enc->ib = &(enc->ob[1]);
+ enc->oused = 0;
+ enc->iused = 0;
+ enc->ao_si = 0;
+ enc->ao_ss = 0;
+ enc->ao_iu = 0;
+ enc->ao_st = RLE_ENC_STATE_NO_RUN;
+ enc->st = RLE_ENC_STATE_NO_RUN;
+ enc->lwo = 0;
+ enc->weod = ((0 != weod) ? 1 : 0);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+}
+
+
+
+static
+void
+dk4rle_process_lwo(dk4_rl_enc_t *enc)
+{
+ if (0 < enc->ao_ss) {
+ dk4mem_cpy_to_left(
+ enc->ib,
+ &((enc->ib)[enc->ao_si]),
+ enc->ao_ss,
+ NULL
+ );
+ }
+ enc->iused = enc->ao_iu;
+ enc->st = enc->ao_st;
+ enc->lwo = 0;
+}
+
+
+
+int
+dk4rle_add(dk4_rl_enc_t *enc, unsigned char ibyte, dk4_er_t *erp)
+{
+ int back = DK4_EDSTM_ERROR;
+ int cr = 0; /* Flag: Change to run */
+
+
+#line 226 "dk4rle.ctr"
+ if (NULL != enc) {
+ if (0 != enc->lwo) { dk4rle_process_lwo(enc); }
+
+
+#line 229 "dk4rle.ctr"
+ back = DK4_EDSTM_ACCEPT;
+ (enc->ib)[enc->iused] = ibyte;
+ enc->iused += 1;
+ switch (enc->st) {
+ case RLE_ENC_STATE_RUN : {
+ /*
+ In a run.
+ */
+ if ((enc->ib)[enc->iused - 1] != (enc->ib)[enc->iused - 2]) {
+
+
+#line 239 "dk4rle.ctr"
+ /*
+ End of run, change to normal mode.
+ */
+ enc->ob[0] = dk4rle_run_length_byte(enc->iused - 1);
+ enc->oused = 2;
+ back = DK4_EDSTM_FINISHED;
+ enc->ao_si = enc->iused - 1;
+ enc->ao_ss = 1;
+ enc->ao_iu = 1;
+ enc->ao_st = RLE_ENC_STATE_NO_RUN;
+ } else {
+ /*
+ No end of run, continue.
+ */
+ if (128 <= enc->iused) {
+
+
+#line 255 "dk4rle.ctr"
+ /*
+ Full 128 byte run, output.
+ */
+ enc->ob[0] = dk4rle_run_length_byte(128);
+ enc->oused = 2;
+ back = DK4_EDSTM_FINISHED;
+ enc->ao_si = 0;
+ enc->ao_ss = 0;
+ enc->ao_iu = 0;
+ enc->ao_st = RLE_ENC_STATE_NO_RUN;
+ }
+ }
+ } break;
+ default : {
+ /*
+ Not in a run.
+ */
+ if (4 <= enc->iused) {
+ if (enc->ib[enc->iused - 1] == enc->ib[enc->iused - 2]) {
+ if (enc->ib[enc->iused - 1] == enc->ib[enc->iused - 3]) {
+ if (enc->ib[enc->iused - 1] == enc->ib[enc->iused - 4]) {
+ cr = 1;
+
+#line 277 "dk4rle.ctr"
+ }
+ }
+ }
+ }
+ if (1 == cr) {
+
+
+#line 283 "dk4rle.ctr"
+ if (4 < enc->iused) {
+ enc->ob[0] = dk4rle_literal_length_byte(enc->iused - 4);
+ enc->oused = (enc->iused - 3);
+ back = DK4_EDSTM_FINISHED;
+ enc->ao_si = enc->iused - 4;
+ enc->ao_ss = 4;
+ enc->ao_iu = 4;
+ enc->ao_st = RLE_ENC_STATE_RUN;
+ } else {
+ enc->st = RLE_ENC_STATE_RUN;
+ }
+ } else {
+ if (128 <= enc->iused) {
+ if ((enc->ib)[127] == (enc->ib)[126]) {
+ if ((enc->ib)[127] == (enc->ib)[125]) {
+
+#line 298 "dk4rle.ctr"
+ enc->ob[0] = dk4rle_literal_length_byte(125);
+ enc->oused = 126;
+ back = DK4_EDSTM_FINISHED;
+ enc->ao_si = 125;
+ enc->ao_ss = 3;
+ enc->ao_iu = 3;
+ enc->ao_st = RLE_ENC_STATE_NO_RUN;
+ } else {
+
+#line 306 "dk4rle.ctr"
+ enc->ob[0] = dk4rle_literal_length_byte(126);
+ enc->oused = 127;
+ back = DK4_EDSTM_FINISHED;
+ enc->ao_si = 126;
+ enc->ao_ss = 2;
+ enc->ao_iu = 2;
+ enc->ao_st = RLE_ENC_STATE_NO_RUN;
+ }
+ } else {
+
+#line 315 "dk4rle.ctr"
+ enc->ob[0] = dk4rle_literal_length_byte(128);
+ enc->oused = 129;
+ back = DK4_EDSTM_FINISHED;
+ enc->ao_si = 0;
+ enc->ao_ss = 0;
+ enc->ao_iu = 0;
+ enc->ao_st = RLE_ENC_STATE_NO_RUN;
+ }
+ }
+ }
+ } break;
+ }
+ if (DK4_EDSTM_FINISHED == back) {
+ enc->lwo = 1;
+
+#line 329 "dk4rle.ctr"
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 333 "dk4rle.ctr"
+ return back;
+}
+
+
+
+int
+dk4rle_finish(dk4_rl_enc_t *enc, dk4_er_t *erp)
+{
+ int back = DK4_EDSTM_ERROR;
+
+
+#line 343 "dk4rle.ctr"
+ if (NULL != enc) {
+ if (0 != enc->lwo) { dk4rle_process_lwo(enc); }
+ back = DK4_EDSTM_ACCEPT;
+ if (0 < enc->iused) {
+
+#line 347 "dk4rle.ctr"
+ switch (enc->st) {
+ case RLE_ENC_STATE_RUN : {
+
+#line 349 "dk4rle.ctr"
+ enc->ob[0] = dk4rle_run_length_byte(enc->iused);
+ enc->oused = 2;
+ back = DK4_EDSTM_FINISHED;
+ enc->ao_si = 0;
+ enc->ao_ss = 0;
+ enc->ao_iu = 0;
+ enc->ao_st = RLE_ENC_STATE_NO_RUN;
+ if (0 != enc->weod) {
+
+#line 357 "dk4rle.ctr"
+ enc->ob[2] = (unsigned char)128;
+ enc->oused = 3;
+ }
+ } break;
+ default : {
+
+#line 362 "dk4rle.ctr"
+ enc->ob[0] = dk4rle_literal_length_byte(enc->iused);
+ enc->oused = enc->iused + 1;
+ back = DK4_EDSTM_FINISHED;
+ enc->ao_si = 0;
+ enc->ao_ss = 0;
+ enc->ao_iu = 0;
+ enc->ao_st = RLE_ENC_STATE_NO_RUN;
+ if (0 != enc->weod) {
+
+#line 370 "dk4rle.ctr"
+ enc->ob[enc->iused] = (unsigned char)128;
+ enc->oused += 1;
+ }
+ } break;
+ }
+ } else {
+ if (0 != enc->weod) {
+
+#line 377 "dk4rle.ctr"
+ enc->ob[0] = (unsigned char)128;
+ enc->oused = 1;
+ back = DK4_EDSTM_FINISHED;
+ enc->ao_si = 0;
+ enc->ao_ss = 0;
+ enc->ao_iu = 0;
+ enc->ao_st = RLE_ENC_STATE_NO_RUN;
+ }
+ }
+ if (DK4_EDSTM_FINISHED == back) {
+ enc->lwo = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 392 "dk4rle.ctr"
+ return back;
+}
+
+
+
+int
+dk4rle_output(
+ const unsigned char **dptr, size_t *szptr, dk4_rl_enc_t *enc, dk4_er_t *erp
+)
+{
+ int back = 0;
+ if ((NULL != enc) && (NULL != dptr) && (NULL != szptr)) {
+ if (0 < enc->oused) {
+ *dptr = &(enc->ob[0]);
+ *szptr = enc->oused;
+ back = 1;
+ } else {
+ *dptr = NULL; *szptr = 0;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+/*
+ Below is the first working code for the module.
+ This code worked perfectly fine, but for performance reasons
+ I wanted to avoid the memory copy operations from input buffer
+ to output buffer.
+ If there is any problem with the current code, we have the chance
+ to go back and test with the original code.
+*/
+#if 0
+/* ---------- Header ---------- */
+#include "dk4error.h"
+
+/** Run length encoder.
+*/
+typedef struct {
+ unsigned char ob[144]; /**< Output buffer. */
+ unsigned char ib[128]; /**< Input buffer. */
+ size_t iused; /**< Number of bytes in ib. */
+ size_t oused; /**< Number of bytes in ob. */
+ int st; /**< Current state. */
+ int weod; /**< Flag: Write EOD marker at end. */
+} dk4_rl_enc_t;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Initialize encoder before using it.
+ @param enc Encoder to initialize.
+ @param weod Flag: Write EOD marker at end of data.
+ @param erp Error report, may be NULL.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS if enc is NULL.
+*/
+void
+dk4rle_init(dk4_rl_enc_t *enc, int weod, dk4_er_t *erp);
+
+/** Add a single byte to the encoder.
+ @param enc Encoder.
+ @param ibyte Input byte to process.
+ @param erp Error report, may be NULL.
+ @return Action to take, one from:
+ - DK4_EDSTM_ACCEPT<br>
+ if the input byte was successfully stored in the internal data
+ structures without completing a run. No further action
+ necessary.
+ - DK4_EDSTM_FINISHED<br>
+ if a run was completed. Use dk4rle_output() to obtain the
+ output data.
+ - DK4_EDSTM_ERROR<br>
+ if an error occured.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS if enc is NULL.
+*/
+int
+dk4rle_add(dk4_rl_enc_t *enc, unsigned char ibyte, dk4_er_t *erp);
+
+/** Finish data stream, process final data still stored in the
+ encoder.
+ @param enc Encoder.
+ @param erp Error report, may be NULL.
+ @return Action to take, one from:
+ - DK4_EDSTM_ACCEPT<br>
+ if the input byte was successfully stored in the internal data
+ structures without completing a run. No further action
+ necessary.
+ - DK4_EDSTM_FINISHED<br>
+ if a run was completed. Use dk4rle_output() to obtain the
+ output data.
+ - DK4_EDSTM_ERROR<br>
+ if an error occured.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS if enc is NULL.
+*/
+int
+dk4rle_finish(dk4_rl_enc_t *enc, dk4_er_t *erp);
+
+/** Retrieve encoder output.
+ @param dptr Address of pointer to set to output bytes, should
+ be initialized to NULL.
+ @param szptr Address of size variable for buffer length,
+ should be initialized to 0.
+ @param enc Encoder.
+ @param erp Error report, may be NULL.
+ @return 1 if there is data available, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS if enc is NULL.
+*/
+int
+dk4rle_output(
+ const unsigned char **dptr, size_t *szptr, dk4_rl_enc_t *enc, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+/* ---------------------------- */
+
+/* ---------- Module ---------- */
+#include "dk4rle.h"
+#include "dk4edstm.h"
+#include "dk4mem.h"
+#include "dk4memcpl.h"
+
+
+
+#line 529 "dk4rle.ctr"
+
+/** Run length encoder state.
+*/
+enum {
+ /** No run detected yet.
+ */
+ RLE_ENC_STATE_NO_RUN = 0,
+
+ /** Currently in a run.
+ */
+ RLE_ENC_STATE_RUN
+};
+
+void
+dk4rle_init(dk4_rl_enc_t *enc, int weod, dk4_er_t *erp)
+{
+
+
+#line 546 "dk4rle.ctr"
+ if (NULL != enc) {
+ DK4_MEMRES(enc, sizeof(dk4_rl_enc_t));
+ enc->st = RLE_ENC_STATE_NO_RUN;
+ enc->iused = 0;
+ enc->oused = 0;
+ enc->weod = ((0 != weod) ? 1 : 0);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 555 "dk4rle.ctr"
+}
+
+/** Calculate byte for a run length.
+ @param sz Length of the run.
+ @return Byte value to indicate length.
+*/
+static
+unsigned char
+dk4rle_run_length_byte(size_t sz)
+{
+ return ((unsigned char)(257 - sz));
+}
+
+/** Calculate byte for a literal length.
+ @param sz Length of literal data.
+ @return Byte value to indicate the length.
+*/
+static
+unsigned char
+dk4rle_literal_length_byte(size_t sz)
+{
+ return ((unsigned char)(sz - 1));
+}
+
+int
+dk4rle_add(dk4_rl_enc_t *enc, unsigned char ibyte, dk4_er_t *erp)
+{
+ int back = DK4_EDSTM_ERROR;
+ int cr = 0; /* Flag: Change run */
+
+
+#line 585 "dk4rle.ctr"
+ if (NULL != enc) {
+
+#line 586 "dk4rle.ctr"
+
+
+#line 587 "dk4rle.ctr"
+ back = DK4_EDSTM_ACCEPT;
+
+#line 588 "dk4rle.ctr"
+ enc->ib[enc->iused] = ibyte;
+
+#line 589 "dk4rle.ctr"
+ enc->iused += 1;
+
+#line 590 "dk4rle.ctr"
+ switch (enc->st) {
+ case RLE_ENC_STATE_RUN : {
+
+#line 592 "dk4rle.ctr"
+ if (enc->ib[enc->iused - 1] != enc->ib[enc->iused - 2]) {
+ /* Copy data to output buffer.
+ */
+ enc->ob[1] = enc->ib[enc->iused - 2];
+ /* Set run-length byte.
+ */
+ enc->ob[0] = dk4rle_run_length_byte(enc->iused - 1);
+ /* Set total byte size.
+ */
+ enc->oused = 2;
+ /* Keep input byte.
+ */
+ enc->ib[0] = enc->ib[enc->iused - 1];
+ /* Number of input bytes is 1 now.
+ */
+ enc->iused = 1;
+ /* Output ready.
+ */
+ back = DK4_EDSTM_FINISHED;
+ /* No longer in a run.
+ */
+ enc->st = RLE_ENC_STATE_NO_RUN;
+ } else {
+ if (128 <= enc->iused) {
+ /* Copy data to output buffer.
+ */
+ enc->ob[1] = enc->ib[0];
+ /* Set run-length byte.
+ */
+ enc->ob[0] = dk4rle_run_length_byte(128);
+ /* Set total byte size.
+ */
+ enc->oused = 2;
+ /* No input bytes available.
+ */
+ enc->iused = 0;
+ /* Output ready.
+ */
+ back = DK4_EDSTM_FINISHED;
+ /* No longer in a run.
+ */
+ enc->st = RLE_ENC_STATE_NO_RUN;
+ }
+ }
+ } break;
+ default : {
+
+#line 638 "dk4rle.ctr"
+ if (4 <= enc->iused) {
+
+#line 639 "dk4rle.ctr"
+ if (enc->ib[enc->iused - 1] == enc->ib[enc->iused - 2]) {
+
+#line 640 "dk4rle.ctr"
+ if (enc->ib[enc->iused - 1] == enc->ib[enc->iused - 3]) {
+
+#line 641 "dk4rle.ctr"
+ if (enc->ib[enc->iused - 1] == enc->ib[enc->iused - 4]) {
+
+#line 642 "dk4rle.ctr"
+ cr = 1;
+ }
+ }
+ }
+ if (1 == cr) {
+
+#line 647 "dk4rle.ctr"
+ /*
+ Start of run.
+ */
+ if (4 < enc->iused) {
+ /*
+ Output the literal data before run.
+ */
+ /* Copy data to output buffer.
+ */
+ DK4_MEMCPY( &(enc->ob[1]), &(enc->ib[0]), (enc->iused - 4));
+ /* Set run-length byte.
+ */
+ enc->ob[0] = dk4rle_literal_length_byte(enc->iused - 4);
+ /* Set total byte size.
+ */
+ enc->oused = enc->iused - 3;
+ /* Keep last 4 bytes.
+ */
+ dk4mem_cpy_to_left(
+ &(enc->ib[0]),
+ &(enc->ib[enc->iused - 4]),
+ 4, NULL
+ );
+ /* Number of used input bytes is 4.
+ */
+ enc->iused = 4;
+ back = DK4_EDSTM_FINISHED;
+ }
+ enc->st = RLE_ENC_STATE_RUN;
+ } else {
+
+#line 677 "dk4rle.ctr"
+ if (128 <= enc->iused) {
+ if (enc->ib[enc->iused - 1] == enc->ib[enc->iused - 2]) {
+ if (enc->ib[enc->iused - 1] == enc->ib[enc->iused - 3]) {
+ /*
+ Keep final 3 bytes, potentially start of run.
+ */
+ /* Copy data to output buffer.
+ */
+ DK4_MEMCPY( &(enc->ob[1]), &(enc->ib[0]), 125);
+ /* Set run-length byte.
+ */
+ enc->ob[0] = dk4rle_literal_length_byte(128 - 3);
+ /* Set total byte size.
+ */
+ enc->oused = 126;
+ /* Keep last 3 bytes.
+ */
+ dk4mem_cpy_to_left(
+ &(enc->ib[0]),
+ &(enc->ib[125]),
+ 3, NULL
+ );
+ /* Number of used bytes is 2.
+ */
+ enc->iused = 3;
+ } else {
+ /*
+ Keep final 2 bytes, potentially start of run.
+ */
+ /* Copy data.
+ */
+ DK4_MEMCPY( &(enc->ob[1]), &(enc->ib[0]), 126 );
+ /* Set run-length byte.
+ */
+ enc->ob[0] = dk4rle_literal_length_byte(128 - 2);
+ /* Set total byte size.
+ */
+ enc->oused = 127;
+ /* Keep last 2 bytes.
+ */
+ dk4mem_cpy_to_left(
+ &(enc->ib[0]),
+ &(enc->ib[126]),
+ 2, NULL
+ );
+ /* Number of used bytes is 2.
+ */
+ enc->iused = 2;
+ }
+ } else {
+ /*
+ No need to keep any final bytes.
+ */
+ /* Copy data.
+ */
+ DK4_MEMCPY( &(enc->ob[1]), &(enc->ib[0]), enc->iused );
+ /* Set run-length byte.
+ */
+ enc->ob[0] = dk4rle_literal_length_byte(128);
+ /* Set total byte size.
+ */
+ enc->oused = 129;
+ /* No input byte in buffer.
+ */
+ enc->iused = 0;
+ }
+ back = DK4_EDSTM_FINISHED;
+ }
+ }
+ }
+ } break;
+ }
+ } else {
+
+#line 750 "dk4rle.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 752 "dk4rle.ctr"
+ return back;
+}
+
+int
+dk4rle_finish(dk4_rl_enc_t *enc, dk4_er_t *erp)
+{
+ int back = DK4_EDSTM_ERROR;
+
+
+#line 760 "dk4rle.ctr"
+ if (NULL != enc) {
+ back = DK4_EDSTM_ACCEPT;
+ if (0 < enc->iused) {
+ switch (enc->st) {
+ case RLE_ENC_STATE_RUN : {
+ /* Copy data to output buffer.
+ */
+ enc->ob[1] = enc->ib[0];
+ /* Set run-length byte.
+ */
+ enc->ob[0] = dk4rle_run_length_byte(enc->iused);
+ /* Set total byte size.
+ */
+ enc->oused = 2;
+ if (0 != enc->weod) {
+ /* Add EOD marker.
+ */
+ enc->ob[2] = (unsigned char)128;
+ enc->oused = 3;
+ }
+ } break;
+ default : {
+ /* Copy data to output buffer.
+ */
+ DK4_MEMCPY( &(enc->ob[1]), &(enc->ib[0]), enc->iused );
+ /* Set literal length byte.
+ */
+ enc->ob[0] = dk4rle_literal_length_byte(enc->iused);
+ /* Set total byte size.
+ */
+ enc->oused = 1 + enc->iused;
+ if (0 != enc->weod) {
+ /* Add EOD marker.
+ */
+ enc->ob[1 + enc->iused] = (unsigned char)128;
+ enc->oused += 1;
+ }
+ } break;
+ }
+ back = DK4_EDSTM_FINISHED;
+ } else {
+ if (0 != enc->weod) {
+ enc->ob[0] = (unsigned char)128;
+ enc->oused = 1;
+ back = DK4_EDSTM_FINISHED;
+ }
+ }
+ enc->iused = 0;
+ enc->st = RLE_ENC_STATE_NO_RUN;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 812 "dk4rle.ctr"
+ return back;
+}
+
+int
+dk4rle_output(
+ const unsigned char **dptr, size_t *szptr, dk4_rl_enc_t *enc, dk4_er_t *erp
+)
+{
+ int back = 0;
+
+
+#line 822 "dk4rle.ctr"
+ if (NULL != enc) {
+ if (0 < enc->oused) {
+ *dptr = &(enc->ob[0]);
+ *szptr = enc->oused;
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 831 "dk4rle.ctr"
+ return back;
+}
+/* ---------------------------- */
+#endif
+
diff --git a/support/dktools/dk4rle.ctr b/support/dktools/dk4rle.ctr
new file mode 100644
index 0000000000..ece71c3140
--- /dev/null
+++ b/support/dktools/dk4rle.ctr
@@ -0,0 +1,835 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk4rle.h Run length encoder as
+described in the PS and PDF specifications.
+
+Use the dk4rle_init() function to initialize the encoder first.
+
+Add binary data byte by byte, use dk4rle_add(). If this function
+returns DK4_EDSTM_ACCEPT, the byte was successfully stored in the encoder,
+no further action is necessary. If the function returns DK4_EDSTM_FINISHED,
+either a run or a sequence of literal bytes was completed; use
+dk4rle_output() to retrieve the output data.
+
+After passing all bytes to the encoder there is probably data in the
+encoder not yet retrieved. Use the dk4rle_finish() function to check.
+If the function returns DK4_EDSTM_FINISHED, use dk4rle_output() to retrieve
+the final output data.
+*/
+
+#include "dk4error.h"
+
+/** Run-length encoder.
+*/
+typedef struct {
+ unsigned char ob[144]; /**< Buffer for both input and output. */
+ unsigned char *ib; /**< Pointer to ob[1], input buffer. */
+ size_t oused; /**< Output buffer size. */
+ size_t iused; /**< Number of input bytes available. */
+ size_t ao_si; /**< Index to save bytes from after output. */
+ size_t ao_ss; /**< Size of buffer part to save after out. */
+ size_t ao_iu; /**< Number of input bytes after output. */
+ int ao_st; /**< New state after output. */
+ int st; /**< Current state. */
+ int lwo; /**< Flag: Last operation was output. */
+ int weod; /**< Flag: Write EOD marker at end. */
+} dk4_rl_enc_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Initialize encoder before using it.
+ @param enc Encoder to initialize.
+ @param weod Flag: Write EOD marker at end of data.
+ @param erp Error report, may be NULL.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS if enc is NULL.
+*/
+void
+dk4rle_init(dk4_rl_enc_t *enc, int weod, dk4_er_t *erp);
+
+/** Add a single byte to the encoder.
+ @param enc Encoder.
+ @param ibyte Input byte to process.
+ @param erp Error report, may be NULL.
+ @return Action to take, one from:
+ - DK4_EDSTM_ACCEPT<br>
+ if the input byte was successfully stored in the internal data
+ structures without completing a run. No further action
+ necessary.
+ - DK4_EDSTM_FINISHED<br>
+ if a run was completed. Use dk4rle_output() to obtain the
+ output data.
+ - DK4_EDSTM_ERROR<br>
+ if an error occured.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS if enc is NULL.
+*/
+int
+dk4rle_add(dk4_rl_enc_t *enc, unsigned char ibyte, dk4_er_t *erp);
+
+/** Finish data stream, process final data still stored in the
+ encoder.
+ @param enc Encoder.
+ @param erp Error report, may be NULL.
+ @return Action to take, one from:
+ - DK4_EDSTM_ACCEPT<br>
+ if the input byte was successfully stored in the internal data
+ structures without completing a run. No further action
+ necessary.
+ - DK4_EDSTM_FINISHED<br>
+ if a run was completed. Use dk4rle_output() to obtain the
+ output data.
+ - DK4_EDSTM_ERROR<br>
+ if an error occured.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS if enc is NULL.
+*/
+int
+dk4rle_finish(dk4_rl_enc_t *enc, dk4_er_t *erp);
+
+/** Retrieve encoder output.
+ @param dptr Address of pointer to set to output bytes, should
+ be initialized to NULL.
+ @param szptr Address of size variable for buffer length,
+ should be initialized to 0.
+ @param enc Encoder.
+ @param erp Error report, may be NULL.
+ @return 1 if there is data available, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS if enc is NULL.
+*/
+int
+dk4rle_output(
+ const unsigned char **dptr, size_t *szptr, dk4_rl_enc_t *enc, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4rle.h"
+#include "dk4edstm.h"
+#include "dk4mem.h"
+#include "dk4memcpl.h"
+
+
+
+$!trace-include
+
+
+
+/** Run length encoder state.
+*/
+enum {
+ /** No run detected yet.
+ */
+ RLE_ENC_STATE_NO_RUN = 0,
+
+ /** Currently in a run.
+ */
+ RLE_ENC_STATE_RUN
+};
+
+
+
+/** Calculate byte for a run length.
+ @param sz Length of the run.
+ @return Byte value to indicate length.
+*/
+static
+unsigned char
+dk4rle_run_length_byte(size_t sz)
+{
+ return ((unsigned char)(257 - sz));
+}
+
+
+
+/** Calculate byte for a literal length.
+ @param sz Length of literal data.
+ @return Byte value to indicate the length.
+*/
+static
+unsigned char
+dk4rle_literal_length_byte(size_t sz)
+{
+ return ((unsigned char)(sz - 1));
+}
+
+
+
+
+void
+dk4rle_init(dk4_rl_enc_t *enc, int weod, dk4_er_t *erp)
+{
+ if (NULL != enc) {
+ enc->ib = &(enc->ob[1]);
+ enc->oused = 0;
+ enc->iused = 0;
+ enc->ao_si = 0;
+ enc->ao_ss = 0;
+ enc->ao_iu = 0;
+ enc->ao_st = RLE_ENC_STATE_NO_RUN;
+ enc->st = RLE_ENC_STATE_NO_RUN;
+ enc->lwo = 0;
+ enc->weod = ((0 != weod) ? 1 : 0);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+}
+
+
+
+static
+void
+dk4rle_process_lwo(dk4_rl_enc_t *enc)
+{
+ if (0 < enc->ao_ss) {
+ dk4mem_cpy_to_left(
+ enc->ib,
+ &((enc->ib)[enc->ao_si]),
+ enc->ao_ss,
+ NULL
+ );
+ }
+ enc->iused = enc->ao_iu;
+ enc->st = enc->ao_st;
+ enc->lwo = 0;
+}
+
+
+
+int
+dk4rle_add(dk4_rl_enc_t *enc, unsigned char ibyte, dk4_er_t *erp)
+{
+ int back = DK4_EDSTM_ERROR;
+ int cr = 0; /* Flag: Change to run */
+ $? "+ dk4rle_add %02x", (unsigned)ibyte
+ if (NULL != enc) {
+ if (0 != enc->lwo) { dk4rle_process_lwo(enc); }
+ $? ". index = %u", (unsigned)(enc->iused)
+ back = DK4_EDSTM_ACCEPT;
+ (enc->ib)[enc->iused] = ibyte;
+ enc->iused += 1;
+ switch (enc->st) {
+ case RLE_ENC_STATE_RUN : {
+ /*
+ In a run.
+ */
+ if ((enc->ib)[enc->iused - 1] != (enc->ib)[enc->iused - 2]) {
+ $? ". end of run"
+ /*
+ End of run, change to normal mode.
+ */
+ enc->ob[0] = dk4rle_run_length_byte(enc->iused - 1);
+ enc->oused = 2;
+ back = DK4_EDSTM_FINISHED;
+ enc->ao_si = enc->iused - 1;
+ enc->ao_ss = 1;
+ enc->ao_iu = 1;
+ enc->ao_st = RLE_ENC_STATE_NO_RUN;
+ } else {
+ /*
+ No end of run, continue.
+ */
+ if (128 <= enc->iused) {
+ $? ". run at limit"
+ /*
+ Full 128 byte run, output.
+ */
+ enc->ob[0] = dk4rle_run_length_byte(128);
+ enc->oused = 2;
+ back = DK4_EDSTM_FINISHED;
+ enc->ao_si = 0;
+ enc->ao_ss = 0;
+ enc->ao_iu = 0;
+ enc->ao_st = RLE_ENC_STATE_NO_RUN;
+ }
+ }
+ } break;
+ default : {
+ /*
+ Not in a run.
+ */
+ if (4 <= enc->iused) {
+ if (enc->ib[enc->iused - 1] == enc->ib[enc->iused - 2]) {
+ if (enc->ib[enc->iused - 1] == enc->ib[enc->iused - 3]) {
+ if (enc->ib[enc->iused - 1] == enc->ib[enc->iused - 4]) {
+ cr = 1; $? ". change to run"
+ }
+ }
+ }
+ }
+ if (1 == cr) {
+ $? ". start run"
+ if (4 < enc->iused) {
+ enc->ob[0] = dk4rle_literal_length_byte(enc->iused - 4);
+ enc->oused = (enc->iused - 3);
+ back = DK4_EDSTM_FINISHED;
+ enc->ao_si = enc->iused - 4;
+ enc->ao_ss = 4;
+ enc->ao_iu = 4;
+ enc->ao_st = RLE_ENC_STATE_RUN;
+ } else {
+ enc->st = RLE_ENC_STATE_RUN;
+ }
+ } else {
+ if (128 <= enc->iused) {
+ if ((enc->ib)[127] == (enc->ib)[126]) {
+ if ((enc->ib)[127] == (enc->ib)[125]) { $? ". save last 3"
+ enc->ob[0] = dk4rle_literal_length_byte(125);
+ enc->oused = 126;
+ back = DK4_EDSTM_FINISHED;
+ enc->ao_si = 125;
+ enc->ao_ss = 3;
+ enc->ao_iu = 3;
+ enc->ao_st = RLE_ENC_STATE_NO_RUN;
+ } else { $? ". limit reached, save last 2"
+ enc->ob[0] = dk4rle_literal_length_byte(126);
+ enc->oused = 127;
+ back = DK4_EDSTM_FINISHED;
+ enc->ao_si = 126;
+ enc->ao_ss = 2;
+ enc->ao_iu = 2;
+ enc->ao_st = RLE_ENC_STATE_NO_RUN;
+ }
+ } else { $? ". limit reached, output all"
+ enc->ob[0] = dk4rle_literal_length_byte(128);
+ enc->oused = 129;
+ back = DK4_EDSTM_FINISHED;
+ enc->ao_si = 0;
+ enc->ao_ss = 0;
+ enc->ao_iu = 0;
+ enc->ao_st = RLE_ENC_STATE_NO_RUN;
+ }
+ }
+ }
+ } break;
+ }
+ if (DK4_EDSTM_FINISHED == back) {
+ enc->lwo = 1; $? ". finished"
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4rle_add %d", back
+ return back;
+}
+
+
+
+int
+dk4rle_finish(dk4_rl_enc_t *enc, dk4_er_t *erp)
+{
+ int back = DK4_EDSTM_ERROR;
+ $? "+ dk4rle_finish"
+ if (NULL != enc) {
+ if (0 != enc->lwo) { dk4rle_process_lwo(enc); }
+ back = DK4_EDSTM_ACCEPT;
+ if (0 < enc->iused) { $? ". input available"
+ switch (enc->st) {
+ case RLE_ENC_STATE_RUN : { $? ". final run"
+ enc->ob[0] = dk4rle_run_length_byte(enc->iused);
+ enc->oused = 2;
+ back = DK4_EDSTM_FINISHED;
+ enc->ao_si = 0;
+ enc->ao_ss = 0;
+ enc->ao_iu = 0;
+ enc->ao_st = RLE_ENC_STATE_NO_RUN;
+ if (0 != enc->weod) { $? ". add eod"
+ enc->ob[2] = (unsigned char)128;
+ enc->oused = 3;
+ }
+ } break;
+ default : { $? ". final literal bytes"
+ enc->ob[0] = dk4rle_literal_length_byte(enc->iused);
+ enc->oused = enc->iused + 1;
+ back = DK4_EDSTM_FINISHED;
+ enc->ao_si = 0;
+ enc->ao_ss = 0;
+ enc->ao_iu = 0;
+ enc->ao_st = RLE_ENC_STATE_NO_RUN;
+ if (0 != enc->weod) { $? ". add eod"
+ enc->ob[enc->iused] = (unsigned char)128;
+ enc->oused += 1;
+ }
+ } break;
+ }
+ } else {
+ if (0 != enc->weod) { $? ". write eod"
+ enc->ob[0] = (unsigned char)128;
+ enc->oused = 1;
+ back = DK4_EDSTM_FINISHED;
+ enc->ao_si = 0;
+ enc->ao_ss = 0;
+ enc->ao_iu = 0;
+ enc->ao_st = RLE_ENC_STATE_NO_RUN;
+ }
+ }
+ if (DK4_EDSTM_FINISHED == back) {
+ enc->lwo = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4rle_finish %d", back
+ return back;
+}
+
+
+
+int
+dk4rle_output(
+ const unsigned char **dptr, size_t *szptr, dk4_rl_enc_t *enc, dk4_er_t *erp
+)
+{
+ int back = 0;
+ if ((NULL != enc) && (NULL != dptr) && (NULL != szptr)) {
+ if (0 < enc->oused) {
+ *dptr = &(enc->ob[0]);
+ *szptr = enc->oused;
+ back = 1;
+ } else {
+ *dptr = NULL; *szptr = 0;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+/*
+ Below is the first working code for the module.
+ This code worked perfectly fine, but for performance reasons
+ I wanted to avoid the memory copy operations from input buffer
+ to output buffer.
+ If there is any problem with the current code, we have the chance
+ to go back and test with the original code.
+*/
+#if 0
+/* ---------- Header ---------- */
+#include "dk4error.h"
+
+/** Run length encoder.
+*/
+typedef struct {
+ unsigned char ob[144]; /**< Output buffer. */
+ unsigned char ib[128]; /**< Input buffer. */
+ size_t iused; /**< Number of bytes in ib. */
+ size_t oused; /**< Number of bytes in ob. */
+ int st; /**< Current state. */
+ int weod; /**< Flag: Write EOD marker at end. */
+} dk4_rl_enc_t;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Initialize encoder before using it.
+ @param enc Encoder to initialize.
+ @param weod Flag: Write EOD marker at end of data.
+ @param erp Error report, may be NULL.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS if enc is NULL.
+*/
+void
+dk4rle_init(dk4_rl_enc_t *enc, int weod, dk4_er_t *erp);
+
+/** Add a single byte to the encoder.
+ @param enc Encoder.
+ @param ibyte Input byte to process.
+ @param erp Error report, may be NULL.
+ @return Action to take, one from:
+ - DK4_EDSTM_ACCEPT<br>
+ if the input byte was successfully stored in the internal data
+ structures without completing a run. No further action
+ necessary.
+ - DK4_EDSTM_FINISHED<br>
+ if a run was completed. Use dk4rle_output() to obtain the
+ output data.
+ - DK4_EDSTM_ERROR<br>
+ if an error occured.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS if enc is NULL.
+*/
+int
+dk4rle_add(dk4_rl_enc_t *enc, unsigned char ibyte, dk4_er_t *erp);
+
+/** Finish data stream, process final data still stored in the
+ encoder.
+ @param enc Encoder.
+ @param erp Error report, may be NULL.
+ @return Action to take, one from:
+ - DK4_EDSTM_ACCEPT<br>
+ if the input byte was successfully stored in the internal data
+ structures without completing a run. No further action
+ necessary.
+ - DK4_EDSTM_FINISHED<br>
+ if a run was completed. Use dk4rle_output() to obtain the
+ output data.
+ - DK4_EDSTM_ERROR<br>
+ if an error occured.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS if enc is NULL.
+*/
+int
+dk4rle_finish(dk4_rl_enc_t *enc, dk4_er_t *erp);
+
+/** Retrieve encoder output.
+ @param dptr Address of pointer to set to output bytes, should
+ be initialized to NULL.
+ @param szptr Address of size variable for buffer length,
+ should be initialized to 0.
+ @param enc Encoder.
+ @param erp Error report, may be NULL.
+ @return 1 if there is data available, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS if enc is NULL.
+*/
+int
+dk4rle_output(
+ const unsigned char **dptr, size_t *szptr, dk4_rl_enc_t *enc, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+/* ---------------------------- */
+
+/* ---------- Module ---------- */
+#include "dk4rle.h"
+#include "dk4edstm.h"
+#include "dk4mem.h"
+#include "dk4memcpl.h"
+
+$!trace-include
+
+/** Run length encoder state.
+*/
+enum {
+ /** No run detected yet.
+ */
+ RLE_ENC_STATE_NO_RUN = 0,
+
+ /** Currently in a run.
+ */
+ RLE_ENC_STATE_RUN
+};
+
+void
+dk4rle_init(dk4_rl_enc_t *enc, int weod, dk4_er_t *erp)
+{
+ $? "+ dk4rle_init"
+ if (NULL != enc) {
+ DK4_MEMRES(enc, sizeof(dk4_rl_enc_t));
+ enc->st = RLE_ENC_STATE_NO_RUN;
+ enc->iused = 0;
+ enc->oused = 0;
+ enc->weod = ((0 != weod) ? 1 : 0);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4rle_init"
+}
+
+/** Calculate byte for a run length.
+ @param sz Length of the run.
+ @return Byte value to indicate length.
+*/
+static
+unsigned char
+dk4rle_run_length_byte(size_t sz)
+{
+ return ((unsigned char)(257 - sz));
+}
+
+/** Calculate byte for a literal length.
+ @param sz Length of literal data.
+ @return Byte value to indicate the length.
+*/
+static
+unsigned char
+dk4rle_literal_length_byte(size_t sz)
+{
+ return ((unsigned char)(sz - 1));
+}
+
+int
+dk4rle_add(dk4_rl_enc_t *enc, unsigned char ibyte, dk4_er_t *erp)
+{
+ int back = DK4_EDSTM_ERROR;
+ int cr = 0; /* Flag: Change run */
+ $? "+ dk4rle_add"
+ if (NULL != enc) { $? ". enc"
+ $? ". iused = %u", (unsigned)(enc->iused)
+ back = DK4_EDSTM_ACCEPT; $? ". back"
+ enc->ib[enc->iused] = ibyte; $? ". ib[used]"
+ enc->iused += 1; $? ". iused += 1"
+ switch (enc->st) {
+ case RLE_ENC_STATE_RUN : { $? ". in run"
+ if (enc->ib[enc->iused - 1] != enc->ib[enc->iused - 2]) {
+ /* Copy data to output buffer.
+ */
+ enc->ob[1] = enc->ib[enc->iused - 2];
+ /* Set run-length byte.
+ */
+ enc->ob[0] = dk4rle_run_length_byte(enc->iused - 1);
+ /* Set total byte size.
+ */
+ enc->oused = 2;
+ /* Keep input byte.
+ */
+ enc->ib[0] = enc->ib[enc->iused - 1];
+ /* Number of input bytes is 1 now.
+ */
+ enc->iused = 1;
+ /* Output ready.
+ */
+ back = DK4_EDSTM_FINISHED;
+ /* No longer in a run.
+ */
+ enc->st = RLE_ENC_STATE_NO_RUN;
+ } else {
+ if (128 <= enc->iused) {
+ /* Copy data to output buffer.
+ */
+ enc->ob[1] = enc->ib[0];
+ /* Set run-length byte.
+ */
+ enc->ob[0] = dk4rle_run_length_byte(128);
+ /* Set total byte size.
+ */
+ enc->oused = 2;
+ /* No input bytes available.
+ */
+ enc->iused = 0;
+ /* Output ready.
+ */
+ back = DK4_EDSTM_FINISHED;
+ /* No longer in a run.
+ */
+ enc->st = RLE_ENC_STATE_NO_RUN;
+ }
+ }
+ } break;
+ default : { $? ". not in a run"
+ if (4 <= enc->iused) { $? ". 4"
+ if (enc->ib[enc->iused - 1] == enc->ib[enc->iused - 2]) { $? ". 2"
+ if (enc->ib[enc->iused - 1] == enc->ib[enc->iused - 3]) { $? ". 3"
+ if (enc->ib[enc->iused - 1] == enc->ib[enc->iused - 4]) { $? ". 4"
+ cr = 1;
+ }
+ }
+ }
+ if (1 == cr) { $? ". start of run found"
+ /*
+ Start of run.
+ */
+ if (4 < enc->iused) {
+ /*
+ Output the literal data before run.
+ */
+ /* Copy data to output buffer.
+ */
+ DK4_MEMCPY( &(enc->ob[1]), &(enc->ib[0]), (enc->iused - 4));
+ /* Set run-length byte.
+ */
+ enc->ob[0] = dk4rle_literal_length_byte(enc->iused - 4);
+ /* Set total byte size.
+ */
+ enc->oused = enc->iused - 3;
+ /* Keep last 4 bytes.
+ */
+ dk4mem_cpy_to_left(
+ &(enc->ib[0]),
+ &(enc->ib[enc->iused - 4]),
+ 4, NULL
+ );
+ /* Number of used input bytes is 4.
+ */
+ enc->iused = 4;
+ back = DK4_EDSTM_FINISHED;
+ }
+ enc->st = RLE_ENC_STATE_RUN;
+ } else { $? ". no start of run found"
+ if (128 <= enc->iused) {
+ if (enc->ib[enc->iused - 1] == enc->ib[enc->iused - 2]) {
+ if (enc->ib[enc->iused - 1] == enc->ib[enc->iused - 3]) {
+ /*
+ Keep final 3 bytes, potentially start of run.
+ */
+ /* Copy data to output buffer.
+ */
+ DK4_MEMCPY( &(enc->ob[1]), &(enc->ib[0]), 125);
+ /* Set run-length byte.
+ */
+ enc->ob[0] = dk4rle_literal_length_byte(128 - 3);
+ /* Set total byte size.
+ */
+ enc->oused = 126;
+ /* Keep last 3 bytes.
+ */
+ dk4mem_cpy_to_left(
+ &(enc->ib[0]),
+ &(enc->ib[125]),
+ 3, NULL
+ );
+ /* Number of used bytes is 2.
+ */
+ enc->iused = 3;
+ } else {
+ /*
+ Keep final 2 bytes, potentially start of run.
+ */
+ /* Copy data.
+ */
+ DK4_MEMCPY( &(enc->ob[1]), &(enc->ib[0]), 126 );
+ /* Set run-length byte.
+ */
+ enc->ob[0] = dk4rle_literal_length_byte(128 - 2);
+ /* Set total byte size.
+ */
+ enc->oused = 127;
+ /* Keep last 2 bytes.
+ */
+ dk4mem_cpy_to_left(
+ &(enc->ib[0]),
+ &(enc->ib[126]),
+ 2, NULL
+ );
+ /* Number of used bytes is 2.
+ */
+ enc->iused = 2;
+ }
+ } else {
+ /*
+ No need to keep any final bytes.
+ */
+ /* Copy data.
+ */
+ DK4_MEMCPY( &(enc->ob[1]), &(enc->ib[0]), enc->iused );
+ /* Set run-length byte.
+ */
+ enc->ob[0] = dk4rle_literal_length_byte(128);
+ /* Set total byte size.
+ */
+ enc->oused = 129;
+ /* No input byte in buffer.
+ */
+ enc->iused = 0;
+ }
+ back = DK4_EDSTM_FINISHED;
+ }
+ }
+ }
+ } break;
+ }
+ } else { $? "! enc"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4rle_add %d", back
+ return back;
+}
+
+int
+dk4rle_finish(dk4_rl_enc_t *enc, dk4_er_t *erp)
+{
+ int back = DK4_EDSTM_ERROR;
+ $? "+ dk4rle_finish"
+ if (NULL != enc) {
+ back = DK4_EDSTM_ACCEPT;
+ if (0 < enc->iused) {
+ switch (enc->st) {
+ case RLE_ENC_STATE_RUN : {
+ /* Copy data to output buffer.
+ */
+ enc->ob[1] = enc->ib[0];
+ /* Set run-length byte.
+ */
+ enc->ob[0] = dk4rle_run_length_byte(enc->iused);
+ /* Set total byte size.
+ */
+ enc->oused = 2;
+ if (0 != enc->weod) {
+ /* Add EOD marker.
+ */
+ enc->ob[2] = (unsigned char)128;
+ enc->oused = 3;
+ }
+ } break;
+ default : {
+ /* Copy data to output buffer.
+ */
+ DK4_MEMCPY( &(enc->ob[1]), &(enc->ib[0]), enc->iused );
+ /* Set literal length byte.
+ */
+ enc->ob[0] = dk4rle_literal_length_byte(enc->iused);
+ /* Set total byte size.
+ */
+ enc->oused = 1 + enc->iused;
+ if (0 != enc->weod) {
+ /* Add EOD marker.
+ */
+ enc->ob[1 + enc->iused] = (unsigned char)128;
+ enc->oused += 1;
+ }
+ } break;
+ }
+ back = DK4_EDSTM_FINISHED;
+ } else {
+ if (0 != enc->weod) {
+ enc->ob[0] = (unsigned char)128;
+ enc->oused = 1;
+ back = DK4_EDSTM_FINISHED;
+ }
+ }
+ enc->iused = 0;
+ enc->st = RLE_ENC_STATE_NO_RUN;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4rle_finish %d", back
+ return back;
+}
+
+int
+dk4rle_output(
+ const unsigned char **dptr, size_t *szptr, dk4_rl_enc_t *enc, dk4_er_t *erp
+)
+{
+ int back = 0;
+ $? "+ dk4rle_output"
+ if (NULL != enc) {
+ if (0 < enc->oused) {
+ *dptr = &(enc->ob[0]);
+ *szptr = enc->oused;
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4rle_output %d", back
+ return back;
+}
+/* ---------------------------- */
+#endif
+
diff --git a/support/dktools/dk4rle.h b/support/dktools/dk4rle.h
new file mode 100644
index 0000000000..770ad0807b
--- /dev/null
+++ b/support/dktools/dk4rle.h
@@ -0,0 +1,159 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4rle.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4RLE_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4RLE_H_INCLUDED 1
+
+
+#line 10 "dk4rle.ctr"
+
+/** @file dk4rle.h Run length encoder as
+described in the PS and PDF specifications.
+
+Use the dk4rle_init() function to initialize the encoder first.
+
+Add binary data byte by byte, use dk4rle_add(). If this function
+returns DK4_EDSTM_ACCEPT, the byte was successfully stored in the encoder,
+no further action is necessary. If the function returns DK4_EDSTM_FINISHED,
+either a run or a sequence of literal bytes was completed; use
+dk4rle_output() to retrieve the output data.
+
+After passing all bytes to the encoder there is probably data in the
+encoder not yet retrieved. Use the dk4rle_finish() function to check.
+If the function returns DK4_EDSTM_FINISHED, use dk4rle_output() to retrieve
+the final output data.
+*/
+
+#include "dk4error.h"
+
+/** Run-length encoder.
+*/
+typedef struct {
+ unsigned char ob[144]; /**< Buffer for both input and output. */
+ unsigned char *ib; /**< Pointer to ob[1], input buffer. */
+ size_t oused; /**< Output buffer size. */
+ size_t iused; /**< Number of input bytes available. */
+ size_t ao_si; /**< Index to save bytes from after output. */
+ size_t ao_ss; /**< Size of buffer part to save after out. */
+ size_t ao_iu; /**< Number of input bytes after output. */
+ int ao_st; /**< New state after output. */
+ int st; /**< Current state. */
+ int lwo; /**< Flag: Last operation was output. */
+ int weod; /**< Flag: Write EOD marker at end. */
+} dk4_rl_enc_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Initialize encoder before using it.
+ @param enc Encoder to initialize.
+ @param weod Flag: Write EOD marker at end of data.
+ @param erp Error report, may be NULL.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS if enc is NULL.
+*/
+void
+dk4rle_init(dk4_rl_enc_t *enc, int weod, dk4_er_t *erp);
+
+/** Add a single byte to the encoder.
+ @param enc Encoder.
+ @param ibyte Input byte to process.
+ @param erp Error report, may be NULL.
+ @return Action to take, one from:
+ - DK4_EDSTM_ACCEPT<br>
+ if the input byte was successfully stored in the internal data
+ structures without completing a run. No further action
+ necessary.
+ - DK4_EDSTM_FINISHED<br>
+ if a run was completed. Use dk4rle_output() to obtain the
+ output data.
+ - DK4_EDSTM_ERROR<br>
+ if an error occured.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS if enc is NULL.
+*/
+int
+dk4rle_add(dk4_rl_enc_t *enc, unsigned char ibyte, dk4_er_t *erp);
+
+/** Finish data stream, process final data still stored in the
+ encoder.
+ @param enc Encoder.
+ @param erp Error report, may be NULL.
+ @return Action to take, one from:
+ - DK4_EDSTM_ACCEPT<br>
+ if the input byte was successfully stored in the internal data
+ structures without completing a run. No further action
+ necessary.
+ - DK4_EDSTM_FINISHED<br>
+ if a run was completed. Use dk4rle_output() to obtain the
+ output data.
+ - DK4_EDSTM_ERROR<br>
+ if an error occured.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS if enc is NULL.
+*/
+int
+dk4rle_finish(dk4_rl_enc_t *enc, dk4_er_t *erp);
+
+/** Retrieve encoder output.
+ @param dptr Address of pointer to set to output bytes, should
+ be initialized to NULL.
+ @param szptr Address of size variable for buffer length,
+ should be initialized to 0.
+ @param enc Encoder.
+ @param erp Error report, may be NULL.
+ @return 1 if there is data available, 0 otherwise.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS if enc is NULL.
+*/
+int
+dk4rle_output(
+ const unsigned char **dptr, size_t *szptr, dk4_rl_enc_t *enc, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4serf.c b/support/dktools/dk4serf.c
new file mode 100644
index 0000000000..8f91d08db6
--- /dev/null
+++ b/support/dktools/dk4serf.c
@@ -0,0 +1,301 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4serf.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4serf.c The dk4serf module.
+*/
+
+
+#line 147 "dk4serf.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4serf.h"
+#include "dk4mem.h"
+#include "dk4mao8dbl.h"
+#include "dk4enc.h"
+#include "dk4maasz.h"
+#include "dk4rec03.h"
+#include "dk4rec05.h"
+#include "dk4rec12.h"
+#include "dk4rec18.h"
+
+
+
+
+#line 176 "dk4serf.ctr"
+
+
+
+int
+dk4serialize_file_uint16_t(FILE *fipo, uint16_t u, dk4_er_t *erp)
+{
+ unsigned char uc[4];
+ int back = 0;
+ if ((NULL != fipo) && (DK4_U16_MAX >= u)) {
+ uc[0] = (unsigned char)((u >> 8) & 0x00FFU);
+ uc[1] = (unsigned char)(u & 0x00FFU);
+ errno = 0;
+ if (2 == fwrite(uc, 1, 2, fipo)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_WRITE_FAILED, errno);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4serialize_file_int16_t(FILE *fipo, int16_t i, dk4_er_t *erp)
+{
+ unsigned char uc[4];
+ int back = 0;
+ if ((NULL != fipo) && (DK4_I16_MAX >= i) && (DK4_I16_MIN <= i)) {
+ uc[0] = (unsigned char)((((uint16_t)i) >> 8) & 0x00FFU);
+ uc[1] = (unsigned char)(((uint16_t)i) & 0x00FFU);
+ errno = 0;
+ if (2 == fwrite(uc, 1, 2, fipo)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_WRITE_FAILED, errno);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4serialize_file_uint32_t(FILE *fipo, uint32_t u, dk4_er_t *erp)
+{
+ unsigned char uc[4];
+ int back = 0;
+ if ((NULL != fipo) && (DK4_U32_MAX >= u)) {
+ uc[0] = (unsigned char)((u >> 24) & 0x000000FFUL);
+ uc[1] = (unsigned char)((u >> 16) & 0x000000FFUL);
+ uc[2] = (unsigned char)((u >> 8) & 0x000000FFUL);
+ uc[3] = (unsigned char)(u & 0x000000FFUL);
+ errno = 0;
+ if (4 == fwrite(uc, 1, 4, fipo)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_WRITE_FAILED, errno);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4serialize_file_int32_t(FILE *fipo, int32_t i, dk4_er_t *erp)
+{
+ unsigned char uc[4];
+ int back = 0;
+ if ((NULL != fipo) && (DK4_I32_MAX >= i) && (DK4_I32_MIN <= i)) {
+ uc[0] = (unsigned char)((((uint32_t)i) >> 24) & 0x000000FFUL);
+ uc[1] = (unsigned char)((((uint32_t)i) >> 16) & 0x000000FFUL);
+ uc[2] = (unsigned char)((((uint32_t)i) >> 8) & 0x000000FFUL);
+ uc[3] = (unsigned char)(((uint32_t)i) & 0x000000FFUL);
+ errno = 0;
+ if (4 == fwrite(uc, 1, 4, fipo)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_WRITE_FAILED, errno);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4serialize_file_utf8_string(FILE *fipo, const char *str, dk4_er_t *erp)
+{
+ dk4_er_t er;
+ size_t sz;
+ int back = 0;
+ uint16_t usz;
+
+ if ((NULL != fipo) && (NULL != str)) {
+ sz = strlen(str);
+ dk4error_init(&er);
+ sz = dk4ma_size_t_add(sz, 1, &er);
+ if (DK4_E_NONE == er.ec) {
+ if (((dk4_um_t)DK4_U16_MAX) >= ((dk4_um_t)sz)) {
+ usz = (uint16_t)sz;
+ if (0 != dk4serialize_file_uint16_t(fipo, usz, erp)) {
+ errno = 0;
+ if (fwrite(str, 1, usz, fipo) == usz) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_WRITE_FAILED, errno);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ dk4error_copy(erp, &er);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4serialize_file_double(FILE *fipo, double d, dk4_er_t *erp)
+{
+#if 64 > (2 * DK4_DBL_DIGITS)
+ char buffer[64];
+#else
+ char buffer[2 * DK4_DBL_DIGITS];
+#endif
+ int back = 0;
+ if (NULL != fipo) {
+ if (0 != dk4ma_write_c8_double(buffer, sizeof(buffer), d, 1, 1, erp)) {
+ back = dk4serialize_file_utf8_string(fipo, buffer, erp);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4serialize_file_dk_string(FILE *fipo,const dkChar *str,int de,dk4_er_t *erp)
+{
+ char *tmpbuf = NULL;
+ size_t szbuf = 0;
+ int back = 0;
+ if ((NULL != fipo) && (NULL != str)) {
+ switch (de) {
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ case DK4_ENCODING_32 : {
+ szbuf = dk4recode_size_c32_to_utf8(str, erp);
+ if (0 < szbuf) {
+ tmpbuf = dk4mem_new(char,szbuf,erp);
+ if (NULL != tmpbuf) {
+ if (0 != dk4recode_c32_to_utf8(tmpbuf, szbuf, str, erp)) {
+ back = dk4serialize_file_utf8_string(fipo, tmpbuf, erp);
+ }
+ dk4mem_free(tmpbuf);
+ }
+ }
+ } break;
+#else
+ case DK4_ENCODING_UTF16 : {
+ szbuf = dk4recode_size_utf16_to_utf8(str, erp);
+ if (0 < szbuf) {
+ tmpbuf = dk4mem_new(char,szbuf,erp);
+ if (NULL != tmpbuf) {
+ if (0 != dk4recode_utf16_to_utf8(tmpbuf, szbuf, str, erp)) {
+ back = dk4serialize_file_utf8_string(fipo, tmpbuf, erp);
+ }
+ dk4mem_free(tmpbuf);
+ }
+ }
+ } break;
+#endif
+#else
+ case DK4_ENCODING_ASCII : {
+ szbuf = dk4recode_size_ascii_to_utf8(str, erp);
+ if (0 < szbuf) {
+ tmpbuf = dk4mem_new(char,szbuf,erp);
+ if (NULL != tmpbuf) {
+ if (0 != dk4recode_ascii_to_utf8(tmpbuf, szbuf, str, erp)) {
+ back = dk4serialize_file_utf8_string(fipo, tmpbuf, erp);
+ }
+ dk4mem_free(tmpbuf);
+ }
+ }
+ } break;
+ case DK4_ENCODING_ANSI : {
+ szbuf = dk4recode_size_ansi_to_utf8(str, erp);
+ if (0 < szbuf) {
+ tmpbuf = dk4mem_new(char,szbuf,erp);
+ if (NULL != tmpbuf) {
+ if (0 != dk4recode_ansi_to_utf8(tmpbuf, szbuf, str, erp)) {
+ back = dk4serialize_file_utf8_string(fipo, tmpbuf, erp);
+ }
+ dk4mem_free(tmpbuf);
+ }
+ }
+ } break;
+ case DK4_ENCODING_UTF8 : {
+ back = dk4serialize_file_utf8_string(fipo, str, erp);
+ } break;
+#endif
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
diff --git a/support/dktools/dk4serf.ctr b/support/dktools/dk4serf.ctr
new file mode 100644
index 0000000000..3b7f444e2c
--- /dev/null
+++ b/support/dktools/dk4serf.ctr
@@ -0,0 +1,405 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+
+%% header
+
+/** @file dk4serf.h Serialize data to binary file.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef DK4_STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define DK4_STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef DK4_SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define DK4_SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDINT_H
+#ifndef DK4_STDINT_H_INCLUDED
+#include <stdint.h>
+#define DK4_STDINT_H_INCLUDED 1
+#endif
+#endif
+
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Serialize 16 bit unsigned int to file.
+ @param fipo Output file.
+ @param u Number to write.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fipo is NULL or u is out of range,
+ - DK4_E_WRITE_FAILED<br>
+ if fwrite() failed.
+*/
+int
+dk4serialize_file_uint16_t(FILE *fipo, uint16_t u, dk4_er_t *erp);
+
+/** Serialize 16 bit signed int to file.
+ @param fipo Output file.
+ @param i Number to write.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fipo is NULL or i is out of range,
+ - DK4_E_WRITE_FAILED<br>
+ if fwrite() failed.
+*/
+int
+dk4serialize_file_int16_t(FILE *fipo, int16_t i, dk4_er_t *erp);
+
+/** Serialize 32 bit unsigned int to file.
+ @param fipo Output file.
+ @param u Number to write.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fipo is NULL or u is out of range,
+ - DK4_E_WRITE_FAILED<br>
+ if fwrite() failed.
+*/
+int
+dk4serialize_file_uint32_t(FILE *fipo, uint32_t u, dk4_er_t *erp);
+
+/** Serialize 32 bit signed int to file.
+ @param fipo Output file.
+ @param i Number to write.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fipo is NULL or i is out of range,
+ - DK4_E_WRITE_FAILED<br>
+ if fwrite() failed.
+*/
+int
+dk4serialize_file_int32_t(FILE *fipo, int32_t i, dk4_er_t *erp);
+
+/** Serialize UTF-8 encoded string to file.
+ @param fipo Output file.
+ @param str String to write.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4serialize_file_utf8_string(FILE *fipo, const char *str, dk4_er_t *erp);
+
+/** Serialize dkChar string to file (convert to UTF-8).
+ @param fipo Output file.
+ @param str String to write.
+ @param de Encoding for dkChar strings.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4serialize_file_dk_string(FILE *fipo,const dkChar *str,int de,dk4_er_t *erp);
+
+/** Serialize double value to file.
+ The value is converted to string and saved as string, so you
+ may loose information.
+ @param fipo Output file.
+ @param d Value to write.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4serialize_file_double(FILE *fipo, double d, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4serf.h"
+#include "dk4mem.h"
+#include "dk4mao8dbl.h"
+#include "dk4enc.h"
+#include "dk4maasz.h"
+#include "dk4rec03.h"
+#include "dk4rec05.h"
+#include "dk4rec12.h"
+#include "dk4rec18.h"
+
+
+$!trace-include
+
+
+
+int
+dk4serialize_file_uint16_t(FILE *fipo, uint16_t u, dk4_er_t *erp)
+{
+ unsigned char uc[4];
+ int back = 0;
+ if ((NULL != fipo) && (DK4_U16_MAX >= u)) {
+ uc[0] = (unsigned char)((u >> 8) & 0x00FFU);
+ uc[1] = (unsigned char)(u & 0x00FFU);
+ errno = 0;
+ if (2 == fwrite(uc, 1, 2, fipo)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_WRITE_FAILED, errno);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4serialize_file_int16_t(FILE *fipo, int16_t i, dk4_er_t *erp)
+{
+ unsigned char uc[4];
+ int back = 0;
+ if ((NULL != fipo) && (DK4_I16_MAX >= i) && (DK4_I16_MIN <= i)) {
+ uc[0] = (unsigned char)((((uint16_t)i) >> 8) & 0x00FFU);
+ uc[1] = (unsigned char)(((uint16_t)i) & 0x00FFU);
+ errno = 0;
+ if (2 == fwrite(uc, 1, 2, fipo)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_WRITE_FAILED, errno);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4serialize_file_uint32_t(FILE *fipo, uint32_t u, dk4_er_t *erp)
+{
+ unsigned char uc[4];
+ int back = 0;
+ if ((NULL != fipo) && (DK4_U32_MAX >= u)) {
+ uc[0] = (unsigned char)((u >> 24) & 0x000000FFUL);
+ uc[1] = (unsigned char)((u >> 16) & 0x000000FFUL);
+ uc[2] = (unsigned char)((u >> 8) & 0x000000FFUL);
+ uc[3] = (unsigned char)(u & 0x000000FFUL);
+ errno = 0;
+ if (4 == fwrite(uc, 1, 4, fipo)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_WRITE_FAILED, errno);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4serialize_file_int32_t(FILE *fipo, int32_t i, dk4_er_t *erp)
+{
+ unsigned char uc[4];
+ int back = 0;
+ if ((NULL != fipo) && (DK4_I32_MAX >= i) && (DK4_I32_MIN <= i)) {
+ uc[0] = (unsigned char)((((uint32_t)i) >> 24) & 0x000000FFUL);
+ uc[1] = (unsigned char)((((uint32_t)i) >> 16) & 0x000000FFUL);
+ uc[2] = (unsigned char)((((uint32_t)i) >> 8) & 0x000000FFUL);
+ uc[3] = (unsigned char)(((uint32_t)i) & 0x000000FFUL);
+ errno = 0;
+ if (4 == fwrite(uc, 1, 4, fipo)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_WRITE_FAILED, errno);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4serialize_file_utf8_string(FILE *fipo, const char *str, dk4_er_t *erp)
+{
+ dk4_er_t er;
+ size_t sz;
+ int back = 0;
+ uint16_t usz;
+
+ if ((NULL != fipo) && (NULL != str)) {
+ sz = strlen(str);
+ dk4error_init(&er);
+ sz = dk4ma_size_t_add(sz, 1, &er);
+ if (DK4_E_NONE == er.ec) {
+ if (((dk4_um_t)DK4_U16_MAX) >= ((dk4_um_t)sz)) {
+ usz = (uint16_t)sz;
+ if (0 != dk4serialize_file_uint16_t(fipo, usz, erp)) {
+ errno = 0;
+ if (fwrite(str, 1, usz, fipo) == usz) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_WRITE_FAILED, errno);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ dk4error_copy(erp, &er);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4serialize_file_double(FILE *fipo, double d, dk4_er_t *erp)
+{
+#if 64 > (2 * DK4_DBL_DIGITS)
+ char buffer[64];
+#else
+ char buffer[2 * DK4_DBL_DIGITS];
+#endif
+ int back = 0;
+ if (NULL != fipo) {
+ if (0 != dk4ma_write_c8_double(buffer, sizeof(buffer), d, 1, 1, erp)) {
+ back = dk4serialize_file_utf8_string(fipo, buffer, erp);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4serialize_file_dk_string(FILE *fipo,const dkChar *str,int de,dk4_er_t *erp)
+{
+ char *tmpbuf = NULL;
+ size_t szbuf = 0;
+ int back = 0;
+ if ((NULL != fipo) && (NULL != str)) {
+ switch (de) {
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ case DK4_ENCODING_32 : {
+ szbuf = dk4recode_size_c32_to_utf8(str, erp);
+ if (0 < szbuf) {
+ tmpbuf = dk4mem_new(char,szbuf,erp);
+ if (NULL != tmpbuf) {
+ if (0 != dk4recode_c32_to_utf8(tmpbuf, szbuf, str, erp)) {
+ back = dk4serialize_file_utf8_string(fipo, tmpbuf, erp);
+ }
+ dk4mem_free(tmpbuf);
+ }
+ }
+ } break;
+#else
+ case DK4_ENCODING_UTF16 : {
+ szbuf = dk4recode_size_utf16_to_utf8(str, erp);
+ if (0 < szbuf) {
+ tmpbuf = dk4mem_new(char,szbuf,erp);
+ if (NULL != tmpbuf) {
+ if (0 != dk4recode_utf16_to_utf8(tmpbuf, szbuf, str, erp)) {
+ back = dk4serialize_file_utf8_string(fipo, tmpbuf, erp);
+ }
+ dk4mem_free(tmpbuf);
+ }
+ }
+ } break;
+#endif
+#else
+ case DK4_ENCODING_ASCII : {
+ szbuf = dk4recode_size_ascii_to_utf8(str, erp);
+ if (0 < szbuf) {
+ tmpbuf = dk4mem_new(char,szbuf,erp);
+ if (NULL != tmpbuf) {
+ if (0 != dk4recode_ascii_to_utf8(tmpbuf, szbuf, str, erp)) {
+ back = dk4serialize_file_utf8_string(fipo, tmpbuf, erp);
+ }
+ dk4mem_free(tmpbuf);
+ }
+ }
+ } break;
+ case DK4_ENCODING_ANSI : {
+ szbuf = dk4recode_size_ansi_to_utf8(str, erp);
+ if (0 < szbuf) {
+ tmpbuf = dk4mem_new(char,szbuf,erp);
+ if (NULL != tmpbuf) {
+ if (0 != dk4recode_ansi_to_utf8(tmpbuf, szbuf, str, erp)) {
+ back = dk4serialize_file_utf8_string(fipo, tmpbuf, erp);
+ }
+ dk4mem_free(tmpbuf);
+ }
+ }
+ } break;
+ case DK4_ENCODING_UTF8 : {
+ back = dk4serialize_file_utf8_string(fipo, str, erp);
+ } break;
+#endif
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
diff --git a/support/dktools/dk4serf.h b/support/dktools/dk4serf.h
new file mode 100644
index 0000000000..6ba897037d
--- /dev/null
+++ b/support/dktools/dk4serf.h
@@ -0,0 +1,180 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4serf.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4SERF_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4SERF_H_INCLUDED 1
+
+
+#line 9 "dk4serf.ctr"
+
+/** @file dk4serf.h Serialize data to binary file.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef DK4_STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define DK4_STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef DK4_SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define DK4_SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDINT_H
+#ifndef DK4_STDINT_H_INCLUDED
+#include <stdint.h>
+#define DK4_STDINT_H_INCLUDED 1
+#endif
+#endif
+
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Serialize 16 bit unsigned int to file.
+ @param fipo Output file.
+ @param u Number to write.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fipo is NULL or u is out of range,
+ - DK4_E_WRITE_FAILED<br>
+ if fwrite() failed.
+*/
+int
+dk4serialize_file_uint16_t(FILE *fipo, uint16_t u, dk4_er_t *erp);
+
+/** Serialize 16 bit signed int to file.
+ @param fipo Output file.
+ @param i Number to write.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fipo is NULL or i is out of range,
+ - DK4_E_WRITE_FAILED<br>
+ if fwrite() failed.
+*/
+int
+dk4serialize_file_int16_t(FILE *fipo, int16_t i, dk4_er_t *erp);
+
+/** Serialize 32 bit unsigned int to file.
+ @param fipo Output file.
+ @param u Number to write.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fipo is NULL or u is out of range,
+ - DK4_E_WRITE_FAILED<br>
+ if fwrite() failed.
+*/
+int
+dk4serialize_file_uint32_t(FILE *fipo, uint32_t u, dk4_er_t *erp);
+
+/** Serialize 32 bit signed int to file.
+ @param fipo Output file.
+ @param i Number to write.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fipo is NULL or i is out of range,
+ - DK4_E_WRITE_FAILED<br>
+ if fwrite() failed.
+*/
+int
+dk4serialize_file_int32_t(FILE *fipo, int32_t i, dk4_er_t *erp);
+
+/** Serialize UTF-8 encoded string to file.
+ @param fipo Output file.
+ @param str String to write.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4serialize_file_utf8_string(FILE *fipo, const char *str, dk4_er_t *erp);
+
+/** Serialize dkChar string to file (convert to UTF-8).
+ @param fipo Output file.
+ @param str String to write.
+ @param de Encoding for dkChar strings.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4serialize_file_dk_string(FILE *fipo,const dkChar *str,int de,dk4_er_t *erp);
+
+/** Serialize double value to file.
+ The value is converted to string and saved as string, so you
+ may loose information.
+ @param fipo Output file.
+ @param d Value to write.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4serialize_file_double(FILE *fipo, double d, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4sock.h b/support/dktools/dk4sock.h
new file mode 100644
index 0000000000..91ba45fe17
--- /dev/null
+++ b/support/dktools/dk4sock.h
@@ -0,0 +1,2765 @@
+#ifndef DK4SOCK_H_INCLUDED
+/** Protection against multiple inclusions. */
+#define DK4SOCK_H_INCLUDED 1
+
+/** @file dk4sock.h Socket functions.
+
+The functions in this module are for both networking and local UNIX
+domain sockets.
+
+Use dk4socket_up() before using any other function shown here, use
+dk4socket_down() to release the socket subsystem when you are done.
+These functions simply indicate success on POSIX systems but
+are required for subsystem initialization and release on Windows.
+
+Exception: dk4socket_htons(), dk4socket_ntohs(), dk4socket_htonl()
+and dk4socket_ntohl() and some other bit/byte handling functions
+can be used without calling dk4socket_up() before.
+
+Errors from the systems native socket functions are stored in errno
+on POSIX systems. On Windows you can use WSAGetLastError() to find
+an error code.
+The dk4socket_error_reset(), dk4socket_error_get() and dk4socket_error_report()
+functions are used to hide this difference.
+
+
+*/
+#include "dk4conf.h"
+
+
+
+#if DK4_ON_WINDOWS
+
+#if DK4_HAVE_WINSOCK2_H
+#ifndef WINSOCK2_H_INCLUDED
+#include <winsock2.h>
+#define WINSOCK2_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_WS2TCPIP_H
+#ifndef WS2TCPIP_H_INCLUDED
+#include <ws2tcpip.h>
+#define WS2TCPIP_H_INCLUDED
+#endif
+#endif
+
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+
+#endif
+/* if DK4_ON_WINDOWS*/
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_SOCKET_H
+#ifndef SYS_SOCKET_H_INCLUDED
+#include <sys/socket.h>
+#define SYS_SOCKET_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_UN_H
+#ifndef SYS_UN_H_INCLUDED
+#include <sys/un.h>
+#define SYS_UN_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ARPA_INET_H
+#ifndef ARPA_INET_H_INCLUDED
+#include <arpa/inet.h>
+#define ARPA_INET_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_NETINET_IN_H
+#ifndef NETINET_IN_H_INCLUDED
+#include <netinet/in.h>
+#define NETINET_IN_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_NETINET_IN6_H
+#ifndef NETINET_IN6_H_INCLUDED
+#include <netinet/in6.h>
+#define NETINET_IN6_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_NETDB_H
+#ifndef NETDB_H_INCLUDED
+#include <netdb.h>
+#define NETDB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_ON_WINDOWS
+/** Data type for sockets. */
+typedef SOCKET dk4_socket_t;
+#else
+/** Data type for sockets. */
+typedef int dk4_socket_t;
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+/** Set of sockets, for listening or for receiving datagrams.
+*/
+typedef struct {
+ dk4_socket_t *pSockets; /**< Array of sockets. */
+ size_t szMax; /**< Array size allocated, no of sockets. */
+ size_t szUsed; /**< Number of used sockets in array. */
+} dk4_socket_set_t;
+
+
+#if !DK4_HAVE_IN_ADDR
+/** IPv4 internet address.
+*/
+typedef struct in_addr IN_ADDR;
+#endif
+
+
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+#if !DK4_HAVE_IN6_ADDR
+/** IPv6 internet address.
+*/
+typedef struct in6_addr IN6_ADDR;
+#endif
+#endif
+
+
+/** Allowed IPv4 peer address or address range.
+*/
+typedef struct {
+ IN_ADDR ad; /**< Address or address base. */
+ IN_ADDR ma; /**< Net mask. */
+} dk4_allowed_peer_ipv4_t;
+
+
+
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+/** Allowed IPv6 peer address or address range.
+*/
+typedef struct {
+ IN6_ADDR ad; /**< Address or address base. */
+ IN6_ADDR ma; /**< Net mask. */
+} dk4_allowed_peer_ipv6_t;
+#endif
+
+
+
+/** Allowed IPv6 or IPv4 peer address or range.
+*/
+typedef struct {
+ int af; /**< Addr family AF_INET or AF_INET6. */
+ union {
+ dk4_allowed_peer_ipv4_t ipv4; /**< IPv4 peer data. */
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ dk4_allowed_peer_ipv6_t ipv6; /**< IPv6 peer data. */
+#endif
+ } data; /**< Peer data. */
+} dk4_allowed_peer_t;
+
+
+
+#if DK4_HAVE_SOCKADDR_STORAGE
+/** Buffer large enough to hold all sockaddr_xxx structures.
+*/
+typedef struct sockaddr_storage dk4_sockaddr_storage_t;
+#else
+/** Buffer large enough to hold all sockaddr_xxx structures.
+*/
+typedef union {
+ struct sockaddr sa; /**< Default sockaddr. */
+ struct sockaddr_in i4; /**< IPv4 address. */
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ struct sockaddr_in6 i6; /**< IPv6 address. */
+#endif
+#if DK4_HAVE_STRUCT_SOCKADDR_UN
+ struct sockaddr_un su; /**< UNIX domain socket address. */
+#endif
+} dk4_sockaddr_storage_t;
+#endif
+
+/** Operation result values.
+*/
+enum {
+ /** The operation failed.
+ */
+ DK4_SOCKET_RESULT_FAILED = -1,
+
+ /** The operation is still in progress,
+ not yet finished.
+ */
+ DK4_SOCKET_RESULT_IN_PROGRESS = 0,
+
+ /** The operation succeeded.
+ */
+ DK4_SOCKET_RESULT_SUCCESS = 1
+};
+
+
+#if DK4_ON_WINDOWS
+/** How to shut down a socket.
+*/
+enum {
+ /** Shut down read (receive) operations.
+ */
+ DK4_SOCKET_SHUT_READ = SD_RECEIVE ,
+
+ /** Shut down write (send) operations.
+ */
+ DK4_SOCKET_SHUT_WRITE = SD_SEND ,
+
+ /** Shut down both.
+ */
+ DK4_SOCKET_SHUT_RDWR = SD_BOTH
+};
+#else
+/** How to shut down a socket.
+*/
+enum {
+ /** Shut down read (receive) operations.
+ */
+ DK4_SOCKET_SHUT_READ = SHUT_RD ,
+
+ /** Shut down write (send) operations.
+ */
+ DK4_SOCKET_SHUT_WRITE = SHUT_WR ,
+
+ /** Shut down both.
+ */
+ DK4_SOCKET_SHUT_RDWR = SHUT_RDWR
+};
+#endif
+
+
+#ifndef INVALID_SOCKET
+/** Special socket values.
+*/
+enum {
+ /** Invalid socket.
+ */
+ INVALID_SOCKET = -1
+};
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ Error reporting.
+ ----------------
+ Module: dk4sock01
+*/
+
+/** Reset error code variable (either errno or WSAGetLastError()).
+*/
+void
+dk4socket_error_reset(void);
+
+/** Get error code (either from errno or via WSAGetLastError()).
+ @return Error code.
+*/
+int
+dk4socket_error_get(void);
+
+/** Note error in error report, use error details from either
+ errno or WSAGetLastError().
+ @param erp Error report to fill.
+ @param ec Error code DK4_E_xxx.
+*/
+void
+dk4socket_error_report(dk4_er_t *erp, int ec);
+
+/** Write IP address to debug output file.
+ For internal use only.
+ @param text Text to show before address.
+ @param addr Start of address buffer.
+ @param sz Size of address.
+*/
+void
+dk4socket_debug_address(const char *text, struct sockaddr *addr, size_t sz);
+
+
+#if (DK4_HAVE_SETSOCKOPT) && defined(SOL_SOCKET) && defined(SO_ERROR)
+
+/** Check integer result from getsockopt() for non-null value.
+ On some systems the getsockopt() function writes an int value for
+ boolean flags, a simple byte is used on other systems.
+ After calling getsockopt() you can use this function to check
+ boolean values for true or false.
+ @param optval The value stored in an int variable by getsockopt().
+ @param slo The length stored in the size variable.
+ @return 1 for non-null value, 0 for 0 value.
+*/
+int
+dk4socket_non_null_getsockopt(int optval, socklen_t slo);
+
+#endif
+
+/*
+ Long and short conversion between network and host representation.
+ ------------------------------------------------------------------
+ Module: dk4sock02
+*/
+
+/** Convert short from host to network representation.
+ Does not require dk4socket_up() to be called before.
+ @param u Value to convert.
+ @return Conversion result.
+*/
+uint16_t
+dk4socket_htons(uint16_t u);
+
+/** Convert short from network to host representation.
+ Does not require dk4socket_up() to be called before.
+ @param u Value to convert.
+ @return Conversion result.
+*/
+uint16_t
+dk4socket_ntohs(uint16_t u);
+
+/** Convert long from host to network representation.
+ Does not require dk4socket_up() to be called before.
+ @param u Value to convert.
+ @return Conversion result.
+*/
+uint32_t
+dk4socket_htonl(uint32_t u);
+
+/** Convert long from network to host representation.
+ Does not require dk4socket_up() to be called before.
+ @param u Value to convert.
+ @return Conversion result.
+*/
+uint32_t
+dk4socket_ntohl(uint32_t u);
+
+/** Change byte order for arbitrary data types, if the
+ Does not require dk4socket_up() to be called before.
+ systems byte order is not big-endian.
+ Does not require dk4socket_up() to be called before.
+ @param buf Address of variable.
+ @param sz Size of variable.
+*/
+void
+dk4socket_swap_bytes_if_not_bigendian(void *buf, size_t sz);
+
+/** Create a netmask in host representation for a given bit number.
+ Does not require dk4socket_up() to be called before.
+ @param dptr Address of destination variable.
+ @param sz Number of bits to set.
+ @param erp Error report, may be NULL.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if inp is NULL,
+ - DK4_E_SYNTAX<br>
+ if the number of bits is out of range.
+*/
+int
+dk4socket_mask_bits(unsigned long *dptr, size_t sz, dk4_er_t *erp);
+
+/** Set all bytes to 0x01.
+ Does not require dk4socket_up() to be called before.
+ @param ptr Pointer to variable.
+ @param nbytes Number of bytes in variable.
+*/
+void
+dk4socket_set_one_bytes(void *ptr, size_t nbytes);
+
+
+
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+
+/** Create IPv6 netmask in network representation.
+ @param inp Address of destination variable.
+ @param sz Number of bits to set (1 to 128).
+ @param erp Error report, may be NULL.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if inp is NULL,
+ - DK4_E_SYNTAX<br>
+ if the number of bits is out of range.
+*/
+int
+dk4socket_mask6_bits(struct in6_addr *inp, size_t sz, dk4_er_t *erp);
+
+#endif
+
+
+
+#if DK4_HAVE_STRUCT_SOCKADDR_UN
+
+/** Find socket address length for local UNIX domain socket.
+ For UNIX sockets the address size is not the size of
+ struct sockaddr_un, only the used part of the file name
+ buffer is counted.
+ @param sock Pointer to socket address structure.
+ @return Number of bytes used by address.
+*/
+size_t
+dk4socket_unix_length(const struct sockaddr_un *sock);
+
+#endif
+
+/** Get protocol family for address family.
+ @param af Address family.
+ @return Protocol family on success, PF_UNSPEC on error.
+*/
+int
+dk4socket_pf_for_af(int af);
+
+/** Check address length, correct if necessary.
+ This function allows to pass a dk4_sockaddr_storage_t
+ address and sizeof(dk4_sockaddr_storage_t), the
+ dk4socket_bind(), dk4socket_connect() and dk4socket_sendto()
+ use the correct size for the address family stored.
+ @param soa Socket address.
+ @param plgt Address of length variable.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4socket_correct_addr_lgt(const struct sockaddr *soa, size_t *plgt);
+
+/*
+ Convert addresses to text and vice versa.
+ -----------------------------------------
+ Module: dk4sock03
+*/
+
+/** Convert address to text representation (char).
+ @param dptr Destination buffer address.
+ @param dsz Destination buffer size.
+ @param afam Address family (AF_INET or AF_INET6).
+ @param src Pointer to struct in_addr or struct in6_addr.
+ @param erp Error report, may be NULL.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error.
+
+ Restriction: If the inet_ntop() function is not available
+ (i.e. on Windows with DK4_WINDOWS_LEGACY enabled) IPv6 adddresses
+ containing zero sequences are not abbreviated using ``::''.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or src is NULL, dsz is 0 or afam is an invalid family,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the output buffer is too small,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in size calculations,
+ - DK4_E_SOCKET_INET_NTOP<br>
+ if the inet_ntop() function failed (details in iDetails1).
+*/
+int
+dk4socket_c8_inet_ntop(
+ char *dptr,
+ size_t dsz,
+ int afam,
+ const void *src,
+ dk4_er_t *erp
+);
+
+/** Convert IP address including port number to char text.
+ @param dptr Destination buffer address.
+ @param dsz Destination buffer size.
+ @param afam Address family.
+ @param saptr Address buffer.
+ @param sasz Address size.
+ @param erp Error report, may be NULL.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error.
+
+ Restriction: If neither the getnameinfo() nor the inet_ntop()
+ function is available (i.e. on Windows with DK4_WINDOWS_LEGACY
+ enabled) IPv6 adddresses containing zero sequences are
+ not abbreviated using ``::''.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS
+ - DK4_SOCKET_GETADDRINFO
+ - DK4_E_BUFFER_TOO_SMALL
+*/
+int
+dk4socket_c8_addr_port_to_text(
+ char *dptr,
+ size_t dsz,
+ int afam,
+ const struct sockaddr *saptr,
+ size_t sasz,
+ dk4_er_t *erp
+);
+
+/** Convert generic socket address structure to char text.
+ @param dptr Destination buffer address.
+ @param dsz Destination buffer size.
+ @param saptr Pointer to socket address structure.
+ @param erp Error report, may be NULL.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error.
+
+ Restriction: If neither the getnameinfo() nor the inet_ntop()
+ function is available (i.e. on Windows with DK4_WINDOWS_LEGACY
+ enabled) IPv6 adddresses containing zero sequences are
+ not abbreviated using ``::''.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS
+ - DK4_E_SOCKET_GETADDRINFO
+ - DK4_E_SYNTAX
+ - DK4_E_BUFFER_TOO_SMALL
+*/
+int
+dk4socket_c8_sockaddr_to_text(
+ char *dptr,
+ size_t dsz,
+ const dk4_sockaddr_storage_t *saptr,
+ dk4_er_t *erp
+);
+
+/*
+ Convert addresses to text and vice versa.
+ -----------------------------------------
+ Module: dk4sock04
+*/
+
+/** Convert address to text representation (wchar_t).
+ @param dptr Destination buffer address.
+ @param dsz Destination buffer size (number of wchar_t).
+ @param afam Address family (AF_INET or AF_INET6).
+ @param src Pointer to struct in_addr or struct in6_addr.
+ @param erp Error report, may be NULL.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error.
+
+ Restriction: If the inet_ntop() function is not available
+ (i.e. on Windows with DK4_WINDOWS_LEGACY enabled) IPv6 adddresses
+ containing zero sequences are not abbreviated using ``::''.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or src is NULL, dsz is 0 or afam is an invalid family,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the output buffer is too small,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in size calculations,
+ - DK4_E_SOCKET_INET_NTOP<br>
+ if the inet_ntop() function failed (details in iDetails1),
+ - DK4_E_NOT_SUPPORTED<br>
+ if there is not wchar_t support.
+*/
+int
+dk4socket_wc_inet_ntop(
+ wchar_t *dptr,
+ size_t dsz,
+ int afam,
+ const void *src,
+ dk4_er_t *erp
+);
+
+/** Convert IP address including port number to wchar_t text.
+ @param dptr Destination buffer address.
+ @param dsz Destination buffer size (number of wchar_t).
+ @param afam Address family.
+ @param saptr Address buffer.
+ @param sasz Address size.
+ @param erp Error report, may be NULL.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error.
+
+ Restriction: If neither the getnameinfo() nor the inet_ntop()
+ function is available (i.e. on Windows with DK4_WINDOWS_LEGACY
+ enabled) IPv6 adddresses containing zero sequences are
+ not abbreviated using ``::''.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS
+ - DK4_SOCKET_GETADDRINFO
+ - DK4_E_BUFFER_TOO_SMALL
+ - DK4_E_NOT_SUPPORTED
+*/
+int
+dk4socket_wc_addr_port_to_text(
+ wchar_t *dptr,
+ size_t dsz,
+ int afam,
+ const struct sockaddr *saptr,
+ size_t sasz,
+ dk4_er_t *erp
+);
+
+/** Convert generic socket address structure to wchar_t text.
+ @param dptr Destination buffer address.
+ @param dsz Destination buffer size (Number of wchar_t).
+ @param saptr Pointer to socket address structure.
+ @param erp Error report, may be NULL.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error.
+
+ Restriction: If neither the getnameinfo() nor the inet_ntop()
+ function is available (i.e. on Windows with DK4_WINDOWS_LEGACY
+ enabled) IPv6 adddresses containing zero sequences are
+ not abbreviated using ``::''.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS
+ - DK4_E_SOCKET_GETADDRINFO
+ - DK4_E_SYNTAX
+ - DK4_E_BUFFER_TOO_SMALL
+*/
+int
+dk4socket_wc_sockaddr_to_text(
+ wchar_t *dptr,
+ size_t dsz,
+ const dk4_sockaddr_storage_t *saptr,
+ dk4_er_t *erp
+);
+
+/*
+ Convert addresses to text and vice versa.
+ -----------------------------------------
+ Module: dk4sock05
+*/
+
+/** Convert address to text representation (dkChar).
+ @param dptr Destination buffer address.
+ @param dsz Destination buffer size (number of dkChar).
+ @param afam Address family (AF_INET or AF_INET6).
+ @param src Pointer to struct in_addr or struct in6_addr.
+ @param erp Error report, may be NULL.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error.
+
+ Restriction: If the inet_ntop() function is not available
+ (i.e. on Windows with DK4_WINDOWS_LEGACY enabled) IPv6 adddresses
+ containing zero sequences are not abbreviated using ``::''.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or src is NULL, dsz is 0 or afam is an invalid family,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the output buffer is too small,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in size calculations,
+ - DK4_E_SOCKET_INET_NTOP<br>
+ if the inet_ntop() function failed (details in iDetails1).
+*/
+int
+dk4socket_inet_ntop(
+ dkChar *dptr,
+ size_t dsz,
+ int afam,
+ const void *src,
+ dk4_er_t *erp
+);
+
+/** Convert IP address including port number to dkChar text.
+ @param dptr Destination buffer address.
+ @param dsz Destination buffer size (number of dkChar).
+ @param afam Address family.
+ @param saptr Address buffer.
+ @param sasz Address size.
+ @param erp Error report, may be NULL.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error.
+
+ Restriction: If neither the getnameinfo() nor the inet_ntop()
+ function is available (i.e. on Windows with DK4_WINDOWS_LEGACY
+ enabled) IPv6 adddresses containing zero sequences are
+ not abbreviated using ``::''.
+*/
+int
+dk4socket_addr_port_to_text(
+ dkChar *dptr,
+ size_t dsz,
+ int afam,
+ const struct sockaddr *saptr,
+ size_t sasz,
+ dk4_er_t *erp
+);
+
+/** Convert generic socket address structure to dkChar text.
+ @param dptr Destination buffer address.
+ @param dsz Destination buffer size (Number of dkChar).
+ @param saptr Pointer to socket address structure.
+ @param erp Error report, may be NULL.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error.
+
+ Restriction: If neither the getnameinfo() nor the inet_ntop()
+ function is available (i.e. on Windows with DK4_WINDOWS_LEGACY
+ enabled) IPv6 adddresses containing zero sequences are
+ not abbreviated using ``::''.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS
+ - DK4_E_SOCKET_GETADDRINFO
+ - DK4_E_SYNTAX
+ - DK4_E_BUFFER_TOO_SMALL
+*/
+int
+dk4socket_sockaddr_to_text(
+ dkChar *dptr,
+ size_t dsz,
+ const dk4_sockaddr_storage_t *saptr,
+ dk4_er_t *erp
+);
+
+/*
+ Convert text to IP address (char).
+ ----------------------------------
+ Module: dk4sock06
+*/
+
+/** Convert text IP address to struct in_addr or struct in6_addr.
+ @param pAddr Pointer to destination buffer.
+ @param szAddr Destination buffer size.
+ @param afam Address family (AF_INET or AF_INET6).
+ @param src Source text.
+ @param erp Error report, may be NULL.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if pAddr or src is NULL or szAddr is 0, or szAddr does not have
+ the correct size for the specified family,
+ - DK4_E_SYNTAX<br>
+ if src does not contain a valid IPv4 or IPv6 address,
+ - DK4_E_SOCKET_INET_PTON<br>
+ if the inet_pton() function failed for some reason.
+*/
+int
+dk4socket_c8_inet_pton(
+ void *pAddr,
+ size_t szAddr,
+ int afam,
+ const char *src,
+ dk4_er_t *erp
+);
+
+/*
+ Convert text to IP address (wchar_t).
+ -------------------------------------
+ Module: dk4sock07
+*/
+
+/** Convert text IP address to struct in_addr or struct in6_addr.
+ @param pAddr Pointer to destination buffer.
+ @param szAddr Destination buffer size.
+ @param afam Address family (AF_INET or AF_INET6).
+ @param src Source text.
+ @param erp Error report, may be NULL.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if pAddr or src is NULL or szAddr is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if src is too long for conversion into an internal buffer,
+ - DK4_E_SYNTAX<br>
+ if src contains non-ASCII characters or is not a valid
+ IPv6 or IPv6 address,
+ - DK4_E_SOCKET_INET_PTON<br>
+ if InetPtonW() fails for some reason.
+*/
+int
+dk4socket_wc_inet_pton(
+ void *pAddr,
+ size_t szAddr,
+ int afam,
+ const wchar_t *src,
+ dk4_er_t *erp
+);
+
+/*
+ Convert text to IP address (dkChar).
+ ------------------------------------
+ Module: dk4sock08
+*/
+
+/** Convert text IP address to struct in_addr or struct in6_addr.
+ @param pAddr Pointer to destination buffer.
+ @param szAddr Destination buffer size.
+ @param afam Address family (AF_INET or AF_INET6).
+ @param src Source text.
+ @param erp Error report, may be NULL.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if pAddr or src is NULL or szAddr is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if src is too long for conversion into an internal buffer,
+ - DK4_E_SYNTAX<br>
+ if src contains non-ASCII characters or is not a valid
+ IPv6 or IPv6 address,
+ - DK4_E_SOCKET_INET_PTON<br>
+ if inet_pton() or InetPtonW() fails for some reason.
+*/
+int
+dk4socket_inet_pton(
+ void *pAddr,
+ size_t szAddr,
+ int afam,
+ const dkChar *src,
+ dk4_er_t *erp
+);
+
+/*
+ Bring socket subsystem up and down.
+ -----------------------------------
+ Module: dk4sock09
+*/
+/** Bring socket subsystem up.
+ This function calls WSAStartup() on Windows, simply indicates
+ success on all other systems.
+ @param er Error report, may be NULL.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error.
+
+ Error codes:
+ * DK4_E_SOCKET_UP<br>
+ with WSAGetLastError() result in iDetails1 if a WinSock
+ error occured.
+*/
+int
+dk4socket_up(dk4_er_t *er);
+
+/** Bring socket subsystem down.
+ This function calls WSACleanup() on Windows, simply indicates
+ success on all other systems.
+ @param er Error report, may be NULL.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error.
+
+ Error codes:
+ * DK4_E_SOCKET_DOWN<br>
+ with WSAGetLastError() result in iDetails1 if a WinSock
+ error occured.
+*/
+int
+dk4socket_down(dk4_er_t *er);
+
+/*
+ Basic socket operations (open and close).
+ -----------------------------------------
+ Module: dk4sock10
+*/
+
+/** Open a socket.
+ @param af Address family (AF_INET or AF_INET6).
+ @param tp Socket type (SOCK_STREAM or SOCK_DGRAM).
+ @param pr Protocol (0).
+ @param erp Error report, may be NULL.
+ @return New socket on success, INVALID_SOCKET on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if af is not one from AF_INET, AF_INET6, AF_UNIX, or AF_LOCAL
+ or tp is not one from SOCK_STREAM or SOCK_DGRAM or pr is
+ not 0,
+ - DK4_E_SOCKET_SOCKET<br>
+ with errno/WSAGetLastError() value in iDetails1 if
+ the socket() function failed.
+*/
+dk4_socket_t
+dk4socket_open(int af, int tp, int pr, dk4_er_t *erp);
+
+/** Shut down socket.
+ @param so Socket to shut down.
+ @param how Choose tasks to end, one from:
+ DK4_SOCKET_SHUT_READ to stop reading (receiving),
+ DK4_SOCKET_SHUT_WRITE to stop writing (sending), or
+ DK4_SOCKET_SHUT_RDWR to stop both.
+ @param erp Error report, may be NULL.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error.
+*/
+int
+dk4socket_shutdown(dk4_socket_t so, int how, dk4_er_t *erp);
+
+/** Close a socket.
+ @param so Socket to close.
+ @param erp Error report, may be NULL.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if af is not one from AF_INET, AF_INET6, AF_UNIX, or AF_LOCAL
+ or tp is not one from SOCK_STREAM or SOCK_DGRAM or pr is
+ not 0,
+ - DK4_E_SOCKET_CLOSE<br>
+ with errno/WSAGetLastError() value in iDetails1 if
+ the close()/closesocket() function failed.
+*/
+int
+dk4socket_close(dk4_socket_t so, dk4_er_t *erp);
+
+/*
+ Address binding.
+ ----------------
+ Module: dk4sock11
+*/
+
+/** Bind a local address.
+ @param sock Socket to configure.
+ @param pAddr Pointer to socket address buffer.
+ @param szAddr Size of socket address buffer.
+ @param erp Error report, may be NULL.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if the address pointer is NULL or the address size is 0,
+ - DK4_E_SOCKET_BIND<br>
+ with errno/WSAGetLastError() value in iDetails1 if the
+ bind() function failed.
+*/
+int
+dk4socket_bind(
+ dk4_socket_t sock,
+ const struct sockaddr *pAddr,
+ size_t szAddr,
+ dk4_er_t *erp
+);
+
+/*
+ Client side: connecting to remote server.
+ -----------------------------------------
+ Module: dk4sock12
+*/
+
+/** Connect to remote server.
+ @param sock Socket to configure.
+ @param pAddr Pointer to remote socket address buffer.
+ @param szAddr Size of remote socket address buffer.
+ @param erp Error report, may be NULL.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_IN_PROGRESS if the operation is still in progress,
+ DK4_SOCKET_RESULT_FAILED on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if remote address pointer is NULL or remote address size is 0,
+ - DK4_E_SOCKET_CONNECT<br>
+ with errno/WSAGetLastError() value in iDetails1 if the
+ connect() function failed.
+*/
+int
+dk4socket_connect(
+ dk4_socket_t sock,
+ const struct sockaddr *pAddr,
+ size_t szAddr,
+ dk4_er_t *erp
+);
+
+#if DK4_HAVE_STRUCT_SOCKADDR_UN
+
+/** Create a UNIX domain socket in client mode.
+ @param filename File name, max 107 characters long.
+ @param erp Error report, may be NULL.
+ @return Valid socket on success, INVALID_SOCKET on error.
+*/
+dk4_socket_t
+dk4socket_c8_unix_client(
+ const char *filename,
+ dk4_er_t *erp
+);
+
+#endif
+
+/*
+ Server side: listen and accept.
+ -------------------------------
+ Module: dk4sock13
+*/
+
+/** Listen on a socket.
+ @param sock Socket to configure for listening.
+ @param bl Backlog (Number of connections requests to queue).
+ @param erp Error report, may be NULL.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if any argument is bad,
+ - DK4_E_SOCKET_LISTEN<br>
+ with errno/WSAGetLastError() value in iDetails1 if the
+ listen() function failed.
+*/
+int
+dk4socket_listen(
+ dk4_socket_t sock,
+ int bl,
+ dk4_er_t *erp
+);
+
+/** Accept incoming connection requests on listener socket.
+ @param sock Listener socket.
+ @param pAddr Pointer to address buffer, address of a
+ dk4_sockaddr_storage_t recommended, NULL allowed.
+ @param pSzAddr Pointer to address buffer size variable,
+ in: buffer size,
+ out: used size, should be NULL if pAddr is NULL.
+ @param erp Error report, may be NULL.
+ @return Socket for new connection on success, INVALID_SOCKET
+ on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if any argument is bad,
+ - DK4_E_SOCKET_ACCEPT<br>
+ with errno/WSAGetLastError() value in iDetails1 if the
+ accept() function failed.
+*/
+dk4_socket_t
+dk4socket_accept(
+ dk4_socket_t sock,
+ struct sockaddr *pAddr,
+ size_t *pSzAddr,
+ dk4_er_t *erp
+);
+
+#if DK4_HAVE_STRUCT_SOCKADDR_UN
+
+/** Create a UNIX domain socket in listening state.
+ @param filename File name, max 107 characters long.
+ @param backlog Number of connection requests to queue.
+ @param erp Error report, may be NULL.
+ @return Valid socket on success, INVALID_SOCKET on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if filename is NULL or backlog is 0,
+ - DK4_E_SYNTAX<br>
+ if the file name is too long,
+ - DK4_E_NON_SOCKET<br>
+ if the file exists but is not a socket,
+ - DK4_E_UNLINK_FAILED<br>
+ if deletion of an already existing socket failed,
+ - DK4_E_SOCKET_SOCKET<br>
+ with errno value in iDetails1 if
+ the socket() function failed,
+ - DK4_E_SOCKET_BIND<br>
+ with errno value in iDetails1 if the
+ bind() function failed,
+ - DK4_E_SOCKET_LISTEN<br>
+ with errno value in iDetails1 if the
+ listen() function failed,
+ - DK4_E_CHMOD_FAILED<br>
+ with errno value in iDetails1 if the chmod() function failed.
+*/
+dk4_socket_t
+dk4socket_c8_unix_listener(
+ const char *filename,
+ int backlog,
+ dk4_er_t *erp
+);
+
+/** Create a UNIX domain socket in listening state,
+ change ownership and permission.
+ This function is intended for use in daemons which will give
+ up root privileges before doing any service.
+ @param filename File name, max 107 characters long.
+ @param backlog Number of connection requests to queue.
+ @param owner Owner UID.
+ @param group Owner GID.
+ @param mode File permissions in octal notation.
+ @param erp Error report, may be NULL.
+ @return Valid socket on success, INVALID_SOCKET on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if filename is NULL or backlog is 0,
+ - DK4_E_SYNTAX<br>
+ if the file name is too long,
+ - DK4_E_NON_SOCKET<br>
+ if the file exists but is not a socket,
+ - DK4_E_UNLINK_FAILED<br>
+ if deletion of an already existing socket failed,
+ - DK4_E_SOCKET_SOCKET<br>
+ with errno value in iDetails1 if
+ the socket() function failed,
+ - DK4_E_SOCKET_BIND<br>
+ with errno value in iDetails1 if the
+ bind() function failed,
+ - DK4_E_SOCKET_LISTEN<br>
+ with errno value in iDetails1 if the
+ listen() function failed,
+ - DK4_E_CHOWN_FAILED<br>
+ with errno value in iDetails1 if the chown() function failed,
+ - DK4_E_CHMOD_FAILED<br>
+ with errno value in iDetails1 if the chmod() function failed.
+*/
+dk4_socket_t
+dk4socket_c8_unix_listener_owner_group_mode(
+ const char *filename,
+ int backlog,
+ uid_t owner,
+ gid_t group,
+ mode_t mode,
+ dk4_er_t *erp
+);
+
+#endif
+
+/*
+ Set socket options.
+ -------------------
+ Module: dk4sock14
+*/
+
+/** Set reuse flag for socket.
+ Typically you should call this function immediately after
+ creating the socket before binding any local address.
+ @param sock
+ @param val
+ @param erp
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ if the setsockopt() function is not available,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if the socket is invalid,
+ - DK4_E_SOCKET_SETSOCKOPT<br>
+ if setsockopt() indicated an error.
+*/
+int
+dk4socket_option_set_reuse(
+ dk4_socket_t sock,
+ int val,
+ dk4_er_t *erp
+);
+
+/** Set broadcast flag for socket.
+ Typically you should call this function immediately after
+ creating the socket before binding any local address.
+ @param sock
+ @param val
+ @param erp
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ if the setsockopt() function is not available,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if the socket is invalid,
+ - DK4_E_SOCKET_SETSOCKOPT<br>
+ if setsockopt() indicated an error.
+*/
+int
+dk4socket_option_set_broadcast(
+ dk4_socket_t sock,
+ int val,
+ dk4_er_t *erp
+);
+
+/*
+ Set non-blocking mode.
+ ----------------------
+ Module: dk4sock15
+*/
+
+/** Set non-blocking mode for socket.
+ @param sock
+ @param val
+ @param erp
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if any argument is bad,
+ - DK4_E_SOCKET_FCNTL<br>
+ with errno value in iDetails1 if the fcntl() function failed,
+ - DK4_E_SOCKET_IOCTLSOCKET
+ with WSAGetLastError() value in iDetails1 if the
+ ioctlsocket() function failed.
+*/
+int
+dk4socket_option_set_nonblock(
+ dk4_socket_t sock,
+ int val,
+ dk4_er_t *erp
+);
+
+/*
+ Create client side connection.
+ ------------------------------
+ Module: dk4sock16
+*/
+
+/** Create client side socket for a given address pair (remote
+ and local address).
+ @param protfam Protocol family (PF_INET or PF_INET6).
+ @param pRemoteAddr Pointer to address structure containing
+ remote address.
+ @param szRemoteAddr Size of remote address.
+ @param pLocalAddr Pointer to address structure for local
+ address to bind, may be NULL to chose
+ any address.
+ @param szLocalAddr Size of remote address, must be 0 if
+ pLocalAddr is NULL.
+ @param seconds Timeout in seconds.
+ @param microSeconds Timeout in microseconds.
+ @param erp Error report, may be NULL.
+ @return Valid socket on success, INVALID_SOCKET on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if any argument is bad,
+ - DK4_E_SOCKET_SOCKET<br>
+ if the socket() function failed to create a new socket,
+ - DK4_E_SOCKET_BIND<br>
+ if the bind() function failed to bind the requested local address,
+ - DK4_E_SOCKET_FCNTL<br>
+ if the fcntl() function failed,
+ - DK4_E_SOCKET_IOCTLSOCKET
+ if the ioctlsocket() function failed.
+ - DK4_E_SOCKET_CONNECT<br>
+ if the connect() function failed,
+ - DK4_E_SOCKET_TIMEOUT<br>
+ if a timeout occured in the connect attempt,
+ - DK4_E_SOCKET_SELECT<br>
+ if the select() function failed,
+ - DK4_E_SOCKET_GETSOCKOPT<br>
+ if the getsockopt() function failed.
+ For all error codes - except DK4_E_SOCKET_TIMEOUT - the iDetails1
+ field contains the errno or WSAGetLastError() value.
+*/
+dk4_socket_t
+dk4socket_tcp_client_for_addr(
+ int protfam,
+ struct sockaddr *pRemoteAddr,
+ size_t szRemoteAddr,
+ struct sockaddr *pLocalAddr,
+ size_t szLocalAddr,
+ long seconds,
+ long microSeconds,
+ dk4_er_t *erp
+);
+
+/*
+ Choose remote and optionaly local address and connect.
+ ------------------------------------------------------
+ Module: dk4sock17
+*/
+
+/** Connect to a specified host name and service name.
+ @param hostname Host name to connect to.
+ @param svcname Service name or port number as string.
+ @param lsvcname Local service name or port number as string.
+ @param secs Timeout seconds (may be 0).
+ @param usecs Timeout microseconds (may be 0).
+ @param nsrv Flag: svname and lsvcname are numeric strings.
+ @param erp Error report, may be NULL.
+ @return Valid socket on success, INVALID_SOCKET on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if any argument is bad,
+ - DK4_E_SOCKET_SOCKET<br>
+ if the socket() function failed to create a new socket,
+ - DK4_E_SOCKET_BIND<br>
+ if the bind() function failed to bind the requested local address,
+ - DK4_E_SOCKET_FCNTL<br>
+ if the fcntl() function failed,
+ - DK4_E_SOCKET_IOCTLSOCKET
+ if the ioctlsocket() function failed.
+ - DK4_E_SOCKET_GETHOSTBYNAME<br>
+ if the gethostbyname() function failed to find the remote host.
+ - DK4_E_SOCKET_GETSERVBYNAME<br>
+ if the getservbyname() function failed to find the port
+ number for the remote or local service.
+ - DK4_E_SOCKET_GETADDRLOC<br>
+ if the getaddrinfo() function failed to find local addresses.
+ - DK4_E_SOCKET_GETADDRINFO<br>
+ if the getaddrinfo() function failed to find the remote host,
+ - DK4_E_SOCKET_CONNECT<br>
+ if the connect() function failed,
+ - DK4_E_SOCKET_TIMEOUT<br>
+ if a timeout occured in the connect attempt,
+ - DK4_E_SOCKET_SELECT<br>
+ if the select() function failed,
+ - DK4_E_SOCKET_GETSOCKOPT<br>
+ if the getsockopt() function failed.
+ - DK4_E_BUG<br>
+ if the gethostbyname() function returned non-matching or
+ otherwise illegal address lengths.
+ For all error codes - except DK4_E_SOCKET_TIMEOUT and
+ DK4_E_BUG - the iDetails1
+ field contains the errno or WSAGetLastError() value.
+*/
+dk4_socket_t
+dk4socket_c8_tcp_client_host_num_srv(
+ const char *hostname,
+ const char *svcname,
+ const char *lsvcname,
+ long secs,
+ long usecs,
+ int nsrv,
+ dk4_er_t *erp
+);
+
+/** Connect to a specified host name and service name.
+ @param hostname Host name to connect to.
+ @param svcname Service name or port number as string.
+ @param lsvcname Local service name or port number as string.
+ @param secs Timeout seconds (may be 0).
+ @param usecs Timeout microseconds (may be 0).
+ @param erp Error report, may be NULL.
+ @return Valid socket on success, INVALID_SOCKET on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if any argument is bad,
+ - DK4_E_SOCKET_SOCKET<br>
+ if the socket() function failed to create a new socket,
+ - DK4_E_SOCKET_BIND<br>
+ if the bind() function failed to bind the requested local address,
+ - DK4_E_SOCKET_FCNTL<br>
+ if the fcntl() function failed,
+ - DK4_E_SOCKET_IOCTLSOCKET
+ if the ioctlsocket() function failed.
+ - DK4_E_SOCKET_GETHOSTBYNAME<br>
+ if the gethostbyname() function failed to find the remote host.
+ - DK4_E_SOCKET_GETSERVBYNAME<br>
+ if the getservbyname() function failed to find the port
+ number for the remote or local service.
+ - DK4_E_SOCKET_GETADDRLOC<br>
+ if the getaddrinfo() function failed to find local addresses.
+ - DK4_E_SOCKET_GETADDRINFO<br>
+ if the getaddrinfo() function failed to find the remote host,
+ - DK4_E_SOCKET_CONNECT<br>
+ if the connect() function failed,
+ - DK4_E_SOCKET_TIMEOUT<br>
+ if a timeout occured in the connect attempt,
+ - DK4_E_SOCKET_SELECT<br>
+ if the select() function failed,
+ - DK4_E_SOCKET_GETSOCKOPT<br>
+ if the getsockopt() function failed.
+ - DK4_E_BUG<br>
+ if the gethostbyname() function returned non-matching or
+ otherwise illegal address lengths.
+ For all error codes - except DK4_E_SOCKET_TIMEOUT and
+ DK4_E_BUG - the iDetails1
+ field contains the errno or WSAGetLastError() value.
+*/
+dk4_socket_t
+dk4socket_c8_tcp_client_host_srv(
+ const char *hostname,
+ const char *svcname,
+ const char *lsvcname,
+ long secs,
+ long usecs,
+ dk4_er_t *erp
+);
+
+/** Connect to a specified host name and port number.
+ @param hostname Host name to connect to.
+ @param portno Port number in host byte order to connect to.
+ @param lportno Local port number in host byte order (0 = any).
+ @param secs Timeout seconds (may be 0).
+ @param usecs Timeout microseconds (may be 0).
+ @param erp Error report, may be NULL.
+ @return Valid socket on success, INVALID_SOCKET on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if any argument is bad,
+ - DK4_E_SOCKET_SOCKET<br>
+ if the socket() function failed to create a new socket,
+ - DK4_E_SOCKET_BIND<br>
+ if the bind() function failed to bind the requested local address,
+ - DK4_E_SOCKET_FCNTL<br>
+ if the fcntl() function failed,
+ - DK4_E_SOCKET_IOCTLSOCKET
+ if the ioctlsocket() function failed.
+ - DK4_E_SOCKET_GETHOSTBYNAME<br>
+ if the gethostbyname() function failed to find the remote host.
+ - DK4_E_SOCKET_GETSERVBYNAME<br>
+ if the getservbyname() function failed to find the port
+ number for the remote or local service.
+ - DK4_E_SOCKET_GETADDRLOC<br>
+ if the getaddrinfo() function failed to find local addresses.
+ - DK4_E_SOCKET_GETADDRINFO<br>
+ if the getaddrinfo() function failed to find the remote host,
+ - DK4_E_SOCKET_CONNECT<br>
+ if the connect() function failed,
+ - DK4_E_SOCKET_TIMEOUT<br>
+ if a timeout occured in the connect attempt,
+ - DK4_E_SOCKET_SELECT<br>
+ if the select() function failed,
+ - DK4_E_SOCKET_GETSOCKOPT<br>
+ if the getsockopt() function failed.
+ - DK4_E_BUG<br>
+ if the gethostbyname() function returned non-matching or
+ otherwise illegal address lengths.
+ For all error codes - except DK4_E_SOCKET_TIMEOUT and
+ DK4_E_BUG - the iDetails1
+ field contains the errno or WSAGetLastError() value.
+*/
+dk4_socket_t
+dk4socket_c8_tcp_client_host_port(
+ const char *hostname,
+ unsigned short portno,
+ unsigned short lportno,
+ long secs,
+ long usecs,
+ dk4_er_t *erp
+);
+
+/*
+ Choose remote and optionally local address and connect (wchar_t).
+ -----------------------------------------------------------------
+ Module: dk4sock18
+*/
+
+/** Connect to a specified host name and service name.
+ @param hostname Host name to connect to.
+ @param svcname Service name or port number as string.
+ @param lsvcname Local service name or port number as string.
+ @param secs Timeout seconds (may be 0).
+ @param usecs Timeout microseconds (may be 0).
+ @param nsrv Flag: svname and lsvcname are numeric strings.
+ @param erp Error report, may be NULL.
+ @return Valid socket on success, INVALID_SOCKET on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if any argument is bad,
+ - DK4_E_SOCKET_SOCKET<br>
+ if the socket() function failed to create a new socket,
+ - DK4_E_SOCKET_BIND<br>
+ if the bind() function failed to bind the requested local address,
+ - DK4_E_SOCKET_FCNTL<br>
+ if the fcntl() function failed,
+ - DK4_E_SOCKET_IOCTLSOCKET
+ if the ioctlsocket() function failed.
+ - DK4_E_SOCKET_GETHOSTBYNAME<br>
+ if the gethostbyname() function failed to find the remote host.
+ - DK4_E_SOCKET_GETSERVBYNAME<br>
+ if the getservbyname() function failed to find the port
+ number for the remote or local service.
+ - DK4_E_SOCKET_GETADDRLOC<br>
+ if the getaddrinfo() function failed to find local addresses.
+ - DK4_E_SOCKET_GETADDRINFO<br>
+ if the getaddrinfo() function failed to find the remote host,
+ - DK4_E_SOCKET_CONNECT<br>
+ if the connect() function failed,
+ - DK4_E_SOCKET_TIMEOUT<br>
+ if a timeout occured in the connect attempt,
+ - DK4_E_SOCKET_SELECT<br>
+ if the select() function failed,
+ - DK4_E_SOCKET_GETSOCKOPT<br>
+ if the getsockopt() function failed.
+ - DK4_E_BUG<br>
+ if the gethostbyname() function returned non-matching or
+ otherwise illegal address lengths,
+ - DK4_E_NOT_SUPPORTED<br>
+ if wide character functions for networking are not available.
+ For all error codes - except DK4_E_SOCKET_TIMEOUT and
+ DK4_E_BUG - the iDetails1
+ field contains the errno or WSAGetLastError() value.
+*/
+dk4_socket_t
+dk4socket_wc_tcp_client_host_num_srv(
+ const wchar_t *hostname,
+ const wchar_t *svcname,
+ const wchar_t *lsvcname,
+ long secs,
+ long usecs,
+ int nsrv,
+ dk4_er_t *erp
+);
+
+/** Connect to a specified host name and service name.
+ @param hostname Host name to connect to.
+ @param svcname Service name or port number as string.
+ @param lsvcname Local service name or port number as string.
+ @param secs Timeout seconds (may be 0).
+ @param usecs Timeout microseconds (may be 0).
+ @param erp Error report, may be NULL.
+ @return Valid socket on success, INVALID_SOCKET on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if any argument is bad,
+ - DK4_E_SOCKET_SOCKET<br>
+ if the socket() function failed to create a new socket,
+ - DK4_E_SOCKET_BIND<br>
+ if the bind() function failed to bind the requested local address,
+ - DK4_E_SOCKET_FCNTL<br>
+ if the fcntl() function failed,
+ - DK4_E_SOCKET_IOCTLSOCKET
+ if the ioctlsocket() function failed.
+ - DK4_E_SOCKET_GETHOSTBYNAME<br>
+ if the gethostbyname() function failed to find the remote host.
+ - DK4_E_SOCKET_GETSERVBYNAME<br>
+ if the getservbyname() function failed to find the port
+ number for the remote or local service.
+ - DK4_E_SOCKET_GETADDRLOC<br>
+ if the getaddrinfo() function failed to find local addresses.
+ - DK4_E_SOCKET_GETADDRINFO<br>
+ if the getaddrinfo() function failed to find the remote host,
+ - DK4_E_SOCKET_CONNECT<br>
+ if the connect() function failed,
+ - DK4_E_SOCKET_TIMEOUT<br>
+ if a timeout occured in the connect attempt,
+ - DK4_E_SOCKET_SELECT<br>
+ if the select() function failed,
+ - DK4_E_SOCKET_GETSOCKOPT<br>
+ if the getsockopt() function failed.
+ - DK4_E_BUG<br>
+ if the gethostbyname() function returned non-matching or
+ otherwise illegal address lengths,
+ - DK4_E_NOT_SUPPORTED<br>
+ if no wide character functions for networking are avaialble.
+ For all error codes - except DK4_E_SOCKET_TIMEOUT, DK4_E_NOT_SUPPORTED
+ and DK4_E_BUG - the iDetails1
+ field contains the errno or WSAGetLastError() value.
+*/
+dk4_socket_t
+dk4socket_wc_tcp_client_host_srv(
+ const wchar_t *hostname,
+ const wchar_t *svcname,
+ const wchar_t *lsvcname,
+ long secs,
+ long usecs,
+ dk4_er_t *erp
+);
+
+/** Connect to a specified host name and port number.
+ @param hostname Host name to connect to.
+ @param portno Port number in host byte order to connect to.
+ @param lportno Local port number in host byte order (0 = any).
+ @param secs Timeout seconds (may be 0).
+ @param usecs Timeout microseconds (may be 0).
+ @param erp Error report, may be NULL.
+ @return Valid socket on success, INVALID_SOCKET on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if any argument is bad,
+ - DK4_E_SOCKET_SOCKET<br>
+ if the socket() function failed to create a new socket,
+ - DK4_E_SOCKET_BIND<br>
+ if the bind() function failed to bind the requested local address,
+ - DK4_E_SOCKET_FCNTL<br>
+ if the fcntl() function failed,
+ - DK4_E_SOCKET_IOCTLSOCKET
+ if the ioctlsocket() function failed.
+ - DK4_E_SOCKET_GETHOSTBYNAME<br>
+ if the gethostbyname() function failed to find the remote host.
+ - DK4_E_SOCKET_GETSERVBYNAME<br>
+ if the getservbyname() function failed to find the port
+ number for the remote or local service.
+ - DK4_E_SOCKET_GETADDRLOC<br>
+ if the getaddrinfo() function failed to find local addresses.
+ - DK4_E_SOCKET_GETADDRINFO<br>
+ if the getaddrinfo() function failed to find the remote host,
+ - DK4_E_SOCKET_CONNECT<br>
+ if the connect() function failed,
+ - DK4_E_SOCKET_TIMEOUT<br>
+ if a timeout occured in the connect attempt,
+ - DK4_E_SOCKET_SELECT<br>
+ if the select() function failed,
+ - DK4_E_SOCKET_GETSOCKOPT<br>
+ if the getsockopt() function failed.
+ - DK4_E_BUG<br>
+ if the gethostbyname() function returned non-matching or
+ otherwise illegal address lengths,
+ - DK4_E_NOT_SUPPORTED<br>
+ if no wide character functions for networking are available.
+ For all error codes - except DK4_E_SOCKET_TIMEOUT and
+ DK4_E_BUG - the iDetails1
+ field contains the errno or WSAGetLastError() value.
+*/
+dk4_socket_t
+dk4socket_wc_tcp_client_host_port(
+ const wchar_t *hostname,
+ unsigned short portno,
+ unsigned short lportno,
+ long secs,
+ long usecs,
+ dk4_er_t *erp
+);
+
+/*
+ Choose remote and optionaly local address and connect (dkChar).
+ ---------------------------------------------------------------
+ Module: dk4sock19
+*/
+
+/** Connect to a specified host name and service name.
+ @param hostname Host name to connect to.
+ @param svcname Service name or port number as string.
+ @param lsvcname Local service name or port number as string.
+ @param secs Timeout seconds (may be 0).
+ @param usecs Timeout microseconds (may be 0).
+ @param nsrv Flag: svname and lsvcname are numeric strings.
+ @param erp Error report, may be NULL.
+ @return Valid socket on success, INVALID_SOCKET on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if any argument is bad,
+ - DK4_E_SOCKET_SOCKET<br>
+ if the socket() function failed to create a new socket,
+ - DK4_E_SOCKET_BIND<br>
+ if the bind() function failed to bind the requested local address,
+ - DK4_E_SOCKET_FCNTL<br>
+ if the fcntl() function failed,
+ - DK4_E_SOCKET_IOCTLSOCKET
+ if the ioctlsocket() function failed.
+ - DK4_E_SOCKET_GETHOSTBYNAME<br>
+ if the gethostbyname() function failed to find the remote host.
+ - DK4_E_SOCKET_GETSERVBYNAME<br>
+ if the getservbyname() function failed to find the port
+ number for the remote or local service.
+ - DK4_E_SOCKET_GETADDRLOC<br>
+ if the getaddrinfo() function failed to find local addresses.
+ - DK4_E_SOCKET_GETADDRINFO<br>
+ if the getaddrinfo() function failed to find the remote host,
+ - DK4_E_SOCKET_CONNECT<br>
+ if the connect() function failed,
+ - DK4_E_SOCKET_TIMEOUT<br>
+ if a timeout occured in the connect attempt,
+ - DK4_E_SOCKET_SELECT<br>
+ if the select() function failed,
+ - DK4_E_SOCKET_GETSOCKOPT<br>
+ if the getsockopt() function failed.
+ - DK4_E_BUG<br>
+ if the gethostbyname() function returned non-matching or
+ otherwise illegal address lengths,
+ - DK4_E_NOT_SUPPORTED<br>
+ if wide character functions for networking are not available.
+ For all error codes - except DK4_E_SOCKET_TIMEOUT and
+ DK4_E_BUG - the iDetails1
+ field contains the errno or WSAGetLastError() value.
+*/
+dk4_socket_t
+dk4socket_tcp_client_host_num_srv(
+ const dkChar *hostname,
+ const dkChar *svcname,
+ const dkChar *lsvcname,
+ long secs,
+ long usecs,
+ int nsrv,
+ dk4_er_t *erp
+);
+
+/** Connect to a specified host name and service name.
+ @param hostname Host name to connect to.
+ @param svcname Service name or port number as string.
+ @param lsvcname Local service name or port number as string.
+ @param secs Timeout seconds (may be 0).
+ @param usecs Timeout microseconds (may be 0).
+ @param erp Error report, may be NULL.
+ @return Valid socket on success, INVALID_SOCKET on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if any argument is bad,
+ - DK4_E_SOCKET_SOCKET<br>
+ if the socket() function failed to create a new socket,
+ - DK4_E_SOCKET_BIND<br>
+ if the bind() function failed to bind the requested local address,
+ - DK4_E_SOCKET_FCNTL<br>
+ if the fcntl() function failed,
+ - DK4_E_SOCKET_IOCTLSOCKET
+ if the ioctlsocket() function failed.
+ - DK4_E_SOCKET_GETHOSTBYNAME<br>
+ if the gethostbyname() function failed to find the remote host.
+ - DK4_E_SOCKET_GETSERVBYNAME<br>
+ if the getservbyname() function failed to find the port
+ number for the remote or local service.
+ - DK4_E_SOCKET_GETADDRLOC<br>
+ if the getaddrinfo() function failed to find local addresses.
+ - DK4_E_SOCKET_GETADDRINFO<br>
+ if the getaddrinfo() function failed to find the remote host,
+ - DK4_E_SOCKET_CONNECT<br>
+ if the connect() function failed,
+ - DK4_E_SOCKET_TIMEOUT<br>
+ if a timeout occured in the connect attempt,
+ - DK4_E_SOCKET_SELECT<br>
+ if the select() function failed,
+ - DK4_E_SOCKET_GETSOCKOPT<br>
+ if the getsockopt() function failed.
+ - DK4_E_BUG<br>
+ if the gethostbyname() function returned non-matching or
+ otherwise illegal address lengths,
+ - DK4_E_NOT_SUPPORTED<br>
+ if no wide character functions for networking are avaialble.
+ For all error codes - except DK4_E_SOCKET_TIMEOUT, DK4_E_NOT_SUPPORTED
+ and DK4_E_BUG - the iDetails1
+ field contains the errno or WSAGetLastError() value.
+*/
+dk4_socket_t
+dk4socket_tcp_client_host_srv(
+ const dkChar *hostname,
+ const dkChar *svcname,
+ const dkChar *lsvcname,
+ long secs,
+ long usecs,
+ dk4_er_t *erp
+);
+
+/** Connect to a specified host name and port number.
+ @param hostname Host name to connect to.
+ @param portno Port number in host byte order to connect to.
+ @param lportno Local port number in host byte order (0 = any).
+ @param secs Timeout seconds (may be 0).
+ @param usecs Timeout microseconds (may be 0).
+ @param erp Error report, may be NULL.
+ @return Valid socket on success, INVALID_SOCKET on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if any argument is bad,
+ - DK4_E_SOCKET_SOCKET<br>
+ if the socket() function failed to create a new socket,
+ - DK4_E_SOCKET_BIND<br>
+ if the bind() function failed to bind the requested local address,
+ - DK4_E_SOCKET_FCNTL<br>
+ if the fcntl() function failed,
+ - DK4_E_SOCKET_IOCTLSOCKET
+ if the ioctlsocket() function failed.
+ - DK4_E_SOCKET_GETHOSTBYNAME<br>
+ if the gethostbyname() function failed to find the remote host.
+ - DK4_E_SOCKET_GETSERVBYNAME<br>
+ if the getservbyname() function failed to find the port
+ number for the remote or local service.
+ - DK4_E_SOCKET_GETADDRLOC<br>
+ if the getaddrinfo() function failed to find local addresses.
+ - DK4_E_SOCKET_GETADDRINFO<br>
+ if the getaddrinfo() function failed to find the remote host,
+ - DK4_E_SOCKET_CONNECT<br>
+ if the connect() function failed,
+ - DK4_E_SOCKET_TIMEOUT<br>
+ if a timeout occured in the connect attempt,
+ - DK4_E_SOCKET_SELECT<br>
+ if the select() function failed,
+ - DK4_E_SOCKET_GETSOCKOPT<br>
+ if the getsockopt() function failed.
+ - DK4_E_BUG<br>
+ if the gethostbyname() function returned non-matching or
+ otherwise illegal address lengths,
+ - DK4_E_NOT_SUPPORTED<br>
+ if no wide character functions for networking are available.
+ For all error codes - except DK4_E_SOCKET_TIMEOUT and
+ DK4_E_BUG - the iDetails1
+ field contains the errno or WSAGetLastError() value.
+*/
+dk4_socket_t
+dk4socket_tcp_client_host_port(
+ const dkChar *hostname,
+ unsigned short portno,
+ unsigned short lportno,
+ long secs,
+ long usecs,
+ dk4_er_t *erp
+);
+
+/*
+ Send and receive data over an established connection.
+ -----------------------------------------------------
+ Module: dk4sock20
+*/
+
+/** Send data.
+ @param sock Socket to use.
+ @param buf Start address of buffer.
+ @param pszbuf Pointer to size variable
+ (in: buffer size, out: bytes send).
+ @param flags Flags for send() function.
+ @param secs Seconds for timeout.
+ @param usecs Microseconds for timeout.
+ @param erp Error report, may be NULL.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error (0 bytes send),
+ DK4_SOCKET_RESULT_IN_PROGRESS on partial success.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if sock is an invalid socket, buf is NULL, pszbuf is NULL,
+ *pszbuf is 0 or *pszbuf is too large to fit into an ssize_t
+ or int,
+ - DK4_E_SOCKET_TIMEOUT<br>
+ if the timeout was reached without getting the socket writable,
+ - DK4_E_SOCKET_SELECT<br>
+ if the select() function failed (details in iDetails1),
+ - DK4_E_SOCKET_SEND<br>
+ if the send() function failed (details in iDetails1).
+*/
+int
+dk4socket_send(
+ dk4_socket_t sock,
+ const void *buf,
+ size_t *pszbuf,
+ int flags,
+ long secs,
+ long usecs,
+ dk4_er_t *erp
+);
+
+/** Receive data.
+ @param sock Socket to use.
+ @param buf Start address of buffer.
+ @param pszbuf Pointer to size variable
+ (in: buffer size, out: bytes received).
+ @param flags Flags for send() function.
+ @param secs Seconds for timeout.
+ @param usecs Microseconds for timeout.
+ @param erp Error report, may be NULL.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if sock is an invalid socket, buf is NULL, pszbuf is NULL,
+ *pszbuf is 0 or *pszbuf is too large to fit into an ssize_t
+ or int,
+ - DK4_E_SOCKET_TIMEOUT<br>
+ if the timeout was reached without getting data on the socket,
+ - DK4_E_SOCKET_SELECT<br>
+ if the select() function failed (details in iDetails1),
+ - DK4_E_SOCKET_RECV<br>
+ if the send() function failed (details in iDetails1).
+*/
+int
+dk4socket_recv(
+ dk4_socket_t sock,
+ void *buf,
+ size_t *pszbuf,
+ int flags,
+ long secs,
+ long usecs,
+ dk4_er_t *erp
+);
+
+/*
+ Connectionless send and receive operations.
+ -------------------------------------------
+ Module: dk4sock21
+*/
+
+/** Send UDP datagram.
+ @param sock Socket to use.
+ @param buf Start address of buffer.
+ @param pszbuf Pointer to size variable
+ (in: buffer size, out: bytes send).
+ @param flags Flags for sendto() function.
+ @param saddr Pointer to destination address.
+ @param addrlen Length of destination address.
+ @param secs Seconds for timeout.
+ @param usecs Microseconds for timeout.
+ @param erp Error report, may be NULL.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_IN_PROGRESS on partial success (not all bytes send),
+ DK4_SOCKET_RESULT_FAILED on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if sock is an invalid socket, buf is NULL, pszbuf is NULL,
+ *pszbuf is 0 or *pszbuf is too large to fit into an ssize_t
+ or int,
+ - DK4_E_SOCKET_TIMEOUT<br>
+ if the timeout was reached without getting data on the socket,
+ - DK4_E_SOCKET_SELECT<br>
+ if the select() function failed (details in iDetails1),
+ - DK4_E_SOCKET_RECV<br>
+ if the send() function failed (details in iDetails1).
+*/
+int
+dk4socket_sendto(
+ dk4_socket_t sock,
+ const void *buf,
+ size_t *pszbuf,
+ int flags,
+ const struct sockaddr *saddr,
+ size_t addrlen,
+ long secs,
+ long usecs,
+ dk4_er_t *erp
+);
+
+/** Receive UDP datagram.
+ @param sock Socket to use.
+ @param buf Start address of buffer.
+ @param pszbuf Pointer to size variable
+ (in: buffer size, out: bytes used).
+ @param flags Flags for recvfrom() function.
+ @param saddr Pointer to buffer for source address.
+ @param paddrlen Source address buffer size.
+ @param secs Seconds for timeout.
+ @param usecs Microseconds for timeout.
+ @param erp Error report, may be NULL.
+
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if sock is an invalid socket, buf is NULL, pszbuf is NULL,
+ *pszbuf is 0 or *pszbuf is too large to fit into an ssize_t
+ or int,
+ - DK4_E_SOCKET_TIMEOUT<br>
+ if the timeout was reached without getting data on the socket,
+ - DK4_E_SOCKET_SELECT<br>
+ if the select() function failed (details in iDetails1),
+ - DK4_E_SOCKET_RECV<br>
+ if the send() function failed (details in iDetails1).
+*/
+int
+dk4socket_recvfrom(
+ dk4_socket_t sock,
+ void *buf,
+ size_t *pszbuf,
+ int flags,
+ struct sockaddr *saddr,
+ size_t *paddrlen,
+ long secs,
+ long usecs,
+ dk4_er_t *erp
+);
+
+/*
+ Listener socket set (create and delete).
+ ----------------------------------------
+ Module: dk4sock22
+*/
+
+/** Allocate memory for a socket set but do not open any
+ socket (set all to INVALID_SOCKET).
+ @param max Number of sockets to plan for.
+ @param erp Error report, may be NULL.
+ @return Pointer to new socket set on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if max is 0,
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow when calculating the number of bytes to
+ allocate,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem set if there is not enough memory
+ available.
+*/
+dk4_socket_set_t *
+dk4socket_set_new(
+ size_t max,
+ dk4_er_t *erp
+);
+
+/** Delete socket set (do not close anything, just release the memory).
+ @param set Socket set to destroy.
+ @param erp Error report, may be NULL.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if set is NULL.
+*/
+void
+dk4socket_set_delete(
+ dk4_socket_set_t *set,
+ dk4_er_t *erp
+);
+
+/** Close all sockets and delete the socket set (release memory).
+ @param set Socket set to close.
+ @param erp Error report, may be NULL.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if set is NULL.
+ - DK4_E_SOCKET_CLOSE<br>
+ with errno/WSAGetLastError() value in iDetails1 if
+ the close()/closesocket() function failed.
+*/
+void
+dk4socket_set_close(
+ dk4_socket_set_t *set,
+ dk4_er_t *erp
+);
+
+/*
+ Create listener socket set for local/remote connections.
+ --------------------------------------------------------
+ Module: dk4sock23
+*/
+
+/** Create listener socket set for a local port number, do
+ not use getaddrinfo() to obtain local addresses, construct
+ addresses.
+ @param portno Local port number to listen on.
+ @param local Flag: Allow local connections only.
+ @param backlog Number of connection requests to queue.
+ @param erp Error report, may be NULL.
+ @return Socket set on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if an invalid argument was specified,
+ - DK4_E_MATH_OVERFLOW<br>
+ if there was a numeric overflow in memory size calculation
+ (should not happen),
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if a memory allocation failed,
+ - DK4_E_SOCKET_SOCKET<br>
+ with errno/WSAGetLastError() value in iDetails1 if
+ the socket() function failed.
+ - DK4_E_SOCKET_BIND<br>
+ with errno/WSAGetLastError() value in iDetails1 if the
+ bind() function failed.
+ - DK4_E_SOCKET_LISTEN<br>
+ with errno/WSAGetLastError() value in iDetails1 if the
+ listen() function failed.
+*/
+dk4_socket_set_t *
+dk4socket_set_server_directly(
+ unsigned short portno,
+ int backlog,
+ int local,
+ dk4_er_t *erp
+);
+
+/*
+ Create listener socket set for local/remote connections.
+ --------------------------------------------------------
+ Module: dk4sock24
+*/
+
+/** Create listener socket set for a local port number, use
+ getaddrinfo() if available to obtain a collection of local
+ addresses.
+ @param portno Local port number to listen on.
+ @param local Flag: Allow local connections only.
+ @param backlog Number of connection requests to queue.
+ @param erp Error report, may be NULL.
+ @return Socket set on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if an invalid argument was specified,
+ - DK4_E_MATH_OVERFLOW<br>
+ if there was a numeric overflow in memory size calculation
+ (should not happen),
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if a memory allocation failed,
+ - DK4_E_SOCKET_SOCKET<br>
+ with errno/WSAGetLastError() value in iDetails1 if
+ the socket() function failed.
+ - DK4_E_SOCKET_BIND<br>
+ with errno/WSAGetLastError() value in iDetails1 if the
+ bind() function failed.
+ - DK4_E_SOCKET_LISTEN<br>
+ with errno/WSAGetLastError() value in iDetails1 if the
+ listen() function failed.
+ - DK4_E_SOCKET_GETADDRLOC<br>
+ with errno/WSAGetLastError() value in iDetails1 if the
+ getaddrinfo() function failed.
+*/
+dk4_socket_set_t *
+dk4socket_c8_set_server(
+ unsigned short portno,
+ int backlog,
+ int local,
+ dk4_er_t *erp
+);
+
+/** Create listener socket set for a local port number.
+ @param servicename Local service name.
+ @param backlog Number of connection requests to queue.
+ @param local Flag: Allow local connections only.
+ @param erp Error report, may be NULL.
+ @return Socket set on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if an invalid argument was specified,
+ - DK4_E_MATH_OVERFLOW<br>
+ if there was a numeric overflow in memory size calculation
+ (should not happen),
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if a memory allocation failed,
+ - DK4_E_SOCKET_SOCKET<br>
+ with errno/WSAGetLastError() value in iDetails1 if
+ the socket() function failed.
+ - DK4_E_SOCKET_BIND<br>
+ with errno/WSAGetLastError() value in iDetails1 if the
+ bind() function failed.
+ - DK4_E_SOCKET_LISTEN<br>
+ with errno/WSAGetLastError() value in iDetails1 if the
+ listen() function failed.
+ - DK4_E_SOCKET_GETADDRLOC<br>
+ with errno/WSAGetLastError() value in iDetails1 if the
+ getaddrinfo() function failed.
+ - DK4_E_SYNTAX<br>
+ if a non-digit was found in a port number,
+ - DK4_E_SOCKET_GETSERVBYNAME<br>
+ with errno/WSAGetLastError() value in iDetails1 if the
+ getservbyname() function failed to find a port number of a service,
+*/
+dk4_socket_set_t *
+dk4socket_c8_set_service(
+ const char *servicename,
+ int backlog,
+ int local,
+ dk4_er_t *erp
+);
+
+/*
+ dkChar variants of the functions above.
+ ---------------------------------------
+ Module: dk4sock25
+*/
+
+/** Create listener socket set for a local port number.
+ @param portno Local port number to listen on.
+ @param local Flag: Allow local connections only.
+ @param backlog Number of connection requests to queue.
+ @param erp Error report, may be NULL.
+ @return Socket set on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if an invalid argument was specified,
+ - DK4_E_MATH_OVERFLOW<br>
+ if there was a numeric overflow in memory size calculation
+ (should not happen),
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if a memory allocation failed,
+ - DK4_E_SOCKET_SOCKET<br>
+ with errno/WSAGetLastError() value in iDetails1 if
+ the socket() function failed.
+ - DK4_E_SOCKET_BIND<br>
+ with errno/WSAGetLastError() value in iDetails1 if the
+ bind() function failed.
+ - DK4_E_SOCKET_LISTEN<br>
+ with errno/WSAGetLastError() value in iDetails1 if the
+ listen() function failed.
+ - DK4_E_SOCKET_GETADDRLOC<br>
+ with errno/WSAGetLastError() value in iDetails1 if the
+ getaddrinfo() function failed.
+*/
+dk4_socket_set_t *
+dk4socket_set_server(
+ unsigned short portno,
+ int backlog,
+ int local,
+ dk4_er_t *erp
+);
+
+/** Create listener socket set for a local port number.
+ @param servicename Local service name.
+ @param backlog Number of connection requests to queue.
+ @param local Flag: Allow local connections only.
+ @param erp Error report, may be NULL.
+ @return Socket set on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if an invalid argument was specified,
+ - DK4_E_MATH_OVERFLOW<br>
+ if there was a numeric overflow in memory size calculation
+ (should not happen),
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if a memory allocation failed,
+ - DK4_E_SOCKET_SOCKET<br>
+ with errno/WSAGetLastError() value in iDetails1 if
+ the socket() function failed.
+ - DK4_E_SOCKET_BIND<br>
+ with errno/WSAGetLastError() value in iDetails1 if the
+ bind() function failed.
+ - DK4_E_SOCKET_LISTEN<br>
+ with errno/WSAGetLastError() value in iDetails1 if the
+ listen() function failed.
+ - DK4_E_SOCKET_GETADDRLOC<br>
+ with errno/WSAGetLastError() value in iDetails1 if the
+ getaddrinfo() function failed.
+ - DK4_E_SOCKET_GETSERVBYNAME<br>
+ with errno/WSAGetLastError() value in iDetails1 if the
+ getservbyname() function failed to find a port number of a service,
+*/
+dk4_socket_set_t *
+dk4socket_set_service(
+ const dkChar *servicename,
+ int backlog,
+ int local,
+ dk4_er_t *erp
+);
+
+/*
+ Get allowed peer from char string.
+ ----------------------------------
+ Module: dk4sock26
+*/
+
+/** Get allowed peer from string.
+ @param peerptr Data structure to save peer information.
+ @param str Text containing the information.
+ @param erp Error report, may be NULL.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS
+ - DK4_E_BUFFER_TOO_SMALL
+ - DK4_E_SYNTAX<br>
+ if the IP address component in str is not a valid IPv4 or IPv6
+ address, the mask component is not a valid IPv4 or IPv6 address
+ or an unsigned bit number or the bit number is too large,
+ - DK4_E_SOCKET_INET_PTON<br>
+ if the inet_pton() function failed for some reason.
+*/
+int
+dk4socket_c8_get_allowed_peer(
+ dk4_allowed_peer_t *peerptr,
+ const char *str,
+ dk4_er_t *erp
+);
+
+/*
+ Get allowed peer from dkChar string.
+ ------------------------------------
+ Module: dk4sock27
+*/
+
+/** Get allowed peer from string.
+ @param peerptr Data structure to save peer information.
+ @param str Text containing the information.
+ @param erp Error report, may be NULL.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS
+ - DK4_E_BUFFER_TOO_SMALL
+ - DK4_E_SYNTAX<br>
+ if the IP address component in str is not a valid IPv4 or IPv6
+ address, the mask component is not a valid IPv4 or IPv6 address
+ or an unsigned bit number or the bit number is too large,
+ - DK4_E_SOCKET_INET_PTON<br>
+ if the inet_pton() function failed for some reason.
+*/
+int
+dk4socket_get_allowed_peer(
+ dk4_allowed_peer_t *peerptr,
+ const dkChar *str,
+ dk4_er_t *erp
+);
+
+/*
+ Comparison of allowed peers.
+ ----------------------------
+ Module: dk4sock28
+*/
+
+/** Compare allowed peers.
+ @param pl Left pointer, always dk4_allowed_peer_t.
+ @param pr Right pointer, dk4_allowed_peer_t or struct sockaddr.
+ @param cr Comparison criteria:
+ 1: pr is struct sockaddr, else pr is dk4_allowed_peer_t.
+ @return -1, 0 or 1 for pl<pr, pl==pr, pl>pr.
+*/
+int
+dk4socket_allowed_peer_compare(
+ const void *pl,
+ const void *pr,
+ int cr
+);
+
+/*
+ Create UDP socket set for local/remote connections.
+ ---------------------------------------------------
+ Module: dk4sock29
+*/
+
+/** Create server UDP socket set for a local port number, do
+ not use getaddrinfo() to obtain local addresses, construct
+ addresses.
+ @param portno Local port number to listen on.
+ @param local Flag: Allow local connections only.
+ @param broadcast Flag: Prepare for broadcast sending.
+ @param erp Error report, may be NULL.
+ @return Socket set on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if an invalid argument was specified,
+ - DK4_E_MATH_OVERFLOW<br>
+ if there was a numeric overflow in memory size calculation
+ (should not happen),
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if a memory allocation failed,
+ - DK4_E_SOCKET_SOCKET<br>
+ with errno/WSAGetLastError() value in iDetails1 if
+ the socket() function failed.
+ - DK4_E_SOCKET_BIND<br>
+ with errno/WSAGetLastError() value in iDetails1 if the
+ bind() function failed.
+ - DK4_E_SOCKET_LISTEN<br>
+ with errno/WSAGetLastError() value in iDetails1 if the
+ listen() function failed.
+*/
+dk4_socket_set_t *
+dk4socket_set_udp_directly(
+ unsigned short portno,
+ int local,
+ int broadcast,
+ dk4_er_t *erp
+);
+
+/*
+ Create UDP socket set for local/remote connections.
+ ---------------------------------------------------
+ Module: dk4sock30
+*/
+
+/** Create UDP socket set for a local port number, use
+ getaddrinfo() if available to obtain a collection of local
+ addresses.
+ @param portno Local port number to listen on.
+ @param local Flag: Allow local connections only.
+ @param broadcast Flag: Prepare for broadcast send.
+ @param erp Error report, may be NULL.
+ @return Socket set on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if an invalid argument was specified,
+ - DK4_E_MATH_OVERFLOW<br>
+ if there was a numeric overflow in memory size calculation
+ (should not happen),
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if a memory allocation failed,
+ - DK4_E_SOCKET_SOCKET<br>
+ with errno/WSAGetLastError() value in iDetails1 if
+ the socket() function failed.
+ - DK4_E_SOCKET_BIND<br>
+ with errno/WSAGetLastError() value in iDetails1 if the
+ bind() function failed.
+ - DK4_E_SOCKET_LISTEN<br>
+ with errno/WSAGetLastError() value in iDetails1 if the
+ listen() function failed.
+ - DK4_E_SOCKET_GETADDRLOC<br>
+ with errno/WSAGetLastError() value in iDetails1 if the
+ getaddrinfo() function failed.
+*/
+dk4_socket_set_t *
+dk4socket_c8_set_udp(
+ unsigned short portno,
+ int local,
+ int broadcast,
+ dk4_er_t *erp
+);
+
+/** Create UDP socket set for a local port number.
+ @param servicename Local service name.
+ @param local Flag: Allow local connections only.
+ @param broadcast Flag: Prepare for broadcast transmission.
+ @param erp Error report, may be NULL.
+ @return Socket set on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if an invalid argument was specified,
+ - DK4_E_MATH_OVERFLOW<br>
+ if there was a numeric overflow in memory size calculation
+ (should not happen),
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if a memory allocation failed,
+ - DK4_E_SOCKET_SOCKET<br>
+ with errno/WSAGetLastError() value in iDetails1 if
+ the socket() function failed.
+ - DK4_E_SOCKET_BIND<br>
+ with errno/WSAGetLastError() value in iDetails1 if the
+ bind() function failed.
+ - DK4_E_SOCKET_LISTEN<br>
+ with errno/WSAGetLastError() value in iDetails1 if the
+ listen() function failed.
+ - DK4_E_SOCKET_GETADDRLOC<br>
+ with errno/WSAGetLastError() value in iDetails1 if the
+ getaddrinfo() function failed.
+ - DK4_E_SYNTAX<br>
+ if a non-digit was found in a port number,
+ - DK4_E_SOCKET_GETSERVBYNAME<br>
+ with errno/WSAGetLastError() value in iDetails1 if the
+ getservbyname() function failed to find a port number of a service,
+*/
+dk4_socket_set_t *
+dk4socket_c8_set_udp_service(
+ const char *servicename,
+ int local,
+ int broadcast,
+ dk4_er_t *erp
+);
+
+/*
+ Create UDP socket set for local/remote connections.
+ ---------------------------------------------------
+ Module: dk4sock31
+*/
+
+/** Create UDP socket set for a local port number, use
+ getaddrinfo() if available to obtain a collection of local
+ addresses.
+ @param portno Local port number to listen on.
+ @param local Flag: Allow local connections only.
+ @param broadcast Flag: Prepare for broadcast send.
+ @param erp Error report, may be NULL.
+ @return Socket set on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if an invalid argument was specified,
+ - DK4_E_MATH_OVERFLOW<br>
+ if there was a numeric overflow in memory size calculation
+ (should not happen),
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if a memory allocation failed,
+ - DK4_E_SOCKET_SOCKET<br>
+ with errno/WSAGetLastError() value in iDetails1 if
+ the socket() function failed.
+ - DK4_E_SOCKET_BIND<br>
+ with errno/WSAGetLastError() value in iDetails1 if the
+ bind() function failed.
+ - DK4_E_SOCKET_LISTEN<br>
+ with errno/WSAGetLastError() value in iDetails1 if the
+ listen() function failed.
+ - DK4_E_SOCKET_GETADDRLOC<br>
+ with errno/WSAGetLastError() value in iDetails1 if the
+ getaddrinfo() function failed.
+*/
+dk4_socket_set_t *
+dk4socket_set_udp(
+ unsigned short portno,
+ int local,
+ int broadcast,
+ dk4_er_t *erp
+);
+
+/** Create UDP socket set for a local port number.
+ @param servicename Local service name.
+ @param local Flag: Allow local connections only.
+ @param broadcast Flag: Prepare for broadcast transmission.
+ @param erp Error report, may be NULL.
+ @return Socket set on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if an invalid argument was specified,
+ - DK4_E_MATH_OVERFLOW<br>
+ if there was a numeric overflow in memory size calculation
+ (should not happen),
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if a memory allocation failed,
+ - DK4_E_SOCKET_SOCKET<br>
+ with errno/WSAGetLastError() value in iDetails1 if
+ the socket() function failed.
+ - DK4_E_SOCKET_BIND<br>
+ with errno/WSAGetLastError() value in iDetails1 if the
+ bind() function failed.
+ - DK4_E_SOCKET_LISTEN<br>
+ with errno/WSAGetLastError() value in iDetails1 if the
+ listen() function failed.
+ - DK4_E_SOCKET_GETADDRLOC<br>
+ with errno/WSAGetLastError() value in iDetails1 if the
+ getaddrinfo() function failed.
+ - DK4_E_SYNTAX<br>
+ if a non-digit was found in a port number,
+ - DK4_E_SOCKET_GETSERVBYNAME<br>
+ with errno/WSAGetLastError() value in iDetails1 if the
+ getservbyname() function failed to find a port number of a service,
+*/
+dk4_socket_set_t *
+dk4socket_set_udp_service(
+ const dkChar *servicename,
+ int local,
+ int broadcast,
+ dk4_er_t *erp
+);
+
+/*
+ Prepare addresses for UDP client socket.
+ ----------------------------------------
+ Module: dk4sock32
+*/
+
+/** Get address family for generic socket address structure.
+ @param aptr Address of generic socket address structure.
+ @return AF_INET or AF_INET6 on success, AF_UNSPEC on error.
+*/
+int
+dk4socket_address_family(dk4_sockaddr_storage_t *aptr);
+
+/** Get used structure size for generic socket address structure.
+ @param aptr Address of generic socket address structure.
+ @return Size of sockaddr_in or sockaddr_in6 on success, 0 on error.
+*/
+size_t
+dk4socket_address_size(dk4_sockaddr_storage_t *aptr);
+
+/** Complete address structures if IP address was found
+ (add port numbers).
+ @param array Address structures array (2 elements:
+ 0=remote, 1=local).
+ @param remport Remote port number.
+ @param locport Local port number.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error.
+*/
+int
+dk4socket_complete_addresses(
+ dk4_sockaddr_storage_t *array,
+ unsigned short remport,
+ unsigned short locport
+);
+
+/*
+ Prepare addresses for UDP client socket.
+ ----------------------------------------
+ Module: dk4sock33
+*/
+
+/** Find addresses to send UDP packets to a remote host.
+ @param array Destination array (2 elements),
+ element 0 is the remote address to send to,
+ element 1 is the local address to bind.
+ @param remhost Remote host name or IP address.
+ @param remport Remote port number in host representation.
+ @param locport Local port number in host representation.
+ @param ip4 Flag: Prefer IPv4 addresses.
+ @param erp Error report, may be NULL.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ for invalid arguments,
+ - DK4_E_NOT_FOUND<br>
+ if the requested host was not found.
+*/
+int
+dk4socket_c8_udp_addresses_numeric(
+ dk4_sockaddr_storage_t *array,
+ const char *remhost,
+ unsigned short remport,
+ unsigned short locport,
+ int ip4,
+ dk4_er_t *erp
+);
+
+/*
+ Prepare addresses for UDP client socket.
+ ----------------------------------------
+ Module: dk4sock34
+*/
+
+/** Find addresses to send UDP packets to a remote host (wchar_t).
+ @param array Destination array (2 elements),
+ element 0 is the remote address to send to,
+ element 1 is the local address to bind.
+ @param remhost Remote host name or IP address.
+ @param remport Remote port number in host representation.
+ @param locport Local port number in host representation.
+ @param ip4 Flag: Prefer IPv4 addresses.
+ @param erp Error report, may be NULL.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ for invalid arguments,
+ - DK4_E_NOT_FOUND<br>
+ if the requested host was not found.
+*/
+int
+dk4socket_wc_udp_addresses_numeric(
+ dk4_sockaddr_storage_t *array,
+ const wchar_t *remhost,
+ unsigned short remport,
+ unsigned short locport,
+ int ip4,
+ dk4_er_t *erp
+);
+
+
+/** Find addresses to send UDP packets to a remote host (dkChar).
+ @param array Destination array (2 elements),
+ element 0 is the remote address to send to,
+ element 1 is the local address to bind.
+ @param remhost Remote host name or IP address.
+ @param remport Remote port number in host representation.
+ @param locport Local port number in host representation.
+ @param ip4 Flag: Prefer IPv4 addresses.
+ @param erp Error report, may be NULL.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ for invalid arguments,
+ - DK4_E_NOT_FOUND<br>
+ if the requested host was not found.
+ - DK4_E_NOT_SUPPORTED<br>
+ if networking with wide characters is not supported.
+*/
+int
+dk4socket_udp_addresses_numeric(
+ dk4_sockaddr_storage_t *array,
+ const dkChar *remhost,
+ unsigned short remport,
+ unsigned short locport,
+ int ip4,
+ dk4_er_t *erp
+);
+
+
+/*
+ Create UDP socket and bind to local port.
+ -----------------------------------------
+ Module: dk4sock35
+*/
+
+/** Create UDP socket bound to local port.
+ @param protfam Protocol family, PF_INET or PF_INET6.
+ @param pLocalAddr Local address to bind.
+ @param szLocalAddr Size of local address.
+ @param erp Error report. may be NULL.
+ @return Valid socket on success, INVALID_SOCKET on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if pLocalAddr is NULL or szLocalAddr is 0 or protfam is not
+ a valid protocol family,
+ - DK4_E_SOCKET_SOCKET<br>
+ with errno/WSAGetLastError() value in iDetails1 if
+ the socket() function failed,
+ - DK4_E_SOCKET_BIND<br>
+ with errno/WSAGetLastError() value in iDetails1 if the
+ bind() function failed.
+*/
+dk4_socket_t
+dk4socket_udp_client_for_addr(
+ int protfam,
+ struct sockaddr *pLocalAddr,
+ size_t szLocalAddr,
+ dk4_er_t *erp
+);
+
+/*
+ Create UDP socket and bind to local port.
+ -----------------------------------------
+ Module: dk4sock36
+*/
+
+/** Create UDP socket for communication to remote host (char).
+ @param array Destination array (2 elements),
+ element 0 is the remote address we want to send data to,
+ element 1 is the local address to use.
+ @param remhost Remote host name or address.
+ @param remport Remote port number in host representation.
+ @param locport Local port number in host representation.
+ @param ip4 Flag: Prefer IPv4 over IPv6.
+ @param erp Error report, may be NULL.
+ @return Valid socket on success, INVALID_SOCKET on error.
+*/
+dk4_socket_t
+dk4socket_c8_udp_client_for_host(
+ dk4_sockaddr_storage_t *array,
+ const char *remhost,
+ unsigned short remport,
+ unsigned short locport,
+ int ip4,
+ dk4_er_t *erp
+);
+
+/*
+ Create UDP socket and bind to local port.
+ -----------------------------------------
+ Module: dk4sock37
+*/
+
+/** Create UDP socket for communication to remote host (wchar_t).
+ @param array Destination array (2 elements),
+ element 0 is the remote address we want to send data to,
+ element 1 is the local address to use.
+ @param remhost Remote host name or address.
+ @param remport Remote port number in host representation.
+ @param locport Local port number in host representation.
+ @param ip4 Flag: Prefer IPv4 over IPv6.
+ @param erp Error report, may be NULL.
+ @return Valid socket on success, INVALID_SOCKET on error.
+*/
+dk4_socket_t
+dk4socket_wc_udp_client_for_host(
+ dk4_sockaddr_storage_t *array,
+ const wchar_t *remhost,
+ unsigned short remport,
+ unsigned short locport,
+ int ip4,
+ dk4_er_t *erp
+);
+
+/** Create UDP socket for communication to remote host (dkChar).
+ @param array Destination array (2 elements),
+ element 0 is the remote address we want to send data to,
+ element 1 is the local address to use.
+ @param remhost Remote host name or address.
+ @param remport Remote port number in host representation.
+ @param locport Local port number in host representation.
+ @param ip4 Flag: Prefer IPv4 over IPv6.
+ @param erp Error report, may be NULL.
+ @return Valid socket on success, INVALID_SOCKET on error.
+*/
+dk4_socket_t
+dk4socket_udp_client_for_host(
+ dk4_sockaddr_storage_t *array,
+ const dkChar *remhost,
+ unsigned short remport,
+ unsigned short locport,
+ int ip4,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* ifndef DK4SOCK_H_INCLUDED */
+
diff --git a/support/dktools/dk4sock01.c b/support/dktools/dk4sock01.c
new file mode 100644
index 0000000000..e49a0b9089
--- /dev/null
+++ b/support/dktools/dk4sock01.c
@@ -0,0 +1,177 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sock01.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4sock01.c The dk4sock01 module.
+*/
+
+
+#line 10 "dk4sock01.ctr"
+
+#include "dk4sock.h"
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+
+
+
+
+#line 23 "dk4sock01.ctr"
+
+
+
+void
+dk4socket_error_reset(void)
+{
+#if DK4_ON_WINDOWS
+ WSASetLastError(0);
+#else
+ errno = 0;
+ h_errno = 0;
+#endif
+}
+
+
+
+int
+dk4socket_error_get(void)
+{
+#if DK4_ON_WINDOWS
+ return (WSAGetLastError());
+#else
+ return (errno);
+#endif
+}
+
+
+
+void
+dk4socket_error_report(dk4_er_t *erp, int ec)
+{
+#if DK4_ON_WINDOWS
+ dk4error_set_idetails(erp, ec, WSAGetLastError());
+#else
+ switch (ec) {
+ case DK4_E_SOCKET_GETHOSTBYNAME : {
+ dk4error_set_idetails(erp, ec, h_errno);
+ } break;
+ default : {
+ dk4error_set_idetails(erp, ec, errno);
+ } break;
+ }
+#endif
+}
+
+
+void
+dk4socket_debug_address(const char *text, struct sockaddr *addr, size_t sz)
+{
+#if TRACE_DEBUG
+ FILE *fipo;
+ struct sockaddr_in *soin;
+ unsigned long ul;
+ unsigned short us;
+ fipo = dktrace_file();
+ if (NULL != fipo) {
+ if (NULL != text) {
+ fputs(text, fipo);
+ fputc('\n', fipo);
+ }
+ switch (addr->sa_family) {
+ case AF_INET : {
+ fputs("Address family: AF_INET\n", fipo);
+ soin = (struct sockaddr_in *)addr;
+ ul = soin->sin_addr.s_addr;
+ us = soin->sin_port;
+ ul = ntohl(ul);
+ us = ntohs(us);
+ fprintf(
+ fipo,
+ "%lu.%lu.%lu.%lu:%u\n",
+ ((ul >> 24) & 0x000000FFUL),
+ ((ul >> 16) & 0x000000FFUL),
+ ((ul >> 8) & 0x000000FFUL),
+ (ul & 0x000000FFUL),
+ (unsigned)us
+ );
+ } break;
+ case AF_INET6 : {
+ fputs("Address family: AF_INET6\n", fipo);
+ } break;
+ case AF_UNIX : {
+ fputs("Address family: AF_UNIX\n", fipo);
+ } break;
+ default : {
+ fputs("Address family: !UNKNOWN!\n", fipo);
+ } break;
+ }
+ }
+#endif
+}
+
+
+
+#if (DK4_HAVE_SETSOCKOPT) && defined(SOL_SOCKET) && defined(SO_ERROR)
+
+int
+dk4socket_non_null_getsockopt(int optval, socklen_t slo)
+{
+ unsigned char *ptr;
+ socklen_t i;
+ socklen_t max;
+ int back = 0;
+
+
+#line 127 "dk4sock01.ctr"
+ max = sizeof(int);
+ if (slo < max) { max = slo; }
+ ptr = (unsigned char *)(&optval);
+ for (i = 0; ((0 == back) && (i < max)); i++) {
+ if (0x00 != *(ptr++)) {
+ back = 1;
+ }
+ }
+
+
+#line 136 "dk4sock01.ctr"
+ return back;
+}
+
+#endif
+
diff --git a/support/dktools/dk4sock01.ctr b/support/dktools/dk4sock01.ctr
new file mode 100644
index 0000000000..8811430e69
--- /dev/null
+++ b/support/dktools/dk4sock01.ctr
@@ -0,0 +1,140 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4sock.h"
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+
+
+$!trace-include
+
+
+
+void
+dk4socket_error_reset(void)
+{
+#if DK4_ON_WINDOWS
+ WSASetLastError(0);
+#else
+ errno = 0;
+ h_errno = 0;
+#endif
+}
+
+
+
+int
+dk4socket_error_get(void)
+{
+#if DK4_ON_WINDOWS
+ return (WSAGetLastError());
+#else
+ return (errno);
+#endif
+}
+
+
+
+void
+dk4socket_error_report(dk4_er_t *erp, int ec)
+{
+#if DK4_ON_WINDOWS
+ dk4error_set_idetails(erp, ec, WSAGetLastError());
+#else
+ switch (ec) {
+ case DK4_E_SOCKET_GETHOSTBYNAME : {
+ dk4error_set_idetails(erp, ec, h_errno);
+ } break;
+ default : {
+ dk4error_set_idetails(erp, ec, errno);
+ } break;
+ }
+#endif
+}
+
+
+void
+dk4socket_debug_address(const char *text, struct sockaddr *addr, size_t sz)
+{
+#if TRACE_DEBUG
+ FILE *fipo;
+ struct sockaddr_in *soin;
+ unsigned long ul;
+ unsigned short us;
+ fipo = dktrace_file();
+ if (NULL != fipo) {
+ if (NULL != text) {
+ fputs(text, fipo);
+ fputc('\n', fipo);
+ }
+ switch (addr->sa_family) {
+ case AF_INET : {
+ fputs("Address family: AF_INET\n", fipo);
+ soin = (struct sockaddr_in *)addr;
+ ul = soin->sin_addr.s_addr;
+ us = soin->sin_port;
+ ul = ntohl(ul);
+ us = ntohs(us);
+ fprintf(
+ fipo,
+ "%lu.%lu.%lu.%lu:%u\n",
+ ((ul >> 24) & 0x000000FFUL),
+ ((ul >> 16) & 0x000000FFUL),
+ ((ul >> 8) & 0x000000FFUL),
+ (ul & 0x000000FFUL),
+ (unsigned)us
+ );
+ } break;
+ case AF_INET6 : {
+ fputs("Address family: AF_INET6\n", fipo);
+ } break;
+ case AF_UNIX : {
+ fputs("Address family: AF_UNIX\n", fipo);
+ } break;
+ default : {
+ fputs("Address family: !UNKNOWN!\n", fipo);
+ } break;
+ }
+ }
+#endif
+}
+
+
+
+#if (DK4_HAVE_SETSOCKOPT) && defined(SOL_SOCKET) && defined(SO_ERROR)
+
+int
+dk4socket_non_null_getsockopt(int optval, socklen_t slo)
+{
+ unsigned char *ptr;
+ socklen_t i;
+ socklen_t max;
+ int back = 0;
+ $? "+ dk4socket_non_null_getsockopt %d %d", optval, (int)slo
+ max = sizeof(int);
+ if (slo < max) { max = slo; }
+ ptr = (unsigned char *)(&optval);
+ for (i = 0; ((0 == back) && (i < max)); i++) {
+ if (0x00 != *(ptr++)) {
+ back = 1;
+ }
+ }
+ $? "- dk4socket_non_null_getsockopt %d", back
+ return back;
+}
+
+#endif
+
diff --git a/support/dktools/dk4sock02.c b/support/dktools/dk4sock02.c
new file mode 100644
index 0000000000..a33a52c729
--- /dev/null
+++ b/support/dktools/dk4sock02.c
@@ -0,0 +1,453 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sock02.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#line 8 "dk4sock02.ctr"
+
+/** @file dk4sock01.c Conversion between host and net representation.
+*/
+
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4sock.h"
+
+#if DK4_HAVE_STRINGS_H
+#ifndef STRINGS_H_INCLUDED
+#include <strings.h>
+#define STRINGS_H_INCLUDED 1
+#endif
+#endif
+
+#if (!DK4_ON_WINDOWS) \
+&& (DK4_HAVE_HTONS || DK4_HAVE_NTOHS || DK4_HAVE_HTONL || DK4_HAVE_NTOHL)
+
+#if DK4_HAVE_ARPA_INET_H
+#ifndef ARPA_INET_H_INCLUDED
+#include <arpa/inet.h>
+#define ARPA_INET_H_INCLUDED 1
+#endif
+#endif
+#if DK4_HAVE_NETINET_IN_H
+#ifndef NETINET_IN_H_INCLUDED
+#include <netinet/in.h>
+#define NETINET_IN_H_INCLUDED 1
+#endif
+#endif
+
+#endif
+
+
+#if DK4_ON_WINDOWS || (!DK4_HAVE_HTONS) || (!DK4_HAVE_NTOHS)
+#if !DK4_WORDS_BIGENDIAN
+
+static
+uint16_t
+dk4socket_short_swap(uint16_t u)
+{
+ return (
+ ((u >> 8) & 0x00FFU)
+ | ((u << 8) & 0xFF00U)
+ );
+}
+
+#endif
+#endif
+
+#if DK4_ON_WINDOWS || (!DK4_HAVE_HTONL) || (!DK4_HAVE_NTOHL)
+#if !DK4_WORDS_BIGENDIAN
+
+static
+uint32_t
+dk4socket_long_swap(uint32_t u)
+{
+ return (
+ ( (u >> 24) & 0x000000FFUL)
+ | ((u >> 8) & 0x0000FF00UL)
+ | ((u << 8) & 0x00FF0000UL)
+ | ((u << 24) & 0xFF000000UL)
+ );
+}
+
+#endif
+#endif
+
+uint16_t
+dk4socket_htons(uint16_t u)
+{
+#if DK4_HAVE_HTONS && (!DK4_ON_WINDOWS)
+ return (htons(u));
+#else
+#if DK4_WORDS_BIGENDIAN
+ return u;
+#else
+ return (dk4socket_short_swap(u));
+#endif
+#endif
+}
+
+
+
+uint16_t
+dk4socket_ntohs(uint16_t u)
+{
+#if DK4_HAVE_NTOHS && (!DK4_ON_WINDOWS)
+ return (ntohs(u));
+#else
+#if DK4_WORDS_BIGENDIAN
+ return u;
+#else
+ return (dk4socket_short_swap(u));
+#endif
+#endif
+}
+
+uint32_t
+dk4socket_htonl(uint32_t u)
+{
+#if DK4_HAVE_HTONL && (!DK4_ON_WINDOWS)
+ return (htonl(u));
+#else
+#if DK4_WORDS_BIGENDIAN
+ return u;
+#else
+ return (dk4socket_long_swap(u));
+#endif
+#endif
+}
+
+uint32_t
+dk4socket_ntohl(uint32_t u)
+{
+#if DK4_HAVE_NTOHL && (!DK4_ON_WINDOWS)
+ return (ntohl(u));
+#else
+#if DK4_WORDS_BIGENDIAN
+ return u;
+#else
+ return (dk4socket_long_swap(u));
+#endif
+#endif
+}
+
+void
+dk4socket_swap_bytes_if_not_bigendian(void *buf, size_t sz)
+{
+#if !DK4_WORDS_BIGENDIAN
+ unsigned char *ucp; /* Buffer address converted ty bytes pointer */
+ size_t szh; /* Half of the size sz */
+ size_t i; /* Current byte index, 0 to szh-1 */
+ unsigned char u; /* Byte variable used to swap bytes */
+
+ if ((NULL != buf) && (0 < sz)) {
+ ucp = (unsigned char *)buf;
+ szh = sz / 2;
+ for (i = 0; i < szh; i++) {
+ u = ucp[i];
+ ucp[i] = ucp[sz - 1 - i];
+ ucp[sz - 1 - i] = u;
+ }
+ }
+#endif
+}
+
+
+
+int
+dk4socket_mask_bits(unsigned long *dptr, size_t sz, dk4_er_t *erp)
+{
+ unsigned long res = 0UL;
+ unsigned long val = 0x80000000UL;
+ int back = DK4_SOCKET_RESULT_FAILED;
+ if (NULL != dptr) {
+ if ((0 < sz) && (33 > sz)) {
+ while (0 < sz--) {
+ res |= val;
+ val = val / 2UL;
+ }
+ *dptr = res;
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+
+int
+dk4socket_mask6_bits(struct in6_addr *inp, size_t sz, dk4_er_t *erp)
+{
+ int back = DK4_SOCKET_RESULT_FAILED;
+ size_t i = 0;
+ size_t j = 0;
+ unsigned char rchr = 0x00;
+ unsigned char vchr = 0x80;
+
+ if (NULL != inp) {
+ for (i = 0; i < 16; i++) { inp->s6_addr[i] = 0xFF; }
+ if ((0 < sz) && (129 > sz)) {
+ for (i = 0; i < 16; i++) {
+ rchr = 0x00;
+ vchr = 0x80;
+ for (j = 0; j < 8; j++) {
+ if (0 < sz) {
+ rchr |= vchr;
+ sz--;
+ }
+ vchr = vchr / 2;
+ }
+ inp->s6_addr[i] = rchr;
+ }
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+#endif
+
+
+
+void
+dk4socket_set_one_bytes(void *ptr, size_t nbytes)
+{
+ unsigned char *cptr;
+ cptr = ptr;
+ while (0 < nbytes--) { *(cptr++) = 0x01; }
+}
+
+
+
+#if DK4_HAVE_STRUCT_SOCKADDR_UN
+
+size_t
+dk4socket_unix_length(const struct sockaddr_un *sock)
+{
+ size_t back = 0;
+ if (NULL != sock) {
+#ifdef SUN_LEN
+ back = SUN_LEN(sock);
+#else
+ back = sizeof(struct sockaddr_un)
+ - sizeof(sock->sun_path)
+ + strlen(sock->sun_path);
+#endif
+ }
+ return back;
+}
+
+#endif
+
+
+int
+dk4socket_pf_for_af(int af)
+{
+ int back = 0;
+ switch (af) {
+
+#if defined(AF_UNSPEC) && defined(PF_UNSPEC)
+ case AF_UNSPEC : { back = PF_UNSPEC ; } break;
+#endif
+#if defined(AF_UNIX) && defined(PF_UNIX)
+ case AF_UNIX : { back = PF_UNIX ; } break;
+#endif
+#if defined(AF_LOCAL) && defined(PF_LOCAL) && \
+ (!(defined(AF_UNIX) && defined(PF_UNIX)))
+ case AF_LOCAL : { back = PF_LOCAL ; } break;
+#endif
+#if defined(AF_FILE) && defined(PF_FILE) && \
+ (!(defined(AF_UNIX) && defined(PF_UNIX))) && \
+ (!(defined(AF_LOCAL) && defined(PF_LOCAL)))
+ case AF_FILE : { back = PF_FILE ; } break;
+#endif
+#if defined(AF_INET) && defined(PF_INET)
+ case AF_INET : { back = PF_INET ; } break;
+#endif
+#if defined(AF_AX25) && defined(PF_AX25)
+ case AF_AX25 : { back = PF_AX25 ; } break;
+#endif
+#if defined(AF_IPX) && defined(PF_IPX)
+ case AF_IPX : { back = PF_IPX ; } break;
+#endif
+#if defined(AF_APPLETALK) && defined(PF_APPLETALK)
+ case AF_APPLETALK : { back = PF_APPLETALK ; } break;
+#endif
+#if defined(AF_NETROM) && defined(PF_NETROM)
+ case AF_NETROM : { back = PF_NETROM ; } break;
+#endif
+#if defined(AF_BRIDGE) && defined(PF_BRIDGE)
+ case AF_BRIDGE : { back = PF_BRIDGE ; } break;
+#endif
+#if defined(AF_ATMPVC) && defined(PF_ATMPVC)
+ case AF_ATMPVC : { back = PF_ATMPVC ; } break;
+#endif
+#if defined(AF_X25) && defined(PF_X25)
+ case AF_X25 : { back = PF_X25 ; } break;
+#endif
+#if defined(AF_INET6) && defined(PF_INET6)
+ case AF_INET6 : { back = PF_INET6 ; } break;
+#endif
+#if defined(AF_ROSE) && defined(PF_ROSE)
+ case AF_ROSE : { back = PF_ROSE ; } break;
+#endif
+#if defined(AF_DECnet) && defined(PF_DECnet)
+ case AF_DECnet : { back = PF_DECnet ; } break;
+#endif
+#if defined(AF_NETBEUI) && defined(PF_NETBEUI)
+ case AF_NETBEUI : { back = PF_NETBEUI ; } break;
+#endif
+#if defined(AF_SECURITY) && defined(PF_SECURITY)
+ case AF_SECURITY : { back = PF_SECURITY ; } break;
+#endif
+#if defined(AF_KEY) && defined(PF_KEY)
+ case AF_KEY : { back = PF_KEY ; } break;
+#endif
+#if defined(AF_NETLINK) && defined(PF_NETLINK)
+ case AF_NETLINK : { back = PF_NETLINK ; } break;
+#endif
+#if defined(AF_ROUTE) && defined(PF_ROUTE) && \
+ (!(defined(AF_NETLINK) && defined(PF_NETLINK)))
+ case AF_ROUTE : { back = PF_ROUTE ; } break;
+#endif
+#if defined(AF_PACKET) && defined(PF_PACKET)
+ case AF_PACKET : { back = PF_PACKET ; } break;
+#endif
+#if defined(AF_ASH) && defined(PF_ASH)
+ case AF_ASH : { back = PF_ASH ; } break;
+#endif
+#if defined(AF_ECONET) && defined(PF_ECONET)
+ case AF_ECONET : { back = PF_ECONET ; } break;
+#endif
+#if defined(AF_ATMSVC) && defined(PF_ATMSVC)
+ case AF_ATMSVC : { back = PF_ATMSVC ; } break;
+#endif
+#if defined(AF_RDS) && defined(PF_RDS)
+ case AF_RDS : { back = PF_RDS ; } break;
+#endif
+#if defined(AF_SNA) && defined(PF_SNA)
+ case AF_SNA : { back = PF_SNA ; } break;
+#endif
+#if defined(AF_IRDA) && defined(PF_IRDA)
+ case AF_IRDA : { back = PF_IRDA ; } break;
+#endif
+#if defined(AF_PPPOX) && defined(PF_PPPOX)
+ case AF_PPPOX : { back = PF_PPPOX ; } break;
+#endif
+#if defined(AF_WANPIPE) && defined(PF_WANPIPE)
+ case AF_WANPIPE : { back = PF_WANPIPE ; } break;
+#endif
+#if defined(AF_LLC) && defined(PF_LLC)
+ case AF_LLC : { back = PF_LLC ; } break;
+#endif
+#if defined(AF_CAN) && defined(PF_CAN)
+ case AF_CAN : { back = PF_CAN ; } break;
+#endif
+#if defined(AF_TIPC) && defined(PF_TIPC)
+ case AF_TIPC : { back = PF_TIPC ; } break;
+#endif
+#if defined(AF_BLUETOOTH) && defined(PF_BLUETOOTH)
+ case AF_BLUETOOTH : { back = PF_BLUETOOTH ; } break;
+#endif
+#if defined(AF_IUCV) && defined(PF_IUCV)
+ case AF_IUCV : { back = PF_IUCV ; } break;
+#endif
+#if defined(AF_RXRPC) && defined(PF_RXRPC)
+ case AF_RXRPC : { back = PF_RXRPC ; } break;
+#endif
+#if defined(AF_ISDN) && defined(PF_ISDN)
+ case AF_ISDN : { back = PF_ISDN ; } break;
+#endif
+#if defined(AF_PHONET) && defined(PF_PHONET)
+ case AF_PHONET : { back = PF_PHONET ; } break;
+#endif
+#if defined(AF_IEEE802154) && defined(PF_IEEE802154)
+ case AF_IEEE802154 : { back = PF_IEEE802154 ; } break;
+#endif
+#if defined(AF_CAIF) && defined(PF_CAIF)
+ case AF_CAIF : { back = PF_CAIF ; } break;
+#endif
+#if defined(AF_ALG) && defined(PF_ALG)
+ case AF_ALG : { back = PF_ALG ; } break;
+#endif
+#if defined(AF_NFC) && defined(PF_NFC)
+ case AF_NFC : { back = PF_NFC ; } break;
+#endif
+#if defined(AF_VSOCK) && defined(PF_VSOCK)
+ case AF_VSOCK : { back = PF_VSOCK ; } break;
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk4socket_correct_addr_lgt(const struct sockaddr *soa, size_t *plgt)
+{
+ int back = 0;
+ if ((NULL != soa) && (NULL != plgt)) {
+ back = 1;
+ switch (soa->sa_family) {
+ case AF_INET : {
+ if (sizeof(struct sockaddr_in) <= *plgt) {
+ *plgt = sizeof(struct sockaddr_in);
+ } else {
+ back = 0;
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ if (sizeof(struct sockaddr_in6) <= *plgt) {
+ *plgt = sizeof(struct sockaddr_in6);
+ } else {
+ back = 0;
+ }
+ } break;
+#endif
+ }
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4sock02.ctr b/support/dktools/dk4sock02.ctr
new file mode 100644
index 0000000000..8e39a7dc7b
--- /dev/null
+++ b/support/dktools/dk4sock02.ctr
@@ -0,0 +1,423 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+%% module
+
+/** @file dk4sock01.c Conversion between host and net representation.
+*/
+
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4sock.h"
+
+#if DK4_HAVE_STRINGS_H
+#ifndef STRINGS_H_INCLUDED
+#include <strings.h>
+#define STRINGS_H_INCLUDED 1
+#endif
+#endif
+
+#if (!DK4_ON_WINDOWS) \
+&& (DK4_HAVE_HTONS || DK4_HAVE_NTOHS || DK4_HAVE_HTONL || DK4_HAVE_NTOHL)
+
+#if DK4_HAVE_ARPA_INET_H
+#ifndef ARPA_INET_H_INCLUDED
+#include <arpa/inet.h>
+#define ARPA_INET_H_INCLUDED 1
+#endif
+#endif
+#if DK4_HAVE_NETINET_IN_H
+#ifndef NETINET_IN_H_INCLUDED
+#include <netinet/in.h>
+#define NETINET_IN_H_INCLUDED 1
+#endif
+#endif
+
+#endif
+
+
+#if DK4_ON_WINDOWS || (!DK4_HAVE_HTONS) || (!DK4_HAVE_NTOHS)
+#if !DK4_WORDS_BIGENDIAN
+
+static
+uint16_t
+dk4socket_short_swap(uint16_t u)
+{
+ return (
+ ((u >> 8) & 0x00FFU)
+ | ((u << 8) & 0xFF00U)
+ );
+}
+
+#endif
+#endif
+
+#if DK4_ON_WINDOWS || (!DK4_HAVE_HTONL) || (!DK4_HAVE_NTOHL)
+#if !DK4_WORDS_BIGENDIAN
+
+static
+uint32_t
+dk4socket_long_swap(uint32_t u)
+{
+ return (
+ ( (u >> 24) & 0x000000FFUL)
+ | ((u >> 8) & 0x0000FF00UL)
+ | ((u << 8) & 0x00FF0000UL)
+ | ((u << 24) & 0xFF000000UL)
+ );
+}
+
+#endif
+#endif
+
+uint16_t
+dk4socket_htons(uint16_t u)
+{
+#if DK4_HAVE_HTONS && (!DK4_ON_WINDOWS)
+ return (htons(u));
+#else
+#if DK4_WORDS_BIGENDIAN
+ return u;
+#else
+ return (dk4socket_short_swap(u));
+#endif
+#endif
+}
+
+
+
+uint16_t
+dk4socket_ntohs(uint16_t u)
+{
+#if DK4_HAVE_NTOHS && (!DK4_ON_WINDOWS)
+ return (ntohs(u));
+#else
+#if DK4_WORDS_BIGENDIAN
+ return u;
+#else
+ return (dk4socket_short_swap(u));
+#endif
+#endif
+}
+
+uint32_t
+dk4socket_htonl(uint32_t u)
+{
+#if DK4_HAVE_HTONL && (!DK4_ON_WINDOWS)
+ return (htonl(u));
+#else
+#if DK4_WORDS_BIGENDIAN
+ return u;
+#else
+ return (dk4socket_long_swap(u));
+#endif
+#endif
+}
+
+uint32_t
+dk4socket_ntohl(uint32_t u)
+{
+#if DK4_HAVE_NTOHL && (!DK4_ON_WINDOWS)
+ return (ntohl(u));
+#else
+#if DK4_WORDS_BIGENDIAN
+ return u;
+#else
+ return (dk4socket_long_swap(u));
+#endif
+#endif
+}
+
+void
+dk4socket_swap_bytes_if_not_bigendian(void *buf, size_t sz)
+{
+#if !DK4_WORDS_BIGENDIAN
+ unsigned char *ucp; /* Buffer address converted ty bytes pointer */
+ size_t szh; /* Half of the size sz */
+ size_t i; /* Current byte index, 0 to szh-1 */
+ unsigned char u; /* Byte variable used to swap bytes */
+
+ if ((NULL != buf) && (0 < sz)) {
+ ucp = (unsigned char *)buf;
+ szh = sz / 2;
+ for (i = 0; i < szh; i++) {
+ u = ucp[i];
+ ucp[i] = ucp[sz - 1 - i];
+ ucp[sz - 1 - i] = u;
+ }
+ }
+#endif
+}
+
+
+
+int
+dk4socket_mask_bits(unsigned long *dptr, size_t sz, dk4_er_t *erp)
+{
+ unsigned long res = 0UL;
+ unsigned long val = 0x80000000UL;
+ int back = DK4_SOCKET_RESULT_FAILED;
+ if (NULL != dptr) {
+ if ((0 < sz) && (33 > sz)) {
+ while (0 < sz--) {
+ res |= val;
+ val = val / 2UL;
+ }
+ *dptr = res;
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+
+int
+dk4socket_mask6_bits(struct in6_addr *inp, size_t sz, dk4_er_t *erp)
+{
+ int back = DK4_SOCKET_RESULT_FAILED;
+ size_t i = 0;
+ size_t j = 0;
+ unsigned char rchr = 0x00;
+ unsigned char vchr = 0x80;
+
+ if (NULL != inp) {
+ for (i = 0; i < 16; i++) { inp->s6_addr[i] = 0xFF; }
+ if ((0 < sz) && (129 > sz)) {
+ for (i = 0; i < 16; i++) {
+ rchr = 0x00;
+ vchr = 0x80;
+ for (j = 0; j < 8; j++) {
+ if (0 < sz) {
+ rchr |= vchr;
+ sz--;
+ }
+ vchr = vchr / 2;
+ }
+ inp->s6_addr[i] = rchr;
+ }
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+#endif
+
+
+
+void
+dk4socket_set_one_bytes(void *ptr, size_t nbytes)
+{
+ unsigned char *cptr;
+ cptr = ptr;
+ while (0 < nbytes--) { *(cptr++) = 0x01; }
+}
+
+
+
+#if DK4_HAVE_STRUCT_SOCKADDR_UN
+
+size_t
+dk4socket_unix_length(const struct sockaddr_un *sock)
+{
+ size_t back = 0;
+ if (NULL != sock) {
+#ifdef SUN_LEN
+ back = SUN_LEN(sock);
+#else
+ back = sizeof(struct sockaddr_un)
+ - sizeof(sock->sun_path)
+ + strlen(sock->sun_path);
+#endif
+ }
+ return back;
+}
+
+#endif
+
+
+int
+dk4socket_pf_for_af(int af)
+{
+ int back = 0;
+ switch (af) {
+
+#if defined(AF_UNSPEC) && defined(PF_UNSPEC)
+ case AF_UNSPEC : { back = PF_UNSPEC ; } break;
+#endif
+#if defined(AF_UNIX) && defined(PF_UNIX)
+ case AF_UNIX : { back = PF_UNIX ; } break;
+#endif
+#if defined(AF_LOCAL) && defined(PF_LOCAL) && \
+ (!(defined(AF_UNIX) && defined(PF_UNIX)))
+ case AF_LOCAL : { back = PF_LOCAL ; } break;
+#endif
+#if defined(AF_FILE) && defined(PF_FILE) && \
+ (!(defined(AF_UNIX) && defined(PF_UNIX))) && \
+ (!(defined(AF_LOCAL) && defined(PF_LOCAL)))
+ case AF_FILE : { back = PF_FILE ; } break;
+#endif
+#if defined(AF_INET) && defined(PF_INET)
+ case AF_INET : { back = PF_INET ; } break;
+#endif
+#if defined(AF_AX25) && defined(PF_AX25)
+ case AF_AX25 : { back = PF_AX25 ; } break;
+#endif
+#if defined(AF_IPX) && defined(PF_IPX)
+ case AF_IPX : { back = PF_IPX ; } break;
+#endif
+#if defined(AF_APPLETALK) && defined(PF_APPLETALK)
+ case AF_APPLETALK : { back = PF_APPLETALK ; } break;
+#endif
+#if defined(AF_NETROM) && defined(PF_NETROM)
+ case AF_NETROM : { back = PF_NETROM ; } break;
+#endif
+#if defined(AF_BRIDGE) && defined(PF_BRIDGE)
+ case AF_BRIDGE : { back = PF_BRIDGE ; } break;
+#endif
+#if defined(AF_ATMPVC) && defined(PF_ATMPVC)
+ case AF_ATMPVC : { back = PF_ATMPVC ; } break;
+#endif
+#if defined(AF_X25) && defined(PF_X25)
+ case AF_X25 : { back = PF_X25 ; } break;
+#endif
+#if defined(AF_INET6) && defined(PF_INET6)
+ case AF_INET6 : { back = PF_INET6 ; } break;
+#endif
+#if defined(AF_ROSE) && defined(PF_ROSE)
+ case AF_ROSE : { back = PF_ROSE ; } break;
+#endif
+#if defined(AF_DECnet) && defined(PF_DECnet)
+ case AF_DECnet : { back = PF_DECnet ; } break;
+#endif
+#if defined(AF_NETBEUI) && defined(PF_NETBEUI)
+ case AF_NETBEUI : { back = PF_NETBEUI ; } break;
+#endif
+#if defined(AF_SECURITY) && defined(PF_SECURITY)
+ case AF_SECURITY : { back = PF_SECURITY ; } break;
+#endif
+#if defined(AF_KEY) && defined(PF_KEY)
+ case AF_KEY : { back = PF_KEY ; } break;
+#endif
+#if defined(AF_NETLINK) && defined(PF_NETLINK)
+ case AF_NETLINK : { back = PF_NETLINK ; } break;
+#endif
+#if defined(AF_ROUTE) && defined(PF_ROUTE) && \
+ (!(defined(AF_NETLINK) && defined(PF_NETLINK)))
+ case AF_ROUTE : { back = PF_ROUTE ; } break;
+#endif
+#if defined(AF_PACKET) && defined(PF_PACKET)
+ case AF_PACKET : { back = PF_PACKET ; } break;
+#endif
+#if defined(AF_ASH) && defined(PF_ASH)
+ case AF_ASH : { back = PF_ASH ; } break;
+#endif
+#if defined(AF_ECONET) && defined(PF_ECONET)
+ case AF_ECONET : { back = PF_ECONET ; } break;
+#endif
+#if defined(AF_ATMSVC) && defined(PF_ATMSVC)
+ case AF_ATMSVC : { back = PF_ATMSVC ; } break;
+#endif
+#if defined(AF_RDS) && defined(PF_RDS)
+ case AF_RDS : { back = PF_RDS ; } break;
+#endif
+#if defined(AF_SNA) && defined(PF_SNA)
+ case AF_SNA : { back = PF_SNA ; } break;
+#endif
+#if defined(AF_IRDA) && defined(PF_IRDA)
+ case AF_IRDA : { back = PF_IRDA ; } break;
+#endif
+#if defined(AF_PPPOX) && defined(PF_PPPOX)
+ case AF_PPPOX : { back = PF_PPPOX ; } break;
+#endif
+#if defined(AF_WANPIPE) && defined(PF_WANPIPE)
+ case AF_WANPIPE : { back = PF_WANPIPE ; } break;
+#endif
+#if defined(AF_LLC) && defined(PF_LLC)
+ case AF_LLC : { back = PF_LLC ; } break;
+#endif
+#if defined(AF_CAN) && defined(PF_CAN)
+ case AF_CAN : { back = PF_CAN ; } break;
+#endif
+#if defined(AF_TIPC) && defined(PF_TIPC)
+ case AF_TIPC : { back = PF_TIPC ; } break;
+#endif
+#if defined(AF_BLUETOOTH) && defined(PF_BLUETOOTH)
+ case AF_BLUETOOTH : { back = PF_BLUETOOTH ; } break;
+#endif
+#if defined(AF_IUCV) && defined(PF_IUCV)
+ case AF_IUCV : { back = PF_IUCV ; } break;
+#endif
+#if defined(AF_RXRPC) && defined(PF_RXRPC)
+ case AF_RXRPC : { back = PF_RXRPC ; } break;
+#endif
+#if defined(AF_ISDN) && defined(PF_ISDN)
+ case AF_ISDN : { back = PF_ISDN ; } break;
+#endif
+#if defined(AF_PHONET) && defined(PF_PHONET)
+ case AF_PHONET : { back = PF_PHONET ; } break;
+#endif
+#if defined(AF_IEEE802154) && defined(PF_IEEE802154)
+ case AF_IEEE802154 : { back = PF_IEEE802154 ; } break;
+#endif
+#if defined(AF_CAIF) && defined(PF_CAIF)
+ case AF_CAIF : { back = PF_CAIF ; } break;
+#endif
+#if defined(AF_ALG) && defined(PF_ALG)
+ case AF_ALG : { back = PF_ALG ; } break;
+#endif
+#if defined(AF_NFC) && defined(PF_NFC)
+ case AF_NFC : { back = PF_NFC ; } break;
+#endif
+#if defined(AF_VSOCK) && defined(PF_VSOCK)
+ case AF_VSOCK : { back = PF_VSOCK ; } break;
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk4socket_correct_addr_lgt(const struct sockaddr *soa, size_t *plgt)
+{
+ int back = 0;
+ if ((NULL != soa) && (NULL != plgt)) {
+ back = 1;
+ switch (soa->sa_family) {
+ case AF_INET : {
+ if (sizeof(struct sockaddr_in) <= *plgt) {
+ *plgt = sizeof(struct sockaddr_in);
+ } else {
+ back = 0;
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ if (sizeof(struct sockaddr_in6) <= *plgt) {
+ *plgt = sizeof(struct sockaddr_in6);
+ } else {
+ back = 0;
+ }
+ } break;
+#endif
+ }
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4sock03.c b/support/dktools/dk4sock03.c
new file mode 100644
index 0000000000..97696625f5
--- /dev/null
+++ b/support/dktools/dk4sock03.c
@@ -0,0 +1,436 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sock03.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4sock03.c The dk4sock03 module.
+*/
+
+
+#line 10 "dk4sock03.ctr"
+
+#include "dk4sock.h"
+#include "dk4mem.h"
+#include "dk4str8.h"
+#include "dk4strd.h"
+#include "dk4mao8d.h"
+#include "dk4mao8h.h"
+#include "dk4rec23.h"
+
+
+
+
+
+#line 22 "dk4sock03.ctr"
+
+
+
+/** Constant texts used by the module, not localized.
+*/
+static const char * const dk4socket_c8_kw[] = {
+/* 0 */
+"@",
+
+/* 1 */
+".",
+
+/* 2 */
+":",
+
+NULL
+
+
+#line 42 "dk4sock03.ctr"
+};
+
+
+
+int
+dk4socket_c8_inet_ntop(
+ char *dptr,
+ size_t dsz,
+ int afam,
+ const void *src,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_INET_NTOP
+#if DK4_ON_WINDOWS
+ /* +++++ +inet_ntop +Windows */
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ struct in6_addr in6; /* IPv6 host address */
+#endif
+ struct in_addr in4; /* IPv4 host address */
+ int back = DK4_SOCKET_RESULT_FAILED;
+
+ if ((NULL != dptr) && (0 < dsz)) { *dptr = '\0'; }
+ if ((NULL != dptr) && (NULL != src) && (0 < dsz)) {
+ dk4socket_error_reset();
+ switch (afam) {
+ case AF_INET : {
+ DK4_MEMCPY(&in4, src, sizeof(in4));
+ if (NULL != inet_ntop(afam, (void *)(&in4), dptr, dsz)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_INET_NTOP);
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ DK4_MEMCPY(&in6, src, sizeof(in6));
+ if (NULL != inet_ntop(afam, (void *)(&in6), dptr, dsz)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_INET_NTOP);
+ }
+ } break;
+#endif
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- +inet_ntop +Windows */
+#else
+ /* +++++ +inet_ntop -Windows */
+ int back = DK4_SOCKET_RESULT_FAILED;
+ if ((NULL != dptr) && (0 < dsz)) { *dptr = '\0'; }
+ if ((NULL != dptr) && (NULL != src) && (0 < dsz)) {
+ if (NULL != inet_ntop(afam, src, dptr, dsz)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_INET_NTOP);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- +inet_ntop -Windows */
+#endif
+#else
+ /* +++++ -inet_ntop */
+ char buf[16*sizeof(dk4_um_t)];
+ const struct in_addr *inp4;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ const struct in6_addr *inp6;
+#endif
+ unsigned long ul;
+ unsigned long u1;
+ int back = DK4_SOCKET_RESULT_FAILED;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ int i;
+#endif
+ int res;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ unsigned short us;
+#endif
+
+ if ((NULL != dptr) && (0 < dsz)) { *dptr = '\0'; }
+ if ((NULL != dptr) && (NULL != src) && (0 < dsz)) {
+ switch (afam) {
+ case AF_INET : {
+ inp4 = (const struct in_addr *)src;
+ ul = inp4->s_addr;
+ ul = dk4socket_htonl(ul);
+ u1 = ((ul >> 24) & 0x000000FFUL);
+ res = dk4ma_write_c8_decimal_unsigned(
+ buf, sizeof(buf), (dk4_um_t)u1, 0, erp
+ );
+ if (0 != res) {
+ if (0 != dk4str8_cpy_s(dptr, dsz, buf, erp)) {
+ u1 = ((ul >> 16) & 0x000000FFUL);
+ res = dk4ma_write_c8_decimal_unsigned(
+ buf, sizeof(buf), (dk4_um_t)u1, 0, erp
+ );
+ if (0 != res) {
+ if (0 != dk4str8_cat_s(dptr, dsz, dk4socket_c8_kw[1], erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, buf, erp)) {
+ u1 = ((ul >> 8) & 0x000000FFUL);
+ res = dk4ma_write_c8_decimal_unsigned(
+ buf, sizeof(buf), (dk4_um_t)u1, 0, erp
+ );
+ if (0 != res) {
+ if (0 != dk4str8_cat_s(dptr,dsz,dk4socket_c8_kw[1],erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, buf, erp)) {
+ u1 = (ul & 0x000000FFUL);
+ res = dk4ma_write_c8_decimal_unsigned(
+ buf, sizeof(buf), (dk4_um_t)u1, 0, erp
+ );
+ if (0 != res) {
+ if (
+ 0 != dk4str8_cat_s(dptr,dsz,dk4socket_c8_kw[1],erp)
+ )
+ {
+ if (0 != dk4str8_cat_s(dptr, dsz, buf, erp)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ inp6 = (const struct in6_addr *)src;
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ for (i = 0; i < 8; i++) {
+#if DK4_ON_WINDOWS
+ us = inp6->u.Word[i];
+#else
+ us = inp6->s6_addr16[i];
+#endif
+ us = dk4socket_htons(us);
+ res = dk4ma_write_c8_hex_unsigned(
+ buf, sizeof(buf), (dk4_um_t)us, 0, erp
+ );
+ if (0 != res) {
+ if (0 == i) {
+ if (0 == dk4str8_cpy_s(dptr, dsz, buf, erp)) {
+ back = DK4_SOCKET_RESULT_FAILED;
+ i = 8;
+ }
+ } else {
+ if (0 != dk4str8_cat_s(dptr, dsz, dk4socket_c8_kw[2], erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, buf, erp)) {
+ back = DK4_SOCKET_RESULT_FAILED;
+ i = 8;
+ }
+ } else {
+ back = DK4_SOCKET_RESULT_FAILED;
+ i = 8;
+ }
+ }
+ } else {
+ back = DK4_SOCKET_RESULT_FAILED;
+ i = 8;
+ }
+ }
+ } break;
+#endif
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- -inet_ntop */
+#endif
+}
+
+
+
+int
+dk4socket_c8_addr_port_to_text(
+ char *dptr,
+ size_t dsz,
+ int afam,
+ const struct sockaddr *saptr,
+ size_t sasz,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_GETNAMEINFO
+ /* +++++ +getnameinfo */
+ char hbuf[64]; /* Buffer for host address */
+ char pbuf[64]; /* Buffer for port number */
+ int res; /* Operation result */
+ int back = DK4_SOCKET_RESULT_FAILED;
+
+
+#line 248 "dk4sock03.ctr"
+ if ((NULL != dptr) && (0 < dsz)) { *dptr = '\0'; }
+ if ((NULL != dptr) && (NULL != saptr) && (0 < dsz) && (0 < sasz)) {
+ res = NI_NUMERICHOST | NI_NUMERICSERV;
+ dk4socket_error_reset();
+#if DK4_HAVE_SOCKLEN_T
+ res = getnameinfo(
+ saptr, (socklen_t)sasz, hbuf, sizeof(hbuf), pbuf, sizeof(pbuf), res
+ );
+#else
+ res = getnameinfo(saptr, sasz, hbuf, sizeof(hbuf), pbuf, sizeof(pbuf), res);
+#endif
+ if (0 == res) {
+ if (0 != dk4str8_cpy_s(dptr, dsz, pbuf, erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, dk4socket_c8_kw[0], erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, hbuf, erp)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+
+#line 265 "dk4sock03.ctr"
+ }
+ } else {
+
+#line 267 "dk4sock03.ctr"
+ }
+ } else {
+
+#line 269 "dk4sock03.ctr"
+ }
+ } else {
+
+#line 271 "dk4sock03.ctr"
+ dk4error_set_idetails(erp, DK4_E_SOCKET_GETADDRINFO, res);
+ }
+ } else {
+
+#line 274 "dk4sock03.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 276 "dk4sock03.ctr"
+ return back;
+ /* ----- +getnameinfo */
+#else
+ /* +++++ -getnameinfo */
+ char hbuf[64]; /* Host address buffer */
+ char pbuf[64]; /* Port name buffer */
+ struct sockaddr_in *psoin4; /* IPv4 address */
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ struct sockaddr_in6 *psoin6; /* IPv6 address */
+#endif
+ int back = DK4_SOCKET_RESULT_FAILED;
+ int hpah = 0;
+ int res;
+ unsigned short us;
+
+
+#line 291 "dk4sock03.ctr"
+ if ((NULL != dptr) && (0 < dsz)) { *dptr = '\0'; }
+ if ((NULL != dptr) && (NULL != saptr) && (0 < dsz) && (0 < sasz)) {
+ switch (afam) {
+ case AF_INET : {
+ psoin4 = (struct sockaddr_in *)saptr;
+ us = psoin4->sin_port;
+ us = dk4socket_ntohs(us);
+ res = dk4ma_write_c8_decimal_unsigned(
+ pbuf, sizeof(pbuf), (dk4_um_t)us, 0, erp
+ );
+ if (0 != res) {
+ res = dk4socket_c8_inet_ntop(
+ hbuf, sizeof(hbuf), AF_INET, &(psoin4->sin_addr), erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ hpah = 1;
+ }
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ psoin6 = (struct sockaddr_in6 *)saptr;
+ us = psoin6->sin6_port;
+ us = dk4socket_ntohs(us);
+ res = dk4ma_write_c8_decimal_unsigned(
+ pbuf, sizeof(pbuf), (dk4_um_t)us, 0, erp
+ );
+ if (0 != res) {
+ res = dk4socket_c8_inet_ntop(
+ hbuf, sizeof(hbuf), AF_INET6, &(psoin6->sin6_addr), erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ hpah = 1;
+ }
+ }
+ } break;
+#endif
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } break;
+ }
+ if (0 != hpah) {
+ if (0 != dk4str8_cpy_s(dptr, dsz, pbuf, erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, dk4socket_c8_kw[0], erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, hbuf, erp)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ }
+ }
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 344 "dk4sock03.ctr"
+ return back;
+ /* ----- -getnameinfo */
+#endif
+}
+
+
+
+int
+dk4socket_c8_sockaddr_to_text(
+ char *dptr,
+ size_t dsz,
+ const dk4_sockaddr_storage_t *saptr,
+ dk4_er_t *erp
+)
+{
+ const struct sockaddr *soa;
+ int back = DK4_SOCKET_RESULT_FAILED;
+
+ if ((NULL != dptr) && (NULL != saptr) && (0 < dsz)) {
+ soa = (const struct sockaddr *)saptr;
+ switch (soa->sa_family) {
+ case AF_INET : {
+ back = dk4socket_c8_addr_port_to_text(
+ dptr, dsz, AF_INET, soa, sizeof(struct sockaddr_in), erp
+ );
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ back = dk4socket_c8_addr_port_to_text(
+ dptr, dsz, AF_INET6, soa, sizeof(struct sockaddr_in6), erp
+ );
+ } break;
+#endif
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4sock03.ctr b/support/dktools/dk4sock03.ctr
new file mode 100644
index 0000000000..9a36f71799
--- /dev/null
+++ b/support/dktools/dk4sock03.ctr
@@ -0,0 +1,386 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4sock.h"
+#include "dk4mem.h"
+#include "dk4str8.h"
+#include "dk4strd.h"
+#include "dk4mao8d.h"
+#include "dk4mao8h.h"
+#include "dk4rec23.h"
+
+
+
+$!trace-include
+
+
+
+/** Constant texts used by the module, not localized.
+*/
+static const char * const dk4socket_c8_kw[] = {
+$!string-table
+#
+# 0 Separator between port number and address
+#
+@
+#
+# 1 Separator between IPv4 address components
+#
+.
+#
+# 2 Separator between IPv6 address components
+#
+:
+$!end
+};
+
+
+
+int
+dk4socket_c8_inet_ntop(
+ char *dptr,
+ size_t dsz,
+ int afam,
+ const void *src,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_INET_NTOP
+#if DK4_ON_WINDOWS
+ /* +++++ +inet_ntop +Windows */
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ struct in6_addr in6; /* IPv6 host address */
+#endif
+ struct in_addr in4; /* IPv4 host address */
+ int back = DK4_SOCKET_RESULT_FAILED;
+
+ if ((NULL != dptr) && (0 < dsz)) { *dptr = '\0'; }
+ if ((NULL != dptr) && (NULL != src) && (0 < dsz)) {
+ dk4socket_error_reset();
+ switch (afam) {
+ case AF_INET : {
+ DK4_MEMCPY(&in4, src, sizeof(in4));
+ if (NULL != inet_ntop(afam, (void *)(&in4), dptr, dsz)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_INET_NTOP);
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ DK4_MEMCPY(&in6, src, sizeof(in6));
+ if (NULL != inet_ntop(afam, (void *)(&in6), dptr, dsz)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_INET_NTOP);
+ }
+ } break;
+#endif
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- +inet_ntop +Windows */
+#else
+ /* +++++ +inet_ntop -Windows */
+ int back = DK4_SOCKET_RESULT_FAILED;
+ if ((NULL != dptr) && (0 < dsz)) { *dptr = '\0'; }
+ if ((NULL != dptr) && (NULL != src) && (0 < dsz)) {
+ if (NULL != inet_ntop(afam, src, dptr, dsz)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_INET_NTOP);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- +inet_ntop -Windows */
+#endif
+#else
+ /* +++++ -inet_ntop */
+ char buf[16*sizeof(dk4_um_t)];
+ const struct in_addr *inp4;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ const struct in6_addr *inp6;
+#endif
+ unsigned long ul;
+ unsigned long u1;
+ int back = DK4_SOCKET_RESULT_FAILED;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ int i;
+#endif
+ int res;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ unsigned short us;
+#endif
+
+ if ((NULL != dptr) && (0 < dsz)) { *dptr = '\0'; }
+ if ((NULL != dptr) && (NULL != src) && (0 < dsz)) {
+ switch (afam) {
+ case AF_INET : {
+ inp4 = (const struct in_addr *)src;
+ ul = inp4->s_addr;
+ ul = dk4socket_htonl(ul);
+ u1 = ((ul >> 24) & 0x000000FFUL);
+ res = dk4ma_write_c8_decimal_unsigned(
+ buf, sizeof(buf), (dk4_um_t)u1, 0, erp
+ );
+ if (0 != res) {
+ if (0 != dk4str8_cpy_s(dptr, dsz, buf, erp)) {
+ u1 = ((ul >> 16) & 0x000000FFUL);
+ res = dk4ma_write_c8_decimal_unsigned(
+ buf, sizeof(buf), (dk4_um_t)u1, 0, erp
+ );
+ if (0 != res) {
+ if (0 != dk4str8_cat_s(dptr, dsz, dk4socket_c8_kw[1], erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, buf, erp)) {
+ u1 = ((ul >> 8) & 0x000000FFUL);
+ res = dk4ma_write_c8_decimal_unsigned(
+ buf, sizeof(buf), (dk4_um_t)u1, 0, erp
+ );
+ if (0 != res) {
+ if (0 != dk4str8_cat_s(dptr,dsz,dk4socket_c8_kw[1],erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, buf, erp)) {
+ u1 = (ul & 0x000000FFUL);
+ res = dk4ma_write_c8_decimal_unsigned(
+ buf, sizeof(buf), (dk4_um_t)u1, 0, erp
+ );
+ if (0 != res) {
+ if (
+ 0 != dk4str8_cat_s(dptr,dsz,dk4socket_c8_kw[1],erp)
+ )
+ {
+ if (0 != dk4str8_cat_s(dptr, dsz, buf, erp)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ inp6 = (const struct in6_addr *)src;
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ for (i = 0; i < 8; i++) {
+#if DK4_ON_WINDOWS
+ us = inp6->u.Word[i];
+#else
+ us = inp6->s6_addr16[i];
+#endif
+ us = dk4socket_htons(us);
+ res = dk4ma_write_c8_hex_unsigned(
+ buf, sizeof(buf), (dk4_um_t)us, 0, erp
+ );
+ if (0 != res) {
+ if (0 == i) {
+ if (0 == dk4str8_cpy_s(dptr, dsz, buf, erp)) {
+ back = DK4_SOCKET_RESULT_FAILED;
+ i = 8;
+ }
+ } else {
+ if (0 != dk4str8_cat_s(dptr, dsz, dk4socket_c8_kw[2], erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, buf, erp)) {
+ back = DK4_SOCKET_RESULT_FAILED;
+ i = 8;
+ }
+ } else {
+ back = DK4_SOCKET_RESULT_FAILED;
+ i = 8;
+ }
+ }
+ } else {
+ back = DK4_SOCKET_RESULT_FAILED;
+ i = 8;
+ }
+ }
+ } break;
+#endif
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- -inet_ntop */
+#endif
+}
+
+
+
+int
+dk4socket_c8_addr_port_to_text(
+ char *dptr,
+ size_t dsz,
+ int afam,
+ const struct sockaddr *saptr,
+ size_t sasz,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_GETNAMEINFO
+ /* +++++ +getnameinfo */
+ char hbuf[64]; /* Buffer for host address */
+ char pbuf[64]; /* Buffer for port number */
+ int res; /* Operation result */
+ int back = DK4_SOCKET_RESULT_FAILED;
+ $? "+ dk4socket_c8_addr_port_to_text (+getnameinfo)"
+ if ((NULL != dptr) && (0 < dsz)) { *dptr = '\0'; }
+ if ((NULL != dptr) && (NULL != saptr) && (0 < dsz) && (0 < sasz)) {
+ res = NI_NUMERICHOST | NI_NUMERICSERV;
+ dk4socket_error_reset();
+#if DK4_HAVE_SOCKLEN_T
+ res = getnameinfo(
+ saptr, (socklen_t)sasz, hbuf, sizeof(hbuf), pbuf, sizeof(pbuf), res
+ );
+#else
+ res = getnameinfo(saptr, sasz, hbuf, sizeof(hbuf), pbuf, sizeof(pbuf), res);
+#endif
+ if (0 == res) {
+ if (0 != dk4str8_cpy_s(dptr, dsz, pbuf, erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, dk4socket_c8_kw[0], erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, hbuf, erp)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else { $? "! buffer length"
+ }
+ } else { $? "! buffer length"
+ }
+ } else { $? "! buffer length"
+ }
+ } else { $? "! getnameinfo"
+ dk4error_set_idetails(erp, DK4_E_SOCKET_GETADDRINFO, res);
+ }
+ } else { $? "! args"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4socket_c8_addr_port_to_text %d", back
+ return back;
+ /* ----- +getnameinfo */
+#else
+ /* +++++ -getnameinfo */
+ char hbuf[64]; /* Host address buffer */
+ char pbuf[64]; /* Port name buffer */
+ struct sockaddr_in *psoin4; /* IPv4 address */
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ struct sockaddr_in6 *psoin6; /* IPv6 address */
+#endif
+ int back = DK4_SOCKET_RESULT_FAILED;
+ int hpah = 0;
+ int res;
+ unsigned short us;
+ $? "+ dk4socket_c8_addr_port_to_text (-getnameinfo)"
+ if ((NULL != dptr) && (0 < dsz)) { *dptr = '\0'; }
+ if ((NULL != dptr) && (NULL != saptr) && (0 < dsz) && (0 < sasz)) {
+ switch (afam) {
+ case AF_INET : {
+ psoin4 = (struct sockaddr_in *)saptr;
+ us = psoin4->sin_port;
+ us = dk4socket_ntohs(us);
+ res = dk4ma_write_c8_decimal_unsigned(
+ pbuf, sizeof(pbuf), (dk4_um_t)us, 0, erp
+ );
+ if (0 != res) {
+ res = dk4socket_c8_inet_ntop(
+ hbuf, sizeof(hbuf), AF_INET, &(psoin4->sin_addr), erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ hpah = 1;
+ }
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ psoin6 = (struct sockaddr_in6 *)saptr;
+ us = psoin6->sin6_port;
+ us = dk4socket_ntohs(us);
+ res = dk4ma_write_c8_decimal_unsigned(
+ pbuf, sizeof(pbuf), (dk4_um_t)us, 0, erp
+ );
+ if (0 != res) {
+ res = dk4socket_c8_inet_ntop(
+ hbuf, sizeof(hbuf), AF_INET6, &(psoin6->sin6_addr), erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ hpah = 1;
+ }
+ }
+ } break;
+#endif
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } break;
+ }
+ if (0 != hpah) {
+ if (0 != dk4str8_cpy_s(dptr, dsz, pbuf, erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, dk4socket_c8_kw[0], erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, hbuf, erp)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ }
+ }
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4socket_c8_addr_port_to_text %d", back
+ return back;
+ /* ----- -getnameinfo */
+#endif
+}
+
+
+
+int
+dk4socket_c8_sockaddr_to_text(
+ char *dptr,
+ size_t dsz,
+ const dk4_sockaddr_storage_t *saptr,
+ dk4_er_t *erp
+)
+{
+ const struct sockaddr *soa;
+ int back = DK4_SOCKET_RESULT_FAILED;
+
+ if ((NULL != dptr) && (NULL != saptr) && (0 < dsz)) {
+ soa = (const struct sockaddr *)saptr;
+ switch (soa->sa_family) {
+ case AF_INET : {
+ back = dk4socket_c8_addr_port_to_text(
+ dptr, dsz, AF_INET, soa, sizeof(struct sockaddr_in), erp
+ );
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ back = dk4socket_c8_addr_port_to_text(
+ dptr, dsz, AF_INET6, soa, sizeof(struct sockaddr_in6), erp
+ );
+ } break;
+#endif
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4sock04.c b/support/dktools/dk4sock04.c
new file mode 100644
index 0000000000..653125b4fd
--- /dev/null
+++ b/support/dktools/dk4sock04.c
@@ -0,0 +1,376 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sock04.ctr
+*/
+
+/** @file dk4sock04.c The dk4sock04 module.
+*/
+
+
+#line 6 "dk4sock04.ctr"
+
+#include "dk4sock.h"
+#include "dk4mem.h"
+#include "dk4strw.h"
+#include "dk4strd.h"
+#include "dk4maowd.h"
+#include "dk4maowh.h"
+#include "dk4rec23.h"
+
+
+
+
+
+#line 18 "dk4sock04.ctr"
+
+
+
+/** Constant texts used by the module, not localized.
+*/
+static const wchar_t * const dk4socket_wc_kw[] = {
+/* 0 */
+L"@",
+
+/* 1 */
+L".",
+
+/* 2 */
+L":",
+
+NULL
+
+
+#line 38 "dk4sock04.ctr"
+};
+
+
+int
+dk4socket_wc_inet_ntop(
+ wchar_t *dptr,
+ size_t dsz,
+ int afam,
+ const void *src,
+ dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+#if DK4_HAVE_INET_NTOP
+ /* +++++ +Windows +inet_ntop */
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ struct in6_addr in6;
+#endif
+ struct in_addr in4;
+ int back = DK4_SOCKET_RESULT_FAILED;
+ if ((NULL != dptr) && (0 < dsz)) { *dptr = L'\0'; }
+ if ((NULL != dptr) && (NULL != src) && (0 < dsz)) {
+ dk4socket_error_reset();
+ switch (afam) {
+ case AF_INET : {
+ DK4_MEMCPY(&in4, src, sizeof(in4));
+ if (NULL != InetNtopW(afam, (void *)(&in4), dptr, dsz)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_INET_NTOP);
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ DK4_MEMCPY(&in6, src, sizeof(in6));
+ if (NULL != InetNtopW(afam, (void *)(&in6), dptr, dsz)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_INET_NTOP);
+ }
+ } break;
+#endif
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- +Windows +inet_ntop */
+#else
+ /* +++++ +Windows -inet_ntop */
+ wchar_t buf[16*sizeof(dk4_um_t)];
+ const struct in_addr *inp4;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ const struct in6_addr *inp6;
+#endif
+ unsigned long ul;
+ unsigned long u1;
+ int back = DK4_SOCKET_RESULT_FAILED;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ int i;
+#endif
+ int res;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ unsigned short us;
+#endif
+
+ if ((NULL != dptr) && (0 < dsz)) { *dptr = L'\0'; }
+ if ((NULL != dptr) && (NULL != src) && (0 < dsz)) {
+ switch (afam) {
+ case AF_INET : {
+ inp4 = (const struct in_addr *)src;
+ ul = inp4->s_addr;
+ ul = dk4socket_htonl(ul);
+ u1 = ((ul >> 24) & 0x000000FFUL);
+ res = dk4ma_write_wc_decimal_unsigned(
+ buf, sizeof(buf), (dk4_um_t)u1, 0, erp
+ );
+ if (0 != res) {
+ if (0 != dk4strw_cpy_s(dptr, dsz, buf, erp)) {
+ u1 = ((ul >> 16) & 0x000000FFUL);
+ res = dk4ma_write_wc_decimal_unsigned(
+ buf, sizeof(buf), (dk4_um_t)u1, 0, erp
+ );
+ if (0 != res) {
+ if (0 != dk4strw_cat_s(dptr, dsz, dk4socket_wc_kw[1], erp)) {
+ if (0 != dk4strw_cat_s(dptr, dsz, buf, erp)) {
+ u1 = ((ul >> 8) & 0x000000FFUL);
+ res = dk4ma_write_wc_decimal_unsigned(
+ buf, sizeof(buf), (dk4_um_t)u1, 0, erp
+ );
+ if (0 != res) {
+ if (0 != dk4strw_cat_s(dptr,dsz,dk4socket_wc_kw[1],erp)) {
+ if (0 != dk4strw_cat_s(dptr, dsz, buf, erp)) {
+ u1 = (ul & 0x000000FFUL);
+ res = dk4ma_write_wc_decimal_unsigned(
+ buf, sizeof(buf), (dk4_um_t)u1, 0, erp
+ );
+ if (0 != res) {
+ if (
+ 0 != dk4strw_cat_s(dptr,dsz,dk4socket_wc_kw[1],erp)
+ )
+ {
+ if (0 != dk4strw_cat_s(dptr, dsz, buf, erp)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ inp6 = (const struct in6_addr *)src;
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ for (i = 0; i < 8; i++) {
+#if DK4_ON_WINDOWS
+ us = inp6->u.Word[i];
+#else
+ us = inp6->s6_addr16[i];
+#endif
+ us = dk4socket_htons(us);
+ res = dk4ma_write_wc_hex_unsigned(
+ buf, sizeof(buf), (dk4_um_t)us, 0, erp
+ );
+ if (0 != res) {
+ if (0 == i) {
+ if (0 == dk4strw_cpy_s(dptr, dsz, buf, erp)) {
+ back = DK4_SOCKET_RESULT_FAILED;
+ i = 8;
+ }
+ } else {
+ if (0 != dk4strw_cat_s(dptr, dsz, dk4socket_wc_kw[2], erp)) {
+ if (0 != dk4strw_cat_s(dptr, dsz, buf, erp)) {
+ back = DK4_SOCKET_RESULT_FAILED;
+ i = 8;
+ }
+ } else {
+ back = DK4_SOCKET_RESULT_FAILED;
+ i = 8;
+ }
+ }
+ } else {
+ back = DK4_SOCKET_RESULT_FAILED;
+ i = 8;
+ }
+ }
+ } break;
+#endif
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- +Windows -inet_ntop */
+#endif
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return DK4_SOCKET_RESULT_FAILED;
+#endif
+}
+
+
+
+int
+dk4socket_wc_addr_port_to_text(
+ wchar_t *dptr,
+ size_t dsz,
+ int afam,
+ const struct sockaddr *saptr,
+ size_t sasz,
+ dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+#if DK4_HAVE_GETNAMEINFO
+ /* +++++ +getnameinfo */
+ wchar_t hbuf[64];
+ wchar_t pbuf[64];
+ const DWORD szh = DK4_SIZEOF(hbuf,wchar_t);
+ const DWORD szp = DK4_SIZEOF(pbuf,wchar_t);
+ int back = DK4_SOCKET_RESULT_FAILED;
+ int res;
+ if ((NULL != dptr) && (0 < dsz)) { *dptr = '\0'; }
+ if ((NULL != dptr) && (NULL != saptr) && (0 < dsz) && (0 < sasz)) {
+ res = NI_NUMERICHOST | NI_NUMERICSERV;
+ dk4socket_error_reset();
+#if DK4_HAVE_SOCKLEN_T
+ res = GetNameInfoW(saptr, (socklen_t)sasz, hbuf, szh, pbuf, szp, res);
+#else
+ res = GetNameInfoW(saptr, sasz, hbuf, szh, pbuf, szp, res);
+#endif
+ if (0 == res) {
+ if (0 != dk4strw_cpy_s(dptr, dsz, pbuf, erp)) {
+ if (0 != dk4strw_cat_s(dptr, dsz, dk4socket_wc_kw[0], erp)) {
+ if (0 != dk4strw_cat_s(dptr, dsz, hbuf, erp)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ }
+ }
+ }
+ } else {
+ dk4error_set_idetails(erp, DK4_E_SOCKET_GETADDRINFO, res);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- +getnameinfo */
+#else
+ /* +++++ -getnameinfo */
+ wchar_t hbuf[64];
+ wchar_t pbuf[64];
+ struct sockaddr_in *psoin4;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ struct sockaddr_in6 *psoin6;
+#endif
+ int back = DK4_SOCKET_RESULT_FAILED;
+ int hpah = 0;
+ int res;
+ unsigned short us;
+ if ((NULL != dptr) && (0 < dsz)) { *dptr = L'\0'; }
+ if ((NULL != dptr) && (NULL != saptr) && (0 < dsz) && (0 < sasz)) {
+ switch (afam) {
+ case AF_INET : {
+ psoin4 = (struct sockaddr_in *)saptr;
+ us = psoin4->sin_port;
+ us = dk4socket_ntohs(us);
+ res = dk4ma_write_wc_decimal_unsigned(
+ pbuf, sizeof(pbuf), (dk4_um_t)us, 0, erp
+ );
+ if (0 != res) {
+ res = dk4socket_wc_inet_ntop(
+ hbuf, sizeof(hbuf), AF_INET, &(psoin4->sin_addr), erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ hpah = 1;
+ }
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ psoin6 = (struct sockaddr_in6 *)saptr;
+ us = psoin6->sin6_port;
+ us = dk4socket_ntohs(us);
+ res = dk4ma_write_wc_decimal_unsigned(
+ pbuf, sizeof(pbuf), (dk4_um_t)us, 0, erp
+ );
+ if (0 != res) {
+ res = dk4socket_wc_inet_ntop(
+ hbuf, sizeof(hbuf), AF_INET6, &(psoin6->sin6_addr), erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ hpah = 1;
+ }
+ }
+ } break;
+#endif
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } break;
+ }
+ if (0 != hpah) {
+ if (0 != dk4strw_cpy_s(dptr, dsz, pbuf, erp)) {
+ if (0 != dk4strw_cat_s(dptr, dsz, dk4socket_wc_kw[0], erp)) {
+ if (0 != dk4strw_cat_s(dptr, dsz, hbuf, erp)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ }
+ }
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- -getnameinfo */
+#endif
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return DK4_SOCKET_RESULT_FAILED;
+#endif
+}
+
+
+
+int
+dk4socket_wc_sockaddr_to_text(
+ wchar_t *dptr,
+ size_t dsz,
+ const dk4_sockaddr_storage_t *saptr,
+ dk4_er_t *erp
+)
+{
+ const struct sockaddr *soa;
+ int back = DK4_SOCKET_RESULT_FAILED;
+
+ if ((NULL != dptr) && (NULL != saptr) && (0 < dsz)) {
+ soa = (const struct sockaddr *)saptr;
+ switch (soa->sa_family) {
+ case AF_INET : {
+ back = dk4socket_wc_addr_port_to_text(
+ dptr, dsz, AF_INET, soa, sizeof(struct sockaddr_in), erp
+ );
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ back = dk4socket_wc_addr_port_to_text(
+ dptr, dsz, AF_INET6, soa, sizeof(struct sockaddr_in6), erp
+ );
+ } break;
+#endif
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4sock04.ctr b/support/dktools/dk4sock04.ctr
new file mode 100644
index 0000000000..fdc9799775
--- /dev/null
+++ b/support/dktools/dk4sock04.ctr
@@ -0,0 +1,368 @@
+%% options
+
+
+
+%% module
+
+#include "dk4sock.h"
+#include "dk4mem.h"
+#include "dk4strw.h"
+#include "dk4strd.h"
+#include "dk4maowd.h"
+#include "dk4maowh.h"
+#include "dk4rec23.h"
+
+
+
+$!trace-include
+
+
+
+/** Constant texts used by the module, not localized.
+*/
+static const wchar_t * const dk4socket_wc_kw[] = {
+$!string-table prefix=L
+#
+# 0 Separator between port number and address
+#
+@
+#
+# 1 Separator between IPv4 address components
+#
+.
+#
+# 2 Separator between IPv6 address components
+#
+:
+$!end
+};
+
+
+int
+dk4socket_wc_inet_ntop(
+ wchar_t *dptr,
+ size_t dsz,
+ int afam,
+ const void *src,
+ dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+#if DK4_HAVE_INET_NTOP
+ /* +++++ +Windows +inet_ntop */
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ struct in6_addr in6;
+#endif
+ struct in_addr in4;
+ int back = DK4_SOCKET_RESULT_FAILED;
+ if ((NULL != dptr) && (0 < dsz)) { *dptr = L'\0'; }
+ if ((NULL != dptr) && (NULL != src) && (0 < dsz)) {
+ dk4socket_error_reset();
+ switch (afam) {
+ case AF_INET : {
+ DK4_MEMCPY(&in4, src, sizeof(in4));
+ if (NULL != InetNtopW(afam, (void *)(&in4), dptr, dsz)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_INET_NTOP);
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ DK4_MEMCPY(&in6, src, sizeof(in6));
+ if (NULL != InetNtopW(afam, (void *)(&in6), dptr, dsz)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_INET_NTOP);
+ }
+ } break;
+#endif
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- +Windows +inet_ntop */
+#else
+ /* +++++ +Windows -inet_ntop */
+ wchar_t buf[16*sizeof(dk4_um_t)];
+ const struct in_addr *inp4;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ const struct in6_addr *inp6;
+#endif
+ unsigned long ul;
+ unsigned long u1;
+ int back = DK4_SOCKET_RESULT_FAILED;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ int i;
+#endif
+ int res;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ unsigned short us;
+#endif
+
+ if ((NULL != dptr) && (0 < dsz)) { *dptr = L'\0'; }
+ if ((NULL != dptr) && (NULL != src) && (0 < dsz)) {
+ switch (afam) {
+ case AF_INET : {
+ inp4 = (const struct in_addr *)src;
+ ul = inp4->s_addr;
+ ul = dk4socket_htonl(ul);
+ u1 = ((ul >> 24) & 0x000000FFUL);
+ res = dk4ma_write_wc_decimal_unsigned(
+ buf, sizeof(buf), (dk4_um_t)u1, 0, erp
+ );
+ if (0 != res) {
+ if (0 != dk4strw_cpy_s(dptr, dsz, buf, erp)) {
+ u1 = ((ul >> 16) & 0x000000FFUL);
+ res = dk4ma_write_wc_decimal_unsigned(
+ buf, sizeof(buf), (dk4_um_t)u1, 0, erp
+ );
+ if (0 != res) {
+ if (0 != dk4strw_cat_s(dptr, dsz, dk4socket_wc_kw[1], erp)) {
+ if (0 != dk4strw_cat_s(dptr, dsz, buf, erp)) {
+ u1 = ((ul >> 8) & 0x000000FFUL);
+ res = dk4ma_write_wc_decimal_unsigned(
+ buf, sizeof(buf), (dk4_um_t)u1, 0, erp
+ );
+ if (0 != res) {
+ if (0 != dk4strw_cat_s(dptr,dsz,dk4socket_wc_kw[1],erp)) {
+ if (0 != dk4strw_cat_s(dptr, dsz, buf, erp)) {
+ u1 = (ul & 0x000000FFUL);
+ res = dk4ma_write_wc_decimal_unsigned(
+ buf, sizeof(buf), (dk4_um_t)u1, 0, erp
+ );
+ if (0 != res) {
+ if (
+ 0 != dk4strw_cat_s(dptr,dsz,dk4socket_wc_kw[1],erp)
+ )
+ {
+ if (0 != dk4strw_cat_s(dptr, dsz, buf, erp)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ inp6 = (const struct in6_addr *)src;
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ for (i = 0; i < 8; i++) {
+#if DK4_ON_WINDOWS
+ us = inp6->u.Word[i];
+#else
+ us = inp6->s6_addr16[i];
+#endif
+ us = dk4socket_htons(us);
+ res = dk4ma_write_wc_hex_unsigned(
+ buf, sizeof(buf), (dk4_um_t)us, 0, erp
+ );
+ if (0 != res) {
+ if (0 == i) {
+ if (0 == dk4strw_cpy_s(dptr, dsz, buf, erp)) {
+ back = DK4_SOCKET_RESULT_FAILED;
+ i = 8;
+ }
+ } else {
+ if (0 != dk4strw_cat_s(dptr, dsz, dk4socket_wc_kw[2], erp)) {
+ if (0 != dk4strw_cat_s(dptr, dsz, buf, erp)) {
+ back = DK4_SOCKET_RESULT_FAILED;
+ i = 8;
+ }
+ } else {
+ back = DK4_SOCKET_RESULT_FAILED;
+ i = 8;
+ }
+ }
+ } else {
+ back = DK4_SOCKET_RESULT_FAILED;
+ i = 8;
+ }
+ }
+ } break;
+#endif
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- +Windows -inet_ntop */
+#endif
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return DK4_SOCKET_RESULT_FAILED;
+#endif
+}
+
+
+
+int
+dk4socket_wc_addr_port_to_text(
+ wchar_t *dptr,
+ size_t dsz,
+ int afam,
+ const struct sockaddr *saptr,
+ size_t sasz,
+ dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+#if DK4_HAVE_GETNAMEINFO
+ /* +++++ +getnameinfo */
+ wchar_t hbuf[64];
+ wchar_t pbuf[64];
+ const DWORD szh = DK4_SIZEOF(hbuf,wchar_t);
+ const DWORD szp = DK4_SIZEOF(pbuf,wchar_t);
+ int back = DK4_SOCKET_RESULT_FAILED;
+ int res;
+ if ((NULL != dptr) && (0 < dsz)) { *dptr = '\0'; }
+ if ((NULL != dptr) && (NULL != saptr) && (0 < dsz) && (0 < sasz)) {
+ res = NI_NUMERICHOST | NI_NUMERICSERV;
+ dk4socket_error_reset();
+#if DK4_HAVE_SOCKLEN_T
+ res = GetNameInfoW(saptr, (socklen_t)sasz, hbuf, szh, pbuf, szp, res);
+#else
+ res = GetNameInfoW(saptr, sasz, hbuf, szh, pbuf, szp, res);
+#endif
+ if (0 == res) {
+ if (0 != dk4strw_cpy_s(dptr, dsz, pbuf, erp)) {
+ if (0 != dk4strw_cat_s(dptr, dsz, dk4socket_wc_kw[0], erp)) {
+ if (0 != dk4strw_cat_s(dptr, dsz, hbuf, erp)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ }
+ }
+ }
+ } else {
+ dk4error_set_idetails(erp, DK4_E_SOCKET_GETADDRINFO, res);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- +getnameinfo */
+#else
+ /* +++++ -getnameinfo */
+ wchar_t hbuf[64];
+ wchar_t pbuf[64];
+ struct sockaddr_in *psoin4;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ struct sockaddr_in6 *psoin6;
+#endif
+ int back = DK4_SOCKET_RESULT_FAILED;
+ int hpah = 0;
+ int res;
+ unsigned short us;
+ if ((NULL != dptr) && (0 < dsz)) { *dptr = L'\0'; }
+ if ((NULL != dptr) && (NULL != saptr) && (0 < dsz) && (0 < sasz)) {
+ switch (afam) {
+ case AF_INET : {
+ psoin4 = (struct sockaddr_in *)saptr;
+ us = psoin4->sin_port;
+ us = dk4socket_ntohs(us);
+ res = dk4ma_write_wc_decimal_unsigned(
+ pbuf, sizeof(pbuf), (dk4_um_t)us, 0, erp
+ );
+ if (0 != res) {
+ res = dk4socket_wc_inet_ntop(
+ hbuf, sizeof(hbuf), AF_INET, &(psoin4->sin_addr), erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ hpah = 1;
+ }
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ psoin6 = (struct sockaddr_in6 *)saptr;
+ us = psoin6->sin6_port;
+ us = dk4socket_ntohs(us);
+ res = dk4ma_write_wc_decimal_unsigned(
+ pbuf, sizeof(pbuf), (dk4_um_t)us, 0, erp
+ );
+ if (0 != res) {
+ res = dk4socket_wc_inet_ntop(
+ hbuf, sizeof(hbuf), AF_INET6, &(psoin6->sin6_addr), erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ hpah = 1;
+ }
+ }
+ } break;
+#endif
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } break;
+ }
+ if (0 != hpah) {
+ if (0 != dk4strw_cpy_s(dptr, dsz, pbuf, erp)) {
+ if (0 != dk4strw_cat_s(dptr, dsz, dk4socket_wc_kw[0], erp)) {
+ if (0 != dk4strw_cat_s(dptr, dsz, hbuf, erp)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ }
+ }
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- -getnameinfo */
+#endif
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return DK4_SOCKET_RESULT_FAILED;
+#endif
+}
+
+
+
+int
+dk4socket_wc_sockaddr_to_text(
+ wchar_t *dptr,
+ size_t dsz,
+ const dk4_sockaddr_storage_t *saptr,
+ dk4_er_t *erp
+)
+{
+ const struct sockaddr *soa;
+ int back = DK4_SOCKET_RESULT_FAILED;
+
+ if ((NULL != dptr) && (NULL != saptr) && (0 < dsz)) {
+ soa = (const struct sockaddr *)saptr;
+ switch (soa->sa_family) {
+ case AF_INET : {
+ back = dk4socket_wc_addr_port_to_text(
+ dptr, dsz, AF_INET, soa, sizeof(struct sockaddr_in), erp
+ );
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ back = dk4socket_wc_addr_port_to_text(
+ dptr, dsz, AF_INET6, soa, sizeof(struct sockaddr_in6), erp
+ );
+ } break;
+#endif
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4sock05.c b/support/dktools/dk4sock05.c
new file mode 100644
index 0000000000..53ff475de9
--- /dev/null
+++ b/support/dktools/dk4sock05.c
@@ -0,0 +1,95 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sock05.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4sock05.c The dk4sock05 module.
+*/
+
+
+#line 10 "dk4sock05.ctr"
+
+#include "dk4sock.h"
+
+int
+dk4socket_inet_ntop(
+ dkChar *dptr,
+ size_t dsz,
+ int afam,
+ const void *src,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4socket_wc_inet_ntop(dptr, dsz, afam, src, erp));
+#else
+ return (dk4socket_c8_inet_ntop(dptr, dsz, afam, src, erp));
+#endif
+}
+
+int
+dk4socket_addr_port_to_text(
+ dkChar *dptr,
+ size_t dsz,
+ int afam,
+ const struct sockaddr *saptr,
+ size_t sasz,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4socket_wc_addr_port_to_text(dptr, dsz, afam, saptr, sasz, erp));
+#else
+ return (dk4socket_c8_addr_port_to_text(dptr, dsz, afam, saptr, sasz, erp));
+#endif
+}
+
+
+
+
+int
+dk4socket_sockaddr_to_text(
+ dkChar *dptr,
+ size_t dsz,
+ const dk4_sockaddr_storage_t *saptr,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4socket_wc_sockaddr_to_text(dptr, dsz, saptr, erp));
+#else
+ return (dk4socket_c8_sockaddr_to_text(dptr, dsz, saptr, erp));
+#endif
+}
+
+
diff --git a/support/dktools/dk4sock05.ctr b/support/dktools/dk4sock05.ctr
new file mode 100644
index 0000000000..0fef1ac9e2
--- /dev/null
+++ b/support/dktools/dk4sock05.ctr
@@ -0,0 +1,64 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4sock.h"
+
+int
+dk4socket_inet_ntop(
+ dkChar *dptr,
+ size_t dsz,
+ int afam,
+ const void *src,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4socket_wc_inet_ntop(dptr, dsz, afam, src, erp));
+#else
+ return (dk4socket_c8_inet_ntop(dptr, dsz, afam, src, erp));
+#endif
+}
+
+int
+dk4socket_addr_port_to_text(
+ dkChar *dptr,
+ size_t dsz,
+ int afam,
+ const struct sockaddr *saptr,
+ size_t sasz,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4socket_wc_addr_port_to_text(dptr, dsz, afam, saptr, sasz, erp));
+#else
+ return (dk4socket_c8_addr_port_to_text(dptr, dsz, afam, saptr, sasz, erp));
+#endif
+}
+
+
+
+
+int
+dk4socket_sockaddr_to_text(
+ dkChar *dptr,
+ size_t dsz,
+ const dk4_sockaddr_storage_t *saptr,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4socket_wc_sockaddr_to_text(dptr, dsz, saptr, erp));
+#else
+ return (dk4socket_c8_sockaddr_to_text(dptr, dsz, saptr, erp));
+#endif
+}
+
+
diff --git a/support/dktools/dk4sock06.c b/support/dktools/dk4sock06.c
new file mode 100644
index 0000000000..81f617a0ee
--- /dev/null
+++ b/support/dktools/dk4sock06.c
@@ -0,0 +1,629 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sock06.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4sock06.c The dk4sock06 module.
+*/
+
+
+#line 10 "dk4sock06.ctr"
+
+#include "dk4sock.h"
+#include "dk4maaul.h"
+#include "dk4maaus.h"
+
+
+
+
+
+#line 18 "dk4sock06.ctr"
+
+
+
+#if !DK4_HAVE_INET_PTON
+
+/** Character classes.
+*/
+enum {
+ /** Any character not rom the types below.
+ */
+ INPUT_ANY = 0 ,
+
+ /** Digit.
+ */
+ INPUT_DIGIT ,
+
+ /** Separator (dot for IPv4, colon for IPv6).
+ */
+ INPUT_SEP ,
+
+ /** End of input reached.
+ */
+ INPUT_END
+};
+
+/** States while reading IPv4.
+*/
+enum {
+ /** Nothing processed yet.
+ */
+ S4_INIT = 0 ,
+
+ /** Previous character was a separator.
+ */
+ S4_SEP ,
+
+ /** Previous character was digit.
+ */
+ S4_DIG ,
+
+ /** Successfully finished IP address retrieval.
+ */
+ S4_FINISHED ,
+
+ /** Error found in previous input.
+ */
+ S4_ERROR
+};
+
+static
+int
+dk4socket_classify_input_char(
+ char c,
+ int ipv6,
+ unsigned short *valptr
+)
+{
+ int back = INPUT_ANY;
+ switch (c) {
+ case ':' : {
+ if (0 != ipv6) { back = INPUT_SEP; }
+ } break;
+ case '.' : {
+ if (0 == ipv6) { back = INPUT_SEP; }
+ } break;
+ case '0': { back = INPUT_DIGIT; *valptr = 0; } break;
+ case '1': { back = INPUT_DIGIT; *valptr = 1; } break;
+ case '2': { back = INPUT_DIGIT; *valptr = 2; } break;
+ case '3': { back = INPUT_DIGIT; *valptr = 3; } break;
+ case '4': { back = INPUT_DIGIT; *valptr = 4; } break;
+ case '5': { back = INPUT_DIGIT; *valptr = 5; } break;
+ case '6': { back = INPUT_DIGIT; *valptr = 6; } break;
+ case '7': { back = INPUT_DIGIT; *valptr = 7; } break;
+ case '8': { back = INPUT_DIGIT; *valptr = 8; } break;
+ case '9': { back = INPUT_DIGIT; *valptr = 9; } break;
+ case 'a': {
+ if (0 != ipv6) { back = INPUT_DIGIT; *valptr = 10; }
+ } break;
+ case 'A': {
+ if (0 != ipv6) { back = INPUT_DIGIT; *valptr = 10; }
+ } break;
+ case 'b': {
+ if (0 != ipv6) { back = INPUT_DIGIT; *valptr = 11; }
+ } break;
+ case 'B': {
+ if (0 != ipv6) { back = INPUT_DIGIT; *valptr = 11; }
+ } break;
+ case 'c': {
+ if (0 != ipv6) { back = INPUT_DIGIT; *valptr = 12; }
+ } break;
+ case 'C': {
+ if (0 != ipv6) { back = INPUT_DIGIT; *valptr = 12; }
+ } break;
+ case 'd': {
+ if (0 != ipv6) { back = INPUT_DIGIT; *valptr = 13; }
+ } break;
+ case 'D': {
+ if (0 != ipv6) { back = INPUT_DIGIT; *valptr = 13; }
+ } break;
+ case 'e': {
+ if (0 != ipv6) { back = INPUT_DIGIT; *valptr = 14; }
+ } break;
+ case 'E': {
+ if (0 != ipv6) { back = INPUT_DIGIT; *valptr = 14; }
+ } break;
+ case 'f': {
+ if (0 != ipv6) { back = INPUT_DIGIT; *valptr = 15; }
+ } break;
+ case 'F': {
+ if (0 != ipv6) { back = INPUT_DIGIT; *valptr = 15; }
+ } break;
+ }
+ return back;
+}
+
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+
+
+/** States while reading IPv4.
+*/
+enum {
+ /** Nothing processed yet.
+ */
+ S6_INIT = 0 ,
+
+ /** Previous character was a separator.
+ */
+ S6_SEP ,
+
+ /** Previous two characters were separators.
+ */
+ S6_DSEP ,
+
+ /** Previous character was digit.
+ */
+ S6_DIG ,
+
+ /** Successfully finished IP address retrieval.
+ */
+ S6_FINISHED ,
+
+ /** Error found in previous input.
+ */
+ S6_ERROR
+};
+
+static
+int
+dk4socket_my_ip6_pton(
+ void *pAddr,
+ size_t szAddr,
+ const char *src,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er;
+ unsigned short left[8]; /* Values for left side */
+ unsigned short right[8]; /* Values for right side */
+ struct in6_addr *inp6 = NULL; /* Result */
+ int isright = 0; /* Flag: Already on right side */
+ int hl = 0; /* Number of values on left side */
+ int hr = 0; /* Number of values on right side */
+ int icl = 0; /* Input character class */
+ int cc = 1; /* Flag: Can continue */
+ int st = S6_INIT; /* Current state */
+ int back = DK4_SOCKET_RESULT_FAILED;
+ int i = 0; /* Index to fill address */
+ unsigned short curval = 0; /* Value collected so far */
+ unsigned short us = 0; /* Current character value */
+
+ do {
+ if ('\0' == *src) {
+ icl = INPUT_END;
+ } else {
+ icl = dk4socket_classify_input_char(*src, 1, &us);
+ }
+ switch (st) {
+ case S6_INIT : {
+ switch (icl) {
+ case INPUT_DIGIT : {
+ curval = us;
+ st = S6_DIG;
+ } break;
+ case INPUT_SEP : {
+ st = S6_SEP;
+ } break;
+ default : {
+ st = S6_ERROR;
+ cc = -1;
+ } break;
+ }
+ } break;
+ case S6_SEP : {
+ switch (icl) {
+ case INPUT_DIGIT : {
+ curval = us;
+ st = S6_DIG;
+ } break;
+ case INPUT_SEP : {
+ st = S6_DSEP;
+ if (0 == isright) {
+ isright = 1;
+ } else {
+ st = S6_ERROR;
+ cc = -1;
+ }
+ } break;
+ default : {
+ st = S6_ERROR;
+ cc = -1;
+ } break;
+ }
+ } break;
+ case S6_DSEP : {
+ switch (icl) {
+ case INPUT_DIGIT : {
+ curval = us;
+ st = S6_DIG;
+ } break;
+ case INPUT_END : {
+ st = S6_FINISHED;
+ } break;
+ default : {
+ st = S6_ERROR;
+ cc = -1;
+ } break;
+ }
+ } break;
+ case S6_DIG : {
+ switch (icl) {
+ case INPUT_DIGIT : {
+ dk4error_init(&er);
+ curval = dk4ma_ushort_add(
+ dk4ma_ushort_mul(curval, 16UL, &er),
+ us, &er
+ );
+ if (DK4_E_NONE != er.ec) {
+ st = S6_ERROR;
+ cc = -1;
+ }
+ } break;
+ case INPUT_SEP : {
+ if (0 != isright) {
+ if (8 > hr) {
+ right[hr++] = curval;
+ st = S6_SEP;
+ } else {
+ st = S6_ERROR;
+ cc = -1;
+ }
+ } else {
+ if (8 > hl) {
+ left[hl++] = curval;
+ st = S6_SEP;
+ } else {
+ st = S6_ERROR;
+ cc = -1;
+ }
+ }
+ } break;
+ case INPUT_END : {
+ if (0 != isright) {
+ if (8 > hr) {
+ right[hr++] = curval;
+ st = S6_FINISHED;
+ cc = 0;
+ } else {
+ st = S6_ERROR;
+ cc = -1;
+ }
+ } else {
+ if (8 > hl) {
+ left[hl++] = curval;
+ st = S6_FINISHED;
+ cc = 0;
+ } else {
+ st = S6_ERROR;
+ cc = -1;
+ }
+ }
+ } break;
+ default : {
+ st = S6_ERROR;
+ cc = -1;
+ } break;
+ }
+ } break;
+ }
+ src++;
+ if ((1 == cc) && (INPUT_END == icl)) { cc = 0; }
+ } while (1 == cc);
+ if ((0 == cc) && (S6_FINISHED == st)) {
+ if (9 > (hl + hr)) {
+ inp6 = (struct in6_addr *)pAddr;
+ for (i = 0; i < 8; i++) {
+#if DK4_ON_WINDOWS
+ inp6->u.Word[i] = dk4socket_htons(0);
+#else
+ inp6->s6_addr16[i] = dk4socket_htons(0);
+#endif
+ }
+ for (i = 0; i < hl; i++) {
+#if DK4_ON_WINDOWS
+ inp6->u.Word[i] = dk4socket_htons(left[i]);
+#else
+ inp6->s6_addr16[i] = dk4socket_htons(left[i]);
+#endif
+ }
+ for (i = 0; i < hr; i++) {
+#if DK4_ON_WINDOWS
+ inp6->u.Word[8 - hr + i ] = dk4socket_htons(right[i]);
+#else
+ inp6->s6_addr16[8 - hr + i] = dk4socket_htons(right[i]);
+#endif
+ }
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ return back;
+}
+
+#endif
+
+static
+int
+dk4socket_my_ip4_pton(
+ void *pAddr,
+ size_t szAddr,
+ const char *src,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er;
+ struct in_addr *pin4;
+ unsigned long curval = 0UL;
+ unsigned long result = 0UL;
+ int back = DK4_SOCKET_RESULT_FAILED;
+ int cc = 1;
+ int icl = 0;
+ int st = S4_INIT;
+ int curnum = 0;
+ unsigned short us = 0;
+
+
+#line 365 "dk4sock06.ctr"
+ do {
+ us = 0;
+ if ('\0' == *src) {
+ icl = INPUT_END;
+ } else {
+ icl = dk4socket_classify_input_char(*src, 0, &us);
+ }
+ switch (icl) {
+ case INPUT_DIGIT : {
+ switch (st) {
+ case S4_INIT: {
+ curval = (unsigned long)us;
+ st = S4_DIG;
+ } break;
+ case S4_SEP : {
+ curval = (unsigned long)us;
+ st = S4_DIG;
+ } break;
+ case S4_DIG : {
+ dk4error_init(&er);
+ curval = dk4ma_ulong_add(
+ dk4ma_ulong_mul(curval, 10UL, &er),
+ (unsigned long)us,
+ &er
+ );
+ if (DK4_E_NONE != er.ec) {
+ st = S4_ERROR;
+ cc = -1;
+ }
+ } break;
+ }
+ } break;
+ case INPUT_SEP : {
+ switch (st) {
+ case S4_INIT: {
+ st = S4_ERROR;
+ cc = -1;
+ } break;
+ case S4_SEP : {
+ st = S4_ERROR;
+ cc = -1;
+ } break;
+ case S4_DIG : {
+ if (256UL > curval) {
+ switch (curnum++) {
+ case 0: {
+ result = ((curval << 24) & 0xFF000000UL);
+ st = S4_SEP;
+ curval = 0UL;
+ } break;
+ case 1: {
+ result |= ((curval << 16) & 0x00FF0000UL);
+ st = S4_SEP;
+ curval = 0UL;
+ } break;
+ case 2: {
+ result |= ((curval << 8) & 0x0000FF00UL);
+ st = S4_SEP;
+ curval = 0UL;
+ } break;
+ default: {
+ st = S4_ERROR;
+ cc = -1;
+ } break;
+ }
+ } else {
+ st = S4_ERROR;
+ cc = -1;
+ }
+ } break;
+ }
+ } break;
+ case INPUT_END : {
+ switch (st) {
+ case S4_INIT: {
+ st = S4_ERROR;
+ cc = -1;
+ } break;
+ case S4_SEP : {
+ st = S4_ERROR;
+ cc = -1;
+ } break;
+ case S4_DIG : {
+ st = S4_ERROR;
+ cc = -1;
+ if (3 == curnum) {
+ if (256UL > curval) {
+ result |= curval;
+ cc = 0;
+ st = S4_FINISHED;
+ }
+ }
+ } break;
+ }
+ } break;
+ default : {
+ st = S4_ERROR;
+ cc = -1;
+ } break;
+ }
+ src++;
+ } while(1 == cc);
+ if ((0 == cc) && (S4_FINISHED == st)) {
+ pin4 = (struct in_addr *)pAddr;
+ pin4->s_addr = dk4socket_htonl(result);
+ back = DK4_SOCKET_RESULT_FAILED;
+
+
+#line 472 "dk4sock06.ctr"
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+
+
+#line 475 "dk4sock06.ctr"
+ }
+
+
+#line 477 "dk4sock06.ctr"
+ return back;
+}
+
+static
+int
+dk4socket_my_inet_pton(
+ void *pAddr,
+ size_t szAddr,
+ int afam,
+ const char *src,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_SOCKET_RESULT_FAILED;
+
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ if (AF_INET6 == afam) {
+ back = dk4socket_my_ip6_pton(pAddr, szAddr, src, erp);
+ } else {
+#endif
+ back = dk4socket_my_ip4_pton(pAddr, szAddr, src, erp);
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ }
+#endif
+ return back;
+}
+
+#endif
+
+
+int
+dk4socket_c8_inet_pton(
+ void *pAddr,
+ size_t szAddr,
+ int afam,
+ const char *src,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_INET_PTON
+ /* +++++ +inet_pton */
+ int back = DK4_SOCKET_RESULT_FAILED;
+ int res;
+ if ((NULL != pAddr) && (0 < szAddr) && (NULL != src)) {
+ switch (afam) {
+ case AF_INET : {
+ if (sizeof(struct in_addr) == szAddr) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ if (sizeof(struct in6_addr) == szAddr) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ }
+ } break;
+#endif
+ }
+ if (DK4_SOCKET_RESULT_SUCCESS == back) {
+ back = DK4_SOCKET_RESULT_FAILED;
+ dk4socket_error_reset();
+ res = inet_pton(afam, src, pAddr);
+ switch (res) {
+ case 0 : {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ case -1 : {
+ dk4socket_error_report(erp, DK4_E_SOCKET_INET_PTON);
+ } break;
+ default : {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- +inet_pton */
+#else
+ /* +++++ -inet_pton */
+ int back = DK4_SOCKET_RESULT_FAILED;
+ if ((NULL != pAddr) && (0 < szAddr) && (NULL != src)) {
+ switch (afam) {
+ case AF_INET : {
+ if (sizeof(struct in_addr) == szAddr) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ if (sizeof(struct in6_addr) == szAddr) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ }
+ } break;
+#endif
+ }
+ if (DK4_SOCKET_RESULT_SUCCESS == back) {
+ back = dk4socket_my_inet_pton(pAddr, szAddr, afam, src, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- -inet_pton */
+#endif
+}
+
diff --git a/support/dktools/dk4sock06.ctr b/support/dktools/dk4sock06.ctr
new file mode 100644
index 0000000000..e8101716e6
--- /dev/null
+++ b/support/dktools/dk4sock06.ctr
@@ -0,0 +1,588 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4sock.h"
+#include "dk4maaul.h"
+#include "dk4maaus.h"
+
+
+
+$!trace-include
+
+
+
+#if !DK4_HAVE_INET_PTON
+
+/** Character classes.
+*/
+enum {
+ /** Any character not rom the types below.
+ */
+ INPUT_ANY = 0 ,
+
+ /** Digit.
+ */
+ INPUT_DIGIT ,
+
+ /** Separator (dot for IPv4, colon for IPv6).
+ */
+ INPUT_SEP ,
+
+ /** End of input reached.
+ */
+ INPUT_END
+};
+
+/** States while reading IPv4.
+*/
+enum {
+ /** Nothing processed yet.
+ */
+ S4_INIT = 0 ,
+
+ /** Previous character was a separator.
+ */
+ S4_SEP ,
+
+ /** Previous character was digit.
+ */
+ S4_DIG ,
+
+ /** Successfully finished IP address retrieval.
+ */
+ S4_FINISHED ,
+
+ /** Error found in previous input.
+ */
+ S4_ERROR
+};
+
+static
+int
+dk4socket_classify_input_char(
+ char c,
+ int ipv6,
+ unsigned short *valptr
+)
+{
+ int back = INPUT_ANY;
+ switch (c) {
+ case ':' : {
+ if (0 != ipv6) { back = INPUT_SEP; }
+ } break;
+ case '.' : {
+ if (0 == ipv6) { back = INPUT_SEP; }
+ } break;
+ case '0': { back = INPUT_DIGIT; *valptr = 0; } break;
+ case '1': { back = INPUT_DIGIT; *valptr = 1; } break;
+ case '2': { back = INPUT_DIGIT; *valptr = 2; } break;
+ case '3': { back = INPUT_DIGIT; *valptr = 3; } break;
+ case '4': { back = INPUT_DIGIT; *valptr = 4; } break;
+ case '5': { back = INPUT_DIGIT; *valptr = 5; } break;
+ case '6': { back = INPUT_DIGIT; *valptr = 6; } break;
+ case '7': { back = INPUT_DIGIT; *valptr = 7; } break;
+ case '8': { back = INPUT_DIGIT; *valptr = 8; } break;
+ case '9': { back = INPUT_DIGIT; *valptr = 9; } break;
+ case 'a': {
+ if (0 != ipv6) { back = INPUT_DIGIT; *valptr = 10; }
+ } break;
+ case 'A': {
+ if (0 != ipv6) { back = INPUT_DIGIT; *valptr = 10; }
+ } break;
+ case 'b': {
+ if (0 != ipv6) { back = INPUT_DIGIT; *valptr = 11; }
+ } break;
+ case 'B': {
+ if (0 != ipv6) { back = INPUT_DIGIT; *valptr = 11; }
+ } break;
+ case 'c': {
+ if (0 != ipv6) { back = INPUT_DIGIT; *valptr = 12; }
+ } break;
+ case 'C': {
+ if (0 != ipv6) { back = INPUT_DIGIT; *valptr = 12; }
+ } break;
+ case 'd': {
+ if (0 != ipv6) { back = INPUT_DIGIT; *valptr = 13; }
+ } break;
+ case 'D': {
+ if (0 != ipv6) { back = INPUT_DIGIT; *valptr = 13; }
+ } break;
+ case 'e': {
+ if (0 != ipv6) { back = INPUT_DIGIT; *valptr = 14; }
+ } break;
+ case 'E': {
+ if (0 != ipv6) { back = INPUT_DIGIT; *valptr = 14; }
+ } break;
+ case 'f': {
+ if (0 != ipv6) { back = INPUT_DIGIT; *valptr = 15; }
+ } break;
+ case 'F': {
+ if (0 != ipv6) { back = INPUT_DIGIT; *valptr = 15; }
+ } break;
+ }
+ return back;
+}
+
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+
+
+/** States while reading IPv4.
+*/
+enum {
+ /** Nothing processed yet.
+ */
+ S6_INIT = 0 ,
+
+ /** Previous character was a separator.
+ */
+ S6_SEP ,
+
+ /** Previous two characters were separators.
+ */
+ S6_DSEP ,
+
+ /** Previous character was digit.
+ */
+ S6_DIG ,
+
+ /** Successfully finished IP address retrieval.
+ */
+ S6_FINISHED ,
+
+ /** Error found in previous input.
+ */
+ S6_ERROR
+};
+
+static
+int
+dk4socket_my_ip6_pton(
+ void *pAddr,
+ size_t szAddr,
+ const char *src,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er;
+ unsigned short left[8]; /* Values for left side */
+ unsigned short right[8]; /* Values for right side */
+ struct in6_addr *inp6 = NULL; /* Result */
+ int isright = 0; /* Flag: Already on right side */
+ int hl = 0; /* Number of values on left side */
+ int hr = 0; /* Number of values on right side */
+ int icl = 0; /* Input character class */
+ int cc = 1; /* Flag: Can continue */
+ int st = S6_INIT; /* Current state */
+ int back = DK4_SOCKET_RESULT_FAILED;
+ int i = 0; /* Index to fill address */
+ unsigned short curval = 0; /* Value collected so far */
+ unsigned short us = 0; /* Current character value */
+
+ do {
+ if ('\0' == *src) {
+ icl = INPUT_END;
+ } else {
+ icl = dk4socket_classify_input_char(*src, 1, &us);
+ }
+ switch (st) {
+ case S6_INIT : {
+ switch (icl) {
+ case INPUT_DIGIT : {
+ curval = us;
+ st = S6_DIG;
+ } break;
+ case INPUT_SEP : {
+ st = S6_SEP;
+ } break;
+ default : {
+ st = S6_ERROR;
+ cc = -1;
+ } break;
+ }
+ } break;
+ case S6_SEP : {
+ switch (icl) {
+ case INPUT_DIGIT : {
+ curval = us;
+ st = S6_DIG;
+ } break;
+ case INPUT_SEP : {
+ st = S6_DSEP;
+ if (0 == isright) {
+ isright = 1;
+ } else {
+ st = S6_ERROR;
+ cc = -1;
+ }
+ } break;
+ default : {
+ st = S6_ERROR;
+ cc = -1;
+ } break;
+ }
+ } break;
+ case S6_DSEP : {
+ switch (icl) {
+ case INPUT_DIGIT : {
+ curval = us;
+ st = S6_DIG;
+ } break;
+ case INPUT_END : {
+ st = S6_FINISHED;
+ } break;
+ default : {
+ st = S6_ERROR;
+ cc = -1;
+ } break;
+ }
+ } break;
+ case S6_DIG : {
+ switch (icl) {
+ case INPUT_DIGIT : {
+ dk4error_init(&er);
+ curval = dk4ma_ushort_add(
+ dk4ma_ushort_mul(curval, 16UL, &er),
+ us, &er
+ );
+ if (DK4_E_NONE != er.ec) {
+ st = S6_ERROR;
+ cc = -1;
+ }
+ } break;
+ case INPUT_SEP : {
+ if (0 != isright) {
+ if (8 > hr) {
+ right[hr++] = curval;
+ st = S6_SEP;
+ } else {
+ st = S6_ERROR;
+ cc = -1;
+ }
+ } else {
+ if (8 > hl) {
+ left[hl++] = curval;
+ st = S6_SEP;
+ } else {
+ st = S6_ERROR;
+ cc = -1;
+ }
+ }
+ } break;
+ case INPUT_END : {
+ if (0 != isright) {
+ if (8 > hr) {
+ right[hr++] = curval;
+ st = S6_FINISHED;
+ cc = 0;
+ } else {
+ st = S6_ERROR;
+ cc = -1;
+ }
+ } else {
+ if (8 > hl) {
+ left[hl++] = curval;
+ st = S6_FINISHED;
+ cc = 0;
+ } else {
+ st = S6_ERROR;
+ cc = -1;
+ }
+ }
+ } break;
+ default : {
+ st = S6_ERROR;
+ cc = -1;
+ } break;
+ }
+ } break;
+ }
+ src++;
+ if ((1 == cc) && (INPUT_END == icl)) { cc = 0; }
+ } while (1 == cc);
+ if ((0 == cc) && (S6_FINISHED == st)) {
+ if (9 > (hl + hr)) {
+ inp6 = (struct in6_addr *)pAddr;
+ for (i = 0; i < 8; i++) {
+#if DK4_ON_WINDOWS
+ inp6->u.Word[i] = dk4socket_htons(0);
+#else
+ inp6->s6_addr16[i] = dk4socket_htons(0);
+#endif
+ }
+ for (i = 0; i < hl; i++) {
+#if DK4_ON_WINDOWS
+ inp6->u.Word[i] = dk4socket_htons(left[i]);
+#else
+ inp6->s6_addr16[i] = dk4socket_htons(left[i]);
+#endif
+ }
+ for (i = 0; i < hr; i++) {
+#if DK4_ON_WINDOWS
+ inp6->u.Word[8 - hr + i ] = dk4socket_htons(right[i]);
+#else
+ inp6->s6_addr16[8 - hr + i] = dk4socket_htons(right[i]);
+#endif
+ }
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ return back;
+}
+
+#endif
+
+static
+int
+dk4socket_my_ip4_pton(
+ void *pAddr,
+ size_t szAddr,
+ const char *src,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er;
+ struct in_addr *pin4;
+ unsigned long curval = 0UL;
+ unsigned long result = 0UL;
+ int back = DK4_SOCKET_RESULT_FAILED;
+ int cc = 1;
+ int icl = 0;
+ int st = S4_INIT;
+ int curnum = 0;
+ unsigned short us = 0;
+ $? "+ dk4socket_my_ip4_pton \"%!8s\"", src
+ do {
+ us = 0;
+ if ('\0' == *src) {
+ icl = INPUT_END;
+ } else {
+ icl = dk4socket_classify_input_char(*src, 0, &us);
+ }
+ switch (icl) {
+ case INPUT_DIGIT : {
+ switch (st) {
+ case S4_INIT: {
+ curval = (unsigned long)us;
+ st = S4_DIG;
+ } break;
+ case S4_SEP : {
+ curval = (unsigned long)us;
+ st = S4_DIG;
+ } break;
+ case S4_DIG : {
+ dk4error_init(&er);
+ curval = dk4ma_ulong_add(
+ dk4ma_ulong_mul(curval, 10UL, &er),
+ (unsigned long)us,
+ &er
+ );
+ if (DK4_E_NONE != er.ec) {
+ st = S4_ERROR;
+ cc = -1;
+ }
+ } break;
+ }
+ } break;
+ case INPUT_SEP : {
+ switch (st) {
+ case S4_INIT: {
+ st = S4_ERROR;
+ cc = -1;
+ } break;
+ case S4_SEP : {
+ st = S4_ERROR;
+ cc = -1;
+ } break;
+ case S4_DIG : {
+ if (256UL > curval) {
+ switch (curnum++) {
+ case 0: {
+ result = ((curval << 24) & 0xFF000000UL);
+ st = S4_SEP;
+ curval = 0UL;
+ } break;
+ case 1: {
+ result |= ((curval << 16) & 0x00FF0000UL);
+ st = S4_SEP;
+ curval = 0UL;
+ } break;
+ case 2: {
+ result |= ((curval << 8) & 0x0000FF00UL);
+ st = S4_SEP;
+ curval = 0UL;
+ } break;
+ default: {
+ st = S4_ERROR;
+ cc = -1;
+ } break;
+ }
+ } else {
+ st = S4_ERROR;
+ cc = -1;
+ }
+ } break;
+ }
+ } break;
+ case INPUT_END : {
+ switch (st) {
+ case S4_INIT: {
+ st = S4_ERROR;
+ cc = -1;
+ } break;
+ case S4_SEP : {
+ st = S4_ERROR;
+ cc = -1;
+ } break;
+ case S4_DIG : {
+ st = S4_ERROR;
+ cc = -1;
+ if (3 == curnum) {
+ if (256UL > curval) {
+ result |= curval;
+ cc = 0;
+ st = S4_FINISHED;
+ }
+ }
+ } break;
+ }
+ } break;
+ default : {
+ st = S4_ERROR;
+ cc = -1;
+ } break;
+ }
+ src++;
+ } while(1 == cc);
+ if ((0 == cc) && (S4_FINISHED == st)) {
+ pin4 = (struct in_addr *)pAddr;
+ pin4->s_addr = dk4socket_htonl(result);
+ back = DK4_SOCKET_RESULT_FAILED;
+ $? ". result = %lu.%lu.%lu.%lu", ((result >> 24) & 0x000000FFUL), ((result >> 16) & 0x000000FFUL), ((result >> 8) & 0x000000FFUL), (result & 0x000000FFUL)
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ $? ". failed"
+ }
+ $? "- dk4socket_my_ip4_pton %d", back
+ return back;
+}
+
+static
+int
+dk4socket_my_inet_pton(
+ void *pAddr,
+ size_t szAddr,
+ int afam,
+ const char *src,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_SOCKET_RESULT_FAILED;
+
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ if (AF_INET6 == afam) {
+ back = dk4socket_my_ip6_pton(pAddr, szAddr, src, erp);
+ } else {
+#endif
+ back = dk4socket_my_ip4_pton(pAddr, szAddr, src, erp);
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ }
+#endif
+ return back;
+}
+
+#endif
+
+
+int
+dk4socket_c8_inet_pton(
+ void *pAddr,
+ size_t szAddr,
+ int afam,
+ const char *src,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_INET_PTON
+ /* +++++ +inet_pton */
+ int back = DK4_SOCKET_RESULT_FAILED;
+ int res;
+ if ((NULL != pAddr) && (0 < szAddr) && (NULL != src)) {
+ switch (afam) {
+ case AF_INET : {
+ if (sizeof(struct in_addr) == szAddr) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ if (sizeof(struct in6_addr) == szAddr) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ }
+ } break;
+#endif
+ }
+ if (DK4_SOCKET_RESULT_SUCCESS == back) {
+ back = DK4_SOCKET_RESULT_FAILED;
+ dk4socket_error_reset();
+ res = inet_pton(afam, src, pAddr);
+ switch (res) {
+ case 0 : {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ case -1 : {
+ dk4socket_error_report(erp, DK4_E_SOCKET_INET_PTON);
+ } break;
+ default : {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- +inet_pton */
+#else
+ /* +++++ -inet_pton */
+ int back = DK4_SOCKET_RESULT_FAILED;
+ if ((NULL != pAddr) && (0 < szAddr) && (NULL != src)) {
+ switch (afam) {
+ case AF_INET : {
+ if (sizeof(struct in_addr) == szAddr) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ if (sizeof(struct in6_addr) == szAddr) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ }
+ } break;
+#endif
+ }
+ if (DK4_SOCKET_RESULT_SUCCESS == back) {
+ back = dk4socket_my_inet_pton(pAddr, szAddr, afam, src, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- -inet_pton */
+#endif
+}
+
diff --git a/support/dktools/dk4sock07.c b/support/dktools/dk4sock07.c
new file mode 100644
index 0000000000..65a0a044d1
--- /dev/null
+++ b/support/dktools/dk4sock07.c
@@ -0,0 +1,94 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sock07.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4sock07.c The dk4sock07 module.
+*/
+
+
+#line 10 "dk4sock07.ctr"
+
+#include "dk4sock.h"
+#include "dk4rec24.h"
+
+
+
+
+
+#line 17 "dk4sock07.ctr"
+
+
+
+int
+dk4socket_wc_inet_pton(
+ void *pAddr,
+ size_t szAddr,
+ int afam,
+ const wchar_t *src,
+ dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS && DK4_HAVE_INET_PTON
+ int back = DK4_SOCKET_RESULT_FAILED;
+ int res;
+ if ((NULL != pAddr) && (NULL != src) && (0 < szAddr)) {
+ dk4socket_error_reset();
+ res = InetPtonW(afam, src, pAddr);
+ if (0 < res) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ if (0 > res) {
+ dk4socket_error_report(erp, DK4_E_SOCKET_INET_PTON);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ char buf[128];
+ int back = DK4_SOCKET_RESULT_FAILED;
+ if ((NULL != pAddr) && (NULL != src) && (0 < szAddr)) {
+ if (0 != dk4recode_wchar_t_to_char(buf, sizeof(buf), src, erp)) {
+ back = dk4socket_c8_inet_pton(pAddr, szAddr, afam, buf, erp);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#endif
+}
+
diff --git a/support/dktools/dk4sock07.ctr b/support/dktools/dk4sock07.ctr
new file mode 100644
index 0000000000..b2af0aedf9
--- /dev/null
+++ b/support/dktools/dk4sock07.ctr
@@ -0,0 +1,61 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4sock.h"
+#include "dk4rec24.h"
+
+
+
+$!trace-include
+
+
+
+int
+dk4socket_wc_inet_pton(
+ void *pAddr,
+ size_t szAddr,
+ int afam,
+ const wchar_t *src,
+ dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS && DK4_HAVE_INET_PTON
+ int back = DK4_SOCKET_RESULT_FAILED;
+ int res;
+ if ((NULL != pAddr) && (NULL != src) && (0 < szAddr)) {
+ dk4socket_error_reset();
+ res = InetPtonW(afam, src, pAddr);
+ if (0 < res) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ if (0 > res) {
+ dk4socket_error_report(erp, DK4_E_SOCKET_INET_PTON);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ char buf[128];
+ int back = DK4_SOCKET_RESULT_FAILED;
+ if ((NULL != pAddr) && (NULL != src) && (0 < szAddr)) {
+ if (0 != dk4recode_wchar_t_to_char(buf, sizeof(buf), src, erp)) {
+ back = dk4socket_c8_inet_pton(pAddr, szAddr, afam, buf, erp);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#endif
+}
+
diff --git a/support/dktools/dk4sock08.c b/support/dktools/dk4sock08.c
new file mode 100644
index 0000000000..b8cd68e35a
--- /dev/null
+++ b/support/dktools/dk4sock08.c
@@ -0,0 +1,60 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sock08.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4sock08.c The dk4sock08 module.
+*/
+
+
+#line 10 "dk4sock08.ctr"
+
+#include "dk4sock.h"
+
+
+
+int
+dk4socket_inet_pton(
+ void *pAddr,
+ size_t szAddr,
+ int afam,
+ const dkChar *src,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4socket_wc_inet_pton(pAddr, szAddr, afam, src, erp));
+#else
+ return (dk4socket_c8_inet_pton(pAddr, szAddr, afam, src, erp));
+#endif
+}
diff --git a/support/dktools/dk4sock08.ctr b/support/dktools/dk4sock08.ctr
new file mode 100644
index 0000000000..7fa1d12e8b
--- /dev/null
+++ b/support/dktools/dk4sock08.ctr
@@ -0,0 +1,29 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4sock.h"
+
+
+
+int
+dk4socket_inet_pton(
+ void *pAddr,
+ size_t szAddr,
+ int afam,
+ const dkChar *src,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4socket_wc_inet_pton(pAddr, szAddr, afam, src, erp));
+#else
+ return (dk4socket_c8_inet_pton(pAddr, szAddr, afam, src, erp));
+#endif
+}
diff --git a/support/dktools/dk4sock09.c b/support/dktools/dk4sock09.c
new file mode 100644
index 0000000000..b9a90f2c36
--- /dev/null
+++ b/support/dktools/dk4sock09.c
@@ -0,0 +1,113 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sock09.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4sock09.c The dk4sock09 module.
+*/
+
+
+#line 10 "dk4sock09.ctr"
+
+#include "dk4sock.h"
+
+
+
+
+
+#line 16 "dk4sock09.ctr"
+
+
+
+int
+dk4socket_up(dk4_er_t *er)
+{
+#if DK4_ON_WINDOWS
+ WSADATA wsaData;
+ WORD wVersionRequested;
+ int back = DK4_SOCKET_RESULT_FAILED;
+ int err;
+
+
+#line 28 "dk4sock09.ctr"
+ wVersionRequested = MAKEWORD(2,0);
+ err = WSAStartup(wVersionRequested, &wsaData);
+ if (0 == err) {
+
+#line 31 "dk4sock09.ctr"
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+
+#line 33 "dk4sock09.ctr"
+ dk4error_set_idetails(er, DK4_E_SOCKET_UP, err);
+ }
+
+
+#line 36 "dk4sock09.ctr"
+ return back;
+#else
+ return DK4_SOCKET_RESULT_SUCCESS;
+#endif
+}
+
+
+
+int
+dk4socket_down(dk4_er_t *er)
+{
+#if DK4_ON_WINDOWS
+ int back = DK4_SOCKET_RESULT_FAILED;
+ int errc;
+
+
+#line 51 "dk4sock09.ctr"
+ WSASetLastError(0);
+ if (0 == WSACleanup()) {
+
+#line 53 "dk4sock09.ctr"
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ errc = WSAGetLastError();
+
+#line 56 "dk4sock09.ctr"
+ dk4error_set_idetails(er, DK4_E_SOCKET_DOWN, errc);
+ }
+
+
+#line 59 "dk4sock09.ctr"
+ return back;
+#else
+ return DK4_SOCKET_RESULT_SUCCESS;
+#endif
+}
+
diff --git a/support/dktools/dk4sock09.ctr b/support/dktools/dk4sock09.ctr
new file mode 100644
index 0000000000..78706e365d
--- /dev/null
+++ b/support/dktools/dk4sock09.ctr
@@ -0,0 +1,64 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4sock.h"
+
+
+
+$!trace-include
+
+
+
+int
+dk4socket_up(dk4_er_t *er)
+{
+#if DK4_ON_WINDOWS
+ WSADATA wsaData;
+ WORD wVersionRequested;
+ int back = DK4_SOCKET_RESULT_FAILED;
+ int err;
+ $? "+ dk4socket_up"
+ wVersionRequested = MAKEWORD(2,0);
+ err = WSAStartup(wVersionRequested, &wsaData);
+ if (0 == err) { $? ". success"
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else { $? "! error %d (%x)", err, err
+ dk4error_set_idetails(er, DK4_E_SOCKET_UP, err);
+ }
+ $? "- dk4socket_up %d", back
+ return back;
+#else
+ return DK4_SOCKET_RESULT_SUCCESS;
+#endif
+}
+
+
+
+int
+dk4socket_down(dk4_er_t *er)
+{
+#if DK4_ON_WINDOWS
+ int back = DK4_SOCKET_RESULT_FAILED;
+ int errc;
+ $? "+ dk4socket_down"
+ WSASetLastError(0);
+ if (0 == WSACleanup()) { $? ". success"
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ errc = WSAGetLastError(); $? "! error %d (%x)", errc, errc
+ dk4error_set_idetails(er, DK4_E_SOCKET_DOWN, errc);
+ }
+ $? "- dk4socket_down %d", back
+ return back;
+#else
+ return DK4_SOCKET_RESULT_SUCCESS;
+#endif
+}
+
diff --git a/support/dktools/dk4sock10.c b/support/dktools/dk4sock10.c
new file mode 100644
index 0000000000..ff048fa5be
--- /dev/null
+++ b/support/dktools/dk4sock10.c
@@ -0,0 +1,175 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sock10.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4sock10.c The dk4sock10 module.
+*/
+
+
+#line 9 "dk4sock10.ctr"
+
+
+#include "dk4sock.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+
+
+#line 37 "dk4sock10.ctr"
+
+
+
+dk4_socket_t
+dk4socket_open(int af, int tp, int pr, dk4_er_t *erp)
+{
+ dk4_socket_t back = INVALID_SOCKET;
+
+
+#line 45 "dk4sock10.ctr"
+ switch (af) {
+ case AF_INET:
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6:
+#endif
+#if defined(AF_UNIX)
+ case AF_UNIX:
+#endif
+#if defined(AF_LOCAL) && (AF_UNIX != AF_LOCAL)
+ case AF_LOCAL:
+#endif
+ {
+ switch (tp) {
+ case SOCK_STREAM : case SOCK_DGRAM : {
+ dk4socket_error_reset();
+ back = socket(af, tp, pr);
+ if (INVALID_SOCKET == back) {
+ dk4socket_error_report(erp, DK4_E_SOCKET_SOCKET);
+ }
+ } break;
+ default: {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+
+
+#line 68 "dk4sock10.ctr"
+ } break;
+ }
+ } break;
+ default: {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+
+
+#line 74 "dk4sock10.ctr"
+ } break;
+ }
+
+
+#line 77 "dk4sock10.ctr"
+ return back;
+}
+
+
+
+int
+dk4socket_close(dk4_socket_t so, dk4_er_t *erp)
+{
+ int back = DK4_SOCKET_RESULT_FAILED;
+
+ if (INVALID_SOCKET != so) {
+ dk4socket_error_reset();
+#if DK4_ON_WINDOWS
+ if (0 == closesocket(so))
+#else
+ if (0 == close(so))
+#endif
+ {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_CLOSE);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4socket_shutdown(dk4_socket_t so, int how, dk4_er_t *erp)
+{
+ int back = DK4_SOCKET_RESULT_FAILED;
+ if (INVALID_SOCKET != so) {
+ switch (how) {
+ case DK4_SOCKET_SHUT_READ :
+ case DK4_SOCKET_SHUT_WRITE :
+ case DK4_SOCKET_SHUT_RDWR :
+ {
+ dk4socket_error_reset();
+ if (0 == shutdown(so, how)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_SHUTDOWN);
+ }
+ } break;
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4sock10.ctr b/support/dktools/dk4sock10.ctr
new file mode 100644
index 0000000000..b7f58e8feb
--- /dev/null
+++ b/support/dktools/dk4sock10.ctr
@@ -0,0 +1,133 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% module
+
+
+#include "dk4sock.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+$!trace-include
+
+
+
+dk4_socket_t
+dk4socket_open(int af, int tp, int pr, dk4_er_t *erp)
+{
+ dk4_socket_t back = INVALID_SOCKET;
+ $? "+ dk4socket_open"
+ switch (af) {
+ case AF_INET:
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6:
+#endif
+#if defined(AF_UNIX)
+ case AF_UNIX:
+#endif
+#if defined(AF_LOCAL) && (AF_UNIX != AF_LOCAL)
+ case AF_LOCAL:
+#endif
+ {
+ switch (tp) {
+ case SOCK_STREAM : case SOCK_DGRAM : {
+ dk4socket_error_reset();
+ back = socket(af, tp, pr);
+ if (INVALID_SOCKET == back) {
+ dk4socket_error_report(erp, DK4_E_SOCKET_SOCKET);
+ }
+ } break;
+ default: {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ $? "! tp"
+ } break;
+ }
+ } break;
+ default: {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ $? "! af"
+ } break;
+ }
+ $? "- dk4socket_open %d", (int)back
+ return back;
+}
+
+
+
+int
+dk4socket_close(dk4_socket_t so, dk4_er_t *erp)
+{
+ int back = DK4_SOCKET_RESULT_FAILED;
+
+ if (INVALID_SOCKET != so) {
+ dk4socket_error_reset();
+#if DK4_ON_WINDOWS
+ if (0 == closesocket(so))
+#else
+ if (0 == close(so))
+#endif
+ {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_CLOSE);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4socket_shutdown(dk4_socket_t so, int how, dk4_er_t *erp)
+{
+ int back = DK4_SOCKET_RESULT_FAILED;
+ if (INVALID_SOCKET != so) {
+ switch (how) {
+ case DK4_SOCKET_SHUT_READ :
+ case DK4_SOCKET_SHUT_WRITE :
+ case DK4_SOCKET_SHUT_RDWR :
+ {
+ dk4socket_error_reset();
+ if (0 == shutdown(so, how)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_SHUTDOWN);
+ }
+ } break;
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4sock11.c b/support/dktools/dk4sock11.c
new file mode 100644
index 0000000000..8561a6d43b
--- /dev/null
+++ b/support/dktools/dk4sock11.c
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sock11.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4sock11.c The dk4sock11 module.
+*/
+
+
+#line 9 "dk4sock11.ctr"
+
+#include "dk4sock.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+
+
+#line 36 "dk4sock11.ctr"
+
+
+
+int
+dk4socket_bind(
+ dk4_socket_t sock,
+ const struct sockaddr *pAddr,
+ size_t szAddr,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_SOCKET_RESULT_FAILED;
+ if ((INVALID_SOCKET != sock) && (NULL != pAddr) && (0 < szAddr)) {
+ (void)dk4socket_correct_addr_lgt(pAddr, &szAddr);
+ dk4socket_error_reset();
+#if DK4_HAVE_SOCKLEN_T
+ if (0 == bind(sock, pAddr, (socklen_t)szAddr))
+#else
+ if (0 == bind(sock, pAddr, (int)szAddr))
+#endif
+ {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ }
+ else
+ {
+ dk4socket_error_report(erp, DK4_E_SOCKET_BIND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4sock11.ctr b/support/dktools/dk4sock11.ctr
new file mode 100644
index 0000000000..b483837cb2
--- /dev/null
+++ b/support/dktools/dk4sock11.ctr
@@ -0,0 +1,68 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% module
+
+#include "dk4sock.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+$!trace-include
+
+
+
+int
+dk4socket_bind(
+ dk4_socket_t sock,
+ const struct sockaddr *pAddr,
+ size_t szAddr,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_SOCKET_RESULT_FAILED;
+ if ((INVALID_SOCKET != sock) && (NULL != pAddr) && (0 < szAddr)) {
+ (void)dk4socket_correct_addr_lgt(pAddr, &szAddr);
+ dk4socket_error_reset();
+#if DK4_HAVE_SOCKLEN_T
+ if (0 == bind(sock, pAddr, (socklen_t)szAddr))
+#else
+ if (0 == bind(sock, pAddr, (int)szAddr))
+#endif
+ {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ }
+ else
+ {
+ dk4socket_error_report(erp, DK4_E_SOCKET_BIND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4sock12.c b/support/dktools/dk4sock12.c
new file mode 100644
index 0000000000..4586300270
--- /dev/null
+++ b/support/dktools/dk4sock12.c
@@ -0,0 +1,196 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sock12.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4sock12.c The dk4sock12 module.
+*/
+
+
+#line 9 "dk4sock12.ctr"
+
+#include "dk4sock.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STRINGS_H
+#ifndef STRINGS_H_INCLUDED
+#include <strings.h>
+#define STRINGS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4mem.h"
+
+
+
+
+
+#line 47 "dk4sock12.ctr"
+
+
+int
+dk4socket_connect(
+ dk4_socket_t sock,
+ const struct sockaddr *pAddr,
+ size_t szAddr,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_SOCKET_RESULT_FAILED;
+ int errc = 0;
+
+
+#line 60 "dk4sock12.ctr"
+ if ((INVALID_SOCKET != sock) && (NULL != pAddr) && (0 < szAddr)) {
+
+
+#line 62 "dk4sock12.ctr"
+ (void)dk4socket_correct_addr_lgt(pAddr, &szAddr);
+ dk4socket_error_reset();
+#if DK4_HAVE_SOCKLEN_T
+ if (0 == connect(sock, pAddr, (socklen_t)szAddr))
+#else
+ if (0 == connect(sock, pAddr, (int)szAddr))
+#endif
+ {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+
+
+#line 72 "dk4sock12.ctr"
+ }
+ else
+ {
+ errc = dk4socket_error_get();
+
+
+#line 77 "dk4sock12.ctr"
+#if DK4_ON_WINDOWS
+ if (WSAEWOULDBLOCK == errc)
+#else
+ if (EINPROGRESS == errc)
+#endif
+ {
+ back = DK4_SOCKET_RESULT_IN_PROGRESS;
+
+
+#line 85 "dk4sock12.ctr"
+ }
+ else
+ {
+ dk4error_set_idetails(erp, DK4_E_SOCKET_CONNECT, errc);
+
+
+#line 90 "dk4sock12.ctr"
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+
+
+#line 95 "dk4sock12.ctr"
+ }
+
+
+#line 97 "dk4sock12.ctr"
+ return back;
+}
+
+
+
+#if DK4_HAVE_STRUCT_SOCKADDR_UN
+
+/** Create a UNIX domain socket in client mode.
+ @param filename File name, max 107 characters long.
+ @param erp Error report, may be NULL.
+ @return Valid socket on success, INVALID_SOCKET on error.
+*/
+dk4_socket_t
+dk4socket_c8_unix_client(
+ const char *filename,
+ dk4_er_t *erp
+)
+{
+ struct sockaddr_un soun;
+ size_t slen;
+ dk4_socket_t back = INVALID_SOCKET;
+ int res;
+
+ if (NULL != filename) {
+ if (108 > strlen(filename)) {
+ DK4_MEMRES(&soun, sizeof(soun));
+ soun.sun_family = AF_UNIX;
+ strcpy(soun.sun_path, filename);
+ slen = dk4socket_unix_length(&soun);
+ back = dk4socket_open(AF_UNIX, SOCK_STREAM, 0, erp);
+ if (INVALID_SOCKET != back) {
+ res = dk4socket_connect(
+ back, (const struct sockaddr *)(&soun), slen, erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS != res) {
+ (void)dk4socket_close(back, NULL);
+ back = INVALID_SOCKET;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+#endif
+
diff --git a/support/dktools/dk4sock12.ctr b/support/dktools/dk4sock12.ctr
new file mode 100644
index 0000000000..941b2328eb
--- /dev/null
+++ b/support/dktools/dk4sock12.ctr
@@ -0,0 +1,146 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% module
+
+#include "dk4sock.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STRINGS_H
+#ifndef STRINGS_H_INCLUDED
+#include <strings.h>
+#define STRINGS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4mem.h"
+
+
+
+$!trace-include
+
+
+int
+dk4socket_connect(
+ dk4_socket_t sock,
+ const struct sockaddr *pAddr,
+ size_t szAddr,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_SOCKET_RESULT_FAILED;
+ int errc = 0;
+ $? "+ dk4socket_connect"
+ if ((INVALID_SOCKET != sock) && (NULL != pAddr) && (0 < szAddr)) {
+ $? ". args PTR=%d %lu", TR_IPTR(pAddr), (unsigned long)szAddr
+ (void)dk4socket_correct_addr_lgt(pAddr, &szAddr);
+ dk4socket_error_reset();
+#if DK4_HAVE_SOCKLEN_T
+ if (0 == connect(sock, pAddr, (socklen_t)szAddr))
+#else
+ if (0 == connect(sock, pAddr, (int)szAddr))
+#endif
+ {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ $? ". connect() = 0"
+ }
+ else
+ {
+ errc = dk4socket_error_get();
+ $? "! connect() != 0, error code = %d", errc
+#if DK4_ON_WINDOWS
+ if (WSAEWOULDBLOCK == errc)
+#else
+ if (EINPROGRESS == errc)
+#endif
+ {
+ back = DK4_SOCKET_RESULT_IN_PROGRESS;
+ $? ". would block"
+ }
+ else
+ {
+ dk4error_set_idetails(erp, DK4_E_SOCKET_CONNECT, errc);
+ $? "! any error"
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ $? "! args"
+ }
+ $? "- dk4socket_connect %d", back
+ return back;
+}
+
+
+
+#if DK4_HAVE_STRUCT_SOCKADDR_UN
+
+/** Create a UNIX domain socket in client mode.
+ @param filename File name, max 107 characters long.
+ @param erp Error report, may be NULL.
+ @return Valid socket on success, INVALID_SOCKET on error.
+*/
+dk4_socket_t
+dk4socket_c8_unix_client(
+ const char *filename,
+ dk4_er_t *erp
+)
+{
+ struct sockaddr_un soun;
+ size_t slen;
+ dk4_socket_t back = INVALID_SOCKET;
+ int res;
+
+ if (NULL != filename) {
+ if (108 > strlen(filename)) {
+ DK4_MEMRES(&soun, sizeof(soun));
+ soun.sun_family = AF_UNIX;
+ strcpy(soun.sun_path, filename);
+ slen = dk4socket_unix_length(&soun);
+ back = dk4socket_open(AF_UNIX, SOCK_STREAM, 0, erp);
+ if (INVALID_SOCKET != back) {
+ res = dk4socket_connect(
+ back, (const struct sockaddr *)(&soun), slen, erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS != res) {
+ (void)dk4socket_close(back, NULL);
+ back = INVALID_SOCKET;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+#endif
+
diff --git a/support/dktools/dk4sock13.c b/support/dktools/dk4sock13.c
new file mode 100644
index 0000000000..47c54c82c5
--- /dev/null
+++ b/support/dktools/dk4sock13.c
@@ -0,0 +1,361 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sock13.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4sock13.c The dk4sock13 module.
+*/
+
+
+#line 9 "dk4sock13.ctr"
+
+#include "dk4sock.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STRINGS_H
+#ifndef STRINGS_H_INCLUDED
+#include <strings.h>
+#define STRINGS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4mem.h"
+#include "dk4stat.h"
+#include "dk4stat8.h"
+#include "dk4delfile08.h"
+
+
+
+
+#line 49 "dk4sock13.ctr"
+
+
+
+int
+dk4socket_listen(
+ dk4_socket_t sock,
+ int bl,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_SOCKET_RESULT_FAILED;
+ if ((INVALID_SOCKET != sock) && (0 < bl)) {
+ dk4socket_error_reset();
+ if (0 == listen(sock, bl)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_LISTEN);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+dk4_socket_t
+dk4socket_accept(
+ dk4_socket_t sock,
+ struct sockaddr *pAddr,
+ size_t *pSzAddr,
+ dk4_er_t *erp
+)
+{
+ dk4_socket_t back = INVALID_SOCKET;
+#if DK4_HAVE_SOCKLEN_T
+ socklen_t sz;
+#else
+ int sz;
+#endif
+
+
+#line 90 "dk4sock13.ctr"
+ if (INVALID_SOCKET != sock) {
+ if (NULL != pAddr) {
+
+#line 92 "dk4sock13.ctr"
+ if (NULL != pSzAddr) {
+
+#line 93 "dk4sock13.ctr"
+ if (0 < *pSzAddr) {
+
+#line 94 "dk4sock13.ctr"
+#if DK4_HAVE_SOCKLEN_T
+ sz = (socklen_t)(*pSzAddr);
+#else
+ sz = (int)(*pSzAddr);
+#endif
+ dk4socket_error_reset();
+ back = accept(sock, pAddr, &sz);
+ if (INVALID_SOCKET != back) {
+ *pSzAddr = (size_t)sz;
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_ACCEPT);
+ *pSzAddr = 0;
+ }
+ } else {
+
+#line 108 "dk4sock13.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+
+#line 111 "dk4sock13.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+
+#line 114 "dk4sock13.ctr"
+ /* ACCEPT */
+ dk4socket_error_reset();
+ back = accept(sock, NULL, NULL);
+ if (INVALID_SOCKET == back) {
+ dk4socket_error_report(erp, DK4_E_SOCKET_ACCEPT);
+ }
+ }
+ } else {
+
+#line 122 "dk4sock13.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 124 "dk4sock13.ctr"
+ return back;
+}
+
+#if DK4_HAVE_STRUCT_SOCKADDR_UN
+
+
+/** Change mode and optionally owner and group for a socket.
+ @param sock Socket file descriptor.
+ @param filename Socket file name.
+ @param owner New owner.
+ @param group New group.
+ @param mode New file mode.
+ @param cog Flag: Also change owner and group.
+ @param erp Error report, may be NULL
+*/
+static
+int
+dk4socket_i_change_owner_group_mode(
+ dk4_socket_t sock,
+ const char *filename,
+ uid_t owner,
+ gid_t group,
+ mode_t mode,
+ int cog,
+ dk4_er_t *erp
+)
+{
+ int errval;
+ int back = 1;
+
+
+#line 154 "dk4sock13.ctr"
+ if (0 != cog) {
+ errno = 0;
+ if (0 != chown(filename, owner, group)) {
+ errval = errno;
+ if (0 != fchown(sock, owner, group)) {
+ back = 0;
+ dk4error_set_idetails(erp, DK4_E_CHOWN_FAILED, errval);
+ }
+ }
+ }
+ errno = 0;
+ if (0 != chmod(filename, mode)) {
+ errval = errno;
+ if (0 != fchmod(sock, mode)) {
+ back = 0;
+ dk4error_set_idetails(erp, DK4_E_CHMOD_FAILED, errval);
+ }
+ }
+
+
+#line 173 "dk4sock13.ctr"
+ return back;
+}
+
+
+
+static
+dk4_socket_t
+dk4socket_i_c8_unix_listener_ogm(
+ const char *filename,
+ int backlog,
+ uid_t owner,
+ gid_t group,
+ mode_t mode,
+ int change,
+ dk4_er_t *erp
+)
+{
+ struct sockaddr_un soun;
+ dk4_stat_t stb;
+ size_t slen;
+ dk4_socket_t back = INVALID_SOCKET;
+ int md = 0;
+ int res;
+ int ogm1;
+ int ogm2;
+
+ if ((NULL != filename) && (0 < backlog)) {
+ if (108 > strlen(filename)) {
+ /* Attempt to remove existing socket.
+ */
+ res = 1;
+ if (0 != dk4stat_c8(&stb, filename, NULL)) {
+ res = 0;
+ if (0 != dk4stat_is_unix_domain_socket(&stb, NULL)) {
+ if (0 != dk4delete_file_c8(filename, NULL)) {
+ res = 1;
+ } else {
+ /* ERROR: Failed to remove old socket */
+ dk4error_set_simple_error_code(erp, DK4_E_UNLINK_FAILED);
+ }
+ } else {
+ /* ERROR: Not a socket */
+ dk4error_set_simple_error_code(erp, DK4_E_NON_SOCKET);
+ }
+ }
+ /* Open and bind new socket.
+ */
+ if (0 != res) {
+ DK4_MEMRES(&soun, sizeof(soun));
+ soun.sun_family = AF_UNIX;
+ strcpy(soun.sun_path, filename);
+ slen = dk4socket_unix_length(&soun);
+ back = dk4socket_open(AF_UNIX, SOCK_STREAM, 0, erp);
+ if (INVALID_SOCKET != back) {
+ (void)dk4socket_option_set_reuse(back, 1, NULL);
+ res = dk4socket_bind(
+ back, (const struct sockaddr *)(&soun), slen, erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ ogm1 = dk4socket_i_change_owner_group_mode(
+ back, filename, owner, group, mode, change, erp
+ );
+ res = dk4socket_listen(back, backlog, erp);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ ogm2 = dk4socket_i_change_owner_group_mode(
+ back, filename, owner, group, mode, change, erp
+ );
+ if ((0 == ogm1) && (0 == ogm2)) {
+ (void)dk4socket_close(back, NULL);
+ back = INVALID_SOCKET;
+ md = 1;
+ }
+ } else {
+ (void)dk4socket_close(back, NULL);
+ back = INVALID_SOCKET;
+ md = 1;
+ }
+ } else {
+ (void)dk4socket_close(back, NULL);
+ back = INVALID_SOCKET;
+ }
+ if ((INVALID_SOCKET == back) && (0 != md)) {
+ (void)dk4delete_file_c8(filename, NULL);
+ }
+ }
+ } else {
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+dk4_socket_t
+dk4socket_c8_unix_listener(
+ const char *filename,
+ int backlog,
+ dk4_er_t *erp
+)
+{
+ return (
+ dk4socket_i_c8_unix_listener_ogm(filename, backlog, 0, 0, 0660, 0, erp)
+ );
+}
+
+
+
+dk4_socket_t
+dk4socket_c8_unix_listener_owner_group_mode(
+ const char *filename,
+ int backlog,
+ uid_t owner,
+ gid_t group,
+ mode_t mode,
+ dk4_er_t *erp
+)
+{
+ return (
+ dk4socket_i_c8_unix_listener_ogm(
+ filename, backlog, owner, group, mode, 1, erp
+ )
+ );
+}
+
+
+
+
+#endif
diff --git a/support/dktools/dk4sock13.ctr b/support/dktools/dk4sock13.ctr
new file mode 100644
index 0000000000..739ba73c50
--- /dev/null
+++ b/support/dktools/dk4sock13.ctr
@@ -0,0 +1,305 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% module
+
+#include "dk4sock.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STRINGS_H
+#ifndef STRINGS_H_INCLUDED
+#include <strings.h>
+#define STRINGS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4mem.h"
+#include "dk4stat.h"
+#include "dk4stat8.h"
+#include "dk4delfile08.h"
+
+
+$!trace-include
+
+
+
+int
+dk4socket_listen(
+ dk4_socket_t sock,
+ int bl,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_SOCKET_RESULT_FAILED;
+ if ((INVALID_SOCKET != sock) && (0 < bl)) {
+ dk4socket_error_reset();
+ if (0 == listen(sock, bl)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_LISTEN);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+dk4_socket_t
+dk4socket_accept(
+ dk4_socket_t sock,
+ struct sockaddr *pAddr,
+ size_t *pSzAddr,
+ dk4_er_t *erp
+)
+{
+ dk4_socket_t back = INVALID_SOCKET;
+#if DK4_HAVE_SOCKLEN_T
+ socklen_t sz;
+#else
+ int sz;
+#endif
+ $? "+ dk4socket_accept %d", (int)sock
+ if (INVALID_SOCKET != sock) {
+ if (NULL != pAddr) { $? ". address buffer"
+ if (NULL != pSzAddr) { $? ". address size pointer"
+ if (0 < *pSzAddr) { $? ". arguments ok"
+#if DK4_HAVE_SOCKLEN_T
+ sz = (socklen_t)(*pSzAddr);
+#else
+ sz = (int)(*pSzAddr);
+#endif
+ dk4socket_error_reset();
+ back = accept(sock, pAddr, &sz);
+ if (INVALID_SOCKET != back) {
+ *pSzAddr = (size_t)sz;
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_ACCEPT);
+ *pSzAddr = 0;
+ }
+ } else { $? "! address size 0"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else { $? "! no address size pointer"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else { $? ". no address buffer"
+ /* ACCEPT */
+ dk4socket_error_reset();
+ back = accept(sock, NULL, NULL);
+ if (INVALID_SOCKET == back) {
+ dk4socket_error_report(erp, DK4_E_SOCKET_ACCEPT);
+ }
+ }
+ } else { $? "! invalid sock"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4socket_accept %d", back
+ return back;
+}
+
+#if DK4_HAVE_STRUCT_SOCKADDR_UN
+
+
+/** Change mode and optionally owner and group for a socket.
+ @param sock Socket file descriptor.
+ @param filename Socket file name.
+ @param owner New owner.
+ @param group New group.
+ @param mode New file mode.
+ @param cog Flag: Also change owner and group.
+ @param erp Error report, may be NULL
+*/
+static
+int
+dk4socket_i_change_owner_group_mode(
+ dk4_socket_t sock,
+ const char *filename,
+ uid_t owner,
+ gid_t group,
+ mode_t mode,
+ int cog,
+ dk4_er_t *erp
+)
+{
+ int errval;
+ int back = 1;
+ $? "+ dk4socket_i_change_owner_group_mode"
+ if (0 != cog) {
+ errno = 0;
+ if (0 != chown(filename, owner, group)) {
+ errval = errno;
+ if (0 != fchown(sock, owner, group)) {
+ back = 0;
+ dk4error_set_idetails(erp, DK4_E_CHOWN_FAILED, errval);
+ }
+ }
+ }
+ errno = 0;
+ if (0 != chmod(filename, mode)) {
+ errval = errno;
+ if (0 != fchmod(sock, mode)) {
+ back = 0;
+ dk4error_set_idetails(erp, DK4_E_CHMOD_FAILED, errval);
+ }
+ }
+ $? "- dk4socket_i_change_owner_group_mode"
+ return back;
+}
+
+
+
+static
+dk4_socket_t
+dk4socket_i_c8_unix_listener_ogm(
+ const char *filename,
+ int backlog,
+ uid_t owner,
+ gid_t group,
+ mode_t mode,
+ int change,
+ dk4_er_t *erp
+)
+{
+ struct sockaddr_un soun;
+ dk4_stat_t stb;
+ size_t slen;
+ dk4_socket_t back = INVALID_SOCKET;
+ int md = 0;
+ int res;
+ int ogm1;
+ int ogm2;
+
+ if ((NULL != filename) && (0 < backlog)) {
+ if (108 > strlen(filename)) {
+ /* Attempt to remove existing socket.
+ */
+ res = 1;
+ if (0 != dk4stat_c8(&stb, filename, NULL)) {
+ res = 0;
+ if (0 != dk4stat_is_unix_domain_socket(&stb, NULL)) {
+ if (0 != dk4delete_file_c8(filename, NULL)) {
+ res = 1;
+ } else {
+ /* ERROR: Failed to remove old socket */
+ dk4error_set_simple_error_code(erp, DK4_E_UNLINK_FAILED);
+ }
+ } else {
+ /* ERROR: Not a socket */
+ dk4error_set_simple_error_code(erp, DK4_E_NON_SOCKET);
+ }
+ }
+ /* Open and bind new socket.
+ */
+ if (0 != res) {
+ DK4_MEMRES(&soun, sizeof(soun));
+ soun.sun_family = AF_UNIX;
+ strcpy(soun.sun_path, filename);
+ slen = dk4socket_unix_length(&soun);
+ back = dk4socket_open(AF_UNIX, SOCK_STREAM, 0, erp);
+ if (INVALID_SOCKET != back) {
+ (void)dk4socket_option_set_reuse(back, 1, NULL);
+ res = dk4socket_bind(
+ back, (const struct sockaddr *)(&soun), slen, erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ ogm1 = dk4socket_i_change_owner_group_mode(
+ back, filename, owner, group, mode, change, erp
+ );
+ res = dk4socket_listen(back, backlog, erp);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ ogm2 = dk4socket_i_change_owner_group_mode(
+ back, filename, owner, group, mode, change, erp
+ );
+ if ((0 == ogm1) && (0 == ogm2)) {
+ (void)dk4socket_close(back, NULL);
+ back = INVALID_SOCKET;
+ md = 1;
+ }
+ } else {
+ (void)dk4socket_close(back, NULL);
+ back = INVALID_SOCKET;
+ md = 1;
+ }
+ } else {
+ (void)dk4socket_close(back, NULL);
+ back = INVALID_SOCKET;
+ }
+ if ((INVALID_SOCKET == back) && (0 != md)) {
+ (void)dk4delete_file_c8(filename, NULL);
+ }
+ }
+ } else {
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+dk4_socket_t
+dk4socket_c8_unix_listener(
+ const char *filename,
+ int backlog,
+ dk4_er_t *erp
+)
+{
+ return (
+ dk4socket_i_c8_unix_listener_ogm(filename, backlog, 0, 0, 0660, 0, erp)
+ );
+}
+
+
+
+dk4_socket_t
+dk4socket_c8_unix_listener_owner_group_mode(
+ const char *filename,
+ int backlog,
+ uid_t owner,
+ gid_t group,
+ mode_t mode,
+ dk4_er_t *erp
+)
+{
+ return (
+ dk4socket_i_c8_unix_listener_ogm(
+ filename, backlog, owner, group, mode, 1, erp
+ )
+ );
+}
+
+
+
+
+#endif
diff --git a/support/dktools/dk4sock14.c b/support/dktools/dk4sock14.c
new file mode 100644
index 0000000000..c8093c88b4
--- /dev/null
+++ b/support/dktools/dk4sock14.c
@@ -0,0 +1,179 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sock14.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4sock14.c The dk4sock14 module.
+*/
+
+
+#line 10 "dk4sock14.ctr"
+
+#include "dk4sock.h"
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4numco.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+
+
+#line 40 "dk4sock14.ctr"
+
+
+
+int
+dk4socket_option_set_reuse(
+ dk4_socket_t sock,
+ int val,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_SOCKET_RESULT_FAILED;
+ int opt = 0;
+ int res = 0;
+
+
+#line 54 "dk4sock14.ctr"
+ if (INVALID_SOCKET != sock) {
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEADDR)
+ if (0 != val) { dk4socket_set_one_bytes(&opt, sizeof(opt)); }
+ dk4socket_error_reset();
+ res = setsockopt(
+ sock, SOL_SOCKET, SO_REUSEADDR, (void *)(&opt), sizeof(opt)
+ );
+ if (0 == res) {
+
+#line 62 "dk4sock14.ctr"
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+
+#line 64 "dk4sock14.ctr"
+ dk4socket_error_report(erp, DK4_E_SOCKET_SETSOCKOPT);
+ }
+#else
+
+
+#line 68 "dk4sock14.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEPORT)
+ if (0 != val) { dk4socket_set_one_bytes(&opt, sizeof(opt)); }
+ else opt = 0;
+ dk4socket_error_reset();
+ res = setsockopt(
+ sock, SOL_SOCKET, SO_REUSEPORT, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) {
+
+#line 78 "dk4sock14.ctr"
+ back = DK4_SOCKET_RESULT_FAILED;
+ dk4socket_error_report(erp, DK4_E_SOCKET_SETSOCKOPT);
+ }
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 86 "dk4sock14.ctr"
+ return back;
+}
+
+
+int
+dk4socket_option_set_broadcast(
+ dk4_socket_t sock,
+ int val,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_SOCKET_RESULT_FAILED;
+ int opt = 0;
+ int res = 0;
+
+
+#line 101 "dk4sock14.ctr"
+ if (INVALID_SOCKET != sock) {
+#if DK4_HAVE_SETSOCKOPT && defined(SO_BROADCAST)
+ if (0 != val) { dk4socket_set_one_bytes(&opt, sizeof(opt)); }
+ dk4socket_error_reset();
+ res = setsockopt(
+ sock, SOL_SOCKET, SO_BROADCAST, (void *)(&opt), sizeof(opt)
+ );
+ if (0 == res) {
+
+#line 109 "dk4sock14.ctr"
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+
+#line 111 "dk4sock14.ctr"
+ dk4socket_error_report(erp, DK4_E_SOCKET_SETSOCKOPT);
+ }
+#else
+
+
+#line 115 "dk4sock14.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 121 "dk4sock14.ctr"
+ return back;
+}
+
+
diff --git a/support/dktools/dk4sock14.ctr b/support/dktools/dk4sock14.ctr
new file mode 100644
index 0000000000..b70cedda3f
--- /dev/null
+++ b/support/dktools/dk4sock14.ctr
@@ -0,0 +1,124 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4sock.h"
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4numco.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+$!trace-include
+
+
+
+int
+dk4socket_option_set_reuse(
+ dk4_socket_t sock,
+ int val,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_SOCKET_RESULT_FAILED;
+ int opt = 0;
+ int res = 0;
+ $? "+ dk4socket_option_set_reuse %d", val
+ if (INVALID_SOCKET != sock) {
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEADDR)
+ if (0 != val) { dk4socket_set_one_bytes(&opt, sizeof(opt)); }
+ dk4socket_error_reset();
+ res = setsockopt(
+ sock, SOL_SOCKET, SO_REUSEADDR, (void *)(&opt), sizeof(opt)
+ );
+ if (0 == res) { $? ". setsockopt (1) ok"
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else { $? "! setsockopt (1)"
+ dk4socket_error_report(erp, DK4_E_SOCKET_SETSOCKOPT);
+ }
+#else
+ $? "! not setsockopt or no SO_REUSEADDR"
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEPORT)
+ if (0 != val) { dk4socket_set_one_bytes(&opt, sizeof(opt)); }
+ else opt = 0;
+ dk4socket_error_reset();
+ res = setsockopt(
+ sock, SOL_SOCKET, SO_REUSEPORT, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) { $? "! setsockopt (2)"
+ back = DK4_SOCKET_RESULT_FAILED;
+ dk4socket_error_report(erp, DK4_E_SOCKET_SETSOCKOPT);
+ }
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4socket_option_set_reuse %d", back
+ return back;
+}
+
+
+int
+dk4socket_option_set_broadcast(
+ dk4_socket_t sock,
+ int val,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_SOCKET_RESULT_FAILED;
+ int opt = 0;
+ int res = 0;
+ $? "+ dk4socket_option_set_broadcast %d", val
+ if (INVALID_SOCKET != sock) {
+#if DK4_HAVE_SETSOCKOPT && defined(SO_BROADCAST)
+ if (0 != val) { dk4socket_set_one_bytes(&opt, sizeof(opt)); }
+ dk4socket_error_reset();
+ res = setsockopt(
+ sock, SOL_SOCKET, SO_BROADCAST, (void *)(&opt), sizeof(opt)
+ );
+ if (0 == res) { $? ". setsockopt ok"
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else { $? "! setsockopt"
+ dk4socket_error_report(erp, DK4_E_SOCKET_SETSOCKOPT);
+ }
+#else
+ $? "! not available"
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4socket_option_set_broadcast %d", back
+ return back;
+}
+
+
diff --git a/support/dktools/dk4sock15.c b/support/dktools/dk4sock15.c
new file mode 100644
index 0000000000..2a91ca32ac
--- /dev/null
+++ b/support/dktools/dk4sock15.c
@@ -0,0 +1,138 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sock15.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4sock15.c The dk4sock15 module.
+*/
+
+
+#line 10 "dk4sock15.ctr"
+
+#include "dk4sock.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+
+
+#line 44 "dk4sock15.ctr"
+
+
+
+int
+dk4socket_option_set_nonblock(
+ dk4_socket_t sock,
+ int val,
+ dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+ unsigned long xv = 0UL;
+ int back = DK4_SOCKET_RESULT_FAILED;
+ if (INVALID_SOCKET != sock) {
+ if (0 != val) { xv = 0x11111111UL; }
+ WSASetLastError(0);
+ if (0 == ioctlsocket(sock, FIONBIO, &xv)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_SOCKET_IOCTLSOCKET, WSAGetLastError());
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ int back = DK4_SOCKET_RESULT_FAILED;
+ int om;
+ if (INVALID_SOCKET != sock) {
+ om = fcntl(sock, F_GETFL);
+ if (0 != val) {
+ if (0 != (om & O_NONBLOCK)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ om |= O_NONBLOCK;
+ errno = 0;
+ if (-1 != fcntl(sock, F_SETFL, om)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_SOCKET_FCNTL, errno);
+ }
+ }
+ } else {
+ if (0 == (om & O_NONBLOCK)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ om &= (~(O_NONBLOCK));
+ errno = 0;
+ if (-1 != fcntl(sock, F_SETFL, om)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_SOCKET_FCNTL, errno);
+ }
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#endif
+}
+
diff --git a/support/dktools/dk4sock15.ctr b/support/dktools/dk4sock15.ctr
new file mode 100644
index 0000000000..9a5a81dece
--- /dev/null
+++ b/support/dktools/dk4sock15.ctr
@@ -0,0 +1,105 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4sock.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+$!trace-include
+
+
+
+int
+dk4socket_option_set_nonblock(
+ dk4_socket_t sock,
+ int val,
+ dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+ unsigned long xv = 0UL;
+ int back = DK4_SOCKET_RESULT_FAILED;
+ if (INVALID_SOCKET != sock) {
+ if (0 != val) { xv = 0x11111111UL; }
+ WSASetLastError(0);
+ if (0 == ioctlsocket(sock, FIONBIO, &xv)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_SOCKET_IOCTLSOCKET, WSAGetLastError());
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ int back = DK4_SOCKET_RESULT_FAILED;
+ int om;
+ if (INVALID_SOCKET != sock) {
+ om = fcntl(sock, F_GETFL);
+ if (0 != val) {
+ if (0 != (om & O_NONBLOCK)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ om |= O_NONBLOCK;
+ errno = 0;
+ if (-1 != fcntl(sock, F_SETFL, om)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_SOCKET_FCNTL, errno);
+ }
+ }
+ } else {
+ if (0 == (om & O_NONBLOCK)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ om &= (~(O_NONBLOCK));
+ errno = 0;
+ if (-1 != fcntl(sock, F_SETFL, om)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_SOCKET_FCNTL, errno);
+ }
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#endif
+}
+
diff --git a/support/dktools/dk4sock16.c b/support/dktools/dk4sock16.c
new file mode 100644
index 0000000000..256974cfd3
--- /dev/null
+++ b/support/dktools/dk4sock16.c
@@ -0,0 +1,380 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sock16.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4sock16.c The dk4sock16 module.
+*/
+
+
+#line 9 "dk4sock16.ctr"
+
+#include "dk4sock.h"
+
+#include <stdio.h>
+
+#if !DK4_ON_WINDOWS
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+
+
+#line 52 "dk4sock16.ctr"
+
+
+
+static
+dk4_socket_t
+dk4socket_tcp_client_cleanup_socket(
+ dk4_socket_t sock,
+ int level,
+ struct sockaddr *pAddr,
+ size_t szAddr
+)
+{
+#if 0
+ /* Setting SO_REUSEADDR or SO_REUSEPORT must follow socket()
+ immediately.
+ */
+ if ((0 < level) || ((NULL != pAddr) && (0 < szAddr))) {
+ (void)dk4socket_option_set_reuse(sock, 1, NULL);
+ }
+#endif
+
+#if DK4_ON_WINDOWS
+ closesocket(sock);
+#else
+ close(sock);
+#endif
+ return (INVALID_SOCKET);
+}
+
+
+
+static
+dk4_socket_t
+dk4socket_tcp_client_connect_attempt(
+ dk4_socket_t back,
+ struct sockaddr *pAddr,
+ size_t szAddr,
+ struct sockaddr *pLoAddr,
+ size_t szLoAddr,
+ long secs,
+ long usecs,
+ dk4_er_t *erp
+)
+{
+ fd_set wfds;
+ struct timeval to;
+#if (!DK4_ON_WINDOWS) && (DK4_HAVE_SETSOCKOPT) \
+ && defined(SOL_SOCKET) && defined(SO_ERROR)
+#if DK4_HAVE_SOCKLEN_T
+ socklen_t slo;
+#else
+ int slo;
+#endif
+ int err;
+#endif
+ int res;
+
+
+#line 109 "dk4sock16.ctr"
+
+
+#line 110 "dk4sock16.ctr"
+ res = dk4socket_connect(back, pAddr, szAddr, erp);
+ switch (res) {
+ case DK4_SOCKET_RESULT_SUCCESS : {
+
+#line 113 "dk4sock16.ctr"
+ /* do nothing */
+ } break;
+ case DK4_SOCKET_RESULT_IN_PROGRESS : {
+
+#line 116 "dk4sock16.ctr"
+ FD_ZERO(&wfds);
+ FD_SET(back, &wfds);
+ to.tv_sec = secs;
+ to.tv_usec = usecs;
+ dk4socket_error_reset();
+ res = select((((int)back) + 1), NULL, &wfds, NULL, &to);
+ if (0 < res) {
+
+#line 123 "dk4sock16.ctr"
+ if (FD_ISSET(back, &wfds)) {
+
+#line 124 "dk4sock16.ctr"
+#if (!DK4_ON_WINDOWS) && (DK4_HAVE_SETSOCKOPT) \
+ && defined(SOL_SOCKET) && defined(SO_ERROR)
+ err = 0;
+ slo = sizeof(err);
+ dk4socket_error_reset();
+ res = getsockopt(back, SOL_SOCKET, SO_ERROR, &err, &slo);
+ if (0 == res) {
+
+#line 131 "dk4sock16.ctr"
+ if (0 != dk4socket_non_null_getsockopt(err, slo)) {
+
+
+#line 133 "dk4sock16.ctr"
+ dk4error_set_idetails(erp, DK4_E_SOCKET_CONNECT, err);
+ back = dk4socket_tcp_client_cleanup_socket(
+ back, 1, pLoAddr, szLoAddr
+ );
+ }
+#if VERSION_BEFORE_20160415
+ if (sizeof(int) != slo) {
+ if (0 != err) {
+
+#line 141 "dk4sock16.ctr"
+ dk4error_set_idetails(erp, DK4_E_SOCKET_CONNECT, err);
+ back = dk4socket_tcp_client_cleanup_socket(
+ back, 1, pLoAddr, szLoAddr
+ );
+ }
+ } else {
+
+#line 147 "dk4sock16.ctr"
+ dk4socket_error_report(erp, DK4_E_SOCKET_GETSOCKOPT);
+ back = dk4socket_tcp_client_cleanup_socket(
+ back, 1, pLoAddr, szLoAddr
+ );
+ }
+#endif
+ } else {
+
+#line 154 "dk4sock16.ctr"
+ dk4socket_error_report(erp, DK4_E_SOCKET_GETSOCKOPT);
+ back = dk4socket_tcp_client_cleanup_socket(back,1,pLoAddr,szLoAddr);
+ }
+#endif
+ } else {
+
+#line 159 "dk4sock16.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_SOCKET_TIMEOUT);
+ back = dk4socket_tcp_client_cleanup_socket(back,0,pLoAddr,szLoAddr);
+ }
+ } else {
+ if (0 > res) {
+
+#line 164 "dk4sock16.ctr"
+ dk4socket_error_report(erp, DK4_E_SOCKET_SELECT);
+ } else {
+
+#line 166 "dk4sock16.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_SOCKET_TIMEOUT);
+ }
+ back = dk4socket_tcp_client_cleanup_socket(back,0,pLoAddr,szLoAddr);
+ }
+ } break;
+ default : {
+
+#line 172 "dk4sock16.ctr"
+ back = dk4socket_tcp_client_cleanup_socket(back, 0, pLoAddr, szLoAddr);
+ } break;
+ }
+
+
+#line 176 "dk4sock16.ctr"
+ return back;
+}
+
+
+
+dk4_socket_t
+dk4socket_tcp_client_for_addr(
+ int protfam,
+ struct sockaddr *pRemoteAddr,
+ size_t szRemoteAddr,
+ struct sockaddr *pLocalAddr,
+ size_t szLocalAddr,
+ long seconds,
+ long microSeconds,
+ dk4_er_t *erp
+)
+{
+ dk4_socket_t back = INVALID_SOCKET;
+ int res;
+#if DK4_HAVE_SETSOCKOPT && (defined(SO_REUSEPORT) || defined(SO_REUSEADDR))
+ int opt = 0;
+#endif
+
+
+#line 199 "dk4sock16.ctr"
+ if ((NULL != pRemoteAddr) && (0 < szRemoteAddr)) {
+
+#line 200 "dk4sock16.ctr"
+
+
+#line 201 "dk4sock16.ctr"
+ back = dk4socket_open(protfam, SOCK_STREAM, 0, erp);
+ if (INVALID_SOCKET != back) {
+
+#line 203 "dk4sock16.ctr"
+ if ((NULL != pLocalAddr) && (0 < szLocalAddr)) {
+
+#line 204 "dk4sock16.ctr"
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEPORT)
+
+
+#line 206 "dk4sock16.ctr"
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ back, SOL_SOCKET,
+ SO_REUSEPORT, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) {
+
+#line 212 "dk4sock16.ctr"
+ }
+#else
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEADDR)
+
+
+#line 216 "dk4sock16.ctr"
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ back, SOL_SOCKET,
+ SO_REUSEADDR, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) {
+
+#line 222 "dk4sock16.ctr"
+ }
+#else
+
+
+#line 225 "dk4sock16.ctr"
+#endif
+#endif
+ res = dk4socket_bind(back, pLocalAddr, szLocalAddr, erp);
+ if (DK4_SOCKET_RESULT_FAILED == res) {
+
+#line 229 "dk4sock16.ctr"
+ back = dk4socket_tcp_client_cleanup_socket(
+ back, 0, pLocalAddr, szLocalAddr
+ );
+ }
+ }
+ if (INVALID_SOCKET != back) {
+ if ((0L != seconds) || (0L != microSeconds)) {
+
+#line 236 "dk4sock16.ctr"
+ res = dk4socket_option_set_nonblock(back, 1, erp);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+
+#line 238 "dk4sock16.ctr"
+ back = dk4socket_tcp_client_connect_attempt(
+ back, pRemoteAddr, szRemoteAddr, pLocalAddr, szLocalAddr,
+ seconds, microSeconds, erp
+ );
+ if (INVALID_SOCKET != back) {
+ res = dk4socket_option_set_nonblock(back, 0, erp);
+ if (DK4_SOCKET_RESULT_SUCCESS != res) {
+
+#line 245 "dk4sock16.ctr"
+ back = dk4socket_tcp_client_cleanup_socket(
+ back, 1, pLocalAddr, szLocalAddr
+ );
+ }
+ }
+ } else {
+
+#line 251 "dk4sock16.ctr"
+ back = dk4socket_tcp_client_cleanup_socket(
+ back, 0, pLocalAddr, szLocalAddr
+ );
+ }
+ } else {
+
+#line 256 "dk4sock16.ctr"
+ back = dk4socket_tcp_client_connect_attempt(
+ back, pRemoteAddr, szRemoteAddr, pLocalAddr, szLocalAddr,
+ 0L, 0L, erp
+ );
+ }
+ }
+ } else {
+
+#line 263 "dk4sock16.ctr"
+
+
+#line 264 "dk4sock16.ctr"
+ }
+ } else {
+
+#line 266 "dk4sock16.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 269 "dk4sock16.ctr"
+ return back;
+}
+
+
+
+
diff --git a/support/dktools/dk4sock16.ctr b/support/dktools/dk4sock16.ctr
new file mode 100644
index 0000000000..ebac56871b
--- /dev/null
+++ b/support/dktools/dk4sock16.ctr
@@ -0,0 +1,274 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% module
+
+#include "dk4sock.h"
+
+#include <stdio.h>
+
+#if !DK4_ON_WINDOWS
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+$!trace-include
+
+
+
+static
+dk4_socket_t
+dk4socket_tcp_client_cleanup_socket(
+ dk4_socket_t sock,
+ int level,
+ struct sockaddr *pAddr,
+ size_t szAddr
+)
+{
+#if 0
+ /* Setting SO_REUSEADDR or SO_REUSEPORT must follow socket()
+ immediately.
+ */
+ if ((0 < level) || ((NULL != pAddr) && (0 < szAddr))) {
+ (void)dk4socket_option_set_reuse(sock, 1, NULL);
+ }
+#endif
+
+#if DK4_ON_WINDOWS
+ closesocket(sock);
+#else
+ close(sock);
+#endif
+ return (INVALID_SOCKET);
+}
+
+
+
+static
+dk4_socket_t
+dk4socket_tcp_client_connect_attempt(
+ dk4_socket_t back,
+ struct sockaddr *pAddr,
+ size_t szAddr,
+ struct sockaddr *pLoAddr,
+ size_t szLoAddr,
+ long secs,
+ long usecs,
+ dk4_er_t *erp
+)
+{
+ fd_set wfds;
+ struct timeval to;
+#if (!DK4_ON_WINDOWS) && (DK4_HAVE_SETSOCKOPT) \
+ && defined(SOL_SOCKET) && defined(SO_ERROR)
+#if DK4_HAVE_SOCKLEN_T
+ socklen_t slo;
+#else
+ int slo;
+#endif
+ int err;
+#endif
+ int res;
+ $? "+ dk4socket_tcp_client_connect_attempt"
+ $? ". remote = PTR=%d %lu", TR_IPTR(pAddr), (unsigned long)szAddr
+ res = dk4socket_connect(back, pAddr, szAddr, erp);
+ switch (res) {
+ case DK4_SOCKET_RESULT_SUCCESS : { $? ". connected"
+ /* do nothing */
+ } break;
+ case DK4_SOCKET_RESULT_IN_PROGRESS : { $? ". in progress"
+ FD_ZERO(&wfds);
+ FD_SET(back, &wfds);
+ to.tv_sec = secs;
+ to.tv_usec = usecs;
+ dk4socket_error_reset();
+ res = select((((int)back) + 1), NULL, &wfds, NULL, &to);
+ if (0 < res) { $? ". select"
+ if (FD_ISSET(back, &wfds)) { $? ". in write set"
+#if (!DK4_ON_WINDOWS) && (DK4_HAVE_SETSOCKOPT) \
+ && defined(SOL_SOCKET) && defined(SO_ERROR)
+ err = 0;
+ slo = sizeof(err);
+ dk4socket_error_reset();
+ res = getsockopt(back, SOL_SOCKET, SO_ERROR, &err, &slo);
+ if (0 == res) { $? ". getsockopt ok"
+ if (0 != dk4socket_non_null_getsockopt(err, slo)) {
+ $? "! non-null from getsockopt"
+ dk4error_set_idetails(erp, DK4_E_SOCKET_CONNECT, err);
+ back = dk4socket_tcp_client_cleanup_socket(
+ back, 1, pLoAddr, szLoAddr
+ );
+ }
+#if VERSION_BEFORE_20160415
+ if (sizeof(int) != slo) {
+ if (0 != err) { $? "! error from getsockopt"
+ dk4error_set_idetails(erp, DK4_E_SOCKET_CONNECT, err);
+ back = dk4socket_tcp_client_cleanup_socket(
+ back, 1, pLoAddr, szLoAddr
+ );
+ }
+ } else { $? "! getsockopt (size)"
+ dk4socket_error_report(erp, DK4_E_SOCKET_GETSOCKOPT);
+ back = dk4socket_tcp_client_cleanup_socket(
+ back, 1, pLoAddr, szLoAddr
+ );
+ }
+#endif
+ } else { $? "! getsockopt"
+ dk4socket_error_report(erp, DK4_E_SOCKET_GETSOCKOPT);
+ back = dk4socket_tcp_client_cleanup_socket(back,1,pLoAddr,szLoAddr);
+ }
+#endif
+ } else { $? "! timeout (not in list)"
+ dk4error_set_simple_error_code(erp, DK4_E_SOCKET_TIMEOUT);
+ back = dk4socket_tcp_client_cleanup_socket(back,0,pLoAddr,szLoAddr);
+ }
+ } else {
+ if (0 > res) { $? "! select"
+ dk4socket_error_report(erp, DK4_E_SOCKET_SELECT);
+ } else { $? "! timeout (from select)"
+ dk4error_set_simple_error_code(erp, DK4_E_SOCKET_TIMEOUT);
+ }
+ back = dk4socket_tcp_client_cleanup_socket(back,0,pLoAddr,szLoAddr);
+ }
+ } break;
+ default : { $? "! failed"
+ back = dk4socket_tcp_client_cleanup_socket(back, 0, pLoAddr, szLoAddr);
+ } break;
+ }
+ $? "- dk4socket_tcp_client_connect_attempt %d", (int)back
+ return back;
+}
+
+
+
+dk4_socket_t
+dk4socket_tcp_client_for_addr(
+ int protfam,
+ struct sockaddr *pRemoteAddr,
+ size_t szRemoteAddr,
+ struct sockaddr *pLocalAddr,
+ size_t szLocalAddr,
+ long seconds,
+ long microSeconds,
+ dk4_er_t *erp
+)
+{
+ dk4_socket_t back = INVALID_SOCKET;
+ int res;
+#if DK4_HAVE_SETSOCKOPT && (defined(SO_REUSEPORT) || defined(SO_REUSEADDR))
+ int opt = 0;
+#endif
+ $? "+ dk4socket_tcp_client_for_addr"
+ if ((NULL != pRemoteAddr) && (0 < szRemoteAddr)) { $? ". args ok"
+ $? ". remote = PTR=%d %lu",TR_IPTR(pRemoteAddr),(unsigned long)szRemoteAddr
+ back = dk4socket_open(protfam, SOCK_STREAM, 0, erp);
+ if (INVALID_SOCKET != back) { $? ". socket"
+ if ((NULL != pLocalAddr) && (0 < szLocalAddr)) { $? ". must bind"
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEPORT)
+ $? ". SO_REUSEPORT"
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ back, SOL_SOCKET,
+ SO_REUSEPORT, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) { $? "! failed to reuse port number"
+ }
+#else
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEADDR)
+ $? ". SO_REUSEADDR"
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ back, SOL_SOCKET,
+ SO_REUSEADDR, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) { $? "! failed to reuse address"
+ }
+#else
+ $? ". neither SO_REUSEPORT nor SO_REUSEADDR"
+#endif
+#endif
+ res = dk4socket_bind(back, pLocalAddr, szLocalAddr, erp);
+ if (DK4_SOCKET_RESULT_FAILED == res) { $? "! bind"
+ back = dk4socket_tcp_client_cleanup_socket(
+ back, 0, pLocalAddr, szLocalAddr
+ );
+ }
+ }
+ if (INVALID_SOCKET != back) {
+ if ((0L != seconds) || (0L != microSeconds)) { $? ". use timeout"
+ res = dk4socket_option_set_nonblock(back, 1, erp);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) { $? ". non-blocking"
+ back = dk4socket_tcp_client_connect_attempt(
+ back, pRemoteAddr, szRemoteAddr, pLocalAddr, szLocalAddr,
+ seconds, microSeconds, erp
+ );
+ if (INVALID_SOCKET != back) {
+ res = dk4socket_option_set_nonblock(back, 0, erp);
+ if (DK4_SOCKET_RESULT_SUCCESS != res) { $? "! back blocking"
+ back = dk4socket_tcp_client_cleanup_socket(
+ back, 1, pLocalAddr, szLocalAddr
+ );
+ }
+ }
+ } else { $? "! non-blocking"
+ back = dk4socket_tcp_client_cleanup_socket(
+ back, 0, pLocalAddr, szLocalAddr
+ );
+ }
+ } else { $? ". no timeout"
+ back = dk4socket_tcp_client_connect_attempt(
+ back, pRemoteAddr, szRemoteAddr, pLocalAddr, szLocalAddr,
+ 0L, 0L, erp
+ );
+ }
+ }
+ } else { $? "! socket"
+ $? "! errno=%d", errno
+ }
+ } else { $? "! args"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4socket_tcp_client_for_addr %d", (int)back
+ return back;
+}
+
+
+
+
diff --git a/support/dktools/dk4sock17.c b/support/dktools/dk4sock17.c
new file mode 100644
index 0000000000..49ed4e0be5
--- /dev/null
+++ b/support/dktools/dk4sock17.c
@@ -0,0 +1,505 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sock17.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4sock17.c The dk4sock17 module.
+*/
+
+
+#line 10 "dk4sock17.ctr"
+
+#include "dk4sock.h"
+#include "dk4mem.h"
+#include "dk4mao8d.h"
+
+#if !DK4_HAVE_GETADDRINFO
+#include "dk4mai8dus.h"
+#endif
+
+
+
+
+#line 21 "dk4sock17.ctr"
+
+
+
+#if DK4_HAVE_GETADDRINFO
+/* +++++ +getaddrinfo +++++ */
+
+/** Create client socket for given address lists.
+ @param hostname Remote host name to connect to.
+ @param raddrst List of remote addresses.
+ @param laddrst List of local addresses to use, optional.
+ @param secs Seconds for timeout.
+ @param usecs Microseconds for timeout.
+ @param erp Error report, may be NULL.
+ @return Valid socket on success, INVALID_SOCKET on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if any argument is bad,
+ - DK4_E_SOCKET_SOCKET<br>
+ if the socket() function failed to create a new socket,
+ - DK4_E_SOCKET_BIND<br>
+ if the bind() function failed to bind the requested local address,
+ - DK4_E_SOCKET_FCNTL<br>
+ if the fcntl() function failed,
+ - DK4_E_SOCKET_IOCTLSOCKET
+ if the ioctlsocket() function failed.
+ - DK4_E_SOCKET_CONNECT<br>
+ if the connect() function failed,
+ - DK4_E_SOCKET_TIMEOUT<br>
+ if a timeout occured in the connect attempt,
+ - DK4_E_SOCKET_SELECT<br>
+ if the select() function failed,
+ - DK4_E_SOCKET_GETSOCKOPT<br>
+ if the getsockopt() function failed.
+ For all error codes - except DK4_E_SOCKET_TIMEOUT - the iDetails1
+ field contains the errno or WSAGetLastError() value.
+*/
+static
+dk4_socket_t
+dk4socket_c8_tcp_client_addresses(
+ const char *hostname,
+ struct addrinfo *raddrst,
+ struct addrinfo *laddrst,
+ long secs,
+ long usecs,
+ dk4_er_t *erp
+)
+{
+ struct addrinfo *ra;
+ struct addrinfo *la;
+ dk4_socket_t back = INVALID_SOCKET;
+
+
+#line 73 "dk4sock17.ctr"
+ ra = raddrst;
+ while ((INVALID_SOCKET == back) && (NULL != ra)) {
+ if (NULL != laddrst) {
+ la = laddrst;
+ while ((INVALID_SOCKET == back) && (NULL != la)) {
+ if (la->ai_family == ra->ai_family) {
+
+
+#line 80 "dk4sock17.ctr"
+
+
+#line 81 "dk4sock17.ctr"
+
+
+#line 82 "dk4sock17.ctr"
+
+
+#line 83 "dk4sock17.ctr"
+ back = dk4socket_tcp_client_for_addr(
+ ra->ai_family, ra->ai_addr, ra->ai_addrlen,
+ la->ai_addr, la->ai_addrlen, secs, usecs, erp
+ );
+ if (INVALID_SOCKET != back) {
+ la = NULL; ra = NULL;
+ }
+ }
+ if (NULL != la) { la = la->ai_next; }
+ }
+ } else {
+ back = dk4socket_tcp_client_for_addr(
+ ra->ai_family, ra->ai_addr, ra->ai_addrlen, NULL, 0,
+ secs, usecs, erp
+ );
+ if (INVALID_SOCKET != back) {
+ ra = NULL;
+ }
+ }
+ if (NULL != ra) { ra = ra->ai_next; }
+ }
+
+
+#line 105 "dk4sock17.ctr"
+ return back;
+}
+
+/* ----- +getaddrinfo ----- */
+#else
+/* +++++ -getaddrinfo +++++ */
+
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+/** used to initialize IPv6 address for binding local ports.
+*/
+static const IN6_ADDR dk4socket_any6 = IN6ADDR_ANY_INIT;
+#endif
+
+/* ----- -getaddrinfo ----- */
+#endif
+
+
+
+dk4_socket_t
+dk4socket_c8_tcp_client_host_num_srv(
+ const char *hostname,
+ const char *svcname,
+ const char *lsvcname,
+ long secs,
+ long usecs,
+ int nsrv,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_GETADDRINFO
+ /* +++++ +getaddrinfo */
+ struct addrinfo rhints; /* Hints for remote address */
+ struct addrinfo lhints; /* Hints for local address */
+ struct addrinfo *raddrst = NULL; /* Storage for remote addresses */
+ struct addrinfo *laddrst = NULL; /* Storage for local addresses */
+ int res; /* Operation result */
+ dk4_socket_t back = INVALID_SOCKET;
+
+
+#line 143 "dk4sock17.ctr"
+ if ((NULL != hostname) && (NULL != svcname)) {
+
+#line 144 "dk4sock17.ctr"
+
+
+#line 145 "dk4sock17.ctr"
+ DK4_MEMRES(&rhints, sizeof(rhints));
+ rhints.ai_family = AF_UNSPEC;
+ rhints.ai_socktype = SOCK_STREAM;
+ if (0 != nsrv) { rhints.ai_flags = AI_NUMERICSERV; }
+ rhints.ai_protocol = 0;
+ res = getaddrinfo(hostname, svcname, &rhints, &raddrst);
+ if ((0 == res) && (NULL != raddrst)) {
+ if (NULL != lsvcname) {
+ DK4_MEMRES(&lhints, sizeof(lhints));
+ lhints.ai_family = AF_UNSPEC;
+ lhints.ai_socktype = SOCK_STREAM;
+ lhints.ai_flags = AI_PASSIVE;
+ if (0 != nsrv) { lhints.ai_flags |= AI_NUMERICSERV; }
+ lhints.ai_protocol = 0;
+ res = getaddrinfo(NULL, lsvcname, &lhints, &laddrst);
+ if ((0 == res) && (NULL != laddrst)) {
+ back = dk4socket_c8_tcp_client_addresses(
+ hostname, raddrst, laddrst, secs, usecs, erp
+ );
+ if (NULL != laddrst) { freeaddrinfo(laddrst); }
+ } else {
+
+#line 166 "dk4sock17.ctr"
+ /* ERROR: getaddrinfo failed */
+ dk4error_set_idetails(erp, DK4_E_SOCKET_GETADDRLOC, res);
+ }
+ } else {
+ back = dk4socket_c8_tcp_client_addresses(
+ hostname, raddrst, NULL, secs, usecs, erp
+ );
+ }
+ if (NULL != raddrst) { freeaddrinfo(raddrst); }
+ } else {
+
+#line 176 "dk4sock17.ctr"
+ /* ERROR: getaddrinfo failed */
+ dk4error_set_idetails(erp, DK4_E_SOCKET_GETADDRINFO, res);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 183 "dk4sock17.ctr"
+ return back;
+ /* ----- +getaddrinfo */
+#else
+ /* +++++ -getaddrinfo */
+ struct servent *serv = NULL; /* Service entry */
+ const char *endptr = NULL; /* End of used text */
+ int iport = 0; /* Port number from servent */
+ unsigned short rport = 0; /* Remote port number */
+ unsigned short lport = 0; /* Local port number */
+ int res; /* Operation result */
+ dk4_socket_t back = INVALID_SOCKET;
+
+
+#line 195 "dk4sock17.ctr"
+ if ((NULL != hostname) && (NULL != svcname)) {
+
+#line 196 "dk4sock17.ctr"
+ res = dk4ma_input_c8_dec_ushort(&rport, svcname, &endptr, 1, NULL);
+ if (0 == res) {
+ dk4socket_error_reset();
+ serv = getservbyname(svcname, NULL);
+ if (NULL != serv) {
+ iport = serv->s_port;
+ dk4socket_swap_bytes_if_not_bigendian((void *)(&iport), sizeof(iport));
+ rport = (unsigned short)iport;
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_GETSERVBYNAME);
+ }
+ }
+ if (0 != rport) {
+ if (NULL != lsvcname) {
+ endptr = NULL;
+ res = dk4ma_input_c8_dec_ushort(&lport, lsvcname, &endptr, 1, NULL);
+ if (0 == res) {
+ dk4socket_error_reset();
+ serv = getservbyname(lsvcname, NULL);
+ if (NULL != serv) {
+ iport = serv->s_port;
+ dk4socket_swap_bytes_if_not_bigendian(
+ (void *)(&iport), sizeof(iport)
+ );
+ lport = (unsigned short)iport;
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_GETSERVBYNAME);
+ }
+ }
+ if (0 != lport) {
+ back = dk4socket_c8_tcp_client_host_port(
+ hostname, rport, lport, secs, usecs, erp
+ );
+ }
+ } else {
+ back = dk4socket_c8_tcp_client_host_port(
+ hostname, rport, (unsigned short)0, secs, usecs, erp
+ );
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 240 "dk4sock17.ctr"
+ return back;
+ /* ----- -getaddrinfo */
+#endif
+}
+
+
+
+dk4_socket_t
+dk4socket_c8_tcp_client_host_srv(
+ const char *hostname,
+ const char *svcname,
+ const char *lsvcname,
+ long secs,
+ long usecs,
+ dk4_er_t *erp
+)
+{
+ return (
+ dk4socket_c8_tcp_client_host_num_srv(
+ hostname, svcname, lsvcname, secs, usecs, 0, erp
+ )
+ );
+}
+
+
+
+dk4_socket_t
+dk4socket_c8_tcp_client_host_port(
+ const char *hostname,
+ unsigned short portno,
+ unsigned short lportno,
+ long secs,
+ long usecs,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_GETADDRINFO
+ /* +++++ +getaddrinfo */
+ char rpnb[16*sizeof(dk4_um_t)]; /* Remote port no */
+ char lpnb[16*sizeof(dk4_um_t)]; /* Local port no */
+ int res;
+ dk4_socket_t back = INVALID_SOCKET;
+
+
+#line 283 "dk4sock17.ctr"
+ if ((NULL != hostname) && (0 < portno)) {
+ res = dk4ma_write_c8_decimal_unsigned(
+ rpnb, sizeof(rpnb), (dk4_um_t)portno, 0, erp
+ );
+ if (0 != res) {
+ if (0 < lportno) {
+ res = dk4ma_write_c8_decimal_unsigned(
+ lpnb, sizeof(lpnb), (dk4_um_t)lportno, 0, erp
+ );
+ if (0 != res) {
+ back = dk4socket_c8_tcp_client_host_num_srv(
+ hostname, rpnb, lpnb, secs, usecs, 1, erp
+ );
+ } else {
+
+#line 297 "dk4sock17.ctr"
+ }
+ } else {
+ back = dk4socket_c8_tcp_client_host_num_srv(
+ hostname, rpnb, NULL, secs, usecs, 1, erp
+ );
+ }
+ } else {
+
+#line 304 "dk4sock17.ctr"
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- -getaddrinfo */
+ /* ----- +getaddrinfo */
+#else
+ /* +++++ -getaddrinfo */
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ struct sockaddr_in6 sr6;
+ struct sockaddr_in6 sl6;
+#endif
+ struct sockaddr_in sr4;
+ struct sockaddr_in sl4;
+ char **addrptr;
+ struct hostent * hep = NULL;
+ dk4_socket_t back = INVALID_SOCKET;
+
+
+#line 323 "dk4sock17.ctr"
+ if ((NULL != hostname) && (0 < portno)) {
+ hep = gethostbyname(hostname);
+ if (NULL != hep) {
+
+#line 326 "dk4sock17.ctr"
+ if (NULL != hep->h_addr_list) {
+
+#line 327 "dk4sock17.ctr"
+ switch (hep->h_addrtype) {
+ case AF_INET : {
+
+#line 329 "dk4sock17.ctr"
+ if (4 == hep->h_length) {
+
+#line 330 "dk4sock17.ctr"
+ addrptr = hep->h_addr_list;
+ while ((INVALID_SOCKET == back) && (NULL != *addrptr)) {
+ DK4_MEMRES(&sr4, sizeof(sr4));
+ sr4.sin_family = AF_INET;
+ sr4.sin_port = dk4socket_htons(portno);
+ DK4_MEMCPY(&(sr4.sin_addr), *addrptr, sizeof(IN_ADDR));
+
+
+#line 337 "dk4sock17.ctr"
+ if (0 != lportno) {
+ DK4_MEMRES(&sl4, sizeof(sl4));
+ sl4.sin_family = AF_INET;
+ sl4.sin_port = dk4socket_htons(lportno);
+ sl4.sin_addr.s_addr = dk4socket_htonl(INADDR_ANY);
+
+
+#line 343 "dk4sock17.ctr"
+ back = dk4socket_tcp_client_for_addr(
+ AF_INET, (struct sockaddr *)(&sr4), sizeof(sr4),
+ (struct sockaddr *)(&sl4), sizeof(sl4),
+ secs, usecs, erp
+ );
+ } else {
+ back = dk4socket_tcp_client_for_addr(
+ AF_INET, (struct sockaddr *)(&sr4), sizeof(sr4),
+ NULL, 0, secs, usecs, erp
+ );
+ }
+ addrptr++;
+ }
+ } else {
+
+#line 357 "dk4sock17.ctr"
+ /* ERROR: Address length mismatch */
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+
+#line 363 "dk4sock17.ctr"
+ if (16 == hep->h_length) {
+ addrptr = hep->h_addr_list;
+ while ((INVALID_SOCKET == back) && (NULL != *addrptr)) {
+ DK4_MEMRES(&sr6, sizeof(sr6));
+ sr6.sin6_family = AF_INET6;
+ sr6.sin6_port = dk4socket_htons(portno);
+ DK4_MEMCPY(&(sr6.sin6_addr), *addrptr, sizeof(IN6_ADDR));
+ if (0 != lportno) {
+ DK4_MEMRES(&sl6, sizeof(sl6));
+ sl6.sin6_family = AF_INET6;
+ sl6.sin6_port = dk4socket_htons(lportno);
+ DK4_MEMCPY(&(sl6.sin6_addr), &dk4socket_any6, sizeof(IN6_ADDR));
+ back = dk4socket_tcp_client_for_addr(
+ AF_INET6, (struct sockaddr *)(&sr6), sizeof(sr6),
+ (struct sockaddr *)(&sl6), sizeof(sl6),
+ secs, usecs, erp
+ );
+ } else {
+ back = dk4socket_tcp_client_for_addr(
+ AF_INET6, (struct sockaddr *)(&sr6), sizeof(sr6),
+ NULL, 0, secs, usecs, erp
+ );
+ }
+ addrptr++;
+ }
+ } else {
+ /* ERROR: Address length mismatch */
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ } break;
+#endif
+ default : {
+ /* ERROR: Unknown protocol */
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ } break;
+ }
+ } else {
+
+#line 400 "dk4sock17.ctr"
+ /* ERROR: Host not found (empty list) */
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ } else {
+
+#line 404 "dk4sock17.ctr"
+ /* ERROR: Host not found */
+ dk4socket_error_report(erp, DK4_E_SOCKET_GETHOSTBYNAME);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- -getaddrinfo */
+#endif
+}
+
diff --git a/support/dktools/dk4sock17.ctr b/support/dktools/dk4sock17.ctr
new file mode 100644
index 0000000000..0b32c77f74
--- /dev/null
+++ b/support/dktools/dk4sock17.ctr
@@ -0,0 +1,414 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4sock.h"
+#include "dk4mem.h"
+#include "dk4mao8d.h"
+
+#if !DK4_HAVE_GETADDRINFO
+#include "dk4mai8dus.h"
+#endif
+
+
+$!trace-include
+
+
+
+#if DK4_HAVE_GETADDRINFO
+/* +++++ +getaddrinfo +++++ */
+
+/** Create client socket for given address lists.
+ @param hostname Remote host name to connect to.
+ @param raddrst List of remote addresses.
+ @param laddrst List of local addresses to use, optional.
+ @param secs Seconds for timeout.
+ @param usecs Microseconds for timeout.
+ @param erp Error report, may be NULL.
+ @return Valid socket on success, INVALID_SOCKET on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if any argument is bad,
+ - DK4_E_SOCKET_SOCKET<br>
+ if the socket() function failed to create a new socket,
+ - DK4_E_SOCKET_BIND<br>
+ if the bind() function failed to bind the requested local address,
+ - DK4_E_SOCKET_FCNTL<br>
+ if the fcntl() function failed,
+ - DK4_E_SOCKET_IOCTLSOCKET
+ if the ioctlsocket() function failed.
+ - DK4_E_SOCKET_CONNECT<br>
+ if the connect() function failed,
+ - DK4_E_SOCKET_TIMEOUT<br>
+ if a timeout occured in the connect attempt,
+ - DK4_E_SOCKET_SELECT<br>
+ if the select() function failed,
+ - DK4_E_SOCKET_GETSOCKOPT<br>
+ if the getsockopt() function failed.
+ For all error codes - except DK4_E_SOCKET_TIMEOUT - the iDetails1
+ field contains the errno or WSAGetLastError() value.
+*/
+static
+dk4_socket_t
+dk4socket_c8_tcp_client_addresses(
+ const char *hostname,
+ struct addrinfo *raddrst,
+ struct addrinfo *laddrst,
+ long secs,
+ long usecs,
+ dk4_er_t *erp
+)
+{
+ struct addrinfo *ra;
+ struct addrinfo *la;
+ dk4_socket_t back = INVALID_SOCKET;
+ $? "+ dk4socket_c8_tcp_client_addresses"
+ ra = raddrst;
+ while ((INVALID_SOCKET == back) && (NULL != ra)) {
+ if (NULL != laddrst) {
+ la = laddrst;
+ while ((INVALID_SOCKET == back) && (NULL != la)) {
+ if (la->ai_family == ra->ai_family) {
+$? ". remote = %d PTR=%d %lu", (int)(ra->ai_family), TR_IPTR(ra->ai_addr), (unsigned long)(ra->ai_addrlen)
+$? ". local = %d PTR=%d %lu", (int)(la->ai_family), TR_IPTR(la->ai_addr), (unsigned long)(la->ai_addrlen)
+$!trace-code dk4socket_debug_address("remote", ra->ai_addr, ra->ai_addrlen);
+$!trace-code dk4socket_debug_address("local ", la->ai_addr, la->ai_addrlen);
+ back = dk4socket_tcp_client_for_addr(
+ ra->ai_family, ra->ai_addr, ra->ai_addrlen,
+ la->ai_addr, la->ai_addrlen, secs, usecs, erp
+ );
+ if (INVALID_SOCKET != back) {
+ la = NULL; ra = NULL;
+ }
+ }
+ if (NULL != la) { la = la->ai_next; }
+ }
+ } else {
+ back = dk4socket_tcp_client_for_addr(
+ ra->ai_family, ra->ai_addr, ra->ai_addrlen, NULL, 0,
+ secs, usecs, erp
+ );
+ if (INVALID_SOCKET != back) {
+ ra = NULL;
+ }
+ }
+ if (NULL != ra) { ra = ra->ai_next; }
+ }
+ $? "- dk4socket_c8_tcp_client_addresses %d", (int)back
+ return back;
+}
+
+/* ----- +getaddrinfo ----- */
+#else
+/* +++++ -getaddrinfo +++++ */
+
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+/** used to initialize IPv6 address for binding local ports.
+*/
+static const IN6_ADDR dk4socket_any6 = IN6ADDR_ANY_INIT;
+#endif
+
+/* ----- -getaddrinfo ----- */
+#endif
+
+
+
+dk4_socket_t
+dk4socket_c8_tcp_client_host_num_srv(
+ const char *hostname,
+ const char *svcname,
+ const char *lsvcname,
+ long secs,
+ long usecs,
+ int nsrv,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_GETADDRINFO
+ /* +++++ +getaddrinfo */
+ struct addrinfo rhints; /* Hints for remote address */
+ struct addrinfo lhints; /* Hints for local address */
+ struct addrinfo *raddrst = NULL; /* Storage for remote addresses */
+ struct addrinfo *laddrst = NULL; /* Storage for local addresses */
+ int res; /* Operation result */
+ dk4_socket_t back = INVALID_SOCKET;
+ $? "+ dk4socket_c8_tcp_client_host_num_srv (+getaddrinfo)"
+ if ((NULL != hostname) && (NULL != svcname)) { $? ". args ok"
+ $? ". have getaddrinfo"
+ DK4_MEMRES(&rhints, sizeof(rhints));
+ rhints.ai_family = AF_UNSPEC;
+ rhints.ai_socktype = SOCK_STREAM;
+ if (0 != nsrv) { rhints.ai_flags = AI_NUMERICSERV; }
+ rhints.ai_protocol = 0;
+ res = getaddrinfo(hostname, svcname, &rhints, &raddrst);
+ if ((0 == res) && (NULL != raddrst)) {
+ if (NULL != lsvcname) {
+ DK4_MEMRES(&lhints, sizeof(lhints));
+ lhints.ai_family = AF_UNSPEC;
+ lhints.ai_socktype = SOCK_STREAM;
+ lhints.ai_flags = AI_PASSIVE;
+ if (0 != nsrv) { lhints.ai_flags |= AI_NUMERICSERV; }
+ lhints.ai_protocol = 0;
+ res = getaddrinfo(NULL, lsvcname, &lhints, &laddrst);
+ if ((0 == res) && (NULL != laddrst)) {
+ back = dk4socket_c8_tcp_client_addresses(
+ hostname, raddrst, laddrst, secs, usecs, erp
+ );
+ if (NULL != laddrst) { freeaddrinfo(laddrst); }
+ } else { $? "! bug"
+ /* ERROR: getaddrinfo failed */
+ dk4error_set_idetails(erp, DK4_E_SOCKET_GETADDRLOC, res);
+ }
+ } else {
+ back = dk4socket_c8_tcp_client_addresses(
+ hostname, raddrst, NULL, secs, usecs, erp
+ );
+ }
+ if (NULL != raddrst) { freeaddrinfo(raddrst); }
+ } else { $? "! host not found"
+ /* ERROR: getaddrinfo failed */
+ dk4error_set_idetails(erp, DK4_E_SOCKET_GETADDRINFO, res);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4socket_c8_tcp_client_host_num_srv %d", (int)back
+ return back;
+ /* ----- +getaddrinfo */
+#else
+ /* +++++ -getaddrinfo */
+ struct servent *serv = NULL; /* Service entry */
+ const char *endptr = NULL; /* End of used text */
+ int iport = 0; /* Port number from servent */
+ unsigned short rport = 0; /* Remote port number */
+ unsigned short lport = 0; /* Local port number */
+ int res; /* Operation result */
+ dk4_socket_t back = INVALID_SOCKET;
+ $? "+ dk4socket_c8_tcp_client_host_num_srv (-getaddrinfo)"
+ if ((NULL != hostname) && (NULL != svcname)) { $? ". args ok"
+ res = dk4ma_input_c8_dec_ushort(&rport, svcname, &endptr, 1, NULL);
+ if (0 == res) {
+ dk4socket_error_reset();
+ serv = getservbyname(svcname, NULL);
+ if (NULL != serv) {
+ iport = serv->s_port;
+ dk4socket_swap_bytes_if_not_bigendian((void *)(&iport), sizeof(iport));
+ rport = (unsigned short)iport;
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_GETSERVBYNAME);
+ }
+ }
+ if (0 != rport) {
+ if (NULL != lsvcname) {
+ endptr = NULL;
+ res = dk4ma_input_c8_dec_ushort(&lport, lsvcname, &endptr, 1, NULL);
+ if (0 == res) {
+ dk4socket_error_reset();
+ serv = getservbyname(lsvcname, NULL);
+ if (NULL != serv) {
+ iport = serv->s_port;
+ dk4socket_swap_bytes_if_not_bigendian(
+ (void *)(&iport), sizeof(iport)
+ );
+ lport = (unsigned short)iport;
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_GETSERVBYNAME);
+ }
+ }
+ if (0 != lport) {
+ back = dk4socket_c8_tcp_client_host_port(
+ hostname, rport, lport, secs, usecs, erp
+ );
+ }
+ } else {
+ back = dk4socket_c8_tcp_client_host_port(
+ hostname, rport, (unsigned short)0, secs, usecs, erp
+ );
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4socket_c8_tcp_client_host_num_srv %d", (int)back
+ return back;
+ /* ----- -getaddrinfo */
+#endif
+}
+
+
+
+dk4_socket_t
+dk4socket_c8_tcp_client_host_srv(
+ const char *hostname,
+ const char *svcname,
+ const char *lsvcname,
+ long secs,
+ long usecs,
+ dk4_er_t *erp
+)
+{
+ return (
+ dk4socket_c8_tcp_client_host_num_srv(
+ hostname, svcname, lsvcname, secs, usecs, 0, erp
+ )
+ );
+}
+
+
+
+dk4_socket_t
+dk4socket_c8_tcp_client_host_port(
+ const char *hostname,
+ unsigned short portno,
+ unsigned short lportno,
+ long secs,
+ long usecs,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_GETADDRINFO
+ /* +++++ +getaddrinfo */
+ char rpnb[16*sizeof(dk4_um_t)]; /* Remote port no */
+ char lpnb[16*sizeof(dk4_um_t)]; /* Local port no */
+ int res;
+ dk4_socket_t back = INVALID_SOCKET;
+ $? "+ dk4socket_c8_tcp_client_host_port"
+ if ((NULL != hostname) && (0 < portno)) {
+ res = dk4ma_write_c8_decimal_unsigned(
+ rpnb, sizeof(rpnb), (dk4_um_t)portno, 0, erp
+ );
+ if (0 != res) {
+ if (0 < lportno) {
+ res = dk4ma_write_c8_decimal_unsigned(
+ lpnb, sizeof(lpnb), (dk4_um_t)lportno, 0, erp
+ );
+ if (0 != res) {
+ back = dk4socket_c8_tcp_client_host_num_srv(
+ hostname, rpnb, lpnb, secs, usecs, 1, erp
+ );
+ } else { $? "! bug"
+ }
+ } else {
+ back = dk4socket_c8_tcp_client_host_num_srv(
+ hostname, rpnb, NULL, secs, usecs, 1, erp
+ );
+ }
+ } else { $? "! bug"
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- -getaddrinfo */
+ /* ----- +getaddrinfo */
+#else
+ /* +++++ -getaddrinfo */
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ struct sockaddr_in6 sr6;
+ struct sockaddr_in6 sl6;
+#endif
+ struct sockaddr_in sr4;
+ struct sockaddr_in sl4;
+ char **addrptr;
+ struct hostent * hep = NULL;
+ dk4_socket_t back = INVALID_SOCKET;
+ $? "+ dk4socket_c8_tcp_client_host_port"
+ if ((NULL != hostname) && (0 < portno)) {
+ hep = gethostbyname(hostname);
+ if (NULL != hep) { $? ". hep"
+ if (NULL != hep->h_addr_list) { $? ". addrlist"
+ switch (hep->h_addrtype) {
+ case AF_INET : { $? ". AF_INET"
+ if (4 == hep->h_length) { $? ". h_length"
+ addrptr = hep->h_addr_list;
+ while ((INVALID_SOCKET == back) && (NULL != *addrptr)) {
+ DK4_MEMRES(&sr4, sizeof(sr4));
+ sr4.sin_family = AF_INET;
+ sr4.sin_port = dk4socket_htons(portno);
+ DK4_MEMCPY(&(sr4.sin_addr), *addrptr, sizeof(IN_ADDR));
+$!trace-code dk4socket_debug_address("remote", (struct sockaddr *)(&sr4), sizeof(sr4));
+ if (0 != lportno) {
+ DK4_MEMRES(&sl4, sizeof(sl4));
+ sl4.sin_family = AF_INET;
+ sl4.sin_port = dk4socket_htons(lportno);
+ sl4.sin_addr.s_addr = dk4socket_htonl(INADDR_ANY);
+$!trace-code dk4socket_debug_address("local ", (struct sockaddr *)(&sl4), sizeof(sl4));
+ back = dk4socket_tcp_client_for_addr(
+ AF_INET, (struct sockaddr *)(&sr4), sizeof(sr4),
+ (struct sockaddr *)(&sl4), sizeof(sl4),
+ secs, usecs, erp
+ );
+ } else {
+ back = dk4socket_tcp_client_for_addr(
+ AF_INET, (struct sockaddr *)(&sr4), sizeof(sr4),
+ NULL, 0, secs, usecs, erp
+ );
+ }
+ addrptr++;
+ }
+ } else { $? "!. h_length"
+ /* ERROR: Address length mismatch */
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : { $? ". AF_INET6"
+ if (16 == hep->h_length) {
+ addrptr = hep->h_addr_list;
+ while ((INVALID_SOCKET == back) && (NULL != *addrptr)) {
+ DK4_MEMRES(&sr6, sizeof(sr6));
+ sr6.sin6_family = AF_INET6;
+ sr6.sin6_port = dk4socket_htons(portno);
+ DK4_MEMCPY(&(sr6.sin6_addr), *addrptr, sizeof(IN6_ADDR));
+ if (0 != lportno) {
+ DK4_MEMRES(&sl6, sizeof(sl6));
+ sl6.sin6_family = AF_INET6;
+ sl6.sin6_port = dk4socket_htons(lportno);
+ DK4_MEMCPY(&(sl6.sin6_addr), &dk4socket_any6, sizeof(IN6_ADDR));
+ back = dk4socket_tcp_client_for_addr(
+ AF_INET6, (struct sockaddr *)(&sr6), sizeof(sr6),
+ (struct sockaddr *)(&sl6), sizeof(sl6),
+ secs, usecs, erp
+ );
+ } else {
+ back = dk4socket_tcp_client_for_addr(
+ AF_INET6, (struct sockaddr *)(&sr6), sizeof(sr6),
+ NULL, 0, secs, usecs, erp
+ );
+ }
+ addrptr++;
+ }
+ } else {
+ /* ERROR: Address length mismatch */
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ } break;
+#endif
+ default : {
+ /* ERROR: Unknown protocol */
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ } break;
+ }
+ } else { $? "! addrlist"
+ /* ERROR: Host not found (empty list) */
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ } else { $? "! hep"
+ /* ERROR: Host not found */
+ dk4socket_error_report(erp, DK4_E_SOCKET_GETHOSTBYNAME);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- -getaddrinfo */
+#endif
+}
+
diff --git a/support/dktools/dk4sock18.c b/support/dktools/dk4sock18.c
new file mode 100644
index 0000000000..afdff9611f
--- /dev/null
+++ b/support/dktools/dk4sock18.c
@@ -0,0 +1,487 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sock18.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4sock18.c The dk4sock18 module.
+*/
+
+
+#line 10 "dk4sock18.ctr"
+
+#include "dk4sock.h"
+#include "dk4mem.h"
+#include "dk4maodd.h"
+
+#if !DK4_HAVE_GETADDRINFO
+#include "dk4rec24.h"
+#endif
+
+#include "dk4maiddus.h"
+
+
+
+
+#line 23 "dk4sock18.ctr"
+
+
+
+#if DK4_ON_WINDOWS
+#if DK4_HAVE_GETADDRINFO
+
+static
+dk4_socket_t
+dk4socket_wc_tcp_client_addresses(
+ const wchar_t *hostname,
+ ADDRINFOW *raddrst,
+ ADDRINFOW *laddrst,
+ long secs,
+ long usecs,
+ dk4_er_t *erp
+)
+{
+ ADDRINFOW *ra;
+ ADDRINFOW *la;
+ dk4_socket_t back = INVALID_SOCKET;
+
+
+#line 44 "dk4sock18.ctr"
+ ra = raddrst;
+ while ((INVALID_SOCKET == back) && (NULL != ra)) {
+ if (NULL != laddrst) {
+ la = laddrst;
+ while ((INVALID_SOCKET == back) && (NULL != la)) {
+ if (la->ai_family == ra->ai_family) {
+
+
+#line 51 "dk4sock18.ctr"
+
+
+#line 52 "dk4sock18.ctr"
+
+
+#line 53 "dk4sock18.ctr"
+
+
+#line 54 "dk4sock18.ctr"
+ back = dk4socket_tcp_client_for_addr(
+ ra->ai_family, ra->ai_addr, ra->ai_addrlen,
+ la->ai_addr, la->ai_addrlen, secs, usecs, erp
+ );
+ if (INVALID_SOCKET != back) {
+ la = NULL; ra = NULL;
+ }
+ }
+ if (NULL != la) { la = la->ai_next; }
+ }
+ } else {
+ back = dk4socket_tcp_client_for_addr(
+ ra->ai_family, ra->ai_addr, ra->ai_addrlen, NULL, 0,
+ secs, usecs, erp
+ );
+ if (INVALID_SOCKET != back) {
+ ra = NULL;
+ }
+ }
+ if (NULL != ra) { ra = ra->ai_next; }
+ }
+
+
+#line 76 "dk4sock18.ctr"
+ return back;
+}
+
+#else
+
+#endif
+#endif
+
+
+
+dk4_socket_t
+dk4socket_wc_tcp_client_host_num_srv(
+ const wchar_t *hostname,
+ const wchar_t *svcname,
+ const wchar_t *lsvcname,
+ long secs,
+ long usecs,
+ int nsrv,
+ dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+#if DK4_HAVE_GETADDRINFO
+ /* +++++ +getaddrinfo */
+ ADDRINFOW rhints;
+ ADDRINFOW lhints;
+ ADDRINFOW *raddrst = NULL;
+ ADDRINFOW *laddrst = NULL;
+ dk4_socket_t back = INVALID_SOCKET;
+ int res;
+
+
+#line 107 "dk4sock18.ctr"
+ if ((NULL != hostname) && (NULL != svcname)) {
+ DK4_MEMRES(&rhints, sizeof(rhints));
+ rhints.ai_family = AF_UNSPEC;
+ rhints.ai_socktype = SOCK_STREAM;
+ if (0 != nsrv) { rhints.ai_flags = AI_NUMERICSERV; }
+ rhints.ai_protocol = 0;
+ res = GetAddrInfoW(hostname, svcname, &rhints, &raddrst);
+ if ((0 == res) && (NULL != raddrst)) {
+ if (NULL != lsvcname) {
+ DK4_MEMRES(&lhints, sizeof(lhints));
+ lhints.ai_family = AF_UNSPEC;
+ lhints.ai_socktype = SOCK_STREAM;
+ lhints.ai_flags = AI_PASSIVE;
+ if (0 != nsrv) { lhints.ai_flags |= AI_NUMERICSERV; }
+ lhints.ai_protocol = 0;
+ res = GetAddrInfoW(NULL, lsvcname, &lhints, &laddrst);
+ if ((0 == res) && (NULL != laddrst)) {
+ back = dk4socket_wc_tcp_client_addresses(
+ hostname, raddrst, laddrst, secs, usecs, erp
+ );
+ if (NULL != laddrst) { FreeAddrInfoW(laddrst); }
+ } else {
+ /* ERROR: getaddrinfo failed */
+ dk4error_set_idetails(erp, DK4_E_SOCKET_GETADDRLOC, res);
+ }
+ } else {
+ back = dk4socket_wc_tcp_client_addresses(
+ hostname, raddrst, NULL, secs, usecs, erp
+ );
+ }
+ } else {
+ /* ERROR: getaddrinfo failed */
+ dk4error_set_idetails(erp, DK4_E_SOCKET_GETADDRINFO, res);
+ }
+ if (NULL != laddrst) { FreeAddrInfoW(laddrst); }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 146 "dk4sock18.ctr"
+ return back;
+ /* ----- +getaddrinfo */
+#else
+ /* +++++ -getaddrinfo */
+ char cppt[48];
+ char cplp[48];
+ struct servent *serv = NULL;
+ const wchar_t *endptr = NULL;
+ dk4_socket_t back = INVALID_SOCKET;
+ int res = 0;
+ unsigned short rport = 0U;
+ unsigned short lport = 0U;
+ unsigned short iport = 0U;
+ if ((NULL != hostname) && (NULL != svcname)) {
+ res = dk4ma_input_dk_dec_ushort(&rport, svcname, &endptr, 1, erp);
+ if (0 == res) {
+ if (0 != dk4recode_wchar_t_to_char(cppt, sizeof(cppt), svcname, erp)) {
+ dk4socket_error_reset();
+ serv = getservbyname(cppt, NULL);
+ if (NULL != serv) {
+ iport = serv->s_port;
+ dk4socket_swap_bytes_if_not_bigendian((void *)(&iport),sizeof(iport));
+ rport = (unsigned short)iport;
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_GETSERVBYNAME);
+ }
+ }
+ }
+ if (0 != rport) {
+ if (NULL != lsvcname) {
+ endptr = NULL;
+ res = dk4ma_input_dk_dec_ushort(&lport, lsvcname, &endptr, 1, erp);
+ if (0 == res) {
+ if (0 != dk4recode_wchar_t_to_char(cplp,sizeof(cplp),lsvcname,erp)) {
+ dk4socket_error_reset();
+ serv = getservbyname(cplp, NULL);
+ if (NULL != serv) {
+ iport = serv->s_port;
+ dk4socket_swap_bytes_if_not_bigendian(
+ (void *)(&iport), sizeof(iport)
+ );
+ lport = (unsigned short)iport;
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_GETSERVBYNAME);
+ }
+ } else {
+ /* ERROR: Text conversion failed, already reported */
+ }
+ }
+ if (0 != lport) {
+ back = dk4socket_wc_tcp_client_host_port(
+ hostname, rport, lport, secs, usecs, erp
+ );
+ }
+ } else {
+ back = dk4socket_wc_tcp_client_host_port(
+ hostname, rport, (unsigned short)0, secs, usecs, erp
+ );
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- -getaddrinfo */
+#endif
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return (DK4_SOCKET_RESULT_FAILED);
+#endif
+}
+
+
+
+dk4_socket_t
+dk4socket_wc_tcp_client_host_srv(
+ const wchar_t *hostname,
+ const wchar_t *svcname,
+ const wchar_t *lsvcname,
+ long secs,
+ long usecs,
+ dk4_er_t *erp
+)
+{
+ return (
+ dk4socket_wc_tcp_client_host_num_srv(
+ hostname, svcname, lsvcname, secs, usecs, 0, erp
+ )
+ );
+}
+
+
+
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+/** used to initialize IPv6 address for binding local ports.
+*/
+static const IN6_ADDR dk4sock18_any6 = IN6ADDR_ANY_INIT ;
+#endif
+
+
+
+dk4_socket_t
+dk4socket_wc_tcp_client_host_port(
+ const wchar_t *hostname,
+ unsigned short portno,
+ unsigned short lportno,
+ long secs,
+ long usecs,
+ dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+#if DK4_HAVE_GETADDRINFO
+ /* +++++ +getaddrinfo */
+ wchar_t rpnb[16*sizeof(dk4_um_t)];
+ wchar_t lpnb[16*sizeof(dk4_um_t)];
+ const size_t szrpbn = DK4_SIZEOF(rpnb,wchar_t);
+ const size_t szlpnb = DK4_SIZEOF(lpnb,wchar_t);
+ dk4_socket_t back = INVALID_SOCKET;
+ int res;
+
+
+#line 267 "dk4sock18.ctr"
+ if ((NULL != hostname) && (0 < portno)) {
+ res = dk4ma_write_decimal_unsigned(rpnb, szrpbn, (dk4_um_t)portno, 0, erp);
+ if (0 != res) {
+ if (0 < lportno) {
+ res = dk4ma_write_decimal_unsigned(lpnb,szlpnb,(dk4_um_t)lportno,0,erp);
+ if (0 != res) {
+ back = dk4socket_wc_tcp_client_host_num_srv(
+ hostname, rpnb, lpnb, secs, usecs, 1, erp
+ );
+ } else {
+
+#line 277 "dk4sock18.ctr"
+ }
+ } else {
+ back = dk4socket_wc_tcp_client_host_num_srv(
+ hostname, rpnb, NULL, secs, usecs, 1, erp
+ );
+ }
+ } else {
+
+#line 284 "dk4sock18.ctr"
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 289 "dk4sock18.ctr"
+ return back;
+ /* ----- +getaddrinfo */
+#else
+ /* +++++ -getaddrinfo */
+ char hona[1040];
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ struct sockaddr_in6 sr6;
+ struct sockaddr_in6 sl6;
+#endif
+ struct sockaddr_in sr4;
+ struct sockaddr_in sl4;
+ char **addrptr;
+ struct hostent *hep;
+ dk4_socket_t back = INVALID_SOCKET;
+
+
+#line 304 "dk4sock18.ctr"
+ if ((NULL != hostname) && (0 < portno)) {
+
+#line 305 "dk4sock18.ctr"
+ if (0 != dk4recode_wchar_t_to_char(hona, sizeof(hona), hostname, erp)) {
+ dk4socket_error_reset();
+ hep = gethostbyname(hona);
+
+#line 308 "dk4sock18.ctr"
+ if (NULL != hep) {
+
+#line 309 "dk4sock18.ctr"
+ if (NULL != hep->h_addr_list) {
+
+#line 310 "dk4sock18.ctr"
+ switch (hep->h_addrtype) {
+ case AF_INET : {
+ if (4 == hep->h_length) {
+ addrptr = hep->h_addr_list;
+ while ((INVALID_SOCKET == back) && (NULL != *addrptr)) {
+ DK4_MEMRES(&sr4, sizeof(sr4));
+ sr4.sin_family = AF_INET;
+ sr4.sin_port = dk4socket_htons(portno);
+ DK4_MEMCPY(&(sr4.sin_addr), *addrptr, sizeof(IN_ADDR));
+
+
+#line 320 "dk4sock18.ctr"
+ if (0 != lportno) {
+ DK4_MEMRES(&sl4, sizeof(sl4));
+ sl4.sin_family = AF_INET;
+ sl4.sin_port = dk4socket_htons(lportno);
+ sl4.sin_addr.s_addr = dk4socket_htonl(INADDR_ANY);
+
+
+#line 326 "dk4sock18.ctr"
+ back = dk4socket_tcp_client_for_addr(
+ AF_INET, (struct sockaddr *)(&sr4), sizeof(sr4),
+ (struct sockaddr *)(&sl4), sizeof(sl4),
+ secs, usecs, erp
+ );
+ } else {
+ back = dk4socket_tcp_client_for_addr(
+ AF_INET, (struct sockaddr *)(&sr4), sizeof(sr4),
+ NULL, 0, secs, usecs, erp
+ );
+ }
+ addrptr++;
+ }
+ } else {
+
+#line 340 "dk4sock18.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ if (16 == hep->h_length) {
+ addrptr = hep->h_addr_list;
+ while ((INVALID_SOCKET == back) && (NULL != *addrptr)) {
+ DK4_MEMRES(&sr6, sizeof(sr6));
+ sr6.sin6_family = AF_INET6;
+ sr6.sin6_port = dk4socket_htons(portno);
+ DK4_MEMCPY(&(sr6.sin6_addr), *addrptr, sizeof(IN6_ADDR));
+ if (0 != lportno) {
+ DK4_MEMRES(&sl6, sizeof(sl6));
+ sl6.sin6_family = AF_INET6;
+ sl6.sin6_port = dk4socket_htons(lportno);
+ DK4_MEMCPY(&(sl6.sin6_addr), &dk4sock18_any6, sizeof(IN6_ADDR));
+ back = dk4socket_tcp_client_for_addr(
+ AF_INET6, (struct sockaddr *)(&sr6), sizeof(sr6),
+ (struct sockaddr *)(&sl6), sizeof(sl6),
+ secs, usecs, erp
+ );
+ } else {
+ back = dk4socket_tcp_client_for_addr(
+ AF_INET6, (struct sockaddr *)(&sr6), sizeof(sr6),
+ NULL, 0, secs, usecs, erp
+ );
+ }
+ addrptr++;
+ }
+ } else {
+ /* ERROR: Address length mismatch */
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ } break;
+#endif
+ default : {
+ /* ERROR: Unknown protocol */
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ } break;
+ }
+ } else {
+
+#line 382 "dk4sock18.ctr"
+ /* ERROR: List empty */
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ } else {
+
+#line 386 "dk4sock18.ctr"
+ /* ERROR: Host not found */
+ dk4socket_error_report(erp, DK4_E_SOCKET_GETHOSTBYNAME);
+ }
+ } else {
+
+#line 390 "dk4sock18.ctr"
+ /* ERROR: Failed to convert hostname to ASCII, already reported */
+ }
+ } else {
+
+#line 393 "dk4sock18.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 396 "dk4sock18.ctr"
+ return back;
+ /* ----- -getaddrinfo */
+#endif
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return (DK4_SOCKET_RESULT_FAILED);
+#endif
+}
+
diff --git a/support/dktools/dk4sock18.ctr b/support/dktools/dk4sock18.ctr
new file mode 100644
index 0000000000..117d3969a9
--- /dev/null
+++ b/support/dktools/dk4sock18.ctr
@@ -0,0 +1,404 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4sock.h"
+#include "dk4mem.h"
+#include "dk4maodd.h"
+
+#if !DK4_HAVE_GETADDRINFO
+#include "dk4rec24.h"
+#endif
+
+#include "dk4maiddus.h"
+
+
+$!trace-include
+
+
+
+#if DK4_ON_WINDOWS
+#if DK4_HAVE_GETADDRINFO
+
+static
+dk4_socket_t
+dk4socket_wc_tcp_client_addresses(
+ const wchar_t *hostname,
+ ADDRINFOW *raddrst,
+ ADDRINFOW *laddrst,
+ long secs,
+ long usecs,
+ dk4_er_t *erp
+)
+{
+ ADDRINFOW *ra;
+ ADDRINFOW *la;
+ dk4_socket_t back = INVALID_SOCKET;
+ $? "+ dk4socket_wc_tcp_client_addresses"
+ ra = raddrst;
+ while ((INVALID_SOCKET == back) && (NULL != ra)) {
+ if (NULL != laddrst) {
+ la = laddrst;
+ while ((INVALID_SOCKET == back) && (NULL != la)) {
+ if (la->ai_family == ra->ai_family) {
+$? ". remote = %d PTR=%d %lu", (int)(ra->ai_family), TR_IPTR(ra->ai_addr), (unsigned long)(ra->ai_addrlen)
+$? ". local = %d PTR=%d %lu", (int)(la->ai_family), TR_IPTR(la->ai_addr), (unsigned long)(la->ai_addrlen)
+$!trace-code dk4socket_debug_address("remote", ra->ai_addr, ra->ai_addrlen);
+$!trace-code dk4socket_debug_address("local ", la->ai_addr, la->ai_addrlen);
+ back = dk4socket_tcp_client_for_addr(
+ ra->ai_family, ra->ai_addr, ra->ai_addrlen,
+ la->ai_addr, la->ai_addrlen, secs, usecs, erp
+ );
+ if (INVALID_SOCKET != back) {
+ la = NULL; ra = NULL;
+ }
+ }
+ if (NULL != la) { la = la->ai_next; }
+ }
+ } else {
+ back = dk4socket_tcp_client_for_addr(
+ ra->ai_family, ra->ai_addr, ra->ai_addrlen, NULL, 0,
+ secs, usecs, erp
+ );
+ if (INVALID_SOCKET != back) {
+ ra = NULL;
+ }
+ }
+ if (NULL != ra) { ra = ra->ai_next; }
+ }
+ $? "- dk4socket_wc_tcp_client_addresses %d", (int)back
+ return back;
+}
+
+#else
+
+#endif
+#endif
+
+
+
+dk4_socket_t
+dk4socket_wc_tcp_client_host_num_srv(
+ const wchar_t *hostname,
+ const wchar_t *svcname,
+ const wchar_t *lsvcname,
+ long secs,
+ long usecs,
+ int nsrv,
+ dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+#if DK4_HAVE_GETADDRINFO
+ /* +++++ +getaddrinfo */
+ ADDRINFOW rhints;
+ ADDRINFOW lhints;
+ ADDRINFOW *raddrst = NULL;
+ ADDRINFOW *laddrst = NULL;
+ dk4_socket_t back = INVALID_SOCKET;
+ int res;
+ $? "+ dk4socket_dk_tcp_client_host_num_srv (getaddrinfo)"
+ if ((NULL != hostname) && (NULL != svcname)) {
+ DK4_MEMRES(&rhints, sizeof(rhints));
+ rhints.ai_family = AF_UNSPEC;
+ rhints.ai_socktype = SOCK_STREAM;
+ if (0 != nsrv) { rhints.ai_flags = AI_NUMERICSERV; }
+ rhints.ai_protocol = 0;
+ res = GetAddrInfoW(hostname, svcname, &rhints, &raddrst);
+ if ((0 == res) && (NULL != raddrst)) {
+ if (NULL != lsvcname) {
+ DK4_MEMRES(&lhints, sizeof(lhints));
+ lhints.ai_family = AF_UNSPEC;
+ lhints.ai_socktype = SOCK_STREAM;
+ lhints.ai_flags = AI_PASSIVE;
+ if (0 != nsrv) { lhints.ai_flags |= AI_NUMERICSERV; }
+ lhints.ai_protocol = 0;
+ res = GetAddrInfoW(NULL, lsvcname, &lhints, &laddrst);
+ if ((0 == res) && (NULL != laddrst)) {
+ back = dk4socket_wc_tcp_client_addresses(
+ hostname, raddrst, laddrst, secs, usecs, erp
+ );
+ if (NULL != laddrst) { FreeAddrInfoW(laddrst); }
+ } else {
+ /* ERROR: getaddrinfo failed */
+ dk4error_set_idetails(erp, DK4_E_SOCKET_GETADDRLOC, res);
+ }
+ } else {
+ back = dk4socket_wc_tcp_client_addresses(
+ hostname, raddrst, NULL, secs, usecs, erp
+ );
+ }
+ } else {
+ /* ERROR: getaddrinfo failed */
+ dk4error_set_idetails(erp, DK4_E_SOCKET_GETADDRINFO, res);
+ }
+ if (NULL != laddrst) { FreeAddrInfoW(laddrst); }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4socket_dk_tcp_client_host_num_srv %d", (int)back
+ return back;
+ /* ----- +getaddrinfo */
+#else
+ /* +++++ -getaddrinfo */
+ char cppt[48];
+ char cplp[48];
+ struct servent *serv = NULL;
+ const wchar_t *endptr = NULL;
+ dk4_socket_t back = INVALID_SOCKET;
+ int res = 0;
+ unsigned short rport = 0U;
+ unsigned short lport = 0U;
+ unsigned short iport = 0U;
+ if ((NULL != hostname) && (NULL != svcname)) {
+ res = dk4ma_input_dk_dec_ushort(&rport, svcname, &endptr, 1, erp);
+ if (0 == res) {
+ if (0 != dk4recode_wchar_t_to_char(cppt, sizeof(cppt), svcname, erp)) {
+ dk4socket_error_reset();
+ serv = getservbyname(cppt, NULL);
+ if (NULL != serv) {
+ iport = serv->s_port;
+ dk4socket_swap_bytes_if_not_bigendian((void *)(&iport),sizeof(iport));
+ rport = (unsigned short)iport;
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_GETSERVBYNAME);
+ }
+ }
+ }
+ if (0 != rport) {
+ if (NULL != lsvcname) {
+ endptr = NULL;
+ res = dk4ma_input_dk_dec_ushort(&lport, lsvcname, &endptr, 1, erp);
+ if (0 == res) {
+ if (0 != dk4recode_wchar_t_to_char(cplp,sizeof(cplp),lsvcname,erp)) {
+ dk4socket_error_reset();
+ serv = getservbyname(cplp, NULL);
+ if (NULL != serv) {
+ iport = serv->s_port;
+ dk4socket_swap_bytes_if_not_bigendian(
+ (void *)(&iport), sizeof(iport)
+ );
+ lport = (unsigned short)iport;
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_GETSERVBYNAME);
+ }
+ } else {
+ /* ERROR: Text conversion failed, already reported */
+ }
+ }
+ if (0 != lport) {
+ back = dk4socket_wc_tcp_client_host_port(
+ hostname, rport, lport, secs, usecs, erp
+ );
+ }
+ } else {
+ back = dk4socket_wc_tcp_client_host_port(
+ hostname, rport, (unsigned short)0, secs, usecs, erp
+ );
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- -getaddrinfo */
+#endif
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return (DK4_SOCKET_RESULT_FAILED);
+#endif
+}
+
+
+
+dk4_socket_t
+dk4socket_wc_tcp_client_host_srv(
+ const wchar_t *hostname,
+ const wchar_t *svcname,
+ const wchar_t *lsvcname,
+ long secs,
+ long usecs,
+ dk4_er_t *erp
+)
+{
+ return (
+ dk4socket_wc_tcp_client_host_num_srv(
+ hostname, svcname, lsvcname, secs, usecs, 0, erp
+ )
+ );
+}
+
+
+
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+/** used to initialize IPv6 address for binding local ports.
+*/
+static const IN6_ADDR dk4sock18_any6 = IN6ADDR_ANY_INIT ;
+#endif
+
+
+
+dk4_socket_t
+dk4socket_wc_tcp_client_host_port(
+ const wchar_t *hostname,
+ unsigned short portno,
+ unsigned short lportno,
+ long secs,
+ long usecs,
+ dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+#if DK4_HAVE_GETADDRINFO
+ /* +++++ +getaddrinfo */
+ wchar_t rpnb[16*sizeof(dk4_um_t)];
+ wchar_t lpnb[16*sizeof(dk4_um_t)];
+ const size_t szrpbn = DK4_SIZEOF(rpnb,wchar_t);
+ const size_t szlpnb = DK4_SIZEOF(lpnb,wchar_t);
+ dk4_socket_t back = INVALID_SOCKET;
+ int res;
+ $? "+ dk4socket_dk_tcp_client_host_port (getaddrinfo)"
+ if ((NULL != hostname) && (0 < portno)) {
+ res = dk4ma_write_decimal_unsigned(rpnb, szrpbn, (dk4_um_t)portno, 0, erp);
+ if (0 != res) {
+ if (0 < lportno) {
+ res = dk4ma_write_decimal_unsigned(lpnb,szlpnb,(dk4_um_t)lportno,0,erp);
+ if (0 != res) {
+ back = dk4socket_wc_tcp_client_host_num_srv(
+ hostname, rpnb, lpnb, secs, usecs, 1, erp
+ );
+ } else { $? "! bug"
+ }
+ } else {
+ back = dk4socket_wc_tcp_client_host_num_srv(
+ hostname, rpnb, NULL, secs, usecs, 1, erp
+ );
+ }
+ } else { $? "! bug"
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4socket_dk_tcp_client_host_port %d", (int)back
+ return back;
+ /* ----- +getaddrinfo */
+#else
+ /* +++++ -getaddrinfo */
+ char hona[1040];
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ struct sockaddr_in6 sr6;
+ struct sockaddr_in6 sl6;
+#endif
+ struct sockaddr_in sr4;
+ struct sockaddr_in sl4;
+ char **addrptr;
+ struct hostent *hep;
+ dk4_socket_t back = INVALID_SOCKET;
+ $? "+ dk4socket_dk_tcp_client_host_port (no getaddrinfo)"
+ if ((NULL != hostname) && (0 < portno)) { $? ". args ok"
+ if (0 != dk4recode_wchar_t_to_char(hona, sizeof(hona), hostname, erp)) {
+ dk4socket_error_reset();
+ hep = gethostbyname(hona); $? ". recode ok"
+ if (NULL != hep) { $? ". host found"
+ if (NULL != hep->h_addr_list) { $? ". entries in list"
+ switch (hep->h_addrtype) {
+ case AF_INET : {
+ if (4 == hep->h_length) {
+ addrptr = hep->h_addr_list;
+ while ((INVALID_SOCKET == back) && (NULL != *addrptr)) {
+ DK4_MEMRES(&sr4, sizeof(sr4));
+ sr4.sin_family = AF_INET;
+ sr4.sin_port = dk4socket_htons(portno);
+ DK4_MEMCPY(&(sr4.sin_addr), *addrptr, sizeof(IN_ADDR));
+$!trace-code dk4socket_debug_address("remote", (struct sockaddr *)(&sr4), sizeof(sr4));
+ if (0 != lportno) {
+ DK4_MEMRES(&sl4, sizeof(sl4));
+ sl4.sin_family = AF_INET;
+ sl4.sin_port = dk4socket_htons(lportno);
+ sl4.sin_addr.s_addr = dk4socket_htonl(INADDR_ANY);
+$!trace-code dk4socket_debug_address("local ", (struct sockaddr *)(&sl4), sizeof(sl4));
+ back = dk4socket_tcp_client_for_addr(
+ AF_INET, (struct sockaddr *)(&sr4), sizeof(sr4),
+ (struct sockaddr *)(&sl4), sizeof(sl4),
+ secs, usecs, erp
+ );
+ } else {
+ back = dk4socket_tcp_client_for_addr(
+ AF_INET, (struct sockaddr *)(&sr4), sizeof(sr4),
+ NULL, 0, secs, usecs, erp
+ );
+ }
+ addrptr++;
+ }
+ } else { $? "! length"
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ if (16 == hep->h_length) {
+ addrptr = hep->h_addr_list;
+ while ((INVALID_SOCKET == back) && (NULL != *addrptr)) {
+ DK4_MEMRES(&sr6, sizeof(sr6));
+ sr6.sin6_family = AF_INET6;
+ sr6.sin6_port = dk4socket_htons(portno);
+ DK4_MEMCPY(&(sr6.sin6_addr), *addrptr, sizeof(IN6_ADDR));
+ if (0 != lportno) {
+ DK4_MEMRES(&sl6, sizeof(sl6));
+ sl6.sin6_family = AF_INET6;
+ sl6.sin6_port = dk4socket_htons(lportno);
+ DK4_MEMCPY(&(sl6.sin6_addr), &dk4sock18_any6, sizeof(IN6_ADDR));
+ back = dk4socket_tcp_client_for_addr(
+ AF_INET6, (struct sockaddr *)(&sr6), sizeof(sr6),
+ (struct sockaddr *)(&sl6), sizeof(sl6),
+ secs, usecs, erp
+ );
+ } else {
+ back = dk4socket_tcp_client_for_addr(
+ AF_INET6, (struct sockaddr *)(&sr6), sizeof(sr6),
+ NULL, 0, secs, usecs, erp
+ );
+ }
+ addrptr++;
+ }
+ } else {
+ /* ERROR: Address length mismatch */
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ } break;
+#endif
+ default : {
+ /* ERROR: Unknown protocol */
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ } break;
+ }
+ } else { $? "! empty list"
+ /* ERROR: List empty */
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ } else { $? "! gethostbyname"
+ /* ERROR: Host not found */
+ dk4socket_error_report(erp, DK4_E_SOCKET_GETHOSTBYNAME);
+ }
+ } else { $? "! recode"
+ /* ERROR: Failed to convert hostname to ASCII, already reported */
+ }
+ } else { $? "! args"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4socket_dk_tcp_client_host_port %d", (int)back
+ return back;
+ /* ----- -getaddrinfo */
+#endif
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return (DK4_SOCKET_RESULT_FAILED);
+#endif
+}
+
diff --git a/support/dktools/dk4sock19.c b/support/dktools/dk4sock19.c
new file mode 100644
index 0000000000..059774bce2
--- /dev/null
+++ b/support/dktools/dk4sock19.c
@@ -0,0 +1,104 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sock19.ctr
+*/
+
+/** @file dk4sock19.c The dk4sock19 module.
+*/
+
+
+#line 5 "dk4sock19.ctr"
+
+#include "dk4sock.h"
+#include "dk4socka.h"
+
+
+
+
+
+#line 12 "dk4sock19.ctr"
+
+
+
+dk4_socket_t
+dk4socket_tcp_client_host_num_srv(
+ const dkChar *hostname,
+ const dkChar *svcname,
+ const dkChar *lsvcname,
+ long secs,
+ long usecs,
+ int nsrv,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (
+ dk4socket_wc_tcp_client_host_num_srv(
+ hostname, svcname, lsvcname, secs, usecs, nsrv, erp
+ )
+ );
+#else
+ return (
+ dk4socket_c8_tcp_client_host_num_srv(
+ hostname, svcname, lsvcname, secs, usecs, nsrv, erp
+ )
+ );
+#endif
+}
+
+
+
+dk4_socket_t
+dk4socket_tcp_client_host_srv(
+ const dkChar *hostname,
+ const dkChar *svcname,
+ const dkChar *lsvcname,
+ long secs,
+ long usecs,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (
+ dk4socket_wc_tcp_client_host_srv(
+ hostname, svcname, lsvcname, secs, usecs, erp
+ )
+ );
+#else
+ return (
+ dk4socket_c8_tcp_client_host_srv(
+ hostname, svcname, lsvcname, secs, usecs, erp
+ )
+ );
+#endif
+}
+
+
+
+dk4_socket_t
+dk4socket_tcp_client_host_port(
+ const dkChar *hostname,
+ unsigned short portno,
+ unsigned short lportno,
+ long secs,
+ long usecs,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (
+ dk4socket_wc_tcp_client_host_port(
+ hostname, portno, lportno, secs, usecs, erp
+ )
+ );
+#else
+ return (
+ dk4socket_c8_tcp_client_host_port(
+ hostname, portno, lportno, secs, usecs, erp
+ )
+ );
+#endif
+}
+
diff --git a/support/dktools/dk4sock19.ctr b/support/dktools/dk4sock19.ctr
new file mode 100644
index 0000000000..ba2ced394f
--- /dev/null
+++ b/support/dktools/dk4sock19.ctr
@@ -0,0 +1,94 @@
+%% options
+
+
+%% module
+
+#include "dk4sock.h"
+#include "dk4socka.h"
+
+
+
+$!trace-include
+
+
+
+dk4_socket_t
+dk4socket_tcp_client_host_num_srv(
+ const dkChar *hostname,
+ const dkChar *svcname,
+ const dkChar *lsvcname,
+ long secs,
+ long usecs,
+ int nsrv,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (
+ dk4socket_wc_tcp_client_host_num_srv(
+ hostname, svcname, lsvcname, secs, usecs, nsrv, erp
+ )
+ );
+#else
+ return (
+ dk4socket_c8_tcp_client_host_num_srv(
+ hostname, svcname, lsvcname, secs, usecs, nsrv, erp
+ )
+ );
+#endif
+}
+
+
+
+dk4_socket_t
+dk4socket_tcp_client_host_srv(
+ const dkChar *hostname,
+ const dkChar *svcname,
+ const dkChar *lsvcname,
+ long secs,
+ long usecs,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (
+ dk4socket_wc_tcp_client_host_srv(
+ hostname, svcname, lsvcname, secs, usecs, erp
+ )
+ );
+#else
+ return (
+ dk4socket_c8_tcp_client_host_srv(
+ hostname, svcname, lsvcname, secs, usecs, erp
+ )
+ );
+#endif
+}
+
+
+
+dk4_socket_t
+dk4socket_tcp_client_host_port(
+ const dkChar *hostname,
+ unsigned short portno,
+ unsigned short lportno,
+ long secs,
+ long usecs,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (
+ dk4socket_wc_tcp_client_host_port(
+ hostname, portno, lportno, secs, usecs, erp
+ )
+ );
+#else
+ return (
+ dk4socket_c8_tcp_client_host_port(
+ hostname, portno, lportno, secs, usecs, erp
+ )
+ );
+#endif
+}
+
diff --git a/support/dktools/dk4sock20.c b/support/dktools/dk4sock20.c
new file mode 100644
index 0000000000..fd75d1bceb
--- /dev/null
+++ b/support/dktools/dk4sock20.c
@@ -0,0 +1,287 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sock20.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4sock20.c The dk4sock20 module.
+*/
+
+
+#line 10 "dk4sock20.ctr"
+
+#include "dk4sock.h"
+
+#if DK4_HAVE_LIMITS_H
+#ifndef LIMITS_H_INCLUDED
+#include <limits.h>
+#define LIMITS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDINT_H
+#ifndef STDINT_H_INCLUDED
+#if defined(__cplusplus) && (!defined(__STDC_LIMIT_MACROS))
+#define __STDC_LIMIT_MACROS 1
+#endif
+#if defined(__cplusplus) && (!defined(__STDC_CONSTANT_MACROS))
+#define __STDC_CONSTANT_MACROS 1
+#endif
+#include <stdint.h>
+#define STDINT_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4numco.h"
+
+
+
+
+
+#line 45 "dk4sock20.ctr"
+
+
+
+
+int
+dk4socket_send(
+ dk4_socket_t sock,
+ const void *buf,
+ size_t *pszbuf,
+ int flags,
+ long secs,
+ long usecs,
+ dk4_er_t *erp
+)
+{
+ fd_set wfds;
+ struct timeval to;
+#if DK4_HAVE_SSIZE_T
+ ssize_t bwr;
+#else
+ int bwr;
+#endif
+ int res;
+ int back = DK4_SOCKET_RESULT_FAILED;
+
+ if ((INVALID_SOCKET != sock) && (NULL != buf) && (NULL != pszbuf)) {
+ if (0 < *pszbuf) {
+#if DK4_HAVE_SSIZE_T
+ if ((dk4_um_t)(*pszbuf) <= (dk4_um_t)(SIZE_MAX / 2))
+#else
+ if ((dk4_um_t)(*pszbuf) <= (dk4_um_t)(INT_MAX))
+#endif
+ {
+ if ((0L != secs) || (0L != usecs)) {
+ /*
+ Timeout, check writability.
+ */
+ FD_ZERO(&wfds);
+ FD_SET(sock, &wfds);
+ to.tv_sec = secs;
+ to.tv_usec = usecs;
+ dk4socket_error_reset();
+ res = select(((int)sock + 1), NULL, &wfds, NULL, &to);
+ if (0 < res) {
+ if (FD_ISSET(sock, &wfds)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ /* Timeout */
+ dk4error_set_simple_error_code(erp, DK4_E_SOCKET_TIMEOUT);
+ }
+ } else {
+#if DK4_ON_WINDOWS
+ if (SOCKET_ERROR == res)
+#else
+ if (-1 == res)
+#endif
+ {
+ /* select error */
+ dk4socket_error_report(erp, DK4_E_SOCKET_SELECT);
+ }
+ else
+ {
+ /* Timeout */
+ dk4error_set_simple_error_code(erp, DK4_E_SOCKET_TIMEOUT);
+ }
+ }
+ } else {
+ /*
+ No timeout, can continue sending immediately.
+ */
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ }
+ if (DK4_SOCKET_RESULT_SUCCESS == back) {
+ back = DK4_SOCKET_RESULT_FAILED;
+ /*
+ Really send.
+ */
+ dk4socket_error_reset();
+#if DK4_ON_WINDOWS
+ bwr = send(sock, buf, (int)(*pszbuf), flags);
+#else
+ bwr = send(sock, buf, *pszbuf, flags);
+#endif
+ if (0 <= bwr) {
+ if ((size_t)bwr == *pszbuf) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ back = DK4_SOCKET_RESULT_IN_PROGRESS;
+ }
+ *pszbuf = (size_t)bwr;
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_SEND);
+ *pszbuf = 0;
+ }
+ } else {
+ *pszbuf = 0;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ *pszbuf = 0;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ *pszbuf = 0;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ if (NULL != pszbuf) { *pszbuf = 0; }
+ }
+ return back;
+}
+
+
+
+int
+dk4socket_recv(
+ dk4_socket_t sock,
+ void *buf,
+ size_t *pszbuf,
+ int flags,
+ long secs,
+ long usecs,
+ dk4_er_t *erp
+)
+{
+ fd_set rfds;
+ struct timeval to;
+#if DK4_HAVE_SSIZE_T
+ ssize_t bwr;
+#else
+ int bwr;
+#endif
+ int res;
+ int back = DK4_SOCKET_RESULT_FAILED;
+
+ if ((INVALID_SOCKET != sock) && (NULL != buf) && (NULL != pszbuf)) {
+ if (0 < *pszbuf) {
+#if DK4_HAVE_SSIZE_T
+ if ((dk4_um_t)(*pszbuf) <= (dk4_um_t)(SIZE_MAX / 2))
+#else
+ if ((dk4_um_t)(*pszbuf) <= (dk4_um_t)(INT_MAX))
+#endif
+ {
+ if ((0L != secs) || (0L != usecs)) {
+ /*
+ Timeout, check readability.
+ */
+ FD_ZERO(&rfds);
+ FD_SET(sock, &rfds);
+ to.tv_sec = secs;
+ to.tv_usec = usecs;
+ dk4socket_error_reset();
+ res = select(((int)sock + 1), &rfds, NULL, NULL, &to);
+ if (0 < res) {
+ if (FD_ISSET(sock, &rfds)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SOCKET_TIMEOUT);
+ }
+ } else {
+#if DK4_ON_WINDOWS
+ if (SOCKET_ERROR == res)
+#else
+ if (-1 == res)
+#endif
+ {
+ dk4socket_error_report(erp, DK4_E_SOCKET_SELECT);
+ }
+ else
+ {
+ dk4error_set_simple_error_code(erp, DK4_E_SOCKET_TIMEOUT);
+ }
+ }
+ } else {
+ /*
+ No timeout.
+ */
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ }
+ if (DK4_SOCKET_RESULT_SUCCESS == back) {
+ back = DK4_SOCKET_RESULT_FAILED;
+ dk4socket_error_reset();
+#if DK4_ON_WINDOWS
+ bwr = recv(sock, buf, (int)(*pszbuf), flags);
+#else
+ bwr = recv(sock, buf, *pszbuf, flags);
+#endif
+ if (0 <= bwr) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ *pszbuf = (size_t)bwr;
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_RECV);
+ *pszbuf = 0;
+ }
+ }
+ }
+ else
+ {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4sock20.ctr b/support/dktools/dk4sock20.ctr
new file mode 100644
index 0000000000..0c81d22d25
--- /dev/null
+++ b/support/dktools/dk4sock20.ctr
@@ -0,0 +1,254 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4sock.h"
+
+#if DK4_HAVE_LIMITS_H
+#ifndef LIMITS_H_INCLUDED
+#include <limits.h>
+#define LIMITS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDINT_H
+#ifndef STDINT_H_INCLUDED
+#if defined(__cplusplus) && (!defined(__STDC_LIMIT_MACROS))
+#define __STDC_LIMIT_MACROS 1
+#endif
+#if defined(__cplusplus) && (!defined(__STDC_CONSTANT_MACROS))
+#define __STDC_CONSTANT_MACROS 1
+#endif
+#include <stdint.h>
+#define STDINT_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4numco.h"
+
+
+
+$!trace-include
+
+
+
+
+int
+dk4socket_send(
+ dk4_socket_t sock,
+ const void *buf,
+ size_t *pszbuf,
+ int flags,
+ long secs,
+ long usecs,
+ dk4_er_t *erp
+)
+{
+ fd_set wfds;
+ struct timeval to;
+#if DK4_HAVE_SSIZE_T
+ ssize_t bwr;
+#else
+ int bwr;
+#endif
+ int res;
+ int back = DK4_SOCKET_RESULT_FAILED;
+
+ if ((INVALID_SOCKET != sock) && (NULL != buf) && (NULL != pszbuf)) {
+ if (0 < *pszbuf) {
+#if DK4_HAVE_SSIZE_T
+ if ((dk4_um_t)(*pszbuf) <= (dk4_um_t)(SIZE_MAX / 2))
+#else
+ if ((dk4_um_t)(*pszbuf) <= (dk4_um_t)(INT_MAX))
+#endif
+ {
+ if ((0L != secs) || (0L != usecs)) {
+ /*
+ Timeout, check writability.
+ */
+ FD_ZERO(&wfds);
+ FD_SET(sock, &wfds);
+ to.tv_sec = secs;
+ to.tv_usec = usecs;
+ dk4socket_error_reset();
+ res = select(((int)sock + 1), NULL, &wfds, NULL, &to);
+ if (0 < res) {
+ if (FD_ISSET(sock, &wfds)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ /* Timeout */
+ dk4error_set_simple_error_code(erp, DK4_E_SOCKET_TIMEOUT);
+ }
+ } else {
+#if DK4_ON_WINDOWS
+ if (SOCKET_ERROR == res)
+#else
+ if (-1 == res)
+#endif
+ {
+ /* select error */
+ dk4socket_error_report(erp, DK4_E_SOCKET_SELECT);
+ }
+ else
+ {
+ /* Timeout */
+ dk4error_set_simple_error_code(erp, DK4_E_SOCKET_TIMEOUT);
+ }
+ }
+ } else {
+ /*
+ No timeout, can continue sending immediately.
+ */
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ }
+ if (DK4_SOCKET_RESULT_SUCCESS == back) {
+ back = DK4_SOCKET_RESULT_FAILED;
+ /*
+ Really send.
+ */
+ dk4socket_error_reset();
+#if DK4_ON_WINDOWS
+ bwr = send(sock, buf, (int)(*pszbuf), flags);
+#else
+ bwr = send(sock, buf, *pszbuf, flags);
+#endif
+ if (0 <= bwr) {
+ if ((size_t)bwr == *pszbuf) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ back = DK4_SOCKET_RESULT_IN_PROGRESS;
+ }
+ *pszbuf = (size_t)bwr;
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_SEND);
+ *pszbuf = 0;
+ }
+ } else {
+ *pszbuf = 0;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ *pszbuf = 0;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ *pszbuf = 0;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ if (NULL != pszbuf) { *pszbuf = 0; }
+ }
+ return back;
+}
+
+
+
+int
+dk4socket_recv(
+ dk4_socket_t sock,
+ void *buf,
+ size_t *pszbuf,
+ int flags,
+ long secs,
+ long usecs,
+ dk4_er_t *erp
+)
+{
+ fd_set rfds;
+ struct timeval to;
+#if DK4_HAVE_SSIZE_T
+ ssize_t bwr;
+#else
+ int bwr;
+#endif
+ int res;
+ int back = DK4_SOCKET_RESULT_FAILED;
+
+ if ((INVALID_SOCKET != sock) && (NULL != buf) && (NULL != pszbuf)) {
+ if (0 < *pszbuf) {
+#if DK4_HAVE_SSIZE_T
+ if ((dk4_um_t)(*pszbuf) <= (dk4_um_t)(SIZE_MAX / 2))
+#else
+ if ((dk4_um_t)(*pszbuf) <= (dk4_um_t)(INT_MAX))
+#endif
+ {
+ if ((0L != secs) || (0L != usecs)) {
+ /*
+ Timeout, check readability.
+ */
+ FD_ZERO(&rfds);
+ FD_SET(sock, &rfds);
+ to.tv_sec = secs;
+ to.tv_usec = usecs;
+ dk4socket_error_reset();
+ res = select(((int)sock + 1), &rfds, NULL, NULL, &to);
+ if (0 < res) {
+ if (FD_ISSET(sock, &rfds)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SOCKET_TIMEOUT);
+ }
+ } else {
+#if DK4_ON_WINDOWS
+ if (SOCKET_ERROR == res)
+#else
+ if (-1 == res)
+#endif
+ {
+ dk4socket_error_report(erp, DK4_E_SOCKET_SELECT);
+ }
+ else
+ {
+ dk4error_set_simple_error_code(erp, DK4_E_SOCKET_TIMEOUT);
+ }
+ }
+ } else {
+ /*
+ No timeout.
+ */
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ }
+ if (DK4_SOCKET_RESULT_SUCCESS == back) {
+ back = DK4_SOCKET_RESULT_FAILED;
+ dk4socket_error_reset();
+#if DK4_ON_WINDOWS
+ bwr = recv(sock, buf, (int)(*pszbuf), flags);
+#else
+ bwr = recv(sock, buf, *pszbuf, flags);
+#endif
+ if (0 <= bwr) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ *pszbuf = (size_t)bwr;
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_RECV);
+ *pszbuf = 0;
+ }
+ }
+ }
+ else
+ {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4sock21.c b/support/dktools/dk4sock21.c
new file mode 100644
index 0000000000..ae8b91f689
--- /dev/null
+++ b/support/dktools/dk4sock21.c
@@ -0,0 +1,326 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sock21.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4sock21.c The dk4sock21 module.
+*/
+
+
+#line 10 "dk4sock21.ctr"
+
+#include "dk4sock.h"
+
+#if DK4_HAVE_LIMITS_H
+#ifndef LIMITS_H_INCLUDED
+#include <limits.h>
+#define LIMITS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDINT_H
+#ifndef STDINT_H_INCLUDED
+#if defined(__cplusplus) && (!defined(__STDC_LIMIT_MACROS))
+#define __STDC_LIMIT_MACROS 1
+#endif
+#if defined(__cplusplus) && (!defined(__STDC_CONSTANT_MACROS))
+#define __STDC_CONSTANT_MACROS 1
+#endif
+#include <stdint.h>
+#define STDINT_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4numco.h"
+
+
+
+
+
+#line 45 "dk4sock21.ctr"
+
+
+
+
+int
+dk4socket_sendto(
+ dk4_socket_t sock,
+ const void *buf,
+ size_t *pszbuf,
+ int flags,
+ const struct sockaddr *saddr,
+ size_t addrlen,
+ long secs,
+ long usecs,
+ dk4_er_t *erp
+)
+{
+ fd_set wfds;
+ struct timeval to;
+#if DK4_HAVE_SSIZE_T
+ ssize_t bwr;
+#else
+ int bwr;
+#endif
+ int res;
+ int back = DK4_SOCKET_RESULT_FAILED;
+
+ if (
+ (INVALID_SOCKET != sock) && (NULL != buf) && (NULL != pszbuf)
+ && (NULL != saddr) && (0 < addrlen)
+ )
+ {
+ if ((0 < *pszbuf) && (0 != dk4socket_correct_addr_lgt(saddr, &addrlen))) {
+#if DK4_HAVE_SSIZE_T
+ if ((dk4_um_t)(*pszbuf) <= (dk4_um_t)(SIZE_MAX / 2))
+#else
+ if ((dk4_um_t)(*pszbuf) <= (dk4_um_t)(INT_MAX))
+#endif
+ {
+ if ((0L != secs) || (0L != usecs)) {
+ /*
+ Timeout, check writability.
+ */
+ FD_ZERO(&wfds);
+ FD_SET(sock, &wfds);
+ to.tv_sec = secs;
+ to.tv_usec = usecs;
+ dk4socket_error_reset();
+ res = select(((int)sock + 1), NULL, &wfds, NULL, &to);
+ if (0 < res) {
+ if (FD_ISSET(sock, &wfds)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ /* Timeout */
+ dk4error_set_simple_error_code(erp, DK4_E_SOCKET_TIMEOUT);
+ }
+ } else {
+#if DK4_ON_WINDOWS
+ if (SOCKET_ERROR == res)
+#else
+ if (-1 == res)
+#endif
+ {
+ /* select error */
+ dk4socket_error_report(erp, DK4_E_SOCKET_SELECT);
+ }
+ else
+ {
+ /* Timeout */
+ dk4error_set_simple_error_code(erp, DK4_E_SOCKET_TIMEOUT);
+ }
+ }
+ } else {
+ /*
+ No timeout, can continue sending immediately.
+ */
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ }
+ if (DK4_SOCKET_RESULT_SUCCESS == back) {
+ (void)dk4socket_correct_addr_lgt(saddr, &addrlen);
+ back = DK4_SOCKET_RESULT_FAILED;
+ /*
+ Really send.
+ */
+ dk4socket_error_reset();
+#if DK4_ON_WINDOWS
+#if DK4_HAVE_SOCKLEN_T
+ bwr = sendto(
+ sock, buf, (int)(*pszbuf), flags, saddr, (socklen_t)addrlen
+ );
+#else
+ bwr = sendto(
+ sock, buf, (int)(*pszbuf), flags, saddr, (int)addrlen
+ );
+#endif
+#else
+#if DK4_HAVE_SOCKLEN_T
+ bwr = sendto(
+ sock, buf, *pszbuf, flags, saddr, (socklen_t)addrlen
+ );
+#else
+ bwr = sendto(
+ sock, buf, *pszbuf, flags, saddr, (int)addrlen
+ );
+#endif
+#endif
+ if (0 <= bwr) {
+ if ((size_t)bwr == *pszbuf) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ back = DK4_SOCKET_RESULT_IN_PROGRESS;
+ }
+ *pszbuf = (size_t)bwr;
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_SEND);
+ *pszbuf = 0;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4socket_recvfrom(
+ dk4_socket_t sock,
+ void *buf,
+ size_t *pszbuf,
+ int flags,
+ struct sockaddr *saddr,
+ size_t *paddrlen,
+ long secs,
+ long usecs,
+ dk4_er_t *erp
+)
+{
+ fd_set rfds;
+ struct timeval to;
+#if DK4_HAVE_SSIZE_T
+ ssize_t bwr;
+#else
+ int bwr;
+#endif
+#if DK4_HAVE_SOCKLEN_T
+ socklen_t peersize;
+#else
+ int peersize;
+#endif
+ int res;
+ int back = DK4_SOCKET_RESULT_FAILED;
+
+ if (
+ (INVALID_SOCKET != sock) && (NULL != buf) && (NULL != pszbuf)
+ && (NULL != saddr) && (NULL != paddrlen)
+ )
+ {
+ if ((0 < *pszbuf) && (0 < *paddrlen)) {
+#if DK4_HAVE_SSIZE_T
+ if ((dk4_um_t)(*pszbuf) <= (dk4_um_t)(SIZE_MAX / 2))
+#else
+ if ((dk4_um_t)(*pszbuf) <= (dk4_um_t)(INT_MAX))
+#endif
+ {
+ if ((0L != secs) || (0L != usecs)) {
+ /*
+ Timeout, check readability.
+ */
+ FD_ZERO(&rfds);
+ FD_SET(sock, &rfds);
+ to.tv_sec = secs;
+ to.tv_usec = usecs;
+ dk4socket_error_reset();
+ res = select(((int)sock + 1), &rfds, NULL, NULL, &to);
+ if (0 < res) {
+ if (FD_ISSET(sock, &rfds)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SOCKET_TIMEOUT);
+ }
+ } else {
+#if DK4_ON_WINDOWS
+ if (SOCKET_ERROR == res)
+#else
+ if (-1 == res)
+#endif
+ {
+ dk4socket_error_report(erp, DK4_E_SOCKET_SELECT);
+ }
+ else
+ {
+ dk4error_set_simple_error_code(erp, DK4_E_SOCKET_TIMEOUT);
+ }
+ }
+ } else {
+ /*
+ No timeout.
+ */
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ }
+ if (DK4_SOCKET_RESULT_SUCCESS == back) {
+ back = DK4_SOCKET_RESULT_FAILED;
+#if DK4_HAVE_SOCKLEN_T
+ peersize = (socklen_t)(*paddrlen);
+#else
+ peersize = (int)(*paddrlen);
+#endif
+ dk4socket_error_reset();
+#if DK4_ON_WINDOWS
+ bwr = recvfrom(
+ sock, buf, (int)(*pszbuf), flags, saddr, &peersize
+ );
+#else
+ bwr = recvfrom(
+ sock, buf, *pszbuf, flags, saddr, &peersize
+ );
+#endif
+ if (0 <= bwr) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ *pszbuf = (size_t)bwr;
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_RECV);
+ *pszbuf = 0;
+ }
+ *paddrlen = (size_t)peersize;
+ }
+ }
+ else
+ {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4sock21.ctr b/support/dktools/dk4sock21.ctr
new file mode 100644
index 0000000000..c778b67d9d
--- /dev/null
+++ b/support/dktools/dk4sock21.ctr
@@ -0,0 +1,293 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4sock.h"
+
+#if DK4_HAVE_LIMITS_H
+#ifndef LIMITS_H_INCLUDED
+#include <limits.h>
+#define LIMITS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDINT_H
+#ifndef STDINT_H_INCLUDED
+#if defined(__cplusplus) && (!defined(__STDC_LIMIT_MACROS))
+#define __STDC_LIMIT_MACROS 1
+#endif
+#if defined(__cplusplus) && (!defined(__STDC_CONSTANT_MACROS))
+#define __STDC_CONSTANT_MACROS 1
+#endif
+#include <stdint.h>
+#define STDINT_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4numco.h"
+
+
+
+$!trace-include
+
+
+
+
+int
+dk4socket_sendto(
+ dk4_socket_t sock,
+ const void *buf,
+ size_t *pszbuf,
+ int flags,
+ const struct sockaddr *saddr,
+ size_t addrlen,
+ long secs,
+ long usecs,
+ dk4_er_t *erp
+)
+{
+ fd_set wfds;
+ struct timeval to;
+#if DK4_HAVE_SSIZE_T
+ ssize_t bwr;
+#else
+ int bwr;
+#endif
+ int res;
+ int back = DK4_SOCKET_RESULT_FAILED;
+
+ if (
+ (INVALID_SOCKET != sock) && (NULL != buf) && (NULL != pszbuf)
+ && (NULL != saddr) && (0 < addrlen)
+ )
+ {
+ if ((0 < *pszbuf) && (0 != dk4socket_correct_addr_lgt(saddr, &addrlen))) {
+#if DK4_HAVE_SSIZE_T
+ if ((dk4_um_t)(*pszbuf) <= (dk4_um_t)(SIZE_MAX / 2))
+#else
+ if ((dk4_um_t)(*pszbuf) <= (dk4_um_t)(INT_MAX))
+#endif
+ {
+ if ((0L != secs) || (0L != usecs)) {
+ /*
+ Timeout, check writability.
+ */
+ FD_ZERO(&wfds);
+ FD_SET(sock, &wfds);
+ to.tv_sec = secs;
+ to.tv_usec = usecs;
+ dk4socket_error_reset();
+ res = select(((int)sock + 1), NULL, &wfds, NULL, &to);
+ if (0 < res) {
+ if (FD_ISSET(sock, &wfds)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ /* Timeout */
+ dk4error_set_simple_error_code(erp, DK4_E_SOCKET_TIMEOUT);
+ }
+ } else {
+#if DK4_ON_WINDOWS
+ if (SOCKET_ERROR == res)
+#else
+ if (-1 == res)
+#endif
+ {
+ /* select error */
+ dk4socket_error_report(erp, DK4_E_SOCKET_SELECT);
+ }
+ else
+ {
+ /* Timeout */
+ dk4error_set_simple_error_code(erp, DK4_E_SOCKET_TIMEOUT);
+ }
+ }
+ } else {
+ /*
+ No timeout, can continue sending immediately.
+ */
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ }
+ if (DK4_SOCKET_RESULT_SUCCESS == back) {
+ (void)dk4socket_correct_addr_lgt(saddr, &addrlen);
+ back = DK4_SOCKET_RESULT_FAILED;
+ /*
+ Really send.
+ */
+ dk4socket_error_reset();
+#if DK4_ON_WINDOWS
+#if DK4_HAVE_SOCKLEN_T
+ bwr = sendto(
+ sock, buf, (int)(*pszbuf), flags, saddr, (socklen_t)addrlen
+ );
+#else
+ bwr = sendto(
+ sock, buf, (int)(*pszbuf), flags, saddr, (int)addrlen
+ );
+#endif
+#else
+#if DK4_HAVE_SOCKLEN_T
+ bwr = sendto(
+ sock, buf, *pszbuf, flags, saddr, (socklen_t)addrlen
+ );
+#else
+ bwr = sendto(
+ sock, buf, *pszbuf, flags, saddr, (int)addrlen
+ );
+#endif
+#endif
+ if (0 <= bwr) {
+ if ((size_t)bwr == *pszbuf) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ back = DK4_SOCKET_RESULT_IN_PROGRESS;
+ }
+ *pszbuf = (size_t)bwr;
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_SEND);
+ *pszbuf = 0;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4socket_recvfrom(
+ dk4_socket_t sock,
+ void *buf,
+ size_t *pszbuf,
+ int flags,
+ struct sockaddr *saddr,
+ size_t *paddrlen,
+ long secs,
+ long usecs,
+ dk4_er_t *erp
+)
+{
+ fd_set rfds;
+ struct timeval to;
+#if DK4_HAVE_SSIZE_T
+ ssize_t bwr;
+#else
+ int bwr;
+#endif
+#if DK4_HAVE_SOCKLEN_T
+ socklen_t peersize;
+#else
+ int peersize;
+#endif
+ int res;
+ int back = DK4_SOCKET_RESULT_FAILED;
+
+ if (
+ (INVALID_SOCKET != sock) && (NULL != buf) && (NULL != pszbuf)
+ && (NULL != saddr) && (NULL != paddrlen)
+ )
+ {
+ if ((0 < *pszbuf) && (0 < *paddrlen)) {
+#if DK4_HAVE_SSIZE_T
+ if ((dk4_um_t)(*pszbuf) <= (dk4_um_t)(SIZE_MAX / 2))
+#else
+ if ((dk4_um_t)(*pszbuf) <= (dk4_um_t)(INT_MAX))
+#endif
+ {
+ if ((0L != secs) || (0L != usecs)) {
+ /*
+ Timeout, check readability.
+ */
+ FD_ZERO(&rfds);
+ FD_SET(sock, &rfds);
+ to.tv_sec = secs;
+ to.tv_usec = usecs;
+ dk4socket_error_reset();
+ res = select(((int)sock + 1), &rfds, NULL, NULL, &to);
+ if (0 < res) {
+ if (FD_ISSET(sock, &rfds)) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SOCKET_TIMEOUT);
+ }
+ } else {
+#if DK4_ON_WINDOWS
+ if (SOCKET_ERROR == res)
+#else
+ if (-1 == res)
+#endif
+ {
+ dk4socket_error_report(erp, DK4_E_SOCKET_SELECT);
+ }
+ else
+ {
+ dk4error_set_simple_error_code(erp, DK4_E_SOCKET_TIMEOUT);
+ }
+ }
+ } else {
+ /*
+ No timeout.
+ */
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ }
+ if (DK4_SOCKET_RESULT_SUCCESS == back) {
+ back = DK4_SOCKET_RESULT_FAILED;
+#if DK4_HAVE_SOCKLEN_T
+ peersize = (socklen_t)(*paddrlen);
+#else
+ peersize = (int)(*paddrlen);
+#endif
+ dk4socket_error_reset();
+#if DK4_ON_WINDOWS
+ bwr = recvfrom(
+ sock, buf, (int)(*pszbuf), flags, saddr, &peersize
+ );
+#else
+ bwr = recvfrom(
+ sock, buf, *pszbuf, flags, saddr, &peersize
+ );
+#endif
+ if (0 <= bwr) {
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ *pszbuf = (size_t)bwr;
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_RECV);
+ *pszbuf = 0;
+ }
+ *paddrlen = (size_t)peersize;
+ }
+ }
+ else
+ {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4sock22.c b/support/dktools/dk4sock22.c
new file mode 100644
index 0000000000..12013493cd
--- /dev/null
+++ b/support/dktools/dk4sock22.c
@@ -0,0 +1,139 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sock22.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4sock22.c The dk4sock22 module.
+*/
+
+
+#line 10 "dk4sock22.ctr"
+
+
+#include "dk4sock.h"
+#include "dk4mem.h"
+
+
+
+
+
+#line 18 "dk4sock22.ctr"
+
+
+
+dk4_socket_set_t *
+dk4socket_set_new(
+ size_t max,
+ dk4_er_t *erp
+)
+{
+ dk4_socket_set_t *back = NULL;
+ dk4_socket_t *ps;
+ size_t i;
+
+ if (0 < max) {
+ if ((SIZE_MAX / sizeof(dk4_socket_t)) >= max) {
+ back = dk4mem_new(dk4_socket_set_t,1,erp);
+ if (NULL != back) {
+ back->szMax = max;
+ back->szUsed = 0;
+ back->pSockets = dk4mem_new(dk4_socket_t,max,erp);
+ if (NULL != back->pSockets) {
+ ps = back->pSockets;
+ i = max;
+ while (i--) { *(ps++) = INVALID_SOCKET; }
+ } else {
+ dk4mem_free(back);
+ back = NULL;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+void
+dk4socket_set_delete(
+ dk4_socket_set_t *set,
+ dk4_er_t *erp
+)
+{
+ if (NULL != set) {
+ if (NULL != set->pSockets) {
+ dk4mem_release(set->pSockets);
+ }
+ dk4mem_free(set);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+}
+
+
+
+void
+dk4socket_set_close(
+ dk4_socket_set_t *set,
+ dk4_er_t *erp
+)
+{
+ size_t i;
+
+ if (NULL != set) {
+ if (NULL != set->pSockets) {
+ for (i = 0; i < set->szUsed; i++) {
+ if (INVALID_SOCKET != (set->pSockets)[i]) {
+#if 0
+ /* 2015-06-22 Setting SO_REUSEADDR or SO_REUSEPORT must
+ follow immediately on socket()
+ */
+ (void)dk4socket_option_set_reuse((set->pSockets)[i], 1, NULL);
+#endif
+ (void)dk4socket_close((set->pSockets)[i], erp);
+ (set->pSockets)[i] = INVALID_SOCKET;
+ }
+ }
+ dk4socket_set_delete(set, erp);
+ } else {
+ dk4mem_free(set);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+}
+
diff --git a/support/dktools/dk4sock22.ctr b/support/dktools/dk4sock22.ctr
new file mode 100644
index 0000000000..06809a82bd
--- /dev/null
+++ b/support/dktools/dk4sock22.ctr
@@ -0,0 +1,106 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+
+#include "dk4sock.h"
+#include "dk4mem.h"
+
+
+
+$!trace-include
+
+
+
+dk4_socket_set_t *
+dk4socket_set_new(
+ size_t max,
+ dk4_er_t *erp
+)
+{
+ dk4_socket_set_t *back = NULL;
+ dk4_socket_t *ps;
+ size_t i;
+
+ if (0 < max) {
+ if ((SIZE_MAX / sizeof(dk4_socket_t)) >= max) {
+ back = dk4mem_new(dk4_socket_set_t,1,erp);
+ if (NULL != back) {
+ back->szMax = max;
+ back->szUsed = 0;
+ back->pSockets = dk4mem_new(dk4_socket_t,max,erp);
+ if (NULL != back->pSockets) {
+ ps = back->pSockets;
+ i = max;
+ while (i--) { *(ps++) = INVALID_SOCKET; }
+ } else {
+ dk4mem_free(back);
+ back = NULL;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+void
+dk4socket_set_delete(
+ dk4_socket_set_t *set,
+ dk4_er_t *erp
+)
+{
+ if (NULL != set) {
+ if (NULL != set->pSockets) {
+ dk4mem_release(set->pSockets);
+ }
+ dk4mem_free(set);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+}
+
+
+
+void
+dk4socket_set_close(
+ dk4_socket_set_t *set,
+ dk4_er_t *erp
+)
+{
+ size_t i;
+
+ if (NULL != set) {
+ if (NULL != set->pSockets) {
+ for (i = 0; i < set->szUsed; i++) {
+ if (INVALID_SOCKET != (set->pSockets)[i]) {
+#if 0
+ /* 2015-06-22 Setting SO_REUSEADDR or SO_REUSEPORT must
+ follow immediately on socket()
+ */
+ (void)dk4socket_option_set_reuse((set->pSockets)[i], 1, NULL);
+#endif
+ (void)dk4socket_close((set->pSockets)[i], erp);
+ (set->pSockets)[i] = INVALID_SOCKET;
+ }
+ }
+ dk4socket_set_delete(set, erp);
+ } else {
+ dk4mem_free(set);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+}
+
diff --git a/support/dktools/dk4sock23.c b/support/dktools/dk4sock23.c
new file mode 100644
index 0000000000..a65cfea596
--- /dev/null
+++ b/support/dktools/dk4sock23.c
@@ -0,0 +1,223 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sock23.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4sock23.c The dk4sock23 module.
+*/
+
+
+#line 8 "dk4sock23.ctr"
+
+
+#include "dk4sock.h"
+#include "dk4mem.h"
+
+
+
+
+
+#line 16 "dk4sock23.ctr"
+
+
+
+dk4_socket_set_t *
+dk4socket_set_server_directly(
+ unsigned short portno,
+ int backlog,
+ int local,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ struct sockaddr_in6 soin6;
+#endif
+ struct sockaddr_in soin4;
+ dk4_socket_set_t *back = NULL;
+ size_t max;
+ int res;
+#if DK4_HAVE_SETSOCKOPT && (defined(SO_REUSEPORT) || defined(SO_REUSEADDR))
+ int opt;
+#endif
+
+ if (0 < portno) {
+ max = 1;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ max++;
+#endif
+ back = dk4socket_set_new(max, erp);
+ if (NULL != back) {
+ /* IPv4 address
+ */
+ DK4_MEMRES(&soin4, sizeof(soin4));
+ soin4.sin_family = AF_INET;
+ soin4.sin_port = dk4socket_htons(portno);
+ if (0 != local) {
+ soin4.sin_addr.s_addr = dk4socket_htonl(INADDR_LOOPBACK);
+ } else {
+ soin4.sin_addr.s_addr = dk4socket_htonl(INADDR_ANY);
+ }
+ (back->pSockets)[back->szUsed] = dk4socket_open(
+ AF_INET, SOCK_STREAM, 0, erp
+ );
+ if (INVALID_SOCKET != (back->pSockets)[back->szUsed]) {
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEPORT)
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_REUSEPORT, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) {
+
+#line 66 "dk4sock23.ctr"
+ }
+#else
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEADDR)
+
+
+#line 70 "dk4sock23.ctr"
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_REUSEADDR, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) {
+
+#line 76 "dk4sock23.ctr"
+ }
+#else
+
+
+#line 79 "dk4sock23.ctr"
+#endif
+#endif
+
+ res = dk4socket_bind(
+ (back->pSockets)[back->szUsed],
+ (struct sockaddr *)(&soin4),
+ sizeof(soin4),
+ erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ res = dk4socket_listen(
+ (back->pSockets)[back->szUsed],
+ backlog,
+ erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ back->szUsed += 1;
+ } else {
+ (void)dk4socket_close((back->pSockets)[back->szUsed], NULL);
+ (back->pSockets)[back->szUsed] = INVALID_SOCKET;
+ }
+ } else {
+ (void)dk4socket_close((back->pSockets)[back->szUsed], NULL);
+ (back->pSockets)[back->szUsed] = INVALID_SOCKET;
+ }
+ }
+ /* IPv6 address if available
+ */
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ DK4_MEMRES(&soin6, sizeof(soin6));
+ soin6.sin6_family = AF_INET6;
+ if (0 != local) { soin6.sin6_addr.s6_addr[15] = 0x01; }
+ soin6.sin6_port = dk4socket_htons(portno);
+ (back->pSockets)[back->szUsed] = dk4socket_open(
+ AF_INET6, SOCK_STREAM, 0, erp
+ );
+ if (INVALID_SOCKET != (back->pSockets)[back->szUsed]) {
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEPORT)
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_REUSEPORT, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) {
+
+#line 123 "dk4sock23.ctr"
+ }
+#else
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEADDR)
+
+
+#line 127 "dk4sock23.ctr"
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_REUSEADDR, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) {
+
+#line 133 "dk4sock23.ctr"
+ }
+#else
+
+
+#line 136 "dk4sock23.ctr"
+#endif
+#endif
+ res = dk4socket_bind(
+ (back->pSockets)[back->szUsed],
+ (struct sockaddr *)(&soin6),
+ sizeof(soin6),
+ erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ res = dk4socket_listen(
+ (back->pSockets)[back->szUsed],
+ backlog,
+ erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ back->szUsed += 1;
+ } else {
+ (void)dk4socket_close((back->pSockets)[back->szUsed], NULL);
+ (back->pSockets)[back->szUsed] = INVALID_SOCKET;
+ }
+ } else {
+ (void)dk4socket_close((back->pSockets)[back->szUsed], NULL);
+ (back->pSockets)[back->szUsed] = INVALID_SOCKET;
+ }
+ }
+#endif
+ if (0 == back->szUsed) {
+ dk4socket_set_delete(back, NULL);
+ back = NULL;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4sock23.ctr b/support/dktools/dk4sock23.ctr
new file mode 100644
index 0000000000..8e711a175a
--- /dev/null
+++ b/support/dktools/dk4sock23.ctr
@@ -0,0 +1,172 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+%% module
+
+
+#include "dk4sock.h"
+#include "dk4mem.h"
+
+
+
+$!trace-include
+
+
+
+dk4_socket_set_t *
+dk4socket_set_server_directly(
+ unsigned short portno,
+ int backlog,
+ int local,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ struct sockaddr_in6 soin6;
+#endif
+ struct sockaddr_in soin4;
+ dk4_socket_set_t *back = NULL;
+ size_t max;
+ int res;
+#if DK4_HAVE_SETSOCKOPT && (defined(SO_REUSEPORT) || defined(SO_REUSEADDR))
+ int opt;
+#endif
+
+ if (0 < portno) {
+ max = 1;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ max++;
+#endif
+ back = dk4socket_set_new(max, erp);
+ if (NULL != back) {
+ /* IPv4 address
+ */
+ DK4_MEMRES(&soin4, sizeof(soin4));
+ soin4.sin_family = AF_INET;
+ soin4.sin_port = dk4socket_htons(portno);
+ if (0 != local) {
+ soin4.sin_addr.s_addr = dk4socket_htonl(INADDR_LOOPBACK);
+ } else {
+ soin4.sin_addr.s_addr = dk4socket_htonl(INADDR_ANY);
+ }
+ (back->pSockets)[back->szUsed] = dk4socket_open(
+ AF_INET, SOCK_STREAM, 0, erp
+ );
+ if (INVALID_SOCKET != (back->pSockets)[back->szUsed]) {
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEPORT)
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_REUSEPORT, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) { $? "! failed to reuse port number"
+ }
+#else
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEADDR)
+ $? ". SO_REUSEADDR"
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_REUSEADDR, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) { $? "! failed to reuse address"
+ }
+#else
+ $? ". neither SO_REUSEPORT nor SO_REUSEADDR"
+#endif
+#endif
+
+ res = dk4socket_bind(
+ (back->pSockets)[back->szUsed],
+ (struct sockaddr *)(&soin4),
+ sizeof(soin4),
+ erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ res = dk4socket_listen(
+ (back->pSockets)[back->szUsed],
+ backlog,
+ erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ back->szUsed += 1;
+ } else {
+ (void)dk4socket_close((back->pSockets)[back->szUsed], NULL);
+ (back->pSockets)[back->szUsed] = INVALID_SOCKET;
+ }
+ } else {
+ (void)dk4socket_close((back->pSockets)[back->szUsed], NULL);
+ (back->pSockets)[back->szUsed] = INVALID_SOCKET;
+ }
+ }
+ /* IPv6 address if available
+ */
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ DK4_MEMRES(&soin6, sizeof(soin6));
+ soin6.sin6_family = AF_INET6;
+ if (0 != local) { soin6.sin6_addr.s6_addr[15] = 0x01; }
+ soin6.sin6_port = dk4socket_htons(portno);
+ (back->pSockets)[back->szUsed] = dk4socket_open(
+ AF_INET6, SOCK_STREAM, 0, erp
+ );
+ if (INVALID_SOCKET != (back->pSockets)[back->szUsed]) {
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEPORT)
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_REUSEPORT, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) { $? "! failed to reuse port number"
+ }
+#else
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEADDR)
+ $? ". SO_REUSEADDR"
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_REUSEADDR, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) { $? "! failed to reuse address"
+ }
+#else
+ $? ". neither SO_REUSEPORT nor SO_REUSEADDR"
+#endif
+#endif
+ res = dk4socket_bind(
+ (back->pSockets)[back->szUsed],
+ (struct sockaddr *)(&soin6),
+ sizeof(soin6),
+ erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ res = dk4socket_listen(
+ (back->pSockets)[back->szUsed],
+ backlog,
+ erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ back->szUsed += 1;
+ } else {
+ (void)dk4socket_close((back->pSockets)[back->szUsed], NULL);
+ (back->pSockets)[back->szUsed] = INVALID_SOCKET;
+ }
+ } else {
+ (void)dk4socket_close((back->pSockets)[back->szUsed], NULL);
+ (back->pSockets)[back->szUsed] = INVALID_SOCKET;
+ }
+ }
+#endif
+ if (0 == back->szUsed) {
+ dk4socket_set_delete(back, NULL);
+ back = NULL;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4sock24.c b/support/dktools/dk4sock24.c
new file mode 100644
index 0000000000..ac1d6a0453
--- /dev/null
+++ b/support/dktools/dk4sock24.c
@@ -0,0 +1,296 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sock24.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4sock24.c The dk4sock24 module.
+*/
+
+
+#line 9 "dk4sock24.ctr"
+
+#include "dk4sock.h"
+#include "dk4mem.h"
+
+#if DK4_HAVE_GETADDRINFO
+#include "dk4mao8d.h"
+#else
+#include "dk4mai8dus.h"
+#endif
+
+
+
+
+
+#line 22 "dk4sock24.ctr"
+
+
+
+/** Create listener socket set for a local port number.
+ @param servicename Local service name.
+ @param backlog Number of connection requests to queue.
+ @param local Flag: Allow local connections only.
+ @param numeric Flag: Service name is numeric.
+ @param erp Error report, may be NULL.
+ @return Socket set on success, NULL on error.
+*/
+static
+dk4_socket_set_t *
+dk4socket_c8_set_service_num_flag(
+ const char *servicename,
+ int backlog,
+ int local,
+ int numeric,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_GETADDRINFO
+ /* +++++ +getaddrinfo */
+ struct addrinfo hints;
+ struct addrinfo *addri = NULL;
+ struct addrinfo *paddr = NULL;
+ dk4_socket_set_t *back = NULL;
+ size_t numad = 0;
+ int res = 0;
+#if DK4_HAVE_SETSOCKOPT && (defined(SO_REUSEPORT) || defined(SO_REUSEADDR))
+ int opt = 0;
+#endif
+
+
+#line 55 "dk4sock24.ctr"
+ if (NULL != servicename) {
+ DK4_MEMRES(&hints, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = 0;
+ hints.ai_protocol = 0;
+ hints.ai_addrlen = 0;
+ hints.ai_canonname = NULL;
+ hints.ai_addr = NULL;
+ hints.ai_next = NULL;
+ if (0 == local) { hints.ai_flags |= AI_PASSIVE; }
+ if (0 != numeric) { hints.ai_flags |= AI_NUMERICSERV; }
+ res = getaddrinfo(NULL, servicename, &hints, &addri);
+ if ((0 == res) && (NULL != addri)) {
+ paddr = addri;
+ while (NULL != paddr) { numad++; paddr = paddr->ai_next; }
+ if (0 < numad) {
+
+#line 72 "dk4sock24.ctr"
+ paddr = addri;
+ back = dk4socket_set_new(numad, erp);
+ if (NULL != back) {
+ while (NULL != paddr) {
+
+#line 76 "dk4sock24.ctr"
+ (back->pSockets)[back->szUsed] = dk4socket_open(
+ paddr->ai_family, SOCK_STREAM, 0, erp
+ );
+ if (INVALID_SOCKET != (back->pSockets)[back->szUsed]) {
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEPORT)
+
+
+#line 82 "dk4sock24.ctr"
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_REUSEPORT, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) {
+
+#line 88 "dk4sock24.ctr"
+ }
+#else
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEADDR)
+
+
+#line 92 "dk4sock24.ctr"
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_REUSEADDR, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) {
+
+#line 98 "dk4sock24.ctr"
+ }
+#else
+
+
+#line 101 "dk4sock24.ctr"
+#endif
+#endif
+ res = dk4socket_bind(
+ (back->pSockets)[back->szUsed], paddr->ai_addr,
+ paddr->ai_addrlen, erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ res = dk4socket_listen(
+ (back->pSockets)[back->szUsed], backlog, erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ back->szUsed += 1;
+
+
+#line 114 "dk4sock24.ctr"
+ } else {
+
+#line 115 "dk4sock24.ctr"
+ (void)dk4socket_close((back->pSockets)[back->szUsed], NULL);
+ (back->pSockets)[back->szUsed] = INVALID_SOCKET;
+ }
+ } else {
+
+#line 119 "dk4sock24.ctr"
+ (void)dk4socket_close((back->pSockets)[back->szUsed], NULL);
+ (back->pSockets)[back->szUsed] = INVALID_SOCKET;
+ }
+ } else {
+
+#line 123 "dk4sock24.ctr"
+ }
+ paddr = paddr->ai_next;
+ }
+ if (0 == back->szUsed) {
+ dk4socket_set_delete(back, NULL);
+ back = NULL;
+ }
+ }
+ }
+ freeaddrinfo(addri);
+ } else {
+ dk4error_set_idetails(erp, DK4_E_SOCKET_GETADDRLOC, res);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 140 "dk4sock24.ctr"
+ return back;
+ /* ----- +getaddrinfo */
+#else
+ /* +++++ -getaddrinfo */
+ const char *endptr = NULL;
+ dk4_socket_set_t *back = NULL;
+ struct servent *serv = NULL;
+ int iport = 0;
+ int res = 0;
+ unsigned short portno = 0;
+
+
+#line 151 "dk4sock24.ctr"
+ if (NULL != servicename) {
+ res = dk4ma_input_c8_dec_ushort(
+ &portno, servicename, &endptr, 1, NULL
+ );
+ if (0 != res) {
+ back = dk4socket_set_server_directly(portno, backlog, local, erp);
+ } else {
+ dk4socket_error_reset();
+ serv = getservbyname(servicename, NULL);
+ if (NULL != serv) {
+ iport = serv->s_port;
+ dk4socket_swap_bytes_if_not_bigendian((void *)(&iport), sizeof(iport));
+ portno = (unsigned short)iport;
+ back = dk4socket_set_server_directly(portno, backlog, local, erp);
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_GETSERVBYNAME);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 173 "dk4sock24.ctr"
+ return back;
+ /* ----- -getaddrinfo */
+#endif
+}
+
+
+
+dk4_socket_set_t *
+dk4socket_c8_set_server(
+ unsigned short portno,
+ int backlog,
+ int local,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_GETADDRINFO
+ /* +++++ +getaddrinfo */
+ char pnb[16*sizeof(dk4_um_t)];
+ dk4_socket_set_t *back = NULL;
+ int res;
+ if (0 < portno) {
+ res = dk4ma_write_c8_decimal_unsigned(
+ pnb, sizeof(pnb), (dk4_um_t)portno, 0, erp
+ );
+ if (0 != res) {
+ back = dk4socket_c8_set_service_num_flag(
+ pnb, backlog, local, 1, erp
+ );
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- +getaddrinfo */
+#else
+ /* +++++ -getaddrinfo */
+ return (
+ dk4socket_set_server_directly(portno, backlog, local, erp)
+ );
+ /* ----- -getaddrinfo */
+#endif
+}
+
+
+
+dk4_socket_set_t *
+dk4socket_c8_set_service(
+ const char *servicename,
+ int backlog,
+ int local,
+ dk4_er_t *erp
+)
+{
+ return (
+ dk4socket_c8_set_service_num_flag(servicename, backlog, local, 0, erp)
+ );
+}
+
+
+
diff --git a/support/dktools/dk4sock24.ctr b/support/dktools/dk4sock24.ctr
new file mode 100644
index 0000000000..cce68e3b8d
--- /dev/null
+++ b/support/dktools/dk4sock24.ctr
@@ -0,0 +1,232 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% module
+
+#include "dk4sock.h"
+#include "dk4mem.h"
+
+#if DK4_HAVE_GETADDRINFO
+#include "dk4mao8d.h"
+#else
+#include "dk4mai8dus.h"
+#endif
+
+
+
+$!trace-include
+
+
+
+/** Create listener socket set for a local port number.
+ @param servicename Local service name.
+ @param backlog Number of connection requests to queue.
+ @param local Flag: Allow local connections only.
+ @param numeric Flag: Service name is numeric.
+ @param erp Error report, may be NULL.
+ @return Socket set on success, NULL on error.
+*/
+static
+dk4_socket_set_t *
+dk4socket_c8_set_service_num_flag(
+ const char *servicename,
+ int backlog,
+ int local,
+ int numeric,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_GETADDRINFO
+ /* +++++ +getaddrinfo */
+ struct addrinfo hints;
+ struct addrinfo *addri = NULL;
+ struct addrinfo *paddr = NULL;
+ dk4_socket_set_t *back = NULL;
+ size_t numad = 0;
+ int res = 0;
+#if DK4_HAVE_SETSOCKOPT && (defined(SO_REUSEPORT) || defined(SO_REUSEADDR))
+ int opt = 0;
+#endif
+ $? "+ dk4socket_c8_set_service_num_flag"
+ if (NULL != servicename) {
+ DK4_MEMRES(&hints, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = 0;
+ hints.ai_protocol = 0;
+ hints.ai_addrlen = 0;
+ hints.ai_canonname = NULL;
+ hints.ai_addr = NULL;
+ hints.ai_next = NULL;
+ if (0 == local) { hints.ai_flags |= AI_PASSIVE; }
+ if (0 != numeric) { hints.ai_flags |= AI_NUMERICSERV; }
+ res = getaddrinfo(NULL, servicename, &hints, &addri);
+ if ((0 == res) && (NULL != addri)) {
+ paddr = addri;
+ while (NULL != paddr) { numad++; paddr = paddr->ai_next; }
+ if (0 < numad) { $? ". numad = %u", (unsigned)numad
+ paddr = addri;
+ back = dk4socket_set_new(numad, erp);
+ if (NULL != back) {
+ while (NULL != paddr) { $? ". try next address"
+ (back->pSockets)[back->szUsed] = dk4socket_open(
+ paddr->ai_family, SOCK_STREAM, 0, erp
+ );
+ if (INVALID_SOCKET != (back->pSockets)[back->szUsed]) {
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEPORT)
+ $? ". SO_REUSEPORT"
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_REUSEPORT, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) { $? "! failed to reuse port number"
+ }
+#else
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEADDR)
+ $? ". SO_REUSEADDR"
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_REUSEADDR, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) { $? "! failed to reuse address"
+ }
+#else
+ $? ". neither SO_REUSEPORT nor SO_REUSEADDR"
+#endif
+#endif
+ res = dk4socket_bind(
+ (back->pSockets)[back->szUsed], paddr->ai_addr,
+ paddr->ai_addrlen, erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ res = dk4socket_listen(
+ (back->pSockets)[back->szUsed], backlog, erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ back->szUsed += 1;
+ $? ". used = %u", (unsigned)(back->szUsed)
+ } else { $? "! failed to listen"
+ (void)dk4socket_close((back->pSockets)[back->szUsed], NULL);
+ (back->pSockets)[back->szUsed] = INVALID_SOCKET;
+ }
+ } else { $? "! failed to bind address"
+ (void)dk4socket_close((back->pSockets)[back->szUsed], NULL);
+ (back->pSockets)[back->szUsed] = INVALID_SOCKET;
+ }
+ } else { $? "! failed to create socket"
+ }
+ paddr = paddr->ai_next;
+ }
+ if (0 == back->szUsed) {
+ dk4socket_set_delete(back, NULL);
+ back = NULL;
+ }
+ }
+ }
+ freeaddrinfo(addri);
+ } else {
+ dk4error_set_idetails(erp, DK4_E_SOCKET_GETADDRLOC, res);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4socket_c8_set_service_num_flag"
+ return back;
+ /* ----- +getaddrinfo */
+#else
+ /* +++++ -getaddrinfo */
+ const char *endptr = NULL;
+ dk4_socket_set_t *back = NULL;
+ struct servent *serv = NULL;
+ int iport = 0;
+ int res = 0;
+ unsigned short portno = 0;
+ $? "+ dk4socket_c8_set_service_num_flag"
+ if (NULL != servicename) {
+ res = dk4ma_input_c8_dec_ushort(
+ &portno, servicename, &endptr, 1, NULL
+ );
+ if (0 != res) {
+ back = dk4socket_set_server_directly(portno, backlog, local, erp);
+ } else {
+ dk4socket_error_reset();
+ serv = getservbyname(servicename, NULL);
+ if (NULL != serv) {
+ iport = serv->s_port;
+ dk4socket_swap_bytes_if_not_bigendian((void *)(&iport), sizeof(iport));
+ portno = (unsigned short)iport;
+ back = dk4socket_set_server_directly(portno, backlog, local, erp);
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_GETSERVBYNAME);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4socket_c8_set_service_num_flag"
+ return back;
+ /* ----- -getaddrinfo */
+#endif
+}
+
+
+
+dk4_socket_set_t *
+dk4socket_c8_set_server(
+ unsigned short portno,
+ int backlog,
+ int local,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_GETADDRINFO
+ /* +++++ +getaddrinfo */
+ char pnb[16*sizeof(dk4_um_t)];
+ dk4_socket_set_t *back = NULL;
+ int res;
+ if (0 < portno) {
+ res = dk4ma_write_c8_decimal_unsigned(
+ pnb, sizeof(pnb), (dk4_um_t)portno, 0, erp
+ );
+ if (0 != res) {
+ back = dk4socket_c8_set_service_num_flag(
+ pnb, backlog, local, 1, erp
+ );
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- +getaddrinfo */
+#else
+ /* +++++ -getaddrinfo */
+ return (
+ dk4socket_set_server_directly(portno, backlog, local, erp)
+ );
+ /* ----- -getaddrinfo */
+#endif
+}
+
+
+
+dk4_socket_set_t *
+dk4socket_c8_set_service(
+ const char *servicename,
+ int backlog,
+ int local,
+ dk4_er_t *erp
+)
+{
+ return (
+ dk4socket_c8_set_service_num_flag(servicename, backlog, local, 0, erp)
+ );
+}
+
+
+
diff --git a/support/dktools/dk4sock25.c b/support/dktools/dk4sock25.c
new file mode 100644
index 0000000000..e844e4920f
--- /dev/null
+++ b/support/dktools/dk4sock25.c
@@ -0,0 +1,341 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sock25.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4sock25.c The dk4sock25 module.
+*/
+
+
+#line 10 "dk4sock25.ctr"
+
+
+
+#include "dk4sock.h"
+#include "dk4mem.h"
+
+#if DK4_HAVE_GETADDRINFO
+#include "dk4maowd.h"
+#else
+#include "dk4maiwdus.h"
+#endif
+
+#include "dk4rec24.h"
+
+
+
+
+
+#line 27 "dk4sock25.ctr"
+
+
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_ON_WINDOWS
+
+/* +++++ +wchar_t +Windows */
+
+/** Create listener socket set for a local port number.
+ @param servicename Local service name.
+ @param backlog Number of connection requests to queue.
+ @param local Flag: Allow local connections only.
+ @param numeric Flag: Service name is numeric.
+ @param erp Error report, may be NULL.
+ @return Socket set on success, NULL on error.
+*/
+static
+dk4_socket_set_t *
+dk4socket_wc_set_service_num_flag(
+ const wchar_t *servicename,
+ int backlog,
+ int local,
+ int numeric,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_GETADDRINFO
+ /* +++++ +getaddrinfo */
+ ADDRINFOW hints;
+ ADDRINFOW *addri = NULL;
+ ADDRINFOW *paddr = NULL;
+ dk4_socket_set_t *back = NULL;
+ size_t numad = 0;
+ int res = 0;
+#if DK4_HAVE_SETSOCKOPT && (defined(SO_REUSEPORT) || defined(SO_REUSEADDR))
+ int opt = 0;
+#endif
+
+ if (NULL != servicename) {
+ DK4_MEMRES(&hints, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = 0;
+ hints.ai_protocol = 0;
+ hints.ai_addrlen = 0;
+ hints.ai_canonname = NULL;
+ hints.ai_addr = NULL;
+ hints.ai_next = NULL;
+ if (0 == local) { hints.ai_flags |= AI_PASSIVE; }
+ if (0 != numeric) { hints.ai_flags |= AI_NUMERICSERV; }
+ res = GetAddrInfoW(NULL, servicename, &hints, &addri);
+ if ((0 == res) && (NULL != addri)) {
+ paddr = addri;
+ while (NULL != paddr) { numad++; paddr = paddr->ai_next; }
+ if (0 < numad) {
+ paddr = addri;
+ back = dk4socket_set_new(numad, erp);
+ if (NULL != back) {
+ while (NULL != paddr) {
+ (back->pSockets)[back->szUsed] = dk4socket_open(
+ paddr->ai_family, SOCK_STREAM, 0, erp
+ );
+ if (INVALID_SOCKET != (back->pSockets)[back->szUsed]) {
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEPORT)
+
+
+#line 92 "dk4sock25.ctr"
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_REUSEPORT, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) {
+
+#line 98 "dk4sock25.ctr"
+ }
+#else
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEADDR)
+
+
+#line 102 "dk4sock25.ctr"
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_REUSEADDR, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) {
+
+#line 108 "dk4sock25.ctr"
+ }
+#else
+
+
+#line 111 "dk4sock25.ctr"
+#endif
+#endif
+ res = dk4socket_bind(
+ (back->pSockets)[back->szUsed], paddr->ai_addr,
+ paddr->ai_addrlen, erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+#if 0
+ /* Setting SO_REUSEADDR or SO_REUSEPORT must follow
+ immediately on socket().
+ */
+ (void)dk4socket_option_set_reuse(back, 1, NULL);
+#endif
+ res = dk4socket_listen(
+ (back->pSockets)[back->szUsed], backlog, erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ back->szUsed += 1;
+ } else {
+ (void)dk4socket_close((back->pSockets)[back->szUsed], NULL);
+ (back->pSockets)[back->szUsed] = INVALID_SOCKET;
+ }
+ } else {
+ (void)dk4socket_close((back->pSockets)[back->szUsed], NULL);
+ (back->pSockets)[back->szUsed] = INVALID_SOCKET;
+ }
+ }
+ paddr = paddr->ai_next;
+ }
+ if (0 == back->szUsed) {
+ dk4socket_set_delete(back, NULL);
+ back = NULL;
+ }
+ }
+ }
+ FreeAddrInfo(addri);
+ } else {
+ dk4error_set_idetails(erp, DK4_E_SOCKET_GETADDRLOC, res);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- +getaddrinfo */
+#else
+ /* +++++ -getaddrinfo */
+ char asvcn[128];
+ const wchar_t *endptr = NULL;
+ dk4_socket_set_t *back = NULL;
+ struct servent *serv = NULL;
+ int iport = 0;
+ int res = 0;
+ unsigned short portno = 0;
+ if (NULL != servicename) {
+ res = dk4ma_input_wc_dec_ushort(
+ &portno, servicename, &endptr, 1, erp
+ );
+ if (0 != res) {
+ back = dk4socket_set_server_directly(portno, backlog, local, erp);
+ } else {
+ res = dk4recode_wchar_t_to_char(asvcn, sizeof(asvcn), servicename, erp);
+ if (0 != res) {
+ serv = getservbyname(asvcn, NULL);
+ if (NULL != serv) {
+ iport = serv->s_port;
+ dk4socket_swap_bytes_if_not_bigendian((void *)(&iport),sizeof(iport));
+ portno = (unsigned short)iport;
+ back = dk4socket_set_server_directly(portno, backlog, local, erp);
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_GETSERVBYNAME);
+ }
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- -getaddrinfo */
+#endif
+}
+
+
+
+static
+dk4_socket_set_t *
+dk4socket_wc_set_server(
+ unsigned short portno,
+ int backlog,
+ int local,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_GETADDRINFO
+ /* +++++ +getaddrinfo */
+ wchar_t pnb[16*sizeof(dk4_um_t)];
+ dk4_socket_set_t *back = NULL;
+ int res;
+ if (0 < portno) {
+ res = dk4ma_write_wc_decimal_unsigned(
+ pnb, DK4_SIZEOF(pnb,wchar_t), (dk4_um_t)portno, 0, erp
+ );
+ if (0 != res) {
+ back = dk4socket_wc_set_service_num_flag(
+ pnb, backlog, local, 1, erp
+ );
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- +getaddrinfo */
+#else
+ /* +++++ -getaddrinfo */
+ return (
+ dk4socket_set_server_directly(portno, backlog, local, erp)
+ );
+ /* ----- -getaddrinfo */
+#endif
+}
+
+
+
+static
+dk4_socket_set_t *
+dk4socket_wc_set_service(
+ const wchar_t *servicename,
+ int backlog,
+ int local,
+ dk4_er_t *erp
+)
+{
+ return (
+ dk4socket_wc_set_service_num_flag(servicename, backlog, local, 0, erp)
+ );
+}
+
+/* ----- +wchar_t +Windows */
+
+#else
+#error No networking functions using wchar_t host and service names available!
+#endif
+#endif
+
+
+
+
+dk4_socket_set_t *
+dk4socket_set_server(
+ unsigned short portno,
+ int backlog,
+ int local,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (
+ dk4socket_wc_set_server(portno, backlog, local, erp)
+ );
+#else
+ return (
+ dk4socket_c8_set_server(portno, backlog, local, erp)
+ );
+#endif
+}
+
+
+
+dk4_socket_set_t *
+dk4socket_set_service(
+ const dkChar *servicename,
+ int backlog,
+ int local,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (
+ dk4socket_wc_set_service(servicename, backlog, local, erp)
+ );
+#else
+ return (
+ dk4socket_c8_set_service(servicename, backlog, local, erp)
+ );
+#endif
+}
+
+
+
diff --git a/support/dktools/dk4sock25.ctr b/support/dktools/dk4sock25.ctr
new file mode 100644
index 0000000000..f24299cb5a
--- /dev/null
+++ b/support/dktools/dk4sock25.ctr
@@ -0,0 +1,298 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+
+
+#include "dk4sock.h"
+#include "dk4mem.h"
+
+#if DK4_HAVE_GETADDRINFO
+#include "dk4maowd.h"
+#else
+#include "dk4maiwdus.h"
+#endif
+
+#include "dk4rec24.h"
+
+
+
+$!trace-include
+
+
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_ON_WINDOWS
+
+/* +++++ +wchar_t +Windows */
+
+/** Create listener socket set for a local port number.
+ @param servicename Local service name.
+ @param backlog Number of connection requests to queue.
+ @param local Flag: Allow local connections only.
+ @param numeric Flag: Service name is numeric.
+ @param erp Error report, may be NULL.
+ @return Socket set on success, NULL on error.
+*/
+static
+dk4_socket_set_t *
+dk4socket_wc_set_service_num_flag(
+ const wchar_t *servicename,
+ int backlog,
+ int local,
+ int numeric,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_GETADDRINFO
+ /* +++++ +getaddrinfo */
+ ADDRINFOW hints;
+ ADDRINFOW *addri = NULL;
+ ADDRINFOW *paddr = NULL;
+ dk4_socket_set_t *back = NULL;
+ size_t numad = 0;
+ int res = 0;
+#if DK4_HAVE_SETSOCKOPT && (defined(SO_REUSEPORT) || defined(SO_REUSEADDR))
+ int opt = 0;
+#endif
+
+ if (NULL != servicename) {
+ DK4_MEMRES(&hints, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = 0;
+ hints.ai_protocol = 0;
+ hints.ai_addrlen = 0;
+ hints.ai_canonname = NULL;
+ hints.ai_addr = NULL;
+ hints.ai_next = NULL;
+ if (0 == local) { hints.ai_flags |= AI_PASSIVE; }
+ if (0 != numeric) { hints.ai_flags |= AI_NUMERICSERV; }
+ res = GetAddrInfoW(NULL, servicename, &hints, &addri);
+ if ((0 == res) && (NULL != addri)) {
+ paddr = addri;
+ while (NULL != paddr) { numad++; paddr = paddr->ai_next; }
+ if (0 < numad) {
+ paddr = addri;
+ back = dk4socket_set_new(numad, erp);
+ if (NULL != back) {
+ while (NULL != paddr) {
+ (back->pSockets)[back->szUsed] = dk4socket_open(
+ paddr->ai_family, SOCK_STREAM, 0, erp
+ );
+ if (INVALID_SOCKET != (back->pSockets)[back->szUsed]) {
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEPORT)
+ $? ". SO_REUSEPORT"
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_REUSEPORT, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) { $? "! failed to reuse port number"
+ }
+#else
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEADDR)
+ $? ". SO_REUSEADDR"
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_REUSEADDR, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) { $? "! failed to reuse address"
+ }
+#else
+ $? ". neither SO_REUSEPORT nor SO_REUSEADDR"
+#endif
+#endif
+ res = dk4socket_bind(
+ (back->pSockets)[back->szUsed], paddr->ai_addr,
+ paddr->ai_addrlen, erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+#if 0
+ /* Setting SO_REUSEADDR or SO_REUSEPORT must follow
+ immediately on socket().
+ */
+ (void)dk4socket_option_set_reuse(back, 1, NULL);
+#endif
+ res = dk4socket_listen(
+ (back->pSockets)[back->szUsed], backlog, erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ back->szUsed += 1;
+ } else {
+ (void)dk4socket_close((back->pSockets)[back->szUsed], NULL);
+ (back->pSockets)[back->szUsed] = INVALID_SOCKET;
+ }
+ } else {
+ (void)dk4socket_close((back->pSockets)[back->szUsed], NULL);
+ (back->pSockets)[back->szUsed] = INVALID_SOCKET;
+ }
+ }
+ paddr = paddr->ai_next;
+ }
+ if (0 == back->szUsed) {
+ dk4socket_set_delete(back, NULL);
+ back = NULL;
+ }
+ }
+ }
+ FreeAddrInfo(addri);
+ } else {
+ dk4error_set_idetails(erp, DK4_E_SOCKET_GETADDRLOC, res);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- +getaddrinfo */
+#else
+ /* +++++ -getaddrinfo */
+ char asvcn[128];
+ const wchar_t *endptr = NULL;
+ dk4_socket_set_t *back = NULL;
+ struct servent *serv = NULL;
+ int iport = 0;
+ int res = 0;
+ unsigned short portno = 0;
+ if (NULL != servicename) {
+ res = dk4ma_input_wc_dec_ushort(
+ &portno, servicename, &endptr, 1, erp
+ );
+ if (0 != res) {
+ back = dk4socket_set_server_directly(portno, backlog, local, erp);
+ } else {
+ res = dk4recode_wchar_t_to_char(asvcn, sizeof(asvcn), servicename, erp);
+ if (0 != res) {
+ serv = getservbyname(asvcn, NULL);
+ if (NULL != serv) {
+ iport = serv->s_port;
+ dk4socket_swap_bytes_if_not_bigendian((void *)(&iport),sizeof(iport));
+ portno = (unsigned short)iport;
+ back = dk4socket_set_server_directly(portno, backlog, local, erp);
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_GETSERVBYNAME);
+ }
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- -getaddrinfo */
+#endif
+}
+
+
+
+static
+dk4_socket_set_t *
+dk4socket_wc_set_server(
+ unsigned short portno,
+ int backlog,
+ int local,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_GETADDRINFO
+ /* +++++ +getaddrinfo */
+ wchar_t pnb[16*sizeof(dk4_um_t)];
+ dk4_socket_set_t *back = NULL;
+ int res;
+ if (0 < portno) {
+ res = dk4ma_write_wc_decimal_unsigned(
+ pnb, DK4_SIZEOF(pnb,wchar_t), (dk4_um_t)portno, 0, erp
+ );
+ if (0 != res) {
+ back = dk4socket_wc_set_service_num_flag(
+ pnb, backlog, local, 1, erp
+ );
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- +getaddrinfo */
+#else
+ /* +++++ -getaddrinfo */
+ return (
+ dk4socket_set_server_directly(portno, backlog, local, erp)
+ );
+ /* ----- -getaddrinfo */
+#endif
+}
+
+
+
+static
+dk4_socket_set_t *
+dk4socket_wc_set_service(
+ const wchar_t *servicename,
+ int backlog,
+ int local,
+ dk4_er_t *erp
+)
+{
+ return (
+ dk4socket_wc_set_service_num_flag(servicename, backlog, local, 0, erp)
+ );
+}
+
+/* ----- +wchar_t +Windows */
+
+#else
+#error No networking functions using wchar_t host and service names available!
+#endif
+#endif
+
+
+
+
+dk4_socket_set_t *
+dk4socket_set_server(
+ unsigned short portno,
+ int backlog,
+ int local,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (
+ dk4socket_wc_set_server(portno, backlog, local, erp)
+ );
+#else
+ return (
+ dk4socket_c8_set_server(portno, backlog, local, erp)
+ );
+#endif
+}
+
+
+
+dk4_socket_set_t *
+dk4socket_set_service(
+ const dkChar *servicename,
+ int backlog,
+ int local,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (
+ dk4socket_wc_set_service(servicename, backlog, local, erp)
+ );
+#else
+ return (
+ dk4socket_c8_set_service(servicename, backlog, local, erp)
+ );
+#endif
+}
+
+
+
diff --git a/support/dktools/dk4sock26.c b/support/dktools/dk4sock26.c
new file mode 100644
index 0000000000..793b5dff0a
--- /dev/null
+++ b/support/dktools/dk4sock26.c
@@ -0,0 +1,289 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sock26.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4sock26.c The dk4sock26 module.
+*/
+
+
+#line 8 "dk4sock26.ctr"
+
+
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4mem.h"
+#include "dk4sock.h"
+#include "dk4str8.h"
+#include "dk4mai8dsz.h"
+
+
+
+
+
+#line 22 "dk4sock26.ctr"
+
+
+
+#if TRACE_DEBUG
+
+static
+void
+dk4socket_c8_debug_allowed_peer(dk4_allowed_peer_t *peerptr)
+{
+ FILE *fipo;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ unsigned char *ucptr;
+ size_t i;
+ size_t pass;
+#endif
+ unsigned long ul1, ul2;
+ fipo = dktrace_file();
+
+ if (NULL != fipo) {
+ switch (peerptr->af) {
+ case AF_INET : {
+ ul1 = (peerptr->data).ipv4.ad.s_addr;
+ ul2 = (peerptr->data).ipv4.ma.s_addr;
+ ul1 = dk4socket_ntohl(ul1);
+ ul2 = dk4socket_ntohl(ul2);
+ fprintf(
+ fipo,
+ "Address/Mask: %lu.%lu.%lu.%lu/%lu.%lu.%lu.%lu\n",
+ ((ul1 >> 24) & 0x000000FFUL),
+ ((ul1 >> 16) & 0x000000FFUL),
+ ((ul1 >> 8) & 0x000000FFUL),
+ ((ul1 ) & 0x000000FFUL),
+ ((ul2 >> 24) & 0x000000FFUL),
+ ((ul2 >> 16) & 0x000000FFUL),
+ ((ul2 >> 8) & 0x000000FFUL),
+ ((ul2 ) & 0x000000FFUL)
+ );
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ fputs("Address/Mask: ", fipo);
+ for (pass = 0; pass < 2; pass++) {
+ if (0 != pass) {
+ fputc('/', fipo);
+ ucptr = &((peerptr->data).ipv6.ma.s6_addr[0]);
+ } else {
+ ucptr = &((peerptr->data).ipv6.ad.s6_addr[0]);
+ }
+ for (i = 0; i < 16; i++) {
+ if ((0 != i) && (0 == (i % 2))) {
+ fputc(':', fipo);
+ }
+ fprintf(fipo, "%02x", *(ucptr++));
+ }
+ }
+ fputc('\n', fipo);
+ } break;
+#endif
+ }
+ }
+}
+
+#endif
+
+
+
+int
+dk4socket_c8_get_allowed_peer(
+ dk4_allowed_peer_t *peerptr,
+ const char *str,
+ dk4_er_t *erp
+)
+{
+ char mycp[128];
+ IN_ADDR in4;
+ IN_ADDR ma4;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ IN6_ADDR in6;
+ IN6_ADDR ma6;
+#endif
+ char *maptr;
+ const char *endptr = NULL;
+ size_t bitno = 0;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ size_t i = 0;
+#endif
+ unsigned long nm4 = 0UL;
+ int back = DK4_SOCKET_RESULT_FAILED;
+ int af = AF_UNSPEC;
+ int res = 0;
+
+
+#line 113 "dk4sock26.ctr"
+ if ((NULL != peerptr) && (NULL != str)) {
+ if (0 != dk4str8_cpy_s(mycp, sizeof(mycp), str, erp)) {
+ maptr = dk4str8_chr(mycp, '/');
+ if (NULL != maptr) { *(maptr++) = '\0'; }
+ back = dk4socket_c8_inet_pton( &in4, sizeof(in4), AF_INET, mycp, erp);
+ if (DK4_SOCKET_RESULT_SUCCESS == back) { af = AF_INET; }
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ else {
+ back = dk4socket_c8_inet_pton( &in6, sizeof(in6), AF_INET6, mycp, erp);
+ if (DK4_SOCKET_RESULT_SUCCESS == back) { af = AF_INET6; }
+ }
+#endif
+ if (DK4_SOCKET_RESULT_SUCCESS == back) {
+ back = DK4_SOCKET_RESULT_FAILED;
+ if (NULL != maptr) {
+
+#line 128 "dk4sock26.ctr"
+ res = dk4ma_input_c8_dec_size_t(&bitno, maptr, &endptr, 1, NULL);
+ if (0 != res) {
+
+#line 130 "dk4sock26.ctr"
+ /* Bit number was specified.
+ */
+ switch (af) {
+ case AF_INET : {
+ if (0 != dk4socket_mask_bits(&nm4, bitno, erp)) {
+ ma4.s_addr = dk4socket_htonl(nm4);
+ DK4_MEMCPY(&((peerptr->data).ipv4.ad),&in4,sizeof(in4));
+ DK4_MEMCPY(&((peerptr->data).ipv4.ma),&ma4,sizeof(ma4));
+ peerptr->af = af;
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else {
+
+#line 141 "dk4sock26.ctr"
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ back = dk4socket_mask6_bits(&ma6, bitno, erp);
+ if (DK4_SOCKET_RESULT_SUCCESS == back) {
+ DK4_MEMCPY(&((peerptr->data).ipv6.ad),&in6,sizeof(in6));
+ DK4_MEMCPY(&((peerptr->data).ipv6.ma),&ma6,sizeof(ma6));
+ peerptr->af = af;
+ } else {
+
+#line 151 "dk4sock26.ctr"
+ }
+ } break;
+#endif
+ default : {
+ /* Must not happen */
+ } break;
+ }
+ } else {
+
+#line 159 "dk4sock26.ctr"
+ /* Not a bit number, probably an address.
+ */
+ switch (af) {
+ case AF_INET : {
+ back = dk4socket_c8_inet_pton(
+ &ma4, sizeof(ma4), AF_INET, maptr, erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == back) {
+ DK4_MEMCPY(&((peerptr->data).ipv4.ad),&in4,sizeof(in4));
+ DK4_MEMCPY(&((peerptr->data).ipv4.ma),&ma4,sizeof(ma4));
+ peerptr->af = af;
+ } else {
+
+#line 171 "dk4sock26.ctr"
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ back = dk4socket_c8_inet_pton(
+ &ma6, sizeof(ma6), AF_INET6, maptr, erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == back) {
+ DK4_MEMCPY(&((peerptr->data).ipv6.ad),&in6,sizeof(in6));
+ DK4_MEMCPY(&((peerptr->data).ipv6.ma),&ma6,sizeof(ma6));
+ peerptr->af = af;
+ } else {
+
+#line 183 "dk4sock26.ctr"
+ }
+ } break;
+#endif
+ }
+ }
+ } else {
+
+#line 189 "dk4sock26.ctr"
+ /* Host was specified
+ */
+ switch (af) {
+ case AF_INET : {
+ ma4.s_addr = dk4socket_htonl(0xFFFFFFFFUL);
+ DK4_MEMCPY(&((peerptr->data).ipv4.ad), &in4, sizeof(in4));
+ DK4_MEMCPY(&((peerptr->data).ipv4.ma), &ma4, sizeof(ma4));
+ peerptr->af = af;
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ for (i = 0; i < 16; i++) { ma6.s6_addr[i] = 0xFF; }
+ DK4_MEMCPY(&((peerptr->data).ipv6.ad), &in6, sizeof(in6));
+ DK4_MEMCPY(&((peerptr->data).ipv6.ma), &ma6, sizeof(ma6));
+ peerptr->af = af;
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } break;
+#endif
+ default : {
+ /* Must not happen */
+ } break;
+ }
+ }
+ } else {
+
+#line 214 "dk4sock26.ctr"
+ }
+ } else {
+
+#line 216 "dk4sock26.ctr"
+ }
+ } else {
+
+#line 218 "dk4sock26.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+#if TRACE_DEBUG
+ if (DK4_SOCKET_RESULT_SUCCESS == back) {
+ dk4socket_c8_debug_allowed_peer(peerptr);
+ }
+#endif
+
+
+#line 226 "dk4sock26.ctr"
+ return back;
+}
+
diff --git a/support/dktools/dk4sock26.ctr b/support/dktools/dk4sock26.ctr
new file mode 100644
index 0000000000..6a26fd6f81
--- /dev/null
+++ b/support/dktools/dk4sock26.ctr
@@ -0,0 +1,228 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+%% module
+
+
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4mem.h"
+#include "dk4sock.h"
+#include "dk4str8.h"
+#include "dk4mai8dsz.h"
+
+
+
+$!trace-include
+
+
+
+#if TRACE_DEBUG
+
+static
+void
+dk4socket_c8_debug_allowed_peer(dk4_allowed_peer_t *peerptr)
+{
+ FILE *fipo;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ unsigned char *ucptr;
+ size_t i;
+ size_t pass;
+#endif
+ unsigned long ul1, ul2;
+ fipo = dktrace_file();
+
+ if (NULL != fipo) {
+ switch (peerptr->af) {
+ case AF_INET : {
+ ul1 = (peerptr->data).ipv4.ad.s_addr;
+ ul2 = (peerptr->data).ipv4.ma.s_addr;
+ ul1 = dk4socket_ntohl(ul1);
+ ul2 = dk4socket_ntohl(ul2);
+ fprintf(
+ fipo,
+ "Address/Mask: %lu.%lu.%lu.%lu/%lu.%lu.%lu.%lu\n",
+ ((ul1 >> 24) & 0x000000FFUL),
+ ((ul1 >> 16) & 0x000000FFUL),
+ ((ul1 >> 8) & 0x000000FFUL),
+ ((ul1 ) & 0x000000FFUL),
+ ((ul2 >> 24) & 0x000000FFUL),
+ ((ul2 >> 16) & 0x000000FFUL),
+ ((ul2 >> 8) & 0x000000FFUL),
+ ((ul2 ) & 0x000000FFUL)
+ );
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ fputs("Address/Mask: ", fipo);
+ for (pass = 0; pass < 2; pass++) {
+ if (0 != pass) {
+ fputc('/', fipo);
+ ucptr = &((peerptr->data).ipv6.ma.s6_addr[0]);
+ } else {
+ ucptr = &((peerptr->data).ipv6.ad.s6_addr[0]);
+ }
+ for (i = 0; i < 16; i++) {
+ if ((0 != i) && (0 == (i % 2))) {
+ fputc(':', fipo);
+ }
+ fprintf(fipo, "%02x", *(ucptr++));
+ }
+ }
+ fputc('\n', fipo);
+ } break;
+#endif
+ }
+ }
+}
+
+#endif
+
+
+
+int
+dk4socket_c8_get_allowed_peer(
+ dk4_allowed_peer_t *peerptr,
+ const char *str,
+ dk4_er_t *erp
+)
+{
+ char mycp[128];
+ IN_ADDR in4;
+ IN_ADDR ma4;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ IN6_ADDR in6;
+ IN6_ADDR ma6;
+#endif
+ char *maptr;
+ const char *endptr = NULL;
+ size_t bitno = 0;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ size_t i = 0;
+#endif
+ unsigned long nm4 = 0UL;
+ int back = DK4_SOCKET_RESULT_FAILED;
+ int af = AF_UNSPEC;
+ int res = 0;
+ $? "+ dk4socket_c8_get_allowed_peer \"%!8s\"", str
+ if ((NULL != peerptr) && (NULL != str)) {
+ if (0 != dk4str8_cpy_s(mycp, sizeof(mycp), str, erp)) {
+ maptr = dk4str8_chr(mycp, '/');
+ if (NULL != maptr) { *(maptr++) = '\0'; }
+ back = dk4socket_c8_inet_pton( &in4, sizeof(in4), AF_INET, mycp, erp);
+ if (DK4_SOCKET_RESULT_SUCCESS == back) { af = AF_INET; }
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ else {
+ back = dk4socket_c8_inet_pton( &in6, sizeof(in6), AF_INET6, mycp, erp);
+ if (DK4_SOCKET_RESULT_SUCCESS == back) { af = AF_INET6; }
+ }
+#endif
+ if (DK4_SOCKET_RESULT_SUCCESS == back) {
+ back = DK4_SOCKET_RESULT_FAILED;
+ if (NULL != maptr) { $? ". mask"
+ res = dk4ma_input_c8_dec_size_t(&bitno, maptr, &endptr, 1, NULL);
+ if (0 != res) { $? ". mask by number of bits"
+ /* Bit number was specified.
+ */
+ switch (af) {
+ case AF_INET : {
+ if (0 != dk4socket_mask_bits(&nm4, bitno, erp)) {
+ ma4.s_addr = dk4socket_htonl(nm4);
+ DK4_MEMCPY(&((peerptr->data).ipv4.ad),&in4,sizeof(in4));
+ DK4_MEMCPY(&((peerptr->data).ipv4.ma),&ma4,sizeof(ma4));
+ peerptr->af = af;
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } else { $? "! out of range"
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ back = dk4socket_mask6_bits(&ma6, bitno, erp);
+ if (DK4_SOCKET_RESULT_SUCCESS == back) {
+ DK4_MEMCPY(&((peerptr->data).ipv6.ad),&in6,sizeof(in6));
+ DK4_MEMCPY(&((peerptr->data).ipv6.ma),&ma6,sizeof(ma6));
+ peerptr->af = af;
+ } else { $? "! out of range"
+ }
+ } break;
+#endif
+ default : {
+ /* Must not happen */
+ } break;
+ }
+ } else { $? ". mask address"
+ /* Not a bit number, probably an address.
+ */
+ switch (af) {
+ case AF_INET : {
+ back = dk4socket_c8_inet_pton(
+ &ma4, sizeof(ma4), AF_INET, maptr, erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == back) {
+ DK4_MEMCPY(&((peerptr->data).ipv4.ad),&in4,sizeof(in4));
+ DK4_MEMCPY(&((peerptr->data).ipv4.ma),&ma4,sizeof(ma4));
+ peerptr->af = af;
+ } else { $? "! out of range"
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ back = dk4socket_c8_inet_pton(
+ &ma6, sizeof(ma6), AF_INET6, maptr, erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == back) {
+ DK4_MEMCPY(&((peerptr->data).ipv6.ad),&in6,sizeof(in6));
+ DK4_MEMCPY(&((peerptr->data).ipv6.ma),&ma6,sizeof(ma6));
+ peerptr->af = af;
+ } else { $? "! out of range"
+ }
+ } break;
+#endif
+ }
+ }
+ } else { $? ". no mask"
+ /* Host was specified
+ */
+ switch (af) {
+ case AF_INET : {
+ ma4.s_addr = dk4socket_htonl(0xFFFFFFFFUL);
+ DK4_MEMCPY(&((peerptr->data).ipv4.ad), &in4, sizeof(in4));
+ DK4_MEMCPY(&((peerptr->data).ipv4.ma), &ma4, sizeof(ma4));
+ peerptr->af = af;
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ for (i = 0; i < 16; i++) { ma6.s6_addr[i] = 0xFF; }
+ DK4_MEMCPY(&((peerptr->data).ipv6.ad), &in6, sizeof(in6));
+ DK4_MEMCPY(&((peerptr->data).ipv6.ma), &ma6, sizeof(ma6));
+ peerptr->af = af;
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } break;
+#endif
+ default : {
+ /* Must not happen */
+ } break;
+ }
+ }
+ } else { $? "! address invalid"
+ }
+ } else { $? "! string too long"
+ }
+ } else { $? "! args"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+#if TRACE_DEBUG
+ if (DK4_SOCKET_RESULT_SUCCESS == back) {
+ dk4socket_c8_debug_allowed_peer(peerptr);
+ }
+#endif
+ $? "- dk4socket_c8_get_allowed_peer %d", back
+ return back;
+}
+
diff --git a/support/dktools/dk4sock27.c b/support/dktools/dk4sock27.c
new file mode 100644
index 0000000000..7a65e34eaf
--- /dev/null
+++ b/support/dktools/dk4sock27.c
@@ -0,0 +1,215 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sock27.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4sock27.c The dk4sock27 module.
+*/
+
+
+#line 11 "dk4sock27.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4mem.h"
+#include "dk4sock.h"
+#include "dk4str8.h"
+#include "dk4strw.h"
+#include "dk4mai8dsz.h"
+#include "dk4maiwdsz.h"
+
+
+
+
+
+#line 25 "dk4sock27.ctr"
+
+
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_ON_WINDOWS
+
+
+int
+dk4socket_wc_get_allowed_peer(
+ dk4_allowed_peer_t *peerptr,
+ const wchar_t *str,
+ dk4_er_t *erp
+)
+{
+ wchar_t mycp[128];
+ IN_ADDR in4;
+ IN_ADDR ma4;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ IN6_ADDR in6;
+ IN6_ADDR ma6;
+#endif
+ wchar_t *maptr;
+ const wchar_t *endptr = NULL;
+ size_t bitno = 0;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ size_t i = 0;
+#endif
+ unsigned long nm4 = 0UL;
+ int back = DK4_SOCKET_RESULT_FAILED;
+ int af = AF_UNSPEC;
+ int res = 0;
+ if ((NULL != peerptr) && (NULL != str)) {
+ if (0 != dk4strw_cpy_s(mycp, DK4_SIZEOF(mycp,wchar_t), str, erp)) {
+ maptr = dk4strw_chr(mycp, L'/');
+ if (NULL != maptr) { *(maptr++) = L'\0'; }
+ back = dk4socket_wc_inet_pton(&in4, sizeof(in4), AF_INET, mycp, erp);
+ if (DK4_SOCKET_RESULT_SUCCESS == back) { af = AF_INET; }
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ else {
+ back = dk4socket_wc_inet_pton(&in6, sizeof(in6), AF_INET6, mycp, erp);
+ if (DK4_SOCKET_RESULT_SUCCESS == back) { af = AF_INET6; }
+ }
+#endif
+ if (DK4_SOCKET_RESULT_SUCCESS == back) {
+ back = DK4_SOCKET_RESULT_FAILED;
+ if (NULL != maptr) {
+ res = dk4ma_input_wc_dec_size_t(&bitno, maptr, &endptr, 1, NULL);
+ if (0 != res) {
+ /* Bit number
+ */
+ switch (af) {
+ case AF_INET : {
+ if (0 != dk4socket_mask_bits(&nm4, bitno, erp)) {
+ ma4.s_addr = dk4socket_htonl(nm4);
+ DK4_MEMCPY(&((peerptr->data).ipv4.ad),&in4,sizeof(in4));
+ DK4_MEMCPY(&((peerptr->data).ipv4.ma),&ma4,sizeof(ma4));
+ peerptr->af = af;
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ back = dk4socket_mask6_bits(&ma6, bitno, erp);
+ if (DK4_SOCKET_RESULT_SUCCESS == back) {
+ DK4_MEMCPY(&((peerptr->data).ipv6.ad),&in6,sizeof(in6));
+ DK4_MEMCPY(&((peerptr->data).ipv6.ma),&ma6,sizeof(ma6));
+ peerptr->af = af;
+ }
+ } break;
+#endif
+ default : {
+ }
+ }
+ } else {
+ /* Mask as address
+ */
+ switch (af) {
+ case AF_INET : {
+ back = dk4socket_wc_inet_pton(
+ &ma4, sizeof(ma4), AF_INET, maptr, erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == back) {
+ DK4_MEMCPY(&((peerptr->data).ipv4.ad),&in4,sizeof(in4));
+ DK4_MEMCPY(&((peerptr->data).ipv4.ma),&ma4,sizeof(ma4));
+ peerptr->af = af;
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ back = dk4socket_wc_inet_pton(
+ &ma6, sizeof(ma6), AF_INET6, maptr, erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == back) {
+ DK4_MEMCPY(&((peerptr->data).ipv6.ad),&in6,sizeof(in6));
+ DK4_MEMCPY(&((peerptr->data).ipv6.ma),&ma6,sizeof(ma6));
+ peerptr->af = af;
+ }
+ } break;
+#endif
+ }
+ }
+ } else {
+ /* Host
+ */
+ switch (af) {
+ case AF_INET : {
+ ma4.s_addr = dk4socket_htonl(0xFFFFFFFFUL);
+ DK4_MEMCPY(&((peerptr->data).ipv4.ad), &in4, sizeof(in4));
+ DK4_MEMCPY(&((peerptr->data).ipv4.ma), &ma4, sizeof(ma4));
+ peerptr->af = af;
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ for (i = 0; i < 16; i++) { ma6.s6_addr[i] = 0xFF; }
+ DK4_MEMCPY(&((peerptr->data).ipv6.ad), &in6, sizeof(in6));
+ DK4_MEMCPY(&((peerptr->data).ipv6.ma), &ma6, sizeof(ma6));
+ peerptr->af = af;
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } break;
+#endif
+ default : {
+ /* Must not happen */
+ } break;
+ }
+ }
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+#else
+#error No networking functions using wchar_t host and service names available!
+#endif
+#endif
+
+
+int
+dk4socket_get_allowed_peer(
+ dk4_allowed_peer_t *peerptr,
+ const dkChar *str,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (
+ dk4socket_wc_get_allowed_peer(peerptr, str, erp)
+ );
+#else
+ return (
+ dk4socket_c8_get_allowed_peer(peerptr, str, erp)
+ );
+#endif
+}
+
diff --git a/support/dktools/dk4sock27.ctr b/support/dktools/dk4sock27.ctr
new file mode 100644
index 0000000000..f63fdb21a7
--- /dev/null
+++ b/support/dktools/dk4sock27.ctr
@@ -0,0 +1,183 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4mem.h"
+#include "dk4sock.h"
+#include "dk4str8.h"
+#include "dk4strw.h"
+#include "dk4mai8dsz.h"
+#include "dk4maiwdsz.h"
+
+
+
+$!trace-include
+
+
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_ON_WINDOWS
+
+
+int
+dk4socket_wc_get_allowed_peer(
+ dk4_allowed_peer_t *peerptr,
+ const wchar_t *str,
+ dk4_er_t *erp
+)
+{
+ wchar_t mycp[128];
+ IN_ADDR in4;
+ IN_ADDR ma4;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ IN6_ADDR in6;
+ IN6_ADDR ma6;
+#endif
+ wchar_t *maptr;
+ const wchar_t *endptr = NULL;
+ size_t bitno = 0;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ size_t i = 0;
+#endif
+ unsigned long nm4 = 0UL;
+ int back = DK4_SOCKET_RESULT_FAILED;
+ int af = AF_UNSPEC;
+ int res = 0;
+ if ((NULL != peerptr) && (NULL != str)) {
+ if (0 != dk4strw_cpy_s(mycp, DK4_SIZEOF(mycp,wchar_t), str, erp)) {
+ maptr = dk4strw_chr(mycp, L'/');
+ if (NULL != maptr) { *(maptr++) = L'\0'; }
+ back = dk4socket_wc_inet_pton(&in4, sizeof(in4), AF_INET, mycp, erp);
+ if (DK4_SOCKET_RESULT_SUCCESS == back) { af = AF_INET; }
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ else {
+ back = dk4socket_wc_inet_pton(&in6, sizeof(in6), AF_INET6, mycp, erp);
+ if (DK4_SOCKET_RESULT_SUCCESS == back) { af = AF_INET6; }
+ }
+#endif
+ if (DK4_SOCKET_RESULT_SUCCESS == back) {
+ back = DK4_SOCKET_RESULT_FAILED;
+ if (NULL != maptr) {
+ res = dk4ma_input_wc_dec_size_t(&bitno, maptr, &endptr, 1, NULL);
+ if (0 != res) {
+ /* Bit number
+ */
+ switch (af) {
+ case AF_INET : {
+ if (0 != dk4socket_mask_bits(&nm4, bitno, erp)) {
+ ma4.s_addr = dk4socket_htonl(nm4);
+ DK4_MEMCPY(&((peerptr->data).ipv4.ad),&in4,sizeof(in4));
+ DK4_MEMCPY(&((peerptr->data).ipv4.ma),&ma4,sizeof(ma4));
+ peerptr->af = af;
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ back = dk4socket_mask6_bits(&ma6, bitno, erp);
+ if (DK4_SOCKET_RESULT_SUCCESS == back) {
+ DK4_MEMCPY(&((peerptr->data).ipv6.ad),&in6,sizeof(in6));
+ DK4_MEMCPY(&((peerptr->data).ipv6.ma),&ma6,sizeof(ma6));
+ peerptr->af = af;
+ }
+ } break;
+#endif
+ default : {
+ }
+ }
+ } else {
+ /* Mask as address
+ */
+ switch (af) {
+ case AF_INET : {
+ back = dk4socket_wc_inet_pton(
+ &ma4, sizeof(ma4), AF_INET, maptr, erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == back) {
+ DK4_MEMCPY(&((peerptr->data).ipv4.ad),&in4,sizeof(in4));
+ DK4_MEMCPY(&((peerptr->data).ipv4.ma),&ma4,sizeof(ma4));
+ peerptr->af = af;
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ back = dk4socket_wc_inet_pton(
+ &ma6, sizeof(ma6), AF_INET6, maptr, erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == back) {
+ DK4_MEMCPY(&((peerptr->data).ipv6.ad),&in6,sizeof(in6));
+ DK4_MEMCPY(&((peerptr->data).ipv6.ma),&ma6,sizeof(ma6));
+ peerptr->af = af;
+ }
+ } break;
+#endif
+ }
+ }
+ } else {
+ /* Host
+ */
+ switch (af) {
+ case AF_INET : {
+ ma4.s_addr = dk4socket_htonl(0xFFFFFFFFUL);
+ DK4_MEMCPY(&((peerptr->data).ipv4.ad), &in4, sizeof(in4));
+ DK4_MEMCPY(&((peerptr->data).ipv4.ma), &ma4, sizeof(ma4));
+ peerptr->af = af;
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ for (i = 0; i < 16; i++) { ma6.s6_addr[i] = 0xFF; }
+ DK4_MEMCPY(&((peerptr->data).ipv6.ad), &in6, sizeof(in6));
+ DK4_MEMCPY(&((peerptr->data).ipv6.ma), &ma6, sizeof(ma6));
+ peerptr->af = af;
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } break;
+#endif
+ default : {
+ /* Must not happen */
+ } break;
+ }
+ }
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+#else
+#error No networking functions using wchar_t host and service names available!
+#endif
+#endif
+
+
+int
+dk4socket_get_allowed_peer(
+ dk4_allowed_peer_t *peerptr,
+ const dkChar *str,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (
+ dk4socket_wc_get_allowed_peer(peerptr, str, erp)
+ );
+#else
+ return (
+ dk4socket_c8_get_allowed_peer(peerptr, str, erp)
+ );
+#endif
+}
+
diff --git a/support/dktools/dk4sock28.c b/support/dktools/dk4sock28.c
new file mode 100644
index 0000000000..025d0095b6
--- /dev/null
+++ b/support/dktools/dk4sock28.c
@@ -0,0 +1,268 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sock28.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4sock28.c The dk4sock28 module.
+*/
+
+
+#line 10 "dk4sock28.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4sock.h"
+#include "dk4sto.h"
+
+
+
+
+
+#line 20 "dk4sock28.ctr"
+
+
+
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+
+/** Compare IPv6 address structures.
+ @param left Left address in comparison.
+ @param mask Network mask to use, may be NULL.
+ @param right Right address in comparison.
+ @return -1, 0 or 1 if l<r, l==r or l>r.
+*/
+static
+int
+dk4socket_compare_in6_addr3(
+ const struct in6_addr *left,
+ const struct in6_addr *mask,
+ const struct in6_addr *right
+)
+{
+ const unsigned char *ucl;
+ const unsigned char *ucm;
+ const unsigned char *ucr;
+ unsigned char ul;
+ unsigned char ur;
+ size_t i;
+
+ int back = 0;
+ ucl = &(left->s6_addr[0]);
+ ucm = &(mask->s6_addr[0]);
+ ucr = &(right->s6_addr[0]);
+ for (i = 0; ((16 > i) && (0 == back)); i++) {
+ ul = ucl[i];
+ ur = ucr[i];
+ if (NULL != mask) {
+ ul &= ucm[i];
+ ur &= ucm[i];
+ }
+ if (ul > ur) {
+ back = 1;
+ } else {
+ if (ul < ur) {
+ back = -1;
+ }
+ }
+ }
+ return back;
+}
+
+#endif
+
+
+
+int
+dk4socket_allowed_peer_compare(
+ const void *pl,
+ const void *pr,
+ int cr
+)
+{
+ const dk4_allowed_peer_t *ppl;
+ const dk4_allowed_peer_t *ppr;
+ const struct sockaddr *pso;
+ const struct sockaddr_in *ps4;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ const struct sockaddr_in6 *ps6;
+#endif
+ unsigned long ul1;
+ unsigned long ul2;
+ unsigned long ul3;
+ int back = 0;
+
+
+#line 91 "dk4sock28.ctr"
+ if (NULL != pl) {
+ if (NULL != pr) {
+ switch (cr) {
+ case 1: {
+
+#line 95 "dk4sock28.ctr"
+ ppl = (const dk4_allowed_peer_t *)pl;
+ pso = (const struct sockaddr *)pr;
+
+
+#line 98 "dk4sock28.ctr"
+ if (ppl->af < pso->sa_family) {
+
+#line 99 "dk4sock28.ctr"
+ back = -1;
+ } else {
+ if (ppl->af > pso->sa_family) {
+
+#line 102 "dk4sock28.ctr"
+ back = 1;
+ }
+ }
+ if (0 == back) {
+
+#line 106 "dk4sock28.ctr"
+ switch (ppl->af) {
+ case AF_INET : {
+
+#line 108 "dk4sock28.ctr"
+ ul1 = (ppl->data).ipv4.ad.s_addr;
+ ul3 = (ppl->data).ipv4.ma.s_addr;
+ ps4 = (const struct sockaddr_in *)pso;
+ ul2 = ps4->sin_addr.s_addr;
+ ul1 = dk4socket_ntohl(ul1);
+ ul2 = dk4socket_ntohl(ul2);
+ ul3 = dk4socket_ntohl(ul3);
+
+
+#line 116 "dk4sock28.ctr"
+
+
+#line 117 "dk4sock28.ctr"
+
+
+#line 118 "dk4sock28.ctr"
+ ul1 &= ul3;
+ ul2 &= ul3;
+
+
+#line 121 "dk4sock28.ctr"
+
+
+#line 122 "dk4sock28.ctr"
+ if (ul1 > ul2) {
+ back = 1;
+ } else {
+ if (ul1 < ul2) {
+ back = -1;
+ }
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+
+#line 132 "dk4sock28.ctr"
+ ps6 = (const struct sockaddr_in6 *)pso;
+ back = dk4socket_compare_in6_addr3(
+ &((ppl->data).ipv6.ad),
+ &((ppl->data).ipv6.ma),
+ &(ps6->sin6_addr)
+ );
+ } break;
+#endif
+ }
+ }
+ } break;
+ default : {
+
+#line 144 "dk4sock28.ctr"
+ ppl = (const dk4_allowed_peer_t *)pl;
+ ppr = (const dk4_allowed_peer_t *)pr;
+ if (ppl->af < ppr->af) {
+ back = -1;
+ } else {
+ if (ppl->af > ppr->af) {
+ back = 1;
+ }
+ }
+ if (0 == back) {
+ switch (ppl->af) {
+ case AF_INET : {
+ ul1 = (ppl->data).ipv4.ad.s_addr;
+ ul2 = (ppr->data).ipv4.ad.s_addr;
+ ul1 = dk4socket_ntohl(ul1);
+ ul2 = dk4socket_ntohl(ul2);
+ if (ul1 > ul2) {
+ back = 1;
+ } else {
+ if (ul1 < ul2) {
+ back = -1;
+ }
+ }
+ ul1 = (ppl->data).ipv4.ma.s_addr;
+ ul2 = (ppr->data).ipv4.ma.s_addr;
+ ul1 = dk4socket_ntohl(ul1);
+ ul2 = dk4socket_ntohl(ul2);
+ if (ul1 > ul2) {
+ back = 1;
+ } else {
+ if (ul1 < ul2) {
+ back = -1;
+ }
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ back = dk4socket_compare_in6_addr3(
+ &((ppl->data).ipv6.ad),
+ NULL,
+ &((ppr->data).ipv6.ad)
+ );
+ if (0 == back) {
+ back = dk4socket_compare_in6_addr3(
+ &((ppl->data).ipv6.ma),
+ NULL,
+ &((ppr->data).ipv6.ma)
+ );
+ }
+ } break;
+#endif
+ }
+ }
+ } break;
+ }
+ } else { back= 1; }
+ } else {
+ if (NULL != pr) { back = -1; }
+ }
+
+#line 203 "dk4sock28.ctr"
+ return back;
+}
+
diff --git a/support/dktools/dk4sock28.ctr b/support/dktools/dk4sock28.ctr
new file mode 100644
index 0000000000..e54365d4be
--- /dev/null
+++ b/support/dktools/dk4sock28.ctr
@@ -0,0 +1,205 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4sock.h"
+#include "dk4sto.h"
+
+
+
+$!trace-include
+
+
+
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+
+/** Compare IPv6 address structures.
+ @param left Left address in comparison.
+ @param mask Network mask to use, may be NULL.
+ @param right Right address in comparison.
+ @return -1, 0 or 1 if l<r, l==r or l>r.
+*/
+static
+int
+dk4socket_compare_in6_addr3(
+ const struct in6_addr *left,
+ const struct in6_addr *mask,
+ const struct in6_addr *right
+)
+{
+ const unsigned char *ucl;
+ const unsigned char *ucm;
+ const unsigned char *ucr;
+ unsigned char ul;
+ unsigned char ur;
+ size_t i;
+
+ int back = 0;
+ ucl = &(left->s6_addr[0]);
+ ucm = &(mask->s6_addr[0]);
+ ucr = &(right->s6_addr[0]);
+ for (i = 0; ((16 > i) && (0 == back)); i++) {
+ ul = ucl[i];
+ ur = ucr[i];
+ if (NULL != mask) {
+ ul &= ucm[i];
+ ur &= ucm[i];
+ }
+ if (ul > ur) {
+ back = 1;
+ } else {
+ if (ul < ur) {
+ back = -1;
+ }
+ }
+ }
+ return back;
+}
+
+#endif
+
+
+
+int
+dk4socket_allowed_peer_compare(
+ const void *pl,
+ const void *pr,
+ int cr
+)
+{
+ const dk4_allowed_peer_t *ppl;
+ const dk4_allowed_peer_t *ppr;
+ const struct sockaddr *pso;
+ const struct sockaddr_in *ps4;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ const struct sockaddr_in6 *ps6;
+#endif
+ unsigned long ul1;
+ unsigned long ul2;
+ unsigned long ul3;
+ int back = 0;
+ $? "+ dk4socket_allowed_peer_compare %d", cr
+ if (NULL != pl) {
+ if (NULL != pr) {
+ switch (cr) {
+ case 1: { $? ". peer /sockaddr"
+ ppl = (const dk4_allowed_peer_t *)pl;
+ pso = (const struct sockaddr *)pr;
+ $? ". ppl->af = %d pso->af = %d", ppl->af, pso->sa_family
+ if (ppl->af < pso->sa_family) { $? ". families differ"
+ back = -1;
+ } else {
+ if (ppl->af > pso->sa_family) { $? ". families differ"
+ back = 1;
+ }
+ }
+ if (0 == back) { $? ". same family"
+ switch (ppl->af) {
+ case AF_INET : { $? ". IPv4"
+ ul1 = (ppl->data).ipv4.ad.s_addr;
+ ul3 = (ppl->data).ipv4.ma.s_addr;
+ ps4 = (const struct sockaddr_in *)pso;
+ ul2 = ps4->sin_addr.s_addr;
+ ul1 = dk4socket_ntohl(ul1);
+ ul2 = dk4socket_ntohl(ul2);
+ ul3 = dk4socket_ntohl(ul3);
+ $? ". ul1 = %lu.%lu.%lu.%lu", ((ul1 >> 24) & 0xFFUL), ((ul1 >> 16) & 0xFFUL), ((ul1 >> 8) & 0xFFUL), (ul1 & 0xFFUL)
+ $? ". ul2 = %lu.%lu.%lu.%lu", ((ul2 >> 24) & 0xFFUL), ((ul2 >> 16) & 0xFFUL), ((ul2 >> 8) & 0xFFUL), (ul2 & 0xFFUL)
+ $? ". ul3 = %lu.%lu.%lu.%lu", ((ul3 >> 24) & 0xFFUL), ((ul3 >> 16) & 0xFFUL), ((ul3 >> 8) & 0xFFUL), (ul3 & 0xFFUL)
+ ul1 &= ul3;
+ ul2 &= ul3;
+ $? ". ul1 = %lu.%lu.%lu.%lu", ((ul1 >> 24) & 0xFFUL), ((ul1 >> 16) & 0xFFUL), ((ul1 >> 8) & 0xFFUL), (ul1 & 0xFFUL)
+ $? ". ul2 = %lu.%lu.%lu.%lu", ((ul2 >> 24) & 0xFFUL), ((ul2 >> 16) & 0xFFUL), ((ul2 >> 8) & 0xFFUL), (ul2 & 0xFFUL)
+ if (ul1 > ul2) {
+ back = 1;
+ } else {
+ if (ul1 < ul2) {
+ back = -1;
+ }
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : { $? ". IPv6"
+ ps6 = (const struct sockaddr_in6 *)pso;
+ back = dk4socket_compare_in6_addr3(
+ &((ppl->data).ipv6.ad),
+ &((ppl->data).ipv6.ma),
+ &(ps6->sin6_addr)
+ );
+ } break;
+#endif
+ }
+ }
+ } break;
+ default : { $? ". peer / peer"
+ ppl = (const dk4_allowed_peer_t *)pl;
+ ppr = (const dk4_allowed_peer_t *)pr;
+ if (ppl->af < ppr->af) {
+ back = -1;
+ } else {
+ if (ppl->af > ppr->af) {
+ back = 1;
+ }
+ }
+ if (0 == back) {
+ switch (ppl->af) {
+ case AF_INET : {
+ ul1 = (ppl->data).ipv4.ad.s_addr;
+ ul2 = (ppr->data).ipv4.ad.s_addr;
+ ul1 = dk4socket_ntohl(ul1);
+ ul2 = dk4socket_ntohl(ul2);
+ if (ul1 > ul2) {
+ back = 1;
+ } else {
+ if (ul1 < ul2) {
+ back = -1;
+ }
+ }
+ ul1 = (ppl->data).ipv4.ma.s_addr;
+ ul2 = (ppr->data).ipv4.ma.s_addr;
+ ul1 = dk4socket_ntohl(ul1);
+ ul2 = dk4socket_ntohl(ul2);
+ if (ul1 > ul2) {
+ back = 1;
+ } else {
+ if (ul1 < ul2) {
+ back = -1;
+ }
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ back = dk4socket_compare_in6_addr3(
+ &((ppl->data).ipv6.ad),
+ NULL,
+ &((ppr->data).ipv6.ad)
+ );
+ if (0 == back) {
+ back = dk4socket_compare_in6_addr3(
+ &((ppl->data).ipv6.ma),
+ NULL,
+ &((ppr->data).ipv6.ma)
+ );
+ }
+ } break;
+#endif
+ }
+ }
+ } break;
+ }
+ } else { back= 1; }
+ } else {
+ if (NULL != pr) { back = -1; }
+ } $? "- dk4socket_allowed_peer_compare %d", back
+ return back;
+}
+
diff --git a/support/dktools/dk4sock29.c b/support/dktools/dk4sock29.c
new file mode 100644
index 0000000000..fbf2862301
--- /dev/null
+++ b/support/dktools/dk4sock29.c
@@ -0,0 +1,242 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sock29.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4sock29.c The dk4sock29 module.
+*/
+
+
+#line 8 "dk4sock29.ctr"
+
+#include "dk4sock.h"
+#include "dk4mem.h"
+
+
+
+
+
+#line 15 "dk4sock29.ctr"
+
+
+
+dk4_socket_set_t *
+dk4socket_set_udp_directly(
+ unsigned short portno,
+ int local,
+ int broadcast,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ struct sockaddr_in6 soin6;
+#endif
+ struct sockaddr_in soin4;
+ dk4_socket_set_t *back = NULL;
+ size_t max;
+ int res;
+#if DK4_HAVE_SETSOCKOPT && (defined(SO_REUSEPORT) || defined(SO_REUSEADDR))
+ int opt;
+#endif
+
+ if (0 < portno) {
+ max = 1;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ max++;
+#endif
+ back = dk4socket_set_new(max, erp);
+ if (NULL != back) {
+ /* IPv4 address
+ */
+ DK4_MEMRES(&soin4, sizeof(soin4));
+ soin4.sin_family = AF_INET;
+ soin4.sin_port = dk4socket_htons(portno);
+ if (0 != local) {
+ soin4.sin_addr.s_addr = dk4socket_htonl(INADDR_LOOPBACK);
+ } else {
+ soin4.sin_addr.s_addr = dk4socket_htonl(INADDR_ANY);
+ }
+ (back->pSockets)[back->szUsed] = dk4socket_open(
+ AF_INET, SOCK_DGRAM, 0, erp
+ );
+ if (INVALID_SOCKET != (back->pSockets)[back->szUsed]) {
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEPORT)
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_REUSEPORT, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) {
+
+#line 65 "dk4sock29.ctr"
+ }
+#else
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEADDR)
+
+
+#line 69 "dk4sock29.ctr"
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_REUSEADDR, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) {
+
+#line 75 "dk4sock29.ctr"
+ }
+#else
+
+
+#line 78 "dk4sock29.ctr"
+#endif
+#endif
+#if DK4_HAVE_SETSOCKOPT && defined(SO_BROADCAST)
+
+
+#line 82 "dk4sock29.ctr"
+ if (0 != broadcast) {
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_BROADCAST, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) {
+
+#line 89 "dk4sock29.ctr"
+ }
+ }
+#else
+
+
+#line 93 "dk4sock29.ctr"
+#endif
+ res = dk4socket_bind(
+ (back->pSockets)[back->szUsed],
+ (struct sockaddr *)(&soin4),
+ sizeof(soin4),
+ erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ back->szUsed += 1;
+ } else {
+ (void)dk4socket_close((back->pSockets)[back->szUsed], NULL);
+ (back->pSockets)[back->szUsed] = INVALID_SOCKET;
+ }
+ }
+ /* IPv6 address if available
+ */
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ DK4_MEMRES(&soin6, sizeof(soin6));
+ soin6.sin6_family = AF_INET6;
+ if (0 != local) { soin6.sin6_addr.s6_addr[15] = 0x01; }
+ soin6.sin6_port = dk4socket_htons(portno);
+ (back->pSockets)[back->szUsed] = dk4socket_open(
+ AF_INET6, SOCK_DGRAM, 0, erp
+ );
+ if (INVALID_SOCKET != (back->pSockets)[back->szUsed]) {
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEPORT)
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_REUSEPORT, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) {
+
+#line 125 "dk4sock29.ctr"
+ }
+#else
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEADDR)
+
+
+#line 129 "dk4sock29.ctr"
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_REUSEADDR, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) {
+
+#line 135 "dk4sock29.ctr"
+ }
+#else
+
+
+#line 138 "dk4sock29.ctr"
+#endif
+#endif
+#if DK4_HAVE_SETSOCKOPT && defined(SO_BROADCAST)
+
+
+#line 142 "dk4sock29.ctr"
+ if (0 != broadcast) {
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_BROADCAST, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) {
+
+#line 149 "dk4sock29.ctr"
+ }
+ }
+#else
+
+
+#line 153 "dk4sock29.ctr"
+#endif
+
+ res = dk4socket_bind(
+ (back->pSockets)[back->szUsed],
+ (struct sockaddr *)(&soin6),
+ sizeof(soin6),
+ erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ back->szUsed += 1;
+ } else {
+ (void)dk4socket_close((back->pSockets)[back->szUsed], NULL);
+ (back->pSockets)[back->szUsed] = INVALID_SOCKET;
+ }
+ }
+#endif
+ if (0 == back->szUsed) {
+ dk4socket_set_delete(back, NULL);
+ back = NULL;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4sock29.ctr b/support/dktools/dk4sock29.ctr
new file mode 100644
index 0000000000..a5553e0cf2
--- /dev/null
+++ b/support/dktools/dk4sock29.ctr
@@ -0,0 +1,179 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+%% module
+
+#include "dk4sock.h"
+#include "dk4mem.h"
+
+
+
+$!trace-include
+
+
+
+dk4_socket_set_t *
+dk4socket_set_udp_directly(
+ unsigned short portno,
+ int local,
+ int broadcast,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ struct sockaddr_in6 soin6;
+#endif
+ struct sockaddr_in soin4;
+ dk4_socket_set_t *back = NULL;
+ size_t max;
+ int res;
+#if DK4_HAVE_SETSOCKOPT && (defined(SO_REUSEPORT) || defined(SO_REUSEADDR))
+ int opt;
+#endif
+
+ if (0 < portno) {
+ max = 1;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ max++;
+#endif
+ back = dk4socket_set_new(max, erp);
+ if (NULL != back) {
+ /* IPv4 address
+ */
+ DK4_MEMRES(&soin4, sizeof(soin4));
+ soin4.sin_family = AF_INET;
+ soin4.sin_port = dk4socket_htons(portno);
+ if (0 != local) {
+ soin4.sin_addr.s_addr = dk4socket_htonl(INADDR_LOOPBACK);
+ } else {
+ soin4.sin_addr.s_addr = dk4socket_htonl(INADDR_ANY);
+ }
+ (back->pSockets)[back->szUsed] = dk4socket_open(
+ AF_INET, SOCK_DGRAM, 0, erp
+ );
+ if (INVALID_SOCKET != (back->pSockets)[back->szUsed]) {
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEPORT)
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_REUSEPORT, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) { $? "! failed to reuse port number"
+ }
+#else
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEADDR)
+ $? ". SO_REUSEADDR"
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_REUSEADDR, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) { $? "! failed to reuse address"
+ }
+#else
+ $? ". neither SO_REUSEPORT nor SO_REUSEADDR"
+#endif
+#endif
+#if DK4_HAVE_SETSOCKOPT && defined(SO_BROADCAST)
+ $? ". SO_BROADCAST"
+ if (0 != broadcast) {
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_BROADCAST, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) { $? "! failed to enable broadcast"
+ }
+ }
+#else
+ $? ". can not prepare for broadcast"
+#endif
+ res = dk4socket_bind(
+ (back->pSockets)[back->szUsed],
+ (struct sockaddr *)(&soin4),
+ sizeof(soin4),
+ erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ back->szUsed += 1;
+ } else {
+ (void)dk4socket_close((back->pSockets)[back->szUsed], NULL);
+ (back->pSockets)[back->szUsed] = INVALID_SOCKET;
+ }
+ }
+ /* IPv6 address if available
+ */
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ DK4_MEMRES(&soin6, sizeof(soin6));
+ soin6.sin6_family = AF_INET6;
+ if (0 != local) { soin6.sin6_addr.s6_addr[15] = 0x01; }
+ soin6.sin6_port = dk4socket_htons(portno);
+ (back->pSockets)[back->szUsed] = dk4socket_open(
+ AF_INET6, SOCK_DGRAM, 0, erp
+ );
+ if (INVALID_SOCKET != (back->pSockets)[back->szUsed]) {
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEPORT)
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_REUSEPORT, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) { $? "! failed to reuse port number"
+ }
+#else
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEADDR)
+ $? ". SO_REUSEADDR"
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_REUSEADDR, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) { $? "! failed to reuse address"
+ }
+#else
+ $? ". neither SO_REUSEPORT nor SO_REUSEADDR"
+#endif
+#endif
+#if DK4_HAVE_SETSOCKOPT && defined(SO_BROADCAST)
+ $? ". SO_BROADCAST"
+ if (0 != broadcast) {
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_BROADCAST, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) { $? "! failed to enable broadcast"
+ }
+ }
+#else
+ $? ". can not prepare for broadcast"
+#endif
+
+ res = dk4socket_bind(
+ (back->pSockets)[back->szUsed],
+ (struct sockaddr *)(&soin6),
+ sizeof(soin6),
+ erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ back->szUsed += 1;
+ } else {
+ (void)dk4socket_close((back->pSockets)[back->szUsed], NULL);
+ (back->pSockets)[back->szUsed] = INVALID_SOCKET;
+ }
+ }
+#endif
+ if (0 == back->szUsed) {
+ dk4socket_set_delete(back, NULL);
+ back = NULL;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4sock30.c b/support/dktools/dk4sock30.c
new file mode 100644
index 0000000000..11a7254fa2
--- /dev/null
+++ b/support/dktools/dk4sock30.c
@@ -0,0 +1,306 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sock30.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4sock30.c The dk4sock30 module.
+*/
+
+
+#line 9 "dk4sock30.ctr"
+
+#include "dk4sock.h"
+#include "dk4mem.h"
+
+#if DK4_HAVE_GETADDRINFO
+#include "dk4mao8d.h"
+#else
+#include "dk4mai8dus.h"
+#endif
+
+
+
+
+
+#line 22 "dk4sock30.ctr"
+
+
+
+/** Create UDP socket set for a local port number.
+ @param servicename Local service name.
+ @param local Flag: Allow local connections only.
+ @param broadcast Flag: Prepare for broadcast send.
+ @param numeric Flag: Service name is numeric.
+ @param erp Error report, may be NULL.
+ @return Socket set on success, NULL on error.
+*/
+static
+dk4_socket_set_t *
+dk4socket_c8_set_udp_num_flag(
+ const char *servicename,
+ int local,
+ int broadcast,
+ int numeric,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_GETADDRINFO
+ /* +++++ +getaddrinfo */
+ struct addrinfo hints;
+ struct addrinfo *addri = NULL;
+ struct addrinfo *paddr = NULL;
+ dk4_socket_set_t *back = NULL;
+ size_t numad = 0;
+ int res = 0;
+#if DK4_HAVE_SETSOCKOPT && (defined(SO_REUSEPORT) || defined(SO_REUSEADDR))
+ int opt = 0;
+#endif
+
+
+#line 55 "dk4sock30.ctr"
+ if (NULL != servicename) {
+ DK4_MEMRES(&hints, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_flags = 0;
+ hints.ai_protocol = 0;
+ hints.ai_addrlen = 0;
+ hints.ai_canonname = NULL;
+ hints.ai_addr = NULL;
+ hints.ai_next = NULL;
+ if (0 == local) { hints.ai_flags |= AI_PASSIVE; }
+ if (0 != numeric) { hints.ai_flags |= AI_NUMERICSERV; }
+ res = getaddrinfo(NULL, servicename, &hints, &addri);
+ if ((0 == res) && (NULL != addri)) {
+ paddr = addri;
+ while (NULL != paddr) { numad++; paddr = paddr->ai_next; }
+ if (0 < numad) {
+
+#line 72 "dk4sock30.ctr"
+ paddr = addri;
+ back = dk4socket_set_new(numad, erp);
+ if (NULL != back) {
+ while (NULL != paddr) {
+
+#line 76 "dk4sock30.ctr"
+ (back->pSockets)[back->szUsed] = dk4socket_open(
+ paddr->ai_family, SOCK_DGRAM, 0, erp
+ );
+ if (INVALID_SOCKET != (back->pSockets)[back->szUsed]) {
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEPORT)
+
+
+#line 82 "dk4sock30.ctr"
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_REUSEPORT, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) {
+
+#line 88 "dk4sock30.ctr"
+ }
+#else
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEADDR)
+
+
+#line 92 "dk4sock30.ctr"
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_REUSEADDR, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) {
+
+#line 98 "dk4sock30.ctr"
+ }
+#else
+
+
+#line 101 "dk4sock30.ctr"
+#endif
+#endif
+#if DK4_HAVE_SETSOCKOPT && defined(SO_BROADCAST)
+
+
+#line 105 "dk4sock30.ctr"
+ if (0 != broadcast) {
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_BROADCAST, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) {
+
+#line 112 "dk4sock30.ctr"
+ }
+ }
+#else
+
+
+#line 116 "dk4sock30.ctr"
+#endif
+ res = dk4socket_bind(
+ (back->pSockets)[back->szUsed], paddr->ai_addr,
+ paddr->ai_addrlen, erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ back->szUsed += 1;
+
+
+#line 124 "dk4sock30.ctr"
+ } else {
+
+#line 125 "dk4sock30.ctr"
+ (void)dk4socket_close((back->pSockets)[back->szUsed], NULL);
+ (back->pSockets)[back->szUsed] = INVALID_SOCKET;
+ }
+ } else {
+
+#line 129 "dk4sock30.ctr"
+ }
+ paddr = paddr->ai_next;
+ }
+ if (0 == back->szUsed) {
+ dk4socket_set_delete(back, NULL);
+ back = NULL;
+ }
+ }
+ }
+ freeaddrinfo(addri);
+ } else {
+ dk4error_set_idetails(erp, DK4_E_SOCKET_GETADDRLOC, res);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 146 "dk4sock30.ctr"
+ return back;
+ /* ----- +getaddrinfo */
+#else
+ /* +++++ -getaddrinfo */
+ const char *endptr = NULL;
+ dk4_socket_set_t *back = NULL;
+ struct servent *serv = NULL;
+ int iport = 0;
+ int res = 0;
+ unsigned short portno = 0;
+
+
+#line 157 "dk4sock30.ctr"
+ if (NULL != servicename) {
+ res = dk4ma_input_c8_dec_ushort(
+ &portno, servicename, &endptr, 1, NULL
+ );
+ if (0 != res) {
+ back = dk4socket_set_udp_directly(portno, local, broadcast, erp);
+ } else {
+ dk4socket_error_reset();
+ serv = getservbyname(servicename, NULL);
+ if (NULL != serv) {
+ iport = serv->s_port;
+ dk4socket_swap_bytes_if_not_bigendian((void *)(&iport), sizeof(iport));
+ portno = (unsigned short)iport;
+ back = dk4socket_set_udp_directly(portno, local, broadcast, erp);
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_GETSERVBYNAME);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 179 "dk4sock30.ctr"
+ return back;
+ /* ----- -getaddrinfo */
+#endif
+}
+
+
+
+dk4_socket_set_t *
+dk4socket_c8_set_udp(
+ unsigned short portno,
+ int local,
+ int broadcast,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_GETADDRINFO
+ /* +++++ +getaddrinfo */
+ char pnb[16*sizeof(dk4_um_t)];
+ dk4_socket_set_t *back = NULL;
+ int res;
+ if (0 < portno) {
+ res = dk4ma_write_c8_decimal_unsigned(
+ pnb, sizeof(pnb), (dk4_um_t)portno, 0, erp
+ );
+ if (0 != res) {
+ back = dk4socket_c8_set_udp_num_flag(
+ pnb, local, broadcast, 1, erp
+ );
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- +getaddrinfo */
+#else
+ /* +++++ -getaddrinfo */
+ return (
+ dk4socket_set_udp_directly(portno, local, broadcast, erp)
+ );
+ /* ----- -getaddrinfo */
+#endif
+}
+
+
+
+dk4_socket_set_t *
+dk4socket_c8_set_udp_service(
+ const char *servicename,
+ int local,
+ int broadcast,
+ dk4_er_t *erp
+)
+{
+ return (
+ dk4socket_c8_set_udp_num_flag(servicename, local, broadcast, 0, erp)
+ );
+}
+
+
+
diff --git a/support/dktools/dk4sock30.ctr b/support/dktools/dk4sock30.ctr
new file mode 100644
index 0000000000..eb97c5f740
--- /dev/null
+++ b/support/dktools/dk4sock30.ctr
@@ -0,0 +1,238 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+
+%% module
+
+#include "dk4sock.h"
+#include "dk4mem.h"
+
+#if DK4_HAVE_GETADDRINFO
+#include "dk4mao8d.h"
+#else
+#include "dk4mai8dus.h"
+#endif
+
+
+
+$!trace-include
+
+
+
+/** Create UDP socket set for a local port number.
+ @param servicename Local service name.
+ @param local Flag: Allow local connections only.
+ @param broadcast Flag: Prepare for broadcast send.
+ @param numeric Flag: Service name is numeric.
+ @param erp Error report, may be NULL.
+ @return Socket set on success, NULL on error.
+*/
+static
+dk4_socket_set_t *
+dk4socket_c8_set_udp_num_flag(
+ const char *servicename,
+ int local,
+ int broadcast,
+ int numeric,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_GETADDRINFO
+ /* +++++ +getaddrinfo */
+ struct addrinfo hints;
+ struct addrinfo *addri = NULL;
+ struct addrinfo *paddr = NULL;
+ dk4_socket_set_t *back = NULL;
+ size_t numad = 0;
+ int res = 0;
+#if DK4_HAVE_SETSOCKOPT && (defined(SO_REUSEPORT) || defined(SO_REUSEADDR))
+ int opt = 0;
+#endif
+ $? "+ dk4socket_c8_set_udp_num_flag"
+ if (NULL != servicename) {
+ DK4_MEMRES(&hints, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_flags = 0;
+ hints.ai_protocol = 0;
+ hints.ai_addrlen = 0;
+ hints.ai_canonname = NULL;
+ hints.ai_addr = NULL;
+ hints.ai_next = NULL;
+ if (0 == local) { hints.ai_flags |= AI_PASSIVE; }
+ if (0 != numeric) { hints.ai_flags |= AI_NUMERICSERV; }
+ res = getaddrinfo(NULL, servicename, &hints, &addri);
+ if ((0 == res) && (NULL != addri)) {
+ paddr = addri;
+ while (NULL != paddr) { numad++; paddr = paddr->ai_next; }
+ if (0 < numad) { $? ". numad = %u", (unsigned)numad
+ paddr = addri;
+ back = dk4socket_set_new(numad, erp);
+ if (NULL != back) {
+ while (NULL != paddr) { $? ". try next address"
+ (back->pSockets)[back->szUsed] = dk4socket_open(
+ paddr->ai_family, SOCK_DGRAM, 0, erp
+ );
+ if (INVALID_SOCKET != (back->pSockets)[back->szUsed]) {
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEPORT)
+ $? ". SO_REUSEPORT"
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_REUSEPORT, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) { $? "! failed to reuse port number"
+ }
+#else
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEADDR)
+ $? ". SO_REUSEADDR"
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_REUSEADDR, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) { $? "! failed to reuse address"
+ }
+#else
+ $? ". neither SO_REUSEPORT nor SO_REUSEADDR"
+#endif
+#endif
+#if DK4_HAVE_SETSOCKOPT && defined(SO_BROADCAST)
+ $? ". SO_BROADCAST"
+ if (0 != broadcast) {
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_BROADCAST, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) { $? "! failed to enable broadcast"
+ }
+ }
+#else
+ $? ". can not prepare for broadcast"
+#endif
+ res = dk4socket_bind(
+ (back->pSockets)[back->szUsed], paddr->ai_addr,
+ paddr->ai_addrlen, erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ back->szUsed += 1;
+ $? ". used = %u", (unsigned)(back->szUsed)
+ } else { $? "! failed to bind address"
+ (void)dk4socket_close((back->pSockets)[back->szUsed], NULL);
+ (back->pSockets)[back->szUsed] = INVALID_SOCKET;
+ }
+ } else { $? "! failed to create socket"
+ }
+ paddr = paddr->ai_next;
+ }
+ if (0 == back->szUsed) {
+ dk4socket_set_delete(back, NULL);
+ back = NULL;
+ }
+ }
+ }
+ freeaddrinfo(addri);
+ } else {
+ dk4error_set_idetails(erp, DK4_E_SOCKET_GETADDRLOC, res);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4socket_c8_set_udp_num_flag"
+ return back;
+ /* ----- +getaddrinfo */
+#else
+ /* +++++ -getaddrinfo */
+ const char *endptr = NULL;
+ dk4_socket_set_t *back = NULL;
+ struct servent *serv = NULL;
+ int iport = 0;
+ int res = 0;
+ unsigned short portno = 0;
+ $? "+ dk4socket_c8_set_udp_num_flag"
+ if (NULL != servicename) {
+ res = dk4ma_input_c8_dec_ushort(
+ &portno, servicename, &endptr, 1, NULL
+ );
+ if (0 != res) {
+ back = dk4socket_set_udp_directly(portno, local, broadcast, erp);
+ } else {
+ dk4socket_error_reset();
+ serv = getservbyname(servicename, NULL);
+ if (NULL != serv) {
+ iport = serv->s_port;
+ dk4socket_swap_bytes_if_not_bigendian((void *)(&iport), sizeof(iport));
+ portno = (unsigned short)iport;
+ back = dk4socket_set_udp_directly(portno, local, broadcast, erp);
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_GETSERVBYNAME);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4socket_c8_set_udp_num_flag"
+ return back;
+ /* ----- -getaddrinfo */
+#endif
+}
+
+
+
+dk4_socket_set_t *
+dk4socket_c8_set_udp(
+ unsigned short portno,
+ int local,
+ int broadcast,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_GETADDRINFO
+ /* +++++ +getaddrinfo */
+ char pnb[16*sizeof(dk4_um_t)];
+ dk4_socket_set_t *back = NULL;
+ int res;
+ if (0 < portno) {
+ res = dk4ma_write_c8_decimal_unsigned(
+ pnb, sizeof(pnb), (dk4_um_t)portno, 0, erp
+ );
+ if (0 != res) {
+ back = dk4socket_c8_set_udp_num_flag(
+ pnb, local, broadcast, 1, erp
+ );
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- +getaddrinfo */
+#else
+ /* +++++ -getaddrinfo */
+ return (
+ dk4socket_set_udp_directly(portno, local, broadcast, erp)
+ );
+ /* ----- -getaddrinfo */
+#endif
+}
+
+
+
+dk4_socket_set_t *
+dk4socket_c8_set_udp_service(
+ const char *servicename,
+ int local,
+ int broadcast,
+ dk4_er_t *erp
+)
+{
+ return (
+ dk4socket_c8_set_udp_num_flag(servicename, local, broadcast, 0, erp)
+ );
+}
+
+
+
diff --git a/support/dktools/dk4sock31.c b/support/dktools/dk4sock31.c
new file mode 100644
index 0000000000..df8ded713f
--- /dev/null
+++ b/support/dktools/dk4sock31.c
@@ -0,0 +1,347 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sock31.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4sock31.c The dk4sock31 module.
+*/
+
+
+#line 10 "dk4sock31.ctr"
+
+
+
+#include "dk4sock.h"
+#include "dk4mem.h"
+
+#if DK4_HAVE_GETADDRINFO
+#include "dk4maowd.h"
+#else
+#include "dk4maiwdus.h"
+#endif
+
+#include "dk4rec24.h"
+
+
+
+
+
+#line 27 "dk4sock31.ctr"
+
+
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_ON_WINDOWS
+
+/* +++++ +wchar_t +Windows */
+
+/** Create UDP socket set for a local port number.
+ @param servicename Local service name.
+ @param local Flag: Allow local connections only.
+ @param broadcast Flag: Prepare for broadcast operations.
+ @param numeric Flag: Service name is numeric.
+ @param erp Error report, may be NULL.
+ @return Socket set on success, NULL on error.
+*/
+static
+dk4_socket_set_t *
+dk4socket_wc_set_udp_num_flag(
+ const wchar_t *servicename,
+ int local,
+ int broadcast,
+ int numeric,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_GETADDRINFO
+ /* +++++ +getaddrinfo */
+ ADDRINFOW hints;
+ ADDRINFOW *addri = NULL;
+ ADDRINFOW *paddr = NULL;
+ dk4_socket_set_t *back = NULL;
+ size_t numad = 0;
+ int res = 0;
+#if DK4_HAVE_SETSOCKOPT && (defined(SO_REUSEPORT) || defined(SO_REUSEADDR))
+ int opt = 0;
+#endif
+
+ if (NULL != servicename) {
+ DK4_MEMRES(&hints, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = 0;
+ hints.ai_protocol = 0;
+ hints.ai_addrlen = 0;
+ hints.ai_canonname = NULL;
+ hints.ai_addr = NULL;
+ hints.ai_next = NULL;
+ if (0 == local) { hints.ai_flags |= AI_PASSIVE; }
+ if (0 != numeric) { hints.ai_flags |= AI_NUMERICSERV; }
+ res = GetAddrInfoW(NULL, servicename, &hints, &addri);
+ if ((0 == res) && (NULL != addri)) {
+ paddr = addri;
+ while (NULL != paddr) { numad++; paddr = paddr->ai_next; }
+ if (0 < numad) {
+ paddr = addri;
+ back = dk4socket_set_new(numad, erp);
+ if (NULL != back) {
+ while (NULL != paddr) {
+ (back->pSockets)[back->szUsed] = dk4socket_open(
+ paddr->ai_family, SOCK_STREAM, 0, erp
+ );
+ if (INVALID_SOCKET != (back->pSockets)[back->szUsed]) {
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEPORT)
+
+
+#line 92 "dk4sock31.ctr"
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_REUSEPORT, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) {
+
+#line 98 "dk4sock31.ctr"
+ }
+#else
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEADDR)
+
+
+#line 102 "dk4sock31.ctr"
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_REUSEADDR, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) {
+
+#line 108 "dk4sock31.ctr"
+ }
+#else
+
+
+#line 111 "dk4sock31.ctr"
+#endif
+#endif
+#if DK4_HAVE_SETSOCKOPT && defined(SO_BROADCAST)
+
+
+#line 115 "dk4sock31.ctr"
+ if (0 != broadcast) {
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_BROADCAST, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) {
+
+#line 122 "dk4sock31.ctr"
+ }
+ }
+#else
+
+
+#line 126 "dk4sock31.ctr"
+#endif
+ res = dk4socket_bind(
+ (back->pSockets)[back->szUsed], paddr->ai_addr,
+ paddr->ai_addrlen, erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ back->szUsed += 1;
+ } else {
+ (void)dk4socket_close((back->pSockets)[back->szUsed], NULL);
+ (back->pSockets)[back->szUsed] = INVALID_SOCKET;
+ }
+ }
+ paddr = paddr->ai_next;
+ }
+ if (0 == back->szUsed) {
+ dk4socket_set_delete(back, NULL);
+ back = NULL;
+ }
+ }
+ }
+ FreeAddrInfo(addri);
+ } else {
+ dk4error_set_idetails(erp, DK4_E_SOCKET_GETADDRLOC, res);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- +getaddrinfo */
+#else
+ /* +++++ -getaddrinfo */
+ char asvcn[128];
+ const wchar_t *endptr = NULL;
+ dk4_socket_set_t *back = NULL;
+ struct servent *serv = NULL;
+ int iport = 0;
+ int res = 0;
+ unsigned short portno = 0;
+ if (NULL != servicename) {
+ res = dk4ma_input_wc_dec_ushort(
+ &portno, servicename, &endptr, 1, erp
+ );
+ if (0 != res) {
+ back = dk4socket_set_udp_directly(portno, local, broadcast, erp);
+ } else {
+ res = dk4recode_wchar_t_to_char(asvcn, sizeof(asvcn), servicename, erp);
+ if (0 != res) {
+ serv = getservbyname(asvcn, NULL);
+ if (NULL != serv) {
+ iport = serv->s_port;
+ dk4socket_swap_bytes_if_not_bigendian((void *)(&iport),sizeof(iport));
+ portno = (unsigned short)iport;
+ back = dk4socket_set_udp_directly(portno, local, broadcast, erp);
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_GETSERVBYNAME);
+ }
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- -getaddrinfo */
+#endif
+}
+
+
+
+static
+dk4_socket_set_t *
+dk4socket_wc_set_udp(
+ unsigned short portno,
+ int local,
+ int broadcast,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_GETADDRINFO
+ /* +++++ +getaddrinfo */
+ wchar_t pnb[16*sizeof(dk4_um_t)];
+ dk4_socket_set_t *back = NULL;
+ int res;
+ if (0 < portno) {
+ res = dk4ma_write_wc_decimal_unsigned(
+ pnb, DK4_SIZEOF(pnb,wchar_t), (dk4_um_t)portno, 0, erp
+ );
+ if (0 != res) {
+ back = dk4socket_wc_set_udp_num_flag(
+ pnb, local, broadcast, 1, erp
+ );
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- +getaddrinfo */
+#else
+ /* +++++ -getaddrinfo */
+ return (
+ dk4socket_set_udp_directly(portno, local, broadcast, erp)
+ );
+ /* ----- -getaddrinfo */
+#endif
+}
+
+
+
+static
+dk4_socket_set_t *
+dk4socket_wc_set_udp_service(
+ const wchar_t *servicename,
+ int local,
+ int broadcast,
+ dk4_er_t *erp
+)
+{
+ return (
+ dk4socket_wc_set_udp_num_flag(servicename, local, broadcast, 0, erp)
+ );
+}
+
+/* ----- +wchar_t +Windows */
+
+#else
+#error No networking functions using wchar_t host and service names available!
+#endif
+#endif
+
+
+
+
+dk4_socket_set_t *
+dk4socket_set_udp(
+ unsigned short portno,
+ int local,
+ int broadcast,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (
+ dk4socket_wc_set_udp(portno, local, broadcast, erp)
+ );
+#else
+ return (
+ dk4socket_c8_set_udp(portno, local, broadcast, erp)
+ );
+#endif
+}
+
+
+
+dk4_socket_set_t *
+dk4socket_set_udp_service(
+ const dkChar *servicename,
+ int local,
+ int broadcast,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (
+ dk4socket_wc_set_udp_service(servicename, local, broadcast, erp)
+ );
+#else
+ return (
+ dk4socket_c8_set_udp_service(servicename, local, broadcast, erp)
+ );
+#endif
+}
+
+
+
diff --git a/support/dktools/dk4sock31.ctr b/support/dktools/dk4sock31.ctr
new file mode 100644
index 0000000000..d63ec4e784
--- /dev/null
+++ b/support/dktools/dk4sock31.ctr
@@ -0,0 +1,298 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+
+
+%% module
+
+
+
+#include "dk4sock.h"
+#include "dk4mem.h"
+
+#if DK4_HAVE_GETADDRINFO
+#include "dk4maowd.h"
+#else
+#include "dk4maiwdus.h"
+#endif
+
+#include "dk4rec24.h"
+
+
+
+$!trace-include
+
+
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_ON_WINDOWS
+
+/* +++++ +wchar_t +Windows */
+
+/** Create UDP socket set for a local port number.
+ @param servicename Local service name.
+ @param local Flag: Allow local connections only.
+ @param broadcast Flag: Prepare for broadcast operations.
+ @param numeric Flag: Service name is numeric.
+ @param erp Error report, may be NULL.
+ @return Socket set on success, NULL on error.
+*/
+static
+dk4_socket_set_t *
+dk4socket_wc_set_udp_num_flag(
+ const wchar_t *servicename,
+ int local,
+ int broadcast,
+ int numeric,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_GETADDRINFO
+ /* +++++ +getaddrinfo */
+ ADDRINFOW hints;
+ ADDRINFOW *addri = NULL;
+ ADDRINFOW *paddr = NULL;
+ dk4_socket_set_t *back = NULL;
+ size_t numad = 0;
+ int res = 0;
+#if DK4_HAVE_SETSOCKOPT && (defined(SO_REUSEPORT) || defined(SO_REUSEADDR))
+ int opt = 0;
+#endif
+
+ if (NULL != servicename) {
+ DK4_MEMRES(&hints, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = 0;
+ hints.ai_protocol = 0;
+ hints.ai_addrlen = 0;
+ hints.ai_canonname = NULL;
+ hints.ai_addr = NULL;
+ hints.ai_next = NULL;
+ if (0 == local) { hints.ai_flags |= AI_PASSIVE; }
+ if (0 != numeric) { hints.ai_flags |= AI_NUMERICSERV; }
+ res = GetAddrInfoW(NULL, servicename, &hints, &addri);
+ if ((0 == res) && (NULL != addri)) {
+ paddr = addri;
+ while (NULL != paddr) { numad++; paddr = paddr->ai_next; }
+ if (0 < numad) {
+ paddr = addri;
+ back = dk4socket_set_new(numad, erp);
+ if (NULL != back) {
+ while (NULL != paddr) {
+ (back->pSockets)[back->szUsed] = dk4socket_open(
+ paddr->ai_family, SOCK_STREAM, 0, erp
+ );
+ if (INVALID_SOCKET != (back->pSockets)[back->szUsed]) {
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEPORT)
+ $? ". SO_REUSEPORT"
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_REUSEPORT, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) { $? "! failed to reuse port number"
+ }
+#else
+#if DK4_HAVE_SETSOCKOPT && defined(SO_REUSEADDR)
+ $? ". SO_REUSEADDR"
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_REUSEADDR, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) { $? "! failed to reuse address"
+ }
+#else
+ $? ". neither SO_REUSEPORT nor SO_REUSEADDR"
+#endif
+#endif
+#if DK4_HAVE_SETSOCKOPT && defined(SO_BROADCAST)
+ $? ". SO_BROADCAST"
+ if (0 != broadcast) {
+ dk4socket_set_one_bytes(&opt, sizeof(opt));
+ res = setsockopt(
+ (back->pSockets)[back->szUsed], SOL_SOCKET,
+ SO_BROADCAST, (void *)(&opt), sizeof(opt)
+ );
+ if (0 != res) { $? "! failed to enable broadcast"
+ }
+ }
+#else
+ $? ". can not prepare for broadcast"
+#endif
+ res = dk4socket_bind(
+ (back->pSockets)[back->szUsed], paddr->ai_addr,
+ paddr->ai_addrlen, erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ back->szUsed += 1;
+ } else {
+ (void)dk4socket_close((back->pSockets)[back->szUsed], NULL);
+ (back->pSockets)[back->szUsed] = INVALID_SOCKET;
+ }
+ }
+ paddr = paddr->ai_next;
+ }
+ if (0 == back->szUsed) {
+ dk4socket_set_delete(back, NULL);
+ back = NULL;
+ }
+ }
+ }
+ FreeAddrInfo(addri);
+ } else {
+ dk4error_set_idetails(erp, DK4_E_SOCKET_GETADDRLOC, res);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- +getaddrinfo */
+#else
+ /* +++++ -getaddrinfo */
+ char asvcn[128];
+ const wchar_t *endptr = NULL;
+ dk4_socket_set_t *back = NULL;
+ struct servent *serv = NULL;
+ int iport = 0;
+ int res = 0;
+ unsigned short portno = 0;
+ if (NULL != servicename) {
+ res = dk4ma_input_wc_dec_ushort(
+ &portno, servicename, &endptr, 1, erp
+ );
+ if (0 != res) {
+ back = dk4socket_set_udp_directly(portno, local, broadcast, erp);
+ } else {
+ res = dk4recode_wchar_t_to_char(asvcn, sizeof(asvcn), servicename, erp);
+ if (0 != res) {
+ serv = getservbyname(asvcn, NULL);
+ if (NULL != serv) {
+ iport = serv->s_port;
+ dk4socket_swap_bytes_if_not_bigendian((void *)(&iport),sizeof(iport));
+ portno = (unsigned short)iport;
+ back = dk4socket_set_udp_directly(portno, local, broadcast, erp);
+ } else {
+ dk4socket_error_report(erp, DK4_E_SOCKET_GETSERVBYNAME);
+ }
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- -getaddrinfo */
+#endif
+}
+
+
+
+static
+dk4_socket_set_t *
+dk4socket_wc_set_udp(
+ unsigned short portno,
+ int local,
+ int broadcast,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_GETADDRINFO
+ /* +++++ +getaddrinfo */
+ wchar_t pnb[16*sizeof(dk4_um_t)];
+ dk4_socket_set_t *back = NULL;
+ int res;
+ if (0 < portno) {
+ res = dk4ma_write_wc_decimal_unsigned(
+ pnb, DK4_SIZEOF(pnb,wchar_t), (dk4_um_t)portno, 0, erp
+ );
+ if (0 != res) {
+ back = dk4socket_wc_set_udp_num_flag(
+ pnb, local, broadcast, 1, erp
+ );
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+ /* ----- +getaddrinfo */
+#else
+ /* +++++ -getaddrinfo */
+ return (
+ dk4socket_set_udp_directly(portno, local, broadcast, erp)
+ );
+ /* ----- -getaddrinfo */
+#endif
+}
+
+
+
+static
+dk4_socket_set_t *
+dk4socket_wc_set_udp_service(
+ const wchar_t *servicename,
+ int local,
+ int broadcast,
+ dk4_er_t *erp
+)
+{
+ return (
+ dk4socket_wc_set_udp_num_flag(servicename, local, broadcast, 0, erp)
+ );
+}
+
+/* ----- +wchar_t +Windows */
+
+#else
+#error No networking functions using wchar_t host and service names available!
+#endif
+#endif
+
+
+
+
+dk4_socket_set_t *
+dk4socket_set_udp(
+ unsigned short portno,
+ int local,
+ int broadcast,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (
+ dk4socket_wc_set_udp(portno, local, broadcast, erp)
+ );
+#else
+ return (
+ dk4socket_c8_set_udp(portno, local, broadcast, erp)
+ );
+#endif
+}
+
+
+
+dk4_socket_set_t *
+dk4socket_set_udp_service(
+ const dkChar *servicename,
+ int local,
+ int broadcast,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (
+ dk4socket_wc_set_udp_service(servicename, local, broadcast, erp)
+ );
+#else
+ return (
+ dk4socket_c8_set_udp_service(servicename, local, broadcast, erp)
+ );
+#endif
+}
+
+
+
diff --git a/support/dktools/dk4sock32.c b/support/dktools/dk4sock32.c
new file mode 100644
index 0000000000..d2cc296a35
--- /dev/null
+++ b/support/dktools/dk4sock32.c
@@ -0,0 +1,158 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sock32.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4sock32.c The dk4sock32 module.
+*/
+
+
+#line 10 "dk4sock32.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4mem.h"
+#include "dk4sock.h"
+#include "dk4mai8dus.h"
+#include "dk4mao8d.h"
+
+
+
+
+
+#line 21 "dk4sock32.ctr"
+
+
+
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+/** used to initialize IPv6 address for binding local ports.
+*/
+static const IN6_ADDR dk4socket_any6 = IN6ADDR_ANY_INIT;
+#endif
+
+
+
+int
+dk4socket_address_family(dk4_sockaddr_storage_t *aptr)
+{
+ struct sockaddr *sa = NULL;
+ int back = AF_UNSPEC;
+ if (NULL != aptr) {
+ sa = (struct sockaddr *)aptr;
+ switch (sa->sa_family) {
+ case AF_INET :
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 :
+#endif
+ {
+ back = sa->sa_family;
+ } break;
+ }
+ }
+ return back;
+}
+
+
+size_t
+dk4socket_address_size(dk4_sockaddr_storage_t *aptr)
+{
+ struct sockaddr *sa;
+ size_t back = 0;
+
+ if (NULL != aptr) {
+ sa = (struct sockaddr *)aptr;
+ switch (sa->sa_family) {
+ case AF_INET : {
+ back = sizeof(struct sockaddr_in);
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ back = sizeof(struct sockaddr_in6);
+ } break;
+#endif
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4socket_complete_addresses(
+ dk4_sockaddr_storage_t *array,
+ unsigned short remport,
+ unsigned short locport
+)
+{
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ struct sockaddr_in6 *sa6;
+#endif
+ struct sockaddr_in *sa4;
+ struct sockaddr *sa;
+ int back = DK4_SOCKET_RESULT_FAILED;
+
+
+#line 91 "dk4sock32.ctr"
+ sa = (struct sockaddr *)array;
+ switch (sa->sa_family) {
+ case AF_INET : {
+
+#line 94 "dk4sock32.ctr"
+ sa4 = (struct sockaddr_in *)array;
+ sa4->sin_port = dk4socket_htons(remport);
+ sa4 = (struct sockaddr_in *)(&(array[1]));
+ sa4->sin_family = AF_INET;
+ sa4->sin_addr.s_addr = dk4socket_htonl(INADDR_ANY);
+ sa4->sin_port = dk4socket_htons(locport);
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+
+#line 104 "dk4sock32.ctr"
+ sa6 = (struct sockaddr_in6 *)array;
+ sa6->sin6_port = dk4socket_htons(remport);
+ sa6 = (struct sockaddr_in6 *)(&(array[1]));
+ sa6->sin6_family = AF_INET6;
+ DK4_MEMCPY(&(sa6->sin6_addr), &dk4socket_any6, sizeof(IN6_ADDR));
+ sa6->sin6_port = dk4socket_htons(locport);
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } break;
+#endif
+ }
+
+
+#line 115 "dk4sock32.ctr"
+ return back;
+}
+
diff --git a/support/dktools/dk4sock32.ctr b/support/dktools/dk4sock32.ctr
new file mode 100644
index 0000000000..686db27b73
--- /dev/null
+++ b/support/dktools/dk4sock32.ctr
@@ -0,0 +1,117 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4mem.h"
+#include "dk4sock.h"
+#include "dk4mai8dus.h"
+#include "dk4mao8d.h"
+
+
+
+$!trace-include
+
+
+
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+/** used to initialize IPv6 address for binding local ports.
+*/
+static const IN6_ADDR dk4socket_any6 = IN6ADDR_ANY_INIT;
+#endif
+
+
+
+int
+dk4socket_address_family(dk4_sockaddr_storage_t *aptr)
+{
+ struct sockaddr *sa = NULL;
+ int back = AF_UNSPEC;
+ if (NULL != aptr) {
+ sa = (struct sockaddr *)aptr;
+ switch (sa->sa_family) {
+ case AF_INET :
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 :
+#endif
+ {
+ back = sa->sa_family;
+ } break;
+ }
+ }
+ return back;
+}
+
+
+size_t
+dk4socket_address_size(dk4_sockaddr_storage_t *aptr)
+{
+ struct sockaddr *sa;
+ size_t back = 0;
+
+ if (NULL != aptr) {
+ sa = (struct sockaddr *)aptr;
+ switch (sa->sa_family) {
+ case AF_INET : {
+ back = sizeof(struct sockaddr_in);
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ back = sizeof(struct sockaddr_in6);
+ } break;
+#endif
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4socket_complete_addresses(
+ dk4_sockaddr_storage_t *array,
+ unsigned short remport,
+ unsigned short locport
+)
+{
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ struct sockaddr_in6 *sa6;
+#endif
+ struct sockaddr_in *sa4;
+ struct sockaddr *sa;
+ int back = DK4_SOCKET_RESULT_FAILED;
+ $? "+ dk4socket_complete_addresses"
+ sa = (struct sockaddr *)array;
+ switch (sa->sa_family) {
+ case AF_INET : { $? ". IPv4"
+ sa4 = (struct sockaddr_in *)array;
+ sa4->sin_port = dk4socket_htons(remport);
+ sa4 = (struct sockaddr_in *)(&(array[1]));
+ sa4->sin_family = AF_INET;
+ sa4->sin_addr.s_addr = dk4socket_htonl(INADDR_ANY);
+ sa4->sin_port = dk4socket_htons(locport);
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : { $? ". IPv6"
+ sa6 = (struct sockaddr_in6 *)array;
+ sa6->sin6_port = dk4socket_htons(remport);
+ sa6 = (struct sockaddr_in6 *)(&(array[1]));
+ sa6->sin6_family = AF_INET6;
+ DK4_MEMCPY(&(sa6->sin6_addr), &dk4socket_any6, sizeof(IN6_ADDR));
+ sa6->sin6_port = dk4socket_htons(locport);
+ back = DK4_SOCKET_RESULT_SUCCESS;
+ } break;
+#endif
+ }
+ $? "- dk4socket_complete_addresses %d", back
+ return back;
+}
+
diff --git a/support/dktools/dk4sock33.c b/support/dktools/dk4sock33.c
new file mode 100644
index 0000000000..d2f47ade70
--- /dev/null
+++ b/support/dktools/dk4sock33.c
@@ -0,0 +1,366 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sock33.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4sock33.c The dk4sock33 module.
+*/
+
+
+#line 10 "dk4sock33.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4mem.h"
+#include "dk4sock.h"
+#include "dk4mai8dus.h"
+#include "dk4mao8d.h"
+
+
+
+
+
+#line 21 "dk4sock33.ctr"
+
+
+
+/** Attempt to convert an IPv4 or IPv6 address from text to address.
+ @param dptr Destination variable.
+ @param str Source text.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4socket_c8_find_address(dk4_sockaddr_storage_t *dptr, const char *str)
+{
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ struct sockaddr_in6 *in6;
+#endif
+ struct sockaddr_in *in4;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ IN6_ADDR addr6;
+#endif
+ IN_ADDR addr4;
+ int back = 0;
+ int res;
+
+
+#line 44 "dk4sock33.ctr"
+ res = dk4socket_c8_inet_pton(&addr4, sizeof(addr4), AF_INET, str, NULL);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+
+#line 46 "dk4sock33.ctr"
+ in4 = (struct sockaddr_in *)dptr;
+ in4->sin_family = AF_INET;
+ DK4_MEMCPY(&(in4->sin_addr), &addr4, sizeof(addr4));
+ back = 1;
+ } else {
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ res = dk4socket_c8_inet_pton(&addr6, sizeof(addr6), AF_INET6, str, NULL);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+
+#line 54 "dk4sock33.ctr"
+ in6 = (struct sockaddr_in6 *)dptr;
+ in6->sin6_family = AF_INET6;
+ DK4_MEMCPY(&(in6->sin6_addr), &addr6, sizeof(addr6));
+ back = 1;
+ }
+#endif
+ }
+
+
+#line 62 "dk4sock33.ctr"
+ return back;
+}
+
+
+
+/** Find address for one host name.
+ @param dptr Address of destination data structure.
+ @param remhost Remote host name.
+ @param remport Remote port number in host representation.
+ @param ip4 Flag: Prefer IPv4 over IPv6 addresses.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4socket_c8_find_host(
+ dk4_sockaddr_storage_t *dptr,
+ const char *remhost,
+ unsigned short remport,
+ int ip4
+)
+{
+#if DK4_HAVE_GETADDRINFO
+ char buf[16*sizeof(unsigned short)];
+ struct addrinfo hints;
+ struct addrinfo *results = NULL;
+ struct addrinfo *rptr = NULL;
+ int back = 0;
+ int res = 0;
+
+
+#line 91 "dk4sock33.ctr"
+ res = dk4ma_write_c8_decimal_unsigned(
+ buf, sizeof(buf), (dk4_um_t)remport, 0, NULL
+ );
+ if (0 != res) {
+ DK4_MEMRES(&hints, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_protocol = 0;
+ hints.ai_flags = AI_NUMERICSERV;
+ res = getaddrinfo(remhost, buf, &hints, &results);
+ if ((0 == res) && (NULL != results)) {
+
+#line 102 "dk4sock33.ctr"
+ if (0 != ip4) {
+
+#line 103 "dk4sock33.ctr"
+ rptr = results;
+ while ((NULL != rptr) && (0 == back)) {
+
+#line 105 "dk4sock33.ctr"
+ if ((0 < rptr->ai_addrlen) && (NULL != rptr->ai_addr)) {
+ if (AF_INET == rptr->ai_addr->sa_family) {
+ if (sizeof(dk4_sockaddr_storage_t) >= rptr->ai_addrlen) {
+ DK4_MEMCPY(dptr, rptr->ai_addr, rptr->ai_addrlen);
+ back = 1;
+
+#line 110 "dk4sock33.ctr"
+ } else {
+
+#line 111 "dk4sock33.ctr"
+ }
+ } else {
+
+#line 113 "dk4sock33.ctr"
+ }
+ } else {
+
+#line 115 "dk4sock33.ctr"
+ }
+ rptr = rptr->ai_next;
+ }
+ if (0 == back) {
+ rptr = results;
+ while ((NULL != rptr) && (0 == back)) {
+
+#line 121 "dk4sock33.ctr"
+ if ((0 < rptr->ai_addrlen) && (NULL != rptr->ai_addr)) {
+ if (sizeof(dk4_sockaddr_storage_t) >= rptr->ai_addrlen) {
+ DK4_MEMCPY(dptr, rptr->ai_addr, rptr->ai_addrlen);
+ back = 1;
+
+#line 125 "dk4sock33.ctr"
+ } else {
+
+#line 126 "dk4sock33.ctr"
+ }
+ } else {
+
+#line 128 "dk4sock33.ctr"
+ }
+ rptr = rptr->ai_next;
+ }
+ }
+ } else {
+
+#line 133 "dk4sock33.ctr"
+ rptr = results;
+ while ((NULL != rptr) && (0 == back)) {
+
+#line 135 "dk4sock33.ctr"
+ if ((0 < rptr->ai_addrlen) && (NULL != rptr->ai_addr)) {
+ if (sizeof(dk4_sockaddr_storage_t) >= rptr->ai_addrlen) {
+ DK4_MEMCPY(dptr, rptr->ai_addr, rptr->ai_addrlen);
+ back = 1;
+
+#line 139 "dk4sock33.ctr"
+ } else {
+
+#line 140 "dk4sock33.ctr"
+ }
+ } else {
+
+#line 142 "dk4sock33.ctr"
+ }
+ rptr = rptr->ai_next;
+ }
+ }
+ } else {
+
+#line 147 "dk4sock33.ctr"
+ }
+ if (NULL != results) { freeaddrinfo(results); }
+ } else {
+
+#line 150 "dk4sock33.ctr"
+ }
+
+
+#line 152 "dk4sock33.ctr"
+ return back;
+#else
+#if DK4_HAVE_GETHOSTBYNAME
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ struct sockaddr_in6 *sa6;
+#endif
+ struct sockaddr_in *sa4;
+ struct hostent *hep = NULL;
+ int back = 0;
+
+
+#line 162 "dk4sock33.ctr"
+ hep = gethostbyname(remhost);
+ if (NULL != hep) {
+
+#line 164 "dk4sock33.ctr"
+ if (NULL != hep->h_addr_list) {
+
+#line 165 "dk4sock33.ctr"
+ if (NULL != *(hep->h_addr_list)) {
+
+#line 166 "dk4sock33.ctr"
+ switch (hep->h_addrtype) {
+ case AF_INET : {
+
+#line 168 "dk4sock33.ctr"
+ sa4 = (struct sockaddr_in *)dptr;
+ DK4_MEMRES(sa4, sizeof(struct sockaddr_in));
+ sa4->sin_family = AF_INET;
+ sa4->sin_port = dk4socket_htons(remport);
+ DK4_MEMCPY(&(sa4->sin_addr),*(hep->h_addr_list),sizeof(IN_ADDR));
+ back = 1;
+
+#line 174 "dk4sock33.ctr"
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+
+#line 177 "dk4sock33.ctr"
+ sa6 = (struct sockaddr_in6 *)dptr;
+ DK4_MEMRES(sa6, sizeof(struct sockaddr_in6));
+ sa6->sin6_family = AF_INET6;
+ sa6->sin_port = dk4socket_htons(remport);
+ DK4_MEMCPY(&(sa6->sin6_addr),*(hep->h_addr_list),sizeof(IN6_ADDR));
+ back = 1;
+
+#line 183 "dk4sock33.ctr"
+ } break;
+#endif
+ }
+ } else {
+
+#line 187 "dk4sock33.ctr"
+ }
+ } else {
+
+#line 189 "dk4sock33.ctr"
+ }
+ } else {
+
+#line 191 "dk4sock33.ctr"
+ }
+
+
+#line 193 "dk4sock33.ctr"
+ return back;
+#else
+ int back = 0;
+
+
+#line 197 "dk4sock33.ctr"
+
+
+#line 198 "dk4sock33.ctr"
+ return back;
+#endif
+#endif
+}
+
+
+
+int
+dk4socket_c8_udp_addresses_numeric(
+ dk4_sockaddr_storage_t *array,
+ const char *remhost,
+ unsigned short remport,
+ unsigned short locport,
+ int ip4,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_SOCKET_RESULT_FAILED;
+
+
+#line 217 "dk4sock33.ctr"
+ if ((NULL != array) && (NULL != remhost) && (0 < remport) && (0 < locport)) {
+ DK4_MEMRES(array, (2*sizeof(dk4_sockaddr_storage_t)));
+ if (0 != dk4socket_c8_find_address(array, remhost)) {
+
+
+#line 221 "dk4sock33.ctr"
+ back = dk4socket_complete_addresses(array, remport, locport);
+
+
+#line 223 "dk4sock33.ctr"
+ }
+ if (DK4_SOCKET_RESULT_FAILED == back) {
+
+#line 225 "dk4sock33.ctr"
+ if (0 != dk4socket_c8_find_host(array, remhost, remport, ip4)) {
+ back = dk4socket_complete_addresses(array, remport, locport);
+ if (DK4_SOCKET_RESULT_FAILED == back) {
+
+#line 228 "dk4sock33.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ } else {
+
+#line 231 "dk4sock33.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ }
+ } else {
+
+#line 235 "dk4sock33.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 238 "dk4sock33.ctr"
+ return back;
+}
+
+
diff --git a/support/dktools/dk4sock33.ctr b/support/dktools/dk4sock33.ctr
new file mode 100644
index 0000000000..d6ff6b842e
--- /dev/null
+++ b/support/dktools/dk4sock33.ctr
@@ -0,0 +1,241 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4mem.h"
+#include "dk4sock.h"
+#include "dk4mai8dus.h"
+#include "dk4mao8d.h"
+
+
+
+$!trace-include
+
+
+
+/** Attempt to convert an IPv4 or IPv6 address from text to address.
+ @param dptr Destination variable.
+ @param str Source text.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4socket_c8_find_address(dk4_sockaddr_storage_t *dptr, const char *str)
+{
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ struct sockaddr_in6 *in6;
+#endif
+ struct sockaddr_in *in4;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ IN6_ADDR addr6;
+#endif
+ IN_ADDR addr4;
+ int back = 0;
+ int res;
+ $? "+ dk4socket_c8_find_address"
+ res = dk4socket_c8_inet_pton(&addr4, sizeof(addr4), AF_INET, str, NULL);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) { $? ". IPv4"
+ in4 = (struct sockaddr_in *)dptr;
+ in4->sin_family = AF_INET;
+ DK4_MEMCPY(&(in4->sin_addr), &addr4, sizeof(addr4));
+ back = 1;
+ } else {
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ res = dk4socket_c8_inet_pton(&addr6, sizeof(addr6), AF_INET6, str, NULL);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) { $? ". IPv6"
+ in6 = (struct sockaddr_in6 *)dptr;
+ in6->sin6_family = AF_INET6;
+ DK4_MEMCPY(&(in6->sin6_addr), &addr6, sizeof(addr6));
+ back = 1;
+ }
+#endif
+ }
+ $? "- dk4socket_c8_find_address %d", back
+ return back;
+}
+
+
+
+/** Find address for one host name.
+ @param dptr Address of destination data structure.
+ @param remhost Remote host name.
+ @param remport Remote port number in host representation.
+ @param ip4 Flag: Prefer IPv4 over IPv6 addresses.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4socket_c8_find_host(
+ dk4_sockaddr_storage_t *dptr,
+ const char *remhost,
+ unsigned short remport,
+ int ip4
+)
+{
+#if DK4_HAVE_GETADDRINFO
+ char buf[16*sizeof(unsigned short)];
+ struct addrinfo hints;
+ struct addrinfo *results = NULL;
+ struct addrinfo *rptr = NULL;
+ int back = 0;
+ int res = 0;
+ $? "+ dk4socket_c8_find_host (getaddrinfo) \"%s\"", TR_8STR(remhost)
+ res = dk4ma_write_c8_decimal_unsigned(
+ buf, sizeof(buf), (dk4_um_t)remport, 0, NULL
+ );
+ if (0 != res) {
+ DK4_MEMRES(&hints, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_protocol = 0;
+ hints.ai_flags = AI_NUMERICSERV;
+ res = getaddrinfo(remhost, buf, &hints, &results);
+ if ((0 == res) && (NULL != results)) { $? ". getaddrinfo"
+ if (0 != ip4) { $? ". IPv4 preferred"
+ rptr = results;
+ while ((NULL != rptr) && (0 == back)) { $? ". entry"
+ if ((0 < rptr->ai_addrlen) && (NULL != rptr->ai_addr)) {
+ if (AF_INET == rptr->ai_addr->sa_family) {
+ if (sizeof(dk4_sockaddr_storage_t) >= rptr->ai_addrlen) {
+ DK4_MEMCPY(dptr, rptr->ai_addr, rptr->ai_addrlen);
+ back = 1; $? ". found"
+ } else { $? "! address too large"
+ }
+ } else { $? "! not IPv4"
+ }
+ } else { $? "! no address data"
+ }
+ rptr = rptr->ai_next;
+ }
+ if (0 == back) {
+ rptr = results;
+ while ((NULL != rptr) && (0 == back)) { $? ". entry"
+ if ((0 < rptr->ai_addrlen) && (NULL != rptr->ai_addr)) {
+ if (sizeof(dk4_sockaddr_storage_t) >= rptr->ai_addrlen) {
+ DK4_MEMCPY(dptr, rptr->ai_addr, rptr->ai_addrlen);
+ back = 1; $? ". found"
+ } else { $? "! address too large"
+ }
+ } else { $? "! no address data"
+ }
+ rptr = rptr->ai_next;
+ }
+ }
+ } else { $? ". any address family"
+ rptr = results;
+ while ((NULL != rptr) && (0 == back)) { $? ". entry"
+ if ((0 < rptr->ai_addrlen) && (NULL != rptr->ai_addr)) {
+ if (sizeof(dk4_sockaddr_storage_t) >= rptr->ai_addrlen) {
+ DK4_MEMCPY(dptr, rptr->ai_addr, rptr->ai_addrlen);
+ back = 1; $? ". found"
+ } else { $? "! address too large"
+ }
+ } else { $? "! no address data"
+ }
+ rptr = rptr->ai_next;
+ }
+ }
+ } else { $? "! getaddrinfo"
+ }
+ if (NULL != results) { freeaddrinfo(results); }
+ } else { $? "! failed to convert port no to text"
+ }
+ $? "- dk4socket_c8_find_host %d", back
+ return back;
+#else
+#if DK4_HAVE_GETHOSTBYNAME
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ struct sockaddr_in6 *sa6;
+#endif
+ struct sockaddr_in *sa4;
+ struct hostent *hep = NULL;
+ int back = 0;
+ $? "+ dk4socket_c8_find_host (gethostbyname) \"%s\"", TR_8STR(remhost)
+ hep = gethostbyname(remhost);
+ if (NULL != hep) { $? ". entry"
+ if (NULL != hep->h_addr_list) { $? ". list"
+ if (NULL != *(hep->h_addr_list)) { $? ". element"
+ switch (hep->h_addrtype) {
+ case AF_INET : { $? ". IPv4"
+ sa4 = (struct sockaddr_in *)dptr;
+ DK4_MEMRES(sa4, sizeof(struct sockaddr_in));
+ sa4->sin_family = AF_INET;
+ sa4->sin_port = dk4socket_htons(remport);
+ DK4_MEMCPY(&(sa4->sin_addr),*(hep->h_addr_list),sizeof(IN_ADDR));
+ back = 1; $? ". found"
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : { $? ". IPv6"
+ sa6 = (struct sockaddr_in6 *)dptr;
+ DK4_MEMRES(sa6, sizeof(struct sockaddr_in6));
+ sa6->sin6_family = AF_INET6;
+ sa6->sin_port = dk4socket_htons(remport);
+ DK4_MEMCPY(&(sa6->sin6_addr),*(hep->h_addr_list),sizeof(IN6_ADDR));
+ back = 1; $? ". found"
+ } break;
+#endif
+ }
+ } else { $? "! NULL pointer"
+ }
+ } else { $? "! NULL list"
+ }
+ } else { $? "! not found"
+ }
+ $? "- dk4socket_c8_find_host %d", back
+ return back;
+#else
+ int back = 0;
+ $? "+ dk4socket_c8_find_host (none) \"%s\"", TR_8STR(remhost)
+ $? "- dk4socket_c8_find_host %d", back
+ return back;
+#endif
+#endif
+}
+
+
+
+int
+dk4socket_c8_udp_addresses_numeric(
+ dk4_sockaddr_storage_t *array,
+ const char *remhost,
+ unsigned short remport,
+ unsigned short locport,
+ int ip4,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_SOCKET_RESULT_FAILED;
+ $? "+ dk4socket_c8_udp_addresses_numeric \"%s\"", TR_8STR(remhost)
+ if ((NULL != array) && (NULL != remhost) && (0 < remport) && (0 < locport)) {
+ DK4_MEMRES(array, (2*sizeof(dk4_sockaddr_storage_t)));
+ if (0 != dk4socket_c8_find_address(array, remhost)) {
+ $? ". address found"
+ back = dk4socket_complete_addresses(array, remport, locport);
+ $? ". back = %d", back
+ }
+ if (DK4_SOCKET_RESULT_FAILED == back) { $? ". no addr"
+ if (0 != dk4socket_c8_find_host(array, remhost, remport, ip4)) {
+ back = dk4socket_complete_addresses(array, remport, locport);
+ if (DK4_SOCKET_RESULT_FAILED == back) { $? "! not completed"
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ } else { $? "! host not found"
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ }
+ } else { $? "! arguments"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4socket_c8_udp_addresses_numeric %d", back
+ return back;
+}
+
+
diff --git a/support/dktools/dk4sock34.c b/support/dktools/dk4sock34.c
new file mode 100644
index 0000000000..9174b8ece0
--- /dev/null
+++ b/support/dktools/dk4sock34.c
@@ -0,0 +1,441 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sock34.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4sock34.c The dk4sock34 module.
+*/
+
+
+#line 10 "dk4sock34.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4mem.h"
+#include "dk4sock.h"
+#include "dk4mai8dus.h"
+#include "dk4maowd.h"
+#include "dk4mao8d.h"
+#include "dk4rec24.h"
+
+
+
+
+
+#line 23 "dk4sock34.ctr"
+
+
+
+#if DK4_ON_WINDOWS
+
+/** Attempt to convert an IPv4 or IPv6 address from text to address.
+ @param dptr Destination variable.
+ @param str Source text.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4socket_wc_find_address(dk4_sockaddr_storage_t *dptr, const wchar_t *str)
+{
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ struct sockaddr_in6 *in6;
+#endif
+ struct sockaddr_in *in4;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ IN6_ADDR addr6;
+#endif
+ IN_ADDR addr4;
+ int back = 0;
+ int res;
+
+
+#line 48 "dk4sock34.ctr"
+ res = dk4socket_wc_inet_pton(&addr4, sizeof(addr4), AF_INET, str, NULL);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ in4 = (struct sockaddr_in *)dptr;
+ in4->sin_family = AF_INET;
+ DK4_MEMCPY(&(in4->sin_addr), &addr4, sizeof(addr4));
+ back = 1;
+ } else {
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ res = dk4socket_wc_inet_pton(&addr6, sizeof(addr6), AF_INET6, str, NULL);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ in6 = (struct sockaddr_in6 *)dptr;
+ in6->sin6_family = AF_INET6;
+ DK4_MEMCPY(&(in6->sin6_addr), &addr6, sizeof(addr6));
+ back = 1;
+ }
+#endif
+ }
+
+
+#line 66 "dk4sock34.ctr"
+ return back;
+}
+
+/** Find address for one host name.
+ @param dptr Address of destination data structure.
+ @param remhost Remote host name.
+ @param remport Remote port number in host representation.
+ @param ip4 Flag: Prefer IPv4 over IPv6 addresses.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4socket_wc_find_host(
+ dk4_sockaddr_storage_t *dptr,
+ const wchar_t *remhost,
+ unsigned short remport,
+ int ip4,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_GETADDRINFO
+ /* +++ getaddrinfo +++ */
+ wchar_t buf[16*sizeof(unsigned short)];
+ ADDRINFOW hints;
+ ADDRINFOW *results = NULL;
+ ADDRINFOW *rptr = NULL;
+ int back = 0;
+ int res = 0;
+
+
+#line 96 "dk4sock34.ctr"
+ res = dk4ma_write_wc_decimal_unsigned(
+ buf, DK4_SIZEOF(buf,wchar_t), (dk4_um_t)remport, 0, NULL
+ );
+ if (0 != res) {
+ DK4_MEMRES(&hints, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_protocol = 0;
+ hints.ai_flags = AI_NUMERICSERV;
+ res = GetAddrInfoW(remhost, buf, &hints, &results);
+ if ((0 == res) && (NULL != results)) {
+
+#line 107 "dk4sock34.ctr"
+ if (0 != ip4) {
+ rptr = results;
+ while ((NULL != rptr) && (0 == back)) {
+ if ((0 < rptr->ai_addrlen) && (NULL != rptr->ai_addr)) {
+ if (AF_INET == rptr->ai_addr->sa_family) {
+ if (sizeof(dk4_sockaddr_storage_t) >= rptr->ai_addrlen) {
+ DK4_MEMCPY(dptr, rptr->ai_addr, rptr->ai_addrlen);
+ back = 1;
+
+#line 115 "dk4sock34.ctr"
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 118 "dk4sock34.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 123 "dk4sock34.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 128 "dk4sock34.ctr"
+ }
+#endif
+ rptr = rptr->ai_next;
+ }
+ if (0 == back) {
+ rptr = results;
+ while ((NULL != rptr) && (0 == back)) {
+ if ((0 < rptr->ai_addrlen) && (NULL != rptr->ai_addr)) {
+ if (sizeof(dk4_sockaddr_storage_t) >= rptr->ai_addrlen) {
+ DK4_MEMCPY(dptr, rptr->ai_addr, rptr->ai_addrlen);
+ back = 1;
+
+#line 139 "dk4sock34.ctr"
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 142 "dk4sock34.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 147 "dk4sock34.ctr"
+ }
+#endif
+ rptr = rptr->ai_next;
+ }
+ }
+ } else {
+
+#line 153 "dk4sock34.ctr"
+ rptr = results;
+ while ((NULL != rptr) && (0 == back)) {
+ if ((0 < rptr->ai_addrlen) && (NULL != rptr->ai_addr)) {
+ if (sizeof(dk4_sockaddr_storage_t) >= rptr->ai_addrlen) {
+ DK4_MEMCPY(dptr, rptr->ai_addr, rptr->ai_addrlen);
+ back = 1;
+
+#line 159 "dk4sock34.ctr"
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 162 "dk4sock34.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 167 "dk4sock34.ctr"
+ }
+#endif
+ rptr = rptr->ai_next;
+ }
+ }
+ } else {
+
+#line 173 "dk4sock34.ctr"
+ }
+ if (NULL != results) { FreeAddrInfoW(results); }
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 178 "dk4sock34.ctr"
+ }
+#endif
+
+
+#line 181 "dk4sock34.ctr"
+ return back;
+ /* --- getaddrinfo --- */
+#else
+ /* +++ ! getaddrinfo +++ */
+#if DK4_HAVE_GETHOSTBYNAME
+ /* +++ gethostbyname +++ */
+ char hona[1040];
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ struct sockaddr_in6 *sa6;
+#endif
+ struct sockaddr_in *sa4;
+ struct hostent *hep = NULL;
+ int back = 0;
+
+
+#line 195 "dk4sock34.ctr"
+ if (0 != dk4recode_wchar_t_to_char(hona, sizeof(hona), remhost, erp)) {
+ hep = gethostbyname(hona);
+ if (NULL != hep) {
+
+#line 198 "dk4sock34.ctr"
+ if (NULL != hep->h_addr_list) {
+
+#line 199 "dk4sock34.ctr"
+ if (NULL != *(hep->h_addr_list)) {
+
+#line 200 "dk4sock34.ctr"
+ switch (hep->h_addrtype) {
+ case AF_INET : {
+
+#line 202 "dk4sock34.ctr"
+ sa4 = (struct sockaddr_in *)dptr;
+ DK4_MEMRES(sa4, sizeof(struct sockaddr_in));
+ sa4->sin_family = AF_INET;
+ sa4->sin_port = dk4socket_htons(remport);
+ DK4_MEMCPY(&(sa4->sin_addr),*(hep->h_addr_list),sizeof(IN_ADDR));
+ back = 1;
+
+#line 208 "dk4sock34.ctr"
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+
+#line 211 "dk4sock34.ctr"
+ sa6 = (struct sockaddr_in6 *)dptr;
+ DK4_MEMRES(sa6, sizeof(struct sockaddr_in6));
+ sa6->sin6_family = AF_INET6;
+ sa6->sin_port = dk4socket_htons(remport);
+ DK4_MEMCPY(&(sa6->sin6_addr),*(hep->h_addr_list),sizeof(IN6_ADDR));
+ back = 1;
+
+#line 217 "dk4sock34.ctr"
+ } break;
+#endif
+#if TRACE_DEBUG
+ default : {
+
+#line 221 "dk4sock34.ctr"
+ } break;
+#endif
+ }
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 227 "dk4sock34.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 232 "dk4sock34.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 237 "dk4sock34.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 242 "dk4sock34.ctr"
+ }
+#endif
+
+
+#line 245 "dk4sock34.ctr"
+ return back;
+ /* --- gethostbyname --- */
+#else
+ /* +++ ! gethostbyname +++ */
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+
+#line 251 "dk4sock34.ctr"
+ /* --- ! gethostbyname --- */
+#endif
+ /* --- ! getaddrinfo --- */
+#endif
+}
+
+#endif
+
+int
+dk4socket_wc_udp_addresses_numeric(
+ dk4_sockaddr_storage_t *array,
+ const wchar_t *remhost,
+ unsigned short remport,
+ unsigned short locport,
+ int ip4,
+ dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+ int back = DK4_SOCKET_RESULT_FAILED;
+
+
+#line 272 "dk4sock34.ctr"
+ if ((NULL != array) && (NULL != remhost) && (0 < remport) && (0 < locport)) {
+ DK4_MEMRES(array, (2*sizeof(dk4_sockaddr_storage_t)));
+ if (0 != dk4socket_wc_find_address(array, remhost)) {
+
+
+#line 276 "dk4sock34.ctr"
+ back = dk4socket_complete_addresses(array, remport, locport);
+
+
+#line 278 "dk4sock34.ctr"
+ }
+ if (DK4_SOCKET_RESULT_FAILED == back) {
+
+#line 280 "dk4sock34.ctr"
+ if (0 != dk4socket_wc_find_host(array, remhost, remport, ip4, erp)) {
+ back = dk4socket_complete_addresses(array, remport, locport);
+ if (DK4_SOCKET_RESULT_FAILED == back) {
+
+#line 283 "dk4sock34.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ } else {
+
+#line 286 "dk4sock34.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ }
+ } else {
+
+#line 290 "dk4sock34.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 293 "dk4sock34.ctr"
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+}
+
+
+int
+dk4socket_udp_addresses_numeric(
+ dk4_sockaddr_storage_t *array,
+ const dkChar *remhost,
+ unsigned short remport,
+ unsigned short locport,
+ int ip4,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (
+ dk4socket_wc_udp_addresses_numeric(
+ array, remhost, remport, locport, ip4, erp
+ )
+ );
+#else
+ return (
+ dk4socket_c8_udp_addresses_numeric(
+ array, remhost, remport, locport, ip4, erp
+ )
+ );
+#endif
+}
+
+
diff --git a/support/dktools/dk4sock34.ctr b/support/dktools/dk4sock34.ctr
new file mode 100644
index 0000000000..ba221eed2d
--- /dev/null
+++ b/support/dktools/dk4sock34.ctr
@@ -0,0 +1,326 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4mem.h"
+#include "dk4sock.h"
+#include "dk4mai8dus.h"
+#include "dk4maowd.h"
+#include "dk4mao8d.h"
+#include "dk4rec24.h"
+
+
+
+$!trace-include
+
+
+
+#if DK4_ON_WINDOWS
+
+/** Attempt to convert an IPv4 or IPv6 address from text to address.
+ @param dptr Destination variable.
+ @param str Source text.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4socket_wc_find_address(dk4_sockaddr_storage_t *dptr, const wchar_t *str)
+{
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ struct sockaddr_in6 *in6;
+#endif
+ struct sockaddr_in *in4;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ IN6_ADDR addr6;
+#endif
+ IN_ADDR addr4;
+ int back = 0;
+ int res;
+ $? "+ dk4socket_wc_find_address"
+ res = dk4socket_wc_inet_pton(&addr4, sizeof(addr4), AF_INET, str, NULL);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ in4 = (struct sockaddr_in *)dptr;
+ in4->sin_family = AF_INET;
+ DK4_MEMCPY(&(in4->sin_addr), &addr4, sizeof(addr4));
+ back = 1;
+ } else {
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ res = dk4socket_wc_inet_pton(&addr6, sizeof(addr6), AF_INET6, str, NULL);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ in6 = (struct sockaddr_in6 *)dptr;
+ in6->sin6_family = AF_INET6;
+ DK4_MEMCPY(&(in6->sin6_addr), &addr6, sizeof(addr6));
+ back = 1;
+ }
+#endif
+ }
+ $? "- dk4socket_wc_find_address %d", back
+ return back;
+}
+
+/** Find address for one host name.
+ @param dptr Address of destination data structure.
+ @param remhost Remote host name.
+ @param remport Remote port number in host representation.
+ @param ip4 Flag: Prefer IPv4 over IPv6 addresses.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4socket_wc_find_host(
+ dk4_sockaddr_storage_t *dptr,
+ const wchar_t *remhost,
+ unsigned short remport,
+ int ip4,
+ dk4_er_t *erp
+)
+{
+#if DK4_HAVE_GETADDRINFO
+ /* +++ getaddrinfo +++ */
+ wchar_t buf[16*sizeof(unsigned short)];
+ ADDRINFOW hints;
+ ADDRINFOW *results = NULL;
+ ADDRINFOW *rptr = NULL;
+ int back = 0;
+ int res = 0;
+ $? "+ dk4socket_wc_find_host (getaddrinfo) \"%!ws\"", TR_LSTR(remhost)
+ res = dk4ma_write_wc_decimal_unsigned(
+ buf, DK4_SIZEOF(buf,wchar_t), (dk4_um_t)remport, 0, NULL
+ );
+ if (0 != res) {
+ DK4_MEMRES(&hints, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_protocol = 0;
+ hints.ai_flags = AI_NUMERICSERV;
+ res = GetAddrInfoW(remhost, buf, &hints, &results);
+ if ((0 == res) && (NULL != results)) { $? ". GetAddrInfoW"
+ if (0 != ip4) {
+ rptr = results;
+ while ((NULL != rptr) && (0 == back)) {
+ if ((0 < rptr->ai_addrlen) && (NULL != rptr->ai_addr)) {
+ if (AF_INET == rptr->ai_addr->sa_family) {
+ if (sizeof(dk4_sockaddr_storage_t) >= rptr->ai_addrlen) {
+ DK4_MEMCPY(dptr, rptr->ai_addr, rptr->ai_addrlen);
+ back = 1; $? ". found"
+ }
+#if TRACE_DEBUG
+ else { $? "! address too large"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! not IPv4"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! no address data"
+ }
+#endif
+ rptr = rptr->ai_next;
+ }
+ if (0 == back) {
+ rptr = results;
+ while ((NULL != rptr) && (0 == back)) {
+ if ((0 < rptr->ai_addrlen) && (NULL != rptr->ai_addr)) {
+ if (sizeof(dk4_sockaddr_storage_t) >= rptr->ai_addrlen) {
+ DK4_MEMCPY(dptr, rptr->ai_addr, rptr->ai_addrlen);
+ back = 1; $? "- found"
+ }
+#if TRACE_DEBUG
+ else { $? "! address to large"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! no address data"
+ }
+#endif
+ rptr = rptr->ai_next;
+ }
+ }
+ } else { $? ". any address fam"
+ rptr = results;
+ while ((NULL != rptr) && (0 == back)) {
+ if ((0 < rptr->ai_addrlen) && (NULL != rptr->ai_addr)) {
+ if (sizeof(dk4_sockaddr_storage_t) >= rptr->ai_addrlen) {
+ DK4_MEMCPY(dptr, rptr->ai_addr, rptr->ai_addrlen);
+ back = 1; $? ". found"
+ }
+#if TRACE_DEBUG
+ else { $? "! addr too large"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! no address data"
+ }
+#endif
+ rptr = rptr->ai_next;
+ }
+ }
+ } else { $? "! GetAddrInfoW"
+ }
+ if (NULL != results) { FreeAddrInfoW(results); }
+ }
+#if TRACE_DEBUG
+ else { $? "! failed to convert port number to text"
+ }
+#endif
+ $? "- dk4socket_wc_find_host %d", back
+ return back;
+ /* --- getaddrinfo --- */
+#else
+ /* +++ ! getaddrinfo +++ */
+#if DK4_HAVE_GETHOSTBYNAME
+ /* +++ gethostbyname +++ */
+ char hona[1040];
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ struct sockaddr_in6 *sa6;
+#endif
+ struct sockaddr_in *sa4;
+ struct hostent *hep = NULL;
+ int back = 0;
+ $? "+ dk4socket_wc_find_host (gethostbyname) \"%s\"", TR_LSTR(remhost)
+ if (0 != dk4recode_wchar_t_to_char(hona, sizeof(hona), remhost, erp)) {
+ hep = gethostbyname(hona);
+ if (NULL != hep) { $? ". hep"
+ if (NULL != hep->h_addr_list) { $? ". hep->h_addr_list"
+ if (NULL != *(hep->h_addr_list)) { $? ". *(hep->h_addr_list)"
+ switch (hep->h_addrtype) {
+ case AF_INET : { $? ". IPv4"
+ sa4 = (struct sockaddr_in *)dptr;
+ DK4_MEMRES(sa4, sizeof(struct sockaddr_in));
+ sa4->sin_family = AF_INET;
+ sa4->sin_port = dk4socket_htons(remport);
+ DK4_MEMCPY(&(sa4->sin_addr),*(hep->h_addr_list),sizeof(IN_ADDR));
+ back = 1; $? ". found"
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : { $? ". IPv6"
+ sa6 = (struct sockaddr_in6 *)dptr;
+ DK4_MEMRES(sa6, sizeof(struct sockaddr_in6));
+ sa6->sin6_family = AF_INET6;
+ sa6->sin_port = dk4socket_htons(remport);
+ DK4_MEMCPY(&(sa6->sin6_addr),*(hep->h_addr_list),sizeof(IN6_ADDR));
+ back = 1; $? ". found"
+ } break;
+#endif
+#if TRACE_DEBUG
+ default : { $? "! address type"
+ } break;
+#endif
+ }
+ }
+#if TRACE_DEBUG
+ else { $? "! *(hep->h_addr_list)"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! hep->h_addr_list"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! not found"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! recode"
+ }
+#endif
+ $? "- dk4socket_wc_find_host %d", back
+ return back;
+ /* --- gethostbyname --- */
+#else
+ /* +++ ! gethostbyname +++ */
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0; $? "! not supported"
+ /* --- ! gethostbyname --- */
+#endif
+ /* --- ! getaddrinfo --- */
+#endif
+}
+
+#endif
+
+int
+dk4socket_wc_udp_addresses_numeric(
+ dk4_sockaddr_storage_t *array,
+ const wchar_t *remhost,
+ unsigned short remport,
+ unsigned short locport,
+ int ip4,
+ dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+ int back = DK4_SOCKET_RESULT_FAILED;
+ $? "+ dk4socket_wc_udp_addresses_numeric DK4_ON_WINDOWS"
+ if ((NULL != array) && (NULL != remhost) && (0 < remport) && (0 < locport)) {
+ DK4_MEMRES(array, (2*sizeof(dk4_sockaddr_storage_t)));
+ if (0 != dk4socket_wc_find_address(array, remhost)) {
+ $? ". address pair found"
+ back = dk4socket_complete_addresses(array, remport, locport);
+ $? ". back = %d", back
+ }
+ if (DK4_SOCKET_RESULT_FAILED == back) { $? ". no pair"
+ if (0 != dk4socket_wc_find_host(array, remhost, remport, ip4, erp)) {
+ back = dk4socket_complete_addresses(array, remport, locport);
+ if (DK4_SOCKET_RESULT_FAILED == back) { $? "! complete"
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ } else { $? "! not found"
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ }
+ } else { $? "! arguments"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4socket_wc_udp_addresses_numeric DK4_ON_WINDOWS %d", back
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+}
+
+
+int
+dk4socket_udp_addresses_numeric(
+ dk4_sockaddr_storage_t *array,
+ const dkChar *remhost,
+ unsigned short remport,
+ unsigned short locport,
+ int ip4,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (
+ dk4socket_wc_udp_addresses_numeric(
+ array, remhost, remport, locport, ip4, erp
+ )
+ );
+#else
+ return (
+ dk4socket_c8_udp_addresses_numeric(
+ array, remhost, remport, locport, ip4, erp
+ )
+ );
+#endif
+}
+
+
diff --git a/support/dktools/dk4sock35.c b/support/dktools/dk4sock35.c
new file mode 100644
index 0000000000..16705599b5
--- /dev/null
+++ b/support/dktools/dk4sock35.c
@@ -0,0 +1,114 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sock35.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4sock35.c The dk4sock35 module.
+*/
+
+
+#line 8 "dk4sock35.ctr"
+
+#include "dk4sock.h"
+
+
+
+
+
+#line 14 "dk4sock35.ctr"
+
+
+
+dk4_socket_t
+dk4socket_udp_client_for_addr(
+ int addrfam,
+ struct sockaddr *pLocalAddr,
+ size_t szLocalAddr,
+ dk4_er_t *erp
+)
+{
+ dk4_socket_t back = INVALID_SOCKET;
+ int res;
+
+
+#line 28 "dk4sock35.ctr"
+ if ((NULL != pLocalAddr) && (0 < szLocalAddr)) {
+
+#line 29 "dk4sock35.ctr"
+ switch (addrfam) {
+ case PF_INET :
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case PF_INET6 :
+#endif
+ {
+
+#line 35 "dk4sock35.ctr"
+ back = dk4socket_open(addrfam, SOCK_DGRAM, 0, erp);
+ if (INVALID_SOCKET != back) {
+ res = dk4socket_bind(back, pLocalAddr, szLocalAddr, erp);
+ if (DK4_SOCKET_RESULT_SUCCESS != res) {
+
+#line 39 "dk4sock35.ctr"
+ (void)dk4socket_close(back, NULL);
+ back = INVALID_SOCKET;
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 44 "dk4sock35.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 49 "dk4sock35.ctr"
+ }
+#endif
+ } break;
+ default : {
+
+#line 53 "dk4sock35.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } break;
+ }
+ } else {
+
+#line 57 "dk4sock35.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 59 "dk4sock35.ctr"
+ return back;
+}
+
diff --git a/support/dktools/dk4sock35.ctr b/support/dktools/dk4sock35.ctr
new file mode 100644
index 0000000000..2b58ea1293
--- /dev/null
+++ b/support/dktools/dk4sock35.ctr
@@ -0,0 +1,61 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+%% module
+
+#include "dk4sock.h"
+
+
+
+$!trace-include
+
+
+
+dk4_socket_t
+dk4socket_udp_client_for_addr(
+ int addrfam,
+ struct sockaddr *pLocalAddr,
+ size_t szLocalAddr,
+ dk4_er_t *erp
+)
+{
+ dk4_socket_t back = INVALID_SOCKET;
+ int res;
+ $? "+ dk4socket_udp_client_for_addr"
+ if ((NULL != pLocalAddr) && (0 < szLocalAddr)) { $? ". arguments"
+ switch (addrfam) {
+ case PF_INET :
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case PF_INET6 :
+#endif
+ { $? ". pf ok"
+ back = dk4socket_open(addrfam, SOCK_DGRAM, 0, erp);
+ if (INVALID_SOCKET != back) {
+ res = dk4socket_bind(back, pLocalAddr, szLocalAddr, erp);
+ if (DK4_SOCKET_RESULT_SUCCESS != res) { $? "! bind"
+ (void)dk4socket_close(back, NULL);
+ back = INVALID_SOCKET;
+ }
+#if TRACE_DEBUG
+ else { $? ". bind"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! socket"
+ }
+#endif
+ } break;
+ default : { $? "! invalid pf"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } break;
+ }
+ } else { $? "! arguments"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4socket_udp_client_for_addr %d", (int)back
+ return back;
+}
+
diff --git a/support/dktools/dk4sock36.c b/support/dktools/dk4sock36.c
new file mode 100644
index 0000000000..c8b3921f3e
--- /dev/null
+++ b/support/dktools/dk4sock36.c
@@ -0,0 +1,103 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sock36.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4sock36.c The dk4sock36 module.
+*/
+
+
+#line 10 "dk4sock36.ctr"
+
+#include "dk4sock.h"
+
+
+
+
+
+#line 16 "dk4sock36.ctr"
+
+
+
+dk4_socket_t
+dk4socket_c8_udp_client_for_host(
+ dk4_sockaddr_storage_t *array,
+ const char *remhost,
+ unsigned short remport,
+ unsigned short locport,
+ int ip4,
+ dk4_er_t *erp
+)
+{
+ struct sockaddr *sa;
+ dk4_socket_t back = INVALID_SOCKET;
+ int res;
+
+
+#line 33 "dk4sock36.ctr"
+ if ((NULL != array) && (NULL != remhost) && (0 != remport) && (0 != locport))
+ {
+
+#line 35 "dk4sock36.ctr"
+ res = dk4socket_c8_udp_addresses_numeric(
+ array, remhost, remport, locport, ip4, erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+
+#line 39 "dk4sock36.ctr"
+ sa = (struct sockaddr *)(&(array[1]));
+ back = dk4socket_udp_client_for_addr(
+ sa->sa_family, sa, sizeof(dk4_sockaddr_storage_t), erp
+ );
+
+#line 43 "dk4sock36.ctr"
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 46 "dk4sock36.ctr"
+ }
+#endif
+ }
+ else
+ {
+
+#line 51 "dk4sock36.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 54 "dk4sock36.ctr"
+ return back;
+}
+
diff --git a/support/dktools/dk4sock36.ctr b/support/dktools/dk4sock36.ctr
new file mode 100644
index 0000000000..3b467b67bf
--- /dev/null
+++ b/support/dktools/dk4sock36.ctr
@@ -0,0 +1,56 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4sock.h"
+
+
+
+$!trace-include
+
+
+
+dk4_socket_t
+dk4socket_c8_udp_client_for_host(
+ dk4_sockaddr_storage_t *array,
+ const char *remhost,
+ unsigned short remport,
+ unsigned short locport,
+ int ip4,
+ dk4_er_t *erp
+)
+{
+ struct sockaddr *sa;
+ dk4_socket_t back = INVALID_SOCKET;
+ int res;
+ $? "+ dk4socket_c8_udp_client_for_host \"%s\" %u %u", TR_8STR(remhost), (unsigned)remport, (unsigned)locport
+ if ((NULL != array) && (NULL != remhost) && (0 != remport) && (0 != locport))
+ { $? ". arguments"
+ res = dk4socket_c8_udp_addresses_numeric(
+ array, remhost, remport, locport, ip4, erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) { $? ". address pair found"
+ sa = (struct sockaddr *)(&(array[1]));
+ back = dk4socket_udp_client_for_addr(
+ sa->sa_family, sa, sizeof(dk4_sockaddr_storage_t), erp
+ ); $? ". back = %d", (int)back
+ }
+#if TRACE_DEBUG
+ else { $? "! address pair not found"
+ }
+#endif
+ }
+ else
+ { $? "! arguments"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4socket_c8_udp_client_for_host %d", (int)back
+ return back;
+}
+
diff --git a/support/dktools/dk4sock37.c b/support/dktools/dk4sock37.c
new file mode 100644
index 0000000000..3e115c56e2
--- /dev/null
+++ b/support/dktools/dk4sock37.c
@@ -0,0 +1,126 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sock37.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4sock37.c The dk4sock37 module.
+*/
+
+
+#line 10 "dk4sock37.ctr"
+
+#include "dk4sock.h"
+
+
+
+
+
+#line 16 "dk4sock37.ctr"
+
+
+
+dk4_socket_t
+dk4socket_wc_udp_client_for_host(
+ dk4_sockaddr_storage_t *array,
+ const wchar_t *remhost,
+ unsigned short remport,
+ unsigned short locport,
+ int ip4,
+ dk4_er_t *erp
+)
+{
+ struct sockaddr *sa;
+ dk4_socket_t back = INVALID_SOCKET;
+ int res;
+
+
+#line 33 "dk4sock37.ctr"
+ if ((NULL != array) && (NULL != remhost) && (0 != remport) && (0 != locport))
+ {
+
+#line 35 "dk4sock37.ctr"
+ res = dk4socket_wc_udp_addresses_numeric(
+ array, remhost, remport, locport, ip4, erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+
+#line 39 "dk4sock37.ctr"
+ sa = (struct sockaddr *)(&(array[1]));
+ back = dk4socket_udp_client_for_addr(
+ sa->sa_family, sa, sizeof(dk4_sockaddr_storage_t), erp
+ );
+
+#line 43 "dk4sock37.ctr"
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 46 "dk4sock37.ctr"
+ }
+#endif
+ }
+ else
+ {
+
+#line 51 "dk4sock37.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 54 "dk4sock37.ctr"
+ return back;
+}
+
+
+
+dk4_socket_t
+dk4socket_udp_client_for_host(
+ dk4_sockaddr_storage_t *array,
+ const dkChar *remhost,
+ unsigned short remport,
+ unsigned short locport,
+ int ip4,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (
+ dk4socket_wc_udp_client_for_host(array, remhost, remport, locport, ip4, erp)
+ );
+#else
+ return (
+ dk4socket_c8_udp_client_for_host(array, remhost, remport, locport, ip4, erp)
+ );
+#endif
+}
+
diff --git a/support/dktools/dk4sock37.ctr b/support/dktools/dk4sock37.ctr
new file mode 100644
index 0000000000..d03a4cd2fc
--- /dev/null
+++ b/support/dktools/dk4sock37.ctr
@@ -0,0 +1,79 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4sock.h"
+
+
+
+$!trace-include
+
+
+
+dk4_socket_t
+dk4socket_wc_udp_client_for_host(
+ dk4_sockaddr_storage_t *array,
+ const wchar_t *remhost,
+ unsigned short remport,
+ unsigned short locport,
+ int ip4,
+ dk4_er_t *erp
+)
+{
+ struct sockaddr *sa;
+ dk4_socket_t back = INVALID_SOCKET;
+ int res;
+ $? "+ dk4socket_wc_udp_client_for_host \"%!ws\" %u %u", TR_LSTR(remhost), (unsigned)remport, (unsigned)locport
+ if ((NULL != array) && (NULL != remhost) && (0 != remport) && (0 != locport))
+ { $? ". arguments"
+ res = dk4socket_wc_udp_addresses_numeric(
+ array, remhost, remport, locport, ip4, erp
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) { $? ". addresses found"
+ sa = (struct sockaddr *)(&(array[1]));
+ back = dk4socket_udp_client_for_addr(
+ sa->sa_family, sa, sizeof(dk4_sockaddr_storage_t), erp
+ ); $? ". back = %d", (int)back
+ }
+#if TRACE_DEBUG
+ else { $? "! address pair not found"
+ }
+#endif
+ }
+ else
+ { $? "! arguments"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4socket_wc_udp_client_for_host %d", (int)back
+ return back;
+}
+
+
+
+dk4_socket_t
+dk4socket_udp_client_for_host(
+ dk4_sockaddr_storage_t *array,
+ const dkChar *remhost,
+ unsigned short remport,
+ unsigned short locport,
+ int ip4,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (
+ dk4socket_wc_udp_client_for_host(array, remhost, remport, locport, ip4, erp)
+ );
+#else
+ return (
+ dk4socket_c8_udp_client_for_host(array, remhost, remport, locport, ip4, erp)
+ );
+#endif
+}
+
diff --git a/support/dktools/dk4socka.h b/support/dktools/dk4socka.h
new file mode 100644
index 0000000000..fb046a69bb
--- /dev/null
+++ b/support/dktools/dk4socka.h
@@ -0,0 +1,415 @@
+#ifndef DK4SOCKA_H_INCLUDED
+#define DK4SOCKA_H_INCLUDED 1
+
+/** @file dk4socka.h Socket functions with application support.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+#ifndef DK4CONST_H_INCLUDED
+#include "dk4const.h"
+#endif
+#ifndef DK4SOCK_H_INCLUDED
+#include "dk4sock.h"
+#endif
+#ifndef DK4APP_H_INCLUDED
+#include "dk4app.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ Logging functions.
+ ------------------
+ Module: dk4socka01
+*/
+
+/** Retrieve number of log texts in localized string array.
+ @return Number of elements.
+*/
+size_t
+dk4socket_log_num_texts(void);
+
+/** Retrieve function name and error code text.
+ On success the function sets the output variables to valid
+ pointers, on error they are set to NULL.
+ @param fctname Address of pointer variable for function name.
+ @param msgtext Address of pointer variable for error code text.
+ @param app Application structure.
+ @param erp Error report.
+*/
+void
+dk4socket_log_fctname_msg(
+ const dkChar **fctname,
+ const dkChar **msgtext,
+ dk4_app_t *app,
+ dk4_er_t *erp
+);
+
+/** Retrieve array containing localized strings.
+ @param app Application structure, required here.
+ @return Pointer to localized strings array.
+*/
+const dkChar * const *
+dk4socket_log_texts(dk4_app_t *app);
+
+/** Issue simple log message, one component.
+ @param app Application structure.
+ @param ll Log level.
+ @param imain Index of main text in array of localized texts.
+ @param erp Error report containing details, may be NULL.
+*/
+void
+dk4socket_log_simple_1(
+ dk4_app_t *app,
+ int ll,
+ size_t imain,
+ dk4_er_t *erp
+);
+
+
+/** Issue simple log message, one component.
+ @param app Application structure.
+ @param ll Log level.
+ @param i1 Index of main text in array of localized texts.
+ @param i2 Index of second text in array of localized texts.
+ @param ctext Customized text piece.
+ @param erp Error report containing details, may be NULL.
+*/
+void
+dk4socket_log_simple_3(
+ dk4_app_t *app,
+ int ll,
+ size_t i1,
+ size_t i2,
+ const dkChar *ctext,
+ dk4_er_t *erp
+);
+
+/** Issue simple log message, five components.
+ @param app Application structure.
+ @param ll Log level.
+ @param i1 Index of main text in array of localized texts.
+ @param i2 Index of third text in array of localized texts.
+ @param i3 Index of fifth text in array of localized texts.
+ @param ct1 Customized text piece 1.
+ @param ct2 Customized text piece 2.
+ @param erp Error report containing details, may be NULL.
+*/
+void
+dk4socket_log_simple_5(
+ dk4_app_t *app,
+ int ll,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ const dkChar *ct1,
+ const dkChar *ct2,
+ dk4_er_t *erp
+);
+
+/*
+ Bring socket subsystem up and down.
+ -----------------------------------
+ Module: dk4socka02
+*/
+/** Bring socket subsystem up.
+ @param app Application structure for diagnostics.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error.
+
+ Error codes:
+ * DK4_E_SOCKET_UP<br>
+ with WSAGetLastError() result in iDetails1 if a WinSock
+ error occured.
+*/
+int
+dk4socket_up_app(dk4_app_t *app);
+
+/** Bring socket subsystem down.
+ @param app Application structure for diagnostics.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error.
+
+ Error codes:
+ * DK4_E_SOCKET_DOWN<br>
+ with WSAGetLastError() result in iDetails1 if a WinSock
+ error occured.
+*/
+int
+dk4socket_down_app(dk4_app_t *app);
+
+/*
+ Open and close sockets.
+ -----------------------
+ Module: dk4socka03
+*/
+
+/** Open a socket.
+ @param af Address family (AF_INET or AF_INET6).
+ @param tp Socket type (SOCK_STREAM or SOCK_DGRAM).
+ @param pr Protocol number.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Valid socket on success, INVALID_SOCKET on error.
+*/
+dk4_socket_t
+dk4socket_open_app(int af, int tp, int pr, dk4_app_t *app);
+
+/** Shut down a socket.
+ @param so Socket to shutdown.
+ @param how How to shut down the socket, one from:
+ DK4_SOCKET_SHUT_READ, DK4_SOCKET_SHUT_WRITE, or
+ DK4_SOCKET_SHUT_RDWR.
+ @param app Application structure for diagnostics, may be NULL.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error.
+*/
+int
+dk4socket_shutdown_app(dk4_socket_t so, int how, dk4_app_t *app);
+
+/** Close a socket.
+ @param so Socket to close.
+ @param app Application structure for diagnostics, may be NULL.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error.
+*/
+int
+dk4socket_close_app(dk4_socket_t so, dk4_app_t *app);
+
+/*
+ Bind local address.
+ -------------------
+ Module: dk4socka04
+*/
+
+/** Bind local address.
+ @param sock Socket to configure.
+ @param pAddr Pointer to address variable.
+ @param szAddr Size of address.
+ @param app Application structure for diagnostics, may be NULL.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error.
+*/
+int
+dk4socket_bind_app(
+ dk4_socket_t sock,
+ const struct sockaddr *pAddr,
+ size_t szAddr,
+ dk4_app_t *app
+);
+
+/*
+ Listen and accept incoming connection requests.
+ -----------------------------------------------
+ Module: dk4socka05
+*/
+
+/** Listen for incoming connection requests.
+ @param sock Server side socket already bound to local address.
+ @param bl Backlog (number of connection requests to keep
+ in the queue).
+ @param app Application structure for diagnostics, may be NULL.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error.
+*/
+int
+dk4socket_listen_app(
+ dk4_socket_t sock,
+ int bl,
+ dk4_app_t *app
+);
+
+/** Accept an incoming connection.
+ @param sock Server socket in listening state.
+ @param pAddr Buffer for remote address.
+ @param pSzAddr Pointer to address buffer size variable,
+ in: buffer size, out: used buffer size.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Valid socket on success, INVALID_SOCKET on error.
+*/
+dk4_socket_t
+dk4socket_accept_app(
+ dk4_socket_t sock,
+ struct sockaddr *pAddr,
+ size_t *pSzAddr,
+ dk4_app_t *app
+);
+
+
+/*
+ Create a tcp client socket.
+ ---------------------------
+ Module: dk4socka07
+*/
+
+/** Create TCP connection to specified remote host and service.
+ @param hostname Remote host name to connect to.
+ @param svcname Remote service name to connect to.
+ @param lsvcname Local service name, may be NULL.
+ @param secs Seconds for timeout.
+ @param usecs Microseconds for timeout.
+ @param app Application structure for diagnostics,
+ may be NULL.
+ @return Valid socket on success, INVALID_SOCKET on error.
+*/
+dk4_socket_t
+dk4socket_tcp_client_for_host_service_app(
+ const dkChar *hostname,
+ const dkChar *svcname,
+ const dkChar *lsvcname,
+ long secs,
+ long usecs,
+ dk4_app_t *app
+);
+
+/** Create TCP connection to specified remote host and service.
+ @param hostname Remote host name to connect to.
+ @param svcname Remote service name to connect to.
+ @param lsvcname Local service name, may be NULL.
+ @param secs Seconds for timeout.
+ @param usecs Microseconds for timeout.
+ @param nsrv Flag: Service names contain numbers only.
+ @param app Application structure for diagnostics,
+ may be NULL.
+ @return Valid socket on success, INVALID_SOCKET on error.
+*/
+dk4_socket_t
+dk4socket_tcp_client_for_host_num_service_app(
+ const dkChar *hostname,
+ const dkChar *svcname,
+ const dkChar *lsvcname,
+ long secs,
+ long usecs,
+ int nsrv,
+ dk4_app_t *app
+);
+
+/** Create TCP connection to specified remote host and port.
+ @param hostname Remote host name to connect to.
+ @param portno Remote port to connect to.
+ @param lportno Local port number, 0 for arbitrary port.
+ @param secs Seconds for timeout.
+ @param usecs Microseconds for timeout.
+ @param app Application structure for diagnostics,
+ may be NULL.
+ @return Valid socket on success, INVALID_SOCKET on error.
+*/
+dk4_socket_t
+dk4socket_tcp_client_for_host_port_app(
+ const dkChar *hostname,
+ unsigned short portno,
+ unsigned short lportno,
+ long secs,
+ long usecs,
+ dk4_app_t *app
+);
+
+/*
+ Send and receive data.
+ ----------------------
+ Module: dk4socka08
+*/
+
+/** Attempt to send data.
+ @param sock Socket to use.
+ @param buf Address of buffer containing data.
+ @param pszbuf Pointer to size variable (in: buffer size, out:
+ bytes transferred).
+ @param flags Flags.
+ @param secs Seconds for timeout.
+ @param usecs Microseconds for timeout.
+ @param app Application structure for diagnostics, may be NULL.
+ @param complain Flag: Complain on partial send.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_IN_PROGRESS on partial success (not all bytes
+ transferred),
+ DK4_SOCKET_RESULT_FAILED on error.
+*/
+int
+dk4socket_send_attempt_app(
+ dk4_socket_t sock,
+ const void *buf,
+ size_t *pszbuf,
+ int flags,
+ long secs,
+ long usecs,
+ dk4_app_t *app,
+ int complain
+);
+
+/** Send data.
+ @param sock Socket to use.
+ @param buf Address of buffer containing data.
+ @param pszbuf Pointer to size variable (in: buffer size, out:
+ bytes transferred).
+ @param flags Flags.
+ @param secs Seconds for timeout.
+ @param usecs Microseconds for timeout.
+ @param app Application structure for diagnostics, may be NULL.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_IN_PROGRESS on partial success (not all bytes
+ transferred),
+ DK4_SOCKET_RESULT_FAILED on error.
+*/
+int
+dk4socket_send_app(
+ dk4_socket_t sock,
+ const void *buf,
+ size_t *pszbuf,
+ int flags,
+ long secs,
+ long usecs,
+ dk4_app_t *app
+);
+
+/** Receive data.
+ @param sock Socket to use.
+ @param buf Address of buffer for data.
+ @param pszbuf Pointer to size variable (in: buffer size, out:
+ bytes received).
+ @param flags Flags.
+ @param secs Seconds for timeout.
+ @param usecs Microseconds for timeout.
+ @param app Application structure for diagnostics, may be NULL.
+ @return DK4_SOCKET_RESULT_SUCCESS on success,
+ DK4_SOCKET_RESULT_FAILED on error.
+*/
+int
+dk4socket_recv_app(
+ dk4_socket_t sock,
+ void *buf,
+ size_t *pszbuf,
+ int flags,
+ long secs,
+ long usecs,
+ dk4_app_t *app
+);
+
+/** Create listener socket set.
+ @param servicename Service name or number.
+ @param backlog Number of queued requests.
+ @param local Flag: Listen on localhost interface only.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to socket set on success, NULL on error.
+*/
+dk4_socket_set_t *
+dk4socket_set_service_app(
+ const dkChar *servicename,
+ int backlog,
+ int local,
+ dk4_app_t *app
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* ifndef DK4SOCKA_H_INCLUDED */
+
diff --git a/support/dktools/dk4socka01.c b/support/dktools/dk4socka01.c
new file mode 100644
index 0000000000..1722cfde96
--- /dev/null
+++ b/support/dktools/dk4socka01.c
@@ -0,0 +1,1758 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4socka01.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4socka01.c The dk4socka01 module.
+*/
+
+
+#line 10 "dk4socka01.ctr"
+
+
+#include "dk4sock.h"
+#include "dk4socka.h"
+#include "dk4mem.h"
+#include "dk4maodd.h"
+#include "dk4maodh.h"
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+
+
+
+#line 34 "dk4socka01.ctr"
+
+
+
+/** Constant text keywords, not localized.
+*/
+static const dkChar * const dk4socket_app_kwnl[] = {
+/* 0 */
+dkT("dk4sock.str"),
+
+/* 1 */
+dkT("\n\t"),
+
+/* 2 */
+dkT(": "),
+
+/* 3 */
+dkT("WSAStartup"),
+
+/* 4 */
+dkT("WSACleanup"),
+
+/* 5 */
+dkT("socket"),
+
+/* 6 */
+dkT("close"),
+
+/* 7 */
+dkT("closesocket"),
+
+/* 8 */
+dkT("bind"),
+
+/* 9 */
+dkT("listen"),
+
+/* 10 */
+dkT("accept"),
+
+/* 11 */
+dkT("connect"),
+
+/* 12 */
+dkT("setsockopt"),
+
+/* 13 */
+dkT("ioctlsocket"),
+
+/* 14 */
+dkT("fcntl"),
+
+/* 15 */
+dkT("select"),
+
+/* 16 */
+dkT("getsockopt"),
+
+/* 17 */
+dkT("getaddrinfo"),
+
+/* 18 */
+dkT("getnameinfo"),
+
+/* 19 */
+dkT("gethostbyname"),
+
+/* 20 */
+dkT("getservbyname"),
+
+/* 21 */
+dkT("GetAddrInfoW"),
+
+/* 22 */
+dkT("inet_ntop"),
+
+/* 23 */
+dkT("shutdown"),
+
+/* 24 */
+dkT("send/sendto"),
+
+/* 25 */
+dkT("recv/recvfrom"),
+
+/* 26 */
+dkT("inet_pton"),
+
+NULL
+
+
+#line 126 "dk4socka01.ctr"
+};
+
+
+
+/** Constant text keywords, replaced by localized version if found.
+*/
+static const dkChar * const dk4socket_app_kw_def[] = {
+/* 0 */
+dkT("Failed to initialize Winsock subsystem!"),
+
+/* 1 */
+dkT("Failed to shut down Winsock subsystem!"),
+
+/* 2 */
+dkT("Failed to create socket!"),
+
+/* 3 */
+dkT("Failed to close socket!"),
+
+/* 4 */
+dkT("Failed to bind local address!"),
+
+/* 5 */
+dkT("Failed to listen for incoming connection requests!"),
+
+/* 6 */
+dkT("Failed to accept incoming connection request!"),
+
+/* 7 */
+dkT("Failed to connect to remote address!"),
+
+/* 8 */
+dkT("Failed to modify ``reusable'' option for socket!"),
+
+/* 9 */
+dkT("Failed to modify ``non-blocking'' option for socket!"),
+
+/* 10 */
+dkT("Failed to retrieve remote address(es)!"),
+
+/* 11 */
+dkT("Failed to retrieve local address(es)!"),
+
+/* 12 */
+dkT("Failed to retrieve remote host address!"),
+
+/* 13 */
+dkT("Failed to retrieve port number for remote service!"),
+
+/* 14 */
+dkT("Failed to retrieve port number for local service!"),
+
+/* 15 */
+dkT("Failed to convert text to ASCII!"),
+
+/* 16 */
+dkT("\""),
+
+/* 17 */
+dkT("\"!"),
+
+/* 18 */
+dkT("Failed to obtain local address(es)!"),
+
+/* 19 */
+dkT("Port/service: "),
+
+/* 20 */
+dkT("Failed to obtain remote address(es)!"),
+
+/* 21 */
+dkT("Host: "),
+
+/* 22 */
+dkT("Port/service: "),
+
+/* 23 */
+dkT("Service/port not found: \""),
+
+/* 24 */
+dkT("\"!"),
+
+/* 25 */
+dkT("Failed to convert service/port to ASCII: \""),
+
+/* 26 */
+dkT("\"!"),
+
+/* 27 */
+dkT("No matching pair of local/remote addresses found!"),
+
+/* 28 */
+dkT("Illegal local port number!"),
+
+/* 29 */
+dkT("Illegal remote port number!"),
+
+/* 30 */
+dkT("Connection established."),
+
+/* 31 */
+dkT("Illegal address length in gethostbyname() result!"),
+
+/* 32 */
+dkT("Illegal address family in gethostbyname() result!"),
+
+/* 33 */
+dkT("Remote host not found: \""),
+
+/* 34 */
+dkT("\"!"),
+
+/* 35 */
+dkT("Non-ASCII characters in host name: \n\t\""),
+
+/* 36 */
+dkT("\"!"),
+
+/* 37 */
+dkT("errno="),
+
+/* 38 */
+dkT(" (0x"),
+
+/* 39 */
+dkT(")"),
+
+/* 40 */
+dkT("WSAGetLastError()="),
+
+/* 41 */
+dkT("Failed to create TCP connection!"),
+
+/* 42 */
+dkT("Local: "),
+
+/* 43 */
+dkT("Remote: "),
+
+/* 44 */
+dkT("Timeout while attempting to connect."),
+
+/* 45 */
+dkT("Invalid arguments passed to function, probably a bug."),
+
+/* 46 */
+dkT("No matching local/remote address pair available!"),
+
+/* 47 */
+dkT("Network subsystem not yet ready."),
+
+/* 48 */
+dkT("Winsock version not supported!"),
+
+/* 49 */
+dkT("Blocking Winsock operation in progress!"),
+
+/* 50 */
+dkT("Process limit for Winsock reached!"),
+
+/* 51 */
+dkT("Invalid parameters passed to function!"),
+
+/* 52 */
+dkT("Winsock not initialized!"),
+
+/* 53 */
+dkT("Network subsystem has failed!"),
+
+/* 54 */
+dkT("Address family not supported!"),
+
+/* 55 */
+dkT("No more socket/file descriptors available"),
+
+/* 56 */
+dkT("No buffer space available!"),
+
+/* 57 */
+dkT("Protocol not supported!"),
+
+/* 58 */
+dkT("Wrong protocol type for socket!"),
+
+/* 59 */
+dkT("Service provider failed to initialize!"),
+
+/* 60 */
+dkT("Socket type not supported by address family!"),
+
+/* 61 */
+dkT("Unusable service provider version!"),
+
+/* 62 */
+dkT("Invalid/incomplete procedure table from service provider!"),
+
+/* 63 */
+dkT("Insufficient permissions!"),
+
+/* 64 */
+dkT("Address already in use!"),
+
+/* 65 */
+dkT("Address not available!"),
+
+/* 66 */
+dkT("File descriptor is not a socket!"),
+
+/* 67 */
+dkT("Host has no addresses in specified address family!"),
+
+/* 68 */
+dkT("Temporary problem on name server, try again later!"),
+
+/* 69 */
+dkT("Illegal flag combination!"),
+
+/* 70 */
+dkT("Name server failure!"),
+
+/* 71 */
+dkT("Address family not supported!"),
+
+/* 72 */
+dkT("Out of memory!"),
+
+/* 73 */
+dkT("No network address found for host!"),
+
+/* 74 */
+dkT("No such name or number!"),
+
+/* 75 */
+dkT("Service not available through specified socket type!"),
+
+/* 76 */
+dkT("Unsupported socket type or inconsistent arguments!"),
+
+/* 77 */
+dkT("System error, check errno!"),
+
+/* 78 */
+dkT("Argument buffer overflow!"),
+
+/* 79 */
+dkT("Resource temporarily locked, try again later!"),
+
+/* 80 */
+dkT("Attempt already in progress!"),
+
+/* 81 */
+dkT("Not a file descriptor!"),
+
+/* 82 */
+dkT("No-one listening on remote address!"),
+
+/* 83 */
+dkT("Connection reset by peer!"),
+
+/* 84 */
+dkT("Operation would result in deadlock!"),
+
+/* 85 */
+dkT("Destination address required!"),
+
+/* 86 */
+dkT("Timeout values too large!"),
+
+/* 87 */
+dkT("Operation is in progress."),
+
+/* 88 */
+dkT("Operation interrupted by signal!"),
+
+/* 89 */
+dkT("Socket is already connected!"),
+
+/* 90 */
+dkT("I/O error occured!"),
+
+/* 91 */
+dkT("Symbolic link loop detected!"),
+
+/* 92 */
+dkT("No more file descriptors available for process!"),
+
+/* 93 */
+dkT("Address or path name too long!"),
+
+/* 94 */
+dkT("Network unreachable!"),
+
+/* 95 */
+dkT("No more file descriptors available on system!"),
+
+/* 96 */
+dkT("File or path component does not exist or is empty!"),
+
+/* 97 */
+dkT("Failed to set a lock!"),
+
+/* 98 */
+dkT("Attempt to retrieve or modify unsupported option!"),
+
+/* 99 */
+dkT("Path component is not a directory!"),
+
+/* 100 */
+dkT("Provided buffer size is too small!"),
+
+/* 101 */
+dkT("Operation not supported by socket type or protocol!"),
+
+/* 102 */
+dkT("File system is mounted read-only!"),
+
+/* 103 */
+dkT("Timed out!"),
+
+/* 104 */
+dkT("Numeric overflow in file size/position calculation!"),
+
+/* 105 */
+dkT("Connection closed due to timeout or other failure!"),
+
+/* 106 */
+dkT("Host unreachable!"),
+
+/* 107 */
+dkT("Blocking Winsock operation interrupted by WSACancelBlockingCall()!"),
+
+/* 108 */
+dkT("Socket is in listening state!"),
+
+/* 109 */
+dkT("No local address bound yet!"),
+
+/* 110 */
+dkT("Socket is not in listening state!"),
+
+/* 111 */
+dkT("Invalid shutdown parameter"),
+
+/* 112 */
+dkT("Message size too large!"),
+
+/* 113 */
+dkT("Connection closed, failures in keep-alive tests!"),
+
+/* 114 */
+dkT("Not connected!"),
+
+/* 115 */
+dkT("Failed to initialize socket provider!"),
+
+/* 116 */
+dkT("Socket already shut down!"),
+
+/* 117 */
+dkT("Operation would block!"),
+
+/* 118 */
+dkT("Host not found (authorative answer)!"),
+
+/* 119 */
+dkT("Service provider returned invalid/incomplete procedure table!"),
+
+/* 120 */
+dkT("Invalid service provider version!"),
+
+/* 121 */
+dkT("Protocol error!"),
+
+/* 122 */
+dkT("Insufficient stream resources!"),
+
+/* 123 */
+dkT("Protocol family not supported!"),
+
+/* 124 */
+dkT("Connection to remote machine no longer active!"),
+
+/* 125 */
+dkT("Server exited before completing connection!"),
+
+/* 126 */
+dkT("Protocol family and type not found in network configuration!"),
+
+/* 127 */
+dkT("Stale NFS file handle!"),
+
+/* 128 */
+dkT("Failed to shut down socket!"),
+
+/* 129 */
+dkT("Failed to bind local address\n\t\""),
+
+/* 130 */
+dkT("\"!"),
+
+/* 131 */
+dkT("Failed to connect to remote address\n\t\""),
+
+/* 132 */
+dkT("\"!"),
+
+/* 133 */
+dkT("Send operation completed partially, only "),
+
+/* 134 */
+dkT(" of "),
+
+/* 135 */
+dkT(" bytes!"),
+
+/* 136 */
+dkT("Send operation completed partially!"),
+
+/* 137 */
+dkT("Send operation failed!"),
+
+/* 138 */
+dkT("Failed to receive data!"),
+
+/* 139 */
+dkT("Failed to create listener sockets!"),
+
+/* 140 */
+dkT("Listening: "),
+
+/* 141 */
+dkT("Failed to obtain allowed peer from string:\n\t\""),
+
+/* 142 */
+dkT("\"!"),
+
+NULL
+
+
+#line 641 "dk4socka01.ctr"
+};
+
+
+/** Number of elements in the dk4socket_app_kw_def array.
+*/
+static const size_t dk4socket_sz_kw_def =
+sizeof(dk4socket_app_kw_def)/sizeof(DK4_PCDKCHAR);
+
+
+
+size_t
+dk4socket_log_num_texts(void)
+{
+ return (dk4socket_sz_kw_def);
+}
+
+
+
+const dkChar * const *
+dk4socket_log_texts(dk4_app_t *app)
+{
+ const dkChar * const *back = dk4socket_app_kw_def;
+
+ if (NULL != app) {
+ back = dk4app_string_table(app,dk4socket_app_kwnl[0],dk4socket_app_kw_def);
+ }
+ return back;
+}
+
+
+
+void
+dk4socket_log_fctname_msg(
+ const dkChar **fctname,
+ const dkChar **msgtext,
+ dk4_app_t *app,
+ dk4_er_t *erp
+)
+{
+ const dkChar * const *msgtexts = dk4socket_app_kw_def;
+ const dkChar *mytext = NULL;
+ if ((NULL != app) && (NULL != erp)) {
+ msgtexts =
+ dk4app_string_table(app, dk4socket_app_kwnl[0], dk4socket_app_kw_def);
+ if (NULL != fctname) {
+ switch (erp->ec) {
+ case DK4_E_SOCKET_GETADDRINFO : {
+#if DK4_CHAR_SIZE > 1
+ *fctname = dk4socket_app_kwnl[21];
+#else
+ *fctname = dk4socket_app_kwnl[17];
+#endif
+ } break;
+ case DK4_E_SOCKET_GETADDRLOC : {
+#if DK4_CHAR_SIZE > 1
+ *fctname = dk4socket_app_kwnl[21];
+#else
+ *fctname = dk4socket_app_kwnl[17];
+#endif
+ } break;
+ case DK4_E_SOCKET_UP : {
+ *fctname = dk4socket_app_kwnl[3];
+ } break;
+ case DK4_E_SOCKET_DOWN : {
+ *fctname = dk4socket_app_kwnl[4];
+ } break;
+ case DK4_E_SOCKET_SOCKET : {
+ *fctname = dk4socket_app_kwnl[5];
+ } break;
+ case DK4_E_SOCKET_CLOSE : {
+#if DK4_ON_WINDOWS
+ *fctname = dk4socket_app_kwnl[7];
+#else
+ *fctname = dk4socket_app_kwnl[6];
+#endif
+ } break;
+ case DK4_E_SOCKET_BIND : {
+ *fctname = dk4socket_app_kwnl[8];
+ } break;
+ case DK4_E_SOCKET_CONNECT : {
+ *fctname = dk4socket_app_kwnl[11];
+ } break;
+ case DK4_E_SOCKET_LISTEN : {
+ *fctname = dk4socket_app_kwnl[9];
+ } break;
+ case DK4_E_SOCKET_ACCEPT : {
+ *fctname = dk4socket_app_kwnl[10];
+ } break;
+ case DK4_E_SOCKET_SHUTDOWN : {
+ *fctname = dk4socket_app_kwnl[23];
+ } break;
+ case DK4_E_SOCKET_SEND : {
+ *fctname = dk4socket_app_kwnl[24];
+ } break;
+ case DK4_E_SOCKET_RECV : {
+ *fctname = dk4socket_app_kwnl[25];
+ } break;
+ case DK4_E_SOCKET_SELECT : {
+ *fctname = dk4socket_app_kwnl[15];
+ } break;
+ case DK4_E_SOCKET_SETSOCKOPT : {
+ *fctname = dk4socket_app_kwnl[12];
+ } break;
+ case DK4_E_SOCKET_GETSOCKOPT : {
+ *fctname = dk4socket_app_kwnl[16];
+ } break;
+ case DK4_E_SOCKET_IOCTLSOCKET : {
+ *fctname = dk4socket_app_kwnl[13];
+ } break;
+ case DK4_E_SOCKET_FCNTL : {
+ *fctname = dk4socket_app_kwnl[14];
+ } break;
+ case DK4_E_SOCKET_GETSERVBYNAME : {
+ *fctname = dk4socket_app_kwnl[20];
+ } break;
+ case DK4_E_SOCKET_GETHOSTBYNAME : {
+ *fctname = dk4socket_app_kwnl[19];
+ } break;
+ case DK4_E_SOCKET_INET_NTOP : {
+ *fctname = dk4socket_app_kwnl[22];
+ } break;
+ case DK4_E_SOCKET_INET_PTON : {
+ *fctname = dk4socket_app_kwnl[26];
+ } break;
+ default : {
+ *fctname = NULL;
+ } break;
+ }
+ }
+ if (NULL != msgtext) {
+#if (DK4_CHAR_SIZE == 1) && (!DK4_ON_WINDOWS)
+ switch (erp->ec) {
+ case DK4_E_SOCKET_GETADDRINFO :
+ case DK4_E_SOCKET_GETADDRLOC :
+ {
+#if DK4_HAVE_GETADDRINFO
+ mytext = gai_strerror((erp->dt).iDetails1);
+#endif
+ } break;
+ case DK4_E_SOCKET_UP :
+ case DK4_E_SOCKET_DOWN :
+ case DK4_E_SOCKET_SOCKET :
+ case DK4_E_SOCKET_CLOSE :
+ case DK4_E_SOCKET_BIND :
+ case DK4_E_SOCKET_CONNECT :
+ case DK4_E_SOCKET_LISTEN :
+ case DK4_E_SOCKET_ACCEPT :
+ case DK4_E_SOCKET_SHUTDOWN :
+ case DK4_E_SOCKET_SEND :
+ case DK4_E_SOCKET_RECV :
+ case DK4_E_SOCKET_SELECT :
+ case DK4_E_SOCKET_SETSOCKOPT :
+ case DK4_E_SOCKET_GETSOCKOPT :
+ case DK4_E_SOCKET_IOCTLSOCKET :
+ case DK4_E_SOCKET_FCNTL :
+ case DK4_E_SOCKET_INET_NTOP :
+ case DK4_E_SOCKET_INET_PTON :
+ {
+ mytext = strerror((erp->dt).iDetails1);
+ } break;
+ }
+#endif
+ if (NULL == mytext) {
+
+
+#line 805 "dk4socka01.ctr"
+ switch (erp->ec) {
+#if DK4_ON_WINDOWS
+ /* +++++ Windows +++++ */
+ case DK4_E_SOCKET_GETADDRINFO :
+ case DK4_E_SOCKET_GETADDRLOC :
+ {
+ switch (erp->dt.iDetails1) {
+ case EAI_AGAIN : {
+ /* Temporary problem in name resolution */
+ mytext = msgtexts[68];
+ } break;
+ case EAI_BADFLAGS : {
+ /* Incorrect flag combination */
+ mytext = msgtexts[69];
+ } break;
+ case EAI_FAIL : {
+ /* Nonrecoverable failure in name resolution */
+ mytext = msgtexts[70];
+ } break;
+ case EAI_FAMILY : {
+ /* Unsupported address family */
+ mytext = msgtexts[71];
+ } break;
+ case EAI_MEMORY: {
+ /* Not enough memory available */
+ mytext = msgtexts[72];
+ } break;
+ case EAI_NONAME : {
+ /* No address found for host */
+ mytext = msgtexts[74];
+ } break;
+ case EAI_SERVICE : {
+ /* Service type not supported for specified socket type */
+ mytext = msgtexts[75];
+ } break;
+ case EAI_SOCKTYPE : {
+ /* Socket type not supported */
+ mytext = msgtexts[76];
+ } break;
+ }
+ } break;
+ case DK4_E_SOCKET_UP :
+ case DK4_E_SOCKET_DOWN :
+ case DK4_E_SOCKET_SOCKET :
+ case DK4_E_SOCKET_CLOSE :
+ case DK4_E_SOCKET_BIND :
+ case DK4_E_SOCKET_CONNECT :
+ case DK4_E_SOCKET_LISTEN :
+ case DK4_E_SOCKET_ACCEPT :
+ case DK4_E_SOCKET_SHUTDOWN :
+ case DK4_E_SOCKET_SEND :
+ case DK4_E_SOCKET_RECV :
+ case DK4_E_SOCKET_SELECT :
+ case DK4_E_SOCKET_SETSOCKOPT :
+ case DK4_E_SOCKET_GETSOCKOPT :
+ case DK4_E_SOCKET_IOCTLSOCKET :
+ case DK4_E_SOCKET_FCNTL :
+ case DK4_E_SOCKET_GETSERVBYNAME :
+ case DK4_E_SOCKET_GETHOSTBYNAME :
+ case DK4_E_SOCKET_INET_NTOP :
+ case DK4_E_SOCKET_INET_PTON :
+ {
+ switch (erp->dt.iDetails1) {
+ case ERROR_INVALID_PARAMETER : {
+ /* inet_ntop: Buffer not present or too small */
+ mytext = msgtexts[100];
+ } break;
+ case WSAEACCES : {
+ /* bind: Insufficient permissions */
+ /* connect, send, sendto */
+ mytext = msgtexts[63];
+ } break;
+ case WSAEADDRINUSE : {
+ /* bind: Address is already in use */
+ /* connect, listen */
+ mytext = msgtexts[64];
+ } break;
+ case WSAEADDRNOTAVAIL : {
+ /* bind: Address is not valid in context, not a local address*/
+ /* connect: Invalid remote address */
+ /* sendto */
+ mytext = msgtexts[65];
+ } break;
+ case WSAEAFNOSUPPORT : {
+ /* socket: Addres family is not supported */
+ /* connect, sendto, inet_ntop, inet_pton */
+ mytext = msgtexts[54];
+ } break;
+ case WSAEALREADY : {
+ /* connect: Non-blocking connect already running for socket */
+ mytext = msgtexts[80];
+ } break;
+ case WSAECONNABORTED : {
+ /* send: Timeout or other failure, close the socket */
+ /* sendto, recv, shutdown */
+ mytext = msgtexts[105];
+ } break;
+ case WSAECONNREFUSED : {
+ /* connect: Connect attempt forcefully rejected */
+ mytext = msgtexts[82];
+ } break;
+ case WSAECONNRESET : {
+ /* accept: Connection request followed by termination request */
+ /* send, sendto, recv, recvfrom, shutdown */
+ mytext = msgtexts[83];
+ } break;
+ case WSAEDESTADDRREQ : {
+ /* sendto: Destination address required */
+ mytext = msgtexts[85];
+ } break;
+ case WSAEFAULT : {
+ /* WSAStartup: Invalid data pointer */
+ /* bind, connect, accept, select, ioctlsocket, gethostbyname */
+ /* send, sendto, recv, recvfrom, inet_pton */
+ mytext = msgtexts[51];
+ } break;
+ case WSAEHOSTUNREACH : {
+ /* connect: Host unreachable */
+ /* send, sendto */
+ mytext = msgtexts[106];
+ } break;
+ case WSAEINPROGRESS : {
+ /* WSAStartup: Blocking Winsock 1.1 operation in progress */
+ /* WSACleanup, socket, bind, connect, listen, select */
+ /* ioctlsocket, closesocket, gethostbyname, getservbyname */
+ /* send, sendto, recv, recvfrom, shutdown */
+ mytext = msgtexts[49];
+ } break;
+ case WSAEINTR : {
+ /* connect: Blocking call cancelled by WSACancelBlockingCall */
+ /* accept, select, closesocket, gethostbyname, getservbyname */
+ /* send, sendto, recv, recvfrom */
+ mytext = msgtexts[107];
+ } break;
+ case WSAEINVAL : {
+ /* socket: Invalid argument supplied */
+ /* bind, select, send, sendto, recv, recvfrom */
+ /* connect: The socket is in listening state */
+ /* listen: Socket not yet bound */
+ /* accept: Not listening */
+ /* shutdown: Invalid shutdown parameter */
+ switch (erp->ec) {
+ case DK4_E_SOCKET_CONNECT : {
+ mytext = msgtexts[108];
+ } break;
+ case DK4_E_SOCKET_LISTEN : {
+ mytext = msgtexts[109];
+ } break;
+ case DK4_E_SOCKET_ACCEPT : {
+ mytext = msgtexts[110];
+ } break;
+ case DK4_E_SOCKET_SHUTDOWN : {
+ mytext = msgtexts[111];
+ } break;
+ default : {
+ mytext = msgtexts[51];
+ } break;
+ }
+ } break;
+ case WSAEINVALIDPROCTABLE : {
+ /* socket: Service provider returned invalid procedure table */
+ mytext = msgtexts[119];
+ } break;
+ case WSAEINVALIDPROVIDER : {
+ /* socket: Invalid provider version */
+ mytext = msgtexts[120];
+ } break;
+ case WSAEISCONN : {
+ /* connect: Socket already connected */
+ /* listen */
+ /* recvfrom */
+ mytext = msgtexts[89];
+ } break;
+ case WSAEMFILE : {
+ /* socket: No more file descriptors available */
+ /* listen, accept */
+ mytext = msgtexts[92];
+ } break;
+ case WSAEMSGSIZE : {
+ /* send: Message size too large */
+ /* sendto, recv, recvfrom */
+ mytext = msgtexts[112];
+ } break;
+ case WSAENETDOWN : {
+ /* WSACleanup: Network subsystem has failed */
+ /* socket, bind, connect, listen, accept, select, ioctlsocket */
+ /* closesocket, gethostbyname, getservbyname, send, sendto */
+ /* recv, recvfrom, shutdown */
+ mytext = msgtexts[53];
+ } break;
+ case WSAENETRESET : {
+ /* send: Connection closed while keep-alive tests */
+ /* sendto, recv, recvfrom */
+ mytext = msgtexts[113];
+ } break;
+ case WSAENETUNREACH : {
+ /* connect: Network unreachable */
+ /* sendto */
+ mytext = msgtexts[94];
+ } break;
+ case WSAENOBUFS : {
+ /* socket: No buffer space available */
+ /* bind, connect, listen, accept, send, sendto */
+ mytext = msgtexts[56];
+ } break;
+ case WSAENOTCONN : {
+ /* send: Not connected */
+ /* recv, shutdown */
+ mytext = msgtexts[114];
+ } break;
+ case WSAENOTSOCK : {
+ /* bind: file descriptor is not a socket */
+ /* connect, listen, connect, select, ioctlsocket */
+ /* closesocket, send, sendto, recv, recvfrom, shutdown */
+ mytext = msgtexts[66];
+ } break;
+ case WSAEOPNOTSUPP : {
+ /* listen: Not supported by socket type */
+ /* accept, send, sendto, recv, recvfrom */
+ mytext = msgtexts[101];
+ } break;
+ case WSAEPROCLIM : {
+ /* WSAStartup: Limit of processes using Winsock is reached */
+ mytext = msgtexts[50];
+ } break;
+ case WSAEPROTONOSUPPORT : {
+ /* socket: Unsupported protocol */
+ mytext = msgtexts[57];
+ } break;
+ case WSAEPROTOTYPE : {
+ /* socket: Specified protocol invalid for socket */
+ mytext = msgtexts[58];
+ } break;
+ case WSAEPROVIDERFAILEDINIT : {
+ /* socket: Failed to initialize socket provider */
+ mytext = msgtexts[115];
+ } break;
+ case WSAESHUTDOWN : {
+ /* send: Socket was shut down */
+ /* sendto, recv, recvfrom */
+ mytext = msgtexts[116];
+ } break;
+ case WSAESOCKTNOSUPPORT : {
+ /* socket: Socket type not supported by address family */
+ mytext = msgtexts[60];
+ } break;
+ case WSAETIMEDOUT : {
+ /* connect: Timeout */
+ /* send, sendto, recv, recvfrom */
+ mytext = msgtexts[103];
+ } break;
+ case WSAEWOULDBLOCK : {
+ /* connect: Connection not finished on non-blocking socket */
+ /* accept: Non-blocking, not connection attempts are present */
+ /* closesocket, send, sendto, recv, recvfrom */
+ mytext = msgtexts[117];
+ } break;
+ case WSAHOST_NOT_FOUND : {
+ /* gethostbyname: Host not found (authorative answer) */
+ /* getservbyname */
+ mytext = msgtexts[118];
+ } break;
+ case WSANO_DATA : {
+ /* gethostbyname: Host name is valid, but no data found */
+ /* getservbyname */
+ mytext = msgtexts[73];
+ } break;
+ case WSANO_RECOVERY : {
+ /* gethostbyname: Unrecoverable error */
+ /* getservbyname */
+ mytext = msgtexts[70];
+ } break;
+ case WSANOTINITIALISED : {
+ /* WSACleanup: Winsock not initialized */
+ /* socket, bind, connect, listen, accept, select, ioctlsocket */
+ /* closesocket, gethostbyname, getservbyname, send, sendto */
+ /* recv, recvfrom, shutdown */
+ mytext = msgtexts[52];
+ } break;
+ case WSASYSNOTREADY : {
+ /* WSAStartup: Underlying subsystem not yet read */
+ mytext = msgtexts[47];
+ } break;
+ case WSATRY_AGAIN : {
+ /* gethostbyname: Host not found (non-authorative, or server
+ failure */
+ /* getservbyname */
+ mytext = msgtexts[68];
+ } break;
+ case WSAVERNOTSUPPORTED : {
+ /* WSAStartup: The requested version is not supported */
+ mytext = msgtexts[48];
+ } break;
+ }
+ } break;
+ /* ----- Windows ----- */
+#else
+ /* +++++ non-Windows +++++ */
+
+ case DK4_E_SOCKET_GETADDRINFO :
+ case DK4_E_SOCKET_GETADDRLOC :
+ {
+ switch (erp->dt.iDetails1) {
+#ifdef EAI_ADDRFAMILY
+ case EAI_ADDRFAMILY : {
+ mytext = msgtexts[67];
+ } break;
+#endif
+#ifdef EAI_AGAIN
+ case EAI_AGAIN : {
+ mytext = msgtexts[68];
+ } break;
+#endif
+#ifdef EAI_BADFLAGS
+ case EAI_BADFLAGS : {
+ mytext = msgtexts[69];
+ } break;
+#endif
+#ifdef EAI_FAIL
+ case EAI_FAIL : {
+ mytext = msgtexts[70];
+ } break;
+#endif
+#ifdef EAI_FAMILY
+ case EAI_FAMILY : {
+ mytext = msgtexts[71];
+ } break;
+#endif
+#ifdef EAI_MEMORY
+ case EAI_MEMORY : {
+ mytext = msgtexts[72];
+ } break;
+#endif
+#ifdef EAI_NODATA
+ case EAI_NODATA : {
+ mytext = msgtexts[73];
+ } break;
+#endif
+#ifdef EAI_NONAME
+ case EAI_NONAME : {
+ mytext = msgtexts[74];
+ } break;
+#endif
+#ifdef EAI_OVERFLOW
+ case EAI_OVERFLOW : {
+ mytext = msgtexts[78];
+ } break;
+#endif
+#ifdef EAI_SERVICE
+ case EAI_SERVICE : {
+ mytext = msgtexts[75];
+ } break;
+#endif
+#ifdef EAI_SOCKTYPE
+ case EAI_SOCKTYPE : {
+ mytext = msgtexts[76];
+ } break;
+#endif
+#ifdef EAI_SYSTEM
+ case EAI_SYSTEM : {
+ mytext = msgtexts[77];
+ } break;
+#endif
+ }
+ } break;
+ case DK4_E_SOCKET_GETHOSTBYNAME : {
+ switch (erp->dt.iDetails1) {
+#ifdef HOST_NOT_FOUND
+ case HOST_NOT_FOUND : {
+ mytext = msgtexts[73];
+ } break;
+#endif
+#ifdef NO_ADDRESS
+ case NO_ADDRESS : {
+ mytext = msgtexts[73];
+ } break;
+#endif
+#if defined(NO_DATA) && ((!defined(NO_ADDRESS)) || (NO_DATA != NO_ADDRESS))
+ case NO_DATA : {
+ mytext = msgtexts[73];
+ } break;
+#endif
+#ifdef NO_RECOVERY
+ case NO_RECOVERY : {
+ mytext = msgtexts[70];
+ } break;
+#endif
+#ifdef TRY_AGAIN
+ case TRY_AGAIN : {
+ mytext = msgtexts[68];
+ } break;
+#endif
+ }
+ } break;
+ case DK4_E_SOCKET_UP :
+ case DK4_E_SOCKET_DOWN :
+ case DK4_E_SOCKET_SOCKET :
+ case DK4_E_SOCKET_CLOSE :
+ case DK4_E_SOCKET_BIND :
+ case DK4_E_SOCKET_CONNECT :
+ case DK4_E_SOCKET_LISTEN :
+ case DK4_E_SOCKET_ACCEPT :
+ case DK4_E_SOCKET_SELECT :
+ case DK4_E_SOCKET_SETSOCKOPT :
+ case DK4_E_SOCKET_GETSOCKOPT :
+ case DK4_E_SOCKET_IOCTLSOCKET :
+ case DK4_E_SOCKET_FCNTL :
+ case DK4_E_SOCKET_INET_NTOP :
+ case DK4_E_SOCKET_INET_PTON :
+ {
+ switch (erp->dt.iDetails1) {
+#ifdef EACCES
+ case EACCES : {
+ /* socket: Insufficient permissions */
+ /* bind, connect, listen, send */
+ mytext = msgtexts[63];
+ } break;
+#endif
+#ifdef EADDRINUSE
+ case EADDRINUSE : {
+ /* bind: Address already in used */
+ /* connect */
+ /* listen */
+ mytext = msgtexts[64];
+ } break;
+#endif
+#ifdef EADDRNOTAVAIL
+ case EADDRNOTAVAIL : {
+ /* bind: nonexistent interface or address is not local */
+ /* connect */
+ mytext = msgtexts[65];
+ } break;
+#endif
+#ifdef EAFNOSUPPORT
+ case EAFNOSUPPORT : {
+ /* socket: Address family not supported */
+ /* bind: Mismatch address and address family */
+ /* connect, sendto, inet_pton */
+ mytext = msgtexts[54];
+ } break;
+#endif
+#ifdef EAGAIN
+ case EAGAIN : {
+ /* accept: Socket non-blocking, no incoming requests */
+ /* send, recv */
+ mytext = msgtexts[79];
+ } break;
+#endif
+#ifdef EALREADY
+ case EALREADY : {
+ /* connect: Already connected */
+ mytext = msgtexts[80];
+ } break;
+#endif
+#ifdef EBADF
+ case EBADF : {
+ /* close: Not a file descriptr */
+ /* shutdown, bind, connect */
+ /* listen, accept, send, recv */
+ mytext = msgtexts[81];
+ } break;
+#endif
+#ifdef ECONNABORTED
+ case ECONNABORTED : {
+ /* accept: Connection attempt aborted */
+ mytext = msgtexts[105];
+ } break;
+#endif
+#ifdef ECONNREFUSED
+ case ECONNREFUSED : {
+ /* connect: No-one listening on remote address */
+ /* recv */
+ mytext = msgtexts[82];
+ } break;
+#endif
+#ifdef ECONNRESET
+ case ECONNRESET : {
+ /* connect: Remote host denied connection */
+ /* send, recv */
+ mytext = msgtexts[83];
+ } break;
+#endif
+#ifdef EDEADLK
+ case EDEADLK : {
+ mytext = msgtexts[84];
+ } break;
+#endif
+#ifdef EDESTADDRREQ
+ case EDESTADDRREQ : {
+ /* bind: Address is a NULL pointer */
+ /* listen: Socket not yet bound */
+ /* send */
+ mytext = msgtexts[85];
+ } break;
+#endif
+#ifdef EDOM
+ case EDOM : {
+ mytext = msgtexts[86];
+ } break;
+#endif
+#ifdef EFAULT
+ case EFAULT : {
+ /* bind: Pointer to outside usable address space */
+ /* connect, accept, send, recv */
+ mytext = msgtexts[51];
+ } break;
+#endif
+#ifdef EHOSTUNREACH
+ case EHOSTUNREACH : {
+ /* connect: Remote host unreachable */
+ /* send */
+ mytext = msgtexts[106];
+ } break;
+#endif
+#ifdef EINPROGRESS
+ case EINPROGRESS : {
+ /* connect: Socket is non-blocking, operation would block */
+ mytext = msgtexts[87];
+ } break;
+#endif
+#ifdef EINTR
+ case EINTR : {
+ /* close: Interrupted by signal */
+ /* connect, accept, send, recv */
+ mytext = msgtexts[88];
+ } break;
+#endif
+#ifdef EINVAL
+ case EINVAL : {
+ /* socket: unknown protocol, illegal protocol family or flags */
+ /* shutdown: Invalid argument */
+ /* bind: Socket already bound */
+ /* bind: wrong address length */
+ /* bind: Socket already shut down */
+ /* connect: Wrong address length or address family */
+ /* listen: Socket already connected */
+ /* listen: Socket already shut down */
+ /* accept: Socket not listening, or illegal socket value */
+ /* accept: Invalid flags */
+ /* send: Invalid arguments , recv */
+ mytext = msgtexts[51];
+ } break;
+#endif
+#ifdef EISCONN
+ case EISCONN : {
+ /* bind: Socket already connected */
+ /* connect, send */
+ mytext = msgtexts[89];
+ } break;
+#endif
+#ifdef EISDIR
+ case EISDIR : {
+ /* bind: Address is a NULL pointer */
+ mytext = msgtexts[85];
+ } break;
+#endif
+#ifdef EIO
+ case EIO : {
+ /* close: I/O error */
+ /* connect, send */
+ mytext = msgtexts[90];
+ } break;
+#endif
+#ifdef ELOOP
+ case ELOOP : {
+ /* bind: Too many symbolic links or symlink loop */
+ /* connect, send */
+ mytext = msgtexts[91];
+ } break;
+#endif
+#ifdef EMFILE
+ case EMFILE : {
+ /* socket: Process file table overflow */
+ /* accept */
+ mytext = msgtexts[92];
+ } break;
+#endif
+#ifdef EMSGSIZE
+ case EMSGSIZE : {
+ /* send: Message size too large */
+ mytext = msgtexts[112];
+ } break;
+#endif
+#ifdef ENAMETOOLONG
+ case ENAMETOOLONG : {
+ /* bind: Address is too long */
+ /* connect, send */
+ mytext = msgtexts[93];
+ } break;
+#endif
+#ifdef ENETDOWN
+ case ENETDOWN : {
+ /* connect: Local network interface is down */
+ /* send */
+ mytext = msgtexts[53];
+ } break;
+#endif
+#ifdef ENETUNREACH
+ case ENETUNREACH : {
+ /* connect: Network is unreachable */
+ /* send */
+ mytext = msgtexts[94];
+ } break;
+#endif
+#ifdef ENFILE
+ case ENFILE : {
+ /* socket: System file table overflow */
+ /* accept */
+ mytext = msgtexts[95];
+ } break;
+#endif
+#ifdef ENOBUFS
+ case ENOBUFS : {
+ /* socket: No memory for buffers */
+ /* shutdown: Insufficient resources */
+ /* connect, listen, accept, send */
+ mytext = msgtexts[56];
+ } break;
+#endif
+#ifdef ENODEV
+ case ENODEV : {
+ /* accept: Protocol family and type not in network config */
+ mytext = msgtexts[126];
+ } break;
+#endif
+#ifdef ENOENT
+ case ENOENT : {
+ /* bind: File does not exist */
+ /* connect, send */
+ mytext = msgtexts[96];
+ } break;
+#endif
+#ifdef ENOLCK
+ case ENOLCK : {
+ mytext = msgtexts[97];
+ } break;
+#endif
+#ifdef ENOLINK
+ case ENOLINK : {
+ /* close: Connection to remote machine no longer active */
+ mytext = msgtexts[124];
+ } break;
+#endif
+#ifdef ENOMEM
+ case ENOMEM : {
+ /* socket: Not enough memory available */
+ /* bind, accept, send, recv */
+ mytext = msgtexts[72];
+ } break;
+#endif
+#ifdef ENOPROTOOPT
+ case ENOPROTOOPT : {
+ mytext = msgtexts[98];
+ } break;
+#endif
+#ifdef ENOSR
+ case ENOSR : {
+ /* socket: Insufficient stream resources */
+ /* bind, connect, accept, send, recv, shutdown */
+ mytext = msgtexts[122];
+ } break;
+#endif
+#ifdef ENOTCONN
+ case ENOTCONN : {
+ /* shutdown: Not connected */
+ /* send, recv */
+ mytext = msgtexts[114];
+ } break;
+#endif
+#ifdef ENOTDIR
+ case ENOTDIR : {
+ /* bind: Component or path prefix is not a directory */
+ /* connect, send */
+ mytext = msgtexts[99];
+ } break;
+#endif
+#ifdef ENOTSOCK
+ case ENOTSOCK : {
+ /* shutdown: Not a socket */
+ /* bind, connect, listen, accept, send, recv */
+ mytext = msgtexts[66];
+ } break;
+#endif
+#ifdef ENOSPC
+ case ENOSPC : {
+ /* inet_pton: Insufficient buffer size */
+ /* close: Not enough space on device */
+ mytext = msgtexts[100];
+ } break;
+#endif
+#ifdef ENXIO
+ case ENXIO : {
+ /* connect: Server exited before completing connection */
+ mytext = msgtexts[125];
+ } break;
+#endif
+#ifdef EOPNOTSUPP
+ case EOPNOTSUPP : {
+ /* bind: Operation not supported by socket type */
+ /* connect: Socket is listening */
+ /* listen: Socket can not listen */
+ /* accept: Not a stream socket */
+ /* send: Illegal flags, recv */
+ mytext = msgtexts[101];
+ } break;
+#endif
+#ifdef EPERM
+ case EPERM : {
+ /* connect: Insufficient permissions */
+ /* accept: Firewall rules forbid connection */
+ mytext = msgtexts[63];
+ } break;
+#endif
+#ifdef EPFNOSUPPORT
+ case EPFNOSUPPORT : {
+ /* socket: Protocol family not supported */
+ mytext = msgtexts[123];
+ } break;
+#endif
+#ifdef EPIPE
+ case EPIPE : {
+ mytext = msgtexts[116];
+ } break;
+#endif
+#ifdef EPROTONOSUPPORT
+ case EPROTONOSUPPORT : {
+ /* socket: Protocol type not supported in this domain */
+ mytext = msgtexts[57];
+ } break;
+#endif
+#ifdef EPROTO
+ case EPROTO : {
+ /* accept: Protocol error */
+ mytext = msgtexts[121];
+ } break;
+#endif
+#ifdef EPROTOTYPE
+ case EPROTOTYPE : {
+ /* socket: Socket type not supported by protocol */
+ /* connect: Remote type is different address family as local */
+ mytext = msgtexts[58];
+ } break;
+#endif
+#ifdef EROFS
+ case EROFS : {
+ /* bind: File system is mounted read-only */
+ mytext = msgtexts[102];
+ } break;
+#endif
+#ifdef ESTALE
+ case ESTALE : {
+ /* recv: Stale NFS file handle */
+ mytext = msgtexts[127];
+ } break;
+#endif
+#ifdef ETIMEDOUT
+ case ETIMEDOUT : {
+ /* connect: Timed out */
+ /* recv */
+ mytext = msgtexts[103];
+ } break;
+#endif
+#ifdef EOVERFLOW
+ case EOVERFLOW : {
+ mytext = msgtexts[104];
+ } break;
+#endif
+#if defined(EWOULDBLOCK) && ((!defined(EAGAIN)) || (EWOULDBLOCK != EAGAIN))
+ case EWOULDBLOCK : {
+ /* accept: Socket non-blocking, no incoming requests */
+ /* send, recv */
+ mytext = msgtexts[79];
+ } break;
+#endif
+ }
+ } break;
+ /* ----- non-Windows ----- */
+#endif
+ }
+ }
+ *msgtext = mytext;
+ }
+ }
+}
+
+
+
+void
+dk4socket_log_simple_1(
+ dk4_app_t *app,
+ int ll,
+ size_t imain,
+ dk4_er_t *erp
+)
+{
+ dkChar b1[16*sizeof(dk4_um_t)]; /* decimal */
+ dkChar b2[16*sizeof(dk4_um_t)]; /* hexadecimal */
+ const dkChar *fctn = NULL; /* Function name */
+ const dkChar *errt = NULL; /* Error text */
+ const dkChar *msgt[16]; /* Message components */
+ const dkChar * const *msga; /* Localized texts array */
+ size_t used = 0; /* Number of used components */
+ int res = 0; /* Conversion result */
+
+ if (0 != dk4app_log_do(app, ll)) {
+ msga = dk4app_string_table(app,dk4socket_app_kwnl[0],dk4socket_app_kw_def);
+ if (dk4socket_sz_kw_def > imain) {
+ msgt[used++] = msga[imain];
+ dk4socket_log_fctname_msg(&fctn, &errt, app, erp);
+ if (NULL != fctn) {
+ if (NULL != errt) {
+ msgt[used++] = dk4socket_app_kwnl[1];
+ msgt[used++] = fctn;
+ msgt[used++] = dk4socket_app_kwnl[2];
+ msgt[used++] = errt;
+ } else {
+ res = dk4ma_write_decimal_signed(
+ b1, DK4_SIZEOF(b1,dkChar), (dk4_um_t)(erp->dt.iDetails1), 0, NULL
+ );
+ if (0 != res) {
+ res = dk4ma_write_hex_signed(
+ b2, DK4_SIZEOF(b2,dkChar), (dk4_im_t)(erp->dt.iDetails1), 8, NULL
+ );
+ if (0 != res) {
+ msgt[used++] = dk4socket_app_kwnl[1];
+ msgt[used++] = fctn;
+ msgt[used++] = dk4socket_app_kwnl[2];
+#if DK4_ON_WINDOWS
+ msgt[used++] = msga[40];
+#else
+ msgt[used++] = msga[37];
+#endif
+ msgt[used++] = b1;
+ msgt[used++] = msga[38];
+ msgt[used++] = b2;
+ msgt[used++] = msga[39];
+ }
+ }
+ }
+ } else {
+ if (NULL != errt) {
+ msgt[used++] = dk4socket_app_kwnl[1];
+ msgt[used++] = errt;
+ } else {
+ }
+ }
+ dk4app_log_msg(app, ll, msgt, used);
+ }
+ }
+}
+
+
+
+void
+dk4socket_log_simple_3(
+ dk4_app_t *app,
+ int ll,
+ size_t i1,
+ size_t i2,
+ const dkChar *ctext,
+ dk4_er_t *erp
+)
+{
+ dkChar b1[16*sizeof(dk4_um_t)]; /* decimal */
+ dkChar b2[16*sizeof(dk4_um_t)]; /* hexadecimal */
+ const dkChar *fctn = NULL; /* Function name */
+ const dkChar *errt = NULL; /* Error text */
+ const dkChar *msgt[16]; /* Message components */
+ const dkChar * const *msga; /* Localized texts array */
+ size_t used = 0; /* Number of used components */
+ int res = 0; /* Conversion result */
+
+ if (0 != dk4app_log_do(app, ll)) {
+ msga = dk4app_string_table(app,dk4socket_app_kwnl[0],dk4socket_app_kw_def);
+ if ((dk4socket_sz_kw_def > i1) && (dk4socket_sz_kw_def > i2)) {
+ msgt[used++] = msga[i1];
+ if (NULL != ctext) { msgt[used++] = ctext; }
+ msgt[used++] = msga[i2];
+ dk4socket_log_fctname_msg(&fctn, &errt, app, erp);
+ if (NULL != fctn) {
+ if (NULL != errt) {
+ msgt[used++] = dk4socket_app_kwnl[1];
+ msgt[used++] = fctn;
+ msgt[used++] = dk4socket_app_kwnl[2];
+ msgt[used++] = errt;
+ } else {
+ res = dk4ma_write_decimal_signed(
+ b1, DK4_SIZEOF(b1,dkChar), (dk4_um_t)(erp->dt.iDetails1), 0, NULL
+ );
+ if (0 != res) {
+ res = dk4ma_write_hex_signed(
+ b2, DK4_SIZEOF(b2,dkChar), (dk4_im_t)(erp->dt.iDetails1), 8, NULL
+ );
+ if (0 != res) {
+ msgt[used++] = dk4socket_app_kwnl[1];
+ msgt[used++] = fctn;
+ msgt[used++] = dk4socket_app_kwnl[2];
+#if DK4_ON_WINDOWS
+ msgt[used++] = msga[40];
+#else
+ msgt[used++] = msga[37];
+#endif
+ msgt[used++] = b1;
+ msgt[used++] = msga[38];
+ msgt[used++] = b2;
+ msgt[used++] = msga[39];
+ }
+ }
+ }
+ } else {
+ if (NULL != errt) {
+ msgt[used++] = dk4socket_app_kwnl[1];
+ msgt[used++] = errt;
+ } else {
+ }
+ }
+ dk4app_log_msg(app, ll, msgt, used);
+ }
+ }
+}
+
+
+
+void
+dk4socket_log_simple_5(
+ dk4_app_t *app,
+ int ll,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ const dkChar *ct1,
+ const dkChar *ct2,
+ dk4_er_t *erp
+)
+{
+ dkChar b1[16*sizeof(dk4_um_t)]; /* decimal */
+ dkChar b2[16*sizeof(dk4_um_t)]; /* hexadecimal */
+ const dkChar *fctn = NULL; /* Function name */
+ const dkChar *errt = NULL; /* Error text */
+ const dkChar *msgt[16]; /* Message components */
+ const dkChar * const *msga; /* Localized texts array */
+ size_t used = 0; /* Number of used components */
+ int res = 0; /* Conversion result */
+
+ if (0 != dk4app_log_do(app, ll)) {
+ msga = dk4app_string_table(app,dk4socket_app_kwnl[0],dk4socket_app_kw_def);
+ if ((dk4socket_sz_kw_def > i1) && (dk4socket_sz_kw_def > i2)) {
+ msgt[used++] = msga[i1];
+ if (NULL != ct1) { msgt[used++] = ct1; }
+ msgt[used++] = msga[i2];
+ if (NULL != ct2) { msgt[used++] = ct2; }
+ msgt[used++] = msga[i3];
+ dk4socket_log_fctname_msg(&fctn, &errt, app, erp);
+ if (NULL != fctn) {
+ if (NULL != errt) {
+ msgt[used++] = dk4socket_app_kwnl[1];
+ msgt[used++] = fctn;
+ msgt[used++] = dk4socket_app_kwnl[2];
+ msgt[used++] = errt;
+ } else {
+ res = dk4ma_write_decimal_signed(
+ b1, DK4_SIZEOF(b1,dkChar), (dk4_um_t)(erp->dt.iDetails1), 0, NULL
+ );
+ if (0 != res) {
+ res = dk4ma_write_hex_signed(
+ b2, DK4_SIZEOF(b2,dkChar), (dk4_im_t)(erp->dt.iDetails1), 8, NULL
+ );
+ if (0 != res) {
+ msgt[used++] = dk4socket_app_kwnl[1];
+ msgt[used++] = fctn;
+ msgt[used++] = dk4socket_app_kwnl[2];
+#if DK4_ON_WINDOWS
+ msgt[used++] = msga[40];
+#else
+ msgt[used++] = msga[37];
+#endif
+ msgt[used++] = b1;
+ msgt[used++] = msga[38];
+ msgt[used++] = b2;
+ msgt[used++] = msga[39];
+ }
+ }
+ }
+ } else {
+ if (NULL != errt) {
+ msgt[used++] = dk4socket_app_kwnl[1];
+ msgt[used++] = errt;
+ } else {
+ }
+ }
+ dk4app_log_msg(app, ll, msgt, used);
+ }
+ }
+}
+
diff --git a/support/dktools/dk4socka01.ctr b/support/dktools/dk4socka01.ctr
new file mode 100644
index 0000000000..0822476329
--- /dev/null
+++ b/support/dktools/dk4socka01.ctr
@@ -0,0 +1,1799 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+
+#include "dk4sock.h"
+#include "dk4socka.h"
+#include "dk4mem.h"
+#include "dk4maodd.h"
+#include "dk4maodh.h"
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+
+$!trace-include
+
+
+
+/** Constant text keywords, not localized.
+*/
+static const dkChar * const dk4socket_app_kwnl[] = {
+$!string-table macro=dkT
+#
+# 0 String table file name.
+#
+dk4sock.str
+#
+# 1 Separator for details line.
+#
+\n\t
+#
+# 2 Separator between function name and further text.
+#
+:
+#
+# 3 4 Function names
+#
+WSAStartup
+WSACleanup
+#
+# 5 6 7 Function names
+#
+socket
+close
+closesocket
+#
+# 8 Function name
+#
+bind
+#
+# 9 10 Function names
+#
+listen
+accept
+#
+# 11 Function name
+#
+connect
+#
+# 12 Function name
+#
+setsockopt
+#
+# 13 14 Function names
+#
+ioctlsocket
+fcntl
+#
+# 15 16 Function names
+#
+select
+getsockopt
+#
+# 17 18 Function names
+#
+getaddrinfo
+getnameinfo
+#
+# 19 20 Function names
+#
+gethostbyname
+getservbyname
+#
+# 21 Function name
+#
+GetAddrInfoW
+#
+# 22 Function name
+#
+inet_ntop
+#
+# 23
+#
+shutdown
+#
+# 24
+#
+send/sendto
+#
+# 25
+#
+recv/recvfrom
+#
+# 26
+#
+inet_pton
+$!end
+};
+
+
+
+/** Constant text keywords, replaced by localized version if found.
+*/
+static const dkChar * const dk4socket_app_kw_def[] = {
+$!string-table macro=dkT
+#
+# 0 Error: Failed to initialize Winsock subsystem!
+#
+Failed to initialize Winsock subsystem!
+#
+# 1 Error: Failed to shut down Winsock subsystem!
+#
+Failed to shut down Winsock subsystem!
+#
+# 2 Error: Failed to create socket!
+#
+Failed to create socket!
+#
+# 3 Error: Failed to close socket!
+#
+Failed to close socket!
+#
+# 4 Error: Failed to bind local address!
+#
+Failed to bind local address!
+#
+# 5 Error: Failed to listen for incoming connection requests!
+#
+Failed to listen for incoming connection requests!
+#
+# 6 Error: Failed to accept incoming connection request!
+#
+Failed to accept incoming connection request!
+#
+# 7 Error: Failed to connect to remote address!
+#
+Failed to connect to remote address!
+#
+# 8 Error: Failed to set reusable flag for socket!
+#
+Failed to modify ``reusable'' option for socket!
+#
+# 9 Error: Failed to modify ``non-blocking'' option for socket!
+#
+Failed to modify ``non-blocking'' option for socket!
+#
+# 10 Error: Failed to retrieve remote address(es)!
+#
+Failed to retrieve remote address(es)!
+#
+# 11 Error: Failed to retrieve local address(es)!
+#
+Failed to retrieve local address(es)!
+#
+# 12 Error: Failed to retrieve remote host address!
+#
+Failed to retrieve remote host address!
+#
+# 13 Error: Failed to retrieve port number for remote service!
+#
+Failed to retrieve port number for remote service!
+#
+# 14 Error: Failed to retrieve port number for local service!
+#
+Failed to retrieve port number for local service!
+#
+# 15 16 17 Error: Failed to convert text to ASCII!
+#
+Failed to convert text to ASCII!
+"
+"!
+#
+# 18 19 Error: Failed to obtain local addresses ...
+#
+Failed to obtain local address(es)!
+Port/service:
+#
+# 20 21 22 Error: Failed to obtain remote address(es)!
+#
+Failed to obtain remote address(es)!
+Host:
+Port/service:
+#
+# 23 24 Error: Service/port not found
+#
+Service/port not found: "
+"!
+#
+# 25 26 Error: Failed to convert service/port to ASCII
+#
+Failed to convert service/port to ASCII: "
+"!
+#
+# 27 Error: No matching pair of local/remote addresses found!
+#
+No matching pair of local/remote addresses found!
+#
+# 28 Error: Illegal local port number!
+#
+Illegal local port number!
+#
+# 29 Error: Illegal remote port number!
+#
+Illegal remote port number!
+#
+# 30 Debug: Connection established.
+#
+Connection established.
+#
+# 31 Error: Illegal address length in getservbyname() result!
+#
+Illegal address length in gethostbyname() result!
+#
+# 32 Error: Illegal address family in gethostbyname() result!
+#
+Illegal address family in gethostbyname() result!
+#
+# 33 34 Error: Remote host not found: "..."!
+#
+Remote host not found: "
+"!
+#
+# 35 36 Error: Failed to convert host name to ASCII: ...
+#
+Non-ASCII characters in host name: \n\t"
+"!
+#
+# 37 38 39 40 Texts to show error code
+#
+errno=
+ (0x
+)
+WSAGetLastError()=
+#
+# 41 42 43
+#
+Failed to create TCP connection!
+Local:
+Remote:
+#
+# 44
+#
+Timeout while attempting to connect.
+#
+# 45
+#
+Invalid arguments passed to function, probably a bug.
+#
+# 46
+#
+No matching local/remote address pair available!
+#
+# 47 WSASYSNOTREADY
+#
+Network subsystem not yet ready.
+#
+# 48 WSAVERNOTSUPPORTED
+#
+Winsock version not supported!
+#
+# 49 WSAEINPROGRESS
+#
+Blocking Winsock operation in progress!
+#
+# 50 WSAEPROCLIM
+#
+Process limit for Winsock reached!
+#
+# 51 WSAEFAULT WSAEINVAL / EFAULT
+#
+Invalid parameters passed to function!
+#
+# 52 WSANOTINITIALIZED
+#
+Winsock not initialized!
+#
+# 53 WSAENETDOWN
+#
+Network subsystem has failed!
+#
+# 54 WSAEAFNOSUPPORT / EAFNOSUPPORT
+#
+Address family not supported!
+#
+# 55 WSAEMFILE
+#
+No more socket/file descriptors available
+#
+# 56 WSAENOBUFS
+#
+No buffer space available!
+#
+# 57 WSAEPROTONOSUPPORT
+#
+Protocol not supported!
+#
+# 58 WSAEPROTOTYPE
+#
+Wrong protocol type for socket!
+#
+# 59 WSAEPROVIDERFAILEDINIT
+#
+Service provider failed to initialize!
+#
+# 60 WSAESOCKTNOSUPPORT
+#
+Socket type not supported by address family!
+#
+# 61 WSAINVALIDPROVIDER
+#
+Unusable service provider version!
+#
+# 62 WSAINVALIDPROCTABLE
+#
+Invalid/incomplete procedure table from service provider!
+#
+# 63 WSAEACCES / EACCES
+#
+Insufficient permissions!
+#
+# 64 WSAEADDRINUSE / EADDRINUSE
+#
+Address already in use!
+#
+# 65 WSAEADDRNOTAVAIL / EADDRNOTAVAIL
+#
+Address not available!
+#
+# 66 WSAENOTSOCK
+#
+File descriptor is not a socket!
+#
+# 67 EAI_ADDRFAMILY
+#
+Host has no addresses in specified address family!
+#
+# 68 EAI_AGAIN / TRY_AGAIN
+#
+Temporary problem on name server, try again later!
+#
+# 69 EAI_BADFLAGS
+#
+Illegal flag combination!
+#
+# 70 EAI_FAIL
+#
+Name server failure!
+#
+# 71 EAI_FAMILY
+#
+Address family not supported!
+#
+# 72 EAI_MEMORY
+#
+Out of memory!
+#
+# 73 EAI_NODATA / NO_DATA
+#
+No network address found for host!
+#
+# 74 EAI_NONAME
+#
+No such name or number!
+#
+# 75 EAI_SERVICE
+#
+Service not available through specified socket type!
+#
+# 76 EAI_SOCKTYPE
+#
+Unsupported socket type or inconsistent arguments!
+#
+# 77 EAI_SYSTEM
+#
+System error, check errno!
+#
+# 78 EAI_OVERFLOW
+#
+Argument buffer overflow!
+#
+# 79 EAGAIN
+#
+Resource temporarily locked, try again later!
+#
+# 80 EALREADY
+#
+Attempt already in progress!
+#
+# 81 EBADF
+#
+Not a file descriptor!
+#
+# 82 ECONNREFUSED
+#
+No-one listening on remote address!
+#
+# 83 ECONNRESET
+#
+Connection reset by peer!
+#
+# 84 EDEADLK
+#
+Operation would result in deadlock!
+#
+# 85 EDESTADDRREQ / EISDIR
+#
+Destination address required!
+#
+# 86 EDOM
+#
+Timeout values too large!
+#
+# 87 EINPROGRESS
+#
+Operation is in progress.
+#
+# 88 EINTR
+#
+Operation interrupted by signal!
+#
+# 89 EISCONN
+#
+Socket is already connected!
+#
+# 90 EIO
+#
+I/O error occured!
+#
+# 91 ELOOP
+#
+Symbolic link loop detected!
+#
+# 92 EMFILE
+#
+No more file descriptors available for process!
+#
+# 93 ENAMETOOLONG
+#
+Address or path name too long!
+#
+# 94 ENETUNREACH
+#
+Network unreachable!
+#
+# 95 ENFILE
+#
+No more file descriptors available on system!
+#
+# 96 ENOENT
+#
+File or path component does not exist or is empty!
+#
+# 97 ENOLCK
+#
+Failed to set a lock!
+#
+# 98 ENOPROTOOPT
+#
+Attempt to retrieve or modify unsupported option!
+#
+# 99 ENOTDIR
+#
+Path component is not a directory!
+#
+# 100 ENOSPC
+#
+Provided buffer size is too small!
+#
+# 101 EOPNOTSUPP
+#
+Operation not supported by socket type or protocol!
+#
+# 102 EROFS
+#
+File system is mounted read-only!
+#
+# 103 ETIMEDOUT
+#
+Timed out!
+#
+# 104 EOVERFLOW
+#
+Numeric overflow in file size/position calculation!
+#
+# 105 WSAECONNABORTED
+#
+Connection closed due to timeout or other failure!
+#
+# 106 WSAEHOSTUNREACH
+#
+Host unreachable!
+#
+# 107 WSAEINTR
+#
+Blocking Winsock operation interrupted by WSACancelBlockingCall()!
+#
+# 108 109 110 111 WSAEINVAL
+#
+Socket is in listening state!
+No local address bound yet!
+Socket is not in listening state!
+Invalid shutdown parameter
+#
+# 112 WSAEMSGSIZE
+#
+Message size too large!
+#
+# 113 WSAENETRESET
+#
+Connection closed, failures in keep-alive tests!
+#
+# 114 WSAENOTCONN
+#
+Not connected!
+#
+# 115 WSAEPROVIDERFAILEDINIT
+#
+Failed to initialize socket provider!
+#
+# 116 WSAESHUTDOWN
+#
+Socket already shut down!
+#
+# 117 WSAEWOULDBLOCK
+#
+Operation would block!
+#
+# 118 WSAHOST_NOT_FOUND
+#
+Host not found (authorative answer)!
+#
+# 119 WSAINVALIDPROCTABLE
+#
+Service provider returned invalid/incomplete procedure table!
+#
+# 120 WSAINVALIDPROVIDER
+#
+Invalid service provider version!
+#
+# 121 EPROTO
+#
+Protocol error!
+#
+# 122 ENOSR
+#
+Insufficient stream resources!
+#
+# 123 EPFNOSUPPORT
+#
+Protocol family not supported!
+#
+# 124 ENOLINK
+#
+Connection to remote machine no longer active!
+#
+# 125 ENXIO
+#
+Server exited before completing connection!
+#
+# 126 ENODEV
+#
+Protocol family and type not found in network configuration!
+#
+# 127 ESTALE
+#
+Stale NFS file handle!
+#
+# 128
+#
+Failed to shut down socket!
+#
+# 129 130
+#
+Failed to bind local address\n\t"
+"!
+#
+# 131 132
+#
+Failed to connect to remote address\n\t"
+"!
+#
+# 133 134 135
+#
+Send operation completed partially, only
+ of
+ bytes!
+#
+# 136
+#
+Send operation completed partially!
+#
+# 137
+#
+Send operation failed!
+#
+# 138
+#
+Failed to receive data!
+#
+# 139
+#
+Failed to create listener sockets!
+#
+# 140
+#
+Listening:
+#
+# 141 142
+#
+Failed to obtain allowed peer from string:\n\t"
+"!
+$!end
+};
+
+
+/** Number of elements in the dk4socket_app_kw_def array.
+*/
+static const size_t dk4socket_sz_kw_def =
+sizeof(dk4socket_app_kw_def)/sizeof(DK4_PCDKCHAR);
+
+
+
+size_t
+dk4socket_log_num_texts(void)
+{
+ return (dk4socket_sz_kw_def);
+}
+
+
+
+const dkChar * const *
+dk4socket_log_texts(dk4_app_t *app)
+{
+ const dkChar * const *back = dk4socket_app_kw_def;
+
+ if (NULL != app) {
+ back = dk4app_string_table(app,dk4socket_app_kwnl[0],dk4socket_app_kw_def);
+ }
+ return back;
+}
+
+
+
+void
+dk4socket_log_fctname_msg(
+ const dkChar **fctname,
+ const dkChar **msgtext,
+ dk4_app_t *app,
+ dk4_er_t *erp
+)
+{
+ const dkChar * const *msgtexts = dk4socket_app_kw_def;
+ const dkChar *mytext = NULL;
+ if ((NULL != app) && (NULL != erp)) {
+ msgtexts =
+ dk4app_string_table(app, dk4socket_app_kwnl[0], dk4socket_app_kw_def);
+ if (NULL != fctname) {
+ switch (erp->ec) {
+ case DK4_E_SOCKET_GETADDRINFO : {
+#if DK4_CHAR_SIZE > 1
+ *fctname = dk4socket_app_kwnl[21];
+#else
+ *fctname = dk4socket_app_kwnl[17];
+#endif
+ } break;
+ case DK4_E_SOCKET_GETADDRLOC : {
+#if DK4_CHAR_SIZE > 1
+ *fctname = dk4socket_app_kwnl[21];
+#else
+ *fctname = dk4socket_app_kwnl[17];
+#endif
+ } break;
+ case DK4_E_SOCKET_UP : {
+ *fctname = dk4socket_app_kwnl[3];
+ } break;
+ case DK4_E_SOCKET_DOWN : {
+ *fctname = dk4socket_app_kwnl[4];
+ } break;
+ case DK4_E_SOCKET_SOCKET : {
+ *fctname = dk4socket_app_kwnl[5];
+ } break;
+ case DK4_E_SOCKET_CLOSE : {
+#if DK4_ON_WINDOWS
+ *fctname = dk4socket_app_kwnl[7];
+#else
+ *fctname = dk4socket_app_kwnl[6];
+#endif
+ } break;
+ case DK4_E_SOCKET_BIND : {
+ *fctname = dk4socket_app_kwnl[8];
+ } break;
+ case DK4_E_SOCKET_CONNECT : {
+ *fctname = dk4socket_app_kwnl[11];
+ } break;
+ case DK4_E_SOCKET_LISTEN : {
+ *fctname = dk4socket_app_kwnl[9];
+ } break;
+ case DK4_E_SOCKET_ACCEPT : {
+ *fctname = dk4socket_app_kwnl[10];
+ } break;
+ case DK4_E_SOCKET_SHUTDOWN : {
+ *fctname = dk4socket_app_kwnl[23];
+ } break;
+ case DK4_E_SOCKET_SEND : {
+ *fctname = dk4socket_app_kwnl[24];
+ } break;
+ case DK4_E_SOCKET_RECV : {
+ *fctname = dk4socket_app_kwnl[25];
+ } break;
+ case DK4_E_SOCKET_SELECT : {
+ *fctname = dk4socket_app_kwnl[15];
+ } break;
+ case DK4_E_SOCKET_SETSOCKOPT : {
+ *fctname = dk4socket_app_kwnl[12];
+ } break;
+ case DK4_E_SOCKET_GETSOCKOPT : {
+ *fctname = dk4socket_app_kwnl[16];
+ } break;
+ case DK4_E_SOCKET_IOCTLSOCKET : {
+ *fctname = dk4socket_app_kwnl[13];
+ } break;
+ case DK4_E_SOCKET_FCNTL : {
+ *fctname = dk4socket_app_kwnl[14];
+ } break;
+ case DK4_E_SOCKET_GETSERVBYNAME : {
+ *fctname = dk4socket_app_kwnl[20];
+ } break;
+ case DK4_E_SOCKET_GETHOSTBYNAME : {
+ *fctname = dk4socket_app_kwnl[19];
+ } break;
+ case DK4_E_SOCKET_INET_NTOP : {
+ *fctname = dk4socket_app_kwnl[22];
+ } break;
+ case DK4_E_SOCKET_INET_PTON : {
+ *fctname = dk4socket_app_kwnl[26];
+ } break;
+ default : {
+ *fctname = NULL;
+ } break;
+ }
+ }
+ if (NULL != msgtext) {
+#if (DK4_CHAR_SIZE == 1) && (!DK4_ON_WINDOWS)
+ switch (erp->ec) {
+ case DK4_E_SOCKET_GETADDRINFO :
+ case DK4_E_SOCKET_GETADDRLOC :
+ {
+#if DK4_HAVE_GETADDRINFO
+ mytext = gai_strerror((erp->dt).iDetails1);
+#endif
+ } break;
+ case DK4_E_SOCKET_UP :
+ case DK4_E_SOCKET_DOWN :
+ case DK4_E_SOCKET_SOCKET :
+ case DK4_E_SOCKET_CLOSE :
+ case DK4_E_SOCKET_BIND :
+ case DK4_E_SOCKET_CONNECT :
+ case DK4_E_SOCKET_LISTEN :
+ case DK4_E_SOCKET_ACCEPT :
+ case DK4_E_SOCKET_SHUTDOWN :
+ case DK4_E_SOCKET_SEND :
+ case DK4_E_SOCKET_RECV :
+ case DK4_E_SOCKET_SELECT :
+ case DK4_E_SOCKET_SETSOCKOPT :
+ case DK4_E_SOCKET_GETSOCKOPT :
+ case DK4_E_SOCKET_IOCTLSOCKET :
+ case DK4_E_SOCKET_FCNTL :
+ case DK4_E_SOCKET_INET_NTOP :
+ case DK4_E_SOCKET_INET_PTON :
+ {
+ mytext = strerror((erp->dt).iDetails1);
+ } break;
+ }
+#endif
+ if (NULL == mytext) {
+ $? ". no mytext yet"
+ switch (erp->ec) {
+#if DK4_ON_WINDOWS
+ /* +++++ Windows +++++ */
+ case DK4_E_SOCKET_GETADDRINFO :
+ case DK4_E_SOCKET_GETADDRLOC :
+ {
+ switch (erp->dt.iDetails1) {
+ case EAI_AGAIN : {
+ /* Temporary problem in name resolution */
+ mytext = msgtexts[68];
+ } break;
+ case EAI_BADFLAGS : {
+ /* Incorrect flag combination */
+ mytext = msgtexts[69];
+ } break;
+ case EAI_FAIL : {
+ /* Nonrecoverable failure in name resolution */
+ mytext = msgtexts[70];
+ } break;
+ case EAI_FAMILY : {
+ /* Unsupported address family */
+ mytext = msgtexts[71];
+ } break;
+ case EAI_MEMORY: {
+ /* Not enough memory available */
+ mytext = msgtexts[72];
+ } break;
+ case EAI_NONAME : {
+ /* No address found for host */
+ mytext = msgtexts[74];
+ } break;
+ case EAI_SERVICE : {
+ /* Service type not supported for specified socket type */
+ mytext = msgtexts[75];
+ } break;
+ case EAI_SOCKTYPE : {
+ /* Socket type not supported */
+ mytext = msgtexts[76];
+ } break;
+ }
+ } break;
+ case DK4_E_SOCKET_UP :
+ case DK4_E_SOCKET_DOWN :
+ case DK4_E_SOCKET_SOCKET :
+ case DK4_E_SOCKET_CLOSE :
+ case DK4_E_SOCKET_BIND :
+ case DK4_E_SOCKET_CONNECT :
+ case DK4_E_SOCKET_LISTEN :
+ case DK4_E_SOCKET_ACCEPT :
+ case DK4_E_SOCKET_SHUTDOWN :
+ case DK4_E_SOCKET_SEND :
+ case DK4_E_SOCKET_RECV :
+ case DK4_E_SOCKET_SELECT :
+ case DK4_E_SOCKET_SETSOCKOPT :
+ case DK4_E_SOCKET_GETSOCKOPT :
+ case DK4_E_SOCKET_IOCTLSOCKET :
+ case DK4_E_SOCKET_FCNTL :
+ case DK4_E_SOCKET_GETSERVBYNAME :
+ case DK4_E_SOCKET_GETHOSTBYNAME :
+ case DK4_E_SOCKET_INET_NTOP :
+ case DK4_E_SOCKET_INET_PTON :
+ {
+ switch (erp->dt.iDetails1) {
+ case ERROR_INVALID_PARAMETER : {
+ /* inet_ntop: Buffer not present or too small */
+ mytext = msgtexts[100];
+ } break;
+ case WSAEACCES : {
+ /* bind: Insufficient permissions */
+ /* connect, send, sendto */
+ mytext = msgtexts[63];
+ } break;
+ case WSAEADDRINUSE : {
+ /* bind: Address is already in use */
+ /* connect, listen */
+ mytext = msgtexts[64];
+ } break;
+ case WSAEADDRNOTAVAIL : {
+ /* bind: Address is not valid in context, not a local address*/
+ /* connect: Invalid remote address */
+ /* sendto */
+ mytext = msgtexts[65];
+ } break;
+ case WSAEAFNOSUPPORT : {
+ /* socket: Addres family is not supported */
+ /* connect, sendto, inet_ntop, inet_pton */
+ mytext = msgtexts[54];
+ } break;
+ case WSAEALREADY : {
+ /* connect: Non-blocking connect already running for socket */
+ mytext = msgtexts[80];
+ } break;
+ case WSAECONNABORTED : {
+ /* send: Timeout or other failure, close the socket */
+ /* sendto, recv, shutdown */
+ mytext = msgtexts[105];
+ } break;
+ case WSAECONNREFUSED : {
+ /* connect: Connect attempt forcefully rejected */
+ mytext = msgtexts[82];
+ } break;
+ case WSAECONNRESET : {
+ /* accept: Connection request followed by termination request */
+ /* send, sendto, recv, recvfrom, shutdown */
+ mytext = msgtexts[83];
+ } break;
+ case WSAEDESTADDRREQ : {
+ /* sendto: Destination address required */
+ mytext = msgtexts[85];
+ } break;
+ case WSAEFAULT : {
+ /* WSAStartup: Invalid data pointer */
+ /* bind, connect, accept, select, ioctlsocket, gethostbyname */
+ /* send, sendto, recv, recvfrom, inet_pton */
+ mytext = msgtexts[51];
+ } break;
+ case WSAEHOSTUNREACH : {
+ /* connect: Host unreachable */
+ /* send, sendto */
+ mytext = msgtexts[106];
+ } break;
+ case WSAEINPROGRESS : {
+ /* WSAStartup: Blocking Winsock 1.1 operation in progress */
+ /* WSACleanup, socket, bind, connect, listen, select */
+ /* ioctlsocket, closesocket, gethostbyname, getservbyname */
+ /* send, sendto, recv, recvfrom, shutdown */
+ mytext = msgtexts[49];
+ } break;
+ case WSAEINTR : {
+ /* connect: Blocking call cancelled by WSACancelBlockingCall */
+ /* accept, select, closesocket, gethostbyname, getservbyname */
+ /* send, sendto, recv, recvfrom */
+ mytext = msgtexts[107];
+ } break;
+ case WSAEINVAL : {
+ /* socket: Invalid argument supplied */
+ /* bind, select, send, sendto, recv, recvfrom */
+ /* connect: The socket is in listening state */
+ /* listen: Socket not yet bound */
+ /* accept: Not listening */
+ /* shutdown: Invalid shutdown parameter */
+ switch (erp->ec) {
+ case DK4_E_SOCKET_CONNECT : {
+ mytext = msgtexts[108];
+ } break;
+ case DK4_E_SOCKET_LISTEN : {
+ mytext = msgtexts[109];
+ } break;
+ case DK4_E_SOCKET_ACCEPT : {
+ mytext = msgtexts[110];
+ } break;
+ case DK4_E_SOCKET_SHUTDOWN : {
+ mytext = msgtexts[111];
+ } break;
+ default : {
+ mytext = msgtexts[51];
+ } break;
+ }
+ } break;
+ case WSAEINVALIDPROCTABLE : {
+ /* socket: Service provider returned invalid procedure table */
+ mytext = msgtexts[119];
+ } break;
+ case WSAEINVALIDPROVIDER : {
+ /* socket: Invalid provider version */
+ mytext = msgtexts[120];
+ } break;
+ case WSAEISCONN : {
+ /* connect: Socket already connected */
+ /* listen */
+ /* recvfrom */
+ mytext = msgtexts[89];
+ } break;
+ case WSAEMFILE : {
+ /* socket: No more file descriptors available */
+ /* listen, accept */
+ mytext = msgtexts[92];
+ } break;
+ case WSAEMSGSIZE : {
+ /* send: Message size too large */
+ /* sendto, recv, recvfrom */
+ mytext = msgtexts[112];
+ } break;
+ case WSAENETDOWN : {
+ /* WSACleanup: Network subsystem has failed */
+ /* socket, bind, connect, listen, accept, select, ioctlsocket */
+ /* closesocket, gethostbyname, getservbyname, send, sendto */
+ /* recv, recvfrom, shutdown */
+ mytext = msgtexts[53];
+ } break;
+ case WSAENETRESET : {
+ /* send: Connection closed while keep-alive tests */
+ /* sendto, recv, recvfrom */
+ mytext = msgtexts[113];
+ } break;
+ case WSAENETUNREACH : {
+ /* connect: Network unreachable */
+ /* sendto */
+ mytext = msgtexts[94];
+ } break;
+ case WSAENOBUFS : {
+ /* socket: No buffer space available */
+ /* bind, connect, listen, accept, send, sendto */
+ mytext = msgtexts[56];
+ } break;
+ case WSAENOTCONN : {
+ /* send: Not connected */
+ /* recv, shutdown */
+ mytext = msgtexts[114];
+ } break;
+ case WSAENOTSOCK : {
+ /* bind: file descriptor is not a socket */
+ /* connect, listen, connect, select, ioctlsocket */
+ /* closesocket, send, sendto, recv, recvfrom, shutdown */
+ mytext = msgtexts[66];
+ } break;
+ case WSAEOPNOTSUPP : {
+ /* listen: Not supported by socket type */
+ /* accept, send, sendto, recv, recvfrom */
+ mytext = msgtexts[101];
+ } break;
+ case WSAEPROCLIM : {
+ /* WSAStartup: Limit of processes using Winsock is reached */
+ mytext = msgtexts[50];
+ } break;
+ case WSAEPROTONOSUPPORT : {
+ /* socket: Unsupported protocol */
+ mytext = msgtexts[57];
+ } break;
+ case WSAEPROTOTYPE : {
+ /* socket: Specified protocol invalid for socket */
+ mytext = msgtexts[58];
+ } break;
+ case WSAEPROVIDERFAILEDINIT : {
+ /* socket: Failed to initialize socket provider */
+ mytext = msgtexts[115];
+ } break;
+ case WSAESHUTDOWN : {
+ /* send: Socket was shut down */
+ /* sendto, recv, recvfrom */
+ mytext = msgtexts[116];
+ } break;
+ case WSAESOCKTNOSUPPORT : {
+ /* socket: Socket type not supported by address family */
+ mytext = msgtexts[60];
+ } break;
+ case WSAETIMEDOUT : {
+ /* connect: Timeout */
+ /* send, sendto, recv, recvfrom */
+ mytext = msgtexts[103];
+ } break;
+ case WSAEWOULDBLOCK : {
+ /* connect: Connection not finished on non-blocking socket */
+ /* accept: Non-blocking, not connection attempts are present */
+ /* closesocket, send, sendto, recv, recvfrom */
+ mytext = msgtexts[117];
+ } break;
+ case WSAHOST_NOT_FOUND : {
+ /* gethostbyname: Host not found (authorative answer) */
+ /* getservbyname */
+ mytext = msgtexts[118];
+ } break;
+ case WSANO_DATA : {
+ /* gethostbyname: Host name is valid, but no data found */
+ /* getservbyname */
+ mytext = msgtexts[73];
+ } break;
+ case WSANO_RECOVERY : {
+ /* gethostbyname: Unrecoverable error */
+ /* getservbyname */
+ mytext = msgtexts[70];
+ } break;
+ case WSANOTINITIALISED : {
+ /* WSACleanup: Winsock not initialized */
+ /* socket, bind, connect, listen, accept, select, ioctlsocket */
+ /* closesocket, gethostbyname, getservbyname, send, sendto */
+ /* recv, recvfrom, shutdown */
+ mytext = msgtexts[52];
+ } break;
+ case WSASYSNOTREADY : {
+ /* WSAStartup: Underlying subsystem not yet read */
+ mytext = msgtexts[47];
+ } break;
+ case WSATRY_AGAIN : {
+ /* gethostbyname: Host not found (non-authorative, or server
+ failure */
+ /* getservbyname */
+ mytext = msgtexts[68];
+ } break;
+ case WSAVERNOTSUPPORTED : {
+ /* WSAStartup: The requested version is not supported */
+ mytext = msgtexts[48];
+ } break;
+ }
+ } break;
+ /* ----- Windows ----- */
+#else
+ /* +++++ non-Windows +++++ */
+
+ case DK4_E_SOCKET_GETADDRINFO :
+ case DK4_E_SOCKET_GETADDRLOC :
+ {
+ switch (erp->dt.iDetails1) {
+#ifdef EAI_ADDRFAMILY
+ case EAI_ADDRFAMILY : {
+ mytext = msgtexts[67];
+ } break;
+#endif
+#ifdef EAI_AGAIN
+ case EAI_AGAIN : {
+ mytext = msgtexts[68];
+ } break;
+#endif
+#ifdef EAI_BADFLAGS
+ case EAI_BADFLAGS : {
+ mytext = msgtexts[69];
+ } break;
+#endif
+#ifdef EAI_FAIL
+ case EAI_FAIL : {
+ mytext = msgtexts[70];
+ } break;
+#endif
+#ifdef EAI_FAMILY
+ case EAI_FAMILY : {
+ mytext = msgtexts[71];
+ } break;
+#endif
+#ifdef EAI_MEMORY
+ case EAI_MEMORY : {
+ mytext = msgtexts[72];
+ } break;
+#endif
+#ifdef EAI_NODATA
+ case EAI_NODATA : {
+ mytext = msgtexts[73];
+ } break;
+#endif
+#ifdef EAI_NONAME
+ case EAI_NONAME : {
+ mytext = msgtexts[74];
+ } break;
+#endif
+#ifdef EAI_OVERFLOW
+ case EAI_OVERFLOW : {
+ mytext = msgtexts[78];
+ } break;
+#endif
+#ifdef EAI_SERVICE
+ case EAI_SERVICE : {
+ mytext = msgtexts[75];
+ } break;
+#endif
+#ifdef EAI_SOCKTYPE
+ case EAI_SOCKTYPE : {
+ mytext = msgtexts[76];
+ } break;
+#endif
+#ifdef EAI_SYSTEM
+ case EAI_SYSTEM : {
+ mytext = msgtexts[77];
+ } break;
+#endif
+ }
+ } break;
+ case DK4_E_SOCKET_GETHOSTBYNAME : {
+ switch (erp->dt.iDetails1) {
+#ifdef HOST_NOT_FOUND
+ case HOST_NOT_FOUND : {
+ mytext = msgtexts[73];
+ } break;
+#endif
+#ifdef NO_ADDRESS
+ case NO_ADDRESS : {
+ mytext = msgtexts[73];
+ } break;
+#endif
+#if defined(NO_DATA) && ((!defined(NO_ADDRESS)) || (NO_DATA != NO_ADDRESS))
+ case NO_DATA : {
+ mytext = msgtexts[73];
+ } break;
+#endif
+#ifdef NO_RECOVERY
+ case NO_RECOVERY : {
+ mytext = msgtexts[70];
+ } break;
+#endif
+#ifdef TRY_AGAIN
+ case TRY_AGAIN : {
+ mytext = msgtexts[68];
+ } break;
+#endif
+ }
+ } break;
+ case DK4_E_SOCKET_UP :
+ case DK4_E_SOCKET_DOWN :
+ case DK4_E_SOCKET_SOCKET :
+ case DK4_E_SOCKET_CLOSE :
+ case DK4_E_SOCKET_BIND :
+ case DK4_E_SOCKET_CONNECT :
+ case DK4_E_SOCKET_LISTEN :
+ case DK4_E_SOCKET_ACCEPT :
+ case DK4_E_SOCKET_SELECT :
+ case DK4_E_SOCKET_SETSOCKOPT :
+ case DK4_E_SOCKET_GETSOCKOPT :
+ case DK4_E_SOCKET_IOCTLSOCKET :
+ case DK4_E_SOCKET_FCNTL :
+ case DK4_E_SOCKET_INET_NTOP :
+ case DK4_E_SOCKET_INET_PTON :
+ {
+ switch (erp->dt.iDetails1) {
+#ifdef EACCES
+ case EACCES : {
+ /* socket: Insufficient permissions */
+ /* bind, connect, listen, send */
+ mytext = msgtexts[63];
+ } break;
+#endif
+#ifdef EADDRINUSE
+ case EADDRINUSE : {
+ /* bind: Address already in used */
+ /* connect */
+ /* listen */
+ mytext = msgtexts[64];
+ } break;
+#endif
+#ifdef EADDRNOTAVAIL
+ case EADDRNOTAVAIL : {
+ /* bind: nonexistent interface or address is not local */
+ /* connect */
+ mytext = msgtexts[65];
+ } break;
+#endif
+#ifdef EAFNOSUPPORT
+ case EAFNOSUPPORT : {
+ /* socket: Address family not supported */
+ /* bind: Mismatch address and address family */
+ /* connect, sendto, inet_pton */
+ mytext = msgtexts[54];
+ } break;
+#endif
+#ifdef EAGAIN
+ case EAGAIN : {
+ /* accept: Socket non-blocking, no incoming requests */
+ /* send, recv */
+ mytext = msgtexts[79];
+ } break;
+#endif
+#ifdef EALREADY
+ case EALREADY : {
+ /* connect: Already connected */
+ mytext = msgtexts[80];
+ } break;
+#endif
+#ifdef EBADF
+ case EBADF : {
+ /* close: Not a file descriptr */
+ /* shutdown, bind, connect */
+ /* listen, accept, send, recv */
+ mytext = msgtexts[81];
+ } break;
+#endif
+#ifdef ECONNABORTED
+ case ECONNABORTED : {
+ /* accept: Connection attempt aborted */
+ mytext = msgtexts[105];
+ } break;
+#endif
+#ifdef ECONNREFUSED
+ case ECONNREFUSED : {
+ /* connect: No-one listening on remote address */
+ /* recv */
+ mytext = msgtexts[82];
+ } break;
+#endif
+#ifdef ECONNRESET
+ case ECONNRESET : {
+ /* connect: Remote host denied connection */
+ /* send, recv */
+ mytext = msgtexts[83];
+ } break;
+#endif
+#ifdef EDEADLK
+ case EDEADLK : {
+ mytext = msgtexts[84];
+ } break;
+#endif
+#ifdef EDESTADDRREQ
+ case EDESTADDRREQ : {
+ /* bind: Address is a NULL pointer */
+ /* listen: Socket not yet bound */
+ /* send */
+ mytext = msgtexts[85];
+ } break;
+#endif
+#ifdef EDOM
+ case EDOM : {
+ mytext = msgtexts[86];
+ } break;
+#endif
+#ifdef EFAULT
+ case EFAULT : {
+ /* bind: Pointer to outside usable address space */
+ /* connect, accept, send, recv */
+ mytext = msgtexts[51];
+ } break;
+#endif
+#ifdef EHOSTUNREACH
+ case EHOSTUNREACH : {
+ /* connect: Remote host unreachable */
+ /* send */
+ mytext = msgtexts[106];
+ } break;
+#endif
+#ifdef EINPROGRESS
+ case EINPROGRESS : {
+ /* connect: Socket is non-blocking, operation would block */
+ mytext = msgtexts[87];
+ } break;
+#endif
+#ifdef EINTR
+ case EINTR : {
+ /* close: Interrupted by signal */
+ /* connect, accept, send, recv */
+ mytext = msgtexts[88];
+ } break;
+#endif
+#ifdef EINVAL
+ case EINVAL : {
+ /* socket: unknown protocol, illegal protocol family or flags */
+ /* shutdown: Invalid argument */
+ /* bind: Socket already bound */
+ /* bind: wrong address length */
+ /* bind: Socket already shut down */
+ /* connect: Wrong address length or address family */
+ /* listen: Socket already connected */
+ /* listen: Socket already shut down */
+ /* accept: Socket not listening, or illegal socket value */
+ /* accept: Invalid flags */
+ /* send: Invalid arguments , recv */
+ mytext = msgtexts[51];
+ } break;
+#endif
+#ifdef EISCONN
+ case EISCONN : {
+ /* bind: Socket already connected */
+ /* connect, send */
+ mytext = msgtexts[89];
+ } break;
+#endif
+#ifdef EISDIR
+ case EISDIR : {
+ /* bind: Address is a NULL pointer */
+ mytext = msgtexts[85];
+ } break;
+#endif
+#ifdef EIO
+ case EIO : {
+ /* close: I/O error */
+ /* connect, send */
+ mytext = msgtexts[90];
+ } break;
+#endif
+#ifdef ELOOP
+ case ELOOP : {
+ /* bind: Too many symbolic links or symlink loop */
+ /* connect, send */
+ mytext = msgtexts[91];
+ } break;
+#endif
+#ifdef EMFILE
+ case EMFILE : {
+ /* socket: Process file table overflow */
+ /* accept */
+ mytext = msgtexts[92];
+ } break;
+#endif
+#ifdef EMSGSIZE
+ case EMSGSIZE : {
+ /* send: Message size too large */
+ mytext = msgtexts[112];
+ } break;
+#endif
+#ifdef ENAMETOOLONG
+ case ENAMETOOLONG : {
+ /* bind: Address is too long */
+ /* connect, send */
+ mytext = msgtexts[93];
+ } break;
+#endif
+#ifdef ENETDOWN
+ case ENETDOWN : {
+ /* connect: Local network interface is down */
+ /* send */
+ mytext = msgtexts[53];
+ } break;
+#endif
+#ifdef ENETUNREACH
+ case ENETUNREACH : {
+ /* connect: Network is unreachable */
+ /* send */
+ mytext = msgtexts[94];
+ } break;
+#endif
+#ifdef ENFILE
+ case ENFILE : {
+ /* socket: System file table overflow */
+ /* accept */
+ mytext = msgtexts[95];
+ } break;
+#endif
+#ifdef ENOBUFS
+ case ENOBUFS : {
+ /* socket: No memory for buffers */
+ /* shutdown: Insufficient resources */
+ /* connect, listen, accept, send */
+ mytext = msgtexts[56];
+ } break;
+#endif
+#ifdef ENODEV
+ case ENODEV : {
+ /* accept: Protocol family and type not in network config */
+ mytext = msgtexts[126];
+ } break;
+#endif
+#ifdef ENOENT
+ case ENOENT : {
+ /* bind: File does not exist */
+ /* connect, send */
+ mytext = msgtexts[96];
+ } break;
+#endif
+#ifdef ENOLCK
+ case ENOLCK : {
+ mytext = msgtexts[97];
+ } break;
+#endif
+#ifdef ENOLINK
+ case ENOLINK : {
+ /* close: Connection to remote machine no longer active */
+ mytext = msgtexts[124];
+ } break;
+#endif
+#ifdef ENOMEM
+ case ENOMEM : {
+ /* socket: Not enough memory available */
+ /* bind, accept, send, recv */
+ mytext = msgtexts[72];
+ } break;
+#endif
+#ifdef ENOPROTOOPT
+ case ENOPROTOOPT : {
+ mytext = msgtexts[98];
+ } break;
+#endif
+#ifdef ENOSR
+ case ENOSR : {
+ /* socket: Insufficient stream resources */
+ /* bind, connect, accept, send, recv, shutdown */
+ mytext = msgtexts[122];
+ } break;
+#endif
+#ifdef ENOTCONN
+ case ENOTCONN : {
+ /* shutdown: Not connected */
+ /* send, recv */
+ mytext = msgtexts[114];
+ } break;
+#endif
+#ifdef ENOTDIR
+ case ENOTDIR : {
+ /* bind: Component or path prefix is not a directory */
+ /* connect, send */
+ mytext = msgtexts[99];
+ } break;
+#endif
+#ifdef ENOTSOCK
+ case ENOTSOCK : {
+ /* shutdown: Not a socket */
+ /* bind, connect, listen, accept, send, recv */
+ mytext = msgtexts[66];
+ } break;
+#endif
+#ifdef ENOSPC
+ case ENOSPC : {
+ /* inet_pton: Insufficient buffer size */
+ /* close: Not enough space on device */
+ mytext = msgtexts[100];
+ } break;
+#endif
+#ifdef ENXIO
+ case ENXIO : {
+ /* connect: Server exited before completing connection */
+ mytext = msgtexts[125];
+ } break;
+#endif
+#ifdef EOPNOTSUPP
+ case EOPNOTSUPP : {
+ /* bind: Operation not supported by socket type */
+ /* connect: Socket is listening */
+ /* listen: Socket can not listen */
+ /* accept: Not a stream socket */
+ /* send: Illegal flags, recv */
+ mytext = msgtexts[101];
+ } break;
+#endif
+#ifdef EPERM
+ case EPERM : {
+ /* connect: Insufficient permissions */
+ /* accept: Firewall rules forbid connection */
+ mytext = msgtexts[63];
+ } break;
+#endif
+#ifdef EPFNOSUPPORT
+ case EPFNOSUPPORT : {
+ /* socket: Protocol family not supported */
+ mytext = msgtexts[123];
+ } break;
+#endif
+#ifdef EPIPE
+ case EPIPE : {
+ mytext = msgtexts[116];
+ } break;
+#endif
+#ifdef EPROTONOSUPPORT
+ case EPROTONOSUPPORT : {
+ /* socket: Protocol type not supported in this domain */
+ mytext = msgtexts[57];
+ } break;
+#endif
+#ifdef EPROTO
+ case EPROTO : {
+ /* accept: Protocol error */
+ mytext = msgtexts[121];
+ } break;
+#endif
+#ifdef EPROTOTYPE
+ case EPROTOTYPE : {
+ /* socket: Socket type not supported by protocol */
+ /* connect: Remote type is different address family as local */
+ mytext = msgtexts[58];
+ } break;
+#endif
+#ifdef EROFS
+ case EROFS : {
+ /* bind: File system is mounted read-only */
+ mytext = msgtexts[102];
+ } break;
+#endif
+#ifdef ESTALE
+ case ESTALE : {
+ /* recv: Stale NFS file handle */
+ mytext = msgtexts[127];
+ } break;
+#endif
+#ifdef ETIMEDOUT
+ case ETIMEDOUT : {
+ /* connect: Timed out */
+ /* recv */
+ mytext = msgtexts[103];
+ } break;
+#endif
+#ifdef EOVERFLOW
+ case EOVERFLOW : {
+ mytext = msgtexts[104];
+ } break;
+#endif
+#if defined(EWOULDBLOCK) && ((!defined(EAGAIN)) || (EWOULDBLOCK != EAGAIN))
+ case EWOULDBLOCK : {
+ /* accept: Socket non-blocking, no incoming requests */
+ /* send, recv */
+ mytext = msgtexts[79];
+ } break;
+#endif
+ }
+ } break;
+ /* ----- non-Windows ----- */
+#endif
+ }
+ }
+ *msgtext = mytext;
+ }
+ }
+}
+
+
+
+void
+dk4socket_log_simple_1(
+ dk4_app_t *app,
+ int ll,
+ size_t imain,
+ dk4_er_t *erp
+)
+{
+ dkChar b1[16*sizeof(dk4_um_t)]; /* decimal */
+ dkChar b2[16*sizeof(dk4_um_t)]; /* hexadecimal */
+ const dkChar *fctn = NULL; /* Function name */
+ const dkChar *errt = NULL; /* Error text */
+ const dkChar *msgt[16]; /* Message components */
+ const dkChar * const *msga; /* Localized texts array */
+ size_t used = 0; /* Number of used components */
+ int res = 0; /* Conversion result */
+
+ if (0 != dk4app_log_do(app, ll)) {
+ msga = dk4app_string_table(app,dk4socket_app_kwnl[0],dk4socket_app_kw_def);
+ if (dk4socket_sz_kw_def > imain) {
+ msgt[used++] = msga[imain];
+ dk4socket_log_fctname_msg(&fctn, &errt, app, erp);
+ if (NULL != fctn) {
+ if (NULL != errt) {
+ msgt[used++] = dk4socket_app_kwnl[1];
+ msgt[used++] = fctn;
+ msgt[used++] = dk4socket_app_kwnl[2];
+ msgt[used++] = errt;
+ } else {
+ res = dk4ma_write_decimal_signed(
+ b1, DK4_SIZEOF(b1,dkChar), (dk4_um_t)(erp->dt.iDetails1), 0, NULL
+ );
+ if (0 != res) {
+ res = dk4ma_write_hex_signed(
+ b2, DK4_SIZEOF(b2,dkChar), (dk4_im_t)(erp->dt.iDetails1), 8, NULL
+ );
+ if (0 != res) {
+ msgt[used++] = dk4socket_app_kwnl[1];
+ msgt[used++] = fctn;
+ msgt[used++] = dk4socket_app_kwnl[2];
+#if DK4_ON_WINDOWS
+ msgt[used++] = msga[40];
+#else
+ msgt[used++] = msga[37];
+#endif
+ msgt[used++] = b1;
+ msgt[used++] = msga[38];
+ msgt[used++] = b2;
+ msgt[used++] = msga[39];
+ }
+ }
+ }
+ } else {
+ if (NULL != errt) {
+ msgt[used++] = dk4socket_app_kwnl[1];
+ msgt[used++] = errt;
+ } else {
+ }
+ }
+ dk4app_log_msg(app, ll, msgt, used);
+ }
+ }
+}
+
+
+
+void
+dk4socket_log_simple_3(
+ dk4_app_t *app,
+ int ll,
+ size_t i1,
+ size_t i2,
+ const dkChar *ctext,
+ dk4_er_t *erp
+)
+{
+ dkChar b1[16*sizeof(dk4_um_t)]; /* decimal */
+ dkChar b2[16*sizeof(dk4_um_t)]; /* hexadecimal */
+ const dkChar *fctn = NULL; /* Function name */
+ const dkChar *errt = NULL; /* Error text */
+ const dkChar *msgt[16]; /* Message components */
+ const dkChar * const *msga; /* Localized texts array */
+ size_t used = 0; /* Number of used components */
+ int res = 0; /* Conversion result */
+
+ if (0 != dk4app_log_do(app, ll)) {
+ msga = dk4app_string_table(app,dk4socket_app_kwnl[0],dk4socket_app_kw_def);
+ if ((dk4socket_sz_kw_def > i1) && (dk4socket_sz_kw_def > i2)) {
+ msgt[used++] = msga[i1];
+ if (NULL != ctext) { msgt[used++] = ctext; }
+ msgt[used++] = msga[i2];
+ dk4socket_log_fctname_msg(&fctn, &errt, app, erp);
+ if (NULL != fctn) {
+ if (NULL != errt) {
+ msgt[used++] = dk4socket_app_kwnl[1];
+ msgt[used++] = fctn;
+ msgt[used++] = dk4socket_app_kwnl[2];
+ msgt[used++] = errt;
+ } else {
+ res = dk4ma_write_decimal_signed(
+ b1, DK4_SIZEOF(b1,dkChar), (dk4_um_t)(erp->dt.iDetails1), 0, NULL
+ );
+ if (0 != res) {
+ res = dk4ma_write_hex_signed(
+ b2, DK4_SIZEOF(b2,dkChar), (dk4_im_t)(erp->dt.iDetails1), 8, NULL
+ );
+ if (0 != res) {
+ msgt[used++] = dk4socket_app_kwnl[1];
+ msgt[used++] = fctn;
+ msgt[used++] = dk4socket_app_kwnl[2];
+#if DK4_ON_WINDOWS
+ msgt[used++] = msga[40];
+#else
+ msgt[used++] = msga[37];
+#endif
+ msgt[used++] = b1;
+ msgt[used++] = msga[38];
+ msgt[used++] = b2;
+ msgt[used++] = msga[39];
+ }
+ }
+ }
+ } else {
+ if (NULL != errt) {
+ msgt[used++] = dk4socket_app_kwnl[1];
+ msgt[used++] = errt;
+ } else {
+ }
+ }
+ dk4app_log_msg(app, ll, msgt, used);
+ }
+ }
+}
+
+
+
+void
+dk4socket_log_simple_5(
+ dk4_app_t *app,
+ int ll,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ const dkChar *ct1,
+ const dkChar *ct2,
+ dk4_er_t *erp
+)
+{
+ dkChar b1[16*sizeof(dk4_um_t)]; /* decimal */
+ dkChar b2[16*sizeof(dk4_um_t)]; /* hexadecimal */
+ const dkChar *fctn = NULL; /* Function name */
+ const dkChar *errt = NULL; /* Error text */
+ const dkChar *msgt[16]; /* Message components */
+ const dkChar * const *msga; /* Localized texts array */
+ size_t used = 0; /* Number of used components */
+ int res = 0; /* Conversion result */
+
+ if (0 != dk4app_log_do(app, ll)) {
+ msga = dk4app_string_table(app,dk4socket_app_kwnl[0],dk4socket_app_kw_def);
+ if ((dk4socket_sz_kw_def > i1) && (dk4socket_sz_kw_def > i2)) {
+ msgt[used++] = msga[i1];
+ if (NULL != ct1) { msgt[used++] = ct1; }
+ msgt[used++] = msga[i2];
+ if (NULL != ct2) { msgt[used++] = ct2; }
+ msgt[used++] = msga[i3];
+ dk4socket_log_fctname_msg(&fctn, &errt, app, erp);
+ if (NULL != fctn) {
+ if (NULL != errt) {
+ msgt[used++] = dk4socket_app_kwnl[1];
+ msgt[used++] = fctn;
+ msgt[used++] = dk4socket_app_kwnl[2];
+ msgt[used++] = errt;
+ } else {
+ res = dk4ma_write_decimal_signed(
+ b1, DK4_SIZEOF(b1,dkChar), (dk4_um_t)(erp->dt.iDetails1), 0, NULL
+ );
+ if (0 != res) {
+ res = dk4ma_write_hex_signed(
+ b2, DK4_SIZEOF(b2,dkChar), (dk4_im_t)(erp->dt.iDetails1), 8, NULL
+ );
+ if (0 != res) {
+ msgt[used++] = dk4socket_app_kwnl[1];
+ msgt[used++] = fctn;
+ msgt[used++] = dk4socket_app_kwnl[2];
+#if DK4_ON_WINDOWS
+ msgt[used++] = msga[40];
+#else
+ msgt[used++] = msga[37];
+#endif
+ msgt[used++] = b1;
+ msgt[used++] = msga[38];
+ msgt[used++] = b2;
+ msgt[used++] = msga[39];
+ }
+ }
+ }
+ } else {
+ if (NULL != errt) {
+ msgt[used++] = dk4socket_app_kwnl[1];
+ msgt[used++] = errt;
+ } else {
+ }
+ }
+ dk4app_log_msg(app, ll, msgt, used);
+ }
+ }
+}
+
diff --git a/support/dktools/dk4socka02.c b/support/dktools/dk4socka02.c
new file mode 100644
index 0000000000..07cb8a97ff
--- /dev/null
+++ b/support/dktools/dk4socka02.c
@@ -0,0 +1,84 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4socka02.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4socka02.c The dk4socka02 module.
+*/
+
+
+#line 9 "dk4socka02.ctr"
+
+#include "dk4sock.h"
+#include "dk4socka.h"
+
+
+
+int
+dk4socket_up_app(dk4_app_t *app)
+{
+#if DK4_ON_WINDOWS
+ dk4_er_t er;
+ int back;
+
+ dk4error_init(&er);
+ back = dk4socket_up(&er);
+ if (DK4_SOCKET_RESULT_SUCCESS != back) {
+ dk4socket_log_simple_1(app, DK4_LL_ERROR, 0, &er);
+ }
+ return back;
+#else
+ return (DK4_SOCKET_RESULT_SUCCESS);
+#endif
+}
+
+
+
+int
+dk4socket_down_app(dk4_app_t *app)
+{
+#if DK4_ON_WINDOWS
+ dk4_er_t er;
+ int back;
+
+ dk4error_init(&er);
+ back = dk4socket_down(&er);
+ if (DK4_SOCKET_RESULT_SUCCESS != back) {
+ dk4socket_log_simple_1(app, DK4_LL_ERROR, 1, &er);
+ }
+ return back;
+#else
+ return (DK4_SOCKET_RESULT_SUCCESS);
+#endif
+}
+
diff --git a/support/dktools/dk4socka02.ctr b/support/dktools/dk4socka02.ctr
new file mode 100644
index 0000000000..45671ac1e1
--- /dev/null
+++ b/support/dktools/dk4socka02.ctr
@@ -0,0 +1,52 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% module
+
+#include "dk4sock.h"
+#include "dk4socka.h"
+
+
+
+int
+dk4socket_up_app(dk4_app_t *app)
+{
+#if DK4_ON_WINDOWS
+ dk4_er_t er;
+ int back;
+
+ dk4error_init(&er);
+ back = dk4socket_up(&er);
+ if (DK4_SOCKET_RESULT_SUCCESS != back) {
+ dk4socket_log_simple_1(app, DK4_LL_ERROR, 0, &er);
+ }
+ return back;
+#else
+ return (DK4_SOCKET_RESULT_SUCCESS);
+#endif
+}
+
+
+
+int
+dk4socket_down_app(dk4_app_t *app)
+{
+#if DK4_ON_WINDOWS
+ dk4_er_t er;
+ int back;
+
+ dk4error_init(&er);
+ back = dk4socket_down(&er);
+ if (DK4_SOCKET_RESULT_SUCCESS != back) {
+ dk4socket_log_simple_1(app, DK4_LL_ERROR, 1, &er);
+ }
+ return back;
+#else
+ return (DK4_SOCKET_RESULT_SUCCESS);
+#endif
+}
+
diff --git a/support/dktools/dk4socka03.c b/support/dktools/dk4socka03.c
new file mode 100644
index 0000000000..cf7ec3e035
--- /dev/null
+++ b/support/dktools/dk4socka03.c
@@ -0,0 +1,91 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4socka03.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4socka03.c The dk4socka03 module.
+*/
+
+
+#line 10 "dk4socka03.ctr"
+
+
+#include "dk4sock.h"
+#include "dk4socka.h"
+
+
+
+dk4_socket_t
+dk4socket_open_app(int af, int tp, int pr, dk4_app_t *app)
+{
+ dk4_er_t er;
+ dk4_socket_t back = INVALID_SOCKET;
+ dk4error_init(&er);
+ back = dk4socket_open(af, tp, pr, &er);
+ if (INVALID_SOCKET == back) {
+ dk4socket_log_simple_1(app, DK4_LL_ERROR, 2, &er);
+ }
+ return back;
+}
+
+
+
+int
+dk4socket_close_app(dk4_socket_t so, dk4_app_t *app)
+{
+ dk4_er_t er;
+ int back = DK4_SOCKET_RESULT_FAILED;
+ dk4error_init(&er);
+ back = dk4socket_close(so, &er);
+ if (DK4_SOCKET_RESULT_SUCCESS != back) {
+ dk4socket_log_simple_1(app, DK4_LL_ERROR, 3, &er);
+ }
+ return back;
+}
+
+
+
+int
+dk4socket_shutdown_app(dk4_socket_t so, int how, dk4_app_t *app)
+{
+ dk4_er_t er;
+ int back = DK4_SOCKET_RESULT_FAILED;
+ dk4error_init(&er);
+ back = dk4socket_shutdown(so, how, &er);
+ if (DK4_SOCKET_RESULT_SUCCESS != back) {
+ dk4socket_log_simple_1(app, DK4_LL_ERROR, 128, &er);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4socka03.ctr b/support/dktools/dk4socka03.ctr
new file mode 100644
index 0000000000..4232fb9e3a
--- /dev/null
+++ b/support/dktools/dk4socka03.ctr
@@ -0,0 +1,60 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+
+#include "dk4sock.h"
+#include "dk4socka.h"
+
+
+
+dk4_socket_t
+dk4socket_open_app(int af, int tp, int pr, dk4_app_t *app)
+{
+ dk4_er_t er;
+ dk4_socket_t back = INVALID_SOCKET;
+ dk4error_init(&er);
+ back = dk4socket_open(af, tp, pr, &er);
+ if (INVALID_SOCKET == back) {
+ dk4socket_log_simple_1(app, DK4_LL_ERROR, 2, &er);
+ }
+ return back;
+}
+
+
+
+int
+dk4socket_close_app(dk4_socket_t so, dk4_app_t *app)
+{
+ dk4_er_t er;
+ int back = DK4_SOCKET_RESULT_FAILED;
+ dk4error_init(&er);
+ back = dk4socket_close(so, &er);
+ if (DK4_SOCKET_RESULT_SUCCESS != back) {
+ dk4socket_log_simple_1(app, DK4_LL_ERROR, 3, &er);
+ }
+ return back;
+}
+
+
+
+int
+dk4socket_shutdown_app(dk4_socket_t so, int how, dk4_app_t *app)
+{
+ dk4_er_t er;
+ int back = DK4_SOCKET_RESULT_FAILED;
+ dk4error_init(&er);
+ back = dk4socket_shutdown(so, how, &er);
+ if (DK4_SOCKET_RESULT_SUCCESS != back) {
+ dk4socket_log_simple_1(app, DK4_LL_ERROR, 128, &er);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4socka04.c b/support/dktools/dk4socka04.c
new file mode 100644
index 0000000000..bfa45458e7
--- /dev/null
+++ b/support/dktools/dk4socka04.c
@@ -0,0 +1,83 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4socka04.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4socka04.c The dk4socka04 module.
+*/
+
+
+#line 10 "dk4socka04.ctr"
+
+#include "dk4sock.h"
+#include "dk4socka.h"
+#include "dk4mem.h"
+
+
+
+
+
+#line 18 "dk4socka04.ctr"
+
+
+int
+dk4socket_bind_app(
+ dk4_socket_t sock,
+ const struct sockaddr *pAddr,
+ size_t szAddr,
+ dk4_app_t *app
+)
+{
+ dkChar buf[128];
+ dk4_er_t er;
+ size_t szbuf = DK4_SIZEOF(buf,dkChar);
+ int back = DK4_SOCKET_RESULT_FAILED;
+ int res;
+ dk4error_init(&er);
+ back = dk4socket_bind(sock, pAddr, szAddr, &er);
+ if (DK4_SOCKET_RESULT_SUCCESS != back) {
+ if (0 != dk4app_log_do(app, DK4_LL_ERROR)) {
+ res = dk4socket_addr_port_to_text(
+ buf, szbuf, pAddr->sa_family, pAddr, szAddr, NULL
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ dk4socket_log_simple_3(app, DK4_LL_ERROR, 129, 130, buf, &er);
+ } else {
+ dk4socket_log_simple_1(app, DK4_LL_ERROR, 4, &er);
+ }
+ }
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4socka04.ctr b/support/dktools/dk4socka04.ctr
new file mode 100644
index 0000000000..3bf7a61d96
--- /dev/null
+++ b/support/dktools/dk4socka04.ctr
@@ -0,0 +1,50 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4sock.h"
+#include "dk4socka.h"
+#include "dk4mem.h"
+
+
+
+$!trace-include
+
+
+int
+dk4socket_bind_app(
+ dk4_socket_t sock,
+ const struct sockaddr *pAddr,
+ size_t szAddr,
+ dk4_app_t *app
+)
+{
+ dkChar buf[128];
+ dk4_er_t er;
+ size_t szbuf = DK4_SIZEOF(buf,dkChar);
+ int back = DK4_SOCKET_RESULT_FAILED;
+ int res;
+ dk4error_init(&er);
+ back = dk4socket_bind(sock, pAddr, szAddr, &er);
+ if (DK4_SOCKET_RESULT_SUCCESS != back) {
+ if (0 != dk4app_log_do(app, DK4_LL_ERROR)) {
+ res = dk4socket_addr_port_to_text(
+ buf, szbuf, pAddr->sa_family, pAddr, szAddr, NULL
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ dk4socket_log_simple_3(app, DK4_LL_ERROR, 129, 130, buf, &er);
+ } else {
+ dk4socket_log_simple_1(app, DK4_LL_ERROR, 4, &er);
+ }
+ }
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4socka05.c b/support/dktools/dk4socka05.c
new file mode 100644
index 0000000000..3871a089a1
--- /dev/null
+++ b/support/dktools/dk4socka05.c
@@ -0,0 +1,84 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4socka05.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4socka05.c The dk4socka05 module.
+*/
+
+
+#line 10 "dk4socka05.ctr"
+
+
+#include "dk4app.h"
+#include "dk4socka.h"
+
+
+
+int
+dk4socket_listen_app(
+ dk4_socket_t sock,
+ int bl,
+ dk4_app_t *app
+)
+{
+ dk4_er_t er;
+ int back = DK4_SOCKET_RESULT_FAILED;
+ dk4error_init(&er);
+ back = dk4socket_listen(sock, bl, &er);
+ if (DK4_SOCKET_RESULT_SUCCESS != back) {
+ dk4socket_log_simple_1(app, DK4_LL_ERROR, 5, &er);
+ }
+ return back;
+}
+
+
+
+dk4_socket_t
+dk4socket_accept_app(
+ dk4_socket_t sock,
+ struct sockaddr *pAddr,
+ size_t *pSzAddr,
+ dk4_app_t *app
+)
+{
+ dk4_er_t er;
+ dk4_socket_t back = INVALID_SOCKET;
+ dk4error_init(&er);
+ back = dk4socket_accept(sock, pAddr, pSzAddr, &er);
+ if (INVALID_SOCKET == back) {
+ dk4socket_log_simple_1(app, DK4_LL_ERROR, 6, &er);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4socka05.ctr b/support/dktools/dk4socka05.ctr
new file mode 100644
index 0000000000..5a15106e36
--- /dev/null
+++ b/support/dktools/dk4socka05.ctr
@@ -0,0 +1,53 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+
+#include "dk4app.h"
+#include "dk4socka.h"
+
+
+
+int
+dk4socket_listen_app(
+ dk4_socket_t sock,
+ int bl,
+ dk4_app_t *app
+)
+{
+ dk4_er_t er;
+ int back = DK4_SOCKET_RESULT_FAILED;
+ dk4error_init(&er);
+ back = dk4socket_listen(sock, bl, &er);
+ if (DK4_SOCKET_RESULT_SUCCESS != back) {
+ dk4socket_log_simple_1(app, DK4_LL_ERROR, 5, &er);
+ }
+ return back;
+}
+
+
+
+dk4_socket_t
+dk4socket_accept_app(
+ dk4_socket_t sock,
+ struct sockaddr *pAddr,
+ size_t *pSzAddr,
+ dk4_app_t *app
+)
+{
+ dk4_er_t er;
+ dk4_socket_t back = INVALID_SOCKET;
+ dk4error_init(&er);
+ back = dk4socket_accept(sock, pAddr, pSzAddr, &er);
+ if (INVALID_SOCKET == back) {
+ dk4socket_log_simple_1(app, DK4_LL_ERROR, 6, &er);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4socka06.c b/support/dktools/dk4socka06.c
new file mode 100644
index 0000000000..79830178ff
--- /dev/null
+++ b/support/dktools/dk4socka06.c
@@ -0,0 +1,83 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4socka06.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4socka06.c The dk4socka06 module.
+*/
+
+
+#line 10 "dk4socka06.ctr"
+
+
+#include "dk4socka.h"
+#include "dk4mem.h"
+
+
+
+
+
+#line 18 "dk4socka06.ctr"
+
+
+
+int
+dk4socket_connect_app(
+ dk4_socket_t sock,
+ const struct sockaddr *pAddr,
+ size_t szAddr,
+ dk4_app_t *app
+)
+{
+ dkChar buf[128];
+ dk4_er_t er;
+ const size_t szbuf = DK4_SIZEOF(buf,dkChar);
+ int back = DK4_SOCKET_RESULT_FAILED;
+ int res = 0;
+ dk4error_init(&er);
+ back = dk4socket_connect(sock, pAddr, szAddr, &er);
+ if (DK4_SOCKET_RESULT_SUCCESS != back) {
+ if (0 != dk4app_log_do(app, DK4_LL_ERROR)) {
+ res = dk4socket_addr_port_to_text(
+ buf, szbuf, pAddr->sa_family, pAddr, szAddr, NULL
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ dk4socket_log_simple_3(app, DK4_LL_ERROR, 131, 132, buf, &er);
+ } else {
+ dk4socket_log_simple_1(app, DK4_LL_ERROR, 7, &er);
+ }
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4socka06.ctr b/support/dktools/dk4socka06.ctr
new file mode 100644
index 0000000000..4b4015cb9e
--- /dev/null
+++ b/support/dktools/dk4socka06.ctr
@@ -0,0 +1,50 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+
+#include "dk4socka.h"
+#include "dk4mem.h"
+
+
+
+$!trace-include
+
+
+
+int
+dk4socket_connect_app(
+ dk4_socket_t sock,
+ const struct sockaddr *pAddr,
+ size_t szAddr,
+ dk4_app_t *app
+)
+{
+ dkChar buf[128];
+ dk4_er_t er;
+ const size_t szbuf = DK4_SIZEOF(buf,dkChar);
+ int back = DK4_SOCKET_RESULT_FAILED;
+ int res = 0;
+ dk4error_init(&er);
+ back = dk4socket_connect(sock, pAddr, szAddr, &er);
+ if (DK4_SOCKET_RESULT_SUCCESS != back) {
+ if (0 != dk4app_log_do(app, DK4_LL_ERROR)) {
+ res = dk4socket_addr_port_to_text(
+ buf, szbuf, pAddr->sa_family, pAddr, szAddr, NULL
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ dk4socket_log_simple_3(app, DK4_LL_ERROR, 131, 132, buf, &er);
+ } else {
+ dk4socket_log_simple_1(app, DK4_LL_ERROR, 7, &er);
+ }
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4socka07.c b/support/dktools/dk4socka07.c
new file mode 100644
index 0000000000..7b7cf9ba97
--- /dev/null
+++ b/support/dktools/dk4socka07.c
@@ -0,0 +1,1748 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4socka07.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4socka07.c The dk4socka07 module.
+*/
+
+
+#line 9 "dk4socka07.ctr"
+
+
+#include "dk4sock.h"
+#include "dk4socka.h"
+#include "dk4mem.h"
+
+#if DK4_HAVE_GETADDRINFO
+#include "dk4mao8d.h"
+#else
+#if DK4_CHAR_SIZE > 1
+#include "dk4maiwdus.h"
+#include "dk4rec24.h"
+#endif
+#include "dk4mai8dus.h"
+#endif
+
+#include "dk4maiddus.h"
+#include "dk4maodd.h"
+#include "dk4maodh.h"
+
+
+
+
+
+#line 32 "dk4socka07.ctr"
+
+
+
+/** Constant texts used by module, not localized.
+*/
+static const dkChar * const dk4socket_03_kwnl[] = {
+/* 0 */
+dkT("\n\t"),
+
+/* 1 */
+dkT(": "),
+
+/* 2 */
+dkT("@"),
+
+NULL
+
+
+#line 52 "dk4socka07.ctr"
+};
+
+
+
+/*
+ Internal tool functions
+ -----------------------
+*/
+
+/** Report error from dk4socket_tcp_client_for_addr().
+ @param app Application structure for logging.
+ @param hostname Host name to connect to.
+ @param afam Address family.
+ @param sremote Pointer to remote address buffer.
+ @param szremote Remote address size.
+ @param slocal Pointer to local address buffer.
+ @param szlocal Local address size.
+ @param erp Error report, required.
+*/
+static
+void
+dk4socket_report_connection_error(
+ dk4_app_t *app,
+ const dkChar *hostname,
+ int afam,
+ const struct sockaddr *sremote,
+ size_t szremote,
+ const struct sockaddr *slocal,
+ size_t szlocal,
+ dk4_er_t *erp
+)
+{
+ const dkChar * msgt[32]; /* Message components */
+ dkChar bdec[16*sizeof(dk4_um_t)]; /* Decimal */
+ dkChar bhex[16*sizeof(dk4_um_t)]; /* Hexadecimal */
+ dkChar bloc[128]; /* Local address */
+ dkChar brem[128]; /* Remote address */
+ const dkChar * const *msga = NULL; /* Localized texts */
+ const dkChar *fctname = NULL; /* Name of failed function */
+ const dkChar *msgtext = NULL; /* Text why fct failed */
+#if VERSION_BEFORE_20150821
+ size_t szmsga = 0; /* Number of elems in msga */
+#endif
+ size_t used = 0; /* No used elems in msgt */
+ int res = 0; /* Conversion result */
+ int bothbuf = 0; /* Flag: Have bdec and bhex */
+ int fctnmsg = 0; /* Flag: Use fct name */
+
+
+#line 100 "dk4socka07.ctr"
+ if (NULL != app) {
+ if (dk4app_log_do(app, DK4_LL_ERROR)) {
+#if VERSION_BEFORE_20150821
+ szmsga = dk4socket_log_num_texts();
+#endif
+ msga = dk4socket_log_texts(app);
+ dk4socket_log_fctname_msg(&fctname, &msgtext, app, erp);
+ if (NULL == msgtext) {
+ res = dk4ma_write_decimal_signed(
+ bdec, DK4_SIZEOF(bdec,dkChar), (dk4_im_t)(erp->dt.iDetails1), 0, NULL
+ );
+ if (0 != res) {
+ res = dk4ma_write_hex_signed(
+ bhex,DK4_SIZEOF(bhex,dkChar),(dk4_im_t)(erp->dt.iDetails1),0,NULL
+ );
+ if (0 != res) { bothbuf = 1; }
+ }
+ }
+ msgt[used++] = msga[41];
+ if ((NULL != slocal) && (0 < szlocal)) {
+ res = dk4socket_addr_port_to_text(
+ bloc, DK4_SIZEOF(bloc,dkChar), afam, slocal, szlocal, NULL
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[42];
+ msgt[used++] = bloc;
+ }
+ }
+ if ((NULL != sremote) && (0 < szremote)) {
+ res = dk4socket_addr_port_to_text(
+ brem, DK4_SIZEOF(brem,dkChar), afam, sremote, szremote, NULL
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[43];
+ msgt[used++] = brem;
+ }
+ }
+ switch (erp->ec) {
+ case DK4_E_INVALID_ARGUMENTS : {
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[45];
+ } break;
+ case DK4_E_SOCKET_SOCKET : {
+ fctnmsg = 1;
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[2];
+ } break;
+ case DK4_E_SOCKET_BIND : {
+ fctnmsg = 1;
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[4];
+ } break;
+ case DK4_E_SOCKET_FCNTL : {
+ fctnmsg = 1;
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[9];
+ } break;
+ case DK4_E_SOCKET_IOCTLSOCKET : {
+ fctnmsg = 1;
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[9];
+ } break;
+ case DK4_E_SOCKET_CONNECT : {
+ fctnmsg = 1;
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[7];
+ } break;
+ case DK4_E_SOCKET_TIMEOUT : {
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[44];
+ } break;
+ case DK4_E_SOCKET_SELECT : {
+ fctnmsg = 1;
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[44];
+ } break;
+ case DK4_E_SOCKET_GETSOCKOPT : {
+ fctnmsg = 1;
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[8];
+ } break;
+ case DK4_E_SOCKET_SETSOCKOPT : {
+ fctnmsg = 1;
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[8];
+ } break;
+ }
+ if (0 != fctnmsg) {
+ if ((NULL != fctname) && ((NULL != msgtext) || (0 != bothbuf))) {
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = fctname;
+ msgt[used++] = dk4socket_03_kwnl[1];
+ if (NULL != msgtext) {
+ msgt[used++] = msgtext;
+ } else {
+#if DK4_ON_WINDOWS
+ msgt[used++] = msga[40];
+#else
+ msgt[used++] = msga[37];
+#endif
+ msgt[used++] = bdec;
+ msgt[used++] = msga[38];
+ msgt[used++] = bhex;
+ msgt[used++] = msga[39];
+ }
+ }
+ }
+ dk4app_log_msg(app, DK4_LL_ERROR, msgt, used);
+ }
+ }
+
+
+#line 213 "dk4socka07.ctr"
+}
+
+
+
+/** Report error from dk4socket_tcp_client_for_addr().
+ @param app Application structure for logging.
+ @param hostname Host name to connect to.
+ @param afam Address family.
+ @param sremote Pointer to remote address buffer.
+ @param szremote Remote address size.
+ @param slocal Pointer to local address buffer.
+ @param szlocal Local address size.
+ @param erp Error report, required.
+*/
+static
+void
+dk4socket_report_connection_established(
+ dk4_app_t *app,
+ const dkChar *hostname,
+ int afam,
+ const struct sockaddr *sremote,
+ size_t szremote,
+ const struct sockaddr *slocal,
+ size_t szlocal
+)
+{
+ const dkChar * msgt[32]; /* Message components */
+ dkChar bloc[128]; /* Local address */
+ dkChar brem[128]; /* Remote address */
+ const dkChar * const *msga = NULL; /* Localized texts */
+#if VERSION_BEFORE_20150821
+ size_t szmsga = 0; /* Number of elems in msga */
+#endif
+ size_t used = 0; /* No used elems in msgt */
+ int res = 0; /* Conversion result */
+
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, DK4_LL_PROGRESS)) {
+#if VERSION_BEFORE_20150821
+ szmsga = dk4socket_log_num_texts();
+#endif
+ msga = dk4socket_log_texts(app);
+ msgt[used++] = msga[30];
+ if ((NULL != slocal) && (0 < szlocal)) {
+ res = dk4socket_addr_port_to_text(
+ bloc, DK4_SIZEOF(bloc,dkChar), afam, slocal, szlocal, NULL
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[42];
+ msgt[used++] = bloc;
+ }
+ }
+ if ((NULL != sremote) && (0 < szremote)) {
+ res = dk4socket_addr_port_to_text(
+ brem, DK4_SIZEOF(brem,dkChar), afam, sremote, szremote, NULL
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[43];
+ msgt[used++] = brem;
+ }
+ }
+ dk4app_log_msg(app, DK4_LL_PROGRESS, msgt, used);
+ }
+ }
+}
+
+
+
+static
+void
+dk4socket_report_invalid_arguments(
+ dk4_app_t *app
+)
+{
+ const dkChar * msgt[16];
+ const dkChar * const *msga;
+#if VERSION_BEFORE_20150821
+ size_t szmsga;
+#endif
+ size_t used = 0;
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, DK4_LL_ERROR)) {
+#if VERSION_BEFORE_20150821
+ szmsga = dk4socket_log_num_texts();
+#endif
+ msga = dk4socket_log_texts(app);
+ msgt[used++] = msga[41];
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[45];
+ dk4app_log_msg(app, DK4_LL_ERROR, msgt, used);
+ }
+ }
+}
+
+
+#if DK4_HAVE_GETADDRINFO
+/* +++++ +getaddrinfo +++++ */
+
+static
+void
+dk4socket_report_no_matching_addresses(
+ const dkChar *hostname,
+ dk4_app_t *app
+)
+{
+ const dkChar *msgt[16];
+ const dkChar * const *msga;
+#if VERSION_BEFORE_20150821
+ size_t szmsga;
+#endif
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, DK4_LL_ERROR)) {
+#if VERSION_BEFORE_20150821
+ szmsga = dk4socket_log_num_texts();
+#endif
+ msga = dk4socket_log_texts(app);
+ msgt[0] = msga[41];
+ msgt[1] = dk4socket_03_kwnl[0];
+ msgt[2] = msga[43];
+ msgt[4] = hostname;
+ msgt[5] = dk4socket_03_kwnl[0];
+ msgt[6] = msga[46];
+ dk4app_log_msg(app, DK4_LL_ERROR, msgt, 7);
+ }
+ }
+}
+
+
+
+static
+void
+dk4socket_report_gai(
+ const dkChar *hostname,
+ const dkChar *lsvcname,
+ int res,
+ int local,
+ dk4_app_t *app,
+ dk4_er_t *erp
+)
+{
+ dkChar bdec[16*sizeof(dk4_um_t)];
+ dkChar bhex[16*sizeof(dk4_um_t)];
+ const dkChar *msgt[16];
+ const dkChar * const *msga;
+ const dkChar *fctname = NULL;
+ const dkChar *msgtext = NULL;
+#if VERSION_BEFORE_20150821
+ size_t szmsga;
+#endif
+ size_t used = 0;
+
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, DK4_LL_ERROR)) {
+#if VERSION_BEFORE_20150821
+ szmsga = dk4socket_log_num_texts();
+#endif
+ msga = dk4socket_log_texts(app);
+ dk4socket_log_fctname_msg(&fctname, &msgtext, app, erp);
+ msgt[used++] = msga[41];
+ if ((NULL != hostname) && (0 == local)) {
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[20];
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[21];
+ msgt[used++] = hostname;
+ if (NULL != lsvcname) {
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[22];
+ msgt[used++] = lsvcname;
+ }
+ } else {
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[18];
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[19];
+ msgt[used++] = lsvcname;
+ }
+ if (NULL != fctname) {
+ if (NULL != msgtext) {
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = fctname;
+ msgt[used++] = dk4socket_03_kwnl[1];
+ msgt[used++] = msgtext;
+ } else {
+ res = dk4ma_write_decimal_signed(
+ bdec,DK4_SIZEOF(bdec,dkChar),(dk4_im_t)(erp->dt.iDetails1),0,NULL
+ );
+ if (0 != res) {
+ res = dk4ma_write_hex_signed(
+ bhex,DK4_SIZEOF(bhex,dkChar),(dk4_im_t)(erp->dt.iDetails1),0,NULL
+ );
+ if (0 != res) {
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = fctname;
+ msgt[used++] = dk4socket_03_kwnl[1];
+#if DK4_ON_WINDOWS
+ msgt[used++] = msga[40];
+#else
+ msgt[used++] = msga[37];
+#endif
+ msgt[used++] = bdec;
+ msgt[used++] = msga[38];
+ msgt[used++] = bhex;
+ msgt[used++] = msga[39];
+ }
+ }
+ }
+ } else {
+ }
+ dk4app_log_msg(app, DK4_LL_ERROR, msgt, used);
+ }
+ }
+}
+
+#if DK4_CHAR_SIZE > 1
+
+/** Create a socket using remote and optionally local address lists.
+ @param hostname Remote host name.
+ @param rast List of remote addresses.
+ @param last List of local addresses, may be NULL.
+ @param secs Seconds for timeout.
+ @param usecs Microseconds for timeout.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Valid socket on success, INVALID_SOCKET on error.
+*/
+static
+dk4_socket_t
+dk4socket_tcp_client_addresses_app(
+ const dkChar *hostname,
+ ADDRINFOW *rast,
+ ADDRINFOW *last,
+ long secs,
+ long usecs,
+ dk4_app_t *app
+)
+{
+ dk4_er_t er;
+ ADDRINFOW *ra;
+ ADDRINFOW *la;
+ dk4_socket_t back = INVALID_SOCKET;
+ int mpf = 0;
+
+
+#line 457 "dk4socka07.ctr"
+ ra = rast;
+ while ((INVALID_SOCKET == back) && (NULL != ra)) {
+ if (NULL != last) {
+ la = last;
+ while ((INVALID_SOCKET == back) && (NULL != la)) {
+ if (ra->ai_family == la->ai_family) {
+ mpf = 1;
+
+#line 464 "dk4socka07.ctr"
+ dk4error_init(&er);
+ back = dk4socket_tcp_client_for_addr(
+ ra->ai_family,
+ ra->ai_addr, ra->ai_addrlen,
+ la->ai_addr, la->ai_addrlen,
+ secs, usecs, &er
+ );
+ if (INVALID_SOCKET != back) {
+ dk4socket_report_connection_established(
+ app, hostname, ra->ai_family,
+ ra->ai_addr, ra->ai_addrlen,
+ la->ai_addr, la->ai_addrlen
+ );
+ ra = NULL; la = NULL;
+ } else {
+
+#line 479 "dk4socka07.ctr"
+ /* ERROR: Failed */
+ dk4socket_report_connection_error(
+ app, hostname, ra->ai_family,
+ ra->ai_addr, ra->ai_addrlen,
+ la->ai_addr, la->ai_addrlen,
+ &er
+ );
+ }
+ }
+ if (NULL != la) { la = la->ai_next; }
+ }
+ } else {
+ mpf = 1;
+ dk4error_init(&er);
+ back = dk4socket_tcp_client_for_addr(
+ ra->ai_family, ra->ai_addr, ra->ai_addrlen, NULL, 0, secs, usecs, &er
+ );
+ if (INVALID_SOCKET != back) {
+ dk4socket_report_connection_established(
+ app, hostname, ra->ai_family,
+ ra->ai_addr, ra->ai_addrlen,
+ NULL, 0
+ );
+ ra = NULL;
+ } else {
+
+#line 504 "dk4socka07.ctr"
+ /* ERROR: Failed */
+ dk4socket_report_connection_error(
+ app,hostname,ra->ai_family,ra->ai_addr,ra->ai_addrlen,NULL,0,&er
+ );
+ }
+ }
+ if (NULL != ra) { ra = ra->ai_next; }
+ }
+ if (INVALID_SOCKET == back) {
+ if (0 == mpf) {
+
+#line 514 "dk4socka07.ctr"
+ /* ERROR: No matching address pair found (27) */
+ dk4socket_report_no_matching_addresses(hostname, app);
+ }
+ }
+
+
+#line 519 "dk4socka07.ctr"
+ return back;
+}
+
+#else
+
+/** Create a socket using remote and optionally local address lists.
+ @param hostname Remote host name.
+ @param rast List of remote addresses.
+ @param last List of local addresses, may be NULL.
+ @param secs Seconds for timeout.
+ @param usecs Microseconds for timeout.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Valid socket on success, INVALID_SOCKET on error.
+*/
+static
+dk4_socket_t
+dk4socket_tcp_client_addresses_app(
+ const dkChar *hostname,
+ struct addrinfo *rast,
+ struct addrinfo *last,
+ long secs,
+ long usecs,
+ dk4_app_t *app
+)
+{
+ dk4_er_t er;
+ struct addrinfo *ra;
+ struct addrinfo *la;
+ dk4_socket_t back = INVALID_SOCKET;
+ int mpf = 0;
+
+
+#line 550 "dk4socka07.ctr"
+ ra = rast;
+ while ((INVALID_SOCKET == back) && (NULL != ra)) {
+ if (NULL != last) {
+ la = last;
+ while ((INVALID_SOCKET == back) && (NULL != la)) {
+ if (ra->ai_family == la->ai_family) {
+ mpf = 1;
+ dk4error_init(&er);
+ back = dk4socket_tcp_client_for_addr(
+ ra->ai_family,
+ ra->ai_addr, ra->ai_addrlen,
+ la->ai_addr, la->ai_addrlen,
+ secs, usecs, &er
+ );
+ if (INVALID_SOCKET != back) {
+ dk4socket_report_connection_established(
+ app, hostname, ra->ai_family,
+ ra->ai_addr, ra->ai_addrlen,
+ la->ai_addr, la->ai_addrlen
+ );
+ ra = NULL; la = NULL;
+ } else {
+
+#line 572 "dk4socka07.ctr"
+ /* ERROR: Failed */
+ dk4socket_report_connection_error(
+ app, hostname, ra->ai_family,
+ ra->ai_addr, ra->ai_addrlen,
+ la->ai_addr, la->ai_addrlen,
+ &er
+ );
+ }
+ }
+ if (NULL != la) { la = la->ai_next; }
+ }
+ } else {
+ mpf = 1;
+ dk4error_init(&er);
+ back = dk4socket_tcp_client_for_addr(
+ ra->ai_family, ra->ai_addr, ra->ai_addrlen, NULL, 0, secs, usecs, &er
+ );
+ if (INVALID_SOCKET != back) {
+ dk4socket_report_connection_established(
+ app, hostname, ra->ai_family,
+ ra->ai_addr, ra->ai_addrlen,
+ NULL, 0
+ );
+ ra = NULL;
+ } else {
+
+#line 597 "dk4socka07.ctr"
+ /* ERROR: Failed */
+ dk4socket_report_connection_error(
+ app,hostname,ra->ai_family,ra->ai_addr,ra->ai_addrlen,NULL,0,&er
+ );
+ }
+ }
+ if (NULL != ra) { ra = ra->ai_next; }
+ }
+ if (INVALID_SOCKET == back) {
+ if (0 == mpf) {
+ /* ERROR: No matching address pair found (27) */
+ dk4socket_report_no_matching_addresses(hostname, app);
+ }
+ }
+
+
+#line 612 "dk4socka07.ctr"
+ return back;
+}
+
+#endif
+
+/* ----- +getaddrinfo ----- */
+#else
+/* +++++ -getaddrinfo +++++ */
+
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+/** used to initialize IPv6 address for binding local ports.
+*/
+static const IN6_ADDR dk4socket_any6 = IN6ADDR_ANY_INIT;
+#endif
+
+static
+void
+dk4socket_report_invalid_port_number(dk4_app_t *app, size_t i)
+{
+ const dkChar * msgt[16];
+ const dkChar * const *msga;
+ size_t szmsga;
+ size_t used = 0;
+
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, DK4_LL_ERROR)) {
+ szmsga = dk4socket_log_num_texts();
+ msga = dk4socket_log_texts(app);
+ msgt[used++] = msga[41];
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[i];
+ dk4app_log_msg(app, DK4_LL_ERROR, msgt, used);
+ }
+ }
+}
+
+
+static
+void
+dk4socket_report_service_not_found(dk4_app_t *app, const dkChar *svcname)
+{
+ const dkChar * msgt[16];
+ const dkChar * const *msga;
+ size_t szmsga;
+ size_t used = 0;
+
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, DK4_LL_ERROR)) {
+ szmsga = dk4socket_log_num_texts();
+ msga = dk4socket_log_texts(app);
+ msgt[used++] = msga[23];
+ msgt[used++] = svcname;
+ msgt[used++] = msga[24];
+ dk4app_log_msg(app, DK4_LL_ERROR, msgt, used);
+ }
+ }
+}
+
+
+
+#if DK4_CHAR_SIZE > 1
+
+static
+void
+dk4socket_report_service_not_ascii(dk4_app_t *app, const dkChar *svcname)
+{
+ const dkChar * msgt[16];
+ const dkChar * const *msga;
+ size_t szmsga;
+ size_t used = 0;
+
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, DK4_LL_ERROR)) {
+ szmsga = dk4socket_log_num_texts();
+ msga = dk4socket_log_texts(app);
+ msgt[used++] = msga[25];
+ msgt[used++] = svcname;
+ msgt[used++] = msga[26];
+ dk4app_log_msg(app, DK4_LL_ERROR, msgt, used);
+ }
+ }
+}
+
+#endif
+
+
+
+static
+void
+dk4socket_report_illegal_address_part(
+ dk4_app_t *app,
+ const dkChar *hostname,
+ size_t i
+)
+{
+ const dkChar * msgt[16];
+ const dkChar * const *msga;
+ size_t szmsga;
+ size_t used = 0;
+
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, DK4_LL_ERROR)) {
+ szmsga = dk4socket_log_num_texts();
+ msga = dk4socket_log_texts(app);
+ msgt[used++] = msga[i];
+ if (NULL != hostname) {
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[43];
+ msgt[used++] = hostname;
+ }
+ dk4app_log_msg(app, DK4_LL_ERROR, msgt, used);
+ }
+ }
+}
+
+
+
+static
+void
+dk4socket_report_host_name_problem(
+ dk4_app_t *app,
+ const dkChar *hostname,
+ size_t i1,
+ size_t i2
+)
+{
+ const dkChar * msgt[16];
+ const dkChar * const *msga;
+ size_t szmsga;
+ size_t used = 0;
+
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, DK4_LL_ERROR)) {
+ szmsga = dk4socket_log_num_texts();
+ msga = dk4socket_log_texts(app);
+ if (NULL != hostname) {
+ msgt[used++] = msga[i1];
+ msgt[used++] = hostname;
+ msgt[used++] = msga[i2];
+ }
+ dk4app_log_msg(app, DK4_LL_ERROR, msgt, used);
+ }
+ }
+}
+
+/* ----- -getaddrinfo ----- */
+#endif
+
+
+
+/*
+ Exported functions
+ ------------------
+*/
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_ON_WINDOWS
+#if DK4_HAVE_GETADDRINFO
+/* +++++ wchar_t (Windows), +getaddrinfo +++++ */
+
+
+
+dk4_socket_t
+dk4socket_tcp_client_for_host_num_service_app(
+ const dkChar *hostname,
+ const dkChar *svcname,
+ const dkChar *lsvcname,
+ long secs,
+ long usecs,
+ int nsrv,
+ dk4_app_t *app
+)
+{
+ ADDRINFOW rhints;
+ ADDRINFOW lhints;
+ dk4_er_t er;
+ ADDRINFOW *rast = NULL;
+ ADDRINFOW *last = NULL;
+ dk4_socket_t back = INVALID_SOCKET;
+ int res;
+
+
+#line 793 "dk4socka07.ctr"
+ if ((NULL != hostname) && (NULL != svcname)) {
+
+#line 794 "dk4socka07.ctr"
+ DK4_MEMRES(&rhints, sizeof(rhints));
+ rhints.ai_family = AF_UNSPEC;
+ rhints.ai_socktype = SOCK_STREAM;
+ if (0 != nsrv) { rhints.ai_flags = AI_NUMERICSERV; }
+ rhints.ai_protocol = 0;
+ dk4error_init(&er);
+ res = GetAddrInfoW(hostname, svcname, &rhints, &rast);
+ if ((0 == res) && (NULL != rast)) {
+
+#line 802 "dk4socka07.ctr"
+ if (NULL != lsvcname) {
+
+#line 803 "dk4socka07.ctr"
+ DK4_MEMRES(&lhints, sizeof(lhints));
+ lhints.ai_family = AF_UNSPEC;
+ lhints.ai_socktype = SOCK_STREAM;
+ lhints.ai_flags = AI_PASSIVE;
+ if (0 != nsrv) { lhints.ai_flags |= AI_NUMERICSERV; }
+ lhints.ai_protocol = 0;
+ dk4error_init(&er);
+ res = GetAddrInfoW(NULL, lsvcname, &lhints, &last);
+ if ((0 == res) && (NULL != last)) {
+
+#line 812 "dk4socka07.ctr"
+ back = dk4socket_tcp_client_addresses_app(
+ hostname, rast, last, secs, usecs, app
+ );
+ FreeAddrInfoW(last);
+ } else {
+
+#line 817 "dk4socka07.ctr"
+ /* ERROR: Failed to obtain local addresses to bind (18, 19) */
+ dk4error_set_idetails(&er, DK4_E_SOCKET_GETADDRINFO, res);
+ dk4socket_report_gai(NULL, lsvcname, res, 1, app, &er);
+ }
+ } else {
+
+#line 822 "dk4socka07.ctr"
+ back = dk4socket_tcp_client_addresses_app(
+ hostname, rast, NULL, secs, usecs, app
+ );
+ }
+ FreeAddrInfoW(rast);
+ } else {
+
+#line 828 "dk4socka07.ctr"
+ /* ERROR: Failed to obtain remote addresses (20, 21, 22) */
+ dk4error_set_idetails(&er, DK4_E_SOCKET_GETADDRINFO, res);
+ dk4socket_report_gai(hostname, svcname, res, 0, app, &er);
+ }
+ } else {
+
+#line 833 "dk4socka07.ctr"
+ /* ERROR: Invalid arguments (bug) */
+ dk4socket_report_invalid_arguments(app);
+ }
+
+
+#line 837 "dk4socka07.ctr"
+ return back;
+}
+
+
+
+dk4_socket_t
+dk4socket_tcp_client_for_host_service_app(
+ const dkChar *hostname,
+ const dkChar *svcname,
+ const dkChar *lsvcname,
+ long secs,
+ long usecs,
+ dk4_app_t *app
+)
+{
+ return (
+ dk4socket_tcp_client_for_host_num_service_app(
+ hostname, svcname, lsvcname, secs, usecs, 0, app
+ )
+ );
+}
+
+
+
+dk4_socket_t
+dk4socket_tcp_client_for_host_port_app(
+ const dkChar *hostname,
+ unsigned short portno,
+ unsigned short lportno,
+ long secs,
+ long usecs,
+ dk4_app_t *app
+)
+{
+ dkChar rpnb[16*sizeof(dk4_um_t)];
+ dkChar lpnb[16*sizeof(dk4_um_t)];
+ dk4_er_t er;
+ dk4_socket_t back = INVALID_SOCKET;
+ int res;
+
+
+#line 877 "dk4socka07.ctr"
+ if ((NULL != hostname) && (0 < portno)) {
+
+#line 878 "dk4socka07.ctr"
+ dk4error_init(&er);
+ res = dk4ma_write_decimal_unsigned(
+ rpnb, DK4_SIZEOF(rpnb,dkChar), (dk4_um_t)portno, 0, &er
+ );
+ if (0 != res) {
+
+#line 883 "dk4socka07.ctr"
+ if (0 < lportno) {
+
+#line 884 "dk4socka07.ctr"
+ dk4error_init(&er);
+ res = dk4ma_write_decimal_unsigned(
+ lpnb, DK4_SIZEOF(lpnb,dkChar), (dk4_um_t)lportno, 0, &er
+ );
+ if (0 != res) {
+
+#line 889 "dk4socka07.ctr"
+ back = dk4socket_tcp_client_for_host_num_service_app(
+ hostname, rpnb, lpnb, secs, usecs, 0, app
+ );
+ } else {
+
+#line 893 "dk4socka07.ctr"
+ /* ERROR: Failed to convert local port number to text, bug */
+ }
+ } else {
+
+#line 896 "dk4socka07.ctr"
+ back = dk4socket_tcp_client_for_host_num_service_app(
+ hostname, rpnb, NULL, secs, usecs, 0, app
+ );
+ }
+ } else {
+
+#line 901 "dk4socka07.ctr"
+ /* ERROR: Failed to convert port number to text, bug */
+ }
+ } else {
+
+#line 904 "dk4socka07.ctr"
+ /* ERROR: Invalid arguments (bug) */
+ dk4socket_report_invalid_arguments(app);
+ }
+
+
+#line 908 "dk4socka07.ctr"
+ return back;
+}
+
+
+
+/* ----- wchar_t (Windows), +getaddrinfo ----- */
+#else
+/* +++++ wchar_t (Windows), -getaddrinfo +++++ */
+
+
+
+dk4_socket_t
+dk4socket_tcp_client_for_host_num_service_app(
+ const dkChar *hostname,
+ const dkChar *svcname,
+ const dkChar *lsvcname,
+ long secs,
+ long usecs,
+ int nsrv,
+ dk4_app_t *app
+)
+{
+ char cppt[48];
+ char cplp[48];
+ dk4_er_t er;
+ struct servent *serv = NULL;
+ const dkChar *endptr = NULL;
+ dk4_socket_t back = INVALID_SOCKET;
+ int res = 0;
+ unsigned short rport = 0U;
+ unsigned short lport = 0U;
+ unsigned short iport = 0U;
+
+
+#line 941 "dk4socka07.ctr"
+ if ((NULL != hostname) && (NULL != svcname)) {
+ dk4error_init(&er);
+ res = dk4ma_input_dk_dec_ushort(&rport, svcname, &endptr, 1, NULL);
+ if (0 == res) {
+ if (0 != dk4recode_wchar_t_to_char(cppt, sizeof(cppt), svcname, &er)) {
+ dk4socket_error_reset();
+ serv = getservbyname(cppt, NULL);
+ if (NULL != serv) {
+ iport = serv->s_port;
+ dk4socket_swap_bytes_if_not_bigendian((void *)(&iport),sizeof(iport));
+ rport = (unsigned short)iport;
+ } else {
+ dk4socket_error_report(&er, DK4_E_SOCKET_GETSERVBYNAME);
+ /* ERROR: Service not found (23, 24) */
+ dk4socket_report_service_not_found(app, svcname);
+ }
+ } else {
+ /* ERROR: Failed to convert service name (25, 26) */
+ dk4socket_report_service_not_ascii(app, svcname);
+ }
+ }
+ if (0 < rport) {
+ if (NULL != lsvcname) {
+ endptr = NULL;
+ dk4error_init(&er);
+ res = dk4ma_input_dk_dec_ushort(&lport, lsvcname, &endptr, 1, NULL);
+ if (0 == res) {
+ dk4error_init(&er);
+ if (0 != dk4recode_wchar_t_to_char(cplp,sizeof(cplp),lsvcname,&er)) {
+ dk4socket_error_reset();
+ serv = getservbyname(cplp, NULL);
+ if (NULL != serv) {
+ iport = serv->s_port;
+ dk4socket_swap_bytes_if_not_bigendian(
+ (void *)(&iport), sizeof(iport)
+ );
+ lport = (unsigned short)iport;
+ } else {
+ dk4socket_error_report(&er, DK4_E_SOCKET_GETSERVBYNAME);
+ /* Service not found (23, 24) */
+ dk4socket_report_service_not_found(app, lsvcname);
+ }
+ } else {
+ /* ERROR: Text conversion failed (25, 26) */
+ dk4socket_report_service_not_ascii(app, lsvcname);
+ }
+ }
+ if (0 < lport) {
+ back = dk4socket_tcp_client_for_host_port_app(
+ hostname, rport, lport, secs, usecs, app
+ );
+ } else {
+ /* ERROR: Illegal local port number (28) */
+ dk4socket_report_invalid_port_number(app, 28);
+ }
+ } else {
+ back = dk4socket_tcp_client_for_host_port_app(
+ hostname, rport, 0, secs, usecs, app
+ );
+ }
+ } else {
+ /* ERROR: Illegal remote port number (29) */
+ dk4socket_report_invalid_port_number(app, 29);
+ }
+ } else {
+ /* ERROR: Invalid arguments (bug) */
+ dk4socket_report_invalid_arguments(app);
+ }
+
+
+#line 1010 "dk4socka07.ctr"
+ return back;
+}
+
+
+
+dk4_socket_t
+dk4socket_tcp_client_for_host_service_app(
+ const dkChar *hostname,
+ const dkChar *svcname,
+ const dkChar *lsvcname,
+ long secs,
+ long usecs,
+ dk4_app_t *app
+)
+{
+ return (
+ dk4socket_tcp_client_for_host_num_service_app(
+ hostname, svcname, lsvcname, secs, usecs, 0, app
+ )
+ );
+}
+
+
+
+dk4_socket_t
+dk4socket_tcp_client_for_host_port_app(
+ const dkChar *hostname,
+ unsigned short portno,
+ unsigned short lportno,
+ long secs,
+ long usecs,
+ dk4_app_t *app
+)
+{
+ char hona[1040];
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ struct sockaddr_in6 sr6;
+ struct sockaddr_in6 sl6;
+#endif
+ struct sockaddr_in sr4;
+ struct sockaddr_in sl4;
+ dk4_er_t er;
+ char **addrptr;
+ struct hostent *hep;
+ dk4_socket_t back = INVALID_SOCKET;
+
+
+
+#line 1057 "dk4socka07.ctr"
+ if ((NULL != hostname) && (0 < portno)) {
+ dk4error_init(&er);
+ if (0 != dk4recode_wchar_t_to_char(hona, sizeof(hona), hostname, &er)) {
+ dk4socket_error_reset();
+ hep = gethostbyname(hona);
+ if (NULL != hep) {
+ if (NULL != hep->h_addr_list) {
+ switch (hep->h_addrtype) {
+ case AF_INET : {
+ if (4 == hep->h_length) {
+ addrptr = hep->h_addr_list;
+ while ((INVALID_SOCKET == back) && (NULL != *addrptr)) {
+ DK4_MEMRES(&sr4, sizeof(sr4));
+ sr4.sin_family = AF_INET;
+ sr4.sin_port = dk4socket_htons(portno);
+ DK4_MEMCPY(&(sr4.sin_addr), *addrptr, sizeof(IN_ADDR));
+ dk4error_init(&er);
+ if (0 != lportno) {
+ DK4_MEMRES(&sl4, sizeof(sl4));
+ sl4.sin_family = AF_INET;
+ sl4.sin_port = dk4socket_htons(lportno);
+ sl4.sin_addr.s_addr = dk4socket_htonl(INADDR_ANY);
+ back = dk4socket_tcp_client_for_addr(
+ AF_INET, (struct sockaddr *)(&sr4), sizeof(sr4),
+ (struct sockaddr *)(&sl4), sizeof(sl4), secs, usecs, &er
+ );
+ } else {
+ back = dk4socket_tcp_client_for_addr(
+ AF_INET, (struct sockaddr *)(&sr4), sizeof(sr4),
+ NULL, 0, secs, usecs, &er
+ );
+ }
+ if (INVALID_SOCKET == back) {
+
+#line 1090 "dk4socka07.ctr"
+ /* ERROR: Failed */
+ dk4socket_report_connection_error(
+ app, hostname, AF_INET,
+ (struct sockaddr *)(&sr4), sizeof(sr4),
+ ((0 < lportno) ? ((struct sockaddr *)(&sl4)) : NULL),
+ ((0 < lportno) ? (sizeof(sl4)) : 0),
+ &er
+ );
+ } else {
+ /* DEBUG: Connection established (30) */
+ dk4socket_report_connection_established(
+ app, hostname, AF_INET,
+ (struct sockaddr *)(&sr4), sizeof(sr4),
+ ((0 < lportno) ? ((struct sockaddr *)(&sl4)) : NULL),
+ ((0 < lportno) ? (sizeof(sl4)) : 0)
+ );
+ }
+ addrptr++;
+ }
+ } else {
+ /* ERROR: Illegal address length, bug (31) */
+ dk4socket_report_illegal_address_part(app, hostname, 31);
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ if (16 == hep->h_length) {
+ addrptr = hep->h_addr_list;
+ while ((INVALID_SOCKET == back) && (NULL != *addrptr)) {
+ DK4_MEMRES(&sr6, sizeof(sr6));
+ sr6.sin6_family = AF_INET6;
+ sr6.sin6_port = dk4socket_htons(portno);
+ DK4_MEMCPY(&(sr6.sin6_addr), *addrptr, sizeof(IN6_ADDR));
+ dk4error_init(&er);
+ if (0 < lportno) {
+ DK4_MEMRES(&sl6, sizeof(sl6));
+ sl6.sin6_family = AF_INET6;
+ sl6.sin6_port = dk4socket_htons(lportno);
+ DK4_MEMCPY(&(sl6.sin6_addr),&dk4socket_any6,sizeof(IN6_ADDR));
+ back = dk4socket_tcp_client_for_addr(
+ AF_INET6, (struct sockaddr *)(&sr6), sizeof(sr6),
+ (struct sockaddr *)(&sl6), sizeof(sl6), secs, usecs, &er
+ );
+ } else {
+ back = dk4socket_tcp_client_for_addr(
+ AF_INET6, (struct sockaddr *)(&sr6), sizeof(sr6),
+ NULL, 0, secs, usecs, &er
+ );
+ }
+ if (INVALID_SOCKET == back) {
+
+#line 1140 "dk4socka07.ctr"
+ /* ERROR: Failed */
+ dk4socket_report_connection_error(
+ app, hostname, AF_INET6,
+ (struct sockaddr *)(&sr6), sizeof(sr6),
+ ((0 < lportno) ? ((struct sockaddr *)(&sl6)) : NULL),
+ ((0 < lportno) ? (sizeof(sl6)) : 0),
+ &er
+ );
+ } else {
+ /* DEBUG: Connection established (30) */
+ dk4socket_report_connection_established(
+ app, hostname, AF_INET6,
+ (struct sockaddr *)(&sr6), sizeof(sr6),
+ ((0 < lportno) ? ((struct sockaddr *)(&sl6)) : NULL),
+ ((0 < lportno) ? (sizeof(sl6)) : 0)
+ );
+ }
+ addrptr++;
+ }
+ } else {
+ /* ERROR: Illegal address length, bug (31) */
+ dk4socket_report_illegal_address_part(app, hostname, 31);
+ }
+ } break;
+#endif
+ default : {
+ /* ERROR: Illegal address family (32) */
+ dk4socket_report_illegal_address_part(app, hostname, 32);
+ } break;
+ }
+ } else {
+ /* ERROR: Host not found (33, 34) */
+ dk4socket_report_host_name_problem(app, hostname, 33, 34);
+ }
+ } else {
+ dk4socket_error_report(&er, DK4_E_SOCKET_GETHOSTBYNAME);
+ /* ERROR: Host not found (33, 34) */
+ dk4socket_report_host_name_problem(app, hostname, 33, 34);
+ }
+ } else {
+ /* ERROR: Failed to convert host name to ASCII (35, 36) */
+ dk4socket_report_host_name_problem(app, hostname, 35, 36);
+ }
+ } else {
+ /* ERROR: Invalid arguments (bug) */
+ dk4socket_report_invalid_arguments(app);
+ }
+
+
+#line 1188 "dk4socka07.ctr"
+ return back;
+}
+
+
+
+/* ----- wchar_t (Windows), -getaddrinfo ----- */
+#endif
+#else
+#error No support for networking with wchar_t strings!
+#endif
+#else
+#if DK4_HAVE_GETADDRINFO
+/* +++++ char, +getaddrinfo +++++ */
+
+dk4_socket_t
+dk4socket_tcp_client_for_host_num_service_app(
+ const dkChar *hostname,
+ const dkChar *svcname,
+ const dkChar *lsvcname,
+ long secs,
+ long usecs,
+ int nsrv,
+ dk4_app_t *app
+)
+{
+ struct addrinfo rhints;
+ struct addrinfo lhints;
+ dk4_er_t er;
+ struct addrinfo *raddrst = NULL;
+ struct addrinfo *laddrst = NULL;
+ dk4_socket_t back = INVALID_SOCKET;
+ int res;
+
+
+#line 1221 "dk4socka07.ctr"
+
+
+#line 1222 "dk4socka07.ctr"
+
+
+#line 1223 "dk4socka07.ctr"
+ if ((NULL != hostname) && (NULL != svcname)) {
+
+#line 1224 "dk4socka07.ctr"
+ DK4_MEMRES(&rhints, sizeof(rhints));
+ rhints.ai_family = AF_UNSPEC;
+ rhints.ai_socktype = SOCK_STREAM;
+ if (0 != nsrv) { rhints.ai_flags = AI_NUMERICSERV; }
+ rhints.ai_protocol = 0;
+ dk4error_init(&er);
+ res = getaddrinfo(hostname, svcname, &rhints, &raddrst);
+ if ((0 == res) && (NULL != raddrst)) {
+
+#line 1232 "dk4socka07.ctr"
+ if (NULL != lsvcname) {
+
+#line 1233 "dk4socka07.ctr"
+ DK4_MEMRES(&lhints, sizeof(lhints));
+ lhints.ai_family = AF_UNSPEC;
+ lhints.ai_socktype = SOCK_STREAM;
+ lhints.ai_flags = AI_PASSIVE;
+ if (0 != nsrv) { lhints.ai_flags |= AI_NUMERICSERV; }
+ lhints.ai_protocol = 0;
+ dk4error_init(&er);
+ res = getaddrinfo(NULL, lsvcname, &lhints, &laddrst);
+ if ((0 == res) && (NULL != laddrst)) {
+
+#line 1242 "dk4socka07.ctr"
+ back = dk4socket_tcp_client_addresses_app(
+ hostname, raddrst, laddrst, secs, usecs, app
+ );
+ freeaddrinfo(laddrst);
+ } else {
+
+#line 1247 "dk4socka07.ctr"
+ /* ERROR: Failed to obtain local addresses (18, 19) */
+ dk4error_set_idetails(&er, DK4_E_SOCKET_GETADDRINFO, res);
+ dk4socket_report_gai(NULL, lsvcname, res, 1, app, &er);
+ }
+ } else {
+
+#line 1252 "dk4socka07.ctr"
+ back = dk4socket_tcp_client_addresses_app(
+ hostname, raddrst, NULL, secs, usecs, app
+ );
+ }
+ freeaddrinfo(raddrst);
+ } else {
+
+#line 1258 "dk4socka07.ctr"
+ /* ERROR: Failed to obtain remote addresses (20, 21, 22) */
+ dk4error_set_idetails(&er, DK4_E_SOCKET_GETADDRINFO, res);
+ dk4socket_report_gai(hostname, svcname, res, 0, app, &er);
+ }
+ } else {
+
+#line 1263 "dk4socka07.ctr"
+ /* ERROR: Invalid arguments (bug) */
+ dk4socket_report_invalid_arguments(app);
+ }
+
+
+#line 1267 "dk4socka07.ctr"
+ return back;
+}
+
+
+
+dk4_socket_t
+dk4socket_tcp_client_for_host_service_app(
+ const dkChar *hostname,
+ const dkChar *svcname,
+ const dkChar *lsvcname,
+ long secs,
+ long usecs,
+ dk4_app_t *app
+)
+{
+ return (
+ dk4socket_tcp_client_for_host_num_service_app(
+ hostname, svcname, lsvcname, secs, usecs, 0, app
+ )
+ );
+}
+
+
+
+dk4_socket_t
+dk4socket_tcp_client_for_host_port_app(
+ const dkChar *hostname,
+ unsigned short portno,
+ unsigned short lportno,
+ long secs,
+ long usecs,
+ dk4_app_t *app
+)
+{
+ char rpn[16*sizeof(dk4_um_t)];
+ char lpn[16*sizeof(dk4_um_t)];
+ dk4_socket_t back = INVALID_SOCKET;
+ int res;
+
+
+#line 1306 "dk4socka07.ctr"
+ if ((NULL != hostname) && (0 < portno)) {
+ res = dk4ma_write_c8_decimal_unsigned(
+ rpn, sizeof(rpn), (dk4_um_t)portno, 0, NULL
+ );
+ if (0 != res) {
+ if (0 < lportno) {
+ res = dk4ma_write_c8_decimal_unsigned(
+ lpn, sizeof(lpn), (dk4_um_t)lportno, 0, NULL
+ );
+ if (0 != res) {
+ back = dk4socket_tcp_client_for_host_num_service_app(
+ hostname, rpn, lpn, secs, usecs, 1, app
+ );
+ } else {
+ /* ERROR: Failed to convert port number to text, bug */
+ }
+ } else {
+ back = dk4socket_tcp_client_for_host_num_service_app(
+ hostname, rpn, NULL, secs, usecs, 1, app
+ );
+ }
+ } else {
+ /* ERROR: Failed to convert port number to text, bug */
+ }
+ } else {
+ /* ERROR: Invalid arguments (bug) */
+ dk4socket_report_invalid_arguments(app);
+ }
+
+
+#line 1335 "dk4socka07.ctr"
+ return back;
+}
+
+
+
+/* ----- char, +getaddrinfo ----- */
+#else
+/* +++++ char, -getaddrinfo ----- */
+
+
+
+dk4_socket_t
+dk4socket_tcp_client_for_host_num_service_app(
+ const dkChar *hostname,
+ const dkChar *svcname,
+ const dkChar *lsvcname,
+ long secs,
+ long usecs,
+ int nsrv,
+ dk4_app_t *app
+)
+{
+ const char *endptr = NULL;
+ struct servent *serv = NULL;
+ dk4_socket_t back = INVALID_SOCKET;
+ int res = 0;
+ int iport = 0;
+ unsigned short rport = 0;
+ unsigned short lport = 0;
+
+
+#line 1365 "dk4socka07.ctr"
+ if ((NULL != hostname) && (NULL != svcname)) {
+ res = dk4ma_input_c8_dec_ushort(&rport, svcname, &endptr, 1, NULL);
+ if (0 == res) {
+ dk4socket_error_reset();
+ serv = getservbyname(svcname, NULL);
+ if (NULL != serv) {
+ iport = serv->s_port;
+ dk4socket_swap_bytes_if_not_bigendian((void *)(&iport), sizeof(iport));
+ rport = (unsigned short)iport;
+ } else {
+ /* ERROR: Service name for remote port not found (23, 24) */
+ dk4socket_report_service_not_found(app, svcname);
+ }
+ }
+ if (0 != rport) {
+ if (NULL != lsvcname) {
+ endptr = NULL;
+ res = dk4ma_input_c8_dec_ushort(&lport, lsvcname, &endptr, 1, NULL);
+ if (0 == res) {
+ dk4socket_error_reset();
+ serv = getservbyname(lsvcname, NULL);
+ if (NULL != serv) {
+ iport = serv->s_port;
+ dk4socket_swap_bytes_if_not_bigendian(
+ (void *)(&iport), sizeof(iport)
+ );
+ lport = (unsigned short)iport;
+ } else {
+ /* ERROR: Service name for local port not found (23, 24) */
+ dk4socket_report_service_not_found(app, lsvcname);
+ }
+ }
+ if (0 != lport) {
+ back = dk4socket_tcp_client_for_host_port_app(
+ hostname, rport, lport, secs, usecs, app
+ );
+ } else {
+ /* ERROR: Illegal local port number (28) */
+ dk4socket_report_invalid_port_number(app, 28);
+ }
+ } else {
+ back = dk4socket_tcp_client_for_host_port_app(
+ hostname, rport, 0, secs, usecs, app
+ );
+ }
+ } else {
+ /* ERROR: Illegal remote port number (29) */
+ dk4socket_report_invalid_port_number(app, 29);
+ }
+ } else {
+ /* ERROR: Invalid arguments (bug) */
+ dk4socket_report_invalid_arguments(app);
+ }
+
+
+#line 1419 "dk4socka07.ctr"
+ return back;
+}
+
+
+
+dk4_socket_t
+dk4socket_tcp_client_for_host_service_app(
+ const dkChar *hostname,
+ const dkChar *svcname,
+ const dkChar *lsvcname,
+ long secs,
+ long usecs,
+ dk4_app_t *app
+)
+{
+ return (
+ dk4socket_tcp_client_for_host_num_service_app(
+ hostname, svcname, lsvcname, secs, usecs, 0, app
+ )
+ );
+}
+
+
+
+dk4_socket_t
+dk4socket_tcp_client_for_host_port_app(
+ const dkChar *hostname,
+ unsigned short portno,
+ unsigned short lportno,
+ long secs,
+ long usecs,
+ dk4_app_t *app
+)
+{
+ dk4_er_t er;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ struct sockaddr_in6 sr6;
+ struct sockaddr_in6 sl6;
+#endif
+ struct sockaddr_in sr4;
+ struct sockaddr_in sl4;
+ char **addrptr;
+ struct hostent *hep = NULL;
+ dk4_socket_t back = INVALID_SOCKET;
+
+
+#line 1464 "dk4socka07.ctr"
+ if ((NULL != hostname) && (0 < portno)) {
+ dk4error_init(&er);
+ dk4socket_error_reset();
+ hep = gethostbyname(hostname);
+ if (NULL != hep) {
+ if (NULL != hep->h_addr_list) {
+ switch (hep->h_addrtype) {
+ case AF_INET : {
+ if (4 == hep->h_length) {
+ addrptr = hep->h_addr_list;
+ while ((INVALID_SOCKET == back) && (NULL != *addrptr)) {
+ DK4_MEMRES(&sr4, sizeof(sr4));
+ sr4.sin_family = AF_INET;
+ sr4.sin_port = dk4socket_htons(portno);
+ DK4_MEMCPY(&(sr4.sin_addr), *addrptr, sizeof(IN_ADDR));
+ dk4error_init(&er);
+ if (0 != lportno) {
+ DK4_MEMRES(&sl4, sizeof(sl4));
+ sl4.sin_family = AF_INET;
+ sl4.sin_port = dk4socket_htons(lportno);
+ sl4.sin_addr.s_addr = dk4socket_htonl(INADDR_ANY);
+ back = dk4socket_tcp_client_for_addr(
+ AF_INET, (struct sockaddr *)(&sr4), sizeof(sr4),
+ (struct sockaddr *)(&sl4), sizeof(sl4), secs, usecs, &er
+ );
+ } else {
+ back = dk4socket_tcp_client_for_addr(
+ AF_INET, (struct sockaddr *)(&sr4), sizeof(sr4),
+ NULL, 0, secs, usecs, &er
+ );
+ }
+ if (INVALID_SOCKET == back) {
+
+#line 1496 "dk4socka07.ctr"
+ /* ERROR: Failed */
+ dk4socket_report_connection_error(
+ app, hostname, AF_INET,
+ (struct sockaddr *)(&sr4), sizeof(sr4),
+ ((0 < lportno) ? ((struct sockaddr *)(&sl4)) : NULL),
+ ((0 < lportno) ? (sizeof(sl4)) : 0),
+ &er
+ );
+ } else {
+ /* DEBUG: Connection established (30) */
+ dk4socket_report_connection_established(
+ app, hostname, AF_INET,
+ (struct sockaddr *)(&sr4), sizeof(sr4),
+ ((0 < lportno) ? ((struct sockaddr *)(&sl4)) : NULL),
+ ((0 < lportno) ? (sizeof(sl4)) : 0)
+ );
+ }
+ addrptr++;
+ }
+ } else {
+ /* ERROR: Illegal address length (31) */
+ dk4socket_report_illegal_address_part(app, hostname, 31);
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ if (16 == hep->h_length) {
+ addrptr = hep->h_addr_list;
+ while ((INVALID_SOCKET == back) && (NULL != *addrptr)) {
+ DK4_MEMRES(&sr6, sizeof(sr6));
+ sr6.sin6_family = AF_INET6;
+ sr6.sin6_port = dk4socket_htons(portno);
+ DK4_MEMCPY(&(sr6.sin6_addr), *addrptr, sizeof(IN6_ADDR));
+ dk4error_init(&er);
+ if (0 != lportno) {
+ DK4_MEMRES(&sl6, sizeof(sl6));
+ sl6.sin6_family = AF_INET6;
+ sl6.sin6_port = dk4socket_htons(lportno);
+ DK4_MEMCPY(&(sl6.sin6_addr),&dk4socket_any6,sizeof(IN6_ADDR));
+ back = dk4socket_tcp_client_for_addr(
+ AF_INET6, (struct sockaddr *)(&sr6), sizeof(sr6),
+ (struct sockaddr *)(&sl6), sizeof(sl6),
+ secs, usecs, &er
+ );
+ } else {
+ back = dk4socket_tcp_client_for_addr(
+ AF_INET6, (struct sockaddr *)(&sr6), sizeof(sr6),
+ NULL, 0, secs, usecs, &er
+ );
+ }
+ if (INVALID_SOCKET == back) {
+
+#line 1547 "dk4socka07.ctr"
+ /* ERROR: Failed */
+ dk4socket_report_connection_error(
+ app, hostname, AF_INET6,
+ (struct sockaddr *)(&sr6), sizeof(sr6),
+ ((0 < lportno) ? ((struct sockaddr *)(&sl6)) : NULL),
+ ((0 < lportno) ? (sizeof(sl6)) : 0),
+ &er
+ );
+ } else {
+ /* DEBUG: Connection established (30) */
+ dk4socket_report_connection_established(
+ app, hostname, AF_INET6,
+ (struct sockaddr *)(&sr6), sizeof(sr6),
+ ((0 < lportno) ? ((struct sockaddr *)(&sl6)) : NULL),
+ ((0 < lportno) ? (sizeof(sl6)) : 0)
+ );
+ }
+ addrptr++;
+ }
+ } else {
+ /* ERROR: Illegal address length (31) */
+ dk4socket_report_illegal_address_part(app, hostname, 31);
+ }
+ } break;
+#endif
+ default : {
+ /* ERROR: Illegal address family (32) */
+ dk4socket_report_illegal_address_part(app, hostname, 32);
+ } break;
+ }
+ } else {
+ /* ERROR: Remote host address not found! (33, 34) */
+ dk4socket_report_host_name_problem(app, hostname, 33, 34);
+ }
+ } else {
+ dk4socket_error_report(&er, DK4_E_SOCKET_GETHOSTBYNAME);
+ /* ERROR: Remote host address not found! (33, 34) */
+ dk4socket_report_host_name_problem(app, hostname, 33, 34);
+ }
+ } else {
+ /* ERROR: Invalid arguments (bug) */
+ dk4socket_report_invalid_arguments(app);
+ }
+
+
+#line 1591 "dk4socka07.ctr"
+ return back;
+}
+
+
+
+/* ----- char, -getaddrinfo ----- */
+#endif
+#endif
+
diff --git a/support/dktools/dk4socka07.ctr b/support/dktools/dk4socka07.ctr
new file mode 100644
index 0000000000..1fc622710a
--- /dev/null
+++ b/support/dktools/dk4socka07.ctr
@@ -0,0 +1,1599 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% module
+
+
+#include "dk4sock.h"
+#include "dk4socka.h"
+#include "dk4mem.h"
+
+#if DK4_HAVE_GETADDRINFO
+#include "dk4mao8d.h"
+#else
+#if DK4_CHAR_SIZE > 1
+#include "dk4maiwdus.h"
+#include "dk4rec24.h"
+#endif
+#include "dk4mai8dus.h"
+#endif
+
+#include "dk4maiddus.h"
+#include "dk4maodd.h"
+#include "dk4maodh.h"
+
+
+
+$!trace-include
+
+
+
+/** Constant texts used by module, not localized.
+*/
+static const dkChar * const dk4socket_03_kwnl[] = {
+$!string-table macro=dkT
+#
+# 0 Separator to switch to next line.
+#
+\n\t
+#
+# 1 Separator between function name and message text
+#
+:
+#
+# 2 Separator between service and host name
+#
+@
+$!end
+};
+
+
+
+/*
+ Internal tool functions
+ -----------------------
+*/
+
+/** Report error from dk4socket_tcp_client_for_addr().
+ @param app Application structure for logging.
+ @param hostname Host name to connect to.
+ @param afam Address family.
+ @param sremote Pointer to remote address buffer.
+ @param szremote Remote address size.
+ @param slocal Pointer to local address buffer.
+ @param szlocal Local address size.
+ @param erp Error report, required.
+*/
+static
+void
+dk4socket_report_connection_error(
+ dk4_app_t *app,
+ const dkChar *hostname,
+ int afam,
+ const struct sockaddr *sremote,
+ size_t szremote,
+ const struct sockaddr *slocal,
+ size_t szlocal,
+ dk4_er_t *erp
+)
+{
+ const dkChar * msgt[32]; /* Message components */
+ dkChar bdec[16*sizeof(dk4_um_t)]; /* Decimal */
+ dkChar bhex[16*sizeof(dk4_um_t)]; /* Hexadecimal */
+ dkChar bloc[128]; /* Local address */
+ dkChar brem[128]; /* Remote address */
+ const dkChar * const *msga = NULL; /* Localized texts */
+ const dkChar *fctname = NULL; /* Name of failed function */
+ const dkChar *msgtext = NULL; /* Text why fct failed */
+#if VERSION_BEFORE_20150821
+ size_t szmsga = 0; /* Number of elems in msga */
+#endif
+ size_t used = 0; /* No used elems in msgt */
+ int res = 0; /* Conversion result */
+ int bothbuf = 0; /* Flag: Have bdec and bhex */
+ int fctnmsg = 0; /* Flag: Use fct name */
+ $? "+ dk4socket_report_connection_error"
+ if (NULL != app) {
+ if (dk4app_log_do(app, DK4_LL_ERROR)) {
+#if VERSION_BEFORE_20150821
+ szmsga = dk4socket_log_num_texts();
+#endif
+ msga = dk4socket_log_texts(app);
+ dk4socket_log_fctname_msg(&fctname, &msgtext, app, erp);
+ if (NULL == msgtext) {
+ res = dk4ma_write_decimal_signed(
+ bdec, DK4_SIZEOF(bdec,dkChar), (dk4_im_t)(erp->dt.iDetails1), 0, NULL
+ );
+ if (0 != res) {
+ res = dk4ma_write_hex_signed(
+ bhex,DK4_SIZEOF(bhex,dkChar),(dk4_im_t)(erp->dt.iDetails1),0,NULL
+ );
+ if (0 != res) { bothbuf = 1; }
+ }
+ }
+ msgt[used++] = msga[41];
+ if ((NULL != slocal) && (0 < szlocal)) {
+ res = dk4socket_addr_port_to_text(
+ bloc, DK4_SIZEOF(bloc,dkChar), afam, slocal, szlocal, NULL
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[42];
+ msgt[used++] = bloc;
+ }
+ }
+ if ((NULL != sremote) && (0 < szremote)) {
+ res = dk4socket_addr_port_to_text(
+ brem, DK4_SIZEOF(brem,dkChar), afam, sremote, szremote, NULL
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[43];
+ msgt[used++] = brem;
+ }
+ }
+ switch (erp->ec) {
+ case DK4_E_INVALID_ARGUMENTS : {
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[45];
+ } break;
+ case DK4_E_SOCKET_SOCKET : {
+ fctnmsg = 1;
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[2];
+ } break;
+ case DK4_E_SOCKET_BIND : {
+ fctnmsg = 1;
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[4];
+ } break;
+ case DK4_E_SOCKET_FCNTL : {
+ fctnmsg = 1;
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[9];
+ } break;
+ case DK4_E_SOCKET_IOCTLSOCKET : {
+ fctnmsg = 1;
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[9];
+ } break;
+ case DK4_E_SOCKET_CONNECT : {
+ fctnmsg = 1;
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[7];
+ } break;
+ case DK4_E_SOCKET_TIMEOUT : {
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[44];
+ } break;
+ case DK4_E_SOCKET_SELECT : {
+ fctnmsg = 1;
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[44];
+ } break;
+ case DK4_E_SOCKET_GETSOCKOPT : {
+ fctnmsg = 1;
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[8];
+ } break;
+ case DK4_E_SOCKET_SETSOCKOPT : {
+ fctnmsg = 1;
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[8];
+ } break;
+ }
+ if (0 != fctnmsg) {
+ if ((NULL != fctname) && ((NULL != msgtext) || (0 != bothbuf))) {
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = fctname;
+ msgt[used++] = dk4socket_03_kwnl[1];
+ if (NULL != msgtext) {
+ msgt[used++] = msgtext;
+ } else {
+#if DK4_ON_WINDOWS
+ msgt[used++] = msga[40];
+#else
+ msgt[used++] = msga[37];
+#endif
+ msgt[used++] = bdec;
+ msgt[used++] = msga[38];
+ msgt[used++] = bhex;
+ msgt[used++] = msga[39];
+ }
+ }
+ }
+ dk4app_log_msg(app, DK4_LL_ERROR, msgt, used);
+ }
+ }
+ $? "- dk4socket_report_connection_error"
+}
+
+
+
+/** Report error from dk4socket_tcp_client_for_addr().
+ @param app Application structure for logging.
+ @param hostname Host name to connect to.
+ @param afam Address family.
+ @param sremote Pointer to remote address buffer.
+ @param szremote Remote address size.
+ @param slocal Pointer to local address buffer.
+ @param szlocal Local address size.
+ @param erp Error report, required.
+*/
+static
+void
+dk4socket_report_connection_established(
+ dk4_app_t *app,
+ const dkChar *hostname,
+ int afam,
+ const struct sockaddr *sremote,
+ size_t szremote,
+ const struct sockaddr *slocal,
+ size_t szlocal
+)
+{
+ const dkChar * msgt[32]; /* Message components */
+ dkChar bloc[128]; /* Local address */
+ dkChar brem[128]; /* Remote address */
+ const dkChar * const *msga = NULL; /* Localized texts */
+#if VERSION_BEFORE_20150821
+ size_t szmsga = 0; /* Number of elems in msga */
+#endif
+ size_t used = 0; /* No used elems in msgt */
+ int res = 0; /* Conversion result */
+
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, DK4_LL_PROGRESS)) {
+#if VERSION_BEFORE_20150821
+ szmsga = dk4socket_log_num_texts();
+#endif
+ msga = dk4socket_log_texts(app);
+ msgt[used++] = msga[30];
+ if ((NULL != slocal) && (0 < szlocal)) {
+ res = dk4socket_addr_port_to_text(
+ bloc, DK4_SIZEOF(bloc,dkChar), afam, slocal, szlocal, NULL
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[42];
+ msgt[used++] = bloc;
+ }
+ }
+ if ((NULL != sremote) && (0 < szremote)) {
+ res = dk4socket_addr_port_to_text(
+ brem, DK4_SIZEOF(brem,dkChar), afam, sremote, szremote, NULL
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[43];
+ msgt[used++] = brem;
+ }
+ }
+ dk4app_log_msg(app, DK4_LL_PROGRESS, msgt, used);
+ }
+ }
+}
+
+
+
+static
+void
+dk4socket_report_invalid_arguments(
+ dk4_app_t *app
+)
+{
+ const dkChar * msgt[16];
+ const dkChar * const *msga;
+#if VERSION_BEFORE_20150821
+ size_t szmsga;
+#endif
+ size_t used = 0;
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, DK4_LL_ERROR)) {
+#if VERSION_BEFORE_20150821
+ szmsga = dk4socket_log_num_texts();
+#endif
+ msga = dk4socket_log_texts(app);
+ msgt[used++] = msga[41];
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[45];
+ dk4app_log_msg(app, DK4_LL_ERROR, msgt, used);
+ }
+ }
+}
+
+
+#if DK4_HAVE_GETADDRINFO
+/* +++++ +getaddrinfo +++++ */
+
+static
+void
+dk4socket_report_no_matching_addresses(
+ const dkChar *hostname,
+ dk4_app_t *app
+)
+{
+ const dkChar *msgt[16];
+ const dkChar * const *msga;
+#if VERSION_BEFORE_20150821
+ size_t szmsga;
+#endif
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, DK4_LL_ERROR)) {
+#if VERSION_BEFORE_20150821
+ szmsga = dk4socket_log_num_texts();
+#endif
+ msga = dk4socket_log_texts(app);
+ msgt[0] = msga[41];
+ msgt[1] = dk4socket_03_kwnl[0];
+ msgt[2] = msga[43];
+ msgt[4] = hostname;
+ msgt[5] = dk4socket_03_kwnl[0];
+ msgt[6] = msga[46];
+ dk4app_log_msg(app, DK4_LL_ERROR, msgt, 7);
+ }
+ }
+}
+
+
+
+static
+void
+dk4socket_report_gai(
+ const dkChar *hostname,
+ const dkChar *lsvcname,
+ int res,
+ int local,
+ dk4_app_t *app,
+ dk4_er_t *erp
+)
+{
+ dkChar bdec[16*sizeof(dk4_um_t)];
+ dkChar bhex[16*sizeof(dk4_um_t)];
+ const dkChar *msgt[16];
+ const dkChar * const *msga;
+ const dkChar *fctname = NULL;
+ const dkChar *msgtext = NULL;
+#if VERSION_BEFORE_20150821
+ size_t szmsga;
+#endif
+ size_t used = 0;
+
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, DK4_LL_ERROR)) {
+#if VERSION_BEFORE_20150821
+ szmsga = dk4socket_log_num_texts();
+#endif
+ msga = dk4socket_log_texts(app);
+ dk4socket_log_fctname_msg(&fctname, &msgtext, app, erp);
+ msgt[used++] = msga[41];
+ if ((NULL != hostname) && (0 == local)) {
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[20];
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[21];
+ msgt[used++] = hostname;
+ if (NULL != lsvcname) {
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[22];
+ msgt[used++] = lsvcname;
+ }
+ } else {
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[18];
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[19];
+ msgt[used++] = lsvcname;
+ }
+ if (NULL != fctname) {
+ if (NULL != msgtext) {
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = fctname;
+ msgt[used++] = dk4socket_03_kwnl[1];
+ msgt[used++] = msgtext;
+ } else {
+ res = dk4ma_write_decimal_signed(
+ bdec,DK4_SIZEOF(bdec,dkChar),(dk4_im_t)(erp->dt.iDetails1),0,NULL
+ );
+ if (0 != res) {
+ res = dk4ma_write_hex_signed(
+ bhex,DK4_SIZEOF(bhex,dkChar),(dk4_im_t)(erp->dt.iDetails1),0,NULL
+ );
+ if (0 != res) {
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = fctname;
+ msgt[used++] = dk4socket_03_kwnl[1];
+#if DK4_ON_WINDOWS
+ msgt[used++] = msga[40];
+#else
+ msgt[used++] = msga[37];
+#endif
+ msgt[used++] = bdec;
+ msgt[used++] = msga[38];
+ msgt[used++] = bhex;
+ msgt[used++] = msga[39];
+ }
+ }
+ }
+ } else {
+ }
+ dk4app_log_msg(app, DK4_LL_ERROR, msgt, used);
+ }
+ }
+}
+
+#if DK4_CHAR_SIZE > 1
+
+/** Create a socket using remote and optionally local address lists.
+ @param hostname Remote host name.
+ @param rast List of remote addresses.
+ @param last List of local addresses, may be NULL.
+ @param secs Seconds for timeout.
+ @param usecs Microseconds for timeout.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Valid socket on success, INVALID_SOCKET on error.
+*/
+static
+dk4_socket_t
+dk4socket_tcp_client_addresses_app(
+ const dkChar *hostname,
+ ADDRINFOW *rast,
+ ADDRINFOW *last,
+ long secs,
+ long usecs,
+ dk4_app_t *app
+)
+{
+ dk4_er_t er;
+ ADDRINFOW *ra;
+ ADDRINFOW *la;
+ dk4_socket_t back = INVALID_SOCKET;
+ int mpf = 0;
+ $? "+ dk4socket_tcp_client_addresses_app %d %d", TR_IPTR(rast), TR_IPTR(last)
+ ra = rast;
+ while ((INVALID_SOCKET == back) && (NULL != ra)) {
+ if (NULL != last) {
+ la = last;
+ while ((INVALID_SOCKET == back) && (NULL != la)) {
+ if (ra->ai_family == la->ai_family) {
+ mpf = 1; $? ". families match, attempt to connect"
+ dk4error_init(&er);
+ back = dk4socket_tcp_client_for_addr(
+ ra->ai_family,
+ ra->ai_addr, ra->ai_addrlen,
+ la->ai_addr, la->ai_addrlen,
+ secs, usecs, &er
+ );
+ if (INVALID_SOCKET != back) {
+ dk4socket_report_connection_established(
+ app, hostname, ra->ai_family,
+ ra->ai_addr, ra->ai_addrlen,
+ la->ai_addr, la->ai_addrlen
+ );
+ ra = NULL; la = NULL;
+ } else { $? "! report failure"
+ /* ERROR: Failed */
+ dk4socket_report_connection_error(
+ app, hostname, ra->ai_family,
+ ra->ai_addr, ra->ai_addrlen,
+ la->ai_addr, la->ai_addrlen,
+ &er
+ );
+ }
+ }
+ if (NULL != la) { la = la->ai_next; }
+ }
+ } else {
+ mpf = 1;
+ dk4error_init(&er);
+ back = dk4socket_tcp_client_for_addr(
+ ra->ai_family, ra->ai_addr, ra->ai_addrlen, NULL, 0, secs, usecs, &er
+ );
+ if (INVALID_SOCKET != back) {
+ dk4socket_report_connection_established(
+ app, hostname, ra->ai_family,
+ ra->ai_addr, ra->ai_addrlen,
+ NULL, 0
+ );
+ ra = NULL;
+ } else { $? "! report failure"
+ /* ERROR: Failed */
+ dk4socket_report_connection_error(
+ app,hostname,ra->ai_family,ra->ai_addr,ra->ai_addrlen,NULL,0,&er
+ );
+ }
+ }
+ if (NULL != ra) { ra = ra->ai_next; }
+ }
+ if (INVALID_SOCKET == back) {
+ if (0 == mpf) { $? ". report no matching families"
+ /* ERROR: No matching address pair found (27) */
+ dk4socket_report_no_matching_addresses(hostname, app);
+ }
+ }
+ $? "- dk4socket_tcp_client_addresses_app %d", (int)back
+ return back;
+}
+
+#else
+
+/** Create a socket using remote and optionally local address lists.
+ @param hostname Remote host name.
+ @param rast List of remote addresses.
+ @param last List of local addresses, may be NULL.
+ @param secs Seconds for timeout.
+ @param usecs Microseconds for timeout.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Valid socket on success, INVALID_SOCKET on error.
+*/
+static
+dk4_socket_t
+dk4socket_tcp_client_addresses_app(
+ const dkChar *hostname,
+ struct addrinfo *rast,
+ struct addrinfo *last,
+ long secs,
+ long usecs,
+ dk4_app_t *app
+)
+{
+ dk4_er_t er;
+ struct addrinfo *ra;
+ struct addrinfo *la;
+ dk4_socket_t back = INVALID_SOCKET;
+ int mpf = 0;
+ $? "+ dk4socket_tcp_client_addresses_app %d %d", TR_IPTR(rast), TR_IPTR(last)
+ ra = rast;
+ while ((INVALID_SOCKET == back) && (NULL != ra)) {
+ if (NULL != last) {
+ la = last;
+ while ((INVALID_SOCKET == back) && (NULL != la)) {
+ if (ra->ai_family == la->ai_family) {
+ mpf = 1;
+ dk4error_init(&er);
+ back = dk4socket_tcp_client_for_addr(
+ ra->ai_family,
+ ra->ai_addr, ra->ai_addrlen,
+ la->ai_addr, la->ai_addrlen,
+ secs, usecs, &er
+ );
+ if (INVALID_SOCKET != back) {
+ dk4socket_report_connection_established(
+ app, hostname, ra->ai_family,
+ ra->ai_addr, ra->ai_addrlen,
+ la->ai_addr, la->ai_addrlen
+ );
+ ra = NULL; la = NULL;
+ } else { $? "! report failure"
+ /* ERROR: Failed */
+ dk4socket_report_connection_error(
+ app, hostname, ra->ai_family,
+ ra->ai_addr, ra->ai_addrlen,
+ la->ai_addr, la->ai_addrlen,
+ &er
+ );
+ }
+ }
+ if (NULL != la) { la = la->ai_next; }
+ }
+ } else {
+ mpf = 1;
+ dk4error_init(&er);
+ back = dk4socket_tcp_client_for_addr(
+ ra->ai_family, ra->ai_addr, ra->ai_addrlen, NULL, 0, secs, usecs, &er
+ );
+ if (INVALID_SOCKET != back) {
+ dk4socket_report_connection_established(
+ app, hostname, ra->ai_family,
+ ra->ai_addr, ra->ai_addrlen,
+ NULL, 0
+ );
+ ra = NULL;
+ } else { $? "! report failure"
+ /* ERROR: Failed */
+ dk4socket_report_connection_error(
+ app,hostname,ra->ai_family,ra->ai_addr,ra->ai_addrlen,NULL,0,&er
+ );
+ }
+ }
+ if (NULL != ra) { ra = ra->ai_next; }
+ }
+ if (INVALID_SOCKET == back) {
+ if (0 == mpf) {
+ /* ERROR: No matching address pair found (27) */
+ dk4socket_report_no_matching_addresses(hostname, app);
+ }
+ }
+ $? "- dk4socket_tcp_client_addresses_app %d", (int)back
+ return back;
+}
+
+#endif
+
+/* ----- +getaddrinfo ----- */
+#else
+/* +++++ -getaddrinfo +++++ */
+
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+/** used to initialize IPv6 address for binding local ports.
+*/
+static const IN6_ADDR dk4socket_any6 = IN6ADDR_ANY_INIT;
+#endif
+
+static
+void
+dk4socket_report_invalid_port_number(dk4_app_t *app, size_t i)
+{
+ const dkChar * msgt[16];
+ const dkChar * const *msga;
+ size_t szmsga;
+ size_t used = 0;
+
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, DK4_LL_ERROR)) {
+ szmsga = dk4socket_log_num_texts();
+ msga = dk4socket_log_texts(app);
+ msgt[used++] = msga[41];
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[i];
+ dk4app_log_msg(app, DK4_LL_ERROR, msgt, used);
+ }
+ }
+}
+
+
+static
+void
+dk4socket_report_service_not_found(dk4_app_t *app, const dkChar *svcname)
+{
+ const dkChar * msgt[16];
+ const dkChar * const *msga;
+ size_t szmsga;
+ size_t used = 0;
+
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, DK4_LL_ERROR)) {
+ szmsga = dk4socket_log_num_texts();
+ msga = dk4socket_log_texts(app);
+ msgt[used++] = msga[23];
+ msgt[used++] = svcname;
+ msgt[used++] = msga[24];
+ dk4app_log_msg(app, DK4_LL_ERROR, msgt, used);
+ }
+ }
+}
+
+
+
+#if DK4_CHAR_SIZE > 1
+
+static
+void
+dk4socket_report_service_not_ascii(dk4_app_t *app, const dkChar *svcname)
+{
+ const dkChar * msgt[16];
+ const dkChar * const *msga;
+ size_t szmsga;
+ size_t used = 0;
+
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, DK4_LL_ERROR)) {
+ szmsga = dk4socket_log_num_texts();
+ msga = dk4socket_log_texts(app);
+ msgt[used++] = msga[25];
+ msgt[used++] = svcname;
+ msgt[used++] = msga[26];
+ dk4app_log_msg(app, DK4_LL_ERROR, msgt, used);
+ }
+ }
+}
+
+#endif
+
+
+
+static
+void
+dk4socket_report_illegal_address_part(
+ dk4_app_t *app,
+ const dkChar *hostname,
+ size_t i
+)
+{
+ const dkChar * msgt[16];
+ const dkChar * const *msga;
+ size_t szmsga;
+ size_t used = 0;
+
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, DK4_LL_ERROR)) {
+ szmsga = dk4socket_log_num_texts();
+ msga = dk4socket_log_texts(app);
+ msgt[used++] = msga[i];
+ if (NULL != hostname) {
+ msgt[used++] = dk4socket_03_kwnl[0];
+ msgt[used++] = msga[43];
+ msgt[used++] = hostname;
+ }
+ dk4app_log_msg(app, DK4_LL_ERROR, msgt, used);
+ }
+ }
+}
+
+
+
+static
+void
+dk4socket_report_host_name_problem(
+ dk4_app_t *app,
+ const dkChar *hostname,
+ size_t i1,
+ size_t i2
+)
+{
+ const dkChar * msgt[16];
+ const dkChar * const *msga;
+ size_t szmsga;
+ size_t used = 0;
+
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, DK4_LL_ERROR)) {
+ szmsga = dk4socket_log_num_texts();
+ msga = dk4socket_log_texts(app);
+ if (NULL != hostname) {
+ msgt[used++] = msga[i1];
+ msgt[used++] = hostname;
+ msgt[used++] = msga[i2];
+ }
+ dk4app_log_msg(app, DK4_LL_ERROR, msgt, used);
+ }
+ }
+}
+
+/* ----- -getaddrinfo ----- */
+#endif
+
+
+
+/*
+ Exported functions
+ ------------------
+*/
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_ON_WINDOWS
+#if DK4_HAVE_GETADDRINFO
+/* +++++ wchar_t (Windows), +getaddrinfo +++++ */
+
+
+
+dk4_socket_t
+dk4socket_tcp_client_for_host_num_service_app(
+ const dkChar *hostname,
+ const dkChar *svcname,
+ const dkChar *lsvcname,
+ long secs,
+ long usecs,
+ int nsrv,
+ dk4_app_t *app
+)
+{
+ ADDRINFOW rhints;
+ ADDRINFOW lhints;
+ dk4_er_t er;
+ ADDRINFOW *rast = NULL;
+ ADDRINFOW *last = NULL;
+ dk4_socket_t back = INVALID_SOCKET;
+ int res;
+ $? "+ dk4socket_tcp_client_for_host_num_service_app (wchar_t +getaddrinfo)"
+ if ((NULL != hostname) && (NULL != svcname)) { $? ". args ok"
+ DK4_MEMRES(&rhints, sizeof(rhints));
+ rhints.ai_family = AF_UNSPEC;
+ rhints.ai_socktype = SOCK_STREAM;
+ if (0 != nsrv) { rhints.ai_flags = AI_NUMERICSERV; }
+ rhints.ai_protocol = 0;
+ dk4error_init(&er);
+ res = GetAddrInfoW(hostname, svcname, &rhints, &rast);
+ if ((0 == res) && (NULL != rast)) { $? ". getaddrinfo (remote)"
+ if (NULL != lsvcname) { $? ". local service name"
+ DK4_MEMRES(&lhints, sizeof(lhints));
+ lhints.ai_family = AF_UNSPEC;
+ lhints.ai_socktype = SOCK_STREAM;
+ lhints.ai_flags = AI_PASSIVE;
+ if (0 != nsrv) { lhints.ai_flags |= AI_NUMERICSERV; }
+ lhints.ai_protocol = 0;
+ dk4error_init(&er);
+ res = GetAddrInfoW(NULL, lsvcname, &lhints, &last);
+ if ((0 == res) && (NULL != last)) { $? ". getaddrinfo local"
+ back = dk4socket_tcp_client_addresses_app(
+ hostname, rast, last, secs, usecs, app
+ );
+ FreeAddrInfoW(last);
+ } else { $? "! getaddrinfo local"
+ /* ERROR: Failed to obtain local addresses to bind (18, 19) */
+ dk4error_set_idetails(&er, DK4_E_SOCKET_GETADDRINFO, res);
+ dk4socket_report_gai(NULL, lsvcname, res, 1, app, &er);
+ }
+ } else { $? ". no local service name"
+ back = dk4socket_tcp_client_addresses_app(
+ hostname, rast, NULL, secs, usecs, app
+ );
+ }
+ FreeAddrInfoW(rast);
+ } else { $? "! getaddrinfo (remote)"
+ /* ERROR: Failed to obtain remote addresses (20, 21, 22) */
+ dk4error_set_idetails(&er, DK4_E_SOCKET_GETADDRINFO, res);
+ dk4socket_report_gai(hostname, svcname, res, 0, app, &er);
+ }
+ } else { $? "! args"
+ /* ERROR: Invalid arguments (bug) */
+ dk4socket_report_invalid_arguments(app);
+ }
+ $? "- dk4socket_tcp_client_for_host_num_service_app (wchar_t) %d", (int)back
+ return back;
+}
+
+
+
+dk4_socket_t
+dk4socket_tcp_client_for_host_service_app(
+ const dkChar *hostname,
+ const dkChar *svcname,
+ const dkChar *lsvcname,
+ long secs,
+ long usecs,
+ dk4_app_t *app
+)
+{
+ return (
+ dk4socket_tcp_client_for_host_num_service_app(
+ hostname, svcname, lsvcname, secs, usecs, 0, app
+ )
+ );
+}
+
+
+
+dk4_socket_t
+dk4socket_tcp_client_for_host_port_app(
+ const dkChar *hostname,
+ unsigned short portno,
+ unsigned short lportno,
+ long secs,
+ long usecs,
+ dk4_app_t *app
+)
+{
+ dkChar rpnb[16*sizeof(dk4_um_t)];
+ dkChar lpnb[16*sizeof(dk4_um_t)];
+ dk4_er_t er;
+ dk4_socket_t back = INVALID_SOCKET;
+ int res;
+ $? "+ dk4socket_tcp_client_for_host_port_app (wchar_t)"
+ if ((NULL != hostname) && (0 < portno)) { $? ". args ok"
+ dk4error_init(&er);
+ res = dk4ma_write_decimal_unsigned(
+ rpnb, DK4_SIZEOF(rpnb,dkChar), (dk4_um_t)portno, 0, &er
+ );
+ if (0 != res) { $? ". num to text"
+ if (0 < lportno) { $? ". local port"
+ dk4error_init(&er);
+ res = dk4ma_write_decimal_unsigned(
+ lpnb, DK4_SIZEOF(lpnb,dkChar), (dk4_um_t)lportno, 0, &er
+ );
+ if (0 != res) { $? ". num to text"
+ back = dk4socket_tcp_client_for_host_num_service_app(
+ hostname, rpnb, lpnb, secs, usecs, 0, app
+ );
+ } else { $? "! bug"
+ /* ERROR: Failed to convert local port number to text, bug */
+ }
+ } else { $? ". no local port"
+ back = dk4socket_tcp_client_for_host_num_service_app(
+ hostname, rpnb, NULL, secs, usecs, 0, app
+ );
+ }
+ } else { $? "! num to text"
+ /* ERROR: Failed to convert port number to text, bug */
+ }
+ } else { $? "! args"
+ /* ERROR: Invalid arguments (bug) */
+ dk4socket_report_invalid_arguments(app);
+ }
+ $? "- dk4socket_tcp_client_for_host_port_app (wchar_t) %d", (int)back
+ return back;
+}
+
+
+
+/* ----- wchar_t (Windows), +getaddrinfo ----- */
+#else
+/* +++++ wchar_t (Windows), -getaddrinfo +++++ */
+
+
+
+dk4_socket_t
+dk4socket_tcp_client_for_host_num_service_app(
+ const dkChar *hostname,
+ const dkChar *svcname,
+ const dkChar *lsvcname,
+ long secs,
+ long usecs,
+ int nsrv,
+ dk4_app_t *app
+)
+{
+ char cppt[48];
+ char cplp[48];
+ dk4_er_t er;
+ struct servent *serv = NULL;
+ const dkChar *endptr = NULL;
+ dk4_socket_t back = INVALID_SOCKET;
+ int res = 0;
+ unsigned short rport = 0U;
+ unsigned short lport = 0U;
+ unsigned short iport = 0U;
+ $? "+ dk4socket_tcp_client_for_host_num_service_app (wchar_t)"
+ if ((NULL != hostname) && (NULL != svcname)) {
+ dk4error_init(&er);
+ res = dk4ma_input_dk_dec_ushort(&rport, svcname, &endptr, 1, NULL);
+ if (0 == res) {
+ if (0 != dk4recode_wchar_t_to_char(cppt, sizeof(cppt), svcname, &er)) {
+ dk4socket_error_reset();
+ serv = getservbyname(cppt, NULL);
+ if (NULL != serv) {
+ iport = serv->s_port;
+ dk4socket_swap_bytes_if_not_bigendian((void *)(&iport),sizeof(iport));
+ rport = (unsigned short)iport;
+ } else {
+ dk4socket_error_report(&er, DK4_E_SOCKET_GETSERVBYNAME);
+ /* ERROR: Service not found (23, 24) */
+ dk4socket_report_service_not_found(app, svcname);
+ }
+ } else {
+ /* ERROR: Failed to convert service name (25, 26) */
+ dk4socket_report_service_not_ascii(app, svcname);
+ }
+ }
+ if (0 < rport) {
+ if (NULL != lsvcname) {
+ endptr = NULL;
+ dk4error_init(&er);
+ res = dk4ma_input_dk_dec_ushort(&lport, lsvcname, &endptr, 1, NULL);
+ if (0 == res) {
+ dk4error_init(&er);
+ if (0 != dk4recode_wchar_t_to_char(cplp,sizeof(cplp),lsvcname,&er)) {
+ dk4socket_error_reset();
+ serv = getservbyname(cplp, NULL);
+ if (NULL != serv) {
+ iport = serv->s_port;
+ dk4socket_swap_bytes_if_not_bigendian(
+ (void *)(&iport), sizeof(iport)
+ );
+ lport = (unsigned short)iport;
+ } else {
+ dk4socket_error_report(&er, DK4_E_SOCKET_GETSERVBYNAME);
+ /* Service not found (23, 24) */
+ dk4socket_report_service_not_found(app, lsvcname);
+ }
+ } else {
+ /* ERROR: Text conversion failed (25, 26) */
+ dk4socket_report_service_not_ascii(app, lsvcname);
+ }
+ }
+ if (0 < lport) {
+ back = dk4socket_tcp_client_for_host_port_app(
+ hostname, rport, lport, secs, usecs, app
+ );
+ } else {
+ /* ERROR: Illegal local port number (28) */
+ dk4socket_report_invalid_port_number(app, 28);
+ }
+ } else {
+ back = dk4socket_tcp_client_for_host_port_app(
+ hostname, rport, 0, secs, usecs, app
+ );
+ }
+ } else {
+ /* ERROR: Illegal remote port number (29) */
+ dk4socket_report_invalid_port_number(app, 29);
+ }
+ } else {
+ /* ERROR: Invalid arguments (bug) */
+ dk4socket_report_invalid_arguments(app);
+ }
+ $? "- dk4socket_tcp_client_for_host_num_service_app (wchar_t) %d", (int)back
+ return back;
+}
+
+
+
+dk4_socket_t
+dk4socket_tcp_client_for_host_service_app(
+ const dkChar *hostname,
+ const dkChar *svcname,
+ const dkChar *lsvcname,
+ long secs,
+ long usecs,
+ dk4_app_t *app
+)
+{
+ return (
+ dk4socket_tcp_client_for_host_num_service_app(
+ hostname, svcname, lsvcname, secs, usecs, 0, app
+ )
+ );
+}
+
+
+
+dk4_socket_t
+dk4socket_tcp_client_for_host_port_app(
+ const dkChar *hostname,
+ unsigned short portno,
+ unsigned short lportno,
+ long secs,
+ long usecs,
+ dk4_app_t *app
+)
+{
+ char hona[1040];
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ struct sockaddr_in6 sr6;
+ struct sockaddr_in6 sl6;
+#endif
+ struct sockaddr_in sr4;
+ struct sockaddr_in sl4;
+ dk4_er_t er;
+ char **addrptr;
+ struct hostent *hep;
+ dk4_socket_t back = INVALID_SOCKET;
+
+ $? "+ dk4socket_tcp_client_for_host_port_app (wchar_t)"
+ if ((NULL != hostname) && (0 < portno)) {
+ dk4error_init(&er);
+ if (0 != dk4recode_wchar_t_to_char(hona, sizeof(hona), hostname, &er)) {
+ dk4socket_error_reset();
+ hep = gethostbyname(hona);
+ if (NULL != hep) {
+ if (NULL != hep->h_addr_list) {
+ switch (hep->h_addrtype) {
+ case AF_INET : {
+ if (4 == hep->h_length) {
+ addrptr = hep->h_addr_list;
+ while ((INVALID_SOCKET == back) && (NULL != *addrptr)) {
+ DK4_MEMRES(&sr4, sizeof(sr4));
+ sr4.sin_family = AF_INET;
+ sr4.sin_port = dk4socket_htons(portno);
+ DK4_MEMCPY(&(sr4.sin_addr), *addrptr, sizeof(IN_ADDR));
+ dk4error_init(&er);
+ if (0 != lportno) {
+ DK4_MEMRES(&sl4, sizeof(sl4));
+ sl4.sin_family = AF_INET;
+ sl4.sin_port = dk4socket_htons(lportno);
+ sl4.sin_addr.s_addr = dk4socket_htonl(INADDR_ANY);
+ back = dk4socket_tcp_client_for_addr(
+ AF_INET, (struct sockaddr *)(&sr4), sizeof(sr4),
+ (struct sockaddr *)(&sl4), sizeof(sl4), secs, usecs, &er
+ );
+ } else {
+ back = dk4socket_tcp_client_for_addr(
+ AF_INET, (struct sockaddr *)(&sr4), sizeof(sr4),
+ NULL, 0, secs, usecs, &er
+ );
+ }
+ if (INVALID_SOCKET == back) { $? "! report failure"
+ /* ERROR: Failed */
+ dk4socket_report_connection_error(
+ app, hostname, AF_INET,
+ (struct sockaddr *)(&sr4), sizeof(sr4),
+ ((0 < lportno) ? ((struct sockaddr *)(&sl4)) : NULL),
+ ((0 < lportno) ? (sizeof(sl4)) : 0),
+ &er
+ );
+ } else {
+ /* DEBUG: Connection established (30) */
+ dk4socket_report_connection_established(
+ app, hostname, AF_INET,
+ (struct sockaddr *)(&sr4), sizeof(sr4),
+ ((0 < lportno) ? ((struct sockaddr *)(&sl4)) : NULL),
+ ((0 < lportno) ? (sizeof(sl4)) : 0)
+ );
+ }
+ addrptr++;
+ }
+ } else {
+ /* ERROR: Illegal address length, bug (31) */
+ dk4socket_report_illegal_address_part(app, hostname, 31);
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ if (16 == hep->h_length) {
+ addrptr = hep->h_addr_list;
+ while ((INVALID_SOCKET == back) && (NULL != *addrptr)) {
+ DK4_MEMRES(&sr6, sizeof(sr6));
+ sr6.sin6_family = AF_INET6;
+ sr6.sin6_port = dk4socket_htons(portno);
+ DK4_MEMCPY(&(sr6.sin6_addr), *addrptr, sizeof(IN6_ADDR));
+ dk4error_init(&er);
+ if (0 < lportno) {
+ DK4_MEMRES(&sl6, sizeof(sl6));
+ sl6.sin6_family = AF_INET6;
+ sl6.sin6_port = dk4socket_htons(lportno);
+ DK4_MEMCPY(&(sl6.sin6_addr),&dk4socket_any6,sizeof(IN6_ADDR));
+ back = dk4socket_tcp_client_for_addr(
+ AF_INET6, (struct sockaddr *)(&sr6), sizeof(sr6),
+ (struct sockaddr *)(&sl6), sizeof(sl6), secs, usecs, &er
+ );
+ } else {
+ back = dk4socket_tcp_client_for_addr(
+ AF_INET6, (struct sockaddr *)(&sr6), sizeof(sr6),
+ NULL, 0, secs, usecs, &er
+ );
+ }
+ if (INVALID_SOCKET == back) { $? "! report failure"
+ /* ERROR: Failed */
+ dk4socket_report_connection_error(
+ app, hostname, AF_INET6,
+ (struct sockaddr *)(&sr6), sizeof(sr6),
+ ((0 < lportno) ? ((struct sockaddr *)(&sl6)) : NULL),
+ ((0 < lportno) ? (sizeof(sl6)) : 0),
+ &er
+ );
+ } else {
+ /* DEBUG: Connection established (30) */
+ dk4socket_report_connection_established(
+ app, hostname, AF_INET6,
+ (struct sockaddr *)(&sr6), sizeof(sr6),
+ ((0 < lportno) ? ((struct sockaddr *)(&sl6)) : NULL),
+ ((0 < lportno) ? (sizeof(sl6)) : 0)
+ );
+ }
+ addrptr++;
+ }
+ } else {
+ /* ERROR: Illegal address length, bug (31) */
+ dk4socket_report_illegal_address_part(app, hostname, 31);
+ }
+ } break;
+#endif
+ default : {
+ /* ERROR: Illegal address family (32) */
+ dk4socket_report_illegal_address_part(app, hostname, 32);
+ } break;
+ }
+ } else {
+ /* ERROR: Host not found (33, 34) */
+ dk4socket_report_host_name_problem(app, hostname, 33, 34);
+ }
+ } else {
+ dk4socket_error_report(&er, DK4_E_SOCKET_GETHOSTBYNAME);
+ /* ERROR: Host not found (33, 34) */
+ dk4socket_report_host_name_problem(app, hostname, 33, 34);
+ }
+ } else {
+ /* ERROR: Failed to convert host name to ASCII (35, 36) */
+ dk4socket_report_host_name_problem(app, hostname, 35, 36);
+ }
+ } else {
+ /* ERROR: Invalid arguments (bug) */
+ dk4socket_report_invalid_arguments(app);
+ }
+ $? "- dk4socket_tcp_client_for_host_port_app (wchar_t) %d", (int)back
+ return back;
+}
+
+
+
+/* ----- wchar_t (Windows), -getaddrinfo ----- */
+#endif
+#else
+#error No support for networking with wchar_t strings!
+#endif
+#else
+#if DK4_HAVE_GETADDRINFO
+/* +++++ char, +getaddrinfo +++++ */
+
+dk4_socket_t
+dk4socket_tcp_client_for_host_num_service_app(
+ const dkChar *hostname,
+ const dkChar *svcname,
+ const dkChar *lsvcname,
+ long secs,
+ long usecs,
+ int nsrv,
+ dk4_app_t *app
+)
+{
+ struct addrinfo rhints;
+ struct addrinfo lhints;
+ dk4_er_t er;
+ struct addrinfo *raddrst = NULL;
+ struct addrinfo *laddrst = NULL;
+ dk4_socket_t back = INVALID_SOCKET;
+ int res;
+ $? "+ dk4socket_tcp_client_for_host_num_service_app (char)"
+ $? ". svcname \"%!ds\"", TR_STR(svcname)
+ $? ". lsvcname \"%!ds\"", TR_STR(lsvcname)
+ if ((NULL != hostname) && (NULL != svcname)) { $? ". args ok"
+ DK4_MEMRES(&rhints, sizeof(rhints));
+ rhints.ai_family = AF_UNSPEC;
+ rhints.ai_socktype = SOCK_STREAM;
+ if (0 != nsrv) { rhints.ai_flags = AI_NUMERICSERV; }
+ rhints.ai_protocol = 0;
+ dk4error_init(&er);
+ res = getaddrinfo(hostname, svcname, &rhints, &raddrst);
+ if ((0 == res) && (NULL != raddrst)) { $? ". remote addr ok"
+ if (NULL != lsvcname) { $? ". need local addr"
+ DK4_MEMRES(&lhints, sizeof(lhints));
+ lhints.ai_family = AF_UNSPEC;
+ lhints.ai_socktype = SOCK_STREAM;
+ lhints.ai_flags = AI_PASSIVE;
+ if (0 != nsrv) { lhints.ai_flags |= AI_NUMERICSERV; }
+ lhints.ai_protocol = 0;
+ dk4error_init(&er);
+ res = getaddrinfo(NULL, lsvcname, &lhints, &laddrst);
+ if ((0 == res) && (NULL != laddrst)) { $? ". use local addr"
+ back = dk4socket_tcp_client_addresses_app(
+ hostname, raddrst, laddrst, secs, usecs, app
+ );
+ freeaddrinfo(laddrst);
+ } else { $? "! no local addr"
+ /* ERROR: Failed to obtain local addresses (18, 19) */
+ dk4error_set_idetails(&er, DK4_E_SOCKET_GETADDRINFO, res);
+ dk4socket_report_gai(NULL, lsvcname, res, 1, app, &er);
+ }
+ } else { $? ". no local addr"
+ back = dk4socket_tcp_client_addresses_app(
+ hostname, raddrst, NULL, secs, usecs, app
+ );
+ }
+ freeaddrinfo(raddrst);
+ } else { $? "! remote"
+ /* ERROR: Failed to obtain remote addresses (20, 21, 22) */
+ dk4error_set_idetails(&er, DK4_E_SOCKET_GETADDRINFO, res);
+ dk4socket_report_gai(hostname, svcname, res, 0, app, &er);
+ }
+ } else { $? "! args"
+ /* ERROR: Invalid arguments (bug) */
+ dk4socket_report_invalid_arguments(app);
+ }
+ $? "- dk4socket_tcp_client_for_host_num_service_app (char) %d", (int)back
+ return back;
+}
+
+
+
+dk4_socket_t
+dk4socket_tcp_client_for_host_service_app(
+ const dkChar *hostname,
+ const dkChar *svcname,
+ const dkChar *lsvcname,
+ long secs,
+ long usecs,
+ dk4_app_t *app
+)
+{
+ return (
+ dk4socket_tcp_client_for_host_num_service_app(
+ hostname, svcname, lsvcname, secs, usecs, 0, app
+ )
+ );
+}
+
+
+
+dk4_socket_t
+dk4socket_tcp_client_for_host_port_app(
+ const dkChar *hostname,
+ unsigned short portno,
+ unsigned short lportno,
+ long secs,
+ long usecs,
+ dk4_app_t *app
+)
+{
+ char rpn[16*sizeof(dk4_um_t)];
+ char lpn[16*sizeof(dk4_um_t)];
+ dk4_socket_t back = INVALID_SOCKET;
+ int res;
+ $? "+ dk4socket_tcp_client_for_host_port_app (char)"
+ if ((NULL != hostname) && (0 < portno)) {
+ res = dk4ma_write_c8_decimal_unsigned(
+ rpn, sizeof(rpn), (dk4_um_t)portno, 0, NULL
+ );
+ if (0 != res) {
+ if (0 < lportno) {
+ res = dk4ma_write_c8_decimal_unsigned(
+ lpn, sizeof(lpn), (dk4_um_t)lportno, 0, NULL
+ );
+ if (0 != res) {
+ back = dk4socket_tcp_client_for_host_num_service_app(
+ hostname, rpn, lpn, secs, usecs, 1, app
+ );
+ } else {
+ /* ERROR: Failed to convert port number to text, bug */
+ }
+ } else {
+ back = dk4socket_tcp_client_for_host_num_service_app(
+ hostname, rpn, NULL, secs, usecs, 1, app
+ );
+ }
+ } else {
+ /* ERROR: Failed to convert port number to text, bug */
+ }
+ } else {
+ /* ERROR: Invalid arguments (bug) */
+ dk4socket_report_invalid_arguments(app);
+ }
+ $? "- dk4socket_tcp_client_for_host_port_app (char) %d", (int)back
+ return back;
+}
+
+
+
+/* ----- char, +getaddrinfo ----- */
+#else
+/* +++++ char, -getaddrinfo ----- */
+
+
+
+dk4_socket_t
+dk4socket_tcp_client_for_host_num_service_app(
+ const dkChar *hostname,
+ const dkChar *svcname,
+ const dkChar *lsvcname,
+ long secs,
+ long usecs,
+ int nsrv,
+ dk4_app_t *app
+)
+{
+ const char *endptr = NULL;
+ struct servent *serv = NULL;
+ dk4_socket_t back = INVALID_SOCKET;
+ int res = 0;
+ int iport = 0;
+ unsigned short rport = 0;
+ unsigned short lport = 0;
+ $? "+ dk4socket_tcp_client_for_host_num_service_app (char)"
+ if ((NULL != hostname) && (NULL != svcname)) {
+ res = dk4ma_input_c8_dec_ushort(&rport, svcname, &endptr, 1, NULL);
+ if (0 == res) {
+ dk4socket_error_reset();
+ serv = getservbyname(svcname, NULL);
+ if (NULL != serv) {
+ iport = serv->s_port;
+ dk4socket_swap_bytes_if_not_bigendian((void *)(&iport), sizeof(iport));
+ rport = (unsigned short)iport;
+ } else {
+ /* ERROR: Service name for remote port not found (23, 24) */
+ dk4socket_report_service_not_found(app, svcname);
+ }
+ }
+ if (0 != rport) {
+ if (NULL != lsvcname) {
+ endptr = NULL;
+ res = dk4ma_input_c8_dec_ushort(&lport, lsvcname, &endptr, 1, NULL);
+ if (0 == res) {
+ dk4socket_error_reset();
+ serv = getservbyname(lsvcname, NULL);
+ if (NULL != serv) {
+ iport = serv->s_port;
+ dk4socket_swap_bytes_if_not_bigendian(
+ (void *)(&iport), sizeof(iport)
+ );
+ lport = (unsigned short)iport;
+ } else {
+ /* ERROR: Service name for local port not found (23, 24) */
+ dk4socket_report_service_not_found(app, lsvcname);
+ }
+ }
+ if (0 != lport) {
+ back = dk4socket_tcp_client_for_host_port_app(
+ hostname, rport, lport, secs, usecs, app
+ );
+ } else {
+ /* ERROR: Illegal local port number (28) */
+ dk4socket_report_invalid_port_number(app, 28);
+ }
+ } else {
+ back = dk4socket_tcp_client_for_host_port_app(
+ hostname, rport, 0, secs, usecs, app
+ );
+ }
+ } else {
+ /* ERROR: Illegal remote port number (29) */
+ dk4socket_report_invalid_port_number(app, 29);
+ }
+ } else {
+ /* ERROR: Invalid arguments (bug) */
+ dk4socket_report_invalid_arguments(app);
+ }
+ $? "- dk4socket_tcp_client_for_host_num_service_app (char) %d", (int)back
+ return back;
+}
+
+
+
+dk4_socket_t
+dk4socket_tcp_client_for_host_service_app(
+ const dkChar *hostname,
+ const dkChar *svcname,
+ const dkChar *lsvcname,
+ long secs,
+ long usecs,
+ dk4_app_t *app
+)
+{
+ return (
+ dk4socket_tcp_client_for_host_num_service_app(
+ hostname, svcname, lsvcname, secs, usecs, 0, app
+ )
+ );
+}
+
+
+
+dk4_socket_t
+dk4socket_tcp_client_for_host_port_app(
+ const dkChar *hostname,
+ unsigned short portno,
+ unsigned short lportno,
+ long secs,
+ long usecs,
+ dk4_app_t *app
+)
+{
+ dk4_er_t er;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ struct sockaddr_in6 sr6;
+ struct sockaddr_in6 sl6;
+#endif
+ struct sockaddr_in sr4;
+ struct sockaddr_in sl4;
+ char **addrptr;
+ struct hostent *hep = NULL;
+ dk4_socket_t back = INVALID_SOCKET;
+ $? "+ dk4socket_tcp_client_for_host_port_app (char)"
+ if ((NULL != hostname) && (0 < portno)) {
+ dk4error_init(&er);
+ dk4socket_error_reset();
+ hep = gethostbyname(hostname);
+ if (NULL != hep) {
+ if (NULL != hep->h_addr_list) {
+ switch (hep->h_addrtype) {
+ case AF_INET : {
+ if (4 == hep->h_length) {
+ addrptr = hep->h_addr_list;
+ while ((INVALID_SOCKET == back) && (NULL != *addrptr)) {
+ DK4_MEMRES(&sr4, sizeof(sr4));
+ sr4.sin_family = AF_INET;
+ sr4.sin_port = dk4socket_htons(portno);
+ DK4_MEMCPY(&(sr4.sin_addr), *addrptr, sizeof(IN_ADDR));
+ dk4error_init(&er);
+ if (0 != lportno) {
+ DK4_MEMRES(&sl4, sizeof(sl4));
+ sl4.sin_family = AF_INET;
+ sl4.sin_port = dk4socket_htons(lportno);
+ sl4.sin_addr.s_addr = dk4socket_htonl(INADDR_ANY);
+ back = dk4socket_tcp_client_for_addr(
+ AF_INET, (struct sockaddr *)(&sr4), sizeof(sr4),
+ (struct sockaddr *)(&sl4), sizeof(sl4), secs, usecs, &er
+ );
+ } else {
+ back = dk4socket_tcp_client_for_addr(
+ AF_INET, (struct sockaddr *)(&sr4), sizeof(sr4),
+ NULL, 0, secs, usecs, &er
+ );
+ }
+ if (INVALID_SOCKET == back) { $? "! report failure"
+ /* ERROR: Failed */
+ dk4socket_report_connection_error(
+ app, hostname, AF_INET,
+ (struct sockaddr *)(&sr4), sizeof(sr4),
+ ((0 < lportno) ? ((struct sockaddr *)(&sl4)) : NULL),
+ ((0 < lportno) ? (sizeof(sl4)) : 0),
+ &er
+ );
+ } else {
+ /* DEBUG: Connection established (30) */
+ dk4socket_report_connection_established(
+ app, hostname, AF_INET,
+ (struct sockaddr *)(&sr4), sizeof(sr4),
+ ((0 < lportno) ? ((struct sockaddr *)(&sl4)) : NULL),
+ ((0 < lportno) ? (sizeof(sl4)) : 0)
+ );
+ }
+ addrptr++;
+ }
+ } else {
+ /* ERROR: Illegal address length (31) */
+ dk4socket_report_illegal_address_part(app, hostname, 31);
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ if (16 == hep->h_length) {
+ addrptr = hep->h_addr_list;
+ while ((INVALID_SOCKET == back) && (NULL != *addrptr)) {
+ DK4_MEMRES(&sr6, sizeof(sr6));
+ sr6.sin6_family = AF_INET6;
+ sr6.sin6_port = dk4socket_htons(portno);
+ DK4_MEMCPY(&(sr6.sin6_addr), *addrptr, sizeof(IN6_ADDR));
+ dk4error_init(&er);
+ if (0 != lportno) {
+ DK4_MEMRES(&sl6, sizeof(sl6));
+ sl6.sin6_family = AF_INET6;
+ sl6.sin6_port = dk4socket_htons(lportno);
+ DK4_MEMCPY(&(sl6.sin6_addr),&dk4socket_any6,sizeof(IN6_ADDR));
+ back = dk4socket_tcp_client_for_addr(
+ AF_INET6, (struct sockaddr *)(&sr6), sizeof(sr6),
+ (struct sockaddr *)(&sl6), sizeof(sl6),
+ secs, usecs, &er
+ );
+ } else {
+ back = dk4socket_tcp_client_for_addr(
+ AF_INET6, (struct sockaddr *)(&sr6), sizeof(sr6),
+ NULL, 0, secs, usecs, &er
+ );
+ }
+ if (INVALID_SOCKET == back) { $? "! report failure"
+ /* ERROR: Failed */
+ dk4socket_report_connection_error(
+ app, hostname, AF_INET6,
+ (struct sockaddr *)(&sr6), sizeof(sr6),
+ ((0 < lportno) ? ((struct sockaddr *)(&sl6)) : NULL),
+ ((0 < lportno) ? (sizeof(sl6)) : 0),
+ &er
+ );
+ } else {
+ /* DEBUG: Connection established (30) */
+ dk4socket_report_connection_established(
+ app, hostname, AF_INET6,
+ (struct sockaddr *)(&sr6), sizeof(sr6),
+ ((0 < lportno) ? ((struct sockaddr *)(&sl6)) : NULL),
+ ((0 < lportno) ? (sizeof(sl6)) : 0)
+ );
+ }
+ addrptr++;
+ }
+ } else {
+ /* ERROR: Illegal address length (31) */
+ dk4socket_report_illegal_address_part(app, hostname, 31);
+ }
+ } break;
+#endif
+ default : {
+ /* ERROR: Illegal address family (32) */
+ dk4socket_report_illegal_address_part(app, hostname, 32);
+ } break;
+ }
+ } else {
+ /* ERROR: Remote host address not found! (33, 34) */
+ dk4socket_report_host_name_problem(app, hostname, 33, 34);
+ }
+ } else {
+ dk4socket_error_report(&er, DK4_E_SOCKET_GETHOSTBYNAME);
+ /* ERROR: Remote host address not found! (33, 34) */
+ dk4socket_report_host_name_problem(app, hostname, 33, 34);
+ }
+ } else {
+ /* ERROR: Invalid arguments (bug) */
+ dk4socket_report_invalid_arguments(app);
+ }
+ $? "- dk4socket_tcp_client_for_host_port_app (char) %d", (int)back
+ return back;
+}
+
+
+
+/* ----- char, -getaddrinfo ----- */
+#endif
+#endif
+
diff --git a/support/dktools/dk4socka08.c b/support/dktools/dk4socka08.c
new file mode 100644
index 0000000000..89a9125bb2
--- /dev/null
+++ b/support/dktools/dk4socka08.c
@@ -0,0 +1,146 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4socka08.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4socka08.c The dk4socka08 module.
+*/
+
+
+#line 9 "dk4socka08.ctr"
+
+#include "dk4socka.h"
+#include "dk4mem.h"
+#include "dk4maodd.h"
+
+
+
+
+
+#line 17 "dk4socka08.ctr"
+
+
+
+int
+dk4socket_send_attempt_app(
+ dk4_socket_t sock,
+ const void *buf,
+ size_t *pszbuf,
+ int flags,
+ long secs,
+ long usecs,
+ dk4_app_t *app,
+ int complain
+)
+{
+ dkChar nb1[16*sizeof(dk4_um_t)];
+ dkChar nb2[16*sizeof(dk4_um_t)];
+ dk4_er_t er;
+ size_t b0 = 0;
+ size_t b1 = 0;
+ const size_t sznb1 = DK4_SIZEOF(nb1,dkChar);
+ const size_t sznb2 = DK4_SIZEOF(nb2,dkChar);
+ int back = DK4_SOCKET_RESULT_FAILED;
+ int res = 0;
+ int abok = 0;
+ dk4error_init(&er);
+ if (NULL != pszbuf) { b0 = *pszbuf; }
+ back = dk4socket_send(sock, buf, pszbuf, flags, secs, usecs, &er);
+ if (DK4_SOCKET_RESULT_SUCCESS != back) {
+ switch (back) {
+ case DK4_SOCKET_RESULT_FAILED : {
+ dk4socket_log_simple_1(app, DK4_LL_ERROR, 137, &er);
+ } break;
+ case DK4_SOCKET_RESULT_IN_PROGRESS : {
+ if (0 != complain) {
+ if (NULL != pszbuf) { b1 = *pszbuf; }
+ res = dk4ma_write_decimal_unsigned(nb1,sznb1,(dk4_um_t)b1,0,NULL);
+ if (0 != res) {
+ res = dk4ma_write_decimal_unsigned(nb2,sznb2,(dk4_um_t)b0,0,NULL);
+ if (0 != res) {
+ abok = 1;
+ }
+ }
+ if (0 != abok) {
+ dk4socket_log_simple_5(app,DK4_LL_ERROR,133,134,135,nb1,nb2,&er);
+ } else {
+ dk4socket_log_simple_1(app, DK4_LL_ERROR, 136, &er);
+ }
+ }
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4socket_send_app(
+ dk4_socket_t sock,
+ const void *buf,
+ size_t *pszbuf,
+ int flags,
+ long secs,
+ long usecs,
+ dk4_app_t *app
+)
+{
+ return (
+ dk4socket_send_attempt_app(sock, buf, pszbuf, flags, secs, usecs, app, 0)
+ );
+}
+
+
+
+int
+dk4socket_recv_app(
+ dk4_socket_t sock,
+ void *buf,
+ size_t *pszbuf,
+ int flags,
+ long secs,
+ long usecs,
+ dk4_app_t *app
+)
+{
+ dk4_er_t er;
+ int back = DK4_SOCKET_RESULT_FAILED;
+ dk4error_init(&er);
+ back = dk4socket_recv(sock, buf, pszbuf, flags, secs, usecs, &er);
+ if (DK4_SOCKET_RESULT_SUCCESS != back) {
+ dk4socket_log_simple_1(app, DK4_LL_ERROR, 138, &er);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4socka08.ctr b/support/dktools/dk4socka08.ctr
new file mode 100644
index 0000000000..0c47f1fddc
--- /dev/null
+++ b/support/dktools/dk4socka08.ctr
@@ -0,0 +1,112 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% module
+
+#include "dk4socka.h"
+#include "dk4mem.h"
+#include "dk4maodd.h"
+
+
+
+$!trace-include
+
+
+
+int
+dk4socket_send_attempt_app(
+ dk4_socket_t sock,
+ const void *buf,
+ size_t *pszbuf,
+ int flags,
+ long secs,
+ long usecs,
+ dk4_app_t *app,
+ int complain
+)
+{
+ dkChar nb1[16*sizeof(dk4_um_t)];
+ dkChar nb2[16*sizeof(dk4_um_t)];
+ dk4_er_t er;
+ size_t b0 = 0;
+ size_t b1 = 0;
+ const size_t sznb1 = DK4_SIZEOF(nb1,dkChar);
+ const size_t sznb2 = DK4_SIZEOF(nb2,dkChar);
+ int back = DK4_SOCKET_RESULT_FAILED;
+ int res = 0;
+ int abok = 0;
+ dk4error_init(&er);
+ if (NULL != pszbuf) { b0 = *pszbuf; }
+ back = dk4socket_send(sock, buf, pszbuf, flags, secs, usecs, &er);
+ if (DK4_SOCKET_RESULT_SUCCESS != back) {
+ switch (back) {
+ case DK4_SOCKET_RESULT_FAILED : {
+ dk4socket_log_simple_1(app, DK4_LL_ERROR, 137, &er);
+ } break;
+ case DK4_SOCKET_RESULT_IN_PROGRESS : {
+ if (0 != complain) {
+ if (NULL != pszbuf) { b1 = *pszbuf; }
+ res = dk4ma_write_decimal_unsigned(nb1,sznb1,(dk4_um_t)b1,0,NULL);
+ if (0 != res) {
+ res = dk4ma_write_decimal_unsigned(nb2,sznb2,(dk4_um_t)b0,0,NULL);
+ if (0 != res) {
+ abok = 1;
+ }
+ }
+ if (0 != abok) {
+ dk4socket_log_simple_5(app,DK4_LL_ERROR,133,134,135,nb1,nb2,&er);
+ } else {
+ dk4socket_log_simple_1(app, DK4_LL_ERROR, 136, &er);
+ }
+ }
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4socket_send_app(
+ dk4_socket_t sock,
+ const void *buf,
+ size_t *pszbuf,
+ int flags,
+ long secs,
+ long usecs,
+ dk4_app_t *app
+)
+{
+ return (
+ dk4socket_send_attempt_app(sock, buf, pszbuf, flags, secs, usecs, app, 0)
+ );
+}
+
+
+
+int
+dk4socket_recv_app(
+ dk4_socket_t sock,
+ void *buf,
+ size_t *pszbuf,
+ int flags,
+ long secs,
+ long usecs,
+ dk4_app_t *app
+)
+{
+ dk4_er_t er;
+ int back = DK4_SOCKET_RESULT_FAILED;
+ dk4error_init(&er);
+ back = dk4socket_recv(sock, buf, pszbuf, flags, secs, usecs, &er);
+ if (DK4_SOCKET_RESULT_SUCCESS != back) {
+ dk4socket_log_simple_1(app, DK4_LL_ERROR, 138, &er);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4socka09.c b/support/dktools/dk4socka09.c
new file mode 100644
index 0000000000..096f6f2099
--- /dev/null
+++ b/support/dktools/dk4socka09.c
@@ -0,0 +1,152 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4socka09.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4socka09.c The dk4socka09 module.
+*/
+
+
+#line 10 "dk4socka09.ctr"
+
+#include "dk4sock.h"
+#include "dk4socka.h"
+#include "dk4error.h"
+#include "dk4mem.h"
+
+
+
+
+
+#line 19 "dk4socka09.ctr"
+
+
+
+dk4_socket_set_t *
+dk4socket_set_service_app(
+ const dkChar *servicename,
+ int backlog,
+ int local,
+ dk4_app_t *app
+)
+{
+ dkChar habuf[128];
+ dk4_sockaddr_storage_t sname;
+ dk4_er_t er;
+ const dkChar *msgt[8];
+ const dkChar * const *ltx = NULL;
+ dk4_socket_set_t *back = NULL;
+ struct sockaddr *so = NULL;
+#if VERSION_BEFORE_20150821
+ struct sockaddr_in *in4 = NULL;
+#endif
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+#if VERSION_BEFORE_20150821
+ struct sockaddr_in6 *in6 = NULL;
+#endif
+#endif
+ size_t i = 0; /* Traverse socket set */
+#if DK4_HAVE_SOCKLEN_T
+ socklen_t slgt = 0;
+#else
+ int slgt = 0;
+#endif
+ int res = 0; /* Operation result */
+ int hat = 0; /* Have address text */
+
+ if ((NULL != servicename) && (0 < backlog)) {
+ dk4error_init(&er);
+ back = dk4socket_set_service(servicename, backlog, local, &er);
+ if (NULL != back) {
+ if (0 != dk4app_log_do(app, DK4_LL_PROGRESS)) {
+ ltx = dk4socket_log_texts(app);
+ if (NULL != ltx) {
+ for (i = 0; i < back->szUsed; i++) {
+ hat = 0;
+#if DK4_HAVE_SOCKLEN_T
+ slgt = (socklen_t)sizeof(sname);
+#else
+ slgt = (int)sizeof(sname);
+#endif
+ so = (struct sockaddr *)(&sname);
+ res = getsockname((back->pSockets)[i], so, &slgt);
+ if (0 == res) {
+ switch (so->sa_family) {
+ case AF_INET : {
+ if (sizeof(struct sockaddr_in) == slgt) {
+#if VERSION_BEFORE_20150821
+ in4 = (struct sockaddr_in *)so;
+#endif
+ res = dk4socket_addr_port_to_text(
+ habuf, DK4_SIZEOF(habuf,dkChar), AF_INET,
+ so, sizeof(struct sockaddr_in), NULL
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ hat = 1;
+ }
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ if (sizeof(struct sockaddr_in6) == slgt) {
+#if VERSION_BEFORE_20150821
+ in6 = (struct sockaddr_in6 *)so;
+#endif
+ res = dk4socket_addr_port_to_text(
+ habuf, DK4_SIZEOF(habuf,dkChar), AF_INET6,
+ so, sizeof(struct sockaddr_in6), NULL
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ hat = 1;
+ }
+ }
+ } break;
+#endif
+ }
+ if (0 != hat) {
+ msgt[0] = ltx[140];
+ msgt[1] = habuf;
+ msgt[2] = NULL;
+ dk4app_log_msg(app, DK4_LL_PROGRESS, msgt, 2);
+ }
+ }
+ }
+ }
+ }
+ } else {
+ dk4socket_log_simple_1(app, DK4_LL_ERROR, 139, &er);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4socka09.ctr b/support/dktools/dk4socka09.ctr
new file mode 100644
index 0000000000..7b3c55b740
--- /dev/null
+++ b/support/dktools/dk4socka09.ctr
@@ -0,0 +1,119 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4sock.h"
+#include "dk4socka.h"
+#include "dk4error.h"
+#include "dk4mem.h"
+
+
+
+$!trace-include
+
+
+
+dk4_socket_set_t *
+dk4socket_set_service_app(
+ const dkChar *servicename,
+ int backlog,
+ int local,
+ dk4_app_t *app
+)
+{
+ dkChar habuf[128];
+ dk4_sockaddr_storage_t sname;
+ dk4_er_t er;
+ const dkChar *msgt[8];
+ const dkChar * const *ltx = NULL;
+ dk4_socket_set_t *back = NULL;
+ struct sockaddr *so = NULL;
+#if VERSION_BEFORE_20150821
+ struct sockaddr_in *in4 = NULL;
+#endif
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+#if VERSION_BEFORE_20150821
+ struct sockaddr_in6 *in6 = NULL;
+#endif
+#endif
+ size_t i = 0; /* Traverse socket set */
+#if DK4_HAVE_SOCKLEN_T
+ socklen_t slgt = 0;
+#else
+ int slgt = 0;
+#endif
+ int res = 0; /* Operation result */
+ int hat = 0; /* Have address text */
+
+ if ((NULL != servicename) && (0 < backlog)) {
+ dk4error_init(&er);
+ back = dk4socket_set_service(servicename, backlog, local, &er);
+ if (NULL != back) {
+ if (0 != dk4app_log_do(app, DK4_LL_PROGRESS)) {
+ ltx = dk4socket_log_texts(app);
+ if (NULL != ltx) {
+ for (i = 0; i < back->szUsed; i++) {
+ hat = 0;
+#if DK4_HAVE_SOCKLEN_T
+ slgt = (socklen_t)sizeof(sname);
+#else
+ slgt = (int)sizeof(sname);
+#endif
+ so = (struct sockaddr *)(&sname);
+ res = getsockname((back->pSockets)[i], so, &slgt);
+ if (0 == res) {
+ switch (so->sa_family) {
+ case AF_INET : {
+ if (sizeof(struct sockaddr_in) == slgt) {
+#if VERSION_BEFORE_20150821
+ in4 = (struct sockaddr_in *)so;
+#endif
+ res = dk4socket_addr_port_to_text(
+ habuf, DK4_SIZEOF(habuf,dkChar), AF_INET,
+ so, sizeof(struct sockaddr_in), NULL
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ hat = 1;
+ }
+ }
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ if (sizeof(struct sockaddr_in6) == slgt) {
+#if VERSION_BEFORE_20150821
+ in6 = (struct sockaddr_in6 *)so;
+#endif
+ res = dk4socket_addr_port_to_text(
+ habuf, DK4_SIZEOF(habuf,dkChar), AF_INET6,
+ so, sizeof(struct sockaddr_in6), NULL
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ hat = 1;
+ }
+ }
+ } break;
+#endif
+ }
+ if (0 != hat) {
+ msgt[0] = ltx[140];
+ msgt[1] = habuf;
+ msgt[2] = NULL;
+ dk4app_log_msg(app, DK4_LL_PROGRESS, msgt, 2);
+ }
+ }
+ }
+ }
+ }
+ } else {
+ dk4socket_log_simple_1(app, DK4_LL_ERROR, 139, &er);
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4stat.c b/support/dktools/dk4stat.c
new file mode 100644
index 0000000000..18764478c4
--- /dev/null
+++ b/support/dktools/dk4stat.c
@@ -0,0 +1,138 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4stat.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4stat.c The dk4stat module.
+*/
+
+
+#line 78 "dk4stat.ctr"
+
+#include "dk4stat.h"
+#if DK4_CHAR_SIZE > 1
+#include "dk4statw.h"
+#else
+#include "dk4stat8.h"
+#endif
+
+
+
+#line 87 "dk4stat.ctr"
+
+
+
+int
+dk4stat_is_regular(const dk4_stat_t *stb, dk4_er_t *erp)
+{
+ int back = 0;
+ if (NULL != stb) {
+#if DK4_ON_WINDOWS
+ if (((stb->st_mode) & _S_IFMT) == _S_IFREG) {
+ back = 1;
+ }
+#else
+ if (((stb->st_mode) & S_IFMT) == S_IFREG) {
+ back = 1;
+ }
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4stat_is_directory(const dk4_stat_t *stb, dk4_er_t *erp)
+{
+ int back = 0;
+ if (NULL != stb) {
+#if DK4_ON_WINDOWS
+ if (((stb->st_mode) & _S_IFMT) == _S_IFDIR) {
+ back = 1;
+ }
+#else
+ if (((stb->st_mode) & S_IFMT) == S_IFDIR) {
+ back = 1;
+ }
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+int
+dk4stat_is_symlink(const dk4_stat_t *stb, dk4_er_t *erp)
+{
+ int back = 0;
+ if (NULL != stb) {
+#if DK4_ON_WINDOWS
+
+#else
+#if defined(S_IFMT) && defined(S_IFLNK)
+ if (S_IFLNK == ((stb->st_mode) & S_IFMT)) {
+ back = 1;
+ }
+#endif
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4stat_is_unix_domain_socket(const dk4_stat_t *stb, dk4_er_t *erp)
+{
+ int back = 0;
+ if (NULL != stb) {
+#if DK4_ON_WINDOWS
+
+#else
+#if defined(S_IFMT) && defined(S_IFSOCK)
+ if (S_IFSOCK == ((stb->st_mode) & S_IFMT)) {
+ back = 1;
+ }
+#endif
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
diff --git a/support/dktools/dk4stat.ctr b/support/dktools/dk4stat.ctr
new file mode 100644
index 0000000000..f7b3fce431
--- /dev/null
+++ b/support/dktools/dk4stat.ctr
@@ -0,0 +1,173 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+%% header
+
+/** @file
+ File statistics (retrieve information from
+ stat() and lstat() results).
+
+ Note: The stat() and lstat() functions are sufficient for
+ non-Windows systems.
+ On Windows systems the st_dev and st_ino components may contain
+ dummy contents, the stat structure does not contain information
+ about symbolic links.
+
+ For a portable (both Windows and non-Windows) check whether a file
+ is a symbolic link, reparse point... use the dk4_file_info_t
+ data type from dk4fileit.h and the functions from dk4filei.h.
+
+ CRT on Windows: Required.
+*/
+
+#include "dk4statt.h"
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Check whether the file information is about a regular file.
+ @param stb Stat buffer filled previously.
+ @param erp Error report, may be NULL.
+ @return 1 for regular file, 0 otherwise.
+
+*/
+int
+dk4stat_is_regular(const dk4_stat_t *stb, dk4_er_t *erp);
+
+/** Check whether the file information is about a directory.
+ @param stb Stat buffer filled previously.
+ @param erp Error report, may be NULL.
+ @return 1 for regular file, 0 otherwise.
+
+*/
+int
+dk4stat_is_directory(const dk4_stat_t *stb, dk4_er_t *erp);
+
+/** Check whether the file information is about a symbolic link.
+ @param stb Stat buffer filled previously.
+ @param erp Error report, may be NULL.
+ @return 1 for regular file, 0 otherwise.
+
+*/
+int
+dk4stat_is_symlink(const dk4_stat_t *stb, dk4_er_t *erp);
+
+/** Check whether the file information is about UNIX domain socket.
+ @param stb Stat buffer filled previously.
+ @param erp Error report, may be NULL.
+ @return 1 for regular file, 0 otherwise.
+
+*/
+int
+dk4stat_is_unix_domain_socket(const dk4_stat_t *stb, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4stat.h"
+#if DK4_CHAR_SIZE > 1
+#include "dk4statw.h"
+#else
+#include "dk4stat8.h"
+#endif
+
+$!trace-include
+
+
+
+int
+dk4stat_is_regular(const dk4_stat_t *stb, dk4_er_t *erp)
+{
+ int back = 0;
+ if (NULL != stb) {
+#if DK4_ON_WINDOWS
+ if (((stb->st_mode) & _S_IFMT) == _S_IFREG) {
+ back = 1;
+ }
+#else
+ if (((stb->st_mode) & S_IFMT) == S_IFREG) {
+ back = 1;
+ }
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4stat_is_directory(const dk4_stat_t *stb, dk4_er_t *erp)
+{
+ int back = 0;
+ if (NULL != stb) {
+#if DK4_ON_WINDOWS
+ if (((stb->st_mode) & _S_IFMT) == _S_IFDIR) {
+ back = 1;
+ }
+#else
+ if (((stb->st_mode) & S_IFMT) == S_IFDIR) {
+ back = 1;
+ }
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+int
+dk4stat_is_symlink(const dk4_stat_t *stb, dk4_er_t *erp)
+{
+ int back = 0;
+ if (NULL != stb) {
+#if DK4_ON_WINDOWS
+
+#else
+#if defined(S_IFMT) && defined(S_IFLNK)
+ if (S_IFLNK == ((stb->st_mode) & S_IFMT)) {
+ back = 1;
+ }
+#endif
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4stat_is_unix_domain_socket(const dk4_stat_t *stb, dk4_er_t *erp)
+{
+ int back = 0;
+ if (NULL != stb) {
+#if DK4_ON_WINDOWS
+
+#else
+#if defined(S_IFMT) && defined(S_IFSOCK)
+ if (S_IFSOCK == ((stb->st_mode) & S_IFMT)) {
+ back = 1;
+ }
+#endif
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
diff --git a/support/dktools/dk4stat.h b/support/dktools/dk4stat.h
new file mode 100644
index 0000000000..6b1b72f9ec
--- /dev/null
+++ b/support/dktools/dk4stat.h
@@ -0,0 +1,112 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4stat.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4STAT_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4STAT_H_INCLUDED 1
+
+
+#line 8 "dk4stat.ctr"
+
+/** @file
+ File statistics (retrieve information from
+ stat() and lstat() results).
+
+ Note: The stat() and lstat() functions are sufficient for
+ non-Windows systems.
+ On Windows systems the st_dev and st_ino components may contain
+ dummy contents, the stat structure does not contain information
+ about symbolic links.
+
+ For a portable (both Windows and non-Windows) check whether a file
+ is a symbolic link, reparse point... use the dk4_file_info_t
+ data type from dk4fileit.h and the functions from dk4filei.h.
+
+ CRT on Windows: Required.
+*/
+
+#include "dk4statt.h"
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Check whether the file information is about a regular file.
+ @param stb Stat buffer filled previously.
+ @param erp Error report, may be NULL.
+ @return 1 for regular file, 0 otherwise.
+
+*/
+int
+dk4stat_is_regular(const dk4_stat_t *stb, dk4_er_t *erp);
+
+/** Check whether the file information is about a directory.
+ @param stb Stat buffer filled previously.
+ @param erp Error report, may be NULL.
+ @return 1 for regular file, 0 otherwise.
+
+*/
+int
+dk4stat_is_directory(const dk4_stat_t *stb, dk4_er_t *erp);
+
+/** Check whether the file information is about a symbolic link.
+ @param stb Stat buffer filled previously.
+ @param erp Error report, may be NULL.
+ @return 1 for regular file, 0 otherwise.
+
+*/
+int
+dk4stat_is_symlink(const dk4_stat_t *stb, dk4_er_t *erp);
+
+/** Check whether the file information is about UNIX domain socket.
+ @param stb Stat buffer filled previously.
+ @param erp Error report, may be NULL.
+ @return 1 for regular file, 0 otherwise.
+
+*/
+int
+dk4stat_is_unix_domain_socket(const dk4_stat_t *stb, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4stat8.c b/support/dktools/dk4stat8.c
new file mode 100644
index 0000000000..44f56881fe
--- /dev/null
+++ b/support/dktools/dk4stat8.c
@@ -0,0 +1,140 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4stat8.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4stat8.c The dk4stat8 module.
+*/
+
+
+#line 77 "dk4stat8.ctr"
+
+#include "dk4stat8.h"
+#include "dk4mem.h"
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+
+
+#line 103 "dk4stat8.ctr"
+
+
+
+int
+dk4stat_c8(dk4_stat_t *dst, const char *path, dk4_er_t *erp)
+{
+ int back = 0;
+ if ((NULL != dst) && (NULL != path)) {
+ errno = 0;
+#if DK4_ON_WINDOWS
+ if (0 == _stat64(path, dst))
+#else
+#if DK4_HAVE_LARGEFILE64_SOURCE && DK4_HAVE_STAT64
+ if (0 == stat64(path, dst))
+#else
+ if (0 == stat(path, dst))
+#endif
+#endif
+ {
+ back = 1;
+ }
+ else
+ {
+ dk4error_set_idetails(erp, DK4_E_SYSTEM, errno);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4stat_l_c8(dk4_stat_t *dst, const char *path, dk4_er_t *erp)
+{
+ int back = 0;
+ if ((NULL != dst) && (NULL != path)) {
+#if DK4_ON_WINDOWS
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#else
+#if DK4_HAVE_LARGEFILE64_SOURCE && DK4_HAVE_STAT64
+#if DK4_HAVE_LSTAT64
+ errno = 0;
+ if (0 == lstat64(path, dst)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_SYSTEM, errno);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+#else
+#if DK4_HAVE_LSTAT
+ errno = 0;
+ if (0 == lstat(path, dst)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_SYSTEM, errno);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+#endif
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4stat8.ctr b/support/dktools/dk4stat8.ctr
new file mode 100644
index 0000000000..23ceb0da3b
--- /dev/null
+++ b/support/dktools/dk4stat8.ctr
@@ -0,0 +1,174 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ File statistics (using stat() and
+ lstat() functions, 8 bit characters).
+
+ Note: The stat() and lstat() functions are sufficient for
+ non-Windows systems.
+ On Windows systems the st_dev and st_ino components may contain
+ dummy contents, the stat structure does not contain information
+ about symbolic links.
+
+ For a portable (both Windows and non-Windows) check whether a file
+ is a symbolic link, reparse point... use the dk4_file_info_t
+ data type from dk4fileit.h and the functions from dk4filei.h.
+
+ CRT on Windows: Required.
+*/
+
+#include "dk4statt.h"
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve information about a file using stat/stat64/_stat64.
+ @param dst Structure to fill with information.
+ @param path File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dst or path is NULL,
+ - DK4_E_SYSTEM<br>
+ with errno value stored in iDetails1 if the stat() function fails.
+*/
+int
+dk4stat_c8(dk4_stat_t *dst, const char *path, dk4_er_t *erp);
+
+/** Retrieve information about a file using lstat/lstat64.
+ @param dst Structure to fill with information.
+ @param path File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ if there is no support for lstat(),
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dst or path is NULL,
+ - DK4_E_SYSTEM<br>
+ with errno value stored in iDetails1 if lstat() fails.
+*/
+int
+dk4stat_l_c8(dk4_stat_t *dst, const char *path, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4stat8.h"
+#include "dk4mem.h"
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+$!trace-include
+
+
+
+int
+dk4stat_c8(dk4_stat_t *dst, const char *path, dk4_er_t *erp)
+{
+ int back = 0;
+ if ((NULL != dst) && (NULL != path)) {
+ errno = 0;
+#if DK4_ON_WINDOWS
+ if (0 == _stat64(path, dst))
+#else
+#if DK4_HAVE_LARGEFILE64_SOURCE && DK4_HAVE_STAT64
+ if (0 == stat64(path, dst))
+#else
+ if (0 == stat(path, dst))
+#endif
+#endif
+ {
+ back = 1;
+ }
+ else
+ {
+ dk4error_set_idetails(erp, DK4_E_SYSTEM, errno);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4stat_l_c8(dk4_stat_t *dst, const char *path, dk4_er_t *erp)
+{
+ int back = 0;
+ if ((NULL != dst) && (NULL != path)) {
+#if DK4_ON_WINDOWS
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#else
+#if DK4_HAVE_LARGEFILE64_SOURCE && DK4_HAVE_STAT64
+#if DK4_HAVE_LSTAT64
+ errno = 0;
+ if (0 == lstat64(path, dst)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_SYSTEM, errno);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+#else
+#if DK4_HAVE_LSTAT
+ errno = 0;
+ if (0 == lstat(path, dst)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_SYSTEM, errno);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+#endif
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4stat8.h b/support/dktools/dk4stat8.h
new file mode 100644
index 0000000000..74eeff76ef
--- /dev/null
+++ b/support/dktools/dk4stat8.h
@@ -0,0 +1,109 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4stat8.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4STAT8_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4STAT8_H_INCLUDED 1
+
+
+#line 10 "dk4stat8.ctr"
+
+/** @file
+ File statistics (using stat() and
+ lstat() functions, 8 bit characters).
+
+ Note: The stat() and lstat() functions are sufficient for
+ non-Windows systems.
+ On Windows systems the st_dev and st_ino components may contain
+ dummy contents, the stat structure does not contain information
+ about symbolic links.
+
+ For a portable (both Windows and non-Windows) check whether a file
+ is a symbolic link, reparse point... use the dk4_file_info_t
+ data type from dk4fileit.h and the functions from dk4filei.h.
+
+ CRT on Windows: Required.
+*/
+
+#include "dk4statt.h"
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve information about a file using stat/stat64/_stat64.
+ @param dst Structure to fill with information.
+ @param path File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dst or path is NULL,
+ - DK4_E_SYSTEM<br>
+ with errno value stored in iDetails1 if the stat() function fails.
+*/
+int
+dk4stat_c8(dk4_stat_t *dst, const char *path, dk4_er_t *erp);
+
+/** Retrieve information about a file using lstat/lstat64.
+ @param dst Structure to fill with information.
+ @param path File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ if there is no support for lstat(),
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dst or path is NULL,
+ - DK4_E_SYSTEM<br>
+ with errno value stored in iDetails1 if lstat() fails.
+*/
+int
+dk4stat_l_c8(dk4_stat_t *dst, const char *path, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4statd.c b/support/dktools/dk4statd.c
new file mode 100644
index 0000000000..2efefb4fbe
--- /dev/null
+++ b/support/dktools/dk4statd.c
@@ -0,0 +1,69 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4statd.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4statd.c The dk4statd module.
+*/
+
+
+#line 70 "dk4statd.ctr"
+
+#include "dk4statd.h"
+#include "dk4stat8.h"
+#include "dk4statw.h"
+
+
+
+int
+dk4stat(dk4_stat_t *dst, const dkChar *path, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4stat_wc(dst, path, erp));
+#else
+ return (dk4stat_c8(dst, path, erp));
+#endif
+}
+
+
+
+int
+dk4stat_l(dk4_stat_t *dst, const dkChar *path, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4stat_l_wc(dst, path, erp));
+#else
+ return (dk4stat_l_c8(dst, path, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4statd.ctr b/support/dktools/dk4statd.ctr
new file mode 100644
index 0000000000..bf275bcce5
--- /dev/null
+++ b/support/dktools/dk4statd.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ File statistics (using stat() and
+ lstat() functions, dkChar).
+
+ For a portable (both Windows and non-Windows) check whether a file
+ is a symbolic link, reparse point... use the dk4_file_info_t
+ data type from dk4fileit.h and the functions from dk4filei.h.
+
+ CRT on Windows: Required.
+*/
+
+#include "dk4statt.h"
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve information about a file using stat/stat64/_stat64.
+ @param dst Structure to fill with information.
+ @param path File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dst or path is NULL,
+ - DK4_E_SYSTEM<br>
+ with errno value stored in iDetails1 if the stat() function fails.
+*/
+int
+dk4stat(dk4_stat_t *dst, const dkChar *path, dk4_er_t *erp);
+
+/** Retrieve information about a file using lstat/lstat64.
+ @param dst Structure to fill with information.
+ @param path File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ if there is no support for lstat(),
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dst or path is NULL,
+ - DK4_E_SYSTEM<br>
+ with errno value stored in iDetails1 if lstat() fails.
+*/
+int
+dk4stat_l(dk4_stat_t *dst, const dkChar *path, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4statd.h"
+#include "dk4stat8.h"
+#include "dk4statw.h"
+
+
+
+int
+dk4stat(dk4_stat_t *dst, const dkChar *path, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4stat_wc(dst, path, erp));
+#else
+ return (dk4stat_c8(dst, path, erp));
+#endif
+}
+
+
+
+int
+dk4stat_l(dk4_stat_t *dst, const dkChar *path, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4stat_l_wc(dst, path, erp));
+#else
+ return (dk4stat_l_c8(dst, path, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4statd.h b/support/dktools/dk4statd.h
new file mode 100644
index 0000000000..2c04dac673
--- /dev/null
+++ b/support/dktools/dk4statd.h
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4statd.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4STATD_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4STATD_H_INCLUDED 1
+
+
+#line 10 "dk4statd.ctr"
+
+/** @file
+ File statistics (using stat() and
+ lstat() functions, dkChar).
+
+ For a portable (both Windows and non-Windows) check whether a file
+ is a symbolic link, reparse point... use the dk4_file_info_t
+ data type from dk4fileit.h and the functions from dk4filei.h.
+
+ CRT on Windows: Required.
+*/
+
+#include "dk4statt.h"
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve information about a file using stat/stat64/_stat64.
+ @param dst Structure to fill with information.
+ @param path File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dst or path is NULL,
+ - DK4_E_SYSTEM<br>
+ with errno value stored in iDetails1 if the stat() function fails.
+*/
+int
+dk4stat(dk4_stat_t *dst, const dkChar *path, dk4_er_t *erp);
+
+/** Retrieve information about a file using lstat/lstat64.
+ @param dst Structure to fill with information.
+ @param path File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ if there is no support for lstat(),
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dst or path is NULL,
+ - DK4_E_SYSTEM<br>
+ with errno value stored in iDetails1 if lstat() fails.
+*/
+int
+dk4stat_l(dk4_stat_t *dst, const dkChar *path, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4statt.h b/support/dktools/dk4statt.h
new file mode 100644
index 0000000000..cd85489082
--- /dev/null
+++ b/support/dktools/dk4statt.h
@@ -0,0 +1,288 @@
+#ifndef DK4STATT_H_INCLUDED
+#define DK4STATT_H_INCLUDED 1
+
+/** @file dk4statt.h Default type definitions for dev_t and ino_t.
+
+ Note: The stat() and lstat() functions are sufficient for
+ non-Windows systems.
+ On Windows systems the st_dev and st_ino components may contain
+ dummy contents, the stat structure does not contain information
+ about symbolic links.
+
+ For a portable (both Windows and non-Windows) check whether a file
+ is a symbolic link, reparse point... use the dk4_file_info_t
+ data type from dk4fileit.h.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_STAT_H
+#ifndef SYS_STAT_H_INCLUDED
+#include <sys/stat.h>
+#define SYS_STAT_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_DEV_T
+/** Device number.
+*/
+typedef dev_t dk4_dev_t;
+#else
+#if DK4_HAVE__DEV_T
+/** Device number.
+*/
+typedef _dev_t dk4_dev_t;
+#else
+/** Device number.
+*/
+typdef dk4_um_t dk4_dev_t;
+#endif
+#endif
+
+#if DK4_ON_WINDOWS
+/* +++ Windows +++ */
+#if DK4_HAVE_INO_T
+/** Inode number.
+*/
+typedef ino_t dk4_ino_t;
+#else
+#if DK4_HAVE__INO_T
+/** Inode number.
+*/
+typedef _ino_t dk4_ino_t;
+#else
+/** Inode number.
+*/
+typedef dk4_um_t dk4_ino_t;
+#endif
+#endif
+/* --- Windows --- */
+#else
+#if DK4_HAVE_LARGEFILE64_SOURCE && DK4_HAVE_STAT64
+/* +++ Unix, stat64 +++ */
+#if DK4_HAVE_INO64_T
+/** Inode number.
+*/
+typedef ino64_t dk4_ino_t;
+#else
+#if DK4_HAVE__INO64_T
+/** Inode number.
+*/
+typedef _ino64_t dk4_ino_t;
+#else
+#if DK4_HAVE_INO_T
+/** Inode number.
+*/
+typedef ino_t dk4_ino_t;
+#else
+#if DK4_HAVE__INO_T
+typedef _ino_t dk4_ino_t;
+#else
+/** Inode number.
+*/
+typedef dk4_um_t dk4_ino_t;
+#endif
+#endif
+#endif
+#endif
+/* --- Unix, stat64 --- */
+#else
+/* +++ Unix, stat +++ */
+#if DK4_HAVE_INO_T
+/** Inode number.
+*/
+typedef ino_t dk4_ino_t;
+#else
+#if DK4_HAVE__INO_T
+/** Inode number.
+*/
+typedef _ino_t dk4_ino_t;
+#else
+/** Inode number.
+*/
+typedef dk4_um_t dk4_ino_t;
+#endif
+#endif
+/* --- Unix, stat --- */
+#endif
+#endif
+
+#if DK4_HAVE_MODE_T
+/** File mode (type and permissions).
+*/
+typedef mode_t dk4_mode_t;
+#else
+/** File mode (type and permissions).
+*/
+typedef unsigned short dk4_mode_t;
+#endif
+
+#if DK4_HAVE_NLINK_T
+/** Number of links to inode.
+*/
+typedef nlink_t dk4_nlink_t;
+#else
+#if DK4_ON_WINDOWS
+/** Number of links to inode.
+*/
+typedef short dk4_nlink_t;
+#else
+/** Number of links to inode.
+*/
+typedef unsigned short dk4_nlink_t;
+#endif
+#endif
+
+#if DK4_HAVE_UID_T
+/** User id.
+*/
+typedef uid_t dk4_uid_t;
+#else
+#if DK4_ON_WINDOWS
+/** User id.
+*/
+typedef short dk4_uid_t;
+#else
+/** User id.
+*/
+typedef dk4_um_t dk4_uid_t;
+#endif
+#endif
+
+#if DK4_HAVE_GID_T
+/** Group ID.
+*/
+typedef gid_t dk4_gid_t;
+#else
+#if DK4_ON_WINDOWS
+/** Group ID.
+*/
+typedef short dk4_gid_t;
+#else
+/** Group ID.
+*/
+typedef dk4_um_t dk4_gid_t;
+#endif
+#endif
+
+#if DK4_ON_WINDOWS
+/* +++ Windows +++ */
+#if DK4_HAVE_OFF_T
+/** File size or position.
+*/
+typedef off_t dk4_off_t;
+#else
+#if DK4_HAVE__OFF_T
+/** File size or position.
+*/
+typedef _off_t dk4_off_t;
+#else
+/** File size or position.
+*/
+typedef dk4_um_t dk4_off_t;
+#endif
+#endif
+/* --- Windows --- */
+#else
+#if DK4_HAVE_LARGEFILE64_SOURCE && DK4_HAVE_STAT64
+/* +++ Unix, stat64 +++ */
+#if DK4_HAVE_OFF64_T
+/** File size or position.
+*/
+typedef off64_t dk4_off_t;
+#else
+#if DK4_HAVE__OFF64_T
+/** File size or position.
+*/
+typedef _off64_t dk4_off_t;
+#else
+#if DK4_HAVE_OFF_T
+/** File size or position.
+*/
+typedef off_t dk4_off_t;
+#else
+#if DK4_HAVE__OFF_T
+/** File size or position.
+*/
+typedef _off_t dk4_off_t;
+#else
+/** File size or position.
+*/
+typedef dk4_um_t dk4_off_t;
+#endif
+#endif
+#endif
+#endif
+/* --- Unix, stat64 --- */
+#else
+/* +++ Unix, stat +++ */
+#if DK4_HAVE_OFF_T
+/** File size or position.
+*/
+typedef off_t dk4_off_t;
+#else
+#if DK4_HAVE__OFF_T
+/** File size or position.
+*/
+typedef _off_t dk4_off_t;
+#else
+/** File size or position.
+*/
+typedef dk4_um_t dk4_off_t;
+#endif
+#endif
+/* --- Unix, stat --- */
+#endif
+#endif
+
+#if DK4_HAVE_BLKSIZE_T
+/** Filesystem block size.
+*/
+typedef blksize_t dk4_blksize_t;
+#else
+/** Filesystem block size.
+*/
+typedef dk4_um_t dk4_blksize_t;
+#endif
+
+#if DK4_HAVE_BLKCNT_T
+/** Filesystem block count for file.
+*/
+typedef blkcnt_t dk4_blkcnt_t;
+#else
+/** Filesystem block count for file.
+*/
+typedef dk4_um_t dk4_blkcnt_t;
+#endif
+
+#if DK4_ON_WINDOWS
+/** File statistics.
+*/
+typedef struct __stat64 dk4_stat_t;
+#else
+#if DK4_HAVE_LARGEFILE64_SOURCE && DK4_HAVE_STAT64
+/** File statistics.
+*/
+typedef struct stat64 dk4_stat_t;
+#else
+/** File statistics.
+*/
+typedef struct stat dk4_stat_t;
+#endif
+#endif
+
+#endif
+
diff --git a/support/dktools/dk4statw.c b/support/dktools/dk4statw.c
new file mode 100644
index 0000000000..feb6831427
--- /dev/null
+++ b/support/dktools/dk4statw.c
@@ -0,0 +1,114 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4statw.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4statw.c The dk4statw module.
+*/
+
+
+#line 77 "dk4statw.ctr"
+
+#include "dk4statw.h"
+#include "dk4mem.h"
+
+#if DK4_HAVE_WCHAR_H
+#ifndef WCHAR_H_INCLUDED
+#include <wchar.h>
+#define WCHAR_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+
+
+#line 110 "dk4statw.ctr"
+
+
+
+int
+dk4stat_wc(dk4_stat_t *dst, const wchar_t *path, dk4_er_t *erp)
+{
+ int back = 0;
+ if ((NULL != dst) && (NULL != path)) {
+ errno = 0;
+#if DK4_ON_WINDOWS
+ if (0 == _wstat64(path, dst)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_SYSTEM, errno);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4stat_l_wc(dk4_stat_t *dst, const wchar_t *path, dk4_er_t *erp)
+{
+ int back = 0;
+ if ((NULL != dst) && (NULL != path)) {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4statw.ctr b/support/dktools/dk4statw.ctr
new file mode 100644
index 0000000000..46c19515a8
--- /dev/null
+++ b/support/dktools/dk4statw.ctr
@@ -0,0 +1,148 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ File statistics (using stat() and
+ lstat() functions, wchar_t).
+
+ Note: The stat() and lstat() functions are sufficient for
+ non-Windows systems.
+ On Windows systems the st_dev and st_ino components may contain
+ dummy contents, the stat structure does not contain information
+ about symbolic links.
+
+ For a portable (both Windows and non-Windows) check whether a file
+ is a symbolic link, reparse point... use the dk4_file_info_t
+ data type from dk4fileit.h and the functions from dk4filei.h.
+
+ CRT on Windows: Required.
+*/
+
+#include "dk4statt.h"
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve information about a file using stat/stat64/_stat64.
+ @param dst Structure to fill with information.
+ @param path File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dst or path is NULL,
+ - DK4_E_SYSTEM<br>
+ with errno value stored in iDetails1 if the stat() function fails.
+*/
+int
+dk4stat_wc(dk4_stat_t *dst, const wchar_t *path, dk4_er_t *erp);
+
+/** Retrieve information about a file using lstat/lstat64.
+ @param dst Structure to fill with information.
+ @param path File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ if there is no support for lstat(),
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dst or path is NULL,
+ - DK4_E_SYSTEM<br>
+ with errno value stored in iDetails1 if lstat() fails.
+*/
+int
+dk4stat_l_wc(dk4_stat_t *dst, const wchar_t *path, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4statw.h"
+#include "dk4mem.h"
+
+#if DK4_HAVE_WCHAR_H
+#ifndef WCHAR_H_INCLUDED
+#include <wchar.h>
+#define WCHAR_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+$!trace-include
+
+
+
+int
+dk4stat_wc(dk4_stat_t *dst, const wchar_t *path, dk4_er_t *erp)
+{
+ int back = 0;
+ if ((NULL != dst) && (NULL != path)) {
+ errno = 0;
+#if DK4_ON_WINDOWS
+ if (0 == _wstat64(path, dst)) {
+ back = 1;
+ } else {
+ dk4error_set_idetails(erp, DK4_E_SYSTEM, errno);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4stat_l_wc(dk4_stat_t *dst, const wchar_t *path, dk4_er_t *erp)
+{
+ int back = 0;
+ if ((NULL != dst) && (NULL != path)) {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4statw.h b/support/dktools/dk4statw.h
new file mode 100644
index 0000000000..99e5fc5d5e
--- /dev/null
+++ b/support/dktools/dk4statw.h
@@ -0,0 +1,109 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4statw.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4STATW_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4STATW_H_INCLUDED 1
+
+
+#line 10 "dk4statw.ctr"
+
+/** @file
+ File statistics (using stat() and
+ lstat() functions, wchar_t).
+
+ Note: The stat() and lstat() functions are sufficient for
+ non-Windows systems.
+ On Windows systems the st_dev and st_ino components may contain
+ dummy contents, the stat structure does not contain information
+ about symbolic links.
+
+ For a portable (both Windows and non-Windows) check whether a file
+ is a symbolic link, reparse point... use the dk4_file_info_t
+ data type from dk4fileit.h and the functions from dk4filei.h.
+
+ CRT on Windows: Required.
+*/
+
+#include "dk4statt.h"
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve information about a file using stat/stat64/_stat64.
+ @param dst Structure to fill with information.
+ @param path File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dst or path is NULL,
+ - DK4_E_SYSTEM<br>
+ with errno value stored in iDetails1 if the stat() function fails.
+*/
+int
+dk4stat_wc(dk4_stat_t *dst, const wchar_t *path, dk4_er_t *erp);
+
+/** Retrieve information about a file using lstat/lstat64.
+ @param dst Structure to fill with information.
+ @param path File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ if there is no support for lstat(),
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dst or path is NULL,
+ - DK4_E_SYSTEM<br>
+ with errno value stored in iDetails1 if lstat() fails.
+*/
+int
+dk4stat_l_wc(dk4_stat_t *dst, const wchar_t *path, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4sto.c b/support/dktools/dk4sto.c
new file mode 100644
index 0000000000..816bb21f7a
--- /dev/null
+++ b/support/dktools/dk4sto.c
@@ -0,0 +1,2235 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sto.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4sto.c The dk4sto module.
+*/
+
+
+#line 451 "dk4sto.ctr"
+
+#include "dk4sto.h"
+#include "dk4mem.h"
+
+#if 0
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+
+
+
+
+#line 464 "dk4sto.ctr"
+
+
+
+/** Comparison criteria for comparing nodes.
+*/
+enum {
+ DK4STO_COMPARE_NONE = 0, /**< Do not compare the objects (unsorted). */
+ DK4STO_COMPARE_FCT , /**< Use comparison function. */
+ DK4STO_COMPARE_CHAR , /**< Evaluate objects to char values. */
+ DK4STO_COMPARE_UCHAR , /**< Evaluate to unsigned char values. */
+ DK4STO_COMPARE_SHORT , /**< Evaluate to short values. */
+ DK4STO_COMPARE_USHORT , /**< Evaluate to unsigned short values. */
+ DK4STO_COMPARE_INT , /**< Evaluate to int values. */
+ DK4STO_COMPARE_UINT , /**< Evaluate to unsigned int values. */
+ DK4STO_COMPARE_LONG , /**< Evaluate to long values. */
+ DK4STO_COMPARE_ULONG , /**< Evaluate to unsigned long values. */
+ DK4STO_COMPARE_FLOAT , /**< Evaluate to float values. */
+ DK4STO_COMPARE_DOUBLE /**< Evaluate to double values. */
+};
+
+
+
+/*
+ GENERAL STATIC FUNCTIONS
+*/
+
+/** Initialize storage node for object.
+ @param n Storage node.
+ @param o Object.
+ @param s Storage.
+ @param crit Comparison/evaluation criteria used by storage.
+*/
+static void
+dk4sto_node_init_for_object(
+ dk4_sto_node_t *n,
+ void *o,
+ dk4_sto_t *s,
+ int crit
+)
+{
+
+
+#line 505 "dk4sto.ctr"
+ n->p = n->l = n->r = NULL;
+ n->b = n->w = 0;
+ n->o = o;
+ switch(s->h) {
+ case DK4STO_COMPARE_CHAR: (n->v).c = (*((s->e).c))(o,crit); break;
+ case DK4STO_COMPARE_UCHAR: (n->v).uc = (*((s->e).uc))(o,crit); break;
+ case DK4STO_COMPARE_SHORT: (n->v).s = (*((s->e).s))(o,crit); break;
+ case DK4STO_COMPARE_USHORT: (n->v).us = (*((s->e).us))(o,crit); break;
+ case DK4STO_COMPARE_INT: (n->v).i = (*((s->e).i))(o,crit); break;
+ case DK4STO_COMPARE_UINT: (n->v).ui = (*((s->e).ui))(o,crit); break;
+ case DK4STO_COMPARE_LONG: (n->v).l = (*((s->e).l))(o,crit); break;
+ case DK4STO_COMPARE_ULONG: (n->v).ul = (*((s->e).ul))(o,crit); break;
+ case DK4STO_COMPARE_FLOAT: (n->v).f = (*((s->e).f))(o,crit); break;
+ case DK4STO_COMPARE_DOUBLE: (n->v).d = (*((s->e).d))(o,crit); break;
+ }
+
+#line 520 "dk4sto.ctr"
+}
+
+
+
+/** Copy data from one storage node to another.
+ @param d Destination node.
+ @param s Source node.
+ @param st Storage.
+*/
+static void
+dk4sto_node_data_copy(
+ dk4_sto_node_t *d,
+ dk4_sto_node_t const *s,
+ dk4_sto_t *st
+)
+{
+
+
+#line 537 "dk4sto.ctr"
+ d->o = s->o;
+ switch(st->h) {
+ case DK4STO_COMPARE_CHAR: (d->v).c = (s->v).c ; break;
+ case DK4STO_COMPARE_UCHAR: (d->v).uc = (s->v).uc ; break;
+ case DK4STO_COMPARE_SHORT: (d->v).s = (s->v).s ; break;
+ case DK4STO_COMPARE_USHORT: (d->v).us = (s->v).us ; break;
+ case DK4STO_COMPARE_INT: (d->v).i = (s->v).i ; break;
+ case DK4STO_COMPARE_UINT: (d->v).ui = (s->v).ui ; break;
+ case DK4STO_COMPARE_LONG: (d->v).l = (s->v).l ; break;
+ case DK4STO_COMPARE_ULONG: (d->v).ul = (s->v).ul ; break;
+ case DK4STO_COMPARE_FLOAT: (d->v).f = (s->v).f ; break;
+ case DK4STO_COMPARE_DOUBLE: (d->v).d = (s->v).d ; break;
+ }
+
+
+#line 551 "dk4sto.ctr"
+}
+
+
+
+/** Compare two storage nodes.
+ @param l Left node.
+ @param r Right node.
+ @param s Storage.
+ @param c Comparison criteria.
+ @return Comparison result.
+*/
+static
+int
+dk4sto_node_compare(
+ dk4_sto_node_t const *l,
+ dk4_sto_node_t const *r,
+ dk4_sto_t const *s,
+ int c
+)
+{
+ int back = 0;
+
+
+#line 573 "dk4sto.ctr"
+ switch(s->h) {
+ case DK4STO_COMPARE_FCT: {
+
+#line 575 "dk4sto.ctr"
+ back = (*((s->e).comp))((void *)(l->o),(void *)(r->o),c);
+ if(back < 0) back = -1;
+ if(back > 0) back = 1;
+ } break;
+ case DK4STO_COMPARE_CHAR: {
+
+#line 580 "dk4sto.ctr"
+ if(((l->v).c) > ((r->v).c)) { back = 1; }
+ else { if(((l->v).c) < ((r->v).c)) { back = -1; } }
+ } break;
+ case DK4STO_COMPARE_UCHAR: {
+
+#line 584 "dk4sto.ctr"
+ if(((l->v).uc) > ((r->v).uc)) { back = 1; }
+ else { if(((l->v).uc) < ((r->v).uc)) { back = -1; } }
+ } break;
+ case DK4STO_COMPARE_SHORT: {
+
+#line 588 "dk4sto.ctr"
+ if(((l->v).s) > ((r->v).s)) { back = 1; }
+ else { if(((l->v).s) < ((r->v).s)) { back = -1; } }
+ } break;
+ case DK4STO_COMPARE_USHORT: {
+
+#line 592 "dk4sto.ctr"
+ if(((l->v).us) > ((r->v).us)) { back = 1; }
+ else { if(((l->v).us) < ((r->v).us)) { back = -1; } }
+ } break;
+ case DK4STO_COMPARE_INT: {
+
+#line 596 "dk4sto.ctr"
+ if(((l->v).i) > ((r->v).i)) { back = 1; }
+ else { if(((l->v).i) < ((r->v).i)) { back = -1; } }
+ } break;
+ case DK4STO_COMPARE_UINT: {
+
+#line 600 "dk4sto.ctr"
+ if(((l->v).ui) > ((r->v).ui)) { back = 1; }
+ else { if(((l->v).ui) < ((r->v).ui)) { back = -1; } }
+ } break;
+ case DK4STO_COMPARE_LONG: {
+
+#line 604 "dk4sto.ctr"
+ if(((l->v).l) > ((r->v).l)) { back = 1; }
+ else { if(((l->v).l) < ((r->v).l)) { back = -1; } }
+ } break;
+ case DK4STO_COMPARE_ULONG: {
+
+#line 608 "dk4sto.ctr"
+ if(((l->v).ul) > ((r->v).ul)) { back = 1; }
+ else { if(((l->v).ul) < ((r->v).ul)) { back = -1; } }
+ } break;
+ case DK4STO_COMPARE_FLOAT: {
+
+#line 612 "dk4sto.ctr"
+ if(((l->v).f) > ((r->v).f)) { back = 1; }
+ else { if(((l->v).f) < ((r->v).f)) { back = -1; } }
+ } break;
+ case DK4STO_COMPARE_DOUBLE: {
+
+#line 616 "dk4sto.ctr"
+ if(((l->v).d) > ((r->v).d)) { back = 1; }
+ else { if(((l->v).d) < ((r->v).d)) { back = -1; } }
+ } break;
+ }
+
+#line 620 "dk4sto.ctr"
+ return back;
+}
+
+
+
+/*
+ UNSORTED DATA HANDLING
+*/
+
+/** Remove node from an unsorted storage.
+ @param ro Root node.
+ @param n Node to remove.
+ @return New root node.
+*/
+static dk4_sto_node_t *
+dk4sto_unsorted_remove(dk4_sto_node_t *ro, dk4_sto_node_t *n)
+{
+ dk4_sto_node_t *back = NULL;
+ dk4_sto_node_t *l = NULL; /* Left element. */
+ dk4_sto_node_t *r = NULL; /* Right element. */
+
+
+#line 641 "dk4sto.ctr"
+ back = ro;
+ l = n->l; r = n->r;
+ if(r) {
+ r->l = l;
+ }
+ if(l) {
+ l->r = r;
+ } else {
+ back = r;
+ }
+
+#line 651 "dk4sto.ctr"
+ return back;
+}
+
+
+
+/** Add node to an unsorted storage.
+ @param r Old root node.
+ @param n Node to add.
+ @return New root node or NULL.
+*/
+static dk4_sto_node_t *
+dk4sto_unsorted_add(dk4_sto_node_t *r, dk4_sto_node_t *n)
+{
+ dk4_sto_node_t *back;
+
+
+#line 666 "dk4sto.ctr"
+ back = n;
+ n->r = r;
+ if(r) {
+ r->l = n;
+ }
+
+#line 671 "dk4sto.ctr"
+ return back;
+}
+
+
+
+/** Release all nodes in an unsorted storage.
+ @param r Root node.
+*/
+static void
+dk4sto_unsorted_release_all_nodes(dk4_sto_node_t *r)
+{
+ dk4_sto_node_t *c; /* Current element. */
+ dk4_sto_node_t *n; /* Next element. */
+
+
+#line 685 "dk4sto.ctr"
+ c = r;
+ while(c) {
+ n = c->r;
+ c->p = c->l = c->r = NULL;
+ c->o = NULL;
+ c->b = c->w = 0;
+ dk4mem_free(c) ;
+ c = n;
+ }
+
+
+#line 695 "dk4sto.ctr"
+}
+
+
+
+/** Find next node in an unsorted storage.
+ @param n Current node.
+ @param r Root node.
+ @return Pointer to next node or NULL.
+*/
+static
+dk4_sto_node_t *
+dk4sto_unsorted_find_next_node(dk4_sto_node_t *n, dk4_sto_node_t *r)
+{
+ dk4_sto_node_t *back = NULL;
+
+
+#line 710 "dk4sto.ctr"
+ if(n) {
+ back = n->r;
+ } else {
+ back = r;
+ }
+
+#line 715 "dk4sto.ctr"
+ return back;
+}
+
+
+
+/** Find last node in an unsorted storage.
+ @param n Root node.
+ @return Last node or NULL.
+*/
+static dk4_sto_node_t *
+dk4sto_unsorted_find_last_node(dk4_sto_node_t *n)
+{
+ dk4_sto_node_t *back = NULL;
+
+
+#line 729 "dk4sto.ctr"
+ if(n) back = n->l;
+
+
+#line 731 "dk4sto.ctr"
+ return back;
+}
+
+
+
+/** Find node for an object in an unsorted storage.
+ @param r Root node.
+ @param o Object.
+ @return Node for object or NULL.
+*/
+static dk4_sto_node_t *
+dk4sto_unsorted_find_exact(dk4_sto_node_t *r, void const *o)
+{
+ dk4_sto_node_t *back = NULL;
+ dk4_sto_node_t *c; /* Current node. */
+
+
+#line 747 "dk4sto.ctr"
+ c = r;
+ while(c && (!back)) {
+ if((c->o) == o) {
+ back = c;
+ }
+ c = c->r;
+ }
+
+#line 754 "dk4sto.ctr"
+ return back;
+}
+
+
+
+/*
+ SORTED DATA HANDLING
+*/
+
+
+
+/** Direction to walk to.
+*/
+enum {
+ DK4STO_WALK_LEFT = 1, /**< Go to left. */
+ DK4STO_WALK_RIGHT = 2 /**< Go to right. */
+};
+
+
+
+/** Perform left rotation at node.
+ @param p Subpath to modify.
+ @return New subpath root node or NULL.
+*/
+static dk4_sto_node_t *
+dk4sto_left_rotation(dk4_sto_node_t *p)
+{
+ dk4_sto_node_t *p1;
+
+
+#line 783 "dk4sto.ctr"
+ p1 = p->r;
+ p->r = p1->l;
+ if(p->r) (p->r)->p = p;
+ p1->l = p;
+ if(p) p->p = p1;
+
+
+#line 789 "dk4sto.ctr"
+ return p1;
+}
+
+
+
+/** Perform right rotation at node.
+ @param p Subpath to modify.
+ @return New subpath root node or NULL.
+*/
+static dk4_sto_node_t *
+dk4sto_right_rotation(dk4_sto_node_t *p)
+{
+ dk4_sto_node_t *p1;
+
+
+#line 803 "dk4sto.ctr"
+ p1 = p->l;
+ p->l = p1->r;
+ if(p->l) (p->l)->p = p;
+ p1->r = p;
+ if(p) p->p = p1;
+
+
+#line 809 "dk4sto.ctr"
+ return p1;
+}
+
+
+
+/** Increment balance field of a storage node.
+ @param p Node to modify.
+*/
+static void
+dk4sto_inc_balance(dk4_sto_node_t *p)
+{
+ short x; /* New balance value. */
+
+
+#line 822 "dk4sto.ctr"
+ x = p->b;
+
+#line 823 "dk4sto.ctr"
+ x++;
+ if(x > 3) x = 0;
+ p->b = x;
+
+#line 826 "dk4sto.ctr"
+}
+
+
+
+/** Decrement balance field of a storage node.
+ @param p Storage node.
+*/
+static void
+dk4sto_dec_balance(dk4_sto_node_t *p)
+{
+ short x; /* New balance value. */
+
+
+#line 838 "dk4sto.ctr"
+ x = p->b;
+
+#line 839 "dk4sto.ctr"
+ x--;
+ if(x < 0) x = 3;
+ p->b = x;
+
+#line 842 "dk4sto.ctr"
+}
+
+
+
+
+/** Set mark for "left node deleted".
+ @param p Node.
+ @param h Pointer to balance variable.
+ @return New root node for path behind \a p.
+*/
+static dk4_sto_node_t *
+dk4sto_left_deleted(dk4_sto_node_t *p, short *h)
+{
+
+
+#line 856 "dk4sto.ctr"
+ switch(p->b) {
+ case 0: *h = - *h;
+ case 3:
+
+
+#line 860 "dk4sto.ctr"
+ dk4sto_inc_balance(p);
+
+
+#line 862 "dk4sto.ctr"
+ break;
+ case 1: {
+ switch((p->r)->b) {
+ case 0:
+ (p->r)->b = 3;
+ *h = - *h;
+ p = dk4sto_left_rotation(p);
+ break;
+ case 1:
+ (p->r)->b = 0;
+ p->b = 0;
+ p = dk4sto_left_rotation(p);
+ break;
+ case 3:
+ p->b = (((((p->r)->l)->b) == 1) ? 3 : 0);
+ (p->r)->b = (((((p->r)->l)->b) == 3) ? 1 : 0);
+ p->r = dk4sto_right_rotation(p->r);
+ if(p->r) (p->r)->p = p;
+ p = dk4sto_left_rotation(p);
+ p->b = 0;
+ }
+ }
+ }
+
+
+#line 886 "dk4sto.ctr"
+ return p;
+}
+
+
+
+/** Set mark for "right node deleted".
+ @param p Node.
+ @param h Pointer to balance variable.
+ @return New root node for path behind \a p.
+*/
+static dk4_sto_node_t *
+dk4sto_right_deleted(dk4_sto_node_t *p, short *h)
+{
+
+
+#line 900 "dk4sto.ctr"
+ switch(p->b) {
+ case 0: *h = - *h;
+ case 1: dk4sto_dec_balance(p);
+ break;
+ case 3: {
+ switch((p->l)->b) {
+ case 0:
+ (p->l)->b = 1;
+ *h = - *h;
+ p = dk4sto_right_rotation(p);
+ break;
+ case 3:
+ (p->l)->b = 0;
+ p->b = 0;
+ p = dk4sto_right_rotation(p);
+ break;
+ case 1:
+ p->b = (((((p->l)->r)->b) == 3) ? 1 : 0);
+ (p->l)->b = (((((p->l)->r)->b) == 1) ? 3 : 0);
+ p->l = dk4sto_left_rotation(p->l);
+ if(p->l) (p->l)->p = p;
+ p = dk4sto_right_rotation(p);
+ p->b = 0;
+ }
+ }
+ }
+
+
+#line 927 "dk4sto.ctr"
+ return p;
+}
+
+
+
+/** Add node to tree storage.
+ @param root Root node.
+ @param newnode Node to add.
+ @param st Storage.
+ @return New root node or NULL.
+*/
+static
+dk4_sto_node_t *
+dk4sto_avlt_add(dk4_sto_node_t *root, dk4_sto_node_t *newnode, dk4_sto_t *st)
+{
+ dk4_sto_node_t *back = NULL;
+ dk4_sto_node_t *p = NULL; /* Current node. */
+ dk4_sto_node_t *q = NULL; /* Father of p. */
+ dk4_sto_node_t *r = NULL; /* Critical node. */
+ dk4_sto_node_t *s = NULL; /* Father of r. */
+
+
+#line 948 "dk4sto.ctr"
+ back = root;
+ p = r = root; q = s = NULL;
+ /*
+ Search place for insertion, write direction into
+ the "w" field in each node.
+ The final new node has an empty "w" field.
+ */
+ while(p) {
+ if(p->b) {
+ s = q; r = p;
+ }
+ q = p;
+ if(dk4sto_node_compare(p,newnode,st,st->c) > 0) {
+ p->w = DK4STO_WALK_LEFT;
+ p = p->l;
+ } else {
+ p->w = DK4STO_WALK_RIGHT;
+ p = p->r;
+ }
+ }
+ p = newnode;
+ if(!back) {
+ /*
+ When inserting into an empty tree we are done here.
+ */
+ back = p;
+ } else {
+ /*
+ The tree is not empty.
+ The new node p is concatenated to the parent q.
+ */
+ if(dk4sto_node_compare(q,newnode,st,st->c) > 0) {
+ q->l = p;
+ q->w = DK4STO_WALK_LEFT;
+ } else {
+ q->r = p;
+ q->w = DK4STO_WALK_RIGHT;
+ }
+ /*
+ Now we must balance the tree again if necessary.
+ */
+ p->p = q;
+ if(r) {
+ /*
+ There is a critical node.
+ */
+ p = r;
+ /*
+ Modify balance fields from critial node
+ until we find our new node.
+ */
+ while(p->w) {
+ if(p->w == DK4STO_WALK_LEFT) {
+ dk4sto_dec_balance(p);
+ p = p->l;
+ } else {
+ dk4sto_inc_balance(p);
+ p = p->r;
+ }
+ }
+ p = r;
+ /*
+ Now look whether we are dis-balanced,
+ correct if necessary.
+ */
+ if((p->b) == 2) {
+ /* We must balance */
+ if(p->w == DK4STO_WALK_LEFT) {
+ if((p->l)->b == 3) {
+ p->b = 0;
+ p = dk4sto_right_rotation(p);
+ } else {
+ p->b = (((((p->l)->r)->b) == 3) ? 1 : 0);
+ (p->l)->b = (((((p->l)->r)->b) == 1) ? 3 : 0);
+ p->l = dk4sto_left_rotation(p->l);
+ if(p->l) (p->l)->p = p;
+ p = dk4sto_right_rotation(p);
+ }
+ } else {
+ if((p->r)->b == 1) {
+ p->b = 0;
+ p = dk4sto_left_rotation(p);
+ } else {
+ p->b = (((((p->r)->l)->b) == 1) ? 3 : 0);
+ (p->r)->b = (((((p->r)->l)->b) == 3) ? 1 : 0);
+ p->r = dk4sto_right_rotation(p->r);
+ if(p->r) (p->r)->p = p;
+ p = dk4sto_left_rotation(p);
+ }
+ }
+ p->b = 0;
+ /*
+ Balance at the critical nodes father (if
+ there is one) or create new root.
+ */
+ if(s) {
+ if(s->w == DK4STO_WALK_LEFT) {
+ s->l = p;
+ } else {
+ s->r = p;
+ }
+ if(p) p->p = s;
+ } else {
+ back = p;
+ }
+ }
+ }
+ }
+ if(back) {
+ back->p = NULL;
+ }
+
+
+#line 1060 "dk4sto.ctr"
+ return back;
+}
+
+
+
+/** Remove storage node from tree storage.
+ @param root Root object.
+ @param node Node to remove.
+ @param delpath Deletion path (used for tree balancing).
+ @param st Storage.
+ @param success_indicator Pointer to success variable.
+ @param toremove Node to remove.
+ @return New root object.
+*/
+static dk4_sto_node_t *
+dk4sto_avlt_delete(
+ dk4_sto_node_t *root, dk4_sto_node_t *node, dk4_sto_node_t **delpath,
+ dk4_sto_t *st, int *success_indicator, dk4_sto_node_t **toremove
+)
+{
+ dk4_sto_node_t *back = NULL;
+ dk4_sto_node_t *p = NULL; /* Current node. */
+ dk4_sto_node_t *q = NULL; /* Father of p. */
+ dk4_sto_node_t *r = NULL; /* Critical node. */
+ dk4_sto_node_t *todel = NULL; /* Node to delete. */
+ short x1 = 0; /* Balance value. */
+ short delroot = 0; /* Flag: Delete tree node. */
+ int can_continue = 1; /* Flag: Can continue. */
+ back = root;
+ todel = node;
+
+
+#line 1091 "dk4sto.ctr"
+ /*
+ Make sure the node to delete has max.
+ 1 subtree.
+ */
+ if((todel->l) && (todel->r)) {
+
+
+#line 1097 "dk4sto.ctr"
+ todel = todel->l;
+ while(todel->r) todel = todel->r;
+ dk4sto_node_data_copy(node,todel,st);
+ }
+ if(!(todel->p)) {
+
+#line 1102 "dk4sto.ctr"
+ delroot = 1;
+ }
+ /*
+ Mark the way in the "w" fields.
+ */
+ *toremove = todel;
+ todel->w = 0;
+ while(todel->p) {
+ if((todel->p)->l == todel) {
+
+
+#line 1112 "dk4sto.ctr"
+ (todel->p)->w = DK4STO_WALK_LEFT;
+ } else {
+
+
+#line 1115 "dk4sto.ctr"
+ (todel->p)->w = DK4STO_WALK_RIGHT;
+ }
+ todel = todel->p;
+ }
+ p = back;
+ q = r = NULL;
+ x1 = 0;
+ can_continue = 1;
+ while(can_continue) {
+
+
+#line 1125 "dk4sto.ctr"
+#if VERSION_BEFORE_20150821
+ if(p) {
+
+#line 1127 "dk4sto.ctr"
+#endif
+ if(p->w) {
+
+#line 1129 "dk4sto.ctr"
+ if(p->b == 0) {
+ x1 = 0;
+
+#line 1131 "dk4sto.ctr"
+ }
+ delpath[x1++] = p;
+
+#line 1133 "dk4sto.ctr"
+ if(x1 >= st->l) {
+
+#line 1134 "dk4sto.ctr"
+ /* x1 too large */
+ *success_indicator = 0;
+ goto error_mark;
+ }
+ if(p->w == DK4STO_WALK_LEFT) {
+
+#line 1139 "dk4sto.ctr"
+ p = p->l;
+ } else {
+
+#line 1141 "dk4sto.ctr"
+ p = p->r;
+ }
+ } else {
+ can_continue = 0;
+
+#line 1145 "dk4sto.ctr"
+ }
+#if VERSION_BEFORE_20150821
+ } else {
+ can_continue = 0;
+
+#line 1149 "dk4sto.ctr"
+ }
+#endif
+ }
+#if VERSION_BEFORE_20150821
+ r = p;
+#endif
+ /* 2015-08-21 Static code analysis complains p could be NULL.
+ I think it can not.
+ */
+ if(NULL != p->l) q = p->l;
+ else q = p->r;
+ if(x1 == 0) {
+ if(delroot) {
+
+#line 1162 "dk4sto.ctr"
+ back = q;
+ }
+ }
+ while(x1 > 0) {
+
+#line 1166 "dk4sto.ctr"
+ x1--;
+ p = delpath[x1];
+ if(p->w == DK4STO_WALK_LEFT) {
+
+
+#line 1170 "dk4sto.ctr"
+ p->l = q; if(q) q->p = p;
+ q = dk4sto_left_deleted(p, &x1);
+
+
+#line 1173 "dk4sto.ctr"
+ } else {
+
+
+#line 1175 "dk4sto.ctr"
+ p->r = q; if(q) q->p = p;
+ q = dk4sto_right_deleted(p, &x1);
+
+
+#line 1178 "dk4sto.ctr"
+ }
+ if(x1 == 0) {
+
+
+#line 1181 "dk4sto.ctr"
+ if(delpath[x1] == back) {
+
+
+#line 1183 "dk4sto.ctr"
+ back = q;
+ }
+ }
+ if(x1 < 0) {
+
+#line 1187 "dk4sto.ctr"
+ p = delpath[0 - x1 - 1];
+ if(p->w == DK4STO_WALK_LEFT) {
+ p->l = q;
+ } else {
+ p->r = q;
+ }
+ if(q) q->p = p;
+ }
+ }
+error_mark:
+ if(back) {
+ back->p = NULL;
+ }
+
+
+#line 1201 "dk4sto.ctr"
+ return back;
+}
+
+
+
+/** Find storage node for an object evaluated like a given object.
+ @param root Root node.
+ @param testnode Node of the given object.
+ @param st Storage.
+ @param crit Comparison criteria.
+ @param cand Pointer for candidate.
+ @return Pointer to storage node or NULL.
+*/
+static
+dk4_sto_node_t *
+dk4sto_tree_find_like(
+ dk4_sto_node_t *root, dk4_sto_node_t *testnode, dk4_sto_t *st, int crit,
+ dk4_sto_node_t **cand
+)
+{
+ dk4_sto_node_t *back = NULL;
+ dk4_sto_node_t *c = NULL; /* Current node. */
+ int testval = 0; /* Comparison result. */
+
+
+#line 1225 "dk4sto.ctr"
+ c = root;
+ while(c) {
+ testval = dk4sto_node_compare(c,testnode,st,crit);
+ switch(testval) {
+ case -1: {
+ if(cand) *cand = c;
+ c = c->r;
+ } break;
+ case 0: {
+ back = c; c = c->l;
+ } break;
+ default: {
+ c = c->l;
+ } break;
+ }
+ }
+
+#line 1241 "dk4sto.ctr"
+ return back;
+}
+
+
+
+/** Add node to a tree.
+ @param r Root node.
+ @param n New node to add.
+ @param s Storage.
+ @return Node pointer on success, NULL on error.
+*/
+static dk4_sto_node_t *
+dk4sto_tree_add(dk4_sto_node_t *r, dk4_sto_node_t *n, dk4_sto_t *s)
+{
+ dk4_sto_node_t *back;
+ back = dk4sto_avlt_add(r,n,s);
+ return back;
+}
+
+
+
+/** Release all nodes in a tree storage.
+ @param r Root node.
+*/
+static void
+dk4sto_tree_release_all_nodes(dk4_sto_node_t *r)
+{
+
+
+#line 1269 "dk4sto.ctr"
+ if(r) {
+ dk4sto_tree_release_all_nodes(r->l);
+ dk4sto_tree_release_all_nodes(r->r);
+ r->l = r->r = r->p = NULL;
+ r->o = NULL;
+ r->b = 0; r->w = 0;
+ dk4mem_free(r) ;
+ }
+
+#line 1277 "dk4sto.ctr"
+}
+
+
+
+/** Find next node in a tree storage.
+ @param n Current node.
+ @param r Root node.
+ @return Pointer to next node or NULL.
+*/
+static dk4_sto_node_t *
+dk4sto_tree_find_next_node(dk4_sto_node_t *n, dk4_sto_node_t *r)
+{
+ dk4_sto_node_t *back = NULL;
+ dk4_sto_node_t *c = NULL; /* Current node. */
+ dk4_sto_node_t *p = NULL; /* Parent of c. */
+
+
+#line 1293 "dk4sto.ctr"
+ /*
+ if(n) {
+ if(n->r) {
+ back = n->r;
+ while(back->l) { back = back->l; }
+ } else {
+ c = n; p = c->p;
+ while(p && (!back)) {
+ if((p->l) == c) {
+ back = p;
+ } else {
+ c = p; p = c->p;
+ }
+ }
+ }
+ } else {
+ back = r;
+ if(back) { while(back->l) { back = back->l; } }
+ }
+ */
+ if(n) {
+ if(n->r) {
+ back = n->r;
+ while(back->l) back = back->l;
+ } else {
+ c = n; p = c->p;
+ while(p && (!back)) {
+ if(p->l == c) {
+ back = p;
+ } else {
+ c = p; p = c->p;
+ }
+ }
+ }
+ } else {
+ back = r;
+ if(back) {
+ while(back->l) back = back->l;
+ }
+ }
+
+
+#line 1334 "dk4sto.ctr"
+ return back;
+}
+
+
+
+/** Find last node in a tree storage.
+ @param n Node to start search from.
+ @return Last node or NULL.
+*/
+static dk4_sto_node_t *
+dk4sto_tree_find_last_node(dk4_sto_node_t *n)
+{
+ dk4_sto_node_t *back = NULL;
+ dk4_sto_node_t *c; /* Current node. */
+ dk4_sto_node_t *p; /* Father of c. */
+
+
+#line 1350 "dk4sto.ctr"
+ if(n->l) {
+ back = n->l;
+ while(back->r) { back = back->r; }
+ } else {
+ c = n; p = c->p;
+ while(p && (!back)) {
+ if((p->r) == c) {
+ back = p;
+ } else {
+ c = p; p = c->p;
+ }
+ }
+ }
+
+#line 1363 "dk4sto.ctr"
+ return back;
+}
+
+
+
+/** Find node for object in tree storage (exact search).
+ @param r Root node.
+ @param o Object to find node for.
+ @param s Storage.
+ @return Pointer to node or NULL.
+*/
+static dk4_sto_node_t *
+dk4sto_tree_find_exact(dk4_sto_node_t *r, void const *o, dk4_sto_t *s)
+{
+ dk4_sto_node_t *back = NULL;
+ dk4_sto_node_t testnode; /* Test node for comparisons. */
+ dk4_sto_node_t *c; /* Current node to test. */
+ dk4_sto_node_t *candidate; /* Candidate for found node. */
+ int testval = 0; /* Comparison result. */
+
+
+#line 1383 "dk4sto.ctr"
+ dk4sto_node_init_for_object(&testnode, (void *)o, s, s->c);
+ c = dk4sto_tree_find_like(r, &testnode, s, s->c, &candidate);
+ while(c && (!back)) {
+ testval = dk4sto_node_compare(c, &testnode, s, s->c);
+ if(testval == 0) {
+ if((c->o) == o) {
+ back = c;
+ } else {
+ c = dk4sto_tree_find_next_node(c, r);
+ }
+ } else {
+ c = NULL;
+ }
+ }
+
+#line 1397 "dk4sto.ctr"
+ return back;
+}
+
+
+
+/** Remove storage node from tree storage.
+ @param ro Root node.
+ @param n Node to delete.
+ @param st Storage.
+ @param sci ???
+ @param toremove Node to remove.
+ @return New root node.
+*/
+static dk4_sto_node_t *
+dk4sto_tree_remove(
+ dk4_sto_node_t *ro, dk4_sto_node_t *n, dk4_sto_t *st, int *sci,
+ dk4_sto_node_t **toremove
+)
+{
+ dk4_sto_node_t *back;
+ back = dk4sto_avlt_delete(ro,n,st->d,st,sci,toremove);
+ return back;
+}
+
+
+
+/*
+ USE DOUBLE LINKED LIST
+*/
+
+/** Find node for an object evaluated like a given object in a list storage.
+ @param root Root node.
+ @param testnode Node with object for comparison.
+ @param st Storage.
+ @param crit Comparison criteria.
+ @param cand Test candidate.
+ @return Pointer to storage node or NULL.
+*/
+static dk4_sto_node_t *
+dk4sto_list_find_like(
+ dk4_sto_node_t *root, dk4_sto_node_t *testnode, dk4_sto_t *st, int crit,
+ dk4_sto_node_t **cand
+)
+{
+ dk4_sto_node_t *back = NULL;
+ dk4_sto_node_t *c = NULL; /* Current node. */
+ int testval = 0; /* Comparison result. */
+
+
+#line 1445 "dk4sto.ctr"
+ c = root;
+ while(c && (!back)) {
+ testval = dk4sto_node_compare(c,testnode,st,crit);
+ switch(testval) {
+ case -1: {
+ if(cand) *cand = c;
+ c = c->r;
+ } break;
+ case 0: {
+ back = c; c = NULL;
+ } break;
+ default : {
+ c = NULL;
+ } break;
+ }
+ }
+
+#line 1461 "dk4sto.ctr"
+ return back;
+}
+
+
+
+/** Find node for an object (exact search).
+ @param r Root node.
+ @param o Object.
+ @param s Storage.
+ @return Pointer to the objects node or NULL.
+*/
+static dk4_sto_node_t *
+dk4sto_list_find_exact(dk4_sto_node_t *r, void const *o, dk4_sto_t *s)
+{
+ dk4_sto_node_t *back;
+
+
+#line 1477 "dk4sto.ctr"
+ back = dk4sto_unsorted_find_exact(r,o);
+
+
+#line 1479 "dk4sto.ctr"
+ return back;
+}
+
+
+
+/** Add node to list storage.
+ @param r Root node.
+ @param n New node.
+ @param s Storage.
+ @return Pointer on success, NULL on error.
+*/
+static dk4_sto_node_t *
+dk4sto_list_add(dk4_sto_node_t *r, dk4_sto_node_t *n, dk4_sto_t *s)
+{
+ dk4_sto_node_t *back;
+ dk4_sto_node_t *larger = NULL; /* Last found larger entry. */
+ dk4_sto_node_t *current = NULL; /* Current node. */
+ dk4_sto_node_t *smaller = NULL; /* Last found smaller entry. */
+ int ende;
+
+
+#line 1499 "dk4sto.ctr"
+ back = r;
+ if(r) {
+ larger = smaller = NULL;
+ current = r;
+ ende = 0;
+ while(!ende) {
+ if(dk4sto_node_compare(current,n,s,s->c) >= 0) {
+ larger = current; ende = 1;
+ } else {
+ smaller = current;
+ }
+ if(current->r) {
+ current = current->r;
+ } else {
+ ende = 1;
+ }
+ }
+ if(larger) {
+ n->r = larger;
+ larger->l = n;
+ if(smaller) {
+ smaller->r = n;
+ n->l = smaller;
+ } else {
+ back = n;
+ }
+ } else {
+ if(smaller) {
+ smaller->r = n;
+ n->l = smaller;
+ }
+ }
+ } else {
+ back = n;
+ }
+
+#line 1534 "dk4sto.ctr"
+ return back;
+}
+
+
+
+/** Release all nodes of a list storage.
+ @param r Root node.
+*/
+static void
+dk4sto_list_release_all_nodes(dk4_sto_node_t *r)
+{
+
+
+#line 1546 "dk4sto.ctr"
+ dk4sto_unsorted_release_all_nodes(r);
+
+
+#line 1548 "dk4sto.ctr"
+}
+
+
+
+/** Find next node.
+ @param n Current node.
+ @param r Root node.
+ @return Pointer to next node or NULL.
+*/
+static dk4_sto_node_t *
+dk4sto_list_find_next_node(dk4_sto_node_t *n, dk4_sto_node_t *r)
+{
+ dk4_sto_node_t *back;
+
+
+#line 1562 "dk4sto.ctr"
+ back = dk4sto_unsorted_find_next_node(n,r);
+
+
+#line 1564 "dk4sto.ctr"
+ return back;
+}
+
+
+
+/** Find last (previous) node.
+ @param n Current node.
+ @return Pointer to previous node or NULL.
+*/
+static dk4_sto_node_t *
+dk4sto_list_find_last_node(dk4_sto_node_t *n)
+{
+ dk4_sto_node_t *back;
+
+
+#line 1578 "dk4sto.ctr"
+ back = dk4sto_unsorted_find_last_node(n);
+
+
+#line 1580 "dk4sto.ctr"
+ return back;
+}
+
+
+
+/** Remove storage node from list storage.
+ @param ro Root node.
+ @param n Node to remove.
+ @param st Storage.
+ @param sci ???
+ @param toremove ???
+*/
+static dk4_sto_node_t *
+dk4sto_list_remove(
+ dk4_sto_node_t *ro, dk4_sto_node_t *n, dk4_sto_t *st, int *sci,
+ dk4_sto_node_t **toremove
+)
+{
+ dk4_sto_node_t *back;
+
+
+#line 1600 "dk4sto.ctr"
+ back = dk4sto_unsorted_remove(ro,n);
+
+
+#line 1602 "dk4sto.ctr"
+ return back;
+}
+
+
+/*
+ COMMON STATIC FUNCTIONS
+*/
+
+
+/** Get object node (traverse storage).
+ @param it Storage iterator.
+ @param o Object to find storage node.
+ @return Pointer to node or NULL.
+*/
+static dk4_sto_node_t *
+dk4sto_traverse_iterators_for(void *it, void *o)
+{
+ dk4_sto_node_t *back = NULL;
+ dk4_sto_it_t *c = NULL; /* Current node. */
+
+
+#line 1622 "dk4sto.ctr"
+ if(it) {
+ c = (dk4_sto_it_t *)it;
+ while(c && (!back)) {
+ if(c->c) {
+ if(((c->c)->o) == o) {
+ back = c->c;
+ }
+ }
+ if(!back) c = c->r;
+ }
+ }
+
+#line 1633 "dk4sto.ctr"
+ return back;
+}
+
+
+
+/** Find last storage node.
+ @param n Current storage node.
+ @param st Storage.
+ @return Pointer to last node or NULL.
+*/
+static dk4_sto_node_t *
+dk4sto_find_last_node(dk4_sto_node_t *n, dk4_sto_t *st)
+{
+ dk4_sto_node_t *back = NULL;
+
+
+#line 1648 "dk4sto.ctr"
+ if(st->h) {
+ if(st->t) {
+ back = dk4sto_tree_find_last_node(n);
+ } else {
+ back = dk4sto_list_find_last_node(n);
+ }
+ } else {
+ back = dk4sto_unsorted_find_last_node(n);
+ }
+
+
+#line 1658 "dk4sto.ctr"
+ return back;
+}
+
+
+
+/** Initialize storage.
+ @param st Storage to initialize.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static int
+dk4sto_storage_init(dk4_sto_t *st, dk4_er_t *erp)
+{
+ int back = 0;
+ short l = 0; /* Critical path length. */
+
+
+#line 1674 "dk4sto.ctr"
+ /* delpath begin address and length */
+ st->d = NULL; st->l = 0;
+ /* root node */
+ st->r = NULL;
+ /* comparison method */
+ st->h = 0;
+ /* comparison criteria */
+ st->c = 0;
+ /* iterators list */
+ st->i = NULL;
+ st->l = l = 1536;
+ st->d = dk4mem_new(dk4_sto_node_p,l,erp);
+ st->t = 1;
+ if(st->d) {
+ back = 1;
+ }
+
+#line 1690 "dk4sto.ctr"
+ return back;
+}
+
+
+
+/** Close the storage, release memory.
+ @param st Storage to close.
+*/
+static void
+dk4sto_storage_end(dk4_sto_t *st)
+{
+
+
+#line 1702 "dk4sto.ctr"
+ /* release iterators */
+ {
+ dk4_sto_it_t *c = NULL; /* Current iterator. */
+ dk4_sto_it_t *n = NULL; /* Next iterator. */
+ c = (dk4_sto_it_t *)(st->i);
+ st->i = NULL;
+ while(c) {
+
+
+#line 1710 "dk4sto.ctr"
+ n = c->r;
+ c->r = NULL;
+ c->l = NULL;
+ c->c = NULL;
+ c->s = NULL;
+ dk4mem_free(c) ;
+ c = n;
+ }
+ st->i = NULL;
+ }
+
+
+#line 1721 "dk4sto.ctr"
+ /* release nodes */
+ {
+ if(st->h) {
+ if(st->t) {
+ dk4sto_tree_release_all_nodes(st->r);
+ } else {
+ dk4sto_list_release_all_nodes(st->r);
+ }
+ } else {
+ dk4sto_unsorted_release_all_nodes(st->r);
+ }
+ st->r = NULL;
+ }
+
+
+#line 1735 "dk4sto.ctr"
+ /* release delpath */
+ {
+ dk4_sto_node_p *p;
+ p = st->d;
+ dk4mem_free(p);
+ st->d = NULL; st->l = 0;
+ }
+
+
+#line 1743 "dk4sto.ctr"
+ /* set pointers to NULL */
+ {
+ st->h = 0;
+ st->c = 0;
+ }
+
+
+#line 1749 "dk4sto.ctr"
+
+
+#line 1750 "dk4sto.ctr"
+}
+
+
+
+/*
+ PUBLIC INTERFACES
+*/
+
+
+dk4_sto_t *
+dk4sto_open(dk4_er_t *erp)
+{
+ dk4_sto_t *back = NULL;
+
+
+#line 1764 "dk4sto.ctr"
+ back = dk4mem_new(dk4_sto_t,1,erp) ;
+ if(back) {
+ if(!dk4sto_storage_init(back,erp)) {
+ dk4mem_free(back);
+ back = NULL;
+ }
+ }
+
+#line 1771 "dk4sto.ctr"
+ return back;
+}
+
+
+
+void
+dk4sto_close(dk4_sto_t *st)
+{
+
+
+#line 1780 "dk4sto.ctr"
+ if(st) {
+ dk4sto_storage_end(st);
+ dk4mem_free(st) ;
+ }
+
+#line 1784 "dk4sto.ctr"
+}
+
+
+
+void
+dk4sto_remove_all(dk4_sto_t *st)
+{
+ if(st) {
+ /* reset all iterators */
+ dk4_sto_it_t *c = NULL; /* Curent iterator. */
+ dk4_sto_it_t *n = NULL; /* Next iterator. */
+ c = (dk4_sto_it_t *)(st->i);
+ while(c) {
+ n = c->r;
+ c->c = NULL;
+ c = n;
+ }
+ /* remove all nodes */
+ if(st->r) {
+ if(st->h) {
+ if(st->t) {
+ dk4sto_tree_release_all_nodes(st->r);
+ } else {
+ dk4sto_list_release_all_nodes(st->r);
+ }
+ } else {
+ dk4sto_unsorted_release_all_nodes(st->r);
+ }
+ }
+ st->r = NULL;
+ }
+}
+
+
+
+int
+dk4sto_remove(dk4_sto_t *st, void *o, dk4_er_t *erp)
+{
+ int back = 0;
+ dk4_sto_node_t *node_to_remove = NULL; /* Node to remove. */
+ dk4_sto_node_t *ln = NULL; /* Last node. */
+ dk4_sto_it_t *iterator = NULL; /* Traverse all iterators. */
+
+
+#line 1827 "dk4sto.ctr"
+ if(st && o) {
+ node_to_remove = dk4sto_traverse_iterators_for(st->i, o);
+ if(!node_to_remove) {
+ if(st->h) {
+ if(st->t) {
+ node_to_remove = dk4sto_tree_find_exact(st->r,o,st);
+ } else {
+ node_to_remove = dk4sto_list_find_exact(st->r,o,st);
+ }
+ } else {
+ node_to_remove = dk4sto_unsorted_find_exact(st->r,o);
+ }
+ }
+ if(node_to_remove) {
+ back = 1;
+ ln = dk4sto_find_last_node(node_to_remove,st);
+ iterator = (dk4_sto_it_t *)(st->i);
+ while(iterator) {
+ if((iterator->c) == node_to_remove) {
+ iterator->c = ln;
+ }
+ iterator = iterator->r;
+ }
+ if(st->h) {
+ if(st->t) {
+ st->r =
+ dk4sto_tree_remove(st->r,node_to_remove,st,&back,&node_to_remove);
+ } else {
+ st->r =
+ dk4sto_list_remove(st->r,node_to_remove,st,&back,&node_to_remove);
+ }
+ } else {
+ st->r = dk4sto_unsorted_remove(st->r,node_to_remove);
+ }
+ node_to_remove->l = node_to_remove->r = node_to_remove->p = NULL;
+ node_to_remove->o = NULL;
+ dk4mem_free(node_to_remove);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 1870 "dk4sto.ctr"
+ return back;
+}
+
+
+
+int
+dk4sto_add(dk4_sto_t *st, void *o, dk4_er_t *erp)
+{
+ int back = 0;
+ dk4_sto_node_t *n = NULL; /* New node. */
+
+
+#line 1881 "dk4sto.ctr"
+ if(st && o) {
+ n = dk4mem_new(dk4_sto_node_t,1,erp);
+ if(n) {
+ dk4sto_node_init_for_object(n,o,st,st->c);
+ if(st->h) {
+ if(st->t) {
+ st->r = dk4sto_tree_add(st->r, n, st);
+ } else {
+ st->r = dk4sto_list_add(st->r, n, st);
+ }
+ } else {
+ st->r = dk4sto_unsorted_add(st->r, n);
+ }
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 1899 "dk4sto.ctr"
+ return back;
+}
+
+
+
+dk4_sto_it_t *
+dk4sto_it_open(dk4_sto_t *st, dk4_er_t *erp)
+{
+ dk4_sto_it_t *back = NULL;
+
+
+#line 1909 "dk4sto.ctr"
+ if(st) {
+ back = dk4mem_new(dk4_sto_it_t,1,erp);
+ if(back) {
+ back->s = st;
+ back->l = NULL;
+ back->r = (dk4_sto_it_t *)(st->i);
+ back->c = NULL;
+ st->i = (void *)back;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 1921 "dk4sto.ctr"
+ return back;
+}
+
+
+
+void
+dk4sto_it_close(dk4_sto_it_t *it)
+{
+ dk4_sto_it_t *l = NULL; /* Left iterator. */
+ dk4_sto_it_t *r = NULL; /* Right iterator. */
+ dk4_sto_t *s = NULL; /* The storage. */
+
+
+#line 1933 "dk4sto.ctr"
+ if(it) {
+ s = it->s;
+ l = it->l;
+ r = it->r;
+ if(l) {
+ l->r = r;
+ } else {
+ s->i = (void *)(r);
+ }
+ if(r) {
+ r->l = l;
+ }
+ it->s = NULL;
+ it->l = it->r = NULL;
+ it->c = NULL;
+ dk4mem_free(it) ;
+ }
+
+#line 1950 "dk4sto.ctr"
+}
+
+
+
+void
+dk4sto_it_reset(dk4_sto_it_t *it)
+{
+
+
+#line 1958 "dk4sto.ctr"
+ if(it) {
+ it->c = NULL;
+ }
+
+#line 1961 "dk4sto.ctr"
+}
+
+
+
+void *
+dk4sto_it_next(dk4_sto_it_t *it)
+{
+ void *back = NULL;
+
+
+#line 1970 "dk4sto.ctr"
+ if(it) {
+ if(it->s) {
+ if((it->s)->h) {
+ if((it->s)->t) {
+ it->c = dk4sto_tree_find_next_node(it->c, (it->s)->r);
+ } else {
+ it->c = dk4sto_list_find_next_node(it->c, (it->s)->r);
+ }
+ } else {
+ it->c = dk4sto_unsorted_find_next_node(it->c, (it->s)->r);
+ }
+ if(it->c) {
+ back = (it->c)->o;
+ }
+ }
+ }
+
+#line 1986 "dk4sto.ctr"
+ return back;
+}
+
+
+
+void *
+dk4sto_it_find_exact(dk4_sto_it_t *i, void const *o)
+{
+ void *back = NULL;
+
+
+#line 1996 "dk4sto.ctr"
+ if(i && o) {
+ if(i->s) {
+ if((i->s)->h) {
+ if((i->s)->t) {
+ i->c = dk4sto_tree_find_exact((i->s)->r, o, i->s);
+ } else {
+ i->c = dk4sto_list_find_exact((i->s)->r, o, i->s);
+ }
+ } else {
+ i->c = dk4sto_unsorted_find_exact((i->s)->r, o);
+ }
+ }
+ if(i->c) {
+ back = (i->c)->o;
+ }
+ }
+
+#line 2012 "dk4sto.ctr"
+ return back;
+}
+
+
+
+void *
+dk4sto_it_find_like(dk4_sto_it_t *i, void const *o, int cr)
+{
+ void *back = NULL;
+ dk4_sto_node_t testnode; /* Test node for comparisons. */
+ dk4_sto_node_t *candidate = NULL; /* Candicate node. */
+
+
+#line 2024 "dk4sto.ctr"
+ if(i && o) {
+ if(i->s) {
+ candidate = NULL;
+ if((i->s)->h) {
+ dk4sto_node_init_for_object(&testnode, (void *)o, (i->s), cr);
+ if((i->s)->t) {
+ i->c =
+ dk4sto_tree_find_like((i->s)->r, &testnode, i->s, cr, &candidate);
+ } else {
+ i->c =
+ dk4sto_list_find_like((i->s)->r, &testnode, i->s, cr, &candidate);
+ }
+ } else {
+ i->c = dk4sto_unsorted_find_exact((i->s)->r, o);
+ }
+ if(i->c) {
+ back = (i->c)->o;
+ } else {
+ i->c = candidate;
+ }
+ }
+ }
+
+#line 2046 "dk4sto.ctr"
+ return back;
+}
+
+
+
+int
+dk4sto_set_eval_c(dk4_sto_t *st, dk4_fct_eval_c_t *f, int cr)
+{
+ int back = 0;
+
+
+#line 2056 "dk4sto.ctr"
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).c = f;
+ st->c = cr;
+ st->h = DK4STO_COMPARE_CHAR;
+ }
+ }
+
+#line 2064 "dk4sto.ctr"
+ return back;
+}
+
+
+
+int
+dk4sto_set_eval_uc(dk4_sto_t *st, dk4_fct_eval_uc_t *f, int cr)
+{
+ int back = 0;
+
+
+#line 2074 "dk4sto.ctr"
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).uc = f;
+ st->c = cr;
+ st->h = DK4STO_COMPARE_UCHAR;
+ }
+ }
+
+#line 2082 "dk4sto.ctr"
+ return back;
+}
+
+
+
+int
+dk4sto_set_eval_s(dk4_sto_t *st, dk4_fct_eval_s_t *f, int cr)
+{
+ int back = 0;
+
+
+#line 2092 "dk4sto.ctr"
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).s = f;
+ st->c = cr;
+ st->h = DK4STO_COMPARE_SHORT;
+ }
+ }
+
+#line 2100 "dk4sto.ctr"
+ return back;
+}
+
+
+
+int
+dk4sto_set_eval_us(dk4_sto_t *st, dk4_fct_eval_us_t *f, int cr)
+{
+ int back = 0;
+
+
+#line 2110 "dk4sto.ctr"
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).us = f;
+ st->c = cr;
+ st->h = DK4STO_COMPARE_USHORT;
+ }
+ }
+
+#line 2118 "dk4sto.ctr"
+ return back;
+}
+
+
+
+int
+dk4sto_set_eval_i(dk4_sto_t *st, dk4_fct_eval_i_t *f, int cr)
+{
+ int back = 0;
+
+
+#line 2128 "dk4sto.ctr"
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).i = f;
+ st->c = cr;
+ st->h = DK4STO_COMPARE_INT;
+ }
+ }
+
+#line 2136 "dk4sto.ctr"
+ return back;
+}
+
+
+
+int
+dk4sto_set_eval_ui(dk4_sto_t *st, dk4_fct_eval_ui_t *f, int cr)
+{
+ int back = 0;
+
+
+#line 2146 "dk4sto.ctr"
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).ui = f;
+ st->c = cr;
+ st->h = DK4STO_COMPARE_UINT;
+ }
+ }
+
+#line 2154 "dk4sto.ctr"
+ return back;
+}
+
+
+
+int
+dk4sto_set_eval_l(dk4_sto_t *st, dk4_fct_eval_l_t *f, int cr)
+{
+ int back = 0;
+
+
+#line 2164 "dk4sto.ctr"
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).l = f;
+ st->c = cr;
+ st->h = DK4STO_COMPARE_LONG;
+ }
+ }
+
+#line 2172 "dk4sto.ctr"
+ return back;
+}
+
+
+
+int
+dk4sto_set_eval_ul(dk4_sto_t *st, dk4_fct_eval_ul_t *f, int cr)
+{
+ int back = 0;
+
+
+#line 2182 "dk4sto.ctr"
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).ul = f;
+ st->c = cr;
+ st->h = DK4STO_COMPARE_ULONG;
+ }
+ }
+
+#line 2190 "dk4sto.ctr"
+ return back;
+}
+
+
+
+int
+dk4sto_set_eval_f(dk4_sto_t *st, dk4_fct_eval_f_t *f, int cr)
+{
+ int back = 0;
+
+
+#line 2200 "dk4sto.ctr"
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).f = f;
+ st->c = cr;
+ st->h = DK4STO_COMPARE_FLOAT;
+ }
+ }
+
+#line 2208 "dk4sto.ctr"
+ return back;
+}
+
+
+
+int
+dk4sto_set_eval_d(dk4_sto_t *st, dk4_fct_eval_d_t *f, int cr)
+{
+ int back = 0;
+
+
+#line 2218 "dk4sto.ctr"
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).d = f;
+ st->c = cr;
+ st->h = DK4STO_COMPARE_DOUBLE;
+ }
+ }
+
+#line 2226 "dk4sto.ctr"
+ return back;
+}
+
+
+
+int
+dk4sto_set_comp(dk4_sto_t *st, dk4_fct_comp_t *f, int cr)
+{
+ int back = 0;
+
+
+#line 2236 "dk4sto.ctr"
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).comp = f;
+ st->c = cr;
+ st->h = DK4STO_COMPARE_FCT;
+ }
+ }
+
+#line 2244 "dk4sto.ctr"
+ return back;
+}
+
+
+
+int
+dk4sto_use_trees(dk4_sto_t *st,int ok)
+{
+ int back = 0;
+ if(st) {
+ if(!(st->r)) {
+ st->t = (ok ? 1 : 0);
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+void *
+dk4sto_find_root(dk4_sto_t *s)
+{
+ void *back = NULL;
+ if(s) {
+ if(s->r) {
+ back = (s->r)->o;
+ }
+ }
+ return back;
+}
+
+
+
+void *
+dk4sto_it_find_parent(dk4_sto_it_t *i)
+{
+ void *back = NULL;
+ if(i) {
+ if(i->c) {
+ if((i->c)->p) {
+ back = ((i->c)->p)->o;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void *
+dk4sto_it_find_left(dk4_sto_it_t *i)
+{
+ void *back = NULL;
+ if(i) {
+ if(i->c) {
+ if((i->c)->l) {
+ back = ((i->c)->l)->o;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void *
+dk4sto_it_find_right(dk4_sto_it_t *i)
+{
+ void *back = NULL;
+ if(i) {
+ if(i->c) {
+ if((i->c)->r) {
+ back = ((i->c)->r)->o;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void *
+dk4sto_it_find_root(dk4_sto_it_t *i)
+{
+ void *back = NULL;
+ if(i) {
+ if(i->s) {
+ back = dk4sto_find_root(i->s);
+ }
+ }
+ return back;
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dk4sto.ctr b/support/dktools/dk4sto.ctr
new file mode 100644
index 0000000000..1ba6b42b34
--- /dev/null
+++ b/support/dktools/dk4sto.ctr
@@ -0,0 +1,2340 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Sorted and unsorted data storage in
+ AVL trees or double linked lists.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+/** Evaluation result for an object.
+*/
+typedef union {
+ double d; /**< Evaluation to double. */
+ float f; /**< Evaluation to float. */
+ long l; /**< Evaluation to long. */
+ unsigned long ul; /**< Evaluation to unsigned long. */
+ int i; /**< Evaluation to int. */
+ unsigned int ui; /**< Evaluation to unsigned int. */
+ short s; /**< Evaluation to short. */
+ unsigned short us; /**< Evaluation to unsigned short. */
+ char c; /**< Evaluation to char. */
+ unsigned char uc; /**< Evaluation to unsigned char. */
+} dk4_object_eval_res_t;
+
+
+
+/** Internal node for dk4_sto_t.
+ This structure is used internally by the dksto module.
+*/
+struct dk4__sto__node {
+ dk4_object_eval_res_t v; /**< Object evaluation of @a o. */
+ struct dk4__sto__node *p; /**< Parent node in tree. */
+ struct dk4__sto__node *l; /**< Left child (tree) or neighbour (list). */
+ struct dk4__sto__node *r; /**< Right child (tree) or neighbour (list). */
+ void *o; /**< Object to store. */
+ short b; /**< Balance flag (used in tree only). */
+ short w; /**< Direction to walk. */
+};
+
+/** Internal node for dk4_sto_t.
+*/
+typedef struct dk4__sto__node dk4_sto_node_t;
+
+/** Pointer to internal node for dk4_sto_t.
+*/
+typedef dk4_sto_node_t *dk4_sto_node_p;
+
+
+
+/** Evaluation functions.
+ These function type are used to evaluate and compare objects
+ stored in a sorted dk4_sto_t.
+*/
+
+/** Object evaluation function for sorted storage.
+*/
+typedef char dk4_fct_eval_c_t(void const *obj, int crit);
+
+/** Object evaluation function for sorted storage.
+*/
+typedef unsigned char dk4_fct_eval_uc_t(void const *obj, int crit);
+
+/** Object evaluation function for sorted storage.
+*/
+typedef short dk4_fct_eval_s_t(void const *obj, int crit);
+
+/** Object evaluation function for sorted storage.
+*/
+typedef unsigned short dk4_fct_eval_us_t(void const *obj, int crit);
+
+/** Object evaluation function for sorted storage.
+*/
+typedef int dk4_fct_eval_i_t(void const *obj, int crit);
+
+/** Object evaluation function for sorted storage.
+*/
+typedef unsigned int dk4_fct_eval_ui_t(void const *obj, int crit);
+
+/** Object evaluation function for sorted storage.
+*/
+typedef long dk4_fct_eval_l_t(void const *obj, int crit);
+
+/** Object evaluation function for sorted storage.
+*/
+typedef unsigned long dk4_fct_eval_ul_t(void const *obj, int crit);
+
+/** Object evaluation function for sorted storage.
+*/
+typedef float dk4_fct_eval_f_t(void const *obj, int crit);
+
+/** Object evaluation function for sorted storage.
+*/
+typedef double dk4_fct_eval_d_t(void const *obj, int crit);
+
+/** Object comparison function for sorted storage.
+ When comparing to objects while inserting a new object into
+ a storage both @a o1 and @a o2 are object pointers.
+ When this function is called from dk4sto_it_find_like() the
+ @a o1 argument is an object pointer from the storage,
+ @a o2 is the pointer passed to dk4sto_it_find_like().
+*/
+typedef int dk4_fct_comp_t(void const *o1, void const *o2, int crit);
+
+
+
+/** Choice for object evaluation function.
+*/
+typedef union {
+ dk4_fct_eval_c_t *c; /**< Evaluate to char. */
+ dk4_fct_eval_uc_t *uc; /**< Evaluate to unsigned char. */
+ dk4_fct_eval_s_t *s; /**< Evaluate to short. */
+ dk4_fct_eval_us_t *us; /**< Evaluate to unsigned short. */
+ dk4_fct_eval_i_t *i; /**< Evaluate to int. */
+ dk4_fct_eval_ui_t *ui; /**< Evaluate to unsigned int. */
+ dk4_fct_eval_l_t *l; /**< Evaluate to long. */
+ dk4_fct_eval_ul_t*ul; /**< Evaluate to unsigned long. */
+ dk4_fct_eval_f_t *f; /**< Evaluate to float. */
+ dk4_fct_eval_d_t *d; /**< Evaluate to double. */
+ dk4_fct_comp_t *comp; /**< Compare two objects. */
+} dk4_object_eval_fct_t;
+
+
+
+/** Object storage.
+ A storage can be used to store pointers to objects.
+*/
+typedef struct dk4__sto__t {
+ dk4_object_eval_fct_t e; /**< Comparison or evaluation function. */
+ dk4_sto_node_p *d; /**< Critical path for delete operations. */
+ dk4_sto_node_t *r; /**< Tree root or start of list. */
+ void *i; /**< Double-linked list of iterators. */
+ int h; /**< Selection for comparison or evaluation. */
+ int c; /**< Comparison or evaluation criteria. */
+ int t; /**< Flag: Use tree, 1=tree, 0=list. */
+ short l; /**< Path length of critical path. */
+} dk4_sto_t;
+
+
+
+/** Storage iterator.
+ This structure can be used to iterate through a dk4_sto_t.
+*/
+struct dk4__sto__iterator {
+ struct dk4__sto__iterator *l; /**< Left neighbour (preceeding iterator). */
+ struct dk4__sto__iterator *r; /**< Right neighbour (following iterator). */
+ dk4_sto_t *s; /**< Owner storage. */
+ dk4_sto_node_t *c; /**< Current node, current position. */
+};
+
+/** Storage iterator. Can be used to iterate through a dk4_sto_t.
+*/
+typedef struct dk4__sto__iterator dk4_sto_it_t;
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Create new storage.
+ @param erp Error report, may be NULL.
+ @return Pointer to new storage on succcess, NULL on error.
+ Use dk4sto_close() to destroy the storage when done with it.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if elsize or nelem is 0,
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow when calculating the
+ product of elsize and nelem,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available.
+*/
+dk4_sto_t *
+dk4sto_open(dk4_er_t *erp);
+
+/** Destroy storage, release memory.
+ @param st Storage to destroy.
+*/
+void
+dk4sto_close(dk4_sto_t *st);
+
+/** Remove all pointers from a storage.
+ @param st Storage.
+*/
+void
+dk4sto_remove_all(dk4_sto_t *st);
+
+/** Remove one pointer from storage.
+ @param st Storage.
+ @param o Object pointer to remove.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error (not found).
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if st or o is NULL,
+ - DK4_E_NOT_FOUND
+ if o was not found in st.
+*/
+int
+dk4sto_remove(dk4_sto_t *st, void *o, dk4_er_t *erp);
+
+/** Add object pointer to storage.
+ @param st Storage.
+ @param o Object pointer to add.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error (not enough memory).
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if st or os is NULL,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available.
+*/
+int
+dk4sto_add(dk4_sto_t *st, void *o, dk4_er_t *erp);
+
+/** Create iterator for storage.
+ @param st Storage.
+ @param erp Error report, may be NULL.
+ @return Pointer to new iterator on success, NULL on error.
+ Use dk4sto_it_close() to destroy the iterator when done with it.
+ When closing/destroying a storage all iterators for that
+ storage are destroyed automatically.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if st is NULL,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available.
+*/
+dk4_sto_it_t *
+dk4sto_it_open(dk4_sto_t *st, dk4_er_t *erp);
+
+/** Destroy iterator.
+ @param it Iterator to destroy.
+*/
+void
+dk4sto_it_close(dk4_sto_it_t *it);
+
+/** Reset iterator (next call to dk4sto_it_next() will return the
+ first object pointer.
+ @param it Iterator.
+*/
+void
+dk4sto_it_reset(dk4_sto_it_t *it);
+
+/** Return next object pointer.
+ @param it Iterator.
+ @return Pointer to next object on success, NULL on error
+ (no more pointers available).
+*/
+void *
+dk4sto_it_next(dk4_sto_it_t *it);
+
+/** Find a pointer exactly.
+ @param i Iterator.
+ @param o Object pointer.
+ @return Object pointer on success, NULL on error (object not found).
+ The next calls to dk4sto_it_next() will return pointers to objects
+ after the specified object \a o.
+*/
+void *
+dk4sto_it_find_exact(dk4_sto_it_t *i, void const *o);
+
+/** Find object pointer for object evaluating equally to \a o.
+ @param i Iterator.
+ @param o Object pointer.
+ @param cr Comparison criteria.
+ @return Object pointer on success, NULL on error (no such object).
+*/
+void *
+dk4sto_it_find_like(dk4_sto_it_t *i, void const *o, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to a char.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4sto_set_eval_c(dk4_sto_t *st, dk4_fct_eval_c_t *f, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to an unsigned char.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4sto_set_eval_uc(dk4_sto_t *st, dk4_fct_eval_uc_t *f, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to a short.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4sto_set_eval_s(dk4_sto_t *st, dk4_fct_eval_s_t *f, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to an unsigned short.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4sto_set_eval_us(dk4_sto_t *st, dk4_fct_eval_us_t *f, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to an int.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4sto_set_eval_i(dk4_sto_t *st, dk4_fct_eval_i_t *f, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to an unsigned int.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4sto_set_eval_ui(dk4_sto_t *st, dk4_fct_eval_ui_t *f, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to a long.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4sto_set_eval_l(dk4_sto_t *st, dk4_fct_eval_l_t *f, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to an unsigned long.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4sto_set_eval_ul(dk4_sto_t *st, dk4_fct_eval_ul_t *f, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to a float.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4sto_set_eval_f(dk4_sto_t *st, dk4_fct_eval_f_t *f, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to a double.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4sto_set_eval_d(dk4_sto_t *st, dk4_fct_eval_d_t *f, int cr);
+
+/** Set comparison function.
+ @param st Storage.
+ @param f Function comparing two object pointers.
+ @param cr Comparison criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4sto_set_comp(dk4_sto_t *st, dk4_fct_comp_t *f, int cr);
+
+/** Allow use of tree structures.
+ This function must be called before adding any data.
+ @param st Storage.
+ @param ok Flag: Trees may be used.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4sto_use_trees(dk4_sto_t *st,int ok);
+
+/** Find object pointer at the trees root.
+ @param s Storage.
+*/
+void *
+dk4sto_find_root(dk4_sto_t *s);
+
+/** Find object pointer for the parent node
+ of the last found object.
+ @param i Iterator.
+ @return Object pointer on success, NULL on error.
+*/
+void *
+dk4sto_it_find_parent(dk4_sto_it_t *i);
+
+/** Find object pointer for node on left child of the last found object.
+ @param i Iterator.
+ @return Object pointer on success, NULL on error.
+*/
+void *
+dk4sto_it_find_left(dk4_sto_it_t *i);
+
+/** Find object pointer for node on right child of the last found object.
+ @param i Iterator.
+ @return Object pointer on success, NULL on error.
+*/
+void *
+dk4sto_it_find_right(dk4_sto_it_t *i);
+
+/** Find object pointer at the trees root.
+ @param i Iterator.
+*/
+void *
+dk4sto_it_find_root(dk4_sto_it_t *i);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4sto.h"
+#include "dk4mem.h"
+
+#if 0
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+
+$(trace-include)
+
+
+
+/** Comparison criteria for comparing nodes.
+*/
+enum {
+ DK4STO_COMPARE_NONE = 0, /**< Do not compare the objects (unsorted). */
+ DK4STO_COMPARE_FCT , /**< Use comparison function. */
+ DK4STO_COMPARE_CHAR , /**< Evaluate objects to char values. */
+ DK4STO_COMPARE_UCHAR , /**< Evaluate to unsigned char values. */
+ DK4STO_COMPARE_SHORT , /**< Evaluate to short values. */
+ DK4STO_COMPARE_USHORT , /**< Evaluate to unsigned short values. */
+ DK4STO_COMPARE_INT , /**< Evaluate to int values. */
+ DK4STO_COMPARE_UINT , /**< Evaluate to unsigned int values. */
+ DK4STO_COMPARE_LONG , /**< Evaluate to long values. */
+ DK4STO_COMPARE_ULONG , /**< Evaluate to unsigned long values. */
+ DK4STO_COMPARE_FLOAT , /**< Evaluate to float values. */
+ DK4STO_COMPARE_DOUBLE /**< Evaluate to double values. */
+};
+
+
+
+/*
+ GENERAL STATIC FUNCTIONS
+*/
+
+/** Initialize storage node for object.
+ @param n Storage node.
+ @param o Object.
+ @param s Storage.
+ @param crit Comparison/evaluation criteria used by storage.
+*/
+static void
+dk4sto_node_init_for_object(
+ dk4_sto_node_t *n,
+ void *o,
+ dk4_sto_t *s,
+ int crit
+)
+{
+ $? "+ dk4sto_node_init_for_object PTR=%d PTR=%d PTR=%d %d", TR_IPTR(n), TR_IPTR(o), TR_IPTR(s), crit
+ n->p = n->l = n->r = NULL;
+ n->b = n->w = 0;
+ n->o = o;
+ switch(s->h) {
+ case DK4STO_COMPARE_CHAR: (n->v).c = (*((s->e).c))(o,crit); break;
+ case DK4STO_COMPARE_UCHAR: (n->v).uc = (*((s->e).uc))(o,crit); break;
+ case DK4STO_COMPARE_SHORT: (n->v).s = (*((s->e).s))(o,crit); break;
+ case DK4STO_COMPARE_USHORT: (n->v).us = (*((s->e).us))(o,crit); break;
+ case DK4STO_COMPARE_INT: (n->v).i = (*((s->e).i))(o,crit); break;
+ case DK4STO_COMPARE_UINT: (n->v).ui = (*((s->e).ui))(o,crit); break;
+ case DK4STO_COMPARE_LONG: (n->v).l = (*((s->e).l))(o,crit); break;
+ case DK4STO_COMPARE_ULONG: (n->v).ul = (*((s->e).ul))(o,crit); break;
+ case DK4STO_COMPARE_FLOAT: (n->v).f = (*((s->e).f))(o,crit); break;
+ case DK4STO_COMPARE_DOUBLE: (n->v).d = (*((s->e).d))(o,crit); break;
+ } $? "- dk4sto_node_init_for_object"
+}
+
+
+
+/** Copy data from one storage node to another.
+ @param d Destination node.
+ @param s Source node.
+ @param st Storage.
+*/
+static void
+dk4sto_node_data_copy(
+ dk4_sto_node_t *d,
+ dk4_sto_node_t const *s,
+ dk4_sto_t *st
+)
+{
+ $? "+ dk4sto_node_data_copy PTR=%d PTR=%d", TR_IPTR(d), TR_IPTR(s)
+ d->o = s->o;
+ switch(st->h) {
+ case DK4STO_COMPARE_CHAR: (d->v).c = (s->v).c ; break;
+ case DK4STO_COMPARE_UCHAR: (d->v).uc = (s->v).uc ; break;
+ case DK4STO_COMPARE_SHORT: (d->v).s = (s->v).s ; break;
+ case DK4STO_COMPARE_USHORT: (d->v).us = (s->v).us ; break;
+ case DK4STO_COMPARE_INT: (d->v).i = (s->v).i ; break;
+ case DK4STO_COMPARE_UINT: (d->v).ui = (s->v).ui ; break;
+ case DK4STO_COMPARE_LONG: (d->v).l = (s->v).l ; break;
+ case DK4STO_COMPARE_ULONG: (d->v).ul = (s->v).ul ; break;
+ case DK4STO_COMPARE_FLOAT: (d->v).f = (s->v).f ; break;
+ case DK4STO_COMPARE_DOUBLE: (d->v).d = (s->v).d ; break;
+ }
+ $? "- dk4sto_node_data_copy"
+}
+
+
+
+/** Compare two storage nodes.
+ @param l Left node.
+ @param r Right node.
+ @param s Storage.
+ @param c Comparison criteria.
+ @return Comparison result.
+*/
+static
+int
+dk4sto_node_compare(
+ dk4_sto_node_t const *l,
+ dk4_sto_node_t const *r,
+ dk4_sto_t const *s,
+ int c
+)
+{
+ int back = 0;
+ $? "+ dk4sto_node_compare PTR=%d PTR=%d PTR=%d %d", TR_IPTR(l), TR_IPTR(r), TR_IPTR(s), c
+ switch(s->h) {
+ case DK4STO_COMPARE_FCT: { $? ". compare by function"
+ back = (*((s->e).comp))((void *)(l->o),(void *)(r->o),c);
+ if(back < 0) back = -1;
+ if(back > 0) back = 1;
+ } break;
+ case DK4STO_COMPARE_CHAR: { $? ". compare character"
+ if(((l->v).c) > ((r->v).c)) { back = 1; }
+ else { if(((l->v).c) < ((r->v).c)) { back = -1; } }
+ } break;
+ case DK4STO_COMPARE_UCHAR: { $? ". compare unsigned character"
+ if(((l->v).uc) > ((r->v).uc)) { back = 1; }
+ else { if(((l->v).uc) < ((r->v).uc)) { back = -1; } }
+ } break;
+ case DK4STO_COMPARE_SHORT: { $? ". compare short"
+ if(((l->v).s) > ((r->v).s)) { back = 1; }
+ else { if(((l->v).s) < ((r->v).s)) { back = -1; } }
+ } break;
+ case DK4STO_COMPARE_USHORT: { $? ". compare unsigned short"
+ if(((l->v).us) > ((r->v).us)) { back = 1; }
+ else { if(((l->v).us) < ((r->v).us)) { back = -1; } }
+ } break;
+ case DK4STO_COMPARE_INT: { $? ". compare int"
+ if(((l->v).i) > ((r->v).i)) { back = 1; }
+ else { if(((l->v).i) < ((r->v).i)) { back = -1; } }
+ } break;
+ case DK4STO_COMPARE_UINT: { $? ". compare unsigned int"
+ if(((l->v).ui) > ((r->v).ui)) { back = 1; }
+ else { if(((l->v).ui) < ((r->v).ui)) { back = -1; } }
+ } break;
+ case DK4STO_COMPARE_LONG: { $? ". compare long"
+ if(((l->v).l) > ((r->v).l)) { back = 1; }
+ else { if(((l->v).l) < ((r->v).l)) { back = -1; } }
+ } break;
+ case DK4STO_COMPARE_ULONG: { $? ". compare unsigned long"
+ if(((l->v).ul) > ((r->v).ul)) { back = 1; }
+ else { if(((l->v).ul) < ((r->v).ul)) { back = -1; } }
+ } break;
+ case DK4STO_COMPARE_FLOAT: { $? ". compare float"
+ if(((l->v).f) > ((r->v).f)) { back = 1; }
+ else { if(((l->v).f) < ((r->v).f)) { back = -1; } }
+ } break;
+ case DK4STO_COMPARE_DOUBLE: { $? ". compare double"
+ if(((l->v).d) > ((r->v).d)) { back = 1; }
+ else { if(((l->v).d) < ((r->v).d)) { back = -1; } }
+ } break;
+ } $? "- dk4sto_node_compare %d", back
+ return back;
+}
+
+
+
+/*
+ UNSORTED DATA HANDLING
+*/
+
+/** Remove node from an unsorted storage.
+ @param ro Root node.
+ @param n Node to remove.
+ @return New root node.
+*/
+static dk4_sto_node_t *
+dk4sto_unsorted_remove(dk4_sto_node_t *ro, dk4_sto_node_t *n)
+{
+ dk4_sto_node_t *back = NULL;
+ dk4_sto_node_t *l = NULL; /* Left element. */
+ dk4_sto_node_t *r = NULL; /* Right element. */
+ $? "+ dk4sto_unsorted_remove PTR=%d PTR=%d", TR_IPTR(ro), TR_IPTR(n)
+ back = ro;
+ l = n->l; r = n->r;
+ if(r) {
+ r->l = l;
+ }
+ if(l) {
+ l->r = r;
+ } else {
+ back = r;
+ } $? "- dk4sto_unsorted_remove PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/** Add node to an unsorted storage.
+ @param r Old root node.
+ @param n Node to add.
+ @return New root node or NULL.
+*/
+static dk4_sto_node_t *
+dk4sto_unsorted_add(dk4_sto_node_t *r, dk4_sto_node_t *n)
+{
+ dk4_sto_node_t *back;
+ $? "+ dk4sto_unsorted_add PTR=%d PTR=%d", TR_IPTR(r), TR_IPTR(n)
+ back = n;
+ n->r = r;
+ if(r) {
+ r->l = n;
+ } $? "- dk4sto_unsorted_add PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/** Release all nodes in an unsorted storage.
+ @param r Root node.
+*/
+static void
+dk4sto_unsorted_release_all_nodes(dk4_sto_node_t *r)
+{
+ dk4_sto_node_t *c; /* Current element. */
+ dk4_sto_node_t *n; /* Next element. */
+ $? "+ dk4sto_unsorted_release_all_nodes PTR=%d", TR_IPTR(r)
+ c = r;
+ while(c) {
+ n = c->r;
+ c->p = c->l = c->r = NULL;
+ c->o = NULL;
+ c->b = c->w = 0;
+ dk4mem_free(c) ;
+ c = n;
+ }
+ $? "- dk4sto_unsorted_release_all_nodes"
+}
+
+
+
+/** Find next node in an unsorted storage.
+ @param n Current node.
+ @param r Root node.
+ @return Pointer to next node or NULL.
+*/
+static
+dk4_sto_node_t *
+dk4sto_unsorted_find_next_node(dk4_sto_node_t *n, dk4_sto_node_t *r)
+{
+ dk4_sto_node_t *back = NULL;
+ $? "+ dk4sto_unsorted_find_next_node PTR=%d PTR=%d", TR_IPTR(n), TR_IPTR(r)
+ if(n) {
+ back = n->r;
+ } else {
+ back = r;
+ } $? "- dk4sto_unsorted_find_next_node PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/** Find last node in an unsorted storage.
+ @param n Root node.
+ @return Last node or NULL.
+*/
+static dk4_sto_node_t *
+dk4sto_unsorted_find_last_node(dk4_sto_node_t *n)
+{
+ dk4_sto_node_t *back = NULL;
+ $? "+ dk4sto_unsorted_find_last_node PTR=%d", TR_IPTR(n)
+ if(n) back = n->l;
+ $? "- dk4sto_unsorted_find_last_node PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/** Find node for an object in an unsorted storage.
+ @param r Root node.
+ @param o Object.
+ @return Node for object or NULL.
+*/
+static dk4_sto_node_t *
+dk4sto_unsorted_find_exact(dk4_sto_node_t *r, void const *o)
+{
+ dk4_sto_node_t *back = NULL;
+ dk4_sto_node_t *c; /* Current node. */
+ $? "+ dk4sto_unsorted_find_exact PTR=%d PTR=%d", TR_IPTR(r), TR_IPTR(o)
+ c = r;
+ while(c && (!back)) {
+ if((c->o) == o) {
+ back = c;
+ }
+ c = c->r;
+ } $? "- dk4sto_unsorted_find_exact PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/*
+ SORTED DATA HANDLING
+*/
+
+
+
+/** Direction to walk to.
+*/
+enum {
+ DK4STO_WALK_LEFT = 1, /**< Go to left. */
+ DK4STO_WALK_RIGHT = 2 /**< Go to right. */
+};
+
+
+
+/** Perform left rotation at node.
+ @param p Subpath to modify.
+ @return New subpath root node or NULL.
+*/
+static dk4_sto_node_t *
+dk4sto_left_rotation(dk4_sto_node_t *p)
+{
+ dk4_sto_node_t *p1;
+ $? "+ dk4sto_left_rotation PTR=%d", TR_IPTR(p)
+ p1 = p->r;
+ p->r = p1->l;
+ if(p->r) (p->r)->p = p;
+ p1->l = p;
+ if(p) p->p = p1;
+ $? "- dk4sto_left_rotation PTR=%d", TR_IPTR(p1)
+ return p1;
+}
+
+
+
+/** Perform right rotation at node.
+ @param p Subpath to modify.
+ @return New subpath root node or NULL.
+*/
+static dk4_sto_node_t *
+dk4sto_right_rotation(dk4_sto_node_t *p)
+{
+ dk4_sto_node_t *p1;
+ $? "+ dk4sto_right_rotation PTR=%d", TR_IPTR(p)
+ p1 = p->l;
+ p->l = p1->r;
+ if(p->l) (p->l)->p = p;
+ p1->r = p;
+ if(p) p->p = p1;
+ $? "- dk4sto_right_rotation PTR=%d", TR_IPTR(p1)
+ return p1;
+}
+
+
+
+/** Increment balance field of a storage node.
+ @param p Node to modify.
+*/
+static void
+dk4sto_inc_balance(dk4_sto_node_t *p)
+{
+ short x; /* New balance value. */
+ $? "+ dk4sto_inc_balance PTR=%d", TR_IPTR(p)
+ x = p->b; $? ". old balance %d", x
+ x++;
+ if(x > 3) x = 0;
+ p->b = x; $? "- dk4sto_inc_balance %d", p->b
+}
+
+
+
+/** Decrement balance field of a storage node.
+ @param p Storage node.
+*/
+static void
+dk4sto_dec_balance(dk4_sto_node_t *p)
+{
+ short x; /* New balance value. */
+ $? "+ dk4sto_dec_balance PTR=%d", TR_IPTR(p)
+ x = p->b; $? ". old balance %d", x
+ x--;
+ if(x < 0) x = 3;
+ p->b = x; $? "- dk4sto_dec_balance %d", p->b
+}
+
+
+
+
+/** Set mark for "left node deleted".
+ @param p Node.
+ @param h Pointer to balance variable.
+ @return New root node for path behind \a p.
+*/
+static dk4_sto_node_t *
+dk4sto_left_deleted(dk4_sto_node_t *p, short *h)
+{
+ $? "+ dk4sto_left_deleted PTR=%d PTR=%d", TR_IPTR(p), TR_IPTR(h)
+ switch(p->b) {
+ case 0: *h = - *h;
+ case 3:
+ $? ". going to increment balance field of PTR=%d", TR_IPTR(p)
+ dk4sto_inc_balance(p);
+ $? ". balance field incremented"
+ break;
+ case 1: {
+ switch((p->r)->b) {
+ case 0:
+ (p->r)->b = 3;
+ *h = - *h;
+ p = dk4sto_left_rotation(p);
+ break;
+ case 1:
+ (p->r)->b = 0;
+ p->b = 0;
+ p = dk4sto_left_rotation(p);
+ break;
+ case 3:
+ p->b = (((((p->r)->l)->b) == 1) ? 3 : 0);
+ (p->r)->b = (((((p->r)->l)->b) == 3) ? 1 : 0);
+ p->r = dk4sto_right_rotation(p->r);
+ if(p->r) (p->r)->p = p;
+ p = dk4sto_left_rotation(p);
+ p->b = 0;
+ }
+ }
+ }
+ $? "- dk4sto_left_deleted PTR=%d", TR_IPTR(p)
+ return p;
+}
+
+
+
+/** Set mark for "right node deleted".
+ @param p Node.
+ @param h Pointer to balance variable.
+ @return New root node for path behind \a p.
+*/
+static dk4_sto_node_t *
+dk4sto_right_deleted(dk4_sto_node_t *p, short *h)
+{
+ $? "+ dk4sto_right_deleted PTR=%d PTR=%d", TR_IPTR(p), TR_IPTR(h)
+ switch(p->b) {
+ case 0: *h = - *h;
+ case 1: dk4sto_dec_balance(p);
+ break;
+ case 3: {
+ switch((p->l)->b) {
+ case 0:
+ (p->l)->b = 1;
+ *h = - *h;
+ p = dk4sto_right_rotation(p);
+ break;
+ case 3:
+ (p->l)->b = 0;
+ p->b = 0;
+ p = dk4sto_right_rotation(p);
+ break;
+ case 1:
+ p->b = (((((p->l)->r)->b) == 3) ? 1 : 0);
+ (p->l)->b = (((((p->l)->r)->b) == 1) ? 3 : 0);
+ p->l = dk4sto_left_rotation(p->l);
+ if(p->l) (p->l)->p = p;
+ p = dk4sto_right_rotation(p);
+ p->b = 0;
+ }
+ }
+ }
+ $? "- dk4sto_right_deleted PTR=%d", TR_IPTR(p)
+ return p;
+}
+
+
+
+/** Add node to tree storage.
+ @param root Root node.
+ @param newnode Node to add.
+ @param st Storage.
+ @return New root node or NULL.
+*/
+static
+dk4_sto_node_t *
+dk4sto_avlt_add(dk4_sto_node_t *root, dk4_sto_node_t *newnode, dk4_sto_t *st)
+{
+ dk4_sto_node_t *back = NULL;
+ dk4_sto_node_t *p = NULL; /* Current node. */
+ dk4_sto_node_t *q = NULL; /* Father of p. */
+ dk4_sto_node_t *r = NULL; /* Critical node. */
+ dk4_sto_node_t *s = NULL; /* Father of r. */
+ $? "+ dk4sto_avlt_add PTR=%d PTR=%d PTR=%d", TR_IPTR(root), TR_IPTR(newnode), TR_IPTR(st)
+ back = root;
+ p = r = root; q = s = NULL;
+ /*
+ Search place for insertion, write direction into
+ the "w" field in each node.
+ The final new node has an empty "w" field.
+ */
+ while(p) {
+ if(p->b) {
+ s = q; r = p;
+ }
+ q = p;
+ if(dk4sto_node_compare(p,newnode,st,st->c) > 0) {
+ p->w = DK4STO_WALK_LEFT;
+ p = p->l;
+ } else {
+ p->w = DK4STO_WALK_RIGHT;
+ p = p->r;
+ }
+ }
+ p = newnode;
+ if(!back) {
+ /*
+ When inserting into an empty tree we are done here.
+ */
+ back = p;
+ } else {
+ /*
+ The tree is not empty.
+ The new node p is concatenated to the parent q.
+ */
+ if(dk4sto_node_compare(q,newnode,st,st->c) > 0) {
+ q->l = p;
+ q->w = DK4STO_WALK_LEFT;
+ } else {
+ q->r = p;
+ q->w = DK4STO_WALK_RIGHT;
+ }
+ /*
+ Now we must balance the tree again if necessary.
+ */
+ p->p = q;
+ if(r) {
+ /*
+ There is a critical node.
+ */
+ p = r;
+ /*
+ Modify balance fields from critial node
+ until we find our new node.
+ */
+ while(p->w) {
+ if(p->w == DK4STO_WALK_LEFT) {
+ dk4sto_dec_balance(p);
+ p = p->l;
+ } else {
+ dk4sto_inc_balance(p);
+ p = p->r;
+ }
+ }
+ p = r;
+ /*
+ Now look whether we are dis-balanced,
+ correct if necessary.
+ */
+ if((p->b) == 2) {
+ /* We must balance */
+ if(p->w == DK4STO_WALK_LEFT) {
+ if((p->l)->b == 3) {
+ p->b = 0;
+ p = dk4sto_right_rotation(p);
+ } else {
+ p->b = (((((p->l)->r)->b) == 3) ? 1 : 0);
+ (p->l)->b = (((((p->l)->r)->b) == 1) ? 3 : 0);
+ p->l = dk4sto_left_rotation(p->l);
+ if(p->l) (p->l)->p = p;
+ p = dk4sto_right_rotation(p);
+ }
+ } else {
+ if((p->r)->b == 1) {
+ p->b = 0;
+ p = dk4sto_left_rotation(p);
+ } else {
+ p->b = (((((p->r)->l)->b) == 1) ? 3 : 0);
+ (p->r)->b = (((((p->r)->l)->b) == 3) ? 1 : 0);
+ p->r = dk4sto_right_rotation(p->r);
+ if(p->r) (p->r)->p = p;
+ p = dk4sto_left_rotation(p);
+ }
+ }
+ p->b = 0;
+ /*
+ Balance at the critical nodes father (if
+ there is one) or create new root.
+ */
+ if(s) {
+ if(s->w == DK4STO_WALK_LEFT) {
+ s->l = p;
+ } else {
+ s->r = p;
+ }
+ if(p) p->p = s;
+ } else {
+ back = p;
+ }
+ }
+ }
+ }
+ if(back) {
+ back->p = NULL;
+ }
+ $? "- dk4sto_avlt_add PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/** Remove storage node from tree storage.
+ @param root Root object.
+ @param node Node to remove.
+ @param delpath Deletion path (used for tree balancing).
+ @param st Storage.
+ @param success_indicator Pointer to success variable.
+ @param toremove Node to remove.
+ @return New root object.
+*/
+static dk4_sto_node_t *
+dk4sto_avlt_delete(
+ dk4_sto_node_t *root, dk4_sto_node_t *node, dk4_sto_node_t **delpath,
+ dk4_sto_t *st, int *success_indicator, dk4_sto_node_t **toremove
+)
+{
+ dk4_sto_node_t *back = NULL;
+ dk4_sto_node_t *p = NULL; /* Current node. */
+ dk4_sto_node_t *q = NULL; /* Father of p. */
+ dk4_sto_node_t *r = NULL; /* Critical node. */
+ dk4_sto_node_t *todel = NULL; /* Node to delete. */
+ short x1 = 0; /* Balance value. */
+ short delroot = 0; /* Flag: Delete tree node. */
+ int can_continue = 1; /* Flag: Can continue. */
+ back = root;
+ todel = node;
+ $? "+ dk4sto_avlt_delete PTRS=%d %d %d %d %d", TR_IPTR(root), TR_IPTR(node), TR_IPTR(delpath), TR_IPTR(st), TR_IPTR(success_indicator)
+ /*
+ Make sure the node to delete has max.
+ 1 subtree.
+ */
+ if((todel->l) && (todel->r)) {
+ $? ". finding another node to delete"
+ todel = todel->l;
+ while(todel->r) todel = todel->r;
+ dk4sto_node_data_copy(node,todel,st);
+ }
+ if(!(todel->p)) { $? ". deleting the root node"
+ delroot = 1;
+ }
+ /*
+ Mark the way in the "w" fields.
+ */
+ *toremove = todel;
+ todel->w = 0;
+ while(todel->p) {
+ if((todel->p)->l == todel) {
+ $? ". walk left"
+ (todel->p)->w = DK4STO_WALK_LEFT;
+ } else {
+ $? ". walk right"
+ (todel->p)->w = DK4STO_WALK_RIGHT;
+ }
+ todel = todel->p;
+ }
+ p = back;
+ q = r = NULL;
+ x1 = 0;
+ can_continue = 1;
+ while(can_continue) {
+ $? ". new while loop 1 %d", x1
+#if VERSION_BEFORE_20150821
+ if(p) { $? ". have current node"
+#endif
+ if(p->w) { $? ". not final node"
+ if(p->b == 0) {
+ x1 = 0; $? ". current node is balanced"
+ }
+ delpath[x1++] = p; $? ". adding current node to delpath %d", (x1 - 1)
+ if(x1 >= st->l) { $? ". x1 out of range"
+ /* x1 too large */
+ *success_indicator = 0;
+ goto error_mark;
+ }
+ if(p->w == DK4STO_WALK_LEFT) { $? ". going down left"
+ p = p->l;
+ } else { $? ". going down right"
+ p = p->r;
+ }
+ } else {
+ can_continue = 0; $? ". we are at the final point"
+ }
+#if VERSION_BEFORE_20150821
+ } else {
+ can_continue = 0; $? ". no more nodes to visit"
+ }
+#endif
+ }
+#if VERSION_BEFORE_20150821
+ r = p;
+#endif
+ /* 2015-08-21 Static code analysis complains p could be NULL.
+ I think it can not.
+ */
+ if(NULL != p->l) q = p->l;
+ else q = p->r;
+ if(x1 == 0) {
+ if(delroot) { $? ". setting new root node"
+ back = q;
+ }
+ }
+ while(x1 > 0) { $? ". begin of while loop 2 %d", (x1 - 1)
+ x1--;
+ p = delpath[x1];
+ if(p->w == DK4STO_WALK_LEFT) {
+ $? ". going to left"
+ p->l = q; if(q) q->p = p;
+ q = dk4sto_left_deleted(p, &x1);
+ $? ". after dk4sto_left_deleted"
+ } else {
+ $? ". going to right"
+ p->r = q; if(q) q->p = p;
+ q = dk4sto_right_deleted(p, &x1);
+ $? ". after dk4sto_right_deleted"
+ }
+ if(x1 == 0) {
+ $? ". final node"
+ if(delpath[x1] == back) {
+ $? ". setting new root node"
+ back = q;
+ }
+ }
+ if(x1 < 0) { $? ". finished"
+ p = delpath[0 - x1 - 1];
+ if(p->w == DK4STO_WALK_LEFT) {
+ p->l = q;
+ } else {
+ p->r = q;
+ }
+ if(q) q->p = p;
+ }
+ }
+error_mark:
+ if(back) {
+ back->p = NULL;
+ }
+ $? "- dk4sto_avlt_delete PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/** Find storage node for an object evaluated like a given object.
+ @param root Root node.
+ @param testnode Node of the given object.
+ @param st Storage.
+ @param crit Comparison criteria.
+ @param cand Pointer for candidate.
+ @return Pointer to storage node or NULL.
+*/
+static
+dk4_sto_node_t *
+dk4sto_tree_find_like(
+ dk4_sto_node_t *root, dk4_sto_node_t *testnode, dk4_sto_t *st, int crit,
+ dk4_sto_node_t **cand
+)
+{
+ dk4_sto_node_t *back = NULL;
+ dk4_sto_node_t *c = NULL; /* Current node. */
+ int testval = 0; /* Comparison result. */
+ $? "+ sorted_find_like PTR=%d PTR=%d PTR=%d %d", TR_IPTR(root), TR_IPTR(testnode), TR_IPTR(st), crit
+ c = root;
+ while(c) {
+ testval = dk4sto_node_compare(c,testnode,st,crit);
+ switch(testval) {
+ case -1: {
+ if(cand) *cand = c;
+ c = c->r;
+ } break;
+ case 0: {
+ back = c; c = c->l;
+ } break;
+ default: {
+ c = c->l;
+ } break;
+ }
+ } $? "- sorted_find_like PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/** Add node to a tree.
+ @param r Root node.
+ @param n New node to add.
+ @param s Storage.
+ @return Node pointer on success, NULL on error.
+*/
+static dk4_sto_node_t *
+dk4sto_tree_add(dk4_sto_node_t *r, dk4_sto_node_t *n, dk4_sto_t *s)
+{
+ dk4_sto_node_t *back;
+ back = dk4sto_avlt_add(r,n,s);
+ return back;
+}
+
+
+
+/** Release all nodes in a tree storage.
+ @param r Root node.
+*/
+static void
+dk4sto_tree_release_all_nodes(dk4_sto_node_t *r)
+{
+ $? "+ sorted_release_all_nodes PTR=%d", TR_IPTR(r)
+ if(r) {
+ dk4sto_tree_release_all_nodes(r->l);
+ dk4sto_tree_release_all_nodes(r->r);
+ r->l = r->r = r->p = NULL;
+ r->o = NULL;
+ r->b = 0; r->w = 0;
+ dk4mem_free(r) ;
+ } $? "- sorted_release_all_nodes"
+}
+
+
+
+/** Find next node in a tree storage.
+ @param n Current node.
+ @param r Root node.
+ @return Pointer to next node or NULL.
+*/
+static dk4_sto_node_t *
+dk4sto_tree_find_next_node(dk4_sto_node_t *n, dk4_sto_node_t *r)
+{
+ dk4_sto_node_t *back = NULL;
+ dk4_sto_node_t *c = NULL; /* Current node. */
+ dk4_sto_node_t *p = NULL; /* Parent of c. */
+ $? "+ sorted_find_next_node PTR=%d PTR=%d", TR_IPTR(n), TR_IPTR(r)
+ /*
+ if(n) {
+ if(n->r) {
+ back = n->r;
+ while(back->l) { back = back->l; }
+ } else {
+ c = n; p = c->p;
+ while(p && (!back)) {
+ if((p->l) == c) {
+ back = p;
+ } else {
+ c = p; p = c->p;
+ }
+ }
+ }
+ } else {
+ back = r;
+ if(back) { while(back->l) { back = back->l; } }
+ }
+ */
+ if(n) {
+ if(n->r) {
+ back = n->r;
+ while(back->l) back = back->l;
+ } else {
+ c = n; p = c->p;
+ while(p && (!back)) {
+ if(p->l == c) {
+ back = p;
+ } else {
+ c = p; p = c->p;
+ }
+ }
+ }
+ } else {
+ back = r;
+ if(back) {
+ while(back->l) back = back->l;
+ }
+ }
+ $? "- sorted_find_next_node PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/** Find last node in a tree storage.
+ @param n Node to start search from.
+ @return Last node or NULL.
+*/
+static dk4_sto_node_t *
+dk4sto_tree_find_last_node(dk4_sto_node_t *n)
+{
+ dk4_sto_node_t *back = NULL;
+ dk4_sto_node_t *c; /* Current node. */
+ dk4_sto_node_t *p; /* Father of c. */
+ $? "+ sorted_find_last_node PTR=%d", TR_IPTR(n)
+ if(n->l) {
+ back = n->l;
+ while(back->r) { back = back->r; }
+ } else {
+ c = n; p = c->p;
+ while(p && (!back)) {
+ if((p->r) == c) {
+ back = p;
+ } else {
+ c = p; p = c->p;
+ }
+ }
+ } $? "- sorted_find_last_node PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/** Find node for object in tree storage (exact search).
+ @param r Root node.
+ @param o Object to find node for.
+ @param s Storage.
+ @return Pointer to node or NULL.
+*/
+static dk4_sto_node_t *
+dk4sto_tree_find_exact(dk4_sto_node_t *r, void const *o, dk4_sto_t *s)
+{
+ dk4_sto_node_t *back = NULL;
+ dk4_sto_node_t testnode; /* Test node for comparisons. */
+ dk4_sto_node_t *c; /* Current node to test. */
+ dk4_sto_node_t *candidate; /* Candidate for found node. */
+ int testval = 0; /* Comparison result. */
+ $? "+ sorted_find_exact PTRS= %d %d %d", TR_IPTR(r), TR_IPTR(o), TR_IPTR(s)
+ dk4sto_node_init_for_object(&testnode, (void *)o, s, s->c);
+ c = dk4sto_tree_find_like(r, &testnode, s, s->c, &candidate);
+ while(c && (!back)) {
+ testval = dk4sto_node_compare(c, &testnode, s, s->c);
+ if(testval == 0) {
+ if((c->o) == o) {
+ back = c;
+ } else {
+ c = dk4sto_tree_find_next_node(c, r);
+ }
+ } else {
+ c = NULL;
+ }
+ } $? "- sorted_find_exact PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/** Remove storage node from tree storage.
+ @param ro Root node.
+ @param n Node to delete.
+ @param st Storage.
+ @param sci ???
+ @param toremove Node to remove.
+ @return New root node.
+*/
+static dk4_sto_node_t *
+dk4sto_tree_remove(
+ dk4_sto_node_t *ro, dk4_sto_node_t *n, dk4_sto_t *st, int *sci,
+ dk4_sto_node_t **toremove
+)
+{
+ dk4_sto_node_t *back;
+ back = dk4sto_avlt_delete(ro,n,st->d,st,sci,toremove);
+ return back;
+}
+
+
+
+/*
+ USE DOUBLE LINKED LIST
+*/
+
+/** Find node for an object evaluated like a given object in a list storage.
+ @param root Root node.
+ @param testnode Node with object for comparison.
+ @param st Storage.
+ @param crit Comparison criteria.
+ @param cand Test candidate.
+ @return Pointer to storage node or NULL.
+*/
+static dk4_sto_node_t *
+dk4sto_list_find_like(
+ dk4_sto_node_t *root, dk4_sto_node_t *testnode, dk4_sto_t *st, int crit,
+ dk4_sto_node_t **cand
+)
+{
+ dk4_sto_node_t *back = NULL;
+ dk4_sto_node_t *c = NULL; /* Current node. */
+ int testval = 0; /* Comparison result. */
+ $? "+ sorted_find_like PTR=%d PTR=%d PTR=%d %d", TR_IPTR(root), TR_IPTR(testnode), TR_IPTR(st), crit
+ c = root;
+ while(c && (!back)) {
+ testval = dk4sto_node_compare(c,testnode,st,crit);
+ switch(testval) {
+ case -1: {
+ if(cand) *cand = c;
+ c = c->r;
+ } break;
+ case 0: {
+ back = c; c = NULL;
+ } break;
+ default : {
+ c = NULL;
+ } break;
+ }
+ } $? "- sorted_find_like PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/** Find node for an object (exact search).
+ @param r Root node.
+ @param o Object.
+ @param s Storage.
+ @return Pointer to the objects node or NULL.
+*/
+static dk4_sto_node_t *
+dk4sto_list_find_exact(dk4_sto_node_t *r, void const *o, dk4_sto_t *s)
+{
+ dk4_sto_node_t *back;
+ $? "+ sorted_find_exact PTRS= %d %d %d", TR_IPTR(r), TR_IPTR(o), TR_IPTR(s)
+ back = dk4sto_unsorted_find_exact(r,o);
+ $? "- sorted_find_exact PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/** Add node to list storage.
+ @param r Root node.
+ @param n New node.
+ @param s Storage.
+ @return Pointer on success, NULL on error.
+*/
+static dk4_sto_node_t *
+dk4sto_list_add(dk4_sto_node_t *r, dk4_sto_node_t *n, dk4_sto_t *s)
+{
+ dk4_sto_node_t *back;
+ dk4_sto_node_t *larger = NULL; /* Last found larger entry. */
+ dk4_sto_node_t *current = NULL; /* Current node. */
+ dk4_sto_node_t *smaller = NULL; /* Last found smaller entry. */
+ int ende;
+ $? "+ sorted_add PTRS= %d %d %d", TR_IPTR(r), TR_IPTR(n), TR_IPTR(s)
+ back = r;
+ if(r) {
+ larger = smaller = NULL;
+ current = r;
+ ende = 0;
+ while(!ende) {
+ if(dk4sto_node_compare(current,n,s,s->c) >= 0) {
+ larger = current; ende = 1;
+ } else {
+ smaller = current;
+ }
+ if(current->r) {
+ current = current->r;
+ } else {
+ ende = 1;
+ }
+ }
+ if(larger) {
+ n->r = larger;
+ larger->l = n;
+ if(smaller) {
+ smaller->r = n;
+ n->l = smaller;
+ } else {
+ back = n;
+ }
+ } else {
+ if(smaller) {
+ smaller->r = n;
+ n->l = smaller;
+ }
+ }
+ } else {
+ back = n;
+ } $? "- sorted_add PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/** Release all nodes of a list storage.
+ @param r Root node.
+*/
+static void
+dk4sto_list_release_all_nodes(dk4_sto_node_t *r)
+{
+ $? "+ sorted_release_all_nodes"
+ dk4sto_unsorted_release_all_nodes(r);
+ $? "- sorted_release_all_nodes"
+}
+
+
+
+/** Find next node.
+ @param n Current node.
+ @param r Root node.
+ @return Pointer to next node or NULL.
+*/
+static dk4_sto_node_t *
+dk4sto_list_find_next_node(dk4_sto_node_t *n, dk4_sto_node_t *r)
+{
+ dk4_sto_node_t *back;
+ $? "+ sorted_find_next_node PTR=%d PTR=%d", TR_IPTR(n), TR_IPTR(r)
+ back = dk4sto_unsorted_find_next_node(n,r);
+ $? "- sorted_find_next_node PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/** Find last (previous) node.
+ @param n Current node.
+ @return Pointer to previous node or NULL.
+*/
+static dk4_sto_node_t *
+dk4sto_list_find_last_node(dk4_sto_node_t *n)
+{
+ dk4_sto_node_t *back;
+ $? "+ sorted_find_last_node PTR=%d", TR_IPTR(n)
+ back = dk4sto_unsorted_find_last_node(n);
+ $? "- sorted_find_last_node PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/** Remove storage node from list storage.
+ @param ro Root node.
+ @param n Node to remove.
+ @param st Storage.
+ @param sci ???
+ @param toremove ???
+*/
+static dk4_sto_node_t *
+dk4sto_list_remove(
+ dk4_sto_node_t *ro, dk4_sto_node_t *n, dk4_sto_t *st, int *sci,
+ dk4_sto_node_t **toremove
+)
+{
+ dk4_sto_node_t *back;
+ $? "+ sorted_remove PTRS= %d %d %d", TR_IPTR(ro), TR_IPTR(n), TR_IPTR(st)
+ back = dk4sto_unsorted_remove(ro,n);
+ $? "- sorted_remove PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+/*
+ COMMON STATIC FUNCTIONS
+*/
+
+
+/** Get object node (traverse storage).
+ @param it Storage iterator.
+ @param o Object to find storage node.
+ @return Pointer to node or NULL.
+*/
+static dk4_sto_node_t *
+dk4sto_traverse_iterators_for(void *it, void *o)
+{
+ dk4_sto_node_t *back = NULL;
+ dk4_sto_it_t *c = NULL; /* Current node. */
+ $? "+ dk4sto_traverse_iterators_for PTR=%d PTR=%d", TR_IPTR(it), TR_IPTR(o)
+ if(it) {
+ c = (dk4_sto_it_t *)it;
+ while(c && (!back)) {
+ if(c->c) {
+ if(((c->c)->o) == o) {
+ back = c->c;
+ }
+ }
+ if(!back) c = c->r;
+ }
+ } $? "- dk4sto_traverse_iterators_for PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/** Find last storage node.
+ @param n Current storage node.
+ @param st Storage.
+ @return Pointer to last node or NULL.
+*/
+static dk4_sto_node_t *
+dk4sto_find_last_node(dk4_sto_node_t *n, dk4_sto_t *st)
+{
+ dk4_sto_node_t *back = NULL;
+ $? "+ dk4sto_find_last_node PTR=%d PTR=%d", TR_IPTR(n), TR_IPTR(st)
+ if(st->h) {
+ if(st->t) {
+ back = dk4sto_tree_find_last_node(n);
+ } else {
+ back = dk4sto_list_find_last_node(n);
+ }
+ } else {
+ back = dk4sto_unsorted_find_last_node(n);
+ }
+ $? "- dk4sto_find_last_node PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/** Initialize storage.
+ @param st Storage to initialize.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static int
+dk4sto_storage_init(dk4_sto_t *st, dk4_er_t *erp)
+{
+ int back = 0;
+ short l = 0; /* Critical path length. */
+ $? "+ dk4sto_storage_init PTR=%d", TR_IPTR(st)
+ /* delpath begin address and length */
+ st->d = NULL; st->l = 0;
+ /* root node */
+ st->r = NULL;
+ /* comparison method */
+ st->h = 0;
+ /* comparison criteria */
+ st->c = 0;
+ /* iterators list */
+ st->i = NULL;
+ st->l = l = 1536;
+ st->d = dk4mem_new(dk4_sto_node_p,l,erp);
+ st->t = 1;
+ if(st->d) {
+ back = 1;
+ } $? "- dk4sto_storage_init %d", back
+ return back;
+}
+
+
+
+/** Close the storage, release memory.
+ @param st Storage to close.
+*/
+static void
+dk4sto_storage_end(dk4_sto_t *st)
+{
+ $? "+ dk4sto_storage_end PTR=%d", TR_IPTR(st)
+ /* release iterators */
+ {
+ dk4_sto_it_t *c = NULL; /* Current iterator. */
+ dk4_sto_it_t *n = NULL; /* Next iterator. */
+ c = (dk4_sto_it_t *)(st->i);
+ st->i = NULL;
+ while(c) {
+ $? ". going to release iterator PTR=%d", TR_IPTR(c)
+ n = c->r;
+ c->r = NULL;
+ c->l = NULL;
+ c->c = NULL;
+ c->s = NULL;
+ dk4mem_free(c) ;
+ c = n;
+ }
+ st->i = NULL;
+ }
+ $? ". iterators released"
+ /* release nodes */
+ {
+ if(st->h) {
+ if(st->t) {
+ dk4sto_tree_release_all_nodes(st->r);
+ } else {
+ dk4sto_list_release_all_nodes(st->r);
+ }
+ } else {
+ dk4sto_unsorted_release_all_nodes(st->r);
+ }
+ st->r = NULL;
+ }
+ $? ". nodes released"
+ /* release delpath */
+ {
+ dk4_sto_node_p *p;
+ p = st->d;
+ dk4mem_free(p);
+ st->d = NULL; st->l = 0;
+ }
+ $? ". delpath released"
+ /* set pointers to NULL */
+ {
+ st->h = 0;
+ st->c = 0;
+ }
+ $? ". function pointers resetted"
+ $? "- dk4sto_storage_end"
+}
+
+
+
+/*
+ PUBLIC INTERFACES
+*/
+
+
+dk4_sto_t *
+dk4sto_open(dk4_er_t *erp)
+{
+ dk4_sto_t *back = NULL;
+ $? "+ dk4sto_open"
+ back = dk4mem_new(dk4_sto_t,1,erp) ;
+ if(back) {
+ if(!dk4sto_storage_init(back,erp)) {
+ dk4mem_free(back);
+ back = NULL;
+ }
+ } $? "- dk4sto_open PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+void
+dk4sto_close(dk4_sto_t *st)
+{
+ $? "+ dk4sto_close PTR=%d", TR_IPTR(st)
+ if(st) {
+ dk4sto_storage_end(st);
+ dk4mem_free(st) ;
+ } $? "- dk4sto_close"
+}
+
+
+
+void
+dk4sto_remove_all(dk4_sto_t *st)
+{
+ if(st) {
+ /* reset all iterators */
+ dk4_sto_it_t *c = NULL; /* Curent iterator. */
+ dk4_sto_it_t *n = NULL; /* Next iterator. */
+ c = (dk4_sto_it_t *)(st->i);
+ while(c) {
+ n = c->r;
+ c->c = NULL;
+ c = n;
+ }
+ /* remove all nodes */
+ if(st->r) {
+ if(st->h) {
+ if(st->t) {
+ dk4sto_tree_release_all_nodes(st->r);
+ } else {
+ dk4sto_list_release_all_nodes(st->r);
+ }
+ } else {
+ dk4sto_unsorted_release_all_nodes(st->r);
+ }
+ }
+ st->r = NULL;
+ }
+}
+
+
+
+int
+dk4sto_remove(dk4_sto_t *st, void *o, dk4_er_t *erp)
+{
+ int back = 0;
+ dk4_sto_node_t *node_to_remove = NULL; /* Node to remove. */
+ dk4_sto_node_t *ln = NULL; /* Last node. */
+ dk4_sto_it_t *iterator = NULL; /* Traverse all iterators. */
+ $? "+ dk4sto_remove PTR=%d PTR=%d", TR_IPTR(st), TR_IPTR(o)
+ if(st && o) {
+ node_to_remove = dk4sto_traverse_iterators_for(st->i, o);
+ if(!node_to_remove) {
+ if(st->h) {
+ if(st->t) {
+ node_to_remove = dk4sto_tree_find_exact(st->r,o,st);
+ } else {
+ node_to_remove = dk4sto_list_find_exact(st->r,o,st);
+ }
+ } else {
+ node_to_remove = dk4sto_unsorted_find_exact(st->r,o);
+ }
+ }
+ if(node_to_remove) {
+ back = 1;
+ ln = dk4sto_find_last_node(node_to_remove,st);
+ iterator = (dk4_sto_it_t *)(st->i);
+ while(iterator) {
+ if((iterator->c) == node_to_remove) {
+ iterator->c = ln;
+ }
+ iterator = iterator->r;
+ }
+ if(st->h) {
+ if(st->t) {
+ st->r =
+ dk4sto_tree_remove(st->r,node_to_remove,st,&back,&node_to_remove);
+ } else {
+ st->r =
+ dk4sto_list_remove(st->r,node_to_remove,st,&back,&node_to_remove);
+ }
+ } else {
+ st->r = dk4sto_unsorted_remove(st->r,node_to_remove);
+ }
+ node_to_remove->l = node_to_remove->r = node_to_remove->p = NULL;
+ node_to_remove->o = NULL;
+ dk4mem_free(node_to_remove);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4sto_remove %d", back
+ return back;
+}
+
+
+
+int
+dk4sto_add(dk4_sto_t *st, void *o, dk4_er_t *erp)
+{
+ int back = 0;
+ dk4_sto_node_t *n = NULL; /* New node. */
+ $? "+ dk4sto_add st=PTR:%d o=PTR:%d", TR_IPTR(st), TR_IPTR(o)
+ if(st && o) {
+ n = dk4mem_new(dk4_sto_node_t,1,erp);
+ if(n) {
+ dk4sto_node_init_for_object(n,o,st,st->c);
+ if(st->h) {
+ if(st->t) {
+ st->r = dk4sto_tree_add(st->r, n, st);
+ } else {
+ st->r = dk4sto_list_add(st->r, n, st);
+ }
+ } else {
+ st->r = dk4sto_unsorted_add(st->r, n);
+ }
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4sto_add %d", back
+ return back;
+}
+
+
+
+dk4_sto_it_t *
+dk4sto_it_open(dk4_sto_t *st, dk4_er_t *erp)
+{
+ dk4_sto_it_t *back = NULL;
+ $? "+ dk4sto_it_open PTR=%d", TR_IPTR(st)
+ if(st) {
+ back = dk4mem_new(dk4_sto_it_t,1,erp);
+ if(back) {
+ back->s = st;
+ back->l = NULL;
+ back->r = (dk4_sto_it_t *)(st->i);
+ back->c = NULL;
+ st->i = (void *)back;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }$? "- dk4sto_it_open PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+void
+dk4sto_it_close(dk4_sto_it_t *it)
+{
+ dk4_sto_it_t *l = NULL; /* Left iterator. */
+ dk4_sto_it_t *r = NULL; /* Right iterator. */
+ dk4_sto_t *s = NULL; /* The storage. */
+ $? "+ dk4sto_it_close PTR=%d", TR_IPTR(it)
+ if(it) {
+ s = it->s;
+ l = it->l;
+ r = it->r;
+ if(l) {
+ l->r = r;
+ } else {
+ s->i = (void *)(r);
+ }
+ if(r) {
+ r->l = l;
+ }
+ it->s = NULL;
+ it->l = it->r = NULL;
+ it->c = NULL;
+ dk4mem_free(it) ;
+ } $? "- dk4sto_it_close"
+}
+
+
+
+void
+dk4sto_it_reset(dk4_sto_it_t *it)
+{
+ $? "+ dk4sto_it_reset PTR=%d", TR_IPTR(it)
+ if(it) {
+ it->c = NULL;
+ } $? "- dk4sto_it_reset"
+}
+
+
+
+void *
+dk4sto_it_next(dk4_sto_it_t *it)
+{
+ void *back = NULL;
+ $? "+ dk4sto_it_next PTR=%d", TR_IPTR(it)
+ if(it) {
+ if(it->s) {
+ if((it->s)->h) {
+ if((it->s)->t) {
+ it->c = dk4sto_tree_find_next_node(it->c, (it->s)->r);
+ } else {
+ it->c = dk4sto_list_find_next_node(it->c, (it->s)->r);
+ }
+ } else {
+ it->c = dk4sto_unsorted_find_next_node(it->c, (it->s)->r);
+ }
+ if(it->c) {
+ back = (it->c)->o;
+ }
+ }
+ } $? "- dk4sto_it_next PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+void *
+dk4sto_it_find_exact(dk4_sto_it_t *i, void const *o)
+{
+ void *back = NULL;
+ $? "+ dk4sto_it_find_exact i=PTR:%d o=PTR:%d", TR_IPTR(i), TR_IPTR(o)
+ if(i && o) {
+ if(i->s) {
+ if((i->s)->h) {
+ if((i->s)->t) {
+ i->c = dk4sto_tree_find_exact((i->s)->r, o, i->s);
+ } else {
+ i->c = dk4sto_list_find_exact((i->s)->r, o, i->s);
+ }
+ } else {
+ i->c = dk4sto_unsorted_find_exact((i->s)->r, o);
+ }
+ }
+ if(i->c) {
+ back = (i->c)->o;
+ }
+ } $? "- dk4sto_it_find_exact PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+void *
+dk4sto_it_find_like(dk4_sto_it_t *i, void const *o, int cr)
+{
+ void *back = NULL;
+ dk4_sto_node_t testnode; /* Test node for comparisons. */
+ dk4_sto_node_t *candidate = NULL; /* Candicate node. */
+ $? "+ dk4sto_it_find_like i=PTR:%d o=PTR:%d %d", TR_IPTR(i), TR_IPTR(o), cr
+ if(i && o) {
+ if(i->s) {
+ candidate = NULL;
+ if((i->s)->h) {
+ dk4sto_node_init_for_object(&testnode, (void *)o, (i->s), cr);
+ if((i->s)->t) {
+ i->c =
+ dk4sto_tree_find_like((i->s)->r, &testnode, i->s, cr, &candidate);
+ } else {
+ i->c =
+ dk4sto_list_find_like((i->s)->r, &testnode, i->s, cr, &candidate);
+ }
+ } else {
+ i->c = dk4sto_unsorted_find_exact((i->s)->r, o);
+ }
+ if(i->c) {
+ back = (i->c)->o;
+ } else {
+ i->c = candidate;
+ }
+ }
+ } $? "- dk4sto_it_find_like PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+int
+dk4sto_set_eval_c(dk4_sto_t *st, dk4_fct_eval_c_t *f, int cr)
+{
+ int back = 0;
+ $? "+ dk4sto_set_eval_c st=PTR:%d f=PTR:%d %d", TR_IPTR(st), TR_IPTR(f), cr
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).c = f;
+ st->c = cr;
+ st->h = DK4STO_COMPARE_CHAR;
+ }
+ } $? "- dk4sto_set_eval_c %d", back
+ return back;
+}
+
+
+
+int
+dk4sto_set_eval_uc(dk4_sto_t *st, dk4_fct_eval_uc_t *f, int cr)
+{
+ int back = 0;
+ $? "+ dk4sto_set_eval_uc st=PTR:%d f=PTR:%d %d", TR_IPTR(st), TR_IPTR(f), cr
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).uc = f;
+ st->c = cr;
+ st->h = DK4STO_COMPARE_UCHAR;
+ }
+ } $? "- dk4sto_set_eval_uc %d", back
+ return back;
+}
+
+
+
+int
+dk4sto_set_eval_s(dk4_sto_t *st, dk4_fct_eval_s_t *f, int cr)
+{
+ int back = 0;
+ $? "+ dk4sto_set_eval_s st=PTR:%d f=PTR:%d %d", TR_IPTR(st), TR_IPTR(f), cr
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).s = f;
+ st->c = cr;
+ st->h = DK4STO_COMPARE_SHORT;
+ }
+ } $? "- dk4sto_set_eval_s %d", back
+ return back;
+}
+
+
+
+int
+dk4sto_set_eval_us(dk4_sto_t *st, dk4_fct_eval_us_t *f, int cr)
+{
+ int back = 0;
+ $? "+ dk4sto_set_eval_us %s %s %d", TR_PTR(st), TR_PTR(f), cr
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).us = f;
+ st->c = cr;
+ st->h = DK4STO_COMPARE_USHORT;
+ }
+ } $? "- dk4sto_set_eval_us %d", back
+ return back;
+}
+
+
+
+int
+dk4sto_set_eval_i(dk4_sto_t *st, dk4_fct_eval_i_t *f, int cr)
+{
+ int back = 0;
+ $? "+ dk4sto_set_eval_i st=PTR:%d f=PTR:%d %d", TR_IPTR(st), TR_IPTR(f), cr
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).i = f;
+ st->c = cr;
+ st->h = DK4STO_COMPARE_INT;
+ }
+ } $? "- dk4sto_set_eval_i %d", back
+ return back;
+}
+
+
+
+int
+dk4sto_set_eval_ui(dk4_sto_t *st, dk4_fct_eval_ui_t *f, int cr)
+{
+ int back = 0;
+ $? "+ dk4sto_set_eval_ui st=PTR:%d f=PTR:%d %d", TR_IPTR(st), TR_IPTR(f), cr
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).ui = f;
+ st->c = cr;
+ st->h = DK4STO_COMPARE_UINT;
+ }
+ } $? "- dk4sto_set_eval_ui %d", back
+ return back;
+}
+
+
+
+int
+dk4sto_set_eval_l(dk4_sto_t *st, dk4_fct_eval_l_t *f, int cr)
+{
+ int back = 0;
+ $? "+ dk4sto_set_eval_l st=PTR:%d f=PTR:%d %d", TR_IPTR(st), TR_IPTR(f), cr
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).l = f;
+ st->c = cr;
+ st->h = DK4STO_COMPARE_LONG;
+ }
+ } $? "- dk4sto_set_eval_l %d", back
+ return back;
+}
+
+
+
+int
+dk4sto_set_eval_ul(dk4_sto_t *st, dk4_fct_eval_ul_t *f, int cr)
+{
+ int back = 0;
+ $? "+ dk4sto_set_eval_ul st=PTR:%d f=PTR:%d %d", TR_IPTR(st), TR_IPTR(f), cr
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).ul = f;
+ st->c = cr;
+ st->h = DK4STO_COMPARE_ULONG;
+ }
+ } $? "- dk4sto_set_eval_ul %d", back
+ return back;
+}
+
+
+
+int
+dk4sto_set_eval_f(dk4_sto_t *st, dk4_fct_eval_f_t *f, int cr)
+{
+ int back = 0;
+ $? "+ dk4sto_set_eval_f st=PTR:%d f=PTR:%d %d", TR_IPTR(st), TR_IPTR(f), cr
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).f = f;
+ st->c = cr;
+ st->h = DK4STO_COMPARE_FLOAT;
+ }
+ } $? "- dk4sto_set_eval_f %d", back
+ return back;
+}
+
+
+
+int
+dk4sto_set_eval_d(dk4_sto_t *st, dk4_fct_eval_d_t *f, int cr)
+{
+ int back = 0;
+ $? "+ dk4sto_set_eval_d st=PTR:%d f=PTR:%d %d", TR_IPTR(st), TR_IPTR(f), cr
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).d = f;
+ st->c = cr;
+ st->h = DK4STO_COMPARE_DOUBLE;
+ }
+ } $? "- dk4sto_set_eval_d %d", back
+ return back;
+}
+
+
+
+int
+dk4sto_set_comp(dk4_sto_t *st, dk4_fct_comp_t *f, int cr)
+{
+ int back = 0;
+ $? "+ dk4sto_set_eval_d st=PTR:%d f=PTR:%d %d", TR_IPTR(st), TR_IPTR(f), cr
+ if(st) {
+ if(!(st->r)) {
+ back = 1;
+ (st->e).comp = f;
+ st->c = cr;
+ st->h = DK4STO_COMPARE_FCT;
+ }
+ } $? "- dk4sto_set_eval_d %d", back
+ return back;
+}
+
+
+
+int
+dk4sto_use_trees(dk4_sto_t *st,int ok)
+{
+ int back = 0;
+ if(st) {
+ if(!(st->r)) {
+ st->t = (ok ? 1 : 0);
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+void *
+dk4sto_find_root(dk4_sto_t *s)
+{
+ void *back = NULL;
+ if(s) {
+ if(s->r) {
+ back = (s->r)->o;
+ }
+ }
+ return back;
+}
+
+
+
+void *
+dk4sto_it_find_parent(dk4_sto_it_t *i)
+{
+ void *back = NULL;
+ if(i) {
+ if(i->c) {
+ if((i->c)->p) {
+ back = ((i->c)->p)->o;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void *
+dk4sto_it_find_left(dk4_sto_it_t *i)
+{
+ void *back = NULL;
+ if(i) {
+ if(i->c) {
+ if((i->c)->l) {
+ back = ((i->c)->l)->o;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void *
+dk4sto_it_find_right(dk4_sto_it_t *i)
+{
+ void *back = NULL;
+ if(i) {
+ if(i->c) {
+ if((i->c)->r) {
+ back = ((i->c)->r)->o;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void *
+dk4sto_it_find_root(dk4_sto_it_t *i)
+{
+ void *back = NULL;
+ if(i) {
+ if(i->s) {
+ back = dk4sto_find_root(i->s);
+ }
+ }
+ return back;
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dk4sto.h b/support/dktools/dk4sto.h
new file mode 100644
index 0000000000..392ae59210
--- /dev/null
+++ b/support/dktools/dk4sto.h
@@ -0,0 +1,483 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4sto.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4STO_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4STO_H_INCLUDED 1
+
+
+#line 10 "dk4sto.ctr"
+
+/** @file
+ Sorted and unsorted data storage in
+ AVL trees or double linked lists.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+/** Evaluation result for an object.
+*/
+typedef union {
+ double d; /**< Evaluation to double. */
+ float f; /**< Evaluation to float. */
+ long l; /**< Evaluation to long. */
+ unsigned long ul; /**< Evaluation to unsigned long. */
+ int i; /**< Evaluation to int. */
+ unsigned int ui; /**< Evaluation to unsigned int. */
+ short s; /**< Evaluation to short. */
+ unsigned short us; /**< Evaluation to unsigned short. */
+ char c; /**< Evaluation to char. */
+ unsigned char uc; /**< Evaluation to unsigned char. */
+} dk4_object_eval_res_t;
+
+
+
+/** Internal node for dk4_sto_t.
+ This structure is used internally by the dksto module.
+*/
+struct dk4__sto__node {
+ dk4_object_eval_res_t v; /**< Object evaluation of @a o. */
+ struct dk4__sto__node *p; /**< Parent node in tree. */
+ struct dk4__sto__node *l; /**< Left child (tree) or neighbour (list). */
+ struct dk4__sto__node *r; /**< Right child (tree) or neighbour (list). */
+ void *o; /**< Object to store. */
+ short b; /**< Balance flag (used in tree only). */
+ short w; /**< Direction to walk. */
+};
+
+/** Internal node for dk4_sto_t.
+*/
+typedef struct dk4__sto__node dk4_sto_node_t;
+
+/** Pointer to internal node for dk4_sto_t.
+*/
+typedef dk4_sto_node_t *dk4_sto_node_p;
+
+
+
+/** Evaluation functions.
+ These function type are used to evaluate and compare objects
+ stored in a sorted dk4_sto_t.
+*/
+
+/** Object evaluation function for sorted storage.
+*/
+typedef char dk4_fct_eval_c_t(void const *obj, int crit);
+
+/** Object evaluation function for sorted storage.
+*/
+typedef unsigned char dk4_fct_eval_uc_t(void const *obj, int crit);
+
+/** Object evaluation function for sorted storage.
+*/
+typedef short dk4_fct_eval_s_t(void const *obj, int crit);
+
+/** Object evaluation function for sorted storage.
+*/
+typedef unsigned short dk4_fct_eval_us_t(void const *obj, int crit);
+
+/** Object evaluation function for sorted storage.
+*/
+typedef int dk4_fct_eval_i_t(void const *obj, int crit);
+
+/** Object evaluation function for sorted storage.
+*/
+typedef unsigned int dk4_fct_eval_ui_t(void const *obj, int crit);
+
+/** Object evaluation function for sorted storage.
+*/
+typedef long dk4_fct_eval_l_t(void const *obj, int crit);
+
+/** Object evaluation function for sorted storage.
+*/
+typedef unsigned long dk4_fct_eval_ul_t(void const *obj, int crit);
+
+/** Object evaluation function for sorted storage.
+*/
+typedef float dk4_fct_eval_f_t(void const *obj, int crit);
+
+/** Object evaluation function for sorted storage.
+*/
+typedef double dk4_fct_eval_d_t(void const *obj, int crit);
+
+/** Object comparison function for sorted storage.
+ When comparing to objects while inserting a new object into
+ a storage both @a o1 and @a o2 are object pointers.
+ When this function is called from dk4sto_it_find_like() the
+ @a o1 argument is an object pointer from the storage,
+ @a o2 is the pointer passed to dk4sto_it_find_like().
+*/
+typedef int dk4_fct_comp_t(void const *o1, void const *o2, int crit);
+
+
+
+/** Choice for object evaluation function.
+*/
+typedef union {
+ dk4_fct_eval_c_t *c; /**< Evaluate to char. */
+ dk4_fct_eval_uc_t *uc; /**< Evaluate to unsigned char. */
+ dk4_fct_eval_s_t *s; /**< Evaluate to short. */
+ dk4_fct_eval_us_t *us; /**< Evaluate to unsigned short. */
+ dk4_fct_eval_i_t *i; /**< Evaluate to int. */
+ dk4_fct_eval_ui_t *ui; /**< Evaluate to unsigned int. */
+ dk4_fct_eval_l_t *l; /**< Evaluate to long. */
+ dk4_fct_eval_ul_t*ul; /**< Evaluate to unsigned long. */
+ dk4_fct_eval_f_t *f; /**< Evaluate to float. */
+ dk4_fct_eval_d_t *d; /**< Evaluate to double. */
+ dk4_fct_comp_t *comp; /**< Compare two objects. */
+} dk4_object_eval_fct_t;
+
+
+
+/** Object storage.
+ A storage can be used to store pointers to objects.
+*/
+typedef struct dk4__sto__t {
+ dk4_object_eval_fct_t e; /**< Comparison or evaluation function. */
+ dk4_sto_node_p *d; /**< Critical path for delete operations. */
+ dk4_sto_node_t *r; /**< Tree root or start of list. */
+ void *i; /**< Double-linked list of iterators. */
+ int h; /**< Selection for comparison or evaluation. */
+ int c; /**< Comparison or evaluation criteria. */
+ int t; /**< Flag: Use tree, 1=tree, 0=list. */
+ short l; /**< Path length of critical path. */
+} dk4_sto_t;
+
+
+
+/** Storage iterator.
+ This structure can be used to iterate through a dk4_sto_t.
+*/
+struct dk4__sto__iterator {
+ struct dk4__sto__iterator *l; /**< Left neighbour (preceeding iterator). */
+ struct dk4__sto__iterator *r; /**< Right neighbour (following iterator). */
+ dk4_sto_t *s; /**< Owner storage. */
+ dk4_sto_node_t *c; /**< Current node, current position. */
+};
+
+/** Storage iterator. Can be used to iterate through a dk4_sto_t.
+*/
+typedef struct dk4__sto__iterator dk4_sto_it_t;
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Create new storage.
+ @param erp Error report, may be NULL.
+ @return Pointer to new storage on succcess, NULL on error.
+ Use dk4sto_close() to destroy the storage when done with it.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if elsize or nelem is 0,
+ - DK4_E_MATH_OVERFLOW<br>
+ on numeric overflow when calculating the
+ product of elsize and nelem,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available.
+*/
+dk4_sto_t *
+dk4sto_open(dk4_er_t *erp);
+
+/** Destroy storage, release memory.
+ @param st Storage to destroy.
+*/
+void
+dk4sto_close(dk4_sto_t *st);
+
+/** Remove all pointers from a storage.
+ @param st Storage.
+*/
+void
+dk4sto_remove_all(dk4_sto_t *st);
+
+/** Remove one pointer from storage.
+ @param st Storage.
+ @param o Object pointer to remove.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error (not found).
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if st or o is NULL,
+ - DK4_E_NOT_FOUND
+ if o was not found in st.
+*/
+int
+dk4sto_remove(dk4_sto_t *st, void *o, dk4_er_t *erp);
+
+/** Add object pointer to storage.
+ @param st Storage.
+ @param o Object pointer to add.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error (not enough memory).
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if st or os is NULL,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available.
+*/
+int
+dk4sto_add(dk4_sto_t *st, void *o, dk4_er_t *erp);
+
+/** Create iterator for storage.
+ @param st Storage.
+ @param erp Error report, may be NULL.
+ @return Pointer to new iterator on success, NULL on error.
+ Use dk4sto_it_close() to destroy the iterator when done with it.
+ When closing/destroying a storage all iterators for that
+ storage are destroyed automatically.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if st is NULL,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available.
+*/
+dk4_sto_it_t *
+dk4sto_it_open(dk4_sto_t *st, dk4_er_t *erp);
+
+/** Destroy iterator.
+ @param it Iterator to destroy.
+*/
+void
+dk4sto_it_close(dk4_sto_it_t *it);
+
+/** Reset iterator (next call to dk4sto_it_next() will return the
+ first object pointer.
+ @param it Iterator.
+*/
+void
+dk4sto_it_reset(dk4_sto_it_t *it);
+
+/** Return next object pointer.
+ @param it Iterator.
+ @return Pointer to next object on success, NULL on error
+ (no more pointers available).
+*/
+void *
+dk4sto_it_next(dk4_sto_it_t *it);
+
+/** Find a pointer exactly.
+ @param i Iterator.
+ @param o Object pointer.
+ @return Object pointer on success, NULL on error (object not found).
+ The next calls to dk4sto_it_next() will return pointers to objects
+ after the specified object \a o.
+*/
+void *
+dk4sto_it_find_exact(dk4_sto_it_t *i, void const *o);
+
+/** Find object pointer for object evaluating equally to \a o.
+ @param i Iterator.
+ @param o Object pointer.
+ @param cr Comparison criteria.
+ @return Object pointer on success, NULL on error (no such object).
+*/
+void *
+dk4sto_it_find_like(dk4_sto_it_t *i, void const *o, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to a char.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4sto_set_eval_c(dk4_sto_t *st, dk4_fct_eval_c_t *f, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to an unsigned char.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4sto_set_eval_uc(dk4_sto_t *st, dk4_fct_eval_uc_t *f, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to a short.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4sto_set_eval_s(dk4_sto_t *st, dk4_fct_eval_s_t *f, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to an unsigned short.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4sto_set_eval_us(dk4_sto_t *st, dk4_fct_eval_us_t *f, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to an int.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4sto_set_eval_i(dk4_sto_t *st, dk4_fct_eval_i_t *f, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to an unsigned int.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4sto_set_eval_ui(dk4_sto_t *st, dk4_fct_eval_ui_t *f, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to a long.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4sto_set_eval_l(dk4_sto_t *st, dk4_fct_eval_l_t *f, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to an unsigned long.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4sto_set_eval_ul(dk4_sto_t *st, dk4_fct_eval_ul_t *f, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to a float.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4sto_set_eval_f(dk4_sto_t *st, dk4_fct_eval_f_t *f, int cr);
+
+/** Set evaluation function.
+ @param st Storage.
+ @param f Function evaluating a pointer to a double.
+ @param cr Evaluation criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4sto_set_eval_d(dk4_sto_t *st, dk4_fct_eval_d_t *f, int cr);
+
+/** Set comparison function.
+ @param st Storage.
+ @param f Function comparing two object pointers.
+ @param cr Comparison criteria.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4sto_set_comp(dk4_sto_t *st, dk4_fct_comp_t *f, int cr);
+
+/** Allow use of tree structures.
+ This function must be called before adding any data.
+ @param st Storage.
+ @param ok Flag: Trees may be used.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4sto_use_trees(dk4_sto_t *st,int ok);
+
+/** Find object pointer at the trees root.
+ @param s Storage.
+*/
+void *
+dk4sto_find_root(dk4_sto_t *s);
+
+/** Find object pointer for the parent node
+ of the last found object.
+ @param i Iterator.
+ @return Object pointer on success, NULL on error.
+*/
+void *
+dk4sto_it_find_parent(dk4_sto_it_t *i);
+
+/** Find object pointer for node on left child of the last found object.
+ @param i Iterator.
+ @return Object pointer on success, NULL on error.
+*/
+void *
+dk4sto_it_find_left(dk4_sto_it_t *i);
+
+/** Find object pointer for node on right child of the last found object.
+ @param i Iterator.
+ @return Object pointer on success, NULL on error.
+*/
+void *
+dk4sto_it_find_right(dk4_sto_it_t *i);
+
+/** Find object pointer at the trees root.
+ @param i Iterator.
+*/
+void *
+dk4sto_it_find_root(dk4_sto_it_t *i);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4str.c b/support/dktools/dk4str.c
new file mode 100644
index 0000000000..cace727448
--- /dev/null
+++ b/support/dktools/dk4str.c
@@ -0,0 +1,222 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4str.ctr
+*/
+
+/*
+Copyright (C) 2014, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4str.c The dk4str module.
+*/
+
+
+#line 196 "dk4str.ctr"
+
+
+#include "dk4str.h"
+
+
+
+int
+dk4str_cpy_s(dkChar *dst, size_t sz, const dkChar *src, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_cpy_s(dst, sz, src, erp));
+#else
+ return (dk4str8_cpy_s(dst, sz, src, erp));
+#endif
+}
+
+
+
+int
+dk4str_cat_s(dkChar *dst, size_t sz, const dkChar *src, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_cat_s(dst, sz, src, erp));
+#else
+ return (dk4str8_cat_s(dst, sz, src, erp));
+#endif
+}
+
+
+
+void
+dk4str_cpy_to_left(dkChar *dst, const dkChar *src)
+{
+#if DK4_CHAR_SIZE > 1
+ dk4strw_cpy_to_left(dst, src);
+#else
+ dk4str8_cpy_to_left(dst, src);
+#endif
+}
+
+
+
+size_t
+dk4str_len(const dkChar *src)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_len(src));
+#else
+ return (dk4str8_len(src));
+#endif
+}
+
+
+
+int
+dk4str_cmp(const dkChar *s1, const dkChar *s2)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_cmp(s1, s2));
+#else
+ return (dk4str8_cmp(s1, s2));
+#endif
+}
+
+
+
+int
+dk4str_casecmp(const dkChar *s1, const dkChar *s2)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_casecmp(s1, s2));
+#else
+ return (dk4str8_casecmp(s1, s2));
+#endif
+}
+
+
+
+dkChar *
+dk4str_sep(dkChar **stringp, const dkChar *delim)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_sep(stringp, delim));
+#else
+ return (dk4str8_sep(stringp, delim));
+#endif
+}
+
+
+
+dkChar *
+dk4str_start(const dkChar *src, const dkChar *delim)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_start(src, delim));
+#else
+ return (dk4str8_start(src, delim));
+#endif
+}
+
+
+
+dkChar *
+dk4str_next(dkChar *src, const dkChar *delim)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_next(src, delim));
+#else
+ return (dk4str8_next(src, delim));
+#endif
+}
+
+
+
+size_t
+dk4str_tokenize(
+ dkChar **dpp, size_t szdpp, dkChar *src, const dkChar *delim, dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_tokenize(dpp, szdpp, src, delim, erp));
+#else
+ return (dk4str8_tokenize(dpp, szdpp, src, delim, erp));
+#endif
+}
+
+
+
+void
+dk4str_normalize(dkChar *src, const dkChar *delim)
+{
+#if DK4_CHAR_SIZE > 1
+ dk4strw_normalize(src, delim);
+#else
+ dk4str8_normalize(src, delim);
+#endif
+}
+
+
+
+#if (defined(_WIN32) && DK4_USE_WINDOWS_LOCAL_ALLOC) \
+ || (DK4_HAVE_MALLOC && DK4_HAVE_FREE)
+
+dkChar *
+dk4str_dup(const dkChar *src, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_dup(src, erp));
+#else
+ return (dk4str8_dup(src, erp));
+#endif
+}
+
+#endif
+/* if (defined(_WIN32) ... */
+
+
+
+int
+dk4str_array_index(const dkChar * const *arr, const dkChar *str, int cs)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_array_index(arr, str, cs));
+#else
+ return (dk4str8_array_index(arr, str, cs));
+#endif
+}
+
+
+
+int
+dk4str_is_abbr(const dkChar *str, const dkChar *pattern, dkChar spec, int cs)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_is_abbr(str, pattern, spec, cs));
+#else
+ return (dk4str8_is_abbr(str, pattern, spec, cs));
+#endif
+}
+
+
+
diff --git a/support/dktools/dk4str8.c b/support/dktools/dk4str8.c
new file mode 100644
index 0000000000..a529edb081
--- /dev/null
+++ b/support/dktools/dk4str8.c
@@ -0,0 +1,981 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4str8.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4str8.c The dk4str8 module.
+*/
+
+
+#line 402 "dk4str8.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS && (DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT)
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4str8.h"
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_CTYPE_H
+#ifndef CTYPE_H_INCLUDED
+#include <ctype.h>
+#define CTYPE_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef DK4NUMCO_H_INCLUDED
+#include "dk4numco.h"
+#endif
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4MEMRS_H_INCLUDED
+#include "dk4memrs.h"
+#endif
+
+
+
+
+#line 442 "dk4str8.ctr"
+
+
+
+/** Constant strings used in the module.
+*/
+static const char * const dk4str8_modkw[] = {
+/* 0 */
+" \t\r\n",
+
+NULL
+
+
+#line 454 "dk4str8.ctr"
+};
+
+
+
+/** First index of a keyword indicating true in the
+ dk4str8_boolkw array below.
+*/
+#define DK4STR8_FIRST_TRUE 5
+
+/** Keywords for boolean values.
+*/
+static const char * const dk4str8_boolkw[] = {
+/* 0 */
+"-",
+
+/* 1 */
+"0",
+
+/* 2 */
+"n$o",
+
+/* 3 */
+"of$f",
+
+/* 4 */
+"f$alse",
+
+/* 5 */
+"+",
+
+/* 6 */
+"1",
+
+/* 7 */
+"y$es",
+
+/* 8 */
+"on",
+
+/* 9 */
+"t$rue",
+
+/* 10 */
+"ok",
+
+NULL
+
+
+#line 485 "dk4str8.ctr"
+};
+
+
+
+/** Number of significant digits.
+*/
+static const int dk4str8_dbl_digits = DK4_DBL_DIGITS;
+
+
+void
+dk4str8_cpy_to_left(char *dst, const char *src)
+{
+ register char *dptr;
+ register const char *sptr;
+ if (NULL != dst) {
+ *dst = '\0';
+ if (NULL != src) {
+ dptr = dst; sptr = src;
+ while('\0' != *sptr) { *(dptr++) = *(sptr++); }
+ *dptr = '\0';
+ }
+ }
+}
+
+
+
+size_t
+dk4str8_len(const char *src)
+{
+ if (NULL == src) {
+ return 0;
+ }
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ return ((size_t)lstrlenA(src));
+#else
+ return (strlen(src));
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+ return (strlen(src));
+ /* --- non-Windows */
+#endif
+}
+
+
+
+char
+dk4str8_toupper(char c)
+{
+#if DK4_ON_WINDOWS
+#if DK4_WIN_DENY_CRT
+ char back;
+ back = c;
+ if (('a' <= c) && ('z' >= c)) {
+ back = 'A' + (c - 'a');
+ }
+ return back;
+#else
+ return (char)toupper((unsigned char)c);
+#endif
+#else
+ return (char)toupper((unsigned char)c);
+#endif
+}
+
+
+
+char
+dk4str8_tolower(char c)
+{
+#if DK4_ON_WINDOWS
+#if DK4_WIN_DENY_CRT
+ char back;
+ back = c;
+ if (('A' <= c) && ('Z' >= c)) {
+ back = 'a' + (c - 'A');
+ }
+ return back;
+#else
+ return (char)tolower((unsigned char)c);
+#endif
+#else
+ return (char)tolower((unsigned char)c);
+#endif
+}
+
+
+
+char *
+dk4str8_chr(const char *s, char c)
+{
+ if (NULL == s) { return NULL; }
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_DENY_CRT
+ {
+ char *back = NULL;
+ while (('\0' != *s) && (NULL == back)) {
+ if (c == *s) {
+ back = (char *)s;
+ } else {
+ s++;
+ }
+ }
+ return back;
+ }
+#else
+ return (strchr(s, (int)((unsigned char)c)));
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+ return (strchr(s, (int)((unsigned char)c)));
+ /* --- non-Windows */
+#endif
+}
+
+
+
+char *
+dk4str8_rchr(const char *s, char c)
+{
+ if (NULL == s) { return NULL; }
+#if DK4_ON_WINDOWS
+#if DK4_WIN_DENY_CRT
+ {
+ char *back = NULL;
+ while ('\0' != *s) {
+ if (c == *s) {
+ back = (char *)s;
+ }
+ s++;
+ }
+ return back;
+ }
+#else
+ return (strrchr(s, (int)((unsigned char)c)));
+#endif
+#else
+ return (strrchr(s, (int)((unsigned char)c)));
+#endif
+}
+
+
+
+int
+dk4str8_cpy_s(char *dst, size_t sz, const char *src, dk4_er_t *erp)
+{
+ int back = 0;
+ if ((NULL != dst) && (0 < sz)) {
+ *dst = '\0';
+ if (NULL != src) {
+ if (dk4str8_len(src) < sz) {
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ (void)lstrcpyA(dst, (char *)src);
+#else
+#pragma warning (disable:4996)
+ (void)strcpy(dst, src);
+#pragma warning (default:4996)
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+ (void)strcpy(dst, src);
+ /* --- non-Windows */
+#endif
+ back = 1;
+ } else {
+ *dst = '\0';
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4str8_cat_s(char *dst, size_t sz, const char *src, dk4_er_t *erp)
+{
+ size_t la;
+ size_t lb;
+ int back = 0;
+ if ((NULL != dst) && (0 < sz) && (NULL != src)) {
+ la = dk4str8_len(dst);
+ lb = dk4str8_len(src);
+ if ((SIZE_MAX - la) >= lb) {
+ if ((la + lb) < sz) {
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ (void)lstrcatA(dst, (char *)src);
+#else
+#pragma warning (disable:4996)
+ (void)strcat(dst, src);
+#pragma warning (default:4996)
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+ (void)strcat(dst, src);
+ /* --- non-Windows */
+#endif
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4str8_cmp(const char *s1, const char *s2)
+{
+ int back = 0;
+ if (NULL != s1) {
+ if (NULL != s2) {
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ back = lstrcmpA(s1, s2);
+#else
+ back = strcmp(s1, s2);
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+ back = strcmp(s1, s2);
+ /* --- non-Windows */
+#endif
+ if (0 > back) back = -1;
+ if (0 < back) back = 1;
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != s2) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4str8_ncmp(const char *s1, const char *s2, size_t n)
+{
+ int back = 0;
+ if (NULL != s1) {
+ if (NULL != s2) {
+#if (DK4_ON_WINDOWS && (DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT) ) \
+|| (!(DK4_HAVE_WCSNCMP)) || (!(DK4_HAVE__WCSNCMP))
+ while((0 < n--) && (0 == back)) {
+ if ('\0' == *s1) {
+ if ('\0' == *s2) {
+ n = 0;
+ } else {
+ back = -1;
+ }
+ } else {
+ if ('\0' == *s2) {
+ back = 1;
+ } else {
+ if (*s1 > *s2) {
+ back = 1;
+ } else {
+ if (*s1 < *s2) {
+ back = -1;
+ } else {
+ s1++; s2++;
+ }
+ }
+ }
+ }
+ }
+#else
+ back = strncmp(s1, s2, n);
+ if (-1 > back) back = -1;
+ if ( 1 < back) back = 1;
+#endif
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != s2) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4str8_casecmp(const char *s1, const char *s2)
+{
+ int back = 0;
+ if (NULL != s1) {
+ if (NULL != s2) {
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ back = lstrcmpiA(s1, s2);
+#else
+ back = _stricmp(s1, s2);
+#endif
+ /* --- non-Windows */
+#else
+ /* +++ non-Windows */
+#if DK4_HAVE_STRCASECMP
+ back = strcasecmp(s1, s2);
+#else
+#if DK4_HAVE__STRICMP
+ back = _stricmp(s1, s2);
+#else
+#if DK4_HAVE_STRICMP
+ back = stricmp(s1, s2);
+#else
+#error No function for case-insensitive comparison available!
+#endif
+#endif
+#endif
+ /* --- non-Windows */
+#endif
+ if (0 > back) back = -1;
+ if (0 < back) back = 1;
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != s2) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+#if (defined(_WIN32) && DK4_USE_WINDOWS_LOCAL_ALLOC) \
+ || (DK4_HAVE_MALLOC && DK4_HAVE_FREE)
+
+char *
+dk4str8_dup(const char *src, dk4_er_t *erp)
+{
+ char *back = NULL;
+ size_t lgt;
+ if (NULL != src) {
+ lgt = dk4str8_len(src);
+ if (SIZE_MAX > lgt) {
+ back = dk4mem_malloc_bytes((1+lgt), erp);
+ if (NULL != back) {
+ (void)dk4str8_cpy_s(back, (1+lgt), src, erp);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+#endif
+/* if (defined(_WIN32) ... */
+
+
+
+char *
+dk4str8_start(const char *src, const char *delim)
+{
+ char *back = NULL;
+ if (NULL != src) {
+ if (NULL == delim) { delim = dk4str8_modkw[0]; }
+ while (('\0' != *src) && (NULL == back)) {
+ if (NULL != dk4str8_chr(delim, (unsigned char)(*src))) {
+ src++;
+ } else {
+ back = (char *)src;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Internal function for next token search.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param src String containing tokens, must be set to
+ the start of a token.
+ @param delim Delimiter set.
+ @return Pointer to next token on success, NULL on error.
+*/
+static
+char *
+dk4str8_i_next(char *src, const char *delim)
+{
+ char *back = NULL;
+ if (NULL != src) {
+ if (NULL == delim) { delim = dk4str8_modkw[0]; }
+ while (('\0' != *src) && (NULL == back)) {
+ if (NULL != dk4str8_chr(delim, (unsigned char)(*src))) {
+ back = src;
+ } else {
+ src++;
+ }
+ }
+ if (NULL != back) {
+ *(back++) = '\0';
+ back = dk4str8_start(back, delim);
+ }
+ }
+ return back;
+}
+
+
+
+char *
+dk4str8_next(char *src, const char *delim)
+{
+ char *back = NULL;
+ if (NULL != src) {
+ back = dk4str8_start(src, delim);
+ if (NULL != back) {
+ back = dk4str8_i_next(back, delim);
+ }
+ }
+ return back;
+}
+
+
+
+char *
+dk4str8_sep(char **stringp, const char *delim)
+{
+ char *back = NULL;
+
+
+#line 942 "dk4str8.ctr"
+ if (NULL != stringp) {
+ if (NULL != *stringp) {
+ if (NULL == delim) { delim = dk4str8_modkw[0]; }
+ back = dk4str8_start(*stringp, delim);
+ if (NULL != back) {
+ *stringp = dk4str8_next(back, delim);
+ } else {
+ *stringp = NULL;
+ }
+ }
+ }
+
+#line 953 "dk4str8.ctr"
+ return back;
+}
+
+
+
+size_t
+dk4str8_tokenize(
+ char **dpp, size_t szdpp, char *src, const char *delim, dk4_er_t *erp
+)
+{
+ char *context;
+ char *token;
+ size_t back = 0;
+ if ((NULL != dpp) && (0 < szdpp) && (NULL != src)) {
+ if (NULL == delim) { delim = dk4str8_modkw[0]; }
+ context = src;
+ while (NULL != (token = dk4str8_sep(&context, delim))) {
+ if (back < szdpp) {
+ dpp[back] = token;
+ }
+ back++;
+ }
+ if (back >= szdpp) {
+ dk4error_set_elsize_nelem(
+ erp, DK4_E_BUFFER_TOO_SMALL, sizeof(DK4_PCHAR), back
+ );
+ back = 0;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+void
+dk4str8_normalize(char *src, const char *delim)
+{
+ char *p1; /* Pointer to traverse text. */
+ char *p2; /* Start of next token. */
+ int cc; /* Flag: Can continue. */
+
+ if (NULL != src) {
+ /*
+ Set up delimiter set, correct if necessary.
+ */
+ if (NULL == delim) { delim = dk4str8_modkw[0]; }
+ /*
+ Remove leading delimiters.
+ */
+ p1 = src;
+ cc = 0;
+ if ('\0' != *p1) {
+ if (NULL != dk4str8_chr(delim, (unsigned char)(*p1))) {
+ p2 = dk4str8_start(p1, delim);
+ if (NULL != p2) {
+ dk4str8_cpy_to_left(p1, p2);
+ cc = 1;
+ } else {
+ *p1 = '\0';
+ }
+ } else {
+ cc = 1;
+ }
+ }
+ /*
+ Now traverse the string.
+ */
+ while (0 != cc) {
+ if ('\0' == *p1) {
+ cc = 0;
+ } else {
+ if (NULL != dk4str8_chr(delim, (unsigned char)(*p1))) {
+ *p1 = *delim;
+ if ('\0' == p1[1]) {
+ *p1 = '\0';
+ cc = 0;
+ } else {
+ if (NULL != dk4str8_chr(delim, (unsigned char)(p1[1]))) {
+ p2 = dk4str8_start(p1, delim);
+ if (NULL != p2) {
+ dk4str8_cpy_to_left(++p1, p2);
+ } else {
+ *p1 = '\0';
+ cc = 0;
+ }
+ } else {
+ p1++;
+ }
+ }
+ } else {
+ p1++;
+ }
+ }
+ }
+ }
+}
+
+
+
+int
+dk4str8_array_index(const char * const *arr, const char *str, int cs)
+{
+ int back = -1;
+ int cand = 0;
+ if ((NULL != arr) && (NULL != str)) {
+ while((NULL != *arr) && (-1 == back)) {
+ if (0 != cs) {
+ if (0 == dk4str8_cmp(*arr, str)) { back = cand; }
+ } else {
+ if (0 == dk4str8_casecmp(*arr, str)) { back = cand; }
+ }
+ arr++; cand++;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4str8_is_abbr(const char *str, const char *pattern, char spec, int cs)
+{
+ const char *lptr = NULL; /* Pointer to traverse string */
+ const char *pptr = NULL; /* Pointer to traverse pattern */
+ int back = 0; /* Function result */
+ int fspec = 0; /* Flag: spec was found */
+ int cc = 1; /* Flag: Can continue */
+ char cl;
+ char cp;
+
+
+#line 1085 "dk4str8.ctr"
+ if ((NULL != str) && (NULL != pattern)) {
+ lptr = str; pptr = pattern;
+ while (0 != cc) {
+ if ((0 == fspec) && (*pptr == spec)) {
+ fspec = 1;
+ pptr++;
+ } else {
+ if ('\0' != *lptr) {
+ cl = *lptr; cp = *pptr;
+ if (0 == cs) {
+ cl = dk4str8_toupper(cl);
+ cp = dk4str8_toupper(cp);
+ }
+ if (cl == cp) {
+ lptr++;
+ pptr++;
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = 0;
+ if (('\0' == *pptr) || (0 != fspec)) { back = 1; }
+ }
+ }
+ }
+ }
+
+#line 1111 "dk4str8.ctr"
+ return back;
+}
+
+
+
+int
+dk4str8_abbr_index(const char * const *arr, char spec, const char *str, int cs)
+{
+ int back = -1;
+ int cand = 0;
+
+
+#line 1122 "dk4str8.ctr"
+ if ((NULL != arr) && (NULL != str)) {
+ while ((NULL != *arr) && (-1 == back)) {
+ if (0 != dk4str8_is_abbr(str, *arr, spec, cs)) {
+ back = cand;
+ }
+ arr++; cand++;
+ }
+ }
+
+
+#line 1131 "dk4str8.ctr"
+ return back;
+}
+
+
+
+int
+dk4str8_is_bool(const char *str)
+{
+ int back = 0;
+ if (NULL != str) {
+ if (-1 < dk4str8_abbr_index(dk4str8_boolkw, '$', str, 0)) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4str8_is_on(const char *str)
+{
+ int back = 0;
+
+
+#line 1155 "dk4str8.ctr"
+ if (NULL != str) {
+ back = dk4str8_abbr_index(dk4str8_boolkw, '$', str, 0);
+ if (-1 < back) {
+ if (DK4STR8_FIRST_TRUE <= back) {
+ back = 1;
+ } else {
+ back = 0;
+ }
+ } else {
+ back = 0;
+ }
+ }
+
+
+#line 1168 "dk4str8.ctr"
+ return back;
+}
+
+
+
+int
+dk4str8_pathcmp(const char *s1, const char *s2)
+{
+#if DK4_HAVE_CASE_INSENSITIVE_PATHNAMES
+ return (dk4str8_casecmp(s1, s2));
+#else
+ return (dk4str8_cmp(s1, s2));
+#endif
+}
+
+
+
+void
+dk4str8_rtwh(char *str, const char *whsp)
+{
+ char *ptr = NULL;
+ if (NULL == whsp) { whsp = dk4str8_modkw[0]; }
+ if (NULL != str) {
+ while ('\0' != *str) {
+ if (NULL != dk4str8_chr(whsp, *str)) {
+ if (NULL == ptr) { ptr = str; }
+ } else {
+ ptr = NULL;
+ }
+ str++;
+ }
+ if (NULL != ptr) { *ptr = '\0'; }
+ }
+}
+
+
+
+void
+dk4str8_delnl(char *lptr)
+{
+ if (NULL != lptr) {
+ while ('\0' != *lptr) {
+ if ('\n' == *lptr) {
+ *lptr = '\0';
+ } else {
+ if ('\r' == *lptr) {
+ if ('\n' == lptr[1]) {
+ *lptr = '\0';
+ } else {
+ if ('\0' == lptr[1]) {
+ *lptr = '\0';
+ } else {
+ lptr++;
+ }
+ }
+ } else {
+ lptr++;
+ }
+ }
+ }
+ }
+}
+
+
+
+const char *
+dk4str8_skip(const char *line, size_t skip)
+{
+ const char *back = NULL;
+ size_t words = 0; /* Number of words already found */
+ int lwt = 0; /* Flag: Last char was text */
+
+ if (NULL != line) {
+ if (0 < skip) {
+ while((NULL == back) && ('\0' != *line)) {
+ switch (*line) {
+ case ' ': case '\t': case '\n': case '\r': {
+ lwt = 0;
+ } break;
+ default: {
+ if (0 == lwt) {
+ if (++words > skip) {
+ back = line;
+ }
+ }
+ lwt = 1;
+ } break;
+ }
+ line++;
+ }
+ } else {
+ back = dk4str8_start(line, NULL);
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4str8_buffer_sanitize(char *str, size_t sz)
+{
+ int back = 0;
+ if (NULL != str) {
+ if (0 < sz) {
+ back = dk4mem_reset_secure(str, sz, NULL);
+ } else {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4str8_sanitize(char *str)
+{
+ int back = 0;
+ if (NULL != str) {
+ back = dk4str8_buffer_sanitize(str, strlen(str));
+ }
+ return back;
+}
+
+
+
+int
+dk4str8_free_sanitized(char *str)
+{
+ int back = 0;
+ if (NULL != str) {
+ back = dk4str8_sanitize(str);
+ dk4mem_free(str);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4str8.ctr b/support/dktools/dk4str8.ctr
new file mode 100644
index 0000000000..8b5bcd1fa5
--- /dev/null
+++ b/support/dktools/dk4str8.ctr
@@ -0,0 +1,1305 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Additional string functions for
+ 8 bit characters.
+
+ Although some of the functions in this module duplicate
+ functionality from string.h functions, you should use
+ the functions from this module.
+ With DK4DK4_WIN_AVOID_CRT or DK4_WIN_DENY_CRT defined to non-zero
+ these functions call Windows API functions like
+ lstrcmpA() ... instead of CRT functions.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Copy string, check destination buffer size.
+
+ CRT on Windows: Optional.
+ @param dst Destination buffer address.
+ @param sz Destination buffer size.
+ @param src Source string.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dst or src is NULL or sz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the dst buffer is too small.
+*/
+int
+dk4str8_cpy_s(char *dst, size_t sz, const char *src, dk4_er_t *erp);
+
+/** Concatenate strings, check destination buffer size.
+
+ CRT on Windows: Optional.
+ @param dst Destination buffer address.
+ @param sz Destination buffer size.
+ @param src Source string.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dst or src is NULL or sz is 0,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in size calculation,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the concatenated string doest not fit into the buffer.
+*/
+int
+dk4str8_cat_s(char *dst, size_t sz, const char *src, dk4_er_t *erp);
+
+/** Copy characters within a string from right to left.
+ This copy operation is intended for moving characters within
+ one string from right to left, making the string shorter
+ as is. This function does not check buffer size or report
+ any error.
+ For normal string copy operations, use the dk4str8_cpy_s()
+ function instead.
+
+ CRT on Windows: Not used.
+ @param dst Destination buffer address.
+ @param src Source string.
+*/
+void
+dk4str8_cpy_to_left(char *dst, const char *src);
+
+/** Find string length.
+
+ CRT on Windows: Optional.
+ @param src Source string.
+ @return String length.
+*/
+size_t
+dk4str8_len(const char *src);
+
+/** Compare two strings.
+
+ CRT on Windows: Optional.
+ @param s1 Left string, may be NULL.
+ @param s2 Right string, may be NULL.
+ @return 1 if s1>s2, 0 if s1==s2, -1 if s1<s2.
+*/
+int
+dk4str8_cmp(const char *s1, const char *s2);
+
+/** Compare two strings.
+
+ CRT on Windows: Optional, disabling CRT probably degrades performance.
+ @param s1 Left string, may be NULL.
+ @param s2 Right string, may be NULL.
+ @param n Maximum number of characters to compare.
+ @return 1 if s1>s2, 0 if s1==s2, -1 if s1<s2.
+*/
+int
+dk4str8_ncmp(const char *s1, const char *s2, size_t n);
+
+/** Compare two strings, case-insensitive comparison.
+
+ CRT on Windows: Optional.
+ @param s1 Left string, may be NULL.
+ @param s2 Right string, may be NULL.
+ @return 1 if s1>s2, 0 if s1==s2, -1 if s1<s2.
+*/
+int
+dk4str8_casecmp(const char *s1, const char *s2);
+
+/** Compare two file path names.
+
+ CRT on Windows: Optional.
+ @param s1 Left string, may be NULL.
+ @param s2 Right string, may be NULL.
+ @return 1 if s1>s2, 0 if s1==s2, -1 if s1<s2.
+*/
+int
+dk4str8_pathcmp(const char *s1, const char *s2);
+
+/** Find first occurance of character c in string s.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param s String to search for c.
+ @param c Character to find.
+ @return Pointer to first occurance if found, NULL otherwise.
+*/
+char *
+dk4str8_chr(const char *s, char c);
+
+/** Find last occurance of character c in string s.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param s String to search for c.
+ @param c Character to find.
+ @return Pointer to last occurance if found, NULL otherwise.
+*/
+char *
+dk4str8_rchr(const char *s, char c);
+
+/** Retrieve first token from *stringp.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param stringp Adress of string pointer.
+ @param delim String containing the delimiter set,
+ my be NULL to use the default delimiter
+ set (space, tabulator, carriage return and newline).
+ @return Pointer to first token on success, NULL if no (further)
+ token found.
+*/
+char *
+dk4str8_sep(char **stringp, const char *delim);
+
+/** Find first token in string.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param src String to search for tokens.
+ @param delim String containing the delimiter characters,
+ may be NULL to use the default delimiter set.
+ @return Pointer to first token if found, NULL otherwise.
+*/
+char *
+dk4str8_start(const char *src, const char *delim);
+
+/** Cut string after first token, find start of second token in string.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param src String to search for tokens,
+ normally the result of dk4str8_start() or a
+ previous dk4str8_next() call.
+ @param delim String containing the delimiter characters,
+ may be NULL to use the default delimiter set.
+ @return Pointer to second token if found, NULL otherwise.
+*/
+char *
+dk4str8_next(char *src, const char *delim);
+
+/** Split a string into tokens.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param dpp Pointer to string pointer array.
+ @param szdpp Size of destination string pointer array.
+ @param src Source string to process.
+ @param delim String containing delimiter characters,
+ may be NULL to use the default delimiter set.
+ @param erp Error report, may be NULL.
+ @return Number of tokens found on success, 0 if no token
+ found or on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ for invalid function arguments,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ with dt.mem.nelem set to the number of tokens in string if the dpp
+ array is too short.
+*/
+size_t
+dk4str8_tokenize(
+ char **dpp, size_t szdpp, char *src, const char *delim, dk4_er_t *erp
+);
+
+/** Normalize a string (remove leading and trailing delimiters,
+ replace delimiter sequences by just one delimiter).
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param src Buffer containing the string to normalize.
+ @param delim String containing delimiter characters,
+ may be NULL to use the default delimiter set.
+*/
+void
+dk4str8_normalize(char *src, const char *delim);
+
+/** Find index of a string in an array of strings.
+
+ CRT on Windows: Optional.
+ @param arr Array of strings.
+ @param str String to find in array.
+ @param cs Flag: Case-sensitive search (0=no, other=yes).
+ @return Non-negative index value on success, -1 on error.
+*/
+int
+dk4str8_array_index(const char * const *arr, const char *str, int cs);
+
+/** Find index of a string in an array of strings.
+
+ CRT on Windows: Optional, disabling CRT degrades performances
+ and reduces to upper-case conversion to characters 'a' to 'z'.
+ @param arr Array of string allowing abbreviations.
+ @param spec Special character indicating start of optional text.
+ @param str String to find in array.
+ @param cs Flag: Case-sensitive search (0=no, other=yes).
+ @return Non-negative index value on success, -1 on error.
+*/
+int
+dk4str8_abbr_index(const char * const *arr, char spec, const char *str, int cs);
+
+/** Check whether a text matches a pattern, the text may be abbreviated.
+
+ CRT on Windows: Optional, disabling CRT degrades performances
+ and reduces to upper-case conversion to characters 'a' to 'z'
+ in case-insensitive comparisons.
+ @param str Text to check.
+ @param pattern Pattern for comparison.
+ @param spec Special character marking the abbreviation in the
+ pattern.
+ @param cs Flag: Case sensitive (1) or not (0).
+ @return 1 for a match, 0 otherwise.
+*/
+int
+dk4str8_is_abbr(const char *str, const char *pattern, char spec, int cs);
+
+/** Check whether a string represents a boolean value.
+
+ CRT on Windows: Optional, disabling CRT degrades performances.
+ @param str String to check.
+ @return 1 if str represents a boolean value, 0 otherwise.
+*/
+int
+dk4str8_is_bool(const char *str);
+
+/** Check whether a string represents the boolean value TRUE.
+
+ CRT on Windows: Optional, disabling CRT degrades performances.
+ @param str String to check.
+ @return 1 if str represents the boolean value TRUE, 0 otherwise.
+*/
+int
+dk4str8_is_on(const char *str);
+
+#if (defined(_WIN32) && DK4_USE_WINDOWS_LOCAL_ALLOC) \
+ || (DK4_HAVE_MALLOC && DK4_HAVE_FREE)
+
+/** Duplicate string in dynamically allocated memory.
+
+ CRT on Windows: Optional, disabling CRT reduces functionality
+ to strings with length fitting to int and overall size in
+ bytes - including finalizer - fitting into a DWORD.
+ @param src String to duplicate.
+ @param erp Error report, may be NULL.
+ @return Pointer to string in new memory on succes, NULL on error.
+ Use dk4mem_free() to release the memory after usage.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src is a NULL pointer,
+ - DK4_E_MATH_OVERFLOW<br>
+ on mathematical overflow in size calculation,
+ - DK4_E_MEMORY<br>
+ if no memory is available.
+*/
+char *
+dk4str8_dup(const char *src, dk4_er_t *erp);
+
+#endif
+/* if (defined(_WIN32) ... */
+
+/** Remove trailing white spaces.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param str String to remove white spaces from.
+ @param whsp White spaces set.
+*/
+void
+dk4str8_rtwh(char *str, const char *whsp);
+
+/** Convert character to uppercase.
+
+ CRT on Windows: Optional, disabling CRT degrades performances
+ and reduces functionality to characters 'a' to 'z'.
+ @param c Character to convert.
+ @return Conversion result.
+*/
+char
+dk4str8_toupper(char c);
+
+/** Convert character to lowercase.
+
+ CRT on Windows: Optional, disabling CRT degrades performances
+ and reduces functionality to characters 'A' to 'Z'.
+ @param c Character to convert.
+ @return Conversion result.
+*/
+char
+dk4str8_tolower(char c);
+
+/** Remove trailing newline from line.
+ @param lptr Line pointer.
+*/
+void
+dk4str8_delnl(char *lptr);
+
+/** Skip the first text words in a line, return pointer to start
+ of next word.
+ @param line Line to process.
+ @param skip Number of words to skip.
+ @return Pointer to next word on success, NULL on error.
+*/
+const char *
+dk4str8_skip(const char *line, size_t skip);
+
+/** Sanitize string (overwrite using 0 bytes).
+ @param str Address of string to sanitize.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4str8_sanitize(char *str);
+
+/** Sanitize string buffer (overwrite using 0 bytes).
+ @param str Address of string buffer.
+ @param sz Size of string buffer (number of elements).
+ @return 1 on success, 0 on error.
+*/
+int
+dk4str8_buffer_sanitize(char *str, size_t sz);
+
+/** Sanitize dynamically allocated memory and release it.
+ @param str Address of string to sanitize and release.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4str8_free_sanitized(char *str);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/** Sanitize string and release it, set pointer to NULL.
+ @param p Pointer to string to release.
+*/
+#define dk4str8_release_sanitized(p) \
+do { if (NULL != p) { (void)dk4str8_free_sanitized(p); } p = NULL; } while (0)
+
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS && (DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT)
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4str8.h"
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_CTYPE_H
+#ifndef CTYPE_H_INCLUDED
+#include <ctype.h>
+#define CTYPE_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef DK4NUMCO_H_INCLUDED
+#include "dk4numco.h"
+#endif
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#ifndef DK4MEMRS_H_INCLUDED
+#include "dk4memrs.h"
+#endif
+
+
+$!trace-include
+
+
+
+/** Constant strings used in the module.
+*/
+static const char * const dk4str8_modkw[] = {
+$!string-table
+#
+# 0 Default delimiters.
+#
+ \t\r\n
+$!end
+};
+
+
+
+/** First index of a keyword indicating true in the
+ dk4str8_boolkw array below.
+*/
+#define DK4STR8_FIRST_TRUE 5
+
+/** Keywords for boolean values.
+*/
+static const char * const dk4str8_boolkw[] = {
+$!string-table
+#
+# 0...4 false
+#
+-
+0
+n$o
+of$f
+f$alse
+#
+# 5... true
+#
++
+1
+y$es
+on
+t$rue
+ok
+$!end
+};
+
+
+
+/** Number of significant digits.
+*/
+static const int dk4str8_dbl_digits = DK4_DBL_DIGITS;
+
+
+void
+dk4str8_cpy_to_left(char *dst, const char *src)
+{
+ register char *dptr;
+ register const char *sptr;
+ if (NULL != dst) {
+ *dst = '\0';
+ if (NULL != src) {
+ dptr = dst; sptr = src;
+ while('\0' != *sptr) { *(dptr++) = *(sptr++); }
+ *dptr = '\0';
+ }
+ }
+}
+
+
+
+size_t
+dk4str8_len(const char *src)
+{
+ if (NULL == src) {
+ return 0;
+ }
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ return ((size_t)lstrlenA(src));
+#else
+ return (strlen(src));
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+ return (strlen(src));
+ /* --- non-Windows */
+#endif
+}
+
+
+
+char
+dk4str8_toupper(char c)
+{
+#if DK4_ON_WINDOWS
+#if DK4_WIN_DENY_CRT
+ char back;
+ back = c;
+ if (('a' <= c) && ('z' >= c)) {
+ back = 'A' + (c - 'a');
+ }
+ return back;
+#else
+ return (char)toupper((unsigned char)c);
+#endif
+#else
+ return (char)toupper((unsigned char)c);
+#endif
+}
+
+
+
+char
+dk4str8_tolower(char c)
+{
+#if DK4_ON_WINDOWS
+#if DK4_WIN_DENY_CRT
+ char back;
+ back = c;
+ if (('A' <= c) && ('Z' >= c)) {
+ back = 'a' + (c - 'A');
+ }
+ return back;
+#else
+ return (char)tolower((unsigned char)c);
+#endif
+#else
+ return (char)tolower((unsigned char)c);
+#endif
+}
+
+
+
+char *
+dk4str8_chr(const char *s, char c)
+{
+ if (NULL == s) { return NULL; }
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_DENY_CRT
+ {
+ char *back = NULL;
+ while (('\0' != *s) && (NULL == back)) {
+ if (c == *s) {
+ back = (char *)s;
+ } else {
+ s++;
+ }
+ }
+ return back;
+ }
+#else
+ return (strchr(s, (int)((unsigned char)c)));
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+ return (strchr(s, (int)((unsigned char)c)));
+ /* --- non-Windows */
+#endif
+}
+
+
+
+char *
+dk4str8_rchr(const char *s, char c)
+{
+ if (NULL == s) { return NULL; }
+#if DK4_ON_WINDOWS
+#if DK4_WIN_DENY_CRT
+ {
+ char *back = NULL;
+ while ('\0' != *s) {
+ if (c == *s) {
+ back = (char *)s;
+ }
+ s++;
+ }
+ return back;
+ }
+#else
+ return (strrchr(s, (int)((unsigned char)c)));
+#endif
+#else
+ return (strrchr(s, (int)((unsigned char)c)));
+#endif
+}
+
+
+
+int
+dk4str8_cpy_s(char *dst, size_t sz, const char *src, dk4_er_t *erp)
+{
+ int back = 0;
+ if ((NULL != dst) && (0 < sz)) {
+ *dst = '\0';
+ if (NULL != src) {
+ if (dk4str8_len(src) < sz) {
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ (void)lstrcpyA(dst, (char *)src);
+#else
+#pragma warning (disable:4996)
+ (void)strcpy(dst, src);
+#pragma warning (default:4996)
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+ (void)strcpy(dst, src);
+ /* --- non-Windows */
+#endif
+ back = 1;
+ } else {
+ *dst = '\0';
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4str8_cat_s(char *dst, size_t sz, const char *src, dk4_er_t *erp)
+{
+ size_t la;
+ size_t lb;
+ int back = 0;
+ if ((NULL != dst) && (0 < sz) && (NULL != src)) {
+ la = dk4str8_len(dst);
+ lb = dk4str8_len(src);
+ if ((SIZE_MAX - la) >= lb) {
+ if ((la + lb) < sz) {
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ (void)lstrcatA(dst, (char *)src);
+#else
+#pragma warning (disable:4996)
+ (void)strcat(dst, src);
+#pragma warning (default:4996)
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+ (void)strcat(dst, src);
+ /* --- non-Windows */
+#endif
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4str8_cmp(const char *s1, const char *s2)
+{
+ int back = 0;
+ if (NULL != s1) {
+ if (NULL != s2) {
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ back = lstrcmpA(s1, s2);
+#else
+ back = strcmp(s1, s2);
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+ back = strcmp(s1, s2);
+ /* --- non-Windows */
+#endif
+ if (0 > back) back = -1;
+ if (0 < back) back = 1;
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != s2) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4str8_ncmp(const char *s1, const char *s2, size_t n)
+{
+ int back = 0;
+ if (NULL != s1) {
+ if (NULL != s2) {
+#if (DK4_ON_WINDOWS && (DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT) ) \
+|| (!(DK4_HAVE_WCSNCMP)) || (!(DK4_HAVE__WCSNCMP))
+ while((0 < n--) && (0 == back)) {
+ if ('\0' == *s1) {
+ if ('\0' == *s2) {
+ n = 0;
+ } else {
+ back = -1;
+ }
+ } else {
+ if ('\0' == *s2) {
+ back = 1;
+ } else {
+ if (*s1 > *s2) {
+ back = 1;
+ } else {
+ if (*s1 < *s2) {
+ back = -1;
+ } else {
+ s1++; s2++;
+ }
+ }
+ }
+ }
+ }
+#else
+ back = strncmp(s1, s2, n);
+ if (-1 > back) back = -1;
+ if ( 1 < back) back = 1;
+#endif
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != s2) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4str8_casecmp(const char *s1, const char *s2)
+{
+ int back = 0;
+ if (NULL != s1) {
+ if (NULL != s2) {
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ back = lstrcmpiA(s1, s2);
+#else
+ back = _stricmp(s1, s2);
+#endif
+ /* --- non-Windows */
+#else
+ /* +++ non-Windows */
+#if DK4_HAVE_STRCASECMP
+ back = strcasecmp(s1, s2);
+#else
+#if DK4_HAVE__STRICMP
+ back = _stricmp(s1, s2);
+#else
+#if DK4_HAVE_STRICMP
+ back = stricmp(s1, s2);
+#else
+#error No function for case-insensitive comparison available!
+#endif
+#endif
+#endif
+ /* --- non-Windows */
+#endif
+ if (0 > back) back = -1;
+ if (0 < back) back = 1;
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != s2) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+#if (defined(_WIN32) && DK4_USE_WINDOWS_LOCAL_ALLOC) \
+ || (DK4_HAVE_MALLOC && DK4_HAVE_FREE)
+
+char *
+dk4str8_dup(const char *src, dk4_er_t *erp)
+{
+ char *back = NULL;
+ size_t lgt;
+ if (NULL != src) {
+ lgt = dk4str8_len(src);
+ if (SIZE_MAX > lgt) {
+ back = dk4mem_malloc_bytes((1+lgt), erp);
+ if (NULL != back) {
+ (void)dk4str8_cpy_s(back, (1+lgt), src, erp);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+#endif
+/* if (defined(_WIN32) ... */
+
+
+
+char *
+dk4str8_start(const char *src, const char *delim)
+{
+ char *back = NULL;
+ if (NULL != src) {
+ if (NULL == delim) { delim = dk4str8_modkw[0]; }
+ while (('\0' != *src) && (NULL == back)) {
+ if (NULL != dk4str8_chr(delim, (unsigned char)(*src))) {
+ src++;
+ } else {
+ back = (char *)src;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Internal function for next token search.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param src String containing tokens, must be set to
+ the start of a token.
+ @param delim Delimiter set.
+ @return Pointer to next token on success, NULL on error.
+*/
+static
+char *
+dk4str8_i_next(char *src, const char *delim)
+{
+ char *back = NULL;
+ if (NULL != src) {
+ if (NULL == delim) { delim = dk4str8_modkw[0]; }
+ while (('\0' != *src) && (NULL == back)) {
+ if (NULL != dk4str8_chr(delim, (unsigned char)(*src))) {
+ back = src;
+ } else {
+ src++;
+ }
+ }
+ if (NULL != back) {
+ *(back++) = '\0';
+ back = dk4str8_start(back, delim);
+ }
+ }
+ return back;
+}
+
+
+
+char *
+dk4str8_next(char *src, const char *delim)
+{
+ char *back = NULL;
+ if (NULL != src) {
+ back = dk4str8_start(src, delim);
+ if (NULL != back) {
+ back = dk4str8_i_next(back, delim);
+ }
+ }
+ return back;
+}
+
+
+
+char *
+dk4str8_sep(char **stringp, const char *delim)
+{
+ char *back = NULL;
+ $? "+ dk4str8_sep \"%!8s\" \"%!8s\"", TR_8STR(*stringp), TR_8STR(delim)
+ if (NULL != stringp) {
+ if (NULL != *stringp) {
+ if (NULL == delim) { delim = dk4str8_modkw[0]; }
+ back = dk4str8_start(*stringp, delim);
+ if (NULL != back) {
+ *stringp = dk4str8_next(back, delim);
+ } else {
+ *stringp = NULL;
+ }
+ }
+ } $? "- dk4str8_sep \"%!8s\"", TR_8STR(back)
+ return back;
+}
+
+
+
+size_t
+dk4str8_tokenize(
+ char **dpp, size_t szdpp, char *src, const char *delim, dk4_er_t *erp
+)
+{
+ char *context;
+ char *token;
+ size_t back = 0;
+ if ((NULL != dpp) && (0 < szdpp) && (NULL != src)) {
+ if (NULL == delim) { delim = dk4str8_modkw[0]; }
+ context = src;
+ while (NULL != (token = dk4str8_sep(&context, delim))) {
+ if (back < szdpp) {
+ dpp[back] = token;
+ }
+ back++;
+ }
+ if (back >= szdpp) {
+ dk4error_set_elsize_nelem(
+ erp, DK4_E_BUFFER_TOO_SMALL, sizeof(DK4_PCHAR), back
+ );
+ back = 0;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+void
+dk4str8_normalize(char *src, const char *delim)
+{
+ char *p1; /* Pointer to traverse text. */
+ char *p2; /* Start of next token. */
+ int cc; /* Flag: Can continue. */
+
+ if (NULL != src) {
+ /*
+ Set up delimiter set, correct if necessary.
+ */
+ if (NULL == delim) { delim = dk4str8_modkw[0]; }
+ /*
+ Remove leading delimiters.
+ */
+ p1 = src;
+ cc = 0;
+ if ('\0' != *p1) {
+ if (NULL != dk4str8_chr(delim, (unsigned char)(*p1))) {
+ p2 = dk4str8_start(p1, delim);
+ if (NULL != p2) {
+ dk4str8_cpy_to_left(p1, p2);
+ cc = 1;
+ } else {
+ *p1 = '\0';
+ }
+ } else {
+ cc = 1;
+ }
+ }
+ /*
+ Now traverse the string.
+ */
+ while (0 != cc) {
+ if ('\0' == *p1) {
+ cc = 0;
+ } else {
+ if (NULL != dk4str8_chr(delim, (unsigned char)(*p1))) {
+ *p1 = *delim;
+ if ('\0' == p1[1]) {
+ *p1 = '\0';
+ cc = 0;
+ } else {
+ if (NULL != dk4str8_chr(delim, (unsigned char)(p1[1]))) {
+ p2 = dk4str8_start(p1, delim);
+ if (NULL != p2) {
+ dk4str8_cpy_to_left(++p1, p2);
+ } else {
+ *p1 = '\0';
+ cc = 0;
+ }
+ } else {
+ p1++;
+ }
+ }
+ } else {
+ p1++;
+ }
+ }
+ }
+ }
+}
+
+
+
+int
+dk4str8_array_index(const char * const *arr, const char *str, int cs)
+{
+ int back = -1;
+ int cand = 0;
+ if ((NULL != arr) && (NULL != str)) {
+ while((NULL != *arr) && (-1 == back)) {
+ if (0 != cs) {
+ if (0 == dk4str8_cmp(*arr, str)) { back = cand; }
+ } else {
+ if (0 == dk4str8_casecmp(*arr, str)) { back = cand; }
+ }
+ arr++; cand++;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4str8_is_abbr(const char *str, const char *pattern, char spec, int cs)
+{
+ const char *lptr = NULL; /* Pointer to traverse string */
+ const char *pptr = NULL; /* Pointer to traverse pattern */
+ int back = 0; /* Function result */
+ int fspec = 0; /* Flag: spec was found */
+ int cc = 1; /* Flag: Can continue */
+ char cl;
+ char cp;
+ $? "+ dk4str8_is_abbr \"%!8s\" \"%!8s\" \"%!8c\"", pattern, str, spec
+ if ((NULL != str) && (NULL != pattern)) {
+ lptr = str; pptr = pattern;
+ while (0 != cc) {
+ if ((0 == fspec) && (*pptr == spec)) {
+ fspec = 1;
+ pptr++;
+ } else {
+ if ('\0' != *lptr) {
+ cl = *lptr; cp = *pptr;
+ if (0 == cs) {
+ cl = dk4str8_toupper(cl);
+ cp = dk4str8_toupper(cp);
+ }
+ if (cl == cp) {
+ lptr++;
+ pptr++;
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = 0;
+ if (('\0' == *pptr) || (0 != fspec)) { back = 1; }
+ }
+ }
+ }
+ } $? "- dk4str8_is_abbr %d", back
+ return back;
+}
+
+
+
+int
+dk4str8_abbr_index(const char * const *arr, char spec, const char *str, int cs)
+{
+ int back = -1;
+ int cand = 0;
+ $? "+ dk4str8_abbr_index"
+ if ((NULL != arr) && (NULL != str)) {
+ while ((NULL != *arr) && (-1 == back)) {
+ if (0 != dk4str8_is_abbr(str, *arr, spec, cs)) {
+ back = cand;
+ }
+ arr++; cand++;
+ }
+ }
+ $? "- dk4str8_abbr_index %d", back
+ return back;
+}
+
+
+
+int
+dk4str8_is_bool(const char *str)
+{
+ int back = 0;
+ if (NULL != str) {
+ if (-1 < dk4str8_abbr_index(dk4str8_boolkw, '$', str, 0)) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4str8_is_on(const char *str)
+{
+ int back = 0;
+ $? "+ dk4str8_is_on"
+ if (NULL != str) {
+ back = dk4str8_abbr_index(dk4str8_boolkw, '$', str, 0);
+ if (-1 < back) {
+ if (DK4STR8_FIRST_TRUE <= back) {
+ back = 1;
+ } else {
+ back = 0;
+ }
+ } else {
+ back = 0;
+ }
+ }
+ $? "- dk4str8_is_on %d", back
+ return back;
+}
+
+
+
+int
+dk4str8_pathcmp(const char *s1, const char *s2)
+{
+#if DK4_HAVE_CASE_INSENSITIVE_PATHNAMES
+ return (dk4str8_casecmp(s1, s2));
+#else
+ return (dk4str8_cmp(s1, s2));
+#endif
+}
+
+
+
+void
+dk4str8_rtwh(char *str, const char *whsp)
+{
+ char *ptr = NULL;
+ if (NULL == whsp) { whsp = dk4str8_modkw[0]; }
+ if (NULL != str) {
+ while ('\0' != *str) {
+ if (NULL != dk4str8_chr(whsp, *str)) {
+ if (NULL == ptr) { ptr = str; }
+ } else {
+ ptr = NULL;
+ }
+ str++;
+ }
+ if (NULL != ptr) { *ptr = '\0'; }
+ }
+}
+
+
+
+void
+dk4str8_delnl(char *lptr)
+{
+ if (NULL != lptr) {
+ while ('\0' != *lptr) {
+ if ('\n' == *lptr) {
+ *lptr = '\0';
+ } else {
+ if ('\r' == *lptr) {
+ if ('\n' == lptr[1]) {
+ *lptr = '\0';
+ } else {
+ if ('\0' == lptr[1]) {
+ *lptr = '\0';
+ } else {
+ lptr++;
+ }
+ }
+ } else {
+ lptr++;
+ }
+ }
+ }
+ }
+}
+
+
+
+const char *
+dk4str8_skip(const char *line, size_t skip)
+{
+ const char *back = NULL;
+ size_t words = 0; /* Number of words already found */
+ int lwt = 0; /* Flag: Last char was text */
+
+ if (NULL != line) {
+ if (0 < skip) {
+ while((NULL == back) && ('\0' != *line)) {
+ switch (*line) {
+ case ' ': case '\t': case '\n': case '\r': {
+ lwt = 0;
+ } break;
+ default: {
+ if (0 == lwt) {
+ if (++words > skip) {
+ back = line;
+ }
+ }
+ lwt = 1;
+ } break;
+ }
+ line++;
+ }
+ } else {
+ back = dk4str8_start(line, NULL);
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4str8_buffer_sanitize(char *str, size_t sz)
+{
+ int back = 0;
+ if (NULL != str) {
+ if (0 < sz) {
+ back = dk4mem_reset_secure(str, sz, NULL);
+ } else {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4str8_sanitize(char *str)
+{
+ int back = 0;
+ if (NULL != str) {
+ back = dk4str8_buffer_sanitize(str, strlen(str));
+ }
+ return back;
+}
+
+
+
+int
+dk4str8_free_sanitized(char *str)
+{
+ int back = 0;
+ if (NULL != str) {
+ back = dk4str8_sanitize(str);
+ dk4mem_free(str);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4str8.h b/support/dktools/dk4str8.h
new file mode 100644
index 0000000000..743db89c80
--- /dev/null
+++ b/support/dktools/dk4str8.h
@@ -0,0 +1,434 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4str8.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4STR8_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4STR8_H_INCLUDED 1
+
+
+#line 10 "dk4str8.ctr"
+
+/** @file
+ Additional string functions for
+ 8 bit characters.
+
+ Although some of the functions in this module duplicate
+ functionality from string.h functions, you should use
+ the functions from this module.
+ With DK4DK4_WIN_AVOID_CRT or DK4_WIN_DENY_CRT defined to non-zero
+ these functions call Windows API functions like
+ lstrcmpA() ... instead of CRT functions.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Copy string, check destination buffer size.
+
+ CRT on Windows: Optional.
+ @param dst Destination buffer address.
+ @param sz Destination buffer size.
+ @param src Source string.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dst or src is NULL or sz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the dst buffer is too small.
+*/
+int
+dk4str8_cpy_s(char *dst, size_t sz, const char *src, dk4_er_t *erp);
+
+/** Concatenate strings, check destination buffer size.
+
+ CRT on Windows: Optional.
+ @param dst Destination buffer address.
+ @param sz Destination buffer size.
+ @param src Source string.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dst or src is NULL or sz is 0,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in size calculation,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the concatenated string doest not fit into the buffer.
+*/
+int
+dk4str8_cat_s(char *dst, size_t sz, const char *src, dk4_er_t *erp);
+
+/** Copy characters within a string from right to left.
+ This copy operation is intended for moving characters within
+ one string from right to left, making the string shorter
+ as is. This function does not check buffer size or report
+ any error.
+ For normal string copy operations, use the dk4str8_cpy_s()
+ function instead.
+
+ CRT on Windows: Not used.
+ @param dst Destination buffer address.
+ @param src Source string.
+*/
+void
+dk4str8_cpy_to_left(char *dst, const char *src);
+
+/** Find string length.
+
+ CRT on Windows: Optional.
+ @param src Source string.
+ @return String length.
+*/
+size_t
+dk4str8_len(const char *src);
+
+/** Compare two strings.
+
+ CRT on Windows: Optional.
+ @param s1 Left string, may be NULL.
+ @param s2 Right string, may be NULL.
+ @return 1 if s1>s2, 0 if s1==s2, -1 if s1<s2.
+*/
+int
+dk4str8_cmp(const char *s1, const char *s2);
+
+/** Compare two strings.
+
+ CRT on Windows: Optional, disabling CRT probably degrades performance.
+ @param s1 Left string, may be NULL.
+ @param s2 Right string, may be NULL.
+ @param n Maximum number of characters to compare.
+ @return 1 if s1>s2, 0 if s1==s2, -1 if s1<s2.
+*/
+int
+dk4str8_ncmp(const char *s1, const char *s2, size_t n);
+
+/** Compare two strings, case-insensitive comparison.
+
+ CRT on Windows: Optional.
+ @param s1 Left string, may be NULL.
+ @param s2 Right string, may be NULL.
+ @return 1 if s1>s2, 0 if s1==s2, -1 if s1<s2.
+*/
+int
+dk4str8_casecmp(const char *s1, const char *s2);
+
+/** Compare two file path names.
+
+ CRT on Windows: Optional.
+ @param s1 Left string, may be NULL.
+ @param s2 Right string, may be NULL.
+ @return 1 if s1>s2, 0 if s1==s2, -1 if s1<s2.
+*/
+int
+dk4str8_pathcmp(const char *s1, const char *s2);
+
+/** Find first occurance of character c in string s.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param s String to search for c.
+ @param c Character to find.
+ @return Pointer to first occurance if found, NULL otherwise.
+*/
+char *
+dk4str8_chr(const char *s, char c);
+
+/** Find last occurance of character c in string s.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param s String to search for c.
+ @param c Character to find.
+ @return Pointer to last occurance if found, NULL otherwise.
+*/
+char *
+dk4str8_rchr(const char *s, char c);
+
+/** Retrieve first token from *stringp.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param stringp Adress of string pointer.
+ @param delim String containing the delimiter set,
+ my be NULL to use the default delimiter
+ set (space, tabulator, carriage return and newline).
+ @return Pointer to first token on success, NULL if no (further)
+ token found.
+*/
+char *
+dk4str8_sep(char **stringp, const char *delim);
+
+/** Find first token in string.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param src String to search for tokens.
+ @param delim String containing the delimiter characters,
+ may be NULL to use the default delimiter set.
+ @return Pointer to first token if found, NULL otherwise.
+*/
+char *
+dk4str8_start(const char *src, const char *delim);
+
+/** Cut string after first token, find start of second token in string.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param src String to search for tokens,
+ normally the result of dk4str8_start() or a
+ previous dk4str8_next() call.
+ @param delim String containing the delimiter characters,
+ may be NULL to use the default delimiter set.
+ @return Pointer to second token if found, NULL otherwise.
+*/
+char *
+dk4str8_next(char *src, const char *delim);
+
+/** Split a string into tokens.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param dpp Pointer to string pointer array.
+ @param szdpp Size of destination string pointer array.
+ @param src Source string to process.
+ @param delim String containing delimiter characters,
+ may be NULL to use the default delimiter set.
+ @param erp Error report, may be NULL.
+ @return Number of tokens found on success, 0 if no token
+ found or on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ for invalid function arguments,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ with dt.mem.nelem set to the number of tokens in string if the dpp
+ array is too short.
+*/
+size_t
+dk4str8_tokenize(
+ char **dpp, size_t szdpp, char *src, const char *delim, dk4_er_t *erp
+);
+
+/** Normalize a string (remove leading and trailing delimiters,
+ replace delimiter sequences by just one delimiter).
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param src Buffer containing the string to normalize.
+ @param delim String containing delimiter characters,
+ may be NULL to use the default delimiter set.
+*/
+void
+dk4str8_normalize(char *src, const char *delim);
+
+/** Find index of a string in an array of strings.
+
+ CRT on Windows: Optional.
+ @param arr Array of strings.
+ @param str String to find in array.
+ @param cs Flag: Case-sensitive search (0=no, other=yes).
+ @return Non-negative index value on success, -1 on error.
+*/
+int
+dk4str8_array_index(const char * const *arr, const char *str, int cs);
+
+/** Find index of a string in an array of strings.
+
+ CRT on Windows: Optional, disabling CRT degrades performances
+ and reduces to upper-case conversion to characters 'a' to 'z'.
+ @param arr Array of string allowing abbreviations.
+ @param spec Special character indicating start of optional text.
+ @param str String to find in array.
+ @param cs Flag: Case-sensitive search (0=no, other=yes).
+ @return Non-negative index value on success, -1 on error.
+*/
+int
+dk4str8_abbr_index(const char * const *arr, char spec, const char *str, int cs);
+
+/** Check whether a text matches a pattern, the text may be abbreviated.
+
+ CRT on Windows: Optional, disabling CRT degrades performances
+ and reduces to upper-case conversion to characters 'a' to 'z'
+ in case-insensitive comparisons.
+ @param str Text to check.
+ @param pattern Pattern for comparison.
+ @param spec Special character marking the abbreviation in the
+ pattern.
+ @param cs Flag: Case sensitive (1) or not (0).
+ @return 1 for a match, 0 otherwise.
+*/
+int
+dk4str8_is_abbr(const char *str, const char *pattern, char spec, int cs);
+
+/** Check whether a string represents a boolean value.
+
+ CRT on Windows: Optional, disabling CRT degrades performances.
+ @param str String to check.
+ @return 1 if str represents a boolean value, 0 otherwise.
+*/
+int
+dk4str8_is_bool(const char *str);
+
+/** Check whether a string represents the boolean value TRUE.
+
+ CRT on Windows: Optional, disabling CRT degrades performances.
+ @param str String to check.
+ @return 1 if str represents the boolean value TRUE, 0 otherwise.
+*/
+int
+dk4str8_is_on(const char *str);
+
+#if (defined(_WIN32) && DK4_USE_WINDOWS_LOCAL_ALLOC) \
+ || (DK4_HAVE_MALLOC && DK4_HAVE_FREE)
+
+/** Duplicate string in dynamically allocated memory.
+
+ CRT on Windows: Optional, disabling CRT reduces functionality
+ to strings with length fitting to int and overall size in
+ bytes - including finalizer - fitting into a DWORD.
+ @param src String to duplicate.
+ @param erp Error report, may be NULL.
+ @return Pointer to string in new memory on succes, NULL on error.
+ Use dk4mem_free() to release the memory after usage.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src is a NULL pointer,
+ - DK4_E_MATH_OVERFLOW<br>
+ on mathematical overflow in size calculation,
+ - DK4_E_MEMORY<br>
+ if no memory is available.
+*/
+char *
+dk4str8_dup(const char *src, dk4_er_t *erp);
+
+#endif
+/* if (defined(_WIN32) ... */
+
+/** Remove trailing white spaces.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param str String to remove white spaces from.
+ @param whsp White spaces set.
+*/
+void
+dk4str8_rtwh(char *str, const char *whsp);
+
+/** Convert character to uppercase.
+
+ CRT on Windows: Optional, disabling CRT degrades performances
+ and reduces functionality to characters 'a' to 'z'.
+ @param c Character to convert.
+ @return Conversion result.
+*/
+char
+dk4str8_toupper(char c);
+
+/** Convert character to lowercase.
+
+ CRT on Windows: Optional, disabling CRT degrades performances
+ and reduces functionality to characters 'A' to 'Z'.
+ @param c Character to convert.
+ @return Conversion result.
+*/
+char
+dk4str8_tolower(char c);
+
+/** Remove trailing newline from line.
+ @param lptr Line pointer.
+*/
+void
+dk4str8_delnl(char *lptr);
+
+/** Skip the first text words in a line, return pointer to start
+ of next word.
+ @param line Line to process.
+ @param skip Number of words to skip.
+ @return Pointer to next word on success, NULL on error.
+*/
+const char *
+dk4str8_skip(const char *line, size_t skip);
+
+/** Sanitize string (overwrite using 0 bytes).
+ @param str Address of string to sanitize.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4str8_sanitize(char *str);
+
+/** Sanitize string buffer (overwrite using 0 bytes).
+ @param str Address of string buffer.
+ @param sz Size of string buffer (number of elements).
+ @return 1 on success, 0 on error.
+*/
+int
+dk4str8_buffer_sanitize(char *str, size_t sz);
+
+/** Sanitize dynamically allocated memory and release it.
+ @param str Address of string to sanitize and release.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4str8_free_sanitized(char *str);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/** Sanitize string and release it, set pointer to NULL.
+ @param p Pointer to string to release.
+*/
+#define dk4str8_release_sanitized(p) \
+do { if (NULL != p) { (void)dk4str8_free_sanitized(p); } p = NULL; } while (0)
+
+
+
+#endif
diff --git a/support/dktools/dk4strd.c b/support/dktools/dk4strd.c
new file mode 100644
index 0000000000..ef9984c65b
--- /dev/null
+++ b/support/dktools/dk4strd.c
@@ -0,0 +1,390 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4strd.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4strd.c The dk4strd module.
+*/
+
+
+#line 333 "dk4strd.ctr"
+
+
+#include "dk4strd.h"
+
+#if DK4_CHAR_SIZE > 1
+#ifndef DK4STRW_H_INCLUDED
+#include "dk4strw.h"
+#endif
+#else
+#ifndef DK4STR8_H_INCLUDED
+#include "dk4str8.h"
+#endif
+#endif
+
+
+int
+dk4str_cpy_s(dkChar *dst, size_t sz, const dkChar *src, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_cpy_s(dst, sz, src, erp));
+#else
+ return (dk4str8_cpy_s(dst, sz, src, erp));
+#endif
+}
+
+
+
+int
+dk4str_cat_s(dkChar *dst, size_t sz, const dkChar *src, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_cat_s(dst, sz, src, erp));
+#else
+ return (dk4str8_cat_s(dst, sz, src, erp));
+#endif
+}
+
+
+
+void
+dk4str_cpy_to_left(dkChar *dst, const dkChar *src)
+{
+#if DK4_CHAR_SIZE > 1
+ dk4strw_cpy_to_left(dst, src);
+#else
+ dk4str8_cpy_to_left(dst, src);
+#endif
+}
+
+
+
+size_t
+dk4str_len(const dkChar *src)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_len(src));
+#else
+ return (dk4str8_len(src));
+#endif
+}
+
+
+
+int
+dk4str_cmp(const dkChar *s1, const dkChar *s2)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_cmp(s1, s2));
+#else
+ return (dk4str8_cmp(s1, s2));
+#endif
+}
+
+
+
+int
+dk4str_ncmp(const dkChar *s1, const dkChar *s2, size_t n)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_ncmp(s1, s2, n));
+#else
+ return (dk4str8_ncmp(s1, s2, n));
+#endif
+}
+
+
+int
+dk4str_casecmp(const dkChar *s1, const dkChar *s2)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_casecmp(s1, s2));
+#else
+ return (dk4str8_casecmp(s1, s2));
+#endif
+}
+
+
+
+dkChar *
+dk4str_sep(dkChar **stringp, const dkChar *delim)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_sep(stringp, delim));
+#else
+ return (dk4str8_sep(stringp, delim));
+#endif
+}
+
+
+
+dkChar *
+dk4str_start(const dkChar *src, const dkChar *delim)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_start(src, delim));
+#else
+ return (dk4str8_start(src, delim));
+#endif
+}
+
+
+
+dkChar *
+dk4str_next(dkChar *src, const dkChar *delim)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_next(src, delim));
+#else
+ return (dk4str8_next(src, delim));
+#endif
+}
+
+
+
+size_t
+dk4str_tokenize(
+ dkChar **dpp, size_t szdpp, dkChar *src, const dkChar *delim, dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_tokenize(dpp, szdpp, src, delim, erp));
+#else
+ return (dk4str8_tokenize(dpp, szdpp, src, delim, erp));
+#endif
+}
+
+
+
+void
+dk4str_normalize(dkChar *src, const dkChar *delim)
+{
+#if DK4_CHAR_SIZE > 1
+ dk4strw_normalize(src, delim);
+#else
+ dk4str8_normalize(src, delim);
+#endif
+}
+
+
+
+#if (defined(_WIN32) && DK4_USE_WINDOWS_LOCAL_ALLOC) \
+ || (DK4_HAVE_MALLOC && DK4_HAVE_FREE)
+
+dkChar *
+dk4str_dup(const dkChar *src, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_dup(src, erp));
+#else
+ return (dk4str8_dup(src, erp));
+#endif
+}
+
+#endif
+/* if (defined(_WIN32) ... */
+
+
+
+int
+dk4str_array_index(const dkChar * const *arr, const dkChar *str, int cs)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_array_index(arr, str, cs));
+#else
+ return (dk4str8_array_index(arr, str, cs));
+#endif
+}
+
+
+
+int
+dk4str_is_abbr(const dkChar *str, const dkChar *pattern, dkChar spec, int cs)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_is_abbr(str, pattern, spec, cs));
+#else
+ return (dk4str8_is_abbr(str, pattern, spec, cs));
+#endif
+}
+
+
+
+int
+dk4str_abbr_index(
+ const dkChar * const *arr,
+ dkChar spec,
+ const dkChar *str,
+ int cs
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_abbr_index(arr, spec, str, cs));
+#else
+ return (dk4str8_abbr_index(arr, spec, str, cs));
+#endif
+}
+
+
+
+int
+dk4str_is_bool(const dkChar *str)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_is_bool(str));
+#else
+ return (dk4str8_is_bool(str));
+#endif
+}
+
+
+
+int
+dk4str_is_on(const dkChar *str)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_is_on(str));
+#else
+ return (dk4str8_is_on(str));
+#endif
+}
+
+
+
+dkChar *
+dk4str_chr(const dkChar *s, dkChar c)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_chr(s, c));
+#else
+ return (dk4str8_chr(s, c));
+#endif
+}
+
+
+
+dkChar *
+dk4str_rchr(const dkChar *s, dkChar c)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_rchr(s, c));
+#else
+ return (dk4str8_rchr(s, c));
+#endif
+}
+
+
+
+int
+dk4str_pathcmp(const dkChar *s1, const dkChar *s2)
+{
+#if DK4_HAVE_CASE_INSENSITIVE_PATHNAMES
+ return (dk4str_casecmp(s1, s2));
+#else
+ return (dk4str_cmp(s1, s2));
+#endif
+}
+
+
+
+void
+dk4str_rtwh(dkChar *str, const dkChar *whsp)
+{
+#if DK4_CHAR_SIZE > 1
+ dk4strw_rtwh(str, whsp);
+#else
+ dk4str8_rtwh(str, whsp);
+#endif
+}
+
+
+
+void
+dk4str_delnl(dkChar *lptr)
+{
+#if DK4_CHAR_SIZE > 1
+ dk4strw_delnl(lptr);
+#else
+ dk4str8_delnl(lptr);
+#endif
+}
+
+
+
+const dkChar *
+dk4str_skip(const dkChar *line, size_t skip)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_skip(line, skip));
+#else
+ return (dk4str8_skip(line, skip));
+#endif
+}
+
+
+
+
+int
+dk4str_sanitize(dkChar *str)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_sanitize(str));
+#else
+ return (dk4str8_sanitize(str));
+#endif
+}
+
+
+
+int
+dk4str_buffer_sanitize(dkChar *str, size_t sz)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_buffer_sanitize(str, sz));
+#else
+ return (dk4str8_buffer_sanitize(str, sz));
+#endif
+}
+
+
+
+int
+dk4str_free_sanitized(dkChar *str)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_free_sanitized(str));
+#else
+ return (dk4str8_free_sanitized(str));
+#endif
+}
+
diff --git a/support/dktools/dk4strd.ctr b/support/dktools/dk4strd.ctr
new file mode 100644
index 0000000000..d9bee9dab5
--- /dev/null
+++ b/support/dktools/dk4strd.ctr
@@ -0,0 +1,682 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ String functions for dkChar characters.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Copy string, check destination buffer size.
+ @param dst Destination buffer address.
+ @param sz Destination buffer size.
+ @param src Source string.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dst or src is NULL or sz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the dst buffer is too small.
+*/
+int
+dk4str_cpy_s(dkChar *dst, size_t sz, const dkChar *src, dk4_er_t *erp);
+
+/** Concatenate strings, check destination buffer size.
+ @param dst Destination buffer address.
+ @param sz Destination buffer size.
+ @param src Source string.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dst or src is NULL or sz is 0,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in size calculation,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the concatenated string doest not fit into the buffer.
+*/
+int
+dk4str_cat_s(dkChar *dst, size_t sz, const dkChar *src, dk4_er_t *erp);
+
+/** Copy characters within a string from right to left.
+ This copy operation is intended for moving characters within
+ one string from right to left, making the string shorter
+ as is. This function does not check buffer size or report
+ any error.
+ For normal string copy operations, use the dk4str_cpy_s()
+ function instead.
+ @param dst Destination buffer address.
+ @param src Source string.
+*/
+void
+dk4str_cpy_to_left(dkChar *dst, const dkChar *src);
+
+/** Find string length.
+ @param src Source string.
+ @return String length.
+*/
+size_t
+dk4str_len(const dkChar *src);
+
+/** Compare two strings.
+ @param s1 Left string, may be NULL.
+ @param s2 Right string, may be NULL.
+ @return 1 if s1>s2, 0 if s1==s2, -1 if s1<s2.
+*/
+int
+dk4str_cmp(const dkChar *s1, const dkChar *s2);
+
+/** Compare two strings.
+ @param s1 Left string, may be NULL.
+ @param s2 Right string, may be NULL.
+ @param n Maximum number of characters to compare.
+ @return 1 if s1>s2, 0 if s1==s2, -1 if s1<s2.
+*/
+int
+dk4str_ncmp(const dkChar *s1, const dkChar *s2, size_t n);
+
+/** Compare two strings, case-insensitive comparison.
+ @param s1 Left string, may be NULL.
+ @param s2 Right string, may be NULL.
+ @return 1 if s1>s2, 0 if s1==s2, -1 if s1<s2.
+*/
+int
+dk4str_casecmp(const dkChar *s1, const dkChar *s2);
+
+/** Compare two file path names.
+ @param s1 Left string, may be NULL.
+ @param s2 Right string, may be NULL.
+ @return 1 if s1>s2, 0 if s1==s2, -1 if s1<s2.
+*/
+int
+dk4str_pathcmp(const dkChar *s1, const dkChar *s2);
+
+/** Find first occurance of character c in string s.
+ @param s String to search for c.
+ @param c Character to find.
+ @return Pointer to first occurance if found, NULL otherwise.
+*/
+dkChar *
+dk4str_chr(const dkChar *s, dkChar c);
+
+/** Find last occurance of character c in string s.
+ @param s String to search for c.
+ @param c Character to find.
+ @return Pointer to last occurance if found, NULL otherwise.
+*/
+dkChar *
+dk4str_rchr(const dkChar *s, dkChar c);
+
+/** Retrieve first token from *stringp.
+ @param stringp Adress of string pointer.
+ @param delim String containing the delimiter set,
+ my be NULL to use the default delimiter
+ set (space, tabulator, carriage return and newline).
+ @return Pointer to first token on success, NULL if no (further)
+ token found.
+*/
+dkChar *
+dk4str_sep(dkChar **stringp, const dkChar *delim);
+
+/** Find first token in string.
+ @param src String to search for tokens.
+ @param delim String containing the delimiter characters,
+ may be NULL to use the default delimiter set.
+ @return Pointer to first token if found, NULL otherwise.
+*/
+dkChar *
+dk4str_start(const dkChar *src, const dkChar *delim);
+
+/** Cut string after first token, find start of second token in string.
+ @param src String to search for tokens,
+ normally the result of dk4str_start() or a
+ previous dk4str_next() call.
+ @param delim String containing the delimiter characters,
+ may be NULL to use the default delimiter set.
+ @return Pointer to second token if found, NULL otherwise.
+*/
+dkChar *
+dk4str_next(dkChar *src, const dkChar *delim);
+
+/** Split a string into tokens.
+ @param dpp Pointer to string pointer array.
+ @param szdpp Size of destination string pointer array.
+ @param src Source string to process.
+ @param delim String containing delimiter characters,
+ may be NULL to use the default delimiter set.
+ @param erp Error report, may be NULL.
+ @return Number of tokens found on success, 0 if no token
+ found or on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ for invalid function arguments,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ with dt.mem.nelem set to the number of tokens in string if the dpp
+ array is too short.
+*/
+size_t
+dk4str_tokenize(
+ dkChar **dpp, size_t szdpp, dkChar *src, const dkChar *delim, dk4_er_t *erp
+);
+
+/** Normalize a string (remove leading and trailing delimiters,
+ replace delimiter sequences by just one delimiter).
+ @param src Buffer containing the string to normalize.
+ @param delim String containing delimiter characters,
+ may be NULL to use the default delimiter set.
+*/
+void
+dk4str_normalize(dkChar *src, const dkChar *delim);
+
+/** Find index of a string in an array of strings.
+ @param arr Array of strings.
+ @param str String to find in array.
+ @param cs Flag: Case-sensitive search (0=no, other=yes).
+ @return Non-negative index value on success, -1 on error.
+*/
+int
+dk4str_array_index(const dkChar * const *arr, const dkChar *str, int cs);
+
+/** Find index of a string in an array of strings.
+ @param arr Array of strings allowing abbreviation.
+ @param spec Special character indicating start of optional text.
+ @param str String to find in array.
+ @param cs Flag: Case-sensitive search (0=no, other=yes).
+ @return Non-negative index value on success, -1 on error.
+*/
+int
+dk4str_abbr_index(
+ const dkChar * const *arr,
+ dkChar spec,
+ const dkChar *str,
+ int cs
+);
+
+/** Check whether a text matches a pattern, the text may be abbreviated.
+ @param str Text to check.
+ @param pattern Pattern for comparison.
+ @param spec Special character marking the abbreviation in the
+ pattern.
+ @param cs Flag: Case sensitive (1) or not (0).
+ @return 1 for a match, 0 otherwise.
+*/
+int
+dk4str_is_abbr(const dkChar *str, const dkChar *pattern, dkChar spec, int cs);
+
+/** Check whether a string represents a boolean value.
+ @param str String to check.
+ @return 1 if str represents a boolean value, 0 otherwise.
+*/
+int
+dk4str_is_bool(const dkChar *str);
+
+/** Check whether a string represents the boolean value TRUE.
+ @param str String to check.
+ @return 1 if str represents the boolean value TRUE, 0 otherwise.
+*/
+int
+dk4str_is_on(const dkChar *str);
+
+#if (defined(_WIN32) && DK4_USE_WINDOWS_LOCAL_ALLOC) \
+ || (DK4_HAVE_MALLOC && DK4_HAVE_FREE)
+
+/** Duplicate string in dynamically allocated memory.
+ @param src String to duplicate.
+ @param erp Error report, may be NULL.
+ @return Pointer to string in new memory on succes, NULL on error.
+ Use dk4mem_free() to release the memory after usage.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src is a NULL pointer,
+ - DK4_E_MATH_OVERFLOW<br>
+ on mathematical overflow in size calculation,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem set if no memory is available.
+*/
+dkChar *
+dk4str_dup(const dkChar *src, dk4_er_t *erp);
+
+#endif
+/* if (defined(_WIN32) ... */
+
+/** Remove trailing white spaces.
+ @param str String to remove white spaces from.
+ @param whsp White spaces set.
+*/
+void
+dk4str_rtwh(dkChar *str, const dkChar *whsp);
+
+/** Remove trailing newline from line.
+ @param lptr Line pointer.
+*/
+void
+dk4str_delnl(dkChar *lptr);
+
+/** Skip the first text words in a line, return pointer to start
+ of next word.
+ @param line Line to process.
+ @param skip Number of words to skip.
+ @return Pointer to next word on success, NULL on error.
+*/
+const dkChar *
+dk4str_skip(const dkChar *line, size_t skip);
+
+
+/** Sanitize string (overwrite using 0 bytes).
+ @param str Address of string to sanitize.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4str_sanitize(dkChar *str);
+
+/** Sanitize string buffer (overwrite using 0 bytes).
+ @param str Address of string buffer.
+ @param sz Size of string buffer (number of dkChar).
+ @return 1 on success, 0 on error.
+*/
+int
+dk4str_buffer_sanitize(dkChar *str, size_t sz);
+
+/** Sanitize dynamically allocated memory and release it.
+ @param str Address of string to sanitize and release.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4str_free_sanitized(dkChar *str);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#if DK4_CHAR_SIZE > 1
+/** Sanitize string and release it, set pointer to NULL.
+ @param p Pointer to string to release.
+*/
+#define dk4str_release_sanitized(p) \
+do { if (NULL != p) { (void)dk4strw_free_sanitized(p); } p = NULL; } while (0)
+#else
+/** Sanitize string and release it, set pointer to NULL.
+ @param p Pointer to string to release.
+*/
+#define dk4str_release_sanitized(p) \
+do { if (NULL != p) { (void)dk4str8_free_sanitized(p); } p = NULL; } while (0)
+#endif
+
+%% module
+
+
+#include "dk4strd.h"
+
+#if DK4_CHAR_SIZE > 1
+#ifndef DK4STRW_H_INCLUDED
+#include "dk4strw.h"
+#endif
+#else
+#ifndef DK4STR8_H_INCLUDED
+#include "dk4str8.h"
+#endif
+#endif
+
+
+int
+dk4str_cpy_s(dkChar *dst, size_t sz, const dkChar *src, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_cpy_s(dst, sz, src, erp));
+#else
+ return (dk4str8_cpy_s(dst, sz, src, erp));
+#endif
+}
+
+
+
+int
+dk4str_cat_s(dkChar *dst, size_t sz, const dkChar *src, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_cat_s(dst, sz, src, erp));
+#else
+ return (dk4str8_cat_s(dst, sz, src, erp));
+#endif
+}
+
+
+
+void
+dk4str_cpy_to_left(dkChar *dst, const dkChar *src)
+{
+#if DK4_CHAR_SIZE > 1
+ dk4strw_cpy_to_left(dst, src);
+#else
+ dk4str8_cpy_to_left(dst, src);
+#endif
+}
+
+
+
+size_t
+dk4str_len(const dkChar *src)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_len(src));
+#else
+ return (dk4str8_len(src));
+#endif
+}
+
+
+
+int
+dk4str_cmp(const dkChar *s1, const dkChar *s2)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_cmp(s1, s2));
+#else
+ return (dk4str8_cmp(s1, s2));
+#endif
+}
+
+
+
+int
+dk4str_ncmp(const dkChar *s1, const dkChar *s2, size_t n)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_ncmp(s1, s2, n));
+#else
+ return (dk4str8_ncmp(s1, s2, n));
+#endif
+}
+
+
+int
+dk4str_casecmp(const dkChar *s1, const dkChar *s2)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_casecmp(s1, s2));
+#else
+ return (dk4str8_casecmp(s1, s2));
+#endif
+}
+
+
+
+dkChar *
+dk4str_sep(dkChar **stringp, const dkChar *delim)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_sep(stringp, delim));
+#else
+ return (dk4str8_sep(stringp, delim));
+#endif
+}
+
+
+
+dkChar *
+dk4str_start(const dkChar *src, const dkChar *delim)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_start(src, delim));
+#else
+ return (dk4str8_start(src, delim));
+#endif
+}
+
+
+
+dkChar *
+dk4str_next(dkChar *src, const dkChar *delim)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_next(src, delim));
+#else
+ return (dk4str8_next(src, delim));
+#endif
+}
+
+
+
+size_t
+dk4str_tokenize(
+ dkChar **dpp, size_t szdpp, dkChar *src, const dkChar *delim, dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_tokenize(dpp, szdpp, src, delim, erp));
+#else
+ return (dk4str8_tokenize(dpp, szdpp, src, delim, erp));
+#endif
+}
+
+
+
+void
+dk4str_normalize(dkChar *src, const dkChar *delim)
+{
+#if DK4_CHAR_SIZE > 1
+ dk4strw_normalize(src, delim);
+#else
+ dk4str8_normalize(src, delim);
+#endif
+}
+
+
+
+#if (defined(_WIN32) && DK4_USE_WINDOWS_LOCAL_ALLOC) \
+ || (DK4_HAVE_MALLOC && DK4_HAVE_FREE)
+
+dkChar *
+dk4str_dup(const dkChar *src, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_dup(src, erp));
+#else
+ return (dk4str8_dup(src, erp));
+#endif
+}
+
+#endif
+/* if (defined(_WIN32) ... */
+
+
+
+int
+dk4str_array_index(const dkChar * const *arr, const dkChar *str, int cs)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_array_index(arr, str, cs));
+#else
+ return (dk4str8_array_index(arr, str, cs));
+#endif
+}
+
+
+
+int
+dk4str_is_abbr(const dkChar *str, const dkChar *pattern, dkChar spec, int cs)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_is_abbr(str, pattern, spec, cs));
+#else
+ return (dk4str8_is_abbr(str, pattern, spec, cs));
+#endif
+}
+
+
+
+int
+dk4str_abbr_index(
+ const dkChar * const *arr,
+ dkChar spec,
+ const dkChar *str,
+ int cs
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_abbr_index(arr, spec, str, cs));
+#else
+ return (dk4str8_abbr_index(arr, spec, str, cs));
+#endif
+}
+
+
+
+int
+dk4str_is_bool(const dkChar *str)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_is_bool(str));
+#else
+ return (dk4str8_is_bool(str));
+#endif
+}
+
+
+
+int
+dk4str_is_on(const dkChar *str)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_is_on(str));
+#else
+ return (dk4str8_is_on(str));
+#endif
+}
+
+
+
+dkChar *
+dk4str_chr(const dkChar *s, dkChar c)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_chr(s, c));
+#else
+ return (dk4str8_chr(s, c));
+#endif
+}
+
+
+
+dkChar *
+dk4str_rchr(const dkChar *s, dkChar c)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_rchr(s, c));
+#else
+ return (dk4str8_rchr(s, c));
+#endif
+}
+
+
+
+int
+dk4str_pathcmp(const dkChar *s1, const dkChar *s2)
+{
+#if DK4_HAVE_CASE_INSENSITIVE_PATHNAMES
+ return (dk4str_casecmp(s1, s2));
+#else
+ return (dk4str_cmp(s1, s2));
+#endif
+}
+
+
+
+void
+dk4str_rtwh(dkChar *str, const dkChar *whsp)
+{
+#if DK4_CHAR_SIZE > 1
+ dk4strw_rtwh(str, whsp);
+#else
+ dk4str8_rtwh(str, whsp);
+#endif
+}
+
+
+
+void
+dk4str_delnl(dkChar *lptr)
+{
+#if DK4_CHAR_SIZE > 1
+ dk4strw_delnl(lptr);
+#else
+ dk4str8_delnl(lptr);
+#endif
+}
+
+
+
+const dkChar *
+dk4str_skip(const dkChar *line, size_t skip)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_skip(line, skip));
+#else
+ return (dk4str8_skip(line, skip));
+#endif
+}
+
+
+
+
+int
+dk4str_sanitize(dkChar *str)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_sanitize(str));
+#else
+ return (dk4str8_sanitize(str));
+#endif
+}
+
+
+
+int
+dk4str_buffer_sanitize(dkChar *str, size_t sz)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_buffer_sanitize(str, sz));
+#else
+ return (dk4str8_buffer_sanitize(str, sz));
+#endif
+}
+
+
+
+int
+dk4str_free_sanitized(dkChar *str)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4strw_free_sanitized(str));
+#else
+ return (dk4str8_free_sanitized(str));
+#endif
+}
+
diff --git a/support/dktools/dk4strd.h b/support/dktools/dk4strd.h
new file mode 100644
index 0000000000..7ff914675c
--- /dev/null
+++ b/support/dktools/dk4strd.h
@@ -0,0 +1,365 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4strd.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4STRD_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4STRD_H_INCLUDED 1
+
+
+#line 10 "dk4strd.ctr"
+
+/** @file
+ String functions for dkChar characters.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Copy string, check destination buffer size.
+ @param dst Destination buffer address.
+ @param sz Destination buffer size.
+ @param src Source string.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dst or src is NULL or sz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the dst buffer is too small.
+*/
+int
+dk4str_cpy_s(dkChar *dst, size_t sz, const dkChar *src, dk4_er_t *erp);
+
+/** Concatenate strings, check destination buffer size.
+ @param dst Destination buffer address.
+ @param sz Destination buffer size.
+ @param src Source string.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dst or src is NULL or sz is 0,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in size calculation,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the concatenated string doest not fit into the buffer.
+*/
+int
+dk4str_cat_s(dkChar *dst, size_t sz, const dkChar *src, dk4_er_t *erp);
+
+/** Copy characters within a string from right to left.
+ This copy operation is intended for moving characters within
+ one string from right to left, making the string shorter
+ as is. This function does not check buffer size or report
+ any error.
+ For normal string copy operations, use the dk4str_cpy_s()
+ function instead.
+ @param dst Destination buffer address.
+ @param src Source string.
+*/
+void
+dk4str_cpy_to_left(dkChar *dst, const dkChar *src);
+
+/** Find string length.
+ @param src Source string.
+ @return String length.
+*/
+size_t
+dk4str_len(const dkChar *src);
+
+/** Compare two strings.
+ @param s1 Left string, may be NULL.
+ @param s2 Right string, may be NULL.
+ @return 1 if s1>s2, 0 if s1==s2, -1 if s1<s2.
+*/
+int
+dk4str_cmp(const dkChar *s1, const dkChar *s2);
+
+/** Compare two strings.
+ @param s1 Left string, may be NULL.
+ @param s2 Right string, may be NULL.
+ @param n Maximum number of characters to compare.
+ @return 1 if s1>s2, 0 if s1==s2, -1 if s1<s2.
+*/
+int
+dk4str_ncmp(const dkChar *s1, const dkChar *s2, size_t n);
+
+/** Compare two strings, case-insensitive comparison.
+ @param s1 Left string, may be NULL.
+ @param s2 Right string, may be NULL.
+ @return 1 if s1>s2, 0 if s1==s2, -1 if s1<s2.
+*/
+int
+dk4str_casecmp(const dkChar *s1, const dkChar *s2);
+
+/** Compare two file path names.
+ @param s1 Left string, may be NULL.
+ @param s2 Right string, may be NULL.
+ @return 1 if s1>s2, 0 if s1==s2, -1 if s1<s2.
+*/
+int
+dk4str_pathcmp(const dkChar *s1, const dkChar *s2);
+
+/** Find first occurance of character c in string s.
+ @param s String to search for c.
+ @param c Character to find.
+ @return Pointer to first occurance if found, NULL otherwise.
+*/
+dkChar *
+dk4str_chr(const dkChar *s, dkChar c);
+
+/** Find last occurance of character c in string s.
+ @param s String to search for c.
+ @param c Character to find.
+ @return Pointer to last occurance if found, NULL otherwise.
+*/
+dkChar *
+dk4str_rchr(const dkChar *s, dkChar c);
+
+/** Retrieve first token from *stringp.
+ @param stringp Adress of string pointer.
+ @param delim String containing the delimiter set,
+ my be NULL to use the default delimiter
+ set (space, tabulator, carriage return and newline).
+ @return Pointer to first token on success, NULL if no (further)
+ token found.
+*/
+dkChar *
+dk4str_sep(dkChar **stringp, const dkChar *delim);
+
+/** Find first token in string.
+ @param src String to search for tokens.
+ @param delim String containing the delimiter characters,
+ may be NULL to use the default delimiter set.
+ @return Pointer to first token if found, NULL otherwise.
+*/
+dkChar *
+dk4str_start(const dkChar *src, const dkChar *delim);
+
+/** Cut string after first token, find start of second token in string.
+ @param src String to search for tokens,
+ normally the result of dk4str_start() or a
+ previous dk4str_next() call.
+ @param delim String containing the delimiter characters,
+ may be NULL to use the default delimiter set.
+ @return Pointer to second token if found, NULL otherwise.
+*/
+dkChar *
+dk4str_next(dkChar *src, const dkChar *delim);
+
+/** Split a string into tokens.
+ @param dpp Pointer to string pointer array.
+ @param szdpp Size of destination string pointer array.
+ @param src Source string to process.
+ @param delim String containing delimiter characters,
+ may be NULL to use the default delimiter set.
+ @param erp Error report, may be NULL.
+ @return Number of tokens found on success, 0 if no token
+ found or on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ for invalid function arguments,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ with dt.mem.nelem set to the number of tokens in string if the dpp
+ array is too short.
+*/
+size_t
+dk4str_tokenize(
+ dkChar **dpp, size_t szdpp, dkChar *src, const dkChar *delim, dk4_er_t *erp
+);
+
+/** Normalize a string (remove leading and trailing delimiters,
+ replace delimiter sequences by just one delimiter).
+ @param src Buffer containing the string to normalize.
+ @param delim String containing delimiter characters,
+ may be NULL to use the default delimiter set.
+*/
+void
+dk4str_normalize(dkChar *src, const dkChar *delim);
+
+/** Find index of a string in an array of strings.
+ @param arr Array of strings.
+ @param str String to find in array.
+ @param cs Flag: Case-sensitive search (0=no, other=yes).
+ @return Non-negative index value on success, -1 on error.
+*/
+int
+dk4str_array_index(const dkChar * const *arr, const dkChar *str, int cs);
+
+/** Find index of a string in an array of strings.
+ @param arr Array of strings allowing abbreviation.
+ @param spec Special character indicating start of optional text.
+ @param str String to find in array.
+ @param cs Flag: Case-sensitive search (0=no, other=yes).
+ @return Non-negative index value on success, -1 on error.
+*/
+int
+dk4str_abbr_index(
+ const dkChar * const *arr,
+ dkChar spec,
+ const dkChar *str,
+ int cs
+);
+
+/** Check whether a text matches a pattern, the text may be abbreviated.
+ @param str Text to check.
+ @param pattern Pattern for comparison.
+ @param spec Special character marking the abbreviation in the
+ pattern.
+ @param cs Flag: Case sensitive (1) or not (0).
+ @return 1 for a match, 0 otherwise.
+*/
+int
+dk4str_is_abbr(const dkChar *str, const dkChar *pattern, dkChar spec, int cs);
+
+/** Check whether a string represents a boolean value.
+ @param str String to check.
+ @return 1 if str represents a boolean value, 0 otherwise.
+*/
+int
+dk4str_is_bool(const dkChar *str);
+
+/** Check whether a string represents the boolean value TRUE.
+ @param str String to check.
+ @return 1 if str represents the boolean value TRUE, 0 otherwise.
+*/
+int
+dk4str_is_on(const dkChar *str);
+
+#if (defined(_WIN32) && DK4_USE_WINDOWS_LOCAL_ALLOC) \
+ || (DK4_HAVE_MALLOC && DK4_HAVE_FREE)
+
+/** Duplicate string in dynamically allocated memory.
+ @param src String to duplicate.
+ @param erp Error report, may be NULL.
+ @return Pointer to string in new memory on succes, NULL on error.
+ Use dk4mem_free() to release the memory after usage.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src is a NULL pointer,
+ - DK4_E_MATH_OVERFLOW<br>
+ on mathematical overflow in size calculation,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem set if no memory is available.
+*/
+dkChar *
+dk4str_dup(const dkChar *src, dk4_er_t *erp);
+
+#endif
+/* if (defined(_WIN32) ... */
+
+/** Remove trailing white spaces.
+ @param str String to remove white spaces from.
+ @param whsp White spaces set.
+*/
+void
+dk4str_rtwh(dkChar *str, const dkChar *whsp);
+
+/** Remove trailing newline from line.
+ @param lptr Line pointer.
+*/
+void
+dk4str_delnl(dkChar *lptr);
+
+/** Skip the first text words in a line, return pointer to start
+ of next word.
+ @param line Line to process.
+ @param skip Number of words to skip.
+ @return Pointer to next word on success, NULL on error.
+*/
+const dkChar *
+dk4str_skip(const dkChar *line, size_t skip);
+
+
+/** Sanitize string (overwrite using 0 bytes).
+ @param str Address of string to sanitize.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4str_sanitize(dkChar *str);
+
+/** Sanitize string buffer (overwrite using 0 bytes).
+ @param str Address of string buffer.
+ @param sz Size of string buffer (number of dkChar).
+ @return 1 on success, 0 on error.
+*/
+int
+dk4str_buffer_sanitize(dkChar *str, size_t sz);
+
+/** Sanitize dynamically allocated memory and release it.
+ @param str Address of string to sanitize and release.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4str_free_sanitized(dkChar *str);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#if DK4_CHAR_SIZE > 1
+/** Sanitize string and release it, set pointer to NULL.
+ @param p Pointer to string to release.
+*/
+#define dk4str_release_sanitized(p) \
+do { if (NULL != p) { (void)dk4strw_free_sanitized(p); } p = NULL; } while (0)
+#else
+/** Sanitize string and release it, set pointer to NULL.
+ @param p Pointer to string to release.
+*/
+#define dk4str_release_sanitized(p) \
+do { if (NULL != p) { (void)dk4str8_free_sanitized(p); } p = NULL; } while (0)
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4strda.c b/support/dktools/dk4strda.c
new file mode 100644
index 0000000000..6457ac3b8c
--- /dev/null
+++ b/support/dktools/dk4strda.c
@@ -0,0 +1,100 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4strda.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4strda.c The dk4strda module.
+*/
+
+
+#line 51 "dk4strda.ctr"
+
+#include "dk4strda.h"
+
+#ifndef DK4NUMCO_H_INCLUDED
+#include "dk4numco.h"
+#endif
+
+#ifndef DK4MEMA_H_INCLUDED
+#include "dk4mema.h"
+#endif
+
+#ifndef DK4STRD_H_INCLUDED
+#include "dk4strd.h"
+#endif
+
+#ifndef DK4CONST_H_INCLUDED
+#include "dk4const.h"
+#endif
+
+
+
+
+
+#line 73 "dk4strda.ctr"
+
+
+
+dkChar *
+dk4str_dup_app(const dkChar *src, dk4_app_t *app)
+{
+ dkChar *back = NULL;
+ size_t sz;
+ if (NULL != src) {
+ sz = dk4str_len(src);
+ if (SIZE_MAX > sz) {
+ sz++;
+ back = dk4mem_new_app(dkChar,sz,app);
+ if (NULL != back) {
+ (void)dk4str_cpy_s(back, sz, src, NULL);
+#if 0
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ if ((NULL != app->msg_debug) && (41 < app->sz_msg_debug)) {
+ dk4app_log_3(
+ app,app->msg_debug,app->sz_msg_debug,DK4_LL_DEBUG,40,41,back
+ );
+ }
+ }
+ }
+#endif
+ }
+ } else {
+ dk4app_log_base1(app, DK4_LL_ERROR, 82);
+ }
+ }
+ return back;
+}
+
+
+
diff --git a/support/dktools/dk4strda.ctr b/support/dktools/dk4strda.ctr
new file mode 100644
index 0000000000..a23964c2d8
--- /dev/null
+++ b/support/dktools/dk4strda.ctr
@@ -0,0 +1,108 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Dynamic string allocation with application
+ support.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4APP_H_INCLUDED
+#include "dk4app.h"
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Duplicate string (create copy in dynamically allocated memory).
+ @param src String to copy.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new string on success, NULL on error.
+*/
+dkChar *
+dk4str_dup_app(const dkChar *src, dk4_app_t *app);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+%% module
+
+#include "dk4strda.h"
+
+#ifndef DK4NUMCO_H_INCLUDED
+#include "dk4numco.h"
+#endif
+
+#ifndef DK4MEMA_H_INCLUDED
+#include "dk4mema.h"
+#endif
+
+#ifndef DK4STRD_H_INCLUDED
+#include "dk4strd.h"
+#endif
+
+#ifndef DK4CONST_H_INCLUDED
+#include "dk4const.h"
+#endif
+
+
+
+$!trace-include
+
+
+
+dkChar *
+dk4str_dup_app(const dkChar *src, dk4_app_t *app)
+{
+ dkChar *back = NULL;
+ size_t sz;
+ if (NULL != src) {
+ sz = dk4str_len(src);
+ if (SIZE_MAX > sz) {
+ sz++;
+ back = dk4mem_new_app(dkChar,sz,app);
+ if (NULL != back) {
+ (void)dk4str_cpy_s(back, sz, src, NULL);
+#if 0
+ if (NULL != app) {
+ if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
+ if ((NULL != app->msg_debug) && (41 < app->sz_msg_debug)) {
+ dk4app_log_3(
+ app,app->msg_debug,app->sz_msg_debug,DK4_LL_DEBUG,40,41,back
+ );
+ }
+ }
+ }
+#endif
+ }
+ } else {
+ dk4app_log_base1(app, DK4_LL_ERROR, 82);
+ }
+ }
+ return back;
+}
+
+
+
diff --git a/support/dktools/dk4strda.h b/support/dktools/dk4strda.h
new file mode 100644
index 0000000000..b266cf9131
--- /dev/null
+++ b/support/dktools/dk4strda.h
@@ -0,0 +1,83 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4strda.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4STRDA_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4STRDA_H_INCLUDED 1
+
+
+#line 10 "dk4strda.ctr"
+
+/** @file
+ Dynamic string allocation with application
+ support.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4APP_H_INCLUDED
+#include "dk4app.h"
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Duplicate string (create copy in dynamically allocated memory).
+ @param src String to copy.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new string on success, NULL on error.
+*/
+dkChar *
+dk4str_dup_app(const dkChar *src, dk4_app_t *app);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+
+#endif
diff --git a/support/dktools/dk4strm.c b/support/dktools/dk4strm.c
new file mode 100644
index 0000000000..744623b554
--- /dev/null
+++ b/support/dktools/dk4strm.c
@@ -0,0 +1,777 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4strm.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4strm.c The dk4strm module.
+*/
+
+
+#line 358 "dk4strm.ctr"
+
+
+
+#include "dk4strm.h"
+#include "dk4mem.h"
+#include "dk4enc.h"
+#include "dk4numco.h"
+
+
+
+
+
+#line 369 "dk4strm.ctr"
+
+
+
+
+static
+void
+dk4stream_api_init(dk4_stream_api_t *ptr)
+{
+
+
+#line 378 "dk4strm.ctr"
+ DK4_MEMRES(ptr, sizeof(dk4_stream_api_t));
+ ptr->d = NULL;
+ ptr->b = NULL;
+ ptr->sz_in = 0;
+ ptr->sz_out = 0;
+ ptr->res = 0;
+ ptr->cmd = 0;
+
+
+#line 386 "dk4strm.ctr"
+}
+
+
+
+/** Release memory allocated by a stream.
+ @param strm Stream to release.
+*/
+static
+void
+dk4stream_release_memory(dk4_stream_t *strm)
+{
+
+
+#line 398 "dk4strm.ctr"
+ if (NULL != strm) {
+ dk4mem_release(strm->bi);
+ dk4mem_release(strm->bo);
+ strm->d = NULL;
+ strm->fct = NULL;
+ strm->bwr = (dk4_um_t)0UL;
+ strm->szbi = 0;
+ strm->szbo = 0;
+ strm->usbi = 0;
+ strm->usbo = 0;
+ strm->rebi = 0;
+ strm->fl = 0;
+ strm->feoi = 0;
+ strm->bwo = 0;
+ dk4mem_free(strm);
+ }
+
+#line 414 "dk4strm.ctr"
+}
+
+
+
+
+/** Flush write buffer.
+*/
+static
+int
+dk4stream_i_flush_write(dk4_stream_t *strm, int flfl, dk4_er_t *erp)
+{
+ dk4_stream_api_t api;
+ int back = 1;
+
+
+#line 428 "dk4strm.ctr"
+ /* Write buffer contents (if any) downwards.
+ */
+ if (0 != strm->usbo) {
+
+#line 431 "dk4strm.ctr"
+ dk4stream_api_init(&api);
+ api.cmd = DK4_STREAM_API_WRITE;
+ api.d = strm->d;
+ api.b = strm->bo;
+ api.sz_in = strm->usbo;
+ (*(strm->fct))(&api);
+ if (0 == api.res) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED);
+ }
+ }
+ /* Flush downwards.
+ */
+ if (0 < flfl) {
+
+#line 445 "dk4strm.ctr"
+ dk4stream_api_init(&api);
+ api.cmd = DK4_STREAM_API_FLUSH;
+ api.d = strm->d;
+ (*(strm->fct))(&api);
+ if (0 == api.res) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_FLUSH_FAILED);
+ }
+ }
+ /* Indicate output buffer is empty.
+ */
+ strm->usbo = 0;
+
+
+#line 458 "dk4strm.ctr"
+ return back;
+}
+
+
+
+/** Internal function to write one character after checking stream.
+ @param strm Stream to write to.
+ @param c Character to write.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4stream_i_write_byte(dk4_stream_t *strm, char c, dk4_er_t *erp)
+{
+ int back = 0;
+
+
+#line 475 "dk4strm.ctr"
+ if (strm->usbo < strm->szbo) {
+ (strm->bo)[strm->usbo] = c;
+ strm->usbo += 1;
+ strm->bwr += (dk4_um_t)1UL;
+ if ((dk4_um_t)0UL == strm->bwr) { strm->bwo = 1; }
+ back = 1;
+ if (strm->usbo >= strm->szbo) {
+ back = dk4stream_i_flush_write(strm, 0, erp);
+ }
+ }
+
+#line 485 "dk4strm.ctr"
+ return back;
+}
+
+
+
+
+/** Internal function to read a single character.
+ @param dst Pointer to variable for result.
+ @param strm Stream to read from.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4stream_i_c8_read_byte(char *dst, dk4_stream_t *strm, dk4_er_t *erp)
+{
+ dk4_stream_api_t api;
+ int back = 0;
+
+
+#line 504 "dk4strm.ctr"
+ if ((0 == strm->feoi) && ((strm->usbi == 0) || (strm->rebi >= strm->usbi))) {
+
+
+#line 506 "dk4strm.ctr"
+ dk4stream_api_init(&api);
+ api.cmd = DK4_STREAM_API_READ;
+ api.d = strm->d;
+ api.b = strm->bi;
+ api.sz_in = strm->szbi;
+ (*(strm->fct))(&api);
+ if (0 != api.res) {
+
+#line 513 "dk4strm.ctr"
+ strm->rebi = 0;
+ strm->usbi = api.sz_out;
+ if (api.sz_out < strm->szbi) {
+
+#line 516 "dk4strm.ctr"
+ if (0 == strm->zreof) {
+ dk4stream_api_init(&api);
+ api.cmd = DK4_STREAM_API_AT_END;
+ api.d = strm->d;
+ (*(strm->fct))(&api);
+ if (0 != api.res) {
+
+#line 522 "dk4strm.ctr"
+ strm->feoi = 1;
+ }
+ }
+ }
+ } else {
+
+#line 527 "dk4strm.ctr"
+ if (0 != strm->zreof) {
+ strm->feoi = 1;
+ } else {
+ dk4stream_api_init(&api);
+ api.cmd = DK4_STREAM_API_AT_END;
+ api.d = strm->d;
+ (*(strm->fct))(&api);
+ if (0 != api.res) {
+
+#line 535 "dk4strm.ctr"
+ strm->feoi = 1;
+ }
+ }
+ }
+ } else {
+
+#line 540 "dk4strm.ctr"
+ }
+ if ((0 < strm->usbi) && (strm->rebi < strm->usbi)) {
+
+
+#line 543 "dk4strm.ctr"
+ *dst = (strm->bi)[strm->rebi];
+ strm->rebi += 1;
+ back = 1;
+ } else {
+
+#line 547 "dk4strm.ctr"
+ }
+
+
+#line 549 "dk4strm.ctr"
+ return back;
+}
+
+
+
+
+dk4_stream_t *
+dk4stream_open(
+ void *obj,
+ dk4_stream_api_fct_t *fct,
+ int fl,
+ size_t ibs,
+ size_t obs,
+ dk4_er_t *erp
+)
+{
+ dk4_stream_api_t api;
+ dk4_stream_t *back = NULL;
+
+
+#line 568 "dk4strm.ctr"
+ /* Check arguments
+ */
+ if ((NULL == obj) || (NULL == fct)) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ /* Check flag, at least read or write must be set
+ */
+ if (0 == (fl & (DK4_STREAM_READ | DK4_STREAM_WRITE))) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ /* Allocate memory for stream itself
+ */
+ back = dk4mem_new(dk4_stream_t,1,erp);
+ if (NULL == back) {
+ goto finished;
+ }
+ /* Initialize members
+ */
+ back->d = obj; back->fct = fct;
+ back->bi = NULL; back->bo = NULL;
+ back->bwr = (dk4_um_t)0UL;
+ back->szbi = 0; back->szbo = 0;
+ back->usbi = 0; back->usbo = 0; back->rebi = 0;
+ back->fl = fl; back->feoi = 0;
+ back->bwo = 0;
+ back->oenc = DK4_FILE_ENCODING_ASCII;
+ back->zreof = 0;
+ /* Allocate input buffer or destroy object
+ */
+ if (fl & DK4_STREAM_READ) {
+ back->szbi = ((0 < ibs) ? ibs : 4096);
+ back->bi = dk4mem_new(char,back->szbi,erp);
+ if (NULL == back->bi) {
+ dk4stream_release_memory(back);
+ back = NULL;
+ goto finished;
+ }
+ }
+ /* Allocate output buffer or destroy object
+ */
+ if (fl & DK4_STREAM_WRITE) {
+ back->szbo = ((0 < obs) ? obs : 4096);
+ back->bo = dk4mem_new(char,back->szbo,erp);
+ if (NULL == back->bo) {
+ dk4stream_release_memory(back);
+ back = NULL;
+ goto finished;
+ }
+ }
+ /* Check whether reading zero bytes indicates end of input
+ */
+ dk4stream_api_init(&api);
+ api.cmd = DK4_STREAM_API_ZERO_READ_IS_EOF;
+ api.d = obj;
+ (*(back->fct))(&api);
+ if (0 != api.res) { back->zreof = 1; }
+finished:
+
+
+#line 628 "dk4strm.ctr"
+ return back;
+}
+
+
+
+int
+dk4stream_close(dk4_stream_t *strm, dk4_er_t *erp)
+{
+ dk4_stream_api_t api;
+ int back = 0;
+
+
+#line 639 "dk4strm.ctr"
+ /* Check argument.
+ */
+ if (NULL == strm) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+
+ /* Success so far, unless there are errors in the next sections.
+ */
+ back = 1;
+
+ /* Write bytes in output buffer downwards.
+ */
+ if ((strm->fl) & DK4_STREAM_WRITE) {
+ dk4stream_api_init(&api);
+ api.cmd = DK4_STREAM_API_WRITE;
+ api.d = strm->d;
+ api.b = strm->bo;
+ api.sz_in = strm->usbo;
+ (*(strm->fct))(&api);
+ if (0 == api.res) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED);
+ }
+ }
+
+ /* Attempt to flush downwards.
+ */
+ if ((strm->fl) & DK4_STREAM_WRITE) {
+ dk4stream_api_init(&api);
+ api.cmd = DK4_STREAM_API_FLUSH;
+ api.d = strm->d;
+ (*(strm->fct))(&api);
+ if (0 == api.res) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_FLUSH_FAILED);
+ }
+ }
+
+ /* Finalize downward data structures.
+ */
+ dk4stream_api_init(&api);
+ api.cmd = DK4_STREAM_API_CLOSE;
+ api.d = strm->d;
+ (*(strm->fct))(&api);
+ if (0 == api.res) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_CLOSE_FAILED);
+ }
+
+ /* Release memory.
+ */
+ dk4stream_release_memory(strm);
+
+finished:
+
+
+#line 695 "dk4strm.ctr"
+ return back;
+}
+
+
+
+int
+dk4stream_write_byte(dk4_stream_t *strm, char c, dk4_er_t *erp)
+{
+ int back = 0;
+
+
+#line 705 "dk4strm.ctr"
+ if (NULL != strm) {
+ if ((strm->fl) & DK4_STREAM_WRITE) {
+ back = dk4stream_i_write_byte(strm, c, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 714 "dk4strm.ctr"
+ return back;
+}
+
+
+
+#if NOT_OPTIMIZED
+
+int
+dk4stream_write(dk4_stream_t *strm, const void *b, size_t sz, dk4_er_t *erp)
+{
+ char *cptr; /* Traverse buffer */
+ int back = 0;
+
+
+#line 727 "dk4strm.ctr"
+ if ((NULL != strm) && (NULL != b) && (0 < sz)) {
+ if ((strm->fl) & DK4_STREAM_WRITE) {
+ back = 1;
+ cptr = (char *)b;
+ while(sz--) {
+ if (0 == dk4stream_i_write_byte(strm, *(cptr++), erp)) {
+ back = 0;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 742 "dk4strm.ctr"
+ return back;
+}
+
+#else
+
+int
+dk4stream_write(dk4_stream_t *strm, const void *b, size_t sz, dk4_er_t *erp)
+{
+ char *cptr; /* Traverse buffer */
+ size_t bc;
+ int back = 0;
+ int cc;
+
+
+
+#line 756 "dk4strm.ctr"
+ if ((NULL != strm) && (NULL != b) && (0 < sz)) {
+ if ((strm->fl) & DK4_STREAM_WRITE) {
+ back = 1;
+ cptr = (char *)b;
+ do {
+ cc = 0;
+
+#line 762 "dk4strm.ctr"
+ if (0 < sz) {
+ if (strm->usbo < strm->szbo) {
+
+#line 764 "dk4strm.ctr"
+ /* Attempt to copy as many bytes as still free in output buffer */
+ bc = strm->szbo - strm->usbo;
+
+#line 766 "dk4strm.ctr"
+ /* If not enough bytes available, correct number of bytes */
+ if (bc > sz) { bc = sz; }
+
+#line 768 "dk4strm.ctr"
+ DK4_MEMCPY(&((strm->bo)[strm->usbo]), cptr, bc);
+ strm->usbo += bc;
+
+#line 770 "dk4strm.ctr"
+ cptr = &(cptr[bc]);
+ sz -= bc;
+
+#line 772 "dk4strm.ctr"
+ if ((DK4_UM_MAX - (dk4_um_t)bc) < strm->bwr) {
+ strm->bwo = 1;
+
+#line 774 "dk4strm.ctr"
+ back = 0;
+ }
+ strm->bwr += (dk4_um_t)bc;
+
+#line 777 "dk4strm.ctr"
+ if (strm->usbo >= strm->szbo) {
+
+#line 778 "dk4strm.ctr"
+ if (0 == dk4stream_i_flush_write(strm, 0, erp)) {
+ back = 0;
+
+#line 780 "dk4strm.ctr"
+ }
+ }
+ if (0 < sz) { cc = 1; }
+ } else {
+
+#line 784 "dk4strm.ctr"
+ if (0 == dk4stream_i_flush_write(strm, 0, erp)) {
+ back = 0;
+
+#line 786 "dk4strm.ctr"
+ }
+ }
+ }
+ } while(0 != cc);
+ } else {
+
+#line 791 "dk4strm.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+
+#line 794 "dk4strm.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 796 "dk4strm.ctr"
+ return back;
+}
+
+#endif
+
+
+
+int
+dk4stream_write_char_string(dk4_stream_t *strm, const char *str, dk4_er_t *erp)
+{
+ size_t sl;
+ int back = 0;
+ if ((NULL != strm) && (NULL != str)) {
+ sl = strlen(str);
+ back = dk4stream_write(strm, str, sl, erp);
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4stream_flush_read(dk4_stream_t *strm, dk4_er_t *erp)
+{
+ int back = 0;
+
+
+#line 825 "dk4strm.ctr"
+ if (NULL != strm) {
+ if ((strm->fl) & DK4_STREAM_READ) {
+ back = 1;
+ strm->usbi = 0;
+ strm->rebi = 0;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 836 "dk4strm.ctr"
+ return back;
+}
+
+
+
+int
+dk4stream_flush_write(dk4_stream_t *strm, int flfl, dk4_er_t *erp)
+{
+ int back = 0;
+
+
+#line 846 "dk4strm.ctr"
+ if (NULL != strm) {
+ if ((strm->fl) & DK4_STREAM_WRITE) {
+ back = dk4stream_i_flush_write(strm, flfl, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 855 "dk4strm.ctr"
+ return back;
+}
+
+
+
+int
+dk4stream_flush(dk4_stream_t *strm, int flfl, dk4_er_t *erp)
+{
+ int back = 0;
+
+
+#line 865 "dk4strm.ctr"
+ if (NULL != strm) {
+ back = 1;
+ if ((strm->fl) & DK4_STREAM_WRITE) {
+ if (0 == dk4stream_flush_write(strm, flfl, erp)) {
+ back = 0;
+ }
+ }
+ if ((strm->fl) & DK4_STREAM_READ) {
+ if (0 == dk4stream_flush_read(strm, erp)) {
+ back = 0;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 880 "dk4strm.ctr"
+ return back;
+}
+
+
+
+int
+dk4stream_c8_read_byte(char *dst, dk4_stream_t *strm, dk4_er_t *erp)
+{
+ int back = 0;
+
+
+#line 890 "dk4strm.ctr"
+ if ((NULL != dst) && (NULL != strm)) {
+
+#line 891 "dk4strm.ctr"
+ if ((strm->fl) & DK4_STREAM_READ) {
+
+#line 892 "dk4strm.ctr"
+ back = dk4stream_i_c8_read_byte(dst, strm, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 899 "dk4strm.ctr"
+ return back;
+}
+
+
+
+int
+dk4stream_read(void *b, size_t *szptr, dk4_stream_t *strm, dk4_er_t *erp)
+{
+ char *cptr; /* Traverse the buffer */
+ size_t szin; /* Input: Available buffer size */
+ size_t szout; /* Output: Used buffer size */
+ int back = 0; /* Function result */
+ int cc = 1; /* Flag: Can continue */
+
+
+#line 913 "dk4strm.ctr"
+ if ((NULL != b) && (NULL != szptr) && (NULL != strm)) {
+ if (((strm->fl) & DK4_STREAM_READ) && (0 < *szptr)) {
+ szin = *szptr; szout = 0;
+ cptr = (char *)b;
+ do {
+ if (0 != dk4stream_i_c8_read_byte(cptr++, strm, erp)) {
+ szout++;
+ if (szout >= szin) {
+ cc = 0;
+ back = 1;
+ }
+ } else {
+ cc = 0;
+ if (0 < szout) {
+ back = 1;
+ } else {
+ if (0 != dk4stream_found_eof(strm)) {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_READ_FAILED);
+ }
+ }
+ }
+ } while (0 != cc);
+ *szptr = szout;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 944 "dk4strm.ctr"
+ return back;
+}
+
+
+
+dk4_um_t
+dk4stream_bytes_written(const dk4_stream_t *strm)
+{
+ dk4_um_t back = (dk4_um_t)0UL;
+ if (NULL != strm) { back = strm->bwr; }
+ return back;
+}
+
+
+
+int
+dk4stream_overflow_bytes_written(const dk4_stream_t *strm)
+{
+ int back = 0;
+ if (NULL != strm) { back = strm->bwo; }
+ return back;
+}
+
+
+
+int
+dk4stream_found_eof(const dk4_stream_t *strm)
+{
+ int back = 0;
+ if (NULL != strm) {
+ back = strm->feoi;
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4strm.ctr b/support/dktools/dk4strm.ctr
new file mode 100644
index 0000000000..f26d0f93cb
--- /dev/null
+++ b/support/dktools/dk4strm.ctr
@@ -0,0 +1,978 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Generic dk4_stream_t interface for
+ input and output operations.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+
+/** API for stream function.
+*/
+typedef struct {
+ void *d; /**< In: Low level data. */
+ char *b; /**< In: Buffer for data to write or read. */
+ size_t sz_in; /**< In: Number of bytes to write or read. */
+ size_t sz_out; /**< Out: Number of bytes written or read. */
+ int cmd; /**< In: Command to execute. */
+ int res; /**< Out: Low level operation result. */
+} dk4_stream_api_t;
+
+/** Function to execute one low level command.
+*/
+typedef void dk4_stream_api_fct_t(dk4_stream_api_t *);
+
+/** Generic I/O stream.
+*/
+typedef struct {
+ void *d; /**< Low level data object. */
+ dk4_stream_api_fct_t *fct; /**< Function for low level operations. */
+ char *bi; /**< Buffer for input. */
+ char *bo; /**< Buffer for output. */
+ dk4_um_t bwr; /**< Number of bytes written. */
+ size_t szbi; /**< Input buffer size. */
+ size_t szbo; /**< Output buffer size. */
+ size_t usbi; /**< Bytes used in input buffer. */
+ size_t usbo; /**< Bytes used in output buffer. */
+ size_t rebi; /**< Read bytes from input buffer. */
+ int fl; /**< Flags for allowed operations. */
+ int feoi; /**< Flag: Found end of input. */
+ int bwo; /**< Flag: Numeric overflow in bwr. */
+ int oenc; /**< Output encoding for 32 bit characters. */
+ int zreof; /**< Flag: Zero bytes read indicates EOF. */
+} dk4_stream_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open new stream, allocate memory.
+ @param obj Low level object.
+ @param fct Low level function.
+ @param fl Read/write flags: DK4_STREAM_READ, DK4_STREAM_WRITE
+ or (DK4_STREAM_READ | DK4_STREAM_WRITE).
+ @param ibs Input buffer size (0 for default).
+ @param obs Output buffer size (0 for default).
+ @param erp Error report, may be NULL.
+ @return Pointer to new stream on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if obj or fct is NULL or fl is invalid,
+ - DK4_E_MATH_OVERFLOW<br>
+ if ibs or obs is too large,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if allocation of input or output buffer failed.
+*/
+dk4_stream_t *
+dk4stream_open(
+ void *obj,
+ dk4_stream_api_fct_t *fct,
+ int fl,
+ size_t ibs,
+ size_t obs,
+ dk4_er_t *erp
+);
+
+/** Close data stream, release memory.
+ @param strm Stream to close.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is NULL,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flushing data downwards failed,
+ - DK4_E_CLOSE_FAILED<br>
+ if closing downward data failed.
+*/
+int
+dk4stream_close(dk4_stream_t *strm, dk4_er_t *erp);
+
+/** Write one byte to output stream.
+ @param strm Output stream.
+ @param c Byte to write.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is NULL or not opened for writing,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flusing data downwards failed.
+*/
+int
+dk4stream_write_byte(dk4_stream_t *strm, char c, dk4_er_t *erp);
+
+/** Write a buffer to output stream.
+ @param strm Output stream.
+ @param b Buffer start address.
+ @param sz Number of bytes to write.
+ @param erp Error report, may be NULL.
+ @return 1 on success (all bytes written), 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is NULL or not opened for writing,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flusing data downwards failed.
+*/
+int
+dk4stream_write(dk4_stream_t *strm, const void *b, size_t sz, dk4_er_t *erp);
+
+
+/** Write a char string to the stream.
+ @param strm Output stream.
+ @param str String to write.
+ @param erp Error report, may be NULL.
+ @return 1 on success (all bytes written), 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is NULL or not opened for writing,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flusing data downwards failed.
+*/
+int
+dk4stream_write_char_string(dk4_stream_t *strm, const char *str, dk4_er_t *erp);
+
+/** Flush stream input and output data.
+ @param strm Stream to flush.
+ @param flfl Flush type: 0=just flush output buffer
+ contents to low level object, 1=0+flush low level object,
+ 2=1+flush all low level objects recursively (for output filtering).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is NULL.
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed
+ - DK4_E_FLUSH_FAILED<br>
+ if flusing data downwards failed.
+*/
+int
+dk4stream_flush(dk4_stream_t *strm, int flfl, dk4_er_t *erp);
+
+/** Flush stream output data.
+ @param strm Stream to flush.
+ @param flfl Flush type: 0=just flush output buffer
+ contents to low level object, 1=0+flush low level object,
+ 2=1+flush all low level objects recursively (for output filtering).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is NULL or not opened for writing,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flushing data downwards failed.
+*/
+int
+dk4stream_flush_write(dk4_stream_t *strm, int flfl, dk4_er_t *erp);
+
+/** Flush stream input data (discard data in input buffer).
+ @param strm Stream to flush.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is NULL or not opened for writing.
+*/
+int
+dk4stream_flush_read(dk4_stream_t *strm, dk4_er_t *erp);
+
+/** Read a single character.
+ @param dst Pointer to variable for result.
+ @param strm Stream to read from.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is NULL or not opened for reading,
+*/
+int
+dk4stream_c8_read_byte(char *dst, dk4_stream_t *strm, dk4_er_t *erp);
+
+/** Read multiple bytes into buffer.
+ @param b Pointer to buffer start address.
+ @param szptr Pointer to size variable, in: available size,
+ out: number of bytes read.
+ @param strm Stream to read from.
+ @param erp Error report, may be NULL.
+ @return 1 on success (there were bytes read), 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is NULL or not opened for reading,
+ - DK4_E_NOT_FOUND<br>
+ if end of input was detected in read attempt,
+ - DK4_E_READ_FAILED<br>
+ if a read attempt failed for other reasons.
+*/
+int
+dk4stream_read(void *b, size_t *szptr, dk4_stream_t *strm, dk4_er_t *erp);
+
+/** Get number of bytes written.
+ @param strm Stream to get number of bytes for.
+ @return Number of bytes written to the stream (number of bytes
+ received from the upside, not number of bytes written
+ downwards).
+*/
+dk4_um_t
+dk4stream_bytes_written(const dk4_stream_t *strm);
+
+/** Check for numeric overflow in number of bytes written.
+ @param strm Stream to check.
+ @return 1 if overflow occured, 0 if there was no overflow.
+*/
+int
+dk4stream_overflow_bytes_written(const dk4_stream_t *strm);
+
+/** Check whether end of input was found during read attempt.
+ @param strm Stream to check.
+ @return 1 if EOF was detected, 0 otherwise.
+*/
+int
+dk4stream_found_eof(const dk4_stream_t *strm);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+/** Flags whether read or write operations allowed.
+*/
+enum {
+ DK4_STREAM_READ = 1, /**< Reading from stream allowed. */
+ DK4_STREAM_WRITE = 2 /**< Writing to stream allowed. */
+};
+
+
+
+/** Low level commands to execute in the stream API function.
+ The api.cmd is set to one of the values.
+ Depending on api.cmd, other api attributes must be set
+ on input or must be set as response by the low level function.
+*/
+enum {
+ /** Read data.
+ Input api.d: Low level data.
+ Input api.b: Input data buffer.
+ Input api.sz_in: Input data buffer
+ size.
+ Output api.res: 1=any bytes found,
+ 0=no bytes found.
+ Output api.sz_out: Number of bytes
+ read into input
+ buffer.
+ */
+ DK4_STREAM_API_READ = 1,
+
+ /** Write data.
+ Input api.d: Low level data.
+ Input api.b: Output data buffer.
+ Input api.sz_in: Output data buffer
+ size.
+ Output api.res: 1=all bytes
+ written,
+ 0=not all bytes
+ written.
+ Output api.sz_out: Number of bytes
+ written.
+ */
+ DK4_STREAM_API_WRITE ,
+
+ /** Flush data.
+ Input api.d: Low level data.
+ Output api.res: 1=no error reported,
+ 0=error reported.
+ */
+ DK4_STREAM_API_FLUSH ,
+
+ /** Check whether end of input is found.
+ Input api.d: Low level data.
+ Output api.res 1=end of input
+ reached,
+ 0=not yet reached.
+ */
+ DK4_STREAM_API_AT_END ,
+
+ /** Close low level data.
+ Input api.d: Low level data.
+ Output api.res: 1=no error reported,
+ 0=error reported.
+ */
+ DK4_STREAM_API_CLOSE ,
+
+ /** Check whether a read result of 0
+ indicates EOF.
+ Input api.d: Low level data.
+ Output api.res 1=reading zero bytes
+ indicates EOF, 0=no.
+ */
+ DK4_STREAM_API_ZERO_READ_IS_EOF
+};
+
+%% module
+
+
+
+#include "dk4strm.h"
+#include "dk4mem.h"
+#include "dk4enc.h"
+#include "dk4numco.h"
+
+
+
+$!trace-include
+
+
+
+
+static
+void
+dk4stream_api_init(dk4_stream_api_t *ptr)
+{
+ $? "+ dk4stream_api_init"
+ DK4_MEMRES(ptr, sizeof(dk4_stream_api_t));
+ ptr->d = NULL;
+ ptr->b = NULL;
+ ptr->sz_in = 0;
+ ptr->sz_out = 0;
+ ptr->res = 0;
+ ptr->cmd = 0;
+ $? "- dk4stream_api_init"
+}
+
+
+
+/** Release memory allocated by a stream.
+ @param strm Stream to release.
+*/
+static
+void
+dk4stream_release_memory(dk4_stream_t *strm)
+{
+ $? "+ dk4stream_release_memory PTR=%d", TR_IPTR(strm)
+ if (NULL != strm) {
+ dk4mem_release(strm->bi);
+ dk4mem_release(strm->bo);
+ strm->d = NULL;
+ strm->fct = NULL;
+ strm->bwr = (dk4_um_t)0UL;
+ strm->szbi = 0;
+ strm->szbo = 0;
+ strm->usbi = 0;
+ strm->usbo = 0;
+ strm->rebi = 0;
+ strm->fl = 0;
+ strm->feoi = 0;
+ strm->bwo = 0;
+ dk4mem_free(strm);
+ } $? "- dk4stream_release_memory"
+}
+
+
+
+
+/** Flush write buffer.
+*/
+static
+int
+dk4stream_i_flush_write(dk4_stream_t *strm, int flfl, dk4_er_t *erp)
+{
+ dk4_stream_api_t api;
+ int back = 1;
+ $? "+ dk4stream_i_flush_write"
+ /* Write buffer contents (if any) downwards.
+ */
+ if (0 != strm->usbo) { $? ". bytes in output buffer"
+ dk4stream_api_init(&api);
+ api.cmd = DK4_STREAM_API_WRITE;
+ api.d = strm->d;
+ api.b = strm->bo;
+ api.sz_in = strm->usbo;
+ (*(strm->fct))(&api);
+ if (0 == api.res) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED);
+ }
+ }
+ /* Flush downwards.
+ */
+ if (0 < flfl) { $? ". downward flush"
+ dk4stream_api_init(&api);
+ api.cmd = DK4_STREAM_API_FLUSH;
+ api.d = strm->d;
+ (*(strm->fct))(&api);
+ if (0 == api.res) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_FLUSH_FAILED);
+ }
+ }
+ /* Indicate output buffer is empty.
+ */
+ strm->usbo = 0;
+ $? "- dk4stream_i_flush_write %d", back
+ return back;
+}
+
+
+
+/** Internal function to write one character after checking stream.
+ @param strm Stream to write to.
+ @param c Character to write.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4stream_i_write_byte(dk4_stream_t *strm, char c, dk4_er_t *erp)
+{
+ int back = 0;
+ $? "+ dk4stream_i_write_byte"
+ if (strm->usbo < strm->szbo) {
+ (strm->bo)[strm->usbo] = c;
+ strm->usbo += 1;
+ strm->bwr += (dk4_um_t)1UL;
+ if ((dk4_um_t)0UL == strm->bwr) { strm->bwo = 1; }
+ back = 1;
+ if (strm->usbo >= strm->szbo) {
+ back = dk4stream_i_flush_write(strm, 0, erp);
+ }
+ } $? "- dk4stream_i_write_byte %d", back
+ return back;
+}
+
+
+
+
+/** Internal function to read a single character.
+ @param dst Pointer to variable for result.
+ @param strm Stream to read from.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4stream_i_c8_read_byte(char *dst, dk4_stream_t *strm, dk4_er_t *erp)
+{
+ dk4_stream_api_t api;
+ int back = 0;
+ $? "+ dk4stream_i_c8_read_byte"
+ if ((0 == strm->feoi) && ((strm->usbi == 0) || (strm->rebi >= strm->usbi))) {
+ $? ". low level read required"
+ dk4stream_api_init(&api);
+ api.cmd = DK4_STREAM_API_READ;
+ api.d = strm->d;
+ api.b = strm->bi;
+ api.sz_in = strm->szbi;
+ (*(strm->fct))(&api);
+ if (0 != api.res) { $? ". low level read succeeded"
+ strm->rebi = 0;
+ strm->usbi = api.sz_out;
+ if (api.sz_out < strm->szbi) { $? ". less bytes than buffer size"
+ if (0 == strm->zreof) {
+ dk4stream_api_init(&api);
+ api.cmd = DK4_STREAM_API_AT_END;
+ api.d = strm->d;
+ (*(strm->fct))(&api);
+ if (0 != api.res) { $? ". EOF found"
+ strm->feoi = 1;
+ }
+ }
+ }
+ } else { $? ". low level read failed"
+ if (0 != strm->zreof) {
+ strm->feoi = 1;
+ } else {
+ dk4stream_api_init(&api);
+ api.cmd = DK4_STREAM_API_AT_END;
+ api.d = strm->d;
+ (*(strm->fct))(&api);
+ if (0 != api.res) { $? ". end of input reached"
+ strm->feoi = 1;
+ }
+ }
+ }
+ } else { $? ". data in buffer available"
+ }
+ if ((0 < strm->usbi) && (strm->rebi < strm->usbi)) {
+ $? ". data in buffer available"
+ *dst = (strm->bi)[strm->rebi];
+ strm->rebi += 1;
+ back = 1;
+ } else { $? ". no data in buffer"
+ }
+ $? "- dk4stream_i_c8_read_byte %d", back
+ return back;
+}
+
+
+
+
+dk4_stream_t *
+dk4stream_open(
+ void *obj,
+ dk4_stream_api_fct_t *fct,
+ int fl,
+ size_t ibs,
+ size_t obs,
+ dk4_er_t *erp
+)
+{
+ dk4_stream_api_t api;
+ dk4_stream_t *back = NULL;
+ $? "+ dk4stream_open"
+ /* Check arguments
+ */
+ if ((NULL == obj) || (NULL == fct)) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ /* Check flag, at least read or write must be set
+ */
+ if (0 == (fl & (DK4_STREAM_READ | DK4_STREAM_WRITE))) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+ /* Allocate memory for stream itself
+ */
+ back = dk4mem_new(dk4_stream_t,1,erp);
+ if (NULL == back) {
+ goto finished;
+ }
+ /* Initialize members
+ */
+ back->d = obj; back->fct = fct;
+ back->bi = NULL; back->bo = NULL;
+ back->bwr = (dk4_um_t)0UL;
+ back->szbi = 0; back->szbo = 0;
+ back->usbi = 0; back->usbo = 0; back->rebi = 0;
+ back->fl = fl; back->feoi = 0;
+ back->bwo = 0;
+ back->oenc = DK4_FILE_ENCODING_ASCII;
+ back->zreof = 0;
+ /* Allocate input buffer or destroy object
+ */
+ if (fl & DK4_STREAM_READ) {
+ back->szbi = ((0 < ibs) ? ibs : 4096);
+ back->bi = dk4mem_new(char,back->szbi,erp);
+ if (NULL == back->bi) {
+ dk4stream_release_memory(back);
+ back = NULL;
+ goto finished;
+ }
+ }
+ /* Allocate output buffer or destroy object
+ */
+ if (fl & DK4_STREAM_WRITE) {
+ back->szbo = ((0 < obs) ? obs : 4096);
+ back->bo = dk4mem_new(char,back->szbo,erp);
+ if (NULL == back->bo) {
+ dk4stream_release_memory(back);
+ back = NULL;
+ goto finished;
+ }
+ }
+ /* Check whether reading zero bytes indicates end of input
+ */
+ dk4stream_api_init(&api);
+ api.cmd = DK4_STREAM_API_ZERO_READ_IS_EOF;
+ api.d = obj;
+ (*(back->fct))(&api);
+ if (0 != api.res) { back->zreof = 1; }
+finished:
+ $? "- dk4stream_open PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+int
+dk4stream_close(dk4_stream_t *strm, dk4_er_t *erp)
+{
+ dk4_stream_api_t api;
+ int back = 0;
+ $? "+ dk4stream_close"
+ /* Check argument.
+ */
+ if (NULL == strm) {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ goto finished;
+ }
+
+ /* Success so far, unless there are errors in the next sections.
+ */
+ back = 1;
+
+ /* Write bytes in output buffer downwards.
+ */
+ if ((strm->fl) & DK4_STREAM_WRITE) {
+ dk4stream_api_init(&api);
+ api.cmd = DK4_STREAM_API_WRITE;
+ api.d = strm->d;
+ api.b = strm->bo;
+ api.sz_in = strm->usbo;
+ (*(strm->fct))(&api);
+ if (0 == api.res) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED);
+ }
+ }
+
+ /* Attempt to flush downwards.
+ */
+ if ((strm->fl) & DK4_STREAM_WRITE) {
+ dk4stream_api_init(&api);
+ api.cmd = DK4_STREAM_API_FLUSH;
+ api.d = strm->d;
+ (*(strm->fct))(&api);
+ if (0 == api.res) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_FLUSH_FAILED);
+ }
+ }
+
+ /* Finalize downward data structures.
+ */
+ dk4stream_api_init(&api);
+ api.cmd = DK4_STREAM_API_CLOSE;
+ api.d = strm->d;
+ (*(strm->fct))(&api);
+ if (0 == api.res) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_CLOSE_FAILED);
+ }
+
+ /* Release memory.
+ */
+ dk4stream_release_memory(strm);
+
+finished:
+ $? "- dk4stream_close %d", back
+ return back;
+}
+
+
+
+int
+dk4stream_write_byte(dk4_stream_t *strm, char c, dk4_er_t *erp)
+{
+ int back = 0;
+ $? "+ dk4stream_write_byte"
+ if (NULL != strm) {
+ if ((strm->fl) & DK4_STREAM_WRITE) {
+ back = dk4stream_i_write_byte(strm, c, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4stream_write_byte %d", back
+ return back;
+}
+
+
+
+#if NOT_OPTIMIZED
+
+int
+dk4stream_write(dk4_stream_t *strm, const void *b, size_t sz, dk4_er_t *erp)
+{
+ char *cptr; /* Traverse buffer */
+ int back = 0;
+ $? "+ dk4stream_write"
+ if ((NULL != strm) && (NULL != b) && (0 < sz)) {
+ if ((strm->fl) & DK4_STREAM_WRITE) {
+ back = 1;
+ cptr = (char *)b;
+ while(sz--) {
+ if (0 == dk4stream_i_write_byte(strm, *(cptr++), erp)) {
+ back = 0;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4stream_write %d", back
+ return back;
+}
+
+#else
+
+int
+dk4stream_write(dk4_stream_t *strm, const void *b, size_t sz, dk4_er_t *erp)
+{
+ char *cptr; /* Traverse buffer */
+ size_t bc;
+ int back = 0;
+ int cc;
+
+ $? "+ dk4stream_write %lu", (unsigned long)sz
+ if ((NULL != strm) && (NULL != b) && (0 < sz)) {
+ if ((strm->fl) & DK4_STREAM_WRITE) {
+ back = 1;
+ cptr = (char *)b;
+ do {
+ cc = 0; $? ". loop start"
+ if (0 < sz) {
+ if (strm->usbo < strm->szbo) { $? ". can copy"
+ /* Attempt to copy as many bytes as still free in output buffer */
+ bc = strm->szbo - strm->usbo; $? ". bc = %lu", (unsigned long)bc
+ /* If not enough bytes available, correct number of bytes */
+ if (bc > sz) { bc = sz; } $? ". bc = %lu", (unsigned long)bc
+ DK4_MEMCPY(&((strm->bo)[strm->usbo]), cptr, bc);
+ strm->usbo += bc; $? ". usbo = %lu", (unsigned long)(strm->usbo)
+ cptr = &(cptr[bc]);
+ sz -= bc; $? ". sz = %lu", (unsigned long)sz
+ if ((DK4_UM_MAX - (dk4_um_t)bc) < strm->bwr) {
+ strm->bwo = 1; $? "! numeric overflow"
+ back = 0;
+ }
+ strm->bwr += (dk4_um_t)bc; $? ". bwr = %lu", (unsigned long)(strm->bwr)
+ if (strm->usbo >= strm->szbo) { $? ". must flush"
+ if (0 == dk4stream_i_flush_write(strm, 0, erp)) {
+ back = 0; $? "! flush failed"
+ }
+ }
+ if (0 < sz) { cc = 1; }
+ } else { $? ". must flush first"
+ if (0 == dk4stream_i_flush_write(strm, 0, erp)) {
+ back = 0; $? "! flush failed"
+ }
+ }
+ }
+ } while(0 != cc);
+ } else { $? "! stream not writable"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else { $? "! invalid args"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4stream_write %d", back
+ return back;
+}
+
+#endif
+
+
+
+int
+dk4stream_write_char_string(dk4_stream_t *strm, const char *str, dk4_er_t *erp)
+{
+ size_t sl;
+ int back = 0;
+ if ((NULL != strm) && (NULL != str)) {
+ sl = strlen(str);
+ back = dk4stream_write(strm, str, sl, erp);
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4stream_flush_read(dk4_stream_t *strm, dk4_er_t *erp)
+{
+ int back = 0;
+ $? "+ dk4stream_flush_read"
+ if (NULL != strm) {
+ if ((strm->fl) & DK4_STREAM_READ) {
+ back = 1;
+ strm->usbi = 0;
+ strm->rebi = 0;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4stream_flush_read %d", back
+ return back;
+}
+
+
+
+int
+dk4stream_flush_write(dk4_stream_t *strm, int flfl, dk4_er_t *erp)
+{
+ int back = 0;
+ $? "+ dk4stream_flush_write"
+ if (NULL != strm) {
+ if ((strm->fl) & DK4_STREAM_WRITE) {
+ back = dk4stream_i_flush_write(strm, flfl, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4stream_flush_write %d", back
+ return back;
+}
+
+
+
+int
+dk4stream_flush(dk4_stream_t *strm, int flfl, dk4_er_t *erp)
+{
+ int back = 0;
+ $? "+ dk4stream_flush"
+ if (NULL != strm) {
+ back = 1;
+ if ((strm->fl) & DK4_STREAM_WRITE) {
+ if (0 == dk4stream_flush_write(strm, flfl, erp)) {
+ back = 0;
+ }
+ }
+ if ((strm->fl) & DK4_STREAM_READ) {
+ if (0 == dk4stream_flush_read(strm, erp)) {
+ back = 0;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4stream_flush %d", back
+ return back;
+}
+
+
+
+int
+dk4stream_c8_read_byte(char *dst, dk4_stream_t *strm, dk4_er_t *erp)
+{
+ int back = 0;
+ $? "+ dk4stream_c8_read_byte"
+ if ((NULL != dst) && (NULL != strm)) { $? ". pointers ok"
+ if ((strm->fl) & DK4_STREAM_READ) { $? ". read"
+ back = dk4stream_i_c8_read_byte(dst, strm, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4stream_c8_read_byte %d", back
+ return back;
+}
+
+
+
+int
+dk4stream_read(void *b, size_t *szptr, dk4_stream_t *strm, dk4_er_t *erp)
+{
+ char *cptr; /* Traverse the buffer */
+ size_t szin; /* Input: Available buffer size */
+ size_t szout; /* Output: Used buffer size */
+ int back = 0; /* Function result */
+ int cc = 1; /* Flag: Can continue */
+ $? "+ dk4stream_read"
+ if ((NULL != b) && (NULL != szptr) && (NULL != strm)) {
+ if (((strm->fl) & DK4_STREAM_READ) && (0 < *szptr)) {
+ szin = *szptr; szout = 0;
+ cptr = (char *)b;
+ do {
+ if (0 != dk4stream_i_c8_read_byte(cptr++, strm, erp)) {
+ szout++;
+ if (szout >= szin) {
+ cc = 0;
+ back = 1;
+ }
+ } else {
+ cc = 0;
+ if (0 < szout) {
+ back = 1;
+ } else {
+ if (0 != dk4stream_found_eof(strm)) {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_READ_FAILED);
+ }
+ }
+ }
+ } while (0 != cc);
+ *szptr = szout;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4stream_read %d", back
+ return back;
+}
+
+
+
+dk4_um_t
+dk4stream_bytes_written(const dk4_stream_t *strm)
+{
+ dk4_um_t back = (dk4_um_t)0UL;
+ if (NULL != strm) { back = strm->bwr; }
+ return back;
+}
+
+
+
+int
+dk4stream_overflow_bytes_written(const dk4_stream_t *strm)
+{
+ int back = 0;
+ if (NULL != strm) { back = strm->bwo; }
+ return back;
+}
+
+
+
+int
+dk4stream_found_eof(const dk4_stream_t *strm)
+{
+ int back = 0;
+ if (NULL != strm) {
+ back = strm->feoi;
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4strm.h b/support/dktools/dk4strm.h
new file mode 100644
index 0000000000..aa02a5ef28
--- /dev/null
+++ b/support/dktools/dk4strm.h
@@ -0,0 +1,390 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4strm.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4STRM_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4STRM_H_INCLUDED 1
+
+
+#line 10 "dk4strm.ctr"
+
+/** @file
+ Generic dk4_stream_t interface for
+ input and output operations.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+
+/** API for stream function.
+*/
+typedef struct {
+ void *d; /**< In: Low level data. */
+ char *b; /**< In: Buffer for data to write or read. */
+ size_t sz_in; /**< In: Number of bytes to write or read. */
+ size_t sz_out; /**< Out: Number of bytes written or read. */
+ int cmd; /**< In: Command to execute. */
+ int res; /**< Out: Low level operation result. */
+} dk4_stream_api_t;
+
+/** Function to execute one low level command.
+*/
+typedef void dk4_stream_api_fct_t(dk4_stream_api_t *);
+
+/** Generic I/O stream.
+*/
+typedef struct {
+ void *d; /**< Low level data object. */
+ dk4_stream_api_fct_t *fct; /**< Function for low level operations. */
+ char *bi; /**< Buffer for input. */
+ char *bo; /**< Buffer for output. */
+ dk4_um_t bwr; /**< Number of bytes written. */
+ size_t szbi; /**< Input buffer size. */
+ size_t szbo; /**< Output buffer size. */
+ size_t usbi; /**< Bytes used in input buffer. */
+ size_t usbo; /**< Bytes used in output buffer. */
+ size_t rebi; /**< Read bytes from input buffer. */
+ int fl; /**< Flags for allowed operations. */
+ int feoi; /**< Flag: Found end of input. */
+ int bwo; /**< Flag: Numeric overflow in bwr. */
+ int oenc; /**< Output encoding for 32 bit characters. */
+ int zreof; /**< Flag: Zero bytes read indicates EOF. */
+} dk4_stream_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open new stream, allocate memory.
+ @param obj Low level object.
+ @param fct Low level function.
+ @param fl Read/write flags: DK4_STREAM_READ, DK4_STREAM_WRITE
+ or (DK4_STREAM_READ | DK4_STREAM_WRITE).
+ @param ibs Input buffer size (0 for default).
+ @param obs Output buffer size (0 for default).
+ @param erp Error report, may be NULL.
+ @return Pointer to new stream on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if obj or fct is NULL or fl is invalid,
+ - DK4_E_MATH_OVERFLOW<br>
+ if ibs or obs is too large,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if allocation of input or output buffer failed.
+*/
+dk4_stream_t *
+dk4stream_open(
+ void *obj,
+ dk4_stream_api_fct_t *fct,
+ int fl,
+ size_t ibs,
+ size_t obs,
+ dk4_er_t *erp
+);
+
+/** Close data stream, release memory.
+ @param strm Stream to close.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is NULL,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flushing data downwards failed,
+ - DK4_E_CLOSE_FAILED<br>
+ if closing downward data failed.
+*/
+int
+dk4stream_close(dk4_stream_t *strm, dk4_er_t *erp);
+
+/** Write one byte to output stream.
+ @param strm Output stream.
+ @param c Byte to write.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is NULL or not opened for writing,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flusing data downwards failed.
+*/
+int
+dk4stream_write_byte(dk4_stream_t *strm, char c, dk4_er_t *erp);
+
+/** Write a buffer to output stream.
+ @param strm Output stream.
+ @param b Buffer start address.
+ @param sz Number of bytes to write.
+ @param erp Error report, may be NULL.
+ @return 1 on success (all bytes written), 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is NULL or not opened for writing,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flusing data downwards failed.
+*/
+int
+dk4stream_write(dk4_stream_t *strm, const void *b, size_t sz, dk4_er_t *erp);
+
+
+/** Write a char string to the stream.
+ @param strm Output stream.
+ @param str String to write.
+ @param erp Error report, may be NULL.
+ @return 1 on success (all bytes written), 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is NULL or not opened for writing,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flusing data downwards failed.
+*/
+int
+dk4stream_write_char_string(dk4_stream_t *strm, const char *str, dk4_er_t *erp);
+
+/** Flush stream input and output data.
+ @param strm Stream to flush.
+ @param flfl Flush type: 0=just flush output buffer
+ contents to low level object, 1=0+flush low level object,
+ 2=1+flush all low level objects recursively (for output filtering).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is NULL.
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed
+ - DK4_E_FLUSH_FAILED<br>
+ if flusing data downwards failed.
+*/
+int
+dk4stream_flush(dk4_stream_t *strm, int flfl, dk4_er_t *erp);
+
+/** Flush stream output data.
+ @param strm Stream to flush.
+ @param flfl Flush type: 0=just flush output buffer
+ contents to low level object, 1=0+flush low level object,
+ 2=1+flush all low level objects recursively (for output filtering).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is NULL or not opened for writing,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flushing data downwards failed.
+*/
+int
+dk4stream_flush_write(dk4_stream_t *strm, int flfl, dk4_er_t *erp);
+
+/** Flush stream input data (discard data in input buffer).
+ @param strm Stream to flush.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is NULL or not opened for writing.
+*/
+int
+dk4stream_flush_read(dk4_stream_t *strm, dk4_er_t *erp);
+
+/** Read a single character.
+ @param dst Pointer to variable for result.
+ @param strm Stream to read from.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is NULL or not opened for reading,
+*/
+int
+dk4stream_c8_read_byte(char *dst, dk4_stream_t *strm, dk4_er_t *erp);
+
+/** Read multiple bytes into buffer.
+ @param b Pointer to buffer start address.
+ @param szptr Pointer to size variable, in: available size,
+ out: number of bytes read.
+ @param strm Stream to read from.
+ @param erp Error report, may be NULL.
+ @return 1 on success (there were bytes read), 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is NULL or not opened for reading,
+ - DK4_E_NOT_FOUND<br>
+ if end of input was detected in read attempt,
+ - DK4_E_READ_FAILED<br>
+ if a read attempt failed for other reasons.
+*/
+int
+dk4stream_read(void *b, size_t *szptr, dk4_stream_t *strm, dk4_er_t *erp);
+
+/** Get number of bytes written.
+ @param strm Stream to get number of bytes for.
+ @return Number of bytes written to the stream (number of bytes
+ received from the upside, not number of bytes written
+ downwards).
+*/
+dk4_um_t
+dk4stream_bytes_written(const dk4_stream_t *strm);
+
+/** Check for numeric overflow in number of bytes written.
+ @param strm Stream to check.
+ @return 1 if overflow occured, 0 if there was no overflow.
+*/
+int
+dk4stream_overflow_bytes_written(const dk4_stream_t *strm);
+
+/** Check whether end of input was found during read attempt.
+ @param strm Stream to check.
+ @return 1 if EOF was detected, 0 otherwise.
+*/
+int
+dk4stream_found_eof(const dk4_stream_t *strm);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+/** Flags whether read or write operations allowed.
+*/
+enum {
+ DK4_STREAM_READ = 1, /**< Reading from stream allowed. */
+ DK4_STREAM_WRITE = 2 /**< Writing to stream allowed. */
+};
+
+
+
+/** Low level commands to execute in the stream API function.
+ The api.cmd is set to one of the values.
+ Depending on api.cmd, other api attributes must be set
+ on input or must be set as response by the low level function.
+*/
+enum {
+ /** Read data.
+ Input api.d: Low level data.
+ Input api.b: Input data buffer.
+ Input api.sz_in: Input data buffer
+ size.
+ Output api.res: 1=any bytes found,
+ 0=no bytes found.
+ Output api.sz_out: Number of bytes
+ read into input
+ buffer.
+ */
+ DK4_STREAM_API_READ = 1,
+
+ /** Write data.
+ Input api.d: Low level data.
+ Input api.b: Output data buffer.
+ Input api.sz_in: Output data buffer
+ size.
+ Output api.res: 1=all bytes
+ written,
+ 0=not all bytes
+ written.
+ Output api.sz_out: Number of bytes
+ written.
+ */
+ DK4_STREAM_API_WRITE ,
+
+ /** Flush data.
+ Input api.d: Low level data.
+ Output api.res: 1=no error reported,
+ 0=error reported.
+ */
+ DK4_STREAM_API_FLUSH ,
+
+ /** Check whether end of input is found.
+ Input api.d: Low level data.
+ Output api.res 1=end of input
+ reached,
+ 0=not yet reached.
+ */
+ DK4_STREAM_API_AT_END ,
+
+ /** Close low level data.
+ Input api.d: Low level data.
+ Output api.res: 1=no error reported,
+ 0=error reported.
+ */
+ DK4_STREAM_API_CLOSE ,
+
+ /** Check whether a read result of 0
+ indicates EOF.
+ Input api.d: Low level data.
+ Output api.res 1=reading zero bytes
+ indicates EOF, 0=no.
+ */
+ DK4_STREAM_API_ZERO_READ_IS_EOF
+};
+
+
+#endif
diff --git a/support/dktools/dk4strmb.c b/support/dktools/dk4strmb.c
new file mode 100644
index 0000000000..141f1aef2b
--- /dev/null
+++ b/support/dktools/dk4strmb.c
@@ -0,0 +1,150 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4strmb.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4strmb.c The dk4strmb module.
+*/
+
+
+#line 94 "dk4strmb.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_BZLIB_H
+
+#include "dk4strm.h"
+#include "dk4strmb.h"
+
+
+
+void
+dk4stream_bzfile_with_close_function(dk4_stream_api_t *api)
+{
+ BZFILE *fipo;
+ int res;
+ if (NULL != api) {
+ api->res = 0;
+ api->sz_out = 0;
+ fipo = (BZFILE *)(api->d);
+ if (NULL != fipo) {
+ switch (api->cmd) {
+ case DK4_STREAM_API_READ: {
+ res = BZ2_bzread(fipo, api->b, (int)(api->sz_in));
+ if (0 < res) {
+ api->res = 1;
+ api->sz_out = (size_t)res;
+ }
+ } break;
+ case DK4_STREAM_API_WRITE: {
+ res = BZ2_bzwrite(fipo, api->b, (int)(api->sz_in));
+ if (0 < res) {
+ if (res == (int)(api->sz_in)) {
+ api->res = 1;
+ }
+ api->sz_out = (size_t)res;
+ }
+ } break;
+ case DK4_STREAM_API_FLUSH: {
+ BZ2_bzflush(fipo);
+ api->res = 1;
+ } break;
+ case DK4_STREAM_API_AT_END: {
+ } break;
+ case DK4_STREAM_API_CLOSE: {
+ BZ2_bzclose(fipo);
+ api->res = 1;
+ } break;
+ case DK4_STREAM_API_ZERO_READ_IS_EOF: {
+ api->res = 1;
+ } break;
+ }
+ }
+ }
+}
+
+
+
+void
+dk4stream_bzfile_function(dk4_stream_api_t *api)
+{
+ if (NULL != api) {
+ switch (api->cmd) {
+ case DK4_STREAM_API_CLOSE: {
+ api->res = 1;
+ api->sz_out = 0;
+ } break;
+ default: {
+ dk4stream_bzfile_with_close_function(api);
+ } break;
+ }
+ }
+}
+
+
+
+dk4_stream_t *
+dk4stream_open_for_bzfile(
+ BZFILE *fipo,
+ int fl,
+ size_t ibs,
+ size_t obs,
+ dk4_er_t *erp
+)
+{
+ return (
+ dk4stream_open( (void *)fipo, dk4stream_bzfile_function, fl, ibs, obs, erp)
+ );
+}
+
+
+
+dk4_stream_t *
+dk4stream_open_for_bzfile_with_close(
+ BZFILE *fipo,
+ int fl,
+ size_t ibs,
+ size_t obs,
+ dk4_er_t *erp
+)
+{
+ return (
+ dk4stream_open(
+ (void *)fipo, dk4stream_bzfile_with_close_function, fl, ibs, obs, erp
+ )
+ );
+}
+
+
+#endif
+
diff --git a/support/dktools/dk4strmb.ctr b/support/dktools/dk4strmb.ctr
new file mode 100644
index 0000000000..5e9d6d737c
--- /dev/null
+++ b/support/dktools/dk4strmb.ctr
@@ -0,0 +1,203 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Generic dk4_stream_t API for input
+ and output, implementation for BZFILE.
+
+ CRT on Windows: Required.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_BZLIB_H
+
+#ifndef DK4STRM_H_INCLUDED
+#include "dk4strm.h"
+#endif
+
+#ifndef BZLIB_H_INCLUDED
+#include <bzlib.h>
+#define BZLIB_H_INCLUDED 1
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Low level function to access a BZFILE.
+ @param api The stream API structure for arguments and results.
+*/
+void
+dk4stream_bzfile_function(dk4_stream_api_t *api);
+
+/** Low level function to access a BZFILE and close it on
+ dk4stream_close().
+ @param api The stream API structure for arguments and results.
+*/
+void
+dk4stream_bzfile_with_close_function(dk4_stream_api_t *api);
+
+/** Open a stream for an existing BZFILE.
+ @param fipo Existing BZFILE, not closed on dk4stream_close().
+ @param fl Access flag: DK4_STREAM_READ,, DK4_STREAM_WRITE
+ or (DK4_STREAM_READ | DK4_STREAM_WRITE).
+ @param ibs Input buffer size (0 for default).
+ @param obs Output buffer size (0 for default).
+ @param erp Error report, may be NULL.
+ @return Pointer to stream on success, NULL on error.
+*/
+dk4_stream_t *
+dk4stream_open_for_bzfile(
+ BZFILE *fipo,
+ int fl,
+ size_t ibs,
+ size_t obs,
+ dk4_er_t *erp
+);
+
+/** Open a stream for an existing BZFILE.
+ @param fipo Existing BZFILE, closed on dk4stream_close().
+ @param fl Access flag: DK4_STREAM_READ,, DK4_STREAM_WRITE
+ or (DK4_STREAM_READ | DK4_STREAM_WRITE).
+ @param ibs Input buffer size (0 for default).
+ @param obs Output buffer size (0 for default).
+ @param erp Error report, may be NULL.
+ @return Pointer to stream on success, NULL on error.
+*/
+dk4_stream_t *
+dk4stream_open_for_bzfile_with_close(
+ BZFILE *fipo,
+ int fl,
+ size_t ibs,
+ size_t obs,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_BZLIB_H
+
+#include "dk4strm.h"
+#include "dk4strmb.h"
+
+
+
+void
+dk4stream_bzfile_with_close_function(dk4_stream_api_t *api)
+{
+ BZFILE *fipo;
+ int res;
+ if (NULL != api) {
+ api->res = 0;
+ api->sz_out = 0;
+ fipo = (BZFILE *)(api->d);
+ if (NULL != fipo) {
+ switch (api->cmd) {
+ case DK4_STREAM_API_READ: {
+ res = BZ2_bzread(fipo, api->b, (int)(api->sz_in));
+ if (0 < res) {
+ api->res = 1;
+ api->sz_out = (size_t)res;
+ }
+ } break;
+ case DK4_STREAM_API_WRITE: {
+ res = BZ2_bzwrite(fipo, api->b, (int)(api->sz_in));
+ if (0 < res) {
+ if (res == (int)(api->sz_in)) {
+ api->res = 1;
+ }
+ api->sz_out = (size_t)res;
+ }
+ } break;
+ case DK4_STREAM_API_FLUSH: {
+ BZ2_bzflush(fipo);
+ api->res = 1;
+ } break;
+ case DK4_STREAM_API_AT_END: {
+ } break;
+ case DK4_STREAM_API_CLOSE: {
+ BZ2_bzclose(fipo);
+ api->res = 1;
+ } break;
+ case DK4_STREAM_API_ZERO_READ_IS_EOF: {
+ api->res = 1;
+ } break;
+ }
+ }
+ }
+}
+
+
+
+void
+dk4stream_bzfile_function(dk4_stream_api_t *api)
+{
+ if (NULL != api) {
+ switch (api->cmd) {
+ case DK4_STREAM_API_CLOSE: {
+ api->res = 1;
+ api->sz_out = 0;
+ } break;
+ default: {
+ dk4stream_bzfile_with_close_function(api);
+ } break;
+ }
+ }
+}
+
+
+
+dk4_stream_t *
+dk4stream_open_for_bzfile(
+ BZFILE *fipo,
+ int fl,
+ size_t ibs,
+ size_t obs,
+ dk4_er_t *erp
+)
+{
+ return (
+ dk4stream_open( (void *)fipo, dk4stream_bzfile_function, fl, ibs, obs, erp)
+ );
+}
+
+
+
+dk4_stream_t *
+dk4stream_open_for_bzfile_with_close(
+ BZFILE *fipo,
+ int fl,
+ size_t ibs,
+ size_t obs,
+ dk4_er_t *erp
+)
+{
+ return (
+ dk4stream_open(
+ (void *)fipo, dk4stream_bzfile_with_close_function, fl, ibs, obs, erp
+ )
+ );
+}
+
+
+#endif
+
diff --git a/support/dktools/dk4strmb.h b/support/dktools/dk4strmb.h
new file mode 100644
index 0000000000..c870defb98
--- /dev/null
+++ b/support/dktools/dk4strmb.h
@@ -0,0 +1,126 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4strmb.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4STRMB_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4STRMB_H_INCLUDED 1
+
+
+#line 10 "dk4strmb.ctr"
+
+/** @file
+ Generic dk4_stream_t API for input
+ and output, implementation for BZFILE.
+
+ CRT on Windows: Required.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_BZLIB_H
+
+#ifndef DK4STRM_H_INCLUDED
+#include "dk4strm.h"
+#endif
+
+#ifndef BZLIB_H_INCLUDED
+#include <bzlib.h>
+#define BZLIB_H_INCLUDED 1
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Low level function to access a BZFILE.
+ @param api The stream API structure for arguments and results.
+*/
+void
+dk4stream_bzfile_function(dk4_stream_api_t *api);
+
+/** Low level function to access a BZFILE and close it on
+ dk4stream_close().
+ @param api The stream API structure for arguments and results.
+*/
+void
+dk4stream_bzfile_with_close_function(dk4_stream_api_t *api);
+
+/** Open a stream for an existing BZFILE.
+ @param fipo Existing BZFILE, not closed on dk4stream_close().
+ @param fl Access flag: DK4_STREAM_READ,, DK4_STREAM_WRITE
+ or (DK4_STREAM_READ | DK4_STREAM_WRITE).
+ @param ibs Input buffer size (0 for default).
+ @param obs Output buffer size (0 for default).
+ @param erp Error report, may be NULL.
+ @return Pointer to stream on success, NULL on error.
+*/
+dk4_stream_t *
+dk4stream_open_for_bzfile(
+ BZFILE *fipo,
+ int fl,
+ size_t ibs,
+ size_t obs,
+ dk4_er_t *erp
+);
+
+/** Open a stream for an existing BZFILE.
+ @param fipo Existing BZFILE, closed on dk4stream_close().
+ @param fl Access flag: DK4_STREAM_READ,, DK4_STREAM_WRITE
+ or (DK4_STREAM_READ | DK4_STREAM_WRITE).
+ @param ibs Input buffer size (0 for default).
+ @param obs Output buffer size (0 for default).
+ @param erp Error report, may be NULL.
+ @return Pointer to stream on success, NULL on error.
+*/
+dk4_stream_t *
+dk4stream_open_for_bzfile_with_close(
+ BZFILE *fipo,
+ int fl,
+ size_t ibs,
+ size_t obs,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4strmco.c b/support/dktools/dk4strmco.c
new file mode 100644
index 0000000000..6c8609aaf4
--- /dev/null
+++ b/support/dktools/dk4strmco.c
@@ -0,0 +1,1033 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4strmco.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4strmco.c The dk4strmco module.
+*/
+
+
+#line 116 "dk4strmco.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_ZLIB_H
+#ifndef ZLIB_H_INCLUDED
+#include <zlib.h>
+#define ZLIB_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4rle.h"
+#include "dk4a85e.h"
+#include "dk4strmco.h"
+#include "dk4mem.h"
+#include "dk4memrs.h"
+#include "dk4lzwe.h"
+
+
+
+
+#line 135 "dk4strmco.ctr"
+
+
+
+#ifndef DK4_STRMCO_ZBUF_SIZE
+#define DK4_STRMCO_ZBUF_SIZE 4096
+#endif
+
+
+
+/** Compressor data structure.
+*/
+typedef struct {
+ char zbuf[DK4_STRMCO_ZBUF_SIZE]; /**< Output buffer. */
+ union {
+#if DK4_HAVE_ZLIB_H
+ z_stream zs; /**< Flate compression structure. */
+#endif
+ dk4_lzwe_t lzw; /**< LZW compression structure. */
+ } u_co; /**< Compression structures. */
+ union {
+ dk4_rl_enc_t rle; /**< Run-length encoder. */
+ } u_pp; /**< Preprocessing structures. */
+ union {
+ dk4_a85_enc_t a85; /**< ASCII-85 encoder. */
+ } u_oe; /**< Output encoding structures. */
+ dk4_stream_t *dststrm; /**< Destination stream. */
+ size_t ll; /**< Line length. */
+ int pp; /**< Preprocessing. */
+ int co; /**< Compression. */
+ int oe; /**< Output encoding. */
+ int fl; /**< Flags. */
+} compressor_t;
+
+
+
+/** Newline.
+*/
+static char nl[] = {
+ '\n', '\0'
+};
+
+
+
+/** Carriage return and newline.
+*/
+static char crnl[] = {
+ '\r', '\n', '\0'
+};
+
+
+
+/** Finalizer for ASCII-Hex encoding.
+*/
+static char ahfin[] = {
+ '>', '\0'
+};
+
+
+
+/** Finalizer for ASCII-85 encoding.
+*/
+static char a85fin[] = {
+ '~', '>', '\0'
+};
+
+
+
+/** Hexadecimal digits using lower case characters.
+*/
+static char lower[] = {
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', '\0'
+};
+
+
+
+/** Hexadecimal digits using upper case characters.
+*/
+static char upper[] = {
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', '\0'
+};
+
+
+
+/** Write newline to destination stream.
+ @param co Compressor structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4strmco_nl(compressor_t *co)
+{
+ int back = 0;
+
+
+#line 230 "dk4strmco.ctr"
+ if (0 != (DK4_STRMCO_FL_CR_NL & (co->fl))) {
+ back = dk4stream_write(co->dststrm, crnl, 2, NULL);
+ }
+ else {
+ back = dk4stream_write(co->dststrm, nl, 1, NULL);
+ }
+
+
+#line 237 "dk4strmco.ctr"
+ return back;
+}
+
+
+
+
+/** Write bytes to compressor at output encoding level.
+ @param co Compressor to write to.
+ @param b Buffer start address.
+ @param sz Number of bytes to write.
+ @param szo Address of variable for number of bytes written, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4strmco_co_oe(
+ compressor_t *co,
+ const char *b,
+ size_t sz,
+ size_t *szo
+)
+{
+ char buf[8]; /* Buffer for hexadecimal digits. */
+ const char *dptr; /* Pointer to A85 encoding result. */
+ size_t osz = 0; /* Number of bytes processed. */
+ size_t szd = 0; /* A85 encoding result length. */
+ size_t i = 0; /* Index of current byte to process. */
+ size_t j = 0; /* Index of cur out char. */
+ int back = 0; /* Function result. */
+ int res; /* Result from various operations. */
+ unsigned us; /* Index in hex digits array. */
+ unsigned char uc; /* UC version of current character */
+
+
+#line 270 "dk4strmco.ctr"
+ switch (co->oe) {
+ case DK4_STRMCO_OE_ASCII85 : {
+
+
+#line 273 "dk4strmco.ctr"
+ back = 1;
+ for (i = 0; ((i < sz) && (1 == back)); i++) {
+ switch (dk4a85_enc_add(&(co->u_oe.a85), b[i], NULL)) {
+ case DK4_EDSTM_ACCEPT : {
+ osz++;
+ } break;
+ case DK4_EDSTM_FINISHED : {
+ dptr = NULL;
+ szd = 0;
+ res = dk4a85_enc_output(
+ &dptr, &szd, &(co->u_oe.a85), NULL
+ );
+ if (0 < res) {
+ if (0 < szd) {
+#if VERSION_BEFORE_20161019
+ res = dk4stream_write(
+ co->dststrm, dptr, szd, NULL
+ );
+ if (0 < res) {
+ osz++;
+ co->ll += szd;
+ if (0 != (DK4_STRMCO_FL_NL_OE & (co->fl))) {
+ if (74 <= co->ll) {
+ res = dk4strmco_nl(co);
+ if (0 < res) {
+ co->ll = 0;
+ }
+ else {
+ back = 0;
+ }
+ }
+ }
+ }
+ else {
+ back = 0;
+ }
+#else
+ back = 1;
+ for (j = 0; ((j < szd) && (1 == back)); j++) {
+ res = dk4stream_write_byte(
+ co->dststrm, dptr[j], NULL
+ );
+ if (0 < res) {
+ osz++;
+ co->ll += 1;
+ if (75 <= co->ll) {
+ res = dk4strmco_nl(co);
+ if (0 < res) {
+ co->ll = 0;
+ }
+ else {
+ back = 0;
+ }
+ }
+ }
+ else {
+ back = 0;
+ }
+ }
+#endif
+ }
+ else {
+ osz++;
+ }
+ }
+ else {
+ back = 0;
+ }
+ } break;
+ default : {
+ back = 0;
+ } break;
+ }
+ }
+ } break;
+ case DK4_STRMCO_OE_HEX : {
+
+
+#line 350 "dk4strmco.ctr"
+ back = 1;
+ buf[2] = '\0';
+ for (i = 0; ((i < sz) && (1 == back)); i++) {
+ uc = (unsigned char)(b[i]);
+ us = 0x000FU & ((unsigned char)uc);
+ if (0 != (DK4_STRMCO_FL_UPPER_OE & (co->fl))) {
+ buf[1] = upper[us];
+ }
+ else {
+ buf[1] = lower[us];
+ }
+ us = 0x000FU & (((unsigned char)uc) >> 4);
+ if (0 != (DK4_STRMCO_FL_UPPER_OE & (co->fl))) {
+ buf[0] = upper[us];
+ }
+ else {
+ buf[0] = lower[us];
+ }
+ res = dk4stream_write(co->dststrm, buf, 2, NULL);
+ co->ll += 2;
+ if (0 < res) {
+ osz++;
+ if (0 != (DK4_STRMCO_FL_NL_OE & (co->fl))) {
+ if (78 <= co->ll) {
+ res = dk4strmco_nl(co);
+ if (0 < res) {
+ co->ll = 0;
+ }
+ else {
+ back = 0;
+ }
+ }
+ }
+ }
+ else {
+ back = 0;
+ }
+ }
+ } break;
+ default : {
+
+
+#line 391 "dk4strmco.ctr"
+ back = dk4stream_write(co->dststrm, b, sz, NULL);
+ if (0 != back) {
+ osz = sz;
+ }
+ } break;
+ }
+ if (NULL != szo) { *szo = osz; }
+
+
+#line 399 "dk4strmco.ctr"
+ return back;
+}
+
+
+
+/** Write bytes to compressor at compression level.
+ @param co Compressor to write to.
+ @param b Buffer start address.
+ @param sz Number of bytes to write.
+ @param szo Address of variable for number of bytes written, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4strmco_co_co(
+ compressor_t *co,
+ const char *b,
+ size_t sz,
+ size_t *szo
+)
+{
+ const unsigned char *cptr;
+ size_t osz = 0; /* Number of bytes processed successfully. */
+ size_t used = 0; /* Used bytes in output buffer. */
+ size_t i = 0; /* Index of current LZW byte to process. */
+ size_t lzwsz = 0; /* Bytes from LZW compression. */
+ int back = 0; /* Function result. */
+ int res = 0; /* Result from various operations. */
+
+
+#line 428 "dk4strmco.ctr"
+ switch (co->co) {
+ case DK4_STRMCO_CO_FLATE : {
+
+
+#line 431 "dk4strmco.ctr"
+ back = 1;
+ co->u_co.zs.next_in = (unsigned char *)b;
+ co->u_co.zs.avail_in = sz;
+ do {
+ co->u_co.zs.next_out = (unsigned char *)(&(co->zbuf[0]));
+ co->u_co.zs.avail_out = DK4_STRMCO_ZBUF_SIZE;
+ res = deflate(&(co->u_co.zs), Z_NO_FLUSH);
+ switch (res) {
+ case Z_OK : {
+ used = DK4_STRMCO_ZBUF_SIZE - co->u_co.zs.avail_out;
+ if (0 < used) {
+ res = dk4strmco_co_oe(co,&(co->zbuf[0]),used,NULL);
+ if (0 < res) {
+ osz = sz - co->u_co.zs.avail_in;
+ }
+ else {
+ back = 0;
+ }
+ }
+ else {
+ osz = sz - co->u_co.zs.avail_in;
+ }
+ } break;
+ default : {
+ back = 0;
+ } break;
+ }
+ } while ((0 < co->u_co.zs.avail_in) && (1 == back));
+ if (NULL != szo) { *szo = osz; }
+ } break;
+ case DK4_STRMCO_CO_LZW : {
+ back = 1;
+ for (i = 0; ((1 == back) && (i < sz)); i++) {
+ res = dk4lzwe_add(&(co->u_co.lzw), (unsigned char)(b[i]), NULL);
+ switch (res) {
+ case DK4_EDSTM_ACCEPT : {
+ osz++;
+ } break;
+ case DK4_EDSTM_FINISHED : {
+ cptr = NULL;
+ lzwsz = 0;
+ res = dk4lzwe_output(
+ &cptr, &lzwsz, &(co->u_co.lzw), NULL
+ );
+ if ((0 != res) && (NULL != cptr) && (0 < lzwsz)) {
+ back = dk4strmco_co_oe(
+ co, (const char *)cptr, lzwsz, NULL
+ );
+ if (0 != back) {
+ osz++;
+ }
+ }
+ else {
+ back = 0;
+ }
+ } break;
+ case DK4_EDSTM_ERROR : {
+ back = 0;
+ } break;
+ }
+ }
+ if (NULL != szo) { *szo = osz; }
+ } break;
+ default : {
+
+
+#line 496 "dk4strmco.ctr"
+ back = dk4strmco_co_oe(co, b, sz, szo);
+ } break;
+ }
+
+
+#line 500 "dk4strmco.ctr"
+ return back;
+}
+
+
+
+/** Write bytes to compressor at preprocessor level.
+ @param co Compressor to write to.
+ @param b Buffer start address.
+ @param sz Number of bytes to write.
+ @param szo Address of variable for number of bytes written, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4strmco_co_write(
+ compressor_t *co,
+ const char *b,
+ size_t sz,
+ size_t *szo
+)
+{
+ const unsigned char *rleptr; /* RL encoding result */
+ size_t osz = 0; /* Bytes processed successfully */
+ size_t i; /* Running index of current byte */
+ size_t rlesz; /* Size of RL encoding result */
+ int back = 0; /* Function result */
+ int res; /* Result from various operations */
+
+
+#line 528 "dk4strmco.ctr"
+ switch (co->pp) {
+ case DK4_STRMCO_PP_RUNLENGTH : {
+
+
+#line 531 "dk4strmco.ctr"
+ back = 1;
+ for (i = 0; ((i < sz) && (0 != back)); i++) {
+ switch (dk4rle_add(&(co->u_pp.rle),(unsigned char)(b[i]),NULL))
+ {
+ case DK4_EDSTM_FINISHED : {
+ rleptr = NULL;
+ rlesz = 0;
+ res = dk4rle_output(
+ &rleptr, &rlesz, &(co->u_pp.rle), NULL
+ );
+ if (0 != res) {
+ res = dk4strmco_co_co(
+ co, (const char *)rleptr, rlesz, NULL
+ );
+ if (0 != res) {
+ osz++;
+ }
+ else {
+ back = 0;
+ }
+ }
+ else {
+ back = 0;
+ }
+ } break;
+ case DK4_EDSTM_ERROR : {
+ back = 0;
+ } break;
+ default : {
+ osz++;
+ } break;
+ }
+ }
+ if (NULL != szo) { *szo = osz; }
+ } break;
+ default : {
+
+
+#line 568 "dk4strmco.ctr"
+ back = dk4strmco_co_co(co, b, sz, szo);
+ } break;
+ }
+
+
+#line 572 "dk4strmco.ctr"
+ return back;
+}
+
+
+
+/** Flush data in output encoders if used.
+ @param co Compressor structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4strmco_co_oe_close(compressor_t *co)
+{
+ const char *dptr = NULL;
+ size_t sz = 0;
+ size_t j = 0;
+ int back = 1;
+ int res = 0;
+
+
+#line 591 "dk4strmco.ctr"
+ switch (co->oe) {
+ case DK4_STRMCO_OE_ASCII85 : {
+
+
+#line 594 "dk4strmco.ctr"
+ switch (dk4a85_enc_finish(&(co->u_oe.a85), NULL)) {
+
+
+#line 596 "dk4strmco.ctr"
+ case DK4_EDSTM_FINISHED : {
+ if (0 < dk4a85_enc_output(&dptr,&sz,&(co->u_oe.a85),NULL)) {
+ if (0 < sz) {
+#if VERSION_BEFORE_20161019
+ back = dk4stream_write(co->dststrm, dptr, sz, NULL);
+#else
+ back = 1;
+ for (j = 0; ((j < sz) && (1 == back)); j++) {
+ res = dk4stream_write_byte(
+ co->dststrm, dptr[j], NULL
+ );
+ if (0 < res) {
+ co->ll += 1;
+ if (75 <= co->ll) {
+ res = dk4strmco_nl(co);
+ if (0 < res) {
+ co->ll = 0;
+ }
+ else {
+ back = 0;
+ }
+ }
+ }
+ else {
+ back = 0;
+ }
+ }
+#endif
+ }
+ }
+ else {
+ back = 0;
+ }
+ } break;
+ }
+ if (0 != (DK4_STRMCO_FL_EOD_OE & (co->fl))) {
+
+
+#line 633 "dk4strmco.ctr"
+ res = dk4stream_write(co->dststrm, a85fin, 2, NULL);
+ if (0 == res) {
+ back = 0;
+ }
+ }
+ if (0 != (DK4_STRMCO_FL_NL_OE & (co->fl))) {
+
+
+#line 640 "dk4strmco.ctr"
+ if (0 == dk4strmco_nl(co)) {
+ back = 0;
+ }
+ }
+ } break;
+ case DK4_STRMCO_OE_HEX : {
+ if (0 != (DK4_STRMCO_FL_EOD_OE & (co->fl))) {
+
+
+#line 648 "dk4strmco.ctr"
+ back = dk4stream_write(co->dststrm, ahfin, 1, NULL);
+ }
+ if (0 != (DK4_STRMCO_FL_NL_OE & (co->fl))) {
+
+
+#line 652 "dk4strmco.ctr"
+ if (0 == dk4strmco_nl(co)) {
+ back = 0;
+ }
+ }
+ } break;
+ }
+
+
+#line 659 "dk4strmco.ctr"
+ return back;
+}
+
+
+
+/** Flush data from flate compressor if used.
+ @param co Compressor structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4strmco_co_co_close(compressor_t *co)
+{
+ const unsigned char *cptr;
+ size_t used = 0;
+ int back = 1;
+ int zres = Z_OK;
+ int res = 0;
+
+
+#line 678 "dk4strmco.ctr"
+ switch (co->co) {
+ case DK4_STRMCO_CO_FLATE : {
+
+
+#line 681 "dk4strmco.ctr"
+ co->u_co.zs.next_in = (unsigned char *)nl;
+ co->u_co.zs.avail_in = 0;
+ do {
+ co->u_co.zs.next_out = (unsigned char *)(&(co->zbuf[0]));
+ co->u_co.zs.avail_out = DK4_STRMCO_ZBUF_SIZE;
+ zres = deflate(&(co->u_co.zs), Z_FINISH);
+
+
+#line 688 "dk4strmco.ctr"
+ switch (zres) {
+ case Z_OK : case Z_STREAM_END : {
+ used = DK4_STRMCO_ZBUF_SIZE - co->u_co.zs.avail_out;
+
+
+#line 692 "dk4strmco.ctr"
+ if (0 < used) {
+ res = dk4strmco_co_oe(co,&(co->zbuf[0]),used,NULL);
+ if (0 == res) {
+ back = 0;
+ }
+ }
+ } break;
+ default : {
+ back = 0;
+ } break;
+ }
+ } while ((Z_OK == zres) && (1 == back));
+
+
+#line 705 "dk4strmco.ctr"
+ if (Z_OK != deflateEnd(&(co->u_co.zs))) {
+ back = 0;
+ }
+ } break;
+ case DK4_STRMCO_CO_LZW : {
+ res = dk4lzwe_finish(&(co->u_co.lzw), NULL);
+ switch (res) {
+ case DK4_EDSTM_FINISHED : {
+ cptr = NULL;
+ used = 0;
+ res = dk4lzwe_output(
+ &cptr, &used, &(co->u_co.lzw), NULL
+ );
+ if ((0 != res) && (NULL != cptr) && (0 < used)) {
+ back = dk4strmco_co_oe(
+ co, (const char *)cptr, used, NULL
+ );
+ }
+ else {
+ back = 0;
+ }
+ } break;
+ case DK4_EDSTM_ERROR : {
+ back = 0;
+ } break;
+ }
+ } break;
+ }
+
+
+#line 734 "dk4strmco.ctr"
+ return back;
+}
+
+
+
+/** Flush data from run-length encoder if used.
+ @param co Compressor structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4strmco_co_pp_close(compressor_t *co)
+{
+ const unsigned char *dptr = NULL;
+ size_t szd = 0;
+ int back = 1;
+ int res;
+
+
+#line 752 "dk4strmco.ctr"
+ switch (co->pp) {
+ case DK4_STRMCO_PP_RUNLENGTH : {
+
+
+#line 755 "dk4strmco.ctr"
+ switch (dk4rle_finish(&(co->u_pp.rle), NULL)) {
+ case DK4_EDSTM_ACCEPT : {
+ } break;
+ case DK4_EDSTM_FINISHED : {
+
+
+#line 760 "dk4strmco.ctr"
+ if (0 < dk4rle_output(&dptr, &szd, &(co->u_pp.rle), NULL)) {
+ res = dk4strmco_co_write(
+ co, (const char *)dptr, szd, NULL
+ );
+ if (0 == res) {
+
+#line 765 "dk4strmco.ctr"
+ back = 0;
+ }
+ }
+ else {
+
+#line 769 "dk4strmco.ctr"
+ back = 0;
+ }
+ } break;
+ default : {
+ } break;
+ }
+ } break;
+ }
+
+
+#line 778 "dk4strmco.ctr"
+ return back;
+}
+
+
+
+/** Finish output (flush data stored in the encoders).
+ @param co Compressor structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4strmco_co_close(compressor_t *co)
+{
+ int back = 1;
+
+
+#line 793 "dk4strmco.ctr"
+ /* Flush preprocessor (run-length encoder).
+ */
+ if (0 == dk4strmco_co_pp_close(co)) {
+ back = 0;
+ }
+ /* Flush compressor (flate stream).
+ */
+ if (0 == dk4strmco_co_co_close(co)) {
+ back = 0;
+ }
+ /* Flush output encoder (ASCII-Hex or ASCII-85 encoder).
+ */
+ if (0 == dk4strmco_co_oe_close(co)) {
+ back = 0;
+ }
+ /* Release memory.
+ */
+
+
+#line 811 "dk4strmco.ctr"
+ if (0 == dk4mem_reset_secure(co, sizeof(compressor_t), NULL)) {
+ back = 0;
+ }
+
+
+#line 815 "dk4strmco.ctr"
+ dk4mem_free(co);
+
+
+#line 817 "dk4strmco.ctr"
+ return back;
+}
+
+
+
+void
+dk4strmco_handler(dk4_stream_api_t *api)
+{
+ compressor_t *co = NULL;
+
+
+#line 827 "dk4strmco.ctr"
+ if (NULL != api) {
+ api->res = 0;
+ api->sz_out = 0;
+ co = (compressor_t *)(api->d);
+ switch (api->cmd) {
+ case DK4_STREAM_API_WRITE : {
+
+#line 833 "dk4strmco.ctr"
+ api->res = dk4strmco_co_write(
+ co, api->b, api->sz_in, &(api->sz_out)
+ );
+ } break;
+ case DK4_STREAM_API_FLUSH : {
+
+#line 838 "dk4strmco.ctr"
+ /*
+ Do nothing but indicate success.
+ Otherwise closing a stream will return an error.
+ */
+ api->res = 1;
+ } break;
+ case DK4_STREAM_API_CLOSE : {
+
+#line 845 "dk4strmco.ctr"
+ api->res = dk4strmco_co_close(co);
+ } break;
+ case DK4_STREAM_API_ZERO_READ_IS_EOF : {
+
+#line 848 "dk4strmco.ctr"
+ api->res = 0;
+ } break;
+ default : {
+
+#line 851 "dk4strmco.ctr"
+ /* Error: Functions not available */
+ } break;
+ }
+ }
+
+
+#line 856 "dk4strmco.ctr"
+}
+
+
+
+dk4_stream_t *
+dk4strmco_open(
+ dk4_stream_t *strm,
+ enum dk4_strmco_pp pp,
+ enum dk4_strmco_co co,
+ enum dk4_strmco_oe oe,
+ int fl,
+ dk4_er_t *erp
+)
+{
+ dk4_stream_t *back = NULL;
+ compressor_t *cc = NULL;
+
+
+#line 873 "dk4strmco.ctr"
+ /* Allocate compressor and set up.
+ */
+
+
+#line 876 "dk4strmco.ctr"
+ cc = dk4mem_new(compressor_t,1,erp);
+ if (NULL != cc) {
+ cc->dststrm = strm;
+ cc->pp = pp;
+ cc->co = co;
+ cc->oe = oe;
+ cc->fl = fl;
+ cc->ll = 0;
+ switch (pp) {
+ case DK4_STRMCO_PP_RUNLENGTH : {
+
+
+#line 887 "dk4strmco.ctr"
+ dk4rle_init(
+ &(cc->u_pp.rle),
+ ((0 != (DK4_STRMCO_FL_EOD_PP & fl)) ? 1 : 0),
+ erp
+ );
+ } break;
+ default : {
+ } break;
+ }
+ switch (co) {
+ case DK4_STRMCO_CO_FLATE : {
+
+
+#line 899 "dk4strmco.ctr"
+ cc->u_co.zs.zalloc = Z_NULL;
+ cc->u_co.zs.zfree = Z_NULL;
+ cc->u_co.zs.opaque = Z_NULL;
+
+
+#line 903 "dk4strmco.ctr"
+ if (Z_OK != deflateInit(&(cc->u_co.zs), 9)) {
+
+
+#line 905 "dk4strmco.ctr"
+ dk4mem_free(cc);
+ cc = NULL;
+
+
+#line 908 "dk4strmco.ctr"
+ }
+ } break;
+ case DK4_STRMCO_CO_LZW : {
+
+
+#line 912 "dk4strmco.ctr"
+ if (0 == dk4lzwe_init(&(cc->u_co.lzw), NULL)) {
+
+
+#line 914 "dk4strmco.ctr"
+ dk4mem_free(cc);
+ cc = NULL;
+
+
+#line 917 "dk4strmco.ctr"
+ }
+ } break;
+ default : {
+ } break;
+ }
+ switch (oe) {
+ case DK4_STRMCO_OE_ASCII85 : {
+
+
+#line 925 "dk4strmco.ctr"
+ dk4a85_enc_init(&(cc->u_oe.a85), 1, erp);
+ } break;
+ default : {
+ } break;
+ }
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 933 "dk4strmco.ctr"
+ }
+#endif
+
+ /* If the compressor was set up successfully, create stream.
+ */
+ if (NULL != cc) {
+
+
+#line 940 "dk4strmco.ctr"
+ back = dk4stream_open(cc,dk4strmco_handler,DK4_STREAM_WRITE,0,4096,erp);
+ /*
+ When failed to create stream, we must release the compressor.
+ */
+ if (NULL == back) {
+ /*
+ Release dynamic resources assigned to components.
+ */
+
+
+#line 949 "dk4strmco.ctr"
+ switch (co) {
+ case DK4_STRMCO_CO_FLATE : {
+
+
+#line 952 "dk4strmco.ctr"
+ (void)deflateEnd(&(cc->u_co.zs));
+ } break;
+ case DK4_STRMCO_CO_LZW : {
+
+
+#line 956 "dk4strmco.ctr"
+ (void)dk4lzwe_finish(&(cc->u_co.lzw), NULL);
+ } break;
+ default : {
+ } break;
+ }
+
+
+#line 962 "dk4strmco.ctr"
+ dk4mem_free(cc);
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 966 "dk4strmco.ctr"
+ }
+#endif
+ }
+
+
+#line 970 "dk4strmco.ctr"
+ return back;
+}
+
+
+
+/* vim: set ai sw=4 ts=4 : */
+
diff --git a/support/dktools/dk4strmco.ctr b/support/dktools/dk4strmco.ctr
new file mode 100644
index 0000000000..6bd073c309
--- /dev/null
+++ b/support/dktools/dk4strmco.ctr
@@ -0,0 +1,976 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+
+%% header
+
+/** @file dk4strmco.h Compression streams.
+
+A compression stream is an additional dk4_stream_t object on top of
+an existring stream (referred to as downside stream).
+
+Data written to the compression stream is compressed using one or multiple
+algorithms:
+
+- Run-length encoding as preprocessing.
+- Flate compression or LZW compression.
+- ASCII-Hex or ASCII-85 output encoding.
+
+The results of the compression operations are passed to the downside stream.
+
+Note: Closing the compression stream does not close the downside stream.
+
+So you create a mixed stream (i.e. for PDF files) containing both plain
+text and compressed chunks. To add a compressed chunk open a compression
+stream on top of the existing output stream, pass data to the compression
+stream, close the compression stream and continue writing to the output
+stream.
+
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4STRM_H_INCLUDED
+#include "dk4strm.h"
+#endif
+
+
+/** Preprocessing before compression.
+*/
+enum dk4_strmco_pp {
+ DK4_STRMCO_PP_NONE = 0 , /**< No preprocessing. */
+ DK4_STRMCO_PP_RUNLENGTH /**< Use run-length before real compression. */
+};
+
+
+/** Compression method.
+*/
+enum dk4_strmco_co {
+ DK4_STRMCO_CO_NONE = 0 , /**< No compression. */
+ DK4_STRMCO_CO_FLATE , /**< Use flate compression. */
+ DK4_STRMCO_CO_LZW /**< Use LZW compression for PS level 2. */
+};
+
+
+/** Output encoding.
+*/
+enum dk4_strmco_oe {
+ DK4_STRMCO_OE_NONE = 0 , /**< No output encoding. */
+ DK4_STRMCO_OE_HEX , /**< Hexadecimal encoding. */
+ DK4_STRMCO_OE_ASCII85 /**< ASCII85 encoding. */
+};
+
+
+/** Flags for compression stream.
+*/
+enum {
+ DK4_STRMCO_FL_EOD_PP = 1 , /**< Write EOD marker at end of preproc. */
+ DK4_STRMCO_FL_EOD_OE = 2 , /**< Write EOD marker at end of out enc. */
+ DK4_STRMCO_FL_NL_OE = 4 , /**< Break output lines before 80. */
+ DK4_STRMCO_FL_CR_NL = 8 , /**< Use CR/NL combination. */
+ DK4_STRMCO_FL_UPPER_OE = 16 , /**< Upper case characters in hex digits. */
+};
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open a compressing stream on top of an existing stream.
+ Only write operations can be performed on the new stream, no
+ read operations.
+ @param strm Low-level destination stream, must be writable.
+ @param pp Preprocessing method.
+ @param co Compression method.
+ @param oe Output encoding.
+ @param fl Flags.
+ @param erp Error report, may be NULL.
+ @return Valid pointer to new stream on success, NULL on error.
+*/
+dk4_stream_t *
+dk4strmco_open(
+ dk4_stream_t *strm,
+ enum dk4_strmco_pp pp,
+ enum dk4_strmco_co co,
+ enum dk4_strmco_oe oe,
+ int fl,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/* vim: set ai sw=4 ts=4 : */
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_ZLIB_H
+#ifndef ZLIB_H_INCLUDED
+#include <zlib.h>
+#define ZLIB_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4rle.h"
+#include "dk4a85e.h"
+#include "dk4strmco.h"
+#include "dk4mem.h"
+#include "dk4memrs.h"
+#include "dk4lzwe.h"
+
+
+$!trace-include
+
+
+
+#ifndef DK4_STRMCO_ZBUF_SIZE
+#define DK4_STRMCO_ZBUF_SIZE 4096
+#endif
+
+
+
+/** Compressor data structure.
+*/
+typedef struct {
+ char zbuf[DK4_STRMCO_ZBUF_SIZE]; /**< Output buffer. */
+ union {
+#if DK4_HAVE_ZLIB_H
+ z_stream zs; /**< Flate compression structure. */
+#endif
+ dk4_lzwe_t lzw; /**< LZW compression structure. */
+ } u_co; /**< Compression structures. */
+ union {
+ dk4_rl_enc_t rle; /**< Run-length encoder. */
+ } u_pp; /**< Preprocessing structures. */
+ union {
+ dk4_a85_enc_t a85; /**< ASCII-85 encoder. */
+ } u_oe; /**< Output encoding structures. */
+ dk4_stream_t *dststrm; /**< Destination stream. */
+ size_t ll; /**< Line length. */
+ int pp; /**< Preprocessing. */
+ int co; /**< Compression. */
+ int oe; /**< Output encoding. */
+ int fl; /**< Flags. */
+} compressor_t;
+
+
+
+/** Newline.
+*/
+static char nl[] = {
+ '\n', '\0'
+};
+
+
+
+/** Carriage return and newline.
+*/
+static char crnl[] = {
+ '\r', '\n', '\0'
+};
+
+
+
+/** Finalizer for ASCII-Hex encoding.
+*/
+static char ahfin[] = {
+ '>', '\0'
+};
+
+
+
+/** Finalizer for ASCII-85 encoding.
+*/
+static char a85fin[] = {
+ '~', '>', '\0'
+};
+
+
+
+/** Hexadecimal digits using lower case characters.
+*/
+static char lower[] = {
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', '\0'
+};
+
+
+
+/** Hexadecimal digits using upper case characters.
+*/
+static char upper[] = {
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', '\0'
+};
+
+
+
+/** Write newline to destination stream.
+ @param co Compressor structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4strmco_nl(compressor_t *co)
+{
+ int back = 0;
+ $? "+ dk4strmco_nl"
+ if (0 != (DK4_STRMCO_FL_CR_NL & (co->fl))) {
+ back = dk4stream_write(co->dststrm, crnl, 2, NULL);
+ }
+ else {
+ back = dk4stream_write(co->dststrm, nl, 1, NULL);
+ }
+ $? "- dk4strmco_nl %d", back
+ return back;
+}
+
+
+
+
+/** Write bytes to compressor at output encoding level.
+ @param co Compressor to write to.
+ @param b Buffer start address.
+ @param sz Number of bytes to write.
+ @param szo Address of variable for number of bytes written, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4strmco_co_oe(
+ compressor_t *co,
+ const char *b,
+ size_t sz,
+ size_t *szo
+)
+{
+ char buf[8]; /* Buffer for hexadecimal digits. */
+ const char *dptr; /* Pointer to A85 encoding result. */
+ size_t osz = 0; /* Number of bytes processed. */
+ size_t szd = 0; /* A85 encoding result length. */
+ size_t i = 0; /* Index of current byte to process. */
+ size_t j = 0; /* Index of cur out char. */
+ int back = 0; /* Function result. */
+ int res; /* Result from various operations. */
+ unsigned us; /* Index in hex digits array. */
+ unsigned char uc; /* UC version of current character */
+ $? "+ dk4strmco_co_oe"
+ switch (co->oe) {
+ case DK4_STRMCO_OE_ASCII85 : {
+ $? ". ASCII-85 encoding"
+ back = 1;
+ for (i = 0; ((i < sz) && (1 == back)); i++) {
+ switch (dk4a85_enc_add(&(co->u_oe.a85), b[i], NULL)) {
+ case DK4_EDSTM_ACCEPT : {
+ osz++;
+ } break;
+ case DK4_EDSTM_FINISHED : {
+ dptr = NULL;
+ szd = 0;
+ res = dk4a85_enc_output(
+ &dptr, &szd, &(co->u_oe.a85), NULL
+ );
+ if (0 < res) {
+ if (0 < szd) {
+#if VERSION_BEFORE_20161019
+ res = dk4stream_write(
+ co->dststrm, dptr, szd, NULL
+ );
+ if (0 < res) {
+ osz++;
+ co->ll += szd;
+ if (0 != (DK4_STRMCO_FL_NL_OE & (co->fl))) {
+ if (74 <= co->ll) {
+ res = dk4strmco_nl(co);
+ if (0 < res) {
+ co->ll = 0;
+ }
+ else {
+ back = 0;
+ }
+ }
+ }
+ }
+ else {
+ back = 0;
+ }
+#else
+ back = 1;
+ for (j = 0; ((j < szd) && (1 == back)); j++) {
+ res = dk4stream_write_byte(
+ co->dststrm, dptr[j], NULL
+ );
+ if (0 < res) {
+ osz++;
+ co->ll += 1;
+ if (75 <= co->ll) {
+ res = dk4strmco_nl(co);
+ if (0 < res) {
+ co->ll = 0;
+ }
+ else {
+ back = 0;
+ }
+ }
+ }
+ else {
+ back = 0;
+ }
+ }
+#endif
+ }
+ else {
+ osz++;
+ }
+ }
+ else {
+ back = 0;
+ }
+ } break;
+ default : {
+ back = 0;
+ } break;
+ }
+ }
+ } break;
+ case DK4_STRMCO_OE_HEX : {
+ $? ". ASCII-Hex encoding"
+ back = 1;
+ buf[2] = '\0';
+ for (i = 0; ((i < sz) && (1 == back)); i++) {
+ uc = (unsigned char)(b[i]);
+ us = 0x000FU & ((unsigned char)uc);
+ if (0 != (DK4_STRMCO_FL_UPPER_OE & (co->fl))) {
+ buf[1] = upper[us];
+ }
+ else {
+ buf[1] = lower[us];
+ }
+ us = 0x000FU & (((unsigned char)uc) >> 4);
+ if (0 != (DK4_STRMCO_FL_UPPER_OE & (co->fl))) {
+ buf[0] = upper[us];
+ }
+ else {
+ buf[0] = lower[us];
+ }
+ res = dk4stream_write(co->dststrm, buf, 2, NULL);
+ co->ll += 2;
+ if (0 < res) {
+ osz++;
+ if (0 != (DK4_STRMCO_FL_NL_OE & (co->fl))) {
+ if (78 <= co->ll) {
+ res = dk4strmco_nl(co);
+ if (0 < res) {
+ co->ll = 0;
+ }
+ else {
+ back = 0;
+ }
+ }
+ }
+ }
+ else {
+ back = 0;
+ }
+ }
+ } break;
+ default : {
+ $? ". no encoding"
+ back = dk4stream_write(co->dststrm, b, sz, NULL);
+ if (0 != back) {
+ osz = sz;
+ }
+ } break;
+ }
+ if (NULL != szo) { *szo = osz; }
+ $? "- dk4strmco_co_oe %d", back
+ return back;
+}
+
+
+
+/** Write bytes to compressor at compression level.
+ @param co Compressor to write to.
+ @param b Buffer start address.
+ @param sz Number of bytes to write.
+ @param szo Address of variable for number of bytes written, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4strmco_co_co(
+ compressor_t *co,
+ const char *b,
+ size_t sz,
+ size_t *szo
+)
+{
+ const unsigned char *cptr;
+ size_t osz = 0; /* Number of bytes processed successfully. */
+ size_t used = 0; /* Used bytes in output buffer. */
+ size_t i = 0; /* Index of current LZW byte to process. */
+ size_t lzwsz = 0; /* Bytes from LZW compression. */
+ int back = 0; /* Function result. */
+ int res = 0; /* Result from various operations. */
+ $? "+ dk4strmco_co_co"
+ switch (co->co) {
+ case DK4_STRMCO_CO_FLATE : {
+ $? ". flate compression"
+ back = 1;
+ co->u_co.zs.next_in = (unsigned char *)b;
+ co->u_co.zs.avail_in = sz;
+ do {
+ co->u_co.zs.next_out = (unsigned char *)(&(co->zbuf[0]));
+ co->u_co.zs.avail_out = DK4_STRMCO_ZBUF_SIZE;
+ res = deflate(&(co->u_co.zs), Z_NO_FLUSH);
+ switch (res) {
+ case Z_OK : {
+ used = DK4_STRMCO_ZBUF_SIZE - co->u_co.zs.avail_out;
+ if (0 < used) {
+ res = dk4strmco_co_oe(co,&(co->zbuf[0]),used,NULL);
+ if (0 < res) {
+ osz = sz - co->u_co.zs.avail_in;
+ }
+ else {
+ back = 0;
+ }
+ }
+ else {
+ osz = sz - co->u_co.zs.avail_in;
+ }
+ } break;
+ default : {
+ back = 0;
+ } break;
+ }
+ } while ((0 < co->u_co.zs.avail_in) && (1 == back));
+ if (NULL != szo) { *szo = osz; }
+ } break;
+ case DK4_STRMCO_CO_LZW : {
+ back = 1;
+ for (i = 0; ((1 == back) && (i < sz)); i++) {
+ res = dk4lzwe_add(&(co->u_co.lzw), (unsigned char)(b[i]), NULL);
+ switch (res) {
+ case DK4_EDSTM_ACCEPT : {
+ osz++;
+ } break;
+ case DK4_EDSTM_FINISHED : {
+ cptr = NULL;
+ lzwsz = 0;
+ res = dk4lzwe_output(
+ &cptr, &lzwsz, &(co->u_co.lzw), NULL
+ );
+ if ((0 != res) && (NULL != cptr) && (0 < lzwsz)) {
+ back = dk4strmco_co_oe(
+ co, (const char *)cptr, lzwsz, NULL
+ );
+ if (0 != back) {
+ osz++;
+ }
+ }
+ else {
+ back = 0;
+ }
+ } break;
+ case DK4_EDSTM_ERROR : {
+ back = 0;
+ } break;
+ }
+ }
+ if (NULL != szo) { *szo = osz; }
+ } break;
+ default : {
+ $? ". no compression"
+ back = dk4strmco_co_oe(co, b, sz, szo);
+ } break;
+ }
+ $? "- dk4strmco_co_co %d", back
+ return back;
+}
+
+
+
+/** Write bytes to compressor at preprocessor level.
+ @param co Compressor to write to.
+ @param b Buffer start address.
+ @param sz Number of bytes to write.
+ @param szo Address of variable for number of bytes written, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4strmco_co_write(
+ compressor_t *co,
+ const char *b,
+ size_t sz,
+ size_t *szo
+)
+{
+ const unsigned char *rleptr; /* RL encoding result */
+ size_t osz = 0; /* Bytes processed successfully */
+ size_t i; /* Running index of current byte */
+ size_t rlesz; /* Size of RL encoding result */
+ int back = 0; /* Function result */
+ int res; /* Result from various operations */
+ $? "+ dk4strmco_co_write"
+ switch (co->pp) {
+ case DK4_STRMCO_PP_RUNLENGTH : {
+ $? ". run-length preprocessing"
+ back = 1;
+ for (i = 0; ((i < sz) && (0 != back)); i++) {
+ switch (dk4rle_add(&(co->u_pp.rle),(unsigned char)(b[i]),NULL))
+ {
+ case DK4_EDSTM_FINISHED : {
+ rleptr = NULL;
+ rlesz = 0;
+ res = dk4rle_output(
+ &rleptr, &rlesz, &(co->u_pp.rle), NULL
+ );
+ if (0 != res) {
+ res = dk4strmco_co_co(
+ co, (const char *)rleptr, rlesz, NULL
+ );
+ if (0 != res) {
+ osz++;
+ }
+ else {
+ back = 0;
+ }
+ }
+ else {
+ back = 0;
+ }
+ } break;
+ case DK4_EDSTM_ERROR : {
+ back = 0;
+ } break;
+ default : {
+ osz++;
+ } break;
+ }
+ }
+ if (NULL != szo) { *szo = osz; }
+ } break;
+ default : {
+ $? ". no preprocessing"
+ back = dk4strmco_co_co(co, b, sz, szo);
+ } break;
+ }
+ $? "- dk4strmco_co_write %d", back
+ return back;
+}
+
+
+
+/** Flush data in output encoders if used.
+ @param co Compressor structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4strmco_co_oe_close(compressor_t *co)
+{
+ const char *dptr = NULL;
+ size_t sz = 0;
+ size_t j = 0;
+ int back = 1;
+ int res = 0;
+ $? "+ dk4strmco_co_oe_close"
+ switch (co->oe) {
+ case DK4_STRMCO_OE_ASCII85 : {
+ $? ". ASCII-85"
+ switch (dk4a85_enc_finish(&(co->u_oe.a85), NULL)) {
+ $? ". handle final A85 data"
+ case DK4_EDSTM_FINISHED : {
+ if (0 < dk4a85_enc_output(&dptr,&sz,&(co->u_oe.a85),NULL)) {
+ if (0 < sz) {
+#if VERSION_BEFORE_20161019
+ back = dk4stream_write(co->dststrm, dptr, sz, NULL);
+#else
+ back = 1;
+ for (j = 0; ((j < sz) && (1 == back)); j++) {
+ res = dk4stream_write_byte(
+ co->dststrm, dptr[j], NULL
+ );
+ if (0 < res) {
+ co->ll += 1;
+ if (75 <= co->ll) {
+ res = dk4strmco_nl(co);
+ if (0 < res) {
+ co->ll = 0;
+ }
+ else {
+ back = 0;
+ }
+ }
+ }
+ else {
+ back = 0;
+ }
+ }
+#endif
+ }
+ }
+ else {
+ back = 0;
+ }
+ } break;
+ }
+ if (0 != (DK4_STRMCO_FL_EOD_OE & (co->fl))) {
+ $? ". write EOD marker"
+ res = dk4stream_write(co->dststrm, a85fin, 2, NULL);
+ if (0 == res) {
+ back = 0;
+ }
+ }
+ if (0 != (DK4_STRMCO_FL_NL_OE & (co->fl))) {
+ $? ". line end"
+ if (0 == dk4strmco_nl(co)) {
+ back = 0;
+ }
+ }
+ } break;
+ case DK4_STRMCO_OE_HEX : {
+ if (0 != (DK4_STRMCO_FL_EOD_OE & (co->fl))) {
+ $? ". write EOD marker"
+ back = dk4stream_write(co->dststrm, ahfin, 1, NULL);
+ }
+ if (0 != (DK4_STRMCO_FL_NL_OE & (co->fl))) {
+ $? ". line end"
+ if (0 == dk4strmco_nl(co)) {
+ back = 0;
+ }
+ }
+ } break;
+ }
+ $? "- dk4strmco_co_oe_close %d", back
+ return back;
+}
+
+
+
+/** Flush data from flate compressor if used.
+ @param co Compressor structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4strmco_co_co_close(compressor_t *co)
+{
+ const unsigned char *cptr;
+ size_t used = 0;
+ int back = 1;
+ int zres = Z_OK;
+ int res = 0;
+ $? "+ dk4strmco_co_co_close"
+ switch (co->co) {
+ case DK4_STRMCO_CO_FLATE : {
+ $? ". flate compression used"
+ co->u_co.zs.next_in = (unsigned char *)nl;
+ co->u_co.zs.avail_in = 0;
+ do {
+ co->u_co.zs.next_out = (unsigned char *)(&(co->zbuf[0]));
+ co->u_co.zs.avail_out = DK4_STRMCO_ZBUF_SIZE;
+ zres = deflate(&(co->u_co.zs), Z_FINISH);
+ $? ". zres = %d", zres
+ switch (zres) {
+ case Z_OK : case Z_STREAM_END : {
+ used = DK4_STRMCO_ZBUF_SIZE - co->u_co.zs.avail_out;
+ $? ". used = %u", (unsigned)used
+ if (0 < used) {
+ res = dk4strmco_co_oe(co,&(co->zbuf[0]),used,NULL);
+ if (0 == res) {
+ back = 0;
+ }
+ }
+ } break;
+ default : {
+ back = 0;
+ } break;
+ }
+ } while ((Z_OK == zres) && (1 == back));
+ $? ". deflateEnd"
+ if (Z_OK != deflateEnd(&(co->u_co.zs))) {
+ back = 0;
+ }
+ } break;
+ case DK4_STRMCO_CO_LZW : {
+ res = dk4lzwe_finish(&(co->u_co.lzw), NULL);
+ switch (res) {
+ case DK4_EDSTM_FINISHED : {
+ cptr = NULL;
+ used = 0;
+ res = dk4lzwe_output(
+ &cptr, &used, &(co->u_co.lzw), NULL
+ );
+ if ((0 != res) && (NULL != cptr) && (0 < used)) {
+ back = dk4strmco_co_oe(
+ co, (const char *)cptr, used, NULL
+ );
+ }
+ else {
+ back = 0;
+ }
+ } break;
+ case DK4_EDSTM_ERROR : {
+ back = 0;
+ } break;
+ }
+ } break;
+ }
+ $? "- dk4strmco_co_co_close %d", back
+ return back;
+}
+
+
+
+/** Flush data from run-length encoder if used.
+ @param co Compressor structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4strmco_co_pp_close(compressor_t *co)
+{
+ const unsigned char *dptr = NULL;
+ size_t szd = 0;
+ int back = 1;
+ int res;
+ $? "+ dk4strmco_co_pp_close"
+ switch (co->pp) {
+ case DK4_STRMCO_PP_RUNLENGTH : {
+ $? ". run-length preprocessing used"
+ switch (dk4rle_finish(&(co->u_pp.rle), NULL)) {
+ case DK4_EDSTM_ACCEPT : {
+ } break;
+ case DK4_EDSTM_FINISHED : {
+ $? ". data in encoder"
+ if (0 < dk4rle_output(&dptr, &szd, &(co->u_pp.rle), NULL)) {
+ res = dk4strmco_co_write(
+ co, (const char *)dptr, szd, NULL
+ );
+ if (0 == res) { $? "! failed to write final data"
+ back = 0;
+ }
+ }
+ else { $? "! failed to retrieve final data"
+ back = 0;
+ }
+ } break;
+ default : {
+ } break;
+ }
+ } break;
+ }
+ $? "- dk4strmco_co_pp_close %d", back
+ return back;
+}
+
+
+
+/** Finish output (flush data stored in the encoders).
+ @param co Compressor structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4strmco_co_close(compressor_t *co)
+{
+ int back = 1;
+ $? "+ dk4strmco_co_close"
+ /* Flush preprocessor (run-length encoder).
+ */
+ if (0 == dk4strmco_co_pp_close(co)) {
+ back = 0;
+ }
+ /* Flush compressor (flate stream).
+ */
+ if (0 == dk4strmco_co_co_close(co)) {
+ back = 0;
+ }
+ /* Flush output encoder (ASCII-Hex or ASCII-85 encoder).
+ */
+ if (0 == dk4strmco_co_oe_close(co)) {
+ back = 0;
+ }
+ /* Release memory.
+ */
+ $? ". reset memory"
+ if (0 == dk4mem_reset_secure(co, sizeof(compressor_t), NULL)) {
+ back = 0;
+ }
+ $? ". release memory"
+ dk4mem_free(co);
+ $? "- dk4strmco_co_close %d", back
+ return back;
+}
+
+
+
+void
+dk4strmco_handler(dk4_stream_api_t *api)
+{
+ compressor_t *co = NULL;
+ $? "+ dk4strmco_handler %d", api->cmd
+ if (NULL != api) {
+ api->res = 0;
+ api->sz_out = 0;
+ co = (compressor_t *)(api->d);
+ switch (api->cmd) {
+ case DK4_STREAM_API_WRITE : { $? ". write"
+ api->res = dk4strmco_co_write(
+ co, api->b, api->sz_in, &(api->sz_out)
+ );
+ } break;
+ case DK4_STREAM_API_FLUSH : { $? ". flush (ignored)"
+ /*
+ Do nothing but indicate success.
+ Otherwise closing a stream will return an error.
+ */
+ api->res = 1;
+ } break;
+ case DK4_STREAM_API_CLOSE : { $? ". close"
+ api->res = dk4strmco_co_close(co);
+ } break;
+ case DK4_STREAM_API_ZERO_READ_IS_EOF : { $? ". zero read is eof"
+ api->res = 0;
+ } break;
+ default : { $? "! any else"
+ /* Error: Functions not available */
+ } break;
+ }
+ }
+ $? "- dk4strmco_handler %d", api->res
+}
+
+
+
+dk4_stream_t *
+dk4strmco_open(
+ dk4_stream_t *strm,
+ enum dk4_strmco_pp pp,
+ enum dk4_strmco_co co,
+ enum dk4_strmco_oe oe,
+ int fl,
+ dk4_er_t *erp
+)
+{
+ dk4_stream_t *back = NULL;
+ compressor_t *cc = NULL;
+ $? "+ dk4strmco_open"
+ /* Allocate compressor and set up.
+ */
+ $? ". allocate memory"
+ cc = dk4mem_new(compressor_t,1,erp);
+ if (NULL != cc) {
+ cc->dststrm = strm;
+ cc->pp = pp;
+ cc->co = co;
+ cc->oe = oe;
+ cc->fl = fl;
+ cc->ll = 0;
+ switch (pp) {
+ case DK4_STRMCO_PP_RUNLENGTH : {
+ $? ". initialize run-length encoder"
+ dk4rle_init(
+ &(cc->u_pp.rle),
+ ((0 != (DK4_STRMCO_FL_EOD_PP & fl)) ? 1 : 0),
+ erp
+ );
+ } break;
+ default : {
+ } break;
+ }
+ switch (co) {
+ case DK4_STRMCO_CO_FLATE : {
+ $? ". initialize flate compression"
+ cc->u_co.zs.zalloc = Z_NULL;
+ cc->u_co.zs.zfree = Z_NULL;
+ cc->u_co.zs.opaque = Z_NULL;
+ $? ". deflateInit"
+ if (Z_OK != deflateInit(&(cc->u_co.zs), 9)) {
+ $? ". release memory"
+ dk4mem_free(cc);
+ cc = NULL;
+ $? "! failed to initialize flate compression"
+ }
+ } break;
+ case DK4_STRMCO_CO_LZW : {
+ $? ". initialize LZW compression"
+ if (0 == dk4lzwe_init(&(cc->u_co.lzw), NULL)) {
+ $? ". release memory"
+ dk4mem_free(cc);
+ cc = NULL;
+ $? "! failed to initialize LZW compression"
+ }
+ } break;
+ default : {
+ } break;
+ }
+ switch (oe) {
+ case DK4_STRMCO_OE_ASCII85 : {
+ $? ". initialize ASCII-85 output encoding"
+ dk4a85_enc_init(&(cc->u_oe.a85), 1, erp);
+ } break;
+ default : {
+ } break;
+ }
+ }
+#if TRACE_DEBUG
+ else { $? "! memory"
+ }
+#endif
+
+ /* If the compressor was set up successfully, create stream.
+ */
+ if (NULL != cc) {
+ $? ". create stream"
+ back = dk4stream_open(cc,dk4strmco_handler,DK4_STREAM_WRITE,0,4096,erp);
+ /*
+ When failed to create stream, we must release the compressor.
+ */
+ if (NULL == back) {
+ /*
+ Release dynamic resources assigned to components.
+ */
+ $? "! failed to create stream"
+ switch (co) {
+ case DK4_STRMCO_CO_FLATE : {
+ $? ". deflateEnd"
+ (void)deflateEnd(&(cc->u_co.zs));
+ } break;
+ case DK4_STRMCO_CO_LZW : {
+ $? ". LZW finish"
+ (void)dk4lzwe_finish(&(cc->u_co.lzw), NULL);
+ } break;
+ default : {
+ } break;
+ }
+ $? ". release memory"
+ dk4mem_free(cc);
+ }
+#if TRACE_DEBUG
+ else { $? ". stream created"
+ }
+#endif
+ }
+ $? "- dk4strmco_open %d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/* vim: set ai sw=4 ts=4 : */
+
diff --git a/support/dktools/dk4strmco.h b/support/dktools/dk4strmco.h
new file mode 100644
index 0000000000..c698b3c9f9
--- /dev/null
+++ b/support/dktools/dk4strmco.h
@@ -0,0 +1,149 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4strmco.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4STRMCO_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4STRMCO_H_INCLUDED 1
+
+
+#line 9 "dk4strmco.ctr"
+
+/** @file dk4strmco.h Compression streams.
+
+A compression stream is an additional dk4_stream_t object on top of
+an existring stream (referred to as downside stream).
+
+Data written to the compression stream is compressed using one or multiple
+algorithms:
+
+- Run-length encoding as preprocessing.
+- Flate compression or LZW compression.
+- ASCII-Hex or ASCII-85 output encoding.
+
+The results of the compression operations are passed to the downside stream.
+
+Note: Closing the compression stream does not close the downside stream.
+
+So you create a mixed stream (i.e. for PDF files) containing both plain
+text and compressed chunks. To add a compressed chunk open a compression
+stream on top of the existing output stream, pass data to the compression
+stream, close the compression stream and continue writing to the output
+stream.
+
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4STRM_H_INCLUDED
+#include "dk4strm.h"
+#endif
+
+
+/** Preprocessing before compression.
+*/
+enum dk4_strmco_pp {
+ DK4_STRMCO_PP_NONE = 0 , /**< No preprocessing. */
+ DK4_STRMCO_PP_RUNLENGTH /**< Use run-length before real compression. */
+};
+
+
+/** Compression method.
+*/
+enum dk4_strmco_co {
+ DK4_STRMCO_CO_NONE = 0 , /**< No compression. */
+ DK4_STRMCO_CO_FLATE , /**< Use flate compression. */
+ DK4_STRMCO_CO_LZW /**< Use LZW compression for PS level 2. */
+};
+
+
+/** Output encoding.
+*/
+enum dk4_strmco_oe {
+ DK4_STRMCO_OE_NONE = 0 , /**< No output encoding. */
+ DK4_STRMCO_OE_HEX , /**< Hexadecimal encoding. */
+ DK4_STRMCO_OE_ASCII85 /**< ASCII85 encoding. */
+};
+
+
+/** Flags for compression stream.
+*/
+enum {
+ DK4_STRMCO_FL_EOD_PP = 1 , /**< Write EOD marker at end of preproc. */
+ DK4_STRMCO_FL_EOD_OE = 2 , /**< Write EOD marker at end of out enc. */
+ DK4_STRMCO_FL_NL_OE = 4 , /**< Break output lines before 80. */
+ DK4_STRMCO_FL_CR_NL = 8 , /**< Use CR/NL combination. */
+ DK4_STRMCO_FL_UPPER_OE = 16 , /**< Upper case characters in hex digits. */
+};
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open a compressing stream on top of an existing stream.
+ Only write operations can be performed on the new stream, no
+ read operations.
+ @param strm Low-level destination stream, must be writable.
+ @param pp Preprocessing method.
+ @param co Compression method.
+ @param oe Output encoding.
+ @param fl Flags.
+ @param erp Error report, may be NULL.
+ @return Valid pointer to new stream on success, NULL on error.
+*/
+dk4_stream_t *
+dk4strmco_open(
+ dk4_stream_t *strm,
+ enum dk4_strmco_pp pp,
+ enum dk4_strmco_co co,
+ enum dk4_strmco_oe oe,
+ int fl,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/* vim: set ai sw=4 ts=4 : */
+
+#endif
diff --git a/support/dktools/dk4strmf.c b/support/dktools/dk4strmf.c
new file mode 100644
index 0000000000..e042de4e6c
--- /dev/null
+++ b/support/dktools/dk4strmf.c
@@ -0,0 +1,147 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4strmf.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4strmf.c The dk4strmf module.
+*/
+
+
+#line 105 "dk4strmf.ctr"
+
+
+#include "dk4strmf.h"
+
+#ifndef STDIO_H_INCLUDED
+#include <stdio.h>
+#define STDIO_H_INCLUDED 1
+#endif
+
+
+void
+dk4stream_file_with_close_function(dk4_stream_api_t *api)
+{
+ FILE *fipo;
+ size_t res;
+ if (NULL != api) {
+ api->res = 0;
+ api->sz_out = 0;
+ fipo = (FILE *)(api->d);
+ if (NULL != fipo) {
+ switch (api->cmd) {
+ case DK4_STREAM_API_READ: {
+ res = fread(api->b, 1, api->sz_in, fipo);
+ api->sz_out = res;
+ if (0 < res) {
+ api->res = 1;
+ }
+ } break;
+ case DK4_STREAM_API_WRITE: {
+ res = fwrite(api->b, 1, api->sz_in, fipo);
+ if (res == api->sz_in) {
+ api->res = 1;
+ }
+ api->sz_out = res;
+ } break;
+ case DK4_STREAM_API_FLUSH: {
+ if (0 == fflush(fipo)) {
+ api->res = 1;
+ }
+ } break;
+ case DK4_STREAM_API_AT_END: {
+ if (0 != feof(fipo)) {
+ api->res = 1;
+ }
+ } break;
+ case DK4_STREAM_API_CLOSE: {
+ if (0 == fclose(fipo)) {
+ api->res = 1;
+ }
+ } break;
+ }
+ }
+ }
+}
+
+
+
+void
+dk4stream_file_function(dk4_stream_api_t *api)
+{
+ if (NULL != api) {
+ switch (api->cmd) {
+ case DK4_STREAM_API_CLOSE: {
+ api->res = 1;
+ } break;
+ default: {
+ dk4stream_file_with_close_function(api);
+ } break;
+ }
+ }
+}
+
+
+
+
+dk4_stream_t *
+dk4stream_open_for_file(
+ FILE *fipo,
+ int fl,
+ size_t ibs,
+ size_t obs,
+ dk4_er_t *erp
+)
+{
+ return (
+ dk4stream_open( (void *)fipo, dk4stream_file_function, fl, ibs, obs, erp )
+ );
+}
+
+
+
+dk4_stream_t *
+dk4stream_open_for_file_with_close(
+ FILE *fipo,
+ int fl,
+ size_t ibs,
+ size_t obs,
+ dk4_er_t *erp
+)
+{
+ return (
+ dk4stream_open(
+ (void *)fipo, dk4stream_file_with_close_function, fl, ibs, obs, erp
+ )
+ );
+}
+
diff --git a/support/dktools/dk4strmf.ctr b/support/dktools/dk4strmf.ctr
new file mode 100644
index 0000000000..24851d08c3
--- /dev/null
+++ b/support/dktools/dk4strmf.ctr
@@ -0,0 +1,211 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Generic dk4_stream_t API for input
+ and output, implementation for FILE.
+
+ CRT on Windows: Required.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4STRM_H_INCLUDED
+#include "dk4strm.h"
+#endif
+
+#ifndef STDIO_H_INCLUDED
+#include <stdio.h>
+#define STDIO_H_INCLUDED 1
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Low level function to access a FILE.
+ @param api The stream API structure for arguments and results.
+*/
+void
+dk4stream_file_function(dk4_stream_api_t *api);
+
+/** Low level function to access a FILE and close it on
+ dk4stream_close().
+ @param api The stream API structure for arguments and results.
+*/
+void
+dk4stream_file_with_close_function(dk4_stream_api_t *api);
+
+/** Open a stream for an existing file.
+ @param fipo Existing file, not closed on dk4stream_close().
+ @param fl Access flag: DK4_STREAM_READ,, DK4_STREAM_WRITE
+ or (DK4_STREAM_READ | DK4_STREAM_WRITE).
+ @param ibs Input buffer size (0 for default).
+ @param obs Output buffer size (0 for default).
+ @param erp Error report, may be NULL.
+ @return Pointer to stream on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if obj or fct is NULL or fl is invalid,
+ - DK4_E_MATH_OVERFLOW<br>
+ if ibs or obs is too large,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if allocation of input or output buffer failed.
+*/
+dk4_stream_t *
+dk4stream_open_for_file(
+ FILE *fipo,
+ int fl,
+ size_t ibs,
+ size_t obs,
+ dk4_er_t *erp
+);
+
+/** Open a stream for an existing file.
+ @param fipo Existing file, closed on dk4stream_close().
+ @param fl Access flag: DK4_STREAM_READ,, DK4_STREAM_WRITE
+ or (DK4_STREAM_READ | DK4_STREAM_WRITE).
+ @param ibs Input buffer size (0 for default).
+ @param obs Output buffer size (0 for default).
+ @param erp Error report, may be NULL.
+ @return Pointer to stream on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if obj or fct is NULL or fl is invalid,
+ - DK4_E_MATH_OVERFLOW<br>
+ if ibs or obs is too large,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if allocation of input or output buffer failed.
+*/
+dk4_stream_t *
+dk4stream_open_for_file_with_close(
+ FILE *fipo,
+ int fl,
+ size_t ibs,
+ size_t obs,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+
+#include "dk4strmf.h"
+
+#ifndef STDIO_H_INCLUDED
+#include <stdio.h>
+#define STDIO_H_INCLUDED 1
+#endif
+
+
+void
+dk4stream_file_with_close_function(dk4_stream_api_t *api)
+{
+ FILE *fipo;
+ size_t res;
+ if (NULL != api) {
+ api->res = 0;
+ api->sz_out = 0;
+ fipo = (FILE *)(api->d);
+ if (NULL != fipo) {
+ switch (api->cmd) {
+ case DK4_STREAM_API_READ: {
+ res = fread(api->b, 1, api->sz_in, fipo);
+ api->sz_out = res;
+ if (0 < res) {
+ api->res = 1;
+ }
+ } break;
+ case DK4_STREAM_API_WRITE: {
+ res = fwrite(api->b, 1, api->sz_in, fipo);
+ if (res == api->sz_in) {
+ api->res = 1;
+ }
+ api->sz_out = res;
+ } break;
+ case DK4_STREAM_API_FLUSH: {
+ if (0 == fflush(fipo)) {
+ api->res = 1;
+ }
+ } break;
+ case DK4_STREAM_API_AT_END: {
+ if (0 != feof(fipo)) {
+ api->res = 1;
+ }
+ } break;
+ case DK4_STREAM_API_CLOSE: {
+ if (0 == fclose(fipo)) {
+ api->res = 1;
+ }
+ } break;
+ }
+ }
+ }
+}
+
+
+
+void
+dk4stream_file_function(dk4_stream_api_t *api)
+{
+ if (NULL != api) {
+ switch (api->cmd) {
+ case DK4_STREAM_API_CLOSE: {
+ api->res = 1;
+ } break;
+ default: {
+ dk4stream_file_with_close_function(api);
+ } break;
+ }
+ }
+}
+
+
+
+
+dk4_stream_t *
+dk4stream_open_for_file(
+ FILE *fipo,
+ int fl,
+ size_t ibs,
+ size_t obs,
+ dk4_er_t *erp
+)
+{
+ return (
+ dk4stream_open( (void *)fipo, dk4stream_file_function, fl, ibs, obs, erp )
+ );
+}
+
+
+
+dk4_stream_t *
+dk4stream_open_for_file_with_close(
+ FILE *fipo,
+ int fl,
+ size_t ibs,
+ size_t obs,
+ dk4_er_t *erp
+)
+{
+ return (
+ dk4stream_open(
+ (void *)fipo, dk4stream_file_with_close_function, fl, ibs, obs, erp
+ )
+ );
+}
+
diff --git a/support/dktools/dk4strmf.h b/support/dktools/dk4strmf.h
new file mode 100644
index 0000000000..d61962aadf
--- /dev/null
+++ b/support/dktools/dk4strmf.h
@@ -0,0 +1,137 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4strmf.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4STRMF_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4STRMF_H_INCLUDED 1
+
+
+#line 10 "dk4strmf.ctr"
+
+/** @file
+ Generic dk4_stream_t API for input
+ and output, implementation for FILE.
+
+ CRT on Windows: Required.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4STRM_H_INCLUDED
+#include "dk4strm.h"
+#endif
+
+#ifndef STDIO_H_INCLUDED
+#include <stdio.h>
+#define STDIO_H_INCLUDED 1
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Low level function to access a FILE.
+ @param api The stream API structure for arguments and results.
+*/
+void
+dk4stream_file_function(dk4_stream_api_t *api);
+
+/** Low level function to access a FILE and close it on
+ dk4stream_close().
+ @param api The stream API structure for arguments and results.
+*/
+void
+dk4stream_file_with_close_function(dk4_stream_api_t *api);
+
+/** Open a stream for an existing file.
+ @param fipo Existing file, not closed on dk4stream_close().
+ @param fl Access flag: DK4_STREAM_READ,, DK4_STREAM_WRITE
+ or (DK4_STREAM_READ | DK4_STREAM_WRITE).
+ @param ibs Input buffer size (0 for default).
+ @param obs Output buffer size (0 for default).
+ @param erp Error report, may be NULL.
+ @return Pointer to stream on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if obj or fct is NULL or fl is invalid,
+ - DK4_E_MATH_OVERFLOW<br>
+ if ibs or obs is too large,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if allocation of input or output buffer failed.
+*/
+dk4_stream_t *
+dk4stream_open_for_file(
+ FILE *fipo,
+ int fl,
+ size_t ibs,
+ size_t obs,
+ dk4_er_t *erp
+);
+
+/** Open a stream for an existing file.
+ @param fipo Existing file, closed on dk4stream_close().
+ @param fl Access flag: DK4_STREAM_READ,, DK4_STREAM_WRITE
+ or (DK4_STREAM_READ | DK4_STREAM_WRITE).
+ @param ibs Input buffer size (0 for default).
+ @param obs Output buffer size (0 for default).
+ @param erp Error report, may be NULL.
+ @return Pointer to stream on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if obj or fct is NULL or fl is invalid,
+ - DK4_E_MATH_OVERFLOW<br>
+ if ibs or obs is too large,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if allocation of input or output buffer failed.
+*/
+dk4_stream_t *
+dk4stream_open_for_file_with_close(
+ FILE *fipo,
+ int fl,
+ size_t ibs,
+ size_t obs,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4strmg.c b/support/dktools/dk4strmg.c
new file mode 100644
index 0000000000..3bfb99fa6f
--- /dev/null
+++ b/support/dktools/dk4strmg.c
@@ -0,0 +1,151 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4strmg.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4strmg.c The dk4strmg module.
+*/
+
+
+#line 93 "dk4strmg.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_ZLIB_H
+
+#include "dk4strm.h"
+#include "dk4strmg.h"
+
+
+
+void
+dk4stream_gzfile_with_close_function(dk4_stream_api_t *api)
+{
+ gzFile fipo;
+ int res;
+ if (NULL != api) {
+ api->res = 0;
+ api->sz_out = 0;
+ fipo = (gzFile)(api->d);
+ if (NULL != fipo) {
+ switch (api->cmd) {
+ case DK4_STREAM_API_READ: {
+ res = gzread(fipo, api->b, (int)(api->sz_in));
+ if (0 < res) {
+ api->res = 1;
+ api->sz_out = (size_t)res;
+ }
+ } break;
+ case DK4_STREAM_API_WRITE: {
+ res = gzwrite(fipo, api->b, (int)(api->sz_in));
+ if (res == (int)(api->sz_in)) {
+ api->res = 1;
+ }
+ if (0 <= res) { api->sz_out = (size_t)res; }
+ else { api->sz_out = 0; }
+ } break;
+ case DK4_STREAM_API_FLUSH: {
+ if (Z_OK == gzflush(fipo, Z_FULL_FLUSH)) {
+ api->res = 1;
+ }
+ } break;
+ case DK4_STREAM_API_AT_END: {
+ if (1 == gzeof(fipo)) {
+ api->res = 1;
+ }
+ } break;
+ case DK4_STREAM_API_CLOSE: {
+ if (Z_OK == gzclose(fipo)) {
+ api->res = 1;
+ }
+ } break;
+ }
+ }
+ } else {
+ }
+}
+
+
+
+void
+dk4stream_gzfile_function(dk4_stream_api_t *api)
+{
+ if (NULL != api) {
+ switch (api->cmd) {
+ case DK4_STREAM_API_CLOSE: {
+ api->res = 1;
+ } break;
+ default: {
+ dk4stream_gzfile_with_close_function(api);
+ } break;
+ }
+ }
+}
+
+
+
+dk4_stream_t *
+dk4stream_open_for_gzfile(
+ gzFile fipo,
+ int fl,
+ size_t ibs,
+ size_t obs,
+ dk4_er_t *erp
+)
+{
+ return (
+ dk4stream_open( (void *)fipo, dk4stream_gzfile_function, fl, ibs, obs, erp )
+ );
+}
+
+
+
+dk4_stream_t *
+dk4stream_open_for_gzfile_with_close(
+ gzFile fipo,
+ int fl,
+ size_t ibs,
+ size_t obs,
+ dk4_er_t *erp
+)
+{
+ return (
+ dk4stream_open(
+ (void *)fipo, dk4stream_gzfile_with_close_function, fl, ibs, obs, erp
+ )
+ );
+}
+
+
+#endif
+
diff --git a/support/dktools/dk4strmg.ctr b/support/dktools/dk4strmg.ctr
new file mode 100644
index 0000000000..31678d0be3
--- /dev/null
+++ b/support/dktools/dk4strmg.ctr
@@ -0,0 +1,203 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Generic dk4_stream_t API for input
+ and output, implementation for gzfile.
+
+ CRT on Windows: Required.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_ZLIB_H
+
+#ifndef DK4STRM_H_INCLUDED
+#include "dk4strm.h"
+#endif
+
+#ifndef ZLIB_H_INCLUDED
+#include <zlib.h>
+#define ZLIB_H_INCLUDED 1
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Low level function to access a gzFile.
+ @param api The stream API structure for arguments and results.
+*/
+void
+dk4stream_gzfile_function(dk4_stream_api_t *api);
+
+/** Low level function to access a gzFile and close it on
+ dk4stream_close().
+ @param api The stream API structure for arguments and results.
+*/
+void
+dk4stream_gzfile_with_close_function(dk4_stream_api_t *api);
+
+/** Open a stream for an existing gzFile.
+ @param fipo Existing gzFile, not closed on dk4stream_close().
+ @param fl Access flag: DK4_STREAM_READ,, DK4_STREAM_WRITE
+ or (DK4_STREAM_READ | DK4_STREAM_WRITE).
+ @param ibs Input buffer size (0 for default).
+ @param obs Output buffer size (0 for default).
+ @param erp Error report, may be NULL.
+ @return Pointer to stream on success, NULL on error.
+*/
+dk4_stream_t *
+dk4stream_open_for_gzfile(
+ gzFile fipo,
+ int fl,
+ size_t ibs,
+ size_t obs,
+ dk4_er_t *erp
+);
+
+/** Open a stream for an existing gzFile.
+ @param fipo Existing gzFile, closed on dk4stream_close().
+ @param fl Access flag: DK4_STREAM_READ,, DK4_STREAM_WRITE
+ or (DK4_STREAM_READ | DK4_STREAM_WRITE).
+ @param ibs Input buffer size (0 for default).
+ @param obs Output buffer size (0 for default).
+ @param erp Error report, may be NULL.
+ @return Pointer to stream on success, NULL on error.
+*/
+dk4_stream_t *
+dk4stream_open_for_gzfile_with_close(
+ gzFile fipo,
+ int fl,
+ size_t ibs,
+ size_t obs,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_ZLIB_H
+
+#include "dk4strm.h"
+#include "dk4strmg.h"
+
+
+
+void
+dk4stream_gzfile_with_close_function(dk4_stream_api_t *api)
+{
+ gzFile fipo;
+ int res;
+ if (NULL != api) {
+ api->res = 0;
+ api->sz_out = 0;
+ fipo = (gzFile)(api->d);
+ if (NULL != fipo) {
+ switch (api->cmd) {
+ case DK4_STREAM_API_READ: {
+ res = gzread(fipo, api->b, (int)(api->sz_in));
+ if (0 < res) {
+ api->res = 1;
+ api->sz_out = (size_t)res;
+ }
+ } break;
+ case DK4_STREAM_API_WRITE: {
+ res = gzwrite(fipo, api->b, (int)(api->sz_in));
+ if (res == (int)(api->sz_in)) {
+ api->res = 1;
+ }
+ if (0 <= res) { api->sz_out = (size_t)res; }
+ else { api->sz_out = 0; }
+ } break;
+ case DK4_STREAM_API_FLUSH: {
+ if (Z_OK == gzflush(fipo, Z_FULL_FLUSH)) {
+ api->res = 1;
+ }
+ } break;
+ case DK4_STREAM_API_AT_END: {
+ if (1 == gzeof(fipo)) {
+ api->res = 1;
+ }
+ } break;
+ case DK4_STREAM_API_CLOSE: {
+ if (Z_OK == gzclose(fipo)) {
+ api->res = 1;
+ }
+ } break;
+ }
+ }
+ } else {
+ }
+}
+
+
+
+void
+dk4stream_gzfile_function(dk4_stream_api_t *api)
+{
+ if (NULL != api) {
+ switch (api->cmd) {
+ case DK4_STREAM_API_CLOSE: {
+ api->res = 1;
+ } break;
+ default: {
+ dk4stream_gzfile_with_close_function(api);
+ } break;
+ }
+ }
+}
+
+
+
+dk4_stream_t *
+dk4stream_open_for_gzfile(
+ gzFile fipo,
+ int fl,
+ size_t ibs,
+ size_t obs,
+ dk4_er_t *erp
+)
+{
+ return (
+ dk4stream_open( (void *)fipo, dk4stream_gzfile_function, fl, ibs, obs, erp )
+ );
+}
+
+
+
+dk4_stream_t *
+dk4stream_open_for_gzfile_with_close(
+ gzFile fipo,
+ int fl,
+ size_t ibs,
+ size_t obs,
+ dk4_er_t *erp
+)
+{
+ return (
+ dk4stream_open(
+ (void *)fipo, dk4stream_gzfile_with_close_function, fl, ibs, obs, erp
+ )
+ );
+}
+
+
+#endif
+
diff --git a/support/dktools/dk4strmg.h b/support/dktools/dk4strmg.h
new file mode 100644
index 0000000000..e506bab3c9
--- /dev/null
+++ b/support/dktools/dk4strmg.h
@@ -0,0 +1,125 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4strmg.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4STRMG_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4STRMG_H_INCLUDED 1
+
+
+#line 10 "dk4strmg.ctr"
+
+/** @file
+ Generic dk4_stream_t API for input
+ and output, implementation for gzfile.
+
+ CRT on Windows: Required.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_HAVE_ZLIB_H
+
+#ifndef DK4STRM_H_INCLUDED
+#include "dk4strm.h"
+#endif
+
+#ifndef ZLIB_H_INCLUDED
+#include <zlib.h>
+#define ZLIB_H_INCLUDED 1
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Low level function to access a gzFile.
+ @param api The stream API structure for arguments and results.
+*/
+void
+dk4stream_gzfile_function(dk4_stream_api_t *api);
+
+/** Low level function to access a gzFile and close it on
+ dk4stream_close().
+ @param api The stream API structure for arguments and results.
+*/
+void
+dk4stream_gzfile_with_close_function(dk4_stream_api_t *api);
+
+/** Open a stream for an existing gzFile.
+ @param fipo Existing gzFile, not closed on dk4stream_close().
+ @param fl Access flag: DK4_STREAM_READ,, DK4_STREAM_WRITE
+ or (DK4_STREAM_READ | DK4_STREAM_WRITE).
+ @param ibs Input buffer size (0 for default).
+ @param obs Output buffer size (0 for default).
+ @param erp Error report, may be NULL.
+ @return Pointer to stream on success, NULL on error.
+*/
+dk4_stream_t *
+dk4stream_open_for_gzfile(
+ gzFile fipo,
+ int fl,
+ size_t ibs,
+ size_t obs,
+ dk4_er_t *erp
+);
+
+/** Open a stream for an existing gzFile.
+ @param fipo Existing gzFile, closed on dk4stream_close().
+ @param fl Access flag: DK4_STREAM_READ,, DK4_STREAM_WRITE
+ or (DK4_STREAM_READ | DK4_STREAM_WRITE).
+ @param ibs Input buffer size (0 for default).
+ @param obs Output buffer size (0 for default).
+ @param erp Error report, may be NULL.
+ @return Pointer to stream on success, NULL on error.
+*/
+dk4_stream_t *
+dk4stream_open_for_gzfile_with_close(
+ gzFile fipo,
+ int fl,
+ size_t ibs,
+ size_t obs,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4strmh.c b/support/dktools/dk4strmh.c
new file mode 100644
index 0000000000..5fbc629c9c
--- /dev/null
+++ b/support/dktools/dk4strmh.c
@@ -0,0 +1,201 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4strmh.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4strmh.c The dk4strmh module.
+*/
+
+
+#line 112 "dk4strmh.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+
+#include "dk4strmh.h"
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+/** Low level function to access a Windows handle.
+ @param api The stream API structure for arguments and results.
+ @param wc Flag: Close handle when closing the stream.
+*/
+static
+void
+dk4stream_windows_handle_static_function(dk4_stream_api_t *api, int wc)
+{
+ dk4_stream_handle_t *sh;
+ DWORD dwi;
+ DWORD dwo;
+
+ if (NULL != api) {
+ api->res = 0;
+ api->sz_out = 0;
+ sh = (dk4_stream_handle_t *)(api->d);
+ if (NULL != sh) {
+ switch (api->cmd) {
+ case DK4_STREAM_API_READ : {
+ if (0 == sh->feof) {
+ if ((dk4_um_t)0xFFFFFFFFUL < (dk4_um_t)(api->sz_in)) {
+ dwi = 0xFFFFFFFFUL;
+ } else {
+ dwi = (DWORD)(api->sz_in);
+ }
+ dwo = (DWORD)0UL;
+ if (ReadFile(sh->ha, api->b, dwi, &dwo, NULL)) {
+ if ((DWORD)0UL == dwo) { sh->feof = 1; }
+ api->sz_out = (size_t)dwo;
+ if ((DWORD)0UL < dwo) {
+ api->res = 1;
+ }
+ }
+ }
+ } break;
+ case DK4_STREAM_API_WRITE : {
+ if ((dk4_um_t)0xFFFFFFFFUL >= (dk4_um_t)(api->sz_in)) {
+ dwi = (DWORD)(api->sz_in);
+ dwo = (DWORD)0UL;
+ if (WriteFile(sh->ha, api->b, dwi, &dwo, NULL)) {
+ api->sz_out = dwo;
+ if (dwo == dwi) {
+ api->res = 1;
+ }
+ }
+ } else {
+ /* ERROR: Size too large */
+ }
+ } break;
+ case DK4_STREAM_API_FLUSH : {
+ api->res = 1; /* Dont know how to flush */
+ } break;
+ case DK4_STREAM_API_AT_END : {
+ if (0 != sh->feof) {
+ api->res = 1;
+ }
+ } break;
+ case DK4_STREAM_API_CLOSE : {
+ if (0 != wc) {
+ if (CloseHandle(sh->ha)) {
+ api->res = 1;
+ }
+ } else {
+ api->res = 1;
+ }
+ dk4mem_free(sh);
+ } break;
+ }
+ }
+ }
+}
+
+
+
+void
+dk4stream_windows_handle_with_close_function(dk4_stream_api_t *api)
+{
+ dk4stream_windows_handle_static_function(api, 1);
+}
+
+
+
+void
+dk4stream_windows_handle_function(dk4_stream_api_t *api)
+{
+ dk4stream_windows_handle_static_function(api, 0);
+}
+
+
+
+dk4_stream_t *
+dk4stream_open_for_windows_handle(
+ HANDLE ha,
+ int fl,
+ size_t ibs,
+ size_t obs,
+ dk4_er_t *erp
+)
+{
+ dk4_stream_handle_t *sh = NULL;
+ dk4_stream_t *back = NULL;
+
+ sh = dk4mem_new(dk4_stream_handle_t,1,erp);
+ if (NULL != sh) {
+ sh->ha = ha;
+ sh->feof = 0;
+ back = dk4stream_open(
+ (void *)sh, dk4stream_windows_handle_function, fl, ibs, obs, erp
+ );
+ if (NULL == back) {
+ dk4mem_free(sh);
+ }
+ }
+ return back;
+}
+
+
+
+dk4_stream_t *
+dk4stream_open_for_windows_handle_with_close(
+ HANDLE ha,
+ int fl,
+ size_t ibs,
+ size_t obs,
+ dk4_er_t *erp
+)
+{
+ dk4_stream_handle_t *sh = NULL;
+ dk4_stream_t *back = NULL;
+
+ sh = dk4mem_new(dk4_stream_handle_t,1,erp);
+ if (NULL != sh) {
+ sh->ha = ha;
+ sh->feof = 0;
+ back = dk4stream_open(
+ (void *)sh, dk4stream_windows_handle_with_close_function,
+ fl, ibs, obs, erp
+ );
+ if (NULL == back) {
+ dk4mem_free(sh);
+ }
+ }
+ return back;
+}
+
+
+
+#endif
+/* if DK4_ON_WINDOWS */
+
diff --git a/support/dktools/dk4strmh.ctr b/support/dktools/dk4strmh.ctr
new file mode 100644
index 0000000000..05df699e2f
--- /dev/null
+++ b/support/dktools/dk4strmh.ctr
@@ -0,0 +1,272 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Generic dk4_stream_t API for input
+ from Windows file handle.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_ON_WINDOWS
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4STRM_H_INCLUDED
+#include "dk4strm.h"
+#endif
+
+#ifndef STDIO_H_INCLUDED
+#include <stdio.h>
+#define STDIO_H_INCLUDED 1
+#endif
+
+/** Structure for keeping a HANDLE.
+*/
+typedef struct {
+ HANDLE ha; /**< Windows file handle. */
+ int feof; /**< Flag: Found EOF while reading. */
+} dk4_stream_handle_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Low level function to access a Windows handle.
+ @param api The stream API structure for arguments and results.
+*/
+void
+dk4stream_windows_handle_function(dk4_stream_api_t *api);
+
+/** Low level function to access a Windows handle and close it on
+ dk4stream_close().
+ @param api The stream API structure for arguments and results.
+*/
+void
+dk4stream_windows_handle_with_close_function(dk4_stream_api_t *api);
+
+/** Open a stream for an existing handle.
+ @param ha Existing file handle, not closed on dk4stream_close().
+ @param fl Access flag: DK4_STREAM_READ,, DK4_STREAM_WRITE
+ or (DK4_STREAM_READ | DK4_STREAM_WRITE).
+ @param ibs Input buffer size (0 for default).
+ @param obs Output buffer size (0 for default).
+ @param erp Error report, may be NULL.
+ @return Pointer to new stream on success, NULL on error.
+*/
+dk4_stream_t *
+dk4stream_open_for_windows_handle(
+ HANDLE ha,
+ int fl,
+ size_t ibs,
+ size_t obs,
+ dk4_er_t *erp
+);
+
+/** Open a stream for an existing handle.
+ @param ha Existing file handle, closed on dk4stream_close().
+ @param fl Access flag: DK4_STREAM_READ,, DK4_STREAM_WRITE
+ or (DK4_STREAM_READ | DK4_STREAM_WRITE).
+ @param ibs Input buffer size (0 for default).
+ @param obs Output buffer size (0 for default).
+ @param erp Error report, may be NULL.
+ @return Pointer to new stream on success, NULL on error.
+*/
+dk4_stream_t *
+dk4stream_open_for_windows_handle_with_close(
+ HANDLE ha,
+ int fl,
+ size_t ibs,
+ size_t obs,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+
+#include "dk4strmh.h"
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+/** Low level function to access a Windows handle.
+ @param api The stream API structure for arguments and results.
+ @param wc Flag: Close handle when closing the stream.
+*/
+static
+void
+dk4stream_windows_handle_static_function(dk4_stream_api_t *api, int wc)
+{
+ dk4_stream_handle_t *sh;
+ DWORD dwi;
+ DWORD dwo;
+
+ if (NULL != api) {
+ api->res = 0;
+ api->sz_out = 0;
+ sh = (dk4_stream_handle_t *)(api->d);
+ if (NULL != sh) {
+ switch (api->cmd) {
+ case DK4_STREAM_API_READ : {
+ if (0 == sh->feof) {
+ if ((dk4_um_t)0xFFFFFFFFUL < (dk4_um_t)(api->sz_in)) {
+ dwi = 0xFFFFFFFFUL;
+ } else {
+ dwi = (DWORD)(api->sz_in);
+ }
+ dwo = (DWORD)0UL;
+ if (ReadFile(sh->ha, api->b, dwi, &dwo, NULL)) {
+ if ((DWORD)0UL == dwo) { sh->feof = 1; }
+ api->sz_out = (size_t)dwo;
+ if ((DWORD)0UL < dwo) {
+ api->res = 1;
+ }
+ }
+ }
+ } break;
+ case DK4_STREAM_API_WRITE : {
+ if ((dk4_um_t)0xFFFFFFFFUL >= (dk4_um_t)(api->sz_in)) {
+ dwi = (DWORD)(api->sz_in);
+ dwo = (DWORD)0UL;
+ if (WriteFile(sh->ha, api->b, dwi, &dwo, NULL)) {
+ api->sz_out = dwo;
+ if (dwo == dwi) {
+ api->res = 1;
+ }
+ }
+ } else {
+ /* ERROR: Size too large */
+ }
+ } break;
+ case DK4_STREAM_API_FLUSH : {
+ api->res = 1; /* Dont know how to flush */
+ } break;
+ case DK4_STREAM_API_AT_END : {
+ if (0 != sh->feof) {
+ api->res = 1;
+ }
+ } break;
+ case DK4_STREAM_API_CLOSE : {
+ if (0 != wc) {
+ if (CloseHandle(sh->ha)) {
+ api->res = 1;
+ }
+ } else {
+ api->res = 1;
+ }
+ dk4mem_free(sh);
+ } break;
+ }
+ }
+ }
+}
+
+
+
+void
+dk4stream_windows_handle_with_close_function(dk4_stream_api_t *api)
+{
+ dk4stream_windows_handle_static_function(api, 1);
+}
+
+
+
+void
+dk4stream_windows_handle_function(dk4_stream_api_t *api)
+{
+ dk4stream_windows_handle_static_function(api, 0);
+}
+
+
+
+dk4_stream_t *
+dk4stream_open_for_windows_handle(
+ HANDLE ha,
+ int fl,
+ size_t ibs,
+ size_t obs,
+ dk4_er_t *erp
+)
+{
+ dk4_stream_handle_t *sh = NULL;
+ dk4_stream_t *back = NULL;
+
+ sh = dk4mem_new(dk4_stream_handle_t,1,erp);
+ if (NULL != sh) {
+ sh->ha = ha;
+ sh->feof = 0;
+ back = dk4stream_open(
+ (void *)sh, dk4stream_windows_handle_function, fl, ibs, obs, erp
+ );
+ if (NULL == back) {
+ dk4mem_free(sh);
+ }
+ }
+ return back;
+}
+
+
+
+dk4_stream_t *
+dk4stream_open_for_windows_handle_with_close(
+ HANDLE ha,
+ int fl,
+ size_t ibs,
+ size_t obs,
+ dk4_er_t *erp
+)
+{
+ dk4_stream_handle_t *sh = NULL;
+ dk4_stream_t *back = NULL;
+
+ sh = dk4mem_new(dk4_stream_handle_t,1,erp);
+ if (NULL != sh) {
+ sh->ha = ha;
+ sh->feof = 0;
+ back = dk4stream_open(
+ (void *)sh, dk4stream_windows_handle_with_close_function,
+ fl, ibs, obs, erp
+ );
+ if (NULL == back) {
+ dk4mem_free(sh);
+ }
+ }
+ return back;
+}
+
+
+
+#endif
+/* if DK4_ON_WINDOWS */
+
diff --git a/support/dktools/dk4strmh.h b/support/dktools/dk4strmh.h
new file mode 100644
index 0000000000..f107ae4fd8
--- /dev/null
+++ b/support/dktools/dk4strmh.h
@@ -0,0 +1,144 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4strmh.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4STRMH_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4STRMH_H_INCLUDED 1
+
+
+#line 10 "dk4strmh.ctr"
+
+/** @file
+ Generic dk4_stream_t API for input
+ from Windows file handle.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#if DK4_ON_WINDOWS
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4STRM_H_INCLUDED
+#include "dk4strm.h"
+#endif
+
+#ifndef STDIO_H_INCLUDED
+#include <stdio.h>
+#define STDIO_H_INCLUDED 1
+#endif
+
+/** Structure for keeping a HANDLE.
+*/
+typedef struct {
+ HANDLE ha; /**< Windows file handle. */
+ int feof; /**< Flag: Found EOF while reading. */
+} dk4_stream_handle_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Low level function to access a Windows handle.
+ @param api The stream API structure for arguments and results.
+*/
+void
+dk4stream_windows_handle_function(dk4_stream_api_t *api);
+
+/** Low level function to access a Windows handle and close it on
+ dk4stream_close().
+ @param api The stream API structure for arguments and results.
+*/
+void
+dk4stream_windows_handle_with_close_function(dk4_stream_api_t *api);
+
+/** Open a stream for an existing handle.
+ @param ha Existing file handle, not closed on dk4stream_close().
+ @param fl Access flag: DK4_STREAM_READ,, DK4_STREAM_WRITE
+ or (DK4_STREAM_READ | DK4_STREAM_WRITE).
+ @param ibs Input buffer size (0 for default).
+ @param obs Output buffer size (0 for default).
+ @param erp Error report, may be NULL.
+ @return Pointer to new stream on success, NULL on error.
+*/
+dk4_stream_t *
+dk4stream_open_for_windows_handle(
+ HANDLE ha,
+ int fl,
+ size_t ibs,
+ size_t obs,
+ dk4_er_t *erp
+);
+
+/** Open a stream for an existing handle.
+ @param ha Existing file handle, closed on dk4stream_close().
+ @param fl Access flag: DK4_STREAM_READ,, DK4_STREAM_WRITE
+ or (DK4_STREAM_READ | DK4_STREAM_WRITE).
+ @param ibs Input buffer size (0 for default).
+ @param obs Output buffer size (0 for default).
+ @param erp Error report, may be NULL.
+ @return Pointer to new stream on success, NULL on error.
+*/
+dk4_stream_t *
+dk4stream_open_for_windows_handle_with_close(
+ HANDLE ha,
+ int fl,
+ size_t ibs,
+ size_t obs,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4strmo08.c b/support/dktools/dk4strmo08.c
new file mode 100644
index 0000000000..bf665e9e2f
--- /dev/null
+++ b/support/dktools/dk4strmo08.c
@@ -0,0 +1,134 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4strmo08.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4strmo08.c The dk4strmo08 module.
+*/
+
+
+#line 51 "dk4strmo08.ctr"
+
+#include "dk4strm.h"
+#include "dk4strmo32.h"
+#include "dk4enc.h"
+#include "dk4ansi.h"
+#include "dk4utf8.h"
+
+int
+dk4stream_c08_puts(dk4_stream_t *strm, const char *txt, int ie, dk4_er_t *erp)
+{
+ dk4_utf8_decoder_t dec;
+ dk4_c32_t c32;
+ int back = 0;
+ char c;
+ unsigned char uc;
+ if ((NULL != strm) && (NULL != txt)) {
+ if (0 != ((strm->fl) & DK4_STREAM_WRITE)) {
+ switch (ie) {
+ case DK4_ENCODING_ASCII:
+ case DK4_ENCODING_ANSI:
+ case DK4_ENCODING_UTF8:
+ {
+ if (strm->oenc == ie) {
+ back = 1;
+ while (('\0' != *txt) && (1 == back)) {
+ if (0 == dk4stream_write_byte(strm, *(txt++), erp)) {
+ back = 0;
+ }
+ }
+ } else {
+ switch (ie) {
+ case DK4_ENCODING_ASCII: {
+ back = 1;
+ while (('\0' != *txt) && (1 == back)) {
+ c = *(txt++);
+ uc = (unsigned char)c;
+ c32 = (dk4_c32_t)uc;
+ if (0 == dk4stream_c32_putc(strm, c32, erp)) {
+ back = 0;
+ }
+ }
+ } break;
+ case DK4_ENCODING_ANSI: {
+ back = 1;
+ while (('\0' != *txt) && (1 == back)) {
+ if (0 != dk4ansi_decode(&c32, (unsigned char)(*(txt++)))) {
+ if (0 == dk4stream_c32_putc(strm, c32, erp)) {
+ back = 0;
+ }
+ } else {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_DECODING_FAILED);
+ }
+ }
+ } break;
+ case DK4_ENCODING_UTF8: {
+ back = 1;
+ dk4utf8_init(&dec);
+ while (('\0' != *txt) && (1 == back)) {
+ switch (dk4utf8_add(&dec, (unsigned char)(*(txt++)))) {
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf8_get(&dec);
+ dk4utf8_init(&dec);
+ if (0 == dk4stream_c32_putc(strm, c32, erp)) {
+ back = 0;
+ }
+ } break;
+ case DK4_EDSTM_ERROR: {
+ back = 0;
+ dk4error_set_simple_error_code(erp,DK4_E_DECODING_FAILED);
+ } break;
+ }
+ }
+ if (0 == dk4utf8_is_empty(&dec)) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_DECODING_FAILED);
+ }
+ } break;
+ }
+ }
+ } break;
+ default: {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4strmo08.ctr b/support/dktools/dk4strmo08.ctr
new file mode 100644
index 0000000000..02929a7042
--- /dev/null
+++ b/support/dktools/dk4strmo08.ctr
@@ -0,0 +1,144 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ String output over dk4_stream_t API,
+ 8 bit character strings.
+
+ CRT on Windows: Not used.
+*/
+
+#include "dk4strm.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Write 8 bit character string to stream.
+ @param strm Stream to write to.
+ @param txt Text to write.
+ @param ie Input encoding.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is NULL or not opened for writing,
+ - DK4_E_SYNTAX<br>
+ if ie does not indicate an 8 bit encoding,
+ - DK4_E_DECODING_FAILED<br>
+ if input decoding failed,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flusing data downwards failed.
+*/
+int
+dk4stream_c08_puts(dk4_stream_t *strm, const char *txt, int ie, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4strm.h"
+#include "dk4strmo32.h"
+#include "dk4enc.h"
+#include "dk4ansi.h"
+#include "dk4utf8.h"
+
+int
+dk4stream_c08_puts(dk4_stream_t *strm, const char *txt, int ie, dk4_er_t *erp)
+{
+ dk4_utf8_decoder_t dec;
+ dk4_c32_t c32;
+ int back = 0;
+ char c;
+ unsigned char uc;
+ if ((NULL != strm) && (NULL != txt)) {
+ if (0 != ((strm->fl) & DK4_STREAM_WRITE)) {
+ switch (ie) {
+ case DK4_ENCODING_ASCII:
+ case DK4_ENCODING_ANSI:
+ case DK4_ENCODING_UTF8:
+ {
+ if (strm->oenc == ie) {
+ back = 1;
+ while (('\0' != *txt) && (1 == back)) {
+ if (0 == dk4stream_write_byte(strm, *(txt++), erp)) {
+ back = 0;
+ }
+ }
+ } else {
+ switch (ie) {
+ case DK4_ENCODING_ASCII: {
+ back = 1;
+ while (('\0' != *txt) && (1 == back)) {
+ c = *(txt++);
+ uc = (unsigned char)c;
+ c32 = (dk4_c32_t)uc;
+ if (0 == dk4stream_c32_putc(strm, c32, erp)) {
+ back = 0;
+ }
+ }
+ } break;
+ case DK4_ENCODING_ANSI: {
+ back = 1;
+ while (('\0' != *txt) && (1 == back)) {
+ if (0 != dk4ansi_decode(&c32, (unsigned char)(*(txt++)))) {
+ if (0 == dk4stream_c32_putc(strm, c32, erp)) {
+ back = 0;
+ }
+ } else {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_DECODING_FAILED);
+ }
+ }
+ } break;
+ case DK4_ENCODING_UTF8: {
+ back = 1;
+ dk4utf8_init(&dec);
+ while (('\0' != *txt) && (1 == back)) {
+ switch (dk4utf8_add(&dec, (unsigned char)(*(txt++)))) {
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf8_get(&dec);
+ dk4utf8_init(&dec);
+ if (0 == dk4stream_c32_putc(strm, c32, erp)) {
+ back = 0;
+ }
+ } break;
+ case DK4_EDSTM_ERROR: {
+ back = 0;
+ dk4error_set_simple_error_code(erp,DK4_E_DECODING_FAILED);
+ } break;
+ }
+ }
+ if (0 == dk4utf8_is_empty(&dec)) {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_DECODING_FAILED);
+ }
+ } break;
+ }
+ }
+ } break;
+ default: {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
diff --git a/support/dktools/dk4strmo08.h b/support/dktools/dk4strmo08.h
new file mode 100644
index 0000000000..1cb54927df
--- /dev/null
+++ b/support/dktools/dk4strmo08.h
@@ -0,0 +1,83 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4strmo08.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4STRMO08_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4STRMO08_H_INCLUDED 1
+
+
+#line 10 "dk4strmo08.ctr"
+
+/** @file
+ String output over dk4_stream_t API,
+ 8 bit character strings.
+
+ CRT on Windows: Not used.
+*/
+
+#include "dk4strm.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Write 8 bit character string to stream.
+ @param strm Stream to write to.
+ @param txt Text to write.
+ @param ie Input encoding.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is NULL or not opened for writing,
+ - DK4_E_SYNTAX<br>
+ if ie does not indicate an 8 bit encoding,
+ - DK4_E_DECODING_FAILED<br>
+ if input decoding failed,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flusing data downwards failed.
+*/
+int
+dk4stream_c08_puts(dk4_stream_t *strm, const char *txt, int ie, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4strmo16.c b/support/dktools/dk4strmo16.c
new file mode 100644
index 0000000000..9afb4d709e
--- /dev/null
+++ b/support/dktools/dk4strmo16.c
@@ -0,0 +1,121 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4strmo16.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4strmo16.c The dk4strmo16 module.
+*/
+
+
+#line 53 "dk4strmo16.ctr"
+
+#include "dk4strmo16.h"
+#include "dk4strmo32.h"
+#include "dk4enc.h"
+#include "dk4utf16.h"
+
+
+int
+dk4stream_c16_puts(dk4_stream_t *strm, const dk4_c16_t *txt, dk4_er_t *erp)
+{
+ dk4_utf16_decoder_t enc;
+ dk4_c16_t c16;
+ dk4_c32_t c32;
+ int back = 0;
+ char c8;
+ if ((NULL != strm) && (NULL != txt)) {
+ if (0 != ((strm->fl) & DK4_STREAM_WRITE)) {
+ switch (strm->oenc) {
+ case DK4_FILE_ENCODING_UTF16_LE:
+ case DK4_FILE_ENCODING_UTF16_BE:
+ {
+ back = 1;
+ while((0 != *txt) && (1 == back)) {
+ c16 = *(txt++);
+ if (DK4_FILE_ENCODING_UTF16_LE == strm->oenc) {
+ c8 = (char)(c16 & 0x00FF);
+ if (0 == dk4stream_write_byte(strm, c8, erp)) {
+ back = 0;
+ } else {
+ c8 = (char)((c16 >> 8) & 0x00FF);
+ if (0 == dk4stream_write_byte(strm, c8, erp)) {
+ back = 0;
+ }
+ }
+ } else {
+ c8 = (char)((c16 >> 8) & 0x00FF);
+ if (0 == dk4stream_write_byte(strm, c8, erp)) {
+ back = 0;
+ } else {
+ c8 = (char)(c16 & 0x00FF);
+ if (0 == dk4stream_write_byte(strm, c8, erp)) {
+ back = 0;
+ }
+ }
+ }
+ }
+ } break;
+ default: {
+ back = 1;
+ dk4utf16_init(&enc);
+ while((0 != *txt) && (1 == back)) {
+ switch (dk4utf16_add(&enc, *(txt++))) {
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf16_get(&enc);
+ dk4utf16_init(&enc);
+ if (0 == dk4stream_c32_putc(strm, c32, erp)) {
+ back = 0;
+ }
+ } break;
+ case DK4_EDSTM_ERROR: {
+ back = 0;
+ dk4error_set_simple_error_code(erp,DK4_E_DECODING_FAILED);
+ } break;
+ }
+ }
+ if (0 == dk4utf16_is_empty(&enc)) {
+ back = 0;
+ dk4error_set_simple_error_code(erp,DK4_E_DECODING_FAILED);
+ }
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4strmo16.ctr b/support/dktools/dk4strmo16.ctr
new file mode 100644
index 0000000000..f7a562c26d
--- /dev/null
+++ b/support/dktools/dk4strmo16.ctr
@@ -0,0 +1,133 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ String output over dk4_stream_t API,
+ 16 bit character strings.
+
+ CRT on Windows: Not used.
+*/
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4strm.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Write one 32 bit character string to stream.
+ @param strm Stream to write to.
+ @param txt Text string to write.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is null or not set up for writing,
+ - DK4_E_ENCODING_FAILED<br>
+ if it is not possible to encode c32 to the output encoding for the
+ stream,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flushing data downwards failed.
+*/
+int
+dk4stream_c16_puts(dk4_stream_t *strm, const dk4_c16_t *txt, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4strmo16.h"
+#include "dk4strmo32.h"
+#include "dk4enc.h"
+#include "dk4utf16.h"
+
+
+int
+dk4stream_c16_puts(dk4_stream_t *strm, const dk4_c16_t *txt, dk4_er_t *erp)
+{
+ dk4_utf16_decoder_t enc;
+ dk4_c16_t c16;
+ dk4_c32_t c32;
+ int back = 0;
+ char c8;
+ if ((NULL != strm) && (NULL != txt)) {
+ if (0 != ((strm->fl) & DK4_STREAM_WRITE)) {
+ switch (strm->oenc) {
+ case DK4_FILE_ENCODING_UTF16_LE:
+ case DK4_FILE_ENCODING_UTF16_BE:
+ {
+ back = 1;
+ while((0 != *txt) && (1 == back)) {
+ c16 = *(txt++);
+ if (DK4_FILE_ENCODING_UTF16_LE == strm->oenc) {
+ c8 = (char)(c16 & 0x00FF);
+ if (0 == dk4stream_write_byte(strm, c8, erp)) {
+ back = 0;
+ } else {
+ c8 = (char)((c16 >> 8) & 0x00FF);
+ if (0 == dk4stream_write_byte(strm, c8, erp)) {
+ back = 0;
+ }
+ }
+ } else {
+ c8 = (char)((c16 >> 8) & 0x00FF);
+ if (0 == dk4stream_write_byte(strm, c8, erp)) {
+ back = 0;
+ } else {
+ c8 = (char)(c16 & 0x00FF);
+ if (0 == dk4stream_write_byte(strm, c8, erp)) {
+ back = 0;
+ }
+ }
+ }
+ }
+ } break;
+ default: {
+ back = 1;
+ dk4utf16_init(&enc);
+ while((0 != *txt) && (1 == back)) {
+ switch (dk4utf16_add(&enc, *(txt++))) {
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf16_get(&enc);
+ dk4utf16_init(&enc);
+ if (0 == dk4stream_c32_putc(strm, c32, erp)) {
+ back = 0;
+ }
+ } break;
+ case DK4_EDSTM_ERROR: {
+ back = 0;
+ dk4error_set_simple_error_code(erp,DK4_E_DECODING_FAILED);
+ } break;
+ }
+ }
+ if (0 == dk4utf16_is_empty(&enc)) {
+ back = 0;
+ dk4error_set_simple_error_code(erp,DK4_E_DECODING_FAILED);
+ }
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4strmo16.h b/support/dktools/dk4strmo16.h
new file mode 100644
index 0000000000..c5a5ab626f
--- /dev/null
+++ b/support/dktools/dk4strmo16.h
@@ -0,0 +1,85 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4strmo16.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4STRMO16_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4STRMO16_H_INCLUDED 1
+
+
+#line 10 "dk4strmo16.ctr"
+
+/** @file
+ String output over dk4_stream_t API,
+ 16 bit character strings.
+
+ CRT on Windows: Not used.
+*/
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4strm.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Write one 32 bit character string to stream.
+ @param strm Stream to write to.
+ @param txt Text string to write.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is null or not set up for writing,
+ - DK4_E_ENCODING_FAILED<br>
+ if it is not possible to encode c32 to the output encoding for the
+ stream,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flushing data downwards failed.
+*/
+int
+dk4stream_c16_puts(dk4_stream_t *strm, const dk4_c16_t *txt, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4strmo32.c b/support/dktools/dk4strmo32.c
new file mode 100644
index 0000000000..e2417e7cab
--- /dev/null
+++ b/support/dktools/dk4strmo32.c
@@ -0,0 +1,297 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4strmo32.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4strmo32.c The dk4strmo32 module.
+*/
+
+
+#line 95 "dk4strmo32.ctr"
+
+#include "dk4strmo32.h"
+#include "dk4mem.h"
+#include "dk4ansi.h"
+#include "dk4utf8.h"
+#include "dk4utf16.h"
+#include "dk4enc.h"
+
+
+
+
+
+#line 106 "dk4strmo32.ctr"
+
+
+
+void
+dk4stream_set_output_encoding(dk4_stream_t *strm, int oe)
+{
+
+
+#line 113 "dk4strmo32.ctr"
+ if (NULL != strm) {
+ switch (oe) {
+ case DK4_FILE_ENCODING_ASCII:
+ case DK4_FILE_ENCODING_ANSI:
+ case DK4_FILE_ENCODING_UTF8:
+ case DK4_FILE_ENCODING_UTF16_LE:
+ case DK4_FILE_ENCODING_UTF16_BE:
+ case DK4_FILE_ENCODING_32_LE:
+ case DK4_FILE_ENCODING_32_BE:
+ {
+ strm->oenc = oe;
+ } break;
+ }
+ }
+
+#line 127 "dk4strmo32.ctr"
+}
+
+
+
+int
+dk4stream_c32_putc(dk4_stream_t *strm, dk4_c32_t c32, dk4_er_t *erp)
+{
+ unsigned char buf[16];
+ dk4_c16_t b16[4];
+ size_t sz;
+ int back = 0;
+
+
+#line 139 "dk4strmo32.ctr"
+ if (NULL != strm) {
+
+#line 140 "dk4strmo32.ctr"
+ if (0 != ((strm->fl) & DK4_STREAM_WRITE)) {
+
+#line 141 "dk4strmo32.ctr"
+ switch (strm->oenc) {
+ case DK4_FILE_ENCODING_ASCII: {
+
+#line 143 "dk4strmo32.ctr"
+ if (dkC32(0x00000100) > c32) {
+ back = dk4stream_write_byte(strm, (unsigned char)c32, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_ENCODING_FAILED);
+ }
+ } break;
+ case DK4_FILE_ENCODING_ANSI: {
+
+#line 150 "dk4strmo32.ctr"
+ if (0 != dk4ansi_encode(buf, c32)) {
+ back = dk4stream_write_byte(strm, buf[0], erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_ENCODING_FAILED);
+ }
+ } break;
+ case DK4_FILE_ENCODING_UTF8: {
+
+#line 157 "dk4strmo32.ctr"
+ sz = sizeof(buf);
+ if (0 != dk4utf8_encode(buf, &sz, c32, NULL)) {
+ back = dk4stream_write(strm, (void *)buf, sz, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_ENCODING_FAILED);
+ }
+ } break;
+ case DK4_FILE_ENCODING_UTF16_LE: {
+
+#line 165 "dk4strmo32.ctr"
+ sz = DK4_SIZEOF(b16,dk4_c16_t);
+ if (0 != dk4utf16_encode(b16, &sz, c32, erp)) {
+
+#line 167 "dk4strmo32.ctr"
+ if ((1 == sz) || (2 == sz)) {
+ buf[0] = (unsigned char)( b16[0] & 0x00FF);
+ buf[1] = (unsigned char)((b16[0] >> 8) & 0x00FF);
+ if (2 == sz) {
+
+#line 171 "dk4strmo32.ctr"
+ buf[2] = (unsigned char)( b16[1] & 0x00FF);
+ buf[3] = (unsigned char)((b16[1] >> 8) & 0x00FF);
+
+
+#line 174 "dk4strmo32.ctr"
+ back = dk4stream_write(strm, (void *)buf, 4, erp);
+ } else {
+
+#line 176 "dk4strmo32.ctr"
+
+
+#line 177 "dk4strmo32.ctr"
+ back = dk4stream_write(strm, (void *)buf, 2, erp);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_ENCODING_FAILED);
+ }
+ } else {
+
+#line 183 "dk4strmo32.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_ENCODING_FAILED);
+ }
+ } break;
+ case DK4_FILE_ENCODING_UTF16_BE: {
+
+#line 187 "dk4strmo32.ctr"
+ sz = DK4_SIZEOF(b16,dk4_c16_t);
+ if (0 != dk4utf16_encode(b16, &sz, c32, erp)) {
+
+#line 189 "dk4strmo32.ctr"
+ if ((1 == sz) || (2 == sz)) {
+ buf[1] = (unsigned char)( b16[0] & 0x00FF);
+ buf[0] = (unsigned char)((b16[0] >> 8) & 0x00FF);
+ if (2 == sz) {
+
+#line 193 "dk4strmo32.ctr"
+ buf[3] = (unsigned char)( b16[1] & 0x00FF);
+ buf[2] = (unsigned char)((b16[1] >> 8) & 0x00FF);
+ back = dk4stream_write(strm, (void *)buf, 4, erp);
+ } else {
+
+#line 197 "dk4strmo32.ctr"
+ back = dk4stream_write(strm, (void *)buf, 2, erp);
+ }
+ } else {
+
+#line 200 "dk4strmo32.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_ENCODING_FAILED);
+ }
+ } else {
+
+#line 203 "dk4strmo32.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_ENCODING_FAILED);
+ }
+ } break;
+ case DK4_FILE_ENCODING_32_LE: {
+
+#line 207 "dk4strmo32.ctr"
+ buf[0] = (unsigned char)( c32 & dkC32(0x000000FF));
+ buf[1] = (unsigned char)((c32 >> 8) & dkC32(0x000000FF));
+ buf[2] = (unsigned char)((c32 >> 16) & dkC32(0x000000FF));
+ buf[3] = (unsigned char)((c32 >> 24) & dkC32(0x000000FF));
+ back = dk4stream_write(strm, (void *)buf, 4, erp);
+ } break;
+ case DK4_FILE_ENCODING_32_BE: {
+
+#line 214 "dk4strmo32.ctr"
+ buf[3] = (unsigned char)( c32 & dkC32(0x000000FF));
+ buf[2] = (unsigned char)((c32 >> 8) & dkC32(0x000000FF));
+ buf[1] = (unsigned char)((c32 >> 16) & dkC32(0x000000FF));
+ buf[0] = (unsigned char)((c32 >> 24) & dkC32(0x000000FF));
+ back = dk4stream_write(strm, (void *)buf, 4, erp);
+ } break;
+ default: {
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ } break;
+ }
+ } else{
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 230 "dk4strmo32.ctr"
+ return back;
+}
+
+
+
+int
+dk4stream_c32_puts(dk4_stream_t *strm, const dk4_c32_t *txt, dk4_er_t *erp)
+{
+ int back = 0;
+ if ((NULL != strm) && (NULL != txt)) {
+ if (0 != ((strm->fl) & DK4_STREAM_WRITE)) {
+ back = 1;
+ while ((dkC32(0) != *txt) && (1 == back)) {
+ if (0 == dk4stream_c32_putc(strm, *(txt++), erp)) {
+ back = 0;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4stream_write_bom_if_necessary(dk4_stream_t *strm, dk4_er_t *erp)
+{
+ int back = 0;
+
+
+#line 263 "dk4strmo32.ctr"
+ if (NULL != strm) {
+ if (0 != ((strm->fl) & DK4_STREAM_WRITE)) {
+ switch (strm->oenc) {
+#if VERSION_BEFORE_20141218
+ /* For UTF-8 files most text editors do not handle
+ the BOM correctly, they show a glyph for unrepresentable
+ characters.
+ So I decided to write a BOM only for 16 bit and 32 bit
+ character output.
+ */
+ case DK4_FILE_ENCODING_UTF8:
+#endif
+ case DK4_FILE_ENCODING_UTF16_LE:
+ case DK4_FILE_ENCODING_UTF16_BE:
+ case DK4_FILE_ENCODING_32_LE:
+ case DK4_FILE_ENCODING_32_BE:
+ {
+
+#line 280 "dk4strmo32.ctr"
+ back = dk4stream_c32_putc(strm, dkC32(0x0000FEFF), erp);
+ } break;
+ default: {
+ back = 1;
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 292 "dk4strmo32.ctr"
+ return back;
+}
+
+
diff --git a/support/dktools/dk4strmo32.ctr b/support/dktools/dk4strmo32.ctr
new file mode 100644
index 0000000000..8a1037aaa5
--- /dev/null
+++ b/support/dktools/dk4strmo32.ctr
@@ -0,0 +1,295 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ String output over dk4_stream_t API,
+ 32 bit character strings.
+
+ CRT on Windows: Not used.
+*/
+
+#include "dk4strm.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Set output encoding for 32 bit character output.
+ @param strm Stream to modify.
+ @param oe New output encoding.
+*/
+void
+dk4stream_set_output_encoding(dk4_stream_t *strm, int oe);
+
+/** Write one 32 bit character to stream.
+ @param strm Stream to write to.
+ @param c32 Character to write.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is null or not set up for writing,
+ - DK4_E_ENCODING_FAILED<br>
+ if it is not possible to encode c32 to the output encoding for the
+ stream,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flushing data downwards failed.
+*/
+int
+dk4stream_c32_putc(dk4_stream_t *strm, dk4_c32_t c32, dk4_er_t *erp);
+
+/** Write one 32 bit character string to stream.
+ @param strm Stream to write to.
+ @param txt Text string to write.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is null or not set up for writing,
+ - DK4_E_ENCODING_FAILED<br>
+ if it is not possible to encode c32 to the output encoding for the
+ stream,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flushing data downwards failed.
+*/
+int
+dk4stream_c32_puts(dk4_stream_t *strm, const dk4_c32_t *txt, dk4_er_t *erp);
+
+/** Write byte order marker for those output encodings
+ supporting a BOM.
+ @param strm Stream to write the BOM to.
+ @param erp Error report, may be NULL.
+ @return 1 on success (BOM written or not required), 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is null or not set up for writing,
+ - DK4_E_ENCODING_FAILED<br>
+ if it is not possible to encode c32 to the output encoding for the
+ stream,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flushing data downwards failed.
+*/
+int
+dk4stream_write_bom_if_necessary(dk4_stream_t *strm, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4strmo32.h"
+#include "dk4mem.h"
+#include "dk4ansi.h"
+#include "dk4utf8.h"
+#include "dk4utf16.h"
+#include "dk4enc.h"
+
+
+
+$!trace-include
+
+
+
+void
+dk4stream_set_output_encoding(dk4_stream_t *strm, int oe)
+{
+ $? "+ dk4stream_set_output_encoding %d", oe
+ if (NULL != strm) {
+ switch (oe) {
+ case DK4_FILE_ENCODING_ASCII:
+ case DK4_FILE_ENCODING_ANSI:
+ case DK4_FILE_ENCODING_UTF8:
+ case DK4_FILE_ENCODING_UTF16_LE:
+ case DK4_FILE_ENCODING_UTF16_BE:
+ case DK4_FILE_ENCODING_32_LE:
+ case DK4_FILE_ENCODING_32_BE:
+ {
+ strm->oenc = oe;
+ } break;
+ }
+ } $? "- dk4stream_set_output_encoding"
+}
+
+
+
+int
+dk4stream_c32_putc(dk4_stream_t *strm, dk4_c32_t c32, dk4_er_t *erp)
+{
+ unsigned char buf[16];
+ dk4_c16_t b16[4];
+ size_t sz;
+ int back = 0;
+ $? "+ dk4stream_c32_putc %lx", (unsigned long)c32
+ if (NULL != strm) { $? ". stream ok"
+ if (0 != ((strm->fl) & DK4_STREAM_WRITE)) { $? ". wr flag ok"
+ switch (strm->oenc) {
+ case DK4_FILE_ENCODING_ASCII: { $? ". ASCII"
+ if (dkC32(0x00000100) > c32) {
+ back = dk4stream_write_byte(strm, (unsigned char)c32, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_ENCODING_FAILED);
+ }
+ } break;
+ case DK4_FILE_ENCODING_ANSI: { $? ". ANSI"
+ if (0 != dk4ansi_encode(buf, c32)) {
+ back = dk4stream_write_byte(strm, buf[0], erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_ENCODING_FAILED);
+ }
+ } break;
+ case DK4_FILE_ENCODING_UTF8: { $? ". UTF-8"
+ sz = sizeof(buf);
+ if (0 != dk4utf8_encode(buf, &sz, c32, NULL)) {
+ back = dk4stream_write(strm, (void *)buf, sz, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_ENCODING_FAILED);
+ }
+ } break;
+ case DK4_FILE_ENCODING_UTF16_LE: { $? ". UTF-16.LSB"
+ sz = DK4_SIZEOF(b16,dk4_c16_t);
+ if (0 != dk4utf16_encode(b16, &sz, c32, erp)) { $? ". enc"
+ if ((1 == sz) || (2 == sz)) {
+ buf[0] = (unsigned char)( b16[0] & 0x00FF);
+ buf[1] = (unsigned char)((b16[0] >> 8) & 0x00FF);
+ if (2 == sz) { $? ". 2 words"
+ buf[2] = (unsigned char)( b16[1] & 0x00FF);
+ buf[3] = (unsigned char)((b16[1] >> 8) & 0x00FF);
+ $? ". write 4 bytes to stream"
+ back = dk4stream_write(strm, (void *)buf, 4, erp);
+ } else { $? ". 1 word"
+ $? ". write 2 bytes to stream"
+ back = dk4stream_write(strm, (void *)buf, 2, erp);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_ENCODING_FAILED);
+ }
+ } else { $? "! enc"
+ dk4error_set_simple_error_code(erp, DK4_E_ENCODING_FAILED);
+ }
+ } break;
+ case DK4_FILE_ENCODING_UTF16_BE: { $? ". UTF-16.MSB"
+ sz = DK4_SIZEOF(b16,dk4_c16_t);
+ if (0 != dk4utf16_encode(b16, &sz, c32, erp)) { $? ". enc"
+ if ((1 == sz) || (2 == sz)) {
+ buf[1] = (unsigned char)( b16[0] & 0x00FF);
+ buf[0] = (unsigned char)((b16[0] >> 8) & 0x00FF);
+ if (2 == sz) { $? ". 2 bytes"
+ buf[3] = (unsigned char)( b16[1] & 0x00FF);
+ buf[2] = (unsigned char)((b16[1] >> 8) & 0x00FF);
+ back = dk4stream_write(strm, (void *)buf, 4, erp);
+ } else { $? ". 1 byte"
+ back = dk4stream_write(strm, (void *)buf, 2, erp);
+ }
+ } else { $? "! enc"
+ dk4error_set_simple_error_code(erp, DK4_E_ENCODING_FAILED);
+ }
+ } else { $? "! enc"
+ dk4error_set_simple_error_code(erp, DK4_E_ENCODING_FAILED);
+ }
+ } break;
+ case DK4_FILE_ENCODING_32_LE: { $? ". C32.LSB"
+ buf[0] = (unsigned char)( c32 & dkC32(0x000000FF));
+ buf[1] = (unsigned char)((c32 >> 8) & dkC32(0x000000FF));
+ buf[2] = (unsigned char)((c32 >> 16) & dkC32(0x000000FF));
+ buf[3] = (unsigned char)((c32 >> 24) & dkC32(0x000000FF));
+ back = dk4stream_write(strm, (void *)buf, 4, erp);
+ } break;
+ case DK4_FILE_ENCODING_32_BE: { $? ". C32.MSB"
+ buf[3] = (unsigned char)( c32 & dkC32(0x000000FF));
+ buf[2] = (unsigned char)((c32 >> 8) & dkC32(0x000000FF));
+ buf[1] = (unsigned char)((c32 >> 16) & dkC32(0x000000FF));
+ buf[0] = (unsigned char)((c32 >> 24) & dkC32(0x000000FF));
+ back = dk4stream_write(strm, (void *)buf, 4, erp);
+ } break;
+ default: {
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ } break;
+ }
+ } else{
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4stream_c32_putc %d", back
+ return back;
+}
+
+
+
+int
+dk4stream_c32_puts(dk4_stream_t *strm, const dk4_c32_t *txt, dk4_er_t *erp)
+{
+ int back = 0;
+ if ((NULL != strm) && (NULL != txt)) {
+ if (0 != ((strm->fl) & DK4_STREAM_WRITE)) {
+ back = 1;
+ while ((dkC32(0) != *txt) && (1 == back)) {
+ if (0 == dk4stream_c32_putc(strm, *(txt++), erp)) {
+ back = 0;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4stream_write_bom_if_necessary(dk4_stream_t *strm, dk4_er_t *erp)
+{
+ int back = 0;
+ $? "+ dk4stream_write_bom_if_necessary"
+ if (NULL != strm) {
+ if (0 != ((strm->fl) & DK4_STREAM_WRITE)) {
+ switch (strm->oenc) {
+#if VERSION_BEFORE_20141218
+ /* For UTF-8 files most text editors do not handle
+ the BOM correctly, they show a glyph for unrepresentable
+ characters.
+ So I decided to write a BOM only for 16 bit and 32 bit
+ character output.
+ */
+ case DK4_FILE_ENCODING_UTF8:
+#endif
+ case DK4_FILE_ENCODING_UTF16_LE:
+ case DK4_FILE_ENCODING_UTF16_BE:
+ case DK4_FILE_ENCODING_32_LE:
+ case DK4_FILE_ENCODING_32_BE:
+ { $? ". attempt to write bom"
+ back = dk4stream_c32_putc(strm, dkC32(0x0000FEFF), erp);
+ } break;
+ default: {
+ back = 1;
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4stream_write_bom_if_necessary %d", back
+ return back;
+}
+
+
diff --git a/support/dktools/dk4strmo32.h b/support/dktools/dk4strmo32.h
new file mode 100644
index 0000000000..efdcdb9fd8
--- /dev/null
+++ b/support/dktools/dk4strmo32.h
@@ -0,0 +1,128 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4strmo32.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4STRMO32_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4STRMO32_H_INCLUDED 1
+
+
+#line 9 "dk4strmo32.ctr"
+
+/** @file
+ String output over dk4_stream_t API,
+ 32 bit character strings.
+
+ CRT on Windows: Not used.
+*/
+
+#include "dk4strm.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Set output encoding for 32 bit character output.
+ @param strm Stream to modify.
+ @param oe New output encoding.
+*/
+void
+dk4stream_set_output_encoding(dk4_stream_t *strm, int oe);
+
+/** Write one 32 bit character to stream.
+ @param strm Stream to write to.
+ @param c32 Character to write.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is null or not set up for writing,
+ - DK4_E_ENCODING_FAILED<br>
+ if it is not possible to encode c32 to the output encoding for the
+ stream,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flushing data downwards failed.
+*/
+int
+dk4stream_c32_putc(dk4_stream_t *strm, dk4_c32_t c32, dk4_er_t *erp);
+
+/** Write one 32 bit character string to stream.
+ @param strm Stream to write to.
+ @param txt Text string to write.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is null or not set up for writing,
+ - DK4_E_ENCODING_FAILED<br>
+ if it is not possible to encode c32 to the output encoding for the
+ stream,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flushing data downwards failed.
+*/
+int
+dk4stream_c32_puts(dk4_stream_t *strm, const dk4_c32_t *txt, dk4_er_t *erp);
+
+/** Write byte order marker for those output encodings
+ supporting a BOM.
+ @param strm Stream to write the BOM to.
+ @param erp Error report, may be NULL.
+ @return 1 on success (BOM written or not required), 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is null or not set up for writing,
+ - DK4_E_ENCODING_FAILED<br>
+ if it is not possible to encode c32 to the output encoding for the
+ stream,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flushing data downwards failed.
+*/
+int
+dk4stream_write_bom_if_necessary(dk4_stream_t *strm, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4strmodk.c b/support/dktools/dk4strmodk.c
new file mode 100644
index 0000000000..ec591fe457
--- /dev/null
+++ b/support/dktools/dk4strmodk.c
@@ -0,0 +1,62 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4strmodk.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4strmodk.c The dk4strmodk module.
+*/
+
+
+#line 53 "dk4strmodk.ctr"
+
+#include "dk4strmodk.h"
+#include "dk4strmo32.h"
+#include "dk4strmo16.h"
+#include "dk4strmo08.h"
+
+int
+dk4stream_dk_puts(dk4_stream_t *strm, const dkChar *txt, int ie, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ return (dk4stream_c32_puts(strm, txt, erp));
+#else
+ return (dk4stream_c16_puts(strm, txt, erp));
+#endif
+#else
+ return (dk4stream_c08_puts(strm, txt, ie, erp));
+#endif
+}
+
+
+
diff --git a/support/dktools/dk4strmodk.ctr b/support/dktools/dk4strmodk.ctr
new file mode 100644
index 0000000000..3ac8e5a8e4
--- /dev/null
+++ b/support/dktools/dk4strmodk.ctr
@@ -0,0 +1,74 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ String output over dk4_stream_t API,
+ dkChar strings.
+
+ CRT on Windows: Not used.
+*/
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4strm.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Write one 32 bit character string to stream.
+ @param strm Stream to write to.
+ @param txt Text string to write.
+ @param ie Input encoding used for txt.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is null or not set up for writing,
+ - DK4_E_ENCODING_FAILED<br>
+ if it is not possible to encode c32 to the output encoding for the
+ stream,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flushing data downwards failed.
+*/
+int
+dk4stream_dk_puts(dk4_stream_t *strm, const dkChar *txt, int ie, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4strmodk.h"
+#include "dk4strmo32.h"
+#include "dk4strmo16.h"
+#include "dk4strmo08.h"
+
+int
+dk4stream_dk_puts(dk4_stream_t *strm, const dkChar *txt, int ie, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ return (dk4stream_c32_puts(strm, txt, erp));
+#else
+ return (dk4stream_c16_puts(strm, txt, erp));
+#endif
+#else
+ return (dk4stream_c08_puts(strm, txt, ie, erp));
+#endif
+}
+
+
+
diff --git a/support/dktools/dk4strmodk.h b/support/dktools/dk4strmodk.h
new file mode 100644
index 0000000000..e1b526f5e0
--- /dev/null
+++ b/support/dktools/dk4strmodk.h
@@ -0,0 +1,85 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4strmodk.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4STRMODK_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4STRMODK_H_INCLUDED 1
+
+
+#line 10 "dk4strmodk.ctr"
+
+/** @file
+ String output over dk4_stream_t API,
+ dkChar strings.
+
+ CRT on Windows: Not used.
+*/
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4strm.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Write one 32 bit character string to stream.
+ @param strm Stream to write to.
+ @param txt Text string to write.
+ @param ie Input encoding used for txt.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is null or not set up for writing,
+ - DK4_E_ENCODING_FAILED<br>
+ if it is not possible to encode c32 to the output encoding for the
+ stream,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flushing data downwards failed.
+*/
+int
+dk4stream_dk_puts(dk4_stream_t *strm, const dkChar *txt, int ie, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4strmr.c b/support/dktools/dk4strmr.c
new file mode 100644
index 0000000000..482885711b
--- /dev/null
+++ b/support/dktools/dk4strmr.c
@@ -0,0 +1,309 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4strmr.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4strmr.c The dk4strmr module.
+*/
+
+
+#line 69 "dk4strmr.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS && DK4_WIN_DENY_CRT
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#ifndef DK4STRMH_H_INCLUDED
+#include "dk4strmh.h"
+#endif
+#endif
+
+#include "dk4strmr.h"
+
+#ifndef DK4FD_H_INCLUDED
+#include "dk4fd.h"
+#endif
+
+#ifndef DK4PATH_H_INCLUDED
+#include "dk4pathd.h"
+#endif
+
+#ifndef DK4STRD_H_INCLUDED
+#include "dk4strd.h"
+#endif
+
+#ifndef DK4FOPD_H_INCLUDED
+#include "dk4fopd.h"
+#endif
+
+
+
+
+
+#line 103 "dk4strmr.ctr"
+
+
+
+/** Compression suffixes.
+*/
+static const dkChar * const dk4strmr_co_su[] = {
+/* 0 */
+dkT(".gz"),
+
+/* 1 */
+dkT(".bz2"),
+
+/* 2 */
+dkT(".svgz"),
+
+NULL
+
+
+#line 114 "dk4strmr.ctr"
+};
+
+
+
+/** File mode for binary reading.
+*/
+static const char dk4strmr_c8_mode[] = { "rb" };
+
+/** File mode for binary reading.
+*/
+static const dkChar dk4strmr_dk_mode[] = { dkT("rb") };
+
+
+dk4_stream_t *
+dk4stream_open_file_reader(const dkChar *filename, dk4_er_t *erp)
+{
+ dk4_stream_t *back = NULL; /* Function result */
+ const dkChar *p1 = NULL; /* Suffix pointer */
+#if DK4_HAVE_ZLIB_H && (!(DK4_ON_WINDOWS && DK4_WIN_DENY_CRT))
+ gzFile gzf = NULL; /* gzip compressed input file */
+#endif
+#if DK4_HAVE_BZLIB_H && (!(DK4_ON_WINDOWS && DK4_WIN_DENY_CRT))
+ BZFILE *bzf = NULL; /* bzip2 compressed input file */
+#endif
+ FILE *fipo = NULL; /* Input file */
+#if DK4_ON_WINDOWS && DK4_WIN_DENY_CRT
+ HANDLE fha = INVALID_HANDLE_VALUE;
+ DWORD dwattr = (DWORD)0UL;
+#endif
+ int coi = -1; /* Compression algorithm index */
+#if DK4_CHAR_SIZE > 1
+ int fd = -1; /* File descriptor */
+#endif
+
+
+#line 148 "dk4strmr.ctr"
+ if (NULL != filename) {
+ p1 = dk4path_get_suffix(filename, erp);
+ if (NULL != p1) {
+
+#line 151 "dk4strmr.ctr"
+ coi = dk4str_array_index(
+ dk4strmr_co_su, p1, DK4_HAVE_CASE_INSENSITIVE_PATHNAMES
+ );
+ if (0 > coi) coi = -1;
+
+#line 155 "dk4strmr.ctr"
+ }
+ if (0 != dk4fopen_check(filename, 0, DK4_FOPEN_SC_IS_REGULAR, erp)) {
+
+
+#line 158 "dk4strmr.ctr"
+ switch (coi) {
+ case 1: {
+#if DK4_HAVE_BZLIB_H && (!(DK4_ON_WINDOWS && DK4_WIN_DENY_CRT))
+#if DK4_CHAR_SIZE > 1
+ /* +++++ bzip2, wchar_t */
+
+
+#line 164 "dk4strmr.ctr"
+ fd = dk4fd_wc_open(filename, (DK4_O_RDONLY | DK4_O_BINARY), erp);
+ if (-1 < fd) {
+ bzf = BZ2_bzdopen(fd, dk4strmr_c8_mode);
+ if (NULL != bzf) {
+ back = dk4stream_open_for_bzfile_with_close(
+ bzf, DK4_STREAM_READ, 4096, 1024, erp
+ );
+ if (NULL == back) {
+ BZ2_bzclose(bzf);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_OPEN_READ_FAILED);
+ (void)dk4fd_close(fd, NULL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_OPEN_READ_FAILED);
+ }
+ /* ----- bzip2, wchar_t */
+#else
+ /* +++++ bzip2, char */
+
+
+#line 185 "dk4strmr.ctr"
+ bzf = BZ2_bzopen(filename, dk4strmr_c8_mode);
+ if (NULL != bzf) {
+ back = dk4stream_open_for_bzfile_with_close(
+ bzf, DK4_STREAM_READ, 4096, 1024, erp
+ );
+ if (NULL == back) {
+ BZ2_bzclose(bzf);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_OPEN_READ_FAILED);
+ }
+ /* ----- bzip2, char */
+#endif
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case 0: case 2: {
+
+#line 203 "dk4strmr.ctr"
+#if DK4_HAVE_ZLIB_H && (!(DK4_ON_WINDOWS && DK4_WIN_DENY_CRT))
+#if DK4_CHAR_SIZE > 1
+
+
+#line 206 "dk4strmr.ctr"
+ /* +++++ gzip, wchar_t */
+ fd = dk4fd_wc_open(filename, (DK4_O_RDONLY | DK4_O_BINARY), erp);
+ if (-1 < fd) {
+ gzf = gzdopen(fd, dk4strmr_c8_mode);
+ if (NULL != gzf) {
+ back = dk4stream_open_for_gzfile_with_close(
+ gzf, DK4_STREAM_READ, 4096, 1024, erp
+ );
+ if (NULL == back) {
+ gzclose(gzf);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_OPEN_READ_FAILED);
+ (void)dk4fd_close(fd, NULL);
+ }
+ }
+ /* ----- gzip, wchar_t */
+#else
+
+
+#line 225 "dk4strmr.ctr"
+ /* +++++ gzip, char */
+ gzf = gzopen(filename, dk4strmr_c8_mode);
+ if (NULL != gzf) {
+ back = dk4stream_open_for_gzfile_with_close(
+ gzf, DK4_STREAM_READ, 4096, 1024, erp
+ );
+ if (NULL == back) {
+ gzclose(gzf);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_OPEN_READ_FAILED);
+ }
+ /* ----- gzip, char */
+#endif
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ default: {
+
+#line 244 "dk4strmr.ctr"
+#if DK4_ON_WINDOWS && DK4_WIN_DENY_CRT
+ dwattr = FILE_ATTRIBUTE_NORMAL;
+ dwattr |= FILE_FLAG_BACKUP_SEMANTICS;
+ dwattr |= FILE_FLAG_SEQUENTIAL_SCAN;
+#if DK4_CHAR_SIZE > 1
+ fha = CreateFileW(
+ filename, GENERIC_READ, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, dwattr, NULL
+ );
+#else
+ fha = CreateFileA(
+ filename, GENERIC_READ, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, dwattr, NULL
+ );
+#endif
+ if (INVALID_HANDLE_VALUE != fha) {
+ back = dk4stream_open_for_windows_handle_with_close(
+ fha, DK4_STREAM_READ, 4096, 1024, erp
+ );
+ if (NULL == back) {
+ (void)CloseHandle(fha);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_OPEN_READ_FAILED);
+ }
+#else
+ fipo = dk4fopen(
+ filename, dk4strmr_dk_mode, DK4_FOPEN_SC_IS_REGULAR, erp
+ );
+ if (NULL != fipo) {
+
+#line 274 "dk4strmr.ctr"
+ back = dk4stream_open_for_file_with_close(
+ fipo, DK4_STREAM_READ, 4096, 1024, erp
+ );
+ if (NULL == back) {
+
+#line 278 "dk4strmr.ctr"
+ (void)fclose(fipo);
+ }
+ } else {
+
+#line 281 "dk4strmr.ctr"
+ }
+#endif
+
+
+#line 284 "dk4strmr.ctr"
+ } break;
+ }
+ } else {
+
+#line 287 "dk4strmr.ctr"
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 291 "dk4strmr.ctr"
+ return back;
+}
+
+
+
diff --git a/support/dktools/dk4strmr.ctr b/support/dktools/dk4strmr.ctr
new file mode 100644
index 0000000000..2cdba61daf
--- /dev/null
+++ b/support/dktools/dk4strmr.ctr
@@ -0,0 +1,295 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ Open stream to read a file.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4STRM_H_INCLUDED
+#include "dk4strm.h"
+#endif
+
+#ifndef DK4STRMF_H_INCLUDED
+#include "dk4strmf.h"
+#endif
+
+#ifndef DK4STRMG_H_INCLUDED
+#include "dk4strmg.h"
+#endif
+
+#ifndef DK4STRMB_H_INCLUDED
+#include "dk4strmb.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open a stream to read a file.
+ CRT on Windows: Optional, disabling CRT reduces functionality
+ by disabling the gzip and bzip2 compression libraries.
+ @param filename File name of file to read.
+ @param erp Error report, may be NULL.
+ @return Pointer to stream on success, NULL on error.
+ DK4_E_INVALID_ARGUMENTS if filename is NULL,
+ DK4_E_MATH_OVERFLOW if ibs or obs is too large,
+ DK4_E_MEMORY_ALLOCATION_FAILED if allocation of input or output buffer
+ failed.
+*/
+
+dk4_stream_t *
+dk4stream_open_file_reader(const dkChar *filename, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS && DK4_WIN_DENY_CRT
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#ifndef DK4STRMH_H_INCLUDED
+#include "dk4strmh.h"
+#endif
+#endif
+
+#include "dk4strmr.h"
+
+#ifndef DK4FD_H_INCLUDED
+#include "dk4fd.h"
+#endif
+
+#ifndef DK4PATH_H_INCLUDED
+#include "dk4pathd.h"
+#endif
+
+#ifndef DK4STRD_H_INCLUDED
+#include "dk4strd.h"
+#endif
+
+#ifndef DK4FOPD_H_INCLUDED
+#include "dk4fopd.h"
+#endif
+
+
+
+$!trace-include
+
+
+
+/** Compression suffixes.
+*/
+static const dkChar * const dk4strmr_co_su[] = {
+$!string-table macro=dkT
+.gz
+.bz2
+.svgz
+$!end
+};
+
+
+
+/** File mode for binary reading.
+*/
+static const char dk4strmr_c8_mode[] = { "rb" };
+
+/** File mode for binary reading.
+*/
+static const dkChar dk4strmr_dk_mode[] = { dkT("rb") };
+
+
+dk4_stream_t *
+dk4stream_open_file_reader(const dkChar *filename, dk4_er_t *erp)
+{
+ dk4_stream_t *back = NULL; /* Function result */
+ const dkChar *p1 = NULL; /* Suffix pointer */
+#if DK4_HAVE_ZLIB_H && (!(DK4_ON_WINDOWS && DK4_WIN_DENY_CRT))
+ gzFile gzf = NULL; /* gzip compressed input file */
+#endif
+#if DK4_HAVE_BZLIB_H && (!(DK4_ON_WINDOWS && DK4_WIN_DENY_CRT))
+ BZFILE *bzf = NULL; /* bzip2 compressed input file */
+#endif
+ FILE *fipo = NULL; /* Input file */
+#if DK4_ON_WINDOWS && DK4_WIN_DENY_CRT
+ HANDLE fha = INVALID_HANDLE_VALUE;
+ DWORD dwattr = (DWORD)0UL;
+#endif
+ int coi = -1; /* Compression algorithm index */
+#if DK4_CHAR_SIZE > 1
+ int fd = -1; /* File descriptor */
+#endif
+ $? "+ dk4stream_open_file_reader \"%!ds\"", filename
+ if (NULL != filename) {
+ p1 = dk4path_get_suffix(filename, erp);
+ if (NULL != p1) { $? ". file name suffix \"%!ds\"", p1
+ coi = dk4str_array_index(
+ dk4strmr_co_su, p1, DK4_HAVE_CASE_INSENSITIVE_PATHNAMES
+ );
+ if (0 > coi) coi = -1; $? ". coi = %d", coi
+ }
+ if (0 != dk4fopen_check(filename, 0, DK4_FOPEN_SC_IS_REGULAR, erp)) {
+ $? ". fopen check ok"
+ switch (coi) {
+ case 1: {
+#if DK4_HAVE_BZLIB_H && (!(DK4_ON_WINDOWS && DK4_WIN_DENY_CRT))
+#if DK4_CHAR_SIZE > 1
+ /* +++++ bzip2, wchar_t */
+ $? ". bzip2 for wchar_t"
+ fd = dk4fd_wc_open(filename, (DK4_O_RDONLY | DK4_O_BINARY), erp);
+ if (-1 < fd) {
+ bzf = BZ2_bzdopen(fd, dk4strmr_c8_mode);
+ if (NULL != bzf) {
+ back = dk4stream_open_for_bzfile_with_close(
+ bzf, DK4_STREAM_READ, 4096, 1024, erp
+ );
+ if (NULL == back) {
+ BZ2_bzclose(bzf);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_OPEN_READ_FAILED);
+ (void)dk4fd_close(fd, NULL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_OPEN_READ_FAILED);
+ }
+ /* ----- bzip2, wchar_t */
+#else
+ /* +++++ bzip2, char */
+ $? ". bzip2 for char"
+ bzf = BZ2_bzopen(filename, dk4strmr_c8_mode);
+ if (NULL != bzf) {
+ back = dk4stream_open_for_bzfile_with_close(
+ bzf, DK4_STREAM_READ, 4096, 1024, erp
+ );
+ if (NULL == back) {
+ BZ2_bzclose(bzf);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_OPEN_READ_FAILED);
+ }
+ /* ----- bzip2, char */
+#endif
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case 0: case 2: { $? ". gzip"
+#if DK4_HAVE_ZLIB_H && (!(DK4_ON_WINDOWS && DK4_WIN_DENY_CRT))
+#if DK4_CHAR_SIZE > 1
+ $? ". gzip for wide characters"
+ /* +++++ gzip, wchar_t */
+ fd = dk4fd_wc_open(filename, (DK4_O_RDONLY | DK4_O_BINARY), erp);
+ if (-1 < fd) {
+ gzf = gzdopen(fd, dk4strmr_c8_mode);
+ if (NULL != gzf) {
+ back = dk4stream_open_for_gzfile_with_close(
+ gzf, DK4_STREAM_READ, 4096, 1024, erp
+ );
+ if (NULL == back) {
+ gzclose(gzf);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_OPEN_READ_FAILED);
+ (void)dk4fd_close(fd, NULL);
+ }
+ }
+ /* ----- gzip, wchar_t */
+#else
+ $? ". gzip for char"
+ /* +++++ gzip, char */
+ gzf = gzopen(filename, dk4strmr_c8_mode);
+ if (NULL != gzf) {
+ back = dk4stream_open_for_gzfile_with_close(
+ gzf, DK4_STREAM_READ, 4096, 1024, erp
+ );
+ if (NULL == back) {
+ gzclose(gzf);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_OPEN_READ_FAILED);
+ }
+ /* ----- gzip, char */
+#endif
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ default: { $? ". simple file"
+#if DK4_ON_WINDOWS && DK4_WIN_DENY_CRT
+ dwattr = FILE_ATTRIBUTE_NORMAL;
+ dwattr |= FILE_FLAG_BACKUP_SEMANTICS;
+ dwattr |= FILE_FLAG_SEQUENTIAL_SCAN;
+#if DK4_CHAR_SIZE > 1
+ fha = CreateFileW(
+ filename, GENERIC_READ, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, dwattr, NULL
+ );
+#else
+ fha = CreateFileA(
+ filename, GENERIC_READ, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, dwattr, NULL
+ );
+#endif
+ if (INVALID_HANDLE_VALUE != fha) {
+ back = dk4stream_open_for_windows_handle_with_close(
+ fha, DK4_STREAM_READ, 4096, 1024, erp
+ );
+ if (NULL == back) {
+ (void)CloseHandle(fha);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_OPEN_READ_FAILED);
+ }
+#else
+ fipo = dk4fopen(
+ filename, dk4strmr_dk_mode, DK4_FOPEN_SC_IS_REGULAR, erp
+ );
+ if (NULL != fipo) { $? ". fopen ok"
+ back = dk4stream_open_for_file_with_close(
+ fipo, DK4_STREAM_READ, 4096, 1024, erp
+ );
+ if (NULL == back) { $? "! stream open failed"
+ (void)fclose(fipo);
+ }
+ } else { $? "! fipo"
+ }
+#endif
+ $? ". simple file ended"
+ } break;
+ }
+ } else { $? "! file check failed"
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4stream_open_file_reader PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
diff --git a/support/dktools/dk4strmr.h b/support/dktools/dk4strmr.h
new file mode 100644
index 0000000000..eb6e30dee5
--- /dev/null
+++ b/support/dktools/dk4strmr.h
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4strmr.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4STRMR_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4STRMR_H_INCLUDED 1
+
+
+#line 9 "dk4strmr.ctr"
+
+/** @file
+ Open stream to read a file.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4STRM_H_INCLUDED
+#include "dk4strm.h"
+#endif
+
+#ifndef DK4STRMF_H_INCLUDED
+#include "dk4strmf.h"
+#endif
+
+#ifndef DK4STRMG_H_INCLUDED
+#include "dk4strmg.h"
+#endif
+
+#ifndef DK4STRMB_H_INCLUDED
+#include "dk4strmb.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open a stream to read a file.
+ CRT on Windows: Optional, disabling CRT reduces functionality
+ by disabling the gzip and bzip2 compression libraries.
+ @param filename File name of file to read.
+ @param erp Error report, may be NULL.
+ @return Pointer to stream on success, NULL on error.
+ DK4_E_INVALID_ARGUMENTS if filename is NULL,
+ DK4_E_MATH_OVERFLOW if ibs or obs is too large,
+ DK4_E_MEMORY_ALLOCATION_FAILED if allocation of input or output buffer
+ failed.
+*/
+
+dk4_stream_t *
+dk4stream_open_file_reader(const dkChar *filename, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4strms.c b/support/dktools/dk4strms.c
new file mode 100644
index 0000000000..a96e3a350c
--- /dev/null
+++ b/support/dktools/dk4strms.c
@@ -0,0 +1,218 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4strms.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4strms.c The dk4strms module.
+*/
+
+
+#line 226 "dk4strms.ctr"
+
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_MATH_H
+#ifndef MATH_H_INCLUDED
+#include <math.h>
+#define MATH_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4strms.h"
+#include "dk4mao8dbl.h"
+
+
+int
+dk4stream_serialize_u32(dk4_stream_t *strm, uint32_t u32, dk4_er_t *erp)
+{
+ unsigned char buf[8];
+ int back = 0;
+
+ if (NULL != strm) {
+ buf[0] = (unsigned char)( u32 & 0x000000FFUL);
+ buf[1] = (unsigned char)((u32 >> 8) & 0x000000FFUL);
+ buf[2] = (unsigned char)((u32 >> 16) & 0x000000FFUL);
+ buf[3] = (unsigned char)((u32 >> 24) & 0x000000FFUL);
+ back = dk4stream_write(strm, buf, 4, erp);
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4stream_serialize_i32(dk4_stream_t *strm, int32_t i32, dk4_er_t *erp)
+{
+ return ( dk4stream_serialize_u32(strm, (uint32_t)i32, erp) );
+}
+
+
+
+int
+dk4stream_serialize_u16(dk4_stream_t *strm, uint16_t u16, dk4_er_t *erp)
+{
+ unsigned char buf[8];
+ int back = 0;
+
+ if (NULL != strm) {
+ buf[0] = (unsigned char)( u16 & 0x00FFU);
+ buf[1] = (unsigned char)((u16 >> 8) & 0x00FFU);
+ back = dk4stream_write(strm, buf, 2, erp);
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4stream_serialize_i16(dk4_stream_t *strm, int16_t i16, dk4_er_t *erp)
+{
+ return ( dk4stream_serialize_u16(strm, (uint16_t)i16, erp) );
+}
+
+
+
+int
+dk4stream_serialize_u8(dk4_stream_t *strm, uint8_t u8, dk4_er_t *erp)
+{
+ unsigned char uc;
+ int back = 0;
+
+ if (NULL != strm) {
+ uc = (unsigned char)u8;
+ back = dk4stream_write(strm, &uc, 1, erp);
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4stream_serialize_i8(dk4_stream_t *strm, int8_t i8, dk4_er_t *erp)
+{
+ return ( dk4stream_serialize_u8(strm, (uint8_t)i8, erp) );
+}
+
+
+
+int
+dk4stream_serialize_string(dk4_stream_t *strm, const char *str, dk4_er_t *erp)
+{
+ size_t sl = 0;
+ int back = 0;
+
+ if ((NULL != strm) && (NULL != str)) {
+ sl = strlen(str);
+ if (((size_t)0xFFFFU) > sl) {
+ sl++;
+ if (0 < dk4stream_serialize_u16(strm, (uint16_t)sl, erp)) {
+ back = dk4stream_write(strm, str, sl, erp);
+ }
+ else {
+ /* ERROR: Failed to serialize string length already reported */
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4stream_serialize_double(dk4_stream_t *strm,double d,double e,dk4_er_t *erp)
+{
+ char buf[16*sizeof(double)];
+ size_t szbuf = sizeof(buf);
+ int back = 0;
+ if (NULL != strm) {
+ if (fabs(d) < e) {
+ back = dk4stream_serialize_u16(strm, (uint16_t)0U, erp);
+ }
+ else {
+ if (0 < dk4ma_write_c8_double(buf, szbuf, d, 1, 1, erp)) {
+ back = dk4stream_serialize_string(strm, buf, erp);
+ }
+ else {
+ /* ##### ERROR: Failed to write double to string */
+ }
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4stream_serialize_double_0(dk4_stream_t *strm, dk4_er_t *erp)
+{
+ int back = 0;
+
+ if (NULL != strm) {
+ back = dk4stream_serialize_u16(strm, 0U, erp);
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+/* vim: set ai sw=4 ts=4 : */
+
diff --git a/support/dktools/dk4strms.ctr b/support/dktools/dk4strms.ctr
new file mode 100644
index 0000000000..a6b292ec32
--- /dev/null
+++ b/support/dktools/dk4strms.ctr
@@ -0,0 +1,403 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+%% header
+
+/** @file dk4strms.h Serialize data to a stream.
+
+The functions to serialize integers write the least significant byte
+first.
+
+When serializing a string, the string length is serialized first as
+16 bit unsigned number, string contents follows.
+The finalizing 0x00 byte is both counted in the string length and written
+to the stream.
+So a reader application can retrieve the length first, allocate a memory
+block of exact size and read the string. Reader applications should
+check/ensure the finalizing byte after reading string contents.
+
+When serializing a double, the double is converted to a string and the
+string is serialized to the stream. For 0.0 and values nearby
+(absolute value is below a given limit) a string length 0 is serialized
+to the stream instead, no string is written.
+
+*/
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4STRM_H_INCLUDED
+#include <dk4strm.h>
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+/** Serialize unsigned 32 bit integer to stream.
+ @param strm Destination stream.
+ @param u32 Value to serialize.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is NULL or not opened for writing,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flusing data downwards failed.
+*/
+
+int
+dk4stream_serialize_u32(dk4_stream_t *strm, uint32_t u32, dk4_er_t *erp);
+
+
+/** Serialize signed 32 bit integer to stream.
+ @param strm Destination stream.
+ @param i32 Value to serialize.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is NULL or not opened for writing,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flusing data downwards failed.
+*/
+
+int
+dk4stream_serialize_i32(dk4_stream_t *strm, int32_t i32, dk4_er_t *erp);
+
+
+/** Serialize unsigned 16 bit integer to stream.
+ @param strm Destination stream.
+ @param u16 Value to serialize.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is NULL or not opened for writing,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flusing data downwards failed.
+*/
+
+int
+dk4stream_serialize_u16(dk4_stream_t *strm, uint16_t u16, dk4_er_t *erp);
+
+
+/** Serialize signed 16 bit integer to stream.
+ @param strm Destination stream.
+ @param i16 Value to serialize.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is NULL or not opened for writing,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flusing data downwards failed.
+*/
+
+int
+dk4stream_serialize_i16(dk4_stream_t *strm, int16_t i16, dk4_er_t *erp);
+
+
+/** Serialize unsigned 8 bit integer to stream.
+ @param strm Destination stream.
+ @param u8 Value to serialize.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is NULL or not opened for writing,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flusing data downwards failed.
+*/
+
+int
+dk4stream_serialize_u8(dk4_stream_t *strm, uint8_t u8, dk4_er_t *erp);
+
+
+/** Serialize signed 8 bit integer to stream.
+ @param strm Destination stream.
+ @param i8 Value to serialize.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is NULL or not opened for writing,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flusing data downwards failed.
+*/
+
+int
+dk4stream_serialize_i8(dk4_stream_t *strm, int8_t i8, dk4_er_t *erp);
+
+
+/** Serialize string to stream.
+ First the string length including the 0x00 finalizer byte
+ is written as 16 bit unsigned integer, the string including the
+ finalizer byte follows.
+ By reading the length first, a reader application can allocate
+ a memory block of exact size before reading the string contents.
+ @param strm Destination stream.
+ @param str String to serialize, max 65534 characters long.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is NULL or not opened for writing,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the str string is too long,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flusing data downwards failed.
+*/
+
+int
+dk4stream_serialize_string(dk4_stream_t *strm, const char *str, dk4_er_t *erp);
+
+
+/** Serialize floating point value to stream.
+ For non-0.0 values the value is converted to a string, the string
+ is serialized to the stream. For 0.0 and values near enough
+ (absolute value is below a given limit) a string length 0 is written
+ indicating the 0.0 value to reader applications.
+ @param strm Destination stream.
+ @param d Value to serialize.
+ @param e Epsilon for check whether d is 0.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+
+int
+dk4stream_serialize_double(dk4_stream_t *strm,double d,double e,dk4_er_t *erp);
+
+
+/** Serialize floating point value 0 in short form.
+ @param strm Stream to write to.
+ @param erp Error report, may be NULL.
+*/
+
+int
+dk4stream_serialize_double_0(dk4_stream_t *strm, dk4_er_t *erp);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/* vim: set ai sw=4 ts=4 : */
+
+%% module
+
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_MATH_H
+#ifndef MATH_H_INCLUDED
+#include <math.h>
+#define MATH_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4strms.h"
+#include "dk4mao8dbl.h"
+
+
+int
+dk4stream_serialize_u32(dk4_stream_t *strm, uint32_t u32, dk4_er_t *erp)
+{
+ unsigned char buf[8];
+ int back = 0;
+
+ if (NULL != strm) {
+ buf[0] = (unsigned char)( u32 & 0x000000FFUL);
+ buf[1] = (unsigned char)((u32 >> 8) & 0x000000FFUL);
+ buf[2] = (unsigned char)((u32 >> 16) & 0x000000FFUL);
+ buf[3] = (unsigned char)((u32 >> 24) & 0x000000FFUL);
+ back = dk4stream_write(strm, buf, 4, erp);
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4stream_serialize_i32(dk4_stream_t *strm, int32_t i32, dk4_er_t *erp)
+{
+ return ( dk4stream_serialize_u32(strm, (uint32_t)i32, erp) );
+}
+
+
+
+int
+dk4stream_serialize_u16(dk4_stream_t *strm, uint16_t u16, dk4_er_t *erp)
+{
+ unsigned char buf[8];
+ int back = 0;
+
+ if (NULL != strm) {
+ buf[0] = (unsigned char)( u16 & 0x00FFU);
+ buf[1] = (unsigned char)((u16 >> 8) & 0x00FFU);
+ back = dk4stream_write(strm, buf, 2, erp);
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4stream_serialize_i16(dk4_stream_t *strm, int16_t i16, dk4_er_t *erp)
+{
+ return ( dk4stream_serialize_u16(strm, (uint16_t)i16, erp) );
+}
+
+
+
+int
+dk4stream_serialize_u8(dk4_stream_t *strm, uint8_t u8, dk4_er_t *erp)
+{
+ unsigned char uc;
+ int back = 0;
+
+ if (NULL != strm) {
+ uc = (unsigned char)u8;
+ back = dk4stream_write(strm, &uc, 1, erp);
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4stream_serialize_i8(dk4_stream_t *strm, int8_t i8, dk4_er_t *erp)
+{
+ return ( dk4stream_serialize_u8(strm, (uint8_t)i8, erp) );
+}
+
+
+
+int
+dk4stream_serialize_string(dk4_stream_t *strm, const char *str, dk4_er_t *erp)
+{
+ size_t sl = 0;
+ int back = 0;
+
+ if ((NULL != strm) && (NULL != str)) {
+ sl = strlen(str);
+ if (((size_t)0xFFFFU) > sl) {
+ sl++;
+ if (0 < dk4stream_serialize_u16(strm, (uint16_t)sl, erp)) {
+ back = dk4stream_write(strm, str, sl, erp);
+ }
+ else {
+ /* ERROR: Failed to serialize string length already reported */
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4stream_serialize_double(dk4_stream_t *strm,double d,double e,dk4_er_t *erp)
+{
+ char buf[16*sizeof(double)];
+ size_t szbuf = sizeof(buf);
+ int back = 0;
+ if (NULL != strm) {
+ if (fabs(d) < e) {
+ back = dk4stream_serialize_u16(strm, (uint16_t)0U, erp);
+ }
+ else {
+ if (0 < dk4ma_write_c8_double(buf, szbuf, d, 1, 1, erp)) {
+ back = dk4stream_serialize_string(strm, buf, erp);
+ }
+ else {
+ /* ##### ERROR: Failed to write double to string */
+ }
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4stream_serialize_double_0(dk4_stream_t *strm, dk4_er_t *erp)
+{
+ int back = 0;
+
+ if (NULL != strm) {
+ back = dk4stream_serialize_u16(strm, 0U, erp);
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+/* vim: set ai sw=4 ts=4 : */
+
diff --git a/support/dktools/dk4strms.h b/support/dktools/dk4strms.h
new file mode 100644
index 0000000000..6113340e8b
--- /dev/null
+++ b/support/dktools/dk4strms.h
@@ -0,0 +1,260 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4strms.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4STRMS_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4STRMS_H_INCLUDED 1
+
+
+#line 8 "dk4strms.ctr"
+
+/** @file dk4strms.h Serialize data to a stream.
+
+The functions to serialize integers write the least significant byte
+first.
+
+When serializing a string, the string length is serialized first as
+16 bit unsigned number, string contents follows.
+The finalizing 0x00 byte is both counted in the string length and written
+to the stream.
+So a reader application can retrieve the length first, allocate a memory
+block of exact size and read the string. Reader applications should
+check/ensure the finalizing byte after reading string contents.
+
+When serializing a double, the double is converted to a string and the
+string is serialized to the stream. For 0.0 and values nearby
+(absolute value is below a given limit) a string length 0 is serialized
+to the stream instead, no string is written.
+
+*/
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4STRM_H_INCLUDED
+#include <dk4strm.h>
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+/** Serialize unsigned 32 bit integer to stream.
+ @param strm Destination stream.
+ @param u32 Value to serialize.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is NULL or not opened for writing,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flusing data downwards failed.
+*/
+
+int
+dk4stream_serialize_u32(dk4_stream_t *strm, uint32_t u32, dk4_er_t *erp);
+
+
+/** Serialize signed 32 bit integer to stream.
+ @param strm Destination stream.
+ @param i32 Value to serialize.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is NULL or not opened for writing,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flusing data downwards failed.
+*/
+
+int
+dk4stream_serialize_i32(dk4_stream_t *strm, int32_t i32, dk4_er_t *erp);
+
+
+/** Serialize unsigned 16 bit integer to stream.
+ @param strm Destination stream.
+ @param u16 Value to serialize.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is NULL or not opened for writing,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flusing data downwards failed.
+*/
+
+int
+dk4stream_serialize_u16(dk4_stream_t *strm, uint16_t u16, dk4_er_t *erp);
+
+
+/** Serialize signed 16 bit integer to stream.
+ @param strm Destination stream.
+ @param i16 Value to serialize.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is NULL or not opened for writing,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flusing data downwards failed.
+*/
+
+int
+dk4stream_serialize_i16(dk4_stream_t *strm, int16_t i16, dk4_er_t *erp);
+
+
+/** Serialize unsigned 8 bit integer to stream.
+ @param strm Destination stream.
+ @param u8 Value to serialize.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is NULL or not opened for writing,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flusing data downwards failed.
+*/
+
+int
+dk4stream_serialize_u8(dk4_stream_t *strm, uint8_t u8, dk4_er_t *erp);
+
+
+/** Serialize signed 8 bit integer to stream.
+ @param strm Destination stream.
+ @param i8 Value to serialize.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is NULL or not opened for writing,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flusing data downwards failed.
+*/
+
+int
+dk4stream_serialize_i8(dk4_stream_t *strm, int8_t i8, dk4_er_t *erp);
+
+
+/** Serialize string to stream.
+ First the string length including the 0x00 finalizer byte
+ is written as 16 bit unsigned integer, the string including the
+ finalizer byte follows.
+ By reading the length first, a reader application can allocate
+ a memory block of exact size before reading the string contents.
+ @param strm Destination stream.
+ @param str String to serialize, max 65534 characters long.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strm is NULL or not opened for writing,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the str string is too long,
+ - DK4_E_WRITE_FAILED<br>
+ if writing one ore multiple bytes to the stream failed,
+ - DK4_E_FLUSH_FAILED<br>
+ if flusing data downwards failed.
+*/
+
+int
+dk4stream_serialize_string(dk4_stream_t *strm, const char *str, dk4_er_t *erp);
+
+
+/** Serialize floating point value to stream.
+ For non-0.0 values the value is converted to a string, the string
+ is serialized to the stream. For 0.0 and values near enough
+ (absolute value is below a given limit) a string length 0 is written
+ indicating the 0.0 value to reader applications.
+ @param strm Destination stream.
+ @param d Value to serialize.
+ @param e Epsilon for check whether d is 0.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+
+int
+dk4stream_serialize_double(dk4_stream_t *strm,double d,double e,dk4_er_t *erp);
+
+
+/** Serialize floating point value 0 in short form.
+ @param strm Stream to write to.
+ @param erp Error report, may be NULL.
+*/
+
+int
+dk4stream_serialize_double_0(dk4_stream_t *strm, dk4_er_t *erp);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/* vim: set ai sw=4 ts=4 : */
+
+
+#endif
diff --git a/support/dktools/dk4strmu.c b/support/dktools/dk4strmu.c
new file mode 100644
index 0000000000..8c3d234efb
--- /dev/null
+++ b/support/dktools/dk4strmu.c
@@ -0,0 +1,361 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4strmu.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4strmu.c The dk4strmu module.
+*/
+
+
+#line 222 "dk4strmu.ctr"
+
+#include "dk4conf.h"
+#include "dk4strmu.h"
+#include "dk4mai8dbl.h"
+#include "dk4mem.h"
+
+
+int
+dk4stream_unser_u32(uint32_t *ptr, dk4_stream_t *strm, dk4_er_t *erp)
+{
+ unsigned char buf[8];
+ size_t sz = 4;
+ unsigned long res = 0UL;
+ int back = 0;
+
+ if ((NULL != ptr) && (NULL != strm)) {
+ if (0 < dk4stream_read(buf, &sz, strm, erp)) {
+ if (4 == sz) {
+ res =
+ (
+ ( (unsigned long)(buf[0])) & 0x000000FFUL
+ )
+ | (
+ (((unsigned long)(buf[1])) << 8) & 0x0000FF00UL
+ )
+ | (
+ (((unsigned long)(buf[2])) << 16) & 0x00FF0000UL
+ )
+ | (
+ (((unsigned long)(buf[3])) << 24) & 0xFF000000UL
+ );
+ *ptr = (uint32_t)res;
+ back = 1;
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ }
+ else {
+ /* ERROR: Read failed, already reported */
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4stream_unser_i32(int32_t *ptr, dk4_stream_t *strm, dk4_er_t *erp)
+{
+ uint32_t res = 0UL;
+ int back = 0;
+
+ if (NULL != ptr) {
+ back = dk4stream_unser_u32(&res, strm, erp);
+ if (0 < back) {
+ *ptr = (int32_t)res;
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+
+int
+dk4stream_unser_u16(uint16_t *ptr, dk4_stream_t *strm, dk4_er_t *erp)
+{
+ unsigned char buf[8];
+ size_t sz = 2;
+ unsigned res = 0U;
+ int back = 0;
+
+ if ((NULL != ptr) && (NULL != strm)) {
+ if (0 < dk4stream_read(buf, &sz, strm, erp)) {
+ if (2 == sz) {
+ res =
+ (
+ ( (unsigned)(buf[0])) & 0x00FFU
+ )
+ | (
+ (((unsigned)(buf[1])) << 8) & 0xFF00U
+ );
+ *ptr = (uint16_t)res;
+ back = 1;
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ }
+ else {
+ /* ERROR: Read failed, already reported */
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4stream_unser_i16(int16_t *ptr, dk4_stream_t *strm, dk4_er_t *erp)
+{
+ uint16_t res = 0UL;
+ int back = 0;
+
+ if (NULL != ptr) {
+ back = dk4stream_unser_u16(&res, strm, erp);
+ if (0 < back) {
+ *ptr = (int16_t)res;
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4stream_unser_u8(uint8_t *ptr, dk4_stream_t *strm, dk4_er_t *erp)
+{
+ unsigned char buf[8];
+ size_t sz = 1;
+ int back = 0;
+
+ if ((NULL != ptr) && (NULL != strm)) {
+ if (0 < dk4stream_read(buf, &sz, strm, erp)) {
+ if (1 == sz) {
+ *ptr = (uint8_t)(buf[0]);
+ back = 1;
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ }
+ else {
+ /* ERROR: Read failed, already reported */
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4stream_unser_i8(int8_t *ptr, dk4_stream_t *strm, dk4_er_t *erp)
+{
+ uint8_t res = 0UL;
+ int back = 0;
+
+ if (NULL != ptr) {
+ back = dk4stream_unser_u8(&res, strm, erp);
+ if (0 < back) {
+ *ptr = (int8_t)res;
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4stream_unser_string(char **strptr, dk4_stream_t *strm, dk4_er_t *erp)
+{
+ char *np = NULL;
+ size_t sz = 0;
+ int back = 0;
+ int res = 0;
+ uint16_t sl = 0;
+
+ if ((NULL != strptr) && (NULL != strm)) {
+ res = dk4stream_unser_u16(&sl, strm, erp);
+ if (0 < res) {
+ if (0U < sl) {
+ np = dk4mem_new(char, (size_t)sl, erp);
+ if (NULL != np) {
+ sz = (size_t)sl;
+ back = dk4stream_read(np, &sz, strm, erp);
+ if (0 < back) {
+ back = 0;
+ if (sz == (size_t)sl) {
+ if ('\0' == np[sz - 1]) {
+ back = 1;
+ }
+ else {
+ /* ERROR: Missing delimiter */
+ dk4error_set_simple_error_code(
+ erp, DK4_E_SYNTAX
+ );
+ dk4mem_free(np);
+ np = NULL;
+ }
+ }
+ else {
+ /* ERROR: Wrong number of bytes */
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ dk4mem_free(np);
+ np = NULL;
+ }
+ }
+ else {
+ /* ERROR: Read attempt failed */
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ dk4mem_free(np);
+ np = NULL;
+ }
+ }
+ else {
+ /* ERROR: Memory, already reported */
+ }
+ }
+ else {
+ /* ERROR: Length is zero */
+ back = 1;
+#if 0
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+#endif
+ }
+ }
+ else {
+ /* ERROR: Failed to read string length, already reported */
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ if (NULL != strptr) {
+ *strptr = np;
+ }
+ return back;
+}
+
+
+
+int
+dk4stream_unser_double(double *ptr, dk4_stream_t *strm, dk4_er_t *erp)
+{
+ char buf[16*sizeof(double)];
+ const char *ep = NULL;
+ double d = 0.0;
+ size_t szb = sizeof(buf);
+ size_t sz = 0;
+ int back = 0;
+ uint16_t sl = 0;
+
+ if ((NULL != ptr) && (NULL != strm)) {
+ if (0 < dk4stream_unser_u16(&sl, strm, erp)) {
+ if (0U == sl) {
+ /* Easy variant for 0.0 */
+ *ptr = 0.0;
+ back = 1;
+ }
+ else {
+ if (szb >= (size_t)sl) {
+ sz = (size_t)sl;
+ if (0 < dk4stream_read(buf, &sz, strm, erp)) {
+ if (sz == (size_t)sl) {
+ if ('\0' == buf[sz - 1]) {
+ back = dk4ma_input_c8_double(
+ &d, buf, &ep, 0, erp
+ );
+ if (0 < back) {
+ *ptr = d;
+ }
+ else {
+ /* ERROR: Conversion failed, reported */
+ }
+ }
+ else {
+ /* ERROR: Not 0x00-terminated */
+ dk4error_set_simple_error_code(
+ erp, DK4_E_SYNTAX
+ );
+ }
+ }
+ else {
+ /* ERROR: Too few bytes */
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ }
+ else {
+ /* ERROR: Failed to read */
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ }
+ else {
+ /* ERROR: String too long */
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ }
+ }
+ else {
+ /* ERROR: Failed to read length, already reported */
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+/* vim: set ai sw=4 ts=4 : */
+
diff --git a/support/dktools/dk4strmu.ctr b/support/dktools/dk4strmu.ctr
new file mode 100644
index 0000000000..8b2d38ec1e
--- /dev/null
+++ b/support/dktools/dk4strmu.ctr
@@ -0,0 +1,542 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+%% header
+
+/** @file dk4strmu.h Unserialize data from stream.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4STRM_H_INCLUDED
+#include <dk4strm.h>
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** Retrieve 32 bit unsigned value from stream.
+ @param ptr Address of result variable.
+ @param strm Data stream to read from.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if ptr is NULL or strm is NULL or not opened for reading,
+ - DK4_E_SYNTAX<br>
+ if the end of data stream was reached before reading 4 bytes,
+ - DK4_E_NOT_FOUND<br>
+ if not further data was found (EOF reached),
+ - DK4_E_READ_FAILED<br>
+ if a read attempt failed for other reasons.
+*/
+
+int
+dk4stream_unser_u32(uint32_t *ptr, dk4_stream_t *strm, dk4_er_t *erp);
+
+
+/** Retrieve 32 bit signed value from stream.
+ @param ptr Address of result variable.
+ @param strm Data stream to read from.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if ptr is NULL or strm is NULL or not opened for reading,
+ - DK4_E_SYNTAX<br>
+ if the end of data stream was reached before reading 4 bytes,
+ - DK4_E_NOT_FOUND<br>
+ if not further data was found (EOF reached),
+ - DK4_E_READ_FAILED<br>
+ if a read attempt failed for other reasons.
+*/
+
+int
+dk4stream_unser_i32(int32_t *ptr, dk4_stream_t *strm, dk4_er_t *erp);
+
+
+/** Retrieve 16 bit unsigned value from stream.
+ @param ptr Address of result variable.
+ @param strm Data stream to read from.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if ptr is NULL or strm is NULL or not opened for reading,
+ - DK4_E_SYNTAX<br>
+ if the end of data stream was reached before reading 2 bytes,
+ - DK4_E_NOT_FOUND<br>
+ if not further data was found (EOF reached),
+ - DK4_E_READ_FAILED<br>
+ if a read attempt failed for other reasons.
+*/
+
+int
+dk4stream_unser_u16(uint16_t *ptr, dk4_stream_t *strm, dk4_er_t *erp);
+
+
+/** Retrieve 16 bit signed value from stream.
+ @param ptr Address of result variable.
+ @param strm Data stream to read from.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if ptr is NULL or strm is NULL or not opened for reading,
+ - DK4_E_SYNTAX<br>
+ if the end of data stream was reached before reading 2 bytes,
+ - DK4_E_NOT_FOUND<br>
+ if not further data was found (EOF reached),
+ - DK4_E_READ_FAILED<br>
+ if a read attempt failed for other reasons.
+*/
+
+int
+dk4stream_unser_i16(int16_t *ptr, dk4_stream_t *strm, dk4_er_t *erp);
+
+
+/** Retrieve 8 bit unsigned value from stream.
+ @param ptr Address of result variable.
+ @param strm Data stream to read from.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if ptr is NULL or strm is NULL or not opened for reading,
+ - DK4_E_SYNTAX<br>
+ if the end of data stream was reached before reading 1 byte,
+ - DK4_E_NOT_FOUND<br>
+ if not further data was found (EOF reached),
+ - DK4_E_READ_FAILED<br>
+ if a read attempt failed for other reasons.
+*/
+
+int
+dk4stream_unser_u8(uint8_t *ptr, dk4_stream_t *strm, dk4_er_t *erp);
+
+
+/** Retrieve 8 bit signed value from stream.
+ @param ptr Address of result variable.
+ @param strm Data stream to read from.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if ptr is NULL or strm is NULL or not opened for reading,
+ - DK4_E_SYNTAX<br>
+ if the end of data stream was reached before reading 1 byte,
+ - DK4_E_NOT_FOUND<br>
+ if not further data was found (EOF reached),
+ - DK4_E_READ_FAILED<br>
+ if a read attempt failed for other reasons.
+*/
+
+int
+dk4stream_unser_i8(int8_t *ptr, dk4_stream_t *strm, dk4_er_t *erp);
+
+
+/** Retrieve string from stream.
+ The variable strptr points to should be initialized to NULL.
+ On success (string found) this variable is set to dynamically allocated
+ memory. Use dk4mem_release() or dk4mem_free() to release that
+ memory after use.
+ The function sets the destination pointer variable to NULL and reports
+ success if a leading string length 0 was found.
+ @param strptr Address of pointer variable.
+ @param strm Data stream to read from.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strptr is NULL or strm is NULL or not opened for reading,
+ - DK4_E_SYNTAX<br>
+ on unexpected end of data stream or when missing the finalizing
+ 0x00 byte on end of string,
+ - DK4_E_NOT_FOUND<br>
+ if EOF was reached,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available.
+ - DK4_E_READ_FAILED<br>
+ if a read attempt failed for other reasons.
+*/
+
+int
+dk4stream_unser_string(char **strptr, dk4_stream_t *strm, dk4_er_t *erp);
+
+
+/** Retrieve double value from stream.
+ @param ptr Address of result variable.
+ @param strm Data stream to read from.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if ptr is NULL or strm is NULL or not opened for reading,
+ - DK4_E_SYNTAX<br>
+ on
+ - unexpected end of data stream
+ - or when missing the finalizing 0x00 byte on end of string
+ - or when the string is too long
+ - or when the string does not contain a double number,
+ - DK4_E_NOT_FOUND<br>
+ if not further data was found (EOF reached),
+ - DK4_E_READ_FAILED<br>
+ if a read attempt failed for other reasons.
+*/
+
+int
+dk4stream_unser_double(double *ptr, dk4_stream_t *strm, dk4_er_t *erp);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4strmu.h"
+#include "dk4mai8dbl.h"
+#include "dk4mem.h"
+
+
+int
+dk4stream_unser_u32(uint32_t *ptr, dk4_stream_t *strm, dk4_er_t *erp)
+{
+ unsigned char buf[8];
+ size_t sz = 4;
+ unsigned long res = 0UL;
+ int back = 0;
+
+ if ((NULL != ptr) && (NULL != strm)) {
+ if (0 < dk4stream_read(buf, &sz, strm, erp)) {
+ if (4 == sz) {
+ res =
+ (
+ ( (unsigned long)(buf[0])) & 0x000000FFUL
+ )
+ | (
+ (((unsigned long)(buf[1])) << 8) & 0x0000FF00UL
+ )
+ | (
+ (((unsigned long)(buf[2])) << 16) & 0x00FF0000UL
+ )
+ | (
+ (((unsigned long)(buf[3])) << 24) & 0xFF000000UL
+ );
+ *ptr = (uint32_t)res;
+ back = 1;
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ }
+ else {
+ /* ERROR: Read failed, already reported */
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4stream_unser_i32(int32_t *ptr, dk4_stream_t *strm, dk4_er_t *erp)
+{
+ uint32_t res = 0UL;
+ int back = 0;
+
+ if (NULL != ptr) {
+ back = dk4stream_unser_u32(&res, strm, erp);
+ if (0 < back) {
+ *ptr = (int32_t)res;
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+
+int
+dk4stream_unser_u16(uint16_t *ptr, dk4_stream_t *strm, dk4_er_t *erp)
+{
+ unsigned char buf[8];
+ size_t sz = 2;
+ unsigned res = 0U;
+ int back = 0;
+
+ if ((NULL != ptr) && (NULL != strm)) {
+ if (0 < dk4stream_read(buf, &sz, strm, erp)) {
+ if (2 == sz) {
+ res =
+ (
+ ( (unsigned)(buf[0])) & 0x00FFU
+ )
+ | (
+ (((unsigned)(buf[1])) << 8) & 0xFF00U
+ );
+ *ptr = (uint16_t)res;
+ back = 1;
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ }
+ else {
+ /* ERROR: Read failed, already reported */
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4stream_unser_i16(int16_t *ptr, dk4_stream_t *strm, dk4_er_t *erp)
+{
+ uint16_t res = 0UL;
+ int back = 0;
+
+ if (NULL != ptr) {
+ back = dk4stream_unser_u16(&res, strm, erp);
+ if (0 < back) {
+ *ptr = (int16_t)res;
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4stream_unser_u8(uint8_t *ptr, dk4_stream_t *strm, dk4_er_t *erp)
+{
+ unsigned char buf[8];
+ size_t sz = 1;
+ int back = 0;
+
+ if ((NULL != ptr) && (NULL != strm)) {
+ if (0 < dk4stream_read(buf, &sz, strm, erp)) {
+ if (1 == sz) {
+ *ptr = (uint8_t)(buf[0]);
+ back = 1;
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ }
+ else {
+ /* ERROR: Read failed, already reported */
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4stream_unser_i8(int8_t *ptr, dk4_stream_t *strm, dk4_er_t *erp)
+{
+ uint8_t res = 0UL;
+ int back = 0;
+
+ if (NULL != ptr) {
+ back = dk4stream_unser_u8(&res, strm, erp);
+ if (0 < back) {
+ *ptr = (int8_t)res;
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4stream_unser_string(char **strptr, dk4_stream_t *strm, dk4_er_t *erp)
+{
+ char *np = NULL;
+ size_t sz = 0;
+ int back = 0;
+ int res = 0;
+ uint16_t sl = 0;
+
+ if ((NULL != strptr) && (NULL != strm)) {
+ res = dk4stream_unser_u16(&sl, strm, erp);
+ if (0 < res) {
+ if (0U < sl) {
+ np = dk4mem_new(char, (size_t)sl, erp);
+ if (NULL != np) {
+ sz = (size_t)sl;
+ back = dk4stream_read(np, &sz, strm, erp);
+ if (0 < back) {
+ back = 0;
+ if (sz == (size_t)sl) {
+ if ('\0' == np[sz - 1]) {
+ back = 1;
+ }
+ else {
+ /* ERROR: Missing delimiter */
+ dk4error_set_simple_error_code(
+ erp, DK4_E_SYNTAX
+ );
+ dk4mem_free(np);
+ np = NULL;
+ }
+ }
+ else {
+ /* ERROR: Wrong number of bytes */
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ dk4mem_free(np);
+ np = NULL;
+ }
+ }
+ else {
+ /* ERROR: Read attempt failed */
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ dk4mem_free(np);
+ np = NULL;
+ }
+ }
+ else {
+ /* ERROR: Memory, already reported */
+ }
+ }
+ else {
+ /* ERROR: Length is zero */
+ back = 1;
+#if 0
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+#endif
+ }
+ }
+ else {
+ /* ERROR: Failed to read string length, already reported */
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ if (NULL != strptr) {
+ *strptr = np;
+ }
+ return back;
+}
+
+
+
+int
+dk4stream_unser_double(double *ptr, dk4_stream_t *strm, dk4_er_t *erp)
+{
+ char buf[16*sizeof(double)];
+ const char *ep = NULL;
+ double d = 0.0;
+ size_t szb = sizeof(buf);
+ size_t sz = 0;
+ int back = 0;
+ uint16_t sl = 0;
+
+ if ((NULL != ptr) && (NULL != strm)) {
+ if (0 < dk4stream_unser_u16(&sl, strm, erp)) {
+ if (0U == sl) {
+ /* Easy variant for 0.0 */
+ *ptr = 0.0;
+ back = 1;
+ }
+ else {
+ if (szb >= (size_t)sl) {
+ sz = (size_t)sl;
+ if (0 < dk4stream_read(buf, &sz, strm, erp)) {
+ if (sz == (size_t)sl) {
+ if ('\0' == buf[sz - 1]) {
+ back = dk4ma_input_c8_double(
+ &d, buf, &ep, 0, erp
+ );
+ if (0 < back) {
+ *ptr = d;
+ }
+ else {
+ /* ERROR: Conversion failed, reported */
+ }
+ }
+ else {
+ /* ERROR: Not 0x00-terminated */
+ dk4error_set_simple_error_code(
+ erp, DK4_E_SYNTAX
+ );
+ }
+ }
+ else {
+ /* ERROR: Too few bytes */
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ }
+ else {
+ /* ERROR: Failed to read */
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ }
+ else {
+ /* ERROR: String too long */
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ }
+ }
+ else {
+ /* ERROR: Failed to read length, already reported */
+ }
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+/* vim: set ai sw=4 ts=4 : */
+
diff --git a/support/dktools/dk4strmu.h b/support/dktools/dk4strmu.h
new file mode 100644
index 0000000000..f20886a106
--- /dev/null
+++ b/support/dktools/dk4strmu.h
@@ -0,0 +1,256 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4strmu.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4STRMU_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4STRMU_H_INCLUDED 1
+
+
+#line 8 "dk4strmu.ctr"
+
+/** @file dk4strmu.h Unserialize data from stream.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4STRM_H_INCLUDED
+#include <dk4strm.h>
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** Retrieve 32 bit unsigned value from stream.
+ @param ptr Address of result variable.
+ @param strm Data stream to read from.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if ptr is NULL or strm is NULL or not opened for reading,
+ - DK4_E_SYNTAX<br>
+ if the end of data stream was reached before reading 4 bytes,
+ - DK4_E_NOT_FOUND<br>
+ if not further data was found (EOF reached),
+ - DK4_E_READ_FAILED<br>
+ if a read attempt failed for other reasons.
+*/
+
+int
+dk4stream_unser_u32(uint32_t *ptr, dk4_stream_t *strm, dk4_er_t *erp);
+
+
+/** Retrieve 32 bit signed value from stream.
+ @param ptr Address of result variable.
+ @param strm Data stream to read from.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if ptr is NULL or strm is NULL or not opened for reading,
+ - DK4_E_SYNTAX<br>
+ if the end of data stream was reached before reading 4 bytes,
+ - DK4_E_NOT_FOUND<br>
+ if not further data was found (EOF reached),
+ - DK4_E_READ_FAILED<br>
+ if a read attempt failed for other reasons.
+*/
+
+int
+dk4stream_unser_i32(int32_t *ptr, dk4_stream_t *strm, dk4_er_t *erp);
+
+
+/** Retrieve 16 bit unsigned value from stream.
+ @param ptr Address of result variable.
+ @param strm Data stream to read from.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if ptr is NULL or strm is NULL or not opened for reading,
+ - DK4_E_SYNTAX<br>
+ if the end of data stream was reached before reading 2 bytes,
+ - DK4_E_NOT_FOUND<br>
+ if not further data was found (EOF reached),
+ - DK4_E_READ_FAILED<br>
+ if a read attempt failed for other reasons.
+*/
+
+int
+dk4stream_unser_u16(uint16_t *ptr, dk4_stream_t *strm, dk4_er_t *erp);
+
+
+/** Retrieve 16 bit signed value from stream.
+ @param ptr Address of result variable.
+ @param strm Data stream to read from.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if ptr is NULL or strm is NULL or not opened for reading,
+ - DK4_E_SYNTAX<br>
+ if the end of data stream was reached before reading 2 bytes,
+ - DK4_E_NOT_FOUND<br>
+ if not further data was found (EOF reached),
+ - DK4_E_READ_FAILED<br>
+ if a read attempt failed for other reasons.
+*/
+
+int
+dk4stream_unser_i16(int16_t *ptr, dk4_stream_t *strm, dk4_er_t *erp);
+
+
+/** Retrieve 8 bit unsigned value from stream.
+ @param ptr Address of result variable.
+ @param strm Data stream to read from.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if ptr is NULL or strm is NULL or not opened for reading,
+ - DK4_E_SYNTAX<br>
+ if the end of data stream was reached before reading 1 byte,
+ - DK4_E_NOT_FOUND<br>
+ if not further data was found (EOF reached),
+ - DK4_E_READ_FAILED<br>
+ if a read attempt failed for other reasons.
+*/
+
+int
+dk4stream_unser_u8(uint8_t *ptr, dk4_stream_t *strm, dk4_er_t *erp);
+
+
+/** Retrieve 8 bit signed value from stream.
+ @param ptr Address of result variable.
+ @param strm Data stream to read from.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if ptr is NULL or strm is NULL or not opened for reading,
+ - DK4_E_SYNTAX<br>
+ if the end of data stream was reached before reading 1 byte,
+ - DK4_E_NOT_FOUND<br>
+ if not further data was found (EOF reached),
+ - DK4_E_READ_FAILED<br>
+ if a read attempt failed for other reasons.
+*/
+
+int
+dk4stream_unser_i8(int8_t *ptr, dk4_stream_t *strm, dk4_er_t *erp);
+
+
+/** Retrieve string from stream.
+ The variable strptr points to should be initialized to NULL.
+ On success (string found) this variable is set to dynamically allocated
+ memory. Use dk4mem_release() or dk4mem_free() to release that
+ memory after use.
+ The function sets the destination pointer variable to NULL and reports
+ success if a leading string length 0 was found.
+ @param strptr Address of pointer variable.
+ @param strm Data stream to read from.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if strptr is NULL or strm is NULL or not opened for reading,
+ - DK4_E_SYNTAX<br>
+ on unexpected end of data stream or when missing the finalizing
+ 0x00 byte on end of string,
+ - DK4_E_NOT_FOUND<br>
+ if EOF was reached,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ with mem.elsize and mem.nelem
+ set if there is not enough memory available.
+ - DK4_E_READ_FAILED<br>
+ if a read attempt failed for other reasons.
+*/
+
+int
+dk4stream_unser_string(char **strptr, dk4_stream_t *strm, dk4_er_t *erp);
+
+
+/** Retrieve double value from stream.
+ @param ptr Address of result variable.
+ @param strm Data stream to read from.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if ptr is NULL or strm is NULL or not opened for reading,
+ - DK4_E_SYNTAX<br>
+ on
+ - unexpected end of data stream
+ - or when missing the finalizing 0x00 byte on end of string
+ - or when the string is too long
+ - or when the string does not contain a double number,
+ - DK4_E_NOT_FOUND<br>
+ if not further data was found (EOF reached),
+ - DK4_E_READ_FAILED<br>
+ if a read attempt failed for other reasons.
+*/
+
+int
+dk4stream_unser_double(double *ptr, dk4_stream_t *strm, dk4_er_t *erp);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4strmw.c b/support/dktools/dk4strmw.c
new file mode 100644
index 0000000000..45a50a3663
--- /dev/null
+++ b/support/dktools/dk4strmw.c
@@ -0,0 +1,391 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4strmw.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4strmw.c The dk4strmw module.
+*/
+
+
+#line 72 "dk4strmw.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS && DK4_WIN_DENY_CRT
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#ifndef DK4STRMH_H_INCLUDED
+#include "dk4strmh.h"
+#endif
+#endif
+
+#include "dk4strmw.h"
+
+#ifndef DK4FD_H_INCLUDED
+#include "dk4fd.h"
+#endif
+
+#ifndef DK4PATH_H_INCLUDED
+#include "dk4pathd.h"
+#endif
+
+#ifndef DK4STRD_H_INCLUDED
+#include "dk4strd.h"
+#endif
+
+#ifndef DK4FOPD_H_INCLUDED
+#include "dk4fopd.h"
+#endif
+
+
+
+
+
+#line 106 "dk4strmw.ctr"
+
+
+
+/** Compression suffixes.
+*/
+static const dkChar * const dk4strmw_co_su[] = {
+/* 0 */
+dkT(".gz"),
+
+/* 1 */
+dkT(".svgz"),
+
+/* 2 */
+dkT(".bz2"),
+
+NULL
+
+
+#line 117 "dk4strmw.ctr"
+};
+
+
+
+/** File mode for binary writing.
+*/
+static const char dk4strmw_c8_mode[] = { "wb" };
+
+
+
+/** File mode for binary writing.
+*/
+static const dkChar dk4strmw_dk_mode[] = { dkT("wb") };
+
+
+
+dk4_stream_t *
+dk4stream_open_file_writer(const dkChar *filename, dk4_er_t *erp)
+{
+ dk4_stream_t *back = NULL; /* Function result */
+ dkChar *p1 = NULL; /* File name suffix */
+#if DK4_HAVE_ZLIB_H && (!(DK4_ON_WINDOWS && DK4_WIN_DENY_CRT))
+ gzFile gzf = NULL; /* gzip compressed output file */
+#endif
+#if DK4_HAVE_BZLIB_H && (!(DK4_ON_WINDOWS && DK4_WIN_DENY_CRT))
+ BZFILE *bzf = NULL; /* bzip2 compressed output file */
+#endif
+ FILE *fipo = NULL; /* Output file */
+#if DK4_ON_WINDOWS && DK4_WIN_DENY_CRT
+ HANDLE fha = INVALID_HANDLE_VALUE;
+ DWORD dwattr = (DWORD)0UL;
+#endif
+ int coi = -1; /* Compression algorithm index */
+#if DK4_CHAR_SIZE > 1
+ int fd = -1; /* File descriptor */
+#endif
+
+
+
+#line 155 "dk4strmw.ctr"
+ if (NULL != filename) {
+ p1 = dk4path_get_suffix(filename, erp);
+ if (NULL != p1) {
+
+#line 158 "dk4strmw.ctr"
+ coi = dk4str_array_index(
+ dk4strmw_co_su, p1, DK4_HAVE_CASE_INSENSITIVE_PATHNAMES
+ );
+ if (0 > coi) { coi = -1; }
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 165 "dk4strmw.ctr"
+ }
+#endif
+ if (0 != dk4fopen_check(filename, 1, DK4_FOPEN_SC_IS_REGULAR, erp)) {
+ switch (coi) {
+ case 0: case 1: {
+
+#line 170 "dk4strmw.ctr"
+#if DK4_HAVE_ZLIB_H && (!(DK4_ON_WINDOWS && DK4_WIN_DENY_CRT))
+#if DK4_CHAR_SIZE > 1
+ /* +++++ gzip, wchar_t */
+
+
+#line 174 "dk4strmw.ctr"
+ fd = dk4fd_wc_open(
+ filename,
+ (DK4_O_WRONLY | DK4_O_BINARY | DK4_O_TRUNC | DK4_O_CREAT),
+ erp
+ );
+ if (-1 < fd) {
+ gzf = gzdopen(fd, dk4strmw_c8_mode);
+ if (NULL != gzf) {
+ back = dk4stream_open_for_gzfile_with_close(
+ gzf, DK4_STREAM_WRITE, 1024, 4096, erp
+ );
+ if (NULL == back) {
+
+#line 186 "dk4strmw.ctr"
+ gzclose(gzf);
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 190 "dk4strmw.ctr"
+ }
+#endif
+ } else {
+
+#line 193 "dk4strmw.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_OPEN_WRITE_FAILED);
+ (void)dk4fd_close(fd, NULL);
+ }
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 199 "dk4strmw.ctr"
+ }
+#endif
+ /* ----- gzip, wchar_t */
+#else
+ /* +++++ gzip, char */
+
+
+#line 205 "dk4strmw.ctr"
+ gzf = gzopen(filename, dk4strmw_c8_mode);
+ if (NULL != gzf) {
+ back = dk4stream_open_for_gzfile_with_close(
+ gzf, DK4_STREAM_WRITE, 1024, 4096, erp
+ );
+ if (NULL == back) {
+
+#line 211 "dk4strmw.ctr"
+ gzclose(gzf);
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 215 "dk4strmw.ctr"
+ }
+#endif
+ } else {
+
+#line 218 "dk4strmw.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_OPEN_WRITE_FAILED);
+ }
+ /* ----- gzip, char */
+#endif
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case 2: {
+
+#line 227 "dk4strmw.ctr"
+#if DK4_HAVE_BZLIB_H && (!(DK4_ON_WINDOWS && DK4_WIN_DENY_CRT))
+#if DK4_CHAR_SIZE > 1
+ /* +++++ bzip2, wchar_t */
+
+
+#line 231 "dk4strmw.ctr"
+ fd = dk4fd_wc_open(
+ filename,
+ (DK4_O_WRONLY | DK4_O_BINARY | DK4_O_TRUNC | DK4_O_CREAT),
+ erp
+ );
+ if (-1 < fd) {
+ bzf = BZ2_bzdopen(fd, dk4strmw_c8_mode);
+ if (NULL != bzf) {
+ back = dk4stream_open_for_bzfile_with_close(
+ bzf, DK4_STREAM_WRITE, 1024, 4096, erp
+ );
+ if (NULL == back) {
+
+#line 243 "dk4strmw.ctr"
+ BZ2_bzclose(bzf);
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 247 "dk4strmw.ctr"
+ }
+#endif
+ } else {
+
+#line 250 "dk4strmw.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_OPEN_WRITE_FAILED);
+ (void)dk4fd_close(fd, NULL);
+ }
+ } else {
+
+#line 254 "dk4strmw.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_OPEN_WRITE_FAILED);
+ }
+ /* ----- bzip2, wchar_t */
+#else
+ /* +++++ bzip2, char */
+
+
+#line 260 "dk4strmw.ctr"
+ bzf = BZ2_bzopen(filename, dk4strmw_c8_mode);
+ if (NULL != bzf) {
+ back = dk4stream_open_for_bzfile_with_close(
+ bzf, DK4_STREAM_WRITE, 1024, 4096, erp
+ );
+ if (NULL == back) {
+
+#line 266 "dk4strmw.ctr"
+ BZ2_bzclose(bzf);
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 270 "dk4strmw.ctr"
+ }
+#endif
+ } else {
+
+#line 273 "dk4strmw.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_OPEN_WRITE_FAILED);
+ }
+ /* ----- bzip2, char */
+#endif
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ default: {
+
+#line 282 "dk4strmw.ctr"
+#if DK4_ON_WINDOWS && DK4_WIN_DENY_CRT
+
+
+#line 284 "dk4strmw.ctr"
+ dwattr = FILE_ATTRIBUTE_NORMAL;
+ dwattr |= FILE_FLAG_BACKUP_SEMANTICS;
+ dwattr |= FILE_FLAG_SEQUENTIAL_SCAN;
+#if DK4_CHAR_SIZE > 1
+ fha = CreateFileW(
+ filename, GENERIC_WRITE, 0, NULL,
+ CREATE_ALWAYS, dwattr, NULL
+ );
+#else
+ fha = CreateFileA(
+ filename, GENERIC_WRITE, 0, NULL,
+ CREATE_ALWAYS, dwattr, NULL
+ );
+#endif
+ if (INVALID_HANDLE_VALUE != fha) {
+ back = dk4stream_open_for_windows_handle_with_close(
+ fha, DK4_STREAM_WRITE, 1024, 4096, erp
+ );
+ if (NULL == back) {
+
+#line 303 "dk4strmw.ctr"
+ (void)CloseHandle(fha);
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 307 "dk4strmw.ctr"
+ }
+#endif
+ } else {
+
+#line 310 "dk4strmw.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_OPEN_WRITE_FAILED);
+ }
+#else
+
+
+#line 314 "dk4strmw.ctr"
+ fipo = dk4fopen(
+ filename, dk4strmw_dk_mode, DK4_FOPEN_SC_IS_REGULAR, erp
+ );
+ if (NULL != fipo) {
+ back = dk4stream_open_for_file_with_close(
+ fipo, DK4_STREAM_WRITE, 1024, 4096, erp
+ );
+ if (NULL == back) {
+
+#line 322 "dk4strmw.ctr"
+ (void)fclose(fipo);
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 326 "dk4strmw.ctr"
+ }
+#endif
+ } else {
+
+#line 329 "dk4strmw.ctr"
+ }
+#endif
+ } break;
+ }
+ } else {
+
+#line 334 "dk4strmw.ctr"
+ }
+ } else {
+
+#line 336 "dk4strmw.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 339 "dk4strmw.ctr"
+ return back;
+}
+
+
diff --git a/support/dktools/dk4strmw.ctr b/support/dktools/dk4strmw.ctr
new file mode 100644
index 0000000000..1f69ad78a8
--- /dev/null
+++ b/support/dktools/dk4strmw.ctr
@@ -0,0 +1,342 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ Open a stream to write a file.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4STRM_H_INCLUDED
+#include "dk4strm.h"
+#endif
+
+#ifndef DK4STRMF_H_INCLUDED
+#include "dk4strmf.h"
+#endif
+
+#ifndef DK4STRMG_H_INCLUDED
+#include "dk4strmg.h"
+#endif
+
+#ifndef DK4STRMB_H_INCLUDED
+#include "dk4strmb.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open a stream to write a file.
+ CRT on Windows: Optional, disabling CRT reduces functionality
+ by disabling the gzip and bzip2 compression libraries.
+ @param filename File name of file to write.
+ @param erp Error report, may be NULL.
+ @return Pointer to stream on success, NULL on error.
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if filename is NULL,
+ - DK4_E_MATH_OVERFLOW<br>
+ if ibs or obs is too large,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if allocation of input or output buffer failed.
+*/
+
+dk4_stream_t *
+dk4stream_open_file_writer(const dkChar *filename, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS && DK4_WIN_DENY_CRT
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#ifndef DK4STRMH_H_INCLUDED
+#include "dk4strmh.h"
+#endif
+#endif
+
+#include "dk4strmw.h"
+
+#ifndef DK4FD_H_INCLUDED
+#include "dk4fd.h"
+#endif
+
+#ifndef DK4PATH_H_INCLUDED
+#include "dk4pathd.h"
+#endif
+
+#ifndef DK4STRD_H_INCLUDED
+#include "dk4strd.h"
+#endif
+
+#ifndef DK4FOPD_H_INCLUDED
+#include "dk4fopd.h"
+#endif
+
+
+
+$!trace-include
+
+
+
+/** Compression suffixes.
+*/
+static const dkChar * const dk4strmw_co_su[] = {
+$!string-table macro=dkT
+.gz
+.svgz
+.bz2
+$!end
+};
+
+
+
+/** File mode for binary writing.
+*/
+static const char dk4strmw_c8_mode[] = { "wb" };
+
+
+
+/** File mode for binary writing.
+*/
+static const dkChar dk4strmw_dk_mode[] = { dkT("wb") };
+
+
+
+dk4_stream_t *
+dk4stream_open_file_writer(const dkChar *filename, dk4_er_t *erp)
+{
+ dk4_stream_t *back = NULL; /* Function result */
+ dkChar *p1 = NULL; /* File name suffix */
+#if DK4_HAVE_ZLIB_H && (!(DK4_ON_WINDOWS && DK4_WIN_DENY_CRT))
+ gzFile gzf = NULL; /* gzip compressed output file */
+#endif
+#if DK4_HAVE_BZLIB_H && (!(DK4_ON_WINDOWS && DK4_WIN_DENY_CRT))
+ BZFILE *bzf = NULL; /* bzip2 compressed output file */
+#endif
+ FILE *fipo = NULL; /* Output file */
+#if DK4_ON_WINDOWS && DK4_WIN_DENY_CRT
+ HANDLE fha = INVALID_HANDLE_VALUE;
+ DWORD dwattr = (DWORD)0UL;
+#endif
+ int coi = -1; /* Compression algorithm index */
+#if DK4_CHAR_SIZE > 1
+ int fd = -1; /* File descriptor */
+#endif
+
+ $? "+ dk4stream_open_file_writer \"%!ds\"", TR_STR(filename)
+ if (NULL != filename) {
+ p1 = dk4path_get_suffix(filename, erp);
+ if (NULL != p1) { $? ". suffix \"%!ds\"", p1
+ coi = dk4str_array_index(
+ dk4strmw_co_su, p1, DK4_HAVE_CASE_INSENSITIVE_PATHNAMES
+ );
+ if (0 > coi) { coi = -1; }
+ }
+#if TRACE_DEBUG
+ else { $? ". no suffix"
+ }
+#endif
+ if (0 != dk4fopen_check(filename, 1, DK4_FOPEN_SC_IS_REGULAR, erp)) {
+ switch (coi) {
+ case 0: case 1: { $? ". gzip"
+#if DK4_HAVE_ZLIB_H && (!(DK4_ON_WINDOWS && DK4_WIN_DENY_CRT))
+#if DK4_CHAR_SIZE > 1
+ /* +++++ gzip, wchar_t */
+ $? ". gzip mit wchar_t"
+ fd = dk4fd_wc_open(
+ filename,
+ (DK4_O_WRONLY | DK4_O_BINARY | DK4_O_TRUNC | DK4_O_CREAT),
+ erp
+ );
+ if (-1 < fd) {
+ gzf = gzdopen(fd, dk4strmw_c8_mode);
+ if (NULL != gzf) {
+ back = dk4stream_open_for_gzfile_with_close(
+ gzf, DK4_STREAM_WRITE, 1024, 4096, erp
+ );
+ if (NULL == back) { $? "! failed to open stream"
+ gzclose(gzf);
+ }
+#if TRACE_DEBUG
+ else { $? ". stream opened"
+ }
+#endif
+ } else { $? "! failed to open gzf"
+ dk4error_set_simple_error_code(erp, DK4_E_OPEN_WRITE_FAILED);
+ (void)dk4fd_close(fd, NULL);
+ }
+ }
+#if TRACE_DEBUG
+ else { $? "! failed to open fd"
+ }
+#endif
+ /* ----- gzip, wchar_t */
+#else
+ /* +++++ gzip, char */
+ $? ". gzip char"
+ gzf = gzopen(filename, dk4strmw_c8_mode);
+ if (NULL != gzf) {
+ back = dk4stream_open_for_gzfile_with_close(
+ gzf, DK4_STREAM_WRITE, 1024, 4096, erp
+ );
+ if (NULL == back) { $? "! failed to open stream"
+ gzclose(gzf);
+ }
+#if TRACE_DEBUG
+ else { $? ". stream opened"
+ }
+#endif
+ } else { $? "! failed to open gzf"
+ dk4error_set_simple_error_code(erp, DK4_E_OPEN_WRITE_FAILED);
+ }
+ /* ----- gzip, char */
+#endif
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ case 2: { $? ". bzip"
+#if DK4_HAVE_BZLIB_H && (!(DK4_ON_WINDOWS && DK4_WIN_DENY_CRT))
+#if DK4_CHAR_SIZE > 1
+ /* +++++ bzip2, wchar_t */
+ $? ". bzip2 wchar_t"
+ fd = dk4fd_wc_open(
+ filename,
+ (DK4_O_WRONLY | DK4_O_BINARY | DK4_O_TRUNC | DK4_O_CREAT),
+ erp
+ );
+ if (-1 < fd) {
+ bzf = BZ2_bzdopen(fd, dk4strmw_c8_mode);
+ if (NULL != bzf) {
+ back = dk4stream_open_for_bzfile_with_close(
+ bzf, DK4_STREAM_WRITE, 1024, 4096, erp
+ );
+ if (NULL == back) { $? "! failed to open stream"
+ BZ2_bzclose(bzf);
+ }
+#if TRACE_DEBUG
+ else { $? ". stream opened"
+ }
+#endif
+ } else { $? "! failed to open bzf"
+ dk4error_set_simple_error_code(erp, DK4_E_OPEN_WRITE_FAILED);
+ (void)dk4fd_close(fd, NULL);
+ }
+ } else { $? "! failed to open fd"
+ dk4error_set_simple_error_code(erp, DK4_E_OPEN_WRITE_FAILED);
+ }
+ /* ----- bzip2, wchar_t */
+#else
+ /* +++++ bzip2, char */
+ $? ". bzip2 char"
+ bzf = BZ2_bzopen(filename, dk4strmw_c8_mode);
+ if (NULL != bzf) {
+ back = dk4stream_open_for_bzfile_with_close(
+ bzf, DK4_STREAM_WRITE, 1024, 4096, erp
+ );
+ if (NULL == back) { $? "! failed to open stream"
+ BZ2_bzclose(bzf);
+ }
+#if TRACE_DEBUG
+ else { $? ". stream opened"
+ }
+#endif
+ } else { $? "! failed to open bzf"
+ dk4error_set_simple_error_code(erp, DK4_E_OPEN_WRITE_FAILED);
+ }
+ /* ----- bzip2, char */
+#endif
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ } break;
+ default: { $? ". plain file"
+#if DK4_ON_WINDOWS && DK4_WIN_DENY_CRT
+ $? ". Windows without CRT"
+ dwattr = FILE_ATTRIBUTE_NORMAL;
+ dwattr |= FILE_FLAG_BACKUP_SEMANTICS;
+ dwattr |= FILE_FLAG_SEQUENTIAL_SCAN;
+#if DK4_CHAR_SIZE > 1
+ fha = CreateFileW(
+ filename, GENERIC_WRITE, 0, NULL,
+ CREATE_ALWAYS, dwattr, NULL
+ );
+#else
+ fha = CreateFileA(
+ filename, GENERIC_WRITE, 0, NULL,
+ CREATE_ALWAYS, dwattr, NULL
+ );
+#endif
+ if (INVALID_HANDLE_VALUE != fha) {
+ back = dk4stream_open_for_windows_handle_with_close(
+ fha, DK4_STREAM_WRITE, 1024, 4096, erp
+ );
+ if (NULL == back) { $? "! failed to open stream"
+ (void)CloseHandle(fha);
+ }
+#if TRACE_DEBUG
+ else { $? ". stream opened"
+ }
+#endif
+ } else { $? "! CreataeFile failed"
+ dk4error_set_simple_error_code(erp, DK4_E_OPEN_WRITE_FAILED);
+ }
+#else
+ $? ". Windows with CRT allowed"
+ fipo = dk4fopen(
+ filename, dk4strmw_dk_mode, DK4_FOPEN_SC_IS_REGULAR, erp
+ );
+ if (NULL != fipo) {
+ back = dk4stream_open_for_file_with_close(
+ fipo, DK4_STREAM_WRITE, 1024, 4096, erp
+ );
+ if (NULL == back) { $? "! failed to open stream"
+ (void)fclose(fipo);
+ }
+#if TRACE_DEBUG
+ else { $? ". stream opened"
+ }
+#endif
+ } else { $? "! fipo"
+ }
+#endif
+ } break;
+ }
+ } else { $? "! file check failed"
+ }
+ } else { $? "! no filename"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4stream_open_file_writer %d", TR_IPTR(back)
+ return back;
+}
+
+
diff --git a/support/dktools/dk4strmw.h b/support/dktools/dk4strmw.h
new file mode 100644
index 0000000000..6c31d8e218
--- /dev/null
+++ b/support/dktools/dk4strmw.h
@@ -0,0 +1,105 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4strmw.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4STRMW_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4STRMW_H_INCLUDED 1
+
+
+#line 9 "dk4strmw.ctr"
+
+/** @file
+ Open a stream to write a file.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4STRM_H_INCLUDED
+#include "dk4strm.h"
+#endif
+
+#ifndef DK4STRMF_H_INCLUDED
+#include "dk4strmf.h"
+#endif
+
+#ifndef DK4STRMG_H_INCLUDED
+#include "dk4strmg.h"
+#endif
+
+#ifndef DK4STRMB_H_INCLUDED
+#include "dk4strmb.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open a stream to write a file.
+ CRT on Windows: Optional, disabling CRT reduces functionality
+ by disabling the gzip and bzip2 compression libraries.
+ @param filename File name of file to write.
+ @param erp Error report, may be NULL.
+ @return Pointer to stream on success, NULL on error.
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if filename is NULL,
+ - DK4_E_MATH_OVERFLOW<br>
+ if ibs or obs is too large,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if allocation of input or output buffer failed.
+*/
+
+dk4_stream_t *
+dk4stream_open_file_writer(const dkChar *filename, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4strw.c b/support/dktools/dk4strw.c
new file mode 100644
index 0000000000..e4fc7e58f3
--- /dev/null
+++ b/support/dktools/dk4strw.c
@@ -0,0 +1,1151 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4strw.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4strw.c The dk4strw module.
+*/
+
+
+#line 413 "dk4strw.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS && (DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT)
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+
+#include "dk4strw.h"
+#include "dk4mem.h"
+#include "dk4numco.h"
+
+#if DK4_HAVE_WCTYPE_H
+#ifndef WCTYPE_H_INCLUDED
+#include <wctype.h>
+#define WCTYPE_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef DK4MEMRS_H_INCLUDED
+#include "dk4memrs.h"
+#endif
+
+
+
+
+
+#line 442 "dk4strw.ctr"
+
+
+
+/** Constant strings used in the module.
+*/
+static const wchar_t * const dk4strw_modkw[] = {
+/* 0 */
+L" \t\r\n",
+
+NULL
+
+
+#line 454 "dk4strw.ctr"
+};
+
+
+
+/** First index of a keyword indicating true in the
+ dk4str8_boolkw array below.
+*/
+#define DK4STRW_FIRST_TRUE 5
+
+/** Keywords for boolean values.
+*/
+static const wchar_t * const dk4strw_boolkw[] = {
+/* 0 */
+L"-",
+
+/* 1 */
+L"0",
+
+/* 2 */
+L"n$o",
+
+/* 3 */
+L"of$f",
+
+/* 4 */
+L"f$alse",
+
+/* 5 */
+L"+",
+
+/* 6 */
+L"1",
+
+/* 7 */
+L"y$es",
+
+/* 8 */
+L"on",
+
+/* 9 */
+L"t$rue",
+
+/* 10 */
+L"ok",
+
+NULL
+
+
+#line 485 "dk4strw.ctr"
+};
+
+
+
+/** Number of significant digits when printing a double.
+*/
+static const int dk4strw_dbl_digits = DK4_DBL_DIGITS;
+
+
+
+void
+dk4strw_cpy_to_left(wchar_t *dst, const wchar_t *src)
+{
+ register wchar_t *dptr;
+ register const wchar_t *sptr;
+ if ((NULL != dst) && (NULL != src)) {
+ dptr = dst; sptr = src;
+ while(L'\0' != *sptr) { *(dptr++) = *(sptr++); }
+ *dptr = L'\0';
+ }
+}
+
+
+
+size_t
+dk4strw_len(const wchar_t *src)
+{
+ if (NULL == src) { return 0; }
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ return ((size_t)lstrlenW(src));
+#else
+ return (wcslen(src));
+#endif
+ /* --- Windows */
+#else
+ /* +++ Windows */
+#if DK4_HAVE_WCSLEN
+ return (wcslen(src));
+#else
+ size_t back = 0;
+ while(L'\0' != *src) { src++; back++; }
+ return back;
+#endif
+ /* --- Windows */
+#endif
+}
+
+
+
+wchar_t *
+dk4strw_chr(const wchar_t *s, wchar_t c)
+{
+ if (NULL == s) { return NULL; }
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_DENY_CRT
+ {
+ wchar_t *back = NULL;
+ while ((L'\0' != *s) && (NULL == back)) {
+ if (c == *s) {
+ back = (wchar_t *)s;
+ }
+ s++;
+ }
+ return back;
+ }
+#else
+ return (wcschr(s, c));
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+#if DK4_HAVE_WCSCHR
+ return (wcschr(s, c));
+#else
+ {
+ wchar_t *back = NULL;
+ while ((L'\0' != *s) && (NULL == back)) {
+ if (c == *s) {
+ back = (wchar_t *)s;
+ }
+ s++;
+ }
+ return back;
+ }
+#endif
+ /* --- non-Windows */
+#endif
+}
+
+
+
+wchar_t *
+dk4strw_rchr(const wchar_t *s, wchar_t c)
+{
+ if (NULL == s) { return NULL; }
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_DENY_CRT
+ {
+ wchar_t *back = NULL;
+ while (L'\0' != *s) {
+ if (c == *s) {
+ back = (wchar_t *)s;
+ }
+ s++;
+ }
+ return back;
+ }
+#else
+ return (wcsrchr(s, c));
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+#if DK4_HAVE_WCSRCHR
+ return (wcsrchr(s, c));
+#else
+ {
+ wchar_t *back = NULL;
+ while (L'\0' != *s) {
+ if (c == *s) {
+ back = (wchar_t *)s;
+ }
+ s++;
+ }
+ return back;
+ }
+#endif
+ /* --- non-Windows */
+#endif
+}
+
+
+
+wchar_t
+dk4strw_toupper(wchar_t c)
+{
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_DENY_CRT
+ if ((L'a' <= c) && (L'z' >= c)) {
+ return (L'A' + (c - L'a'));
+ } else {
+ return c;
+ }
+#else
+ return (towupper(c));
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+ return (towupper(c));
+ /* --- non-Windows */
+#endif
+}
+
+
+
+wchar_t
+dk4strw_tolower(wchar_t c)
+{
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_DENY_CRT
+ if ((L'A' <= c) && (L'Z' >= c)) {
+ return (L'a' + (c - L'A'));
+ } else {
+ return c;
+ }
+#else
+ return (towlower(c));
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+ return (towlower(c));
+ /* --- non-Windows */
+#endif
+}
+
+
+
+int
+dk4strw_cpy_s(wchar_t *dst, size_t sz, const wchar_t *src, dk4_er_t *erp)
+{
+ int back = 0;
+ size_t sl;
+ if ((NULL != dst) && (0 < sz)) {
+ *dst = L'\0';
+ if (NULL != src) {
+ sl = dk4strw_len(src);
+ if (sz > sl) {
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ (void)lstrcpyW(dst, (wchar_t *)src);
+#else
+#pragma warning (disable:4996)
+ (void)wcscpy(dst, src);
+#pragma warning (default:4996)
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+#if DK4_HAVE_WCSCPY
+ (void)wcscpy(dst, src);
+#else
+ size_t nbytes;
+ dk4_er_t er;
+ dk4error_init(&er);
+ if ((SIZE_MAX - 1) < sl) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ if ((SIZE_MAX / sizeof(wchar_t)) < (sl + 1)) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ nbytes = sizeof(wchar_t) * (sl + 1);
+ }
+ }
+ if (DK4_E_NONE == er.ec) {
+ DK4_MEMCPY(dst, src, nbytes);
+ } else {
+ dk4strw_cpy_to_left(dst, src);
+ }
+#endif
+ /* --- non-Windows */
+#endif
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4strw_cat_s(wchar_t *dst, size_t sz, const wchar_t *src, dk4_er_t *erp)
+{
+ size_t la; /* Size of string in destination buffer */
+ size_t lb; /* Source string size */
+ int back = 0;
+ if ((NULL != dst) && (0 < sz) && (NULL != src)) {
+ la = dk4strw_len(dst);
+ lb = dk4strw_len(src);
+ if (sz > (la + lb)) {
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ (void)lstrcatW(dst, src);
+#else
+#pragma warning (disable:4996)
+ (void)wcscat(dst, src);
+#pragma warning (default:4996)
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+#if DK4_HAVE_WCSCAT
+ (void)wcscat(dst, src);
+#else
+ size_t nb;
+ dk4_er_t er;
+ dk4error_init(&er);
+ if ((SIZE_MAX - 1) < lb) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ if ((SIZE_MAX / sizeof(wchar_t)) < (lb + 1)) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ nb = sizeof(wchar_t) * (lb + 1);
+ }
+ }
+ if (DK4_E_NONE == er.ec) {
+ DK4_MEMCPY(&(dst[la]), src, nb);
+ } else {
+ dk4strw_cpy_to_left(&(dst[la]), src);
+ }
+#endif
+ /* --- non-Windows */
+#endif
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+
+int
+dk4strw_cmp(const wchar_t *s1, const wchar_t *s2)
+{
+ int back = 0;
+ if (NULL != s1) {
+ if (NULL != s2) {
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ back = lstrcmpW(s1, s2);
+ if (0 > back) back = -1;
+ if (0 < back) back = 1;
+#else
+ back = wcscmp(s1, s2);
+ if (0 > back) back = -1;
+ if (0 < back) back = 1;
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+#if DK4_HAVE_WCSCMP
+ back = wcscmp(s1, s2);
+ if (0 > back) back = -1;
+ if (0 < back) back = 1;
+#else
+#if DK4_HAVE__WCSCMP
+ back = _wcscmp(s1, s2);
+ if (0 > back) back = -1;
+ if (0 < back) back = 1;
+#else
+ do {
+ if (*s1 > *s2) {
+ back = 1;
+ } else {
+ if (*s1 < *s2) {
+ back = -1;
+ } else {
+ if (L'\0' != *s1) {
+ s1++; s2++;
+ }
+ }
+ }
+ } while((0 == back) && (L'\0' != *s1));
+#endif
+#endif
+ /* --- non-Windows */
+#endif
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != s2) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4strw_ncmp(const wchar_t *s1, const wchar_t *s2, size_t n)
+{
+ int back = 0;
+ if (NULL != s1) {
+ if (NULL != s2) {
+#if (DK4_ON_WINDOWS && (DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT) ) \
+|| (!(DK4_HAVE_WCSNCMP)) || (!(DK4_HAVE__WCSNCMP))
+ while ((0 < n--) && (0 == back)) {
+ if (L'\0' == *s1) {
+ if (L'\0' == *s2) {
+ n = 0;
+ } else {
+ back = -1;
+ }
+ } else {
+ if (L'\0' == *s2) {
+ back = 1;
+ } else {
+ if (*s1 < *s2) {
+ back = -1;
+ } else {
+ if (*s1 > *s2) {
+ back = 1;
+ } else {
+ s1++; s2++;
+ }
+ }
+ }
+ }
+ }
+#else
+#if DK4_HAVE_WCSNCMP
+ back = wcsncmp(s1, s2, n);
+#else
+ back = _wcsncmp(s1, s2, n);
+#endif
+ if (-1 > back) back = -1;
+ if ( 1 < back) back = 1;
+#endif
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != s2) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4strw_casecmp(const wchar_t *s1, const wchar_t *s2)
+{
+ int back = 0;
+ if (NULL != s1) {
+ if (NULL != s2) {
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ back = lstrcmpiW(s1, s2);
+ if (0 > back) back = -1;
+ if (0 < back) back = 1;
+#else
+ back =_wcsicmp(s1, s2);
+ if (0 > back) back = -1;
+ if (0 < back) back = 1;
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+#if DK4_HAVE_WCSCASECMP
+ back = wcscasecmp(s1, s2);
+ if (0 > back) back = -1;
+ if (0 < back) back = 1;
+#else
+#if DK4_HAVE__WCSCASECMP
+ back = _wcscasecmp(s1, s2);
+ if (0 > back) back = -1;
+ if (0 < back) back = 1;
+#else
+#if DK4_HAVE__WCSICMP
+ back = _wcsicmp(s1, s2);
+ if (0 > back) back = -1;
+ if (0 < back) back = 1;
+#else
+#if DK4_HAVE_WCSICMP
+ back = wcsicmp(s1, s2);
+ if (0 > back) back = -1;
+ if (0 < back) back = 1;
+#else
+ wchar_t c1;
+ wchar_t c2;
+ c1 = dk4strw_toupper(*s1);
+ c2 = dk4strw_toupper(*s2);
+ do {
+ if (c1 > c2) {
+ back = 1;
+ } else {
+ if (c1 < c2) {
+ back = -1;
+ } else {
+ if (L'\0' != *s1) {
+ s1++; s2++;
+ }
+ }
+ }
+ } while((0 == back) && (L'\0' != *s1));
+#endif
+#endif
+#endif
+#endif
+ /* --- non-Windows */
+#endif
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != s2) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+#if (defined(_WIN32) && DK4_USE_WINDOWS_LOCAL_ALLOC) \
+ || (DK4_HAVE_MALLOC && DK4_HAVE_FREE)
+
+wchar_t *
+dk4strw_dup(const wchar_t *src, dk4_er_t *erp)
+{
+ wchar_t *back = NULL;
+ size_t lgt;
+ if (NULL != src) {
+ lgt = dk4strw_len(src);
+ if (SIZE_MAX > lgt) {
+ back = dk4mem_new(wchar_t,(lgt+1),erp);
+ if (NULL != back) {
+ (void)dk4strw_cpy_s(back, (lgt+1), src, erp);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+#endif
+/* if (defined(_WIN32) ... */
+
+
+
+#if !DK4_HAVE_WCSCHR
+/** Find first occurance of character in string.
+ @param src String to search for character.
+ @param c Character to find.
+ @return Pointer to first occurance on success, NULL on error.
+*/
+static
+const wchar_t *
+dk4strw_i_wcschr(const wchar_t *src, wchar_t c)
+{
+ const wchar_t *back = NULL;
+ while ((L'\0' != *src) && (NULL == back)) {
+ if (*src == c) {
+ back = src;
+ } else {
+ src++;
+ }
+ }
+ return back;
+}
+#endif
+
+
+
+wchar_t *
+dk4strw_start(const wchar_t *src, const wchar_t *delim)
+{
+ wchar_t *back = NULL;
+ if (NULL != src) {
+ if (NULL == delim) { delim = dk4strw_modkw[0]; }
+ while((L'\0' != *src) && (NULL == back)) {
+ if (NULL != dk4strw_chr(delim, *src)) {
+ src++;
+ } else {
+ back = (wchar_t *)src;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Internal function for next token search.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param src String containing tokens, must be set to
+ the start of a token.
+ @param delim Delimiter set.
+ @return Pointer to next token on success, NULL on error.
+*/
+static
+wchar_t *
+dk4strw_i_next(wchar_t *src, const wchar_t *delim)
+{
+ wchar_t *back = NULL;
+ if (NULL != src) {
+ if (NULL == delim) { delim = dk4strw_modkw[0]; }
+ while ((L'\0' != *src) && (NULL == back)) {
+ if (NULL != dk4strw_chr(delim, *src)) {
+ back = src;
+ } else {
+ src++;
+ }
+ }
+ if (NULL != back) {
+ *(back++) = L'\0';
+ back = dk4strw_start(back, delim);
+ }
+ }
+ return back;
+}
+
+
+
+wchar_t *
+dk4strw_next(wchar_t *src, const wchar_t *delim)
+{
+ wchar_t *back = NULL;
+ if (NULL != src) {
+ back = dk4strw_start(src, delim);
+ if (NULL != back) {
+ back = dk4strw_i_next(back, delim);
+ }
+ }
+ return back;
+}
+
+
+
+wchar_t *
+dk4strw_sep(wchar_t **stringp, const wchar_t *delim)
+{
+ wchar_t *back = NULL;
+
+
+#line 1101 "dk4strw.ctr"
+ if (NULL != stringp) {
+ if (NULL != *stringp) {
+ if (NULL == delim) { delim = dk4strw_modkw[0]; }
+ back = dk4strw_start(*stringp, delim);
+ if (NULL != back) {
+ *stringp = dk4strw_next(back, delim);
+ } else {
+ *stringp = NULL;
+ }
+ }
+ }
+
+#line 1112 "dk4strw.ctr"
+ return back;
+}
+
+
+
+size_t
+dk4strw_tokenize(
+ wchar_t **dpp, size_t szdpp, wchar_t *src, const wchar_t *delim, dk4_er_t *erp
+)
+{
+ wchar_t *context;
+ wchar_t *token;
+ size_t back = 0;
+ if ((NULL != dpp) && (0 < szdpp) && (NULL != src)) {
+ if (NULL == delim) { delim = dk4strw_modkw[0]; }
+ context = src;
+ while (NULL != (token = dk4strw_sep(&context, delim))) {
+ if (back < szdpp) {
+ dpp[back] = token;
+ }
+ back++;
+ }
+ if (back >= szdpp) { /* Too many tokens found */
+ dk4error_set_elsize_nelem(
+ erp, DK4_E_BUFFER_TOO_SMALL, sizeof(DK4_PCHAR), back
+ );
+ back = 0;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+void
+dk4strw_normalize(wchar_t *src, const wchar_t *delim)
+{
+
+ wchar_t *p1; /* Pointer to traverse text. */
+ wchar_t *p2; /* Start of next token. */
+ int cc; /* Flag: Can continue. */
+
+ if (NULL != src) {
+ if (NULL == delim) { delim = dk4strw_modkw[0]; }
+ p1 = src;
+ cc = 0;
+ if (L'\0' != *p1) {
+ if (NULL != dk4strw_chr(delim, *p1)) {
+ p2 = dk4strw_start(p1, delim);
+ if (NULL != p2) {
+ dk4strw_cpy_to_left(p1, p2);
+ cc = 1;
+ } else {
+ *p1 = L'\0';
+ }
+ } else {
+ cc = 1;
+ }
+ }
+ while (0 != cc) {
+ if (L'\0' == *p1) {
+ cc = 0;
+ } else {
+ if (NULL != dk4strw_chr(delim, *p1)) {
+ *p1 = *delim;
+ if (L'\0' == p1[1]) {
+ *p1 = L'\0';
+ cc = 0;
+ } else {
+ if (NULL != dk4strw_chr(delim, p1[1])) {
+ p2 = dk4strw_start(p1, delim);
+ if (NULL != p2) {
+ dk4strw_cpy_to_left(++p1, p2);
+ } else {
+ *p1 = L'\0';
+ cc = 0;
+ }
+ } else {
+ p1++;
+ }
+ }
+ } else {
+ p1++;
+ }
+ }
+ }
+ }
+}
+
+
+
+int
+dk4strw_array_index(const wchar_t * const *arr, const wchar_t *str, int cs)
+{
+ int back = -1;
+ int cand = 0;
+ while ((NULL != *arr) && (-1 == back)) {
+ if (0 != cs) {
+ if (0 == dk4strw_cmp(*arr, str)) { back = cand; }
+ } else {
+ if (0 == dk4strw_casecmp(*arr, str)) { back = cand; }
+ }
+ arr++; cand++;
+ }
+ return back;
+}
+
+
+
+
+int
+dk4strw_is_abbr(const wchar_t *str,const wchar_t *pattern,wchar_t spec,int cs)
+{
+ const wchar_t *lptr = NULL; /* Pointer to traverse string */
+ const wchar_t *pptr = NULL; /* Pointer to traverse pattern */
+ int back = 0; /* Function result */
+ int fspec = 0; /* Flag: spec was found */
+ int cc = 1; /* Flag: Can continue */
+ wchar_t cl;
+ wchar_t cp;
+
+
+#line 1235 "dk4strw.ctr"
+ if ((NULL != str) && (NULL != pattern)) {
+ lptr = str; pptr = pattern;
+ while (0 != cc) {
+ if ((0 == fspec) && (*pptr == spec)) {
+ fspec = 1;
+ pptr++;
+ } else {
+ if (L'\0' != *lptr) {
+ cl = *lptr; cp = *pptr;
+ if (0 == cs) {
+ cl = dk4strw_toupper(cl);
+ cp = dk4strw_toupper(cp);
+ }
+ if (cl == cp) {
+ lptr++;
+ pptr++;
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = 0;
+ if ((L'\0' == *pptr) || (0 != fspec)) { back = 1; }
+ }
+ }
+ }
+ }
+
+
+#line 1262 "dk4strw.ctr"
+ return back;
+}
+
+
+
+int
+dk4strw_abbr_index(
+ const wchar_t * const *arr,
+ wchar_t spec,
+ const wchar_t *str,
+ int cs
+)
+{
+ int back = -1;
+ int cand = 0; /* Traverse array */
+
+
+#line 1278 "dk4strw.ctr"
+ if ((NULL != arr) && (NULL != str)) {
+ while ((NULL != *arr) && (-1 == back)) {
+ if (0 != dk4strw_is_abbr(str, *arr, spec, cs)) {
+ back = cand;
+ }
+ arr++; cand++;
+ }
+ }
+
+
+#line 1287 "dk4strw.ctr"
+ return back;
+}
+
+
+
+int
+dk4strw_is_bool(const wchar_t *str)
+{
+ int back = 0;
+ if (NULL != str) {
+ if (-1 < dk4strw_abbr_index(dk4strw_boolkw, L'$', str, 0)) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4strw_is_on(const wchar_t *str)
+{
+ int back = 0;
+
+
+#line 1311 "dk4strw.ctr"
+ if (NULL != str) {
+ back = dk4strw_abbr_index(dk4strw_boolkw, L'$', str, 0);
+ if (-1 < back) {
+ if (DK4STRW_FIRST_TRUE <= back) {
+ back = 1;
+
+#line 1316 "dk4strw.ctr"
+ } else {
+ back = 0;
+
+#line 1318 "dk4strw.ctr"
+ }
+ } else {
+ back = 0;
+
+#line 1321 "dk4strw.ctr"
+ }
+ }
+
+
+#line 1324 "dk4strw.ctr"
+ return back;
+}
+
+
+
+int
+dk4strw_pathcmp(const wchar_t *s1, const wchar_t *s2)
+{
+#if DK4_HAVE_CASE_INSENSITIVE_PATHNAMES
+ return (dk4strw_casecmp(s1, s2));
+#else
+ return (dk4strw_cmp(s1, s2));
+#endif
+}
+
+
+
+void
+dk4strw_rtwh(wchar_t *str, const wchar_t *whsp)
+{
+ wchar_t *ptr = NULL; /* Pointer to first whitespace */
+
+ if (NULL == whsp) { whsp = dk4strw_modkw[0]; }
+ if (NULL != str) {
+ while (L'\0' != *str) {
+ if (NULL != dk4strw_chr(whsp, *str)) {
+ if (NULL == ptr) { ptr = str; }
+ } else {
+ ptr = NULL;
+ }
+ str++;
+ }
+ if (NULL != ptr) { *ptr = L'\0'; }
+ }
+}
+
+
+
+void
+dk4strw_delnl(wchar_t *lptr)
+{
+ if (NULL != lptr) {
+ while (L'\0' != *lptr) {
+ if (L'\n' == *lptr) {
+ *lptr = L'\0';
+ } else {
+ if (L'\r' == *lptr) {
+ if (L'\n' == lptr[1]) {
+ *lptr = L'\0';
+ } else {
+ if (L'\0' == lptr[1]) {
+ *lptr = L'\0';
+ } else {
+ lptr++;
+ }
+ }
+ } else {
+ lptr++;
+ }
+ }
+ }
+ }
+}
+
+
+
+const wchar_t *
+dk4strw_skip(const wchar_t *line, size_t skip)
+{
+ const wchar_t *back = NULL;
+ size_t words = 0; /* Number of words already found */
+ int lwt = 0; /* Flag: Last char was text */
+
+ if (NULL != line) {
+ if (0 < skip) {
+ while ((NULL == back) && (L'\0' != *line)) {
+ if (L' ' == *line) {
+ lwt = 0;
+ } else {
+ if (L'\t' == *line) {
+ lwt = 0;
+ } else {
+ if (L'\n' == *line) {
+ lwt = 0;
+ } else {
+ if (L'\r' == *line) {
+ lwt = 0;
+ } else {
+ if (0 == lwt) {
+ if (++words > skip) {
+ back = line;
+ }
+ }
+ lwt = 1;
+ }
+ }
+ }
+ }
+ line++;
+ }
+ } else {
+ back = dk4strw_start(line, NULL);
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4strw_buffer_sanitize(wchar_t *str, size_t sz)
+{
+ size_t i;
+ int back = 0;
+
+ if (NULL != str) {
+ if (0 < sz) {
+ if ((SIZE_MAX / sizeof(wchar_t)) >= sz) {
+ back = dk4mem_reset_secure(str, (sz * sizeof(wchar_t)), NULL);
+ } else {
+ for (i = 0; i < sz; i++) { str[i] = L'\0'; }
+ back = 1;
+ for (i = 0; i < sz; i++) { if (L'\0' != str[i]) { back = 0; } }
+ }
+ } else {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4strw_sanitize(wchar_t *str)
+{
+ int back = 0;
+ if (NULL != str) {
+ back = dk4strw_buffer_sanitize(str, dk4strw_len(str));
+ }
+ return back;
+}
+
+
+
+int
+dk4strw_free_sanitized(wchar_t *str)
+{
+ int back = 0;
+ if (NULL != str) {
+ back = dk4strw_sanitize(str);
+ dk4mem_free(str);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4strw.ctr b/support/dktools/dk4strw.ctr
new file mode 100644
index 0000000000..8e0b560ab5
--- /dev/null
+++ b/support/dktools/dk4strw.ctr
@@ -0,0 +1,1480 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Additional string functions for
+ wchar_t strings.
+
+ Although some of the functions in this module duplicate
+ functionality from the C runtime library on Windows, you should use
+ the functions from this module.
+ With DK4DK4_WIN_AVOID_CRT or DK4_WIN_DENY_CRT defined to non-zero
+ these functions call Windows API functions like
+ lstrcmpW() ... instead of CRT functions.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+
+#if DK4_HAVE_WCHAR_H
+#ifndef WCHAR_H_INCLUDED
+#include <wchar.h>
+#define WCHAR_H_INCLUDED 1
+#endif
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Copy string, check destination buffer size.
+
+ CRT on Windows: Optional.
+ @param dst Destination buffer address.
+ @param sz Destination buffer size.
+ @param src Source string.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dst or src is NULL or sz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the dst buffer is too small.
+*/
+int
+dk4strw_cpy_s(wchar_t *dst, size_t sz, const wchar_t *src, dk4_er_t *erp);
+
+/** Concatenate strings, check destination buffer size.
+
+ CRT on Windows: Optional.
+ @param dst Destination buffer address.
+ @param sz Destination buffer size.
+ @param src Source string.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dst or src is NULL or sz is 0,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in size calculation,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the concatenated string doest not fit into the buffer.
+*/
+int
+dk4strw_cat_s(wchar_t *dst, size_t sz, const wchar_t *src, dk4_er_t *erp);
+
+/** Copy characters within a string from right to left.
+ This copy operation is intended for moving characters within
+ one string from right to left, making the string shorter
+ as is. This function does not check buffer size or report
+ any error.
+ For normal string copy operations, use the dk4strw_cpy_s()
+ function instead.
+
+ CRT on Windows: Not used.
+ @param dst Destination buffer address.
+ @param src Source string.
+*/
+void
+dk4strw_cpy_to_left(wchar_t *dst, const wchar_t *src);
+
+/** Find string length.
+
+ CRT on Windows: Optional, disabling CRT reduces functionality
+ to strings with length fitting to int.
+ @param src Source string.
+ @return String length.
+*/
+size_t
+dk4strw_len(const wchar_t *src);
+
+/** Compare two strings.
+
+ CRT on Windows: Optional.
+ @param s1 Left string, may be NULL.
+ @param s2 Right string, may be NULL.
+ @return 1 if s1>s2, 0 if s1==s2, -1 if s1<s2.
+*/
+int
+dk4strw_cmp(const wchar_t *s1, const wchar_t *s2);
+
+/** Compare two strings.
+
+ CRT on Windows: Optional.
+ @param s1 Left string, may be NULL.
+ @param s2 Right string, may be NULL.
+ @param n Maximum number of characters to compare.
+ @return 1 if s1>s2, 0 if s1==s2, -1 if s1<s2.
+*/
+int
+dk4strw_ncmp(const wchar_t *s1, const wchar_t *s2, size_t n);
+
+/** Compare two strings, case-insensitive comparison.
+
+ CRT on Windows: Optional, disabling CRT probably degrades performance.
+ @param s1 Left string, may be NULL.
+ @param s2 Right string, may be NULL.
+ @return 1 if s1>s2, 0 if s1==s2, -1 if s1<s2.
+*/
+int
+dk4strw_casecmp(const wchar_t *s1, const wchar_t *s2);
+
+/** Compare two file path names.
+
+ CRT on Windows: Optional.
+ @param s1 Left string, may be NULL.
+ @param s2 Right string, may be NULL.
+ @return 1 if s1>s2, 0 if s1==s2, -1 if s1<s2.
+*/
+int
+dk4strw_pathcmp(const wchar_t *s1, const wchar_t *s2);
+
+/** Find first occurance of character c in string s.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param s String to search for c.
+ @param c Character to find.
+ @return Pointer to first occurance if found, NULL otherwise.
+*/
+wchar_t *
+dk4strw_chr(const wchar_t *s, wchar_t c);
+
+/** Find last occurance of character c in string s.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param s String to search for c.
+ @param c Character to find.
+ @return Pointer to last occurance if found, NULL otherwise.
+*/
+wchar_t *
+dk4strw_rchr(const wchar_t *s, wchar_t c);
+
+/** Convert character to upper-case character.
+
+ CRT on windows: Optional, disabling CRT degrades performance.
+ @param c Character to convert.
+ @return Conversion result.
+*/
+wchar_t
+dk4strw_toupper(wchar_t c);
+
+/** Convert character to lower-case character.
+
+ CRT on windows: Optional, disabling CRT degrades performance.
+ @param c Character to convert.
+ @return Conversion result.
+*/
+wchar_t
+dk4strw_tolower(wchar_t c);
+
+/** Retrieve first token from *stringp.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param stringp Adress of string pointer.
+ @param delim String containing the delimiter set,
+ my be NULL to use the default delimiter
+ set (space, tabulator, carriage return and newline).
+ @return Pointer to first token on success, NULL if no (further)
+ token found.
+*/
+wchar_t *
+dk4strw_sep(wchar_t **stringp, const wchar_t *delim);
+
+/** Find first token in string.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param src String to search for tokens.
+ @param delim String containing the delimiter characters,
+ may be NULL to use the default delimiter set.
+ @return Pointer to first token if found, NULL otherwise.
+*/
+wchar_t *
+dk4strw_start(const wchar_t *src, const wchar_t *delim);
+
+/** Cut string after first token, find start of second token in string.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param src String to search for tokens,
+ normally the result of dk4strw_start() or a
+ previous dk4strw_next() call.
+ @param delim String containing the delimiter characters,
+ may be NULL to use the default delimiter set.
+ @return Pointer to second token if found, NULL otherwise.
+*/
+wchar_t *
+dk4strw_next(wchar_t *src, const wchar_t *delim);
+
+/** Split a string into tokens.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param dpp Pointer to string pointer array.
+ @param szdpp Size of destination string pointer array.
+ @param src Source string to process.
+ @param delim String containing delimiter characters,
+ may be NULL to use the default delimiter set.
+ @param erp Error report, may be NULL.
+ @return Number of tokens found on success, 0 if no token
+ found or on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ for invalid function arguments,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ with dt.mem.nelem set to the number of tokens in string if the dpp
+ array is too short.
+*/
+size_t
+dk4strw_tokenize(
+ wchar_t **dpp, size_t szdpp, wchar_t *src, const wchar_t *delim, dk4_er_t *erp
+);
+
+/** Normalize a string (remove leading and trailing delimiters,
+ replace delimiter sequences by just one delimiter).
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param src Buffer containing the string to normalize.
+ @param delim String containing delimiter characters,
+ may be NULL to use the default delimiter set.
+*/
+void
+dk4strw_normalize(wchar_t *src, const wchar_t *delim);
+
+/** Find index of a string in an array of strings.
+
+ CRT on Windows: Optional.
+ @param arr Array of strings.
+ @param str String to find in array.
+ @param cs Flag: Case-sensitive search (0=no, other=yes).
+ @return Non-negative index value on success, -1 on error.
+*/
+int
+dk4strw_array_index(const wchar_t * const *arr, const wchar_t *str, int cs);
+
+/** Find index of a string in an array of strings.
+
+ CRT on windows: Optional, disabling CRT degrades performance
+ for case-insensitive comparisons.
+ @param arr Array of strings allowing abbreviation.
+ @param spec Special character indicating start of optional text.
+ @param str String to find in array.
+ @param cs Flag: Case-sensitive search (0=no, other=yes).
+ @return Non-negative index value on success, -1 on error.
+*/
+int
+dk4strw_abbr_index(
+ const wchar_t * const *arr,
+ wchar_t spec,
+ const wchar_t *str,
+ int cs
+);
+
+/** Check whether a text matches a pattern, the text may be abbreviated.
+
+ CRT on windows: Optional, disabling CRT degrades performance
+ for case-insensitive comparisons.
+ @param str Text to check.
+ @param pattern Pattern for comparison.
+ @param spec Special character marking the abbreviation in the
+ pattern.
+ @param cs Flag: Case sensitive (1) or not (0).
+ @return 1 for a match, 0 otherwise.
+*/
+int
+dk4strw_is_abbr(const wchar_t *str,const wchar_t *pattern,wchar_t spec,int cs);
+
+/** Check whether a string represents a boolean value.
+
+ CRT on windows: Optional, disabling CRT degrades performance.
+ @param str String to check.
+ @return 1 if str represents a boolean value, 0 otherwise.
+*/
+int
+dk4strw_is_bool(const wchar_t *str);
+
+/** Check whether a string represents the boolean value TRUE.
+
+ CRT on windows: Optional, disabling CRT degrades performance.
+ @param str String to check.
+ @return 1 if str represents the boolean value TRUE, 0 otherwise.
+*/
+int
+dk4strw_is_on(const wchar_t *str);
+
+#if (defined(_WIN32) && DK4_USE_WINDOWS_LOCAL_ALLOC) \
+ || (DK4_HAVE_MALLOC && DK4_HAVE_FREE)
+
+/** Duplicate string in dynamically allocated memory.
+
+ CRT on Windows: Optional, disabling CRT reduces functionality
+ to strings with length fitting to int and overall size in
+ bytes - including finalizer - fitting into a DWORD.
+ @param src String to duplicate.
+ @param erp Error report, may be NULL.
+ @return Pointer to string in new memory on succes, NULL on error.
+ Use dk4mem_free() to release the memory after usage.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src is a NULL pointer,
+ - DK4_E_MATH_OVERFLOW<br>
+ on mathematical overflow in size calculation,
+ - DK4_E_MEMORY<br>
+ if no memory is available.
+*/
+wchar_t *
+dk4strw_dup(const wchar_t *src, dk4_er_t *erp);
+
+#endif
+/* if (defined(_WIN32) ... */
+
+
+/** Remove trailing white spaces.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param str String to remove white spaces from.
+ @param whsp White spaces set.
+*/
+void
+dk4strw_rtwh(wchar_t *str, const wchar_t *whsp);
+
+/** Remove trailing newline from line.
+ @param lptr Line pointer.
+*/
+void
+dk4strw_delnl(wchar_t *lptr);
+
+/** Skip the first text words in a line, return pointer to start
+ of next word.
+ @param line Line to process.
+ @param skip Number of words to skip.
+ @return Pointer to next word on success, NULL on error.
+*/
+const wchar_t *
+dk4strw_skip(const wchar_t *line, size_t skip);
+
+/** Sanitize string (overwrite using 0).
+ @param str Address of string to sanitize.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4strw_sanitize(wchar_t *str);
+
+/** Sanitize string buffer (overwrite using 0 bytes).
+ @param str Address of string buffer.
+ @param sz Size of string buffer (number of wchar_t).
+ @return 1 on success, 0 on error.
+*/
+int
+dk4strw_buffer_sanitize(wchar_t *str, size_t sz);
+
+/** Sanitize dynamically allocated memory and release it.
+ @param str Address of string to sanitize and release.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4strw_free_sanitized(wchar_t *str);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/** Sanitize string and release it, set pointer to NULL.
+ @param p Pointer to string to release.
+*/
+#define dk4strw_release_sanitized(p) \
+do { if (NULL != p) { (void)dk4strw_free_sanitized(p); } p = NULL; } while (0)
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS && (DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT)
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+
+#include "dk4strw.h"
+#include "dk4mem.h"
+#include "dk4numco.h"
+
+#if DK4_HAVE_WCTYPE_H
+#ifndef WCTYPE_H_INCLUDED
+#include <wctype.h>
+#define WCTYPE_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef DK4MEMRS_H_INCLUDED
+#include "dk4memrs.h"
+#endif
+
+
+
+$!trace-include
+
+
+
+/** Constant strings used in the module.
+*/
+static const wchar_t * const dk4strw_modkw[] = {
+$!string-table prefix=L
+#
+# 0 Default delimiters.
+#
+ \t\r\n
+$!end
+};
+
+
+
+/** First index of a keyword indicating true in the
+ dk4str8_boolkw array below.
+*/
+#define DK4STRW_FIRST_TRUE 5
+
+/** Keywords for boolean values.
+*/
+static const wchar_t * const dk4strw_boolkw[] = {
+$!string-table prefix=L
+#
+# 0...4 false
+#
+-
+0
+n$o
+of$f
+f$alse
+#
+# 5... true
+#
++
+1
+y$es
+on
+t$rue
+ok
+$!end
+};
+
+
+
+/** Number of significant digits when printing a double.
+*/
+static const int dk4strw_dbl_digits = DK4_DBL_DIGITS;
+
+
+
+void
+dk4strw_cpy_to_left(wchar_t *dst, const wchar_t *src)
+{
+ register wchar_t *dptr;
+ register const wchar_t *sptr;
+ if ((NULL != dst) && (NULL != src)) {
+ dptr = dst; sptr = src;
+ while(L'\0' != *sptr) { *(dptr++) = *(sptr++); }
+ *dptr = L'\0';
+ }
+}
+
+
+
+size_t
+dk4strw_len(const wchar_t *src)
+{
+ if (NULL == src) { return 0; }
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ return ((size_t)lstrlenW(src));
+#else
+ return (wcslen(src));
+#endif
+ /* --- Windows */
+#else
+ /* +++ Windows */
+#if DK4_HAVE_WCSLEN
+ return (wcslen(src));
+#else
+ size_t back = 0;
+ while(L'\0' != *src) { src++; back++; }
+ return back;
+#endif
+ /* --- Windows */
+#endif
+}
+
+
+
+wchar_t *
+dk4strw_chr(const wchar_t *s, wchar_t c)
+{
+ if (NULL == s) { return NULL; }
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_DENY_CRT
+ {
+ wchar_t *back = NULL;
+ while ((L'\0' != *s) && (NULL == back)) {
+ if (c == *s) {
+ back = (wchar_t *)s;
+ }
+ s++;
+ }
+ return back;
+ }
+#else
+ return (wcschr(s, c));
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+#if DK4_HAVE_WCSCHR
+ return (wcschr(s, c));
+#else
+ {
+ wchar_t *back = NULL;
+ while ((L'\0' != *s) && (NULL == back)) {
+ if (c == *s) {
+ back = (wchar_t *)s;
+ }
+ s++;
+ }
+ return back;
+ }
+#endif
+ /* --- non-Windows */
+#endif
+}
+
+
+
+wchar_t *
+dk4strw_rchr(const wchar_t *s, wchar_t c)
+{
+ if (NULL == s) { return NULL; }
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_DENY_CRT
+ {
+ wchar_t *back = NULL;
+ while (L'\0' != *s) {
+ if (c == *s) {
+ back = (wchar_t *)s;
+ }
+ s++;
+ }
+ return back;
+ }
+#else
+ return (wcsrchr(s, c));
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+#if DK4_HAVE_WCSRCHR
+ return (wcsrchr(s, c));
+#else
+ {
+ wchar_t *back = NULL;
+ while (L'\0' != *s) {
+ if (c == *s) {
+ back = (wchar_t *)s;
+ }
+ s++;
+ }
+ return back;
+ }
+#endif
+ /* --- non-Windows */
+#endif
+}
+
+
+
+wchar_t
+dk4strw_toupper(wchar_t c)
+{
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_DENY_CRT
+ if ((L'a' <= c) && (L'z' >= c)) {
+ return (L'A' + (c - L'a'));
+ } else {
+ return c;
+ }
+#else
+ return (towupper(c));
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+ return (towupper(c));
+ /* --- non-Windows */
+#endif
+}
+
+
+
+wchar_t
+dk4strw_tolower(wchar_t c)
+{
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_DENY_CRT
+ if ((L'A' <= c) && (L'Z' >= c)) {
+ return (L'a' + (c - L'A'));
+ } else {
+ return c;
+ }
+#else
+ return (towlower(c));
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+ return (towlower(c));
+ /* --- non-Windows */
+#endif
+}
+
+
+
+int
+dk4strw_cpy_s(wchar_t *dst, size_t sz, const wchar_t *src, dk4_er_t *erp)
+{
+ int back = 0;
+ size_t sl;
+ if ((NULL != dst) && (0 < sz)) {
+ *dst = L'\0';
+ if (NULL != src) {
+ sl = dk4strw_len(src);
+ if (sz > sl) {
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ (void)lstrcpyW(dst, (wchar_t *)src);
+#else
+#pragma warning (disable:4996)
+ (void)wcscpy(dst, src);
+#pragma warning (default:4996)
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+#if DK4_HAVE_WCSCPY
+ (void)wcscpy(dst, src);
+#else
+ size_t nbytes;
+ dk4_er_t er;
+ dk4error_init(&er);
+ if ((SIZE_MAX - 1) < sl) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ if ((SIZE_MAX / sizeof(wchar_t)) < (sl + 1)) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ nbytes = sizeof(wchar_t) * (sl + 1);
+ }
+ }
+ if (DK4_E_NONE == er.ec) {
+ DK4_MEMCPY(dst, src, nbytes);
+ } else {
+ dk4strw_cpy_to_left(dst, src);
+ }
+#endif
+ /* --- non-Windows */
+#endif
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4strw_cat_s(wchar_t *dst, size_t sz, const wchar_t *src, dk4_er_t *erp)
+{
+ size_t la; /* Size of string in destination buffer */
+ size_t lb; /* Source string size */
+ int back = 0;
+ if ((NULL != dst) && (0 < sz) && (NULL != src)) {
+ la = dk4strw_len(dst);
+ lb = dk4strw_len(src);
+ if (sz > (la + lb)) {
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ (void)lstrcatW(dst, src);
+#else
+#pragma warning (disable:4996)
+ (void)wcscat(dst, src);
+#pragma warning (default:4996)
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+#if DK4_HAVE_WCSCAT
+ (void)wcscat(dst, src);
+#else
+ size_t nb;
+ dk4_er_t er;
+ dk4error_init(&er);
+ if ((SIZE_MAX - 1) < lb) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ if ((SIZE_MAX / sizeof(wchar_t)) < (lb + 1)) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ nb = sizeof(wchar_t) * (lb + 1);
+ }
+ }
+ if (DK4_E_NONE == er.ec) {
+ DK4_MEMCPY(&(dst[la]), src, nb);
+ } else {
+ dk4strw_cpy_to_left(&(dst[la]), src);
+ }
+#endif
+ /* --- non-Windows */
+#endif
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+
+int
+dk4strw_cmp(const wchar_t *s1, const wchar_t *s2)
+{
+ int back = 0;
+ if (NULL != s1) {
+ if (NULL != s2) {
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ back = lstrcmpW(s1, s2);
+ if (0 > back) back = -1;
+ if (0 < back) back = 1;
+#else
+ back = wcscmp(s1, s2);
+ if (0 > back) back = -1;
+ if (0 < back) back = 1;
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+#if DK4_HAVE_WCSCMP
+ back = wcscmp(s1, s2);
+ if (0 > back) back = -1;
+ if (0 < back) back = 1;
+#else
+#if DK4_HAVE__WCSCMP
+ back = _wcscmp(s1, s2);
+ if (0 > back) back = -1;
+ if (0 < back) back = 1;
+#else
+ do {
+ if (*s1 > *s2) {
+ back = 1;
+ } else {
+ if (*s1 < *s2) {
+ back = -1;
+ } else {
+ if (L'\0' != *s1) {
+ s1++; s2++;
+ }
+ }
+ }
+ } while((0 == back) && (L'\0' != *s1));
+#endif
+#endif
+ /* --- non-Windows */
+#endif
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != s2) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4strw_ncmp(const wchar_t *s1, const wchar_t *s2, size_t n)
+{
+ int back = 0;
+ if (NULL != s1) {
+ if (NULL != s2) {
+#if (DK4_ON_WINDOWS && (DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT) ) \
+|| (!(DK4_HAVE_WCSNCMP)) || (!(DK4_HAVE__WCSNCMP))
+ while ((0 < n--) && (0 == back)) {
+ if (L'\0' == *s1) {
+ if (L'\0' == *s2) {
+ n = 0;
+ } else {
+ back = -1;
+ }
+ } else {
+ if (L'\0' == *s2) {
+ back = 1;
+ } else {
+ if (*s1 < *s2) {
+ back = -1;
+ } else {
+ if (*s1 > *s2) {
+ back = 1;
+ } else {
+ s1++; s2++;
+ }
+ }
+ }
+ }
+ }
+#else
+#if DK4_HAVE_WCSNCMP
+ back = wcsncmp(s1, s2, n);
+#else
+ back = _wcsncmp(s1, s2, n);
+#endif
+ if (-1 > back) back = -1;
+ if ( 1 < back) back = 1;
+#endif
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != s2) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4strw_casecmp(const wchar_t *s1, const wchar_t *s2)
+{
+ int back = 0;
+ if (NULL != s1) {
+ if (NULL != s2) {
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+#if DK4_WIN_AVOID_CRT || DK4_WIN_DENY_CRT
+ back = lstrcmpiW(s1, s2);
+ if (0 > back) back = -1;
+ if (0 < back) back = 1;
+#else
+ back =_wcsicmp(s1, s2);
+ if (0 > back) back = -1;
+ if (0 < back) back = 1;
+#endif
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+#if DK4_HAVE_WCSCASECMP
+ back = wcscasecmp(s1, s2);
+ if (0 > back) back = -1;
+ if (0 < back) back = 1;
+#else
+#if DK4_HAVE__WCSCASECMP
+ back = _wcscasecmp(s1, s2);
+ if (0 > back) back = -1;
+ if (0 < back) back = 1;
+#else
+#if DK4_HAVE__WCSICMP
+ back = _wcsicmp(s1, s2);
+ if (0 > back) back = -1;
+ if (0 < back) back = 1;
+#else
+#if DK4_HAVE_WCSICMP
+ back = wcsicmp(s1, s2);
+ if (0 > back) back = -1;
+ if (0 < back) back = 1;
+#else
+ wchar_t c1;
+ wchar_t c2;
+ c1 = dk4strw_toupper(*s1);
+ c2 = dk4strw_toupper(*s2);
+ do {
+ if (c1 > c2) {
+ back = 1;
+ } else {
+ if (c1 < c2) {
+ back = -1;
+ } else {
+ if (L'\0' != *s1) {
+ s1++; s2++;
+ }
+ }
+ }
+ } while((0 == back) && (L'\0' != *s1));
+#endif
+#endif
+#endif
+#endif
+ /* --- non-Windows */
+#endif
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != s2) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+#if (defined(_WIN32) && DK4_USE_WINDOWS_LOCAL_ALLOC) \
+ || (DK4_HAVE_MALLOC && DK4_HAVE_FREE)
+
+wchar_t *
+dk4strw_dup(const wchar_t *src, dk4_er_t *erp)
+{
+ wchar_t *back = NULL;
+ size_t lgt;
+ if (NULL != src) {
+ lgt = dk4strw_len(src);
+ if (SIZE_MAX > lgt) {
+ back = dk4mem_new(wchar_t,(lgt+1),erp);
+ if (NULL != back) {
+ (void)dk4strw_cpy_s(back, (lgt+1), src, erp);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+#endif
+/* if (defined(_WIN32) ... */
+
+
+
+#if !DK4_HAVE_WCSCHR
+/** Find first occurance of character in string.
+ @param src String to search for character.
+ @param c Character to find.
+ @return Pointer to first occurance on success, NULL on error.
+*/
+static
+const wchar_t *
+dk4strw_i_wcschr(const wchar_t *src, wchar_t c)
+{
+ const wchar_t *back = NULL;
+ while ((L'\0' != *src) && (NULL == back)) {
+ if (*src == c) {
+ back = src;
+ } else {
+ src++;
+ }
+ }
+ return back;
+}
+#endif
+
+
+
+wchar_t *
+dk4strw_start(const wchar_t *src, const wchar_t *delim)
+{
+ wchar_t *back = NULL;
+ if (NULL != src) {
+ if (NULL == delim) { delim = dk4strw_modkw[0]; }
+ while((L'\0' != *src) && (NULL == back)) {
+ if (NULL != dk4strw_chr(delim, *src)) {
+ src++;
+ } else {
+ back = (wchar_t *)src;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Internal function for next token search.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param src String containing tokens, must be set to
+ the start of a token.
+ @param delim Delimiter set.
+ @return Pointer to next token on success, NULL on error.
+*/
+static
+wchar_t *
+dk4strw_i_next(wchar_t *src, const wchar_t *delim)
+{
+ wchar_t *back = NULL;
+ if (NULL != src) {
+ if (NULL == delim) { delim = dk4strw_modkw[0]; }
+ while ((L'\0' != *src) && (NULL == back)) {
+ if (NULL != dk4strw_chr(delim, *src)) {
+ back = src;
+ } else {
+ src++;
+ }
+ }
+ if (NULL != back) {
+ *(back++) = L'\0';
+ back = dk4strw_start(back, delim);
+ }
+ }
+ return back;
+}
+
+
+
+wchar_t *
+dk4strw_next(wchar_t *src, const wchar_t *delim)
+{
+ wchar_t *back = NULL;
+ if (NULL != src) {
+ back = dk4strw_start(src, delim);
+ if (NULL != back) {
+ back = dk4strw_i_next(back, delim);
+ }
+ }
+ return back;
+}
+
+
+
+wchar_t *
+dk4strw_sep(wchar_t **stringp, const wchar_t *delim)
+{
+ wchar_t *back = NULL;
+ $? "+ dk4strw_sep \"%ls\" \"%ls\"", TR_LSTR(*stringp), TR_LSTR(delim)
+ if (NULL != stringp) {
+ if (NULL != *stringp) {
+ if (NULL == delim) { delim = dk4strw_modkw[0]; }
+ back = dk4strw_start(*stringp, delim);
+ if (NULL != back) {
+ *stringp = dk4strw_next(back, delim);
+ } else {
+ *stringp = NULL;
+ }
+ }
+ } $? "- dk4strw_sep \"%ls\"", TR_LSTR(back)
+ return back;
+}
+
+
+
+size_t
+dk4strw_tokenize(
+ wchar_t **dpp, size_t szdpp, wchar_t *src, const wchar_t *delim, dk4_er_t *erp
+)
+{
+ wchar_t *context;
+ wchar_t *token;
+ size_t back = 0;
+ if ((NULL != dpp) && (0 < szdpp) && (NULL != src)) {
+ if (NULL == delim) { delim = dk4strw_modkw[0]; }
+ context = src;
+ while (NULL != (token = dk4strw_sep(&context, delim))) {
+ if (back < szdpp) {
+ dpp[back] = token;
+ }
+ back++;
+ }
+ if (back >= szdpp) { /* Too many tokens found */
+ dk4error_set_elsize_nelem(
+ erp, DK4_E_BUFFER_TOO_SMALL, sizeof(DK4_PCHAR), back
+ );
+ back = 0;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+void
+dk4strw_normalize(wchar_t *src, const wchar_t *delim)
+{
+
+ wchar_t *p1; /* Pointer to traverse text. */
+ wchar_t *p2; /* Start of next token. */
+ int cc; /* Flag: Can continue. */
+
+ if (NULL != src) {
+ if (NULL == delim) { delim = dk4strw_modkw[0]; }
+ p1 = src;
+ cc = 0;
+ if (L'\0' != *p1) {
+ if (NULL != dk4strw_chr(delim, *p1)) {
+ p2 = dk4strw_start(p1, delim);
+ if (NULL != p2) {
+ dk4strw_cpy_to_left(p1, p2);
+ cc = 1;
+ } else {
+ *p1 = L'\0';
+ }
+ } else {
+ cc = 1;
+ }
+ }
+ while (0 != cc) {
+ if (L'\0' == *p1) {
+ cc = 0;
+ } else {
+ if (NULL != dk4strw_chr(delim, *p1)) {
+ *p1 = *delim;
+ if (L'\0' == p1[1]) {
+ *p1 = L'\0';
+ cc = 0;
+ } else {
+ if (NULL != dk4strw_chr(delim, p1[1])) {
+ p2 = dk4strw_start(p1, delim);
+ if (NULL != p2) {
+ dk4strw_cpy_to_left(++p1, p2);
+ } else {
+ *p1 = L'\0';
+ cc = 0;
+ }
+ } else {
+ p1++;
+ }
+ }
+ } else {
+ p1++;
+ }
+ }
+ }
+ }
+}
+
+
+
+int
+dk4strw_array_index(const wchar_t * const *arr, const wchar_t *str, int cs)
+{
+ int back = -1;
+ int cand = 0;
+ while ((NULL != *arr) && (-1 == back)) {
+ if (0 != cs) {
+ if (0 == dk4strw_cmp(*arr, str)) { back = cand; }
+ } else {
+ if (0 == dk4strw_casecmp(*arr, str)) { back = cand; }
+ }
+ arr++; cand++;
+ }
+ return back;
+}
+
+
+
+
+int
+dk4strw_is_abbr(const wchar_t *str,const wchar_t *pattern,wchar_t spec,int cs)
+{
+ const wchar_t *lptr = NULL; /* Pointer to traverse string */
+ const wchar_t *pptr = NULL; /* Pointer to traverse pattern */
+ int back = 0; /* Function result */
+ int fspec = 0; /* Flag: spec was found */
+ int cc = 1; /* Flag: Can continue */
+ wchar_t cl;
+ wchar_t cp;
+ $? "+ dk4strw_is_abbr str=\"%ls\" pattern=\"%ls\"", TR_LSTR(str), TR_LSTR(pattern)
+ if ((NULL != str) && (NULL != pattern)) {
+ lptr = str; pptr = pattern;
+ while (0 != cc) {
+ if ((0 == fspec) && (*pptr == spec)) {
+ fspec = 1;
+ pptr++;
+ } else {
+ if (L'\0' != *lptr) {
+ cl = *lptr; cp = *pptr;
+ if (0 == cs) {
+ cl = dk4strw_toupper(cl);
+ cp = dk4strw_toupper(cp);
+ }
+ if (cl == cp) {
+ lptr++;
+ pptr++;
+ } else {
+ cc = 0;
+ }
+ } else {
+ cc = 0;
+ if ((L'\0' == *pptr) || (0 != fspec)) { back = 1; }
+ }
+ }
+ }
+ }
+ $? "- dk4strw_is_abbr %d", back
+ return back;
+}
+
+
+
+int
+dk4strw_abbr_index(
+ const wchar_t * const *arr,
+ wchar_t spec,
+ const wchar_t *str,
+ int cs
+)
+{
+ int back = -1;
+ int cand = 0; /* Traverse array */
+ $? "+ dk4strw_abbr_index"
+ if ((NULL != arr) && (NULL != str)) {
+ while ((NULL != *arr) && (-1 == back)) {
+ if (0 != dk4strw_is_abbr(str, *arr, spec, cs)) {
+ back = cand;
+ }
+ arr++; cand++;
+ }
+ }
+ $? "- dk4strw_abbr_index %d", back
+ return back;
+}
+
+
+
+int
+dk4strw_is_bool(const wchar_t *str)
+{
+ int back = 0;
+ if (NULL != str) {
+ if (-1 < dk4strw_abbr_index(dk4strw_boolkw, L'$', str, 0)) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4strw_is_on(const wchar_t *str)
+{
+ int back = 0;
+ $? "+ dk4strw_is_on"
+ if (NULL != str) {
+ back = dk4strw_abbr_index(dk4strw_boolkw, L'$', str, 0);
+ if (-1 < back) {
+ if (DK4STRW_FIRST_TRUE <= back) {
+ back = 1; $? ". true"
+ } else {
+ back = 0; $? ". false"
+ }
+ } else {
+ back = 0; $? ". not found"
+ }
+ }
+ $? "- dk4strw_is_on %d", back
+ return back;
+}
+
+
+
+int
+dk4strw_pathcmp(const wchar_t *s1, const wchar_t *s2)
+{
+#if DK4_HAVE_CASE_INSENSITIVE_PATHNAMES
+ return (dk4strw_casecmp(s1, s2));
+#else
+ return (dk4strw_cmp(s1, s2));
+#endif
+}
+
+
+
+void
+dk4strw_rtwh(wchar_t *str, const wchar_t *whsp)
+{
+ wchar_t *ptr = NULL; /* Pointer to first whitespace */
+
+ if (NULL == whsp) { whsp = dk4strw_modkw[0]; }
+ if (NULL != str) {
+ while (L'\0' != *str) {
+ if (NULL != dk4strw_chr(whsp, *str)) {
+ if (NULL == ptr) { ptr = str; }
+ } else {
+ ptr = NULL;
+ }
+ str++;
+ }
+ if (NULL != ptr) { *ptr = L'\0'; }
+ }
+}
+
+
+
+void
+dk4strw_delnl(wchar_t *lptr)
+{
+ if (NULL != lptr) {
+ while (L'\0' != *lptr) {
+ if (L'\n' == *lptr) {
+ *lptr = L'\0';
+ } else {
+ if (L'\r' == *lptr) {
+ if (L'\n' == lptr[1]) {
+ *lptr = L'\0';
+ } else {
+ if (L'\0' == lptr[1]) {
+ *lptr = L'\0';
+ } else {
+ lptr++;
+ }
+ }
+ } else {
+ lptr++;
+ }
+ }
+ }
+ }
+}
+
+
+
+const wchar_t *
+dk4strw_skip(const wchar_t *line, size_t skip)
+{
+ const wchar_t *back = NULL;
+ size_t words = 0; /* Number of words already found */
+ int lwt = 0; /* Flag: Last char was text */
+
+ if (NULL != line) {
+ if (0 < skip) {
+ while ((NULL == back) && (L'\0' != *line)) {
+ if (L' ' == *line) {
+ lwt = 0;
+ } else {
+ if (L'\t' == *line) {
+ lwt = 0;
+ } else {
+ if (L'\n' == *line) {
+ lwt = 0;
+ } else {
+ if (L'\r' == *line) {
+ lwt = 0;
+ } else {
+ if (0 == lwt) {
+ if (++words > skip) {
+ back = line;
+ }
+ }
+ lwt = 1;
+ }
+ }
+ }
+ }
+ line++;
+ }
+ } else {
+ back = dk4strw_start(line, NULL);
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4strw_buffer_sanitize(wchar_t *str, size_t sz)
+{
+ size_t i;
+ int back = 0;
+
+ if (NULL != str) {
+ if (0 < sz) {
+ if ((SIZE_MAX / sizeof(wchar_t)) >= sz) {
+ back = dk4mem_reset_secure(str, (sz * sizeof(wchar_t)), NULL);
+ } else {
+ for (i = 0; i < sz; i++) { str[i] = L'\0'; }
+ back = 1;
+ for (i = 0; i < sz; i++) { if (L'\0' != str[i]) { back = 0; } }
+ }
+ } else {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4strw_sanitize(wchar_t *str)
+{
+ int back = 0;
+ if (NULL != str) {
+ back = dk4strw_buffer_sanitize(str, dk4strw_len(str));
+ }
+ return back;
+}
+
+
+
+int
+dk4strw_free_sanitized(wchar_t *str)
+{
+ int back = 0;
+ if (NULL != str) {
+ back = dk4strw_sanitize(str);
+ dk4mem_free(str);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4strw.h b/support/dktools/dk4strw.h
new file mode 100644
index 0000000000..454b893a48
--- /dev/null
+++ b/support/dktools/dk4strw.h
@@ -0,0 +1,445 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4strw.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4STRW_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4STRW_H_INCLUDED 1
+
+
+#line 10 "dk4strw.ctr"
+
+/** @file
+ Additional string functions for
+ wchar_t strings.
+
+ Although some of the functions in this module duplicate
+ functionality from the C runtime library on Windows, you should use
+ the functions from this module.
+ With DK4DK4_WIN_AVOID_CRT or DK4_WIN_DENY_CRT defined to non-zero
+ these functions call Windows API functions like
+ lstrcmpW() ... instead of CRT functions.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+
+#if DK4_HAVE_WCHAR_H
+#ifndef WCHAR_H_INCLUDED
+#include <wchar.h>
+#define WCHAR_H_INCLUDED 1
+#endif
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Copy string, check destination buffer size.
+
+ CRT on Windows: Optional.
+ @param dst Destination buffer address.
+ @param sz Destination buffer size.
+ @param src Source string.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dst or src is NULL or sz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the dst buffer is too small.
+*/
+int
+dk4strw_cpy_s(wchar_t *dst, size_t sz, const wchar_t *src, dk4_er_t *erp);
+
+/** Concatenate strings, check destination buffer size.
+
+ CRT on Windows: Optional.
+ @param dst Destination buffer address.
+ @param sz Destination buffer size.
+ @param src Source string.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dst or src is NULL or sz is 0,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in size calculation,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the concatenated string doest not fit into the buffer.
+*/
+int
+dk4strw_cat_s(wchar_t *dst, size_t sz, const wchar_t *src, dk4_er_t *erp);
+
+/** Copy characters within a string from right to left.
+ This copy operation is intended for moving characters within
+ one string from right to left, making the string shorter
+ as is. This function does not check buffer size or report
+ any error.
+ For normal string copy operations, use the dk4strw_cpy_s()
+ function instead.
+
+ CRT on Windows: Not used.
+ @param dst Destination buffer address.
+ @param src Source string.
+*/
+void
+dk4strw_cpy_to_left(wchar_t *dst, const wchar_t *src);
+
+/** Find string length.
+
+ CRT on Windows: Optional, disabling CRT reduces functionality
+ to strings with length fitting to int.
+ @param src Source string.
+ @return String length.
+*/
+size_t
+dk4strw_len(const wchar_t *src);
+
+/** Compare two strings.
+
+ CRT on Windows: Optional.
+ @param s1 Left string, may be NULL.
+ @param s2 Right string, may be NULL.
+ @return 1 if s1>s2, 0 if s1==s2, -1 if s1<s2.
+*/
+int
+dk4strw_cmp(const wchar_t *s1, const wchar_t *s2);
+
+/** Compare two strings.
+
+ CRT on Windows: Optional.
+ @param s1 Left string, may be NULL.
+ @param s2 Right string, may be NULL.
+ @param n Maximum number of characters to compare.
+ @return 1 if s1>s2, 0 if s1==s2, -1 if s1<s2.
+*/
+int
+dk4strw_ncmp(const wchar_t *s1, const wchar_t *s2, size_t n);
+
+/** Compare two strings, case-insensitive comparison.
+
+ CRT on Windows: Optional, disabling CRT probably degrades performance.
+ @param s1 Left string, may be NULL.
+ @param s2 Right string, may be NULL.
+ @return 1 if s1>s2, 0 if s1==s2, -1 if s1<s2.
+*/
+int
+dk4strw_casecmp(const wchar_t *s1, const wchar_t *s2);
+
+/** Compare two file path names.
+
+ CRT on Windows: Optional.
+ @param s1 Left string, may be NULL.
+ @param s2 Right string, may be NULL.
+ @return 1 if s1>s2, 0 if s1==s2, -1 if s1<s2.
+*/
+int
+dk4strw_pathcmp(const wchar_t *s1, const wchar_t *s2);
+
+/** Find first occurance of character c in string s.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param s String to search for c.
+ @param c Character to find.
+ @return Pointer to first occurance if found, NULL otherwise.
+*/
+wchar_t *
+dk4strw_chr(const wchar_t *s, wchar_t c);
+
+/** Find last occurance of character c in string s.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param s String to search for c.
+ @param c Character to find.
+ @return Pointer to last occurance if found, NULL otherwise.
+*/
+wchar_t *
+dk4strw_rchr(const wchar_t *s, wchar_t c);
+
+/** Convert character to upper-case character.
+
+ CRT on windows: Optional, disabling CRT degrades performance.
+ @param c Character to convert.
+ @return Conversion result.
+*/
+wchar_t
+dk4strw_toupper(wchar_t c);
+
+/** Convert character to lower-case character.
+
+ CRT on windows: Optional, disabling CRT degrades performance.
+ @param c Character to convert.
+ @return Conversion result.
+*/
+wchar_t
+dk4strw_tolower(wchar_t c);
+
+/** Retrieve first token from *stringp.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param stringp Adress of string pointer.
+ @param delim String containing the delimiter set,
+ my be NULL to use the default delimiter
+ set (space, tabulator, carriage return and newline).
+ @return Pointer to first token on success, NULL if no (further)
+ token found.
+*/
+wchar_t *
+dk4strw_sep(wchar_t **stringp, const wchar_t *delim);
+
+/** Find first token in string.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param src String to search for tokens.
+ @param delim String containing the delimiter characters,
+ may be NULL to use the default delimiter set.
+ @return Pointer to first token if found, NULL otherwise.
+*/
+wchar_t *
+dk4strw_start(const wchar_t *src, const wchar_t *delim);
+
+/** Cut string after first token, find start of second token in string.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param src String to search for tokens,
+ normally the result of dk4strw_start() or a
+ previous dk4strw_next() call.
+ @param delim String containing the delimiter characters,
+ may be NULL to use the default delimiter set.
+ @return Pointer to second token if found, NULL otherwise.
+*/
+wchar_t *
+dk4strw_next(wchar_t *src, const wchar_t *delim);
+
+/** Split a string into tokens.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param dpp Pointer to string pointer array.
+ @param szdpp Size of destination string pointer array.
+ @param src Source string to process.
+ @param delim String containing delimiter characters,
+ may be NULL to use the default delimiter set.
+ @param erp Error report, may be NULL.
+ @return Number of tokens found on success, 0 if no token
+ found or on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ for invalid function arguments,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ with dt.mem.nelem set to the number of tokens in string if the dpp
+ array is too short.
+*/
+size_t
+dk4strw_tokenize(
+ wchar_t **dpp, size_t szdpp, wchar_t *src, const wchar_t *delim, dk4_er_t *erp
+);
+
+/** Normalize a string (remove leading and trailing delimiters,
+ replace delimiter sequences by just one delimiter).
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param src Buffer containing the string to normalize.
+ @param delim String containing delimiter characters,
+ may be NULL to use the default delimiter set.
+*/
+void
+dk4strw_normalize(wchar_t *src, const wchar_t *delim);
+
+/** Find index of a string in an array of strings.
+
+ CRT on Windows: Optional.
+ @param arr Array of strings.
+ @param str String to find in array.
+ @param cs Flag: Case-sensitive search (0=no, other=yes).
+ @return Non-negative index value on success, -1 on error.
+*/
+int
+dk4strw_array_index(const wchar_t * const *arr, const wchar_t *str, int cs);
+
+/** Find index of a string in an array of strings.
+
+ CRT on windows: Optional, disabling CRT degrades performance
+ for case-insensitive comparisons.
+ @param arr Array of strings allowing abbreviation.
+ @param spec Special character indicating start of optional text.
+ @param str String to find in array.
+ @param cs Flag: Case-sensitive search (0=no, other=yes).
+ @return Non-negative index value on success, -1 on error.
+*/
+int
+dk4strw_abbr_index(
+ const wchar_t * const *arr,
+ wchar_t spec,
+ const wchar_t *str,
+ int cs
+);
+
+/** Check whether a text matches a pattern, the text may be abbreviated.
+
+ CRT on windows: Optional, disabling CRT degrades performance
+ for case-insensitive comparisons.
+ @param str Text to check.
+ @param pattern Pattern for comparison.
+ @param spec Special character marking the abbreviation in the
+ pattern.
+ @param cs Flag: Case sensitive (1) or not (0).
+ @return 1 for a match, 0 otherwise.
+*/
+int
+dk4strw_is_abbr(const wchar_t *str,const wchar_t *pattern,wchar_t spec,int cs);
+
+/** Check whether a string represents a boolean value.
+
+ CRT on windows: Optional, disabling CRT degrades performance.
+ @param str String to check.
+ @return 1 if str represents a boolean value, 0 otherwise.
+*/
+int
+dk4strw_is_bool(const wchar_t *str);
+
+/** Check whether a string represents the boolean value TRUE.
+
+ CRT on windows: Optional, disabling CRT degrades performance.
+ @param str String to check.
+ @return 1 if str represents the boolean value TRUE, 0 otherwise.
+*/
+int
+dk4strw_is_on(const wchar_t *str);
+
+#if (defined(_WIN32) && DK4_USE_WINDOWS_LOCAL_ALLOC) \
+ || (DK4_HAVE_MALLOC && DK4_HAVE_FREE)
+
+/** Duplicate string in dynamically allocated memory.
+
+ CRT on Windows: Optional, disabling CRT reduces functionality
+ to strings with length fitting to int and overall size in
+ bytes - including finalizer - fitting into a DWORD.
+ @param src String to duplicate.
+ @param erp Error report, may be NULL.
+ @return Pointer to string in new memory on succes, NULL on error.
+ Use dk4mem_free() to release the memory after usage.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src is a NULL pointer,
+ - DK4_E_MATH_OVERFLOW<br>
+ on mathematical overflow in size calculation,
+ - DK4_E_MEMORY<br>
+ if no memory is available.
+*/
+wchar_t *
+dk4strw_dup(const wchar_t *src, dk4_er_t *erp);
+
+#endif
+/* if (defined(_WIN32) ... */
+
+
+/** Remove trailing white spaces.
+
+ CRT on Windows: Optional, disabling CRT degrades performance.
+ @param str String to remove white spaces from.
+ @param whsp White spaces set.
+*/
+void
+dk4strw_rtwh(wchar_t *str, const wchar_t *whsp);
+
+/** Remove trailing newline from line.
+ @param lptr Line pointer.
+*/
+void
+dk4strw_delnl(wchar_t *lptr);
+
+/** Skip the first text words in a line, return pointer to start
+ of next word.
+ @param line Line to process.
+ @param skip Number of words to skip.
+ @return Pointer to next word on success, NULL on error.
+*/
+const wchar_t *
+dk4strw_skip(const wchar_t *line, size_t skip);
+
+/** Sanitize string (overwrite using 0).
+ @param str Address of string to sanitize.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4strw_sanitize(wchar_t *str);
+
+/** Sanitize string buffer (overwrite using 0 bytes).
+ @param str Address of string buffer.
+ @param sz Size of string buffer (number of wchar_t).
+ @return 1 on success, 0 on error.
+*/
+int
+dk4strw_buffer_sanitize(wchar_t *str, size_t sz);
+
+/** Sanitize dynamically allocated memory and release it.
+ @param str Address of string to sanitize and release.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4strw_free_sanitized(wchar_t *str);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/** Sanitize string and release it, set pointer to NULL.
+ @param p Pointer to string to release.
+*/
+#define dk4strw_release_sanitized(p) \
+do { if (NULL != p) { (void)dk4strw_free_sanitized(p); } p = NULL; } while (0)
+
+
+#endif
diff --git a/support/dktools/dk4strx.cpp b/support/dktools/dk4strx.cpp
new file mode 100644
index 0000000000..d60a284b34
--- /dev/null
+++ b/support/dktools/dk4strx.cpp
@@ -0,0 +1,331 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4strx.cpt
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4strx.cpp The dk4strx module.
+*/
+
+
+#line 313 "dk4strx.cpt"
+
+#include "dk4strx.h"
+
+
+#if DK4_SIZEOF_WXCHAR > 1
+#include "dk4strw.h"
+#else
+#include "dk4str8.h"
+#endif
+
+
+
+
+
+#line 326 "dk4strx.cpt"
+
+
+
+int
+dk4strx_cpy_s(wxChar *dst, size_t sz, const wxChar *src, dk4_er_t *erp)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4strw_cpy_s(dst, sz, src, erp));
+#else
+ return (dk4str8_cpy_s(dst, sz, src, erp));
+#endif
+}
+
+
+
+int
+dk4strx_cat_s(wxChar *dst, size_t sz, const wxChar *src, dk4_er_t *erp)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4strw_cat_s(dst, sz, src, erp));
+#else
+ return (dk4str8_cat_s(dst, sz, src, erp));
+#endif
+}
+
+
+
+void
+dk4strx_cpy_to_left(wxChar *dst, const wxChar *src)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ dk4strw_cpy_to_left(dst, src);
+#else
+ dk4str8_cpy_to_left(dst, src);
+#endif
+}
+
+
+
+size_t
+dk4strx_len(const wxChar *src)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4strw_len(src));
+#else
+ return (dk4str8_len(src));
+#endif
+}
+
+
+
+int
+dk4strx_cmp(const wxChar *s1, const wxChar *s2)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4strw_cmp(s1, s2));
+#else
+ return (dk4str8_cmp(s1, s2));
+#endif
+}
+
+
+
+int
+dk4strx_casecmp(const wxChar *s1, const wxChar *s2)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4strw_casecmp(s1, s2));
+#else
+ return (dk4str8_casecmp(s1, s2));
+#endif
+}
+
+
+
+int
+dk4strx_pathcmp(const wxChar *s1, const wxChar *s2)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4strw_pathcmp(s1, s2));
+#else
+ return (dk4str8_pathcmp(s1, s2));
+#endif
+}
+
+
+
+wxChar *
+dk4strx_chr(const wxChar *s, wxChar c)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4strw_chr(s, c));
+#else
+ return (dk4str8_chr(s, c));
+#endif
+}
+
+
+
+wxChar *
+dk4strx_rchr(const wxChar *s, wxChar c)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4strw_rchr(s, c));
+#else
+ return (dk4str8_rchr(s, c));
+#endif
+}
+
+
+
+wxChar *
+dk4strx_sep(wxChar **stringp, const wxChar *delim)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4strw_sep(stringp, delim));
+#else
+ return (dk4str8_sep(stringp, delim));
+#endif
+}
+
+
+
+wxChar *
+dk4strx_start(const wxChar *src, const wxChar *delim)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4strw_start(src, delim));
+#else
+ return (dk4str8_start(src, delim));
+#endif
+}
+
+
+
+wxChar *
+dk4strx_next(wxChar *src, const wxChar *delim)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4strw_next(src, delim));
+#else
+ return (dk4str8_next(src, delim));
+#endif
+}
+
+
+
+size_t
+dk4strx_tokenize(
+ wxChar **dpp, size_t szdpp, wxChar *src, const wxChar *delim, dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4strw_tokenize(dpp, szdpp, src, delim, erp));
+#else
+ return (dk4str8_tokenize(dpp, szdpp, src, delim, erp));
+#endif
+}
+
+
+
+void
+dk4strx_normalize(wxChar *src, const wxChar *delim)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ dk4strw_normalize(src, delim);
+#else
+ dk4str8_normalize(src, delim);
+#endif
+}
+
+
+
+int
+dk4strx_array_index(const wxChar * const *arr, const wxChar *str, int cs)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4strw_array_index(arr, str, cs));
+#else
+ return (dk4str8_array_index(arr, str, cs));
+#endif
+}
+
+
+
+int
+dk4strx_abbr_index(
+ const wxChar * const *arr,
+ wxChar spec,
+ const wxChar *str,
+ int cs
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4strw_abbr_index(arr, spec, str, cs));
+#else
+ return (dk4str8_abbr_index(arr, spec, str, cs));
+#endif
+}
+
+
+
+int
+dk4strx_is_abbr(const wxChar *str, const wxChar *pattern, wxChar spec, int cs)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4strw_is_abbr(str, pattern, spec, cs));
+#else
+ return (dk4str8_is_abbr(str, pattern, spec, cs));
+#endif
+}
+
+
+
+int
+dk4strx_is_bool(const wxChar *str)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4strw_is_bool(str));
+#else
+ return (dk4str8_is_bool(str));
+#endif
+}
+
+
+
+int
+dk4strx_is_on(const wxChar *str)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4strw_is_on(str));
+#else
+ return (dk4str8_is_on(str));
+#endif
+}
+
+
+
+#if (defined(_WIN32) && DK4_USE_WINDOWS_LOCAL_ALLOC) \
+ || (DK4_HAVE_MALLOC && DK4_HAVE_FREE)
+
+wxChar *
+dk4strx_dup(const wxChar *src, dk4_er_t *erp)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4strw_dup(src, erp));
+#else
+ return (dk4str8_dup(src, erp));
+#endif
+}
+
+#endif
+/* if (defined(_WIN32) ... */
+
+void
+dk4strx_rtwh(wxChar *str, const wxChar *whsp)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ dk4strw_rtwh(str, whsp);
+#else
+ dk4str8_rtwh(str, whsp);
+#endif
+}
+
+
+
+void
+dk4strx_delnl(wxChar *lptr)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ dk4strw_delnl(lptr);
+#else
+ dk4str8_delnl(lptr);
+#endif
+}
+
diff --git a/support/dktools/dk4strx.cpt b/support/dktools/dk4strx.cpt
new file mode 100644
index 0000000000..cf8b9c8ea9
--- /dev/null
+++ b/support/dktools/dk4strx.cpt
@@ -0,0 +1,601 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+%% header
+
+/** @file dk4strx.h String functions for wxChar.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4CONST_H_INCLUDED
+#include "dk4const.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4WXCS_H_INCLUDED
+#include "dk4wxcs.h"
+#endif
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Copy string, check destination buffer size.
+ @param dst Destination buffer address.
+ @param sz Destination buffer size.
+ @param src Source string.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dst or src is NULL or sz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the dst buffer is too small.
+*/
+int
+dk4strx_cpy_s(wxChar *dst, size_t sz, const wxChar *src, dk4_er_t *erp);
+
+/** Concatenate strings, check destination buffer size.
+ @param dst Destination buffer address.
+ @param sz Destination buffer size.
+ @param src Source string.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dst or src is NULL or sz is 0,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in size calculation,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the concatenated string doest not fit into the buffer.
+*/
+int
+dk4strx_cat_s(wxChar *dst, size_t sz, const wxChar *src, dk4_er_t *erp);
+
+/** Copy characters within a string from right to left.
+ This copy operation is intended for moving characters within
+ one string from right to left, making the string shorter
+ as is. This function does not check buffer size or report
+ any error.
+ For normal string copy operations, use the dk4strx_cpy_s()
+ function instead.
+ @param dst Destination buffer address.
+ @param src Source string.
+*/
+void
+dk4strx_cpy_to_left(wxChar *dst, const wxChar *src);
+
+/** Find string length.
+ @param src Source string.
+ @return String length.
+*/
+size_t
+dk4strx_len(const wxChar *src);
+
+/** Compare two strings.
+ @param s1 Left string, may be NULL.
+ @param s2 Right string, may be NULL.
+ @return 1 if s1>s2, 0 if s1==s2, -1 if s1<s2.
+*/
+int
+dk4strx_cmp(const wxChar *s1, const wxChar *s2);
+
+/** Compare two strings, case-insensitive comparison.
+ @param s1 Left string, may be NULL.
+ @param s2 Right string, may be NULL.
+ @return 1 if s1>s2, 0 if s1==s2, -1 if s1<s2.
+*/
+int
+dk4strx_casecmp(const wxChar *s1, const wxChar *s2);
+
+/** Compare two file path names.
+ @param s1 Left string, may be NULL.
+ @param s2 Right string, may be NULL.
+ @return 1 if s1>s2, 0 if s1==s2, -1 if s1<s2.
+*/
+int
+dk4strx_pathcmp(const wxChar *s1, const wxChar *s2);
+
+/** Find first occurance of character c in string s.
+ @param s String to search for c.
+ @param c Character to find.
+ @return Pointer to first occurance if found, NULL otherwise.
+*/
+wxChar *
+dk4strx_chr(const wxChar *s, wxChar c);
+
+/** Find last occurance of character c in string s.
+ @param s String to search for c.
+ @param c Character to find.
+ @return Pointer to last occurance if found, NULL otherwise.
+*/
+wxChar *
+dk4strx_rchr(const wxChar *s, wxChar c);
+
+/** Retrieve first token from *stringp.
+ @param stringp Adress of string pointer.
+ @param delim String containing the delimiter set,
+ my be NULL to use the default delimiter
+ set (space, tabulator, carriage return and newline).
+ @return Pointer to first token on success, NULL if no (further)
+ token found.
+*/
+wxChar *
+dk4strx_sep(wxChar **stringp, const wxChar *delim);
+
+/** Find first token in string.
+ @param src String to search for tokens.
+ @param delim String containing the delimiter characters,
+ may be NULL to use the default delimiter set.
+ @return Pointer to first token if found, NULL otherwise.
+*/
+wxChar *
+dk4strx_start(const wxChar *src, const wxChar *delim);
+
+/** Cut string after first token, find start of second token in string.
+ @param src String to search for tokens,
+ normally the result of dk4strx_start() or a
+ previous dk4strx_next() call.
+ @param delim String containing the delimiter characters,
+ may be NULL to use the default delimiter set.
+ @return Pointer to second token if found, NULL otherwise.
+*/
+wxChar *
+dk4strx_next(wxChar *src, const wxChar *delim);
+
+/** Split a string into tokens.
+ @param dpp Pointer to string pointer array.
+ @param szdpp Size of destination string pointer array.
+ @param src Source string to process.
+ @param delim String containing delimiter characters,
+ may be NULL to use the default delimiter set.
+ @param erp Error report, may be NULL.
+ @return Number of tokens found on success, 0 if no token
+ found or on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ for invalid function arguments,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ with dt.mem.nelem set to the number of tokens in string if the dpp
+ array is too short.
+*/
+size_t
+dk4strx_tokenize(
+ wxChar **dpp, size_t szdpp, wxChar *src, const wxChar *delim, dk4_er_t *erp
+);
+
+/** Normalize a string (remove leading and trailing delimiters,
+ replace delimiter sequences by just one delimiter).
+ @param src Buffer containing the string to normalize.
+ @param delim String containing delimiter characters,
+ may be NULL to use the default delimiter set.
+*/
+void
+dk4strx_normalize(wxChar *src, const wxChar *delim);
+
+/** Find index of a string in an array of strings.
+ @param arr Array of strings.
+ @param str String to find in array.
+ @param cs Flag: Case-sensitive search (0=no, other=yes).
+ @return Non-negative index value on success, -1 on error.
+*/
+int
+dk4strx_array_index(const wxChar * const *arr, const wxChar *str, int cs);
+
+/** Find index of a string in an array of strings.
+ @param arr Array of strings allowing abbreviation.
+ @param spec Special character indicating start of optional text.
+ @param str String to find in array.
+ @param cs Flag: Case-sensitive search (0=no, other=yes).
+ @return Non-negative index value on success, -1 on error.
+*/
+int
+dk4strx_abbr_index(
+ const wxChar * const *arr,
+ wxChar spec,
+ const wxChar *str,
+ int cs
+);
+
+/** Check whether a text matches a pattern, the text may be abbreviated.
+ @param str Text to check.
+ @param pattern Pattern for comparison.
+ @param spec Special character marking the abbreviation in the
+ pattern.
+ @param cs Flag: Case sensitive (1) or not (0).
+ @return 1 for a match, 0 otherwise.
+*/
+int
+dk4strx_is_abbr(const wxChar *str, const wxChar *pattern, wxChar spec, int cs);
+
+/** Check whether a string represents a boolean value.
+ @param str String to check.
+ @return 1 if str represents a boolean value, 0 otherwise.
+*/
+int
+dk4strx_is_bool(const wxChar *str);
+
+/** Check whether a string represents the boolean value TRUE.
+ @param str String to check.
+ @return 1 if str represents the boolean value TRUE, 0 otherwise.
+*/
+int
+dk4strx_is_on(const wxChar *str);
+
+#if (defined(_WIN32) && DK4_USE_WINDOWS_LOCAL_ALLOC) \
+ || (DK4_HAVE_MALLOC && DK4_HAVE_FREE)
+
+/** Duplicate string in dynamically allocated memory.
+ @param src String to duplicate.
+ @param erp Error report, may be NULL.
+ @return Pointer to string in new memory on succes, NULL on error.
+ Use dk4mem_free() to release the memory after usage.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src is a NULL pointer,
+ - DK4_E_MATH_OVERFLOW<br>
+ on mathematical overflow in size calculation,
+ - DK4_E_MEMORY<br>
+ if no memory is available.
+*/
+wxChar *
+dk4strx_dup(const wxChar *src, dk4_er_t *erp);
+
+#endif
+/* if (defined(_WIN32) ... */
+
+/** Remove trailing white spaces.
+ @param str String to remove white spaces from.
+ @param whsp White spaces set.
+*/
+void
+dk4strx_rtwh(wxChar *str, const wxChar *whsp);
+
+/** Remove trailing newline from line.
+ @param lptr Line pointer.
+*/
+void
+dk4strx_delnl(wxChar *lptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4strx.h"
+
+
+#if DK4_SIZEOF_WXCHAR > 1
+#include "dk4strw.h"
+#else
+#include "dk4str8.h"
+#endif
+
+
+
+$!trace-include
+
+
+
+int
+dk4strx_cpy_s(wxChar *dst, size_t sz, const wxChar *src, dk4_er_t *erp)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4strw_cpy_s(dst, sz, src, erp));
+#else
+ return (dk4str8_cpy_s(dst, sz, src, erp));
+#endif
+}
+
+
+
+int
+dk4strx_cat_s(wxChar *dst, size_t sz, const wxChar *src, dk4_er_t *erp)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4strw_cat_s(dst, sz, src, erp));
+#else
+ return (dk4str8_cat_s(dst, sz, src, erp));
+#endif
+}
+
+
+
+void
+dk4strx_cpy_to_left(wxChar *dst, const wxChar *src)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ dk4strw_cpy_to_left(dst, src);
+#else
+ dk4str8_cpy_to_left(dst, src);
+#endif
+}
+
+
+
+size_t
+dk4strx_len(const wxChar *src)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4strw_len(src));
+#else
+ return (dk4str8_len(src));
+#endif
+}
+
+
+
+int
+dk4strx_cmp(const wxChar *s1, const wxChar *s2)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4strw_cmp(s1, s2));
+#else
+ return (dk4str8_cmp(s1, s2));
+#endif
+}
+
+
+
+int
+dk4strx_casecmp(const wxChar *s1, const wxChar *s2)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4strw_casecmp(s1, s2));
+#else
+ return (dk4str8_casecmp(s1, s2));
+#endif
+}
+
+
+
+int
+dk4strx_pathcmp(const wxChar *s1, const wxChar *s2)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4strw_pathcmp(s1, s2));
+#else
+ return (dk4str8_pathcmp(s1, s2));
+#endif
+}
+
+
+
+wxChar *
+dk4strx_chr(const wxChar *s, wxChar c)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4strw_chr(s, c));
+#else
+ return (dk4str8_chr(s, c));
+#endif
+}
+
+
+
+wxChar *
+dk4strx_rchr(const wxChar *s, wxChar c)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4strw_rchr(s, c));
+#else
+ return (dk4str8_rchr(s, c));
+#endif
+}
+
+
+
+wxChar *
+dk4strx_sep(wxChar **stringp, const wxChar *delim)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4strw_sep(stringp, delim));
+#else
+ return (dk4str8_sep(stringp, delim));
+#endif
+}
+
+
+
+wxChar *
+dk4strx_start(const wxChar *src, const wxChar *delim)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4strw_start(src, delim));
+#else
+ return (dk4str8_start(src, delim));
+#endif
+}
+
+
+
+wxChar *
+dk4strx_next(wxChar *src, const wxChar *delim)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4strw_next(src, delim));
+#else
+ return (dk4str8_next(src, delim));
+#endif
+}
+
+
+
+size_t
+dk4strx_tokenize(
+ wxChar **dpp, size_t szdpp, wxChar *src, const wxChar *delim, dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4strw_tokenize(dpp, szdpp, src, delim, erp));
+#else
+ return (dk4str8_tokenize(dpp, szdpp, src, delim, erp));
+#endif
+}
+
+
+
+void
+dk4strx_normalize(wxChar *src, const wxChar *delim)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ dk4strw_normalize(src, delim);
+#else
+ dk4str8_normalize(src, delim);
+#endif
+}
+
+
+
+int
+dk4strx_array_index(const wxChar * const *arr, const wxChar *str, int cs)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4strw_array_index(arr, str, cs));
+#else
+ return (dk4str8_array_index(arr, str, cs));
+#endif
+}
+
+
+
+int
+dk4strx_abbr_index(
+ const wxChar * const *arr,
+ wxChar spec,
+ const wxChar *str,
+ int cs
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4strw_abbr_index(arr, spec, str, cs));
+#else
+ return (dk4str8_abbr_index(arr, spec, str, cs));
+#endif
+}
+
+
+
+int
+dk4strx_is_abbr(const wxChar *str, const wxChar *pattern, wxChar spec, int cs)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4strw_is_abbr(str, pattern, spec, cs));
+#else
+ return (dk4str8_is_abbr(str, pattern, spec, cs));
+#endif
+}
+
+
+
+int
+dk4strx_is_bool(const wxChar *str)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4strw_is_bool(str));
+#else
+ return (dk4str8_is_bool(str));
+#endif
+}
+
+
+
+int
+dk4strx_is_on(const wxChar *str)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4strw_is_on(str));
+#else
+ return (dk4str8_is_on(str));
+#endif
+}
+
+
+
+#if (defined(_WIN32) && DK4_USE_WINDOWS_LOCAL_ALLOC) \
+ || (DK4_HAVE_MALLOC && DK4_HAVE_FREE)
+
+wxChar *
+dk4strx_dup(const wxChar *src, dk4_er_t *erp)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ return (dk4strw_dup(src, erp));
+#else
+ return (dk4str8_dup(src, erp));
+#endif
+}
+
+#endif
+/* if (defined(_WIN32) ... */
+
+void
+dk4strx_rtwh(wxChar *str, const wxChar *whsp)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ dk4strw_rtwh(str, whsp);
+#else
+ dk4str8_rtwh(str, whsp);
+#endif
+}
+
+
+
+void
+dk4strx_delnl(wxChar *lptr)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+ dk4strw_delnl(lptr);
+#else
+ dk4str8_delnl(lptr);
+#endif
+}
+
diff --git a/support/dktools/dk4strx.h b/support/dktools/dk4strx.h
new file mode 100644
index 0000000000..cadf1843bc
--- /dev/null
+++ b/support/dktools/dk4strx.h
@@ -0,0 +1,347 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4strx.cpt
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4STRX_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4STRX_H_INCLUDED 1
+
+
+#line 8 "dk4strx.cpt"
+
+/** @file dk4strx.h String functions for wxChar.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4CONST_H_INCLUDED
+#include "dk4const.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4WXCS_H_INCLUDED
+#include "dk4wxcs.h"
+#endif
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Copy string, check destination buffer size.
+ @param dst Destination buffer address.
+ @param sz Destination buffer size.
+ @param src Source string.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dst or src is NULL or sz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the dst buffer is too small.
+*/
+int
+dk4strx_cpy_s(wxChar *dst, size_t sz, const wxChar *src, dk4_er_t *erp);
+
+/** Concatenate strings, check destination buffer size.
+ @param dst Destination buffer address.
+ @param sz Destination buffer size.
+ @param src Source string.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dst or src is NULL or sz is 0,
+ - DK4_E_MATH_OVERFLOW<br>
+ if a mathematical overflow occured in size calculation,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the concatenated string doest not fit into the buffer.
+*/
+int
+dk4strx_cat_s(wxChar *dst, size_t sz, const wxChar *src, dk4_er_t *erp);
+
+/** Copy characters within a string from right to left.
+ This copy operation is intended for moving characters within
+ one string from right to left, making the string shorter
+ as is. This function does not check buffer size or report
+ any error.
+ For normal string copy operations, use the dk4strx_cpy_s()
+ function instead.
+ @param dst Destination buffer address.
+ @param src Source string.
+*/
+void
+dk4strx_cpy_to_left(wxChar *dst, const wxChar *src);
+
+/** Find string length.
+ @param src Source string.
+ @return String length.
+*/
+size_t
+dk4strx_len(const wxChar *src);
+
+/** Compare two strings.
+ @param s1 Left string, may be NULL.
+ @param s2 Right string, may be NULL.
+ @return 1 if s1>s2, 0 if s1==s2, -1 if s1<s2.
+*/
+int
+dk4strx_cmp(const wxChar *s1, const wxChar *s2);
+
+/** Compare two strings, case-insensitive comparison.
+ @param s1 Left string, may be NULL.
+ @param s2 Right string, may be NULL.
+ @return 1 if s1>s2, 0 if s1==s2, -1 if s1<s2.
+*/
+int
+dk4strx_casecmp(const wxChar *s1, const wxChar *s2);
+
+/** Compare two file path names.
+ @param s1 Left string, may be NULL.
+ @param s2 Right string, may be NULL.
+ @return 1 if s1>s2, 0 if s1==s2, -1 if s1<s2.
+*/
+int
+dk4strx_pathcmp(const wxChar *s1, const wxChar *s2);
+
+/** Find first occurance of character c in string s.
+ @param s String to search for c.
+ @param c Character to find.
+ @return Pointer to first occurance if found, NULL otherwise.
+*/
+wxChar *
+dk4strx_chr(const wxChar *s, wxChar c);
+
+/** Find last occurance of character c in string s.
+ @param s String to search for c.
+ @param c Character to find.
+ @return Pointer to last occurance if found, NULL otherwise.
+*/
+wxChar *
+dk4strx_rchr(const wxChar *s, wxChar c);
+
+/** Retrieve first token from *stringp.
+ @param stringp Adress of string pointer.
+ @param delim String containing the delimiter set,
+ my be NULL to use the default delimiter
+ set (space, tabulator, carriage return and newline).
+ @return Pointer to first token on success, NULL if no (further)
+ token found.
+*/
+wxChar *
+dk4strx_sep(wxChar **stringp, const wxChar *delim);
+
+/** Find first token in string.
+ @param src String to search for tokens.
+ @param delim String containing the delimiter characters,
+ may be NULL to use the default delimiter set.
+ @return Pointer to first token if found, NULL otherwise.
+*/
+wxChar *
+dk4strx_start(const wxChar *src, const wxChar *delim);
+
+/** Cut string after first token, find start of second token in string.
+ @param src String to search for tokens,
+ normally the result of dk4strx_start() or a
+ previous dk4strx_next() call.
+ @param delim String containing the delimiter characters,
+ may be NULL to use the default delimiter set.
+ @return Pointer to second token if found, NULL otherwise.
+*/
+wxChar *
+dk4strx_next(wxChar *src, const wxChar *delim);
+
+/** Split a string into tokens.
+ @param dpp Pointer to string pointer array.
+ @param szdpp Size of destination string pointer array.
+ @param src Source string to process.
+ @param delim String containing delimiter characters,
+ may be NULL to use the default delimiter set.
+ @param erp Error report, may be NULL.
+ @return Number of tokens found on success, 0 if no token
+ found or on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ for invalid function arguments,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ with dt.mem.nelem set to the number of tokens in string if the dpp
+ array is too short.
+*/
+size_t
+dk4strx_tokenize(
+ wxChar **dpp, size_t szdpp, wxChar *src, const wxChar *delim, dk4_er_t *erp
+);
+
+/** Normalize a string (remove leading and trailing delimiters,
+ replace delimiter sequences by just one delimiter).
+ @param src Buffer containing the string to normalize.
+ @param delim String containing delimiter characters,
+ may be NULL to use the default delimiter set.
+*/
+void
+dk4strx_normalize(wxChar *src, const wxChar *delim);
+
+/** Find index of a string in an array of strings.
+ @param arr Array of strings.
+ @param str String to find in array.
+ @param cs Flag: Case-sensitive search (0=no, other=yes).
+ @return Non-negative index value on success, -1 on error.
+*/
+int
+dk4strx_array_index(const wxChar * const *arr, const wxChar *str, int cs);
+
+/** Find index of a string in an array of strings.
+ @param arr Array of strings allowing abbreviation.
+ @param spec Special character indicating start of optional text.
+ @param str String to find in array.
+ @param cs Flag: Case-sensitive search (0=no, other=yes).
+ @return Non-negative index value on success, -1 on error.
+*/
+int
+dk4strx_abbr_index(
+ const wxChar * const *arr,
+ wxChar spec,
+ const wxChar *str,
+ int cs
+);
+
+/** Check whether a text matches a pattern, the text may be abbreviated.
+ @param str Text to check.
+ @param pattern Pattern for comparison.
+ @param spec Special character marking the abbreviation in the
+ pattern.
+ @param cs Flag: Case sensitive (1) or not (0).
+ @return 1 for a match, 0 otherwise.
+*/
+int
+dk4strx_is_abbr(const wxChar *str, const wxChar *pattern, wxChar spec, int cs);
+
+/** Check whether a string represents a boolean value.
+ @param str String to check.
+ @return 1 if str represents a boolean value, 0 otherwise.
+*/
+int
+dk4strx_is_bool(const wxChar *str);
+
+/** Check whether a string represents the boolean value TRUE.
+ @param str String to check.
+ @return 1 if str represents the boolean value TRUE, 0 otherwise.
+*/
+int
+dk4strx_is_on(const wxChar *str);
+
+#if (defined(_WIN32) && DK4_USE_WINDOWS_LOCAL_ALLOC) \
+ || (DK4_HAVE_MALLOC && DK4_HAVE_FREE)
+
+/** Duplicate string in dynamically allocated memory.
+ @param src String to duplicate.
+ @param erp Error report, may be NULL.
+ @return Pointer to string in new memory on succes, NULL on error.
+ Use dk4mem_free() to release the memory after usage.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if src is a NULL pointer,
+ - DK4_E_MATH_OVERFLOW<br>
+ on mathematical overflow in size calculation,
+ - DK4_E_MEMORY<br>
+ if no memory is available.
+*/
+wxChar *
+dk4strx_dup(const wxChar *src, dk4_er_t *erp);
+
+#endif
+/* if (defined(_WIN32) ... */
+
+/** Remove trailing white spaces.
+ @param str String to remove white spaces from.
+ @param whsp White spaces set.
+*/
+void
+dk4strx_rtwh(wxChar *str, const wxChar *whsp);
+
+/** Remove trailing newline from line.
+ @param lptr Line pointer.
+*/
+void
+dk4strx_delnl(wxChar *lptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4stt.c b/support/dktools/dk4stt.c
new file mode 100644
index 0000000000..d1f9417479
--- /dev/null
+++ b/support/dktools/dk4stt.c
@@ -0,0 +1,397 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4stt.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4stt.c The dk4stt module.
+*/
+
+
+#line 99 "dk4stt.ctr"
+
+#include "dk4error.h"
+#include "dk4mem.h"
+#include "dk4strd.h"
+#include "dk4strm.h"
+#include "dk4stt.h"
+#include "dk4tspdk.h"
+#include "dk4enc.h"
+
+
+
+
+#line 110 "dk4stt.ctr"
+
+
+
+void
+dk4stt_close(dk4_string_table_t *ptr)
+{
+ dkChar **stptr;
+ size_t nstrings;
+
+
+#line 119 "dk4stt.ctr"
+ if (NULL != ptr) {
+ if (NULL != ptr->strings) {
+ stptr = ptr->strings;
+ nstrings = ptr->nstrings;
+ while (0 < nstrings--) {
+ dk4mem_release(*stptr);
+ stptr++;
+ }
+ dk4mem_release(ptr->strings);
+ }
+ dk4mem_release(ptr->shrtfn);
+ ptr->nstrings = 0;
+ dk4mem_free(ptr);
+ }
+
+#line 133 "dk4stt.ctr"
+}
+
+
+
+dk4_string_table_t *
+dk4stt_open(const dkChar *fn, size_t sz, dk4_er_t *erp)
+{
+ dk4_string_table_t *back = NULL;
+ dkChar **stptr = NULL;
+ int ok = 0;
+
+
+#line 144 "dk4stt.ctr"
+ if ((NULL != fn) && (0 < sz)) {
+ back = dk4mem_new(dk4_string_table_t,1,erp);
+ if (NULL != back) {
+ back->strings = NULL;
+ back->nstrings = 0;
+ back->shrtfn = dk4str_dup(fn, erp);
+ if (NULL != back->shrtfn) {
+ back->nstrings = sz;
+ back->strings = dk4mem_new(DK4_PDKCHAR,sz,erp);
+ if (NULL != back->strings) {
+ stptr = back->strings;
+ while (0 < sz--) { *(stptr++) = NULL; }
+ ok = 1;
+ }
+ }
+ if (1 > ok) {
+ dk4stt_close(back);
+ back = NULL;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 167 "dk4stt.ctr"
+ return back;
+}
+
+
+
+int
+dk4stt_compare(const void *l, const void *r, int cr)
+{
+ int back = 0;
+ const dk4_string_table_t *pl;
+ const dk4_string_table_t *pr;
+
+ if (NULL != l) {
+ if (NULL != r) {
+ pl = (const dk4_string_table_t *)l;
+ switch (cr) {
+ case 1: {
+ if (NULL != pl->shrtfn) {
+ back = dk4str_cmp(pl->shrtfn, (const dkChar *)r);
+ } else {
+ back = -1;
+ }
+ } break;
+ default: {
+ pr = (const dk4_string_table_t *)r;
+ if (NULL != pl->shrtfn) {
+ if (NULL != pr->shrtfn) {
+ back = dk4str_cmp(pl->shrtfn, pr->shrtfn);
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != pr->shrtfn) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != r) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Structure to read a string table from stream.
+*/
+typedef struct {
+ dk4_string_table_t *dptr; /**< String table to configure. */
+ size_t curpos; /**< Current line number. */
+} dk4_string_table_reader_t;
+
+
+
+/** Handler function for text lines.
+ @param obj Object to modify while processing the character.
+ @param line Text line to process.
+ @param lineno Current line number.
+ @param erp Error report, may be NULL.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+dk4stt_line_handler(
+ void *obj,
+ dkChar *line,
+ dk4_um_t lineno,
+ dk4_er_t *erp
+)
+{
+ dk4_string_table_reader_t *reader; /* Reader structure */
+#if TRACE_DEBUG
+ dkChar *olcp; /* Original pointer */
+#endif
+ dkChar *linecp; /* Copy of line */
+ int back = DK4_TSP_RES_ERROR;
+
+
+#line 255 "dk4stt.ctr"
+ reader = (dk4_string_table_reader_t *)obj;
+ if (dkT('#') != line[0]) {
+
+#line 257 "dk4stt.ctr"
+ if (reader->curpos < reader->dptr->nstrings) {
+
+#line 258 "dk4stt.ctr"
+ linecp = dk4str_dup(line, NULL);
+ if (NULL != linecp) {
+
+#line 260 "dk4stt.ctr"
+#if TRACE_DEBUG
+ olcp = linecp;
+#endif
+ /* Save copy of line to string table */
+ (reader->dptr->strings)[reader->curpos] = linecp;
+ reader->curpos += 1;
+ back = DK4_TSP_RES_OK;
+ /* Handle backslash escape sequences, remove trailing newline */
+ while (dkT('\0') != *linecp) {
+ if (dkT('\\') == *linecp) {
+ if (dkT('r') == linecp[1]) {
+ *linecp = dkT('\r');
+ dk4str_cpy_to_left(&(linecp[1]), &(linecp[2]));
+ } else {
+ if (dkT('n') == linecp[1]) {
+ *linecp = dkT('\n');
+ dk4str_cpy_to_left(&(linecp[1]), &(linecp[2]));
+ } else {
+ if (dkT('t') == linecp[1]) {
+ *linecp = dkT('\t');
+ dk4str_cpy_to_left(&(linecp[1]), &(linecp[2]));
+ } else {
+ dk4str_cpy_to_left(linecp, &(linecp[1]));
+ if (dkT('\0') == *linecp) { linecp--; }
+ }
+ }
+ }
+ } else {
+ if (dkT('\n') == *linecp) {
+ *linecp = dkT('\0');
+ linecp--;
+ } else {
+ if ((dkT('\r') == *linecp) && (dkT('\n') == linecp[1])) {
+ *linecp = dkT('\0');
+ linecp--;
+ }
+ }
+ }
+ linecp++;
+ }
+
+#line 300 "dk4stt.ctr"
+ } else {
+
+#line 301 "dk4stt.ctr"
+ /* Not enough memory. */
+ back = DK4_TSP_RES_FATAL;
+ }
+ } else {
+
+#line 305 "dk4stt.ctr"
+ /* More lines than expected, ignore additional lines. */
+ back = DK4_TSP_RES_OK;
+ }
+ } else {
+
+#line 309 "dk4stt.ctr"
+ /* Comment line, no processing required. */
+ back = DK4_TSP_RES_OK;
+ }
+
+#line 312 "dk4stt.ctr"
+ return back;
+}
+
+
+
+int
+dk4stt_apply_stream(
+ dk4_string_table_t *tptr,
+ dk4_stream_t *strm,
+ int pre,
+ dk4_er_t *erp1,
+ dk4_er_t *erp2
+)
+{
+ dkChar line[1024]; /* Input line buffer */
+ char buf[4096]; /* Buffer for stream input */
+ dk4_string_table_reader_t reader; /* Reader structure */
+ dk4_tspdk_t tspdk; /* Text stream processor */
+ dk4_er_t e1; /* Error report f decoding */
+ dk4_er_t e2; /* Error report f processing */
+ size_t rdb; /* Bytes read */
+ int cc; /* Flag: Can continue */
+ int back = 0;
+
+
+#line 336 "dk4stt.ctr"
+ if ((NULL != tptr) && (NULL != strm)) {
+
+#line 337 "dk4stt.ctr"
+ dk4error_init(&e1);
+ dk4error_init(&e2);
+ reader.dptr = tptr;
+ reader.curpos = 0;
+ back = dk4tspdk_setup_line(
+ &tspdk, (void *)(&reader), dk4stt_line_handler,
+ line, DK4_SIZEOF(line,dkChar),
+ pre, DK4_FILE_ENCODING_UTF8, &e2
+ );
+ if (0 < back) {
+
+#line 347 "dk4stt.ctr"
+#if VERSION_BEFORE_20150821
+ cc = 1;
+#endif
+ do {
+ cc = 0;
+ rdb = sizeof(buf);
+ if (0 < dk4stream_read(buf, &rdb, strm, NULL)) {
+ if (0 < rdb) {
+
+#line 355 "dk4stt.ctr"
+ switch (dk4tspdk_add_bytes(&tspdk, (unsigned char *)buf, rdb)) {
+ case DK4_TSP_RES_OK: {
+
+#line 357 "dk4stt.ctr"
+ cc = 1;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+
+#line 360 "dk4stt.ctr"
+ cc = 1;
+ } break;
+ default: {
+
+#line 363 "dk4stt.ctr"
+ back = 0;
+ } break;
+ }
+ } else {
+
+#line 367 "dk4stt.ctr"
+ }
+ } else {
+
+#line 369 "dk4stt.ctr"
+ }
+ } while (cc);
+ if (0 < back) {
+
+#line 372 "dk4stt.ctr"
+ if (DK4_TSP_RES_FATAL == dk4tspdk_finish(&tspdk)) {
+ back = 0;
+
+#line 374 "dk4stt.ctr"
+ }
+ if (0 < back) {
+
+#line 376 "dk4stt.ctr"
+ if (reader.curpos < (reader.dptr)->nstrings) {
+ back = 0;
+
+#line 378 "dk4stt.ctr"
+
+
+#line 379 "dk4stt.ctr"
+
+
+#line 380 "dk4stt.ctr"
+ }
+ }
+ }
+ } else {
+
+#line 384 "dk4stt.ctr"
+ }
+ } else {
+
+#line 386 "dk4stt.ctr"
+ dk4error_set_simple_error_code(erp2, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 388 "dk4stt.ctr"
+ return back;
+}
+
+
diff --git a/support/dktools/dk4stt.ctr b/support/dktools/dk4stt.ctr
new file mode 100644
index 0000000000..c25271ed27
--- /dev/null
+++ b/support/dktools/dk4stt.ctr
@@ -0,0 +1,391 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ String table data type.
+ Normally there is no need for you to deal with string tables
+ manually. String tables are handled by the dk4_app_t related
+ functions.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4STRM_H_INCLUDED
+#include "dk4strm.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+/** String table.
+*/
+typedef struct {
+ dkChar *shrtfn; /**< Short file name. */
+ dkChar **strings; /**< Strings read from file. */
+ size_t nstrings; /**< Number of strings. */
+} dk4_string_table_t;
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Create string table from file.
+ @param fn Short file name to store in structure.
+ @param sz Number of lines required.
+ @param erp Error report, may be NULL.
+ @return Pointer to new string table structure on success, NULL
+ on error.
+*/
+dk4_string_table_t *
+dk4stt_open(const dkChar *fn, size_t sz, dk4_er_t *erp);
+
+/** Apply a text stream to a string table.
+ @param tptr String table to configure.
+ @param strm Text stream, opened for reading.
+ @param pre Processing encoding.
+ @param erp1 Error report for decoding/encoding, may be NULL.
+ @param erp2 Error report for processing, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4stt_apply_stream(
+ dk4_string_table_t *tptr,
+ dk4_stream_t *strm,
+ int pre,
+ dk4_er_t *erp1,
+ dk4_er_t *erp2
+);
+
+/** Destroy a string table, free allocated memory.
+ @param ptr String table to destroy.
+*/
+void
+dk4stt_close(dk4_string_table_t *ptr);
+
+/** Compare two string tables by short name.
+ @param l Left pointer (always string table).
+ @param r Right pointer (string table or short name).
+ @param cr Comparison criteria
+ (0=string table/string table,
+ 1=string table/short name).
+ @return Comparison result.
+*/
+int
+dk4stt_compare(const void *l, const void *r, int cr);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4error.h"
+#include "dk4mem.h"
+#include "dk4strd.h"
+#include "dk4strm.h"
+#include "dk4stt.h"
+#include "dk4tspdk.h"
+#include "dk4enc.h"
+
+
+$!trace-include
+
+
+
+void
+dk4stt_close(dk4_string_table_t *ptr)
+{
+ dkChar **stptr;
+ size_t nstrings;
+ $? "+ dk4stt_close"
+ if (NULL != ptr) {
+ if (NULL != ptr->strings) {
+ stptr = ptr->strings;
+ nstrings = ptr->nstrings;
+ while (0 < nstrings--) {
+ dk4mem_release(*stptr);
+ stptr++;
+ }
+ dk4mem_release(ptr->strings);
+ }
+ dk4mem_release(ptr->shrtfn);
+ ptr->nstrings = 0;
+ dk4mem_free(ptr);
+ } $? "- dk4stt_close"
+}
+
+
+
+dk4_string_table_t *
+dk4stt_open(const dkChar *fn, size_t sz, dk4_er_t *erp)
+{
+ dk4_string_table_t *back = NULL;
+ dkChar **stptr = NULL;
+ int ok = 0;
+ $? "+ dk4stt_open \"%!ds\" %u", TR_DKSTR(fn), (unsigned)sz
+ if ((NULL != fn) && (0 < sz)) {
+ back = dk4mem_new(dk4_string_table_t,1,erp);
+ if (NULL != back) {
+ back->strings = NULL;
+ back->nstrings = 0;
+ back->shrtfn = dk4str_dup(fn, erp);
+ if (NULL != back->shrtfn) {
+ back->nstrings = sz;
+ back->strings = dk4mem_new(DK4_PDKCHAR,sz,erp);
+ if (NULL != back->strings) {
+ stptr = back->strings;
+ while (0 < sz--) { *(stptr++) = NULL; }
+ ok = 1;
+ }
+ }
+ if (1 > ok) {
+ dk4stt_close(back);
+ back = NULL;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4stt_open PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+int
+dk4stt_compare(const void *l, const void *r, int cr)
+{
+ int back = 0;
+ const dk4_string_table_t *pl;
+ const dk4_string_table_t *pr;
+
+ if (NULL != l) {
+ if (NULL != r) {
+ pl = (const dk4_string_table_t *)l;
+ switch (cr) {
+ case 1: {
+ if (NULL != pl->shrtfn) {
+ back = dk4str_cmp(pl->shrtfn, (const dkChar *)r);
+ } else {
+ back = -1;
+ }
+ } break;
+ default: {
+ pr = (const dk4_string_table_t *)r;
+ if (NULL != pl->shrtfn) {
+ if (NULL != pr->shrtfn) {
+ back = dk4str_cmp(pl->shrtfn, pr->shrtfn);
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != pr->shrtfn) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != r) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Structure to read a string table from stream.
+*/
+typedef struct {
+ dk4_string_table_t *dptr; /**< String table to configure. */
+ size_t curpos; /**< Current line number. */
+} dk4_string_table_reader_t;
+
+
+
+/** Handler function for text lines.
+ @param obj Object to modify while processing the character.
+ @param line Text line to process.
+ @param lineno Current line number.
+ @param erp Error report, may be NULL.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+dk4stt_line_handler(
+ void *obj,
+ dkChar *line,
+ dk4_um_t lineno,
+ dk4_er_t *erp
+)
+{
+ dk4_string_table_reader_t *reader; /* Reader structure */
+#if TRACE_DEBUG
+ dkChar *olcp; /* Original pointer */
+#endif
+ dkChar *linecp; /* Copy of line */
+ int back = DK4_TSP_RES_ERROR;
+ $? "+ dk4stt_line_handler \"%!ds\"", line
+ reader = (dk4_string_table_reader_t *)obj;
+ if (dkT('#') != line[0]) { $? ". data line %lu", (unsigned long)(reader->curpos)
+ if (reader->curpos < reader->dptr->nstrings) { $? ". need processing"
+ linecp = dk4str_dup(line, NULL);
+ if (NULL != linecp) { $? ". copy allocated"
+#if TRACE_DEBUG
+ olcp = linecp;
+#endif
+ /* Save copy of line to string table */
+ (reader->dptr->strings)[reader->curpos] = linecp;
+ reader->curpos += 1;
+ back = DK4_TSP_RES_OK;
+ /* Handle backslash escape sequences, remove trailing newline */
+ while (dkT('\0') != *linecp) {
+ if (dkT('\\') == *linecp) {
+ if (dkT('r') == linecp[1]) {
+ *linecp = dkT('\r');
+ dk4str_cpy_to_left(&(linecp[1]), &(linecp[2]));
+ } else {
+ if (dkT('n') == linecp[1]) {
+ *linecp = dkT('\n');
+ dk4str_cpy_to_left(&(linecp[1]), &(linecp[2]));
+ } else {
+ if (dkT('t') == linecp[1]) {
+ *linecp = dkT('\t');
+ dk4str_cpy_to_left(&(linecp[1]), &(linecp[2]));
+ } else {
+ dk4str_cpy_to_left(linecp, &(linecp[1]));
+ if (dkT('\0') == *linecp) { linecp--; }
+ }
+ }
+ }
+ } else {
+ if (dkT('\n') == *linecp) {
+ *linecp = dkT('\0');
+ linecp--;
+ } else {
+ if ((dkT('\r') == *linecp) && (dkT('\n') == linecp[1])) {
+ *linecp = dkT('\0');
+ linecp--;
+ }
+ }
+ }
+ linecp++;
+ } $? ". processing result: \"%!ds\"", olcp
+ } else { $? "! memory"
+ /* Not enough memory. */
+ back = DK4_TSP_RES_FATAL;
+ }
+ } else { $? ". additional line"
+ /* More lines than expected, ignore additional lines. */
+ back = DK4_TSP_RES_OK;
+ }
+ } else { $? ". comment line"
+ /* Comment line, no processing required. */
+ back = DK4_TSP_RES_OK;
+ } $? "- dk4stt_line_handler %d", back
+ return back;
+}
+
+
+
+int
+dk4stt_apply_stream(
+ dk4_string_table_t *tptr,
+ dk4_stream_t *strm,
+ int pre,
+ dk4_er_t *erp1,
+ dk4_er_t *erp2
+)
+{
+ dkChar line[1024]; /* Input line buffer */
+ char buf[4096]; /* Buffer for stream input */
+ dk4_string_table_reader_t reader; /* Reader structure */
+ dk4_tspdk_t tspdk; /* Text stream processor */
+ dk4_er_t e1; /* Error report f decoding */
+ dk4_er_t e2; /* Error report f processing */
+ size_t rdb; /* Bytes read */
+ int cc; /* Flag: Can continue */
+ int back = 0;
+ $? "+ dk4stt_apply_stream"
+ if ((NULL != tptr) && (NULL != strm)) { $? ". args ok"
+ dk4error_init(&e1);
+ dk4error_init(&e2);
+ reader.dptr = tptr;
+ reader.curpos = 0;
+ back = dk4tspdk_setup_line(
+ &tspdk, (void *)(&reader), dk4stt_line_handler,
+ line, DK4_SIZEOF(line,dkChar),
+ pre, DK4_FILE_ENCODING_UTF8, &e2
+ );
+ if (0 < back) { $? ". init ok"
+#if VERSION_BEFORE_20150821
+ cc = 1;
+#endif
+ do {
+ cc = 0;
+ rdb = sizeof(buf);
+ if (0 < dk4stream_read(buf, &rdb, strm, NULL)) {
+ if (0 < rdb) { $? ". bytes found"
+ switch (dk4tspdk_add_bytes(&tspdk, (unsigned char *)buf, rdb)) {
+ case DK4_TSP_RES_OK: { $? ". success"
+ cc = 1;
+ } break;
+ case DK4_TSP_RES_ERROR: { $? "! error"
+ cc = 1;
+ } break;
+ default: { $? "! fatal error"
+ back = 0;
+ } break;
+ }
+ } else { $? ". no byte found"
+ }
+ } else { $? ". end of input"
+ }
+ } while (cc);
+ if (0 < back) { $? ". flush final bytes"
+ if (DK4_TSP_RES_FATAL == dk4tspdk_finish(&tspdk)) {
+ back = 0; $? "! flush failed"
+ }
+ if (0 < back) { $? ". flush succeeded"
+ if (reader.curpos < (reader.dptr)->nstrings) {
+ back = 0; $? "! too few lines"
+ $? ". curpos = %lu", (unsigned long)(reader.curpos)
+ $? ". nstrings = %lu", (unsigned long)((reader.dptr)->nstrings)
+ }
+ }
+ }
+ } else { $? "! init"
+ }
+ } else { $? "! args"
+ dk4error_set_simple_error_code(erp2, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4stt_apply_stream %d", back
+ return back;
+}
+
+
diff --git a/support/dktools/dk4stt.h b/support/dktools/dk4stt.h
new file mode 100644
index 0000000000..3edd818bf6
--- /dev/null
+++ b/support/dktools/dk4stt.h
@@ -0,0 +1,132 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4stt.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4STT_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4STT_H_INCLUDED 1
+
+
+#line 9 "dk4stt.ctr"
+
+/** @file
+ String table data type.
+ Normally there is no need for you to deal with string tables
+ manually. String tables are handled by the dk4_app_t related
+ functions.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4STRM_H_INCLUDED
+#include "dk4strm.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+/** String table.
+*/
+typedef struct {
+ dkChar *shrtfn; /**< Short file name. */
+ dkChar **strings; /**< Strings read from file. */
+ size_t nstrings; /**< Number of strings. */
+} dk4_string_table_t;
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Create string table from file.
+ @param fn Short file name to store in structure.
+ @param sz Number of lines required.
+ @param erp Error report, may be NULL.
+ @return Pointer to new string table structure on success, NULL
+ on error.
+*/
+dk4_string_table_t *
+dk4stt_open(const dkChar *fn, size_t sz, dk4_er_t *erp);
+
+/** Apply a text stream to a string table.
+ @param tptr String table to configure.
+ @param strm Text stream, opened for reading.
+ @param pre Processing encoding.
+ @param erp1 Error report for decoding/encoding, may be NULL.
+ @param erp2 Error report for processing, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4stt_apply_stream(
+ dk4_string_table_t *tptr,
+ dk4_stream_t *strm,
+ int pre,
+ dk4_er_t *erp1,
+ dk4_er_t *erp2
+);
+
+/** Destroy a string table, free allocated memory.
+ @param ptr String table to destroy.
+*/
+void
+dk4stt_close(dk4_string_table_t *ptr);
+
+/** Compare two string tables by short name.
+ @param l Left pointer (always string table).
+ @param r Right pointer (string table or short name).
+ @param cr Comparison criteria
+ (0=string table/string table,
+ 1=string table/short name).
+ @return Comparison result.
+*/
+int
+dk4stt_compare(const void *l, const void *r, int cr);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4svbuf.c b/support/dktools/dk4svbuf.c
new file mode 100644
index 0000000000..eb5c75d8ba
--- /dev/null
+++ b/support/dktools/dk4svbuf.c
@@ -0,0 +1,110 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4svbuf.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4svbuf.c The dk4svbuf module.
+*/
+
+
+#line 60 "dk4svbuf.ctr"
+
+
+#include "dk4svbuf.h"
+
+
+
+
+#line 66 "dk4svbuf.ctr"
+
+
+
+/** Buffering type constants.
+*/
+static int buffering_types[] = {
+ _IONBF, _IOLBF, _IOFBF
+};
+
+
+int
+dk4setvbuf(
+ FILE *fipo,
+ dk4_file_buffering_t tp,
+ char *pbuf,
+ size_t szbuf,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+#if DK4_HAVE_SETVBUF
+ int svbres = 0;
+#endif
+ int btp;
+
+ if (NULL != fipo) {
+ btp = (
+ ((0 <= (int)tp) && (3 > (int)tp))
+ ? (buffering_types[(int)tp])
+ : (buffering_types[2])
+ );
+#if DK4_HAVE_SETVBUF
+ svbres = setvbuf(
+ fipo,
+ ((0 < szbuf) ? (pbuf) : (NULL)),
+ (((NULL != pbuf) && (0 < szbuf)) ? (btp) : (buffering_types[0])),
+ szbuf
+ );
+ if (0 == svbres) {
+ back = 1;
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+#if DK4_HAVE_SETBUFFER
+ setbuffer(fipo, pbuf, szbuf);
+ back = 1;
+#else
+ back = 1;
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+#endif
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+/* vim: set ai sw=4 ts=4 : */
+
diff --git a/support/dktools/dk4svbuf.ctr b/support/dktools/dk4svbuf.ctr
new file mode 100644
index 0000000000..4bba80db63
--- /dev/null
+++ b/support/dktools/dk4svbuf.ctr
@@ -0,0 +1,127 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+%% header
+
+/** @file dk4svbuf.h File buffering.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef STDIO_H_INCLUDED
+#include <stdio.h>
+#define STDIO_H_INCLUDED 1
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+/** How to buffer a file.
+*/
+typedef enum {
+ DK4_FILE_NO_BUFFERING = 0 , /**< Do not use buffers. */
+ DK4_FILE_LINE_BUFFERING , /**< Buffer lines. */
+ DK4_FILE_FULL_BUFFERING /**< Full buffering. */
+} dk4_file_buffering_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Set up buffering for a file.
+ @param fipo File to modify.
+ @param tp Buffering type.
+ @param pbuf Start address of buffer to use, may be NULL.
+ @param szbuf Size of buffer, may be 0.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4setvbuf(
+ FILE *fipo,
+ dk4_file_buffering_t tp,
+ char *pbuf,
+ size_t szbuf,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+/* vim: set ai sw=4 ts=4 : */
+%% module
+
+
+#include "dk4svbuf.h"
+
+
+$!trace-include
+
+
+
+/** Buffering type constants.
+*/
+static int buffering_types[] = {
+ _IONBF, _IOLBF, _IOFBF
+};
+
+
+int
+dk4setvbuf(
+ FILE *fipo,
+ dk4_file_buffering_t tp,
+ char *pbuf,
+ size_t szbuf,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+#if DK4_HAVE_SETVBUF
+ int svbres = 0;
+#endif
+ int btp;
+
+ if (NULL != fipo) {
+ btp = (
+ ((0 <= (int)tp) && (3 > (int)tp))
+ ? (buffering_types[(int)tp])
+ : (buffering_types[2])
+ );
+#if DK4_HAVE_SETVBUF
+ svbres = setvbuf(
+ fipo,
+ ((0 < szbuf) ? (pbuf) : (NULL)),
+ (((NULL != pbuf) && (0 < szbuf)) ? (btp) : (buffering_types[0])),
+ szbuf
+ );
+ if (0 == svbres) {
+ back = 1;
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYSTEM);
+ }
+#else
+#if DK4_HAVE_SETBUFFER
+ setbuffer(fipo, pbuf, szbuf);
+ back = 1;
+#else
+ back = 1;
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+#endif
+ }
+ else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+/* vim: set ai sw=4 ts=4 : */
+
diff --git a/support/dktools/dk4svbuf.h b/support/dktools/dk4svbuf.h
new file mode 100644
index 0000000000..a609b79009
--- /dev/null
+++ b/support/dktools/dk4svbuf.h
@@ -0,0 +1,94 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4svbuf.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4SVBUF_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4SVBUF_H_INCLUDED 1
+
+
+#line 8 "dk4svbuf.ctr"
+
+/** @file dk4svbuf.h File buffering.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef STDIO_H_INCLUDED
+#include <stdio.h>
+#define STDIO_H_INCLUDED 1
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+/** How to buffer a file.
+*/
+typedef enum {
+ DK4_FILE_NO_BUFFERING = 0 , /**< Do not use buffers. */
+ DK4_FILE_LINE_BUFFERING , /**< Buffer lines. */
+ DK4_FILE_FULL_BUFFERING /**< Full buffering. */
+} dk4_file_buffering_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Set up buffering for a file.
+ @param fipo File to modify.
+ @param tp Buffering type.
+ @param pbuf Start address of buffer to use, may be NULL.
+ @param szbuf Size of buffer, may be 0.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4setvbuf(
+ FILE *fipo,
+ dk4_file_buffering_t tp,
+ char *pbuf,
+ size_t szbuf,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+/* vim: set ai sw=4 ts=4 : */
+
+#endif
diff --git a/support/dktools/dk4svbufa.c b/support/dktools/dk4svbufa.c
new file mode 100644
index 0000000000..3ae3743205
--- /dev/null
+++ b/support/dktools/dk4svbufa.c
@@ -0,0 +1,90 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4svbufa.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4svbufa.c The dk4svbufa module.
+*/
+
+
+#line 60 "dk4svbufa.ctr"
+
+
+#include "dk4svbufa.h"
+
+
+
+
+
+#line 67 "dk4svbufa.ctr"
+
+
+
+int
+dk4setvbuf_app(
+ FILE *fipo,
+ dk4_file_buffering_t btype,
+ char *pbuf,
+ size_t szbuf,
+ const char *fn,
+ dk4_app_t *app
+)
+{
+ dk4_er_t er;
+ int back = 0;
+ int ll = DK4_LL_ERROR;
+
+ if (NULL != fipo) {
+ dk4error_init(&er);
+ back = dk4setvbuf(fipo, btype, pbuf, szbuf, &er);
+ if (DK4_E_NONE != er.ec) {
+ if (0 != back) {
+ ll = DK4_LL_WARNING;
+ }
+ switch (er.ec) {
+ if (NULL != fn) {
+ dk4app_log_base3(app, ll, 156, 157, fn);
+ }
+ else {
+ dk4app_log_base1(app, ll, 155);
+ }
+ if (DK4_E_NOT_SUPPORTED == er.ec) {
+ dk4app_log_base1(app, ll, 158);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+/* vim: set ai sw=4 ts=4 : */
diff --git a/support/dktools/dk4svbufa.ctr b/support/dktools/dk4svbufa.ctr
new file mode 100644
index 0000000000..955b8a9613
--- /dev/null
+++ b/support/dktools/dk4svbufa.ctr
@@ -0,0 +1,107 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+%% header
+
+/** @file dk4svbufa.h Set file buffer.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef STDIO_H_INCLUDED
+#include <stdio.h>
+#define STDIO_H_INCLUDED 1
+#endif
+
+#ifndef DK4SVBUF_H_INCLUDED
+#include "dk4svbuf.h"
+#endif
+
+#ifndef DK4APP_H_INCLUDED
+#include "dk4app.h"
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Change buffering for FILE.
+ @param fipo File to change buffering for.
+ @param pbuf Address of buffer to use, may be NULL.
+ @param btype Buffering type, one from: _IONBF, _IOLBF or _IOFBF
+ (not buffered, line buffered, fully buffered).
+ @param szbuf Size of buffer, may be 0.
+ @param fn File to to change buffering for, may be NULL.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4setvbuf_app(
+ FILE *fipo,
+ dk4_file_buffering_t btype,
+ char *pbuf,
+ size_t szbuf,
+ const char *fn,
+ dk4_app_t *app
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+/* vim: set ai sw=4 ts=4 : */
+%% module
+
+
+#include "dk4svbufa.h"
+
+
+
+$!trace-include
+
+
+
+int
+dk4setvbuf_app(
+ FILE *fipo,
+ dk4_file_buffering_t btype,
+ char *pbuf,
+ size_t szbuf,
+ const char *fn,
+ dk4_app_t *app
+)
+{
+ dk4_er_t er;
+ int back = 0;
+ int ll = DK4_LL_ERROR;
+
+ if (NULL != fipo) {
+ dk4error_init(&er);
+ back = dk4setvbuf(fipo, btype, pbuf, szbuf, &er);
+ if (DK4_E_NONE != er.ec) {
+ if (0 != back) {
+ ll = DK4_LL_WARNING;
+ }
+ switch (er.ec) {
+ if (NULL != fn) {
+ dk4app_log_base3(app, ll, 156, 157, fn);
+ }
+ else {
+ dk4app_log_base1(app, ll, 155);
+ }
+ if (DK4_E_NOT_SUPPORTED == er.ec) {
+ dk4app_log_base1(app, ll, 158);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+/* vim: set ai sw=4 ts=4 : */
diff --git a/support/dktools/dk4svbufa.h b/support/dktools/dk4svbufa.h
new file mode 100644
index 0000000000..ef279fb714
--- /dev/null
+++ b/support/dktools/dk4svbufa.h
@@ -0,0 +1,94 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4svbufa.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4SVBUFA_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4SVBUFA_H_INCLUDED 1
+
+
+#line 8 "dk4svbufa.ctr"
+
+/** @file dk4svbufa.h Set file buffer.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef STDIO_H_INCLUDED
+#include <stdio.h>
+#define STDIO_H_INCLUDED 1
+#endif
+
+#ifndef DK4SVBUF_H_INCLUDED
+#include "dk4svbuf.h"
+#endif
+
+#ifndef DK4APP_H_INCLUDED
+#include "dk4app.h"
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Change buffering for FILE.
+ @param fipo File to change buffering for.
+ @param pbuf Address of buffer to use, may be NULL.
+ @param btype Buffering type, one from: _IONBF, _IOLBF or _IOFBF
+ (not buffered, line buffered, fully buffered).
+ @param szbuf Size of buffer, may be 0.
+ @param fn File to to change buffering for, may be NULL.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4setvbuf_app(
+ FILE *fipo,
+ dk4_file_buffering_t btype,
+ char *pbuf,
+ size_t szbuf,
+ const char *fn,
+ dk4_app_t *app
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+/* vim: set ai sw=4 ts=4 : */
+
+#endif
diff --git a/support/dktools/dk4symlink.c b/support/dktools/dk4symlink.c
new file mode 100644
index 0000000000..39f4fb57ea
--- /dev/null
+++ b/support/dktools/dk4symlink.c
@@ -0,0 +1,365 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4symlink.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4symlink.c The dk4symlink module.
+*/
+
+
+#line 61 "dk4symlink.ctr"
+
+#include "dk4symlink.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#if DK4_HAVE_NTIFS_H
+#ifndef NTIFS_H_INCLUDED
+#include <ntifs.h>
+#define NTIFS_H_INCLUDED 1
+#endif
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4mpl.h"
+#include "dk4mem.h"
+#include "dk4strd.h"
+
+
+
+
+
+#line 98 "dk4symlink.ctr"
+
+
+
+#if DK4_ON_WINDOWS
+
+#if !DK4_HAVE_NTIFS_H
+
+typedef struct _REPARSE_DATA_BUFFER {
+ ULONG ReparseTag;
+ USHORT ReparseDataLength;
+ USHORT Reserved;
+ union {
+ struct {
+ USHORT SubstituteNameOffset;
+ USHORT SubstituteNameLength;
+ USHORT PrintNameOffset;
+ USHORT PrintNameLength;
+ ULONG Flags;
+ WCHAR PathBuffer[1];
+ } SymbolicLinkReparseBuffer;
+ struct {
+ USHORT SubstituteNameOffset;
+ USHORT SubstituteNameLength;
+ USHORT PrintNameOffset;
+ USHORT PrintNameLength;
+ WCHAR PathBuffer[1];
+ } MountPointReparseBuffer;
+ struct {
+ UCHAR DataBuffer[1];
+ } GenericReparseBuffer;
+ };
+} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
+
+#endif
+
+
+#if defined(FSCTL_GET_REPARSE_POINT)
+/** Size of reparse point information for a symlink.
+*/
+#define SYMLINK_INFO_SIZE ((8 * (DK4_MAX_PATH))+sizeof(REPARSE_DATA_BUFFER))
+/** The above size aligned to 16 bytes.
+*/
+#define SYMLINK_INFO_ALIGNED (16 * (((SYMLINK_INFO_SIZE) / 16) + 1))
+
+#ifdef MAXIMUM_REPARSE_DATA_BUFFER_SIZE
+#define SYMLINK_BUFFER_SIZE \
+(MAXIMUM_REPARSE_DATA_BUFFER_SIZE + SYMLINK_INFO_ALIGNED)
+#endif
+#endif
+
+/** Copy path name from reparse point buffer to destination buffer.
+ @param bptr Destination buffer.
+ @param szb Destination buffer size (number of wchar_t).
+ @param sptr Source pointer.
+ @param offs Offset of path name in source (in bytes).
+ @param length Length of path name (in bytes).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4symlink_copy_string(
+ wchar_t *bptr,
+ size_t szb,
+ const wchar_t *sptr,
+ USHORT offs,
+ USHORT length,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+ if ((length / sizeof(wchar_t)) < szb) {
+ DK4_MEMCPY(bptr,&(sptr[offs / sizeof(wchar_t)]),length);
+ bptr[length / sizeof(wchar_t)] = L'\0';
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ return back;
+}
+
+#endif
+
+int
+dk4symlink_target(dkChar *bptr, size_t szb, const dkChar *fn, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+#if defined(FSCTL_GET_REPARSE_POINT)
+ char repdabuf[SYMLINK_BUFFER_SIZE];
+ REPARSE_DATA_BUFFER *rdb;
+#endif
+ HANDLE fh;
+ DWORD dwres;
+ BOOL result;
+#else
+ ssize_t res;
+#endif
+ int back = 0;
+
+
+
+#line 198 "dk4symlink.ctr"
+ if ((NULL != bptr) && (NULL != fn) && (0 < szb)) {
+ *bptr = dkT('\0');
+#if DK4_ON_WINDOWS
+#if DK4_CHAR_SIZE > 1
+#if DK4_HAVE_GETFINALPATHNAMEBYHANDLE
+ fh = CreateFileW(
+ fn,
+ FILE_READ_ATTRIBUTES,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ NULL
+ );
+ if (INVALID_HANDLE_VALUE != fh) {
+ dwres = GetFinalPathNameByHandleW(fh, bptr, (DWORD)szb, 0);
+ if (0 < dwres) {
+ if (dwres < (DWORD)szb) {
+ back = 1;
+ }
+ }
+ CloseHandle(fh);
+ }
+#else
+
+
+#line 223 "dk4symlink.ctr"
+#endif
+ if (0 == back) {
+#if defined(FSCTL_GET_REPARSE_POINT)
+ /* !!!!! Second attempt with legacy procedure */
+
+
+#line 228 "dk4symlink.ctr"
+ fh = CreateFileW(
+ fn,
+ FILE_READ_ATTRIBUTES,
+ (FILE_SHARE_READ | FILE_SHARE_WRITE),
+ NULL,
+ OPEN_EXISTING,
+ (
+ FILE_FLAG_BACKUP_SEMANTICS
+ | FILE_FLAG_OPEN_REPARSE_POINT
+ | FILE_ATTRIBUTE_REPARSE_POINT
+ ),
+ NULL
+ );
+ if (INVALID_HANDLE_VALUE != fh) {
+ dwres = 0;
+
+#line 243 "dk4symlink.ctr"
+ result = DeviceIoControl(
+ fh,
+ FSCTL_GET_REPARSE_POINT,
+ NULL,
+ (DWORD)0U,
+ (void *)repdabuf,
+ (DWORD)sizeof(repdabuf),
+ &dwres,
+ NULL
+ );
+ if (result) {
+
+#line 254 "dk4symlink.ctr"
+ rdb = (REPARSE_DATA_BUFFER *)repdabuf;
+ if (IO_REPARSE_TAG_MOUNT_POINT == rdb->ReparseTag) {
+
+
+#line 257 "dk4symlink.ctr"
+ back = dk4symlink_copy_string(
+ bptr, szb,
+ &(rdb->MountPointReparseBuffer.PathBuffer[0]),
+ rdb->MountPointReparseBuffer.SubstituteNameOffset,
+ rdb->MountPointReparseBuffer.SubstituteNameLength,
+ erp
+ );
+ } else {
+ if (IO_REPARSE_TAG_SYMLINK == rdb->ReparseTag) {
+
+
+#line 267 "dk4symlink.ctr"
+ back = dk4symlink_copy_string(
+ bptr, szb,
+ &(rdb->SymbolicLinkReparseBuffer.PathBuffer[0]),
+ rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset,
+ rdb->SymbolicLinkReparseBuffer.SubstituteNameLength,
+ erp
+ );
+ } else {
+ /* !!!!! Not mount point, not symlink */
+
+
+#line 277 "dk4symlink.ctr"
+ }
+ }
+ } else {
+
+#line 280 "dk4symlink.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ CloseHandle(fh);
+ } else {
+
+#line 284 "dk4symlink.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ }
+#else
+#if DK4_HAVE_GETFINALPATHNAMEBYHANDLE
+ fh = CreateFileA(
+ fn,
+ FILE_READ_ATTRIBUTES,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ NULL
+ );
+ if (INVALID_HANDLE_VALUE != fh) {
+ dwres = GetFinalPathNameByHandleA(fh, bptr, (DWORD)szb, 0);
+ if (0 < dwres) {
+ if (dwres < (DWORD)szb) {
+ back = 1;
+ }
+ }
+ CloseHandle(fh);
+ }
+#else
+ /* Legacy procedure only available for wchar_t.
+ */
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+#endif
+ if (0 < back) {
+ if (dkT('\\') == bptr[0]) {
+ if ((dkT('\\') == bptr[1]) || (dkT('?') == bptr[1])) {
+ if (dkT('?') == bptr[2]) {
+ if (dkT('\\') == bptr[3]) {
+ if (260 > dk4str_len(&(bptr[4]))) {
+ dk4str_cpy_to_left(bptr, &(bptr[4]));
+ }
+ }
+ }
+ }
+ }
+ }
+#else
+#if DK4_CHAR_SIZE > 1
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#else
+ errno = 0;
+ res = readlink(fn, bptr, szb);
+ if (0 < res) {
+ if (res < szb) {
+ bptr[res] = dkT('\0');
+ back = 1;
+ } else {
+
+#line 340 "dk4symlink.ctr"
+ bptr[0] = dkT('\0');
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+
+#line 344 "dk4symlink.ctr"
+ bptr[0] = dkT('\0');
+ if (0 > res) {
+ dk4error_set_idetails(erp, DK4_E_SYSTEM, errno);
+ }
+ }
+#endif
+#endif
+ if (0 == back) { *bptr = dkT('\0'); }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 355 "dk4symlink.ctr"
+ return back;
+}
+
diff --git a/support/dktools/dk4symlink.ctr b/support/dktools/dk4symlink.ctr
new file mode 100644
index 0000000000..1b3138b0e6
--- /dev/null
+++ b/support/dktools/dk4symlink.ctr
@@ -0,0 +1,357 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk4symlink.h Find symbolic link target.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Find target for symbolic link.
+ @param bptr Destination buffer pointer.
+ @param szb Size of destination buffer (number of dkChar).
+ @param fn File name of link.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if bptr or fn is NULL or szb is 0,
+ - DK4_E_SYSTEM<br>
+ with errno value in iDetails1 if the readlink() function failed
+ on Linux/Unix,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the output buffer is too small,
+ - DK4_E_NOT_SUPPORTED<br>
+ if no function was found to read a symbolic link target,
+ - DK4_E_NOT_FOUND<br>
+ if the CreateFile() or DeviceIoControl() function failed
+ on Windows.
+*/
+int
+dk4symlink_target(dkChar *bptr, size_t szb, const dkChar *fn, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4symlink.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#if DK4_HAVE_NTIFS_H
+#ifndef NTIFS_H_INCLUDED
+#include <ntifs.h>
+#define NTIFS_H_INCLUDED 1
+#endif
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4mpl.h"
+#include "dk4mem.h"
+#include "dk4strd.h"
+
+
+
+$!trace-include
+
+
+
+#if DK4_ON_WINDOWS
+
+#if !DK4_HAVE_NTIFS_H
+
+typedef struct _REPARSE_DATA_BUFFER {
+ ULONG ReparseTag;
+ USHORT ReparseDataLength;
+ USHORT Reserved;
+ union {
+ struct {
+ USHORT SubstituteNameOffset;
+ USHORT SubstituteNameLength;
+ USHORT PrintNameOffset;
+ USHORT PrintNameLength;
+ ULONG Flags;
+ WCHAR PathBuffer[1];
+ } SymbolicLinkReparseBuffer;
+ struct {
+ USHORT SubstituteNameOffset;
+ USHORT SubstituteNameLength;
+ USHORT PrintNameOffset;
+ USHORT PrintNameLength;
+ WCHAR PathBuffer[1];
+ } MountPointReparseBuffer;
+ struct {
+ UCHAR DataBuffer[1];
+ } GenericReparseBuffer;
+ };
+} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
+
+#endif
+
+
+#if defined(FSCTL_GET_REPARSE_POINT)
+/** Size of reparse point information for a symlink.
+*/
+#define SYMLINK_INFO_SIZE ((8 * (DK4_MAX_PATH))+sizeof(REPARSE_DATA_BUFFER))
+/** The above size aligned to 16 bytes.
+*/
+#define SYMLINK_INFO_ALIGNED (16 * (((SYMLINK_INFO_SIZE) / 16) + 1))
+
+#ifdef MAXIMUM_REPARSE_DATA_BUFFER_SIZE
+#define SYMLINK_BUFFER_SIZE \
+(MAXIMUM_REPARSE_DATA_BUFFER_SIZE + SYMLINK_INFO_ALIGNED)
+#endif
+#endif
+
+/** Copy path name from reparse point buffer to destination buffer.
+ @param bptr Destination buffer.
+ @param szb Destination buffer size (number of wchar_t).
+ @param sptr Source pointer.
+ @param offs Offset of path name in source (in bytes).
+ @param length Length of path name (in bytes).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4symlink_copy_string(
+ wchar_t *bptr,
+ size_t szb,
+ const wchar_t *sptr,
+ USHORT offs,
+ USHORT length,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+ if ((length / sizeof(wchar_t)) < szb) {
+ DK4_MEMCPY(bptr,&(sptr[offs / sizeof(wchar_t)]),length);
+ bptr[length / sizeof(wchar_t)] = L'\0';
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ return back;
+}
+
+#endif
+
+int
+dk4symlink_target(dkChar *bptr, size_t szb, const dkChar *fn, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+#if defined(FSCTL_GET_REPARSE_POINT)
+ char repdabuf[SYMLINK_BUFFER_SIZE];
+ REPARSE_DATA_BUFFER *rdb;
+#endif
+ HANDLE fh;
+ DWORD dwres;
+ BOOL result;
+#else
+ ssize_t res;
+#endif
+ int back = 0;
+
+ $? "+ dk4symlink_target"
+ if ((NULL != bptr) && (NULL != fn) && (0 < szb)) {
+ *bptr = dkT('\0');
+#if DK4_ON_WINDOWS
+#if DK4_CHAR_SIZE > 1
+#if DK4_HAVE_GETFINALPATHNAMEBYHANDLE
+ fh = CreateFileW(
+ fn,
+ FILE_READ_ATTRIBUTES,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ NULL
+ );
+ if (INVALID_HANDLE_VALUE != fh) {
+ dwres = GetFinalPathNameByHandleW(fh, bptr, (DWORD)szb, 0);
+ if (0 < dwres) {
+ if (dwres < (DWORD)szb) {
+ back = 1;
+ }
+ }
+ CloseHandle(fh);
+ }
+#else
+ $? ". no GetFinalPathNameByHandle"
+#endif
+ if (0 == back) {
+#if defined(FSCTL_GET_REPARSE_POINT)
+ /* !!!!! Second attempt with legacy procedure */
+ $? ". legacy procedure"
+ fh = CreateFileW(
+ fn,
+ FILE_READ_ATTRIBUTES,
+ (FILE_SHARE_READ | FILE_SHARE_WRITE),
+ NULL,
+ OPEN_EXISTING,
+ (
+ FILE_FLAG_BACKUP_SEMANTICS
+ | FILE_FLAG_OPEN_REPARSE_POINT
+ | FILE_ATTRIBUTE_REPARSE_POINT
+ ),
+ NULL
+ );
+ if (INVALID_HANDLE_VALUE != fh) {
+ dwres = 0; $? ". CreateFileW"
+ result = DeviceIoControl(
+ fh,
+ FSCTL_GET_REPARSE_POINT,
+ NULL,
+ (DWORD)0U,
+ (void *)repdabuf,
+ (DWORD)sizeof(repdabuf),
+ &dwres,
+ NULL
+ );
+ if (result) { $? ". DeviceIoControl"
+ rdb = (REPARSE_DATA_BUFFER *)repdabuf;
+ if (IO_REPARSE_TAG_MOUNT_POINT == rdb->ReparseTag) {
+ $? ". mount point"
+ back = dk4symlink_copy_string(
+ bptr, szb,
+ &(rdb->MountPointReparseBuffer.PathBuffer[0]),
+ rdb->MountPointReparseBuffer.SubstituteNameOffset,
+ rdb->MountPointReparseBuffer.SubstituteNameLength,
+ erp
+ );
+ } else {
+ if (IO_REPARSE_TAG_SYMLINK == rdb->ReparseTag) {
+ $? ". symbolic link"
+ back = dk4symlink_copy_string(
+ bptr, szb,
+ &(rdb->SymbolicLinkReparseBuffer.PathBuffer[0]),
+ rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset,
+ rdb->SymbolicLinkReparseBuffer.SubstituteNameLength,
+ erp
+ );
+ } else {
+ /* !!!!! Not mount point, not symlink */
+ $? "! neither mount point nor symbolic link"
+ }
+ }
+ } else { $? "! DeviceIoControl"
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ CloseHandle(fh);
+ } else { $? "! CreateFile"
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+ }
+#else
+#if DK4_HAVE_GETFINALPATHNAMEBYHANDLE
+ fh = CreateFileA(
+ fn,
+ FILE_READ_ATTRIBUTES,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ NULL
+ );
+ if (INVALID_HANDLE_VALUE != fh) {
+ dwres = GetFinalPathNameByHandleA(fh, bptr, (DWORD)szb, 0);
+ if (0 < dwres) {
+ if (dwres < (DWORD)szb) {
+ back = 1;
+ }
+ }
+ CloseHandle(fh);
+ }
+#else
+ /* Legacy procedure only available for wchar_t.
+ */
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#endif
+#endif
+ if (0 < back) {
+ if (dkT('\\') == bptr[0]) {
+ if ((dkT('\\') == bptr[1]) || (dkT('?') == bptr[1])) {
+ if (dkT('?') == bptr[2]) {
+ if (dkT('\\') == bptr[3]) {
+ if (260 > dk4str_len(&(bptr[4]))) {
+ dk4str_cpy_to_left(bptr, &(bptr[4]));
+ }
+ }
+ }
+ }
+ }
+ }
+#else
+#if DK4_CHAR_SIZE > 1
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+#else
+ errno = 0;
+ res = readlink(fn, bptr, szb);
+ if (0 < res) {
+ if (res < szb) {
+ bptr[res] = dkT('\0');
+ back = 1;
+ } else { $? "! readlink requires larger buffer"
+ bptr[0] = dkT('\0');
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else { $? "! readlink <= 0"
+ bptr[0] = dkT('\0');
+ if (0 > res) {
+ dk4error_set_idetails(erp, DK4_E_SYSTEM, errno);
+ }
+ }
+#endif
+#endif
+ if (0 == back) { *bptr = dkT('\0'); }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4symlink_target %d", back
+ return back;
+}
+
diff --git a/support/dktools/dk4symlink.h b/support/dktools/dk4symlink.h
new file mode 100644
index 0000000000..f9844ebeae
--- /dev/null
+++ b/support/dktools/dk4symlink.h
@@ -0,0 +1,93 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4symlink.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4SYMLINK_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4SYMLINK_H_INCLUDED 1
+
+
+#line 10 "dk4symlink.ctr"
+
+/** @file dk4symlink.h Find symbolic link target.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Find target for symbolic link.
+ @param bptr Destination buffer pointer.
+ @param szb Size of destination buffer (number of dkChar).
+ @param fn File name of link.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if bptr or fn is NULL or szb is 0,
+ - DK4_E_SYSTEM<br>
+ with errno value in iDetails1 if the readlink() function failed
+ on Linux/Unix,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the output buffer is too small,
+ - DK4_E_NOT_SUPPORTED<br>
+ if no function was found to read a symbolic link target,
+ - DK4_E_NOT_FOUND<br>
+ if the CreateFile() or DeviceIoControl() function failed
+ on Windows.
+*/
+int
+dk4symlink_target(dkChar *bptr, size_t szb, const dkChar *fn, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4time.c b/support/dktools/dk4time.c
new file mode 100644
index 0000000000..df2fc9ec13
--- /dev/null
+++ b/support/dktools/dk4time.c
@@ -0,0 +1,66 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4time.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4time.c The dk4time module.
+*/
+
+
+#line 81 "dk4time.ctr"
+
+#include "dk4time.h"
+
+
+
+static const char * const dk4time_kw[] = {
+/* 0 */ "0",
+/* 1 */ " ",
+/* 2 */ "-",
+/* 3 */ ":"
+};
+
+
+
+void
+dk4time_get(dk4_time_t *timer)
+{
+#if DK4_ON_WINDOWS
+ (void)_time64(timer);
+#else
+ (void)time(timer);
+#endif
+}
+
+
+
diff --git a/support/dktools/dk4time.ctr b/support/dktools/dk4time.ctr
new file mode 100644
index 0000000000..374c3abac3
--- /dev/null
+++ b/support/dktools/dk4time.ctr
@@ -0,0 +1,106 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Retrieve current timestamp using CRT functions.
+
+
+ CRT on Windows: Required.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_TIME_WITH_SYS_TIME
+#ifndef SYS_TIME_H_INCLUDED
+#include <sys/time.h>
+#define SYS_TIME_H_INCLUDED 1
+#endif
+#ifndef TIME_H_INCLUDED
+#include <time.h>
+#define TIME_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_TIME_H
+#ifndef TIME_H_INCLUDED
+#include <time.h>
+#define TIME_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_SYS_TIME_H
+#ifndef SYS_TIME_H_INCLUDED
+#include <sys/time.h>
+#define SYS_TIME_H_INCLUDED 1
+#endif
+#endif
+#endif
+#endif
+
+
+#if DK4_ON_WINDOWS
+/** Timestamp.
+*/
+typedef __time64_t dk4_time_t;
+#else
+/** Timestamp.
+*/
+typedef time_t dk4_time_t;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve current time.
+ @param timer Address of result variable.
+*/
+void
+dk4time_get(dk4_time_t *timer);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4time.h"
+
+
+
+static const char * const dk4time_kw[] = {
+/* 0 */ "0",
+/* 1 */ " ",
+/* 2 */ "-",
+/* 3 */ ":"
+};
+
+
+
+void
+dk4time_get(dk4_time_t *timer)
+{
+#if DK4_ON_WINDOWS
+ (void)_time64(timer);
+#else
+ (void)time(timer);
+#endif
+}
+
+
+
diff --git a/support/dktools/dk4time.h b/support/dktools/dk4time.h
new file mode 100644
index 0000000000..4b8a22650a
--- /dev/null
+++ b/support/dktools/dk4time.h
@@ -0,0 +1,113 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4time.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4TIME_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4TIME_H_INCLUDED 1
+
+
+#line 10 "dk4time.ctr"
+
+/** @file
+ Retrieve current timestamp using CRT functions.
+
+
+ CRT on Windows: Required.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_TIME_WITH_SYS_TIME
+#ifndef SYS_TIME_H_INCLUDED
+#include <sys/time.h>
+#define SYS_TIME_H_INCLUDED 1
+#endif
+#ifndef TIME_H_INCLUDED
+#include <time.h>
+#define TIME_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_TIME_H
+#ifndef TIME_H_INCLUDED
+#include <time.h>
+#define TIME_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_SYS_TIME_H
+#ifndef SYS_TIME_H_INCLUDED
+#include <sys/time.h>
+#define SYS_TIME_H_INCLUDED 1
+#endif
+#endif
+#endif
+#endif
+
+
+#if DK4_ON_WINDOWS
+/** Timestamp.
+*/
+typedef __time64_t dk4_time_t;
+#else
+/** Timestamp.
+*/
+typedef time_t dk4_time_t;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve current time.
+ @param timer Address of result variable.
+*/
+void
+dk4time_get(dk4_time_t *timer);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4time08.c b/support/dktools/dk4time08.c
new file mode 100644
index 0000000000..e3f9449f34
--- /dev/null
+++ b/support/dktools/dk4time08.c
@@ -0,0 +1,295 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4time08.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4time08.c The dk4time08 module.
+*/
+
+
+#line 132 "dk4time08.ctr"
+
+#include "dk4time08.h"
+
+#ifndef DK4STR8_H_INCLUDED
+#include "dk4str8.h"
+#endif
+
+#ifndef DK4MAO8D_H_INCLUDED
+#include "dk4mao8d.h"
+#endif
+
+
+
+
+
+#line 146 "dk4time08.ctr"
+
+
+
+/** Constant text strings used by this module.
+*/
+static const char * const dk4time08_kw[] = {
+/* 0 */
+"0",
+
+/* 1 */
+"-",
+
+/* 2 */
+"/",
+
+/* 3 */
+".",
+
+/* 4 */
+" ",
+
+/* 5 */
+":",
+
+NULL
+
+
+#line 160 "dk4time08.ctr"
+};
+
+
+
+int
+dk4time_to_text_c8(
+ char *dptr,
+ size_t dsz,
+ int format,
+ unsigned short year,
+ unsigned short month,
+ unsigned short mday,
+ unsigned short hour,
+ unsigned short min,
+ unsigned short sec,
+ dk4_er_t *erp
+)
+{
+ char bye[8];
+ char bmo[8];
+ char bda[8];
+ char bho[8];
+ char bmi[8];
+ char bse[8];
+ int res;
+ int back = 0;
+ if ((NULL != dptr) && (0 < dsz)) {
+ back = 1;
+ res = dk4ma_write_c8_decimal_unsigned(
+ bye, sizeof(bye), (dk4_um_t)year, 4, erp
+ );
+ if (0 == res) { back = 0; }
+ res = dk4ma_write_c8_decimal_unsigned(
+ bmo, sizeof(bmo), (dk4_um_t)month, 2, erp
+ );
+ if (0 == res) { back = 0; }
+ res = dk4ma_write_c8_decimal_unsigned(
+ bda, sizeof(bda), (dk4_um_t)mday, 2, erp
+ );
+ if (0 == res) { back = 0; }
+ if (DK4_TIMEFORMAT_DATE_SORTABLE != format) {
+ if (DK4_TIMEFORMAT_DATE_ENGLISH != format) {
+ if (DK4_TIMEFORMAT_DATE_GERMAN != format) {
+ res = dk4ma_write_c8_decimal_unsigned(
+ bho, sizeof(bho), (dk4_um_t)hour, 2, erp
+ );
+ if (0 == res) { back = 0; }
+ res = dk4ma_write_c8_decimal_unsigned(
+ bmi, sizeof(bmi), (dk4_um_t)min, 2, erp
+ );
+ if (0 == res) { back = 0; }
+ res = dk4ma_write_c8_decimal_unsigned(
+ bse, sizeof(bse), (dk4_um_t)sec, 2, erp
+ );
+ if (0 == res) { back = 0; }
+ }
+ }
+ }
+ if (0 != back) {
+ back = 0;
+ switch (format) {
+ case DK4_TIMEFORMAT_DATE_ENGLISH: {
+ if (0 != dk4str8_cpy_s(dptr, dsz, bmo, erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, dk4time08_kw[2], erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, bda, erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, dk4time08_kw[2], erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, bye, erp)) {
+ back = 1;
+ }
+ }
+ }
+ }
+ }
+ } break;
+ case DK4_TIMEFORMAT_DATE_GERMAN: {
+ if (0 != dk4str8_cpy_s(dptr, dsz, bda, erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, dk4time08_kw[3], erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, bmo, erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, dk4time08_kw[3], erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, bye, erp)) {
+ back = 1;
+ }
+ }
+ }
+ }
+ }
+ } break;
+ default: {
+ /* yyyy-mm-dd */
+ if (0 != dk4str8_cpy_s(dptr, dsz, bye, erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, dk4time08_kw[1], erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, bmo, erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, dk4time08_kw[1], erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, bda, erp)) {
+ back = 1;
+ }
+ }
+ }
+ }
+ }
+ if ((0 != back) && (DK4_TIMEFORMAT_DATE_SORTABLE != format)) {
+ back = 0;
+ if (0 != dk4str8_cat_s(dptr, dsz, dk4time08_kw[4], erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, bho, erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, dk4time08_kw[5], erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, bmi, erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, dk4time08_kw[5], erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, bse, erp)) {
+ back = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } break;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4time_convert_to_text_c8(
+ char *dptr, size_t dsz, const struct tm *tm, dk4_er_t *erp
+)
+{
+ int back = 0;
+ if ((NULL != dptr) && (0 < dsz)) {
+ *dptr = '\0';
+ if (NULL != tm) {
+ back = dk4time_to_text_c8(
+ dptr, dsz, DK4_TIMEFORMAT_DATE_TIME,
+ (1900 + tm->tm_year), (1 + tm->tm_mon), tm->tm_mday,
+ tm->tm_hour, tm->tm_min, tm->tm_sec,
+ erp
+ );
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+static
+int
+dk4time_i_as_text_c8(
+ char *dptr, size_t dsz, const dk4_time_t *timer, dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+ struct tm lct;
+ int back = 0;
+ if (0 == _localtime64_s(&lct, timer)) {
+ back = dk4time_convert_to_text_c8(dptr, dsz, &lct, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ return back;
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+#if DK4_HAVE_LOCALTIME_R
+ struct tm lct;
+ int back = 0;
+ if (NULL != localtime_r(timer, &lct)) {
+ back = dk4time_convert_to_text_c8(dptr, dsz, &lct, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+ /* --- non-Windows */
+#endif
+}
+
+
+
+int
+dk4time_as_text_c8(
+ char *dptr, size_t dsz, const dk4_time_t *timer, dk4_er_t *erp
+)
+{
+ int back = 0;
+ if ((NULL != dptr) && (0 < dsz)) {
+ *dptr = '\0';
+ if (NULL != timer) {
+ back = dk4time_i_as_text_c8(dptr, dsz, timer, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4time08.ctr b/support/dktools/dk4time08.ctr
new file mode 100644
index 0000000000..a85cba406e
--- /dev/null
+++ b/support/dktools/dk4time08.ctr
@@ -0,0 +1,370 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ Convert timestamp to char string, timestamp either given as set
+ of components (year, month, day, hour, minute, second), as
+ pointer to struct tm or as dk4_time_t value.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4TIME_H_INCLUDED
+#include "dk4time.h"
+#endif
+
+#ifndef DK4TIMEC_H_INCLUDED
+#include "dk4timec.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert timestamp to char string.
+ CRT on Windows: Optional.
+ @param dptr Destination buffer address.
+ @param dsz Destination buffer size (number of char).
+ @param format Output format:
+ DK4_TIMEFORMAT_DATE_TIME for sortable date/time
+ combination
+ yyyy-mm-dd hh:mm:ss
+ (default),
+ DK4_TIMEFORMAT_DATE_SORTABLE for sortable date
+ yyyy-mm-dd,
+ DK4_TIMEFORMAT_DATE_ENGLISH for English style date
+ mm/dd/yyyy,
+ DK4_TIMEFORMAT_DATE_GERMAN for German style date
+ dd.mm.yyyy.
+ @param year Year.
+ @param month Month (1 to 12).
+ @param mday Day within month (1 to 31).
+ @param hour Hour of day (0 to 23).
+ @param min Minute within hour (0 to 59).
+ @param sec Second within minute (0 to 59).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or dsz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the buffer is too small.
+
+*/
+int
+dk4time_to_text_c8(
+ char *dptr,
+ size_t dsz,
+ int format,
+ unsigned short year,
+ unsigned short month,
+ unsigned short mday,
+ unsigned short hour,
+ unsigned short min,
+ unsigned short sec,
+ dk4_er_t *erp
+);
+
+/** Create text representation for a struct tm.
+ CRT on Windows: Required.
+ @param dptr Destination buffer address.
+ @param dsz Destination buffer size (number of wchar_t).
+ @param tm Struct to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or dsz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the buffer is too small.
+*/
+int
+dk4time_convert_to_text_c8(
+ char *dptr, size_t dsz, const struct tm *tm, dk4_er_t *erp
+);
+
+/** Create text representation for timestamp.
+ CRT on Windows: Required.
+ @param dptr Destination buffer address.
+ @param dsz Destination buffer size.
+ @param timer Timestamp to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or dsz is 0,
+ - DK4_E_BUG<br>
+ if an internal conversion function fails,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the buffer is too small.
+*/
+int
+dk4time_as_text_c8(
+ char *dptr, size_t dsz, const dk4_time_t *timer, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4time08.h"
+
+#ifndef DK4STR8_H_INCLUDED
+#include "dk4str8.h"
+#endif
+
+#ifndef DK4MAO8D_H_INCLUDED
+#include "dk4mao8d.h"
+#endif
+
+
+
+$!trace-include
+
+
+
+/** Constant text strings used by this module.
+*/
+static const char * const dk4time08_kw[] = {
+$!string-table
+0
+-
+/
+.
+
+:
+$!end
+};
+
+
+
+int
+dk4time_to_text_c8(
+ char *dptr,
+ size_t dsz,
+ int format,
+ unsigned short year,
+ unsigned short month,
+ unsigned short mday,
+ unsigned short hour,
+ unsigned short min,
+ unsigned short sec,
+ dk4_er_t *erp
+)
+{
+ char bye[8];
+ char bmo[8];
+ char bda[8];
+ char bho[8];
+ char bmi[8];
+ char bse[8];
+ int res;
+ int back = 0;
+ if ((NULL != dptr) && (0 < dsz)) {
+ back = 1;
+ res = dk4ma_write_c8_decimal_unsigned(
+ bye, sizeof(bye), (dk4_um_t)year, 4, erp
+ );
+ if (0 == res) { back = 0; }
+ res = dk4ma_write_c8_decimal_unsigned(
+ bmo, sizeof(bmo), (dk4_um_t)month, 2, erp
+ );
+ if (0 == res) { back = 0; }
+ res = dk4ma_write_c8_decimal_unsigned(
+ bda, sizeof(bda), (dk4_um_t)mday, 2, erp
+ );
+ if (0 == res) { back = 0; }
+ if (DK4_TIMEFORMAT_DATE_SORTABLE != format) {
+ if (DK4_TIMEFORMAT_DATE_ENGLISH != format) {
+ if (DK4_TIMEFORMAT_DATE_GERMAN != format) {
+ res = dk4ma_write_c8_decimal_unsigned(
+ bho, sizeof(bho), (dk4_um_t)hour, 2, erp
+ );
+ if (0 == res) { back = 0; }
+ res = dk4ma_write_c8_decimal_unsigned(
+ bmi, sizeof(bmi), (dk4_um_t)min, 2, erp
+ );
+ if (0 == res) { back = 0; }
+ res = dk4ma_write_c8_decimal_unsigned(
+ bse, sizeof(bse), (dk4_um_t)sec, 2, erp
+ );
+ if (0 == res) { back = 0; }
+ }
+ }
+ }
+ if (0 != back) {
+ back = 0;
+ switch (format) {
+ case DK4_TIMEFORMAT_DATE_ENGLISH: {
+ if (0 != dk4str8_cpy_s(dptr, dsz, bmo, erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, dk4time08_kw[2], erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, bda, erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, dk4time08_kw[2], erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, bye, erp)) {
+ back = 1;
+ }
+ }
+ }
+ }
+ }
+ } break;
+ case DK4_TIMEFORMAT_DATE_GERMAN: {
+ if (0 != dk4str8_cpy_s(dptr, dsz, bda, erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, dk4time08_kw[3], erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, bmo, erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, dk4time08_kw[3], erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, bye, erp)) {
+ back = 1;
+ }
+ }
+ }
+ }
+ }
+ } break;
+ default: {
+ /* yyyy-mm-dd */
+ if (0 != dk4str8_cpy_s(dptr, dsz, bye, erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, dk4time08_kw[1], erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, bmo, erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, dk4time08_kw[1], erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, bda, erp)) {
+ back = 1;
+ }
+ }
+ }
+ }
+ }
+ if ((0 != back) && (DK4_TIMEFORMAT_DATE_SORTABLE != format)) {
+ back = 0;
+ if (0 != dk4str8_cat_s(dptr, dsz, dk4time08_kw[4], erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, bho, erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, dk4time08_kw[5], erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, bmi, erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, dk4time08_kw[5], erp)) {
+ if (0 != dk4str8_cat_s(dptr, dsz, bse, erp)) {
+ back = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } break;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4time_convert_to_text_c8(
+ char *dptr, size_t dsz, const struct tm *tm, dk4_er_t *erp
+)
+{
+ int back = 0;
+ if ((NULL != dptr) && (0 < dsz)) {
+ *dptr = '\0';
+ if (NULL != tm) {
+ back = dk4time_to_text_c8(
+ dptr, dsz, DK4_TIMEFORMAT_DATE_TIME,
+ (1900 + tm->tm_year), (1 + tm->tm_mon), tm->tm_mday,
+ tm->tm_hour, tm->tm_min, tm->tm_sec,
+ erp
+ );
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+static
+int
+dk4time_i_as_text_c8(
+ char *dptr, size_t dsz, const dk4_time_t *timer, dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+ struct tm lct;
+ int back = 0;
+ if (0 == _localtime64_s(&lct, timer)) {
+ back = dk4time_convert_to_text_c8(dptr, dsz, &lct, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ return back;
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+#if DK4_HAVE_LOCALTIME_R
+ struct tm lct;
+ int back = 0;
+ if (NULL != localtime_r(timer, &lct)) {
+ back = dk4time_convert_to_text_c8(dptr, dsz, &lct, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+ /* --- non-Windows */
+#endif
+}
+
+
+
+int
+dk4time_as_text_c8(
+ char *dptr, size_t dsz, const dk4_time_t *timer, dk4_er_t *erp
+)
+{
+ int back = 0;
+ if ((NULL != dptr) && (0 < dsz)) {
+ *dptr = '\0';
+ if (NULL != timer) {
+ back = dk4time_i_as_text_c8(dptr, dsz, timer, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4time08.h b/support/dktools/dk4time08.h
new file mode 100644
index 0000000000..555a7873a1
--- /dev/null
+++ b/support/dktools/dk4time08.h
@@ -0,0 +1,165 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4time08.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4TIME08_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4TIME08_H_INCLUDED 1
+
+
+#line 9 "dk4time08.ctr"
+
+/** @file
+ Convert timestamp to char string, timestamp either given as set
+ of components (year, month, day, hour, minute, second), as
+ pointer to struct tm or as dk4_time_t value.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4TIME_H_INCLUDED
+#include "dk4time.h"
+#endif
+
+#ifndef DK4TIMEC_H_INCLUDED
+#include "dk4timec.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert timestamp to char string.
+ CRT on Windows: Optional.
+ @param dptr Destination buffer address.
+ @param dsz Destination buffer size (number of char).
+ @param format Output format:
+ DK4_TIMEFORMAT_DATE_TIME for sortable date/time
+ combination
+ yyyy-mm-dd hh:mm:ss
+ (default),
+ DK4_TIMEFORMAT_DATE_SORTABLE for sortable date
+ yyyy-mm-dd,
+ DK4_TIMEFORMAT_DATE_ENGLISH for English style date
+ mm/dd/yyyy,
+ DK4_TIMEFORMAT_DATE_GERMAN for German style date
+ dd.mm.yyyy.
+ @param year Year.
+ @param month Month (1 to 12).
+ @param mday Day within month (1 to 31).
+ @param hour Hour of day (0 to 23).
+ @param min Minute within hour (0 to 59).
+ @param sec Second within minute (0 to 59).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or dsz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the buffer is too small.
+
+*/
+int
+dk4time_to_text_c8(
+ char *dptr,
+ size_t dsz,
+ int format,
+ unsigned short year,
+ unsigned short month,
+ unsigned short mday,
+ unsigned short hour,
+ unsigned short min,
+ unsigned short sec,
+ dk4_er_t *erp
+);
+
+/** Create text representation for a struct tm.
+ CRT on Windows: Required.
+ @param dptr Destination buffer address.
+ @param dsz Destination buffer size (number of wchar_t).
+ @param tm Struct to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or dsz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the buffer is too small.
+*/
+int
+dk4time_convert_to_text_c8(
+ char *dptr, size_t dsz, const struct tm *tm, dk4_er_t *erp
+);
+
+/** Create text representation for timestamp.
+ CRT on Windows: Required.
+ @param dptr Destination buffer address.
+ @param dsz Destination buffer size.
+ @param timer Timestamp to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or dsz is 0,
+ - DK4_E_BUG<br>
+ if an internal conversion function fails,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the buffer is too small.
+*/
+int
+dk4time_as_text_c8(
+ char *dptr, size_t dsz, const dk4_time_t *timer, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4timec.h b/support/dktools/dk4timec.h
new file mode 100644
index 0000000000..6a8219dc98
--- /dev/null
+++ b/support/dktools/dk4timec.h
@@ -0,0 +1,33 @@
+#ifndef DK4TIMEC_H_INCLUDED
+/** Protection against multiple inclusions */
+#define DK4TIMEC_H_INCLUDED 1
+
+/** @file dk4timec.h Date/time formats.
+*/
+
+/** Date/time formats.
+*/
+enum {
+ /** Complete date and time sortabel,
+ yyyy-mm-dd hh:mm:ss
+ */
+ DK4_TIMEFORMAT_DATE_TIME = 1,
+
+ /** Date in sortable format,
+ yyyy-mm-dd
+ */
+ DK4_TIMEFORMAT_DATE_SORTABLE ,
+
+ /** English/american date format,
+ mm/dd/yyyy
+ */
+ DK4_TIMEFORMAT_DATE_ENGLISH ,
+
+ /** German date format
+ dd.mm.yyyy
+ */
+ DK4_TIMEFORMAT_DATE_GERMAN
+};
+
+#endif
+
diff --git a/support/dktools/dk4timedk.c b/support/dktools/dk4timedk.c
new file mode 100644
index 0000000000..abe6c20ffe
--- /dev/null
+++ b/support/dktools/dk4timedk.c
@@ -0,0 +1,104 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4timedk.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4timedk.c The dk4timedk module.
+*/
+
+
+#line 132 "dk4timedk.ctr"
+
+#include "dk4timedk.h"
+
+#if DK4_CHAR_SIZE > 1
+#ifndef DK4TIMEWC_H_INCLUDED
+#include "dk4timewc.h"
+#endif
+#else
+#ifndef DK4TIME08_H_INCLUDED
+#include "dk4time08.h"
+#endif
+#endif
+
+
+
+int
+dk4time_to_text(
+ dkChar *dptr,
+ size_t dsz,
+ int format,
+ unsigned short year,
+ unsigned short month,
+ unsigned short mday,
+ unsigned short hour,
+ unsigned short min,
+ unsigned short sec,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4time_to_text_wc(dptr,dsz,format,year,month,mday,hour,min,sec,erp));
+#else
+ return (dk4time_to_text_c8(dptr,dsz,format,year,month,mday,hour,min,sec,erp));
+#endif
+}
+
+
+
+int
+dk4time_convert_to_text(
+ dkChar *dptr, size_t dsz, const struct tm *tm, dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4time_convert_to_text_wc(dptr, dsz, tm, erp));
+#else
+ return (dk4time_convert_to_text_c8(dptr, dsz, tm, erp));
+#endif
+}
+
+
+
+int
+dk4time_as_text(
+ dkChar *dptr, size_t dsz, const dk4_time_t *timer, dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4time_as_text_wc(dptr, dsz, timer, erp));
+#else
+ return (dk4time_as_text_c8(dptr, dsz, timer, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4timedk.ctr b/support/dktools/dk4timedk.ctr
new file mode 100644
index 0000000000..5628a52faf
--- /dev/null
+++ b/support/dktools/dk4timedk.ctr
@@ -0,0 +1,195 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Convert timestamp to dkChar string, timestamp either given as set
+ of components (year, month, day, hour, minute, second), as
+ pointer to struct tm or as dk4_time_t value.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4TIME_H_INCLUDED
+#include "dk4time.h"
+#endif
+
+#ifndef DK4TIMEC_H_INCLUDED
+#include "dk4timec.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert timestamp to wchar_t string.
+ CRT on Windows: Optional.
+ @param dptr Destination buffer address.
+ @param dsz Destination buffer size (number of dkChar).
+ @param format Output format:
+ DK4_TIMEFORMAT_DATE_TIME for sortable date/time
+ combination
+ yyyy-mm-dd hh:mm:ss
+ (default),
+ DK4_TIMEFORMAT_DATE_SORTABLE for sortable date
+ yyyy-mm-dd,
+ DK4_TIMEFORMAT_DATE_ENGLISH for English style date
+ mm/dd/yyyy,
+ DK4_TIMEFORMAT_DATE_GERMAN for German style date
+ dd.mm.yyyy.
+ @param year Year.
+ @param month Month (1 to 12).
+ @param mday Day within month (1 to 31).
+ @param hour Hour of day (0 to 23).
+ @param min Minute within hour (0 to 59).
+ @param sec Second within minute (0 to 59).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or dsz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the buffer is too small.
+*/
+int
+dk4time_to_text(
+ dkChar *dptr,
+ size_t dsz,
+ int format,
+ unsigned short year,
+ unsigned short month,
+ unsigned short mday,
+ unsigned short hour,
+ unsigned short min,
+ unsigned short sec,
+ dk4_er_t *erp
+);
+
+/** Create text representation for a struct tm.
+ CRT on Windows: Optional.
+ @param dptr Destination buffer address.
+ @param dsz Destination buffer size (number of dkChar).
+ @param tm Struct to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or dsz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the buffer is too small.
+*/
+int
+dk4time_convert_to_text(
+ dkChar *dptr, size_t dsz, const struct tm *tm, dk4_er_t *erp
+);
+
+/** Create text representation for timestamp.
+ CRT on Windows: Required.
+ @param dptr Destination buffer address.
+ @param dsz Destination buffer size (Number of dkChar).
+ @param timer Timestamp to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or dsz is 0,
+ - DK4_E_BUG<br>
+ if an internal conversion function fails,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the buffer is too small.
+*/
+int
+dk4time_as_text(
+ dkChar *dptr, size_t dsz, const dk4_time_t *timer, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4timedk.h"
+
+#if DK4_CHAR_SIZE > 1
+#ifndef DK4TIMEWC_H_INCLUDED
+#include "dk4timewc.h"
+#endif
+#else
+#ifndef DK4TIME08_H_INCLUDED
+#include "dk4time08.h"
+#endif
+#endif
+
+
+
+int
+dk4time_to_text(
+ dkChar *dptr,
+ size_t dsz,
+ int format,
+ unsigned short year,
+ unsigned short month,
+ unsigned short mday,
+ unsigned short hour,
+ unsigned short min,
+ unsigned short sec,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4time_to_text_wc(dptr,dsz,format,year,month,mday,hour,min,sec,erp));
+#else
+ return (dk4time_to_text_c8(dptr,dsz,format,year,month,mday,hour,min,sec,erp));
+#endif
+}
+
+
+
+int
+dk4time_convert_to_text(
+ dkChar *dptr, size_t dsz, const struct tm *tm, dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4time_convert_to_text_wc(dptr, dsz, tm, erp));
+#else
+ return (dk4time_convert_to_text_c8(dptr, dsz, tm, erp));
+#endif
+}
+
+
+
+int
+dk4time_as_text(
+ dkChar *dptr, size_t dsz, const dk4_time_t *timer, dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4time_as_text_wc(dptr, dsz, timer, erp));
+#else
+ return (dk4time_as_text_c8(dptr, dsz, timer, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4timedk.h b/support/dktools/dk4timedk.h
new file mode 100644
index 0000000000..76ff344f31
--- /dev/null
+++ b/support/dktools/dk4timedk.h
@@ -0,0 +1,164 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4timedk.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4TIMEDK_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4TIMEDK_H_INCLUDED 1
+
+
+#line 10 "dk4timedk.ctr"
+
+/** @file
+ Convert timestamp to dkChar string, timestamp either given as set
+ of components (year, month, day, hour, minute, second), as
+ pointer to struct tm or as dk4_time_t value.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4TIME_H_INCLUDED
+#include "dk4time.h"
+#endif
+
+#ifndef DK4TIMEC_H_INCLUDED
+#include "dk4timec.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert timestamp to wchar_t string.
+ CRT on Windows: Optional.
+ @param dptr Destination buffer address.
+ @param dsz Destination buffer size (number of dkChar).
+ @param format Output format:
+ DK4_TIMEFORMAT_DATE_TIME for sortable date/time
+ combination
+ yyyy-mm-dd hh:mm:ss
+ (default),
+ DK4_TIMEFORMAT_DATE_SORTABLE for sortable date
+ yyyy-mm-dd,
+ DK4_TIMEFORMAT_DATE_ENGLISH for English style date
+ mm/dd/yyyy,
+ DK4_TIMEFORMAT_DATE_GERMAN for German style date
+ dd.mm.yyyy.
+ @param year Year.
+ @param month Month (1 to 12).
+ @param mday Day within month (1 to 31).
+ @param hour Hour of day (0 to 23).
+ @param min Minute within hour (0 to 59).
+ @param sec Second within minute (0 to 59).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or dsz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the buffer is too small.
+*/
+int
+dk4time_to_text(
+ dkChar *dptr,
+ size_t dsz,
+ int format,
+ unsigned short year,
+ unsigned short month,
+ unsigned short mday,
+ unsigned short hour,
+ unsigned short min,
+ unsigned short sec,
+ dk4_er_t *erp
+);
+
+/** Create text representation for a struct tm.
+ CRT on Windows: Optional.
+ @param dptr Destination buffer address.
+ @param dsz Destination buffer size (number of dkChar).
+ @param tm Struct to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or dsz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the buffer is too small.
+*/
+int
+dk4time_convert_to_text(
+ dkChar *dptr, size_t dsz, const struct tm *tm, dk4_er_t *erp
+);
+
+/** Create text representation for timestamp.
+ CRT on Windows: Required.
+ @param dptr Destination buffer address.
+ @param dsz Destination buffer size (Number of dkChar).
+ @param timer Timestamp to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or dsz is 0,
+ - DK4_E_BUG<br>
+ if an internal conversion function fails,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the buffer is too small.
+*/
+int
+dk4time_as_text(
+ dkChar *dptr, size_t dsz, const dk4_time_t *timer, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4timewc.c b/support/dktools/dk4timewc.c
new file mode 100644
index 0000000000..635aad3bd4
--- /dev/null
+++ b/support/dktools/dk4timewc.c
@@ -0,0 +1,164 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4timewc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4timewc.c The dk4timewc module.
+*/
+
+
+#line 132 "dk4timewc.ctr"
+
+#include "dk4timewc.h"
+
+#ifndef DK4TIME08_H_INCLUDED
+#include "dk4time08.h"
+#endif
+
+#ifndef DK4REC23_H_INCLUDED
+#include "dk4rec23.h"
+#endif
+
+
+
+int
+dk4time_to_text_wc(
+ wchar_t *dptr,
+ size_t dsz,
+ int format,
+ unsigned short year,
+ unsigned short month,
+ unsigned short mday,
+ unsigned short hour,
+ unsigned short min,
+ unsigned short sec,
+ dk4_er_t *erp
+)
+{
+ char buffer[64];
+ int back = 0;
+ back = dk4time_to_text_c8(
+ buffer, sizeof(buffer), format, year, month, mday, hour, min, sec, erp
+ );
+ if (0 != back) {
+ back = dk4recode_char_to_wchar_t(dptr, dsz, buffer, erp);
+ }
+ return back;
+}
+
+
+
+int
+dk4time_convert_to_text_wc(
+ wchar_t *dptr, size_t dsz, const struct tm *tm, dk4_er_t *erp
+)
+{
+ int back = 0;
+ if ((NULL != dptr) && (0 < dsz)) {
+ *dptr = L'\0';
+ if (NULL != tm) {
+ back = dk4time_to_text_wc(
+ dptr, dsz, DK4_TIMEFORMAT_DATE_TIME,
+ (1900 + tm->tm_year), (1 + tm->tm_mon), tm->tm_mday,
+ tm->tm_hour, tm->tm_min, tm->tm_sec,
+ erp
+ );
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+static
+int
+dk4time_i_as_text_wc(
+ wchar_t *dptr, size_t dsz, const dk4_time_t *timer, dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+ struct tm lct;
+ int back = 0;
+ if (0 == _localtime64_s(&lct, timer)) {
+ back = dk4time_convert_to_text_wc(dptr, dsz, &lct, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ return back;
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+#if DK4_HAVE_LOCALTIME_R
+ struct tm lct;
+ int back = 0;
+ if (NULL != localtime_r(timer, &lct)) {
+ back = dk4time_convert_to_text_wc(dptr, dsz, &lct, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+ /* --- non-Windows */
+#endif
+}
+
+
+
+int
+dk4time_as_text_wc(
+ wchar_t *dptr, size_t dsz, const dk4_time_t *timer, dk4_er_t *erp
+)
+{
+ int back = 0;
+ if ((dptr != NULL) && (0 < dsz)) {
+ *dptr = L'\0';
+ if (NULL != timer) {
+ back = dk4time_i_as_text_wc(dptr, dsz, timer, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4timewc.ctr b/support/dktools/dk4timewc.ctr
new file mode 100644
index 0000000000..70c74ff278
--- /dev/null
+++ b/support/dktools/dk4timewc.ctr
@@ -0,0 +1,255 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Convert timestamp to wchar_t string, timestamp either given as set
+ of components (year, month, day, hour, minute, second), as
+ pointer to struct tm or as dk4_time_t value.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4TIME_H_INCLUDED
+#include "dk4time.h"
+#endif
+
+#ifndef DK4TIMEC_H_INCLUDED
+#include "dk4timec.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert timestamp to wchar_t string.
+ CRT on Windows: Optional.
+ @param dptr Destination buffer address.
+ @param dsz Destination buffer size (number of wchar_t).
+ @param format Output format:
+ DK4_TIMEFORMAT_DATE_TIME for sortable date/time
+ combination
+ yyyy-mm-dd hh:mm:ss
+ (default),
+ DK4_TIMEFORMAT_DATE_SORTABLE for sortable date
+ yyyy-mm-dd,
+ DK4_TIMEFORMAT_DATE_ENGLISH for English style date
+ mm/dd/yyyy,
+ DK4_TIMEFORMAT_DATE_GERMAN for German style date
+ dd.mm.yyyy.
+ @param year Year.
+ @param month Month (1 to 12).
+ @param mday Day within month (1 to 31).
+ @param hour Hour of day (0 to 23).
+ @param min Minute within hour (0 to 59).
+ @param sec Second within minute (0 to 59).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or dsz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the buffer is too small.
+*/
+int
+dk4time_to_text_wc(
+ wchar_t *dptr,
+ size_t dsz,
+ int format,
+ unsigned short year,
+ unsigned short month,
+ unsigned short mday,
+ unsigned short hour,
+ unsigned short min,
+ unsigned short sec,
+ dk4_er_t *erp
+);
+
+/** Create text representation for a struct tm.
+ CRT on Windows: Optional.
+ @param dptr Destination buffer address.
+ @param dsz Destination buffer size (number of wchar_t).
+ @param tm Struct to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or dsz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the buffer is too small.
+*/
+int
+dk4time_convert_to_text_wc(
+ wchar_t *dptr, size_t dsz, const struct tm *tm, dk4_er_t *erp
+);
+
+/** Create text representation for timestamp.
+ CRT on Windows: Required.
+ @param dptr Destination buffer address.
+ @param dsz Destination buffer size (number of wchar_t).
+ @param timer Timestamp to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or dsz is 0,
+ - DK4_E_BUG<br>
+ if an internal conversion function fails,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the buffer is too small.
+*/
+int
+dk4time_as_text_wc(
+ wchar_t *dptr, size_t dsz, const dk4_time_t *timer, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4timewc.h"
+
+#ifndef DK4TIME08_H_INCLUDED
+#include "dk4time08.h"
+#endif
+
+#ifndef DK4REC23_H_INCLUDED
+#include "dk4rec23.h"
+#endif
+
+
+
+int
+dk4time_to_text_wc(
+ wchar_t *dptr,
+ size_t dsz,
+ int format,
+ unsigned short year,
+ unsigned short month,
+ unsigned short mday,
+ unsigned short hour,
+ unsigned short min,
+ unsigned short sec,
+ dk4_er_t *erp
+)
+{
+ char buffer[64];
+ int back = 0;
+ back = dk4time_to_text_c8(
+ buffer, sizeof(buffer), format, year, month, mday, hour, min, sec, erp
+ );
+ if (0 != back) {
+ back = dk4recode_char_to_wchar_t(dptr, dsz, buffer, erp);
+ }
+ return back;
+}
+
+
+
+int
+dk4time_convert_to_text_wc(
+ wchar_t *dptr, size_t dsz, const struct tm *tm, dk4_er_t *erp
+)
+{
+ int back = 0;
+ if ((NULL != dptr) && (0 < dsz)) {
+ *dptr = L'\0';
+ if (NULL != tm) {
+ back = dk4time_to_text_wc(
+ dptr, dsz, DK4_TIMEFORMAT_DATE_TIME,
+ (1900 + tm->tm_year), (1 + tm->tm_mon), tm->tm_mday,
+ tm->tm_hour, tm->tm_min, tm->tm_sec,
+ erp
+ );
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+static
+int
+dk4time_i_as_text_wc(
+ wchar_t *dptr, size_t dsz, const dk4_time_t *timer, dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+ /* +++ Windows */
+ struct tm lct;
+ int back = 0;
+ if (0 == _localtime64_s(&lct, timer)) {
+ back = dk4time_convert_to_text_wc(dptr, dsz, &lct, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ return back;
+ /* --- Windows */
+#else
+ /* +++ non-Windows */
+#if DK4_HAVE_LOCALTIME_R
+ struct tm lct;
+ int back = 0;
+ if (NULL != localtime_r(timer, &lct)) {
+ back = dk4time_convert_to_text_wc(dptr, dsz, &lct, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUG);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+ /* --- non-Windows */
+#endif
+}
+
+
+
+int
+dk4time_as_text_wc(
+ wchar_t *dptr, size_t dsz, const dk4_time_t *timer, dk4_er_t *erp
+)
+{
+ int back = 0;
+ if ((dptr != NULL) && (0 < dsz)) {
+ *dptr = L'\0';
+ if (NULL != timer) {
+ back = dk4time_i_as_text_wc(dptr, dsz, timer, erp);
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4timewc.h b/support/dktools/dk4timewc.h
new file mode 100644
index 0000000000..f5dbf1c70e
--- /dev/null
+++ b/support/dktools/dk4timewc.h
@@ -0,0 +1,164 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4timewc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4TIMEWC_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4TIMEWC_H_INCLUDED 1
+
+
+#line 10 "dk4timewc.ctr"
+
+/** @file
+ Convert timestamp to wchar_t string, timestamp either given as set
+ of components (year, month, day, hour, minute, second), as
+ pointer to struct tm or as dk4_time_t value.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4TIME_H_INCLUDED
+#include "dk4time.h"
+#endif
+
+#ifndef DK4TIMEC_H_INCLUDED
+#include "dk4timec.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Convert timestamp to wchar_t string.
+ CRT on Windows: Optional.
+ @param dptr Destination buffer address.
+ @param dsz Destination buffer size (number of wchar_t).
+ @param format Output format:
+ DK4_TIMEFORMAT_DATE_TIME for sortable date/time
+ combination
+ yyyy-mm-dd hh:mm:ss
+ (default),
+ DK4_TIMEFORMAT_DATE_SORTABLE for sortable date
+ yyyy-mm-dd,
+ DK4_TIMEFORMAT_DATE_ENGLISH for English style date
+ mm/dd/yyyy,
+ DK4_TIMEFORMAT_DATE_GERMAN for German style date
+ dd.mm.yyyy.
+ @param year Year.
+ @param month Month (1 to 12).
+ @param mday Day within month (1 to 31).
+ @param hour Hour of day (0 to 23).
+ @param min Minute within hour (0 to 59).
+ @param sec Second within minute (0 to 59).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or dsz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the buffer is too small.
+*/
+int
+dk4time_to_text_wc(
+ wchar_t *dptr,
+ size_t dsz,
+ int format,
+ unsigned short year,
+ unsigned short month,
+ unsigned short mday,
+ unsigned short hour,
+ unsigned short min,
+ unsigned short sec,
+ dk4_er_t *erp
+);
+
+/** Create text representation for a struct tm.
+ CRT on Windows: Optional.
+ @param dptr Destination buffer address.
+ @param dsz Destination buffer size (number of wchar_t).
+ @param tm Struct to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or dsz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the buffer is too small.
+*/
+int
+dk4time_convert_to_text_wc(
+ wchar_t *dptr, size_t dsz, const struct tm *tm, dk4_er_t *erp
+);
+
+/** Create text representation for timestamp.
+ CRT on Windows: Required.
+ @param dptr Destination buffer address.
+ @param dsz Destination buffer size (number of wchar_t).
+ @param timer Timestamp to convert.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr is NULL or dsz is 0,
+ - DK4_E_BUG<br>
+ if an internal conversion function fails,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the buffer is too small.
+*/
+int
+dk4time_as_text_wc(
+ wchar_t *dptr, size_t dsz, const dk4_time_t *timer, dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4tsp.h b/support/dktools/dk4tsp.h
new file mode 100644
index 0000000000..d231af5a5a
--- /dev/null
+++ b/support/dktools/dk4tsp.h
@@ -0,0 +1,43 @@
+#ifndef DK4TSP_H_INCLUDED
+#define DK4TSP_H_INCLUDED 1
+
+/** @file dk4tsp.h Text stream processing.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+/** Position in a data stream.
+*/
+typedef struct {
+ dk4_um_t bytes; /**< Number of bytes successfully processed. */
+ dk4_um_t chars; /**< Number of current character. */
+ dk4_um_t lineno; /**< Current line number. */
+ dk4_um_t charil; /**< Number of current character in line. */
+} dk4_text_stream_position_t;
+
+/** Results from processing a text character or a line.
+*/
+enum {
+ /** Text processing succeeded.
+ */
+ DK4_TSP_RES_OK = 1,
+
+ /** There was an error while applying
+ the information, but we can continue.
+ */
+ DK4_TSP_RES_ERROR = 0,
+
+ /** Fatal error while applying information,
+ abort processing.
+ */
+ DK4_TSP_RES_FATAL = -1
+};
+
+#endif
+
diff --git a/support/dktools/dk4tsp08.c b/support/dktools/dk4tsp08.c
new file mode 100644
index 0000000000..0a42521f52
--- /dev/null
+++ b/support/dktools/dk4tsp08.c
@@ -0,0 +1,936 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4tsp08.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4tsp08.c The dk4tsp08 module.
+*/
+
+
+#line 254 "dk4tsp08.ctr"
+
+#include "dk4tsp.h"
+#include "dk4tsp08.h"
+#include "dk4mem.h"
+#include "dk4enc.h"
+#include "dk4ansi.h"
+#include "dk4utf8.h"
+#include "dk4utf16.h"
+#include "dk4c32.h"
+#include "dk4bom.h"
+
+
+
+
+
+#line 268 "dk4tsp08.ctr"
+
+
+
+/** Initialize text stream processor structure.
+ @param tsp Text stream processor to set up.
+ @param eie Expected input encoding.
+*/
+static
+void
+dk4tsp08_init(dk4_tsp08_t *tsp, int eie)
+{
+
+
+#line 280 "dk4tsp08.ctr"
+ DK4_MEMRES(tsp, sizeof(dk4_tsp08_t));
+ dk4bom_detect_init(&(tsp->bomd), eie);
+ dk4error_init(&(tsp->er_en));
+ dk4error_init(&(tsp->er_pr));
+ tsp->inbuf = NULL;
+ tsp->obj = NULL;
+ tsp->in_sz = 0;
+ tsp->in_us = 0;
+ tsp->ief = eie;
+ tsp->iee = eie;
+ tsp->upt = 0;
+ tsp->pen = 0;
+
+#line 292 "dk4tsp08.ctr"
+ tsp->pst = 0;
+ tsp->pth = 0;
+ (tsp->pos).bytes = (dk4_um_t)0UL;
+ (tsp->pos).chars = (dk4_um_t)1UL;
+
+#line 296 "dk4tsp08.ctr"
+ (tsp->pos).lineno = (dk4_um_t)1UL;
+ (tsp->pos).charil = (dk4_um_t)1UL;
+
+
+#line 299 "dk4tsp08.ctr"
+}
+
+
+
+/** Initialize decoder for found input encoding.
+ @param tsp Text stream processor.
+*/
+static
+void
+dk4tsp08_initialize_decoder(dk4_tsp08_t *tsp)
+{
+
+
+#line 311 "dk4tsp08.ctr"
+ if (0 == tsp->pth) {
+ switch (tsp->ief) {
+ case DK4_FILE_ENCODING_UTF8: {
+ dk4utf8_init(&((tsp->dec).u08));
+ } break;
+ case DK4_FILE_ENCODING_UTF16_LE: {
+ dk4utf16_byte_init(&((tsp->dec).u16), 0);
+ } break;
+ case DK4_FILE_ENCODING_UTF16_BE: {
+ dk4utf16_byte_init(&((tsp->dec).u16), 1);
+ } break;
+ case DK4_FILE_ENCODING_32_LE: {
+ dk4c32_decoder_init(&((tsp->dec).c32), 0);
+ } break;
+ case DK4_FILE_ENCODING_32_BE: {
+ dk4c32_decoder_init(&((tsp->dec).c32), 1);
+ } break;
+ }
+ }
+
+#line 330 "dk4tsp08.ctr"
+}
+
+
+
+/** Process group of characters (one UTF-8 encoded 32 bit character).
+ @param tsp Text stream processor.
+ @param buf Buffer containing characters to process.
+ @param sz Number of characters in buffer.
+ @return DK4_TSP_RES_OK if the characters were processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+dk4tsp08_process_group(dk4_tsp08_t *tsp, char *buf, size_t sz)
+{
+ size_t i;
+ int back = DK4_TSP_RES_FATAL;
+ int res;
+
+
+#line 353 "dk4tsp08.ctr"
+ /* Increase character numbers
+ */
+ (tsp->pos).chars += (dk4_um_t)1UL;
+
+#line 356 "dk4tsp08.ctr"
+ (tsp->pos).charil += (dk4_um_t)1UL;
+ /* Decide between line by line or char by char processing */
+ if ((NULL != tsp->inbuf) && (0 < tsp->in_sz) && (NULL != (tsp->fct).lh)) {
+ /* Line processing */
+ if (sz < tsp->in_sz) {
+ if ((tsp->in_sz - sz) > tsp->in_us) {
+ back = DK4_TSP_RES_OK;
+ DK4_MEMCPY( &((tsp->inbuf)[tsp->in_us]), buf, sz );
+ tsp->in_us += sz;
+ if ((1 == sz) && ('\n' == buf[0])) {
+ back = DK4_TSP_RES_FATAL;
+ if (tsp->in_us < tsp->in_sz) {
+ (tsp->inbuf)[tsp->in_us] = '\0';
+ back = (*((tsp->fct).lh))(
+ tsp->obj,tsp->inbuf,(tsp->pos).lineno,&(tsp->er_pr)
+ );
+ } else {
+ /* ERROR: Line too long! */
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_BUFFER_TOO_SMALL,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ tsp->in_us = 0;
+ }
+ } else {
+ /* ERROR: Line too long! */
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_BUFFER_TOO_SMALL,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ } else {
+ /* ERROR: Line too long! */
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_BUFFER_TOO_SMALL,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ } else {
+ /* Direct char processing */
+ if (NULL != (tsp->fct).ch) {
+ back = DK4_TSP_RES_OK;
+ for (i = 0; i < sz; i++) {
+ res = (*((tsp->fct).ch))(tsp->obj, buf[i], &(tsp->pos), &(tsp->er_pr));
+ switch (res) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) { back = DK4_TSP_RES_ERROR; }
+ } break;
+ }
+ }
+ } else {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_INVALID_ARGUMENTS,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ }
+ /* After newline correct line number and position in line
+ */
+ if (1 == sz) {
+ if ('\n' == buf[0]) {
+ (tsp->pos).lineno += (dk4_um_t)1UL;
+ (tsp->pos).charil = (dk4_um_t)1UL;
+ }
+ }
+
+#line 429 "dk4tsp08.ctr"
+ return back;
+}
+
+
+/** Normal processing for one byte.
+ @param tsp Text stream processor.
+ @param inbyte Byte to process.
+ @return Operation result, one from DK4_TSP_RES_OK,
+ DK4_TSP_RES_ERROR or DK4_TSP_RES_FATAL.
+*/
+static
+int
+dk4tsp08_process_byte(
+ dk4_tsp08_t *tsp,
+ unsigned char inbyte
+)
+{
+ unsigned char buf[8];
+ dk4_c32_t c32;
+ size_t sz;
+ int back = DK4_TSP_RES_FATAL;
+ int cuc32 = 0;
+ int res = 0;
+ unsigned char uc = '\0';
+ char c08;
+
+
+#line 455 "dk4tsp08.ctr"
+ if (0 != tsp->pth) {
+
+#line 456 "dk4tsp08.ctr"
+ back = dk4tsp08_process_group(tsp, (char *)(&inbyte), 1);
+ } else {
+
+#line 458 "dk4tsp08.ctr"
+ /* Decode and process */
+ switch (tsp->ief) {
+ case DK4_FILE_ENCODING_ASCII: {
+
+#line 461 "dk4tsp08.ctr"
+ c32 = (dk4_c32_t)inbyte;
+ cuc32 = 1;
+ } break;
+ case DK4_FILE_ENCODING_ANSI: {
+
+#line 465 "dk4tsp08.ctr"
+ if (0 != dk4ansi_decode(&c32, inbyte)) {
+ cuc32 = 1;
+ } else {
+
+#line 468 "dk4tsp08.ctr"
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ } break;
+ case DK4_FILE_ENCODING_UTF8: {
+
+#line 476 "dk4tsp08.ctr"
+ res = dk4utf8_add(&((tsp->dec).u08), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ERROR: {
+
+#line 479 "dk4tsp08.ctr"
+ /* Decoding error */
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ } break;
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf8_get(&((tsp->dec).u08));
+ cuc32 = 1;
+ dk4utf8_init(&((tsp->dec).u08));
+ } break;
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ }
+ } break;
+ case DK4_FILE_ENCODING_UTF16_LE: {
+
+#line 497 "dk4tsp08.ctr"
+ res = dk4utf16_byte_add(&((tsp->dec).u16), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ERROR: {
+
+#line 500 "dk4tsp08.ctr"
+ /* Decoding error */
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ } break;
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf16_byte_get(&((tsp->dec).u16));
+ cuc32 = 1;
+ dk4utf16_byte_init(&((tsp->dec).u16), 0);
+ } break;
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ }
+ } break;
+ case DK4_FILE_ENCODING_UTF16_BE: {
+
+#line 518 "dk4tsp08.ctr"
+ res = dk4utf16_byte_add(&((tsp->dec).u16), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ERROR: {
+
+#line 521 "dk4tsp08.ctr"
+ /* Decoding error */
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ } break;
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf16_byte_get(&((tsp->dec).u16));
+ cuc32 = 1;
+ dk4utf16_byte_init(&((tsp->dec).u16), 1);
+ } break;
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ }
+ } break;
+ case DK4_FILE_ENCODING_32_LE: {
+
+#line 539 "dk4tsp08.ctr"
+ res = dk4c32_decoder_add(&((tsp->dec).c32), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ERROR: {
+
+#line 542 "dk4tsp08.ctr"
+ /* Decoding error */
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ } break;
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4c32_decoder_get(&((tsp->dec).c32));
+ cuc32 = 1;
+ dk4c32_decoder_init(&((tsp->dec).c32), 0);
+ } break;
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ }
+ } break;
+ case DK4_FILE_ENCODING_32_BE: {
+
+#line 560 "dk4tsp08.ctr"
+ res = dk4c32_decoder_add(&((tsp->dec).c32), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ERROR: {
+
+#line 563 "dk4tsp08.ctr"
+ /* Decoding error */
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ } break;
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4c32_decoder_get(&((tsp->dec).c32));
+ cuc32 = 1;
+ dk4c32_decoder_init(&((tsp->dec).c32), 1);
+ } break;
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ }
+ } break;
+ }
+ if (0 != cuc32) {
+ switch (tsp->pen) {
+ case DK4_ENCODING_ASCII: {
+
+#line 584 "dk4tsp08.ctr"
+ if (dkC32(0x00000100) > c32) {
+ c08 = (char)c32;
+ back = dk4tsp08_process_group(tsp, &c08, 1);
+ } else {
+
+#line 588 "dk4tsp08.ctr"
+ /* Encoding error */
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_ENCODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ } break;
+ case DK4_ENCODING_ANSI: {
+
+#line 597 "dk4tsp08.ctr"
+ if (0 != dk4ansi_encode(&uc, c32)) {
+ c08 = (char)uc;
+ back = dk4tsp08_process_group(tsp, &c08, 1);
+ } else {
+
+#line 601 "dk4tsp08.ctr"
+ /* Encoding error */
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_ENCODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ } break;
+ case DK4_ENCODING_UTF8: {
+
+#line 610 "dk4tsp08.ctr"
+ sz = sizeof(buf);
+ if (0 != dk4utf8_encode(buf, &sz, c32, NULL)) {
+ back = dk4tsp08_process_group(tsp, (char *)buf, sz);
+ } else {
+
+#line 614 "dk4tsp08.ctr"
+ /* Encoding error */
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_ENCODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ } break;
+ }
+ }
+ }
+ if (DK4_TSP_RES_FATAL == back) {
+ tsp->pst = 2;
+ }
+
+
+#line 629 "dk4tsp08.ctr"
+ return back;
+}
+
+
+
+/** Add one byte to internal data structures
+ (BOM detection and/or normal processing).
+ @param tsp Text stream processor.
+ @param inbyte Byte to add.
+ @return Operation result, one from DK4_TSP_RES_OK,
+ DK4_TSP_RES_ERROR or DK4_TSP_RES_FATAL.
+*/
+static
+int
+dk4tsp08_i_add_one_byte(
+ dk4_tsp08_t *tsp,
+ unsigned char inbyte
+)
+{
+ size_t nrej = 0;
+ size_t i = 0;
+ int back = DK4_TSP_RES_FATAL;
+ int res;
+ unsigned char uc;
+
+
+#line 654 "dk4tsp08.ctr"
+ (tsp->pos).bytes += (dk4_um_t)1UL;
+ switch (tsp->pst) {
+ case 0: { /* BOM detection */
+
+
+#line 658 "dk4tsp08.ctr"
+ res = dk4bom_detect_add(&(tsp->bomd), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ case DK4_EDSTM_FINISHED:
+ case DK4_EDSTM_FINISHED_WITH_UNUSED: {
+
+
+#line 666 "dk4tsp08.ctr"
+ /* This result is ok. */
+ back = DK4_TSP_RES_OK;
+ /* Retrieve found encoding */
+ tsp->ief = dk4bom_detect_get_encoding(&(tsp->bomd));
+ /* Check whether we can pass through data unchanged */
+ if (tsp->ief == tsp->pen) {
+ switch (tsp->ief) {
+
+#if VERSION_BEFORE_20150321
+ /* 2015-30-21 We do not hard-code the decision whether or
+ not to enable pass-through for UTF-8
+ encoded bytes, better use a run-time
+ decision.
+ */
+ case DK4_ENCODING_ASCII:
+ case DK4_ENCODING_ANSI:
+#if 0
+ /* 2014-12-01
+ We must make sure to process the complete UTF-8
+ representation of a glyph completely.
+ */
+ case DK4_ENCODING_UTF8:
+#endif
+ {
+ tsp->pth = 1;
+
+#line 691 "dk4tsp08.ctr"
+ } break;
+#endif
+
+ case DK4_ENCODING_ASCII :
+ case DK4_ENCODING_ANSI : {
+ tsp->pth = 1;
+ } break;
+ case DK4_ENCODING_UTF8 : {
+ if (0 != tsp->upt) { tsp->pth = 1; }
+ } break;
+ }
+ }
+ /* If necessary, initialize decoder */
+ dk4tsp08_initialize_decoder(tsp);
+ /* Switch to normal processing */
+ tsp->pst = 1;
+ /* Process bytes stored in BOM detector */
+ if (DK4_EDSTM_FINISHED_WITH_UNUSED == res) {
+ nrej = dk4bom_detect_num_unused_bytes(&(tsp->bomd));
+ if (0 < nrej) {
+
+
+#line 712 "dk4tsp08.ctr"
+ for (i = 0; ((i < nrej) && (DK4_TSP_RES_FATAL != back)); i++) {
+ uc = dk4bom_detect_unused_byte(&(tsp->bomd), i);
+
+
+#line 715 "dk4tsp08.ctr"
+ switch (dk4tsp08_process_byte(tsp, uc)) {
+ case DK4_TSP_RES_FATAL: {
+
+#line 717 "dk4tsp08.ctr"
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+
+#line 721 "dk4tsp08.ctr"
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ }
+ }
+ }
+ } break;
+ case DK4_EDSTM_ERROR: {
+
+#line 730 "dk4tsp08.ctr"
+ } break;
+ }
+ } break;
+ case 1: { /* Normal processing */
+
+
+#line 735 "dk4tsp08.ctr"
+ back = dk4tsp08_process_byte(tsp, inbyte);
+ } break;
+ /*
+ Processing stage 2 indicates there was a serious error
+ before, we must skip further processing.
+ This situation is covered by the initialization value
+ DK4_TSP_RES_FATAL, so we do not need a case branch here.
+ */
+ }
+
+
+#line 745 "dk4tsp08.ctr"
+ return back;
+}
+
+
+
+int
+dk4tsp08_setup_char(
+ dk4_tsp08_t *tsp,
+ void *obj,
+ dk4_c8_handler_t *fct,
+ int pre,
+ int eie,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+
+
+#line 762 "dk4tsp08.ctr"
+ if (NULL != tsp) {
+
+#line 763 "dk4tsp08.ctr"
+ dk4tsp08_init(tsp, eie);
+ if (NULL != fct) {
+
+#line 765 "dk4tsp08.ctr"
+ switch (pre) {
+ case DK4_ENCODING_ASCII:
+ case DK4_ENCODING_ANSI:
+ case DK4_ENCODING_UTF8:
+ {
+ tsp->obj = obj;
+ (tsp->fct).ch = fct;
+ tsp->pen = pre;
+ tsp->iee = eie;
+
+#line 774 "dk4tsp08.ctr"
+ tsp->ief = eie;
+ back = 1;
+ } break;
+ default: {
+
+#line 778 "dk4tsp08.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ tsp->pst = 2;
+ } break;
+ }
+ } else {
+
+#line 783 "dk4tsp08.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ tsp->pst = 2;
+ }
+ } else {
+
+#line 787 "dk4tsp08.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 789 "dk4tsp08.ctr"
+ return back;
+}
+
+
+int
+dk4tsp08_setup_line(
+ dk4_tsp08_t *tsp,
+ void *obj,
+ dk4_c8_line_handler_t *fct,
+ char *inbuf,
+ size_t szin,
+ int pre,
+ int eie,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+
+
+#line 807 "dk4tsp08.ctr"
+ if (NULL != tsp) {
+
+#line 808 "dk4tsp08.ctr"
+ dk4tsp08_init(tsp, eie);
+ if ((NULL != fct) && (NULL != inbuf) && (0 < szin)) {
+
+
+#line 811 "dk4tsp08.ctr"
+ switch (pre) {
+ case DK4_ENCODING_ASCII:
+ case DK4_ENCODING_ANSI:
+ case DK4_ENCODING_UTF8:
+ {
+ tsp->obj = obj;
+ (tsp->fct).lh = fct;
+ tsp->inbuf = inbuf;
+ tsp->in_sz = szin;
+ tsp->in_us = 0;
+ tsp->pen = pre;
+ tsp->iee = eie;
+ tsp->ief = eie;
+ back = 1;
+ } break;
+ default: {
+
+#line 827 "dk4tsp08.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ tsp->pst = 2;
+ } break;
+ }
+ } else {
+
+#line 832 "dk4tsp08.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ tsp->pst = 2;
+ }
+ } else {
+
+#line 836 "dk4tsp08.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 838 "dk4tsp08.ctr"
+ return back;
+}
+
+
+
+int
+dk4tsp08_add_one_byte(
+ dk4_tsp08_t *tsp,
+ unsigned char inbyte
+)
+{
+ int back = DK4_TSP_RES_FATAL;
+
+
+#line 851 "dk4tsp08.ctr"
+ if (NULL != tsp) {
+ if (2 > tsp->pst) {
+ back = dk4tsp08_i_add_one_byte(tsp, inbyte);
+ }
+ }
+
+#line 856 "dk4tsp08.ctr"
+ return back;
+}
+
+
+
+int
+dk4tsp08_add_bytes(
+ dk4_tsp08_t *tsp,
+ const unsigned char *buffer,
+ size_t sz
+)
+{
+ int back = DK4_TSP_RES_FATAL;
+ int res;
+
+
+#line 871 "dk4tsp08.ctr"
+ if ((NULL != tsp) && (NULL != buffer) && (0 < sz)) {
+ if (2 > tsp->pst) {
+ back = DK4_TSP_RES_OK;
+ while((sz--) && (2 > tsp->pst)) {
+ res = dk4tsp08_i_add_one_byte(tsp, *(buffer++));
+ switch (res) {
+ case DK4_TSP_RES_FATAL: {
+
+#line 878 "dk4tsp08.ctr"
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+
+#line 882 "dk4tsp08.ctr"
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ }
+ }
+ }
+
+#line 889 "dk4tsp08.ctr"
+ return back;
+}
+
+
+
+int
+dk4tsp08_finish(dk4_tsp08_t *tsp)
+{
+ size_t nrej = 0;
+ size_t i = 0;
+ int back = DK4_TSP_RES_FATAL;
+ int res;
+ unsigned char uc;
+
+
+#line 903 "dk4tsp08.ctr"
+ if (NULL != tsp) {
+ /* Retrieve rejected bytes from BOM detector */
+ back = DK4_TSP_RES_OK;
+ if (0 == tsp->pst) {
+
+#line 907 "dk4tsp08.ctr"
+ tsp->pst = 1;
+ nrej = dk4bom_detect_num_unused_bytes(&(tsp->bomd));
+ if (0 < nrej) {
+ dk4tsp08_initialize_decoder(tsp);
+ for (i = 0; ((i < nrej) && (2 > tsp->pst)); i++) {
+ uc = dk4bom_detect_unused_byte(&(tsp->bomd), i);
+
+
+#line 914 "dk4tsp08.ctr"
+ switch (dk4tsp08_process_byte(tsp, uc)) {
+ case DK4_TSP_RES_FATAL: {
+
+#line 916 "dk4tsp08.ctr"
+ back = DK4_TSP_RES_FATAL;
+ tsp->pst = 2;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+
+#line 920 "dk4tsp08.ctr"
+ if (DK4_TSP_RES_OK == back) { back = DK4_TSP_RES_ERROR; }
+ } break;
+ }
+ }
+ }
+ } else {
+
+#line 926 "dk4tsp08.ctr"
+ }
+ /* Process final line */
+ if ((NULL != tsp->inbuf) && (0 < tsp->in_sz) && (NULL != (tsp->fct).lh)) {
+ if (0 < tsp->in_us) {
+
+
+#line 931 "dk4tsp08.ctr"
+ if (2 > tsp->pst) {
+ if (tsp->in_us < tsp->in_sz) {
+
+#line 933 "dk4tsp08.ctr"
+ (tsp->inbuf)[tsp->in_us] = '\0';
+
+#line 934 "dk4tsp08.ctr"
+ res =
+ (*((tsp->fct).lh))(
+ tsp->obj,tsp->inbuf,(tsp->pos).lineno,&(tsp->er_pr)
+ );
+ switch (res) {
+ case DK4_TSP_RES_FATAL: {
+
+#line 940 "dk4tsp08.ctr"
+ back = DK4_TSP_RES_FATAL;
+ tsp->pst = 2;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+
+#line 944 "dk4tsp08.ctr"
+ if (DK4_TSP_RES_OK == back) { back = DK4_TSP_RES_ERROR; }
+ } break;
+ }
+ } else {
+
+#line 948 "dk4tsp08.ctr"
+ back = DK4_TSP_RES_FATAL;
+ tsp->pst = 2;
+ /* ERROR: Line too long! */
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_BUFFER_TOO_SMALL,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ } else {
+
+#line 958 "dk4tsp08.ctr"
+ }
+ }
+ }
+ }
+
+
+#line 963 "dk4tsp08.ctr"
+ return back;
+}
+
+
+
+void
+dk4tsp08_get_errors(dk4_er_t *er_en, dk4_er_t *er_pr, dk4_tsp08_t *tsp)
+{
+ if (NULL != tsp) {
+ if (NULL != er_en) {
+ DK4_MEMCPY(er_en, &(tsp->er_en), sizeof(dk4_er_t));
+ }
+ if (NULL != er_pr) {
+ DK4_MEMCPY(er_pr, &(tsp->er_pr), sizeof(dk4_er_t));
+ }
+ }
+}
+
+
+
+void
+dk4tsp08_enable_utf8_pass_through(dk4_tsp08_t *tsp, int fl)
+{
+ if (NULL != tsp) {
+ tsp->upt = ((0 != fl) ? 1 : 0);
+ }
+}
+
+
diff --git a/support/dktools/dk4tsp08.ctr b/support/dktools/dk4tsp08.ctr
new file mode 100644
index 0000000000..e8a0ceec5e
--- /dev/null
+++ b/support/dktools/dk4tsp08.ctr
@@ -0,0 +1,991 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk4tsp08.h Text stream processing for 8 bit characters.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4BOM_H_INCLUDED
+#include "dk4bom.h"
+#endif
+
+#ifndef DK4TSP_H_INCLUDED
+#include "dk4tsp.h"
+#endif
+
+#ifndef DK4UTF8_H_INCLUDED
+#include "dk4utf8.h"
+#endif
+
+#ifndef DK4UTF16_H_INCLUDED
+#include "dk4utf16.h"
+#endif
+
+#ifndef DK4C32_H_INCLUDED
+#include "dk4c32.h"
+#endif
+
+/** Handler function for single characters.
+ @param obj Object to modify while processing the character.
+ @param c Character to process.
+ @param pos Current position in file or data stream.
+ @param erp Error report, may be NULL.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+typedef int dk4_c8_handler_t(
+ void *obj,
+ char c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+);
+
+/** Handler function for text lines.
+ @param obj Object to modify while processing the character.
+ @param line Text line to process.
+ @param lineno Current line number.
+ @param erp Error report, may be NULL.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+typedef int dk4_c8_line_handler_t(
+ void *obj,
+ char *line,
+ dk4_um_t lineno,
+ dk4_er_t *erp
+);
+
+/** Structure for 8 bit character processing.
+*/
+typedef struct {
+ union {
+ dk4_utf8_decoder_t u08; /**< UTF-8 decoder. */
+ dk4_utf16_byte_decoder_t u16; /**< UTF-16 decoder. */
+ dk4_c32_byte_decoder_t c32; /**< 32 bit char decoder. */
+ } dec; /**< Input decoder. */
+ dk4_bom_detector_t bomd; /**< BOM detector. */
+ dk4_text_stream_position_t pos; /**< Current position. */
+ dk4_er_t er_en; /**< Errors in input decoding. */
+ dk4_er_t er_pr; /**< Errors in processing. */
+ union {
+ dk4_c8_line_handler_t *lh; /**< Handler function for lines. */
+ dk4_c8_handler_t *ch; /**< Handler function for char. */
+ } fct; /**< Handler function. */
+ char *inbuf; /**< Buffer for input line. */
+ void *obj; /**< Object to modify in processing. */
+ size_t in_sz; /**< Size of input line buffer. */
+ size_t in_us; /**< Used bytes in input line buffer. */
+ int upt; /**< Flag: Enable UTF-8 pass through. */
+ int ief; /**< Input encoding found. */
+ int iee; /**< Input encoding expected. */
+ int pen; /**< Encoding for processing. */
+ int pst; /**< Processing stage. */
+ int pth; /**< Flag: Pass through. */
+} dk4_tsp08_t;
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Set up processor for byte by byte processing.
+ @param tsp Processor to set up.
+ @param obj Object to modify when processing input, may be NULL.
+ @param fct Handler function to call for each character.
+ @param pre Encoding required for processing.
+ @param eie Expected input encoding.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if tsp or fct is NULL or pre is not an encoding for 8-bit characters.
+*/
+int
+dk4tsp08_setup_char(
+ dk4_tsp08_t *tsp,
+ void *obj,
+ dk4_c8_handler_t *fct,
+ int pre,
+ int eie,
+ dk4_er_t *erp
+);
+
+/** Set up processor for line processing.
+ @param tsp Processor to set up.
+ @param obj Object to modify when processing input, may be NULL.
+ @param fct Handler function to invoke for each line.
+ @param inbuf Input line buffer.
+ @param szin Size of input line buffer.
+ @param pre Encoding required for processing.
+ @param eie Expected input encoding.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if tsp, fct or inbuf is NULL, szin is 0 or pre is not a
+ valid encoding for 8-bit characters.
+*/
+int
+dk4tsp08_setup_line(
+ dk4_tsp08_t *tsp,
+ void *obj,
+ dk4_c8_line_handler_t *fct,
+ char *inbuf,
+ size_t szin,
+ int pre,
+ int eie,
+ dk4_er_t *erp
+);
+
+/** Enable or disable pass-through of UTF-8 encoded data.
+ Use this function after dk4tsp08_setup_line() or
+ dk4tsp08_setup_char() but before adding the first byte.
+ @param tsp Text stream processor to configure.
+ @param fl Flag: Enabled.
+*/
+void
+dk4tsp08_enable_utf8_pass_through(dk4_tsp08_t *tsp, int fl);
+
+/** Add one single byte.
+ @param tsp Text stream processor.
+ @param inbyte Byte to process.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+int
+dk4tsp08_add_one_byte(
+ dk4_tsp08_t *tsp,
+ unsigned char inbyte
+);
+
+/** Add multiple bytes.
+ @param tsp Text stream processor.
+ @param buffer Buffer start address.
+ @param sz Number of bytes in buffer.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+int
+dk4tsp08_add_bytes(
+ dk4_tsp08_t *tsp,
+ const unsigned char *buffer,
+ size_t sz
+);
+
+/** Finish processing.
+ @param tsp Text stream processor.
+ @return DK4_TSP_RES_OK if processing was finished
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error,
+ DK4_TSP_RES_FATAL if there was a fatal error.
+*/
+int
+dk4tsp08_finish(dk4_tsp08_t *tsp);
+
+/** Retrieve error reports for encoding/decoding and processing.
+ @param er_en Destination error report buffer for encoding/decoding.
+ @param er_pr Destination error report buffer for processing.
+ @param tsp Text stream processor to retrieve errors from.
+
+ Error codes er_en:
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the input buffer provided in dk4tsp08_setup_line() is too
+ small,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if no character processing function was provided,
+ - DK4_E_DECODING_FAILED<br>
+ if there were decoding errors,
+ - DK4_E_ENCODING_FAILED<br>
+ if there were encoding errors.
+
+ Error codes er_pr:
+ - The error codes returned in er_pr depend on the processing
+ function.
+*/
+void
+dk4tsp08_get_errors(dk4_er_t *er_en, dk4_er_t *er_pr, dk4_tsp08_t *tsp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4tsp.h"
+#include "dk4tsp08.h"
+#include "dk4mem.h"
+#include "dk4enc.h"
+#include "dk4ansi.h"
+#include "dk4utf8.h"
+#include "dk4utf16.h"
+#include "dk4c32.h"
+#include "dk4bom.h"
+
+
+
+$!trace-include
+
+
+
+/** Initialize text stream processor structure.
+ @param tsp Text stream processor to set up.
+ @param eie Expected input encoding.
+*/
+static
+void
+dk4tsp08_init(dk4_tsp08_t *tsp, int eie)
+{
+ $? "+ dk4tsp08_init"
+ DK4_MEMRES(tsp, sizeof(dk4_tsp08_t));
+ dk4bom_detect_init(&(tsp->bomd), eie);
+ dk4error_init(&(tsp->er_en));
+ dk4error_init(&(tsp->er_pr));
+ tsp->inbuf = NULL;
+ tsp->obj = NULL;
+ tsp->in_sz = 0;
+ tsp->in_us = 0;
+ tsp->ief = eie;
+ tsp->iee = eie;
+ tsp->upt = 0;
+ tsp->pen = 0; $? ". pen = 0"
+ tsp->pst = 0;
+ tsp->pth = 0;
+ (tsp->pos).bytes = (dk4_um_t)0UL;
+ (tsp->pos).chars = (dk4_um_t)1UL; $? ". chars = 1"
+ (tsp->pos).lineno = (dk4_um_t)1UL;
+ (tsp->pos).charil = (dk4_um_t)1UL;
+ $? "- dk4tsp08_init"
+}
+
+
+
+/** Initialize decoder for found input encoding.
+ @param tsp Text stream processor.
+*/
+static
+void
+dk4tsp08_initialize_decoder(dk4_tsp08_t *tsp)
+{
+ $? "+ dk4tsp08_initialize_decoder"
+ if (0 == tsp->pth) {
+ switch (tsp->ief) {
+ case DK4_FILE_ENCODING_UTF8: {
+ dk4utf8_init(&((tsp->dec).u08));
+ } break;
+ case DK4_FILE_ENCODING_UTF16_LE: {
+ dk4utf16_byte_init(&((tsp->dec).u16), 0);
+ } break;
+ case DK4_FILE_ENCODING_UTF16_BE: {
+ dk4utf16_byte_init(&((tsp->dec).u16), 1);
+ } break;
+ case DK4_FILE_ENCODING_32_LE: {
+ dk4c32_decoder_init(&((tsp->dec).c32), 0);
+ } break;
+ case DK4_FILE_ENCODING_32_BE: {
+ dk4c32_decoder_init(&((tsp->dec).c32), 1);
+ } break;
+ }
+ } $? "- dk4tsp08_initialize_decoder"
+}
+
+
+
+/** Process group of characters (one UTF-8 encoded 32 bit character).
+ @param tsp Text stream processor.
+ @param buf Buffer containing characters to process.
+ @param sz Number of characters in buffer.
+ @return DK4_TSP_RES_OK if the characters were processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+dk4tsp08_process_group(dk4_tsp08_t *tsp, char *buf, size_t sz)
+{
+ size_t i;
+ int back = DK4_TSP_RES_FATAL;
+ int res;
+ $? "+ dk4tsp08_process_group %u", (unsigned)sz
+ /* Increase character numbers
+ */
+ (tsp->pos).chars += (dk4_um_t)1UL; $? ". increase chars %u", (unsigned)((tsp->pos).chars)
+ (tsp->pos).charil += (dk4_um_t)1UL;
+ /* Decide between line by line or char by char processing */
+ if ((NULL != tsp->inbuf) && (0 < tsp->in_sz) && (NULL != (tsp->fct).lh)) {
+ /* Line processing */
+ if (sz < tsp->in_sz) {
+ if ((tsp->in_sz - sz) > tsp->in_us) {
+ back = DK4_TSP_RES_OK;
+ DK4_MEMCPY( &((tsp->inbuf)[tsp->in_us]), buf, sz );
+ tsp->in_us += sz;
+ if ((1 == sz) && ('\n' == buf[0])) {
+ back = DK4_TSP_RES_FATAL;
+ if (tsp->in_us < tsp->in_sz) {
+ (tsp->inbuf)[tsp->in_us] = '\0';
+ back = (*((tsp->fct).lh))(
+ tsp->obj,tsp->inbuf,(tsp->pos).lineno,&(tsp->er_pr)
+ );
+ } else {
+ /* ERROR: Line too long! */
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_BUFFER_TOO_SMALL,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ tsp->in_us = 0;
+ }
+ } else {
+ /* ERROR: Line too long! */
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_BUFFER_TOO_SMALL,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ } else {
+ /* ERROR: Line too long! */
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_BUFFER_TOO_SMALL,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ } else {
+ /* Direct char processing */
+ if (NULL != (tsp->fct).ch) {
+ back = DK4_TSP_RES_OK;
+ for (i = 0; i < sz; i++) {
+ res = (*((tsp->fct).ch))(tsp->obj, buf[i], &(tsp->pos), &(tsp->er_pr));
+ switch (res) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) { back = DK4_TSP_RES_ERROR; }
+ } break;
+ }
+ }
+ } else {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_INVALID_ARGUMENTS,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ }
+ /* After newline correct line number and position in line
+ */
+ if (1 == sz) {
+ if ('\n' == buf[0]) {
+ (tsp->pos).lineno += (dk4_um_t)1UL;
+ (tsp->pos).charil = (dk4_um_t)1UL;
+ }
+ } $? "- dk4tsp08_process_group %d", back
+ return back;
+}
+
+
+/** Normal processing for one byte.
+ @param tsp Text stream processor.
+ @param inbyte Byte to process.
+ @return Operation result, one from DK4_TSP_RES_OK,
+ DK4_TSP_RES_ERROR or DK4_TSP_RES_FATAL.
+*/
+static
+int
+dk4tsp08_process_byte(
+ dk4_tsp08_t *tsp,
+ unsigned char inbyte
+)
+{
+ unsigned char buf[8];
+ dk4_c32_t c32;
+ size_t sz;
+ int back = DK4_TSP_RES_FATAL;
+ int cuc32 = 0;
+ int res = 0;
+ unsigned char uc = '\0';
+ char c08;
+ $? "+ dk4tsp08_process_byte %02x", (int)inbyte
+ if (0 != tsp->pth) { $? ". pass through"
+ back = dk4tsp08_process_group(tsp, (char *)(&inbyte), 1);
+ } else { $? ". decode and encode"
+ /* Decode and process */
+ switch (tsp->ief) {
+ case DK4_FILE_ENCODING_ASCII: { $? ". ASCII found"
+ c32 = (dk4_c32_t)inbyte;
+ cuc32 = 1;
+ } break;
+ case DK4_FILE_ENCODING_ANSI: { $? ". ANSI found"
+ if (0 != dk4ansi_decode(&c32, inbyte)) {
+ cuc32 = 1;
+ } else { $? "! ANSI decoding failed"
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ } break;
+ case DK4_FILE_ENCODING_UTF8: { $? ". UTF-8 found"
+ res = dk4utf8_add(&((tsp->dec).u08), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ERROR: { $? "! UTF-8 decoding failed"
+ /* Decoding error */
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ } break;
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf8_get(&((tsp->dec).u08));
+ cuc32 = 1;
+ dk4utf8_init(&((tsp->dec).u08));
+ } break;
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ }
+ } break;
+ case DK4_FILE_ENCODING_UTF16_LE: { $? ". UTF-16.LSB found"
+ res = dk4utf16_byte_add(&((tsp->dec).u16), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ERROR: { $? "! UTF-16.LSB failed"
+ /* Decoding error */
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ } break;
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf16_byte_get(&((tsp->dec).u16));
+ cuc32 = 1;
+ dk4utf16_byte_init(&((tsp->dec).u16), 0);
+ } break;
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ }
+ } break;
+ case DK4_FILE_ENCODING_UTF16_BE: { $? ". UTF-16.MSB found"
+ res = dk4utf16_byte_add(&((tsp->dec).u16), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ERROR: { $? "! UTF-16.MSB failed"
+ /* Decoding error */
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ } break;
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf16_byte_get(&((tsp->dec).u16));
+ cuc32 = 1;
+ dk4utf16_byte_init(&((tsp->dec).u16), 1);
+ } break;
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ }
+ } break;
+ case DK4_FILE_ENCODING_32_LE: { $? ". C32.LSB found"
+ res = dk4c32_decoder_add(&((tsp->dec).c32), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ERROR: { $? "! C32.LSB failed"
+ /* Decoding error */
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ } break;
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4c32_decoder_get(&((tsp->dec).c32));
+ cuc32 = 1;
+ dk4c32_decoder_init(&((tsp->dec).c32), 0);
+ } break;
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ }
+ } break;
+ case DK4_FILE_ENCODING_32_BE: { $? ". C32.MSB found"
+ res = dk4c32_decoder_add(&((tsp->dec).c32), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ERROR: { $? "! C32.MSB failed"
+ /* Decoding error */
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ } break;
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4c32_decoder_get(&((tsp->dec).c32));
+ cuc32 = 1;
+ dk4c32_decoder_init(&((tsp->dec).c32), 1);
+ } break;
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ }
+ } break;
+ }
+ if (0 != cuc32) {
+ switch (tsp->pen) {
+ case DK4_ENCODING_ASCII: { $? ". ASCII required"
+ if (dkC32(0x00000100) > c32) {
+ c08 = (char)c32;
+ back = dk4tsp08_process_group(tsp, &c08, 1);
+ } else { $? "! ASCII encoding failed for %lu",(unsigned long)c32
+ /* Encoding error */
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_ENCODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ } break;
+ case DK4_ENCODING_ANSI: { $? ". ANSI required"
+ if (0 != dk4ansi_encode(&uc, c32)) {
+ c08 = (char)uc;
+ back = dk4tsp08_process_group(tsp, &c08, 1);
+ } else { $? "! ANSI encoding failed for %lu", (unsigned long)c32
+ /* Encoding error */
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_ENCODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ } break;
+ case DK4_ENCODING_UTF8: { $? ". UTF-8 required"
+ sz = sizeof(buf);
+ if (0 != dk4utf8_encode(buf, &sz, c32, NULL)) {
+ back = dk4tsp08_process_group(tsp, (char *)buf, sz);
+ } else { $? "! UTF-8 encoding failed for %lu", (unsigned long)c32
+ /* Encoding error */
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_ENCODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ } break;
+ }
+ }
+ }
+ if (DK4_TSP_RES_FATAL == back) {
+ tsp->pst = 2;
+ }
+ $? "- dk4tsp08_process_byte %d", back
+ return back;
+}
+
+
+
+/** Add one byte to internal data structures
+ (BOM detection and/or normal processing).
+ @param tsp Text stream processor.
+ @param inbyte Byte to add.
+ @return Operation result, one from DK4_TSP_RES_OK,
+ DK4_TSP_RES_ERROR or DK4_TSP_RES_FATAL.
+*/
+static
+int
+dk4tsp08_i_add_one_byte(
+ dk4_tsp08_t *tsp,
+ unsigned char inbyte
+)
+{
+ size_t nrej = 0;
+ size_t i = 0;
+ int back = DK4_TSP_RES_FATAL;
+ int res;
+ unsigned char uc;
+ $? "+ dk4tsp08_i_add_one_byte %02x", (int)inbyte
+ (tsp->pos).bytes += (dk4_um_t)1UL;
+ switch (tsp->pst) {
+ case 0: { /* BOM detection */
+ $? ". in BOM detection"
+ res = dk4bom_detect_add(&(tsp->bomd), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ case DK4_EDSTM_FINISHED:
+ case DK4_EDSTM_FINISHED_WITH_UNUSED: {
+ $? ". end of BOM detection"
+ /* This result is ok. */
+ back = DK4_TSP_RES_OK;
+ /* Retrieve found encoding */
+ tsp->ief = dk4bom_detect_get_encoding(&(tsp->bomd));
+ /* Check whether we can pass through data unchanged */
+ if (tsp->ief == tsp->pen) {
+ switch (tsp->ief) {
+
+#if VERSION_BEFORE_20150321
+ /* 2015-30-21 We do not hard-code the decision whether or
+ not to enable pass-through for UTF-8
+ encoded bytes, better use a run-time
+ decision.
+ */
+ case DK4_ENCODING_ASCII:
+ case DK4_ENCODING_ANSI:
+#if 0
+ /* 2014-12-01
+ We must make sure to process the complete UTF-8
+ representation of a glyph completely.
+ */
+ case DK4_ENCODING_UTF8:
+#endif
+ {
+ tsp->pth = 1; $? ". pass through"
+ } break;
+#endif
+
+ case DK4_ENCODING_ASCII :
+ case DK4_ENCODING_ANSI : {
+ tsp->pth = 1;
+ } break;
+ case DK4_ENCODING_UTF8 : {
+ if (0 != tsp->upt) { tsp->pth = 1; }
+ } break;
+ }
+ }
+ /* If necessary, initialize decoder */
+ dk4tsp08_initialize_decoder(tsp);
+ /* Switch to normal processing */
+ tsp->pst = 1;
+ /* Process bytes stored in BOM detector */
+ if (DK4_EDSTM_FINISHED_WITH_UNUSED == res) {
+ nrej = dk4bom_detect_num_unused_bytes(&(tsp->bomd));
+ if (0 < nrej) {
+ $? ". processing bytes rejected by BOM detector"
+ for (i = 0; ((i < nrej) && (DK4_TSP_RES_FATAL != back)); i++) {
+ uc = dk4bom_detect_unused_byte(&(tsp->bomd), i);
+ $? ". process byte %u/%u = %02x", (unsigned)i,(unsigned)nrej,(int)uc
+ switch (dk4tsp08_process_byte(tsp, uc)) {
+ case DK4_TSP_RES_FATAL: { $? "! fatal"
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) { $? "! error"
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ }
+ }
+ }
+ } break;
+ case DK4_EDSTM_ERROR: { $? "! error in BOM detection"
+ } break;
+ }
+ } break;
+ case 1: { /* Normal processing */
+ $? ". in normal processing"
+ back = dk4tsp08_process_byte(tsp, inbyte);
+ } break;
+ /*
+ Processing stage 2 indicates there was a serious error
+ before, we must skip further processing.
+ This situation is covered by the initialization value
+ DK4_TSP_RES_FATAL, so we do not need a case branch here.
+ */
+ }
+ $? "- dk4tsp08_i_add_one_byte %d", back
+ return back;
+}
+
+
+
+int
+dk4tsp08_setup_char(
+ dk4_tsp08_t *tsp,
+ void *obj,
+ dk4_c8_handler_t *fct,
+ int pre,
+ int eie,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+ $? "+ dk4tsp08_setup_char"
+ if (NULL != tsp) { $? ". tsp ok"
+ dk4tsp08_init(tsp, eie);
+ if (NULL != fct) { $? ". args ok"
+ switch (pre) {
+ case DK4_ENCODING_ASCII:
+ case DK4_ENCODING_ANSI:
+ case DK4_ENCODING_UTF8:
+ {
+ tsp->obj = obj;
+ (tsp->fct).ch = fct;
+ tsp->pen = pre;
+ tsp->iee = eie; $? ". expected encoding = %d", eie
+ tsp->ief = eie;
+ back = 1;
+ } break;
+ default: { $? "! invalid char encoding"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ tsp->pst = 2;
+ } break;
+ }
+ } else { $? "! invalid arguments"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ tsp->pst = 2;
+ }
+ } else { $? "! invalid arguments"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4tsp08_setup_char %d", back
+ return back;
+}
+
+
+int
+dk4tsp08_setup_line(
+ dk4_tsp08_t *tsp,
+ void *obj,
+ dk4_c8_line_handler_t *fct,
+ char *inbuf,
+ size_t szin,
+ int pre,
+ int eie,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+ $? "+ dk4tsp08_setup_line"
+ if (NULL != tsp) { $? ". tsp ok"
+ dk4tsp08_init(tsp, eie);
+ if ((NULL != fct) && (NULL != inbuf) && (0 < szin)) {
+ $? ". args ok"
+ switch (pre) {
+ case DK4_ENCODING_ASCII:
+ case DK4_ENCODING_ANSI:
+ case DK4_ENCODING_UTF8:
+ {
+ tsp->obj = obj;
+ (tsp->fct).lh = fct;
+ tsp->inbuf = inbuf;
+ tsp->in_sz = szin;
+ tsp->in_us = 0;
+ tsp->pen = pre;
+ tsp->iee = eie;
+ tsp->ief = eie;
+ back = 1;
+ } break;
+ default: { $? "! invalid char encoding"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ tsp->pst = 2;
+ } break;
+ }
+ } else { $? "! invalid arguments"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ tsp->pst = 2;
+ }
+ } else { $? "! invalid arguments"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4tsp08_setup_line %d", back
+ return back;
+}
+
+
+
+int
+dk4tsp08_add_one_byte(
+ dk4_tsp08_t *tsp,
+ unsigned char inbyte
+)
+{
+ int back = DK4_TSP_RES_FATAL;
+ $? "+ dk4tsp08_add_one_byte"
+ if (NULL != tsp) {
+ if (2 > tsp->pst) {
+ back = dk4tsp08_i_add_one_byte(tsp, inbyte);
+ }
+ } $? "- dk4tsp08_add_one_byte %d", back
+ return back;
+}
+
+
+
+int
+dk4tsp08_add_bytes(
+ dk4_tsp08_t *tsp,
+ const unsigned char *buffer,
+ size_t sz
+)
+{
+ int back = DK4_TSP_RES_FATAL;
+ int res;
+ $? "+ dk4tsp08_add_bytes"
+ if ((NULL != tsp) && (NULL != buffer) && (0 < sz)) {
+ if (2 > tsp->pst) {
+ back = DK4_TSP_RES_OK;
+ while((sz--) && (2 > tsp->pst)) {
+ res = dk4tsp08_i_add_one_byte(tsp, *(buffer++));
+ switch (res) {
+ case DK4_TSP_RES_FATAL: { $? "! fatal"
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) { $? "! error"
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ }
+ }
+ } $? "- dk4tsp08_add_bytes %d", back
+ return back;
+}
+
+
+
+int
+dk4tsp08_finish(dk4_tsp08_t *tsp)
+{
+ size_t nrej = 0;
+ size_t i = 0;
+ int back = DK4_TSP_RES_FATAL;
+ int res;
+ unsigned char uc;
+ $? "+ dk4tsp08_finish"
+ if (NULL != tsp) {
+ /* Retrieve rejected bytes from BOM detector */
+ back = DK4_TSP_RES_OK;
+ if (0 == tsp->pst) { $? ". still in BOM detection"
+ tsp->pst = 1;
+ nrej = dk4bom_detect_num_unused_bytes(&(tsp->bomd));
+ if (0 < nrej) {
+ dk4tsp08_initialize_decoder(tsp);
+ for (i = 0; ((i < nrej) && (2 > tsp->pst)); i++) {
+ uc = dk4bom_detect_unused_byte(&(tsp->bomd), i);
+ $? ". process byte %u/%u = %02x", (unsigned)i,(unsigned)nrej,(int)uc
+ switch (dk4tsp08_process_byte(tsp, uc)) {
+ case DK4_TSP_RES_FATAL: { $? "! fatal"
+ back = DK4_TSP_RES_FATAL;
+ tsp->pst = 2;
+ } break;
+ case DK4_TSP_RES_ERROR: { $? "! error"
+ if (DK4_TSP_RES_OK == back) { back = DK4_TSP_RES_ERROR; }
+ } break;
+ }
+ }
+ }
+ } else { $? ". BOM detection was finished"
+ }
+ /* Process final line */
+ if ((NULL != tsp->inbuf) && (0 < tsp->in_sz) && (NULL != (tsp->fct).lh)) {
+ if (0 < tsp->in_us) {
+ $? ". processing final line"
+ if (2 > tsp->pst) {
+ if (tsp->in_us < tsp->in_sz) { $? ". can add final 0x00"
+ (tsp->inbuf)[tsp->in_us] = '\0'; $? ". run processing function"
+ res =
+ (*((tsp->fct).lh))(
+ tsp->obj,tsp->inbuf,(tsp->pos).lineno,&(tsp->er_pr)
+ );
+ switch (res) {
+ case DK4_TSP_RES_FATAL: { $? "! fatal"
+ back = DK4_TSP_RES_FATAL;
+ tsp->pst = 2;
+ } break;
+ case DK4_TSP_RES_ERROR: { $? "! error"
+ if (DK4_TSP_RES_OK == back) { back = DK4_TSP_RES_ERROR; }
+ } break;
+ }
+ } else { $? "! line too long to add final 0x00"
+ back = DK4_TSP_RES_FATAL;
+ tsp->pst = 2;
+ /* ERROR: Line too long! */
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_BUFFER_TOO_SMALL,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ } else { $? "! previous errors"
+ }
+ }
+ }
+ }
+ $? "- dk4tsp08_finish %d", back
+ return back;
+}
+
+
+
+void
+dk4tsp08_get_errors(dk4_er_t *er_en, dk4_er_t *er_pr, dk4_tsp08_t *tsp)
+{
+ if (NULL != tsp) {
+ if (NULL != er_en) {
+ DK4_MEMCPY(er_en, &(tsp->er_en), sizeof(dk4_er_t));
+ }
+ if (NULL != er_pr) {
+ DK4_MEMCPY(er_pr, &(tsp->er_pr), sizeof(dk4_er_t));
+ }
+ }
+}
+
+
+
+void
+dk4tsp08_enable_utf8_pass_through(dk4_tsp08_t *tsp, int fl)
+{
+ if (NULL != tsp) {
+ tsp->upt = ((0 != fl) ? 1 : 0);
+ }
+}
+
+
diff --git a/support/dktools/dk4tsp08.h b/support/dktools/dk4tsp08.h
new file mode 100644
index 0000000000..88182bad77
--- /dev/null
+++ b/support/dktools/dk4tsp08.h
@@ -0,0 +1,286 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4tsp08.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4TSP08_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4TSP08_H_INCLUDED 1
+
+
+#line 10 "dk4tsp08.ctr"
+
+/** @file dk4tsp08.h Text stream processing for 8 bit characters.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4BOM_H_INCLUDED
+#include "dk4bom.h"
+#endif
+
+#ifndef DK4TSP_H_INCLUDED
+#include "dk4tsp.h"
+#endif
+
+#ifndef DK4UTF8_H_INCLUDED
+#include "dk4utf8.h"
+#endif
+
+#ifndef DK4UTF16_H_INCLUDED
+#include "dk4utf16.h"
+#endif
+
+#ifndef DK4C32_H_INCLUDED
+#include "dk4c32.h"
+#endif
+
+/** Handler function for single characters.
+ @param obj Object to modify while processing the character.
+ @param c Character to process.
+ @param pos Current position in file or data stream.
+ @param erp Error report, may be NULL.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+typedef int dk4_c8_handler_t(
+ void *obj,
+ char c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+);
+
+/** Handler function for text lines.
+ @param obj Object to modify while processing the character.
+ @param line Text line to process.
+ @param lineno Current line number.
+ @param erp Error report, may be NULL.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+typedef int dk4_c8_line_handler_t(
+ void *obj,
+ char *line,
+ dk4_um_t lineno,
+ dk4_er_t *erp
+);
+
+/** Structure for 8 bit character processing.
+*/
+typedef struct {
+ union {
+ dk4_utf8_decoder_t u08; /**< UTF-8 decoder. */
+ dk4_utf16_byte_decoder_t u16; /**< UTF-16 decoder. */
+ dk4_c32_byte_decoder_t c32; /**< 32 bit char decoder. */
+ } dec; /**< Input decoder. */
+ dk4_bom_detector_t bomd; /**< BOM detector. */
+ dk4_text_stream_position_t pos; /**< Current position. */
+ dk4_er_t er_en; /**< Errors in input decoding. */
+ dk4_er_t er_pr; /**< Errors in processing. */
+ union {
+ dk4_c8_line_handler_t *lh; /**< Handler function for lines. */
+ dk4_c8_handler_t *ch; /**< Handler function for char. */
+ } fct; /**< Handler function. */
+ char *inbuf; /**< Buffer for input line. */
+ void *obj; /**< Object to modify in processing. */
+ size_t in_sz; /**< Size of input line buffer. */
+ size_t in_us; /**< Used bytes in input line buffer. */
+ int upt; /**< Flag: Enable UTF-8 pass through. */
+ int ief; /**< Input encoding found. */
+ int iee; /**< Input encoding expected. */
+ int pen; /**< Encoding for processing. */
+ int pst; /**< Processing stage. */
+ int pth; /**< Flag: Pass through. */
+} dk4_tsp08_t;
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Set up processor for byte by byte processing.
+ @param tsp Processor to set up.
+ @param obj Object to modify when processing input, may be NULL.
+ @param fct Handler function to call for each character.
+ @param pre Encoding required for processing.
+ @param eie Expected input encoding.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if tsp or fct is NULL or pre is not an encoding for 8-bit characters.
+*/
+int
+dk4tsp08_setup_char(
+ dk4_tsp08_t *tsp,
+ void *obj,
+ dk4_c8_handler_t *fct,
+ int pre,
+ int eie,
+ dk4_er_t *erp
+);
+
+/** Set up processor for line processing.
+ @param tsp Processor to set up.
+ @param obj Object to modify when processing input, may be NULL.
+ @param fct Handler function to invoke for each line.
+ @param inbuf Input line buffer.
+ @param szin Size of input line buffer.
+ @param pre Encoding required for processing.
+ @param eie Expected input encoding.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if tsp, fct or inbuf is NULL, szin is 0 or pre is not a
+ valid encoding for 8-bit characters.
+*/
+int
+dk4tsp08_setup_line(
+ dk4_tsp08_t *tsp,
+ void *obj,
+ dk4_c8_line_handler_t *fct,
+ char *inbuf,
+ size_t szin,
+ int pre,
+ int eie,
+ dk4_er_t *erp
+);
+
+/** Enable or disable pass-through of UTF-8 encoded data.
+ Use this function after dk4tsp08_setup_line() or
+ dk4tsp08_setup_char() but before adding the first byte.
+ @param tsp Text stream processor to configure.
+ @param fl Flag: Enabled.
+*/
+void
+dk4tsp08_enable_utf8_pass_through(dk4_tsp08_t *tsp, int fl);
+
+/** Add one single byte.
+ @param tsp Text stream processor.
+ @param inbyte Byte to process.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+int
+dk4tsp08_add_one_byte(
+ dk4_tsp08_t *tsp,
+ unsigned char inbyte
+);
+
+/** Add multiple bytes.
+ @param tsp Text stream processor.
+ @param buffer Buffer start address.
+ @param sz Number of bytes in buffer.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+int
+dk4tsp08_add_bytes(
+ dk4_tsp08_t *tsp,
+ const unsigned char *buffer,
+ size_t sz
+);
+
+/** Finish processing.
+ @param tsp Text stream processor.
+ @return DK4_TSP_RES_OK if processing was finished
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error,
+ DK4_TSP_RES_FATAL if there was a fatal error.
+*/
+int
+dk4tsp08_finish(dk4_tsp08_t *tsp);
+
+/** Retrieve error reports for encoding/decoding and processing.
+ @param er_en Destination error report buffer for encoding/decoding.
+ @param er_pr Destination error report buffer for processing.
+ @param tsp Text stream processor to retrieve errors from.
+
+ Error codes er_en:
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the input buffer provided in dk4tsp08_setup_line() is too
+ small,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if no character processing function was provided,
+ - DK4_E_DECODING_FAILED<br>
+ if there were decoding errors,
+ - DK4_E_ENCODING_FAILED<br>
+ if there were encoding errors.
+
+ Error codes er_pr:
+ - The error codes returned in er_pr depend on the processing
+ function.
+*/
+void
+dk4tsp08_get_errors(dk4_er_t *er_en, dk4_er_t *er_pr, dk4_tsp08_t *tsp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4tsp16.c b/support/dktools/dk4tsp16.c
new file mode 100644
index 0000000000..e90fc5e8c5
--- /dev/null
+++ b/support/dktools/dk4tsp16.c
@@ -0,0 +1,750 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4tsp16.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4tsp16.c The dk4tsp16 module.
+*/
+
+
+#line 214 "dk4tsp16.ctr"
+
+#include "dk4tsp16.h"
+#include "dk4enc.h"
+#include "dk4mem.h"
+#include "dk4ansi.h"
+#include "dk4utf8.h"
+#include "dk4utf16.h"
+#include "dk4c32.h"
+
+
+
+
+
+#line 226 "dk4tsp16.ctr"
+
+
+
+/** Initialize text stream processing structure.
+ @param tsp Text stream processor.
+ @param eie Expected input encoding.
+*/
+static
+void
+dk4tsp16_init(dk4_tsp16_t *tsp, int eie)
+{
+ DK4_MEMRES(tsp, sizeof(dk4_tsp16_t));
+ dk4bom_detect_init(&(tsp->bomd), eie);
+ dk4error_init(&(tsp->er_en));
+ dk4error_init(&(tsp->er_pr));
+ tsp->inbuf = NULL;
+ tsp->obj = NULL;
+ tsp->in_sz = 0;
+ tsp->in_us = 0;
+ tsp->ief = eie;
+ tsp->iee = eie;
+ tsp->pst = 0;
+ (tsp->pos).bytes = (dk4_um_t)0UL;
+ (tsp->pos).chars = (dk4_um_t)1UL;
+ (tsp->pos).lineno = (dk4_um_t)1UL;
+ (tsp->pos).charil = (dk4_um_t)1UL;
+}
+
+
+
+/** Initialize decoder for found input encoding.
+ @param tsp Text stream processor.
+*/
+static
+void
+dk4tsp16_initialize_decoder(dk4_tsp16_t *tsp)
+{
+ switch (tsp->ief) {
+ case DK4_FILE_ENCODING_UTF8: {
+ dk4utf8_init(&((tsp->dec).u08));
+ } break;
+ case DK4_FILE_ENCODING_UTF16_LE: {
+ dk4utf16_byte_init(&((tsp->dec).u16), 0);
+ } break;
+ case DK4_FILE_ENCODING_UTF16_BE: {
+ dk4utf16_byte_init(&((tsp->dec).u16), 1);
+ } break;
+ case DK4_FILE_ENCODING_32_LE: {
+ dk4c32_decoder_init(&((tsp->dec).c32), 0);
+ } break;
+ case DK4_FILE_ENCODING_32_BE: {
+ dk4c32_decoder_init(&((tsp->dec).c32), 1);
+ } break;
+ }
+}
+
+
+
+#if 0
+static
+int
+dk4tsp16_process_character(
+ dk4_tsp16_t *tsp,
+ dk4_c16_t chr
+)
+{
+ int back = DK4_TSP_RES_FATAL;
+
+
+#line 294 "dk4tsp16.ctr"
+ /* Increase position */
+ (tsp->pos).chars += (dk4_um_t)1UL;
+ (tsp->pos).charil += (dk4_um_t)1UL;
+ /* Check for line buffering or direct processing */
+ if ((NULL != tsp->inbuf) && (0 < tsp->in_sz) && (NULL != (tsp->fct).lh)) {
+
+
+#line 300 "dk4tsp16.ctr"
+ if (tsp->in_us < tsp->in_sz) {
+ (tsp->inbuf)[tsp->in_us] = chr;
+ tsp->in_us += 1;
+ back = DK4_TSP_RES_OK;
+ if ((dk4_c16_t)'\n' == chr) {
+ back = DK4_TSP_RES_FATAL;
+ if (tsp->in_us < tsp->in_sz) {
+ (tsp->inbuf)[tsp->in_us] = (dk4_c16_t)'\0';
+ back = (*((tsp->fct).lh))(
+ tsp->obj,tsp->inbuf,(tsp->pos).lineno,&(tsp->er_pr)
+ );
+ } else {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_BUFFER_TOO_SMALL,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ tsp->in_us = 0;
+ }
+ } else {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_BUFFER_TOO_SMALL,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ } else {
+
+
+#line 329 "dk4tsp16.ctr"
+ if (NULL != (tsp->fct).ch) {
+ back = (*((tsp->fct).ch))(tsp->obj, chr, &(tsp->pos), &(tsp->er_pr));
+ }
+ }
+ /* Increase line number for newline characters */
+ if ((dk4_c16_t)('\n') == chr) {
+ (tsp->pos).lineno += (dk4_um_t)1UL;
+ (tsp->pos).charil = (dk4_um_t)1UL;
+ }
+
+#line 338 "dk4tsp16.ctr"
+ return back;
+}
+#endif
+
+
+
+/** Process a group of 16 bit characters, the group represents
+ one 32 bit character.
+ @param tsp Text stream processor.
+ @param buf Buffer of 16 bit characters.
+ @param sz Number of 16 bit characters.
+ @return DK4_TSP_RES_OK if the characters were processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so
+ we should abort processing.
+*/
+static
+int
+dk4tsp16_process_group(dk4_tsp16_t *tsp, dk4_c16_t *buf, size_t sz)
+{
+ size_t i = 0;
+ int back = DK4_TSP_RES_FATAL;
+ int res = DK4_TSP_RES_FATAL;
+
+
+#line 364 "dk4tsp16.ctr"
+ /* Increase position */
+ (tsp->pos).chars += (dk4_um_t)1UL;
+ (tsp->pos).charil += (dk4_um_t)1UL;
+ /* Check for line buffering or direct processing */
+ if ((NULL != tsp->inbuf) && (0 < tsp->in_sz) && (NULL != (tsp->fct).lh)) {
+
+
+#line 370 "dk4tsp16.ctr"
+ if (sz < tsp->in_sz) {
+ if (tsp->in_us < (tsp->in_sz - sz)) {
+ /* Append group to line and increase used size */
+ DK4_MEMCPY(&((tsp->inbuf)[tsp->in_us]),buf,(sizeof(dk4_c16_t)*sz));
+ tsp->in_us += sz;
+ back = DK4_TSP_RES_OK;
+ /* On newline, process the line buffer */
+ if ((1 == sz) && ((dk4_c16_t)'\n' == buf[0])) {
+ back = DK4_TSP_RES_FATAL;
+ if (tsp->in_us < tsp->in_sz) {
+ (tsp->inbuf)[tsp->in_us] = (dk4_c16_t)'\0';
+ back = (*((tsp->fct).lh))(
+ tsp->obj,tsp->inbuf,(tsp->pos).lineno,&(tsp->er_pr)
+ );
+ } else {
+ /* ERROR: Buffer too small */
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_BUFFER_TOO_SMALL,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ tsp->in_us = 0;
+ }
+ } else {
+ /* ERROR: Buffer too small */
+ back = DK4_TSP_RES_FATAL;
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_BUFFER_TOO_SMALL,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ } else {
+ /* ERROR: Buffer too small */
+ back = DK4_TSP_RES_FATAL;
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_BUFFER_TOO_SMALL,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ } else {
+
+
+#line 414 "dk4tsp16.ctr"
+ if (NULL != (tsp->fct).ch) {
+ back = DK4_TSP_RES_OK;
+ for (i = 0; i < sz; i++) {
+ res = (*((tsp->fct).ch))(tsp->obj, buf[i], &(tsp->pos), &(tsp->er_pr));
+ switch (res) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) { back = DK4_TSP_RES_ERROR; }
+ } break;
+ }
+ }
+ } else {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_INVALID_ARGUMENTS,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ }
+ /* If we have a newline, increase line number and reset char in line */
+ if (1 == sz) {
+ if ((dk4_c16_t)('\n') == buf[0]) {
+ (tsp->pos).lineno += (dk4_um_t)1UL;
+ (tsp->pos).charil = (dk4_um_t)1UL;
+ }
+ }
+
+
+#line 443 "dk4tsp16.ctr"
+ return back;
+}
+
+
+
+/** Normal processing for one byte.
+ Retrieve a 32 bit character first, either by decoding directly
+ or by adding to a decoder. In the next step encode the 32 bit
+ character in one or two 16 bit characters and process these.
+ @param tsp Text stream processor.
+ @param inbyte Byte to process.
+ @return Operation result, one from DK4_TSP_RES_OK,
+ DK4_TSP_RES_ERROR or DK4_TSP_RES_FATAL.
+*/
+static
+int
+dk4tsp16_process_byte(dk4_tsp16_t *tsp, unsigned char inbyte)
+{
+ dk4_c16_t buf[8];
+ dk4_c32_t c32;
+ size_t sz;
+ int back = DK4_TSP_RES_FATAL;
+ int cuc32 = 0;
+ int res = 0;
+ /* Add byte to decoder, attempt to retrieve a 32 bit character */
+ switch (tsp->ief) {
+ case DK4_FILE_ENCODING_ASCII: {
+ c32 = (dk4_c32_t)inbyte;
+ cuc32 = 1;
+ } break;
+ case DK4_FILE_ENCODING_ANSI: {
+ if (0 != dk4ansi_decode(&c32, inbyte)) {
+ cuc32 = 1;
+ } else {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ } break;
+ case DK4_FILE_ENCODING_UTF8: {
+ res = dk4utf8_add(&((tsp->dec).u08), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ERROR: {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ } break;
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf8_get(&((tsp->dec).u08));
+ cuc32 = 1;
+ dk4utf8_init(&((tsp->dec).u08));
+ } break;
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ }
+ } break;
+ case DK4_FILE_ENCODING_UTF16_LE: {
+ res = dk4utf16_byte_add(&((tsp->dec).u16), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ERROR: {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ } break;
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf16_byte_get(&((tsp->dec).u16));
+ cuc32 = 1;
+ dk4utf16_byte_init(&((tsp->dec).u16), 0);
+ } break;
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ }
+ } break;
+ case DK4_FILE_ENCODING_UTF16_BE: {
+ res = dk4utf16_byte_add(&((tsp->dec).u16), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ERROR: {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ } break;
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf16_byte_get(&((tsp->dec).u16));
+ cuc32 = 1;
+ dk4utf16_byte_init(&((tsp->dec).u16), 1);
+ } break;
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ }
+ } break;
+ case DK4_FILE_ENCODING_32_LE: {
+ res = dk4c32_decoder_add(&((tsp->dec).c32), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ERROR: {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ } break;
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4c32_decoder_get(&((tsp->dec).c32));
+ cuc32 = 1;
+ dk4c32_decoder_init(&((tsp->dec).c32), 0);
+ } break;
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ }
+ } break;
+ case DK4_FILE_ENCODING_32_BE: {
+ res = dk4c32_decoder_add(&((tsp->dec).c32), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ERROR: {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ } break;
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4c32_decoder_get(&((tsp->dec).c32));
+ cuc32 = 1;
+ dk4c32_decoder_init(&((tsp->dec).c32), 1);
+ } break;
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ }
+ } break;
+ }
+ /* Process 32 bit character if we have a 32 bit char to process */
+ if (0 != cuc32) {
+ sz = DK4_SIZEOF(buf,dk4_c16_t);
+ if (0 != dk4utf16_encode(buf, &sz, c32, NULL)) {
+#if 0
+ back = DK4_TSP_RES_OK;
+ for (i = 0; ((i < sz) && (DK4_TSP_RES_FATAL != back)); i++) {
+ switch (dk4tsp16_process_character(tsp, buf[i])) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) { back = DK4_TSP_RES_ERROR; }
+ } break;
+ }
+ }
+#else
+ back = dk4tsp16_process_group(tsp, buf, sz);
+#endif
+ } else {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_ENCODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ }
+ if (DK4_TSP_RES_FATAL == back) {
+ tsp->pst = 2;
+ }
+ return back;
+}
+
+
+
+/** Add one byte to internal data structures
+ (BOM detection and/or normal processing).
+ @param tsp Text stream processor.
+ @param inbyte Byte to add.
+ @return Operation result, one from DK4_TSP_RES_OK,
+ DK4_TSP_RES_ERROR or DK4_TSP_RES_FATAL.
+*/
+static
+int
+dk4tsp16_i_add_one_byte(
+ dk4_tsp16_t *tsp,
+ unsigned char inbyte
+)
+{
+ size_t nrej;
+ size_t i;
+ int back = DK4_TSP_RES_FATAL;
+ int res;
+ unsigned char uc;
+
+
+#line 640 "dk4tsp16.ctr"
+ (tsp->pos).bytes += (dk4_um_t)1UL;
+ switch (tsp->pst) {
+ case 0: {
+
+#line 643 "dk4tsp16.ctr"
+ res = dk4bom_detect_add(&(tsp->bomd), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ case DK4_EDSTM_FINISHED: case DK4_EDSTM_FINISHED_WITH_UNUSED: {
+ /* Result is acceptable */
+ back = DK4_TSP_RES_OK;
+ /* Retrieve found encoding */
+ tsp->ief = dk4bom_detect_get_encoding(&(tsp->bomd));
+ /* If necessary, initialize decoder */
+ dk4tsp16_initialize_decoder(tsp);
+ /* Switch to normal processing */
+ tsp->pst = 1;
+ /* Process bytes stored in BOM detector */
+ if (DK4_EDSTM_FINISHED_WITH_UNUSED == res) {
+ nrej = dk4bom_detect_num_unused_bytes(&(tsp->bomd));
+ if (0 < nrej) {
+ for (i = 0; ((i < nrej) && (DK4_TSP_RES_FATAL != back)); i++) {
+ uc = dk4bom_detect_unused_byte(&(tsp->bomd), i);
+ switch (dk4tsp16_process_byte(tsp, uc)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ }
+ }
+ }
+ } break;
+ }
+ } break;
+ case 1: {
+
+#line 680 "dk4tsp16.ctr"
+ back = dk4tsp16_process_byte(tsp, inbyte);
+ } break;
+ /*
+ Processing stage 2 indicates there was a serious error
+ before, we must skip further processing.
+ This situation is covered by the initialization value
+ DK4_TSP_RES_FATAL, so we do not need a case branch here.
+ */
+ }
+
+
+#line 690 "dk4tsp16.ctr"
+ return back;
+}
+
+
+
+int
+dk4tsp16_setup_char(
+ dk4_tsp16_t *tsp,
+ void *obj,
+ dk4_c16_handler_t *fct,
+ int eie,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+ if (NULL != tsp) {
+ dk4tsp16_init(tsp, eie);
+ if (NULL != fct) {
+ tsp->obj = obj;
+ (tsp->fct).ch = fct;
+ tsp->iee = eie;
+ tsp->ief = eie;
+ tsp->pst = 0;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ tsp->pst = 2;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4tsp16_setup_line(
+ dk4_tsp16_t *tsp,
+ void *obj,
+ dk4_c16_line_handler_t *fct,
+ dk4_c16_t *inbuf,
+ size_t szin,
+ int eie,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+ if (NULL != tsp) {
+ dk4tsp16_init(tsp, eie);
+ if ((NULL != fct) && (NULL != inbuf) && (0 < szin)) {
+ tsp->obj = obj;
+ (tsp->fct).lh = fct;
+ tsp->inbuf = inbuf;
+ tsp->in_sz = szin;
+ tsp->in_us = 0;
+ tsp->iee = eie;
+ tsp->ief = eie;
+ tsp->pst = 0;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ tsp->pst = 2;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4tsp16_add_one_byte(
+ dk4_tsp16_t *tsp,
+ unsigned char inbyte
+)
+{
+ int back = DK4_TSP_RES_FATAL;
+ if (NULL != tsp) {
+ if (2 > tsp->pst) {
+ back = dk4tsp16_i_add_one_byte(tsp, inbyte);
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4tsp16_add_bytes(
+ dk4_tsp16_t *tsp,
+ const unsigned char *buffer,
+ size_t sz
+)
+{
+ int back = DK4_TSP_RES_FATAL; /* Function result */
+ int res; /* Processing result */
+ if ((NULL != tsp) && (NULL != buffer) && (0 < sz)) {
+ if (2 > tsp->pst) {
+ back = DK4_TSP_RES_OK;
+ while ((sz--) && (2 > tsp->pst)) {
+ res = dk4tsp16_i_add_one_byte(tsp, *(buffer++));
+ switch (res) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4tsp16_finish(dk4_tsp16_t *tsp)
+{
+ size_t nrej = 0; /* Number of unused bytes */
+ size_t i = 0; /* Current unused byte index */
+ int back = DK4_TSP_RES_FATAL; /* Function result */
+ int res; /* Operation result */
+ unsigned char uc; /* Current unused byte */
+ if (NULL != tsp) {
+ /* Flush all unprocessed output
+ 1. If there are unprocessed bytes in the BOM detector as BOM
+ detection was not completed, process these bytes.
+ 2. If there are characters in the line buffer,
+ finalize the line buffer text and process it.
+ */
+ back = DK4_TSP_RES_OK;
+ /* Retrieve an process bytes stored in BOM detector */
+ if (0 == tsp->pst) {
+ tsp->pst = 1;
+ nrej = dk4bom_detect_num_unused_bytes(&(tsp->bomd));
+ if (0 < nrej) {
+ dk4tsp16_initialize_decoder(tsp);
+ for (i = 0; ((i < nrej) && (2 > tsp->pst)); i++) {
+ uc = dk4bom_detect_unused_byte(&(tsp->bomd), i);
+ switch (dk4tsp16_process_byte(tsp, uc)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ tsp->pst = 2;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) { back = DK4_TSP_RES_ERROR; }
+ } break;
+ }
+ }
+ }
+ }
+ /* Process final line */
+ if ((NULL != tsp->inbuf) && (0 < tsp->in_sz) && (NULL != (tsp->fct).lh)) {
+ if (0 < tsp->in_us) {
+ if (2 > tsp->pst) {
+ if (tsp->in_us < tsp->in_sz) {
+ (tsp->inbuf)[tsp->in_us] = (dk4_c16_t)'\0';
+ res =
+ (*((tsp->fct).lh))(
+ tsp->obj,tsp->inbuf,(tsp->pos).lineno,&(tsp->er_pr)
+ );
+ switch (res) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ tsp->pst = 2;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) { back = DK4_TSP_RES_ERROR; }
+ } break;
+ }
+ } else {
+ back = DK4_TSP_RES_FATAL;
+ tsp->pst = 2;
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_BUFFER_TOO_SMALL,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void
+dk4tsp16_get_errors(dk4_er_t *er_en, dk4_er_t *er_pr, dk4_tsp16_t *tsp)
+{
+ if (NULL != tsp) {
+ if (NULL != er_en) {
+ DK4_MEMCPY(er_en, &(tsp->er_en), sizeof(dk4_er_t));
+ }
+ if (NULL != er_pr) {
+ DK4_MEMCPY(er_pr, &(tsp->er_pr), sizeof(dk4_er_t));
+ }
+ }
+}
+
+
diff --git a/support/dktools/dk4tsp16.ctr b/support/dktools/dk4tsp16.ctr
new file mode 100644
index 0000000000..3a0c9e88cf
--- /dev/null
+++ b/support/dktools/dk4tsp16.ctr
@@ -0,0 +1,897 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ Text stream processing for 16 bit characters.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4BOM_H_INCLUDED
+#include "dk4bom.h"
+#endif
+
+#ifndef DK4TSP_H_INCLUDED
+#include "dk4tsp.h"
+#endif
+
+#ifndef DK4UTF8_H_INCLUDED
+#include "dk4utf8.h"
+#endif
+
+#ifndef DK4UTF16_H_INCLUDED
+#include "dk4utf16.h"
+#endif
+
+#ifndef DK4C32_H_INCLUDED
+#include "dk4c32.h"
+#endif
+
+/** Handler function for single characters.
+ @param obj Object to modify while processing the character.
+ @param c Character to process.
+ @param pos Current position in file or data stream.
+ @param erp Error report, may be NULL.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+typedef int dk4_c16_handler_t(
+ void *obj,
+ dk4_c16_t c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+);
+
+/** Handler function for text lines.
+ @param obj Object to modify while processing the character.
+ @param line Text line to process.
+ @param lineno Current line number.
+ @param erp Error report, may be NULL.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fata error so we
+ should abort processing.
+*/
+typedef int dk4_c16_line_handler_t(
+ void *obj,
+ dk4_c16_t *line,
+ dk4_um_t lineno,
+ dk4_er_t *erp
+);
+
+/** Structure for 16 bit character processing.
+*/
+typedef struct {
+ union {
+ dk4_utf8_decoder_t u08; /**< UTF-8 decoder. */
+ dk4_utf16_byte_decoder_t u16; /**< UTF-16 decoder. */
+ dk4_c32_byte_decoder_t c32; /**< 32 bit char decoder. */
+ } dec; /**< Input decoder. */
+ dk4_bom_detector_t bomd; /**< BOM detector. */
+ dk4_text_stream_position_t pos; /**< Current position. */
+ dk4_er_t er_en; /**< Errors in input decoding. */
+ dk4_er_t er_pr; /**< Errors in processing. */
+ union {
+ dk4_c16_line_handler_t *lh; /**< Handler function for lines. */
+ dk4_c16_handler_t *ch; /**< Handler function for char. */
+ } fct; /**< Handler function. */
+ dk4_c16_t *inbuf; /**< Buffer for input line. */
+ void *obj; /**< Object to modify in processing. */
+ size_t in_sz; /**< Size of input line buffer. */
+ size_t in_us; /**< Used bytes in input line buffer. */
+ int ief; /**< Input encoding found. */
+ int iee; /**< Input encoding expected. */
+ int pst; /**< Processing stage. */
+} dk4_tsp16_t;
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Set up processor for byte by byte processing.
+ @param tsp Processor to set up.
+ @param obj Object to modify when processing input, may be NULL.
+ @param fct Handler function to call for each character.
+ @param eie Expected input encoding.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4tsp16_setup_char(
+ dk4_tsp16_t *tsp,
+ void *obj,
+ dk4_c16_handler_t *fct,
+ int eie,
+ dk4_er_t *erp
+);
+
+/** Set up processor for line processing.
+ @param tsp Processor to set up.
+ @param obj Object to modify when processing input, may be NULL.
+ @param fct Handler function to invoke for each line.
+ @param inbuf Input line buffer.
+ @param szin Size of input line buffer (number of dk4_c16_t).
+ @param eie Expected input encoding.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4tsp16_setup_line(
+ dk4_tsp16_t *tsp,
+ void *obj,
+ dk4_c16_line_handler_t *fct,
+ dk4_c16_t *inbuf,
+ size_t szin,
+ int eie,
+ dk4_er_t *erp
+);
+
+/** Add one single byte.
+ @param tsp Text stream processor.
+ @param inbyte Byte to process.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fata error so we
+ should abort processing.
+*/
+int
+dk4tsp16_add_one_byte(
+ dk4_tsp16_t *tsp,
+ unsigned char inbyte
+);
+
+/** Add multiple bytes.
+ @param tsp Text stream processor.
+ @param buffer Buffer start address.
+ @param sz Number of bytes in buffer.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fata error so we
+ should abort processing.
+*/
+int
+dk4tsp16_add_bytes(
+ dk4_tsp16_t *tsp,
+ const unsigned char *buffer,
+ size_t sz
+);
+
+/** Finish processing.
+ @param tsp Text stream processor.
+ @return DK4_TSP_RES_OK if processing was finished
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error,
+ DK4_TSP_RES_FATAL if there was a fatal error.
+*/
+int
+dk4tsp16_finish(dk4_tsp16_t *tsp);
+
+/** Retrieve error reports for encoding/decoding and processing.
+ @param er_en Destination error report buffer for encoding/decoding.
+ @param er_pr Destination error report buffer for processing.
+ @param tsp Text stream processor to retrieve errors from.
+*/
+void
+dk4tsp16_get_errors(dk4_er_t *er_en, dk4_er_t *er_pr, dk4_tsp16_t *tsp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4tsp16.h"
+#include "dk4enc.h"
+#include "dk4mem.h"
+#include "dk4ansi.h"
+#include "dk4utf8.h"
+#include "dk4utf16.h"
+#include "dk4c32.h"
+
+
+
+$!trace-include
+
+
+
+/** Initialize text stream processing structure.
+ @param tsp Text stream processor.
+ @param eie Expected input encoding.
+*/
+static
+void
+dk4tsp16_init(dk4_tsp16_t *tsp, int eie)
+{
+ DK4_MEMRES(tsp, sizeof(dk4_tsp16_t));
+ dk4bom_detect_init(&(tsp->bomd), eie);
+ dk4error_init(&(tsp->er_en));
+ dk4error_init(&(tsp->er_pr));
+ tsp->inbuf = NULL;
+ tsp->obj = NULL;
+ tsp->in_sz = 0;
+ tsp->in_us = 0;
+ tsp->ief = eie;
+ tsp->iee = eie;
+ tsp->pst = 0;
+ (tsp->pos).bytes = (dk4_um_t)0UL;
+ (tsp->pos).chars = (dk4_um_t)1UL;
+ (tsp->pos).lineno = (dk4_um_t)1UL;
+ (tsp->pos).charil = (dk4_um_t)1UL;
+}
+
+
+
+/** Initialize decoder for found input encoding.
+ @param tsp Text stream processor.
+*/
+static
+void
+dk4tsp16_initialize_decoder(dk4_tsp16_t *tsp)
+{
+ switch (tsp->ief) {
+ case DK4_FILE_ENCODING_UTF8: {
+ dk4utf8_init(&((tsp->dec).u08));
+ } break;
+ case DK4_FILE_ENCODING_UTF16_LE: {
+ dk4utf16_byte_init(&((tsp->dec).u16), 0);
+ } break;
+ case DK4_FILE_ENCODING_UTF16_BE: {
+ dk4utf16_byte_init(&((tsp->dec).u16), 1);
+ } break;
+ case DK4_FILE_ENCODING_32_LE: {
+ dk4c32_decoder_init(&((tsp->dec).c32), 0);
+ } break;
+ case DK4_FILE_ENCODING_32_BE: {
+ dk4c32_decoder_init(&((tsp->dec).c32), 1);
+ } break;
+ }
+}
+
+
+
+#if 0
+static
+int
+dk4tsp16_process_character(
+ dk4_tsp16_t *tsp,
+ dk4_c16_t chr
+)
+{
+ int back = DK4_TSP_RES_FATAL;
+ $? "+ dk4tsp16_process_character %04x", (unsigned)chr
+ /* Increase position */
+ (tsp->pos).chars += (dk4_um_t)1UL;
+ (tsp->pos).charil += (dk4_um_t)1UL;
+ /* Check for line buffering or direct processing */
+ if ((NULL != tsp->inbuf) && (0 < tsp->in_sz) && (NULL != (tsp->fct).lh)) {
+ $? ". line buffering"
+ if (tsp->in_us < tsp->in_sz) {
+ (tsp->inbuf)[tsp->in_us] = chr;
+ tsp->in_us += 1;
+ back = DK4_TSP_RES_OK;
+ if ((dk4_c16_t)'\n' == chr) {
+ back = DK4_TSP_RES_FATAL;
+ if (tsp->in_us < tsp->in_sz) {
+ (tsp->inbuf)[tsp->in_us] = (dk4_c16_t)'\0';
+ back = (*((tsp->fct).lh))(
+ tsp->obj,tsp->inbuf,(tsp->pos).lineno,&(tsp->er_pr)
+ );
+ } else {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_BUFFER_TOO_SMALL,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ tsp->in_us = 0;
+ }
+ } else {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_BUFFER_TOO_SMALL,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ } else {
+ $? ". direct processing"
+ if (NULL != (tsp->fct).ch) {
+ back = (*((tsp->fct).ch))(tsp->obj, chr, &(tsp->pos), &(tsp->er_pr));
+ }
+ }
+ /* Increase line number for newline characters */
+ if ((dk4_c16_t)('\n') == chr) {
+ (tsp->pos).lineno += (dk4_um_t)1UL;
+ (tsp->pos).charil = (dk4_um_t)1UL;
+ } $? "- dk4tsp16_process_character %d", back
+ return back;
+}
+#endif
+
+
+
+/** Process a group of 16 bit characters, the group represents
+ one 32 bit character.
+ @param tsp Text stream processor.
+ @param buf Buffer of 16 bit characters.
+ @param sz Number of 16 bit characters.
+ @return DK4_TSP_RES_OK if the characters were processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so
+ we should abort processing.
+*/
+static
+int
+dk4tsp16_process_group(dk4_tsp16_t *tsp, dk4_c16_t *buf, size_t sz)
+{
+ size_t i = 0;
+ int back = DK4_TSP_RES_FATAL;
+ int res = DK4_TSP_RES_FATAL;
+ $? "+ dk4tsp16_process_group"
+ /* Increase position */
+ (tsp->pos).chars += (dk4_um_t)1UL;
+ (tsp->pos).charil += (dk4_um_t)1UL;
+ /* Check for line buffering or direct processing */
+ if ((NULL != tsp->inbuf) && (0 < tsp->in_sz) && (NULL != (tsp->fct).lh)) {
+ $? ". line buffering"
+ if (sz < tsp->in_sz) {
+ if (tsp->in_us < (tsp->in_sz - sz)) {
+ /* Append group to line and increase used size */
+ DK4_MEMCPY(&((tsp->inbuf)[tsp->in_us]),buf,(sizeof(dk4_c16_t)*sz));
+ tsp->in_us += sz;
+ back = DK4_TSP_RES_OK;
+ /* On newline, process the line buffer */
+ if ((1 == sz) && ((dk4_c16_t)'\n' == buf[0])) {
+ back = DK4_TSP_RES_FATAL;
+ if (tsp->in_us < tsp->in_sz) {
+ (tsp->inbuf)[tsp->in_us] = (dk4_c16_t)'\0';
+ back = (*((tsp->fct).lh))(
+ tsp->obj,tsp->inbuf,(tsp->pos).lineno,&(tsp->er_pr)
+ );
+ } else {
+ /* ERROR: Buffer too small */
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_BUFFER_TOO_SMALL,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ tsp->in_us = 0;
+ }
+ } else {
+ /* ERROR: Buffer too small */
+ back = DK4_TSP_RES_FATAL;
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_BUFFER_TOO_SMALL,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ } else {
+ /* ERROR: Buffer too small */
+ back = DK4_TSP_RES_FATAL;
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_BUFFER_TOO_SMALL,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ } else {
+ $? ". direct char processing"
+ if (NULL != (tsp->fct).ch) {
+ back = DK4_TSP_RES_OK;
+ for (i = 0; i < sz; i++) {
+ res = (*((tsp->fct).ch))(tsp->obj, buf[i], &(tsp->pos), &(tsp->er_pr));
+ switch (res) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) { back = DK4_TSP_RES_ERROR; }
+ } break;
+ }
+ }
+ } else {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_INVALID_ARGUMENTS,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ }
+ /* If we have a newline, increase line number and reset char in line */
+ if (1 == sz) {
+ if ((dk4_c16_t)('\n') == buf[0]) {
+ (tsp->pos).lineno += (dk4_um_t)1UL;
+ (tsp->pos).charil = (dk4_um_t)1UL;
+ }
+ }
+ $? "- dk4tsp16_process_group %d", back
+ return back;
+}
+
+
+
+/** Normal processing for one byte.
+ Retrieve a 32 bit character first, either by decoding directly
+ or by adding to a decoder. In the next step encode the 32 bit
+ character in one or two 16 bit characters and process these.
+ @param tsp Text stream processor.
+ @param inbyte Byte to process.
+ @return Operation result, one from DK4_TSP_RES_OK,
+ DK4_TSP_RES_ERROR or DK4_TSP_RES_FATAL.
+*/
+static
+int
+dk4tsp16_process_byte(dk4_tsp16_t *tsp, unsigned char inbyte)
+{
+ dk4_c16_t buf[8];
+ dk4_c32_t c32;
+ size_t sz;
+ int back = DK4_TSP_RES_FATAL;
+ int cuc32 = 0;
+ int res = 0;
+ /* Add byte to decoder, attempt to retrieve a 32 bit character */
+ switch (tsp->ief) {
+ case DK4_FILE_ENCODING_ASCII: {
+ c32 = (dk4_c32_t)inbyte;
+ cuc32 = 1;
+ } break;
+ case DK4_FILE_ENCODING_ANSI: {
+ if (0 != dk4ansi_decode(&c32, inbyte)) {
+ cuc32 = 1;
+ } else {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ } break;
+ case DK4_FILE_ENCODING_UTF8: {
+ res = dk4utf8_add(&((tsp->dec).u08), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ERROR: {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ } break;
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf8_get(&((tsp->dec).u08));
+ cuc32 = 1;
+ dk4utf8_init(&((tsp->dec).u08));
+ } break;
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ }
+ } break;
+ case DK4_FILE_ENCODING_UTF16_LE: {
+ res = dk4utf16_byte_add(&((tsp->dec).u16), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ERROR: {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ } break;
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf16_byte_get(&((tsp->dec).u16));
+ cuc32 = 1;
+ dk4utf16_byte_init(&((tsp->dec).u16), 0);
+ } break;
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ }
+ } break;
+ case DK4_FILE_ENCODING_UTF16_BE: {
+ res = dk4utf16_byte_add(&((tsp->dec).u16), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ERROR: {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ } break;
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf16_byte_get(&((tsp->dec).u16));
+ cuc32 = 1;
+ dk4utf16_byte_init(&((tsp->dec).u16), 1);
+ } break;
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ }
+ } break;
+ case DK4_FILE_ENCODING_32_LE: {
+ res = dk4c32_decoder_add(&((tsp->dec).c32), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ERROR: {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ } break;
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4c32_decoder_get(&((tsp->dec).c32));
+ cuc32 = 1;
+ dk4c32_decoder_init(&((tsp->dec).c32), 0);
+ } break;
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ }
+ } break;
+ case DK4_FILE_ENCODING_32_BE: {
+ res = dk4c32_decoder_add(&((tsp->dec).c32), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ERROR: {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ } break;
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4c32_decoder_get(&((tsp->dec).c32));
+ cuc32 = 1;
+ dk4c32_decoder_init(&((tsp->dec).c32), 1);
+ } break;
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ }
+ } break;
+ }
+ /* Process 32 bit character if we have a 32 bit char to process */
+ if (0 != cuc32) {
+ sz = DK4_SIZEOF(buf,dk4_c16_t);
+ if (0 != dk4utf16_encode(buf, &sz, c32, NULL)) {
+#if 0
+ back = DK4_TSP_RES_OK;
+ for (i = 0; ((i < sz) && (DK4_TSP_RES_FATAL != back)); i++) {
+ switch (dk4tsp16_process_character(tsp, buf[i])) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) { back = DK4_TSP_RES_ERROR; }
+ } break;
+ }
+ }
+#else
+ back = dk4tsp16_process_group(tsp, buf, sz);
+#endif
+ } else {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_ENCODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ }
+ if (DK4_TSP_RES_FATAL == back) {
+ tsp->pst = 2;
+ }
+ return back;
+}
+
+
+
+/** Add one byte to internal data structures
+ (BOM detection and/or normal processing).
+ @param tsp Text stream processor.
+ @param inbyte Byte to add.
+ @return Operation result, one from DK4_TSP_RES_OK,
+ DK4_TSP_RES_ERROR or DK4_TSP_RES_FATAL.
+*/
+static
+int
+dk4tsp16_i_add_one_byte(
+ dk4_tsp16_t *tsp,
+ unsigned char inbyte
+)
+{
+ size_t nrej;
+ size_t i;
+ int back = DK4_TSP_RES_FATAL;
+ int res;
+ unsigned char uc;
+ $? "+ dk4tsp16_i_add_one_byte"
+ (tsp->pos).bytes += (dk4_um_t)1UL;
+ switch (tsp->pst) {
+ case 0: { $? ". bom detection"
+ res = dk4bom_detect_add(&(tsp->bomd), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ case DK4_EDSTM_FINISHED: case DK4_EDSTM_FINISHED_WITH_UNUSED: {
+ /* Result is acceptable */
+ back = DK4_TSP_RES_OK;
+ /* Retrieve found encoding */
+ tsp->ief = dk4bom_detect_get_encoding(&(tsp->bomd));
+ /* If necessary, initialize decoder */
+ dk4tsp16_initialize_decoder(tsp);
+ /* Switch to normal processing */
+ tsp->pst = 1;
+ /* Process bytes stored in BOM detector */
+ if (DK4_EDSTM_FINISHED_WITH_UNUSED == res) {
+ nrej = dk4bom_detect_num_unused_bytes(&(tsp->bomd));
+ if (0 < nrej) {
+ for (i = 0; ((i < nrej) && (DK4_TSP_RES_FATAL != back)); i++) {
+ uc = dk4bom_detect_unused_byte(&(tsp->bomd), i);
+ switch (dk4tsp16_process_byte(tsp, uc)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ }
+ }
+ }
+ } break;
+ }
+ } break;
+ case 1: { $? ". normal processing"
+ back = dk4tsp16_process_byte(tsp, inbyte);
+ } break;
+ /*
+ Processing stage 2 indicates there was a serious error
+ before, we must skip further processing.
+ This situation is covered by the initialization value
+ DK4_TSP_RES_FATAL, so we do not need a case branch here.
+ */
+ }
+ $? "- dk4tsp16_i_add_one_byte %d", back
+ return back;
+}
+
+
+
+int
+dk4tsp16_setup_char(
+ dk4_tsp16_t *tsp,
+ void *obj,
+ dk4_c16_handler_t *fct,
+ int eie,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+ if (NULL != tsp) {
+ dk4tsp16_init(tsp, eie);
+ if (NULL != fct) {
+ tsp->obj = obj;
+ (tsp->fct).ch = fct;
+ tsp->iee = eie;
+ tsp->ief = eie;
+ tsp->pst = 0;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ tsp->pst = 2;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4tsp16_setup_line(
+ dk4_tsp16_t *tsp,
+ void *obj,
+ dk4_c16_line_handler_t *fct,
+ dk4_c16_t *inbuf,
+ size_t szin,
+ int eie,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+ if (NULL != tsp) {
+ dk4tsp16_init(tsp, eie);
+ if ((NULL != fct) && (NULL != inbuf) && (0 < szin)) {
+ tsp->obj = obj;
+ (tsp->fct).lh = fct;
+ tsp->inbuf = inbuf;
+ tsp->in_sz = szin;
+ tsp->in_us = 0;
+ tsp->iee = eie;
+ tsp->ief = eie;
+ tsp->pst = 0;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ tsp->pst = 2;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4tsp16_add_one_byte(
+ dk4_tsp16_t *tsp,
+ unsigned char inbyte
+)
+{
+ int back = DK4_TSP_RES_FATAL;
+ if (NULL != tsp) {
+ if (2 > tsp->pst) {
+ back = dk4tsp16_i_add_one_byte(tsp, inbyte);
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4tsp16_add_bytes(
+ dk4_tsp16_t *tsp,
+ const unsigned char *buffer,
+ size_t sz
+)
+{
+ int back = DK4_TSP_RES_FATAL; /* Function result */
+ int res; /* Processing result */
+ if ((NULL != tsp) && (NULL != buffer) && (0 < sz)) {
+ if (2 > tsp->pst) {
+ back = DK4_TSP_RES_OK;
+ while ((sz--) && (2 > tsp->pst)) {
+ res = dk4tsp16_i_add_one_byte(tsp, *(buffer++));
+ switch (res) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4tsp16_finish(dk4_tsp16_t *tsp)
+{
+ size_t nrej = 0; /* Number of unused bytes */
+ size_t i = 0; /* Current unused byte index */
+ int back = DK4_TSP_RES_FATAL; /* Function result */
+ int res; /* Operation result */
+ unsigned char uc; /* Current unused byte */
+ if (NULL != tsp) {
+ /* Flush all unprocessed output
+ 1. If there are unprocessed bytes in the BOM detector as BOM
+ detection was not completed, process these bytes.
+ 2. If there are characters in the line buffer,
+ finalize the line buffer text and process it.
+ */
+ back = DK4_TSP_RES_OK;
+ /* Retrieve an process bytes stored in BOM detector */
+ if (0 == tsp->pst) {
+ tsp->pst = 1;
+ nrej = dk4bom_detect_num_unused_bytes(&(tsp->bomd));
+ if (0 < nrej) {
+ dk4tsp16_initialize_decoder(tsp);
+ for (i = 0; ((i < nrej) && (2 > tsp->pst)); i++) {
+ uc = dk4bom_detect_unused_byte(&(tsp->bomd), i);
+ switch (dk4tsp16_process_byte(tsp, uc)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ tsp->pst = 2;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) { back = DK4_TSP_RES_ERROR; }
+ } break;
+ }
+ }
+ }
+ }
+ /* Process final line */
+ if ((NULL != tsp->inbuf) && (0 < tsp->in_sz) && (NULL != (tsp->fct).lh)) {
+ if (0 < tsp->in_us) {
+ if (2 > tsp->pst) {
+ if (tsp->in_us < tsp->in_sz) {
+ (tsp->inbuf)[tsp->in_us] = (dk4_c16_t)'\0';
+ res =
+ (*((tsp->fct).lh))(
+ tsp->obj,tsp->inbuf,(tsp->pos).lineno,&(tsp->er_pr)
+ );
+ switch (res) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ tsp->pst = 2;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) { back = DK4_TSP_RES_ERROR; }
+ } break;
+ }
+ } else {
+ back = DK4_TSP_RES_FATAL;
+ tsp->pst = 2;
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_BUFFER_TOO_SMALL,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void
+dk4tsp16_get_errors(dk4_er_t *er_en, dk4_er_t *er_pr, dk4_tsp16_t *tsp)
+{
+ if (NULL != tsp) {
+ if (NULL != er_en) {
+ DK4_MEMCPY(er_en, &(tsp->er_en), sizeof(dk4_er_t));
+ }
+ if (NULL != er_pr) {
+ DK4_MEMCPY(er_pr, &(tsp->er_pr), sizeof(dk4_er_t));
+ }
+ }
+}
+
+
diff --git a/support/dktools/dk4tsp16.h b/support/dktools/dk4tsp16.h
new file mode 100644
index 0000000000..1cabc17d3c
--- /dev/null
+++ b/support/dktools/dk4tsp16.h
@@ -0,0 +1,247 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4tsp16.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4TSP16_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4TSP16_H_INCLUDED 1
+
+
+#line 9 "dk4tsp16.ctr"
+
+/** @file
+ Text stream processing for 16 bit characters.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4BOM_H_INCLUDED
+#include "dk4bom.h"
+#endif
+
+#ifndef DK4TSP_H_INCLUDED
+#include "dk4tsp.h"
+#endif
+
+#ifndef DK4UTF8_H_INCLUDED
+#include "dk4utf8.h"
+#endif
+
+#ifndef DK4UTF16_H_INCLUDED
+#include "dk4utf16.h"
+#endif
+
+#ifndef DK4C32_H_INCLUDED
+#include "dk4c32.h"
+#endif
+
+/** Handler function for single characters.
+ @param obj Object to modify while processing the character.
+ @param c Character to process.
+ @param pos Current position in file or data stream.
+ @param erp Error report, may be NULL.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+typedef int dk4_c16_handler_t(
+ void *obj,
+ dk4_c16_t c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+);
+
+/** Handler function for text lines.
+ @param obj Object to modify while processing the character.
+ @param line Text line to process.
+ @param lineno Current line number.
+ @param erp Error report, may be NULL.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fata error so we
+ should abort processing.
+*/
+typedef int dk4_c16_line_handler_t(
+ void *obj,
+ dk4_c16_t *line,
+ dk4_um_t lineno,
+ dk4_er_t *erp
+);
+
+/** Structure for 16 bit character processing.
+*/
+typedef struct {
+ union {
+ dk4_utf8_decoder_t u08; /**< UTF-8 decoder. */
+ dk4_utf16_byte_decoder_t u16; /**< UTF-16 decoder. */
+ dk4_c32_byte_decoder_t c32; /**< 32 bit char decoder. */
+ } dec; /**< Input decoder. */
+ dk4_bom_detector_t bomd; /**< BOM detector. */
+ dk4_text_stream_position_t pos; /**< Current position. */
+ dk4_er_t er_en; /**< Errors in input decoding. */
+ dk4_er_t er_pr; /**< Errors in processing. */
+ union {
+ dk4_c16_line_handler_t *lh; /**< Handler function for lines. */
+ dk4_c16_handler_t *ch; /**< Handler function for char. */
+ } fct; /**< Handler function. */
+ dk4_c16_t *inbuf; /**< Buffer for input line. */
+ void *obj; /**< Object to modify in processing. */
+ size_t in_sz; /**< Size of input line buffer. */
+ size_t in_us; /**< Used bytes in input line buffer. */
+ int ief; /**< Input encoding found. */
+ int iee; /**< Input encoding expected. */
+ int pst; /**< Processing stage. */
+} dk4_tsp16_t;
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Set up processor for byte by byte processing.
+ @param tsp Processor to set up.
+ @param obj Object to modify when processing input, may be NULL.
+ @param fct Handler function to call for each character.
+ @param eie Expected input encoding.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4tsp16_setup_char(
+ dk4_tsp16_t *tsp,
+ void *obj,
+ dk4_c16_handler_t *fct,
+ int eie,
+ dk4_er_t *erp
+);
+
+/** Set up processor for line processing.
+ @param tsp Processor to set up.
+ @param obj Object to modify when processing input, may be NULL.
+ @param fct Handler function to invoke for each line.
+ @param inbuf Input line buffer.
+ @param szin Size of input line buffer (number of dk4_c16_t).
+ @param eie Expected input encoding.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4tsp16_setup_line(
+ dk4_tsp16_t *tsp,
+ void *obj,
+ dk4_c16_line_handler_t *fct,
+ dk4_c16_t *inbuf,
+ size_t szin,
+ int eie,
+ dk4_er_t *erp
+);
+
+/** Add one single byte.
+ @param tsp Text stream processor.
+ @param inbyte Byte to process.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fata error so we
+ should abort processing.
+*/
+int
+dk4tsp16_add_one_byte(
+ dk4_tsp16_t *tsp,
+ unsigned char inbyte
+);
+
+/** Add multiple bytes.
+ @param tsp Text stream processor.
+ @param buffer Buffer start address.
+ @param sz Number of bytes in buffer.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fata error so we
+ should abort processing.
+*/
+int
+dk4tsp16_add_bytes(
+ dk4_tsp16_t *tsp,
+ const unsigned char *buffer,
+ size_t sz
+);
+
+/** Finish processing.
+ @param tsp Text stream processor.
+ @return DK4_TSP_RES_OK if processing was finished
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error,
+ DK4_TSP_RES_FATAL if there was a fatal error.
+*/
+int
+dk4tsp16_finish(dk4_tsp16_t *tsp);
+
+/** Retrieve error reports for encoding/decoding and processing.
+ @param er_en Destination error report buffer for encoding/decoding.
+ @param er_pr Destination error report buffer for processing.
+ @param tsp Text stream processor to retrieve errors from.
+*/
+void
+dk4tsp16_get_errors(dk4_er_t *er_en, dk4_er_t *er_pr, dk4_tsp16_t *tsp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4tsp32.c b/support/dktools/dk4tsp32.c
new file mode 100644
index 0000000000..ac1a18b121
--- /dev/null
+++ b/support/dktools/dk4tsp32.c
@@ -0,0 +1,646 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4tsp32.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4tsp32.c The dk4tsp32 module.
+*/
+
+
+#line 215 "dk4tsp32.ctr"
+
+#include "dk4tsp32.h"
+#include "dk4enc.h"
+#include "dk4mem.h"
+#include "dk4ansi.h"
+#include "dk4utf8.h"
+#include "dk4utf16.h"
+#include "dk4c32.h"
+
+
+
+
+
+#line 227 "dk4tsp32.ctr"
+
+
+
+/** Initialize text stream processing structure.
+ @param tsp Text stream processor.
+ @param eie Expected input encoding.
+*/
+static
+void
+dk4tsp32_init(dk4_tsp32_t *tsp, int eie)
+{
+ DK4_MEMRES(tsp, sizeof(dk4_tsp32_t));
+ dk4bom_detect_init(&(tsp->bomd), eie);
+ dk4error_init(&(tsp->er_en));
+ dk4error_init(&(tsp->er_pr));
+ tsp->inbuf = NULL;
+ tsp->obj = NULL;
+ tsp->in_sz = 0;
+ tsp->in_us = 0;
+ tsp->ief = eie;
+ tsp->iee = eie;
+ tsp->pst = 0;
+ (tsp->pos).bytes = (dk4_um_t)0UL;
+ (tsp->pos).chars = (dk4_um_t)1UL;
+ (tsp->pos).lineno = (dk4_um_t)1UL;
+ (tsp->pos).charil = (dk4_um_t)1UL;
+}
+
+
+
+/** Process a 32 bit character.
+ @param tsp Text stream processor.
+ @param chr Character to process.
+ @return DK4_TSP_RES_OK if the characters were processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so
+ we should abort processing.
+*/
+static
+int
+dk4tsp32_process_character(
+ dk4_tsp32_t *tsp,
+ dk4_c32_t chr
+)
+{
+ int back = DK4_TSP_RES_FATAL;
+
+
+#line 276 "dk4tsp32.ctr"
+ /* Increase position */
+ (tsp->pos).chars += (dk4_um_t)1UL;
+ (tsp->pos).charil += (dk4_um_t)1UL;
+ /* Check for line buffering or direct processing */
+ if ((NULL != tsp->inbuf) && (0 < tsp->in_sz) && (NULL != (tsp->fct).lh)) {
+
+
+#line 282 "dk4tsp32.ctr"
+ if (tsp->in_us < tsp->in_sz) {
+
+#line 283 "dk4tsp32.ctr"
+ (tsp->inbuf)[tsp->in_us] = chr;
+ tsp->in_us += 1;
+ back = DK4_TSP_RES_OK;
+ if ((dk4_c32_t)'\n' == chr) {
+ back = DK4_TSP_RES_FATAL;
+ if (tsp->in_us < tsp->in_sz) {
+ (tsp->inbuf)[tsp->in_us] = (dk4_c32_t)0UL;
+ back = (*((tsp->fct).lh))(
+ tsp->obj,tsp->inbuf,(tsp->pos).lineno,&(tsp->er_pr)
+ );
+ } else {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_BUFFER_TOO_SMALL,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ /* 2015-07-18
+ Bugfix: We must reset the number of used characters to 0
+ after processing and flushing the line buffer.
+ */
+ tsp->in_us = 0;
+ }
+ } else {
+
+#line 307 "dk4tsp32.ctr"
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_BUFFER_TOO_SMALL,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ } else {
+
+
+#line 315 "dk4tsp32.ctr"
+ if (NULL != (tsp->fct).ch) {
+ back = (*((tsp->fct).ch))(tsp->obj, chr, &(tsp->pos), &(tsp->er_pr));
+ }
+ }
+ if ((dk4_c32_t)('\n') == chr) {
+ (tsp->pos).lineno += (dk4_um_t)1UL;
+ (tsp->pos).charil = (dk4_um_t)1UL;
+ }
+
+
+#line 324 "dk4tsp32.ctr"
+ return back;
+}
+
+
+
+/** Normal processing for one byte.
+ Retrieve a 32 bit character first, either by decoding directly
+ or by adding to a decoder.
+ @param tsp Text stream processor.
+ @param inbyte Byte to process.
+ @return Operation result, one from DK4_TSP_RES_OK,
+ DK4_TSP_RES_ERROR or DK4_TSP_RES_FATAL.
+*/
+static
+int
+dk4tsp32_process_byte(
+ dk4_tsp32_t *tsp,
+ unsigned char inbyte
+)
+{
+ dk4_c32_t c32 = (dk4_c32_t)0UL; /* 32 bit character */
+ int back = DK4_TSP_RES_FATAL; /* Function result */
+ int cuc32 = 0; /* Flag: Have 32 bit char */
+ int res = 0; /* Operation result */
+ switch (tsp->ief) {
+ case DK4_FILE_ENCODING_ASCII: {
+ c32 = (dk4_c32_t)inbyte;
+ cuc32 = 1;
+ } break;
+ case DK4_FILE_ENCODING_ANSI: {
+ if (0 != dk4ansi_decode(&c32, inbyte)) {
+ cuc32 = 1;
+ } else {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ } break;
+ case DK4_FILE_ENCODING_UTF8: {
+ res = dk4utf8_add(&((tsp->dec).u08), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ERROR: {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ } break;
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf8_get(&((tsp->dec).u08));
+ cuc32 = 1;
+ dk4utf8_init(&((tsp->dec).u08));
+ } break;
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ }
+ } break;
+ case DK4_FILE_ENCODING_UTF16_LE: {
+ res = dk4utf16_byte_add(&((tsp->dec).u16), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ERROR: {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ } break;
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf16_byte_get(&((tsp->dec).u16));
+ cuc32 = 1;
+ dk4utf16_byte_init(&((tsp->dec).u16), 0);
+ } break;
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ }
+ } break;
+ case DK4_FILE_ENCODING_UTF16_BE: {
+ res = dk4utf16_byte_add(&((tsp->dec).u16), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ERROR: {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ } break;
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf16_byte_get(&((tsp->dec).u16));
+ cuc32 = 1;
+ dk4utf16_byte_init(&((tsp->dec).u16), 1);
+ } break;
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ }
+ } break;
+ case DK4_FILE_ENCODING_32_LE: {
+ res = dk4c32_decoder_add(&((tsp->dec).c32), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ERROR: {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ } break;
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4c32_decoder_get(&((tsp->dec).c32));
+ cuc32 = 1;
+ dk4c32_decoder_init(&((tsp->dec).c32), 0);
+ } break;
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ }
+ } break;
+ case DK4_FILE_ENCODING_32_BE: {
+ res = dk4c32_decoder_add(&((tsp->dec).c32), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ERROR: {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ } break;
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4c32_decoder_get(&((tsp->dec).c32));
+ cuc32 = 1;
+ dk4c32_decoder_init(&((tsp->dec).c32), 1);
+ } break;
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ }
+ } break;
+ }
+ if (0 != cuc32) {
+ back = dk4tsp32_process_character(tsp, c32);
+ }
+ if (DK4_TSP_RES_FATAL == back) {
+ tsp->pst = 2;
+ }
+ return back;
+}
+
+
+
+/** Initialize decoder for found input encoding.
+ @param tsp Text stream processor.
+*/
+static
+void
+dk4tsp32_initialize_decoder(dk4_tsp32_t *tsp)
+{
+ switch (tsp->ief) {
+ case DK4_FILE_ENCODING_UTF8: {
+ dk4utf8_init(&((tsp->dec).u08));
+ } break;
+ case DK4_FILE_ENCODING_UTF16_LE: {
+ dk4utf16_byte_init(&((tsp->dec).u16), 0);
+ } break;
+ case DK4_FILE_ENCODING_UTF16_BE: {
+ dk4utf16_byte_init(&((tsp->dec).u16), 1);
+ } break;
+ case DK4_FILE_ENCODING_32_LE: {
+ dk4c32_decoder_init(&((tsp->dec).c32), 0);
+ } break;
+ case DK4_FILE_ENCODING_32_BE: {
+ dk4c32_decoder_init(&((tsp->dec).c32), 1);
+ } break;
+ }
+}
+
+
+
+#if TRACE_DEBUG
+static unsigned long byte_number = 0UL;
+#endif
+
+/** Add one single byte.
+ @param tsp Text stream processor.
+ @param inbyte Byte to process.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fata error so we
+ should abort processing.
+*/
+static
+int
+dk4tsp32_i_add_one_byte(
+ dk4_tsp32_t *tsp,
+ unsigned char inbyte
+)
+{
+ size_t nrej; /* Number of unused bytes */
+ size_t i; /* Current unused byte index */
+ int back = DK4_TSP_RES_FATAL; /* Function result */
+ int res; /* Operation result */
+ unsigned char uc; /* Current unused byte */
+
+
+#line 531 "dk4tsp32.ctr"
+ (tsp->pos).bytes += (dk4_um_t)1UL;
+ switch (tsp->pst) {
+ case 0: {
+ res = dk4bom_detect_add(&(tsp->bomd), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ case DK4_EDSTM_FINISHED: case DK4_EDSTM_FINISHED_WITH_UNUSED: {
+ back = DK4_TSP_RES_OK;
+ tsp->ief = dk4bom_detect_get_encoding(&(tsp->bomd));
+ dk4tsp32_initialize_decoder(tsp);
+ tsp->pst = 1;
+ if (DK4_EDSTM_FINISHED_WITH_UNUSED == res) {
+ nrej = dk4bom_detect_num_unused_bytes(&(tsp->bomd));
+ if (0 < nrej) {
+ for (i = 0; ((i < nrej) && (DK4_TSP_RES_FATAL != back)); i++) {
+ uc = dk4bom_detect_unused_byte(&(tsp->bomd), i);
+ switch (dk4tsp32_process_byte(tsp, uc)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ }
+ }
+ }
+ } break;
+ }
+ } break;
+ case 1: {
+ back = dk4tsp32_process_byte(tsp, inbyte);
+ } break;
+ /*
+ Processing stage 2 indicates there was a serious error
+ before, we must skip further processing.
+ This situation is covered by the initialization value
+ DK4_TSP_RES_FATAL, so we do not need a case branch here.
+ */
+ }
+
+
+#line 576 "dk4tsp32.ctr"
+ return back;
+}
+
+
+
+int
+dk4tsp32_setup_char(
+ dk4_tsp32_t *tsp,
+ void *obj,
+ dk4_c32_handler_t *fct,
+ int eie,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+ if (NULL != tsp) {
+ dk4tsp32_init(tsp, eie);
+ if (NULL != fct) {
+ tsp->obj = obj;
+ (tsp->fct).ch = fct;
+ tsp->iee = eie;
+ tsp->ief = eie;
+ tsp->pst = 0;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ tsp->pst = 2;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4tsp32_setup_line(
+ dk4_tsp32_t *tsp,
+ void *obj,
+ dk4_c32_line_handler_t *fct,
+ dk4_c32_t *inbuf,
+ size_t szin,
+ int eie,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+ if (NULL != tsp) {
+ dk4tsp32_init(tsp, eie);
+ if ((NULL != fct) && (NULL != inbuf) && (0 < szin)) {
+ tsp->obj = obj;
+ (tsp->fct).lh = fct;
+ tsp->inbuf = inbuf;
+ tsp->in_sz = szin;
+ tsp->in_us = 0;
+ tsp->iee = eie;
+ tsp->ief = eie;
+ tsp->pst = 0;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ tsp->pst = 2;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4tsp32_add_one_byte(
+ dk4_tsp32_t *tsp,
+ unsigned char inbyte
+)
+{
+ int back = DK4_TSP_RES_FATAL;
+
+
+#line 656 "dk4tsp32.ctr"
+ if (NULL != tsp) {
+ if (2 > tsp->pst) {
+ back = dk4tsp32_i_add_one_byte(tsp, inbyte);
+ }
+ }
+
+
+#line 662 "dk4tsp32.ctr"
+ return back;
+}
+
+
+
+int
+dk4tsp32_add_bytes(
+ dk4_tsp32_t *tsp,
+ const unsigned char *buffer,
+ size_t sz
+)
+{
+ int back = DK4_TSP_RES_FATAL; /* Function result */
+ int res; /* Processing result */
+
+
+#line 677 "dk4tsp32.ctr"
+ if ((NULL != tsp) && (NULL != buffer) && (0 < sz)) {
+ if (2 > tsp->pst) {
+ back = DK4_TSP_RES_OK;
+ while ((sz--) && (2 > tsp->pst)) {
+ res = dk4tsp32_i_add_one_byte(tsp, *(buffer++));
+ switch (res) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ }
+ }
+ }
+
+
+#line 696 "dk4tsp32.ctr"
+ return back;
+}
+
+
+
+int
+dk4tsp32_finish(dk4_tsp32_t *tsp)
+{
+ size_t nrej = 0; /* Number of unused bytes */
+ size_t i = 0; /* Current unused byte index */
+ int back = DK4_TSP_RES_FATAL; /* Function result */
+ int res; /* Operation result */
+ unsigned char uc; /* Current unused byte */
+
+
+#line 710 "dk4tsp32.ctr"
+ if (NULL != tsp) {
+ /* Flush all unprocessed output
+ 1. If there are unprocessed bytes in the BOM detector as BOM
+ detection was not completed, process these bytes.
+ 2. If there are characters in the line buffer,
+ finalize the line buffer text and process it.
+ */
+ back = DK4_TSP_RES_OK;
+ /* Retrieve an process bytes stored in BOM detector */
+ if (0 == tsp->pst) {
+ tsp->pst = 1;
+ nrej = dk4bom_detect_num_unused_bytes(&(tsp->bomd));
+ if (0 < nrej) {
+ dk4tsp32_initialize_decoder(tsp);
+ for (i = 0; ((i < nrej) && (2 > tsp->pst)); i++) {
+ uc = dk4bom_detect_unused_byte(&(tsp->bomd), i);
+ switch (dk4tsp32_process_byte(tsp, uc)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ tsp->pst = 2;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) { back = DK4_TSP_RES_ERROR; }
+ } break;
+ }
+ }
+ }
+ }
+ /* Process final line */
+ if ((NULL != tsp->inbuf) && (0 < tsp->in_sz) && (NULL != (tsp->fct).lh)) {
+ if (0 < tsp->in_us) {
+ if (2 > tsp->pst) {
+ if (tsp->in_us < tsp->in_sz) {
+ (tsp->inbuf)[tsp->in_us] = (dk4_c32_t)0UL;
+ res =
+ (*((tsp->fct).lh))(
+ tsp->obj,tsp->inbuf,(tsp->pos).lineno,&(tsp->er_pr)
+ );
+ switch (res) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ tsp->pst = 2;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) { back = DK4_TSP_RES_ERROR; }
+ } break;
+ }
+ } else {
+ back = DK4_TSP_RES_FATAL;
+ tsp->pst = 2;
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_BUFFER_TOO_SMALL,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ }
+ }
+ }
+ }
+
+
+#line 771 "dk4tsp32.ctr"
+ return back;
+}
+
+
+
+void
+dk4tsp32_get_errors(dk4_er_t *er_en, dk4_er_t *er_pr, dk4_tsp32_t *tsp)
+{
+ if (NULL != tsp) {
+ if (NULL != er_en) {
+ DK4_MEMCPY(er_en, &(tsp->er_en), sizeof(dk4_er_t));
+ }
+ if (NULL != er_pr) {
+ DK4_MEMCPY(er_pr, &(tsp->er_pr), sizeof(dk4_er_t));
+ }
+ }
+}
+
+
+
diff --git a/support/dktools/dk4tsp32.ctr b/support/dktools/dk4tsp32.ctr
new file mode 100644
index 0000000000..3c1211c62c
--- /dev/null
+++ b/support/dktools/dk4tsp32.ctr
@@ -0,0 +1,790 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Text stream processing for 32 bit characters.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4BOM_H_INCLUDED
+#include "dk4bom.h"
+#endif
+
+#ifndef DK4TSP_H_INCLUDED
+#include "dk4tsp.h"
+#endif
+
+#ifndef DK4UTF8_H_INCLUDED
+#include "dk4utf8.h"
+#endif
+
+#ifndef DK4UTF16_H_INCLUDED
+#include "dk4utf16.h"
+#endif
+
+#ifndef DK4C32_H_INCLUDED
+#include "dk4c32.h"
+#endif
+
+/** Handler function for single characters.
+ @param obj Object to modify while processing the character.
+ @param c Character to process.
+ @param pos Current position in file or data stream.
+ @param erp Error report, may be NULL.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+typedef int dk4_c32_handler_t(
+ void *obj,
+ dk4_c32_t c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+);
+
+/** Handler function for text lines.
+ @param obj Object to modify while processing the character.
+ @param line Text line to process.
+ @param lineno Current line number.
+ @param erp Error report, may be NULL.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fata error so we
+ should abort processing.
+*/
+typedef int dk4_c32_line_handler_t(
+ void *obj,
+ dk4_c32_t *line,
+ dk4_um_t lineno,
+ dk4_er_t *erp
+);
+
+/** Structure for 32 bit character processing.
+*/
+typedef struct {
+ union {
+ dk4_utf8_decoder_t u08; /**< UTF-8 decoder. */
+ dk4_utf16_byte_decoder_t u16; /**< UTF-16 decoder. */
+ dk4_c32_byte_decoder_t c32; /**< 32 bit char decoder. */
+ } dec; /**< Input decoder. */
+ dk4_bom_detector_t bomd; /**< BOM detector. */
+ dk4_text_stream_position_t pos; /**< Current position. */
+ dk4_er_t er_en; /**< Errors in input decoding. */
+ dk4_er_t er_pr; /**< Errors in processing. */
+ union {
+ dk4_c32_line_handler_t *lh; /**< Handler function for lines. */
+ dk4_c32_handler_t *ch; /**< Handler function for char. */
+ } fct; /**< Handler function. */
+ dk4_c32_t *inbuf; /**< Buffer for input line. */
+ void *obj; /**< Object to modify in processing. */
+ size_t in_sz; /**< Size of input line buffer. */
+ size_t in_us; /**< Used bytes in input line buffer. */
+ int ief; /**< Input encoding found. */
+ int iee; /**< Input encoding expected. */
+ int pst; /**< Processing stage. */
+} dk4_tsp32_t;
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Set up processor for byte by byte processing.
+ @param tsp Processor to set up.
+ @param obj Object to modify when processing input, may be NULL.
+ @param fct Handler function to call for each character.
+ @param eie Expected input encoding.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4tsp32_setup_char(
+ dk4_tsp32_t *tsp,
+ void *obj,
+ dk4_c32_handler_t *fct,
+ int eie,
+ dk4_er_t *erp
+);
+
+/** Set up processor for line processing.
+ @param tsp Processor to set up.
+ @param obj Object to modify when processing input, may be NULL.
+ @param fct Handler function to invoke for each line.
+ @param inbuf Input line buffer.
+ @param szin Size of input line buffer (number of dk4_c32_t).
+ @param eie Expected input encoding.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4tsp32_setup_line(
+ dk4_tsp32_t *tsp,
+ void *obj,
+ dk4_c32_line_handler_t *fct,
+ dk4_c32_t *inbuf,
+ size_t szin,
+ int eie,
+ dk4_er_t *erp
+);
+
+/** Add one single byte.
+ @param tsp Text stream processor.
+ @param inbyte Byte to process.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fata error so we
+ should abort processing.
+*/
+int
+dk4tsp32_add_one_byte(
+ dk4_tsp32_t *tsp,
+ unsigned char inbyte
+);
+
+/** Add multiple bytes.
+ @param tsp Text stream processor.
+ @param buffer Buffer start address.
+ @param sz Number of bytes in buffer.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fata error so we
+ should abort processing.
+*/
+int
+dk4tsp32_add_bytes(
+ dk4_tsp32_t *tsp,
+ const unsigned char *buffer,
+ size_t sz
+);
+
+/** Finish processing.
+ @param tsp Text stream processor.
+ @return DK4_TSP_RES_OK if processing was finished
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error,
+ DK4_TSP_RES_FATAL if there was a fatal error.
+*/
+int
+dk4tsp32_finish(dk4_tsp32_t *tsp);
+
+/** Retrieve error reports for encoding/decoding and processing.
+ @param er_en Destination error report buffer for encoding/decoding.
+ @param er_pr Destination error report buffer for processing.
+ @param tsp Text stream processor to retrieve errors from.
+*/
+void
+dk4tsp32_get_errors(dk4_er_t *er_en, dk4_er_t *er_pr, dk4_tsp32_t *tsp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4tsp32.h"
+#include "dk4enc.h"
+#include "dk4mem.h"
+#include "dk4ansi.h"
+#include "dk4utf8.h"
+#include "dk4utf16.h"
+#include "dk4c32.h"
+
+
+
+$!trace-include
+
+
+
+/** Initialize text stream processing structure.
+ @param tsp Text stream processor.
+ @param eie Expected input encoding.
+*/
+static
+void
+dk4tsp32_init(dk4_tsp32_t *tsp, int eie)
+{
+ DK4_MEMRES(tsp, sizeof(dk4_tsp32_t));
+ dk4bom_detect_init(&(tsp->bomd), eie);
+ dk4error_init(&(tsp->er_en));
+ dk4error_init(&(tsp->er_pr));
+ tsp->inbuf = NULL;
+ tsp->obj = NULL;
+ tsp->in_sz = 0;
+ tsp->in_us = 0;
+ tsp->ief = eie;
+ tsp->iee = eie;
+ tsp->pst = 0;
+ (tsp->pos).bytes = (dk4_um_t)0UL;
+ (tsp->pos).chars = (dk4_um_t)1UL;
+ (tsp->pos).lineno = (dk4_um_t)1UL;
+ (tsp->pos).charil = (dk4_um_t)1UL;
+}
+
+
+
+/** Process a 32 bit character.
+ @param tsp Text stream processor.
+ @param chr Character to process.
+ @return DK4_TSP_RES_OK if the characters were processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so
+ we should abort processing.
+*/
+static
+int
+dk4tsp32_process_character(
+ dk4_tsp32_t *tsp,
+ dk4_c32_t chr
+)
+{
+ int back = DK4_TSP_RES_FATAL;
+ $? "+ dk4tsp32_process_character"
+ /* Increase position */
+ (tsp->pos).chars += (dk4_um_t)1UL;
+ (tsp->pos).charil += (dk4_um_t)1UL;
+ /* Check for line buffering or direct processing */
+ if ((NULL != tsp->inbuf) && (0 < tsp->in_sz) && (NULL != (tsp->fct).lh)) {
+ $? ". line buffering %lu %lu", (unsigned long)(tsp->in_us), (unsigned long)(tsp->in_sz)
+ if (tsp->in_us < tsp->in_sz) { $? ". used size < buffer size"
+ (tsp->inbuf)[tsp->in_us] = chr;
+ tsp->in_us += 1;
+ back = DK4_TSP_RES_OK;
+ if ((dk4_c32_t)'\n' == chr) {
+ back = DK4_TSP_RES_FATAL;
+ if (tsp->in_us < tsp->in_sz) {
+ (tsp->inbuf)[tsp->in_us] = (dk4_c32_t)0UL;
+ back = (*((tsp->fct).lh))(
+ tsp->obj,tsp->inbuf,(tsp->pos).lineno,&(tsp->er_pr)
+ );
+ } else {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_BUFFER_TOO_SMALL,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ /* 2015-07-18
+ Bugfix: We must reset the number of used characters to 0
+ after processing and flushing the line buffer.
+ */
+ tsp->in_us = 0;
+ }
+ } else { $? "! line buffer full"
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_BUFFER_TOO_SMALL,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ } else {
+ $? ". direct char processing"
+ if (NULL != (tsp->fct).ch) {
+ back = (*((tsp->fct).ch))(tsp->obj, chr, &(tsp->pos), &(tsp->er_pr));
+ }
+ }
+ if ((dk4_c32_t)('\n') == chr) {
+ (tsp->pos).lineno += (dk4_um_t)1UL;
+ (tsp->pos).charil = (dk4_um_t)1UL;
+ }
+ $? "- dk4tsp32_process_character %d", back
+ return back;
+}
+
+
+
+/** Normal processing for one byte.
+ Retrieve a 32 bit character first, either by decoding directly
+ or by adding to a decoder.
+ @param tsp Text stream processor.
+ @param inbyte Byte to process.
+ @return Operation result, one from DK4_TSP_RES_OK,
+ DK4_TSP_RES_ERROR or DK4_TSP_RES_FATAL.
+*/
+static
+int
+dk4tsp32_process_byte(
+ dk4_tsp32_t *tsp,
+ unsigned char inbyte
+)
+{
+ dk4_c32_t c32 = (dk4_c32_t)0UL; /* 32 bit character */
+ int back = DK4_TSP_RES_FATAL; /* Function result */
+ int cuc32 = 0; /* Flag: Have 32 bit char */
+ int res = 0; /* Operation result */
+ switch (tsp->ief) {
+ case DK4_FILE_ENCODING_ASCII: {
+ c32 = (dk4_c32_t)inbyte;
+ cuc32 = 1;
+ } break;
+ case DK4_FILE_ENCODING_ANSI: {
+ if (0 != dk4ansi_decode(&c32, inbyte)) {
+ cuc32 = 1;
+ } else {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ } break;
+ case DK4_FILE_ENCODING_UTF8: {
+ res = dk4utf8_add(&((tsp->dec).u08), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ERROR: {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ } break;
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf8_get(&((tsp->dec).u08));
+ cuc32 = 1;
+ dk4utf8_init(&((tsp->dec).u08));
+ } break;
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ }
+ } break;
+ case DK4_FILE_ENCODING_UTF16_LE: {
+ res = dk4utf16_byte_add(&((tsp->dec).u16), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ERROR: {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ } break;
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf16_byte_get(&((tsp->dec).u16));
+ cuc32 = 1;
+ dk4utf16_byte_init(&((tsp->dec).u16), 0);
+ } break;
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ }
+ } break;
+ case DK4_FILE_ENCODING_UTF16_BE: {
+ res = dk4utf16_byte_add(&((tsp->dec).u16), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ERROR: {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ } break;
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4utf16_byte_get(&((tsp->dec).u16));
+ cuc32 = 1;
+ dk4utf16_byte_init(&((tsp->dec).u16), 1);
+ } break;
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ }
+ } break;
+ case DK4_FILE_ENCODING_32_LE: {
+ res = dk4c32_decoder_add(&((tsp->dec).c32), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ERROR: {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ } break;
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4c32_decoder_get(&((tsp->dec).c32));
+ cuc32 = 1;
+ dk4c32_decoder_init(&((tsp->dec).c32), 0);
+ } break;
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ }
+ } break;
+ case DK4_FILE_ENCODING_32_BE: {
+ res = dk4c32_decoder_add(&((tsp->dec).c32), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ERROR: {
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_DECODING_FAILED,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ } break;
+ case DK4_EDSTM_FINISHED: {
+ c32 = dk4c32_decoder_get(&((tsp->dec).c32));
+ cuc32 = 1;
+ dk4c32_decoder_init(&((tsp->dec).c32), 1);
+ } break;
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ }
+ } break;
+ }
+ if (0 != cuc32) {
+ back = dk4tsp32_process_character(tsp, c32);
+ }
+ if (DK4_TSP_RES_FATAL == back) {
+ tsp->pst = 2;
+ }
+ return back;
+}
+
+
+
+/** Initialize decoder for found input encoding.
+ @param tsp Text stream processor.
+*/
+static
+void
+dk4tsp32_initialize_decoder(dk4_tsp32_t *tsp)
+{
+ switch (tsp->ief) {
+ case DK4_FILE_ENCODING_UTF8: {
+ dk4utf8_init(&((tsp->dec).u08));
+ } break;
+ case DK4_FILE_ENCODING_UTF16_LE: {
+ dk4utf16_byte_init(&((tsp->dec).u16), 0);
+ } break;
+ case DK4_FILE_ENCODING_UTF16_BE: {
+ dk4utf16_byte_init(&((tsp->dec).u16), 1);
+ } break;
+ case DK4_FILE_ENCODING_32_LE: {
+ dk4c32_decoder_init(&((tsp->dec).c32), 0);
+ } break;
+ case DK4_FILE_ENCODING_32_BE: {
+ dk4c32_decoder_init(&((tsp->dec).c32), 1);
+ } break;
+ }
+}
+
+
+
+#if TRACE_DEBUG
+static unsigned long byte_number = 0UL;
+#endif
+
+/** Add one single byte.
+ @param tsp Text stream processor.
+ @param inbyte Byte to process.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fata error so we
+ should abort processing.
+*/
+static
+int
+dk4tsp32_i_add_one_byte(
+ dk4_tsp32_t *tsp,
+ unsigned char inbyte
+)
+{
+ size_t nrej; /* Number of unused bytes */
+ size_t i; /* Current unused byte index */
+ int back = DK4_TSP_RES_FATAL; /* Function result */
+ int res; /* Operation result */
+ unsigned char uc; /* Current unused byte */
+ $? "+ dk4tsp32_i_add_one_byte index=%lu '%!8c' 0x%02x", byte_number++, inbyte, (unsigned)inbyte
+ (tsp->pos).bytes += (dk4_um_t)1UL;
+ switch (tsp->pst) {
+ case 0: {
+ res = dk4bom_detect_add(&(tsp->bomd), inbyte);
+ switch (res) {
+ case DK4_EDSTM_ACCEPT: {
+ back = DK4_TSP_RES_OK;
+ } break;
+ case DK4_EDSTM_FINISHED: case DK4_EDSTM_FINISHED_WITH_UNUSED: {
+ back = DK4_TSP_RES_OK;
+ tsp->ief = dk4bom_detect_get_encoding(&(tsp->bomd));
+ dk4tsp32_initialize_decoder(tsp);
+ tsp->pst = 1;
+ if (DK4_EDSTM_FINISHED_WITH_UNUSED == res) {
+ nrej = dk4bom_detect_num_unused_bytes(&(tsp->bomd));
+ if (0 < nrej) {
+ for (i = 0; ((i < nrej) && (DK4_TSP_RES_FATAL != back)); i++) {
+ uc = dk4bom_detect_unused_byte(&(tsp->bomd), i);
+ switch (dk4tsp32_process_byte(tsp, uc)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ }
+ }
+ }
+ } break;
+ }
+ } break;
+ case 1: {
+ back = dk4tsp32_process_byte(tsp, inbyte);
+ } break;
+ /*
+ Processing stage 2 indicates there was a serious error
+ before, we must skip further processing.
+ This situation is covered by the initialization value
+ DK4_TSP_RES_FATAL, so we do not need a case branch here.
+ */
+ }
+ $? "- dk4tsp32_i_add_one_byte %d", back
+ return back;
+}
+
+
+
+int
+dk4tsp32_setup_char(
+ dk4_tsp32_t *tsp,
+ void *obj,
+ dk4_c32_handler_t *fct,
+ int eie,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+ if (NULL != tsp) {
+ dk4tsp32_init(tsp, eie);
+ if (NULL != fct) {
+ tsp->obj = obj;
+ (tsp->fct).ch = fct;
+ tsp->iee = eie;
+ tsp->ief = eie;
+ tsp->pst = 0;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ tsp->pst = 2;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4tsp32_setup_line(
+ dk4_tsp32_t *tsp,
+ void *obj,
+ dk4_c32_line_handler_t *fct,
+ dk4_c32_t *inbuf,
+ size_t szin,
+ int eie,
+ dk4_er_t *erp
+)
+{
+ int back = 0;
+ if (NULL != tsp) {
+ dk4tsp32_init(tsp, eie);
+ if ((NULL != fct) && (NULL != inbuf) && (0 < szin)) {
+ tsp->obj = obj;
+ (tsp->fct).lh = fct;
+ tsp->inbuf = inbuf;
+ tsp->in_sz = szin;
+ tsp->in_us = 0;
+ tsp->iee = eie;
+ tsp->ief = eie;
+ tsp->pst = 0;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ tsp->pst = 2;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4tsp32_add_one_byte(
+ dk4_tsp32_t *tsp,
+ unsigned char inbyte
+)
+{
+ int back = DK4_TSP_RES_FATAL;
+ $? "+ dk4tsp32_add_one_byte"
+ if (NULL != tsp) {
+ if (2 > tsp->pst) {
+ back = dk4tsp32_i_add_one_byte(tsp, inbyte);
+ }
+ }
+ $? "- dk4tsp32_add_one_byte %d", back
+ return back;
+}
+
+
+
+int
+dk4tsp32_add_bytes(
+ dk4_tsp32_t *tsp,
+ const unsigned char *buffer,
+ size_t sz
+)
+{
+ int back = DK4_TSP_RES_FATAL; /* Function result */
+ int res; /* Processing result */
+ $? "+ dk4tsp32_add_bytes"
+ if ((NULL != tsp) && (NULL != buffer) && (0 < sz)) {
+ if (2 > tsp->pst) {
+ back = DK4_TSP_RES_OK;
+ while ((sz--) && (2 > tsp->pst)) {
+ res = dk4tsp32_i_add_one_byte(tsp, *(buffer++));
+ switch (res) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) {
+ back = DK4_TSP_RES_ERROR;
+ }
+ } break;
+ }
+ }
+ }
+ }
+ $? "- dk4tsp32_add_bytes %d", back
+ return back;
+}
+
+
+
+int
+dk4tsp32_finish(dk4_tsp32_t *tsp)
+{
+ size_t nrej = 0; /* Number of unused bytes */
+ size_t i = 0; /* Current unused byte index */
+ int back = DK4_TSP_RES_FATAL; /* Function result */
+ int res; /* Operation result */
+ unsigned char uc; /* Current unused byte */
+ $? "+ dk4tsp32_finish"
+ if (NULL != tsp) {
+ /* Flush all unprocessed output
+ 1. If there are unprocessed bytes in the BOM detector as BOM
+ detection was not completed, process these bytes.
+ 2. If there are characters in the line buffer,
+ finalize the line buffer text and process it.
+ */
+ back = DK4_TSP_RES_OK;
+ /* Retrieve an process bytes stored in BOM detector */
+ if (0 == tsp->pst) {
+ tsp->pst = 1;
+ nrej = dk4bom_detect_num_unused_bytes(&(tsp->bomd));
+ if (0 < nrej) {
+ dk4tsp32_initialize_decoder(tsp);
+ for (i = 0; ((i < nrej) && (2 > tsp->pst)); i++) {
+ uc = dk4bom_detect_unused_byte(&(tsp->bomd), i);
+ switch (dk4tsp32_process_byte(tsp, uc)) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ tsp->pst = 2;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) { back = DK4_TSP_RES_ERROR; }
+ } break;
+ }
+ }
+ }
+ }
+ /* Process final line */
+ if ((NULL != tsp->inbuf) && (0 < tsp->in_sz) && (NULL != (tsp->fct).lh)) {
+ if (0 < tsp->in_us) {
+ if (2 > tsp->pst) {
+ if (tsp->in_us < tsp->in_sz) {
+ (tsp->inbuf)[tsp->in_us] = (dk4_c32_t)0UL;
+ res =
+ (*((tsp->fct).lh))(
+ tsp->obj,tsp->inbuf,(tsp->pos).lineno,&(tsp->er_pr)
+ );
+ switch (res) {
+ case DK4_TSP_RES_FATAL: {
+ back = DK4_TSP_RES_FATAL;
+ tsp->pst = 2;
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == back) { back = DK4_TSP_RES_ERROR; }
+ } break;
+ }
+ } else {
+ back = DK4_TSP_RES_FATAL;
+ tsp->pst = 2;
+ dk4error_set_with_position(
+ &(tsp->er_en), DK4_E_BUFFER_TOO_SMALL,
+ (tsp->pos).bytes, (tsp->pos).lineno,
+ (tsp->pos).chars, (tsp->pos).charil
+ );
+ }
+ }
+ }
+ }
+ }
+ $? "- dk4tsp32_finish %d", back
+ return back;
+}
+
+
+
+void
+dk4tsp32_get_errors(dk4_er_t *er_en, dk4_er_t *er_pr, dk4_tsp32_t *tsp)
+{
+ if (NULL != tsp) {
+ if (NULL != er_en) {
+ DK4_MEMCPY(er_en, &(tsp->er_en), sizeof(dk4_er_t));
+ }
+ if (NULL != er_pr) {
+ DK4_MEMCPY(er_pr, &(tsp->er_pr), sizeof(dk4_er_t));
+ }
+ }
+}
+
+
+
diff --git a/support/dktools/dk4tsp32.h b/support/dktools/dk4tsp32.h
new file mode 100644
index 0000000000..e082fe71c3
--- /dev/null
+++ b/support/dktools/dk4tsp32.h
@@ -0,0 +1,247 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4tsp32.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4TSP32_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4TSP32_H_INCLUDED 1
+
+
+#line 10 "dk4tsp32.ctr"
+
+/** @file
+ Text stream processing for 32 bit characters.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4BOM_H_INCLUDED
+#include "dk4bom.h"
+#endif
+
+#ifndef DK4TSP_H_INCLUDED
+#include "dk4tsp.h"
+#endif
+
+#ifndef DK4UTF8_H_INCLUDED
+#include "dk4utf8.h"
+#endif
+
+#ifndef DK4UTF16_H_INCLUDED
+#include "dk4utf16.h"
+#endif
+
+#ifndef DK4C32_H_INCLUDED
+#include "dk4c32.h"
+#endif
+
+/** Handler function for single characters.
+ @param obj Object to modify while processing the character.
+ @param c Character to process.
+ @param pos Current position in file or data stream.
+ @param erp Error report, may be NULL.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+typedef int dk4_c32_handler_t(
+ void *obj,
+ dk4_c32_t c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+);
+
+/** Handler function for text lines.
+ @param obj Object to modify while processing the character.
+ @param line Text line to process.
+ @param lineno Current line number.
+ @param erp Error report, may be NULL.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fata error so we
+ should abort processing.
+*/
+typedef int dk4_c32_line_handler_t(
+ void *obj,
+ dk4_c32_t *line,
+ dk4_um_t lineno,
+ dk4_er_t *erp
+);
+
+/** Structure for 32 bit character processing.
+*/
+typedef struct {
+ union {
+ dk4_utf8_decoder_t u08; /**< UTF-8 decoder. */
+ dk4_utf16_byte_decoder_t u16; /**< UTF-16 decoder. */
+ dk4_c32_byte_decoder_t c32; /**< 32 bit char decoder. */
+ } dec; /**< Input decoder. */
+ dk4_bom_detector_t bomd; /**< BOM detector. */
+ dk4_text_stream_position_t pos; /**< Current position. */
+ dk4_er_t er_en; /**< Errors in input decoding. */
+ dk4_er_t er_pr; /**< Errors in processing. */
+ union {
+ dk4_c32_line_handler_t *lh; /**< Handler function for lines. */
+ dk4_c32_handler_t *ch; /**< Handler function for char. */
+ } fct; /**< Handler function. */
+ dk4_c32_t *inbuf; /**< Buffer for input line. */
+ void *obj; /**< Object to modify in processing. */
+ size_t in_sz; /**< Size of input line buffer. */
+ size_t in_us; /**< Used bytes in input line buffer. */
+ int ief; /**< Input encoding found. */
+ int iee; /**< Input encoding expected. */
+ int pst; /**< Processing stage. */
+} dk4_tsp32_t;
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Set up processor for byte by byte processing.
+ @param tsp Processor to set up.
+ @param obj Object to modify when processing input, may be NULL.
+ @param fct Handler function to call for each character.
+ @param eie Expected input encoding.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4tsp32_setup_char(
+ dk4_tsp32_t *tsp,
+ void *obj,
+ dk4_c32_handler_t *fct,
+ int eie,
+ dk4_er_t *erp
+);
+
+/** Set up processor for line processing.
+ @param tsp Processor to set up.
+ @param obj Object to modify when processing input, may be NULL.
+ @param fct Handler function to invoke for each line.
+ @param inbuf Input line buffer.
+ @param szin Size of input line buffer (number of dk4_c32_t).
+ @param eie Expected input encoding.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4tsp32_setup_line(
+ dk4_tsp32_t *tsp,
+ void *obj,
+ dk4_c32_line_handler_t *fct,
+ dk4_c32_t *inbuf,
+ size_t szin,
+ int eie,
+ dk4_er_t *erp
+);
+
+/** Add one single byte.
+ @param tsp Text stream processor.
+ @param inbyte Byte to process.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fata error so we
+ should abort processing.
+*/
+int
+dk4tsp32_add_one_byte(
+ dk4_tsp32_t *tsp,
+ unsigned char inbyte
+);
+
+/** Add multiple bytes.
+ @param tsp Text stream processor.
+ @param buffer Buffer start address.
+ @param sz Number of bytes in buffer.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fata error so we
+ should abort processing.
+*/
+int
+dk4tsp32_add_bytes(
+ dk4_tsp32_t *tsp,
+ const unsigned char *buffer,
+ size_t sz
+);
+
+/** Finish processing.
+ @param tsp Text stream processor.
+ @return DK4_TSP_RES_OK if processing was finished
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error,
+ DK4_TSP_RES_FATAL if there was a fatal error.
+*/
+int
+dk4tsp32_finish(dk4_tsp32_t *tsp);
+
+/** Retrieve error reports for encoding/decoding and processing.
+ @param er_en Destination error report buffer for encoding/decoding.
+ @param er_pr Destination error report buffer for processing.
+ @param tsp Text stream processor to retrieve errors from.
+*/
+void
+dk4tsp32_get_errors(dk4_er_t *er_en, dk4_er_t *er_pr, dk4_tsp32_t *tsp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4tspdk.c b/support/dktools/dk4tspdk.c
new file mode 100644
index 0000000000..2ad76eaa1b
--- /dev/null
+++ b/support/dktools/dk4tspdk.c
@@ -0,0 +1,175 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4tspdk.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4tspdk.c The dk4tspdk module.
+*/
+
+
+#line 205 "dk4tspdk.ctr"
+
+
+
+#include "dk4tspdk.h"
+
+
+
+int
+dk4tspdk_setup_char(
+ dk4_tspdk_t *tsp,
+ void *obj,
+ dk4_dk_handler_t *fct,
+ int pre,
+ int eie,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ return (dk4tsp32_setup_char(tsp, obj, fct, eie, erp));
+#else
+ return (dk4tsp16_setup_char(tsp, obj, fct, eie, erp));
+#endif
+#else
+ return (dk4tsp08_setup_char(tsp, obj, fct, pre, eie, erp));
+#endif
+}
+
+
+
+int
+dk4tspdk_setup_line(
+ dk4_tspdk_t *tsp,
+ void *obj,
+ dk4_dk_line_handler_t *fct,
+ dkChar *inbuf,
+ size_t szin,
+ int pre,
+ int eie,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ return (dk4tsp32_setup_line(tsp, obj, fct, inbuf, szin, eie, erp));
+#else
+ return (dk4tsp16_setup_line(tsp, obj, fct, inbuf, szin, eie, erp));
+#endif
+#else
+ return (dk4tsp08_setup_line(tsp, obj, fct, inbuf, szin, pre, eie, erp));
+#endif
+}
+
+
+
+int
+dk4tspdk_add_one_byte(
+ dk4_tspdk_t *tsp,
+ unsigned char inbyte
+)
+{
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ return (dk4tsp32_add_one_byte(tsp, inbyte));
+#else
+ return (dk4tsp16_add_one_byte(tsp, inbyte));
+#endif
+#else
+ return (dk4tsp08_add_one_byte(tsp, inbyte));
+#endif
+}
+
+
+
+int
+dk4tspdk_add_bytes(
+ dk4_tspdk_t *tsp,
+ const unsigned char *buffer,
+ size_t sz
+)
+{
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ return (dk4tsp32_add_bytes(tsp, buffer, sz));
+#else
+ return (dk4tsp16_add_bytes(tsp, buffer, sz));
+#endif
+#else
+ return (dk4tsp08_add_bytes(tsp, buffer, sz));
+#endif
+}
+
+
+
+int
+dk4tspdk_finish(dk4_tspdk_t *tsp)
+{
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ return (dk4tsp32_finish(tsp));
+#else
+ return (dk4tsp16_finish(tsp));
+#endif
+#else
+ return (dk4tsp08_finish(tsp));
+#endif
+}
+
+
+
+void
+dk4tspdk_get_errors(dk4_er_t *er_en, dk4_er_t *er_pr, dk4_tspdk_t *tsp)
+{
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ dk4tsp32_get_errors(er_en, er_pr, tsp);
+#else
+ dk4tsp16_get_errors(er_en, er_pr, tsp);
+#endif
+#else
+ dk4tsp08_get_errors(er_en, er_pr, tsp);
+#endif
+}
+
+
+
+void
+dk4tspdk_enable_utf8_pass_through(dk4_tspdk_t *tsp, int fl)
+{
+#if DK4_CHAR_SIZE == 1
+ dk4tsp08_enable_utf8_pass_through(tsp, fl);
+#endif
+}
+
+
diff --git a/support/dktools/dk4tspdk.ctr b/support/dktools/dk4tspdk.ctr
new file mode 100644
index 0000000000..7ea2d7d7c4
--- /dev/null
+++ b/support/dktools/dk4tspdk.ctr
@@ -0,0 +1,339 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Text stream processing for dkChar characters.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+/* +++++ dkChar 4 bytes */
+
+#ifndef DK4TSP32_H_INCLUDED
+#include "dk4tsp32.h"
+#endif
+
+/** Handler function to process a single character.
+*/
+typedef dk4_c32_handler_t dk4_dk_handler_t;
+
+/** Handler function to process an input line.
+*/
+typedef dk4_c32_line_handler_t dk4_dk_line_handler_t;
+
+/** Text stream processor.
+*/
+typedef dk4_tsp32_t dk4_tspdk_t;
+
+/* ----- dkChar 4 bytes */
+#else
+/* +++++ dkChar 2 bytes */
+
+#ifndef DK4TSP16_H_INCLUDED
+#include "dk4tsp16.h"
+#endif
+
+/** Handler function to process a single character.
+*/
+typedef dk4_c16_handler_t dk4_dk_handler_t;
+
+/** Handler function to process an input line.
+*/
+typedef dk4_c16_line_handler_t dk4_dk_line_handler_t;
+
+/** Text stream processor.
+*/
+typedef dk4_tsp16_t dk4_tspdk_t;
+
+/* ----- dkChar 2 bytes */
+#endif
+#else
+/* +++++ dkChar 1 byte */
+
+#ifndef DK4TSP08_H_INCLUDED
+#include "dk4tsp08.h"
+#endif
+
+/** Handler function to process a single character.
+*/
+typedef dk4_c8_handler_t dk4_dk_handler_t;
+
+/** Handler function to process an input line.
+*/
+typedef dk4_c8_line_handler_t dk4_dk_line_handler_t;
+
+/** Text stream processor.
+*/
+typedef dk4_tsp08_t dk4_tspdk_t;
+
+/* ----- dkChar 1 byte */
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Set up processor for char by char processing.
+ @param tsp Processor to set up.
+ @param obj Object to modify when processing input, may be NULL.
+ @param fct Handler function to call for each character.
+ @param pre Encoding required for processing.
+ @param eie Expected input encoding.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4tspdk_setup_char(
+ dk4_tspdk_t *tsp,
+ void *obj,
+ dk4_dk_handler_t *fct,
+ int pre,
+ int eie,
+ dk4_er_t *erp
+);
+
+/** Set up processor for line processing.
+ @param tsp Processor to set up.
+ @param obj Object to modify when processing input, may be NULL.
+ @param fct Handler function to invoke for each line.
+ @param inbuf Input line buffer.
+ @param szin Size of input line buffer.
+ @param pre Encoding required for processing.
+ @param eie Expected input encoding.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4tspdk_setup_line(
+ dk4_tspdk_t *tsp,
+ void *obj,
+ dk4_dk_line_handler_t *fct,
+ dkChar *inbuf,
+ size_t szin,
+ int pre,
+ int eie,
+ dk4_er_t *erp
+);
+
+/** Allow pass-through of UTF-8 encoded data.
+ @param tsp Text stream processor to set up.
+ @param fl Flag: Enable pass-through of UTF-8 encoded data.
+*/
+void
+dk4tspdk_enable_utf8_pass_through(dk4_tspdk_t *tsp, int fl);
+
+/** Add one single byte.
+ @param tsp Text stream processor.
+ @param inbyte Byte to process.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+int
+dk4tspdk_add_one_byte(
+ dk4_tspdk_t *tsp,
+ unsigned char inbyte
+);
+
+/** Add multiple bytes.
+ @param tsp Text stream processor.
+ @param buffer Buffer start address.
+ @param sz Number of bytes in buffer.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+int
+dk4tspdk_add_bytes(
+ dk4_tspdk_t *tsp,
+ const unsigned char *buffer,
+ size_t sz
+);
+
+/** Finish processing.
+ @param tsp Text stream processor.
+ @return DK4_TSP_RES_OK if processing was finished
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error,
+ DK4_TSP_RES_FATAL if there was a fatal error.
+*/
+int
+dk4tspdk_finish(dk4_tspdk_t *tsp);
+
+/** Retrieve error reports for encoding/decoding and processing.
+ @param er_en Destination error report buffer for encoding/decoding.
+ @param er_pr Destination error report buffer for processing.
+ @param tsp Text stream processor to retrieve errors from.
+*/
+void
+dk4tspdk_get_errors(dk4_er_t *er_en, dk4_er_t *er_pr, dk4_tspdk_t *tsp);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+
+
+#include "dk4tspdk.h"
+
+
+
+int
+dk4tspdk_setup_char(
+ dk4_tspdk_t *tsp,
+ void *obj,
+ dk4_dk_handler_t *fct,
+ int pre,
+ int eie,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ return (dk4tsp32_setup_char(tsp, obj, fct, eie, erp));
+#else
+ return (dk4tsp16_setup_char(tsp, obj, fct, eie, erp));
+#endif
+#else
+ return (dk4tsp08_setup_char(tsp, obj, fct, pre, eie, erp));
+#endif
+}
+
+
+
+int
+dk4tspdk_setup_line(
+ dk4_tspdk_t *tsp,
+ void *obj,
+ dk4_dk_line_handler_t *fct,
+ dkChar *inbuf,
+ size_t szin,
+ int pre,
+ int eie,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ return (dk4tsp32_setup_line(tsp, obj, fct, inbuf, szin, eie, erp));
+#else
+ return (dk4tsp16_setup_line(tsp, obj, fct, inbuf, szin, eie, erp));
+#endif
+#else
+ return (dk4tsp08_setup_line(tsp, obj, fct, inbuf, szin, pre, eie, erp));
+#endif
+}
+
+
+
+int
+dk4tspdk_add_one_byte(
+ dk4_tspdk_t *tsp,
+ unsigned char inbyte
+)
+{
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ return (dk4tsp32_add_one_byte(tsp, inbyte));
+#else
+ return (dk4tsp16_add_one_byte(tsp, inbyte));
+#endif
+#else
+ return (dk4tsp08_add_one_byte(tsp, inbyte));
+#endif
+}
+
+
+
+int
+dk4tspdk_add_bytes(
+ dk4_tspdk_t *tsp,
+ const unsigned char *buffer,
+ size_t sz
+)
+{
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ return (dk4tsp32_add_bytes(tsp, buffer, sz));
+#else
+ return (dk4tsp16_add_bytes(tsp, buffer, sz));
+#endif
+#else
+ return (dk4tsp08_add_bytes(tsp, buffer, sz));
+#endif
+}
+
+
+
+int
+dk4tspdk_finish(dk4_tspdk_t *tsp)
+{
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ return (dk4tsp32_finish(tsp));
+#else
+ return (dk4tsp16_finish(tsp));
+#endif
+#else
+ return (dk4tsp08_finish(tsp));
+#endif
+}
+
+
+
+void
+dk4tspdk_get_errors(dk4_er_t *er_en, dk4_er_t *er_pr, dk4_tspdk_t *tsp)
+{
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ dk4tsp32_get_errors(er_en, er_pr, tsp);
+#else
+ dk4tsp16_get_errors(er_en, er_pr, tsp);
+#endif
+#else
+ dk4tsp08_get_errors(er_en, er_pr, tsp);
+#endif
+}
+
+
+
+void
+dk4tspdk_enable_utf8_pass_through(dk4_tspdk_t *tsp, int fl)
+{
+#if DK4_CHAR_SIZE == 1
+ dk4tsp08_enable_utf8_pass_through(tsp, fl);
+#endif
+}
+
+
diff --git a/support/dktools/dk4tspdk.h b/support/dktools/dk4tspdk.h
new file mode 100644
index 0000000000..50a98ccf69
--- /dev/null
+++ b/support/dktools/dk4tspdk.h
@@ -0,0 +1,237 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4tspdk.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4TSPDK_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4TSPDK_H_INCLUDED 1
+
+
+#line 10 "dk4tspdk.ctr"
+
+/** @file
+ Text stream processing for dkChar characters.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+/* +++++ dkChar 4 bytes */
+
+#ifndef DK4TSP32_H_INCLUDED
+#include "dk4tsp32.h"
+#endif
+
+/** Handler function to process a single character.
+*/
+typedef dk4_c32_handler_t dk4_dk_handler_t;
+
+/** Handler function to process an input line.
+*/
+typedef dk4_c32_line_handler_t dk4_dk_line_handler_t;
+
+/** Text stream processor.
+*/
+typedef dk4_tsp32_t dk4_tspdk_t;
+
+/* ----- dkChar 4 bytes */
+#else
+/* +++++ dkChar 2 bytes */
+
+#ifndef DK4TSP16_H_INCLUDED
+#include "dk4tsp16.h"
+#endif
+
+/** Handler function to process a single character.
+*/
+typedef dk4_c16_handler_t dk4_dk_handler_t;
+
+/** Handler function to process an input line.
+*/
+typedef dk4_c16_line_handler_t dk4_dk_line_handler_t;
+
+/** Text stream processor.
+*/
+typedef dk4_tsp16_t dk4_tspdk_t;
+
+/* ----- dkChar 2 bytes */
+#endif
+#else
+/* +++++ dkChar 1 byte */
+
+#ifndef DK4TSP08_H_INCLUDED
+#include "dk4tsp08.h"
+#endif
+
+/** Handler function to process a single character.
+*/
+typedef dk4_c8_handler_t dk4_dk_handler_t;
+
+/** Handler function to process an input line.
+*/
+typedef dk4_c8_line_handler_t dk4_dk_line_handler_t;
+
+/** Text stream processor.
+*/
+typedef dk4_tsp08_t dk4_tspdk_t;
+
+/* ----- dkChar 1 byte */
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Set up processor for char by char processing.
+ @param tsp Processor to set up.
+ @param obj Object to modify when processing input, may be NULL.
+ @param fct Handler function to call for each character.
+ @param pre Encoding required for processing.
+ @param eie Expected input encoding.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4tspdk_setup_char(
+ dk4_tspdk_t *tsp,
+ void *obj,
+ dk4_dk_handler_t *fct,
+ int pre,
+ int eie,
+ dk4_er_t *erp
+);
+
+/** Set up processor for line processing.
+ @param tsp Processor to set up.
+ @param obj Object to modify when processing input, may be NULL.
+ @param fct Handler function to invoke for each line.
+ @param inbuf Input line buffer.
+ @param szin Size of input line buffer.
+ @param pre Encoding required for processing.
+ @param eie Expected input encoding.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4tspdk_setup_line(
+ dk4_tspdk_t *tsp,
+ void *obj,
+ dk4_dk_line_handler_t *fct,
+ dkChar *inbuf,
+ size_t szin,
+ int pre,
+ int eie,
+ dk4_er_t *erp
+);
+
+/** Allow pass-through of UTF-8 encoded data.
+ @param tsp Text stream processor to set up.
+ @param fl Flag: Enable pass-through of UTF-8 encoded data.
+*/
+void
+dk4tspdk_enable_utf8_pass_through(dk4_tspdk_t *tsp, int fl);
+
+/** Add one single byte.
+ @param tsp Text stream processor.
+ @param inbyte Byte to process.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+int
+dk4tspdk_add_one_byte(
+ dk4_tspdk_t *tsp,
+ unsigned char inbyte
+);
+
+/** Add multiple bytes.
+ @param tsp Text stream processor.
+ @param buffer Buffer start address.
+ @param sz Number of bytes in buffer.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+int
+dk4tspdk_add_bytes(
+ dk4_tspdk_t *tsp,
+ const unsigned char *buffer,
+ size_t sz
+);
+
+/** Finish processing.
+ @param tsp Text stream processor.
+ @return DK4_TSP_RES_OK if processing was finished
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error,
+ DK4_TSP_RES_FATAL if there was a fatal error.
+*/
+int
+dk4tspdk_finish(dk4_tspdk_t *tsp);
+
+/** Retrieve error reports for encoding/decoding and processing.
+ @param er_en Destination error report buffer for encoding/decoding.
+ @param er_pr Destination error report buffer for processing.
+ @param tsp Text stream processor to retrieve errors from.
+*/
+void
+dk4tspdk_get_errors(dk4_er_t *er_en, dk4_er_t *er_pr, dk4_tspdk_t *tsp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4tspwx.cpp b/support/dktools/dk4tspwx.cpp
new file mode 100644
index 0000000000..48c87e3102
--- /dev/null
+++ b/support/dktools/dk4tspwx.cpp
@@ -0,0 +1,197 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4tspwx.cpt
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4tspwx.cpp The dk4tspwx module.
+*/
+
+
+#line 233 "dk4tspwx.cpt"
+
+#include "dk4tspwx.h"
+
+
+
+
+
+#line 239 "dk4tspwx.cpt"
+
+
+
+int
+dk4tspwx_setup_char(
+ dk4_tspwx_t *tsp,
+ void *obj,
+ dk4_wx_handler_t *fct,
+ int pre,
+ int eie,
+ dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR > 2
+ return (dk4tsp32_setup_char(tsp, obj, fct, eie, erp));
+#else
+ return (dk4tsp16_setup_char(tsp, obj, fct, eie, erp));
+#endif
+#else
+ return (dk4tsp08_setup_char(tsp, obj, fct, pre, eie, erp));
+#endif
+}
+
+
+
+int
+dk4tspwx_setup_line(
+ dk4_tspwx_t *tsp,
+ void *obj,
+ dk4_wx_line_handler_t *fct,
+ wxChar *inbuf,
+ size_t szin,
+ int pre,
+ int eie,
+ dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR > 2
+ return (dk4tsp32_setup_line(tsp,obj,fct,(dk4_c32_t *)inbuf,szin,eie,erp));
+#else
+ return (dk4tsp16_setup_line(tsp,obj,fct,(dk4_c16_t *)inbuf,szin,eie,erp));
+#endif
+#else
+ return (dk4tsp08_setup_line(tsp,obj,fct,(char *)inbuf,szin,pre,eie,erp));
+#endif
+}
+
+
+
+void
+dk4tspwx_enable_utf8_pass_through(dk4_tspwx_t *tsp, int fl)
+{
+#if DK4_SIZEOF_WXCHAR == 1
+ dk4tsp08_enable_utf8_pass_through(tsp, fl);
+#endif
+}
+
+
+
+#if TRACE_DEBUG
+static unsigned long byteno = 0UL;
+#endif
+
+
+int
+dk4tspwx_add_one_byte(
+ dk4_tspwx_t *tsp,
+ unsigned char inbyte
+)
+{
+
+
+#line 312 "dk4tspwx.cpt"
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR > 2
+ return (dk4tsp32_add_one_byte(tsp, inbyte));
+#else
+ return (dk4tsp16_add_one_byte(tsp, inbyte));
+#endif
+#else
+ return (dk4tsp08_add_one_byte(tsp, inbyte));
+#endif
+}
+
+
+
+int
+dk4tspwx_add_bytes(
+ dk4_tspwx_t *tsp,
+ const unsigned char *buffer,
+ size_t sz
+)
+{
+
+
+#line 333 "dk4tspwx.cpt"
+#if TRACE_DEBUG
+ if (NULL != dktrace_file()) {
+ fputc('"', dktrace_file());
+ fwrite(buffer, sizeof(char), sz, dktrace_file());
+ fputc('"', dktrace_file());
+ }
+#endif
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR > 2
+ return (dk4tsp32_add_bytes(tsp, buffer, sz));
+#else
+ return (dk4tsp16_add_bytes(tsp, buffer, sz));
+#endif
+#else
+ return (dk4tsp08_add_bytes(tsp, buffer, sz));
+#endif
+}
+
+
+
+int
+dk4tspwx_finish(dk4_tspwx_t *tsp)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR > 2
+ return (dk4tsp32_finish(tsp));
+#else
+ return (dk4tsp16_finish(tsp));
+#endif
+#else
+ return (dk4tsp08_finish(tsp));
+#endif
+}
+
+
+
+void
+dk4tspwx_get_errors(dk4_er_t *er_en, dk4_er_t *er_pr, dk4_tspwx_t *tsp)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR > 2
+ dk4tsp32_get_errors(er_en, er_pr, tsp);
+#else
+ dk4tsp16_get_errors(er_en, er_pr, tsp);
+#endif
+#else
+ dk4tsp08_get_errors(er_en, er_pr, tsp);
+#endif
+}
+
diff --git a/support/dktools/dk4tspwx.cpt b/support/dktools/dk4tspwx.cpt
new file mode 100644
index 0000000000..b9b6e8cb59
--- /dev/null
+++ b/support/dktools/dk4tspwx.cpt
@@ -0,0 +1,383 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file dk4tspwx.h Text stream processing for wxChar.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4WXCS_H_INCLUDED
+#include "dk4wxcs.h"
+#endif
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR > 2
+/* +++++ dkChar 4 bytes */
+
+#ifndef DK4TSP32_H_INCLUDED
+#include "dk4tsp32.h"
+#endif
+
+/** Handler function to process a single character.
+*/
+typedef dk4_c32_handler_t dk4_wx_handler_t;
+
+/** Handler function to process an input line.
+*/
+typedef dk4_c32_line_handler_t dk4_wx_line_handler_t;
+
+/** Text stream processor.
+*/
+typedef dk4_tsp32_t dk4_tspwx_t;
+
+/* ----- dkChar 4 bytes */
+#else
+/* +++++ dkChar 2 bytes */
+
+#ifndef DK4TSP16_H_INCLUDED
+#include "dk4tsp16.h"
+#endif
+
+/** Handler function to process a single character.
+*/
+typedef dk4_c16_handler_t dk4_wx_handler_t;
+
+/** Handler function to process an input line.
+*/
+typedef dk4_c16_line_handler_t dk4_wx_line_handler_t;
+
+/** Text stream processor.
+*/
+typedef dk4_tsp16_t dk4_tspwx_t;
+
+/* ----- dkChar 2 bytes */
+#endif
+#else
+/* +++++ dkChar 1 byte */
+
+#ifndef DK4TSP08_H_INCLUDED
+#include "dk4tsp08.h"
+#endif
+
+/** Handler function to process a single character.
+*/
+typedef dk4_c8_handler_t dk4_wx_handler_t;
+
+/** Handler function to process an input line.
+*/
+typedef dk4_c8_line_handler_t dk4_wx_line_handler_t;
+
+/** Text stream processor.
+*/
+typedef dk4_tsp08_t dk4_tspwx_t;
+
+/* ----- dkChar 1 byte */
+#endif
+
+
+
+extern "C" {
+
+/** Set up processor for char by char processing.
+ @param tsp Processor to set up.
+ @param obj Object to modify when processing input, may be NULL.
+ @param fct Handler function to call for each character.
+ @param pre Encoding required for processing.
+ @param eie Expected input encoding.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4tspwx_setup_char(
+ dk4_tspwx_t *tsp,
+ void *obj,
+ dk4_wx_handler_t *fct,
+ int pre,
+ int eie,
+ dk4_er_t *erp
+);
+
+/** Set up processor for line processing.
+ @param tsp Processor to set up.
+ @param obj Object to modify when processing input, may be NULL.
+ @param fct Handler function to invoke for each line.
+ @param inbuf Input line buffer.
+ @param szin Size of input line buffer (number of wxChar).
+ @param pre Encoding required for processing.
+ @param eie Expected input encoding.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4tspwx_setup_line(
+ dk4_tspwx_t *tsp,
+ void *obj,
+ dk4_wx_line_handler_t *fct,
+ wxChar *inbuf,
+ size_t szin,
+ int pre,
+ int eie,
+ dk4_er_t *erp
+);
+
+/** Allow pass-through of UTF-8 encoded data.
+ @param tsp Text stream processor to set up.
+ @param fl Flag: Enable pass-through of UTF-8 encoded data.
+*/
+void
+dk4tspwx_enable_utf8_pass_through(dk4_tspwx_t *tsp, int fl);
+
+/** Add one single byte.
+ @param tsp Text stream processor.
+ @param inbyte Byte to process.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+int
+dk4tspwx_add_one_byte(
+ dk4_tspwx_t *tsp,
+ unsigned char inbyte
+);
+
+/** Add multiple bytes.
+ @param tsp Text stream processor.
+ @param buffer Buffer start address.
+ @param sz Number of bytes in buffer.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+int
+dk4tspwx_add_bytes(
+ dk4_tspwx_t *tsp,
+ const unsigned char *buffer,
+ size_t sz
+);
+
+/** Finish processing.
+ @param tsp Text stream processor.
+ @return DK4_TSP_RES_OK if processing was finished
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error,
+ DK4_TSP_RES_FATAL if there was a fatal error.
+*/
+int
+dk4tspwx_finish(dk4_tspwx_t *tsp);
+
+/** Retrieve error reports for encoding/decoding and processing.
+ @param er_en Destination error report buffer for encoding/decoding.
+ @param er_pr Destination error report buffer for processing.
+ @param tsp Text stream processor to retrieve errors from.
+*/
+void
+dk4tspwx_get_errors(dk4_er_t *er_en, dk4_er_t *er_pr, dk4_tspwx_t *tsp);
+
+}
+
+
+
+%% module
+
+#include "dk4tspwx.h"
+
+
+
+$!trace-include
+
+
+
+int
+dk4tspwx_setup_char(
+ dk4_tspwx_t *tsp,
+ void *obj,
+ dk4_wx_handler_t *fct,
+ int pre,
+ int eie,
+ dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR > 2
+ return (dk4tsp32_setup_char(tsp, obj, fct, eie, erp));
+#else
+ return (dk4tsp16_setup_char(tsp, obj, fct, eie, erp));
+#endif
+#else
+ return (dk4tsp08_setup_char(tsp, obj, fct, pre, eie, erp));
+#endif
+}
+
+
+
+int
+dk4tspwx_setup_line(
+ dk4_tspwx_t *tsp,
+ void *obj,
+ dk4_wx_line_handler_t *fct,
+ wxChar *inbuf,
+ size_t szin,
+ int pre,
+ int eie,
+ dk4_er_t *erp
+)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR > 2
+ return (dk4tsp32_setup_line(tsp,obj,fct,(dk4_c32_t *)inbuf,szin,eie,erp));
+#else
+ return (dk4tsp16_setup_line(tsp,obj,fct,(dk4_c16_t *)inbuf,szin,eie,erp));
+#endif
+#else
+ return (dk4tsp08_setup_line(tsp,obj,fct,(char *)inbuf,szin,pre,eie,erp));
+#endif
+}
+
+
+
+void
+dk4tspwx_enable_utf8_pass_through(dk4_tspwx_t *tsp, int fl)
+{
+#if DK4_SIZEOF_WXCHAR == 1
+ dk4tsp08_enable_utf8_pass_through(tsp, fl);
+#endif
+}
+
+
+
+#if TRACE_DEBUG
+static unsigned long byteno = 0UL;
+#endif
+
+
+int
+dk4tspwx_add_one_byte(
+ dk4_tspwx_t *tsp,
+ unsigned char inbyte
+)
+{
+ $? "= dk4tspwx_add_one_byte index=%lu '%!8c' 0x%02x", byteno++, inbyte, inbyte
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR > 2
+ return (dk4tsp32_add_one_byte(tsp, inbyte));
+#else
+ return (dk4tsp16_add_one_byte(tsp, inbyte));
+#endif
+#else
+ return (dk4tsp08_add_one_byte(tsp, inbyte));
+#endif
+}
+
+
+
+int
+dk4tspwx_add_bytes(
+ dk4_tspwx_t *tsp,
+ const unsigned char *buffer,
+ size_t sz
+)
+{
+ $? "= dk4tspwx_add_bytes %lu", (unsigned long)sz
+#if TRACE_DEBUG
+ if (NULL != dktrace_file()) {
+ fputc('"', dktrace_file());
+ fwrite(buffer, sizeof(char), sz, dktrace_file());
+ fputc('"', dktrace_file());
+ }
+#endif
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR > 2
+ return (dk4tsp32_add_bytes(tsp, buffer, sz));
+#else
+ return (dk4tsp16_add_bytes(tsp, buffer, sz));
+#endif
+#else
+ return (dk4tsp08_add_bytes(tsp, buffer, sz));
+#endif
+}
+
+
+
+int
+dk4tspwx_finish(dk4_tspwx_t *tsp)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR > 2
+ return (dk4tsp32_finish(tsp));
+#else
+ return (dk4tsp16_finish(tsp));
+#endif
+#else
+ return (dk4tsp08_finish(tsp));
+#endif
+}
+
+
+
+void
+dk4tspwx_get_errors(dk4_er_t *er_en, dk4_er_t *er_pr, dk4_tspwx_t *tsp)
+{
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR > 2
+ dk4tsp32_get_errors(er_en, er_pr, tsp);
+#else
+ dk4tsp16_get_errors(er_en, er_pr, tsp);
+#endif
+#else
+ dk4tsp08_get_errors(er_en, er_pr, tsp);
+#endif
+}
+
diff --git a/support/dktools/dk4tspwx.h b/support/dktools/dk4tspwx.h
new file mode 100644
index 0000000000..cccda351dc
--- /dev/null
+++ b/support/dktools/dk4tspwx.h
@@ -0,0 +1,266 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4tspwx.cpt
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4TSPWX_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4TSPWX_H_INCLUDED 1
+
+
+#line 9 "dk4tspwx.cpt"
+
+/** @file dk4tspwx.h Text stream processing for wxChar.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4WXCS_H_INCLUDED
+#include "dk4wxcs.h"
+#endif
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR > 2
+/* +++++ dkChar 4 bytes */
+
+#ifndef DK4TSP32_H_INCLUDED
+#include "dk4tsp32.h"
+#endif
+
+/** Handler function to process a single character.
+*/
+typedef dk4_c32_handler_t dk4_wx_handler_t;
+
+/** Handler function to process an input line.
+*/
+typedef dk4_c32_line_handler_t dk4_wx_line_handler_t;
+
+/** Text stream processor.
+*/
+typedef dk4_tsp32_t dk4_tspwx_t;
+
+/* ----- dkChar 4 bytes */
+#else
+/* +++++ dkChar 2 bytes */
+
+#ifndef DK4TSP16_H_INCLUDED
+#include "dk4tsp16.h"
+#endif
+
+/** Handler function to process a single character.
+*/
+typedef dk4_c16_handler_t dk4_wx_handler_t;
+
+/** Handler function to process an input line.
+*/
+typedef dk4_c16_line_handler_t dk4_wx_line_handler_t;
+
+/** Text stream processor.
+*/
+typedef dk4_tsp16_t dk4_tspwx_t;
+
+/* ----- dkChar 2 bytes */
+#endif
+#else
+/* +++++ dkChar 1 byte */
+
+#ifndef DK4TSP08_H_INCLUDED
+#include "dk4tsp08.h"
+#endif
+
+/** Handler function to process a single character.
+*/
+typedef dk4_c8_handler_t dk4_wx_handler_t;
+
+/** Handler function to process an input line.
+*/
+typedef dk4_c8_line_handler_t dk4_wx_line_handler_t;
+
+/** Text stream processor.
+*/
+typedef dk4_tsp08_t dk4_tspwx_t;
+
+/* ----- dkChar 1 byte */
+#endif
+
+
+
+extern "C" {
+
+/** Set up processor for char by char processing.
+ @param tsp Processor to set up.
+ @param obj Object to modify when processing input, may be NULL.
+ @param fct Handler function to call for each character.
+ @param pre Encoding required for processing.
+ @param eie Expected input encoding.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4tspwx_setup_char(
+ dk4_tspwx_t *tsp,
+ void *obj,
+ dk4_wx_handler_t *fct,
+ int pre,
+ int eie,
+ dk4_er_t *erp
+);
+
+/** Set up processor for line processing.
+ @param tsp Processor to set up.
+ @param obj Object to modify when processing input, may be NULL.
+ @param fct Handler function to invoke for each line.
+ @param inbuf Input line buffer.
+ @param szin Size of input line buffer (number of wxChar).
+ @param pre Encoding required for processing.
+ @param eie Expected input encoding.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4tspwx_setup_line(
+ dk4_tspwx_t *tsp,
+ void *obj,
+ dk4_wx_line_handler_t *fct,
+ wxChar *inbuf,
+ size_t szin,
+ int pre,
+ int eie,
+ dk4_er_t *erp
+);
+
+/** Allow pass-through of UTF-8 encoded data.
+ @param tsp Text stream processor to set up.
+ @param fl Flag: Enable pass-through of UTF-8 encoded data.
+*/
+void
+dk4tspwx_enable_utf8_pass_through(dk4_tspwx_t *tsp, int fl);
+
+/** Add one single byte.
+ @param tsp Text stream processor.
+ @param inbyte Byte to process.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+int
+dk4tspwx_add_one_byte(
+ dk4_tspwx_t *tsp,
+ unsigned char inbyte
+);
+
+/** Add multiple bytes.
+ @param tsp Text stream processor.
+ @param buffer Buffer start address.
+ @param sz Number of bytes in buffer.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+int
+dk4tspwx_add_bytes(
+ dk4_tspwx_t *tsp,
+ const unsigned char *buffer,
+ size_t sz
+);
+
+/** Finish processing.
+ @param tsp Text stream processor.
+ @return DK4_TSP_RES_OK if processing was finished
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error,
+ DK4_TSP_RES_FATAL if there was a fatal error.
+*/
+int
+dk4tspwx_finish(dk4_tspwx_t *tsp);
+
+/** Retrieve error reports for encoding/decoding and processing.
+ @param er_en Destination error report buffer for encoding/decoding.
+ @param er_pr Destination error report buffer for processing.
+ @param tsp Text stream processor to retrieve errors from.
+*/
+void
+dk4tspwx_get_errors(dk4_er_t *er_en, dk4_er_t *er_pr, dk4_tspwx_t *tsp);
+
+}
+
+
+
+
+#endif
diff --git a/support/dktools/dk4types.h b/support/dktools/dk4types.h
new file mode 100644
index 0000000000..2b7c90c167
--- /dev/null
+++ b/support/dktools/dk4types.h
@@ -0,0 +1,428 @@
+/** @file dk4types.h Data types for DK libraries.
+
+The dkChar data type is mapped to char on all non-Windows platforms,
+wchar_t on Windows.
+The dk4_c16_t and dk4_c32_t types are for 16 and 32 bit characters.
+
+The dk4_im_t and dk4_um_t are signed and unsigned integer types
+of largest size available on the system. All integer values can
+be cast to these types without loss.
+
+*/
+#ifndef DK4TYPES_H_INCLUDED
+/** Protection against multiple inclusion.
+*/
+#define DK4TYPES_H_INCLUDED 1
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+
+#ifndef STDIO_H_INCLUDED
+#include <stdio.h>
+#define STDIO_H_INCLUDED 1
+#endif
+
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDINT_H
+#ifndef STDINT_H_INCLUDED
+#if defined(__cplusplus) && (!defined(__STDC_LIMIT_MACROS))
+/** Allow use of limit macros from stdint.h file.
+*/
+#define __STDC_LIMIT_MACROS 1
+#endif
+#if defined(__cplusplus) && (!defined(__STDC_CONSTANT_MACROS))
+/** Allow use of constant macros from stdint.h file.
+*/
+#define __STDC_CONSTANT_MACROS 1
+#endif
+#include <stdint.h>
+#define STDINT_H_INCLUDED 1
+#endif
+#endif
+#if DK4_HAVE_INTTYPES_H
+#ifndef INTTYPES_H_INCLUDED
+#include <inttypes.h>
+#define INTTYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_WCHAR_H
+#ifndef WCHAR_H_INCLUDED
+#include <wchar.h>
+#define WCHAR_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FLOAT_H
+#ifndef FLOAT_H_INCLUDED
+#include <float.h>
+#define FLOAT_H_INCLUDED 1
+#endif
+#endif
+
+#ifdef _WIN32
+
+/** 16 bit character.
+ The dkChar type is mapped to wchar_t on Windows, char on all
+ other systems.
+*/
+typedef wchar_t dkChar;
+
+/** Size of a dkChar.
+*/
+#define DK4_CHAR_SIZE 2
+
+/** Generate dkChar literals.
+*/
+#define dkT(x) L ## x
+
+#else
+/* ifdef _WIN32 */
+
+/** Simple 8 bit character.
+ The dkChar type is mapped to wchar_t on Windows, char on all
+ other systems.
+*/
+typedef char dkChar;
+
+/** Size of a dkChar.
+*/
+#define DK4_CHAR_SIZE 1
+
+/** Generate dkChar literals.
+*/
+#define dkT(x) x
+
+#endif
+/* ifdef _WIN32 */
+
+
+
+#if DK4_SIZEOF_SHORT >= 2
+/** 16 bit character, UTF-16 encoded.
+*/
+typedef unsigned short dk4_c16_t;
+
+/** Notation for 16 bit values.
+*/
+#define dkC16(x) x ## U
+#else
+#if DK4_SIZEOF_INT >= 2
+/** 16 bit character, UTF-16 encoded.
+*/
+typedef unsigned int dk4_c16_t;
+
+/** Notation for 16 bit values.
+*/
+#define dkC16(x) x ## U
+#else
+#if DK4_SIZEOF_LONG >= 2
+/** 16 bit character, UTF-16 encoded.
+*/
+typedef unsigned long dk4_c16_t;
+
+/** Notation for 16 bit values.
+*/
+#define dkC16(x) x ## UL
+#else
+#error "No integer type long enough for 16 bits!"
+#endif
+#endif
+#endif
+
+
+
+#if DK4_SIZEOF_SHORT >= 4
+/** 32 bit Unicode character.
+*/
+typedef unsigned short dk4_c32_t;
+
+/** 4 bytes type (double word).
+*/
+typedef unsigned short dk4_dword_t;
+
+/** Notation for 32 bit values.
+*/
+#define dkC32(x) x ## U
+#else
+#if DK4_SIZEOF_INT >= 4
+/** 32 bit Unicode character.
+*/
+typedef unsigned int dk4_c32_t;
+
+/** 4 bytes type (double word).
+*/
+typedef unsigned int dk4_dword_t;
+
+/** Notation for 32 bit values.
+*/
+#define dkC32(x) x ## U
+#else
+#if DK4_SIZEOF_LONG >= 4
+/** 32 bit Unicode character.
+*/
+typedef unsigned long dk4_c32_t;
+
+/** 4 bytes type (double word).
+*/
+typedef unsigned long dk4_dword_t;
+
+/** Notation for 32 bit values.
+*/
+#define dkC32(x) x ## UL
+#else
+#error "No integer type long enough for 32 bits!"
+#endif
+#endif
+#endif
+
+
+#if DK4_HAVE_INTMAX_T
+/** Maximum unsigned integer.
+*/
+typedef uintmax_t dk4_um_t;
+/** Maximum signed integer.
+*/
+typedef intmax_t dk4_im_t;
+#else
+#if DK4_HAVE_LONG_LONG
+/** Maximum unsigned integer.
+*/
+typedef unsigned long long dk4_um_t;
+/** Maximum signed integer.
+*/
+typedef long long dk4_im_t;
+#else
+/** Maximum unsigned integer.
+*/
+typedef unsigned long dk4_um_t;
+/** Maximum signed integer.
+*/
+typedef long dk4_im_t;
+#endif
+#endif
+
+
+#if DK4_HAVE_SIG_ATOMIC_T
+/** Atomic integer type.
+*/
+typedef sig_atomic_t dk4_sig_atomic_t;
+#else
+/** Atomic integer type.
+*/
+typedef char dk4_sig_atomic_t;
+#endif
+
+/** Protorype for signal handlers.
+*/
+typedef void dk4_sig_handler_t(int);
+
+#if DK4_HAVE_VOLATILE
+/** Use volatile keyword.
+*/
+#define DK4_VOLATILE volatile
+#else
+/** Volatile keyword not defined.
+*/
+#define DK4_VOLATILE /* not defined */
+#endif
+
+#if !DK4_HAVE_UINT8_T
+/** 8 bit data type.
+*/
+typedef unsigned char uint8_t;
+#endif
+
+#if !DK4_HAVE_UINT16_T
+#if DK4_SIZEOF_SHORT >= 2
+/** 16 bit data type.
+*/
+typedef unsigned short uint16_t;
+#else
+#if DK4_SIZEOF_INT >= 2
+/** 16 bit data type.
+*/
+typedef unsigned int uint16_t;
+#else
+#if DK4_SIZEOF_LONG >= 2
+/** 16 bit data type.
+*/
+typedef unsigned long uint16_t;
+#else
+#error "No data type found for uint16_t!"
+#endif
+#endif
+#endif
+#endif
+
+#if !DK4_HAVE_INT8_T
+/** 8 bit signed data type.
+*/
+typedef signed char int8_t;
+#endif
+
+#if !DK4_HAVE_INT16_t
+#if DK4_SIZEOF_SHORT >= 2
+/** 16 bit signed data type.
+*/
+typedef short int16_t;
+#else
+#if DK4_SIZEOF_INT >= 2
+/** 16 bit signed data type.
+*/
+typedef int int16_t;
+#else
+#if DK4_SIZEOF_LONG >= 2
+/** 16 bit signed data type.
+*/
+typedef long int16_t;
+#else
+#error "No data type found for int16_t!"
+#endif
+#endif
+#endif
+#endif
+
+
+#if !DK4_HAVE_UINT32_T
+#if DK4_SIZEOF_SHORT >= 4
+/** 32 bit data type.
+*/
+typedef unsigned short uint32_t;
+#else
+#if DK4_SIZEOF_INT >= 4
+/** 32 bit data type.
+*/
+typedef unsigned int uint32_t;
+#else
+#if DK4_SIZEOF_LONG >= 4
+/** 32 bit data type.
+*/
+typedef unsigned long uint32_t;
+#else
+#error "No data type found for uint32_t!"
+#endif
+#endif
+#endif
+#endif
+
+#if !DK4_HAVE_INT32_T
+#if DK4_SIZEOF_SHORT >= 4
+/** 32 bit signed data type.
+*/
+typedef short int32_t;
+#else
+#if DK4_SIZEOF_INT >= 4
+/** 32 bit signed data type.
+*/
+typedef int int32_t;
+#else
+#if DK4_SIZEOF_LONG >= 4
+/** 32 bit signed data type.
+*/
+#define long int32_t;
+#else
+#error "No data type found for int32_t!"
+#endif
+#endif
+#endif
+#endif
+
+#ifndef DK4_U16_MAX
+/** Maximum value for 16 bit unsigned integer.
+*/
+#define DK4_U16_MAX ((uint16_t)(0xFFFFU))
+#endif
+
+#ifndef DK4_I16_MAX
+/** Maximum value for 16 bit signed integer.
+*/
+#define DK4_I16_MAX ((int16_t)(0x7FFFU))
+#endif
+
+#ifndef DK4_I16_MIN
+/** Minimum value for 16 bit signed integer.
+*/
+#define DK4_I16_MIN ((int16_t)(-0x7FFF - 1))
+#endif
+
+#ifndef DK4_U32_MAX
+/** Maximum value for 32 bit unsigned integer.
+*/
+#define DK4_U32_MAX ((uint32_t)(0xFFFFFFFFUL))
+#endif
+
+#ifndef DK4_I32_MAX
+/** Maximum value for 32 bit signed integer.
+*/
+#define DK4_I32_MAX ((int32_t)(0x7FFFFFFFL))
+#endif
+
+#ifndef DK4_I32_MIN
+/** Minimum value for 32 bit signed integer.
+*/
+#define DK4_I32_MIN ((int32_t)(-0x7FFFFFFFL - 1L))
+#endif
+
+#ifndef DK4_DBL_DIGITS
+#ifdef DBL_DECIMAL_DIG
+/** Number of digits to printf or scanf a double without precision loss.
+*/
+#define DK4_DBL_DIGITS (DBL_DECIMAL_DIG)
+#else
+#ifdef DECIMAL_DIG
+/** Number of digits to printf or scanf a double without precision loss.
+*/
+#define DK4_DBL_DIGITS (DECIMAL_DIG)
+#else
+#ifdef DBL_DIG
+/** Number of digits to printf or scanf a double without precision loss.
+*/
+#define DK4_DBL_DIGITS ((DBL_DIG) + 3)
+#else
+/** Number of digits to printf or scanf a double without precision loss.
+*/
+#define DK4_DBL_DIGITS 17
+#endif
+#endif
+#endif
+#endif
+
+/** Pointer to const dkChar.
+*/
+typedef const dkChar *DK4_PCDKCHAR;
+
+/** Pointer to dkChar.
+*/
+typedef dkChar *DK4_PDKCHAR;
+
+/** Pointer to const character.
+*/
+typedef const char *DK4_PCCHAR;
+
+/** Pointer to character.
+*/
+typedef char *DK4_PCHAR;
+
+#endif
+/* ifndef DK4TYPES_H_INCLUDED */
diff --git a/support/dktools/dk4uc2l.c b/support/dktools/dk4uc2l.c
new file mode 100644
index 0000000000..3f8d54446f
--- /dev/null
+++ b/support/dktools/dk4uc2l.c
@@ -0,0 +1,2358 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4uc2l.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4uc2l.c The dk4uc2l module.
+*/
+
+
+#line 238 "dk4uc2l.ctr"
+
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4const.h"
+#include "dk4uc2l.h"
+#include "dk4mem.h"
+#include "dk4mema.h"
+#include "dk4str8.h"
+#include "dk4strd.h"
+#include "dk4maasz.h"
+#include "dk4filed.h"
+#include "dk4mpl.h"
+#include "dk4strm.h"
+#include "dk4strmr.h"
+#include "dk4dir.h"
+#include "dk4dira.h"
+#include "dk4pathd.h"
+#include "dk4tsp08.h"
+#include "dk4enc.h"
+#include "dk4mai8hdu.h"
+#include "dk4maodh.h"
+#include "dk4maodd.h"
+
+
+
+
+
+#line 274 "dk4uc2l.ctr"
+
+
+
+typedef char *dk4_uc2l_char_ptr;
+
+typedef dk4_uc2l_pkg_t *dk4_uc2l_pkg_ptr;
+
+typedef dk4_uc2l_pkg_ptr *dk4_uc2l_pkg_ptr_ptr;
+
+/** Data passed to the line handler.
+*/
+typedef struct {
+ dk4_uc2l_t *ulptr; /**< Conversion structure. */
+ dk4_app_t *app; /**< Application for diagnostics, may be NULL. */
+ const dkChar *sfn; /**< Short file name (pass 1). */
+ dk4_sto_t *s_r; /**< Storage for file ranges. */
+ dk4_sto_it_t *i_r; /**< Iterator for file ranges. */
+ int e_d; /**< Decoding errors. */
+ int e_e; /**< Encoding errors. */
+ int e_p; /**< Processing errors. */
+} dk4_uc2l_lhobj;
+
+
+
+/** Fixed keywords used by the module, not localized.
+*/
+static const dkChar * const dk4uc2l_kwnl[] = {
+/* 0 */
+dkT("dir.charmap"),
+
+/* 1 */
+dkT("/dktools/charmap"),
+
+/* 2 */
+dkT("/dk4app/charmap"),
+
+/* 3 */
+dkT("/dk3app/charmap"),
+
+/* 4 */
+dkT(".t2l"),
+
+/* 5 */
+dkT(".t2l.gz"),
+
+/* 6 */
+dkT(".t2l.bz2"),
+
+/* 7 */
+dkT("/"),
+
+/* 8 */
+dkT("dk4uc2l.str"),
+
+NULL
+
+
+#line 327 "dk4uc2l.ctr"
+};
+
+
+
+/** Localized texts.
+*/
+static const dkChar * const dk4uc2l_kw_def[] = {
+/* 0 */
+dkT("Syntax error!\n\tHexadecimal number required at start of line!"),
+
+/* 1 */
+dkT("Syntax error!\n\tHexadecimal value outside allowed 32 bit range!"),
+
+/* 2 */
+dkT("Syntax error!\n\tRedefinition of "),
+
+/* 3 */
+dkT("!"),
+
+/* 4 */
+dkT("Syntax error! Redefintion of character!"),
+
+/* 5 */
+dkT("Failed to set up text processing!"),
+
+/* 6 */
+dkT("Failed to open file for reading:\n\t\""),
+
+/* 7 */
+dkT("\"!"),
+
+/* 8 */
+dkT("Syntax error!\n\tIllegal font encoding name!"),
+
+/* 9 */
+dkT("Syntax error!\n\t1 to 15 packages names are allowed!"),
+
+/* 10 */
+dkT("Syntax error!\n\tIllegal attribute name!"),
+
+/* 11 */
+dkT("Syntax error!\n\tAttribute specified without value!"),
+
+/* 12 */
+dkT("Conversion to UTF-8 failed for 0x"),
+
+/* 13 */
+dkT("!"),
+
+/* 14 */
+dkT("Conversion to UTF-8 failed for a character!"),
+
+/* 15 */
+dkT("No directory for character mapping information found!"),
+
+/* 16 */
+dkT("Decoding failed!\n\tByte:"),
+
+/* 17 */
+dkT("Encoding failed!\n\tByte:"),
+
+/* 18 */
+dkT("Processing failed!\n\tByte:"),
+
+/* 19 */
+dkT(",\n\tCharacter:"),
+
+/* 20 */
+dkT(",\n\tPosition in line:"),
+
+/* 21 */
+dkT("."),
+
+/* 22 */
+dkT("Decoding failed!"),
+
+/* 23 */
+dkT("Encoding failed!"),
+
+/* 24 */
+dkT("Processing failed!"),
+
+/* 25 */
+dkT("Further decoding failures!"),
+
+/* 26 */
+dkT("Further encoding failures!"),
+
+/* 27 */
+dkT("Further processing failures!"),
+
+NULL
+
+
+#line 403 "dk4uc2l.ctr"
+};
+
+
+
+static const char * const dk4uc2l_kw8[] = {
+/* 0 */
+"% Font encodings:",
+
+/* 1 */
+"% Recommended package: ",
+
+/* 2 */
+" ot1",
+
+/* 3 */
+" t1",
+
+/* 4 */
+" t4",
+
+/* 5 */
+" t5",
+
+NULL
+
+
+#line 428 "dk4uc2l.ctr"
+};
+
+
+/** Attribute names.
+*/
+static const char * const dk4uc2l_attribute_names[] = {
+/* 0 */
+"b$oth",
+
+/* 1 */
+"t$ext",
+
+/* 2 */
+"m$ath",
+
+/* 3 */
+"e$ncoding",
+
+/* 4 */
+"p$ackages",
+
+NULL
+
+
+#line 441 "dk4uc2l.ctr"
+};
+
+
+
+static const char * const dk4uc2l_font_encodings[] = {
+/* 0 */
+"ot1",
+
+/* 1 */
+"t1",
+
+/* 2 */
+"t4",
+
+/* 3 */
+"t5",
+
+NULL
+
+
+#line 452 "dk4uc2l.ctr"
+};
+
+
+
+/** Destroy LaTeX package structure, release memory.
+ @param pptr Package to destroy.
+*/
+static
+void
+dk4uc2l_pkg_close(dk4_uc2l_pkg_t *pptr)
+{
+
+
+#line 464 "dk4uc2l.ctr"
+ if (NULL != pptr) {
+ pptr->used = 0x00;
+ dk4mem_release(pptr->pn);
+ dk4mem_free(pptr);
+ }
+
+
+#line 470 "dk4uc2l.ctr"
+}
+
+
+
+/** Create LaTeX package structure, allocate memory.
+ @param pn Package name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new structure on success, NULL on error.
+*/
+static
+dk4_uc2l_pkg_t *
+dk4uc2l_pkg_open(const char *pn, dk4_app_t *app)
+{
+ dk4_uc2l_pkg_t *back = NULL;
+
+
+#line 485 "dk4uc2l.ctr"
+ if (NULL != pn) {
+ back = dk4mem_new_app(dk4_uc2l_pkg_t,1,app);
+ if (NULL != back) {
+ back->used = 0x00;
+ back->pn = dk4str8_dup(pn, NULL);
+ if (NULL == back->pn) {
+ dk4uc2l_pkg_close(back);
+ back = NULL;
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ }
+ }
+ }
+
+#line 497 "dk4uc2l.ctr"
+ return back;
+}
+
+
+
+/** Compare two LaTeX package structures.
+ @param l Left pointer, always a package structure.
+ @param r Right pointer.
+ @param cr Comparison criteria: 0 if r is a package pointer,
+ 1 if r is just a package name string.
+ @return Comparison result: 1 if l>r, 0 if l==r, -1 if l<r.
+*/
+static
+int
+dk4uc2l_pkg_compare(const void *l, const void *r, int cr)
+{
+
+ const dk4_uc2l_pkg_t *pl;
+ const dk4_uc2l_pkg_t *pr;
+ int back = 0;
+
+ if (NULL != l) {
+ if (NULL != r) {
+ pl = (const dk4_uc2l_pkg_t *)l;
+ switch (cr) {
+ case 1: {
+ back = strcmp(pl->pn, (const char *)r);
+ } break;
+ default: {
+ pr = (const dk4_uc2l_pkg_t *)r;
+ back = strcmp(pl->pn, pr->pn);
+ } break;
+ }
+ if (-1 > back) back = -1;
+ if ( 1 < back) back = 1;
+ } else { back = 1; }
+ } else {
+ if (NULL != r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+/** Destroy file information structure, release memory.
+ @param fptr File information structure to destroy.
+*/
+static
+void
+dk4uc2l_file_close(dk4_uc2l_file_t *fptr)
+{
+
+
+#line 549 "dk4uc2l.ctr"
+ if (NULL != fptr) {
+ fptr->loaded = 0x00;
+ dk4mem_release(fptr->fn);
+ dk4mem_free(fptr);
+ }
+
+#line 554 "dk4uc2l.ctr"
+}
+
+
+
+/** Create file information structure, allocate memory.
+ @param fn File name to create structure for.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new structure on success, NULL on error.
+*/
+static
+dk4_uc2l_file_t *
+dk4uc2l_file_open(const dkChar *fn, dk4_app_t *app)
+{
+ dk4_uc2l_file_t *back = NULL;
+
+
+#line 569 "dk4uc2l.ctr"
+ if (NULL != fn) {
+ back = dk4mem_new_app(dk4_uc2l_file_t,1,app);
+ if (NULL != back) {
+ back->loaded = 0x00;
+ back->fn = dk4str_dup(fn, NULL);
+ if (NULL == back->fn) {
+ dk4uc2l_file_close(back);
+ back = NULL;
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ }
+ }
+ }
+
+#line 581 "dk4uc2l.ctr"
+ return back;
+}
+
+
+
+/** Compare two file information structures.
+ @param l Left pointer, always a file information structure.
+ @param r Right pointer.
+ @param cr Comparison criteria:
+ 0 if the right pointer is a file information structure
+ pointer,
+ 1 if the right pointer is a file name string.
+ @return Comparison result: 0 if file names are equal, -1 if l<r,
+ 1 if l>r.
+*/
+static
+int
+dk4uc2l_file_compare(const void *l, const void *r, int cr)
+{
+ const dk4_uc2l_file_t *pl;
+ const dk4_uc2l_file_t *pr;
+ int back = 0;
+ if (NULL != l) {
+ if (NULL != r) {
+ pl = (const dk4_uc2l_file_t *)l;
+ switch (cr) {
+ case 1: {
+ back = dk4str_pathcmp(pl->fn, (const dkChar *)r);
+ } break;
+ default: {
+ pr = (const dk4_uc2l_file_t *)r;
+ back = dk4str_pathcmp(pl->fn, pr->fn);
+ } break;
+ }
+ if (-1 > back) { back = -1; }
+ if ( 1 < back) { back = 1; }
+ } else { back = 1; }
+ } else {
+ if (NULL != r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+/** Destroy range structure, release memory.
+ @param rptr Range structure to destroy.
+*/
+static
+void
+dk4uc2l_range_close(dk4_uc2l_range_t *rptr)
+{
+ dk4_er_t er;
+ size_t nelem;
+ size_t i;
+
+
+#line 637 "dk4uc2l.ctr"
+#if TRACE_DEBUG
+ if (NULL != rptr->file) {
+ if (NULL != (rptr->file)->fn) {
+
+
+#line 641 "dk4uc2l.ctr"
+ }
+ }
+#endif
+ if (NULL != rptr) {
+ /*
+ Overflow check when calculating number of elements in range
+ as end-start+1
+ */
+ dk4error_init(&er);
+ nelem = dk4ma_size_t_add(
+ dk4ma_size_t_sub((size_t)(rptr->end), (size_t)(rptr->start), &er),
+ (size_t)1U,
+ &er
+ );
+ if (DK4_E_NONE == er.ec) {
+ /*
+ Release dynamic memory.
+ */
+ if (NULL != rptr->both) {
+ for (i = 0; i < nelem; i++) { dk4mem_release((rptr->both)[i]); }
+ dk4mem_release(rptr->both);
+ }
+ if (NULL != rptr->text) {
+ for (i = 0; i < nelem; i++) { dk4mem_release((rptr->text)[i]); }
+ dk4mem_release(rptr->text);
+ }
+ if (NULL != rptr->math) {
+ for (i = 0; i < nelem; i++) { dk4mem_release((rptr->math)[i]); }
+ dk4mem_release(rptr->math);
+ }
+ if (NULL != rptr->pkgs) {
+ for (i = 0; i < nelem; i++) { dk4mem_release((rptr->pkgs)[i]); }
+ dk4mem_release(rptr->pkgs);
+ }
+ if (NULL != rptr->fenc) {
+ dk4mem_release(rptr->fenc);
+ }
+ }
+ rptr->file = NULL;
+ rptr->start = rptr->end = (dk4_c32_t)0UL;
+ rptr->ia = 0x00;
+ dk4mem_free(rptr);
+ }
+
+#line 684 "dk4uc2l.ctr"
+}
+
+
+
+/** Create range structure, partially allocate memory.
+ @param c Character, initially start and end of range.
+ @param fptr Pointer to exisiting file information structure.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new structure on success, NULL on error.
+*/
+static
+dk4_uc2l_range_t *
+dk4uc2l_range_open(dk4_c32_t c, dk4_uc2l_file_t *fptr, dk4_app_t *app)
+{
+ dk4_uc2l_range_t *back = NULL;
+
+
+#line 700 "dk4uc2l.ctr"
+ if (NULL != fptr) {
+ back = dk4mem_new_app(dk4_uc2l_range_t,1,app);
+ if (NULL != back) {
+ back->file = fptr;
+ back->both = NULL;
+ back->text = NULL;
+ back->math = NULL;
+ back->pkgs = NULL;
+ back->fenc = NULL;
+ back->start = back->end = c;
+ back->ia = 0x00;
+ }
+ }
+
+#line 713 "dk4uc2l.ctr"
+ return back;
+}
+
+
+
+/** Compare two range informations or a range information against a
+ character.
+ @param l Left pointer, always a range information strucutre.
+ @param r Right pointer.
+ @param cr Comparison criteria:
+ 0 if the right pointer is a range information strucutre,
+ 1 if the right pointer is a pointer to a dk4_c32_t.
+ @return Comparison result: -1 if l<r, 0 if l=r, 1 if l>r.
+*/
+static
+int
+dk4uc2l_range_compare(const void *l, const void *r, int cr)
+{
+ const dk4_uc2l_range_t *pl;
+ const dk4_uc2l_range_t *pr;
+ const dk4_c32_t *pc;
+ int back = 0;
+ if (NULL != l) {
+ if (NULL != r) {
+ pl = (const dk4_uc2l_range_t *)l;
+ switch (cr) {
+ case 1: {
+ pc = (const dk4_c32_t *)r;
+ if (pl->start > *pc) {
+ back = 1;
+ } else {
+ if (pl->end < *pc) {
+ back = -1;
+ }
+ }
+ } break;
+ default: {
+ pr = (const dk4_uc2l_range_t *)r;
+ if (pl->start < pr->start) {
+ back = -1;
+ } else {
+ if (pl->start > pr->start) {
+ back = 1;
+ }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if (NULL != r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+void
+dk4uc2l_close(dk4_uc2l_t *ulptr)
+{
+ dk4_uc2l_pkg_t *pptr;
+ dk4_uc2l_file_t *fptr;
+ dk4_uc2l_range_t *rptr;
+
+
+#line 776 "dk4uc2l.ctr"
+ if (NULL != ulptr) {
+ /*
+ Directory name.
+ */
+ dk4mem_release(ulptr->dname);
+ /*
+ Ranges.
+ */
+ if (NULL != ulptr->s_ranges) {
+ if (NULL != ulptr->i_ranges) {
+ dk4sto_it_reset(ulptr->i_ranges);
+ do {
+ rptr = (dk4_uc2l_range_t *)dk4sto_it_next(ulptr->i_ranges);
+ if (NULL != rptr) { dk4uc2l_range_close(rptr); }
+ } while (NULL != rptr);
+ dk4sto_it_close(ulptr->i_ranges);
+ }
+ dk4sto_close(ulptr->s_ranges);
+ }
+ /*
+ File information.
+ */
+ if (NULL != ulptr->s_files) {
+ if (NULL != ulptr->i_files) {
+ dk4sto_it_reset(ulptr->i_files);
+ do {
+ fptr = (dk4_uc2l_file_t *)dk4sto_it_next(ulptr->i_files);
+ if (NULL != fptr) { dk4uc2l_file_close(fptr); }
+ } while (NULL != fptr);
+ dk4sto_it_close(ulptr->i_files);
+ }
+ dk4sto_close(ulptr->s_files);
+ }
+ /*
+ Package information.
+ */
+ if (NULL != ulptr->s_pkgs) {
+ if (NULL != ulptr->i_pkgs) {
+ dk4sto_it_reset(ulptr->i_pkgs);
+ do {
+ pptr = (dk4_uc2l_pkg_t *)dk4sto_it_next(ulptr->i_pkgs);
+ if (NULL != pptr) { dk4uc2l_pkg_close(pptr); }
+ } while (NULL != pptr);
+ dk4sto_it_close(ulptr->i_pkgs);
+ }
+ dk4sto_close(ulptr->s_pkgs);
+ }
+ ulptr->s_ranges = NULL;
+ ulptr->i_ranges = NULL;
+ ulptr->s_files = NULL;
+ ulptr->i_files = NULL;
+ ulptr->s_pkgs = NULL;
+ ulptr->i_pkgs = NULL;
+ ulptr->msgs = NULL;
+ ulptr->szmsgs = 0;
+ dk4mem_free(ulptr);
+ }
+
+#line 833 "dk4uc2l.ctr"
+}
+
+
+
+static
+dk4_uc2l_t *
+dk4uc2l_create(const dkChar *dn, dk4_app_t *app)
+{
+ dk4_uc2l_t *back = NULL;
+ int ok = 0;
+
+
+#line 844 "dk4uc2l.ctr"
+ if (NULL != dn) {
+ back = dk4mem_new_app(dk4_uc2l_t,1,app);
+ if (NULL != back) {
+ back->dname = NULL;
+ back->s_ranges = NULL;
+ back->i_ranges = NULL;
+ back->s_files = NULL;
+ back->i_files = NULL;
+ back->s_pkgs = NULL;
+ back->i_pkgs = NULL;
+ back->fallowed = 0xFF;
+ back->utf8allowed = 0x00;
+ back->had_error = 0;
+ back->msgs = NULL;
+ back->szmsgs = 0;
+ back->dname = dk4str_dup(dn, NULL);
+ if (NULL != back->dname) {
+ back->s_ranges = dk4sto_open(NULL);
+ if (NULL != back->s_ranges) {
+ dk4sto_set_comp(back->s_ranges, dk4uc2l_range_compare, 0);
+ back->s_files = dk4sto_open(NULL);
+ if (NULL != back->s_files) {
+ dk4sto_set_comp(back->s_files, dk4uc2l_file_compare, 0);
+ back->s_pkgs = dk4sto_open(NULL);
+ if (NULL != back->s_pkgs) {
+ dk4sto_set_comp(back->s_pkgs, dk4uc2l_pkg_compare, 0);
+ back->i_ranges = dk4sto_it_open(back->s_ranges, NULL);
+ if (NULL != back->i_ranges) {
+ back->i_files = dk4sto_it_open(back->s_files, NULL);
+ if (NULL != back->i_files) {
+ back->i_pkgs = dk4sto_it_open(back->s_pkgs, NULL);
+ if (NULL != back->i_pkgs) {
+ if (NULL != app) {
+ back->msgs = dk4app_string_table(
+ app, dk4uc2l_kwnl[8], dk4uc2l_kw_def
+ );
+ } else {
+ back->msgs = dk4uc2l_kw_def;
+ }
+ back->szmsgs = dk4app_string_table_size(dk4uc2l_kw_def);
+ ok = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if (0 == ok) {
+ dk4uc2l_close(back);
+ back = NULL;
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ }
+ }
+ }
+
+#line 900 "dk4uc2l.ctr"
+ return back;
+}
+
+
+
+/** Handler function for text lines.
+ @param obj Object to modify while processing the character.
+ @param line Text line to process.
+ @param lineno Current line number.
+ @param erp Error report, may be NULL.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+dk4uc2l_fp_handler(
+ void *obj,
+ char *line,
+ dk4_um_t lineno,
+ dk4_er_t *erp
+)
+{
+ dkChar numbuf[16*sizeof(dk4_um_t)];
+ dk4_uc2l_range_t *rptr;
+ dk4_uc2l_range_t *rptrn;
+ dk4_uc2l_file_t *fptr;
+ dk4_uc2l_lhobj *lhobj;
+ dk4_app_t *app;
+ dk4_uc2l_t *ulptr;
+ char *p1;
+#if VERSION_BEFORE_20150821
+ char *p2;
+#endif
+ const char *p3;
+ dk4_um_t um;
+ dk4_c32_t c32;
+ dk4_c32_t c32a;
+ size_t sznumbuf;
+ int back = DK4_TSP_RES_OK;
+ int res = 0;
+
+
+#line 945 "dk4uc2l.ctr"
+
+ /* Obtain contents from object.
+ */
+ lhobj = (dk4_uc2l_lhobj *)obj;
+ ulptr = lhobj->ulptr;
+ app = lhobj->app;
+ dk4app_set_log_source_line(app, lineno);
+
+ /* Check for any text. Empty lines ok, comments ok.
+ */
+ p1 = dk4str8_start(line, NULL);
+ if (NULL == p1) {
+
+#line 957 "dk4uc2l.ctr"
+ goto finished;
+ }
+ if ('#' == *p1) {
+
+#line 960 "dk4uc2l.ctr"
+ goto finished;
+ }
+
+ /* Retrieve hexadecimal number.
+ */
+#if VERSION_BEFORE_20150821
+ p2 = dk4str8_next(p1, NULL);
+#else
+ (void)dk4str8_next(p1, NULL);
+#endif
+ um = (dk4_um_t)0UL;
+#if VERSION_BEFORE_20150821
+ p2 = NULL;
+#endif
+ p3 = NULL;
+ res = dk4ma_input_c8_hex_dk4_um_t(&um, p1, &p3, 1, NULL);
+ if (0 == res) {
+
+#line 977 "dk4uc2l.ctr"
+ back = DK4_TSP_RES_ERROR;
+ /* ERROR: Syntax, not a number */
+ dk4app_log_1(app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 0);
+ ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX;
+ goto finished;
+ }
+
+#line 983 "dk4uc2l.ctr"
+ c32 = (dk4_c32_t)um;
+
+#line 984 "dk4uc2l.ctr"
+
+ /* Check numeric range.
+ */
+ if ((dk4_um_t)0xFFFFFFFFUL < um) {
+
+#line 988 "dk4uc2l.ctr"
+ back = DK4_TSP_RES_ERROR;
+ /* ERROR: Syntax, out of range */
+ dk4app_log_1(app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 1);
+ ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX;
+ goto finished;
+ }
+
+ /* Check whether number is already contained in a range.
+ */
+ rptr = (dk4_uc2l_range_t *)dk4sto_it_find_like(lhobj->i_r, &c32, 1);
+ if (NULL != rptr) {
+
+#line 999 "dk4uc2l.ctr"
+
+
+#line 1000 "dk4uc2l.ctr"
+ back = DK4_TSP_RES_ERROR;
+ /* ERROR: Already defined */
+ sznumbuf = DK4_SIZEOF(numbuf,dkChar);
+ if (0 != dk4ma_write_hex_unsigned(numbuf,sznumbuf,(dk4_um_t)c32,8,NULL)) {
+ dk4app_log_3(app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 2, 3, numbuf);
+ } else {
+ dk4app_log_1(app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 4);
+ }
+ ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX;
+ goto finished;
+ }
+ rptr = (dk4_uc2l_range_t *)dk4sto_it_find_like(ulptr->i_ranges, &c32, 1);
+ if (NULL != rptr) {
+
+#line 1013 "dk4uc2l.ctr"
+ back = DK4_TSP_RES_ERROR;
+ /* ERROR: Already defined */
+ sznumbuf = DK4_SIZEOF(numbuf,dkChar);
+ if (0 != dk4ma_write_hex_unsigned(numbuf,sznumbuf,(dk4_um_t)c32,8,NULL)) {
+ dk4app_log_3(app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 2, 3, numbuf);
+ } else {
+ dk4app_log_1(app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 4);
+ }
+ ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX;
+ goto finished;
+ }
+
+ /* Check whether we can append to an existing range.
+ */
+ if (dkC32(0) < c32) {
+ c32a = c32 - dkC32(1);
+ rptr = (dk4_uc2l_range_t *)dk4sto_it_find_like(lhobj->i_r, &c32a, 1);
+ if (NULL != rptr) {
+ rptr->end = c32;
+
+#line 1032 "dk4uc2l.ctr"
+ /* Also check if c32 closes a gap between two ranges.
+ */
+ if (dkC32(0xFFFFFFFF) > c32) {
+ c32a = c32 + dkC32(1);
+ rptrn = (dk4_uc2l_range_t *)dk4sto_it_find_like(lhobj->i_r, &c32a, 1);
+ if (NULL != rptrn) {
+
+#line 1038 "dk4uc2l.ctr"
+ c32a = rptrn->end;
+ dk4sto_remove(lhobj->s_r, rptrn, NULL);
+ rptr->end = c32a;
+ }
+ }
+ goto finished;
+ }
+ }
+
+ /* Check whether we can prepend before an existing range.
+ */
+ if (dkC32(0xFFFFFFFF) > c32) {
+ c32a = c32 + dkC32(1);
+ rptr = (dk4_uc2l_range_t *)dk4sto_it_find_like(lhobj->i_r, &c32a, 1);
+ if (NULL != rptr) {
+
+#line 1053 "dk4uc2l.ctr"
+ rptr->start = c32;
+ goto finished;
+ }
+ }
+
+ /* Create a new range.
+ */
+
+#line 1060 "dk4uc2l.ctr"
+ fptr = (dk4_uc2l_file_t *)dk4sto_it_find_like(ulptr->i_files, lhobj->sfn, 1);
+ if (NULL == fptr) {
+ fptr = dk4uc2l_file_open(lhobj->sfn, app);
+ if (NULL != fptr) {
+ if (0 == dk4sto_add(ulptr->s_files, fptr, NULL)) {
+ dk4uc2l_file_close(fptr);
+
+#line 1066 "dk4uc2l.ctr"
+ fptr = NULL;
+ }
+ }
+ }
+ if (NULL == fptr) {
+
+#line 1071 "dk4uc2l.ctr"
+ back = DK4_TSP_RES_ERROR;
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ ulptr->had_error |= DK4_UC2L_ERROR_MEMORY;
+ goto finished;
+ }
+ rptr = dk4uc2l_range_open(c32, fptr, app);
+ if (NULL != rptr) {
+ if (0 == dk4sto_add(lhobj->s_r, rptr, NULL)) {
+ dk4uc2l_range_close(rptr);
+
+#line 1081 "dk4uc2l.ctr"
+ rptr = NULL;
+ back = DK4_TSP_RES_ERROR;
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ }
+ } else {
+
+#line 1087 "dk4uc2l.ctr"
+ back = DK4_TSP_RES_ERROR;
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ ulptr->had_error |= DK4_UC2L_ERROR_MEMORY;
+ }
+
+#line 1092 "dk4uc2l.ctr"
+
+ finished:
+
+
+#line 1095 "dk4uc2l.ctr"
+ return back;
+}
+
+
+
+/** Report an error with position in source line.
+ @param ulptr Conversion structure.
+ @param i1 Index of first message part in array.
+ @param i2 Index of alternative first message part.
+ @param bno Byte processed.
+ @param lno Current line number.
+ @param cno Current character number.
+ @param cil Current character number in line.
+*/
+static
+void
+dk4uc2l_report_with_pos(
+ dk4_uc2l_t *ulptr,
+ dk4_app_t *app,
+ size_t i1,
+ size_t i2,
+ dk4_um_t bno,
+ dk4_um_t lno,
+ dk4_um_t cno,
+ dk4_um_t cil
+)
+{
+ dkChar b1[8*(1+sizeof(dk4_um_t))];
+ dkChar b2[8*(1+sizeof(dk4_um_t))];
+ dkChar b3[8*(1+sizeof(dk4_um_t))];
+ dk4_um_t oldlogline = (dk4_um_t)0UL;
+ int allbuffersok = 0;
+
+ oldlogline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_line(app, lno);
+ if (0 != dk4ma_write_decimal_unsigned(b3,DK4_SIZEOF(b3,dkChar),cil,0,NULL)) {
+ if (0 != dk4ma_write_decimal_unsigned(b2,DK4_SIZEOF(b2,dkChar),cno,0,NULL)) {
+ if (0 != dk4ma_write_decimal_unsigned(b1,DK4_SIZEOF(b1,dkChar),bno,0,NULL)) {
+ allbuffersok = 1;
+ }
+ }
+ }
+ if (0 != allbuffersok) {
+ dk4app_log_7(
+ app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, i1, 19, 20, 21, b1, b2, b3
+ );
+ } else {
+ dk4app_log_1(
+ app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, i2
+ );
+ }
+ dk4app_set_log_source_line(app, oldlogline);
+}
+
+
+
+static
+void
+dk4uc2l_report_errors(
+ dk4_uc2l_t *ulptr,
+ dk4_app_t *app,
+ dk4_uc2l_lhobj *obj,
+ dk4_er_t *er_en,
+ dk4_er_t *er_pr
+)
+{
+ if (NULL != er_en) {
+ switch (er_en->ec) {
+ case DK4_E_DECODING_FAILED: {
+ switch (obj->e_d) {
+ case 0: case 1: {
+ dk4uc2l_report_with_pos(
+ ulptr, app, 16, 22,
+ er_en->dt.fpos.byteno,
+ er_en->dt.fpos.lineno,
+ er_en->dt.fpos.charno,
+ er_en->dt.fpos.charinline
+ );
+ } break;
+ case 2: {
+ dk4app_log_1(
+ app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 25
+ );
+ } break;
+ }
+ if (3 > obj->e_d) { obj->e_d += 1; }
+ } break;
+ case DK4_E_ENCODING_FAILED: {
+ switch (obj->e_e) {
+ case 0: case 1: {
+ dk4uc2l_report_with_pos(
+ ulptr, app, 17, 23,
+ er_en->dt.fpos.byteno,
+ er_en->dt.fpos.lineno,
+ er_en->dt.fpos.charno,
+ er_en->dt.fpos.charinline
+ );
+ } break;
+ case 2: {
+ dk4app_log_1(
+ app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 26
+ );
+ } break;
+ }
+ if (3 > obj->e_e) { obj->e_e += 1; }
+ } break;
+ }
+ }
+ if (NULL != er_pr) {
+ if (DK4_E_NONE != er_pr->ec) {
+ switch (obj->e_p) {
+ case 0: case 1: {
+ dk4uc2l_report_with_pos(
+ ulptr, app, 18, 24,
+ er_pr->dt.fpos.byteno,
+ er_pr->dt.fpos.lineno,
+ er_pr->dt.fpos.charno,
+ er_pr->dt.fpos.charinline
+ );
+ } break;
+ case 2: {
+ dk4app_log_1(
+ app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 27
+ );
+ } break;
+ }
+ if (3 > obj->e_p) { obj->e_p += 1; }
+ }
+ }
+}
+
+
+
+/** Process data from a stream.
+ @param ulptr Conversion structure.
+ @param rstrm Stream to read data from.
+ @param sfn Short file name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4uc2l_fp_process_stream(
+ dk4_uc2l_t *ulptr,
+ dk4_stream_t *rstrm,
+ const dkChar *sfn,
+ dk4_app_t *app
+)
+{
+ char buf[256]; /* Line buffer */
+ dk4_tsp08_t tsp08; /* Text stream processor */
+ dk4_er_t er; /* General error report */
+ dk4_er_t er_en; /* Error report for decoding/encoding */
+ dk4_er_t er_pr; /* Error report for processing */
+ dk4_uc2l_lhobj obj; /* Processing object */
+ dk4_uc2l_range_t *rptr; /* Range to append to */
+ int back = 1;
+ int res; /* Line processing result */
+ int cc; /* Flag: Can continue */
+ char c; /* Current character */
+
+
+#line 1256 "dk4uc2l.ctr"
+ dk4error_init(&er);
+ dk4error_init(&er_en);
+ dk4error_init(&er_pr);
+ obj.ulptr = ulptr;
+ obj.app = app;
+ obj.sfn = sfn;
+ obj.e_d = 0;
+ obj.e_e = 0;
+ obj.e_p = 0;
+ obj.s_r = dk4sto_open(NULL);
+ if (NULL != obj.s_r) {
+ dk4sto_set_comp(obj.s_r, dk4uc2l_range_compare, 0);
+ obj.i_r = dk4sto_it_open(obj.s_r, NULL);
+ if (NULL != obj.i_r) {
+ res = dk4tsp08_setup_line(
+ &tsp08, (void *)(&obj), dk4uc2l_fp_handler, buf, sizeof(buf),
+ DK4_ENCODING_ASCII, DK4_ENCODING_ASCII, &er
+ );
+ if (0 != res) {
+ cc = 1;
+ while (1 == cc) {
+ res = dk4stream_c8_read_byte(&c, rstrm, &er);
+ if (0 != res) {
+ res = dk4tsp08_add_one_byte(&tsp08, (unsigned char)c);
+ switch (res) {
+ case DK4_TSP_RES_ERROR: {
+ back = 0;
+ dk4tsp08_get_errors(&er_en, &er_pr, &tsp08);
+ /* Report errors */
+ dk4uc2l_report_errors(ulptr, app, &obj, &er_en, &er_pr);
+ dk4error_init(&er_en);
+ dk4error_init(&er_pr);
+ ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING;
+ } break;
+ case DK4_TSP_RES_FATAL: {
+ back = 0;
+ cc = -1;
+ dk4tsp08_get_errors(&er_en, &er_pr, &tsp08);
+ /* Report errors */
+ dk4uc2l_report_errors(ulptr, app, &obj, &er_en, &er_pr);
+ dk4error_init(&er_en);
+ dk4error_init(&er_pr);
+ ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING;
+ } break;
+ }
+ } else {
+ cc = 0;
+ }
+ }
+ if (0 == cc) {
+ res = dk4tsp08_finish(&tsp08);
+ switch (res) {
+ case DK4_TSP_RES_ERROR: case DK4_TSP_RES_FATAL: {
+ back = 0;
+ dk4tsp08_get_errors(&er_en, &er_pr, &tsp08);
+ /* Report errors */
+ dk4uc2l_report_errors(ulptr, app, &obj, &er_en, &er_pr);
+ ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING;
+ } break;
+ }
+ }
+ } else {
+ /* ERROR: Failed to set up text processing */
+ dk4app_log_1(app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 5);
+ ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING;
+ }
+ /*
+ Move range descriptions from local storage to global storage.
+ */
+ dk4sto_it_reset(obj.i_r);
+ do {
+ rptr = (dk4_uc2l_range_t *)dk4sto_it_next(obj.i_r);
+ if (NULL != rptr) {
+ if (0 == dk4sto_add(ulptr->s_ranges, rptr, NULL)) {
+ back = 0;
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ dk4uc2l_range_close(rptr);
+ }
+ }
+ } while (NULL != rptr);
+ dk4sto_it_close(obj.i_r);
+ } else {
+ back = 0;
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ ulptr->had_error |= DK4_UC2L_ERROR_MEMORY;
+ }
+ dk4sto_close(obj.s_r);
+ obj.s_r = NULL;
+ } else {
+ back = 0;
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ ulptr->had_error |= DK4_UC2L_ERROR_MEMORY;
+ }
+
+
+
+#line 1354 "dk4uc2l.ctr"
+ return back;
+}
+
+
+
+/** Process one data file in the first pass.
+ @param ulptr Conversion structure.
+ @param fn Full file name.
+ @param sfn Short file name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4uc2l_fp_process_file_name(
+ dk4_uc2l_t *ulptr,
+ const dkChar *fn,
+ const dkChar *sfn,
+ dk4_app_t *app
+)
+{
+ dk4_er_t er; /* Error report */
+ dk4_stream_t *rstrm; /* Stream to read file */
+ const dkChar *oldsourcefile; /* Previous source file */
+ dk4_um_t oldsourceline; /* Previous source line */
+ size_t fnl; /* File name length */
+ size_t fns; /* Suffix length */
+ size_t i; /* Traverse suffix list */
+ int back = 1;
+ int done = 0; /* Flag: Attempted to open file */
+
+
+#line 1385 "dk4uc2l.ctr"
+ fnl = dk4str_len(fn);
+ for (i = 4; ((i < 7) && (0 == done)); i++) {
+
+#line 1387 "dk4uc2l.ctr"
+ fns = dk4str_len(dk4uc2l_kwnl[i]);
+ if (fnl > fns) {
+
+#line 1389 "dk4uc2l.ctr"
+ if (0 == dk4str_pathcmp(&(fn[fnl - fns]), dk4uc2l_kwnl[i])) {
+ done = 1;
+
+#line 1391 "dk4uc2l.ctr"
+ dk4error_init(&er);
+ rstrm = dk4stream_open_file_reader(fn, &er);
+ if (NULL != rstrm) {
+
+#line 1394 "dk4uc2l.ctr"
+ oldsourcefile = dk4app_get_log_source_file(app);
+ oldsourceline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_file(app, fn);
+ dk4app_set_log_source_line(app, (dk4_um_t)0UL);
+ back = dk4uc2l_fp_process_stream(ulptr, rstrm, sfn, app);
+ dk4app_set_log_source_file(app, oldsourcefile);
+ dk4app_set_log_source_line(app, oldsourceline);
+ dk4stream_close(rstrm, NULL);
+ } else {
+
+#line 1403 "dk4uc2l.ctr"
+ back = 0;
+ /* ERROR: Failed to open file */
+ dk4app_log_3(app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 6, 7, fn);
+ ulptr->had_error |= DK4_UC2L_ERROR_FOPEN;
+ }
+ } else {
+
+#line 1409 "dk4uc2l.ctr"
+ }
+ } else {
+
+#line 1411 "dk4uc2l.ctr"
+ }
+ }
+
+
+#line 1414 "dk4uc2l.ctr"
+ return back;
+}
+
+
+
+/** First pass to fill information to the structure,
+ obtain information which character is handled by which file.
+ @param ulptr New structure to fill with data.
+ @param app Application structure for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4uc2l_first_pass(dk4_uc2l_t *ulptr, dk4_app_t *app)
+{
+ dkChar fnb[DK4_MAX_PATH]; /* File name buffer */
+ const dkChar *pth = NULL; /* Path for directory */
+ const dkChar *fn = NULL; /* Current file to process */
+ dk4_dir_t *dir = NULL; /* Traverse the directory */
+ int back = 0;
+
+
+#line 1435 "dk4uc2l.ctr"
+ dir = dk4dir_open_app(ulptr->dname, 0, app);
+ if (NULL != dir) {
+ back = 1;
+ do {
+ fn = dk4dir_next_file(dir);
+ if (NULL != fn) {
+ pth = dk4dir_get_path(dir);
+ if (NULL != pth) {
+ if (dk4str_cpy_s(fnb,DK4_SIZEOF(fnb,dkChar),pth,NULL)) {
+ if (dk4str_cat_s(fnb,DK4_SIZEOF(fnb,dkChar),dk4uc2l_kwnl[7],NULL)) {
+ if (dk4str_cat_s(fnb,DK4_SIZEOF(fnb,dkChar),fn,NULL)) {
+ dk4path_correct_sep(fnb);
+ if (0 == dk4uc2l_fp_process_file_name(ulptr, fnb, fn, app)) {
+ back = 0;
+ }
+ } else {
+ back = 0;
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING;
+ }
+ } else {
+ back = 0;
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING;
+ }
+ } else {
+ back = 0;
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING;
+ }
+ } else {
+ if (0 == dk4uc2l_fp_process_file_name(ulptr, fn, fn, app)) {
+ back = 0;
+ }
+ }
+ }
+ } while (NULL != fn);
+ dk4dir_close(dir);
+ } else {
+ /* ERROR: Failed to open directory */
+ ulptr->had_error |= DK4_UC2L_ERROR_FOPEN;
+ }
+
+#line 1480 "dk4uc2l.ctr"
+ return back;
+}
+
+
+
+static
+void
+dk4uc2l_initialize_range(
+ dk4_uc2l_t *ulptr,
+ dk4_uc2l_range_t *rptr,
+ dk4_app_t *app
+)
+{
+ dk4_er_t er;
+ size_t nelem;
+ size_t i;
+ int errmem;
+ dk4error_init(&er);
+ nelem = dk4ma_size_t_add(
+ dk4ma_size_t_sub((size_t)(rptr->end), (size_t)(rptr->start), &er),
+ (size_t)1U,
+ &er
+ );
+ if (DK4_E_NONE == er.ec) {
+ errmem = 0;
+ rptr->both = dk4mem_new_app(dk4_uc2l_char_ptr,nelem,app);
+ if (NULL != rptr->both) {
+ for (i = 0; i < nelem; i++) { (rptr->both)[i] = NULL; }
+ } else { errmem = 1; }
+ rptr->text = dk4mem_new_app(dk4_uc2l_char_ptr,nelem,app);
+ if (NULL != rptr->text) {
+ for (i = 0; i < nelem; i++) { (rptr->text)[i] = NULL; }
+ } else { errmem = 1; }
+ rptr->math = dk4mem_new_app(dk4_uc2l_char_ptr,nelem,app);
+ if (NULL != rptr->math) {
+ for (i = 0; i < nelem; i++) { (rptr->math)[i] = NULL; }
+ } else { errmem = 1; }
+ rptr->pkgs = dk4mem_new_app(dk4_uc2l_pkg_ptr_ptr, nelem, app);
+ if (NULL != rptr->pkgs) {
+ for (i = 0; i < nelem; i++) { (rptr->pkgs)[i] = NULL; }
+ } else { errmem = 1; }
+ rptr->fenc = dk4mem_new_app(unsigned char,nelem,app);
+ if (NULL != rptr->fenc) {
+ for (i = 0; i < nelem; i++) {
+ (rptr->fenc)[i] = (unsigned char)DK4_UC2L_FONT_ENCODING_ALL;
+ }
+ } else { errmem = 1; }
+ if (0 != errmem) {
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ ulptr->had_error |= DK4_UC2L_ERROR_MEMORY;
+ }
+ }
+}
+
+
+
+/** Handler function for text lines.
+ @param obj Object to modify while processing the character.
+ @param line Text line to process.
+ @param lineno Current line number.
+ @param erp Error report, may be NULL.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+dk4uc2l_sp_handler(
+ void *obj,
+ char *line,
+ dk4_um_t lineno,
+ dk4_er_t *erp
+)
+{
+ dkChar numbuf[16*sizeof(dk4_um_t)];
+ dk4_er_t er; /* Error report */
+ dk4_uc2l_lhobj *lhobj; /* Handler object */
+ dk4_app_t *app; /* Application */
+ dk4_uc2l_range_t *rptr; /* Current range to modify */
+ dk4_uc2l_pkg_t *pkgptr; /* Current package to create */
+ dk4_uc2l_t *ulptr; /* Conversion structure */
+ char *pkgn[16]; /* Package names */
+ char *p1; /* Attribute name */
+ char *p2; /* Next attribute to process */
+ char *p4; /* Value, current value part */
+ char *p5; /* Next value part */
+ const char *pe; /* End of text when reading number */
+ dk4_um_t um; /* Number read at start of line */
+ size_t sznumbuf; /* Buffer size */
+ size_t ind; /* Index of current char in range */
+ size_t numpkg; /* Number of package names found */
+ size_t i; /* Current package index */
+ dk4_c32_t c32; /* Current character to configure */
+ int numres; /* Number conversion result */
+ int encadd; /* Flag: Add font encodings */
+ int res; /* Operation result */
+ int back = DK4_TSP_RES_OK;
+
+
+#line 1582 "dk4uc2l.ctr"
+ /*
+ Set variables.
+ */
+ lhobj = (dk4_uc2l_lhobj *)obj;
+ ulptr = lhobj->ulptr;
+ app = lhobj->app;
+ dk4app_set_log_source_line(app, lineno);
+
+ /*
+ Skip empty lines and comments.
+ */
+ p1 = dk4str8_start(line, NULL);
+ if (NULL == p1) {
+ goto finished;
+ }
+ if ('#' == *p1) {
+ goto finished;
+ }
+ p2 = dk4str8_next(p1, NULL);
+
+ /*
+ Retrieve character number.
+ */
+ um = (dk4_um_t)0UL;
+ pe = NULL;
+ res = dk4ma_input_c8_hex_dk4_um_t(&um, p1, &pe, 1, NULL);
+ if (0 == res) {
+ back = DK4_TSP_RES_ERROR;
+ /* ERROR: Syntax, not a number, already reported in first pass. */
+ ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX;
+ goto finished;
+ }
+ c32 = (dk4_c32_t)um;
+ if ((dk4_um_t)0xFFFFFFFFUL < um) {
+ back = DK4_TSP_RES_ERROR;
+ /* ERROR: Syntax, out of range, already reported in first pass. */
+ ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX;
+ goto finished;
+ }
+
+ /*
+ Find range.
+ */
+ rptr = (dk4_uc2l_range_t *)dk4sto_it_find_like(ulptr->i_ranges, &c32, 1);
+ if (NULL == rptr) {
+ back = DK4_TSP_RES_ERROR;
+ /* ERROR: Bug, range not found, must be memory problem reported in pass 1 */
+ ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING;
+ goto finished;
+ }
+
+ /*
+ Initialize range if not yet done.
+ */
+ if (0x00 == rptr->ia) {
+ rptr->ia = 0x01;
+ dk4uc2l_initialize_range(ulptr, rptr, app);
+ }
+
+ ind = (size_t)(c32 - rptr->start);
+ p1 = p2;
+ while (NULL != p1) {
+ p2 = dk4str8_next(p1, NULL);
+ p4 = dk4str8_chr(p1, '=');
+ if (NULL != p4) {
+ *(p4++) = '\0';
+ p4 = dk4str8_start(p4, NULL);
+ if (NULL != p4) {
+ switch (dk4str8_abbr_index(dk4uc2l_attribute_names, '$', p1, 0)) {
+ case 0: { /* both */
+ if (NULL != rptr->both) {
+ if (NULL == (rptr->both)[ind]) {
+ (rptr->both)[ind] = dk4str8_dup(p4, NULL);
+ if (NULL == (rptr->both)[ind]) {
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ ulptr->had_error |= DK4_UC2L_ERROR_MEMORY;
+ }
+ } else {
+ /* ERROR: Already defined, reported in first pass */
+ sznumbuf = DK4_SIZEOF(numbuf,dkChar);
+ numres = dk4ma_write_hex_unsigned(
+ numbuf, sznumbuf, (dk4_um_t)c32, 8, NULL
+ );
+ if (0 != numres) {
+ dk4app_log_3(
+ app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 2, 3, numbuf
+ );
+ } else {
+ dk4app_log_1(app,ulptr->msgs,ulptr->szmsgs,DK4_LL_ERROR,4);
+ }
+ ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX;
+ }
+ } else {
+ /* ERROR */
+ ulptr->had_error |= DK4_UC2L_ERROR_MEMORY;
+ }
+ } break;
+ case 1: { /* text */
+ if (NULL != rptr->text) {
+ if (NULL == (rptr->text)[ind]) {
+ (rptr->text)[ind] = dk4str8_dup(p4, NULL);
+ if (NULL == (rptr->text)[ind]) {
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ ulptr->had_error |= DK4_UC2L_ERROR_MEMORY;
+ }
+ } else {
+ /* ERROR: Already defined, reported in first pass */
+ sznumbuf = DK4_SIZEOF(numbuf,dkChar);
+ numres = dk4ma_write_hex_unsigned(
+ numbuf, sznumbuf, (dk4_um_t)c32, 8, NULL
+ );
+ if (0 != numres) {
+ dk4app_log_3(
+ app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 2, 3, numbuf
+ );
+ } else {
+ dk4app_log_1(app,ulptr->msgs,ulptr->szmsgs,DK4_LL_ERROR,4);
+ }
+ ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX;
+ }
+ } else {
+ /* ERROR */
+ ulptr->had_error |= DK4_UC2L_ERROR_MEMORY;
+ }
+ } break;
+ case 2: { /* math */
+ if (NULL != rptr->math) {
+ if (NULL == (rptr->math)[ind]) {
+ (rptr->math)[ind] = dk4str8_dup(p4, NULL);
+ if (NULL == (rptr->math)[ind]) {
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ ulptr->had_error |= DK4_UC2L_ERROR_MEMORY;
+ }
+ } else {
+ /* ERROR: Already defined */
+ sznumbuf = DK4_SIZEOF(numbuf,dkChar);
+ numres = dk4ma_write_hex_unsigned(
+ numbuf, sznumbuf, (dk4_um_t)c32, 8, NULL
+ );
+ if (0 != numres) {
+ dk4app_log_3(
+ app, ulptr->msgs,ulptr->szmsgs, DK4_LL_ERROR, 2, 3, numbuf
+ );
+ } else {
+ dk4app_log_1(app,ulptr->msgs,ulptr->szmsgs,DK4_LL_ERROR,4);
+ }
+ ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX;
+ }
+ } else {
+ /* ERROR */
+ ulptr->had_error |= DK4_UC2L_ERROR_MEMORY;
+ }
+ } break;
+ case 3: { /* encoding */
+ encadd = 1;
+ if (NULL != rptr->fenc) {
+ if ('!' == *p4) {
+ p4++;
+ encadd = 0;
+ (rptr->fenc)[ind] = (unsigned char)DK4_UC2L_FONT_ENCODING_ALL;
+ } else {
+ (rptr->fenc)[ind] = 0x00;
+ }
+ while (NULL != p4) {
+ p5 = dk4str8_chr(p4, ',');
+ if (NULL != p5) { *(p5++) = '\0'; }
+ switch (dk4str8_array_index(dk4uc2l_font_encodings, p4, 0)) {
+ case 0: { /* OT1 */
+ if (0 != encadd) {
+ (rptr->fenc)[ind] |=
+ (unsigned char)DK4_UC2L_FONT_ENCODING_OT1;
+ } else {
+ (rptr->fenc)[ind] &=
+ (~((unsigned char)DK4_UC2L_FONT_ENCODING_OT1));
+ }
+ } break;
+ case 1: { /* T1 */
+ if (0 != encadd) {
+ (rptr->fenc)[ind] |=
+ (unsigned char)DK4_UC2L_FONT_ENCODING_T1;
+ } else {
+ (rptr->fenc)[ind] &=
+ (~((unsigned char)DK4_UC2L_FONT_ENCODING_T1));
+ }
+ } break;
+ case 2: { /* T4 */
+ if (0 != encadd) {
+ (rptr->fenc)[ind] |=
+ (unsigned char)DK4_UC2L_FONT_ENCODING_T4;
+ } else {
+ (rptr->fenc)[ind] &=
+ (~((unsigned char)DK4_UC2L_FONT_ENCODING_T4));
+ }
+ } break;
+ case 3: { /* T5 */
+ if (0 != encadd) {
+ (rptr->fenc)[ind] |=
+ (unsigned char)DK4_UC2L_FONT_ENCODING_T5;
+ } else {
+ (rptr->fenc)[ind] &=
+ (~((unsigned char)DK4_UC2L_FONT_ENCODING_T5));
+ }
+ } break;
+ default : {
+ /* ERROR: Syntax, undefined encoding */
+ dk4app_log_1(app,ulptr->msgs,ulptr->szmsgs,DK4_LL_ERROR,8);
+ ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX;
+ } break;
+ }
+ p4 = p5;
+ }
+ } else {
+ /* ERROR */
+ }
+ } break;
+ case 4: { /* packages */
+ dk4error_init(&er);
+ numpkg = dk4str8_tokenize(pkgn, 16, p4, ",", &er);
+ if (0 < numpkg) {
+ if (NULL != rptr->pkgs) {
+ if (NULL == (rptr->pkgs)[ind]) {
+ (rptr->pkgs)[ind] =
+ dk4mem_new_app(dk4_uc2l_pkg_ptr,(numpkg+1),app);
+ if (NULL != (rptr->pkgs)[ind]) {
+ for (i = 0; i <= numpkg; i++) {
+ ((rptr->pkgs)[ind])[i] = NULL;
+ }
+ for (i = 0; i < numpkg; i++) {
+ pkgptr = (dk4_uc2l_pkg_t *)dk4sto_it_find_like(
+ ulptr->i_pkgs, pkgn[i], 1
+ );
+ if (NULL != pkgptr) {
+ ((rptr->pkgs)[ind])[i] = pkgptr;
+ } else {
+ pkgptr = dk4uc2l_pkg_open(pkgn[i], app);
+ if (NULL != pkgptr) {
+ if (0 == dk4sto_add(ulptr->s_pkgs, pkgptr, NULL)) {
+ dk4uc2l_pkg_close(pkgptr);
+ pkgptr = NULL;
+ }
+ }
+ if (NULL != pkgptr) {
+ ((rptr->pkgs)[ind])[i] = pkgptr;
+ } else {
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ ulptr->had_error |= DK4_UC2L_ERROR_MEMORY;
+ }
+ }
+ }
+ } else {
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ ulptr->had_error |= DK4_UC2L_ERROR_MEMORY;
+ }
+ } else {
+ /* ERROR: Redefinition */
+ sznumbuf = DK4_SIZEOF(numbuf,dkChar);
+ numres = dk4ma_write_hex_unsigned(
+ numbuf, sznumbuf, (dk4_um_t)c32, 8, NULL
+ );
+ if (0 != numres) {
+ dk4app_log_3(
+ app, ulptr->msgs,ulptr->szmsgs, DK4_LL_ERROR, 2, 3, numbuf
+ );
+ } else {
+ dk4app_log_1(app,ulptr->msgs,ulptr->szmsgs,DK4_LL_ERROR,4);
+ }
+ ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX;
+ }
+ } else {
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ ulptr->had_error |= DK4_UC2L_ERROR_MEMORY;
+ }
+ } else {
+ /* ERROR Syntax */
+ dk4app_log_1(app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 9);
+ ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX;
+ }
+ } break;
+ default: {
+ /* ERROR: Syntax error */
+ dk4app_log_1(app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 10);
+ ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX;
+ } break;
+ }
+ } else {
+ /* ERROR: Syntax */
+ dk4app_log_1(app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 11);
+ ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX;
+ }
+ } else {
+ /* ERROR: Syntax */
+ dk4app_log_1(app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 11);
+ ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX;
+ }
+ p1 = p2;
+ }
+
+ finished:
+
+
+#line 1887 "dk4uc2l.ctr"
+ return back;
+}
+
+
+
+static
+void
+dk4uc2l_sp_process_stream(
+ dk4_uc2l_t *ulptr,
+ dk4_stream_t *rstrm,
+ const dkChar *fnb,
+ dk4_app_t *app
+)
+{
+ char buf[256]; /* Line buffer */
+ dk4_uc2l_lhobj obj; /* Processing object */
+ dk4_tsp08_t tsp08; /* Text stream processor */
+ dk4_er_t er; /* General error report */
+ dk4_er_t er_en; /* Error report encoding/decoding */
+ dk4_er_t er_pr; /* Error report processing */
+ int res; /* Operation result */
+ int cc; /* Flag: Can continue */
+ char c; /* Current character to process */
+
+ obj.ulptr = ulptr;
+ obj.app = app;
+ obj.sfn = fnb;
+ obj.e_d = 0;
+ obj.e_e = 0;
+ obj.e_p = 0;
+ dk4error_init(&er);
+ dk4error_init(&er_en);
+ dk4error_init(&er_pr);
+ res = dk4tsp08_setup_line(
+ &tsp08, (void *)(&obj), dk4uc2l_sp_handler, buf, sizeof(buf),
+ DK4_ENCODING_ASCII, DK4_ENCODING_ASCII, &er
+ );
+ if (0 != res) {
+ cc = 1;
+ while (1 == cc) {
+ res = dk4stream_c8_read_byte(&c, rstrm, &er);
+ if (0 != res) {
+ res = dk4tsp08_add_one_byte(&tsp08, (unsigned char)c);
+ switch (res) {
+ case DK4_TSP_RES_ERROR: {
+ dk4tsp08_get_errors(&er_en, &er_pr, &tsp08);
+ /* Report errors */
+ dk4uc2l_report_errors(ulptr, app, &obj, &er_en, &er_pr);
+ dk4error_init(&er_en);
+ dk4error_init(&er_pr);
+ ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING;
+ } break;
+ case DK4_TSP_RES_FATAL: {
+ cc = -1;
+ dk4tsp08_get_errors(&er_en, &er_pr, &tsp08);
+ /* Report errors */
+ dk4uc2l_report_errors(ulptr, app, &obj, &er_en, &er_pr);
+ dk4error_init(&er_en);
+ dk4error_init(&er_pr);
+ ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING;
+ } break;
+ }
+ } else {
+ cc = 0;
+ }
+ }
+ if (0 == cc) {
+ res = dk4tsp08_finish(&tsp08);
+ switch (res) {
+ case DK4_TSP_RES_ERROR: case DK4_TSP_RES_FATAL: {
+ dk4tsp08_get_errors(&er_en, &er_pr, &tsp08);
+ /* Report errors */
+ dk4uc2l_report_errors(ulptr, app, &obj, &er_en, &er_pr);
+ ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING;
+ } break;
+ }
+ }
+ } else {
+ ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING;
+ }
+}
+
+
+
+/** Attempt to load one data file if not yet loaded.
+ @param ulptr Conversion structure.
+ @param rptr Pointer to range causing the attempt to load.
+ @param app Application structure for diagnostics, may be NULL.
+*/
+static
+void
+dk4uc2l_load_if_not_yet_done(
+ dk4_uc2l_t *ulptr,
+ dk4_uc2l_range_t *rptr,
+ dk4_app_t *app
+)
+{
+ dkChar fnb[DK4_MAX_PATH];
+ dk4_er_t er;
+ const dkChar *oldsourcefile;
+ dk4_uc2l_file_t *fptr;
+ dk4_stream_t *rstrm;
+ dk4_um_t oldsourceline;
+ size_t fnbsz;
+
+
+#line 1992 "dk4uc2l.ctr"
+ fptr = rptr->file;
+ if (NULL != fptr) {
+
+#line 1994 "dk4uc2l.ctr"
+ if (0x00 == fptr->loaded) {
+
+#line 1995 "dk4uc2l.ctr"
+ fptr->loaded = 0x01;
+ fnbsz = DK4_SIZEOF(fnb, dkChar);
+ if (0 != dk4str_cpy_s(fnb, fnbsz, ulptr->dname, NULL)) {
+ if (0 != dk4str_cat_s(fnb, fnbsz, dk4uc2l_kwnl[7], NULL)) {
+ if (0 != dk4str_cat_s(fnb, fnbsz, fptr->fn, NULL)) {
+ dk4path_correct_sep(fnb);
+ dk4error_init(&er);
+ rstrm = dk4stream_open_file_reader(fnb, &er);
+ if (NULL != rstrm) {
+ oldsourcefile = dk4app_get_log_source_file(app);
+ oldsourceline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_file(app, fnb);
+ dk4app_set_log_source_line(app, (dk4_um_t)0UL);
+ dk4uc2l_sp_process_stream(ulptr, rstrm, fnb, app);
+ dk4app_set_log_source_file(app, oldsourcefile);
+ dk4app_set_log_source_line(app, oldsourceline);
+ dk4stream_close(rstrm, NULL);
+ } else {
+
+#line 2013 "dk4uc2l.ctr"
+ /* ERROR: Failed to open file */
+ dk4app_log_3(
+ app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 6, 7, fnb
+ );
+ ulptr->had_error |= DK4_UC2L_ERROR_FOPEN;
+ }
+ } else {
+
+#line 2020 "dk4uc2l.ctr"
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, ulptr->dname);
+ ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING;
+ }
+ } else {
+
+#line 2025 "dk4uc2l.ctr"
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, ulptr->dname);
+ ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING;
+ }
+ } else {
+
+#line 2030 "dk4uc2l.ctr"
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, ulptr->dname);
+ ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING;
+ }
+ } else {
+
+#line 2035 "dk4uc2l.ctr"
+ }
+ } else {
+
+#line 2037 "dk4uc2l.ctr"
+ ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING;
+ }
+
+#line 2039 "dk4uc2l.ctr"
+}
+
+
+
+const char *
+dk4uc2l_find(dk4_uc2l_t *ulptr, dk4_c32_t c, int mm, dk4_app_t *app)
+{
+ dkChar numbuf[16*sizeof(dk4_um_t)];
+ dk4_uc2l_range_t *rptr;
+ dk4_uc2l_pkg_t **pptr;
+ dk4_uc2l_pkg_t *xpptr;
+ const char *back = NULL;
+ size_t blgt;
+ size_t sznumbuf;
+ int numres;
+
+
+#line 2055 "dk4uc2l.ctr"
+ if (NULL != ulptr) {
+ /*
+ Attempt direct output.
+ */
+ if (0 != dk4uc2lat_direct(c)) {
+ ulptr->buf[0] = (char)c;
+ ulptr->buf[1] = '\0';
+ back = &(ulptr->buf[0]);
+ goto finished;
+ }
+
+ /*
+ Attempt to find output string in data.
+ */
+ rptr = (dk4_uc2l_range_t *)dk4sto_it_find_like(
+ ulptr->i_ranges, &c, 1
+ );
+ if (NULL != rptr) {
+ dk4uc2l_load_if_not_yet_done(ulptr, rptr, app);
+ if (0 != mm) {
+ if (NULL != rptr->math) {
+ back = (rptr->math)[(size_t)(c - rptr->start)];
+ }
+ if (NULL == back) {
+ if (NULL != rptr->both) {
+ back = (rptr->both)[(size_t)(c - rptr->start)];
+ }
+ }
+ } else {
+ if (NULL != rptr->text) {
+ back = (rptr->text)[(size_t)(c - rptr->start)];
+ }
+ if (NULL == back) {
+ if (NULL != rptr->both) {
+ back = (rptr->both)[(size_t)(c - rptr->start)];
+ }
+ }
+ }
+ if (NULL != back) {
+ if (NULL != rptr->fenc) {
+ ulptr->fallowed &= (rptr->fenc)[(size_t)(c - rptr->start)];
+ }
+ if (NULL != rptr->pkgs) {
+ if (NULL != (rptr->pkgs)[(size_t)(c - rptr->start)]) {
+ pptr = (rptr->pkgs)[(size_t)(c - rptr->start)];
+ while (NULL != *pptr) {
+ xpptr = *(pptr++);
+ xpptr->used = 0x01;
+ }
+ }
+ }
+ }
+ }
+ if (NULL != back) { goto finished; }
+
+ /*
+ If everything failed so far, attempt to use UTF-8 output
+ or direct output.
+ */
+ if (0 != mm) { goto finished; }
+ if (0x00 != ulptr->utf8allowed) {
+ blgt = 15;
+ if (0 != dk4utf8_encode((unsigned char *)(&(ulptr->buf[0])),&blgt,c,NULL))
+ {
+ ulptr->buf[blgt] = '\0';
+ back = &(ulptr->buf[0]);
+ }
+ else
+ {
+ /* ERROR: UTF-8 encoding failed */
+ sznumbuf = DK4_SIZEOF(numbuf,dkChar);
+ numres = dk4ma_write_hex_unsigned(
+ numbuf, sznumbuf, (dk4_um_t)c, 8, NULL
+ );
+ if (0 != numres) {
+ dk4app_log_3(
+ app, ulptr->msgs,ulptr->szmsgs, DK4_LL_ERROR, 12, 13, numbuf
+ );
+ } else {
+ dk4app_log_1(app,ulptr->msgs,ulptr->szmsgs,DK4_LL_ERROR,14);
+ }
+
+ }
+ } else {
+ if (dkC32(0x00000100) > c) {
+ ulptr->buf[0] = (char)c;
+ ulptr->buf[1] = '\0';
+ back = &(ulptr->buf[0]);
+ } else {
+ /* ERROR: No encoding found */
+ }
+ }
+ }
+ finished:
+
+
+#line 2150 "dk4uc2l.ctr"
+ return back;
+}
+
+
+
+dk4_uc2l_t *
+dk4uc2l_open(const dkChar *dn, dk4_app_t *app)
+{
+ dk4_er_t er;
+ dk4_uc2l_t *back = NULL;
+
+
+#line 2161 "dk4uc2l.ctr"
+ dk4error_init(&er);
+ if (NULL != dn) {
+ if (0 != dk4file_is_directory(dn, &er)) {
+ back = dk4uc2l_create(dn, app);
+ if (NULL != back) {
+ if (0 == dk4uc2l_first_pass(back, app)) {
+ dk4uc2l_close(back);
+ back = NULL;
+ }
+ }
+ } else {
+ /* ERROR: Not a directory */
+ dk4app_log_base3(app, DK4_LL_ERROR, 152, 153, dn);
+ }
+ }
+
+#line 2176 "dk4uc2l.ctr"
+ return back;
+}
+
+
+
+dk4_uc2l_t *
+dk4uc2l_open_from_app(dk4_app_t *app)
+{
+ dkChar fnb[DK4_MAX_PATH]; /* Buffer to construct name */
+ const dkChar * const *debmsg;
+ dk4_uc2l_t *back = NULL;
+ size_t i = 0; /* Traverse possible dirs */
+ size_t szdm = 0;
+ int done = 0; /* Flag: Attempted */
+ int toolo = 0; /* Flag: Name too long */
+ int res = 0; /* Operation result */
+
+
+#line 2193 "dk4uc2l.ctr"
+ if (NULL != app) {
+ res = dk4app_pref_get(fnb,DK4_SIZEOF(fnb,dkChar),app,dk4uc2l_kwnl[0],0);
+ if (0 != res) {
+ dk4path_correct_sep(fnb);
+ if (0 != dk4file_is_directory(fnb, NULL)) {
+ done = 1;
+ back = dk4uc2l_open(fnb, app);
+ }
+ }
+ for (i = 1; i < 4; i++) {
+ if ((0 == done) && (NULL == back)) {
+ if (0 != dk4str_cpy_s(fnb,DK4_SIZEOF(fnb,dkChar),app->dir_share,NULL)) {
+ if (0 != dk4str_cat_s(fnb,DK4_SIZEOF(fnb,dkChar),dk4uc2l_kwnl[i],NULL))
+ {
+ dk4path_correct_sep(fnb);
+ if (0 != dk4file_is_directory(fnb, NULL)) {
+ done = 1;
+ back = dk4uc2l_open(fnb, app);
+ }
+ } else {
+ toolo = 1;
+ }
+ } else {
+ toolo = 1;
+ }
+ }
+ }
+ }
+ if (NULL == back) {
+ if (0 == done) {
+ if (0 != toolo) {
+ /* ERROR: shared directory name too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, app->dir_share);
+ } else {
+ /* ERROR: No charmap directory found */
+ debmsg = dk4app_string_table(app, dk4uc2l_kwnl[8], dk4uc2l_kw_def);
+ szdm = dk4app_string_table_size(dk4uc2l_kw_def);
+ dk4app_log_1(app, debmsg, szdm, DK4_LL_ERROR, 15);
+ }
+ }
+ }
+
+#line 2234 "dk4uc2l.ctr"
+ return back;
+}
+
+
+
+void
+dk4uc2l_clean_packages_and_fonts(dk4_uc2l_t *ulptr)
+{
+ dk4_uc2l_pkg_t *pptr;
+
+
+#line 2244 "dk4uc2l.ctr"
+ if (NULL != ulptr) {
+ ulptr->fallowed = DK4_UC2L_FONT_ENCODING_ALL;
+ dk4sto_it_reset(ulptr->i_pkgs);
+ do {
+ pptr = (dk4_uc2l_pkg_t *)dk4sto_it_next(ulptr->i_pkgs);
+ if (NULL != pptr) {
+ pptr->used = 0x00;
+ }
+ } while (NULL != pptr);
+ }
+
+#line 2254 "dk4uc2l.ctr"
+}
+
+
+
+unsigned char
+dk4uc2l_retrieve_allowed_fe(dk4_uc2l_t *ulptr)
+{
+ unsigned char back = 0x00;
+
+
+#line 2263 "dk4uc2l.ctr"
+ if (NULL != ulptr) {
+ back = ulptr->fallowed;
+ }
+
+#line 2266 "dk4uc2l.ctr"
+ return back;
+}
+
+
+
+void
+dk4uc2l_allow_utf8(dk4_uc2l_t *ulptr, int enabled)
+{
+ if (NULL != ulptr) {
+ ulptr->utf8allowed = ((0 != enabled) ? 0x01 : 0x00);
+ }
+}
+
+
+
+int
+dk4uc2lat_direct(dk4_c32_t c32)
+{
+ int back = 0;
+ char c; /* 8-bit character version of c32. */
+
+
+#line 2287 "dk4uc2l.ctr"
+ if((unsigned long)c32 < 128UL) {
+ c = (char)c32;
+ switch(c) {
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
+ case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
+ case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u':
+ case 'v': case 'w': case 'x': case 'y': case 'z': case 'A': case 'B':
+ case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I':
+ case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P':
+ case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W':
+ case 'X': case 'Y': case 'Z': case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7': case '8': case '9': case ',':
+ case '.': case ':': case ';': case '+': case '-': case '?': case '!':
+ case '|': case '@': case '(': case ')': case '/': case '=': case ' ':
+ {
+ back = 1;
+ }
+ break;
+ }
+ }
+
+#line 2307 "dk4uc2l.ctr"
+ return back;
+}
+
+
+
+void
+dk4uc2l_recommendations(dk4_uc2l_t *ulptr, FILE *fipo)
+{
+ dk4_uc2l_pkg_t *pptr;
+ if ((NULL != ulptr) && (NULL != fipo)) {
+ fputs(dk4uc2l_kw8[0], fipo);
+ if (0x00 != (ulptr->fallowed & (unsigned char)DK4_UC2L_FONT_ENCODING_T1)) {
+ fputs(dk4uc2l_kw8[3], fipo);
+ }
+ if (0x00 != (ulptr->fallowed & (unsigned char)DK4_UC2L_FONT_ENCODING_OT1)) {
+ fputs(dk4uc2l_kw8[2], fipo);
+ }
+ if (0x00 != (ulptr->fallowed & (unsigned char)DK4_UC2L_FONT_ENCODING_T4)) {
+ fputs(dk4uc2l_kw8[4], fipo);
+ }
+ if (0x00 != (ulptr->fallowed & (unsigned char)DK4_UC2L_FONT_ENCODING_T5)) {
+ fputs(dk4uc2l_kw8[5], fipo);
+ }
+ fputc('\n', stdout);
+ dk4sto_it_reset(ulptr->i_pkgs);
+ do {
+ pptr = (dk4_uc2l_pkg_t *)dk4sto_it_next(ulptr->i_pkgs);
+ if (NULL != pptr) {
+ if (0x00 != pptr->used) {
+ fputs(dk4uc2l_kw8[1], fipo);
+ fputs(pptr->pn, fipo);
+ fputc('\n', fipo);
+ }
+ }
+ } while (NULL != pptr);
+ }
+}
+
+
+
+int
+dk4uc2l_retrieve_errors(dk4_uc2l_t *ulptr)
+{
+ int back = 0;
+ if (NULL != ulptr) {
+ back = ulptr->had_error;
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4uc2l.ctr b/support/dktools/dk4uc2l.ctr
new file mode 100644
index 0000000000..eff48fb915
--- /dev/null
+++ b/support/dktools/dk4uc2l.ctr
@@ -0,0 +1,2357 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk4uc2l.h Text to LaTeX conversion.
+
+LaTeX sequences to represent a 32 bit character are found in lookup tables
+in the ${datarootdir}/dktools/charmap directory. The functions in this
+module read those lookup tables needed, cache the contents and provide
+LaTeX sequences.
+
+After finishing output you can write recommendations (i.e. LaTeX packages
+to include, font encoding to use) as comments to the file.
+*/
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4app.h"
+#endif
+
+#ifndef DK4STO_H_INCLUDED
+#include "dk4sto.h"
+#endif
+
+/** Information about a package.
+*/
+typedef struct {
+ char *pn; /**< Package name. */
+ unsigned char used; /**< Flag: Package used. */
+} dk4_uc2l_pkg_t;
+
+/** Data for contents of one file.
+ The structure contains information about the character
+ ranges covered by the file.
+*/
+typedef struct {
+ dkChar *fn; /**< Short file name. */
+ unsigned char loaded; /**< Flag: File loaded. */
+} dk4_uc2l_file_t;
+
+
+/** Range of characters.
+*/
+typedef struct {
+ dk4_uc2l_file_t *file; /**< File containing data. */
+ char **both; /**< LaTeX text both modes. */
+ char **text; /**< LaTeX text text mode. */
+ char **math; /**< LaTeX text math mode. */
+ dk4_uc2l_pkg_t ***pkgs; /**< Packages for characters. */
+ unsigned char *fenc; /**< Required font encodings. */
+ dk4_c32_t start; /**< First character of range. */
+ dk4_c32_t end; /**< Final character of range. */
+ unsigned char ia; /**< Flag: Initialisation att. */
+} dk4_uc2l_range_t;
+
+
+/** Text to LaTeX conversion structure.
+*/
+typedef struct {
+ char buf[16]; /**< Buffer for direct output. */
+ const dkChar * const *msgs; /**< Localized messages */
+ dkChar *dname; /**< Directory name. */
+ dk4_sto_t *s_ranges; /**< Ranges container. */
+ dk4_sto_it_t *i_ranges; /**< Ranges container iterator. */
+ dk4_sto_t *s_files; /**< Files container. */
+ dk4_sto_it_t *i_files; /**< Files container iterator. */
+ dk4_sto_t *s_pkgs; /**< Package information container. */
+ dk4_sto_it_t *i_pkgs; /**< Package information iterator. */
+ size_t szmsgs; /**< Number of messages in msgs. */
+ int had_error; /**< Flag: Errors occured. */
+ unsigned char utf8allowed; /**< Flag: UTF-8 output allowed. */
+ unsigned char fallowed; /**< Allowed font encodings. */
+} dk4_uc2l_t;
+
+
+/** Font encodings
+*/
+enum {
+ /** OT1 font encoding.
+ */
+ DK4_UC2L_FONT_ENCODING_OT1 = 1 ,
+
+ /** T1 font encoding.
+ */
+ DK4_UC2L_FONT_ENCODING_T1 = 2 ,
+
+ /** T4 font encoding.
+ */
+ DK4_UC2L_FONT_ENCODING_T4 = 4 ,
+
+ /** T5 font encoding.
+ */
+ DK4_UC2L_FONT_ENCODING_T5 = 8 ,
+
+ DK4_UC2L_FONT_ENCODING_ALL = (
+ 0
+ | DK4_UC2L_FONT_ENCODING_OT1
+ | DK4_UC2L_FONT_ENCODING_T1
+ | DK4_UC2L_FONT_ENCODING_T4
+ | DK4_UC2L_FONT_ENCODING_T5
+ )
+};
+
+
+
+/** Errors from this module
+*/
+enum {
+
+ /** Memory allocation failed.
+ */
+ DK4_UC2L_ERROR_MEMORY = 1 ,
+
+ /** Syntax error in configuration file.
+ */
+ DK4_UC2L_ERROR_SYNTAX = 2 ,
+
+ /** Decoding error in configuration file.
+ */
+ DK4_UC2L_ERROR_DECODING = 4 ,
+
+ /** Other processing errors while reading data.
+ */
+ DK4_UC2L_ERROR_PROCESSING = 8 ,
+
+ /** Failed to open one of the data files.
+ */
+ DK4_UC2L_ERROR_FOPEN = 16 ,
+};
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open conversion structure, dynamically allocate memory.
+ @param dn Directory name containing the data files.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to conversion structure on success, NULL on error.
+
+ Use dk4uc2l_close() to close the conversion structure when done
+ with it.
+*/
+dk4_uc2l_t *
+dk4uc2l_open(const dkChar *dn, dk4_app_t *app);
+
+
+/** Open conversion structure, dynamically allocate memory.
+ The directory containing the data files is obtained from
+ the application (if not NULL), ${datarootdir}/dktools/charmap
+ is used by default.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to conversion structure on success, NULL on error.
+
+ Use dk4uc2l_close() to close the conversion structure when done
+ with it.
+*/
+dk4_uc2l_t *
+dk4uc2l_open_from_app(dk4_app_t *app);
+
+/** Close conversion structure, release memory.
+ @param ulptr Conversion structure to close.
+*/
+void
+dk4uc2l_close(dk4_uc2l_t *ulptr);
+
+/** Enable or disable direct UTF-8 output.
+ If you use usepackage[utf-8]{inputenc} you might want to
+ enable UTF-8 output.
+ @param ulptr Conversion structure to set up.
+ @param enabled Flag: Enable UTF-8 output.
+*/
+void
+dk4uc2l_allow_utf8(dk4_uc2l_t *ulptr, int enabled);
+
+/** Reset information about used packages and allowed and denied
+ font encodings.
+ Typically you want to use this function only after finishing
+ one output file and starting a new one.
+ @param ulptr Conversion structure to reset.
+*/
+void
+dk4uc2l_clean_packages_and_fonts(dk4_uc2l_t *ulptr);
+
+/** Find LaTeX encoding for one 32 bit character.
+ @param ulptr Conversion structure.
+ @param c Character to search encoding for.
+ @param mm Flag: Math mode (1) or text mode (0).
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to encoding string on success, NULL on error.
+*/
+const char *
+dk4uc2l_find(dk4_uc2l_t *ulptr, dk4_c32_t c, int mm, dk4_app_t *app);
+
+/** Retrieve or-combination of all allowed font encodings.
+ You should use this function after processing all characters.
+*/
+unsigned char
+dk4uc2l_retrieve_allowed_fe(dk4_uc2l_t *ulptr);
+
+/** Check whether a character can be written to a LaTeX file directly.
+ @param c32 Character to check.
+ @return 1 for yes, 0 for no.
+*/
+int
+dk4uc2lat_direct(dk4_c32_t c32);
+
+/** Issue recommendations about font encodings and packages.
+ Use this function after processing all characters.
+ @param ulptr Conversion structure.
+ @param fipo File to write to.
+*/
+void
+dk4uc2l_recommendations(dk4_uc2l_t *ulptr, FILE *fipo);
+
+/** Retrieve internal error status from conversion structure.
+ @param ulptr Conversion structure.
+ @return Error status, 0 or combination of DK4_UC2L_ERROR_MEMORY,
+ DK4_UC2L_ERROR_SYNTAX, DK4_UC2L_ERROR_DECODING,
+ DK4_UC2L_ERROR_PROCESSING, and DK4_UC2L_ERROR_FOPEN.
+*/
+int
+dk4uc2l_retrieve_errors(dk4_uc2l_t *ulptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4const.h"
+#include "dk4uc2l.h"
+#include "dk4mem.h"
+#include "dk4mema.h"
+#include "dk4str8.h"
+#include "dk4strd.h"
+#include "dk4maasz.h"
+#include "dk4filed.h"
+#include "dk4mpl.h"
+#include "dk4strm.h"
+#include "dk4strmr.h"
+#include "dk4dir.h"
+#include "dk4dira.h"
+#include "dk4pathd.h"
+#include "dk4tsp08.h"
+#include "dk4enc.h"
+#include "dk4mai8hdu.h"
+#include "dk4maodh.h"
+#include "dk4maodd.h"
+
+
+
+$!trace-include
+
+
+
+typedef char *dk4_uc2l_char_ptr;
+
+typedef dk4_uc2l_pkg_t *dk4_uc2l_pkg_ptr;
+
+typedef dk4_uc2l_pkg_ptr *dk4_uc2l_pkg_ptr_ptr;
+
+/** Data passed to the line handler.
+*/
+typedef struct {
+ dk4_uc2l_t *ulptr; /**< Conversion structure. */
+ dk4_app_t *app; /**< Application for diagnostics, may be NULL. */
+ const dkChar *sfn; /**< Short file name (pass 1). */
+ dk4_sto_t *s_r; /**< Storage for file ranges. */
+ dk4_sto_it_t *i_r; /**< Iterator for file ranges. */
+ int e_d; /**< Decoding errors. */
+ int e_e; /**< Encoding errors. */
+ int e_p; /**< Processing errors. */
+} dk4_uc2l_lhobj;
+
+
+
+/** Fixed keywords used by the module, not localized.
+*/
+static const dkChar * const dk4uc2l_kwnl[] = {
+$!string-table macro=dkT
+#
+# 0 Preference: Directory containing map data.
+#
+dir.charmap
+#
+# 1 2 3 Subdirectories to search for.
+#
+/dktools/charmap
+/dk4app/charmap
+/dk3app/charmap
+#
+# 4 5 6 File name suffixes
+#
+.t2l
+.t2l.gz
+.t2l.bz2
+#
+# 7 Path separator
+#
+/
+#
+# 8 String table file name.
+#
+dk4uc2l.str
+$!end
+};
+
+
+
+/** Localized texts.
+*/
+static const dkChar * const dk4uc2l_kw_def[] = {
+$!string-table macro=dkT
+#
+# 0 Error: Syntax
+#
+Syntax error!\n\tHexadecimal number required at start of line!
+#
+# 1 Error: Syntax
+#
+Syntax error!\n\tHexadecimal value outside allowed 32 bit range!
+#
+# 2 3 4 Error: Syntax error! Redefintion of character!
+#
+Syntax error!\n\tRedefinition of
+!
+Syntax error! Redefintion of character!
+#
+# 5 Error: Failed to set up text processing!
+#
+Failed to set up text processing!
+#
+# 6 7 Error: Failed to open file for reading: ...
+#
+Failed to open file for reading:\n\t"
+"!
+#
+# 8 Error: Syntax error!\n\tIllegal font encoding name!
+#
+Syntax error!\n\tIllegal font encoding name!
+#
+# 9 Error: Syntax error!\n\t1 to 15 packages names are allowed!
+#
+Syntax error!\n\t1 to 15 packages names are allowed!
+#
+# 10 Error: Syntax error!\n\tIllegal attribute name!
+#
+Syntax error!\n\tIllegal attribute name!
+#
+# 11 Error: Syntax error!\n\tAttribute specified without value!
+#
+Syntax error!\n\tAttribute specified without value!
+#
+# 12 13 14 Error: Conversion to UTF-8 failed for a character!
+#
+Conversion to UTF-8 failed for 0x
+!
+Conversion to UTF-8 failed for a character!
+#
+# 15 Error: No directory for character mapping information found!
+#
+No directory for character mapping information found!
+#
+# 16 ... 21 Error messages.
+#
+Decoding failed!\n\tByte:
+Encoding failed!\n\tByte:
+Processing failed!\n\tByte:
+,\n\tCharacter:
+,\n\tPosition in line:
+.
+#
+# 22 ... 27 Error messages.
+#
+Decoding failed!
+Encoding failed!
+Processing failed!
+Further decoding failures!
+Further encoding failures!
+Further processing failures!
+$!end
+};
+
+
+
+static const char * const dk4uc2l_kw8[] = {
+$!string-table
+#
+# 0 Font encodings
+#
+% Font encodings:
+#
+# 1 Recommended package
+#
+% Recommended package:
+#
+# 2 3 4 5 Font encoding names
+#
+ ot1
+ t1
+ t4
+ t5
+#
+#
+#
+$!end
+};
+
+
+/** Attribute names.
+*/
+static const char * const dk4uc2l_attribute_names[] = {
+$!string-table
+b$oth
+t$ext
+m$ath
+e$ncoding
+p$ackages
+$!end
+};
+
+
+
+static const char * const dk4uc2l_font_encodings[] = {
+$!string-table
+ot1
+t1
+t4
+t5
+$!end
+};
+
+
+
+/** Destroy LaTeX package structure, release memory.
+ @param pptr Package to destroy.
+*/
+static
+void
+dk4uc2l_pkg_close(dk4_uc2l_pkg_t *pptr)
+{
+ $? "+ dk4uc2l_pkg_close PTR=%d", TR_IPTR(pptr)
+ if (NULL != pptr) {
+ pptr->used = 0x00;
+ dk4mem_release(pptr->pn);
+ dk4mem_free(pptr);
+ }
+ $? "- dk4uc2l_pkg_close"
+}
+
+
+
+/** Create LaTeX package structure, allocate memory.
+ @param pn Package name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new structure on success, NULL on error.
+*/
+static
+dk4_uc2l_pkg_t *
+dk4uc2l_pkg_open(const char *pn, dk4_app_t *app)
+{
+ dk4_uc2l_pkg_t *back = NULL;
+ $? "+ dk4uc2l_pkg_open"
+ if (NULL != pn) {
+ back = dk4mem_new_app(dk4_uc2l_pkg_t,1,app);
+ if (NULL != back) {
+ back->used = 0x00;
+ back->pn = dk4str8_dup(pn, NULL);
+ if (NULL == back->pn) {
+ dk4uc2l_pkg_close(back);
+ back = NULL;
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ }
+ }
+ } $? "- dk4uc2l_pkg_open PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/** Compare two LaTeX package structures.
+ @param l Left pointer, always a package structure.
+ @param r Right pointer.
+ @param cr Comparison criteria: 0 if r is a package pointer,
+ 1 if r is just a package name string.
+ @return Comparison result: 1 if l>r, 0 if l==r, -1 if l<r.
+*/
+static
+int
+dk4uc2l_pkg_compare(const void *l, const void *r, int cr)
+{
+
+ const dk4_uc2l_pkg_t *pl;
+ const dk4_uc2l_pkg_t *pr;
+ int back = 0;
+
+ if (NULL != l) {
+ if (NULL != r) {
+ pl = (const dk4_uc2l_pkg_t *)l;
+ switch (cr) {
+ case 1: {
+ back = strcmp(pl->pn, (const char *)r);
+ } break;
+ default: {
+ pr = (const dk4_uc2l_pkg_t *)r;
+ back = strcmp(pl->pn, pr->pn);
+ } break;
+ }
+ if (-1 > back) back = -1;
+ if ( 1 < back) back = 1;
+ } else { back = 1; }
+ } else {
+ if (NULL != r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+/** Destroy file information structure, release memory.
+ @param fptr File information structure to destroy.
+*/
+static
+void
+dk4uc2l_file_close(dk4_uc2l_file_t *fptr)
+{
+ $? "+ dk4uc2l_file_close"
+ if (NULL != fptr) {
+ fptr->loaded = 0x00;
+ dk4mem_release(fptr->fn);
+ dk4mem_free(fptr);
+ } $? "- dk4uc2l_file_close"
+}
+
+
+
+/** Create file information structure, allocate memory.
+ @param fn File name to create structure for.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new structure on success, NULL on error.
+*/
+static
+dk4_uc2l_file_t *
+dk4uc2l_file_open(const dkChar *fn, dk4_app_t *app)
+{
+ dk4_uc2l_file_t *back = NULL;
+ $? "+ dk4uc2l_file_open"
+ if (NULL != fn) {
+ back = dk4mem_new_app(dk4_uc2l_file_t,1,app);
+ if (NULL != back) {
+ back->loaded = 0x00;
+ back->fn = dk4str_dup(fn, NULL);
+ if (NULL == back->fn) {
+ dk4uc2l_file_close(back);
+ back = NULL;
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ }
+ }
+ } $? "- dk4uc2l_file_open PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/** Compare two file information structures.
+ @param l Left pointer, always a file information structure.
+ @param r Right pointer.
+ @param cr Comparison criteria:
+ 0 if the right pointer is a file information structure
+ pointer,
+ 1 if the right pointer is a file name string.
+ @return Comparison result: 0 if file names are equal, -1 if l<r,
+ 1 if l>r.
+*/
+static
+int
+dk4uc2l_file_compare(const void *l, const void *r, int cr)
+{
+ const dk4_uc2l_file_t *pl;
+ const dk4_uc2l_file_t *pr;
+ int back = 0;
+ if (NULL != l) {
+ if (NULL != r) {
+ pl = (const dk4_uc2l_file_t *)l;
+ switch (cr) {
+ case 1: {
+ back = dk4str_pathcmp(pl->fn, (const dkChar *)r);
+ } break;
+ default: {
+ pr = (const dk4_uc2l_file_t *)r;
+ back = dk4str_pathcmp(pl->fn, pr->fn);
+ } break;
+ }
+ if (-1 > back) { back = -1; }
+ if ( 1 < back) { back = 1; }
+ } else { back = 1; }
+ } else {
+ if (NULL != r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+/** Destroy range structure, release memory.
+ @param rptr Range structure to destroy.
+*/
+static
+void
+dk4uc2l_range_close(dk4_uc2l_range_t *rptr)
+{
+ dk4_er_t er;
+ size_t nelem;
+ size_t i;
+ $? "+ dk4uc2l_range_close %lu %lu (0x%lx 0x%lx)", (unsigned long)(rptr->start), (unsigned long)(rptr->end), (unsigned long)(rptr->start), (unsigned long)(rptr->end)
+#if TRACE_DEBUG
+ if (NULL != rptr->file) {
+ if (NULL != (rptr->file)->fn) {
+ $? ". file name \"%!ds\"", (rptr->file)->fn
+ }
+ }
+#endif
+ if (NULL != rptr) {
+ /*
+ Overflow check when calculating number of elements in range
+ as end-start+1
+ */
+ dk4error_init(&er);
+ nelem = dk4ma_size_t_add(
+ dk4ma_size_t_sub((size_t)(rptr->end), (size_t)(rptr->start), &er),
+ (size_t)1U,
+ &er
+ );
+ if (DK4_E_NONE == er.ec) {
+ /*
+ Release dynamic memory.
+ */
+ if (NULL != rptr->both) {
+ for (i = 0; i < nelem; i++) { dk4mem_release((rptr->both)[i]); }
+ dk4mem_release(rptr->both);
+ }
+ if (NULL != rptr->text) {
+ for (i = 0; i < nelem; i++) { dk4mem_release((rptr->text)[i]); }
+ dk4mem_release(rptr->text);
+ }
+ if (NULL != rptr->math) {
+ for (i = 0; i < nelem; i++) { dk4mem_release((rptr->math)[i]); }
+ dk4mem_release(rptr->math);
+ }
+ if (NULL != rptr->pkgs) {
+ for (i = 0; i < nelem; i++) { dk4mem_release((rptr->pkgs)[i]); }
+ dk4mem_release(rptr->pkgs);
+ }
+ if (NULL != rptr->fenc) {
+ dk4mem_release(rptr->fenc);
+ }
+ }
+ rptr->file = NULL;
+ rptr->start = rptr->end = (dk4_c32_t)0UL;
+ rptr->ia = 0x00;
+ dk4mem_free(rptr);
+ } $? "- dk4uc2l_range_close"
+}
+
+
+
+/** Create range structure, partially allocate memory.
+ @param c Character, initially start and end of range.
+ @param fptr Pointer to exisiting file information structure.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new structure on success, NULL on error.
+*/
+static
+dk4_uc2l_range_t *
+dk4uc2l_range_open(dk4_c32_t c, dk4_uc2l_file_t *fptr, dk4_app_t *app)
+{
+ dk4_uc2l_range_t *back = NULL;
+ $? "+ dk4uc2l_range_open"
+ if (NULL != fptr) {
+ back = dk4mem_new_app(dk4_uc2l_range_t,1,app);
+ if (NULL != back) {
+ back->file = fptr;
+ back->both = NULL;
+ back->text = NULL;
+ back->math = NULL;
+ back->pkgs = NULL;
+ back->fenc = NULL;
+ back->start = back->end = c;
+ back->ia = 0x00;
+ }
+ } $? "- dk4uc2l_range_open PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/** Compare two range informations or a range information against a
+ character.
+ @param l Left pointer, always a range information strucutre.
+ @param r Right pointer.
+ @param cr Comparison criteria:
+ 0 if the right pointer is a range information strucutre,
+ 1 if the right pointer is a pointer to a dk4_c32_t.
+ @return Comparison result: -1 if l<r, 0 if l=r, 1 if l>r.
+*/
+static
+int
+dk4uc2l_range_compare(const void *l, const void *r, int cr)
+{
+ const dk4_uc2l_range_t *pl;
+ const dk4_uc2l_range_t *pr;
+ const dk4_c32_t *pc;
+ int back = 0;
+ if (NULL != l) {
+ if (NULL != r) {
+ pl = (const dk4_uc2l_range_t *)l;
+ switch (cr) {
+ case 1: {
+ pc = (const dk4_c32_t *)r;
+ if (pl->start > *pc) {
+ back = 1;
+ } else {
+ if (pl->end < *pc) {
+ back = -1;
+ }
+ }
+ } break;
+ default: {
+ pr = (const dk4_uc2l_range_t *)r;
+ if (pl->start < pr->start) {
+ back = -1;
+ } else {
+ if (pl->start > pr->start) {
+ back = 1;
+ }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if (NULL != r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+void
+dk4uc2l_close(dk4_uc2l_t *ulptr)
+{
+ dk4_uc2l_pkg_t *pptr;
+ dk4_uc2l_file_t *fptr;
+ dk4_uc2l_range_t *rptr;
+ $? "+ dk4uc2l_close"
+ if (NULL != ulptr) {
+ /*
+ Directory name.
+ */
+ dk4mem_release(ulptr->dname);
+ /*
+ Ranges.
+ */
+ if (NULL != ulptr->s_ranges) {
+ if (NULL != ulptr->i_ranges) {
+ dk4sto_it_reset(ulptr->i_ranges);
+ do {
+ rptr = (dk4_uc2l_range_t *)dk4sto_it_next(ulptr->i_ranges);
+ if (NULL != rptr) { dk4uc2l_range_close(rptr); }
+ } while (NULL != rptr);
+ dk4sto_it_close(ulptr->i_ranges);
+ }
+ dk4sto_close(ulptr->s_ranges);
+ }
+ /*
+ File information.
+ */
+ if (NULL != ulptr->s_files) {
+ if (NULL != ulptr->i_files) {
+ dk4sto_it_reset(ulptr->i_files);
+ do {
+ fptr = (dk4_uc2l_file_t *)dk4sto_it_next(ulptr->i_files);
+ if (NULL != fptr) { dk4uc2l_file_close(fptr); }
+ } while (NULL != fptr);
+ dk4sto_it_close(ulptr->i_files);
+ }
+ dk4sto_close(ulptr->s_files);
+ }
+ /*
+ Package information.
+ */
+ if (NULL != ulptr->s_pkgs) {
+ if (NULL != ulptr->i_pkgs) {
+ dk4sto_it_reset(ulptr->i_pkgs);
+ do {
+ pptr = (dk4_uc2l_pkg_t *)dk4sto_it_next(ulptr->i_pkgs);
+ if (NULL != pptr) { dk4uc2l_pkg_close(pptr); }
+ } while (NULL != pptr);
+ dk4sto_it_close(ulptr->i_pkgs);
+ }
+ dk4sto_close(ulptr->s_pkgs);
+ }
+ ulptr->s_ranges = NULL;
+ ulptr->i_ranges = NULL;
+ ulptr->s_files = NULL;
+ ulptr->i_files = NULL;
+ ulptr->s_pkgs = NULL;
+ ulptr->i_pkgs = NULL;
+ ulptr->msgs = NULL;
+ ulptr->szmsgs = 0;
+ dk4mem_free(ulptr);
+ } $? "- dk4uc2l_close"
+}
+
+
+
+static
+dk4_uc2l_t *
+dk4uc2l_create(const dkChar *dn, dk4_app_t *app)
+{
+ dk4_uc2l_t *back = NULL;
+ int ok = 0;
+ $? "+ dk4uc2l_create"
+ if (NULL != dn) {
+ back = dk4mem_new_app(dk4_uc2l_t,1,app);
+ if (NULL != back) {
+ back->dname = NULL;
+ back->s_ranges = NULL;
+ back->i_ranges = NULL;
+ back->s_files = NULL;
+ back->i_files = NULL;
+ back->s_pkgs = NULL;
+ back->i_pkgs = NULL;
+ back->fallowed = 0xFF;
+ back->utf8allowed = 0x00;
+ back->had_error = 0;
+ back->msgs = NULL;
+ back->szmsgs = 0;
+ back->dname = dk4str_dup(dn, NULL);
+ if (NULL != back->dname) {
+ back->s_ranges = dk4sto_open(NULL);
+ if (NULL != back->s_ranges) {
+ dk4sto_set_comp(back->s_ranges, dk4uc2l_range_compare, 0);
+ back->s_files = dk4sto_open(NULL);
+ if (NULL != back->s_files) {
+ dk4sto_set_comp(back->s_files, dk4uc2l_file_compare, 0);
+ back->s_pkgs = dk4sto_open(NULL);
+ if (NULL != back->s_pkgs) {
+ dk4sto_set_comp(back->s_pkgs, dk4uc2l_pkg_compare, 0);
+ back->i_ranges = dk4sto_it_open(back->s_ranges, NULL);
+ if (NULL != back->i_ranges) {
+ back->i_files = dk4sto_it_open(back->s_files, NULL);
+ if (NULL != back->i_files) {
+ back->i_pkgs = dk4sto_it_open(back->s_pkgs, NULL);
+ if (NULL != back->i_pkgs) {
+ if (NULL != app) {
+ back->msgs = dk4app_string_table(
+ app, dk4uc2l_kwnl[8], dk4uc2l_kw_def
+ );
+ } else {
+ back->msgs = dk4uc2l_kw_def;
+ }
+ back->szmsgs = dk4app_string_table_size(dk4uc2l_kw_def);
+ ok = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if (0 == ok) {
+ dk4uc2l_close(back);
+ back = NULL;
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ }
+ }
+ } $? "- dk4uc2l_create PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/** Handler function for text lines.
+ @param obj Object to modify while processing the character.
+ @param line Text line to process.
+ @param lineno Current line number.
+ @param erp Error report, may be NULL.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+dk4uc2l_fp_handler(
+ void *obj,
+ char *line,
+ dk4_um_t lineno,
+ dk4_er_t *erp
+)
+{
+ dkChar numbuf[16*sizeof(dk4_um_t)];
+ dk4_uc2l_range_t *rptr;
+ dk4_uc2l_range_t *rptrn;
+ dk4_uc2l_file_t *fptr;
+ dk4_uc2l_lhobj *lhobj;
+ dk4_app_t *app;
+ dk4_uc2l_t *ulptr;
+ char *p1;
+#if VERSION_BEFORE_20150821
+ char *p2;
+#endif
+ const char *p3;
+ dk4_um_t um;
+ dk4_c32_t c32;
+ dk4_c32_t c32a;
+ size_t sznumbuf;
+ int back = DK4_TSP_RES_OK;
+ int res = 0;
+ $? "+ dk4uc2l_fp_handler"
+
+ /* Obtain contents from object.
+ */
+ lhobj = (dk4_uc2l_lhobj *)obj;
+ ulptr = lhobj->ulptr;
+ app = lhobj->app;
+ dk4app_set_log_source_line(app, lineno);
+
+ /* Check for any text. Empty lines ok, comments ok.
+ */
+ p1 = dk4str8_start(line, NULL);
+ if (NULL == p1) { $? ". empty line"
+ goto finished;
+ }
+ if ('#' == *p1) { $? ". comment line"
+ goto finished;
+ }
+
+ /* Retrieve hexadecimal number.
+ */
+#if VERSION_BEFORE_20150821
+ p2 = dk4str8_next(p1, NULL);
+#else
+ (void)dk4str8_next(p1, NULL);
+#endif
+ um = (dk4_um_t)0UL;
+#if VERSION_BEFORE_20150821
+ p2 = NULL;
+#endif
+ p3 = NULL;
+ res = dk4ma_input_c8_hex_dk4_um_t(&um, p1, &p3, 1, NULL);
+ if (0 == res) { $? "! hex number"
+ back = DK4_TSP_RES_ERROR;
+ /* ERROR: Syntax, not a number */
+ dk4app_log_1(app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 0);
+ ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX;
+ goto finished;
+ } $? ". %lu", (unsigned long)um
+ c32 = (dk4_c32_t)um; $? ". 0x%lx", (unsigned long)um
+
+ /* Check numeric range.
+ */
+ if ((dk4_um_t)0xFFFFFFFFUL < um) { $? "! out of range"
+ back = DK4_TSP_RES_ERROR;
+ /* ERROR: Syntax, out of range */
+ dk4app_log_1(app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 1);
+ ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX;
+ goto finished;
+ }
+
+ /* Check whether number is already contained in a range.
+ */
+ rptr = (dk4_uc2l_range_t *)dk4sto_it_find_like(lhobj->i_r, &c32, 1);
+ if (NULL != rptr) { $? "! already defined"
+ $? ". start %lu end %lu char %lu", (unsigned long)(rptr->start), (unsigned long)(rptr->end), (unsigned long)c32
+ back = DK4_TSP_RES_ERROR;
+ /* ERROR: Already defined */
+ sznumbuf = DK4_SIZEOF(numbuf,dkChar);
+ if (0 != dk4ma_write_hex_unsigned(numbuf,sznumbuf,(dk4_um_t)c32,8,NULL)) {
+ dk4app_log_3(app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 2, 3, numbuf);
+ } else {
+ dk4app_log_1(app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 4);
+ }
+ ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX;
+ goto finished;
+ }
+ rptr = (dk4_uc2l_range_t *)dk4sto_it_find_like(ulptr->i_ranges, &c32, 1);
+ if (NULL != rptr) { $? "! already defined"
+ back = DK4_TSP_RES_ERROR;
+ /* ERROR: Already defined */
+ sznumbuf = DK4_SIZEOF(numbuf,dkChar);
+ if (0 != dk4ma_write_hex_unsigned(numbuf,sznumbuf,(dk4_um_t)c32,8,NULL)) {
+ dk4app_log_3(app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 2, 3, numbuf);
+ } else {
+ dk4app_log_1(app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 4);
+ }
+ ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX;
+ goto finished;
+ }
+
+ /* Check whether we can append to an existing range.
+ */
+ if (dkC32(0) < c32) {
+ c32a = c32 - dkC32(1);
+ rptr = (dk4_uc2l_range_t *)dk4sto_it_find_like(lhobj->i_r, &c32a, 1);
+ if (NULL != rptr) {
+ rptr->end = c32; $? ". extend existing range"
+ /* Also check if c32 closes a gap between two ranges.
+ */
+ if (dkC32(0xFFFFFFFF) > c32) {
+ c32a = c32 + dkC32(1);
+ rptrn = (dk4_uc2l_range_t *)dk4sto_it_find_like(lhobj->i_r, &c32a, 1);
+ if (NULL != rptrn) { $? ". close gap"
+ c32a = rptrn->end;
+ dk4sto_remove(lhobj->s_r, rptrn, NULL);
+ rptr->end = c32a;
+ }
+ }
+ goto finished;
+ }
+ }
+
+ /* Check whether we can prepend before an existing range.
+ */
+ if (dkC32(0xFFFFFFFF) > c32) {
+ c32a = c32 + dkC32(1);
+ rptr = (dk4_uc2l_range_t *)dk4sto_it_find_like(lhobj->i_r, &c32a, 1);
+ if (NULL != rptr) { $? ". extend existing range"
+ rptr->start = c32;
+ goto finished;
+ }
+ }
+
+ /* Create a new range.
+ */ $? ". create new range"
+ fptr = (dk4_uc2l_file_t *)dk4sto_it_find_like(ulptr->i_files, lhobj->sfn, 1);
+ if (NULL == fptr) {
+ fptr = dk4uc2l_file_open(lhobj->sfn, app);
+ if (NULL != fptr) {
+ if (0 == dk4sto_add(ulptr->s_files, fptr, NULL)) {
+ dk4uc2l_file_close(fptr); $? "! memory"
+ fptr = NULL;
+ }
+ }
+ }
+ if (NULL == fptr) { $? "! memory"
+ back = DK4_TSP_RES_ERROR;
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ ulptr->had_error |= DK4_UC2L_ERROR_MEMORY;
+ goto finished;
+ }
+ rptr = dk4uc2l_range_open(c32, fptr, app);
+ if (NULL != rptr) {
+ if (0 == dk4sto_add(lhobj->s_r, rptr, NULL)) {
+ dk4uc2l_range_close(rptr); $? "! memory"
+ rptr = NULL;
+ back = DK4_TSP_RES_ERROR;
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ }
+ } else { $? "! memory"
+ back = DK4_TSP_RES_ERROR;
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ ulptr->had_error |= DK4_UC2L_ERROR_MEMORY;
+ } $? ". success"
+
+ finished:
+ $? "- dk4uc2l_fp_handler %d", back
+ return back;
+}
+
+
+
+/** Report an error with position in source line.
+ @param ulptr Conversion structure.
+ @param i1 Index of first message part in array.
+ @param i2 Index of alternative first message part.
+ @param bno Byte processed.
+ @param lno Current line number.
+ @param cno Current character number.
+ @param cil Current character number in line.
+*/
+static
+void
+dk4uc2l_report_with_pos(
+ dk4_uc2l_t *ulptr,
+ dk4_app_t *app,
+ size_t i1,
+ size_t i2,
+ dk4_um_t bno,
+ dk4_um_t lno,
+ dk4_um_t cno,
+ dk4_um_t cil
+)
+{
+ dkChar b1[8*(1+sizeof(dk4_um_t))];
+ dkChar b2[8*(1+sizeof(dk4_um_t))];
+ dkChar b3[8*(1+sizeof(dk4_um_t))];
+ dk4_um_t oldlogline = (dk4_um_t)0UL;
+ int allbuffersok = 0;
+
+ oldlogline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_line(app, lno);
+ if (0 != dk4ma_write_decimal_unsigned(b3,DK4_SIZEOF(b3,dkChar),cil,0,NULL)) {
+ if (0 != dk4ma_write_decimal_unsigned(b2,DK4_SIZEOF(b2,dkChar),cno,0,NULL)) {
+ if (0 != dk4ma_write_decimal_unsigned(b1,DK4_SIZEOF(b1,dkChar),bno,0,NULL)) {
+ allbuffersok = 1;
+ }
+ }
+ }
+ if (0 != allbuffersok) {
+ dk4app_log_7(
+ app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, i1, 19, 20, 21, b1, b2, b3
+ );
+ } else {
+ dk4app_log_1(
+ app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, i2
+ );
+ }
+ dk4app_set_log_source_line(app, oldlogline);
+}
+
+
+
+static
+void
+dk4uc2l_report_errors(
+ dk4_uc2l_t *ulptr,
+ dk4_app_t *app,
+ dk4_uc2l_lhobj *obj,
+ dk4_er_t *er_en,
+ dk4_er_t *er_pr
+)
+{
+ if (NULL != er_en) {
+ switch (er_en->ec) {
+ case DK4_E_DECODING_FAILED: {
+ switch (obj->e_d) {
+ case 0: case 1: {
+ dk4uc2l_report_with_pos(
+ ulptr, app, 16, 22,
+ er_en->dt.fpos.byteno,
+ er_en->dt.fpos.lineno,
+ er_en->dt.fpos.charno,
+ er_en->dt.fpos.charinline
+ );
+ } break;
+ case 2: {
+ dk4app_log_1(
+ app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 25
+ );
+ } break;
+ }
+ if (3 > obj->e_d) { obj->e_d += 1; }
+ } break;
+ case DK4_E_ENCODING_FAILED: {
+ switch (obj->e_e) {
+ case 0: case 1: {
+ dk4uc2l_report_with_pos(
+ ulptr, app, 17, 23,
+ er_en->dt.fpos.byteno,
+ er_en->dt.fpos.lineno,
+ er_en->dt.fpos.charno,
+ er_en->dt.fpos.charinline
+ );
+ } break;
+ case 2: {
+ dk4app_log_1(
+ app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 26
+ );
+ } break;
+ }
+ if (3 > obj->e_e) { obj->e_e += 1; }
+ } break;
+ }
+ }
+ if (NULL != er_pr) {
+ if (DK4_E_NONE != er_pr->ec) {
+ switch (obj->e_p) {
+ case 0: case 1: {
+ dk4uc2l_report_with_pos(
+ ulptr, app, 18, 24,
+ er_pr->dt.fpos.byteno,
+ er_pr->dt.fpos.lineno,
+ er_pr->dt.fpos.charno,
+ er_pr->dt.fpos.charinline
+ );
+ } break;
+ case 2: {
+ dk4app_log_1(
+ app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 27
+ );
+ } break;
+ }
+ if (3 > obj->e_p) { obj->e_p += 1; }
+ }
+ }
+}
+
+
+
+/** Process data from a stream.
+ @param ulptr Conversion structure.
+ @param rstrm Stream to read data from.
+ @param sfn Short file name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4uc2l_fp_process_stream(
+ dk4_uc2l_t *ulptr,
+ dk4_stream_t *rstrm,
+ const dkChar *sfn,
+ dk4_app_t *app
+)
+{
+ char buf[256]; /* Line buffer */
+ dk4_tsp08_t tsp08; /* Text stream processor */
+ dk4_er_t er; /* General error report */
+ dk4_er_t er_en; /* Error report for decoding/encoding */
+ dk4_er_t er_pr; /* Error report for processing */
+ dk4_uc2l_lhobj obj; /* Processing object */
+ dk4_uc2l_range_t *rptr; /* Range to append to */
+ int back = 1;
+ int res; /* Line processing result */
+ int cc; /* Flag: Can continue */
+ char c; /* Current character */
+ $? "+ dk4uc2l_fp_process_stream"
+ dk4error_init(&er);
+ dk4error_init(&er_en);
+ dk4error_init(&er_pr);
+ obj.ulptr = ulptr;
+ obj.app = app;
+ obj.sfn = sfn;
+ obj.e_d = 0;
+ obj.e_e = 0;
+ obj.e_p = 0;
+ obj.s_r = dk4sto_open(NULL);
+ if (NULL != obj.s_r) {
+ dk4sto_set_comp(obj.s_r, dk4uc2l_range_compare, 0);
+ obj.i_r = dk4sto_it_open(obj.s_r, NULL);
+ if (NULL != obj.i_r) {
+ res = dk4tsp08_setup_line(
+ &tsp08, (void *)(&obj), dk4uc2l_fp_handler, buf, sizeof(buf),
+ DK4_ENCODING_ASCII, DK4_ENCODING_ASCII, &er
+ );
+ if (0 != res) {
+ cc = 1;
+ while (1 == cc) {
+ res = dk4stream_c8_read_byte(&c, rstrm, &er);
+ if (0 != res) {
+ res = dk4tsp08_add_one_byte(&tsp08, (unsigned char)c);
+ switch (res) {
+ case DK4_TSP_RES_ERROR: {
+ back = 0;
+ dk4tsp08_get_errors(&er_en, &er_pr, &tsp08);
+ /* Report errors */
+ dk4uc2l_report_errors(ulptr, app, &obj, &er_en, &er_pr);
+ dk4error_init(&er_en);
+ dk4error_init(&er_pr);
+ ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING;
+ } break;
+ case DK4_TSP_RES_FATAL: {
+ back = 0;
+ cc = -1;
+ dk4tsp08_get_errors(&er_en, &er_pr, &tsp08);
+ /* Report errors */
+ dk4uc2l_report_errors(ulptr, app, &obj, &er_en, &er_pr);
+ dk4error_init(&er_en);
+ dk4error_init(&er_pr);
+ ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING;
+ } break;
+ }
+ } else {
+ cc = 0;
+ }
+ }
+ if (0 == cc) {
+ res = dk4tsp08_finish(&tsp08);
+ switch (res) {
+ case DK4_TSP_RES_ERROR: case DK4_TSP_RES_FATAL: {
+ back = 0;
+ dk4tsp08_get_errors(&er_en, &er_pr, &tsp08);
+ /* Report errors */
+ dk4uc2l_report_errors(ulptr, app, &obj, &er_en, &er_pr);
+ ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING;
+ } break;
+ }
+ }
+ } else {
+ /* ERROR: Failed to set up text processing */
+ dk4app_log_1(app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 5);
+ ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING;
+ }
+ /*
+ Move range descriptions from local storage to global storage.
+ */
+ dk4sto_it_reset(obj.i_r);
+ do {
+ rptr = (dk4_uc2l_range_t *)dk4sto_it_next(obj.i_r);
+ if (NULL != rptr) {
+ if (0 == dk4sto_add(ulptr->s_ranges, rptr, NULL)) {
+ back = 0;
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ dk4uc2l_range_close(rptr);
+ }
+ }
+ } while (NULL != rptr);
+ dk4sto_it_close(obj.i_r);
+ } else {
+ back = 0;
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ ulptr->had_error |= DK4_UC2L_ERROR_MEMORY;
+ }
+ dk4sto_close(obj.s_r);
+ obj.s_r = NULL;
+ } else {
+ back = 0;
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ ulptr->had_error |= DK4_UC2L_ERROR_MEMORY;
+ }
+
+ $? "- dk4uc2l_fp_process_stream %d", back
+ return back;
+}
+
+
+
+/** Process one data file in the first pass.
+ @param ulptr Conversion structure.
+ @param fn Full file name.
+ @param sfn Short file name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4uc2l_fp_process_file_name(
+ dk4_uc2l_t *ulptr,
+ const dkChar *fn,
+ const dkChar *sfn,
+ dk4_app_t *app
+)
+{
+ dk4_er_t er; /* Error report */
+ dk4_stream_t *rstrm; /* Stream to read file */
+ const dkChar *oldsourcefile; /* Previous source file */
+ dk4_um_t oldsourceline; /* Previous source line */
+ size_t fnl; /* File name length */
+ size_t fns; /* Suffix length */
+ size_t i; /* Traverse suffix list */
+ int back = 1;
+ int done = 0; /* Flag: Attempted to open file */
+ $? "+ dk4uc2l_fp_process_file_name \"%!ds\"", fn
+ fnl = dk4str_len(fn);
+ for (i = 4; ((i < 7) && (0 == done)); i++) { $? ". i = %u", (unsigned)i
+ fns = dk4str_len(dk4uc2l_kwnl[i]);
+ if (fnl > fns) { $? ". file name long enough"
+ if (0 == dk4str_pathcmp(&(fn[fnl - fns]), dk4uc2l_kwnl[i])) {
+ done = 1; $? ". suffix ok"
+ dk4error_init(&er);
+ rstrm = dk4stream_open_file_reader(fn, &er);
+ if (NULL != rstrm) { $? ". stream ok"
+ oldsourcefile = dk4app_get_log_source_file(app);
+ oldsourceline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_file(app, fn);
+ dk4app_set_log_source_line(app, (dk4_um_t)0UL);
+ back = dk4uc2l_fp_process_stream(ulptr, rstrm, sfn, app);
+ dk4app_set_log_source_file(app, oldsourcefile);
+ dk4app_set_log_source_line(app, oldsourceline);
+ dk4stream_close(rstrm, NULL);
+ } else { $? "! stream"
+ back = 0;
+ /* ERROR: Failed to open file */
+ dk4app_log_3(app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 6, 7, fn);
+ ulptr->had_error |= DK4_UC2L_ERROR_FOPEN;
+ }
+ } else { $? "! invalid suffix"
+ }
+ } else { $? "! file name too short"
+ }
+ }
+ $? "- dk4uc2l_fp_process_file_name %d", back
+ return back;
+}
+
+
+
+/** First pass to fill information to the structure,
+ obtain information which character is handled by which file.
+ @param ulptr New structure to fill with data.
+ @param app Application structure for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4uc2l_first_pass(dk4_uc2l_t *ulptr, dk4_app_t *app)
+{
+ dkChar fnb[DK4_MAX_PATH]; /* File name buffer */
+ const dkChar *pth = NULL; /* Path for directory */
+ const dkChar *fn = NULL; /* Current file to process */
+ dk4_dir_t *dir = NULL; /* Traverse the directory */
+ int back = 0;
+ $? "+ dk4uc2l_first_pass"
+ dir = dk4dir_open_app(ulptr->dname, 0, app);
+ if (NULL != dir) {
+ back = 1;
+ do {
+ fn = dk4dir_next_file(dir);
+ if (NULL != fn) {
+ pth = dk4dir_get_path(dir);
+ if (NULL != pth) {
+ if (dk4str_cpy_s(fnb,DK4_SIZEOF(fnb,dkChar),pth,NULL)) {
+ if (dk4str_cat_s(fnb,DK4_SIZEOF(fnb,dkChar),dk4uc2l_kwnl[7],NULL)) {
+ if (dk4str_cat_s(fnb,DK4_SIZEOF(fnb,dkChar),fn,NULL)) {
+ dk4path_correct_sep(fnb);
+ if (0 == dk4uc2l_fp_process_file_name(ulptr, fnb, fn, app)) {
+ back = 0;
+ }
+ } else {
+ back = 0;
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING;
+ }
+ } else {
+ back = 0;
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING;
+ }
+ } else {
+ back = 0;
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, pth);
+ ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING;
+ }
+ } else {
+ if (0 == dk4uc2l_fp_process_file_name(ulptr, fn, fn, app)) {
+ back = 0;
+ }
+ }
+ }
+ } while (NULL != fn);
+ dk4dir_close(dir);
+ } else {
+ /* ERROR: Failed to open directory */
+ ulptr->had_error |= DK4_UC2L_ERROR_FOPEN;
+ } $? "- dk4uc2l_first_pass %d", back
+ return back;
+}
+
+
+
+static
+void
+dk4uc2l_initialize_range(
+ dk4_uc2l_t *ulptr,
+ dk4_uc2l_range_t *rptr,
+ dk4_app_t *app
+)
+{
+ dk4_er_t er;
+ size_t nelem;
+ size_t i;
+ int errmem;
+ dk4error_init(&er);
+ nelem = dk4ma_size_t_add(
+ dk4ma_size_t_sub((size_t)(rptr->end), (size_t)(rptr->start), &er),
+ (size_t)1U,
+ &er
+ );
+ if (DK4_E_NONE == er.ec) {
+ errmem = 0;
+ rptr->both = dk4mem_new_app(dk4_uc2l_char_ptr,nelem,app);
+ if (NULL != rptr->both) {
+ for (i = 0; i < nelem; i++) { (rptr->both)[i] = NULL; }
+ } else { errmem = 1; }
+ rptr->text = dk4mem_new_app(dk4_uc2l_char_ptr,nelem,app);
+ if (NULL != rptr->text) {
+ for (i = 0; i < nelem; i++) { (rptr->text)[i] = NULL; }
+ } else { errmem = 1; }
+ rptr->math = dk4mem_new_app(dk4_uc2l_char_ptr,nelem,app);
+ if (NULL != rptr->math) {
+ for (i = 0; i < nelem; i++) { (rptr->math)[i] = NULL; }
+ } else { errmem = 1; }
+ rptr->pkgs = dk4mem_new_app(dk4_uc2l_pkg_ptr_ptr, nelem, app);
+ if (NULL != rptr->pkgs) {
+ for (i = 0; i < nelem; i++) { (rptr->pkgs)[i] = NULL; }
+ } else { errmem = 1; }
+ rptr->fenc = dk4mem_new_app(unsigned char,nelem,app);
+ if (NULL != rptr->fenc) {
+ for (i = 0; i < nelem; i++) {
+ (rptr->fenc)[i] = (unsigned char)DK4_UC2L_FONT_ENCODING_ALL;
+ }
+ } else { errmem = 1; }
+ if (0 != errmem) {
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ ulptr->had_error |= DK4_UC2L_ERROR_MEMORY;
+ }
+ }
+}
+
+
+
+/** Handler function for text lines.
+ @param obj Object to modify while processing the character.
+ @param line Text line to process.
+ @param lineno Current line number.
+ @param erp Error report, may be NULL.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+dk4uc2l_sp_handler(
+ void *obj,
+ char *line,
+ dk4_um_t lineno,
+ dk4_er_t *erp
+)
+{
+ dkChar numbuf[16*sizeof(dk4_um_t)];
+ dk4_er_t er; /* Error report */
+ dk4_uc2l_lhobj *lhobj; /* Handler object */
+ dk4_app_t *app; /* Application */
+ dk4_uc2l_range_t *rptr; /* Current range to modify */
+ dk4_uc2l_pkg_t *pkgptr; /* Current package to create */
+ dk4_uc2l_t *ulptr; /* Conversion structure */
+ char *pkgn[16]; /* Package names */
+ char *p1; /* Attribute name */
+ char *p2; /* Next attribute to process */
+ char *p4; /* Value, current value part */
+ char *p5; /* Next value part */
+ const char *pe; /* End of text when reading number */
+ dk4_um_t um; /* Number read at start of line */
+ size_t sznumbuf; /* Buffer size */
+ size_t ind; /* Index of current char in range */
+ size_t numpkg; /* Number of package names found */
+ size_t i; /* Current package index */
+ dk4_c32_t c32; /* Current character to configure */
+ int numres; /* Number conversion result */
+ int encadd; /* Flag: Add font encodings */
+ int res; /* Operation result */
+ int back = DK4_TSP_RES_OK;
+ $? "+ dk4uc2l_sp_handler"
+ /*
+ Set variables.
+ */
+ lhobj = (dk4_uc2l_lhobj *)obj;
+ ulptr = lhobj->ulptr;
+ app = lhobj->app;
+ dk4app_set_log_source_line(app, lineno);
+
+ /*
+ Skip empty lines and comments.
+ */
+ p1 = dk4str8_start(line, NULL);
+ if (NULL == p1) {
+ goto finished;
+ }
+ if ('#' == *p1) {
+ goto finished;
+ }
+ p2 = dk4str8_next(p1, NULL);
+
+ /*
+ Retrieve character number.
+ */
+ um = (dk4_um_t)0UL;
+ pe = NULL;
+ res = dk4ma_input_c8_hex_dk4_um_t(&um, p1, &pe, 1, NULL);
+ if (0 == res) {
+ back = DK4_TSP_RES_ERROR;
+ /* ERROR: Syntax, not a number, already reported in first pass. */
+ ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX;
+ goto finished;
+ }
+ c32 = (dk4_c32_t)um;
+ if ((dk4_um_t)0xFFFFFFFFUL < um) {
+ back = DK4_TSP_RES_ERROR;
+ /* ERROR: Syntax, out of range, already reported in first pass. */
+ ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX;
+ goto finished;
+ }
+
+ /*
+ Find range.
+ */
+ rptr = (dk4_uc2l_range_t *)dk4sto_it_find_like(ulptr->i_ranges, &c32, 1);
+ if (NULL == rptr) {
+ back = DK4_TSP_RES_ERROR;
+ /* ERROR: Bug, range not found, must be memory problem reported in pass 1 */
+ ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING;
+ goto finished;
+ }
+
+ /*
+ Initialize range if not yet done.
+ */
+ if (0x00 == rptr->ia) {
+ rptr->ia = 0x01;
+ dk4uc2l_initialize_range(ulptr, rptr, app);
+ }
+
+ ind = (size_t)(c32 - rptr->start);
+ p1 = p2;
+ while (NULL != p1) {
+ p2 = dk4str8_next(p1, NULL);
+ p4 = dk4str8_chr(p1, '=');
+ if (NULL != p4) {
+ *(p4++) = '\0';
+ p4 = dk4str8_start(p4, NULL);
+ if (NULL != p4) {
+ switch (dk4str8_abbr_index(dk4uc2l_attribute_names, '$', p1, 0)) {
+ case 0: { /* both */
+ if (NULL != rptr->both) {
+ if (NULL == (rptr->both)[ind]) {
+ (rptr->both)[ind] = dk4str8_dup(p4, NULL);
+ if (NULL == (rptr->both)[ind]) {
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ ulptr->had_error |= DK4_UC2L_ERROR_MEMORY;
+ }
+ } else {
+ /* ERROR: Already defined, reported in first pass */
+ sznumbuf = DK4_SIZEOF(numbuf,dkChar);
+ numres = dk4ma_write_hex_unsigned(
+ numbuf, sznumbuf, (dk4_um_t)c32, 8, NULL
+ );
+ if (0 != numres) {
+ dk4app_log_3(
+ app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 2, 3, numbuf
+ );
+ } else {
+ dk4app_log_1(app,ulptr->msgs,ulptr->szmsgs,DK4_LL_ERROR,4);
+ }
+ ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX;
+ }
+ } else {
+ /* ERROR */
+ ulptr->had_error |= DK4_UC2L_ERROR_MEMORY;
+ }
+ } break;
+ case 1: { /* text */
+ if (NULL != rptr->text) {
+ if (NULL == (rptr->text)[ind]) {
+ (rptr->text)[ind] = dk4str8_dup(p4, NULL);
+ if (NULL == (rptr->text)[ind]) {
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ ulptr->had_error |= DK4_UC2L_ERROR_MEMORY;
+ }
+ } else {
+ /* ERROR: Already defined, reported in first pass */
+ sznumbuf = DK4_SIZEOF(numbuf,dkChar);
+ numres = dk4ma_write_hex_unsigned(
+ numbuf, sznumbuf, (dk4_um_t)c32, 8, NULL
+ );
+ if (0 != numres) {
+ dk4app_log_3(
+ app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 2, 3, numbuf
+ );
+ } else {
+ dk4app_log_1(app,ulptr->msgs,ulptr->szmsgs,DK4_LL_ERROR,4);
+ }
+ ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX;
+ }
+ } else {
+ /* ERROR */
+ ulptr->had_error |= DK4_UC2L_ERROR_MEMORY;
+ }
+ } break;
+ case 2: { /* math */
+ if (NULL != rptr->math) {
+ if (NULL == (rptr->math)[ind]) {
+ (rptr->math)[ind] = dk4str8_dup(p4, NULL);
+ if (NULL == (rptr->math)[ind]) {
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ ulptr->had_error |= DK4_UC2L_ERROR_MEMORY;
+ }
+ } else {
+ /* ERROR: Already defined */
+ sznumbuf = DK4_SIZEOF(numbuf,dkChar);
+ numres = dk4ma_write_hex_unsigned(
+ numbuf, sznumbuf, (dk4_um_t)c32, 8, NULL
+ );
+ if (0 != numres) {
+ dk4app_log_3(
+ app, ulptr->msgs,ulptr->szmsgs, DK4_LL_ERROR, 2, 3, numbuf
+ );
+ } else {
+ dk4app_log_1(app,ulptr->msgs,ulptr->szmsgs,DK4_LL_ERROR,4);
+ }
+ ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX;
+ }
+ } else {
+ /* ERROR */
+ ulptr->had_error |= DK4_UC2L_ERROR_MEMORY;
+ }
+ } break;
+ case 3: { /* encoding */
+ encadd = 1;
+ if (NULL != rptr->fenc) {
+ if ('!' == *p4) {
+ p4++;
+ encadd = 0;
+ (rptr->fenc)[ind] = (unsigned char)DK4_UC2L_FONT_ENCODING_ALL;
+ } else {
+ (rptr->fenc)[ind] = 0x00;
+ }
+ while (NULL != p4) {
+ p5 = dk4str8_chr(p4, ',');
+ if (NULL != p5) { *(p5++) = '\0'; }
+ switch (dk4str8_array_index(dk4uc2l_font_encodings, p4, 0)) {
+ case 0: { /* OT1 */
+ if (0 != encadd) {
+ (rptr->fenc)[ind] |=
+ (unsigned char)DK4_UC2L_FONT_ENCODING_OT1;
+ } else {
+ (rptr->fenc)[ind] &=
+ (~((unsigned char)DK4_UC2L_FONT_ENCODING_OT1));
+ }
+ } break;
+ case 1: { /* T1 */
+ if (0 != encadd) {
+ (rptr->fenc)[ind] |=
+ (unsigned char)DK4_UC2L_FONT_ENCODING_T1;
+ } else {
+ (rptr->fenc)[ind] &=
+ (~((unsigned char)DK4_UC2L_FONT_ENCODING_T1));
+ }
+ } break;
+ case 2: { /* T4 */
+ if (0 != encadd) {
+ (rptr->fenc)[ind] |=
+ (unsigned char)DK4_UC2L_FONT_ENCODING_T4;
+ } else {
+ (rptr->fenc)[ind] &=
+ (~((unsigned char)DK4_UC2L_FONT_ENCODING_T4));
+ }
+ } break;
+ case 3: { /* T5 */
+ if (0 != encadd) {
+ (rptr->fenc)[ind] |=
+ (unsigned char)DK4_UC2L_FONT_ENCODING_T5;
+ } else {
+ (rptr->fenc)[ind] &=
+ (~((unsigned char)DK4_UC2L_FONT_ENCODING_T5));
+ }
+ } break;
+ default : {
+ /* ERROR: Syntax, undefined encoding */
+ dk4app_log_1(app,ulptr->msgs,ulptr->szmsgs,DK4_LL_ERROR,8);
+ ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX;
+ } break;
+ }
+ p4 = p5;
+ }
+ } else {
+ /* ERROR */
+ }
+ } break;
+ case 4: { /* packages */
+ dk4error_init(&er);
+ numpkg = dk4str8_tokenize(pkgn, 16, p4, ",", &er);
+ if (0 < numpkg) {
+ if (NULL != rptr->pkgs) {
+ if (NULL == (rptr->pkgs)[ind]) {
+ (rptr->pkgs)[ind] =
+ dk4mem_new_app(dk4_uc2l_pkg_ptr,(numpkg+1),app);
+ if (NULL != (rptr->pkgs)[ind]) {
+ for (i = 0; i <= numpkg; i++) {
+ ((rptr->pkgs)[ind])[i] = NULL;
+ }
+ for (i = 0; i < numpkg; i++) {
+ pkgptr = (dk4_uc2l_pkg_t *)dk4sto_it_find_like(
+ ulptr->i_pkgs, pkgn[i], 1
+ );
+ if (NULL != pkgptr) {
+ ((rptr->pkgs)[ind])[i] = pkgptr;
+ } else {
+ pkgptr = dk4uc2l_pkg_open(pkgn[i], app);
+ if (NULL != pkgptr) {
+ if (0 == dk4sto_add(ulptr->s_pkgs, pkgptr, NULL)) {
+ dk4uc2l_pkg_close(pkgptr);
+ pkgptr = NULL;
+ }
+ }
+ if (NULL != pkgptr) {
+ ((rptr->pkgs)[ind])[i] = pkgptr;
+ } else {
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ ulptr->had_error |= DK4_UC2L_ERROR_MEMORY;
+ }
+ }
+ }
+ } else {
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ ulptr->had_error |= DK4_UC2L_ERROR_MEMORY;
+ }
+ } else {
+ /* ERROR: Redefinition */
+ sznumbuf = DK4_SIZEOF(numbuf,dkChar);
+ numres = dk4ma_write_hex_unsigned(
+ numbuf, sznumbuf, (dk4_um_t)c32, 8, NULL
+ );
+ if (0 != numres) {
+ dk4app_log_3(
+ app, ulptr->msgs,ulptr->szmsgs, DK4_LL_ERROR, 2, 3, numbuf
+ );
+ } else {
+ dk4app_log_1(app,ulptr->msgs,ulptr->szmsgs,DK4_LL_ERROR,4);
+ }
+ ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX;
+ }
+ } else {
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ ulptr->had_error |= DK4_UC2L_ERROR_MEMORY;
+ }
+ } else {
+ /* ERROR Syntax */
+ dk4app_log_1(app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 9);
+ ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX;
+ }
+ } break;
+ default: {
+ /* ERROR: Syntax error */
+ dk4app_log_1(app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 10);
+ ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX;
+ } break;
+ }
+ } else {
+ /* ERROR: Syntax */
+ dk4app_log_1(app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 11);
+ ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX;
+ }
+ } else {
+ /* ERROR: Syntax */
+ dk4app_log_1(app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 11);
+ ulptr->had_error |= DK4_UC2L_ERROR_SYNTAX;
+ }
+ p1 = p2;
+ }
+
+ finished:
+ $? "- dk4uc2l_sp_handler %d", back
+ return back;
+}
+
+
+
+static
+void
+dk4uc2l_sp_process_stream(
+ dk4_uc2l_t *ulptr,
+ dk4_stream_t *rstrm,
+ const dkChar *fnb,
+ dk4_app_t *app
+)
+{
+ char buf[256]; /* Line buffer */
+ dk4_uc2l_lhobj obj; /* Processing object */
+ dk4_tsp08_t tsp08; /* Text stream processor */
+ dk4_er_t er; /* General error report */
+ dk4_er_t er_en; /* Error report encoding/decoding */
+ dk4_er_t er_pr; /* Error report processing */
+ int res; /* Operation result */
+ int cc; /* Flag: Can continue */
+ char c; /* Current character to process */
+
+ obj.ulptr = ulptr;
+ obj.app = app;
+ obj.sfn = fnb;
+ obj.e_d = 0;
+ obj.e_e = 0;
+ obj.e_p = 0;
+ dk4error_init(&er);
+ dk4error_init(&er_en);
+ dk4error_init(&er_pr);
+ res = dk4tsp08_setup_line(
+ &tsp08, (void *)(&obj), dk4uc2l_sp_handler, buf, sizeof(buf),
+ DK4_ENCODING_ASCII, DK4_ENCODING_ASCII, &er
+ );
+ if (0 != res) {
+ cc = 1;
+ while (1 == cc) {
+ res = dk4stream_c8_read_byte(&c, rstrm, &er);
+ if (0 != res) {
+ res = dk4tsp08_add_one_byte(&tsp08, (unsigned char)c);
+ switch (res) {
+ case DK4_TSP_RES_ERROR: {
+ dk4tsp08_get_errors(&er_en, &er_pr, &tsp08);
+ /* Report errors */
+ dk4uc2l_report_errors(ulptr, app, &obj, &er_en, &er_pr);
+ dk4error_init(&er_en);
+ dk4error_init(&er_pr);
+ ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING;
+ } break;
+ case DK4_TSP_RES_FATAL: {
+ cc = -1;
+ dk4tsp08_get_errors(&er_en, &er_pr, &tsp08);
+ /* Report errors */
+ dk4uc2l_report_errors(ulptr, app, &obj, &er_en, &er_pr);
+ dk4error_init(&er_en);
+ dk4error_init(&er_pr);
+ ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING;
+ } break;
+ }
+ } else {
+ cc = 0;
+ }
+ }
+ if (0 == cc) {
+ res = dk4tsp08_finish(&tsp08);
+ switch (res) {
+ case DK4_TSP_RES_ERROR: case DK4_TSP_RES_FATAL: {
+ dk4tsp08_get_errors(&er_en, &er_pr, &tsp08);
+ /* Report errors */
+ dk4uc2l_report_errors(ulptr, app, &obj, &er_en, &er_pr);
+ ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING;
+ } break;
+ }
+ }
+ } else {
+ ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING;
+ }
+}
+
+
+
+/** Attempt to load one data file if not yet loaded.
+ @param ulptr Conversion structure.
+ @param rptr Pointer to range causing the attempt to load.
+ @param app Application structure for diagnostics, may be NULL.
+*/
+static
+void
+dk4uc2l_load_if_not_yet_done(
+ dk4_uc2l_t *ulptr,
+ dk4_uc2l_range_t *rptr,
+ dk4_app_t *app
+)
+{
+ dkChar fnb[DK4_MAX_PATH];
+ dk4_er_t er;
+ const dkChar *oldsourcefile;
+ dk4_uc2l_file_t *fptr;
+ dk4_stream_t *rstrm;
+ dk4_um_t oldsourceline;
+ size_t fnbsz;
+ $? "+ dk4uc2l_load_if_not_yet_done"
+ fptr = rptr->file;
+ if (NULL != fptr) { $? ". fptr"
+ if (0x00 == fptr->loaded) { $? ". must load"
+ fptr->loaded = 0x01;
+ fnbsz = DK4_SIZEOF(fnb, dkChar);
+ if (0 != dk4str_cpy_s(fnb, fnbsz, ulptr->dname, NULL)) {
+ if (0 != dk4str_cat_s(fnb, fnbsz, dk4uc2l_kwnl[7], NULL)) {
+ if (0 != dk4str_cat_s(fnb, fnbsz, fptr->fn, NULL)) {
+ dk4path_correct_sep(fnb);
+ dk4error_init(&er);
+ rstrm = dk4stream_open_file_reader(fnb, &er);
+ if (NULL != rstrm) {
+ oldsourcefile = dk4app_get_log_source_file(app);
+ oldsourceline = dk4app_get_log_source_line(app);
+ dk4app_set_log_source_file(app, fnb);
+ dk4app_set_log_source_line(app, (dk4_um_t)0UL);
+ dk4uc2l_sp_process_stream(ulptr, rstrm, fnb, app);
+ dk4app_set_log_source_file(app, oldsourcefile);
+ dk4app_set_log_source_line(app, oldsourceline);
+ dk4stream_close(rstrm, NULL);
+ } else { $? "! stream open"
+ /* ERROR: Failed to open file */
+ dk4app_log_3(
+ app, ulptr->msgs, ulptr->szmsgs, DK4_LL_ERROR, 6, 7, fnb
+ );
+ ulptr->had_error |= DK4_UC2L_ERROR_FOPEN;
+ }
+ } else { $? "! path too long"
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, ulptr->dname);
+ ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING;
+ }
+ } else { $? "! path too long"
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, ulptr->dname);
+ ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING;
+ }
+ } else { $? "! path too long"
+ /* ERROR: Path too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, ulptr->dname);
+ ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING;
+ }
+ } else { $? ". already loaded"
+ }
+ } else { $? "! fptr"
+ ulptr->had_error |= DK4_UC2L_ERROR_PROCESSING;
+ } $? "- dk4uc2l_load_if_not_yet_done"
+}
+
+
+
+const char *
+dk4uc2l_find(dk4_uc2l_t *ulptr, dk4_c32_t c, int mm, dk4_app_t *app)
+{
+ dkChar numbuf[16*sizeof(dk4_um_t)];
+ dk4_uc2l_range_t *rptr;
+ dk4_uc2l_pkg_t **pptr;
+ dk4_uc2l_pkg_t *xpptr;
+ const char *back = NULL;
+ size_t blgt;
+ size_t sznumbuf;
+ int numres;
+ $? "+ dk4uc2l_find %lx", (unsigned long)c
+ if (NULL != ulptr) {
+ /*
+ Attempt direct output.
+ */
+ if (0 != dk4uc2lat_direct(c)) {
+ ulptr->buf[0] = (char)c;
+ ulptr->buf[1] = '\0';
+ back = &(ulptr->buf[0]);
+ goto finished;
+ }
+
+ /*
+ Attempt to find output string in data.
+ */
+ rptr = (dk4_uc2l_range_t *)dk4sto_it_find_like(
+ ulptr->i_ranges, &c, 1
+ );
+ if (NULL != rptr) {
+ dk4uc2l_load_if_not_yet_done(ulptr, rptr, app);
+ if (0 != mm) {
+ if (NULL != rptr->math) {
+ back = (rptr->math)[(size_t)(c - rptr->start)];
+ }
+ if (NULL == back) {
+ if (NULL != rptr->both) {
+ back = (rptr->both)[(size_t)(c - rptr->start)];
+ }
+ }
+ } else {
+ if (NULL != rptr->text) {
+ back = (rptr->text)[(size_t)(c - rptr->start)];
+ }
+ if (NULL == back) {
+ if (NULL != rptr->both) {
+ back = (rptr->both)[(size_t)(c - rptr->start)];
+ }
+ }
+ }
+ if (NULL != back) {
+ if (NULL != rptr->fenc) {
+ ulptr->fallowed &= (rptr->fenc)[(size_t)(c - rptr->start)];
+ }
+ if (NULL != rptr->pkgs) {
+ if (NULL != (rptr->pkgs)[(size_t)(c - rptr->start)]) {
+ pptr = (rptr->pkgs)[(size_t)(c - rptr->start)];
+ while (NULL != *pptr) {
+ xpptr = *(pptr++);
+ xpptr->used = 0x01;
+ }
+ }
+ }
+ }
+ }
+ if (NULL != back) { goto finished; }
+
+ /*
+ If everything failed so far, attempt to use UTF-8 output
+ or direct output.
+ */
+ if (0 != mm) { goto finished; }
+ if (0x00 != ulptr->utf8allowed) {
+ blgt = 15;
+ if (0 != dk4utf8_encode((unsigned char *)(&(ulptr->buf[0])),&blgt,c,NULL))
+ {
+ ulptr->buf[blgt] = '\0';
+ back = &(ulptr->buf[0]);
+ }
+ else
+ {
+ /* ERROR: UTF-8 encoding failed */
+ sznumbuf = DK4_SIZEOF(numbuf,dkChar);
+ numres = dk4ma_write_hex_unsigned(
+ numbuf, sznumbuf, (dk4_um_t)c, 8, NULL
+ );
+ if (0 != numres) {
+ dk4app_log_3(
+ app, ulptr->msgs,ulptr->szmsgs, DK4_LL_ERROR, 12, 13, numbuf
+ );
+ } else {
+ dk4app_log_1(app,ulptr->msgs,ulptr->szmsgs,DK4_LL_ERROR,14);
+ }
+
+ }
+ } else {
+ if (dkC32(0x00000100) > c) {
+ ulptr->buf[0] = (char)c;
+ ulptr->buf[1] = '\0';
+ back = &(ulptr->buf[0]);
+ } else {
+ /* ERROR: No encoding found */
+ }
+ }
+ }
+ finished:
+ $? "- dk4uc2l_find PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+dk4_uc2l_t *
+dk4uc2l_open(const dkChar *dn, dk4_app_t *app)
+{
+ dk4_er_t er;
+ dk4_uc2l_t *back = NULL;
+ $? "+ dk4uc2l_open"
+ dk4error_init(&er);
+ if (NULL != dn) {
+ if (0 != dk4file_is_directory(dn, &er)) {
+ back = dk4uc2l_create(dn, app);
+ if (NULL != back) {
+ if (0 == dk4uc2l_first_pass(back, app)) {
+ dk4uc2l_close(back);
+ back = NULL;
+ }
+ }
+ } else {
+ /* ERROR: Not a directory */
+ dk4app_log_base3(app, DK4_LL_ERROR, 152, 153, dn);
+ }
+ } $? "- dk4uc2l_open PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+dk4_uc2l_t *
+dk4uc2l_open_from_app(dk4_app_t *app)
+{
+ dkChar fnb[DK4_MAX_PATH]; /* Buffer to construct name */
+ const dkChar * const *debmsg;
+ dk4_uc2l_t *back = NULL;
+ size_t i = 0; /* Traverse possible dirs */
+ size_t szdm = 0;
+ int done = 0; /* Flag: Attempted */
+ int toolo = 0; /* Flag: Name too long */
+ int res = 0; /* Operation result */
+ $? "+ dk4uc2l_open_from_app"
+ if (NULL != app) {
+ res = dk4app_pref_get(fnb,DK4_SIZEOF(fnb,dkChar),app,dk4uc2l_kwnl[0],0);
+ if (0 != res) {
+ dk4path_correct_sep(fnb);
+ if (0 != dk4file_is_directory(fnb, NULL)) {
+ done = 1;
+ back = dk4uc2l_open(fnb, app);
+ }
+ }
+ for (i = 1; i < 4; i++) {
+ if ((0 == done) && (NULL == back)) {
+ if (0 != dk4str_cpy_s(fnb,DK4_SIZEOF(fnb,dkChar),app->dir_share,NULL)) {
+ if (0 != dk4str_cat_s(fnb,DK4_SIZEOF(fnb,dkChar),dk4uc2l_kwnl[i],NULL))
+ {
+ dk4path_correct_sep(fnb);
+ if (0 != dk4file_is_directory(fnb, NULL)) {
+ done = 1;
+ back = dk4uc2l_open(fnb, app);
+ }
+ } else {
+ toolo = 1;
+ }
+ } else {
+ toolo = 1;
+ }
+ }
+ }
+ }
+ if (NULL == back) {
+ if (0 == done) {
+ if (0 != toolo) {
+ /* ERROR: shared directory name too long */
+ dk4app_log_base3(app, DK4_LL_ERROR, 98, 99, app->dir_share);
+ } else {
+ /* ERROR: No charmap directory found */
+ debmsg = dk4app_string_table(app, dk4uc2l_kwnl[8], dk4uc2l_kw_def);
+ szdm = dk4app_string_table_size(dk4uc2l_kw_def);
+ dk4app_log_1(app, debmsg, szdm, DK4_LL_ERROR, 15);
+ }
+ }
+ } $? "- dk4uc2l_open_from_app PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+void
+dk4uc2l_clean_packages_and_fonts(dk4_uc2l_t *ulptr)
+{
+ dk4_uc2l_pkg_t *pptr;
+ $? "+ dk4uc2l_clean_packages_and_fonts"
+ if (NULL != ulptr) {
+ ulptr->fallowed = DK4_UC2L_FONT_ENCODING_ALL;
+ dk4sto_it_reset(ulptr->i_pkgs);
+ do {
+ pptr = (dk4_uc2l_pkg_t *)dk4sto_it_next(ulptr->i_pkgs);
+ if (NULL != pptr) {
+ pptr->used = 0x00;
+ }
+ } while (NULL != pptr);
+ } $? "- dk4uc2l_clean_packages_and_fonts"
+}
+
+
+
+unsigned char
+dk4uc2l_retrieve_allowed_fe(dk4_uc2l_t *ulptr)
+{
+ unsigned char back = 0x00;
+ $? "+ dk4uc2l_retrieve_allowed_fe"
+ if (NULL != ulptr) {
+ back = ulptr->fallowed;
+ } $? "- dk4uc2l_retrieve_allowed_fe %u", (unsigned)back
+ return back;
+}
+
+
+
+void
+dk4uc2l_allow_utf8(dk4_uc2l_t *ulptr, int enabled)
+{
+ if (NULL != ulptr) {
+ ulptr->utf8allowed = ((0 != enabled) ? 0x01 : 0x00);
+ }
+}
+
+
+
+int
+dk4uc2lat_direct(dk4_c32_t c32)
+{
+ int back = 0;
+ char c; /* 8-bit character version of c32. */
+ $? "+ dk4uc2lat_direct %lx", (unsigned long)c32
+ if((unsigned long)c32 < 128UL) {
+ c = (char)c32;
+ switch(c) {
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
+ case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
+ case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u':
+ case 'v': case 'w': case 'x': case 'y': case 'z': case 'A': case 'B':
+ case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I':
+ case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P':
+ case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W':
+ case 'X': case 'Y': case 'Z': case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7': case '8': case '9': case ',':
+ case '.': case ':': case ';': case '+': case '-': case '?': case '!':
+ case '|': case '@': case '(': case ')': case '/': case '=': case ' ':
+ {
+ back = 1;
+ }
+ break;
+ }
+ } $? "- dk4uc2lat_direct %d", back
+ return back;
+}
+
+
+
+void
+dk4uc2l_recommendations(dk4_uc2l_t *ulptr, FILE *fipo)
+{
+ dk4_uc2l_pkg_t *pptr;
+ if ((NULL != ulptr) && (NULL != fipo)) {
+ fputs(dk4uc2l_kw8[0], fipo);
+ if (0x00 != (ulptr->fallowed & (unsigned char)DK4_UC2L_FONT_ENCODING_T1)) {
+ fputs(dk4uc2l_kw8[3], fipo);
+ }
+ if (0x00 != (ulptr->fallowed & (unsigned char)DK4_UC2L_FONT_ENCODING_OT1)) {
+ fputs(dk4uc2l_kw8[2], fipo);
+ }
+ if (0x00 != (ulptr->fallowed & (unsigned char)DK4_UC2L_FONT_ENCODING_T4)) {
+ fputs(dk4uc2l_kw8[4], fipo);
+ }
+ if (0x00 != (ulptr->fallowed & (unsigned char)DK4_UC2L_FONT_ENCODING_T5)) {
+ fputs(dk4uc2l_kw8[5], fipo);
+ }
+ fputc('\n', stdout);
+ dk4sto_it_reset(ulptr->i_pkgs);
+ do {
+ pptr = (dk4_uc2l_pkg_t *)dk4sto_it_next(ulptr->i_pkgs);
+ if (NULL != pptr) {
+ if (0x00 != pptr->used) {
+ fputs(dk4uc2l_kw8[1], fipo);
+ fputs(pptr->pn, fipo);
+ fputc('\n', fipo);
+ }
+ }
+ } while (NULL != pptr);
+ }
+}
+
+
+
+int
+dk4uc2l_retrieve_errors(dk4_uc2l_t *ulptr)
+{
+ int back = 0;
+ if (NULL != ulptr) {
+ back = ulptr->had_error;
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4uc2l.h b/support/dktools/dk4uc2l.h
new file mode 100644
index 0000000000..501acc8072
--- /dev/null
+++ b/support/dktools/dk4uc2l.h
@@ -0,0 +1,270 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4uc2l.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4UC2L_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4UC2L_H_INCLUDED 1
+
+
+#line 10 "dk4uc2l.ctr"
+
+/** @file dk4uc2l.h Text to LaTeX conversion.
+
+LaTeX sequences to represent a 32 bit character are found in lookup tables
+in the ${datarootdir}/dktools/charmap directory. The functions in this
+module read those lookup tables needed, cache the contents and provide
+LaTeX sequences.
+
+After finishing output you can write recommendations (i.e. LaTeX packages
+to include, font encoding to use) as comments to the file.
+*/
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4app.h"
+#endif
+
+#ifndef DK4STO_H_INCLUDED
+#include "dk4sto.h"
+#endif
+
+/** Information about a package.
+*/
+typedef struct {
+ char *pn; /**< Package name. */
+ unsigned char used; /**< Flag: Package used. */
+} dk4_uc2l_pkg_t;
+
+/** Data for contents of one file.
+ The structure contains information about the character
+ ranges covered by the file.
+*/
+typedef struct {
+ dkChar *fn; /**< Short file name. */
+ unsigned char loaded; /**< Flag: File loaded. */
+} dk4_uc2l_file_t;
+
+
+/** Range of characters.
+*/
+typedef struct {
+ dk4_uc2l_file_t *file; /**< File containing data. */
+ char **both; /**< LaTeX text both modes. */
+ char **text; /**< LaTeX text text mode. */
+ char **math; /**< LaTeX text math mode. */
+ dk4_uc2l_pkg_t ***pkgs; /**< Packages for characters. */
+ unsigned char *fenc; /**< Required font encodings. */
+ dk4_c32_t start; /**< First character of range. */
+ dk4_c32_t end; /**< Final character of range. */
+ unsigned char ia; /**< Flag: Initialisation att. */
+} dk4_uc2l_range_t;
+
+
+/** Text to LaTeX conversion structure.
+*/
+typedef struct {
+ char buf[16]; /**< Buffer for direct output. */
+ const dkChar * const *msgs; /**< Localized messages */
+ dkChar *dname; /**< Directory name. */
+ dk4_sto_t *s_ranges; /**< Ranges container. */
+ dk4_sto_it_t *i_ranges; /**< Ranges container iterator. */
+ dk4_sto_t *s_files; /**< Files container. */
+ dk4_sto_it_t *i_files; /**< Files container iterator. */
+ dk4_sto_t *s_pkgs; /**< Package information container. */
+ dk4_sto_it_t *i_pkgs; /**< Package information iterator. */
+ size_t szmsgs; /**< Number of messages in msgs. */
+ int had_error; /**< Flag: Errors occured. */
+ unsigned char utf8allowed; /**< Flag: UTF-8 output allowed. */
+ unsigned char fallowed; /**< Allowed font encodings. */
+} dk4_uc2l_t;
+
+
+/** Font encodings
+*/
+enum {
+ /** OT1 font encoding.
+ */
+ DK4_UC2L_FONT_ENCODING_OT1 = 1 ,
+
+ /** T1 font encoding.
+ */
+ DK4_UC2L_FONT_ENCODING_T1 = 2 ,
+
+ /** T4 font encoding.
+ */
+ DK4_UC2L_FONT_ENCODING_T4 = 4 ,
+
+ /** T5 font encoding.
+ */
+ DK4_UC2L_FONT_ENCODING_T5 = 8 ,
+
+ DK4_UC2L_FONT_ENCODING_ALL = (
+ 0
+ | DK4_UC2L_FONT_ENCODING_OT1
+ | DK4_UC2L_FONT_ENCODING_T1
+ | DK4_UC2L_FONT_ENCODING_T4
+ | DK4_UC2L_FONT_ENCODING_T5
+ )
+};
+
+
+
+/** Errors from this module
+*/
+enum {
+
+ /** Memory allocation failed.
+ */
+ DK4_UC2L_ERROR_MEMORY = 1 ,
+
+ /** Syntax error in configuration file.
+ */
+ DK4_UC2L_ERROR_SYNTAX = 2 ,
+
+ /** Decoding error in configuration file.
+ */
+ DK4_UC2L_ERROR_DECODING = 4 ,
+
+ /** Other processing errors while reading data.
+ */
+ DK4_UC2L_ERROR_PROCESSING = 8 ,
+
+ /** Failed to open one of the data files.
+ */
+ DK4_UC2L_ERROR_FOPEN = 16 ,
+};
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open conversion structure, dynamically allocate memory.
+ @param dn Directory name containing the data files.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to conversion structure on success, NULL on error.
+
+ Use dk4uc2l_close() to close the conversion structure when done
+ with it.
+*/
+dk4_uc2l_t *
+dk4uc2l_open(const dkChar *dn, dk4_app_t *app);
+
+
+/** Open conversion structure, dynamically allocate memory.
+ The directory containing the data files is obtained from
+ the application (if not NULL), ${datarootdir}/dktools/charmap
+ is used by default.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to conversion structure on success, NULL on error.
+
+ Use dk4uc2l_close() to close the conversion structure when done
+ with it.
+*/
+dk4_uc2l_t *
+dk4uc2l_open_from_app(dk4_app_t *app);
+
+/** Close conversion structure, release memory.
+ @param ulptr Conversion structure to close.
+*/
+void
+dk4uc2l_close(dk4_uc2l_t *ulptr);
+
+/** Enable or disable direct UTF-8 output.
+ If you use usepackage[utf-8]{inputenc} you might want to
+ enable UTF-8 output.
+ @param ulptr Conversion structure to set up.
+ @param enabled Flag: Enable UTF-8 output.
+*/
+void
+dk4uc2l_allow_utf8(dk4_uc2l_t *ulptr, int enabled);
+
+/** Reset information about used packages and allowed and denied
+ font encodings.
+ Typically you want to use this function only after finishing
+ one output file and starting a new one.
+ @param ulptr Conversion structure to reset.
+*/
+void
+dk4uc2l_clean_packages_and_fonts(dk4_uc2l_t *ulptr);
+
+/** Find LaTeX encoding for one 32 bit character.
+ @param ulptr Conversion structure.
+ @param c Character to search encoding for.
+ @param mm Flag: Math mode (1) or text mode (0).
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to encoding string on success, NULL on error.
+*/
+const char *
+dk4uc2l_find(dk4_uc2l_t *ulptr, dk4_c32_t c, int mm, dk4_app_t *app);
+
+/** Retrieve or-combination of all allowed font encodings.
+ You should use this function after processing all characters.
+*/
+unsigned char
+dk4uc2l_retrieve_allowed_fe(dk4_uc2l_t *ulptr);
+
+/** Check whether a character can be written to a LaTeX file directly.
+ @param c32 Character to check.
+ @return 1 for yes, 0 for no.
+*/
+int
+dk4uc2lat_direct(dk4_c32_t c32);
+
+/** Issue recommendations about font encodings and packages.
+ Use this function after processing all characters.
+ @param ulptr Conversion structure.
+ @param fipo File to write to.
+*/
+void
+dk4uc2l_recommendations(dk4_uc2l_t *ulptr, FILE *fipo);
+
+/** Retrieve internal error status from conversion structure.
+ @param ulptr Conversion structure.
+ @return Error status, 0 or combination of DK4_UC2L_ERROR_MEMORY,
+ DK4_UC2L_ERROR_SYNTAX, DK4_UC2L_ERROR_DECODING,
+ DK4_UC2L_ERROR_PROCESSING, and DK4_UC2L_ERROR_FOPEN.
+*/
+int
+dk4uc2l_retrieve_errors(dk4_uc2l_t *ulptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4ufi.c b/support/dktools/dk4ufi.c
new file mode 100644
index 0000000000..9d0339ead0
--- /dev/null
+++ b/support/dktools/dk4ufi.c
@@ -0,0 +1,75 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4ufi.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4ufi.c The dk4ufi module.
+*/
+
+
+#line 58 "dk4ufi.ctr"
+
+#include "dk4conf.h"
+
+#include "dk4ufi.h"
+
+#if DK4_CHAR_SIZE > 1
+#include "dk4ufiwc.h"
+#else
+#include "dk4ufi08.h"
+#endif
+
+
+
+int
+dk4ufi_get(dk4_ufi_t *dptr, const dkChar *fn, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4ufi_get_wc(dptr, fn, erp));
+#else
+ return (dk4ufi_get_c8(dptr, fn, erp));
+#endif
+}
+
+
+
+int
+dk4ufi_get_l(dk4_ufi_t *dptr, const dkChar *fn, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4ufi_get_l_wc(dptr, fn, erp));
+#else
+ return (dk4ufi_get_l_c8(dptr, fn, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4ufi.ctr b/support/dktools/dk4ufi.ctr
new file mode 100644
index 0000000000..9ebf98da17
--- /dev/null
+++ b/support/dktools/dk4ufi.ctr
@@ -0,0 +1,92 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Obtain unique file identifier for path specified as dkChar string.
+ On non-Windows systems the UFI consists of inode number and
+ device number. On Windows systems the volume serial number,
+ higher index number and lower index number are used.
+
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4UFIT_H_INCLUDED
+#include "dk4ufit.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve unique file identifier (for symbolic links return
+ information about link target).
+ @param dptr Destination buffer.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4ufi_get(dk4_ufi_t *dptr, const dkChar *fn, dk4_er_t *erp);
+
+/** Retrieve unique file identifier (for link itself).
+ @param dptr Destination buffer.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4ufi_get_l(dk4_ufi_t *dptr, const dkChar *fn, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4conf.h"
+
+#include "dk4ufi.h"
+
+#if DK4_CHAR_SIZE > 1
+#include "dk4ufiwc.h"
+#else
+#include "dk4ufi08.h"
+#endif
+
+
+
+int
+dk4ufi_get(dk4_ufi_t *dptr, const dkChar *fn, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4ufi_get_wc(dptr, fn, erp));
+#else
+ return (dk4ufi_get_c8(dptr, fn, erp));
+#endif
+}
+
+
+
+int
+dk4ufi_get_l(dk4_ufi_t *dptr, const dkChar *fn, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4ufi_get_l_wc(dptr, fn, erp));
+#else
+ return (dk4ufi_get_l_c8(dptr, fn, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4ufi.h b/support/dktools/dk4ufi.h
new file mode 100644
index 0000000000..6ebdb4d194
--- /dev/null
+++ b/support/dktools/dk4ufi.h
@@ -0,0 +1,90 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4ufi.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4UFI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4UFI_H_INCLUDED 1
+
+
+#line 10 "dk4ufi.ctr"
+
+/** @file
+ Obtain unique file identifier for path specified as dkChar string.
+ On non-Windows systems the UFI consists of inode number and
+ device number. On Windows systems the volume serial number,
+ higher index number and lower index number are used.
+
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4UFIT_H_INCLUDED
+#include "dk4ufit.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve unique file identifier (for symbolic links return
+ information about link target).
+ @param dptr Destination buffer.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4ufi_get(dk4_ufi_t *dptr, const dkChar *fn, dk4_er_t *erp);
+
+/** Retrieve unique file identifier (for link itself).
+ @param dptr Destination buffer.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4ufi_get_l(dk4_ufi_t *dptr, const dkChar *fn, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4ufi08.c b/support/dktools/dk4ufi08.c
new file mode 100644
index 0000000000..4bd00406f8
--- /dev/null
+++ b/support/dktools/dk4ufi08.c
@@ -0,0 +1,221 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4ufi08.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4ufi08.c The dk4ufi08 module.
+*/
+
+
+#line 92 "dk4ufi08.ctr"
+
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#else
+#include "dk4stat8.h"
+#endif
+
+#include "dk4ufi08.h"
+
+
+int
+dk4ufi_get_c8(dk4_ufi_t *dptr, const char *fn, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ BY_HANDLE_FILE_INFORMATION bhfi;
+ WIN32_FIND_DATAA ffdata;
+ HANDLE han;
+ DWORD dwattr;
+ int i;
+ int back = 0;
+ if ((NULL != dptr) && (NULL != fn)) {
+ dwattr = GetFileAttributesA(fn);
+ if (INVALID_FILE_ATTRIBUTES == dwattr) {
+ han = FindFirstFileA(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != han) {
+ dwattr = ffdata.dwFileAttributes;
+ FindClose(han);
+ }
+ }
+ if (INVALID_FILE_ATTRIBUTES != dwattr) {
+ if (0 != (FILE_ATTRIBUTE_DIRECTORY & dwattr)) {
+ dwattr |= FILE_FLAG_BACKUP_SEMANTICS;
+ }
+ for (i = 0; ((2 > i) && (0 == back)); i++) {
+ han = CreateFileA(
+ fn,
+ ((0 == i) ? (0) : (GENERIC_READ)),
+ (FILE_SHARE_READ | FILE_SHARE_WRITE),
+ NULL,
+ OPEN_EXISTING,
+ dwattr,
+ NULL
+ );
+ if (INVALID_HANDLE_VALUE != han) {
+ if (GetFileInformationByHandle(han, &bhfi)) {
+ back = 1;
+ dptr->ser = bhfi.dwVolumeSerialNumber;
+ dptr->inh = bhfi.nFileIndexHigh;
+ dptr->inl = bhfi.nFileIndexLow;
+ } else {
+ if (1 == i) {
+ /* ERROR: Failed */
+ dk4error_set_ldetails(
+ erp, DK4_E_FILE_INFORMATION_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ }
+ CloseHandle(han);
+ } else {
+ if (1 == i) {
+ /* ERROR: Failed */
+ dk4error_set_ldetails(
+ erp, DK4_E_CREATE_FILE_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ }
+ }
+ }
+
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4_stat_t stb;
+ int back = 0;
+ if ((NULL != dptr) && (NULL != fn)) {
+ if (0 != dk4stat_c8(&stb, fn, erp)) {
+ dptr->dev = stb.st_dev;
+ dptr->ino = stb.st_ino;
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#endif
+}
+
+
+
+int
+dk4ufi_get_l_c8(dk4_ufi_t *dptr, const char *fn, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ BY_HANDLE_FILE_INFORMATION bhfi;
+ WIN32_FIND_DATAA ffdata;
+ HANDLE han;
+ DWORD dwattr;
+ int i;
+ int back = 0;
+ if ((NULL != dptr) && (NULL != fn)) {
+ dwattr = GetFileAttributesA(fn);
+ if (INVALID_FILE_ATTRIBUTES == dwattr) {
+ han = FindFirstFileA(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != han) {
+ dwattr = ffdata.dwFileAttributes;
+ FindClose(han);
+ }
+ }
+ if (INVALID_FILE_ATTRIBUTES != dwattr) {
+ if (0 != (FILE_ATTRIBUTE_DIRECTORY & dwattr)) {
+ dwattr |= FILE_FLAG_BACKUP_SEMANTICS;
+ }
+ dwattr |= FILE_FLAG_OPEN_REPARSE_POINT;
+ for (i = 0; ((2 > i) && (0 == back)); i++) {
+ han = CreateFileA(
+ fn,
+ ((0 == i) ? (0) : (GENERIC_READ)),
+ (FILE_SHARE_READ | FILE_SHARE_WRITE),
+ NULL,
+ OPEN_EXISTING,
+ dwattr,
+ NULL
+ );
+ if (INVALID_HANDLE_VALUE != han) {
+ if (GetFileInformationByHandle(han, &bhfi)) {
+ back = 1;
+ dptr->ser = bhfi.dwVolumeSerialNumber;
+ dptr->inh = bhfi.nFileIndexHigh;
+ dptr->inl = bhfi.nFileIndexLow;
+ } else {
+ if (1 == i) {
+ /* ERROR: Failed */
+ dk4error_set_ldetails(
+ erp, DK4_E_FILE_INFORMATION_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ }
+ CloseHandle(han);
+ } else {
+ if (1 == i) {
+ /* ERROR: Failed */
+ dk4error_set_ldetails(
+ erp, DK4_E_CREATE_FILE_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ }
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4_stat_t stb;
+ int back = 0;
+ if ((NULL != dptr) && (NULL != fn)) {
+ if (0 != dk4stat_l_c8(&stb, fn, erp)) {
+ dptr->dev = stb.st_dev;
+ dptr->ino = stb.st_ino;
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#endif
+}
+
+
diff --git a/support/dktools/dk4ufi08.ctr b/support/dktools/dk4ufi08.ctr
new file mode 100644
index 0000000000..5bfdd4d4dc
--- /dev/null
+++ b/support/dktools/dk4ufi08.ctr
@@ -0,0 +1,272 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+%% header
+
+/** @file
+ Obtain unique file identifier for path specified as char string.
+ On non-Windows systems the UFI consists of inode number and
+ device number. On Windows systems the volume serial number,
+ higher index number and lower index number are used.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4UFI_H_INCLUDED
+#include "dk4ufit.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve unique file identifier.
+ For symbolic links on non-Windows systems, retrieve
+ information about the link target.
+ @param dptr Destination buffer.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or fn is NULL,
+ - DK4_E_SYSTEM<br>
+ with errno value stored in iDetails1 if the stat() function fails on
+ non-Windows systems,
+ - DK4_E_CREATE_FILE_FAILED<br>
+ with GetLastError() result in lDetails1 if the CreateFile() function
+ fails on Windows,
+ - DK4_E_FILE_INFORMATION_FAILED<br>
+ with GetLastError() result in lDetails1 if the
+ GetFileInformationByHandle() function fails on Windows.
+ - DK4_E_NOT_FOUND<br>
+ if the GetFileAttributes() function fails to retrieve file
+ attributes on Windows.
+
+
+*/
+int
+dk4ufi_get_c8(dk4_ufi_t *dptr, const char *fn, dk4_er_t *erp);
+
+/** Retrieve unique file identifier.
+ For symbolic links on non-Windows systems, retrieve
+ information about the link.
+ @param dptr Destination buffer.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or fn is NULL,
+ - DK4_E_SYSTEM<br>
+ with errno value stored in iDetails1 if the lstat() function fails
+ on non-Windows systems,
+ - DK4_E_CREATE_FILE_FAILED<br>
+ with GetLastError() result in lDetails1 if the CreateFile() function
+ fails on Windows,
+ - DK4_E_FILE_INFORMATION_FAILED<br>
+ with GetLastError() result in lDetails1 if the
+ GetFileInformationByHandle() function fails on Windows.
+ - DK4_E_NOT_FOUND<br>
+ if the GetFileAttributes() function fails to retrieve
+ file attributes on Windows.
+
+*/
+int
+dk4ufi_get_l_c8(dk4_ufi_t *dptr, const char *fn, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#else
+#include "dk4stat8.h"
+#endif
+
+#include "dk4ufi08.h"
+
+
+int
+dk4ufi_get_c8(dk4_ufi_t *dptr, const char *fn, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ BY_HANDLE_FILE_INFORMATION bhfi;
+ WIN32_FIND_DATAA ffdata;
+ HANDLE han;
+ DWORD dwattr;
+ int i;
+ int back = 0;
+ if ((NULL != dptr) && (NULL != fn)) {
+ dwattr = GetFileAttributesA(fn);
+ if (INVALID_FILE_ATTRIBUTES == dwattr) {
+ han = FindFirstFileA(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != han) {
+ dwattr = ffdata.dwFileAttributes;
+ FindClose(han);
+ }
+ }
+ if (INVALID_FILE_ATTRIBUTES != dwattr) {
+ if (0 != (FILE_ATTRIBUTE_DIRECTORY & dwattr)) {
+ dwattr |= FILE_FLAG_BACKUP_SEMANTICS;
+ }
+ for (i = 0; ((2 > i) && (0 == back)); i++) {
+ han = CreateFileA(
+ fn,
+ ((0 == i) ? (0) : (GENERIC_READ)),
+ (FILE_SHARE_READ | FILE_SHARE_WRITE),
+ NULL,
+ OPEN_EXISTING,
+ dwattr,
+ NULL
+ );
+ if (INVALID_HANDLE_VALUE != han) {
+ if (GetFileInformationByHandle(han, &bhfi)) {
+ back = 1;
+ dptr->ser = bhfi.dwVolumeSerialNumber;
+ dptr->inh = bhfi.nFileIndexHigh;
+ dptr->inl = bhfi.nFileIndexLow;
+ } else {
+ if (1 == i) {
+ /* ERROR: Failed */
+ dk4error_set_ldetails(
+ erp, DK4_E_FILE_INFORMATION_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ }
+ CloseHandle(han);
+ } else {
+ if (1 == i) {
+ /* ERROR: Failed */
+ dk4error_set_ldetails(
+ erp, DK4_E_CREATE_FILE_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ }
+ }
+ }
+
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4_stat_t stb;
+ int back = 0;
+ if ((NULL != dptr) && (NULL != fn)) {
+ if (0 != dk4stat_c8(&stb, fn, erp)) {
+ dptr->dev = stb.st_dev;
+ dptr->ino = stb.st_ino;
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#endif
+}
+
+
+
+int
+dk4ufi_get_l_c8(dk4_ufi_t *dptr, const char *fn, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ BY_HANDLE_FILE_INFORMATION bhfi;
+ WIN32_FIND_DATAA ffdata;
+ HANDLE han;
+ DWORD dwattr;
+ int i;
+ int back = 0;
+ if ((NULL != dptr) && (NULL != fn)) {
+ dwattr = GetFileAttributesA(fn);
+ if (INVALID_FILE_ATTRIBUTES == dwattr) {
+ han = FindFirstFileA(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != han) {
+ dwattr = ffdata.dwFileAttributes;
+ FindClose(han);
+ }
+ }
+ if (INVALID_FILE_ATTRIBUTES != dwattr) {
+ if (0 != (FILE_ATTRIBUTE_DIRECTORY & dwattr)) {
+ dwattr |= FILE_FLAG_BACKUP_SEMANTICS;
+ }
+ dwattr |= FILE_FLAG_OPEN_REPARSE_POINT;
+ for (i = 0; ((2 > i) && (0 == back)); i++) {
+ han = CreateFileA(
+ fn,
+ ((0 == i) ? (0) : (GENERIC_READ)),
+ (FILE_SHARE_READ | FILE_SHARE_WRITE),
+ NULL,
+ OPEN_EXISTING,
+ dwattr,
+ NULL
+ );
+ if (INVALID_HANDLE_VALUE != han) {
+ if (GetFileInformationByHandle(han, &bhfi)) {
+ back = 1;
+ dptr->ser = bhfi.dwVolumeSerialNumber;
+ dptr->inh = bhfi.nFileIndexHigh;
+ dptr->inl = bhfi.nFileIndexLow;
+ } else {
+ if (1 == i) {
+ /* ERROR: Failed */
+ dk4error_set_ldetails(
+ erp, DK4_E_FILE_INFORMATION_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ }
+ CloseHandle(han);
+ } else {
+ if (1 == i) {
+ /* ERROR: Failed */
+ dk4error_set_ldetails(
+ erp, DK4_E_CREATE_FILE_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ }
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4_stat_t stb;
+ int back = 0;
+ if ((NULL != dptr) && (NULL != fn)) {
+ if (0 != dk4stat_l_c8(&stb, fn, erp)) {
+ dptr->dev = stb.st_dev;
+ dptr->ino = stb.st_ino;
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#endif
+}
+
+
diff --git a/support/dktools/dk4ufi08.h b/support/dktools/dk4ufi08.h
new file mode 100644
index 0000000000..97571d5914
--- /dev/null
+++ b/support/dktools/dk4ufi08.h
@@ -0,0 +1,126 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4ufi08.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4UFI08_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4UFI08_H_INCLUDED 1
+
+
+#line 8 "dk4ufi08.ctr"
+
+/** @file
+ Obtain unique file identifier for path specified as char string.
+ On non-Windows systems the UFI consists of inode number and
+ device number. On Windows systems the volume serial number,
+ higher index number and lower index number are used.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4UFI_H_INCLUDED
+#include "dk4ufit.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve unique file identifier.
+ For symbolic links on non-Windows systems, retrieve
+ information about the link target.
+ @param dptr Destination buffer.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or fn is NULL,
+ - DK4_E_SYSTEM<br>
+ with errno value stored in iDetails1 if the stat() function fails on
+ non-Windows systems,
+ - DK4_E_CREATE_FILE_FAILED<br>
+ with GetLastError() result in lDetails1 if the CreateFile() function
+ fails on Windows,
+ - DK4_E_FILE_INFORMATION_FAILED<br>
+ with GetLastError() result in lDetails1 if the
+ GetFileInformationByHandle() function fails on Windows.
+ - DK4_E_NOT_FOUND<br>
+ if the GetFileAttributes() function fails to retrieve file
+ attributes on Windows.
+
+
+*/
+int
+dk4ufi_get_c8(dk4_ufi_t *dptr, const char *fn, dk4_er_t *erp);
+
+/** Retrieve unique file identifier.
+ For symbolic links on non-Windows systems, retrieve
+ information about the link.
+ @param dptr Destination buffer.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or fn is NULL,
+ - DK4_E_SYSTEM<br>
+ with errno value stored in iDetails1 if the lstat() function fails
+ on non-Windows systems,
+ - DK4_E_CREATE_FILE_FAILED<br>
+ with GetLastError() result in lDetails1 if the CreateFile() function
+ fails on Windows,
+ - DK4_E_FILE_INFORMATION_FAILED<br>
+ with GetLastError() result in lDetails1 if the
+ GetFileInformationByHandle() function fails on Windows.
+ - DK4_E_NOT_FOUND<br>
+ if the GetFileAttributes() function fails to retrieve
+ file attributes on Windows.
+
+*/
+int
+dk4ufi_get_l_c8(dk4_ufi_t *dptr, const char *fn, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4ufic.c b/support/dktools/dk4ufic.c
new file mode 100644
index 0000000000..b8a0fe203c
--- /dev/null
+++ b/support/dktools/dk4ufic.c
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4ufic.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4ufic.c The dk4ufic module.
+*/
+
+
+#line 36 "dk4ufic.ctr"
+
+#include "dk4ufic.h"
+
+int
+dk4ufi_compare(const dk4_ufi_t *l, const dk4_ufi_t *r)
+{
+ if (NULL != l) {
+ if (NULL != r) {
+#if DK4_ON_WINDOWS
+ if (l->ser > r->ser) {
+ back = 1;
+ } else {
+ if (l->ser < r->ser) {
+ back = -1;
+ }
+ }
+ if (0 == back) {
+ if (l->inh > r->inh) {
+ back = 1;
+ } else {
+ if (l->inh < r->inh) {
+ back = -1;
+ }
+ }
+ }
+ if (0 == back) {
+ if (l->inl > r->inl) {
+ back = 1;
+ } else {
+ if (l->inl < r->inl) {
+ back = -1;
+ }
+ }
+ }
+#else
+ if (l->dev > r->dev) {
+ back = 1;
+ } else {
+ if (l->dev < r->dev) {
+ back = -1;
+ }
+ }
+ if (0 == back) {
+ if (l->ino > r->ino) {
+ back = 1;
+ } else {
+ if (l->ino < r->ino) {
+ back = -1;
+ }
+ }
+ }
+#endif
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != r) {
+ back = -1;
+ }
+ }
+}
+
diff --git a/support/dktools/dk4ufic.ctr b/support/dktools/dk4ufic.ctr
new file mode 100644
index 0000000000..e32216d0a9
--- /dev/null
+++ b/support/dktools/dk4ufic.ctr
@@ -0,0 +1,97 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ Compare unique file identifiers.
+*/
+
+#ifndef DK4UFIT_H_INCLUDED
+#include "dk4ufit.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Compare two unique file identifiers.
+ @param l Left identifier.
+ @param r Right identifier.
+ @return 1 if l>r, 0 if l=r, -1 if l<r.
+*/
+int
+dk4ufi_compare(const dk4_ufi_t *l, const dk4_ufi_t *r);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4ufic.h"
+
+int
+dk4ufi_compare(const dk4_ufi_t *l, const dk4_ufi_t *r)
+{
+ if (NULL != l) {
+ if (NULL != r) {
+#if DK4_ON_WINDOWS
+ if (l->ser > r->ser) {
+ back = 1;
+ } else {
+ if (l->ser < r->ser) {
+ back = -1;
+ }
+ }
+ if (0 == back) {
+ if (l->inh > r->inh) {
+ back = 1;
+ } else {
+ if (l->inh < r->inh) {
+ back = -1;
+ }
+ }
+ }
+ if (0 == back) {
+ if (l->inl > r->inl) {
+ back = 1;
+ } else {
+ if (l->inl < r->inl) {
+ back = -1;
+ }
+ }
+ }
+#else
+ if (l->dev > r->dev) {
+ back = 1;
+ } else {
+ if (l->dev < r->dev) {
+ back = -1;
+ }
+ }
+ if (0 == back) {
+ if (l->ino > r->ino) {
+ back = 1;
+ } else {
+ if (l->ino < r->ino) {
+ back = -1;
+ }
+ }
+ }
+#endif
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != r) {
+ back = -1;
+ }
+ }
+}
+
diff --git a/support/dktools/dk4ufic.h b/support/dktools/dk4ufic.h
new file mode 100644
index 0000000000..b5ae1112c0
--- /dev/null
+++ b/support/dktools/dk4ufic.h
@@ -0,0 +1,69 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4ufic.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4UFIC_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4UFIC_H_INCLUDED 1
+
+
+#line 9 "dk4ufic.ctr"
+
+/** @file
+ Compare unique file identifiers.
+*/
+
+#ifndef DK4UFIT_H_INCLUDED
+#include "dk4ufit.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Compare two unique file identifiers.
+ @param l Left identifier.
+ @param r Right identifier.
+ @return 1 if l>r, 0 if l=r, -1 if l<r.
+*/
+int
+dk4ufi_compare(const dk4_ufi_t *l, const dk4_ufi_t *r);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4ufit.h b/support/dktools/dk4ufit.h
new file mode 100644
index 0000000000..8ddaf35c8c
--- /dev/null
+++ b/support/dktools/dk4ufit.h
@@ -0,0 +1,36 @@
+#ifndef DK4UFIT_H_INCLUDED
+/** Protection against multiple inclusion. */
+#define DK4UFIT_H_INCLUDED 1
+
+/** @file dk4ufit.h Data type for unique file identifiers.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#if !DK4_ON_WINDOWS
+#ifndef DK4STATT_H_INCLUDED
+#include "dk4statt.h"
+#endif
+#endif
+
+/** Unique file identification.
+*/
+typedef struct {
+#if DK4_ON_WINDOWS
+ unsigned long ser; /**< Volume serial number (originally DWORD). */
+ unsigned long inh; /**< Higher index part (originally DWORD). */
+ unsigned long inl; /**< Lower index part (originally DWORD). */
+#else
+ dk4_um_t dev; /**< Device number (originally dev_t). */
+ dk4_um_t ino; /**< Inode number (originally ino_t). */
+#endif
+} dk4_ufi_t;
+
+#endif
+
diff --git a/support/dktools/dk4ufiwc.c b/support/dktools/dk4ufiwc.c
new file mode 100644
index 0000000000..7accaca7b5
--- /dev/null
+++ b/support/dktools/dk4ufiwc.c
@@ -0,0 +1,198 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4ufiwc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4ufiwc.c The dk4ufiwc module.
+*/
+
+
+#line 93 "dk4ufiwc.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4ufiwc.h"
+
+
+int
+dk4ufi_get_wc(dk4_ufi_t *dptr, const wchar_t *fn, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ BY_HANDLE_FILE_INFORMATION bhfi;
+ WIN32_FIND_DATAW ffdata;
+ HANDLE han;
+ DWORD dwattr;
+ int i;
+ int back = 0;
+ if ((NULL != dptr) && (NULL != fn)) {
+ dwattr = GetFileAttributesW(fn);
+ if (INVALID_FILE_ATTRIBUTES == dwattr) {
+ han = FindFirstFileW(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != han) {
+ dwattr = ffdata.dwFileAttributes;
+ FindClose(han);
+ }
+ }
+ if (INVALID_FILE_ATTRIBUTES != dwattr) {
+ if (0 != (FILE_ATTRIBUTE_DIRECTORY & dwattr)) {
+ dwattr |= FILE_FLAG_BACKUP_SEMANTICS;
+ }
+ for (i = 0; ((2 > i) && (0 == back)); i++) {
+ han = CreateFileW(
+ fn,
+ ((0 == i) ? (0) : (GENERIC_READ)),
+ (FILE_SHARE_READ | FILE_SHARE_WRITE),
+ NULL,
+ OPEN_EXISTING,
+ dwattr,
+ NULL
+ );
+ if (INVALID_HANDLE_VALUE != han) {
+ if (GetFileInformationByHandle(han, &bhfi)) {
+ back = 1;
+ dptr->ser = bhfi.dwVolumeSerialNumber;
+ dptr->inh = bhfi.nFileIndexHigh;
+ dptr->inl = bhfi.nFileIndexLow;
+ } else {
+ if (1 == i) {
+ /* ERROR */
+ dk4error_set_ldetails(
+ erp, DK4_E_FILE_INFORMATION_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ }
+ } else {
+ if (1 == i) {
+ /* ERROR */
+ dk4error_set_ldetails(
+ erp, DK4_E_CREATE_FILE_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+}
+
+
+
+int
+dk4ufi_get_l_wc(dk4_ufi_t *dptr, const wchar_t *fn, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ BY_HANDLE_FILE_INFORMATION bhfi;
+ WIN32_FIND_DATAW ffdata;
+ HANDLE han;
+ DWORD dwattr;
+ int i;
+ int back = 0;
+ if ((NULL != dptr) && (NULL != fn)) {
+ dwattr = GetFileAttributesW(fn);
+ if (INVALID_FILE_ATTRIBUTES == dwattr) {
+ han = FindFirstFileW(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != han) {
+ dwattr = ffdata.dwFileAttributes;
+ FindClose(han);
+ }
+ }
+ if (INVALID_FILE_ATTRIBUTES != dwattr) {
+ if (0 != (FILE_ATTRIBUTE_DIRECTORY & dwattr)) {
+ dwattr |= FILE_FLAG_BACKUP_SEMANTICS;
+ }
+ dwattr |= FILE_FLAG_OPEN_REPARSE_POINT;
+ for (i = 0; ((2 > i) && (0 == back)); i++) {
+ han = CreateFileW(
+ fn,
+ ((0 == i) ? (0) : (GENERIC_READ)),
+ (FILE_SHARE_READ | FILE_SHARE_WRITE),
+ NULL,
+ OPEN_EXISTING,
+ dwattr,
+ NULL
+ );
+ if (INVALID_HANDLE_VALUE != han) {
+ if (GetFileInformationByHandle(han, &bhfi)) {
+ back = 1;
+ dptr->ser = bhfi.dwVolumeSerialNumber;
+ dptr->inh = bhfi.nFileIndexHigh;
+ dptr->inl = bhfi.nFileIndexLow;
+ } else {
+ if (1 == i) {
+ /* ERROR */
+ dk4error_set_ldetails(
+ erp, DK4_E_FILE_INFORMATION_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ }
+ } else {
+ if (1 == i) {
+ /* ERROR */
+ dk4error_set_ldetails(
+ erp, DK4_E_CREATE_FILE_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+}
+
diff --git a/support/dktools/dk4ufiwc.ctr b/support/dktools/dk4ufiwc.ctr
new file mode 100644
index 0000000000..ac75b44327
--- /dev/null
+++ b/support/dktools/dk4ufiwc.ctr
@@ -0,0 +1,250 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% header
+
+/** @file
+ Obtain unique file identifier for path specified as wchar_t string.
+ On non-Windows systems the UFI consists of inode number and
+ device number. On Windows systems the volume serial number,
+ higher index number and lower index number are used.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4UFI_H_INCLUDED
+#include "dk4ufit.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve unique file identifier.
+ For symbolic links on non-Windows systems, retrieve
+ information about the link target.
+ @param dptr Destination buffer.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or fn is NULL,
+ - DK4_E_SYSTEM<br>
+ with errno value stored in iDetails1 if the stat() function fails
+ on non-Windows systems,
+ - DK4_E_CREATE_FILE_FAILED<br>
+ with GetLastError() result in lDetails1 if the CreateFile()
+ function fails on Windows,
+ - DK4_E_FILE_INFORMATION_FAILED<br>
+ with GetLastError() result in lDetails1 if the
+ GetFileInformationByHandle() function fails on Windows.
+ - DK4_E_NOT_FOUND<br>
+ if the GetFileAttributes() function fails to retrieve file
+ attributes on Windows.
+
+*/
+int
+dk4ufi_get_wc(dk4_ufi_t *dptr, const wchar_t *fn, dk4_er_t *erp);
+
+/** Retrieve unique file identifier.
+ For symbolic links on non-Windows systems, retrieve
+ information about the link.
+ @param dptr Destination buffer.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or fn is NULL,
+ - DK4_E_SYSTEM<br>
+ with errno value stored in iDetails1 if the lstat() function fails
+ on non-Windows systems,
+ - DK4_E_CREATE_FILE_FAILED<br>
+ with GetLastError() result in lDetails1 if the CreateFile()
+ function fails on Windows,
+ - DK4_E_FILE_INFORMATION_FAILED<br>
+ with GetLastError() result in lDetails1 if the
+ GetFileInformationByHandle() function fails on Windows.
+ - DK4_E_NOT_FOUND<br>
+ if the GetFileAttributes() function fails to retrieve file
+ attributes on Windows.
+*/
+int
+dk4ufi_get_l_wc(dk4_ufi_t *dptr, const wchar_t *fn, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4ufiwc.h"
+
+
+int
+dk4ufi_get_wc(dk4_ufi_t *dptr, const wchar_t *fn, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ BY_HANDLE_FILE_INFORMATION bhfi;
+ WIN32_FIND_DATAW ffdata;
+ HANDLE han;
+ DWORD dwattr;
+ int i;
+ int back = 0;
+ if ((NULL != dptr) && (NULL != fn)) {
+ dwattr = GetFileAttributesW(fn);
+ if (INVALID_FILE_ATTRIBUTES == dwattr) {
+ han = FindFirstFileW(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != han) {
+ dwattr = ffdata.dwFileAttributes;
+ FindClose(han);
+ }
+ }
+ if (INVALID_FILE_ATTRIBUTES != dwattr) {
+ if (0 != (FILE_ATTRIBUTE_DIRECTORY & dwattr)) {
+ dwattr |= FILE_FLAG_BACKUP_SEMANTICS;
+ }
+ for (i = 0; ((2 > i) && (0 == back)); i++) {
+ han = CreateFileW(
+ fn,
+ ((0 == i) ? (0) : (GENERIC_READ)),
+ (FILE_SHARE_READ | FILE_SHARE_WRITE),
+ NULL,
+ OPEN_EXISTING,
+ dwattr,
+ NULL
+ );
+ if (INVALID_HANDLE_VALUE != han) {
+ if (GetFileInformationByHandle(han, &bhfi)) {
+ back = 1;
+ dptr->ser = bhfi.dwVolumeSerialNumber;
+ dptr->inh = bhfi.nFileIndexHigh;
+ dptr->inl = bhfi.nFileIndexLow;
+ } else {
+ if (1 == i) {
+ /* ERROR */
+ dk4error_set_ldetails(
+ erp, DK4_E_FILE_INFORMATION_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ }
+ } else {
+ if (1 == i) {
+ /* ERROR */
+ dk4error_set_ldetails(
+ erp, DK4_E_CREATE_FILE_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+}
+
+
+
+int
+dk4ufi_get_l_wc(dk4_ufi_t *dptr, const wchar_t *fn, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ BY_HANDLE_FILE_INFORMATION bhfi;
+ WIN32_FIND_DATAW ffdata;
+ HANDLE han;
+ DWORD dwattr;
+ int i;
+ int back = 0;
+ if ((NULL != dptr) && (NULL != fn)) {
+ dwattr = GetFileAttributesW(fn);
+ if (INVALID_FILE_ATTRIBUTES == dwattr) {
+ han = FindFirstFileW(fn, &ffdata);
+ if (INVALID_HANDLE_VALUE != han) {
+ dwattr = ffdata.dwFileAttributes;
+ FindClose(han);
+ }
+ }
+ if (INVALID_FILE_ATTRIBUTES != dwattr) {
+ if (0 != (FILE_ATTRIBUTE_DIRECTORY & dwattr)) {
+ dwattr |= FILE_FLAG_BACKUP_SEMANTICS;
+ }
+ dwattr |= FILE_FLAG_OPEN_REPARSE_POINT;
+ for (i = 0; ((2 > i) && (0 == back)); i++) {
+ han = CreateFileW(
+ fn,
+ ((0 == i) ? (0) : (GENERIC_READ)),
+ (FILE_SHARE_READ | FILE_SHARE_WRITE),
+ NULL,
+ OPEN_EXISTING,
+ dwattr,
+ NULL
+ );
+ if (INVALID_HANDLE_VALUE != han) {
+ if (GetFileInformationByHandle(han, &bhfi)) {
+ back = 1;
+ dptr->ser = bhfi.dwVolumeSerialNumber;
+ dptr->inh = bhfi.nFileIndexHigh;
+ dptr->inl = bhfi.nFileIndexLow;
+ } else {
+ if (1 == i) {
+ /* ERROR */
+ dk4error_set_ldetails(
+ erp, DK4_E_FILE_INFORMATION_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ }
+ } else {
+ if (1 == i) {
+ /* ERROR */
+ dk4error_set_ldetails(
+ erp, DK4_E_CREATE_FILE_FAILED,
+ (long)((unsigned long)GetLastError())
+ );
+ }
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+}
+
diff --git a/support/dktools/dk4ufiwc.h b/support/dktools/dk4ufiwc.h
new file mode 100644
index 0000000000..a86407553a
--- /dev/null
+++ b/support/dktools/dk4ufiwc.h
@@ -0,0 +1,126 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4ufiwc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4UFIWC_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4UFIWC_H_INCLUDED 1
+
+
+#line 9 "dk4ufiwc.ctr"
+
+/** @file
+ Obtain unique file identifier for path specified as wchar_t string.
+ On non-Windows systems the UFI consists of inode number and
+ device number. On Windows systems the volume serial number,
+ higher index number and lower index number are used.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4UFI_H_INCLUDED
+#include "dk4ufit.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve unique file identifier.
+ For symbolic links on non-Windows systems, retrieve
+ information about the link target.
+ @param dptr Destination buffer.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or fn is NULL,
+ - DK4_E_SYSTEM<br>
+ with errno value stored in iDetails1 if the stat() function fails
+ on non-Windows systems,
+ - DK4_E_CREATE_FILE_FAILED<br>
+ with GetLastError() result in lDetails1 if the CreateFile()
+ function fails on Windows,
+ - DK4_E_FILE_INFORMATION_FAILED<br>
+ with GetLastError() result in lDetails1 if the
+ GetFileInformationByHandle() function fails on Windows.
+ - DK4_E_NOT_FOUND<br>
+ if the GetFileAttributes() function fails to retrieve file
+ attributes on Windows.
+
+*/
+int
+dk4ufi_get_wc(dk4_ufi_t *dptr, const wchar_t *fn, dk4_er_t *erp);
+
+/** Retrieve unique file identifier.
+ For symbolic links on non-Windows systems, retrieve
+ information about the link.
+ @param dptr Destination buffer.
+ @param fn File name.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if dptr or fn is NULL,
+ - DK4_E_SYSTEM<br>
+ with errno value stored in iDetails1 if the lstat() function fails
+ on non-Windows systems,
+ - DK4_E_CREATE_FILE_FAILED<br>
+ with GetLastError() result in lDetails1 if the CreateFile()
+ function fails on Windows,
+ - DK4_E_FILE_INFORMATION_FAILED<br>
+ with GetLastError() result in lDetails1 if the
+ GetFileInformationByHandle() function fails on Windows.
+ - DK4_E_NOT_FOUND<br>
+ if the GetFileAttributes() function fails to retrieve file
+ attributes on Windows.
+*/
+int
+dk4ufi_get_l_wc(dk4_ufi_t *dptr, const wchar_t *fn, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4user.c b/support/dktools/dk4user.c
new file mode 100644
index 0000000000..222e6a2ee8
--- /dev/null
+++ b/support/dktools/dk4user.c
@@ -0,0 +1,538 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4user.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4user.c The dk4user module.
+*/
+
+
+#line 87 "dk4user.ctr"
+
+
+#include "dk4user.h"
+#include "dk4str8.h"
+#include "dk4strw.h"
+#include "dk4strd.h"
+#include "dk4wregw.h"
+#include "dk4wregc.h"
+#include "dk4mem.h"
+#include "dk4error.h"
+#include "dk4masz.h"
+#include "dk4mpl.h"
+
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#ifndef LM_H_INCLUDED
+#include <lm.h>
+#define LM_H_INCLUDED 1
+#endif
+#ifndef SDDL_H_INCLUDED
+#include <sddl.h>
+#define SDDL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PWD_H
+#ifndef PWD_H_INCLUDED
+#include <pwd.h>
+#define PWD_H_INCLUDED 1
+#endif
+#endif
+
+
+
+
+
+#line 140 "dk4user.ctr"
+
+
+
+#if DK4_ON_WINDOWS
+static const wchar_t * const dk4user_kw[] = {
+/* 0 */
+L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
+
+/* 1 */
+L"\\",
+
+/* 2 */
+L"ProfileImagePath",
+
+/* 3 */
+L"LOGONSERVER",
+
+/* 4 */
+L"USERPROFILE",
+
+/* 5 */
+L"HOMEDRIVE",
+
+/* 6 */
+L"HOMEPATH",
+
+NULL
+
+
+#line 160 "dk4user.ctr"
+};
+#endif
+
+int
+dk4user_get_logname(dkChar *pdst, size_t szdst, int eff, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ DWORD sz;
+ int back = 0;
+
+
+#line 170 "dk4user.ctr"
+ if ((NULL != pdst) && (0 < szdst)) {
+ sz = (DWORD)szdst;
+#if DK4_CHAR_SIZE > 1
+ if(GetUserNameW(pdst, &sz))
+#else
+ if(GetUserNameA(pdst, &sz))
+#endif
+ {
+ if (sz < szdst) {
+ pdst[sz] = dkT('\0');
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ }
+ else
+ {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 192 "dk4user.ctr"
+ return back;
+#else
+#if DK4_CHAR_SIZE > 1
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#else
+ struct passwd *pwent;
+ uid_t uid;
+ int back = 0;
+
+
+#line 202 "dk4user.ctr"
+ if ((NULL != pdst) && (0 < szdst)) {
+ if (0 != eff) { uid = geteuid(); } else { uid = getuid(); }
+ pwent = getpwuid(uid);
+ if (NULL != pwent) {
+ if (NULL != pwent->pw_name) {
+ if (0 != dk4str_cpy_s(pdst, szdst, pwent->pw_name, erp)) {
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 219 "dk4user.ctr"
+ return back;
+#endif
+#endif
+}
+
+
+
+#if DK4_ON_WINDOWS
+
+
+
+/** Obtain home directory information using one logon server.
+ @param pdst Destination buffer pointer.
+ @param szdst Destination buffer size (number of wchar_t).
+ @param lsn Logon server name, may be NULL.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4user_get_i_ls_homedir(
+ wchar_t *pdst, size_t szdst, const wchar_t *lsn, dk4_er_t *erp
+)
+{
+ wchar_t b1[DK4_MAX_PATH+16]; /* Buffer RegQueryValue() */
+ wchar_t b2[DK4_MAX_PATH+16]; /* Buffer Expand...() */
+ wchar_t logname[256]; /* Login name */
+ dk4_er_t er; /* Error report */
+ USER_INFO_4 *pbuf4 = NULL; /* User information */
+ wchar_t *pStringSid = NULL; /* String SID */
+ wchar_t *keyname = NULL; /* Registry key name */
+ void *wrkey = NULL; /* Registry key */
+ DWORD szlog = DK4_SIZEOF(logname,wchar_t);
+ size_t sz = 0; /* Key name length */
+ int back = 0; /* Result */
+ NET_API_STATUS nStatus = 0; /* Network op result */
+
+
+#line 256 "dk4user.ctr"
+ dk4error_init(&er);
+ if (GetUserNameW(logname, &szlog)) {
+
+#line 258 "dk4user.ctr"
+ if (DK4_SIZEOF(logname,wchar_t) >= szlog) {
+
+#line 259 "dk4user.ctr"
+ logname[szlog] = L'\0';
+ nStatus = NetUserGetInfo(lsn, logname, (DWORD)4, (LPBYTE *)(&pbuf4));
+ if ((NERR_Success == nStatus) && (NULL != pbuf4)) {
+
+#line 262 "dk4user.ctr"
+ if (ConvertSidToStringSidW(pbuf4->usri4_user_sid, &pStringSid)) {
+
+
+#line 264 "dk4user.ctr"
+ sz = dk4ma_size_t_add(
+ dk4ma_size_t_add(
+ 1,
+ dk4strw_len(dk4user_kw[0]),
+ &er
+ ),
+ dk4ma_size_t_add(
+ dk4strw_len(dk4user_kw[1]),
+ dk4strw_len(pStringSid),
+ &er
+ ),
+ &er
+ );
+ if (DK4_E_NONE == er.ec) {
+
+#line 278 "dk4user.ctr"
+ (void)dk4ma_size_t_mul(sizeof(wchar_t), sz, &er);
+ if (DK4_E_NONE == er.ec) {
+
+#line 280 "dk4user.ctr"
+ keyname = dk4mem_calloc(sizeof(wchar_t),sz,&er);
+ if (NULL != keyname) {
+
+#line 282 "dk4user.ctr"
+ (void)dk4strw_cpy_s(keyname, sz, dk4user_kw[0], NULL);
+ (void)dk4strw_cat_s(keyname, sz, dk4user_kw[1], NULL);
+ (void)dk4strw_cat_s(keyname, sz, pStringSid, NULL);
+ wrkey = dk4wreg_open_key_wc(DK4_WREGKEY_HKLM, keyname, 0, &er);
+ if (NULL != wrkey) {
+
+#line 287 "dk4user.ctr"
+ back = dk4wreg_get_expanded_string_wc(
+ wrkey,
+ dk4user_kw[2],
+ pdst, szdst,
+ b1, DK4_SIZEOF(b1,wchar_t),
+ b2, (DK4_SIZEOF(b2,wchar_t)-2),
+ &er
+ );
+
+#line 295 "dk4user.ctr"
+ dk4wreg_close_key(wrkey);
+ } else {
+
+#line 297 "dk4user.ctr"
+ /* ERROR: Failed to open key (reported) */
+ }
+ dk4mem_free(keyname);
+ } else {
+
+#line 301 "dk4user.ctr"
+ /* ERROR: Memory (reported) */
+ }
+ } else {
+
+#line 304 "dk4user.ctr"
+ /* ERROR: Overflow in size calculation (reported) */
+ }
+ } else {
+
+#line 307 "dk4user.ctr"
+ /* ERROR: Overflow in size calculation (reported) */
+ }
+ } else {
+
+#line 310 "dk4user.ctr"
+ /* ERROR: Failed to convert SID */
+ dk4error_set_simple_error_code(&er, DK4_E_NOT_FOUND);
+ }
+ if (NULL != pStringSid) {
+ LocalFree(pStringSid);
+ }
+ } else {
+
+#line 317 "dk4user.ctr"
+ /* ERROR: No user info */
+ }
+ if (NULL != pbuf4) {
+ NetApiBufferFree(pbuf4);
+ }
+ } else {
+
+#line 323 "dk4user.ctr"
+ /* ERROR: User name too long */
+ dk4error_set_simple_error_code(&er, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+
+#line 327 "dk4user.ctr"
+ /* ERROR: User name not found */
+ }
+ if (0 == back) {
+ dk4error_copy(erp, &er);
+ }
+
+
+#line 333 "dk4user.ctr"
+ return back;
+}
+
+
+
+/** Find Windows home directory.
+ @param pdst Destination buffer pointer.
+ @param szdst Destination buffer size (number of wchar_t).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4user_get_i_homedir(wchar_t *pdst, size_t szdst, dk4_er_t *erp)
+{
+ dk4_er_t myerp;
+ wchar_t *lsn = NULL;
+ wchar_t *hop = NULL;
+ int back = 0;
+
+
+#line 353 "dk4user.ctr"
+ dk4error_init(&myerp);
+ back = dk4user_get_i_ls_homedir(pdst, szdst, NULL, &myerp);
+
+
+#line 356 "dk4user.ctr"
+ if ((0 == back) && (DK4_E_NONE == myerp.ec)) {
+
+#line 357 "dk4user.ctr"
+ lsn = _wgetenv(dk4user_kw[4]);
+
+#line 358 "dk4user.ctr"
+ if (NULL != lsn) {
+ back = dk4strw_cpy_s(pdst, szdst, lsn, &myerp);
+
+
+#line 361 "dk4user.ctr"
+ } else {
+
+#line 362 "dk4user.ctr"
+ }
+ }
+ if ((0 == back) && (DK4_E_NONE == myerp.ec)) {
+
+#line 365 "dk4user.ctr"
+ lsn = _wgetenv(dk4user_kw[5]);
+ hop = _wgetenv(dk4user_kw[6]);
+ if ((NULL != lsn) && (NULL != hop)) {
+
+#line 368 "dk4user.ctr"
+ if (0 != dk4strw_cpy_s(pdst, szdst, lsn, &myerp)) {
+ back = dk4strw_cat_s(pdst, szdst, hop, &myerp);
+
+
+#line 371 "dk4user.ctr"
+ } else {
+
+#line 372 "dk4user.ctr"
+ }
+ } else {
+
+#line 374 "dk4user.ctr"
+ }
+ }
+ if ((0 == back) && (DK4_E_NONE == myerp.ec)) {
+
+#line 377 "dk4user.ctr"
+ lsn = _wgetenv(dk4user_kw[3]);
+ if (NULL != lsn) {
+
+#line 379 "dk4user.ctr"
+ back = dk4user_get_i_ls_homedir(pdst, szdst, lsn, &myerp);
+
+
+#line 381 "dk4user.ctr"
+ }
+ }
+ if ((0 == back) && (DK4_E_NONE == myerp.ec)) {
+
+#line 384 "dk4user.ctr"
+ if (NULL != lsn) {
+
+#line 385 "dk4user.ctr"
+ if (L'\\' == lsn[0]) {
+ if (L'\\' == lsn[1]) {
+ back = dk4user_get_i_ls_homedir(pdst, szdst, &(lsn[2]), &myerp);
+
+
+#line 389 "dk4user.ctr"
+ } else {
+
+#line 390 "dk4user.ctr"
+ }
+ } else {
+
+#line 392 "dk4user.ctr"
+ }
+ } else {
+
+#line 394 "dk4user.ctr"
+ }
+ }
+ if ((0 == back) && (DK4_E_NONE == myerp.ec)) {
+ dk4error_set_simple_error_code(&myerp, DK4_E_NOT_FOUND);
+ }
+ if (0 == back) {
+ dk4error_copy(erp, &myerp);
+ }
+
+#line 402 "dk4user.ctr"
+ return back;
+}
+
+#endif
+
+
+int
+dk4user_get_homedir(dkChar *pdst, size_t szdst, int eff, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+/* +++++ Windows +++++ */
+#if DK4_CHAR_SIZE == 1
+ wchar_t homew[DK4_MAX_PATH];
+#endif
+ int back = 0;
+
+
+#line 418 "dk4user.ctr"
+ if ((NULL != pdst) && (0 < szdst)) {
+
+#line 419 "dk4user.ctr"
+ *pdst = dkT('\0');
+#if DK4_CHAR_SIZE > 1
+
+
+#line 422 "dk4user.ctr"
+ back = dk4user_get_i_homedir(pdst, szdst, erp);
+#else
+
+
+#line 425 "dk4user.ctr"
+ if (0 != dk4user_get_i_homedir(homew, DK4_SIZEOF(homew,wchar_t), erp)) {
+ back = dk4recode_utf16_to_ansi(pdst, szdst, homew, erp);
+ }
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 432 "dk4user.ctr"
+ return back;
+/* ----- Windows ----- */
+#else
+/* +++++ non-Windows +++++ */
+#if DK4_CHAR_SIZE > 1
+/* +++++ non-Windows wchar_t +++++ */
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+/* ----- non-Windows wchar_t ----- */
+#else
+/* +++++ non-Windows char +++++ */
+ struct passwd *pwent;
+ uid_t uid;
+ int back = 0;
+
+
+#line 447 "dk4user.ctr"
+ if ((NULL != pdst) && (0 < szdst)) {
+ if (0 != eff) { uid = geteuid(); } else { uid = getuid(); }
+ pwent = getpwuid(uid);
+ if (NULL != pwent) {
+ if (NULL != pwent->pw_dir) {
+ if (0 != dk4str8_cpy_s(pdst, szdst, pwent->pw_dir, erp)) {
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 464 "dk4user.ctr"
+ return back;
+/* ----- non-Windows char ----- */
+#endif
+/* ----- non-Windows ----- */
+#endif
+}
+
diff --git a/support/dktools/dk4user.ctr b/support/dktools/dk4user.ctr
new file mode 100644
index 0000000000..4d9d89afe4
--- /dev/null
+++ b/support/dktools/dk4user.ctr
@@ -0,0 +1,470 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Get information about user
+ (login name and home directory).
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Get users login name.
+ @param pdst Pointer to destination buffer.
+ @param szdst Size of destination buffer (number of characters).
+ @param eff Flag: Retrieve information about effective user.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ CRT on Windows: Not used.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if pdst is NULL or szdst is 0,
+ - DK4_E_NOT_FOUND<br>
+ if the login name was not found,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the buffer is too small for the result.
+*/
+int
+dk4user_get_logname(dkChar *pdst, size_t szdst, int eff, dk4_er_t *erp);
+
+/** Get users home directory.
+ @param pdst Pointer to destination buffer.
+ @param szdst Size of destination buffer (number of characters).
+ @param eff Flag: Retrieve information about effective user.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ CRT on Windows: Optional.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if pdst is NULL or szdst is 0,
+ - DK4_E_NOT_FOUND<br>
+ if the login name, the user entry or the home
+ directory was not found,
+ - DK4_E_MEMORY<br>
+ if an internal memory allocation failed,
+ - DK4_E_SYNTAX<br>
+ if the retrieved registry entry on
+ Windows is not a string,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the pdst buffer or one of the internal buffers
+ is too small for the result.
+*/
+int
+dk4user_get_homedir(dkChar *pdst, size_t szdst, int eff, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+
+#include "dk4user.h"
+#include "dk4str8.h"
+#include "dk4strw.h"
+#include "dk4strd.h"
+#include "dk4wregw.h"
+#include "dk4wregc.h"
+#include "dk4mem.h"
+#include "dk4error.h"
+#include "dk4masz.h"
+#include "dk4mpl.h"
+
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#ifndef LM_H_INCLUDED
+#include <lm.h>
+#define LM_H_INCLUDED 1
+#endif
+#ifndef SDDL_H_INCLUDED
+#include <sddl.h>
+#define SDDL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PWD_H
+#ifndef PWD_H_INCLUDED
+#include <pwd.h>
+#define PWD_H_INCLUDED 1
+#endif
+#endif
+
+
+
+$!trace-include
+
+
+
+#if DK4_ON_WINDOWS
+static const wchar_t * const dk4user_kw[] = {
+$!string-table prefix=L
+#
+# 0 ... 2 Registry key name and value name for profile dir
+#
+SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList
+\\
+ProfileImagePath
+#
+# 3 4 5 6
+#
+LOGONSERVER
+USERPROFILE
+HOMEDRIVE
+HOMEPATH
+$!end
+};
+#endif
+
+int
+dk4user_get_logname(dkChar *pdst, size_t szdst, int eff, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ DWORD sz;
+ int back = 0;
+ $? "+ dk4user_get_logname (Windows)"
+ if ((NULL != pdst) && (0 < szdst)) {
+ sz = (DWORD)szdst;
+#if DK4_CHAR_SIZE > 1
+ if(GetUserNameW(pdst, &sz))
+#else
+ if(GetUserNameA(pdst, &sz))
+#endif
+ {
+ if (sz < szdst) {
+ pdst[sz] = dkT('\0');
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ }
+ else
+ {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4user_get_logname (Windows) %d", back
+ return back;
+#else
+#if DK4_CHAR_SIZE > 1
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#else
+ struct passwd *pwent;
+ uid_t uid;
+ int back = 0;
+ $? "+ dk4user_get_logname (non-Windows, char)"
+ if ((NULL != pdst) && (0 < szdst)) {
+ if (0 != eff) { uid = geteuid(); } else { uid = getuid(); }
+ pwent = getpwuid(uid);
+ if (NULL != pwent) {
+ if (NULL != pwent->pw_name) {
+ if (0 != dk4str_cpy_s(pdst, szdst, pwent->pw_name, erp)) {
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4user_get_logname (non-Windows, char) %d", back
+ return back;
+#endif
+#endif
+}
+
+
+
+#if DK4_ON_WINDOWS
+
+
+
+/** Obtain home directory information using one logon server.
+ @param pdst Destination buffer pointer.
+ @param szdst Destination buffer size (number of wchar_t).
+ @param lsn Logon server name, may be NULL.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4user_get_i_ls_homedir(
+ wchar_t *pdst, size_t szdst, const wchar_t *lsn, dk4_er_t *erp
+)
+{
+ wchar_t b1[DK4_MAX_PATH+16]; /* Buffer RegQueryValue() */
+ wchar_t b2[DK4_MAX_PATH+16]; /* Buffer Expand...() */
+ wchar_t logname[256]; /* Login name */
+ dk4_er_t er; /* Error report */
+ USER_INFO_4 *pbuf4 = NULL; /* User information */
+ wchar_t *pStringSid = NULL; /* String SID */
+ wchar_t *keyname = NULL; /* Registry key name */
+ void *wrkey = NULL; /* Registry key */
+ DWORD szlog = DK4_SIZEOF(logname,wchar_t);
+ size_t sz = 0; /* Key name length */
+ int back = 0; /* Result */
+ NET_API_STATUS nStatus = 0; /* Network op result */
+ $? "+ dk4user_get_i_ls_homedir lsn=\"%!ws\"", TR_LSTR(lsn)
+ dk4error_init(&er);
+ if (GetUserNameW(logname, &szlog)) { $? ". user name found"
+ if (DK4_SIZEOF(logname,wchar_t) >= szlog) { $? ". name size ok"
+ logname[szlog] = L'\0';
+ nStatus = NetUserGetInfo(lsn, logname, (DWORD)4, (LPBYTE *)(&pbuf4));
+ if ((NERR_Success == nStatus) && (NULL != pbuf4)) { $? ". user info"
+ if (ConvertSidToStringSidW(pbuf4->usri4_user_sid, &pStringSid)) {
+ $? ". sid"
+ sz = dk4ma_size_t_add(
+ dk4ma_size_t_add(
+ 1,
+ dk4strw_len(dk4user_kw[0]),
+ &er
+ ),
+ dk4ma_size_t_add(
+ dk4strw_len(dk4user_kw[1]),
+ dk4strw_len(pStringSid),
+ &er
+ ),
+ &er
+ );
+ if (DK4_E_NONE == er.ec) { $? ". size calc 1 ok"
+ (void)dk4ma_size_t_mul(sizeof(wchar_t), sz, &er);
+ if (DK4_E_NONE == er.ec) { $? ". size calc 2 ok"
+ keyname = dk4mem_calloc(sizeof(wchar_t),sz,&er);
+ if (NULL != keyname) { $? ". calloc ok"
+ (void)dk4strw_cpy_s(keyname, sz, dk4user_kw[0], NULL);
+ (void)dk4strw_cat_s(keyname, sz, dk4user_kw[1], NULL);
+ (void)dk4strw_cat_s(keyname, sz, pStringSid, NULL);
+ wrkey = dk4wreg_open_key_wc(DK4_WREGKEY_HKLM, keyname, 0, &er);
+ if (NULL != wrkey) { $? ". key opened"
+ back = dk4wreg_get_expanded_string_wc(
+ wrkey,
+ dk4user_kw[2],
+ pdst, szdst,
+ b1, DK4_SIZEOF(b1,wchar_t),
+ b2, (DK4_SIZEOF(b2,wchar_t)-2),
+ &er
+ ); $? ". back = %d", back
+ dk4wreg_close_key(wrkey);
+ } else { $? "! registry key"
+ /* ERROR: Failed to open key (reported) */
+ }
+ dk4mem_free(keyname);
+ } else { $? "! memory"
+ /* ERROR: Memory (reported) */
+ }
+ } else { $? "! size calc overflow"
+ /* ERROR: Overflow in size calculation (reported) */
+ }
+ } else { $? "! size calc overflow"
+ /* ERROR: Overflow in size calculation (reported) */
+ }
+ } else { $? "! failed to convert sid"
+ /* ERROR: Failed to convert SID */
+ dk4error_set_simple_error_code(&er, DK4_E_NOT_FOUND);
+ }
+ if (NULL != pStringSid) {
+ LocalFree(pStringSid);
+ }
+ } else { $? "! failed to obtain info"
+ /* ERROR: No user info */
+ }
+ if (NULL != pbuf4) {
+ NetApiBufferFree(pbuf4);
+ }
+ } else { $? "! user name too long"
+ /* ERROR: User name too long */
+ dk4error_set_simple_error_code(&er, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else { $? "! user name not found"
+ /* ERROR: User name not found */
+ }
+ if (0 == back) {
+ dk4error_copy(erp, &er);
+ }
+ $? "- dk4user_get_i_ls_homedir %d", back
+ return back;
+}
+
+
+
+/** Find Windows home directory.
+ @param pdst Destination buffer pointer.
+ @param szdst Destination buffer size (number of wchar_t).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4user_get_i_homedir(wchar_t *pdst, size_t szdst, dk4_er_t *erp)
+{
+ dk4_er_t myerp;
+ wchar_t *lsn = NULL;
+ wchar_t *hop = NULL;
+ int back = 0;
+ $? "+ dk4user_get_i_homedir"
+ dk4error_init(&myerp);
+ back = dk4user_get_i_ls_homedir(pdst, szdst, NULL, &myerp);
+ $? ". back = %d", back
+ if ((0 == back) && (DK4_E_NONE == myerp.ec)) { $? ". attempt"
+ lsn = _wgetenv(dk4user_kw[4]); $? ". userprofile"
+ if (NULL != lsn) {
+ back = dk4strw_cpy_s(pdst, szdst, lsn, &myerp);
+ $? ". back = %d", back
+ } else { $? "! userprofile"
+ }
+ }
+ if ((0 == back) && (DK4_E_NONE == myerp.ec)) { $? ". attempt"
+ lsn = _wgetenv(dk4user_kw[5]);
+ hop = _wgetenv(dk4user_kw[6]);
+ if ((NULL != lsn) && (NULL != hop)) { $? ". drive / path"
+ if (0 != dk4strw_cpy_s(pdst, szdst, lsn, &myerp)) {
+ back = dk4strw_cat_s(pdst, szdst, hop, &myerp);
+ $? ". back = %d", back
+ } else { $? "! too long"
+ }
+ } else { $? "! drive / path"
+ }
+ }
+ if ((0 == back) && (DK4_E_NONE == myerp.ec)) { $? ". attempt"
+ lsn = _wgetenv(dk4user_kw[3]);
+ if (NULL != lsn) { $? ". env ok"
+ back = dk4user_get_i_ls_homedir(pdst, szdst, lsn, &myerp);
+ $? ". back = %d", back
+ }
+ }
+ if ((0 == back) && (DK4_E_NONE == myerp.ec)) { $? ". attempt"
+ if (NULL != lsn) { $? ". lsn"
+ if (L'\\' == lsn[0]) {
+ if (L'\\' == lsn[1]) {
+ back = dk4user_get_i_ls_homedir(pdst, szdst, &(lsn[2]), &myerp);
+ $? ". back = %d", back
+ } else { $? "! lsn[1]"
+ }
+ } else { $? "! lsn[0]"
+ }
+ } else { $? "! lsn"
+ }
+ }
+ if ((0 == back) && (DK4_E_NONE == myerp.ec)) {
+ dk4error_set_simple_error_code(&myerp, DK4_E_NOT_FOUND);
+ }
+ if (0 == back) {
+ dk4error_copy(erp, &myerp);
+ } $? "- dk4user_get_i_homedir %d", back
+ return back;
+}
+
+#endif
+
+
+int
+dk4user_get_homedir(dkChar *pdst, size_t szdst, int eff, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+/* +++++ Windows +++++ */
+#if DK4_CHAR_SIZE == 1
+ wchar_t homew[DK4_MAX_PATH];
+#endif
+ int back = 0;
+ $? "+ dk4user_get_homedir"
+ if ((NULL != pdst) && (0 < szdst)) { $? ". arguments"
+ *pdst = dkT('\0');
+#if DK4_CHAR_SIZE > 1
+ $? ". wchar_t"
+ back = dk4user_get_i_homedir(pdst, szdst, erp);
+#else
+ $? ". char"
+ if (0 != dk4user_get_i_homedir(homew, DK4_SIZEOF(homew,wchar_t), erp)) {
+ back = dk4recode_utf16_to_ansi(pdst, szdst, homew, erp);
+ }
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4user_get_homedir %d", back
+ return back;
+/* ----- Windows ----- */
+#else
+/* +++++ non-Windows +++++ */
+#if DK4_CHAR_SIZE > 1
+/* +++++ non-Windows wchar_t +++++ */
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+/* ----- non-Windows wchar_t ----- */
+#else
+/* +++++ non-Windows char +++++ */
+ struct passwd *pwent;
+ uid_t uid;
+ int back = 0;
+ $? "+ dk4user_get_homedir (non-windows, char)"
+ if ((NULL != pdst) && (0 < szdst)) {
+ if (0 != eff) { uid = geteuid(); } else { uid = getuid(); }
+ pwent = getpwuid(uid);
+ if (NULL != pwent) {
+ if (NULL != pwent->pw_dir) {
+ if (0 != dk4str8_cpy_s(pdst, szdst, pwent->pw_dir, erp)) {
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4user_get_homedir (non-windows, char) %d", back
+ return back;
+/* ----- non-Windows char ----- */
+#endif
+/* ----- non-Windows ----- */
+#endif
+}
+
diff --git a/support/dktools/dk4user.h b/support/dktools/dk4user.h
new file mode 100644
index 0000000000..62bf5c3ef8
--- /dev/null
+++ b/support/dktools/dk4user.h
@@ -0,0 +1,119 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4user.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4USER_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4USER_H_INCLUDED 1
+
+
+#line 10 "dk4user.ctr"
+
+/** @file
+ Get information about user
+ (login name and home directory).
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Get users login name.
+ @param pdst Pointer to destination buffer.
+ @param szdst Size of destination buffer (number of characters).
+ @param eff Flag: Retrieve information about effective user.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ CRT on Windows: Not used.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if pdst is NULL or szdst is 0,
+ - DK4_E_NOT_FOUND<br>
+ if the login name was not found,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the buffer is too small for the result.
+*/
+int
+dk4user_get_logname(dkChar *pdst, size_t szdst, int eff, dk4_er_t *erp);
+
+/** Get users home directory.
+ @param pdst Pointer to destination buffer.
+ @param szdst Size of destination buffer (number of characters).
+ @param eff Flag: Retrieve information about effective user.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ CRT on Windows: Optional.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if pdst is NULL or szdst is 0,
+ - DK4_E_NOT_FOUND<br>
+ if the login name, the user entry or the home
+ directory was not found,
+ - DK4_E_MEMORY<br>
+ if an internal memory allocation failed,
+ - DK4_E_SYNTAX<br>
+ if the retrieved registry entry on
+ Windows is not a string,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the pdst buffer or one of the internal buffers
+ is too small for the result.
+*/
+int
+dk4user_get_homedir(dkChar *pdst, size_t szdst, int eff, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4userf.c b/support/dktools/dk4userf.c
new file mode 100644
index 0000000000..29b7a6b07a
--- /dev/null
+++ b/support/dktools/dk4userf.c
@@ -0,0 +1,388 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4userf.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4userf.c The dk4userf module.
+*/
+
+
+#line 147 "dk4userf.ctr"
+
+#include "dk4userf.h"
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_MATH_H
+#ifndef MATH_H_INCLUDED
+#ifdef _WIN32
+#define _USE_MATH_DEFINES 1
+#endif
+#include <math.h>
+#define MATH_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FLOAT_H
+#ifndef FLOAT_H_INCLUDED
+#include <float.h>
+#define FLOAT_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4enc.h"
+#include "dk4mem.h"
+#include "dk4rec04.h"
+#include "dk4rec06.h"
+#include "dk4rec11.h"
+#include "dk4rec17.h"
+
+
+
+
+#line 183 "dk4userf.ctr"
+
+
+
+int
+dk4unserialize_file_uint16_t(uint16_t *dptr, FILE *fipo, dk4_er_t *erp)
+{
+ unsigned char uc[2];
+ uint16_t ui16;
+ int back = 0;
+
+ if ((NULL != dptr) && (NULL != fipo)) {
+ if (2 == fread(uc, 1, 2, fipo)) {
+ ui16 = (((uint16_t)(uc[0]) << 8) & 0xFF00U)
+ | (((uint16_t)(uc[1])) & 0x00FFU);
+ *dptr = ui16;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_READ_FAILED);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4unserialize_file_int16_t(int16_t *dptr, FILE *fipo, dk4_er_t *erp)
+{
+ uint16_t ui;
+ int back = 0;
+
+ if ((NULL != dptr) && (NULL != fipo)) {
+ back = dk4unserialize_file_uint16_t(&ui, fipo, erp);
+ if (0 != back) {
+ *dptr = (int16_t)ui;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4unserialize_file_uint32_t(uint32_t *dptr, FILE *fipo, dk4_er_t *erp)
+{
+ unsigned char uc[4];
+ uint32_t ui32;
+ int back = 0;
+
+
+#line 236 "dk4userf.ctr"
+ if ((NULL != dptr) && (NULL != fipo)) {
+
+#line 237 "dk4userf.ctr"
+ if (4 == fread(uc, 1, 4, fipo)) {
+
+#line 238 "dk4userf.ctr"
+ ui32 = ((((uint32_t)(uc[0])) << 24) & 0xFF000000UL)
+ | ((((uint32_t)(uc[1])) << 16) & 0x00FF0000UL)
+ | ((((uint32_t)(uc[2])) << 8) & 0x0000FF00UL)
+ | (( (uint32_t)(uc[3])) & 0x000000FFUL);
+ *dptr = ui32;
+ back = 1;
+ } else {
+
+#line 245 "dk4userf.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_READ_FAILED);
+ }
+ } else {
+
+#line 248 "dk4userf.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 251 "dk4userf.ctr"
+ return back;
+}
+
+
+
+int
+dk4unserialize_file_int32_t(int32_t *dptr, FILE *fipo, dk4_er_t *erp)
+{
+ uint32_t ui32;
+ int back = 0;
+ if ((NULL != dptr) && (NULL != fipo)) {
+ back = dk4unserialize_file_uint32_t(&ui32, fipo, erp);
+ if (0 != back) {
+ *dptr = (int32_t)ui32;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4unserialize_file_utf8_string(char **dptr, FILE *fipo, dk4_er_t *erp)
+{
+ char *np = NULL;
+ size_t ls = 0;
+ int back = 0;
+ uint16_t lgt = 0;
+ if ((NULL != dptr) && (NULL != fipo)) {
+ if (0 != dk4unserialize_file_uint16_t(&lgt, fipo, erp)) {
+ if (0 < lgt) {
+ ls = (size_t)lgt;
+ np = dk4mem_new(char,ls,erp);
+ if (NULL != np) {
+ if (fread(np, 1, ls, fipo) == ls) {
+ if ('\0' == np[ls - 1]) {
+ back = 1;
+ *dptr = np;
+ } else {
+ dk4mem_free(np);
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4mem_free(np);
+ dk4error_set_simple_error_code(erp, DK4_E_READ_FAILED);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4unserialize_file_double(double *dptr, FILE *fipo, dk4_er_t *erp)
+{
+ char *bptr = NULL;
+ char *tg = NULL;
+ double dv = 0.0;
+ int back = 0;
+ if ((NULL != dptr) && (NULL != fipo)) {
+ if (0 != dk4unserialize_file_utf8_string(&bptr, fipo, erp)) {
+ if (NULL != bptr) {
+ errno = 0;
+ dv = strtod(bptr, &tg);
+ if ((HUGE_VAL == dv) && (ERANGE == errno)) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ if ((-HUGE_VAL == dv) && (ERANGE == errno)) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ if ((0.0 == dv) && (ERANGE == errno)) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ back = 1;
+ if (NULL != tg) {
+ while ('\0' != *tg) {
+ if (
+ (' ' != *tg) && ('\t' != *tg)
+ && ('\r' != *tg) && ('\n' != *tg)
+ )
+ {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ tg++;
+ }
+ }
+ }
+ }
+ }
+ dk4mem_free(bptr);
+ *dptr = dv;
+ } else {
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+int
+dk4unserialize_file_dk_string(dkChar **dptr, int de, FILE *fipo, dk4_er_t *erp)
+{
+ dkChar *resb = NULL;
+ char *putf8 = NULL;
+ size_t szdk = 0;
+ int back = 0;
+ if ((NULL != dptr) && (NULL != fipo)) {
+ if (0 != dk4unserialize_file_utf8_string(&putf8, fipo, erp)) {
+ if (NULL != putf8) {
+ switch (de) {
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ case DK4_ENCODING_32 : {
+ szdk = dk4recode_size_utf8_to_c32(putf8, erp);
+ if ((0 < szdk) && ((SIZE_MAX / sizeof(dk4_c32_t)) >= szdk)) {
+ resb = dk4mem_new(dk4_c32_t,szdk,erp);
+ if (NULL != resb) {
+ back = dk4recode_utf8_to_c32(resb, szdk, putf8, erp);
+ if (0 != back) {
+ if (dkT('\0') == resb[szdk - 1]) {
+ *dptr = resb;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ dk4mem_free(resb);
+ }
+ } else {
+ dk4mem_free(resb);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } break;
+#else
+ case DK4_ENCODING_UTF16 : {
+ szdk = dk4recode_size_utf8_to_utf16(putf8, erp);
+ if ((0 < szdk) && ((SIZE_MAX / sizeof(dk4_c16_t)) >= szdk)) {
+ resb = dk4mem_new(dk4_c16_t,szdk,erp);
+ if (NULL != resb) {
+ back = dk4recode_utf8_to_utf16(resb, szdk, putf8, erp);
+ if (0 != back) {
+ if (dkT('\0') == resb[szdk - 1]) {
+ *dptr = resb;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ dk4mem_free(resb);
+ }
+ } else {
+ dk4mem_free(resb);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } break;
+#endif
+#else
+ case DK4_ENCODING_ASCII : {
+ szdk = dk4recode_size_utf8_to_ascii(putf8, erp);
+ if (0 < szdk) {
+ resb = dk4mem_new(char,szdk,erp);
+ if (NULL != resb) {
+ back = dk4recode_utf8_to_ascii(resb, szdk, putf8, erp);
+ if (0 != back) {
+ if ('\0' == resb[szdk - 1]) {
+ *dptr = resb;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ dk4mem_free(resb);
+ }
+ } else {
+ dk4mem_free(resb);
+ }
+ }
+ }
+ } break;
+ case DK4_ENCODING_ANSI : {
+ szdk = dk4recode_size_utf8_to_ansi(putf8, erp);
+ if (0 < szdk) {
+ resb = dk4mem_new(char,szdk,erp);
+ if (NULL != resb) {
+ back = dk4recode_utf8_to_ansi(resb, szdk, putf8, erp);
+ if (0 != back) {
+ if ('\0' == resb[szdk - 1]) {
+ *dptr = resb;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ dk4mem_free(resb);
+ }
+ } else {
+ dk4mem_free(resb);
+ }
+ }
+ }
+ } break;
+ case DK4_ENCODING_UTF8 : {
+ *dptr = putf8;
+ putf8 = NULL;
+ back = 1;
+ } break;
+#endif
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } break;
+ }
+ }
+ if (NULL != putf8) {
+ dk4mem_free(putf8);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
diff --git a/support/dktools/dk4userf.ctr b/support/dktools/dk4userf.ctr
new file mode 100644
index 0000000000..0166022078
--- /dev/null
+++ b/support/dktools/dk4userf.ctr
@@ -0,0 +1,480 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk4userf.h Unserialize (read) data from binary file.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef DK4_STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define DK4_STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef DK4_SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define DK4_SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDINT_H
+#ifndef DK4_STDINT_H_INCLUDED
+#include <stdint.h>
+#define DK4_STDINT_H_INCLUDED 1
+#endif
+#endif
+
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** Unserialize (read) a 16 bit unsigned number from binary file.
+ @param dptr Address of destination variable.
+ @param fipo Input file (opened for binary read access).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+
+int
+dk4unserialize_file_uint16_t(uint16_t *dptr, FILE *fipo, dk4_er_t *erp);
+
+
+/** Unserialize (read) a 16 bit signed number from binary file.
+ @param dptr Address of destination variable.
+ @param fipo Input file (opened for binary read access).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+
+int
+dk4unserialize_file_int16_t(int16_t *dptr, FILE *fipo, dk4_er_t *erp);
+
+
+/** Unserialize (read) a 32 bit unsigned number from binary file.
+ @param dptr Address of destination variable.
+ @param fipo Input file (opened for binary read access).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+
+int
+dk4unserialize_file_uint32_t(uint32_t *dptr, FILE *fipo, dk4_er_t *erp);
+
+
+/** Unserialize (read) a 32 bit signed number from binary file.
+ @param dptr Address of destination variable.
+ @param fipo Input file (opened for binary read access).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+
+int
+dk4unserialize_file_int32_t(int32_t *dptr, FILE *fipo, dk4_er_t *erp);
+
+
+/** Unserialize (read) an UTF-8 encoded text string from binary file.
+ On success the function dynamically allocates memory for the string
+ and sets the pointer to this memory. Use dk4mem_free() to release
+ the memory after use.
+ @param dptr Address of destination pointer variable, initialize
+ the pointer to NULL before calling this function.
+ @param fipo Input file (opened for binary read access).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+
+int
+dk4unserialize_file_utf8_string(char **dptr, FILE *fipo, dk4_er_t *erp);
+
+
+/** Unserialize (read) a text string in the system default encoding
+ from binary file.
+ On success the function dynamically allocates memory for the string
+ and sets the pointer to this memory. Use dk4mem_free() to release
+ the memory after use.
+ @param dptr Address of destination pointer variable, initialize
+ the pointer to NULL before calling this function.
+ @param de Encoding for dkChar.
+ @param fipo Input file (opened for binary read access).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+
+int
+dk4unserialize_file_dk_string(dkChar **dptr, int de, FILE *fipo, dk4_er_t *erp);
+
+
+/** Unserialize (read) a double number from binary file.
+ @param dptr Address of destination variable.
+ @param fipo Input file (opened for binary read access).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+
+int
+dk4unserialize_file_double(double *dptr, FILE *fipo, dk4_er_t *erp);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk4userf.h"
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_MATH_H
+#ifndef MATH_H_INCLUDED
+#ifdef _WIN32
+#define _USE_MATH_DEFINES 1
+#endif
+#include <math.h>
+#define MATH_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FLOAT_H
+#ifndef FLOAT_H_INCLUDED
+#include <float.h>
+#define FLOAT_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4enc.h"
+#include "dk4mem.h"
+#include "dk4rec04.h"
+#include "dk4rec06.h"
+#include "dk4rec11.h"
+#include "dk4rec17.h"
+
+
+$!trace-include
+
+
+
+int
+dk4unserialize_file_uint16_t(uint16_t *dptr, FILE *fipo, dk4_er_t *erp)
+{
+ unsigned char uc[2];
+ uint16_t ui16;
+ int back = 0;
+
+ if ((NULL != dptr) && (NULL != fipo)) {
+ if (2 == fread(uc, 1, 2, fipo)) {
+ ui16 = (((uint16_t)(uc[0]) << 8) & 0xFF00U)
+ | (((uint16_t)(uc[1])) & 0x00FFU);
+ *dptr = ui16;
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_READ_FAILED);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4unserialize_file_int16_t(int16_t *dptr, FILE *fipo, dk4_er_t *erp)
+{
+ uint16_t ui;
+ int back = 0;
+
+ if ((NULL != dptr) && (NULL != fipo)) {
+ back = dk4unserialize_file_uint16_t(&ui, fipo, erp);
+ if (0 != back) {
+ *dptr = (int16_t)ui;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4unserialize_file_uint32_t(uint32_t *dptr, FILE *fipo, dk4_er_t *erp)
+{
+ unsigned char uc[4];
+ uint32_t ui32;
+ int back = 0;
+ $? "+ dk4unserialize_file_uint32_t"
+ if ((NULL != dptr) && (NULL != fipo)) { $? ". args ok"
+ if (4 == fread(uc, 1, 4, fipo)) { $? ". fread"
+ ui32 = ((((uint32_t)(uc[0])) << 24) & 0xFF000000UL)
+ | ((((uint32_t)(uc[1])) << 16) & 0x00FF0000UL)
+ | ((((uint32_t)(uc[2])) << 8) & 0x0000FF00UL)
+ | (( (uint32_t)(uc[3])) & 0x000000FFUL);
+ *dptr = ui32;
+ back = 1;
+ } else { $? "! fread"
+ dk4error_set_simple_error_code(erp, DK4_E_READ_FAILED);
+ }
+ } else { $? "! args"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4unserialize_file_uint32_t %d", back
+ return back;
+}
+
+
+
+int
+dk4unserialize_file_int32_t(int32_t *dptr, FILE *fipo, dk4_er_t *erp)
+{
+ uint32_t ui32;
+ int back = 0;
+ if ((NULL != dptr) && (NULL != fipo)) {
+ back = dk4unserialize_file_uint32_t(&ui32, fipo, erp);
+ if (0 != back) {
+ *dptr = (int32_t)ui32;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4unserialize_file_utf8_string(char **dptr, FILE *fipo, dk4_er_t *erp)
+{
+ char *np = NULL;
+ size_t ls = 0;
+ int back = 0;
+ uint16_t lgt = 0;
+ if ((NULL != dptr) && (NULL != fipo)) {
+ if (0 != dk4unserialize_file_uint16_t(&lgt, fipo, erp)) {
+ if (0 < lgt) {
+ ls = (size_t)lgt;
+ np = dk4mem_new(char,ls,erp);
+ if (NULL != np) {
+ if (fread(np, 1, ls, fipo) == ls) {
+ if ('\0' == np[ls - 1]) {
+ back = 1;
+ *dptr = np;
+ } else {
+ dk4mem_free(np);
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4mem_free(np);
+ dk4error_set_simple_error_code(erp, DK4_E_READ_FAILED);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4unserialize_file_double(double *dptr, FILE *fipo, dk4_er_t *erp)
+{
+ char *bptr = NULL;
+ char *tg = NULL;
+ double dv = 0.0;
+ int back = 0;
+ if ((NULL != dptr) && (NULL != fipo)) {
+ if (0 != dk4unserialize_file_utf8_string(&bptr, fipo, erp)) {
+ if (NULL != bptr) {
+ errno = 0;
+ dv = strtod(bptr, &tg);
+ if ((HUGE_VAL == dv) && (ERANGE == errno)) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ if ((-HUGE_VAL == dv) && (ERANGE == errno)) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ if ((0.0 == dv) && (ERANGE == errno)) {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ } else {
+ back = 1;
+ if (NULL != tg) {
+ while ('\0' != *tg) {
+ if (
+ (' ' != *tg) && ('\t' != *tg)
+ && ('\r' != *tg) && ('\n' != *tg)
+ )
+ {
+ back = 0;
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ tg++;
+ }
+ }
+ }
+ }
+ }
+ dk4mem_free(bptr);
+ *dptr = dv;
+ } else {
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+int
+dk4unserialize_file_dk_string(dkChar **dptr, int de, FILE *fipo, dk4_er_t *erp)
+{
+ dkChar *resb = NULL;
+ char *putf8 = NULL;
+ size_t szdk = 0;
+ int back = 0;
+ if ((NULL != dptr) && (NULL != fipo)) {
+ if (0 != dk4unserialize_file_utf8_string(&putf8, fipo, erp)) {
+ if (NULL != putf8) {
+ switch (de) {
+#if DK4_CHAR_SIZE > 1
+#if DK4_CHAR_SIZE > 2
+ case DK4_ENCODING_32 : {
+ szdk = dk4recode_size_utf8_to_c32(putf8, erp);
+ if ((0 < szdk) && ((SIZE_MAX / sizeof(dk4_c32_t)) >= szdk)) {
+ resb = dk4mem_new(dk4_c32_t,szdk,erp);
+ if (NULL != resb) {
+ back = dk4recode_utf8_to_c32(resb, szdk, putf8, erp);
+ if (0 != back) {
+ if (dkT('\0') == resb[szdk - 1]) {
+ *dptr = resb;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ dk4mem_free(resb);
+ }
+ } else {
+ dk4mem_free(resb);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } break;
+#else
+ case DK4_ENCODING_UTF16 : {
+ szdk = dk4recode_size_utf8_to_utf16(putf8, erp);
+ if ((0 < szdk) && ((SIZE_MAX / sizeof(dk4_c16_t)) >= szdk)) {
+ resb = dk4mem_new(dk4_c16_t,szdk,erp);
+ if (NULL != resb) {
+ back = dk4recode_utf8_to_utf16(resb, szdk, putf8, erp);
+ if (0 != back) {
+ if (dkT('\0') == resb[szdk - 1]) {
+ *dptr = resb;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ dk4mem_free(resb);
+ }
+ } else {
+ dk4mem_free(resb);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } break;
+#endif
+#else
+ case DK4_ENCODING_ASCII : {
+ szdk = dk4recode_size_utf8_to_ascii(putf8, erp);
+ if (0 < szdk) {
+ resb = dk4mem_new(char,szdk,erp);
+ if (NULL != resb) {
+ back = dk4recode_utf8_to_ascii(resb, szdk, putf8, erp);
+ if (0 != back) {
+ if ('\0' == resb[szdk - 1]) {
+ *dptr = resb;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ dk4mem_free(resb);
+ }
+ } else {
+ dk4mem_free(resb);
+ }
+ }
+ }
+ } break;
+ case DK4_ENCODING_ANSI : {
+ szdk = dk4recode_size_utf8_to_ansi(putf8, erp);
+ if (0 < szdk) {
+ resb = dk4mem_new(char,szdk,erp);
+ if (NULL != resb) {
+ back = dk4recode_utf8_to_ansi(resb, szdk, putf8, erp);
+ if (0 != back) {
+ if ('\0' == resb[szdk - 1]) {
+ *dptr = resb;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ dk4mem_free(resb);
+ }
+ } else {
+ dk4mem_free(resb);
+ }
+ }
+ }
+ } break;
+ case DK4_ENCODING_UTF8 : {
+ *dptr = putf8;
+ putf8 = NULL;
+ back = 1;
+ } break;
+#endif
+ default : {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } break;
+ }
+ }
+ if (NULL != putf8) {
+ dk4mem_free(putf8);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
diff --git a/support/dktools/dk4userf.h b/support/dktools/dk4userf.h
new file mode 100644
index 0000000000..740662eda9
--- /dev/null
+++ b/support/dktools/dk4userf.h
@@ -0,0 +1,179 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4userf.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4USERF_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4USERF_H_INCLUDED 1
+
+
+#line 10 "dk4userf.ctr"
+
+/** @file dk4userf.h Unserialize (read) data from binary file.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef DK4_STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define DK4_STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef DK4_SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define DK4_SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDINT_H
+#ifndef DK4_STDINT_H_INCLUDED
+#include <stdint.h>
+#define DK4_STDINT_H_INCLUDED 1
+#endif
+#endif
+
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** Unserialize (read) a 16 bit unsigned number from binary file.
+ @param dptr Address of destination variable.
+ @param fipo Input file (opened for binary read access).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+
+int
+dk4unserialize_file_uint16_t(uint16_t *dptr, FILE *fipo, dk4_er_t *erp);
+
+
+/** Unserialize (read) a 16 bit signed number from binary file.
+ @param dptr Address of destination variable.
+ @param fipo Input file (opened for binary read access).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+
+int
+dk4unserialize_file_int16_t(int16_t *dptr, FILE *fipo, dk4_er_t *erp);
+
+
+/** Unserialize (read) a 32 bit unsigned number from binary file.
+ @param dptr Address of destination variable.
+ @param fipo Input file (opened for binary read access).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+
+int
+dk4unserialize_file_uint32_t(uint32_t *dptr, FILE *fipo, dk4_er_t *erp);
+
+
+/** Unserialize (read) a 32 bit signed number from binary file.
+ @param dptr Address of destination variable.
+ @param fipo Input file (opened for binary read access).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+
+int
+dk4unserialize_file_int32_t(int32_t *dptr, FILE *fipo, dk4_er_t *erp);
+
+
+/** Unserialize (read) an UTF-8 encoded text string from binary file.
+ On success the function dynamically allocates memory for the string
+ and sets the pointer to this memory. Use dk4mem_free() to release
+ the memory after use.
+ @param dptr Address of destination pointer variable, initialize
+ the pointer to NULL before calling this function.
+ @param fipo Input file (opened for binary read access).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+
+int
+dk4unserialize_file_utf8_string(char **dptr, FILE *fipo, dk4_er_t *erp);
+
+
+/** Unserialize (read) a text string in the system default encoding
+ from binary file.
+ On success the function dynamically allocates memory for the string
+ and sets the pointer to this memory. Use dk4mem_free() to release
+ the memory after use.
+ @param dptr Address of destination pointer variable, initialize
+ the pointer to NULL before calling this function.
+ @param de Encoding for dkChar.
+ @param fipo Input file (opened for binary read access).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+
+int
+dk4unserialize_file_dk_string(dkChar **dptr, int de, FILE *fipo, dk4_er_t *erp);
+
+
+/** Unserialize (read) a double number from binary file.
+ @param dptr Address of destination variable.
+ @param fipo Input file (opened for binary read access).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+
+int
+dk4unserialize_file_double(double *dptr, FILE *fipo, dk4_er_t *erp);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4utf16.c b/support/dktools/dk4utf16.c
new file mode 100644
index 0000000000..0f763e4028
--- /dev/null
+++ b/support/dktools/dk4utf16.c
@@ -0,0 +1,361 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4utf16.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4utf16.c The dk4utf16 module.
+*/
+
+
+#line 171 "dk4utf16.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4utf16.h"
+#include "dk4mem.h"
+
+
+
+
+
+#line 181 "dk4utf16.ctr"
+
+
+
+/** State value in dk4_utf16_decoder_t.
+*/
+enum {
+ /** No surrogate yet.
+ */
+ DK4_UTF16_DEC_ST_EMPTY = 0,
+
+ /** Found high surrogate,
+ expecting corresponding
+ low surrogate.
+ */
+ DK4_UTF16_DEC_ST_HAVE_HIGH_SURROGATE ,
+
+ /** Found low surrogate,
+ expecting corresponding
+ high surrogate.
+ */
+ DK4_UTF16_DEC_ST_HAVE_LOW_SURROGATE
+};
+
+
+
+void
+dk4utf16_init(dk4_utf16_decoder_t *ptr)
+{
+ if (NULL != ptr) {
+ ptr->uc = dkC32(0);
+ ptr->state = DK4_UTF16_DEC_ST_EMPTY;
+ }
+}
+
+
+
+int
+dk4utf16_add(dk4_utf16_decoder_t *ptr, dk4_c16_t word)
+{
+ int back = DK4_EDSTM_ERROR;
+ if (NULL != ptr) {
+ switch (ptr->state) {
+ case DK4_UTF16_DEC_ST_EMPTY: {
+ if ((dkC32(0x0000DC00) & ((dk4_c32_t)word)) == dkC32(0x0000DC00)) {
+ ptr->state = DK4_UTF16_DEC_ST_HAVE_LOW_SURROGATE;
+ ptr->uc = ((dk4_c32_t)word) & dkC32(0x000003FF);
+ back = DK4_EDSTM_ACCEPT;
+ } else {
+ if ((dkC32(0x0000DC00) & ((dk4_c32_t)word)) == dkC32(0x0000D800)) {
+ ptr->state = DK4_UTF16_DEC_ST_HAVE_HIGH_SURROGATE;
+ ptr->uc = ((((dk4_c32_t)word) << 10) & dkC32(0x000FFC00));
+ back = DK4_EDSTM_ACCEPT;
+ } else {
+ ptr->uc = ((dk4_c32_t)word) & dkC32(0x0000FFFF);
+ back = DK4_EDSTM_FINISHED;
+ }
+ }
+ } break;
+ case DK4_UTF16_DEC_ST_HAVE_HIGH_SURROGATE: {
+ if ((dkC32(0x0000DC00) & ((dk4_c32_t)word)) == dkC32(0x0000DC00)) {
+ ptr->uc |= (((dk4_c32_t)word) & dkC32(0x000003FF));
+ ptr->uc += dkC32(0x00010000);
+ ptr->state = DK4_UTF16_DEC_ST_EMPTY;
+ back = DK4_EDSTM_FINISHED;
+ } else {
+ back = DK4_EDSTM_ERROR;
+ ptr->state = DK4_UTF16_DEC_ST_EMPTY;
+ }
+ } break;
+ case DK4_UTF16_DEC_ST_HAVE_LOW_SURROGATE: {
+ if ((((dk4_c32_t)word) & dkC32(0x0000DC00)) == dkC32(0x0000D800)) {
+ ptr->uc |= ((((dk4_c32_t)word) << 10) & dkC32(0x000FFC00));
+ ptr->uc += dkC32(0x00010000);
+ ptr->state = DK4_UTF16_DEC_ST_EMPTY;
+ back = DK4_EDSTM_FINISHED;
+ } else {
+ back = DK4_EDSTM_ERROR;
+ ptr->state = DK4_UTF16_DEC_ST_EMPTY;
+ }
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+dk4_c32_t
+dk4utf16_get(dk4_utf16_decoder_t *ptr)
+{
+ dk4_c32_t back = dkC32(0);
+ if (NULL != ptr) {
+ back = ptr->uc;
+ }
+ return back;
+}
+
+
+
+int
+dk4utf16_is_empty(dk4_utf16_decoder_t *ptr)
+{
+ int back = 0;
+ if (NULL != ptr) {
+ if (DK4_UTF16_DEC_ST_EMPTY == ptr->state) { back = 1; }
+ }
+ return back;
+}
+
+
+
+int
+dk4utf16_encode(dk4_c16_t *rb, size_t *pszrb, dk4_c32_t c, dk4_er_t *erp)
+{
+ int back = 0;
+
+
+#line 297 "dk4utf16.ctr"
+ if ((NULL != rb) && (NULL != pszrb)) {
+ if (2 < *pszrb) {
+
+#line 299 "dk4utf16.ctr"
+ if ( dkC32(0x00010000) <= c ) {
+
+#line 300 "dk4utf16.ctr"
+ if ( dkC32(0x0010FFFF) >= c ) {
+
+#line 301 "dk4utf16.ctr"
+ back = 1;
+ *pszrb = 2;
+ rb[0] =
+ (dk4_c16_t)(((c >> 10) & dkC32(0x000003FF)) | dkC32(0x0000D800));
+ rb[1] =
+ (dk4_c16_t)((c & dkC32(0x000003FF)) | dkC32(0x0000DC00));
+ rb[2] = (dk4_c16_t)0;
+ } else {
+
+#line 309 "dk4utf16.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+
+#line 312 "dk4utf16.ctr"
+#if VERSION_BEFORE_20141125
+ if ((0x0000DC00 & c) != dkC32(0x0000DC00)) {
+
+#line 314 "dk4utf16.ctr"
+ if ((0x0000DC00 & c) != dkC32(0x0000D800)) {
+
+#line 315 "dk4utf16.ctr"
+ back = 1;
+ *pszrb = 1;
+ rb[0] = (dk4_c16_t)(c & dkC32(0x0000FFFF));
+ rb[1] = (dk4_c16_t)0;
+ } else {
+
+#line 320 "dk4utf16.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+
+#line 323 "dk4utf16.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+#else
+ if ((dkC32(0x0000DFFF) < c) || (dkC32(0x0000D800) > c)) {
+
+
+#line 328 "dk4utf16.ctr"
+ back = 1;
+ *pszrb = 1;
+ rb[0] = (dk4_c16_t)(c & dkC32(0x0000FFFF));
+ rb[1] = (dk4_c16_t)0;
+ } else {
+
+#line 333 "dk4utf16.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+#endif
+ }
+ } else {
+
+#line 338 "dk4utf16.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+
+#line 341 "dk4utf16.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 343 "dk4utf16.ctr"
+ return back;
+}
+
+
+
+void
+dk4utf16_byte_init(dk4_utf16_byte_decoder_t *ptr, int msb)
+{
+ if (NULL != ptr) {
+ dk4utf16_init(&(ptr->dec));
+ ptr->msb = msb;
+ ptr->state = 0;
+ ptr->saved = (dk4_c16_t)0;
+ }
+}
+
+
+
+int
+dk4utf16_byte_add(dk4_utf16_byte_decoder_t *ptr, unsigned char byte)
+{
+ int back = DK4_EDSTM_ERROR;
+ if (NULL != ptr) {
+ if (0 != ptr->state) {
+ ptr->state = 0;
+ if (0 != ptr->msb) {
+ ptr->saved |= (((dk4_c16_t)byte) & dkC16(0x00FF));
+ } else {
+ ptr->saved |= ((((dk4_c16_t)byte) << 8) & dkC16(0xFF00));
+ }
+ back = dk4utf16_add(&(ptr->dec), ptr->saved);
+ ptr->saved = (dk4_c16_t)0;
+ } else {
+ ptr->state = 1;
+ if (0 != ptr->msb) {
+ ptr->saved = ((((dk4_c16_t)byte) << 8) & dkC16(0xFF00));
+ } else {
+ ptr->saved = (((dk4_c16_t)byte) & dkC16(0x00FF));
+ }
+ back = DK4_EDSTM_ACCEPT;
+ }
+ }
+ return back;
+}
+
+
+
+dk4_c32_t
+dk4utf16_byte_get(dk4_utf16_byte_decoder_t *ptr)
+{
+ dk4_c32_t back = dkC32(0);
+ if (NULL != ptr) {
+ back = dk4utf16_get(&(ptr->dec));
+ }
+ return back;
+}
+
+
+
+int
+dk4utf16_byte_is_empty(dk4_utf16_byte_decoder_t *ptr)
+{
+ int back = 0;
+ if (NULL != ptr) {
+ back = dk4utf16_is_empty(&(ptr->dec));
+ if (0 != ptr->state) { back = 0; }
+ }
+ return back;
+}
+
+
+
+int
+dk4utf16_byte_encode(
+ unsigned char *rb, size_t *pszrb, dk4_c32_t c, int msb, dk4_er_t *erp
+)
+{
+ dk4_c16_t buf[3];
+ size_t sz;
+ int back = 0;
+ if ((NULL != rb) && (NULL != pszrb)) {
+ if (4 < *pszrb) {
+ sz = DK4_SIZEOF(buf,dk4_c16_t);
+ if (0 != dk4utf16_encode(buf, &sz, c, erp)) {
+ back = 1;
+ if (0 != msb) {
+ rb[0] = (unsigned char)((buf[0] >> 8) & dkC16(0x00FF));
+ rb[1] = (unsigned char)(buf[0] & dkC16(0x00FF));
+ } else {
+ rb[1] = (unsigned char)((buf[0] >> 8) & dkC16(0x00FF));
+ rb[0] = (unsigned char)(buf[0] & dkC16(0x00FF));
+ }
+ if (1 < sz) {
+ if (0 != msb) {
+ rb[2] = (unsigned char)((buf[1] >> 8) & dkC16(0x00FF));
+ rb[3] = (unsigned char)(buf[1] & dkC16(0x00FF));
+ } else {
+ rb[3] = (unsigned char)((buf[1] >> 8) & dkC16(0x00FF));
+ rb[2] = (unsigned char)(buf[1] & dkC16(0x00FF));
+ }
+ *pszrb = 4;
+ rb[4] = '\0';
+ } else {
+ *pszrb = 2;
+ rb[2] = '\0';
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4utf16.ctr b/support/dktools/dk4utf16.ctr
new file mode 100644
index 0000000000..8ee3ff313b
--- /dev/null
+++ b/support/dktools/dk4utf16.ctr
@@ -0,0 +1,459 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Encode and decode 32 bit characters
+ in UTF-16 encoding.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4DEC_H_INCLUDED
+#include "dk4edstm.h"
+#endif
+
+/** Decode UTF-16 encoded data.
+*/
+typedef struct {
+ dk4_c32_t uc; /**< Unicode character to produce. */
+ int state; /**< Decoder state. */
+} dk4_utf16_decoder_t;
+
+
+
+/** Decode UTF-16 encoded bytes.
+*/
+typedef struct {
+ dk4_utf16_decoder_t dec; /**< Decoder UTF-16 to 32-bit char. */
+ int msb; /**< Flag: Most significant byte comes first. */
+ int state; /**< Decoder state. */
+ dk4_c16_t saved; /**< Partial input character saved. */
+} dk4_utf16_byte_decoder_t;
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Initialize the UTF-16 decoder.
+ @param ptr Decoder to initialize.
+*/
+void
+dk4utf16_init(dk4_utf16_decoder_t *ptr);
+
+/** Add one word to the decoder.
+ @param ptr Decoder to use.
+ @param word Word to add.
+ @return Operation result, one from:
+ DK4_EDSTM_ACCEPT if the byte was added to the next output
+ without completing output,
+ DK4_EDSTM_FINISHED, if the byte was added to the next output
+ completing the output, or
+ DK4_EDSTM_ERROR on error.
+*/
+int
+dk4utf16_add(dk4_utf16_decoder_t *ptr, dk4_c16_t word);
+
+/** Retrieve a completed Unicode character from the decoder.
+ @param ptr Decoder to obtain character from.
+*/
+dk4_c32_t
+dk4utf16_get(dk4_utf16_decoder_t *ptr);
+
+/** Check whether the decoder is empty.
+ @param ptr Decoder to check.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4utf16_is_empty(dk4_utf16_decoder_t *ptr);
+
+/** UTF-16 encode UNICODE character.
+ @param rb Result buffer, should be at least 3 dk4_c16_t.
+ @param pszrb Size of the result buffer, in: available, out: used.
+ @param c Character to encode.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if rb or pszrb is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the buffer size is less than 3,
+ - DK4_E_SYNTAX<br>
+ if c is out of the encodable range.
+*/
+int
+dk4utf16_encode(dk4_c16_t *rb, size_t *pszrb, dk4_c32_t c, dk4_er_t *erp);
+
+/** Initialize the UTF-16 decoder.
+ @param ptr Decoder to initialize.
+ @param msb Flag: Most significant byte comes first.
+*/
+void
+dk4utf16_byte_init(dk4_utf16_byte_decoder_t *ptr, int msb);
+
+/** Add one byte to the decoder.
+ @param ptr Decoder to use.
+ @param byte Byte to add.
+ @return Operation result, one from:
+ DK4_EDSTM_ACCEPT if the byte was added to the next output
+ without completing output,
+ DK4_EDSTM_FINISHED, if the byte was added to the next output
+ completing the output, or
+ DK4_EDSTM_ERROR on error.
+*/
+int
+dk4utf16_byte_add(dk4_utf16_byte_decoder_t *ptr, unsigned char byte);
+
+/** Retrieve a completed Unicode character from the decoder.
+ @param ptr Decoder to obtain character from.
+*/
+dk4_c32_t
+dk4utf16_byte_get(dk4_utf16_byte_decoder_t *ptr);
+
+/** Check whether a decoder is empty.
+ @param ptr Decoder to check.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4utf16_byte_is_empty(dk4_utf16_byte_decoder_t *ptr);
+
+/** UTF-16 encode UNICODE character, write to bytes.
+ @param rb Result buffer, should be at least 5 bytes.
+ @param pszrb Size of the result buffer (number of bytes),
+ in: available, out: used.
+ @param c Character to encode.
+ @param msb Flag: Write most significant byte first.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if rb or pszrb is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the buffer size is less than 3,
+ - DK4_E_SYNTAX<br>
+ if c is out of the encodable range.
+*/
+int
+dk4utf16_byte_encode(
+ unsigned char *rb, size_t *pszrb, dk4_c32_t c, int msb, dk4_er_t *erp
+);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4utf16.h"
+#include "dk4mem.h"
+
+
+
+$!trace-include
+
+
+
+/** State value in dk4_utf16_decoder_t.
+*/
+enum {
+ /** No surrogate yet.
+ */
+ DK4_UTF16_DEC_ST_EMPTY = 0,
+
+ /** Found high surrogate,
+ expecting corresponding
+ low surrogate.
+ */
+ DK4_UTF16_DEC_ST_HAVE_HIGH_SURROGATE ,
+
+ /** Found low surrogate,
+ expecting corresponding
+ high surrogate.
+ */
+ DK4_UTF16_DEC_ST_HAVE_LOW_SURROGATE
+};
+
+
+
+void
+dk4utf16_init(dk4_utf16_decoder_t *ptr)
+{
+ if (NULL != ptr) {
+ ptr->uc = dkC32(0);
+ ptr->state = DK4_UTF16_DEC_ST_EMPTY;
+ }
+}
+
+
+
+int
+dk4utf16_add(dk4_utf16_decoder_t *ptr, dk4_c16_t word)
+{
+ int back = DK4_EDSTM_ERROR;
+ if (NULL != ptr) {
+ switch (ptr->state) {
+ case DK4_UTF16_DEC_ST_EMPTY: {
+ if ((dkC32(0x0000DC00) & ((dk4_c32_t)word)) == dkC32(0x0000DC00)) {
+ ptr->state = DK4_UTF16_DEC_ST_HAVE_LOW_SURROGATE;
+ ptr->uc = ((dk4_c32_t)word) & dkC32(0x000003FF);
+ back = DK4_EDSTM_ACCEPT;
+ } else {
+ if ((dkC32(0x0000DC00) & ((dk4_c32_t)word)) == dkC32(0x0000D800)) {
+ ptr->state = DK4_UTF16_DEC_ST_HAVE_HIGH_SURROGATE;
+ ptr->uc = ((((dk4_c32_t)word) << 10) & dkC32(0x000FFC00));
+ back = DK4_EDSTM_ACCEPT;
+ } else {
+ ptr->uc = ((dk4_c32_t)word) & dkC32(0x0000FFFF);
+ back = DK4_EDSTM_FINISHED;
+ }
+ }
+ } break;
+ case DK4_UTF16_DEC_ST_HAVE_HIGH_SURROGATE: {
+ if ((dkC32(0x0000DC00) & ((dk4_c32_t)word)) == dkC32(0x0000DC00)) {
+ ptr->uc |= (((dk4_c32_t)word) & dkC32(0x000003FF));
+ ptr->uc += dkC32(0x00010000);
+ ptr->state = DK4_UTF16_DEC_ST_EMPTY;
+ back = DK4_EDSTM_FINISHED;
+ } else {
+ back = DK4_EDSTM_ERROR;
+ ptr->state = DK4_UTF16_DEC_ST_EMPTY;
+ }
+ } break;
+ case DK4_UTF16_DEC_ST_HAVE_LOW_SURROGATE: {
+ if ((((dk4_c32_t)word) & dkC32(0x0000DC00)) == dkC32(0x0000D800)) {
+ ptr->uc |= ((((dk4_c32_t)word) << 10) & dkC32(0x000FFC00));
+ ptr->uc += dkC32(0x00010000);
+ ptr->state = DK4_UTF16_DEC_ST_EMPTY;
+ back = DK4_EDSTM_FINISHED;
+ } else {
+ back = DK4_EDSTM_ERROR;
+ ptr->state = DK4_UTF16_DEC_ST_EMPTY;
+ }
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+dk4_c32_t
+dk4utf16_get(dk4_utf16_decoder_t *ptr)
+{
+ dk4_c32_t back = dkC32(0);
+ if (NULL != ptr) {
+ back = ptr->uc;
+ }
+ return back;
+}
+
+
+
+int
+dk4utf16_is_empty(dk4_utf16_decoder_t *ptr)
+{
+ int back = 0;
+ if (NULL != ptr) {
+ if (DK4_UTF16_DEC_ST_EMPTY == ptr->state) { back = 1; }
+ }
+ return back;
+}
+
+
+
+int
+dk4utf16_encode(dk4_c16_t *rb, size_t *pszrb, dk4_c32_t c, dk4_er_t *erp)
+{
+ int back = 0;
+ $? "+ dk4utf16_encode %08lx", (unsigned long)c
+ if ((NULL != rb) && (NULL != pszrb)) {
+ if (2 < *pszrb) { $? ". args ok"
+ if ( dkC32(0x00010000) <= c ) { $? ". surrogate pair"
+ if ( dkC32(0x0010FFFF) >= c ) { $? ". in range"
+ back = 1;
+ *pszrb = 2;
+ rb[0] =
+ (dk4_c16_t)(((c >> 10) & dkC32(0x000003FF)) | dkC32(0x0000D800));
+ rb[1] =
+ (dk4_c16_t)((c & dkC32(0x000003FF)) | dkC32(0x0000DC00));
+ rb[2] = (dk4_c16_t)0;
+ } else { $? "! out of range"
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else { $? ". single 16-bit char"
+#if VERSION_BEFORE_20141125
+ if ((0x0000DC00 & c) != dkC32(0x0000DC00)) { $? ". range 1 ok"
+ if ((0x0000DC00 & c) != dkC32(0x0000D800)) { $? ". range 2 ok"
+ back = 1;
+ *pszrb = 1;
+ rb[0] = (dk4_c16_t)(c & dkC32(0x0000FFFF));
+ rb[1] = (dk4_c16_t)0;
+ } else { $? "! range check 2"
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else { $? "! range check 1"
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+#else
+ if ((dkC32(0x0000DFFF) < c) || (dkC32(0x0000D800) > c)) {
+ $? ". range ok, not in surrogates range"
+ back = 1;
+ *pszrb = 1;
+ rb[0] = (dk4_c16_t)(c & dkC32(0x0000FFFF));
+ rb[1] = (dk4_c16_t)0;
+ } else { $? "! range check, in surrogates range"
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+#endif
+ }
+ } else { $? "! buffer size"
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else { $? "! args"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4utf16_encode %d", back
+ return back;
+}
+
+
+
+void
+dk4utf16_byte_init(dk4_utf16_byte_decoder_t *ptr, int msb)
+{
+ if (NULL != ptr) {
+ dk4utf16_init(&(ptr->dec));
+ ptr->msb = msb;
+ ptr->state = 0;
+ ptr->saved = (dk4_c16_t)0;
+ }
+}
+
+
+
+int
+dk4utf16_byte_add(dk4_utf16_byte_decoder_t *ptr, unsigned char byte)
+{
+ int back = DK4_EDSTM_ERROR;
+ if (NULL != ptr) {
+ if (0 != ptr->state) {
+ ptr->state = 0;
+ if (0 != ptr->msb) {
+ ptr->saved |= (((dk4_c16_t)byte) & dkC16(0x00FF));
+ } else {
+ ptr->saved |= ((((dk4_c16_t)byte) << 8) & dkC16(0xFF00));
+ }
+ back = dk4utf16_add(&(ptr->dec), ptr->saved);
+ ptr->saved = (dk4_c16_t)0;
+ } else {
+ ptr->state = 1;
+ if (0 != ptr->msb) {
+ ptr->saved = ((((dk4_c16_t)byte) << 8) & dkC16(0xFF00));
+ } else {
+ ptr->saved = (((dk4_c16_t)byte) & dkC16(0x00FF));
+ }
+ back = DK4_EDSTM_ACCEPT;
+ }
+ }
+ return back;
+}
+
+
+
+dk4_c32_t
+dk4utf16_byte_get(dk4_utf16_byte_decoder_t *ptr)
+{
+ dk4_c32_t back = dkC32(0);
+ if (NULL != ptr) {
+ back = dk4utf16_get(&(ptr->dec));
+ }
+ return back;
+}
+
+
+
+int
+dk4utf16_byte_is_empty(dk4_utf16_byte_decoder_t *ptr)
+{
+ int back = 0;
+ if (NULL != ptr) {
+ back = dk4utf16_is_empty(&(ptr->dec));
+ if (0 != ptr->state) { back = 0; }
+ }
+ return back;
+}
+
+
+
+int
+dk4utf16_byte_encode(
+ unsigned char *rb, size_t *pszrb, dk4_c32_t c, int msb, dk4_er_t *erp
+)
+{
+ dk4_c16_t buf[3];
+ size_t sz;
+ int back = 0;
+ if ((NULL != rb) && (NULL != pszrb)) {
+ if (4 < *pszrb) {
+ sz = DK4_SIZEOF(buf,dk4_c16_t);
+ if (0 != dk4utf16_encode(buf, &sz, c, erp)) {
+ back = 1;
+ if (0 != msb) {
+ rb[0] = (unsigned char)((buf[0] >> 8) & dkC16(0x00FF));
+ rb[1] = (unsigned char)(buf[0] & dkC16(0x00FF));
+ } else {
+ rb[1] = (unsigned char)((buf[0] >> 8) & dkC16(0x00FF));
+ rb[0] = (unsigned char)(buf[0] & dkC16(0x00FF));
+ }
+ if (1 < sz) {
+ if (0 != msb) {
+ rb[2] = (unsigned char)((buf[1] >> 8) & dkC16(0x00FF));
+ rb[3] = (unsigned char)(buf[1] & dkC16(0x00FF));
+ } else {
+ rb[3] = (unsigned char)((buf[1] >> 8) & dkC16(0x00FF));
+ rb[2] = (unsigned char)(buf[1] & dkC16(0x00FF));
+ }
+ *pszrb = 4;
+ rb[4] = '\0';
+ } else {
+ *pszrb = 2;
+ rb[2] = '\0';
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/dk4utf16.h b/support/dktools/dk4utf16.h
new file mode 100644
index 0000000000..826a8f3abc
--- /dev/null
+++ b/support/dktools/dk4utf16.h
@@ -0,0 +1,203 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4utf16.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4UTF16_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4UTF16_H_INCLUDED 1
+
+
+#line 10 "dk4utf16.ctr"
+
+/** @file
+ Encode and decode 32 bit characters
+ in UTF-16 encoding.
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4DEC_H_INCLUDED
+#include "dk4edstm.h"
+#endif
+
+/** Decode UTF-16 encoded data.
+*/
+typedef struct {
+ dk4_c32_t uc; /**< Unicode character to produce. */
+ int state; /**< Decoder state. */
+} dk4_utf16_decoder_t;
+
+
+
+/** Decode UTF-16 encoded bytes.
+*/
+typedef struct {
+ dk4_utf16_decoder_t dec; /**< Decoder UTF-16 to 32-bit char. */
+ int msb; /**< Flag: Most significant byte comes first. */
+ int state; /**< Decoder state. */
+ dk4_c16_t saved; /**< Partial input character saved. */
+} dk4_utf16_byte_decoder_t;
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Initialize the UTF-16 decoder.
+ @param ptr Decoder to initialize.
+*/
+void
+dk4utf16_init(dk4_utf16_decoder_t *ptr);
+
+/** Add one word to the decoder.
+ @param ptr Decoder to use.
+ @param word Word to add.
+ @return Operation result, one from:
+ DK4_EDSTM_ACCEPT if the byte was added to the next output
+ without completing output,
+ DK4_EDSTM_FINISHED, if the byte was added to the next output
+ completing the output, or
+ DK4_EDSTM_ERROR on error.
+*/
+int
+dk4utf16_add(dk4_utf16_decoder_t *ptr, dk4_c16_t word);
+
+/** Retrieve a completed Unicode character from the decoder.
+ @param ptr Decoder to obtain character from.
+*/
+dk4_c32_t
+dk4utf16_get(dk4_utf16_decoder_t *ptr);
+
+/** Check whether the decoder is empty.
+ @param ptr Decoder to check.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4utf16_is_empty(dk4_utf16_decoder_t *ptr);
+
+/** UTF-16 encode UNICODE character.
+ @param rb Result buffer, should be at least 3 dk4_c16_t.
+ @param pszrb Size of the result buffer, in: available, out: used.
+ @param c Character to encode.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if rb or pszrb is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the buffer size is less than 3,
+ - DK4_E_SYNTAX<br>
+ if c is out of the encodable range.
+*/
+int
+dk4utf16_encode(dk4_c16_t *rb, size_t *pszrb, dk4_c32_t c, dk4_er_t *erp);
+
+/** Initialize the UTF-16 decoder.
+ @param ptr Decoder to initialize.
+ @param msb Flag: Most significant byte comes first.
+*/
+void
+dk4utf16_byte_init(dk4_utf16_byte_decoder_t *ptr, int msb);
+
+/** Add one byte to the decoder.
+ @param ptr Decoder to use.
+ @param byte Byte to add.
+ @return Operation result, one from:
+ DK4_EDSTM_ACCEPT if the byte was added to the next output
+ without completing output,
+ DK4_EDSTM_FINISHED, if the byte was added to the next output
+ completing the output, or
+ DK4_EDSTM_ERROR on error.
+*/
+int
+dk4utf16_byte_add(dk4_utf16_byte_decoder_t *ptr, unsigned char byte);
+
+/** Retrieve a completed Unicode character from the decoder.
+ @param ptr Decoder to obtain character from.
+*/
+dk4_c32_t
+dk4utf16_byte_get(dk4_utf16_byte_decoder_t *ptr);
+
+/** Check whether a decoder is empty.
+ @param ptr Decoder to check.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4utf16_byte_is_empty(dk4_utf16_byte_decoder_t *ptr);
+
+/** UTF-16 encode UNICODE character, write to bytes.
+ @param rb Result buffer, should be at least 5 bytes.
+ @param pszrb Size of the result buffer (number of bytes),
+ in: available, out: used.
+ @param c Character to encode.
+ @param msb Flag: Write most significant byte first.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if rb or pszrb is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the buffer size is less than 3,
+ - DK4_E_SYNTAX<br>
+ if c is out of the encodable range.
+*/
+int
+dk4utf16_byte_encode(
+ unsigned char *rb, size_t *pszrb, dk4_c32_t c, int msb, dk4_er_t *erp
+);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4utf8.c b/support/dktools/dk4utf8.c
new file mode 100644
index 0000000000..5402fb1f4d
--- /dev/null
+++ b/support/dktools/dk4utf8.c
@@ -0,0 +1,355 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4utf8.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4utf8.c The dk4utf8 module.
+*/
+
+
+#line 121 "dk4utf8.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4utf8.h"
+
+
+
+
+
+#line 130 "dk4utf8.ctr"
+
+
+
+void
+dk4utf8_init(dk4_utf8_decoder_t *ptr)
+{
+ if (NULL != ptr) {
+ ptr->uc = dkC32(0);
+ ptr->bfc = 0;
+ ptr->bfn = 0;
+ }
+}
+
+
+
+int
+dk4utf8_add(dk4_utf8_decoder_t *ptr, unsigned char byte)
+{
+ int back = DK4_EDSTM_ERROR;
+
+ if (NULL != ptr) {
+ switch (ptr->bfc) {
+ case 0: {
+ if (0x7F < byte) { /* more than 1 byte */
+ if ((0xE0 & byte) == 0xC0) { /* 2 bytes */
+ ptr->uc = (((dk4_c32_t)byte) << 6) & dkC32(0x000007C0);
+ ptr->bfc = 2;
+ ptr->bfn = 1;
+ back = DK4_EDSTM_ACCEPT;
+ } else {
+ if ((0xF0 & byte) == 0xE0) { /* 3 bytes */
+ ptr->uc = (((dk4_c32_t)byte) << 12) & dkC32(0x0000F000);
+ ptr->bfc = 3;
+ ptr->bfn = 1;
+ back = DK4_EDSTM_ACCEPT;
+ } else {
+ if ((0xF8 & byte) == 0xF0) { /* 4 bytes */
+ ptr->uc = (((dk4_c32_t)byte) << 18) & dkC32(0x001C0000);
+ ptr->bfc = 4;
+ ptr->bfn = 1;
+ back = DK4_EDSTM_ACCEPT;
+ } else {
+ if ((0xFC & byte) == 0xF8) { /* 5 bytes */
+ ptr->uc = ((((dk4_c32_t)byte) << 24) & dkC32(0x03000000));
+ ptr->bfc = 5;
+ ptr->bfn = 1;
+ back = DK4_EDSTM_ACCEPT;
+ } else {
+ if ((0xFE & byte) == 0xFC) { /* 6 bytes */
+ ptr->uc = dkC32(0x40000000);
+ ptr->bfc = 6;
+ ptr->bfn = 1;
+ back = DK4_EDSTM_ACCEPT;
+ } else {
+ /* ERROR: Illegal input! */
+ }
+ }
+ }
+ }
+ }
+ } else { /* just one byte */
+ ptr->uc = (dk4_c32_t)byte;
+ ptr->uc &= dkC32(0xFF);
+ back = DK4_EDSTM_FINISHED;
+ ptr->bfn = 0;
+ }
+ } break;
+ case 2: {
+ switch (ptr->bfn) {
+ case 1: {
+ if ((0xC0 & byte) == 0x80) {
+ back = DK4_EDSTM_FINISHED;
+ ptr->uc |= (((dk4_c32_t)byte) & dkC32(0x0000003F));
+ }
+ ptr->bfc = 0;
+ ptr->bfn = 0;
+ } break;
+ }
+ } break;
+ case 3: {
+ switch (ptr->bfn) {
+ case 1: {
+ if ((0xC0 & byte) == 0x80) {
+ back = DK4_EDSTM_ACCEPT;
+ ptr->uc |= ((((dk4_c32_t)byte) << 6) & dkC32(0x00000FC0));
+ }
+ ptr->bfn = 2;
+ } break;
+ case 2: {
+ if ((0xC0 & byte) == 0x80) {
+ back = DK4_EDSTM_FINISHED;
+ ptr->uc |= (((dk4_c32_t)byte) & dkC32(0x0000003F));
+ }
+ ptr->bfc = 0;
+ ptr->bfn = 0;
+ } break;
+ }
+ } break;
+ case 4: {
+ switch (ptr->bfn) {
+ case 1: {
+ if ((0xC0 & byte) == 0x80) {
+ back = DK4_EDSTM_ACCEPT;
+ ptr->uc |= ((((dk4_c32_t)byte) << 12) & dkC32(0x0003F000));
+ }
+ ptr->bfn = 2;
+ } break;
+ case 2: {
+ if ((0xC0 & byte) == 0x80) {
+ back = DK4_EDSTM_ACCEPT;
+ ptr->uc |= ((((dk4_c32_t)byte) << 6) & dkC32(0x00000FC0));
+ }
+ ptr->bfn = 3;
+ } break;
+ case 3: {
+ if ((0xC0 & byte) == 0x80) {
+ back = DK4_EDSTM_FINISHED;
+ ptr->uc |= (((dk4_c32_t)byte) & dkC32(0x0000003F));
+ }
+ ptr->bfc = 0;
+ ptr->bfn = 0;
+ } break;
+ }
+ } break;
+ case 5: {
+ switch (ptr->bfn) {
+ case 1: {
+ if ((0xC0 & byte) == 0x80) {
+ back = DK4_EDSTM_ACCEPT;
+ ptr->uc |= ((((dk4_c32_t)byte) << 18) & dkC32(0x00FC0000));
+ }
+ ptr->bfn = 2;
+ } break;
+ case 2: {
+ if ((0xC0 & byte) == 0x80) {
+ back = DK4_EDSTM_ACCEPT;
+ ptr->uc |= ((((dk4_c32_t)byte) << 12) & dkC32(0x0003F000));
+ }
+ ptr->bfn = 3;
+ } break;
+ case 3: {
+ if ((0xC0 & byte) == 0x80) {
+ back = DK4_EDSTM_ACCEPT;
+ ptr->uc |= ((((dk4_c32_t)byte) << 6) & dkC32(0x00000FC0));
+ }
+ ptr->bfn = 4;
+ } break;
+ case 4: {
+ if ((0xC0 & byte) == 0x80) {
+ back = DK4_EDSTM_FINISHED;
+ ptr->uc |= (((dk4_c32_t)byte) & dkC32(0x0000003F));
+ }
+ ptr->bfc = 0;
+ ptr->bfn = 0;
+ } break;
+ }
+ } break;
+ case 6: {
+ switch (ptr->bfn) {
+ case 1: {
+ if ((0xC0 & byte) == 0x80) {
+ back = DK4_EDSTM_ACCEPT;
+ ptr->uc |= ((((dk4_c32_t)byte) << 24) & dkC32(0x3F000000));
+ }
+ ptr->bfn = 2;
+ } break;
+ case 2: {
+ if ((0xC0 & byte) == 0x80) {
+ back = DK4_EDSTM_ACCEPT;
+ ptr->uc |= ((((dk4_c32_t)byte) << 18) & dkC32(0x00FC0000));
+ }
+ ptr->bfn = 3;
+ } break;
+ case 3: {
+ if ((0xC0 & byte) == 0x80) {
+ back = DK4_EDSTM_ACCEPT;
+ ptr->uc |= ((((dk4_c32_t)byte) << 12) & dkC32(0x0003F000));
+ }
+ ptr->bfn = 4;
+ } break;
+ case 4: {
+ if ((0xC0 & byte) == 0x80) {
+ back = DK4_EDSTM_ACCEPT;
+ ptr->uc |= ((((dk4_c32_t)byte) << 6) & dkC32(0x00000FC0));
+ }
+ ptr->bfn = 5;
+ } break;
+ case 5: {
+ if ((0xC0 & byte) == 0x80) {
+ back = DK4_EDSTM_FINISHED;
+ ptr->uc |= (((dk4_c32_t)byte) & dkC32(0x0000003F));
+ }
+ ptr->bfc = 0;
+ ptr->bfn = 0;
+ } break;
+ }
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+dk4_c32_t
+dk4utf8_get(dk4_utf8_decoder_t *ptr)
+{
+ dk4_c32_t back = dkC32(0);
+ if (NULL != ptr) {
+ back = ptr->uc;
+ }
+ return back;
+}
+
+
+
+int
+dk4utf8_is_empty(dk4_utf8_decoder_t *ptr)
+{
+ int back = 0;
+ if (NULL != ptr) {
+ if (0 == ptr->bfc) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4utf8_encode(unsigned char *rb, size_t *pszrb, dk4_c32_t c, dk4_er_t *erp)
+{
+ int back = 0;
+
+
+#line 365 "dk4utf8.ctr"
+ if ((NULL != rb) && (NULL != pszrb)) {
+ if (6 < *pszrb) {
+ if (dkC32(0x7F) < c) {
+ if (dkC32(0x000007FF) < c) {
+ if (dkC32(0x001FFFFF) < c) {
+ if (dkC32(0x03FFFFFF) < c) {
+ if (dkC32(0x80000000) < c) { /* 6 bytes */
+ back = 1;
+ *pszrb = 6;
+ rb[0] = ((unsigned char)((c >> 30) & dkC32(0x00000001))) | 0xFC;
+ rb[1] = ((unsigned char)((c >> 24) & dkC32(0x0000003F))) | 0x80;
+ rb[2] = ((unsigned char)((c >> 18) & dkC32(0x0000003F))) | 0x80;
+ rb[3] = ((unsigned char)((c >> 12) & dkC32(0x0000003F))) | 0x80;
+ rb[4] = ((unsigned char)((c >> 6) & dkC32(0x0000003F))) | 0x80;
+ rb[5] = ((unsigned char)( c & dkC32(0x0000003F))) | 0x80;
+ rb[6] = '\0';
+ } else { /* 5 bytes */
+ back = 1;
+ *pszrb = 5;
+ rb[0] = ((unsigned char)((c >> 24) & dkC32(0x00000003))) | 0xF8;
+ rb[1] = ((unsigned char)((c >> 18) & dkC32(0x0000003F))) | 0x80;
+ rb[2] = ((unsigned char)((c >> 12) & dkC32(0x0000003F))) | 0x80;
+ rb[3] = ((unsigned char)((c >> 6) & dkC32(0x0000003F))) | 0x80;
+ rb[4] = ((unsigned char)( c & dkC32(0x0000003F))) | 0x80;
+ rb[5] = '\0';
+ }
+ } else { /* 4 bytes */
+ back = 1;
+ *pszrb = 4;
+ rb[0] = ((unsigned char)((c >> 18) & dkC32(0x00000007))) | 0xF0;
+ rb[1] = ((unsigned char)((c >> 12) & dkC32(0x0000003F))) | 0x80;
+ rb[2] = ((unsigned char)((c >> 6) & dkC32(0x0000003F))) | 0x80;
+ rb[3] = ((unsigned char)( c & dkC32(0x0000003F))) | 0x80;
+ rb[4] = '\0';
+ }
+ } else { /* 3 bytes */
+ back = 1;
+ *pszrb = 3;
+ rb[0] = ((unsigned char)((c >> 12) & dkC32(0x0000000F))) | 0xE0;
+ rb[1] = ((unsigned char)((c >> 6) & dkC32(0x0000003F))) | 0x80;
+ rb[2] = ((unsigned char)( c & dkC32(0x0000003F))) | 0x80;
+ rb[3] = '\0';
+ }
+ } else { /* 2 bytes */
+ back = 1;
+ *pszrb = 2;
+ rb[0] = ((unsigned char)((c >> 6) & dkC32(0x0000001F))) | 0xC0;
+ rb[1] = ((unsigned char)( c & dkC32(0x0000003F))) | 0x80;
+ rb[2] = '\0';
+ }
+ } else { /* 1 byte */
+ back = 1;
+ *pszrb = 1;
+ rb[0] = (unsigned char)(c & dkC32(0x0000007F));
+ rb[1] = '\0';
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 427 "dk4utf8.ctr"
+ return back;
+}
+
diff --git a/support/dktools/dk4utf8.ctr b/support/dktools/dk4utf8.ctr
new file mode 100644
index 0000000000..e487d239fe
--- /dev/null
+++ b/support/dktools/dk4utf8.ctr
@@ -0,0 +1,429 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ UTF-8 decoding and encoding.
+
+To decode an UTF-8 encoded data stream, use a dk4_utf8_decoder_t object.
+Use dk4utf8_init() to initialize the object before you start decoding.
+For each byte from the data stream use dk4utf8_add(). Possible
+return values are DK4_EDSTM_ACCEPT, DK4_EDSTM_FINISHED,
+and DK4_EDSTM_ERROR.
+DK4_EDSTM_ACCEPT indicates the byte was processed successfully,
+but more bytes are required to complete the UNICODE character.
+DK4_EDSTM_FINISHED indicates an UNICODE character was completed,
+use dk4utf8_get() to retrieve it.
+DK4_EDSTM_ERROR indicates an error, invalid input.
+
+The older RFC2279 allows a wider range of UNICODE characters,
+RFC3629 restricts the UNICODE character range to 0x0010FFFF.
+Routines in this module use the range defined by RFC2279.
+To be RFC3629 compliant, check UNICODE values and make sure
+to use the range 0...0x0010FFFF only.
+
+CRT on Windows: Not used.
+*/
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4DEC_H_INCLUDED
+#include "dk4edstm.h"
+#endif
+
+
+/** State machine to decode UTF-8 encoded data byte by byte.
+*/
+typedef struct {
+ dk4_c32_t uc; /**< Unicode character to produce. */
+ int bfc; /**< Bytes needed for character. */
+ int bfn; /**< Bytes already found. */
+} dk4_utf8_decoder_t;
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Initialize the UTF-8 decoder.
+ @param ptr Decoder to initialize.
+*/
+void
+dk4utf8_init(dk4_utf8_decoder_t *ptr);
+
+/** Add one byte to the decoder.
+ @param ptr Decoder to use.
+ @param byte Byte to add.
+ @return Operation result, one from:
+ DK4_EDSTM_ACCEPT if the byte was added to the next output
+ without completing output,
+ DK4_EDSTM_FINISHED if the byte was added to the next output
+ completing the output, or
+ DK4_EDSTM_ERROR on error.
+*/
+int
+dk4utf8_add(dk4_utf8_decoder_t *ptr, unsigned char byte);
+
+/** Retrieve a completed Unicode character from the decoder.
+ @param ptr Decoder to obtain character from.
+*/
+dk4_c32_t
+dk4utf8_get(dk4_utf8_decoder_t *ptr);
+
+/** Check whether the decoder is empty.
+ @param ptr Decoder to check.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4utf8_is_empty(dk4_utf8_decoder_t *ptr);
+
+/** UTF-8 encode UNICODE character.
+ @param rb Result buffer, at least 7 bytes.
+ @param pszrb Size of result buffer, in: available, out: used.
+ @param c Character to encode.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if rb or pszrb is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the size specified in pszrb is less than 7.
+*/
+int
+dk4utf8_encode(unsigned char *rb, size_t *pszrb, dk4_c32_t c, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4utf8.h"
+
+
+
+$!trace-include
+
+
+
+void
+dk4utf8_init(dk4_utf8_decoder_t *ptr)
+{
+ if (NULL != ptr) {
+ ptr->uc = dkC32(0);
+ ptr->bfc = 0;
+ ptr->bfn = 0;
+ }
+}
+
+
+
+int
+dk4utf8_add(dk4_utf8_decoder_t *ptr, unsigned char byte)
+{
+ int back = DK4_EDSTM_ERROR;
+
+ if (NULL != ptr) {
+ switch (ptr->bfc) {
+ case 0: {
+ if (0x7F < byte) { /* more than 1 byte */
+ if ((0xE0 & byte) == 0xC0) { /* 2 bytes */
+ ptr->uc = (((dk4_c32_t)byte) << 6) & dkC32(0x000007C0);
+ ptr->bfc = 2;
+ ptr->bfn = 1;
+ back = DK4_EDSTM_ACCEPT;
+ } else {
+ if ((0xF0 & byte) == 0xE0) { /* 3 bytes */
+ ptr->uc = (((dk4_c32_t)byte) << 12) & dkC32(0x0000F000);
+ ptr->bfc = 3;
+ ptr->bfn = 1;
+ back = DK4_EDSTM_ACCEPT;
+ } else {
+ if ((0xF8 & byte) == 0xF0) { /* 4 bytes */
+ ptr->uc = (((dk4_c32_t)byte) << 18) & dkC32(0x001C0000);
+ ptr->bfc = 4;
+ ptr->bfn = 1;
+ back = DK4_EDSTM_ACCEPT;
+ } else {
+ if ((0xFC & byte) == 0xF8) { /* 5 bytes */
+ ptr->uc = ((((dk4_c32_t)byte) << 24) & dkC32(0x03000000));
+ ptr->bfc = 5;
+ ptr->bfn = 1;
+ back = DK4_EDSTM_ACCEPT;
+ } else {
+ if ((0xFE & byte) == 0xFC) { /* 6 bytes */
+ ptr->uc = dkC32(0x40000000);
+ ptr->bfc = 6;
+ ptr->bfn = 1;
+ back = DK4_EDSTM_ACCEPT;
+ } else {
+ /* ERROR: Illegal input! */
+ }
+ }
+ }
+ }
+ }
+ } else { /* just one byte */
+ ptr->uc = (dk4_c32_t)byte;
+ ptr->uc &= dkC32(0xFF);
+ back = DK4_EDSTM_FINISHED;
+ ptr->bfn = 0;
+ }
+ } break;
+ case 2: {
+ switch (ptr->bfn) {
+ case 1: {
+ if ((0xC0 & byte) == 0x80) {
+ back = DK4_EDSTM_FINISHED;
+ ptr->uc |= (((dk4_c32_t)byte) & dkC32(0x0000003F));
+ }
+ ptr->bfc = 0;
+ ptr->bfn = 0;
+ } break;
+ }
+ } break;
+ case 3: {
+ switch (ptr->bfn) {
+ case 1: {
+ if ((0xC0 & byte) == 0x80) {
+ back = DK4_EDSTM_ACCEPT;
+ ptr->uc |= ((((dk4_c32_t)byte) << 6) & dkC32(0x00000FC0));
+ }
+ ptr->bfn = 2;
+ } break;
+ case 2: {
+ if ((0xC0 & byte) == 0x80) {
+ back = DK4_EDSTM_FINISHED;
+ ptr->uc |= (((dk4_c32_t)byte) & dkC32(0x0000003F));
+ }
+ ptr->bfc = 0;
+ ptr->bfn = 0;
+ } break;
+ }
+ } break;
+ case 4: {
+ switch (ptr->bfn) {
+ case 1: {
+ if ((0xC0 & byte) == 0x80) {
+ back = DK4_EDSTM_ACCEPT;
+ ptr->uc |= ((((dk4_c32_t)byte) << 12) & dkC32(0x0003F000));
+ }
+ ptr->bfn = 2;
+ } break;
+ case 2: {
+ if ((0xC0 & byte) == 0x80) {
+ back = DK4_EDSTM_ACCEPT;
+ ptr->uc |= ((((dk4_c32_t)byte) << 6) & dkC32(0x00000FC0));
+ }
+ ptr->bfn = 3;
+ } break;
+ case 3: {
+ if ((0xC0 & byte) == 0x80) {
+ back = DK4_EDSTM_FINISHED;
+ ptr->uc |= (((dk4_c32_t)byte) & dkC32(0x0000003F));
+ }
+ ptr->bfc = 0;
+ ptr->bfn = 0;
+ } break;
+ }
+ } break;
+ case 5: {
+ switch (ptr->bfn) {
+ case 1: {
+ if ((0xC0 & byte) == 0x80) {
+ back = DK4_EDSTM_ACCEPT;
+ ptr->uc |= ((((dk4_c32_t)byte) << 18) & dkC32(0x00FC0000));
+ }
+ ptr->bfn = 2;
+ } break;
+ case 2: {
+ if ((0xC0 & byte) == 0x80) {
+ back = DK4_EDSTM_ACCEPT;
+ ptr->uc |= ((((dk4_c32_t)byte) << 12) & dkC32(0x0003F000));
+ }
+ ptr->bfn = 3;
+ } break;
+ case 3: {
+ if ((0xC0 & byte) == 0x80) {
+ back = DK4_EDSTM_ACCEPT;
+ ptr->uc |= ((((dk4_c32_t)byte) << 6) & dkC32(0x00000FC0));
+ }
+ ptr->bfn = 4;
+ } break;
+ case 4: {
+ if ((0xC0 & byte) == 0x80) {
+ back = DK4_EDSTM_FINISHED;
+ ptr->uc |= (((dk4_c32_t)byte) & dkC32(0x0000003F));
+ }
+ ptr->bfc = 0;
+ ptr->bfn = 0;
+ } break;
+ }
+ } break;
+ case 6: {
+ switch (ptr->bfn) {
+ case 1: {
+ if ((0xC0 & byte) == 0x80) {
+ back = DK4_EDSTM_ACCEPT;
+ ptr->uc |= ((((dk4_c32_t)byte) << 24) & dkC32(0x3F000000));
+ }
+ ptr->bfn = 2;
+ } break;
+ case 2: {
+ if ((0xC0 & byte) == 0x80) {
+ back = DK4_EDSTM_ACCEPT;
+ ptr->uc |= ((((dk4_c32_t)byte) << 18) & dkC32(0x00FC0000));
+ }
+ ptr->bfn = 3;
+ } break;
+ case 3: {
+ if ((0xC0 & byte) == 0x80) {
+ back = DK4_EDSTM_ACCEPT;
+ ptr->uc |= ((((dk4_c32_t)byte) << 12) & dkC32(0x0003F000));
+ }
+ ptr->bfn = 4;
+ } break;
+ case 4: {
+ if ((0xC0 & byte) == 0x80) {
+ back = DK4_EDSTM_ACCEPT;
+ ptr->uc |= ((((dk4_c32_t)byte) << 6) & dkC32(0x00000FC0));
+ }
+ ptr->bfn = 5;
+ } break;
+ case 5: {
+ if ((0xC0 & byte) == 0x80) {
+ back = DK4_EDSTM_FINISHED;
+ ptr->uc |= (((dk4_c32_t)byte) & dkC32(0x0000003F));
+ }
+ ptr->bfc = 0;
+ ptr->bfn = 0;
+ } break;
+ }
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+dk4_c32_t
+dk4utf8_get(dk4_utf8_decoder_t *ptr)
+{
+ dk4_c32_t back = dkC32(0);
+ if (NULL != ptr) {
+ back = ptr->uc;
+ }
+ return back;
+}
+
+
+
+int
+dk4utf8_is_empty(dk4_utf8_decoder_t *ptr)
+{
+ int back = 0;
+ if (NULL != ptr) {
+ if (0 == ptr->bfc) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk4utf8_encode(unsigned char *rb, size_t *pszrb, dk4_c32_t c, dk4_er_t *erp)
+{
+ int back = 0;
+ $? "+ dk4utf8_encode %08lx", (unsigned long)c
+ if ((NULL != rb) && (NULL != pszrb)) {
+ if (6 < *pszrb) {
+ if (dkC32(0x7F) < c) {
+ if (dkC32(0x000007FF) < c) {
+ if (dkC32(0x001FFFFF) < c) {
+ if (dkC32(0x03FFFFFF) < c) {
+ if (dkC32(0x80000000) < c) { /* 6 bytes */
+ back = 1;
+ *pszrb = 6;
+ rb[0] = ((unsigned char)((c >> 30) & dkC32(0x00000001))) | 0xFC;
+ rb[1] = ((unsigned char)((c >> 24) & dkC32(0x0000003F))) | 0x80;
+ rb[2] = ((unsigned char)((c >> 18) & dkC32(0x0000003F))) | 0x80;
+ rb[3] = ((unsigned char)((c >> 12) & dkC32(0x0000003F))) | 0x80;
+ rb[4] = ((unsigned char)((c >> 6) & dkC32(0x0000003F))) | 0x80;
+ rb[5] = ((unsigned char)( c & dkC32(0x0000003F))) | 0x80;
+ rb[6] = '\0';
+ } else { /* 5 bytes */
+ back = 1;
+ *pszrb = 5;
+ rb[0] = ((unsigned char)((c >> 24) & dkC32(0x00000003))) | 0xF8;
+ rb[1] = ((unsigned char)((c >> 18) & dkC32(0x0000003F))) | 0x80;
+ rb[2] = ((unsigned char)((c >> 12) & dkC32(0x0000003F))) | 0x80;
+ rb[3] = ((unsigned char)((c >> 6) & dkC32(0x0000003F))) | 0x80;
+ rb[4] = ((unsigned char)( c & dkC32(0x0000003F))) | 0x80;
+ rb[5] = '\0';
+ }
+ } else { /* 4 bytes */
+ back = 1;
+ *pszrb = 4;
+ rb[0] = ((unsigned char)((c >> 18) & dkC32(0x00000007))) | 0xF0;
+ rb[1] = ((unsigned char)((c >> 12) & dkC32(0x0000003F))) | 0x80;
+ rb[2] = ((unsigned char)((c >> 6) & dkC32(0x0000003F))) | 0x80;
+ rb[3] = ((unsigned char)( c & dkC32(0x0000003F))) | 0x80;
+ rb[4] = '\0';
+ }
+ } else { /* 3 bytes */
+ back = 1;
+ *pszrb = 3;
+ rb[0] = ((unsigned char)((c >> 12) & dkC32(0x0000000F))) | 0xE0;
+ rb[1] = ((unsigned char)((c >> 6) & dkC32(0x0000003F))) | 0x80;
+ rb[2] = ((unsigned char)( c & dkC32(0x0000003F))) | 0x80;
+ rb[3] = '\0';
+ }
+ } else { /* 2 bytes */
+ back = 1;
+ *pszrb = 2;
+ rb[0] = ((unsigned char)((c >> 6) & dkC32(0x0000001F))) | 0xC0;
+ rb[1] = ((unsigned char)( c & dkC32(0x0000003F))) | 0x80;
+ rb[2] = '\0';
+ }
+ } else { /* 1 byte */
+ back = 1;
+ *pszrb = 1;
+ rb[0] = (unsigned char)(c & dkC32(0x0000007F));
+ rb[1] = '\0';
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4utf8_encode %d", back
+ return back;
+}
+
diff --git a/support/dktools/dk4utf8.h b/support/dktools/dk4utf8.h
new file mode 100644
index 0000000000..5ee7b4db87
--- /dev/null
+++ b/support/dktools/dk4utf8.h
@@ -0,0 +1,153 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4utf8.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4UTF8_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4UTF8_H_INCLUDED 1
+
+
+#line 10 "dk4utf8.ctr"
+
+/** @file
+ UTF-8 decoding and encoding.
+
+To decode an UTF-8 encoded data stream, use a dk4_utf8_decoder_t object.
+Use dk4utf8_init() to initialize the object before you start decoding.
+For each byte from the data stream use dk4utf8_add(). Possible
+return values are DK4_EDSTM_ACCEPT, DK4_EDSTM_FINISHED,
+and DK4_EDSTM_ERROR.
+DK4_EDSTM_ACCEPT indicates the byte was processed successfully,
+but more bytes are required to complete the UNICODE character.
+DK4_EDSTM_FINISHED indicates an UNICODE character was completed,
+use dk4utf8_get() to retrieve it.
+DK4_EDSTM_ERROR indicates an error, invalid input.
+
+The older RFC2279 allows a wider range of UNICODE characters,
+RFC3629 restricts the UNICODE character range to 0x0010FFFF.
+Routines in this module use the range defined by RFC2279.
+To be RFC3629 compliant, check UNICODE values and make sure
+to use the range 0...0x0010FFFF only.
+
+CRT on Windows: Not used.
+*/
+
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4DEC_H_INCLUDED
+#include "dk4edstm.h"
+#endif
+
+
+/** State machine to decode UTF-8 encoded data byte by byte.
+*/
+typedef struct {
+ dk4_c32_t uc; /**< Unicode character to produce. */
+ int bfc; /**< Bytes needed for character. */
+ int bfn; /**< Bytes already found. */
+} dk4_utf8_decoder_t;
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Initialize the UTF-8 decoder.
+ @param ptr Decoder to initialize.
+*/
+void
+dk4utf8_init(dk4_utf8_decoder_t *ptr);
+
+/** Add one byte to the decoder.
+ @param ptr Decoder to use.
+ @param byte Byte to add.
+ @return Operation result, one from:
+ DK4_EDSTM_ACCEPT if the byte was added to the next output
+ without completing output,
+ DK4_EDSTM_FINISHED if the byte was added to the next output
+ completing the output, or
+ DK4_EDSTM_ERROR on error.
+*/
+int
+dk4utf8_add(dk4_utf8_decoder_t *ptr, unsigned char byte);
+
+/** Retrieve a completed Unicode character from the decoder.
+ @param ptr Decoder to obtain character from.
+*/
+dk4_c32_t
+dk4utf8_get(dk4_utf8_decoder_t *ptr);
+
+/** Check whether the decoder is empty.
+ @param ptr Decoder to check.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4utf8_is_empty(dk4_utf8_decoder_t *ptr);
+
+/** UTF-8 encode UNICODE character.
+ @param rb Result buffer, at least 7 bytes.
+ @param pszrb Size of result buffer, in: available, out: used.
+ @param c Character to encode.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if rb or pszrb is NULL,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the size specified in pszrb is less than 7.
+*/
+int
+dk4utf8_encode(unsigned char *rb, size_t *pszrb, dk4_c32_t c, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4vers.h b/support/dktools/dk4vers.h
new file mode 100644
index 0000000000..40ce3f17d2
--- /dev/null
+++ b/support/dktools/dk4vers.h
@@ -0,0 +1,15 @@
+#ifndef DK4VERS_H_INCLUDED
+#define DK4VERS_H_INCLUDED 1
+
+/** @file dk4vers.h Version number as text string.
+*/
+
+/** Version number in 8 bit characters.
+*/
+#define DKT_VERSION_C8 "4.8.3"
+
+/** Version number in dkChar.
+*/
+#define DKT_VERSION_DK dkT("4.8.3")
+
+#endif
diff --git a/support/dktools/dk4verswx.h b/support/dktools/dk4verswx.h
new file mode 100644
index 0000000000..366c25826c
--- /dev/null
+++ b/support/dktools/dk4verswx.h
@@ -0,0 +1,27 @@
+#ifndef DK4VERSWX_H_INCLUDED
+/** Protection against multiple inclusions. */
+#define DK4VERSWX_H_INCLUDED 1
+/** @file dk4verswx.h Version number as wxChar string.
+*/
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include "wx/wxprec.h"
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#ifndef WX_WX_H_INCLUDED
+#include "wx/wx.h"
+#define WX_WX_H_INCLUDED 1
+#endif
+#endif
+
+/** Version number as wxChar string.
+*/
+#define DKT_VERSION_WX wxT("4.8.3")
+
+#endif
diff --git a/support/dktools/dk4wreg.c b/support/dktools/dk4wreg.c
new file mode 100644
index 0000000000..3064969fbc
--- /dev/null
+++ b/support/dktools/dk4wreg.c
@@ -0,0 +1,129 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4wreg.ctr
+*/
+
+/*
+Copyright (C) 2014, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4wreg.c The dk4wreg module.
+*/
+
+
+#line 131 "dk4wreg.ctr"
+
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+#if DK4_CHAR_SIZE > 1
+#include "dk4wregw.h"
+#else
+#include "dk4wreg8.h"
+#endif
+
+#include "dk4wreg.h"
+
+
+
+void *
+dk4wreg_open_key(int pk, const dkChar *keyname, int wr, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4wreg_open_key_wc(pk, keyname, wr, erp));
+#else
+ return (dk4wreg_open_key_c8(pk, keyname, wr, erp));
+#endif
+}
+
+
+
+int
+dk4wreg_set_string(
+ void *kptr, const dkChar *name, const dkChar *val, int expand, dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4wreg_set_string_wc(kptr, name, val, expand, erp));
+#else
+ return (dk4wreg_set_string_c8(kptr, name, val, expand, erp));
+#endif
+}
+
+
+
+int
+dk4wreg_get_string(
+ void *kptr,
+ const dkChar *name,
+ dkChar *bptr,
+ size_t sz,
+ int *expand,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4wreg_get_string_wc(kptr, name, bptr, sz, expand, erp));
+#else
+ return (dk4wreg_get_string_c8(kptr, name, bptr, sz, expand, erp));
+#endif
+}
+
+
+
+int
+dk4wreg_set_dword(
+ void *kptr, const dkChar *name, dk4_dword_t val, dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4wreg_set_dword_wc(kptr, name, val, erp));
+#else
+ return (dk4wreg_set_dword_c8(kptr, name, val, erp));
+#endif
+}
+
+
+
+int
+dk4wreg_get_dword(
+ void *kptr,
+ const dkChar *name,
+ dk4_dword_t *vptr,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4wreg_get_dword_wc(kptr, name, vptr, erp));
+#else
+ return (dk4wreg_get_dword_c8(kptr, name, vptr, erp));
+#endif
+}
+
diff --git a/support/dktools/dk4wreg8.c b/support/dktools/dk4wreg8.c
new file mode 100644
index 0000000000..6b4c7751bb
--- /dev/null
+++ b/support/dktools/dk4wreg8.c
@@ -0,0 +1,459 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4wreg8.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4wreg8.c The dk4wreg8 module.
+*/
+
+
+#line 193 "dk4wreg8.ctr"
+
+#include "dk4conf.h"
+#include "dk4wregt.h"
+#include "dk4wreg8.h"
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+#include "dk4maasz.h"
+
+#if DK4_ON_WINDOWS
+
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#ifndef WINBASE_H_INCLUDED
+#include <winbase.h>
+#define WINBASE_H_INCLUDED 1
+#endif
+#ifndef WINREG_H_INCLUDED
+#include <winreg.h>
+#define WINREG_H_INCLUDED 1
+#endif
+
+#endif
+
+#ifndef DK4STR8_H_INCLUDED
+#include "dk4str8.h"
+#endif
+
+
+
+
+
+#line 226 "dk4wreg8.ctr"
+
+
+
+void *
+dk4wreg_open_key_c8(int pk, const char *keyname, int wr, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ dk4_wreg_key_t *back = NULL;
+ HKEY park = HKEY_LOCAL_MACHINE;
+ LONG res;
+ DWORD disp;
+ if (NULL != keyname) {
+ switch (pk) {
+ case DK4_WREGKEY_HKLM:
+ case DK4_WREGKEY_HKCU:
+ case DK4_WREGKEY_HKCL:
+ case DK4_WREGKEY_KHUS:
+ case DK4_WREGKEY_HKCC: {
+ switch (pk) {
+ case DK4_WREGKEY_HKLM: {
+ park = HKEY_LOCAL_MACHINE;
+ } break;
+ case DK4_WREGKEY_HKCU: {
+ park = HKEY_CURRENT_USER;
+ } break;
+ case DK4_WREGKEY_HKCL: {
+ park = HKEY_CLASSES_ROOT;
+ } break;
+ case DK4_WREGKEY_KHUS: {
+ park = HKEY_USERS;
+ } break;
+ case DK4_WREGKEY_HKCC: {
+ park = HKEY_CURRENT_CONFIG;
+ } break;
+ }
+ back = dk4mem_new(dk4_wreg_key_t,1,erp);
+ if (NULL != back) {
+ res = RegCreateKeyExA(
+ park,
+ keyname,
+ (DWORD)0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ ((0 != wr) ? (KEY_ALL_ACCESS) : (KEY_READ)),
+ NULL,
+ &(back->hk),
+ &disp
+ );
+ if (ERROR_SUCCESS != res) {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ dk4mem_free(back);
+ back = NULL;
+ }
+ }
+ } break;
+ default: {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return ((void *)back);
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return NULL;
+#endif
+}
+
+
+
+int
+dk4wreg_set_string_c8(
+ void *kptr, const char *name, const char *val, int expand, dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+ dk4_er_t er;
+ dk4_wreg_key_t *hptr;
+ int back = 0;
+ size_t lgt;
+ DWORD dwt = REG_SZ;
+ DWORD dw0 = (DWORD)0UL;
+ DWORD sz;
+ LONG res;
+ if ((NULL != kptr) && (NULL != val)) {
+ if (0 != expand) { dwt = REG_EXPAND_SZ; }
+ dk4error_init(&er);
+ lgt = dk4ma_size_t_add( 1, dk4str8_len(val), &er);
+ if (DK4_E_NONE == er.ec) {
+ if ((dk4_um_t)0x7FFFFFFFUL >= (dk4_um_t)lgt) {
+ sz = (DWORD)lgt;
+ hptr = (dk4_wreg_key_t *)kptr;
+ res = RegSetValueExA(
+ hptr->hk,
+ name,
+ dw0,
+ dwt,
+ (const BYTE *)val,
+ sz
+ );
+ if (ERROR_SUCCESS == res) {
+ back = 1;
+ } else {
+ dk4error_set_ldetails(erp, DK4_E_SYSTEM, res);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+}
+
+
+
+int
+dk4wreg_get_string_c8(
+ void *kptr,
+ const char *name,
+ char *bptr,
+ size_t sz,
+ int *expand,
+ dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+ dk4_wreg_key_t *hptr;
+ int back = 0;
+ DWORD dwt = REG_SZ;
+ DWORD dws;
+ DWORD dwsbck;
+ LONG res;
+ if ((NULL != bptr) && (0 < sz)) {
+ *bptr = '\0';
+ }
+ if ((NULL != kptr) && (NULL != name) && (NULL != bptr) && (0 < sz)) {
+ if ((dk4_um_t)0x7FFFFFFFUL >= (dk4_um_t)sz) {
+ dws = (DWORD)sz;
+ } else {
+ dws = (DWORD)0x7FFFFFFFUL;
+ }
+ dwsbck = dws;
+ hptr = (dk4_wreg_key_t *)kptr;
+ res = RegQueryValueExA(
+ hptr->hk,
+ name,
+ NULL,
+ &dwt,
+ (LPBYTE)bptr,
+ &dws
+ );
+ if (ERROR_SUCCESS == res) {
+ switch (dwt) {
+ case REG_SZ: case REG_EXPAND_SZ: {
+ if ((DWORD)0L < dws) {
+ if (dws < dwsbck) { /* dws is positive */
+ bptr[dws] = '\0';
+ } else {
+ bptr[dwsbck-1] = '\0';
+ }
+ back = 1;
+ if (REG_EXPAND_SZ == dwt) {
+ if (NULL != expand) {
+ *expand = 1;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } break;
+ default: {
+ /* ERROR: Not a string */
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+}
+
+
+
+int
+dk4wreg_set_dword_c8(
+ void *kptr, const char *name, dk4_dword_t val, dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+ dk4_wreg_key_t *hptr;
+ int back = 0;
+ DWORD dwt = REG_DWORD;
+ DWORD dws = sizeof(DWORD);
+ DWORD dw0 = (DWORD)0L;
+ LONG res;
+ if (NULL != kptr) {
+ hptr = (dk4_wreg_key_t *)kptr;
+ res = RegSetValueExA(
+ hptr->hk,
+ name,
+ dw0,
+ dwt,
+ (const BYTE *)(&val),
+ dws
+ );
+ if (ERROR_SUCCESS == res) {
+ back = 1;
+ } else {
+ dk4error_set_ldetails(erp, DK4_E_SYSTEM, res);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+}
+
+
+
+int
+dk4wreg_get_dword_c8(
+ void *kptr,
+ const char *name,
+ dk4_dword_t *vptr,
+ dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+ dk4_wreg_key_t *hptr;
+ int back = 0;
+ DWORD dwt = REG_DWORD;
+ DWORD dws = (DWORD)sizeof(DWORD);
+ LONG res;
+ if ((NULL != kptr) && (NULL != vptr)) {
+ hptr = (dk4_wreg_key_t *)kptr;
+ res = RegQueryValueExA(
+ hptr->hk,
+ name,
+ NULL,
+ &dwt,
+ (LPBYTE)vptr,
+ &dws
+ );
+ if (ERROR_SUCCESS == res) {
+ if (REG_DWORD == dwt) {
+ if ((DWORD)sizeof(DWORD) == dws) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+}
+
+
+
+int
+dk4wreg_get_expanded_string_c8(
+ void *kptr,
+ const char *name,
+ char *dptr,
+ size_t dsz,
+ char *b1,
+ size_t b1sz,
+ char *b2,
+ size_t b2sz,
+ dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+ DWORD nc;
+ DWORD dws;
+ int expand = 0;
+ int back = 0;
+
+
+#line 532 "dk4wreg8.ctr"
+ if ((NULL != dptr) && (0 < dsz)) { *dptr = '\0'; }
+ if ((NULL != kptr) && (NULL != name) && (NULL != dptr) && (0 < dsz)) {
+ if ((NULL != b1) && (NULL != b2) && (0 < b1sz) && (2 < b2sz)) {
+ back = dk4wreg_get_string_c8(kptr, name, b1, b1sz, &expand, erp);
+ if (0 != back) {
+
+#line 537 "dk4wreg8.ctr"
+ if (0 != expand) {
+
+#line 538 "dk4wreg8.ctr"
+ if ((dk4_um_t)(0x7FFFFFFFUL) >= (dk4_um_t)b2sz) {
+ dws = (DWORD)b2sz;
+
+#line 540 "dk4wreg8.ctr"
+ } else {
+ dws = 0x7FFFFFFFUL;
+
+#line 542 "dk4wreg8.ctr"
+ }
+ dws = dws - 2;
+ nc = ExpandEnvironmentStringsA(b1, b2, dws);
+ if ((0 < nc) && (nc <= dws)) {
+
+#line 546 "dk4wreg8.ctr"
+ back = dk4str8_cpy_s(dptr, dsz, b2, erp);
+
+
+#line 548 "dk4wreg8.ctr"
+
+
+#line 549 "dk4wreg8.ctr"
+
+
+#line 550 "dk4wreg8.ctr"
+ } else {
+
+#line 551 "dk4wreg8.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+
+#line 554 "dk4wreg8.ctr"
+ back = dk4str8_cpy_s(dptr, dsz, b1, erp);
+
+
+#line 556 "dk4wreg8.ctr"
+
+
+#line 557 "dk4wreg8.ctr"
+
+
+#line 558 "dk4wreg8.ctr"
+ }
+ } else {
+
+#line 560 "dk4wreg8.ctr"
+ }
+ } else {
+
+#line 562 "dk4wreg8.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+
+#line 565 "dk4wreg8.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+#line 567 "dk4wreg8.ctr"
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+}
+
diff --git a/support/dktools/dk4wreg8.ctr b/support/dktools/dk4wreg8.ctr
new file mode 100644
index 0000000000..cda903a275
--- /dev/null
+++ b/support/dktools/dk4wreg8.ctr
@@ -0,0 +1,573 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Access Windows registry, use
+ 8 bit character names.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4WREGK_H_INCLUDED
+#include "dk4wregk.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open a registry key.
+ @param pk Parent key identifier.
+ @param keyname Name of registry key to open.
+ @param wr Flag: Open for write access too.
+ @param erp Error report, may be NULL.
+ @return Pointer to key handle structure on success, NULL on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ if the function is run on a non-Windows system,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if pk or keyname is invalid,
+ - DK4_E_NOT_FOUND<br>
+ if opening or creating the registry key failed,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if memory allocation for the key handle structure failed.
+*/
+void *
+dk4wreg_open_key_c8(int pk, const char *keyname, int wr, dk4_er_t *erp);
+
+/** Set a string value.
+ @param kptr Key handle structure.
+ @param name Entry name.
+ @param val Entry value.
+ @param expand Flag: Use REG_EXPAND_SZ (1) or REG_SZ (0).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ when called on non-Windows systems,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if kptr or val is NULL,
+ - DK4_E_MATH_OVERFLOW<br>
+ if the name is too long,
+ - DK4_E_SYSTEM<br>
+ if RegSetValueExA() failed.
+*/
+int
+dk4wreg_set_string_c8(
+ void *kptr, const char *name, const char *val, int expand, dk4_er_t *erp
+);
+
+/** Get string value.
+ @param kptr Key handle structure.
+ @param name Entry name.
+ @param bptr Buffer for result string.
+ @param sz Result buffer length.
+ @param expand Pointer to expand flag output variable.
+ This variable is set to 1 if the string found
+ is of type REG_EXPAND_SZ. The variable is left
+ unchanged for REG_SZ.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ when called on non-Windows systems,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if kptr, name, or bptr is NULL or sz is 0,
+ - DK4_E_NOT_FOUND<br>
+ if the entry is not found or has 0 length,
+ - DK4_E_SYNTAX<br>
+ if the entry is not a string type.
+*/
+int
+dk4wreg_get_string_c8(
+ void *kptr,
+ const char *name,
+ char *bptr,
+ size_t sz,
+ int *expand,
+ dk4_er_t *erp
+);
+
+/** Set DWORD registry entry.
+ @param kptr Key handle structure.
+ @param name Entry name.
+ @param val Value.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ when called on a non-Windows system,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if kptr is NULL,
+ - DK4_E_SYSTEM<br>
+ if RegSetValueExA() failed.
+*/
+int
+dk4wreg_set_dword_c8(
+ void *kptr, const char *name, dk4_dword_t val, dk4_er_t *erp
+);
+
+/** Retrieve DWORD value from registry.
+ @param kptr Key handle structure.
+ @param name Entry name.
+ @param vptr Pointer to result variable.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4wreg_get_dword_c8(
+ void *kptr,
+ const char *name,
+ dk4_dword_t *vptr,
+ dk4_er_t *erp
+);
+
+/** Get string value.
+ @param kptr Key handle structure.
+ @param name Entry name.
+ @param dptr Buffer for result string.
+ @param dsz Result buffer length.
+ @param b1 First buffer, used for result from RegQueryValue().
+ Should have same size as dptr.
+ @param b1sz Size of b1.
+ @param b2 Second buffer, used for result from ExpandEnvironmentStrings.
+ Should be 2 characters larger than dptr.
+ @param b2sz Size of b2.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ when called on non-Windows systems,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if kptr, name, dptr, b1 or b2 is NULL or
+ dsz, b1sz or b2sz is 0 or out of range,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if one of the buffers is too small,
+ - DK4_E_NOT_FOUND<br>
+ if the entry is not found or has 0 length,
+ - DK4_E_SYNTAX<br>
+ if the entry is not a string type.
+*/
+int
+dk4wreg_get_expanded_string_c8(
+ void *kptr,
+ const char *name,
+ char *dptr,
+ size_t dsz,
+ char *b1,
+ size_t b1sz,
+ char *b2,
+ size_t b2sz,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4wregt.h"
+#include "dk4wreg8.h"
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+#include "dk4maasz.h"
+
+#if DK4_ON_WINDOWS
+
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#ifndef WINBASE_H_INCLUDED
+#include <winbase.h>
+#define WINBASE_H_INCLUDED 1
+#endif
+#ifndef WINREG_H_INCLUDED
+#include <winreg.h>
+#define WINREG_H_INCLUDED 1
+#endif
+
+#endif
+
+#ifndef DK4STR8_H_INCLUDED
+#include "dk4str8.h"
+#endif
+
+
+
+$!trace-include
+
+
+
+void *
+dk4wreg_open_key_c8(int pk, const char *keyname, int wr, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ dk4_wreg_key_t *back = NULL;
+ HKEY park = HKEY_LOCAL_MACHINE;
+ LONG res;
+ DWORD disp;
+ if (NULL != keyname) {
+ switch (pk) {
+ case DK4_WREGKEY_HKLM:
+ case DK4_WREGKEY_HKCU:
+ case DK4_WREGKEY_HKCL:
+ case DK4_WREGKEY_KHUS:
+ case DK4_WREGKEY_HKCC: {
+ switch (pk) {
+ case DK4_WREGKEY_HKLM: {
+ park = HKEY_LOCAL_MACHINE;
+ } break;
+ case DK4_WREGKEY_HKCU: {
+ park = HKEY_CURRENT_USER;
+ } break;
+ case DK4_WREGKEY_HKCL: {
+ park = HKEY_CLASSES_ROOT;
+ } break;
+ case DK4_WREGKEY_KHUS: {
+ park = HKEY_USERS;
+ } break;
+ case DK4_WREGKEY_HKCC: {
+ park = HKEY_CURRENT_CONFIG;
+ } break;
+ }
+ back = dk4mem_new(dk4_wreg_key_t,1,erp);
+ if (NULL != back) {
+ res = RegCreateKeyExA(
+ park,
+ keyname,
+ (DWORD)0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ ((0 != wr) ? (KEY_ALL_ACCESS) : (KEY_READ)),
+ NULL,
+ &(back->hk),
+ &disp
+ );
+ if (ERROR_SUCCESS != res) {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ dk4mem_free(back);
+ back = NULL;
+ }
+ }
+ } break;
+ default: {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return ((void *)back);
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return NULL;
+#endif
+}
+
+
+
+int
+dk4wreg_set_string_c8(
+ void *kptr, const char *name, const char *val, int expand, dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+ dk4_er_t er;
+ dk4_wreg_key_t *hptr;
+ int back = 0;
+ size_t lgt;
+ DWORD dwt = REG_SZ;
+ DWORD dw0 = (DWORD)0UL;
+ DWORD sz;
+ LONG res;
+ if ((NULL != kptr) && (NULL != val)) {
+ if (0 != expand) { dwt = REG_EXPAND_SZ; }
+ dk4error_init(&er);
+ lgt = dk4ma_size_t_add( 1, dk4str8_len(val), &er);
+ if (DK4_E_NONE == er.ec) {
+ if ((dk4_um_t)0x7FFFFFFFUL >= (dk4_um_t)lgt) {
+ sz = (DWORD)lgt;
+ hptr = (dk4_wreg_key_t *)kptr;
+ res = RegSetValueExA(
+ hptr->hk,
+ name,
+ dw0,
+ dwt,
+ (const BYTE *)val,
+ sz
+ );
+ if (ERROR_SUCCESS == res) {
+ back = 1;
+ } else {
+ dk4error_set_ldetails(erp, DK4_E_SYSTEM, res);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+}
+
+
+
+int
+dk4wreg_get_string_c8(
+ void *kptr,
+ const char *name,
+ char *bptr,
+ size_t sz,
+ int *expand,
+ dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+ dk4_wreg_key_t *hptr;
+ int back = 0;
+ DWORD dwt = REG_SZ;
+ DWORD dws;
+ DWORD dwsbck;
+ LONG res;
+ if ((NULL != bptr) && (0 < sz)) {
+ *bptr = '\0';
+ }
+ if ((NULL != kptr) && (NULL != name) && (NULL != bptr) && (0 < sz)) {
+ if ((dk4_um_t)0x7FFFFFFFUL >= (dk4_um_t)sz) {
+ dws = (DWORD)sz;
+ } else {
+ dws = (DWORD)0x7FFFFFFFUL;
+ }
+ dwsbck = dws;
+ hptr = (dk4_wreg_key_t *)kptr;
+ res = RegQueryValueExA(
+ hptr->hk,
+ name,
+ NULL,
+ &dwt,
+ (LPBYTE)bptr,
+ &dws
+ );
+ if (ERROR_SUCCESS == res) {
+ switch (dwt) {
+ case REG_SZ: case REG_EXPAND_SZ: {
+ if ((DWORD)0L < dws) {
+ if (dws < dwsbck) { /* dws is positive */
+ bptr[dws] = '\0';
+ } else {
+ bptr[dwsbck-1] = '\0';
+ }
+ back = 1;
+ if (REG_EXPAND_SZ == dwt) {
+ if (NULL != expand) {
+ *expand = 1;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } break;
+ default: {
+ /* ERROR: Not a string */
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+}
+
+
+
+int
+dk4wreg_set_dword_c8(
+ void *kptr, const char *name, dk4_dword_t val, dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+ dk4_wreg_key_t *hptr;
+ int back = 0;
+ DWORD dwt = REG_DWORD;
+ DWORD dws = sizeof(DWORD);
+ DWORD dw0 = (DWORD)0L;
+ LONG res;
+ if (NULL != kptr) {
+ hptr = (dk4_wreg_key_t *)kptr;
+ res = RegSetValueExA(
+ hptr->hk,
+ name,
+ dw0,
+ dwt,
+ (const BYTE *)(&val),
+ dws
+ );
+ if (ERROR_SUCCESS == res) {
+ back = 1;
+ } else {
+ dk4error_set_ldetails(erp, DK4_E_SYSTEM, res);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+}
+
+
+
+int
+dk4wreg_get_dword_c8(
+ void *kptr,
+ const char *name,
+ dk4_dword_t *vptr,
+ dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+ dk4_wreg_key_t *hptr;
+ int back = 0;
+ DWORD dwt = REG_DWORD;
+ DWORD dws = (DWORD)sizeof(DWORD);
+ LONG res;
+ if ((NULL != kptr) && (NULL != vptr)) {
+ hptr = (dk4_wreg_key_t *)kptr;
+ res = RegQueryValueExA(
+ hptr->hk,
+ name,
+ NULL,
+ &dwt,
+ (LPBYTE)vptr,
+ &dws
+ );
+ if (ERROR_SUCCESS == res) {
+ if (REG_DWORD == dwt) {
+ if ((DWORD)sizeof(DWORD) == dws) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+}
+
+
+
+int
+dk4wreg_get_expanded_string_c8(
+ void *kptr,
+ const char *name,
+ char *dptr,
+ size_t dsz,
+ char *b1,
+ size_t b1sz,
+ char *b2,
+ size_t b2sz,
+ dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+ DWORD nc;
+ DWORD dws;
+ int expand = 0;
+ int back = 0;
+ $? "+ dk4wreg_get_expanded_string_c8 \"%!8s\"", TR_8STR(name)
+ if ((NULL != dptr) && (0 < dsz)) { *dptr = '\0'; }
+ if ((NULL != kptr) && (NULL != name) && (NULL != dptr) && (0 < dsz)) {
+ if ((NULL != b1) && (NULL != b2) && (0 < b1sz) && (2 < b2sz)) {
+ back = dk4wreg_get_string_c8(kptr, name, b1, b1sz, &expand, erp);
+ if (0 != back) { $? "- dk4wreg_get_string_c8"
+ if (0 != expand) { $? ". expansion"
+ if ((dk4_um_t)(0x7FFFFFFFUL) >= (dk4_um_t)b2sz) {
+ dws = (DWORD)b2sz; $? ". original size"
+ } else {
+ dws = 0x7FFFFFFFUL; $? ". cut size"
+ }
+ dws = dws - 2;
+ nc = ExpandEnvironmentStringsA(b1, b2, dws);
+ if ((0 < nc) && (nc <= dws)) { $? ". size ok"
+ back = dk4str8_cpy_s(dptr, dsz, b2, erp);
+ $!trace-code if (0 != back) {
+ $? ". result=\"%!8s\"", dptr
+ $!trace-code }
+ } else { $? "! buffer size"
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else { $? ". no expansion"
+ back = dk4str8_cpy_s(dptr, dsz, b1, erp);
+ $!trace-code if (0 != back) {
+ $? ". result=\"%!8s\"", dptr
+ $!trace-code }
+ }
+ } else { $? "! dk4wreg_get_string_c8"
+ }
+ } else { $? "! arguments"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else { $? "! arguments"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4wreg_get_expanded_string_c8 %d", back
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+}
+
diff --git a/support/dktools/dk4wreg8.h b/support/dktools/dk4wreg8.h
new file mode 100644
index 0000000000..613c9069c7
--- /dev/null
+++ b/support/dktools/dk4wreg8.h
@@ -0,0 +1,225 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4wreg8.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4WREG8_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4WREG8_H_INCLUDED 1
+
+
+#line 10 "dk4wreg8.ctr"
+
+/** @file
+ Access Windows registry, use
+ 8 bit character names.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4WREGK_H_INCLUDED
+#include "dk4wregk.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open a registry key.
+ @param pk Parent key identifier.
+ @param keyname Name of registry key to open.
+ @param wr Flag: Open for write access too.
+ @param erp Error report, may be NULL.
+ @return Pointer to key handle structure on success, NULL on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ if the function is run on a non-Windows system,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if pk or keyname is invalid,
+ - DK4_E_NOT_FOUND<br>
+ if opening or creating the registry key failed,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if memory allocation for the key handle structure failed.
+*/
+void *
+dk4wreg_open_key_c8(int pk, const char *keyname, int wr, dk4_er_t *erp);
+
+/** Set a string value.
+ @param kptr Key handle structure.
+ @param name Entry name.
+ @param val Entry value.
+ @param expand Flag: Use REG_EXPAND_SZ (1) or REG_SZ (0).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ when called on non-Windows systems,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if kptr or val is NULL,
+ - DK4_E_MATH_OVERFLOW<br>
+ if the name is too long,
+ - DK4_E_SYSTEM<br>
+ if RegSetValueExA() failed.
+*/
+int
+dk4wreg_set_string_c8(
+ void *kptr, const char *name, const char *val, int expand, dk4_er_t *erp
+);
+
+/** Get string value.
+ @param kptr Key handle structure.
+ @param name Entry name.
+ @param bptr Buffer for result string.
+ @param sz Result buffer length.
+ @param expand Pointer to expand flag output variable.
+ This variable is set to 1 if the string found
+ is of type REG_EXPAND_SZ. The variable is left
+ unchanged for REG_SZ.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ when called on non-Windows systems,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if kptr, name, or bptr is NULL or sz is 0,
+ - DK4_E_NOT_FOUND<br>
+ if the entry is not found or has 0 length,
+ - DK4_E_SYNTAX<br>
+ if the entry is not a string type.
+*/
+int
+dk4wreg_get_string_c8(
+ void *kptr,
+ const char *name,
+ char *bptr,
+ size_t sz,
+ int *expand,
+ dk4_er_t *erp
+);
+
+/** Set DWORD registry entry.
+ @param kptr Key handle structure.
+ @param name Entry name.
+ @param val Value.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ when called on a non-Windows system,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if kptr is NULL,
+ - DK4_E_SYSTEM<br>
+ if RegSetValueExA() failed.
+*/
+int
+dk4wreg_set_dword_c8(
+ void *kptr, const char *name, dk4_dword_t val, dk4_er_t *erp
+);
+
+/** Retrieve DWORD value from registry.
+ @param kptr Key handle structure.
+ @param name Entry name.
+ @param vptr Pointer to result variable.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4wreg_get_dword_c8(
+ void *kptr,
+ const char *name,
+ dk4_dword_t *vptr,
+ dk4_er_t *erp
+);
+
+/** Get string value.
+ @param kptr Key handle structure.
+ @param name Entry name.
+ @param dptr Buffer for result string.
+ @param dsz Result buffer length.
+ @param b1 First buffer, used for result from RegQueryValue().
+ Should have same size as dptr.
+ @param b1sz Size of b1.
+ @param b2 Second buffer, used for result from ExpandEnvironmentStrings.
+ Should be 2 characters larger than dptr.
+ @param b2sz Size of b2.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ when called on non-Windows systems,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if kptr, name, dptr, b1 or b2 is NULL or
+ dsz, b1sz or b2sz is 0 or out of range,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if one of the buffers is too small,
+ - DK4_E_NOT_FOUND<br>
+ if the entry is not found or has 0 length,
+ - DK4_E_SYNTAX<br>
+ if the entry is not a string type.
+*/
+int
+dk4wreg_get_expanded_string_c8(
+ void *kptr,
+ const char *name,
+ char *dptr,
+ size_t dsz,
+ char *b1,
+ size_t b1sz,
+ char *b2,
+ size_t b2sz,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4wregc.c b/support/dktools/dk4wregc.c
new file mode 100644
index 0000000000..3b5e1ef16e
--- /dev/null
+++ b/support/dktools/dk4wregc.c
@@ -0,0 +1,92 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4wregc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4wregc.c The dk4wregc module.
+*/
+
+
+#line 49 "dk4wregc.ctr"
+
+
+#include "dk4conf.h"
+#include "dk4wregt.h"
+#include "dk4wregc.h"
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#if DK4_ON_WINDOWS
+
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#ifndef WINBASE_H_INCLUDED
+#include <winbase.h>
+#define WINBASE_H_INCLUDED 1
+#endif
+#ifndef WINREG_H_INCLUDED
+#include <winreg.h>
+#define WINREG_H_INCLUDED 1
+#endif
+
+#endif
+
+
+
+
+
+#line 78 "dk4wregc.ctr"
+
+
+
+void
+dk4wreg_close_key(void *kptr)
+{
+#if DK4_ON_WINDOWS
+ dk4_wreg_key_t *hptr;
+#endif
+ if (kptr) {
+#if DK4_ON_WINDOWS
+ hptr = (dk4_wreg_key_t *)kptr;
+ RegCloseKey(hptr->hk);
+#else
+#endif
+ dk4mem_free(kptr);
+ }
+}
+
+
+
diff --git a/support/dktools/dk4wregc.ctr b/support/dktools/dk4wregc.ctr
new file mode 100644
index 0000000000..be050baa23
--- /dev/null
+++ b/support/dktools/dk4wregc.ctr
@@ -0,0 +1,98 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Access Windows registry (close registry key).
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4WREGK_H_INCLUDED
+#include "dk4wregk.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Close a registry key handle structure.
+ @param kptr Key handle structure to close.
+*/
+void
+dk4wreg_close_key(void *kptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+
+#include "dk4conf.h"
+#include "dk4wregt.h"
+#include "dk4wregc.h"
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+#if DK4_ON_WINDOWS
+
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#ifndef WINBASE_H_INCLUDED
+#include <winbase.h>
+#define WINBASE_H_INCLUDED 1
+#endif
+#ifndef WINREG_H_INCLUDED
+#include <winreg.h>
+#define WINREG_H_INCLUDED 1
+#endif
+
+#endif
+
+
+
+$!trace-include
+
+
+
+void
+dk4wreg_close_key(void *kptr)
+{
+#if DK4_ON_WINDOWS
+ dk4_wreg_key_t *hptr;
+#endif
+ if (kptr) {
+#if DK4_ON_WINDOWS
+ hptr = (dk4_wreg_key_t *)kptr;
+ RegCloseKey(hptr->hk);
+#else
+#endif
+ dk4mem_free(kptr);
+ }
+}
+
+
+
diff --git a/support/dktools/dk4wregc.h b/support/dktools/dk4wregc.h
new file mode 100644
index 0000000000..4732a6173a
--- /dev/null
+++ b/support/dktools/dk4wregc.h
@@ -0,0 +1,81 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4wregc.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4WREGC_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4WREGC_H_INCLUDED 1
+
+
+#line 10 "dk4wregc.ctr"
+
+/** @file
+ Access Windows registry (close registry key).
+
+ CRT on Windows: Not used.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4WREGK_H_INCLUDED
+#include "dk4wregk.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Close a registry key handle structure.
+ @param kptr Key handle structure to close.
+*/
+void
+dk4wreg_close_key(void *kptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4wregd.c b/support/dktools/dk4wregd.c
new file mode 100644
index 0000000000..4d7d5dc32f
--- /dev/null
+++ b/support/dktools/dk4wregd.c
@@ -0,0 +1,165 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4wregd.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4wregd.c The dk4wregd module.
+*/
+
+
+#line 194 "dk4wregd.ctr"
+
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+#if DK4_CHAR_SIZE > 1
+#include "dk4wregw.h"
+#else
+#include "dk4wreg8.h"
+#endif
+
+#include "dk4wregd.h"
+
+
+
+
+
+#line 210 "dk4wregd.ctr"
+
+
+
+void *
+dk4wreg_open_key(int pk, const dkChar *keyname, int wr, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4wreg_open_key_wc(pk, keyname, wr, erp));
+#else
+ return (dk4wreg_open_key_c8(pk, keyname, wr, erp));
+#endif
+}
+
+
+
+int
+dk4wreg_set_string(
+ void *kptr, const dkChar *name, const dkChar *val, int expand, dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4wreg_set_string_wc(kptr, name, val, expand, erp));
+#else
+ return (dk4wreg_set_string_c8(kptr, name, val, expand, erp));
+#endif
+}
+
+
+
+int
+dk4wreg_get_string(
+ void *kptr,
+ const dkChar *name,
+ dkChar *bptr,
+ size_t sz,
+ int *expand,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4wreg_get_string_wc(kptr, name, bptr, sz, expand, erp));
+#else
+ return (dk4wreg_get_string_c8(kptr, name, bptr, sz, expand, erp));
+#endif
+}
+
+
+
+int
+dk4wreg_set_dword(
+ void *kptr, const dkChar *name, dk4_dword_t val, dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4wreg_set_dword_wc(kptr, name, val, erp));
+#else
+ return (dk4wreg_set_dword_c8(kptr, name, val, erp));
+#endif
+}
+
+
+
+int
+dk4wreg_get_dword(
+ void *kptr,
+ const dkChar *name,
+ dk4_dword_t *vptr,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4wreg_get_dword_wc(kptr, name, vptr, erp));
+#else
+ return (dk4wreg_get_dword_c8(kptr, name, vptr, erp));
+#endif
+}
+
+
+
+int
+dk4wreg_get_expanded_string(
+ void *kptr,
+ const dkChar *name,
+ dkChar *dptr,
+ size_t dsz,
+ dkChar *b1,
+ size_t b1sz,
+ dkChar *b2,
+ size_t b2sz,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (
+ dk4wreg_get_expanded_string_wc(
+ kptr, name, dptr, dsz, b1, b1sz, b2, b2sz, erp
+ )
+ );
+#else
+ return (
+ dk4wreg_get_expanded_string_c8(
+ kptr, name, dptr, dsz, b1, b1sz, b2, b2sz, erp
+ )
+ );
+#endif
+}
+
diff --git a/support/dktools/dk4wregd.ctr b/support/dktools/dk4wregd.ctr
new file mode 100644
index 0000000000..e6d6b267d6
--- /dev/null
+++ b/support/dktools/dk4wregd.ctr
@@ -0,0 +1,316 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Access Windows registry, use
+ dkChar names.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4WREGK_H_INCLUDED
+#include "dk4wregk.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open a registry key.
+ @param pk Parent key identifier.
+ @param keyname Name of registry key to open.
+ @param wr Flag: Open for write access too.
+ @param erp Error report, may be NULL.
+ @return Pointer to key handle structure on success, NULL on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ if the function is run on a non-Windows system,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if pk or keyname is invalid,
+ - DK4_E_NOT_FOUND<br>
+ if opening or creating the registry key failed,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if memory allocation for the key handle structure failed.
+*/
+void *
+dk4wreg_open_key(int pk, const dkChar *keyname, int wr, dk4_er_t *erp);
+
+/** Set a string value.
+ @param kptr Key handle structure.
+ @param name Entry name.
+ @param val Entry value.
+ @param expand Flag: Use REG_EXPAND_SZ (1) or REG_SZ (0).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ when called on non-Windows systems,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if kptr or val is NULL,
+ - DK4_E_MATH_OVERFLOW<br>
+ if the name is too long,
+ - DK4_E_SYSTEM<br>
+ if RegSetValueExA() failed.
+*/
+int
+dk4wreg_set_string(
+ void *kptr, const dkChar *name, const dkChar *val, int expand, dk4_er_t *erp
+);
+
+/** Get string value.
+ @param kptr Key handle structure.
+ @param name Entry name.
+ @param bptr Buffer for result string.
+ @param sz Result buffer length.
+ @param expand Pointer to expand flag output variable.
+ This variable is set to 1 if the string found
+ is of type REG_EXPAND_SZ. The variable is left
+ unchanged for REG_SZ.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ when called on non-Windows systems,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if kptr, name, or bptr is NULL or sz is 0,
+ - DK4_E_NOT_FOUND<br>
+ if the entry is not found or has 0 length,
+ - DK4_E_SYNTAX<br>
+ if the entry is not a string type.
+*/
+int
+dk4wreg_get_string(
+ void *kptr,
+ const dkChar *name,
+ dkChar *bptr,
+ size_t sz,
+ int *expand,
+ dk4_er_t *erp
+);
+
+/** Set DWORD registry entry.
+ @param kptr Key handle structure.
+ @param name Entry name.
+ @param val Value.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ when called on a non-Windows system,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if kptr is NULL,
+ - DK4_E_SYSTEM<br>
+ if RegSetValueExA() failed.
+*/
+int
+dk4wreg_set_dword(
+ void *kptr, const dkChar *name, dk4_dword_t val, dk4_er_t *erp
+);
+
+/** Retrieve DWORD value from registry.
+ @param kptr Key handle structure.
+ @param name Entry name.
+ @param vptr Pointer to result variable.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4wreg_get_dword(
+ void *kptr,
+ const dkChar *name,
+ dk4_dword_t *vptr,
+ dk4_er_t *erp
+);
+
+/** Get string value.
+ @param kptr Key handle structure.
+ @param name Entry name.
+ @param dptr Buffer for result string.
+ @param dsz Result buffer length, number of dkChar.
+ @param b1 First buffer, used for result from RegQueryValue().
+ Should have same size as dptr.
+ @param b1sz Size of b1, number of dkChar.
+ @param b2 Second buffer, used for result from ExpandEnvironmentStrings.
+ Should be 2 characters larger than dptr.
+ @param b2sz Size of b2, number of dkChar.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ when called on non-Windows systems,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if kptr, name, dptr, b1 or b2 is NULL or
+ dsz, b1sz or b2sz is 0 or out of range,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if one of the buffers is too small,
+ - DK4_E_NOT_FOUND<br>
+ if the entry is not found or has 0 length,
+ - DK4_E_SYNTAX<br>
+ if the entry is not a string type.
+*/
+int
+dk4wreg_get_expanded_string(
+ void *kptr,
+ const dkChar *name,
+ dkChar *dptr,
+ size_t dsz,
+ dkChar *b1,
+ size_t b1sz,
+ dkChar *b2,
+ size_t b2sz,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+#if DK4_CHAR_SIZE > 1
+#include "dk4wregw.h"
+#else
+#include "dk4wreg8.h"
+#endif
+
+#include "dk4wregd.h"
+
+
+
+$!trace-include
+
+
+
+void *
+dk4wreg_open_key(int pk, const dkChar *keyname, int wr, dk4_er_t *erp)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4wreg_open_key_wc(pk, keyname, wr, erp));
+#else
+ return (dk4wreg_open_key_c8(pk, keyname, wr, erp));
+#endif
+}
+
+
+
+int
+dk4wreg_set_string(
+ void *kptr, const dkChar *name, const dkChar *val, int expand, dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4wreg_set_string_wc(kptr, name, val, expand, erp));
+#else
+ return (dk4wreg_set_string_c8(kptr, name, val, expand, erp));
+#endif
+}
+
+
+
+int
+dk4wreg_get_string(
+ void *kptr,
+ const dkChar *name,
+ dkChar *bptr,
+ size_t sz,
+ int *expand,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4wreg_get_string_wc(kptr, name, bptr, sz, expand, erp));
+#else
+ return (dk4wreg_get_string_c8(kptr, name, bptr, sz, expand, erp));
+#endif
+}
+
+
+
+int
+dk4wreg_set_dword(
+ void *kptr, const dkChar *name, dk4_dword_t val, dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4wreg_set_dword_wc(kptr, name, val, erp));
+#else
+ return (dk4wreg_set_dword_c8(kptr, name, val, erp));
+#endif
+}
+
+
+
+int
+dk4wreg_get_dword(
+ void *kptr,
+ const dkChar *name,
+ dk4_dword_t *vptr,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (dk4wreg_get_dword_wc(kptr, name, vptr, erp));
+#else
+ return (dk4wreg_get_dword_c8(kptr, name, vptr, erp));
+#endif
+}
+
+
+
+int
+dk4wreg_get_expanded_string(
+ void *kptr,
+ const dkChar *name,
+ dkChar *dptr,
+ size_t dsz,
+ dkChar *b1,
+ size_t b1sz,
+ dkChar *b2,
+ size_t b2sz,
+ dk4_er_t *erp
+)
+{
+#if DK4_CHAR_SIZE > 1
+ return (
+ dk4wreg_get_expanded_string_wc(
+ kptr, name, dptr, dsz, b1, b1sz, b2, b2sz, erp
+ )
+ );
+#else
+ return (
+ dk4wreg_get_expanded_string_c8(
+ kptr, name, dptr, dsz, b1, b1sz, b2, b2sz, erp
+ )
+ );
+#endif
+}
+
diff --git a/support/dktools/dk4wregd.h b/support/dktools/dk4wregd.h
new file mode 100644
index 0000000000..47191d01b8
--- /dev/null
+++ b/support/dktools/dk4wregd.h
@@ -0,0 +1,226 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4wregd.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4WREGD_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4WREGD_H_INCLUDED 1
+
+
+#line 10 "dk4wregd.ctr"
+
+/** @file
+ Access Windows registry, use
+ dkChar names.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4WREGK_H_INCLUDED
+#include "dk4wregk.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open a registry key.
+ @param pk Parent key identifier.
+ @param keyname Name of registry key to open.
+ @param wr Flag: Open for write access too.
+ @param erp Error report, may be NULL.
+ @return Pointer to key handle structure on success, NULL on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ if the function is run on a non-Windows system,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if pk or keyname is invalid,
+ - DK4_E_NOT_FOUND<br>
+ if opening or creating the registry key failed,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if memory allocation for the key handle structure failed.
+*/
+void *
+dk4wreg_open_key(int pk, const dkChar *keyname, int wr, dk4_er_t *erp);
+
+/** Set a string value.
+ @param kptr Key handle structure.
+ @param name Entry name.
+ @param val Entry value.
+ @param expand Flag: Use REG_EXPAND_SZ (1) or REG_SZ (0).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ when called on non-Windows systems,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if kptr or val is NULL,
+ - DK4_E_MATH_OVERFLOW<br>
+ if the name is too long,
+ - DK4_E_SYSTEM<br>
+ if RegSetValueExA() failed.
+*/
+int
+dk4wreg_set_string(
+ void *kptr, const dkChar *name, const dkChar *val, int expand, dk4_er_t *erp
+);
+
+/** Get string value.
+ @param kptr Key handle structure.
+ @param name Entry name.
+ @param bptr Buffer for result string.
+ @param sz Result buffer length.
+ @param expand Pointer to expand flag output variable.
+ This variable is set to 1 if the string found
+ is of type REG_EXPAND_SZ. The variable is left
+ unchanged for REG_SZ.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ when called on non-Windows systems,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if kptr, name, or bptr is NULL or sz is 0,
+ - DK4_E_NOT_FOUND<br>
+ if the entry is not found or has 0 length,
+ - DK4_E_SYNTAX<br>
+ if the entry is not a string type.
+*/
+int
+dk4wreg_get_string(
+ void *kptr,
+ const dkChar *name,
+ dkChar *bptr,
+ size_t sz,
+ int *expand,
+ dk4_er_t *erp
+);
+
+/** Set DWORD registry entry.
+ @param kptr Key handle structure.
+ @param name Entry name.
+ @param val Value.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ when called on a non-Windows system,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if kptr is NULL,
+ - DK4_E_SYSTEM<br>
+ if RegSetValueExA() failed.
+*/
+int
+dk4wreg_set_dword(
+ void *kptr, const dkChar *name, dk4_dword_t val, dk4_er_t *erp
+);
+
+/** Retrieve DWORD value from registry.
+ @param kptr Key handle structure.
+ @param name Entry name.
+ @param vptr Pointer to result variable.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4wreg_get_dword(
+ void *kptr,
+ const dkChar *name,
+ dk4_dword_t *vptr,
+ dk4_er_t *erp
+);
+
+/** Get string value.
+ @param kptr Key handle structure.
+ @param name Entry name.
+ @param dptr Buffer for result string.
+ @param dsz Result buffer length, number of dkChar.
+ @param b1 First buffer, used for result from RegQueryValue().
+ Should have same size as dptr.
+ @param b1sz Size of b1, number of dkChar.
+ @param b2 Second buffer, used for result from ExpandEnvironmentStrings.
+ Should be 2 characters larger than dptr.
+ @param b2sz Size of b2, number of dkChar.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ when called on non-Windows systems,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if kptr, name, dptr, b1 or b2 is NULL or
+ dsz, b1sz or b2sz is 0 or out of range,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if one of the buffers is too small,
+ - DK4_E_NOT_FOUND<br>
+ if the entry is not found or has 0 length,
+ - DK4_E_SYNTAX<br>
+ if the entry is not a string type.
+*/
+int
+dk4wreg_get_expanded_string(
+ void *kptr,
+ const dkChar *name,
+ dkChar *dptr,
+ size_t dsz,
+ dkChar *b1,
+ size_t b1sz,
+ dkChar *b2,
+ size_t b2sz,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/dk4wregk.h b/support/dktools/dk4wregk.h
new file mode 100644
index 0000000000..e06823d614
--- /dev/null
+++ b/support/dktools/dk4wregk.h
@@ -0,0 +1,34 @@
+#ifndef DK4WREGK_H_INCLUDED
+#define DK4WREGK_H_INCLUDED 1
+
+/** @file dk4wregk.h Keys for Windows registry access.
+*/
+
+
+/** Numeric identifiers for registry hives.
+*/
+enum {
+ /** HKEY_LOCAL_MACHINE.
+ */
+ DK4_WREGKEY_HKLM = 0,
+
+ /** HKEY_CURRENT_USER.
+ */
+ DK4_WREGKEY_HKCU,
+
+ /** HKEY_CLASSES_ROOT.
+ */
+ DK4_WREGKEY_HKCL,
+
+ /** HKEY_USERS.
+ */
+ DK4_WREGKEY_KHUS,
+
+ /** HKEY_CURRENT_CONFIG.
+ */
+ DK4_WREGKEY_HKCC
+};
+
+
+#endif
+
diff --git a/support/dktools/dk4wregt.h b/support/dktools/dk4wregt.h
new file mode 100644
index 0000000000..00ce1c9e57
--- /dev/null
+++ b/support/dktools/dk4wregt.h
@@ -0,0 +1,34 @@
+#ifndef DK4WREGT_H_INCLUDED
+#define DK4WREGT_H_INCLUDED 1
+
+/** @file dk4wregt.h Type definitions for Windows registry access.
+*/
+
+#if DK4_ON_WINDOWS
+
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#ifndef WINBASE_H_INCLUDED
+#include <winbase.h>
+#define WINBASE_H_INCLUDED 1
+#endif
+#ifndef WINREG_H_INCLUDED
+#include <winreg.h>
+#define WINREG_H_INCLUDED 1
+#endif
+
+#endif
+
+/** Key handle structure, useful data on Windows, dummy on others.
+*/
+typedef struct {
+#if DK4_ON_WINDOWS
+ HKEY hk; /**< The registry key handle. */
+#else
+ int dummy; /**< Dummy contents for non-Windows systems. */
+#endif
+} dk4_wreg_key_t;
+
+#endif
diff --git a/support/dktools/dk4wregw.c b/support/dktools/dk4wregw.c
new file mode 100644
index 0000000000..83b7ba4ac1
--- /dev/null
+++ b/support/dktools/dk4wregw.c
@@ -0,0 +1,457 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4wregw.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4wregw.c The dk4wregw module.
+*/
+
+
+#line 192 "dk4wregw.ctr"
+
+#include "dk4conf.h"
+#include "dk4wregt.h"
+#include "dk4wregw.h"
+#include "dk4strw.h"
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+#include "dk4maasz.h"
+
+#if DK4_ON_WINDOWS
+
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#ifndef WINBASE_H_INCLUDED
+#include <winbase.h>
+#define WINBASE_H_INCLUDED 1
+#endif
+#ifndef WINREG_H_INCLUDED
+#include <winreg.h>
+#define WINREG_H_INCLUDED 1
+#endif
+
+#endif
+
+
+
+
+
+#line 222 "dk4wregw.ctr"
+
+
+
+void *
+dk4wreg_open_key_wc(int pk, const wchar_t *keyname, int wr, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ dk4_wreg_key_t *back = NULL;
+ HKEY park = HKEY_LOCAL_MACHINE;
+ LONG res;
+ DWORD disp;
+ if (NULL != keyname) {
+ switch (pk) {
+ case DK4_WREGKEY_HKLM:
+ case DK4_WREGKEY_HKCU:
+ case DK4_WREGKEY_HKCL:
+ case DK4_WREGKEY_KHUS:
+ case DK4_WREGKEY_HKCC: {
+ switch (pk) {
+ case DK4_WREGKEY_HKLM: {
+ park = HKEY_LOCAL_MACHINE;
+ } break;
+ case DK4_WREGKEY_HKCU: {
+ park = HKEY_CURRENT_USER;
+ } break;
+ case DK4_WREGKEY_HKCL: {
+ park = HKEY_CLASSES_ROOT;
+ } break;
+ case DK4_WREGKEY_KHUS: {
+ park = HKEY_USERS;
+ } break;
+ case DK4_WREGKEY_HKCC: {
+ park = HKEY_CURRENT_CONFIG;
+ } break;
+ }
+ back = dk4mem_new(dk4_wreg_key_t,1,erp);
+ if (NULL != back) {
+ res = RegCreateKeyExW(
+ park,
+ keyname,
+ (DWORD)0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ ((0 != wr) ? (KEY_ALL_ACCESS) : (KEY_READ)),
+ NULL,
+ &(back->hk),
+ &disp
+ );
+ if (ERROR_SUCCESS != res) {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ dk4mem_free(back);
+ back = NULL;
+ }
+ }
+ } break;
+ default: {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return ((void *)back);
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return NULL;
+#endif
+}
+
+
+
+int
+dk4wreg_set_string_wc(
+ void *kptr, const wchar_t *name, const wchar_t *val, int expand, dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+ dk4_er_t er;
+ dk4_wreg_key_t *hptr;
+ int back = 0;
+ size_t lgt;
+ DWORD dwt = REG_SZ;
+ DWORD dw0 = (DWORD)0UL;
+ DWORD sz;
+ LONG res;
+ if ((NULL != kptr) && (NULL != val)) {
+ if (0 != expand) { dwt = REG_EXPAND_SZ; }
+ dk4error_init(&er);
+ lgt = dk4ma_size_t_add( 1, dk4strw_len(val), &er );
+ lgt = dk4ma_size_t_mul( 2, lgt, &er );
+ if (DK4_E_NONE == er.ec) {
+ if ((dk4_um_t)0x7FFFFFFFUL >= (dk4_um_t)lgt) {
+ sz = (DWORD)lgt;
+ hptr = (dk4_wreg_key_t *)kptr;
+ res = RegSetValueExW(
+ hptr->hk,
+ name,
+ dw0,
+ dwt,
+ (const BYTE *)val,
+ sz
+ );
+ if (ERROR_SUCCESS == res) {
+ back = 1;
+ } else {
+ dk4error_set_ldetails(erp, DK4_E_SYSTEM, res);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+}
+
+
+
+int
+dk4wreg_get_string_wc(
+ void *kptr,
+ const wchar_t *name,
+ wchar_t *bptr,
+ size_t sz,
+ int *expand,
+ dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+ dk4_er_t er;
+ dk4_wreg_key_t *hptr;
+ int back = 0;
+ DWORD dwt = REG_SZ;
+ DWORD dws;
+ DWORD dwsbck;
+ LONG res;
+ size_t rsz;
+ if ((NULL != bptr) && (0 < sz)) {
+ *bptr = '\0';
+ }
+ if ((NULL != kptr) && (NULL != name) && (NULL != bptr) && (0 < sz)) {
+ dk4error_init(&er);
+ rsz = dk4ma_size_t_mul(sz, 2, &er);
+ if (DK4_E_NONE == er.ec) {
+ if ((dk4_um_t)0x7FFFFFFFUL >= (dk4_um_t)rsz) {
+ dws = (DWORD)rsz;
+ } else {
+ dws = (DWORD)0x7FFFFFFFUL;
+ }
+ dwsbck = dws;
+ hptr = (dk4_wreg_key_t *)kptr;
+ res = RegQueryValueExW(
+ hptr->hk,
+ name,
+ NULL,
+ &dwt,
+ (LPBYTE)bptr,
+ &dws
+ );
+ if (ERROR_SUCCESS == res) {
+ switch (dwt) {
+ case REG_SZ: case REG_EXPAND_SZ: {
+ if ((DWORD)1L < dws) {
+ dws = dws / 2;
+ if (dws < sz) { /* dws is positive */
+ bptr[dws] = L'\0';
+ } else {
+ bptr[sz-1] = L'\0';
+ }
+ back = 1;
+ if (REG_EXPAND_SZ == dwt) {
+ if (NULL != expand) {
+ *expand = 1;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } break;
+ default: {
+ /* ERROR: Not a string */
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+}
+
+
+
+int
+dk4wreg_set_dword_wc(
+ void *kptr, const wchar_t *name, dk4_dword_t val, dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+ dk4_wreg_key_t *hptr;
+ int back = 0;
+ DWORD dwt = REG_DWORD;
+ DWORD dws = sizeof(DWORD);
+ DWORD dw0 = (DWORD)0L;
+ LONG res;
+ if (NULL != kptr) {
+ hptr = (dk4_wreg_key_t *)kptr;
+ res = RegSetValueExW(
+ hptr->hk,
+ name,
+ dw0,
+ dwt,
+ (const BYTE *)(&val),
+ dws
+ );
+ if (ERROR_SUCCESS == res) {
+ back = 1;
+ } else {
+ dk4error_set_ldetails(erp, DK4_E_SYSTEM, res);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+}
+
+
+
+int
+dk4wreg_get_dword_wc(
+ void *kptr,
+ const wchar_t *name,
+ dk4_dword_t *vptr,
+ dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+ dk4_wreg_key_t *hptr;
+ int back = 0;
+ DWORD dwt = REG_DWORD;
+ DWORD dws = (DWORD)sizeof(DWORD);
+ LONG res;
+ if ((NULL != kptr) && (NULL != vptr)) {
+ hptr = (dk4_wreg_key_t *)kptr;
+ res = RegQueryValueExW(
+ hptr->hk,
+ name,
+ NULL,
+ &dwt,
+ (LPBYTE)vptr,
+ &dws
+ );
+ if (ERROR_SUCCESS == res) {
+ if (REG_DWORD == dwt) {
+ if ((DWORD)sizeof(DWORD) == dws) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+}
+
+
+
+int
+dk4wreg_get_expanded_string_wc(
+ void *kptr,
+ const wchar_t *name,
+ wchar_t *dptr,
+ size_t dsz,
+ wchar_t *b1,
+ size_t b1sz,
+ wchar_t *b2,
+ size_t b2sz,
+ dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+ DWORD dws;
+ DWORD nc;
+ int expand = 0;
+ int back = 0;
+ if ((NULL != dptr) && (0 < dsz)) { *dptr = L'\0'; }
+ if ((NULL != kptr) && (NULL != name) && (NULL != dptr) && (0 < dsz)) {
+ if ((NULL != b1) && (NULL != b2) && (0 < b1sz) && (2 < b2sz)) {
+ back = dk4wreg_get_string_wc(kptr, name, b1, b1sz, &expand, erp);
+ if (0 != back) {
+ if (0 != expand) {
+
+#line 541 "dk4wregw.ctr"
+ if ((dk4_um_t)0x7FFFFFFFUL >= (dk4_um_t)b2sz) {
+ dws = (DWORD)b2sz;
+
+#line 543 "dk4wregw.ctr"
+ } else {
+ dws = 0x7FFFFFFFUL;
+
+#line 545 "dk4wregw.ctr"
+ }
+ dws = dws - 2;
+ nc = ExpandEnvironmentStringsW(b1, b2, dws);
+ if ((0 < nc) && (nc <= dws)) {
+
+#line 549 "dk4wregw.ctr"
+ back = dk4strw_cpy_s(dptr, dsz, b2, erp);
+
+
+#line 551 "dk4wregw.ctr"
+
+
+#line 552 "dk4wregw.ctr"
+
+
+#line 553 "dk4wregw.ctr"
+ } else {
+
+#line 554 "dk4wregw.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else {
+
+#line 557 "dk4wregw.ctr"
+ back = dk4strw_cpy_s(dptr, dsz, b1, erp);
+
+
+#line 559 "dk4wregw.ctr"
+
+
+#line 560 "dk4wregw.ctr"
+
+
+#line 561 "dk4wregw.ctr"
+ }
+ } else {
+
+#line 563 "dk4wregw.ctr"
+ }
+ } else {
+
+#line 565 "dk4wregw.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else {
+
+#line 568 "dk4wregw.ctr"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+}
+
diff --git a/support/dktools/dk4wregw.ctr b/support/dktools/dk4wregw.ctr
new file mode 100644
index 0000000000..21c840f10e
--- /dev/null
+++ b/support/dktools/dk4wregw.ctr
@@ -0,0 +1,576 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Access Windows registry, use
+ wchar_t names.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4WREGK_H_INCLUDED
+#include "dk4wregk.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open a registry key.
+ @param pk Parent key identifier.
+ @param keyname Name of registry key to open.
+ @param wr Flag: Open for write access too.
+ @param erp Error report, may be NULL.
+ @return Pointer to key handle structure on success, NULL on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ if the function is run on a non-Windows system,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if pk or keyname is invalid,
+ - DK4_E_NOT_FOUND<br>
+ if opening or creating the registry key failed,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if memory allocation for the key handle structure failed.
+*/
+void *
+dk4wreg_open_key_wc(int pk, const wchar_t *keyname, int wr, dk4_er_t *erp);
+
+/** Set a string value.
+ @param kptr Key handle structure.
+ @param name Entry name.
+ @param val Entry value.
+ @param expand Flag: Use REG_EXPAND_SZ (1) or REG_SZ (0).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ when called on non-Windows systems,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if kptr or val is NULL,
+ - DK4_E_MATH_OVERFLOW<br>
+ if the name is too long,
+ - DK4_E_SYSTEM<br>
+ if RegSetValueExW() failed.
+*/
+int
+dk4wreg_set_string_wc(
+ void *kptr, const wchar_t *name, const wchar_t *val, int expand, dk4_er_t *erp
+);
+
+/** Get string value.
+ @param kptr Key handle structure.
+ @param name Entry name.
+ @param bptr Buffer for result string.
+ @param sz Result buffer length, number of wchar_t.
+ @param expand Pointer to expand flag output variable.
+ This variable is set to 1 if the string found
+ is of type REG_EXPAND_SZ. The variable is left
+ unchanged for REG_SZ.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ when called on non-Windows systems,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if kptr, name, or bptr is NULL or sz is 0,
+ - DK4_E_NOT_FOUND<br>
+ if the entry is not found or has 0 length,
+ - DK4_E_SYNTAX<br>
+ if the entry is not a string type.
+*/
+int
+dk4wreg_get_string_wc(
+ void *kptr,
+ const wchar_t *name,
+ wchar_t *bptr,
+ size_t sz,
+ int *expand,
+ dk4_er_t *erp
+);
+
+/** Set DWORD registry entry.
+ @param kptr Key handle structure.
+ @param name Entry name.
+ @param val Value.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ when called on a non-Windows system,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if kptr is NULL,
+ - DK4_E_SYSTEM<br>
+ if RegSetValueExW() failed.
+*/
+int
+dk4wreg_set_dword_wc(
+ void *kptr, const wchar_t *name, dk4_dword_t val, dk4_er_t *erp
+);
+
+/** Retrieve DWORD value from registry.
+ @param kptr Key handle structure.
+ @param name Entry name.
+ @param vptr Pointer to result variable.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4wreg_get_dword_wc(
+ void *kptr,
+ const wchar_t *name,
+ dk4_dword_t *vptr,
+ dk4_er_t *erp
+);
+
+/** Get string value.
+ @param kptr Key handle structure.
+ @param name Entry name.
+ @param dptr Buffer for result string.
+ @param dsz Result buffer length, number of wchar_t.
+ @param b1 First buffer, used for result from RegQueryValue().
+ Should have same size as dptr.
+ @param b1sz Size of b1, number of wchar_t.
+ @param b2 Second buffer, used for result from ExpandEnvironmentStrings.
+ Should be 2 characters larger than dptr.
+ @param b2sz Size of b2, number of wchar_t.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ when called on non-Windows systems,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if kptr, name, or bptr is NULL or sz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if one of the buffers is too small,
+ - DK4_E_NOT_FOUND<br>
+ if the entry is not found or has 0 length,
+ - DK4_E_SYNTAX<br>
+ if the entry is not a string type.
+*/
+int
+dk4wreg_get_expanded_string_wc(
+ void *kptr,
+ const wchar_t *name,
+ wchar_t *dptr,
+ size_t dsz,
+ wchar_t *b1,
+ size_t b1sz,
+ wchar_t *b2,
+ size_t b2sz,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4wregt.h"
+#include "dk4wregw.h"
+#include "dk4strw.h"
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+#include "dk4maasz.h"
+
+#if DK4_ON_WINDOWS
+
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#ifndef WINBASE_H_INCLUDED
+#include <winbase.h>
+#define WINBASE_H_INCLUDED 1
+#endif
+#ifndef WINREG_H_INCLUDED
+#include <winreg.h>
+#define WINREG_H_INCLUDED 1
+#endif
+
+#endif
+
+
+
+$!trace-include
+
+
+
+void *
+dk4wreg_open_key_wc(int pk, const wchar_t *keyname, int wr, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ dk4_wreg_key_t *back = NULL;
+ HKEY park = HKEY_LOCAL_MACHINE;
+ LONG res;
+ DWORD disp;
+ if (NULL != keyname) {
+ switch (pk) {
+ case DK4_WREGKEY_HKLM:
+ case DK4_WREGKEY_HKCU:
+ case DK4_WREGKEY_HKCL:
+ case DK4_WREGKEY_KHUS:
+ case DK4_WREGKEY_HKCC: {
+ switch (pk) {
+ case DK4_WREGKEY_HKLM: {
+ park = HKEY_LOCAL_MACHINE;
+ } break;
+ case DK4_WREGKEY_HKCU: {
+ park = HKEY_CURRENT_USER;
+ } break;
+ case DK4_WREGKEY_HKCL: {
+ park = HKEY_CLASSES_ROOT;
+ } break;
+ case DK4_WREGKEY_KHUS: {
+ park = HKEY_USERS;
+ } break;
+ case DK4_WREGKEY_HKCC: {
+ park = HKEY_CURRENT_CONFIG;
+ } break;
+ }
+ back = dk4mem_new(dk4_wreg_key_t,1,erp);
+ if (NULL != back) {
+ res = RegCreateKeyExW(
+ park,
+ keyname,
+ (DWORD)0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ ((0 != wr) ? (KEY_ALL_ACCESS) : (KEY_READ)),
+ NULL,
+ &(back->hk),
+ &disp
+ );
+ if (ERROR_SUCCESS != res) {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ dk4mem_free(back);
+ back = NULL;
+ }
+ }
+ } break;
+ default: {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return ((void *)back);
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return NULL;
+#endif
+}
+
+
+
+int
+dk4wreg_set_string_wc(
+ void *kptr, const wchar_t *name, const wchar_t *val, int expand, dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+ dk4_er_t er;
+ dk4_wreg_key_t *hptr;
+ int back = 0;
+ size_t lgt;
+ DWORD dwt = REG_SZ;
+ DWORD dw0 = (DWORD)0UL;
+ DWORD sz;
+ LONG res;
+ if ((NULL != kptr) && (NULL != val)) {
+ if (0 != expand) { dwt = REG_EXPAND_SZ; }
+ dk4error_init(&er);
+ lgt = dk4ma_size_t_add( 1, dk4strw_len(val), &er );
+ lgt = dk4ma_size_t_mul( 2, lgt, &er );
+ if (DK4_E_NONE == er.ec) {
+ if ((dk4_um_t)0x7FFFFFFFUL >= (dk4_um_t)lgt) {
+ sz = (DWORD)lgt;
+ hptr = (dk4_wreg_key_t *)kptr;
+ res = RegSetValueExW(
+ hptr->hk,
+ name,
+ dw0,
+ dwt,
+ (const BYTE *)val,
+ sz
+ );
+ if (ERROR_SUCCESS == res) {
+ back = 1;
+ } else {
+ dk4error_set_ldetails(erp, DK4_E_SYSTEM, res);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+}
+
+
+
+int
+dk4wreg_get_string_wc(
+ void *kptr,
+ const wchar_t *name,
+ wchar_t *bptr,
+ size_t sz,
+ int *expand,
+ dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+ dk4_er_t er;
+ dk4_wreg_key_t *hptr;
+ int back = 0;
+ DWORD dwt = REG_SZ;
+ DWORD dws;
+ DWORD dwsbck;
+ LONG res;
+ size_t rsz;
+ if ((NULL != bptr) && (0 < sz)) {
+ *bptr = '\0';
+ }
+ if ((NULL != kptr) && (NULL != name) && (NULL != bptr) && (0 < sz)) {
+ dk4error_init(&er);
+ rsz = dk4ma_size_t_mul(sz, 2, &er);
+ if (DK4_E_NONE == er.ec) {
+ if ((dk4_um_t)0x7FFFFFFFUL >= (dk4_um_t)rsz) {
+ dws = (DWORD)rsz;
+ } else {
+ dws = (DWORD)0x7FFFFFFFUL;
+ }
+ dwsbck = dws;
+ hptr = (dk4_wreg_key_t *)kptr;
+ res = RegQueryValueExW(
+ hptr->hk,
+ name,
+ NULL,
+ &dwt,
+ (LPBYTE)bptr,
+ &dws
+ );
+ if (ERROR_SUCCESS == res) {
+ switch (dwt) {
+ case REG_SZ: case REG_EXPAND_SZ: {
+ if ((DWORD)1L < dws) {
+ dws = dws / 2;
+ if (dws < sz) { /* dws is positive */
+ bptr[dws] = L'\0';
+ } else {
+ bptr[sz-1] = L'\0';
+ }
+ back = 1;
+ if (REG_EXPAND_SZ == dwt) {
+ if (NULL != expand) {
+ *expand = 1;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } break;
+ default: {
+ /* ERROR: Not a string */
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ } break;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+}
+
+
+
+int
+dk4wreg_set_dword_wc(
+ void *kptr, const wchar_t *name, dk4_dword_t val, dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+ dk4_wreg_key_t *hptr;
+ int back = 0;
+ DWORD dwt = REG_DWORD;
+ DWORD dws = sizeof(DWORD);
+ DWORD dw0 = (DWORD)0L;
+ LONG res;
+ if (NULL != kptr) {
+ hptr = (dk4_wreg_key_t *)kptr;
+ res = RegSetValueExW(
+ hptr->hk,
+ name,
+ dw0,
+ dwt,
+ (const BYTE *)(&val),
+ dws
+ );
+ if (ERROR_SUCCESS == res) {
+ back = 1;
+ } else {
+ dk4error_set_ldetails(erp, DK4_E_SYSTEM, res);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+}
+
+
+
+int
+dk4wreg_get_dword_wc(
+ void *kptr,
+ const wchar_t *name,
+ dk4_dword_t *vptr,
+ dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+ dk4_wreg_key_t *hptr;
+ int back = 0;
+ DWORD dwt = REG_DWORD;
+ DWORD dws = (DWORD)sizeof(DWORD);
+ LONG res;
+ if ((NULL != kptr) && (NULL != vptr)) {
+ hptr = (dk4_wreg_key_t *)kptr;
+ res = RegQueryValueExW(
+ hptr->hk,
+ name,
+ NULL,
+ &dwt,
+ (LPBYTE)vptr,
+ &dws
+ );
+ if (ERROR_SUCCESS == res) {
+ if (REG_DWORD == dwt) {
+ if ((DWORD)sizeof(DWORD) == dws) {
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+}
+
+
+
+int
+dk4wreg_get_expanded_string_wc(
+ void *kptr,
+ const wchar_t *name,
+ wchar_t *dptr,
+ size_t dsz,
+ wchar_t *b1,
+ size_t b1sz,
+ wchar_t *b2,
+ size_t b2sz,
+ dk4_er_t *erp
+)
+{
+#if DK4_ON_WINDOWS
+ DWORD dws;
+ DWORD nc;
+ int expand = 0;
+ int back = 0;
+ if ((NULL != dptr) && (0 < dsz)) { *dptr = L'\0'; }
+ if ((NULL != kptr) && (NULL != name) && (NULL != dptr) && (0 < dsz)) {
+ if ((NULL != b1) && (NULL != b2) && (0 < b1sz) && (2 < b2sz)) {
+ back = dk4wreg_get_string_wc(kptr, name, b1, b1sz, &expand, erp);
+ if (0 != back) {
+ if (0 != expand) { $? ". expansion"
+ if ((dk4_um_t)0x7FFFFFFFUL >= (dk4_um_t)b2sz) {
+ dws = (DWORD)b2sz; $? ". original size"
+ } else {
+ dws = 0x7FFFFFFFUL; $? ". cut size"
+ }
+ dws = dws - 2;
+ nc = ExpandEnvironmentStringsW(b1, b2, dws);
+ if ((0 < nc) && (nc <= dws)) { $? ". size ok"
+ back = dk4strw_cpy_s(dptr, dsz, b2, erp);
+ $!trace-code if (0 != back) {
+ $? ". result \"%ls\"", dptr
+ $!trace-code }
+ } else { $? "! wrong size"
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else { $? ". no expansion"
+ back = dk4strw_cpy_s(dptr, dsz, b1, erp);
+ $!trace-code if (0 != back) {
+ $? ". result \"%ls\"", dptr
+ $!trace-code }
+ }
+ } else { $? "! dk4wreg_get_string_wc"
+ }
+ } else { $? "! arguments"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ } else { $? "! arguments"
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+#else
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#endif
+}
+
diff --git a/support/dktools/dk4wregw.h b/support/dktools/dk4wregw.h
new file mode 100644
index 0000000000..6060bd0ef5
--- /dev/null
+++ b/support/dktools/dk4wregw.h
@@ -0,0 +1,224 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4wregw.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4WREGW_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4WREGW_H_INCLUDED 1
+
+
+#line 10 "dk4wregw.ctr"
+
+/** @file
+ Access Windows registry, use
+ wchar_t names.
+
+ CRT on Windows: Optional.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4WREGK_H_INCLUDED
+#include "dk4wregk.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open a registry key.
+ @param pk Parent key identifier.
+ @param keyname Name of registry key to open.
+ @param wr Flag: Open for write access too.
+ @param erp Error report, may be NULL.
+ @return Pointer to key handle structure on success, NULL on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ if the function is run on a non-Windows system,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if pk or keyname is invalid,
+ - DK4_E_NOT_FOUND<br>
+ if opening or creating the registry key failed,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if memory allocation for the key handle structure failed.
+*/
+void *
+dk4wreg_open_key_wc(int pk, const wchar_t *keyname, int wr, dk4_er_t *erp);
+
+/** Set a string value.
+ @param kptr Key handle structure.
+ @param name Entry name.
+ @param val Entry value.
+ @param expand Flag: Use REG_EXPAND_SZ (1) or REG_SZ (0).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ when called on non-Windows systems,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if kptr or val is NULL,
+ - DK4_E_MATH_OVERFLOW<br>
+ if the name is too long,
+ - DK4_E_SYSTEM<br>
+ if RegSetValueExW() failed.
+*/
+int
+dk4wreg_set_string_wc(
+ void *kptr, const wchar_t *name, const wchar_t *val, int expand, dk4_er_t *erp
+);
+
+/** Get string value.
+ @param kptr Key handle structure.
+ @param name Entry name.
+ @param bptr Buffer for result string.
+ @param sz Result buffer length, number of wchar_t.
+ @param expand Pointer to expand flag output variable.
+ This variable is set to 1 if the string found
+ is of type REG_EXPAND_SZ. The variable is left
+ unchanged for REG_SZ.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ when called on non-Windows systems,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if kptr, name, or bptr is NULL or sz is 0,
+ - DK4_E_NOT_FOUND<br>
+ if the entry is not found or has 0 length,
+ - DK4_E_SYNTAX<br>
+ if the entry is not a string type.
+*/
+int
+dk4wreg_get_string_wc(
+ void *kptr,
+ const wchar_t *name,
+ wchar_t *bptr,
+ size_t sz,
+ int *expand,
+ dk4_er_t *erp
+);
+
+/** Set DWORD registry entry.
+ @param kptr Key handle structure.
+ @param name Entry name.
+ @param val Value.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ when called on a non-Windows system,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if kptr is NULL,
+ - DK4_E_SYSTEM<br>
+ if RegSetValueExW() failed.
+*/
+int
+dk4wreg_set_dword_wc(
+ void *kptr, const wchar_t *name, dk4_dword_t val, dk4_er_t *erp
+);
+
+/** Retrieve DWORD value from registry.
+ @param kptr Key handle structure.
+ @param name Entry name.
+ @param vptr Pointer to result variable.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk4wreg_get_dword_wc(
+ void *kptr,
+ const wchar_t *name,
+ dk4_dword_t *vptr,
+ dk4_er_t *erp
+);
+
+/** Get string value.
+ @param kptr Key handle structure.
+ @param name Entry name.
+ @param dptr Buffer for result string.
+ @param dsz Result buffer length, number of wchar_t.
+ @param b1 First buffer, used for result from RegQueryValue().
+ Should have same size as dptr.
+ @param b1sz Size of b1, number of wchar_t.
+ @param b2 Second buffer, used for result from ExpandEnvironmentStrings.
+ Should be 2 characters larger than dptr.
+ @param b2sz Size of b2, number of wchar_t.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ Error codes:
+ - DK4_E_NOT_SUPPORTED<br>
+ when called on non-Windows systems,
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if kptr, name, or bptr is NULL or sz is 0,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if one of the buffers is too small,
+ - DK4_E_NOT_FOUND<br>
+ if the entry is not found or has 0 length,
+ - DK4_E_SYNTAX<br>
+ if the entry is not a string type.
+*/
+int
+dk4wreg_get_expanded_string_wc(
+ void *kptr,
+ const wchar_t *name,
+ wchar_t *dptr,
+ size_t dsz,
+ wchar_t *b1,
+ size_t b1sz,
+ wchar_t *b2,
+ size_t b2sz,
+ dk4_er_t *erp
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/dk4wxcs.cross b/support/dktools/dk4wxcs.cross
new file mode 100644
index 0000000000..1b3a46a143
--- /dev/null
+++ b/support/dktools/dk4wxcs.cross
@@ -0,0 +1,37 @@
+
+#ifndef DK4WXCS_H_INCLUDED
+
+/** Protection against multiple inclusions.
+*/
+#define DK4WXCS_H_INCLUDED 1
+
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_WXWIDGETS
+
+#include "wx/wxprec.h"
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+
+#if wxUSE_UNICODE
+#define DK4_SIZEOF_WXCHAR 2
+#else
+#define DK4_SIZEOF_WXCHAR 1
+#endif
+
+#else
+/* if DK4_HAVE_WXWIDGETS */
+
+#define DK4_SIZEOF_WXCHAR 0
+
+#endif
+/* if DK4_HAVE_WXWIDGETS */
+
+#endif
+/* DK4WXCS_H_INCLUDED */
+
diff --git a/support/dktools/dk4wxcs.h b/support/dktools/dk4wxcs.h
new file mode 100644
index 0000000000..34dccd8e11
--- /dev/null
+++ b/support/dktools/dk4wxcs.h
@@ -0,0 +1,12 @@
+/** @file dk4wxcs.h Configure size of wide characters.
+*/
+
+#ifndef DK4WXCSZ_H_INCLUDED
+/** Protection against multiple inclusions. */
+#define DK4WXCSZ_H_INCLUDED 1
+
+/** Size of wxChar.
+*/
+#define DK4_SIZEOF_WXCHAR 4
+
+#endif
diff --git a/support/dktools/dk4wxpref.cpp b/support/dktools/dk4wxpref.cpp
new file mode 100644
index 0000000000..979f930efc
--- /dev/null
+++ b/support/dktools/dk4wxpref.cpp
@@ -0,0 +1,645 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4wxpref.cpt
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4wxpref.cpp The dk4wxpref module.
+*/
+
+
+#line 160 "dk4wxpref.cpt"
+
+#include "dk4wxpref.h"
+#include "dk4strd.h"
+#include "dk4strx.h"
+#include "dk4recwx.h"
+#include "dk4mem.h"
+#include "dk4mpl.h"
+#include "dk4tspdk.h"
+#include "dk4fs.h"
+
+
+
+
+
+#line 173 "dk4wxpref.cpt"
+
+
+
+/** Preference reading helper structure.
+*/
+typedef struct {
+ dk4_sto_t *spref; /**< Preference storage. */
+ dk4_sto_it_t *ipref; /**< Preferences iterator. */
+ const dkChar *nameApp; /**< Application name. */
+ const dkChar *nameGrp; /**< Application group name. */
+ const dkChar *nameLog; /**< Users login name. */
+ const dkChar *nameHost; /**< Host name. */
+ const dkChar *language; /**< Users language. */
+ const dkChar *region; /**< Users region. */
+ wxChar *wx1; /**< One wxChar buffer. */
+ wxChar *wx2; /**< Other wxChar buffer. */
+ size_t szwx; /**< Size of wxChar buffers. */
+ int encWx; /**< Encoding for wxChar. */
+ int encDk; /**< Encoding for dkChar. */
+ int compat; /**< Flag: Compatible mode. */
+ int insc; /**< Flag: In scope. */
+ int lasc; /**< Flag: Previous line was scope. */
+} dk4_wx_pref_rd_t;
+
+
+
+/** Constant keywords used by the module, not localized.
+*/
+static const dkChar * const dk4wxpref_kw_dk[] = {
+/* 0 */
+dkT("dk3pref.conf"),
+
+/* 1 */
+dkT("dk4pref.conf"),
+
+/* 2 */
+dkT("*"),
+
+NULL
+
+
+#line 213 "dk4wxpref.cpt"
+};
+
+
+
+/** Names for scope settings.
+*/
+static const dkChar * const dk4wxpref_scope_names[] = {
+/* 0 */
+dkT("user"),
+
+/* 1 */
+dkT("application"),
+
+/* 2 */
+dkT("application-group"),
+
+/* 3 */
+dkT("host"),
+
+/* 4 */
+dkT("windows"),
+
+/* 5 */
+dkT("non-windows"),
+
+/* 6 */
+dkT("language"),
+
+/* 7 */
+dkT("region"),
+
+NULL
+
+
+#line 254 "dk4wxpref.cpt"
+};
+
+
+void
+dk4wxpref_close(dk4_wx_pref_t *ptr)
+{
+ if (NULL != ptr) {
+ dk4mem_release(ptr->name);
+ dk4mem_release(ptr->value);
+ dk4mem_free(ptr);
+ }
+}
+
+
+
+dk4_wx_pref_t *
+dk4wxpref_open(const wxChar *name, const wxChar *value, dk4_er_t *erp)
+{
+ dk4_wx_pref_t *back = NULL;
+ if ((NULL != name) && (NULL != value)) {
+ back = dk4mem_new(dk4_wx_pref_t,1,erp);
+ if (NULL != back) {
+ back->name = back->value = NULL;
+ back->name = dk4strx_dup(name, erp);
+ back->value = dk4strx_dup(value, erp);
+ if ((NULL == back->name) || (NULL == back->value)) {
+ dk4wxpref_close(back);
+ back = NULL;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MEMORY_ALLOCATION_FAILED);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MEMORY_ALLOCATION_FAILED);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4wxpref_compare(const void *l, const void *r, int cr)
+{
+ const dk4_wx_pref_t *lptr;
+ const dk4_wx_pref_t *rptr;
+ int back = 0;
+ if (NULL != l) {
+ if (NULL != r) {
+ lptr = (const dk4_wx_pref_t *)l;
+ switch (cr) {
+ case 1: {
+ if (NULL != lptr->name) {
+ back = dk4strx_cmp(lptr->name, (const wxChar *)r);
+ } else back = -1;
+ } break;
+ default: {
+ rptr = (const dk4_wx_pref_t *)r;
+ if (NULL != lptr->name) {
+ if (NULL != rptr->name) {
+ back = dk4strx_cmp(lptr->name, rptr->name);
+ } else back = 1;
+ } else {
+ if (NULL != rptr->name) back = -1;
+ }
+ } break;
+ }
+ if (-1 > back) back = -1;
+ if ( 1 < back) back = 1;
+ } else back = 1;
+ } else {
+ if (NULL != r) back = -1;
+ }
+ return back;
+}
+
+
+
+#if DK4_HAVE_COMPATDKTOOLS3
+
+/** Modify version 3 preference names to version 4 names.
+ I.e. /a/b/c -> a.b.c
+ @param pstr String to modify.
+*/
+static
+void
+dk4wxpref_modify_compatible(dkChar *pstr)
+{
+ if (dkT('/') == *pstr) {
+ dk4str_cpy_to_left(pstr, &(pstr[1]));
+ }
+ while (dkT('\0') != *pstr) {
+ if (dkT('/') == *pstr) { *pstr = dkT('.'); }
+ pstr++;
+ }
+}
+
+#endif
+
+
+
+/** Test one scope entry.
+ @param rd Reader object.
+ @param scn Scope part name.
+ @return 1 if test succeeded, 0 otherwise.
+*/
+static
+int
+dk4wxpref_check_one_scope_entry(dk4_wx_pref_rd_t *rd, dkChar *scn)
+{
+ dkChar *scv = NULL;
+ int back = 1;
+ scn = dk4str_start(scn, NULL);
+ if (NULL != scn) {
+ scv = dk4str_chr(scn, dkT('='));
+ if (NULL != scv) {
+ *(scv++) = dkT('\0'); scv = dk4str_start(scv, NULL);
+ }
+ dk4str_normalize(scn, NULL);
+ if (NULL != scv) { dk4str_normalize(scv, NULL); }
+ back = 0;
+ switch (dk4str_array_index(dk4wxpref_scope_names, scn, 0)) {
+ case 0: { /* user */
+ if (NULL != scv) {
+ if (0 == dk4str_cmp(dk4wxpref_kw_dk[2], scv)) {
+ back = 1;
+ } else {
+ if (NULL != rd->nameLog) {
+#if DK4_HAVE_CASE_INSENSITIVE_USERNAMES
+ if (0 == dk4str_casecmp(rd->nameLog, scv))
+#else
+ if (0 == dk4str_cmp(rd->nameLog, scv))
+#endif
+ {
+ back = 1;
+ }
+ }
+ }
+ }
+ } break;
+ case 1: { /* application */
+ if (NULL != scv) {
+ if (0 == dk4str_cmp(dk4wxpref_kw_dk[2], scv)) {
+ back = 1;
+ } else {
+ if (NULL != rd->nameApp) {
+ if (0 == dk4str_cmp(rd->nameApp, scv)) {
+ back = 1;
+ }
+ }
+ }
+ }
+ } break;
+ case 2: { /* application group */
+ if (NULL != scv) {
+ if (0 == dk4str_cmp(dk4wxpref_kw_dk[2], scv)) {
+ back = 1;
+ } else {
+ if (NULL != rd->nameGrp) {
+ if (0 == dk4str_cmp(rd->nameGrp, scv)) {
+ back = 1;
+ }
+ }
+ }
+ }
+ } break;
+ case 3: { /* host */
+ if (NULL != scv) {
+ if (0 == dk4str_cmp(dk4wxpref_kw_dk[2], scv)) {
+ back = 1;
+ } else {
+ if (NULL != rd->nameHost) {
+ if (0 == dk4str_casecmp(rd->nameHost, scv)) {
+ back = 1;
+ }
+ }
+ }
+ }
+ } break;
+ case 4: { /* windows */
+ if (NULL != scv) {
+ if (0 != dk4str_is_on(scv)) {
+#if DK4_ON_WINDOWS
+ back = 1;
+#endif
+ } else {
+#if !(DK4_ON_WINDOWS)
+ back = 1;
+#endif
+ }
+ } else {
+#if DK4_ON_WINDOWS
+ back = 1;
+#endif
+ }
+ } break;
+ case 5: { /* non-windows */
+ if (NULL != scv) {
+ if (0 != dk4str_is_on(scv)) {
+#if !(DK4_ON_WINDOWS)
+ back = 1;
+#endif
+ } else {
+#if DK4_ON_WINDOWS
+ back = 1;
+#endif
+ }
+ } else {
+#if !(DK4_ON_WINDOWS)
+ back = 1;
+#endif
+ }
+ } break;
+ case 6: { /* language */
+ if (NULL != scv) {
+ if (0 == dk4str_cmp(dk4wxpref_kw_dk[2], scv)) {
+ back = 1;
+ } else {
+ if (NULL != rd->language) {
+ if (0 == dk4str_casecmp(rd->language, scv)) {
+ back = 1;
+ }
+ }
+ }
+ }
+ } break;
+ case 7: { /* region */
+ if (NULL != scv) {
+ if (0 == dk4str_cmp(dk4wxpref_kw_dk[2], scv)) {
+ back = 1;
+ } else {
+ if (NULL != rd->region) {
+ if (0 == dk4str_casecmp(rd->region, scv)) {
+ back = 1;
+ }
+ }
+ }
+ }
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+/** Process one input line.
+ @param obj Preferences reader object.
+ @param line Current line to process.
+ @param lineno Line number.
+ @param erp Error report, may be NULL.
+ @return
+ DK4_TSP_RES_OK if processing succeeded,
+ DK4_TSP_RES_ERROR on errors (can continue),
+ DK4_TSP_RES_FATAL on fatal errors (can not continue).
+
+*/
+static
+int
+dk4wxpref_line_handler(
+ void *obj,
+ dkChar *line,
+ dk4_um_t lineno,
+ dk4_er_t *erp
+)
+{
+ dk4_wx_pref_rd_t *rd; /* Reader object */
+ dk4_wx_pref_t *pptr; /* New pref */
+ dkChar *p1; /* Pref name */
+ dkChar *p2; /* Pref value */
+ wxChar *nv; /* New value */
+ int isneg; /* Flag: Not in scope */
+ int ok; /* Flag: Tests passed */
+ int res; /* Operation result */
+ int back = DK4_TSP_RES_OK; /* Function result */
+
+ rd = (dk4_wx_pref_rd_t *)obj;
+ dk4str_delnl(line);
+ p1 = dk4str_start(line, NULL);
+ if (NULL != p1) {
+ if (dkT('#') != *p1) {
+ if (dkT('[') == *p1) {
+
+#line 537 "dk4wxpref.cpt"
+ if (0 == rd->lasc) {
+ rd->insc = 0;
+ }
+ p2 = dk4str_chr(p1, dkT(']'));
+ if (NULL != p2) { *p2 = dkT('\0'); }
+ p1++;
+ if (dkT('-') == *p1) {
+ isneg = 1;
+ p1++;
+ } else {
+ isneg = 0;
+ }
+ ok = 1;
+ while (NULL != p1) {
+ p2 = dk4str_chr(p1, dkT(','));
+ if (NULL != p2) {
+ *(p2++) = dkT('\0'); p2 = dk4str_start(p2, NULL);
+ }
+ if (0 == dk4wxpref_check_one_scope_entry(rd, p1)) { ok = 0; }
+ p1 = p2;
+ }
+ if (1 == ok) {
+ if (0 != isneg) { rd->insc = 0; } else { rd->insc = 1; }
+ }
+ rd->lasc = 1;
+ } else {
+
+#line 563 "dk4wxpref.cpt"
+ if (rd->insc) {
+ p2 = dk4str_chr(p1, dkT('='));
+ if (NULL != p2) {
+ *(p2++) = dkT('\0');
+ p2 = dk4str_start(p2, NULL);
+ }
+ if ((NULL != p1) && (NULL != p2)) {
+ dk4str_normalize(p1, NULL);
+ dk4str_rtwh(p2, NULL);
+#if DK4_HAVE_COMPATDKTOOLS3
+ if (0 != rd->compat) {
+ dk4wxpref_modify_compatible(p1);
+ }
+#endif
+ res = dk4recwx_dkchar_to_wxchar(
+ rd->wx1, rd->szwx, rd->encWx, p1, rd->encDk, NULL
+ );
+ if (0 < res) {
+ res = dk4recwx_dkchar_to_wxchar(
+ rd->wx2, rd->szwx, rd->encWx, p2, rd->encDk, NULL
+ );
+ if (0 < res) {
+ pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(
+ rd->ipref, rd->wx1, 1
+ );
+ if (NULL != pptr) {
+ nv = dk4strx_dup(rd->wx2, NULL);
+ if (NULL != nv) {
+ dk4mem_release(pptr->value);
+ pptr->value = nv;
+ }
+ } else {
+ pptr = dk4wxpref_open(rd->wx1, rd->wx2, NULL);
+ if (NULL != pptr) {
+ if (0 == dk4sto_add(rd->spref, pptr, NULL)) {
+ dk4wxpref_close(pptr);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ rd->lasc = 0;
+ }
+ } else {
+
+#line 609 "dk4wxpref.cpt"
+ }
+ } else {
+
+#line 611 "dk4wxpref.cpt"
+ }
+ return back;
+}
+
+
+
+
+/** Use one file.
+ @param spref Preferences storage.
+ @param ipref Iterator for preferences storage.
+ @param nameApp Application name.
+ @param nameGrp Application group name.
+ @param nameLog Users login name.
+ @param nameHost Host name.
+ @param language Language.
+ @param region Region.
+ @param fn File name.
+ @param encWx Encoding for wxChar strings.
+ @param encDk Encoding for dkChar strings.
+ @param encFile Expected encoding for files.
+ @param compat Flag: In compatibility mode.
+*/
+static
+void
+dk4wxpref_one_file(
+ dk4_sto_t *spref,
+ dk4_sto_it_t *ipref,
+ const dkChar *nameApp,
+ const dkChar *nameGrp,
+ const dkChar *nameLog,
+ const dkChar *nameHost,
+ const dkChar *language,
+ const dkChar *region,
+ const dkChar *fn,
+ int encWx,
+ int encDk,
+ int encFile,
+ int compat
+)
+{
+ char ib[4096]; /* Input buffer for stream read */
+ wxChar wx1[1024]; /* Buffer for conversion */
+ wxChar wx2[DK4_SIZEOF(wx1,wxChar)]; /* too */
+ dkChar il[1024]; /* Input line */
+ dk4_wx_pref_rd_t rd; /* Reader object */
+ dk4_er_t er; /* Error report */
+ dk4_tspdk_t tsp; /* Text stream processing */
+ dk4_stream_t *istrm; /* Input stream */
+ size_t szil = DK4_SIZEOF(il,dkChar); /* Buffer size */
+ size_t szwx = DK4_SIZEOF(wx1,wxChar); /* Buffer size */
+ size_t rb; /* Bytes read */
+ int res; /* Operation result */
+ int cc; /* Flag: Can continue */
+
+ dk4error_init(&er);
+ istrm = dk4stream_open_file_reader(fn, &er);
+ if (NULL != istrm) {
+ rd.spref = spref; rd.ipref = ipref;
+ rd.nameApp = nameApp; rd.nameGrp = nameGrp; rd.nameLog = nameLog;
+ rd.nameHost = nameHost;
+ rd.language = language; rd.region = region; rd.compat = compat;
+ rd.encWx = encWx; rd.encDk = encDk;
+ rd.insc = 1; rd.lasc = 0;
+ rd.wx1 = wx1; rd.wx2 = wx2; rd.szwx = szwx;
+ res = dk4tspdk_setup_line(
+ &tsp, &rd,
+ (dk4_dk_line_handler_t *)dk4wxpref_line_handler,
+ il, szil, encDk, encFile, &er
+ );
+ if (0 != res) {
+ cc = 1;
+ while (1 == cc) {
+ cc = 0;
+ rb = sizeof(ib);
+ if (0 != dk4stream_read(ib, &rb, istrm, &er)) {
+ if (0 < rb) {
+ cc = 1;
+ res = dk4tspdk_add_bytes(&tsp, (const unsigned char *)ib, rb);
+ if (DK4_TSP_RES_FATAL == res) {
+ cc = -1;
+ }
+ }
+ }
+ }
+ if (0 == cc) {
+#if VERSION_BEFORE_20150821
+ res = dk4tspdk_finish(&tsp);
+#else
+ (void)dk4tspdk_finish(&tsp);
+#endif
+ }
+ }
+ dk4stream_close(istrm, NULL);
+ }
+}
+
+
+
+void
+dk4wxpref_one_pass(
+ dk4_sto_t *spref,
+ dk4_sto_it_t *ipref,
+ const dkChar *nameApp,
+ const dkChar *nameGrp,
+ const dkChar *nameLog,
+ const dkChar *nameHost,
+ const dkChar *language,
+ const dkChar *region,
+ const dkChar *dirHome,
+ const dkChar *dirEtc,
+ const dkChar *dirShare,
+ int encWx,
+ int encDk,
+ int encFile,
+ int pn
+)
+{
+ dkChar fnb[DK4_MAX_PATH];
+ dk4_er_t er;
+ size_t szfnb = DK4_SIZEOF(fnb,dkChar);
+ int res;
+
+#if DK4_HAVE_COMPATDKTOOLS3
+ dk4error_init(&er);
+ res = dk4fs_config_compat_one(
+ fnb, szfnb, dk4wxpref_kw_dk[0], dirShare, dirEtc, dirHome,
+ nameApp, nameGrp, pn, 1, 1, &er
+ );
+ if (0 != res) {
+ dk4wxpref_one_file(
+ spref, ipref, nameApp, nameGrp, nameLog, nameHost, language, region, fnb,
+ encWx, encDk, encFile, 1
+ );
+ }
+#endif
+ dk4error_init(&er);
+ res = dk4fs_config_one(
+ fnb, szfnb, dk4wxpref_kw_dk[1], dirShare, dirEtc, dirHome,
+ nameApp, nameGrp, pn, 1, &er
+ );
+ if (0 != res) {
+ dk4wxpref_one_file(
+ spref, ipref, nameApp, nameGrp, nameLog, nameHost, language, region, fnb,
+ encWx, encDk, encFile, 0
+ );
+ }
+}
+
diff --git a/support/dktools/dk4wxpref.cpt b/support/dktools/dk4wxpref.cpt
new file mode 100644
index 0000000000..84b9a1e7d8
--- /dev/null
+++ b/support/dktools/dk4wxpref.cpt
@@ -0,0 +1,758 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk4wxpref.h Preferences as wxChar strings.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4CONST_H_INCLUDED
+#include "dk4const.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4STO_H_INCLUDED
+#include "dk4sto.h"
+#endif
+
+#ifndef DK4STRM_H_INCLUDED
+#include "dk4strm.h"
+#endif
+
+#ifndef DK4STRMR_H_INCLUDED
+#include "dk4strmr.h"
+#endif
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+
+/** Preferences data.
+*/
+typedef struct {
+ wxChar *name; /**< Name. */
+ wxChar *value; /**< Value. */
+} dk4_wx_pref_t;
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Create preferences structure, allocate memory.
+ @param name Preference name.
+ @param value Preference value.
+ @param erp Error report, may be NULL.
+ @return Pointer to new preferences object on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if name or value is NULL,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if a memory allocation failed due to insufficient memory.
+*/
+dk4_wx_pref_t *
+dk4wxpref_open(const wxChar *name, const wxChar *value, dk4_er_t *erp);
+
+/** Destroy preference structure, release memory.
+ @param ptr Preference structure to destroy.
+*/
+void
+dk4wxpref_close(dk4_wx_pref_t *ptr);
+
+/** Comparison function.
+ @param l Left pointer.
+ @param r Right pointer.
+ @param cr Comparison criteria:
+ 0=structure/structure,
+ 1=structure/name.
+ @return Comparison result.
+*/
+int
+dk4wxpref_compare(const void *l, const void *r, int cr);
+
+/** Add dk4pref.conf file for one pass.
+ @param spref Preferences storage.
+ @param ipref Iterator for preferences storage.
+ @param nameApp Application name.
+ @param nameGrp Application group name.
+ @param nameLog Users login name.
+ @param nameHost Host name.
+ @param language Language.
+ @param region Region.
+ @param dirHome Users home directory.
+ @param dirEtc System configuration directory.
+ @param dirShare Data file directory.
+ @param encWx Encoding for wxChar strings.
+ @param encDk Encoding for dkChar strings.
+ @param encFile Expected encoding for files.
+ @param pn Pass number.
+*/
+void
+dk4wxpref_one_pass(
+ dk4_sto_t *spref,
+ dk4_sto_it_t *ipref,
+ const dkChar *nameApp,
+ const dkChar *nameGrp,
+ const dkChar *nameLog,
+ const dkChar *nameHost,
+ const dkChar *language,
+ const dkChar *region,
+ const dkChar *dirHome,
+ const dkChar *dirEtc,
+ const dkChar *dirShare,
+ int encWx,
+ int encDk,
+ int encFile,
+ int pn
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk4wxpref.h"
+#include "dk4strd.h"
+#include "dk4strx.h"
+#include "dk4recwx.h"
+#include "dk4mem.h"
+#include "dk4mpl.h"
+#include "dk4tspdk.h"
+#include "dk4fs.h"
+
+
+
+$!trace-include
+
+
+
+/** Preference reading helper structure.
+*/
+typedef struct {
+ dk4_sto_t *spref; /**< Preference storage. */
+ dk4_sto_it_t *ipref; /**< Preferences iterator. */
+ const dkChar *nameApp; /**< Application name. */
+ const dkChar *nameGrp; /**< Application group name. */
+ const dkChar *nameLog; /**< Users login name. */
+ const dkChar *nameHost; /**< Host name. */
+ const dkChar *language; /**< Users language. */
+ const dkChar *region; /**< Users region. */
+ wxChar *wx1; /**< One wxChar buffer. */
+ wxChar *wx2; /**< Other wxChar buffer. */
+ size_t szwx; /**< Size of wxChar buffers. */
+ int encWx; /**< Encoding for wxChar. */
+ int encDk; /**< Encoding for dkChar. */
+ int compat; /**< Flag: Compatible mode. */
+ int insc; /**< Flag: In scope. */
+ int lasc; /**< Flag: Previous line was scope. */
+} dk4_wx_pref_rd_t;
+
+
+
+/** Constant keywords used by the module, not localized.
+*/
+static const dkChar * const dk4wxpref_kw_dk[] = {
+$!string-table macro=dkT
+#
+# 0 1 Configuration file names.
+#
+dk3pref.conf
+dk4pref.conf
+#
+# 2 Asterisk as wildcard matches all.
+#
+*
+$!end
+};
+
+
+
+/** Names for scope settings.
+*/
+static const dkChar * const dk4wxpref_scope_names[] = {
+$!string-table macro=dkT
+#
+# 0
+#
+user
+#
+# 1
+#
+application
+#
+# 2
+#
+application-group
+#
+# 3
+#
+host
+#
+# 4
+#
+windows
+#
+# 5
+#
+non-windows
+#
+# 6
+#
+language
+#
+# 7
+#
+region
+$!end
+};
+
+
+void
+dk4wxpref_close(dk4_wx_pref_t *ptr)
+{
+ if (NULL != ptr) {
+ dk4mem_release(ptr->name);
+ dk4mem_release(ptr->value);
+ dk4mem_free(ptr);
+ }
+}
+
+
+
+dk4_wx_pref_t *
+dk4wxpref_open(const wxChar *name, const wxChar *value, dk4_er_t *erp)
+{
+ dk4_wx_pref_t *back = NULL;
+ if ((NULL != name) && (NULL != value)) {
+ back = dk4mem_new(dk4_wx_pref_t,1,erp);
+ if (NULL != back) {
+ back->name = back->value = NULL;
+ back->name = dk4strx_dup(name, erp);
+ back->value = dk4strx_dup(value, erp);
+ if ((NULL == back->name) || (NULL == back->value)) {
+ dk4wxpref_close(back);
+ back = NULL;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MEMORY_ALLOCATION_FAILED);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_MEMORY_ALLOCATION_FAILED);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ return back;
+}
+
+
+
+int
+dk4wxpref_compare(const void *l, const void *r, int cr)
+{
+ const dk4_wx_pref_t *lptr;
+ const dk4_wx_pref_t *rptr;
+ int back = 0;
+ if (NULL != l) {
+ if (NULL != r) {
+ lptr = (const dk4_wx_pref_t *)l;
+ switch (cr) {
+ case 1: {
+ if (NULL != lptr->name) {
+ back = dk4strx_cmp(lptr->name, (const wxChar *)r);
+ } else back = -1;
+ } break;
+ default: {
+ rptr = (const dk4_wx_pref_t *)r;
+ if (NULL != lptr->name) {
+ if (NULL != rptr->name) {
+ back = dk4strx_cmp(lptr->name, rptr->name);
+ } else back = 1;
+ } else {
+ if (NULL != rptr->name) back = -1;
+ }
+ } break;
+ }
+ if (-1 > back) back = -1;
+ if ( 1 < back) back = 1;
+ } else back = 1;
+ } else {
+ if (NULL != r) back = -1;
+ }
+ return back;
+}
+
+
+
+#if DK4_HAVE_COMPATDKTOOLS3
+
+/** Modify version 3 preference names to version 4 names.
+ I.e. /a/b/c -> a.b.c
+ @param pstr String to modify.
+*/
+static
+void
+dk4wxpref_modify_compatible(dkChar *pstr)
+{
+ if (dkT('/') == *pstr) {
+ dk4str_cpy_to_left(pstr, &(pstr[1]));
+ }
+ while (dkT('\0') != *pstr) {
+ if (dkT('/') == *pstr) { *pstr = dkT('.'); }
+ pstr++;
+ }
+}
+
+#endif
+
+
+
+/** Test one scope entry.
+ @param rd Reader object.
+ @param scn Scope part name.
+ @return 1 if test succeeded, 0 otherwise.
+*/
+static
+int
+dk4wxpref_check_one_scope_entry(dk4_wx_pref_rd_t *rd, dkChar *scn)
+{
+ dkChar *scv = NULL;
+ int back = 1;
+ scn = dk4str_start(scn, NULL);
+ if (NULL != scn) {
+ scv = dk4str_chr(scn, dkT('='));
+ if (NULL != scv) {
+ *(scv++) = dkT('\0'); scv = dk4str_start(scv, NULL);
+ }
+ dk4str_normalize(scn, NULL);
+ if (NULL != scv) { dk4str_normalize(scv, NULL); }
+ back = 0;
+ switch (dk4str_array_index(dk4wxpref_scope_names, scn, 0)) {
+ case 0: { /* user */
+ if (NULL != scv) {
+ if (0 == dk4str_cmp(dk4wxpref_kw_dk[2], scv)) {
+ back = 1;
+ } else {
+ if (NULL != rd->nameLog) {
+#if DK4_HAVE_CASE_INSENSITIVE_USERNAMES
+ if (0 == dk4str_casecmp(rd->nameLog, scv))
+#else
+ if (0 == dk4str_cmp(rd->nameLog, scv))
+#endif
+ {
+ back = 1;
+ }
+ }
+ }
+ }
+ } break;
+ case 1: { /* application */
+ if (NULL != scv) {
+ if (0 == dk4str_cmp(dk4wxpref_kw_dk[2], scv)) {
+ back = 1;
+ } else {
+ if (NULL != rd->nameApp) {
+ if (0 == dk4str_cmp(rd->nameApp, scv)) {
+ back = 1;
+ }
+ }
+ }
+ }
+ } break;
+ case 2: { /* application group */
+ if (NULL != scv) {
+ if (0 == dk4str_cmp(dk4wxpref_kw_dk[2], scv)) {
+ back = 1;
+ } else {
+ if (NULL != rd->nameGrp) {
+ if (0 == dk4str_cmp(rd->nameGrp, scv)) {
+ back = 1;
+ }
+ }
+ }
+ }
+ } break;
+ case 3: { /* host */
+ if (NULL != scv) {
+ if (0 == dk4str_cmp(dk4wxpref_kw_dk[2], scv)) {
+ back = 1;
+ } else {
+ if (NULL != rd->nameHost) {
+ if (0 == dk4str_casecmp(rd->nameHost, scv)) {
+ back = 1;
+ }
+ }
+ }
+ }
+ } break;
+ case 4: { /* windows */
+ if (NULL != scv) {
+ if (0 != dk4str_is_on(scv)) {
+#if DK4_ON_WINDOWS
+ back = 1;
+#endif
+ } else {
+#if !(DK4_ON_WINDOWS)
+ back = 1;
+#endif
+ }
+ } else {
+#if DK4_ON_WINDOWS
+ back = 1;
+#endif
+ }
+ } break;
+ case 5: { /* non-windows */
+ if (NULL != scv) {
+ if (0 != dk4str_is_on(scv)) {
+#if !(DK4_ON_WINDOWS)
+ back = 1;
+#endif
+ } else {
+#if DK4_ON_WINDOWS
+ back = 1;
+#endif
+ }
+ } else {
+#if !(DK4_ON_WINDOWS)
+ back = 1;
+#endif
+ }
+ } break;
+ case 6: { /* language */
+ if (NULL != scv) {
+ if (0 == dk4str_cmp(dk4wxpref_kw_dk[2], scv)) {
+ back = 1;
+ } else {
+ if (NULL != rd->language) {
+ if (0 == dk4str_casecmp(rd->language, scv)) {
+ back = 1;
+ }
+ }
+ }
+ }
+ } break;
+ case 7: { /* region */
+ if (NULL != scv) {
+ if (0 == dk4str_cmp(dk4wxpref_kw_dk[2], scv)) {
+ back = 1;
+ } else {
+ if (NULL != rd->region) {
+ if (0 == dk4str_casecmp(rd->region, scv)) {
+ back = 1;
+ }
+ }
+ }
+ }
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+/** Process one input line.
+ @param obj Preferences reader object.
+ @param line Current line to process.
+ @param lineno Line number.
+ @param erp Error report, may be NULL.
+ @return
+ DK4_TSP_RES_OK if processing succeeded,
+ DK4_TSP_RES_ERROR on errors (can continue),
+ DK4_TSP_RES_FATAL on fatal errors (can not continue).
+
+*/
+static
+int
+dk4wxpref_line_handler(
+ void *obj,
+ dkChar *line,
+ dk4_um_t lineno,
+ dk4_er_t *erp
+)
+{
+ dk4_wx_pref_rd_t *rd; /* Reader object */
+ dk4_wx_pref_t *pptr; /* New pref */
+ dkChar *p1; /* Pref name */
+ dkChar *p2; /* Pref value */
+ wxChar *nv; /* New value */
+ int isneg; /* Flag: Not in scope */
+ int ok; /* Flag: Tests passed */
+ int res; /* Operation result */
+ int back = DK4_TSP_RES_OK; /* Function result */
+
+ rd = (dk4_wx_pref_rd_t *)obj;
+ dk4str_delnl(line);
+ p1 = dk4str_start(line, NULL);
+ if (NULL != p1) {
+ if (dkT('#') != *p1) {
+ if (dkT('[') == *p1) { $? ". scope line"
+ if (0 == rd->lasc) {
+ rd->insc = 0;
+ }
+ p2 = dk4str_chr(p1, dkT(']'));
+ if (NULL != p2) { *p2 = dkT('\0'); }
+ p1++;
+ if (dkT('-') == *p1) {
+ isneg = 1;
+ p1++;
+ } else {
+ isneg = 0;
+ }
+ ok = 1;
+ while (NULL != p1) {
+ p2 = dk4str_chr(p1, dkT(','));
+ if (NULL != p2) {
+ *(p2++) = dkT('\0'); p2 = dk4str_start(p2, NULL);
+ }
+ if (0 == dk4wxpref_check_one_scope_entry(rd, p1)) { ok = 0; }
+ p1 = p2;
+ }
+ if (1 == ok) {
+ if (0 != isneg) { rd->insc = 0; } else { rd->insc = 1; }
+ }
+ rd->lasc = 1;
+ } else { $? ". data line"
+ if (rd->insc) {
+ p2 = dk4str_chr(p1, dkT('='));
+ if (NULL != p2) {
+ *(p2++) = dkT('\0');
+ p2 = dk4str_start(p2, NULL);
+ }
+ if ((NULL != p1) && (NULL != p2)) {
+ dk4str_normalize(p1, NULL);
+ dk4str_rtwh(p2, NULL);
+#if DK4_HAVE_COMPATDKTOOLS3
+ if (0 != rd->compat) {
+ dk4wxpref_modify_compatible(p1);
+ }
+#endif
+ res = dk4recwx_dkchar_to_wxchar(
+ rd->wx1, rd->szwx, rd->encWx, p1, rd->encDk, NULL
+ );
+ if (0 < res) {
+ res = dk4recwx_dkchar_to_wxchar(
+ rd->wx2, rd->szwx, rd->encWx, p2, rd->encDk, NULL
+ );
+ if (0 < res) {
+ pptr = (dk4_wx_pref_t *)dk4sto_it_find_like(
+ rd->ipref, rd->wx1, 1
+ );
+ if (NULL != pptr) {
+ nv = dk4strx_dup(rd->wx2, NULL);
+ if (NULL != nv) {
+ dk4mem_release(pptr->value);
+ pptr->value = nv;
+ }
+ } else {
+ pptr = dk4wxpref_open(rd->wx1, rd->wx2, NULL);
+ if (NULL != pptr) {
+ if (0 == dk4sto_add(rd->spref, pptr, NULL)) {
+ dk4wxpref_close(pptr);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ rd->lasc = 0;
+ }
+ } else { $? ". comment line"
+ }
+ } else { $? ". empty line"
+ }
+ return back;
+}
+
+
+
+
+/** Use one file.
+ @param spref Preferences storage.
+ @param ipref Iterator for preferences storage.
+ @param nameApp Application name.
+ @param nameGrp Application group name.
+ @param nameLog Users login name.
+ @param nameHost Host name.
+ @param language Language.
+ @param region Region.
+ @param fn File name.
+ @param encWx Encoding for wxChar strings.
+ @param encDk Encoding for dkChar strings.
+ @param encFile Expected encoding for files.
+ @param compat Flag: In compatibility mode.
+*/
+static
+void
+dk4wxpref_one_file(
+ dk4_sto_t *spref,
+ dk4_sto_it_t *ipref,
+ const dkChar *nameApp,
+ const dkChar *nameGrp,
+ const dkChar *nameLog,
+ const dkChar *nameHost,
+ const dkChar *language,
+ const dkChar *region,
+ const dkChar *fn,
+ int encWx,
+ int encDk,
+ int encFile,
+ int compat
+)
+{
+ char ib[4096]; /* Input buffer for stream read */
+ wxChar wx1[1024]; /* Buffer for conversion */
+ wxChar wx2[DK4_SIZEOF(wx1,wxChar)]; /* too */
+ dkChar il[1024]; /* Input line */
+ dk4_wx_pref_rd_t rd; /* Reader object */
+ dk4_er_t er; /* Error report */
+ dk4_tspdk_t tsp; /* Text stream processing */
+ dk4_stream_t *istrm; /* Input stream */
+ size_t szil = DK4_SIZEOF(il,dkChar); /* Buffer size */
+ size_t szwx = DK4_SIZEOF(wx1,wxChar); /* Buffer size */
+ size_t rb; /* Bytes read */
+ int res; /* Operation result */
+ int cc; /* Flag: Can continue */
+
+ dk4error_init(&er);
+ istrm = dk4stream_open_file_reader(fn, &er);
+ if (NULL != istrm) {
+ rd.spref = spref; rd.ipref = ipref;
+ rd.nameApp = nameApp; rd.nameGrp = nameGrp; rd.nameLog = nameLog;
+ rd.nameHost = nameHost;
+ rd.language = language; rd.region = region; rd.compat = compat;
+ rd.encWx = encWx; rd.encDk = encDk;
+ rd.insc = 1; rd.lasc = 0;
+ rd.wx1 = wx1; rd.wx2 = wx2; rd.szwx = szwx;
+ res = dk4tspdk_setup_line(
+ &tsp, &rd,
+ (dk4_dk_line_handler_t *)dk4wxpref_line_handler,
+ il, szil, encDk, encFile, &er
+ );
+ if (0 != res) {
+ cc = 1;
+ while (1 == cc) {
+ cc = 0;
+ rb = sizeof(ib);
+ if (0 != dk4stream_read(ib, &rb, istrm, &er)) {
+ if (0 < rb) {
+ cc = 1;
+ res = dk4tspdk_add_bytes(&tsp, (const unsigned char *)ib, rb);
+ if (DK4_TSP_RES_FATAL == res) {
+ cc = -1;
+ }
+ }
+ }
+ }
+ if (0 == cc) {
+#if VERSION_BEFORE_20150821
+ res = dk4tspdk_finish(&tsp);
+#else
+ (void)dk4tspdk_finish(&tsp);
+#endif
+ }
+ }
+ dk4stream_close(istrm, NULL);
+ }
+}
+
+
+
+void
+dk4wxpref_one_pass(
+ dk4_sto_t *spref,
+ dk4_sto_it_t *ipref,
+ const dkChar *nameApp,
+ const dkChar *nameGrp,
+ const dkChar *nameLog,
+ const dkChar *nameHost,
+ const dkChar *language,
+ const dkChar *region,
+ const dkChar *dirHome,
+ const dkChar *dirEtc,
+ const dkChar *dirShare,
+ int encWx,
+ int encDk,
+ int encFile,
+ int pn
+)
+{
+ dkChar fnb[DK4_MAX_PATH];
+ dk4_er_t er;
+ size_t szfnb = DK4_SIZEOF(fnb,dkChar);
+ int res;
+
+#if DK4_HAVE_COMPATDKTOOLS3
+ dk4error_init(&er);
+ res = dk4fs_config_compat_one(
+ fnb, szfnb, dk4wxpref_kw_dk[0], dirShare, dirEtc, dirHome,
+ nameApp, nameGrp, pn, 1, 1, &er
+ );
+ if (0 != res) {
+ dk4wxpref_one_file(
+ spref, ipref, nameApp, nameGrp, nameLog, nameHost, language, region, fnb,
+ encWx, encDk, encFile, 1
+ );
+ }
+#endif
+ dk4error_init(&er);
+ res = dk4fs_config_one(
+ fnb, szfnb, dk4wxpref_kw_dk[1], dirShare, dirEtc, dirHome,
+ nameApp, nameGrp, pn, 1, &er
+ );
+ if (0 != res) {
+ dk4wxpref_one_file(
+ spref, ipref, nameApp, nameGrp, nameLog, nameHost, language, region, fnb,
+ encWx, encDk, encFile, 0
+ );
+ }
+}
+
diff --git a/support/dktools/dk4wxpref.h b/support/dktools/dk4wxpref.h
new file mode 100644
index 0000000000..4f777ee7c9
--- /dev/null
+++ b/support/dktools/dk4wxpref.h
@@ -0,0 +1,192 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4wxpref.cpt
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4WXPREF_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4WXPREF_H_INCLUDED 1
+
+
+#line 10 "dk4wxpref.cpt"
+
+/** @file dk4wxpref.h Preferences as wxChar strings.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4CONST_H_INCLUDED
+#include "dk4const.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4STO_H_INCLUDED
+#include "dk4sto.h"
+#endif
+
+#ifndef DK4STRM_H_INCLUDED
+#include "dk4strm.h"
+#endif
+
+#ifndef DK4STRMR_H_INCLUDED
+#include "dk4strmr.h"
+#endif
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+
+/** Preferences data.
+*/
+typedef struct {
+ wxChar *name; /**< Name. */
+ wxChar *value; /**< Value. */
+} dk4_wx_pref_t;
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Create preferences structure, allocate memory.
+ @param name Preference name.
+ @param value Preference value.
+ @param erp Error report, may be NULL.
+ @return Pointer to new preferences object on success, NULL on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if name or value is NULL,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if a memory allocation failed due to insufficient memory.
+*/
+dk4_wx_pref_t *
+dk4wxpref_open(const wxChar *name, const wxChar *value, dk4_er_t *erp);
+
+/** Destroy preference structure, release memory.
+ @param ptr Preference structure to destroy.
+*/
+void
+dk4wxpref_close(dk4_wx_pref_t *ptr);
+
+/** Comparison function.
+ @param l Left pointer.
+ @param r Right pointer.
+ @param cr Comparison criteria:
+ 0=structure/structure,
+ 1=structure/name.
+ @return Comparison result.
+*/
+int
+dk4wxpref_compare(const void *l, const void *r, int cr);
+
+/** Add dk4pref.conf file for one pass.
+ @param spref Preferences storage.
+ @param ipref Iterator for preferences storage.
+ @param nameApp Application name.
+ @param nameGrp Application group name.
+ @param nameLog Users login name.
+ @param nameHost Host name.
+ @param language Language.
+ @param region Region.
+ @param dirHome Users home directory.
+ @param dirEtc System configuration directory.
+ @param dirShare Data file directory.
+ @param encWx Encoding for wxChar strings.
+ @param encDk Encoding for dkChar strings.
+ @param encFile Expected encoding for files.
+ @param pn Pass number.
+*/
+void
+dk4wxpref_one_pass(
+ dk4_sto_t *spref,
+ dk4_sto_it_t *ipref,
+ const dkChar *nameApp,
+ const dkChar *nameGrp,
+ const dkChar *nameLog,
+ const dkChar *nameHost,
+ const dkChar *language,
+ const dkChar *region,
+ const dkChar *dirHome,
+ const dkChar *dirEtc,
+ const dkChar *dirShare,
+ int encWx,
+ int encDk,
+ int encFile,
+ int pn
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dk4wxstt.cpp b/support/dktools/dk4wxstt.cpp
new file mode 100644
index 0000000000..ecca665f24
--- /dev/null
+++ b/support/dktools/dk4wxstt.cpp
@@ -0,0 +1,426 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4wxstt.cpt
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dk4wxstt.cpp The dk4wxstt module.
+*/
+
+
+#line 146 "dk4wxstt.cpt"
+
+
+
+#include "dk4mem.h"
+#include "dk4enc.h"
+#include "dk4strd.h"
+#include "dk4wxtypes.h"
+#include "dk4strx.h"
+#include "dk4wxstt.h"
+#include "dk4tspwx.h"
+
+
+
+
+
+#line 160 "dk4wxstt.cpt"
+
+
+
+void
+dk4wxstt_shutdown(dk4_wx_string_table_t *ptr)
+{
+ wxChar **stptr;
+ size_t nstrings;
+
+
+#line 169 "dk4wxstt.cpt"
+ if (NULL != ptr) {
+
+#line 170 "dk4wxstt.cpt"
+ if (NULL != ptr->strings) {
+
+#line 171 "dk4wxstt.cpt"
+ stptr = ptr->strings;
+ nstrings = ptr->nstrings;
+ while (0 < nstrings--) {
+
+#line 174 "dk4wxstt.cpt"
+ dk4mem_release(*stptr);
+ stptr++;
+ }
+
+#line 177 "dk4wxstt.cpt"
+ dk4mem_release(ptr->strings);
+ }
+ }
+
+
+#line 181 "dk4wxstt.cpt"
+}
+
+
+void
+dk4wxstt_close(dk4_wx_string_table_t *ptr)
+{
+
+
+#line 188 "dk4wxstt.cpt"
+ if (NULL != ptr) {
+
+#line 189 "dk4wxstt.cpt"
+ dk4wxstt_shutdown(ptr);
+
+#line 190 "dk4wxstt.cpt"
+ dk4mem_release(ptr->shrtfn);
+ ptr->nstrings = 0;
+
+#line 192 "dk4wxstt.cpt"
+ dk4mem_free(ptr);
+ }
+
+
+#line 195 "dk4wxstt.cpt"
+}
+
+
+
+dk4_wx_string_table_t *
+dk4wxstt_open(const dkChar *fn, size_t sz, dk4_er_t *erp)
+{
+ dk4_wx_string_table_t *back = NULL;
+ wxChar **stptr = NULL;
+ int ok = 0;
+
+
+#line 206 "dk4wxstt.cpt"
+ if ((NULL != fn) && (0 < sz)) {
+
+#line 207 "dk4wxstt.cpt"
+ back = dk4mem_new(dk4_wx_string_table_t,1,erp);
+ if (NULL != back) {
+
+#line 209 "dk4wxstt.cpt"
+ back->strings = NULL;
+ back->nstrings = 0;
+ back->shrtfn = dk4str_dup(fn, erp);
+ if (NULL != back->shrtfn) {
+
+#line 213 "dk4wxstt.cpt"
+ back->nstrings = sz;
+ back->strings = dk4mem_new(DK4_PWXCHAR,sz,erp);
+ if (NULL != back->strings) {
+
+#line 216 "dk4wxstt.cpt"
+ stptr = back->strings;
+ while (0 < sz--) { *(stptr++) = NULL; }
+ ok = 1;
+ }
+ }
+ if (1 > ok) {
+
+#line 222 "dk4wxstt.cpt"
+ dk4wxstt_close(back);
+ back = NULL;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 230 "dk4wxstt.cpt"
+ return back;
+}
+
+
+
+int
+dk4wxstt_compare(const void *l, const void *r, int cr)
+{
+ const dk4_wx_string_table_t *lptr;
+ const dk4_wx_string_table_t *rptr;
+ int back = 0;
+ if (NULL != l) {
+ if (NULL != r) {
+ lptr = (const dk4_wx_string_table_t *)l;
+ switch (cr) {
+ case 1: {
+ if (NULL != lptr->shrtfn) {
+ back = dk4str_pathcmp(lptr->shrtfn, (const dkChar *)r);
+ } else {
+ back = -1;
+ }
+ } break;
+ default : {
+ rptr = (const dk4_wx_string_table_t *)r;
+ if (NULL != lptr->shrtfn) {
+ if (NULL != rptr->shrtfn) {
+ back = dk4str_pathcmp(lptr->shrtfn, rptr->shrtfn);
+ } else { back = 1; }
+ } else {
+ if (NULL != rptr->shrtfn) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if (NULL != r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+/** Support structure for reading string table from stream.
+*/
+typedef struct {
+ dk4_wx_string_table_t *dptr; /**< String table to set up. */
+ size_t curpos; /**< Current string number. */
+} dk4_wx_string_table_reader_t;
+
+
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR > 2
+#define TO_SIZED_CHAR(x) ((dk4_c32_t)(x))
+#else
+#define TO_SIZED_CHAR(x) ((dk4_c16_t)(x))
+#endif
+#else
+#define TO_SIZED_CHAR(x) ((char)(x))
+#endif
+
+/** Handler function for text lines.
+ @param obj Object to modify while processing the character.
+ @param line Text line to process.
+ @param lineno Current line number.
+ @param erp Error report, may be NULL.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+dk4wxstt_line_handler(
+ void *obj,
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR > 2
+ dk4_c32_t *line,
+#else
+ dk4_c16_t *line,
+#endif
+#else
+ char *line,
+#endif
+ dk4_um_t lineno,
+ dk4_er_t *erp
+)
+{
+ dk4_wx_string_table_reader_t *reader;
+ wxChar *linecp;
+ int back = DK4_TSP_RES_ERROR;
+
+
+#line 324 "dk4wxstt.cpt"
+ reader = (dk4_wx_string_table_reader_t *)obj;
+ if (wxT('#') != (wxChar)(*line)) {
+
+#line 326 "dk4wxstt.cpt"
+ if (reader->curpos < reader->dptr->nstrings) {
+
+#line 327 "dk4wxstt.cpt"
+ linecp = dk4strx_dup((wxChar *)line, NULL);
+ if (NULL != linecp) {
+ (reader->dptr->strings)[reader->curpos] = linecp;
+ reader->curpos += 1;
+ back = DK4_TSP_RES_OK;
+ while (wxT('\0') != (wxChar)(*linecp)) {
+ if (wxT('\\') == (wxChar)(*linecp)) {
+ if (wxT('r') == (wxChar)(linecp[1])) {
+ *linecp = TO_SIZED_CHAR(wxT('\r'));
+ dk4strx_cpy_to_left(
+ (wxChar *)(&(linecp[1])), (wxChar *)(&(linecp[2]))
+ );
+ } else {
+ if (wxT('n') == wxChar(linecp[1])) {
+ *linecp = TO_SIZED_CHAR(wxT('\n'));
+ dk4strx_cpy_to_left(
+ (wxChar *)(&(linecp[1])), (wxChar *)(&(linecp[2]))
+ );
+ } else {
+ if (wxT('t') == (wxChar)(linecp[1])) {
+ *linecp = TO_SIZED_CHAR(wxT('\t'));
+ dk4strx_cpy_to_left(
+ (wxChar *)(&(linecp[1])), (wxChar *)(&(linecp[2]))
+ );
+ } else {
+ dk4strx_cpy_to_left(
+ (wxChar *)(linecp), (wxChar *)(&(linecp[1]))
+ );
+ if (wxT('\0') == (wxChar)(*linecp)) { linecp--; }
+ }
+ }
+ }
+ } else {
+ if (wxT('\n') == (wxChar)(*linecp)) {
+ *linecp = TO_SIZED_CHAR(wxT('\0'));
+ linecp--;
+ } else {
+ if ((wxT('\r') == (wxChar)(*linecp))
+ && (wxT('\n') == (wxChar)(linecp[1])))
+ {
+ *linecp = TO_SIZED_CHAR(wxT('\0'));
+ linecp--;
+ }
+ }
+ }
+ linecp++;
+ }
+ } else {
+ back = DK4_TSP_RES_FATAL;
+ }
+ } else {
+
+#line 378 "dk4wxstt.cpt"
+ back = DK4_TSP_RES_OK;
+ }
+ } else {
+ back = DK4_TSP_RES_OK;
+ }
+
+#line 383 "dk4wxstt.cpt"
+ return back;
+}
+
+
+
+bool
+dk4wxstt_apply_stream(
+ dk4_wx_string_table_t *tptr,
+ dk4_stream_t *strm,
+ int pre,
+ dk4_er_t *erp1,
+ dk4_er_t *erp2
+)
+{
+ wxChar line[1024]; /* Line buffer */
+ char buf[4096]; /* Input bytes from stream */
+ dk4_wx_string_table_reader_t reader; /* Reader structure */
+ dk4_tspwx_t tspwx; /* Text stream processor */
+ dk4_er_t e1; /* Error report decoding */
+ dk4_er_t e2; /* Error report processing */
+ size_t rdb; /* Number of bytes read */
+ int cc; /* Flag: Can continue */
+ bool back = false; /* Function result */
+
+
+#line 407 "dk4wxstt.cpt"
+ if ((NULL != tptr) && (NULL != strm)) {
+
+#line 408 "dk4wxstt.cpt"
+ dk4error_init(&e1);
+ dk4error_init(&e2);
+ reader.dptr = tptr;
+ reader.curpos = 0;
+ cc = dk4tspwx_setup_line(
+ &tspwx, (void *)(&reader), dk4wxstt_line_handler,
+ line, DK4_SIZEOF(line,wxChar),
+ pre, DK4_FILE_ENCODING_UTF8, &e2
+ ); back = ((cc != 0) ? true : false);
+ if (back) {
+
+#line 418 "dk4wxstt.cpt"
+#if VERSION_BEFORE_20150821
+ cc = 1;
+#endif
+ do {
+ cc = 0;
+ rdb = sizeof(buf);
+ if (0 < dk4stream_read(buf, &rdb, strm, NULL)) {
+ if (0 < rdb) {
+
+#line 426 "dk4wxstt.cpt"
+ switch (dk4tspwx_add_bytes(&tspwx, (unsigned char *)buf, rdb)) {
+ case DK4_TSP_RES_OK: {
+ cc = 1;
+
+#line 429 "dk4wxstt.cpt"
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ cc = 1;
+
+#line 432 "dk4wxstt.cpt"
+ } break;
+ default: {
+ back = false;
+
+#line 435 "dk4wxstt.cpt"
+ } break;
+ }
+ }
+ }
+ } while (0 != cc);
+ if (back) {
+
+#line 441 "dk4wxstt.cpt"
+ if (DK4_TSP_RES_FATAL == dk4tspwx_finish(&tspwx)) {
+ back = false;
+
+#line 443 "dk4wxstt.cpt"
+ }
+ if (back) {
+ if (reader.curpos < (reader.dptr)->nstrings) {
+ back = false;
+
+#line 447 "dk4wxstt.cpt"
+ }
+ }
+ }
+ } else {
+
+#line 451 "dk4wxstt.cpt"
+ }
+ } else {
+ dk4error_set_simple_error_code(erp2, DK4_E_INVALID_ARGUMENTS);
+ }
+
+
+#line 456 "dk4wxstt.cpt"
+ return back;
+}
+
+
diff --git a/support/dktools/dk4wxstt.cpt b/support/dktools/dk4wxstt.cpt
new file mode 100644
index 0000000000..c1ca226365
--- /dev/null
+++ b/support/dktools/dk4wxstt.cpt
@@ -0,0 +1,459 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file dk4wxstt.h String tables for wxChars.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4STRM_H_INCLUDED
+#include "dk4strm.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4WXCS_H_INCLUDED
+#include "dk4wxcs.h"
+#endif
+
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+
+/** String table for wxChar strings.
+*/
+typedef struct {
+ dkChar *shrtfn; /**< Short file name. */
+ wxChar **strings; /**< Strings read from file. */
+ size_t nstrings; /**< Number of strings. */
+} dk4_wx_string_table_t;
+
+
+extern "C" {
+
+/** Create string table from file.
+ @param fn Short file name to store in structure.
+ @param sz Number of lines required.
+ @param erp Error report, may be NULL.
+ @return Pointer to new string table structure on success, NULL
+ on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL or sz is 0,
+ - DK4_E_MATH_OVERFLOW<br>
+ if there was a numeric overflow in size calculations for
+ dynamic memory allocations,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if there is not enough memory available.
+*/
+dk4_wx_string_table_t *
+dk4wxstt_open(const dkChar *fn, size_t sz, dk4_er_t *erp);
+
+/** Apply a text stream to a string table.
+ @param tptr String table to configure.
+ @param strm Text stream, opened for reading.
+ @param pre Processing encoding.
+ @param erp1 Error report for decoding/encoding, may be NULL.
+ @param erp2 Error report for processing, may be NULL.
+ @return True on success, false on error.
+
+ Error codes erp1:
+
+ Error codes erp2:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if tptr or strm is NULL
+*/
+bool
+dk4wxstt_apply_stream(
+ dk4_wx_string_table_t *tptr,
+ dk4_stream_t *strm,
+ int pre,
+ dk4_er_t *erp1,
+ dk4_er_t *erp2
+);
+
+/** Destroy a string table, free allocated memory.
+ @param ptr String table to destroy.
+*/
+void
+dk4wxstt_close(dk4_wx_string_table_t *ptr);
+
+/** Mark string table as empty.
+ Release memory for the strings.
+ @param ptr String table to shut down.
+*/
+void
+dk4wxstt_shutdown(dk4_wx_string_table_t *ptr);
+
+/** Compare two string tables by short name.
+ @param l Left pointer (always string table).
+ @param r Right pointer (string table or short name).
+ @param cr Comparison criteria
+ (0=string table/string table,
+ 1=string table/short name).
+ @return Comparison result.
+*/
+int
+dk4wxstt_compare(const void *l, const void *r, int cr);
+
+}
+
+
+%% module
+
+
+
+#include "dk4mem.h"
+#include "dk4enc.h"
+#include "dk4strd.h"
+#include "dk4wxtypes.h"
+#include "dk4strx.h"
+#include "dk4wxstt.h"
+#include "dk4tspwx.h"
+
+
+
+$!trace-include
+
+
+
+void
+dk4wxstt_shutdown(dk4_wx_string_table_t *ptr)
+{
+ wxChar **stptr;
+ size_t nstrings;
+ $? "+ dk4wxstt_shutdown"
+ if (NULL != ptr) { $? ". arg ok"
+ if (NULL != ptr->strings) { $? ". strings ok"
+ stptr = ptr->strings;
+ nstrings = ptr->nstrings;
+ while (0 < nstrings--) { $? ". release one string"
+ dk4mem_release(*stptr);
+ stptr++;
+ } $? ". release array pointer"
+ dk4mem_release(ptr->strings);
+ }
+ }
+ $? "- dk4wxstt_shutdown"
+}
+
+
+void
+dk4wxstt_close(dk4_wx_string_table_t *ptr)
+{
+ $? "+ dk4wxstt_close"
+ if (NULL != ptr) { $? ". arg ok"
+ dk4wxstt_shutdown(ptr); $? ". release short file name"
+ dk4mem_release(ptr->shrtfn);
+ ptr->nstrings = 0; $? ". release string table"
+ dk4mem_free(ptr);
+ }
+ $? "- dk4wxstt_close"
+}
+
+
+
+dk4_wx_string_table_t *
+dk4wxstt_open(const dkChar *fn, size_t sz, dk4_er_t *erp)
+{
+ dk4_wx_string_table_t *back = NULL;
+ wxChar **stptr = NULL;
+ int ok = 0;
+ $? "+ dk4wxstt_open"
+ if ((NULL != fn) && (0 < sz)) { $? ". fn, sz ok"
+ back = dk4mem_new(dk4_wx_string_table_t,1,erp);
+ if (NULL != back) { $? ". allocated"
+ back->strings = NULL;
+ back->nstrings = 0;
+ back->shrtfn = dk4str_dup(fn, erp);
+ if (NULL != back->shrtfn) { $? ". short file name"
+ back->nstrings = sz;
+ back->strings = dk4mem_new(DK4_PWXCHAR,sz,erp);
+ if (NULL != back->strings) { $? ". array"
+ stptr = back->strings;
+ while (0 < sz--) { *(stptr++) = NULL; }
+ ok = 1;
+ }
+ }
+ if (1 > ok) { $? "! incomplete"
+ dk4wxstt_close(back);
+ back = NULL;
+ }
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4wxstt_open %d", ((NULL != back) ? 1 : 0)
+ return back;
+}
+
+
+
+int
+dk4wxstt_compare(const void *l, const void *r, int cr)
+{
+ const dk4_wx_string_table_t *lptr;
+ const dk4_wx_string_table_t *rptr;
+ int back = 0;
+ if (NULL != l) {
+ if (NULL != r) {
+ lptr = (const dk4_wx_string_table_t *)l;
+ switch (cr) {
+ case 1: {
+ if (NULL != lptr->shrtfn) {
+ back = dk4str_pathcmp(lptr->shrtfn, (const dkChar *)r);
+ } else {
+ back = -1;
+ }
+ } break;
+ default : {
+ rptr = (const dk4_wx_string_table_t *)r;
+ if (NULL != lptr->shrtfn) {
+ if (NULL != rptr->shrtfn) {
+ back = dk4str_pathcmp(lptr->shrtfn, rptr->shrtfn);
+ } else { back = 1; }
+ } else {
+ if (NULL != rptr->shrtfn) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if (NULL != r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+/** Support structure for reading string table from stream.
+*/
+typedef struct {
+ dk4_wx_string_table_t *dptr; /**< String table to set up. */
+ size_t curpos; /**< Current string number. */
+} dk4_wx_string_table_reader_t;
+
+
+
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR > 2
+#define TO_SIZED_CHAR(x) ((dk4_c32_t)(x))
+#else
+#define TO_SIZED_CHAR(x) ((dk4_c16_t)(x))
+#endif
+#else
+#define TO_SIZED_CHAR(x) ((char)(x))
+#endif
+
+/** Handler function for text lines.
+ @param obj Object to modify while processing the character.
+ @param line Text line to process.
+ @param lineno Current line number.
+ @param erp Error report, may be NULL.
+ @return DK4_TSP_RES_OK if the character was processed
+ successfully,
+ DK4_TSP_RES_ERROR if there was an error but we can
+ continue,
+ DK4_TSP_RES_FATAL if there was a fatal error so we
+ should abort processing.
+*/
+static
+int
+dk4wxstt_line_handler(
+ void *obj,
+#if DK4_SIZEOF_WXCHAR > 1
+#if DK4_SIZEOF_WXCHAR > 2
+ dk4_c32_t *line,
+#else
+ dk4_c16_t *line,
+#endif
+#else
+ char *line,
+#endif
+ dk4_um_t lineno,
+ dk4_er_t *erp
+)
+{
+ dk4_wx_string_table_reader_t *reader;
+ wxChar *linecp;
+ int back = DK4_TSP_RES_ERROR;
+ $? "+ dk4wxstt_line_handler"
+ reader = (dk4_wx_string_table_reader_t *)obj;
+ if (wxT('#') != (wxChar)(*line)) { $? ". non-comment"
+ if (reader->curpos < reader->dptr->nstrings) { $? ". save line"
+ linecp = dk4strx_dup((wxChar *)line, NULL);
+ if (NULL != linecp) {
+ (reader->dptr->strings)[reader->curpos] = linecp;
+ reader->curpos += 1;
+ back = DK4_TSP_RES_OK;
+ while (wxT('\0') != (wxChar)(*linecp)) {
+ if (wxT('\\') == (wxChar)(*linecp)) {
+ if (wxT('r') == (wxChar)(linecp[1])) {
+ *linecp = TO_SIZED_CHAR(wxT('\r'));
+ dk4strx_cpy_to_left(
+ (wxChar *)(&(linecp[1])), (wxChar *)(&(linecp[2]))
+ );
+ } else {
+ if (wxT('n') == wxChar(linecp[1])) {
+ *linecp = TO_SIZED_CHAR(wxT('\n'));
+ dk4strx_cpy_to_left(
+ (wxChar *)(&(linecp[1])), (wxChar *)(&(linecp[2]))
+ );
+ } else {
+ if (wxT('t') == (wxChar)(linecp[1])) {
+ *linecp = TO_SIZED_CHAR(wxT('\t'));
+ dk4strx_cpy_to_left(
+ (wxChar *)(&(linecp[1])), (wxChar *)(&(linecp[2]))
+ );
+ } else {
+ dk4strx_cpy_to_left(
+ (wxChar *)(linecp), (wxChar *)(&(linecp[1]))
+ );
+ if (wxT('\0') == (wxChar)(*linecp)) { linecp--; }
+ }
+ }
+ }
+ } else {
+ if (wxT('\n') == (wxChar)(*linecp)) {
+ *linecp = TO_SIZED_CHAR(wxT('\0'));
+ linecp--;
+ } else {
+ if ((wxT('\r') == (wxChar)(*linecp))
+ && (wxT('\n') == (wxChar)(linecp[1])))
+ {
+ *linecp = TO_SIZED_CHAR(wxT('\0'));
+ linecp--;
+ }
+ }
+ }
+ linecp++;
+ }
+ } else {
+ back = DK4_TSP_RES_FATAL;
+ }
+ } else { $? ". line out of range"
+ back = DK4_TSP_RES_OK;
+ }
+ } else {
+ back = DK4_TSP_RES_OK;
+ } $? "- dk4wxstt_line_handler %d", back
+ return back;
+}
+
+
+
+bool
+dk4wxstt_apply_stream(
+ dk4_wx_string_table_t *tptr,
+ dk4_stream_t *strm,
+ int pre,
+ dk4_er_t *erp1,
+ dk4_er_t *erp2
+)
+{
+ wxChar line[1024]; /* Line buffer */
+ char buf[4096]; /* Input bytes from stream */
+ dk4_wx_string_table_reader_t reader; /* Reader structure */
+ dk4_tspwx_t tspwx; /* Text stream processor */
+ dk4_er_t e1; /* Error report decoding */
+ dk4_er_t e2; /* Error report processing */
+ size_t rdb; /* Number of bytes read */
+ int cc; /* Flag: Can continue */
+ bool back = false; /* Function result */
+ $? "+ dk4wxstt_apply_stream"
+ if ((NULL != tptr) && (NULL != strm)) { $? ". args ok"
+ dk4error_init(&e1);
+ dk4error_init(&e2);
+ reader.dptr = tptr;
+ reader.curpos = 0;
+ cc = dk4tspwx_setup_line(
+ &tspwx, (void *)(&reader), dk4wxstt_line_handler,
+ line, DK4_SIZEOF(line,wxChar),
+ pre, DK4_FILE_ENCODING_UTF8, &e2
+ ); back = ((cc != 0) ? true : false);
+ if (back) { $? ". tsp setup ok"
+#if VERSION_BEFORE_20150821
+ cc = 1;
+#endif
+ do {
+ cc = 0;
+ rdb = sizeof(buf);
+ if (0 < dk4stream_read(buf, &rdb, strm, NULL)) {
+ if (0 < rdb) { $? ". read ok"
+ switch (dk4tspwx_add_bytes(&tspwx, (unsigned char *)buf, rdb)) {
+ case DK4_TSP_RES_OK: {
+ cc = 1; $? ". byte add ok"
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ cc = 1; $? ". byte add error"
+ } break;
+ default: {
+ back = false; $? ". byte add fatal"
+ } break;
+ }
+ }
+ }
+ } while (0 != cc);
+ if (back) { $? ". finalize tsp"
+ if (DK4_TSP_RES_FATAL == dk4tspwx_finish(&tspwx)) {
+ back = false; $? "! finalize"
+ }
+ if (back) {
+ if (reader.curpos < (reader.dptr)->nstrings) {
+ back = false; $? "! too few"
+ }
+ }
+ }
+ } else { $? "! init"
+ }
+ } else {
+ dk4error_set_simple_error_code(erp2, DK4_E_INVALID_ARGUMENTS);
+ }
+ $? "- dk4wxstt_apply_stream %d", back
+ return back;
+}
+
+
diff --git a/support/dktools/dk4wxstt.h b/support/dktools/dk4wxstt.h
new file mode 100644
index 0000000000..b6b0dad2de
--- /dev/null
+++ b/support/dktools/dk4wxstt.h
@@ -0,0 +1,178 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dk4wxstt.cpt
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef DK4WXSTT_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK4WXSTT_H_INCLUDED 1
+
+
+#line 10 "dk4wxstt.cpt"
+
+/** @file dk4wxstt.h String tables for wxChars.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4STRM_H_INCLUDED
+#include "dk4strm.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+#ifndef DK4WXCS_H_INCLUDED
+#include "dk4wxcs.h"
+#endif
+
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+
+/** String table for wxChar strings.
+*/
+typedef struct {
+ dkChar *shrtfn; /**< Short file name. */
+ wxChar **strings; /**< Strings read from file. */
+ size_t nstrings; /**< Number of strings. */
+} dk4_wx_string_table_t;
+
+
+extern "C" {
+
+/** Create string table from file.
+ @param fn Short file name to store in structure.
+ @param sz Number of lines required.
+ @param erp Error report, may be NULL.
+ @return Pointer to new string table structure on success, NULL
+ on error.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if fn is NULL or sz is 0,
+ - DK4_E_MATH_OVERFLOW<br>
+ if there was a numeric overflow in size calculations for
+ dynamic memory allocations,
+ - DK4_E_MEMORY_ALLOCATION_FAILED<br>
+ if there is not enough memory available.
+*/
+dk4_wx_string_table_t *
+dk4wxstt_open(const dkChar *fn, size_t sz, dk4_er_t *erp);
+
+/** Apply a text stream to a string table.
+ @param tptr String table to configure.
+ @param strm Text stream, opened for reading.
+ @param pre Processing encoding.
+ @param erp1 Error report for decoding/encoding, may be NULL.
+ @param erp2 Error report for processing, may be NULL.
+ @return True on success, false on error.
+
+ Error codes erp1:
+
+ Error codes erp2:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if tptr or strm is NULL
+*/
+bool
+dk4wxstt_apply_stream(
+ dk4_wx_string_table_t *tptr,
+ dk4_stream_t *strm,
+ int pre,
+ dk4_er_t *erp1,
+ dk4_er_t *erp2
+);
+
+/** Destroy a string table, free allocated memory.
+ @param ptr String table to destroy.
+*/
+void
+dk4wxstt_close(dk4_wx_string_table_t *ptr);
+
+/** Mark string table as empty.
+ Release memory for the strings.
+ @param ptr String table to shut down.
+*/
+void
+dk4wxstt_shutdown(dk4_wx_string_table_t *ptr);
+
+/** Compare two string tables by short name.
+ @param l Left pointer (always string table).
+ @param r Right pointer (string table or short name).
+ @param cr Comparison criteria
+ (0=string table/string table,
+ 1=string table/short name).
+ @return Comparison result.
+*/
+int
+dk4wxstt_compare(const void *l, const void *r, int cr);
+
+}
+
+
+
+#endif
diff --git a/support/dktools/dk4wxtypes.h b/support/dktools/dk4wxtypes.h
new file mode 100644
index 0000000000..41ab0ba314
--- /dev/null
+++ b/support/dktools/dk4wxtypes.h
@@ -0,0 +1,47 @@
+#ifndef DK4WXTYPES_H_INCLUDED
+/** Protection against multiple inclusions. */
+#define DK4WXTYPES_H_INCLUDED 1
+
+/** @file dk4wxtypes.h Types definitions for use with wxWidgets.
+*/
+
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#if DK4_HAVE_WX_CHARTYPE_H
+#ifndef WX_CHARTYPE_H_INCLUDED
+#include <wx/chartype.h>
+#define WX_CHARTYPE_H_INCLUDED 1
+#endif
+#else
+#if DK4_HAVE_WX_WXCHAR_H
+#ifndef WX_WXCHAR_H_INCLUDED
+#include <wx/wxchar.h>
+#define WX_WXCHAR_H_INCLUDED 1
+#endif
+#else
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED
+#endif
+#endif
+#endif
+#endif
+
+/** Pointer to wxChar.
+*/
+typedef wxChar *DK4_PWXCHAR;
+
+/** Pointer to constant wxChar string.
+*/
+typedef const wxChar *DK4_PCWXCHAR;
+
+#endif
+/* ifndef DK4WXTYPES_H_INCLUDED */
+
diff --git a/support/dktools/dkclock.ico b/support/dktools/dkclock.ico
new file mode 100644
index 0000000000..d5aadad6ad
--- /dev/null
+++ b/support/dktools/dkclock.ico
Binary files differ
diff --git a/support/dktools/dkclock.xpm b/support/dktools/dkclock.xpm
new file mode 100644
index 0000000000..d48908e19b
--- /dev/null
+++ b/support/dktools/dkclock.xpm
@@ -0,0 +1,40 @@
+/* XPM */
+static const char *xpm_dkclock[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 17 1",
+/* colors */
+" c #514300",
+". c #DCB700",
+"X c #342B00",
+"o c #1D1900",
+"O c #FFD400",
+"+ c #FCD200",
+"@ c #584900",
+"# c #8E7700",
+"$ c #120E00",
+"% c #F8CE00",
+"& c #1D1800",
+"* c #F5CC00",
+"= c #5A4B00",
+"- c #F9CF00",
+"; c #2F2700",
+": c #F6CD00",
+"> c None",
+/* pixels */
+"OOOOOOO++OOOOOOO",
+"OOOO..+XX+..OOOO",
+"OOO%&&*XX*&&%OOO",
+"OO%O==O##O==O-OO",
+"O.&=OOO;;OOO@o.O",
+"O.&=OOO;;OOO@o.O",
+"O+*OOOO;;OOOO:+O",
+"+XX+OOO&$;#O+XX+",
+"+XX+OOO &;#O+XX+",
+"O+*OOOOOOOOOO:+O",
+"O.&=OOOOOOOO@o.O",
+"O.&=OOOOOOOO@o.O",
+"OO%O@@O++O@@O-OO",
+"OOO-oo:XX:oo-OOO",
+"OOOO..+XX+..OOOO",
+"OOOOOOO++OOOOOOO"
+};
diff --git a/support/dktools/dkconfig.cpp b/support/dktools/dkconfig.cpp
new file mode 100644
index 0000000000..9f36d87fa2
--- /dev/null
+++ b/support/dktools/dkconfig.cpp
@@ -0,0 +1,1935 @@
+/** @file dkconfig.cpp Fix configure results.
+ Redirect output from this program to the dk4conf.h file.
+*/
+
+#include <stdio.h>
+#include "config.h"
+
+/* wxWidgets_header_start */
+#if HAVE_WXWIDGETS
+#include "wx/wxprec.h"
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+#endif
+/* wxWidgets_header_end*/
+
+int main(void)
+{
+
+ fputs("/**\t@file dk4conf.h Fixed configure results.\n*/\n\n", stdout);
+ fputs("#ifndef DK4CONF_H_INCLUDED\n", stdout);
+ fputs("/**\tProtection against multiple inclusion.\n*/\n", stdout);
+ fputs("#define DK4CONF_H_INCLUDED 1\n\n", stdout);
+#if HAVE_ALLOC_H
+ fputs("/** DK4 version of HAVE_ALLOC_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ALLOC_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_ALLOC_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ALLOC_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_ARPA_INET_H
+ fputs("/** DK4 version of HAVE_ARPA_INET_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ARPA_INET_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_ARPA_INET_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ARPA_INET_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_ASSERT_H
+ fputs("/** DK4 version of HAVE_ASSERT_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ASSERT_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_ASSERT_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ASSERT_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_BACKSLASH_AS_SEP
+ fputs("/** DK4 version of HAVE_BACKSLASH_AS_SEP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_BACKSLASH_AS_SEP 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_BACKSLASH_AS_SEP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_BACKSLASH_AS_SEP 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_BCMP
+ fputs("/** DK4 version of HAVE_BCMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_BCMP 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_BCMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_BCMP 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_BCOPY
+ fputs("/** DK4 version of HAVE_BCOPY.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_BCOPY 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_BCOPY.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_BCOPY 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_BIOS_H
+ fputs("/** DK4 version of HAVE_BIOS_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_BIOS_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_BIOS_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_BIOS_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_BLKCNT_T
+ fputs("/** DK4 version of HAVE_BLKCNT_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_BLKCNT_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_BLKCNT_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_BLKCNT_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_BLKSIZE_T
+ fputs("/** DK4 version of HAVE_BLKSIZE_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_BLKSIZE_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_BLKSIZE_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_BLKSIZE_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_BZERO
+ fputs("/** DK4 version of HAVE_BZERO.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_BZERO 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_BZERO.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_BZERO 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_BZLIB_H
+ fputs("/** DK4 version of HAVE_BZLIB_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_BZLIB_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_BZLIB_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_BZLIB_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_CALLOC
+ fputs("/** DK4 version of HAVE_CALLOC.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_CALLOC 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_CALLOC.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_CALLOC 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_CASE_INSENSITIVE_PATHNAMES
+ fputs("/** DK4 version of HAVE_CASE_INSENSITIVE_PATHNAMES.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_CASE_INSENSITIVE_PATHNAMES 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_CASE_INSENSITIVE_PATHNAMES.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_CASE_INSENSITIVE_PATHNAMES 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_CASE_INSENSITIVE_USERNAMES
+ fputs("/** DK4 version of HAVE_CASE_INSENSITIVE_USERNAMES.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_CASE_INSENSITIVE_USERNAMES 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_CASE_INSENSITIVE_USERNAMES.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_CASE_INSENSITIVE_USERNAMES 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_COMPATDKTOOLS3
+ fputs("/** DK4 version of HAVE_COMPATDKTOOLS3.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_COMPATDKTOOLS3 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_COMPATDKTOOLS3.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_COMPATDKTOOLS3 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_COMPLEX_H
+ fputs("/** DK4 version of HAVE_COMPLEX_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_COMPLEX_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_COMPLEX_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_COMPLEX_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_CTYPE_H
+ fputs("/** DK4 version of HAVE_CTYPE_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_CTYPE_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_CTYPE_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_CTYPE_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_DEV_T
+ fputs("/** DK4 version of HAVE_DEV_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_DEV_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_DEV_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_DEV_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_DIRECT_H
+ fputs("/** DK4 version of HAVE_DIRECT_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_DIRECT_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_DIRECT_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_DIRECT_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_DIRENT_H
+ fputs("/** DK4 version of HAVE_DIRENT_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_DIRENT_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_DIRENT_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_DIRENT_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_DOS_H
+ fputs("/** DK4 version of HAVE_DOS_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_DOS_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_DOS_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_DOS_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_ENDPWENT
+ fputs("/** DK4 version of HAVE_ENDPWENT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ENDPWENT 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_ENDPWENT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ENDPWENT 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_ERRNO_H
+ fputs("/** DK4 version of HAVE_ERRNO_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ERRNO_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_ERRNO_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ERRNO_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_FCNTL_H
+ fputs("/** DK4 version of HAVE_FCNTL_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FCNTL_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_FCNTL_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FCNTL_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_FENV_H
+ fputs("/** DK4 version of HAVE_FENV_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FENV_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_FENV_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FENV_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_FILEMODE_BINARY
+ fputs("/** DK4 version of HAVE_FILEMODE_BINARY.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FILEMODE_BINARY 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_FILEMODE_BINARY.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FILEMODE_BINARY 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_FILENO
+ fputs("/** DK4 version of HAVE_FILENO.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FILENO 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_FILENO.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FILENO 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_FILE_ATIMECTIME
+ fputs("/** DK4 version of HAVE_FILE_ATIMECTIME.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FILE_ATIMECTIME 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_FILE_ATIMECTIME.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FILE_ATIMECTIME 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_FILE_BLKSIZECNT
+ fputs("/** DK4 version of HAVE_FILE_BLKSIZECNT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FILE_BLKSIZECNT 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_FILE_BLKSIZECNT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FILE_BLKSIZECNT 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_FILE_DEVINO
+ fputs("/** DK4 version of HAVE_FILE_DEVINO.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FILE_DEVINO 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_FILE_DEVINO.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FILE_DEVINO 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_FILE_UIDGID
+ fputs("/** DK4 version of HAVE_FILE_UIDGID.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FILE_UIDGID 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_FILE_UIDGID.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FILE_UIDGID 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_FLOAT_H
+ fputs("/** DK4 version of HAVE_FLOAT_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FLOAT_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_FLOAT_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FLOAT_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_FOPEN64
+ fputs("/** DK4 version of HAVE_FOPEN64.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FOPEN64 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_FOPEN64.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FOPEN64 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_FOPEN_S
+ fputs("/** DK4 version of HAVE_FOPEN_S.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FOPEN_S 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_FOPEN_S.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FOPEN_S 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_FPOS_T
+ fputs("/** DK4 version of HAVE_FPOS_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FPOS_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_FPOS_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FPOS_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_FPUTWC
+ fputs("/** DK4 version of HAVE_FPUTWC.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FPUTWC 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_FPUTWC.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FPUTWC 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_FPUTWS
+ fputs("/** DK4 version of HAVE_FPUTWS.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FPUTWS 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_FPUTWS.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FPUTWS 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_FREE
+ fputs("/** DK4 version of HAVE_FREE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FREE 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_FREE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_FREE 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_GETADDRINFO
+ fputs("/** DK4 version of HAVE_GETADDRINFO.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETADDRINFO 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_GETADDRINFO.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETADDRINFO 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_GETCWD
+ fputs("/** DK4 version of HAVE_GETCWD.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETCWD 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_GETCWD.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETCWD 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_GETENV
+ fputs("/** DK4 version of HAVE_GETENV.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETENV 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_GETENV.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETENV 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_GETENV_S
+ fputs("/** DK4 version of HAVE_GETENV_S.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETENV_S 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_GETENV_S.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETENV_S 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_GETEUID
+ fputs("/** DK4 version of HAVE_GETEUID.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETEUID 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_GETEUID.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETEUID 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_GETEXECNAME
+ fputs("/** DK4 version of HAVE_GETEXECNAME.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETEXECNAME 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_GETEXECNAME.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETEXECNAME 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_GETHOSTBYNAME
+ fputs("/** DK4 version of HAVE_GETHOSTBYNAME.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETHOSTBYNAME 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_GETHOSTBYNAME.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETHOSTBYNAME 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_GETNAMEINFO
+ fputs("/** DK4 version of HAVE_GETNAMEINFO.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETNAMEINFO 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_GETNAMEINFO.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETNAMEINFO 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_GETPID
+ fputs("/** DK4 version of HAVE_GETPID.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETPID 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_GETPID.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETPID 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_GETPWENT
+ fputs("/** DK4 version of HAVE_GETPWENT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETPWENT 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_GETPWENT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GETPWENT 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_GID_T
+ fputs("/** DK4 version of HAVE_GID_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GID_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_GID_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_GID_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_HTONL
+ fputs("/** DK4 version of HAVE_HTONL.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_HTONL 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_HTONL.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_HTONL 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_HTONS
+ fputs("/** DK4 version of HAVE_HTONS.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_HTONS 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_HTONS.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_HTONS 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_IN6_ADDR
+ fputs("/** DK4 version of HAVE_IN6_ADDR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_IN6_ADDR 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_IN6_ADDR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_IN6_ADDR 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_INET_ADDR
+ fputs("/** DK4 version of HAVE_INET_ADDR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INET_ADDR 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_INET_ADDR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INET_ADDR 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_INET_ATON
+ fputs("/** DK4 version of HAVE_INET_ATON.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INET_ATON 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_INET_ATON.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INET_ATON 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_INET_NTOP
+ fputs("/** DK4 version of HAVE_INET_NTOP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INET_NTOP 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_INET_NTOP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INET_NTOP 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_INET_PTON
+ fputs("/** DK4 version of HAVE_INET_PTON.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INET_PTON 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_INET_PTON.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INET_PTON 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_INITSTATE
+ fputs("/** DK4 version of HAVE_INITSTATE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INITSTATE 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_INITSTATE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INITSTATE 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_INO64_T
+ fputs("/** DK4 version of HAVE_INO64_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INO64_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_INO64_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INO64_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_INO_T
+ fputs("/** DK4 version of HAVE_INO_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INO_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_INO_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INO_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_INTMAX_T
+ fputs("/** DK4 version of HAVE_INTMAX_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INTMAX_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_INTMAX_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INTMAX_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_INTTYPES_H
+ fputs("/** DK4 version of HAVE_INTTYPES_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INTTYPES_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_INTTYPES_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_INTTYPES_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_IN_ADDR
+ fputs("/** DK4 version of HAVE_IN_ADDR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_IN_ADDR 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_IN_ADDR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_IN_ADDR 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_IO_H
+ fputs("/** DK4 version of HAVE_IO_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_IO_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_IO_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_IO_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_ISATTY
+ fputs("/** DK4 version of HAVE_ISATTY.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ISATTY 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_ISATTY.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ISATTY 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_ISO646_H
+ fputs("/** DK4 version of HAVE_ISO646_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ISO646_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_ISO646_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ISO646_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_LARGEFILE64_SOURCE
+ fputs("/** DK4 version of HAVE_LARGEFILE64_SOURCE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LARGEFILE64_SOURCE 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_LARGEFILE64_SOURCE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LARGEFILE64_SOURCE 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_LIMITS_H
+ fputs("/** DK4 version of HAVE_LIMITS_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LIMITS_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_LIMITS_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LIMITS_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_LINE_END_CR_NL
+ fputs("/** DK4 version of HAVE_LINE_END_CR_NL.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LINE_END_CR_NL 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_LINE_END_CR_NL.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LINE_END_CR_NL 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_LOCALE_H
+ fputs("/** DK4 version of HAVE_LOCALE_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LOCALE_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_LOCALE_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LOCALE_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_LOCALTIME_R
+ fputs("/** DK4 version of HAVE_LOCALTIME_R.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LOCALTIME_R 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_LOCALTIME_R.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LOCALTIME_R 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_LONG_DOUBLE
+ fputs("/** DK4 version of HAVE_LONG_DOUBLE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LONG_DOUBLE 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_LONG_DOUBLE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LONG_DOUBLE 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_LONG_LONG
+ fputs("/** DK4 version of HAVE_LONG_LONG.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LONG_LONG 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_LONG_LONG.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LONG_LONG 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_LRAND48
+ fputs("/** DK4 version of HAVE_LRAND48.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LRAND48 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_LRAND48.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LRAND48 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_LSTAT
+ fputs("/** DK4 version of HAVE_LSTAT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LSTAT 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_LSTAT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LSTAT 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_LSTAT64
+ fputs("/** DK4 version of HAVE_LSTAT64.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LSTAT64 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_LSTAT64.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_LSTAT64 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_MALLOC
+ fputs("/** DK4 version of HAVE_MALLOC.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_MALLOC 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_MALLOC.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_MALLOC 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_MALLOC_H
+ fputs("/** DK4 version of HAVE_MALLOC_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_MALLOC_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_MALLOC_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_MALLOC_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_MATH_H
+ fputs("/** DK4 version of HAVE_MATH_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_MATH_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_MATH_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_MATH_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_MEMCMP
+ fputs("/** DK4 version of HAVE_MEMCMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_MEMCMP 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_MEMCMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_MEMCMP 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_MEMCPY
+ fputs("/** DK4 version of HAVE_MEMCPY.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_MEMCPY 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_MEMCPY.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_MEMCPY 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_MEMSET
+ fputs("/** DK4 version of HAVE_MEMSET.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_MEMSET 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_MEMSET.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_MEMSET 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_MKDIR
+ fputs("/** DK4 version of HAVE_MKDIR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_MKDIR 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_MKDIR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_MKDIR 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_MODE_T
+ fputs("/** DK4 version of HAVE_MODE_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_MODE_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_MODE_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_MODE_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_NETDB_H
+ fputs("/** DK4 version of HAVE_NETDB_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_NETDB_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_NETDB_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_NETDB_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_NETINET_IN6_H
+ fputs("/** DK4 version of HAVE_NETINET_IN6_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_NETINET_IN6_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_NETINET_IN6_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_NETINET_IN6_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_NETINET_IN_H
+ fputs("/** DK4 version of HAVE_NETINET_IN_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_NETINET_IN_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_NETINET_IN_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_NETINET_IN_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_NLINK_T
+ fputs("/** DK4 version of HAVE_NLINK_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_NLINK_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_NLINK_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_NLINK_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_NRAND48
+ fputs("/** DK4 version of HAVE_NRAND48.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_NRAND48 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_NRAND48.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_NRAND48 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_NTOHL
+ fputs("/** DK4 version of HAVE_NTOHL.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_NTOHL 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_NTOHL.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_NTOHL 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_NTOHS
+ fputs("/** DK4 version of HAVE_NTOHS.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_NTOHS 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_NTOHS.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_NTOHS 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_OFF64_T
+ fputs("/** DK4 version of HAVE_OFF64_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_OFF64_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_OFF64_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_OFF64_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_OFF_T
+ fputs("/** DK4 version of HAVE_OFF_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_OFF_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_OFF_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_OFF_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_OPENSSL_MD5_H
+ fputs("/** DK4 version of HAVE_OPENSSL_MD5_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_OPENSSL_MD5_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_OPENSSL_MD5_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_OPENSSL_MD5_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_OPENSSL_RAND_H
+ fputs("/** DK4 version of HAVE_OPENSSL_RAND_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_OPENSSL_RAND_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_OPENSSL_RAND_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_OPENSSL_RAND_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_OPENSSL_RIPEMD_H
+ fputs("/** DK4 version of HAVE_OPENSSL_RIPEMD_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_OPENSSL_RIPEMD_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_OPENSSL_RIPEMD_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_OPENSSL_RIPEMD_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_OPENSSL_SHA_H
+ fputs("/** DK4 version of HAVE_OPENSSL_SHA_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_OPENSSL_SHA_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_OPENSSL_SHA_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_OPENSSL_SHA_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_PROCESS_H
+ fputs("/** DK4 version of HAVE_PROCESS_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_PROCESS_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_PROCESS_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_PROCESS_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_PROC_PID_EXE
+ fputs("/** DK4 version of HAVE_PROC_PID_EXE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_PROC_PID_EXE 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_PROC_PID_EXE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_PROC_PID_EXE 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_PWD_H
+ fputs("/** DK4 version of HAVE_PWD_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_PWD_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_PWD_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_PWD_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_RAND
+ fputs("/** DK4 version of HAVE_RAND.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_RAND 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_RAND.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_RAND 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_RANDOM
+ fputs("/** DK4 version of HAVE_RANDOM.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_RANDOM 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_RANDOM.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_RANDOM 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_READLINK
+ fputs("/** DK4 version of HAVE_READLINK.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_READLINK 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_READLINK.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_READLINK 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_RMDIR
+ fputs("/** DK4 version of HAVE_RMDIR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_RMDIR 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_RMDIR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_RMDIR 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SELECT
+ fputs("/** DK4 version of HAVE_SELECT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SELECT 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SELECT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SELECT 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SETJMP_H
+ fputs("/** DK4 version of HAVE_SETJMP_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETJMP_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SETJMP_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETJMP_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SETLOCALE
+ fputs("/** DK4 version of HAVE_SETLOCALE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETLOCALE 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SETLOCALE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETLOCALE 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SETMODE
+ fputs("/** DK4 version of HAVE_SETMODE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETMODE 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SETMODE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETMODE 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SETPWENT
+ fputs("/** DK4 version of HAVE_SETPWENT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETPWENT 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SETPWENT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETPWENT 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SETSOCKOPT
+ fputs("/** DK4 version of HAVE_SETSOCKOPT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETSOCKOPT 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SETSOCKOPT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETSOCKOPT 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SETSTATE
+ fputs("/** DK4 version of HAVE_SETSTATE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETSTATE 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SETSTATE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SETSTATE 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SHA224
+ fputs("/** DK4 version of HAVE_SHA224.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SHA224 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SHA224.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SHA224 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SHA256
+ fputs("/** DK4 version of HAVE_SHA256.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SHA256 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SHA256.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SHA256 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SHA384
+ fputs("/** DK4 version of HAVE_SHA384.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SHA384 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SHA384.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SHA384 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SHA512
+ fputs("/** DK4 version of HAVE_SHA512.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SHA512 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SHA512.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SHA512 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SHARE_H
+ fputs("/** DK4 version of HAVE_SHARE_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SHARE_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SHARE_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SHARE_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SIGACTION
+ fputs("/** DK4 version of HAVE_SIGACTION.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SIGACTION 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SIGACTION.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SIGACTION 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SIGNAL
+ fputs("/** DK4 version of HAVE_SIGNAL.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SIGNAL 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SIGNAL.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SIGNAL 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SIGNAL_H
+ fputs("/** DK4 version of HAVE_SIGNAL_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SIGNAL_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SIGNAL_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SIGNAL_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SIGSET
+ fputs("/** DK4 version of HAVE_SIGSET.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SIGSET 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SIGSET.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SIGSET 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SIG_ATOMIC_T
+ fputs("/** DK4 version of HAVE_SIG_ATOMIC_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SIG_ATOMIC_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SIG_ATOMIC_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SIG_ATOMIC_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SNPRINTF
+ fputs("/** DK4 version of HAVE_SNPRINTF.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SNPRINTF 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SNPRINTF.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SNPRINTF 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SNWPRINTF
+ fputs("/** DK4 version of HAVE_SNWPRINTF.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SNWPRINTF 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SNWPRINTF.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SNWPRINTF 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SOCKET
+ fputs("/** DK4 version of HAVE_SOCKET.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SOCKET 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SOCKET.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SOCKET 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SOCKLEN_T
+ fputs("/** DK4 version of HAVE_SOCKLEN_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SOCKLEN_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SOCKLEN_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SOCKLEN_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SRAND
+ fputs("/** DK4 version of HAVE_SRAND.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SRAND 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SRAND.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SRAND 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SSIZE_T
+ fputs("/** DK4 version of HAVE_SSIZE_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SSIZE_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SSIZE_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SSIZE_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STAT64
+ fputs("/** DK4 version of HAVE_STAT64.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STAT64 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STAT64.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STAT64 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STDALIGN_H
+ fputs("/** DK4 version of HAVE_STDALIGN_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STDALIGN_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STDALIGN_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STDALIGN_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STDARG_H
+ fputs("/** DK4 version of HAVE_STDARG_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STDARG_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STDARG_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STDARG_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STDATOMIC_H
+ fputs("/** DK4 version of HAVE_STDATOMIC_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STDATOMIC_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STDATOMIC_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STDATOMIC_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STDBOOL_H
+ fputs("/** DK4 version of HAVE_STDBOOL_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STDBOOL_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STDBOOL_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STDBOOL_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STDDEF_H
+ fputs("/** DK4 version of HAVE_STDDEF_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STDDEF_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STDDEF_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STDDEF_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STDINT_H
+ fputs("/** DK4 version of HAVE_STDINT_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STDINT_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STDINT_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STDINT_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STDLIB_H
+ fputs("/** DK4 version of HAVE_STDLIB_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STDLIB_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STDLIB_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STDLIB_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STDNORETURN_H
+ fputs("/** DK4 version of HAVE_STDNORETURN_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STDNORETURN_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STDNORETURN_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STDNORETURN_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STRCASECMP
+ fputs("/** DK4 version of HAVE_STRCASECMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRCASECMP 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STRCASECMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRCASECMP 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STRCAT_S
+ fputs("/** DK4 version of HAVE_STRCAT_S.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRCAT_S 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STRCAT_S.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRCAT_S 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STRCPY_S
+ fputs("/** DK4 version of HAVE_STRCPY_S.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRCPY_S 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STRCPY_S.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRCPY_S 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STRERROR
+ fputs("/** DK4 version of HAVE_STRERROR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRERROR 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STRERROR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRERROR 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STRERROR_R
+ fputs("/** DK4 version of HAVE_STRERROR_R.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRERROR_R 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STRERROR_R.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRERROR_R 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STRICMP
+ fputs("/** DK4 version of HAVE_STRICMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRICMP 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STRICMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRICMP 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STRINGS_H
+ fputs("/** DK4 version of HAVE_STRINGS_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRINGS_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STRINGS_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRINGS_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STRING_H
+ fputs("/** DK4 version of HAVE_STRING_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRING_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STRING_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRING_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STRTOD
+ fputs("/** DK4 version of HAVE_STRTOD.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRTOD 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STRTOD.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRTOD 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STRUCT_ADDRINFO
+ fputs("/** DK4 version of HAVE_STRUCT_ADDRINFO.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRUCT_ADDRINFO 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STRUCT_ADDRINFO.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRUCT_ADDRINFO 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STRUCT_SOCKADDR_IN
+ fputs("/** DK4 version of HAVE_STRUCT_SOCKADDR_IN.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRUCT_SOCKADDR_IN 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STRUCT_SOCKADDR_IN.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRUCT_SOCKADDR_IN 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STRUCT_SOCKADDR_IN6
+ fputs("/** DK4 version of HAVE_STRUCT_SOCKADDR_IN6.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRUCT_SOCKADDR_IN6 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STRUCT_SOCKADDR_IN6.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRUCT_SOCKADDR_IN6 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STRUCT_SOCKADDR_STORAGE
+ fputs("/** DK4 version of HAVE_STRUCT_SOCKADDR_STORAGE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRUCT_SOCKADDR_STORAGE 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STRUCT_SOCKADDR_STORAGE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRUCT_SOCKADDR_STORAGE 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_STRUCT_SOCKADDR_UN
+ fputs("/** DK4 version of HAVE_STRUCT_SOCKADDR_UN.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRUCT_SOCKADDR_UN 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_STRUCT_SOCKADDR_UN.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_STRUCT_SOCKADDR_UN 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SWPRINTF
+ fputs("/** DK4 version of HAVE_SWPRINTF.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SWPRINTF 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SWPRINTF.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SWPRINTF 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SYS_PARAM_H
+ fputs("/** DK4 version of HAVE_SYS_PARAM_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SYS_PARAM_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SYS_PARAM_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SYS_PARAM_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SYS_SELECT_H
+ fputs("/** DK4 version of HAVE_SYS_SELECT_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SYS_SELECT_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SYS_SELECT_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SYS_SELECT_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SYS_SOCKET_H
+ fputs("/** DK4 version of HAVE_SYS_SOCKET_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SYS_SOCKET_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SYS_SOCKET_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SYS_SOCKET_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SYS_STAT_H
+ fputs("/** DK4 version of HAVE_SYS_STAT_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SYS_STAT_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SYS_STAT_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SYS_STAT_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SYS_TIME_H
+ fputs("/** DK4 version of HAVE_SYS_TIME_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SYS_TIME_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SYS_TIME_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SYS_TIME_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SYS_TYPES_H
+ fputs("/** DK4 version of HAVE_SYS_TYPES_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SYS_TYPES_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SYS_TYPES_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SYS_TYPES_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_SYS_UN_H
+ fputs("/** DK4 version of HAVE_SYS_UN_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SYS_UN_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_SYS_UN_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_SYS_UN_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_TGMATH_H
+ fputs("/** DK4 version of HAVE_TGMATH_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_TGMATH_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_TGMATH_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_TGMATH_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_THREADS_H
+ fputs("/** DK4 version of HAVE_THREADS_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_THREADS_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_THREADS_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_THREADS_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_TIME_H
+ fputs("/** DK4 version of HAVE_TIME_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_TIME_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_TIME_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_TIME_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_TYPE_STAT64
+ fputs("/** DK4 version of HAVE_TYPE_STAT64.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_TYPE_STAT64 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_TYPE_STAT64.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_TYPE_STAT64 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_UCHAR_H
+ fputs("/** DK4 version of HAVE_UCHAR_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_UCHAR_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_UCHAR_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_UCHAR_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_UID_T
+ fputs("/** DK4 version of HAVE_UID_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_UID_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_UID_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_UID_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_UINT16_T
+ fputs("/** DK4 version of HAVE_UINT16_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_UINT16_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_UINT16_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_UINT16_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_UINT32_T
+ fputs("/** DK4 version of HAVE_UINT32_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_UINT32_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_UINT32_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_UINT32_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_UNISTD_H
+ fputs("/** DK4 version of HAVE_UNISTD_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_UNISTD_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_UNISTD_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_UNISTD_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_UNLINK
+ fputs("/** DK4 version of HAVE_UNLINK.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_UNLINK 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_UNLINK.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_UNLINK 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_VOLATILE
+ fputs("/** DK4 version of HAVE_VOLATILE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_VOLATILE 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_VOLATILE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_VOLATILE 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WCHAR_H
+ fputs("/** DK4 version of HAVE_WCHAR_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCHAR_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WCHAR_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCHAR_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WCSCASECMP
+ fputs("/** DK4 version of HAVE_WCSCASECMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSCASECMP 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WCSCASECMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSCASECMP 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WCSCAT
+ fputs("/** DK4 version of HAVE_WCSCAT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSCAT 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WCSCAT.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSCAT 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WCSCAT_S
+ fputs("/** DK4 version of HAVE_WCSCAT_S.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSCAT_S 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WCSCAT_S.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSCAT_S 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WCSCHR
+ fputs("/** DK4 version of HAVE_WCSCHR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSCHR 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WCSCHR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSCHR 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WCSCMP
+ fputs("/** DK4 version of HAVE_WCSCMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSCMP 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WCSCMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSCMP 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WCSCPY
+ fputs("/** DK4 version of HAVE_WCSCPY.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSCPY 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WCSCPY.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSCPY 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WCSCPY_S
+ fputs("/** DK4 version of HAVE_WCSCPY_S.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSCPY_S 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WCSCPY_S.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSCPY_S 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WCSICMP
+ fputs("/** DK4 version of HAVE_WCSICMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSICMP 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WCSICMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSICMP 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WCSLEN
+ fputs("/** DK4 version of HAVE_WCSLEN.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSLEN 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WCSLEN.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSLEN 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WCSRCHR
+ fputs("/** DK4 version of HAVE_WCSRCHR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSRCHR 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WCSRCHR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSRCHR 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WCSTOD
+ fputs("/** DK4 version of HAVE_WCSTOD.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSTOD 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WCSTOD.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCSTOD 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WCTYPE_H
+ fputs("/** DK4 version of HAVE_WCTYPE_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCTYPE_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WCTYPE_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WCTYPE_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WINDOWS_H
+ fputs("/** DK4 version of HAVE_WINDOWS_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WINDOWS_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WINDOWS_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WINDOWS_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WINSOCK2_H
+ fputs("/** DK4 version of HAVE_WINSOCK2_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WINSOCK2_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WINSOCK2_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WINSOCK2_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WMKDIR
+ fputs("/** DK4 version of HAVE_WMKDIR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WMKDIR 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WMKDIR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WMKDIR 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WRMDIR
+ fputs("/** DK4 version of HAVE_WRMDIR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WRMDIR 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WRMDIR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WRMDIR 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WS2TCPIP_H
+ fputs("/** DK4 version of HAVE_WS2TCPIP_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WS2TCPIP_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WS2TCPIP_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WS2TCPIP_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WUNLINK
+ fputs("/** DK4 version of HAVE_WUNLINK.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WUNLINK 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WUNLINK.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WUNLINK 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_WXWIDGETS
+ fputs("/** DK4 version of HAVE_WXWIDGETS.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WXWIDGETS 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_WXWIDGETS.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_WXWIDGETS 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE_ZLIB_H
+ fputs("/** DK4 version of HAVE_ZLIB_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ZLIB_H 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE_ZLIB_H.\n*/\n", stdout);
+ fputs("#define DK4_HAVE_ZLIB_H 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__DEV_T
+ fputs("/** DK4 version of HAVE__DEV_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__DEV_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__DEV_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__DEV_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__FILENO
+ fputs("/** DK4 version of HAVE__FILENO.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__FILENO 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__FILENO.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__FILENO 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__FPOS_T
+ fputs("/** DK4 version of HAVE__FPOS_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__FPOS_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__FPOS_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__FPOS_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__GETCWD
+ fputs("/** DK4 version of HAVE__GETCWD.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__GETCWD 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__GETCWD.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__GETCWD 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__INO64_T
+ fputs("/** DK4 version of HAVE__INO64_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__INO64_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__INO64_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__INO64_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__INO_T
+ fputs("/** DK4 version of HAVE__INO_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__INO_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__INO_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__INO_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__ISATTY
+ fputs("/** DK4 version of HAVE__ISATTY.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__ISATTY 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__ISATTY.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__ISATTY 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__MKDIR
+ fputs("/** DK4 version of HAVE__MKDIR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__MKDIR 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__MKDIR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__MKDIR 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__OFF64_T
+ fputs("/** DK4 version of HAVE__OFF64_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__OFF64_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__OFF64_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__OFF64_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__OFF_T
+ fputs("/** DK4 version of HAVE__OFF_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__OFF_T 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__OFF_T.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__OFF_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__RMDIR
+ fputs("/** DK4 version of HAVE__RMDIR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__RMDIR 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__RMDIR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__RMDIR 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__SETMODE
+ fputs("/** DK4 version of HAVE__SETMODE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__SETMODE 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__SETMODE.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__SETMODE 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__SNPRINTF
+ fputs("/** DK4 version of HAVE__SNPRINTF.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__SNPRINTF 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__SNPRINTF.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__SNPRINTF 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__SNPRINTF_S
+ fputs("/** DK4 version of HAVE__SNPRINTF_S.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__SNPRINTF_S 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__SNPRINTF_S.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__SNPRINTF_S 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__SNWPRINTF
+ fputs("/** DK4 version of HAVE__SNWPRINTF.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__SNWPRINTF 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__SNWPRINTF.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__SNWPRINTF 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__SNWPRINTF_S
+ fputs("/** DK4 version of HAVE__SNWPRINTF_S.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__SNWPRINTF_S 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__SNWPRINTF_S.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__SNWPRINTF_S 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__STRICMP
+ fputs("/** DK4 version of HAVE__STRICMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__STRICMP 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__STRICMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__STRICMP 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__STRTOD
+ fputs("/** DK4 version of HAVE__STRTOD.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__STRTOD 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__STRTOD.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__STRTOD 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__UNLINK
+ fputs("/** DK4 version of HAVE__UNLINK.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__UNLINK 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__UNLINK.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__UNLINK 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__WCSCASECMP
+ fputs("/** DK4 version of HAVE__WCSCASECMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WCSCASECMP 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__WCSCASECMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WCSCASECMP 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__WCSCMP
+ fputs("/** DK4 version of HAVE__WCSCMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WCSCMP 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__WCSCMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WCSCMP 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__WCSICMP
+ fputs("/** DK4 version of HAVE__WCSICMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WCSICMP 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__WCSICMP.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WCSICMP 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__WCSTOD
+ fputs("/** DK4 version of HAVE__WCSTOD.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WCSTOD 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__WCSTOD.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WCSTOD 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__WFOPEN
+ fputs("/** DK4 version of HAVE__WFOPEN.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WFOPEN 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__WFOPEN.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WFOPEN 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__WFOPEN64
+ fputs("/** DK4 version of HAVE__WFOPEN64.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WFOPEN64 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__WFOPEN64.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WFOPEN64 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__WFOPEN_S
+ fputs("/** DK4 version of HAVE__WFOPEN_S.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WFOPEN_S 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__WFOPEN_S.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WFOPEN_S 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__WGETCWD
+ fputs("/** DK4 version of HAVE__WGETCWD.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WGETCWD 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__WGETCWD.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WGETCWD 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__WMKDIR
+ fputs("/** DK4 version of HAVE__WMKDIR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WMKDIR 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__WMKDIR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WMKDIR 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__WRMDIR
+ fputs("/** DK4 version of HAVE__WRMDIR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WRMDIR 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__WRMDIR.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WRMDIR 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if HAVE__WUNLINK
+ fputs("/** DK4 version of HAVE__WUNLINK.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WUNLINK 1\n", stdout);
+#else
+ fputs("/** DK4 version of HAVE__WUNLINK.\n*/\n", stdout);
+ fputs("#define DK4_HAVE__WUNLINK 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if SIZEOF_DOUBLE
+ fputs("/** DK4 version of SIZEOF_DOUBLE.\n*/\n", stdout);
+ printf("#define DK4_SIZEOF_DOUBLE %u\n", (unsigned)SIZEOF_DOUBLE);
+#else
+ fputs("/** DK4 version of SIZEOF_DOUBLE.\n*/\n", stdout);
+ fputs("#define DK4_SIZEOF_DOUBLE 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if SIZEOF_INO64_T
+ fputs("/** DK4 version of SIZEOF_INO64_T.\n*/\n", stdout);
+ printf("#define DK4_SIZEOF_INO64_T %u\n", (unsigned)SIZEOF_INO64_T);
+#else
+ fputs("/** DK4 version of SIZEOF_INO64_T.\n*/\n", stdout);
+ fputs("#define DK4_SIZEOF_INO64_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if SIZEOF_INO_T
+ fputs("/** DK4 version of SIZEOF_INO_T.\n*/\n", stdout);
+ printf("#define DK4_SIZEOF_INO_T %u\n", (unsigned)SIZEOF_INO_T);
+#else
+ fputs("/** DK4 version of SIZEOF_INO_T.\n*/\n", stdout);
+ fputs("#define DK4_SIZEOF_INO_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if SIZEOF_INT
+ fputs("/** DK4 version of SIZEOF_INT.\n*/\n", stdout);
+ printf("#define DK4_SIZEOF_INT %u\n", (unsigned)SIZEOF_INT);
+#else
+ fputs("/** DK4 version of SIZEOF_INT.\n*/\n", stdout);
+ fputs("#define DK4_SIZEOF_INT 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if SIZEOF_INTMAX_T
+ fputs("/** DK4 version of SIZEOF_INTMAX_T.\n*/\n", stdout);
+ printf("#define DK4_SIZEOF_INTMAX_T %u\n", (unsigned)SIZEOF_INTMAX_T);
+#else
+ fputs("/** DK4 version of SIZEOF_INTMAX_T.\n*/\n", stdout);
+ fputs("#define DK4_SIZEOF_INTMAX_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if SIZEOF_LONG
+ fputs("/** DK4 version of SIZEOF_LONG.\n*/\n", stdout);
+ printf("#define DK4_SIZEOF_LONG %u\n", (unsigned)SIZEOF_LONG);
+#else
+ fputs("/** DK4 version of SIZEOF_LONG.\n*/\n", stdout);
+ fputs("#define DK4_SIZEOF_LONG 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if SIZEOF_LONG_DOUBLE
+ fputs("/** DK4 version of SIZEOF_LONG_DOUBLE.\n*/\n", stdout);
+ printf("#define DK4_SIZEOF_LONG_DOUBLE %u\n", (unsigned)SIZEOF_LONG_DOUBLE);
+#else
+ fputs("/** DK4 version of SIZEOF_LONG_DOUBLE.\n*/\n", stdout);
+ fputs("#define DK4_SIZEOF_LONG_DOUBLE 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if SIZEOF_LONG_LONG
+ fputs("/** DK4 version of SIZEOF_LONG_LONG.\n*/\n", stdout);
+ printf("#define DK4_SIZEOF_LONG_LONG %u\n", (unsigned)SIZEOF_LONG_LONG);
+#else
+ fputs("/** DK4 version of SIZEOF_LONG_LONG.\n*/\n", stdout);
+ fputs("#define DK4_SIZEOF_LONG_LONG 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if SIZEOF_OFF64_T
+ fputs("/** DK4 version of SIZEOF_OFF64_T.\n*/\n", stdout);
+ printf("#define DK4_SIZEOF_OFF64_T %u\n", (unsigned)SIZEOF_OFF64_T);
+#else
+ fputs("/** DK4 version of SIZEOF_OFF64_T.\n*/\n", stdout);
+ fputs("#define DK4_SIZEOF_OFF64_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if SIZEOF_OFF_T
+ fputs("/** DK4 version of SIZEOF_OFF_T.\n*/\n", stdout);
+ printf("#define DK4_SIZEOF_OFF_T %u\n", (unsigned)SIZEOF_OFF_T);
+#else
+ fputs("/** DK4 version of SIZEOF_OFF_T.\n*/\n", stdout);
+ fputs("#define DK4_SIZEOF_OFF_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if SIZEOF_SHORT
+ fputs("/** DK4 version of SIZEOF_SHORT.\n*/\n", stdout);
+ printf("#define DK4_SIZEOF_SHORT %u\n", (unsigned)SIZEOF_SHORT);
+#else
+ fputs("/** DK4 version of SIZEOF_SHORT.\n*/\n", stdout);
+ fputs("#define DK4_SIZEOF_SHORT 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if SIZEOF_SIZE_T
+ fputs("/** DK4 version of SIZEOF_SIZE_T.\n*/\n", stdout);
+ printf("#define DK4_SIZEOF_SIZE_T %u\n", (unsigned)SIZEOF_SIZE_T);
+#else
+ fputs("/** DK4 version of SIZEOF_SIZE_T.\n*/\n", stdout);
+ fputs("#define DK4_SIZEOF_SIZE_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if SIZEOF_WCHAR_T
+ fputs("/** DK4 version of SIZEOF_WCHAR_T.\n*/\n", stdout);
+ printf("#define DK4_SIZEOF_WCHAR_T %u\n", (unsigned)SIZEOF_WCHAR_T);
+#else
+ fputs("/** DK4 version of SIZEOF_WCHAR_T.\n*/\n", stdout);
+ fputs("#define DK4_SIZEOF_WCHAR_T 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if TIME_WITH_SYS_TIME
+ fputs("/** DK4 version of TIME_WITH_SYS_TIME.\n*/\n", stdout);
+ printf("#define DK4_TIME_WITH_SYS_TIME %u\n", (unsigned)TIME_WITH_SYS_TIME);
+#else
+ fputs("/** DK4 version of TIME_WITH_SYS_TIME.\n*/\n", stdout);
+ fputs("#define DK4_TIME_WITH_SYS_TIME 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if USE_FALLBACK_NUMERIC_LIMITS
+ fputs("/** DK4 version of USE_FALLBACK_NUMERIC_LIMITS.\n*/\n", stdout);
+ printf("#define DK4_USE_FALLBACK_NUMERIC_LIMITS %u\n", (unsigned)USE_FALLBACK_NUMERIC_LIMITS);
+#else
+ fputs("/** DK4 version of USE_FALLBACK_NUMERIC_LIMITS.\n*/\n", stdout);
+ fputs("#define DK4_USE_FALLBACK_NUMERIC_LIMITS 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if USE_PRINTF_SCANF
+ fputs("/** DK4 version of USE_PRINTF_SCANF.\n*/\n", stdout);
+ printf("#define DK4_USE_PRINTF_SCANF %u\n", (unsigned)USE_PRINTF_SCANF);
+#else
+ fputs("/** DK4 version of USE_PRINTF_SCANF.\n*/\n", stdout);
+ fputs("#define DK4_USE_PRINTF_SCANF 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if USE_WINDOWS_LOCAL_ALLOC
+ fputs("/** DK4 version of USE_WINDOWS_LOCAL_ALLOC.\n*/\n", stdout);
+ printf("#define DK4_USE_WINDOWS_LOCAL_ALLOC %u\n", (unsigned)USE_WINDOWS_LOCAL_ALLOC);
+#else
+ fputs("/** DK4 version of USE_WINDOWS_LOCAL_ALLOC.\n*/\n", stdout);
+ fputs("#define DK4_USE_WINDOWS_LOCAL_ALLOC 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+#if WORDS_BIGENDIAN
+ fputs("/** DK4 version of WORDS_BIGENDIAN.\n*/\n", stdout);
+ printf("#define DK4_WORDS_BIGENDIAN %u\n", (unsigned)WORDS_BIGENDIAN);
+#else
+ fputs("/** DK4 version of WORDS_BIGENDIAN.\n*/\n", stdout);
+ fputs("#define DK4_WORDS_BIGENDIAN 0\n", stdout);
+#endif
+ fputc('\n', stdout);
+/* wxWidgets_body_start */
+#if HAVE_WXWIDGETS
+ fputs("/** Size of wchar_t.\n*/\n", stdout);
+ printf("#define DK4_SIZEOF_WXCHAR %u\n\n", (unsigned)sizeof(wxChar));
+#else
+ fputs("/** Size of wchar_t.\n*/\n", stdout);
+ fputs("#define DK4_SIZEOF_WXCHAR 0\n\n", stdout);
+#endif
+/* wxWidgets_body_end */
+
+ fputs("#endif\n/* ifndef DK4CONF_H_INCLUDED */\n", stdout);
+ return 0;
+}
diff --git a/support/dktools/dkct-au.c b/support/dktools/dkct-au.c
new file mode 100644
index 0000000000..5b1cab728c
--- /dev/null
+++ b/support/dktools/dkct-au.c
@@ -0,0 +1,1831 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dkct-au.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dkct-au.c The dkct-au module.
+*/
+
+
+#line 10 "dkct-au.ctr"
+
+
+#if DK3_USE_WX
+#include "dkwxtrace.h"
+#else
+#include "dkct.h"
+#endif
+
+
+
+
+#line 20 "dkct-au.ctr"
+
+
+
+/** Sort criteria:Sort by state and input.
+*/
+#define DKCT_AU_RULE_SORT_STATE_INPUT 1
+
+/** Sort criteria: Inverted search order.
+*/
+#define DKCT_AU_RULE_SORT_REVERSE 2
+
+
+
+/** Input file section for options.
+*/
+#define DKCT_AU_SECTION_OPTIONS 0
+
+/** Input file section for states.
+*/
+#define DKCT_AU_SECTION_STATES 1
+
+/** Input file section for inputs.
+*/
+#define DKCT_AU_SECTION_INPUTS 2
+
+/** Input file section for outputs.
+*/
+#define DKCT_AU_SECTION_OUTPUTS 3
+
+/** Input file section for rules.
+*/
+#define DKCT_AU_SECTION_RULES 4
+
+
+
+/** Section names.
+*/
+static char const * const dkct_au_section_names[] = {
+/* 0 */ "options",
+/* 1 */ "states",
+/* 2 */ "inputs",
+/* 3 */ "outputs",
+/* 4 */ "rules",
+/* 5 */ "option",
+/* 6 */ "state",
+/* 7 */ "input",
+/* 8 */ "output",
+/* 9 */ "rule",
+NULL
+};
+
+
+
+/** Keywords used by the module.
+*/
+static char const * const dkct_au_kw8[] = {
+/* 0 */ "*",
+/* 1 */ "\n",
+/* 2 */ " ",
+/* 3 */ "#ifndef ",
+/* 4 */ "#else\n",
+/* 5 */ "#endif\n\n",
+/* 6 */ "#define ",
+/* 7 */ "#error \"Redefinition of ",
+/* 8 */ "\"\n",
+/* 9 */ " %d\n",
+/* 10 */ " (%d)\n",
+/* 11 */ "/** ",
+/* 12 */ " */\n",
+/* 13 */ "State: ",
+/* 14 */ "State machine input: ",
+/* 15 */ "State machine output: ",
+/* 16 */ "state_machine_%lu",
+/* 17 */ "/** @defgroup dkct_state_machine_",
+/* 18 */ " The ",
+/* 19 */ " state machine. */\n/**@{*/\n\n",
+/* 20 */ "/**@}*/\n\n",
+/* 21 */ "#ifdef __cplusplus\nextern \"C\" { \n#endif\n\n",
+/* 22 */ "#ifdef __cplusplus\n}\n#endif\n\n",
+/* 23 */ "/**\tReset ",
+/* 24 */ " state machine.\n",
+/* 25 */ "\t@param\tst\tPointer to state variable.\n*/\n",
+/* 26 */ "void ",
+/* 27 */ "_reset(int *st);\n\n",
+/* 28 */ "/**\tState machine ",
+/* 29 */ " step.\n\t@param\tst\tPointer to state variable.\n",
+/* 30 */ "\t@param\tin\tInput.\n\t@return\tTransition output.\n*/\n",
+/* 31 */ "_step(int *st, int in);\n\n",
+/* 32 */ "static\n",
+/* 33 */ "void\n",
+/* 34 */ "_reset(int *st)\n{\n if(st) { *st = ",
+/* 35 */ "; }\n}\n\n",
+/* 36 */ "0",
+/* 37 */ "int\n",
+/* 38 */ "_step(int *st, int in)\n{\n int back = ",
+/* 39 */ ";\n",
+/* 40 */ " if(st) {\n int os;\n int nf = 1;\n int ns = ",
+/* 41 */ "}\n\n",
+/* 42 */ " } else {\n",
+/* 43 */ " }\n",
+/* 44 */ " if(nf) {\n",
+/* 45 */ " }\n",
+/* 46 */ " os = *st;\n",
+/* 47 */ " switch(os) {\n",
+/* 48 */ " case ",
+/* 49 */ ": {\n",
+/* 50 */ " } break;\n",
+/* 51 */ " switch(in) {\n",
+/* 52 */ " }\n",
+/* 53 */ " case ",
+/* 54 */ ": {\n",
+/* 55 */ " nf = 0;\n } break;\n",
+/* 56 */ "ns = ",
+/* 57 */ "os",
+/* 58 */ "; back = ",
+/* 59 */ ";",
+/* 60 */ " if(",
+/* 61 */ ") {\n",
+/* 62 */ "\n } else {\n",
+/* 63 */ " }\n",
+/* 64 */ "os == ",
+/* 65 */ "in == ",
+/* 66 */ "fprintf(",
+/* 67 */ ", \"+ ",
+/* 68 */ "_step state=%d input=%d\\n\", ((st) ? *st : 0), in);\n",
+/* 69 */ ", \"- ",
+/* 70 */ ", L\"+ ",
+/* 71 */ ", L\"- ",
+/* 72 */ "fwprintf(",
+/* 73 */ "\". rule: ",
+/* 74 */ "\\n\"", /* UNUSED */
+/* 75 */ "_step state=%d output=%d\\n\", ((st) ? *st : 0), back);\n",
+/* 76 */ " return back;\n",
+/* 77 */ " *st = ns;\n",
+NULL
+};
+
+
+
+/** Option names.
+*/
+static char const * const dkct_au_option_names[] = {
+/* 0 */ "name",
+/* 1 */ "write-header",
+NULL
+};
+
+
+
+/** Compare two entries by name.
+ @param l Left entry.
+ @param r Right entry.
+ @param cr Comparison critieria (0=struct/struct, 1=struct/name).
+ @return Comparison result.
+*/
+static
+int
+dkct_au_entry_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ DKCT_STM_ENTRY const *pl; /* Left object pointer. */
+ DKCT_STM_ENTRY const *pr; /* Right object pointer. */
+ if(l) {
+ if(r) {
+ pl = (DKCT_STM_ENTRY const *)l;
+ pr = (DKCT_STM_ENTRY const *)r;
+ switch(cr) {
+ case 1: {
+ if(pl->name) {
+ back = dk3str_c8_cmp(pl->name, (char const *)r);
+ } else {
+ back = -1;
+ }
+ } break;
+ default: {
+ if(pl->name) {
+ if(pr->name) {
+ back = dk3str_c8_cmp(pl->name, pr->name);
+ } else {
+ back = 1;
+ }
+ } else {
+ if(pr->name) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+ if(back < -1) back = -1;
+ if(back > 1) back = 1;
+ return back;
+}
+
+
+
+/** Delete entry.
+ @param p Entry to delete.
+*/
+static
+void
+dkct_au_entry_delete(DKCT_STM_ENTRY *p)
+{
+ if(p) {
+
+#line 231 "dkct-au.ctr"
+ dk3_release(p->name);
+ dk3_release(p->comment);
+ p->lineno = 0UL; p->value = 0; p->flag = 0x00;
+ dk3_delete(p);
+ }
+}
+
+
+
+/** Create entry.
+ @param name Entry name.
+ @param comment Comment.
+ @param lineno Line number in source file.
+ @param value Numeric value (if specified).
+ @param flag Flag: Use value.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new entry on success, NULL on error.
+*/
+DKCT_STM_ENTRY *
+dkct_au_entry_new(
+ char const *name,
+ char const *comment,
+ unsigned long lineno,
+ int value,
+ int flag,
+ dk3_app_t *app
+)
+{
+ DKCT_STM_ENTRY *back = NULL;
+
+
+#line 261 "dkct-au.ctr"
+ if(name) {
+ back = dk3_new_app(DKCT_STM_ENTRY,1,app);
+ if(back) {
+ back->flag = ((flag)? 0x01 : 0x00);
+ back->value = value;
+ back->lineno = lineno;
+ back->name = dk3str_c8_dup_app(name,app);
+ back->comment = NULL;
+ if(back->name) {
+ if(comment) {
+ back->comment = dk3str_c8_dup_app(comment,app);
+ if(!(back->comment)) {
+ dkct_au_entry_delete(back);
+ back = NULL;
+ }
+ }
+ } else {
+ dkct_au_entry_delete(back);
+ back = NULL;
+ }
+ }
+ }
+
+#line 283 "dkct-au.ctr"
+ return back;
+}
+
+
+
+/** Compare two rules, either by state+input or by line number.
+ @param l Left rule.
+ @param r Right rule.
+ @param cr Comparison criteria (0=line,
+ DKCT_AU_RULE_SORT_STATE_INPUT=state+input).
+ @return Comparison result.
+*/
+static
+int
+dkct_au_rule_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ DKCT_STM_RULE const *pl; /* Left rule pointer. */
+ DKCT_STM_RULE const *pr; /* Right rule pointer. */
+ if(l) {
+ if(r) {
+ pl = (DKCT_STM_RULE const *)l;
+ pr = (DKCT_STM_RULE const *)r;
+ switch(cr & (~(DKCT_AU_RULE_SORT_REVERSE))) {
+ case DKCT_AU_RULE_SORT_STATE_INPUT: {
+ /*
+ First sort by states.
+ */
+ if(pl->state) {
+ if(pr->state) {
+ if((pl->state)->name) {
+ if((pr->state)->name) {
+ back = dk3str_c8_cmp((pl->state)->name, (pr->state)->name);
+ } else {
+ back = 1;
+ }
+ } else {
+ if((pr->state)->name) {
+ back = -1;
+ }
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(pr->state) {
+ back = -1;
+ }
+ }
+ /*
+ For equal states sort by input.
+ */
+ if(back == 0) {
+ if(pl->input) {
+ if(pr->input) {
+ if((pl->input)->name) {
+ if((pr->input)->name) {
+ back = dk3str_c8_cmp((pl->input)->name, (pr->input)->name);
+ } else {
+ back = 1;
+ }
+ } else {
+ if((pr->input)->name) {
+ back = -1;
+ }
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(pr->input) {
+ back = -1;
+ }
+ }
+ }
+ } break;
+ default: {
+ /*
+ Simply sort by line number.
+ */
+ if(pl->lineno > pr->lineno) { back = 1; }
+ else {
+ if(pl->lineno < pr->lineno) { back = -1; }
+ }
+ } break;
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+ if(back < -1) { back = -1; }
+ if(back > 1) { back = 1; }
+ if(cr & DKCT_AU_RULE_SORT_REVERSE) {
+ switch(back) {
+ case 1: { back = -1; } break;
+ case -1: { back = 1; } break;
+ }
+ }
+ return back;
+}
+
+
+
+/** Delete rule.
+ @param rp Rule to delete.
+*/
+void
+dkct_au_rule_delete(DKCT_STM_RULE *rp)
+{
+ if(rp) {
+
+#line 397 "dkct-au.ctr"
+ rp->state = NULL;
+ rp->input = NULL;
+ rp->newstate = NULL;
+ rp->output = NULL;
+ rp->lineno = 0UL;
+ dk3_delete(rp);
+ }
+}
+
+
+
+/** Create rule.
+ @param os Old state.
+ @param in Input.
+ @param ns New state.
+ @param out Output.
+ @param lineno Line number in source file.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new element on success, NULL on error.
+*/
+DKCT_STM_RULE *
+dkct_au_rule_new(
+ DKCT_STM_ENTRY *os,
+ DKCT_STM_ENTRY *in,
+ DKCT_STM_ENTRY *ns,
+ DKCT_STM_ENTRY *out,
+ unsigned long lineno,
+ dk3_app_t *app
+)
+{
+ DKCT_STM_RULE *back = NULL;
+ int ok = 1; /* Flag: No errors occured. */
+
+
+#line 430 "dkct-au.ctr"
+ back = dk3_new_app(DKCT_STM_RULE,1,app);
+ if(back) {
+ back->state = os;
+ back->input = in;
+ back->newstate = ns;
+ back->output = out;
+ back->lineno = lineno;
+ if(!(ok)) {
+ dkct_au_rule_delete(back);
+ back = NULL;
+ }
+ }
+
+#line 442 "dkct-au.ctr"
+ return back;
+}
+
+
+
+/** Delete all rules in a storage.
+ @param s Storage containing the rules.
+ @param i Iterator for storage.
+*/
+static
+void
+dkct_au_stm_rules_delete(dk3_sto_t *s, dk3_sto_it_t *i)
+{
+ DKCT_STM_RULE *r; /* Current rule to delete. */
+
+
+#line 457 "dkct-au.ctr"
+ if(s) {
+ if(i) {
+ dk3sto_it_reset(i);
+ while((r = (DKCT_STM_RULE *)dk3sto_it_next(i)) != NULL) {
+ dkct_au_rule_delete(r);
+ }
+ dk3sto_it_close(i);
+ }
+ dk3sto_close(s);
+ }
+
+#line 467 "dkct-au.ctr"
+}
+
+
+
+/** Delete all entries in a storage.
+ @param s Storage containing the entries.
+ @param i Iterator for storage.
+*/
+static
+void
+dkct_au_stm_entries_delete(dk3_sto_t *s, dk3_sto_it_t *i)
+{
+ DKCT_STM_ENTRY *e; /* Current entry to delete. */
+
+
+#line 481 "dkct-au.ctr"
+ if(s) {
+ if(i) {
+ dk3sto_it_reset(i);
+ while((e = (DKCT_STM_ENTRY *)dk3sto_it_next(i)) != NULL) {
+ dkct_au_entry_delete(e);
+ }
+ dk3sto_it_close(i);
+ }
+ dk3sto_close(s);
+ }
+
+#line 491 "dkct-au.ctr"
+}
+
+
+
+/** Delete a state machine description.
+ @param p State machine to delete.
+*/
+void
+dkct_au_stm_delete(DKCT_STM *p)
+{
+
+
+#line 502 "dkct-au.ctr"
+ if(p) {
+ dkct_au_stm_rules_delete(p->s_wildcard, p->i_wildcard);
+ dkct_au_stm_rules_delete(p->s_exact, p->i_exact);
+ dkct_au_stm_entries_delete(p->s_states, p->i_states);
+ dkct_au_stm_entries_delete(p->s_inputs, p->i_inputs);
+ dkct_au_stm_entries_delete(p->s_outputs, p->i_outputs);
+ p->s_wildcard = NULL; p->i_wildcard = NULL;
+ p->s_exact = NULL; p->i_exact = NULL;
+ p->s_states = NULL; p->i_states = NULL;
+ p->s_outputs = NULL; p->i_outputs = NULL;
+ p->s_inputs = NULL; p->i_inputs = NULL;
+ dk3_release(p->name);
+ p->lineno = 0UL;
+ p->wrh = 0;
+ p->rs = NULL;
+ p->ds = NULL;
+ p->dout = NULL;
+ p->lngr = 0UL;
+ dk3_delete(p);
+ }
+
+#line 522 "dkct-au.ctr"
+}
+
+
+
+/** Create new state machine description.
+ @param lineno Line number in source file.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new structure on success, NULL on error.
+*/
+DKCT_STM *
+dkct_au_stm_new(unsigned long lineno, dk3_app_t *app)
+{
+ DKCT_STM *back = NULL;
+ int ok = 0; /* Flag: Successfully initialized. */
+
+
+#line 537 "dkct-au.ctr"
+ back = dk3_new_app(DKCT_STM,1,app);
+ if(back) {
+ back->s_wildcard = NULL; back->i_wildcard = NULL;
+ back->s_exact = NULL; back->i_exact = NULL;
+ back->s_states = NULL; back->i_states = NULL;
+ back->s_outputs = NULL; back->i_outputs = NULL;
+ back->s_inputs = NULL; back->i_inputs = NULL;
+ back->name = NULL;
+ back->lineno = lineno;
+ back->wrh = 1;
+ back->section = DKCT_AU_SECTION_OPTIONS;
+ back->rs = NULL;
+ back->ds = NULL;
+ back->dout = NULL;
+ back->lngr = 0UL;
+ back->stmno = 0UL;
+ back->s_states = dk3sto_open_app(app);
+ back->s_inputs = dk3sto_open_app(app);
+ back->s_outputs = dk3sto_open_app(app);
+ back->s_exact = dk3sto_open_app(app);
+ back->s_wildcard = dk3sto_open_app(app);
+ if(back->s_states) { back->i_states = dk3sto_it_open(back->s_states); }
+ if(back->s_inputs) { back->i_inputs = dk3sto_it_open(back->s_inputs); }
+ if(back->s_outputs) { back->i_outputs = dk3sto_it_open(back->s_outputs); }
+ if(back->s_exact) { back->i_exact = dk3sto_it_open(back->s_exact); }
+ if(back->s_wildcard) { back->i_wildcard= dk3sto_it_open(back->s_wildcard); }
+ if((back->s_states) && (back->s_inputs) && (back->s_outputs)) {
+ dk3sto_set_comp(back->s_states, dkct_au_entry_compare, 0);
+ dk3sto_set_comp(back->s_inputs, dkct_au_entry_compare, 0);
+ dk3sto_set_comp(back->s_outputs, dkct_au_entry_compare, 0);
+ if((back->s_exact) && (back->s_wildcard)) {
+ dk3sto_set_comp(
+ back->s_exact, dkct_au_rule_compare, DKCT_AU_RULE_SORT_STATE_INPUT
+ );
+ dk3sto_set_comp(back->s_wildcard, dkct_au_rule_compare, 0);
+ if((back->i_states) && (back->i_inputs) && (back->i_outputs)) {
+ if((back->i_exact) && (back->i_wildcard)) {
+ ok = 1;
+ }
+ }
+ }
+ }
+ if(!(ok)) {
+ dkct_au_stm_delete(back);
+ back = NULL;
+ }
+ }
+
+#line 584 "dkct-au.ctr"
+ return back;
+}
+
+
+
+/** Process one option line.
+ @param stm State machine description.
+ @param psrc Source structure.
+ @param line Text line.
+ @param lineno Line number of current line.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_au_add_option(
+ DKCT_STM *stm, DKCT_SRC *psrc, char *line, unsigned long lineno
+)
+{
+ int back = 0;
+ char *p1; /* Key (option name). */
+ char *p2; /* Value. */
+ int ai; /* Array index of option name. */
+
+
+#line 607 "dkct-au.ctr"
+ p1 = dk3str_c8_start(line, NULL);
+ if(p1) {
+ p2 = dk3str_c8_chr(p1, '=');
+ if(p2) {
+ *(p2++) = '\0';
+ p2 = dk3str_c8_start(p2, NULL);
+ if(p2) {
+ dk3str_c8_normalize(p1, NULL, '-');
+ ai = dk3str_c8_array_index(dkct_au_option_names, p1, 0);
+ switch(ai) {
+ case 0: {
+
+#line 618 "dkct-au.ctr"
+ if(stm->name) {
+ /* Warning: Redefinition of name */
+ dkct_to_log_1(psrc, 1, DK3_LL_WARNING, 28);
+ dk3_release(stm->name);
+ }
+ stm->name = dk3str_c8_dup_app(p2, psrc->app);
+ if(stm->name) {
+ back = 1;
+ } else {
+ /* ERROR: Memory */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 29);
+ }
+ } break;
+ case 1: {
+
+#line 632 "dkct-au.ctr"
+ if(dk3str_c8_is_bool(p2)) {
+ stm->wrh = (dk3str_c8_is_on(p2) ? 1 : 0);
+ back = 1;
+ } else {
+ /* ERROR: Syntax (not boolean)! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 30);
+ }
+ } break;
+ default: {
+ dkct_to_log_3(psrc, 1, DK3_LL_ERROR, 10, 11, p1);
+ } break;
+ }
+ } else {
+ /* ERROR: No value. */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 9);
+ }
+ } else {
+ /* Syntax */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 9);
+ }
+ }
+
+
+#line 654 "dkct-au.ctr"
+ return back;
+}
+
+
+
+/** Add an entry to storage.
+ @param stm State machine description.
+ @param psrc Source structure.
+ @param line Input line to process.
+ @param co Comment for entry.
+ @param lineno Line number of input line.
+ @param storage Storage for entry.
+ @param iterator Iterator for storage.
+ @param tp Entry type (0=state, 1=input, 2=output).
+ @return 1 on success, 0 on error.
+
+*/
+static
+int
+dkct_au_add_entry(
+ DKCT_STM *stm,
+ DKCT_SRC *psrc,
+ char *line,
+ char *co,
+ unsigned long lineno,
+ dk3_sto_t *storage,
+ dk3_sto_it_t *iterator,
+ int tp
+)
+{
+ int back = 0;
+ char *nptr; /* Entry name. */
+ char *vptr; /* Value (if any). */
+ DKCT_STM_ENTRY *e; /* New entry. */
+ DKCT_STM_ENTRY *ep; /* Search result. */
+ int i; /* Value (if defined). */
+ int f; /* Flag: Value defined. */
+
+
+#line 692 "dkct-au.ctr"
+ nptr = vptr = NULL;
+ i = f = 0;
+ nptr = dk3str_c8_start(line, NULL);
+ if(nptr) {
+ vptr = dk3str_c8_next(nptr, NULL);
+ back = 1;
+ if(vptr) {
+ if(sscanf(vptr, "%d", &i) == 1) {
+ f = 1;
+ } else {
+ back = 0;
+ /* ERROR: Syntax */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 31);
+ }
+ }
+ if(back) {
+ back = 0;
+ e = dkct_au_entry_new(
+ nptr, co, lineno, i, f, psrc->app
+ );
+ if(e) {
+ ep = (DKCT_STM_ENTRY *)dk3sto_it_find_like(iterator, (void *)e, 0);
+ if(ep) {
+ /* ERROR: Redefinition */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 32);
+ dkct_au_entry_delete(e);
+ } else {
+ if(dk3sto_add(storage, (void *)e)) {
+ back = 1;
+ switch(tp) {
+ case 0: {
+ /*
+ First state is reset state.
+ */
+ if(!(stm->rs)) { stm->rs = e; }
+ /*
+ First state is general rule next state default.
+ */
+ if(!(stm->ds)) { stm->ds = e; }
+ } break;
+ case 2: {
+ /*
+ First output is general rule output default.
+ */
+ if(!(stm->dout)) { stm->dout = e; }
+ } break;
+ }
+ } else {
+ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 29);
+ dkct_au_entry_delete(e);
+ }
+ }
+ } else {
+ /* ERROR Memory */
+ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 29);
+ }
+ }
+ } else {
+ /* ERROR: Syntax */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 33);
+ }
+
+#line 753 "dkct-au.ctr"
+ return back;
+}
+
+
+
+/** Find named entry in storage.
+ @param psrc Source structure.
+ @param sto Storage.
+ @param ist Storage iterator.
+ @param name Name of entry to find.
+ @param ok Pointer to not-found-is-ok variable.
+ @param t Type (0=state, 1=input, 2=output).
+ @param lineno Line number.
+ @return Pointer to found entry on success, NULL on error.
+*/
+static
+DKCT_STM_ENTRY *
+dkct_au_find_entry(
+ DKCT_SRC *psrc,
+ dk3_sto_t *sto,
+ dk3_sto_it_t *ist,
+ char *name,
+ unsigned long lineno,
+ int *ok,
+ int t
+)
+{
+ DKCT_STM_ENTRY *back = NULL;
+ if(dk3str_c8_cmp(dkct_au_kw8[0], name) == 0) {
+ *ok = 1;
+ } else {
+ back = (DKCT_STM_ENTRY *)dk3sto_it_find_like(ist, name, 1);
+ if(!(back)) {
+ /* Warning: State/input/output undeclared! */
+ dkct_to_log_3(psrc, 1, DK3_LL_WARNING, 34, 35, name);
+ back = dkct_au_entry_new(name, NULL, lineno, 0, 0, psrc->app);
+ if(back) {
+ if(!dk3sto_add(sto, (void *)back)) {
+ dkct_au_entry_delete(back);
+ back = NULL;
+ }
+ } else {
+ /* ERROR: Failed to create entry! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 29);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Add rule to state machine.
+ @param stm State machine description.
+ @param psrc Source structure.
+ @param line Input line to process.
+ @param co Comment for rule.
+ @param lineno Current line number.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_au_add_rule(
+ DKCT_STM *stm, DKCT_SRC *psrc, char *line, char *co, unsigned long lineno
+)
+{
+ int back = 0;
+ DKCT_STM_RULE tr; /* Test rul. */
+ DKCT_STM_RULE *nr; /* New rule. */
+ char *p1; /* Old state. */
+ char *p2; /* Input. */
+ char *p3; /* New state. */
+ char *p4; /* Output. */
+ DKCT_STM_ENTRY *e1; /* Old state. */
+ DKCT_STM_ENTRY *e2; /* Input. */
+ DKCT_STM_ENTRY *e3; /* New state. */
+ DKCT_STM_ENTRY *e4; /* Output. */
+ int ok1; /* Flag: Old state *. */
+ int ok2; /* Flag: Input *. */
+ int ok3; /* Flag: New state *. */
+ int ok4; /* Flag: Output *. */
+ int can_add; /* Flag: Rule ok, add. */
+
+
+#line 836 "dkct-au.ctr"
+ e1 = e2 = e3 = e4 = NULL; ok1 = ok2 = ok3 = ok4 = 0;
+ p1 = dk3str_c8_start(line, NULL);
+ if(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ if(p2) {
+ p3 = dk3str_c8_next(p2, NULL);
+ if(p3) {
+ p4 = dk3str_c8_next(p3, NULL);
+ if(p4) {
+ (void)dk3str_c8_next(p4, NULL);
+ e1 = dkct_au_find_entry(
+ psrc, stm->s_states, stm->i_states, p1, lineno, &ok1, 0
+ );
+ e2 = dkct_au_find_entry(
+ psrc, stm->s_inputs, stm->i_inputs, p2, lineno, &ok2, 1
+ );
+ e3 = dkct_au_find_entry(
+ psrc, stm->s_states, stm->i_states, p3, lineno, &ok3, 0
+ );
+ e4 = dkct_au_find_entry(
+ psrc, stm->s_outputs, stm->i_outputs, p4, lineno, &ok4, 2
+ );
+ if(
+ ((e1) || (ok1)) && ((e2) || (ok2))
+ && ((e3) || (ok3)) && ((e4) || (ok4))
+ )
+ {
+ can_add = 1;
+ tr.state = e1; tr.input = e2; tr.newstate = e3; tr.output = e4;
+ if((e1) && (e2)) {
+ DKCT_STM_RULE *xrp;
+ if((xrp = (DKCT_STM_RULE *)dk3sto_it_find_like(
+ stm->i_exact, (void *)(&tr),
+ DKCT_AU_RULE_SORT_STATE_INPUT
+ )
+ ) != NULL
+ )
+ {
+ char ulbuffer[32];
+ sprintf(ulbuffer, "%lu", xrp->lineno);
+ can_add = 0;
+ /* ERROR: Conflict! */
+ dkct_to_log_3(psrc, 1, DK3_LL_ERROR, 36, 39, ulbuffer);
+ }
+ }
+ if(can_add) {
+ if((e1) && (e2)) {
+ nr = dkct_au_rule_new(e1, e2, e3, e4, lineno, psrc->app);
+ if(nr) {
+ if(dk3sto_add(stm->s_exact, (void *)nr)) {
+ back = 1;
+ } else {
+ dkct_au_rule_delete(nr);
+ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ /* ERROR: Memory! */
+ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ if((e1) || (e2)) {
+ nr = dkct_au_rule_new(e1, e2, e3, e4, lineno, psrc->app);
+ if(nr) {
+ if(dk3sto_add(stm->s_wildcard, (void *)nr)) {
+ back = 1;
+ } else {
+ dkct_au_rule_delete(nr);
+ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ /* ERROR: Memory! */
+ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ back = 1;
+ if(stm->lngr) {
+ char buffer[32];
+ sprintf(buffer, "%lu", stm->lngr);
+ /* Warning: General rule redefined! */
+ dkct_to_log_3(psrc, 1, DK3_LL_ERROR, 36, 39, buffer);
+ }
+ stm->ds = e3;
+ stm->dout = e4;
+ stm->lngr = lineno;
+ }
+ }
+ }
+ } else {
+ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 33);
+ }
+ } else {
+ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 33);
+ }
+ } else {
+ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 33);
+ }
+ }
+
+
+#line 937 "dkct-au.ctr"
+ return back;
+}
+
+
+
+/** Process one input line.
+ @param stm State machine description.
+ @param psrc Source structure.
+ @param line Line to process.
+ @param lineno Current line number.
+ @return 1 on success, 0 on error.
+*/
+int
+dkct_au_add_line(
+ DKCT_STM *stm, DKCT_SRC *psrc, char *line, unsigned long lineno
+)
+{
+ int back = 0;
+ char *lstart; /* Start of input line. */
+ char *pc; /* Comment pointer. */
+ int ai; /* Array index. */
+
+
+#line 959 "dkct-au.ctr"
+ if((stm) && (line)) {
+
+#line 960 "dkct-au.ctr"
+ lstart = dk3str_c8_start(line, NULL);
+ if(lstart) {
+
+#line 962 "dkct-au.ctr"
+ pc = NULL;
+ if(*lstart != '#') {
+
+#line 964 "dkct-au.ctr"
+ if(*lstart == '[') {
+
+#line 965 "dkct-au.ctr"
+ lstart++;
+ lstart = dk3str_c8_start(lstart, NULL);
+ if(lstart) {
+ stm->section = -1;
+ pc = dk3str_c8_chr(lstart, ']');
+ if(pc) {
+ *pc = '\0';
+ dk3str_c8_chomp(lstart, NULL);
+
+#line 973 "dkct-au.ctr"
+ ai = dk3str_c8_array_index(dkct_au_section_names, lstart, 0);
+
+
+#line 975 "dkct-au.ctr"
+ switch(ai) {
+ case 0: case 5: {
+ stm->section = DKCT_AU_SECTION_OPTIONS; back = 1;
+ } break;
+ case 1: case 6: {
+ stm->section = DKCT_AU_SECTION_STATES; back = 1;
+ } break;
+ case 2: case 7: {
+ stm->section = DKCT_AU_SECTION_INPUTS; back = 1;
+ } break;
+ case 3: case 8: {
+ stm->section = DKCT_AU_SECTION_OUTPUTS; back = 1;
+ } break;
+ case 4: case 9: {
+ stm->section = DKCT_AU_SECTION_RULES; back = 1;
+ } break;
+ default: {
+ dkct_to_log_3(psrc, 1, DK3_LL_ERROR, 99, 100, lstart);
+ } break;
+ }
+ } else {
+ /* ERROR: Syntax! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 37);
+ }
+ } else {
+ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 37);
+ }
+ } else {
+
+#line 1003 "dkct-au.ctr"
+ pc = dk3str_c8_chr(lstart, '#');
+ if(pc) { *(pc++) = '\0'; pc = dk3str_c8_start(pc, NULL); }
+ switch(stm->section) {
+ case DKCT_AU_SECTION_OPTIONS: {
+
+#line 1007 "dkct-au.ctr"
+ back = dkct_au_add_option(stm, psrc, lstart, lineno);
+ } break;
+ case DKCT_AU_SECTION_STATES: {
+
+#line 1010 "dkct-au.ctr"
+ back = dkct_au_add_entry(
+ stm, psrc, lstart, pc, lineno, stm->s_states, stm->i_states, 0
+ );
+ } break;
+ case DKCT_AU_SECTION_INPUTS: {
+
+#line 1015 "dkct-au.ctr"
+ back = dkct_au_add_entry(
+ stm, psrc, lstart, pc, lineno, stm->s_inputs, stm->i_inputs, 1
+ );
+ } break;
+ case DKCT_AU_SECTION_OUTPUTS: {
+
+#line 1020 "dkct-au.ctr"
+ back = dkct_au_add_entry(
+ stm, psrc, lstart, pc, lineno, stm->s_outputs, stm->i_outputs, 2
+ );
+ } break;
+ case DKCT_AU_SECTION_RULES: {
+
+#line 1025 "dkct-au.ctr"
+ back = dkct_au_add_rule(stm, psrc, lstart, pc, lineno);
+ } break;
+ }
+ }
+ } else {
+ back = 1; /* comments ok */
+ }
+ } else {
+ back = 1; /* empty lines ok */
+ }
+ }
+
+#line 1036 "dkct-au.ctr"
+ return back;
+}
+
+
+
+/** Check whether there is at least one entry in the storage.
+ @param it Iterator of storage to check.
+ @return 1 on success, 0 on error (storage empty).
+*/
+static
+int
+dkct_au_stm_entries_check(dk3_sto_it_t *it)
+{
+ int back = 0;
+ dk3sto_it_reset(it);
+ if(dk3sto_it_next(it)) {
+ back = 1;
+ }
+ return back;
+}
+
+
+
+/** Assign values to state/input/output storage.
+ @param psrc Source structure.
+ @param stm State machine to modify.
+ @param it Iterator for state/input/output storage.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_au_set_values(DKCT_SRC *psrc, DKCT_STM *stm, dk3_sto_it_t *it)
+{
+ int back = 1;
+ DKCT_STM_ENTRY *ep = NULL; /* Current entry to process. */
+ dk3_bf_t *bf = NULL; /* Bit field, used values. */
+ int min = 0; /* Minimum value so far. */
+ int max = 0; /* Maximum value so far. */
+ int valfound = 0; /* Flag: Values specified. */
+ int cv = 0; /* Current value. */
+ int cc = 0; /* Flag: Continue search. */
+
+
+#line 1078 "dkct-au.ctr"
+ dk3sto_it_reset(it);
+ while((ep = (DKCT_STM_ENTRY *)dk3sto_it_next(it)) != NULL) {
+ if(ep->flag) {
+
+#line 1081 "dkct-au.ctr"
+ if(valfound) {
+
+#line 1082 "dkct-au.ctr"
+ if(ep->value < min) min = ep->value;
+ if(ep->value > max) max = ep->value;
+ } else {
+
+#line 1085 "dkct-au.ctr"
+ min = max = ep->value;
+ }
+ valfound = 1;
+ } else {
+
+#line 1089 "dkct-au.ctr"
+ }
+ }
+ if(valfound) {
+
+#line 1092 "dkct-au.ctr"
+ bf = dk3bf_open_app((max - min + 1), psrc->app);
+ if(bf) {
+ /*
+ Find used values.
+ */
+ dk3sto_it_reset(it);
+ while((ep = (DKCT_STM_ENTRY *)dk3sto_it_next(it)) != NULL) {
+ if(ep->flag) {
+ dk3bf_set(bf, (ep->value - min), 1);
+ }
+ }
+ /*
+ Set missing values.
+ */
+ cv = 0;
+ dk3sto_it_reset(it);
+ while((ep = (DKCT_STM_ENTRY *)dk3sto_it_next(it)) != NULL) {
+ if(!(ep->flag)) {
+ do {
+
+#line 1111 "dkct-au.ctr"
+ cc = 0;
+ if((cv >= min) && (cv <= max)) {
+ if(dk3bf_get(bf, (cv - min))) {
+ cc = 1;
+
+#line 1115 "dkct-au.ctr"
+ cv++;
+ if(cv == 0) {
+
+#line 1117 "dkct-au.ctr"
+ cc = 0;
+ back = 0;
+ /* ERROR: Overflow */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ } while(cc);
+ cc = 0;
+ if((cv >= min) && (cv <= max)) {
+ if(!dk3bf_get(bf, (cv - min))) {
+ cc = 1;
+ }
+ } else {
+ cc = 1;
+ }
+ if(cc) {
+
+#line 1134 "dkct-au.ctr"
+ ep->value = cv++;
+ if(cv == 0) {
+
+#line 1136 "dkct-au.ctr"
+ back = 0;
+ /* ERROR: Overflow */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ }
+ dk3bf_close(bf);
+ } else {
+
+#line 1145 "dkct-au.ctr"
+ back = 0;
+ /* ERROR: Memory */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 29);
+ }
+ } else {
+
+#line 1150 "dkct-au.ctr"
+ cv = 0;
+ dk3sto_it_reset(it);
+ while((ep = (DKCT_STM_ENTRY *)dk3sto_it_next(it)) != NULL) {
+ ep->value = cv++;
+ if(cv == 0) {
+
+#line 1155 "dkct-au.ctr"
+ back = 0;
+ /* ERROR: Overflow */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+
+#line 1161 "dkct-au.ctr"
+ return back;
+}
+
+
+
+int
+dkct_au_stm_check(DKCT_SRC *psrc, DKCT_STM *stm)
+{
+ int back = 0;
+ int sfound = 0; /* Number of states found. */
+ int ifound = 0; /* Number of inputs found. */
+ int ofound = 0; /* Number of outputs found. */
+
+ dk3app_set_source_line(psrc->app, stm->lineno);
+ sfound = dkct_au_stm_entries_check(stm->i_states);
+ ifound = dkct_au_stm_entries_check(stm->i_inputs);
+ ofound = dkct_au_stm_entries_check(stm->i_outputs);
+ if((sfound) && (ifound) && (ofound)) {
+ back = 1;
+ if(!dkct_au_set_values(psrc, stm, stm->i_states)) { back = 0; }
+ if(!dkct_au_set_values(psrc, stm, stm->i_inputs)) { back = 0; }
+ if(!dkct_au_set_values(psrc, stm, stm->i_outputs)) { back = 0; }
+ } else {
+ if(!(sfound)) {
+ /* ERROR: No states declared! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 40);
+ }
+ if(!(ifound)) {
+ /* ERROR: No inputs declared! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 41);
+ }
+ if(!(ofound)) {
+ /* ERROR: No outputs declared! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 42);
+ }
+ }
+ return back;
+}
+
+
+
+/** Write definition for one storage entry.
+ @param psrc Source structure.
+ @param stm State machine.
+ @param ep Entry to write
+ @param commi Keyword index for "state", "input", or "output".
+*/
+static
+void
+dkct_au_write_one_entry(
+ DKCT_SRC *psrc, DKCT_STM *stm, DKCT_STM_ENTRY *ep, size_t commi
+)
+{
+
+
+#line 1215 "dkct-au.ctr"
+ fputs(dkct_au_kw8[3], psrc->fipo);
+ fputs(ep->name, psrc->fipo);
+ fputs(dkct_au_kw8[1], psrc->fipo);
+ fputs(dkct_au_kw8[11], psrc->fipo);
+ fputs(dkct_au_kw8[commi], psrc->fipo);
+ if(ep->comment) {
+ fputs(ep->comment, psrc->fipo);
+ } else {
+ fputs(ep->name, psrc->fipo);
+ }
+ fputs(dkct_au_kw8[12], psrc->fipo);
+ if((psrc->dkcto).lnn) {
+ psrc->lineno = ep->lineno;
+ dkct_tr_show_source_line(psrc, 0);
+ }
+ fputs(dkct_au_kw8[6], psrc->fipo);
+ fputs(ep->name, psrc->fipo);
+ fprintf(psrc->fipo, dkct_au_kw8[(ep->value >= 0) ? 9 : 10], ep->value);
+ fputs(dkct_au_kw8[4], psrc->fipo); /* else */
+ if((psrc->dkcto).lnn) {
+ psrc->lineno = ep->lineno;
+ dkct_tr_show_source_line(psrc, 0);
+ }
+ fputs(dkct_au_kw8[7], psrc->fipo);
+ fputs(ep->name, psrc->fipo);
+ fputs(dkct_au_kw8[8], psrc->fipo);
+ fputs(dkct_au_kw8[5], psrc->fipo); /* endif */
+
+
+#line 1243 "dkct-au.ctr"
+}
+
+
+
+/** Write all entries of a storage.
+ @param psrc Source structure.
+ @param stm State machine.
+ @param it Storage iterator.
+ @param commi Keyword index for "state", "input", or "output".
+*/
+static
+void
+dkct_au_write_entry_storage(
+ DKCT_SRC *psrc, DKCT_STM *stm, dk3_sto_it_t *it, size_t commi
+)
+{
+ DKCT_STM_ENTRY *ep; /* Current entry. */
+
+
+#line 1261 "dkct-au.ctr"
+ dk3sto_it_reset(it);
+ while((ep = (DKCT_STM_ENTRY *)dk3sto_it_next(it)) != NULL) {
+ dkct_au_write_one_entry(psrc, stm, ep, commi);
+ }
+
+#line 1265 "dkct-au.ctr"
+}
+
+
+
+/** Write state machine name to output file.
+ @param psrc Source structure.
+ @param stm State machine.
+*/
+static
+void
+dkct_au_write_stm_name(DKCT_SRC *psrc, DKCT_STM *stm)
+{
+ if(stm->name) {
+ fputs(stm->name, psrc->fipo);
+ } else {
+ fprintf(psrc->fipo, dkct_au_kw8[16], stm->stmno);
+ }
+}
+
+
+
+/** Write state/input/output entry definitions.
+ @param psrc Source structure.
+ @param stm State machine.
+*/
+void
+dkct_au_write_entries(DKCT_SRC *psrc, DKCT_STM *stm)
+{
+ /*
+ Begin doxygen group
+ */
+ fputs(dkct_au_kw8[17], psrc->fipo);
+ dkct_au_write_stm_name(psrc, stm);
+ fputs(dkct_au_kw8[18], psrc->fipo);
+ dkct_au_write_stm_name(psrc, stm);
+ fputs(dkct_au_kw8[19], psrc->fipo);
+ /*
+ Write the entries
+ */
+ dkct_au_write_entry_storage(psrc, stm, stm->i_states, 13);
+ dkct_au_write_entry_storage(psrc, stm, stm->i_inputs, 14);
+ dkct_au_write_entry_storage(psrc, stm, stm->i_outputs, 15);
+ /*
+ End doxygen group
+ */
+ fputs(dkct_au_kw8[20], psrc->fipo);
+}
+
+
+
+void
+dkct_au_write_prototypes(DKCT_SRC *psrc, DKCT_STM *stm)
+{
+ fputs(dkct_au_kw8[21], psrc->fipo);
+ fputs(dkct_au_kw8[23], psrc->fipo);
+ dkct_au_write_stm_name(psrc, stm);
+ fputs(dkct_au_kw8[24], psrc->fipo);
+ fputs(dkct_au_kw8[25], psrc->fipo);
+ fputs(dkct_au_kw8[26], psrc->fipo);
+ dkct_au_write_stm_name(psrc, stm);
+ fputs(dkct_au_kw8[27], psrc->fipo);
+ fputs(dkct_au_kw8[28], psrc->fipo);
+ dkct_au_write_stm_name(psrc, stm);
+ fputs(dkct_au_kw8[29], psrc->fipo);
+ fputs(dkct_au_kw8[30], psrc->fipo);
+ fputs(dkct_au_kw8[37], psrc->fipo);
+ dkct_au_write_stm_name(psrc, stm);
+ fputs(dkct_au_kw8[31], psrc->fipo);
+ fputs(dkct_au_kw8[22], psrc->fipo);
+}
+
+
+
+/** Write a transition result.
+ @param psrc Source structure.
+ @param stm State machine.
+ @param rp Rule.
+ @param indent Level of indent.
+*/
+static
+void
+dkct_au_write_transition_result(
+ DKCT_SRC *psrc, DKCT_STM *stm, DKCT_STM_RULE *rp, int indent
+)
+{
+ int i; /* Number of indent spaces already written. */
+ /* DEBUG CODE IF -d */
+ for(i = 0; i < indent; i++) { fputc(' ', psrc->fipo); }
+ fputs(dkct_au_kw8[56], psrc->fipo);
+ if(rp->newstate) {
+ fputs((rp->newstate)->name, psrc->fipo);
+ } else {
+ fputs(dkct_au_kw8[57], psrc->fipo);
+ }
+ fputs(dkct_au_kw8[58], psrc->fipo);
+ if(rp->output) {
+ fputs((rp->output)->name, psrc->fipo);
+ } else {
+ if(stm->dout) {
+ fputs((stm->dout)->name, psrc->fipo);
+ } else {
+ fputs(dkct_au_kw8[36], psrc->fipo);
+ }
+ }
+ fputs(dkct_au_kw8[59], psrc->fipo);
+}
+
+
+
+/** Create debug code for entering and leaving the
+ transition function.
+ @param psrc Source structure.
+ @param stm State machine.
+ @param pos Position (0=invokation, 1=return).
+*/
+static
+void
+dkct_au_debug_transition(DKCT_SRC *psrc, DKCT_STM *stm, int pos)
+{
+ char const *fnptr; /* Debug output file. */
+
+ fnptr = dkct_tr_get_kw8(((psrc->dkcto).deb == 2) ? 28 : 29);
+ fputs(dkct_tr_get_kw8(67), psrc->fipo);
+ if((psrc->dkcto).win) {
+ fputs(dkct_tr_get_kw8(21), psrc->fipo);
+ /* char 16 start */
+ psrc->lineno = stm->lineno;
+ fputs(dkct_tr_get_kw8(61), psrc->fipo);
+ dkct_tr_show_filename_and_lineno(psrc);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+
+ fputs(dkct_au_kw8[72], psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_au_kw8[(pos == 1) ? 71 : 70], psrc->fipo);
+ dkct_au_write_stm_name(psrc, stm);
+ fputs(dkct_au_kw8[(pos == 1) ? 75 : 68], psrc->fipo);
+
+ fputs(dkct_tr_get_kw8(37), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ /* char 16 end */
+ fputs(dkct_tr_get_kw8(22), psrc->fipo);
+ }
+ /* char 8 start */
+ if((psrc->dkcto).deb == 1) {
+ fputs(dkct_tr_get_kw8(30), psrc->fipo);
+ }
+ psrc->lineno = stm->lineno;
+ fputs(dkct_tr_get_kw8(33), psrc->fipo);
+ dkct_tr_show_filename_and_lineno(psrc);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+
+ fputs(dkct_au_kw8[66], psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_au_kw8[(pos == 1) ? 69 : 67], psrc->fipo);
+ dkct_au_write_stm_name(psrc, stm);
+ fputs(dkct_au_kw8[(pos == 1) ? 75 : 68], psrc->fipo);
+
+ fputs(dkct_tr_get_kw8(37), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ if((psrc->dkcto).deb == 1) {
+ fputs(dkct_tr_get_kw8(31), psrc->fipo);
+ }
+ /* char 8 end */
+ if((psrc->dkcto).win) {
+ fputs(dkct_tr_get_kw8(23), psrc->fipo);
+ }
+ fputs(dkct_tr_get_kw8(25), psrc->fipo);
+}
+
+
+
+/** Write debug output to show the matching rule.
+ @param psrc Source structure.
+ @param stm State machine.
+ @param rp Rule to show.
+*/
+static
+void
+dkct_au_debug_matching_rule(
+ DKCT_SRC *psrc, DKCT_STM *stm, DKCT_STM_RULE *rp
+)
+{
+ char const *fnptr; /* Debug output file. */
+ char const *p1; /* Current state. */
+ char const *p2; /* Input. */
+ char const *p3; /* Next state. */
+ char const *p4; /* Output. */
+
+ if((psrc->dkcto).deb) {
+ p1 = p2 = p3 = p4 = dkct_au_kw8[0];
+ if(rp) {
+ if(rp->state) { p1 = (rp->state)->name; }
+ if(rp->input) { p2 = (rp->input)->name; }
+ if(rp->newstate) { p3 = (rp->newstate)->name; }
+ if(rp->output) { p4 = (rp->output)->name; }
+ } else {
+ if(stm->ds) { p3 = (stm->ds)->name; }
+ if(stm->dout) { p4 = (stm->dout)->name; }
+ }
+ fnptr = dkct_tr_get_kw8(((psrc->dkcto).deb == 2) ? 28 : 29);
+ psrc->lineno = stm->lineno;
+ if(rp) { psrc->lineno = rp->lineno; }
+ fputs(dkct_tr_get_kw8(67), psrc->fipo);
+ if((psrc->dkcto).win) {
+ fputs(dkct_tr_get_kw8(21), psrc->fipo);
+ /* char 16 start */
+ if((psrc->dkcto).deb == 1) {
+ fputs(dkct_tr_get_kw8(30), psrc->fipo);
+ }
+ fputs(dkct_tr_get_kw8(61), psrc->fipo);
+ dkct_tr_show_filename_and_lineno(psrc);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ fputs(dkct_tr_get_kw8(61), psrc->fipo);
+ fputs(dkct_au_kw8[73], psrc->fipo);
+ fputs(dkct_au_kw8[2], psrc->fipo);
+ fputs(p1, psrc->fipo);
+ fputs(dkct_au_kw8[2], psrc->fipo);
+ fputs(p2, psrc->fipo);
+ fputs(dkct_au_kw8[2], psrc->fipo);
+ fputs(p3, psrc->fipo);
+ fputs(dkct_au_kw8[2], psrc->fipo);
+ fputs(p4, psrc->fipo);
+ fputs(dkct_au_kw8[74], psrc->fipo);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ fputs(dkct_tr_get_kw8(37), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ if((psrc->dkcto).deb == 1) {
+ fputs(dkct_tr_get_kw8(31), psrc->fipo);
+ }
+ /* char 16 end */
+ fputs(dkct_tr_get_kw8(22), psrc->fipo);
+ }
+ /* char 8 start */
+ if((psrc->dkcto).deb == 1) {
+ fputs(dkct_tr_get_kw8(30), psrc->fipo);
+ }
+ fputs(dkct_tr_get_kw8(33), psrc->fipo);
+ dkct_tr_show_filename_and_lineno(psrc);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+
+ fputs(dkct_tr_get_kw8(33), psrc->fipo);
+ fputs(dkct_au_kw8[73], psrc->fipo);
+ fputs(dkct_au_kw8[2], psrc->fipo);
+ fputs(p1, psrc->fipo);
+ fputs(dkct_au_kw8[2], psrc->fipo);
+ fputs(p2, psrc->fipo);
+ fputs(dkct_au_kw8[2], psrc->fipo);
+ fputs(p3, psrc->fipo);
+ fputs(dkct_au_kw8[2], psrc->fipo);
+ fputs(p4, psrc->fipo);
+ fputs(dkct_au_kw8[74], psrc->fipo);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+
+ fputs(dkct_tr_get_kw8(37), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ if((psrc->dkcto).deb == 1) {
+ fputs(dkct_tr_get_kw8(31), psrc->fipo);
+ }
+
+ /* char 8 end */
+ if((psrc->dkcto).win) {
+ fputs(dkct_tr_get_kw8(23), psrc->fipo);
+ }
+ fputs(dkct_tr_get_kw8(25), psrc->fipo);
+ }
+}
+
+
+
+void
+dkct_au_write_functions(DKCT_SRC *psrc, DKCT_STM *stm, int f_static)
+{
+ DKCT_STM_ENTRY *prevstate; /* Current state. */
+ DKCT_STM_RULE *rp; /* Rule to process. */
+ unsigned long nwildcards; /* Number of wildcards. */
+ unsigned long i; /* Current wildcard block to finish. */
+ /*
+ Reset function.
+ */
+ if(f_static) {
+ fputs(dkct_au_kw8[23], psrc->fipo);
+ dkct_au_write_stm_name(psrc, stm);
+ fputs(dkct_au_kw8[24], psrc->fipo);
+ fputs(dkct_au_kw8[25], psrc->fipo);
+ fputs(dkct_au_kw8[32], psrc->fipo);
+ }
+ fputs(dkct_au_kw8[33], psrc->fipo);
+ dkct_au_write_stm_name(psrc, stm);
+ fputs(dkct_au_kw8[34], psrc->fipo);
+ if(stm->rs) {
+ fputs((stm->rs)->name, psrc->fipo);
+ } else {
+ fputs(dkct_au_kw8[36], psrc->fipo);
+ }
+ fputs(dkct_au_kw8[35], psrc->fipo);
+ /*
+ Transition function.
+ */
+ if(f_static) {
+ fputs(dkct_au_kw8[28], psrc->fipo);
+ dkct_au_write_stm_name(psrc, stm);
+ fputs(dkct_au_kw8[29], psrc->fipo);
+ fputs(dkct_au_kw8[30], psrc->fipo);
+ fputs(dkct_au_kw8[32], psrc->fipo);
+ }
+ fputs(dkct_au_kw8[37], psrc->fipo);
+ dkct_au_write_stm_name(psrc, stm);
+ fputs(dkct_au_kw8[38], psrc->fipo);
+ if(stm->dout) {
+ fputs((stm->dout)->name, psrc->fipo);
+ } else {
+ fputs(dkct_au_kw8[36], psrc->fipo);
+ }
+ fputs(dkct_au_kw8[39], psrc->fipo);
+ if((psrc->dkcto).deb) {
+ /* Debug messages for entering function */
+ dkct_au_debug_transition(psrc, stm, 0);
+ }
+ fputs(dkct_au_kw8[40], psrc->fipo);
+ if(stm->ds) {
+ fputs((stm->ds)->name, psrc->fipo);
+ } else {
+ fputs(dkct_au_kw8[36], psrc->fipo);
+ }
+ fputs(dkct_au_kw8[39], psrc->fipo);
+ fputs(dkct_au_kw8[46], psrc->fipo);
+ /*
+ Exact rules
+ */
+ prevstate = NULL;
+ dk3sto_it_reset(stm->i_exact);
+ while((rp = (DKCT_STM_RULE *)dk3sto_it_next(stm->i_exact)) != NULL) {
+ if(prevstate) {
+ if(dk3str_c8_cmp(prevstate->name, (rp->state)->name)) {
+ fputs(dkct_au_kw8[52], psrc->fipo);
+ fputs(dkct_au_kw8[50], psrc->fipo);
+ fputs(dkct_au_kw8[48], psrc->fipo);
+ fputs((rp->state)->name, psrc->fipo);
+ fputs(dkct_au_kw8[49], psrc->fipo);
+ fputs(dkct_au_kw8[51], psrc->fipo);
+ } else {
+ }
+ } else {
+ fputs(dkct_au_kw8[47], psrc->fipo);
+ fputs(dkct_au_kw8[48], psrc->fipo);
+ fputs((rp->state)->name, psrc->fipo);
+ fputs(dkct_au_kw8[49], psrc->fipo);
+ fputs(dkct_au_kw8[51], psrc->fipo);
+ }
+ prevstate = rp->state;
+ fputs(dkct_au_kw8[53], psrc->fipo);
+ fputs((rp->input)->name, psrc->fipo);
+ fputs(dkct_au_kw8[54], psrc->fipo);
+ dkct_au_debug_matching_rule(psrc, stm, rp);
+ dkct_au_write_transition_result(psrc, stm, rp, 12);
+ fputs(dkct_au_kw8[55], psrc->fipo);
+ }
+ if(prevstate) {
+ fputs(dkct_au_kw8[52], psrc->fipo);
+ fputs(dkct_au_kw8[50], psrc->fipo);
+ fputs(dkct_au_kw8[45], psrc->fipo);
+ }
+ fputs(dkct_au_kw8[44], psrc->fipo);
+ /*
+ Wildcard rules
+ */
+ nwildcards = 0UL;
+ dk3sto_it_reset(stm->i_wildcard);
+ while((rp = (DKCT_STM_RULE *)dk3sto_it_next(stm->i_wildcard)) != NULL) {
+ fputs(dkct_au_kw8[60], psrc->fipo);
+ if(rp->state) {
+ fputs(dkct_au_kw8[64], psrc->fipo);
+ fputs((rp->state)->name, psrc->fipo);
+ } else {
+ if(rp->input) {
+ fputs(dkct_au_kw8[65], psrc->fipo);
+ fputs((rp->input)->name, psrc->fipo);
+ } else {
+ fputs(dkct_au_kw8[36], psrc->fipo);
+ }
+ }
+ fputs(dkct_au_kw8[61], psrc->fipo);
+ dkct_au_debug_matching_rule(psrc, stm, rp);
+ dkct_au_write_transition_result(psrc, stm, rp, 6);
+ fputs(dkct_au_kw8[62], psrc->fipo);
+ nwildcards++;
+ }
+ dkct_au_debug_matching_rule(psrc, stm, NULL);
+ for(i = 0; i < nwildcards; i++) {
+ fputs(dkct_au_kw8[63], psrc->fipo);
+ }
+ fputs(dkct_au_kw8[45], psrc->fipo);
+ fputs(dkct_au_kw8[77], psrc->fipo);
+ fputs(dkct_au_kw8[42], psrc->fipo);
+ /* DEBUG: Invalid st pointer */
+ fputs(dkct_au_kw8[43], psrc->fipo);
+ if((psrc->dkcto).deb) {
+ /* Debug messages for entering function */
+ dkct_au_debug_transition(psrc, stm, 1);
+ }
+ fputs(dkct_au_kw8[76], psrc->fipo);
+ fputs(dkct_au_kw8[41], psrc->fipo);
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dkct-au.ctr b/support/dktools/dkct-au.ctr
new file mode 100644
index 0000000000..45046c9c5e
--- /dev/null
+++ b/support/dktools/dkct-au.ctr
@@ -0,0 +1,1688 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% module
+
+
+#if DK3_USE_WX
+#include "dkwxtrace.h"
+#else
+#include "dkct.h"
+#endif
+
+
+$!trace-include
+
+
+
+/** Sort criteria:Sort by state and input.
+*/
+#define DKCT_AU_RULE_SORT_STATE_INPUT 1
+
+/** Sort criteria: Inverted search order.
+*/
+#define DKCT_AU_RULE_SORT_REVERSE 2
+
+
+
+/** Input file section for options.
+*/
+#define DKCT_AU_SECTION_OPTIONS 0
+
+/** Input file section for states.
+*/
+#define DKCT_AU_SECTION_STATES 1
+
+/** Input file section for inputs.
+*/
+#define DKCT_AU_SECTION_INPUTS 2
+
+/** Input file section for outputs.
+*/
+#define DKCT_AU_SECTION_OUTPUTS 3
+
+/** Input file section for rules.
+*/
+#define DKCT_AU_SECTION_RULES 4
+
+
+
+/** Section names.
+*/
+static char const * const dkct_au_section_names[] = {
+/* 0 */ "options",
+/* 1 */ "states",
+/* 2 */ "inputs",
+/* 3 */ "outputs",
+/* 4 */ "rules",
+/* 5 */ "option",
+/* 6 */ "state",
+/* 7 */ "input",
+/* 8 */ "output",
+/* 9 */ "rule",
+NULL
+};
+
+
+
+/** Keywords used by the module.
+*/
+static char const * const dkct_au_kw8[] = {
+/* 0 */ "*",
+/* 1 */ "\n",
+/* 2 */ " ",
+/* 3 */ "#ifndef ",
+/* 4 */ "#else\n",
+/* 5 */ "#endif\n\n",
+/* 6 */ "#define ",
+/* 7 */ "#error \"Redefinition of ",
+/* 8 */ "\"\n",
+/* 9 */ " %d\n",
+/* 10 */ " (%d)\n",
+/* 11 */ "/** ",
+/* 12 */ " */\n",
+/* 13 */ "State: ",
+/* 14 */ "State machine input: ",
+/* 15 */ "State machine output: ",
+/* 16 */ "state_machine_%lu",
+/* 17 */ "/** @defgroup dkct_state_machine_",
+/* 18 */ " The ",
+/* 19 */ " state machine. */\n/**@{*/\n\n",
+/* 20 */ "/**@}*/\n\n",
+/* 21 */ "#ifdef __cplusplus\nextern \"C\" { \n#endif\n\n",
+/* 22 */ "#ifdef __cplusplus\n}\n#endif\n\n",
+/* 23 */ "/**\tReset ",
+/* 24 */ " state machine.\n",
+/* 25 */ "\t@param\tst\tPointer to state variable.\n*/\n",
+/* 26 */ "void ",
+/* 27 */ "_reset(int *st);\n\n",
+/* 28 */ "/**\tState machine ",
+/* 29 */ " step.\n\t@param\tst\tPointer to state variable.\n",
+/* 30 */ "\t@param\tin\tInput.\n\t@return\tTransition output.\n*/\n",
+/* 31 */ "_step(int *st, int in);\n\n",
+/* 32 */ "static\n",
+/* 33 */ "void\n",
+/* 34 */ "_reset(int *st)\n{\n if(st) { *st = ",
+/* 35 */ "; }\n}\n\n",
+/* 36 */ "0",
+/* 37 */ "int\n",
+/* 38 */ "_step(int *st, int in)\n{\n int back = ",
+/* 39 */ ";\n",
+/* 40 */ " if(st) {\n int os;\n int nf = 1;\n int ns = ",
+/* 41 */ "}\n\n",
+/* 42 */ " } else {\n",
+/* 43 */ " }\n",
+/* 44 */ " if(nf) {\n",
+/* 45 */ " }\n",
+/* 46 */ " os = *st;\n",
+/* 47 */ " switch(os) {\n",
+/* 48 */ " case ",
+/* 49 */ ": {\n",
+/* 50 */ " } break;\n",
+/* 51 */ " switch(in) {\n",
+/* 52 */ " }\n",
+/* 53 */ " case ",
+/* 54 */ ": {\n",
+/* 55 */ " nf = 0;\n } break;\n",
+/* 56 */ "ns = ",
+/* 57 */ "os",
+/* 58 */ "; back = ",
+/* 59 */ ";",
+/* 60 */ " if(",
+/* 61 */ ") {\n",
+/* 62 */ "\n } else {\n",
+/* 63 */ " }\n",
+/* 64 */ "os == ",
+/* 65 */ "in == ",
+/* 66 */ "fprintf(",
+/* 67 */ ", \"+ ",
+/* 68 */ "_step state=%d input=%d\\n\", ((st) ? *st : 0), in);\n",
+/* 69 */ ", \"- ",
+/* 70 */ ", L\"+ ",
+/* 71 */ ", L\"- ",
+/* 72 */ "fwprintf(",
+/* 73 */ "\". rule: ",
+/* 74 */ "\\n\"", /* UNUSED */
+/* 75 */ "_step state=%d output=%d\\n\", ((st) ? *st : 0), back);\n",
+/* 76 */ " return back;\n",
+/* 77 */ " *st = ns;\n",
+NULL
+};
+
+
+
+/** Option names.
+*/
+static char const * const dkct_au_option_names[] = {
+/* 0 */ "name",
+/* 1 */ "write-header",
+NULL
+};
+
+
+
+/** Compare two entries by name.
+ @param l Left entry.
+ @param r Right entry.
+ @param cr Comparison critieria (0=struct/struct, 1=struct/name).
+ @return Comparison result.
+*/
+static
+int
+dkct_au_entry_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ DKCT_STM_ENTRY const *pl; /* Left object pointer. */
+ DKCT_STM_ENTRY const *pr; /* Right object pointer. */
+ if(l) {
+ if(r) {
+ pl = (DKCT_STM_ENTRY const *)l;
+ pr = (DKCT_STM_ENTRY const *)r;
+ switch(cr) {
+ case 1: {
+ if(pl->name) {
+ back = dk3str_c8_cmp(pl->name, (char const *)r);
+ } else {
+ back = -1;
+ }
+ } break;
+ default: {
+ if(pl->name) {
+ if(pr->name) {
+ back = dk3str_c8_cmp(pl->name, pr->name);
+ } else {
+ back = 1;
+ }
+ } else {
+ if(pr->name) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+ if(back < -1) back = -1;
+ if(back > 1) back = 1;
+ return back;
+}
+
+
+
+/** Delete entry.
+ @param p Entry to delete.
+*/
+static
+void
+dkct_au_entry_delete(DKCT_STM_ENTRY *p)
+{
+ if(p) { $? "= dkct_au_entry_delete \"%!8s\" \"%!8s\" %d", TR_8STR(p->name), TR_8STR(p->comment), p->value
+ dk3_release(p->name);
+ dk3_release(p->comment);
+ p->lineno = 0UL; p->value = 0; p->flag = 0x00;
+ dk3_delete(p);
+ }
+}
+
+
+
+/** Create entry.
+ @param name Entry name.
+ @param comment Comment.
+ @param lineno Line number in source file.
+ @param value Numeric value (if specified).
+ @param flag Flag: Use value.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new entry on success, NULL on error.
+*/
+DKCT_STM_ENTRY *
+dkct_au_entry_new(
+ char const *name,
+ char const *comment,
+ unsigned long lineno,
+ int value,
+ int flag,
+ dk3_app_t *app
+)
+{
+ DKCT_STM_ENTRY *back = NULL;
+ $? "+ dkct_au_entry_new \"%!8s\" \"%!8s\"", TR_8STR(name), TR_8STR(comment)
+ if(name) {
+ back = dk3_new_app(DKCT_STM_ENTRY,1,app);
+ if(back) {
+ back->flag = ((flag)? 0x01 : 0x00);
+ back->value = value;
+ back->lineno = lineno;
+ back->name = dk3str_c8_dup_app(name,app);
+ back->comment = NULL;
+ if(back->name) {
+ if(comment) {
+ back->comment = dk3str_c8_dup_app(comment,app);
+ if(!(back->comment)) {
+ dkct_au_entry_delete(back);
+ back = NULL;
+ }
+ }
+ } else {
+ dkct_au_entry_delete(back);
+ back = NULL;
+ }
+ }
+ } $? "- dkct_au_entry_new PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/** Compare two rules, either by state+input or by line number.
+ @param l Left rule.
+ @param r Right rule.
+ @param cr Comparison criteria (0=line,
+ DKCT_AU_RULE_SORT_STATE_INPUT=state+input).
+ @return Comparison result.
+*/
+static
+int
+dkct_au_rule_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ DKCT_STM_RULE const *pl; /* Left rule pointer. */
+ DKCT_STM_RULE const *pr; /* Right rule pointer. */
+ if(l) {
+ if(r) {
+ pl = (DKCT_STM_RULE const *)l;
+ pr = (DKCT_STM_RULE const *)r;
+ switch(cr & (~(DKCT_AU_RULE_SORT_REVERSE))) {
+ case DKCT_AU_RULE_SORT_STATE_INPUT: {
+ /*
+ First sort by states.
+ */
+ if(pl->state) {
+ if(pr->state) {
+ if((pl->state)->name) {
+ if((pr->state)->name) {
+ back = dk3str_c8_cmp((pl->state)->name, (pr->state)->name);
+ } else {
+ back = 1;
+ }
+ } else {
+ if((pr->state)->name) {
+ back = -1;
+ }
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(pr->state) {
+ back = -1;
+ }
+ }
+ /*
+ For equal states sort by input.
+ */
+ if(back == 0) {
+ if(pl->input) {
+ if(pr->input) {
+ if((pl->input)->name) {
+ if((pr->input)->name) {
+ back = dk3str_c8_cmp((pl->input)->name, (pr->input)->name);
+ } else {
+ back = 1;
+ }
+ } else {
+ if((pr->input)->name) {
+ back = -1;
+ }
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(pr->input) {
+ back = -1;
+ }
+ }
+ }
+ } break;
+ default: {
+ /*
+ Simply sort by line number.
+ */
+ if(pl->lineno > pr->lineno) { back = 1; }
+ else {
+ if(pl->lineno < pr->lineno) { back = -1; }
+ }
+ } break;
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+ if(back < -1) { back = -1; }
+ if(back > 1) { back = 1; }
+ if(cr & DKCT_AU_RULE_SORT_REVERSE) {
+ switch(back) {
+ case 1: { back = -1; } break;
+ case -1: { back = 1; } break;
+ }
+ }
+ return back;
+}
+
+
+
+/** Delete rule.
+ @param rp Rule to delete.
+*/
+void
+dkct_au_rule_delete(DKCT_STM_RULE *rp)
+{
+ if(rp) { $? "= dkct_au_rule_delete"
+ rp->state = NULL;
+ rp->input = NULL;
+ rp->newstate = NULL;
+ rp->output = NULL;
+ rp->lineno = 0UL;
+ dk3_delete(rp);
+ }
+}
+
+
+
+/** Create rule.
+ @param os Old state.
+ @param in Input.
+ @param ns New state.
+ @param out Output.
+ @param lineno Line number in source file.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new element on success, NULL on error.
+*/
+DKCT_STM_RULE *
+dkct_au_rule_new(
+ DKCT_STM_ENTRY *os,
+ DKCT_STM_ENTRY *in,
+ DKCT_STM_ENTRY *ns,
+ DKCT_STM_ENTRY *out,
+ unsigned long lineno,
+ dk3_app_t *app
+)
+{
+ DKCT_STM_RULE *back = NULL;
+ int ok = 1; /* Flag: No errors occured. */
+ $? "+ dkct_au_rule_new"
+ back = dk3_new_app(DKCT_STM_RULE,1,app);
+ if(back) {
+ back->state = os;
+ back->input = in;
+ back->newstate = ns;
+ back->output = out;
+ back->lineno = lineno;
+ if(!(ok)) {
+ dkct_au_rule_delete(back);
+ back = NULL;
+ }
+ } $? "- dkct_au_rule_new PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/** Delete all rules in a storage.
+ @param s Storage containing the rules.
+ @param i Iterator for storage.
+*/
+static
+void
+dkct_au_stm_rules_delete(dk3_sto_t *s, dk3_sto_it_t *i)
+{
+ DKCT_STM_RULE *r; /* Current rule to delete. */
+ $? "+ dkct_au_stm_rules_delete"
+ if(s) {
+ if(i) {
+ dk3sto_it_reset(i);
+ while((r = (DKCT_STM_RULE *)dk3sto_it_next(i)) != NULL) {
+ dkct_au_rule_delete(r);
+ }
+ dk3sto_it_close(i);
+ }
+ dk3sto_close(s);
+ } $? "- dkct_au_stm_rules_delete"
+}
+
+
+
+/** Delete all entries in a storage.
+ @param s Storage containing the entries.
+ @param i Iterator for storage.
+*/
+static
+void
+dkct_au_stm_entries_delete(dk3_sto_t *s, dk3_sto_it_t *i)
+{
+ DKCT_STM_ENTRY *e; /* Current entry to delete. */
+ $? "+ dkct_au_stm_entries_delete"
+ if(s) {
+ if(i) {
+ dk3sto_it_reset(i);
+ while((e = (DKCT_STM_ENTRY *)dk3sto_it_next(i)) != NULL) {
+ dkct_au_entry_delete(e);
+ }
+ dk3sto_it_close(i);
+ }
+ dk3sto_close(s);
+ } $? "- dkct_au_stm_entries_delete"
+}
+
+
+
+/** Delete a state machine description.
+ @param p State machine to delete.
+*/
+void
+dkct_au_stm_delete(DKCT_STM *p)
+{
+ $? "+ dkct_au_stm_delete"
+ if(p) {
+ dkct_au_stm_rules_delete(p->s_wildcard, p->i_wildcard);
+ dkct_au_stm_rules_delete(p->s_exact, p->i_exact);
+ dkct_au_stm_entries_delete(p->s_states, p->i_states);
+ dkct_au_stm_entries_delete(p->s_inputs, p->i_inputs);
+ dkct_au_stm_entries_delete(p->s_outputs, p->i_outputs);
+ p->s_wildcard = NULL; p->i_wildcard = NULL;
+ p->s_exact = NULL; p->i_exact = NULL;
+ p->s_states = NULL; p->i_states = NULL;
+ p->s_outputs = NULL; p->i_outputs = NULL;
+ p->s_inputs = NULL; p->i_inputs = NULL;
+ dk3_release(p->name);
+ p->lineno = 0UL;
+ p->wrh = 0;
+ p->rs = NULL;
+ p->ds = NULL;
+ p->dout = NULL;
+ p->lngr = 0UL;
+ dk3_delete(p);
+ } $? "- dkct_au_stm_delete"
+}
+
+
+
+/** Create new state machine description.
+ @param lineno Line number in source file.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new structure on success, NULL on error.
+*/
+DKCT_STM *
+dkct_au_stm_new(unsigned long lineno, dk3_app_t *app)
+{
+ DKCT_STM *back = NULL;
+ int ok = 0; /* Flag: Successfully initialized. */
+ $? "+ dkct_au_stm_new %lu", lineno
+ back = dk3_new_app(DKCT_STM,1,app);
+ if(back) {
+ back->s_wildcard = NULL; back->i_wildcard = NULL;
+ back->s_exact = NULL; back->i_exact = NULL;
+ back->s_states = NULL; back->i_states = NULL;
+ back->s_outputs = NULL; back->i_outputs = NULL;
+ back->s_inputs = NULL; back->i_inputs = NULL;
+ back->name = NULL;
+ back->lineno = lineno;
+ back->wrh = 1;
+ back->section = DKCT_AU_SECTION_OPTIONS;
+ back->rs = NULL;
+ back->ds = NULL;
+ back->dout = NULL;
+ back->lngr = 0UL;
+ back->stmno = 0UL;
+ back->s_states = dk3sto_open_app(app);
+ back->s_inputs = dk3sto_open_app(app);
+ back->s_outputs = dk3sto_open_app(app);
+ back->s_exact = dk3sto_open_app(app);
+ back->s_wildcard = dk3sto_open_app(app);
+ if(back->s_states) { back->i_states = dk3sto_it_open(back->s_states); }
+ if(back->s_inputs) { back->i_inputs = dk3sto_it_open(back->s_inputs); }
+ if(back->s_outputs) { back->i_outputs = dk3sto_it_open(back->s_outputs); }
+ if(back->s_exact) { back->i_exact = dk3sto_it_open(back->s_exact); }
+ if(back->s_wildcard) { back->i_wildcard= dk3sto_it_open(back->s_wildcard); }
+ if((back->s_states) && (back->s_inputs) && (back->s_outputs)) {
+ dk3sto_set_comp(back->s_states, dkct_au_entry_compare, 0);
+ dk3sto_set_comp(back->s_inputs, dkct_au_entry_compare, 0);
+ dk3sto_set_comp(back->s_outputs, dkct_au_entry_compare, 0);
+ if((back->s_exact) && (back->s_wildcard)) {
+ dk3sto_set_comp(
+ back->s_exact, dkct_au_rule_compare, DKCT_AU_RULE_SORT_STATE_INPUT
+ );
+ dk3sto_set_comp(back->s_wildcard, dkct_au_rule_compare, 0);
+ if((back->i_states) && (back->i_inputs) && (back->i_outputs)) {
+ if((back->i_exact) && (back->i_wildcard)) {
+ ok = 1;
+ }
+ }
+ }
+ }
+ if(!(ok)) {
+ dkct_au_stm_delete(back);
+ back = NULL;
+ }
+ } $? "- dkct_au_stm_new PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/** Process one option line.
+ @param stm State machine description.
+ @param psrc Source structure.
+ @param line Text line.
+ @param lineno Line number of current line.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_au_add_option(
+ DKCT_STM *stm, DKCT_SRC *psrc, char *line, unsigned long lineno
+)
+{
+ int back = 0;
+ char *p1; /* Key (option name). */
+ char *p2; /* Value. */
+ int ai; /* Array index of option name. */
+ $? "+ dkct_au_add_option %lu \"%!8s\"", lineno, TR_8STR(line)
+ p1 = dk3str_c8_start(line, NULL);
+ if(p1) {
+ p2 = dk3str_c8_chr(p1, '=');
+ if(p2) {
+ *(p2++) = '\0';
+ p2 = dk3str_c8_start(p2, NULL);
+ if(p2) {
+ dk3str_c8_normalize(p1, NULL, '-');
+ ai = dk3str_c8_array_index(dkct_au_option_names, p1, 0);
+ switch(ai) {
+ case 0: { $? ". name"
+ if(stm->name) {
+ /* Warning: Redefinition of name */
+ dkct_to_log_1(psrc, 1, DK3_LL_WARNING, 28);
+ dk3_release(stm->name);
+ }
+ stm->name = dk3str_c8_dup_app(p2, psrc->app);
+ if(stm->name) {
+ back = 1;
+ } else {
+ /* ERROR: Memory */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 29);
+ }
+ } break;
+ case 1: { $? ". write header"
+ if(dk3str_c8_is_bool(p2)) {
+ stm->wrh = (dk3str_c8_is_on(p2) ? 1 : 0);
+ back = 1;
+ } else {
+ /* ERROR: Syntax (not boolean)! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 30);
+ }
+ } break;
+ default: {
+ dkct_to_log_3(psrc, 1, DK3_LL_ERROR, 10, 11, p1);
+ } break;
+ }
+ } else {
+ /* ERROR: No value. */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 9);
+ }
+ } else {
+ /* Syntax */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 9);
+ }
+ }
+ $? "- dkct_au_add_option %d", back
+ return back;
+}
+
+
+
+/** Add an entry to storage.
+ @param stm State machine description.
+ @param psrc Source structure.
+ @param line Input line to process.
+ @param co Comment for entry.
+ @param lineno Line number of input line.
+ @param storage Storage for entry.
+ @param iterator Iterator for storage.
+ @param tp Entry type (0=state, 1=input, 2=output).
+ @return 1 on success, 0 on error.
+
+*/
+static
+int
+dkct_au_add_entry(
+ DKCT_STM *stm,
+ DKCT_SRC *psrc,
+ char *line,
+ char *co,
+ unsigned long lineno,
+ dk3_sto_t *storage,
+ dk3_sto_it_t *iterator,
+ int tp
+)
+{
+ int back = 0;
+ char *nptr; /* Entry name. */
+ char *vptr; /* Value (if any). */
+ DKCT_STM_ENTRY *e; /* New entry. */
+ DKCT_STM_ENTRY *ep; /* Search result. */
+ int i; /* Value (if defined). */
+ int f; /* Flag: Value defined. */
+ $? "+ dkct_au_add_entry %lu \"%!8s\" \"%!8s\"", lineno, TR_8STR(line), TR_8STR(co)
+ nptr = vptr = NULL;
+ i = f = 0;
+ nptr = dk3str_c8_start(line, NULL);
+ if(nptr) {
+ vptr = dk3str_c8_next(nptr, NULL);
+ back = 1;
+ if(vptr) {
+ if(sscanf(vptr, "%d", &i) == 1) {
+ f = 1;
+ } else {
+ back = 0;
+ /* ERROR: Syntax */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 31);
+ }
+ }
+ if(back) {
+ back = 0;
+ e = dkct_au_entry_new(
+ nptr, co, lineno, i, f, psrc->app
+ );
+ if(e) {
+ ep = (DKCT_STM_ENTRY *)dk3sto_it_find_like(iterator, (void *)e, 0);
+ if(ep) {
+ /* ERROR: Redefinition */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 32);
+ dkct_au_entry_delete(e);
+ } else {
+ if(dk3sto_add(storage, (void *)e)) {
+ back = 1;
+ switch(tp) {
+ case 0: {
+ /*
+ First state is reset state.
+ */
+ if(!(stm->rs)) { stm->rs = e; }
+ /*
+ First state is general rule next state default.
+ */
+ if(!(stm->ds)) { stm->ds = e; }
+ } break;
+ case 2: {
+ /*
+ First output is general rule output default.
+ */
+ if(!(stm->dout)) { stm->dout = e; }
+ } break;
+ }
+ } else {
+ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 29);
+ dkct_au_entry_delete(e);
+ }
+ }
+ } else {
+ /* ERROR Memory */
+ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 29);
+ }
+ }
+ } else {
+ /* ERROR: Syntax */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 33);
+ } $? "- dkct_au_add_entry %d", back
+ return back;
+}
+
+
+
+/** Find named entry in storage.
+ @param psrc Source structure.
+ @param sto Storage.
+ @param ist Storage iterator.
+ @param name Name of entry to find.
+ @param ok Pointer to not-found-is-ok variable.
+ @param t Type (0=state, 1=input, 2=output).
+ @param lineno Line number.
+ @return Pointer to found entry on success, NULL on error.
+*/
+static
+DKCT_STM_ENTRY *
+dkct_au_find_entry(
+ DKCT_SRC *psrc,
+ dk3_sto_t *sto,
+ dk3_sto_it_t *ist,
+ char *name,
+ unsigned long lineno,
+ int *ok,
+ int t
+)
+{
+ DKCT_STM_ENTRY *back = NULL;
+ if(dk3str_c8_cmp(dkct_au_kw8[0], name) == 0) {
+ *ok = 1;
+ } else {
+ back = (DKCT_STM_ENTRY *)dk3sto_it_find_like(ist, name, 1);
+ if(!(back)) {
+ /* Warning: State/input/output undeclared! */
+ dkct_to_log_3(psrc, 1, DK3_LL_WARNING, 34, 35, name);
+ back = dkct_au_entry_new(name, NULL, lineno, 0, 0, psrc->app);
+ if(back) {
+ if(!dk3sto_add(sto, (void *)back)) {
+ dkct_au_entry_delete(back);
+ back = NULL;
+ }
+ } else {
+ /* ERROR: Failed to create entry! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 29);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Add rule to state machine.
+ @param stm State machine description.
+ @param psrc Source structure.
+ @param line Input line to process.
+ @param co Comment for rule.
+ @param lineno Current line number.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_au_add_rule(
+ DKCT_STM *stm, DKCT_SRC *psrc, char *line, char *co, unsigned long lineno
+)
+{
+ int back = 0;
+ DKCT_STM_RULE tr; /* Test rul. */
+ DKCT_STM_RULE *nr; /* New rule. */
+ char *p1; /* Old state. */
+ char *p2; /* Input. */
+ char *p3; /* New state. */
+ char *p4; /* Output. */
+ DKCT_STM_ENTRY *e1; /* Old state. */
+ DKCT_STM_ENTRY *e2; /* Input. */
+ DKCT_STM_ENTRY *e3; /* New state. */
+ DKCT_STM_ENTRY *e4; /* Output. */
+ int ok1; /* Flag: Old state *. */
+ int ok2; /* Flag: Input *. */
+ int ok3; /* Flag: New state *. */
+ int ok4; /* Flag: Output *. */
+ int can_add; /* Flag: Rule ok, add. */
+ $? "+ dkct_au_add_rule %lu \"%!8s\" \"%!8s\"", lineno, TR_8STR(line), TR_8STR(co)
+ e1 = e2 = e3 = e4 = NULL; ok1 = ok2 = ok3 = ok4 = 0;
+ p1 = dk3str_c8_start(line, NULL);
+ if(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ if(p2) {
+ p3 = dk3str_c8_next(p2, NULL);
+ if(p3) {
+ p4 = dk3str_c8_next(p3, NULL);
+ if(p4) {
+ (void)dk3str_c8_next(p4, NULL);
+ e1 = dkct_au_find_entry(
+ psrc, stm->s_states, stm->i_states, p1, lineno, &ok1, 0
+ );
+ e2 = dkct_au_find_entry(
+ psrc, stm->s_inputs, stm->i_inputs, p2, lineno, &ok2, 1
+ );
+ e3 = dkct_au_find_entry(
+ psrc, stm->s_states, stm->i_states, p3, lineno, &ok3, 0
+ );
+ e4 = dkct_au_find_entry(
+ psrc, stm->s_outputs, stm->i_outputs, p4, lineno, &ok4, 2
+ );
+ if(
+ ((e1) || (ok1)) && ((e2) || (ok2))
+ && ((e3) || (ok3)) && ((e4) || (ok4))
+ )
+ {
+ can_add = 1;
+ tr.state = e1; tr.input = e2; tr.newstate = e3; tr.output = e4;
+ if((e1) && (e2)) {
+ DKCT_STM_RULE *xrp;
+ if((xrp = (DKCT_STM_RULE *)dk3sto_it_find_like(
+ stm->i_exact, (void *)(&tr),
+ DKCT_AU_RULE_SORT_STATE_INPUT
+ )
+ ) != NULL
+ )
+ {
+ char ulbuffer[32];
+ sprintf(ulbuffer, "%lu", xrp->lineno);
+ can_add = 0;
+ /* ERROR: Conflict! */
+ dkct_to_log_3(psrc, 1, DK3_LL_ERROR, 36, 39, ulbuffer);
+ }
+ }
+ if(can_add) {
+ if((e1) && (e2)) {
+ nr = dkct_au_rule_new(e1, e2, e3, e4, lineno, psrc->app);
+ if(nr) {
+ if(dk3sto_add(stm->s_exact, (void *)nr)) {
+ back = 1;
+ } else {
+ dkct_au_rule_delete(nr);
+ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ /* ERROR: Memory! */
+ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ if((e1) || (e2)) {
+ nr = dkct_au_rule_new(e1, e2, e3, e4, lineno, psrc->app);
+ if(nr) {
+ if(dk3sto_add(stm->s_wildcard, (void *)nr)) {
+ back = 1;
+ } else {
+ dkct_au_rule_delete(nr);
+ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ /* ERROR: Memory! */
+ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ back = 1;
+ if(stm->lngr) {
+ char buffer[32];
+ sprintf(buffer, "%lu", stm->lngr);
+ /* Warning: General rule redefined! */
+ dkct_to_log_3(psrc, 1, DK3_LL_ERROR, 36, 39, buffer);
+ }
+ stm->ds = e3;
+ stm->dout = e4;
+ stm->lngr = lineno;
+ }
+ }
+ }
+ } else {
+ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 33);
+ }
+ } else {
+ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 33);
+ }
+ } else {
+ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 33);
+ }
+ }
+ $? "- dkct_au_add_rule %d", back
+ return back;
+}
+
+
+
+/** Process one input line.
+ @param stm State machine description.
+ @param psrc Source structure.
+ @param line Line to process.
+ @param lineno Current line number.
+ @return 1 on success, 0 on error.
+*/
+int
+dkct_au_add_line(
+ DKCT_STM *stm, DKCT_SRC *psrc, char *line, unsigned long lineno
+)
+{
+ int back = 0;
+ char *lstart; /* Start of input line. */
+ char *pc; /* Comment pointer. */
+ int ai; /* Array index. */
+ $? "+ dkct_au_add_line %lu \"%!8s\"", lineno, TR_8STR(line)
+ if((stm) && (line)) { $? ". args ok"
+ lstart = dk3str_c8_start(line, NULL);
+ if(lstart) { $? ". text found \"%!8s\"", lstart
+ pc = NULL;
+ if(*lstart != '#') { $? ". not a comment line"
+ if(*lstart == '[') { $? ". start of section"
+ lstart++;
+ lstart = dk3str_c8_start(lstart, NULL);
+ if(lstart) {
+ stm->section = -1;
+ pc = dk3str_c8_chr(lstart, ']');
+ if(pc) {
+ *pc = '\0';
+ dk3str_c8_chomp(lstart, NULL); $? ". lstart=\"%!8s\"", lstart
+ ai = dk3str_c8_array_index(dkct_au_section_names, lstart, 0);
+ $? ". ai=%d",ai
+ switch(ai) {
+ case 0: case 5: {
+ stm->section = DKCT_AU_SECTION_OPTIONS; back = 1;
+ } break;
+ case 1: case 6: {
+ stm->section = DKCT_AU_SECTION_STATES; back = 1;
+ } break;
+ case 2: case 7: {
+ stm->section = DKCT_AU_SECTION_INPUTS; back = 1;
+ } break;
+ case 3: case 8: {
+ stm->section = DKCT_AU_SECTION_OUTPUTS; back = 1;
+ } break;
+ case 4: case 9: {
+ stm->section = DKCT_AU_SECTION_RULES; back = 1;
+ } break;
+ default: {
+ dkct_to_log_3(psrc, 1, DK3_LL_ERROR, 99, 100, lstart);
+ } break;
+ }
+ } else {
+ /* ERROR: Syntax! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 37);
+ }
+ } else {
+ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 37);
+ }
+ } else { $? ". section contents %d", stm->section
+ pc = dk3str_c8_chr(lstart, '#');
+ if(pc) { *(pc++) = '\0'; pc = dk3str_c8_start(pc, NULL); }
+ switch(stm->section) {
+ case DKCT_AU_SECTION_OPTIONS: { $? ". options"
+ back = dkct_au_add_option(stm, psrc, lstart, lineno);
+ } break;
+ case DKCT_AU_SECTION_STATES: { $? ". states"
+ back = dkct_au_add_entry(
+ stm, psrc, lstart, pc, lineno, stm->s_states, stm->i_states, 0
+ );
+ } break;
+ case DKCT_AU_SECTION_INPUTS: { $? ". inputs"
+ back = dkct_au_add_entry(
+ stm, psrc, lstart, pc, lineno, stm->s_inputs, stm->i_inputs, 1
+ );
+ } break;
+ case DKCT_AU_SECTION_OUTPUTS: { $? ". outputs"
+ back = dkct_au_add_entry(
+ stm, psrc, lstart, pc, lineno, stm->s_outputs, stm->i_outputs, 2
+ );
+ } break;
+ case DKCT_AU_SECTION_RULES: { $? ". rules"
+ back = dkct_au_add_rule(stm, psrc, lstart, pc, lineno);
+ } break;
+ }
+ }
+ } else {
+ back = 1; /* comments ok */
+ }
+ } else {
+ back = 1; /* empty lines ok */
+ }
+ } $? "- dkct_au_add_line %d", back
+ return back;
+}
+
+
+
+/** Check whether there is at least one entry in the storage.
+ @param it Iterator of storage to check.
+ @return 1 on success, 0 on error (storage empty).
+*/
+static
+int
+dkct_au_stm_entries_check(dk3_sto_it_t *it)
+{
+ int back = 0;
+ dk3sto_it_reset(it);
+ if(dk3sto_it_next(it)) {
+ back = 1;
+ }
+ return back;
+}
+
+
+
+/** Assign values to state/input/output storage.
+ @param psrc Source structure.
+ @param stm State machine to modify.
+ @param it Iterator for state/input/output storage.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_au_set_values(DKCT_SRC *psrc, DKCT_STM *stm, dk3_sto_it_t *it)
+{
+ int back = 1;
+ DKCT_STM_ENTRY *ep = NULL; /* Current entry to process. */
+ dk3_bf_t *bf = NULL; /* Bit field, used values. */
+ int min = 0; /* Minimum value so far. */
+ int max = 0; /* Maximum value so far. */
+ int valfound = 0; /* Flag: Values specified. */
+ int cv = 0; /* Current value. */
+ int cc = 0; /* Flag: Continue search. */
+ $? "+ dkct_au_set_values"
+ dk3sto_it_reset(it);
+ while((ep = (DKCT_STM_ENTRY *)dk3sto_it_next(it)) != NULL) {
+ if(ep->flag) { $? ". have value %d", ep->value
+ if(valfound) { $? ". already values found"
+ if(ep->value < min) min = ep->value;
+ if(ep->value > max) max = ep->value;
+ } else { $? ". first value"
+ min = max = ep->value;
+ }
+ valfound = 1;
+ } else { $? ". no value"
+ }
+ }
+ if(valfound) { $? ". must take care of existing values"
+ bf = dk3bf_open_app((max - min + 1), psrc->app);
+ if(bf) {
+ /*
+ Find used values.
+ */
+ dk3sto_it_reset(it);
+ while((ep = (DKCT_STM_ENTRY *)dk3sto_it_next(it)) != NULL) {
+ if(ep->flag) {
+ dk3bf_set(bf, (ep->value - min), 1);
+ }
+ }
+ /*
+ Set missing values.
+ */
+ cv = 0;
+ dk3sto_it_reset(it);
+ while((ep = (DKCT_STM_ENTRY *)dk3sto_it_next(it)) != NULL) {
+ if(!(ep->flag)) {
+ do { $? ". attempt %d", cv
+ cc = 0;
+ if((cv >= min) && (cv <= max)) {
+ if(dk3bf_get(bf, (cv - min))) {
+ cc = 1; $? "! already in use"
+ cv++;
+ if(cv == 0) { $? "! Numeric overflow"
+ cc = 0;
+ back = 0;
+ /* ERROR: Overflow */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ } while(cc);
+ cc = 0;
+ if((cv >= min) && (cv <= max)) {
+ if(!dk3bf_get(bf, (cv - min))) {
+ cc = 1;
+ }
+ } else {
+ cc = 1;
+ }
+ if(cc) { $? ". can use %d", cv
+ ep->value = cv++;
+ if(cv == 0) { $? "! Numeric overflow"
+ back = 0;
+ /* ERROR: Overflow */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ }
+ dk3bf_close(bf);
+ } else { $? "! failed to allocated bit field"
+ back = 0;
+ /* ERROR: Memory */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 29);
+ }
+ } else { $? ". no existing values yet"
+ cv = 0;
+ dk3sto_it_reset(it);
+ while((ep = (DKCT_STM_ENTRY *)dk3sto_it_next(it)) != NULL) {
+ ep->value = cv++;
+ if(cv == 0) { $? "! numeric overflow"
+ back = 0;
+ /* ERROR: Overflow */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 38);
+ }
+ }
+ } $? "- dkct_au_set_values %d", back
+ return back;
+}
+
+
+
+int
+dkct_au_stm_check(DKCT_SRC *psrc, DKCT_STM *stm)
+{
+ int back = 0;
+ int sfound = 0; /* Number of states found. */
+ int ifound = 0; /* Number of inputs found. */
+ int ofound = 0; /* Number of outputs found. */
+
+ dk3app_set_source_line(psrc->app, stm->lineno);
+ sfound = dkct_au_stm_entries_check(stm->i_states);
+ ifound = dkct_au_stm_entries_check(stm->i_inputs);
+ ofound = dkct_au_stm_entries_check(stm->i_outputs);
+ if((sfound) && (ifound) && (ofound)) {
+ back = 1;
+ if(!dkct_au_set_values(psrc, stm, stm->i_states)) { back = 0; }
+ if(!dkct_au_set_values(psrc, stm, stm->i_inputs)) { back = 0; }
+ if(!dkct_au_set_values(psrc, stm, stm->i_outputs)) { back = 0; }
+ } else {
+ if(!(sfound)) {
+ /* ERROR: No states declared! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 40);
+ }
+ if(!(ifound)) {
+ /* ERROR: No inputs declared! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 41);
+ }
+ if(!(ofound)) {
+ /* ERROR: No outputs declared! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 42);
+ }
+ }
+ return back;
+}
+
+
+
+/** Write definition for one storage entry.
+ @param psrc Source structure.
+ @param stm State machine.
+ @param ep Entry to write
+ @param commi Keyword index for "state", "input", or "output".
+*/
+static
+void
+dkct_au_write_one_entry(
+ DKCT_SRC *psrc, DKCT_STM *stm, DKCT_STM_ENTRY *ep, size_t commi
+)
+{
+ $? "+ dkct_au_write_one_entry"
+ fputs(dkct_au_kw8[3], psrc->fipo);
+ fputs(ep->name, psrc->fipo);
+ fputs(dkct_au_kw8[1], psrc->fipo);
+ fputs(dkct_au_kw8[11], psrc->fipo);
+ fputs(dkct_au_kw8[commi], psrc->fipo);
+ if(ep->comment) {
+ fputs(ep->comment, psrc->fipo);
+ } else {
+ fputs(ep->name, psrc->fipo);
+ }
+ fputs(dkct_au_kw8[12], psrc->fipo);
+ if((psrc->dkcto).lnn) {
+ psrc->lineno = ep->lineno;
+ dkct_tr_show_source_line(psrc, 0);
+ }
+ fputs(dkct_au_kw8[6], psrc->fipo);
+ fputs(ep->name, psrc->fipo);
+ fprintf(psrc->fipo, dkct_au_kw8[(ep->value >= 0) ? 9 : 10], ep->value);
+ fputs(dkct_au_kw8[4], psrc->fipo); /* else */
+ if((psrc->dkcto).lnn) {
+ psrc->lineno = ep->lineno;
+ dkct_tr_show_source_line(psrc, 0);
+ }
+ fputs(dkct_au_kw8[7], psrc->fipo);
+ fputs(ep->name, psrc->fipo);
+ fputs(dkct_au_kw8[8], psrc->fipo);
+ fputs(dkct_au_kw8[5], psrc->fipo); /* endif */
+ $? "- dkct_au_write_one_entry"
+}
+
+
+
+/** Write all entries of a storage.
+ @param psrc Source structure.
+ @param stm State machine.
+ @param it Storage iterator.
+ @param commi Keyword index for "state", "input", or "output".
+*/
+static
+void
+dkct_au_write_entry_storage(
+ DKCT_SRC *psrc, DKCT_STM *stm, dk3_sto_it_t *it, size_t commi
+)
+{
+ DKCT_STM_ENTRY *ep; /* Current entry. */
+ $? "+ dkct_au_write_entry_storage"
+ dk3sto_it_reset(it);
+ while((ep = (DKCT_STM_ENTRY *)dk3sto_it_next(it)) != NULL) {
+ dkct_au_write_one_entry(psrc, stm, ep, commi);
+ } $? "- dkct_au_write_entry_storage"
+}
+
+
+
+/** Write state machine name to output file.
+ @param psrc Source structure.
+ @param stm State machine.
+*/
+static
+void
+dkct_au_write_stm_name(DKCT_SRC *psrc, DKCT_STM *stm)
+{
+ if(stm->name) {
+ fputs(stm->name, psrc->fipo);
+ } else {
+ fprintf(psrc->fipo, dkct_au_kw8[16], stm->stmno);
+ }
+}
+
+
+
+/** Write state/input/output entry definitions.
+ @param psrc Source structure.
+ @param stm State machine.
+*/
+void
+dkct_au_write_entries(DKCT_SRC *psrc, DKCT_STM *stm)
+{
+ /*
+ Begin doxygen group
+ */
+ fputs(dkct_au_kw8[17], psrc->fipo);
+ dkct_au_write_stm_name(psrc, stm);
+ fputs(dkct_au_kw8[18], psrc->fipo);
+ dkct_au_write_stm_name(psrc, stm);
+ fputs(dkct_au_kw8[19], psrc->fipo);
+ /*
+ Write the entries
+ */
+ dkct_au_write_entry_storage(psrc, stm, stm->i_states, 13);
+ dkct_au_write_entry_storage(psrc, stm, stm->i_inputs, 14);
+ dkct_au_write_entry_storage(psrc, stm, stm->i_outputs, 15);
+ /*
+ End doxygen group
+ */
+ fputs(dkct_au_kw8[20], psrc->fipo);
+}
+
+
+
+void
+dkct_au_write_prototypes(DKCT_SRC *psrc, DKCT_STM *stm)
+{
+ fputs(dkct_au_kw8[21], psrc->fipo);
+ fputs(dkct_au_kw8[23], psrc->fipo);
+ dkct_au_write_stm_name(psrc, stm);
+ fputs(dkct_au_kw8[24], psrc->fipo);
+ fputs(dkct_au_kw8[25], psrc->fipo);
+ fputs(dkct_au_kw8[26], psrc->fipo);
+ dkct_au_write_stm_name(psrc, stm);
+ fputs(dkct_au_kw8[27], psrc->fipo);
+ fputs(dkct_au_kw8[28], psrc->fipo);
+ dkct_au_write_stm_name(psrc, stm);
+ fputs(dkct_au_kw8[29], psrc->fipo);
+ fputs(dkct_au_kw8[30], psrc->fipo);
+ fputs(dkct_au_kw8[37], psrc->fipo);
+ dkct_au_write_stm_name(psrc, stm);
+ fputs(dkct_au_kw8[31], psrc->fipo);
+ fputs(dkct_au_kw8[22], psrc->fipo);
+}
+
+
+
+/** Write a transition result.
+ @param psrc Source structure.
+ @param stm State machine.
+ @param rp Rule.
+ @param indent Level of indent.
+*/
+static
+void
+dkct_au_write_transition_result(
+ DKCT_SRC *psrc, DKCT_STM *stm, DKCT_STM_RULE *rp, int indent
+)
+{
+ int i; /* Number of indent spaces already written. */
+ /* DEBUG CODE IF -d */
+ for(i = 0; i < indent; i++) { fputc(' ', psrc->fipo); }
+ fputs(dkct_au_kw8[56], psrc->fipo);
+ if(rp->newstate) {
+ fputs((rp->newstate)->name, psrc->fipo);
+ } else {
+ fputs(dkct_au_kw8[57], psrc->fipo);
+ }
+ fputs(dkct_au_kw8[58], psrc->fipo);
+ if(rp->output) {
+ fputs((rp->output)->name, psrc->fipo);
+ } else {
+ if(stm->dout) {
+ fputs((stm->dout)->name, psrc->fipo);
+ } else {
+ fputs(dkct_au_kw8[36], psrc->fipo);
+ }
+ }
+ fputs(dkct_au_kw8[59], psrc->fipo);
+}
+
+
+
+/** Create debug code for entering and leaving the
+ transition function.
+ @param psrc Source structure.
+ @param stm State machine.
+ @param pos Position (0=invokation, 1=return).
+*/
+static
+void
+dkct_au_debug_transition(DKCT_SRC *psrc, DKCT_STM *stm, int pos)
+{
+ char const *fnptr; /* Debug output file. */
+
+ fnptr = dkct_tr_get_kw8(((psrc->dkcto).deb == 2) ? 28 : 29);
+ fputs(dkct_tr_get_kw8(67), psrc->fipo);
+ if((psrc->dkcto).win) {
+ fputs(dkct_tr_get_kw8(21), psrc->fipo);
+ /* char 16 start */
+ psrc->lineno = stm->lineno;
+ fputs(dkct_tr_get_kw8(61), psrc->fipo);
+ dkct_tr_show_filename_and_lineno(psrc);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+
+ fputs(dkct_au_kw8[72], psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_au_kw8[(pos == 1) ? 71 : 70], psrc->fipo);
+ dkct_au_write_stm_name(psrc, stm);
+ fputs(dkct_au_kw8[(pos == 1) ? 75 : 68], psrc->fipo);
+
+ fputs(dkct_tr_get_kw8(37), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ /* char 16 end */
+ fputs(dkct_tr_get_kw8(22), psrc->fipo);
+ }
+ /* char 8 start */
+ if((psrc->dkcto).deb == 1) {
+ fputs(dkct_tr_get_kw8(30), psrc->fipo);
+ }
+ psrc->lineno = stm->lineno;
+ fputs(dkct_tr_get_kw8(33), psrc->fipo);
+ dkct_tr_show_filename_and_lineno(psrc);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+
+ fputs(dkct_au_kw8[66], psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_au_kw8[(pos == 1) ? 69 : 67], psrc->fipo);
+ dkct_au_write_stm_name(psrc, stm);
+ fputs(dkct_au_kw8[(pos == 1) ? 75 : 68], psrc->fipo);
+
+ fputs(dkct_tr_get_kw8(37), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ if((psrc->dkcto).deb == 1) {
+ fputs(dkct_tr_get_kw8(31), psrc->fipo);
+ }
+ /* char 8 end */
+ if((psrc->dkcto).win) {
+ fputs(dkct_tr_get_kw8(23), psrc->fipo);
+ }
+ fputs(dkct_tr_get_kw8(25), psrc->fipo);
+}
+
+
+
+/** Write debug output to show the matching rule.
+ @param psrc Source structure.
+ @param stm State machine.
+ @param rp Rule to show.
+*/
+static
+void
+dkct_au_debug_matching_rule(
+ DKCT_SRC *psrc, DKCT_STM *stm, DKCT_STM_RULE *rp
+)
+{
+ char const *fnptr; /* Debug output file. */
+ char const *p1; /* Current state. */
+ char const *p2; /* Input. */
+ char const *p3; /* Next state. */
+ char const *p4; /* Output. */
+
+ if((psrc->dkcto).deb) {
+ p1 = p2 = p3 = p4 = dkct_au_kw8[0];
+ if(rp) {
+ if(rp->state) { p1 = (rp->state)->name; }
+ if(rp->input) { p2 = (rp->input)->name; }
+ if(rp->newstate) { p3 = (rp->newstate)->name; }
+ if(rp->output) { p4 = (rp->output)->name; }
+ } else {
+ if(stm->ds) { p3 = (stm->ds)->name; }
+ if(stm->dout) { p4 = (stm->dout)->name; }
+ }
+ fnptr = dkct_tr_get_kw8(((psrc->dkcto).deb == 2) ? 28 : 29);
+ psrc->lineno = stm->lineno;
+ if(rp) { psrc->lineno = rp->lineno; }
+ fputs(dkct_tr_get_kw8(67), psrc->fipo);
+ if((psrc->dkcto).win) {
+ fputs(dkct_tr_get_kw8(21), psrc->fipo);
+ /* char 16 start */
+ if((psrc->dkcto).deb == 1) {
+ fputs(dkct_tr_get_kw8(30), psrc->fipo);
+ }
+ fputs(dkct_tr_get_kw8(61), psrc->fipo);
+ dkct_tr_show_filename_and_lineno(psrc);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ fputs(dkct_tr_get_kw8(61), psrc->fipo);
+ fputs(dkct_au_kw8[73], psrc->fipo);
+ fputs(dkct_au_kw8[2], psrc->fipo);
+ fputs(p1, psrc->fipo);
+ fputs(dkct_au_kw8[2], psrc->fipo);
+ fputs(p2, psrc->fipo);
+ fputs(dkct_au_kw8[2], psrc->fipo);
+ fputs(p3, psrc->fipo);
+ fputs(dkct_au_kw8[2], psrc->fipo);
+ fputs(p4, psrc->fipo);
+ fputs(dkct_au_kw8[74], psrc->fipo);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ fputs(dkct_tr_get_kw8(37), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ if((psrc->dkcto).deb == 1) {
+ fputs(dkct_tr_get_kw8(31), psrc->fipo);
+ }
+ /* char 16 end */
+ fputs(dkct_tr_get_kw8(22), psrc->fipo);
+ }
+ /* char 8 start */
+ if((psrc->dkcto).deb == 1) {
+ fputs(dkct_tr_get_kw8(30), psrc->fipo);
+ }
+ fputs(dkct_tr_get_kw8(33), psrc->fipo);
+ dkct_tr_show_filename_and_lineno(psrc);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+
+ fputs(dkct_tr_get_kw8(33), psrc->fipo);
+ fputs(dkct_au_kw8[73], psrc->fipo);
+ fputs(dkct_au_kw8[2], psrc->fipo);
+ fputs(p1, psrc->fipo);
+ fputs(dkct_au_kw8[2], psrc->fipo);
+ fputs(p2, psrc->fipo);
+ fputs(dkct_au_kw8[2], psrc->fipo);
+ fputs(p3, psrc->fipo);
+ fputs(dkct_au_kw8[2], psrc->fipo);
+ fputs(p4, psrc->fipo);
+ fputs(dkct_au_kw8[74], psrc->fipo);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+
+ fputs(dkct_tr_get_kw8(37), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ if((psrc->dkcto).deb == 1) {
+ fputs(dkct_tr_get_kw8(31), psrc->fipo);
+ }
+
+ /* char 8 end */
+ if((psrc->dkcto).win) {
+ fputs(dkct_tr_get_kw8(23), psrc->fipo);
+ }
+ fputs(dkct_tr_get_kw8(25), psrc->fipo);
+ }
+}
+
+
+
+void
+dkct_au_write_functions(DKCT_SRC *psrc, DKCT_STM *stm, int f_static)
+{
+ DKCT_STM_ENTRY *prevstate; /* Current state. */
+ DKCT_STM_RULE *rp; /* Rule to process. */
+ unsigned long nwildcards; /* Number of wildcards. */
+ unsigned long i; /* Current wildcard block to finish. */
+ /*
+ Reset function.
+ */
+ if(f_static) {
+ fputs(dkct_au_kw8[23], psrc->fipo);
+ dkct_au_write_stm_name(psrc, stm);
+ fputs(dkct_au_kw8[24], psrc->fipo);
+ fputs(dkct_au_kw8[25], psrc->fipo);
+ fputs(dkct_au_kw8[32], psrc->fipo);
+ }
+ fputs(dkct_au_kw8[33], psrc->fipo);
+ dkct_au_write_stm_name(psrc, stm);
+ fputs(dkct_au_kw8[34], psrc->fipo);
+ if(stm->rs) {
+ fputs((stm->rs)->name, psrc->fipo);
+ } else {
+ fputs(dkct_au_kw8[36], psrc->fipo);
+ }
+ fputs(dkct_au_kw8[35], psrc->fipo);
+ /*
+ Transition function.
+ */
+ if(f_static) {
+ fputs(dkct_au_kw8[28], psrc->fipo);
+ dkct_au_write_stm_name(psrc, stm);
+ fputs(dkct_au_kw8[29], psrc->fipo);
+ fputs(dkct_au_kw8[30], psrc->fipo);
+ fputs(dkct_au_kw8[32], psrc->fipo);
+ }
+ fputs(dkct_au_kw8[37], psrc->fipo);
+ dkct_au_write_stm_name(psrc, stm);
+ fputs(dkct_au_kw8[38], psrc->fipo);
+ if(stm->dout) {
+ fputs((stm->dout)->name, psrc->fipo);
+ } else {
+ fputs(dkct_au_kw8[36], psrc->fipo);
+ }
+ fputs(dkct_au_kw8[39], psrc->fipo);
+ if((psrc->dkcto).deb) {
+ /* Debug messages for entering function */
+ dkct_au_debug_transition(psrc, stm, 0);
+ }
+ fputs(dkct_au_kw8[40], psrc->fipo);
+ if(stm->ds) {
+ fputs((stm->ds)->name, psrc->fipo);
+ } else {
+ fputs(dkct_au_kw8[36], psrc->fipo);
+ }
+ fputs(dkct_au_kw8[39], psrc->fipo);
+ fputs(dkct_au_kw8[46], psrc->fipo);
+ /*
+ Exact rules
+ */
+ prevstate = NULL;
+ dk3sto_it_reset(stm->i_exact);
+ while((rp = (DKCT_STM_RULE *)dk3sto_it_next(stm->i_exact)) != NULL) {
+ if(prevstate) {
+ if(dk3str_c8_cmp(prevstate->name, (rp->state)->name)) {
+ fputs(dkct_au_kw8[52], psrc->fipo);
+ fputs(dkct_au_kw8[50], psrc->fipo);
+ fputs(dkct_au_kw8[48], psrc->fipo);
+ fputs((rp->state)->name, psrc->fipo);
+ fputs(dkct_au_kw8[49], psrc->fipo);
+ fputs(dkct_au_kw8[51], psrc->fipo);
+ } else {
+ }
+ } else {
+ fputs(dkct_au_kw8[47], psrc->fipo);
+ fputs(dkct_au_kw8[48], psrc->fipo);
+ fputs((rp->state)->name, psrc->fipo);
+ fputs(dkct_au_kw8[49], psrc->fipo);
+ fputs(dkct_au_kw8[51], psrc->fipo);
+ }
+ prevstate = rp->state;
+ fputs(dkct_au_kw8[53], psrc->fipo);
+ fputs((rp->input)->name, psrc->fipo);
+ fputs(dkct_au_kw8[54], psrc->fipo);
+ dkct_au_debug_matching_rule(psrc, stm, rp);
+ dkct_au_write_transition_result(psrc, stm, rp, 12);
+ fputs(dkct_au_kw8[55], psrc->fipo);
+ }
+ if(prevstate) {
+ fputs(dkct_au_kw8[52], psrc->fipo);
+ fputs(dkct_au_kw8[50], psrc->fipo);
+ fputs(dkct_au_kw8[45], psrc->fipo);
+ }
+ fputs(dkct_au_kw8[44], psrc->fipo);
+ /*
+ Wildcard rules
+ */
+ nwildcards = 0UL;
+ dk3sto_it_reset(stm->i_wildcard);
+ while((rp = (DKCT_STM_RULE *)dk3sto_it_next(stm->i_wildcard)) != NULL) {
+ fputs(dkct_au_kw8[60], psrc->fipo);
+ if(rp->state) {
+ fputs(dkct_au_kw8[64], psrc->fipo);
+ fputs((rp->state)->name, psrc->fipo);
+ } else {
+ if(rp->input) {
+ fputs(dkct_au_kw8[65], psrc->fipo);
+ fputs((rp->input)->name, psrc->fipo);
+ } else {
+ fputs(dkct_au_kw8[36], psrc->fipo);
+ }
+ }
+ fputs(dkct_au_kw8[61], psrc->fipo);
+ dkct_au_debug_matching_rule(psrc, stm, rp);
+ dkct_au_write_transition_result(psrc, stm, rp, 6);
+ fputs(dkct_au_kw8[62], psrc->fipo);
+ nwildcards++;
+ }
+ dkct_au_debug_matching_rule(psrc, stm, NULL);
+ for(i = 0; i < nwildcards; i++) {
+ fputs(dkct_au_kw8[63], psrc->fipo);
+ }
+ fputs(dkct_au_kw8[45], psrc->fipo);
+ fputs(dkct_au_kw8[77], psrc->fipo);
+ fputs(dkct_au_kw8[42], psrc->fipo);
+ /* DEBUG: Invalid st pointer */
+ fputs(dkct_au_kw8[43], psrc->fipo);
+ if((psrc->dkcto).deb) {
+ /* Debug messages for entering function */
+ dkct_au_debug_transition(psrc, stm, 1);
+ }
+ fputs(dkct_au_kw8[76], psrc->fipo);
+ fputs(dkct_au_kw8[41], psrc->fipo);
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dkct-gui.c b/support/dktools/dkct-gui.c
new file mode 100644
index 0000000000..df75933777
--- /dev/null
+++ b/support/dktools/dkct-gui.c
@@ -0,0 +1,10505 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dkct-gui.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dkct-gui.c The dkct-gui module.
+*/
+
+
+#line 594 "dkct-gui.ctr"
+
+#if DK3_USE_WX
+#include "dkwxtrace.h"
+#else
+#include "dkct.h"
+#endif
+
+
+
+#line 602 "dkct-gui.ctr"
+
+
+
+/** Class names for GUI elements.
+*/
+static char const * const dkct_gui_class_names[] = {
+/* 0 */ "wxFrame",
+/* 1 */ "wxDialog",
+/* 2 */ "wxMDIParentFrame",
+/* 3 */ "wxMDIChildFrame",
+/* 4 */ "wxPopupWindow",
+/* 5 */ "wxBoxSizer",
+/* 6 */ "wxFlexGridSizer",
+/* 7 */ "wxGridBagSizer",
+/* 8 */ "wxGridSizer",
+/* 9 */ "wxStaticBoxSizer",
+/* 10 */ "wxStdDialogButtonSizer",
+/* 11 */ "wxPanel",
+/* 12 */ "wxNotebook",
+/* 13 */ "wxScrolledWindow",
+/* 14 */ "wxSplitterWindow",
+/* 15 */ "wxButton",
+/* 16 */ "wxBitmapButton",
+/* 17 */ "wxChoice",
+/* 18 */ "wxComboBox",
+/* 19 */ "wxCheckBox",
+/* 20 */ "wxListBox",
+/* 21 */ "wxCheckListBox",
+/* 22 */ "wxRadioBox",
+/* 23 */ "wxRadioButton",
+/* 24 */ "wxScrollBar",
+/* 25 */ "wxSpinButton",
+/* 26 */ "wxSpinCtrl",
+/* 27 */ "wxSlider",
+/* 28 */ "wxTextCtrl",
+/* 29 */ "wxToggleButton",
+/* 30 */ "wxGauge",
+/* 31 */ "wxStaticText",
+/* 32 */ "wxStaticBitmap",
+/* 33 */ "wxStaticLine",
+/* 34 */ "wxStaticBox",
+/* 35 */ "wxMenuBar",
+/* 36 */ "wxMenu",
+/* 37 */ "wxMenuItem",
+/* 38 */ "wxToolBar",
+/* 39 */ "wxStatusBar",
+/* 40 */ "wxToolBarToolBase", /* Not a wxWidgets class! */
+/* 41 */ "wxGrid",
+NULL
+};
+
+
+
+/** Option names.
+*/
+static char const * const dkct_gui_option_keys[] = {
+/* 0 */ "align",
+NULL
+};
+
+
+
+/** Checkbox state names.
+*/
+static char const * const dkct_gui_db_state_names[] = {
+/* 0 */ "unchecked",
+/* 1 */ "checked",
+/* 2 */ "undetermined",
+NULL
+};
+
+
+
+/** Table selection mode names.
+*/
+static char const * const dkct_gui_cb_sel_names[]= {
+/* 0 */ "single",
+/* 1 */ "multiple",
+/* 2 */ "extended",
+NULL
+};
+
+
+
+/** Style property names for slider.
+*/
+static char const * const dkct_gui_slider_style_names[] = {
+/* 0 */ "ticks",
+/* 1 */ "labels",
+/* 2 */ "left",
+/* 3 */ "right",
+/* 4 */ "top",
+/* 5 */ "bottom",
+/* 6 */ "range",
+/* 7 */ "inverse",
+NULL
+};
+
+
+
+/** Style property names for text control.
+*/
+static char const * const dkct_gui_text_style_names[] = {
+/* 0 */ "enter",
+/* 1 */ "tab",
+/* 2 */ "multiline",
+/* 3 */ "password",
+/* 4 */ "readonly",
+/* 5 */ "rich",
+/* 6 */ "rich2",
+/* 7 */ "url",
+/* 8 */ "selection",
+/* 9 */ "left",
+/* 10 */ "centered",
+/* 11 */ "right",
+/* 12 */ "no-wrap",
+/* 13 */ "char-wrap",
+/* 14 */ "word-wrap",
+/* 15 */ "best-wrap",
+/* 16 */ "capitalize",
+/* 17 */ "no-auto-resize",
+NULL
+};
+
+
+
+/** Style property names for notebook.
+*/
+static char const * const dkct_gui_notebook_style_names[] = {
+/* 0 */ "top",
+/* 1 */ "left",
+/* 2 */ "right",
+/* 3 */ "bottom",
+/* 4 */ "fixed-width",
+/* 5 */ "multiline",
+/* 6 */ "no-theme",
+/* 7 */ "flat",
+NULL
+};
+
+
+
+/** Style property names for splitter window.
+*/
+static char const * const dkct_gui_splitterw_style_names[] = {
+/* 0 */ "3d",
+/* 1 */ "3d-sash",
+/* 2 */ "3d-border",
+/* 3 */ "border",
+/* 4 */ "no-border",
+/* 5 */ "no-xp-theme",
+/* 6 */ "permit-unsplit",
+/* 7 */ "live-update",
+NULL
+};
+
+
+
+/** Style property names for bitmap button.
+*/
+static char const * const dkct_gui_bitmapb_style_names[] = {
+/* 0 */ "auto-draw",
+/* 1 */ "left",
+/* 2 */ "top",
+/* 3 */ "right",
+/* 4 */ "bottom",
+NULL
+};
+
+
+
+/** Style property names for gauge.
+*/
+static char const * const dkct_gui_gauge_style_names[] = {
+/* 0 */ "smooth",
+NULL
+};
+
+
+
+/** Style property names for menu item.
+*/
+static char const * const dkct_gui_menu_item_style_names[] = {
+/* 0 */ "normal",
+/* 1 */ "separator",
+/* 2 */ "check",
+/* 3 */ "radio",
+NULL
+};
+
+
+
+/** Style property names for toolbar.
+*/
+static char const * const dkct_gui_toolbar_style_names[] = {
+/* 0 */ "flat",
+/* 1 */ "dockable",
+/* 2 */ "text",
+/* 3 */ "no-icons",
+/* 4 */ "no-divider",
+/* 5 */ "horizontal-layout",
+/* 6 */ "no-tooltips",
+/* 7 */ "bottom",
+/* 8 */ "right",
+NULL
+};
+
+
+
+/** Style names for wxGrid object.
+*/
+static char const * const dkct_gui_grid_style_names[] = {
+/* 0 */ "autosize-data",
+/* 1 */ "autosize-labels-rows",
+/* 2 */ "autosize-labels-columns",
+/* 3 */ "autosize-labels",
+NULL
+};
+
+
+
+/** Style property names for button.
+*/
+static char const * const dkct_gui_notebook_button_names[] = {
+/* 0 */ "left",
+/* 1 */ "top",
+/* 2 */ "right",
+/* 3 */ "bottom",
+/* 4 */ "fit",
+/* 5 */ "no-border",
+NULL
+};
+
+
+
+/** Names for alignment.
+*/
+static char const * const dkct_gui_align_names[] = {
+/* 0 */ "left",
+/* 1 */ "right",
+/* 2 */ "top",
+/* 3 */ "bottom",
+/* 4 */ "centered",
+/* 5 */ "centered-x",
+/* 6 */ "centered-y",
+NULL
+};
+
+
+
+/** Names for border positions.
+*/
+static char const * const dkct_gui_border_position_names[] = {
+/* 0 */ "all",
+/* 1 */ "top",
+/* 2 */ "left",
+/* 3 */ "right",
+/* 4 */ "bottom",
+NULL
+};
+
+
+
+/** Names of pseudo objects.
+*/
+static char const * const dkct_gui_pseudo_object_names[] = {
+/* 0 */ "$stretch", /* Stretch spacer. */
+/* 1 */ "$space", /* Spacer. */
+/* 2 */ "$separator", /* Separator in menus. */
+NULL
+};
+
+
+
+/** Base type names for the root object.
+*/
+static char const * const dkct_gui_base_type_names[] = {
+"frame",
+"dialog",
+NULL
+};
+
+
+
+/** Attribute names.
+*/
+static char const * const dkct_gui_attribute_keys[] = {
+/* 0 */ "expand",
+/* 1 */ "type",
+/* 2 */ "menu-bar",
+/* 3 */ "tool-bar",
+/* 4 */ "status-bar",
+/* 5 */ "contents",
+/* 6 */ "text",
+/* 7 */ "id",
+/* 8 */ "tip",
+/* 9 */ "proportion",
+/* 10 */ "status-text",
+/* 11 */ "border",
+/* 12 */ "constructor",
+/* 13 */ "grid", /* Grid for wxFlexGridSizer/wxGridSizer. */
+/* 14 */ "sash", /* Sash value for splitter window. */
+/* 15 */ "minimum-pane-size", /* Minimum pane size for splitter window. */
+/* 16 */ "bitmap", /* Bitmap expression for bitmap button. */
+/* 17 */ "choices", /* Choices expression. */
+/* 18 */ "states", /* Number of states + current state for checkbox. */
+/* 19 */ "size", /* Element default size. */
+/* 20 */ "selection", /* Selection style for list box. */
+/* 21 */ "rows", /* Max number of rows for radio box. */
+/* 22 */ "columns", /* Max number of columns for radio box. */
+/* 23 */ "grow", /* Alias for expand. */
+/* 24 */ "start-group", /* Start radio button group. */
+/* 25 */ "direction", /* Spin/slider/scrollbar control direction. */
+/* 26 */ "range", /* Spin/slider min and max value. */
+/* 27 */ "wrap", /* Flag: Wrap spin control. */
+/* 28 */ "keys", /* Flag: Use keys. */
+/* 29 */ "validator", /* Set validator object. */
+/* 30 */ "value", /* Spin/slider value. */
+/* 31 */ "slider-style", /* Style for sliders. */
+/* 32 */ "notebook-style", /* Style for notebooks. */
+/* 33 */ "text-style", /* Style for text controls. */
+/* 34 */ "button-style", /* Style for buttons. */
+/* 35 */ "splitter-window-style", /* Style for splitter window. */
+/* 36 */ "bitmap-button-style", /* Style for bitmap button. */
+/* 37 */ "bitmap-disabled", /* Bitmap in disabled state. */
+/* 38 */ "bitmap-selected", /* Bitmap in selected state. */
+/* 39 */ "bitmap-focus", /* Bitmap when focused. */
+/* 40 */ "bitmap-hover", /* Bitmap when mouse-over. */
+/* 41 */ "gauge-style", /* Gauge style. */
+/* 42 */ "menu-item-style", /* Menu item style. */
+/* 43 */ "toolbar-style", /* Toolbar style. */
+/* 44 */ "toolbar-button-style", /* Toolbar button style. */
+/* 45 */ "icon", /* Icon for window. */
+/* 46 */ "column-head", /* Column head for wxGrid. */
+/* 47 */ "row-head", /* Row head for wxGrid. */
+/* 48 */ "table", /* Table for wxGrid. */
+/* 49 */ "minimum-size", /* Minimum size. */
+/* 50 */ "growable-row", /* Growable row in wxGridBagSizer. */
+/* 51 */ "growable-column", /* Growable column. */
+/* 52 */ "complete-constructor-specified", /* Have complete constructor. */
+/* 53 */ "cell-data", /* Data for a wxGrid cell */
+/* 54 */ "grid-style", /* Style for grid */
+/* 55 */ "tooltip-flag", /* Tool tip flag */
+NULL
+};
+
+
+
+/** Keywords used to produce output file.
+*/
+char const * const dkct_gui_out_kw[] = {
+/* 0 */ "\n",
+/* 1 */ " ",
+/* 2 */ " ",
+/* 3 */ "*",
+/* 4 */ ";",
+/* 5 */ " /**\tGUI element ",
+/* 6 */ ".\n */\n",
+/* 7 */ " /**\tFlag: GUI ok.\n */\n bool dkctGUILayoutOK;\n\n",
+/* 8 */ " ",
+/* 9 */ "dkctGUILayoutOK = false;\n",
+/* 10 */ "dkctGUILayoutOK = true;\n",
+/* 11 */ "dkctGUILayoutFinished",
+/* 12 */ ":",
+/* 13 */ "goto",
+/* 14 */ " = NULL;\n",
+/* 15 */ ".",
+/* 16 */ "%d",
+/* 17 */
+" /**\tContents panel.\n */\n wxPanel *dkctGUIContentsPanel;\n\n",
+/* 18 */ "dkctGUIContentsPanel = NULL;\n",
+/* 19 */ "#if wxUSE_MENUS\n",
+/* 20 */ "#if wxUSE_TOOLBAR\n",
+/* 21 */ "#if wxUSE_STATUSBAR\n",
+/* 22 */ "#endif\n",
+/* 23 */ " = new ",
+/* 24 */ ");",
+/* 25 */ " if(!(",
+/* 26 */ ")) {\n",
+/* 27 */ " goto dkctGUILayoutFinished;\n",
+/* 28 */ " }\n",
+/* 29 */ "(\n",
+/* 30 */ "dkctGUIContentsPanel",
+/* 31 */ "->",
+/* 32 */ "SetSizer(",
+/* 33 */ "dkctGUIContentsPanel = new wxPanel(this);\n",
+/* 34 */ "wxHORIZONTAL",
+/* 35 */ "wxVERTICAL",
+/* 36 */ "Add(\n",
+/* 37 */ " );\n",
+/* 38 */ ",\n",
+/* 39 */ "wxALL",
+/* 40 */ "wxTOP",
+/* 41 */ "wxLEFT",
+/* 42 */ "wxRIGHT",
+/* 43 */ "wxBOTTOM",
+/* 44 */ "|",
+/* 45 */ "wxALIGN_LEFT",
+/* 46 */ "wxALIGN_CENTER_HORIZONTAL",
+/* 47 */ "wxALIGN_RIGHT",
+/* 48 */ "wxALIGN_TOP",
+/* 49 */ "wxALIGN_CENTER_VERTICAL",
+/* 50 */ "wxALIGN_BOTTOM",
+/* 51 */ "wxGROW",
+/* 52 */ "0",
+/* 53 */ "wxGBPosition(",
+/* 54 */ "wxGBSpan(",
+/* 55 */ ", ",
+/* 56 */ ")",
+/* 57 */ "SetMenuBar(",
+/* 58 */ "SetToolBar(",
+/* 59 */ " if(dkctGUILayoutOK) {\n",
+/* 60 */ "->SetSizeHints(this);\n",
+/* 61 */ "", /* UNUSED */
+/* 62 */ " SetClientSize(dkctGUIMinSize);\n",
+/* 63 */ "->Fit(this);\n",
+/* 64 */ " }\n",
+/* 65 */ "this",
+/* 66 */ "wxID_ANY",
+/* 67 */ " if((",
+/* 68 */ ") && (",
+/* 69 */ ")) {\n",
+/* 70 */ "SplitVertically(",
+/* 71 */ "SplitHorizontally(",
+/* 72 */ "->SetMinimumPaneSize(",
+/* 73 */ "wxEmptyString",
+/* 74 */ "wxDefaultPosition",
+/* 75 */ "wxDefaultSize",
+/* 76 */ "wxCHK_3STATE",
+/* 77 */ "->SetValue(true);\n",
+/* 78 */ "->Set3StateValue(wxCHK_UNDETERMINED);\n",
+/* 79 */ "->Set3StateValue(wxCHK_CHECKED);\n",
+/* 80 */ "->Realize();\n",
+/* 81 */ "wxSize(",
+/* 82 */ "wxLB_SINGLE",
+/* 83 */ "wxLB_MULTIPLE",
+/* 84 */ "wxLB_EXTENDED",
+/* 85 */ "|wxLB_HSCROLL|wxLB_NEEDED_SB",
+/* 86 */ "wxRA_SPECIFY_ROWS",
+/* 87 */ "wxRA_SPECIFY_COLS",
+/* 88 */ "wxRB_GROUP",
+/* 89 */ " wxSize const dkctGUIMinSize(",
+/* 90 */ " CreateStatusBar(",
+/* 91 */ " SetStatusText(",
+/* 92 */ "wxSP_HORIZONTAL",
+/* 93 */ "wxSP_VERTICAL",
+/* 94 */ "|wxSP_ARROW_KEYS",
+/* 95 */ "|wxSP_WRAP",
+/* 96 */ "wxSP_ARROW_KEYS|wxSP_WRAP",
+/* 97 */ "wxSP_ARROW_KEYS",
+/* 98 */ "wxSP_WRAP",
+/* 99 */ "",
+/* 100 */ "NULL",
+/* 101 */ "wxSB_HORIZONTAL",
+/* 102 */ "wxSB_VERTICAL",
+/* 103 */ "wxSL_HORIZONTAL",
+/* 104 */ "wxSL_VERTICAL",
+/* 105 */ "wxSL_AUTOTICKS",
+/* 106 */ "wxSL_LABELS",
+/* 107 */ "wxSL_LEFT",
+/* 108 */ "wxSL_RIGHT",
+/* 109 */ "wxSL_TOP",
+/* 110 */ "wxSL_BOTTOM",
+/* 111 */ "wxSL_SELRANGE",
+/* 112 */ "wxSL_INVERSE",
+/* 113 */ "wxNB_TOP",
+/* 114 */ "wxNB_LEFT",
+/* 115 */ "wxNB_RIGHT",
+/* 116 */ "wxNB_BOTTOM",
+/* 117 */ "wxNB_FIXEDWIDTH",
+/* 118 */ "wxNB_MULTILINE",
+/* 119 */ "wxNB_NOPAGETHEME",
+/* 120 */ "wxNB_FLAT",
+/* 121 */ "wxTE_PROCESS_ENTER",
+/* 122 */ "wxTE_PROCESS_TAB",
+/* 123 */ "wxTE_MULTILINE",
+/* 124 */ "wxTE_PASSWORD",
+/* 125 */ "wxTE_READONLY",
+/* 126 */ "wxTE_RICH",
+/* 127 */ "wxTE_RICH2",
+/* 128 */ "wxTE_AUTO_URL",
+/* 129 */ "wxTE_NOHIDESEL",
+/* 130 */ "wxTE_LEFT",
+/* 131 */ "wxTE_CENTRE",
+/* 132 */ "wxTE_RIGHT",
+/* 133 */ "wxTE_DONTWRAP",
+/* 134 */ "wxTE_CHARWRAP",
+/* 135 */ "wxTE_WORDWRAP",
+/* 136 */ "wxTE_BESTWRAP",
+/* 137 */ "wxTE_CAPITALIZE",
+/* 138 */ "wxHSCROLL",
+/* 139 */ "wxVSCROLL",
+/* 140 */ "wxHSCROLL|wxVSCROLL",
+/* 141 */ "wxBU_LEFT",
+/* 142 */ "wxBU_TOP",
+/* 143 */ "wxBU_RIGHT",
+/* 144 */ "wxBU_BOTTOM",
+/* 145 */ "wxBU_EXACTFIT",
+/* 146 */ "wxNO_BORDER",
+/* 147 */ "wxSP_3D",
+/* 148 */ "wxSP_3DSASH",
+/* 149 */ "wxSP_3DBORDER",
+/* 150 */ "wxSP_BORDER",
+/* 151 */ "wxSP_NOBORDER",
+/* 152 */ "wxSP_NO_XP_THEME",
+/* 153 */ "wxSP_PERMIT_UNSPLIT",
+/* 154 */ "wxSP_LIVE_UPDATE",
+/* 155 */ "wxBU_AUTODRAW",
+/* 156 */ "->SetBitmapDisabled(",
+/* 157 */ "->SetBitmapSelected(",
+/* 158 */ "->SetBitmapFocus(",
+/* 159 */ "->SetBitmapHover(",
+/* 160 */ "wxGA_HORIZONTAL",
+/* 161 */ "wxGA_VERTICAL",
+/* 162 */ "|wxGA_SMOOTH",
+/* 163 */ "wxALIGN_CENTRE",
+/* 164 */ "wxST_NO_AUTORESIZE",
+/* 165 */ "wxLI_HORIZONTAL",
+/* 166 */ "wxLI_VERTICAL",
+/* 167 */ "wxITEM_NORMAL",
+/* 168 */ "wxITEM_SEPARATOR",
+/* 169 */ "wxITEM_CHECK",
+/* 170 */ "wxITEM_RADIO",
+/* 171 */ "wxID_SEPARATOR",
+/* 172 */ "wxTB_HORIZONTAL",
+/* 173 */ "wxTB_VERTICAL",
+/* 174 */ "|wxTB_FLAT",
+/* 175 */ "|wxTB_DOCKABLE",
+/* 176 */ "|wxTB_TEXT",
+/* 177 */ "|wxTB_NOICONS",
+/* 178 */ "|wxTB_NODIVIDER",
+/* 179 */ "|wxTB_NOALIGN",
+/* 180 */ "|wxTB_HORZ_LAYOUT",
+/* 181 */ "|wxTB_NO_TOOTIPS",
+/* 182 */ "|wxTB_BOTTOM",
+/* 183 */ "|wxTB_RIGHT",
+/* 184 */ "->Append(",
+/* 185 */ "->AddTool(\n",
+/* 186 */ "wxNullBitmap",
+/* 187 */ "->AddControl(",
+/* 188 */ "AppendSeparator();\n",
+/* 189 */ "AddSeparator();\n",
+/* 190 */ "SetToolTip(",
+/* 191 */ "->AppendCheckItem(",
+/* 192 */ "->AppendRadioItem(",
+/* 193 */ "->AppendSeparator(",
+/* 194 */ " = ",
+/* 195 */ "SetIcon(",
+/* 196 */ "Add(",
+/* 197 */ "<none>",
+/* 198 */ "->SetTable(",
+/* 199 */ "true",
+/* 200 */ "->CreateGrid(",
+/* 201 */ "->SetColLabelValue(",
+/* 202 */ "->SetRowLabelValue(",
+/* 203 */ "->EnableEditing(false);",
+/* 204 */ "->SetMinSize(wxSize(",
+/* 205 */ "));",
+/* 206 */ "->AddGrowableCol(",
+/* 207 */ "->AddGrowableRow(",
+/* 208 */ "AddButton(\n",
+/* 209 */ ",",
+/* 210 */ "SetLabel(",
+/* 211 */ "SetValidator(",
+/* 212 */ "SetSize(",
+/* 213 */ "SetMinSize(",
+/* 214 */ "->SetCellValue(",
+/* 215 */ "->AutoSize(",
+/* 216 */ "->SetRowLabelSize(wxGRID_AUTOSIZE",
+/* 217 */ "->SetColLabelSize(wxGRID_AUTOSIZE",
+/* 218 */ "if(",
+/* 219 */ ") { ",
+NULL
+};
+
+
+
+/** Names for directions.
+*/
+static char const * const dkct_gui_direction_names[] = {
+/* 0 */ "horizontal",
+/* 1 */ "vertical",
+/* 2 */ "both",
+NULL
+};
+
+
+
+/** Delete grid header data.
+ @param gh Header data to delete.
+*/
+static
+void
+dkct_grid_head_delete(DKCT_GRID_HEAD *gh)
+{
+ if(gh) {
+ dk3_release(gh->text);
+ gh->elno = 0;
+ dk3_delete(gh);
+ }
+}
+
+
+static
+void
+dkct_grid_cell_delete(DKCT_CELL_DATA *cd)
+{
+ if (cd) {
+ dk3_release(cd->text);
+ cd->row = cd->col = 0;
+ dk3_delete(cd);
+ }
+}
+
+
+/** Create new grid header data.
+ @param txt Text for row or column label.
+ @param no Index number of grid row or column.
+ @param psrc Source structure.
+*/
+static
+DKCT_GRID_HEAD *
+dkct_grid_head_new(char const *txt, int no, DKCT_SRC *psrc)
+{
+ DKCT_GRID_HEAD *back = NULL;
+ if(txt) {
+ back = dk3_new_app(DKCT_GRID_HEAD,1,psrc->app);
+ if(back) {
+ back->elno = no;
+ back->text = dk3str_c8_dup_app(txt, psrc->app);
+ if(!(back->text)) {
+ dkct_grid_head_delete(back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+static
+DKCT_CELL_DATA *
+dkct_grid_cell_new(char const *txt, int r, int c, DKCT_SRC *psrc)
+{
+ DKCT_CELL_DATA *back = NULL;
+ if (txt) {
+ back = dk3_new_app(DKCT_CELL_DATA,1,psrc->app);
+ if (back) {
+ back->row = r; back->col = c;
+ back->text = dk3str_c8_dup_app(txt, psrc->app);
+ if (!(back->text)) {
+ dkct_grid_cell_delete(back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+static
+int
+dkct_grid_cell_compare(const void *l, const void *r, int cr)
+{
+ DKCT_CELL_DATA *pl;
+ DKCT_CELL_DATA *pr;
+ int back = 0;
+
+ if (l) {
+ if (r) {
+ pl = (DKCT_CELL_DATA *)l;
+ pr = (DKCT_CELL_DATA *)r;
+ if (pl->row < pr->row) {
+ back = -1;
+ } else {
+ if (pl->row > pr->row) {
+ back = 1;
+ } else {
+ if (pl->col < pr->col) {
+ back = -1;
+ } else {
+ if (pl->col > pr->col) {
+ back = 1;
+ }
+ }
+ }
+ }
+ } else back = 1;
+ } else {
+ if (r) back = -1;
+ }
+ return back;
+}
+
+
+/** Compare two row/column heads.
+ @param l Left object.
+ @param r Right object.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+static
+int
+dkct_grid_head_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ DKCT_GRID_HEAD const *pl;
+ DKCT_GRID_HEAD const *pr;
+ if(l) {
+ if(r) {
+ pl = (DKCT_GRID_HEAD const *)l; pr = (DKCT_GRID_HEAD const *)r;
+ if(pl->elno > pr->elno) {
+ back = 1;
+ } else {
+ if(pl->elno < pr->elno) {
+ back = -1;
+ }
+ }
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ }
+ return back;
+}
+
+
+
+/** Compare two GUI elements.
+ @param l Left element.
+ @param r Right element.
+ @param cr Comparison criteria (0=elem/elem by name, 1=elem/name,
+ 2=elem/elem by number, 3=elem/number).
+ @return Comparison result.
+*/
+static
+int
+dkct_gui_element_compare(void const *l, void const *r, int cr)
+{
+ int back = 0; /* Result. */
+ DKCT_GUI_ELEMENT const *pl; /* Left object pointer. */
+ DKCT_GUI_ELEMENT const *pr; /* Right object pointer. */
+ size_t const *pn; /* Right number. */
+ if(l) {
+ if(r) {
+ pl = (DKCT_GUI_ELEMENT const *)l;
+ pr = (DKCT_GUI_ELEMENT const *)r;
+ pn = (size_t const *)r;
+ switch(cr) {
+ case 3: {
+ if(pl->number > *pn) {
+ back = 1;
+ } else {
+ if(pl->number < *pn) {
+ back = -1;
+ }
+ }
+ } break;
+ case 2: {
+ if(pl->number > pr->number) {
+ back = 1;
+ } else {
+ if(pl->number < pr->number) {
+ back = -1;
+ }
+ }
+ } break;
+ case 1: {
+ if(pl->name) {
+ back = dk3str_c8_cmp(pl->name, (char const *)r);
+ } else { back = -1; }
+ } break;
+ default: {
+ if(pl->name) {
+ if(pr->name) {
+ back = dk3str_c8_cmp(pl->name, pr->name);
+ } else { back = 1; }
+ } else {
+ if(pr->name) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ if(back < -1) { back = -1; }
+ if(back > 1) { back = 1; }
+ return back;
+}
+
+
+
+/** Remove all grid heads (row or column heads) from storage
+ and close storage.
+ @param sHeads Storage containing the heads.
+ @param iHeads Iterator through storage.
+*/
+static
+void
+dkct_remove_grid_heads(dk3_sto_t *sHeads, dk3_sto_it_t *iHeads)
+{
+ DKCT_GRID_HEAD *gh;
+
+ if(sHeads) {
+ if(iHeads) {
+ dk3sto_it_reset(iHeads);
+ while(NULL != (gh = (DKCT_GRID_HEAD *)dk3sto_it_next(iHeads))) {
+ dkct_grid_head_delete(gh);
+ }
+ dk3sto_it_close(iHeads);
+ }
+ dk3sto_close(sHeads);
+ }
+}
+
+
+
+static
+void
+dkct_remove_grid_cell_data(dk3_sto_t *scd, dk3_sto_it_t *icd)
+{
+ DKCT_CELL_DATA *cd;
+ if (scd) {
+ if (icd) {
+ dk3sto_it_reset(icd);
+ while (NULL != (cd = (DKCT_CELL_DATA *)dk3sto_it_next(icd))) {
+ dkct_grid_cell_delete(cd);
+ }
+ dk3sto_it_close(icd);
+ }
+ dk3sto_close(scd);
+ }
+}
+
+
+
+
+/** Remove growable row or column information.
+ @param st Storage containing growable row or column data.
+ @param it Iterator through storage.
+*/
+static
+void
+dkct_remove_grow_row_col(dk3_sto_t *st, dk3_sto_it_t *it)
+{
+ void *ip;
+ if(st) {
+ if(it) {
+ dk3sto_it_reset(it);
+ while(NULL != (ip = dk3sto_it_next(it))) {
+ dk3_delete(ip);
+ }
+ dk3sto_it_close(it);
+ }
+ dk3sto_close(st);
+ }
+}
+
+
+/** Destroy GUI element, release memory.
+ @param elp Element to destroy.
+*/
+static
+void
+dkct_gui_elem_delete(DKCT_GUI_ELEMENT *elp)
+{
+
+
+#line 1471 "dkct-gui.ctr"
+ if(elp) {
+ dkct_remove_grid_cell_data(elp->sCellData, elp->iCellData);
+ elp->sCellData = NULL; elp->iCellData = NULL;
+ dkct_remove_grid_heads(elp->sRowHeads, elp->iRowHeads);
+ dkct_remove_grid_heads(elp->sColumnHeads, elp->iColumnHeads);
+ elp->sRowHeads = NULL; elp->iRowHeads = NULL;
+ elp->sColumnHeads = NULL; elp->iColumnHeads = NULL;
+ dkct_remove_grow_row_col(elp->sGrowRow, elp->iGrowRow);
+ dkct_remove_grow_row_col(elp->sGrowCol, elp->iGrowCol);
+ elp->sGrowRow = NULL; elp->iGrowRow = NULL;
+ elp->sGrowCol = NULL; elp->iGrowCol = NULL;
+ if(elp->s_contents) {
+ if(elp->i_contents) {
+ dk3sto_it_close(elp->i_contents);
+ }
+ dk3sto_close(elp->s_contents);
+ } elp->s_contents = NULL; elp->i_contents = NULL;
+ dk3_release(elp->ttflag);
+ dk3_release(elp->gridTable);
+ dk3_release(elp->validator);
+ dk3_release(elp->choices);
+ dk3_release(elp->stbText);
+ dk3_release(elp->bitmapHover);
+ dk3_release(elp->bitmapFocus);
+ dk3_release(elp->bitmapSelected);
+ dk3_release(elp->bitmapDisabled);
+ dk3_release(elp->bitmapVarName);
+ dk3_release(elp->icon);
+ dk3_release(elp->tipText);
+ dk3_release(elp->name);
+ dk3_release(elp->cname);
+ dk3_release(elp->constructor);
+ dk3_release(elp->text);
+ dk3_release(elp->idname);
+ elp->parent = NULL;
+
+
+#line 1507 "dkct-gui.ctr"
+ elp->number = 0;
+
+
+#line 1509 "dkct-gui.ctr"
+ elp->lndef = 0UL;
+
+
+#line 1511 "dkct-gui.ctr"
+ elp->lndecl = 0UL;
+ elp->cln = 0;
+ elp->align = 0x00;
+ dk3_delete(elp);
+ }
+
+#line 1516 "dkct-gui.ctr"
+}
+
+
+
+/** Create GUI element, allocate memory.
+ @param parent Parent GUI element.
+ @param name New GUI elements name.
+ @param number Number of new element.
+ @param psrc Source structure, used for diagnostics.
+ @param gui GUI description.
+ @return Pointer to new element on success, NULL on error.
+*/
+static
+DKCT_GUI_ELEMENT *
+dkct_gui_elem_new(
+ DKCT_GUI_ELEMENT *parent,
+ char const *name,
+ size_t number,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+
+)
+{
+ DKCT_GUI_ELEMENT *back = NULL;
+ int ok = 0; /* Flag: OK so far. */
+
+
+#line 1542 "dkct-gui.ctr"
+ back = dk3_new_app(DKCT_GUI_ELEMENT,1,psrc->app);
+ if(back) {
+ /*
+ Initialize empty object.
+ */
+ back->name = NULL;
+ back->cname = NULL;
+ back->idname = NULL;
+ back->text = NULL;
+ back->constructor = NULL;
+ back->tipText = NULL;
+ back->icon = NULL;
+ back->bitmapVarName = NULL;
+ back->bitmapDisabled = NULL;
+ back->bitmapSelected = NULL;
+ back->bitmapFocus = NULL;
+ back->bitmapHover = NULL;
+ back->stbText = NULL;
+ back->choices = NULL;
+ back->validator = NULL;
+ back->gridTable = NULL;
+ back->ttflag = NULL;
+ back->parent = NULL;
+ back->number = 0;
+ back->align = 0x00;
+ if(gui) { back->align = gui->align; }
+ back->cln = -1;
+ back->menubar = NULL;
+ back->toolbar = NULL;
+ back->passno = 0;
+ back->posx = 0;
+ back->posy = 0;
+ back->spanx = 0;
+ back->spany = 0;
+ back->gridcolumns = 1;
+ back->gridrows = 1;
+ back->gridgapx = -1;
+ back->gridgapy = -1;
+ back->sash = 0;
+ back->minPaneSize = 0;
+ back->nChoices = 0;
+ back->maxRowsCols = 1;
+ back->rbDirection = DKCT_GUI_RB_DIR_COLUMNS;
+ back->startGroup = 0x00;
+ back->curx = 0;
+ back->cury = 0;
+ back->sizex = 0;
+ back->sizey = 0;
+ back->sizemx = 0;
+ back->sizemy = 0;
+ back->stbsz = 0;
+ back->s_contents = NULL;
+ back->i_contents = NULL;
+ back->sRowHeads = NULL;
+ back->iRowHeads = NULL;
+ back->sColumnHeads = NULL;
+ back->iColumnHeads = NULL;
+ back->sCellData = NULL;
+ back->iCellData = NULL;
+ back->sGrowRow = NULL;
+ back->iGrowRow = NULL;
+ back->sGrowCol = NULL;
+ back->iGrowCol = NULL;
+ back->pseudoobj = 0;
+ back->lndef = 0UL;
+ back->lndecl = 0UL;
+ if(psrc) { back->lndecl = psrc->lineno; }
+ back->border = -1;
+ back->borderPos = 0x00;
+ back->expandFlag = 0x00;
+ back->nStates = 0x02;
+ back->state = 0x00;
+ back->selStyle = DKCT_GUI_SELECTION_STYLE_SINGLE;
+ back->prost = DKCT_GUI_PROCESSING_STATE_START;
+ back->proportion = 0;
+ back->direction = DKCT_GUI_DIRECTION_HORIZONTAL;
+ back->spinMin = 0;
+ back->spinMax = 100;
+ back->spinVal = 0;
+ back->nRows = 0;
+ back->nColumns = 0;
+ back->nRowHeads = 0;
+ back->nColumnHeads = 0;
+ back->spinWrap = 0x00;
+ back->useKeys = 0x00;
+ back->sliderStyle = 0x00;
+ back->buttonStyle = 0x00;
+ back->bitmapbStyle = DKCT_GUI_BBUTTON_AUTODRAW;
+ back->gaugeStyle = 0x00;
+ back->menuItemStyle = 0x00;
+ back->tableOwner = 0x00;
+ back->notebookStyle = 0U;
+ back->splitterStyle = DKCT_GUI_SPLITTERW_3D;
+ back->toolbarStyle = DKCT_GUI_TOOLBAR_FLAT;
+ back->gridStyle = 0U;
+ back->textStyle = 0UL;
+ back->compConst = 0x00;
+ /*
+ Allocate memory.
+ */
+ back->s_contents = dk3sto_open_app(psrc->app);
+ if(back->s_contents) {
+ /* Sorting by number needed. */
+ dk3sto_set_comp(back->s_contents, dkct_gui_element_compare, 2);
+ back->i_contents = dk3sto_it_open(back->s_contents);
+ if(back->i_contents) {
+ ok = 1;
+ }
+ }
+ /*
+ Use arguments.
+ */
+ back->parent = parent;
+ if(name) {
+ back->name = dk3str_c8_dup_app(name, psrc->app);
+ if(!(back->name)) { ok = 0; }
+ }
+ back->number = number;
+ if(!(ok)) {
+
+#line 1661 "dkct-gui.ctr"
+ dkct_gui_elem_delete(back); back = NULL;
+ }
+ }
+
+#line 1664 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Create next object in GUI description.
+ @param gui GUI description.
+ @param name New object name.
+ @return Pointer to new object on success, NULL on error.
+*/
+static
+DKCT_GUI_ELEMENT *
+dkct_gui_elem_next(DKCT_GUI *gui, char const *name)
+{
+ DKCT_GUI_ELEMENT *back = NULL;
+
+ if(name) {
+ if(*name != '$') {
+ back = (DKCT_GUI_ELEMENT *)dk3sto_it_find_like(
+ gui->i_el_by_name, (void *)name, 1
+ );
+ }
+ }
+ if(back) {
+ /* Warning: Object already declared! 95/96 */
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_WARNING, 95, 96, name);
+ } else {
+ back = dkct_gui_elem_new(gui->c_el, name, gui->no, gui->psrc, gui);
+ if(back) {
+ if(dk3sto_add(gui->s_el_by_name, (void *)back)) {
+ gui->no += 1;
+ if(!dk3sto_add(gui->s_el_by_num, (void *)back)) {
+ back = NULL;
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ }
+ } else {
+ dkct_gui_elem_delete(back); back = NULL;
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory! */
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory! */
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ }
+ return back;
+}
+
+
+
+DKCT_GUI *
+dkct_gui_new(DKCT_SRC *psrc)
+{
+ DKCT_GUI *back = NULL;
+ int ok = 0; /* FLag: Success. */
+ DKCT_GUI_ELEMENT *el; /* New element. */
+
+
+#line 1723 "dkct-gui.ctr"
+ back = dk3_new_app(DKCT_GUI,1,psrc->app);
+ if(back) {
+ /*
+ Initialize.
+ */
+ back->psrc = psrc;
+ back->c_el = NULL;
+ back->r_el = NULL;
+ back->s_el_by_name = NULL; back->i_el_by_name = NULL;
+ back->s_el_by_num = NULL; back->i_el_by_num = NULL;
+ back->ttflag = NULL;
+ back->no = 0;
+ back->align = 0x00;
+ /*
+ Allocate storages.
+ */
+ back->s_el_by_name = dk3sto_open_app(psrc->app);
+ if(back->s_el_by_name) {
+ dk3sto_set_comp(back->s_el_by_name, dkct_gui_element_compare, 0);
+ back->i_el_by_name = dk3sto_it_open(back->s_el_by_name);
+ if(back->i_el_by_name) {
+ back->s_el_by_num = dk3sto_open_app(psrc->app);
+ if(back->s_el_by_num) {
+ dk3sto_set_comp(back->s_el_by_num, dkct_gui_element_compare, 2);
+ back->i_el_by_num = dk3sto_it_open(back->s_el_by_num);
+ if(back->i_el_by_num) {
+ el = dkct_gui_elem_new(NULL, NULL, 0, psrc, back);
+ if(el) {
+ back->no = 1;
+ if(dk3sto_add(back->s_el_by_name, el)) {
+ if(dk3sto_add(back->s_el_by_num, el)) {
+ ok = 1;
+ back->c_el = el;
+ back->r_el = el;
+ el->cln = 0;
+ }
+ } else {
+ dkct_gui_elem_delete(el); el = NULL;
+ }
+ }
+ }
+ }
+ }
+ }
+ if(!(ok)) {
+ dkct_gui_delete(back); back = NULL;
+ }
+ }
+
+#line 1771 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+void
+dkct_gui_delete(DKCT_GUI *pg)
+{
+ DKCT_GUI_ELEMENT *el; /* Current element to process. */
+
+
+#line 1781 "dkct-gui.ctr"
+ if(pg) {
+ pg->psrc = NULL;
+ pg->c_el = NULL;
+ pg->no = 0;
+ if(pg->s_el_by_num) {
+ if(pg->i_el_by_num) {
+ dk3sto_it_close(pg->i_el_by_num);
+ }
+ dk3sto_close(pg->s_el_by_num);
+ } pg->s_el_by_num = NULL; pg->i_el_by_num = NULL;
+ if(pg->s_el_by_name) {
+ if(pg->i_el_by_name) {
+ dk3sto_it_reset(pg->i_el_by_name);
+ while((el = (DKCT_GUI_ELEMENT *)dk3sto_it_next(pg->i_el_by_name))
+ != NULL)
+ {
+ dkct_gui_elem_delete(el);
+ }
+ dk3sto_it_close(pg->i_el_by_name);
+ }
+ dk3sto_close(pg->s_el_by_name);
+ } pg->s_el_by_name = NULL; pg->i_el_by_name = NULL;
+ if (NULL != pg->ttflag) {
+ dk3_delete(pg->ttflag);
+ }
+ pg->ttflag = NULL;
+ dk3_delete(pg);
+ }
+
+#line 1809 "dkct-gui.ctr"
+}
+
+
+
+/** Class-depending attribute setup.
+ @param el New object to set up.
+*/
+static
+void
+dkct_gui_initialize_object_for_class(DKCT_GUI_ELEMENT *el)
+{
+ switch(el->cln) {
+ case 13: {
+ el->direction = DKCT_GUI_DIRECTION_BOTH;
+ } break;
+ }
+}
+
+
+
+/** Start processing of a new object.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_start_new_object_definition(DKCT_GUI *gui, char *il)
+{
+ int back = 0;
+ char *p2 = NULL; /* Closing square bracket. */
+ DKCT_GUI_ELEMENT *elp; /* Element to process. */
+
+
+#line 1842 "dkct-gui.ctr"
+ gui->c_el = NULL;
+ p2 = dk3str_c8_rchr(il, ']');
+ if(p2) {
+ *p2 = '\0';
+ p2 = dk3str_c8_next(il, NULL);
+ if(p2) {
+ elp = (DKCT_GUI_ELEMENT *)dk3sto_it_find_like(gui->i_el_by_name, p2, 1);
+ if(!(elp)) {
+ /* Warning: Undefined element ! */
+ elp = dkct_gui_elem_new(NULL, p2, gui->no, gui->psrc, gui);
+ if(elp) {
+ if(dk3sto_add(gui->s_el_by_name, (void *)elp)) {
+ gui->no += 1;
+ if(!dk3sto_add(gui->s_el_by_num, (void *)elp)) {
+ elp = NULL;
+ }
+ } else {
+ dkct_gui_elem_delete(elp); elp = NULL;
+ }
+ }
+ }
+ if(elp) {
+ if(elp->cname) {
+ /* ERROR: Class name already defined! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 45);
+ } else {
+ elp->lndef = (gui->psrc)->lineno;
+ if(elp->lndecl == 0UL) { elp->lndecl = (gui->psrc)->lineno; }
+ elp->cname = dk3str_c8_dup_app(il, (gui->psrc)->app);
+ elp->cln = dk3str_c8_array_index(dkct_gui_class_names, il, 1);
+ dkct_gui_initialize_object_for_class(elp);
+ if(elp->cname) {
+ back = 1;
+ gui->c_el = elp;
+ } else {
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 57);
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ /* ERROR: Syntax (missing object name) */#
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 58);
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ /* ERROR: Syntax (missing ']') */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 59);
+ }
+
+
+#line 1896 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set menu bar.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_menu_bar(DKCT_GUI *gui, char *il)
+{
+ int back = 0;
+ DKCT_GUI_ELEMENT *elp; /* Element to modify. */
+
+
+#line 1913 "dkct-gui.ctr"
+ if(gui->c_el) {
+ if(((gui->c_el)->number != 0) && (!((gui->c_el)->parent))) {
+
+
+#line 1916 "dkct-gui.ctr"
+ /* Warning: Attribute applicable to root element only! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 55);
+ }
+ if(!((gui->c_el)->menubar)) {
+ elp = (DKCT_GUI_ELEMENT *)dk3sto_it_find_like(gui->i_el_by_name, il, 1);
+ if(!(elp)) {
+ elp = dkct_gui_elem_next(gui, il);
+ }
+ if(elp) {
+ (gui->c_el)->menubar = (void *)elp;
+ back = 1;
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 57);
+ }
+ } else {
+ DKCT_GUI_ELEMENT *e;
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ e = (DKCT_GUI_ELEMENT *)((gui->c_el)->menubar);
+ if(e->name) {
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 74, 75, e->name);
+ }
+ }
+ }
+
+#line 1941 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set tool bar.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_tool_bar(DKCT_GUI *gui, char *il)
+{
+ int back = 0;
+ DKCT_GUI_ELEMENT *elp; /* Toolbar object. */
+
+
+#line 1958 "dkct-gui.ctr"
+ if(gui->c_el) {
+ if(((gui->c_el)->number != 0) && (!((gui->c_el)->parent))) {
+
+
+#line 1961 "dkct-gui.ctr"
+ /* Warning: Attribute applicable to root object only! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 55);
+ }
+ if(!((gui->c_el)->toolbar)) {
+ elp = (DKCT_GUI_ELEMENT *)dk3sto_it_find_like(gui->i_el_by_name, il, 1);
+ if(!(elp)) {
+ elp = dkct_gui_elem_next(gui, il);
+ }
+ if(elp) {
+ (gui->c_el)->toolbar = (void *)elp;
+ back = 1;
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 57);
+ }
+ } else {
+ DKCT_GUI_ELEMENT *e;
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ /* ERROR: Redefinition */
+ e = (DKCT_GUI_ELEMENT *)((gui->c_el)->toolbar);
+ if(e->name) {
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 74, 75, e->name);
+ }
+ }
+ }
+
+
+#line 1988 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set status bar.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_status_bar(DKCT_GUI *gui, char *il)
+{
+ int back = 0;
+ int num = 0; /* Number of status bar labels. */
+ char *p1; /* Number of status bar labels. */
+ char *p2; /* Initial status text. */
+
+
+#line 2007 "dkct-gui.ctr"
+ if(gui->c_el) {
+ if(((gui->c_el)->number != 0) && (!((gui->c_el)->parent))) {
+
+
+#line 2010 "dkct-gui.ctr"
+ /* Warning: Attribute applicable to root element only! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 55);
+ }
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ if(sscanf(p1, "%d", &num) == 1) {
+ if(num >= 0) {
+ back = 1;
+ (gui->c_el)->stbsz = num;
+ if(p2) {
+ back = 0;
+ dk3_release((gui->c_el)->stbText);
+ (gui->c_el)->stbText = dk3str_c8_dup_app(p2, (gui->psrc)->app);
+ if((gui->c_el)->stbText) {
+ back = 1;
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 57);
+ }
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ /* ERROR: Out of range! */
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 82, 83, p1);
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ /* ERROR: Not a number! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 31);
+ }
+ }
+ }
+
+
+#line 2045 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set text for Window ID.
+ @param gui GUI description.
+ @param il Value part of input line.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_id(DKCT_GUI *gui, char *il)
+{
+ int back = 0;
+ char *p1; /* Start of text. */
+
+
+#line 2062 "dkct-gui.ctr"
+ if(gui->c_el) {
+ switch((gui->c_el)->cln) {
+ case 5: case 6: case 7: case 8: case 9: case 10: {
+
+
+#line 2066 "dkct-gui.ctr"
+ /* Warning: Attribute not applicable to class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ if(!((gui->c_el)->idname)) {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ dk3str_c8_delnl(il);
+ (gui->c_el)->idname = dk3str_c8_dup_app(p1, (gui->psrc)->app);
+ if((gui->c_el)->idname) {
+ back = 1;
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ /* ERROR: Syntax, empty ID */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 71);
+ }
+ } else {
+ /* ERROR: Syntax, ID already defined! */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 60);
+ }
+ }
+
+
+#line 2093 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set constructor arguments.
+ @param gui GUI description.
+ @param il Value part of input line.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_constructor(DKCT_GUI *gui, char *il)
+{
+ int back = 0;
+ char *p1; /* Start of text. */
+
+
+#line 2110 "dkct-gui.ctr"
+ if(gui->c_el) {
+ if((gui->c_el)->cln >= 0) {
+
+#line 2112 "dkct-gui.ctr"
+ /* Warning: Constructor attribute not recommended for class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ }
+ if(!((gui->c_el)->constructor)) {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ dk3str_c8_delnl(il);
+ (gui->c_el)->constructor = dk3str_c8_dup_app(p1, (gui->psrc)->app);
+ if((gui->c_el)->constructor) {
+ back = 1;
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 57);
+ }
+ } else {
+ /* ERROR: Syntax, empty ID */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 61);
+ }
+ } else {
+ /* ERROR: Syntax, ID already defined! */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 60);
+ }
+ }
+
+#line 2138 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set border.
+ @param gui GUI description.
+ @param il Value part of input line.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_border(DKCT_GUI *gui, char *il)
+{
+ int back = 0;
+ int i = 0; /* Number of pixels for border. */
+ char *p1 = NULL; /* Current string to process. */
+ char *p2 = NULL; /* Next string to process. */
+
+
+#line 2157 "dkct-gui.ctr"
+ if(gui->c_el) {
+ switch((gui->c_el)->cln) {
+ case 0: case 1: case 2: case 3: case 4: {
+
+#line 2160 "dkct-gui.ctr"
+ /* Warning: Attribute not applicable to class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ if(sscanf(p1, "%d", &i) == 1) {
+ if(i >= 0) {
+ (gui->c_el)->border = i;
+ back = 1;
+ if(p2) {
+ (gui->c_el)->borderPos = DKCT_GUI_BORDER_POSITION_NONE;
+ while(p2) {
+ p1 = dk3str_c8_next(p2, NULL);
+ i = dk3str_c8_array_index(dkct_gui_border_position_names, p2, 0);
+ switch(i) {
+ case 0: {
+ (gui->c_el)->borderPos |= DKCT_GUI_BORDER_POSITION_ALL;
+ } break;
+ case 1: {
+ (gui->c_el)->borderPos |= DKCT_GUI_BORDER_POSITION_TOP;
+ } break;
+ case 2: {
+ (gui->c_el)->borderPos |= DKCT_GUI_BORDER_POSITION_LEFT;
+ } break;
+ case 3: {
+ (gui->c_el)->borderPos |= DKCT_GUI_BORDER_POSITION_RIGHT;
+ } break;
+ case 4: {
+ (gui->c_el)->borderPos |= DKCT_GUI_BORDER_POSITION_BOTTOM;
+ } break;
+ default: {
+ back = 0;
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p2);
+ } break;
+ }
+ p2 = p1;
+ }
+ } else {
+ (gui->c_el)->borderPos = DKCT_GUI_BORDER_POSITION_ALL;
+ }
+ }
+ }
+ }
+ }
+
+
+#line 2208 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set proportion to grow the object.
+ @param gui GUI description.
+ @param il Value part of input line.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_proportion(DKCT_GUI *gui, char *il)
+{
+ int back = 0;
+ int i; /* Proportion value. */
+
+
+#line 2225 "dkct-gui.ctr"
+ if(gui->c_el) {
+ switch((gui->c_el)->cln) {
+ case 0: case 1: case 2: case 3: {
+
+#line 2228 "dkct-gui.ctr"
+ /* Warning: Attribute not applicable to class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ if(sscanf(il, "%d", &i) == 1) {
+ if(i >= 0) {
+ back = 1;
+ (gui->c_el)->proportion = i;
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_WARNING, 76, 77, il);
+ }
+ }
+
+
+#line 2243 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set status text.
+ @param gui GUI description.
+ @param il Value part of input line.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_status_text(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Start of text. */
+ int back = 0;
+
+
+#line 2261 "dkct-gui.ctr"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ {
+ } break;
+ default: {
+
+#line 2271 "dkct-gui.ctr"
+ /* Warning: Attribute not applicable to class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ if(el->stbText) {
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 74, 75, el->stbText);
+ }
+ dk3_release(el->stbText);
+ el->stbText = dk3str_c8_dup_app(p1, (gui->psrc)->app);
+ if(el->stbText) {
+ back = 1;
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 57);
+ }
+ }
+ }
+ }
+
+
+#line 2294 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set expand flag.
+ @param gui GUI description.
+ @param il Value part of input line.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_expand(DKCT_GUI *gui, char *il)
+{
+ int back = 0;
+ char *p1; /* Start of text. */
+
+
+#line 2311 "dkct-gui.ctr"
+ if(gui->c_el) {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ (void)dk3str_c8_next(p1, NULL);
+ if(dk3str_c8_is_bool(p1)) {
+ back = 1;
+ if(dk3str_c8_is_on(p1)) {
+ (gui->c_el)->expandFlag = 0x01;
+ } else {
+ (gui->c_el)->expandFlag = 0x00;
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ /* ERROR: Not a boolean! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 70);
+ }
+ }
+ }
+
+#line 2329 "dkct-gui.ctr"
+ return back;
+}
+
+
+/** Set text for label or button.
+ @param gui GUI description.
+ @param il Value part of input line.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_text(DKCT_GUI *gui, char *il)
+{
+ int back = 0;
+ char *p1; /* Start of text. */
+
+
+#line 2345 "dkct-gui.ctr"
+ if(gui->c_el) {
+ switch((gui->c_el)->cln) {
+ case -1:
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 9:
+ case 15:
+ case 16:
+ case 19:
+ case 20:
+ case 21:
+ case 22:
+ case 23:
+ case 28:
+ case 29:
+ case 31:
+ case 36:
+ case 37:
+ case 40:
+ {
+ } break;
+ default: {
+
+#line 2370 "dkct-gui.ctr"
+ /* Warning: Attribute not applicable for class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ if(!((gui->c_el)->text)) {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ dk3str_c8_delnl(il);
+ (gui->c_el)->text = dk3str_c8_dup_app(p1, (gui->psrc)->app);
+ if((gui->c_el)->text) {
+ back = 1;
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 57);
+ }
+ } else {
+ /* ERROR: Syntax, empty ID */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 71);
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ }
+ } else {
+ /* ERROR: Syntax, ID already defined! */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 60);
+ }
+ }
+
+#line 2397 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set text for label or button.
+ @param gui GUI description.
+ @param il Value part of input line.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_tip_text(DKCT_GUI *gui, char *il)
+{
+ int back = 0;
+ char *p1; /* Start of text. */
+
+
+#line 2414 "dkct-gui.ctr"
+ if(gui->c_el) {
+ switch((gui->c_el)->cln) {
+ case -1:
+ case 15:
+ case 16:
+ case 17:
+ case 18:
+ case 19:
+ case 20:
+ case 21:
+ case 22:
+ case 23:
+ case 25:
+ case 26:
+ case 27:
+ case 28:
+ case 29:
+ case 30:
+ case 36:
+ case 37: /* wxMenuItem */
+ case 39:
+ case 40:
+ {
+ } break;
+ default: {
+
+#line 2439 "dkct-gui.ctr"
+ /* Warning: Attribute not applicable to class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ if(!((gui->c_el)->tipText)) {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ dk3str_c8_delnl(il);
+ (gui->c_el)->tipText = dk3str_c8_dup_app(p1, (gui->psrc)->app);
+ if((gui->c_el)->tipText) {
+ back = 1;
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 57);
+ }
+ } else {
+ /* ERROR: Syntax, empty ID */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 71);
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ }
+ } else {
+ /* ERROR: Syntax, tip text already defined! */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 62);
+ }
+ }
+
+#line 2466 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set root object type (frame or dialog).
+ @param gui GUI structure.
+ @param il Value part of input line.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_type(DKCT_GUI *gui, char *il)
+{
+ int back = 0;
+
+
+#line 2482 "dkct-gui.ctr"
+ if(gui->c_el) {
+ if(((gui->c_el)->number == 0) && (!((gui->c_el)->parent))) {
+ switch(dk3str_c8_array_index(dkct_gui_base_type_names, il, 0)) {
+ case 0: {
+ (gui->c_el)->cln = 0;
+ back = 1;
+ } break;
+ case 1: {
+ (gui->c_el)->cln = 1;
+ back = 1;
+ } break;
+ default: {
+ /* ERROR: Illegal type */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 63);
+ } break;
+ }
+ } else {
+
+#line 2500 "dkct-gui.ctr"
+ /* ERROR: Attribute applicable to root element only! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 55);
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ }
+ }
+
+#line 2505 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Read placement int value from text.
+ The text may be an absolute or relative number or a dot.
+ @param dest Pointer to destination variable.
+ @param gui GUI structure.
+ @param tptr Text to process.
+ @param oldval Previous value.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_read_number_from_string(
+ int *dest,
+ DKCT_GUI *gui,
+ char *tptr,
+ int oldval
+)
+{
+ int back = 0;
+ int i; /* Number read. */
+
+ if(dk3str_c8_cmp(tptr, dkct_gui_out_kw[15]) == 0) {
+ *dest = oldval; back = 1;
+ } else {
+ if(*tptr == '+') {
+ if(sscanf(&(tptr[1]), dkct_gui_out_kw[16], &i) == 1) {
+ *dest = oldval + i; back = 1;
+ }
+ } else {
+ if(*tptr == '-') {
+ if(sscanf(&(tptr[1]), dkct_gui_out_kw[16], &i) == 1) {
+ *dest = oldval - i; back = 1;
+ }
+ } else {
+ if(sscanf(tptr, dkct_gui_out_kw[16], &i) == 1) {
+ *dest = i; back = 1;
+ }
+ }
+ }
+ }
+ if(!(back)) {
+ /* ERROR: Syntax: Not a numeric value! */
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 64, 65, tptr);
+ }
+ return back;
+}
+
+
+
+/** Apply align specified as text to an object.
+ @param gui GUI description.
+ @param oa Alignment as found so far.
+ @param ptext Text to process.
+ @return Updated alignment.
+*/
+static
+unsigned char
+dkct_gui_apply_align(DKCT_GUI *gui, unsigned char oa, char *ptext)
+{
+ unsigned char back;
+ back = oa;
+
+ switch(dk3str_c8_array_index(dkct_gui_align_names, ptext, 0)) {
+ case 0: {
+ back = (back & (~(DKCT_GUI_ALIGN_H_MASK))) | DKCT_GUI_ALIGN_H_LEFT;
+ } break;
+ case 1: {
+ back = (back & (~(DKCT_GUI_ALIGN_H_MASK))) | DKCT_GUI_ALIGN_H_RIGHT;
+ } break;
+ case 2: {
+ back = (back & (~(DKCT_GUI_ALIGN_V_MASK))) | DKCT_GUI_ALIGN_V_TOP;
+ } break;
+ case 3: {
+ back = (back & (~(DKCT_GUI_ALIGN_V_MASK))) | DKCT_GUI_ALIGN_V_BOTTOM;
+ } break;
+ case 4: {
+ back = DKCT_GUI_ALIGN_H_CENTER | DKCT_GUI_ALIGN_V_CENTER;
+ } break;
+ case 5: {
+ back = (back & (~(DKCT_GUI_ALIGN_H_MASK))) | DKCT_GUI_ALIGN_H_CENTER;
+ } break;
+ case 6: {
+ back = (back & (~(DKCT_GUI_ALIGN_V_MASK))) | DKCT_GUI_ALIGN_V_CENTER;
+ } break;
+ default: {
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, ptext);
+ /* ERROR: Illegal keyword */
+ } break;
+ }
+ return back;
+}
+
+
+
+/** Register additional placement information.
+ Process value part of "contents = element 0 0 1 1 left top" line.
+ @param gui GUI structure.
+ @param parent Parent element.
+ @param gel Element to add.
+ @param p Texts, starting with element name.
+ @param szp Number of elements used in \a p.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_add_additional_placement_info(
+ DKCT_GUI *gui,
+ DKCT_GUI_ELEMENT *parent,
+ DKCT_GUI_ELEMENT *gel,
+ char **p,
+ size_t szp
+)
+{
+ int back = 1;
+ int x; /* Start column. */
+ int y; /* Start row. */
+ int w; /* Number of columns. */
+ int h; /* Number of rows. */
+
+
+#line 2628 "dkct-gui.ctr"
+ switch((gui->c_el)->cln) {
+ case 5: case 9: {
+ /*
+ Box sizer / static box sizer.
+ contents = element [align]
+ */
+ if(szp > 1) {
+ gel->align = 0x00;
+ gel->align = dkct_gui_apply_align(gui, gel->align, p[1]);
+ if(szp > 2) {
+ gel->align = dkct_gui_apply_align(gui, gel->align, p[2]);
+ }
+ }
+ } break;
+ case 6: case 8: {
+ /*
+ Flex grid sizer.
+ Grid sizer.
+ contents = element x y [align [align]]
+ */
+ back = 0;
+ if(szp >= 3) {
+ if(dkct_gui_read_number_from_string(&x, gui, p[1], parent->curx)) {
+ if(dkct_gui_read_number_from_string(&y, gui, p[2], parent->cury)) {
+ gel->posx = x; gel->posy = y;
+ parent->curx = x; parent->cury = y;
+ back = 1;
+ if(szp > 3) {
+ gel->align = 0x00;
+ gel->align = dkct_gui_apply_align(gui, gel->align, p[3]);
+ if(szp > 4) {
+ gel->align = dkct_gui_apply_align(gui, gel->align, p[4]);
+ }
+ }
+ }
+ }
+ }
+ } break;
+ case 7: {
+ /*
+ Gridbag sizer.
+ contents = element x y w h [align [align]]
+ */
+ back = 0;
+ if(szp >= 5) {
+ if(dkct_gui_read_number_from_string(&y, gui, p[1], parent->cury)) {
+ if(dkct_gui_read_number_from_string(&x, gui, p[2], parent->curx)) {
+ gel->posx = x; gel->posy = y; parent->curx = x; parent->cury = y;
+ if(sscanf(p[3], dkct_gui_out_kw[16], &h) == 1) {
+ if(sscanf(p[4], dkct_gui_out_kw[16], &w) == 1) {
+ gel->spanx = w; gel->spany = h; back = 1;
+ if(szp > 5) {
+ gel->align = 0x00;
+ gel->align = dkct_gui_apply_align(gui, gel->align, p[5]);
+ if(szp > 6) {
+ gel->align = dkct_gui_apply_align(gui, gel->align, p[6]);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } break;
+ case 10: {
+ /*
+ Standard dialog button sizer.
+ Ignore anything but the element name.
+ contents = element
+ */
+ } break;
+ default: {
+ /*
+ We don't know whether or not we are a sizer or anything
+ else. So we ignore anything but the element name.
+ */
+ } break;
+ }
+
+#line 2706 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Add one contents line.
+ @param gui GUI structure.
+ @param il Value part of input line.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_add_contents(DKCT_GUI *gui, char *il)
+{
+ int back = 0;
+ char *p[16]; /* Strings in text. */
+ char *p1; /* Pseudo-object start. */
+ char *p2; /* Pseudo-object args start. */
+ char *p3; /* Pseudo-object next arg. */
+ DKCT_GUI_ELEMENT *gel; /* Element to add. */
+ size_t szp; /* Number of strings in text. */
+ int pso; /* Pseudo object value. */
+ int i;
+
+
+#line 2730 "dkct-gui.ctr"
+ if(gui->c_el) {
+ switch((gui->c_el)->cln) {
+ case 0: /* wxFrame */
+ case 1: /* wxDiaglog */
+ case 2: /* wxMDIParentFrame */
+ case 3: /* wxMDIChildFrame */
+ case 5: /* wxBoxSizer */
+ case 6: /* wxFlexGridSizer */
+ case 7: /* wxGridBagSizer */
+ case 8: /* wxGridSizer */
+ case 9: /* wxStaticBoxSizer */
+ case 10: /* wxStdDialogButtonSizer */
+ case 11: /* wxPanel */
+ case 12: /* wxNotebook */
+ case 13: /* wxScrolledWindow */
+ case 14: /* wxSplitterWindow */
+ case 35: /* wxMenuBar */
+ case 36: /* wxMenu */
+ case 38: /* wxToolBar */
+ case 39: /* wxStatusBar */
+ {
+ } break;
+ default: {
+
+#line 2753 "dkct-gui.ctr"
+ /* Warning: Attribute not applicable to this class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ for(szp = 0; szp < 16; szp++) { p[szp] = NULL; }
+ szp = dk3str_c8_explode(p, 15, il, NULL);
+ if(szp > 0) {
+
+#line 2760 "dkct-gui.ctr"
+ gel = dkct_gui_elem_next(gui, p[0]);
+ if(gel) {
+
+#line 2762 "dkct-gui.ctr"
+ if(dk3sto_add((gui->c_el)->s_contents, gel)) {
+
+#line 2763 "dkct-gui.ctr"
+ if(*(p[0]) == '$') {
+
+#line 2764 "dkct-gui.ctr"
+ p1 = p[0]; p2 = NULL; p3 = NULL;
+ p2 = dk3str_c8_chr(p1, '(');
+ if(p2) {
+
+#line 2767 "dkct-gui.ctr"
+ *(p2++) = '\0';
+ p3 = dk3str_c8_rchr(p2, ')');
+ if(p3) {
+
+#line 2770 "dkct-gui.ctr"
+ *p3 = '\0';
+ }
+ }
+ pso = dk3str_c8_array_index(dkct_gui_pseudo_object_names, p[0], 0);
+ if(pso >= 0) {
+ gel->pseudoobj = 1 + pso;
+ back = 1;
+ }
+ if(back) {
+ switch(pso) {
+ case 0: case 1: {
+ if(pso == 0) {
+
+#line 2782 "dkct-gui.ctr"
+ gel->proportion = 1;
+#if 0
+ /*
+ 2011-07-30: No wxGROW for stretch/spacer.
+ */
+ gel->expandFlag = 0x01;
+#endif
+ }
+ if(p2) {
+
+#line 2791 "dkct-gui.ctr"
+ p3 = dk3str_c8_chr(p2, ',');
+ if(p3) *(p3++) = '\0';
+ if(sscanf(p2, "%d", &i) == 1) {
+
+#line 2794 "dkct-gui.ctr"
+ gel->sizex = i;
+ gel->sizey = i;
+ } else {
+ /* ERROR: Not an integer! */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 64, 65, p2);
+ back = 0;
+ }
+ if(p3) {
+
+#line 2803 "dkct-gui.ctr"
+ p2 = dk3str_c8_chr(p3, ',');
+ if(p2) *(p2++) = '\0';
+ if(sscanf(p3, "%d", &i) == 1) {
+
+#line 2806 "dkct-gui.ctr"
+ gel->sizey = i;
+ } else {
+ /* ERROR: Not an integer! */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 64, 65, p2);
+ back = 0;
+ }
+ if(p2) {
+
+#line 2814 "dkct-gui.ctr"
+ if(sscanf(p2, "%d", &i) == 1) {
+
+#line 2815 "dkct-gui.ctr"
+ gel->proportion = i;
+ } else {
+ /* ERROR: Not an integer! */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 64, 65, p2);
+ back = 0;
+ }
+ }
+ }
+ }
+ } break;
+ }
+ }
+ if(back) {
+ back = dkct_gui_add_additional_placement_info(
+ gui, gui->c_el, gel, p, szp
+ );
+ }
+ } else {
+
+#line 2834 "dkct-gui.ctr"
+ back = dkct_gui_add_additional_placement_info(
+ gui, gui->c_el, gel, p, szp
+ );
+ }
+ } else {
+
+#line 2839 "dkct-gui.ctr"
+ /* ERROR: Memory */
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 57);
+ }
+ } else {
+
+#line 2844 "dkct-gui.ctr"
+ /* ERROR: Memory */
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 57);
+ }
+ } else {
+
+#line 2849 "dkct-gui.ctr"
+ /* ERROR: Empty line */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 66);
+ }
+ } else {
+
+#line 2854 "dkct-gui.ctr"
+ }
+
+#line 2855 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set up grid for current GUI object.
+ @param gui GUI description.
+ @param pv Text describing the grid.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_grid(DKCT_GUI *gui, char *pv)
+{
+ int back = 0;
+ char *p1 = NULL; /* First text string. */
+ char *p2 = NULL; /* Second text string. */
+ char *p3 = NULL; /* Third text string. */
+ char *p4 = NULL; /* Fourth text string. */
+ DKCT_GUI_ELEMENT *co; /* Current object to modify. */
+ int v = 0; /* Number read from string. */
+ int i1 = 0; /* First int value. */
+ int i2 = 0; /* Second int value. */
+ int i3 = 0; /* Third int value. */
+ int i4 = 0; /* Fourth int value. */
+
+
+#line 2881 "dkct-gui.ctr"
+ co = gui->c_el;
+ if(co) {
+ switch(co->cln) {
+ case 6: case 7: case 8:
+ {
+ } break;
+ default: {
+
+#line 2888 "dkct-gui.ctr"
+ /* Warning: Attribute not applicable to class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ p1 = dk3str_c8_start(pv, NULL);
+ if(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ if(p2) {
+ p3 = dk3str_c8_next(p2, NULL);
+ if(p3) {
+ p4 = dk3str_c8_next(p3, NULL);
+ if(p4) {
+ dk3str_c8_next(p4, NULL);
+ }
+ }
+ }
+ }
+ if(p1) {
+ if(sscanf(p1, "%d", &i1) == 1) {
+ if(i1 > 0) {
+ v = 1;
+ if(p2) {
+ if(sscanf(p2, "%d", &i2) == 1) {
+ if(i2 > 0) {
+ v = 2;
+ if(p3) {
+ if(sscanf(p3, "%d", &i3) == 1) {
+ if(i3 >= 0) {
+ v = 3;
+ if(p4) {
+ if(sscanf(p4, "%d", &i4) == 1) {
+ if(i4 >= 0) {
+ v = 4;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ switch(co->cln) {
+ case 6: case 8: { /* grid/flexgrid */
+ if(v >= 2) {
+ back = 1;
+ co->gridrows = i1;
+ co->gridcolumns = i2;
+ if(v >= 3) {
+ co->gridgapy = i3;
+ if(v >= 4) {
+ co->gridgapx = i4;
+ }
+ }
+ }
+ if(!(back)) {
+ /* Syntax error. */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 67);
+ }
+ } break;
+ case 7: { /* gridbag */
+ back = 1;
+ if(v >= 1) {
+ co->gridgapy = i1;
+ if(v >= 2) {
+ co->gridgapx = i2;
+ }
+ }
+ } break;
+ default: { back = 1; }
+ }
+ } else {
+ /* ERROR: No current element yet */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 68);
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ }
+
+#line 2968 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set sash for splitter window.
+ @param gui GUI description.
+ @param pv Text describing the grid.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_sash(DKCT_GUI *gui, char *pv)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ int i; /* Number read from string. */
+ int back = 0;
+
+
+#line 2986 "dkct-gui.ctr"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 14: {
+ } break;
+ default: {
+
+#line 2992 "dkct-gui.ctr"
+ /* Warning: Attribute not applicable to class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ {
+ i = 0;
+ if(sscanf(pv, "%d", &i) == 1) {
+ back = 1;
+ el->sash = i;
+ }
+ }
+ }
+
+
+#line 3005 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set minimum pane size for splitter window.
+ @param gui GUI description.
+ @param pv Text describing the grid.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_min_pane_size(DKCT_GUI *gui, char *pv)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ int i; /* Number read from string. */
+ int back = 0;
+
+
+#line 3023 "dkct-gui.ctr"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 14: {
+ } break;
+ default: {
+
+#line 3029 "dkct-gui.ctr"
+ /* Warning: Attribute not applicable to class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ i = 0;
+ if(sscanf(pv, "%d", &i) == 1) {
+ back = 1;
+ el->minPaneSize = i;
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, pv);
+ }
+ }
+
+
+#line 3043 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set flag whether or not the current button is the
+ start of a new radio button group.
+ @param gui GUI description.
+ @param pv Text to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_start_radio_button_group(DKCT_GUI *gui, char *pv)
+{
+ int back = 0;
+ DKCT_GUI_ELEMENT *co; /* Element to modify. */
+ char *p1; /* Start of text. */
+
+
+#line 3062 "dkct-gui.ctr"
+ co = gui->c_el;
+ if(co) {
+ p1 = dk3str_c8_start(pv, NULL);
+ if(p1) {
+ dk3str_c8_delnl(p1);
+ if(dk3str_c8_is_bool(p1)) {
+ back = 1;
+ if(dk3str_c8_is_on(p1)) {
+ co->startGroup = 0x01;
+ } else {
+ co->startGroup = 0x00;
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 70);
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 69);
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 68);
+ }
+
+
+#line 3087 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set size of current GUI object.
+ @param gui GUI description.
+ @param pv Text containing the size.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_size_for_object(DKCT_GUI *gui, char *pv)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Width. */
+ char *p2; /* Height. */
+ int i1 = 0; /* Width. */
+ int i2 = 0; /* Height. */
+ int back = 0;
+
+
+#line 3108 "dkct-gui.ctr"
+ if(gui->c_el) {
+ el = gui->c_el;
+ p1 = dk3str_c8_start(pv, NULL);
+ if(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ if(p2) {
+ if(sscanf(p1, "%d", &i1) == 1) {
+ if(sscanf(p2, "%d", &i2) == 1) {
+ if((i1 >= 0) && (i2 >= 0)) {
+ back = 1;
+ el->sizex = i1; el->sizey = i2;
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p2);
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p1);
+ }
+ }
+ }
+ }
+
+
+#line 3132 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set spin control direction.
+ @param gui GUI description.
+ @param il Value to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_direction(DKCT_GUI *gui, char *il)
+{
+ int back = 0;
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Start of text. */
+
+
+#line 3150 "dkct-gui.ctr"
+ el = gui->c_el;
+ if(el) {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ dk3str_c8_next(p1, NULL);
+ switch(el->cln) {
+ case 5: /* box sizer */
+ case 9: /* static box sizer */
+ case 25: /* spin button */
+ case 26: /* spin control */
+ case 13: /* scrolled window */
+ case 30: /* gauge */
+ case 33: /* static line */
+ {
+ } break;
+ default: {
+
+#line 3166 "dkct-gui.ctr"
+ /* Warning: Direction ignored for this class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ switch(dk3str_c8_array_index(dkct_gui_direction_names, p1, 0)) {
+ case 0: {
+ el->direction = DKCT_GUI_DIRECTION_HORIZONTAL;
+ back = 1;
+ } break;
+ case 1: {
+ el->direction = DKCT_GUI_DIRECTION_VERTICAL;
+ back = 1;
+ } break;
+ case 2: {
+ if(el->cln == 13) {
+ el->direction = DKCT_GUI_DIRECTION_BOTH;
+ back = 1;
+ } else {
+ /* ERROR: Only one direction allowed here! */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 72);
+ }
+ } break;
+ default: {
+ /* ERROR: Unknown direction! */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 73);
+ } break;
+ }
+ }
+ }
+
+
+#line 3198 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set spin control range.
+ @param gui GUI description.
+ @param il Value to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_range(DKCT_GUI *gui, char *il)
+{
+ int back = 0;
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Minimum. */
+ char *p2; /* Maximum. */
+ int i1 = 0; /* Minimum. */
+ int i2 = 100; /* Maximum. */
+
+
+#line 3219 "dkct-gui.ctr"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 25: /* spin */
+ case 26: /* spin */
+ case 27: /* slider */
+ case 30: /* gauge */
+ {
+ } break;
+ default: {
+ /* Warning: Range ignored for this class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ if(p2) {
+ if(sscanf(p1, "%d", &i1) == 1) {
+ if(sscanf(p2, "%d", &i2) == 1) {
+ el->spinMin = i1; el->spinMax = i2; back = 1;
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p2);
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p1);
+ }
+ } else {
+ if(el->cln == 30) { /* Gauge has only one value */
+ if(sscanf(p1, "%d", &i1) == 1) {
+ el->spinMax = i1; el->spinMin = 0; back = 1;
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p1);
+ }
+ }
+ }
+ }
+ }
+
+
+#line 3261 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set spin control value.
+ @param gui GUI description.
+ @param il Value to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_value(DKCT_GUI *gui, char *il)
+{
+ int back = 0;
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Start of text. */
+ int i1 = 0; /* Value. */
+
+
+#line 3280 "dkct-gui.ctr"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 25: /* spin */
+ case 26: /* spin */
+ case 27: /* slider */
+ case 30: /* gauge */
+ {
+ } break;
+ default: {
+ /* Warning: Range ignored for this class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ dk3str_c8_next(p1, NULL);
+ if(sscanf(p1, "%d", &i1) == 1) {
+ el->spinVal = i1;
+ back = 1;
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p1);
+ }
+ }
+ }
+
+
+#line 3307 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set spin control wrap flag.
+ @param gui GUI description.
+ @param il Value to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_wrap(DKCT_GUI *gui, char *il)
+{
+ int back = 0;
+ char *p1; /* Start of text. */
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+
+
+#line 3325 "dkct-gui.ctr"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 25: /* spin button */
+ case 26: /* spin control */
+ {
+ } break;
+ default: {
+ /* ERROR: Wrap ignored for this class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ dk3str_c8_next(p1, NULL);
+ if(dk3str_c8_is_bool(p1)) {
+ back = 1;
+ if(dk3str_c8_is_on(p1)) {
+ el->spinWrap = 0x01;
+ } else {
+ el->spinWrap = 0x00;
+ }
+ } else {
+ /* ERROR: Not a boolean value! */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 70);
+ }
+ }
+ }
+
+#line 3354 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set spin use keys flag.
+ @param gui GUI description.
+ @param il Value to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_keys(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Start of text. */
+ int back = 0;
+
+
+#line 3372 "dkct-gui.ctr"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 25: /* spin button */
+ case 26: /* spin control */
+ {
+ } break;
+ default: {
+
+#line 3380 "dkct-gui.ctr"
+ /* Warning: Keys setting ignored for this class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ dk3str_c8_next(p1, NULL);
+ if(dk3str_c8_is_bool(p1)) {
+ back = 1;
+ if(dk3str_c8_is_on(p1)) {
+ el->useKeys = 0x01;
+ } else {
+ el->useKeys = 0x00;
+ }
+ } else {
+ /* ERROR: Not a boolean! */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 70);
+ }
+ }
+ }
+
+#line 3401 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set validator for object.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_validator(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *co; /* Element to modify. */
+ int back = 0;
+
+
+#line 3418 "dkct-gui.ctr"
+ co = gui->c_el;
+ if(co) {
+ switch(co->cln) {
+ case 15: /* wxButton */
+ case 16: /* wxBitmapButton */
+ case 17: /* wxChoice */
+ case 18: /* wxComboBox */
+ case 19: /* wxCheckBox */
+ case 20: /* wxListBox */
+ case 21: /* wxCheckListBox */
+ case 22: /* wxRadioBox */
+ case 23: /* wxRadioButton */
+ case 24: /* wxScrollBar */
+ case 25: /* wxSpinButton */
+ case 26: /* wxSpinCtrl */
+ case 27: /* wxSlider */
+ case 28: /* wxTextCtrl */
+ case 29: /* wxToggleButton */
+ case 30: /* wxGauge */
+ {
+ } break;
+ default: {
+
+#line 3440 "dkct-gui.ctr"
+ /* Warning: Setting a validator is not recommended! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ if(co->validator) {
+ /* Warning: Redefinition of validator */
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_WARNING, 74, 75, co->validator);
+ }
+ dk3_release(co->validator);
+ co->validator = dk3str_c8_dup_app(il, (gui->psrc)->app);
+ if(co->validator) {
+ back = 1;
+ } else{
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 29);
+ }
+ }
+
+
+#line 3458 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set text style.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_text_style(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Current string to process. */
+ char *p2; /* Next string to process. */
+ int back = 0;
+
+
+#line 3477 "dkct-gui.ctr"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 28: /* wxTextCtrl */
+ case 31: /* wxStaticText */
+ case 41: /* wxGrid (readonly) */
+ {
+ } break;
+ default: {
+
+#line 3486 "dkct-gui.ctr"
+ /* Warning: Attribute not applicable for class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ back = 1;
+ while(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ switch(dk3str_c8_array_index(dkct_gui_text_style_names, p1, 0)) {
+ case 0: { /* enter */
+ el->textStyle |= DKCT_GUI_TEXT_ENTER;
+ } break;
+ case 1: { /* tab */
+ el->textStyle |= DKCT_GUI_TEXT_TAB;
+ } break;
+ case 2: { /* multi */
+ el->textStyle |= DKCT_GUI_TEXT_MULTILINE;
+ } break;
+ case 3: { /* password */
+ el->textStyle |= DKCT_GUI_TEXT_PASSWORD;
+ } break;
+ case 4: { /* readonly */
+ el->textStyle |= DKCT_GUI_TEXT_READONLY;
+ } break;
+ case 5: { /* rich */
+ el->textStyle |= DKCT_GUI_TEXT_RICH;
+ } break;
+ case 6: { /* rich2 */
+ el->textStyle |= DKCT_GUI_TEXT_RICH2;
+ } break;
+ case 7: { /* url */
+ el->textStyle |= DKCT_GUI_TEXT_URL;
+ } break;
+ case 8: { /* selection */
+ el->textStyle |= DKCT_GUI_TEXT_SHOWSEL;
+ } break;
+ case 9: { /* left */
+ el->textStyle |= DKCT_GUI_TEXT_LEFT;
+ } break;
+ case 10: { /* centered */
+ el->textStyle |= DKCT_GUI_TEXT_CENTRE;
+ } break;
+ case 11: { /* right */
+ el->textStyle |= DKCT_GUI_TEXT_RIGHT;
+ } break;
+ case 12: { /* nowrap */
+ el->textStyle |= DKCT_GUI_TEXT_NOWRAP;
+ } break;
+ case 13: { /* charwrap */
+ el->textStyle |= DKCT_GUI_TEXT_CHARWRAP;
+ } break;
+ case 14: { /* wordwrap */
+ el->textStyle |= DKCT_GUI_TEXT_WORDWRAP;
+ } break;
+ case 15: { /* bestwrap */
+ el->textStyle |= DKCT_GUI_TEXT_BESTWRAP;
+ } break;
+ case 16: { /* capitalize */
+ if(el->cln == 31) {
+ el->textStyle |= DKCT_GUI_TEXT_CAPITALIZE;
+ }
+ } break;
+ case 17: {
+ el->textStyle |= DKCT_GUI_TEXT_NO_AUTORESIZE;
+ } break;
+ default: {
+ back = 0;
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p1);
+ } break;
+ }
+ p1 = p2;
+ }
+ }
+ }
+ }
+
+
+#line 3565 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set button style.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_button_style(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Current string to process. */
+ char *p2; /* Next string to process. */
+ int back = 0;
+
+
+#line 3584 "dkct-gui.ctr"
+ el = gui->c_el;
+ if(el) {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ back = 1;
+ while(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ switch(dk3str_c8_array_index(dkct_gui_notebook_button_names, p1, 0)) {
+ case 0: { /* left */
+ el->buttonStyle |= DKCT_GUI_BUTTON_LEFT;
+ } break;
+ case 1: { /* top */
+ el->buttonStyle |= DKCT_GUI_BUTTON_TOP;
+ } break;
+ case 2: { /* right */
+ el->buttonStyle |= DKCT_GUI_BUTTON_RIGHT;
+ } break;
+ case 3: { /* bottom */
+ el->buttonStyle |= DKCT_GUI_BUTTON_BOTTOM;
+ } break;
+ case 4: { /* fit */
+ el->buttonStyle |= DKCT_GUI_BUTTON_EXACTFIT;
+ } break;
+ case 5: { /* no border */
+ el->buttonStyle |= DKCT_GUI_BUTTON_NO_BORDER;
+ } break;
+ default: {
+ back = 0;
+ /* ERROR: Unknown keyword. */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p1);
+ } break;
+ }
+ p1 = p2;
+ }
+ }
+ }
+
+
+#line 3622 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set notebook style.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_notebook_style(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Current string to process. */
+ char *p2; /* Next string to process. */
+ int back = 0;
+
+
+#line 3641 "dkct-gui.ctr"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 12: {
+ } break;
+ default: {
+
+#line 3647 "dkct-gui.ctr"
+ /* Warning: Attribute not applicable for class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ back = 1;
+ while(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ switch(dk3str_c8_array_index(dkct_gui_notebook_style_names, p1, 0))
+ {
+ case 0: { /* top */
+ el->notebookStyle |= DKCT_GUI_NB_TOP;
+ } break;
+ case 1: { /* left */
+ el->notebookStyle |= DKCT_GUI_NB_LEFT;
+ } break;
+ case 2: { /* right */
+ el->notebookStyle |= DKCT_GUI_NB_RIGHT;
+ } break;
+ case 3: { /* bottom */
+ el->notebookStyle |= DKCT_GUI_NB_BOTTOM;
+ } break;
+ case 4: { /* fixed-width */
+ el->notebookStyle |= DKCT_GUI_NB_FIXEDWIDTH;
+ } break;
+ case 5: { /* multiline */
+ el->notebookStyle |= DKCT_GUI_NB_MULTILINE;
+ } break;
+ case 6: { /* no-theme */
+ el->notebookStyle |= DKCT_GUI_NB_NOPAGETHEME;
+ } break;
+ case 7: { /* flat */
+ el->notebookStyle |= DKCT_GUI_NB_FLAT;
+ } break;
+ default: {
+ back = 0;
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p1);
+ } break;
+ }
+ p1 = p2;
+ }
+ }
+ }
+ }
+
+
+#line 3695 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set slider style.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_slider_style(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Current string to process. */
+ char *p2; /* Next string to process. */
+ int back = 0;
+
+
+#line 3714 "dkct-gui.ctr"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 27: {
+ } break;
+ default: {
+
+#line 3720 "dkct-gui.ctr"
+ /* Warning: Attribute not applicable for class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ back = 1;
+ while(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ switch(dk3str_c8_array_index(dkct_gui_slider_style_names, p1, 0)) {
+ case 0: {
+ el->sliderStyle |= DKCT_GUI_SL_STYLE_AUTOTICKS;
+ } break;
+ case 1: {
+ el->sliderStyle |= DKCT_GUI_SL_STYLE_LABELS;
+ } break;
+ case 2: {
+ el->sliderStyle |= DKCT_GUI_SL_STYLE_LEFT;
+ } break;
+ case 3: {
+ el->sliderStyle |= DKCT_GUI_SL_STYLE_RIGHT;
+ } break;
+ case 4: {
+ el->sliderStyle |= DKCT_GUI_SL_STYLE_TOP;
+ } break;
+ case 5: {
+ el->sliderStyle |= DKCT_GUI_SL_STYLE_BOTTOM;
+ } break;
+ case 6: {
+ el->sliderStyle |= DKCT_GUI_SL_STYLE_SELRANGE;
+ } break;
+ case 7: {
+ el->sliderStyle |= DKCT_GUI_SL_STYLE_INVERSE;
+ } break;
+ default: {
+ back = 0;
+ /* ERROR: Syntax, unknown slider style name! */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p1);
+ } break;
+ }
+ p1 = p2;
+ }
+ }
+ }
+
+
+#line 3766 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set splitter window style.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_splitter_window_style(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Current string to process. */
+ char *p2; /* Next string to process .*/
+ int back = 0;
+
+
+#line 3785 "dkct-gui.ctr"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 14: {
+ } break;
+ default: {
+
+#line 3791 "dkct-gui.ctr"
+ /* Warning: Attribute not applicable for class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ back = 1;
+ el->splitterStyle = 0U;
+ while(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ switch(dk3str_c8_array_index(dkct_gui_splitterw_style_names,p1,0)) {
+ case 0: {
+ el->splitterStyle |= DKCT_GUI_SPLITTERW_3D;
+ } break;
+ case 1: {
+ el->splitterStyle |= DKCT_GUI_SPLITTERW_3D_SASH;
+ } break;
+ case 2: {
+ el->splitterStyle |= DKCT_GUI_SPLITTERW_3D_BORDER;
+ } break;
+ case 3: {
+ el->splitterStyle |= DKCT_GUI_SPLITTERW_BORDER;
+ } break;
+ case 4: {
+ el->splitterStyle |= DKCT_GUI_SPLITTERW_NO_BORDER;
+ } break;
+ case 5: {
+ el->splitterStyle |= DKCT_GUI_SPLITTERW_NO_XP_THEME;
+ } break;
+ case 6: {
+ el->splitterStyle |= DKCT_GUI_SPLITTERW_PERMIT_UNSPLIT;
+ } break;
+ case 7: {
+ el->splitterStyle |= DKCT_GUI_SPLITTERW_LIVE_UPDATE;
+ } break;
+ default: {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p1);
+ } break;
+ }
+ p1 = p2;
+ }
+ }
+ }
+ }
+
+
+#line 3838 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set bitmap button style.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_bitmap_button_style(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Current string to process. */
+ char *p2; /* Next string to process. */
+ int back = 0;
+
+
+#line 3857 "dkct-gui.ctr"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 16:
+ case 32:
+ case 40:
+ {
+ } break;
+ default: {
+
+#line 3866 "dkct-gui.ctr"
+ /* Warning: Attribute not applicable to object! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ back = 1;
+ el->bitmapbStyle = 0x00;
+ while(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ switch(dk3str_c8_array_index(dkct_gui_bitmapb_style_names, p1, 0)) {
+ case 0: {
+ el->bitmapbStyle |= DKCT_GUI_BBUTTON_AUTODRAW;
+ } break;
+ case 1: {
+ el->bitmapbStyle |= DKCT_GUI_BBUTTON_LEFT;
+ } break;
+ case 2: {
+ el->bitmapbStyle |= DKCT_GUI_BBUTTON_TOP;
+ } break;
+ case 3: {
+ el->bitmapbStyle |= DKCT_GUI_BBUTTON_RIGHT;
+ } break;
+ case 4: {
+ el->bitmapbStyle |= DKCT_GUI_BBUTTON_BOTTOM;
+ } break;
+ default: {
+ /* ERROR: Unknown style entry! */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p1);
+ back = 0;
+ } break;
+ }
+ p1 = p2;
+ }
+ }
+ }
+ }
+
+
+#line 3906 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set gauge style.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_gauge_style(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Current string to process. */
+ char *p2; /* Next string to process. */
+ int back = 0;
+
+
+#line 3925 "dkct-gui.ctr"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 30: {
+ } break;
+ default: {
+ /* Only allowed for gauge elements! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ back = 1;
+ while(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ switch(dk3str_c8_array_index(dkct_gui_gauge_style_names, p1, 0)) {
+ case 0: {
+ el->gaugeStyle |= DKCT_GUI_GAUGE_SMOOTH;
+ } break;
+ default: {
+ /* Illegal keyword */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p1);
+ back = 0;
+ } break;
+ }
+ p1 = p2;
+ }
+ }
+ }
+ }
+
+
+#line 3958 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set icon.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_icon(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el;
+ char *p1;
+ int back = 0;
+
+
+#line 3976 "dkct-gui.ctr"
+ el = gui->c_el;
+ if(el) {
+ dk3_release(el->icon);
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ dk3str_c8_delnl(p1);
+ el->icon = dk3str_c8_dup_app(p1, (gui->psrc)->app);
+ if((el->parent) || (el->number)) {
+ /* Warning: Icon is recommended for top level windows only! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 63);
+ }
+ if(el->icon) {
+ back = 1;
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 57);
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 33);
+ }
+ }
+
+
+#line 4000 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set menu item style.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_menu_item_style(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Current string to process. */
+ char *p2; /* Next string to process. */
+ int back = 0;
+
+
+#line 4019 "dkct-gui.ctr"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 37:
+ case 40:
+ {
+ } break;
+ default: {
+
+#line 4027 "dkct-gui.ctr"
+ /* Warning: Attribute not applicable for class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ back = 1;
+ while(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ switch(dk3str_c8_array_index(dkct_gui_menu_item_style_names, p1, 0))
+ {
+ case 0: {
+ el->menuItemStyle = DKCT_GUI_MENU_ITEM_NORMAL;
+ } break;
+ case 1: {
+ el->menuItemStyle = DKCT_GUI_MENU_ITEM_SEPARATOR;
+ if(el->cln == 40) {
+ back = 0;
+ /* ERROR: Not allowed for tool bar buttons */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p1);
+ }
+ } break;
+ case 2: {
+ el->menuItemStyle = DKCT_GUI_MENU_ITEM_CHECK;
+ } break;
+ case 3: {
+ el->menuItemStyle = DKCT_GUI_MENU_ITEM_RADIO;
+ } break;
+ default: {
+ back = 0;
+ /* ERROR: Unknown style! */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p1);
+ } break;
+ }
+ p1 = p2;
+ }
+ }
+ }
+ }
+
+
+#line 4070 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set toolbar style.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_toolbar_style(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Current string to process. */
+ char *p2; /* Next string to process. */
+ int back = 0;
+
+
+#line 4089 "dkct-gui.ctr"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 38: {
+ } break;
+ default: {
+
+#line 4095 "dkct-gui.ctr"
+ /* Warning: Attribute not applicable for class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ back = 1;
+ while(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ switch(dk3str_c8_array_index(dkct_gui_toolbar_style_names,p1,0)) {
+ case 0: {
+ el->toolbarStyle |= DKCT_GUI_TOOLBAR_FLAT;
+ } break;
+ case 1: {
+ el->toolbarStyle |= DKCT_GUI_TOOLBAR_DOCKABLE;
+ } break;
+ case 2: {
+ el->toolbarStyle |= DKCT_GUI_TOOLBAR_TEXT;
+ } break;
+ case 3: {
+ el->toolbarStyle |= DKCT_GUI_TOOLBAR_NOICONS;
+ } break;
+ case 4: {
+ el->toolbarStyle |= DKCT_GUI_TOOLBAR_NODIVIDER;
+ } break;
+ case 5: {
+ el->toolbarStyle |= DKCT_GUI_TOOLBAR_HORZ_LAYOUT;
+ } break;
+ case 6: {
+ el->toolbarStyle |= DKCT_GUI_TOOLBAR_NO_TOOLTIPS;
+ } break;
+ case 7: {
+ el->toolbarStyle |= DKCT_GUI_TOOLBAR_BOTTOM;
+ } break;
+ case 8: {
+ el->toolbarStyle |= DKCT_GUI_TOOLBAR_RIGHT;
+ } break;
+ default: {
+ back = 0;
+ /* ERROR: Unknown style keyword */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p1);
+ } break;
+ }
+ p1 = p2;
+ }
+ }
+ }
+ }
+
+
+#line 4146 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set choices for combo, list etc.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_choices(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Current string to process. */
+ char *p2; /* Next string to process. */
+ int i; /* Number read from text. */
+ int back = 0;
+
+
+#line 4166 "dkct-gui.ctr"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 17: /* wxChoice */
+ case 18: /* wxComboBox */
+ case 20: /* wxListBox */
+ case 21: /* wxCheckListBox */
+ case 22: /* wxRadioBox */
+ {
+ } break;
+ default: {
+
+#line 4177 "dkct-gui.ctr"
+ /* Warning: Attribute not applicable to class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ if(p2) {
+
+#line 4186 "dkct-gui.ctr"
+ if(sscanf(p1, "%i", &i) == 1) {
+ if(i > 0) {
+ el->nChoices = i;
+ if(el->choices) {
+ /* Warning: Redefinition */
+ dkct_to_log_3(gui->psrc,1,DK3_LL_WARNING,74,75,el->choices);
+ }
+ dk3_release(el->choices);
+ el->choices = dk3str_c8_dup_app(p2, (gui->psrc)->app);
+ if(el->choices) {
+ back = 1;
+ } else {
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 29);
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ }
+ }
+ }
+ } else {
+
+#line 4205 "dkct-gui.ctr"
+ if(el->choices) {
+ /* Warning: Redefinition */
+ dkct_to_log_3(gui->psrc,1,DK3_LL_WARNING,74,75,el->choices);
+ }
+ dk3_release(el->choices);
+ el->nChoices = -1;
+ el->choices = dk3str_c8_dup_app(p1, (gui->psrc)->app);
+ if(el->choices) {
+ back = 1;
+ } else {
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 29);
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ }
+ }
+ }
+ }
+ }
+
+
+#line 4224 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set style for list box.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_list_box_style(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Start of text. */
+ int back = 0;
+
+
+#line 4242 "dkct-gui.ctr"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 20: /* list box */
+ case 21: /* check list box */
+ {
+ } break;
+ default: {
+
+#line 4250 "dkct-gui.ctr"
+ /* Warning: Attribute not applicable to class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ switch(dk3str_c8_array_index(dkct_gui_cb_sel_names, p1, 0)) {
+ case 0: {
+ el->selStyle = DKCT_GUI_SELECTION_STYLE_SINGLE; back = 1;
+ } break;
+ case 1: {
+ el->selStyle = DKCT_GUI_SELECTION_STYLE_MULTIPLE; back = 1;
+ } break;
+ case 2: {
+ el->selStyle = DKCT_GUI_SELECTION_STYLE_EXTENDED; back = 1;
+ } break;
+ default: {
+ /* ERROR: Illegal argument! */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p1);
+ } break;
+ }
+ }
+ }
+ }
+
+
+#line 4277 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set max number of rows/columns for radio box.
+ @param gui GUI description.
+ @param il Input line to process.
+ @param how Rows (0), columns (1).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_rb_max(DKCT_GUI *gui, char *il, int how)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Start of text. */
+ int i; /* Number read from text. */
+ int back = 0;
+
+
+#line 4297 "dkct-gui.ctr"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 22: case 41:
+ {
+ } break;
+ default: {
+
+#line 4304 "dkct-gui.ctr"
+ /* Warning: Attribute not applicable to class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ {
+ switch(el->cln) {
+ case 22: {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ if(sscanf(p1, "%d", &i) == 1) {
+ if(i > 0) {
+ back = 1;
+ el->maxRowsCols = i;
+ if(how) {
+ el->rbDirection = DKCT_GUI_RB_DIR_COLUMNS;
+ } else {
+ el->rbDirection = DKCT_GUI_RB_DIR_ROWS;
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ /* ERROR: Out of range. */
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 82, 83, p1);
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p1);
+ }
+ } else {
+ /* ERROR: Missing argument */
+ }
+ } break;
+ case 41: {
+ p1 = dk3str_c8_start(il, NULL);
+
+#line 4337 "dkct-gui.ctr"
+ if(p1) {
+ if(sscanf(p1, "%d", &i) == 1) {
+ if(i > 0) {
+ back = 1;
+ if(how) {
+ el->nColumns = i;
+ } else {
+ el->nRows = i;
+ }
+ } else {
+
+#line 4347 "dkct-gui.ctr"
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 82, 83, p1);
+ }
+ } else {
+
+#line 4351 "dkct-gui.ctr"
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p1);
+ }
+ }
+
+#line 4355 "dkct-gui.ctr"
+ } break;
+ }
+ }
+ }
+
+
+#line 4360 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set states for checkbox.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_states(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Current string to process. */
+ char *p2; /* Next string to process. */
+ int i; /* Number read from text. */
+ int back = 0;
+
+
+#line 4380 "dkct-gui.ctr"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 19: /* wxCheckBox */
+ {
+ } break;
+ default: {
+
+#line 4387 "dkct-gui.ctr"
+ /* Warning: Attribute not applicable to class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ {
+ i = 0;
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ if(sscanf(p1, "%d", &i) == 1) {
+ if((i == 2) || (i == 3)) {
+ if(i == 3) el->nStates = 0x03;
+ else el->nStates = 0x02;
+ back = 1;
+ if(p2) {
+ switch(dk3str_c8_array_index(dkct_gui_db_state_names, p2, 0)) {
+ case 0: {
+ el->state = 0x00;
+ } break;
+ case 1: {
+ el->state = 0x01;
+ } break;
+ case 2: {
+ if(el->nStates == 0x03) {
+ el->state = 0x02;
+ } else {
+ back = 0;
+ }
+ } break;
+ default: {
+ back = 0;
+ /* ERROR: Invalid state */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p2);
+ } break;
+ }
+ }
+ } else {
+ /* ERROR: Out of range! */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 82, 83, p1);
+ }
+ } else {
+ /* ERROR: Not a number */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 31);
+ }
+ }
+ }
+ }
+
+
+#line 4438 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set bitmap for bitmap button.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_bitmap(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Start of text. */
+ int back = 0;
+
+
+#line 4456 "dkct-gui.ctr"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 16:
+ case 32:
+ case 37:
+ case 40:
+ {
+ } break;
+ default: {
+
+#line 4466 "dkct-gui.ctr"
+ /* Warning: Attribute not applicable to class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ dk3str_c8_delnl(p1);
+ dk3_release(el->bitmapVarName);
+ el->bitmapVarName = dk3str_c8_dup_app(il, (gui->psrc)->app);
+ if(el->bitmapVarName) {
+ back = 1;
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 57);
+ }
+ }
+ }
+ }
+
+
+#line 4487 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set disabled bitmap for bitmap button.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_bitmap_disabled(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Start of text. */
+ int back = 0;
+
+
+#line 4505 "dkct-gui.ctr"
+ el = gui->c_el;
+ if(el) {
+ if(!((el->cln == 16) || (el->cln == 40))) {
+
+#line 4508 "dkct-gui.ctr"
+ /* Warning: Attribute not applicable to class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ }
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ dk3str_c8_delnl(p1);
+ dk3_release(el->bitmapDisabled);
+ el->bitmapDisabled = dk3str_c8_dup_app(il, (gui->psrc)->app);
+ if(el->bitmapDisabled) {
+ back = 1;
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 57);
+ }
+ }
+ }
+
+
+#line 4526 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set selected bitmap for bitmap button.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_bitmap_selected(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Value for bitmap. */
+ int back = 0;
+
+
+#line 4544 "dkct-gui.ctr"
+ el = gui->c_el;
+ if(el) {
+ if(el->cln != 16) {
+
+#line 4547 "dkct-gui.ctr"
+ /* Warning: Attribute not applicable for class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ }
+ {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ dk3str_c8_delnl(p1);
+ dk3_release(el->bitmapSelected);
+ el->bitmapSelected = dk3str_c8_dup_app(il, (gui->psrc)->app);
+ if(el->bitmapSelected) {
+ back = 1;
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 57);
+ }
+ }
+ }
+ }
+
+
+#line 4567 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set focus bitmap for bitmap button.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_bitmap_focus(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Bitmap value. */
+ int back = 0;
+
+
+#line 4585 "dkct-gui.ctr"
+ el = gui->c_el;
+ if(el) {
+ if(el->cln != 16) {
+
+#line 4588 "dkct-gui.ctr"
+ /* Warning: Attribute not applicable for class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ }
+ {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ dk3str_c8_delnl(p1);
+ dk3_release(el->bitmapFocus);
+ el->bitmapFocus = dk3str_c8_dup_app(il, (gui->psrc)->app);
+ if(el->bitmapFocus) {
+ back = 1;
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 57);
+ }
+ }
+ }
+ }
+
+
+#line 4608 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Set hover bitmap for bitmap button.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_bitmap_hover(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Bitmap value. */
+ int back = 0;
+
+
+#line 4626 "dkct-gui.ctr"
+ el = gui->c_el;
+ if(el) {
+ if(el->cln != 16) {
+
+#line 4629 "dkct-gui.ctr"
+ /* Warning: Attribute not applicable for class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ }
+ {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ dk3str_c8_delnl(p1);
+ dk3_release(el->bitmapHover);
+ el->bitmapHover = dk3str_c8_dup_app(il, (gui->psrc)->app);
+ if(el->bitmapHover) {
+ back = 1;
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 57);
+ }
+ }
+ }
+ }
+
+
+#line 4649 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Add row/column head.
+ @param gui GUI description.
+ @param pv Text for head.
+ @param how Direction (0=row head, 1=column head).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_add_grid_head(DKCT_GUI *gui, char const *pv, int how)
+{
+ DKCT_GRID_HEAD *gh;
+ int back = 0;
+
+
+#line 4667 "dkct-gui.ctr"
+ if((gui->c_el) && (pv)) {
+ switch((gui->c_el)->cln) {
+ case 41: {
+ if(how) {
+
+#line 4671 "dkct-gui.ctr"
+ if(!((gui->c_el)->sColumnHeads)) {
+ (gui->c_el)->sColumnHeads = dk3sto_open_app((gui->psrc)->app);
+ if((gui->c_el)->sColumnHeads) {
+ dk3sto_set_comp(
+ (gui->c_el)->sColumnHeads, dkct_grid_head_compare, 0
+ );
+ }
+ }
+ if(!((gui->c_el)->iColumnHeads)) {
+ if((gui->c_el)->sColumnHeads) {
+ (gui->c_el)->iColumnHeads =
+ dk3sto_it_open((gui->c_el)->sColumnHeads);
+ }
+ }
+ if(((gui->c_el)->sColumnHeads) && ((gui->c_el)->iColumnHeads)) {
+ gh = dkct_grid_head_new(pv, (gui->c_el)->nColumnHeads, gui->psrc);
+ if(gh) {
+ if(dk3sto_add((gui->c_el)->sColumnHeads, gh)) {
+ back = 1 ;
+ (gui->c_el)->nColumnHeads += 1;
+ } else {
+ dkct_grid_head_delete(gh);
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+
+#line 4702 "dkct-gui.ctr"
+ if(!((gui->c_el)->sRowHeads)) {
+ (gui->c_el)->sRowHeads = dk3sto_open_app((gui->psrc)->app);
+ if((gui->c_el)->sRowHeads) {
+ dk3sto_set_comp((gui->c_el)->sRowHeads,dkct_grid_head_compare,0);
+ }
+ }
+ if(!((gui->c_el)->iRowHeads)) {
+ if((gui->c_el)->sRowHeads) {
+ (gui->c_el)->iRowHeads = dk3sto_it_open((gui->c_el)->sRowHeads);
+ }
+ }
+ if(((gui->c_el)->sRowHeads) && ((gui->c_el)->iRowHeads)) {
+ gh = dkct_grid_head_new(pv, (gui->c_el)->nRowHeads, gui->psrc);
+ if(gh) {
+ if(dk3sto_add((gui->c_el)->sRowHeads, gh)) {
+ back = 1;
+ (gui->c_el)->nRowHeads += 1;
+ } else {
+ dkct_grid_head_delete(gh);
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ }
+ } break;
+ default: {
+ /* Warning: Attribute not applicable for class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ }
+
+#line 4737 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Add cell data.
+ @param gui GUI description.
+ @param pv Text to process (Row no, column no, text).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_add_grid_cell_data(DKCT_GUI *gui, char *pv)
+{
+ char *p1;
+ char *p2;
+ char *p3;
+ DKCT_CELL_DATA *pcd;
+ int row = 0;
+ int col = 0;
+ int back = 0;
+ if((gui->c_el) && (pv)) {
+ switch((gui->c_el)->cln) {
+ case 41: {
+ p1 = dk3str_c8_start(pv, NULL);
+ if (p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ if (p2) {
+ p3 = dk3str_c8_next(p2, NULL);
+ if (p3) {
+ if (0 != dk3ma_i_from_c8_string(&row, p1, NULL)) {
+ if (0 != dk3ma_i_from_c8_string(&col, p2, NULL)) {
+ if ((0 <= row) && (0 <= col)) {
+ if (!((gui->c_el)->sCellData)) {
+ (gui->c_el)->sCellData =
+ dk3sto_open_app((gui->psrc)->app);
+ if ((gui->c_el)->sCellData) {
+ dk3sto_set_comp(
+ (gui->c_el)->sCellData, dkct_grid_cell_compare, 0
+ );
+ }
+ }
+ if (((gui->c_el)->sCellData) && (!((gui->c_el)->iCellData)))
+ {
+ (gui->c_el)->iCellData =
+ dk3sto_it_open((gui->c_el)->sCellData);
+ }
+ if (((gui->c_el)->sCellData) && ((gui->c_el)->iCellData)) {
+ pcd = dkct_grid_cell_new(p3, row, col, gui->psrc);
+ if (pcd) {
+ if (dk3sto_add((gui->c_el)->sCellData, pcd)) {
+ back = 1;
+ } else {
+ dkct_grid_cell_delete(pcd);
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ /* !!!!! ERROR: Syntax (negative) */
+ }
+ } else {
+ /* !!!!! ERROR: Syntax (not a number) */
+ }
+ } else {
+ /* !!!!! ERROR: Syntax (not a number) */
+ }
+ } else {
+ /* !!!!! ERROR: No text to save */
+ }
+ } else {
+ /* !!!!! ERROR: No column */
+ }
+ } else {
+ /* !!!!! ERROR: No text */
+ }
+ } break;
+ default: {
+ /* Warning: Attribute not applicable for class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+/** Set grid style.
+ @param gui GUI description.
+ @param pv Text to process (Row no, column no, text).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_set_grid_style(DKCT_GUI *gui, char *pv)
+{
+ int back = 0;
+ char *p1;
+ char *p2;
+ if((gui->c_el) && (pv)) {
+ switch((gui->c_el)->cln) {
+ case 41: {
+ back = 1;
+ p1 = dk3str_c8_start(pv, NULL);
+ while (p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ switch (dk3str_c8_array_index(dkct_gui_grid_style_names, p1, 1)) {
+ case 0: {
+ (gui->c_el)->gridStyle |= DKCT_GUI_GRID_AS_DATA;
+ } break;
+ case 1: {
+ (gui->c_el)->gridStyle |= DKCT_GUI_GRID_AS_LABEL_ROWS;
+ } break;
+ case 2: {
+ (gui->c_el)->gridStyle |= DKCT_GUI_GRID_AS_LABEL_COLS;
+ } break;
+ case 3: {
+ (gui->c_el)->gridStyle |=
+ (DKCT_GUI_GRID_AS_LABEL_ROWS | DKCT_GUI_GRID_AS_LABEL_COLS);
+ } break;
+ default : {
+ /* !!!!! ERROR: Syntax */
+ } break;
+ }
+ p1 = p2;
+ }
+ } break;
+ default: {
+ /* Warning: Attribute not applicable for class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+/** Set tooltip flag for element.
+ @param gui GUI description.
+ @param pv Text value.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_set_tooltip_flag(DKCT_GUI *gui, char *pv)
+{
+ char *p1 = NULL;
+ int back = 0;
+ if ((NULL != gui) && (NULL != pv)) {
+ dk3str_c8_delnl(pv);
+ p1 = dk3str_c8_dup_app(pv, (gui->psrc)->app);
+ if (NULL != p1) {
+ back = 1;
+ if (0 == (gui->c_el)->number) {
+ if (NULL != gui->ttflag) {
+ /* Warning: Redefinition of tooltip flag */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 115);
+ }
+ dk3_release(gui->ttflag);
+ gui->ttflag = p1;
+ } else {
+ if (NULL != (gui->c_el)->ttflag) {
+ /* Warning: Redefinition of tooltip flag */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 115);
+ }
+ dk3_release((gui->c_el)->ttflag);
+ (gui->c_el)->ttflag = p1;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+
+/** Set gridTable entry for current object.
+ @param gui GUI description.
+ @param pv Text to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_set_table_for_grid(DKCT_GUI *gui, char *pv)
+{
+ char *p1 = NULL;
+ char *p2 = NULL;
+ int back = 0;
+ if(gui->c_el) {
+ switch((gui->c_el)->cln) {
+ case 41: {
+ p1 = dk3str_c8_start(pv, NULL);
+ if(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ if((gui->c_el)->gridTable) {
+ dkct_to_log_3(
+ gui->psrc, 1, DK3_LL_ERROR, 74, 75, (gui->c_el)->gridTable
+ );
+ }
+ dk3_release((gui->c_el)->gridTable);
+ (gui->c_el)->gridTable = dk3str_c8_dup_app(pv, (gui->psrc)->app);
+ if((gui->c_el)->gridTable) {
+ back = 1;
+ if(p2) {
+ if(dk3str_c8_is_on(p2)) {
+ (gui->c_el)->tableOwner = 0x01;
+ }
+ }
+ } else {
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ /* ERROR: Empty text! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 69);
+ }
+ } break;
+ default: {
+ /* Warning: Attribute not applicable for class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+/** Set minimum size for an object.
+ @param gui GUI description.
+ @param pv Text containing the size in pixels.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_set_minimum_size(DKCT_GUI *gui, char *pv)
+{
+ char *p1;
+ char *p2;
+ int i1;
+ int i2;
+ int back = 0;
+ p1 = dk3str_c8_start(pv, NULL);
+ if(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ if(p2) {
+ if(1 == sscanf(p1, "%d", &i1)) {
+ if(1 == sscanf(p2, "%d", &i2)) {
+ if(i1 < 0) i1 = 0;
+ if(i2 < 0) i2 = 0;
+ back = 1;
+ if(gui->c_el) {
+ (gui->c_el)->sizemx = i1;
+ (gui->c_el)->sizemy = i2;
+ }
+ } else {
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 64, 65, p2);
+ }
+ } else {
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 64, 65, p1);
+ }
+ } else {
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 69);
+ }
+ return back;
+}
+
+
+
+/** Compare two int pointers by number, reverse sort order.
+ @param l Left pointer.
+ @param r Right pointer.
+ @param cr Comparison criteria, ignored.
+ @return Comparison result for inverted sort order.
+*/
+static
+int
+dkct_int_compare(void const *l, void const *r, int cr)
+{
+ int const *pl;
+ int const *pr;
+ int back = 0;
+ pl = (int const *)l; pr = (int const *)r;
+ if(pl) {
+ if(pr) {
+ if(*pl > *pr) back = -1;
+ else {
+ if(*pl < *pr) back = 1;
+ }
+ } else back = -1;
+ } else {
+ if(pr) back = 1;
+ }
+ return back;
+}
+
+
+
+/** Note information about a growable row.
+ @param gui GUI description.
+ @param pv Text containing the row number.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_add_growable_row(DKCT_GUI *gui, char *pv)
+{
+ int *ip;
+ int back = 0;
+ int i;
+ if(gui->c_el) {
+ if(1 == sscanf(pv, "%d", &i)) {
+ if(i >= 0) {
+ if(!((gui->c_el)->sGrowRow)) {
+ (gui->c_el)->sGrowRow = dk3sto_open_app((gui->psrc)->app);
+ if((gui->c_el)->sGrowRow) {
+ dk3sto_set_comp((gui->c_el)->sGrowRow, dkct_int_compare, 0);
+ }
+ }
+ if(!((gui->c_el)->iGrowRow)) {
+ if((gui->c_el)->sGrowRow) {
+ (gui->c_el)->iGrowRow = dk3sto_it_open((gui->c_el)->sGrowRow);
+ }
+ }
+ if(((gui->c_el)->sGrowRow) && ((gui->c_el)->iGrowRow)) {
+ ip = dk3_new_app(int,1,(gui->psrc)->app);
+ if(ip) {
+ *ip = i;
+ if(dk3sto_add((gui->c_el)->sGrowRow, (void *)ip)) {
+ back = 1;
+ } else {
+ dk3_delete(ip);
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ /* ERROR: Syntax */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 112);
+ }
+ } else {
+ /* ERROR: Not a number! */
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 64, 65, pv);
+ }
+ }
+ return back;
+}
+
+
+
+/** Note information about a growable row.
+ @param gui GUI description.
+ @param pv Text containing the row number.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_add_growable_column(DKCT_GUI *gui, char *pv)
+{
+ int *ip;
+ int back = 0;
+ int i;
+ if(gui->c_el) {
+ if(1 == sscanf(pv, "%d", &i)) {
+ if(i >= 0) {
+ if(!((gui->c_el)->sGrowCol)) {
+ (gui->c_el)->sGrowCol = dk3sto_open_app((gui->psrc)->app);
+ if((gui->c_el)->sGrowCol) {
+ dk3sto_set_comp((gui->c_el)->sGrowCol, dkct_int_compare, 0);
+ }
+ }
+ if(!((gui->c_el)->iGrowCol)) {
+ if((gui->c_el)->sGrowCol) {
+ (gui->c_el)->iGrowCol = dk3sto_it_open((gui->c_el)->sGrowCol);
+ }
+ }
+ if(((gui->c_el)->sGrowCol) && ((gui->c_el)->iGrowCol)) {
+ ip = dk3_new_app(int,1,(gui->psrc)->app);
+ if(ip) {
+ *ip = i;
+ if(dk3sto_add((gui->c_el)->sGrowCol, (void *)ip)) {
+ back = 1;
+ } else {
+ dk3_delete(ip);
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ /* ERROR: Syntax */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 112);
+ }
+ } else {
+ /* ERROR: Not numeric! */
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 64, 65, pv);
+ }
+ }
+ return back;
+}
+
+
+
+/** Set "complete constructor specified" attribute.
+ @param gui GUI description.
+ @param pv Text to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_set_complete_constructor_specified(DKCT_GUI *gui, char *pv)
+{
+ int back = 0;
+ if(gui->c_el) {
+ if(pv) {
+ if(dk3str_c8_is_bool(pv)) {
+ back = 1;
+ if(dk3str_c8_is_on(pv)) {
+ (gui->c_el)->compConst = 0x01;
+ } else {
+ (gui->c_el)->compConst = 0x00;
+ }
+ } else {
+ /* ERROR: Not a boolean value! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 70);
+ }
+ } else {
+ (gui->c_el)->compConst = 0x00;
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Process one line containing object details.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_process_object_line(DKCT_GUI *gui, char *il)
+{
+ int back = 1;
+ char *pv; /* Value. */
+ int action; /* Attribute index. */
+
+
+#line 5208 "dkct-gui.ctr"
+ if(gui->c_el) {
+ pv = dk3str_c8_chr(il, '=');
+ if(pv) {
+ *(pv++) = '\0';
+ pv = dk3str_c8_start(pv, NULL);
+ if(pv) {
+ dk3str_c8_normalize(il, NULL, '-');
+ action = dk3str_c8_array_index(dkct_gui_attribute_keys, il, 0);
+ switch(action) {
+ case 0: case 23: {
+
+#line 5218 "dkct-gui.ctr"
+ back = dkct_gui_set_expand(gui, pv);
+ } break;
+ case 1: {
+
+#line 5221 "dkct-gui.ctr"
+ back = dkct_gui_set_type(gui, pv);
+ } break;
+ case 2: {
+
+#line 5224 "dkct-gui.ctr"
+ back = dkct_gui_set_menu_bar(gui, pv);
+ } break;
+ case 3: {
+
+#line 5227 "dkct-gui.ctr"
+ back = dkct_gui_set_tool_bar(gui, pv);
+ } break;
+ case 4: {
+
+#line 5230 "dkct-gui.ctr"
+ back = dkct_gui_set_status_bar(gui, pv);
+ } break;
+ case 5: {
+
+#line 5233 "dkct-gui.ctr"
+ back = dkct_gui_add_contents(gui, pv);
+ } break;
+ case 6: {
+
+#line 5236 "dkct-gui.ctr"
+ back = dkct_gui_set_text(gui, pv);
+ } break;
+ case 7: {
+
+#line 5239 "dkct-gui.ctr"
+ back = dkct_gui_set_id(gui, pv);
+ } break;
+ case 8: {
+
+#line 5242 "dkct-gui.ctr"
+ back = dkct_gui_set_tip_text(gui, pv);
+ } break;
+ case 9: {
+
+#line 5245 "dkct-gui.ctr"
+ back = dkct_gui_set_proportion(gui, pv);
+ } break;
+ case 10: {
+
+#line 5248 "dkct-gui.ctr"
+ back = dkct_gui_set_status_text(gui, pv);
+ } break;
+ case 11: {
+
+#line 5251 "dkct-gui.ctr"
+ back = dkct_gui_set_border(gui, pv);
+ } break;
+ case 12: {
+
+#line 5254 "dkct-gui.ctr"
+ back = dkct_gui_set_constructor(gui, pv);
+ } break;
+ case 13: {
+ back = dkct_gui_set_grid(gui, pv);
+ } break;
+ case 14: {
+ back = dkct_gui_set_sash(gui, pv);
+ } break;
+ case 15: {
+ back = dkct_gui_set_min_pane_size(gui, pv);
+ } break;
+ case 16: {
+ back = dkct_gui_set_bitmap(gui, pv);
+ } break;
+ case 17: {
+ back = dkct_gui_set_choices(gui, pv);
+ } break;
+ case 18: {
+ back = dkct_gui_set_states(gui, pv);
+ } break;
+ case 19: {
+ back = dkct_gui_set_size_for_object(gui, pv);
+ } break;
+ case 20: {
+ back = dkct_gui_set_list_box_style(gui, pv);
+ } break;
+ case 21: {
+ back = dkct_gui_set_rb_max(gui, pv, 0);
+ } break;
+ case 22: {
+ back = dkct_gui_set_rb_max(gui, pv, 1);
+ } break;
+ case 24: {
+ back = dkct_gui_start_radio_button_group(gui, pv);
+ } break;
+ case 25: {
+ back = dkct_gui_set_direction(gui, pv);
+ } break;
+ case 26: {
+ back = dkct_gui_set_range(gui, pv);
+ } break;
+ case 27: {
+ back = dkct_gui_set_wrap(gui, pv);
+ } break;
+ case 28: {
+ back = dkct_gui_set_keys(gui, pv);
+ } break;
+ case 29: {
+ back = dkct_gui_set_validator(gui, pv);
+ } break;
+ case 30: {
+ back = dkct_gui_set_value(gui, pv);
+ } break;
+ case 31: {
+ back = dkct_gui_set_slider_style(gui, pv);
+ } break;
+ case 32: {
+ back = dkct_gui_set_notebook_style(gui, pv);
+ } break;
+ case 33: {
+ back = dkct_gui_set_text_style(gui, pv);
+ } break;
+ case 34: {
+ back = dkct_gui_set_button_style(gui, pv);
+ } break;
+ case 35: {
+ back = dkct_gui_set_splitter_window_style(gui, pv);
+ } break;
+ case 36: {
+ back = dkct_gui_set_bitmap_button_style(gui, pv);
+ } break;
+ case 37: {
+ back = dkct_gui_set_bitmap_disabled(gui, pv);
+ } break;
+ case 38: {
+ back = dkct_gui_set_bitmap_selected(gui, pv);
+ } break;
+ case 39: {
+ back = dkct_gui_set_bitmap_focus(gui, pv);
+ } break;
+ case 40: {
+ back = dkct_gui_set_bitmap_hover(gui, pv);
+ } break;
+ case 41: {
+ back = dkct_gui_set_gauge_style(gui, pv);
+ } break;
+ case 42: case 44: {
+ back = dkct_gui_set_menu_item_style(gui, pv);
+ } break;
+ case 43: {
+ back = dkct_gui_set_toolbar_style(gui, pv);
+ } break;
+ case 45: {
+ back = dkct_gui_set_icon(gui, pv);
+ } break;
+ case 46: {
+ back = dkct_add_grid_head(gui, pv, 1);
+ } break;
+ case 47: {
+ back = dkct_add_grid_head(gui, pv, 0);
+ } break;
+ case 48: {
+ back = dkct_set_table_for_grid(gui, pv);
+ } break;
+ case 49: {
+ back = dkct_set_minimum_size(gui, pv);
+ } break;
+ case 50: {
+ back = dkct_add_growable_row(gui, pv);
+ } break;
+ case 51: {
+ back = dkct_add_growable_column(gui, pv);
+ } break;
+ case 52: {
+ back = dkct_set_complete_constructor_specified(gui, pv);
+ } break;
+ case 53: {
+ back = dkct_add_grid_cell_data(gui, pv);
+ } break;
+ case 54: {
+ back = dkct_set_grid_style(gui, pv);
+ } break;
+ case 55: {
+ back = dkct_set_tooltip_flag(gui, pv);
+ } break;
+ default: {
+ /* ERROR: Syntax */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 10, 11, il);
+ } break;
+ }
+ if(action >= 0) {
+ if(!(back)) {
+ if(!((gui->psrc)->ec)) {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ /* ERROR: Syntax */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 33);
+ }
+ }
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ /* ERROR: Syntax */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 9);
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ /* ERROR: Syntax */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 9);
+ }
+ }
+
+
+#line 5406 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Process one input line containing an option.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_process_option(DKCT_GUI *gui, char *il)
+{
+ int back = 1;
+ char *pv; /* Attribute value. */
+ char *p1; /* Current string to process. */
+ char *p2; /* Next string to process. */
+
+
+#line 5425 "dkct-gui.ctr"
+ if(gui->c_el) {
+ pv = dk3str_c8_chr(il, '=');
+ if(pv) {
+ *(pv++) = '\0';
+ pv = dk3str_c8_start(pv, NULL);
+ if(pv) {
+ dk3str_c8_normalize(il, NULL, '-');
+ switch(dk3str_c8_array_index(dkct_gui_option_keys, il, 0)) {
+ case 0: {
+ gui->align = 0x00;
+ p1 = dk3str_c8_start(pv, NULL);
+ while(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ gui->align = dkct_gui_apply_align(gui, gui->align, p1);
+ p1 = p2;
+ }
+ } break;
+ default: {
+ /* ERROR: Unknown option "..."! */
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 10, 11, il);
+ } break;
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ /* ERROR: Syntax */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 9);
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ /* ERROR: Syntax */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 9);
+ }
+ }
+
+
+#line 5459 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Add one input file line to GUI description.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+int
+dkct_gui_add_line(DKCT_GUI *gui, char *il)
+{
+ int back = 1;
+ char *p1; /* Start of input line. */
+
+
+#line 5475 "dkct-gui.ctr"
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ switch(*p1) {
+ case '#': {
+
+#line 5479 "dkct-gui.ctr"
+ back = 1;
+ } break;
+ case '.': {
+
+#line 5482 "dkct-gui.ctr"
+ p1++;
+ p1 = dk3str_c8_start(p1, NULL);
+ if(p1) {
+ back = dkct_gui_process_option(gui, p1);
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ /* ERROR: Syntax */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 9);
+ }
+ } break;
+ case '[': {
+
+#line 5493 "dkct-gui.ctr"
+ p1++;
+ p1 = dk3str_c8_start(p1, NULL);
+ if(p1) {
+ back = dkct_gui_start_new_object_definition(gui, p1);
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ /* ERROR: Syntax */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 37);
+ }
+ } break;
+ default: {
+
+#line 5504 "dkct-gui.ctr"
+ back = dkct_gui_process_object_line(gui, p1);
+ } break;
+ }
+ }
+
+
+#line 5509 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Get number of content elements.
+ @param el Element to check.
+ @return Number of content elements.
+*/
+static
+size_t
+dkct_gui_get_number_contents(DKCT_GUI_ELEMENT *el)
+{
+ size_t back = 0;
+ dk3sto_it_reset(el->i_contents);
+ while(dk3sto_it_next(el->i_contents)) { back++; }
+ dk3sto_it_reset(el->i_contents);
+ return back;
+}
+
+
+
+/** Report illegal child.
+ @param co Current object.
+ @param dp Direct parent.
+ @param psrc Source structure.
+*/
+static
+void
+dkct_gui_report_illegal_parent_child(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_SRC *psrc
+)
+{
+ char const *cname;
+ char const *pname;
+
+
+#line 5547 "dkct-gui.ctr"
+ cname = pname = dkct_gui_out_kw[197];
+ if(co) {
+ if(co->cln >= 0) {
+ cname = dkct_gui_class_names[co->cln];
+ }
+ }
+ if(dp) {
+ if(dp->cln >= 0) {
+ pname = dkct_gui_class_names[dp->cln];
+ }
+ }
+ dkct_to_log_5(psrc, 1, DK3_LL_ERROR, 88, 89, 90, pname, cname);
+
+
+#line 5560 "dkct-gui.ctr"
+}
+
+
+
+/** Check GUI element setup.
+ @param el Element to check.
+ @param psrc Source structure.
+ @return 1 on success (element setup ok), 0 on error.
+*/
+static
+int
+dkct_gui_element_check(DKCT_GUI_ELEMENT *el, DKCT_SRC *psrc)
+{
+ size_t nco; /* Number of contents elements. */
+ DKCT_GUI_ELEMENT *dp; /* Direct parent. */
+ DKCT_GUI_ELEMENT *sizer = NULL; /* Sizer. */
+ int back = 1;
+ int szfound = 0; /* Flag: Sizer found. */
+
+
+#line 5579 "dkct-gui.ctr"
+ dp = (DKCT_GUI_ELEMENT *)(el->parent);
+ psrc->lineno = ((el->lndef) > 0UL) ? (el->lndef) : (el->lndecl);
+ dk3app_set_source_line(psrc->app, psrc->lineno);
+ /*
+ Check contents.
+ */
+ switch(el->cln) {
+ case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8:
+ case 9: case 10: case 11: case 12: case 13: case 14: case 35: case 36:
+ case 38:
+ {
+ back = 0;
+ nco = dkct_gui_get_number_contents(el);
+ if(nco > 0) {
+ if(el->cln == 14) {
+ if(nco == 2) {
+ back = 1;
+ } else {
+ /* ERROR: Splitter window must have exactly 2 children! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 47);
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ /* ERROR: Missing contents! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 48);
+ }
+ if(!(back)) {
+
+#line 5608 "dkct-gui.ctr"
+ }
+ } break;
+ }
+ /*
+ Text.
+ */
+ if(back) {
+ switch(el->cln) {
+ case 15: case 19: case 23: case 25: case 28: case 29:
+ case 31: case 36: case 37: case 40:
+ {
+ if(!(el->text)) {
+ if(((el->cln != 37) && (el->cln != 40))
+ || (el->menuItemStyle != DKCT_GUI_MENU_ITEM_SEPARATOR)
+ )
+ {
+ if(el->cln == 28) {
+ /* ERROR: Missing text! */
+ dkct_to_log_1(psrc, 1, DK3_LL_INFO, 49);
+ } else {
+ back = 0;
+
+#line 5629 "dkct-gui.ctr"
+ /* ERROR: Missing text! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 49);
+ }
+ }
+ }
+ } break;
+ }
+ }
+ /*
+ ID.
+ */
+ if(back) {
+ switch(el->cln) {
+ case 15: case 16: case 23: case 25: case 29: case 37: case 40:
+ {
+ if(!(el->idname)) {
+ back = 0;
+
+#line 5646 "dkct-gui.ctr"
+ /* ERROR: Missing ID! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 46);
+ }
+ } break;
+ }
+ }
+ /*
+ Grid.
+ */
+ if(back) {
+ switch(el->cln) {
+ case 6: case 8: {
+ if(el->gridcolumns == 0) {
+ back = 0;
+
+#line 5660 "dkct-gui.ctr"
+ /* ERROR: Missing grid! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 50);
+ }
+ } break;
+ }
+ }
+ /*
+ Bitmap.
+ */
+ if(back) {
+ switch(el->cln) {
+ case 16: /* wxBitmapButton */
+ case 40: /* wxToolBarToolBase */
+ {
+ if(!(el->bitmapVarName)) {
+ if((el->cln != 40)
+ || (el->menuItemStyle != DKCT_GUI_MENU_ITEM_SEPARATOR)
+ )
+ {
+ back = 0;
+
+#line 5680 "dkct-gui.ctr"
+ /* ERROR: Missing bitmap! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 51);
+ }
+ }
+ } break;
+ }
+ }
+ /*
+ Choices.
+ */
+ if(back) {
+ switch(el->cln) {
+ case 17: case 18: case 20: case 21: {
+ if((!(el->choices)) || (el->nChoices == 0)) {
+ back = 0;
+
+#line 5695 "dkct-gui.ctr"
+ /* ERROR: Missing choices! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 52);
+ }
+ } break;
+ }
+ }
+ /*
+ Size.
+ */
+ if(back) {
+ switch(el->cln) {
+ case 12: case 13: case 28: {
+ if(!((el->sizex > 0) && (el->sizey > 0))) {
+
+#line 5708 "dkct-gui.ctr"
+ if(el->cln == 28) {
+ /*
+ Warning: Missing size.
+ Not for single-line text with given text.
+ */
+ if(((el->textStyle) & DKCT_GUI_TEXT_MULTILINE) || (!(el->text))) {
+ dkct_to_log_1(psrc, 1, DK3_LL_WARNING, 53);
+ }
+ } else {
+ back = 0;
+ /* ERROR: Missing size! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 53);
+ }
+ }
+ } break;
+ }
+ }
+ /*
+ Rows or columns for radio box.
+ */
+ if(back) {
+ switch(el->cln) {
+ case 22: {
+ if(el->maxRowsCols < 1) {
+ back = 0;
+
+#line 5733 "dkct-gui.ctr"
+ /* ERROR: Missing rows or columns maximum! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 54);
+ }
+ } break;
+ }
+ }
+ /*
+ Parent/child relationships
+ */
+ switch(el->cln) {
+ case 40: { /* wxToolBarToolBase */
+ if(dp) {
+ if(dp->cln == 38) {
+ if(dp->name) {
+ } else {
+ back = 0;
+ /* ERROR: Missing name for parent */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 91);
+ }
+ } else {
+ back = 0;
+
+#line 5754 "dkct-gui.ctr"
+ /* ERROR: Illegal parent/child combination. */
+ dkct_gui_report_illegal_parent_child(el, dp, psrc);
+ }
+ } else {
+ back = 0;
+ /* ERROR: No parent. */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 92);
+ }
+ } break;
+ case 37: { /* wxMenuItem */
+ if(dp) {
+ if(dp->cln == 36) {
+ if(dp->name) {
+ } else {
+ back = 0;
+ /* ERROR: Missing name for parent */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 91);
+ }
+ } else {
+ back = 0;
+
+#line 5774 "dkct-gui.ctr"
+ /* ERROR: Illegal parent/child combination. */
+ dkct_gui_report_illegal_parent_child(el, dp, psrc);
+ }
+ } else {
+ back = 0;
+ /* ERROR: No parent */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 92);
+ }
+ } break;
+ case 36: { /* wxMenu */
+ if(dp) {
+ if((dp->cln == 35) || (dp->cln == 36)) {
+ } else {
+
+#line 5787 "dkct-gui.ctr"
+ /* ERROR: Illegal parent/child combination. */
+ dkct_gui_report_illegal_parent_child(el, dp, psrc);
+ }
+ } else {
+ back = 0;
+ /* ERROR: No parent */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 92);
+ }
+ } break;
+ }
+ /*
+ Root element must have a sizer as the only content.
+ */
+ if((el->number == 0) && (!(el->parent))) {
+ sizer = NULL; szfound = 0;
+ if(dkct_gui_get_number_contents(el) == 1) {
+ dk3sto_it_reset(el->i_contents);
+ sizer = (DKCT_GUI_ELEMENT *)dk3sto_it_next(el->i_contents);
+ if(sizer) {
+ switch(sizer->cln) {
+ case 5: case 6: case 7: case 8: case 9: case 10: {
+ szfound = 1;
+ } break;
+ }
+ }
+ }
+ if(!(szfound)) {
+ back = 0;
+ /* ERROR: Root element must have one sizer as contents */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 97);
+ }
+ }
+
+#line 5819 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Check whether each object has a class name.
+ @param psrc Source structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_classnames_check(DKCT_SRC *psrc)
+{
+ DKCT_GUI *gui; /* GUI description. */
+ DKCT_GUI_ELEMENT *el; /* Current element to check. */
+ int back = 1;
+
+
+#line 5836 "dkct-gui.ctr"
+ if(psrc->gui) {
+ gui = (DKCT_GUI *)(psrc->gui);
+ dk3sto_it_reset(gui->i_el_by_num);
+ while((el = (DKCT_GUI_ELEMENT *)dk3sto_it_next(gui->i_el_by_num)) != NULL) {
+ psrc->lineno = ((el->lndef) > 0UL) ? (el->lndef) : (el->lndecl);
+ dk3app_set_source_line(psrc->app, psrc->lineno);
+ if(el->number != 0) {
+ if(el->pseudoobj == 0) {
+ if(!(el->name)) {
+ back = 0;
+ /* ERROR: Missing object name! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 58);
+ }
+ if(!(el->cname)) {
+ back = 0;
+
+#line 5851 "dkct-gui.ctr"
+ /* ERROR: Missing object class name! */
+ if(el->name) {
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 93, 94, el->name);
+ } else {
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 78);
+ }
+ }
+ }
+ }
+ if(!dkct_gui_element_check(el, psrc)) {
+ back = 0;
+ psrc->ec = DK3_ERROR_SYNTAX;
+ }
+ }
+ }
+
+#line 5866 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Check for circular dependencies.
+ @param psrc Source structure.
+ @return 1 on success (no circular dependencies), 0 on error.
+*/
+static
+int
+dkct_gui_dependency_check(DKCT_SRC *psrc)
+{
+ int back = 0;
+ dk3_bm_t *bm; /* Dependency matrix. */
+ DKCT_GUI *gui; /* GUI description. */
+ DKCT_GUI_ELEMENT *gel; /* Element to check. */
+ DKCT_GUI_ELEMENT *pp; /* Parent element. */
+ DKCT_GUI_ELEMENT *pm; /* Menu bar/contents element. */
+ DKCT_GUI_ELEMENT *pt; /* Toolbar element. */
+ size_t i; /* Current index to check. */
+
+
+#line 5888 "dkct-gui.ctr"
+ if(psrc->gui) {
+ gui = (DKCT_GUI *)(psrc->gui);
+ bm = dk3bm_open(gui->no, gui->no, psrc->app);
+ if(bm) {
+ back = 1;
+ dk3sto_it_reset(gui->i_el_by_name);
+ while(
+ (gel = (DKCT_GUI_ELEMENT *)dk3sto_it_next(gui->i_el_by_name))
+ != NULL
+ )
+ {
+
+ psrc->lineno = ((gel->lndef) > 0UL) ? (gel->lndef) : (gel->lndecl);
+ dk3app_set_source_line(psrc->app, psrc->lineno);
+ pp = pm = pt = NULL;
+ if(gel->parent) { pp = (DKCT_GUI_ELEMENT *)(gel->parent); }
+ if(gel->menubar) { pm = (DKCT_GUI_ELEMENT *)(gel->menubar); }
+ if(gel->toolbar) { pt = (DKCT_GUI_ELEMENT *)(gel->toolbar); }
+ if(pp) {
+ dk3bm_set(bm, pp->number, gel->number, 1);
+ }
+ if(pm) {
+ dk3bm_set(bm, gel->number, pm->number, 1);
+ }
+ if(pt) {
+ dk3bm_set(bm, gel->number, pt->number, 1);
+ }
+ dk3sto_it_reset(gel->i_contents);
+ while(
+ (pm = (DKCT_GUI_ELEMENT *)dk3sto_it_next(gel->i_contents))
+ != NULL
+ )
+ {
+ dk3bm_set(bm, gel->number, pm->number, 1);
+ }
+ }
+ dk3bm_expand(bm);
+ for(i = 0; i < gui->no; i++) {
+ if(dk3bm_get(bm, i, i)) {
+ psrc->lineno = 0UL;
+ dk3app_set_source_line(psrc->app, 0UL);
+ /* ERROR: Dependency loop */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 79);
+ back = 0;
+ }
+ }
+ dk3bm_close(bm);
+ }
+ }
+
+#line 5937 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+int
+dkct_gui_check(DKCT_SRC *psrc)
+{
+ int back = 0;
+
+
+#line 5947 "dkct-gui.ctr"
+ if(dkct_gui_classnames_check(psrc)) {
+ if(dkct_gui_dependency_check(psrc)) {
+ back = 1;
+ }
+ }
+
+#line 5952 "dkct-gui.ctr"
+ return back;
+}
+
+
+
+/** Check whether we need a wxPanel in the root object.
+ @param gui GUI description.
+ @return 1 for wxPanel needed (frame), 0 for not needed (wxDialog).
+*/
+static
+int
+dkct_gui_need_contents_panel(DKCT_GUI *gui)
+{
+ int back = 1;
+ if(gui->r_el) {
+ if((gui->r_el)->cln == 1) {
+ back = 0;
+ }
+ }
+ return back;
+}
+
+
+
+/** Decide whether or not to write a class member and a
+ constructor method.
+ @param co Current object.
+ @return 1 to write a constructor, 0 for no constructor.
+*/
+static
+int
+dkct_gui_need_element_constructor(
+ DKCT_GUI_ELEMENT *co
+#if 0
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+#endif
+)
+{
+ int back = 1;
+ switch(co->cln) {
+ case 37: /* wxMenuItem */
+ case 40: /* wxToolBarTool */
+ {
+ if(co->menuItemStyle == DKCT_GUI_MENU_ITEM_SEPARATOR) {
+ back = 0;
+ }
+ } break;
+ }
+ return back;
+}
+
+
+
+void
+dkct_gui_class_variables(DKCT_SRC *psrc)
+{
+ DKCT_GUI *gui; /* GUI description. */
+ DKCT_GUI_ELEMENT *el; /* Current element to check. */
+ if(psrc->gui) {
+ gui = (DKCT_GUI *)(psrc->gui);
+ dk3sto_it_reset(gui->i_el_by_num);
+ fputs(dkct_gui_out_kw[7], psrc->fipo);
+ if(dkct_gui_need_contents_panel(gui)) {
+ fputs(dkct_gui_out_kw[17], psrc->fipo);
+ }
+ while((el = (DKCT_GUI_ELEMENT *)dk3sto_it_next(gui->i_el_by_num)) != NULL) {
+ if(el->number != 0) {
+ if(el->pseudoobj == 0) {
+ if(dkct_gui_need_element_constructor(el)) {
+ if((el->name) && (el->cname)) {
+ fputs(dkct_gui_out_kw[5], psrc->fipo);
+ fputs(el->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[6], psrc->fipo);
+ if((psrc->dkcto).lnn) {
+ psrc->lineno = el->lndef;
+ dkct_tr_show_source_line(psrc, 0);
+ }
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ fputs(el->cname, psrc->fipo);
+ fputs(dkct_gui_out_kw[1], psrc->fipo);
+ fputs(dkct_gui_out_kw[3], psrc->fipo);
+ fputs(el->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[4], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+ }
+ }
+ }
+ }
+ /*
+ Write line number.
+ */
+ }
+}
+
+
+
+/** Check whether an object is a sizer.
+ @param gel Object to check.
+ @return 1 for sizer, 0 for non-sizer object.
+*/
+static
+int
+dkct_gui_is_sizer(DKCT_GUI_ELEMENT *gel)
+{
+ int back = 0;
+ if(gel) {
+ if(gel->cln < 11) {
+ if(gel->cln > 4) {
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Find parent window object.
+ @param startelem Direct parent of object.
+ @return Parent representing a non-sizer object or NULL.
+*/
+static
+DKCT_GUI_ELEMENT *
+dkct_gui_find_real_parent(DKCT_GUI_ELEMENT *startelem)
+{
+ DKCT_GUI_ELEMENT *back = NULL;
+ DKCT_GUI_ELEMENT *c; /* Element to check. */
+ c = startelem;
+ while((!(back)) && (c)) {
+ if(dkct_gui_is_sizer(c)) {
+ c = (DKCT_GUI_ELEMENT *)(c->parent);
+ } else {
+ back = c;
+ }
+ }
+ return back;
+}
+
+
+
+/** Write flags to add object to sizer.
+ @param fipo Output file.
+ @param co Current object.
+*/
+static
+void
+dkct_gui_write_flags(FILE *fipo, DKCT_GUI_ELEMENT *co)
+{
+ int found = 0; /* Flag: Already found. */
+
+ if((co->border >= 0) && (co->borderPos)) {
+ if(co->borderPos == DKCT_GUI_BORDER_POSITION_ALL) {
+ fputs(dkct_gui_out_kw[39], fipo);
+ found = 1;
+ } else {
+ if((co->borderPos) & DKCT_GUI_BORDER_POSITION_TOP) {
+ if(found) { fputs(dkct_gui_out_kw[44], fipo); }
+ found = 1;
+ fputs(dkct_gui_out_kw[40], fipo);
+ }
+ if((co->borderPos) & DKCT_GUI_BORDER_POSITION_LEFT) {
+ if(found) { fputs(dkct_gui_out_kw[44], fipo); }
+ found = 1;
+ fputs(dkct_gui_out_kw[41], fipo);
+ }
+ if((co->borderPos) & DKCT_GUI_BORDER_POSITION_RIGHT) {
+ if(found) { fputs(dkct_gui_out_kw[44], fipo); }
+ found = 1;
+ fputs(dkct_gui_out_kw[42], fipo);
+ }
+ if((co->borderPos) & DKCT_GUI_BORDER_POSITION_BOTTOM) {
+ if(found) { fputs(dkct_gui_out_kw[44], fipo); }
+ found = 1;
+ fputs(dkct_gui_out_kw[43], fipo);
+ }
+ }
+ }
+ if((co->align) & DKCT_GUI_ALIGN_H_MASK) {
+ switch((co->align) & DKCT_GUI_ALIGN_H_MASK) {
+ case DKCT_GUI_ALIGN_H_LEFT: {
+ if(found) { fputs(dkct_gui_out_kw[44], fipo); }
+ found = 1;
+ fputs(dkct_gui_out_kw[45], fipo);
+ } break;
+ case DKCT_GUI_ALIGN_H_CENTER: {
+ if(found) { fputs(dkct_gui_out_kw[44], fipo); }
+ found = 1;
+ fputs(dkct_gui_out_kw[46], fipo);
+ } break;
+ case DKCT_GUI_ALIGN_H_RIGHT: {
+ if(found) { fputs(dkct_gui_out_kw[44], fipo); }
+ found = 1;
+ fputs(dkct_gui_out_kw[47], fipo);
+ } break;
+ }
+ }
+ if((co->align) & DKCT_GUI_ALIGN_V_MASK) {
+ switch((co->align) & DKCT_GUI_ALIGN_V_MASK) {
+ case DKCT_GUI_ALIGN_V_TOP: {
+ if(found) { fputs(dkct_gui_out_kw[44], fipo); }
+ found = 1;
+ fputs(dkct_gui_out_kw[48], fipo);
+ } break;
+ case DKCT_GUI_ALIGN_V_CENTER: {
+ if(found) { fputs(dkct_gui_out_kw[44], fipo); }
+ found = 1;
+ fputs(dkct_gui_out_kw[49], fipo);
+ } break;
+ case DKCT_GUI_ALIGN_V_BOTTOM: {
+ if(found) { fputs(dkct_gui_out_kw[44], fipo); }
+ found = 1;
+ fputs(dkct_gui_out_kw[50], fipo);
+ } break;
+ }
+ }
+ if(co->expandFlag) {
+ if(found) { fputs(dkct_gui_out_kw[44], fipo); }
+ found = 1;
+ fputs(dkct_gui_out_kw[51], fipo);
+ }
+ if(!(found)) {
+ fputs(dkct_gui_out_kw[52], fipo);
+ }
+}
+
+
+
+/** Check whether we need to write commands for flags.
+ @param co Current object.
+ @return 1 to configure flags, 0 to skip.
+*/
+static
+int
+dkct_gui_need_flags(DKCT_GUI_ELEMENT *co)
+{
+ int back = 0;
+ if((co->border >= 0) && (co->borderPos)) {
+ back = 0;
+ }
+ if((co->borderPos) & DKCT_GUI_BORDER_POSITION_TOP) {
+ back = 1;
+ }
+ if((co->borderPos) & DKCT_GUI_BORDER_POSITION_LEFT) {
+ back = 1;
+ }
+ if((co->borderPos) & DKCT_GUI_BORDER_POSITION_RIGHT) {
+ back = 1;
+ }
+ if((co->borderPos) & DKCT_GUI_BORDER_POSITION_BOTTOM) {
+ back = 1;
+ }
+ if((co->align) & DKCT_GUI_ALIGN_H_MASK) {
+ back = 1;
+ }
+ if((co->align) & DKCT_GUI_ALIGN_V_MASK) {
+ back = 1;
+ }
+ if(co->expandFlag) {
+ back = 1;
+ }
+ return back;
+}
+
+
+
+/** Write border for object.
+ @param fipo Output file.
+ @param co Current object.
+*/
+static
+void
+dkct_gui_write_border(FILE *fipo, DKCT_GUI_ELEMENT *co)
+{
+ int b = 0; /* Border size. */
+ char bu[32]; /* Buffer for integer variables. */
+
+ if((co->border >= 0) && (co->borderPos)) {
+ b = co->border;
+ }
+ sprintf(bu, "%d", b);
+ fputs(bu, fipo);
+}
+
+
+
+/** Write growable rows and columns.
+ @param co Current object.
+ @param st Storage for growable rows/columns.
+ @param it Iterator for growable rows/columns.
+ @param rowcol Flag: Row=0 or column=1.
+ @param psrc Source structure.
+*/
+static
+void
+dkct_write_growable_rows_cols(
+ DKCT_GUI_ELEMENT *co,
+ dk3_sto_t *st,
+ dk3_sto_it_t *it,
+ int rowcol,
+ DKCT_SRC *psrc
+)
+{
+ int *ip;
+ if((st) && (it)) {
+ dk3sto_it_reset(it);
+ while(NULL != (ip = (int *)dk3sto_it_next(it))) {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[(rowcol) ? 206 : 207], psrc->fipo);
+ fprintf(psrc->fipo, "%d", *ip);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+ }
+}
+
+
+
+/** Add one object to the parent which is a sizer.
+ @param co Current object.
+ @param pa Parent (a sizer object).
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_add_object_to_sizer(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *pa,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ char bu[64]; /* Buffer for integer values. */
+ int det = 0; /* Details to use. */
+
+
+#line 6293 "dkct-gui.ctr"
+ /*
+ Last modifications to object before adding it to parent.
+ */
+ switch(co->cln) {
+ case 7: {
+ /* Growable rows and columns for wxGridBagSizer */
+ dkct_write_growable_rows_cols(co, co->sGrowRow, co->iGrowRow, 0, psrc);
+ dkct_write_growable_rows_cols(co, co->sGrowCol, co->iGrowCol, 1, psrc);
+ } break;
+ }
+ /*
+ Add object to parent.
+ */
+ switch(pa->cln) {
+ case 7: {
+
+#line 6308 "dkct-gui.ctr"
+ /* sizer */
+ if(dkct_gui_need_flags(co)) {
+ det = 1;
+
+#line 6311 "dkct-gui.ctr"
+ }
+ if((co->border >= 0) && (co->borderPos)) {
+ det = 2;
+
+#line 6314 "dkct-gui.ctr"
+ }
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(pa->name, psrc->fipo);
+ /* -> */
+ fputs(dkct_gui_out_kw[31], psrc->fipo);
+ /* Add( */
+ fputs(dkct_gui_out_kw[36], psrc->fipo);
+ /* object */
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ /* , */
+ fputs(dkct_gui_out_kw[38], psrc->fipo);
+ /* wxGBPosition */
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ fputs(dkct_gui_out_kw[53], psrc->fipo);
+ sprintf(bu, "%d", co->posy);
+ fputs(bu, psrc->fipo);
+ fputs(dkct_gui_out_kw[55], psrc->fipo);
+ sprintf(bu, "%d", co->posx);
+ fputs(bu, psrc->fipo);
+ fputs(dkct_gui_out_kw[56], psrc->fipo);
+ /* , */
+ fputs(dkct_gui_out_kw[38], psrc->fipo);
+ /* wxGBSpan */
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ fputs(dkct_gui_out_kw[54], psrc->fipo);
+ sprintf(bu, "%d", co->spany);
+ fputs(bu, psrc->fipo);
+ fputs(dkct_gui_out_kw[55], psrc->fipo);
+ sprintf(bu, "%d", co->spanx);
+ fputs(bu, psrc->fipo);
+ fputs(dkct_gui_out_kw[56], psrc->fipo);
+#if 0
+ /* , */
+ fputs(dkct_gui_out_kw[38], psrc->fipo);
+ /*
+ Proportion not printed for wxGridBagSizer elements.
+ */
+ /* proportion */
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ sprintf(bu, "%d", ((co->proportion >= 0) ? (co->proportion) : 0));
+ fputs(bu, psrc->fipo);
+#endif
+ if(det) {
+ /* , */
+ fputs(dkct_gui_out_kw[38], psrc->fipo);
+ /* flags */
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_flags(psrc->fipo, co);
+ if(det > 1) {
+ /* , */
+ fputs(dkct_gui_out_kw[38], psrc->fipo);
+ /* border */
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_border(psrc->fipo, co);
+ }
+ }
+ /* ); */
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ fputs(dkct_gui_out_kw[37], psrc->fipo);
+ } break;
+ case 5: case 6: case 8: case 9: case 10: {
+
+#line 6376 "dkct-gui.ctr"
+ /*
+ sizer->Add(object, proportion, flags, border);
+ */
+ /* sizer */
+ if(co->proportion) {
+ det = 1;
+
+#line 6382 "dkct-gui.ctr"
+ }
+ if(dkct_gui_need_flags(co)) {
+ det = 2;
+
+#line 6385 "dkct-gui.ctr"
+ }
+ if((co->border >= 0) && (co->borderPos)) {
+ det = 3;
+
+#line 6388 "dkct-gui.ctr"
+ }
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(pa->name, psrc->fipo);
+ /* -> */
+ fputs(dkct_gui_out_kw[31], psrc->fipo);
+ /* Add( */
+ switch(pa->cln) {
+ /*
+ wxStdButtonSizer.
+ */
+ case 10: {
+ switch(co->cln) {
+ case 15: case 16: { /* Buttons. */
+ fputs(dkct_gui_out_kw[208], psrc->fipo);
+ } break;
+ default: { /* Other elements. */
+ fputs(dkct_gui_out_kw[36], psrc->fipo);
+ } break;
+ }
+ } break;
+ /*
+ All other containers and sizers.
+ */
+ default: {
+ fputs(dkct_gui_out_kw[36], psrc->fipo);
+ } break;
+ }
+ /* object */
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ if(det) {
+ /* , */
+ fputs(dkct_gui_out_kw[38], psrc->fipo);
+ /* proportion */
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ sprintf(bu, "%d", ((co->proportion >= 0) ? (co->proportion) : 0));
+ fputs(bu, psrc->fipo);
+ if(det > 1) {
+ /* , */
+ fputs(dkct_gui_out_kw[38], psrc->fipo);
+ /* flags */
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_flags(psrc->fipo, co);
+ if(det > 2) {
+ /* , */
+ fputs(dkct_gui_out_kw[38], psrc->fipo);
+ /* border */
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_border(psrc->fipo, co);
+ }
+ }
+ }
+ /* ); */
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ fputs(dkct_gui_out_kw[37], psrc->fipo);
+ } break;
+ }
+
+
+#line 6446 "dkct-gui.ctr"
+}
+
+
+
+/** Use the current object as the parents sizer object.
+ @param co Current object.
+ @param pa Parent (a sizer object).
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_set_parents_sizer(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *pa,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ char const *pname = NULL; /* Parent object name. */
+
+
+#line 6467 "dkct-gui.ctr"
+ if(pa) { pname = pa->name; }
+ if(!(pname)) {
+ if(pa->cln != 1) { pname = dkct_gui_out_kw[30]; }
+ }
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ if(pname) {
+ fputs(pname, psrc->fipo);
+ fputs(dkct_gui_out_kw[31], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[32], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+
+
+#line 6481 "dkct-gui.ctr"
+}
+
+
+
+/** Write objects parents name.
+ @param pw Parent object.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_write_parent_name(
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ char *pname = NULL; /* Parent object name. */
+
+ if(pw) { pname = pw->name; }
+ if(pname) {
+ fputs(pname, psrc->fipo);
+ } else {
+ if(dkct_gui_need_contents_panel(gui)) {
+ fputs(dkct_gui_out_kw[30], psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[65], psrc->fipo);
+ }
+ }
+}
+
+
+
+/** Switch to next argument.
+ @param psrc Source structure.
+*/
+static
+void
+dkct_gui_next_argument(DKCT_SRC *psrc)
+{
+ fputs(dkct_gui_out_kw[38], psrc->fipo);
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+}
+
+
+
+/** Write ID attribute.
+ @param co Current object.
+ @param psrc Source structure.
+*/
+static
+void
+dkct_gui_write_idname(DKCT_GUI_ELEMENT *co, DKCT_SRC *psrc)
+{
+ if(co->idname) {
+ fputs(co->idname, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[66], psrc->fipo);
+ }
+}
+
+
+
+/** Write size attribute.
+ @param psrc Source structure.
+ @param w Object width.
+ @param h Object height.
+ @param rec Flag: Size attribute recommended.
+ @param co Current object.
+*/
+static
+void
+dkct_gui_write_size(DKCT_SRC *psrc, int w, int h, int rec, DKCT_GUI_ELEMENT *co)
+{
+ char bu[256];
+ if((w > 0) && (h > 0)) {
+ sprintf(bu, "%d, %d", w, h);
+ fputs(dkct_gui_out_kw[81], psrc->fipo);
+ fputs(bu, psrc->fipo);
+ fputs(dkct_gui_out_kw[56], psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[75], psrc->fipo);
+ if(rec) {
+ /* WARNING: Size not specified! */
+ dkct_to_log_1(psrc, 1, DK3_LL_WARNING, 53);
+ }
+ }
+}
+
+
+
+/** Write constructor arguments for wxFrame or wxDialog.
+*/
+static
+void
+dkct_gui_constructor_frame_dialog(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int det = 0; /* Details level. */
+
+ if(co->text) det = 1;
+ if((co->sizex > 0) && (co->sizey > 0)) det = 2;
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ if(det) {
+ dkct_gui_next_argument(psrc);
+ if(co->text) {
+ fputs(co->text, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[73], psrc->fipo);
+ }
+ if(det > 1) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write constructor for box sizer.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window object.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_boxsizer(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ switch(co->direction) {
+ case DKCT_GUI_DIRECTION_VERTICAL: {
+ fputs(dkct_gui_out_kw[35], psrc->fipo);
+ } break;
+ default: {
+ fputs(dkct_gui_out_kw[34], psrc->fipo);
+ } break;
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+#if 0
+/** Write constructor arguments for wxPanel.
+*/
+static
+void
+dkct_gui_constructor_parent_and_id(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+#endif
+
+
+
+/** Write constructor for grid sizer.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window object.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_gridsizer(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ char bu[256]; /* Buffer for integer values. */
+ int c = 0; /* Columns. */
+ int r = 0; /* Rows. */
+ int y = 0; /* Start row. */
+ int x = 0; /* Start column. */
+
+ c = co->gridcolumns;
+ r = co->gridrows;
+ x = co->gridgapx;
+ y = co->gridgapy;
+ bu[0] = '\0';
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ if(r > 0) {
+ if(x < 0) { x = 0; } if(y < 0) { y = 0; }
+ sprintf(bu, "%d, %d, %d, %d", c, r, y, x);
+ } else {
+ if((x > -1) || (y > -1)) {
+ if(x > -1) {
+ sprintf(bu, "%d, %d, %d", c, ((y > -1) ? y : 0), ((x > -1) ? x : 0));
+ } else {
+ sprintf(bu, "%d, %d", c, y);
+ }
+ } else {
+ sprintf(bu, "%d", c);
+ }
+ }
+ fputs(bu, psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write constructor for gridbag sizer.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window object.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_gridbagsizer(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ char bu[128]; /* Buffer for integer values. */
+
+ bu[0] = '\0';
+ if((co->gridgapy > -1) || (co->gridgapy > -1)) {
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ if(co->gridgapx > -1) {
+ sprintf(
+ bu, "%d, %d",
+ ((co->gridgapy > -1) ? co->gridgapy : 0),
+ ((co->gridgapx > -1) ? co->gridgapx : 0)
+ );
+ } else {
+ sprintf(bu, "%d", co->gridgapy);
+ }
+ fputs(bu, psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+}
+
+
+
+/** Write element constructor for static box sizer.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_staticboxsizer(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ fputs(dkct_gui_out_kw[(co->direction) ? 35 : 34], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ if(co->text) {
+ dkct_gui_next_argument(psrc);
+ fputs(co->text, psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write constructor for a panel.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window object.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_panel(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int det = 0; /* Details level. */
+
+ if((co->sizex > 0) && (co->sizey > 0)) det = 1;
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ if(det) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(det > 1) {
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write constructor for notebook.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window object.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_notebook(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int det = 0; /* Details level. */
+ int fe = 0; /* Flag: Found elements. */
+
+ if((co->sizex > 0) && (co->sizey > 0)) det = 1;
+ if(co->notebookStyle) det = 2;
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ if(det) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(det > 1) {
+ if((co->notebookStyle) & DKCT_GUI_NB_TOP) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[113], psrc->fipo);
+ }
+ if((co->notebookStyle) & DKCT_GUI_NB_LEFT) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[114], psrc->fipo);
+ }
+ if((co->notebookStyle) & DKCT_GUI_NB_RIGHT) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[115], psrc->fipo);
+ }
+ if((co->notebookStyle) & DKCT_GUI_NB_BOTTOM) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[116], psrc->fipo);
+ }
+ if((co->notebookStyle) & DKCT_GUI_NB_FIXEDWIDTH) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[117], psrc->fipo);
+ }
+ if((co->notebookStyle) & DKCT_GUI_NB_MULTILINE) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[118], psrc->fipo);
+ }
+ if((co->notebookStyle) & DKCT_GUI_NB_NOPAGETHEME) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[119], psrc->fipo);
+ }
+ if((co->notebookStyle) & DKCT_GUI_NB_FLAT) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[120], psrc->fipo);
+ }
+ if(!(fe)) { fputs(dkct_gui_out_kw[52], psrc->fipo); }
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write constructor for scrolled window.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window object.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_scrolledwindow(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int det = 0; /* Details level. */
+
+ if((co->sizex > 0) && (co->sizey > 0)) det = 1;
+ if(co->direction != DKCT_GUI_DIRECTION_BOTH) det = 2;
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ if(det) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 1, co);
+ if(det > 1) {
+ dkct_gui_next_argument(psrc);
+ switch(co->direction) {
+ case DKCT_GUI_DIRECTION_HORIZONTAL: {
+ fputs(dkct_gui_out_kw[138], psrc->fipo);
+ } break;
+ case DKCT_GUI_DIRECTION_VERTICAL: {
+ fputs(dkct_gui_out_kw[139], psrc->fipo);
+ } break;
+ default: {
+ fputs(dkct_gui_out_kw[140], psrc->fipo);
+ } break;
+ }
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write constructor for splitter window.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window object.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_splitterwindow(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int det = 0; /* Details level. */
+ int fe = 0; /* Flag: Found an element. */
+
+ if((co->sizex > 0) && (co->sizey > 0)) det = 1;
+ if(co->splitterStyle != DKCT_GUI_SPLITTERW_3D) det = 2;
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ if(det) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 1, co);
+ if(det > 1) {
+ dkct_gui_next_argument(psrc);
+ if((co->splitterStyle) & DKCT_GUI_SPLITTERW_3D) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[147], psrc->fipo);
+ } else {
+ if((co->splitterStyle) & DKCT_GUI_SPLITTERW_3D_SASH) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[148], psrc->fipo);
+ }
+ if((co->splitterStyle) & DKCT_GUI_SPLITTERW_3D_BORDER) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[149], psrc->fipo);
+ }
+ }
+ if((co->splitterStyle) & DKCT_GUI_SPLITTERW_BORDER) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[150], psrc->fipo);
+ }
+ if((co->splitterStyle) & DKCT_GUI_SPLITTERW_NO_BORDER) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[151], psrc->fipo);
+ }
+ if((co->splitterStyle) & DKCT_GUI_SPLITTERW_NO_XP_THEME) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[152], psrc->fipo);
+ }
+ if((co->splitterStyle) & DKCT_GUI_SPLITTERW_PERMIT_UNSPLIT) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[153], psrc->fipo);
+ }
+ if((co->splitterStyle) & DKCT_GUI_SPLITTERW_LIVE_UPDATE) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); }
+#if 0
+ /* Re-activate when adding further contents.
+ */
+ fe = 1;
+#endif
+ fputs(dkct_gui_out_kw[154], psrc->fipo);
+ }
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write constructor for button.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window object.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_button(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int det = 0; /* Details level. */
+ int fe = 0; /* Flag: Found an entry. */
+
+ if(co->text) det = 1;
+ if((co->sizex > 0) && (co->sizey > 0)) det = 2;
+ if(co->buttonStyle) det = 3;
+ if(co->validator) det = 4;
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ if(det) {
+ dkct_gui_next_argument(psrc);
+ if(co->text) {
+ fputs(co->text, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[73], psrc->fipo);
+ }
+ if(det > 1) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(det > 2) {
+ dkct_gui_next_argument(psrc);
+ if((co->buttonStyle) & DKCT_GUI_BUTTON_LEFT) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[141], psrc->fipo);
+ }
+ if((co->buttonStyle) & DKCT_GUI_BUTTON_TOP) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[142], psrc->fipo);
+ }
+ if((co->buttonStyle) & DKCT_GUI_BUTTON_RIGHT) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[143], psrc->fipo);
+ }
+ if((co->buttonStyle) & DKCT_GUI_BUTTON_BOTTOM) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[144], psrc->fipo);
+ }
+ if((co->buttonStyle) & DKCT_GUI_BUTTON_EXACTFIT) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[145], psrc->fipo);
+ }
+ if((co->buttonStyle) & DKCT_GUI_BUTTON_NO_BORDER) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); }
+#if 0
+ /* Re-activate when adding further contents later.
+ */
+ fe = 1;
+#endif
+ fputs(dkct_gui_out_kw[146], psrc->fipo);
+ }
+ if(det > 3) {
+ dkct_gui_next_argument(psrc);
+ }
+ }
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write constructor for bitmap button.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window object.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_bitmapbutton(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int det = 0; /* Details level. */
+ int fe = 0; /* Flag: Found entry. */
+
+ if(co->bitmapVarName) {
+ det = 1;
+ if((co->sizex > 0) && (co->sizey > 0)) det = 2;
+ if(co->bitmapbStyle != DKCT_GUI_BBUTTON_AUTODRAW) det = 3;
+ if(co->validator) det = 4;
+
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ dkct_gui_next_argument(psrc);
+ fputs(co->bitmapVarName, psrc->fipo);
+ if(det > 1) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(det > 2) {
+ if((co->bitmapbStyle) & DKCT_GUI_BBUTTON_AUTODRAW) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[155], psrc->fipo);
+ }
+ if((co->bitmapbStyle) & DKCT_GUI_BBUTTON_LEFT) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[141], psrc->fipo);
+ }
+ if((co->bitmapbStyle) & DKCT_GUI_BBUTTON_TOP) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[142], psrc->fipo);
+ }
+ if((co->bitmapbStyle) & DKCT_GUI_BBUTTON_RIGHT) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[143], psrc->fipo);
+ }
+ if((co->bitmapbStyle) & DKCT_GUI_BBUTTON_BOTTOM) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[144], psrc->fipo);
+ }
+ if(!(fe)) { fputs(dkct_gui_out_kw[52], psrc->fipo); }
+ if(det > 3) {
+ dkct_gui_next_argument(psrc);
+ fputs(co->validator, psrc->fipo);
+ }
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ } else {
+ /* ERROR: No bitmap name specified! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 51);
+ }
+}
+
+
+
+/** Write element constructor for choice and combo box.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+ @param iscombo Flag: Combo box.
+*/
+static
+void
+dkct_gui_constructor_choice_combo(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui,
+ int iscombo
+)
+{
+ char bu[64]; /* Buffer for integer values. */
+ int details = 0; /* Details level. */
+ /*
+ parent, id, pos, size (1) , n (2), texts (3), validator (4)
+ parent, id, text, pos, size (1), n (2), texts (3), validator (4)
+ */
+ if((co->sizex > 0) && (co->sizey > 0)) details = 1;
+ if((co->nChoices > 0) || (co->nChoices == -1)) details = 2;
+ if(co->choices) details = 3;
+ if(co->validator) details = 4;
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ if(iscombo) {
+ dkct_gui_next_argument(psrc);
+ if(co->text) {
+ fputs(co->text, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[73], psrc->fipo);
+ }
+ }
+ if(details) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(details > 1) {
+ if(co->nChoices != -1) {
+ dkct_gui_next_argument(psrc);
+ sprintf(bu, "%d", co->nChoices);
+ fputs(bu, psrc->fipo);
+ }
+ if(details > 2) {
+ dkct_gui_next_argument(psrc);
+ if(co->choices) {
+ fputs(co->choices, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[100], psrc->fipo);
+ }
+ if(details > 3) {
+ dkct_gui_next_argument(psrc);
+ fputs(co->validator, psrc->fipo);
+ }
+ }
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write element constructor for checkbox.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_checkbox(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int need_full_arguments = 0; /* Details level. */
+
+ if(co->text) need_full_arguments = 1;
+ if((co->sizex > 0) && (co->sizey > 0)) { need_full_arguments = 2; }
+ if(co->nStates == 0x03) {
+ need_full_arguments = 3;
+ }
+ if(((co->align) & DKCT_GUI_ALIGN_H_MASK) == DKCT_GUI_ALIGN_H_RIGHT) {
+ need_full_arguments = 3;
+ }
+ if(co->validator) need_full_arguments = 4;
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ if(need_full_arguments) {
+ dkct_gui_next_argument(psrc);
+ if(co->text) {
+ fputs(co->text, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[73], psrc->fipo);
+ }
+ if(need_full_arguments > 1) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(need_full_arguments > 2) {
+ dkct_gui_next_argument(psrc);
+ if(co->nStates == 0x03) {
+ fputs(dkct_gui_out_kw[76], psrc->fipo);
+ if(((co->align) & DKCT_GUI_ALIGN_H_MASK) == DKCT_GUI_ALIGN_H_RIGHT) {
+ fputs(dkct_gui_out_kw[44], psrc->fipo);
+ fputs(dkct_gui_out_kw[47], psrc->fipo);
+ } else {
+ }
+ } else {
+ if(((co->align) & DKCT_GUI_ALIGN_H_MASK) == DKCT_GUI_ALIGN_H_RIGHT) {
+ fputs(dkct_gui_out_kw[47], psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[52], psrc->fipo);
+ }
+ }
+ if(need_full_arguments > 3) {
+ dkct_gui_next_argument(psrc);
+ fputs(co->validator, psrc->fipo);
+ }
+ }
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write element constructor for listbox.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_listbox(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ char bu[64]; /* Buffer for numeric values. */
+
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 1, co);
+ if(co->nChoices != -1) {
+ dkct_gui_next_argument(psrc);
+ sprintf(bu, "%d", co->nChoices);
+ fputs(bu, psrc->fipo);
+ }
+ dkct_gui_next_argument(psrc);
+ if(co->choices) {
+ fputs(co->choices, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[100], psrc->fipo);
+ }
+ /* Style */
+ dkct_gui_next_argument(psrc);
+ switch(co->selStyle) {
+ case DKCT_GUI_SELECTION_STYLE_EXTENDED: {
+ fputs(dkct_gui_out_kw[84], psrc->fipo);
+ } break;
+ case DKCT_GUI_SELECTION_STYLE_MULTIPLE: {
+ fputs(dkct_gui_out_kw[83], psrc->fipo);
+ } break;
+ default: {
+ fputs(dkct_gui_out_kw[82], psrc->fipo);
+ } break;
+ }
+ fputs(dkct_gui_out_kw[85], psrc->fipo);
+ if(co->validator) {
+ dkct_gui_next_argument(psrc);
+ fputs(co->validator, psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write element constructor for checklistbox.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_checklistbox(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ dkct_gui_constructor_listbox(co, dp, pw, psrc, gui);
+}
+
+
+
+/** Write element constructor for radio box.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_radiobox(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ /*
+ parent, id, label, pos, size (1), n (2), choices (3),
+ majordim (4), style (5), validator (6)
+ */
+ int det = 0; /* Details level. */
+ char bu[64]; /* Buffer for numeric values. */
+
+ if((co->sizex > 0) && (co->sizey > 0)) det = 1;
+ if((co->nChoices > 0) || (co->nChoices == -1)) det = 2;
+ if(co->choices) det = 3;
+ if(co->maxRowsCols > 0) det = 4;
+ if(co->rbDirection != DKCT_GUI_RB_DIR_COLUMNS) det = 5;
+ if(co->validator) det = 6;
+
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ dkct_gui_next_argument(psrc);
+ if(co->text) {
+ fputs(co->text, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[73], psrc->fipo);
+ }
+ if(det) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(det > 1) {
+ if(co->nChoices != -1) {
+ dkct_gui_next_argument(psrc);
+ sprintf(bu, "%d", ((co->nChoices > 0) ? co->nChoices : 0));
+ fputs(bu, psrc->fipo);
+ }
+ if(det > 2) {
+ dkct_gui_next_argument(psrc);
+ if(co->choices) {
+ fputs(co->choices, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[100], psrc->fipo);
+ }
+ if(det > 3) {
+ /* Majordim */
+ dkct_gui_next_argument(psrc);
+ sprintf(bu, "%d", (co->maxRowsCols >= 0) ? co->maxRowsCols : 0);
+ fputs(bu, psrc->fipo);
+ if(det > 4) {
+ /* Style */
+ dkct_gui_next_argument(psrc);
+ if(co->rbDirection == DKCT_GUI_RB_DIR_COLUMNS) {
+ fputs(dkct_gui_out_kw[87], psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[86], psrc->fipo);
+ }
+ if(det > 5) {
+ dkct_gui_next_argument(psrc);
+ fputs(co->validator, psrc->fipo);
+ }
+ }
+ }
+ }
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write element constructor for radio button.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_radiobutton(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int det = 0; /* Details level. */
+
+ if((co->sizex > 0) && (co->sizey > 0)) det = 1;
+ if(co->startGroup) det = 2;
+ if(co->validator) det = 3;
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ dkct_gui_next_argument(psrc);
+ if(co->text) {
+ fputs(co->text, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[73], psrc->fipo);
+ }
+ if(det) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(det > 1) {
+ dkct_gui_next_argument(psrc);
+ if(co->startGroup) {
+ fputs(dkct_gui_out_kw[88], psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[52], psrc->fipo);
+ }
+ if(det > 2) {
+ dkct_gui_next_argument(psrc);
+ fputs(co->validator, psrc->fipo);
+ }
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write element constructor for scrollbar.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_scrollbar(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int must_write_details = 0; /* Details level. */
+
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ must_write_details = 0;
+ if((co->sizex > 0) && (co->sizey > 0)) {
+ must_write_details = 1;
+ }
+ if(co->direction != DKCT_GUI_DIRECTION_HORIZONTAL) {
+ must_write_details = 2;
+ }
+ if(co->validator) {
+ must_write_details = 3;
+ }
+ if(must_write_details) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(must_write_details > 1) {
+ dkct_gui_next_argument(psrc);
+ if(co->direction == DKCT_GUI_DIRECTION_HORIZONTAL) {
+ fputs(dkct_gui_out_kw[101], psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[102], psrc->fipo);
+ }
+ if(must_write_details > 2) {
+ dkct_gui_next_argument(psrc);
+ fputs(co->validator, psrc->fipo);
+ }
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write element constructor for spin button.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_spinbutton(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int need_details = 0; /* Details level. */
+
+ if(co->sizex > 0) { need_details = 1; }
+ if(co->sizey > 0) { need_details = 1; }
+ if(co->direction != DKCT_GUI_DIRECTION_HORIZONTAL) { need_details = 2; }
+ if(co->useKeys) { need_details = 2; }
+ if(co->spinWrap) { need_details = 2; }
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ if(need_details) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(need_details > 1) {
+ dkct_gui_next_argument(psrc);
+ if(co->direction == DKCT_GUI_DIRECTION_HORIZONTAL) {
+ fputs(dkct_gui_out_kw[92], psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[93], psrc->fipo);
+ }
+ if(co->useKeys) {
+ fputs(dkct_gui_out_kw[94], psrc->fipo);
+ }
+ if(co->spinWrap) {
+ fputs(dkct_gui_out_kw[95], psrc->fipo);
+ }
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write element constructor for spin control.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_spincontrol(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ char bu[64]; /* Buffer for numeric values. */
+ int need_details = 0; /* Details level. */
+
+ if(co->text) { need_details = 1; }
+ if((co->sizex > 0) && (co->sizey > 0)) { need_details = 2; }
+ if(co->useKeys) { need_details = 3; }
+ if(co->spinWrap) { need_details = 3; }
+ if(co->spinMin != 0) { need_details = 4; }
+ if(co->spinMax != 100) { need_details = 5; }
+ if(co->spinVal != 0) { need_details = 6; }
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ if(need_details) {
+ dkct_gui_next_argument(psrc);
+ if(co->text) {
+ fputs(co->text, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[73], psrc->fipo);
+ }
+ if(need_details > 1) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(need_details > 2) {
+ dkct_gui_next_argument(psrc);
+ if(co->useKeys) {
+ if(co->spinWrap) {
+ fputs(dkct_gui_out_kw[96], psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[97], psrc->fipo);
+ }
+ } else {
+ if(co->spinWrap) {
+ fputs(dkct_gui_out_kw[98], psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[52], psrc->fipo);
+ }
+ }
+ if(need_details > 3) {
+ dkct_gui_next_argument(psrc);
+ sprintf(bu, "%d", co->spinMin);
+ fputs(bu, psrc->fipo);
+ if(need_details > 4) {
+ dkct_gui_next_argument(psrc);
+ sprintf(bu, "%d", co->spinMax);
+ fputs(bu, psrc->fipo);
+ if(need_details > 5) {
+ dkct_gui_next_argument(psrc);
+ sprintf(bu, "%d", co->spinVal);
+ fputs(bu, psrc->fipo);
+ }
+ }
+ }
+ }
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write integer value.
+ @param fipo Output file.
+ @param i Value to write.
+*/
+static
+void
+dkct_gui_write_int_arg(FILE *fipo, int i)
+{
+ char bu[64];
+ sprintf(bu, "%d", i);
+ fputs(bu, fipo);
+}
+
+
+
+
+
+/** Write element constructor for slider.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_slider(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int det = 0; /* Details level. */
+ /*
+ parent, id, value, min, max, pos, size (1), style (2), validator (3)
+ */
+ if((co->sizex > 0) && (co->sizey > 0)) det = 1;
+ if(co->sliderStyle) det = 2;
+ if(co->direction != DKCT_GUI_DIRECTION_HORIZONTAL) det = 2;
+ if(co->validator) det = 3;
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_int_arg(psrc->fipo, co->spinVal);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_int_arg(psrc->fipo, co->spinMin);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_int_arg(psrc->fipo, co->spinMax);
+ if(det) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(det > 1) {
+ if(co->direction == DKCT_GUI_DIRECTION_HORIZONTAL) {
+ fputs(dkct_gui_out_kw[103], psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[104], psrc->fipo);
+ }
+ if((co->sliderStyle) & DKCT_GUI_SL_STYLE_AUTOTICKS) {
+ fputs(dkct_gui_out_kw[105], psrc->fipo);
+ }
+ if((co->sliderStyle) & DKCT_GUI_SL_STYLE_LABELS) {
+ fputs(dkct_gui_out_kw[106], psrc->fipo);
+ }
+ if((co->sliderStyle) & DKCT_GUI_SL_STYLE_LEFT) {
+ fputs(dkct_gui_out_kw[107], psrc->fipo);
+ }
+ if((co->sliderStyle) & DKCT_GUI_SL_STYLE_RIGHT) {
+ fputs(dkct_gui_out_kw[108], psrc->fipo);
+ }
+ if((co->sliderStyle) & DKCT_GUI_SL_STYLE_TOP) {
+ fputs(dkct_gui_out_kw[109], psrc->fipo);
+ }
+ if((co->sliderStyle) & DKCT_GUI_SL_STYLE_BOTTOM) {
+ fputs(dkct_gui_out_kw[110], psrc->fipo);
+ }
+ if((co->sliderStyle) & DKCT_GUI_SL_STYLE_SELRANGE) {
+ fputs(dkct_gui_out_kw[111], psrc->fipo);
+ }
+ if((co->sliderStyle) & DKCT_GUI_SL_STYLE_INVERSE) {
+ fputs(dkct_gui_out_kw[112], psrc->fipo);
+ }
+ if(det > 2) {
+ dkct_gui_next_argument(psrc);
+ fputs(co->validator, psrc->fipo);
+ }
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write element constructor text control
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_textctrl(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int det = 0; /* Details level. */
+ int fe = 0; /* Flag: Found entry. */
+ /*
+ parent, id, value (1), pos, size (2), style (3), validator (4)
+ */
+ if(co->text) det = 1;
+ if((co->sizex > 0) && (co->sizey > 0)) det = 2;
+ if(co->textStyle) det = 3;
+ if(co->validator) det = 4;
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ if(det) {
+ dkct_gui_next_argument(psrc);
+ if(co->text) {
+ fputs(co->text, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[73], psrc->fipo);
+ }
+ if(det > 1) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(det > 2) {
+ dkct_gui_next_argument(psrc);
+ if((co->textStyle) & DKCT_GUI_TEXT_ENTER) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[121], psrc->fipo);
+ }
+ if((co->textStyle) & DKCT_GUI_TEXT_TAB) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[122], psrc->fipo);
+ }
+ if((co->textStyle) & DKCT_GUI_TEXT_MULTILINE) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[123], psrc->fipo);
+ }
+ if((co->textStyle) & DKCT_GUI_TEXT_PASSWORD) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[124], psrc->fipo);
+ }
+ if((co->textStyle) & DKCT_GUI_TEXT_READONLY) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[125], psrc->fipo);
+ }
+ if((co->textStyle) & DKCT_GUI_TEXT_RICH) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[126], psrc->fipo);
+ }
+ if((co->textStyle) & DKCT_GUI_TEXT_RICH2) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[127], psrc->fipo);
+ }
+ if((co->textStyle) & DKCT_GUI_TEXT_URL) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[128], psrc->fipo);
+ }
+ if((co->textStyle) & DKCT_GUI_TEXT_SHOWSEL) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[129], psrc->fipo);
+ }
+ if((co->textStyle) & DKCT_GUI_TEXT_LEFT) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[130], psrc->fipo);
+ }
+ if((co->textStyle) & DKCT_GUI_TEXT_CENTRE) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[131], psrc->fipo);
+ }
+ if((co->textStyle) & DKCT_GUI_TEXT_RIGHT) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[132], psrc->fipo);
+ }
+ if((co->textStyle) & DKCT_GUI_TEXT_NOWRAP) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[133], psrc->fipo);
+ }
+ if((co->textStyle) & DKCT_GUI_TEXT_CHARWRAP) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[134], psrc->fipo);
+ }
+ if((co->textStyle) & DKCT_GUI_TEXT_WORDWRAP) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[135], psrc->fipo);
+ }
+ if((co->textStyle) & DKCT_GUI_TEXT_BESTWRAP) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[136], psrc->fipo);
+ }
+ if((co->textStyle) & DKCT_GUI_TEXT_CAPITALIZE) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[137], psrc->fipo);
+ }
+ if(!(fe)) { fputs(dkct_gui_out_kw[52], psrc->fipo); }
+ }
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write element constructor toggle button.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_togglebutton(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int det = 0; /* Details level. */
+ /*
+ parent, id, label, pos, size (1), style (2), validator (3)
+ */
+ if((co->sizex > 0) && (co->sizey > 0)) det = 1;
+ if(co->validator) det = 3;
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ dkct_gui_next_argument(psrc);
+ if(co->text) {
+ fputs(co->text, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[73], psrc->fipo);
+ }
+ if(det) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(det > 1) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[52], psrc->fipo);
+ if(det > 2) {
+ dkct_gui_next_argument(psrc);
+ fputs(co->validator, psrc->fipo);
+ }
+ }
+ }
+}
+
+
+
+/** Write element constructor for gauge.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_gauge(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int det = 0; /* Details level. */
+ char bu[64]; /* Buffer for numeric values. */
+ /*
+ parent, id, range, pos, size (1), style (2), validator (3)
+ */
+ if((co->sizex > 0) && (co->sizey > 0)) det = 1;
+ if(co->direction != DKCT_GUI_DIRECTION_HORIZONTAL) det = 2;
+ if(co->gaugeStyle) det = 2;
+ if(co->validator) det = 3;
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ sprintf(bu, "%d", co->spinMax);
+ dkct_gui_next_argument(psrc);
+ fputs(bu, psrc->fipo);
+ if(det) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(det > 1) {
+ dkct_gui_next_argument(psrc);
+ if(co->direction == DKCT_GUI_DIRECTION_HORIZONTAL) {
+ fputs(dkct_gui_out_kw[160], psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[161], psrc->fipo);
+ }
+ if((co->gaugeStyle) & DKCT_GUI_GAUGE_SMOOTH) {
+ fputs(dkct_gui_out_kw[162], psrc->fipo);
+ }
+ if(det > 2) {
+ dkct_gui_next_argument(psrc);
+ fputs(co->validator, psrc->fipo);
+ }
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write element constructor for static text.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_statictext(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ unsigned long mask; /* Mask for check. */
+ int det = 0; /* Details level. */
+ int fe = 0; /* Flag: Found entry. */
+ /*
+ parent, id, label, pos, size (1), style (2)
+ */
+ if((co->sizex > 0) && (co->sizey > 0)) det = 1;
+ mask = DKCT_GUI_TEXT_LEFT;
+ mask |= DKCT_GUI_TEXT_CENTRE;
+ mask |= DKCT_GUI_TEXT_RIGHT;
+ mask |= DKCT_GUI_TEXT_NO_AUTORESIZE;
+ if((co->textStyle) & mask) det = 2;
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ dkct_gui_next_argument(psrc);
+ if(co->text) {
+ fputs(co->text, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[73], psrc->fipo);
+ }
+ if(det) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(det > 1) {
+ dkct_gui_next_argument(psrc);
+ if((co->textStyle) & DKCT_GUI_TEXT_LEFT) {
+ fputs(dkct_gui_out_kw[45], psrc->fipo); fe = 1;
+ } else {
+ if((co->textStyle) & DKCT_GUI_TEXT_CENTRE) {
+ fputs(dkct_gui_out_kw[163], psrc->fipo); fe = 1;
+ } else {
+ if((co->textStyle) & DKCT_GUI_TEXT_RIGHT) {
+ fputs(dkct_gui_out_kw[47], psrc->fipo); fe = 1;
+ }
+ }
+ }
+ if((co->textStyle) & DKCT_GUI_TEXT_NOWRAP) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); }
+ fputs(dkct_gui_out_kw[164], psrc->fipo);
+ fe = 1;
+ }
+ if(!(fe)) { fputs(dkct_gui_out_kw[52], psrc->fipo); }
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write element constructor for static bitmap.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_staticbitmap(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int det = 0; /* Details level. */
+ /*
+ parent, id, bitmap, pos, size (1), style (2)
+ */
+ if((co->sizex > 0) && (co->sizey > 0)) det = 1;
+ if(co->bitmapVarName) {
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ dkct_gui_next_argument(psrc);
+ fputs(co->bitmapVarName, psrc->fipo);
+ if(det) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ } else {
+ /* ERROR: No bitmap specified! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 51);
+ }
+}
+
+
+
+/** Write element constructor for static line.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_staticline(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int det = 0; /* Details level. */
+ /*
+ parent, id, pos, size (1), style (2)
+ */
+ if((co->sizex > 0) && (co->sizey > 0)) det = 1;
+ if(co->direction != DKCT_GUI_DIRECTION_HORIZONTAL) det = 2;
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ if(det) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(det > 1) {
+ dkct_gui_next_argument(psrc);
+ if(co->direction == DKCT_GUI_DIRECTION_HORIZONTAL) {
+ fputs(dkct_gui_out_kw[165], psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[166], psrc->fipo);
+ }
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write element constructor for static box.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_staticbox(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int det = 0; /* Details level. */
+ /*
+ parent, id, label, pos, size (1), style (2)
+ */
+ if((co->sizex > 0) && (co->sizey > 0)) det = 1;
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ if(det) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(det > 1) {
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write element constructor for menu bar.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_menubar(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ /*
+ No constructor arguments.
+ */
+}
+
+
+
+/** Write element constructor for menu.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_menu(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ /*
+ No constructor arguments.
+ */
+}
+
+
+
+/** Write element constructor for menu item.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_menuitem(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ /*
+ parent->Append(id, label, helpstring, kind);
+ */
+#if 0
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ if(co->menuItemStyle == DKCT_GUI_MENU_ITEM_SEPARATOR) {
+ fputs(dkct_gui_out_kw[171], psrc->fipo);
+ } else {
+ if(co->idname) {
+ fputs(co->idname, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[171], psrc->fipo);
+ }
+ }
+ dkct_gui_next_argument(psrc);
+ if(co->text) {
+ fputs(co->text, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[73], psrc->fipo);
+ }
+ dkct_gui_next_argument(psrc);
+ if(co->tipText) {
+ fputs(co->tipText, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[73], psrc->fipo);
+ }
+ dkct_gui_next_argument(psrc);
+ switch(co->menuItemStyle) {
+ case DKCT_GUI_MENU_ITEM_SEPARATOR: {
+ fputs(dkct_gui_out_kw[168], psrc->fipo);
+ } break;
+ case DKCT_GUI_MENU_ITEM_CHECK: {
+ fputs(dkct_gui_out_kw[169], psrc->fipo);
+ } break;
+ case DKCT_GUI_MENU_ITEM_RADIO: {
+ fputs(dkct_gui_out_kw[170], psrc->fipo);
+ } break;
+ default: {
+ fputs(dkct_gui_out_kw[167], psrc->fipo);
+ } break;
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+#else
+ if(dp) {
+ if((dp->name) && (co->name)) {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[194], psrc->fipo);
+ fputs(dp->name, psrc->fipo);
+ switch(co->menuItemStyle) {
+ case DKCT_GUI_MENU_ITEM_SEPARATOR: {
+ fputs(dkct_gui_out_kw[193], psrc->fipo);
+ } break;
+ case DKCT_GUI_MENU_ITEM_CHECK: {
+ fputs(dkct_gui_out_kw[191], psrc->fipo);
+ } break;
+ case DKCT_GUI_MENU_ITEM_RADIO: {
+ fputs(dkct_gui_out_kw[192], psrc->fipo);
+ } break;
+ default: {
+ fputs(dkct_gui_out_kw[184], psrc->fipo);
+ } break;
+ }
+ if(co->menuItemStyle != DKCT_GUI_MENU_ITEM_SEPARATOR) {
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ if(co->idname) {
+ fputs(co->idname, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[171], psrc->fipo);
+ }
+ dkct_gui_next_argument(psrc);
+ if(co->text) {
+ fputs(co->text, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[73], psrc->fipo);
+ }
+ dkct_gui_next_argument(psrc);
+ if(co->tipText) {
+ fputs(co->tipText, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[73], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+ }
+#endif
+}
+
+
+
+/** Write element constructor for menu item.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_toolbartoolbase(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ /*
+ id, text, bitmap, disbitmap (1), kind (2), tip (3)
+ */
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ if(co->menuItemStyle != DKCT_GUI_MENU_ITEM_SEPARATOR) {
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[194], psrc->fipo);
+ }
+ fputs(dp->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[185], psrc->fipo);
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_idname(co, psrc);
+ dkct_gui_next_argument(psrc);
+ if(co->text) {
+ fputs(co->text, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[73], psrc->fipo);
+ }
+ dkct_gui_next_argument(psrc);
+ fputs(co->bitmapVarName, psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ if(co->bitmapDisabled) {
+ fputs(co->bitmapDisabled, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[186], psrc->fipo);
+ }
+ /* ITEM KIND */
+ dkct_gui_next_argument(psrc);
+ switch(co->menuItemStyle) {
+ case DKCT_GUI_MENU_ITEM_SEPARATOR: {
+ fputs(dkct_gui_out_kw[169], psrc->fipo);
+ } break;
+ case DKCT_GUI_MENU_ITEM_CHECK: {
+ fputs(dkct_gui_out_kw[169], psrc->fipo);
+ } break;
+ case DKCT_GUI_MENU_ITEM_RADIO: {
+ fputs(dkct_gui_out_kw[170], psrc->fipo);
+ } break;
+ default: {
+ fputs(dkct_gui_out_kw[167], psrc->fipo);
+ } break;
+ }
+ if(co->tipText) {
+ dkct_gui_next_argument(psrc);
+ fputs(co->tipText, psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write element constructor for tool bar.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_toolbar(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int det = 0; /* Details level. */
+ /*
+ parent, id, pos, size (1), style (2)
+ */
+ if((co->sizex > 0) && (co->sizey > 0)) det = 1;
+ if(co->direction != DKCT_GUI_DIRECTION_HORIZONTAL) det = 2;
+ if(co->toolbarStyle != DKCT_GUI_TOOLBAR_FLAT) det = 2;
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+#if 0
+ dkct_gui_write_parent_name(pw, psrc, gui);
+#endif
+ if(dp) {
+ if(dp->name) {
+ fputs(dp->name, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[65], psrc->fipo);
+ }
+ } else {
+ fputs(dkct_gui_out_kw[65], psrc->fipo);
+ }
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ if(det) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(det > 1) {
+ dkct_gui_next_argument(psrc);
+ switch(co->direction) {
+ case DKCT_GUI_DIRECTION_VERTICAL: {
+ fputs(dkct_gui_out_kw[173], psrc->fipo);
+ } break;
+ default: {
+ fputs(dkct_gui_out_kw[172], psrc->fipo);
+ } break;
+ }
+ if((co->toolbarStyle) & DKCT_GUI_TOOLBAR_FLAT) {
+ fputs(dkct_gui_out_kw[174], psrc->fipo);
+ }
+ if((co->toolbarStyle) & DKCT_GUI_TOOLBAR_DOCKABLE) {
+ fputs(dkct_gui_out_kw[175], psrc->fipo);
+ }
+ if((co->toolbarStyle) & DKCT_GUI_TOOLBAR_TEXT) {
+ fputs(dkct_gui_out_kw[176], psrc->fipo);
+ }
+ if((co->toolbarStyle) & DKCT_GUI_TOOLBAR_NOICONS) {
+ fputs(dkct_gui_out_kw[177], psrc->fipo);
+ }
+ if((co->toolbarStyle) & DKCT_GUI_TOOLBAR_NODIVIDER) {
+ fputs(dkct_gui_out_kw[178], psrc->fipo);
+ }
+ if((co->toolbarStyle) & DKCT_GUI_TOOLBAR_HORZ_LAYOUT) {
+ if((co->toolbarStyle) & DKCT_GUI_TOOLBAR_TEXT) {
+ if(!((co->toolbarStyle) & DKCT_GUI_TOOLBAR_NOICONS)) {
+ fputs(dkct_gui_out_kw[180], psrc->fipo);
+ }
+ }
+ }
+ if((co->toolbarStyle) & DKCT_GUI_TOOLBAR_NO_TOOLTIPS) {
+ fputs(dkct_gui_out_kw[181], psrc->fipo);
+ }
+ if((co->toolbarStyle) & DKCT_GUI_TOOLBAR_BOTTOM) {
+ fputs(dkct_gui_out_kw[182], psrc->fipo);
+ }
+ if((co->toolbarStyle) & DKCT_GUI_TOOLBAR_RIGHT) {
+ fputs(dkct_gui_out_kw[183], psrc->fipo);
+ }
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write element constructor for grid.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_grid(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ /* parent, id, pos, size (1), style, name */
+ int det = 0;
+ if((co->sizex > 0) && (co->sizey > 0)) det = 1;
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ if(det) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(det > 1) {
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+#if 0
+/** Write element constructor (parent, id and text).
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_parent_id_and_text(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ if(co->text) {
+ dkct_gui_next_argument(psrc);
+ fputs(co->text, psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+#endif
+
+
+#if 0
+/** Write element constructor (parent, id and bitmap).
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_parent_id_and_bitmap(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ if(co->bitmapVarName) {
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ if(co->bitmapVarName) {
+ dkct_gui_next_argument(psrc);
+ fputs(co->bitmapVarName, psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ } else {
+ /* ERROR: No bitmap expression specified! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 51);
+ }
+}
+#endif
+
+
+
+/** Write instruction to set bitmap.
+ @param co Current object.
+ @param psrc Source structure.
+ @param szind Index of method name.
+ @param bm Bitmap value.
+*/
+static
+void
+dkct_gui_write_set_bitmap(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_SRC *psrc,
+ size_t szind,
+ char *bm
+)
+{
+ if(co->name) {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[szind], psrc->fipo);
+ fputs(bm, psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+}
+
+
+
+/** Write element constructor and add element to parent
+ object or sizer.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_finalize_after_constructor(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ DKCT_GRID_HEAD *gh = NULL;
+ DKCT_CELL_DATA *pcd = NULL;
+ char const *fnptr = NULL; /* File to use for debug output. */
+ int rows = 0;
+ int columns= 0;
+
+
+#line 8741 "dkct-gui.ctr"
+ /*
+ Jump to end if construction failed.
+ if(!(object)) {
+ goto dkctGUILayoutFinished;
+ }
+ */
+ fnptr = dkct_tr_get_kw8(((psrc->dkcto).deb == 2) ? 28 : 29);
+ fputs(dkct_gui_out_kw[25], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[26], psrc->fipo);
+ if((psrc->dkcto).deb) {
+
+
+#line 8753 "dkct-gui.ctr"
+ fputs(dkct_tr_get_kw8(24), psrc->fipo);
+ if((psrc->dkcto).win) {
+ fputs(dkct_tr_get_kw8(21), psrc->fipo);
+ /* 16-bit begin */
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_get_kw8(30), psrc->fipo);
+ }
+ if((psrc->dkcto).ts) {
+ if((psrc->dkcto).deb == 2) {
+ fputs(dkct_tr_get_kw8(72), psrc->fipo);
+ } else {
+ fputs(dkct_tr_get_kw8(71), psrc->fipo);
+ }
+ }
+ fputs(dkct_tr_get_kw8(61), psrc->fipo);
+ dkct_tr_show_filename_and_lineno(psrc);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ fputs(dkct_tr_get_kw8(61), psrc->fipo);
+ fputs(dkct_tr_get_kw8(73), psrc->fipo);
+ if(co->name) {
+ fputs(co->name, psrc->fipo);
+ }
+ fputs(dkct_tr_get_kw8(74), psrc->fipo);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_get_kw8(31), psrc->fipo);
+ }
+ /* 16-bit end */
+ fputs(dkct_tr_get_kw8(22), psrc->fipo);
+ }
+ /* 8-bit begin */
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_get_kw8(30), psrc->fipo);
+ }
+ if((psrc->dkcto).ts) {
+ if((psrc->dkcto).deb == 2) {
+ fputs(dkct_tr_get_kw8(70), psrc->fipo);
+ } else {
+ fputs(dkct_tr_get_kw8(32), psrc->fipo);
+ }
+ }
+ fputs(dkct_tr_get_kw8(33), psrc->fipo);
+ dkct_tr_show_filename_and_lineno(psrc);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ fputs(dkct_tr_get_kw8(33), psrc->fipo);
+ fputs(dkct_tr_get_kw8(73), psrc->fipo);
+ if(co->name) {
+ fputs(co->name, psrc->fipo);
+ }
+ fputs(dkct_tr_get_kw8(74), psrc->fipo);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_get_kw8(31), psrc->fipo);
+ }
+ /* 8-bit end */
+ if((psrc->dkcto).win) {
+ fputs(dkct_tr_get_kw8(23), psrc->fipo);
+ }
+ fputs(dkct_tr_get_kw8(25), psrc->fipo);
+ }
+
+
+#line 8822 "dkct-gui.ctr"
+ fputs(dkct_gui_out_kw[27], psrc->fipo);
+ fputs(dkct_gui_out_kw[28], psrc->fipo);
+ /* SUCCESS DEBUG CODE */
+ if((psrc->dkcto).deb) {
+
+
+#line 8827 "dkct-gui.ctr"
+ fputs(dkct_tr_get_kw8(24), psrc->fipo);
+ if((psrc->dkcto).win) {
+ fputs(dkct_tr_get_kw8(21), psrc->fipo);
+ /* 16-bit begin */
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_get_kw8(30), psrc->fipo);
+ }
+ if((psrc->dkcto).ts) {
+ if((psrc->dkcto).deb == 2) {
+ fputs(dkct_tr_get_kw8(72), psrc->fipo);
+ } else {
+ fputs(dkct_tr_get_kw8(71), psrc->fipo);
+ }
+ }
+ fputs(dkct_tr_get_kw8(61), psrc->fipo);
+ dkct_tr_show_filename_and_lineno(psrc);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ fputs(dkct_tr_get_kw8(61), psrc->fipo);
+ fputs(dkct_tr_get_kw8(76), psrc->fipo);
+ if(co->name) {
+ fputs(co->name, psrc->fipo);
+ }
+ fputs(dkct_tr_get_kw8(74), psrc->fipo);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_get_kw8(31), psrc->fipo);
+ }
+ /* 16-bit end */
+ fputs(dkct_tr_get_kw8(22), psrc->fipo);
+ }
+ /* 8-bit begin */
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_get_kw8(30), psrc->fipo);
+ }
+ if((psrc->dkcto).ts) {
+ if((psrc->dkcto).deb == 2) {
+ fputs(dkct_tr_get_kw8(70), psrc->fipo);
+ } else {
+ fputs(dkct_tr_get_kw8(32), psrc->fipo);
+ }
+ }
+ fputs(dkct_tr_get_kw8(33), psrc->fipo);
+ dkct_tr_show_filename_and_lineno(psrc);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ fputs(dkct_tr_get_kw8(33), psrc->fipo);
+ fputs(dkct_tr_get_kw8(76), psrc->fipo);
+ if(co->name) {
+ fputs(co->name, psrc->fipo);
+ }
+ fputs(dkct_tr_get_kw8(74), psrc->fipo);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_get_kw8(31), psrc->fipo);
+ }
+ /* 8-bit end */
+ if((psrc->dkcto).win) {
+ fputs(dkct_tr_get_kw8(23), psrc->fipo);
+ }
+ fputs(dkct_tr_get_kw8(25), psrc->fipo);
+ }
+ /*
+ Further element setup, done *before* we deal with contents.
+ */
+ switch(co->cln) {
+ case 0: {
+
+#line 8900 "dkct-gui.ctr"
+ } break;
+ case 1: {
+
+#line 8902 "dkct-gui.ctr"
+ } break;
+ case 2: {
+
+#line 8904 "dkct-gui.ctr"
+ } break;
+ case 3: {
+
+#line 8906 "dkct-gui.ctr"
+ } break;
+ case 4: {
+
+#line 8908 "dkct-gui.ctr"
+ } break;
+ case 5: {
+
+#line 8910 "dkct-gui.ctr"
+ } break;
+ case 6: {
+
+#line 8912 "dkct-gui.ctr"
+ } break;
+ case 7: {
+
+#line 8914 "dkct-gui.ctr"
+ } break;
+ case 8: {
+
+#line 8916 "dkct-gui.ctr"
+ } break;
+ case 9: {
+
+#line 8918 "dkct-gui.ctr"
+ } break;
+ case 10: {
+
+#line 8920 "dkct-gui.ctr"
+ } break;
+ case 11: {
+
+#line 8922 "dkct-gui.ctr"
+ } break;
+ case 12: {
+
+#line 8924 "dkct-gui.ctr"
+ } break;
+ case 13: {
+
+#line 8926 "dkct-gui.ctr"
+ /* Set size */
+ } break;
+ case 14: {
+
+#line 8929 "dkct-gui.ctr"
+ } break;
+ case 15: {
+
+#line 8931 "dkct-gui.ctr"
+ } break;
+ case 16: {
+
+#line 8933 "dkct-gui.ctr"
+ if(co->bitmapDisabled) {
+ dkct_gui_write_set_bitmap(co, psrc, 156, co->bitmapDisabled);
+ }
+ if(co->bitmapSelected) {
+ dkct_gui_write_set_bitmap(co, psrc, 157, co->bitmapSelected);
+ }
+ if(co->bitmapFocus) {
+ dkct_gui_write_set_bitmap(co, psrc, 158, co->bitmapFocus);
+ }
+ if(co->bitmapHover) {
+ dkct_gui_write_set_bitmap(co, psrc, 159, co->bitmapHover);
+ }
+ } break;
+ case 17: {
+
+#line 8947 "dkct-gui.ctr"
+ } break;
+ case 18: {
+
+#line 8949 "dkct-gui.ctr"
+ } break;
+ case 19: {
+
+#line 8951 "dkct-gui.ctr"
+ if(co->state != 0x00) {
+ fputs(co->name, psrc->fipo);
+ if(co->nStates == 0x03) {
+ if(co->state == 0x02) {
+ fputs(dkct_gui_out_kw[78], psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[79], psrc->fipo);
+ }
+ } else {
+ fputs(dkct_gui_out_kw[77], psrc->fipo);
+ }
+ }
+ } break;
+ case 20: {
+
+#line 8965 "dkct-gui.ctr"
+ } break;
+ case 21: {
+
+#line 8967 "dkct-gui.ctr"
+ } break;
+ case 22: {
+
+#line 8969 "dkct-gui.ctr"
+ } break;
+ case 23: {
+
+#line 8971 "dkct-gui.ctr"
+ } break;
+ case 24: {
+
+#line 8973 "dkct-gui.ctr"
+ } break;
+ case 25: {
+
+#line 8975 "dkct-gui.ctr"
+ } break;
+ case 26: {
+
+#line 8977 "dkct-gui.ctr"
+ } break;
+ case 27: {
+
+#line 8979 "dkct-gui.ctr"
+ } break;
+ case 28: {
+
+#line 8981 "dkct-gui.ctr"
+ } break;
+ case 29: {
+
+#line 8983 "dkct-gui.ctr"
+ } break;
+ case 30: {
+
+#line 8985 "dkct-gui.ctr"
+ } break;
+ case 31: {
+
+#line 8987 "dkct-gui.ctr"
+ } break;
+ case 32: {
+
+#line 8989 "dkct-gui.ctr"
+ } break;
+ case 33: {
+
+#line 8991 "dkct-gui.ctr"
+ } break;
+ case 34: {
+
+#line 8993 "dkct-gui.ctr"
+ } break;
+ case 35: {
+
+#line 8995 "dkct-gui.ctr"
+ } break;
+ case 36: {
+
+#line 8997 "dkct-gui.ctr"
+ } break;
+ case 37: {
+
+#line 8999 "dkct-gui.ctr"
+ } break;
+ case 38: {
+
+#line 9001 "dkct-gui.ctr"
+ } break;
+ case 39: {
+
+#line 9003 "dkct-gui.ctr"
+ } break;
+ case 41: {
+
+#line 9005 "dkct-gui.ctr"
+ if(co->gridTable) {
+
+#line 9006 "dkct-gui.ctr"
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[198], psrc->fipo);
+ fputs(co->gridTable, psrc->fipo);
+ if(co->tableOwner) {
+ fputs(dkct_gui_out_kw[55], psrc->fipo);
+ fputs(dkct_gui_out_kw[199], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ } else {
+
+#line 9017 "dkct-gui.ctr"
+#if VERSION_BEFORE_20150821
+ rows = columns = 0;
+#endif
+ if(co->nRowHeads > co->nRows) {
+ rows = co->nRowHeads;
+ } else {
+ rows = co->nRows;
+ }
+ if(co->nColumnHeads > co->nColumns) {
+ columns = co->nColumnHeads;
+ } else {
+ columns = co->nColumns;
+ }
+ if(rows < 1) rows = 1;
+ if(columns < 1) columns = 1;
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[200], psrc->fipo);
+ fprintf(psrc->fipo, "%d, %d", rows, columns);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+ if((co->sColumnHeads) && (co->iColumnHeads)) {
+ dk3sto_it_reset(co->iColumnHeads);
+ do {
+ gh = (DKCT_GRID_HEAD *)dk3sto_it_next(co->iColumnHeads);
+ if(gh) {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[201], psrc->fipo);
+ fprintf(psrc->fipo, "%d", gh->elno);
+ fputs(dkct_gui_out_kw[55], psrc->fipo);
+ fputs(gh->text, psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+ } while(gh);
+ }
+ if((co->sRowHeads) && (co->iRowHeads)) {
+ dk3sto_it_reset(co->iRowHeads);
+ do {
+ gh = (DKCT_GRID_HEAD *)dk3sto_it_next(co->iRowHeads);
+ if(gh) {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[202], psrc->fipo);
+ fprintf(psrc->fipo, "%d", gh->elno);
+ fputs(dkct_gui_out_kw[55], psrc->fipo);
+ fputs(gh->text, psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+ } while(gh);
+ }
+ if((co->sCellData) && (co->iCellData)) {
+ dk3sto_it_reset(co->iCellData);
+ do {
+ pcd = (DKCT_CELL_DATA *)dk3sto_it_next(co->iCellData);
+ if (pcd) {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[214], psrc->fipo);
+ fprintf(psrc->fipo, "%d, %d, ", pcd->row, pcd->col);
+ fputs(pcd->text, psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+ } while(NULL != pcd);
+ }
+ if (41 == co->cln) {
+ if (co->gridStyle & DKCT_GUI_GRID_AS_LABEL_ROWS) {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[216], psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+ if (co->gridStyle & DKCT_GUI_GRID_AS_LABEL_COLS) {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[217], psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+ if (co->gridStyle & DKCT_GUI_GRID_AS_DATA) {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[215], psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+ }
+ if((DKCT_GUI_TEXT_READONLY) & (co->textStyle)) {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[203], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+ } break;
+ }
+ /*
+ Minimal size, if any.
+ */
+ if((co->sizemx > 0) && (co->sizemy > 0)) {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[204], psrc->fipo);
+ fprintf(psrc->fipo, "%d, %d", co->sizemx, co->sizemy);
+ fputs(dkct_gui_out_kw[205], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+
+
+#line 9129 "dkct-gui.ctr"
+}
+
+
+
+/** Write constructor arguments start when constructor is given.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+ @param comma Flag: Write a final comma.
+*/
+static
+void
+dkct_gui_constructor_constructor(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui,
+ int comma
+)
+{
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ fputs(dkct_gui_out_kw[209], psrc->fipo);
+ if(co->idname) {
+ fputs(co->idname, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[66], psrc->fipo);
+ }
+ if(comma) {
+ fputs(dkct_gui_out_kw[209], psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+}
+
+
+/** Write element constructor and add element to parent
+ object or sizer.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_write_element_constructor(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+
+
+#line 9187 "dkct-gui.ctr"
+ /*
+ Write tests to check constructor prerequisitions.
+ */
+ switch(co->cln) {
+ case 16:
+ case 40:
+ {
+#if 0
+ /*
+ 2011-07-30: Bitmaps are typically compiled-in.
+ */
+ if(co->bitmapVarName) {
+
+
+#line 9200 "dkct-gui.ctr"
+ fputs(dkct_gui_out_kw[25], psrc->fipo);
+ fputs(co->bitmapVarName, psrc->fipo);
+ fputs(dkct_gui_out_kw[26], psrc->fipo);
+ fputs(dkct_gui_out_kw[27], psrc->fipo);
+ fputs(dkct_gui_out_kw[28], psrc->fipo);
+ }
+#endif
+ } break;
+ }
+ /*
+ Write constructor.
+ object = new class(arguments);
+ */
+ switch(co->cln) {
+ case 37: {
+ if(dp) {
+ if(dp->cln == 36) {
+ if(co->text) {
+ dkct_gui_constructor_menuitem(co, dp, pw, psrc, gui);
+ if(co->menuItemStyle != DKCT_GUI_MENU_ITEM_SEPARATOR) {
+ dkct_gui_finalize_after_constructor(co, dp, pw, psrc, gui);
+ }
+ } else {
+ /* ERROR: No text specified */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 49);
+ }
+ } else {
+
+#line 9227 "dkct-gui.ctr"
+ /* ERROR: Parent is not a menu */
+ dkct_gui_report_illegal_parent_child(co, dp, gui->psrc);
+ }
+ } else {
+ /* ERROR: No parent */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 92);
+ }
+ } break;
+ case 40: {
+ if(dp) {
+ if(dp->cln == 38) {
+ if(dp->name) {
+ if(co->bitmapVarName) {
+ if(co->text) {
+ dkct_gui_constructor_toolbartoolbase(co, dp, pw, psrc, gui);
+ if(co->menuItemStyle != DKCT_GUI_MENU_ITEM_SEPARATOR) {
+ dkct_gui_finalize_after_constructor(co, dp, pw, psrc, gui);
+ }
+ } else {
+ /* ERROR: No text */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 49);
+ }
+ } else {
+ /* ERROR: No bitmap */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 51);
+ }
+ } else {
+ /* ERROR: No parent name */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 91);
+ }
+ } else {
+
+#line 9258 "dkct-gui.ctr"
+ /* ERROR: Parent is not a toolbar */
+ dkct_gui_report_illegal_parent_child(co, dp, gui->psrc);
+ }
+ } else {
+ /* ERROR: No parent */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 92);
+ }
+ } break;
+ default: {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[23], psrc->fipo);
+ fputs(co->cname, psrc->fipo);
+ fputs(dkct_gui_out_kw[29], psrc->fipo);
+ if(co->constructor) {
+ if(!(co->compConst)) {
+ dkct_gui_constructor_constructor(co,dp,pw,psrc,gui,1);
+ }
+ fputs(co->constructor, psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ switch(co->cln) {
+ case 5:
+ {
+ /* WARNING: Constructor specified, not recommended! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 80);
+ } break;
+ }
+ } else {
+ switch(co->cln) {
+ case 0: {
+
+#line 9288 "dkct-gui.ctr"
+ dkct_gui_constructor_frame_dialog(co,dp,pw,psrc,gui);
+ } break;
+ case 1: {
+
+#line 9291 "dkct-gui.ctr"
+ dkct_gui_constructor_frame_dialog(co,dp,pw,psrc,gui);
+ } break;
+ case 2: {
+
+#line 9294 "dkct-gui.ctr"
+ dkct_gui_constructor_frame_dialog(co,dp,pw,psrc,gui);
+ } break;
+ case 3: {
+
+#line 9297 "dkct-gui.ctr"
+ dkct_gui_constructor_frame_dialog(co,dp,pw,psrc,gui);
+ } break;
+ case 4: {
+
+#line 9300 "dkct-gui.ctr"
+ } break;
+ case 5: {
+
+#line 9302 "dkct-gui.ctr"
+ dkct_gui_constructor_boxsizer(co, dp, pw, psrc, gui);
+ } break;
+ case 6: {
+
+#line 9305 "dkct-gui.ctr"
+ dkct_gui_constructor_gridsizer(co,dp,pw,psrc,gui);
+ } break;
+ case 7: {
+
+#line 9308 "dkct-gui.ctr"
+ dkct_gui_constructor_gridbagsizer(co,dp,pw,psrc,gui);
+ } break;
+ case 8: {
+
+#line 9311 "dkct-gui.ctr"
+ dkct_gui_constructor_gridsizer(co,dp,pw,psrc,gui);
+ } break;
+ case 9: {
+
+#line 9314 "dkct-gui.ctr"
+ dkct_gui_constructor_staticboxsizer(co,dp,pw,psrc,gui);
+ } break;
+ case 10: {
+
+#line 9317 "dkct-gui.ctr"
+ /* No constructor arguments at all. */
+ } break;
+ case 11: {
+
+#line 9320 "dkct-gui.ctr"
+ dkct_gui_constructor_panel(co, dp, pw, psrc, gui);
+ } break;
+ case 12: {
+
+#line 9323 "dkct-gui.ctr"
+ dkct_gui_constructor_notebook(co, dp, pw, psrc, gui);
+ } break;
+ case 13: {
+
+#line 9326 "dkct-gui.ctr"
+ dkct_gui_constructor_scrolledwindow(co, dp, pw, psrc, gui);
+ } break;
+ case 14: {
+
+#line 9329 "dkct-gui.ctr"
+ dkct_gui_constructor_splitterwindow(co, dp, pw, psrc, gui);
+ } break;
+ case 15: {
+
+#line 9332 "dkct-gui.ctr"
+ dkct_gui_constructor_button(co, dp, pw, psrc, gui);
+ } break;
+ case 16: {
+
+#line 9335 "dkct-gui.ctr"
+ dkct_gui_constructor_bitmapbutton(co, dp, pw, psrc, gui);
+ } break;
+ case 17: {
+
+#line 9338 "dkct-gui.ctr"
+ dkct_gui_constructor_choice_combo(co, dp, pw, psrc, gui, 0);
+ } break;
+ case 18: {
+
+#line 9341 "dkct-gui.ctr"
+ dkct_gui_constructor_choice_combo(co, dp, pw, psrc, gui, 1);
+ } break;
+ case 19: {
+
+#line 9344 "dkct-gui.ctr"
+ dkct_gui_constructor_checkbox(co, dp, pw, psrc, gui);
+ } break;
+ case 20: {
+
+#line 9347 "dkct-gui.ctr"
+ dkct_gui_constructor_listbox(co, dp, pw, psrc, gui);
+ } break;
+ case 21: {
+
+#line 9350 "dkct-gui.ctr"
+ dkct_gui_constructor_checklistbox(co, dp, pw, psrc, gui);
+ } break;
+ case 22: {
+
+#line 9353 "dkct-gui.ctr"
+ dkct_gui_constructor_radiobox(co, dp, pw, psrc, gui);
+ } break;
+ case 23: {
+
+#line 9356 "dkct-gui.ctr"
+ dkct_gui_constructor_radiobutton(co, dp, pw, psrc, gui);
+ } break;
+ case 24: {
+
+#line 9359 "dkct-gui.ctr"
+ dkct_gui_constructor_scrollbar(co, dp, pw, psrc, gui);
+ } break;
+ case 25: {
+
+#line 9362 "dkct-gui.ctr"
+ dkct_gui_constructor_spinbutton(co, dp, pw, psrc, gui);
+ } break;
+ case 26: {
+
+#line 9365 "dkct-gui.ctr"
+ dkct_gui_constructor_spincontrol(co, dp, pw, psrc, gui);
+ } break;
+ case 27: {
+
+#line 9368 "dkct-gui.ctr"
+ dkct_gui_constructor_slider(co, dp, pw, psrc, gui);
+ } break;
+ case 28: {
+
+#line 9371 "dkct-gui.ctr"
+ dkct_gui_constructor_textctrl(co, dp, pw, psrc, gui);
+ } break;
+ case 29: {
+
+#line 9374 "dkct-gui.ctr"
+ dkct_gui_constructor_togglebutton(co, dp, pw, psrc, gui);
+ } break;
+ case 30: {
+
+#line 9377 "dkct-gui.ctr"
+ dkct_gui_constructor_gauge(co, dp, pw, psrc, gui);
+ } break;
+ case 31: {
+
+#line 9380 "dkct-gui.ctr"
+ dkct_gui_constructor_statictext(co, dp, pw, psrc, gui);
+ } break;
+ case 32: {
+
+#line 9383 "dkct-gui.ctr"
+ dkct_gui_constructor_staticbitmap(co, dp, pw, psrc, gui);
+ } break;
+ case 33: {
+
+#line 9386 "dkct-gui.ctr"
+ dkct_gui_constructor_staticline(co, dp, pw, psrc, gui);
+ } break;
+ case 34: {
+
+#line 9389 "dkct-gui.ctr"
+ dkct_gui_constructor_staticbox(co, dp, pw, psrc, gui);
+ } break;
+ case 35: {
+
+#line 9392 "dkct-gui.ctr"
+ dkct_gui_constructor_menubar(co, dp, pw, psrc, gui);
+ } break;
+ case 36: {
+
+#line 9395 "dkct-gui.ctr"
+ dkct_gui_constructor_menu(co, dp, pw, psrc, gui);
+ } break;
+#if 0
+ case 37: {
+
+#line 9399 "dkct-gui.ctr"
+ /*
+ Never happens.
+ */
+ } break;
+#endif
+ case 38: {
+
+#line 9405 "dkct-gui.ctr"
+ dkct_gui_constructor_toolbar(co, dp, pw, psrc, gui);
+ } break;
+ case 39: {
+
+#line 9408 "dkct-gui.ctr"
+ } break;
+ case 41: {
+ dkct_gui_constructor_grid(co, dp, pw, psrc, gui);
+ } break;
+ default: {
+ if(!(co->compConst)) {
+ dkct_gui_constructor_constructor(co,dp,pw,psrc,gui,0);
+ }
+ } break;
+ }
+ }
+ fputs(dkct_gui_out_kw[37], psrc->fipo);
+ dkct_gui_finalize_after_constructor(co, dp, pw, psrc, gui);
+ } break;
+ }
+
+
+#line 9424 "dkct-gui.ctr"
+}
+
+
+
+/** Add pseudo object.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_add_pseudo_object(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ char bu[256]; /* Buffer for numeric values. */
+
+
+#line 9447 "dkct-gui.ctr"
+ if(dp) {
+ switch(dp->cln) {
+ case 7: { /* gridbag sizer */
+ switch(co->pseudoobj) {
+ case 1: case 2: {
+
+#line 9452 "dkct-gui.ctr"
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ if(dp->name) {
+ fputs(dp->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[31], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[196], psrc->fipo);
+ sprintf(bu, "%d", co->sizex);
+ fputs(bu, psrc->fipo);
+ fputs(dkct_gui_out_kw[55], psrc->fipo);
+ sprintf(bu, "%d", co->sizey);
+ fputs(bu, psrc->fipo);
+ fputs(dkct_gui_out_kw[55], psrc->fipo);
+ /* wxGBPosition() */
+ sprintf(bu, "%d, %d", co->posy, co->posx);
+ fputs(dkct_gui_out_kw[53], psrc->fipo);
+ fputs(bu, psrc->fipo);
+ fputs(dkct_gui_out_kw[56], psrc->fipo);
+ fputs(dkct_gui_out_kw[55], psrc->fipo);
+ sprintf(bu, "%d, %d", co->spany, co->spanx);
+ fputs(dkct_gui_out_kw[54], psrc->fipo);
+ fputs(bu, psrc->fipo);
+ fputs(dkct_gui_out_kw[56], psrc->fipo);
+#if 0
+ /* 2011-07-30: No wxGROW flag for spacers. */
+ if(co->expandFlag) {
+ fputs(dkct_gui_out_kw[55], psrc->fipo);
+ fputs(dkct_gui_out_kw[51], psrc->fipo);
+ }
+#endif
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ } break;
+ default: {
+ /* ERROR: Can not add this class to parent! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 81);
+ } break;
+ }
+ } break;
+ case 5: case 6: case 8: case 9: case 10: { /* other sizers */
+ /*
+ parent->Add(width, height, proportion, flags);
+ */
+ switch(co->pseudoobj) {
+ case 1: case 2: {
+
+#line 9496 "dkct-gui.ctr"
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ if(dp->name) {
+ fputs(dp->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[31], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[196], psrc->fipo);
+ sprintf(bu, "%d", co->sizex);
+ fputs(bu, psrc->fipo);
+ fputs(dkct_gui_out_kw[55], psrc->fipo);
+ sprintf(bu, "%d", co->sizey);
+ fputs(bu, psrc->fipo);
+ fputs(dkct_gui_out_kw[55], psrc->fipo);
+ sprintf(bu, "%d", co->proportion);
+ fputs(bu, psrc->fipo);
+#if 0
+ /* 2011-07-30: No wxGROW flag for stretch and spacers. */
+ if(co->expandFlag) {
+ fputs(dkct_gui_out_kw[55], psrc->fipo);
+ fputs(dkct_gui_out_kw[51], psrc->fipo);
+ }
+#endif
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ } break;
+ default: {
+ /* ERROR: Can not add this class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 81);
+ } break;
+ }
+ } break;
+ case 36: { /* menu */
+ switch(co->pseudoobj) {
+ case 3: {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ if(dp->name) {
+ fputs(dp->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[31], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[188], psrc->fipo);
+ } break;
+ default: {
+ /* ERROR: Can not add this class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 81);
+ } break;
+ }
+ } break;
+ case 38: { /* tool bar */
+ switch(co->pseudoobj) {
+ case 3: {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ if(dp->name) {
+ fputs(dp->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[31], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[189], psrc->fipo);
+ } break;
+ default: {
+ /* ERROR: Can not add this class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 81);
+ } break;
+ }
+ } break;
+ }
+ }
+
+
+#line 9561 "dkct-gui.ctr"
+}
+
+
+
+/** Finish wxSplitterWindow after finishing the contents.
+ @param co Current object.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_finish_splitter_window(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ char bu[64]; /* Buffer for numeric values. */
+ DKCT_GUI_ELEMENT *a = NULL; /* First child window. */
+ DKCT_GUI_ELEMENT *b = NULL; /* Second child window. */
+ char *na = NULL; /* Name of first child. */
+ char *nb = NULL; /* Name of second child. */
+ char *nc = NULL; /* Current objects name. */
+ dk3sto_it_reset(co->i_contents);
+ a = (DKCT_GUI_ELEMENT *)dk3sto_it_next(co->i_contents);
+ if(a) {
+ b = (DKCT_GUI_ELEMENT *)dk3sto_it_next(co->i_contents);
+ if(b) {
+ if(dk3sto_it_next(co->i_contents)) {
+ /* ERROR: Too many elements for splitter window */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 47);
+ }
+ }
+ }
+ if(a) { na = a->name; }
+ if(b) { nb = b->name; }
+ nc = co->name;
+ if((na) && (nb)) {
+ /*
+ if((na) && (nb)) {
+ nc->SplitHorizontally(na, nb, sash);
+ }
+ */
+ } else {
+ /* ERROR: Too few contents for splitter window. */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 47);
+ }
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(dkct_gui_out_kw[67], psrc->fipo);
+ fputs(na, psrc->fipo);
+ fputs(dkct_gui_out_kw[68], psrc->fipo);
+ fputs(nb, psrc->fipo);
+ fputs(dkct_gui_out_kw[69], psrc->fipo);
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ fputs(nc, psrc->fipo);
+ fputs(dkct_gui_out_kw[31], psrc->fipo);
+ if(co->direction == DKCT_GUI_DIRECTION_VERTICAL) {
+ fputs(dkct_gui_out_kw[70], psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[71], psrc->fipo);
+ }
+ fputs(na, psrc->fipo);
+ fputs(dkct_gui_out_kw[55], psrc->fipo);
+ fputs(nb, psrc->fipo);
+ fputs(dkct_gui_out_kw[55], psrc->fipo);
+ sprintf(bu, "%d", co->sash);
+ fputs(bu, psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(dkct_gui_out_kw[64], psrc->fipo);
+ if(co->minPaneSize > 0) {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(nc, psrc->fipo);
+ fputs(dkct_gui_out_kw[72], psrc->fipo);
+ sprintf(bu, "%d", co->minPaneSize);
+ fputs(bu, psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+}
+
+
+
+/** Finish setup of current element after setting up all children.
+ @param co Current object.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_finish_current_element(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+
+
+#line 9659 "dkct-gui.ctr"
+ /*
+ Class-dependant finish.
+ */
+ switch(co->cln) {
+ case 10: /* standard dialog button sizer */
+ case 38: /* toolbar */
+ {
+
+#line 9666 "dkct-gui.ctr"
+ /*
+ Call ->Realize() for the standard diaglog button sizer.
+ */
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[80], psrc->fipo);
+ } break;
+ case 14: {
+
+#line 9674 "dkct-gui.ctr"
+ /*
+ Set wxSplitterWindow children and sash.
+ */
+ dkct_gui_finish_splitter_window(co, psrc, gui);
+ } break;
+ }
+ /*
+ Attribute-dependant finish.
+ */
+ if(co->text) {
+ switch(co->cln) {
+ case -1: {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ if(co->name) {
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[31], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[210], psrc->fipo);
+ fputs(co->text, psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ } break;
+ }
+ }
+ if(co->tipText) {
+
+#line 9699 "dkct-gui.ctr"
+ switch(co->cln) {
+ case 36: /* wxMenu */
+ case 37: /* wxMenuItem */
+ case 40: /* $wxToolBarTool */
+ {
+ /* Tip text already used. */
+ } break;
+ default: {
+
+#line 9707 "dkct-gui.ctr"
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ if ((NULL != co->ttflag) || (NULL != gui->ttflag)) {
+ fputs(dkct_gui_out_kw[218], psrc->fipo);
+ if (NULL != co->ttflag) {
+ fputs(co->ttflag, psrc->fipo);
+ } else {
+ fputs(gui->ttflag, psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[219], psrc->fipo);
+ }
+ if(co->name) {
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[31], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[190], psrc->fipo);
+ fputs(co->tipText, psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ if ((NULL != co->ttflag) || (NULL != gui->ttflag)) {
+ fputs(dkct_gui_out_kw[64], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ } break;
+ }
+ }
+ if(co->icon) {
+ if((co->parent) || (co->number)) {
+ /* Warning: Icon only for root level windows. */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 55);
+ }
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ if(co->name) {
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[31], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[195], psrc->fipo);
+ fputs(co->icon, psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+ if(co->validator) {
+ switch(co->cln) {
+ case -1: {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ if(co->name) {
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[31], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[211], psrc->fipo);
+ fputs(co->validator, psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ } break;
+ }
+ }
+ if((co->sizex > 0) && (co->sizey > 0)) {
+ switch(co->cln) {
+ case -1: {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ if(co->name) {
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[31], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[212], psrc->fipo);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ } break;
+ }
+ }
+
+
+#line 9777 "dkct-gui.ctr"
+}
+
+
+
+#if 0
+/** Add item to toolbar.
+ This function is not longer needed as the
+ AddTool() method is used as the constructor
+ for wxToolBarToolBase.
+ @param co Item to add.
+ @param dp Toolbar to add to.
+ @param psrc Source structure.
+*/
+static
+void
+dkct_gui_add_tool_bar_item(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_SRC *psrc
+)
+{
+}
+#endif
+
+
+
+/** Construct all members and add them.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_write_members(DKCT_SRC *psrc, DKCT_GUI *gui)
+{
+ DKCT_GUI_ELEMENT *co; /* Current object. */
+ DKCT_GUI_ELEMENT *dp; /* Direct parent. */
+ DKCT_GUI_ELEMENT *pw; /* Parent window. */
+ DKCT_GUI_ELEMENT *ne; /* Next element. */
+ char const *fnptr = NULL; /* File to use for debug output. */
+ int pprost; /* Parent output state. */
+ int pcln; /* Parent class name. */
+
+
+#line 9819 "dkct-gui.ctr"
+ fnptr = dkct_tr_get_kw8(((psrc->dkcto).deb == 2) ? 28 : 29);
+ co = gui->r_el;
+ if(co->cln != 1) {
+ psrc->lineno = 1UL;
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(dkct_gui_out_kw[33], psrc->fipo);
+ fputs(dkct_gui_out_kw[25], psrc->fipo);
+ fputs(dkct_gui_out_kw[30], psrc->fipo);
+ fputs(dkct_gui_out_kw[26], psrc->fipo);
+ /* DEBUG OUTPUT */
+ if((psrc->dkcto).deb) {
+
+
+#line 9831 "dkct-gui.ctr"
+ fputs(dkct_tr_get_kw8(24), psrc->fipo);
+ if((psrc->dkcto).win) {
+ fputs(dkct_tr_get_kw8(21), psrc->fipo);
+ /* 16-bit begin */
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_get_kw8(30), psrc->fipo);
+ }
+ if((psrc->dkcto).ts) {
+ if((psrc->dkcto).deb == 2) {
+ fputs(dkct_tr_get_kw8(72), psrc->fipo);
+ } else {
+ fputs(dkct_tr_get_kw8(71), psrc->fipo);
+ }
+ }
+ fputs(dkct_tr_get_kw8(61), psrc->fipo);
+ dkct_tr_show_filename_and_lineno(psrc);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ fputs(dkct_tr_get_kw8(61), psrc->fipo);
+ fputs(dkct_tr_get_kw8(73), psrc->fipo);
+ fputs(dkct_tr_get_kw8(75), psrc->fipo);
+ fputs(dkct_tr_get_kw8(74), psrc->fipo);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_get_kw8(31), psrc->fipo);
+ }
+ /* 16-bit end */
+ fputs(dkct_tr_get_kw8(22), psrc->fipo);
+ }
+ /* 8-bit begin */
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_get_kw8(30), psrc->fipo);
+ }
+ if((psrc->dkcto).ts) {
+ if((psrc->dkcto).deb == 2) {
+ fputs(dkct_tr_get_kw8(70), psrc->fipo);
+ } else {
+ fputs(dkct_tr_get_kw8(32), psrc->fipo);
+ }
+ }
+ fputs(dkct_tr_get_kw8(33), psrc->fipo);
+ dkct_tr_show_filename_and_lineno(psrc);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ fputs(dkct_tr_get_kw8(33), psrc->fipo);
+ fputs(dkct_tr_get_kw8(73), psrc->fipo);
+ fputs(dkct_tr_get_kw8(75), psrc->fipo);
+ fputs(dkct_tr_get_kw8(74), psrc->fipo);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_get_kw8(31), psrc->fipo);
+ }
+ /* 8-bit end */
+ if((psrc->dkcto).win) {
+ fputs(dkct_tr_get_kw8(23), psrc->fipo);
+ }
+ fputs(dkct_tr_get_kw8(25), psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[27], psrc->fipo);
+ fputs(dkct_gui_out_kw[28], psrc->fipo);
+ if((psrc->dkcto).deb) {
+
+
+#line 9899 "dkct-gui.ctr"
+ fputs(dkct_tr_get_kw8(24), psrc->fipo);
+ if((psrc->dkcto).win) {
+ fputs(dkct_tr_get_kw8(21), psrc->fipo);
+ /* 16-bit begin */
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_get_kw8(30), psrc->fipo);
+ }
+ if((psrc->dkcto).ts) {
+ if((psrc->dkcto).deb == 2) {
+ fputs(dkct_tr_get_kw8(72), psrc->fipo);
+ } else {
+ fputs(dkct_tr_get_kw8(71), psrc->fipo);
+ }
+ }
+ fputs(dkct_tr_get_kw8(61), psrc->fipo);
+ dkct_tr_show_filename_and_lineno(psrc);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ fputs(dkct_tr_get_kw8(61), psrc->fipo);
+ fputs(dkct_tr_get_kw8(76), psrc->fipo);
+ fputs(dkct_tr_get_kw8(75), psrc->fipo);
+ fputs(dkct_tr_get_kw8(74), psrc->fipo);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_get_kw8(31), psrc->fipo);
+ }
+ /* 16-bit end */
+ fputs(dkct_tr_get_kw8(22), psrc->fipo);
+ }
+ /* 8-bit begin */
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_get_kw8(30), psrc->fipo);
+ }
+ if((psrc->dkcto).ts) {
+ if((psrc->dkcto).deb == 2) {
+ fputs(dkct_tr_get_kw8(70), psrc->fipo);
+ } else {
+ fputs(dkct_tr_get_kw8(32), psrc->fipo);
+ }
+ }
+ fputs(dkct_tr_get_kw8(33), psrc->fipo);
+ dkct_tr_show_filename_and_lineno(psrc);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ fputs(dkct_tr_get_kw8(33), psrc->fipo);
+ fputs(dkct_tr_get_kw8(76), psrc->fipo);
+ fputs(dkct_tr_get_kw8(75), psrc->fipo);
+ fputs(dkct_tr_get_kw8(74), psrc->fipo);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_get_kw8(31), psrc->fipo);
+ }
+ /* 8-bit end */
+ if((psrc->dkcto).win) {
+ fputs(dkct_tr_get_kw8(23), psrc->fipo);
+ }
+ fputs(dkct_tr_get_kw8(25), psrc->fipo);
+ }
+ }
+ dk3sto_it_reset(co->i_contents);
+ while(co) {
+
+#line 9966 "dkct-gui.ctr"
+ psrc->lineno = ((co->lndef) > 0UL) ? (co->lndef) : (co->lndecl);
+ dk3app_set_source_line(psrc->app, psrc->lineno);
+ dp = pw = (DKCT_GUI_ELEMENT *)(co->parent);
+ pw = dkct_gui_find_real_parent(pw);
+ switch(co->prost) {
+ case DKCT_GUI_PROCESSING_STATE_START: {
+ if(co->pseudoobj) {
+ /*
+ Pseudo object (stretch spacer, separator...)
+ */
+ dkct_gui_add_pseudo_object(co, dp, pw, psrc, gui);
+ co = (DKCT_GUI_ELEMENT *)(co->parent);
+ } else {
+ /*
+ Real object.
+ */
+ if((co->parent) && (co->name)) {
+ if(dkct_gui_need_element_constructor(co)) {
+
+
+#line 9985 "dkct-gui.ctr"
+ dkct_gui_write_element_constructor(co, dp, pw, psrc, gui);
+ }
+ }
+ dk3sto_it_reset(co->i_contents);
+ if(co->menubar) {
+
+#line 9990 "dkct-gui.ctr"
+ fputs(dkct_gui_out_kw[19], psrc->fipo);
+ co->prost = DKCT_GUI_PROCESSING_STATE_MENU;
+ co = (DKCT_GUI_ELEMENT *)(co->menubar);
+ } else {
+ if(co->toolbar) {
+
+#line 9995 "dkct-gui.ctr"
+ fputs(dkct_gui_out_kw[20], psrc->fipo);
+ co->prost = DKCT_GUI_PROCESSING_STATE_TOOL;
+ co = (DKCT_GUI_ELEMENT *)(co->toolbar);
+ } else {
+
+#line 9999 "dkct-gui.ctr"
+ co->prost = DKCT_GUI_PROCESSING_STATE_CONTENTS;
+ }
+ }
+ }
+ } break;
+ case DKCT_GUI_PROCESSING_STATE_MENU: {
+ /*
+ Finish menu processing.
+ */
+ fputs(dkct_gui_out_kw[22], psrc->fipo);
+ if(co->toolbar) {
+
+#line 10010 "dkct-gui.ctr"
+ fputs(dkct_gui_out_kw[20], psrc->fipo);
+ co->prost = DKCT_GUI_PROCESSING_STATE_TOOL;
+ co = (DKCT_GUI_ELEMENT *)(co->toolbar);
+ } else {
+
+#line 10014 "dkct-gui.ctr"
+ co->prost = DKCT_GUI_PROCESSING_STATE_CONTENTS;
+ }
+ } break;
+ case DKCT_GUI_PROCESSING_STATE_TOOL: {
+ /*
+ Finish tool bar processing.
+ */
+ fputs(dkct_gui_out_kw[22], psrc->fipo);
+ co->prost = DKCT_GUI_PROCESSING_STATE_CONTENTS;
+
+#line 10023 "dkct-gui.ctr"
+ } break;
+ case DKCT_GUI_PROCESSING_STATE_CONTENTS: {
+
+#line 10025 "dkct-gui.ctr"
+ ne = (DKCT_GUI_ELEMENT *)dk3sto_it_next(co->i_contents);
+
+#line 10026 "dkct-gui.ctr"
+ if(ne) {
+
+#line 10027 "dkct-gui.ctr"
+ co = ne;
+ } else {
+
+#line 10029 "dkct-gui.ctr"
+ co->prost = DKCT_GUI_PROCESSING_STATE_DONE;
+ /*
+ Finish current element.
+ */
+ dkct_gui_finish_current_element(co, psrc, gui);
+ /*
+ Add current element to parent.
+ */
+ if(dkct_gui_is_sizer(co)) {
+ if(dkct_gui_is_sizer((DKCT_GUI_ELEMENT *)(co->parent))) {
+ dkct_gui_add_object_to_sizer(
+ co, (DKCT_GUI_ELEMENT *)(co->parent), psrc, gui
+ );
+ } else {
+ /*
+ parent->SetSizer(object);
+ SetSizer(object);
+ */
+ dkct_gui_set_parents_sizer(
+ co, (DKCT_GUI_ELEMENT *)(co->parent), psrc, gui
+ );
+ }
+ } else {
+ if(dkct_gui_is_sizer((DKCT_GUI_ELEMENT *)(co->parent))) {
+ dkct_gui_add_object_to_sizer(
+ co, (DKCT_GUI_ELEMENT *)(co->parent), psrc, gui
+ );
+ } else {
+ /*
+ Handle special combinations of parent/child classes.
+ */
+ pprost = DKCT_GUI_PROCESSING_STATE_CONTENTS;
+ if(dp) { pprost = dp->prost; }
+ switch(pprost) {
+ /*
+ Add menu bar to root level window.
+ */
+ case DKCT_GUI_PROCESSING_STATE_MENU: {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ if(dp->name) {
+ fputs(dp->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[31], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[57], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ } break;
+ case DKCT_GUI_PROCESSING_STATE_TOOL: {
+ /*
+ Add too lbar to root level window.
+ */
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ if(dp->name) {
+ fputs(dp->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[31], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[58], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ } break;
+ default: {
+ pcln = -1;
+ if(dp) { pcln = dp->cln; }
+ switch(pcln) {
+ case 35: { /* Appending to a menu bar. */
+ switch(co->cln) {
+ case 36: {
+ /*
+ Add menu to menu bar.
+ */
+ if((dp->name) && (co->name)) {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(dp->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[184], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[55], psrc->fipo);
+ if(co->text) {
+ fputs(co->text, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[73], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+ } break;
+ default: {
+ /* ERROR: Illegal child class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 81);
+ } break;
+ }
+ } break;
+ case 36: { /* Appending to a menu. */
+ switch(co->cln) {
+ case 37: {
+ /*
+ Add menu item to menu.
+ */
+#if 0
+ if((dp->name) && (co->name)) {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(dp->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[184], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+#endif
+ } break;
+ case 36: {
+ /*
+ Add sub-menu to menu.
+ */
+ if((dp->name) && (co->name)) {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(dp->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[184], psrc->fipo);
+ dkct_gui_write_idname(co, psrc);
+ fputs(dkct_gui_out_kw[55], psrc->fipo);
+ if(co->text) {
+ fputs(co->text, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[73], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[55], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ if(co->tipText) {
+ fputs(dkct_gui_out_kw[55], psrc->fipo);
+ fputs(co->tipText, psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+ } break;
+ default: {
+ /* ERROR: Illegal child class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 81);
+ } break;
+ }
+ } break;
+ case 38: { /* Appending to a tool bar. */
+ switch(co->cln) {
+ case 40: /* wxToolBarToolBase */
+ {
+ } break;
+ default: { /* Any control */
+ if(co->name) {
+ if(dp->name) {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(dp->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[187], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+ }
+ } break;
+ }
+ } break;
+ case 14: { /* wxSplitterWindow */
+ /*
+ Do nothing, elements are added when finishing
+ the splitter window.
+ */
+ } break;
+ default: {
+ if((co->number) && (co->parent)) {
+ char const *pname;
+ char const *oname;
+ /* ERROR: Don't know how to add */
+ pname = oname = dkct_gui_out_kw[197];
+ if(co->name) oname = co->name;
+ if(dp) { if(dp->name) pname = dp->name; }
+ dkct_to_log_5(
+ gui->psrc, 1, DK3_LL_ERROR, 84, 85, 86, oname, pname
+ );
+ }
+ } break;
+ }
+ } break;
+ }
+ }
+ }
+ co = (DKCT_GUI_ELEMENT *)(co->parent);
+ }
+ } break;
+ default: {
+ co = (DKCT_GUI_ELEMENT *)(co->parent);
+ } break;
+ }
+ }
+
+#line 10221 "dkct-gui.ctr"
+}
+
+
+
+/** Write top level class constructor.
+ @param psrc Source structure.
+*/
+void
+dkct_gui_write_constructor(DKCT_SRC *psrc)
+{
+ char bu[256]; /* Buffer for numeric values. */
+ DKCT_GUI *gui; /* GUI description. */
+ DKCT_GUI_ELEMENT *el; /* Current object. */
+ DKCT_GUI_ELEMENT *szmain; /* Main sizer. */
+ int szfound = 0; /* Flag: Sizer found. */
+ int w = 0; /* Object width. */
+ int h = 0; /* Object height. */
+ if(psrc->gui) {
+ gui = (DKCT_GUI *)(psrc->gui);
+ /*
+ Flag: GUI not ok.
+ */
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(dkct_gui_out_kw[9], psrc->fipo);
+ if(dkct_gui_need_contents_panel(gui)) {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(dkct_gui_out_kw[18], psrc->fipo);
+ }
+ /*
+ Initialize all member variables to NULL.
+ */
+ dk3sto_it_reset(gui->i_el_by_num);
+ while((el = (DKCT_GUI_ELEMENT *)dk3sto_it_next(gui->i_el_by_num)) != NULL) {
+ if(el->pseudoobj == 0) {
+ if(dkct_gui_need_element_constructor(el)) {
+ if((el->name) && (el->cname)) {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(el->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[14], psrc->fipo);
+ }
+ }
+ }
+ }
+ /*
+ Construct member variables.
+ */
+ dkct_gui_write_members(psrc, gui);
+ /*
+ Flag: GUI ok.
+ */
+ el = gui->r_el;
+ if(el) {
+
+#line 10273 "dkct-gui.ctr"
+ w = el->sizex; h = el->sizey;
+
+#line 10274 "dkct-gui.ctr"
+ }
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(dkct_gui_out_kw[10], psrc->fipo);
+ /*
+ End goto label.
+ */
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(dkct_gui_out_kw[11], psrc->fipo);
+ fputs(dkct_gui_out_kw[12], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ if(el) {
+ if(el->stbsz > 0) {
+ /*
+ if wxUSE_STATUSBAR
+ if(dkctGUILayoutOK) {
+ CreateStatusBar(2);
+ SetStatusText(text);
+ }
+ endif
+ */
+ fputs(dkct_gui_out_kw[21], psrc->fipo);
+ fputs(dkct_gui_out_kw[59], psrc->fipo);
+ sprintf(bu, "%d", el->stbsz);
+ fputs(dkct_gui_out_kw[90], psrc->fipo);
+ fputs(bu, psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ if(el->stbText) {
+ fputs(dkct_gui_out_kw[91], psrc->fipo);
+ fputs(el->stbText, psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[64], psrc->fipo);
+ fputs(dkct_gui_out_kw[22], psrc->fipo);
+ }
+ }
+ /* | if(dkctGUILayoutOK) {| */
+ fputs(dkct_gui_out_kw[59], psrc->fipo);
+ if((w > 0) && (h > 0)) {
+ sprintf(bu, "%d, %d", w, h);
+ /* | wxSize const dkctGUIMinSize(| */
+ fputs(dkct_gui_out_kw[89], psrc->fipo);
+ fputs(bu, psrc->fipo);
+ /* |);| */
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ /* | SetClientSize(dkctGUIMinSize);| */
+ fputs(dkct_gui_out_kw[62], psrc->fipo);
+ } else {
+ if (NULL != el) {
+ dk3sto_it_reset(el->i_contents);
+ szmain = (DKCT_GUI_ELEMENT *)dk3sto_it_next(el->i_contents);
+ if(NULL != szmain) {
+ switch(szmain->cln) {
+ case 5: case 6: case 7: case 8: case 9: case 10: {
+ if(szmain->name) {
+ /* | | */
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ fputs(szmain->name, psrc->fipo);
+ /* |->Fit(this);| */
+ fputs(dkct_gui_out_kw[63], psrc->fipo);
+ }
+ } break;
+ }
+ }
+ }
+ }
+ szmain = NULL;
+ if (NULL != el) {
+ dk3sto_it_reset(el->i_contents);
+ szmain = (DKCT_GUI_ELEMENT *)dk3sto_it_next(el->i_contents);
+ if(NULL != szmain) {
+ if(NULL != szmain->name) {
+ switch(szmain->cln) {
+ case 5: case 6: case 7: case 8: case 9: case 10: {
+ /* | | */
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ fputs(szmain->name, psrc->fipo);
+ /* |->SetSizeHints(this);| */
+ fputs(dkct_gui_out_kw[60], psrc->fipo);
+ szfound = 1;
+ } break;
+ }
+ }
+ }
+ }
+ /* | } */
+ fputs(dkct_gui_out_kw[64], psrc->fipo);
+ if(!(szfound)) {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ /* ERROR: No sizer found! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 97);
+ }
+ }
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dkct-gui.ctr b/support/dktools/dkct-gui.ctr
new file mode 100644
index 0000000000..bcf1a8ba6c
--- /dev/null
+++ b/support/dktools/dkct-gui.ctr
@@ -0,0 +1,10374 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+%% header
+
+/** @defgroup dkctguiconst Constants for GUI layout.
+The alignment decides where to place an object if there is more
+room available for the object than necessary.
+*/
+/**@{*/
+
+/** Mask to retrieve horizontal alignment.
+*/
+#define DKCT_GUI_ALIGN_H_MASK 0x03
+
+/** Horizontal alignment: Left.
+*/
+#define DKCT_GUI_ALIGN_H_LEFT 0x01
+
+/** Horizontal alignment: Centered.
+*/
+#define DKCT_GUI_ALIGN_H_CENTER 0x02
+
+/** Horizontal alignment: Right.
+*/
+#define DKCT_GUI_ALIGN_H_RIGHT 0x03
+
+/** Mask to find vertical alignment.
+*/
+#define DKCT_GUI_ALIGN_V_MASK 0x0C
+
+/** Vertical alignment: Top.
+*/
+#define DKCT_GUI_ALIGN_V_TOP 0x04
+
+/** Vertical alignment: Centered.
+*/
+#define DKCT_GUI_ALIGN_V_CENTER 0x08
+
+/** Vertical alignment: bottom.
+*/
+#define DKCT_GUI_ALIGN_V_BOTTOM 0x0C
+
+/** Processing state for element: Nothing done yet.
+*/
+#define DKCT_GUI_PROCESSING_STATE_START 0
+
+/** Processing state for element: Processing the menu bar.
+*/
+#define DKCT_GUI_PROCESSING_STATE_MENU 1
+
+/** Processing state for element: Processing the tool bar.
+*/
+#define DKCT_GUI_PROCESSING_STATE_TOOL 2
+
+/** Processing state for element: Processing the contents.
+*/
+#define DKCT_GUI_PROCESSING_STATE_CONTENTS 3
+
+/** Processing state for element: Finished processing.
+*/
+#define DKCT_GUI_PROCESSING_STATE_DONE 4
+
+/** Left to right sizer.
+*/
+#define DKCT_GUI_DIRECTION_HORIZONTAL 0x00
+
+/** Top to bottom sizer.
+*/
+#define DKCT_GUI_DIRECTION_VERTICAL 0x01
+
+/** Scrollbars for both directions.
+*/
+#define DKCT_GUI_DIRECTION_BOTH 0x02
+
+/** Don't set border pixel number.
+*/
+#define DKCT_GUI_BORDER_POSITION_NONE 0x00
+
+/** Set border pixel number on top side.
+*/
+#define DKCT_GUI_BORDER_POSITION_TOP 0x01
+
+/** Set border pixel number on left side.
+*/
+#define DKCT_GUI_BORDER_POSITION_LEFT 0x02
+
+/** Set border pixel number on right side.
+*/
+#define DKCT_GUI_BORDER_POSITION_RIGHT 0x04
+
+/** Set border pixel number on bottom side.
+*/
+#define DKCT_GUI_BORDER_POSITION_BOTTOM 0x08
+
+/** Set border pixel number on all sides.
+*/
+#define DKCT_GUI_BORDER_POSITION_ALL 0x0F
+
+/** List selection: Allow selection of only one element.
+*/
+#define DKCT_GUI_SELECTION_STYLE_SINGLE 0x00
+
+/** List selection: Allow selection of multiple elements.
+*/
+#define DKCT_GUI_SELECTION_STYLE_MULTIPLE 0x01
+
+/** List selection: Allow CTRL/SHIFT-click.
+*/
+#define DKCT_GUI_SELECTION_STYLE_EXTENDED 0x02
+
+/** Radio box max dimension: columns.
+*/
+#define DKCT_GUI_RB_DIR_COLUMNS 0x00
+
+/** Radio box max dimension: rows.
+*/
+#define DKCT_GUI_RB_DIR_ROWS 0x01
+
+/** Slider style: Automatic tics.
+*/
+#define DKCT_GUI_SL_STYLE_AUTOTICKS 0x01
+
+/** Slider style: Show labels
+*/
+#define DKCT_GUI_SL_STYLE_LABELS 0x02
+
+/** Slider style: Tics left.
+*/
+#define DKCT_GUI_SL_STYLE_LEFT 0x04
+
+/** Slider style: Tics right.
+*/
+#define DKCT_GUI_SL_STYLE_RIGHT 0x08
+
+/** Slider style: Tics top.
+*/
+#define DKCT_GUI_SL_STYLE_TOP 0x10
+
+/** Slider style: Tics bottom.
+*/
+#define DKCT_GUI_SL_STYLE_BOTTOM 0x20
+
+/** Slider style: Range selection allowed.
+*/
+#define DKCT_GUI_SL_STYLE_SELRANGE 0x40
+
+/** Slider style: Inverse endpoints.
+*/
+#define DKCT_GUI_SL_STYLE_INVERSE 0x80
+
+/** Text control style: Enter is line break, not OK command.
+*/
+#define DKCT_GUI_TEXT_ENTER 0x00001UL
+
+/** Text control style: Insert tabulators in text, do not pass to next ctrl.
+*/
+#define DKCT_GUI_TEXT_TAB 0x00002UL
+
+/** Text control style: Multiple lines of text.
+*/
+#define DKCT_GUI_TEXT_MULTILINE 0x00004UL
+
+/** Text control style: Text shown as asterisks.
+*/
+#define DKCT_GUI_TEXT_PASSWORD 0x00008UL
+
+/** Text control style: Not editable.
+*/
+#define DKCT_GUI_TEXT_READONLY 0x00010UL
+
+/** Text control style: Rich-text control.
+*/
+#define DKCT_GUI_TEXT_RICH 0x00020UL
+
+/** Text control style: Richt-text control, higher version.
+*/
+#define DKCT_GUI_TEXT_RICH2 0x00040UL
+
+/** Text control style: Show URLs.
+*/
+#define DKCT_GUI_TEXT_URL 0x00080UL
+
+/** Text control style: Always show selection.
+*/
+#define DKCT_GUI_TEXT_SHOWSEL 0x00100UL
+
+/** Text control style: Left aligned.
+*/
+#define DKCT_GUI_TEXT_LEFT 0x00200UL
+
+/** Text control style: Centered.
+*/
+#define DKCT_GUI_TEXT_CENTRE 0x00400UL
+
+/** Text control style: Right aligned.
+*/
+#define DKCT_GUI_TEXT_RIGHT 0x00800UL
+
+/** Text control style: Do not wrap text.
+*/
+#define DKCT_GUI_TEXT_NOWRAP 0x01000UL
+
+/** Text control style: Wrap characters.
+*/
+#define DKCT_GUI_TEXT_CHARWRAP 0x02000UL
+
+/** Text control style: Wrap at word boundaries.
+*/
+#define DKCT_GUI_TEXT_WORDWRAP 0x04000UL
+
+/** Text control style: Best wrapping.
+*/
+#define DKCT_GUI_TEXT_BESTWRAP 0x08000UL
+
+/** Text control style: Capitalized first letters.
+*/
+#define DKCT_GUI_TEXT_CAPITALIZE 0x10000UL
+
+/** Text control style: No auto-resize.
+*/
+#define DKCT_GUI_TEXT_NO_AUTORESIZE 0x20000UL
+
+/** Notebook style: Tabs on top.
+*/
+#define DKCT_GUI_NB_TOP 0x0001U
+
+/** Notebook style: Tabs on left side.
+*/
+#define DKCT_GUI_NB_LEFT 0x0002U
+
+/** Notebook style: Tabs on right side.
+*/
+#define DKCT_GUI_NB_RIGHT 0x0004U
+
+/** Notebook style: Tabs on bottom.
+*/
+#define DKCT_GUI_NB_BOTTOM 0x0008U
+
+/** Notebook style: Same width for all tabs.
+*/
+#define DKCT_GUI_NB_FIXEDWIDTH 0x0010U
+
+/** Notebook style: Tabs in multiple lines.
+*/
+#define DKCT_GUI_NB_MULTILINE 0x0020U
+
+/** Notebook style: Sold color on notebook pages.
+*/
+#define DKCT_GUI_NB_NOPAGETHEME 0x0040U
+
+/** Notebook style: Show tabs in a flat style.
+*/
+#define DKCT_GUI_NB_FLAT 0x0080U
+
+/** Button style: Label left-justified.
+*/
+#define DKCT_GUI_BUTTON_LEFT 0x01
+
+/** Button style: Label top-justified.
+*/
+#define DKCT_GUI_BUTTON_TOP 0x02
+
+/** Button style: Label right-justified.
+*/
+#define DKCT_GUI_BUTTON_RIGHT 0x04
+
+/** Button style: Label bottom-justified.
+*/
+#define DKCT_GUI_BUTTON_BOTTOM 0x08
+
+/** Button style: Size as small as possible.
+*/
+#define DKCT_GUI_BUTTON_EXACTFIT 0x10
+
+/** Button style: No border.
+*/
+#define DKCT_GUI_BUTTON_NO_BORDER 0x20
+
+/** Splitter window style: 3D border and sash.
+*/
+#define DKCT_GUI_SPLITTERW_3D 0x0001U
+
+/** Splitter window style: 3D sash.
+*/
+#define DKCT_GUI_SPLITTERW_3D_SASH 0x0002U
+
+/** Splitter window style: 3D border.
+*/
+#define DKCT_GUI_SPLITTERW_3D_BORDER 0x0004U
+
+/** Splitter window style: Standard border.
+*/
+#define DKCT_GUI_SPLITTERW_BORDER 0x0008U
+
+/** Splitter window style: No border.
+*/
+#define DKCT_GUI_SPLITTERW_NO_BORDER 0x0010U
+
+/** Splitter window style: No windows XP themes.
+*/
+#define DKCT_GUI_SPLITTERW_NO_XP_THEME 0x0020U
+
+/** Splitter window style: Allow to unsplit.
+*/
+#define DKCT_GUI_SPLITTERW_PERMIT_UNSPLIT 0x0040U
+
+/** Splitter window style: No xor line, resize children immediately.
+*/
+#define DKCT_GUI_SPLITTERW_LIVE_UPDATE 0x0080U
+
+/** Button style: Automatic drawing.
+*/
+#define DKCT_GUI_BBUTTON_AUTODRAW 0x01
+
+/** Button style: Bitmap left-aligned.
+*/
+#define DKCT_GUI_BBUTTON_LEFT 0x02
+
+/** Button style: Bitmap top-aligned.
+*/
+#define DKCT_GUI_BBUTTON_TOP 0x04
+
+/** Button style: Bitmap right-aligned.
+*/
+#define DKCT_GUI_BBUTTON_RIGHT 0x08
+
+/** Button style: Bitmap bottom-aligned.
+*/
+#define DKCT_GUI_BBUTTON_BOTTOM 0x10
+
+/** Gauge style: Smooth.
+*/
+#define DKCT_GUI_GAUGE_SMOOTH 0x01
+
+/** Menu item style: normal.
+*/
+#define DKCT_GUI_MENU_ITEM_NORMAL 0x00
+
+/** Menu item style: separator.
+*/
+#define DKCT_GUI_MENU_ITEM_SEPARATOR 0x01
+
+/** Menu item style: check button.
+*/
+#define DKCT_GUI_MENU_ITEM_CHECK 0x02
+
+/** Menu item style: radio button.
+*/
+#define DKCT_GUI_MENU_ITEM_RADIO 0x03
+
+/** Toolbar style: Flat look (no border).
+*/
+#define DKCT_GUI_TOOLBAR_FLAT 0x0001U
+
+/** Toolbar style: Dockable and floatable.
+*/
+#define DKCT_GUI_TOOLBAR_DOCKABLE 0x0002U
+
+/** Toolbar style: Show text additionally to icons.
+*/
+#define DKCT_GUI_TOOLBAR_TEXT 0x0004U
+
+/** Toolbar style: No icons.
+*/
+#define DKCT_GUI_TOOLBAR_NOICONS 0x0008U
+
+/** Toolbar style: No border above toolbar.
+*/
+#define DKCT_GUI_TOOLBAR_NODIVIDER 0x0010U
+
+/** Toolbar style: No align (not very useful).
+*/
+#define DKCT_GUI_TOOLBAR_NOALIGN 0x0020U
+
+/** Toolbar style: Texts beside icons, not below.
+*/
+#define DKCT_GUI_TOOLBAR_HORZ_LAYOUT 0x0040U
+
+/** Toolbar style: Do not show tool tips.
+*/
+#define DKCT_GUI_TOOLBAR_NO_TOOLTIPS 0x0080U
+
+/** Toolbar style: Bottom side of parent window.
+*/
+#define DKCT_GUI_TOOLBAR_BOTTOM 0x0100U
+
+/** Toolbar style: Right side of parent window.
+*/
+#define DKCT_GUI_TOOLBAR_RIGHT 0x0200U
+
+/** Auto size data cells in wxGrid.
+*/
+#define DKCT_GUI_GRID_AS_DATA 0x0001U
+
+/** Auto size row labels in wxGrid.
+*/
+#define DKCT_GUI_GRID_AS_LABEL_ROWS 0x0002U
+
+/** Auto size column labels in wxGrid.
+*/
+#define DKCT_GUI_GRID_AS_LABEL_COLS 0x0004U
+
+/**@}*/
+
+
+/** Grid head (row head or column head in wxGrid).
+*/
+typedef struct {
+ char *text; /**< Label text. */
+ int elno; /**< Element number. */
+} DKCT_GRID_HEAD;
+
+
+
+/** Cell data for wxGrid contents.
+*/
+typedef struct {
+ char *text; /**< Cell text. */
+ int row; /**< Row number. */
+ int col; /**< Column number. */
+} DKCT_CELL_DATA;
+
+
+
+/** Description for one GUI element.
+*/
+typedef struct {
+ char *name; /**< Variable name. */
+ char *cname; /**< Class name. */
+ char *idname; /**< ID as text. */
+ char *text; /**< Element text (label/button). */
+ char *constructor; /**< Constructor arguments. */
+ char *tipText; /**< Tool tip text. */
+ char *icon; /**< Icon for frame. */
+ char *bitmapVarName; /**< Bitmap variable. */
+ char *bitmapDisabled; /**< Disabled bitmap. */
+ char *bitmapSelected; /**< Selected bitmap. */
+ char *bitmapFocus; /**< Focus bitmap. */
+ char *bitmapHover; /**< Mouse-over bitmap. */
+ char *choices; /**< Choices variable. */
+ char *stbText; /**< Status bar text. */
+ char *validator; /**< Validator. */
+ char *gridTable; /**< Table for grid. */
+ char *ttflag; /**< Tool tip flag. */
+ void *parent; /**< Element's parent. */
+ void *menubar; /**< Menu bar. */
+ void *toolbar; /**< Tool bar. */
+ dk3_sto_t *s_contents; /**< Contents elements storage. */
+ dk3_sto_it_t *i_contents; /**< Contents elements iterator. */
+ dk3_sto_t *sRowHeads; /**< Row heads in wxGrid. */
+ dk3_sto_it_t *iRowHeads; /**< Row heads in wxGrid. */
+ dk3_sto_t *sCellData; /**< Cell data in wxGrid. */
+ dk3_sto_it_t *iCellData; /**< Cell data in wxGrid. */
+ dk3_sto_t *sColumnHeads; /**< Column heads in wxGrid. */
+ dk3_sto_it_t *iColumnHeads; /**< Column heads in wxGrid. */
+ dk3_sto_t *sGrowRow; /**< Growable rows. */
+ dk3_sto_it_t *iGrowRow; /**< Iterator for growable rows. */
+ dk3_sto_t *sGrowCol; /**< Growable columns. */
+ dk3_sto_it_t *iGrowCol; /**< Iterator for growable columns. */
+ unsigned long lndecl; /**< Line number declaration. */
+ unsigned long lndef; /**< Line number definition. */
+ unsigned long textStyle; /**< Style for text control. */
+ size_t number; /**< Internal dkct object number. */
+ size_t passno; /**< Pass number. */
+ int cln; /**< Class number. */
+ int pseudoobj; /**< Pseudo object code. */
+ int posx; /**< X position in gridbag. */
+ int posy; /**< Y position in gridbag. */
+ int spanx; /**< X span (number of columns) in gridbag. */
+ int spany; /**< Y span (number of rows) in gridbag. */
+ int curx; /**< Current x position in grid bag. */
+ int cury; /**< Current y position in grid bag. */
+ int sizex; /**< Object x size (pixels). */
+ int sizey; /**< Object y size (pixels). */
+ int sizemx; /**< Minimum object x size (pixels). */
+ int sizemy; /**< Minimum object y size (pixels). */
+ int stbsz; /**< Status bar size. */
+ int prost; /**< Processing state. */
+ int border; /**< Border pixel number. */
+ int proportion; /**< Growth proportion. */
+ int gridcolumns; /**< Columns for grid/flexgrid. */
+ int gridrows; /**< Rows for grid/flexgrid. */
+ int gridgapx; /**< X gap. */
+ int gridgapy; /**< Y gap. */
+ int sash; /**< Sash for splitter window. */
+ int minPaneSize; /**< Minimum splitter pane size. */
+ int nChoices; /**< Number of choices. */
+ int maxRowsCols; /**< Max rows/columns in radio box. */
+ int spinMin; /**< Minimum for spin control. */
+ int spinMax; /**< Maximum for spin control. */
+ int spinVal; /**< Spin value. */
+ int nRows; /**< Number of rows in wxGrid. */
+ int nColumns; /**< Number of columns in wxGrid. */
+ int nRowHeads; /**< Number of row heads in wxGrid. */
+ int nColumnHeads; /**< Number of col heads in wxGrid. */
+ unsigned notebookStyle; /**< Notebook style. */
+ unsigned splitterStyle; /**< Splitter window style. */
+ unsigned toolbarStyle; /**< Toolbar style. */
+ unsigned gridStyle; /**< Grid style. */
+ unsigned char align; /**< Alignment. */
+ unsigned char direction; /**< Box sizer direction. */
+ unsigned char borderPos; /**< Border position. */
+ unsigned char expandFlag; /**< Flag: Expand object. */
+ unsigned char nStates; /**< Number of states for checkbox. */
+ unsigned char state; /**< Checkbox state. */
+ unsigned char selStyle; /**< Selection style. */
+ unsigned char rbDirection; /**< Direction for max size. */
+ unsigned char startGroup; /**< Flag: Start radio button group. */
+ unsigned char spinWrap; /**< Flag: Wrap spin control. */
+ unsigned char useKeys; /**< Flag: Use keys. */
+ unsigned char sliderStyle; /**< Slider style. */
+ unsigned char buttonStyle; /**< Button style. */
+ unsigned char bitmapbStyle; /**< Bitmap button style. */
+ unsigned char gaugeStyle; /**< Gauge style. */
+ unsigned char menuItemStyle; /**< Menu item style. */
+ unsigned char tableOwner; /**< Flag: Grid is table owner. */
+ unsigned char compConst; /**< Flag: Complete constructor. */
+} DKCT_GUI_ELEMENT;
+
+
+
+/** Description for one frame or dialog.
+*/
+typedef struct {
+ DKCT_SRC *psrc; /**< Source structure. */
+ DKCT_GUI_ELEMENT *c_el; /**< Current element to configure. */
+ DKCT_GUI_ELEMENT *r_el; /**< Root element. */
+ dk3_sto_t *s_el_by_name; /**< Storage for elements by name. */
+ dk3_sto_it_t *i_el_by_name; /**< Iterator for elements by name. */
+ dk3_sto_t *s_el_by_num; /**< Storage for elements by number. */
+ dk3_sto_it_t *i_el_by_num; /**< Iterator for elements by number. */
+ char *ttflag; /**< Flag for tool tips. */
+ size_t no; /**< Number of objects already found. */
+ unsigned char align; /**< Default align. */
+} DKCT_GUI;
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Create new GUI description, allocate memory.
+ @param psrc Source structure.
+ @return Pointer to new GUI description on success, NULL on error.
+*/
+DKCT_GUI *
+dkct_gui_new(DKCT_SRC *psrc);
+
+/** Destroy GUI description, release memory.
+ @param pg GUI description to destroy.
+*/
+void
+dkct_gui_delete(DKCT_GUI *pg);
+
+/** Add one input line.
+ @param gui GUI description.
+ @param il Input line to add.
+ @return 1 on success, 0 on error.
+*/
+int
+dkct_gui_add_line(DKCT_GUI *gui, char *il);
+
+/** Check GUI consistency.
+ @param psrc Source structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dkct_gui_check(DKCT_SRC *psrc);
+
+/** Write class member variables.
+ @param psrc Source structure.
+*/
+void
+dkct_gui_class_variables(DKCT_SRC *psrc);
+
+/** Write constructor for current class.
+ @param psrc Source structure.
+*/
+void
+dkct_gui_write_constructor(DKCT_SRC *psrc);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#if DK3_USE_WX
+#include "dkwxtrace.h"
+#else
+#include "dkct.h"
+#endif
+
+$!trace-include
+
+
+
+/** Class names for GUI elements.
+*/
+static char const * const dkct_gui_class_names[] = {
+/* 0 */ "wxFrame",
+/* 1 */ "wxDialog",
+/* 2 */ "wxMDIParentFrame",
+/* 3 */ "wxMDIChildFrame",
+/* 4 */ "wxPopupWindow",
+/* 5 */ "wxBoxSizer",
+/* 6 */ "wxFlexGridSizer",
+/* 7 */ "wxGridBagSizer",
+/* 8 */ "wxGridSizer",
+/* 9 */ "wxStaticBoxSizer",
+/* 10 */ "wxStdDialogButtonSizer",
+/* 11 */ "wxPanel",
+/* 12 */ "wxNotebook",
+/* 13 */ "wxScrolledWindow",
+/* 14 */ "wxSplitterWindow",
+/* 15 */ "wxButton",
+/* 16 */ "wxBitmapButton",
+/* 17 */ "wxChoice",
+/* 18 */ "wxComboBox",
+/* 19 */ "wxCheckBox",
+/* 20 */ "wxListBox",
+/* 21 */ "wxCheckListBox",
+/* 22 */ "wxRadioBox",
+/* 23 */ "wxRadioButton",
+/* 24 */ "wxScrollBar",
+/* 25 */ "wxSpinButton",
+/* 26 */ "wxSpinCtrl",
+/* 27 */ "wxSlider",
+/* 28 */ "wxTextCtrl",
+/* 29 */ "wxToggleButton",
+/* 30 */ "wxGauge",
+/* 31 */ "wxStaticText",
+/* 32 */ "wxStaticBitmap",
+/* 33 */ "wxStaticLine",
+/* 34 */ "wxStaticBox",
+/* 35 */ "wxMenuBar",
+/* 36 */ "wxMenu",
+/* 37 */ "wxMenuItem",
+/* 38 */ "wxToolBar",
+/* 39 */ "wxStatusBar",
+/* 40 */ "wxToolBarToolBase", /* Not a wxWidgets class! */
+/* 41 */ "wxGrid",
+NULL
+};
+
+
+
+/** Option names.
+*/
+static char const * const dkct_gui_option_keys[] = {
+/* 0 */ "align",
+NULL
+};
+
+
+
+/** Checkbox state names.
+*/
+static char const * const dkct_gui_db_state_names[] = {
+/* 0 */ "unchecked",
+/* 1 */ "checked",
+/* 2 */ "undetermined",
+NULL
+};
+
+
+
+/** Table selection mode names.
+*/
+static char const * const dkct_gui_cb_sel_names[]= {
+/* 0 */ "single",
+/* 1 */ "multiple",
+/* 2 */ "extended",
+NULL
+};
+
+
+
+/** Style property names for slider.
+*/
+static char const * const dkct_gui_slider_style_names[] = {
+/* 0 */ "ticks",
+/* 1 */ "labels",
+/* 2 */ "left",
+/* 3 */ "right",
+/* 4 */ "top",
+/* 5 */ "bottom",
+/* 6 */ "range",
+/* 7 */ "inverse",
+NULL
+};
+
+
+
+/** Style property names for text control.
+*/
+static char const * const dkct_gui_text_style_names[] = {
+/* 0 */ "enter",
+/* 1 */ "tab",
+/* 2 */ "multiline",
+/* 3 */ "password",
+/* 4 */ "readonly",
+/* 5 */ "rich",
+/* 6 */ "rich2",
+/* 7 */ "url",
+/* 8 */ "selection",
+/* 9 */ "left",
+/* 10 */ "centered",
+/* 11 */ "right",
+/* 12 */ "no-wrap",
+/* 13 */ "char-wrap",
+/* 14 */ "word-wrap",
+/* 15 */ "best-wrap",
+/* 16 */ "capitalize",
+/* 17 */ "no-auto-resize",
+NULL
+};
+
+
+
+/** Style property names for notebook.
+*/
+static char const * const dkct_gui_notebook_style_names[] = {
+/* 0 */ "top",
+/* 1 */ "left",
+/* 2 */ "right",
+/* 3 */ "bottom",
+/* 4 */ "fixed-width",
+/* 5 */ "multiline",
+/* 6 */ "no-theme",
+/* 7 */ "flat",
+NULL
+};
+
+
+
+/** Style property names for splitter window.
+*/
+static char const * const dkct_gui_splitterw_style_names[] = {
+/* 0 */ "3d",
+/* 1 */ "3d-sash",
+/* 2 */ "3d-border",
+/* 3 */ "border",
+/* 4 */ "no-border",
+/* 5 */ "no-xp-theme",
+/* 6 */ "permit-unsplit",
+/* 7 */ "live-update",
+NULL
+};
+
+
+
+/** Style property names for bitmap button.
+*/
+static char const * const dkct_gui_bitmapb_style_names[] = {
+/* 0 */ "auto-draw",
+/* 1 */ "left",
+/* 2 */ "top",
+/* 3 */ "right",
+/* 4 */ "bottom",
+NULL
+};
+
+
+
+/** Style property names for gauge.
+*/
+static char const * const dkct_gui_gauge_style_names[] = {
+/* 0 */ "smooth",
+NULL
+};
+
+
+
+/** Style property names for menu item.
+*/
+static char const * const dkct_gui_menu_item_style_names[] = {
+/* 0 */ "normal",
+/* 1 */ "separator",
+/* 2 */ "check",
+/* 3 */ "radio",
+NULL
+};
+
+
+
+/** Style property names for toolbar.
+*/
+static char const * const dkct_gui_toolbar_style_names[] = {
+/* 0 */ "flat",
+/* 1 */ "dockable",
+/* 2 */ "text",
+/* 3 */ "no-icons",
+/* 4 */ "no-divider",
+/* 5 */ "horizontal-layout",
+/* 6 */ "no-tooltips",
+/* 7 */ "bottom",
+/* 8 */ "right",
+NULL
+};
+
+
+
+/** Style names for wxGrid object.
+*/
+static char const * const dkct_gui_grid_style_names[] = {
+/* 0 */ "autosize-data",
+/* 1 */ "autosize-labels-rows",
+/* 2 */ "autosize-labels-columns",
+/* 3 */ "autosize-labels",
+NULL
+};
+
+
+
+/** Style property names for button.
+*/
+static char const * const dkct_gui_notebook_button_names[] = {
+/* 0 */ "left",
+/* 1 */ "top",
+/* 2 */ "right",
+/* 3 */ "bottom",
+/* 4 */ "fit",
+/* 5 */ "no-border",
+NULL
+};
+
+
+
+/** Names for alignment.
+*/
+static char const * const dkct_gui_align_names[] = {
+/* 0 */ "left",
+/* 1 */ "right",
+/* 2 */ "top",
+/* 3 */ "bottom",
+/* 4 */ "centered",
+/* 5 */ "centered-x",
+/* 6 */ "centered-y",
+NULL
+};
+
+
+
+/** Names for border positions.
+*/
+static char const * const dkct_gui_border_position_names[] = {
+/* 0 */ "all",
+/* 1 */ "top",
+/* 2 */ "left",
+/* 3 */ "right",
+/* 4 */ "bottom",
+NULL
+};
+
+
+
+/** Names of pseudo objects.
+*/
+static char const * const dkct_gui_pseudo_object_names[] = {
+/* 0 */ "$stretch", /* Stretch spacer. */
+/* 1 */ "$space", /* Spacer. */
+/* 2 */ "$separator", /* Separator in menus. */
+NULL
+};
+
+
+
+/** Base type names for the root object.
+*/
+static char const * const dkct_gui_base_type_names[] = {
+"frame",
+"dialog",
+NULL
+};
+
+
+
+/** Attribute names.
+*/
+static char const * const dkct_gui_attribute_keys[] = {
+/* 0 */ "expand",
+/* 1 */ "type",
+/* 2 */ "menu-bar",
+/* 3 */ "tool-bar",
+/* 4 */ "status-bar",
+/* 5 */ "contents",
+/* 6 */ "text",
+/* 7 */ "id",
+/* 8 */ "tip",
+/* 9 */ "proportion",
+/* 10 */ "status-text",
+/* 11 */ "border",
+/* 12 */ "constructor",
+/* 13 */ "grid", /* Grid for wxFlexGridSizer/wxGridSizer. */
+/* 14 */ "sash", /* Sash value for splitter window. */
+/* 15 */ "minimum-pane-size", /* Minimum pane size for splitter window. */
+/* 16 */ "bitmap", /* Bitmap expression for bitmap button. */
+/* 17 */ "choices", /* Choices expression. */
+/* 18 */ "states", /* Number of states + current state for checkbox. */
+/* 19 */ "size", /* Element default size. */
+/* 20 */ "selection", /* Selection style for list box. */
+/* 21 */ "rows", /* Max number of rows for radio box. */
+/* 22 */ "columns", /* Max number of columns for radio box. */
+/* 23 */ "grow", /* Alias for expand. */
+/* 24 */ "start-group", /* Start radio button group. */
+/* 25 */ "direction", /* Spin/slider/scrollbar control direction. */
+/* 26 */ "range", /* Spin/slider min and max value. */
+/* 27 */ "wrap", /* Flag: Wrap spin control. */
+/* 28 */ "keys", /* Flag: Use keys. */
+/* 29 */ "validator", /* Set validator object. */
+/* 30 */ "value", /* Spin/slider value. */
+/* 31 */ "slider-style", /* Style for sliders. */
+/* 32 */ "notebook-style", /* Style for notebooks. */
+/* 33 */ "text-style", /* Style for text controls. */
+/* 34 */ "button-style", /* Style for buttons. */
+/* 35 */ "splitter-window-style", /* Style for splitter window. */
+/* 36 */ "bitmap-button-style", /* Style for bitmap button. */
+/* 37 */ "bitmap-disabled", /* Bitmap in disabled state. */
+/* 38 */ "bitmap-selected", /* Bitmap in selected state. */
+/* 39 */ "bitmap-focus", /* Bitmap when focused. */
+/* 40 */ "bitmap-hover", /* Bitmap when mouse-over. */
+/* 41 */ "gauge-style", /* Gauge style. */
+/* 42 */ "menu-item-style", /* Menu item style. */
+/* 43 */ "toolbar-style", /* Toolbar style. */
+/* 44 */ "toolbar-button-style", /* Toolbar button style. */
+/* 45 */ "icon", /* Icon for window. */
+/* 46 */ "column-head", /* Column head for wxGrid. */
+/* 47 */ "row-head", /* Row head for wxGrid. */
+/* 48 */ "table", /* Table for wxGrid. */
+/* 49 */ "minimum-size", /* Minimum size. */
+/* 50 */ "growable-row", /* Growable row in wxGridBagSizer. */
+/* 51 */ "growable-column", /* Growable column. */
+/* 52 */ "complete-constructor-specified", /* Have complete constructor. */
+/* 53 */ "cell-data", /* Data for a wxGrid cell */
+/* 54 */ "grid-style", /* Style for grid */
+/* 55 */ "tooltip-flag", /* Tool tip flag */
+NULL
+};
+
+
+
+/** Keywords used to produce output file.
+*/
+char const * const dkct_gui_out_kw[] = {
+/* 0 */ "\n",
+/* 1 */ " ",
+/* 2 */ " ",
+/* 3 */ "*",
+/* 4 */ ";",
+/* 5 */ " /**\tGUI element ",
+/* 6 */ ".\n */\n",
+/* 7 */ " /**\tFlag: GUI ok.\n */\n bool dkctGUILayoutOK;\n\n",
+/* 8 */ " ",
+/* 9 */ "dkctGUILayoutOK = false;\n",
+/* 10 */ "dkctGUILayoutOK = true;\n",
+/* 11 */ "dkctGUILayoutFinished",
+/* 12 */ ":",
+/* 13 */ "goto",
+/* 14 */ " = NULL;\n",
+/* 15 */ ".",
+/* 16 */ "%d",
+/* 17 */
+" /**\tContents panel.\n */\n wxPanel *dkctGUIContentsPanel;\n\n",
+/* 18 */ "dkctGUIContentsPanel = NULL;\n",
+/* 19 */ "#if wxUSE_MENUS\n",
+/* 20 */ "#if wxUSE_TOOLBAR\n",
+/* 21 */ "#if wxUSE_STATUSBAR\n",
+/* 22 */ "#endif\n",
+/* 23 */ " = new ",
+/* 24 */ ");",
+/* 25 */ " if(!(",
+/* 26 */ ")) {\n",
+/* 27 */ " goto dkctGUILayoutFinished;\n",
+/* 28 */ " }\n",
+/* 29 */ "(\n",
+/* 30 */ "dkctGUIContentsPanel",
+/* 31 */ "->",
+/* 32 */ "SetSizer(",
+/* 33 */ "dkctGUIContentsPanel = new wxPanel(this);\n",
+/* 34 */ "wxHORIZONTAL",
+/* 35 */ "wxVERTICAL",
+/* 36 */ "Add(\n",
+/* 37 */ " );\n",
+/* 38 */ ",\n",
+/* 39 */ "wxALL",
+/* 40 */ "wxTOP",
+/* 41 */ "wxLEFT",
+/* 42 */ "wxRIGHT",
+/* 43 */ "wxBOTTOM",
+/* 44 */ "|",
+/* 45 */ "wxALIGN_LEFT",
+/* 46 */ "wxALIGN_CENTER_HORIZONTAL",
+/* 47 */ "wxALIGN_RIGHT",
+/* 48 */ "wxALIGN_TOP",
+/* 49 */ "wxALIGN_CENTER_VERTICAL",
+/* 50 */ "wxALIGN_BOTTOM",
+/* 51 */ "wxGROW",
+/* 52 */ "0",
+/* 53 */ "wxGBPosition(",
+/* 54 */ "wxGBSpan(",
+/* 55 */ ", ",
+/* 56 */ ")",
+/* 57 */ "SetMenuBar(",
+/* 58 */ "SetToolBar(",
+/* 59 */ " if(dkctGUILayoutOK) {\n",
+/* 60 */ "->SetSizeHints(this);\n",
+/* 61 */ "", /* UNUSED */
+/* 62 */ " SetClientSize(dkctGUIMinSize);\n",
+/* 63 */ "->Fit(this);\n",
+/* 64 */ " }\n",
+/* 65 */ "this",
+/* 66 */ "wxID_ANY",
+/* 67 */ " if((",
+/* 68 */ ") && (",
+/* 69 */ ")) {\n",
+/* 70 */ "SplitVertically(",
+/* 71 */ "SplitHorizontally(",
+/* 72 */ "->SetMinimumPaneSize(",
+/* 73 */ "wxEmptyString",
+/* 74 */ "wxDefaultPosition",
+/* 75 */ "wxDefaultSize",
+/* 76 */ "wxCHK_3STATE",
+/* 77 */ "->SetValue(true);\n",
+/* 78 */ "->Set3StateValue(wxCHK_UNDETERMINED);\n",
+/* 79 */ "->Set3StateValue(wxCHK_CHECKED);\n",
+/* 80 */ "->Realize();\n",
+/* 81 */ "wxSize(",
+/* 82 */ "wxLB_SINGLE",
+/* 83 */ "wxLB_MULTIPLE",
+/* 84 */ "wxLB_EXTENDED",
+/* 85 */ "|wxLB_HSCROLL|wxLB_NEEDED_SB",
+/* 86 */ "wxRA_SPECIFY_ROWS",
+/* 87 */ "wxRA_SPECIFY_COLS",
+/* 88 */ "wxRB_GROUP",
+/* 89 */ " wxSize const dkctGUIMinSize(",
+/* 90 */ " CreateStatusBar(",
+/* 91 */ " SetStatusText(",
+/* 92 */ "wxSP_HORIZONTAL",
+/* 93 */ "wxSP_VERTICAL",
+/* 94 */ "|wxSP_ARROW_KEYS",
+/* 95 */ "|wxSP_WRAP",
+/* 96 */ "wxSP_ARROW_KEYS|wxSP_WRAP",
+/* 97 */ "wxSP_ARROW_KEYS",
+/* 98 */ "wxSP_WRAP",
+/* 99 */ "",
+/* 100 */ "NULL",
+/* 101 */ "wxSB_HORIZONTAL",
+/* 102 */ "wxSB_VERTICAL",
+/* 103 */ "wxSL_HORIZONTAL",
+/* 104 */ "wxSL_VERTICAL",
+/* 105 */ "wxSL_AUTOTICKS",
+/* 106 */ "wxSL_LABELS",
+/* 107 */ "wxSL_LEFT",
+/* 108 */ "wxSL_RIGHT",
+/* 109 */ "wxSL_TOP",
+/* 110 */ "wxSL_BOTTOM",
+/* 111 */ "wxSL_SELRANGE",
+/* 112 */ "wxSL_INVERSE",
+/* 113 */ "wxNB_TOP",
+/* 114 */ "wxNB_LEFT",
+/* 115 */ "wxNB_RIGHT",
+/* 116 */ "wxNB_BOTTOM",
+/* 117 */ "wxNB_FIXEDWIDTH",
+/* 118 */ "wxNB_MULTILINE",
+/* 119 */ "wxNB_NOPAGETHEME",
+/* 120 */ "wxNB_FLAT",
+/* 121 */ "wxTE_PROCESS_ENTER",
+/* 122 */ "wxTE_PROCESS_TAB",
+/* 123 */ "wxTE_MULTILINE",
+/* 124 */ "wxTE_PASSWORD",
+/* 125 */ "wxTE_READONLY",
+/* 126 */ "wxTE_RICH",
+/* 127 */ "wxTE_RICH2",
+/* 128 */ "wxTE_AUTO_URL",
+/* 129 */ "wxTE_NOHIDESEL",
+/* 130 */ "wxTE_LEFT",
+/* 131 */ "wxTE_CENTRE",
+/* 132 */ "wxTE_RIGHT",
+/* 133 */ "wxTE_DONTWRAP",
+/* 134 */ "wxTE_CHARWRAP",
+/* 135 */ "wxTE_WORDWRAP",
+/* 136 */ "wxTE_BESTWRAP",
+/* 137 */ "wxTE_CAPITALIZE",
+/* 138 */ "wxHSCROLL",
+/* 139 */ "wxVSCROLL",
+/* 140 */ "wxHSCROLL|wxVSCROLL",
+/* 141 */ "wxBU_LEFT",
+/* 142 */ "wxBU_TOP",
+/* 143 */ "wxBU_RIGHT",
+/* 144 */ "wxBU_BOTTOM",
+/* 145 */ "wxBU_EXACTFIT",
+/* 146 */ "wxNO_BORDER",
+/* 147 */ "wxSP_3D",
+/* 148 */ "wxSP_3DSASH",
+/* 149 */ "wxSP_3DBORDER",
+/* 150 */ "wxSP_BORDER",
+/* 151 */ "wxSP_NOBORDER",
+/* 152 */ "wxSP_NO_XP_THEME",
+/* 153 */ "wxSP_PERMIT_UNSPLIT",
+/* 154 */ "wxSP_LIVE_UPDATE",
+/* 155 */ "wxBU_AUTODRAW",
+/* 156 */ "->SetBitmapDisabled(",
+/* 157 */ "->SetBitmapSelected(",
+/* 158 */ "->SetBitmapFocus(",
+/* 159 */ "->SetBitmapHover(",
+/* 160 */ "wxGA_HORIZONTAL",
+/* 161 */ "wxGA_VERTICAL",
+/* 162 */ "|wxGA_SMOOTH",
+/* 163 */ "wxALIGN_CENTRE",
+/* 164 */ "wxST_NO_AUTORESIZE",
+/* 165 */ "wxLI_HORIZONTAL",
+/* 166 */ "wxLI_VERTICAL",
+/* 167 */ "wxITEM_NORMAL",
+/* 168 */ "wxITEM_SEPARATOR",
+/* 169 */ "wxITEM_CHECK",
+/* 170 */ "wxITEM_RADIO",
+/* 171 */ "wxID_SEPARATOR",
+/* 172 */ "wxTB_HORIZONTAL",
+/* 173 */ "wxTB_VERTICAL",
+/* 174 */ "|wxTB_FLAT",
+/* 175 */ "|wxTB_DOCKABLE",
+/* 176 */ "|wxTB_TEXT",
+/* 177 */ "|wxTB_NOICONS",
+/* 178 */ "|wxTB_NODIVIDER",
+/* 179 */ "|wxTB_NOALIGN",
+/* 180 */ "|wxTB_HORZ_LAYOUT",
+/* 181 */ "|wxTB_NO_TOOTIPS",
+/* 182 */ "|wxTB_BOTTOM",
+/* 183 */ "|wxTB_RIGHT",
+/* 184 */ "->Append(",
+/* 185 */ "->AddTool(\n",
+/* 186 */ "wxNullBitmap",
+/* 187 */ "->AddControl(",
+/* 188 */ "AppendSeparator();\n",
+/* 189 */ "AddSeparator();\n",
+/* 190 */ "SetToolTip(",
+/* 191 */ "->AppendCheckItem(",
+/* 192 */ "->AppendRadioItem(",
+/* 193 */ "->AppendSeparator(",
+/* 194 */ " = ",
+/* 195 */ "SetIcon(",
+/* 196 */ "Add(",
+/* 197 */ "<none>",
+/* 198 */ "->SetTable(",
+/* 199 */ "true",
+/* 200 */ "->CreateGrid(",
+/* 201 */ "->SetColLabelValue(",
+/* 202 */ "->SetRowLabelValue(",
+/* 203 */ "->EnableEditing(false);",
+/* 204 */ "->SetMinSize(wxSize(",
+/* 205 */ "));",
+/* 206 */ "->AddGrowableCol(",
+/* 207 */ "->AddGrowableRow(",
+/* 208 */ "AddButton(\n",
+/* 209 */ ",",
+/* 210 */ "SetLabel(",
+/* 211 */ "SetValidator(",
+/* 212 */ "SetSize(",
+/* 213 */ "SetMinSize(",
+/* 214 */ "->SetCellValue(",
+/* 215 */ "->AutoSize(",
+/* 216 */ "->SetRowLabelSize(wxGRID_AUTOSIZE",
+/* 217 */ "->SetColLabelSize(wxGRID_AUTOSIZE",
+/* 218 */ "if(",
+/* 219 */ ") { ",
+NULL
+};
+
+
+
+/** Names for directions.
+*/
+static char const * const dkct_gui_direction_names[] = {
+/* 0 */ "horizontal",
+/* 1 */ "vertical",
+/* 2 */ "both",
+NULL
+};
+
+
+
+/** Delete grid header data.
+ @param gh Header data to delete.
+*/
+static
+void
+dkct_grid_head_delete(DKCT_GRID_HEAD *gh)
+{
+ if(gh) {
+ dk3_release(gh->text);
+ gh->elno = 0;
+ dk3_delete(gh);
+ }
+}
+
+
+static
+void
+dkct_grid_cell_delete(DKCT_CELL_DATA *cd)
+{
+ if (cd) {
+ dk3_release(cd->text);
+ cd->row = cd->col = 0;
+ dk3_delete(cd);
+ }
+}
+
+
+/** Create new grid header data.
+ @param txt Text for row or column label.
+ @param no Index number of grid row or column.
+ @param psrc Source structure.
+*/
+static
+DKCT_GRID_HEAD *
+dkct_grid_head_new(char const *txt, int no, DKCT_SRC *psrc)
+{
+ DKCT_GRID_HEAD *back = NULL;
+ if(txt) {
+ back = dk3_new_app(DKCT_GRID_HEAD,1,psrc->app);
+ if(back) {
+ back->elno = no;
+ back->text = dk3str_c8_dup_app(txt, psrc->app);
+ if(!(back->text)) {
+ dkct_grid_head_delete(back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+static
+DKCT_CELL_DATA *
+dkct_grid_cell_new(char const *txt, int r, int c, DKCT_SRC *psrc)
+{
+ DKCT_CELL_DATA *back = NULL;
+ if (txt) {
+ back = dk3_new_app(DKCT_CELL_DATA,1,psrc->app);
+ if (back) {
+ back->row = r; back->col = c;
+ back->text = dk3str_c8_dup_app(txt, psrc->app);
+ if (!(back->text)) {
+ dkct_grid_cell_delete(back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+static
+int
+dkct_grid_cell_compare(const void *l, const void *r, int cr)
+{
+ DKCT_CELL_DATA *pl;
+ DKCT_CELL_DATA *pr;
+ int back = 0;
+
+ if (l) {
+ if (r) {
+ pl = (DKCT_CELL_DATA *)l;
+ pr = (DKCT_CELL_DATA *)r;
+ if (pl->row < pr->row) {
+ back = -1;
+ } else {
+ if (pl->row > pr->row) {
+ back = 1;
+ } else {
+ if (pl->col < pr->col) {
+ back = -1;
+ } else {
+ if (pl->col > pr->col) {
+ back = 1;
+ }
+ }
+ }
+ }
+ } else back = 1;
+ } else {
+ if (r) back = -1;
+ }
+ return back;
+}
+
+
+/** Compare two row/column heads.
+ @param l Left object.
+ @param r Right object.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+static
+int
+dkct_grid_head_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ DKCT_GRID_HEAD const *pl;
+ DKCT_GRID_HEAD const *pr;
+ if(l) {
+ if(r) {
+ pl = (DKCT_GRID_HEAD const *)l; pr = (DKCT_GRID_HEAD const *)r;
+ if(pl->elno > pr->elno) {
+ back = 1;
+ } else {
+ if(pl->elno < pr->elno) {
+ back = -1;
+ }
+ }
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ }
+ return back;
+}
+
+
+
+/** Compare two GUI elements.
+ @param l Left element.
+ @param r Right element.
+ @param cr Comparison criteria (0=elem/elem by name, 1=elem/name,
+ 2=elem/elem by number, 3=elem/number).
+ @return Comparison result.
+*/
+static
+int
+dkct_gui_element_compare(void const *l, void const *r, int cr)
+{
+ int back = 0; /* Result. */
+ DKCT_GUI_ELEMENT const *pl; /* Left object pointer. */
+ DKCT_GUI_ELEMENT const *pr; /* Right object pointer. */
+ size_t const *pn; /* Right number. */
+ if(l) {
+ if(r) {
+ pl = (DKCT_GUI_ELEMENT const *)l;
+ pr = (DKCT_GUI_ELEMENT const *)r;
+ pn = (size_t const *)r;
+ switch(cr) {
+ case 3: {
+ if(pl->number > *pn) {
+ back = 1;
+ } else {
+ if(pl->number < *pn) {
+ back = -1;
+ }
+ }
+ } break;
+ case 2: {
+ if(pl->number > pr->number) {
+ back = 1;
+ } else {
+ if(pl->number < pr->number) {
+ back = -1;
+ }
+ }
+ } break;
+ case 1: {
+ if(pl->name) {
+ back = dk3str_c8_cmp(pl->name, (char const *)r);
+ } else { back = -1; }
+ } break;
+ default: {
+ if(pl->name) {
+ if(pr->name) {
+ back = dk3str_c8_cmp(pl->name, pr->name);
+ } else { back = 1; }
+ } else {
+ if(pr->name) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ if(back < -1) { back = -1; }
+ if(back > 1) { back = 1; }
+ return back;
+}
+
+
+
+/** Remove all grid heads (row or column heads) from storage
+ and close storage.
+ @param sHeads Storage containing the heads.
+ @param iHeads Iterator through storage.
+*/
+static
+void
+dkct_remove_grid_heads(dk3_sto_t *sHeads, dk3_sto_it_t *iHeads)
+{
+ DKCT_GRID_HEAD *gh;
+
+ if(sHeads) {
+ if(iHeads) {
+ dk3sto_it_reset(iHeads);
+ while(NULL != (gh = (DKCT_GRID_HEAD *)dk3sto_it_next(iHeads))) {
+ dkct_grid_head_delete(gh);
+ }
+ dk3sto_it_close(iHeads);
+ }
+ dk3sto_close(sHeads);
+ }
+}
+
+
+
+static
+void
+dkct_remove_grid_cell_data(dk3_sto_t *scd, dk3_sto_it_t *icd)
+{
+ DKCT_CELL_DATA *cd;
+ if (scd) {
+ if (icd) {
+ dk3sto_it_reset(icd);
+ while (NULL != (cd = (DKCT_CELL_DATA *)dk3sto_it_next(icd))) {
+ dkct_grid_cell_delete(cd);
+ }
+ dk3sto_it_close(icd);
+ }
+ dk3sto_close(scd);
+ }
+}
+
+
+
+
+/** Remove growable row or column information.
+ @param st Storage containing growable row or column data.
+ @param it Iterator through storage.
+*/
+static
+void
+dkct_remove_grow_row_col(dk3_sto_t *st, dk3_sto_it_t *it)
+{
+ void *ip;
+ if(st) {
+ if(it) {
+ dk3sto_it_reset(it);
+ while(NULL != (ip = dk3sto_it_next(it))) {
+ dk3_delete(ip);
+ }
+ dk3sto_it_close(it);
+ }
+ dk3sto_close(st);
+ }
+}
+
+
+/** Destroy GUI element, release memory.
+ @param elp Element to destroy.
+*/
+static
+void
+dkct_gui_elem_delete(DKCT_GUI_ELEMENT *elp)
+{
+ $? "+ dkct_gui_elem_delete PTR=%d", TR_IPTR(elp)
+ if(elp) {
+ dkct_remove_grid_cell_data(elp->sCellData, elp->iCellData);
+ elp->sCellData = NULL; elp->iCellData = NULL;
+ dkct_remove_grid_heads(elp->sRowHeads, elp->iRowHeads);
+ dkct_remove_grid_heads(elp->sColumnHeads, elp->iColumnHeads);
+ elp->sRowHeads = NULL; elp->iRowHeads = NULL;
+ elp->sColumnHeads = NULL; elp->iColumnHeads = NULL;
+ dkct_remove_grow_row_col(elp->sGrowRow, elp->iGrowRow);
+ dkct_remove_grow_row_col(elp->sGrowCol, elp->iGrowCol);
+ elp->sGrowRow = NULL; elp->iGrowRow = NULL;
+ elp->sGrowCol = NULL; elp->iGrowCol = NULL;
+ if(elp->s_contents) {
+ if(elp->i_contents) {
+ dk3sto_it_close(elp->i_contents);
+ }
+ dk3sto_close(elp->s_contents);
+ } elp->s_contents = NULL; elp->i_contents = NULL;
+ dk3_release(elp->ttflag);
+ dk3_release(elp->gridTable);
+ dk3_release(elp->validator);
+ dk3_release(elp->choices);
+ dk3_release(elp->stbText);
+ dk3_release(elp->bitmapHover);
+ dk3_release(elp->bitmapFocus);
+ dk3_release(elp->bitmapSelected);
+ dk3_release(elp->bitmapDisabled);
+ dk3_release(elp->bitmapVarName);
+ dk3_release(elp->icon);
+ dk3_release(elp->tipText);
+ dk3_release(elp->name);
+ dk3_release(elp->cname);
+ dk3_release(elp->constructor);
+ dk3_release(elp->text);
+ dk3_release(elp->idname);
+ elp->parent = NULL;
+ $? ". object number = %lu", (unsigned long)(elp->number)
+ elp->number = 0;
+ $? ". lndef = %lu", elp->lndef
+ elp->lndef = 0UL;
+ $? ". lndecl = %lu", elp->lndecl
+ elp->lndecl = 0UL;
+ elp->cln = 0;
+ elp->align = 0x00;
+ dk3_delete(elp);
+ } $? "- dkct_gui_elem_delete"
+}
+
+
+
+/** Create GUI element, allocate memory.
+ @param parent Parent GUI element.
+ @param name New GUI elements name.
+ @param number Number of new element.
+ @param psrc Source structure, used for diagnostics.
+ @param gui GUI description.
+ @return Pointer to new element on success, NULL on error.
+*/
+static
+DKCT_GUI_ELEMENT *
+dkct_gui_elem_new(
+ DKCT_GUI_ELEMENT *parent,
+ char const *name,
+ size_t number,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+
+)
+{
+ DKCT_GUI_ELEMENT *back = NULL;
+ int ok = 0; /* Flag: OK so far. */
+ $? "+ dkct_gui_elem_new PTR=%d \"%!8s\" %lu", TR_IPTR(parent), TR_8STR(name), (unsigned long)number
+ back = dk3_new_app(DKCT_GUI_ELEMENT,1,psrc->app);
+ if(back) {
+ /*
+ Initialize empty object.
+ */
+ back->name = NULL;
+ back->cname = NULL;
+ back->idname = NULL;
+ back->text = NULL;
+ back->constructor = NULL;
+ back->tipText = NULL;
+ back->icon = NULL;
+ back->bitmapVarName = NULL;
+ back->bitmapDisabled = NULL;
+ back->bitmapSelected = NULL;
+ back->bitmapFocus = NULL;
+ back->bitmapHover = NULL;
+ back->stbText = NULL;
+ back->choices = NULL;
+ back->validator = NULL;
+ back->gridTable = NULL;
+ back->ttflag = NULL;
+ back->parent = NULL;
+ back->number = 0;
+ back->align = 0x00;
+ if(gui) { back->align = gui->align; }
+ back->cln = -1;
+ back->menubar = NULL;
+ back->toolbar = NULL;
+ back->passno = 0;
+ back->posx = 0;
+ back->posy = 0;
+ back->spanx = 0;
+ back->spany = 0;
+ back->gridcolumns = 1;
+ back->gridrows = 1;
+ back->gridgapx = -1;
+ back->gridgapy = -1;
+ back->sash = 0;
+ back->minPaneSize = 0;
+ back->nChoices = 0;
+ back->maxRowsCols = 1;
+ back->rbDirection = DKCT_GUI_RB_DIR_COLUMNS;
+ back->startGroup = 0x00;
+ back->curx = 0;
+ back->cury = 0;
+ back->sizex = 0;
+ back->sizey = 0;
+ back->sizemx = 0;
+ back->sizemy = 0;
+ back->stbsz = 0;
+ back->s_contents = NULL;
+ back->i_contents = NULL;
+ back->sRowHeads = NULL;
+ back->iRowHeads = NULL;
+ back->sColumnHeads = NULL;
+ back->iColumnHeads = NULL;
+ back->sCellData = NULL;
+ back->iCellData = NULL;
+ back->sGrowRow = NULL;
+ back->iGrowRow = NULL;
+ back->sGrowCol = NULL;
+ back->iGrowCol = NULL;
+ back->pseudoobj = 0;
+ back->lndef = 0UL;
+ back->lndecl = 0UL;
+ if(psrc) { back->lndecl = psrc->lineno; }
+ back->border = -1;
+ back->borderPos = 0x00;
+ back->expandFlag = 0x00;
+ back->nStates = 0x02;
+ back->state = 0x00;
+ back->selStyle = DKCT_GUI_SELECTION_STYLE_SINGLE;
+ back->prost = DKCT_GUI_PROCESSING_STATE_START;
+ back->proportion = 0;
+ back->direction = DKCT_GUI_DIRECTION_HORIZONTAL;
+ back->spinMin = 0;
+ back->spinMax = 100;
+ back->spinVal = 0;
+ back->nRows = 0;
+ back->nColumns = 0;
+ back->nRowHeads = 0;
+ back->nColumnHeads = 0;
+ back->spinWrap = 0x00;
+ back->useKeys = 0x00;
+ back->sliderStyle = 0x00;
+ back->buttonStyle = 0x00;
+ back->bitmapbStyle = DKCT_GUI_BBUTTON_AUTODRAW;
+ back->gaugeStyle = 0x00;
+ back->menuItemStyle = 0x00;
+ back->tableOwner = 0x00;
+ back->notebookStyle = 0U;
+ back->splitterStyle = DKCT_GUI_SPLITTERW_3D;
+ back->toolbarStyle = DKCT_GUI_TOOLBAR_FLAT;
+ back->gridStyle = 0U;
+ back->textStyle = 0UL;
+ back->compConst = 0x00;
+ /*
+ Allocate memory.
+ */
+ back->s_contents = dk3sto_open_app(psrc->app);
+ if(back->s_contents) {
+ /* Sorting by number needed. */
+ dk3sto_set_comp(back->s_contents, dkct_gui_element_compare, 2);
+ back->i_contents = dk3sto_it_open(back->s_contents);
+ if(back->i_contents) {
+ ok = 1;
+ }
+ }
+ /*
+ Use arguments.
+ */
+ back->parent = parent;
+ if(name) {
+ back->name = dk3str_c8_dup_app(name, psrc->app);
+ if(!(back->name)) { ok = 0; }
+ }
+ back->number = number;
+ if(!(ok)) { $? ". must delete"
+ dkct_gui_elem_delete(back); back = NULL;
+ }
+ } $? "- dkct_gui_elem_new PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/** Create next object in GUI description.
+ @param gui GUI description.
+ @param name New object name.
+ @return Pointer to new object on success, NULL on error.
+*/
+static
+DKCT_GUI_ELEMENT *
+dkct_gui_elem_next(DKCT_GUI *gui, char const *name)
+{
+ DKCT_GUI_ELEMENT *back = NULL;
+
+ if(name) {
+ if(*name != '$') {
+ back = (DKCT_GUI_ELEMENT *)dk3sto_it_find_like(
+ gui->i_el_by_name, (void *)name, 1
+ );
+ }
+ }
+ if(back) {
+ /* Warning: Object already declared! 95/96 */
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_WARNING, 95, 96, name);
+ } else {
+ back = dkct_gui_elem_new(gui->c_el, name, gui->no, gui->psrc, gui);
+ if(back) {
+ if(dk3sto_add(gui->s_el_by_name, (void *)back)) {
+ gui->no += 1;
+ if(!dk3sto_add(gui->s_el_by_num, (void *)back)) {
+ back = NULL;
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ }
+ } else {
+ dkct_gui_elem_delete(back); back = NULL;
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory! */
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory! */
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ }
+ return back;
+}
+
+
+
+DKCT_GUI *
+dkct_gui_new(DKCT_SRC *psrc)
+{
+ DKCT_GUI *back = NULL;
+ int ok = 0; /* FLag: Success. */
+ DKCT_GUI_ELEMENT *el; /* New element. */
+ $? "+ dkct_gui_new"
+ back = dk3_new_app(DKCT_GUI,1,psrc->app);
+ if(back) {
+ /*
+ Initialize.
+ */
+ back->psrc = psrc;
+ back->c_el = NULL;
+ back->r_el = NULL;
+ back->s_el_by_name = NULL; back->i_el_by_name = NULL;
+ back->s_el_by_num = NULL; back->i_el_by_num = NULL;
+ back->ttflag = NULL;
+ back->no = 0;
+ back->align = 0x00;
+ /*
+ Allocate storages.
+ */
+ back->s_el_by_name = dk3sto_open_app(psrc->app);
+ if(back->s_el_by_name) {
+ dk3sto_set_comp(back->s_el_by_name, dkct_gui_element_compare, 0);
+ back->i_el_by_name = dk3sto_it_open(back->s_el_by_name);
+ if(back->i_el_by_name) {
+ back->s_el_by_num = dk3sto_open_app(psrc->app);
+ if(back->s_el_by_num) {
+ dk3sto_set_comp(back->s_el_by_num, dkct_gui_element_compare, 2);
+ back->i_el_by_num = dk3sto_it_open(back->s_el_by_num);
+ if(back->i_el_by_num) {
+ el = dkct_gui_elem_new(NULL, NULL, 0, psrc, back);
+ if(el) {
+ back->no = 1;
+ if(dk3sto_add(back->s_el_by_name, el)) {
+ if(dk3sto_add(back->s_el_by_num, el)) {
+ ok = 1;
+ back->c_el = el;
+ back->r_el = el;
+ el->cln = 0;
+ }
+ } else {
+ dkct_gui_elem_delete(el); el = NULL;
+ }
+ }
+ }
+ }
+ }
+ }
+ if(!(ok)) {
+ dkct_gui_delete(back); back = NULL;
+ }
+ } $? "- dkct_gui_new PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+void
+dkct_gui_delete(DKCT_GUI *pg)
+{
+ DKCT_GUI_ELEMENT *el; /* Current element to process. */
+ $? "+ dkct_gui_delete"
+ if(pg) {
+ pg->psrc = NULL;
+ pg->c_el = NULL;
+ pg->no = 0;
+ if(pg->s_el_by_num) {
+ if(pg->i_el_by_num) {
+ dk3sto_it_close(pg->i_el_by_num);
+ }
+ dk3sto_close(pg->s_el_by_num);
+ } pg->s_el_by_num = NULL; pg->i_el_by_num = NULL;
+ if(pg->s_el_by_name) {
+ if(pg->i_el_by_name) {
+ dk3sto_it_reset(pg->i_el_by_name);
+ while((el = (DKCT_GUI_ELEMENT *)dk3sto_it_next(pg->i_el_by_name))
+ != NULL)
+ {
+ dkct_gui_elem_delete(el);
+ }
+ dk3sto_it_close(pg->i_el_by_name);
+ }
+ dk3sto_close(pg->s_el_by_name);
+ } pg->s_el_by_name = NULL; pg->i_el_by_name = NULL;
+ if (NULL != pg->ttflag) {
+ dk3_delete(pg->ttflag);
+ }
+ pg->ttflag = NULL;
+ dk3_delete(pg);
+ } $? "- dkct_gui_delete"
+}
+
+
+
+/** Class-depending attribute setup.
+ @param el New object to set up.
+*/
+static
+void
+dkct_gui_initialize_object_for_class(DKCT_GUI_ELEMENT *el)
+{
+ switch(el->cln) {
+ case 13: {
+ el->direction = DKCT_GUI_DIRECTION_BOTH;
+ } break;
+ }
+}
+
+
+
+/** Start processing of a new object.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_start_new_object_definition(DKCT_GUI *gui, char *il)
+{
+ int back = 0;
+ char *p2 = NULL; /* Closing square bracket. */
+ DKCT_GUI_ELEMENT *elp; /* Element to process. */
+ $? "+ dkct_gui_start_new_object_definition \"%!8s\"", TR_8STR(il)
+ gui->c_el = NULL;
+ p2 = dk3str_c8_rchr(il, ']');
+ if(p2) {
+ *p2 = '\0';
+ p2 = dk3str_c8_next(il, NULL);
+ if(p2) {
+ elp = (DKCT_GUI_ELEMENT *)dk3sto_it_find_like(gui->i_el_by_name, p2, 1);
+ if(!(elp)) {
+ /* Warning: Undefined element ! */
+ elp = dkct_gui_elem_new(NULL, p2, gui->no, gui->psrc, gui);
+ if(elp) {
+ if(dk3sto_add(gui->s_el_by_name, (void *)elp)) {
+ gui->no += 1;
+ if(!dk3sto_add(gui->s_el_by_num, (void *)elp)) {
+ elp = NULL;
+ }
+ } else {
+ dkct_gui_elem_delete(elp); elp = NULL;
+ }
+ }
+ }
+ if(elp) {
+ if(elp->cname) {
+ /* ERROR: Class name already defined! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 45);
+ } else {
+ elp->lndef = (gui->psrc)->lineno;
+ if(elp->lndecl == 0UL) { elp->lndecl = (gui->psrc)->lineno; }
+ elp->cname = dk3str_c8_dup_app(il, (gui->psrc)->app);
+ elp->cln = dk3str_c8_array_index(dkct_gui_class_names, il, 1);
+ dkct_gui_initialize_object_for_class(elp);
+ if(elp->cname) {
+ back = 1;
+ gui->c_el = elp;
+ } else {
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 57);
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ /* ERROR: Syntax (missing object name) */#
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 58);
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ /* ERROR: Syntax (missing ']') */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 59);
+ }
+ $? "- dkct_gui_start_new_object_definition %d", back
+ return back;
+}
+
+
+
+/** Set menu bar.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_menu_bar(DKCT_GUI *gui, char *il)
+{
+ int back = 0;
+ DKCT_GUI_ELEMENT *elp; /* Element to modify. */
+ $? "+ dkct_gui_set_menu_bar \"%!8s\"", TR_8STR(il)
+ if(gui->c_el) {
+ if(((gui->c_el)->number != 0) && (!((gui->c_el)->parent))) {
+ $? "! not applicable"
+ /* Warning: Attribute applicable to root element only! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 55);
+ }
+ if(!((gui->c_el)->menubar)) {
+ elp = (DKCT_GUI_ELEMENT *)dk3sto_it_find_like(gui->i_el_by_name, il, 1);
+ if(!(elp)) {
+ elp = dkct_gui_elem_next(gui, il);
+ }
+ if(elp) {
+ (gui->c_el)->menubar = (void *)elp;
+ back = 1;
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 57);
+ }
+ } else {
+ DKCT_GUI_ELEMENT *e;
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ e = (DKCT_GUI_ELEMENT *)((gui->c_el)->menubar);
+ if(e->name) {
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 74, 75, e->name);
+ }
+ }
+ } $? "- dkct_gui_set_menu_bar %d", back
+ return back;
+}
+
+
+
+/** Set tool bar.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_tool_bar(DKCT_GUI *gui, char *il)
+{
+ int back = 0;
+ DKCT_GUI_ELEMENT *elp; /* Toolbar object. */
+ $? "+ dkct_gui_set_tool_bar \"%!8s\"", TR_8STR(il)
+ if(gui->c_el) {
+ if(((gui->c_el)->number != 0) && (!((gui->c_el)->parent))) {
+ $? "! not applicable"
+ /* Warning: Attribute applicable to root object only! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 55);
+ }
+ if(!((gui->c_el)->toolbar)) {
+ elp = (DKCT_GUI_ELEMENT *)dk3sto_it_find_like(gui->i_el_by_name, il, 1);
+ if(!(elp)) {
+ elp = dkct_gui_elem_next(gui, il);
+ }
+ if(elp) {
+ (gui->c_el)->toolbar = (void *)elp;
+ back = 1;
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 57);
+ }
+ } else {
+ DKCT_GUI_ELEMENT *e;
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ /* ERROR: Redefinition */
+ e = (DKCT_GUI_ELEMENT *)((gui->c_el)->toolbar);
+ if(e->name) {
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 74, 75, e->name);
+ }
+ }
+ }
+ $? "- dkct_gui_set_tool_bar %d", back
+ return back;
+}
+
+
+
+/** Set status bar.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_status_bar(DKCT_GUI *gui, char *il)
+{
+ int back = 0;
+ int num = 0; /* Number of status bar labels. */
+ char *p1; /* Number of status bar labels. */
+ char *p2; /* Initial status text. */
+ $? "+ dkct_gui_set_status_bar"
+ if(gui->c_el) {
+ if(((gui->c_el)->number != 0) && (!((gui->c_el)->parent))) {
+ $? "! not applicable"
+ /* Warning: Attribute applicable to root element only! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 55);
+ }
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ if(sscanf(p1, "%d", &num) == 1) {
+ if(num >= 0) {
+ back = 1;
+ (gui->c_el)->stbsz = num;
+ if(p2) {
+ back = 0;
+ dk3_release((gui->c_el)->stbText);
+ (gui->c_el)->stbText = dk3str_c8_dup_app(p2, (gui->psrc)->app);
+ if((gui->c_el)->stbText) {
+ back = 1;
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 57);
+ }
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ /* ERROR: Out of range! */
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 82, 83, p1);
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ /* ERROR: Not a number! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 31);
+ }
+ }
+ }
+ $? "- dkct_gui_set_status_bar %d", back
+ return back;
+}
+
+
+
+/** Set text for Window ID.
+ @param gui GUI description.
+ @param il Value part of input line.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_id(DKCT_GUI *gui, char *il)
+{
+ int back = 0;
+ char *p1; /* Start of text. */
+ $? "+ dkct_gui_set_id"
+ if(gui->c_el) {
+ switch((gui->c_el)->cln) {
+ case 5: case 6: case 7: case 8: case 9: case 10: {
+ $? "! not applicable"
+ /* Warning: Attribute not applicable to class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ if(!((gui->c_el)->idname)) {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ dk3str_c8_delnl(il);
+ (gui->c_el)->idname = dk3str_c8_dup_app(p1, (gui->psrc)->app);
+ if((gui->c_el)->idname) {
+ back = 1;
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ /* ERROR: Syntax, empty ID */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 71);
+ }
+ } else {
+ /* ERROR: Syntax, ID already defined! */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 60);
+ }
+ }
+ $? "- dkct_gui_set_id %d", back
+ return back;
+}
+
+
+
+/** Set constructor arguments.
+ @param gui GUI description.
+ @param il Value part of input line.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_constructor(DKCT_GUI *gui, char *il)
+{
+ int back = 0;
+ char *p1; /* Start of text. */
+ $? "+ dkct_gui_set_constructor"
+ if(gui->c_el) {
+ if((gui->c_el)->cln >= 0) { $? "! not applicable"
+ /* Warning: Constructor attribute not recommended for class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ }
+ if(!((gui->c_el)->constructor)) {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ dk3str_c8_delnl(il);
+ (gui->c_el)->constructor = dk3str_c8_dup_app(p1, (gui->psrc)->app);
+ if((gui->c_el)->constructor) {
+ back = 1;
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 57);
+ }
+ } else {
+ /* ERROR: Syntax, empty ID */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 61);
+ }
+ } else {
+ /* ERROR: Syntax, ID already defined! */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 60);
+ }
+ } $? "- dkct_gui_set_constructor"
+ return back;
+}
+
+
+
+/** Set border.
+ @param gui GUI description.
+ @param il Value part of input line.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_border(DKCT_GUI *gui, char *il)
+{
+ int back = 0;
+ int i = 0; /* Number of pixels for border. */
+ char *p1 = NULL; /* Current string to process. */
+ char *p2 = NULL; /* Next string to process. */
+ $? "+ dkct_gui_set_border"
+ if(gui->c_el) {
+ switch((gui->c_el)->cln) {
+ case 0: case 1: case 2: case 3: case 4: { $? "! not applicable"
+ /* Warning: Attribute not applicable to class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ if(sscanf(p1, "%d", &i) == 1) {
+ if(i >= 0) {
+ (gui->c_el)->border = i;
+ back = 1;
+ if(p2) {
+ (gui->c_el)->borderPos = DKCT_GUI_BORDER_POSITION_NONE;
+ while(p2) {
+ p1 = dk3str_c8_next(p2, NULL);
+ i = dk3str_c8_array_index(dkct_gui_border_position_names, p2, 0);
+ switch(i) {
+ case 0: {
+ (gui->c_el)->borderPos |= DKCT_GUI_BORDER_POSITION_ALL;
+ } break;
+ case 1: {
+ (gui->c_el)->borderPos |= DKCT_GUI_BORDER_POSITION_TOP;
+ } break;
+ case 2: {
+ (gui->c_el)->borderPos |= DKCT_GUI_BORDER_POSITION_LEFT;
+ } break;
+ case 3: {
+ (gui->c_el)->borderPos |= DKCT_GUI_BORDER_POSITION_RIGHT;
+ } break;
+ case 4: {
+ (gui->c_el)->borderPos |= DKCT_GUI_BORDER_POSITION_BOTTOM;
+ } break;
+ default: {
+ back = 0;
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p2);
+ } break;
+ }
+ p2 = p1;
+ }
+ } else {
+ (gui->c_el)->borderPos = DKCT_GUI_BORDER_POSITION_ALL;
+ }
+ }
+ }
+ }
+ }
+ $? "- dkct_gui_set_border %d", back
+ return back;
+}
+
+
+
+/** Set proportion to grow the object.
+ @param gui GUI description.
+ @param il Value part of input line.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_proportion(DKCT_GUI *gui, char *il)
+{
+ int back = 0;
+ int i; /* Proportion value. */
+ $? "+ dkct_gui_set_proportion"
+ if(gui->c_el) {
+ switch((gui->c_el)->cln) {
+ case 0: case 1: case 2: case 3: { $? "! not applicable"
+ /* Warning: Attribute not applicable to class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ if(sscanf(il, "%d", &i) == 1) {
+ if(i >= 0) {
+ back = 1;
+ (gui->c_el)->proportion = i;
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_WARNING, 76, 77, il);
+ }
+ }
+ $? "- dkct_gui_set_proportion %d", back
+ return back;
+}
+
+
+
+/** Set status text.
+ @param gui GUI description.
+ @param il Value part of input line.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_status_text(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Start of text. */
+ int back = 0;
+ $? "+ dkct_gui_set_status_text"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ {
+ } break;
+ default: { $? "! not applicable"
+ /* Warning: Attribute not applicable to class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ if(el->stbText) {
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 74, 75, el->stbText);
+ }
+ dk3_release(el->stbText);
+ el->stbText = dk3str_c8_dup_app(p1, (gui->psrc)->app);
+ if(el->stbText) {
+ back = 1;
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 57);
+ }
+ }
+ }
+ }
+ $? "- dkct_gui_set_status_text %d", back
+ return back;
+}
+
+
+
+/** Set expand flag.
+ @param gui GUI description.
+ @param il Value part of input line.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_expand(DKCT_GUI *gui, char *il)
+{
+ int back = 0;
+ char *p1; /* Start of text. */
+ $? "+ dkct_gui_set_expand"
+ if(gui->c_el) {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ (void)dk3str_c8_next(p1, NULL);
+ if(dk3str_c8_is_bool(p1)) {
+ back = 1;
+ if(dk3str_c8_is_on(p1)) {
+ (gui->c_el)->expandFlag = 0x01;
+ } else {
+ (gui->c_el)->expandFlag = 0x00;
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ /* ERROR: Not a boolean! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 70);
+ }
+ }
+ } $? "- dkct_gui_set_expand %d", back
+ return back;
+}
+
+
+/** Set text for label or button.
+ @param gui GUI description.
+ @param il Value part of input line.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_text(DKCT_GUI *gui, char *il)
+{
+ int back = 0;
+ char *p1; /* Start of text. */
+ $? "+ dkct_gui_set_text"
+ if(gui->c_el) {
+ switch((gui->c_el)->cln) {
+ case -1:
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 9:
+ case 15:
+ case 16:
+ case 19:
+ case 20:
+ case 21:
+ case 22:
+ case 23:
+ case 28:
+ case 29:
+ case 31:
+ case 36:
+ case 37:
+ case 40:
+ {
+ } break;
+ default: { $? "! not applicable"
+ /* Warning: Attribute not applicable for class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ if(!((gui->c_el)->text)) {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ dk3str_c8_delnl(il);
+ (gui->c_el)->text = dk3str_c8_dup_app(p1, (gui->psrc)->app);
+ if((gui->c_el)->text) {
+ back = 1;
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 57);
+ }
+ } else {
+ /* ERROR: Syntax, empty ID */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 71);
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ }
+ } else {
+ /* ERROR: Syntax, ID already defined! */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 60);
+ }
+ } $? "- dkct_gui_set_text %d", back
+ return back;
+}
+
+
+
+/** Set text for label or button.
+ @param gui GUI description.
+ @param il Value part of input line.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_tip_text(DKCT_GUI *gui, char *il)
+{
+ int back = 0;
+ char *p1; /* Start of text. */
+ $? "+ dkct_gui_set_tip_text"
+ if(gui->c_el) {
+ switch((gui->c_el)->cln) {
+ case -1:
+ case 15:
+ case 16:
+ case 17:
+ case 18:
+ case 19:
+ case 20:
+ case 21:
+ case 22:
+ case 23:
+ case 25:
+ case 26:
+ case 27:
+ case 28:
+ case 29:
+ case 30:
+ case 36:
+ case 37: /* wxMenuItem */
+ case 39:
+ case 40:
+ {
+ } break;
+ default: { $? "! not applicable"
+ /* Warning: Attribute not applicable to class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ if(!((gui->c_el)->tipText)) {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ dk3str_c8_delnl(il);
+ (gui->c_el)->tipText = dk3str_c8_dup_app(p1, (gui->psrc)->app);
+ if((gui->c_el)->tipText) {
+ back = 1;
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 57);
+ }
+ } else {
+ /* ERROR: Syntax, empty ID */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 71);
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ }
+ } else {
+ /* ERROR: Syntax, tip text already defined! */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 62);
+ }
+ } $? "- dkct_gui_set_tip_text %d", back
+ return back;
+}
+
+
+
+/** Set root object type (frame or dialog).
+ @param gui GUI structure.
+ @param il Value part of input line.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_type(DKCT_GUI *gui, char *il)
+{
+ int back = 0;
+ $? "+ dkct_gui_set_type"
+ if(gui->c_el) {
+ if(((gui->c_el)->number == 0) && (!((gui->c_el)->parent))) {
+ switch(dk3str_c8_array_index(dkct_gui_base_type_names, il, 0)) {
+ case 0: {
+ (gui->c_el)->cln = 0;
+ back = 1;
+ } break;
+ case 1: {
+ (gui->c_el)->cln = 1;
+ back = 1;
+ } break;
+ default: {
+ /* ERROR: Illegal type */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 63);
+ } break;
+ }
+ } else { $? "! not applicable"
+ /* ERROR: Attribute applicable to root element only! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 55);
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ }
+ } $? "- dkct_gui_set_type %d", back
+ return back;
+}
+
+
+
+/** Read placement int value from text.
+ The text may be an absolute or relative number or a dot.
+ @param dest Pointer to destination variable.
+ @param gui GUI structure.
+ @param tptr Text to process.
+ @param oldval Previous value.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_read_number_from_string(
+ int *dest,
+ DKCT_GUI *gui,
+ char *tptr,
+ int oldval
+)
+{
+ int back = 0;
+ int i; /* Number read. */
+
+ if(dk3str_c8_cmp(tptr, dkct_gui_out_kw[15]) == 0) {
+ *dest = oldval; back = 1;
+ } else {
+ if(*tptr == '+') {
+ if(sscanf(&(tptr[1]), dkct_gui_out_kw[16], &i) == 1) {
+ *dest = oldval + i; back = 1;
+ }
+ } else {
+ if(*tptr == '-') {
+ if(sscanf(&(tptr[1]), dkct_gui_out_kw[16], &i) == 1) {
+ *dest = oldval - i; back = 1;
+ }
+ } else {
+ if(sscanf(tptr, dkct_gui_out_kw[16], &i) == 1) {
+ *dest = i; back = 1;
+ }
+ }
+ }
+ }
+ if(!(back)) {
+ /* ERROR: Syntax: Not a numeric value! */
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 64, 65, tptr);
+ }
+ return back;
+}
+
+
+
+/** Apply align specified as text to an object.
+ @param gui GUI description.
+ @param oa Alignment as found so far.
+ @param ptext Text to process.
+ @return Updated alignment.
+*/
+static
+unsigned char
+dkct_gui_apply_align(DKCT_GUI *gui, unsigned char oa, char *ptext)
+{
+ unsigned char back;
+ back = oa;
+
+ switch(dk3str_c8_array_index(dkct_gui_align_names, ptext, 0)) {
+ case 0: {
+ back = (back & (~(DKCT_GUI_ALIGN_H_MASK))) | DKCT_GUI_ALIGN_H_LEFT;
+ } break;
+ case 1: {
+ back = (back & (~(DKCT_GUI_ALIGN_H_MASK))) | DKCT_GUI_ALIGN_H_RIGHT;
+ } break;
+ case 2: {
+ back = (back & (~(DKCT_GUI_ALIGN_V_MASK))) | DKCT_GUI_ALIGN_V_TOP;
+ } break;
+ case 3: {
+ back = (back & (~(DKCT_GUI_ALIGN_V_MASK))) | DKCT_GUI_ALIGN_V_BOTTOM;
+ } break;
+ case 4: {
+ back = DKCT_GUI_ALIGN_H_CENTER | DKCT_GUI_ALIGN_V_CENTER;
+ } break;
+ case 5: {
+ back = (back & (~(DKCT_GUI_ALIGN_H_MASK))) | DKCT_GUI_ALIGN_H_CENTER;
+ } break;
+ case 6: {
+ back = (back & (~(DKCT_GUI_ALIGN_V_MASK))) | DKCT_GUI_ALIGN_V_CENTER;
+ } break;
+ default: {
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, ptext);
+ /* ERROR: Illegal keyword */
+ } break;
+ }
+ return back;
+}
+
+
+
+/** Register additional placement information.
+ Process value part of "contents = element 0 0 1 1 left top" line.
+ @param gui GUI structure.
+ @param parent Parent element.
+ @param gel Element to add.
+ @param p Texts, starting with element name.
+ @param szp Number of elements used in \a p.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_add_additional_placement_info(
+ DKCT_GUI *gui,
+ DKCT_GUI_ELEMENT *parent,
+ DKCT_GUI_ELEMENT *gel,
+ char **p,
+ size_t szp
+)
+{
+ int back = 1;
+ int x; /* Start column. */
+ int y; /* Start row. */
+ int w; /* Number of columns. */
+ int h; /* Number of rows. */
+ $? "+ dkct_gui_add_additional_placement_info"
+ switch((gui->c_el)->cln) {
+ case 5: case 9: {
+ /*
+ Box sizer / static box sizer.
+ contents = element [align]
+ */
+ if(szp > 1) {
+ gel->align = 0x00;
+ gel->align = dkct_gui_apply_align(gui, gel->align, p[1]);
+ if(szp > 2) {
+ gel->align = dkct_gui_apply_align(gui, gel->align, p[2]);
+ }
+ }
+ } break;
+ case 6: case 8: {
+ /*
+ Flex grid sizer.
+ Grid sizer.
+ contents = element x y [align [align]]
+ */
+ back = 0;
+ if(szp >= 3) {
+ if(dkct_gui_read_number_from_string(&x, gui, p[1], parent->curx)) {
+ if(dkct_gui_read_number_from_string(&y, gui, p[2], parent->cury)) {
+ gel->posx = x; gel->posy = y;
+ parent->curx = x; parent->cury = y;
+ back = 1;
+ if(szp > 3) {
+ gel->align = 0x00;
+ gel->align = dkct_gui_apply_align(gui, gel->align, p[3]);
+ if(szp > 4) {
+ gel->align = dkct_gui_apply_align(gui, gel->align, p[4]);
+ }
+ }
+ }
+ }
+ }
+ } break;
+ case 7: {
+ /*
+ Gridbag sizer.
+ contents = element x y w h [align [align]]
+ */
+ back = 0;
+ if(szp >= 5) {
+ if(dkct_gui_read_number_from_string(&y, gui, p[1], parent->cury)) {
+ if(dkct_gui_read_number_from_string(&x, gui, p[2], parent->curx)) {
+ gel->posx = x; gel->posy = y; parent->curx = x; parent->cury = y;
+ if(sscanf(p[3], dkct_gui_out_kw[16], &h) == 1) {
+ if(sscanf(p[4], dkct_gui_out_kw[16], &w) == 1) {
+ gel->spanx = w; gel->spany = h; back = 1;
+ if(szp > 5) {
+ gel->align = 0x00;
+ gel->align = dkct_gui_apply_align(gui, gel->align, p[5]);
+ if(szp > 6) {
+ gel->align = dkct_gui_apply_align(gui, gel->align, p[6]);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } break;
+ case 10: {
+ /*
+ Standard dialog button sizer.
+ Ignore anything but the element name.
+ contents = element
+ */
+ } break;
+ default: {
+ /*
+ We don't know whether or not we are a sizer or anything
+ else. So we ignore anything but the element name.
+ */
+ } break;
+ } $? "- dkct_gui_add_additional_placement_info %d", back
+ return back;
+}
+
+
+
+/** Add one contents line.
+ @param gui GUI structure.
+ @param il Value part of input line.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_add_contents(DKCT_GUI *gui, char *il)
+{
+ int back = 0;
+ char *p[16]; /* Strings in text. */
+ char *p1; /* Pseudo-object start. */
+ char *p2; /* Pseudo-object args start. */
+ char *p3; /* Pseudo-object next arg. */
+ DKCT_GUI_ELEMENT *gel; /* Element to add. */
+ size_t szp; /* Number of strings in text. */
+ int pso; /* Pseudo object value. */
+ int i;
+ $? "+ dkct_gui_add_contents \"%!8s\"", TR_8STR(il)
+ if(gui->c_el) {
+ switch((gui->c_el)->cln) {
+ case 0: /* wxFrame */
+ case 1: /* wxDiaglog */
+ case 2: /* wxMDIParentFrame */
+ case 3: /* wxMDIChildFrame */
+ case 5: /* wxBoxSizer */
+ case 6: /* wxFlexGridSizer */
+ case 7: /* wxGridBagSizer */
+ case 8: /* wxGridSizer */
+ case 9: /* wxStaticBoxSizer */
+ case 10: /* wxStdDialogButtonSizer */
+ case 11: /* wxPanel */
+ case 12: /* wxNotebook */
+ case 13: /* wxScrolledWindow */
+ case 14: /* wxSplitterWindow */
+ case 35: /* wxMenuBar */
+ case 36: /* wxMenu */
+ case 38: /* wxToolBar */
+ case 39: /* wxStatusBar */
+ {
+ } break;
+ default: { $? "! not applicable"
+ /* Warning: Attribute not applicable to this class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ for(szp = 0; szp < 16; szp++) { p[szp] = NULL; }
+ szp = dk3str_c8_explode(p, 15, il, NULL);
+ if(szp > 0) { $? ". have text"
+ gel = dkct_gui_elem_next(gui, p[0]);
+ if(gel) { $? ". element created"
+ if(dk3sto_add((gui->c_el)->s_contents, gel)) { $? ". el added"
+ if(*(p[0]) == '$') { $? ". pseudo object"
+ p1 = p[0]; p2 = NULL; p3 = NULL;
+ p2 = dk3str_c8_chr(p1, '(');
+ if(p2) { $? ". p2 ok"
+ *(p2++) = '\0';
+ p3 = dk3str_c8_rchr(p2, ')');
+ if(p3) { $? ". p3 ok"
+ *p3 = '\0';
+ }
+ }
+ pso = dk3str_c8_array_index(dkct_gui_pseudo_object_names, p[0], 0);
+ if(pso >= 0) {
+ gel->pseudoobj = 1 + pso;
+ back = 1;
+ }
+ if(back) {
+ switch(pso) {
+ case 0: case 1: {
+ if(pso == 0) { $? ". stretcher"
+ gel->proportion = 1;
+#if 0
+ /*
+ 2011-07-30: No wxGROW for stretch/spacer.
+ */
+ gel->expandFlag = 0x01;
+#endif
+ }
+ if(p2) { $? ". have data"
+ p3 = dk3str_c8_chr(p2, ',');
+ if(p3) *(p3++) = '\0';
+ if(sscanf(p2, "%d", &i) == 1) { $? ". width found"
+ gel->sizex = i;
+ gel->sizey = i;
+ } else {
+ /* ERROR: Not an integer! */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 64, 65, p2);
+ back = 0;
+ }
+ if(p3) { $? ". height text"
+ p2 = dk3str_c8_chr(p3, ',');
+ if(p2) *(p2++) = '\0';
+ if(sscanf(p3, "%d", &i) == 1) { $? ". height found"
+ gel->sizey = i;
+ } else {
+ /* ERROR: Not an integer! */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 64, 65, p2);
+ back = 0;
+ }
+ if(p2) { $? ". grow text"
+ if(sscanf(p2, "%d", &i) == 1) { $? ". grow found"
+ gel->proportion = i;
+ } else {
+ /* ERROR: Not an integer! */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 64, 65, p2);
+ back = 0;
+ }
+ }
+ }
+ }
+ } break;
+ }
+ }
+ if(back) {
+ back = dkct_gui_add_additional_placement_info(
+ gui, gui->c_el, gel, p, szp
+ );
+ }
+ } else { $? ". normal object"
+ back = dkct_gui_add_additional_placement_info(
+ gui, gui->c_el, gel, p, szp
+ );
+ }
+ } else { $? "! memory"
+ /* ERROR: Memory */
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 57);
+ }
+ } else { $? "! memory"
+ /* ERROR: Memory */
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 57);
+ }
+ } else { $? "! empty line"
+ /* ERROR: Empty line */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 66);
+ }
+ } else { $? "! no current element"
+ } $? "- dkct_gui_add_contents %d", back
+ return back;
+}
+
+
+
+/** Set up grid for current GUI object.
+ @param gui GUI description.
+ @param pv Text describing the grid.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_grid(DKCT_GUI *gui, char *pv)
+{
+ int back = 0;
+ char *p1 = NULL; /* First text string. */
+ char *p2 = NULL; /* Second text string. */
+ char *p3 = NULL; /* Third text string. */
+ char *p4 = NULL; /* Fourth text string. */
+ DKCT_GUI_ELEMENT *co; /* Current object to modify. */
+ int v = 0; /* Number read from string. */
+ int i1 = 0; /* First int value. */
+ int i2 = 0; /* Second int value. */
+ int i3 = 0; /* Third int value. */
+ int i4 = 0; /* Fourth int value. */
+ $? "+ dkct_gui_set_grid"
+ co = gui->c_el;
+ if(co) {
+ switch(co->cln) {
+ case 6: case 7: case 8:
+ {
+ } break;
+ default: { $? "! not applicable"
+ /* Warning: Attribute not applicable to class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ p1 = dk3str_c8_start(pv, NULL);
+ if(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ if(p2) {
+ p3 = dk3str_c8_next(p2, NULL);
+ if(p3) {
+ p4 = dk3str_c8_next(p3, NULL);
+ if(p4) {
+ dk3str_c8_next(p4, NULL);
+ }
+ }
+ }
+ }
+ if(p1) {
+ if(sscanf(p1, "%d", &i1) == 1) {
+ if(i1 > 0) {
+ v = 1;
+ if(p2) {
+ if(sscanf(p2, "%d", &i2) == 1) {
+ if(i2 > 0) {
+ v = 2;
+ if(p3) {
+ if(sscanf(p3, "%d", &i3) == 1) {
+ if(i3 >= 0) {
+ v = 3;
+ if(p4) {
+ if(sscanf(p4, "%d", &i4) == 1) {
+ if(i4 >= 0) {
+ v = 4;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ switch(co->cln) {
+ case 6: case 8: { /* grid/flexgrid */
+ if(v >= 2) {
+ back = 1;
+ co->gridrows = i1;
+ co->gridcolumns = i2;
+ if(v >= 3) {
+ co->gridgapy = i3;
+ if(v >= 4) {
+ co->gridgapx = i4;
+ }
+ }
+ }
+ if(!(back)) {
+ /* Syntax error. */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 67);
+ }
+ } break;
+ case 7: { /* gridbag */
+ back = 1;
+ if(v >= 1) {
+ co->gridgapy = i1;
+ if(v >= 2) {
+ co->gridgapx = i2;
+ }
+ }
+ } break;
+ default: { back = 1; }
+ }
+ } else {
+ /* ERROR: No current element yet */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 68);
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ } $? "- dkct_gui_set_grid %d", back
+ return back;
+}
+
+
+
+/** Set sash for splitter window.
+ @param gui GUI description.
+ @param pv Text describing the grid.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_sash(DKCT_GUI *gui, char *pv)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ int i; /* Number read from string. */
+ int back = 0;
+ $? "+ dkct_gui_set_sash"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 14: {
+ } break;
+ default: { $? "! not applicable"
+ /* Warning: Attribute not applicable to class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ {
+ i = 0;
+ if(sscanf(pv, "%d", &i) == 1) {
+ back = 1;
+ el->sash = i;
+ }
+ }
+ }
+ $? "- dkct_gui_set_sash %d", back
+ return back;
+}
+
+
+
+/** Set minimum pane size for splitter window.
+ @param gui GUI description.
+ @param pv Text describing the grid.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_min_pane_size(DKCT_GUI *gui, char *pv)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ int i; /* Number read from string. */
+ int back = 0;
+ $? "- dkct_gui_set_min_pane_size"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 14: {
+ } break;
+ default: { $? "! not applicable"
+ /* Warning: Attribute not applicable to class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ i = 0;
+ if(sscanf(pv, "%d", &i) == 1) {
+ back = 1;
+ el->minPaneSize = i;
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, pv);
+ }
+ }
+ $? "- dkct_gui_set_min_pane_size %d", back
+ return back;
+}
+
+
+
+/** Set flag whether or not the current button is the
+ start of a new radio button group.
+ @param gui GUI description.
+ @param pv Text to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_start_radio_button_group(DKCT_GUI *gui, char *pv)
+{
+ int back = 0;
+ DKCT_GUI_ELEMENT *co; /* Element to modify. */
+ char *p1; /* Start of text. */
+ $? "+ dkct_gui_start_radio_button_group"
+ co = gui->c_el;
+ if(co) {
+ p1 = dk3str_c8_start(pv, NULL);
+ if(p1) {
+ dk3str_c8_delnl(p1);
+ if(dk3str_c8_is_bool(p1)) {
+ back = 1;
+ if(dk3str_c8_is_on(p1)) {
+ co->startGroup = 0x01;
+ } else {
+ co->startGroup = 0x00;
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 70);
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 69);
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 68);
+ }
+ $? "- dkct_gui_start_radio_button_group %d", back
+ return back;
+}
+
+
+
+/** Set size of current GUI object.
+ @param gui GUI description.
+ @param pv Text containing the size.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_size_for_object(DKCT_GUI *gui, char *pv)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Width. */
+ char *p2; /* Height. */
+ int i1 = 0; /* Width. */
+ int i2 = 0; /* Height. */
+ int back = 0;
+ $? "+ dkct_gui_set_size_for_object"
+ if(gui->c_el) {
+ el = gui->c_el;
+ p1 = dk3str_c8_start(pv, NULL);
+ if(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ if(p2) {
+ if(sscanf(p1, "%d", &i1) == 1) {
+ if(sscanf(p2, "%d", &i2) == 1) {
+ if((i1 >= 0) && (i2 >= 0)) {
+ back = 1;
+ el->sizex = i1; el->sizey = i2;
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p2);
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p1);
+ }
+ }
+ }
+ }
+ $? "- dkct_gui_set_size_for_object %d", back
+ return back;
+}
+
+
+
+/** Set spin control direction.
+ @param gui GUI description.
+ @param il Value to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_direction(DKCT_GUI *gui, char *il)
+{
+ int back = 0;
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Start of text. */
+ $? "+ dkct_gui_set_direction"
+ el = gui->c_el;
+ if(el) {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ dk3str_c8_next(p1, NULL);
+ switch(el->cln) {
+ case 5: /* box sizer */
+ case 9: /* static box sizer */
+ case 25: /* spin button */
+ case 26: /* spin control */
+ case 13: /* scrolled window */
+ case 30: /* gauge */
+ case 33: /* static line */
+ {
+ } break;
+ default: { $? "! not applicable"
+ /* Warning: Direction ignored for this class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ switch(dk3str_c8_array_index(dkct_gui_direction_names, p1, 0)) {
+ case 0: {
+ el->direction = DKCT_GUI_DIRECTION_HORIZONTAL;
+ back = 1;
+ } break;
+ case 1: {
+ el->direction = DKCT_GUI_DIRECTION_VERTICAL;
+ back = 1;
+ } break;
+ case 2: {
+ if(el->cln == 13) {
+ el->direction = DKCT_GUI_DIRECTION_BOTH;
+ back = 1;
+ } else {
+ /* ERROR: Only one direction allowed here! */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 72);
+ }
+ } break;
+ default: {
+ /* ERROR: Unknown direction! */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 73);
+ } break;
+ }
+ }
+ }
+ $? "- dkct_gui_set_direction %d", back
+ return back;
+}
+
+
+
+/** Set spin control range.
+ @param gui GUI description.
+ @param il Value to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_range(DKCT_GUI *gui, char *il)
+{
+ int back = 0;
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Minimum. */
+ char *p2; /* Maximum. */
+ int i1 = 0; /* Minimum. */
+ int i2 = 100; /* Maximum. */
+ $? "+ dkct_gui_set_range"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 25: /* spin */
+ case 26: /* spin */
+ case 27: /* slider */
+ case 30: /* gauge */
+ {
+ } break;
+ default: {
+ /* Warning: Range ignored for this class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ if(p2) {
+ if(sscanf(p1, "%d", &i1) == 1) {
+ if(sscanf(p2, "%d", &i2) == 1) {
+ el->spinMin = i1; el->spinMax = i2; back = 1;
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p2);
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p1);
+ }
+ } else {
+ if(el->cln == 30) { /* Gauge has only one value */
+ if(sscanf(p1, "%d", &i1) == 1) {
+ el->spinMax = i1; el->spinMin = 0; back = 1;
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p1);
+ }
+ }
+ }
+ }
+ }
+ $? "- dkct_gui_set_range %d", back
+ return back;
+}
+
+
+
+/** Set spin control value.
+ @param gui GUI description.
+ @param il Value to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_value(DKCT_GUI *gui, char *il)
+{
+ int back = 0;
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Start of text. */
+ int i1 = 0; /* Value. */
+ $? "+ dkct_gui_set_value"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 25: /* spin */
+ case 26: /* spin */
+ case 27: /* slider */
+ case 30: /* gauge */
+ {
+ } break;
+ default: {
+ /* Warning: Range ignored for this class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ dk3str_c8_next(p1, NULL);
+ if(sscanf(p1, "%d", &i1) == 1) {
+ el->spinVal = i1;
+ back = 1;
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p1);
+ }
+ }
+ }
+ $? "- dkct_gui_set_value %d", back
+ return back;
+}
+
+
+
+/** Set spin control wrap flag.
+ @param gui GUI description.
+ @param il Value to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_wrap(DKCT_GUI *gui, char *il)
+{
+ int back = 0;
+ char *p1; /* Start of text. */
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ $? "+ dkct_gui_set_wrap"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 25: /* spin button */
+ case 26: /* spin control */
+ {
+ } break;
+ default: {
+ /* ERROR: Wrap ignored for this class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ dk3str_c8_next(p1, NULL);
+ if(dk3str_c8_is_bool(p1)) {
+ back = 1;
+ if(dk3str_c8_is_on(p1)) {
+ el->spinWrap = 0x01;
+ } else {
+ el->spinWrap = 0x00;
+ }
+ } else {
+ /* ERROR: Not a boolean value! */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 70);
+ }
+ }
+ } $? "- dkct_gui_set_wrap %d", back
+ return back;
+}
+
+
+
+/** Set spin use keys flag.
+ @param gui GUI description.
+ @param il Value to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_keys(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Start of text. */
+ int back = 0;
+ $? "+ dkct_gui_set_keys"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 25: /* spin button */
+ case 26: /* spin control */
+ {
+ } break;
+ default: { $? "! not applicable"
+ /* Warning: Keys setting ignored for this class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ dk3str_c8_next(p1, NULL);
+ if(dk3str_c8_is_bool(p1)) {
+ back = 1;
+ if(dk3str_c8_is_on(p1)) {
+ el->useKeys = 0x01;
+ } else {
+ el->useKeys = 0x00;
+ }
+ } else {
+ /* ERROR: Not a boolean! */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 70);
+ }
+ }
+ } $? "- dkct_gui_set_keys %d", back
+ return back;
+}
+
+
+
+/** Set validator for object.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_validator(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *co; /* Element to modify. */
+ int back = 0;
+ $? "+ dkct_gui_set_validator"
+ co = gui->c_el;
+ if(co) {
+ switch(co->cln) {
+ case 15: /* wxButton */
+ case 16: /* wxBitmapButton */
+ case 17: /* wxChoice */
+ case 18: /* wxComboBox */
+ case 19: /* wxCheckBox */
+ case 20: /* wxListBox */
+ case 21: /* wxCheckListBox */
+ case 22: /* wxRadioBox */
+ case 23: /* wxRadioButton */
+ case 24: /* wxScrollBar */
+ case 25: /* wxSpinButton */
+ case 26: /* wxSpinCtrl */
+ case 27: /* wxSlider */
+ case 28: /* wxTextCtrl */
+ case 29: /* wxToggleButton */
+ case 30: /* wxGauge */
+ {
+ } break;
+ default: { $? "! not applicable"
+ /* Warning: Setting a validator is not recommended! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ if(co->validator) {
+ /* Warning: Redefinition of validator */
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_WARNING, 74, 75, co->validator);
+ }
+ dk3_release(co->validator);
+ co->validator = dk3str_c8_dup_app(il, (gui->psrc)->app);
+ if(co->validator) {
+ back = 1;
+ } else{
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 29);
+ }
+ }
+ $? "- dkct_gui_set_validator %d", back
+ return back;
+}
+
+
+
+/** Set text style.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_text_style(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Current string to process. */
+ char *p2; /* Next string to process. */
+ int back = 0;
+ $? "+ dkct_gui_set_text_style"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 28: /* wxTextCtrl */
+ case 31: /* wxStaticText */
+ case 41: /* wxGrid (readonly) */
+ {
+ } break;
+ default: { $? "! not applicable"
+ /* Warning: Attribute not applicable for class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ back = 1;
+ while(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ switch(dk3str_c8_array_index(dkct_gui_text_style_names, p1, 0)) {
+ case 0: { /* enter */
+ el->textStyle |= DKCT_GUI_TEXT_ENTER;
+ } break;
+ case 1: { /* tab */
+ el->textStyle |= DKCT_GUI_TEXT_TAB;
+ } break;
+ case 2: { /* multi */
+ el->textStyle |= DKCT_GUI_TEXT_MULTILINE;
+ } break;
+ case 3: { /* password */
+ el->textStyle |= DKCT_GUI_TEXT_PASSWORD;
+ } break;
+ case 4: { /* readonly */
+ el->textStyle |= DKCT_GUI_TEXT_READONLY;
+ } break;
+ case 5: { /* rich */
+ el->textStyle |= DKCT_GUI_TEXT_RICH;
+ } break;
+ case 6: { /* rich2 */
+ el->textStyle |= DKCT_GUI_TEXT_RICH2;
+ } break;
+ case 7: { /* url */
+ el->textStyle |= DKCT_GUI_TEXT_URL;
+ } break;
+ case 8: { /* selection */
+ el->textStyle |= DKCT_GUI_TEXT_SHOWSEL;
+ } break;
+ case 9: { /* left */
+ el->textStyle |= DKCT_GUI_TEXT_LEFT;
+ } break;
+ case 10: { /* centered */
+ el->textStyle |= DKCT_GUI_TEXT_CENTRE;
+ } break;
+ case 11: { /* right */
+ el->textStyle |= DKCT_GUI_TEXT_RIGHT;
+ } break;
+ case 12: { /* nowrap */
+ el->textStyle |= DKCT_GUI_TEXT_NOWRAP;
+ } break;
+ case 13: { /* charwrap */
+ el->textStyle |= DKCT_GUI_TEXT_CHARWRAP;
+ } break;
+ case 14: { /* wordwrap */
+ el->textStyle |= DKCT_GUI_TEXT_WORDWRAP;
+ } break;
+ case 15: { /* bestwrap */
+ el->textStyle |= DKCT_GUI_TEXT_BESTWRAP;
+ } break;
+ case 16: { /* capitalize */
+ if(el->cln == 31) {
+ el->textStyle |= DKCT_GUI_TEXT_CAPITALIZE;
+ }
+ } break;
+ case 17: {
+ el->textStyle |= DKCT_GUI_TEXT_NO_AUTORESIZE;
+ } break;
+ default: {
+ back = 0;
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p1);
+ } break;
+ }
+ p1 = p2;
+ }
+ }
+ }
+ }
+ $? "- dkct_gui_set_text_style %d", back
+ return back;
+}
+
+
+
+/** Set button style.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_button_style(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Current string to process. */
+ char *p2; /* Next string to process. */
+ int back = 0;
+ $? "+ dkct_gui_set_button_style"
+ el = gui->c_el;
+ if(el) {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ back = 1;
+ while(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ switch(dk3str_c8_array_index(dkct_gui_notebook_button_names, p1, 0)) {
+ case 0: { /* left */
+ el->buttonStyle |= DKCT_GUI_BUTTON_LEFT;
+ } break;
+ case 1: { /* top */
+ el->buttonStyle |= DKCT_GUI_BUTTON_TOP;
+ } break;
+ case 2: { /* right */
+ el->buttonStyle |= DKCT_GUI_BUTTON_RIGHT;
+ } break;
+ case 3: { /* bottom */
+ el->buttonStyle |= DKCT_GUI_BUTTON_BOTTOM;
+ } break;
+ case 4: { /* fit */
+ el->buttonStyle |= DKCT_GUI_BUTTON_EXACTFIT;
+ } break;
+ case 5: { /* no border */
+ el->buttonStyle |= DKCT_GUI_BUTTON_NO_BORDER;
+ } break;
+ default: {
+ back = 0;
+ /* ERROR: Unknown keyword. */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p1);
+ } break;
+ }
+ p1 = p2;
+ }
+ }
+ }
+ $? "- dkct_gui_set_button_style %d", back
+ return back;
+}
+
+
+
+/** Set notebook style.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_notebook_style(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Current string to process. */
+ char *p2; /* Next string to process. */
+ int back = 0;
+ $? "+ dkct_gui_set_notebook_style"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 12: {
+ } break;
+ default: { $? "! not applicable"
+ /* Warning: Attribute not applicable for class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ back = 1;
+ while(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ switch(dk3str_c8_array_index(dkct_gui_notebook_style_names, p1, 0))
+ {
+ case 0: { /* top */
+ el->notebookStyle |= DKCT_GUI_NB_TOP;
+ } break;
+ case 1: { /* left */
+ el->notebookStyle |= DKCT_GUI_NB_LEFT;
+ } break;
+ case 2: { /* right */
+ el->notebookStyle |= DKCT_GUI_NB_RIGHT;
+ } break;
+ case 3: { /* bottom */
+ el->notebookStyle |= DKCT_GUI_NB_BOTTOM;
+ } break;
+ case 4: { /* fixed-width */
+ el->notebookStyle |= DKCT_GUI_NB_FIXEDWIDTH;
+ } break;
+ case 5: { /* multiline */
+ el->notebookStyle |= DKCT_GUI_NB_MULTILINE;
+ } break;
+ case 6: { /* no-theme */
+ el->notebookStyle |= DKCT_GUI_NB_NOPAGETHEME;
+ } break;
+ case 7: { /* flat */
+ el->notebookStyle |= DKCT_GUI_NB_FLAT;
+ } break;
+ default: {
+ back = 0;
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p1);
+ } break;
+ }
+ p1 = p2;
+ }
+ }
+ }
+ }
+ $? "- dkct_gui_set_notebook_style %d", back
+ return back;
+}
+
+
+
+/** Set slider style.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_slider_style(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Current string to process. */
+ char *p2; /* Next string to process. */
+ int back = 0;
+ $? "+ dkct_gui_set_slider_style"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 27: {
+ } break;
+ default: { $? "! not applicable"
+ /* Warning: Attribute not applicable for class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ back = 1;
+ while(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ switch(dk3str_c8_array_index(dkct_gui_slider_style_names, p1, 0)) {
+ case 0: {
+ el->sliderStyle |= DKCT_GUI_SL_STYLE_AUTOTICKS;
+ } break;
+ case 1: {
+ el->sliderStyle |= DKCT_GUI_SL_STYLE_LABELS;
+ } break;
+ case 2: {
+ el->sliderStyle |= DKCT_GUI_SL_STYLE_LEFT;
+ } break;
+ case 3: {
+ el->sliderStyle |= DKCT_GUI_SL_STYLE_RIGHT;
+ } break;
+ case 4: {
+ el->sliderStyle |= DKCT_GUI_SL_STYLE_TOP;
+ } break;
+ case 5: {
+ el->sliderStyle |= DKCT_GUI_SL_STYLE_BOTTOM;
+ } break;
+ case 6: {
+ el->sliderStyle |= DKCT_GUI_SL_STYLE_SELRANGE;
+ } break;
+ case 7: {
+ el->sliderStyle |= DKCT_GUI_SL_STYLE_INVERSE;
+ } break;
+ default: {
+ back = 0;
+ /* ERROR: Syntax, unknown slider style name! */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p1);
+ } break;
+ }
+ p1 = p2;
+ }
+ }
+ }
+ $? "- dkct_gui_set_slider_style %d", back
+ return back;
+}
+
+
+
+/** Set splitter window style.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_splitter_window_style(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Current string to process. */
+ char *p2; /* Next string to process .*/
+ int back = 0;
+ $? "+ dkct_gui_set_splitter_window_style"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 14: {
+ } break;
+ default: { $? "! not applicable"
+ /* Warning: Attribute not applicable for class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ back = 1;
+ el->splitterStyle = 0U;
+ while(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ switch(dk3str_c8_array_index(dkct_gui_splitterw_style_names,p1,0)) {
+ case 0: {
+ el->splitterStyle |= DKCT_GUI_SPLITTERW_3D;
+ } break;
+ case 1: {
+ el->splitterStyle |= DKCT_GUI_SPLITTERW_3D_SASH;
+ } break;
+ case 2: {
+ el->splitterStyle |= DKCT_GUI_SPLITTERW_3D_BORDER;
+ } break;
+ case 3: {
+ el->splitterStyle |= DKCT_GUI_SPLITTERW_BORDER;
+ } break;
+ case 4: {
+ el->splitterStyle |= DKCT_GUI_SPLITTERW_NO_BORDER;
+ } break;
+ case 5: {
+ el->splitterStyle |= DKCT_GUI_SPLITTERW_NO_XP_THEME;
+ } break;
+ case 6: {
+ el->splitterStyle |= DKCT_GUI_SPLITTERW_PERMIT_UNSPLIT;
+ } break;
+ case 7: {
+ el->splitterStyle |= DKCT_GUI_SPLITTERW_LIVE_UPDATE;
+ } break;
+ default: {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p1);
+ } break;
+ }
+ p1 = p2;
+ }
+ }
+ }
+ }
+ $? "- dkct_gui_set_splitter_window_style %d", back
+ return back;
+}
+
+
+
+/** Set bitmap button style.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_bitmap_button_style(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Current string to process. */
+ char *p2; /* Next string to process. */
+ int back = 0;
+ $? "+ dkct_gui_set_bitmap_button_style"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 16:
+ case 32:
+ case 40:
+ {
+ } break;
+ default: { $? "! not applicable"
+ /* Warning: Attribute not applicable to object! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ back = 1;
+ el->bitmapbStyle = 0x00;
+ while(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ switch(dk3str_c8_array_index(dkct_gui_bitmapb_style_names, p1, 0)) {
+ case 0: {
+ el->bitmapbStyle |= DKCT_GUI_BBUTTON_AUTODRAW;
+ } break;
+ case 1: {
+ el->bitmapbStyle |= DKCT_GUI_BBUTTON_LEFT;
+ } break;
+ case 2: {
+ el->bitmapbStyle |= DKCT_GUI_BBUTTON_TOP;
+ } break;
+ case 3: {
+ el->bitmapbStyle |= DKCT_GUI_BBUTTON_RIGHT;
+ } break;
+ case 4: {
+ el->bitmapbStyle |= DKCT_GUI_BBUTTON_BOTTOM;
+ } break;
+ default: {
+ /* ERROR: Unknown style entry! */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p1);
+ back = 0;
+ } break;
+ }
+ p1 = p2;
+ }
+ }
+ }
+ }
+ $? "- dkct_gui_set_bitmap_button_style %d", back
+ return back;
+}
+
+
+
+/** Set gauge style.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_gauge_style(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Current string to process. */
+ char *p2; /* Next string to process. */
+ int back = 0;
+ $? "+ dkct_gui_set_gauge_style"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 30: {
+ } break;
+ default: {
+ /* Only allowed for gauge elements! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ back = 1;
+ while(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ switch(dk3str_c8_array_index(dkct_gui_gauge_style_names, p1, 0)) {
+ case 0: {
+ el->gaugeStyle |= DKCT_GUI_GAUGE_SMOOTH;
+ } break;
+ default: {
+ /* Illegal keyword */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p1);
+ back = 0;
+ } break;
+ }
+ p1 = p2;
+ }
+ }
+ }
+ }
+ $? "- dkct_gui_set_gauge_style %d", back
+ return back;
+}
+
+
+
+/** Set icon.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_icon(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el;
+ char *p1;
+ int back = 0;
+ $? "+ dkct_gui_set_icon"
+ el = gui->c_el;
+ if(el) {
+ dk3_release(el->icon);
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ dk3str_c8_delnl(p1);
+ el->icon = dk3str_c8_dup_app(p1, (gui->psrc)->app);
+ if((el->parent) || (el->number)) {
+ /* Warning: Icon is recommended for top level windows only! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 63);
+ }
+ if(el->icon) {
+ back = 1;
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 57);
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 33);
+ }
+ }
+ $? "- dkct_gui_set_icon %d", back
+ return back;
+}
+
+
+
+/** Set menu item style.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_menu_item_style(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Current string to process. */
+ char *p2; /* Next string to process. */
+ int back = 0;
+ $? "+ dkct_gui_set_menu_item_style"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 37:
+ case 40:
+ {
+ } break;
+ default: { $? "! not applicable"
+ /* Warning: Attribute not applicable for class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ back = 1;
+ while(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ switch(dk3str_c8_array_index(dkct_gui_menu_item_style_names, p1, 0))
+ {
+ case 0: {
+ el->menuItemStyle = DKCT_GUI_MENU_ITEM_NORMAL;
+ } break;
+ case 1: {
+ el->menuItemStyle = DKCT_GUI_MENU_ITEM_SEPARATOR;
+ if(el->cln == 40) {
+ back = 0;
+ /* ERROR: Not allowed for tool bar buttons */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p1);
+ }
+ } break;
+ case 2: {
+ el->menuItemStyle = DKCT_GUI_MENU_ITEM_CHECK;
+ } break;
+ case 3: {
+ el->menuItemStyle = DKCT_GUI_MENU_ITEM_RADIO;
+ } break;
+ default: {
+ back = 0;
+ /* ERROR: Unknown style! */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p1);
+ } break;
+ }
+ p1 = p2;
+ }
+ }
+ }
+ }
+ $? "- dkct_gui_set_menu_item_style %d", back
+ return back;
+}
+
+
+
+/** Set toolbar style.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_toolbar_style(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Current string to process. */
+ char *p2; /* Next string to process. */
+ int back = 0;
+ $? "+ dkct_gui_set_toolbar_style"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 38: {
+ } break;
+ default: { $? "! not applicable"
+ /* Warning: Attribute not applicable for class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ back = 1;
+ while(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ switch(dk3str_c8_array_index(dkct_gui_toolbar_style_names,p1,0)) {
+ case 0: {
+ el->toolbarStyle |= DKCT_GUI_TOOLBAR_FLAT;
+ } break;
+ case 1: {
+ el->toolbarStyle |= DKCT_GUI_TOOLBAR_DOCKABLE;
+ } break;
+ case 2: {
+ el->toolbarStyle |= DKCT_GUI_TOOLBAR_TEXT;
+ } break;
+ case 3: {
+ el->toolbarStyle |= DKCT_GUI_TOOLBAR_NOICONS;
+ } break;
+ case 4: {
+ el->toolbarStyle |= DKCT_GUI_TOOLBAR_NODIVIDER;
+ } break;
+ case 5: {
+ el->toolbarStyle |= DKCT_GUI_TOOLBAR_HORZ_LAYOUT;
+ } break;
+ case 6: {
+ el->toolbarStyle |= DKCT_GUI_TOOLBAR_NO_TOOLTIPS;
+ } break;
+ case 7: {
+ el->toolbarStyle |= DKCT_GUI_TOOLBAR_BOTTOM;
+ } break;
+ case 8: {
+ el->toolbarStyle |= DKCT_GUI_TOOLBAR_RIGHT;
+ } break;
+ default: {
+ back = 0;
+ /* ERROR: Unknown style keyword */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p1);
+ } break;
+ }
+ p1 = p2;
+ }
+ }
+ }
+ }
+ $? "- dkct_gui_set_toolbar_style %d", back
+ return back;
+}
+
+
+
+/** Set choices for combo, list etc.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_choices(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Current string to process. */
+ char *p2; /* Next string to process. */
+ int i; /* Number read from text. */
+ int back = 0;
+ $? "+ dkct_gui_set_choices"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 17: /* wxChoice */
+ case 18: /* wxComboBox */
+ case 20: /* wxListBox */
+ case 21: /* wxCheckListBox */
+ case 22: /* wxRadioBox */
+ {
+ } break;
+ default: { $? "! not applicable"
+ /* Warning: Attribute not applicable to class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ if(p2) { $? ". old style: number array"
+ if(sscanf(p1, "%i", &i) == 1) {
+ if(i > 0) {
+ el->nChoices = i;
+ if(el->choices) {
+ /* Warning: Redefinition */
+ dkct_to_log_3(gui->psrc,1,DK3_LL_WARNING,74,75,el->choices);
+ }
+ dk3_release(el->choices);
+ el->choices = dk3str_c8_dup_app(p2, (gui->psrc)->app);
+ if(el->choices) {
+ back = 1;
+ } else {
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 29);
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ }
+ }
+ }
+ } else { $? ". new style: wxArrayString expression"
+ if(el->choices) {
+ /* Warning: Redefinition */
+ dkct_to_log_3(gui->psrc,1,DK3_LL_WARNING,74,75,el->choices);
+ }
+ dk3_release(el->choices);
+ el->nChoices = -1;
+ el->choices = dk3str_c8_dup_app(p1, (gui->psrc)->app);
+ if(el->choices) {
+ back = 1;
+ } else {
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 29);
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ }
+ }
+ }
+ }
+ }
+ $? "- dkct_gui_set_choices %d", back
+ return back;
+}
+
+
+
+/** Set style for list box.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_list_box_style(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Start of text. */
+ int back = 0;
+ $? "+ dkct_gui_set_list_box_style"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 20: /* list box */
+ case 21: /* check list box */
+ {
+ } break;
+ default: { $? "! not applicable"
+ /* Warning: Attribute not applicable to class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ switch(dk3str_c8_array_index(dkct_gui_cb_sel_names, p1, 0)) {
+ case 0: {
+ el->selStyle = DKCT_GUI_SELECTION_STYLE_SINGLE; back = 1;
+ } break;
+ case 1: {
+ el->selStyle = DKCT_GUI_SELECTION_STYLE_MULTIPLE; back = 1;
+ } break;
+ case 2: {
+ el->selStyle = DKCT_GUI_SELECTION_STYLE_EXTENDED; back = 1;
+ } break;
+ default: {
+ /* ERROR: Illegal argument! */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p1);
+ } break;
+ }
+ }
+ }
+ }
+ $? "- dkct_gui_set_list_box_style %d", back
+ return back;
+}
+
+
+
+/** Set max number of rows/columns for radio box.
+ @param gui GUI description.
+ @param il Input line to process.
+ @param how Rows (0), columns (1).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_rb_max(DKCT_GUI *gui, char *il, int how)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Start of text. */
+ int i; /* Number read from text. */
+ int back = 0;
+ $? "+ dkct_gui_set_rb_max \"%!8s\"", TR_8STR(il)
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 22: case 41:
+ {
+ } break;
+ default: { $? "! not applicable"
+ /* Warning: Attribute not applicable to class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ {
+ switch(el->cln) {
+ case 22: {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ if(sscanf(p1, "%d", &i) == 1) {
+ if(i > 0) {
+ back = 1;
+ el->maxRowsCols = i;
+ if(how) {
+ el->rbDirection = DKCT_GUI_RB_DIR_COLUMNS;
+ } else {
+ el->rbDirection = DKCT_GUI_RB_DIR_ROWS;
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ /* ERROR: Out of range. */
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 82, 83, p1);
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p1);
+ }
+ } else {
+ /* ERROR: Missing argument */
+ }
+ } break;
+ case 41: {
+ p1 = dk3str_c8_start(il, NULL); $? ". 41"
+ if(p1) {
+ if(sscanf(p1, "%d", &i) == 1) {
+ if(i > 0) {
+ back = 1;
+ if(how) {
+ el->nColumns = i;
+ } else {
+ el->nRows = i;
+ }
+ } else { $? "! syntax"
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 82, 83, p1);
+ }
+ } else { $? "! syntax"
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p1);
+ }
+ } $? ". ende"
+ } break;
+ }
+ }
+ }
+ $? "- dkct_gui_set_rb_max %d", back
+ return back;
+}
+
+
+
+/** Set states for checkbox.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_states(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Current string to process. */
+ char *p2; /* Next string to process. */
+ int i; /* Number read from text. */
+ int back = 0;
+ $? "+ dkct_gui_set_states"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 19: /* wxCheckBox */
+ {
+ } break;
+ default: { $? "! not applicable"
+ /* Warning: Attribute not applicable to class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ {
+ i = 0;
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ if(sscanf(p1, "%d", &i) == 1) {
+ if((i == 2) || (i == 3)) {
+ if(i == 3) el->nStates = 0x03;
+ else el->nStates = 0x02;
+ back = 1;
+ if(p2) {
+ switch(dk3str_c8_array_index(dkct_gui_db_state_names, p2, 0)) {
+ case 0: {
+ el->state = 0x00;
+ } break;
+ case 1: {
+ el->state = 0x01;
+ } break;
+ case 2: {
+ if(el->nStates == 0x03) {
+ el->state = 0x02;
+ } else {
+ back = 0;
+ }
+ } break;
+ default: {
+ back = 0;
+ /* ERROR: Invalid state */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 76, 77, p2);
+ } break;
+ }
+ }
+ } else {
+ /* ERROR: Out of range! */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 82, 83, p1);
+ }
+ } else {
+ /* ERROR: Not a number */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 31);
+ }
+ }
+ }
+ }
+ $? "- dkct_gui_set_states %d", back
+ return back;
+}
+
+
+
+/** Set bitmap for bitmap button.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_bitmap(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Start of text. */
+ int back = 0;
+ $? "+ dkct_gui_set_bitmap"
+ el = gui->c_el;
+ if(el) {
+ switch(el->cln) {
+ case 16:
+ case 32:
+ case 37:
+ case 40:
+ {
+ } break;
+ default: { $? "! not applicable"
+ /* Warning: Attribute not applicable to class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ dk3str_c8_delnl(p1);
+ dk3_release(el->bitmapVarName);
+ el->bitmapVarName = dk3str_c8_dup_app(il, (gui->psrc)->app);
+ if(el->bitmapVarName) {
+ back = 1;
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 57);
+ }
+ }
+ }
+ }
+ $? "- dkct_gui_set_bitmap %d", back
+ return back;
+}
+
+
+
+/** Set disabled bitmap for bitmap button.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_bitmap_disabled(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Start of text. */
+ int back = 0;
+ $? "+ dkct_gui_set_bitmap_disabled"
+ el = gui->c_el;
+ if(el) {
+ if(!((el->cln == 16) || (el->cln == 40))) { $? "! not applicable"
+ /* Warning: Attribute not applicable to class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ }
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ dk3str_c8_delnl(p1);
+ dk3_release(el->bitmapDisabled);
+ el->bitmapDisabled = dk3str_c8_dup_app(il, (gui->psrc)->app);
+ if(el->bitmapDisabled) {
+ back = 1;
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 57);
+ }
+ }
+ }
+ $? "- dkct_gui_set_bitmap_disabled %d", back
+ return back;
+}
+
+
+
+/** Set selected bitmap for bitmap button.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_bitmap_selected(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Value for bitmap. */
+ int back = 0;
+ $? "+ dkct_gui_set_bitmap_selected"
+ el = gui->c_el;
+ if(el) {
+ if(el->cln != 16) { $? "! not applicable"
+ /* Warning: Attribute not applicable for class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ }
+ {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ dk3str_c8_delnl(p1);
+ dk3_release(el->bitmapSelected);
+ el->bitmapSelected = dk3str_c8_dup_app(il, (gui->psrc)->app);
+ if(el->bitmapSelected) {
+ back = 1;
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 57);
+ }
+ }
+ }
+ }
+ $? "- dkct_gui_set_bitmap_selected %d", back
+ return back;
+}
+
+
+
+/** Set focus bitmap for bitmap button.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_bitmap_focus(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Bitmap value. */
+ int back = 0;
+ $? "+ dkct_gui_set_bitmap_focus"
+ el = gui->c_el;
+ if(el) {
+ if(el->cln != 16) { $? "! not applicable"
+ /* Warning: Attribute not applicable for class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ }
+ {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ dk3str_c8_delnl(p1);
+ dk3_release(el->bitmapFocus);
+ el->bitmapFocus = dk3str_c8_dup_app(il, (gui->psrc)->app);
+ if(el->bitmapFocus) {
+ back = 1;
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 57);
+ }
+ }
+ }
+ }
+ $? "- dkct_gui_set_bitmap_focus %d", back
+ return back;
+}
+
+
+
+/** Set hover bitmap for bitmap button.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_set_bitmap_hover(DKCT_GUI *gui, char *il)
+{
+ DKCT_GUI_ELEMENT *el; /* Element to modify. */
+ char *p1; /* Bitmap value. */
+ int back = 0;
+ $? "+ dkct_gui_set_bitmap_hover"
+ el = gui->c_el;
+ if(el) {
+ if(el->cln != 16) { $? "! not applicable"
+ /* Warning: Attribute not applicable for class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ }
+ {
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ dk3str_c8_delnl(p1);
+ dk3_release(el->bitmapHover);
+ el->bitmapHover = dk3str_c8_dup_app(il, (gui->psrc)->app);
+ if(el->bitmapHover) {
+ back = 1;
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 57);
+ }
+ }
+ }
+ }
+ $? "- dkct_gui_set_bitmap_hover %d", back
+ return back;
+}
+
+
+
+/** Add row/column head.
+ @param gui GUI description.
+ @param pv Text for head.
+ @param how Direction (0=row head, 1=column head).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_add_grid_head(DKCT_GUI *gui, char const *pv, int how)
+{
+ DKCT_GRID_HEAD *gh;
+ int back = 0;
+ $? "+ dkct_add_grid_head \"%!8s\" %d", TR_8STR(pv), how
+ if((gui->c_el) && (pv)) {
+ switch((gui->c_el)->cln) {
+ case 41: {
+ if(how) { $? ". how=1 column"
+ if(!((gui->c_el)->sColumnHeads)) {
+ (gui->c_el)->sColumnHeads = dk3sto_open_app((gui->psrc)->app);
+ if((gui->c_el)->sColumnHeads) {
+ dk3sto_set_comp(
+ (gui->c_el)->sColumnHeads, dkct_grid_head_compare, 0
+ );
+ }
+ }
+ if(!((gui->c_el)->iColumnHeads)) {
+ if((gui->c_el)->sColumnHeads) {
+ (gui->c_el)->iColumnHeads =
+ dk3sto_it_open((gui->c_el)->sColumnHeads);
+ }
+ }
+ if(((gui->c_el)->sColumnHeads) && ((gui->c_el)->iColumnHeads)) {
+ gh = dkct_grid_head_new(pv, (gui->c_el)->nColumnHeads, gui->psrc);
+ if(gh) {
+ if(dk3sto_add((gui->c_el)->sColumnHeads, gh)) {
+ back = 1 ;
+ (gui->c_el)->nColumnHeads += 1;
+ } else {
+ dkct_grid_head_delete(gh);
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else { $? ". how=0 row"
+ if(!((gui->c_el)->sRowHeads)) {
+ (gui->c_el)->sRowHeads = dk3sto_open_app((gui->psrc)->app);
+ if((gui->c_el)->sRowHeads) {
+ dk3sto_set_comp((gui->c_el)->sRowHeads,dkct_grid_head_compare,0);
+ }
+ }
+ if(!((gui->c_el)->iRowHeads)) {
+ if((gui->c_el)->sRowHeads) {
+ (gui->c_el)->iRowHeads = dk3sto_it_open((gui->c_el)->sRowHeads);
+ }
+ }
+ if(((gui->c_el)->sRowHeads) && ((gui->c_el)->iRowHeads)) {
+ gh = dkct_grid_head_new(pv, (gui->c_el)->nRowHeads, gui->psrc);
+ if(gh) {
+ if(dk3sto_add((gui->c_el)->sRowHeads, gh)) {
+ back = 1;
+ (gui->c_el)->nRowHeads += 1;
+ } else {
+ dkct_grid_head_delete(gh);
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ }
+ } break;
+ default: {
+ /* Warning: Attribute not applicable for class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ } $? "- dkct_add_grid_head %d", back
+ return back;
+}
+
+
+
+/** Add cell data.
+ @param gui GUI description.
+ @param pv Text to process (Row no, column no, text).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_add_grid_cell_data(DKCT_GUI *gui, char *pv)
+{
+ char *p1;
+ char *p2;
+ char *p3;
+ DKCT_CELL_DATA *pcd;
+ int row = 0;
+ int col = 0;
+ int back = 0;
+ if((gui->c_el) && (pv)) {
+ switch((gui->c_el)->cln) {
+ case 41: {
+ p1 = dk3str_c8_start(pv, NULL);
+ if (p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ if (p2) {
+ p3 = dk3str_c8_next(p2, NULL);
+ if (p3) {
+ if (0 != dk3ma_i_from_c8_string(&row, p1, NULL)) {
+ if (0 != dk3ma_i_from_c8_string(&col, p2, NULL)) {
+ if ((0 <= row) && (0 <= col)) {
+ if (!((gui->c_el)->sCellData)) {
+ (gui->c_el)->sCellData =
+ dk3sto_open_app((gui->psrc)->app);
+ if ((gui->c_el)->sCellData) {
+ dk3sto_set_comp(
+ (gui->c_el)->sCellData, dkct_grid_cell_compare, 0
+ );
+ }
+ }
+ if (((gui->c_el)->sCellData) && (!((gui->c_el)->iCellData)))
+ {
+ (gui->c_el)->iCellData =
+ dk3sto_it_open((gui->c_el)->sCellData);
+ }
+ if (((gui->c_el)->sCellData) && ((gui->c_el)->iCellData)) {
+ pcd = dkct_grid_cell_new(p3, row, col, gui->psrc);
+ if (pcd) {
+ if (dk3sto_add((gui->c_el)->sCellData, pcd)) {
+ back = 1;
+ } else {
+ dkct_grid_cell_delete(pcd);
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ /* !!!!! ERROR: Syntax (negative) */
+ }
+ } else {
+ /* !!!!! ERROR: Syntax (not a number) */
+ }
+ } else {
+ /* !!!!! ERROR: Syntax (not a number) */
+ }
+ } else {
+ /* !!!!! ERROR: No text to save */
+ }
+ } else {
+ /* !!!!! ERROR: No column */
+ }
+ } else {
+ /* !!!!! ERROR: No text */
+ }
+ } break;
+ default: {
+ /* Warning: Attribute not applicable for class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+/** Set grid style.
+ @param gui GUI description.
+ @param pv Text to process (Row no, column no, text).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_set_grid_style(DKCT_GUI *gui, char *pv)
+{
+ int back = 0;
+ char *p1;
+ char *p2;
+ if((gui->c_el) && (pv)) {
+ switch((gui->c_el)->cln) {
+ case 41: {
+ back = 1;
+ p1 = dk3str_c8_start(pv, NULL);
+ while (p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ switch (dk3str_c8_array_index(dkct_gui_grid_style_names, p1, 1)) {
+ case 0: {
+ (gui->c_el)->gridStyle |= DKCT_GUI_GRID_AS_DATA;
+ } break;
+ case 1: {
+ (gui->c_el)->gridStyle |= DKCT_GUI_GRID_AS_LABEL_ROWS;
+ } break;
+ case 2: {
+ (gui->c_el)->gridStyle |= DKCT_GUI_GRID_AS_LABEL_COLS;
+ } break;
+ case 3: {
+ (gui->c_el)->gridStyle |=
+ (DKCT_GUI_GRID_AS_LABEL_ROWS | DKCT_GUI_GRID_AS_LABEL_COLS);
+ } break;
+ default : {
+ /* !!!!! ERROR: Syntax */
+ } break;
+ }
+ p1 = p2;
+ }
+ } break;
+ default: {
+ /* Warning: Attribute not applicable for class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+/** Set tooltip flag for element.
+ @param gui GUI description.
+ @param pv Text value.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_set_tooltip_flag(DKCT_GUI *gui, char *pv)
+{
+ char *p1 = NULL;
+ int back = 0;
+ if ((NULL != gui) && (NULL != pv)) {
+ dk3str_c8_delnl(pv);
+ p1 = dk3str_c8_dup_app(pv, (gui->psrc)->app);
+ if (NULL != p1) {
+ back = 1;
+ if (0 == (gui->c_el)->number) {
+ if (NULL != gui->ttflag) {
+ /* Warning: Redefinition of tooltip flag */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 115);
+ }
+ dk3_release(gui->ttflag);
+ gui->ttflag = p1;
+ } else {
+ if (NULL != (gui->c_el)->ttflag) {
+ /* Warning: Redefinition of tooltip flag */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 115);
+ }
+ dk3_release((gui->c_el)->ttflag);
+ (gui->c_el)->ttflag = p1;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+
+/** Set gridTable entry for current object.
+ @param gui GUI description.
+ @param pv Text to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_set_table_for_grid(DKCT_GUI *gui, char *pv)
+{
+ char *p1 = NULL;
+ char *p2 = NULL;
+ int back = 0;
+ if(gui->c_el) {
+ switch((gui->c_el)->cln) {
+ case 41: {
+ p1 = dk3str_c8_start(pv, NULL);
+ if(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ if((gui->c_el)->gridTable) {
+ dkct_to_log_3(
+ gui->psrc, 1, DK3_LL_ERROR, 74, 75, (gui->c_el)->gridTable
+ );
+ }
+ dk3_release((gui->c_el)->gridTable);
+ (gui->c_el)->gridTable = dk3str_c8_dup_app(pv, (gui->psrc)->app);
+ if((gui->c_el)->gridTable) {
+ back = 1;
+ if(p2) {
+ if(dk3str_c8_is_on(p2)) {
+ (gui->c_el)->tableOwner = 0x01;
+ }
+ }
+ } else {
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ /* ERROR: Empty text! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 69);
+ }
+ } break;
+ default: {
+ /* Warning: Attribute not applicable for class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 56);
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+/** Set minimum size for an object.
+ @param gui GUI description.
+ @param pv Text containing the size in pixels.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_set_minimum_size(DKCT_GUI *gui, char *pv)
+{
+ char *p1;
+ char *p2;
+ int i1;
+ int i2;
+ int back = 0;
+ p1 = dk3str_c8_start(pv, NULL);
+ if(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ if(p2) {
+ if(1 == sscanf(p1, "%d", &i1)) {
+ if(1 == sscanf(p2, "%d", &i2)) {
+ if(i1 < 0) i1 = 0;
+ if(i2 < 0) i2 = 0;
+ back = 1;
+ if(gui->c_el) {
+ (gui->c_el)->sizemx = i1;
+ (gui->c_el)->sizemy = i2;
+ }
+ } else {
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 64, 65, p2);
+ }
+ } else {
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 64, 65, p1);
+ }
+ } else {
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 69);
+ }
+ return back;
+}
+
+
+
+/** Compare two int pointers by number, reverse sort order.
+ @param l Left pointer.
+ @param r Right pointer.
+ @param cr Comparison criteria, ignored.
+ @return Comparison result for inverted sort order.
+*/
+static
+int
+dkct_int_compare(void const *l, void const *r, int cr)
+{
+ int const *pl;
+ int const *pr;
+ int back = 0;
+ pl = (int const *)l; pr = (int const *)r;
+ if(pl) {
+ if(pr) {
+ if(*pl > *pr) back = -1;
+ else {
+ if(*pl < *pr) back = 1;
+ }
+ } else back = -1;
+ } else {
+ if(pr) back = 1;
+ }
+ return back;
+}
+
+
+
+/** Note information about a growable row.
+ @param gui GUI description.
+ @param pv Text containing the row number.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_add_growable_row(DKCT_GUI *gui, char *pv)
+{
+ int *ip;
+ int back = 0;
+ int i;
+ if(gui->c_el) {
+ if(1 == sscanf(pv, "%d", &i)) {
+ if(i >= 0) {
+ if(!((gui->c_el)->sGrowRow)) {
+ (gui->c_el)->sGrowRow = dk3sto_open_app((gui->psrc)->app);
+ if((gui->c_el)->sGrowRow) {
+ dk3sto_set_comp((gui->c_el)->sGrowRow, dkct_int_compare, 0);
+ }
+ }
+ if(!((gui->c_el)->iGrowRow)) {
+ if((gui->c_el)->sGrowRow) {
+ (gui->c_el)->iGrowRow = dk3sto_it_open((gui->c_el)->sGrowRow);
+ }
+ }
+ if(((gui->c_el)->sGrowRow) && ((gui->c_el)->iGrowRow)) {
+ ip = dk3_new_app(int,1,(gui->psrc)->app);
+ if(ip) {
+ *ip = i;
+ if(dk3sto_add((gui->c_el)->sGrowRow, (void *)ip)) {
+ back = 1;
+ } else {
+ dk3_delete(ip);
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ /* ERROR: Syntax */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 112);
+ }
+ } else {
+ /* ERROR: Not a number! */
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 64, 65, pv);
+ }
+ }
+ return back;
+}
+
+
+
+/** Note information about a growable row.
+ @param gui GUI description.
+ @param pv Text containing the row number.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_add_growable_column(DKCT_GUI *gui, char *pv)
+{
+ int *ip;
+ int back = 0;
+ int i;
+ if(gui->c_el) {
+ if(1 == sscanf(pv, "%d", &i)) {
+ if(i >= 0) {
+ if(!((gui->c_el)->sGrowCol)) {
+ (gui->c_el)->sGrowCol = dk3sto_open_app((gui->psrc)->app);
+ if((gui->c_el)->sGrowCol) {
+ dk3sto_set_comp((gui->c_el)->sGrowCol, dkct_int_compare, 0);
+ }
+ }
+ if(!((gui->c_el)->iGrowCol)) {
+ if((gui->c_el)->sGrowCol) {
+ (gui->c_el)->iGrowCol = dk3sto_it_open((gui->c_el)->sGrowCol);
+ }
+ }
+ if(((gui->c_el)->sGrowCol) && ((gui->c_el)->iGrowCol)) {
+ ip = dk3_new_app(int,1,(gui->psrc)->app);
+ if(ip) {
+ *ip = i;
+ if(dk3sto_add((gui->c_el)->sGrowCol, (void *)ip)) {
+ back = 1;
+ } else {
+ dk3_delete(ip);
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ /* ERROR: Memory */
+ dkct_to_log_1(gui->psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ /* ERROR: Syntax */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 112);
+ }
+ } else {
+ /* ERROR: Not numeric! */
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 64, 65, pv);
+ }
+ }
+ return back;
+}
+
+
+
+/** Set "complete constructor specified" attribute.
+ @param gui GUI description.
+ @param pv Text to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_set_complete_constructor_specified(DKCT_GUI *gui, char *pv)
+{
+ int back = 0;
+ if(gui->c_el) {
+ if(pv) {
+ if(dk3str_c8_is_bool(pv)) {
+ back = 1;
+ if(dk3str_c8_is_on(pv)) {
+ (gui->c_el)->compConst = 0x01;
+ } else {
+ (gui->c_el)->compConst = 0x00;
+ }
+ } else {
+ /* ERROR: Not a boolean value! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 70);
+ }
+ } else {
+ (gui->c_el)->compConst = 0x00;
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Process one line containing object details.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_process_object_line(DKCT_GUI *gui, char *il)
+{
+ int back = 1;
+ char *pv; /* Value. */
+ int action; /* Attribute index. */
+ $? "+ dkct_gui_process_object_line \"%!8s\"", TR_8STR(il)
+ if(gui->c_el) {
+ pv = dk3str_c8_chr(il, '=');
+ if(pv) {
+ *(pv++) = '\0';
+ pv = dk3str_c8_start(pv, NULL);
+ if(pv) {
+ dk3str_c8_normalize(il, NULL, '-');
+ action = dk3str_c8_array_index(dkct_gui_attribute_keys, il, 0);
+ switch(action) {
+ case 0: case 23: { $? ". expand"
+ back = dkct_gui_set_expand(gui, pv);
+ } break;
+ case 1: { $? ". type"
+ back = dkct_gui_set_type(gui, pv);
+ } break;
+ case 2: { $? ". menu bar"
+ back = dkct_gui_set_menu_bar(gui, pv);
+ } break;
+ case 3: { $? ". tool bar"
+ back = dkct_gui_set_tool_bar(gui, pv);
+ } break;
+ case 4: { $? ". status bar"
+ back = dkct_gui_set_status_bar(gui, pv);
+ } break;
+ case 5: { $? ". contents"
+ back = dkct_gui_add_contents(gui, pv);
+ } break;
+ case 6: { $? ". text"
+ back = dkct_gui_set_text(gui, pv);
+ } break;
+ case 7: { $? ". id"
+ back = dkct_gui_set_id(gui, pv);
+ } break;
+ case 8: { $? ". tip"
+ back = dkct_gui_set_tip_text(gui, pv);
+ } break;
+ case 9: { $? ". proportion"
+ back = dkct_gui_set_proportion(gui, pv);
+ } break;
+ case 10: { $? ". status text"
+ back = dkct_gui_set_status_text(gui, pv);
+ } break;
+ case 11: { $? ". border"
+ back = dkct_gui_set_border(gui, pv);
+ } break;
+ case 12: { $? ". constructor arguments."
+ back = dkct_gui_set_constructor(gui, pv);
+ } break;
+ case 13: {
+ back = dkct_gui_set_grid(gui, pv);
+ } break;
+ case 14: {
+ back = dkct_gui_set_sash(gui, pv);
+ } break;
+ case 15: {
+ back = dkct_gui_set_min_pane_size(gui, pv);
+ } break;
+ case 16: {
+ back = dkct_gui_set_bitmap(gui, pv);
+ } break;
+ case 17: {
+ back = dkct_gui_set_choices(gui, pv);
+ } break;
+ case 18: {
+ back = dkct_gui_set_states(gui, pv);
+ } break;
+ case 19: {
+ back = dkct_gui_set_size_for_object(gui, pv);
+ } break;
+ case 20: {
+ back = dkct_gui_set_list_box_style(gui, pv);
+ } break;
+ case 21: {
+ back = dkct_gui_set_rb_max(gui, pv, 0);
+ } break;
+ case 22: {
+ back = dkct_gui_set_rb_max(gui, pv, 1);
+ } break;
+ case 24: {
+ back = dkct_gui_start_radio_button_group(gui, pv);
+ } break;
+ case 25: {
+ back = dkct_gui_set_direction(gui, pv);
+ } break;
+ case 26: {
+ back = dkct_gui_set_range(gui, pv);
+ } break;
+ case 27: {
+ back = dkct_gui_set_wrap(gui, pv);
+ } break;
+ case 28: {
+ back = dkct_gui_set_keys(gui, pv);
+ } break;
+ case 29: {
+ back = dkct_gui_set_validator(gui, pv);
+ } break;
+ case 30: {
+ back = dkct_gui_set_value(gui, pv);
+ } break;
+ case 31: {
+ back = dkct_gui_set_slider_style(gui, pv);
+ } break;
+ case 32: {
+ back = dkct_gui_set_notebook_style(gui, pv);
+ } break;
+ case 33: {
+ back = dkct_gui_set_text_style(gui, pv);
+ } break;
+ case 34: {
+ back = dkct_gui_set_button_style(gui, pv);
+ } break;
+ case 35: {
+ back = dkct_gui_set_splitter_window_style(gui, pv);
+ } break;
+ case 36: {
+ back = dkct_gui_set_bitmap_button_style(gui, pv);
+ } break;
+ case 37: {
+ back = dkct_gui_set_bitmap_disabled(gui, pv);
+ } break;
+ case 38: {
+ back = dkct_gui_set_bitmap_selected(gui, pv);
+ } break;
+ case 39: {
+ back = dkct_gui_set_bitmap_focus(gui, pv);
+ } break;
+ case 40: {
+ back = dkct_gui_set_bitmap_hover(gui, pv);
+ } break;
+ case 41: {
+ back = dkct_gui_set_gauge_style(gui, pv);
+ } break;
+ case 42: case 44: {
+ back = dkct_gui_set_menu_item_style(gui, pv);
+ } break;
+ case 43: {
+ back = dkct_gui_set_toolbar_style(gui, pv);
+ } break;
+ case 45: {
+ back = dkct_gui_set_icon(gui, pv);
+ } break;
+ case 46: {
+ back = dkct_add_grid_head(gui, pv, 1);
+ } break;
+ case 47: {
+ back = dkct_add_grid_head(gui, pv, 0);
+ } break;
+ case 48: {
+ back = dkct_set_table_for_grid(gui, pv);
+ } break;
+ case 49: {
+ back = dkct_set_minimum_size(gui, pv);
+ } break;
+ case 50: {
+ back = dkct_add_growable_row(gui, pv);
+ } break;
+ case 51: {
+ back = dkct_add_growable_column(gui, pv);
+ } break;
+ case 52: {
+ back = dkct_set_complete_constructor_specified(gui, pv);
+ } break;
+ case 53: {
+ back = dkct_add_grid_cell_data(gui, pv);
+ } break;
+ case 54: {
+ back = dkct_set_grid_style(gui, pv);
+ } break;
+ case 55: {
+ back = dkct_set_tooltip_flag(gui, pv);
+ } break;
+ default: {
+ /* ERROR: Syntax */
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 10, 11, il);
+ } break;
+ }
+ if(action >= 0) {
+ if(!(back)) {
+ if(!((gui->psrc)->ec)) {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ /* ERROR: Syntax */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 33);
+ }
+ }
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ /* ERROR: Syntax */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 9);
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ /* ERROR: Syntax */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 9);
+ }
+ }
+ $? "- dkct_gui_process_object_line %d", back
+ return back;
+}
+
+
+
+/** Process one input line containing an option.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_process_option(DKCT_GUI *gui, char *il)
+{
+ int back = 1;
+ char *pv; /* Attribute value. */
+ char *p1; /* Current string to process. */
+ char *p2; /* Next string to process. */
+ $? "+ dkct_gui_process_option \"%!8s\"", TR_8STR(il)
+ if(gui->c_el) {
+ pv = dk3str_c8_chr(il, '=');
+ if(pv) {
+ *(pv++) = '\0';
+ pv = dk3str_c8_start(pv, NULL);
+ if(pv) {
+ dk3str_c8_normalize(il, NULL, '-');
+ switch(dk3str_c8_array_index(dkct_gui_option_keys, il, 0)) {
+ case 0: {
+ gui->align = 0x00;
+ p1 = dk3str_c8_start(pv, NULL);
+ while(p1) {
+ p2 = dk3str_c8_next(p1, NULL);
+ gui->align = dkct_gui_apply_align(gui, gui->align, p1);
+ p1 = p2;
+ }
+ } break;
+ default: {
+ /* ERROR: Unknown option "..."! */
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 10, 11, il);
+ } break;
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ /* ERROR: Syntax */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 9);
+ }
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ /* ERROR: Syntax */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 9);
+ }
+ }
+ $? "- dkct_gui_process_option %d", back
+ return back;
+}
+
+
+
+/** Add one input file line to GUI description.
+ @param gui GUI description.
+ @param il Input line to process.
+ @return 1 on success, 0 on error.
+*/
+int
+dkct_gui_add_line(DKCT_GUI *gui, char *il)
+{
+ int back = 1;
+ char *p1; /* Start of input line. */
+ $? "+ dkct_gui_add_line \"%!8s\"", TR_8STR(il)
+ p1 = dk3str_c8_start(il, NULL);
+ if(p1) {
+ switch(*p1) {
+ case '#': { $? ". comment, no operation"
+ back = 1;
+ } break;
+ case '.': { $? ". option"
+ p1++;
+ p1 = dk3str_c8_start(p1, NULL);
+ if(p1) {
+ back = dkct_gui_process_option(gui, p1);
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ /* ERROR: Syntax */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 9);
+ }
+ } break;
+ case '[': { $? ". start of new object"
+ p1++;
+ p1 = dk3str_c8_start(p1, NULL);
+ if(p1) {
+ back = dkct_gui_start_new_object_definition(gui, p1);
+ } else {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ /* ERROR: Syntax */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 37);
+ }
+ } break;
+ default: { $? ". object contents"
+ back = dkct_gui_process_object_line(gui, p1);
+ } break;
+ }
+ }
+ $? "- dkct_gui_add_line %d", back
+ return back;
+}
+
+
+
+/** Get number of content elements.
+ @param el Element to check.
+ @return Number of content elements.
+*/
+static
+size_t
+dkct_gui_get_number_contents(DKCT_GUI_ELEMENT *el)
+{
+ size_t back = 0;
+ dk3sto_it_reset(el->i_contents);
+ while(dk3sto_it_next(el->i_contents)) { back++; }
+ dk3sto_it_reset(el->i_contents);
+ return back;
+}
+
+
+
+/** Report illegal child.
+ @param co Current object.
+ @param dp Direct parent.
+ @param psrc Source structure.
+*/
+static
+void
+dkct_gui_report_illegal_parent_child(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_SRC *psrc
+)
+{
+ char const *cname;
+ char const *pname;
+ $? "+ dkct_gui_report_illegal_parent_child"
+ cname = pname = dkct_gui_out_kw[197];
+ if(co) {
+ if(co->cln >= 0) {
+ cname = dkct_gui_class_names[co->cln];
+ }
+ }
+ if(dp) {
+ if(dp->cln >= 0) {
+ pname = dkct_gui_class_names[dp->cln];
+ }
+ }
+ dkct_to_log_5(psrc, 1, DK3_LL_ERROR, 88, 89, 90, pname, cname);
+ $? "- dkct_gui_report_illegal_parent_child"
+}
+
+
+
+/** Check GUI element setup.
+ @param el Element to check.
+ @param psrc Source structure.
+ @return 1 on success (element setup ok), 0 on error.
+*/
+static
+int
+dkct_gui_element_check(DKCT_GUI_ELEMENT *el, DKCT_SRC *psrc)
+{
+ size_t nco; /* Number of contents elements. */
+ DKCT_GUI_ELEMENT *dp; /* Direct parent. */
+ DKCT_GUI_ELEMENT *sizer = NULL; /* Sizer. */
+ int back = 1;
+ int szfound = 0; /* Flag: Sizer found. */
+ $? "+ dkct_gui_element_check \"%!8s\"", TR_8STR(el->name)
+ dp = (DKCT_GUI_ELEMENT *)(el->parent);
+ psrc->lineno = ((el->lndef) > 0UL) ? (el->lndef) : (el->lndecl);
+ dk3app_set_source_line(psrc->app, psrc->lineno);
+ /*
+ Check contents.
+ */
+ switch(el->cln) {
+ case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8:
+ case 9: case 10: case 11: case 12: case 13: case 14: case 35: case 36:
+ case 38:
+ {
+ back = 0;
+ nco = dkct_gui_get_number_contents(el);
+ if(nco > 0) {
+ if(el->cln == 14) {
+ if(nco == 2) {
+ back = 1;
+ } else {
+ /* ERROR: Splitter window must have exactly 2 children! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 47);
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ /* ERROR: Missing contents! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 48);
+ }
+ if(!(back)) { $? "! missing contents"
+ }
+ } break;
+ }
+ /*
+ Text.
+ */
+ if(back) {
+ switch(el->cln) {
+ case 15: case 19: case 23: case 25: case 28: case 29:
+ case 31: case 36: case 37: case 40:
+ {
+ if(!(el->text)) {
+ if(((el->cln != 37) && (el->cln != 40))
+ || (el->menuItemStyle != DKCT_GUI_MENU_ITEM_SEPARATOR)
+ )
+ {
+ if(el->cln == 28) {
+ /* ERROR: Missing text! */
+ dkct_to_log_1(psrc, 1, DK3_LL_INFO, 49);
+ } else {
+ back = 0; $? "! missing text"
+ /* ERROR: Missing text! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 49);
+ }
+ }
+ }
+ } break;
+ }
+ }
+ /*
+ ID.
+ */
+ if(back) {
+ switch(el->cln) {
+ case 15: case 16: case 23: case 25: case 29: case 37: case 40:
+ {
+ if(!(el->idname)) {
+ back = 0; $? "! missing id"
+ /* ERROR: Missing ID! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 46);
+ }
+ } break;
+ }
+ }
+ /*
+ Grid.
+ */
+ if(back) {
+ switch(el->cln) {
+ case 6: case 8: {
+ if(el->gridcolumns == 0) {
+ back = 0; $? "! missing grid"
+ /* ERROR: Missing grid! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 50);
+ }
+ } break;
+ }
+ }
+ /*
+ Bitmap.
+ */
+ if(back) {
+ switch(el->cln) {
+ case 16: /* wxBitmapButton */
+ case 40: /* wxToolBarToolBase */
+ {
+ if(!(el->bitmapVarName)) {
+ if((el->cln != 40)
+ || (el->menuItemStyle != DKCT_GUI_MENU_ITEM_SEPARATOR)
+ )
+ {
+ back = 0; $? "! missing bitmap"
+ /* ERROR: Missing bitmap! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 51);
+ }
+ }
+ } break;
+ }
+ }
+ /*
+ Choices.
+ */
+ if(back) {
+ switch(el->cln) {
+ case 17: case 18: case 20: case 21: {
+ if((!(el->choices)) || (el->nChoices == 0)) {
+ back = 0; $? "! missing choices"
+ /* ERROR: Missing choices! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 52);
+ }
+ } break;
+ }
+ }
+ /*
+ Size.
+ */
+ if(back) {
+ switch(el->cln) {
+ case 12: case 13: case 28: {
+ if(!((el->sizex > 0) && (el->sizey > 0))) { $? "! missing size"
+ if(el->cln == 28) {
+ /*
+ Warning: Missing size.
+ Not for single-line text with given text.
+ */
+ if(((el->textStyle) & DKCT_GUI_TEXT_MULTILINE) || (!(el->text))) {
+ dkct_to_log_1(psrc, 1, DK3_LL_WARNING, 53);
+ }
+ } else {
+ back = 0;
+ /* ERROR: Missing size! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 53);
+ }
+ }
+ } break;
+ }
+ }
+ /*
+ Rows or columns for radio box.
+ */
+ if(back) {
+ switch(el->cln) {
+ case 22: {
+ if(el->maxRowsCols < 1) {
+ back = 0; $? "! missing rows/columns"
+ /* ERROR: Missing rows or columns maximum! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 54);
+ }
+ } break;
+ }
+ }
+ /*
+ Parent/child relationships
+ */
+ switch(el->cln) {
+ case 40: { /* wxToolBarToolBase */
+ if(dp) {
+ if(dp->cln == 38) {
+ if(dp->name) {
+ } else {
+ back = 0;
+ /* ERROR: Missing name for parent */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 91);
+ }
+ } else {
+ back = 0; $? "! illegal parent/child"
+ /* ERROR: Illegal parent/child combination. */
+ dkct_gui_report_illegal_parent_child(el, dp, psrc);
+ }
+ } else {
+ back = 0;
+ /* ERROR: No parent. */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 92);
+ }
+ } break;
+ case 37: { /* wxMenuItem */
+ if(dp) {
+ if(dp->cln == 36) {
+ if(dp->name) {
+ } else {
+ back = 0;
+ /* ERROR: Missing name for parent */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 91);
+ }
+ } else {
+ back = 0; $? "! illegal parent/child %d/%d", dp->cln, el->cln
+ /* ERROR: Illegal parent/child combination. */
+ dkct_gui_report_illegal_parent_child(el, dp, psrc);
+ }
+ } else {
+ back = 0;
+ /* ERROR: No parent */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 92);
+ }
+ } break;
+ case 36: { /* wxMenu */
+ if(dp) {
+ if((dp->cln == 35) || (dp->cln == 36)) {
+ } else { $? "! illegal parent/child"
+ /* ERROR: Illegal parent/child combination. */
+ dkct_gui_report_illegal_parent_child(el, dp, psrc);
+ }
+ } else {
+ back = 0;
+ /* ERROR: No parent */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 92);
+ }
+ } break;
+ }
+ /*
+ Root element must have a sizer as the only content.
+ */
+ if((el->number == 0) && (!(el->parent))) {
+ sizer = NULL; szfound = 0;
+ if(dkct_gui_get_number_contents(el) == 1) {
+ dk3sto_it_reset(el->i_contents);
+ sizer = (DKCT_GUI_ELEMENT *)dk3sto_it_next(el->i_contents);
+ if(sizer) {
+ switch(sizer->cln) {
+ case 5: case 6: case 7: case 8: case 9: case 10: {
+ szfound = 1;
+ } break;
+ }
+ }
+ }
+ if(!(szfound)) {
+ back = 0;
+ /* ERROR: Root element must have one sizer as contents */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 97);
+ }
+ } $? "- dkct_gui_element_check %d", back
+ return back;
+}
+
+
+
+/** Check whether each object has a class name.
+ @param psrc Source structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_gui_classnames_check(DKCT_SRC *psrc)
+{
+ DKCT_GUI *gui; /* GUI description. */
+ DKCT_GUI_ELEMENT *el; /* Current element to check. */
+ int back = 1;
+ $? "+ dkct_gui_classnames_check"
+ if(psrc->gui) {
+ gui = (DKCT_GUI *)(psrc->gui);
+ dk3sto_it_reset(gui->i_el_by_num);
+ while((el = (DKCT_GUI_ELEMENT *)dk3sto_it_next(gui->i_el_by_num)) != NULL) {
+ psrc->lineno = ((el->lndef) > 0UL) ? (el->lndef) : (el->lndecl);
+ dk3app_set_source_line(psrc->app, psrc->lineno);
+ if(el->number != 0) {
+ if(el->pseudoobj == 0) {
+ if(!(el->name)) {
+ back = 0;
+ /* ERROR: Missing object name! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 58);
+ }
+ if(!(el->cname)) {
+ back = 0; $? "! missing class name"
+ /* ERROR: Missing object class name! */
+ if(el->name) {
+ dkct_to_log_3(gui->psrc, 1, DK3_LL_ERROR, 93, 94, el->name);
+ } else {
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 78);
+ }
+ }
+ }
+ }
+ if(!dkct_gui_element_check(el, psrc)) {
+ back = 0;
+ psrc->ec = DK3_ERROR_SYNTAX;
+ }
+ }
+ } $? "- dkct_gui_classnames_check %d", back
+ return back;
+}
+
+
+
+/** Check for circular dependencies.
+ @param psrc Source structure.
+ @return 1 on success (no circular dependencies), 0 on error.
+*/
+static
+int
+dkct_gui_dependency_check(DKCT_SRC *psrc)
+{
+ int back = 0;
+ dk3_bm_t *bm; /* Dependency matrix. */
+ DKCT_GUI *gui; /* GUI description. */
+ DKCT_GUI_ELEMENT *gel; /* Element to check. */
+ DKCT_GUI_ELEMENT *pp; /* Parent element. */
+ DKCT_GUI_ELEMENT *pm; /* Menu bar/contents element. */
+ DKCT_GUI_ELEMENT *pt; /* Toolbar element. */
+ size_t i; /* Current index to check. */
+ $? "+ dkct_gui_dependency_check"
+ if(psrc->gui) {
+ gui = (DKCT_GUI *)(psrc->gui);
+ bm = dk3bm_open(gui->no, gui->no, psrc->app);
+ if(bm) {
+ back = 1;
+ dk3sto_it_reset(gui->i_el_by_name);
+ while(
+ (gel = (DKCT_GUI_ELEMENT *)dk3sto_it_next(gui->i_el_by_name))
+ != NULL
+ )
+ {
+
+ psrc->lineno = ((gel->lndef) > 0UL) ? (gel->lndef) : (gel->lndecl);
+ dk3app_set_source_line(psrc->app, psrc->lineno);
+ pp = pm = pt = NULL;
+ if(gel->parent) { pp = (DKCT_GUI_ELEMENT *)(gel->parent); }
+ if(gel->menubar) { pm = (DKCT_GUI_ELEMENT *)(gel->menubar); }
+ if(gel->toolbar) { pt = (DKCT_GUI_ELEMENT *)(gel->toolbar); }
+ if(pp) {
+ dk3bm_set(bm, pp->number, gel->number, 1);
+ }
+ if(pm) {
+ dk3bm_set(bm, gel->number, pm->number, 1);
+ }
+ if(pt) {
+ dk3bm_set(bm, gel->number, pt->number, 1);
+ }
+ dk3sto_it_reset(gel->i_contents);
+ while(
+ (pm = (DKCT_GUI_ELEMENT *)dk3sto_it_next(gel->i_contents))
+ != NULL
+ )
+ {
+ dk3bm_set(bm, gel->number, pm->number, 1);
+ }
+ }
+ dk3bm_expand(bm);
+ for(i = 0; i < gui->no; i++) {
+ if(dk3bm_get(bm, i, i)) {
+ psrc->lineno = 0UL;
+ dk3app_set_source_line(psrc->app, 0UL);
+ /* ERROR: Dependency loop */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 79);
+ back = 0;
+ }
+ }
+ dk3bm_close(bm);
+ }
+ } $? "- dkct_gui_dependency_check %d", back
+ return back;
+}
+
+
+
+int
+dkct_gui_check(DKCT_SRC *psrc)
+{
+ int back = 0;
+ $? "+ dkct_gui_check"
+ if(dkct_gui_classnames_check(psrc)) {
+ if(dkct_gui_dependency_check(psrc)) {
+ back = 1;
+ }
+ } $? "- dkct_gui_check %d", back
+ return back;
+}
+
+
+
+/** Check whether we need a wxPanel in the root object.
+ @param gui GUI description.
+ @return 1 for wxPanel needed (frame), 0 for not needed (wxDialog).
+*/
+static
+int
+dkct_gui_need_contents_panel(DKCT_GUI *gui)
+{
+ int back = 1;
+ if(gui->r_el) {
+ if((gui->r_el)->cln == 1) {
+ back = 0;
+ }
+ }
+ return back;
+}
+
+
+
+/** Decide whether or not to write a class member and a
+ constructor method.
+ @param co Current object.
+ @return 1 to write a constructor, 0 for no constructor.
+*/
+static
+int
+dkct_gui_need_element_constructor(
+ DKCT_GUI_ELEMENT *co
+#if 0
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+#endif
+)
+{
+ int back = 1;
+ switch(co->cln) {
+ case 37: /* wxMenuItem */
+ case 40: /* wxToolBarTool */
+ {
+ if(co->menuItemStyle == DKCT_GUI_MENU_ITEM_SEPARATOR) {
+ back = 0;
+ }
+ } break;
+ }
+ return back;
+}
+
+
+
+void
+dkct_gui_class_variables(DKCT_SRC *psrc)
+{
+ DKCT_GUI *gui; /* GUI description. */
+ DKCT_GUI_ELEMENT *el; /* Current element to check. */
+ if(psrc->gui) {
+ gui = (DKCT_GUI *)(psrc->gui);
+ dk3sto_it_reset(gui->i_el_by_num);
+ fputs(dkct_gui_out_kw[7], psrc->fipo);
+ if(dkct_gui_need_contents_panel(gui)) {
+ fputs(dkct_gui_out_kw[17], psrc->fipo);
+ }
+ while((el = (DKCT_GUI_ELEMENT *)dk3sto_it_next(gui->i_el_by_num)) != NULL) {
+ if(el->number != 0) {
+ if(el->pseudoobj == 0) {
+ if(dkct_gui_need_element_constructor(el)) {
+ if((el->name) && (el->cname)) {
+ fputs(dkct_gui_out_kw[5], psrc->fipo);
+ fputs(el->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[6], psrc->fipo);
+ if((psrc->dkcto).lnn) {
+ psrc->lineno = el->lndef;
+ dkct_tr_show_source_line(psrc, 0);
+ }
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ fputs(el->cname, psrc->fipo);
+ fputs(dkct_gui_out_kw[1], psrc->fipo);
+ fputs(dkct_gui_out_kw[3], psrc->fipo);
+ fputs(el->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[4], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+ }
+ }
+ }
+ }
+ /*
+ Write line number.
+ */
+ }
+}
+
+
+
+/** Check whether an object is a sizer.
+ @param gel Object to check.
+ @return 1 for sizer, 0 for non-sizer object.
+*/
+static
+int
+dkct_gui_is_sizer(DKCT_GUI_ELEMENT *gel)
+{
+ int back = 0;
+ if(gel) {
+ if(gel->cln < 11) {
+ if(gel->cln > 4) {
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Find parent window object.
+ @param startelem Direct parent of object.
+ @return Parent representing a non-sizer object or NULL.
+*/
+static
+DKCT_GUI_ELEMENT *
+dkct_gui_find_real_parent(DKCT_GUI_ELEMENT *startelem)
+{
+ DKCT_GUI_ELEMENT *back = NULL;
+ DKCT_GUI_ELEMENT *c; /* Element to check. */
+ c = startelem;
+ while((!(back)) && (c)) {
+ if(dkct_gui_is_sizer(c)) {
+ c = (DKCT_GUI_ELEMENT *)(c->parent);
+ } else {
+ back = c;
+ }
+ }
+ return back;
+}
+
+
+
+/** Write flags to add object to sizer.
+ @param fipo Output file.
+ @param co Current object.
+*/
+static
+void
+dkct_gui_write_flags(FILE *fipo, DKCT_GUI_ELEMENT *co)
+{
+ int found = 0; /* Flag: Already found. */
+
+ if((co->border >= 0) && (co->borderPos)) {
+ if(co->borderPos == DKCT_GUI_BORDER_POSITION_ALL) {
+ fputs(dkct_gui_out_kw[39], fipo);
+ found = 1;
+ } else {
+ if((co->borderPos) & DKCT_GUI_BORDER_POSITION_TOP) {
+ if(found) { fputs(dkct_gui_out_kw[44], fipo); }
+ found = 1;
+ fputs(dkct_gui_out_kw[40], fipo);
+ }
+ if((co->borderPos) & DKCT_GUI_BORDER_POSITION_LEFT) {
+ if(found) { fputs(dkct_gui_out_kw[44], fipo); }
+ found = 1;
+ fputs(dkct_gui_out_kw[41], fipo);
+ }
+ if((co->borderPos) & DKCT_GUI_BORDER_POSITION_RIGHT) {
+ if(found) { fputs(dkct_gui_out_kw[44], fipo); }
+ found = 1;
+ fputs(dkct_gui_out_kw[42], fipo);
+ }
+ if((co->borderPos) & DKCT_GUI_BORDER_POSITION_BOTTOM) {
+ if(found) { fputs(dkct_gui_out_kw[44], fipo); }
+ found = 1;
+ fputs(dkct_gui_out_kw[43], fipo);
+ }
+ }
+ }
+ if((co->align) & DKCT_GUI_ALIGN_H_MASK) {
+ switch((co->align) & DKCT_GUI_ALIGN_H_MASK) {
+ case DKCT_GUI_ALIGN_H_LEFT: {
+ if(found) { fputs(dkct_gui_out_kw[44], fipo); }
+ found = 1;
+ fputs(dkct_gui_out_kw[45], fipo);
+ } break;
+ case DKCT_GUI_ALIGN_H_CENTER: {
+ if(found) { fputs(dkct_gui_out_kw[44], fipo); }
+ found = 1;
+ fputs(dkct_gui_out_kw[46], fipo);
+ } break;
+ case DKCT_GUI_ALIGN_H_RIGHT: {
+ if(found) { fputs(dkct_gui_out_kw[44], fipo); }
+ found = 1;
+ fputs(dkct_gui_out_kw[47], fipo);
+ } break;
+ }
+ }
+ if((co->align) & DKCT_GUI_ALIGN_V_MASK) {
+ switch((co->align) & DKCT_GUI_ALIGN_V_MASK) {
+ case DKCT_GUI_ALIGN_V_TOP: {
+ if(found) { fputs(dkct_gui_out_kw[44], fipo); }
+ found = 1;
+ fputs(dkct_gui_out_kw[48], fipo);
+ } break;
+ case DKCT_GUI_ALIGN_V_CENTER: {
+ if(found) { fputs(dkct_gui_out_kw[44], fipo); }
+ found = 1;
+ fputs(dkct_gui_out_kw[49], fipo);
+ } break;
+ case DKCT_GUI_ALIGN_V_BOTTOM: {
+ if(found) { fputs(dkct_gui_out_kw[44], fipo); }
+ found = 1;
+ fputs(dkct_gui_out_kw[50], fipo);
+ } break;
+ }
+ }
+ if(co->expandFlag) {
+ if(found) { fputs(dkct_gui_out_kw[44], fipo); }
+ found = 1;
+ fputs(dkct_gui_out_kw[51], fipo);
+ }
+ if(!(found)) {
+ fputs(dkct_gui_out_kw[52], fipo);
+ }
+}
+
+
+
+/** Check whether we need to write commands for flags.
+ @param co Current object.
+ @return 1 to configure flags, 0 to skip.
+*/
+static
+int
+dkct_gui_need_flags(DKCT_GUI_ELEMENT *co)
+{
+ int back = 0;
+ if((co->border >= 0) && (co->borderPos)) {
+ back = 0;
+ }
+ if((co->borderPos) & DKCT_GUI_BORDER_POSITION_TOP) {
+ back = 1;
+ }
+ if((co->borderPos) & DKCT_GUI_BORDER_POSITION_LEFT) {
+ back = 1;
+ }
+ if((co->borderPos) & DKCT_GUI_BORDER_POSITION_RIGHT) {
+ back = 1;
+ }
+ if((co->borderPos) & DKCT_GUI_BORDER_POSITION_BOTTOM) {
+ back = 1;
+ }
+ if((co->align) & DKCT_GUI_ALIGN_H_MASK) {
+ back = 1;
+ }
+ if((co->align) & DKCT_GUI_ALIGN_V_MASK) {
+ back = 1;
+ }
+ if(co->expandFlag) {
+ back = 1;
+ }
+ return back;
+}
+
+
+
+/** Write border for object.
+ @param fipo Output file.
+ @param co Current object.
+*/
+static
+void
+dkct_gui_write_border(FILE *fipo, DKCT_GUI_ELEMENT *co)
+{
+ int b = 0; /* Border size. */
+ char bu[32]; /* Buffer for integer variables. */
+
+ if((co->border >= 0) && (co->borderPos)) {
+ b = co->border;
+ }
+ sprintf(bu, "%d", b);
+ fputs(bu, fipo);
+}
+
+
+
+/** Write growable rows and columns.
+ @param co Current object.
+ @param st Storage for growable rows/columns.
+ @param it Iterator for growable rows/columns.
+ @param rowcol Flag: Row=0 or column=1.
+ @param psrc Source structure.
+*/
+static
+void
+dkct_write_growable_rows_cols(
+ DKCT_GUI_ELEMENT *co,
+ dk3_sto_t *st,
+ dk3_sto_it_t *it,
+ int rowcol,
+ DKCT_SRC *psrc
+)
+{
+ int *ip;
+ if((st) && (it)) {
+ dk3sto_it_reset(it);
+ while(NULL != (ip = (int *)dk3sto_it_next(it))) {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[(rowcol) ? 206 : 207], psrc->fipo);
+ fprintf(psrc->fipo, "%d", *ip);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+ }
+}
+
+
+
+/** Add one object to the parent which is a sizer.
+ @param co Current object.
+ @param pa Parent (a sizer object).
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_add_object_to_sizer(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *pa,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ char bu[64]; /* Buffer for integer values. */
+ int det = 0; /* Details to use. */
+ $? "+ dkct_gui_add_object_to_sizer"
+ /*
+ Last modifications to object before adding it to parent.
+ */
+ switch(co->cln) {
+ case 7: {
+ /* Growable rows and columns for wxGridBagSizer */
+ dkct_write_growable_rows_cols(co, co->sGrowRow, co->iGrowRow, 0, psrc);
+ dkct_write_growable_rows_cols(co, co->sGrowCol, co->iGrowCol, 1, psrc);
+ } break;
+ }
+ /*
+ Add object to parent.
+ */
+ switch(pa->cln) {
+ case 7: { $? ". wxGridBagSizer"
+ /* sizer */
+ if(dkct_gui_need_flags(co)) {
+ det = 1; $? ". det = 1"
+ }
+ if((co->border >= 0) && (co->borderPos)) {
+ det = 2; $? ". det = 2"
+ }
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(pa->name, psrc->fipo);
+ /* -> */
+ fputs(dkct_gui_out_kw[31], psrc->fipo);
+ /* Add( */
+ fputs(dkct_gui_out_kw[36], psrc->fipo);
+ /* object */
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ /* , */
+ fputs(dkct_gui_out_kw[38], psrc->fipo);
+ /* wxGBPosition */
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ fputs(dkct_gui_out_kw[53], psrc->fipo);
+ sprintf(bu, "%d", co->posy);
+ fputs(bu, psrc->fipo);
+ fputs(dkct_gui_out_kw[55], psrc->fipo);
+ sprintf(bu, "%d", co->posx);
+ fputs(bu, psrc->fipo);
+ fputs(dkct_gui_out_kw[56], psrc->fipo);
+ /* , */
+ fputs(dkct_gui_out_kw[38], psrc->fipo);
+ /* wxGBSpan */
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ fputs(dkct_gui_out_kw[54], psrc->fipo);
+ sprintf(bu, "%d", co->spany);
+ fputs(bu, psrc->fipo);
+ fputs(dkct_gui_out_kw[55], psrc->fipo);
+ sprintf(bu, "%d", co->spanx);
+ fputs(bu, psrc->fipo);
+ fputs(dkct_gui_out_kw[56], psrc->fipo);
+#if 0
+ /* , */
+ fputs(dkct_gui_out_kw[38], psrc->fipo);
+ /*
+ Proportion not printed for wxGridBagSizer elements.
+ */
+ /* proportion */
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ sprintf(bu, "%d", ((co->proportion >= 0) ? (co->proportion) : 0));
+ fputs(bu, psrc->fipo);
+#endif
+ if(det) {
+ /* , */
+ fputs(dkct_gui_out_kw[38], psrc->fipo);
+ /* flags */
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_flags(psrc->fipo, co);
+ if(det > 1) {
+ /* , */
+ fputs(dkct_gui_out_kw[38], psrc->fipo);
+ /* border */
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_border(psrc->fipo, co);
+ }
+ }
+ /* ); */
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ fputs(dkct_gui_out_kw[37], psrc->fipo);
+ } break;
+ case 5: case 6: case 8: case 9: case 10: { $? ". all other sizers"
+ /*
+ sizer->Add(object, proportion, flags, border);
+ */
+ /* sizer */
+ if(co->proportion) {
+ det = 1; $? ". det = 1"
+ }
+ if(dkct_gui_need_flags(co)) {
+ det = 2; $? ". det = 2"
+ }
+ if((co->border >= 0) && (co->borderPos)) {
+ det = 3; $? ". det = 3"
+ }
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(pa->name, psrc->fipo);
+ /* -> */
+ fputs(dkct_gui_out_kw[31], psrc->fipo);
+ /* Add( */
+ switch(pa->cln) {
+ /*
+ wxStdButtonSizer.
+ */
+ case 10: {
+ switch(co->cln) {
+ case 15: case 16: { /* Buttons. */
+ fputs(dkct_gui_out_kw[208], psrc->fipo);
+ } break;
+ default: { /* Other elements. */
+ fputs(dkct_gui_out_kw[36], psrc->fipo);
+ } break;
+ }
+ } break;
+ /*
+ All other containers and sizers.
+ */
+ default: {
+ fputs(dkct_gui_out_kw[36], psrc->fipo);
+ } break;
+ }
+ /* object */
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ if(det) {
+ /* , */
+ fputs(dkct_gui_out_kw[38], psrc->fipo);
+ /* proportion */
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ sprintf(bu, "%d", ((co->proportion >= 0) ? (co->proportion) : 0));
+ fputs(bu, psrc->fipo);
+ if(det > 1) {
+ /* , */
+ fputs(dkct_gui_out_kw[38], psrc->fipo);
+ /* flags */
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_flags(psrc->fipo, co);
+ if(det > 2) {
+ /* , */
+ fputs(dkct_gui_out_kw[38], psrc->fipo);
+ /* border */
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_border(psrc->fipo, co);
+ }
+ }
+ }
+ /* ); */
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ fputs(dkct_gui_out_kw[37], psrc->fipo);
+ } break;
+ }
+ $? "- dkct_gui_add_object_to_sizer"
+}
+
+
+
+/** Use the current object as the parents sizer object.
+ @param co Current object.
+ @param pa Parent (a sizer object).
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_set_parents_sizer(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *pa,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ char const *pname = NULL; /* Parent object name. */
+ $? "+ dkct_gui_set_parents_sizer"
+ if(pa) { pname = pa->name; }
+ if(!(pname)) {
+ if(pa->cln != 1) { pname = dkct_gui_out_kw[30]; }
+ }
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ if(pname) {
+ fputs(pname, psrc->fipo);
+ fputs(dkct_gui_out_kw[31], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[32], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ $? "- dkct_gui_set_parents_sizer"
+}
+
+
+
+/** Write objects parents name.
+ @param pw Parent object.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_write_parent_name(
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ char *pname = NULL; /* Parent object name. */
+
+ if(pw) { pname = pw->name; }
+ if(pname) {
+ fputs(pname, psrc->fipo);
+ } else {
+ if(dkct_gui_need_contents_panel(gui)) {
+ fputs(dkct_gui_out_kw[30], psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[65], psrc->fipo);
+ }
+ }
+}
+
+
+
+/** Switch to next argument.
+ @param psrc Source structure.
+*/
+static
+void
+dkct_gui_next_argument(DKCT_SRC *psrc)
+{
+ fputs(dkct_gui_out_kw[38], psrc->fipo);
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+}
+
+
+
+/** Write ID attribute.
+ @param co Current object.
+ @param psrc Source structure.
+*/
+static
+void
+dkct_gui_write_idname(DKCT_GUI_ELEMENT *co, DKCT_SRC *psrc)
+{
+ if(co->idname) {
+ fputs(co->idname, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[66], psrc->fipo);
+ }
+}
+
+
+
+/** Write size attribute.
+ @param psrc Source structure.
+ @param w Object width.
+ @param h Object height.
+ @param rec Flag: Size attribute recommended.
+ @param co Current object.
+*/
+static
+void
+dkct_gui_write_size(DKCT_SRC *psrc, int w, int h, int rec, DKCT_GUI_ELEMENT *co)
+{
+ char bu[256];
+ if((w > 0) && (h > 0)) {
+ sprintf(bu, "%d, %d", w, h);
+ fputs(dkct_gui_out_kw[81], psrc->fipo);
+ fputs(bu, psrc->fipo);
+ fputs(dkct_gui_out_kw[56], psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[75], psrc->fipo);
+ if(rec) {
+ /* WARNING: Size not specified! */
+ dkct_to_log_1(psrc, 1, DK3_LL_WARNING, 53);
+ }
+ }
+}
+
+
+
+/** Write constructor arguments for wxFrame or wxDialog.
+*/
+static
+void
+dkct_gui_constructor_frame_dialog(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int det = 0; /* Details level. */
+
+ if(co->text) det = 1;
+ if((co->sizex > 0) && (co->sizey > 0)) det = 2;
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ if(det) {
+ dkct_gui_next_argument(psrc);
+ if(co->text) {
+ fputs(co->text, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[73], psrc->fipo);
+ }
+ if(det > 1) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write constructor for box sizer.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window object.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_boxsizer(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ switch(co->direction) {
+ case DKCT_GUI_DIRECTION_VERTICAL: {
+ fputs(dkct_gui_out_kw[35], psrc->fipo);
+ } break;
+ default: {
+ fputs(dkct_gui_out_kw[34], psrc->fipo);
+ } break;
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+#if 0
+/** Write constructor arguments for wxPanel.
+*/
+static
+void
+dkct_gui_constructor_parent_and_id(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+#endif
+
+
+
+/** Write constructor for grid sizer.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window object.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_gridsizer(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ char bu[256]; /* Buffer for integer values. */
+ int c = 0; /* Columns. */
+ int r = 0; /* Rows. */
+ int y = 0; /* Start row. */
+ int x = 0; /* Start column. */
+
+ c = co->gridcolumns;
+ r = co->gridrows;
+ x = co->gridgapx;
+ y = co->gridgapy;
+ bu[0] = '\0';
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ if(r > 0) {
+ if(x < 0) { x = 0; } if(y < 0) { y = 0; }
+ sprintf(bu, "%d, %d, %d, %d", c, r, y, x);
+ } else {
+ if((x > -1) || (y > -1)) {
+ if(x > -1) {
+ sprintf(bu, "%d, %d, %d", c, ((y > -1) ? y : 0), ((x > -1) ? x : 0));
+ } else {
+ sprintf(bu, "%d, %d", c, y);
+ }
+ } else {
+ sprintf(bu, "%d", c);
+ }
+ }
+ fputs(bu, psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write constructor for gridbag sizer.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window object.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_gridbagsizer(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ char bu[128]; /* Buffer for integer values. */
+
+ bu[0] = '\0';
+ if((co->gridgapy > -1) || (co->gridgapy > -1)) {
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ if(co->gridgapx > -1) {
+ sprintf(
+ bu, "%d, %d",
+ ((co->gridgapy > -1) ? co->gridgapy : 0),
+ ((co->gridgapx > -1) ? co->gridgapx : 0)
+ );
+ } else {
+ sprintf(bu, "%d", co->gridgapy);
+ }
+ fputs(bu, psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+}
+
+
+
+/** Write element constructor for static box sizer.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_staticboxsizer(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ fputs(dkct_gui_out_kw[(co->direction) ? 35 : 34], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ if(co->text) {
+ dkct_gui_next_argument(psrc);
+ fputs(co->text, psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write constructor for a panel.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window object.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_panel(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int det = 0; /* Details level. */
+
+ if((co->sizex > 0) && (co->sizey > 0)) det = 1;
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ if(det) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(det > 1) {
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write constructor for notebook.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window object.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_notebook(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int det = 0; /* Details level. */
+ int fe = 0; /* Flag: Found elements. */
+
+ if((co->sizex > 0) && (co->sizey > 0)) det = 1;
+ if(co->notebookStyle) det = 2;
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ if(det) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(det > 1) {
+ if((co->notebookStyle) & DKCT_GUI_NB_TOP) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[113], psrc->fipo);
+ }
+ if((co->notebookStyle) & DKCT_GUI_NB_LEFT) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[114], psrc->fipo);
+ }
+ if((co->notebookStyle) & DKCT_GUI_NB_RIGHT) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[115], psrc->fipo);
+ }
+ if((co->notebookStyle) & DKCT_GUI_NB_BOTTOM) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[116], psrc->fipo);
+ }
+ if((co->notebookStyle) & DKCT_GUI_NB_FIXEDWIDTH) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[117], psrc->fipo);
+ }
+ if((co->notebookStyle) & DKCT_GUI_NB_MULTILINE) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[118], psrc->fipo);
+ }
+ if((co->notebookStyle) & DKCT_GUI_NB_NOPAGETHEME) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[119], psrc->fipo);
+ }
+ if((co->notebookStyle) & DKCT_GUI_NB_FLAT) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[120], psrc->fipo);
+ }
+ if(!(fe)) { fputs(dkct_gui_out_kw[52], psrc->fipo); }
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write constructor for scrolled window.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window object.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_scrolledwindow(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int det = 0; /* Details level. */
+
+ if((co->sizex > 0) && (co->sizey > 0)) det = 1;
+ if(co->direction != DKCT_GUI_DIRECTION_BOTH) det = 2;
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ if(det) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 1, co);
+ if(det > 1) {
+ dkct_gui_next_argument(psrc);
+ switch(co->direction) {
+ case DKCT_GUI_DIRECTION_HORIZONTAL: {
+ fputs(dkct_gui_out_kw[138], psrc->fipo);
+ } break;
+ case DKCT_GUI_DIRECTION_VERTICAL: {
+ fputs(dkct_gui_out_kw[139], psrc->fipo);
+ } break;
+ default: {
+ fputs(dkct_gui_out_kw[140], psrc->fipo);
+ } break;
+ }
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write constructor for splitter window.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window object.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_splitterwindow(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int det = 0; /* Details level. */
+ int fe = 0; /* Flag: Found an element. */
+
+ if((co->sizex > 0) && (co->sizey > 0)) det = 1;
+ if(co->splitterStyle != DKCT_GUI_SPLITTERW_3D) det = 2;
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ if(det) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 1, co);
+ if(det > 1) {
+ dkct_gui_next_argument(psrc);
+ if((co->splitterStyle) & DKCT_GUI_SPLITTERW_3D) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[147], psrc->fipo);
+ } else {
+ if((co->splitterStyle) & DKCT_GUI_SPLITTERW_3D_SASH) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[148], psrc->fipo);
+ }
+ if((co->splitterStyle) & DKCT_GUI_SPLITTERW_3D_BORDER) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[149], psrc->fipo);
+ }
+ }
+ if((co->splitterStyle) & DKCT_GUI_SPLITTERW_BORDER) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[150], psrc->fipo);
+ }
+ if((co->splitterStyle) & DKCT_GUI_SPLITTERW_NO_BORDER) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[151], psrc->fipo);
+ }
+ if((co->splitterStyle) & DKCT_GUI_SPLITTERW_NO_XP_THEME) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[152], psrc->fipo);
+ }
+ if((co->splitterStyle) & DKCT_GUI_SPLITTERW_PERMIT_UNSPLIT) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[153], psrc->fipo);
+ }
+ if((co->splitterStyle) & DKCT_GUI_SPLITTERW_LIVE_UPDATE) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); }
+#if 0
+ /* Re-activate when adding further contents.
+ */
+ fe = 1;
+#endif
+ fputs(dkct_gui_out_kw[154], psrc->fipo);
+ }
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write constructor for button.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window object.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_button(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int det = 0; /* Details level. */
+ int fe = 0; /* Flag: Found an entry. */
+
+ if(co->text) det = 1;
+ if((co->sizex > 0) && (co->sizey > 0)) det = 2;
+ if(co->buttonStyle) det = 3;
+ if(co->validator) det = 4;
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ if(det) {
+ dkct_gui_next_argument(psrc);
+ if(co->text) {
+ fputs(co->text, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[73], psrc->fipo);
+ }
+ if(det > 1) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(det > 2) {
+ dkct_gui_next_argument(psrc);
+ if((co->buttonStyle) & DKCT_GUI_BUTTON_LEFT) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[141], psrc->fipo);
+ }
+ if((co->buttonStyle) & DKCT_GUI_BUTTON_TOP) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[142], psrc->fipo);
+ }
+ if((co->buttonStyle) & DKCT_GUI_BUTTON_RIGHT) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[143], psrc->fipo);
+ }
+ if((co->buttonStyle) & DKCT_GUI_BUTTON_BOTTOM) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[144], psrc->fipo);
+ }
+ if((co->buttonStyle) & DKCT_GUI_BUTTON_EXACTFIT) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[145], psrc->fipo);
+ }
+ if((co->buttonStyle) & DKCT_GUI_BUTTON_NO_BORDER) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); }
+#if 0
+ /* Re-activate when adding further contents later.
+ */
+ fe = 1;
+#endif
+ fputs(dkct_gui_out_kw[146], psrc->fipo);
+ }
+ if(det > 3) {
+ dkct_gui_next_argument(psrc);
+ }
+ }
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write constructor for bitmap button.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window object.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_bitmapbutton(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int det = 0; /* Details level. */
+ int fe = 0; /* Flag: Found entry. */
+
+ if(co->bitmapVarName) {
+ det = 1;
+ if((co->sizex > 0) && (co->sizey > 0)) det = 2;
+ if(co->bitmapbStyle != DKCT_GUI_BBUTTON_AUTODRAW) det = 3;
+ if(co->validator) det = 4;
+
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ dkct_gui_next_argument(psrc);
+ fputs(co->bitmapVarName, psrc->fipo);
+ if(det > 1) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(det > 2) {
+ if((co->bitmapbStyle) & DKCT_GUI_BBUTTON_AUTODRAW) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[155], psrc->fipo);
+ }
+ if((co->bitmapbStyle) & DKCT_GUI_BBUTTON_LEFT) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[141], psrc->fipo);
+ }
+ if((co->bitmapbStyle) & DKCT_GUI_BBUTTON_TOP) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[142], psrc->fipo);
+ }
+ if((co->bitmapbStyle) & DKCT_GUI_BBUTTON_RIGHT) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[143], psrc->fipo);
+ }
+ if((co->bitmapbStyle) & DKCT_GUI_BBUTTON_BOTTOM) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[144], psrc->fipo);
+ }
+ if(!(fe)) { fputs(dkct_gui_out_kw[52], psrc->fipo); }
+ if(det > 3) {
+ dkct_gui_next_argument(psrc);
+ fputs(co->validator, psrc->fipo);
+ }
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ } else {
+ /* ERROR: No bitmap name specified! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 51);
+ }
+}
+
+
+
+/** Write element constructor for choice and combo box.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+ @param iscombo Flag: Combo box.
+*/
+static
+void
+dkct_gui_constructor_choice_combo(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui,
+ int iscombo
+)
+{
+ char bu[64]; /* Buffer for integer values. */
+ int details = 0; /* Details level. */
+ /*
+ parent, id, pos, size (1) , n (2), texts (3), validator (4)
+ parent, id, text, pos, size (1), n (2), texts (3), validator (4)
+ */
+ if((co->sizex > 0) && (co->sizey > 0)) details = 1;
+ if((co->nChoices > 0) || (co->nChoices == -1)) details = 2;
+ if(co->choices) details = 3;
+ if(co->validator) details = 4;
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ if(iscombo) {
+ dkct_gui_next_argument(psrc);
+ if(co->text) {
+ fputs(co->text, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[73], psrc->fipo);
+ }
+ }
+ if(details) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(details > 1) {
+ if(co->nChoices != -1) {
+ dkct_gui_next_argument(psrc);
+ sprintf(bu, "%d", co->nChoices);
+ fputs(bu, psrc->fipo);
+ }
+ if(details > 2) {
+ dkct_gui_next_argument(psrc);
+ if(co->choices) {
+ fputs(co->choices, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[100], psrc->fipo);
+ }
+ if(details > 3) {
+ dkct_gui_next_argument(psrc);
+ fputs(co->validator, psrc->fipo);
+ }
+ }
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write element constructor for checkbox.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_checkbox(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int need_full_arguments = 0; /* Details level. */
+
+ if(co->text) need_full_arguments = 1;
+ if((co->sizex > 0) && (co->sizey > 0)) { need_full_arguments = 2; }
+ if(co->nStates == 0x03) {
+ need_full_arguments = 3;
+ }
+ if(((co->align) & DKCT_GUI_ALIGN_H_MASK) == DKCT_GUI_ALIGN_H_RIGHT) {
+ need_full_arguments = 3;
+ }
+ if(co->validator) need_full_arguments = 4;
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ if(need_full_arguments) {
+ dkct_gui_next_argument(psrc);
+ if(co->text) {
+ fputs(co->text, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[73], psrc->fipo);
+ }
+ if(need_full_arguments > 1) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(need_full_arguments > 2) {
+ dkct_gui_next_argument(psrc);
+ if(co->nStates == 0x03) {
+ fputs(dkct_gui_out_kw[76], psrc->fipo);
+ if(((co->align) & DKCT_GUI_ALIGN_H_MASK) == DKCT_GUI_ALIGN_H_RIGHT) {
+ fputs(dkct_gui_out_kw[44], psrc->fipo);
+ fputs(dkct_gui_out_kw[47], psrc->fipo);
+ } else {
+ }
+ } else {
+ if(((co->align) & DKCT_GUI_ALIGN_H_MASK) == DKCT_GUI_ALIGN_H_RIGHT) {
+ fputs(dkct_gui_out_kw[47], psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[52], psrc->fipo);
+ }
+ }
+ if(need_full_arguments > 3) {
+ dkct_gui_next_argument(psrc);
+ fputs(co->validator, psrc->fipo);
+ }
+ }
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write element constructor for listbox.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_listbox(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ char bu[64]; /* Buffer for numeric values. */
+
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 1, co);
+ if(co->nChoices != -1) {
+ dkct_gui_next_argument(psrc);
+ sprintf(bu, "%d", co->nChoices);
+ fputs(bu, psrc->fipo);
+ }
+ dkct_gui_next_argument(psrc);
+ if(co->choices) {
+ fputs(co->choices, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[100], psrc->fipo);
+ }
+ /* Style */
+ dkct_gui_next_argument(psrc);
+ switch(co->selStyle) {
+ case DKCT_GUI_SELECTION_STYLE_EXTENDED: {
+ fputs(dkct_gui_out_kw[84], psrc->fipo);
+ } break;
+ case DKCT_GUI_SELECTION_STYLE_MULTIPLE: {
+ fputs(dkct_gui_out_kw[83], psrc->fipo);
+ } break;
+ default: {
+ fputs(dkct_gui_out_kw[82], psrc->fipo);
+ } break;
+ }
+ fputs(dkct_gui_out_kw[85], psrc->fipo);
+ if(co->validator) {
+ dkct_gui_next_argument(psrc);
+ fputs(co->validator, psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write element constructor for checklistbox.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_checklistbox(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ dkct_gui_constructor_listbox(co, dp, pw, psrc, gui);
+}
+
+
+
+/** Write element constructor for radio box.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_radiobox(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ /*
+ parent, id, label, pos, size (1), n (2), choices (3),
+ majordim (4), style (5), validator (6)
+ */
+ int det = 0; /* Details level. */
+ char bu[64]; /* Buffer for numeric values. */
+
+ if((co->sizex > 0) && (co->sizey > 0)) det = 1;
+ if((co->nChoices > 0) || (co->nChoices == -1)) det = 2;
+ if(co->choices) det = 3;
+ if(co->maxRowsCols > 0) det = 4;
+ if(co->rbDirection != DKCT_GUI_RB_DIR_COLUMNS) det = 5;
+ if(co->validator) det = 6;
+
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ dkct_gui_next_argument(psrc);
+ if(co->text) {
+ fputs(co->text, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[73], psrc->fipo);
+ }
+ if(det) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(det > 1) {
+ if(co->nChoices != -1) {
+ dkct_gui_next_argument(psrc);
+ sprintf(bu, "%d", ((co->nChoices > 0) ? co->nChoices : 0));
+ fputs(bu, psrc->fipo);
+ }
+ if(det > 2) {
+ dkct_gui_next_argument(psrc);
+ if(co->choices) {
+ fputs(co->choices, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[100], psrc->fipo);
+ }
+ if(det > 3) {
+ /* Majordim */
+ dkct_gui_next_argument(psrc);
+ sprintf(bu, "%d", (co->maxRowsCols >= 0) ? co->maxRowsCols : 0);
+ fputs(bu, psrc->fipo);
+ if(det > 4) {
+ /* Style */
+ dkct_gui_next_argument(psrc);
+ if(co->rbDirection == DKCT_GUI_RB_DIR_COLUMNS) {
+ fputs(dkct_gui_out_kw[87], psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[86], psrc->fipo);
+ }
+ if(det > 5) {
+ dkct_gui_next_argument(psrc);
+ fputs(co->validator, psrc->fipo);
+ }
+ }
+ }
+ }
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write element constructor for radio button.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_radiobutton(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int det = 0; /* Details level. */
+
+ if((co->sizex > 0) && (co->sizey > 0)) det = 1;
+ if(co->startGroup) det = 2;
+ if(co->validator) det = 3;
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ dkct_gui_next_argument(psrc);
+ if(co->text) {
+ fputs(co->text, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[73], psrc->fipo);
+ }
+ if(det) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(det > 1) {
+ dkct_gui_next_argument(psrc);
+ if(co->startGroup) {
+ fputs(dkct_gui_out_kw[88], psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[52], psrc->fipo);
+ }
+ if(det > 2) {
+ dkct_gui_next_argument(psrc);
+ fputs(co->validator, psrc->fipo);
+ }
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write element constructor for scrollbar.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_scrollbar(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int must_write_details = 0; /* Details level. */
+
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ must_write_details = 0;
+ if((co->sizex > 0) && (co->sizey > 0)) {
+ must_write_details = 1;
+ }
+ if(co->direction != DKCT_GUI_DIRECTION_HORIZONTAL) {
+ must_write_details = 2;
+ }
+ if(co->validator) {
+ must_write_details = 3;
+ }
+ if(must_write_details) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(must_write_details > 1) {
+ dkct_gui_next_argument(psrc);
+ if(co->direction == DKCT_GUI_DIRECTION_HORIZONTAL) {
+ fputs(dkct_gui_out_kw[101], psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[102], psrc->fipo);
+ }
+ if(must_write_details > 2) {
+ dkct_gui_next_argument(psrc);
+ fputs(co->validator, psrc->fipo);
+ }
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write element constructor for spin button.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_spinbutton(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int need_details = 0; /* Details level. */
+
+ if(co->sizex > 0) { need_details = 1; }
+ if(co->sizey > 0) { need_details = 1; }
+ if(co->direction != DKCT_GUI_DIRECTION_HORIZONTAL) { need_details = 2; }
+ if(co->useKeys) { need_details = 2; }
+ if(co->spinWrap) { need_details = 2; }
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ if(need_details) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(need_details > 1) {
+ dkct_gui_next_argument(psrc);
+ if(co->direction == DKCT_GUI_DIRECTION_HORIZONTAL) {
+ fputs(dkct_gui_out_kw[92], psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[93], psrc->fipo);
+ }
+ if(co->useKeys) {
+ fputs(dkct_gui_out_kw[94], psrc->fipo);
+ }
+ if(co->spinWrap) {
+ fputs(dkct_gui_out_kw[95], psrc->fipo);
+ }
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write element constructor for spin control.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_spincontrol(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ char bu[64]; /* Buffer for numeric values. */
+ int need_details = 0; /* Details level. */
+
+ if(co->text) { need_details = 1; }
+ if((co->sizex > 0) && (co->sizey > 0)) { need_details = 2; }
+ if(co->useKeys) { need_details = 3; }
+ if(co->spinWrap) { need_details = 3; }
+ if(co->spinMin != 0) { need_details = 4; }
+ if(co->spinMax != 100) { need_details = 5; }
+ if(co->spinVal != 0) { need_details = 6; }
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ if(need_details) {
+ dkct_gui_next_argument(psrc);
+ if(co->text) {
+ fputs(co->text, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[73], psrc->fipo);
+ }
+ if(need_details > 1) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(need_details > 2) {
+ dkct_gui_next_argument(psrc);
+ if(co->useKeys) {
+ if(co->spinWrap) {
+ fputs(dkct_gui_out_kw[96], psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[97], psrc->fipo);
+ }
+ } else {
+ if(co->spinWrap) {
+ fputs(dkct_gui_out_kw[98], psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[52], psrc->fipo);
+ }
+ }
+ if(need_details > 3) {
+ dkct_gui_next_argument(psrc);
+ sprintf(bu, "%d", co->spinMin);
+ fputs(bu, psrc->fipo);
+ if(need_details > 4) {
+ dkct_gui_next_argument(psrc);
+ sprintf(bu, "%d", co->spinMax);
+ fputs(bu, psrc->fipo);
+ if(need_details > 5) {
+ dkct_gui_next_argument(psrc);
+ sprintf(bu, "%d", co->spinVal);
+ fputs(bu, psrc->fipo);
+ }
+ }
+ }
+ }
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write integer value.
+ @param fipo Output file.
+ @param i Value to write.
+*/
+static
+void
+dkct_gui_write_int_arg(FILE *fipo, int i)
+{
+ char bu[64];
+ sprintf(bu, "%d", i);
+ fputs(bu, fipo);
+}
+
+
+
+
+
+/** Write element constructor for slider.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_slider(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int det = 0; /* Details level. */
+ /*
+ parent, id, value, min, max, pos, size (1), style (2), validator (3)
+ */
+ if((co->sizex > 0) && (co->sizey > 0)) det = 1;
+ if(co->sliderStyle) det = 2;
+ if(co->direction != DKCT_GUI_DIRECTION_HORIZONTAL) det = 2;
+ if(co->validator) det = 3;
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_int_arg(psrc->fipo, co->spinVal);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_int_arg(psrc->fipo, co->spinMin);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_int_arg(psrc->fipo, co->spinMax);
+ if(det) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(det > 1) {
+ if(co->direction == DKCT_GUI_DIRECTION_HORIZONTAL) {
+ fputs(dkct_gui_out_kw[103], psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[104], psrc->fipo);
+ }
+ if((co->sliderStyle) & DKCT_GUI_SL_STYLE_AUTOTICKS) {
+ fputs(dkct_gui_out_kw[105], psrc->fipo);
+ }
+ if((co->sliderStyle) & DKCT_GUI_SL_STYLE_LABELS) {
+ fputs(dkct_gui_out_kw[106], psrc->fipo);
+ }
+ if((co->sliderStyle) & DKCT_GUI_SL_STYLE_LEFT) {
+ fputs(dkct_gui_out_kw[107], psrc->fipo);
+ }
+ if((co->sliderStyle) & DKCT_GUI_SL_STYLE_RIGHT) {
+ fputs(dkct_gui_out_kw[108], psrc->fipo);
+ }
+ if((co->sliderStyle) & DKCT_GUI_SL_STYLE_TOP) {
+ fputs(dkct_gui_out_kw[109], psrc->fipo);
+ }
+ if((co->sliderStyle) & DKCT_GUI_SL_STYLE_BOTTOM) {
+ fputs(dkct_gui_out_kw[110], psrc->fipo);
+ }
+ if((co->sliderStyle) & DKCT_GUI_SL_STYLE_SELRANGE) {
+ fputs(dkct_gui_out_kw[111], psrc->fipo);
+ }
+ if((co->sliderStyle) & DKCT_GUI_SL_STYLE_INVERSE) {
+ fputs(dkct_gui_out_kw[112], psrc->fipo);
+ }
+ if(det > 2) {
+ dkct_gui_next_argument(psrc);
+ fputs(co->validator, psrc->fipo);
+ }
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write element constructor text control
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_textctrl(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int det = 0; /* Details level. */
+ int fe = 0; /* Flag: Found entry. */
+ /*
+ parent, id, value (1), pos, size (2), style (3), validator (4)
+ */
+ if(co->text) det = 1;
+ if((co->sizex > 0) && (co->sizey > 0)) det = 2;
+ if(co->textStyle) det = 3;
+ if(co->validator) det = 4;
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ if(det) {
+ dkct_gui_next_argument(psrc);
+ if(co->text) {
+ fputs(co->text, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[73], psrc->fipo);
+ }
+ if(det > 1) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(det > 2) {
+ dkct_gui_next_argument(psrc);
+ if((co->textStyle) & DKCT_GUI_TEXT_ENTER) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[121], psrc->fipo);
+ }
+ if((co->textStyle) & DKCT_GUI_TEXT_TAB) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[122], psrc->fipo);
+ }
+ if((co->textStyle) & DKCT_GUI_TEXT_MULTILINE) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[123], psrc->fipo);
+ }
+ if((co->textStyle) & DKCT_GUI_TEXT_PASSWORD) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[124], psrc->fipo);
+ }
+ if((co->textStyle) & DKCT_GUI_TEXT_READONLY) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[125], psrc->fipo);
+ }
+ if((co->textStyle) & DKCT_GUI_TEXT_RICH) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[126], psrc->fipo);
+ }
+ if((co->textStyle) & DKCT_GUI_TEXT_RICH2) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[127], psrc->fipo);
+ }
+ if((co->textStyle) & DKCT_GUI_TEXT_URL) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[128], psrc->fipo);
+ }
+ if((co->textStyle) & DKCT_GUI_TEXT_SHOWSEL) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[129], psrc->fipo);
+ }
+ if((co->textStyle) & DKCT_GUI_TEXT_LEFT) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[130], psrc->fipo);
+ }
+ if((co->textStyle) & DKCT_GUI_TEXT_CENTRE) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[131], psrc->fipo);
+ }
+ if((co->textStyle) & DKCT_GUI_TEXT_RIGHT) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[132], psrc->fipo);
+ }
+ if((co->textStyle) & DKCT_GUI_TEXT_NOWRAP) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[133], psrc->fipo);
+ }
+ if((co->textStyle) & DKCT_GUI_TEXT_CHARWRAP) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[134], psrc->fipo);
+ }
+ if((co->textStyle) & DKCT_GUI_TEXT_WORDWRAP) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[135], psrc->fipo);
+ }
+ if((co->textStyle) & DKCT_GUI_TEXT_BESTWRAP) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[136], psrc->fipo);
+ }
+ if((co->textStyle) & DKCT_GUI_TEXT_CAPITALIZE) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); } fe = 1;
+ fputs(dkct_gui_out_kw[137], psrc->fipo);
+ }
+ if(!(fe)) { fputs(dkct_gui_out_kw[52], psrc->fipo); }
+ }
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write element constructor toggle button.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_togglebutton(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int det = 0; /* Details level. */
+ /*
+ parent, id, label, pos, size (1), style (2), validator (3)
+ */
+ if((co->sizex > 0) && (co->sizey > 0)) det = 1;
+ if(co->validator) det = 3;
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ dkct_gui_next_argument(psrc);
+ if(co->text) {
+ fputs(co->text, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[73], psrc->fipo);
+ }
+ if(det) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(det > 1) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[52], psrc->fipo);
+ if(det > 2) {
+ dkct_gui_next_argument(psrc);
+ fputs(co->validator, psrc->fipo);
+ }
+ }
+ }
+}
+
+
+
+/** Write element constructor for gauge.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_gauge(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int det = 0; /* Details level. */
+ char bu[64]; /* Buffer for numeric values. */
+ /*
+ parent, id, range, pos, size (1), style (2), validator (3)
+ */
+ if((co->sizex > 0) && (co->sizey > 0)) det = 1;
+ if(co->direction != DKCT_GUI_DIRECTION_HORIZONTAL) det = 2;
+ if(co->gaugeStyle) det = 2;
+ if(co->validator) det = 3;
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ sprintf(bu, "%d", co->spinMax);
+ dkct_gui_next_argument(psrc);
+ fputs(bu, psrc->fipo);
+ if(det) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(det > 1) {
+ dkct_gui_next_argument(psrc);
+ if(co->direction == DKCT_GUI_DIRECTION_HORIZONTAL) {
+ fputs(dkct_gui_out_kw[160], psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[161], psrc->fipo);
+ }
+ if((co->gaugeStyle) & DKCT_GUI_GAUGE_SMOOTH) {
+ fputs(dkct_gui_out_kw[162], psrc->fipo);
+ }
+ if(det > 2) {
+ dkct_gui_next_argument(psrc);
+ fputs(co->validator, psrc->fipo);
+ }
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write element constructor for static text.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_statictext(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ unsigned long mask; /* Mask for check. */
+ int det = 0; /* Details level. */
+ int fe = 0; /* Flag: Found entry. */
+ /*
+ parent, id, label, pos, size (1), style (2)
+ */
+ if((co->sizex > 0) && (co->sizey > 0)) det = 1;
+ mask = DKCT_GUI_TEXT_LEFT;
+ mask |= DKCT_GUI_TEXT_CENTRE;
+ mask |= DKCT_GUI_TEXT_RIGHT;
+ mask |= DKCT_GUI_TEXT_NO_AUTORESIZE;
+ if((co->textStyle) & mask) det = 2;
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ dkct_gui_next_argument(psrc);
+ if(co->text) {
+ fputs(co->text, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[73], psrc->fipo);
+ }
+ if(det) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(det > 1) {
+ dkct_gui_next_argument(psrc);
+ if((co->textStyle) & DKCT_GUI_TEXT_LEFT) {
+ fputs(dkct_gui_out_kw[45], psrc->fipo); fe = 1;
+ } else {
+ if((co->textStyle) & DKCT_GUI_TEXT_CENTRE) {
+ fputs(dkct_gui_out_kw[163], psrc->fipo); fe = 1;
+ } else {
+ if((co->textStyle) & DKCT_GUI_TEXT_RIGHT) {
+ fputs(dkct_gui_out_kw[47], psrc->fipo); fe = 1;
+ }
+ }
+ }
+ if((co->textStyle) & DKCT_GUI_TEXT_NOWRAP) {
+ if(fe) { fputs(dkct_gui_out_kw[44], psrc->fipo); }
+ fputs(dkct_gui_out_kw[164], psrc->fipo);
+ fe = 1;
+ }
+ if(!(fe)) { fputs(dkct_gui_out_kw[52], psrc->fipo); }
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write element constructor for static bitmap.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_staticbitmap(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int det = 0; /* Details level. */
+ /*
+ parent, id, bitmap, pos, size (1), style (2)
+ */
+ if((co->sizex > 0) && (co->sizey > 0)) det = 1;
+ if(co->bitmapVarName) {
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ dkct_gui_next_argument(psrc);
+ fputs(co->bitmapVarName, psrc->fipo);
+ if(det) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ } else {
+ /* ERROR: No bitmap specified! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 51);
+ }
+}
+
+
+
+/** Write element constructor for static line.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_staticline(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int det = 0; /* Details level. */
+ /*
+ parent, id, pos, size (1), style (2)
+ */
+ if((co->sizex > 0) && (co->sizey > 0)) det = 1;
+ if(co->direction != DKCT_GUI_DIRECTION_HORIZONTAL) det = 2;
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ if(det) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(det > 1) {
+ dkct_gui_next_argument(psrc);
+ if(co->direction == DKCT_GUI_DIRECTION_HORIZONTAL) {
+ fputs(dkct_gui_out_kw[165], psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[166], psrc->fipo);
+ }
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write element constructor for static box.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_staticbox(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int det = 0; /* Details level. */
+ /*
+ parent, id, label, pos, size (1), style (2)
+ */
+ if((co->sizex > 0) && (co->sizey > 0)) det = 1;
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ if(det) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(det > 1) {
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write element constructor for menu bar.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_menubar(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ /*
+ No constructor arguments.
+ */
+}
+
+
+
+/** Write element constructor for menu.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_menu(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ /*
+ No constructor arguments.
+ */
+}
+
+
+
+/** Write element constructor for menu item.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_menuitem(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ /*
+ parent->Append(id, label, helpstring, kind);
+ */
+#if 0
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ if(co->menuItemStyle == DKCT_GUI_MENU_ITEM_SEPARATOR) {
+ fputs(dkct_gui_out_kw[171], psrc->fipo);
+ } else {
+ if(co->idname) {
+ fputs(co->idname, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[171], psrc->fipo);
+ }
+ }
+ dkct_gui_next_argument(psrc);
+ if(co->text) {
+ fputs(co->text, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[73], psrc->fipo);
+ }
+ dkct_gui_next_argument(psrc);
+ if(co->tipText) {
+ fputs(co->tipText, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[73], psrc->fipo);
+ }
+ dkct_gui_next_argument(psrc);
+ switch(co->menuItemStyle) {
+ case DKCT_GUI_MENU_ITEM_SEPARATOR: {
+ fputs(dkct_gui_out_kw[168], psrc->fipo);
+ } break;
+ case DKCT_GUI_MENU_ITEM_CHECK: {
+ fputs(dkct_gui_out_kw[169], psrc->fipo);
+ } break;
+ case DKCT_GUI_MENU_ITEM_RADIO: {
+ fputs(dkct_gui_out_kw[170], psrc->fipo);
+ } break;
+ default: {
+ fputs(dkct_gui_out_kw[167], psrc->fipo);
+ } break;
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+#else
+ if(dp) {
+ if((dp->name) && (co->name)) {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[194], psrc->fipo);
+ fputs(dp->name, psrc->fipo);
+ switch(co->menuItemStyle) {
+ case DKCT_GUI_MENU_ITEM_SEPARATOR: {
+ fputs(dkct_gui_out_kw[193], psrc->fipo);
+ } break;
+ case DKCT_GUI_MENU_ITEM_CHECK: {
+ fputs(dkct_gui_out_kw[191], psrc->fipo);
+ } break;
+ case DKCT_GUI_MENU_ITEM_RADIO: {
+ fputs(dkct_gui_out_kw[192], psrc->fipo);
+ } break;
+ default: {
+ fputs(dkct_gui_out_kw[184], psrc->fipo);
+ } break;
+ }
+ if(co->menuItemStyle != DKCT_GUI_MENU_ITEM_SEPARATOR) {
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ if(co->idname) {
+ fputs(co->idname, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[171], psrc->fipo);
+ }
+ dkct_gui_next_argument(psrc);
+ if(co->text) {
+ fputs(co->text, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[73], psrc->fipo);
+ }
+ dkct_gui_next_argument(psrc);
+ if(co->tipText) {
+ fputs(co->tipText, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[73], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+ }
+#endif
+}
+
+
+
+/** Write element constructor for menu item.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_toolbartoolbase(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ /*
+ id, text, bitmap, disbitmap (1), kind (2), tip (3)
+ */
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ if(co->menuItemStyle != DKCT_GUI_MENU_ITEM_SEPARATOR) {
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[194], psrc->fipo);
+ }
+ fputs(dp->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[185], psrc->fipo);
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_idname(co, psrc);
+ dkct_gui_next_argument(psrc);
+ if(co->text) {
+ fputs(co->text, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[73], psrc->fipo);
+ }
+ dkct_gui_next_argument(psrc);
+ fputs(co->bitmapVarName, psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ if(co->bitmapDisabled) {
+ fputs(co->bitmapDisabled, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[186], psrc->fipo);
+ }
+ /* ITEM KIND */
+ dkct_gui_next_argument(psrc);
+ switch(co->menuItemStyle) {
+ case DKCT_GUI_MENU_ITEM_SEPARATOR: {
+ fputs(dkct_gui_out_kw[169], psrc->fipo);
+ } break;
+ case DKCT_GUI_MENU_ITEM_CHECK: {
+ fputs(dkct_gui_out_kw[169], psrc->fipo);
+ } break;
+ case DKCT_GUI_MENU_ITEM_RADIO: {
+ fputs(dkct_gui_out_kw[170], psrc->fipo);
+ } break;
+ default: {
+ fputs(dkct_gui_out_kw[167], psrc->fipo);
+ } break;
+ }
+ if(co->tipText) {
+ dkct_gui_next_argument(psrc);
+ fputs(co->tipText, psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write element constructor for tool bar.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_toolbar(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ int det = 0; /* Details level. */
+ /*
+ parent, id, pos, size (1), style (2)
+ */
+ if((co->sizex > 0) && (co->sizey > 0)) det = 1;
+ if(co->direction != DKCT_GUI_DIRECTION_HORIZONTAL) det = 2;
+ if(co->toolbarStyle != DKCT_GUI_TOOLBAR_FLAT) det = 2;
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+#if 0
+ dkct_gui_write_parent_name(pw, psrc, gui);
+#endif
+ if(dp) {
+ if(dp->name) {
+ fputs(dp->name, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[65], psrc->fipo);
+ }
+ } else {
+ fputs(dkct_gui_out_kw[65], psrc->fipo);
+ }
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ if(det) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(det > 1) {
+ dkct_gui_next_argument(psrc);
+ switch(co->direction) {
+ case DKCT_GUI_DIRECTION_VERTICAL: {
+ fputs(dkct_gui_out_kw[173], psrc->fipo);
+ } break;
+ default: {
+ fputs(dkct_gui_out_kw[172], psrc->fipo);
+ } break;
+ }
+ if((co->toolbarStyle) & DKCT_GUI_TOOLBAR_FLAT) {
+ fputs(dkct_gui_out_kw[174], psrc->fipo);
+ }
+ if((co->toolbarStyle) & DKCT_GUI_TOOLBAR_DOCKABLE) {
+ fputs(dkct_gui_out_kw[175], psrc->fipo);
+ }
+ if((co->toolbarStyle) & DKCT_GUI_TOOLBAR_TEXT) {
+ fputs(dkct_gui_out_kw[176], psrc->fipo);
+ }
+ if((co->toolbarStyle) & DKCT_GUI_TOOLBAR_NOICONS) {
+ fputs(dkct_gui_out_kw[177], psrc->fipo);
+ }
+ if((co->toolbarStyle) & DKCT_GUI_TOOLBAR_NODIVIDER) {
+ fputs(dkct_gui_out_kw[178], psrc->fipo);
+ }
+ if((co->toolbarStyle) & DKCT_GUI_TOOLBAR_HORZ_LAYOUT) {
+ if((co->toolbarStyle) & DKCT_GUI_TOOLBAR_TEXT) {
+ if(!((co->toolbarStyle) & DKCT_GUI_TOOLBAR_NOICONS)) {
+ fputs(dkct_gui_out_kw[180], psrc->fipo);
+ }
+ }
+ }
+ if((co->toolbarStyle) & DKCT_GUI_TOOLBAR_NO_TOOLTIPS) {
+ fputs(dkct_gui_out_kw[181], psrc->fipo);
+ }
+ if((co->toolbarStyle) & DKCT_GUI_TOOLBAR_BOTTOM) {
+ fputs(dkct_gui_out_kw[182], psrc->fipo);
+ }
+ if((co->toolbarStyle) & DKCT_GUI_TOOLBAR_RIGHT) {
+ fputs(dkct_gui_out_kw[183], psrc->fipo);
+ }
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+/** Write element constructor for grid.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_grid(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ /* parent, id, pos, size (1), style, name */
+ int det = 0;
+ if((co->sizex > 0) && (co->sizey > 0)) det = 1;
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ if(det) {
+ dkct_gui_next_argument(psrc);
+ fputs(dkct_gui_out_kw[74], psrc->fipo);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ if(det > 1) {
+ }
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+
+
+
+#if 0
+/** Write element constructor (parent, id and text).
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_parent_id_and_text(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ if(co->text) {
+ dkct_gui_next_argument(psrc);
+ fputs(co->text, psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+}
+#endif
+
+
+#if 0
+/** Write element constructor (parent, id and bitmap).
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_constructor_parent_id_and_bitmap(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ if(co->bitmapVarName) {
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ dkct_gui_next_argument(psrc);
+ dkct_gui_write_idname(co, psrc);
+ if(co->bitmapVarName) {
+ dkct_gui_next_argument(psrc);
+ fputs(co->bitmapVarName, psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ } else {
+ /* ERROR: No bitmap expression specified! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 51);
+ }
+}
+#endif
+
+
+
+/** Write instruction to set bitmap.
+ @param co Current object.
+ @param psrc Source structure.
+ @param szind Index of method name.
+ @param bm Bitmap value.
+*/
+static
+void
+dkct_gui_write_set_bitmap(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_SRC *psrc,
+ size_t szind,
+ char *bm
+)
+{
+ if(co->name) {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[szind], psrc->fipo);
+ fputs(bm, psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+}
+
+
+
+/** Write element constructor and add element to parent
+ object or sizer.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_finalize_after_constructor(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ DKCT_GRID_HEAD *gh = NULL;
+ DKCT_CELL_DATA *pcd = NULL;
+ char const *fnptr = NULL; /* File to use for debug output. */
+ int rows = 0;
+ int columns= 0;
+ $? "+ dkct_gui_finalize_after_constructor"
+ /*
+ Jump to end if construction failed.
+ if(!(object)) {
+ goto dkctGUILayoutFinished;
+ }
+ */
+ fnptr = dkct_tr_get_kw8(((psrc->dkcto).deb == 2) ? 28 : 29);
+ fputs(dkct_gui_out_kw[25], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[26], psrc->fipo);
+ if((psrc->dkcto).deb) {
+ $? ". start debug code"
+ fputs(dkct_tr_get_kw8(24), psrc->fipo);
+ if((psrc->dkcto).win) {
+ fputs(dkct_tr_get_kw8(21), psrc->fipo);
+ /* 16-bit begin */
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_get_kw8(30), psrc->fipo);
+ }
+ if((psrc->dkcto).ts) {
+ if((psrc->dkcto).deb == 2) {
+ fputs(dkct_tr_get_kw8(72), psrc->fipo);
+ } else {
+ fputs(dkct_tr_get_kw8(71), psrc->fipo);
+ }
+ }
+ fputs(dkct_tr_get_kw8(61), psrc->fipo);
+ dkct_tr_show_filename_and_lineno(psrc);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ fputs(dkct_tr_get_kw8(61), psrc->fipo);
+ fputs(dkct_tr_get_kw8(73), psrc->fipo);
+ if(co->name) {
+ fputs(co->name, psrc->fipo);
+ }
+ fputs(dkct_tr_get_kw8(74), psrc->fipo);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_get_kw8(31), psrc->fipo);
+ }
+ /* 16-bit end */
+ fputs(dkct_tr_get_kw8(22), psrc->fipo);
+ }
+ /* 8-bit begin */
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_get_kw8(30), psrc->fipo);
+ }
+ if((psrc->dkcto).ts) {
+ if((psrc->dkcto).deb == 2) {
+ fputs(dkct_tr_get_kw8(70), psrc->fipo);
+ } else {
+ fputs(dkct_tr_get_kw8(32), psrc->fipo);
+ }
+ }
+ fputs(dkct_tr_get_kw8(33), psrc->fipo);
+ dkct_tr_show_filename_and_lineno(psrc);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ fputs(dkct_tr_get_kw8(33), psrc->fipo);
+ fputs(dkct_tr_get_kw8(73), psrc->fipo);
+ if(co->name) {
+ fputs(co->name, psrc->fipo);
+ }
+ fputs(dkct_tr_get_kw8(74), psrc->fipo);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_get_kw8(31), psrc->fipo);
+ }
+ /* 8-bit end */
+ if((psrc->dkcto).win) {
+ fputs(dkct_tr_get_kw8(23), psrc->fipo);
+ }
+ fputs(dkct_tr_get_kw8(25), psrc->fipo);
+ }
+ $? ". end debug code"
+ fputs(dkct_gui_out_kw[27], psrc->fipo);
+ fputs(dkct_gui_out_kw[28], psrc->fipo);
+ /* SUCCESS DEBUG CODE */
+ if((psrc->dkcto).deb) {
+ $? ". start debug code"
+ fputs(dkct_tr_get_kw8(24), psrc->fipo);
+ if((psrc->dkcto).win) {
+ fputs(dkct_tr_get_kw8(21), psrc->fipo);
+ /* 16-bit begin */
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_get_kw8(30), psrc->fipo);
+ }
+ if((psrc->dkcto).ts) {
+ if((psrc->dkcto).deb == 2) {
+ fputs(dkct_tr_get_kw8(72), psrc->fipo);
+ } else {
+ fputs(dkct_tr_get_kw8(71), psrc->fipo);
+ }
+ }
+ fputs(dkct_tr_get_kw8(61), psrc->fipo);
+ dkct_tr_show_filename_and_lineno(psrc);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ fputs(dkct_tr_get_kw8(61), psrc->fipo);
+ fputs(dkct_tr_get_kw8(76), psrc->fipo);
+ if(co->name) {
+ fputs(co->name, psrc->fipo);
+ }
+ fputs(dkct_tr_get_kw8(74), psrc->fipo);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_get_kw8(31), psrc->fipo);
+ }
+ /* 16-bit end */
+ fputs(dkct_tr_get_kw8(22), psrc->fipo);
+ }
+ /* 8-bit begin */
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_get_kw8(30), psrc->fipo);
+ }
+ if((psrc->dkcto).ts) {
+ if((psrc->dkcto).deb == 2) {
+ fputs(dkct_tr_get_kw8(70), psrc->fipo);
+ } else {
+ fputs(dkct_tr_get_kw8(32), psrc->fipo);
+ }
+ }
+ fputs(dkct_tr_get_kw8(33), psrc->fipo);
+ dkct_tr_show_filename_and_lineno(psrc);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ fputs(dkct_tr_get_kw8(33), psrc->fipo);
+ fputs(dkct_tr_get_kw8(76), psrc->fipo);
+ if(co->name) {
+ fputs(co->name, psrc->fipo);
+ }
+ fputs(dkct_tr_get_kw8(74), psrc->fipo);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_get_kw8(31), psrc->fipo);
+ }
+ /* 8-bit end */
+ if((psrc->dkcto).win) {
+ fputs(dkct_tr_get_kw8(23), psrc->fipo);
+ }
+ fputs(dkct_tr_get_kw8(25), psrc->fipo);
+ }
+ /*
+ Further element setup, done *before* we deal with contents.
+ */
+ switch(co->cln) {
+ case 0: { $? ". wxFrame"
+ } break;
+ case 1: { $? ". wxDialog"
+ } break;
+ case 2: { $? ". wxMDIParentFrame"
+ } break;
+ case 3: { $? ". wxMDIChildFrame"
+ } break;
+ case 4: { $? ". wxPopupWindow"
+ } break;
+ case 5: { $? ". wxBoxSizer"
+ } break;
+ case 6: { $? ". wxFlexGridSizer"
+ } break;
+ case 7: { $? ". wxGridBagSizer"
+ } break;
+ case 8: { $? ". wxGridSizer"
+ } break;
+ case 9: { $? ". wxStaticBoxSizer"
+ } break;
+ case 10: { $? ". wxStdDialogButtonSizer"
+ } break;
+ case 11: { $? ". wxPanel"
+ } break;
+ case 12: { $? ". wxNotebook"
+ } break;
+ case 13: { $? ". wxScrolledWindow"
+ /* Set size */
+ } break;
+ case 14: { $? ". wxSplitterWindow"
+ } break;
+ case 15: { $? ". wxButton"
+ } break;
+ case 16: { $? ". wxBitmapButton"
+ if(co->bitmapDisabled) {
+ dkct_gui_write_set_bitmap(co, psrc, 156, co->bitmapDisabled);
+ }
+ if(co->bitmapSelected) {
+ dkct_gui_write_set_bitmap(co, psrc, 157, co->bitmapSelected);
+ }
+ if(co->bitmapFocus) {
+ dkct_gui_write_set_bitmap(co, psrc, 158, co->bitmapFocus);
+ }
+ if(co->bitmapHover) {
+ dkct_gui_write_set_bitmap(co, psrc, 159, co->bitmapHover);
+ }
+ } break;
+ case 17: { $? ". wxChoice"
+ } break;
+ case 18: { $? ". wxComboBox"
+ } break;
+ case 19: { $? ". wxCheckBox"
+ if(co->state != 0x00) {
+ fputs(co->name, psrc->fipo);
+ if(co->nStates == 0x03) {
+ if(co->state == 0x02) {
+ fputs(dkct_gui_out_kw[78], psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[79], psrc->fipo);
+ }
+ } else {
+ fputs(dkct_gui_out_kw[77], psrc->fipo);
+ }
+ }
+ } break;
+ case 20: { $? ". wxListBox"
+ } break;
+ case 21: { $? ". wxCheckListBox"
+ } break;
+ case 22: { $? ". wxRadioBox"
+ } break;
+ case 23: { $? ". wxRadioButton"
+ } break;
+ case 24: { $? ". wxScrollBar"
+ } break;
+ case 25: { $? ". wxSpinButton"
+ } break;
+ case 26: { $? ". wxSpinCtrl"
+ } break;
+ case 27: { $? ". wxSlider"
+ } break;
+ case 28: { $? ". wxTextCtrl"
+ } break;
+ case 29: { $? ". wxToggleButton"
+ } break;
+ case 30: { $? ". wxGauge"
+ } break;
+ case 31: { $? ". wxStaticText"
+ } break;
+ case 32: { $? ". wxStaticBitmap"
+ } break;
+ case 33: { $? ". wxStaticLine"
+ } break;
+ case 34: { $? ". wxStaticBox"
+ } break;
+ case 35: { $? ". wxMenuBar"
+ } break;
+ case 36: { $? ". wxMenu"
+ } break;
+ case 37: { $? ". wxMenuItem"
+ } break;
+ case 38: { $? ". wxToolBar"
+ } break;
+ case 39: { $? ". wxStatusBar"
+ } break;
+ case 41: { $? ". wxGrid"
+ if(co->gridTable) { $? ". SetTable"
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[198], psrc->fipo);
+ fputs(co->gridTable, psrc->fipo);
+ if(co->tableOwner) {
+ fputs(dkct_gui_out_kw[55], psrc->fipo);
+ fputs(dkct_gui_out_kw[199], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ } else { $? ". CreateGrid"
+#if VERSION_BEFORE_20150821
+ rows = columns = 0;
+#endif
+ if(co->nRowHeads > co->nRows) {
+ rows = co->nRowHeads;
+ } else {
+ rows = co->nRows;
+ }
+ if(co->nColumnHeads > co->nColumns) {
+ columns = co->nColumnHeads;
+ } else {
+ columns = co->nColumns;
+ }
+ if(rows < 1) rows = 1;
+ if(columns < 1) columns = 1;
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[200], psrc->fipo);
+ fprintf(psrc->fipo, "%d, %d", rows, columns);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+ if((co->sColumnHeads) && (co->iColumnHeads)) {
+ dk3sto_it_reset(co->iColumnHeads);
+ do {
+ gh = (DKCT_GRID_HEAD *)dk3sto_it_next(co->iColumnHeads);
+ if(gh) {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[201], psrc->fipo);
+ fprintf(psrc->fipo, "%d", gh->elno);
+ fputs(dkct_gui_out_kw[55], psrc->fipo);
+ fputs(gh->text, psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+ } while(gh);
+ }
+ if((co->sRowHeads) && (co->iRowHeads)) {
+ dk3sto_it_reset(co->iRowHeads);
+ do {
+ gh = (DKCT_GRID_HEAD *)dk3sto_it_next(co->iRowHeads);
+ if(gh) {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[202], psrc->fipo);
+ fprintf(psrc->fipo, "%d", gh->elno);
+ fputs(dkct_gui_out_kw[55], psrc->fipo);
+ fputs(gh->text, psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+ } while(gh);
+ }
+ if((co->sCellData) && (co->iCellData)) {
+ dk3sto_it_reset(co->iCellData);
+ do {
+ pcd = (DKCT_CELL_DATA *)dk3sto_it_next(co->iCellData);
+ if (pcd) {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[214], psrc->fipo);
+ fprintf(psrc->fipo, "%d, %d, ", pcd->row, pcd->col);
+ fputs(pcd->text, psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+ } while(NULL != pcd);
+ }
+ if (41 == co->cln) {
+ if (co->gridStyle & DKCT_GUI_GRID_AS_LABEL_ROWS) {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[216], psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+ if (co->gridStyle & DKCT_GUI_GRID_AS_LABEL_COLS) {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[217], psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+ if (co->gridStyle & DKCT_GUI_GRID_AS_DATA) {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[215], psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+ }
+ if((DKCT_GUI_TEXT_READONLY) & (co->textStyle)) {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[203], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+ } break;
+ }
+ /*
+ Minimal size, if any.
+ */
+ if((co->sizemx > 0) && (co->sizemy > 0)) {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[204], psrc->fipo);
+ fprintf(psrc->fipo, "%d, %d", co->sizemx, co->sizemy);
+ fputs(dkct_gui_out_kw[205], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+ $? "- dkct_gui_finalize_after_constructor"
+}
+
+
+
+/** Write constructor arguments start when constructor is given.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+ @param comma Flag: Write a final comma.
+*/
+static
+void
+dkct_gui_constructor_constructor(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui,
+ int comma
+)
+{
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ dkct_gui_write_parent_name(pw, psrc, gui);
+ fputs(dkct_gui_out_kw[209], psrc->fipo);
+ if(co->idname) {
+ fputs(co->idname, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[66], psrc->fipo);
+ }
+ if(comma) {
+ fputs(dkct_gui_out_kw[209], psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+}
+
+
+/** Write element constructor and add element to parent
+ object or sizer.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_write_element_constructor(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ $? "+ dkct_gui_write_element_constructor \"%!8s\"", TR_8STR(co->name)
+ /*
+ Write tests to check constructor prerequisitions.
+ */
+ switch(co->cln) {
+ case 16:
+ case 40:
+ {
+#if 0
+ /*
+ 2011-07-30: Bitmaps are typically compiled-in.
+ */
+ if(co->bitmapVarName) {
+ $? ". write bitmap test for \"%!8s\"", TR_8STR(co->name)
+ fputs(dkct_gui_out_kw[25], psrc->fipo);
+ fputs(co->bitmapVarName, psrc->fipo);
+ fputs(dkct_gui_out_kw[26], psrc->fipo);
+ fputs(dkct_gui_out_kw[27], psrc->fipo);
+ fputs(dkct_gui_out_kw[28], psrc->fipo);
+ }
+#endif
+ } break;
+ }
+ /*
+ Write constructor.
+ object = new class(arguments);
+ */
+ switch(co->cln) {
+ case 37: {
+ if(dp) {
+ if(dp->cln == 36) {
+ if(co->text) {
+ dkct_gui_constructor_menuitem(co, dp, pw, psrc, gui);
+ if(co->menuItemStyle != DKCT_GUI_MENU_ITEM_SEPARATOR) {
+ dkct_gui_finalize_after_constructor(co, dp, pw, psrc, gui);
+ }
+ } else {
+ /* ERROR: No text specified */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 49);
+ }
+ } else { $? "! illegal parent/child"
+ /* ERROR: Parent is not a menu */
+ dkct_gui_report_illegal_parent_child(co, dp, gui->psrc);
+ }
+ } else {
+ /* ERROR: No parent */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 92);
+ }
+ } break;
+ case 40: {
+ if(dp) {
+ if(dp->cln == 38) {
+ if(dp->name) {
+ if(co->bitmapVarName) {
+ if(co->text) {
+ dkct_gui_constructor_toolbartoolbase(co, dp, pw, psrc, gui);
+ if(co->menuItemStyle != DKCT_GUI_MENU_ITEM_SEPARATOR) {
+ dkct_gui_finalize_after_constructor(co, dp, pw, psrc, gui);
+ }
+ } else {
+ /* ERROR: No text */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 49);
+ }
+ } else {
+ /* ERROR: No bitmap */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 51);
+ }
+ } else {
+ /* ERROR: No parent name */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 91);
+ }
+ } else { $? "! illegal parent/child"
+ /* ERROR: Parent is not a toolbar */
+ dkct_gui_report_illegal_parent_child(co, dp, gui->psrc);
+ }
+ } else {
+ /* ERROR: No parent */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 92);
+ }
+ } break;
+ default: {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[23], psrc->fipo);
+ fputs(co->cname, psrc->fipo);
+ fputs(dkct_gui_out_kw[29], psrc->fipo);
+ if(co->constructor) {
+ if(!(co->compConst)) {
+ dkct_gui_constructor_constructor(co,dp,pw,psrc,gui,1);
+ }
+ fputs(co->constructor, psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ switch(co->cln) {
+ case 5:
+ {
+ /* WARNING: Constructor specified, not recommended! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 80);
+ } break;
+ }
+ } else {
+ switch(co->cln) {
+ case 0: { $? ". wxFrame"
+ dkct_gui_constructor_frame_dialog(co,dp,pw,psrc,gui);
+ } break;
+ case 1: { $? ". wxDialog"
+ dkct_gui_constructor_frame_dialog(co,dp,pw,psrc,gui);
+ } break;
+ case 2: { $? ". wxMDIParentFrame"
+ dkct_gui_constructor_frame_dialog(co,dp,pw,psrc,gui);
+ } break;
+ case 3: { $? ". wxMDIChildFrame"
+ dkct_gui_constructor_frame_dialog(co,dp,pw,psrc,gui);
+ } break;
+ case 4: { $? ". wxPopupWindow"
+ } break;
+ case 5: { $? ". wxBoxSizer"
+ dkct_gui_constructor_boxsizer(co, dp, pw, psrc, gui);
+ } break;
+ case 6: { $? ". wxFlexGridSizer"
+ dkct_gui_constructor_gridsizer(co,dp,pw,psrc,gui);
+ } break;
+ case 7: { $? ". wxGridBagSizer"
+ dkct_gui_constructor_gridbagsizer(co,dp,pw,psrc,gui);
+ } break;
+ case 8: { $? ". wxGridSizer"
+ dkct_gui_constructor_gridsizer(co,dp,pw,psrc,gui);
+ } break;
+ case 9: { $? ". wxStaticBoxSizer"
+ dkct_gui_constructor_staticboxsizer(co,dp,pw,psrc,gui);
+ } break;
+ case 10: { $? ". wxStdDialogButtonSizer"
+ /* No constructor arguments at all. */
+ } break;
+ case 11: { $? ". wxPanel"
+ dkct_gui_constructor_panel(co, dp, pw, psrc, gui);
+ } break;
+ case 12: { $? ". wxNotebook"
+ dkct_gui_constructor_notebook(co, dp, pw, psrc, gui);
+ } break;
+ case 13: { $? ". wxScrolledWindow"
+ dkct_gui_constructor_scrolledwindow(co, dp, pw, psrc, gui);
+ } break;
+ case 14: { $? ". wxSplitterWindow"
+ dkct_gui_constructor_splitterwindow(co, dp, pw, psrc, gui);
+ } break;
+ case 15: { $? ". wxButton"
+ dkct_gui_constructor_button(co, dp, pw, psrc, gui);
+ } break;
+ case 16: { $? ". wxBitmapButton"
+ dkct_gui_constructor_bitmapbutton(co, dp, pw, psrc, gui);
+ } break;
+ case 17: { $? ". wxChoice"
+ dkct_gui_constructor_choice_combo(co, dp, pw, psrc, gui, 0);
+ } break;
+ case 18: { $? ". wxComboBox"
+ dkct_gui_constructor_choice_combo(co, dp, pw, psrc, gui, 1);
+ } break;
+ case 19: { $? ". wxCheckBox"
+ dkct_gui_constructor_checkbox(co, dp, pw, psrc, gui);
+ } break;
+ case 20: { $? ". wxListBox"
+ dkct_gui_constructor_listbox(co, dp, pw, psrc, gui);
+ } break;
+ case 21: { $? ". wxCheckListBox"
+ dkct_gui_constructor_checklistbox(co, dp, pw, psrc, gui);
+ } break;
+ case 22: { $? ". wxRadioBox"
+ dkct_gui_constructor_radiobox(co, dp, pw, psrc, gui);
+ } break;
+ case 23: { $? ". wxRadioButton"
+ dkct_gui_constructor_radiobutton(co, dp, pw, psrc, gui);
+ } break;
+ case 24: { $? ". wxScrollBar"
+ dkct_gui_constructor_scrollbar(co, dp, pw, psrc, gui);
+ } break;
+ case 25: { $? ". wxSpinButton"
+ dkct_gui_constructor_spinbutton(co, dp, pw, psrc, gui);
+ } break;
+ case 26: { $? ". wxSpinCtrl"
+ dkct_gui_constructor_spincontrol(co, dp, pw, psrc, gui);
+ } break;
+ case 27: { $? ". wxSlider"
+ dkct_gui_constructor_slider(co, dp, pw, psrc, gui);
+ } break;
+ case 28: { $? ". wxTextCtrl"
+ dkct_gui_constructor_textctrl(co, dp, pw, psrc, gui);
+ } break;
+ case 29: { $? ". wxToggleButton"
+ dkct_gui_constructor_togglebutton(co, dp, pw, psrc, gui);
+ } break;
+ case 30: { $? ". wxGauge"
+ dkct_gui_constructor_gauge(co, dp, pw, psrc, gui);
+ } break;
+ case 31: { $? ". wxStaticText"
+ dkct_gui_constructor_statictext(co, dp, pw, psrc, gui);
+ } break;
+ case 32: { $? ". wxStaticBitmap"
+ dkct_gui_constructor_staticbitmap(co, dp, pw, psrc, gui);
+ } break;
+ case 33: { $? ". wxStaticLine"
+ dkct_gui_constructor_staticline(co, dp, pw, psrc, gui);
+ } break;
+ case 34: { $? ". wxStaticBox"
+ dkct_gui_constructor_staticbox(co, dp, pw, psrc, gui);
+ } break;
+ case 35: { $? ". wxMenuBar"
+ dkct_gui_constructor_menubar(co, dp, pw, psrc, gui);
+ } break;
+ case 36: { $? ". wxMenu"
+ dkct_gui_constructor_menu(co, dp, pw, psrc, gui);
+ } break;
+#if 0
+ case 37: { $? ". wxMenuItem"
+ /*
+ Never happens.
+ */
+ } break;
+#endif
+ case 38: { $? ". wxToolBar"
+ dkct_gui_constructor_toolbar(co, dp, pw, psrc, gui);
+ } break;
+ case 39: { $? ". wxStatusBar"
+ } break;
+ case 41: {
+ dkct_gui_constructor_grid(co, dp, pw, psrc, gui);
+ } break;
+ default: {
+ if(!(co->compConst)) {
+ dkct_gui_constructor_constructor(co,dp,pw,psrc,gui,0);
+ }
+ } break;
+ }
+ }
+ fputs(dkct_gui_out_kw[37], psrc->fipo);
+ dkct_gui_finalize_after_constructor(co, dp, pw, psrc, gui);
+ } break;
+ }
+ $? "- dkct_gui_write_element_constructor"
+}
+
+
+
+/** Add pseudo object.
+ @param co Current object.
+ @param dp Direct parent.
+ @param pw Parent window.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_add_pseudo_object(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_GUI_ELEMENT *pw,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ char bu[256]; /* Buffer for numeric values. */
+ $? "+ dkct_gui_add_pseudo_object \"%!8s\"", TR_8STR(co->name)
+ if(dp) {
+ switch(dp->cln) {
+ case 7: { /* gridbag sizer */
+ switch(co->pseudoobj) {
+ case 1: case 2: { $? ". x=%d y=%d", co->sizex, co->sizey
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ if(dp->name) {
+ fputs(dp->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[31], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[196], psrc->fipo);
+ sprintf(bu, "%d", co->sizex);
+ fputs(bu, psrc->fipo);
+ fputs(dkct_gui_out_kw[55], psrc->fipo);
+ sprintf(bu, "%d", co->sizey);
+ fputs(bu, psrc->fipo);
+ fputs(dkct_gui_out_kw[55], psrc->fipo);
+ /* wxGBPosition() */
+ sprintf(bu, "%d, %d", co->posy, co->posx);
+ fputs(dkct_gui_out_kw[53], psrc->fipo);
+ fputs(bu, psrc->fipo);
+ fputs(dkct_gui_out_kw[56], psrc->fipo);
+ fputs(dkct_gui_out_kw[55], psrc->fipo);
+ sprintf(bu, "%d, %d", co->spany, co->spanx);
+ fputs(dkct_gui_out_kw[54], psrc->fipo);
+ fputs(bu, psrc->fipo);
+ fputs(dkct_gui_out_kw[56], psrc->fipo);
+#if 0
+ /* 2011-07-30: No wxGROW flag for spacers. */
+ if(co->expandFlag) {
+ fputs(dkct_gui_out_kw[55], psrc->fipo);
+ fputs(dkct_gui_out_kw[51], psrc->fipo);
+ }
+#endif
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ } break;
+ default: {
+ /* ERROR: Can not add this class to parent! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 81);
+ } break;
+ }
+ } break;
+ case 5: case 6: case 8: case 9: case 10: { /* other sizers */
+ /*
+ parent->Add(width, height, proportion, flags);
+ */
+ switch(co->pseudoobj) {
+ case 1: case 2: { $? ". x=%d y=%d", co->sizex, co->sizey
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ if(dp->name) {
+ fputs(dp->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[31], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[196], psrc->fipo);
+ sprintf(bu, "%d", co->sizex);
+ fputs(bu, psrc->fipo);
+ fputs(dkct_gui_out_kw[55], psrc->fipo);
+ sprintf(bu, "%d", co->sizey);
+ fputs(bu, psrc->fipo);
+ fputs(dkct_gui_out_kw[55], psrc->fipo);
+ sprintf(bu, "%d", co->proportion);
+ fputs(bu, psrc->fipo);
+#if 0
+ /* 2011-07-30: No wxGROW flag for stretch and spacers. */
+ if(co->expandFlag) {
+ fputs(dkct_gui_out_kw[55], psrc->fipo);
+ fputs(dkct_gui_out_kw[51], psrc->fipo);
+ }
+#endif
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ } break;
+ default: {
+ /* ERROR: Can not add this class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 81);
+ } break;
+ }
+ } break;
+ case 36: { /* menu */
+ switch(co->pseudoobj) {
+ case 3: {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ if(dp->name) {
+ fputs(dp->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[31], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[188], psrc->fipo);
+ } break;
+ default: {
+ /* ERROR: Can not add this class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 81);
+ } break;
+ }
+ } break;
+ case 38: { /* tool bar */
+ switch(co->pseudoobj) {
+ case 3: {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ if(dp->name) {
+ fputs(dp->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[31], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[189], psrc->fipo);
+ } break;
+ default: {
+ /* ERROR: Can not add this class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 81);
+ } break;
+ }
+ } break;
+ }
+ }
+ $? "- dkct_gui_add_pseudo_object"
+}
+
+
+
+/** Finish wxSplitterWindow after finishing the contents.
+ @param co Current object.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_finish_splitter_window(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ char bu[64]; /* Buffer for numeric values. */
+ DKCT_GUI_ELEMENT *a = NULL; /* First child window. */
+ DKCT_GUI_ELEMENT *b = NULL; /* Second child window. */
+ char *na = NULL; /* Name of first child. */
+ char *nb = NULL; /* Name of second child. */
+ char *nc = NULL; /* Current objects name. */
+ dk3sto_it_reset(co->i_contents);
+ a = (DKCT_GUI_ELEMENT *)dk3sto_it_next(co->i_contents);
+ if(a) {
+ b = (DKCT_GUI_ELEMENT *)dk3sto_it_next(co->i_contents);
+ if(b) {
+ if(dk3sto_it_next(co->i_contents)) {
+ /* ERROR: Too many elements for splitter window */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 47);
+ }
+ }
+ }
+ if(a) { na = a->name; }
+ if(b) { nb = b->name; }
+ nc = co->name;
+ if((na) && (nb)) {
+ /*
+ if((na) && (nb)) {
+ nc->SplitHorizontally(na, nb, sash);
+ }
+ */
+ } else {
+ /* ERROR: Too few contents for splitter window. */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 47);
+ }
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(dkct_gui_out_kw[67], psrc->fipo);
+ fputs(na, psrc->fipo);
+ fputs(dkct_gui_out_kw[68], psrc->fipo);
+ fputs(nb, psrc->fipo);
+ fputs(dkct_gui_out_kw[69], psrc->fipo);
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ fputs(nc, psrc->fipo);
+ fputs(dkct_gui_out_kw[31], psrc->fipo);
+ if(co->direction == DKCT_GUI_DIRECTION_VERTICAL) {
+ fputs(dkct_gui_out_kw[70], psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[71], psrc->fipo);
+ }
+ fputs(na, psrc->fipo);
+ fputs(dkct_gui_out_kw[55], psrc->fipo);
+ fputs(nb, psrc->fipo);
+ fputs(dkct_gui_out_kw[55], psrc->fipo);
+ sprintf(bu, "%d", co->sash);
+ fputs(bu, psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(dkct_gui_out_kw[64], psrc->fipo);
+ if(co->minPaneSize > 0) {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(nc, psrc->fipo);
+ fputs(dkct_gui_out_kw[72], psrc->fipo);
+ sprintf(bu, "%d", co->minPaneSize);
+ fputs(bu, psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+}
+
+
+
+/** Finish setup of current element after setting up all children.
+ @param co Current object.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_finish_current_element(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_SRC *psrc,
+ DKCT_GUI *gui
+)
+{
+ $? "+ dkct_gui_finish_current_element"
+ /*
+ Class-dependant finish.
+ */
+ switch(co->cln) {
+ case 10: /* standard dialog button sizer */
+ case 38: /* toolbar */
+ { $? ". standard dialog button sizer"
+ /*
+ Call ->Realize() for the standard diaglog button sizer.
+ */
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[80], psrc->fipo);
+ } break;
+ case 14: { $? ". splitter window"
+ /*
+ Set wxSplitterWindow children and sash.
+ */
+ dkct_gui_finish_splitter_window(co, psrc, gui);
+ } break;
+ }
+ /*
+ Attribute-dependant finish.
+ */
+ if(co->text) {
+ switch(co->cln) {
+ case -1: {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ if(co->name) {
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[31], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[210], psrc->fipo);
+ fputs(co->text, psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ } break;
+ }
+ }
+ if(co->tipText) { $? ". tip text"
+ switch(co->cln) {
+ case 36: /* wxMenu */
+ case 37: /* wxMenuItem */
+ case 40: /* $wxToolBarTool */
+ {
+ /* Tip text already used. */
+ } break;
+ default: { $? ". show tip text"
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ if ((NULL != co->ttflag) || (NULL != gui->ttflag)) {
+ fputs(dkct_gui_out_kw[218], psrc->fipo);
+ if (NULL != co->ttflag) {
+ fputs(co->ttflag, psrc->fipo);
+ } else {
+ fputs(gui->ttflag, psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[219], psrc->fipo);
+ }
+ if(co->name) {
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[31], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[190], psrc->fipo);
+ fputs(co->tipText, psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ if ((NULL != co->ttflag) || (NULL != gui->ttflag)) {
+ fputs(dkct_gui_out_kw[64], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ } break;
+ }
+ }
+ if(co->icon) {
+ if((co->parent) || (co->number)) {
+ /* Warning: Icon only for root level windows. */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_WARNING, 55);
+ }
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ if(co->name) {
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[31], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[195], psrc->fipo);
+ fputs(co->icon, psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+ if(co->validator) {
+ switch(co->cln) {
+ case -1: {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ if(co->name) {
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[31], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[211], psrc->fipo);
+ fputs(co->validator, psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ } break;
+ }
+ }
+ if((co->sizex > 0) && (co->sizey > 0)) {
+ switch(co->cln) {
+ case -1: {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ if(co->name) {
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[31], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[212], psrc->fipo);
+ dkct_gui_write_size(psrc, co->sizex, co->sizey, 0, co);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ } break;
+ }
+ }
+ $? "- dkct_gui_finish_current_element"
+}
+
+
+
+#if 0
+/** Add item to toolbar.
+ This function is not longer needed as the
+ AddTool() method is used as the constructor
+ for wxToolBarToolBase.
+ @param co Item to add.
+ @param dp Toolbar to add to.
+ @param psrc Source structure.
+*/
+static
+void
+dkct_gui_add_tool_bar_item(
+ DKCT_GUI_ELEMENT *co,
+ DKCT_GUI_ELEMENT *dp,
+ DKCT_SRC *psrc
+)
+{
+}
+#endif
+
+
+
+/** Construct all members and add them.
+ @param psrc Source structure.
+ @param gui GUI description.
+*/
+static
+void
+dkct_gui_write_members(DKCT_SRC *psrc, DKCT_GUI *gui)
+{
+ DKCT_GUI_ELEMENT *co; /* Current object. */
+ DKCT_GUI_ELEMENT *dp; /* Direct parent. */
+ DKCT_GUI_ELEMENT *pw; /* Parent window. */
+ DKCT_GUI_ELEMENT *ne; /* Next element. */
+ char const *fnptr = NULL; /* File to use for debug output. */
+ int pprost; /* Parent output state. */
+ int pcln; /* Parent class name. */
+ $? "+ dkct_gui_write_members"
+ fnptr = dkct_tr_get_kw8(((psrc->dkcto).deb == 2) ? 28 : 29);
+ co = gui->r_el;
+ if(co->cln != 1) {
+ psrc->lineno = 1UL;
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(dkct_gui_out_kw[33], psrc->fipo);
+ fputs(dkct_gui_out_kw[25], psrc->fipo);
+ fputs(dkct_gui_out_kw[30], psrc->fipo);
+ fputs(dkct_gui_out_kw[26], psrc->fipo);
+ /* DEBUG OUTPUT */
+ if((psrc->dkcto).deb) {
+ $? ". start debug code"
+ fputs(dkct_tr_get_kw8(24), psrc->fipo);
+ if((psrc->dkcto).win) {
+ fputs(dkct_tr_get_kw8(21), psrc->fipo);
+ /* 16-bit begin */
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_get_kw8(30), psrc->fipo);
+ }
+ if((psrc->dkcto).ts) {
+ if((psrc->dkcto).deb == 2) {
+ fputs(dkct_tr_get_kw8(72), psrc->fipo);
+ } else {
+ fputs(dkct_tr_get_kw8(71), psrc->fipo);
+ }
+ }
+ fputs(dkct_tr_get_kw8(61), psrc->fipo);
+ dkct_tr_show_filename_and_lineno(psrc);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ fputs(dkct_tr_get_kw8(61), psrc->fipo);
+ fputs(dkct_tr_get_kw8(73), psrc->fipo);
+ fputs(dkct_tr_get_kw8(75), psrc->fipo);
+ fputs(dkct_tr_get_kw8(74), psrc->fipo);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_get_kw8(31), psrc->fipo);
+ }
+ /* 16-bit end */
+ fputs(dkct_tr_get_kw8(22), psrc->fipo);
+ }
+ /* 8-bit begin */
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_get_kw8(30), psrc->fipo);
+ }
+ if((psrc->dkcto).ts) {
+ if((psrc->dkcto).deb == 2) {
+ fputs(dkct_tr_get_kw8(70), psrc->fipo);
+ } else {
+ fputs(dkct_tr_get_kw8(32), psrc->fipo);
+ }
+ }
+ fputs(dkct_tr_get_kw8(33), psrc->fipo);
+ dkct_tr_show_filename_and_lineno(psrc);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ fputs(dkct_tr_get_kw8(33), psrc->fipo);
+ fputs(dkct_tr_get_kw8(73), psrc->fipo);
+ fputs(dkct_tr_get_kw8(75), psrc->fipo);
+ fputs(dkct_tr_get_kw8(74), psrc->fipo);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_get_kw8(31), psrc->fipo);
+ }
+ /* 8-bit end */
+ if((psrc->dkcto).win) {
+ fputs(dkct_tr_get_kw8(23), psrc->fipo);
+ }
+ fputs(dkct_tr_get_kw8(25), psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[27], psrc->fipo);
+ fputs(dkct_gui_out_kw[28], psrc->fipo);
+ if((psrc->dkcto).deb) {
+ $? ". start debug code"
+ fputs(dkct_tr_get_kw8(24), psrc->fipo);
+ if((psrc->dkcto).win) {
+ fputs(dkct_tr_get_kw8(21), psrc->fipo);
+ /* 16-bit begin */
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_get_kw8(30), psrc->fipo);
+ }
+ if((psrc->dkcto).ts) {
+ if((psrc->dkcto).deb == 2) {
+ fputs(dkct_tr_get_kw8(72), psrc->fipo);
+ } else {
+ fputs(dkct_tr_get_kw8(71), psrc->fipo);
+ }
+ }
+ fputs(dkct_tr_get_kw8(61), psrc->fipo);
+ dkct_tr_show_filename_and_lineno(psrc);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ fputs(dkct_tr_get_kw8(61), psrc->fipo);
+ fputs(dkct_tr_get_kw8(76), psrc->fipo);
+ fputs(dkct_tr_get_kw8(75), psrc->fipo);
+ fputs(dkct_tr_get_kw8(74), psrc->fipo);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_get_kw8(31), psrc->fipo);
+ }
+ /* 16-bit end */
+ fputs(dkct_tr_get_kw8(22), psrc->fipo);
+ }
+ /* 8-bit begin */
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_get_kw8(30), psrc->fipo);
+ }
+ if((psrc->dkcto).ts) {
+ if((psrc->dkcto).deb == 2) {
+ fputs(dkct_tr_get_kw8(70), psrc->fipo);
+ } else {
+ fputs(dkct_tr_get_kw8(32), psrc->fipo);
+ }
+ }
+ fputs(dkct_tr_get_kw8(33), psrc->fipo);
+ dkct_tr_show_filename_and_lineno(psrc);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ fputs(dkct_tr_get_kw8(33), psrc->fipo);
+ fputs(dkct_tr_get_kw8(76), psrc->fipo);
+ fputs(dkct_tr_get_kw8(75), psrc->fipo);
+ fputs(dkct_tr_get_kw8(74), psrc->fipo);
+ fputs(dkct_tr_get_kw8(35), psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_get_kw8(34), psrc->fipo);
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_get_kw8(31), psrc->fipo);
+ }
+ /* 8-bit end */
+ if((psrc->dkcto).win) {
+ fputs(dkct_tr_get_kw8(23), psrc->fipo);
+ }
+ fputs(dkct_tr_get_kw8(25), psrc->fipo);
+ }
+ }
+ dk3sto_it_reset(co->i_contents);
+ while(co) { $? ". member \"%!8s\"", TR_8STR(co->name)
+ psrc->lineno = ((co->lndef) > 0UL) ? (co->lndef) : (co->lndecl);
+ dk3app_set_source_line(psrc->app, psrc->lineno);
+ dp = pw = (DKCT_GUI_ELEMENT *)(co->parent);
+ pw = dkct_gui_find_real_parent(pw);
+ switch(co->prost) {
+ case DKCT_GUI_PROCESSING_STATE_START: {
+ if(co->pseudoobj) {
+ /*
+ Pseudo object (stretch spacer, separator...)
+ */
+ dkct_gui_add_pseudo_object(co, dp, pw, psrc, gui);
+ co = (DKCT_GUI_ELEMENT *)(co->parent);
+ } else {
+ /*
+ Real object.
+ */
+ if((co->parent) && (co->name)) {
+ if(dkct_gui_need_element_constructor(co)) {
+ $? ". write \"%!8s\" constructor", TR_8STR(co->name)
+ dkct_gui_write_element_constructor(co, dp, pw, psrc, gui);
+ }
+ }
+ dk3sto_it_reset(co->i_contents);
+ if(co->menubar) { $? ". write \"%!8s\" menubar", TR_8STR(co->name)
+ fputs(dkct_gui_out_kw[19], psrc->fipo);
+ co->prost = DKCT_GUI_PROCESSING_STATE_MENU;
+ co = (DKCT_GUI_ELEMENT *)(co->menubar);
+ } else {
+ if(co->toolbar) { $? ". write \"%!8s\" toolbar", TR_8STR(co->name)
+ fputs(dkct_gui_out_kw[20], psrc->fipo);
+ co->prost = DKCT_GUI_PROCESSING_STATE_TOOL;
+ co = (DKCT_GUI_ELEMENT *)(co->toolbar);
+ } else { $? ". write \"%!8s\" contents", TR_8STR(co->name)
+ co->prost = DKCT_GUI_PROCESSING_STATE_CONTENTS;
+ }
+ }
+ }
+ } break;
+ case DKCT_GUI_PROCESSING_STATE_MENU: {
+ /*
+ Finish menu processing.
+ */
+ fputs(dkct_gui_out_kw[22], psrc->fipo);
+ if(co->toolbar) { $? ". write \"%!8s\" toolbar", TR_8STR(co->name)
+ fputs(dkct_gui_out_kw[20], psrc->fipo);
+ co->prost = DKCT_GUI_PROCESSING_STATE_TOOL;
+ co = (DKCT_GUI_ELEMENT *)(co->toolbar);
+ } else { $? ". write \"%!8s\" contents", TR_8STR(co->name)
+ co->prost = DKCT_GUI_PROCESSING_STATE_CONTENTS;
+ }
+ } break;
+ case DKCT_GUI_PROCESSING_STATE_TOOL: {
+ /*
+ Finish tool bar processing.
+ */
+ fputs(dkct_gui_out_kw[22], psrc->fipo);
+ co->prost = DKCT_GUI_PROCESSING_STATE_CONTENTS; $? ". write \"%!8s\" contents", TR_8STR(co->name)
+ } break;
+ case DKCT_GUI_PROCESSING_STATE_CONTENTS: { $? ". process contents"
+ ne = (DKCT_GUI_ELEMENT *)dk3sto_it_next(co->i_contents); $? ". next"
+ if(ne) { $? ". go down to contents element \"%!8s\" -> \"%!8s\"", TR_8STR(co->name), TR_8STR(ne->name)
+ co = ne;
+ } else { $? ". finished \"%!8s\"", TR_8STR(co->name)
+ co->prost = DKCT_GUI_PROCESSING_STATE_DONE;
+ /*
+ Finish current element.
+ */
+ dkct_gui_finish_current_element(co, psrc, gui);
+ /*
+ Add current element to parent.
+ */
+ if(dkct_gui_is_sizer(co)) {
+ if(dkct_gui_is_sizer((DKCT_GUI_ELEMENT *)(co->parent))) {
+ dkct_gui_add_object_to_sizer(
+ co, (DKCT_GUI_ELEMENT *)(co->parent), psrc, gui
+ );
+ } else {
+ /*
+ parent->SetSizer(object);
+ SetSizer(object);
+ */
+ dkct_gui_set_parents_sizer(
+ co, (DKCT_GUI_ELEMENT *)(co->parent), psrc, gui
+ );
+ }
+ } else {
+ if(dkct_gui_is_sizer((DKCT_GUI_ELEMENT *)(co->parent))) {
+ dkct_gui_add_object_to_sizer(
+ co, (DKCT_GUI_ELEMENT *)(co->parent), psrc, gui
+ );
+ } else {
+ /*
+ Handle special combinations of parent/child classes.
+ */
+ pprost = DKCT_GUI_PROCESSING_STATE_CONTENTS;
+ if(dp) { pprost = dp->prost; }
+ switch(pprost) {
+ /*
+ Add menu bar to root level window.
+ */
+ case DKCT_GUI_PROCESSING_STATE_MENU: {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ if(dp->name) {
+ fputs(dp->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[31], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[57], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ } break;
+ case DKCT_GUI_PROCESSING_STATE_TOOL: {
+ /*
+ Add too lbar to root level window.
+ */
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ if(dp->name) {
+ fputs(dp->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[31], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[58], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ } break;
+ default: {
+ pcln = -1;
+ if(dp) { pcln = dp->cln; }
+ switch(pcln) {
+ case 35: { /* Appending to a menu bar. */
+ switch(co->cln) {
+ case 36: {
+ /*
+ Add menu to menu bar.
+ */
+ if((dp->name) && (co->name)) {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(dp->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[184], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[55], psrc->fipo);
+ if(co->text) {
+ fputs(co->text, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[73], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+ } break;
+ default: {
+ /* ERROR: Illegal child class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 81);
+ } break;
+ }
+ } break;
+ case 36: { /* Appending to a menu. */
+ switch(co->cln) {
+ case 37: {
+ /*
+ Add menu item to menu.
+ */
+#if 0
+ if((dp->name) && (co->name)) {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(dp->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[184], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+#endif
+ } break;
+ case 36: {
+ /*
+ Add sub-menu to menu.
+ */
+ if((dp->name) && (co->name)) {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(dp->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[184], psrc->fipo);
+ dkct_gui_write_idname(co, psrc);
+ fputs(dkct_gui_out_kw[55], psrc->fipo);
+ if(co->text) {
+ fputs(co->text, psrc->fipo);
+ } else {
+ fputs(dkct_gui_out_kw[73], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[55], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ if(co->tipText) {
+ fputs(dkct_gui_out_kw[55], psrc->fipo);
+ fputs(co->tipText, psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+ } break;
+ default: {
+ /* ERROR: Illegal child class! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 81);
+ } break;
+ }
+ } break;
+ case 38: { /* Appending to a tool bar. */
+ switch(co->cln) {
+ case 40: /* wxToolBarToolBase */
+ {
+ } break;
+ default: { /* Any control */
+ if(co->name) {
+ if(dp->name) {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(dp->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[187], psrc->fipo);
+ fputs(co->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+ }
+ } break;
+ }
+ } break;
+ case 14: { /* wxSplitterWindow */
+ /*
+ Do nothing, elements are added when finishing
+ the splitter window.
+ */
+ } break;
+ default: {
+ if((co->number) && (co->parent)) {
+ char const *pname;
+ char const *oname;
+ /* ERROR: Don't know how to add */
+ pname = oname = dkct_gui_out_kw[197];
+ if(co->name) oname = co->name;
+ if(dp) { if(dp->name) pname = dp->name; }
+ dkct_to_log_5(
+ gui->psrc, 1, DK3_LL_ERROR, 84, 85, 86, oname, pname
+ );
+ }
+ } break;
+ }
+ } break;
+ }
+ }
+ }
+ co = (DKCT_GUI_ELEMENT *)(co->parent);
+ }
+ } break;
+ default: {
+ co = (DKCT_GUI_ELEMENT *)(co->parent);
+ } break;
+ }
+ } $? "- dkct_gui_write_members"
+}
+
+
+
+/** Write top level class constructor.
+ @param psrc Source structure.
+*/
+void
+dkct_gui_write_constructor(DKCT_SRC *psrc)
+{
+ char bu[256]; /* Buffer for numeric values. */
+ DKCT_GUI *gui; /* GUI description. */
+ DKCT_GUI_ELEMENT *el; /* Current object. */
+ DKCT_GUI_ELEMENT *szmain; /* Main sizer. */
+ int szfound = 0; /* Flag: Sizer found. */
+ int w = 0; /* Object width. */
+ int h = 0; /* Object height. */
+ if(psrc->gui) {
+ gui = (DKCT_GUI *)(psrc->gui);
+ /*
+ Flag: GUI not ok.
+ */
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(dkct_gui_out_kw[9], psrc->fipo);
+ if(dkct_gui_need_contents_panel(gui)) {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(dkct_gui_out_kw[18], psrc->fipo);
+ }
+ /*
+ Initialize all member variables to NULL.
+ */
+ dk3sto_it_reset(gui->i_el_by_num);
+ while((el = (DKCT_GUI_ELEMENT *)dk3sto_it_next(gui->i_el_by_num)) != NULL) {
+ if(el->pseudoobj == 0) {
+ if(dkct_gui_need_element_constructor(el)) {
+ if((el->name) && (el->cname)) {
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(el->name, psrc->fipo);
+ fputs(dkct_gui_out_kw[14], psrc->fipo);
+ }
+ }
+ }
+ }
+ /*
+ Construct member variables.
+ */
+ dkct_gui_write_members(psrc, gui);
+ /*
+ Flag: GUI ok.
+ */
+ el = gui->r_el;
+ if(el) { $? ". have root element"
+ w = el->sizex; h = el->sizey; $? ". size w=%d h=%d", w, h
+ }
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(dkct_gui_out_kw[10], psrc->fipo);
+ /*
+ End goto label.
+ */
+ fputs(dkct_gui_out_kw[8], psrc->fipo);
+ fputs(dkct_gui_out_kw[11], psrc->fipo);
+ fputs(dkct_gui_out_kw[12], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ if(el) {
+ if(el->stbsz > 0) {
+ /*
+ if wxUSE_STATUSBAR
+ if(dkctGUILayoutOK) {
+ CreateStatusBar(2);
+ SetStatusText(text);
+ }
+ endif
+ */
+ fputs(dkct_gui_out_kw[21], psrc->fipo);
+ fputs(dkct_gui_out_kw[59], psrc->fipo);
+ sprintf(bu, "%d", el->stbsz);
+ fputs(dkct_gui_out_kw[90], psrc->fipo);
+ fputs(bu, psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ if(el->stbText) {
+ fputs(dkct_gui_out_kw[91], psrc->fipo);
+ fputs(el->stbText, psrc->fipo);
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ }
+ fputs(dkct_gui_out_kw[64], psrc->fipo);
+ fputs(dkct_gui_out_kw[22], psrc->fipo);
+ }
+ }
+ /* | if(dkctGUILayoutOK) {| */
+ fputs(dkct_gui_out_kw[59], psrc->fipo);
+ if((w > 0) && (h > 0)) {
+ sprintf(bu, "%d, %d", w, h);
+ /* | wxSize const dkctGUIMinSize(| */
+ fputs(dkct_gui_out_kw[89], psrc->fipo);
+ fputs(bu, psrc->fipo);
+ /* |);| */
+ fputs(dkct_gui_out_kw[24], psrc->fipo);
+ fputs(dkct_gui_out_kw[0], psrc->fipo);
+ /* | SetClientSize(dkctGUIMinSize);| */
+ fputs(dkct_gui_out_kw[62], psrc->fipo);
+ } else {
+ if (NULL != el) {
+ dk3sto_it_reset(el->i_contents);
+ szmain = (DKCT_GUI_ELEMENT *)dk3sto_it_next(el->i_contents);
+ if(NULL != szmain) {
+ switch(szmain->cln) {
+ case 5: case 6: case 7: case 8: case 9: case 10: {
+ if(szmain->name) {
+ /* | | */
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ fputs(szmain->name, psrc->fipo);
+ /* |->Fit(this);| */
+ fputs(dkct_gui_out_kw[63], psrc->fipo);
+ }
+ } break;
+ }
+ }
+ }
+ }
+ szmain = NULL;
+ if (NULL != el) {
+ dk3sto_it_reset(el->i_contents);
+ szmain = (DKCT_GUI_ELEMENT *)dk3sto_it_next(el->i_contents);
+ if(NULL != szmain) {
+ if(NULL != szmain->name) {
+ switch(szmain->cln) {
+ case 5: case 6: case 7: case 8: case 9: case 10: {
+ /* | | */
+ fputs(dkct_gui_out_kw[2], psrc->fipo);
+ fputs(szmain->name, psrc->fipo);
+ /* |->SetSizeHints(this);| */
+ fputs(dkct_gui_out_kw[60], psrc->fipo);
+ szfound = 1;
+ } break;
+ }
+ }
+ }
+ }
+ /* | } */
+ fputs(dkct_gui_out_kw[64], psrc->fipo);
+ if(!(szfound)) {
+ (gui->psrc)->ec = DK3_ERROR_SYNTAX;
+ /* ERROR: No sizer found! */
+ dkct_to_log_1(gui->psrc, 1, DK3_LL_ERROR, 97);
+ }
+ }
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dkct-gui.h b/support/dktools/dkct-gui.h
new file mode 100644
index 0000000000..7690c792ce
--- /dev/null
+++ b/support/dktools/dkct-gui.h
@@ -0,0 +1,631 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dkct-gui.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dkct-gui.h Header file for the dkct-gui module.
+*/
+
+#ifndef DKCT_GUI_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DKCT_GUI_H_INCLUDED 1
+
+
+#line 8 "dkct-gui.ctr"
+
+/** @defgroup dkctguiconst Constants for GUI layout.
+The alignment decides where to place an object if there is more
+room available for the object than necessary.
+*/
+/**@{*/
+
+/** Mask to retrieve horizontal alignment.
+*/
+#define DKCT_GUI_ALIGN_H_MASK 0x03
+
+/** Horizontal alignment: Left.
+*/
+#define DKCT_GUI_ALIGN_H_LEFT 0x01
+
+/** Horizontal alignment: Centered.
+*/
+#define DKCT_GUI_ALIGN_H_CENTER 0x02
+
+/** Horizontal alignment: Right.
+*/
+#define DKCT_GUI_ALIGN_H_RIGHT 0x03
+
+/** Mask to find vertical alignment.
+*/
+#define DKCT_GUI_ALIGN_V_MASK 0x0C
+
+/** Vertical alignment: Top.
+*/
+#define DKCT_GUI_ALIGN_V_TOP 0x04
+
+/** Vertical alignment: Centered.
+*/
+#define DKCT_GUI_ALIGN_V_CENTER 0x08
+
+/** Vertical alignment: bottom.
+*/
+#define DKCT_GUI_ALIGN_V_BOTTOM 0x0C
+
+/** Processing state for element: Nothing done yet.
+*/
+#define DKCT_GUI_PROCESSING_STATE_START 0
+
+/** Processing state for element: Processing the menu bar.
+*/
+#define DKCT_GUI_PROCESSING_STATE_MENU 1
+
+/** Processing state for element: Processing the tool bar.
+*/
+#define DKCT_GUI_PROCESSING_STATE_TOOL 2
+
+/** Processing state for element: Processing the contents.
+*/
+#define DKCT_GUI_PROCESSING_STATE_CONTENTS 3
+
+/** Processing state for element: Finished processing.
+*/
+#define DKCT_GUI_PROCESSING_STATE_DONE 4
+
+/** Left to right sizer.
+*/
+#define DKCT_GUI_DIRECTION_HORIZONTAL 0x00
+
+/** Top to bottom sizer.
+*/
+#define DKCT_GUI_DIRECTION_VERTICAL 0x01
+
+/** Scrollbars for both directions.
+*/
+#define DKCT_GUI_DIRECTION_BOTH 0x02
+
+/** Don't set border pixel number.
+*/
+#define DKCT_GUI_BORDER_POSITION_NONE 0x00
+
+/** Set border pixel number on top side.
+*/
+#define DKCT_GUI_BORDER_POSITION_TOP 0x01
+
+/** Set border pixel number on left side.
+*/
+#define DKCT_GUI_BORDER_POSITION_LEFT 0x02
+
+/** Set border pixel number on right side.
+*/
+#define DKCT_GUI_BORDER_POSITION_RIGHT 0x04
+
+/** Set border pixel number on bottom side.
+*/
+#define DKCT_GUI_BORDER_POSITION_BOTTOM 0x08
+
+/** Set border pixel number on all sides.
+*/
+#define DKCT_GUI_BORDER_POSITION_ALL 0x0F
+
+/** List selection: Allow selection of only one element.
+*/
+#define DKCT_GUI_SELECTION_STYLE_SINGLE 0x00
+
+/** List selection: Allow selection of multiple elements.
+*/
+#define DKCT_GUI_SELECTION_STYLE_MULTIPLE 0x01
+
+/** List selection: Allow CTRL/SHIFT-click.
+*/
+#define DKCT_GUI_SELECTION_STYLE_EXTENDED 0x02
+
+/** Radio box max dimension: columns.
+*/
+#define DKCT_GUI_RB_DIR_COLUMNS 0x00
+
+/** Radio box max dimension: rows.
+*/
+#define DKCT_GUI_RB_DIR_ROWS 0x01
+
+/** Slider style: Automatic tics.
+*/
+#define DKCT_GUI_SL_STYLE_AUTOTICKS 0x01
+
+/** Slider style: Show labels
+*/
+#define DKCT_GUI_SL_STYLE_LABELS 0x02
+
+/** Slider style: Tics left.
+*/
+#define DKCT_GUI_SL_STYLE_LEFT 0x04
+
+/** Slider style: Tics right.
+*/
+#define DKCT_GUI_SL_STYLE_RIGHT 0x08
+
+/** Slider style: Tics top.
+*/
+#define DKCT_GUI_SL_STYLE_TOP 0x10
+
+/** Slider style: Tics bottom.
+*/
+#define DKCT_GUI_SL_STYLE_BOTTOM 0x20
+
+/** Slider style: Range selection allowed.
+*/
+#define DKCT_GUI_SL_STYLE_SELRANGE 0x40
+
+/** Slider style: Inverse endpoints.
+*/
+#define DKCT_GUI_SL_STYLE_INVERSE 0x80
+
+/** Text control style: Enter is line break, not OK command.
+*/
+#define DKCT_GUI_TEXT_ENTER 0x00001UL
+
+/** Text control style: Insert tabulators in text, do not pass to next ctrl.
+*/
+#define DKCT_GUI_TEXT_TAB 0x00002UL
+
+/** Text control style: Multiple lines of text.
+*/
+#define DKCT_GUI_TEXT_MULTILINE 0x00004UL
+
+/** Text control style: Text shown as asterisks.
+*/
+#define DKCT_GUI_TEXT_PASSWORD 0x00008UL
+
+/** Text control style: Not editable.
+*/
+#define DKCT_GUI_TEXT_READONLY 0x00010UL
+
+/** Text control style: Rich-text control.
+*/
+#define DKCT_GUI_TEXT_RICH 0x00020UL
+
+/** Text control style: Richt-text control, higher version.
+*/
+#define DKCT_GUI_TEXT_RICH2 0x00040UL
+
+/** Text control style: Show URLs.
+*/
+#define DKCT_GUI_TEXT_URL 0x00080UL
+
+/** Text control style: Always show selection.
+*/
+#define DKCT_GUI_TEXT_SHOWSEL 0x00100UL
+
+/** Text control style: Left aligned.
+*/
+#define DKCT_GUI_TEXT_LEFT 0x00200UL
+
+/** Text control style: Centered.
+*/
+#define DKCT_GUI_TEXT_CENTRE 0x00400UL
+
+/** Text control style: Right aligned.
+*/
+#define DKCT_GUI_TEXT_RIGHT 0x00800UL
+
+/** Text control style: Do not wrap text.
+*/
+#define DKCT_GUI_TEXT_NOWRAP 0x01000UL
+
+/** Text control style: Wrap characters.
+*/
+#define DKCT_GUI_TEXT_CHARWRAP 0x02000UL
+
+/** Text control style: Wrap at word boundaries.
+*/
+#define DKCT_GUI_TEXT_WORDWRAP 0x04000UL
+
+/** Text control style: Best wrapping.
+*/
+#define DKCT_GUI_TEXT_BESTWRAP 0x08000UL
+
+/** Text control style: Capitalized first letters.
+*/
+#define DKCT_GUI_TEXT_CAPITALIZE 0x10000UL
+
+/** Text control style: No auto-resize.
+*/
+#define DKCT_GUI_TEXT_NO_AUTORESIZE 0x20000UL
+
+/** Notebook style: Tabs on top.
+*/
+#define DKCT_GUI_NB_TOP 0x0001U
+
+/** Notebook style: Tabs on left side.
+*/
+#define DKCT_GUI_NB_LEFT 0x0002U
+
+/** Notebook style: Tabs on right side.
+*/
+#define DKCT_GUI_NB_RIGHT 0x0004U
+
+/** Notebook style: Tabs on bottom.
+*/
+#define DKCT_GUI_NB_BOTTOM 0x0008U
+
+/** Notebook style: Same width for all tabs.
+*/
+#define DKCT_GUI_NB_FIXEDWIDTH 0x0010U
+
+/** Notebook style: Tabs in multiple lines.
+*/
+#define DKCT_GUI_NB_MULTILINE 0x0020U
+
+/** Notebook style: Sold color on notebook pages.
+*/
+#define DKCT_GUI_NB_NOPAGETHEME 0x0040U
+
+/** Notebook style: Show tabs in a flat style.
+*/
+#define DKCT_GUI_NB_FLAT 0x0080U
+
+/** Button style: Label left-justified.
+*/
+#define DKCT_GUI_BUTTON_LEFT 0x01
+
+/** Button style: Label top-justified.
+*/
+#define DKCT_GUI_BUTTON_TOP 0x02
+
+/** Button style: Label right-justified.
+*/
+#define DKCT_GUI_BUTTON_RIGHT 0x04
+
+/** Button style: Label bottom-justified.
+*/
+#define DKCT_GUI_BUTTON_BOTTOM 0x08
+
+/** Button style: Size as small as possible.
+*/
+#define DKCT_GUI_BUTTON_EXACTFIT 0x10
+
+/** Button style: No border.
+*/
+#define DKCT_GUI_BUTTON_NO_BORDER 0x20
+
+/** Splitter window style: 3D border and sash.
+*/
+#define DKCT_GUI_SPLITTERW_3D 0x0001U
+
+/** Splitter window style: 3D sash.
+*/
+#define DKCT_GUI_SPLITTERW_3D_SASH 0x0002U
+
+/** Splitter window style: 3D border.
+*/
+#define DKCT_GUI_SPLITTERW_3D_BORDER 0x0004U
+
+/** Splitter window style: Standard border.
+*/
+#define DKCT_GUI_SPLITTERW_BORDER 0x0008U
+
+/** Splitter window style: No border.
+*/
+#define DKCT_GUI_SPLITTERW_NO_BORDER 0x0010U
+
+/** Splitter window style: No windows XP themes.
+*/
+#define DKCT_GUI_SPLITTERW_NO_XP_THEME 0x0020U
+
+/** Splitter window style: Allow to unsplit.
+*/
+#define DKCT_GUI_SPLITTERW_PERMIT_UNSPLIT 0x0040U
+
+/** Splitter window style: No xor line, resize children immediately.
+*/
+#define DKCT_GUI_SPLITTERW_LIVE_UPDATE 0x0080U
+
+/** Button style: Automatic drawing.
+*/
+#define DKCT_GUI_BBUTTON_AUTODRAW 0x01
+
+/** Button style: Bitmap left-aligned.
+*/
+#define DKCT_GUI_BBUTTON_LEFT 0x02
+
+/** Button style: Bitmap top-aligned.
+*/
+#define DKCT_GUI_BBUTTON_TOP 0x04
+
+/** Button style: Bitmap right-aligned.
+*/
+#define DKCT_GUI_BBUTTON_RIGHT 0x08
+
+/** Button style: Bitmap bottom-aligned.
+*/
+#define DKCT_GUI_BBUTTON_BOTTOM 0x10
+
+/** Gauge style: Smooth.
+*/
+#define DKCT_GUI_GAUGE_SMOOTH 0x01
+
+/** Menu item style: normal.
+*/
+#define DKCT_GUI_MENU_ITEM_NORMAL 0x00
+
+/** Menu item style: separator.
+*/
+#define DKCT_GUI_MENU_ITEM_SEPARATOR 0x01
+
+/** Menu item style: check button.
+*/
+#define DKCT_GUI_MENU_ITEM_CHECK 0x02
+
+/** Menu item style: radio button.
+*/
+#define DKCT_GUI_MENU_ITEM_RADIO 0x03
+
+/** Toolbar style: Flat look (no border).
+*/
+#define DKCT_GUI_TOOLBAR_FLAT 0x0001U
+
+/** Toolbar style: Dockable and floatable.
+*/
+#define DKCT_GUI_TOOLBAR_DOCKABLE 0x0002U
+
+/** Toolbar style: Show text additionally to icons.
+*/
+#define DKCT_GUI_TOOLBAR_TEXT 0x0004U
+
+/** Toolbar style: No icons.
+*/
+#define DKCT_GUI_TOOLBAR_NOICONS 0x0008U
+
+/** Toolbar style: No border above toolbar.
+*/
+#define DKCT_GUI_TOOLBAR_NODIVIDER 0x0010U
+
+/** Toolbar style: No align (not very useful).
+*/
+#define DKCT_GUI_TOOLBAR_NOALIGN 0x0020U
+
+/** Toolbar style: Texts beside icons, not below.
+*/
+#define DKCT_GUI_TOOLBAR_HORZ_LAYOUT 0x0040U
+
+/** Toolbar style: Do not show tool tips.
+*/
+#define DKCT_GUI_TOOLBAR_NO_TOOLTIPS 0x0080U
+
+/** Toolbar style: Bottom side of parent window.
+*/
+#define DKCT_GUI_TOOLBAR_BOTTOM 0x0100U
+
+/** Toolbar style: Right side of parent window.
+*/
+#define DKCT_GUI_TOOLBAR_RIGHT 0x0200U
+
+/** Auto size data cells in wxGrid.
+*/
+#define DKCT_GUI_GRID_AS_DATA 0x0001U
+
+/** Auto size row labels in wxGrid.
+*/
+#define DKCT_GUI_GRID_AS_LABEL_ROWS 0x0002U
+
+/** Auto size column labels in wxGrid.
+*/
+#define DKCT_GUI_GRID_AS_LABEL_COLS 0x0004U
+
+/**@}*/
+
+
+/** Grid head (row head or column head in wxGrid).
+*/
+typedef struct {
+ char *text; /**< Label text. */
+ int elno; /**< Element number. */
+} DKCT_GRID_HEAD;
+
+
+
+/** Cell data for wxGrid contents.
+*/
+typedef struct {
+ char *text; /**< Cell text. */
+ int row; /**< Row number. */
+ int col; /**< Column number. */
+} DKCT_CELL_DATA;
+
+
+
+/** Description for one GUI element.
+*/
+typedef struct {
+ char *name; /**< Variable name. */
+ char *cname; /**< Class name. */
+ char *idname; /**< ID as text. */
+ char *text; /**< Element text (label/button). */
+ char *constructor; /**< Constructor arguments. */
+ char *tipText; /**< Tool tip text. */
+ char *icon; /**< Icon for frame. */
+ char *bitmapVarName; /**< Bitmap variable. */
+ char *bitmapDisabled; /**< Disabled bitmap. */
+ char *bitmapSelected; /**< Selected bitmap. */
+ char *bitmapFocus; /**< Focus bitmap. */
+ char *bitmapHover; /**< Mouse-over bitmap. */
+ char *choices; /**< Choices variable. */
+ char *stbText; /**< Status bar text. */
+ char *validator; /**< Validator. */
+ char *gridTable; /**< Table for grid. */
+ char *ttflag; /**< Tool tip flag. */
+ void *parent; /**< Element's parent. */
+ void *menubar; /**< Menu bar. */
+ void *toolbar; /**< Tool bar. */
+ dk3_sto_t *s_contents; /**< Contents elements storage. */
+ dk3_sto_it_t *i_contents; /**< Contents elements iterator. */
+ dk3_sto_t *sRowHeads; /**< Row heads in wxGrid. */
+ dk3_sto_it_t *iRowHeads; /**< Row heads in wxGrid. */
+ dk3_sto_t *sCellData; /**< Cell data in wxGrid. */
+ dk3_sto_it_t *iCellData; /**< Cell data in wxGrid. */
+ dk3_sto_t *sColumnHeads; /**< Column heads in wxGrid. */
+ dk3_sto_it_t *iColumnHeads; /**< Column heads in wxGrid. */
+ dk3_sto_t *sGrowRow; /**< Growable rows. */
+ dk3_sto_it_t *iGrowRow; /**< Iterator for growable rows. */
+ dk3_sto_t *sGrowCol; /**< Growable columns. */
+ dk3_sto_it_t *iGrowCol; /**< Iterator for growable columns. */
+ unsigned long lndecl; /**< Line number declaration. */
+ unsigned long lndef; /**< Line number definition. */
+ unsigned long textStyle; /**< Style for text control. */
+ size_t number; /**< Internal dkct object number. */
+ size_t passno; /**< Pass number. */
+ int cln; /**< Class number. */
+ int pseudoobj; /**< Pseudo object code. */
+ int posx; /**< X position in gridbag. */
+ int posy; /**< Y position in gridbag. */
+ int spanx; /**< X span (number of columns) in gridbag. */
+ int spany; /**< Y span (number of rows) in gridbag. */
+ int curx; /**< Current x position in grid bag. */
+ int cury; /**< Current y position in grid bag. */
+ int sizex; /**< Object x size (pixels). */
+ int sizey; /**< Object y size (pixels). */
+ int sizemx; /**< Minimum object x size (pixels). */
+ int sizemy; /**< Minimum object y size (pixels). */
+ int stbsz; /**< Status bar size. */
+ int prost; /**< Processing state. */
+ int border; /**< Border pixel number. */
+ int proportion; /**< Growth proportion. */
+ int gridcolumns; /**< Columns for grid/flexgrid. */
+ int gridrows; /**< Rows for grid/flexgrid. */
+ int gridgapx; /**< X gap. */
+ int gridgapy; /**< Y gap. */
+ int sash; /**< Sash for splitter window. */
+ int minPaneSize; /**< Minimum splitter pane size. */
+ int nChoices; /**< Number of choices. */
+ int maxRowsCols; /**< Max rows/columns in radio box. */
+ int spinMin; /**< Minimum for spin control. */
+ int spinMax; /**< Maximum for spin control. */
+ int spinVal; /**< Spin value. */
+ int nRows; /**< Number of rows in wxGrid. */
+ int nColumns; /**< Number of columns in wxGrid. */
+ int nRowHeads; /**< Number of row heads in wxGrid. */
+ int nColumnHeads; /**< Number of col heads in wxGrid. */
+ unsigned notebookStyle; /**< Notebook style. */
+ unsigned splitterStyle; /**< Splitter window style. */
+ unsigned toolbarStyle; /**< Toolbar style. */
+ unsigned gridStyle; /**< Grid style. */
+ unsigned char align; /**< Alignment. */
+ unsigned char direction; /**< Box sizer direction. */
+ unsigned char borderPos; /**< Border position. */
+ unsigned char expandFlag; /**< Flag: Expand object. */
+ unsigned char nStates; /**< Number of states for checkbox. */
+ unsigned char state; /**< Checkbox state. */
+ unsigned char selStyle; /**< Selection style. */
+ unsigned char rbDirection; /**< Direction for max size. */
+ unsigned char startGroup; /**< Flag: Start radio button group. */
+ unsigned char spinWrap; /**< Flag: Wrap spin control. */
+ unsigned char useKeys; /**< Flag: Use keys. */
+ unsigned char sliderStyle; /**< Slider style. */
+ unsigned char buttonStyle; /**< Button style. */
+ unsigned char bitmapbStyle; /**< Bitmap button style. */
+ unsigned char gaugeStyle; /**< Gauge style. */
+ unsigned char menuItemStyle; /**< Menu item style. */
+ unsigned char tableOwner; /**< Flag: Grid is table owner. */
+ unsigned char compConst; /**< Flag: Complete constructor. */
+} DKCT_GUI_ELEMENT;
+
+
+
+/** Description for one frame or dialog.
+*/
+typedef struct {
+ DKCT_SRC *psrc; /**< Source structure. */
+ DKCT_GUI_ELEMENT *c_el; /**< Current element to configure. */
+ DKCT_GUI_ELEMENT *r_el; /**< Root element. */
+ dk3_sto_t *s_el_by_name; /**< Storage for elements by name. */
+ dk3_sto_it_t *i_el_by_name; /**< Iterator for elements by name. */
+ dk3_sto_t *s_el_by_num; /**< Storage for elements by number. */
+ dk3_sto_it_t *i_el_by_num; /**< Iterator for elements by number. */
+ char *ttflag; /**< Flag for tool tips. */
+ size_t no; /**< Number of objects already found. */
+ unsigned char align; /**< Default align. */
+} DKCT_GUI;
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Create new GUI description, allocate memory.
+ @param psrc Source structure.
+ @return Pointer to new GUI description on success, NULL on error.
+*/
+DKCT_GUI *
+dkct_gui_new(DKCT_SRC *psrc);
+
+/** Destroy GUI description, release memory.
+ @param pg GUI description to destroy.
+*/
+void
+dkct_gui_delete(DKCT_GUI *pg);
+
+/** Add one input line.
+ @param gui GUI description.
+ @param il Input line to add.
+ @return 1 on success, 0 on error.
+*/
+int
+dkct_gui_add_line(DKCT_GUI *gui, char *il);
+
+/** Check GUI consistency.
+ @param psrc Source structure.
+ @return 1 on success, 0 on error.
+*/
+int
+dkct_gui_check(DKCT_SRC *psrc);
+
+/** Write class member variables.
+ @param psrc Source structure.
+*/
+void
+dkct_gui_class_variables(DKCT_SRC *psrc);
+
+/** Write constructor for current class.
+ @param psrc Source structure.
+*/
+void
+dkct_gui_write_constructor(DKCT_SRC *psrc);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dkct-str.c b/support/dktools/dkct-str.c
new file mode 100644
index 0000000000..e953c7efb0
--- /dev/null
+++ b/support/dktools/dkct-str.c
@@ -0,0 +1,508 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dkct-str.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dkct-str.c The dkct-str module.
+*/
+
+
+#line 46 "dkct-str.ctr"
+
+#if DK3_USE_WX
+#include "dkwxtrace.h"
+#else
+#include "dkct.h"
+#endif
+
+
+/** Message texts in English, texts in the users preferred language
+ are used instead, if found.
+*/
+static dkChar const * dkct_str_message_texts[] = {
+/* 0 */
+dkT("Not an input file (wrong suffix): \""),
+
+/* 1 */
+dkT("\"!"),
+
+/* 2 */
+dkT("Illegal type: \""),
+
+/* 3 */
+dkT("\"!"),
+
+/* 4 */
+dkT("Copyright owner redefined!"),
+
+/* 5 */
+dkT("Copyright year redefined!"),
+
+/* 6 */
+dkT("License redefined!"),
+
+/* 7 */
+dkT("Unknown license type: \""),
+
+/* 8 */
+dkT("\"!"),
+
+/* 9 */
+dkT("Syntax error - Missing value!"),
+
+/* 10 */
+dkT("Syntax error!\nUnknown option: \""),
+
+/* 11 */
+dkT("\"!"),
+
+/* 12 */
+dkT("Ouput file name contains non-ASCII: \""),
+
+/* 13 */
+dkT("\"!"),
+
+/* 14 */
+dkT("Missing file name!"),
+
+/* 15 */
+dkT("Failed to open pipe: \""),
+
+/* 16 */
+dkT("\"!"),
+
+/* 17 */
+dkT("No popen() function available on this system!"),
+
+/* 18 */
+dkT("Problem while writing output!"),
+
+/* 19 */
+dkT("The macro= and prefix= settings are exclusive!"),
+
+/* 20 */
+dkT("Failed to open file \""),
+
+/* 21 */
+dkT("\"!"),
+
+/* 22 */
+dkT("Source line too long!"),
+
+/* 23 */
+dkT("No such built-in function: \""),
+
+/* 24 */
+dkT("\"!"),
+
+/* 25 */
+dkT("Missing function name!"),
+
+/* 26 */
+dkT("File name too long: \""),
+
+/* 27 */
+dkT("\"!"),
+
+/* 28 */
+dkT("Redefinition of state machine name!"),
+
+/* 29 */
+dkT("Not enough memory!"),
+
+/* 30 */
+dkT("Syntax error - Boolean expected!"),
+
+/* 31 */
+dkT("Syntax error - Not a number!"),
+
+/* 32 */
+dkT("Redefinition of state, input, or output!"),
+
+/* 33 */
+dkT("Syntax error!"),
+
+/* 34 */
+dkT("Undeclared state, input, or output: \""),
+
+/* 35 */
+dkT("\"!"),
+
+/* 36 */
+dkT("Conflict with previous rule (line "),
+
+/* 37 */
+dkT("Syntax error - Incomplete section name!"),
+
+/* 38 */
+dkT("Numeric overflow!"),
+
+/* 39 */
+dkT(")!"),
+
+/* 40 */
+dkT("No states declared!"),
+
+/* 41 */
+dkT("No inputs declared!"),
+
+/* 42 */
+dkT("No outputs declared!"),
+
+/* 43 */
+dkT("Syntax error!\nUnknown header \""),
+
+/* 44 */
+dkT("\"!"),
+
+/* 45 */
+dkT("Class name already set!"),
+
+/* 46 */
+dkT("Missing window ID attribute for object!"),
+
+/* 47 */
+dkT("Splitter window requires exactly 2 children!"),
+
+/* 48 */
+dkT("Container element has no contents!"),
+
+/* 49 */
+dkT("Missing text attribute for object!"),
+
+/* 50 */
+dkT("Grid setup invalid or missing for object!"),
+
+/* 51 */
+dkT("Missing bitmap attribute for object!"),
+
+/* 52 */
+dkT("Missing or invalid choices attribute for object!"),
+
+/* 53 */
+dkT("Missing or invalid size attribute for object!"),
+
+/* 54 */
+dkT("Missing rows or columns attribute for radio box!"),
+
+/* 55 */
+dkT("Attribute ignored (allowed for root object only)!"),
+
+/* 56 */
+dkT("Attribute ignored (not supported by class)!"),
+
+/* 57 */
+dkT("Not enough memory (RAM/swap)!"),
+
+/* 58 */
+dkT("Syntax error - Missing object name!"),
+
+/* 59 */
+dkT("Syntax error - Missing ']'!"),
+
+/* 60 */
+dkT("Syntax error - Redefinition of id!"),
+
+/* 61 */
+dkT("Syntax error - ID undefined!"),
+
+/* 62 */
+dkT("Syntax error - Redefinition of text!"),
+
+/* 63 */
+dkT("Syntax error - Unknown top level window type!"),
+
+/* 64 */
+dkT("Syntax error!\nNot a numeric value: \""),
+
+/* 65 */
+dkT("\"!"),
+
+/* 66 */
+dkT("Syntax error - Empty line!"),
+
+/* 67 */
+dkT("Syntax error!"),
+
+/* 68 */
+dkT("Syntax error - No current element yet!"),
+
+/* 69 */
+dkT("Syntax error - Missing value!"),
+
+/* 70 */
+dkT("Syntax error - Not a boolean value!"),
+
+/* 71 */
+dkT("Syntax error - Empty ID!"),
+
+/* 72 */
+dkT("Syntax error - Only one direction allowed!"),
+
+/* 73 */
+dkT("Syntax error - Not a direction!"),
+
+/* 74 */
+dkT("Attribute redefinition, previous value \""),
+
+/* 75 */
+dkT("\" discarded!"),
+
+/* 76 */
+dkT("Syntax error!\nKeyword \""),
+
+/* 77 */
+dkT("\" not acceptable here!"),
+
+/* 78 */
+dkT("Syntax error - Missing class name for object!"),
+
+/* 79 */
+dkT("Syntax error - Dependency loop detected!"),
+
+/* 80 */
+dkT("Constructor specified, not recommended for this class!"),
+
+/* 81 */
+dkT("Syntax error - Don't know how to add object to parent!"),
+
+/* 82 */
+dkT("Syntax error!\nNumber out of range: \""),
+
+/* 83 */
+dkT("\"!"),
+
+/* 84 */
+dkT("Syntax error!\nCan't add object \""),
+
+/* 85 */
+dkT("\" to parent object \""),
+
+/* 86 */
+dkT("\"!"),
+
+/* 87 */
+dkT(""),
+
+/* 88 */
+dkT("Syntax error!\nIllegal parent/child class combination: \""),
+
+/* 89 */
+dkT("/"),
+
+/* 90 */
+dkT("\"!"),
+
+/* 91 */
+dkT("Syntax error - Missing name for parent object!"),
+
+/* 92 */
+dkT("Syntax error - Missing parent object!"),
+
+/* 93 */
+dkT("Syntax error!\nMissing class name for object \""),
+
+/* 94 */
+dkT("\"!"),
+
+/* 95 */
+dkT("Redeclaration of object \""),
+
+/* 96 */
+dkT("\"!"),
+
+/* 97 */
+dkT("Root element must have exactly one sizer as contents!"),
+
+/* 98 */
+dkT("Command too long!"),
+
+/* 99 */
+dkT("Illegal section name \""),
+
+/* 100 */
+dkT("\"!"),
+
+/* 101 */
+dkT("File name too long in trace function!"),
+
+/* 102 */
+dkT("File name \""),
+
+/* 103 */
+dkT("\" contains non-ASCII characters!"),
+
+/* 104 */
+dkT("Pipe started, but not processing current directory!"),
+
+/* 105 */
+dkT("All output files up to date."),
+
+/* 106 */
+dkT("Start processing."),
+
+/* 107 */
+dkT("Processing finished."),
+
+/* 108 */
+dkT("Writing file \""),
+
+/* 109 */
+dkT("\"."),
+
+/* 110 */
+dkT("File \""),
+
+/* 111 */
+dkT("\" is up to date."),
+
+/* 112 */
+dkT("Sizes must not be negative!"),
+
+/* 113 */
+dkT("Copyright end year is not current year!"),
+
+/* 114 */
+dkT("Preprocessor instructions and file=... used in $!text section!"),
+
+/* 115 */
+dkT("Redefinition of tooltip flag!"),
+
+NULL
+
+
+#line 449 "dkct-str.ctr"
+};
+
+
+
+/** String table file name.
+*/
+static dkChar const dkct_str_string_table_file_name[] = { dkT("dkct3.str") };
+
+
+
+/** Source file name suffixes.
+ The order here must match the order in dkct_src_dest_suffixes.
+*/
+static dkChar const * const dkct_str_source_suffixes[] = {
+/* 0 */ dkT(".ctr"),
+/* 1 */ dkT(".cpt"),
+/* 2 */ dkT(".mtr"),
+/* 3 */ dkT(".jtr"),
+/* 4 */ dkT(".wxc"),
+NULL
+};
+
+
+
+/** Destination file suffixes for C (.ctr input).
+*/
+static dkChar const * const dkct_dest_c_suffixes[] = {
+dkT(".c"), dkT(".h"), NULL
+};
+
+
+
+/** Destination file suffixes for C++ (.cpt and .wxc input).
+*/
+static dkChar const * const dkct_dest_cpp_suffixes[] = {
+dkT(".cpp"), dkT(".h"), NULL
+};
+
+
+
+/** Destination file suffixes for Objective-C (.mtr input).
+*/
+static dkChar const * const dkct_dest_m_suffixes[] = {
+dkT(".m"), dkT(".h"), NULL
+};
+
+
+
+/** Destination file suffixes for Java (.jtr input).
+*/
+static dkChar const * const dkct_dest_j_suffixes[] = {
+dkT(".java"), NULL
+};
+
+
+
+/** Array of destination file suffix lists.
+ The order of lists must match the order in dkct_str_source_suffixes.
+*/
+static dkChar const * const * const dkct_str_dest_suffixes[] = {
+dkct_dest_c_suffixes,
+dkct_dest_cpp_suffixes,
+dkct_dest_m_suffixes,
+dkct_dest_j_suffixes,
+dkct_dest_cpp_suffixes,
+NULL
+};
+
+
+
+dkChar const * const *
+dkct_str_get_message_texts(void)
+{
+ return dkct_str_message_texts;
+}
+
+
+
+dkChar const *
+dkct_str_get_string_table_file_name(void)
+{
+ return dkct_str_string_table_file_name;
+}
+
+
+
+dkChar const * const *
+dkct_str_get_source_suffixes(void)
+{
+ return dkct_str_source_suffixes;
+}
+
+
+
+dkChar const * const * const *
+dkct_str_get_dest_suffixes(void)
+{
+ return dkct_str_dest_suffixes;
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dkct-str.ctr b/support/dktools/dkct-str.ctr
new file mode 100644
index 0000000000..91d64dd74e
--- /dev/null
+++ b/support/dktools/dkct-str.ctr
@@ -0,0 +1,552 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Get default message texts.
+ @return Default message texts in English.
+*/
+dkChar const * const *
+dkct_str_get_message_texts(void);
+
+/** Get string table file name.
+ @return String table file name.
+*/
+dkChar const *
+dkct_str_get_string_table_file_name(void);
+
+/** Get array of source file suffixes.
+ @return Suffix list.
+*/
+dkChar const * const *
+dkct_str_get_source_suffixes(void);
+
+/** Get array of destination file suffixes.
+ @return Output file name suffix list.
+*/
+dkChar const * const * const *
+dkct_str_get_dest_suffixes(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#if DK3_USE_WX
+#include "dkwxtrace.h"
+#else
+#include "dkct.h"
+#endif
+
+
+/** Message texts in English, texts in the users preferred language
+ are used instead, if found.
+*/
+static dkChar const * dkct_str_message_texts[] = {
+$!string-table macro=dkT
+#
+# 0 / 1: Error: Not an input file (wrong suffix): "..."!
+#
+Not an input file (wrong suffix): "
+"!
+#
+# 2 / 3: Error: Illegal type: "..."!
+#
+Illegal type: "
+"!
+#
+# 4: Error: Copyright owner redefined!
+#
+Copyright owner redefined!
+#
+# 5: Error: Copyright year redefined!
+#
+Copyright year redefined!
+#
+# 6: Error: License redefined!
+#
+License redefined!
+#
+# 7 / 8: Error: Unknown license type: "..."!
+#
+Unknown license type: "
+"!
+#
+# 9: Error: Syntax error, value expected!
+#
+Syntax error - Missing value!
+#
+# 10 / 11: Error: Syntax error, unknown option "..."!
+#
+Syntax error!\nUnknown option: "
+"!
+#
+# 12 / 13: Error: Output file name contains non-ASCII: "..."!
+#
+Ouput file name contains non-ASCII: "
+"!
+#
+# 14: Error: Missing file name!
+#
+Missing file name!
+#
+# 15: Error: Failed to open pipe: "..."!
+#
+Failed to open pipe: "
+"!
+#
+# 17: Error: No popen() function available here!
+#
+No popen() function available on this system!
+#
+# 18: Error: Problem while writing output!
+#
+Problem while writing output!
+#
+# 19: Error: Either macro= or prefix= allowed, not both!
+#
+The macro= and prefix= settings are exclusive!
+#
+# 20 / 21: Error: Failed to open file "..."!
+#
+Failed to open file "
+"!
+#
+# 22: Error: Source line too long!
+#
+Source line too long!
+#
+# 23 / 24: Error: No such built-in function: "..."!
+#
+No such built-in function: "
+"!
+#
+# 25: Error: Missing function name!
+#
+Missing function name!
+#
+# 26 / 27: Error: File name too long: "..."!
+#
+File name too long: "
+"!
+#
+# 28: Error: Redefinition of state machine name!
+#
+Redefinition of state machine name!
+#
+# 29: Error: Not enough memory!
+#
+Not enough memory!
+#
+# 30: Error: Syntax error (boolean expected)!
+#
+Syntax error - Boolean expected!
+#
+# 31: Error: Syntax error (not a number)!
+#
+Syntax error - Not a number!
+#
+# 32: Error: Redefinition of state, input, or output!
+#
+Redefinition of state, input, or output!
+#
+# 33: Error: Syntax error!
+#
+Syntax error!
+#
+# 34 / 35: Error: Undeclared state, input, or output: "..."!
+#
+Undeclared state, input, or output: "
+"!
+#
+# 36 / 39: Error: Conflict with previous rule (line ...)!
+#
+Conflict with previous rule (line
+#
+# 37: Error: Syntax error (incomplete section name)!
+#
+Syntax error - Incomplete section name!
+#
+# 38: Error: Numeric overflow!
+#
+Numeric overflow!
+#
+# 39: End of message 36
+#
+)!
+#
+# 40: Error: No states declared!
+#
+No states declared!
+#
+# 41: Error: No inputs declared!
+#
+No inputs declared!
+#
+# 42: Error: Not outputs declared!
+#
+No outputs declared!
+#
+# 43 / 44: Error: Syntax error (unknown header ...)!
+#
+Syntax error!\nUnknown header "
+"!
+#
+# 45: Error: Class name already set!
+#
+Class name already set!
+#
+# 46: Error: Missing window ID for object!
+#
+Missing window ID attribute for object!
+#
+# 47: Error: Splitter window requires exactly 2 children!
+#
+Splitter window requires exactly 2 children!
+#
+# 48: Error: Container element has no contents!
+#
+Container element has no contents!
+#
+# 49: Error: Missing text attribute for object!
+#
+Missing text attribute for object!
+#
+# 50: Error: Grid setup invalid or missing for object!
+#
+Grid setup invalid or missing for object!
+#
+# 51: Error: Missing bitmap attribute for object!
+#
+Missing bitmap attribute for object!
+#
+# 52: Error: Missing or invalid choices attribute for object!
+#
+Missing or invalid choices attribute for object!
+#
+# 53: Error: Missing or invalid size attribute for object!
+#
+Missing or invalid size attribute for object!
+#
+# 54: Error: Missing rows or columns attribute for radio box!
+#
+Missing rows or columns attribute for radio box!
+#
+# 55: Warning: Attribute ignored (usable for root object only)!
+#
+Attribute ignored (allowed for root object only)!
+#
+# 56: Warning: Attribute ignored (not applicable to this class)!
+#
+Attribute ignored (not supported by class)!
+#
+# 57: Error: Not enough memory!
+#
+Not enough memory (RAM/swap)!
+#
+# 58: Error: Syntax error - Missing object name!
+#
+Syntax error - Missing object name!
+#
+# 59: Error: Syntax error - Missing closing bracket!
+#
+Syntax error - Missing ']'!
+#
+# 60: Error: Syntax error - Redefinition of id!
+#
+Syntax error - Redefinition of id!
+#
+# 61: Error: Syntax error - ID undefined!
+#
+Syntax error - ID undefined!
+#
+# 62: Error: Syntax error - Redefinition of text!
+#
+Syntax error - Redefinition of text!
+#
+# 63: Error: Syntax error - Unknown top level window type!
+#
+Syntax error - Unknown top level window type!
+#
+# 64/65: Error: Syntax error - Not a numeric value: "...."!
+#
+Syntax error!\nNot a numeric value: "
+"!
+#
+# 66: Error: Syntax error - Empty line!
+#
+Syntax error - Empty line!
+#
+# 67: Error: Syntax error!
+#
+Syntax error!
+#
+# 68: Error: Syntax error - No current element yet!
+#
+Syntax error - No current element yet!
+#
+# 69: Error: Syntax error - Missing value!
+#
+Syntax error - Missing value!
+#
+# 70: Error: Syntax error - Not a boolean value!
+#
+Syntax error - Not a boolean value!
+#
+# 71: Error: Syntax error - Empty ID!
+#
+Syntax error - Empty ID!
+#
+# 72: Error: Syntax error - Only one direction allowed here!
+#
+Syntax error - Only one direction allowed!
+#
+# 73: Error: Syntax error - Not a direction!
+#
+Syntax error - Not a direction!
+#
+# 74/75: Warning: Attribute redefinition discards previous value!
+#
+Attribute redefinition, previous value "
+" discarded!
+#
+# 76/77: Error: Unknown keyword "..."!
+#
+Syntax error!\nKeyword "
+" not acceptable here!
+#
+# 78: Error: Missing class name for object!
+#
+Syntax error - Missing class name for object!
+#
+# 79: Error: Dependency loop detected!
+#
+Syntax error - Dependency loop detected!
+#
+# 80: Warning: Constructor specified, not recommended for this class!
+#
+Constructor specified, not recommended for this class!
+#
+# 81: ERROR: Don't know how to add object to parent!
+#
+Syntax error - Don't know how to add object to parent!
+#
+# 82/83: Error: Number out of range: "..."!
+#
+Syntax error!\nNumber out of range: "
+"!
+#
+# 84/85/86: Error: Can't add object "..." to parent object "..."!
+#
+Syntax error!\nCan't add object "
+" to parent object "
+"!
+#
+# 87: UNUSED Object/class name: Not specified.
+#
+
+#
+# 88/89/90: Illegal parent/child class combination: ".../..."!
+#
+Syntax error!\nIllegal parent/child class combination: "
+/
+"!
+#
+# 91: Error: Missing name for parent object!
+#
+Syntax error - Missing name for parent object!
+#
+# 92: Error: Missing parent object!
+#
+Syntax error - Missing parent object!
+#
+# 93/94: Error: Syntax error - Missing class name for object "..."!
+#
+Syntax error!\nMissing class name for object "
+"!
+#
+# 95/96: Warning: Redeclaration of object "..."!
+#
+Redeclaration of object "
+"!
+#
+# 97: Error: Root element must have exactly one sizer as contents!
+#
+Root element must have exactly one sizer as contents!
+#
+# 98: Error: Command too long!
+#
+Command too long!
+#
+# 99/100: Error: Illegal section name for state machine "..."!
+#
+Illegal section name "
+"!
+#
+# 101: Error: File name too long in trace function!
+#
+File name too long in trace function!
+#
+# 102/203: Error: File name "..." contains non-ASCII characters!
+#
+File name "
+" contains non-ASCII characters!
+#
+# 104: Error: Pipe started but not processing current directory!
+#
+Pipe started, but not processing current directory!
+#
+# 105: Progress message: All output files up to date.
+#
+All output files up to date.
+#
+# 106: Progress message: Start processing.
+#
+Start processing.
+#
+# 107: Progress message: Processing finished.
+#
+Processing finished.
+#
+# 108/109: Progress message: Writing file "...".
+#
+Writing file "
+".
+#
+# 110/111: Progress message: File "..." is up to date.
+#
+File "
+" is up to date.
+#
+# 112: Error: Sizes must not be negative!
+#
+Sizes must not be negative!
+#
+# 113
+#
+Copyright end year is not current year!
+#
+# 114
+#
+Preprocessor instructions and file=... used in $!text section!
+#
+# 115
+#
+Redefinition of tooltip flag!
+$!end
+};
+
+
+
+/** String table file name.
+*/
+static dkChar const dkct_str_string_table_file_name[] = { dkT("dkct3.str") };
+
+
+
+/** Source file name suffixes.
+ The order here must match the order in dkct_src_dest_suffixes.
+*/
+static dkChar const * const dkct_str_source_suffixes[] = {
+/* 0 */ dkT(".ctr"),
+/* 1 */ dkT(".cpt"),
+/* 2 */ dkT(".mtr"),
+/* 3 */ dkT(".jtr"),
+/* 4 */ dkT(".wxc"),
+NULL
+};
+
+
+
+/** Destination file suffixes for C (.ctr input).
+*/
+static dkChar const * const dkct_dest_c_suffixes[] = {
+dkT(".c"), dkT(".h"), NULL
+};
+
+
+
+/** Destination file suffixes for C++ (.cpt and .wxc input).
+*/
+static dkChar const * const dkct_dest_cpp_suffixes[] = {
+dkT(".cpp"), dkT(".h"), NULL
+};
+
+
+
+/** Destination file suffixes for Objective-C (.mtr input).
+*/
+static dkChar const * const dkct_dest_m_suffixes[] = {
+dkT(".m"), dkT(".h"), NULL
+};
+
+
+
+/** Destination file suffixes for Java (.jtr input).
+*/
+static dkChar const * const dkct_dest_j_suffixes[] = {
+dkT(".java"), NULL
+};
+
+
+
+/** Array of destination file suffix lists.
+ The order of lists must match the order in dkct_str_source_suffixes.
+*/
+static dkChar const * const * const dkct_str_dest_suffixes[] = {
+dkct_dest_c_suffixes,
+dkct_dest_cpp_suffixes,
+dkct_dest_m_suffixes,
+dkct_dest_j_suffixes,
+dkct_dest_cpp_suffixes,
+NULL
+};
+
+
+
+dkChar const * const *
+dkct_str_get_message_texts(void)
+{
+ return dkct_str_message_texts;
+}
+
+
+
+dkChar const *
+dkct_str_get_string_table_file_name(void)
+{
+ return dkct_str_string_table_file_name;
+}
+
+
+
+dkChar const * const *
+dkct_str_get_source_suffixes(void)
+{
+ return dkct_str_source_suffixes;
+}
+
+
+
+dkChar const * const * const *
+dkct_str_get_dest_suffixes(void)
+{
+ return dkct_str_dest_suffixes;
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dkct-str.h b/support/dktools/dkct-str.h
new file mode 100644
index 0000000000..b73d78f9c3
--- /dev/null
+++ b/support/dktools/dkct-str.h
@@ -0,0 +1,81 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dkct-str.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dkct-str.h Header file for the dkct-str module.
+*/
+
+#ifndef DKCT_STR_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DKCT_STR_H_INCLUDED 1
+
+
+#line 10 "dkct-str.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Get default message texts.
+ @return Default message texts in English.
+*/
+dkChar const * const *
+dkct_str_get_message_texts(void);
+
+/** Get string table file name.
+ @return String table file name.
+*/
+dkChar const *
+dkct_str_get_string_table_file_name(void);
+
+/** Get array of source file suffixes.
+ @return Suffix list.
+*/
+dkChar const * const *
+dkct_str_get_source_suffixes(void);
+
+/** Get array of destination file suffixes.
+ @return Output file name suffix list.
+*/
+dkChar const * const * const *
+dkct_str_get_dest_suffixes(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dkct-to.c b/support/dktools/dkct-to.c
new file mode 100644
index 0000000000..63531e8517
--- /dev/null
+++ b/support/dktools/dkct-to.c
@@ -0,0 +1,181 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dkct-to.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dkct-to.c The dkct-to module.
+*/
+
+
+#line 77 "dkct-to.ctr"
+
+#if DK3_USE_WX
+#include "dkwxtrace.h"
+#else
+#include "dkct.h"
+#endif
+
+
+#if DK3_USE_WX
+static
+void
+dkct_to_log_lineno(DKCT_SRC *psrc)
+{
+ char buffer[64];
+ if(psrc->sfn) {
+ if(psrc->lineno) {
+ if(psrc->pComm) {
+ (psrc->pComm)->addCharText(psrc->sfn);
+ sprintf(buffer, ":%lu: ", psrc->lineno);
+ (psrc->pComm)->addCharText(buffer);
+ }
+ }
+ }
+}
+#endif
+
+void
+dkct_to_log_1(DKCT_SRC *psrc, int scope, int ll, size_t i1)
+{
+ if(scope) {
+ dk3app_set_source_line(psrc->app, psrc->lineno);
+ dk3app_log_1(psrc->app, ll, psrc->msg, i1);
+ }
+#if DK3_USE_WX
+ if(psrc->pComm) {
+ dkct_to_log_lineno(psrc);
+ (psrc->pComm)->addDkText((psrc->msg)[i1]);
+ (psrc->pComm)->nl();
+ (psrc->pComm)->setLogLevel(ll);
+ }
+#endif
+}
+
+
+
+void
+dkct_to_log_3(
+ DKCT_SRC *psrc, int scope, int ll, size_t i1, size_t i2, char const *text
+)
+{
+ dkChar b3[DK3_MAX_PATH];
+ if(scope) {
+ dk3app_set_source_line(psrc->app, psrc->lineno);
+ if(dk3str_c8_to_str_simple_app(b3,DK3_SIZEOF(b3,dkChar),text,psrc->app)) {
+ dk3app_log_3(psrc->app, ll, psrc->msg, i1, i2, b3);
+ }
+ }
+#if DK3_USE_WX
+ if(psrc->pComm) {
+ dkct_to_log_lineno(psrc);
+ (psrc->pComm)->addDkText((psrc->msg)[i1]);
+ if(text) {
+ (psrc->pComm)->addCharText(text);
+ }
+ (psrc->pComm)->addDkText((psrc->msg)[i2]);
+ (psrc->pComm)->nl();
+ (psrc->pComm)->setLogLevel(ll);
+ }
+#endif
+}
+
+
+
+void
+dkct_to_log_5(
+ DKCT_SRC *psrc,
+ int scope,
+ int ll,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ char const *t1,
+ char const *t2
+)
+{
+ dkChar b1[DK3_MAX_PATH];
+ dkChar b2[DK3_MAX_PATH];
+ if(scope) {
+ dk3app_set_source_line(psrc->app, psrc->lineno);
+ if(dk3str_c8_to_str_simple_app(b1,DK3_SIZEOF(b1,dkChar),t1,psrc->app)) {
+ if(dk3str_c8_to_str_simple_app(b2,DK3_SIZEOF(b2,dkChar),t2,psrc->app)) {
+ dk3app_log_5(psrc->app, ll, psrc->msg, i1, i2, i3, b1, b2);
+ }
+ }
+ }
+#if DK3_USE_WX
+ if(psrc->pComm) {
+ dkct_to_log_lineno(psrc);
+ (psrc->pComm)->addDkText((psrc->msg)[i1]);
+ if(t1) {
+ (psrc->pComm)->addCharText(t1);
+ }
+ (psrc->pComm)->addDkText((psrc->msg)[i2]);
+ if(t2) {
+ (psrc->pComm)->addCharText(t2);
+ }
+ (psrc->pComm)->addDkText((psrc->msg)[i3]);
+ (psrc->pComm)->nl();
+ (psrc->pComm)->setLogLevel(ll);
+ }
+#endif
+}
+
+
+void
+dkct_to_log_dk_3(
+ DKCT_SRC *psrc, int scope, int ll, size_t i1, size_t i2, dkChar const *text
+)
+{
+ if(scope) {
+ dk3app_set_source_line(psrc->app, psrc->lineno);
+ dk3app_log_3(psrc->app, ll, psrc->msg, i1, i2, text);
+ }
+#if DK3_USE_WX
+ if(psrc->pComm) {
+ dkct_to_log_lineno(psrc);
+ (psrc->pComm)->addDkText((psrc->msg)[i1]);
+ if(text) {
+ (psrc->pComm)->addDkText(text);
+ }
+ (psrc->pComm)->addDkText((psrc->msg)[i2]);
+ (psrc->pComm)->nl();
+ (psrc->pComm)->setLogLevel(ll);
+ }
+#endif
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dkct-to.ctr b/support/dktools/dkct-to.ctr
new file mode 100644
index 0000000000..b987fffe54
--- /dev/null
+++ b/support/dktools/dkct-to.ctr
@@ -0,0 +1,217 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Write one-part log message.
+ @param psrc Source structure.
+ @param scope Scope flag.
+ @param ll Log level.
+ @param i1 Index of message in message array.
+*/
+void
+dkct_to_log_1(DKCT_SRC *psrc, int scope, int ll, size_t i1);
+
+/** Write three-parts log message.
+ @param psrc Source structure.
+ @param scope Scope flag.
+ @param ll Log level.
+ @param i1 Index of first message part in message array.
+ @param i2 Index of third message part in message array.
+ @param text Second message part.
+*/
+void
+dkct_to_log_3(
+ DKCT_SRC *psrc, int scope, int ll, size_t i1, size_t i2, char const *text
+);
+
+/** Write three-parts log message.
+ @param psrc Source structure.
+ @param scope Scope flag.
+ @param ll Log level.
+ @param i1 Index of first message part in message array.
+ @param i2 Index of third message part in message array.
+ @param text Second message part.
+*/
+void
+dkct_to_log_dk_3(
+ DKCT_SRC *psrc, int scope, int ll, size_t i1, size_t i2, dkChar const *text
+);
+
+/** Write five-parts log message.
+ @param psrc Source structure.
+ @param scope Scope flag.
+ @param ll Log level.
+ @param i1 Index of first message part in message array.
+ @param i2 Index of third message part in message array.
+ @param i3 Index of fifth message part in message array.
+ @param t1 Second message part.
+ @param t2 Fourth message part.
+*/
+void
+dkct_to_log_5(
+ DKCT_SRC *psrc,
+ int scope,
+ int ll,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ char const *t1,
+ char const *t2
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#if DK3_USE_WX
+#include "dkwxtrace.h"
+#else
+#include "dkct.h"
+#endif
+
+
+#if DK3_USE_WX
+static
+void
+dkct_to_log_lineno(DKCT_SRC *psrc)
+{
+ char buffer[64];
+ if(psrc->sfn) {
+ if(psrc->lineno) {
+ if(psrc->pComm) {
+ (psrc->pComm)->addCharText(psrc->sfn);
+ sprintf(buffer, ":%lu: ", psrc->lineno);
+ (psrc->pComm)->addCharText(buffer);
+ }
+ }
+ }
+}
+#endif
+
+void
+dkct_to_log_1(DKCT_SRC *psrc, int scope, int ll, size_t i1)
+{
+ if(scope) {
+ dk3app_set_source_line(psrc->app, psrc->lineno);
+ dk3app_log_1(psrc->app, ll, psrc->msg, i1);
+ }
+#if DK3_USE_WX
+ if(psrc->pComm) {
+ dkct_to_log_lineno(psrc);
+ (psrc->pComm)->addDkText((psrc->msg)[i1]);
+ (psrc->pComm)->nl();
+ (psrc->pComm)->setLogLevel(ll);
+ }
+#endif
+}
+
+
+
+void
+dkct_to_log_3(
+ DKCT_SRC *psrc, int scope, int ll, size_t i1, size_t i2, char const *text
+)
+{
+ dkChar b3[DK3_MAX_PATH];
+ if(scope) {
+ dk3app_set_source_line(psrc->app, psrc->lineno);
+ if(dk3str_c8_to_str_simple_app(b3,DK3_SIZEOF(b3,dkChar),text,psrc->app)) {
+ dk3app_log_3(psrc->app, ll, psrc->msg, i1, i2, b3);
+ }
+ }
+#if DK3_USE_WX
+ if(psrc->pComm) {
+ dkct_to_log_lineno(psrc);
+ (psrc->pComm)->addDkText((psrc->msg)[i1]);
+ if(text) {
+ (psrc->pComm)->addCharText(text);
+ }
+ (psrc->pComm)->addDkText((psrc->msg)[i2]);
+ (psrc->pComm)->nl();
+ (psrc->pComm)->setLogLevel(ll);
+ }
+#endif
+}
+
+
+
+void
+dkct_to_log_5(
+ DKCT_SRC *psrc,
+ int scope,
+ int ll,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ char const *t1,
+ char const *t2
+)
+{
+ dkChar b1[DK3_MAX_PATH];
+ dkChar b2[DK3_MAX_PATH];
+ if(scope) {
+ dk3app_set_source_line(psrc->app, psrc->lineno);
+ if(dk3str_c8_to_str_simple_app(b1,DK3_SIZEOF(b1,dkChar),t1,psrc->app)) {
+ if(dk3str_c8_to_str_simple_app(b2,DK3_SIZEOF(b2,dkChar),t2,psrc->app)) {
+ dk3app_log_5(psrc->app, ll, psrc->msg, i1, i2, i3, b1, b2);
+ }
+ }
+ }
+#if DK3_USE_WX
+ if(psrc->pComm) {
+ dkct_to_log_lineno(psrc);
+ (psrc->pComm)->addDkText((psrc->msg)[i1]);
+ if(t1) {
+ (psrc->pComm)->addCharText(t1);
+ }
+ (psrc->pComm)->addDkText((psrc->msg)[i2]);
+ if(t2) {
+ (psrc->pComm)->addCharText(t2);
+ }
+ (psrc->pComm)->addDkText((psrc->msg)[i3]);
+ (psrc->pComm)->nl();
+ (psrc->pComm)->setLogLevel(ll);
+ }
+#endif
+}
+
+
+void
+dkct_to_log_dk_3(
+ DKCT_SRC *psrc, int scope, int ll, size_t i1, size_t i2, dkChar const *text
+)
+{
+ if(scope) {
+ dk3app_set_source_line(psrc->app, psrc->lineno);
+ dk3app_log_3(psrc->app, ll, psrc->msg, i1, i2, text);
+ }
+#if DK3_USE_WX
+ if(psrc->pComm) {
+ dkct_to_log_lineno(psrc);
+ (psrc->pComm)->addDkText((psrc->msg)[i1]);
+ if(text) {
+ (psrc->pComm)->addDkText(text);
+ }
+ (psrc->pComm)->addDkText((psrc->msg)[i2]);
+ (psrc->pComm)->nl();
+ (psrc->pComm)->setLogLevel(ll);
+ }
+#endif
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dkct-to.h b/support/dktools/dkct-to.h
new file mode 100644
index 0000000000..8167fb732f
--- /dev/null
+++ b/support/dktools/dkct-to.h
@@ -0,0 +1,114 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dkct-to.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dkct-to.h Header file for the dkct-to module.
+*/
+
+#ifndef DKCT_TO_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DKCT_TO_H_INCLUDED 1
+
+
+#line 8 "dkct-to.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Write one-part log message.
+ @param psrc Source structure.
+ @param scope Scope flag.
+ @param ll Log level.
+ @param i1 Index of message in message array.
+*/
+void
+dkct_to_log_1(DKCT_SRC *psrc, int scope, int ll, size_t i1);
+
+/** Write three-parts log message.
+ @param psrc Source structure.
+ @param scope Scope flag.
+ @param ll Log level.
+ @param i1 Index of first message part in message array.
+ @param i2 Index of third message part in message array.
+ @param text Second message part.
+*/
+void
+dkct_to_log_3(
+ DKCT_SRC *psrc, int scope, int ll, size_t i1, size_t i2, char const *text
+);
+
+/** Write three-parts log message.
+ @param psrc Source structure.
+ @param scope Scope flag.
+ @param ll Log level.
+ @param i1 Index of first message part in message array.
+ @param i2 Index of third message part in message array.
+ @param text Second message part.
+*/
+void
+dkct_to_log_dk_3(
+ DKCT_SRC *psrc, int scope, int ll, size_t i1, size_t i2, dkChar const *text
+);
+
+/** Write five-parts log message.
+ @param psrc Source structure.
+ @param scope Scope flag.
+ @param ll Log level.
+ @param i1 Index of first message part in message array.
+ @param i2 Index of third message part in message array.
+ @param i3 Index of fifth message part in message array.
+ @param t1 Second message part.
+ @param t2 Fourth message part.
+*/
+void
+dkct_to_log_5(
+ DKCT_SRC *psrc,
+ int scope,
+ int ll,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ char const *t1,
+ char const *t2
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/dkct-tr.c b/support/dktools/dkct-tr.c
new file mode 100644
index 0000000000..a11ec5e4a6
--- /dev/null
+++ b/support/dktools/dkct-tr.c
@@ -0,0 +1,3842 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dkct-tr.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dkct-tr.c The dkct-tr module.
+*/
+
+
+#line 10 "dkct-tr.ctr"
+
+
+#if DK3_USE_WX
+#include "dkwxtrace.h"
+#else
+#include "dkct.h"
+#endif
+
+
+
+#include "dk3wxcs.h"
+
+
+
+
+
+#line 25 "dkct-tr.ctr"
+
+
+/** Dkct user function.
+*/
+typedef int dkct_tr_fct(DKCT_SRC *psrc, char *args);
+
+
+
+/** Table entry to connect a function to a name.
+*/
+typedef struct {
+ char const *name; /**< Function name. */
+ dkct_tr_fct *fct; /**< Function to execute. */
+} dkct_tr_fct_table_entry;
+
+
+
+/** Indicate that current character is trace control character.
+*/
+#define TRACE_CONTROL 512
+
+
+
+/** Operation: Do nothing.
+*/
+#define DKCT_O_NOOP 0
+
+
+
+/** Operation: Print current character.
+*/
+#define DKCT_O_PRINT 1
+
+/** Operation: Print dollar and current character.
+*/
+#define DKCT_O_DOLLAR_AND_CHAR 2
+
+/** Operation: Print slash and current character.
+*/
+#define DKCT_O_SLASH_AND_CHAR 3
+
+/** Operation: Reset buffer.
+*/
+#define DKCT_O_RESET_BUFFER 4
+
+/** Operation: Add current character to buffer.
+*/
+#define DKCT_O_ADD_BUFFER 5
+
+/** Operation: Write buffer as trace output.
+*/
+#define DKCT_O_TRACE_OUTPUT 6
+
+/** Operation: Execute command in buffer.
+*/
+#define DKCT_O_EXEC_CMD 7
+
+/** Operation: Start C++ style comment.
+*/
+#define DKCT_O_START_CPP_COMMENT 8
+
+/** Operation: End C++ style comment.
+*/
+#define DKCT_O_END_CPP_COMMENT 9
+
+/** Operation: Open file to save data for a box comment.
+*/
+#define DKCT_O_START_BOX 10
+
+/** Operation: Add normal character for box comment.
+*/
+#define DKCT_O_ADD_BOX 11
+
+/** Operation: Add newline to box comment file.
+*/
+#define DKCT_O_ADD_BOX_NL 12
+
+/** Operation: Add dollar and current character to box comment file.
+*/
+#define DKCT_O_ADD_BOX_DOLLAR_CHAR 13
+
+/** Operation: Print box comment file in box comment.
+*/
+#define DKCT_O_END_BOX 14
+
+
+
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+/** Separator character. */
+#define DKCT_TR_SEP '\\'
+#else
+/** Separator character. */
+#define DKCT_TR_SEP '/'
+#endif
+
+
+/** Section names.
+*/
+static char const * const dkct_tr_section_headers[] = {
+/* 0 */ "options",
+/* 1 */ "header",
+/* 2 */ "header start",
+/* 3 */ "header end",
+/* 4 */ "class start",
+/* 5 */ "class end",
+/* 6 */ "module",
+/* 7 */ "module start",
+/* 8 */ "module end",
+/* 9 */ "constructor start",
+/* 10 */ "constructor end",
+/* 11 */ "wx-gui",
+/* 12 */ "state machine",
+NULL
+};
+
+
+
+/** Keywords for option processing.
+*/
+static char const * const dkct_option_keywords[] = {
+/* 0 */ "copyright-owner",
+/* 1 */ "copyright-year",
+/* 2 */ "license",
+/* 3 */ "splint-comment-character",
+NULL
+};
+
+
+
+/** License type names.
+*/
+static char const * const dkct_license_names[] = {
+/* 0 */ "BSD",
+/* 1 */ "GPL",
+/* 2 */ "LGPL",
+/* 5 */ "wxWidgets",
+/* 4 */ "commercial",
+NULL
+};
+
+
+
+/** File name suffixes for output files.
+*/
+static dkChar const * const dkct_tr_out_suffixes[] = {
+/* 0 */ dkT(".h"),
+/* 1 */ dkT(".c"),
+/* 2 */ dkT(".cpp"),
+/* 3 */ dkT(".m"),
+/* 4 */ dkT(".java"),
+NULL
+};
+
+
+
+/** Warning at start of output files, do not modify!
+*/
+static char const * const dkct_tr_mod_warning_start[] = {
+"/*",
+" WARNING: This file was generated by dkct.",
+" Changes you make here will be lost if dkct is run again!",
+" You should modify the original source and run dkct on it.",
+NULL
+};
+
+
+
+/** End of modification warning.
+*/
+static char const * const dkct_tr_mod_warning_end[] = {
+"*/",
+"",
+NULL
+};
+
+
+/** Keywords to use when producing output.
+*/
+static char const * const dkct_tr_kw8[] = {
+/* 0 */ "\n",
+/* 1 */ " ",
+/* 2 */ "/*",
+/* 3 */ "*/",
+/* 4 */ "Copyright (C) ",
+/* 5 */ ", ",
+/* 6 */ "#ifndef ",
+/* 7 */ "_INCLUDED",
+/* 8 */ "/** Avoid multiple inclusions. */\n#define ",
+/* 9 */ " 1",
+/* 10 */ "#endif",
+/* 11 */ "/**\t@file ",
+/* 12 */ " Header file for the ",
+/* 13 */ " module.",
+/* 14 */ " The ",
+/* 15 */ "KrTrace.printMessage(",
+/* 16 */ " + ",
+/* 17 */ ":",
+/* 18 */ "\"",
+/* 19 */ "trace ",
+/* 20 */ "#line %lu \"%s\"\n",
+/* 21 */ "#if TRACE_WIDE\n",
+/* 22 */ "#else\n",
+/* 23 */ "#endif\n",
+/* 24 */ "\n/* TRACE BEGIN */\n",
+/* 25 */ "/* TRACE END */\n",
+/* 26 */ "//",
+/* 27 */ " */",
+/* 28 */ "stdout",
+/* 29 */ "dktrace_file()",
+/* 30 */ "if(dktrace_file()) {\n",
+/* 31 */ "}\n",
+/* 32 */ "dktrace_time();\n",
+/* 33 */ "fputs(",
+/* 34 */ ");\n",
+/* 35 */ ", ",
+/* 36 */ "fprintf(",
+/* 37 */ "fflush(",
+/* 38 */ "dkct-tmp-%lu",
+/* 39 */ "w+",
+/* 40 */ "/* * ",
+/* 41 */ " * */\n",
+/* 42 */ "/* **",
+/* 43 */ "** */\n",
+/* 44 */ "#include <dk3trace.h>\n",
+/* 45 */ "dktrace_init(\"",
+/* 46 */ "\");\n",
+/* 47 */ "dktrace_end();\n",
+/* 48 */ "fputc('\\n', ",
+/* 49 */ "r",
+/* 50 */ "w",
+/* 51 */ "$!end",
+/* 52 */ "(",
+/* 53 */ ")",
+/* 54 */ ",\n\n",
+/* 55 */ "\"",
+/* 56 */ "if(dktrace_file()) {\n",
+/* 57 */ " _setmode(_fileno(dktrace_file()), _O_U16TEXT);\n",
+/* 58 */ " fputwc(0xFEFF, dktrace_file());\n",
+/* 59 */ "}\n",
+/* 60 */ "_setmode(_fileno(stdout), _O_U16TEXT);\n",
+/* 61 */ "fputws(L",
+/* 62 */ "fwprintf(",
+/* 63 */ ", L",
+/* 64 */ "fputwc(L'\\n', ",
+/* 65 */ "NULL\n",
+/* 66 */ "/* %lu */\n",
+/* 67 */ "/* TRACE BEGIN */\n",
+/* 68 */ "#include <stdio.h>\n",
+/* 69 */ ",\n",
+/* 70 */ "dktrace_stdout_time();\n",
+/* 71 */ "dktrace_wtime();\n",
+/* 72 */ "dktrace_stdout_wtime();\n",
+/* 73 */ "\"! ",
+/* 74 */ "\\n\"",
+/* 75 */ "contents panel",
+/* 76 */ "\". ",
+/* 77 */ "\tOriginal source: ",
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+/* 78 */ "\\",
+#else
+/* 78 */ "/",
+#endif
+/* 79 */ "#ifndef TRACE_DEBUG\n#define TRACE_DEBUG 1\n#endif\n",
+/* 80 */ "/*@-nullassign@*/\n",
+/* 81 */ "/*@=nullassign@*/\n",
+/* 82 */
+"#if TRACE_WIDE && (defined(_WIN32) || DK3_ON_WINDOWS || DK4_ON_WINDOWS)\n",
+/* 83 */
+"#if (SIZEOF_WXCHAR > 1) || (DK4_SIZEOF_WXCHAR > 1) || (DK3_SIZEOF_WXCHAR > 1)\n",
+/* 84 */ "#if (DK3_CHAR_SIZE > 1) || (DK4_CHAR_SIZE > 1)\n",
+/* 85 */ "#if (defined(_WIN32)) || (DK3_ON_WINDOWS) || (DK4_ON_WINDOWS)\n",
+NULL
+};
+
+
+
+/** Keywords used by the module.
+*/
+static dkChar const * const dkct_tr_kw[] = {
+/* 0 */
+dkT(".h"),
+
+/* 1 */
+dkT(".dox"),
+
+NULL
+
+
+#line 314 "dkct-tr.ctr"
+};
+
+
+/** Arguments for the string-table command.
+*/
+static char const * const dkct_tr_string_table_args[] = {
+/* 0 */ "file",
+/* 1 */ "macro",
+/* 2 */ "prefix",
+/* 3 */ "preprocessor",
+NULL
+};
+
+
+
+/** Text to include in GPL-licensed sources.
+*/
+static char const * const dkct_tr_gpl_text[] = {
+"This program 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.",
+"",
+"This program 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",
+"this program. If not, see <http://www.gnu.org/licenses/>.",
+NULL
+
+
+#line 346 "dkct-tr.ctr"
+};
+
+
+
+/** Text to include in LGPL licensed sources.
+*/
+static char const * const dkct_tr_lgpl_text[] = {
+"This software is free software: you can redistribute it and/or modify it",
+"under the terms of the GNU Lesser General Public License as published by the",
+"Free Software Foundation, either version 3 of the License, or (at your",
+"option) any later version.",
+"",
+"This software 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 Lesser General Public License for more",
+"details.",
+"",
+"You should have received a copy of the GNU Lesser General Public License",
+"along with this software. If not, see <http://www.gnu.org/licenses/>.",
+NULL
+
+
+#line 367 "dkct-tr.ctr"
+};
+
+
+
+/** Text to include in BSD licensed sources.
+*/
+static char const * const dkct_tr_bsd_text[] = {
+"Redistribution and use in source and binary forms, with or without",
+"modification, are permitted provided that the following conditions are met:",
+"",
+"* Redistributions of source code must retain the above copyright notice,",
+" this list of conditions and the following disclaimer.",
+"* Redistributions in binary form must reproduce the above opyright notice,",
+" this list of conditions and the following disclaimer in the documentation",
+" and/or other materials provided with the distribution.",
+"* Neither the name of the author nor the names of contributors may be used",
+" to endorse or promote products derived from this software without specific",
+" prior written permission.",
+"",
+"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''",
+"AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE",
+"IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE",
+"ARE DISCLAIMED.",
+"IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY",
+"DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES",
+"(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;",
+"LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND",
+"ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT",
+"(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF",
+"THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.",
+NULL
+
+
+#line 399 "dkct-tr.ctr"
+};
+
+
+
+/** Text to include in commercially licensed sources.
+*/
+static char const * const dkct_tr_commercial_text[] = {
+"All rights reserved.",
+NULL
+
+
+#line 409 "dkct-tr.ctr"
+};
+
+#if DK3_USE_WX
+
+#else
+
+#endif
+
+
+
+/** Flag: wxChar is wchar_t
+*/
+static const int is_wx_wide =
+#if DK3_SIZEOF_WXCHAR > 1
+1
+#else
+0
+#endif
+;
+
+
+
+/** Flag: dkChar is wchar_t
+*/
+static const int is_dk_wide =
+#if DK3_CHAR_SIZE > 1
+1
+#else
+0
+#endif
+;
+
+
+
+static const int is_on_windows =
+#if DK3_ON_WINDOWS || defined(_WIN32)
+1
+#else
+0
+#endif
+;
+
+
+
+/** Compare two stored lines by line number.
+ @param l Left DKCT_LINE object.
+ @param r Right DKCT_LINE object.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+static
+int
+dkct_tr_line_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ DKCT_LINE const *pl; /* Left line. */
+ DKCT_LINE const *pr; /* Right line. */
+ if(l) {
+ if(r) {
+ pl = (DKCT_LINE const *)l; pr = (DKCT_LINE const *)r;
+ if(pl->l > pr->l) { back = 1; }
+ else {
+ if(pl->l < pr->l) { back = -1; }
+ }
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ }
+ return back;
+}
+
+
+
+void
+dkct_tr_line_delete(DKCT_LINE *p)
+{
+
+
+#line 486 "dkct-tr.ctr"
+ if(p) {
+
+#line 487 "dkct-tr.ctr"
+ dk3_release(p->t);
+ p->l = 0UL;
+ dk3_delete(p);
+ }
+
+#line 491 "dkct-tr.ctr"
+}
+
+
+
+DKCT_LINE *
+dkct_tr_line_new(char const *t, unsigned long l, dk3_app_t *app)
+{
+ DKCT_LINE *back = NULL;
+
+
+#line 500 "dkct-tr.ctr"
+ if((t) && (l)) {
+ back = dk3_new_app(DKCT_LINE,1,app);
+ if(back) {
+ back->t = NULL;
+ back->l = l;
+ back->t = dk3str_c8_dup_app(t,app);
+ if(!(back->t)) {
+ dkct_tr_line_delete(back);
+ back = NULL;
+ }
+ }
+ }
+
+#line 512 "dkct-tr.ctr"
+ return back;
+}
+
+
+
+/** Compare two state machine descriptions.
+ @param l Left state machine.
+ @param r Right state machine.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+static
+int
+dkct_tr_stm_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ DKCT_STM const *sl; /* Left state machine. */
+ DKCT_STM const *sr; /* Right state machine. */
+ if(l) {
+ if(r) {
+ sl = (DKCT_STM const *)l; sr = (DKCT_STM const *)r;
+ if(sl->lineno > sr->lineno) {
+ back = 1;
+ } else {
+ if(sl->lineno < sr->lineno) {
+ back = -1;
+ }
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Clean up a storage and it's iterator containing DKCT_LINE data.
+ @param s Storage.
+ @param i Iterator.
+*/
+static
+void
+dkct_tr_cleanup_storage_and_iterator(dk3_sto_t *s, dk3_sto_it_t *i)
+{
+ DKCT_LINE *l; /* Current line to clean up. */
+
+
+#line 563 "dkct-tr.ctr"
+ if(s) {
+ if(i) {
+ dk3sto_it_reset(i);
+ while((l = (DKCT_LINE *)dk3sto_it_next(i)) != NULL) {
+
+#line 567 "dkct-tr.ctr"
+ dkct_tr_line_delete(l);
+ }
+ dk3sto_it_close(i);
+ }
+ dk3sto_close(s);
+ }
+
+#line 573 "dkct-tr.ctr"
+}
+
+
+
+void
+dkct_tr_delete(DKCT_SRC *p)
+{
+ DKCT_STM *stmptr; /* Current state machine to clean up. */
+
+
+#line 582 "dkct-tr.ctr"
+ if(p) {
+ if(p->gui) {
+ dkct_gui_delete((DKCT_GUI *)(p->gui));
+ } p->gui = NULL;
+ p->app = NULL;
+ dkct_tr_cleanup_storage_and_iterator(p->hss, p->hsi);
+ dkct_tr_cleanup_storage_and_iterator(p->hes, p->hei);
+ dkct_tr_cleanup_storage_and_iterator(p->clss, p->clsi);
+ dkct_tr_cleanup_storage_and_iterator(p->cles, p->clei);
+ dkct_tr_cleanup_storage_and_iterator(p->mss, p->msi);
+ dkct_tr_cleanup_storage_and_iterator(p->mes, p->mei);
+ dkct_tr_cleanup_storage_and_iterator(p->coss, p->cosi);
+ dkct_tr_cleanup_storage_and_iterator(p->coes, p->coei);
+ p->hss = p->hes = p->clss = p->cles =
+ p->mss = p->mes = p->coss = p->coes = NULL;
+ p->hsi = p->hei = p->clsi = p->clei =
+ p->msi = p->mei = p->cosi = p->coei = NULL;
+ if(p->s_stm) {
+ if(p->i_stm) {
+ dk3sto_it_reset(p->i_stm);
+ while((stmptr = (DKCT_STM *)dk3sto_it_next(p->i_stm)) != NULL) {
+ dkct_au_stm_delete(stmptr);
+ }
+ dk3sto_it_close(p->i_stm);
+ }
+ dk3sto_close(p->s_stm);
+ } p->s_stm = NULL; p->i_stm = NULL; p->cstm = NULL;
+ if(p->crn) {
+
+#line 610 "dkct-tr.ctr"
+ }
+ if(p->cry) {
+
+#line 612 "dkct-tr.ctr"
+ }
+ if(p->lict > -1) {
+
+#line 614 "dkct-tr.ctr"
+ }
+ p->ffn = NULL;
+ dk3_release(p->crn);
+ dk3_release(p->cry);
+ dk3_release(p->sfn);
+ dk3_release(p->cmdb);
+ p->szcmd = 0; p->ucmd = 0; p->fipo = NULL;
+ p->msg = NULL;
+ dk3_delete(p);
+ }
+
+#line 624 "dkct-tr.ctr"
+}
+
+
+
+DKCT_SRC *
+dkct_tr_new(
+ DKCT_OPTION_SET *o,
+ char const *fn,
+ int ai,
+ dk3_app_t *app,
+ dkChar const *ffn
+)
+{
+ DKCT_SRC *back = NULL;
+ int ok = 0; /* Flag: Successfully initialized. */
+ char const *fnptrsfn; /* Pointer to short file name. */
+
+
+#line 641 "dkct-tr.ctr"
+ if((o) && (fn)) {
+ back = dk3_new_app(DKCT_SRC,1,app);
+ if(back) {
+ dk3mem_cpy(&(back->dkcto), o, sizeof(DKCT_OPTION_SET));
+ (back->dkcto).deben = 1;
+ back->ffn = ffn;
+ back->app = app;
+ back->msg = NULL;
+ back->type = ai;
+ back->ec = 0;
+ back->hss = back->hes = back->clss = back->cles =
+ back->mss = back->mes = back->coss = back->coes = NULL;
+ back->hsi = back->hei = back->clsi = back->clei =
+ back->msi = back->mei = back->cosi = back->coei = NULL;
+ back->s_stm = NULL; back->i_stm = NULL;
+ back->sfn = NULL;
+ back->crn = NULL;
+ back->cry = NULL;
+ back->cmdb = NULL;
+ back->lict = -1;
+ back->st = 0;
+ back->szcmd = 0;
+ back->ucmd = 0;
+ back->sufi = 0;
+ back->fipo = NULL;
+ back->cbfip = NULL;
+ back->cbfn = NULL;
+ back->cbmx = 0;
+ back->cbcp = 0;
+ back->cursr = NULL;
+ back->cstm = NULL;
+ back->curdi = 0;
+ back->hss = dk3sto_open_app(app);
+ back->hes = dk3sto_open_app(app);
+ back->clss = dk3sto_open_app(app);
+ back->cles = dk3sto_open_app(app);
+ back->mss = dk3sto_open_app(app);
+ back->mes = dk3sto_open_app(app);
+ back->coss = dk3sto_open_app(app);
+ back->coes = dk3sto_open_app(app);
+ back->s_stm = dk3sto_open_app(app);
+ back->gui = NULL;
+ back->hdr = 0;
+ back->doxyh = 0;
+ back->doxym = 0;
+#if DK3_USE_WX
+ back->pComm = NULL;
+#endif
+ if((back->hss) && (back->hes) && (back->clss) && (back->cles)) {
+ if((back->mss) && (back->mes) && (back->coss) && (back->coes)) {
+ if(back->s_stm) {
+ back->hsi = dk3sto_it_open(back->hss);
+ back->hei = dk3sto_it_open(back->hes);
+ back->clsi = dk3sto_it_open(back->clss);
+ back->clei = dk3sto_it_open(back->cles);
+ back->msi = dk3sto_it_open(back->mss);
+ back->mei = dk3sto_it_open(back->mes);
+ back->cosi = dk3sto_it_open(back->coss);
+ back->coei = dk3sto_it_open(back->coes);
+ back->i_stm = dk3sto_it_open(back->s_stm);
+ if((back->hsi) && (back->hei) && (back->clsi) && (back->clei)) {
+ if((back->msi) && (back->mei) && (back->cosi) && (back->coei)) {
+ if(back->i_stm) {
+ dk3sto_set_comp(back->hss , dkct_tr_line_compare, 0);
+ dk3sto_set_comp(back->hes , dkct_tr_line_compare, 0);
+ dk3sto_set_comp(back->clss, dkct_tr_line_compare, 0);
+ dk3sto_set_comp(back->cles, dkct_tr_line_compare, 0);
+ dk3sto_set_comp(back->mss , dkct_tr_line_compare, 0);
+ dk3sto_set_comp(back->mes , dkct_tr_line_compare, 0);
+ dk3sto_set_comp(back->coss, dkct_tr_line_compare, 0);
+ dk3sto_set_comp(back->coes, dkct_tr_line_compare, 0);
+ dk3sto_set_comp(back->s_stm, dkct_tr_stm_compare, 0);
+ fnptrsfn = dk3str_c8_rchr(fn, DKCT_TR_SEP);
+ if(fnptrsfn) {
+ fnptrsfn++;
+ } else {
+ fnptrsfn = fn;
+ }
+ back->sfn = dk3str_c8_dup_app(fnptrsfn, app);
+ if(back->sfn) {
+
+#line 721 "dkct-tr.ctr"
+ back->cmdb = dk3_new_app(char,DKCT_LINE_SIZE,app);
+ if(back->cmdb) {
+ back->szcmd = DKCT_LINE_SIZE;
+ ok = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if(!ok) {
+ dkct_tr_delete(back);
+ back = NULL;
+ }
+ }
+ }
+
+#line 739 "dkct-tr.ctr"
+ return back;
+}
+
+
+
+/** Check whether or not an input line is a section header.
+ @param inputline Line to check.
+ @return 1 for section header, 0 otherwise.
+*/
+static
+int
+dkct_tr_is_section_header(char *inputline)
+{
+ int back = 0;
+ char *p1; /* Start of text. */
+
+ if(inputline) {
+ p1 = dk3str_c8_start(inputline, NULL);
+ if(p1) {
+ if(*p1 == '%') {
+ if(p1[1] == '%') {
+ back = 1;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Find section number for input line.
+ @param psrc Source structure.
+ @param inputline Input line to process.
+ @param sufi File suffix index of input file.
+ @return The section number (index in dkct_tr_section_headers).
+*/
+static
+int
+dkct_tr_find_section_number(DKCT_SRC *psrc, char *inputline, int sufi)
+{
+ int back = -1;
+ int ai; /* Array index of section name. */
+ char *p1; /* Section name. */
+
+ p1 = dk3str_c8_start(inputline, NULL);
+ if(p1) {
+ if(*p1 == '%') {
+ if(p1[1] == '%') {
+ p1++; p1++;
+ p1 = dk3str_c8_start(p1, NULL);
+ if(p1) {
+ dk3str_c8_normalize(p1, NULL, ' ');
+ ai = dk3str_c8_array_index(dkct_tr_section_headers, p1, 0);
+ switch(sufi) {
+ case 4: {
+ switch(ai) {
+ case 0: { back = DKCT_SECTION_OPTIONS; } break;
+ case 1: case 2: { back = DKCT_SECTION_HEADER_START; } break;
+ case 3: { back = DKCT_SECTION_HEADER_END; } break;
+ case 4: { back = DKCT_SECTION_CLASS_START; } break;
+ case 5: { back = DKCT_SECTION_CLASS_END; } break;
+ case 6: case 7: { back = DKCT_SECTION_MODULE_START; } break;
+ case 8: { back = DKCT_SECTION_MODULE_END; } break;
+ case 9: { back = DKCT_SECTION_CONSTRUCTOR_START; } break;
+ case 10: { back = DKCT_SECTION_CONSTRUCTOR_END; } break;
+ case 11: { back = DKCT_SECTION_GUI; } break;
+ case 12: { back = DKCT_SECTION_STATE_MACHINE; } break;
+ }
+ } break;
+ case 3: {
+ switch(ai) {
+ case 0: { back = DKCT_SECTION_OPTIONS; } break;
+ case 6: { back = DKCT_SECTION_MODULE_START; } break;
+ }
+ } break;
+ default: {
+ switch(ai) {
+ case 0: { back = DKCT_SECTION_OPTIONS; } break;
+ case 1: { back = DKCT_SECTION_HEADER_START; } break;
+ case 6: { back = DKCT_SECTION_MODULE_START; } break;
+ case 12: { back = DKCT_SECTION_STATE_MACHINE; } break;
+ }
+ } break;
+ }
+ if(back == -1) {
+ dkct_to_log_3(psrc, 1, DK3_LL_ERROR, 43, 44, p1);
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+static
+void
+dkct_tr_expand_copyright_year(DKCT_SRC *psrc)
+{
+ char buf[16*sizeof(int)];
+ dk3_tm_t loctime;
+ dk3_time_t currenttime;
+ char *ptr;
+
+ ptr = dk3str_c8_chr(psrc->cry, 'x');
+ if (NULL != ptr) {
+ if ('x' == ptr[1]) {
+ if ('x' == ptr[2]) {
+ if ('x' == ptr[3]) {
+ if (0 != dk3sf_time(&currenttime)) {
+ if (0 != dk3sf_localtime_app(&loctime, &currenttime, NULL)) {
+ sprintf(buf, "%d", loctime.Y);
+ if (4 == dk3str_c8_len(buf)) {
+ ptr[0] = buf[0];
+ ptr[1] = buf[1];
+ ptr[2] = buf[2];
+ ptr[3] = buf[3];
+ }
+ } else {
+ /* ERROR: Failed to convert timer to local time */
+ }
+ } else {
+ /* ERROR: Failed to get current time */
+ }
+ }
+ }
+ }
+ }
+}
+
+
+
+static
+void
+dkct_tr_check_copyright_year(DKCT_SRC *psrc)
+{
+ dk3_tm_t loctime;
+ dk3_time_t currenttime;
+ int cry;
+ const char *p1;
+
+
+
+#line 883 "dkct-tr.ctr"
+ if (NULL != psrc) {
+ if (NULL != psrc->cry) {
+ p1 = dk3str_c8_rchr(psrc->cry, '-');
+ if (NULL != p1) {
+ p1++;
+ } else {
+ p1 = psrc->cry;
+ }
+
+#line 891 "dkct-tr.ctr"
+ if (0 != dk3ma_i_from_c8_string(&cry, p1, NULL)) {
+
+
+#line 893 "dkct-tr.ctr"
+ if (0 != dk3sf_time(&currenttime)) {
+ if (0 != dk3sf_localtime_app(&loctime, &currenttime, NULL)) {
+
+
+#line 896 "dkct-tr.ctr"
+ if (cry != loctime.Y) {
+ dk3app_log_1(psrc->app, DK3_LL_WARNING, psrc->msg, 113);
+ }
+ } else {
+ /* Failed to convert timer to local time */
+ }
+ } else {
+ /* Failed to obtain current time */
+ }
+ } else {
+ /* Failed to read integer from text */
+ }
+ }
+ }
+
+#line 910 "dkct-tr.ctr"
+}
+
+
+
+/** Process an option (key/value pair).
+ @param psrc Source structure.
+ @param key Key (option name).
+ @param val Value.
+ @param sufi Source file type.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_tr_process_option(DKCT_SRC *psrc, char *key, char *val, int sufi)
+{
+ int back = 0;
+
+
+#line 927 "dkct-tr.ctr"
+ switch(dk3str_c8_array_index(dkct_option_keywords, key, 0)) {
+ case 0: {
+
+#line 929 "dkct-tr.ctr"
+ if(psrc->crn) {
+ /* Warning: Redefinition of copyright owner */
+ dkct_to_log_1(psrc, 1, DK3_LL_WARNING, 4);
+ dk3_release(psrc->crn);
+ }
+ psrc->crn = dk3str_c8_dup_app(val, psrc->app);
+ if(psrc->crn) {
+ back = 1;
+ } else {
+ psrc->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory */
+ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } break;
+ case 1: {
+
+#line 944 "dkct-tr.ctr"
+ if(psrc->cry) {
+ /* Warning: Redefinition of copyright year(s)! */
+ dkct_to_log_1(psrc, 1, DK3_LL_WARNING, 5);
+ dk3_release(psrc->cry);
+ }
+ psrc->cry = dk3str_c8_dup_app(val, psrc->app);
+ if(psrc->cry) {
+ dkct_tr_expand_copyright_year(psrc);
+ dkct_tr_check_copyright_year(psrc);
+ back = 1;
+ } else {
+ psrc->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory */
+ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } break;
+ case 2: {
+
+#line 961 "dkct-tr.ctr"
+ if(psrc->lict >= 0) {
+ /* Warning: Redefinition of license! */
+ dkct_to_log_1(psrc, 1, DK3_LL_WARNING, 6);
+ }
+ psrc->lict = dk3str_c8_array_index(dkct_license_names, val, 0);
+ if(psrc->lict >= 0) {
+ back = 1;
+ } else {
+ /* ERROR: Unknown license! */
+ dkct_to_log_3(psrc, 1, DK3_LL_ERROR, 7, 8, val);
+ psrc->ec = DK3_ERROR_SYNTAX;
+ }
+ } break;
+ case 3: {
+
+#line 975 "dkct-tr.ctr"
+ if (val) {
+ (psrc->dkcto).spls = *val;
+ } else {
+ (psrc->dkcto).spls = '@';
+ }
+ back = 1;
+ } break;
+ default: {
+ dkct_to_log_3(psrc, 1, DK3_LL_ERROR, 10, 11, key);
+ back = 0;
+ } break;
+ }
+
+#line 987 "dkct-tr.ctr"
+ return back;
+}
+
+
+
+/** Check whether the line contains a doxygen file start comment.
+ @param inputline Line to check.
+ @return 1 if comment found, 0 otherwise.
+*/
+static
+int
+dkct_tr_has_doxygen_file_comment(char *inputline)
+{
+ int back = 0;
+ char *p1;
+
+ p1 = strstr(inputline, "/**");
+ if (NULL != p1) {
+ p1 = dk3str_c8_start(&(p1[3]), NULL);
+ if (NULL != p1) {
+ if ('@' == *(p1++)) {
+ if ('f' == *(p1++)) {
+ if ('i' == *(p1++)) {
+ if ('l' == *(p1++)) {
+ if ('e' == *(p1++)) {
+ if ((' ' == *p1) || ('\t' == *p1)) {
+ back = 1;
+ } else {
+ if (('\r' == *p1) || ('\n' == *p1) || ('\0' == *p1)) {
+ back = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dkct_tr_read(DKCT_SRC *psrc, dkChar const *fn, int sufi)
+{
+ int back = 0;
+ dk3_sto_t *stp = NULL; /* Current storage to save lines. */
+ FILE *fipo = NULL; /* Input file. */
+ DKCT_LINE *pline = NULL; /* Input line to store. */
+ unsigned long lineno = 0UL; /* Input line number. */
+ int cc = 1; /* Flag: Can continue processing. */
+ int section = DKCT_SECTION_MODULE_START; /* Current section. */
+ char inputline[DKCT_LINE_SIZE]; /* Input line buffer. */
+ char *p1; /* Option name. */
+ char *p2; /* Option value. */
+
+
+#line 1045 "dkct-tr.ctr"
+ if((psrc) && (fn)) {
+
+#line 1046 "dkct-tr.ctr"
+ fipo = dk3sf_fopen_app(fn, dk3app_not_localized(22), psrc->app);
+ if(fipo) {
+
+#line 1048 "dkct-tr.ctr"
+ back = 1;
+ switch(sufi) {
+ case 4: {
+ section = DKCT_SECTION_GUI;
+ } break;
+ default: {
+ stp = psrc->mss;
+ } break;
+ }
+ psrc->hdr = 0;
+ psrc->doxyh = 0;
+ psrc->doxym = 0;
+ do {
+ cc = 0;
+ if(fgets(inputline, sizeof(inputline), fipo)) {
+ cc = 1; lineno++;
+ psrc->lineno = lineno;
+ dk3app_set_source_line(psrc->app, lineno);
+ dk3str_c8_delnl(inputline);
+
+#line 1067 "dkct-tr.ctr"
+ if(dkct_tr_is_section_header(inputline)) {
+ /*
+ Start of new section.
+ */
+ stp = NULL;
+ psrc->cstm = NULL;
+ psrc->hdr = 0;
+ section = dkct_tr_find_section_number(psrc, inputline, sufi);
+ if(section == -1) {
+ psrc->ec = DK3_ERROR_SYNTAX;
+
+#line 1077 "dkct-tr.ctr"
+ cc = 0;
+ } else {
+ switch(section) {
+ case DKCT_SECTION_MODULE_START: {
+ stp = psrc->mss;
+ } break;
+ case DKCT_SECTION_MODULE_END: {
+ stp = psrc->mes;
+ } break;
+ case DKCT_SECTION_CONSTRUCTOR_START: {
+ stp = psrc->coss;
+ } break;
+ case DKCT_SECTION_CONSTRUCTOR_END: {
+ stp = psrc->coes;
+ } break;
+ case DKCT_SECTION_HEADER_START: {
+ stp = psrc->hss;
+ psrc->hdr = 1;
+ } break;
+ case DKCT_SECTION_HEADER_END: {
+ stp = psrc->hes;
+ psrc->hdr = 1;
+ } break;
+ case DKCT_SECTION_CLASS_START: {
+ stp = psrc->clss;
+ } break;
+ case DKCT_SECTION_CLASS_END: {
+ stp = psrc->cles;
+ } break;
+ case DKCT_SECTION_STATE_MACHINE: {
+ psrc->cstm = dkct_au_stm_new(lineno, psrc->app);
+ if(psrc->cstm) {
+
+#line 1109 "dkct-tr.ctr"
+ if(!dk3sto_add(psrc->s_stm, (void *)(psrc->cstm))) {
+
+#line 1110 "dkct-tr.ctr"
+ dkct_au_stm_delete(psrc->cstm);
+ psrc->cstm = NULL;
+ }
+ } else {
+ /* ERROR: Memory! */
+ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } break;
+ case DKCT_SECTION_GUI: {
+ if(!(psrc->gui)) {
+ psrc->gui = (void *)dkct_gui_new(psrc);
+ }
+ if(!(psrc->gui)) {
+ back = 0;
+ psrc->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory! */
+ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } break;
+ }
+ }
+ } else {
+ /*
+ Apply line to current section.
+ */
+ switch(section) {
+ case DKCT_SECTION_OPTIONS: {
+ p1 = dk3str_c8_start(inputline, NULL);
+ if(p1) {
+ if(*p1 != '#') {
+ p2 = dk3str_c8_chr(p1, '=');
+ if(p2) {
+ *(p2++) = '\0';
+ p2 = dk3str_c8_start(p2, NULL);
+ if(p2) {
+ dk3str_c8_normalize(p1, NULL, '-');
+ dk3str_c8_chomp(p2, NULL);
+ if(!dkct_tr_process_option(psrc, p1, p2, sufi)) {
+ cc = 0; psrc->ec = DK3_ERROR_SYNTAX;
+ }
+ } else {
+ /* ERROR: Syntax */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 9);
+ psrc->ec = DK3_ERROR_SYNTAX; cc = 0;
+ }
+ } else {
+ /* ERROR: Syntax */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 9);
+ psrc->ec = DK3_ERROR_SYNTAX; cc = 0;
+ }
+ }
+ }
+ } break;
+ case DKCT_SECTION_GUI: {
+ if(psrc->gui) {
+ if(back) {
+ if(!dkct_gui_add_line((DKCT_GUI *)(psrc->gui), inputline)) {
+ back = 0;
+
+#line 1168 "dkct-tr.ctr"
+ if(psrc->ec == 0) {
+ psrc->ec = DK3_ERROR_MEMORY;
+ }
+ }
+ }
+ } else {
+ back = 0;
+ psrc->ec = DK3_ERROR_MEMORY;
+ }
+ } break;
+ case DKCT_SECTION_STATE_MACHINE: {
+ if(!dkct_au_add_line(psrc->cstm, psrc, inputline, lineno)) {
+ back = 0;
+
+#line 1181 "dkct-tr.ctr"
+ }
+ } break;
+ default: {
+ if (0 < psrc->hdr) {
+ if (0 == psrc->doxyh) {
+ if (dkct_tr_has_doxygen_file_comment(inputline)) {
+ psrc->doxyh = 1;
+ }
+ }
+ } else {
+ if (0 == psrc->doxym) {
+ if (dkct_tr_has_doxygen_file_comment(inputline)) {
+ psrc->doxym = 1;
+ }
+ }
+ }
+ if(section > -1) {
+ if(stp) {
+ pline = dkct_tr_line_new(inputline, lineno, psrc->app);
+ if(pline) {
+ if(!dk3sto_add(stp, pline)) {
+ dkct_tr_line_delete(pline); pline = NULL;
+ psrc->ec = DK3_ERROR_MEMORY; cc = 0;
+ }
+ } else {
+ psrc->ec = DK3_ERROR_MEMORY; cc = 0;
+ /* ERROR: Memory! */
+ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ psrc->ec = DK3_ERROR_MEMORY; cc = 0;
+ }
+ } else {
+ psrc->ec = DK3_ERROR_SYNTAX; cc = 0;
+ }
+ } break;
+ }
+ }
+ }
+#if DK3_USE_WX
+
+#endif
+ } while((cc) && (!(psrc->ec)));
+ /*
+ On error we can not return success.
+ */
+ if(psrc->ec) {
+
+#line 1228 "dkct-tr.ctr"
+ back = 0;
+ }
+ fclose(fipo);
+ } else {
+ /* ERROR: Failed to open file! */
+ dkct_to_log_dk_3(psrc, 0, DK3_LL_ERROR, 20, 21, fn);
+ }
+ }
+
+#line 1236 "dkct-tr.ctr"
+ return back;
+}
+
+
+
+int
+dkct_tr_check(DKCT_SRC *psrc, dkChar const *fn, int sufi)
+{
+ int back = 0;
+ DKCT_STM *pstm; /* Current state machine to check. */
+ unsigned long stmno; /* Index of current state machine. */
+
+
+
+#line 1249 "dkct-tr.ctr"
+ switch(sufi) {
+ case 4: {
+ back = dkct_gui_check(psrc);
+ } break;
+ default: {
+ back = 1;
+ } break;
+ }
+ if(back) {
+
+#line 1258 "dkct-tr.ctr"
+ /*
+ Check state machines consistency
+ */
+ dk3sto_it_reset(psrc->i_stm);
+ stmno = 0UL;
+ while((pstm = (DKCT_STM *)dk3sto_it_next(psrc->i_stm)) != NULL) {
+ pstm->stmno = stmno++;
+ if(!dkct_au_stm_check(psrc, pstm)) {
+ back = 0;
+
+#line 1267 "dkct-tr.ctr"
+ }
+ }
+ }
+
+#line 1270 "dkct-tr.ctr"
+ return back;
+}
+
+
+
+/** Check whether data for a header file is available.
+ @param psrc Source structure.
+ @return 1 if header data is available, 0 otherwise.
+*/
+static
+int
+dkct_tr_have_header_data(DKCT_SRC *psrc)
+{
+ int back = 0;
+ DKCT_STM *pstm; /* Current state machine to check for header data. */
+
+
+#line 1286 "dkct-tr.ctr"
+ if(psrc->hsi) {
+ if(dk3sto_it_next(psrc->hsi)) {
+ back = 1;
+ }
+ }
+ if(psrc->hei) {
+ if(dk3sto_it_next(psrc->hei)) {
+ back = 1;
+ }
+ }
+ if(psrc->clsi) {
+ if(dk3sto_it_next(psrc->clsi)) {
+ back = 1;
+ }
+ }
+ if(psrc->clei) {
+ if(dk3sto_it_next(psrc->clei)) {
+ back = 1;
+ }
+ }
+ if(psrc->i_stm) {
+ dk3sto_it_reset(psrc->i_stm);
+ while((pstm = (DKCT_STM *)dk3sto_it_next(psrc->i_stm)) != NULL) {
+ if(pstm->wrh) {
+ back = 1;
+ }
+ }
+ }
+
+#line 1314 "dkct-tr.ctr"
+ return back;
+}
+
+
+
+/** Check whether data for a module file is available.
+ @param psrc Source structure.
+ @return 1 if module data is available, 0 otherwise.
+*/
+static
+int
+dkct_tr_have_module_data(DKCT_SRC *psrc)
+{
+ int back = 0;
+
+
+#line 1329 "dkct-tr.ctr"
+ if(psrc->msi) {
+ if(dk3sto_it_next(psrc->msi)) {
+ back = 1;
+ }
+ }
+ if(psrc->mei) {
+ if(dk3sto_it_next(psrc->mei)) {
+ back = 1;
+ }
+ }
+ if(psrc->cosi) {
+ if(dk3sto_it_next(psrc->cosi)) {
+ back = 1;
+ }
+ }
+ if(psrc->coei) {
+ if(dk3sto_it_next(psrc->coei)) {
+ back = 1;
+ }
+ }
+ if(psrc->i_stm) {
+ dk3sto_it_reset(psrc->i_stm);
+ while(dk3sto_it_next(psrc->i_stm) != NULL) {
+ back = 1;
+ }
+ }
+
+#line 1355 "dkct-tr.ctr"
+ return back;
+}
+
+
+
+/** Write one text paragraph to output file.
+ @param fipo Output file.
+ @param tptr Pointer to text.
+*/
+static
+void
+dkct_tr_write_text(FILE *fipo, char const * const *tptr)
+{
+ char const * const *ptr; /* Write a text to file. */
+
+
+#line 1370 "dkct-tr.ctr"
+ ptr = tptr;
+ while(*ptr) {
+ fputs(*(ptr++), fipo);
+ fputc('\n', fipo);
+ }
+}
+
+
+
+/** Write copyright and license information for a known license name.
+ @param psrc Source structure.
+ @param license_text License text to print to file.
+*/
+static
+void
+dkct_tr_write_copyright_and_license_internal(
+ DKCT_SRC *psrc, char const * const *license_text
+)
+{
+
+
+#line 1390 "dkct-tr.ctr"
+ fputs(dkct_tr_kw8[2], psrc->fipo);
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+ if(psrc->crn) {
+
+#line 1393 "dkct-tr.ctr"
+ fputs(dkct_tr_kw8[4], psrc->fipo);
+ if(psrc->cry) {
+ fputs(psrc->cry, psrc->fipo);
+ fputs(dkct_tr_kw8[5], psrc->fipo);
+ }
+ fputs(psrc->crn, psrc->fipo);
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+ }
+ dkct_tr_write_text(psrc->fipo, license_text);
+ fputs(dkct_tr_kw8[3], psrc->fipo);
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+
+
+#line 1407 "dkct-tr.ctr"
+}
+
+
+
+/** Check whether we need to add a short description line
+ to the doxygen file tag.
+ If the output file is *.h and there is a *.dox file we can leave the
+ doxygen file tag in the header file empty as the *.dox file
+ contains the detailed description.
+ @param psrc Source structure.
+ @param ofn Output file name.
+ @return 1 to add description, 0 for empty tag.
+*/
+static
+int
+dkct_tr_need_file_description(DKCT_SRC *psrc, dkChar const *ofn)
+{
+ dkChar fnb[DK3_MAX_PATH];
+ dk3_stat_t st;
+ dkChar *fns;
+ int back = 1;
+ if(dk3str_len(ofn) < DK3_SIZEOF(fnb,dkChar)) {
+ dk3str_cpy_not_overlapped(fnb,ofn);
+ fns = dk3str_get_suffix(fnb);
+ if(fns) {
+#if DK3_HAVE_FNCASEINS
+ if(dk3str_casecmp(dkct_tr_kw[0], fns) == 0)
+#else
+ if(dk3str_cmp(dkct_tr_kw[0], fns) == 0)
+#endif
+ {
+ *fns = dkT('\0');
+ if(
+ (dk3str_len(fnb) + dk3str_len(dkct_tr_kw[1]))
+ < DK3_SIZEOF(fnb,dkChar)
+ )
+ {
+ dk3str_cat(fnb, dkct_tr_kw[1]);
+ if(dk3sf_stat_app(&st, fnb, NULL)) {
+ switch((st.ft) & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_REGULAR: {
+ back = 0;
+ } break;
+ }
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Write start of output file.
+ @param psrc Source structure.
+ @param ofn Output file name.
+ @param sfn Source file name.
+ @param f_hdr Flag: Output is a header file.
+*/
+static
+void
+dkct_tr_write_file_start(
+ DKCT_SRC *psrc, dkChar const *ofn, dkChar const *sfn, int f_hdr
+)
+{
+ char const * const *license_text_ptr = NULL; /* Text pointer. */
+ char myfn[DK3_MAX_PATH]; /* Short file name. */
+ char *ptr; /* Text pointer. */
+ char *myshortfn;
+
+
+#line 1478 "dkct-tr.ctr"
+ dkct_tr_write_text(psrc->fipo, dkct_tr_mod_warning_start);
+ if(psrc->sfn) {
+ fputs(dkct_tr_kw8[77], psrc->fipo);
+ fputs(psrc->sfn, psrc->fipo);
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+ }
+ dkct_tr_write_text(psrc->fipo, dkct_tr_mod_warning_end);
+ if((psrc->crn) || (psrc->cry) || (psrc->lict > -1)) {
+ switch(psrc->lict) {
+ case 0: { license_text_ptr = dkct_tr_bsd_text; } break;
+ case 1: { license_text_ptr = dkct_tr_gpl_text; } break;
+ case 2: { license_text_ptr = dkct_tr_lgpl_text; } break;
+ case 3: { } break;
+ case 4: { license_text_ptr = dkct_tr_commercial_text; } break;
+ }
+ if(license_text_ptr) {
+
+#line 1494 "dkct-tr.ctr"
+ dkct_tr_write_copyright_and_license_internal(psrc,license_text_ptr);
+ } else {
+
+#line 1496 "dkct-tr.ctr"
+ /* ##### OTHER LICENSE */
+ }
+ }
+ if (((0 != f_hdr)&&(0 == psrc->doxyh))||((0 == f_hdr)&&(0 == psrc->doxym))) {
+ if(dk3str_string_to_c8_simple_app(myfn, sizeof(myfn), ofn, psrc->app)) {
+ fputs(dkct_tr_kw8[11], psrc->fipo);
+ if(dkct_tr_need_file_description(psrc, ofn)) {
+ myshortfn = dk3str_c8_rchr(myfn, DKCT_TR_SEP);
+ if(myshortfn) {
+ myshortfn++;
+ } else {
+ myshortfn = myfn;
+ }
+ fputs(myshortfn, psrc->fipo);
+ fputs(dkct_tr_kw8[(f_hdr) ? 12 : 14], psrc->fipo);
+ ptr = dk3str_c8_get_suffix(myfn);
+ if(ptr) { *ptr = '\0'; }
+ myshortfn = dk3str_c8_rchr(myfn, DKCT_TR_SEP);
+ if(myshortfn) {
+ myshortfn++;
+ } else {
+ myshortfn = myfn;
+ }
+ fputs(myshortfn, psrc->fipo);
+ fputs(dkct_tr_kw8[13], psrc->fipo);
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+ }
+ fputs(dkct_tr_kw8[3], psrc->fipo);
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+ } else {
+ /* ERROR: Not a simple file name! */
+ dkct_to_log_dk_3(psrc, 1, DK3_LL_ERROR, 12, 13, ofn);
+ }
+ }
+
+
+#line 1532 "dkct-tr.ctr"
+}
+
+
+
+/** Print file name char in upper cases.
+ Characters are printed upper-case, numbers ``as is'', all other
+ characters are replaced by underscore.
+ @param psrc Source structure.
+ @param c Character to print.
+*/
+static
+void
+dkct_tr_char_filename_to_upper(DKCT_SRC *psrc, char c)
+{
+ char oc; /* Output character. */
+ oc = '_';
+ if((c >= 'A') && (c <= 'Z')) {
+ oc = c;
+ } else {
+ if((c >= 'a') && (c <= 'z')) {
+ oc = (char)toupper(c);
+ } else {
+ if((c >= '0') && (c <= '9')) {
+ oc = c;
+ }
+ }
+ }
+ fputc(oc, psrc->fipo);
+}
+
+
+
+/** Print file name upper-case to avoid multiple inclusions.
+ @param psrc Source structure.
+ @param ofn Output file name.
+*/
+static
+void
+dkct_tr_filename_to_upper(DKCT_SRC *psrc, dkChar const *ofn)
+{
+ char b[DK3_MAX_PATH]; /* Temporary file name buffer. */
+ char *ptr; /* Current character to process. */
+ dkChar const *shortofn;
+
+ shortofn = dk3str_rchr(ofn, DK3_CHAR_SEP);
+ if(shortofn) {
+ shortofn++;
+ } else {
+ shortofn = ofn;
+ }
+ if(dk3str_string_to_c8_simple_app(b, sizeof(b), shortofn, psrc->app)) {
+ ptr = b;
+ while(*ptr) {
+ dkct_tr_char_filename_to_upper(psrc, *ptr);
+ ptr++;
+ }
+ } else {
+ /* ERROR: Illegal file name! */
+ dkct_to_log_dk_3(psrc, 1, DK3_LL_ERROR, 12, 13, ofn);
+ }
+}
+
+
+
+void
+dkct_tr_show_source_line(DKCT_SRC *psrc, size_t newlines)
+{
+ size_t i;
+ if(psrc->sufi != 3) {
+ if(newlines > 0) {
+ for(i = 0; i < newlines; i++) {
+ fputc('\n', psrc->fipo);
+ }
+ }
+ fprintf(psrc->fipo, dkct_tr_kw8[20], psrc->lineno, psrc->sfn);
+ }
+}
+
+
+
+#if 0
+/** Process header lines from storage iterator.
+ @param psrc Source structure,
+ @param iterator Iterator for source line storage.
+*/
+static
+void
+dkct_tr_header_lines(DKCT_SRC *psrc, dk3_sto_it_t *iterator)
+{
+ DKCT_LINE *lp; /* Current line to process. */
+
+ if(iterator) {
+ dk3sto_it_reset(iterator);
+ while((lp = (DKCT_LINE *)dk3sto_it_next(iterator)) != NULL) {
+
+
+#line 1627 "dkct-tr.ctr"
+ if(lp->t) {
+
+#line 1628 "dkct-tr.ctr"
+ psrc->lineno = lp->l;
+ if(psrc->shln) {
+ psrc->shln = 0;
+ dkct_tr_show_source_line(psrc, 1);
+ }
+ fputs(lp->t, psrc->fipo);
+ fputc('\n', psrc->fipo);
+ } else {
+
+#line 1636 "dkct-tr.ctr"
+ }
+ }
+ }
+}
+#endif
+
+
+
+/** Find action to process current input character.
+ @param st Pointer to state variable.
+ @param input Current input character.
+ @return Action identifier.
+*/
+static
+int
+dkct_tr_state_machine_transition(int *st, int input)
+{
+ int back = 0;
+ int ns = 0; /* New state. */
+
+
+#line 1656 "dkct-tr.ctr"
+ switch(*st) {
+ case 0: { /* Initial state. */
+ switch(input) {
+ case '\\': { ns = 1; back = DKCT_O_PRINT; } break;
+ case '"': { ns = 2; back = DKCT_O_PRINT; } break;
+ case '\'': { ns = 4; back = DKCT_O_PRINT; } break;
+ case '/': { ns = 6; back = DKCT_O_NOOP; } break;
+ case TRACE_CONTROL: { ns = 10; back = DKCT_O_RESET_BUFFER; } break;
+ default: { ns = 0; back = DKCT_O_PRINT; } break;
+ }
+ } break;
+ case 1: { /* After backslash. */
+ ns = 0; back = DKCT_O_PRINT;
+ } break;
+ case 2: { /* In a string. */
+ back = DKCT_O_PRINT;
+ switch(input) {
+ case '"': { ns = 0; } break;
+ case '\\': { ns = 3; } break;
+ default: { ns = 2; } break;
+ }
+ } break;
+ case 3: { /* After backslash in string. */
+ ns = 2; back = DKCT_O_PRINT;
+ } break;
+ case 4: { /* Single character literal. */
+ back = DKCT_O_PRINT;
+ switch(input) {
+ case '\'': { ns = 0; } break;
+ case '\\': { ns = 5; } break;
+ default: { ns = 4; } break;
+ }
+ } break;
+ case 5: { /* After backslash in character literal. */
+ ns = 4; back = DKCT_O_PRINT;
+ } break;
+ case 6: { /* After slash. */
+ switch(input) {
+ case '/': { ns = 7; back = DKCT_O_START_CPP_COMMENT; } break;
+ case '*': { ns = 8; back = DKCT_O_SLASH_AND_CHAR; } break;
+ default: { ns = 0; back = DKCT_O_SLASH_AND_CHAR; } break;
+ }
+ } break;
+ case 7: { /* In C++ style comment. */
+ switch(input) {
+ case '\n': { ns = 0; back = DKCT_O_END_CPP_COMMENT; } break;
+ default: { ns = 7; back = DKCT_O_PRINT; } break;
+ }
+ } break;
+ case 8: { /* In normal comment. */
+ back = DKCT_O_PRINT;
+ switch(input) {
+ case '*': { ns = 9; } break;
+ default: { ns = 8; } break;
+ }
+ } break;
+ case 9: { /* After * in normal comment. */
+ back = DKCT_O_PRINT;
+ switch(input) {
+ case '*': { ns = 9; } break;
+ case '/': { ns = 0; } break;
+ default: { ns = 8; } break;
+ }
+ } break;
+ case 10: { /* After TRACE_CONTROL. */
+ switch(input) {
+ case '(': { ns = 15; back = DKCT_O_RESET_BUFFER; } break;
+ case '!': { ns = 12; back = DKCT_O_RESET_BUFFER; } break;
+ case '?': { ns = 11; back = DKCT_O_RESET_BUFFER; } break;
+ case '*': { ns = 17; back = DKCT_O_START_BOX; } break;
+ default: { ns = 0; back = DKCT_O_DOLLAR_AND_CHAR; } break;
+ }
+ } break;
+ case 11: { /* After TRACE_CONTROL, ?. */
+ switch(input) {
+ case '\n': { ns = 0; back = DKCT_O_TRACE_OUTPUT; } break;
+ case ' ':
+ case '\t': { ns = 11; back = DKCT_O_NOOP; } break;
+ default: { ns = 13; back = DKCT_O_ADD_BUFFER; } break;
+ }
+ } break;
+ case 12: { /* After TRACE_CONTROL, !. */
+ switch(input) {
+ case '\n': { ns = 0; back = DKCT_O_EXEC_CMD; } break;
+ case ' ':
+ case '\t': { ns = 12; back = DKCT_O_NOOP; } break;
+ default: { ns = 14; back = DKCT_O_ADD_BUFFER; } break;
+ }
+ } break;
+ case 13: { /* In debug output. */
+ switch(input) {
+ case '\n': { ns = 0; back = DKCT_O_TRACE_OUTPUT; } break;
+ default: { ns = 13; back = DKCT_O_ADD_BUFFER; } break;
+ }
+ } break;
+ case 14: { /* In interprete context. */
+ switch(input) {
+ case '\n': { ns = 0; back = DKCT_O_EXEC_CMD; } break;
+ default: { ns = 14; back = DKCT_O_ADD_BUFFER; } break;
+ }
+ } break;
+ case 15: { /* In brackets in interprete context. */
+ switch(input) {
+ case '\n': { ns = 0; back = DKCT_O_PRINT; } break;
+ case ')': { ns = 1; back = DKCT_O_NOOP; } break;
+ case ' ':
+ case '\t': { ns = 15; back = DKCT_O_NOOP; } break;
+ default: { ns = 16; back = DKCT_O_ADD_BUFFER; } break;
+ }
+ } break;
+ case 16: {
+ switch(input) {
+ case ')': { ns = 0; back = DKCT_O_EXEC_CMD; } break;
+ default: { ns = 16; back = DKCT_O_ADD_BUFFER; } break;
+ }
+ } break;
+ case 17: { /* In comment box. */
+ switch(input) {
+ case '\n': { ns = 17; back = DKCT_O_ADD_BOX_NL; } break;
+ case TRACE_CONTROL: { ns = 18; back = DKCT_O_NOOP; } break;
+ default: { ns = 17; back = DKCT_O_ADD_BOX; } break;
+ }
+ } break;
+ case 18: { /* In comment box, found TRACE_CONTROL. */
+ switch(input) {
+ case '*': { ns = 0; back = DKCT_O_END_BOX; } break;
+ default: { ns = 17; back = DKCT_O_ADD_BOX_DOLLAR_CHAR;
+ } break;
+ }
+ } break;
+ }
+ *st = ns;
+
+#line 1788 "dkct-tr.ctr"
+ return back;
+}
+
+
+
+void
+dkct_tr_show_filename_and_lineno(DKCT_SRC *psrc)
+{
+
+
+#line 1797 "dkct-tr.ctr"
+ fputs(dkct_tr_kw8[18], psrc->fipo);
+ fputs(psrc->sfn, psrc->fipo);
+ fputs(dkct_tr_kw8[17], psrc->fipo);
+ fprintf(psrc->fipo, "%lu", psrc->lineno);
+ fputs(dkct_tr_kw8[17], psrc->fipo);
+ fputs(dkct_tr_kw8[1], psrc->fipo);
+ if((psrc->dkcto).tkw) {
+ fputs(dkct_tr_kw8[19], psrc->fipo);
+ }
+ fputs(dkct_tr_kw8[18], psrc->fipo);
+
+
+#line 1808 "dkct-tr.ctr"
+}
+
+
+
+/** Mark buffer as completely empty.
+ @param psrc Source structure.
+*/
+static
+void
+dkct_tr_reset_buffer(DKCT_SRC *psrc)
+{
+ dk3mem_res(psrc->cmdb, psrc->szcmd);
+ psrc->ucmd = 0;
+}
+
+
+
+static
+void
+dkct_tr_convert_printf_format(
+ DKCT_SRC *psrc,
+ int trace_wide,
+ int on_windows,
+ int wx_wide,
+ int dk_wide,
+ char c1,
+ char c2
+)
+{
+ int show_long = 0;
+ int show_short = 0;
+
+ fputc('%', psrc->fipo);
+ if (0 != trace_wide) {
+ if (0 != on_windows) {
+ switch (c1) {
+ case '8' : {
+ show_short = 1;
+ } break;
+ case 'd' : {
+ if (0 != dk_wide) {
+ show_long = 1;
+ } else {
+ show_short = 1;
+ }
+ } break;
+ case 'w' : case 'x' : {
+ if (0 != wx_wide) {
+ show_long = 1;
+ } else {
+ show_short = 1;
+ }
+ } break;
+ }
+ } else {
+ switch (c1) {
+ case 'd' : {
+ if (0 != dk_wide) { show_long = 1; }
+ } break;
+ case 'w' : case 'x' : {
+ if (0 != wx_wide) { show_long = 1; }
+ } break;
+ }
+ }
+ } else {
+ switch (c1) {
+ case 'd' : {
+ if (0 != dk_wide) { show_long = 1; }
+ } break;
+ case 'w' : case 'x' : {
+ if (0 != wx_wide) { show_long = 1; }
+ } break;
+ }
+ }
+ if (0 != show_long) {
+ fputc('l', psrc->fipo);
+ } else {
+ if (0 != show_short) {
+ fputc('h', psrc->fipo);
+ }
+ }
+ fputc(c2, psrc->fipo);
+}
+
+
+
+static
+int
+dkct_tr_must_convert(const char *p)
+{
+ int back = 0;
+ int in_format = 0;
+ while (('\0' != *p) && (0 == back)) {
+ if ('"' == *p) {
+ in_format = ((0 == in_format) ? 1 : 0);
+ if (0 == in_format) { goto finished; }
+ } else {
+ if (0 != in_format) {
+ if ('\\' == *p) {
+ if ('\0' != p[1]) { p++; }
+ else { goto finished; }
+ } else {
+ if ('%' == *p) {
+ if ('%' == p[1]) {
+ p++;
+ } else {
+ if ('!' == p[1]) {
+ switch (p[2]) {
+ case '8' : case 'w' : case 'd' : case 'x' : {
+ switch (p[3]) {
+ case 'c' : case 's' : {
+ back = 1;
+ goto finished;
+ } break;
+ }
+ } break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ p++;
+ }
+ finished:
+ return back;
+}
+
+
+
+static
+void
+dkct_tr_printf_format_and_args(
+ DKCT_SRC *psrc,
+ const char *p,
+ int trace_wide,
+ int on_windows,
+ int wx_wide,
+ int dk_wide
+)
+{
+ int in_format = 0;
+ int must_convert = 0;
+
+ while ('\0' != *p) {
+ if ('"' == *p) {
+ in_format = ((0 == in_format) ? 1 : 0);
+ fputc(*p, psrc->fipo);
+ } else {
+ if (0 != in_format) {
+ if ('\\' == *p) {
+ if ('\0' != p[1]) {
+ fputc(*(p++), psrc->fipo);
+ fputc(*p, psrc->fipo);
+ } else {
+ fputc(*p, psrc->fipo);
+ }
+ } else {
+ if ('%' == *p) {
+ if ('%' == p[1]) {
+ fputc(*(p++), psrc->fipo);
+ fputc(*p, psrc->fipo);
+ } else {
+ must_convert = 0;
+ if ('!' == p[1]) {
+ switch (p[2]) {
+ case '8' : case 'w' : case 'd' : case 'x' : {
+ switch (p[3]) {
+ case 'c' : case 's' : {
+ must_convert = 1;
+ } break;
+ }
+ } break;
+ }
+ }
+ if (0 != must_convert) {
+ dkct_tr_convert_printf_format(
+ psrc, trace_wide, on_windows, wx_wide, dk_wide, p[2], p[3]
+ );
+ p++; p++; p++;
+ } else {
+ fputc(*p, psrc->fipo);
+ }
+ }
+ } else {
+ fputc(*p, psrc->fipo);
+ }
+ }
+ } else {
+ fputc(*p, psrc->fipo);
+ }
+ }
+ p++;
+ }
+}
+
+
+
+/** Write trace information instructions to output.
+ @param psrc Source structure.
+*/
+static
+void
+dkct_tr_trace_output(DKCT_SRC *psrc)
+{
+ char const *fnptr = NULL; /* File to use for debug output. */
+ int mconv = 0; /* Flag: Must convert to multiple lines. */
+
+ if(((psrc->dkcto).deb) && ((psrc->dkcto).deben)) {
+ switch(psrc->sufi) {
+ case 3: {
+ /*
+ Java
+ */
+ fputs(dkct_tr_kw8[15], psrc->fipo);
+ dkct_tr_show_filename_and_lineno(psrc);
+ fputs(dkct_tr_kw8[16], psrc->fipo);
+ if(psrc->ucmd > 0) {
+ fputs(psrc->cmdb, psrc->fipo);
+ } else {
+ fputs(dkct_tr_kw8[1], psrc->fipo);
+ }
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+ } break;
+ /*
+ C/C++
+ */
+ default: {
+ fnptr = dkct_tr_kw8[((psrc->dkcto).deb == 2) ? 28 : 29];
+ mconv = dkct_tr_must_convert(psrc->cmdb);
+ fputs(dkct_tr_kw8[24], psrc->fipo); /* TRACE BEGIN */
+ if(((psrc->dkcto).win) || ((psrc->dkcto).port)) {
+ /*
+ Mit wide char Code.
+ */
+ fputs(dkct_tr_kw8[21], psrc->fipo);
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_kw8[30], psrc->fipo); /* if(dktrace_file()) */
+ }
+ if((psrc->dkcto).ts) {
+ if((psrc->dkcto).deb == 2) {
+ fputs(dkct_tr_kw8[72], psrc->fipo); /* dktrace_time(); */
+ } else {
+ fputs(dkct_tr_kw8[71], psrc->fipo);
+ }
+ }
+ fputs(dkct_tr_kw8[61], psrc->fipo); /* fputs( */
+ dkct_tr_show_filename_and_lineno(psrc);
+ fputs(dkct_tr_kw8[35], psrc->fipo); /* , */
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_kw8[34], psrc->fipo); /* ); */
+ if(psrc->ucmd > 0) {
+ if (((psrc->dkcto).port) && (0 != mconv)) {
+ fputs(dkct_tr_kw8[85], psrc->fipo);
+ /* + wide, windows */
+ fputs(dkct_tr_kw8[83], psrc->fipo);
+ /* +++ wide, windows, wx wide */
+ fputs(dkct_tr_kw8[84], psrc->fipo);
+ /* +++++ wide, windows, wx wide, dk wide */
+ dkct_tr_show_source_line(psrc, 0);
+ fputs(dkct_tr_kw8[62], psrc->fipo); /* fwprintf( */
+ fputs(fnptr, psrc->fipo); /* file name ( stdout */
+ fputs(dkct_tr_kw8[63], psrc->fipo);
+ dkct_tr_printf_format_and_args( psrc, psrc->cmdb, 1, 1, 1, 1);
+ fputs(dkct_tr_kw8[34], psrc->fipo); /* ); */
+ /* ----- wide, windows, wx wide, dk wide */
+ fputs(dkct_tr_kw8[22], psrc->fipo);
+ /* +++++ wide, windows, wx wide, dk not wide */
+ dkct_tr_show_source_line(psrc, 0);
+ fputs(dkct_tr_kw8[62], psrc->fipo); /* fwprintf( */
+ fputs(fnptr, psrc->fipo); /* file name ( stdout */
+ fputs(dkct_tr_kw8[63], psrc->fipo);
+ dkct_tr_printf_format_and_args(psrc, psrc->cmdb, 1, 1, 1, 0);
+ fputs(dkct_tr_kw8[34], psrc->fipo); /* ); */
+ /* ----- wide, windows, wx wide, dk not wide */
+ fputs(dkct_tr_kw8[23], psrc->fipo);
+ /* --- wide, windows, wx wide */
+ fputs(dkct_tr_kw8[22], psrc->fipo);
+ /* +++ wide, windows, wx not wide */
+ fputs(dkct_tr_kw8[84], psrc->fipo);
+ /* +++++ wide, windows, wx not wide, dk wide */
+ dkct_tr_show_source_line(psrc, 0);
+ fputs(dkct_tr_kw8[62], psrc->fipo); /* fwprintf( */
+ fputs(fnptr, psrc->fipo); /* file name ( stdout */
+ fputs(dkct_tr_kw8[63], psrc->fipo);
+ dkct_tr_printf_format_and_args(psrc, psrc->cmdb, 1, 1, 0, 1);
+ fputs(dkct_tr_kw8[34], psrc->fipo); /* ); */
+ /* ----- wide, windows, wx not wide, dk wide */
+ fputs(dkct_tr_kw8[22], psrc->fipo);
+ /* +++++ wide, windows, wx not wide, dk not wide */
+ dkct_tr_show_source_line(psrc, 0);
+ fputs(dkct_tr_kw8[62], psrc->fipo); /* fwprintf( */
+ fputs(fnptr, psrc->fipo); /* file name ( stdout */
+ fputs(dkct_tr_kw8[63], psrc->fipo);
+ dkct_tr_printf_format_and_args(psrc, psrc->cmdb, 1, 1, 0, 0);
+ fputs(dkct_tr_kw8[34], psrc->fipo); /* ); */
+ /* -----wide, windows, wx not wide, dk not wide */
+ fputs(dkct_tr_kw8[23], psrc->fipo);
+ /* --- wide, windows, wx not wide */
+ fputs(dkct_tr_kw8[23], psrc->fipo);
+ /* - wide, windows */
+ fputs(dkct_tr_kw8[22], psrc->fipo);
+ /* + wide, not windows */
+ fputs(dkct_tr_kw8[83], psrc->fipo);
+ /* +++ wide, not windows, wx wide */
+ fputs(dkct_tr_kw8[84], psrc->fipo);
+ /* +++++ wide, not windows, wx wide, dk wide */
+ dkct_tr_show_source_line(psrc, 0);
+ fputs(dkct_tr_kw8[62], psrc->fipo); /* fwprintf( */
+ fputs(fnptr, psrc->fipo); /* file name ( stdout */
+ fputs(dkct_tr_kw8[63], psrc->fipo);
+ dkct_tr_printf_format_and_args(psrc, psrc->cmdb, 1, 0, 1, 1);
+ fputs(dkct_tr_kw8[34], psrc->fipo); /* ); */
+ /* ----- wide, not windows, wx wide, dk wide */
+ fputs(dkct_tr_kw8[22], psrc->fipo);
+ /* +++++ wide, not windows, wx wide, dk not wide */
+ dkct_tr_show_source_line(psrc, 0);
+ fputs(dkct_tr_kw8[62], psrc->fipo); /* fwprintf( */
+ fputs(fnptr, psrc->fipo); /* file name ( stdout */
+ fputs(dkct_tr_kw8[63], psrc->fipo);
+ dkct_tr_printf_format_and_args(psrc, psrc->cmdb, 1, 0, 1, 0);
+ fputs(dkct_tr_kw8[34], psrc->fipo); /* ); */
+ /* ----- wide, not windows, wx wide, dk not wide */
+ fputs(dkct_tr_kw8[23], psrc->fipo);
+ /* --- wide, not windows, wx wide */
+ fputs(dkct_tr_kw8[22], psrc->fipo);
+ /* +++ wide, not windows, wx not wide */
+ fputs(dkct_tr_kw8[84], psrc->fipo);
+ /* +++++ wide, not windows, wx not wide, dk wide */
+ dkct_tr_show_source_line(psrc, 0);
+ fputs(dkct_tr_kw8[62], psrc->fipo); /* fwprintf( */
+ fputs(fnptr, psrc->fipo); /* file name ( stdout */
+ fputs(dkct_tr_kw8[63], psrc->fipo);
+ dkct_tr_printf_format_and_args(psrc, psrc->cmdb, 1, 0, 0, 1);
+ fputs(dkct_tr_kw8[34], psrc->fipo); /* ); */
+ /* ----- wide, not windows, wx not wide, dk wide */
+ fputs(dkct_tr_kw8[22], psrc->fipo);
+ /* +++++ wide, not windows, wx not wide, dk not wide */
+ dkct_tr_show_source_line(psrc, 0);
+ fputs(dkct_tr_kw8[62], psrc->fipo); /* fwprintf( */
+ fputs(fnptr, psrc->fipo); /* file name ( stdout */
+ fputs(dkct_tr_kw8[63], psrc->fipo);
+ dkct_tr_printf_format_and_args(psrc, psrc->cmdb, 1, 0, 0, 0);
+ fputs(dkct_tr_kw8[34], psrc->fipo); /* ); */
+ /* ----- wide, not windows, wx not wide, dk not wide */
+ fputs(dkct_tr_kw8[23], psrc->fipo);
+ /* --- wide, not windows, wx not wide */
+ fputs(dkct_tr_kw8[23], psrc->fipo);
+ /* - wide, not windows */
+ fputs(dkct_tr_kw8[23], psrc->fipo);
+ } else {
+ dkct_tr_show_source_line(psrc, 0);
+ fputs(dkct_tr_kw8[62], psrc->fipo); /* fwprintf( */
+ fputs(fnptr, psrc->fipo); /* file name ( stdout */
+ fputs(dkct_tr_kw8[63], psrc->fipo);
+#if 0
+ fputs(psrc->cmdb, psrc->fipo);
+#endif
+ dkct_tr_printf_format_and_args(
+ psrc, psrc->cmdb, 1, is_on_windows, is_wx_wide, is_dk_wide
+ );
+ fputs(dkct_tr_kw8[34], psrc->fipo); /* ); */
+ }
+ fputs(dkct_tr_kw8[64], psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_kw8[34], psrc->fipo);
+ fputs(dkct_tr_kw8[37], psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_kw8[34], psrc->fipo);
+ }
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_kw8[31], psrc->fipo);
+ }
+ fputs(dkct_tr_kw8[22], psrc->fipo);
+ }
+ /*
+ Mit oder ohne wide char (in beiden Faellen).
+ */
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_kw8[30], psrc->fipo); /* if(dktrace_file()) */
+ }
+ if((psrc->dkcto).ts) {
+ if((psrc->dkcto).deb == 2) {
+ fputs(dkct_tr_kw8[70], psrc->fipo); /* dktrace_time(); */
+ } else {
+ fputs(dkct_tr_kw8[32], psrc->fipo);
+ }
+ }
+ fputs(dkct_tr_kw8[33], psrc->fipo); /* fputs( */
+ dkct_tr_show_filename_and_lineno(psrc);
+ fputs(dkct_tr_kw8[35], psrc->fipo); /* , */
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_kw8[34], psrc->fipo); /* ); */
+ if(psrc->ucmd > 0) {
+ if (((psrc->dkcto).port) && (0 != mconv)) {
+ fputs(dkct_tr_kw8[83], psrc->fipo);
+ /* +++ not-wide, wx wide */
+ fputs(dkct_tr_kw8[84], psrc->fipo);
+ /* +++++ not-wide, wx wide, dk wide */
+ dkct_tr_show_source_line(psrc, 0);
+ fputs(dkct_tr_kw8[36], psrc->fipo); /* fprintf( */
+ fputs(fnptr, psrc->fipo); /* file name or stdout */
+ fputs(dkct_tr_kw8[35], psrc->fipo);
+ dkct_tr_printf_format_and_args(
+ psrc, psrc->cmdb, 0, is_on_windows, 1, 1
+ );
+ fputs(dkct_tr_kw8[34], psrc->fipo); /* ); */
+ /* ----- not-wide, wx wide, dk wide */
+ fputs(dkct_tr_kw8[22], psrc->fipo);
+ /* +++++ not-wide, wx wide, dk not wide */
+ dkct_tr_show_source_line(psrc, 0);
+ fputs(dkct_tr_kw8[36], psrc->fipo); /* fprintf( */
+ fputs(fnptr, psrc->fipo); /* file name or stdout */
+ fputs(dkct_tr_kw8[35], psrc->fipo);
+ dkct_tr_printf_format_and_args(
+ psrc, psrc->cmdb, 0, is_on_windows, 1, 0
+ );
+ fputs(dkct_tr_kw8[34], psrc->fipo); /* ); */
+ /* ----- not-wide, wx wide, dk not wide */
+ fputs(dkct_tr_kw8[23], psrc->fipo);
+ /* --- not-wide, wx wide */
+ fputs(dkct_tr_kw8[22], psrc->fipo);
+ /* +++ not-wide, wx not wide */
+ fputs(dkct_tr_kw8[84], psrc->fipo);
+ /* +++++ not-wide, wx not wide, dk wide */
+ dkct_tr_show_source_line(psrc, 0);
+ fputs(dkct_tr_kw8[36], psrc->fipo); /* fprintf( */
+ fputs(fnptr, psrc->fipo); /* file name or stdout */
+ fputs(dkct_tr_kw8[35], psrc->fipo);
+ dkct_tr_printf_format_and_args(
+ psrc, psrc->cmdb, 0, is_on_windows, 0, 1
+ );
+ fputs(dkct_tr_kw8[34], psrc->fipo); /* ); */
+ /* ----- not-wide, wx not wide, dk wide */
+ fputs(dkct_tr_kw8[22], psrc->fipo);
+ /* +++++ not-wide, wx not wide, dk not wide */
+ dkct_tr_show_source_line(psrc, 0);
+ fputs(dkct_tr_kw8[36], psrc->fipo); /* fprintf( */
+ fputs(fnptr, psrc->fipo); /* file name or stdout */
+ fputs(dkct_tr_kw8[35], psrc->fipo);
+ dkct_tr_printf_format_and_args(
+ psrc, psrc->cmdb, 0, is_on_windows, 0, 0
+ );
+ fputs(dkct_tr_kw8[34], psrc->fipo); /* ); */
+ /* ----- not-wide, wx not wide, dk not wide */
+ fputs(dkct_tr_kw8[23], psrc->fipo);
+ /* --- not-wide, wx not wide */
+ fputs(dkct_tr_kw8[23], psrc->fipo);
+ } else {
+ dkct_tr_show_source_line(psrc, 0);
+ fputs(dkct_tr_kw8[36], psrc->fipo); /* fprintf( */
+ fputs(fnptr, psrc->fipo); /* file name or stdout */
+ fputs(dkct_tr_kw8[35], psrc->fipo);
+#if 0
+ fputs(psrc->cmdb, psrc->fipo);
+#endif
+ dkct_tr_printf_format_and_args(
+ psrc, psrc->cmdb, 0, is_on_windows, is_wx_wide, is_dk_wide
+ );
+ fputs(dkct_tr_kw8[34], psrc->fipo); /* ); */
+ }
+ fputs(dkct_tr_kw8[48], psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_kw8[34], psrc->fipo);
+ fputs(dkct_tr_kw8[37], psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_kw8[34], psrc->fipo);
+ }
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_kw8[31], psrc->fipo);
+ }
+ if(((psrc->dkcto).win) || ((psrc->dkcto).port)) {
+ /*
+ Closing endif for wide char code.
+ */
+ fputs(dkct_tr_kw8[23], psrc->fipo);
+ }
+ fputs(dkct_tr_kw8[25], psrc->fipo);
+ } break;
+ }
+ } else {
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+ }
+}
+
+
+
+/** Create full path name from relative file name.
+ @param psrc Source structure.
+ @param fn Short file name.
+ @param fnb Buffer for full path name.
+ @param szfnb Size of \a fnb.
+ @return Pointer to buffer with full path name on success,
+ NULL on error.
+*/
+static
+char *
+dkct_tr_function_filename(
+ DKCT_SRC *psrc,
+ char *fn,
+ char *fnb,
+ size_t szfnb
+)
+{
+ char *back = NULL;
+ char *ptr;
+ size_t sz;
+ int ie;
+
+
+#line 2318 "dkct-tr.ctr"
+ if(dk3str_c8_is_abs_path(fn) || (psrc->curdi)) {
+
+#line 2319 "dkct-tr.ctr"
+ back = fn;
+ } else {
+
+#line 2321 "dkct-tr.ctr"
+ ie = dk3app_get_encoding(psrc->app);
+ if(dk3str_to_c8p_app(fnb, szfnb, psrc->ffn, ie, psrc->app)) {
+ ptr = dk3str_c8_rchr(fnb, (dkct_tr_kw8[78])[0]);
+
+#line 2324 "dkct-tr.ctr"
+ if(ptr) {
+
+#line 2325 "dkct-tr.ctr"
+ *ptr = '\0';
+
+#line 2326 "dkct-tr.ctr"
+ sz = dk3str_c8_len(fnb);
+ sz += 1;
+ sz += dk3str_c8_len(fn);
+ if(sz < szfnb) {
+
+#line 2330 "dkct-tr.ctr"
+ strcat(fnb, dkct_tr_kw8[78]);
+ strcat(fnb, fn);
+ back = fnb;
+ } else {
+
+#line 2334 "dkct-tr.ctr"
+ /* ERROR: Resulting file name too long! 101 */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 101);
+ }
+ } else {
+
+#line 2338 "dkct-tr.ctr"
+ back = fn;
+ }
+ } else {
+
+#line 2341 "dkct-tr.ctr"
+ /* ERROR: Non-ASCII characters in source file name! */
+ dkct_to_log_dk_3(psrc, 1, DK3_LL_ERROR, 102, 103, psrc->ffn);
+ }
+ }
+
+#line 2345 "dkct-tr.ctr"
+ return back;
+}
+
+
+
+/** Disable debugging.
+ @param psrc Source structure.
+ @param args Arguments (ignored).
+ @return 1 on success, 0 on error.
+
+*/
+static
+int
+dkct_tr_fct_trace_off(DKCT_SRC *psrc, char *args)
+{
+ (psrc->dkcto).deben = 0;
+ return 1;
+}
+
+
+
+/** Enable debugging.
+ @param psrc Source structure.
+ @param args Arguments (ignored).
+ @return 1 on success, 0 on error.
+
+*/
+static
+int
+dkct_tr_fct_trace_on(DKCT_SRC *psrc, char *args)
+{
+ (psrc->dkcto).deben = 1;
+ return 1;
+}
+
+
+
+/** Initialize tracing for source.
+ @param psrc Source structure.
+ @param args Debug output file name.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_tr_fct_trace_init(DKCT_SRC *psrc, char *args)
+{
+ int back = 0;
+
+ if((psrc->dkcto).deb == 1) {
+ if(args) {
+ fputs(dkct_tr_kw8[45], psrc->fipo);
+ fputs(args, psrc->fipo);
+ fputs(dkct_tr_kw8[46], psrc->fipo);
+ if(((psrc->dkcto).win) || ((psrc->dkcto).port)) {
+ fputs(dkct_tr_kw8[82], psrc->fipo);
+ fputs(dkct_tr_kw8[56], psrc->fipo);
+
+ fputs(dkct_tr_kw8[57], psrc->fipo);
+ fputs(dkct_tr_kw8[58], psrc->fipo);
+
+ fputs(dkct_tr_kw8[59], psrc->fipo);
+ fputs(dkct_tr_kw8[23], psrc->fipo);
+ }
+ back = 1;
+ } else {
+ /* ERROR: Missing file name! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 14);
+ }
+ } else {
+ back = 1;
+ if((psrc->dkcto).deb == 2) {
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+ if(((psrc->dkcto).win) || ((psrc->dkcto).port)) {
+ fputs(dkct_tr_kw8[82], psrc->fipo);
+ fputs(dkct_tr_kw8[60], psrc->fipo);
+ fputs(dkct_tr_kw8[23], psrc->fipo);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** End tracing for a source.
+ @param psrc Source structure.
+ @param args Ignored.
+ @return 1 on success always.
+*/
+static
+int
+dkct_tr_fct_trace_end(DKCT_SRC *psrc, char *args)
+{
+ int back = 1;
+
+ if((psrc->dkcto).deb == 1) {
+ fputs(dkct_tr_kw8[47], psrc->fipo);
+ }
+ return back;
+}
+
+
+
+/** Write "#include <dk3trace.h>" to output.
+ @param psrc Source structure.
+ @param args Ignored.
+ @return 1 to indicate success always.
+*/
+static
+int
+dkct_tr_fct_trace_include(DKCT_SRC *psrc, char *args)
+{
+ int back = 0;
+ if((psrc->dkcto).deb) {
+ if(!((psrc->dkcto).tip)) {
+ if((psrc->dkcto).deb == 2) {
+ fputs(dkct_tr_kw8[68], psrc->fipo);
+ }
+ fputs(dkct_tr_kw8[44], psrc->fipo);
+ fputs(dkct_tr_kw8[79], psrc->fipo);
+ }
+ }
+ return back;
+}
+
+
+
+/** Write trace code to output.
+ @param psrc Source structure.
+ @param args Code for debug mode.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_tr_fct_trace_code(DKCT_SRC *psrc, char *args)
+{
+ int back = 0;
+ if(args) {
+ if(((psrc->dkcto).deb) && ((psrc->dkcto).deben)) {
+ fputs(args, psrc->fipo);
+ }
+ back = 1;
+ }
+ return back;
+}
+
+
+
+/** Pipe command output.
+ @param psrc Source structure.
+ @param args Command to execute.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_tr_fct_trace_pipe(DKCT_SRC *psrc, char *args)
+{
+ int back = 0;
+ FILE *fipo = NULL; /* File pointer to read from pipe. */
+ char buffer[4096]; /* Input buffer. */
+ size_t rdbytes; /* Number of bytes read from pipe. */
+ int wrbytes; /* Result from write operation. */
+
+ if(args) {
+ if(psrc->curdi) {
+#if DK3_ON_WINDOWS || (DK3_HAVE__POPEN && (!(DK3_HAVE_POPEN)))
+ fipo = _popen(args, dkct_tr_kw8[49]);
+ if(!(fipo)) {
+ /* ERROR: Failed to open pipe! */
+ dkct_to_log_3(psrc, 1, DK3_LL_ERROR, 15, 16, args);
+ }
+#else
+#if DK3_HAVE_POPEN
+ fipo = popen(args, dkct_tr_kw8[49]);
+ if(!(fipo)) {
+ /* ERROR: Failed to open pipe! */
+ dkct_to_log_3(psrc, 1, DK3_LL_ERROR, 15, 16, args);
+ }
+#else
+ /* ERROR: No popen() function available! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 17);
+#endif
+#endif
+ if(fipo) {
+ back = 1;
+ while(
+ (rdbytes = dk3sf_fread_app(buffer, 1, sizeof(buffer), fipo, psrc->app))
+ > 0
+ )
+ {
+ wrbytes = dk3sf_fwrite_app(buffer, 1, rdbytes, psrc->fipo, psrc->app);
+ if(wrbytes != 1) {
+ back = 0;
+ /* ERROR: Not all bytes written! */
+ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 18);
+ }
+ }
+#if DK3_ON_WINDOWS || (DK3_HAVE__POPEN && (!(DK3_HAVE_POPEN)))
+ _pclose(fipo);
+#else
+#if DK3_HAVE_POPEN
+ pclose(fipo);
+#endif
+#endif
+ }
+ } else {
+ /* ERROR: Not in the current directory! 104 */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 104);
+ }
+ }
+ return back;
+}
+
+
+
+/** Check whether a line contains the dollar exclam end at start
+ @param textline Line to test.
+ @return 1 for line contains pattern, 0 otherwise.
+*/
+static
+int
+dkct_tr_is_end_command(char const *textline)
+{
+ int back = 0;
+ char *p1; /* Text start in line. */
+ size_t ltext; /* Text length. */
+ size_t lpat; /* Pattern length. */
+
+
+#line 2573 "dkct-tr.ctr"
+ if(textline) {
+ p1 = dk3str_c8_start(textline, NULL);
+ if(p1) {
+ ltext = dk3str_c8_len(p1);
+ lpat = dk3str_c8_len(dkct_tr_kw8[51]);
+ if(ltext >= lpat) {
+ if(dk3str_c8_ncmp(p1, dkct_tr_kw8[51], lpat) == 0) {
+ back = 1;
+ }
+ }
+ }
+ }
+
+#line 2585 "dkct-tr.ctr"
+ return back;
+}
+
+
+
+/** Write splint tag, replace special character.
+ @param psrc Source structure.
+ @param splt Splint tag text.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_tr_write_splint_tag(DKCT_SRC *psrc, char const *splt)
+{
+ int back = 1;
+ char const *p1;
+
+
+#line 2602 "dkct-tr.ctr"
+ if ((psrc->dkcto).spls) {
+
+#line 2603 "dkct-tr.ctr"
+ p1 = splt;
+ while (*p1) {
+ if ('@' == *p1) {
+ if (EOF == fputc((psrc->dkcto).spls, psrc->fipo)) { back = 0; }
+ } else {
+ if (EOF == fputc(*p1, psrc->fipo)) { back = 0; }
+ }
+ p1++;
+ }
+ } else {
+
+#line 2613 "dkct-tr.ctr"
+ }
+
+#line 2614 "dkct-tr.ctr"
+ return back;
+}
+
+
+
+/** Generate string table from the following lines.
+ @param psrc Source structure.
+ @param args Command to execute.
+ @return 1 on success, 0 on error.
+*/
+static
+int dkct_tr_fct_string_table(DKCT_SRC *psrc, char *args)
+{
+ char fnb[DK3_MAX_PATH]; /* Buffer for file name. */
+ int back = 1;
+ char *pfile = NULL; /* String table file name. */
+ char *pmacro = NULL; /* Macro around strings. */
+ char *pprefix = NULL; /* Prefix for strings. */
+ char *pc; /* Pointer to current setting. */
+ char *pn; /* Pointer to next setting. */
+ char *pk; /* Setting key. */
+ char *pv; /* Setting value. */
+ FILE *fipo = NULL; /* String table output file. */
+ int cc = 1; /* Flag: Can continue. */
+ DKCT_LINE *lp; /* Current line to process. */
+ char lb[DKCT_LINE_SIZE]; /* Private copy of line. */
+ char *ptr; /* Current character to process. */
+ unsigned long lineno = 0UL; /* Line number of current line. */
+
+ if(args) {
+ pc = dk3str_c8_start(args, NULL);
+ while(pc) {
+ pk = pv = NULL;
+ pn = dk3str_c8_chr(pc, ',');
+ if(pn) { *(pn++) = '\0'; pn = dk3str_c8_start(pn, NULL); }
+ pk = dk3str_c8_start(pc, NULL);
+ if(pk) {
+ pv = dk3str_c8_chr(pk, '=');
+ if(pv) { *(pv++) = '\0'; pv = dk3str_c8_start(pv, NULL); }
+ switch(dk3str_c8_array_index(dkct_tr_string_table_args, pk, 0)) {
+ case 0: { /* file */
+ pfile = pv;
+ } break;
+ case 1: { /* macro */
+ pmacro = pv;
+ } break;
+ case 2: { /* prefix */
+ pprefix = pv;
+ } break;
+ default: {
+ /* ERROR: Unknown key! */
+ dkct_to_log_3(psrc, 1, DK3_LL_ERROR, 76, 77, pk);
+ } break;
+ }
+ } else {
+ /* ERROR: No key */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 33);
+ }
+ pc = pn;
+ }
+ }
+ if((pmacro) && (pprefix)) {
+ /* Warning: Either macro or prefix allowed! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 19);
+ }
+ if(pfile) {
+ pfile = dkct_tr_function_filename(psrc, pfile, fnb, sizeof(fnb));
+ }
+ if(pfile) {
+ fipo = dk3sf_c8_fopen_app(pfile, dkct_tr_kw8[50], psrc->app);
+ if(!(fipo)) {
+ /* ERROR: Failed to open file! */
+ dkct_to_log_3(psrc, 0, DK3_LL_ERROR, 20, 21, pfile);
+ }
+ }
+ if(psrc->cursr) {
+ do {
+ cc = 0;
+ lp = (DKCT_LINE *)dk3sto_it_next(psrc->cursr);
+ if(lp) {
+ if(lp->t) {
+ cc = 1;
+ if(dkct_tr_is_end_command(lp->t)) {
+ cc = 0;
+ } else {
+ if(dk3str_c8_len(lp->t) < sizeof(lb)) {
+ dk3str_c8_cpy(lb, lp->t);
+ /*
+ Write line to output file as is.
+ */
+ dk3str_c8_delnl(lb);
+ if(fipo) { fputs(lb, fipo); fputc('\n', fipo); }
+ /*
+ Generate source string.
+ */
+ if(*(lb) != '#') {
+ fprintf(psrc->fipo, dkct_tr_kw8[66], lineno++);
+ if(pmacro) {
+ fputs(pmacro, psrc->fipo);
+ fputs(dkct_tr_kw8[52], psrc->fipo);
+ }
+ if(pprefix) {
+ fputs(pprefix, psrc->fipo);
+ }
+ fputs(dkct_tr_kw8[55], psrc->fipo);
+ dk3app_squeeze_line(lb);
+ ptr = lb;
+ while(*ptr) {
+ switch(*ptr) {
+ case '\\': {
+ fputc('\\', psrc->fipo);
+ fputc('\\', psrc->fipo);
+ } break;
+ case '"': {
+ fputc('\\', psrc->fipo);
+ fputc('"', psrc->fipo);
+ } break;
+ case '\n': {
+ fputc('\\', psrc->fipo);
+ fputc('n', psrc->fipo);
+ } break;
+ case '\r': {
+ fputc('\\', psrc->fipo);
+ fputc('r', psrc->fipo);
+ } break;
+ case '\t': {
+ fputc('\\', psrc->fipo);
+ fputc('t', psrc->fipo);
+ } break;
+ default: {
+ fputc(*ptr, psrc->fipo);
+ } break;
+ }
+ ptr++;
+ }
+ fputs(dkct_tr_kw8[55], psrc->fipo);
+ if(pmacro) {
+ fputs(dkct_tr_kw8[53], psrc->fipo);
+ }
+ fputs(dkct_tr_kw8[54], psrc->fipo);
+ }
+ } else {
+ /* ERROR: Source line too large. */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 22);
+ }
+ }
+ }
+ }
+ } while(cc);
+ dkct_tr_write_splint_tag(psrc, dkct_tr_kw8[80]);
+ fputs(dkct_tr_kw8[65], psrc->fipo);
+ dkct_tr_write_splint_tag(psrc, dkct_tr_kw8[81]);
+ }
+ if(fipo) {
+#if DK3_CHAR_SIZE == 1
+ if(!dk3sf_fclose_fn_app(fipo, pfile, psrc->app)) {
+ back = 0;
+ }
+#else
+ if(!dk3sf_fclose_fn_app(fipo, NULL, psrc->app)) {
+ back = 0;
+ }
+#endif
+ fipo = NULL;
+ }
+ return back;
+}
+
+
+
+/** Generate text from the following lines.
+ @param psrc Source structure.
+ @param args Command to execute.
+ @return 1 on success, 0 on error.
+*/
+static
+int dkct_tr_fct_text(DKCT_SRC *psrc, char *args)
+{
+ int back = 1;
+ char fnb[DK3_MAX_PATH]; /* Buffer for output file name. */
+ char lb[DKCT_LINE_SIZE]; /* Line buffer. */
+ char *pfile = NULL; /* Output file name. */
+ char *pmacro = NULL; /* Macro name. */
+ char *pprefix = NULL; /* Prefix name. */
+ char *pc; /* Current arg to process. */
+ char *pn; /* Next arg to process. */
+ char *pv; /* Value pointer. */
+ char *ptr; /* Current character to process. */
+ FILE *fipo = NULL; /* Output file. */
+ DKCT_LINE *lp; /* Current line to process. */
+ int cc; /* Flag: Can continue. */
+ int indr; /* Index search result */
+ int preprocessor = 0; /* Flag: Allow preprocessor */
+ int fipopre = 0; /* Flag: Error already reported. */
+
+ pc = dk3str_c8_start(args, NULL);
+ while(pc) {
+ pn = dk3str_c8_chr(pc, ',');
+ if(pn) { *(pn++) = '\0'; pn = dk3str_c8_start(pn, NULL); }
+
+
+#line 2814 "dkct-tr.ctr"
+ pv = dk3str_c8_chr(pc, '=');
+ if(pv) {
+ *(pv++) = '\0'; pv = dk3str_c8_start(pv, NULL);
+ if(pv) {
+ switch(dk3str_c8_array_index(dkct_tr_string_table_args, pc, 0)) {
+ case 0: { pfile = pv; } break;
+ case 1: { pmacro = pv; } break;
+ case 2: { pprefix = pv; } break;
+ case 3: { preprocessor = 1; } break;
+ default: {
+ /* ERROR: Unknown key! */
+ dkct_to_log_3(psrc, 1, DK3_LL_ERROR, 76, 77, pc);
+ } break;
+ }
+ }
+ } else {
+
+#line 2830 "dkct-tr.ctr"
+ switch(indr = dk3str_c8_array_index(dkct_tr_string_table_args, pc, 0)) {
+ case 3: {
+
+#line 2832 "dkct-tr.ctr"
+ preprocessor = 1;
+ } break;
+ default: {
+
+#line 2835 "dkct-tr.ctr"
+ /* ERROR: Not key=value pair */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 33);
+ } break;
+ }
+ }
+ pc = pn;
+ }
+ if(pfile) {
+ pfile = dkct_tr_function_filename(psrc, pfile, fnb, sizeof(fnb));
+ }
+ if(pfile) {
+ fipo = dk3sf_c8_fopen_app(pfile, dkct_tr_kw8[50], psrc->app);
+ if(!(fipo)) {
+ /* ERROR: Failed to open file! */
+ dkct_to_log_3(psrc, 0, DK3_LL_ERROR, 20, 21, pfile);
+ }
+ }
+ if(psrc->cursr) {
+ do {
+ cc = 0;
+ lp = (DKCT_LINE *)dk3sto_it_next(psrc->cursr);
+ if(lp) {
+ if(lp->t) {
+ cc = 1;
+ if(dkct_tr_is_end_command(lp->t)) {
+ cc = 0;
+ } else {
+ if(fipo) { if(lp->t) { fputs(lp->t, fipo); fputc('\n', fipo); } }
+ if(dk3str_c8_len(lp->t) < sizeof(lb)) {
+ dk3str_c8_cpy(lb, lp->t);
+ dk3str_c8_delnl(lb);
+ if (('#' == lb[0]) && (0 != preprocessor)) {
+ fputs(lb, psrc->fipo);
+ fputc('\n', psrc->fipo);
+ if ((NULL != fipo) && (0 == fipopre)) {
+ fipopre = 1;
+ dkct_to_log_1(psrc, 1, DK3_LL_WARNING, 114);
+ }
+ } else {
+ if(pmacro) {
+ fputs(pmacro, psrc->fipo);
+ fputs(dkct_tr_kw8[52], psrc->fipo);
+ } else {
+ if(pprefix) {
+ fputs(pprefix, psrc->fipo);
+ }
+ }
+ fputs(dkct_tr_kw8[55], psrc->fipo);
+#if VERSION_BEFORE_20120214
+ /*
+ No need to handle backslash escape sequences.
+ */
+ dk3app_squeeze_line(lb);
+#endif
+ ptr = lb;
+ if (('\\' == *ptr) && ('#' == ptr[1]) && (0 != preprocessor)) {
+ ptr++;
+ }
+ while(*ptr) {
+ switch(*ptr) {
+ case '\\': {
+ switch(ptr[1]) {
+ case '%': {
+ /* Just ignore the backslash, it is used to
+ escape the percent character.
+ */
+ } break;
+ default: {
+ fputc('\\', psrc->fipo);
+ fputc('\\', psrc->fipo);
+ } break;
+ }
+ } break;
+ case '"': {
+ fputc('\\', psrc->fipo);
+ fputc('"', psrc->fipo);
+ } break;
+ case '\n': {
+ fputc('\\', psrc->fipo);
+ fputc('n', psrc->fipo);
+ } break;
+ case '\r': {
+ fputc('\\', psrc->fipo);
+ fputc('r', psrc->fipo);
+ } break;
+ case '\t': {
+ fputc('\\', psrc->fipo);
+ fputc('t', psrc->fipo);
+ } break;
+ default: {
+ fputc(*ptr, psrc->fipo);
+ } break;
+ }
+ ptr++;
+ }
+ fputs(dkct_tr_kw8[55], psrc->fipo);
+ if(pmacro) {
+ fputs(dkct_tr_kw8[53], psrc->fipo);
+ }
+ fputs(dkct_tr_kw8[69], psrc->fipo);
+ }
+ } else {
+ /* ERROR: Source line too large. */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 22);
+ }
+ }
+ }
+ }
+ } while(cc);
+ dkct_tr_write_splint_tag(psrc, dkct_tr_kw8[80]);
+ fputs(dkct_tr_kw8[65], psrc->fipo);
+ dkct_tr_write_splint_tag(psrc, dkct_tr_kw8[81]);
+ }
+ if(fipo) {
+#if DK3_CHAR_SIZE == 1
+ if(!dk3sf_fclose_fn_app(fipo, pfile, psrc->app)) {
+ back = 0;
+ }
+#else
+ if(!dk3sf_fclose_fn_app(fipo, NULL, psrc->app)) {
+ back = 0;
+ }
+#endif
+ fipo = NULL;
+ }
+ return back;
+}
+
+
+
+/** Function table connecting functions to names.
+*/
+dkct_tr_fct_table_entry const dkct_tr_fct_table[] = {
+ { "trace-init", dkct_tr_fct_trace_init },
+ { "trace-end", dkct_tr_fct_trace_end },
+ { "trace-include", dkct_tr_fct_trace_include },
+ { "trace-code", dkct_tr_fct_trace_code },
+ { "!", dkct_tr_fct_trace_code },
+ { "pipe", dkct_tr_fct_trace_pipe },
+ { "|", dkct_tr_fct_trace_pipe },
+ { "string-table", dkct_tr_fct_string_table },
+ { "text", dkct_tr_fct_text },
+ { "trace-on", dkct_tr_fct_trace_on },
+ { "trace-off", dkct_tr_fct_trace_off },
+ { NULL, NULL }
+};
+
+
+
+/** Execute command stored in psrc->cmdb.
+ @param psrc Source structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_tr_exec_command(DKCT_SRC *psrc)
+{
+ int back = 0;
+ dkct_tr_fct *fctptr = NULL; /* Function to execute. */
+ dkct_tr_fct_table_entry const *pte; /* Current entry to inspect. */
+ char *cmdname; /* Command name. */
+ char *args; /* Command arguments. */
+
+ if(psrc->ucmd > 0) {
+ cmdname = dk3str_c8_start(psrc->cmdb, NULL);
+ if(cmdname) {
+ args = dk3str_c8_next(cmdname, NULL);
+ pte = dkct_tr_fct_table; fctptr = NULL;
+ while((pte->name) && (pte->fct) && (!(fctptr))) {
+ if(dk3str_c8_cmp(pte->name, cmdname) == 0) {
+ fctptr = pte->fct;
+ }
+ pte++;
+ }
+ if(fctptr) {
+ back = (*fctptr)(psrc, args);
+ fputc('\n', psrc->fipo);
+ if((psrc->dkcto).lnn) { psrc->shln = 1; }
+ } else {
+ /* ERROR: No such function! */
+ dkct_to_log_3(psrc, 1, DK3_LL_ERROR, 23, 24, cmdname);
+ }
+ } else {
+ /* ERROR: No function name! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 25);
+ }
+ }
+ return back;
+}
+
+
+
+/** Create comment box border line (top or bottom).
+ @param psrc Source structure.
+ @param max Maximum line length.
+*/
+static
+void
+dkct_tr_comment_box_border(DKCT_SRC *psrc, size_t max)
+{
+ size_t lgt; /* Length of asterisk line so far. */
+
+ fputs(dkct_tr_kw8[42], psrc->fipo);
+ lgt = 0;
+ while(lgt++ < max) { fputc('*', psrc->fipo); }
+ fputs(dkct_tr_kw8[43], psrc->fipo);
+}
+
+
+
+#if 0
+static
+void
+dkct_tr_comment_box_empty_line(DKCT_SRC *psrc, size_t max)
+{
+ size_t lgt; /* Length of line so far. */
+
+ fputs(dkct_tr_kw8[40], psrc->fipo);
+ lgt = 0;
+ while(lgt++ < max) { fputc(' ', psrc->fipo); }
+ fputs(dkct_tr_kw8[41], psrc->fipo);
+}
+#endif
+
+
+
+/** Add text line to comment box.
+ @param psrc Source structure.
+ @param max Maximum line length.
+ @param inl Input line to add.
+*/
+static
+void
+dkct_tr_comment_box_text_line(DKCT_SRC *psrc, size_t max, char const *inl)
+{
+ size_t lgt; /* Length of line so far. */
+
+ fputs(dkct_tr_kw8[40], psrc->fipo);
+ fputs(inl, psrc->fipo);
+ lgt = dk3str_c8_len(inl);
+ while(lgt++ < max) { fputc(' ', psrc->fipo); }
+ fputs(dkct_tr_kw8[41], psrc->fipo);
+}
+
+
+
+/** Add comment box to output.
+ @param psrc Source structure.
+*/
+static
+void
+dkct_tr_print_comment_box(DKCT_SRC *psrc)
+{
+ char inl[DKCT_LINE_SIZE]; /* Current input line to process. */
+ size_t max; /* Box width. */
+
+
+#line 3091 "dkct-tr.ctr"
+ max = psrc->cbmx;
+ if((size_t)((psrc->dkcto).bw) > (max + 10)) {
+ max = (size_t)((psrc->dkcto).bw) - 10;
+ }
+ fflush(psrc->cbfip);
+ rewind(psrc->cbfip);
+ dkct_tr_comment_box_border(psrc, max);
+ /* dkct_tr_comment_box_empty_line(psrc, max); */
+ while(fgets(inl, sizeof(inl), psrc->cbfip)) {
+ dk3str_c8_delnl(inl);
+ dkct_tr_comment_box_text_line(psrc, max, inl);
+ }
+ /* dkct_tr_comment_box_empty_line(psrc, max); */
+ dkct_tr_comment_box_border(psrc, max);
+
+
+#line 3106 "dkct-tr.ctr"
+}
+
+
+
+/** Process one character in psrc->cchr.
+ @param psrc Source structure.
+*/
+static
+int
+dkct_tr_process_character(DKCT_SRC *psrc)
+{
+ int back = 0;
+ int input; /* State machine input. */
+ int action; /* State machine output. */
+
+
+#line 3121 "dkct-tr.ctr"
+ input = psrc->cchr;
+ if(psrc->cchr == '$') { input = TRACE_CONTROL; }
+ action = dkct_tr_state_machine_transition(&(psrc->st), input);
+ switch(action) {
+ case DKCT_O_NOOP: { /* Nothing to do. */
+ back = 1;
+ } break;
+ case DKCT_O_PRINT: { /* Print current character. */
+ fputc(psrc->cchr, psrc->fipo);
+ back = 1;
+ } break;
+ case DKCT_O_DOLLAR_AND_CHAR: {
+ fputc('$', psrc->fipo);
+ fputc(psrc->cchr, psrc->fipo);
+ back = 1;
+ } break;
+ case DKCT_O_SLASH_AND_CHAR: {
+ fputc('/', psrc->fipo);
+ fputc(psrc->cchr, psrc->fipo);
+ back = 1;
+ } break;
+ case DKCT_O_RESET_BUFFER: {
+ dkct_tr_reset_buffer(psrc);
+ back = 1;
+ } break;
+ case DKCT_O_ADD_BUFFER: {
+ if(psrc->ucmd < psrc->szcmd) {
+ (psrc->cmdb)[psrc->ucmd] = psrc->cchr;
+ psrc->ucmd += 1;
+ back = 1;
+ } else {
+ /* ERROR: Buffer full */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 98);
+ }
+ } break;
+ case DKCT_O_TRACE_OUTPUT: {
+ if(psrc->ucmd < psrc->szcmd) {
+ (psrc->cmdb)[psrc->ucmd] = '\0';
+ } else {
+ (psrc->cmdb)[psrc->szcmd - 1] = '\0';
+ }
+ dkct_tr_trace_output(psrc);
+ dkct_tr_reset_buffer(psrc);
+ back = 1;
+ if((psrc->dkcto).lnn) { psrc->shln = 1; }
+ } break;
+ case DKCT_O_EXEC_CMD: {
+ if(psrc->ucmd < psrc->szcmd) {
+ (psrc->cmdb)[psrc->ucmd] = '\0';
+ } else {
+ (psrc->cmdb)[psrc->szcmd - 1] = '\0';
+ }
+ dkct_tr_exec_command(psrc);
+ dkct_tr_reset_buffer(psrc);
+ back = 1;
+ if((psrc->dkcto).lnn) { psrc->shln = 1; }
+ } break;
+ case DKCT_O_START_CPP_COMMENT: {
+ switch(psrc->sufi) {
+ case 1: case 3: case 4: {
+ fputs(dkct_tr_kw8[26], psrc->fipo);
+ } break;
+ default: {
+ fputs(dkct_tr_kw8[2], psrc->fipo);
+ } break;
+ }
+ back = 1;
+ } break;
+ case DKCT_O_END_CPP_COMMENT: {
+ switch(psrc->sufi) {
+ case 1: case 3: case 4: {
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+ } break;
+ default: {
+ fputs(dkct_tr_kw8[27], psrc->fipo);
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+ } break;
+ }
+ back = 1;
+ } break;
+ case DKCT_O_START_BOX: {
+
+#line 3202 "dkct-tr.ctr"
+ if(psrc->cbfip) {
+ fclose(psrc->cbfip); psrc->cbfip = NULL;
+ }
+ psrc->cbfip = dk3sf_c8_fopen_app(psrc->cbfn, dkct_tr_kw8[39], psrc->app);
+ psrc->cbcp = 0; psrc->cbmx = 0;
+ if(psrc->cbfip) {
+ back = 1;
+ } else {
+
+#line 3210 "dkct-tr.ctr"
+ /* ERROR: Failed to open file */
+ dkct_to_log_3(psrc, 0, DK3_LL_ERROR, 20, 21, psrc->cbfn);
+ }
+ } break;
+ case DKCT_O_ADD_BOX: {
+
+#line 3215 "dkct-tr.ctr"
+ if(psrc->cbfip) {
+ if(psrc->cchr == '\t') {
+ fputc(' ', psrc->cbfip);
+ psrc->cbcp += 1;
+ while((psrc->cbcp) % 8) {
+ fputc(' ', psrc->cbfip);
+ psrc->cbcp += 1;
+ }
+ } else {
+ fputc(psrc->cchr, psrc->cbfip);
+ psrc->cbcp += 1;
+ }
+ if(psrc->cbcp > psrc->cbmx) { psrc->cbmx = psrc->cbcp; }
+ back = 1;
+ }
+ } break;
+ case DKCT_O_ADD_BOX_NL: {
+
+#line 3232 "dkct-tr.ctr"
+ if(psrc->cbfip) {
+ fputc('\n', psrc->cbfip);
+ psrc->cbcp = 0;
+ back = 1;
+ }
+ } break;
+ case DKCT_O_ADD_BOX_DOLLAR_CHAR: {
+
+#line 3239 "dkct-tr.ctr"
+ if(psrc->cbfip) {
+ fputc('$', psrc->cbfip);
+ psrc->cbcp += 1;
+ if(psrc->cchr == '\t') {
+ fputc(' ', psrc->cbfip);
+ psrc->cbcp += 1;
+ while((psrc->cbcp) % 8) {
+ fputc(' ', psrc->cbfip);
+ psrc->cbcp += 1;
+ }
+ } else {
+ fputc(psrc->cchr, psrc->cbfip);
+ psrc->cbcp += 1;
+ }
+ if(psrc->cbcp > psrc->cbmx) { psrc->cbmx = psrc->cbcp; }
+ back = 1;
+ }
+ } break;
+ case DKCT_O_END_BOX: {
+
+#line 3258 "dkct-tr.ctr"
+ if(psrc->cbfip) {
+ fputc('\n', psrc->cbfip);
+ dkct_tr_print_comment_box(psrc);
+ fclose(psrc->cbfip); psrc->cbfip = NULL;
+ back = 1;
+ }
+ if((psrc->dkcto).lnn) { psrc->shln = 1; }
+ } break;
+ }
+
+#line 3267 "dkct-tr.ctr"
+ return back;
+}
+
+
+
+/** Process all source lines from a storage.
+ @param psrc Source structure.
+ @param iterator Storage iterator.
+*/
+static
+int
+dkct_tr_module_lines(DKCT_SRC *psrc, dk3_sto_it_t *iterator)
+{
+ int back = 1;
+ DKCT_LINE *lp; /* Current line to process. */
+ char const *ptr; /* Current character to process. */
+
+
+#line 3284 "dkct-tr.ctr"
+ if(iterator) {
+ psrc->cursr = iterator;
+ dk3sto_it_reset(iterator);
+ while((lp = (DKCT_LINE *)dk3sto_it_next(iterator)) != NULL) {
+ if(lp->t) {
+
+#line 3289 "dkct-tr.ctr"
+ psrc->lineno = lp->l;
+ if(psrc->app) { dk3app_set_source_line(psrc->app, lp->l); }
+ if(psrc->shln) {
+ psrc->shln = 0;
+ dkct_tr_show_source_line(psrc, 1);
+ }
+ ptr = lp->t;
+ while(*ptr) {
+ psrc->cchr = *(ptr++);
+ if(!dkct_tr_process_character(psrc)) { back = 0; }
+ }
+ psrc->cchr = '\n';
+ if(!dkct_tr_process_character(psrc)) { back = 0; }
+ }
+ }
+ psrc->cursr = NULL;
+ }
+
+#line 3306 "dkct-tr.ctr"
+ return back;
+}
+
+
+
+/** Attempt to write one output file.
+ @param psrc Source structure.
+ @param sfn Source file name.
+ @param osf Output file name suffix.
+ @param f_hdr Flag: This is the header file.
+*/
+static
+int
+dkct_tr_attempt_to_write_file(
+ DKCT_SRC *psrc, dkChar const *sfn, dkChar const *osf, int f_hdr
+)
+{
+ int back = 1;
+ dkChar ofn[DK3_MAX_PATH]; /* Output file name. */
+ dkChar *sofn = NULL; /* Short output name. */
+ dkChar *ps = NULL; /* Output suffix. */
+ int f_must_run = 1; /* Flag: Must run. */
+ int first_state_machine = 1; /* Flag: First stm. */
+ DKCT_STM *pstm; /* State machine. */
+
+
+#line 3331 "dkct-tr.ctr"
+ if(dk3str_len(sfn) < DK3_SIZEOF(ofn,dkChar)) {
+ dk3str_cpy_not_overlapped(ofn, sfn);
+ ps = dk3str_get_suffix(ofn);
+ if(ps) { *ps = dkT('\0'); }
+ if((dk3str_len(ofn) + dk3str_len(osf)) < DK3_SIZEOF(ofn,dkChar)) {
+ dk3str_cat(ofn, osf);
+
+#line 3337 "dkct-tr.ctr"
+ if((psrc->dkcto).mak) {
+
+#line 3338 "dkct-tr.ctr"
+ f_must_run = dk3sf_must_rebuild(ofn, sfn);
+ }
+ sofn = dk3str_rchr(ofn, DK3_CHAR_SEP);
+ if(sofn) {
+ sofn++;
+ } else {
+ sofn = ofn;
+ }
+ dk3app_set_source_line(psrc->app, 0UL);
+ if(f_must_run) {
+
+#line 3348 "dkct-tr.ctr"
+ /* Progress: Writing output file. */
+ dk3app_log_3(psrc->app, DK3_LL_PROGRESS, psrc->msg, 108, 109, sofn);
+ psrc->fipo = dk3sf_fopen_app(ofn, dk3app_not_localized(24), psrc->app);
+ if(psrc->fipo) {
+
+#line 3352 "dkct-tr.ctr"
+ dkct_tr_write_file_start(psrc, ofn, sfn, f_hdr);
+ if((psrc->dkcto).lnn) { psrc->shln = 1; }
+ if(f_hdr) {
+ /*
+ Protect against multiple inclusion (file start)
+ */
+ fputs(dkct_tr_kw8[6], psrc->fipo);
+ dkct_tr_filename_to_upper(psrc, ofn);
+ fputs(dkct_tr_kw8[7], psrc->fipo);
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+ fputs(dkct_tr_kw8[8], psrc->fipo);
+ dkct_tr_filename_to_upper(psrc, ofn);
+ fputs(dkct_tr_kw8[7], psrc->fipo);
+ fputs(dkct_tr_kw8[9], psrc->fipo);
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+ /*
+ Header start and class start.
+ */
+
+ if((psrc->dkcto).lnn) { psrc->shln = 1; }
+ if(!dkct_tr_module_lines(psrc, psrc->hsi)) { back = 0; }
+ if((psrc->dkcto).lnn) { psrc->shln = 1; }
+ if(!dkct_tr_module_lines(psrc, psrc->clsi)) { back = 0; }
+ /*
+ wxWindows GUI output.
+ */
+ if(psrc->sufi == 4) {
+ dkct_gui_class_variables(psrc);
+ }
+ /*
+ Class end and header end.
+ */
+ if((psrc->dkcto).lnn) { psrc->shln = 1; }
+ if(!dkct_tr_module_lines(psrc, psrc->clei)) { back = 0; }
+ if((psrc->dkcto).lnn) { psrc->shln = 1; }
+ if(!dkct_tr_module_lines(psrc, psrc->hei)) { back = 0; }
+ /*
+ State machine constants, if any.
+ */
+ dk3sto_it_reset(psrc->i_stm);
+ while((pstm = (DKCT_STM *)dk3sto_it_next(psrc->i_stm)) != NULL) {
+ if(pstm->wrh) {
+ psrc->lineno = pstm->lineno;
+ dk3app_set_source_line(psrc->app, pstm->lineno);
+ dkct_au_write_entries(psrc, pstm);
+ dkct_au_write_prototypes(psrc, pstm);
+ }
+ }
+ /*
+ Protect against multiple inclusion (file end)
+ */
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+ fputs(dkct_tr_kw8[10], psrc->fipo);
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+ } else {
+ /*
+ State machine constants and functions if any.
+ */
+ dk3sto_it_reset(psrc->i_stm);
+ while((pstm = (DKCT_STM *)dk3sto_it_next(psrc->i_stm)) != NULL) {
+ if(first_state_machine) {
+ first_state_machine = 0;
+ if(((psrc->dkcto).deb) && ((psrc->dkcto).deben)) {
+ if((psrc->dkcto).deb == 2) {
+ fputs(dkct_tr_kw8[68], psrc->fipo);
+ }
+ fputs(dkct_tr_kw8[44], psrc->fipo);
+ fputs(dkct_tr_kw8[79], psrc->fipo);
+ (psrc->dkcto).tip = 1;
+ }
+ }
+ psrc->lineno = pstm->lineno;
+ dk3app_set_source_line(psrc->app, pstm->lineno);
+ if(!(pstm->wrh)) {
+ dkct_au_write_entries(psrc, pstm);
+ dkct_au_write_functions(psrc, pstm, 1);
+ } else {
+ dkct_au_write_functions(psrc, pstm, 0);
+ }
+ }
+ /*
+ Start of module.
+ */
+ psrc->st = 0;
+ if((psrc->dkcto).lnn) { psrc->shln = 1; }
+ if(!dkct_tr_module_lines(psrc, psrc->msi)) { back = 0; }
+ if((psrc->dkcto).lnn) { psrc->shln = 1; }
+ if(!dkct_tr_module_lines(psrc, psrc->cosi)) { back = 0; }
+ /*
+ GUI setup.
+ */
+ if(psrc->sufi == 4) {
+ dkct_gui_write_constructor(psrc);
+ }
+ /*
+ End of module.
+ */
+ if((psrc->dkcto).lnn) { psrc->shln = 1; }
+ if(!dkct_tr_module_lines(psrc, psrc->coei)) { back = 0; }
+ if((psrc->dkcto).lnn) { psrc->shln = 1; }
+ if(!dkct_tr_module_lines(psrc, psrc->mei)) { back = 0; }
+ }
+ if(!dk3sf_fclose_fn_app(psrc->fipo, ofn, psrc->app)) {
+ back = 0;
+ }
+ } else {
+
+#line 3459 "dkct-tr.ctr"
+ /* ERROR: Failed to open file! */
+ dkct_to_log_dk_3(psrc, 0, DK3_LL_ERROR, 20, 21, ofn);
+ back = 0;
+ }
+ } else {
+ /* Progress: Output file is up to date. */
+ dk3app_log_3(psrc->app, DK3_LL_PROGRESS, psrc->msg, 110, 111, sofn);
+ }
+ } else {
+
+#line 3468 "dkct-tr.ctr"
+ /* ERROR: File name too long! */
+ dkct_to_log_dk_3(psrc, 1, DK3_LL_ERROR, 26, 27, ofn);
+ back = 0;
+ }
+ } else {
+
+#line 3473 "dkct-tr.ctr"
+ /* File name too long! */
+ dkct_to_log_dk_3(psrc, 1, DK3_LL_ERROR, 26, 27, sfn);
+ back = 0;
+ }
+
+#line 3477 "dkct-tr.ctr"
+ return back;
+}
+
+
+
+int
+dkct_tr_write(DKCT_SRC *psrc, dkChar const *fn, int sufi)
+{
+ int back = 1;
+ char fnb[128]; /* File name for temporary box file. */
+
+
+#line 3488 "dkct-tr.ctr"
+ psrc->cbfip = NULL;
+ psrc->sufi = sufi;
+ psrc->shln = 0;
+ sprintf(fnb, dkct_tr_kw8[38], (unsigned long)dk3sf_getpid());
+ psrc->cbfn = fnb;
+ psrc->lineno = 1UL;
+ dk3app_set_source_line(psrc->app, 1UL);
+ switch(sufi) {
+ case 4: { /* .h .cpp */
+ if(dkct_tr_have_header_data(psrc)) {
+ if(!dkct_tr_attempt_to_write_file(psrc,fn,dkct_tr_out_suffixes[0],1))
+ {
+ back = 0;
+ }
+ }
+ if(dkct_tr_have_module_data(psrc)) {
+ if(!dkct_tr_attempt_to_write_file(psrc,fn,dkct_tr_out_suffixes[2],0))
+ {
+ back = 0;
+ }
+ }
+ } break;
+ case 3: { /* .java */
+ if(dkct_tr_have_module_data(psrc)) {
+ if(!dkct_tr_attempt_to_write_file(psrc,fn,dkct_tr_out_suffixes[4],0))
+ {
+ back = 0;
+ }
+ }
+ } break;
+ case 2: { /* .h .m */
+ if(dkct_tr_have_header_data(psrc)) {
+ if(!dkct_tr_attempt_to_write_file(psrc,fn,dkct_tr_out_suffixes[0],1))
+ {
+ back = 0;
+ }
+ }
+ if(dkct_tr_have_module_data(psrc)) {
+ if(!dkct_tr_attempt_to_write_file(psrc,fn,dkct_tr_out_suffixes[3],0))
+ {
+ back = 0;
+ }
+ }
+ } break;
+ case 1: { /* .h .cpp */
+ if(dkct_tr_have_header_data(psrc)) {
+ if(!dkct_tr_attempt_to_write_file(psrc,fn,dkct_tr_out_suffixes[0],1))
+ {
+ back = 0;
+ }
+ }
+ if(dkct_tr_have_module_data(psrc)) {
+ if(!dkct_tr_attempt_to_write_file(psrc,fn,dkct_tr_out_suffixes[2],0))
+ {
+ back = 0;
+ }
+ }
+ } break;
+ case 0: { /* .h .c */
+ if(dkct_tr_have_header_data(psrc)) {
+ if(!dkct_tr_attempt_to_write_file(psrc,fn,dkct_tr_out_suffixes[0],1))
+ {
+ back = 0;
+ }
+ }
+ if(dkct_tr_have_module_data(psrc)) {
+ if(!dkct_tr_attempt_to_write_file(psrc,fn,dkct_tr_out_suffixes[1],0))
+ {
+ back = 0;
+ }
+ }
+ } break;
+ }
+ if(psrc->cbfip) {
+ fclose(psrc->cbfip); psrc->cbfip = NULL;
+ }
+ dk3sf_c8_remove_file_app(psrc->cbfn, NULL);
+ psrc->cbfn = NULL;
+
+
+#line 3567 "dkct-tr.ctr"
+ return back;
+}
+
+
+
+/** Pointer to a constant string.
+*/
+typedef char const *DKCT_TR_CONST_CHAR_PTR;
+
+char const *
+dkct_tr_get_kw8(size_t sz)
+{
+ char const *back = NULL;
+ if(sz < (sizeof(dkct_tr_kw8)/sizeof(DKCT_TR_CONST_CHAR_PTR))) {
+ back = dkct_tr_kw8[sz];
+ }
+ return back;
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dkct-tr.ctr b/support/dktools/dkct-tr.ctr
new file mode 100644
index 0000000000..851f25300e
--- /dev/null
+++ b/support/dktools/dkct-tr.ctr
@@ -0,0 +1,3589 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% module
+
+
+#if DK3_USE_WX
+#include "dkwxtrace.h"
+#else
+#include "dkct.h"
+#endif
+
+
+
+#include "dk3wxcs.h"
+
+
+
+$!trace-include
+
+
+/** Dkct user function.
+*/
+typedef int dkct_tr_fct(DKCT_SRC *psrc, char *args);
+
+
+
+/** Table entry to connect a function to a name.
+*/
+typedef struct {
+ char const *name; /**< Function name. */
+ dkct_tr_fct *fct; /**< Function to execute. */
+} dkct_tr_fct_table_entry;
+
+
+
+/** Indicate that current character is trace control character.
+*/
+#define TRACE_CONTROL 512
+
+
+
+/** Operation: Do nothing.
+*/
+#define DKCT_O_NOOP 0
+
+
+
+/** Operation: Print current character.
+*/
+#define DKCT_O_PRINT 1
+
+/** Operation: Print dollar and current character.
+*/
+#define DKCT_O_DOLLAR_AND_CHAR 2
+
+/** Operation: Print slash and current character.
+*/
+#define DKCT_O_SLASH_AND_CHAR 3
+
+/** Operation: Reset buffer.
+*/
+#define DKCT_O_RESET_BUFFER 4
+
+/** Operation: Add current character to buffer.
+*/
+#define DKCT_O_ADD_BUFFER 5
+
+/** Operation: Write buffer as trace output.
+*/
+#define DKCT_O_TRACE_OUTPUT 6
+
+/** Operation: Execute command in buffer.
+*/
+#define DKCT_O_EXEC_CMD 7
+
+/** Operation: Start C++ style comment.
+*/
+#define DKCT_O_START_CPP_COMMENT 8
+
+/** Operation: End C++ style comment.
+*/
+#define DKCT_O_END_CPP_COMMENT 9
+
+/** Operation: Open file to save data for a box comment.
+*/
+#define DKCT_O_START_BOX 10
+
+/** Operation: Add normal character for box comment.
+*/
+#define DKCT_O_ADD_BOX 11
+
+/** Operation: Add newline to box comment file.
+*/
+#define DKCT_O_ADD_BOX_NL 12
+
+/** Operation: Add dollar and current character to box comment file.
+*/
+#define DKCT_O_ADD_BOX_DOLLAR_CHAR 13
+
+/** Operation: Print box comment file in box comment.
+*/
+#define DKCT_O_END_BOX 14
+
+
+
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+/** Separator character. */
+#define DKCT_TR_SEP '\\'
+#else
+/** Separator character. */
+#define DKCT_TR_SEP '/'
+#endif
+
+
+/** Section names.
+*/
+static char const * const dkct_tr_section_headers[] = {
+/* 0 */ "options",
+/* 1 */ "header",
+/* 2 */ "header start",
+/* 3 */ "header end",
+/* 4 */ "class start",
+/* 5 */ "class end",
+/* 6 */ "module",
+/* 7 */ "module start",
+/* 8 */ "module end",
+/* 9 */ "constructor start",
+/* 10 */ "constructor end",
+/* 11 */ "wx-gui",
+/* 12 */ "state machine",
+NULL
+};
+
+
+
+/** Keywords for option processing.
+*/
+static char const * const dkct_option_keywords[] = {
+/* 0 */ "copyright-owner",
+/* 1 */ "copyright-year",
+/* 2 */ "license",
+/* 3 */ "splint-comment-character",
+NULL
+};
+
+
+
+/** License type names.
+*/
+static char const * const dkct_license_names[] = {
+/* 0 */ "BSD",
+/* 1 */ "GPL",
+/* 2 */ "LGPL",
+/* 5 */ "wxWidgets",
+/* 4 */ "commercial",
+NULL
+};
+
+
+
+/** File name suffixes for output files.
+*/
+static dkChar const * const dkct_tr_out_suffixes[] = {
+/* 0 */ dkT(".h"),
+/* 1 */ dkT(".c"),
+/* 2 */ dkT(".cpp"),
+/* 3 */ dkT(".m"),
+/* 4 */ dkT(".java"),
+NULL
+};
+
+
+
+/** Warning at start of output files, do not modify!
+*/
+static char const * const dkct_tr_mod_warning_start[] = {
+"/*",
+" WARNING: This file was generated by dkct.",
+" Changes you make here will be lost if dkct is run again!",
+" You should modify the original source and run dkct on it.",
+NULL
+};
+
+
+
+/** End of modification warning.
+*/
+static char const * const dkct_tr_mod_warning_end[] = {
+"*/",
+"",
+NULL
+};
+
+
+/** Keywords to use when producing output.
+*/
+static char const * const dkct_tr_kw8[] = {
+/* 0 */ "\n",
+/* 1 */ " ",
+/* 2 */ "/*",
+/* 3 */ "*/",
+/* 4 */ "Copyright (C) ",
+/* 5 */ ", ",
+/* 6 */ "#ifndef ",
+/* 7 */ "_INCLUDED",
+/* 8 */ "/** Avoid multiple inclusions. */\n#define ",
+/* 9 */ " 1",
+/* 10 */ "#endif",
+/* 11 */ "/**\t@file ",
+/* 12 */ " Header file for the ",
+/* 13 */ " module.",
+/* 14 */ " The ",
+/* 15 */ "KrTrace.printMessage(",
+/* 16 */ " + ",
+/* 17 */ ":",
+/* 18 */ "\"",
+/* 19 */ "trace ",
+/* 20 */ "#line %lu \"%s\"\n",
+/* 21 */ "#if TRACE_WIDE\n",
+/* 22 */ "#else\n",
+/* 23 */ "#endif\n",
+/* 24 */ "\n/* TRACE BEGIN */\n",
+/* 25 */ "/* TRACE END */\n",
+/* 26 */ "//",
+/* 27 */ " */",
+/* 28 */ "stdout",
+/* 29 */ "dktrace_file()",
+/* 30 */ "if(dktrace_file()) {\n",
+/* 31 */ "}\n",
+/* 32 */ "dktrace_time();\n",
+/* 33 */ "fputs(",
+/* 34 */ ");\n",
+/* 35 */ ", ",
+/* 36 */ "fprintf(",
+/* 37 */ "fflush(",
+/* 38 */ "dkct-tmp-%lu",
+/* 39 */ "w+",
+/* 40 */ "/* * ",
+/* 41 */ " * */\n",
+/* 42 */ "/* **",
+/* 43 */ "** */\n",
+/* 44 */ "#include <dk3trace.h>\n",
+/* 45 */ "dktrace_init(\"",
+/* 46 */ "\");\n",
+/* 47 */ "dktrace_end();\n",
+/* 48 */ "fputc('\\n', ",
+/* 49 */ "r",
+/* 50 */ "w",
+/* 51 */ "$!end",
+/* 52 */ "(",
+/* 53 */ ")",
+/* 54 */ ",\n\n",
+/* 55 */ "\"",
+/* 56 */ "if(dktrace_file()) {\n",
+/* 57 */ " _setmode(_fileno(dktrace_file()), _O_U16TEXT);\n",
+/* 58 */ " fputwc(0xFEFF, dktrace_file());\n",
+/* 59 */ "}\n",
+/* 60 */ "_setmode(_fileno(stdout), _O_U16TEXT);\n",
+/* 61 */ "fputws(L",
+/* 62 */ "fwprintf(",
+/* 63 */ ", L",
+/* 64 */ "fputwc(L'\\n', ",
+/* 65 */ "NULL\n",
+/* 66 */ "/* %lu */\n",
+/* 67 */ "/* TRACE BEGIN */\n",
+/* 68 */ "#include <stdio.h>\n",
+/* 69 */ ",\n",
+/* 70 */ "dktrace_stdout_time();\n",
+/* 71 */ "dktrace_wtime();\n",
+/* 72 */ "dktrace_stdout_wtime();\n",
+/* 73 */ "\"! ",
+/* 74 */ "\\n\"",
+/* 75 */ "contents panel",
+/* 76 */ "\". ",
+/* 77 */ "\tOriginal source: ",
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+/* 78 */ "\\",
+#else
+/* 78 */ "/",
+#endif
+/* 79 */ "#ifndef TRACE_DEBUG\n#define TRACE_DEBUG 1\n#endif\n",
+/* 80 */ "/*@-nullassign@*/\n",
+/* 81 */ "/*@=nullassign@*/\n",
+/* 82 */
+"#if TRACE_WIDE && (defined(_WIN32) || DK3_ON_WINDOWS || DK4_ON_WINDOWS)\n",
+/* 83 */
+"#if (SIZEOF_WXCHAR > 1) || (DK4_SIZEOF_WXCHAR > 1) || (DK3_SIZEOF_WXCHAR > 1)\n",
+/* 84 */ "#if (DK3_CHAR_SIZE > 1) || (DK4_CHAR_SIZE > 1)\n",
+/* 85 */ "#if (defined(_WIN32)) || (DK3_ON_WINDOWS) || (DK4_ON_WINDOWS)\n",
+NULL
+};
+
+
+
+/** Keywords used by the module.
+*/
+static dkChar const * const dkct_tr_kw[] = {
+$!string-table macro=dkT
+#
+# 0: Suffix for header files
+#
+.h
+#
+# 1: Suffix for *.dox files
+#
+.dox
+$!end
+};
+
+
+/** Arguments for the string-table command.
+*/
+static char const * const dkct_tr_string_table_args[] = {
+/* 0 */ "file",
+/* 1 */ "macro",
+/* 2 */ "prefix",
+/* 3 */ "preprocessor",
+NULL
+};
+
+
+
+/** Text to include in GPL-licensed sources.
+*/
+static char const * const dkct_tr_gpl_text[] = {
+$!text
+This program 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.
+
+This program 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
+this program. If not, see <http://www.gnu.org/licenses/>.
+$!end
+};
+
+
+
+/** Text to include in LGPL licensed sources.
+*/
+static char const * const dkct_tr_lgpl_text[] = {
+$!text
+This software is free software: you can redistribute it and/or modify it
+under the terms of the GNU Lesser General Public License as published by the
+Free Software Foundation, either version 3 of the License, or (at your
+option) any later version.
+
+This software 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 Lesser General Public License for more
+details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this software. If not, see <http://www.gnu.org/licenses/>.
+$!end
+};
+
+
+
+/** Text to include in BSD licensed sources.
+*/
+static char const * const dkct_tr_bsd_text[] = {
+$!text
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+$!end
+};
+
+
+
+/** Text to include in commercially licensed sources.
+*/
+static char const * const dkct_tr_commercial_text[] = {
+$!text
+All rights reserved.
+$!end
+};
+
+#if DK3_USE_WX
+
+#else
+
+#endif
+
+
+
+/** Flag: wxChar is wchar_t
+*/
+static const int is_wx_wide =
+#if DK3_SIZEOF_WXCHAR > 1
+1
+#else
+0
+#endif
+;
+
+
+
+/** Flag: dkChar is wchar_t
+*/
+static const int is_dk_wide =
+#if DK3_CHAR_SIZE > 1
+1
+#else
+0
+#endif
+;
+
+
+
+static const int is_on_windows =
+#if DK3_ON_WINDOWS || defined(_WIN32)
+1
+#else
+0
+#endif
+;
+
+
+
+/** Compare two stored lines by line number.
+ @param l Left DKCT_LINE object.
+ @param r Right DKCT_LINE object.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+static
+int
+dkct_tr_line_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ DKCT_LINE const *pl; /* Left line. */
+ DKCT_LINE const *pr; /* Right line. */
+ if(l) {
+ if(r) {
+ pl = (DKCT_LINE const *)l; pr = (DKCT_LINE const *)r;
+ if(pl->l > pr->l) { back = 1; }
+ else {
+ if(pl->l < pr->l) { back = -1; }
+ }
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ }
+ return back;
+}
+
+
+
+void
+dkct_tr_line_delete(DKCT_LINE *p)
+{
+ $? "+ dkct_tr_line_delete"
+ if(p) { $? ". text \"%!8s\"", TR_8STR(p->t)
+ dk3_release(p->t);
+ p->l = 0UL;
+ dk3_delete(p);
+ } $? "- dkct_tr_line_delete"
+}
+
+
+
+DKCT_LINE *
+dkct_tr_line_new(char const *t, unsigned long l, dk3_app_t *app)
+{
+ DKCT_LINE *back = NULL;
+ $? "+ dkct_tr_line_new %lu \"%!8s\"", l, t
+ if((t) && (l)) {
+ back = dk3_new_app(DKCT_LINE,1,app);
+ if(back) {
+ back->t = NULL;
+ back->l = l;
+ back->t = dk3str_c8_dup_app(t,app);
+ if(!(back->t)) {
+ dkct_tr_line_delete(back);
+ back = NULL;
+ }
+ }
+ } $? "- dkct_tr_line_new PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/** Compare two state machine descriptions.
+ @param l Left state machine.
+ @param r Right state machine.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+static
+int
+dkct_tr_stm_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ DKCT_STM const *sl; /* Left state machine. */
+ DKCT_STM const *sr; /* Right state machine. */
+ if(l) {
+ if(r) {
+ sl = (DKCT_STM const *)l; sr = (DKCT_STM const *)r;
+ if(sl->lineno > sr->lineno) {
+ back = 1;
+ } else {
+ if(sl->lineno < sr->lineno) {
+ back = -1;
+ }
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Clean up a storage and it's iterator containing DKCT_LINE data.
+ @param s Storage.
+ @param i Iterator.
+*/
+static
+void
+dkct_tr_cleanup_storage_and_iterator(dk3_sto_t *s, dk3_sto_it_t *i)
+{
+ DKCT_LINE *l; /* Current line to clean up. */
+ $? "+ dkct_tr_cleanup_storage_and_iterator PTR=%d PTR=%d", TR_IPTR(s), TR_IPTR(i)
+ if(s) {
+ if(i) {
+ dk3sto_it_reset(i);
+ while((l = (DKCT_LINE *)dk3sto_it_next(i)) != NULL) { $? ". line found"
+ dkct_tr_line_delete(l);
+ }
+ dk3sto_it_close(i);
+ }
+ dk3sto_close(s);
+ } $? "- dkct_tr_cleanup_storage_and_iterator"
+}
+
+
+
+void
+dkct_tr_delete(DKCT_SRC *p)
+{
+ DKCT_STM *stmptr; /* Current state machine to clean up. */
+ $? "+ dkct_tr_delete PTR=%d", TR_IPTR(p)
+ if(p) {
+ if(p->gui) {
+ dkct_gui_delete((DKCT_GUI *)(p->gui));
+ } p->gui = NULL;
+ p->app = NULL;
+ dkct_tr_cleanup_storage_and_iterator(p->hss, p->hsi);
+ dkct_tr_cleanup_storage_and_iterator(p->hes, p->hei);
+ dkct_tr_cleanup_storage_and_iterator(p->clss, p->clsi);
+ dkct_tr_cleanup_storage_and_iterator(p->cles, p->clei);
+ dkct_tr_cleanup_storage_and_iterator(p->mss, p->msi);
+ dkct_tr_cleanup_storage_and_iterator(p->mes, p->mei);
+ dkct_tr_cleanup_storage_and_iterator(p->coss, p->cosi);
+ dkct_tr_cleanup_storage_and_iterator(p->coes, p->coei);
+ p->hss = p->hes = p->clss = p->cles =
+ p->mss = p->mes = p->coss = p->coes = NULL;
+ p->hsi = p->hei = p->clsi = p->clei =
+ p->msi = p->mei = p->cosi = p->coei = NULL;
+ if(p->s_stm) {
+ if(p->i_stm) {
+ dk3sto_it_reset(p->i_stm);
+ while((stmptr = (DKCT_STM *)dk3sto_it_next(p->i_stm)) != NULL) {
+ dkct_au_stm_delete(stmptr);
+ }
+ dk3sto_it_close(p->i_stm);
+ }
+ dk3sto_close(p->s_stm);
+ } p->s_stm = NULL; p->i_stm = NULL; p->cstm = NULL;
+ if(p->crn) { $? ". copyright owner \"%!8s\"", p->crn
+ }
+ if(p->cry) { $? ". copyright year \"%!8s\"", p->cry
+ }
+ if(p->lict > -1) { $? ". license type %d", p->lict
+ }
+ p->ffn = NULL;
+ dk3_release(p->crn);
+ dk3_release(p->cry);
+ dk3_release(p->sfn);
+ dk3_release(p->cmdb);
+ p->szcmd = 0; p->ucmd = 0; p->fipo = NULL;
+ p->msg = NULL;
+ dk3_delete(p);
+ } $? "- dkct_tr_delete"
+}
+
+
+
+DKCT_SRC *
+dkct_tr_new(
+ DKCT_OPTION_SET *o,
+ char const *fn,
+ int ai,
+ dk3_app_t *app,
+ dkChar const *ffn
+)
+{
+ DKCT_SRC *back = NULL;
+ int ok = 0; /* Flag: Successfully initialized. */
+ char const *fnptrsfn; /* Pointer to short file name. */
+ $? "+ dkct_tr_new"
+ if((o) && (fn)) {
+ back = dk3_new_app(DKCT_SRC,1,app);
+ if(back) {
+ dk3mem_cpy(&(back->dkcto), o, sizeof(DKCT_OPTION_SET));
+ (back->dkcto).deben = 1;
+ back->ffn = ffn;
+ back->app = app;
+ back->msg = NULL;
+ back->type = ai;
+ back->ec = 0;
+ back->hss = back->hes = back->clss = back->cles =
+ back->mss = back->mes = back->coss = back->coes = NULL;
+ back->hsi = back->hei = back->clsi = back->clei =
+ back->msi = back->mei = back->cosi = back->coei = NULL;
+ back->s_stm = NULL; back->i_stm = NULL;
+ back->sfn = NULL;
+ back->crn = NULL;
+ back->cry = NULL;
+ back->cmdb = NULL;
+ back->lict = -1;
+ back->st = 0;
+ back->szcmd = 0;
+ back->ucmd = 0;
+ back->sufi = 0;
+ back->fipo = NULL;
+ back->cbfip = NULL;
+ back->cbfn = NULL;
+ back->cbmx = 0;
+ back->cbcp = 0;
+ back->cursr = NULL;
+ back->cstm = NULL;
+ back->curdi = 0;
+ back->hss = dk3sto_open_app(app);
+ back->hes = dk3sto_open_app(app);
+ back->clss = dk3sto_open_app(app);
+ back->cles = dk3sto_open_app(app);
+ back->mss = dk3sto_open_app(app);
+ back->mes = dk3sto_open_app(app);
+ back->coss = dk3sto_open_app(app);
+ back->coes = dk3sto_open_app(app);
+ back->s_stm = dk3sto_open_app(app);
+ back->gui = NULL;
+ back->hdr = 0;
+ back->doxyh = 0;
+ back->doxym = 0;
+#if DK3_USE_WX
+ back->pComm = NULL;
+#endif
+ if((back->hss) && (back->hes) && (back->clss) && (back->cles)) {
+ if((back->mss) && (back->mes) && (back->coss) && (back->coes)) {
+ if(back->s_stm) {
+ back->hsi = dk3sto_it_open(back->hss);
+ back->hei = dk3sto_it_open(back->hes);
+ back->clsi = dk3sto_it_open(back->clss);
+ back->clei = dk3sto_it_open(back->cles);
+ back->msi = dk3sto_it_open(back->mss);
+ back->mei = dk3sto_it_open(back->mes);
+ back->cosi = dk3sto_it_open(back->coss);
+ back->coei = dk3sto_it_open(back->coes);
+ back->i_stm = dk3sto_it_open(back->s_stm);
+ if((back->hsi) && (back->hei) && (back->clsi) && (back->clei)) {
+ if((back->msi) && (back->mei) && (back->cosi) && (back->coei)) {
+ if(back->i_stm) {
+ dk3sto_set_comp(back->hss , dkct_tr_line_compare, 0);
+ dk3sto_set_comp(back->hes , dkct_tr_line_compare, 0);
+ dk3sto_set_comp(back->clss, dkct_tr_line_compare, 0);
+ dk3sto_set_comp(back->cles, dkct_tr_line_compare, 0);
+ dk3sto_set_comp(back->mss , dkct_tr_line_compare, 0);
+ dk3sto_set_comp(back->mes , dkct_tr_line_compare, 0);
+ dk3sto_set_comp(back->coss, dkct_tr_line_compare, 0);
+ dk3sto_set_comp(back->coes, dkct_tr_line_compare, 0);
+ dk3sto_set_comp(back->s_stm, dkct_tr_stm_compare, 0);
+ fnptrsfn = dk3str_c8_rchr(fn, DKCT_TR_SEP);
+ if(fnptrsfn) {
+ fnptrsfn++;
+ } else {
+ fnptrsfn = fn;
+ }
+ back->sfn = dk3str_c8_dup_app(fnptrsfn, app);
+ if(back->sfn) { $? ". ok"
+ back->cmdb = dk3_new_app(char,DKCT_LINE_SIZE,app);
+ if(back->cmdb) {
+ back->szcmd = DKCT_LINE_SIZE;
+ ok = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if(!ok) {
+ dkct_tr_delete(back);
+ back = NULL;
+ }
+ }
+ } $? "- dkct_tr_new PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/** Check whether or not an input line is a section header.
+ @param inputline Line to check.
+ @return 1 for section header, 0 otherwise.
+*/
+static
+int
+dkct_tr_is_section_header(char *inputline)
+{
+ int back = 0;
+ char *p1; /* Start of text. */
+
+ if(inputline) {
+ p1 = dk3str_c8_start(inputline, NULL);
+ if(p1) {
+ if(*p1 == '%') {
+ if(p1[1] == '%') {
+ back = 1;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Find section number for input line.
+ @param psrc Source structure.
+ @param inputline Input line to process.
+ @param sufi File suffix index of input file.
+ @return The section number (index in dkct_tr_section_headers).
+*/
+static
+int
+dkct_tr_find_section_number(DKCT_SRC *psrc, char *inputline, int sufi)
+{
+ int back = -1;
+ int ai; /* Array index of section name. */
+ char *p1; /* Section name. */
+
+ p1 = dk3str_c8_start(inputline, NULL);
+ if(p1) {
+ if(*p1 == '%') {
+ if(p1[1] == '%') {
+ p1++; p1++;
+ p1 = dk3str_c8_start(p1, NULL);
+ if(p1) {
+ dk3str_c8_normalize(p1, NULL, ' ');
+ ai = dk3str_c8_array_index(dkct_tr_section_headers, p1, 0);
+ switch(sufi) {
+ case 4: {
+ switch(ai) {
+ case 0: { back = DKCT_SECTION_OPTIONS; } break;
+ case 1: case 2: { back = DKCT_SECTION_HEADER_START; } break;
+ case 3: { back = DKCT_SECTION_HEADER_END; } break;
+ case 4: { back = DKCT_SECTION_CLASS_START; } break;
+ case 5: { back = DKCT_SECTION_CLASS_END; } break;
+ case 6: case 7: { back = DKCT_SECTION_MODULE_START; } break;
+ case 8: { back = DKCT_SECTION_MODULE_END; } break;
+ case 9: { back = DKCT_SECTION_CONSTRUCTOR_START; } break;
+ case 10: { back = DKCT_SECTION_CONSTRUCTOR_END; } break;
+ case 11: { back = DKCT_SECTION_GUI; } break;
+ case 12: { back = DKCT_SECTION_STATE_MACHINE; } break;
+ }
+ } break;
+ case 3: {
+ switch(ai) {
+ case 0: { back = DKCT_SECTION_OPTIONS; } break;
+ case 6: { back = DKCT_SECTION_MODULE_START; } break;
+ }
+ } break;
+ default: {
+ switch(ai) {
+ case 0: { back = DKCT_SECTION_OPTIONS; } break;
+ case 1: { back = DKCT_SECTION_HEADER_START; } break;
+ case 6: { back = DKCT_SECTION_MODULE_START; } break;
+ case 12: { back = DKCT_SECTION_STATE_MACHINE; } break;
+ }
+ } break;
+ }
+ if(back == -1) {
+ dkct_to_log_3(psrc, 1, DK3_LL_ERROR, 43, 44, p1);
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+static
+void
+dkct_tr_expand_copyright_year(DKCT_SRC *psrc)
+{
+ char buf[16*sizeof(int)];
+ dk3_tm_t loctime;
+ dk3_time_t currenttime;
+ char *ptr;
+
+ ptr = dk3str_c8_chr(psrc->cry, 'x');
+ if (NULL != ptr) {
+ if ('x' == ptr[1]) {
+ if ('x' == ptr[2]) {
+ if ('x' == ptr[3]) {
+ if (0 != dk3sf_time(&currenttime)) {
+ if (0 != dk3sf_localtime_app(&loctime, &currenttime, NULL)) {
+ sprintf(buf, "%d", loctime.Y);
+ if (4 == dk3str_c8_len(buf)) {
+ ptr[0] = buf[0];
+ ptr[1] = buf[1];
+ ptr[2] = buf[2];
+ ptr[3] = buf[3];
+ }
+ } else {
+ /* ERROR: Failed to convert timer to local time */
+ }
+ } else {
+ /* ERROR: Failed to get current time */
+ }
+ }
+ }
+ }
+ }
+}
+
+
+
+static
+void
+dkct_tr_check_copyright_year(DKCT_SRC *psrc)
+{
+ dk3_tm_t loctime;
+ dk3_time_t currenttime;
+ int cry;
+ const char *p1;
+
+ $? "+ dkct_tr_check_copyright_year"
+ if (NULL != psrc) {
+ if (NULL != psrc->cry) {
+ p1 = dk3str_c8_rchr(psrc->cry, '-');
+ if (NULL != p1) {
+ p1++;
+ } else {
+ p1 = psrc->cry;
+ } $? ". p1 = %!8s", p1
+ if (0 != dk3ma_i_from_c8_string(&cry, p1, NULL)) {
+ $? ". cry = %d", cry
+ if (0 != dk3sf_time(&currenttime)) {
+ if (0 != dk3sf_localtime_app(&loctime, &currenttime, NULL)) {
+ $? ". loctime.Y = %d", loctime.Y
+ if (cry != loctime.Y) {
+ dk3app_log_1(psrc->app, DK3_LL_WARNING, psrc->msg, 113);
+ }
+ } else {
+ /* Failed to convert timer to local time */
+ }
+ } else {
+ /* Failed to obtain current time */
+ }
+ } else {
+ /* Failed to read integer from text */
+ }
+ }
+ } $? "- dkct_tr_check_copyright_year"
+}
+
+
+
+/** Process an option (key/value pair).
+ @param psrc Source structure.
+ @param key Key (option name).
+ @param val Value.
+ @param sufi Source file type.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_tr_process_option(DKCT_SRC *psrc, char *key, char *val, int sufi)
+{
+ int back = 0;
+ $? "+ dkct_tr_process_option \"%!8s\"=\"%!8s\"", key, val
+ switch(dk3str_c8_array_index(dkct_option_keywords, key, 0)) {
+ case 0: { $? ". copyright owner"
+ if(psrc->crn) {
+ /* Warning: Redefinition of copyright owner */
+ dkct_to_log_1(psrc, 1, DK3_LL_WARNING, 4);
+ dk3_release(psrc->crn);
+ }
+ psrc->crn = dk3str_c8_dup_app(val, psrc->app);
+ if(psrc->crn) {
+ back = 1;
+ } else {
+ psrc->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory */
+ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } break;
+ case 1: { $? ". copyright year"
+ if(psrc->cry) {
+ /* Warning: Redefinition of copyright year(s)! */
+ dkct_to_log_1(psrc, 1, DK3_LL_WARNING, 5);
+ dk3_release(psrc->cry);
+ }
+ psrc->cry = dk3str_c8_dup_app(val, psrc->app);
+ if(psrc->cry) {
+ dkct_tr_expand_copyright_year(psrc);
+ dkct_tr_check_copyright_year(psrc);
+ back = 1;
+ } else {
+ psrc->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory */
+ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } break;
+ case 2: { $? ". license type"
+ if(psrc->lict >= 0) {
+ /* Warning: Redefinition of license! */
+ dkct_to_log_1(psrc, 1, DK3_LL_WARNING, 6);
+ }
+ psrc->lict = dk3str_c8_array_index(dkct_license_names, val, 0);
+ if(psrc->lict >= 0) {
+ back = 1;
+ } else {
+ /* ERROR: Unknown license! */
+ dkct_to_log_3(psrc, 1, DK3_LL_ERROR, 7, 8, val);
+ psrc->ec = DK3_ERROR_SYNTAX;
+ }
+ } break;
+ case 3: { $? ". splint comment character"
+ if (val) {
+ (psrc->dkcto).spls = *val;
+ } else {
+ (psrc->dkcto).spls = '@';
+ }
+ back = 1;
+ } break;
+ default: {
+ dkct_to_log_3(psrc, 1, DK3_LL_ERROR, 10, 11, key);
+ back = 0;
+ } break;
+ } $? "- dkct_tr_process_option %d", back
+ return back;
+}
+
+
+
+/** Check whether the line contains a doxygen file start comment.
+ @param inputline Line to check.
+ @return 1 if comment found, 0 otherwise.
+*/
+static
+int
+dkct_tr_has_doxygen_file_comment(char *inputline)
+{
+ int back = 0;
+ char *p1;
+
+ p1 = strstr(inputline, "/**");
+ if (NULL != p1) {
+ p1 = dk3str_c8_start(&(p1[3]), NULL);
+ if (NULL != p1) {
+ if ('@' == *(p1++)) {
+ if ('f' == *(p1++)) {
+ if ('i' == *(p1++)) {
+ if ('l' == *(p1++)) {
+ if ('e' == *(p1++)) {
+ if ((' ' == *p1) || ('\t' == *p1)) {
+ back = 1;
+ } else {
+ if (('\r' == *p1) || ('\n' == *p1) || ('\0' == *p1)) {
+ back = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dkct_tr_read(DKCT_SRC *psrc, dkChar const *fn, int sufi)
+{
+ int back = 0;
+ dk3_sto_t *stp = NULL; /* Current storage to save lines. */
+ FILE *fipo = NULL; /* Input file. */
+ DKCT_LINE *pline = NULL; /* Input line to store. */
+ unsigned long lineno = 0UL; /* Input line number. */
+ int cc = 1; /* Flag: Can continue processing. */
+ int section = DKCT_SECTION_MODULE_START; /* Current section. */
+ char inputline[DKCT_LINE_SIZE]; /* Input line buffer. */
+ char *p1; /* Option name. */
+ char *p2; /* Option value. */
+ $? "+ dkct_tr_read"
+ if((psrc) && (fn)) { $? ". args ok"
+ fipo = dk3sf_fopen_app(fn, dk3app_not_localized(22), psrc->app);
+ if(fipo) { $? ". fipo ok"
+ back = 1;
+ switch(sufi) {
+ case 4: {
+ section = DKCT_SECTION_GUI;
+ } break;
+ default: {
+ stp = psrc->mss;
+ } break;
+ }
+ psrc->hdr = 0;
+ psrc->doxyh = 0;
+ psrc->doxym = 0;
+ do {
+ cc = 0;
+ if(fgets(inputline, sizeof(inputline), fipo)) {
+ cc = 1; lineno++;
+ psrc->lineno = lineno;
+ dk3app_set_source_line(psrc->app, lineno);
+ dk3str_c8_delnl(inputline); $? ". process line \"%!8s\"", inputline
+ if(dkct_tr_is_section_header(inputline)) {
+ /*
+ Start of new section.
+ */
+ stp = NULL;
+ psrc->cstm = NULL;
+ psrc->hdr = 0;
+ section = dkct_tr_find_section_number(psrc, inputline, sufi);
+ if(section == -1) {
+ psrc->ec = DK3_ERROR_SYNTAX; $? "! wrong section"
+ cc = 0;
+ } else {
+ switch(section) {
+ case DKCT_SECTION_MODULE_START: {
+ stp = psrc->mss;
+ } break;
+ case DKCT_SECTION_MODULE_END: {
+ stp = psrc->mes;
+ } break;
+ case DKCT_SECTION_CONSTRUCTOR_START: {
+ stp = psrc->coss;
+ } break;
+ case DKCT_SECTION_CONSTRUCTOR_END: {
+ stp = psrc->coes;
+ } break;
+ case DKCT_SECTION_HEADER_START: {
+ stp = psrc->hss;
+ psrc->hdr = 1;
+ } break;
+ case DKCT_SECTION_HEADER_END: {
+ stp = psrc->hes;
+ psrc->hdr = 1;
+ } break;
+ case DKCT_SECTION_CLASS_START: {
+ stp = psrc->clss;
+ } break;
+ case DKCT_SECTION_CLASS_END: {
+ stp = psrc->cles;
+ } break;
+ case DKCT_SECTION_STATE_MACHINE: {
+ psrc->cstm = dkct_au_stm_new(lineno, psrc->app);
+ if(psrc->cstm) { $? ". stm ok"
+ if(!dk3sto_add(psrc->s_stm, (void *)(psrc->cstm))) { $? "! failed to add"
+ dkct_au_stm_delete(psrc->cstm);
+ psrc->cstm = NULL;
+ }
+ } else {
+ /* ERROR: Memory! */
+ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } break;
+ case DKCT_SECTION_GUI: {
+ if(!(psrc->gui)) {
+ psrc->gui = (void *)dkct_gui_new(psrc);
+ }
+ if(!(psrc->gui)) {
+ back = 0;
+ psrc->ec = DK3_ERROR_MEMORY;
+ /* ERROR: Memory! */
+ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } break;
+ }
+ }
+ } else {
+ /*
+ Apply line to current section.
+ */
+ switch(section) {
+ case DKCT_SECTION_OPTIONS: {
+ p1 = dk3str_c8_start(inputline, NULL);
+ if(p1) {
+ if(*p1 != '#') {
+ p2 = dk3str_c8_chr(p1, '=');
+ if(p2) {
+ *(p2++) = '\0';
+ p2 = dk3str_c8_start(p2, NULL);
+ if(p2) {
+ dk3str_c8_normalize(p1, NULL, '-');
+ dk3str_c8_chomp(p2, NULL);
+ if(!dkct_tr_process_option(psrc, p1, p2, sufi)) {
+ cc = 0; psrc->ec = DK3_ERROR_SYNTAX;
+ }
+ } else {
+ /* ERROR: Syntax */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 9);
+ psrc->ec = DK3_ERROR_SYNTAX; cc = 0;
+ }
+ } else {
+ /* ERROR: Syntax */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 9);
+ psrc->ec = DK3_ERROR_SYNTAX; cc = 0;
+ }
+ }
+ }
+ } break;
+ case DKCT_SECTION_GUI: {
+ if(psrc->gui) {
+ if(back) {
+ if(!dkct_gui_add_line((DKCT_GUI *)(psrc->gui), inputline)) {
+ back = 0; $? "! error in GUI section line"
+ if(psrc->ec == 0) {
+ psrc->ec = DK3_ERROR_MEMORY;
+ }
+ }
+ }
+ } else {
+ back = 0;
+ psrc->ec = DK3_ERROR_MEMORY;
+ }
+ } break;
+ case DKCT_SECTION_STATE_MACHINE: {
+ if(!dkct_au_add_line(psrc->cstm, psrc, inputline, lineno)) {
+ back = 0; $? "! failed to add line to state machine"
+ }
+ } break;
+ default: {
+ if (0 < psrc->hdr) {
+ if (0 == psrc->doxyh) {
+ if (dkct_tr_has_doxygen_file_comment(inputline)) {
+ psrc->doxyh = 1;
+ }
+ }
+ } else {
+ if (0 == psrc->doxym) {
+ if (dkct_tr_has_doxygen_file_comment(inputline)) {
+ psrc->doxym = 1;
+ }
+ }
+ }
+ if(section > -1) {
+ if(stp) {
+ pline = dkct_tr_line_new(inputline, lineno, psrc->app);
+ if(pline) {
+ if(!dk3sto_add(stp, pline)) {
+ dkct_tr_line_delete(pline); pline = NULL;
+ psrc->ec = DK3_ERROR_MEMORY; cc = 0;
+ }
+ } else {
+ psrc->ec = DK3_ERROR_MEMORY; cc = 0;
+ /* ERROR: Memory! */
+ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 29);
+ }
+ } else {
+ psrc->ec = DK3_ERROR_MEMORY; cc = 0;
+ }
+ } else {
+ psrc->ec = DK3_ERROR_SYNTAX; cc = 0;
+ }
+ } break;
+ }
+ }
+ }
+#if DK3_USE_WX
+
+#endif
+ } while((cc) && (!(psrc->ec)));
+ /*
+ On error we can not return success.
+ */
+ if(psrc->ec) { $? "! ec indicates error"
+ back = 0;
+ }
+ fclose(fipo);
+ } else {
+ /* ERROR: Failed to open file! */
+ dkct_to_log_dk_3(psrc, 0, DK3_LL_ERROR, 20, 21, fn);
+ }
+ } $? "- dkct_tr_read %d", back
+ return back;
+}
+
+
+
+int
+dkct_tr_check(DKCT_SRC *psrc, dkChar const *fn, int sufi)
+{
+ int back = 0;
+ DKCT_STM *pstm; /* Current state machine to check. */
+ unsigned long stmno; /* Index of current state machine. */
+
+ $? "+ dkct_tr_check"
+ switch(sufi) {
+ case 4: {
+ back = dkct_gui_check(psrc);
+ } break;
+ default: {
+ back = 1;
+ } break;
+ }
+ if(back) { $? ". OK so far"
+ /*
+ Check state machines consistency
+ */
+ dk3sto_it_reset(psrc->i_stm);
+ stmno = 0UL;
+ while((pstm = (DKCT_STM *)dk3sto_it_next(psrc->i_stm)) != NULL) {
+ pstm->stmno = stmno++;
+ if(!dkct_au_stm_check(psrc, pstm)) {
+ back = 0; $? "! state machine check failed"
+ }
+ }
+ } $? "- dkct_tr_check %d", back
+ return back;
+}
+
+
+
+/** Check whether data for a header file is available.
+ @param psrc Source structure.
+ @return 1 if header data is available, 0 otherwise.
+*/
+static
+int
+dkct_tr_have_header_data(DKCT_SRC *psrc)
+{
+ int back = 0;
+ DKCT_STM *pstm; /* Current state machine to check for header data. */
+ $? "+ dkct_tr_have_header_data"
+ if(psrc->hsi) {
+ if(dk3sto_it_next(psrc->hsi)) {
+ back = 1;
+ }
+ }
+ if(psrc->hei) {
+ if(dk3sto_it_next(psrc->hei)) {
+ back = 1;
+ }
+ }
+ if(psrc->clsi) {
+ if(dk3sto_it_next(psrc->clsi)) {
+ back = 1;
+ }
+ }
+ if(psrc->clei) {
+ if(dk3sto_it_next(psrc->clei)) {
+ back = 1;
+ }
+ }
+ if(psrc->i_stm) {
+ dk3sto_it_reset(psrc->i_stm);
+ while((pstm = (DKCT_STM *)dk3sto_it_next(psrc->i_stm)) != NULL) {
+ if(pstm->wrh) {
+ back = 1;
+ }
+ }
+ } $? "- dkct_tr_have_header_data %d", back
+ return back;
+}
+
+
+
+/** Check whether data for a module file is available.
+ @param psrc Source structure.
+ @return 1 if module data is available, 0 otherwise.
+*/
+static
+int
+dkct_tr_have_module_data(DKCT_SRC *psrc)
+{
+ int back = 0;
+ $? "+ dkct_tr_have_module_data"
+ if(psrc->msi) {
+ if(dk3sto_it_next(psrc->msi)) {
+ back = 1;
+ }
+ }
+ if(psrc->mei) {
+ if(dk3sto_it_next(psrc->mei)) {
+ back = 1;
+ }
+ }
+ if(psrc->cosi) {
+ if(dk3sto_it_next(psrc->cosi)) {
+ back = 1;
+ }
+ }
+ if(psrc->coei) {
+ if(dk3sto_it_next(psrc->coei)) {
+ back = 1;
+ }
+ }
+ if(psrc->i_stm) {
+ dk3sto_it_reset(psrc->i_stm);
+ while(dk3sto_it_next(psrc->i_stm) != NULL) {
+ back = 1;
+ }
+ } $? "- dkct_tr_have_module_data %d", back
+ return back;
+}
+
+
+
+/** Write one text paragraph to output file.
+ @param fipo Output file.
+ @param tptr Pointer to text.
+*/
+static
+void
+dkct_tr_write_text(FILE *fipo, char const * const *tptr)
+{
+ char const * const *ptr; /* Write a text to file. */
+ $? "= dkct_tr_write_text"
+ ptr = tptr;
+ while(*ptr) {
+ fputs(*(ptr++), fipo);
+ fputc('\n', fipo);
+ }
+}
+
+
+
+/** Write copyright and license information for a known license name.
+ @param psrc Source structure.
+ @param license_text License text to print to file.
+*/
+static
+void
+dkct_tr_write_copyright_and_license_internal(
+ DKCT_SRC *psrc, char const * const *license_text
+)
+{
+ $? "+ dkct_tr_write_copyright_and_license_internal"
+ fputs(dkct_tr_kw8[2], psrc->fipo);
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+ if(psrc->crn) { $? ". copyright name ok"
+ fputs(dkct_tr_kw8[4], psrc->fipo);
+ if(psrc->cry) {
+ fputs(psrc->cry, psrc->fipo);
+ fputs(dkct_tr_kw8[5], psrc->fipo);
+ }
+ fputs(psrc->crn, psrc->fipo);
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+ }
+ dkct_tr_write_text(psrc->fipo, license_text);
+ fputs(dkct_tr_kw8[3], psrc->fipo);
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+ $? "- dkct_tr_write_copyright_and_license_internal"
+}
+
+
+
+/** Check whether we need to add a short description line
+ to the doxygen file tag.
+ If the output file is *.h and there is a *.dox file we can leave the
+ doxygen file tag in the header file empty as the *.dox file
+ contains the detailed description.
+ @param psrc Source structure.
+ @param ofn Output file name.
+ @return 1 to add description, 0 for empty tag.
+*/
+static
+int
+dkct_tr_need_file_description(DKCT_SRC *psrc, dkChar const *ofn)
+{
+ dkChar fnb[DK3_MAX_PATH];
+ dk3_stat_t st;
+ dkChar *fns;
+ int back = 1;
+ if(dk3str_len(ofn) < DK3_SIZEOF(fnb,dkChar)) {
+ dk3str_cpy_not_overlapped(fnb,ofn);
+ fns = dk3str_get_suffix(fnb);
+ if(fns) {
+#if DK3_HAVE_FNCASEINS
+ if(dk3str_casecmp(dkct_tr_kw[0], fns) == 0)
+#else
+ if(dk3str_cmp(dkct_tr_kw[0], fns) == 0)
+#endif
+ {
+ *fns = dkT('\0');
+ if(
+ (dk3str_len(fnb) + dk3str_len(dkct_tr_kw[1]))
+ < DK3_SIZEOF(fnb,dkChar)
+ )
+ {
+ dk3str_cat(fnb, dkct_tr_kw[1]);
+ if(dk3sf_stat_app(&st, fnb, NULL)) {
+ switch((st.ft) & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_REGULAR: {
+ back = 0;
+ } break;
+ }
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Write start of output file.
+ @param psrc Source structure.
+ @param ofn Output file name.
+ @param sfn Source file name.
+ @param f_hdr Flag: Output is a header file.
+*/
+static
+void
+dkct_tr_write_file_start(
+ DKCT_SRC *psrc, dkChar const *ofn, dkChar const *sfn, int f_hdr
+)
+{
+ char const * const *license_text_ptr = NULL; /* Text pointer. */
+ char myfn[DK3_MAX_PATH]; /* Short file name. */
+ char *ptr; /* Text pointer. */
+ char *myshortfn;
+ $? "+ dkct_tr_write_file_start \"%!ds\"", ofn
+ dkct_tr_write_text(psrc->fipo, dkct_tr_mod_warning_start);
+ if(psrc->sfn) {
+ fputs(dkct_tr_kw8[77], psrc->fipo);
+ fputs(psrc->sfn, psrc->fipo);
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+ }
+ dkct_tr_write_text(psrc->fipo, dkct_tr_mod_warning_end);
+ if((psrc->crn) || (psrc->cry) || (psrc->lict > -1)) {
+ switch(psrc->lict) {
+ case 0: { license_text_ptr = dkct_tr_bsd_text; } break;
+ case 1: { license_text_ptr = dkct_tr_gpl_text; } break;
+ case 2: { license_text_ptr = dkct_tr_lgpl_text; } break;
+ case 3: { } break;
+ case 4: { license_text_ptr = dkct_tr_commercial_text; } break;
+ }
+ if(license_text_ptr) { $? ". license terms internally known"
+ dkct_tr_write_copyright_and_license_internal(psrc,license_text_ptr);
+ } else { $? "! License not found"
+ /* ##### OTHER LICENSE */
+ }
+ }
+ if (((0 != f_hdr)&&(0 == psrc->doxyh))||((0 == f_hdr)&&(0 == psrc->doxym))) {
+ if(dk3str_string_to_c8_simple_app(myfn, sizeof(myfn), ofn, psrc->app)) {
+ fputs(dkct_tr_kw8[11], psrc->fipo);
+ if(dkct_tr_need_file_description(psrc, ofn)) {
+ myshortfn = dk3str_c8_rchr(myfn, DKCT_TR_SEP);
+ if(myshortfn) {
+ myshortfn++;
+ } else {
+ myshortfn = myfn;
+ }
+ fputs(myshortfn, psrc->fipo);
+ fputs(dkct_tr_kw8[(f_hdr) ? 12 : 14], psrc->fipo);
+ ptr = dk3str_c8_get_suffix(myfn);
+ if(ptr) { *ptr = '\0'; }
+ myshortfn = dk3str_c8_rchr(myfn, DKCT_TR_SEP);
+ if(myshortfn) {
+ myshortfn++;
+ } else {
+ myshortfn = myfn;
+ }
+ fputs(myshortfn, psrc->fipo);
+ fputs(dkct_tr_kw8[13], psrc->fipo);
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+ }
+ fputs(dkct_tr_kw8[3], psrc->fipo);
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+ } else {
+ /* ERROR: Not a simple file name! */
+ dkct_to_log_dk_3(psrc, 1, DK3_LL_ERROR, 12, 13, ofn);
+ }
+ }
+ $? "- dkct_tr_write_file_start"
+}
+
+
+
+/** Print file name char in upper cases.
+ Characters are printed upper-case, numbers ``as is'', all other
+ characters are replaced by underscore.
+ @param psrc Source structure.
+ @param c Character to print.
+*/
+static
+void
+dkct_tr_char_filename_to_upper(DKCT_SRC *psrc, char c)
+{
+ char oc; /* Output character. */
+ oc = '_';
+ if((c >= 'A') && (c <= 'Z')) {
+ oc = c;
+ } else {
+ if((c >= 'a') && (c <= 'z')) {
+ oc = (char)toupper(c);
+ } else {
+ if((c >= '0') && (c <= '9')) {
+ oc = c;
+ }
+ }
+ }
+ fputc(oc, psrc->fipo);
+}
+
+
+
+/** Print file name upper-case to avoid multiple inclusions.
+ @param psrc Source structure.
+ @param ofn Output file name.
+*/
+static
+void
+dkct_tr_filename_to_upper(DKCT_SRC *psrc, dkChar const *ofn)
+{
+ char b[DK3_MAX_PATH]; /* Temporary file name buffer. */
+ char *ptr; /* Current character to process. */
+ dkChar const *shortofn;
+
+ shortofn = dk3str_rchr(ofn, DK3_CHAR_SEP);
+ if(shortofn) {
+ shortofn++;
+ } else {
+ shortofn = ofn;
+ }
+ if(dk3str_string_to_c8_simple_app(b, sizeof(b), shortofn, psrc->app)) {
+ ptr = b;
+ while(*ptr) {
+ dkct_tr_char_filename_to_upper(psrc, *ptr);
+ ptr++;
+ }
+ } else {
+ /* ERROR: Illegal file name! */
+ dkct_to_log_dk_3(psrc, 1, DK3_LL_ERROR, 12, 13, ofn);
+ }
+}
+
+
+
+void
+dkct_tr_show_source_line(DKCT_SRC *psrc, size_t newlines)
+{
+ size_t i;
+ if(psrc->sufi != 3) {
+ if(newlines > 0) {
+ for(i = 0; i < newlines; i++) {
+ fputc('\n', psrc->fipo);
+ }
+ }
+ fprintf(psrc->fipo, dkct_tr_kw8[20], psrc->lineno, psrc->sfn);
+ }
+}
+
+
+
+#if 0
+/** Process header lines from storage iterator.
+ @param psrc Source structure,
+ @param iterator Iterator for source line storage.
+*/
+static
+void
+dkct_tr_header_lines(DKCT_SRC *psrc, dk3_sto_it_t *iterator)
+{
+ DKCT_LINE *lp; /* Current line to process. */
+
+ if(iterator) {
+ dk3sto_it_reset(iterator);
+ while((lp = (DKCT_LINE *)dk3sto_it_next(iterator)) != NULL) {
+ $? ". just another line"
+ if(lp->t) { $? ". line contains text"
+ psrc->lineno = lp->l;
+ if(psrc->shln) {
+ psrc->shln = 0;
+ dkct_tr_show_source_line(psrc, 1);
+ }
+ fputs(lp->t, psrc->fipo);
+ fputc('\n', psrc->fipo);
+ } else { $? "! no text in line"
+ }
+ }
+ }
+}
+#endif
+
+
+
+/** Find action to process current input character.
+ @param st Pointer to state variable.
+ @param input Current input character.
+ @return Action identifier.
+*/
+static
+int
+dkct_tr_state_machine_transition(int *st, int input)
+{
+ int back = 0;
+ int ns = 0; /* New state. */
+ $? "+ dkct_tr_state_machine_transition %d %d %!8c", *st, input, (char)input
+ switch(*st) {
+ case 0: { /* Initial state. */
+ switch(input) {
+ case '\\': { ns = 1; back = DKCT_O_PRINT; } break;
+ case '"': { ns = 2; back = DKCT_O_PRINT; } break;
+ case '\'': { ns = 4; back = DKCT_O_PRINT; } break;
+ case '/': { ns = 6; back = DKCT_O_NOOP; } break;
+ case TRACE_CONTROL: { ns = 10; back = DKCT_O_RESET_BUFFER; } break;
+ default: { ns = 0; back = DKCT_O_PRINT; } break;
+ }
+ } break;
+ case 1: { /* After backslash. */
+ ns = 0; back = DKCT_O_PRINT;
+ } break;
+ case 2: { /* In a string. */
+ back = DKCT_O_PRINT;
+ switch(input) {
+ case '"': { ns = 0; } break;
+ case '\\': { ns = 3; } break;
+ default: { ns = 2; } break;
+ }
+ } break;
+ case 3: { /* After backslash in string. */
+ ns = 2; back = DKCT_O_PRINT;
+ } break;
+ case 4: { /* Single character literal. */
+ back = DKCT_O_PRINT;
+ switch(input) {
+ case '\'': { ns = 0; } break;
+ case '\\': { ns = 5; } break;
+ default: { ns = 4; } break;
+ }
+ } break;
+ case 5: { /* After backslash in character literal. */
+ ns = 4; back = DKCT_O_PRINT;
+ } break;
+ case 6: { /* After slash. */
+ switch(input) {
+ case '/': { ns = 7; back = DKCT_O_START_CPP_COMMENT; } break;
+ case '*': { ns = 8; back = DKCT_O_SLASH_AND_CHAR; } break;
+ default: { ns = 0; back = DKCT_O_SLASH_AND_CHAR; } break;
+ }
+ } break;
+ case 7: { /* In C++ style comment. */
+ switch(input) {
+ case '\n': { ns = 0; back = DKCT_O_END_CPP_COMMENT; } break;
+ default: { ns = 7; back = DKCT_O_PRINT; } break;
+ }
+ } break;
+ case 8: { /* In normal comment. */
+ back = DKCT_O_PRINT;
+ switch(input) {
+ case '*': { ns = 9; } break;
+ default: { ns = 8; } break;
+ }
+ } break;
+ case 9: { /* After * in normal comment. */
+ back = DKCT_O_PRINT;
+ switch(input) {
+ case '*': { ns = 9; } break;
+ case '/': { ns = 0; } break;
+ default: { ns = 8; } break;
+ }
+ } break;
+ case 10: { /* After TRACE_CONTROL. */
+ switch(input) {
+ case '(': { ns = 15; back = DKCT_O_RESET_BUFFER; } break;
+ case '!': { ns = 12; back = DKCT_O_RESET_BUFFER; } break;
+ case '?': { ns = 11; back = DKCT_O_RESET_BUFFER; } break;
+ case '*': { ns = 17; back = DKCT_O_START_BOX; } break;
+ default: { ns = 0; back = DKCT_O_DOLLAR_AND_CHAR; } break;
+ }
+ } break;
+ case 11: { /* After TRACE_CONTROL, ?. */
+ switch(input) {
+ case '\n': { ns = 0; back = DKCT_O_TRACE_OUTPUT; } break;
+ case ' ':
+ case '\t': { ns = 11; back = DKCT_O_NOOP; } break;
+ default: { ns = 13; back = DKCT_O_ADD_BUFFER; } break;
+ }
+ } break;
+ case 12: { /* After TRACE_CONTROL, !. */
+ switch(input) {
+ case '\n': { ns = 0; back = DKCT_O_EXEC_CMD; } break;
+ case ' ':
+ case '\t': { ns = 12; back = DKCT_O_NOOP; } break;
+ default: { ns = 14; back = DKCT_O_ADD_BUFFER; } break;
+ }
+ } break;
+ case 13: { /* In debug output. */
+ switch(input) {
+ case '\n': { ns = 0; back = DKCT_O_TRACE_OUTPUT; } break;
+ default: { ns = 13; back = DKCT_O_ADD_BUFFER; } break;
+ }
+ } break;
+ case 14: { /* In interprete context. */
+ switch(input) {
+ case '\n': { ns = 0; back = DKCT_O_EXEC_CMD; } break;
+ default: { ns = 14; back = DKCT_O_ADD_BUFFER; } break;
+ }
+ } break;
+ case 15: { /* In brackets in interprete context. */
+ switch(input) {
+ case '\n': { ns = 0; back = DKCT_O_PRINT; } break;
+ case ')': { ns = 1; back = DKCT_O_NOOP; } break;
+ case ' ':
+ case '\t': { ns = 15; back = DKCT_O_NOOP; } break;
+ default: { ns = 16; back = DKCT_O_ADD_BUFFER; } break;
+ }
+ } break;
+ case 16: {
+ switch(input) {
+ case ')': { ns = 0; back = DKCT_O_EXEC_CMD; } break;
+ default: { ns = 16; back = DKCT_O_ADD_BUFFER; } break;
+ }
+ } break;
+ case 17: { /* In comment box. */
+ switch(input) {
+ case '\n': { ns = 17; back = DKCT_O_ADD_BOX_NL; } break;
+ case TRACE_CONTROL: { ns = 18; back = DKCT_O_NOOP; } break;
+ default: { ns = 17; back = DKCT_O_ADD_BOX; } break;
+ }
+ } break;
+ case 18: { /* In comment box, found TRACE_CONTROL. */
+ switch(input) {
+ case '*': { ns = 0; back = DKCT_O_END_BOX; } break;
+ default: { ns = 17; back = DKCT_O_ADD_BOX_DOLLAR_CHAR;
+ } break;
+ }
+ } break;
+ }
+ *st = ns; $? "- dkct_tr_state_machine_transition %d (new state %d)", back, ns
+ return back;
+}
+
+
+
+void
+dkct_tr_show_filename_and_lineno(DKCT_SRC *psrc)
+{
+ $? "+ dkct_tr_show_filename_and_lineno"
+ fputs(dkct_tr_kw8[18], psrc->fipo);
+ fputs(psrc->sfn, psrc->fipo);
+ fputs(dkct_tr_kw8[17], psrc->fipo);
+ fprintf(psrc->fipo, "%lu", psrc->lineno);
+ fputs(dkct_tr_kw8[17], psrc->fipo);
+ fputs(dkct_tr_kw8[1], psrc->fipo);
+ if((psrc->dkcto).tkw) {
+ fputs(dkct_tr_kw8[19], psrc->fipo);
+ }
+ fputs(dkct_tr_kw8[18], psrc->fipo);
+ $? "- dkct_tr_show_filename_and_lineno"
+}
+
+
+
+/** Mark buffer as completely empty.
+ @param psrc Source structure.
+*/
+static
+void
+dkct_tr_reset_buffer(DKCT_SRC *psrc)
+{
+ dk3mem_res(psrc->cmdb, psrc->szcmd);
+ psrc->ucmd = 0;
+}
+
+
+
+static
+void
+dkct_tr_convert_printf_format(
+ DKCT_SRC *psrc,
+ int trace_wide,
+ int on_windows,
+ int wx_wide,
+ int dk_wide,
+ char c1,
+ char c2
+)
+{
+ int show_long = 0;
+ int show_short = 0;
+
+ fputc('%', psrc->fipo);
+ if (0 != trace_wide) {
+ if (0 != on_windows) {
+ switch (c1) {
+ case '8' : {
+ show_short = 1;
+ } break;
+ case 'd' : {
+ if (0 != dk_wide) {
+ show_long = 1;
+ } else {
+ show_short = 1;
+ }
+ } break;
+ case 'w' : case 'x' : {
+ if (0 != wx_wide) {
+ show_long = 1;
+ } else {
+ show_short = 1;
+ }
+ } break;
+ }
+ } else {
+ switch (c1) {
+ case 'd' : {
+ if (0 != dk_wide) { show_long = 1; }
+ } break;
+ case 'w' : case 'x' : {
+ if (0 != wx_wide) { show_long = 1; }
+ } break;
+ }
+ }
+ } else {
+ switch (c1) {
+ case 'd' : {
+ if (0 != dk_wide) { show_long = 1; }
+ } break;
+ case 'w' : case 'x' : {
+ if (0 != wx_wide) { show_long = 1; }
+ } break;
+ }
+ }
+ if (0 != show_long) {
+ fputc('l', psrc->fipo);
+ } else {
+ if (0 != show_short) {
+ fputc('h', psrc->fipo);
+ }
+ }
+ fputc(c2, psrc->fipo);
+}
+
+
+
+static
+int
+dkct_tr_must_convert(const char *p)
+{
+ int back = 0;
+ int in_format = 0;
+ while (('\0' != *p) && (0 == back)) {
+ if ('"' == *p) {
+ in_format = ((0 == in_format) ? 1 : 0);
+ if (0 == in_format) { goto finished; }
+ } else {
+ if (0 != in_format) {
+ if ('\\' == *p) {
+ if ('\0' != p[1]) { p++; }
+ else { goto finished; }
+ } else {
+ if ('%' == *p) {
+ if ('%' == p[1]) {
+ p++;
+ } else {
+ if ('!' == p[1]) {
+ switch (p[2]) {
+ case '8' : case 'w' : case 'd' : case 'x' : {
+ switch (p[3]) {
+ case 'c' : case 's' : {
+ back = 1;
+ goto finished;
+ } break;
+ }
+ } break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ p++;
+ }
+ finished:
+ return back;
+}
+
+
+
+static
+void
+dkct_tr_printf_format_and_args(
+ DKCT_SRC *psrc,
+ const char *p,
+ int trace_wide,
+ int on_windows,
+ int wx_wide,
+ int dk_wide
+)
+{
+ int in_format = 0;
+ int must_convert = 0;
+
+ while ('\0' != *p) {
+ if ('"' == *p) {
+ in_format = ((0 == in_format) ? 1 : 0);
+ fputc(*p, psrc->fipo);
+ } else {
+ if (0 != in_format) {
+ if ('\\' == *p) {
+ if ('\0' != p[1]) {
+ fputc(*(p++), psrc->fipo);
+ fputc(*p, psrc->fipo);
+ } else {
+ fputc(*p, psrc->fipo);
+ }
+ } else {
+ if ('%' == *p) {
+ if ('%' == p[1]) {
+ fputc(*(p++), psrc->fipo);
+ fputc(*p, psrc->fipo);
+ } else {
+ must_convert = 0;
+ if ('!' == p[1]) {
+ switch (p[2]) {
+ case '8' : case 'w' : case 'd' : case 'x' : {
+ switch (p[3]) {
+ case 'c' : case 's' : {
+ must_convert = 1;
+ } break;
+ }
+ } break;
+ }
+ }
+ if (0 != must_convert) {
+ dkct_tr_convert_printf_format(
+ psrc, trace_wide, on_windows, wx_wide, dk_wide, p[2], p[3]
+ );
+ p++; p++; p++;
+ } else {
+ fputc(*p, psrc->fipo);
+ }
+ }
+ } else {
+ fputc(*p, psrc->fipo);
+ }
+ }
+ } else {
+ fputc(*p, psrc->fipo);
+ }
+ }
+ p++;
+ }
+}
+
+
+
+/** Write trace information instructions to output.
+ @param psrc Source structure.
+*/
+static
+void
+dkct_tr_trace_output(DKCT_SRC *psrc)
+{
+ char const *fnptr = NULL; /* File to use for debug output. */
+ int mconv = 0; /* Flag: Must convert to multiple lines. */
+
+ if(((psrc->dkcto).deb) && ((psrc->dkcto).deben)) {
+ switch(psrc->sufi) {
+ case 3: {
+ /*
+ Java
+ */
+ fputs(dkct_tr_kw8[15], psrc->fipo);
+ dkct_tr_show_filename_and_lineno(psrc);
+ fputs(dkct_tr_kw8[16], psrc->fipo);
+ if(psrc->ucmd > 0) {
+ fputs(psrc->cmdb, psrc->fipo);
+ } else {
+ fputs(dkct_tr_kw8[1], psrc->fipo);
+ }
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+ } break;
+ /*
+ C/C++
+ */
+ default: {
+ fnptr = dkct_tr_kw8[((psrc->dkcto).deb == 2) ? 28 : 29];
+ mconv = dkct_tr_must_convert(psrc->cmdb);
+ fputs(dkct_tr_kw8[24], psrc->fipo); /* TRACE BEGIN */
+ if(((psrc->dkcto).win) || ((psrc->dkcto).port)) {
+ /*
+ Mit wide char Code.
+ */
+ fputs(dkct_tr_kw8[21], psrc->fipo);
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_kw8[30], psrc->fipo); /* if(dktrace_file()) */
+ }
+ if((psrc->dkcto).ts) {
+ if((psrc->dkcto).deb == 2) {
+ fputs(dkct_tr_kw8[72], psrc->fipo); /* dktrace_time(); */
+ } else {
+ fputs(dkct_tr_kw8[71], psrc->fipo);
+ }
+ }
+ fputs(dkct_tr_kw8[61], psrc->fipo); /* fputs( */
+ dkct_tr_show_filename_and_lineno(psrc);
+ fputs(dkct_tr_kw8[35], psrc->fipo); /* , */
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_kw8[34], psrc->fipo); /* ); */
+ if(psrc->ucmd > 0) {
+ if (((psrc->dkcto).port) && (0 != mconv)) {
+ fputs(dkct_tr_kw8[85], psrc->fipo);
+ /* + wide, windows */
+ fputs(dkct_tr_kw8[83], psrc->fipo);
+ /* +++ wide, windows, wx wide */
+ fputs(dkct_tr_kw8[84], psrc->fipo);
+ /* +++++ wide, windows, wx wide, dk wide */
+ dkct_tr_show_source_line(psrc, 0);
+ fputs(dkct_tr_kw8[62], psrc->fipo); /* fwprintf( */
+ fputs(fnptr, psrc->fipo); /* file name ( stdout */
+ fputs(dkct_tr_kw8[63], psrc->fipo);
+ dkct_tr_printf_format_and_args( psrc, psrc->cmdb, 1, 1, 1, 1);
+ fputs(dkct_tr_kw8[34], psrc->fipo); /* ); */
+ /* ----- wide, windows, wx wide, dk wide */
+ fputs(dkct_tr_kw8[22], psrc->fipo);
+ /* +++++ wide, windows, wx wide, dk not wide */
+ dkct_tr_show_source_line(psrc, 0);
+ fputs(dkct_tr_kw8[62], psrc->fipo); /* fwprintf( */
+ fputs(fnptr, psrc->fipo); /* file name ( stdout */
+ fputs(dkct_tr_kw8[63], psrc->fipo);
+ dkct_tr_printf_format_and_args(psrc, psrc->cmdb, 1, 1, 1, 0);
+ fputs(dkct_tr_kw8[34], psrc->fipo); /* ); */
+ /* ----- wide, windows, wx wide, dk not wide */
+ fputs(dkct_tr_kw8[23], psrc->fipo);
+ /* --- wide, windows, wx wide */
+ fputs(dkct_tr_kw8[22], psrc->fipo);
+ /* +++ wide, windows, wx not wide */
+ fputs(dkct_tr_kw8[84], psrc->fipo);
+ /* +++++ wide, windows, wx not wide, dk wide */
+ dkct_tr_show_source_line(psrc, 0);
+ fputs(dkct_tr_kw8[62], psrc->fipo); /* fwprintf( */
+ fputs(fnptr, psrc->fipo); /* file name ( stdout */
+ fputs(dkct_tr_kw8[63], psrc->fipo);
+ dkct_tr_printf_format_and_args(psrc, psrc->cmdb, 1, 1, 0, 1);
+ fputs(dkct_tr_kw8[34], psrc->fipo); /* ); */
+ /* ----- wide, windows, wx not wide, dk wide */
+ fputs(dkct_tr_kw8[22], psrc->fipo);
+ /* +++++ wide, windows, wx not wide, dk not wide */
+ dkct_tr_show_source_line(psrc, 0);
+ fputs(dkct_tr_kw8[62], psrc->fipo); /* fwprintf( */
+ fputs(fnptr, psrc->fipo); /* file name ( stdout */
+ fputs(dkct_tr_kw8[63], psrc->fipo);
+ dkct_tr_printf_format_and_args(psrc, psrc->cmdb, 1, 1, 0, 0);
+ fputs(dkct_tr_kw8[34], psrc->fipo); /* ); */
+ /* -----wide, windows, wx not wide, dk not wide */
+ fputs(dkct_tr_kw8[23], psrc->fipo);
+ /* --- wide, windows, wx not wide */
+ fputs(dkct_tr_kw8[23], psrc->fipo);
+ /* - wide, windows */
+ fputs(dkct_tr_kw8[22], psrc->fipo);
+ /* + wide, not windows */
+ fputs(dkct_tr_kw8[83], psrc->fipo);
+ /* +++ wide, not windows, wx wide */
+ fputs(dkct_tr_kw8[84], psrc->fipo);
+ /* +++++ wide, not windows, wx wide, dk wide */
+ dkct_tr_show_source_line(psrc, 0);
+ fputs(dkct_tr_kw8[62], psrc->fipo); /* fwprintf( */
+ fputs(fnptr, psrc->fipo); /* file name ( stdout */
+ fputs(dkct_tr_kw8[63], psrc->fipo);
+ dkct_tr_printf_format_and_args(psrc, psrc->cmdb, 1, 0, 1, 1);
+ fputs(dkct_tr_kw8[34], psrc->fipo); /* ); */
+ /* ----- wide, not windows, wx wide, dk wide */
+ fputs(dkct_tr_kw8[22], psrc->fipo);
+ /* +++++ wide, not windows, wx wide, dk not wide */
+ dkct_tr_show_source_line(psrc, 0);
+ fputs(dkct_tr_kw8[62], psrc->fipo); /* fwprintf( */
+ fputs(fnptr, psrc->fipo); /* file name ( stdout */
+ fputs(dkct_tr_kw8[63], psrc->fipo);
+ dkct_tr_printf_format_and_args(psrc, psrc->cmdb, 1, 0, 1, 0);
+ fputs(dkct_tr_kw8[34], psrc->fipo); /* ); */
+ /* ----- wide, not windows, wx wide, dk not wide */
+ fputs(dkct_tr_kw8[23], psrc->fipo);
+ /* --- wide, not windows, wx wide */
+ fputs(dkct_tr_kw8[22], psrc->fipo);
+ /* +++ wide, not windows, wx not wide */
+ fputs(dkct_tr_kw8[84], psrc->fipo);
+ /* +++++ wide, not windows, wx not wide, dk wide */
+ dkct_tr_show_source_line(psrc, 0);
+ fputs(dkct_tr_kw8[62], psrc->fipo); /* fwprintf( */
+ fputs(fnptr, psrc->fipo); /* file name ( stdout */
+ fputs(dkct_tr_kw8[63], psrc->fipo);
+ dkct_tr_printf_format_and_args(psrc, psrc->cmdb, 1, 0, 0, 1);
+ fputs(dkct_tr_kw8[34], psrc->fipo); /* ); */
+ /* ----- wide, not windows, wx not wide, dk wide */
+ fputs(dkct_tr_kw8[22], psrc->fipo);
+ /* +++++ wide, not windows, wx not wide, dk not wide */
+ dkct_tr_show_source_line(psrc, 0);
+ fputs(dkct_tr_kw8[62], psrc->fipo); /* fwprintf( */
+ fputs(fnptr, psrc->fipo); /* file name ( stdout */
+ fputs(dkct_tr_kw8[63], psrc->fipo);
+ dkct_tr_printf_format_and_args(psrc, psrc->cmdb, 1, 0, 0, 0);
+ fputs(dkct_tr_kw8[34], psrc->fipo); /* ); */
+ /* ----- wide, not windows, wx not wide, dk not wide */
+ fputs(dkct_tr_kw8[23], psrc->fipo);
+ /* --- wide, not windows, wx not wide */
+ fputs(dkct_tr_kw8[23], psrc->fipo);
+ /* - wide, not windows */
+ fputs(dkct_tr_kw8[23], psrc->fipo);
+ } else {
+ dkct_tr_show_source_line(psrc, 0);
+ fputs(dkct_tr_kw8[62], psrc->fipo); /* fwprintf( */
+ fputs(fnptr, psrc->fipo); /* file name ( stdout */
+ fputs(dkct_tr_kw8[63], psrc->fipo);
+#if 0
+ fputs(psrc->cmdb, psrc->fipo);
+#endif
+ dkct_tr_printf_format_and_args(
+ psrc, psrc->cmdb, 1, is_on_windows, is_wx_wide, is_dk_wide
+ );
+ fputs(dkct_tr_kw8[34], psrc->fipo); /* ); */
+ }
+ fputs(dkct_tr_kw8[64], psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_kw8[34], psrc->fipo);
+ fputs(dkct_tr_kw8[37], psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_kw8[34], psrc->fipo);
+ }
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_kw8[31], psrc->fipo);
+ }
+ fputs(dkct_tr_kw8[22], psrc->fipo);
+ }
+ /*
+ Mit oder ohne wide char (in beiden Faellen).
+ */
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_kw8[30], psrc->fipo); /* if(dktrace_file()) */
+ }
+ if((psrc->dkcto).ts) {
+ if((psrc->dkcto).deb == 2) {
+ fputs(dkct_tr_kw8[70], psrc->fipo); /* dktrace_time(); */
+ } else {
+ fputs(dkct_tr_kw8[32], psrc->fipo);
+ }
+ }
+ fputs(dkct_tr_kw8[33], psrc->fipo); /* fputs( */
+ dkct_tr_show_filename_and_lineno(psrc);
+ fputs(dkct_tr_kw8[35], psrc->fipo); /* , */
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_kw8[34], psrc->fipo); /* ); */
+ if(psrc->ucmd > 0) {
+ if (((psrc->dkcto).port) && (0 != mconv)) {
+ fputs(dkct_tr_kw8[83], psrc->fipo);
+ /* +++ not-wide, wx wide */
+ fputs(dkct_tr_kw8[84], psrc->fipo);
+ /* +++++ not-wide, wx wide, dk wide */
+ dkct_tr_show_source_line(psrc, 0);
+ fputs(dkct_tr_kw8[36], psrc->fipo); /* fprintf( */
+ fputs(fnptr, psrc->fipo); /* file name or stdout */
+ fputs(dkct_tr_kw8[35], psrc->fipo);
+ dkct_tr_printf_format_and_args(
+ psrc, psrc->cmdb, 0, is_on_windows, 1, 1
+ );
+ fputs(dkct_tr_kw8[34], psrc->fipo); /* ); */
+ /* ----- not-wide, wx wide, dk wide */
+ fputs(dkct_tr_kw8[22], psrc->fipo);
+ /* +++++ not-wide, wx wide, dk not wide */
+ dkct_tr_show_source_line(psrc, 0);
+ fputs(dkct_tr_kw8[36], psrc->fipo); /* fprintf( */
+ fputs(fnptr, psrc->fipo); /* file name or stdout */
+ fputs(dkct_tr_kw8[35], psrc->fipo);
+ dkct_tr_printf_format_and_args(
+ psrc, psrc->cmdb, 0, is_on_windows, 1, 0
+ );
+ fputs(dkct_tr_kw8[34], psrc->fipo); /* ); */
+ /* ----- not-wide, wx wide, dk not wide */
+ fputs(dkct_tr_kw8[23], psrc->fipo);
+ /* --- not-wide, wx wide */
+ fputs(dkct_tr_kw8[22], psrc->fipo);
+ /* +++ not-wide, wx not wide */
+ fputs(dkct_tr_kw8[84], psrc->fipo);
+ /* +++++ not-wide, wx not wide, dk wide */
+ dkct_tr_show_source_line(psrc, 0);
+ fputs(dkct_tr_kw8[36], psrc->fipo); /* fprintf( */
+ fputs(fnptr, psrc->fipo); /* file name or stdout */
+ fputs(dkct_tr_kw8[35], psrc->fipo);
+ dkct_tr_printf_format_and_args(
+ psrc, psrc->cmdb, 0, is_on_windows, 0, 1
+ );
+ fputs(dkct_tr_kw8[34], psrc->fipo); /* ); */
+ /* ----- not-wide, wx not wide, dk wide */
+ fputs(dkct_tr_kw8[22], psrc->fipo);
+ /* +++++ not-wide, wx not wide, dk not wide */
+ dkct_tr_show_source_line(psrc, 0);
+ fputs(dkct_tr_kw8[36], psrc->fipo); /* fprintf( */
+ fputs(fnptr, psrc->fipo); /* file name or stdout */
+ fputs(dkct_tr_kw8[35], psrc->fipo);
+ dkct_tr_printf_format_and_args(
+ psrc, psrc->cmdb, 0, is_on_windows, 0, 0
+ );
+ fputs(dkct_tr_kw8[34], psrc->fipo); /* ); */
+ /* ----- not-wide, wx not wide, dk not wide */
+ fputs(dkct_tr_kw8[23], psrc->fipo);
+ /* --- not-wide, wx not wide */
+ fputs(dkct_tr_kw8[23], psrc->fipo);
+ } else {
+ dkct_tr_show_source_line(psrc, 0);
+ fputs(dkct_tr_kw8[36], psrc->fipo); /* fprintf( */
+ fputs(fnptr, psrc->fipo); /* file name or stdout */
+ fputs(dkct_tr_kw8[35], psrc->fipo);
+#if 0
+ fputs(psrc->cmdb, psrc->fipo);
+#endif
+ dkct_tr_printf_format_and_args(
+ psrc, psrc->cmdb, 0, is_on_windows, is_wx_wide, is_dk_wide
+ );
+ fputs(dkct_tr_kw8[34], psrc->fipo); /* ); */
+ }
+ fputs(dkct_tr_kw8[48], psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_kw8[34], psrc->fipo);
+ fputs(dkct_tr_kw8[37], psrc->fipo);
+ fputs(fnptr, psrc->fipo);
+ fputs(dkct_tr_kw8[34], psrc->fipo);
+ }
+ if((psrc->dkcto).deb != 2) {
+ fputs(dkct_tr_kw8[31], psrc->fipo);
+ }
+ if(((psrc->dkcto).win) || ((psrc->dkcto).port)) {
+ /*
+ Closing endif for wide char code.
+ */
+ fputs(dkct_tr_kw8[23], psrc->fipo);
+ }
+ fputs(dkct_tr_kw8[25], psrc->fipo);
+ } break;
+ }
+ } else {
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+ }
+}
+
+
+
+/** Create full path name from relative file name.
+ @param psrc Source structure.
+ @param fn Short file name.
+ @param fnb Buffer for full path name.
+ @param szfnb Size of \a fnb.
+ @return Pointer to buffer with full path name on success,
+ NULL on error.
+*/
+static
+char *
+dkct_tr_function_filename(
+ DKCT_SRC *psrc,
+ char *fn,
+ char *fnb,
+ size_t szfnb
+)
+{
+ char *back = NULL;
+ char *ptr;
+ size_t sz;
+ int ie;
+ $? "+ dkct_tr_function_filename %!8s", TR_8STR(fn)
+ if(dk3str_c8_is_abs_path(fn) || (psrc->curdi)) { $? ". abs or cur"
+ back = fn;
+ } else { $? ". must check"
+ ie = dk3app_get_encoding(psrc->app);
+ if(dk3str_to_c8p_app(fnb, szfnb, psrc->ffn, ie, psrc->app)) {
+ ptr = dk3str_c8_rchr(fnb, (dkct_tr_kw8[78])[0]); $? ". converted"
+ if(ptr) { $? ". directory part"
+ *ptr = '\0'; $? ". dir = \"%!8s\"", fnb
+ sz = dk3str_c8_len(fnb);
+ sz += 1;
+ sz += dk3str_c8_len(fn);
+ if(sz < szfnb) { $? ". size ok"
+ strcat(fnb, dkct_tr_kw8[78]);
+ strcat(fnb, fn);
+ back = fnb;
+ } else { $? "! too large"
+ /* ERROR: Resulting file name too long! 101 */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 101);
+ }
+ } else { $? ". no separator"
+ back = fn;
+ }
+ } else { $? "! failed to convert source name"
+ /* ERROR: Non-ASCII characters in source file name! */
+ dkct_to_log_dk_3(psrc, 1, DK3_LL_ERROR, 102, 103, psrc->ffn);
+ }
+ } $? "- dkct_tr_function_filename \"%!8s\"", TR_8STR(back)
+ return back;
+}
+
+
+
+/** Disable debugging.
+ @param psrc Source structure.
+ @param args Arguments (ignored).
+ @return 1 on success, 0 on error.
+
+*/
+static
+int
+dkct_tr_fct_trace_off(DKCT_SRC *psrc, char *args)
+{
+ (psrc->dkcto).deben = 0;
+ return 1;
+}
+
+
+
+/** Enable debugging.
+ @param psrc Source structure.
+ @param args Arguments (ignored).
+ @return 1 on success, 0 on error.
+
+*/
+static
+int
+dkct_tr_fct_trace_on(DKCT_SRC *psrc, char *args)
+{
+ (psrc->dkcto).deben = 1;
+ return 1;
+}
+
+
+
+/** Initialize tracing for source.
+ @param psrc Source structure.
+ @param args Debug output file name.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_tr_fct_trace_init(DKCT_SRC *psrc, char *args)
+{
+ int back = 0;
+
+ if((psrc->dkcto).deb == 1) {
+ if(args) {
+ fputs(dkct_tr_kw8[45], psrc->fipo);
+ fputs(args, psrc->fipo);
+ fputs(dkct_tr_kw8[46], psrc->fipo);
+ if(((psrc->dkcto).win) || ((psrc->dkcto).port)) {
+ fputs(dkct_tr_kw8[82], psrc->fipo);
+ fputs(dkct_tr_kw8[56], psrc->fipo);
+
+ fputs(dkct_tr_kw8[57], psrc->fipo);
+ fputs(dkct_tr_kw8[58], psrc->fipo);
+
+ fputs(dkct_tr_kw8[59], psrc->fipo);
+ fputs(dkct_tr_kw8[23], psrc->fipo);
+ }
+ back = 1;
+ } else {
+ /* ERROR: Missing file name! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 14);
+ }
+ } else {
+ back = 1;
+ if((psrc->dkcto).deb == 2) {
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+ if(((psrc->dkcto).win) || ((psrc->dkcto).port)) {
+ fputs(dkct_tr_kw8[82], psrc->fipo);
+ fputs(dkct_tr_kw8[60], psrc->fipo);
+ fputs(dkct_tr_kw8[23], psrc->fipo);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** End tracing for a source.
+ @param psrc Source structure.
+ @param args Ignored.
+ @return 1 on success always.
+*/
+static
+int
+dkct_tr_fct_trace_end(DKCT_SRC *psrc, char *args)
+{
+ int back = 1;
+
+ if((psrc->dkcto).deb == 1) {
+ fputs(dkct_tr_kw8[47], psrc->fipo);
+ }
+ return back;
+}
+
+
+
+/** Write "#include <dk3trace.h>" to output.
+ @param psrc Source structure.
+ @param args Ignored.
+ @return 1 to indicate success always.
+*/
+static
+int
+dkct_tr_fct_trace_include(DKCT_SRC *psrc, char *args)
+{
+ int back = 0;
+ if((psrc->dkcto).deb) {
+ if(!((psrc->dkcto).tip)) {
+ if((psrc->dkcto).deb == 2) {
+ fputs(dkct_tr_kw8[68], psrc->fipo);
+ }
+ fputs(dkct_tr_kw8[44], psrc->fipo);
+ fputs(dkct_tr_kw8[79], psrc->fipo);
+ }
+ }
+ return back;
+}
+
+
+
+/** Write trace code to output.
+ @param psrc Source structure.
+ @param args Code for debug mode.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_tr_fct_trace_code(DKCT_SRC *psrc, char *args)
+{
+ int back = 0;
+ if(args) {
+ if(((psrc->dkcto).deb) && ((psrc->dkcto).deben)) {
+ fputs(args, psrc->fipo);
+ }
+ back = 1;
+ }
+ return back;
+}
+
+
+
+/** Pipe command output.
+ @param psrc Source structure.
+ @param args Command to execute.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_tr_fct_trace_pipe(DKCT_SRC *psrc, char *args)
+{
+ int back = 0;
+ FILE *fipo = NULL; /* File pointer to read from pipe. */
+ char buffer[4096]; /* Input buffer. */
+ size_t rdbytes; /* Number of bytes read from pipe. */
+ int wrbytes; /* Result from write operation. */
+
+ if(args) {
+ if(psrc->curdi) {
+#if DK3_ON_WINDOWS || (DK3_HAVE__POPEN && (!(DK3_HAVE_POPEN)))
+ fipo = _popen(args, dkct_tr_kw8[49]);
+ if(!(fipo)) {
+ /* ERROR: Failed to open pipe! */
+ dkct_to_log_3(psrc, 1, DK3_LL_ERROR, 15, 16, args);
+ }
+#else
+#if DK3_HAVE_POPEN
+ fipo = popen(args, dkct_tr_kw8[49]);
+ if(!(fipo)) {
+ /* ERROR: Failed to open pipe! */
+ dkct_to_log_3(psrc, 1, DK3_LL_ERROR, 15, 16, args);
+ }
+#else
+ /* ERROR: No popen() function available! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 17);
+#endif
+#endif
+ if(fipo) {
+ back = 1;
+ while(
+ (rdbytes = dk3sf_fread_app(buffer, 1, sizeof(buffer), fipo, psrc->app))
+ > 0
+ )
+ {
+ wrbytes = dk3sf_fwrite_app(buffer, 1, rdbytes, psrc->fipo, psrc->app);
+ if(wrbytes != 1) {
+ back = 0;
+ /* ERROR: Not all bytes written! */
+ dkct_to_log_1(psrc, 0, DK3_LL_ERROR, 18);
+ }
+ }
+#if DK3_ON_WINDOWS || (DK3_HAVE__POPEN && (!(DK3_HAVE_POPEN)))
+ _pclose(fipo);
+#else
+#if DK3_HAVE_POPEN
+ pclose(fipo);
+#endif
+#endif
+ }
+ } else {
+ /* ERROR: Not in the current directory! 104 */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 104);
+ }
+ }
+ return back;
+}
+
+
+
+/** Check whether a line contains the dollar exclam end at start
+ @param textline Line to test.
+ @return 1 for line contains pattern, 0 otherwise.
+*/
+static
+int
+dkct_tr_is_end_command(char const *textline)
+{
+ int back = 0;
+ char *p1; /* Text start in line. */
+ size_t ltext; /* Text length. */
+ size_t lpat; /* Pattern length. */
+ $? "+ dkct_tr_is_end_command \"%!8s\"", textline
+ if(textline) {
+ p1 = dk3str_c8_start(textline, NULL);
+ if(p1) {
+ ltext = dk3str_c8_len(p1);
+ lpat = dk3str_c8_len(dkct_tr_kw8[51]);
+ if(ltext >= lpat) {
+ if(dk3str_c8_ncmp(p1, dkct_tr_kw8[51], lpat) == 0) {
+ back = 1;
+ }
+ }
+ }
+ } $? "- dkct_tr_is_end_command %d", back
+ return back;
+}
+
+
+
+/** Write splint tag, replace special character.
+ @param psrc Source structure.
+ @param splt Splint tag text.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_tr_write_splint_tag(DKCT_SRC *psrc, char const *splt)
+{
+ int back = 1;
+ char const *p1;
+ $? "+ dkct_tr_write_splint_tag"
+ if ((psrc->dkcto).spls) { $? ". char %!8c\n", (psrc->dkcto).spls
+ p1 = splt;
+ while (*p1) {
+ if ('@' == *p1) {
+ if (EOF == fputc((psrc->dkcto).spls, psrc->fipo)) { back = 0; }
+ } else {
+ if (EOF == fputc(*p1, psrc->fipo)) { back = 0; }
+ }
+ p1++;
+ }
+ } else { $? ". no char"
+ } $? "- dkct_tr_write_splint_tag"
+ return back;
+}
+
+
+
+/** Generate string table from the following lines.
+ @param psrc Source structure.
+ @param args Command to execute.
+ @return 1 on success, 0 on error.
+*/
+static
+int dkct_tr_fct_string_table(DKCT_SRC *psrc, char *args)
+{
+ char fnb[DK3_MAX_PATH]; /* Buffer for file name. */
+ int back = 1;
+ char *pfile = NULL; /* String table file name. */
+ char *pmacro = NULL; /* Macro around strings. */
+ char *pprefix = NULL; /* Prefix for strings. */
+ char *pc; /* Pointer to current setting. */
+ char *pn; /* Pointer to next setting. */
+ char *pk; /* Setting key. */
+ char *pv; /* Setting value. */
+ FILE *fipo = NULL; /* String table output file. */
+ int cc = 1; /* Flag: Can continue. */
+ DKCT_LINE *lp; /* Current line to process. */
+ char lb[DKCT_LINE_SIZE]; /* Private copy of line. */
+ char *ptr; /* Current character to process. */
+ unsigned long lineno = 0UL; /* Line number of current line. */
+
+ if(args) {
+ pc = dk3str_c8_start(args, NULL);
+ while(pc) {
+ pk = pv = NULL;
+ pn = dk3str_c8_chr(pc, ',');
+ if(pn) { *(pn++) = '\0'; pn = dk3str_c8_start(pn, NULL); }
+ pk = dk3str_c8_start(pc, NULL);
+ if(pk) {
+ pv = dk3str_c8_chr(pk, '=');
+ if(pv) { *(pv++) = '\0'; pv = dk3str_c8_start(pv, NULL); }
+ switch(dk3str_c8_array_index(dkct_tr_string_table_args, pk, 0)) {
+ case 0: { /* file */
+ pfile = pv;
+ } break;
+ case 1: { /* macro */
+ pmacro = pv;
+ } break;
+ case 2: { /* prefix */
+ pprefix = pv;
+ } break;
+ default: {
+ /* ERROR: Unknown key! */
+ dkct_to_log_3(psrc, 1, DK3_LL_ERROR, 76, 77, pk);
+ } break;
+ }
+ } else {
+ /* ERROR: No key */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 33);
+ }
+ pc = pn;
+ }
+ }
+ if((pmacro) && (pprefix)) {
+ /* Warning: Either macro or prefix allowed! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 19);
+ }
+ if(pfile) {
+ pfile = dkct_tr_function_filename(psrc, pfile, fnb, sizeof(fnb));
+ }
+ if(pfile) {
+ fipo = dk3sf_c8_fopen_app(pfile, dkct_tr_kw8[50], psrc->app);
+ if(!(fipo)) {
+ /* ERROR: Failed to open file! */
+ dkct_to_log_3(psrc, 0, DK3_LL_ERROR, 20, 21, pfile);
+ }
+ }
+ if(psrc->cursr) {
+ do {
+ cc = 0;
+ lp = (DKCT_LINE *)dk3sto_it_next(psrc->cursr);
+ if(lp) {
+ if(lp->t) {
+ cc = 1;
+ if(dkct_tr_is_end_command(lp->t)) {
+ cc = 0;
+ } else {
+ if(dk3str_c8_len(lp->t) < sizeof(lb)) {
+ dk3str_c8_cpy(lb, lp->t);
+ /*
+ Write line to output file as is.
+ */
+ dk3str_c8_delnl(lb);
+ if(fipo) { fputs(lb, fipo); fputc('\n', fipo); }
+ /*
+ Generate source string.
+ */
+ if(*(lb) != '#') {
+ fprintf(psrc->fipo, dkct_tr_kw8[66], lineno++);
+ if(pmacro) {
+ fputs(pmacro, psrc->fipo);
+ fputs(dkct_tr_kw8[52], psrc->fipo);
+ }
+ if(pprefix) {
+ fputs(pprefix, psrc->fipo);
+ }
+ fputs(dkct_tr_kw8[55], psrc->fipo);
+ dk3app_squeeze_line(lb);
+ ptr = lb;
+ while(*ptr) {
+ switch(*ptr) {
+ case '\\': {
+ fputc('\\', psrc->fipo);
+ fputc('\\', psrc->fipo);
+ } break;
+ case '"': {
+ fputc('\\', psrc->fipo);
+ fputc('"', psrc->fipo);
+ } break;
+ case '\n': {
+ fputc('\\', psrc->fipo);
+ fputc('n', psrc->fipo);
+ } break;
+ case '\r': {
+ fputc('\\', psrc->fipo);
+ fputc('r', psrc->fipo);
+ } break;
+ case '\t': {
+ fputc('\\', psrc->fipo);
+ fputc('t', psrc->fipo);
+ } break;
+ default: {
+ fputc(*ptr, psrc->fipo);
+ } break;
+ }
+ ptr++;
+ }
+ fputs(dkct_tr_kw8[55], psrc->fipo);
+ if(pmacro) {
+ fputs(dkct_tr_kw8[53], psrc->fipo);
+ }
+ fputs(dkct_tr_kw8[54], psrc->fipo);
+ }
+ } else {
+ /* ERROR: Source line too large. */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 22);
+ }
+ }
+ }
+ }
+ } while(cc);
+ dkct_tr_write_splint_tag(psrc, dkct_tr_kw8[80]);
+ fputs(dkct_tr_kw8[65], psrc->fipo);
+ dkct_tr_write_splint_tag(psrc, dkct_tr_kw8[81]);
+ }
+ if(fipo) {
+#if DK3_CHAR_SIZE == 1
+ if(!dk3sf_fclose_fn_app(fipo, pfile, psrc->app)) {
+ back = 0;
+ }
+#else
+ if(!dk3sf_fclose_fn_app(fipo, NULL, psrc->app)) {
+ back = 0;
+ }
+#endif
+ fipo = NULL;
+ }
+ return back;
+}
+
+
+
+/** Generate text from the following lines.
+ @param psrc Source structure.
+ @param args Command to execute.
+ @return 1 on success, 0 on error.
+*/
+static
+int dkct_tr_fct_text(DKCT_SRC *psrc, char *args)
+{
+ int back = 1;
+ char fnb[DK3_MAX_PATH]; /* Buffer for output file name. */
+ char lb[DKCT_LINE_SIZE]; /* Line buffer. */
+ char *pfile = NULL; /* Output file name. */
+ char *pmacro = NULL; /* Macro name. */
+ char *pprefix = NULL; /* Prefix name. */
+ char *pc; /* Current arg to process. */
+ char *pn; /* Next arg to process. */
+ char *pv; /* Value pointer. */
+ char *ptr; /* Current character to process. */
+ FILE *fipo = NULL; /* Output file. */
+ DKCT_LINE *lp; /* Current line to process. */
+ int cc; /* Flag: Can continue. */
+ int indr; /* Index search result */
+ int preprocessor = 0; /* Flag: Allow preprocessor */
+ int fipopre = 0; /* Flag: Error already reported. */
+
+ pc = dk3str_c8_start(args, NULL);
+ while(pc) {
+ pn = dk3str_c8_chr(pc, ',');
+ if(pn) { *(pn++) = '\0'; pn = dk3str_c8_start(pn, NULL); }
+ $? " pc = \"%!8s\"", pc
+ pv = dk3str_c8_chr(pc, '=');
+ if(pv) {
+ *(pv++) = '\0'; pv = dk3str_c8_start(pv, NULL);
+ if(pv) {
+ switch(dk3str_c8_array_index(dkct_tr_string_table_args, pc, 0)) {
+ case 0: { pfile = pv; } break;
+ case 1: { pmacro = pv; } break;
+ case 2: { pprefix = pv; } break;
+ case 3: { preprocessor = 1; } break;
+ default: {
+ /* ERROR: Unknown key! */
+ dkct_to_log_3(psrc, 1, DK3_LL_ERROR, 76, 77, pc);
+ } break;
+ }
+ }
+ } else { $? ". no pv"
+ switch(indr = dk3str_c8_array_index(dkct_tr_string_table_args, pc, 0)) {
+ case 3: { $? ". 3 found"
+ preprocessor = 1;
+ } break;
+ default: { $? " write error %d", indr
+ /* ERROR: Not key=value pair */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 33);
+ } break;
+ }
+ }
+ pc = pn;
+ }
+ if(pfile) {
+ pfile = dkct_tr_function_filename(psrc, pfile, fnb, sizeof(fnb));
+ }
+ if(pfile) {
+ fipo = dk3sf_c8_fopen_app(pfile, dkct_tr_kw8[50], psrc->app);
+ if(!(fipo)) {
+ /* ERROR: Failed to open file! */
+ dkct_to_log_3(psrc, 0, DK3_LL_ERROR, 20, 21, pfile);
+ }
+ }
+ if(psrc->cursr) {
+ do {
+ cc = 0;
+ lp = (DKCT_LINE *)dk3sto_it_next(psrc->cursr);
+ if(lp) {
+ if(lp->t) {
+ cc = 1;
+ if(dkct_tr_is_end_command(lp->t)) {
+ cc = 0;
+ } else {
+ if(fipo) { if(lp->t) { fputs(lp->t, fipo); fputc('\n', fipo); } }
+ if(dk3str_c8_len(lp->t) < sizeof(lb)) {
+ dk3str_c8_cpy(lb, lp->t);
+ dk3str_c8_delnl(lb);
+ if (('#' == lb[0]) && (0 != preprocessor)) {
+ fputs(lb, psrc->fipo);
+ fputc('\n', psrc->fipo);
+ if ((NULL != fipo) && (0 == fipopre)) {
+ fipopre = 1;
+ dkct_to_log_1(psrc, 1, DK3_LL_WARNING, 114);
+ }
+ } else {
+ if(pmacro) {
+ fputs(pmacro, psrc->fipo);
+ fputs(dkct_tr_kw8[52], psrc->fipo);
+ } else {
+ if(pprefix) {
+ fputs(pprefix, psrc->fipo);
+ }
+ }
+ fputs(dkct_tr_kw8[55], psrc->fipo);
+#if VERSION_BEFORE_20120214
+ /*
+ No need to handle backslash escape sequences.
+ */
+ dk3app_squeeze_line(lb);
+#endif
+ ptr = lb;
+ if (('\\' == *ptr) && ('#' == ptr[1]) && (0 != preprocessor)) {
+ ptr++;
+ }
+ while(*ptr) {
+ switch(*ptr) {
+ case '\\': {
+ switch(ptr[1]) {
+ case '%': {
+ /* Just ignore the backslash, it is used to
+ escape the percent character.
+ */
+ } break;
+ default: {
+ fputc('\\', psrc->fipo);
+ fputc('\\', psrc->fipo);
+ } break;
+ }
+ } break;
+ case '"': {
+ fputc('\\', psrc->fipo);
+ fputc('"', psrc->fipo);
+ } break;
+ case '\n': {
+ fputc('\\', psrc->fipo);
+ fputc('n', psrc->fipo);
+ } break;
+ case '\r': {
+ fputc('\\', psrc->fipo);
+ fputc('r', psrc->fipo);
+ } break;
+ case '\t': {
+ fputc('\\', psrc->fipo);
+ fputc('t', psrc->fipo);
+ } break;
+ default: {
+ fputc(*ptr, psrc->fipo);
+ } break;
+ }
+ ptr++;
+ }
+ fputs(dkct_tr_kw8[55], psrc->fipo);
+ if(pmacro) {
+ fputs(dkct_tr_kw8[53], psrc->fipo);
+ }
+ fputs(dkct_tr_kw8[69], psrc->fipo);
+ }
+ } else {
+ /* ERROR: Source line too large. */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 22);
+ }
+ }
+ }
+ }
+ } while(cc);
+ dkct_tr_write_splint_tag(psrc, dkct_tr_kw8[80]);
+ fputs(dkct_tr_kw8[65], psrc->fipo);
+ dkct_tr_write_splint_tag(psrc, dkct_tr_kw8[81]);
+ }
+ if(fipo) {
+#if DK3_CHAR_SIZE == 1
+ if(!dk3sf_fclose_fn_app(fipo, pfile, psrc->app)) {
+ back = 0;
+ }
+#else
+ if(!dk3sf_fclose_fn_app(fipo, NULL, psrc->app)) {
+ back = 0;
+ }
+#endif
+ fipo = NULL;
+ }
+ return back;
+}
+
+
+
+/** Function table connecting functions to names.
+*/
+dkct_tr_fct_table_entry const dkct_tr_fct_table[] = {
+ { "trace-init", dkct_tr_fct_trace_init },
+ { "trace-end", dkct_tr_fct_trace_end },
+ { "trace-include", dkct_tr_fct_trace_include },
+ { "trace-code", dkct_tr_fct_trace_code },
+ { "!", dkct_tr_fct_trace_code },
+ { "pipe", dkct_tr_fct_trace_pipe },
+ { "|", dkct_tr_fct_trace_pipe },
+ { "string-table", dkct_tr_fct_string_table },
+ { "text", dkct_tr_fct_text },
+ { "trace-on", dkct_tr_fct_trace_on },
+ { "trace-off", dkct_tr_fct_trace_off },
+ { NULL, NULL }
+};
+
+
+
+/** Execute command stored in psrc->cmdb.
+ @param psrc Source structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_tr_exec_command(DKCT_SRC *psrc)
+{
+ int back = 0;
+ dkct_tr_fct *fctptr = NULL; /* Function to execute. */
+ dkct_tr_fct_table_entry const *pte; /* Current entry to inspect. */
+ char *cmdname; /* Command name. */
+ char *args; /* Command arguments. */
+
+ if(psrc->ucmd > 0) {
+ cmdname = dk3str_c8_start(psrc->cmdb, NULL);
+ if(cmdname) {
+ args = dk3str_c8_next(cmdname, NULL);
+ pte = dkct_tr_fct_table; fctptr = NULL;
+ while((pte->name) && (pte->fct) && (!(fctptr))) {
+ if(dk3str_c8_cmp(pte->name, cmdname) == 0) {
+ fctptr = pte->fct;
+ }
+ pte++;
+ }
+ if(fctptr) {
+ back = (*fctptr)(psrc, args);
+ fputc('\n', psrc->fipo);
+ if((psrc->dkcto).lnn) { psrc->shln = 1; }
+ } else {
+ /* ERROR: No such function! */
+ dkct_to_log_3(psrc, 1, DK3_LL_ERROR, 23, 24, cmdname);
+ }
+ } else {
+ /* ERROR: No function name! */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 25);
+ }
+ }
+ return back;
+}
+
+
+
+/** Create comment box border line (top or bottom).
+ @param psrc Source structure.
+ @param max Maximum line length.
+*/
+static
+void
+dkct_tr_comment_box_border(DKCT_SRC *psrc, size_t max)
+{
+ size_t lgt; /* Length of asterisk line so far. */
+
+ fputs(dkct_tr_kw8[42], psrc->fipo);
+ lgt = 0;
+ while(lgt++ < max) { fputc('*', psrc->fipo); }
+ fputs(dkct_tr_kw8[43], psrc->fipo);
+}
+
+
+
+#if 0
+static
+void
+dkct_tr_comment_box_empty_line(DKCT_SRC *psrc, size_t max)
+{
+ size_t lgt; /* Length of line so far. */
+
+ fputs(dkct_tr_kw8[40], psrc->fipo);
+ lgt = 0;
+ while(lgt++ < max) { fputc(' ', psrc->fipo); }
+ fputs(dkct_tr_kw8[41], psrc->fipo);
+}
+#endif
+
+
+
+/** Add text line to comment box.
+ @param psrc Source structure.
+ @param max Maximum line length.
+ @param inl Input line to add.
+*/
+static
+void
+dkct_tr_comment_box_text_line(DKCT_SRC *psrc, size_t max, char const *inl)
+{
+ size_t lgt; /* Length of line so far. */
+
+ fputs(dkct_tr_kw8[40], psrc->fipo);
+ fputs(inl, psrc->fipo);
+ lgt = dk3str_c8_len(inl);
+ while(lgt++ < max) { fputc(' ', psrc->fipo); }
+ fputs(dkct_tr_kw8[41], psrc->fipo);
+}
+
+
+
+/** Add comment box to output.
+ @param psrc Source structure.
+*/
+static
+void
+dkct_tr_print_comment_box(DKCT_SRC *psrc)
+{
+ char inl[DKCT_LINE_SIZE]; /* Current input line to process. */
+ size_t max; /* Box width. */
+ $? "+ dkct_tr_print_comment_box"
+ max = psrc->cbmx;
+ if((size_t)((psrc->dkcto).bw) > (max + 10)) {
+ max = (size_t)((psrc->dkcto).bw) - 10;
+ }
+ fflush(psrc->cbfip);
+ rewind(psrc->cbfip);
+ dkct_tr_comment_box_border(psrc, max);
+ /* dkct_tr_comment_box_empty_line(psrc, max); */
+ while(fgets(inl, sizeof(inl), psrc->cbfip)) {
+ dk3str_c8_delnl(inl);
+ dkct_tr_comment_box_text_line(psrc, max, inl);
+ }
+ /* dkct_tr_comment_box_empty_line(psrc, max); */
+ dkct_tr_comment_box_border(psrc, max);
+ $? "- dkct_tr_print_comment_box"
+}
+
+
+
+/** Process one character in psrc->cchr.
+ @param psrc Source structure.
+*/
+static
+int
+dkct_tr_process_character(DKCT_SRC *psrc)
+{
+ int back = 0;
+ int input; /* State machine input. */
+ int action; /* State machine output. */
+ $? "+ dkct_tr_process_character"
+ input = psrc->cchr;
+ if(psrc->cchr == '$') { input = TRACE_CONTROL; }
+ action = dkct_tr_state_machine_transition(&(psrc->st), input);
+ switch(action) {
+ case DKCT_O_NOOP: { /* Nothing to do. */
+ back = 1;
+ } break;
+ case DKCT_O_PRINT: { /* Print current character. */
+ fputc(psrc->cchr, psrc->fipo);
+ back = 1;
+ } break;
+ case DKCT_O_DOLLAR_AND_CHAR: {
+ fputc('$', psrc->fipo);
+ fputc(psrc->cchr, psrc->fipo);
+ back = 1;
+ } break;
+ case DKCT_O_SLASH_AND_CHAR: {
+ fputc('/', psrc->fipo);
+ fputc(psrc->cchr, psrc->fipo);
+ back = 1;
+ } break;
+ case DKCT_O_RESET_BUFFER: {
+ dkct_tr_reset_buffer(psrc);
+ back = 1;
+ } break;
+ case DKCT_O_ADD_BUFFER: {
+ if(psrc->ucmd < psrc->szcmd) {
+ (psrc->cmdb)[psrc->ucmd] = psrc->cchr;
+ psrc->ucmd += 1;
+ back = 1;
+ } else {
+ /* ERROR: Buffer full */
+ dkct_to_log_1(psrc, 1, DK3_LL_ERROR, 98);
+ }
+ } break;
+ case DKCT_O_TRACE_OUTPUT: {
+ if(psrc->ucmd < psrc->szcmd) {
+ (psrc->cmdb)[psrc->ucmd] = '\0';
+ } else {
+ (psrc->cmdb)[psrc->szcmd - 1] = '\0';
+ }
+ dkct_tr_trace_output(psrc);
+ dkct_tr_reset_buffer(psrc);
+ back = 1;
+ if((psrc->dkcto).lnn) { psrc->shln = 1; }
+ } break;
+ case DKCT_O_EXEC_CMD: {
+ if(psrc->ucmd < psrc->szcmd) {
+ (psrc->cmdb)[psrc->ucmd] = '\0';
+ } else {
+ (psrc->cmdb)[psrc->szcmd - 1] = '\0';
+ }
+ dkct_tr_exec_command(psrc);
+ dkct_tr_reset_buffer(psrc);
+ back = 1;
+ if((psrc->dkcto).lnn) { psrc->shln = 1; }
+ } break;
+ case DKCT_O_START_CPP_COMMENT: {
+ switch(psrc->sufi) {
+ case 1: case 3: case 4: {
+ fputs(dkct_tr_kw8[26], psrc->fipo);
+ } break;
+ default: {
+ fputs(dkct_tr_kw8[2], psrc->fipo);
+ } break;
+ }
+ back = 1;
+ } break;
+ case DKCT_O_END_CPP_COMMENT: {
+ switch(psrc->sufi) {
+ case 1: case 3: case 4: {
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+ } break;
+ default: {
+ fputs(dkct_tr_kw8[27], psrc->fipo);
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+ } break;
+ }
+ back = 1;
+ } break;
+ case DKCT_O_START_BOX: { $? ". open box file"
+ if(psrc->cbfip) {
+ fclose(psrc->cbfip); psrc->cbfip = NULL;
+ }
+ psrc->cbfip = dk3sf_c8_fopen_app(psrc->cbfn, dkct_tr_kw8[39], psrc->app);
+ psrc->cbcp = 0; psrc->cbmx = 0;
+ if(psrc->cbfip) {
+ back = 1;
+ } else { $? "! failed to open box file"
+ /* ERROR: Failed to open file */
+ dkct_to_log_3(psrc, 0, DK3_LL_ERROR, 20, 21, psrc->cbfn);
+ }
+ } break;
+ case DKCT_O_ADD_BOX: { $? ". add character"
+ if(psrc->cbfip) {
+ if(psrc->cchr == '\t') {
+ fputc(' ', psrc->cbfip);
+ psrc->cbcp += 1;
+ while((psrc->cbcp) % 8) {
+ fputc(' ', psrc->cbfip);
+ psrc->cbcp += 1;
+ }
+ } else {
+ fputc(psrc->cchr, psrc->cbfip);
+ psrc->cbcp += 1;
+ }
+ if(psrc->cbcp > psrc->cbmx) { psrc->cbmx = psrc->cbcp; }
+ back = 1;
+ }
+ } break;
+ case DKCT_O_ADD_BOX_NL: { $? ". add newline"
+ if(psrc->cbfip) {
+ fputc('\n', psrc->cbfip);
+ psrc->cbcp = 0;
+ back = 1;
+ }
+ } break;
+ case DKCT_O_ADD_BOX_DOLLAR_CHAR: { $? ". add dollar and char"
+ if(psrc->cbfip) {
+ fputc('$', psrc->cbfip);
+ psrc->cbcp += 1;
+ if(psrc->cchr == '\t') {
+ fputc(' ', psrc->cbfip);
+ psrc->cbcp += 1;
+ while((psrc->cbcp) % 8) {
+ fputc(' ', psrc->cbfip);
+ psrc->cbcp += 1;
+ }
+ } else {
+ fputc(psrc->cchr, psrc->cbfip);
+ psrc->cbcp += 1;
+ }
+ if(psrc->cbcp > psrc->cbmx) { psrc->cbmx = psrc->cbcp; }
+ back = 1;
+ }
+ } break;
+ case DKCT_O_END_BOX: { $? ". end box"
+ if(psrc->cbfip) {
+ fputc('\n', psrc->cbfip);
+ dkct_tr_print_comment_box(psrc);
+ fclose(psrc->cbfip); psrc->cbfip = NULL;
+ back = 1;
+ }
+ if((psrc->dkcto).lnn) { psrc->shln = 1; }
+ } break;
+ } $? "- dkct_tr_process_character %d", back
+ return back;
+}
+
+
+
+/** Process all source lines from a storage.
+ @param psrc Source structure.
+ @param iterator Storage iterator.
+*/
+static
+int
+dkct_tr_module_lines(DKCT_SRC *psrc, dk3_sto_it_t *iterator)
+{
+ int back = 1;
+ DKCT_LINE *lp; /* Current line to process. */
+ char const *ptr; /* Current character to process. */
+ $? "+ dkct_tr_module_lines"
+ if(iterator) {
+ psrc->cursr = iterator;
+ dk3sto_it_reset(iterator);
+ while((lp = (DKCT_LINE *)dk3sto_it_next(iterator)) != NULL) {
+ if(lp->t) { $? ". line=\"%!8s\"", lp->t
+ psrc->lineno = lp->l;
+ if(psrc->app) { dk3app_set_source_line(psrc->app, lp->l); }
+ if(psrc->shln) {
+ psrc->shln = 0;
+ dkct_tr_show_source_line(psrc, 1);
+ }
+ ptr = lp->t;
+ while(*ptr) {
+ psrc->cchr = *(ptr++);
+ if(!dkct_tr_process_character(psrc)) { back = 0; }
+ }
+ psrc->cchr = '\n';
+ if(!dkct_tr_process_character(psrc)) { back = 0; }
+ }
+ }
+ psrc->cursr = NULL;
+ } $? "- dkct_tr_module_lines %d", back
+ return back;
+}
+
+
+
+/** Attempt to write one output file.
+ @param psrc Source structure.
+ @param sfn Source file name.
+ @param osf Output file name suffix.
+ @param f_hdr Flag: This is the header file.
+*/
+static
+int
+dkct_tr_attempt_to_write_file(
+ DKCT_SRC *psrc, dkChar const *sfn, dkChar const *osf, int f_hdr
+)
+{
+ int back = 1;
+ dkChar ofn[DK3_MAX_PATH]; /* Output file name. */
+ dkChar *sofn = NULL; /* Short output name. */
+ dkChar *ps = NULL; /* Output suffix. */
+ int f_must_run = 1; /* Flag: Must run. */
+ int first_state_machine = 1; /* Flag: First stm. */
+ DKCT_STM *pstm; /* State machine. */
+ $? "+ dkct_tr_attempt_to_write_file %d \"%!ds\"", psrc->sufi, osf
+ if(dk3str_len(sfn) < DK3_SIZEOF(ofn,dkChar)) {
+ dk3str_cpy_not_overlapped(ofn, sfn);
+ ps = dk3str_get_suffix(ofn);
+ if(ps) { *ps = dkT('\0'); }
+ if((dk3str_len(ofn) + dk3str_len(osf)) < DK3_SIZEOF(ofn,dkChar)) {
+ dk3str_cat(ofn, osf); $? ". output file name \"%!ds\"", ofn
+ if((psrc->dkcto).mak) { $? ". make mode"
+ f_must_run = dk3sf_must_rebuild(ofn, sfn);
+ }
+ sofn = dk3str_rchr(ofn, DK3_CHAR_SEP);
+ if(sofn) {
+ sofn++;
+ } else {
+ sofn = ofn;
+ }
+ dk3app_set_source_line(psrc->app, 0UL);
+ if(f_must_run) { $? ". must run"
+ /* Progress: Writing output file. */
+ dk3app_log_3(psrc->app, DK3_LL_PROGRESS, psrc->msg, 108, 109, sofn);
+ psrc->fipo = dk3sf_fopen_app(ofn, dk3app_not_localized(24), psrc->app);
+ if(psrc->fipo) { $? ". file opened"
+ dkct_tr_write_file_start(psrc, ofn, sfn, f_hdr);
+ if((psrc->dkcto).lnn) { psrc->shln = 1; }
+ if(f_hdr) {
+ /*
+ Protect against multiple inclusion (file start)
+ */
+ fputs(dkct_tr_kw8[6], psrc->fipo);
+ dkct_tr_filename_to_upper(psrc, ofn);
+ fputs(dkct_tr_kw8[7], psrc->fipo);
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+ fputs(dkct_tr_kw8[8], psrc->fipo);
+ dkct_tr_filename_to_upper(psrc, ofn);
+ fputs(dkct_tr_kw8[7], psrc->fipo);
+ fputs(dkct_tr_kw8[9], psrc->fipo);
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+ /*
+ Header start and class start.
+ */
+
+ if((psrc->dkcto).lnn) { psrc->shln = 1; }
+ if(!dkct_tr_module_lines(psrc, psrc->hsi)) { back = 0; }
+ if((psrc->dkcto).lnn) { psrc->shln = 1; }
+ if(!dkct_tr_module_lines(psrc, psrc->clsi)) { back = 0; }
+ /*
+ wxWindows GUI output.
+ */
+ if(psrc->sufi == 4) {
+ dkct_gui_class_variables(psrc);
+ }
+ /*
+ Class end and header end.
+ */
+ if((psrc->dkcto).lnn) { psrc->shln = 1; }
+ if(!dkct_tr_module_lines(psrc, psrc->clei)) { back = 0; }
+ if((psrc->dkcto).lnn) { psrc->shln = 1; }
+ if(!dkct_tr_module_lines(psrc, psrc->hei)) { back = 0; }
+ /*
+ State machine constants, if any.
+ */
+ dk3sto_it_reset(psrc->i_stm);
+ while((pstm = (DKCT_STM *)dk3sto_it_next(psrc->i_stm)) != NULL) {
+ if(pstm->wrh) {
+ psrc->lineno = pstm->lineno;
+ dk3app_set_source_line(psrc->app, pstm->lineno);
+ dkct_au_write_entries(psrc, pstm);
+ dkct_au_write_prototypes(psrc, pstm);
+ }
+ }
+ /*
+ Protect against multiple inclusion (file end)
+ */
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+ fputs(dkct_tr_kw8[10], psrc->fipo);
+ fputs(dkct_tr_kw8[0], psrc->fipo);
+ } else {
+ /*
+ State machine constants and functions if any.
+ */
+ dk3sto_it_reset(psrc->i_stm);
+ while((pstm = (DKCT_STM *)dk3sto_it_next(psrc->i_stm)) != NULL) {
+ if(first_state_machine) {
+ first_state_machine = 0;
+ if(((psrc->dkcto).deb) && ((psrc->dkcto).deben)) {
+ if((psrc->dkcto).deb == 2) {
+ fputs(dkct_tr_kw8[68], psrc->fipo);
+ }
+ fputs(dkct_tr_kw8[44], psrc->fipo);
+ fputs(dkct_tr_kw8[79], psrc->fipo);
+ (psrc->dkcto).tip = 1;
+ }
+ }
+ psrc->lineno = pstm->lineno;
+ dk3app_set_source_line(psrc->app, pstm->lineno);
+ if(!(pstm->wrh)) {
+ dkct_au_write_entries(psrc, pstm);
+ dkct_au_write_functions(psrc, pstm, 1);
+ } else {
+ dkct_au_write_functions(psrc, pstm, 0);
+ }
+ }
+ /*
+ Start of module.
+ */
+ psrc->st = 0;
+ if((psrc->dkcto).lnn) { psrc->shln = 1; }
+ if(!dkct_tr_module_lines(psrc, psrc->msi)) { back = 0; }
+ if((psrc->dkcto).lnn) { psrc->shln = 1; }
+ if(!dkct_tr_module_lines(psrc, psrc->cosi)) { back = 0; }
+ /*
+ GUI setup.
+ */
+ if(psrc->sufi == 4) {
+ dkct_gui_write_constructor(psrc);
+ }
+ /*
+ End of module.
+ */
+ if((psrc->dkcto).lnn) { psrc->shln = 1; }
+ if(!dkct_tr_module_lines(psrc, psrc->coei)) { back = 0; }
+ if((psrc->dkcto).lnn) { psrc->shln = 1; }
+ if(!dkct_tr_module_lines(psrc, psrc->mei)) { back = 0; }
+ }
+ if(!dk3sf_fclose_fn_app(psrc->fipo, ofn, psrc->app)) {
+ back = 0;
+ }
+ } else { $? "! failed to open file"
+ /* ERROR: Failed to open file! */
+ dkct_to_log_dk_3(psrc, 0, DK3_LL_ERROR, 20, 21, ofn);
+ back = 0;
+ }
+ } else {
+ /* Progress: Output file is up to date. */
+ dk3app_log_3(psrc->app, DK3_LL_PROGRESS, psrc->msg, 110, 111, sofn);
+ }
+ } else { $? "! output file name too long"
+ /* ERROR: File name too long! */
+ dkct_to_log_dk_3(psrc, 1, DK3_LL_ERROR, 26, 27, ofn);
+ back = 0;
+ }
+ } else { $? "! input file name too long"
+ /* File name too long! */
+ dkct_to_log_dk_3(psrc, 1, DK3_LL_ERROR, 26, 27, sfn);
+ back = 0;
+ } $? "- dkct_tr_attempt_to_write_file %d", back
+ return back;
+}
+
+
+
+int
+dkct_tr_write(DKCT_SRC *psrc, dkChar const *fn, int sufi)
+{
+ int back = 1;
+ char fnb[128]; /* File name for temporary box file. */
+ $? "+ dkct_tr_write %d", sufi
+ psrc->cbfip = NULL;
+ psrc->sufi = sufi;
+ psrc->shln = 0;
+ sprintf(fnb, dkct_tr_kw8[38], (unsigned long)dk3sf_getpid());
+ psrc->cbfn = fnb;
+ psrc->lineno = 1UL;
+ dk3app_set_source_line(psrc->app, 1UL);
+ switch(sufi) {
+ case 4: { /* .h .cpp */
+ if(dkct_tr_have_header_data(psrc)) {
+ if(!dkct_tr_attempt_to_write_file(psrc,fn,dkct_tr_out_suffixes[0],1))
+ {
+ back = 0;
+ }
+ }
+ if(dkct_tr_have_module_data(psrc)) {
+ if(!dkct_tr_attempt_to_write_file(psrc,fn,dkct_tr_out_suffixes[2],0))
+ {
+ back = 0;
+ }
+ }
+ } break;
+ case 3: { /* .java */
+ if(dkct_tr_have_module_data(psrc)) {
+ if(!dkct_tr_attempt_to_write_file(psrc,fn,dkct_tr_out_suffixes[4],0))
+ {
+ back = 0;
+ }
+ }
+ } break;
+ case 2: { /* .h .m */
+ if(dkct_tr_have_header_data(psrc)) {
+ if(!dkct_tr_attempt_to_write_file(psrc,fn,dkct_tr_out_suffixes[0],1))
+ {
+ back = 0;
+ }
+ }
+ if(dkct_tr_have_module_data(psrc)) {
+ if(!dkct_tr_attempt_to_write_file(psrc,fn,dkct_tr_out_suffixes[3],0))
+ {
+ back = 0;
+ }
+ }
+ } break;
+ case 1: { /* .h .cpp */
+ if(dkct_tr_have_header_data(psrc)) {
+ if(!dkct_tr_attempt_to_write_file(psrc,fn,dkct_tr_out_suffixes[0],1))
+ {
+ back = 0;
+ }
+ }
+ if(dkct_tr_have_module_data(psrc)) {
+ if(!dkct_tr_attempt_to_write_file(psrc,fn,dkct_tr_out_suffixes[2],0))
+ {
+ back = 0;
+ }
+ }
+ } break;
+ case 0: { /* .h .c */
+ if(dkct_tr_have_header_data(psrc)) {
+ if(!dkct_tr_attempt_to_write_file(psrc,fn,dkct_tr_out_suffixes[0],1))
+ {
+ back = 0;
+ }
+ }
+ if(dkct_tr_have_module_data(psrc)) {
+ if(!dkct_tr_attempt_to_write_file(psrc,fn,dkct_tr_out_suffixes[1],0))
+ {
+ back = 0;
+ }
+ }
+ } break;
+ }
+ if(psrc->cbfip) {
+ fclose(psrc->cbfip); psrc->cbfip = NULL;
+ }
+ dk3sf_c8_remove_file_app(psrc->cbfn, NULL);
+ psrc->cbfn = NULL;
+ $? "- dkct_tr_write %d", back
+ return back;
+}
+
+
+
+/** Pointer to a constant string.
+*/
+typedef char const *DKCT_TR_CONST_CHAR_PTR;
+
+char const *
+dkct_tr_get_kw8(size_t sz)
+{
+ char const *back = NULL;
+ if(sz < (sizeof(dkct_tr_kw8)/sizeof(DKCT_TR_CONST_CHAR_PTR))) {
+ back = dkct_tr_kw8[sz];
+ }
+ return back;
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dkct-tr.h b/support/dktools/dkct-tr.h
new file mode 100644
index 0000000000..ab2311ccb9
--- /dev/null
+++ b/support/dktools/dkct-tr.h
@@ -0,0 +1,368 @@
+
+/** @file dkct-tr.h Header file for the dkct-tr module.
+*/
+
+#ifndef DKCT_TR_H_INCLUDED
+#define DKCT_TR_H_INCLUDED 1
+
+
+#if DK3_USE_WX
+#include "DkWxCommunicator.h"
+#endif
+
+
+/** State machine entry (input, output state).
+*/
+typedef struct {
+ char const *name; /**< Name. */
+ char const *comment; /**< Comment text. */
+ unsigned long lineno; /**< Line number of definition. */
+ int value; /**< Numeric value. */
+ char flag; /**< Flag: Numeric value set. */
+} DKCT_STM_ENTRY;
+
+
+
+/** Transition rule.
+*/
+typedef struct {
+ DKCT_STM_ENTRY *state; /**< Current (old) state. */
+ DKCT_STM_ENTRY *input; /**< Input. */
+ DKCT_STM_ENTRY *newstate; /**< New state. */
+ DKCT_STM_ENTRY *output; /**< Output. */
+ unsigned long lineno; /**< Line number of definition. */
+} DKCT_STM_RULE;
+
+
+
+/** State machine description.
+*/
+typedef struct {
+ dk3_sto_t *s_states; /**< Storage for states. */
+ dk3_sto_it_t *i_states; /**< Iterator for states. */
+ dk3_sto_t *s_inputs; /**< Storage for inputs. */
+ dk3_sto_it_t *i_inputs; /**< Iterator for inputs. */
+ dk3_sto_t *s_outputs; /**< Storage for outputs. */
+ dk3_sto_it_t *i_outputs; /**< Iterator for outputs. */
+ dk3_sto_t *s_exact; /**< Storage for exact rules. */
+ dk3_sto_it_t *i_exact; /**< Iterator for exact rules. */
+ dk3_sto_t *s_wildcard; /**< Storage for one-wildcard rules. */
+ dk3_sto_it_t *i_wildcard; /**< Iterator for one-wildcard rules. */
+ char const *name; /**< State machine name. */
+ DKCT_STM_ENTRY *rs; /**< Reset state. */
+ DKCT_STM_ENTRY *ds; /**< Default state. */
+ DKCT_STM_ENTRY *dout; /**< Default output. */
+ unsigned long stmno; /**< State machine number. */
+ unsigned long lineno; /**< Line number of start. */
+ unsigned long lngr; /**< Line number of general rule. */
+ int wrh; /**< Flag: Write definitions to header. */
+ int section; /**< Current section. */
+} DKCT_STM;
+
+
+
+/** One input source line.
+*/
+typedef struct {
+ char const *t; /**< Text. */
+ unsigned long l; /**< Line number. */
+} DKCT_LINE;
+
+
+
+/** One source file read in.
+*/
+typedef struct {
+ DKCT_OPTION_SET dkcto; /**< Conversion options. */
+ dk3_app_t *app; /**< Application structure. */
+ dkChar const * const *msg; /**< Localized message texts. */
+ dkChar const *ffn; /**< Full source file name. */
+ dk3_sto_t *hss; /**< Header start storage. */
+ dk3_sto_it_t *hsi; /**< Header start iterator. */
+ dk3_sto_t *hes; /**< Header end storage. */
+ dk3_sto_it_t *hei; /**< Header end iterator. */
+ dk3_sto_t *clss; /**< Class start storage. */
+ dk3_sto_it_t *clsi; /**< Class start iterator. */
+ dk3_sto_t *cles; /**< Class end storage. */
+ dk3_sto_it_t *clei; /**< Class end iterator. */
+ dk3_sto_t *mss; /**< Module start storage. */
+ dk3_sto_it_t *msi; /**< Module start iterator. */
+ dk3_sto_t *mes; /**< Module end iterator. */
+ dk3_sto_it_t *mei; /**< Module end iterator. */
+ dk3_sto_t *coss; /**< Constructor start storage. */
+ dk3_sto_it_t *cosi; /**< Constructor start iterator. */
+ dk3_sto_t *coes; /**< Constructor end iterator. */
+ dk3_sto_it_t *coei; /**< Constructor end iterator. */
+ dk3_sto_t *s_stm; /**< Storage for state machines. */
+ dk3_sto_it_t *i_stm; /**< Iterator for state machines. */
+ dk3_sto_it_t *cursr; /**< Current source. */
+ DKCT_STM *cstm; /**< Current state machine. */
+ void *gui; /**< GUI description. */
+ FILE *fipo; /**< Output file. */
+ FILE *cbfip; /**< Comment box file. */
+ char const *sfn; /**< Short file name. */
+ char const *crn; /**< Copyright name. */
+ char const *cry; /**< Copyright year. */
+ char *cmdb; /**< Command buffer. */
+ char *cbfn; /**< Comment box file name. */
+ unsigned long lineno; /**< Current line number. */
+ size_t szcmd; /**< Size of command buffer. */
+ size_t ucmd; /**< Used characters in command buffer. */
+ size_t cbcp; /**< Comment box current position. */
+ size_t cbmx; /**< Comment box max line length. */
+ int lict; /**< License type. */
+ int type; /**< Source type. */
+ int ec; /**< Error code. */
+ int st; /**< Current state. */
+ int sufi; /**< Source suffix index. */
+ int doxyh; /**< Doxygen comment found in header. */
+ int doxym; /**< Doxygen comment found in module. */
+ int shln; /**< Flag: Show line number. */
+ int curdi; /**< Flag: Processing the current directory. */
+ int hdr; /**< Flag: Currently processing header. */
+ char cchr; /**< Current character to process. */
+#if DK3_USE_WX
+ DkWxCommunicator *pComm; /**< Communicator for threads. */
+#endif
+} DKCT_SRC;
+
+
+/** @defgroup dkctsections Source file sections.
+*/
+/**@{*/
+
+/** Start of module.
+*/
+#define DKCT_SECTION_MODULE_START 0
+
+/** End of module
+*/
+#define DKCT_SECTION_MODULE_END 1
+
+/** Start of constructor.
+*/
+#define DKCT_SECTION_CONSTRUCTOR_START 2
+
+/** End of constructor.
+*/
+#define DKCT_SECTION_CONSTRUCTOR_END 3
+
+/** Start of header.
+*/
+#define DKCT_SECTION_HEADER_START 4
+
+/** End of header.
+*/
+#define DKCT_SECTION_HEADER_END 5
+
+/** Start of class.
+*/
+#define DKCT_SECTION_CLASS_START 6
+
+/** End of class.
+*/
+#define DKCT_SECTION_CLASS_END 7
+
+/** Options.
+*/
+#define DKCT_SECTION_OPTIONS 8
+
+/** wxWidgets GUI.
+*/
+#define DKCT_SECTION_GUI 9
+
+/** State machine description.
+*/
+#define DKCT_SECTION_STATE_MACHINE 10
+
+/**@}*/
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Destroy line structure.
+ @param p Structure to destroy.
+*/
+void
+dkct_tr_line_delete(DKCT_LINE *p);
+
+/** Create new source line.
+ @param t Text.
+ @param l Line number.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new line structure on success, NULL on error.
+*/
+DKCT_LINE *
+dkct_tr_line_new(char const *t, unsigned long l, dk3_app_t *app);
+
+/** Destroy dkct-tr source structure.
+ @param p Structure to destroy.
+*/
+void
+dkct_tr_delete(DKCT_SRC *p);
+
+/** Create new dkct-tr source structure.
+ @param o Option set.
+ @param fn Short file name.
+ @param ai File suffix array index.
+ @param app Application structure for diagnostics, may be NULL.
+ @param ffn Full source file name.
+ @return Pointer to new structure on success, NULL on error.
+*/
+DKCT_SRC *
+dkct_tr_new(
+ DKCT_OPTION_SET *o,
+ char const *fn,
+ int ai,
+ dk3_app_t *app,
+ dkChar const *ffn
+);
+
+/** Read source file.
+ @param psrc Source file structure to store data.
+ @param fn Source file name.
+ @param sufi File name suffix index.
+ @return 1 on success, 0 on error.
+*/
+int
+dkct_tr_read(DKCT_SRC *psrc, dkChar const *fn, int sufi);
+
+/** Check setup (especially GUI).
+ @param psrc Source file structure to store data.
+ @param fn Source file name.
+ @param sufi File name suffix index.
+ @return 1 on success, 0 on error.
+*/
+int
+dkct_tr_check(DKCT_SRC *psrc, dkChar const *fn, int sufi);
+
+/** Write output.
+ @param psrc Source file structure to store data.
+ @param fn Source file name.
+ @param sufi File name suffix index.
+ @return 1 on success, 0 on error.
+*/
+int
+dkct_tr_write(DKCT_SRC *psrc, dkChar const *fn, int sufi);
+
+/** Create new state machine description.
+ @param lineno Source line number.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new structure on success, NULL on error.
+*/
+DKCT_STM *
+dkct_au_stm_new(unsigned long lineno, dk3_app_t *app);
+
+/** Destroy state machine description.
+ @param p Structure to destroy.
+*/
+void
+dkct_au_stm_delete(DKCT_STM *p);
+
+/** Add one text line to state machine description.
+ @param stm State machine description.
+ @param psrc Source structure.
+ @param line Text to add.
+ @param lineno Line number.
+ @return 1 on success, 0 on error.
+*/
+int
+dkct_au_add_line(
+ DKCT_STM *stm, DKCT_SRC *psrc, char *line, unsigned long lineno
+);
+
+/** Check state machine consistency.
+ @param psrc Source structure.
+ @param stm State machine to check.
+ @return 1 on success, 0 on error.
+*/
+int
+dkct_au_stm_check(DKCT_SRC *psrc, DKCT_STM *stm);
+
+/** Write "#line ..." information to output.
+ @param psrc Source structure.
+ @param newlines Number of newlines to use in counting.
+*/
+void
+dkct_tr_show_source_line(DKCT_SRC *psrc, size_t newlines);
+
+/** Write state, input and output constants.
+ @param psrc Source structure.
+ @param stm State machine.
+*/
+void
+dkct_au_write_entries(DKCT_SRC *psrc, DKCT_STM *stm);
+
+/** Write function prototypes for state machine.
+ @param psrc Source structure.
+ @param stm State machine.
+*/
+void
+dkct_au_write_prototypes(DKCT_SRC *psrc, DKCT_STM *stm);
+
+/** Write state machine functions.
+ @param psrc Source structure.
+ @param stm State machine.
+ @param f_static Flag: Use static keyword.
+*/
+void
+dkct_au_write_functions(DKCT_SRC *psrc, DKCT_STM *stm, int f_static);
+
+/** Get one of the dkct-tr keywords.
+ @param sz Keyword index.
+ @return Pointer to keyword or NULL.
+*/
+char const *
+dkct_tr_get_kw8(size_t sz);
+
+/** Write string containing file name and line number to output.
+ @param psrc Source structure.
+*/
+void
+dkct_tr_show_filename_and_lineno(DKCT_SRC *psrc);
+
+/** Log one message.
+ @param psrc Source structure.
+ @param scope Scope (0=GUI only, 1=app+GUI).
+ @param ll Log level.
+ @param i1 Index of message text in \a psrc->msg.
+*/
+void
+dkct_to_log_1(DKCT_SRC *psrc, int scope, int ll, size_t i1);
+
+/** Log one message.
+ @param psrc Source structure.
+ @param scope Scope (0=GUI only, 1=app+GUI).
+ @param ll Log level.
+ @param i1 Index of message text in \a psrc->msg.
+ @param i2 Index of second fixed text in \a psrc->msg.
+ @param text Variable text part.
+*/
+void
+dkct_to_log_3(
+ DKCT_SRC *psrc, int scope, int ll, size_t i1, size_t i2, char const *text
+);
+
+/** Log one message.
+ @param psrc Source structure.
+ @param scope Scope (0=GUI only, 1=app+GUI).
+ @param ll Log level.
+ @param i1 Index of message text in \a psrc->msg.
+ @param i2 Index of second fixed text in \a psrc->msg.
+ @param text Variable text part.
+*/
+void
+dkct_to_log_dk_3(
+ DKCT_SRC *psrc, int scope, int ll, size_t i1, size_t i2, dkChar const *text
+);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/support/dktools/dkct.c b/support/dktools/dkct.c
new file mode 100644
index 0000000000..1c4a8944e3
--- /dev/null
+++ b/support/dktools/dkct.c
@@ -0,0 +1,921 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dkct.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#line 10 "dkct.ctr"
+
+/** @file dkct.c Dirk Krause's C/C++ tool.
+*/
+
+
+#if DK3_USE_WX
+#include "dkwxtrace.h"
+#else
+#include "dkct.h"
+#endif
+
+
+
+#line 22 "dkct.ctr"
+
+
+
+/** Application group name.
+*/
+static dkChar const dkct_group_name[] = { dkT("dktools") };
+
+
+
+/** Version number string.
+*/
+static dkChar const dkct_version[] = {
+dkT("dkct ") DKT_VERSION_DK
+};
+
+
+
+/** License conditions shown for dkct --license.
+*/
+static dkChar const * const dkct_license[] = {
+dkT(""),
+dkT("Copyright (c) 2011-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms,"),
+dkT("with or without modification, are permitted provided"),
+dkT("that the following conditions are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above"),
+dkT(" copyright notice, this list of conditions and the"),
+dkT(" following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above"),
+dkT(" copyright notice, this list of conditions and the following"),
+dkT(" disclaimer in the documentation and/or other materials"),
+dkT(" provided with the distribution."),
+dkT("* Neither the name of the copyright holder(s) nor the names of"),
+dkT(" contributors may be used to endorse or promote"),
+dkT(" products derived from this software without specific"),
+dkT(" prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND"),
+dkT("CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,"),
+dkT("INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF"),
+dkT("MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE"),
+dkT("DISCLAIMED."),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE"),
+dkT("LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,"),
+dkT("EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT"),
+dkT("LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;"),
+dkT("LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)"),
+dkT("HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN"),
+dkT("CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE"),
+dkT("OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS"),
+dkT("SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH"),
+dkT("DAMAGE."),
+dkT(""),
+NULL
+
+
+#line 80 "dkct.ctr"
+};
+
+
+
+/** Options for the dkct program.
+*/
+static dk3_option_t const dkct_options[] = {
+ { dkT('R'), dkT("reset"), 0 },
+ { dkT('d'), dkT("debug"), 0 },
+ { dkT('s'), dkT("debug-stdout"), 0 },
+ { dkT('l'), dkT("line-numbers"), 0 },
+ { dkT('m'), dkT("make"), 0 },
+ { dkT('b'), dkT("box-width"), 1 },
+ { dkT('h'), dkT("help"), 0 },
+ { dkT('v'), dkT("version"), 0 },
+ { dkT('L'), dkT("license-terms"), 0 },
+ { dkT('\0'),dkT("license"), 0 },
+ { dkT('t'), dkT("timestamp"), 0 },
+ { dkT('k'), dkT("trace-keyword"), 0 },
+ { dkT('w'), dkT("windows-wide-char"), 0 },
+ { dkT('p'), dkT("portable-output"), 0 },
+ { dkT('S'), dkT("splint"), 0 },
+ { dkT('\0'),dkT("splint-comment-char"), 1 }
+};
+/** Number of options in the \a dkct_options array.
+*/
+static size_t dkct_sz_options = sizeof(dkct_options)/sizeof(dk3_option_t);
+
+/** Keywords without need for localization.
+*/
+static dkChar const * dkct_not_localized[] = {
+/* 0 */ dkT("."), /* Current directory. */
+NULL
+};
+
+
+
+/** File name for help file.
+*/
+static dkChar const dkct_help_file_name[] = {
+dkT("dkct.txt")
+};
+
+
+
+/** Default help text, shown if help text file is not found.
+*/
+static dkChar const * dkct_help_text[] = {
+dkT(""),
+dkT("NAME"),
+dkT(""),
+dkT(" dkct - Dirk Krause's C tool"),
+dkT(""),
+dkT("SYNOPSIS"),
+dkT(""),
+dkT(" dkt [<options>] [<files>]"),
+dkT(""),
+dkT("DESCRIPTION"),
+dkT(""),
+dkT("The program provides:"),
+dkT("- A preprocessor for debug/trace instructions,"),
+dkT("- a code generator for state machines,"),
+dkT("- a code generator for GUIs using the wxWidgets library."),
+dkT(""),
+dkT("The program converts *.ctr, *.cpt, *.mtr and *.jtr files to *.c, *.cpp,"),
+dkT("*.m and *.java. The source files can contain debug instructions in a special"),
+dkT("notation. When producing release versions the debug instructions are ignored."),
+dkT("When producing debug versions the debug instructions are converted to output"),
+dkT("instructtions."),
+dkT(""),
+dkT("OPTIONS"),
+dkT(""),
+dkT("-R"),
+dkT("--reset"),
+dkT("\tIgnore all settings from configuration files."),
+dkT(""),
+dkT("-d"),
+dkT("--debug"),
+dkT("\tCreate debug output."),
+dkT(""),
+dkT("-s"),
+dkT("--debug-stdout"),
+dkT("\tDebug output goes to standard output."),
+dkT(""),
+dkT("-t"),
+dkT("--timestamp"),
+dkT("\tDebug output contains a timestamp."),
+dkT(""),
+dkT("-k"),
+dkT("--trace-keyword"),
+dkT("\tDebug output contains \"trace\" string."),
+dkT(""),
+dkT("-w"),
+dkT("--windows-wide-char"),
+dkT("\tPrepare debug output for wchar_t."),
+dkT(""),
+dkT("-p"),
+dkT("--portable-output"),
+dkT("\tCreate portable debug output code (implies -w)."),
+dkT(""),
+dkT("-l"),
+dkT("--line-numbers"),
+dkT("\tWrite preprozessor directives \"#line ...\" to output."),
+dkT(""),
+dkT("-m"),
+dkT("--make"),
+dkT("\tMake mode: rebuild destination files only if necessary."),
+dkT(""),
+dkT("-b <width>"),
+dkT("--box-width=<width>"),
+dkT("\tBox with for comment boxes."),
+dkT(""),
+dkT("-h"),
+dkT("--help"),
+dkT("\tShow help text."),
+dkT(""),
+dkT("-v"),
+dkT("--version"),
+dkT("\tShow version number."),
+dkT(""),
+dkT("-L"),
+dkT("--license-terms"),
+dkT("\tShow license conditions."),
+dkT(""),
+dkT("EXIT STATUS"),
+dkT(""),
+dkT("The program returns 0 on success, any other value indicates an error."),
+dkT(""),
+dkT("SEE ALSO"),
+dkT(""),
+dkT("http://dktools.sourceforge.net"),
+dkT(""),
+dkT("AUTHOR"),
+dkT(""),
+dkT("Dirk Krause"),
+dkT(""),
+dkT("LICENSE"),
+dkT(""),
+dkT("Use"),
+dkT(" dkct --license-terms"),
+dkT("to view the license conditions."),
+dkT(""),
+NULL
+
+
+#line 224 "dkct.ctr"
+};
+
+
+
+/** Initialize option set.
+ @param o Option set.
+*/
+static
+void
+dkct_option_set_init(DKCT_OPTION_SET *o)
+{
+ o->deb = 0; o->lnn = 0; o->mak = 0; o->sty = 0;
+ o->bw = 78; o->tkw = 0; o->ts = 0; o->win = 0;
+ o->tip = 0; o->deben = 1; o->port = 0;
+ o->spls = '\0';
+}
+
+
+
+/** Initialize job structure.
+ @param j Structure to initialize.
+*/
+static
+void
+dkct_job_init(DKCT_J *j)
+{
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ j->app = NULL;
+ j->msg = NULL;
+ j->nlc = NULL;
+ j->opt = NULL;
+ j->sCwd = NULL;
+ j->cmd = 0;
+ j->curdi = 0;
+ dkct_option_set_init(&(j->dkcto));
+}
+
+
+
+/** Clean up job structure.
+ @param j Job structure to clean up.
+*/
+static
+void
+dkct_job_cleanup(DKCT_J *j)
+{
+ if(j->opt) {
+ dk3opt_close(j->opt);
+ } j->opt = NULL;
+ if(j->app) {
+ dk3app_close(j->app);
+ } j->app = NULL;
+ j->msg = NULL; j->nlc = NULL;
+}
+
+
+
+/** Process command line arguments, search for options.
+ @param j Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_process_arguments(DKCT_J *j)
+{
+ int back = 0;
+ int i; /* Temporary value to read box width. */
+ dkChar const *arg; /* Argument value. */
+
+
+#line 293 "dkct.ctr"
+ j->opt = dk3opt_open_from_app(
+ dkct_options,
+ dkct_sz_options,
+ 0x00,
+ NULL,
+ j->app
+ );
+ if(j->opt) {
+ if(dk3opt_get_error_code(j->opt) == 0) {
+ back = 1;
+ if(dk3opt_is_set(j->opt, dkT('R'))) {
+ dkct_option_set_init(&(j->dkcto));
+ }
+ if(dk3opt_is_set(j->opt, dkT('d'))) {
+ (j->dkcto).deb = 1;
+ }
+ if(dk3opt_is_set(j->opt, dkT('s'))) {
+ (j->dkcto).deb = 2;
+ }
+ if((j->dkcto).deb) {
+ if(dk3opt_is_set(j->opt, dkT('t'))) {
+ (j->dkcto).ts = 1;
+ }
+ if(dk3opt_is_set(j->opt, dkT('k'))) {
+ (j->dkcto).tkw = 1;
+ }
+ if(dk3opt_is_set(j->opt, dkT('w'))) {
+ (j->dkcto).win = 1;
+ }
+ if(dk3opt_is_set(j->opt, dkT('p'))) {
+ (j->dkcto).port = 1;
+ }
+ }
+ if(dk3opt_is_set(j->opt, dkT('l'))) {
+ (j->dkcto).lnn = 1;
+ }
+ if(dk3opt_is_set(j->opt, dkT('m'))) {
+ (j->dkcto).mak = 1;
+ }
+ if(dk3opt_is_set(j->opt, dkT('h'))) {
+ j->cmd |= DK3_APP_CMD_HELP;
+ }
+ if(dk3opt_is_set(j->opt, dkT('v'))) {
+ j->cmd |= DK3_APP_CMD_VERSION;
+ }
+ if(dk3opt_is_set(j->opt, dkT('L'))) {
+ j->cmd |= DK3_APP_CMD_LICENSE;
+ }
+ if(dk3opt_is_set_long(j->opt, dkT("license"))) {
+ j->cmd |= DK3_APP_CMD_LICENSE;
+ }
+ if(dk3opt_is_set(j->opt, dkT('b'))) {
+ arg = dk3opt_get_short_arg(j->opt, dkT('b'));
+ if(arg) {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(arg, dkT("%d"), &i))
+#else
+ if(0 != dk3ma_i_from_string(&i, arg, NULL))
+#endif
+ {
+ if(i > 20) {
+ (j->dkcto).bw = i;
+ } else {
+ j->exval = DKT_RESULT_ERR_OPTION; back = 0;
+ }
+ } else {
+ j->exval = DKT_RESULT_ERR_OPTION; back = 0;
+ }
+ } else {
+ j->exval = DKT_RESULT_ERR_OPTION; back = 0;
+ }
+ }
+
+#if VERSION_BEFORE_20140611
+ if (dk3opt_is_set(j->opt, dkT('S'))) {
+
+#line 368 "dkct.ctr"
+ arg = dk3opt_get_short_arg(j->opt, dkT('S'));
+ if (arg) {
+
+#line 370 "dkct.ctr"
+ if (dk3str_len(arg) == 1) {
+
+#line 371 "dkct.ctr"
+ if (128 > (int)(*arg)) {
+
+#line 372 "dkct.ctr"
+ (j->dkcto).spls = (char)(*arg);
+ } else {
+
+#line 374 "dkct.ctr"
+ j->exval = DKT_RESULT_ERR_OPTION; back = 0;
+ /* ##### ERROR: Not an ASCII character */
+ }
+ } else {
+
+#line 378 "dkct.ctr"
+ j->exval = DKT_RESULT_ERR_OPTION; back = 0;
+ /* ##### ERROR: Just one character allowed */
+ }
+ } else {
+
+#line 382 "dkct.ctr"
+ j->exval = DKT_RESULT_ERR_OPTION; back = 0;
+ }
+ }
+#else
+ if (dk3opt_is_set_long(j->opt, dkct_options[14].lo)) {
+
+#line 387 "dkct.ctr"
+ arg = dk3opt_get_long_arg(j->opt, dkct_options[14].lo);
+ if (arg) {
+ if (1 == dk3str_len(arg)) {
+ if (128 > (int)(*arg)) {
+ (j->dkcto).spls = (char)(*arg);
+ } else {
+ /* ##### ERROR: Not an ASCII character! */
+ j->exval = DKT_RESULT_ERR_OPTION; back = 0;
+ }
+ } else {
+ /* ##### ERROR: Exactly one character required! */
+ j->exval = DKT_RESULT_ERR_OPTION; back = 0;
+ }
+ } else {
+ /* ##### ERROR: Argument required for option! */
+ j->exval = DKT_RESULT_ERR_OPTION; back = 0;
+ }
+ } else {
+
+#line 405 "dkct.ctr"
+ }
+ if (dk3opt_is_set(j->opt, dkT('S'))) {
+
+#line 407 "dkct.ctr"
+ if ('\0' == (j->dkcto).spls) {
+ (j->dkcto).spls = '@';
+ }
+ } else {
+
+#line 411 "dkct.ctr"
+ }
+#endif
+ } else {
+ j->exval = DKT_RESULT_ERR_OPTION;
+ }
+ } else {
+ j->exval = DKT_RESULT_ERR_OPTION;
+ }
+
+#line 419 "dkct.ctr"
+ return back;
+}
+
+
+
+/** Run for file after expanding wildcards.
+ @param j Job structure.
+ @param fn Source file name.
+ @param sufi Source file suffix index.
+*/
+static
+void
+dkct_really_run_for_file(DKCT_J *j, dkChar const *fn, int sufi)
+{
+ char shn[DK3_MAX_PATH]; /* Short file name. */
+ dkChar const *pstart; /* Short file name. */
+ int ie; /* System input encoding. */
+ DKCT_SRC *psrc; /* Source structure. */
+ int success; /* Flag: Success so far. */
+
+
+#line 439 "dkct.ctr"
+ pstart = dk3str_rchr(fn, DK3_CHAR_SEP);
+ if(pstart) {
+ pstart++;
+ } else {
+ pstart = fn;
+ }
+ if(pstart) {
+ ie = dk3app_get_encoding(j->app);
+ if(dk3str_to_c8p_app(shn, sizeof(shn), pstart, ie, j->app)) {
+
+#line 448 "dkct.ctr"
+ psrc = dkct_tr_new(&(j->dkcto), shn, sufi, j->app, fn);
+ if(psrc) {
+
+#line 450 "dkct.ctr"
+ success = 0;
+ if(j->curdi) { psrc->curdi = 1; }
+ psrc->msg = j->msg;
+ dk3app_log_1(j->app, DK3_LL_PROGRESS, j->msg, 106);
+ if(dkct_tr_read(psrc, fn, sufi)) {
+
+#line 455 "dkct.ctr"
+ if(dkct_tr_check(psrc, fn, sufi)) {
+
+#line 456 "dkct.ctr"
+ if(dkct_tr_write(psrc, fn, sufi)) {
+ success = 1;
+ }
+ }
+ }
+ dk3app_set_source_line(j->app, 0UL);
+ dk3app_log_1(j->app, DK3_LL_PROGRESS, j->msg, 107);
+ if(!success) {
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ switch(psrc->ec) {
+ case DK3_ERROR_MEMORY: {
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ } break;
+ case DK3_ERROR_SYNTAX: {
+ j->exval = DKT_RESULT_ERR_INPUT;
+ } break;
+ }
+ }
+ dkct_tr_delete(psrc); psrc = NULL;
+ } else {
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ }
+ }
+ }
+
+
+#line 481 "dkct.ctr"
+}
+
+
+
+/** Run for a file name.
+ @param j Job structure.
+ @param fn Source file name.
+*/
+static
+void
+dkct_run_for_file(DKCT_J *j, dkChar const *fn)
+{
+ int must_run = 1; /* Flag: Must run. */
+ int ai; /* Source suffix type. */
+ dkChar const *su; /* Source suffx. */
+ dkChar const *oldsourcename; /* Old source file name. */
+ dkChar const *shortSourceName; /* Short source file name. */
+ dkChar *xsu; /* Suffix position. */
+ dkChar const * const *lfdsu; /* Destination suffix. */
+ dkChar b1[DK3_MAX_PATH]; /* Destination file name. */
+ unsigned long oldsourceline; /* Old source line number. */
+
+
+#line 503 "dkct.ctr"
+ oldsourcename = dk3app_get_source_file(j->app);
+ oldsourceline = dk3app_get_source_line(j->app);
+ if(j->curdi) {
+ shortSourceName = dk3str_rchr(fn, (dk3app_not_localized(20))[0]);
+ if(shortSourceName) { shortSourceName++; }
+ else { shortSourceName = fn; }
+ } else {
+ shortSourceName = fn;
+ }
+ dk3app_set_source_file(j->app, shortSourceName);
+ dk3app_set_source_line(j->app, 0UL);
+ su = dk3str_get_suffix(fn);
+ if(su) {
+#if DK3_ON_WINDOWS || DK3_HAVE_FNCASEINS
+ ai = dk3str_array_index(dkct_str_get_source_suffixes(), su, 0);
+#else
+ ai = dk3str_array_index(dkct_str_get_source_suffixes(), su, 1);
+#endif
+ if(ai >= 0) {
+ if((j->dkcto).mak) {
+ if(dk3str_len(fn) < DK3_SIZEOF(b1,dkChar)) {
+ dk3str_cpy_not_overlapped(b1, fn);
+ lfdsu = (dkct_str_get_dest_suffixes())[ai];
+ xsu = dk3str_get_suffix(b1);
+ if(xsu) {
+ must_run = 0;
+ while(*lfdsu) {
+ *xsu = dkT('\0');
+ if((dk3str_len(b1)+dk3str_len(*lfdsu)) < DK3_SIZEOF(b1,dkChar)) {
+ dk3str_cat(b1, *lfdsu);
+ if(dk3sf_must_rebuild(b1, fn)) {
+ must_run = 1;
+ }
+ } else {
+ must_run = 1;
+ }
+ lfdsu++;
+ }
+ }
+ }
+ }
+ if(must_run) {
+ dkct_really_run_for_file(j, fn, ai);
+ } else {
+ /* Progress: All output files up to date. 105 */
+ dk3app_log_1(j->app, DK3_LL_PROGRESS, j->msg, 105);
+ }
+ } else {
+ /* Wrong suffix, not an input file! */
+ dk3app_log_3(j->app, DK3_LL_ERROR, j->msg, 0, 1, fn);
+ j->exval = DKT_RESULT_ERR_FILENAME;
+ }
+ } else {
+ /* No suffix, Not an input file! */
+ dk3app_log_3(j->app, DK3_LL_ERROR, j->msg, 0, 1, fn);
+ j->exval = DKT_RESULT_ERR_FILENAME;
+ }
+ dk3app_set_source_file(j->app, oldsourcename);
+ dk3app_set_source_line(j->app, oldsourceline);
+
+
+#line 563 "dkct.ctr"
+}
+
+
+
+/** Run for a directory.
+ @param j Job structure.
+ @param dn Directory name.
+ @param fcd Flag: Use chdir() to enter directory (ignored).
+*/
+static
+void
+dkct_run_for_directory(DKCT_J *j, dkChar const *dn, int fcd)
+{
+ int ok = 1; /* Flag: Ok so far. */
+ dk3_dir_t *dir; /* Directory. */
+ dkChar const *en; /* Current file name. */
+ dkChar const *su; /* File name suffix. */
+ dk3_stat_t const *es; /* Stat information for current file. */
+ int ai; /* Source suffix type. */
+
+ if(fcd) {
+#if 0
+ /* Change into directory dn. */
+ if(!dk3sf_chdir_app(dn, j->app)) {
+ ok = 0;
+ }
+#endif
+ }
+ if(ok) {
+ dir = dk3dir_open_app(dn, j->app);
+ if(dir) {
+ while(dk3dir_get_next_file(dir)) {
+ en = dk3dir_get_fullname(dir);
+ es = dk3dir_get_stat(dir);
+ if((en) && (es)) {
+ switch((es->ft) & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_REGULAR: {
+ su = dk3str_get_suffix(en);
+ if(su) {
+#if DK3_ON_WINDOWS || DK3_HAVE_FNCASEINS
+ ai = dk3str_array_index(dkct_str_get_source_suffixes(), su, 0);
+#else
+ ai = dk3str_array_index(dkct_str_get_source_suffixes(), su, 1);
+#endif
+ if(ai >= 0) {
+ dkct_run_for_file(j, en);
+ }
+ }
+ } break;
+ }
+ }
+ }
+ dk3dir_close(dir);
+ } else {
+ /* ERROR: Failed to open directory! */
+ j->exval = DKT_RESULT_ERR_OPENDIR;
+ }
+ }
+ if(fcd) {
+#if 0
+ /* Change back into previous current directory. */
+ if(ok) {
+ dk3sf_chdir_app(j->sCwd, j->app);
+ }
+#endif
+ }
+}
+
+
+
+/** Run for a directory, test for current directory before running.
+ @param j Job structure.
+ @param fn Directory name.
+*/
+static
+void
+dkct_run_for_directory_test_current(DKCT_J *j, dkChar const *fn)
+{
+ if(dk3str_cmp(fn, dkct_not_localized[0]) == 0) {
+ j->curdi = 1;
+ dkct_run_for_directory(j, fn, 0);
+ } else {
+ dkct_run_for_directory(j, fn, 1);
+ }
+}
+
+
+
+/** Run for the given file names.
+ @param j Job structure.
+*/
+static
+void
+dkct_run(DKCT_J *j)
+{
+ int nfn; /* Number of file names. */
+ dkChar const *arg; /* Current argument. */
+ dkChar const *en; /* File name. */
+ dkChar bu[DK3_MAX_PATH]; /* Buffer input file name. */
+ dk3_stat_t stb; /* Stat inf for input file. */
+ dk3_stat_t const *es; /* Stat inf for output file. */
+ dk3_dir_t *fne; /* File name expander. */
+ int i; /* Current argument index. */
+ int found = 0; /* Flag: Matching file found. */
+
+ nfn = dk3opt_get_num_args(j->opt);
+ if(nfn > 0) {
+ for(i = 0; i < nfn; i++) {
+ arg = dk3opt_get_arg(j->opt, i);
+ if(arg) {
+ if(dk3str_len(arg) < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy_not_overlapped(bu, arg);
+ dk3str_correct_filename(bu);
+ if(dk3sf_must_expand(bu)) {
+ fne = dk3dir_fne_open_app(bu, j->app);
+ if(fne) {
+ found = 0;
+ while(dk3dir_get_next_file(fne)) {
+ en = dk3dir_get_fullname(fne);
+ es = dk3dir_get_stat(fne);
+ if((en) && (es)) {
+ switch((es->ft) & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_REGULAR: {
+ found = 1;
+ dkct_run_for_file(j, en);
+ } break;
+ default: {
+ /* Illegal file type! */
+ dk3app_log_3(j->app, DK3_LL_ERROR, j->msg, 2, 3, en);
+ j->exval = DKT_RESULT_ERR_INPUT;
+ } break;
+ }
+ }
+ }
+ while(dk3dir_get_next_directory(fne)) {
+ en = dk3dir_get_fullname(fne);
+ es = dk3dir_get_stat(fne);
+ if((en) && (es)) {
+ switch((es->ft) & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_DIRECTORY: {
+ dkct_run_for_directory_test_current(j, en);
+ } break;
+ default: {
+ /* Illegal file type! */
+ dk3app_log_3(j->app, DK3_LL_ERROR, j->msg, 2, 3, en);
+ j->exval = DKT_RESULT_ERR_INPUT;
+ } break;
+ }
+ }
+ }
+ if(!found) {
+ /* ERROR: No such file or directory! */
+ dk3app_log_i3(j->app, DK3_LL_ERROR, 215, 216, bu);
+ j->exval = DKT_RESULT_ERR_FILENAME;
+ }
+ dk3dir_close(fne);
+ } else {
+ /* ERROR: No fne */
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ }
+ } else {
+ if(dk3sf_stat_app(&stb, bu, j->app)) {
+ switch((stb.ft) & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_REGULAR: {
+ dkct_run_for_file(j, bu);
+ } break;
+ case DK3_FT_DIRECTORY: {
+ dkct_run_for_directory_test_current(j, bu);
+ } break;
+ default: {
+ /* ERROR: Illegal file type! */
+ dk3app_log_3(j->app, DK3_LL_ERROR, j->msg, 2, 3, bu);
+ j->exval = DKT_RESULT_ERR_FILENAME;
+ } break;
+ }
+ } else {
+ /* ERROR: No such file or directory! */
+ j->exval = DKT_RESULT_ERR_FILENAME;
+ }
+ }
+ } else {
+ /* ERROR: Name too long! */
+ dk3app_log_i3(j->app, DK3_LL_ERROR, 65, 66, arg);
+ j->exval = DKT_RESULT_ERR_FILENAME;
+ }
+ } else {
+ /* BUG */
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ }
+ } else {
+ j->curdi = 1;
+ dkct_run_for_directory(j, j->sCwd, 0);
+ }
+}
+
+
+
+/** Show license conditions.
+ @param j Job structure.
+*/
+static
+void
+dkct_show_license(DKCT_J *j)
+{
+ dkChar const * const *sptr; /* Pointer to traverse text. */
+
+ sptr = dkct_license;
+ dk3sf_initialize_stdout();
+ while(*sptr) {
+ dk3sf_fputs(*(sptr++), stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+}
+
+
+
+/** The main() function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, any other value indicates an error.
+*/
+DK3_MAIN
+{
+ int exval = 0; /* Exit status code. */
+ DKCT_J j; /* Job structure. */
+ dkChar cd[DK3_MAX_PATH]; /* Buffer for current directory. */
+
+
+#line 791 "dkct.ctr"
+
+
+#line 792 "dkct.ctr"
+ dkct_job_init(&j);
+ j.app = dk3app_open_command(
+ argc, (dkChar const * const *)argv, dkct_group_name
+ );
+ if(j.app) {
+ j.msg = dk3app_messages(
+ j.app,
+ dkct_str_get_string_table_file_name(),
+ (dkChar const **)dkct_str_get_message_texts()
+ );
+ j.nlc = dkct_not_localized;
+ if(dk3sf_getcwd_app(cd, DK3_SIZEOF(cd,dkChar), j.app)) {
+ j.sCwd = cd;
+ if(dkct_process_arguments(&j)) {
+ j.exval = DKT_RESULT_OK;
+ if(j.cmd) {
+ /* Help, version, license */
+ if((j.cmd) & DK3_APP_CMD_VERSION) {
+ dk3sf_initialize_stdout();
+ dk3sf_fputs(dkct_version, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ if((j.cmd) & DK3_APP_CMD_LICENSE) {
+ dkct_show_license(&j);
+ }
+ if((j.cmd) & DK3_APP_CMD_HELP) {
+ dk3app_help(j.app, dkct_help_file_name, dkct_help_text);
+ }
+ } else {
+ dkct_run(&j);
+ }
+ }
+ }
+ }
+ exval = j.exval;
+ dkct_job_cleanup(&j);
+
+
+#line 829 "dkct.ctr"
+
+
+#line 830 "dkct.ctr"
+ fflush(stdout);
+ exit(exval); return exval;
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dkct.ctr b/support/dktools/dkct.ctr
new file mode 100644
index 0000000000..72bddf85cc
--- /dev/null
+++ b/support/dktools/dkct.ctr
@@ -0,0 +1,837 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% module
+
+/** @file dkct.c Dirk Krause's C/C++ tool.
+*/
+
+
+#if DK3_USE_WX
+#include "dkwxtrace.h"
+#else
+#include "dkct.h"
+#endif
+
+$!trace-include
+
+
+
+/** Application group name.
+*/
+static dkChar const dkct_group_name[] = { dkT("dktools") };
+
+
+
+/** Version number string.
+*/
+static dkChar const dkct_version[] = {
+dkT("dkct ") DKT_VERSION_DK
+};
+
+
+
+/** License conditions shown for dkct --license.
+*/
+static dkChar const * const dkct_license[] = {
+$!text macro=dkT
+
+Copyright (c) 2011-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms,
+with or without modification, are permitted provided
+that the following conditions are met:
+
+* Redistributions of source code must retain the above
+ copyright notice, this list of conditions and the
+ following disclaimer.
+* Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials
+ provided with the distribution.
+* Neither the name of the copyright holder(s) nor the names of
+ contributors may be used to endorse or promote
+ products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+
+$!end
+};
+
+
+
+/** Options for the dkct program.
+*/
+static dk3_option_t const dkct_options[] = {
+ { dkT('R'), dkT("reset"), 0 },
+ { dkT('d'), dkT("debug"), 0 },
+ { dkT('s'), dkT("debug-stdout"), 0 },
+ { dkT('l'), dkT("line-numbers"), 0 },
+ { dkT('m'), dkT("make"), 0 },
+ { dkT('b'), dkT("box-width"), 1 },
+ { dkT('h'), dkT("help"), 0 },
+ { dkT('v'), dkT("version"), 0 },
+ { dkT('L'), dkT("license-terms"), 0 },
+ { dkT('\0'),dkT("license"), 0 },
+ { dkT('t'), dkT("timestamp"), 0 },
+ { dkT('k'), dkT("trace-keyword"), 0 },
+ { dkT('w'), dkT("windows-wide-char"), 0 },
+ { dkT('p'), dkT("portable-output"), 0 },
+ { dkT('S'), dkT("splint"), 0 },
+ { dkT('\0'),dkT("splint-comment-char"), 1 }
+};
+/** Number of options in the \a dkct_options array.
+*/
+static size_t dkct_sz_options = sizeof(dkct_options)/sizeof(dk3_option_t);
+
+/** Keywords without need for localization.
+*/
+static dkChar const * dkct_not_localized[] = {
+/* 0 */ dkT("."), /* Current directory. */
+NULL
+};
+
+
+
+/** File name for help file.
+*/
+static dkChar const dkct_help_file_name[] = {
+dkT("dkct.txt")
+};
+
+
+
+/** Default help text, shown if help text file is not found.
+*/
+static dkChar const * dkct_help_text[] = {
+$!text macro=dkT
+
+NAME
+
+ dkct - Dirk Krause's C tool
+
+SYNOPSIS
+
+ dkt [<options>] [<files>]
+
+DESCRIPTION
+
+The program provides:
+- A preprocessor for debug/trace instructions,
+- a code generator for state machines,
+- a code generator for GUIs using the wxWidgets library.
+
+The program converts *.ctr, *.cpt, *.mtr and *.jtr files to *.c, *.cpp,
+*.m and *.java. The source files can contain debug instructions in a special
+notation. When producing release versions the debug instructions are ignored.
+When producing debug versions the debug instructions are converted to output
+instructtions.
+
+OPTIONS
+
+-R
+--reset
+ Ignore all settings from configuration files.
+
+-d
+--debug
+ Create debug output.
+
+-s
+--debug-stdout
+ Debug output goes to standard output.
+
+-t
+--timestamp
+ Debug output contains a timestamp.
+
+-k
+--trace-keyword
+ Debug output contains "trace" string.
+
+-w
+--windows-wide-char
+ Prepare debug output for wchar_t.
+
+-p
+--portable-output
+ Create portable debug output code (implies -w).
+
+-l
+--line-numbers
+ Write preprozessor directives "#line ..." to output.
+
+-m
+--make
+ Make mode: rebuild destination files only if necessary.
+
+-b <width>
+--box-width=<width>
+ Box with for comment boxes.
+
+-h
+--help
+ Show help text.
+
+-v
+--version
+ Show version number.
+
+-L
+--license-terms
+ Show license conditions.
+
+EXIT STATUS
+
+The program returns 0 on success, any other value indicates an error.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
+AUTHOR
+
+Dirk Krause
+
+LICENSE
+
+Use
+ dkct --license-terms
+to view the license conditions.
+
+$!end
+};
+
+
+
+/** Initialize option set.
+ @param o Option set.
+*/
+static
+void
+dkct_option_set_init(DKCT_OPTION_SET *o)
+{
+ o->deb = 0; o->lnn = 0; o->mak = 0; o->sty = 0;
+ o->bw = 78; o->tkw = 0; o->ts = 0; o->win = 0;
+ o->tip = 0; o->deben = 1; o->port = 0;
+ o->spls = '\0';
+}
+
+
+
+/** Initialize job structure.
+ @param j Structure to initialize.
+*/
+static
+void
+dkct_job_init(DKCT_J *j)
+{
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ j->app = NULL;
+ j->msg = NULL;
+ j->nlc = NULL;
+ j->opt = NULL;
+ j->sCwd = NULL;
+ j->cmd = 0;
+ j->curdi = 0;
+ dkct_option_set_init(&(j->dkcto));
+}
+
+
+
+/** Clean up job structure.
+ @param j Job structure to clean up.
+*/
+static
+void
+dkct_job_cleanup(DKCT_J *j)
+{
+ if(j->opt) {
+ dk3opt_close(j->opt);
+ } j->opt = NULL;
+ if(j->app) {
+ dk3app_close(j->app);
+ } j->app = NULL;
+ j->msg = NULL; j->nlc = NULL;
+}
+
+
+
+/** Process command line arguments, search for options.
+ @param j Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkct_process_arguments(DKCT_J *j)
+{
+ int back = 0;
+ int i; /* Temporary value to read box width. */
+ dkChar const *arg; /* Argument value. */
+ $? "+ dkct_process_arguments"
+ j->opt = dk3opt_open_from_app(
+ dkct_options,
+ dkct_sz_options,
+ 0x00,
+ NULL,
+ j->app
+ );
+ if(j->opt) {
+ if(dk3opt_get_error_code(j->opt) == 0) {
+ back = 1;
+ if(dk3opt_is_set(j->opt, dkT('R'))) {
+ dkct_option_set_init(&(j->dkcto));
+ }
+ if(dk3opt_is_set(j->opt, dkT('d'))) {
+ (j->dkcto).deb = 1;
+ }
+ if(dk3opt_is_set(j->opt, dkT('s'))) {
+ (j->dkcto).deb = 2;
+ }
+ if((j->dkcto).deb) {
+ if(dk3opt_is_set(j->opt, dkT('t'))) {
+ (j->dkcto).ts = 1;
+ }
+ if(dk3opt_is_set(j->opt, dkT('k'))) {
+ (j->dkcto).tkw = 1;
+ }
+ if(dk3opt_is_set(j->opt, dkT('w'))) {
+ (j->dkcto).win = 1;
+ }
+ if(dk3opt_is_set(j->opt, dkT('p'))) {
+ (j->dkcto).port = 1;
+ }
+ }
+ if(dk3opt_is_set(j->opt, dkT('l'))) {
+ (j->dkcto).lnn = 1;
+ }
+ if(dk3opt_is_set(j->opt, dkT('m'))) {
+ (j->dkcto).mak = 1;
+ }
+ if(dk3opt_is_set(j->opt, dkT('h'))) {
+ j->cmd |= DK3_APP_CMD_HELP;
+ }
+ if(dk3opt_is_set(j->opt, dkT('v'))) {
+ j->cmd |= DK3_APP_CMD_VERSION;
+ }
+ if(dk3opt_is_set(j->opt, dkT('L'))) {
+ j->cmd |= DK3_APP_CMD_LICENSE;
+ }
+ if(dk3opt_is_set_long(j->opt, dkT("license"))) {
+ j->cmd |= DK3_APP_CMD_LICENSE;
+ }
+ if(dk3opt_is_set(j->opt, dkT('b'))) {
+ arg = dk3opt_get_short_arg(j->opt, dkT('b'));
+ if(arg) {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(arg, dkT("%d"), &i))
+#else
+ if(0 != dk3ma_i_from_string(&i, arg, NULL))
+#endif
+ {
+ if(i > 20) {
+ (j->dkcto).bw = i;
+ } else {
+ j->exval = DKT_RESULT_ERR_OPTION; back = 0;
+ }
+ } else {
+ j->exval = DKT_RESULT_ERR_OPTION; back = 0;
+ }
+ } else {
+ j->exval = DKT_RESULT_ERR_OPTION; back = 0;
+ }
+ }
+
+#if VERSION_BEFORE_20140611
+ if (dk3opt_is_set(j->opt, dkT('S'))) { $? ". option S"
+ arg = dk3opt_get_short_arg(j->opt, dkT('S'));
+ if (arg) { $? ". have arg"
+ if (dk3str_len(arg) == 1) { $? ". length ok"
+ if (128 > (int)(*arg)) { $? ". char ok"
+ (j->dkcto).spls = (char)(*arg);
+ } else { $? "! not ASCII"
+ j->exval = DKT_RESULT_ERR_OPTION; back = 0;
+ /* ##### ERROR: Not an ASCII character */
+ }
+ } else { $? "! too long"
+ j->exval = DKT_RESULT_ERR_OPTION; back = 0;
+ /* ##### ERROR: Just one character allowed */
+ }
+ } else { $? "! missing arg"
+ j->exval = DKT_RESULT_ERR_OPTION; back = 0;
+ }
+ }
+#else
+ if (dk3opt_is_set_long(j->opt, dkct_options[14].lo)) { $? ". --splint-comment-char set"
+ arg = dk3opt_get_long_arg(j->opt, dkct_options[14].lo);
+ if (arg) {
+ if (1 == dk3str_len(arg)) {
+ if (128 > (int)(*arg)) {
+ (j->dkcto).spls = (char)(*arg);
+ } else {
+ /* ##### ERROR: Not an ASCII character! */
+ j->exval = DKT_RESULT_ERR_OPTION; back = 0;
+ }
+ } else {
+ /* ##### ERROR: Exactly one character required! */
+ j->exval = DKT_RESULT_ERR_OPTION; back = 0;
+ }
+ } else {
+ /* ##### ERROR: Argument required for option! */
+ j->exval = DKT_RESULT_ERR_OPTION; back = 0;
+ }
+ } else { $? ". --splint-comment-char not set"
+ }
+ if (dk3opt_is_set(j->opt, dkT('S'))) { $? ". -S set"
+ if ('\0' == (j->dkcto).spls) {
+ (j->dkcto).spls = '@';
+ }
+ } else { $? ". -S not set"
+ }
+#endif
+ } else {
+ j->exval = DKT_RESULT_ERR_OPTION;
+ }
+ } else {
+ j->exval = DKT_RESULT_ERR_OPTION;
+ } $? "- dkct_process_arguments %d exval=%d", back, j->exval
+ return back;
+}
+
+
+
+/** Run for file after expanding wildcards.
+ @param j Job structure.
+ @param fn Source file name.
+ @param sufi Source file suffix index.
+*/
+static
+void
+dkct_really_run_for_file(DKCT_J *j, dkChar const *fn, int sufi)
+{
+ char shn[DK3_MAX_PATH]; /* Short file name. */
+ dkChar const *pstart; /* Short file name. */
+ int ie; /* System input encoding. */
+ DKCT_SRC *psrc; /* Source structure. */
+ int success; /* Flag: Success so far. */
+ $? "+ dkct_really_run_for_file \"%!ds\"", fn
+ pstart = dk3str_rchr(fn, DK3_CHAR_SEP);
+ if(pstart) {
+ pstart++;
+ } else {
+ pstart = fn;
+ }
+ if(pstart) {
+ ie = dk3app_get_encoding(j->app);
+ if(dk3str_to_c8p_app(shn, sizeof(shn), pstart, ie, j->app)) { $? ". shn ok"
+ psrc = dkct_tr_new(&(j->dkcto), shn, sufi, j->app, fn);
+ if(psrc) { $? ". psrc ok"
+ success = 0;
+ if(j->curdi) { psrc->curdi = 1; }
+ psrc->msg = j->msg;
+ dk3app_log_1(j->app, DK3_LL_PROGRESS, j->msg, 106);
+ if(dkct_tr_read(psrc, fn, sufi)) { $? ". read ok"
+ if(dkct_tr_check(psrc, fn, sufi)) { $? ". check ok"
+ if(dkct_tr_write(psrc, fn, sufi)) {
+ success = 1;
+ }
+ }
+ }
+ dk3app_set_source_line(j->app, 0UL);
+ dk3app_log_1(j->app, DK3_LL_PROGRESS, j->msg, 107);
+ if(!success) {
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ switch(psrc->ec) {
+ case DK3_ERROR_MEMORY: {
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ } break;
+ case DK3_ERROR_SYNTAX: {
+ j->exval = DKT_RESULT_ERR_INPUT;
+ } break;
+ }
+ }
+ dkct_tr_delete(psrc); psrc = NULL;
+ } else {
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ }
+ }
+ }
+ $? "- dkct_really_run_for_file"
+}
+
+
+
+/** Run for a file name.
+ @param j Job structure.
+ @param fn Source file name.
+*/
+static
+void
+dkct_run_for_file(DKCT_J *j, dkChar const *fn)
+{
+ int must_run = 1; /* Flag: Must run. */
+ int ai; /* Source suffix type. */
+ dkChar const *su; /* Source suffx. */
+ dkChar const *oldsourcename; /* Old source file name. */
+ dkChar const *shortSourceName; /* Short source file name. */
+ dkChar *xsu; /* Suffix position. */
+ dkChar const * const *lfdsu; /* Destination suffix. */
+ dkChar b1[DK3_MAX_PATH]; /* Destination file name. */
+ unsigned long oldsourceline; /* Old source line number. */
+ $? "+ dkct_run_for_file \"%!ds\"", fn
+ oldsourcename = dk3app_get_source_file(j->app);
+ oldsourceline = dk3app_get_source_line(j->app);
+ if(j->curdi) {
+ shortSourceName = dk3str_rchr(fn, (dk3app_not_localized(20))[0]);
+ if(shortSourceName) { shortSourceName++; }
+ else { shortSourceName = fn; }
+ } else {
+ shortSourceName = fn;
+ }
+ dk3app_set_source_file(j->app, shortSourceName);
+ dk3app_set_source_line(j->app, 0UL);
+ su = dk3str_get_suffix(fn);
+ if(su) {
+#if DK3_ON_WINDOWS || DK3_HAVE_FNCASEINS
+ ai = dk3str_array_index(dkct_str_get_source_suffixes(), su, 0);
+#else
+ ai = dk3str_array_index(dkct_str_get_source_suffixes(), su, 1);
+#endif
+ if(ai >= 0) {
+ if((j->dkcto).mak) {
+ if(dk3str_len(fn) < DK3_SIZEOF(b1,dkChar)) {
+ dk3str_cpy_not_overlapped(b1, fn);
+ lfdsu = (dkct_str_get_dest_suffixes())[ai];
+ xsu = dk3str_get_suffix(b1);
+ if(xsu) {
+ must_run = 0;
+ while(*lfdsu) {
+ *xsu = dkT('\0');
+ if((dk3str_len(b1)+dk3str_len(*lfdsu)) < DK3_SIZEOF(b1,dkChar)) {
+ dk3str_cat(b1, *lfdsu);
+ if(dk3sf_must_rebuild(b1, fn)) {
+ must_run = 1;
+ }
+ } else {
+ must_run = 1;
+ }
+ lfdsu++;
+ }
+ }
+ }
+ }
+ if(must_run) {
+ dkct_really_run_for_file(j, fn, ai);
+ } else {
+ /* Progress: All output files up to date. 105 */
+ dk3app_log_1(j->app, DK3_LL_PROGRESS, j->msg, 105);
+ }
+ } else {
+ /* Wrong suffix, not an input file! */
+ dk3app_log_3(j->app, DK3_LL_ERROR, j->msg, 0, 1, fn);
+ j->exval = DKT_RESULT_ERR_FILENAME;
+ }
+ } else {
+ /* No suffix, Not an input file! */
+ dk3app_log_3(j->app, DK3_LL_ERROR, j->msg, 0, 1, fn);
+ j->exval = DKT_RESULT_ERR_FILENAME;
+ }
+ dk3app_set_source_file(j->app, oldsourcename);
+ dk3app_set_source_line(j->app, oldsourceline);
+ $? "- dkct_run_for_file"
+}
+
+
+
+/** Run for a directory.
+ @param j Job structure.
+ @param dn Directory name.
+ @param fcd Flag: Use chdir() to enter directory (ignored).
+*/
+static
+void
+dkct_run_for_directory(DKCT_J *j, dkChar const *dn, int fcd)
+{
+ int ok = 1; /* Flag: Ok so far. */
+ dk3_dir_t *dir; /* Directory. */
+ dkChar const *en; /* Current file name. */
+ dkChar const *su; /* File name suffix. */
+ dk3_stat_t const *es; /* Stat information for current file. */
+ int ai; /* Source suffix type. */
+
+ if(fcd) {
+#if 0
+ /* Change into directory dn. */
+ if(!dk3sf_chdir_app(dn, j->app)) {
+ ok = 0;
+ }
+#endif
+ }
+ if(ok) {
+ dir = dk3dir_open_app(dn, j->app);
+ if(dir) {
+ while(dk3dir_get_next_file(dir)) {
+ en = dk3dir_get_fullname(dir);
+ es = dk3dir_get_stat(dir);
+ if((en) && (es)) {
+ switch((es->ft) & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_REGULAR: {
+ su = dk3str_get_suffix(en);
+ if(su) {
+#if DK3_ON_WINDOWS || DK3_HAVE_FNCASEINS
+ ai = dk3str_array_index(dkct_str_get_source_suffixes(), su, 0);
+#else
+ ai = dk3str_array_index(dkct_str_get_source_suffixes(), su, 1);
+#endif
+ if(ai >= 0) {
+ dkct_run_for_file(j, en);
+ }
+ }
+ } break;
+ }
+ }
+ }
+ dk3dir_close(dir);
+ } else {
+ /* ERROR: Failed to open directory! */
+ j->exval = DKT_RESULT_ERR_OPENDIR;
+ }
+ }
+ if(fcd) {
+#if 0
+ /* Change back into previous current directory. */
+ if(ok) {
+ dk3sf_chdir_app(j->sCwd, j->app);
+ }
+#endif
+ }
+}
+
+
+
+/** Run for a directory, test for current directory before running.
+ @param j Job structure.
+ @param fn Directory name.
+*/
+static
+void
+dkct_run_for_directory_test_current(DKCT_J *j, dkChar const *fn)
+{
+ if(dk3str_cmp(fn, dkct_not_localized[0]) == 0) {
+ j->curdi = 1;
+ dkct_run_for_directory(j, fn, 0);
+ } else {
+ dkct_run_for_directory(j, fn, 1);
+ }
+}
+
+
+
+/** Run for the given file names.
+ @param j Job structure.
+*/
+static
+void
+dkct_run(DKCT_J *j)
+{
+ int nfn; /* Number of file names. */
+ dkChar const *arg; /* Current argument. */
+ dkChar const *en; /* File name. */
+ dkChar bu[DK3_MAX_PATH]; /* Buffer input file name. */
+ dk3_stat_t stb; /* Stat inf for input file. */
+ dk3_stat_t const *es; /* Stat inf for output file. */
+ dk3_dir_t *fne; /* File name expander. */
+ int i; /* Current argument index. */
+ int found = 0; /* Flag: Matching file found. */
+
+ nfn = dk3opt_get_num_args(j->opt);
+ if(nfn > 0) {
+ for(i = 0; i < nfn; i++) {
+ arg = dk3opt_get_arg(j->opt, i);
+ if(arg) {
+ if(dk3str_len(arg) < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy_not_overlapped(bu, arg);
+ dk3str_correct_filename(bu);
+ if(dk3sf_must_expand(bu)) {
+ fne = dk3dir_fne_open_app(bu, j->app);
+ if(fne) {
+ found = 0;
+ while(dk3dir_get_next_file(fne)) {
+ en = dk3dir_get_fullname(fne);
+ es = dk3dir_get_stat(fne);
+ if((en) && (es)) {
+ switch((es->ft) & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_REGULAR: {
+ found = 1;
+ dkct_run_for_file(j, en);
+ } break;
+ default: {
+ /* Illegal file type! */
+ dk3app_log_3(j->app, DK3_LL_ERROR, j->msg, 2, 3, en);
+ j->exval = DKT_RESULT_ERR_INPUT;
+ } break;
+ }
+ }
+ }
+ while(dk3dir_get_next_directory(fne)) {
+ en = dk3dir_get_fullname(fne);
+ es = dk3dir_get_stat(fne);
+ if((en) && (es)) {
+ switch((es->ft) & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_DIRECTORY: {
+ dkct_run_for_directory_test_current(j, en);
+ } break;
+ default: {
+ /* Illegal file type! */
+ dk3app_log_3(j->app, DK3_LL_ERROR, j->msg, 2, 3, en);
+ j->exval = DKT_RESULT_ERR_INPUT;
+ } break;
+ }
+ }
+ }
+ if(!found) {
+ /* ERROR: No such file or directory! */
+ dk3app_log_i3(j->app, DK3_LL_ERROR, 215, 216, bu);
+ j->exval = DKT_RESULT_ERR_FILENAME;
+ }
+ dk3dir_close(fne);
+ } else {
+ /* ERROR: No fne */
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ }
+ } else {
+ if(dk3sf_stat_app(&stb, bu, j->app)) {
+ switch((stb.ft) & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_REGULAR: {
+ dkct_run_for_file(j, bu);
+ } break;
+ case DK3_FT_DIRECTORY: {
+ dkct_run_for_directory_test_current(j, bu);
+ } break;
+ default: {
+ /* ERROR: Illegal file type! */
+ dk3app_log_3(j->app, DK3_LL_ERROR, j->msg, 2, 3, bu);
+ j->exval = DKT_RESULT_ERR_FILENAME;
+ } break;
+ }
+ } else {
+ /* ERROR: No such file or directory! */
+ j->exval = DKT_RESULT_ERR_FILENAME;
+ }
+ }
+ } else {
+ /* ERROR: Name too long! */
+ dk3app_log_i3(j->app, DK3_LL_ERROR, 65, 66, arg);
+ j->exval = DKT_RESULT_ERR_FILENAME;
+ }
+ } else {
+ /* BUG */
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ }
+ } else {
+ j->curdi = 1;
+ dkct_run_for_directory(j, j->sCwd, 0);
+ }
+}
+
+
+
+/** Show license conditions.
+ @param j Job structure.
+*/
+static
+void
+dkct_show_license(DKCT_J *j)
+{
+ dkChar const * const *sptr; /* Pointer to traverse text. */
+
+ sptr = dkct_license;
+ dk3sf_initialize_stdout();
+ while(*sptr) {
+ dk3sf_fputs(*(sptr++), stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+}
+
+
+
+/** The main() function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, any other value indicates an error.
+*/
+DK3_MAIN
+{
+ int exval = 0; /* Exit status code. */
+ DKCT_J j; /* Job structure. */
+ dkChar cd[DK3_MAX_PATH]; /* Buffer for current directory. */
+ $!trace-init dkct.deb
+ $? "+ main"
+ dkct_job_init(&j);
+ j.app = dk3app_open_command(
+ argc, (dkChar const * const *)argv, dkct_group_name
+ );
+ if(j.app) {
+ j.msg = dk3app_messages(
+ j.app,
+ dkct_str_get_string_table_file_name(),
+ (dkChar const **)dkct_str_get_message_texts()
+ );
+ j.nlc = dkct_not_localized;
+ if(dk3sf_getcwd_app(cd, DK3_SIZEOF(cd,dkChar), j.app)) {
+ j.sCwd = cd;
+ if(dkct_process_arguments(&j)) {
+ j.exval = DKT_RESULT_OK;
+ if(j.cmd) {
+ /* Help, version, license */
+ if((j.cmd) & DK3_APP_CMD_VERSION) {
+ dk3sf_initialize_stdout();
+ dk3sf_fputs(dkct_version, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ if((j.cmd) & DK3_APP_CMD_LICENSE) {
+ dkct_show_license(&j);
+ }
+ if((j.cmd) & DK3_APP_CMD_HELP) {
+ dk3app_help(j.app, dkct_help_file_name, dkct_help_text);
+ }
+ } else {
+ dkct_run(&j);
+ }
+ }
+ }
+ }
+ exval = j.exval;
+ dkct_job_cleanup(&j);
+ $? "- main %d", exval
+ $!trace-end
+ fflush(stdout);
+ exit(exval); return exval;
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dkct.h b/support/dktools/dkct.h
new file mode 100644
index 0000000000..890048290b
--- /dev/null
+++ b/support/dktools/dkct.h
@@ -0,0 +1,64 @@
+
+#ifndef DKCT_H_INCLUDED
+#define DKCT_H_INCLUDED 1
+
+#define DKCT_STYLE_GCC 0
+
+
+#include "dk3all.h"
+#include "dkt.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4vers.h"
+
+/** Option set for dkct.
+ * The configuration dialog of dkwxtrace must set this.
+ */
+typedef struct {
+ int deb; /**< Debug: 0=no debug, 1=file, 2=stdout. */
+ int deben; /**< Flag: Debugging enabled. */
+ int lnn; /**< Show line numbers. */
+ int mak; /**< Make mode. */
+ int sty; /**< Style for Output to stdout (DKCT_STYLE_xxx). */
+ int bw; /**< Box width. */
+ int tkw; /**< Flag: Add trace keyword. */
+ int ts; /**< Flag: Print timestamp. */
+ int win; /**< Flag: Add support for Windows wide chars. */
+ int port; /**< Flag: Produce portable output (implies win). */
+ int tip; /**< Flag: trace include printed. */
+ char spls; /**< Splint special character. */
+} DKCT_OPTION_SET;
+
+
+
+/** Job structure for dkct.
+*/
+typedef struct {
+ DKCT_OPTION_SET dkcto; /**< Conversion options. */
+ dk3_app_t *app; /**< Application. */
+ dkChar const * const *msg; /**< Localized texts. */
+ dkChar const * const *nlc; /**< Non-localized keywords. */
+ dk3_option_set_t *opt; /**< Command line options. */
+ dkChar const *sCwd; /**< Current working directory. */
+ int exval; /**< Exit status code. */
+ int cmd; /**< Command. */
+ int curdi; /**< Flag: Processing the current directory. */
+} DKCT_J;
+
+
+
+#include "dkct-tr.h"
+#include "dkct-to.h"
+#include "dkct-gui.h"
+#include "dkct-str.h"
+
+
+
+/** Buffer size for input lines.
+*/
+#define DKCT_LINE_SIZE 4096
+
+
+#endif
+
diff --git a/support/dktools/dkct.rc b/support/dktools/dkct.rc
new file mode 100644
index 0000000000..6fd61494e7
--- /dev/null
+++ b/support/dktools/dkct.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Dirk Krause's C tool\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "Dirk Krause's C tool\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "dkct\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/dkctinst.ico b/support/dktools/dkctinst.ico
new file mode 100644
index 0000000000..6e3d218787
--- /dev/null
+++ b/support/dktools/dkctinst.ico
Binary files differ
diff --git a/support/dktools/dkctunin.ico b/support/dktools/dkctunin.ico
new file mode 100644
index 0000000000..ad4acae0ae
--- /dev/null
+++ b/support/dktools/dkctunin.ico
Binary files differ
diff --git a/support/dktools/dkdbt.c b/support/dktools/dkdbt.c
new file mode 100644
index 0000000000..8771fa2569
--- /dev/null
+++ b/support/dktools/dkdbt.c
@@ -0,0 +1,2475 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dkdbt.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dkdbt.c The dkdbt module.
+*/
+
+/** @defgroup dkct_state_machine_dkdbt_sql_split The dkdbt_sql_split state machine. */
+/**@{*/
+
+#ifndef ST_BT
+/** State: Backtick text. */
+#line 31 "dkdbt.ctr"
+#define ST_BT 0
+#else
+#line 31 "dkdbt.ctr"
+#error "Redefinition of ST_BT"
+#endif
+
+#ifndef ST_BT_BS
+/** State: Backtick text, backslash found. */
+#line 32 "dkdbt.ctr"
+#define ST_BT_BS 1
+#else
+#line 32 "dkdbt.ctr"
+#error "Redefinition of ST_BT_BS"
+#endif
+
+#ifndef ST_CB
+/** State: Normal text, closing bracket found. */
+#line 20 "dkdbt.ctr"
+#define ST_CB 2
+#else
+#line 20 "dkdbt.ctr"
+#error "Redefinition of ST_CB"
+#endif
+
+#ifndef ST_CB_CO
+/** State: Normal text, bracket and comma found. */
+#line 21 "dkdbt.ctr"
+#define ST_CB_CO 3
+#else
+#line 21 "dkdbt.ctr"
+#error "Redefinition of ST_CB_CO"
+#endif
+
+#ifndef ST_CO
+/** State: Comment. */
+#line 24 "dkdbt.ctr"
+#define ST_CO 4
+#else
+#line 24 "dkdbt.ctr"
+#error "Redefinition of ST_CO"
+#endif
+
+#ifndef ST_CO_AST
+/** State: Comment, asterisk found. */
+#line 25 "dkdbt.ctr"
+#define ST_CO_AST 5
+#else
+#line 25 "dkdbt.ctr"
+#error "Redefinition of ST_CO_AST"
+#endif
+
+#ifndef ST_DQ
+/** State: Double quote text. */
+#line 29 "dkdbt.ctr"
+#define ST_DQ 6
+#else
+#line 29 "dkdbt.ctr"
+#error "Redefinition of ST_DQ"
+#endif
+
+#ifndef ST_DQ_BS
+/** State: Double quote text, backslash found. */
+#line 30 "dkdbt.ctr"
+#define ST_DQ_BS 7
+#else
+#line 30 "dkdbt.ctr"
+#error "Redefinition of ST_DQ_BS"
+#endif
+
+#ifndef ST_ERROR
+/** State: Any error occured. */
+#line 33 "dkdbt.ctr"
+#define ST_ERROR 8
+#else
+#line 33 "dkdbt.ctr"
+#error "Redefinition of ST_ERROR"
+#endif
+
+#ifndef ST_LCO
+/** State: Line comment. */
+#line 26 "dkdbt.ctr"
+#define ST_LCO 9
+#else
+#line 26 "dkdbt.ctr"
+#error "Redefinition of ST_LCO"
+#endif
+
+#ifndef ST_MINUS
+/** State: Normal text, one minus found. */
+#line 23 "dkdbt.ctr"
+#define ST_MINUS 10
+#else
+#line 23 "dkdbt.ctr"
+#error "Redefinition of ST_MINUS"
+#endif
+
+#ifndef ST_N
+/** State: Normal text. */
+#line 18 "dkdbt.ctr"
+#define ST_N 11
+#else
+#line 18 "dkdbt.ctr"
+#error "Redefinition of ST_N"
+#endif
+
+#ifndef ST_N_BS
+/** State: Normal text, backslash found. */
+#line 19 "dkdbt.ctr"
+#define ST_N_BS 12
+#else
+#line 19 "dkdbt.ctr"
+#error "Redefinition of ST_N_BS"
+#endif
+
+#ifndef ST_Q
+/** State: Single quote text. */
+#line 27 "dkdbt.ctr"
+#define ST_Q 13
+#else
+#line 27 "dkdbt.ctr"
+#error "Redefinition of ST_Q"
+#endif
+
+#ifndef ST_Q_BS
+/** State: Single quote text, backslash found. */
+#line 28 "dkdbt.ctr"
+#define ST_Q_BS 14
+#else
+#line 28 "dkdbt.ctr"
+#error "Redefinition of ST_Q_BS"
+#endif
+
+#ifndef ST_SL
+/** State: Normal text, slash found. */
+#line 22 "dkdbt.ctr"
+#define ST_SL 15
+#else
+#line 22 "dkdbt.ctr"
+#error "Redefinition of ST_SL"
+#endif
+
+#ifndef I_ANY
+/** State machine input: Any text. */
+#line 36 "dkdbt.ctr"
+#define I_ANY 0
+#else
+#line 36 "dkdbt.ctr"
+#error "Redefinition of I_ANY"
+#endif
+
+#ifndef I_AST
+/** State machine input: Asterisk. */
+#line 39 "dkdbt.ctr"
+#define I_AST 1
+#else
+#line 39 "dkdbt.ctr"
+#error "Redefinition of I_AST"
+#endif
+
+#ifndef I_BS
+/** State machine input: Backslash. */
+#line 37 "dkdbt.ctr"
+#define I_BS 2
+#else
+#line 37 "dkdbt.ctr"
+#error "Redefinition of I_BS"
+#endif
+
+#ifndef I_BT
+/** State machine input: Backtick. */
+#line 42 "dkdbt.ctr"
+#define I_BT 3
+#else
+#line 42 "dkdbt.ctr"
+#error "Redefinition of I_BT"
+#endif
+
+#ifndef I_CL
+/** State machine input: Closing bracket. */
+#line 43 "dkdbt.ctr"
+#define I_CL 4
+#else
+#line 43 "dkdbt.ctr"
+#error "Redefinition of I_CL"
+#endif
+
+#ifndef I_COMMA
+/** State machine input: Comma. */
+#line 44 "dkdbt.ctr"
+#define I_COMMA 5
+#else
+#line 44 "dkdbt.ctr"
+#error "Redefinition of I_COMMA"
+#endif
+
+#ifndef I_DQ
+/** State machine input: Double quote. */
+#line 41 "dkdbt.ctr"
+#define I_DQ 6
+#else
+#line 41 "dkdbt.ctr"
+#error "Redefinition of I_DQ"
+#endif
+
+#ifndef I_MINUS
+/** State machine input: Minus sign. */
+#line 45 "dkdbt.ctr"
+#define I_MINUS 7
+#else
+#line 45 "dkdbt.ctr"
+#error "Redefinition of I_MINUS"
+#endif
+
+#ifndef I_NL
+/** State machine input: Newline. */
+#line 46 "dkdbt.ctr"
+#define I_NL 8
+#else
+#line 46 "dkdbt.ctr"
+#error "Redefinition of I_NL"
+#endif
+
+#ifndef I_Q
+/** State machine input: Single quote. */
+#line 40 "dkdbt.ctr"
+#define I_Q 9
+#else
+#line 40 "dkdbt.ctr"
+#error "Redefinition of I_Q"
+#endif
+
+#ifndef I_SL
+/** State machine input: Slash. */
+#line 38 "dkdbt.ctr"
+#define I_SL 10
+#else
+#line 38 "dkdbt.ctr"
+#error "Redefinition of I_SL"
+#endif
+
+#ifndef O_NL
+/** State machine output: Append newline to current output. */
+#line 50 "dkdbt.ctr"
+#define O_NL 0
+#else
+#line 50 "dkdbt.ctr"
+#error "Redefinition of O_NL"
+#endif
+
+#ifndef O_NORMAL
+/** State machine output: Normal output. */
+#line 49 "dkdbt.ctr"
+#define O_NORMAL 1
+#else
+#line 49 "dkdbt.ctr"
+#error "Redefinition of O_NORMAL"
+#endif
+
+/**@}*/
+
+/** Reset dkdbt_sql_split state machine.
+ @param st Pointer to state variable.
+*/
+static
+void
+dkdbt_sql_split_reset(int *st)
+{
+ if(st) { *st = ST_N; }
+}
+
+/** State machine dkdbt_sql_split step.
+ @param st Pointer to state variable.
+ @param in Input.
+ @return Transition output.
+*/
+static
+int
+dkdbt_sql_split_step(int *st, int in)
+{
+ int back = O_NORMAL;
+ if(st) {
+ int os;
+ int nf = 1;
+ int ns = ST_ERROR;
+ os = *st;
+ switch(os) {
+ case ST_BT: {
+ switch(in) {
+ case I_BS: {
+ ns = ST_BT_BS; back = O_NORMAL; nf = 0;
+ } break;
+ case I_BT: {
+ ns = ST_N; back = O_NORMAL; nf = 0;
+ } break;
+ }
+ } break;
+ case ST_CB: {
+ switch(in) {
+ case I_CL: {
+ ns = ST_CB; back = O_NORMAL; nf = 0;
+ } break;
+ case I_COMMA: {
+ ns = ST_CB_CO; back = O_NORMAL; nf = 0;
+ } break;
+ }
+ } break;
+ case ST_CB_CO: {
+ switch(in) {
+ case I_CL: {
+ ns = ST_CB; back = O_NL; nf = 0;
+ } break;
+ case I_NL: {
+ ns = ST_N; back = O_NORMAL; nf = 0;
+ } break;
+ }
+ } break;
+ case ST_CO: {
+ switch(in) {
+ case I_AST: {
+ ns = ST_CO_AST; back = O_NORMAL; nf = 0;
+ } break;
+ }
+ } break;
+ case ST_CO_AST: {
+ switch(in) {
+ case I_AST: {
+ ns = ST_CO_AST; back = O_NORMAL; nf = 0;
+ } break;
+ case I_SL: {
+ ns = ST_N; back = O_NORMAL; nf = 0;
+ } break;
+ }
+ } break;
+ case ST_DQ: {
+ switch(in) {
+ case I_BS: {
+ ns = ST_DQ_BS; back = O_NORMAL; nf = 0;
+ } break;
+ case I_DQ: {
+ ns = ST_N; back = O_NORMAL; nf = 0;
+ } break;
+ }
+ } break;
+ case ST_LCO: {
+ switch(in) {
+ case I_NL: {
+ ns = ST_N; back = O_NORMAL; nf = 0;
+ } break;
+ }
+ } break;
+ case ST_MINUS: {
+ switch(in) {
+ case I_MINUS: {
+ ns = ST_LCO; back = O_NORMAL; nf = 0;
+ } break;
+ }
+ } break;
+ case ST_N: {
+ switch(in) {
+ case I_BS: {
+ ns = ST_N_BS; back = O_NORMAL; nf = 0;
+ } break;
+ case I_BT: {
+ ns = ST_BT; back = O_NORMAL; nf = 0;
+ } break;
+ case I_CL: {
+ ns = ST_CB; back = O_NORMAL; nf = 0;
+ } break;
+ case I_DQ: {
+ ns = ST_DQ; back = O_NORMAL; nf = 0;
+ } break;
+ case I_MINUS: {
+ ns = ST_MINUS; back = O_NORMAL; nf = 0;
+ } break;
+ case I_Q: {
+ ns = ST_Q; back = O_NORMAL; nf = 0;
+ } break;
+ case I_SL: {
+ ns = ST_SL; back = O_NORMAL; nf = 0;
+ } break;
+ }
+ } break;
+ case ST_Q: {
+ switch(in) {
+ case I_BS: {
+ ns = ST_Q_BS; back = O_NORMAL; nf = 0;
+ } break;
+ case I_Q: {
+ ns = ST_N; back = O_NORMAL; nf = 0;
+ } break;
+ }
+ } break;
+ case ST_SL: {
+ switch(in) {
+ case I_AST: {
+ ns = ST_CO; back = O_NORMAL; nf = 0;
+ } break;
+ case I_SL: {
+ ns = ST_SL; back = O_NORMAL; nf = 0;
+ } break;
+ }
+ } break;
+ }
+ if(nf) {
+ if(os == ST_N) {
+ ns = ST_N; back = O_NORMAL;
+ } else {
+ if(os == ST_CB) {
+ ns = ST_N; back = O_NORMAL;
+ } else {
+ if(os == ST_CB_CO) {
+ ns = ST_N; back = O_NL;
+ } else {
+ if(os == ST_N_BS) {
+ ns = ST_N; back = O_NORMAL;
+ } else {
+ if(os == ST_SL) {
+ ns = ST_N; back = O_NORMAL;
+ } else {
+ if(os == ST_CO) {
+ ns = ST_CO; back = O_NORMAL;
+ } else {
+ if(os == ST_CO_AST) {
+ ns = ST_CO; back = O_NORMAL;
+ } else {
+ if(os == ST_MINUS) {
+ ns = ST_N; back = O_NORMAL;
+ } else {
+ if(os == ST_LCO) {
+ ns = ST_LCO; back = O_NORMAL;
+ } else {
+ if(os == ST_Q) {
+ ns = ST_Q; back = O_NORMAL;
+ } else {
+ if(os == ST_Q_BS) {
+ ns = ST_Q; back = O_NORMAL;
+ } else {
+ if(os == ST_DQ) {
+ ns = ST_DQ; back = O_NORMAL;
+ } else {
+ if(os == ST_DQ_BS) {
+ ns = ST_DQ; back = O_NORMAL;
+ } else {
+ if(os == ST_BT) {
+ ns = ST_BT; back = O_NORMAL;
+ } else {
+ if(os == ST_BT_BS) {
+ ns = ST_BT; back = O_NORMAL;
+ } else {
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ *st = ns;
+ } else {
+ }
+ return back;
+}
+
+
+#line 144 "dkdbt.ctr"
+
+#include "dk3all.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4vers.h"
+#include "dk3ma.h"
+
+
+
+
+
+#line 155 "dkdbt.ctr"
+
+
+
+#ifdef DK3_USE_DB
+#undef DK3_USE_DB
+#endif
+#ifdef DK3_USE_NDBM
+#undef DK3_USE_NDBM
+#endif
+
+#if DK3_HAVE_DB_H
+#include <db.h>
+/** Use Berkeley DB.
+*/
+#define DK3_USE_DB 1
+#endif
+
+#if DK3_HAVE_NDBM_H
+#include <ndbm.h>
+/** Use NDBM.
+*/
+#define DK3_USE_NDBM 1
+#endif
+
+
+
+/** Job structure.
+*/
+typedef struct {
+ dk3_app_t *app; /**< Application structure. */
+ dkChar const * const *msg; /**< Localized messages. */
+ dk3_option_set_t *opt; /**< Options. */
+ dkChar const * const *xargv; /**< Command line arguments array. */
+ dk3_dbi_t *in; /**< Input database. */
+ dk3_dbi_t *out; /**< Output database. */
+ dk3_stream_t *os; /**< Output stream. */
+ size_t ls; /**< Line size. */
+ int xargc; /**< Number of command line arguments. */
+ int f_add; /**< Flag: Add to existing database. */
+ int enc_s; /**< Encoding for stdin. */
+ int enc_f; /**< Encoding for files. */
+ int ie; /**< Default system encoding. */
+ int oe; /**< Output encoding. */
+ char comm; /**< Character to start comment line. */
+} DKDBT_JOB;
+
+
+
+/** Application group name.
+*/
+static dkChar const dkt_group_name[] = { dkT("dktools") };
+
+
+
+/** File name for string table file.
+*/
+static dkChar const dkdbt_stt_file_name[] = { dkT("dkdbtool.str") };
+
+
+
+/** File name for help file.
+*/
+static dkChar const dkdbt_help_file_name[] = { dkT("dkdbtool.txt") };
+
+
+
+/** Version number string.
+*/
+static dkChar const dkdbt_version[] = {
+dkT("dkdbt ") DKT_VERSION_DK
+};
+
+
+
+/** Options for the copy operation.
+*/
+static dk3_option_t const dkdbt_copy_options[] = {
+ { dkT('a'), dkT("append"), 0 }
+};
+
+/** Number of elements in dkdbt_copy_options.
+*/
+static size_t const dkdbt_sz_copy_options =
+sizeof(dkdbt_copy_options)/sizeof(dk3_option_t);
+
+
+
+/** Options for the make operation.
+*/
+static dk3_option_t const dkdbt_make_options[] = {
+ { dkT('a'), dkT("append"), 0 },
+ { dkT('c'), dkT("comment"), 1 },
+ { dkT('i'), dkT("input-encoding"), 1 },
+ { dkT('l'), dkT("line-size"), 1 }
+};
+
+/** Number of elements in dkdbt_make_options.
+*/
+static size_t const dkdbt_sz_make_options =
+sizeof(dkdbt_make_options)/sizeof(dk3_option_t);
+
+
+
+/** Options for the reverse make operation.
+*/
+static dk3_option_t const dkdbt_text_options[] = {
+ { dkT('o'), dkT("output-encoding"), 1 },
+};
+
+/** Number of elements in dkdbt_text_options.
+*/
+static size_t const dkdbt_sz_text_options =
+sizeof(dkdbt_text_options)/sizeof(dk3_option_t);
+
+
+
+/** Help text to show if help text file is not found.
+*/
+static dkChar const * const dkdbt_help_text[] = {
+dkT(""),
+dkT("dkdbt - Dirk Krause's database tool"),
+dkT("==================================="),
+dkT(""),
+dkT("Usage"),
+dkT("-----"),
+dkT(""),
+dkT("dkdbt copy [-a] <source-db-name> <destination-db-name>"),
+dkT("dkdbt make [-c <char>] [-a] [-i <encoding>] <destination-db-name> [<file(s)>]"),
+dkT("dkdbt text [-o <encoding>] <source-db-name> [<file>]"),
+dkT("dkdbt split-sql-lines [<inputfile> [<outputfile>]]"),
+dkT(""),
+dkT("dkdbt help"),
+dkT("dkdbt version"),
+dkT("dkdbt license"),
+dkT("dkdbt features"),
+dkT(""),
+dkT("In a copy operation a new copy of the database is created, probably using"),
+dkT("another database type. By default the destination database is truncated"),
+dkT("when opening it so the destination database contains exactly the same"),
+dkT("records as the source database."),
+dkT("The -a option switches to add mode, the records from the source database"),
+dkT("are added to the destination database. Records for existing keys are"),
+dkT("replaced, records for keys not yet existing are inserted."),
+dkT(""),
+dkT("A make operation creates a database from text input. Each input line"),
+dkT("contains one record. The first text word in the line is the key, all"),
+dkT("remaining text beginning with the second text word is the value."),
+dkT("The -c option can be used to specify a special character to start"),
+dkT("a comment. All lines started by the specified character are comment lines"),
+dkT("and thus ignored."),
+dkT("The -i option can be used to specify the input encoding."),
+dkT("The files specified on the command line after the destination database name"),
+dkT("are used as input files. If no files are specified, standard input is used."),
+dkT(""),
+dkT("The text operation is a reverse make operation. It writes data from the"),
+dkT("database as a sequence of lines. The -o option can be used to specify"),
+dkT("the output encoding."),
+dkT(""),
+dkT("The split-sql-lines operation can be used to split overlong lines in"),
+dkT("mysqldump output."),
+dkT(""),
+dkT("The help operation shows this help text."),
+dkT(""),
+dkT("The version operation shows the version number."),
+dkT(""),
+dkT("The license-terms operation shows the license terms."),
+dkT(""),
+dkT("The features operation lists the database types supported by the program."),
+dkT(""),
+NULL
+
+
+#line 326 "dkdbt.ctr"
+};
+
+
+
+/** Default message texts, used if no string table file is found.
+*/
+static dkChar const * const dkdbt_message_texts[] = {
+/* 0 */
+dkT("The following database types are supported:"),
+
+/* 1 */
+dkT("mem\tIn-memory database from the dktools project."),
+
+/* 2 */
+dkT("bdb\tBerkeley DB: An embedded database programmatic toolkit."),
+
+/* 3 */
+dkT("NDBM\tThe NDBM database."),
+
+/* 4 */
+dkT("Missing dkdbt command!\nType \"dkdbt help\" for a list of commands."),
+
+/* 5 */
+dkT("Unknown command: \""),
+
+/* 6 */
+dkT("\"!\nType \"dkdbt help\" for a list of commands."),
+
+/* 7 */
+dkT("Failed to expand file name pattern \""),
+
+/* 8 */
+dkT("\"!"),
+
+/* 9 */
+dkT("No input files found!"),
+
+/* 10 */
+dkT("Wrong file type!"),
+
+/* 11 */
+dkT("Error in SQL input!"),
+
+/* 12 */
+dkT("Error while traversing data!"),
+
+/* 13 */
+dkT("Key data is not text!"),
+
+/* 14 */
+dkT("Value data is not text!"),
+
+/* 15 */
+dkT("Failed to print key!"),
+
+/* 16 */
+dkT("Failed to print space!"),
+
+/* 17 */
+dkT("Failed to print value!"),
+
+/* 18 */
+dkT("Failed to print newline!"),
+
+/* 19 */
+dkT("Missing destination database name!"),
+
+/* 20 */
+dkT("Error(s) occured while processing input!"),
+
+/* 21 */
+dkT("Input and output database file name required!"),
+
+/* 22 */
+dkT("Missing input file name!"),
+
+/* 23 */
+dkT("Missing output file name!"),
+
+/* 24 */
+dkT("Error(s) occured while copying data!"),
+
+NULL
+
+
+#line 429 "dkdbt.ctr"
+};
+
+
+
+/** Commands for dkdbt.
+*/
+static dkChar const * const dkdbt_commands[] = {
+/* 0 */
+dkT("h$elp"),
+
+/* 1 */
+dkT("--help"),
+
+/* 2 */
+dkT("v$ersion"),
+
+/* 3 */
+dkT("--version"),
+
+/* 4 */
+dkT("l$icense"),
+
+/* 5 */
+dkT("--license"),
+
+/* 6 */
+dkT("f$eatures"),
+
+/* 7 */
+dkT("--features"),
+
+/* 8 */
+dkT("c$opy"),
+
+/* 9 */
+dkT("m$ake"),
+
+/* 10 */
+dkT("t$ext"),
+
+/* 11 */
+dkT("s$plit-sql-lines"),
+
+/* 12 */
+dkT("split-sql"),
+
+/* 13 */
+dkT("--license-terms"),
+
+/* 14 */
+dkT("-L"),
+
+NULL
+
+
+#line 480 "dkdbt.ctr"
+};
+
+
+
+/** Licensing overview, list of all sources.
+*/
+static dkChar const * const dkdbt_overview_license[] = {
+dkT("This software uses code from the following projects either directly"),
+dkT("or as a library:"),
+dkT(""),
+dkT("dktools\t\tDirk Krause's tools and libraries."),
+dkT("\t\tSee http://dktools.sourceforge.net for more information."),
+#if DK3_USE_DB
+dkT(""),
+dkT("Berkeley DB\tBerkeley DB: An embedded database programmatic toolkit."),
+dkT("\t\tSee http://www.oracle.com for more information."),
+#endif
+#if DK3_USE_NDBM
+dkT(""),
+dkT("NDBM\t\tA library implementing the NDBM API."),
+dkT("\t\tLicense conditions depend on the NDBM library you use."),
+#endif
+dkT(""),
+NULL
+};
+
+
+
+/** License terms for the dktools project itself.
+*/
+static dkChar const * const dkt_license[] = {
+dkT("License for the dktools project"),
+dkT("==============================="),
+dkT("Copyright (c) 2011-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms,"),
+dkT("with or without modification, are permitted provided"),
+dkT("that the following conditions are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above"),
+dkT(" copyright notice, this list of conditions and the"),
+dkT(" following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above "),
+dkT(" copyright notice, this list of conditions and the following"),
+dkT(" disclaimer in the documentation and/or other materials"),
+dkT(" provided with the distribution."),
+dkT("* Neither the name of the copyright holder(s) nor the names of"),
+dkT(" contributors may be used to endorse or promote"),
+dkT(" products derived from this software without specific"),
+dkT(" prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND"),
+dkT("CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,"),
+dkT("INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF"),
+dkT("MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE"),
+dkT("DISCLAIMED."),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE"),
+dkT("LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,"),
+dkT("EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT"),
+dkT("LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;"),
+dkT("LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)"),
+dkT("HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN"),
+dkT("CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE"),
+dkT("OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS"),
+dkT("SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH"),
+dkT("DAMAGE."),
+dkT(""),
+NULL
+
+
+#line 550 "dkdbt.ctr"
+};
+
+
+
+#if DK3_USE_DB
+/** License conditions for the Berkeley DB.
+*/
+static dkChar const * const dkbtt_bdb_license[] = {
+dkT(""),
+dkT("License for the Berkeley DB"),
+dkT("==========================="),
+dkT(""),
+dkT("The license that applies to your copy of the Berkeley DB software may be"),
+dkT("found in the \"LICENSE\" file included in each Berkeley DB distribution."),
+dkT("For a license to use the Berkeley DB software under conditions other than"),
+dkT("those described in the \"LICENSE\" file, or to purchase support for the"),
+dkT("Berkeley DB software, please send email to berkeleydb-info_us@oracle.com ."),
+dkT("Copyright (c) 1996,2009 Oracle. All rights reserved."),
+dkT(""),
+dkT("/*-"),
+dkT(" * $Id: LICENSE,v 12.9 2008/02/07 17:12:17 mark Exp $"),
+dkT(" */"),
+dkT(""),
+dkT("The following is the license that applies to this copy of the Berkeley DB"),
+dkT("software. For a license to use the Berkeley DB software under conditions"),
+dkT("other than those described here, or to purchase support for this software,"),
+dkT("please contact Oracle at berkeleydb-info_us@oracle.com."),
+dkT(""),
+dkT("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="),
+dkT("/*"),
+dkT(" * Copyright (c) 1990,2008 Oracle. All rights reserved."),
+dkT(" *"),
+dkT(" * Redistribution and use in source and binary forms, with or without"),
+dkT(" * modification, are permitted provided that the following conditions"),
+dkT(" * are met:"),
+dkT(" * 1. Redistributions of source code must retain the above copyright"),
+dkT(" * notice, this list of conditions and the following disclaimer."),
+dkT(" * 2. Redistributions in binary form must reproduce the above copyright"),
+dkT(" * notice, this list of conditions and the following disclaimer in the"),
+dkT(" * documentation and/or other materials provided with the distribution."),
+dkT(" * 3. Redistributions in any form must be accompanied by information on"),
+dkT(" * how to obtain complete source code for the DB software and any"),
+dkT(" * accompanying software that uses the DB software. The source code"),
+dkT(" * must either be included in the distribution or be available for no"),
+dkT(" * more than the cost of distribution plus a nominal fee, and must be"),
+dkT(" * freely redistributable under reasonable conditions. For an"),
+dkT(" * executable file, complete source code means the source code for all"),
+dkT(" * modules it contains. It does not include source code for modules or"),
+dkT(" * files that typically accompany the major components of the operating"),
+dkT(" * system on which the executable file runs."),
+dkT(" *"),
+dkT(" * THIS SOFTWARE IS PROVIDED BY ORACLE ``AS IS'' AND ANY EXPRESS OR"),
+dkT(" * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED"),
+dkT(" * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR"),
+dkT(" * NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL ORACLE BE LIABLE"),
+dkT(" * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR"),
+dkT(" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF"),
+dkT(" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR"),
+dkT(" * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,"),
+dkT(" * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE"),
+dkT(" * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN"),
+dkT(" * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+dkT(" */"),
+dkT("/*"),
+dkT(" * Copyright (c) 1990, 1993, 1994, 1995"),
+dkT(" *\tThe Regents of the University of California. All rights reserved."),
+dkT(" *"),
+dkT(" * Redistribution and use in source and binary forms, with or without"),
+dkT(" * modification, are permitted provided that the following conditions"),
+dkT(" * are met:"),
+dkT(" * 1. Redistributions of source code must retain the above copyright"),
+dkT(" * notice, this list of conditions and the following disclaimer."),
+dkT(" * 2. Redistributions in binary form must reproduce the above copyright"),
+dkT(" * notice, this list of conditions and the following disclaimer in the"),
+dkT(" * documentation and/or other materials provided with the distribution."),
+dkT(" * 3. Neither the name of the University nor the names of its contributors"),
+dkT(" * may be used to endorse or promote products derived from this software"),
+dkT(" * without specific prior written permission."),
+dkT(" *"),
+dkT(" * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND"),
+dkT(" * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT(" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT(" * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE"),
+dkT(" * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT(" * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS"),
+dkT(" * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)"),
+dkT(" * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT"),
+dkT(" * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY"),
+dkT(" * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF"),
+dkT(" * SUCH DAMAGE."),
+dkT(" */"),
+dkT("/*"),
+dkT(" * Copyright (c) 1995, 1996"),
+dkT(" *\tThe President and Fellows of Harvard University. All rights reserved."),
+dkT(" *"),
+dkT(" * Redistribution and use in source and binary forms, with or without"),
+dkT(" * modification, are permitted provided that the following conditions"),
+dkT(" * are met:"),
+dkT(" * 1. Redistributions of source code must retain the above copyright"),
+dkT(" * notice, this list of conditions and the following disclaimer."),
+dkT(" * 2. Redistributions in binary form must reproduce the above copyright"),
+dkT(" * notice, this list of conditions and the following disclaimer in the"),
+dkT(" * documentation and/or other materials provided with the distribution."),
+dkT(" * 3. Neither the name of the University nor the names of its contributors"),
+dkT(" * may be used to endorse or promote products derived from this software"),
+dkT(" * without specific prior written permission."),
+dkT(" *"),
+dkT(" * THIS SOFTWARE IS PROVIDED BY HARVARD AND ITS CONTRIBUTORS ``AS IS'' AND"),
+dkT(" * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT(" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT(" * ARE DISCLAIMED. IN NO EVENT SHALL HARVARD OR ITS CONTRIBUTORS BE LIABLE"),
+dkT(" * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT(" * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS"),
+dkT(" * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)"),
+dkT(" * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT"),
+dkT(" * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY"),
+dkT(" * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF"),
+dkT(" * SUCH DAMAGE."),
+dkT(" */"),
+dkT("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="),
+dkT("/***"),
+dkT(" * ASM: a very small and fast Java bytecode manipulation framework"),
+dkT(" * Copyright (c) 2000-2005 INRIA, France Telecom"),
+dkT(" * All rights reserved."),
+dkT(" *"),
+dkT(" * Redistribution and use in source and binary forms, with or without"),
+dkT(" * modification, are permitted provided that the following conditions"),
+dkT(" * are met:"),
+dkT(" * 1. Redistributions of source code must retain the above copyright"),
+dkT(" * notice, this list of conditions and the following disclaimer."),
+dkT(" * 2. Redistributions in binary form must reproduce the above copyright"),
+dkT(" * notice, this list of conditions and the following disclaimer in the"),
+dkT(" * documentation and/or other materials provided with the distribution."),
+dkT(" * 3. Neither the name of the copyright holders nor the names of its"),
+dkT(" * contributors may be used to endorse or promote products derived from"),
+dkT(" * this software without specific prior written permission."),
+dkT(" *"),
+dkT(" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\""),
+dkT(" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT(" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT(" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE"),
+dkT(" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR"),
+dkT(" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF"),
+dkT(" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS"),
+dkT(" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN"),
+dkT(" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)"),
+dkT(" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF"),
+dkT(" * THE POSSIBILITY OF SUCH DAMAGE."),
+dkT(" */"),
+dkT(""),
+NULL
+
+
+#line 702 "dkdbt.ctr"
+};
+#endif
+
+
+
+#if DK3_USE_NDBM
+/** License notice for NDBM libraries.
+*/
+static dkChar const * const dkdbt_ndbm_license[] = {
+dkT("License for the NDBM software"),
+dkT("============================="),
+dkT("NDBM is an API implemented by different libraries from different vendors."),
+dkT("The most common implementations are"),
+dkT("- NDBM software contained in the system distribution of commercial"),
+dkT(" UNIX operating systems, and"),
+dkT("- the NDBM compatibility library of the GDBM software."),
+dkT("Your use of the dktools software together with NDBM libraries must be in"),
+dkT("compliance to the license conditions of the NDBM library used."),
+dkT(""),
+NULL
+
+
+#line 723 "dkdbt.ctr"
+};
+#endif
+
+
+
+/** Keywords used by this module.
+*/
+static dkChar const * const dkdbt_kw[] = {
+/* 0 */ dkT("w"),
+/* 1 */ dkT(" "),
+/* 2 */ dkT("\n"),
+/* 3 */ dkT("DB: mem"),
+/* 4 */ dkT(" bdb"),
+/* 5 */ dkT(" ndbm"),
+};
+
+
+
+/** Exit code.
+*/
+static int exval = 1;
+
+
+
+/** Initialize job structure.
+ @param j Job structure to initialize.
+ @param app Application structure.
+ @param msg Localized message texts.
+ @param xargc Number of command line arguments.
+ @param xargv Command line arguments array.
+*/
+static
+void
+dkdbt_job_init(
+ DKDBT_JOB *j,
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ int xargc,
+ dkChar const * const *xargv
+)
+{
+ j->app = app;
+ j->msg = msg;
+ j->opt = NULL;
+ j->xargc = xargc;
+ j->xargv = xargv;
+ j->ls = 1024;
+ j->f_add = 0;
+ j->enc_s = dk3app_get_input_stdin_encoding(j->app);
+ j->enc_f = dk3app_get_input_file_encoding(j->app);
+ j->comm = '\0';
+ j->in = NULL;
+ j->out = NULL;
+}
+
+
+
+/** Clean up job structure.
+ @param j Job structure to clean up.
+*/
+static
+void
+dkdbt_job_end(DKDBT_JOB *j)
+{
+ if(j->opt) {
+ dk3opt_close(j->opt);
+ } j->opt = NULL;
+}
+
+
+
+/** Show help text, either from file or default text.
+ @param app Application structure.
+*/
+static
+void
+dkdbt_show_help(dk3_app_t *app)
+{
+ dk3app_help(app, dkdbt_help_file_name, dkdbt_help_text);
+}
+
+
+
+/** Show license terms.
+ @param app Application structure.
+*/
+static
+void
+dkdbt_show_license(dk3_app_t *app)
+{
+ dkChar const * const *sptr;
+ dk3sf_initialize_stdout();
+ sptr = dkdbt_overview_license;
+ while(*sptr) {
+ dk3sf_fputs(*(sptr++), stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ sptr = dkt_license;
+ while(*sptr) {
+ dk3sf_fputs(*(sptr++), stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+#if DK3_USE_DB
+ sptr = dkbtt_bdb_license;
+ while(*sptr) {
+ dk3sf_fputs(*(sptr++), stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+#endif
+#if DK3_USE_NDBM
+ sptr = dkdbt_ndbm_license;
+ while(*sptr) {
+ dk3sf_fputs(*(sptr++), stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+#endif
+}
+
+
+
+/** Show features.
+ @param app Application structure.
+ @param msg Localized message texts.
+*/
+static
+void
+dkdbt_show_features(dk3_app_t *app, dkChar const * const *msg)
+{
+ dk3sf_initialize_stdout();
+ dk3sf_fputs(msg[0], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ dk3sf_fputs(msg[1], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+#if DK3_USE_DB
+ dk3sf_fputs(msg[2], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+#endif
+#if DK3_USE_NDBM
+ dk3sf_fputs(msg[3], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+#endif
+}
+
+
+
+/** Show version number.
+ @param app Application structure.
+*/
+static
+void
+dkdbt_show_version(dk3_app_t *app)
+{
+ dk3sf_initialize_stdout();
+ dk3sf_fputs(dkdbt_version, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ dk3sf_fputs(dkdbt_kw[3], stdout);
+ if(dk3dbi_type_supported(DK3_DB_TYPE_BDB)) {
+ dk3sf_fputs(dkdbt_kw[4], stdout);
+ }
+ if(dk3dbi_type_supported(DK3_DB_TYPE_NDBM)) {
+ dk3sf_fputs(dkdbt_kw[5], stdout);
+ }
+ dk3sf_fputs(dkdbt_kw[2], stdout);
+}
+
+
+
+/** Traversal function to copy all records to new database.
+ @param obj Job structure.
+ @param key Record key.
+ @param val Record value.
+ @return 1 on success, 0 on error (can continue), -1 on error (abort).
+*/
+static
+int
+dkdbt_copy_data(void *obj, dk3_datum_t *key, dk3_datum_t *val)
+{
+ DKDBT_JOB *j; /* Copy job. */
+ int back;
+
+ j = (DKDBT_JOB *)obj;
+ back = dk3dbi_set(j->out, key, val);
+ return back;
+}
+
+
+
+/** Copy function.
+ @param app Application structure.
+ @param msg Localized message texts.
+ @param xargc Number of command line arguments.
+ @param xargv Command line arguments array.
+*/
+static
+void
+dkdbt_copy(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ int xargc,
+ dkChar const * const *xargv
+)
+{
+ DKDBT_JOB dkdbtj; /* Copy job. */
+ dkChar const *inname; /* Input database name. */
+ dkChar const *outname; /* Output database name. */
+ int ec; /* Error code. */
+ int res; /* Operation result. */
+
+ dkdbt_job_init(&dkdbtj, app, msg, xargc, xargv);
+ ec = 0;
+ dkdbtj.opt = dk3opt_open_app(
+ dkdbt_copy_options,
+ dkdbt_sz_copy_options,
+ dkT('\0'),
+ NULL,
+ (xargc - 1),
+ &(xargv[1]),
+ app
+ );
+ if(dkdbtj.opt) {
+ if(dk3opt_get_error_code(dkdbtj.opt) == 0) {
+ if(dk3opt_is_set(dkdbtj.opt, dkT('a'))) {
+ dkdbtj.f_add = 1;
+ }
+ if(dk3opt_get_num_args(dkdbtj.opt) >= 3) {
+ inname = dk3opt_get_arg(dkdbtj.opt, 1);
+ if(inname) {
+ outname = dk3opt_get_arg(dkdbtj.opt, 2);
+ if(outname) {
+ dkdbtj.in = dk3dbi_open_app(
+ inname,
+ DK3_DB_TYPE_UNKNOWN,
+ DK3_DB_ACCESS_READ,
+ &ec,
+ app
+ );
+ if(dkdbtj.in) {
+ if(dkdbtj.f_add) {
+ dkdbtj.out = dk3dbi_open_app(
+ outname,
+ DK3_DB_TYPE_UNKNOWN,
+ DK3_DB_ACCESS_WRITE,
+ &ec,
+ app
+ );
+ } else {
+ dkdbtj.out = dk3dbi_open_truncate_app(
+ outname,
+ DK3_DB_TYPE_UNKNOWN,
+ DK3_DB_ACCESS_WRITE,
+ &ec,
+ app
+ );
+ }
+ if(dkdbtj.out) {
+ res = dk3dbi_traverse(
+ dkdbtj.in, (void *)(&dkdbtj), dkdbt_copy_data
+ );
+ if(res) {
+ exval = 0;
+ } else {
+ /* ERROR While copying */
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 24);
+ }
+ dk3dbi_close(dkdbtj.out);
+ } else {
+ /* ERROR: Failed to open output database! */
+ }
+ dk3dbi_close(dkdbtj.in);
+ } else {
+ /* ERROR: Failed to open input database! */
+ }
+ } else {
+ /* ERROR: Output file name missing! */
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 23);
+ }
+ } else {
+ /* ERROR: Missing input file name! */
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 22);
+ }
+ if(dk3opt_get_num_args(dkdbtj.opt) > 3) {
+ dk3app_log_i3(
+ app, DK3_LL_WARNING, 164, 165,
+ dk3opt_get_arg(dkdbtj.opt, 3)
+ );
+ }
+ } else {
+ /* ERROR: File name missing! */
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 22);
+ }
+ } else {
+ /* ERROR: Error during option set creation! */
+ }
+ } else {
+ /* ERROR: Failed to create option set! */
+ }
+ dkdbt_job_end(&dkdbtj);
+}
+
+
+
+/** Set input or output encoding from command line arguments.
+ @param app Application structure.
+ @param enc Variable to set.
+ @param val Encoding name found on command line.
+ @param de Default encoding.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkdbt_set_encoding(
+ dk3_app_t *app,
+ int *enc,
+ dkChar const *val,
+ int de
+)
+{
+ int back = 0;
+ int i = -1; /* Index of string in array of encodings. */
+
+ if((app) && (enc)) {
+ if(val) {
+ i = dk3enc_get_text_encoding_app(val, app);
+ if(i > -1) {
+ *enc = i;
+ back = 1;
+ } else {
+ *enc = de;
+ }
+ } else {
+ *enc = de;
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Handler function for one line.
+ @param vj Job structure casted to void *.
+ @param il Input line to process.
+ @return 1=OK, 0=error, can continue, -1=error, abort processing.
+*/
+static
+int
+dkdbt_make_line_handler(void *vj, dkChar *il)
+{
+ DKDBT_JOB *j; /* Make job. */
+ dkChar *ptr; /* Pointer to modify string. */
+ dkChar *p1; /* Key pointer. */
+ dkChar *p2; /* Value pointer. */
+ int back = 0;
+ int comm = 0; /* Flag: Check lines for comments. */
+
+
+#line 1078 "dkdbt.ctr"
+ j = (DKDBT_JOB *)vj;
+ ptr = il;
+ while(*ptr) {
+ if(*ptr == dkT('\n')) *ptr = dkT('\0');
+ if(*ptr == dkT('\r')) *ptr = dkT('\0');
+ ptr++;
+ }
+
+#line 1085 "dkdbt.ctr"
+ p1 = dk3str_start(il, NULL);
+ if(p1) {
+ if(j->comm) {
+ if(*p1 == j->comm) {
+ comm = 1;
+ back = 1;
+ }
+ }
+ if(!(comm)) {
+ p2 = dk3str_next(p1, NULL);
+ if(p2) {
+ dk3str_chomp(p2, NULL);
+ back = dk3dbi_set_string(j->out, p1, p2);
+ } else {
+ dk3dbi_delete_string(j->out, p1);
+ back = 1;
+ }
+ }
+ } else {
+
+#line 1104 "dkdbt.ctr"
+ back = 1;
+ }
+
+
+#line 1107 "dkdbt.ctr"
+ return back;
+}
+
+
+
+/** Run make operation.
+ @param j Job structure.
+ @param buffer Line buffer.
+ @param szbuffer Size of @a buffer (number of characters).
+*/
+static
+void
+dkdbt_make_with_buffer(DKDBT_JOB *j, dkChar *buffer, size_t szbuffer)
+{
+ dkChar bu[DK3_MAX_PATH]; /* Local file name copy. */
+ dk3_dir_t *fne; /* File name expander. */
+ dkChar const *outname; /* Output database name. */
+ dkChar const *fn; /* Current input file name. */
+ dkChar const *en; /* Entry name. */
+ dk3_um_t nf; /* Number of files available. */
+ int nargs; /* Number of command line arguments. */
+ int i; /* Index of current file to process. */
+ int ec; /* Error code. */
+ int res; /* Result for one file. */
+
+
+#line 1132 "dkdbt.ctr"
+ ec = 0;
+ nargs = dk3opt_get_num_args(j->opt);
+ if(nargs > 1) {
+
+#line 1135 "dkdbt.ctr"
+ outname = dk3opt_get_arg(j->opt, 1);
+ if(outname) {
+
+#line 1137 "dkdbt.ctr"
+ if(j->f_add) {
+
+#line 1138 "dkdbt.ctr"
+ j->out = dk3dbi_open_app(
+ outname, DK3_DB_TYPE_UNKNOWN, DK3_DB_ACCESS_WRITE,
+ &ec, j->app
+ );
+ } else {
+
+#line 1143 "dkdbt.ctr"
+ j->out = dk3dbi_open_truncate_app(
+ outname, DK3_DB_TYPE_UNKNOWN, DK3_DB_ACCESS_WRITE,
+ &ec, j->app
+ );
+ }
+ if(j->out) {
+
+#line 1149 "dkdbt.ctr"
+ if(nargs > 2) {
+
+#line 1150 "dkdbt.ctr"
+ exval = 0;
+ for(i = 2; i < nargs; i++) {
+
+#line 1152 "dkdbt.ctr"
+ fn = dk3opt_get_arg(j->opt, i);
+ if(fn) {
+
+#line 1154 "dkdbt.ctr"
+ if(dk3str_len(fn) < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy_not_overlapped(bu, fn);
+ dk3str_correct_filename(bu);
+ if(dk3sf_must_expand(bu)) {
+ fne = dk3dir_fne_open_app(bu, j->app);
+ if(fne) {
+ nf = dk3dir_get_number_of_files(fne);
+ if(nf > 0) {
+ while(dk3dir_get_next_file(fne)) {
+ en = dk3dir_get_fullname(fne);
+ if(en) {
+ res = dk3stream_process_filename_lines_app(
+ (void *)j, dkdbt_make_line_handler, en,
+ buffer, szbuffer,
+ dk3app_get_encoding(j->app), j->enc_f, j->app
+ );
+ if(res < 1) {
+ exval = 1;
+ /* ERROR: Error while processing input! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 20);
+ }
+ } else {
+ /* BUG: Should not happen. */
+ }
+ }
+ } else {
+ exval = 1;
+ /* ERROR: No matching file name! */
+ dk3app_log_i3(j->app, DK3_LL_ERROR, 215, 216, bu);
+ }
+ dk3dir_close(fne);
+ } else {
+ /* ERROR: File name expansion failed! */
+ exval = 1;
+ }
+ } else {
+ res = dk3stream_process_filename_lines_app(
+ (void *)j, dkdbt_make_line_handler, bu,
+ buffer, szbuffer, dk3app_get_encoding(j->app),
+ j->enc_f, j->app
+ );
+ if(res < 1) {
+ /* ERROR: Error while processing input! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 20);
+ exval = 1;
+ }
+ }
+ } else {
+ /* ERROR: File name too large! */
+ dk3app_log_i3(j->app, DK3_LL_ERROR, 65, 66, fn);
+ exval = 1;
+ }
+ } else {
+
+#line 1207 "dkdbt.ctr"
+ /* BUG: Should not happen. */
+ exval = 1;
+ }
+ }
+ } else {
+
+#line 1212 "dkdbt.ctr"
+ res = dk3app_process_stdin_lines(
+ j->app, (void *)j, dkdbt_make_line_handler,
+ buffer, szbuffer, j->enc_s
+ );
+ if(res) {
+ exval = 0;
+ } else {
+
+#line 1219 "dkdbt.ctr"
+ /* ERROR: Error while processing input! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 20);
+ }
+ }
+ dk3dbi_close(j->out); j->out = NULL;
+ } else {
+
+#line 1225 "dkdbt.ctr"
+ /* ERROR: Failed to open database! */
+ }
+ } else {
+
+#line 1228 "dkdbt.ctr"
+ /* ERROR: Missing destination database name! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 19);
+ }
+ } else {
+
+#line 1232 "dkdbt.ctr"
+ /* ERROR: Missing destination database name! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 19);
+ }
+
+#line 1235 "dkdbt.ctr"
+}
+
+
+
+/** Run make operation with automatic default size buffer.
+ @param j Job structure.
+*/
+static
+void
+dkdbt_make_with_auto_buffer(DKDBT_JOB *j)
+{
+ dkChar buffer[1024]; /* Buffer for input lines. */
+
+ dkdbt_make_with_buffer(j, buffer, DK3_SIZEOF(buffer,dkChar));
+}
+
+
+
+/** Run make operation, allocate buffer of given size.
+ @param j Job structure.
+*/
+static
+void
+dkdbt_make_with_allocated_buffer(DKDBT_JOB *j)
+{
+ dkChar *bu; /* Buffer for input lines. */
+
+ bu = dk3_new_app(dkChar,j->ls,j->app);
+ if(bu) {
+ dkdbt_make_with_buffer(j, bu, j->ls);
+ dk3_delete(bu);
+ } else {
+ /* ERROR: Memory! */
+ }
+}
+
+
+
+/** Make operation.
+ @param app Application structure.
+ @param msg Localized message texts.
+ @param xargc Number of command line arguments.
+ @param xargv Command line arguments array.
+*/
+static
+void
+dkdbt_make(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ int xargc,
+ dkChar const * const *xargv
+)
+{
+ DKDBT_JOB dkdbtj; /* Make job. */
+ dkChar const *arg; /* Option argument. */
+#if VERSION_BEFORE_20140809
+ unsigned long ul; /* Line size as unsigned long. */
+#endif
+ size_t ls; /* Line size as size_t. */
+ int ok; /* Flag: No errors found. */
+ int res; /* Operation result. */
+
+
+#line 1297 "dkdbt.ctr"
+ ok = 1;
+ dkdbt_job_init(&dkdbtj, app, msg, xargc, xargv);
+ dkdbtj.opt = dk3opt_open_app(
+ dkdbt_make_options,
+ dkdbt_sz_make_options,
+ dkT('\0'),
+ NULL,
+ (xargc - 1),
+ &(xargv[1]),
+ app
+ );
+ if(dkdbtj.opt) {
+ if(dk3opt_get_error_code(dkdbtj.opt) == 0) {
+ if(dk3opt_is_set(dkdbtj.opt, dkT('a'))) {
+ dkdbtj.f_add = 1;
+ }
+ if(dk3opt_is_set(dkdbtj.opt, dkT('c'))) {
+ arg = dk3opt_get_short_arg(dkdbtj.opt, dkT('c'));
+ if(arg) {
+ dkdbtj.comm = (char)(*arg);
+ } else {
+ ok = 0;
+ /* ERROR: Missing argument for -c! */
+ }
+ }
+ if(dk3opt_is_set(dkdbtj.opt, dkT('i'))) {
+ arg = dk3opt_get_short_arg(dkdbtj.opt, dkT('i'));
+ if(arg) {
+ res = dkdbt_set_encoding(
+ app, &(dkdbtj.enc_s), arg,
+ dk3app_get_input_stdin_encoding(dkdbtj.app)
+ );
+ if(res) {
+ dkdbtj.enc_f = dkdbtj.enc_s;
+ } else {
+ ok = 0;
+ }
+ } else {
+ ok = 0;
+ /* ERROR: Missing argument for -i! */
+ }
+ }
+ if(dk3opt_is_set(dkdbtj.opt, dkT('l'))) {
+ arg = dk3opt_get_short_arg(dkdbtj.opt, dkT('l'));
+ if(arg) {
+#if VERSION_BEFORE_20140809
+ if(dk3sf_sscanf3(arg, dkT("%lu"), &ul) == 1) {
+ ls = (size_t)ul;
+ if((unsigned long)ls == ul) {
+ dkdbtj.ls = ls;
+ } else {
+ ok = 0;
+ /* ERROR: Too large! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 135, 136, arg);
+ }
+ } else {
+ ok = 0;
+ /* ERROR: Not a number! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 141, 142, arg);
+ }
+#else
+ dk3_um_t um = DK3_UM_0;
+#if VERSION_BEFORE_20140716
+ if (dk3ma_c8_string_to_um(&um, arg))
+#else
+ if (0 != dk3ma_um_from_string(&um, arg, NULL))
+#endif
+ {
+ if (DK3_UM_0 != um) {
+ ls = dk3ma_um_to_sz(um, 0);
+ if (0 != ls) {
+ dkdbtj.ls = ls;
+ } else {
+ ok = 0;
+ dk3app_log_i3(app, DK3_LL_ERROR, 135, 136, arg);
+ }
+ } else {
+ /* Must not be 0 */
+ ok = 0;
+ dk3app_log_i3(app, DK3_LL_ERROR, 135, 136, arg);
+ }
+ } else {
+ ok = 0;
+ dk3app_log_i3(app, DK3_LL_ERROR, 141, 142, arg);
+ }
+#endif
+ } else {
+ ok = 0;
+ /* ERROR: Missing argument for -l! */
+ }
+ }
+ if(ok) {
+ if(dkdbtj.ls <= 1024) {
+ dkdbt_make_with_auto_buffer(&dkdbtj);
+ } else {
+ dkdbt_make_with_allocated_buffer(&dkdbtj);
+ }
+ }
+ } else {
+ /* ERROR: Error while creating options set! */
+ }
+ } else {
+ /* ERROR: Failed to create options set! */
+ }
+ dkdbt_job_end(&dkdbtj);
+
+#line 1402 "dkdbt.ctr"
+}
+
+
+
+/** Check whether or not a datum contains printable text.
+ @param dt Data buffer.
+ @param sz Data buffer size in bytes.
+ @return 1 on success (can print), 0 on error.
+*/
+static
+int
+dkdbt_can_print_text(void *dt, size_t sz)
+{
+ int back = 0;
+ size_t lgt; /* Data length. */
+ dkChar *tptr; /* Data buffer start address as dkChar pointer. */
+
+ if(dt) {
+ if(sz) {
+ if((sz % sizeof(dkChar)) == 0) {
+ lgt = sz / sizeof(dkChar);
+ if(lgt > 0) {
+ tptr = (dkChar *)dt;
+ if(tptr[lgt - 1] == dkT('\0')) {
+ back = 1;
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Traversal function to show data as text.
+ @param obj Job structure.
+ @param key Record key.
+ @param val Record value.
+ @return 1 on success, 0 on error (can continue), -1 on error (abort).
+*/
+static
+int
+dkdbt_show_data(void *obj, dk3_datum_t *key, dk3_datum_t *val)
+{
+ DKDBT_JOB *j; /* Text job. */
+ int back = 0;
+
+
+#line 1450 "dkdbt.ctr"
+ j = (DKDBT_JOB *)obj;
+ if(dkdbt_can_print_text(key->dt, key->sz)) {
+ if(dkdbt_can_print_text(val->dt, val->sz)) {
+ if(dk3stream_strputs(j->os, (dkChar const *)(key->dt), j->ie)) {
+ if(dk3stream_strputs(j->os, dkdbt_kw[1], j->ie)) {
+ if(dk3stream_strputs(j->os, (dkChar const *)(val->dt), j->ie)) {
+ if(dk3stream_strputs(j->os, dkdbt_kw[2], j->ie)) {
+ back = 1;
+ } else {
+
+#line 1459 "dkdbt.ctr"
+ /* ERROR: Failed to print newline! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 18);
+ }
+ } else {
+
+#line 1463 "dkdbt.ctr"
+ /* ERROR: Failed to print value! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 17);
+ }
+ } else {
+
+#line 1467 "dkdbt.ctr"
+ /* ERROR: Failed to print space! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 16);
+ }
+ } else {
+
+#line 1471 "dkdbt.ctr"
+ /* ERROR: Failed to print key! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 15);
+ }
+ } else {
+
+#line 1475 "dkdbt.ctr"
+ /* ERROR: Illegal value data! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 14);
+ }
+ } else {
+
+#line 1479 "dkdbt.ctr"
+ /* ERROR: Illegal key data! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 13);
+ }
+
+#line 1482 "dkdbt.ctr"
+ return back;
+}
+
+
+
+/** Reverse make operation (show database as text).
+ @param job Job structure.
+ @param fipo Output file, opened for text writing.
+ @param isfile Flag: Writing to a file, not a terminal.
+*/
+static
+void
+dkdbt_make_reverse_file(DKDBT_JOB *job, FILE *fipo, int isfile)
+{
+ int res; /* Operation result. */
+
+ job->os = dk3stream_open_file_app(fipo, DK3_STREAM_FLAG_WRITE, job->app);
+ if(job->os) {
+ job->oe = ((isfile) ? (job->enc_f) : (job->enc_s));
+ job->ie = dk3app_get_encoding(job->app);
+ dk3stream_set_output_encoding(job->os, job->oe);
+ if(job->oe != DK3_FILE_ENCODING_ASCII) {
+ if(job->oe != DK3_FILE_ENCODING_UTF8) {
+ dk3stream_write_byte_order_marker(job->os);
+ }
+ }
+ res = dk3dbi_traverse(job->in, (void *)job, dkdbt_show_data);
+ if(res) {
+
+#line 1510 "dkdbt.ctr"
+ exval = 0;
+ } else {
+
+#line 1512 "dkdbt.ctr"
+ /* ERROR: Error while showing data! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 12);
+ }
+ dk3stream_close(job->os);
+ } else {
+ /* ERROR: Failed to open stream */
+ }
+}
+
+
+
+/** Reverse make operation (show database as text).
+ @param app Application structure.
+ @param msg Localized message texts.
+ @param xargc Number of command line arguments.
+ @param xargv Command line arguments array.
+*/
+static
+void
+dkdbt_make_reverse(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ int xargc,
+ dkChar const * const *xargv
+)
+{
+ DKDBT_JOB dkdbtj; /* Text job. */
+ FILE *fipo; /* Output file. */
+ dkChar const *arg; /* Option argument. */
+ dkChar const *inname; /* Input database name. */
+ dkChar const *outname; /* Output file name. */
+ int ok = 1; /* Flag: No errors found. */
+ int res = 0; /* Operation result. */
+ int ec = 0; /* Error code. */
+
+ dkdbt_job_init(&dkdbtj, app, msg, xargc, xargv);
+#if VERSION_BEFORE_20150821
+ ok = 1; ec = 0;
+#endif
+ dkdbtj.opt = dk3opt_open_app(
+ dkdbt_text_options,
+ dkdbt_sz_text_options,
+ dkT('\0'),
+ NULL,
+ (xargc - 1),
+ &(xargv[1]),
+ app
+ );
+ if(dkdbtj.opt) {
+ if(dk3opt_get_error_code(dkdbtj.opt) == 0) {
+ if(dk3opt_is_set(dkdbtj.opt, dkT('o'))) {
+ arg = dk3opt_get_short_arg(dkdbtj.opt, dkT('o'));
+ if(arg) {
+ res = dkdbt_set_encoding(
+ app, &(dkdbtj.enc_s), arg,
+ dk3app_get_input_stdin_encoding(dkdbtj.app)
+ );
+ if(res) {
+ dkdbtj.enc_f = dkdbtj.enc_s;
+ } else {
+ ok = 0;
+ }
+ } else {
+ ok = 0;
+ /* ERROR: Missing argument for -o! */
+ }
+ }
+ if(ok) {
+ switch(dk3opt_get_num_args(dkdbtj.opt)) {
+ case 2: case 3: {
+ inname = dk3opt_get_arg(dkdbtj.opt, 1);
+ if(inname) {
+ dkdbtj.in = dk3dbi_open_app(
+ inname,
+ DK3_DB_TYPE_UNKNOWN,
+ DK3_DB_ACCESS_READ,
+ &ec,
+ app
+ );
+ if(dkdbtj.in) {
+ if(dk3opt_get_num_args(dkdbtj.opt) >= 3) {
+ outname = dk3opt_get_arg(dkdbtj.opt, 2);
+ if(outname) {
+ fipo = dk3sf_fopen_app(outname, dkdbt_kw[0], dkdbtj.app);
+ if(fipo) {
+ dkdbt_make_reverse_file(&dkdbtj, fipo, 1);
+ if(!dk3sf_fclose_fn_app(fipo, outname, dkdbtj.app)) {
+#if VERSION_BEFORE_20150821
+ ok = 0;
+#endif
+ }
+ } else {
+ /* ERROR: Failed to open file! */
+ }
+ } else {
+ /* BUG: Should not happen */
+ }
+ if(dk3opt_get_num_args(dkdbtj.opt) > 3) {
+ dk3app_log_i3(
+ dkdbtj.app, DK3_LL_WARNING, 164, 165,
+ dk3opt_get_arg(dkdbtj.opt, 3)
+ );
+ }
+ } else {
+ dkdbt_make_reverse_file(&dkdbtj, stdout, 0);
+ }
+ dk3dbi_close(dkdbtj.in);
+ } else {
+ /* ERROR: Failed to open input database! */
+ }
+ } else {
+ /* BUG: Should not happen */
+ }
+ } break;
+ default: {
+ /* ERROR: Wrong number of arguments! */
+ if(dk3opt_get_num_args(dkdbtj.opt) > 3) {
+ dk3app_log_i3(
+ app, DK3_LL_ERROR, 164, 165,
+ dk3opt_get_arg(dkdbtj.opt, 3)
+ );
+ }
+ } break;
+ }
+ }
+ }
+ }
+ dkdbt_job_end(&dkdbtj);
+}
+
+
+
+/** Split SQL input lines.
+ @param app Application structure.
+ @param msg Localized message texts.
+ @param infile Input file, opened for text reading.
+ @param outfile Output file, opened for text writing.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkdbt_split_for_files(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ FILE *infile,
+ FILE *outfile
+)
+{
+ int back = 0;
+ int inputc; /* Current input character. */
+ int cc; /* Flag: Can continue. */
+ int inputt; /* Input character classification. */
+ int state; /* Current state. */
+ char c; /* Current input character. */
+
+
+#line 1667 "dkdbt.ctr"
+ dkdbt_sql_split_reset(&state);
+ do {
+ cc = 0;
+ inputc = fgetc(infile);
+ if(inputc != EOF) {
+ cc = 1;
+ c = (char)inputc;
+ inputt = I_ANY;
+ switch(c) {
+ case '\\': inputt = I_BS; break;
+ case '/': inputt = I_SL; break;
+ case '*': inputt = I_AST; break;
+ case '\'': inputt = I_Q; break;
+ case '"': inputt = I_DQ; break;
+ case '`': inputt = I_BT; break;
+ case ')': inputt = I_CL; break;
+ case ',': inputt = I_COMMA; break;
+ case '-': inputt = I_MINUS; break;
+ case '\n': inputt = I_NL; break;
+ }
+ switch(dkdbt_sql_split_step(&state, inputt)) {
+ case O_NL: {
+ fputc('\n', outfile);
+ } break;
+ }
+ fputc(inputc, outfile);
+ }
+ } while(cc);
+ if(state == ST_N) {
+ back = 1;
+ } else {
+ /* ERROR: Error in SQL input! */
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 11);
+ }
+
+#line 1701 "dkdbt.ctr"
+ return back;
+}
+
+
+
+/** Issue error message for wrong file type.
+ @param app Application structure for diagnostics.
+ @param msg Array containing localized message texts.
+ @param en File name.
+ @param es Stat information for file.
+*/
+static
+void
+dkdbt_wrong_file_type(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const *en,
+ dk3_stat_t const *es
+)
+{
+ dkChar const *oldsourcename; /* Previous source file name. */
+ unsigned long oldsourceline; /* Previous source file line. */
+
+ oldsourcename = dk3app_get_source_file(app);
+ oldsourceline = dk3app_get_source_line(app);
+ dk3app_set_source_file(app, en);
+ dk3app_set_source_line(app, 0UL);
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 10);
+ dk3app_set_source_file(app, oldsourcename);
+ dk3app_set_source_line(app, oldsourceline);
+}
+
+
+/** Process one input file for splitting SQL lines.
+ @param app Application structure.
+ @param msg Localized message texts.
+ @param fipo Input file, opened for text reading.
+ @param xargc Number of command line arguments.
+ @param xargv Command line arguments array.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkdbt_split_input_file(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ FILE *fipo,
+ int xargc,
+ dkChar const * const *xargv
+)
+{
+ dkChar fnb[DK3_MAX_PATH]; /* Copy of file name. */
+ FILE *outf; /* Output file. */
+ dk3_dir_t *fne; /* File name expander. */
+ dk3_stat_t const *es; /* stat inf for current file. */
+ dkChar const *en; /* Full name current file. */
+ int back = 0;
+
+ if(xargc > 3) {
+ if(dk3str_len(xargv[3]) < DK3_SIZEOF(fnb,dkChar)) {
+ dk3str_cpy_not_overlapped(fnb, xargv[3]);
+ dk3str_correct_filename(fnb);
+ if(dk3sf_must_expand(fnb)) {
+ fne = dk3dir_fne_open_app(fnb, app);
+ if(fne) {
+ if(dk3dir_get_number_of_files(fne) == 1) {
+ if(dk3dir_get_next_file(fne)) {
+ en = dk3dir_get_fullname(fne);
+ es = dk3dir_get_stat(fne);
+ if((en) && (es)) {
+ switch((es->ft) & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_REGULAR: {
+ outf = dk3sf_fopen_app(en, dk3app_not_localized(24), app);
+ if(outf) {
+ if(dkdbt_split_for_files(app, msg, fipo, outf)) {
+ back = 1;
+ }
+ if(!dk3sf_fclose_fn_app(outf, en, app)) {
+ back = 0;
+ }
+ } else {
+ /* ERROR: Failed to open output file! */
+ }
+ } break;
+ default: {
+ /* ERROR: Wrong file type! */
+ dkdbt_wrong_file_type(app, msg, en, es);
+ } break;
+ }
+ } else {
+ /* BUG: Should not happen! */
+ }
+ } else {
+ /* ERROR: No matching file name! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 215, 216, fnb);
+ }
+ } else {
+ if(dk3dir_get_number_of_files(fne)) {
+ /* ERROR: Too many matching file names! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 168, 169, fnb);
+ } else {
+ /* ERROR: No matching file name! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 215, 216, fnb);
+ }
+ }
+ dk3dir_close(fne);
+ } else {
+ /* ERROR: Failed to open file name expander! */
+ }
+ } else {
+ outf = dk3sf_fopen_app(fnb, dk3app_not_localized(24), app);
+ if(outf) {
+ if(dkdbt_split_for_files(app, msg, fipo, outf)) {
+ back = 1;
+ }
+ if(!dk3sf_fclose_fn_app(outf, fnb, app)) {
+ back = 0;
+ }
+ } else {
+ /* ERROR: Failed to open output file! */
+ }
+ }
+ } else {
+ /* ERROR: File name too long! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 65, 66, xargv[3]);
+ }
+ } else {
+ if(dkdbt_split_for_files(app, msg, fipo, stdout)) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Split long lines in mysqldump output.
+ @param app Application structure for diagnostics.
+ @param msg Localized messages.
+ @param xargc Number of command line arguments.
+ @param xargv Command line arguments array.
+*/
+static
+void
+dkdbt_split_sql_lines(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ int xargc,
+ dkChar const * const *xargv
+)
+{
+ dkChar fnb[DK3_MAX_PATH]; /* Copy of file name. */
+ FILE *fipo; /* Input file. */
+ dk3_dir_t *fne; /* File name expander. */
+ dkChar const *en; /* File name current file. */
+ dk3_stat_t const *es; /* stat info current file. */
+ int ok = 1; /* Flag: No errors. */
+ int have_files = 0; /* Flag: Files found. */
+
+
+
+#line 1861 "dkdbt.ctr"
+#if VERSION_BEFORE_20150821
+ ok = 1; have_files = 0;
+#endif
+ if(xargc > 2) {
+ if(dk3str_len(xargv[2]) < DK3_SIZEOF(fnb,DK3_SIZEOF(fnb,dkChar))) {
+ dk3str_cpy_not_overlapped(fnb, xargv[2]);
+ dk3str_correct_filename(fnb);
+ if(dk3sf_must_expand(fnb)) {
+ fne = dk3dir_fne_open_app(fnb, app);
+ if(fne) {
+ if(dk3dir_get_number_of_files(fne)) {
+ ok = 1;
+ while(dk3dir_get_next_file(fne)) {
+ en = dk3dir_get_shortname(fne);
+ es = dk3dir_get_stat(fne);
+ if((en) && (es)) {
+ switch((es->ft) & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_REGULAR: {
+ fipo = dk3sf_fopen_app(
+ en,
+ dk3app_not_localized(22),
+ app
+ );
+ if(fipo) {
+ have_files = 1;
+ if(!dkdbt_split_input_file(app, msg, fipo, xargc, xargv))
+ {
+ ok = 0;
+ }
+ fclose(fipo);
+ } else {
+ /* ERROR: Failed to open file! */
+ ok = 0;
+ }
+ } break;
+ default: {
+ /* ERROR: Wrong file type! */
+ dkdbt_wrong_file_type(app, msg, en, es);
+ ok = 0;
+ } break;
+ }
+ } else {
+ ok = 0;
+ /* BUG: Should not happen! */
+ }
+ }
+ if((ok > 0) && (have_files > 0)) {
+ exval = 0;
+ } else {
+ if(have_files == 0) {
+ /* ERROR: No input files found! */
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 9);
+ }
+ }
+ } else {
+ /* ERROR: No matching file name! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 215, 216, fnb);
+ }
+ dk3dir_close(fne);
+ } else {
+ /* ERROR: Failed to expand file name! */
+ dk3app_log_3(app, DK3_LL_ERROR, msg, 7, 8, fnb);
+ }
+ } else {
+ fipo = dk3sf_fopen_app(fnb, dk3app_not_localized(22), app);
+ if(fipo) {
+ if(dkdbt_split_input_file(app, msg, fipo, xargc, xargv)) {
+ exval = 0;
+ }
+ fclose(fipo);
+ } else {
+ /* ERROR: Failed to open file! */
+ }
+ }
+ } else {
+ /* ERROR: Input file name too long! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 65, 66, xargv[2]);
+ }
+ } else {
+ if(dkdbt_split_for_files(app, msg, stdin, stdout)) {
+ exval = 0;
+ }
+ }
+
+#line 1944 "dkdbt.ctr"
+}
+
+
+
+/** The main() function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, any other value indicates an error.
+*/
+DK3_MAIN
+{
+ dk3_app_t *app = NULL; /* Application structure. */
+ dkChar const * const *msg = NULL; /* Localized message texts. */
+ dkChar const * const *xargv; /* Command line arguments array. */
+ int xargc; /* Number of command line arguments. */
+
+
+#line 1960 "dkdbt.ctr"
+
+
+#line 1961 "dkdbt.ctr"
+ app = dk3app_open_command(
+ argc, (dkChar const * const *)argv, dkt_group_name
+ );
+ if(app) {
+ msg = dk3app_messages(
+ app, dkdbt_stt_file_name, (dkChar const **)dkdbt_message_texts
+ );
+ xargc = dk3app_get_argc(app);
+ xargv = dk3app_get_argv(app);
+ if(xargc > 1) {
+ switch(dk3str_array_abbr(dkdbt_commands, xargv[1], dkT('$'), 0)) {
+ case 0: case 1: { /* Help */
+ dkdbt_show_help(app);
+ exval = 0;
+ } break;
+ case 2: case 3: { /* Version */
+ dkdbt_show_version(app);
+ exval = 0;
+ } break;
+ case 4: case 5: case 13: case 14:{ /* License */
+ dkdbt_show_license(app);
+ exval = 0;
+ } break;
+ case 6: case 7: { /* Features */
+ dkdbt_show_features(app, msg);
+ exval = 0;
+ } break;
+ case 8: { /* Copy */
+ dkdbt_copy(app, msg, xargc, xargv);
+ } break;
+ case 9: { /* Make */
+ dkdbt_make(app, msg, xargc, xargv);
+ } break;
+ case 10: { /* Reverse make. */
+ dkdbt_make_reverse(app, msg, xargc, xargv);
+ } break;
+ case 11: case 12: { /* Split SQL lines. */
+ dkdbt_split_sql_lines(app, msg, xargc, xargv);
+ } break;
+ default: { /* Unknown command. */
+ /* ERROR: Unknown command! */
+ dk3app_log_3(app, DK3_LL_ERROR, dkdbt_message_texts, 5, 6, xargv[1]);
+ dkdbt_show_help(app);
+ } break;
+ }
+ } else {
+ /* ERROR: Syntax */
+ dk3app_log_1(app, DK3_LL_ERROR, dkdbt_message_texts, 4);
+ dkdbt_show_help(app);
+ }
+ dk3app_close(app);
+ } else {
+ /* ERROR: Memory */
+ fputs("Error: Not enough memory!\n", stderr);
+ fflush(stderr);
+ }
+
+
+#line 2018 "dkdbt.ctr"
+
+
+#line 2019 "dkdbt.ctr"
+ fflush(stdout);
+ exit(exval); return exval;
+}
+
+
diff --git a/support/dktools/dkdbt.ctr b/support/dktools/dkdbt.ctr
new file mode 100644
index 0000000000..f249fecb38
--- /dev/null
+++ b/support/dktools/dkdbt.ctr
@@ -0,0 +1,2023 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% state machine
+
+# This state machine is used when splitting SQL lines.
+
+[options]
+ name = dkdbt_sql_split
+ write header = no
+
+[states]
+ ST_N # Normal text.
+ ST_N_BS # Normal text, backslash found.
+ ST_CB # Normal text, closing bracket found.
+ ST_CB_CO # Normal text, bracket and comma found.
+ ST_SL # Normal text, slash found.
+ ST_MINUS # Normal text, one minus found.
+ ST_CO # Comment.
+ ST_CO_AST # Comment, asterisk found.
+ ST_LCO # Line comment.
+ ST_Q # Single quote text.
+ ST_Q_BS # Single quote text, backslash found.
+ ST_DQ # Double quote text.
+ ST_DQ_BS # Double quote text, backslash found.
+ ST_BT # Backtick text.
+ ST_BT_BS # Backtick text, backslash found.
+ ST_ERROR # Any error occured.
+
+[inputs]
+ I_ANY # Any text.
+ I_BS # Backslash.
+ I_SL # Slash.
+ I_AST # Asterisk.
+ I_Q # Single quote.
+ I_DQ # Double quote.
+ I_BT # Backtick.
+ I_CL # Closing bracket.
+ I_COMMA # Comma.
+ I_MINUS # Minus sign.
+ I_NL # Newline.
+
+[outputs]
+ O_NORMAL # Normal output.
+ O_NL # Append newline to current output.
+
+[rules]
+ * * ST_ERROR O_NORMAL
+ ST_N * ST_N O_NORMAL
+ ST_N I_BS ST_N_BS O_NORMAL
+ ST_N I_CL ST_CB O_NORMAL
+ ST_N I_SL ST_SL O_NORMAL
+ ST_N I_MINUS ST_MINUS O_NORMAL
+ ST_N I_Q ST_Q O_NORMAL
+ ST_N I_DQ ST_DQ O_NORMAL
+ ST_N I_BT ST_BT O_NORMAL
+
+ # If we have found a closing bracket we wait for
+ # a comma.
+
+ ST_CB * ST_N O_NORMAL
+ ST_CB I_CL ST_CB O_NORMAL
+ ST_CB I_COMMA ST_CB_CO O_NORMAL
+
+ # After closing bracket and comma we want to have a newline.
+
+ ST_CB_CO * ST_N O_NL
+ ST_CB_CO I_NL ST_N O_NORMAL
+ ST_CB_CO I_CL ST_CB O_NL
+
+ # After a backslash we go back to normal work.
+
+ ST_N_BS * ST_N O_NORMAL
+
+ # A slash may be the start of a comment.
+
+ ST_SL * ST_N O_NORMAL
+ ST_SL I_SL ST_SL O_NORMAL
+ ST_SL I_AST ST_CO O_NORMAL
+
+ # A comment is continued until the end marker.
+
+ ST_CO * ST_CO O_NORMAL
+ ST_CO I_AST ST_CO_AST O_NORMAL
+
+ # Once we have found an asterisk in a comment it might
+ # be the start of the comment end marker.
+
+ ST_CO_AST * ST_CO O_NORMAL
+ ST_CO_AST I_AST ST_CO_AST O_NORMAL
+ ST_CO_AST I_SL ST_N O_NORMAL
+
+ # When a minus is found in normal state a second minus
+ # will start a line comment.
+
+ ST_MINUS * ST_N O_NORMAL
+ ST_MINUS I_MINUS ST_LCO O_NORMAL
+
+ # A line comment is finished at line end.
+
+ ST_LCO * ST_LCO O_NORMAL
+ ST_LCO I_NL ST_N O_NORMAL
+
+ # A single quote text can be finished by another
+ # single quote only.
+
+ ST_Q * ST_Q O_NORMAL
+ ST_Q I_BS ST_Q_BS O_NORMAL
+ ST_Q I_Q ST_N O_NORMAL
+
+ # A backslash in a single quote text escapes one character.
+
+ ST_Q_BS * ST_Q O_NORMAL
+
+ # A double quote text can be finished by another
+ # double quote only.
+
+ ST_DQ * ST_DQ O_NORMAL
+ ST_DQ I_DQ ST_N O_NORMAL
+ ST_DQ I_BS ST_DQ_BS O_NORMAL
+
+ # A backslash in a double quote text escapes one character.
+
+ ST_DQ_BS * ST_DQ O_NORMAL
+
+ # A backtick text can be finished by another backtick only.
+
+ ST_BT * ST_BT O_NORMAL
+ ST_BT I_BT ST_N O_NORMAL
+ ST_BT I_BS ST_BT_BS O_NORMAL
+
+ # A backslash in a backtick text escapes one character.
+
+ ST_BT_BS * ST_BT O_NORMAL
+
+
+
+%% module
+
+#include "dk3all.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4vers.h"
+#include "dk3ma.h"
+
+
+
+$!trace-include
+
+
+
+#ifdef DK3_USE_DB
+#undef DK3_USE_DB
+#endif
+#ifdef DK3_USE_NDBM
+#undef DK3_USE_NDBM
+#endif
+
+#if DK3_HAVE_DB_H
+#include <db.h>
+/** Use Berkeley DB.
+*/
+#define DK3_USE_DB 1
+#endif
+
+#if DK3_HAVE_NDBM_H
+#include <ndbm.h>
+/** Use NDBM.
+*/
+#define DK3_USE_NDBM 1
+#endif
+
+
+
+/** Job structure.
+*/
+typedef struct {
+ dk3_app_t *app; /**< Application structure. */
+ dkChar const * const *msg; /**< Localized messages. */
+ dk3_option_set_t *opt; /**< Options. */
+ dkChar const * const *xargv; /**< Command line arguments array. */
+ dk3_dbi_t *in; /**< Input database. */
+ dk3_dbi_t *out; /**< Output database. */
+ dk3_stream_t *os; /**< Output stream. */
+ size_t ls; /**< Line size. */
+ int xargc; /**< Number of command line arguments. */
+ int f_add; /**< Flag: Add to existing database. */
+ int enc_s; /**< Encoding for stdin. */
+ int enc_f; /**< Encoding for files. */
+ int ie; /**< Default system encoding. */
+ int oe; /**< Output encoding. */
+ char comm; /**< Character to start comment line. */
+} DKDBT_JOB;
+
+
+
+/** Application group name.
+*/
+static dkChar const dkt_group_name[] = { dkT("dktools") };
+
+
+
+/** File name for string table file.
+*/
+static dkChar const dkdbt_stt_file_name[] = { dkT("dkdbtool.str") };
+
+
+
+/** File name for help file.
+*/
+static dkChar const dkdbt_help_file_name[] = { dkT("dkdbtool.txt") };
+
+
+
+/** Version number string.
+*/
+static dkChar const dkdbt_version[] = {
+dkT("dkdbt ") DKT_VERSION_DK
+};
+
+
+
+/** Options for the copy operation.
+*/
+static dk3_option_t const dkdbt_copy_options[] = {
+ { dkT('a'), dkT("append"), 0 }
+};
+
+/** Number of elements in dkdbt_copy_options.
+*/
+static size_t const dkdbt_sz_copy_options =
+sizeof(dkdbt_copy_options)/sizeof(dk3_option_t);
+
+
+
+/** Options for the make operation.
+*/
+static dk3_option_t const dkdbt_make_options[] = {
+ { dkT('a'), dkT("append"), 0 },
+ { dkT('c'), dkT("comment"), 1 },
+ { dkT('i'), dkT("input-encoding"), 1 },
+ { dkT('l'), dkT("line-size"), 1 }
+};
+
+/** Number of elements in dkdbt_make_options.
+*/
+static size_t const dkdbt_sz_make_options =
+sizeof(dkdbt_make_options)/sizeof(dk3_option_t);
+
+
+
+/** Options for the reverse make operation.
+*/
+static dk3_option_t const dkdbt_text_options[] = {
+ { dkT('o'), dkT("output-encoding"), 1 },
+};
+
+/** Number of elements in dkdbt_text_options.
+*/
+static size_t const dkdbt_sz_text_options =
+sizeof(dkdbt_text_options)/sizeof(dk3_option_t);
+
+
+
+/** Help text to show if help text file is not found.
+*/
+static dkChar const * const dkdbt_help_text[] = {
+$!text macro=dkT
+
+dkdbt - Dirk Krause's database tool
+===================================
+
+Usage
+-----
+
+dkdbt copy [-a] <source-db-name> <destination-db-name>
+dkdbt make [-c <char>] [-a] [-i <encoding>] <destination-db-name> [<file(s)>]
+dkdbt text [-o <encoding>] <source-db-name> [<file>]
+dkdbt split-sql-lines [<inputfile> [<outputfile>]]
+
+dkdbt help
+dkdbt version
+dkdbt license
+dkdbt features
+
+In a copy operation a new copy of the database is created, probably using
+another database type. By default the destination database is truncated
+when opening it so the destination database contains exactly the same
+records as the source database.
+The -a option switches to add mode, the records from the source database
+are added to the destination database. Records for existing keys are
+replaced, records for keys not yet existing are inserted.
+
+A make operation creates a database from text input. Each input line
+contains one record. The first text word in the line is the key, all
+remaining text beginning with the second text word is the value.
+The -c option can be used to specify a special character to start
+a comment. All lines started by the specified character are comment lines
+and thus ignored.
+The -i option can be used to specify the input encoding.
+The files specified on the command line after the destination database name
+are used as input files. If no files are specified, standard input is used.
+
+The text operation is a reverse make operation. It writes data from the
+database as a sequence of lines. The -o option can be used to specify
+the output encoding.
+
+The split-sql-lines operation can be used to split overlong lines in
+mysqldump output.
+
+The help operation shows this help text.
+
+The version operation shows the version number.
+
+The license-terms operation shows the license terms.
+
+The features operation lists the database types supported by the program.
+
+$!end
+};
+
+
+
+/** Default message texts, used if no string table file is found.
+*/
+static dkChar const * const dkdbt_message_texts[] = {
+$!string-table macro=dkT
+#
+# 0
+#
+The following database types are supported:
+#
+# 1
+#
+mem In-memory database from the dktools project.
+#
+# 2
+#
+bdb Berkeley DB: An embedded database programmatic toolkit.
+#
+# 3
+#
+NDBM The NDBM database.
+#
+# 4: Error message: Missing dkdbt command!
+#
+Missing dkdbt command!\nType "dkdbt help" for a list of commands.
+#
+# 5/6: Error message: Unknown command "..."!
+#
+Unknown command: "
+"!\nType "dkdbt help" for a list of commands.
+#
+# 7/8: Error message: Failed to expand file name pattern "..."!
+#
+Failed to expand file name pattern "
+"!
+#
+# 9: Error message: No input files found!
+#
+No input files found!
+#
+# 10: Error message: Wrong file type!
+#
+Wrong file type!
+#
+# 11: Error message: Error in SQL input!
+#
+Error in SQL input!
+#
+# 12: Error message: Error while traversing data!
+#
+Error while traversing data!
+#
+# 13: Error message: Key data is no text!
+#
+Key data is not text!
+#
+# 14: Error message: Value data is no text!
+#
+Value data is not text!
+#
+# 15: Error message: Failed to print key!
+#
+Failed to print key!
+#
+# 16: Error message: Failed to print space!
+#
+Failed to print space!
+#
+# 17: Error message: Failed to print value!
+#
+Failed to print value!
+#
+# 18: Error message: Failed to print newline!
+#
+Failed to print newline!
+#
+# 19: Error message: Missing destination database name!
+#
+Missing destination database name!
+#
+# 20: Error message: Errors occured while processing input!
+#
+Error(s) occured while processing input!
+#
+# 21: Error message: Input and output database file name required!
+#
+Input and output database file name required!
+#
+# 22: Error message: Missing input file name!
+#
+Missing input file name!
+#
+# 23: Error message: Missing output file name!
+#
+Missing output file name!
+#
+# 24: Error message: Error(s) occured while copying data!
+#
+Error(s) occured while copying data!
+$!end
+};
+
+
+
+/** Commands for dkdbt.
+*/
+static dkChar const * const dkdbt_commands[] = {
+$!string-table macro=dkT
+#
+# 0, 1: Help
+#
+h$elp
+--help
+#
+# 2, 3: Version
+#
+v$ersion
+--version
+#
+# 4, 5: License
+#
+l$icense
+--license
+#
+# 6, 7: Features
+#
+f$eatures
+--features
+#
+# 8: Copy
+#
+c$opy
+#
+# 9: Make
+#
+m$ake
+#
+# 10: Reverse make (reconstruct text)
+#
+t$ext
+#
+# 11/12: Split lines in mysqldump output
+#
+s$plit-sql-lines
+split-sql
+#
+# 13/14: License terms
+#
+--license-terms
+-L
+$!end
+};
+
+
+
+/** Licensing overview, list of all sources.
+*/
+static dkChar const * const dkdbt_overview_license[] = {
+dkT("This software uses code from the following projects either directly"),
+dkT("or as a library:"),
+dkT(""),
+dkT("dktools\t\tDirk Krause's tools and libraries."),
+dkT("\t\tSee http://dktools.sourceforge.net for more information."),
+#if DK3_USE_DB
+dkT(""),
+dkT("Berkeley DB\tBerkeley DB: An embedded database programmatic toolkit."),
+dkT("\t\tSee http://www.oracle.com for more information."),
+#endif
+#if DK3_USE_NDBM
+dkT(""),
+dkT("NDBM\t\tA library implementing the NDBM API."),
+dkT("\t\tLicense conditions depend on the NDBM library you use."),
+#endif
+dkT(""),
+NULL
+};
+
+
+
+/** License terms for the dktools project itself.
+*/
+static dkChar const * const dkt_license[] = {
+$!text macro=dkT
+License for the dktools project
+===============================
+Copyright (c) 2011-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms,
+with or without modification, are permitted provided
+that the following conditions are met:
+
+* Redistributions of source code must retain the above
+ copyright notice, this list of conditions and the
+ following disclaimer.
+* Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials
+ provided with the distribution.
+* Neither the name of the copyright holder(s) nor the names of
+ contributors may be used to endorse or promote
+ products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+
+$!end
+};
+
+
+
+#if DK3_USE_DB
+/** License conditions for the Berkeley DB.
+*/
+static dkChar const * const dkbtt_bdb_license[] = {
+$!text macro=dkT
+
+License for the Berkeley DB
+===========================
+
+The license that applies to your copy of the Berkeley DB software may be
+found in the "LICENSE" file included in each Berkeley DB distribution.
+For a license to use the Berkeley DB software under conditions other than
+those described in the "LICENSE" file, or to purchase support for the
+Berkeley DB software, please send email to berkeleydb-info_us@oracle.com .
+Copyright (c) 1996,2009 Oracle. All rights reserved.
+
+/*-
+ * $Id: LICENSE,v 12.9 2008/02/07 17:12:17 mark Exp $
+ */
+
+The following is the license that applies to this copy of the Berkeley DB
+software. For a license to use the Berkeley DB software under conditions
+other than those described here, or to purchase support for this software,
+please contact Oracle at berkeleydb-info_us@oracle.com.
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+/*
+ * Copyright (c) 1990,2008 Oracle. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Redistributions in any form must be accompanied by information on
+ * how to obtain complete source code for the DB software and any
+ * accompanying software that uses the DB software. The source code
+ * must either be included in the distribution or be available for no
+ * more than the cost of distribution plus a nominal fee, and must be
+ * freely redistributable under reasonable conditions. For an
+ * executable file, complete source code means the source code for all
+ * modules it contains. It does not include source code for modules or
+ * files that typically accompany the major components of the operating
+ * system on which the executable file runs.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ORACLE ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ * NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL ORACLE BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * Copyright (c) 1990, 1993, 1994, 1995
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * Copyright (c) 1995, 1996
+ * The President and Fellows of Harvard University. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY HARVARD AND ITS CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HARVARD OR ITS CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2005 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+$!end
+};
+#endif
+
+
+
+#if DK3_USE_NDBM
+/** License notice for NDBM libraries.
+*/
+static dkChar const * const dkdbt_ndbm_license[] = {
+$!text macro=dkT
+License for the NDBM software
+=============================
+NDBM is an API implemented by different libraries from different vendors.
+The most common implementations are
+- NDBM software contained in the system distribution of commercial
+ UNIX operating systems, and
+- the NDBM compatibility library of the GDBM software.
+Your use of the dktools software together with NDBM libraries must be in
+compliance to the license conditions of the NDBM library used.
+
+$!end
+};
+#endif
+
+
+
+/** Keywords used by this module.
+*/
+static dkChar const * const dkdbt_kw[] = {
+/* 0 */ dkT("w"),
+/* 1 */ dkT(" "),
+/* 2 */ dkT("\n"),
+/* 3 */ dkT("DB: mem"),
+/* 4 */ dkT(" bdb"),
+/* 5 */ dkT(" ndbm"),
+};
+
+
+
+/** Exit code.
+*/
+static int exval = 1;
+
+
+
+/** Initialize job structure.
+ @param j Job structure to initialize.
+ @param app Application structure.
+ @param msg Localized message texts.
+ @param xargc Number of command line arguments.
+ @param xargv Command line arguments array.
+*/
+static
+void
+dkdbt_job_init(
+ DKDBT_JOB *j,
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ int xargc,
+ dkChar const * const *xargv
+)
+{
+ j->app = app;
+ j->msg = msg;
+ j->opt = NULL;
+ j->xargc = xargc;
+ j->xargv = xargv;
+ j->ls = 1024;
+ j->f_add = 0;
+ j->enc_s = dk3app_get_input_stdin_encoding(j->app);
+ j->enc_f = dk3app_get_input_file_encoding(j->app);
+ j->comm = '\0';
+ j->in = NULL;
+ j->out = NULL;
+}
+
+
+
+/** Clean up job structure.
+ @param j Job structure to clean up.
+*/
+static
+void
+dkdbt_job_end(DKDBT_JOB *j)
+{
+ if(j->opt) {
+ dk3opt_close(j->opt);
+ } j->opt = NULL;
+}
+
+
+
+/** Show help text, either from file or default text.
+ @param app Application structure.
+*/
+static
+void
+dkdbt_show_help(dk3_app_t *app)
+{
+ dk3app_help(app, dkdbt_help_file_name, dkdbt_help_text);
+}
+
+
+
+/** Show license terms.
+ @param app Application structure.
+*/
+static
+void
+dkdbt_show_license(dk3_app_t *app)
+{
+ dkChar const * const *sptr;
+ dk3sf_initialize_stdout();
+ sptr = dkdbt_overview_license;
+ while(*sptr) {
+ dk3sf_fputs(*(sptr++), stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ sptr = dkt_license;
+ while(*sptr) {
+ dk3sf_fputs(*(sptr++), stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+#if DK3_USE_DB
+ sptr = dkbtt_bdb_license;
+ while(*sptr) {
+ dk3sf_fputs(*(sptr++), stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+#endif
+#if DK3_USE_NDBM
+ sptr = dkdbt_ndbm_license;
+ while(*sptr) {
+ dk3sf_fputs(*(sptr++), stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+#endif
+}
+
+
+
+/** Show features.
+ @param app Application structure.
+ @param msg Localized message texts.
+*/
+static
+void
+dkdbt_show_features(dk3_app_t *app, dkChar const * const *msg)
+{
+ dk3sf_initialize_stdout();
+ dk3sf_fputs(msg[0], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ dk3sf_fputs(msg[1], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+#if DK3_USE_DB
+ dk3sf_fputs(msg[2], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+#endif
+#if DK3_USE_NDBM
+ dk3sf_fputs(msg[3], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+#endif
+}
+
+
+
+/** Show version number.
+ @param app Application structure.
+*/
+static
+void
+dkdbt_show_version(dk3_app_t *app)
+{
+ dk3sf_initialize_stdout();
+ dk3sf_fputs(dkdbt_version, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ dk3sf_fputs(dkdbt_kw[3], stdout);
+ if(dk3dbi_type_supported(DK3_DB_TYPE_BDB)) {
+ dk3sf_fputs(dkdbt_kw[4], stdout);
+ }
+ if(dk3dbi_type_supported(DK3_DB_TYPE_NDBM)) {
+ dk3sf_fputs(dkdbt_kw[5], stdout);
+ }
+ dk3sf_fputs(dkdbt_kw[2], stdout);
+}
+
+
+
+/** Traversal function to copy all records to new database.
+ @param obj Job structure.
+ @param key Record key.
+ @param val Record value.
+ @return 1 on success, 0 on error (can continue), -1 on error (abort).
+*/
+static
+int
+dkdbt_copy_data(void *obj, dk3_datum_t *key, dk3_datum_t *val)
+{
+ DKDBT_JOB *j; /* Copy job. */
+ int back;
+
+ j = (DKDBT_JOB *)obj;
+ back = dk3dbi_set(j->out, key, val);
+ return back;
+}
+
+
+
+/** Copy function.
+ @param app Application structure.
+ @param msg Localized message texts.
+ @param xargc Number of command line arguments.
+ @param xargv Command line arguments array.
+*/
+static
+void
+dkdbt_copy(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ int xargc,
+ dkChar const * const *xargv
+)
+{
+ DKDBT_JOB dkdbtj; /* Copy job. */
+ dkChar const *inname; /* Input database name. */
+ dkChar const *outname; /* Output database name. */
+ int ec; /* Error code. */
+ int res; /* Operation result. */
+
+ dkdbt_job_init(&dkdbtj, app, msg, xargc, xargv);
+ ec = 0;
+ dkdbtj.opt = dk3opt_open_app(
+ dkdbt_copy_options,
+ dkdbt_sz_copy_options,
+ dkT('\0'),
+ NULL,
+ (xargc - 1),
+ &(xargv[1]),
+ app
+ );
+ if(dkdbtj.opt) {
+ if(dk3opt_get_error_code(dkdbtj.opt) == 0) {
+ if(dk3opt_is_set(dkdbtj.opt, dkT('a'))) {
+ dkdbtj.f_add = 1;
+ }
+ if(dk3opt_get_num_args(dkdbtj.opt) >= 3) {
+ inname = dk3opt_get_arg(dkdbtj.opt, 1);
+ if(inname) {
+ outname = dk3opt_get_arg(dkdbtj.opt, 2);
+ if(outname) {
+ dkdbtj.in = dk3dbi_open_app(
+ inname,
+ DK3_DB_TYPE_UNKNOWN,
+ DK3_DB_ACCESS_READ,
+ &ec,
+ app
+ );
+ if(dkdbtj.in) {
+ if(dkdbtj.f_add) {
+ dkdbtj.out = dk3dbi_open_app(
+ outname,
+ DK3_DB_TYPE_UNKNOWN,
+ DK3_DB_ACCESS_WRITE,
+ &ec,
+ app
+ );
+ } else {
+ dkdbtj.out = dk3dbi_open_truncate_app(
+ outname,
+ DK3_DB_TYPE_UNKNOWN,
+ DK3_DB_ACCESS_WRITE,
+ &ec,
+ app
+ );
+ }
+ if(dkdbtj.out) {
+ res = dk3dbi_traverse(
+ dkdbtj.in, (void *)(&dkdbtj), dkdbt_copy_data
+ );
+ if(res) {
+ exval = 0;
+ } else {
+ /* ERROR While copying */
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 24);
+ }
+ dk3dbi_close(dkdbtj.out);
+ } else {
+ /* ERROR: Failed to open output database! */
+ }
+ dk3dbi_close(dkdbtj.in);
+ } else {
+ /* ERROR: Failed to open input database! */
+ }
+ } else {
+ /* ERROR: Output file name missing! */
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 23);
+ }
+ } else {
+ /* ERROR: Missing input file name! */
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 22);
+ }
+ if(dk3opt_get_num_args(dkdbtj.opt) > 3) {
+ dk3app_log_i3(
+ app, DK3_LL_WARNING, 164, 165,
+ dk3opt_get_arg(dkdbtj.opt, 3)
+ );
+ }
+ } else {
+ /* ERROR: File name missing! */
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 22);
+ }
+ } else {
+ /* ERROR: Error during option set creation! */
+ }
+ } else {
+ /* ERROR: Failed to create option set! */
+ }
+ dkdbt_job_end(&dkdbtj);
+}
+
+
+
+/** Set input or output encoding from command line arguments.
+ @param app Application structure.
+ @param enc Variable to set.
+ @param val Encoding name found on command line.
+ @param de Default encoding.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkdbt_set_encoding(
+ dk3_app_t *app,
+ int *enc,
+ dkChar const *val,
+ int de
+)
+{
+ int back = 0;
+ int i = -1; /* Index of string in array of encodings. */
+
+ if((app) && (enc)) {
+ if(val) {
+ i = dk3enc_get_text_encoding_app(val, app);
+ if(i > -1) {
+ *enc = i;
+ back = 1;
+ } else {
+ *enc = de;
+ }
+ } else {
+ *enc = de;
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Handler function for one line.
+ @param vj Job structure casted to void *.
+ @param il Input line to process.
+ @return 1=OK, 0=error, can continue, -1=error, abort processing.
+*/
+static
+int
+dkdbt_make_line_handler(void *vj, dkChar *il)
+{
+ DKDBT_JOB *j; /* Make job. */
+ dkChar *ptr; /* Pointer to modify string. */
+ dkChar *p1; /* Key pointer. */
+ dkChar *p2; /* Value pointer. */
+ int back = 0;
+ int comm = 0; /* Flag: Check lines for comments. */
+ $? "+ dkdbt_make_line_handler"
+ j = (DKDBT_JOB *)vj;
+ ptr = il;
+ while(*ptr) {
+ if(*ptr == dkT('\n')) *ptr = dkT('\0');
+ if(*ptr == dkT('\r')) *ptr = dkT('\0');
+ ptr++;
+ } $? ". line=\"%!ds\"", il
+ p1 = dk3str_start(il, NULL);
+ if(p1) {
+ if(j->comm) {
+ if(*p1 == j->comm) {
+ comm = 1;
+ back = 1;
+ }
+ }
+ if(!(comm)) {
+ p2 = dk3str_next(p1, NULL);
+ if(p2) {
+ dk3str_chomp(p2, NULL);
+ back = dk3dbi_set_string(j->out, p1, p2);
+ } else {
+ dk3dbi_delete_string(j->out, p1);
+ back = 1;
+ }
+ }
+ } else { $? ". empty line"
+ back = 1;
+ }
+ $? "- dkdbt_make_line_handler %d", back
+ return back;
+}
+
+
+
+/** Run make operation.
+ @param j Job structure.
+ @param buffer Line buffer.
+ @param szbuffer Size of @a buffer (number of characters).
+*/
+static
+void
+dkdbt_make_with_buffer(DKDBT_JOB *j, dkChar *buffer, size_t szbuffer)
+{
+ dkChar bu[DK3_MAX_PATH]; /* Local file name copy. */
+ dk3_dir_t *fne; /* File name expander. */
+ dkChar const *outname; /* Output database name. */
+ dkChar const *fn; /* Current input file name. */
+ dkChar const *en; /* Entry name. */
+ dk3_um_t nf; /* Number of files available. */
+ int nargs; /* Number of command line arguments. */
+ int i; /* Index of current file to process. */
+ int ec; /* Error code. */
+ int res; /* Result for one file. */
+ $? "+ dkdbt_make_with_buffer"
+ ec = 0;
+ nargs = dk3opt_get_num_args(j->opt);
+ if(nargs > 1) { $? ". nargs > 1"
+ outname = dk3opt_get_arg(j->opt, 1);
+ if(outname) { $? ". outname = \"%!ds\"", outname
+ if(j->f_add) { $? ". add"
+ j->out = dk3dbi_open_app(
+ outname, DK3_DB_TYPE_UNKNOWN, DK3_DB_ACCESS_WRITE,
+ &ec, j->app
+ );
+ } else { $? ". new"
+ j->out = dk3dbi_open_truncate_app(
+ outname, DK3_DB_TYPE_UNKNOWN, DK3_DB_ACCESS_WRITE,
+ &ec, j->app
+ );
+ }
+ if(j->out) { $? ". db opened"
+ if(nargs > 2) { $? ". use files %d", nargs
+ exval = 0;
+ for(i = 2; i < nargs; i++) { $? ". yet another file"
+ fn = dk3opt_get_arg(j->opt, i);
+ if(fn) { $? ". input file \"%!ds\"", fn
+ if(dk3str_len(fn) < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy_not_overlapped(bu, fn);
+ dk3str_correct_filename(bu);
+ if(dk3sf_must_expand(bu)) {
+ fne = dk3dir_fne_open_app(bu, j->app);
+ if(fne) {
+ nf = dk3dir_get_number_of_files(fne);
+ if(nf > 0) {
+ while(dk3dir_get_next_file(fne)) {
+ en = dk3dir_get_fullname(fne);
+ if(en) {
+ res = dk3stream_process_filename_lines_app(
+ (void *)j, dkdbt_make_line_handler, en,
+ buffer, szbuffer,
+ dk3app_get_encoding(j->app), j->enc_f, j->app
+ );
+ if(res < 1) {
+ exval = 1;
+ /* ERROR: Error while processing input! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 20);
+ }
+ } else {
+ /* BUG: Should not happen. */
+ }
+ }
+ } else {
+ exval = 1;
+ /* ERROR: No matching file name! */
+ dk3app_log_i3(j->app, DK3_LL_ERROR, 215, 216, bu);
+ }
+ dk3dir_close(fne);
+ } else {
+ /* ERROR: File name expansion failed! */
+ exval = 1;
+ }
+ } else {
+ res = dk3stream_process_filename_lines_app(
+ (void *)j, dkdbt_make_line_handler, bu,
+ buffer, szbuffer, dk3app_get_encoding(j->app),
+ j->enc_f, j->app
+ );
+ if(res < 1) {
+ /* ERROR: Error while processing input! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 20);
+ exval = 1;
+ }
+ }
+ } else {
+ /* ERROR: File name too large! */
+ dk3app_log_i3(j->app, DK3_LL_ERROR, 65, 66, fn);
+ exval = 1;
+ }
+ } else { $? "! Missing input file name"
+ /* BUG: Should not happen. */
+ exval = 1;
+ }
+ }
+ } else { $? ". use standard input"
+ res = dk3app_process_stdin_lines(
+ j->app, (void *)j, dkdbt_make_line_handler,
+ buffer, szbuffer, j->enc_s
+ );
+ if(res) {
+ exval = 0;
+ } else { $? "! error while processing"
+ /* ERROR: Error while processing input! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 20);
+ }
+ }
+ dk3dbi_close(j->out); j->out = NULL;
+ } else { $? "! failed to open db"
+ /* ERROR: Failed to open database! */
+ }
+ } else { $? "! missing destination db name"
+ /* ERROR: Missing destination database name! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 19);
+ }
+ } else { $? "! missing destination db name"
+ /* ERROR: Missing destination database name! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 19);
+ } $? "- dkdbt_make_with_buffer"
+}
+
+
+
+/** Run make operation with automatic default size buffer.
+ @param j Job structure.
+*/
+static
+void
+dkdbt_make_with_auto_buffer(DKDBT_JOB *j)
+{
+ dkChar buffer[1024]; /* Buffer for input lines. */
+
+ dkdbt_make_with_buffer(j, buffer, DK3_SIZEOF(buffer,dkChar));
+}
+
+
+
+/** Run make operation, allocate buffer of given size.
+ @param j Job structure.
+*/
+static
+void
+dkdbt_make_with_allocated_buffer(DKDBT_JOB *j)
+{
+ dkChar *bu; /* Buffer for input lines. */
+
+ bu = dk3_new_app(dkChar,j->ls,j->app);
+ if(bu) {
+ dkdbt_make_with_buffer(j, bu, j->ls);
+ dk3_delete(bu);
+ } else {
+ /* ERROR: Memory! */
+ }
+}
+
+
+
+/** Make operation.
+ @param app Application structure.
+ @param msg Localized message texts.
+ @param xargc Number of command line arguments.
+ @param xargv Command line arguments array.
+*/
+static
+void
+dkdbt_make(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ int xargc,
+ dkChar const * const *xargv
+)
+{
+ DKDBT_JOB dkdbtj; /* Make job. */
+ dkChar const *arg; /* Option argument. */
+#if VERSION_BEFORE_20140809
+ unsigned long ul; /* Line size as unsigned long. */
+#endif
+ size_t ls; /* Line size as size_t. */
+ int ok; /* Flag: No errors found. */
+ int res; /* Operation result. */
+ $? "+ dkdbt_make"
+ ok = 1;
+ dkdbt_job_init(&dkdbtj, app, msg, xargc, xargv);
+ dkdbtj.opt = dk3opt_open_app(
+ dkdbt_make_options,
+ dkdbt_sz_make_options,
+ dkT('\0'),
+ NULL,
+ (xargc - 1),
+ &(xargv[1]),
+ app
+ );
+ if(dkdbtj.opt) {
+ if(dk3opt_get_error_code(dkdbtj.opt) == 0) {
+ if(dk3opt_is_set(dkdbtj.opt, dkT('a'))) {
+ dkdbtj.f_add = 1;
+ }
+ if(dk3opt_is_set(dkdbtj.opt, dkT('c'))) {
+ arg = dk3opt_get_short_arg(dkdbtj.opt, dkT('c'));
+ if(arg) {
+ dkdbtj.comm = (char)(*arg);
+ } else {
+ ok = 0;
+ /* ERROR: Missing argument for -c! */
+ }
+ }
+ if(dk3opt_is_set(dkdbtj.opt, dkT('i'))) {
+ arg = dk3opt_get_short_arg(dkdbtj.opt, dkT('i'));
+ if(arg) {
+ res = dkdbt_set_encoding(
+ app, &(dkdbtj.enc_s), arg,
+ dk3app_get_input_stdin_encoding(dkdbtj.app)
+ );
+ if(res) {
+ dkdbtj.enc_f = dkdbtj.enc_s;
+ } else {
+ ok = 0;
+ }
+ } else {
+ ok = 0;
+ /* ERROR: Missing argument for -i! */
+ }
+ }
+ if(dk3opt_is_set(dkdbtj.opt, dkT('l'))) {
+ arg = dk3opt_get_short_arg(dkdbtj.opt, dkT('l'));
+ if(arg) {
+#if VERSION_BEFORE_20140809
+ if(dk3sf_sscanf3(arg, dkT("%lu"), &ul) == 1) {
+ ls = (size_t)ul;
+ if((unsigned long)ls == ul) {
+ dkdbtj.ls = ls;
+ } else {
+ ok = 0;
+ /* ERROR: Too large! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 135, 136, arg);
+ }
+ } else {
+ ok = 0;
+ /* ERROR: Not a number! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 141, 142, arg);
+ }
+#else
+ dk3_um_t um = DK3_UM_0;
+#if VERSION_BEFORE_20140716
+ if (dk3ma_c8_string_to_um(&um, arg))
+#else
+ if (0 != dk3ma_um_from_string(&um, arg, NULL))
+#endif
+ {
+ if (DK3_UM_0 != um) {
+ ls = dk3ma_um_to_sz(um, 0);
+ if (0 != ls) {
+ dkdbtj.ls = ls;
+ } else {
+ ok = 0;
+ dk3app_log_i3(app, DK3_LL_ERROR, 135, 136, arg);
+ }
+ } else {
+ /* Must not be 0 */
+ ok = 0;
+ dk3app_log_i3(app, DK3_LL_ERROR, 135, 136, arg);
+ }
+ } else {
+ ok = 0;
+ dk3app_log_i3(app, DK3_LL_ERROR, 141, 142, arg);
+ }
+#endif
+ } else {
+ ok = 0;
+ /* ERROR: Missing argument for -l! */
+ }
+ }
+ if(ok) {
+ if(dkdbtj.ls <= 1024) {
+ dkdbt_make_with_auto_buffer(&dkdbtj);
+ } else {
+ dkdbt_make_with_allocated_buffer(&dkdbtj);
+ }
+ }
+ } else {
+ /* ERROR: Error while creating options set! */
+ }
+ } else {
+ /* ERROR: Failed to create options set! */
+ }
+ dkdbt_job_end(&dkdbtj); $? "- dkdbt_make"
+}
+
+
+
+/** Check whether or not a datum contains printable text.
+ @param dt Data buffer.
+ @param sz Data buffer size in bytes.
+ @return 1 on success (can print), 0 on error.
+*/
+static
+int
+dkdbt_can_print_text(void *dt, size_t sz)
+{
+ int back = 0;
+ size_t lgt; /* Data length. */
+ dkChar *tptr; /* Data buffer start address as dkChar pointer. */
+
+ if(dt) {
+ if(sz) {
+ if((sz % sizeof(dkChar)) == 0) {
+ lgt = sz / sizeof(dkChar);
+ if(lgt > 0) {
+ tptr = (dkChar *)dt;
+ if(tptr[lgt - 1] == dkT('\0')) {
+ back = 1;
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Traversal function to show data as text.
+ @param obj Job structure.
+ @param key Record key.
+ @param val Record value.
+ @return 1 on success, 0 on error (can continue), -1 on error (abort).
+*/
+static
+int
+dkdbt_show_data(void *obj, dk3_datum_t *key, dk3_datum_t *val)
+{
+ DKDBT_JOB *j; /* Text job. */
+ int back = 0;
+ $? "+ dkdbt_show_data"
+ j = (DKDBT_JOB *)obj;
+ if(dkdbt_can_print_text(key->dt, key->sz)) {
+ if(dkdbt_can_print_text(val->dt, val->sz)) {
+ if(dk3stream_strputs(j->os, (dkChar const *)(key->dt), j->ie)) {
+ if(dk3stream_strputs(j->os, dkdbt_kw[1], j->ie)) {
+ if(dk3stream_strputs(j->os, (dkChar const *)(val->dt), j->ie)) {
+ if(dk3stream_strputs(j->os, dkdbt_kw[2], j->ie)) {
+ back = 1;
+ } else { $? "! failed to print newline"
+ /* ERROR: Failed to print newline! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 18);
+ }
+ } else { $? "! failed to print value"
+ /* ERROR: Failed to print value! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 17);
+ }
+ } else { $? "! failed to print space"
+ /* ERROR: Failed to print space! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 16);
+ }
+ } else { $? "! failed to print key"
+ /* ERROR: Failed to print key! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 15);
+ }
+ } else { $? "! illegal value data"
+ /* ERROR: Illegal value data! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 14);
+ }
+ } else { $? "! illegal key data"
+ /* ERROR: Illegal key data! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 13);
+ } $? "- dkdbt_show_data %d", back
+ return back;
+}
+
+
+
+/** Reverse make operation (show database as text).
+ @param job Job structure.
+ @param fipo Output file, opened for text writing.
+ @param isfile Flag: Writing to a file, not a terminal.
+*/
+static
+void
+dkdbt_make_reverse_file(DKDBT_JOB *job, FILE *fipo, int isfile)
+{
+ int res; /* Operation result. */
+
+ job->os = dk3stream_open_file_app(fipo, DK3_STREAM_FLAG_WRITE, job->app);
+ if(job->os) {
+ job->oe = ((isfile) ? (job->enc_f) : (job->enc_s));
+ job->ie = dk3app_get_encoding(job->app);
+ dk3stream_set_output_encoding(job->os, job->oe);
+ if(job->oe != DK3_FILE_ENCODING_ASCII) {
+ if(job->oe != DK3_FILE_ENCODING_UTF8) {
+ dk3stream_write_byte_order_marker(job->os);
+ }
+ }
+ res = dk3dbi_traverse(job->in, (void *)job, dkdbt_show_data);
+ if(res) { $? ". res ok"
+ exval = 0;
+ } else { $? "! res"
+ /* ERROR: Error while showing data! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 12);
+ }
+ dk3stream_close(job->os);
+ } else {
+ /* ERROR: Failed to open stream */
+ }
+}
+
+
+
+/** Reverse make operation (show database as text).
+ @param app Application structure.
+ @param msg Localized message texts.
+ @param xargc Number of command line arguments.
+ @param xargv Command line arguments array.
+*/
+static
+void
+dkdbt_make_reverse(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ int xargc,
+ dkChar const * const *xargv
+)
+{
+ DKDBT_JOB dkdbtj; /* Text job. */
+ FILE *fipo; /* Output file. */
+ dkChar const *arg; /* Option argument. */
+ dkChar const *inname; /* Input database name. */
+ dkChar const *outname; /* Output file name. */
+ int ok = 1; /* Flag: No errors found. */
+ int res = 0; /* Operation result. */
+ int ec = 0; /* Error code. */
+
+ dkdbt_job_init(&dkdbtj, app, msg, xargc, xargv);
+#if VERSION_BEFORE_20150821
+ ok = 1; ec = 0;
+#endif
+ dkdbtj.opt = dk3opt_open_app(
+ dkdbt_text_options,
+ dkdbt_sz_text_options,
+ dkT('\0'),
+ NULL,
+ (xargc - 1),
+ &(xargv[1]),
+ app
+ );
+ if(dkdbtj.opt) {
+ if(dk3opt_get_error_code(dkdbtj.opt) == 0) {
+ if(dk3opt_is_set(dkdbtj.opt, dkT('o'))) {
+ arg = dk3opt_get_short_arg(dkdbtj.opt, dkT('o'));
+ if(arg) {
+ res = dkdbt_set_encoding(
+ app, &(dkdbtj.enc_s), arg,
+ dk3app_get_input_stdin_encoding(dkdbtj.app)
+ );
+ if(res) {
+ dkdbtj.enc_f = dkdbtj.enc_s;
+ } else {
+ ok = 0;
+ }
+ } else {
+ ok = 0;
+ /* ERROR: Missing argument for -o! */
+ }
+ }
+ if(ok) {
+ switch(dk3opt_get_num_args(dkdbtj.opt)) {
+ case 2: case 3: {
+ inname = dk3opt_get_arg(dkdbtj.opt, 1);
+ if(inname) {
+ dkdbtj.in = dk3dbi_open_app(
+ inname,
+ DK3_DB_TYPE_UNKNOWN,
+ DK3_DB_ACCESS_READ,
+ &ec,
+ app
+ );
+ if(dkdbtj.in) {
+ if(dk3opt_get_num_args(dkdbtj.opt) >= 3) {
+ outname = dk3opt_get_arg(dkdbtj.opt, 2);
+ if(outname) {
+ fipo = dk3sf_fopen_app(outname, dkdbt_kw[0], dkdbtj.app);
+ if(fipo) {
+ dkdbt_make_reverse_file(&dkdbtj, fipo, 1);
+ if(!dk3sf_fclose_fn_app(fipo, outname, dkdbtj.app)) {
+#if VERSION_BEFORE_20150821
+ ok = 0;
+#endif
+ }
+ } else {
+ /* ERROR: Failed to open file! */
+ }
+ } else {
+ /* BUG: Should not happen */
+ }
+ if(dk3opt_get_num_args(dkdbtj.opt) > 3) {
+ dk3app_log_i3(
+ dkdbtj.app, DK3_LL_WARNING, 164, 165,
+ dk3opt_get_arg(dkdbtj.opt, 3)
+ );
+ }
+ } else {
+ dkdbt_make_reverse_file(&dkdbtj, stdout, 0);
+ }
+ dk3dbi_close(dkdbtj.in);
+ } else {
+ /* ERROR: Failed to open input database! */
+ }
+ } else {
+ /* BUG: Should not happen */
+ }
+ } break;
+ default: {
+ /* ERROR: Wrong number of arguments! */
+ if(dk3opt_get_num_args(dkdbtj.opt) > 3) {
+ dk3app_log_i3(
+ app, DK3_LL_ERROR, 164, 165,
+ dk3opt_get_arg(dkdbtj.opt, 3)
+ );
+ }
+ } break;
+ }
+ }
+ }
+ }
+ dkdbt_job_end(&dkdbtj);
+}
+
+
+
+/** Split SQL input lines.
+ @param app Application structure.
+ @param msg Localized message texts.
+ @param infile Input file, opened for text reading.
+ @param outfile Output file, opened for text writing.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkdbt_split_for_files(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ FILE *infile,
+ FILE *outfile
+)
+{
+ int back = 0;
+ int inputc; /* Current input character. */
+ int cc; /* Flag: Can continue. */
+ int inputt; /* Input character classification. */
+ int state; /* Current state. */
+ char c; /* Current input character. */
+ $? "+ dkdbt_split_for_files"
+ dkdbt_sql_split_reset(&state);
+ do {
+ cc = 0;
+ inputc = fgetc(infile);
+ if(inputc != EOF) {
+ cc = 1;
+ c = (char)inputc;
+ inputt = I_ANY;
+ switch(c) {
+ case '\\': inputt = I_BS; break;
+ case '/': inputt = I_SL; break;
+ case '*': inputt = I_AST; break;
+ case '\'': inputt = I_Q; break;
+ case '"': inputt = I_DQ; break;
+ case '`': inputt = I_BT; break;
+ case ')': inputt = I_CL; break;
+ case ',': inputt = I_COMMA; break;
+ case '-': inputt = I_MINUS; break;
+ case '\n': inputt = I_NL; break;
+ }
+ switch(dkdbt_sql_split_step(&state, inputt)) {
+ case O_NL: {
+ fputc('\n', outfile);
+ } break;
+ }
+ fputc(inputc, outfile);
+ }
+ } while(cc);
+ if(state == ST_N) {
+ back = 1;
+ } else {
+ /* ERROR: Error in SQL input! */
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 11);
+ } $? "- dkdbt_split_for_files"
+ return back;
+}
+
+
+
+/** Issue error message for wrong file type.
+ @param app Application structure for diagnostics.
+ @param msg Array containing localized message texts.
+ @param en File name.
+ @param es Stat information for file.
+*/
+static
+void
+dkdbt_wrong_file_type(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const *en,
+ dk3_stat_t const *es
+)
+{
+ dkChar const *oldsourcename; /* Previous source file name. */
+ unsigned long oldsourceline; /* Previous source file line. */
+
+ oldsourcename = dk3app_get_source_file(app);
+ oldsourceline = dk3app_get_source_line(app);
+ dk3app_set_source_file(app, en);
+ dk3app_set_source_line(app, 0UL);
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 10);
+ dk3app_set_source_file(app, oldsourcename);
+ dk3app_set_source_line(app, oldsourceline);
+}
+
+
+/** Process one input file for splitting SQL lines.
+ @param app Application structure.
+ @param msg Localized message texts.
+ @param fipo Input file, opened for text reading.
+ @param xargc Number of command line arguments.
+ @param xargv Command line arguments array.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkdbt_split_input_file(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ FILE *fipo,
+ int xargc,
+ dkChar const * const *xargv
+)
+{
+ dkChar fnb[DK3_MAX_PATH]; /* Copy of file name. */
+ FILE *outf; /* Output file. */
+ dk3_dir_t *fne; /* File name expander. */
+ dk3_stat_t const *es; /* stat inf for current file. */
+ dkChar const *en; /* Full name current file. */
+ int back = 0;
+
+ if(xargc > 3) {
+ if(dk3str_len(xargv[3]) < DK3_SIZEOF(fnb,dkChar)) {
+ dk3str_cpy_not_overlapped(fnb, xargv[3]);
+ dk3str_correct_filename(fnb);
+ if(dk3sf_must_expand(fnb)) {
+ fne = dk3dir_fne_open_app(fnb, app);
+ if(fne) {
+ if(dk3dir_get_number_of_files(fne) == 1) {
+ if(dk3dir_get_next_file(fne)) {
+ en = dk3dir_get_fullname(fne);
+ es = dk3dir_get_stat(fne);
+ if((en) && (es)) {
+ switch((es->ft) & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_REGULAR: {
+ outf = dk3sf_fopen_app(en, dk3app_not_localized(24), app);
+ if(outf) {
+ if(dkdbt_split_for_files(app, msg, fipo, outf)) {
+ back = 1;
+ }
+ if(!dk3sf_fclose_fn_app(outf, en, app)) {
+ back = 0;
+ }
+ } else {
+ /* ERROR: Failed to open output file! */
+ }
+ } break;
+ default: {
+ /* ERROR: Wrong file type! */
+ dkdbt_wrong_file_type(app, msg, en, es);
+ } break;
+ }
+ } else {
+ /* BUG: Should not happen! */
+ }
+ } else {
+ /* ERROR: No matching file name! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 215, 216, fnb);
+ }
+ } else {
+ if(dk3dir_get_number_of_files(fne)) {
+ /* ERROR: Too many matching file names! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 168, 169, fnb);
+ } else {
+ /* ERROR: No matching file name! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 215, 216, fnb);
+ }
+ }
+ dk3dir_close(fne);
+ } else {
+ /* ERROR: Failed to open file name expander! */
+ }
+ } else {
+ outf = dk3sf_fopen_app(fnb, dk3app_not_localized(24), app);
+ if(outf) {
+ if(dkdbt_split_for_files(app, msg, fipo, outf)) {
+ back = 1;
+ }
+ if(!dk3sf_fclose_fn_app(outf, fnb, app)) {
+ back = 0;
+ }
+ } else {
+ /* ERROR: Failed to open output file! */
+ }
+ }
+ } else {
+ /* ERROR: File name too long! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 65, 66, xargv[3]);
+ }
+ } else {
+ if(dkdbt_split_for_files(app, msg, fipo, stdout)) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Split long lines in mysqldump output.
+ @param app Application structure for diagnostics.
+ @param msg Localized messages.
+ @param xargc Number of command line arguments.
+ @param xargv Command line arguments array.
+*/
+static
+void
+dkdbt_split_sql_lines(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ int xargc,
+ dkChar const * const *xargv
+)
+{
+ dkChar fnb[DK3_MAX_PATH]; /* Copy of file name. */
+ FILE *fipo; /* Input file. */
+ dk3_dir_t *fne; /* File name expander. */
+ dkChar const *en; /* File name current file. */
+ dk3_stat_t const *es; /* stat info current file. */
+ int ok = 1; /* Flag: No errors. */
+ int have_files = 0; /* Flag: Files found. */
+
+ $? "+ dkdbt_split_sql_lines"
+#if VERSION_BEFORE_20150821
+ ok = 1; have_files = 0;
+#endif
+ if(xargc > 2) {
+ if(dk3str_len(xargv[2]) < DK3_SIZEOF(fnb,DK3_SIZEOF(fnb,dkChar))) {
+ dk3str_cpy_not_overlapped(fnb, xargv[2]);
+ dk3str_correct_filename(fnb);
+ if(dk3sf_must_expand(fnb)) {
+ fne = dk3dir_fne_open_app(fnb, app);
+ if(fne) {
+ if(dk3dir_get_number_of_files(fne)) {
+ ok = 1;
+ while(dk3dir_get_next_file(fne)) {
+ en = dk3dir_get_shortname(fne);
+ es = dk3dir_get_stat(fne);
+ if((en) && (es)) {
+ switch((es->ft) & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_REGULAR: {
+ fipo = dk3sf_fopen_app(
+ en,
+ dk3app_not_localized(22),
+ app
+ );
+ if(fipo) {
+ have_files = 1;
+ if(!dkdbt_split_input_file(app, msg, fipo, xargc, xargv))
+ {
+ ok = 0;
+ }
+ fclose(fipo);
+ } else {
+ /* ERROR: Failed to open file! */
+ ok = 0;
+ }
+ } break;
+ default: {
+ /* ERROR: Wrong file type! */
+ dkdbt_wrong_file_type(app, msg, en, es);
+ ok = 0;
+ } break;
+ }
+ } else {
+ ok = 0;
+ /* BUG: Should not happen! */
+ }
+ }
+ if((ok > 0) && (have_files > 0)) {
+ exval = 0;
+ } else {
+ if(have_files == 0) {
+ /* ERROR: No input files found! */
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 9);
+ }
+ }
+ } else {
+ /* ERROR: No matching file name! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 215, 216, fnb);
+ }
+ dk3dir_close(fne);
+ } else {
+ /* ERROR: Failed to expand file name! */
+ dk3app_log_3(app, DK3_LL_ERROR, msg, 7, 8, fnb);
+ }
+ } else {
+ fipo = dk3sf_fopen_app(fnb, dk3app_not_localized(22), app);
+ if(fipo) {
+ if(dkdbt_split_input_file(app, msg, fipo, xargc, xargv)) {
+ exval = 0;
+ }
+ fclose(fipo);
+ } else {
+ /* ERROR: Failed to open file! */
+ }
+ }
+ } else {
+ /* ERROR: Input file name too long! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 65, 66, xargv[2]);
+ }
+ } else {
+ if(dkdbt_split_for_files(app, msg, stdin, stdout)) {
+ exval = 0;
+ }
+ } $? "- dkdbt_split_sql_lines"
+}
+
+
+
+/** The main() function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, any other value indicates an error.
+*/
+DK3_MAIN
+{
+ dk3_app_t *app = NULL; /* Application structure. */
+ dkChar const * const *msg = NULL; /* Localized message texts. */
+ dkChar const * const *xargv; /* Command line arguments array. */
+ int xargc; /* Number of command line arguments. */
+ $!trace-init dkdbtool.deb
+ $? "+ main"
+ app = dk3app_open_command(
+ argc, (dkChar const * const *)argv, dkt_group_name
+ );
+ if(app) {
+ msg = dk3app_messages(
+ app, dkdbt_stt_file_name, (dkChar const **)dkdbt_message_texts
+ );
+ xargc = dk3app_get_argc(app);
+ xargv = dk3app_get_argv(app);
+ if(xargc > 1) {
+ switch(dk3str_array_abbr(dkdbt_commands, xargv[1], dkT('$'), 0)) {
+ case 0: case 1: { /* Help */
+ dkdbt_show_help(app);
+ exval = 0;
+ } break;
+ case 2: case 3: { /* Version */
+ dkdbt_show_version(app);
+ exval = 0;
+ } break;
+ case 4: case 5: case 13: case 14:{ /* License */
+ dkdbt_show_license(app);
+ exval = 0;
+ } break;
+ case 6: case 7: { /* Features */
+ dkdbt_show_features(app, msg);
+ exval = 0;
+ } break;
+ case 8: { /* Copy */
+ dkdbt_copy(app, msg, xargc, xargv);
+ } break;
+ case 9: { /* Make */
+ dkdbt_make(app, msg, xargc, xargv);
+ } break;
+ case 10: { /* Reverse make. */
+ dkdbt_make_reverse(app, msg, xargc, xargv);
+ } break;
+ case 11: case 12: { /* Split SQL lines. */
+ dkdbt_split_sql_lines(app, msg, xargc, xargv);
+ } break;
+ default: { /* Unknown command. */
+ /* ERROR: Unknown command! */
+ dk3app_log_3(app, DK3_LL_ERROR, dkdbt_message_texts, 5, 6, xargv[1]);
+ dkdbt_show_help(app);
+ } break;
+ }
+ } else {
+ /* ERROR: Syntax */
+ dk3app_log_1(app, DK3_LL_ERROR, dkdbt_message_texts, 4);
+ dkdbt_show_help(app);
+ }
+ dk3app_close(app);
+ } else {
+ /* ERROR: Memory */
+ fputs("Error: Not enough memory!\n", stderr);
+ fflush(stderr);
+ }
+ $? "- main %d", exval
+ $!trace-end
+ fflush(stdout);
+ exit(exval); return exval;
+}
+
+
diff --git a/support/dktools/dkdbt.rc b/support/dktools/dkdbt.rc
new file mode 100644
index 0000000000..3c3df1cb0a
--- /dev/null
+++ b/support/dktools/dkdbt.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Database tool\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "Database tool\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "dkdbt\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/dkdbt2.c b/support/dktools/dkdbt2.c
new file mode 100644
index 0000000000..425ccca16f
--- /dev/null
+++ b/support/dktools/dkdbt2.c
@@ -0,0 +1,903 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dkdbt2.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dkdbt2.c The dkdbt2 module.
+*/
+
+
+#line 9 "dkdbt2.ctr"
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4dbi.h"
+#include "dk4dbit8.h"
+#include "dk4dbitw.h"
+#include "dk4dbit.h"
+#include "dk4fput.h"
+#include "dk4app.h"
+#include "dk4vers.h"
+
+
+
+/** Actions the program can perform.
+*/
+enum {
+ /** Do nothing (illegal options).
+ */
+ DKDBT_ACTION_NONE = 0 ,
+
+ /** Copy one database to another.
+ */
+ DKDBT_ACTION_COPY = 1 ,
+
+ /** Make database from text.
+ */
+ DKDBT_ACTION_FROM_TEXT = 2 ,
+
+ /** Convert database to text.
+ */
+ DKDBT_ACTION_TO_TEXT = 3
+};
+
+
+/** License conditions.
+*/
+static const dkChar * const dkdbt_license_text[] = {
+dkT("This software uses code from the following projects, either directly or as"),
+dkT("a library:"),
+dkT(""),
+dkT("dktools\t\tDirk Krause's tools and libraries."),
+dkT("\t\tSee http://dktools.sourceforge.net/ for more information."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT("zlib\t\tData compression library."),
+dkT("\t\tSee http://www.zlib.net/ for more information."),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT("bzip2\t\tData compression program and library."),
+dkT("\t\tSee http://www.bzip.org/ for more information."),
+#endif
+dkT(""),
+dkT("All the licenses below apply to the program."),
+dkT("Licenses for used libraries are shown as found on my Scientific Linux 6.x"),
+dkT("computer in the /usr/share/doc directory on 2015-04-01. Check the project"),
+dkT("homepages of the used libraries for additional information and/or updated"),
+dkT("license terms."),
+dkT(""),
+dkT(""),
+dkT("DK tools and libraries license"),
+dkT("=============================="),
+dkT("Copyright (c) 2015-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above copyright notice,"),
+dkT(" this list of conditions and the following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("* Neither the name of the Dirk Krause nor the names of contributors may be"),
+dkT(" used to endorse or promote products derived from this software without"),
+dkT(" specific prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\""),
+dkT("AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED."),
+dkT(""),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,"),
+dkT("INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,"),
+dkT("BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,"),
+dkT("DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY"),
+dkT("OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,"),
+dkT("EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT(""),
+dkT("Zlib license"),
+dkT("============"),
+dkT("(C) 1995-2004 Jean-loup Gailly and Mark Adler"),
+dkT(""),
+dkT("This software is provided 'as-is', without any express or implied"),
+dkT("warranty. In no event will the authors be held liable for any damages"),
+dkT("arising from the use of this software."),
+dkT(""),
+dkT("Permission is granted to anyone to use this software for any purpose,"),
+dkT("including commercial applications, and to alter it and redistribute it"),
+dkT("freely, subject to the following restrictions:"),
+dkT(""),
+dkT("1. The origin of this software must not be misrepresented; you must not"),
+dkT(" claim that you wrote the original software. If you use this software"),
+dkT(" in a product, an acknowledgment in the product documentation would be"),
+dkT(" appreciated but is not required."),
+dkT("2. Altered source versions must be plainly marked as such, and must not be"),
+dkT(" misrepresented as being the original software."),
+dkT("3. This notice may not be removed or altered from any source distribution."),
+dkT(""),
+dkT("Jean-loup Gailly Mark Adler"),
+dkT("jloup@gzip.org madler@alumni.caltech.edu"),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT(""),
+dkT("Bzip2 and libbzip2 library license"),
+dkT("=================================="),
+dkT("This program, \"bzip2\", the associated library \"libbzip2\", and all"),
+dkT("documentation, are copyright (C) 1996-2007 Julian R Seward. All"),
+dkT("rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions"),
+dkT("are met:"),
+dkT(""),
+dkT("1. Redistributions of source code must retain the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer."),
+dkT(""),
+dkT("2. The origin of this software must not be misrepresented; you must "),
+dkT(" not claim that you wrote the original software. If you use this "),
+dkT(" software in a product, an acknowledgment in the product "),
+dkT(" documentation would be appreciated but is not required."),
+dkT(""),
+dkT("3. Altered source versions must be plainly marked as such, and must"),
+dkT(" not be misrepresented as being the original software."),
+dkT(""),
+dkT("4. The name of the author may not be used to endorse or promote "),
+dkT(" products derived from this software without specific prior written "),
+dkT(" permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS"),
+dkT("OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED"),
+dkT("WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE"),
+dkT("GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS"),
+dkT("INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,"),
+dkT("WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS"),
+dkT("SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+dkT(""),
+dkT("Julian Seward, jseward@bzip.org"),
+dkT("bzip2/libbzip2 version 1.0.5 of 10 December 2007"),
+#endif
+dkT(""),
+NULL
+
+
+#line 176 "dkdbt2.ctr"
+};
+
+
+
+/** Short help text.
+*/
+static const dkChar * const dkdbt_help_text[] = {
+/* 0 */
+dkT(""),
+
+/* 1 */
+dkT("Database tool"),
+
+/* 2 */
+dkT(""),
+
+/* 3 */
+dkT("dkdbt -m [-a] [-c <char>] [-i <encoding>] <database> [<textfile(s)>]"),
+
+/* 4 */
+dkT("dkdbt -t <database> [<textfile>]"),
+
+/* 5 */
+dkT("dkdbt [-a] <source> <destination>"),
+
+/* 6 */
+dkT(""),
+
+/* 7 */
+dkT("-m\t\tMake database from text file(s)."),
+
+/* 8 */
+dkT("-t\t\tShow database as text, optionally save to file."),
+
+/* 9 */
+dkT("\t\tWithout -m and -t the database is copied."),
+
+/* 10 */
+dkT(""),
+
+/* 11 */
+dkT("-a\t\tAppend to existing database when copying or making"),
+
+/* 12 */
+dkT("\t\ta database. Without this option an existing database"),
+
+/* 13 */
+dkT("\t\tis truncated."),
+
+/* 14 */
+dkT("-c character\tCommentar character. Lines started by this character"),
+
+/* 15 */
+dkT("\t\tare comments."),
+
+/* 16 */
+dkT("-i encoding\tExpected input encoding when making a database from text."),
+
+/* 17 */
+dkT(""),
+
+/* 18 */
+dkT("--help\t\tShow short help text."),
+
+/* 19 */
+dkT("--manual\t*** SHOW MANUAL ***"),
+
+/* 20 */
+dkT("--version\tShow version number."),
+
+/* 21 */
+dkT("--license\tShow license information."),
+
+/* 22 */
+dkT(""),
+
+NULL
+
+
+#line 208 "dkdbt2.ctr"
+};
+
+
+
+static const dkChar version_text[] = {
+DKT_VERSION_DK
+#if DK4_HAVE_DB_H
+dkT(" bdb")
+#endif
+#if DK4_HAVE_NDBM_H
+dkT(" ndbm")
+#endif
+dkT(" mem")
+};
+
+
+/** Constant keywords, not localized.
+*/
+static const dkChar * const dkdbt_kwnl[] = {
+/* 0 */
+dkT("dktools"),
+
+/* 1 */
+dkT("dkdbt.txt"),
+
+/* 2 */
+dkT("dkdbt.str"),
+
+NULL
+
+
+#line 235 "dkdbt2.ctr"
+};
+
+
+
+/** Keywords, replaced by localized text.
+*/
+static const dkChar * const dkdbt_kw_def[] = {
+/* 0 */
+dkT("Failed to set up signal handlers!"),
+
+/* 1 */
+dkT("Failed to restore previous signal handlers!"),
+
+NULL
+
+
+#line 252 "dkdbt2.ctr"
+};
+
+
+
+/** Command line options.
+*/
+static const dk4_option_specification_t dkdbt_options[] = {
+ { dkT('m'), dkT("make"), DK4_OPT_ARG_NONE },
+ { dkT('t'), dkT("text"), DK4_OPT_ARG_NONE },
+ { dkT('a'), dkT("append"), DK4_OPT_ARG_NONE },
+ { dkT('c'), dkT("comment"), DK4_OPT_ARG_STRING },
+ { dkT('i'), dkT("input-encoding"), DK4_OPT_ARG_STRING }
+};
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Pointer to localized messages array.
+*/
+static const dkChar * const *dkdbt_msg = dkdbt_kw_def;
+
+
+
+/** Number of options in the dkdbt_options array.
+*/
+static const size_t dkdbt_sz_options =
+sizeof(dkdbt_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Number of keywords in the dkdbt_msg array.
+*/
+static size_t dkdbt_sz_msg =
+(sizeof(dkdbt_kw_def)/sizeof(DK4_PDKCHAR) - 1);
+
+
+
+/** Maximum key size (0 = unlimited).
+*/
+static size_t keymax = 4096;
+
+
+
+/** Maximum value size (0 = unlimited).
+*/
+static size_t valmax = 4096;
+
+
+
+/** Exit status code.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+/** Action to execute.
+*/
+static int action = DKDBT_ACTION_COPY;
+
+
+
+/** Expected input encoding on stdin.
+*/
+static int input_enc_s = DK4_FILE_ENCODING_ASCII;
+
+
+
+/** Expected input encoding on input files.
+*/
+static int input_enc_f = DK4_FILE_ENCODING_ASCII;
+
+
+
+/** Flag: Append instead of truncate.
+*/
+static int append = 0;
+
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+/** Pass a volatile pointer to an atomic integer.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ptr Address of atomic integer variable.
+ @return The unmodified pointer.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+/** Check whether we can continue or if a signal was received.
+ @param check_pipe Flag: Check for occured SIGPIPE signal too.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(int check_pipe)
+{
+ int back = 1;
+#ifdef SIGPIPE
+ if (0 != check_pipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_int )) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+/** Check whether we can continue.
+ @return 1 for yes, 0 for no.
+*/
+static
+int
+dkdbt_can_continue(void)
+{
+ int back = 1;
+ if (0 == sig_can_continue(1)) {
+ back = 0;
+ }
+ return back;
+}
+
+
+
+static
+void
+dkdbt_copy_databases(void)
+{
+ /* ##### */
+}
+
+
+
+static
+void
+dkdbt_make_database(void)
+{
+ /* ##### */
+}
+
+
+
+static
+void
+dkdbt_show_database(void)
+{
+ dk4_er_t er;
+ dk4_dbi_t *dbi;
+ const dkChar *fn;
+ int argc;
+
+ argc = dk4app_get_argc(app);
+ if (0 < argc) {
+ if (3 > argc) {
+ fn = dk4app_get_argv(app, 0);
+ if (NULL != fn) {
+ dk4error_init(&er);
+ dbi = dk4dbi_open(fn, 0, 0, keymax, valmax, &er);
+ if (NULL != dbi) {
+ dk4dbi_close(dbi, &er);
+ }
+ } else {
+ /* ##### ERROR: Bug */
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ##### ERROR: Too many file names */
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ##### ERROR: At least one file name required */
+ exval = EXIT_FAILURE;
+ }
+}
+
+
+
+/** Run with signal handlers installed.
+*/
+static
+void
+dkdbt_normal_run(void)
+{
+ dkChar buf[32];
+ const size_t szbuf = DK4_SIZEOF(buf,dkChar);
+ int bom = 0;
+
+ if (0 != dk4app_opt_is_set_short(app, dkT('m'), NULL)) {
+ if (0 != dk4app_opt_is_set_short(app, dkT('t'), NULL)) {
+ action = DKDBT_ACTION_NONE;
+ exval = EXIT_FAILURE;
+ /* ##### ERROR: Illegal option combination */
+ } else {
+ action = DKDBT_ACTION_FROM_TEXT;
+ if (0 != dk4app_opt_is_set_short(app, dkT('a'), NULL)) {
+ append = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('i'), NULL)) {
+ if (0 != dk4app_opt_get_string_short(buf,sz_buf,app,dkT('i'),NULL)) {
+ if (0 != dk4enc_find(&input_enc_s, &bom, buf, NULL)) {
+ input_enc_f = input_enc_s;
+ } else {
+ /* ##### ERROR: Illegal input encoding */
+ exit = EXIT_FAILURE;
+ }
+ }
+ }
+ }
+ } else {
+ if (0 != dk4app_opt_is_set_short(app, dkT('t'), NULL)) {
+ action = DKDBT_ACTION_TO_TEXT;
+ } else {
+ if (0 != dk4app_opt_is_set_short(app, dkT('a'), NULL)) {
+ append = 1;
+ }
+ }
+ }
+ if (EXIT_SUCCESS == exval) {
+ switch (action) {
+ case DKDBT_ACTION_COPY : {
+ dkdbt_copy_databases();
+ } break;
+ case DKDBT_ACTION_FROM_TEXT : {
+ dkdbt_make_database();
+ } break;
+ case DKDBT_ACTION_TO_TEXT : {
+ dkdbt_show_database();
+ } break;
+ }
+ }
+}
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+dkdbt_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ struct sigaction opipe;
+#endif
+ struct sigaction oint;
+#ifdef SIGPIPE
+ struct sigaction npipe;
+#endif
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+ int success = 0;
+
+#ifdef SIGPIPE
+ /* Set up signal handling for SIGPIPE.
+ */
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dkdbt_msg, dkdbt_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dkdbt_msg, dkdbt_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ dk4app_log_1(app, dkdbt_msg, dkdbt_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+#endif
+
+ /* Set up signal handling for SIGINT.
+ */
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dkdbt_msg, dkdbt_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dkdbt_msg, dkdbt_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, dkdbt_msg, dkdbt_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dkdbt_msg, dkdbt_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dkdbt_msg, dkdbt_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, dkdbt_msg, dkdbt_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ dkdbt_normal_run();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, dkdbt_msg, dkdbt_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dkdbt_msg, dkdbt_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+#ifdef SIGPIPE
+ /* Restore signal handling for SIGPIPE.
+ */
+ restore_old_pipe:
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dkdbt_msg, dkdbt_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+#endif
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+dkdbt_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ dkdbt_normal_run();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+#ifdef SIGPIPE
+ sigset(SIGPIPE, oldpipe);
+#endif
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+dkdbt_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = signal(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ dkdbt_normal_run();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+#ifdef SIGPIPE
+ signal(SIGPIPE, oldpipe);
+#endif
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+dkdbt_run_with_signal_handlers(void)
+{
+ dkdbt_normal_run();
+}
+#endif
+#endif
+#endif
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ dk4_sig_atomic_t shp = 0;
+
+
+#line 765 "dkdbt2.ctr"
+
+
+#line 766 "dkdbt2.ctr"
+ dk4fput_initialize_stdout();
+ dk4fput_initialize_stderr();
+ app = dk4app_open_cmd(
+ argc, argv,
+ dkdbt_options, dkdbt_sz_options,
+ dkdbt_kwnl[0], version_text,
+ dkdbt_kwnl[1], dkdbt_help_text, dkdbt_license_text
+ );
+ if (NULL != app) {
+ dkdbt_sz_msg = dk4app_string_table_size(dkdbt_kw_def);
+ dkdbt_msg = dk4app_string_table(app, dkdbt_kwnl[2], dkdbt_kw_def);
+ if (0 != dk4app_can_run_normally(app)) {
+ exval = EXIT_SUCCESS;
+ dkdbt_run_with_signal_handlers();
+#ifdef SIGPIPE
+ shp = sig_read_atomic(&sig_had_pipe);
+#endif
+ if (0 != shp) {
+
+#line 784 "dkdbt2.ctr"
+ /* ##### ERROR: Writing to pipe failed */
+ }
+ if (0 != sig_read_atomic(&sig_had_int)) {
+
+#line 787 "dkdbt2.ctr"
+ /* ##### ERROR: Interrupted */
+ }
+ } else {
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ dk4app_close(app); app = NULL;
+ }
+ fflush(stdout);
+ fflush(stderr);
+ dk4fput_cleanup_stderr();
+ dk4fput_cleanup_stdout();
+
+
+#line 801 "dkdbt2.ctr"
+
+
+#line 802 "dkdbt2.ctr"
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/dkdbt2.ctr b/support/dktools/dkdbt2.ctr
new file mode 100644
index 0000000000..90c8aba497
--- /dev/null
+++ b/support/dktools/dkdbt2.ctr
@@ -0,0 +1,804 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% module
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4dbi.h"
+#include "dk4dbit8.h"
+#include "dk4dbitw.h"
+#include "dk4dbit.h"
+#include "dk4fput.h"
+#include "dk4app.h"
+#include "dk4vers.h"
+
+
+
+/** Actions the program can perform.
+*/
+enum {
+ /** Do nothing (illegal options).
+ */
+ DKDBT_ACTION_NONE = 0 ,
+
+ /** Copy one database to another.
+ */
+ DKDBT_ACTION_COPY = 1 ,
+
+ /** Make database from text.
+ */
+ DKDBT_ACTION_FROM_TEXT = 2 ,
+
+ /** Convert database to text.
+ */
+ DKDBT_ACTION_TO_TEXT = 3
+};
+
+
+/** License conditions.
+*/
+static const dkChar * const dkdbt_license_text[] = {
+$!text macro=dkT,preprocessor
+This software uses code from the following projects, either directly or as
+a library:
+
+dktools Dirk Krause's tools and libraries.
+ See http://dktools.sourceforge.net/ for more information.
+#if DK4_HAVE_ZLIB_H
+
+zlib Data compression library.
+ See http://www.zlib.net/ for more information.
+#endif
+#if DK4_HAVE_BZLIB_H
+
+bzip2 Data compression program and library.
+ See http://www.bzip.org/ for more information.
+#endif
+
+All the licenses below apply to the program.
+Licenses for used libraries are shown as found on my Scientific Linux 6.x
+computer in the /usr/share/doc directory on 2015-04-01. Check the project
+homepages of the used libraries for additional information and/or updated
+license terms.
+
+
+DK tools and libraries license
+==============================
+Copyright (c) 2015-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#if DK4_HAVE_ZLIB_H
+
+
+Zlib license
+============
+(C) 1995-2004 Jean-loup Gailly and Mark Adler
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+
+Jean-loup Gailly Mark Adler
+jloup@gzip.org madler@alumni.caltech.edu
+#endif
+#if DK4_HAVE_BZLIB_H
+
+
+Bzip2 and libbzip2 library license
+==================================
+This program, "bzip2", the associated library "libbzip2", and all
+documentation, are copyright (C) 1996-2007 Julian R Seward. All
+rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+3. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Julian Seward, jseward@bzip.org
+bzip2/libbzip2 version 1.0.5 of 10 December 2007
+#endif
+
+$!end
+};
+
+
+
+/** Short help text.
+*/
+static const dkChar * const dkdbt_help_text[] = {
+$!string-table macro=dkT
+
+Database tool
+
+dkdbt -m [-a] [-c <char>] [-i <encoding>] <database> [<textfile(s)>]
+dkdbt -t <database> [<textfile>]
+dkdbt [-a] <source> <destination>
+
+-m Make database from text file(s).
+-t Show database as text, optionally save to file.
+ Without -m and -t the database is copied.
+
+-a Append to existing database when copying or making
+ a database. Without this option an existing database
+ is truncated.
+-c character Commentar character. Lines started by this character
+ are comments.
+-i encoding Expected input encoding when making a database from text.
+
+--help Show short help text.
+--manual *** SHOW MANUAL ***
+--version Show version number.
+--license Show license information.
+
+$!end
+};
+
+
+
+static const dkChar version_text[] = {
+DKT_VERSION_DK
+#if DK4_HAVE_DB_H
+dkT(" bdb")
+#endif
+#if DK4_HAVE_NDBM_H
+dkT(" ndbm")
+#endif
+dkT(" mem")
+};
+
+
+/** Constant keywords, not localized.
+*/
+static const dkChar * const dkdbt_kwnl[] = {
+$!string-table macro=dkT
+#
+# 0, 1, 2 Program group name, manual text, string table
+#
+dktools
+dkdbt.txt
+dkdbt.str
+$!end
+};
+
+
+
+/** Keywords, replaced by localized text.
+*/
+static const dkChar * const dkdbt_kw_def[] = {
+$!string-table macro=dkT
+#
+# 0 Error message: Failed to set up signal handlers!
+#
+Failed to set up signal handlers!
+#
+# 1 Error message: Failed to restore previous signal handlers!
+#
+Failed to restore previous signal handlers!
+$!end
+};
+
+
+
+/** Command line options.
+*/
+static const dk4_option_specification_t dkdbt_options[] = {
+ { dkT('m'), dkT("make"), DK4_OPT_ARG_NONE },
+ { dkT('t'), dkT("text"), DK4_OPT_ARG_NONE },
+ { dkT('a'), dkT("append"), DK4_OPT_ARG_NONE },
+ { dkT('c'), dkT("comment"), DK4_OPT_ARG_STRING },
+ { dkT('i'), dkT("input-encoding"), DK4_OPT_ARG_STRING }
+};
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Pointer to localized messages array.
+*/
+static const dkChar * const *dkdbt_msg = dkdbt_kw_def;
+
+
+
+/** Number of options in the dkdbt_options array.
+*/
+static const size_t dkdbt_sz_options =
+sizeof(dkdbt_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Number of keywords in the dkdbt_msg array.
+*/
+static size_t dkdbt_sz_msg =
+(sizeof(dkdbt_kw_def)/sizeof(DK4_PDKCHAR) - 1);
+
+
+
+/** Maximum key size (0 = unlimited).
+*/
+static size_t keymax = 4096;
+
+
+
+/** Maximum value size (0 = unlimited).
+*/
+static size_t valmax = 4096;
+
+
+
+/** Exit status code.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+/** Action to execute.
+*/
+static int action = DKDBT_ACTION_COPY;
+
+
+
+/** Expected input encoding on stdin.
+*/
+static int input_enc_s = DK4_FILE_ENCODING_ASCII;
+
+
+
+/** Expected input encoding on input files.
+*/
+static int input_enc_f = DK4_FILE_ENCODING_ASCII;
+
+
+
+/** Flag: Append instead of truncate.
+*/
+static int append = 0;
+
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+/** Pass a volatile pointer to an atomic integer.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ptr Address of atomic integer variable.
+ @return The unmodified pointer.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+/** Check whether we can continue or if a signal was received.
+ @param check_pipe Flag: Check for occured SIGPIPE signal too.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(int check_pipe)
+{
+ int back = 1;
+#ifdef SIGPIPE
+ if (0 != check_pipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_int )) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+/** Check whether we can continue.
+ @return 1 for yes, 0 for no.
+*/
+static
+int
+dkdbt_can_continue(void)
+{
+ int back = 1;
+ if (0 == sig_can_continue(1)) {
+ back = 0;
+ }
+ return back;
+}
+
+
+
+static
+void
+dkdbt_copy_databases(void)
+{
+ /* ##### */
+}
+
+
+
+static
+void
+dkdbt_make_database(void)
+{
+ /* ##### */
+}
+
+
+
+static
+void
+dkdbt_show_database(void)
+{
+ dk4_er_t er;
+ dk4_dbi_t *dbi;
+ const dkChar *fn;
+ int argc;
+
+ argc = dk4app_get_argc(app);
+ if (0 < argc) {
+ if (3 > argc) {
+ fn = dk4app_get_argv(app, 0);
+ if (NULL != fn) {
+ dk4error_init(&er);
+ dbi = dk4dbi_open(fn, 0, 0, keymax, valmax, &er);
+ if (NULL != dbi) {
+ dk4dbi_close(dbi, &er);
+ }
+ } else {
+ /* ##### ERROR: Bug */
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ##### ERROR: Too many file names */
+ exval = EXIT_FAILURE;
+ }
+ } else {
+ /* ##### ERROR: At least one file name required */
+ exval = EXIT_FAILURE;
+ }
+}
+
+
+
+/** Run with signal handlers installed.
+*/
+static
+void
+dkdbt_normal_run(void)
+{
+ dkChar buf[32];
+ const size_t szbuf = DK4_SIZEOF(buf,dkChar);
+ int bom = 0;
+
+ if (0 != dk4app_opt_is_set_short(app, dkT('m'), NULL)) {
+ if (0 != dk4app_opt_is_set_short(app, dkT('t'), NULL)) {
+ action = DKDBT_ACTION_NONE;
+ exval = EXIT_FAILURE;
+ /* ##### ERROR: Illegal option combination */
+ } else {
+ action = DKDBT_ACTION_FROM_TEXT;
+ if (0 != dk4app_opt_is_set_short(app, dkT('a'), NULL)) {
+ append = 1;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('i'), NULL)) {
+ if (0 != dk4app_opt_get_string_short(buf,sz_buf,app,dkT('i'),NULL)) {
+ if (0 != dk4enc_find(&input_enc_s, &bom, buf, NULL)) {
+ input_enc_f = input_enc_s;
+ } else {
+ /* ##### ERROR: Illegal input encoding */
+ exit = EXIT_FAILURE;
+ }
+ }
+ }
+ }
+ } else {
+ if (0 != dk4app_opt_is_set_short(app, dkT('t'), NULL)) {
+ action = DKDBT_ACTION_TO_TEXT;
+ } else {
+ if (0 != dk4app_opt_is_set_short(app, dkT('a'), NULL)) {
+ append = 1;
+ }
+ }
+ }
+ if (EXIT_SUCCESS == exval) {
+ switch (action) {
+ case DKDBT_ACTION_COPY : {
+ dkdbt_copy_databases();
+ } break;
+ case DKDBT_ACTION_FROM_TEXT : {
+ dkdbt_make_database();
+ } break;
+ case DKDBT_ACTION_TO_TEXT : {
+ dkdbt_show_database();
+ } break;
+ }
+ }
+}
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+dkdbt_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ struct sigaction opipe;
+#endif
+ struct sigaction oint;
+#ifdef SIGPIPE
+ struct sigaction npipe;
+#endif
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+ int success = 0;
+
+#ifdef SIGPIPE
+ /* Set up signal handling for SIGPIPE.
+ */
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dkdbt_msg, dkdbt_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, dkdbt_msg, dkdbt_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ dk4app_log_1(app, dkdbt_msg, dkdbt_sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+#endif
+
+ /* Set up signal handling for SIGINT.
+ */
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dkdbt_msg, dkdbt_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, dkdbt_msg, dkdbt_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, dkdbt_msg, dkdbt_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dkdbt_msg, dkdbt_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, dkdbt_msg, dkdbt_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, dkdbt_msg, dkdbt_sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+
+ success = 1;
+ dkdbt_normal_run();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, dkdbt_msg, dkdbt_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dkdbt_msg, dkdbt_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+#ifdef SIGPIPE
+ /* Restore signal handling for SIGPIPE.
+ */
+ restore_old_pipe:
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, dkdbt_msg, dkdbt_sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+#endif
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { exval = EXIT_FAILURE; }
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+dkdbt_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ dkdbt_normal_run();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+#ifdef SIGPIPE
+ sigset(SIGPIPE, oldpipe);
+#endif
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+dkdbt_run_with_signal_handlers(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+#ifdef SIGPIPE
+ oldpipe = signal(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ dkdbt_normal_run();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+#ifdef SIGPIPE
+ signal(SIGPIPE, oldpipe);
+#endif
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+dkdbt_run_with_signal_handlers(void)
+{
+ dkdbt_normal_run();
+}
+#endif
+#endif
+#endif
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ dk4_sig_atomic_t shp = 0;
+ $!trace-init dkdbt.deb
+ $? "+ main"
+ dk4fput_initialize_stdout();
+ dk4fput_initialize_stderr();
+ app = dk4app_open_cmd(
+ argc, argv,
+ dkdbt_options, dkdbt_sz_options,
+ dkdbt_kwnl[0], version_text,
+ dkdbt_kwnl[1], dkdbt_help_text, dkdbt_license_text
+ );
+ if (NULL != app) {
+ dkdbt_sz_msg = dk4app_string_table_size(dkdbt_kw_def);
+ dkdbt_msg = dk4app_string_table(app, dkdbt_kwnl[2], dkdbt_kw_def);
+ if (0 != dk4app_can_run_normally(app)) {
+ exval = EXIT_SUCCESS;
+ dkdbt_run_with_signal_handlers();
+#ifdef SIGPIPE
+ shp = sig_read_atomic(&sig_had_pipe);
+#endif
+ if (0 != shp) { $? "! writing to pipe failed"
+ /* ##### ERROR: Writing to pipe failed */
+ }
+ if (0 != sig_read_atomic(&sig_had_int)) { $? "! interrupted"
+ /* ##### ERROR: Interrupted */
+ }
+ } else {
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ dk4app_close(app); app = NULL;
+ }
+ fflush(stdout);
+ fflush(stderr);
+ dk4fput_cleanup_stderr();
+ dk4fput_cleanup_stdout();
+ $? "- main %d", exval
+ $!trace-end
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/dkicon.ico b/support/dktools/dkicon.ico
new file mode 100644
index 0000000000..c07cdafd81
--- /dev/null
+++ b/support/dktools/dkicon.ico
Binary files differ
diff --git a/support/dktools/dkicon.xpm b/support/dktools/dkicon.xpm
new file mode 100644
index 0000000000..69c420c91e
--- /dev/null
+++ b/support/dktools/dkicon.xpm
@@ -0,0 +1,40 @@
+/* XPM */
+static const char *xpm_dkicon[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 17 1",
+/* colors */
+" c #000000",
+". c #FDD200",
+"X c #DCB700",
+"o c #F7CE00",
+"O c #050400",
+"+ c #A48800",
+"@ c #FFD400",
+"# c #241E00",
+"$ c #B29400",
+"% c #685600",
+"& c #BA9A00",
+"* c #EBC300",
+"= c #504200",
+"- c #AB8E00",
+"; c #8D7500",
+": c #CAA800",
+"> c None",
+/* pixels */
+"@@@@@@@@@@@@@@@@",
+"@$---&*@@@@@@@@@",
+"@: $+=O&@@@@@@@@",
+"@X :@@==@@@@@@@@",
+"@X :@@;O.@@@@@@@",
+"@X :@@%#@@@@@@@@",
+"@X :@o#+@@@@@@@@",
+"@- %=#-@@@@@@@@@",
+"@....@@@*%#-@+%X",
+"@@@@@@@@@+O@&%.@",
+"@@@@@@@@@+O&%.@@",
+"@@@@@@@@@+O##*@@",
+"@@@@@@@@@+O*#=.@",
+"@@@@@@@@@+O.:O%o",
+"@@@@@@@@*;;-@&;$",
+"@@@@@@@@@@@@@@@@"
+};
diff --git a/support/dktools/dkt-version.h b/support/dktools/dkt-version.h
new file mode 100644
index 0000000000..8c08c3c96a
--- /dev/null
+++ b/support/dktools/dkt-version.h
@@ -0,0 +1,25 @@
+#ifndef DKT_VERSION_H_INCLUDED
+/** Protection from multiple inclusions.
+*/
+#define DKT_VERSION_H_INCLUDED 1
+
+/** @file dkt-version.h Version number for dktools.
+*/
+
+
+/** Current version.
+*/
+#define DKT_CHAR_VERSION "3.18.10"
+
+/** Current version.
+*/
+#define DKT_VERSION dkT("3.18.10")
+
+#if DK3_USE_WX
+/** Current version.
+*/
+#define DKT_WXCHAR_VERSION wxT("3.18.10")
+#endif
+
+#endif
+
diff --git a/support/dktools/dkt.h b/support/dktools/dkt.h
new file mode 100644
index 0000000000..c7695c9e70
--- /dev/null
+++ b/support/dktools/dkt.h
@@ -0,0 +1,608 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dkt.ctr
+*/
+
+/*
+Copyright (C) 2011-2015, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dkt.h Header file for the dkt module.
+*/
+
+#ifndef DKT_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DKT_H_INCLUDED 1
+
+
+#line 10 "dkt.ctr"
+
+
+#if DK3_HAVE_OPENSSL_RAND_H
+#include <openssl/rand.h>
+#endif
+
+
+
+/** Handler function to process one configuration line.
+ @param o Object to modify during processing.
+ @param k Key found in the line.
+ @param v Value found in the line or NULL if no value was found.
+ @return 1 on success, 0 on error (can continue), -1 on error (abort).
+*/
+typedef int dkt_conf_fct_t(void *o, dkChar const *k, dkChar const *v);
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Print current working directory.
+ @param app Application structure.
+ @param sn Section name for configuration file.
+ @param msg Messages.
+ @param kwnl Keywords, not localized.
+ @return 0 on success or other exit code on errors.
+*/
+int
+dkt_cwd(
+ dk3_app_t *app,
+ dkChar const *sn,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl
+);
+
+/** Sort texts line by line.
+ @param app Application structure.
+ @param sn Section name for configuration file.
+ @param msg Messages.
+ @param kwnl Keywords, not localized.
+ @return 0 on success or other exit code on errors.
+*/
+int
+dkt_sort(
+ dk3_app_t *app,
+ dkChar const *sn,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl
+);
+
+/** List specified files.
+ @param app Application structure.
+ @param sn Section name for configuration file.
+ @param msg Message texts.
+ @param kwnl Keywords, not localized.
+ @return Exit status code.
+*/
+int
+dkt_ls(
+ dk3_app_t *app,
+ dkChar const *sn,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl
+);
+
+/** Read configuration file section.
+ @param app Application structure.
+ @param sn Section name.
+ @param obj Object to store information.
+ @param fct Function to process key/value pair.
+*/
+void
+dkt_tool_read_conf(
+ dk3_app_t *app, dkChar const *sn, void *obj, dkt_conf_fct_t *fct
+);
+
+/** Find encoding.
+ @param app Application structure.
+ @param enc Pointer to encoding variable.
+ @param val Text containing encoding.
+ @param de Default encoding.
+ @return 1 on success, 0 on error.
+ */
+int
+dkt_tool_set_encoding(
+ dk3_app_t *app,
+ int *enc,
+ dkChar const *val,
+ int de
+);
+
+/** Perform checksum or checksize command.
+ @param app Application structure.
+ @param sn Section name for configuration file.
+ @param msg Localized messages.
+ @param kwnl Keywords, not localized.
+ @param what Flag: Run for checksum (0) or checksize (1).
+ @return Exit status code.
+*/
+int
+dkt_check(
+ dk3_app_t *app,
+ dkChar const *sn,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl,
+ int what
+);
+
+/** Run the "uid" sub-command.
+ @param app Application structure for diagnostics.
+ @param sn Section name for configuration file.
+ @param msg Localized messages.
+ @param kwnl Keywords, not localized.
+ @return Exit status code.
+*/
+int
+dkt_uid(
+ dk3_app_t *app,
+ dkChar const *sn,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl
+);
+
+/** Run the "tape" sub-command.
+ @param app Application structure for diagnostics.
+ @param sn Section name for configuration file.
+ @param msg Localized messages.
+ @param kwnl Keywords, not localized.
+ @return Exit status code.
+*/
+int
+dkt_tape(
+ dk3_app_t *app,
+ dkChar const *sn,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl
+);
+
+/** Run the "tape-report" sub-command.
+ @param app Application structure for diagnostics.
+ @param sn Section name for configuration file.
+ @param msg Localized messages.
+ @param kwnl Keywords, not localized.
+ @return Exit status code.
+*/
+int
+dkt_tapereport(
+ dk3_app_t *app,
+ dkChar const *sn,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl
+);
+
+/** Run the "tapeset" sub-command.
+ @param app Application structure for diagnostics.
+ @param sn Section name for configuration file.
+ @param msg Localized messages.
+ @param kwnl Keywords, not localized.
+ @return Exit status code.
+*/
+int
+dkt_tapeset(
+ dk3_app_t *app,
+ dkChar const *sn,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl
+);
+
+/** Run the "dkt blocksize" sub-command.
+ @param app Application structure for diagnostics.
+ @param sn Section name for configuration file.
+ @param msg Localized messages.
+ @param kwnl Keywords, not localized.
+ @return Exit status code.
+*/
+int
+dkt_blocksize(
+ dk3_app_t *app,
+ dkChar const *sn,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl
+);
+
+/** Run the "dkt hex" sub-command.
+ @param app Application structure for diagnostics.
+ @param sn Section name for configuration file.
+ @param msg Localized messages.
+ @param kwnoloc Not localized keywords.
+ @param f_oct Flag: Show contents octal.
+ @return Exit status code.
+*/
+int
+dkt_hex(
+ dk3_app_t *app,
+ dkChar const *sn,
+ dkChar const * const *msg,
+ dkChar const * const *kwnoloc,
+ int f_oct
+);
+
+/** Create password suggestions.
+ @param app Application structure.
+ @param sn Section name for configuration file.
+ @param msg Localized messages.
+ @param kwnoloc Keywords, not localized.
+ @return Exit status code.
+*/
+int
+dkt_create_password(
+ dk3_app_t *app,
+ dkChar const *sn,
+ dkChar const * const *msg,
+ dkChar const * const *kwnoloc
+);
+
+/** Convert standard input, file or cmd argument to LaTeX.
+ @param app Application structure.
+ @param sn Section name for configuration file.
+ @param msg Localized messages.
+ @param kwnoloc Keywords, not localized.
+ @return Exit status code.
+*/
+int
+dkt_lat(
+ dk3_app_t *app,
+ dkChar const *sn,
+ dkChar const * const *msg,
+ dkChar const * const *kwnoloc
+);
+
+/** Conversion to HTML (dkt html).
+ @param app Application structure.
+ @param sn Section name for configuration file.
+ @param msg Localized texts.
+ @param kwnl Keywords, not localized.
+*/
+int
+dkt_html(
+ dk3_app_t *app,
+ dkChar const *sn,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl
+);
+
+/** Cat file(s).
+ @param app Application structure.
+ @param sn Configuration file section name.
+ @param msg Localized texts.
+ @param kwnl Keywords, not localized.
+*/
+int
+dkt_cat(
+ dk3_app_t *app,
+ dkChar const *sn,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl
+);
+
+/** Create password.
+ @param app Application structure.
+ @param sn Configuration file section name.
+ @param msg Localized texts.
+ @param kwnl Keywords, not localized.
+*/
+int
+dkt_crp(
+ dk3_app_t *app,
+ dkChar const *sn,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl
+);
+
+/** Show help text file(s).
+ @param app Application structure.
+ @param sn Configuration file section name.
+ @param msg Localized texts.
+ @param kwnl Keywords, not localized.
+ @param htp Help topic index.
+*/
+int
+dkt_help(
+ dk3_app_t *app,
+ dkChar const *sn,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl,
+ int htp
+);
+
+/** Find message digest type and digest encoding.
+ @param jmdt Pointer to result variable for digest type.
+ @param jmde Pointer to result variable for digest encoding.
+ @param exval Pointer to exit status code variable.
+ @param txt Text to inspect.
+ @param app Application structure for diagnostics.
+ @param msg Message array for diagnostics.
+ @param verb Flag: Verbose.
+ @return 1 on success, 0 on error.
+*/
+int
+dkt_tool_set_md_type(
+ int *jmdt,
+ int *jmde,
+ int *exval,
+ dkChar const *txt,
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ int verb
+);
+
+/** Set size_t value from string.
+ @param rp Pointer to result variable.
+ @param src String containing the value.
+ @param msg Localized text messages for diagnostics.
+ @param kwnl Non-localized keywords for diagnostics.
+ @param app Application structure for diagnostics.
+ @param exc Pointer to exit code variable.
+ @return 1 on success, 0 on error.
+*/
+int
+dkt_tool_set_size(
+ size_t *rp,
+ dkChar const *src,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl,
+ dk3_app_t *app,
+ int *exc
+);
+
+/** Run the "dkt erase-disk" sub-command.
+ @param app Application structure for diagnostics.
+ @param sn Section name for configuration file.
+ @param msg Localized messages.
+ @param kwnl Not localized keywords.
+ @return Exit status code.
+*/
+int
+dkt_ed(
+ dk3_app_t *app,
+ dkChar const *sn,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl
+);
+
+/** Run the "dkt random" sub-command.
+ @param app Application structure for diagnostics.
+ @param sn Section name for configuration file.
+ @param msg Localized messages.
+ @param kwnl Not localized keywords.
+ @return Exit status code.
+*/
+int
+dkt_rnd(
+ dk3_app_t *app,
+ dkChar const *sn,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+/** @defgroup dktresult Exit codes for dkt. */
+/**@{*/
+/** Result: No error occured.
+*/
+#define DKT_RESULT_OK 0
+
+/** Error: Unspecific error.
+*/
+#define DKT_RESULT_ERR_UNSPECIFIC 1
+
+/** Error: Aborted by signal.
+*/
+#define DKT_RESULT_ERR_SIGNAL 2
+
+/** Error: Illegal/unknown option or problem in configuration file.
+*/
+#define DKT_RESULT_ERR_OPTION 3
+
+/** Error: getcwd() failed.
+*/
+#define DKT_RESULT_ERR_GETCWD 4
+
+/** Error: Memory allocation failed.
+*/
+#define DKT_RESULT_ERR_MEMORY 5
+
+/** Error: Failed to open one of the input files.
+*/
+#define DKT_RESULT_ERR_FOPEN 6
+
+/** Error: No such file.
+*/
+#define DKT_RESULT_ERR_FILENAME 7
+
+/** Error: Checksum or size mismatch.
+*/
+#define DKT_RESULT_ERR_MISMATCH 8
+
+/** Error: Failed to create or write output.
+*/
+#define DKT_RESULT_ERR_OUTPUT 9
+
+/** Error: The PRNG was unable to deliver enough bytes.
+*/
+#define DKT_RESULT_ERR_PRNG 10
+
+/** Error: Invalid input (Input can't be processed).
+*/
+#define DKT_RESULT_ERR_INPUT 11
+
+/** Error: Mathematical overflow.
+ */
+#define DKT_RESULT_ERR_MATH_OVERFLOW 12
+
+/** Error: Failed to open directory.
+*/
+#define DKT_RESULT_ERR_OPENDIR 13
+
+/** Error: Functionality not supported on this system.
+*/
+#define DKT_RESULT_ERR_UNSUPPORTED 14
+
+/** Error: Status code from command execution indicates error.
+*/
+#define DKT_RESULT_ERR_SYSEXEC 15
+/**@}*/
+
+
+
+/** @defgroup dktsortcrit Sort criteria for "dkt sort". */
+/**@{*/
+/** Sort criteria: Normal text search.
+*/
+#define DKT_SORT_NORMAL 0
+
+/** Sort criteria: Sort by leading integer.
+*/
+#define DKT_SORT_INTEGER 1
+
+/** Sort criteria: Sort by leading unsigned integer.
+*/
+#define DKT_SORT_UNSIGNED 2
+
+/** Sort criteria: Sort by leading double.
+*/
+#define DKT_SORT_DOUBLE 3
+
+/** Sort criteria mask.
+*/
+#define DKT_SORT_CRITERIA_MASK 7
+
+/** Normalize strings before comparison.
+*/
+#define DKT_SORT_NORMALIZE 8
+
+/** Ignore leading whitespaces.
+*/
+#define DKT_SORT_IGNORE_LWHS 16
+
+/** Do exact comparison.
+*/
+#define DKT_SORT_EXACT 32
+
+/** Merge equal strings.
+*/
+#define DKT_SORT_MERGE 64
+
+/** Invert search order.
+*/
+#define DKT_SORT_INVERT 128
+
+/** Case insensitve comparisons.
+*/
+#define DKT_SORT_CASEINS 256
+
+/** Show lines without value before lines with value.
+*/
+#define DKT_SORT_NOVALUE_FIRST 512
+
+/**@}*/
+
+
+
+/** @defgroup dktsortmerge Merge criteria for "dkt sort". */
+/**@{*/
+/** No line merging.
+*/
+#define DKT_SORT_MERGE_NONE 0
+
+/** Merge lines evaluating equally.
+*/
+#define DKT_SORT_MERGE_EQUAL 1
+
+/** Merge lines exactly equally.
+*/
+#define DKT_SORT_MERGE_EXACT 2
+/**@}*/
+
+/** @defgroup pwclasses Password classes. */
+/**@{*/
+
+/** Simple password.
+*/
+#define DKT_PWCLASS_SIMPLE 0
+
+/** Hexadecimal characters.
+*/
+#define DKT_PWCLASS_HEX 1
+
+/** ASCII-85 set password.
+*/
+#define DKT_PWCLASS_A85 2
+/**@}*/
+
+/** Default line size for the sort component.
+*/
+#define DKT_SORT_LINE_SIZE ((size_t)4096U)
+
+/** Size of builtin buffer for dkt blocksize.
+*/
+#define DKT_BLOCKSIZE_OUTPUT_SIZE ((size_t)4096)
+
+/** Size of builtin buffer for dkt latex.
+*/
+#define DKT_LATEX_LINE_SIZE ((size_t)4096U)
+
+/** Line size for dkt html.
+*/
+#define DKT_HTML_LINE_SIZE ((size_t)4096U)
+
+/** Size for long options
+*/
+#define DKT_LONGOPT_LINE_SIZE ((size_t)256)
+
+/** Maximum length for password.
+*/
+#define DKT_PASSWORD_MAXLENGTH 4096
+
+/** Line size for dkt tapeset.
+*/
+#define DKT_TS_LINE_SIZE 1024
+
+/** Buffer size for dkt ed.
+*/
+#define DKT_ED_BUFFER_SIZE ((size_t)16384U)
+
+/** Buffer size for dkt random.
+*/
+#define DKT_RND_BUFFER_SIZE ((size_t)16384U)
+
+/** For allocation of string pointer arrays.
+*/
+typedef dkChar const *DKT_PDKCHAR;
+
+
+
+
+#endif
diff --git a/support/dktools/dktools-el.spec b/support/dktools/dktools-el.spec
new file mode 100644
index 0000000000..13237847d4
--- /dev/null
+++ b/support/dktools/dktools-el.spec
@@ -0,0 +1,254 @@
+Name: dktools
+Version: 3.15.0
+Source: file:///home/krause/work/dktools-3.15.0.tar.gz
+Release: 1%{?dist}
+Summary: Dirk Krause's tools and libraries
+Vendor: Dirk Krause
+# Packager: Dirk Krause
+Group: Applications/System
+License: BSD
+URL: http://dktools.sourceforge.net/index.html
+BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
+
+BuildRequires: mysql-devel zlib-devel bzip2-devel libpng-devel openssl-devel libjpeg-devel libtiff-devel net-snmp-devel wxGTK wxGTK-devel
+Requires: bzip2 openssl net-snmp wxGTK
+Prefix: %{_prefix}
+
+%description
+A set of tools for graphics conversion, text conversion, software
+development, administration and printing and some general-purpose tools.
+ bmpp / wxbmpp Convert PNG/JPEG/TIFF to PS/EPS/PDF
+ fig2lat Convert FIG to PGF,EPS+TeX,PDF+TeX,EPS,SVG
+ wximgsz Suggest good sizes to rescale bitmap images
+ htmlbook Publish HTML like a book
+ dkct / wxdkct Preprocessor for C, C++, Objective-C and Java
+ (debugging/tracing, state machines, wxWidgets GUIs)
+ dkwxwiz Create project skeleton for wxWidgets+dktools based programs
+ dkt Multi-purpose tool:
+ * File and directory listings, column order is configurable
+ * Text conversion to HTML
+ * Text conversion to LaTeX
+ * Text sorting
+ * Text re-encoding
+ * File/directory checksumming and checksum verification
+ * Show file contents in hexadecimal or octal notation
+ * Backup media management
+ * Password suggestion
+ * UID suggestion
+ * Pattern stream to erase disks or partitions
+ * Random data block generation
+ dknet Data transmission from one sender to multiple receivers
+ dkdbt Tool for simple databases
+ itadmin Use a MySQL database to manage your IT
+ printqd Print quota enforcement for LPRng print systems
+
+%prep
+%setup -q
+# %setup
+
+
+%build
+%configure
+make %{?_smp_mflags}
+
+%install
+rm -rf $RPM_BUILD_ROOT
+make install DESTDIR=$RPM_BUILD_ROOT
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+
+%files
+%defattr(-,root,root,-)
+%doc README bsdlic.txt
+%{_bindir}/*
+%{_datadir}/applications/*
+%{_datadir}/dk3app
+%{_datadir}/dkt-3
+%config %{_sysconfdir}/dk3app/dk3paper.conf
+
+
+
+#
+# The lib sub-package installes the shared libraries.
+#
+
+%package lib
+Summary: Shared libraries from the DK tools project
+Group: Development/Libraries
+Requires: dktools = %{version}-%{release} bzip2 openssl net-snmp wxGTK
+Prefix: %{_prefix}
+
+%description lib
+The shared libraries created from the DK tools project.
+
+%post lib
+ldconfig
+
+%postun lib
+ldconfig
+
+%files lib
+%defattr(-,root,root,-)
+%{_libdir}/lib*
+
+#
+# The devel sub-package installs developer support.
+#
+
+%package devel
+Summary: Development files for libraries from the DK tools project
+Group: Development/Libraries
+Requires: dktools-lib = %{version}-%{release} mysql-devel zlib-devel bzip2-devel libpng-devel openssl-devel libjpeg-devel libtiff-devel net-snmp-devel gcc wxGTK wxGTK-devel
+Prefix: %{_prefix}
+
+%description devel
+If you want to use modules from the DK tools project in your programs,
+you need the libraries from the dktools-lib package and the header
+files provided by this project.
+
+%files devel
+%defattr(-,root,root,-)
+%{_includedir}/*
+%{_libdir}/pkgconfig/dktools.pc
+
+%changelog
+
+* Fri Mar 13 2015 Dirk Krause <devnull@fh-schmalkalden.de> 3.18.8-0.0.1
+- configure script and Makefile modified
+
+* Sat Jun 28 2014 Dirk Krause <devnull@fh-schmalkalden.de> 3.15.0-0.0.1
+- Source code reorganized.
+
+* Thu Jun 19 2014 Dirk Krause <devnull@fh-schmalkalden.de> 3.14.0-0.0.1
+- Options -S... added to dkct and wxdkct.
+- Memory usage reorganized for bit matrices.
+- Cache friendly algorithm for bit matrix expansion.
+- dktools.spec file modified to build sub-packages lib and devel.
+
+* Mon Jul 29 2013 Dirk Krause <devnull@fh-schmalkalden.de> 3.3.1-0.0.1
+- Bugfix in distribution and build system.
+
+* Sun Jul 28 2013 Dirk Krause <devnull@fh-schmalkalden.de> 3.3.0-0.0.1
+- API change, comparison and evaluation functions operate on void const *
+ pointers.
+
+* Wed Jul 24 2013 Dirk Krause <devnull@fh-schmalkalden.de> 3.2.2-0.0.1
+- More useful error message for malformed path to dkt ls on Windows
+ (paths in double quotes where backslash escapes closing double quote).
+
+* Thu Mar 20 2013 Dirk Krause <devnull@fh-schmalkalden.de> 3.0.6-0.0.1
+- dkct enhanced for unknown classes.
+
+* Wed Mar 20 2013 Dirk Krause <devnull@fh-schmalkalden.de> 3.0.5-0.0.1
+- Bugfix: Use AddButton method of wxStdButtonSizer, not Add.
+
+* Sun Mar 17 2013 Dirk Krause <devnull@fh-schmalkalden.de> 3.0.4-0.0.1
+- The dk3sock4 module was added.
+
+* Sat Mar 16 2013 Dirk Krause <devnull@fh-schmalkalden.de> 3.0.3-0.0.1
+- Online documentation updated for the -f option in dknet.
+
+* Thu Mar 14 2013 Dirk Krause <devnull@fh-schmalkalden.de> 3.0.2-0.0.1
+- The dknet program is more verbose now when run as sender.
+
+* Sun Feb 03 2013 Dirk Krause <devnull@fh-schmalkalden.de> 3.0.1-0.0.1
+- The dkwxwiz program was added.
+- The winprint program (for Windows) was added.
+- The wprclean program (for Windows) was added.
+- The lprngcl program (for Windows) was added.
+- Option bbts for fig2lat.
+- Bugfix in Win32 setup: The dk3paper.conf file was not installed.
+
+* Thu Jan 31 2013 Dirk Krause <devnull@fh-schmalkalden.de> 3.0.0-0.0.12
+- Code for 3.0.0 release.
+
+* Tue Jan 29 2013 Dirk Krause <devnull@fh-schmalkalden.de> 3.0.0-0.0.11
+- All code completed, now preparing for the initial release.
+
+* Sun Jan 20 2013 Dirk Krause <devnull@fh-schmalkalden.de> 3.0.0-0.0.10
+- Program fig2lat added, without SVG driver (not finished yet).
+- dkwt clp is less noisy now.
+
+* Thu Sep 27 2012 Dirk Krause <devnull@fh-schmalkalden.de> 3.0.0-0.0.9
+- New preprocessor directive TRACE_DEBUG added.
+
+* Sun Aug 19 2012 Dirk Krause <devnull@fh-schmalkalden.de> 3.0.0-0.0.8
+- Bugfix in wximgsz: Colors now initialized correctly.
+
+* Fri Jul 06 2012 Dirk Krause <devnull@fh-schmalkalden.de> 3.0.0-0.0.7
+- Bugfix in dknet: After receiving the first connection attempt the
+ program listened on this socket only.
+
+* Thu Jul 05 2012 Dirk Krause <devnull@fh-schmalkalden.de> 3.0.0-0.0.6
+- dknet rewritten for IPv6 support, previous version still available as dknet4.
+
+* Thu Jun 14 2012 Dirk Krause <devnull@fh-schmalkalden.de> 3.0.0-0.0.5
+- printqd and companions added.
+
+* Wed Nov 02 2011 Dirk Krause <devnull@fh-schmalkalden.de> 3.0.0-0.0.4
+- wxT_2() macro for wxCmdLineEntryDesc structures in wxdkct.
+
+* Wed Nov 02 2011 Dirk Krause <devnull@fh-schmalkalden.de> 2.2.22
+- Bugfix in the configure script: Unnecessary call to wx-config removed.
+
+* Tue Nov 01 2011 Dirk Krause <devnull@fh-schmalkalden.de> 3.0.0-0.0.3
+- dkdbt program completed.
+
+* Tue Nov 01 2011 Dirk Krause <devnull@fh-schmalkalden.de> 2.2.21
+- The hostsadm.pl script now adds a netgroup triple containing
+ the IP address to the netgroup.ldif file.
+- The "ctrl database-cleanup" operation for prqd now removes
+ print accounts and page counts with value 0.
+
+* Sun Oct 09 2011 Dirk Krause <devnull@fh-schmalkalden.de> 3.0.0-0.0.2
+- dkt program completed.
+- dkwt program completed.
+- dkct program completed.
+- wxdkct program completed.
+- GIT repository created.
+
+* Sun Jun 06 2011 Dirk Krause <devnull@fh-schmalkalden.de> 2.2.20
+- Program imgsize renamed to chimgsize to avoid name conflicts
+ with perl-Image-Size RPM.
+
+* Sun Apr 19 2011 Dirk Krause <devnull@fh-schmalkalden.de> 2.2.19
+- Bugfix in text2htm, wrong format specification.
+
+* Sun Mar 06 2011 Dirk Krause <devnull@fh-schmalkalden.de> 3.0.0-0.0.1
+- dkt uid was added.
+
+* Sun Nov 14 2010 Dirk Krause <devnull@fh-schmalkalden.de> 2.2.18
+- The function dkstr_w_cat() (a fallback implementation for systems without
+ the wcscat() function) was added.
+- New programs kwintool and kwindown for Windows.
+
+* Tue Oct 26 2010 Dirk Krause <devnull@fh-schmalkalden.de> 2.2.17
+- New option ``create accounts automatically'' for prqd. By default
+ we avoid to create personal print accounts automatically to keep
+ the database small.
+- Improvements in the GUI of the PrintLimit application.
+
+* Sun Oct 24 2010 Dirk Krause <devnull@fh-schmalkalden.de> 2.2.16
+- New Java application PrintLimit for users of LPRng/prqd to show
+ users print quota information.
+- The dklibsj.html page was improved. A tutorial and a short reference
+ were added.
+
+* Wed Oct 20 2010 Dirk Krause <devnull@fh-schmalkalden.de> 2.2.15
+- The LANG environment variable is now tested for both ".UTF-8"
+ and ".utf8" to indicate the use of UTF-8 encoding.
+
+* Wed Sep 15 2010 Dirk Krause <devnull@fh-schmalkalden.de> 2.2.14
+- Documentation update: Notes about differences in the appearance of
+ interpolated splines in Xfig/transfig and fig2vect. Recommendations how
+ to modify the sources of Xfig and transfig.
+
+* Tue Sep 14 2010 Dirk Krause <devnull@fh-schmalkalden.de> 2.2.13
+- Corrected typographic errors in the DKrause::Diagram documentation.
+
+* Tue Sep 13 2010 Dirk Krause <devnull@fh-schmalkalden.de> 2.2.12
+- The *.jar files were missing in the Windows executable setup of
+ 2.2.11. Here they are back.
+
diff --git a/support/dktools/dktools-el6.spec b/support/dktools/dktools-el6.spec
new file mode 100644
index 0000000000..a97cdd1883
--- /dev/null
+++ b/support/dktools/dktools-el6.spec
@@ -0,0 +1,673 @@
+#
+# If you think the *.spec files need corrections, please send me a
+# complete working *.spec file, not just a bug report.
+# I moved my laptop from Scientific Linux to Debian (they still
+# provide a 32 bit version with recent software), so I do no longer
+# have access to machines I could use to test *.spec files.
+#
+Name: dktools
+Version: 4.8.3
+Source: file:///home/krause/work/dktools-4.8.3.tar.gz
+Release: 1%{?dist}
+Summary: Dirk Krause's tools and libraries
+Vendor: Dirk Krause
+# Packager: Dirk Krause
+Group: Applications/System
+License: BSD
+URL: http://dktools.sourceforge.net/index.html
+BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
+
+BuildRequires: mysql-devel zlib-devel bzip2-devel libpng-devel openssl-devel libjpeg-devel libtiff-devel net-snmp-devel wxGTK wxGTK-devel
+Requires: zlib bzip2 openssl mysql-libs libpng libjpeg libtiff net-snmp wxGTK
+Conflicts: dktools-rescue
+Prefix: %{_prefix}
+
+# ___PROVIDES___
+
+%description
+A set of tools for graphics conversion, text conversion, software
+development, administration and printing and some general-purpose tools.
+ bmpp / wxbmpp Convert PNG/JPEG/TIFF to PS/EPS/PDF
+ fig2lat Convert FIG to PGF,EPS+TeX,PDF+TeX,EPS,SVG
+ wximgsz Suggest good sizes to rescale bitmap images
+ htmlbook Publish HTML like a book
+ dkct / wxdkct Preprocessor for C, C++, Objective-C and Java
+ (debugging/tracing, state machines, wxWidgets GUIs)
+ dkwxwiz Create project skeleton for wxWidgets+dktools based programs
+ wxdkhtb Viewer for *.htb help files
+ itadmin Use a MySQL database to manage your IT
+ dk-ls ls clone, configurable column order
+ dk-fic File integrity checker
+ dk-bmm Backup media manager (10 tape rotation)
+ dk-blks Correct data stream blocksize (for use with dd)
+ dk-eradisk Create data stream to erase a disk
+ dk-hex Show data in hexadecimal or octal notation
+ dk-cat cat clone, recoding between ASCII/UTF-8/UTF-16
+ dk-sort sort clone, processes ASCII/UTF-8/UTF-16
+ dk-t2h Text to HTML converter
+ dk-t2l Text to LaTeX converter
+ dk-sqlsplit Split overlong SQL lines from mysqldump
+ dk-uid Find user ID in given range
+ dk-pwgen Create passwords, PINs and WiFi keys
+ dk-send Send data stream to one or multiple recipients over TCP
+ dk-recv Receive data stream from a dk-send process
+ dkdbt Tool for simple databases
+ printqd Print quota enforcement for LPRng print systems
+ wxpqdic GUI client to check print quota
+ addctrld Add CTRL-D to end of data stream if not yet present
+ wxdkclock Simple clock, one alert
+ plpdftex Output driver for octpgfpl
+
+%prep
+%setup -q
+# %setup
+
+
+%build
+%configure --enable-packaging
+make %{?_smp_mflags}
+
+%install
+rm -rf $RPM_BUILD_ROOT
+make install DESTDIR=$RPM_BUILD_ROOT
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+
+%files
+%defattr(-,root,root,-)
+%doc README bsdlic.txt
+%{_bindir}/*
+%{_libdir}/libdk3*.so.*
+%{_libdir}/libdk4*.so.*
+%{_datadir}/applications/*
+%{_datadir}/dktools
+%{_datadir}/dk4app
+%{_datadir}/man/man1/*
+%{_datadir}/man/man5/*
+%{_sysconfdir}/printqd/printqd.conf.sample
+%{_sysconfdir}/rshdown/rshdown.conf.sample
+%config %{_sysconfdir}/dk3app/dk3paper.conf
+
+%post
+# ##### ATTEMPT TO GUESS USER AND GROUP FOR LPRng LPD DAEMON
+#
+LPUSER=`getent passwd | grep '^daemon:' | cut -f 1 -d :`
+if [ "X$LPUSER" = "X" ]
+then
+ LPUSER=`getent passwd | grep '^lp:' | cut -f 1 -d :`
+fi
+if [ "X$LPUSER" = "X" ]
+then
+ LPUSER="root"
+fi
+LPGROUP=`getent group | grep '^daemon:' | cut -f 1 -d :`
+if [ "X$LPGROUP" = "X" ]
+then
+ LPGROUP=`getent group | grep '^lp:' | cut -f 1 -d :`
+fi
+if [ "X$LPGROUP" = "X" ]
+then
+ LPGROUP="root"
+fi
+#
+# #####
+#
+#
+#
+# ##### LINUX DISTRIBUTION PACKAGERS
+# ##### If your distribution contains the LPRng software, please
+# ##### uncomment the two lines below and set LPUSER and LPGROUP to
+# ##### the user and group used to run the LPRng lpd daemon on
+# ##### your distribution.
+# ##### Optionally remove the lines above attempting to guess these names.
+#
+# LPUSER="daemon"
+# LPGROUP="daemon"
+#
+# #####
+for i in /var/printqd /var/log/printqd /var/run/printqd
+do
+ [ -d $i ] || mkdir -p $i
+ chown -R ${LPUSER}:${LPGROUP} $i
+ chmod 770 $i
+done
+ldconfig
+
+%postun
+if [ "X$1" = "X0" ]
+then
+ [ ! -d /var/run/printqd ] || rm -fr /var/run/printqd
+ [ ! -d /var/log/printqd ] || rm -fr /var/log/printqd
+fi
+ldconfig
+
+
+
+#
+# The rescue sub-package installs only those binaries useful on
+# a rescue live system.
+#
+%package rescue
+#
+# The devel sub-package installs developer support.
+#
+Summary: Only those DK tools binaries useful on a rescue live system
+Group: Applications/System
+Requires: zlib bzip2 openssl
+Conflicts: dktools
+Prefix: %{_prefix}
+
+%description rescue
+On live systems for system rescue we only need the dknet and dkt program.
+
+%files rescue
+%defattr(-,root,root,-)
+%doc README bsdlic.txt
+%{_bindir}/dk-send
+%{_bindir}/dk-recv
+%{_bindir}/dk-blks
+%{_bindir}/dk-cat
+%{_bindir}/dk-eradisk
+%{_bindir}/dk-ls
+%{_libdir}/libdk4socka.so.*
+%{_libdir}/libdk4sock.so.*
+%{_libdir}/libdk4maiodh.so.*
+%{_libdir}/libdk4maio8h.so.*
+%{_libdir}/libdk4app.so.*
+%{_libdir}/libdk4c.so.*
+%{_libdir}/libdk4maiodd.so.*
+%{_libdir}/libdk4maiowd.so.*
+%{_libdir}/libdk4maio8d.so.*
+%{_libdir}/libdk4base.so.*
+%{_datadir}/dktools/en/dk-send.*
+%{_datadir}/dktools/en/dk-recv.*
+%{_datadir}/dktools/en/dk-cat.*
+%{_datadir}/dktools/en/dk-blks.*
+%{_datadir}/dktools/en/dk-ls.*
+%{_datadir}/dktools/de/dk-send.*
+%{_datadir}/dktools/de/dk-recv.*
+%{_datadir}/dktools/de/dk-cat.*
+%{_datadir}/dktools/de/dk-blks.*
+%{_datadir}/dktools/de/dk-ls.*
+
+
+%post rescue
+ldconfig
+
+%postun rescue
+ldconfig
+
+
+
+
+
+%package devel
+Summary: Development files for libraries from the DK tools project
+Group: Development/Libraries
+Requires: dktools = %{version}-%{release} mysql-devel zlib-devel bzip2-devel libpng-devel openssl-devel libjpeg-devel libtiff-devel net-snmp-devel gcc wxGTK wxGTK-devel
+Prefix: %{_prefix}
+
+%description devel
+If you want to use modules from the DK tools project in your programs,
+you need the libraries from the dktools-lib package and the header
+files provided by this project.
+
+%files devel
+%defattr(-,root,root,-)
+%{_includedir}/*
+%{_libdir}/pkgconfig/dktools.pc
+%{_libdir}/libdk3*.so
+%{_libdir}/libdk4*.so
+
+%changelog
+
+* Tue Mar 28 2017 Dirk Krause <krause.dirk@web.de> 4.8.3-0.0.1
+- Followed improvement suggestions from the CTAN team.
+
+* Fri Mar 24 2017 Dirk Krause <krause.dirk@web.de> 4.8.2-0.0.1
+- Modified bmpp to write a /CropBox in addition to /MediaBox in PDF output.
+
+* Wed Mar 22 2017 Dirk Krause <krause.dirk@web.de> 4.8.1-0.0.1
+- Modified dk-send to stop reading input if all clients disconnected
+ unexpectedly.
+
+* Sun Mar 19 2017 Dirk Krause <krause.dirk@web.de> 4.8.0-0.0.1
+- Library libdk4maioxd added (wxChar numbers input and output).
+- Package lshw added to package list for DKtoolian.
+- Configure script and Makefile.in modified to have less warnings from
+ Debian package building.
+
+* Fri Feb 03 2017 Dirk Krause <krause.dirk@web.de> 4.7.0-0.0.1
+- "xxxx" can be used as copyright end year in the "copyright year"
+ setting in options sections of *.ctr, *.wxc and *.cpt files.
+- New modules dk4paper and dk4papea to read papersizes configuration
+ files.
+
+* Sun Dec 11 2016 Dirk Krause <krause.dirk@web.de> 4.6.0-0.0.1
+- New functions in dk4memrs, dk4str8, dk4strw and dk4str to sanitize
+ buffers and strings.
+
+* Thu Oct 27 2016 Dirk Krause <krause.dirk@web.de> 4.5.0-0.0.1
+- Added support for meta/description and meta/keywords tags to htmlbook.
+- New modules for arithmetic operations on int16_t, uint16_t, int32_t, uint32_t.
+- New modules to serialize data to stream, unserialize from stream.
+- New module for compressed/encoded output on a dk4_stream_t.
+
+* Wed Sep 07 2016 Dirk Krause <krause.dirk@web.de> 4.4.0-0.0.1
+- Configuration option for itadmin to release lease on shutdown.
+- Markers in dhcpd.conf produced by itadmin for easier post-processing.
+- New module dk4strmw to open a file stream for writing.
+- New module dk4fpe to check for floating point exceptions.
+- New modules to read double from string and write double to string.
+- Mathematical operations on int16_t, int32_t, uint16_t and uint32_t
+ including error checking.
+- Inline functions or macros to copy, reset and compare memory buffers.
+- Modules dk4mai8dbl, dk4maiddbl, dk4maiwdbl, dk4mao8dbl, dk4maoddbl
+ and dk4maowdbl to read double from string and write double to string.
+- API change in dk4stream_write(): the buffer argument is const now.
+- Optimization in dk4stream_write().
+- Bugfixes in GUI applications: No wxXXX objects must survive OnExit().
+- Bugfixes in the dk4strw module.
+- Bugfixes in checking for mysql.h file.
+- Code cleanup in DkWxBmepsApp.cpt, DkWxImgszApp.cpt and DkWxTraceApp.cpt
+ to improve readability.
+
+* Tue Jul 12 2016 Dirk Krause <krause.dirk@web.de> 4.3.6-0.0.1
+- Bugfix for Windows (try multiple sources to get home directory).
+- Replacements for GetVersionEx() function in Windows.
+- Docu update for installation using stow.
+
+* Sat Jul 02 2016 Dirk Krause <krause.dirk@web.de> 4.3.5-0.0.1
+- New hint special command for htmlbook.
+- Scripts to produce live systems.
+
+* Fri Jun 10 2016 Dirk Krause <krause.dirk@web.de> 4.3.4-0.0.1
+- Added span.hint to style.css for htmlbook.
+- Smaller changes related to Debian packaging.
+
+* Sat May 28 2016 Dirk Krause <krause.dirk@web.de> 4.3.3-0.0.1
+- Debian packaging changed, developer package is dktools-lib-$(4.8)-dev.
+- RPM packaging changed, shared library symlinks now in devel package.
+- New script to generate debian/changelog from dktools-el6.spec.in file.
+
+* Fri May 27 2016 Dirk Krause <krause.dirk@web.de> 4.3.2-0.0.1
+- New special command "htmlname" in htmlbook program.
+- Directory structure in build process changed due to lintian complaints.
+- Bugfix in dktools.pc, Libs.private now set correctly.
+- Script itaclean.sh renamed to itaclean (due to lintian complaints).
+
+* Mon Apr 25 2016 Dirk Krause <krause.dirk@web.de> 4.3.1-0.0.1
+- Printqdc now accepts empty input lines.
+
+* Tue Apr 19 2016 Dirk Krause <krause.dirk@web.de> 4.3.0-0.0.1
+- Printqd and related programs rewritten completely.
+- Rshdown is back on a users request, ported to library version 4.
+- Print order character 'N' added to dk-ls (do not show symlink target).
+- Option -b for dk-pwgen on non-Windows systems (create binary random data).
+- New program dk-rand to generate binary random data.
+- Modifications to dk4_app_t and dk3_app_t modules: create log and tmp
+ directories only when needed.
+- Modified dk4inst.h header: Compiler constant texts for directories.
+- Module dk4dmt added, tool functions for standing daemons.
+- Modified dk4sock13 module, delete existing UNIX domain sockets.
+- Modified DkWxFrame and Dk4WxFrame, restore position when frame is shown.
+- Bugfix in dkwxwiz data files, typo corrected.
+- Bugfix in dk4dbi module, must set ulen, not size when retrieving data.
+- Retired dk3sock module, all networking programs use library version 4 now.
+
+* Fri Jan 22 2016 Dirk Krause <krause.dirk@web.de> 4.2.2-0.0.1
+- Modified dk-cat, dk-hex, dk-pwgen, dk-t2h, dk-t2l, dk-db2t:
+ No error message for SIGPIPE received.
+- Some modifications following suggestions from clang static code analysis.
+
+* Tue Jan 19 2016 Dirk Krause <krause.dirk@web.de> 4.2.1-0.0.1
+- Modifications in Makefile.in and scripts/dkmkproto.pl for SVR4 packaging.
+
+* Mon Jan 18 2016 Dirk Krause <krause.dirk@web.de> 4.2.0-0.0.1
+- Performance fix for dk-send/dk-recv: Use larger buffers.
+- Performance fix for dk-ls: Avoid unnecessary size calculations.
+- Programs dk-t2db, dk-db2t and dk-dbco to replace dkdbt.
+- Libraries dk4dbia and dk4dbi added to replace dk3dbi.
+- Bugfix in dk4loc module, set encoding even if no LANG variable available.
+
+* Mon Dec 14 2015 Dirk Krause <krause.dirk@web.de> 4.1.0-0.0.1
+- Added -s option to dk-ls, show summary at end.
+- Manpage installation avoided, when building on Debian
+ (manpage installation on Debian is done by package management).
+- New functions to retrieve and expand strings from Windows registry.
+- Changes in makefiles for Visual Studio for Desktop on Windows.
+- Bugfix in dk4user module: Must expand user profile string from registry.
+- Bugfix in DkClockFrame.wxc: Minimum size specified.
+- Bugfix in DkWxImgszFrame.wxc: Format specifier corrected.
+- Bugfix in DkWxImgszApp.cpt: Load all image handlers wxInitAllImageHandlers()
+
+* Fri Dec 04 2015 Dirk Krause <krause.dirk@web.de> 4.0.10-0.0.1
+- Man pages added, required for Debian packaging.
+- Build process on Windows can now use different library directories.
+- Bugfix in dkdbt program: No longer error messages for comment lines.
+- First release after changing Linux distribution to Debian on my laptop.
+
+* Tue Nov 10 2015 Dirk Krause <krause.dirk@web.de> 4.0.9-0.0.1
+- Bugfix in Makefile.in: Some programs were mentioned twice.
+
+* Sun Nov 08 2015 Dirk Krause <krause.dirk@web.de> 4.0.8-0.0.1
+- Number of duplicated files in source archive reduced by use of hard links.
+
+* Fri Oct 16 2015 Dirk Krause <krause.dirk@web.de> 4.0.7-0.0.1
+- Bugfix in dk4loc module: Use "en" as default language.
+- Bugfix in configure.ac: Install shared libraries for rescue systems too.
+
+* Sat Oct 10 2015 Dirk Krause <krause.dirk@web.de> 4.0.6-0.0.1
+- Added -t option to dk-sort.
+- Only one AC_OUTPUT line in Makefile.in.
+
+* Tue Oct 06 2015 Dirk Krause <krause.dirk@web.de> 4.0.5-0.0.1
+- Help text for dk-recv corrected, host and port are mandatory.
+- Compiler flags for wxcs added in Makefile.in.
+- Removed some dead assignments after static analysis.
+
+* Wed Sep 23 2015 Dirk Krause <krause.dirk@web.de> 4.0.4-0.0.1
+- Makefile.in: Use C++ compiler to drive linker if any C++ module in project.
+- Makefile.in: libdk4wx.a in the LIB_ST_GUI group, not LIB_ST_CLI.
+- dktools.pc.in: Correct variable for version number used now.
+- dk3strkv/dk-sqlsplit: S_ERROR replaced by ST_ERROR.
+- configure.ac: No -Bdynamic -dy -KPIC -D_REENTRANT for static builds.
+- configure.ac: Option --with-corrections for some Solaris systems.
+
+* Tue Aug 11 2015 Dirk Krause <krause.dirk@web.de> 4.0.3-0.0.1
+- Module dk3uc2l rewritten to use the *.t2l files.
+
+* Tue Aug 04 2015 Dirk Krause <krause.dirk@web.de> 4.0.2-0.0.1
+- Setting for tooltip flag added to dkct.
+
+* Tue Aug 04 2015 Dirk Krause <krause.dirk@web.de> 4.0.1-0.0.1
+- dkct: Special placeholders in $? format string.
+- dkct: Option -p added for portable debug output code.
+
+* Tue Aug 04 2015 Dirk Krause <krause.dirk@web.de> 4.0.0-0.0.1
+- New rewritten library modules dk4*.
+- Simplified error reporting from callee to caller via dk4_er_t structure.
+- Reduced use of runtime library on Windows systems.
+- Text stream processing functions recognize BOM at start of data.
+- Multiple dk4sock* modules instead of one large module.
+- wxdkfcs: GUI program to inspect file checksums.
+- dkt: Replaced by multiple smaller programs.
+- dkct: Cell contents for wxGrid in wx gui section.
+
+* Thu Jul 09 2015 Dirk Krause <krause.dirk@web.de> 3.18.10-0.0.1
+- dk-tape: Code simplified.
+
+* Thu Apr 02 2015 Dirk Krause <krause.dirk@web.de> 3.18.9-0.0.1
+- Modified configure script and Makefile for --enable-packaging option.
+
+* Fri Mar 13 2015 Dirk Krause <krause.dirk@web.de> 3.18.8-0.0.1
+- Modified configure script and Makefile.
+
+* Sat Feb 21 2015 Dirk Krause <krause.dirk@web.de> 3.18.7-0.0.1
+- dkct: Bugfix, doxygen allows pure @file lines.
+
+* Wed Jan 28 2015 Dirk Krause <krause.dirk@web.de> 3.18.6-0.0.1
+- Bugfix in plpdftex: smash used only for texts aligned by base line.
+
+* Thu Jan 22 2015 Dirk Krause <krause.dirk@web.de> 3.18.5-0.0.1
+- Bugfix in dkt tape: wrong number printed.
+- Bugfix in plpdftex: smash not for texts in boxes.
+- Modified pjsnmp: Added pjsnmpreadystates configuration option
+- Modified pjsnmp: Message texts modified, distinction errors/warnings.
+
+* Mon Dec 08 2014 Dirk Krause <krause.dirk@web.de> 3.18.4-0.0.1
+- Bugfix in plpdftex: sometimes invalid *.tex output.
+
+* Mon Dec 01 2014 Dirk Krause <krause.dirk@web.de> 3.18.3-0.0.1
+- Bugfix in UTF-16 encoding: Surrogate range was wrong.
+
+* Wed Nov 26 2014 Dirk Krause <krause.dirk@web.de> 3.18.2-0.0.1
+- Modified dkct: No @file line added if @file line is already present.
+- Data type dk3_c32_t changed to unsigned if unsigned is 4 bytes long.
+- Check whether password memory really was reset.
+
+* Tue Oct 21 2014 Dirk Krause <krause.dirk@web.de> 3.18.1-0.0.1
+- Bugfix in multiplication overflow detection in dk3mas/dk3mai/dk3mal modules.
+
+* Thu Oct 16 2014 Dirk Krause <krause.dirk@web.de> 3.18.0-0.0.1
+- Copyright year check in dkct.
+- API bugfix in dk3str32/dk3str16: Use correct character size now.
+- Bugfix in htmlbook for using dkChar.
+- Bugfix in dkdbt for using dkChar.
+- Splitted dk3mastr module into several modules.
+- Most uses of sscanf() and dk3sf_sscanf3() replaced by other functions.
+
+* Wed Sep 24 2014 Dirk Krause <krause.dirk@web.de> 3.17.2-0.0.1
+- Bugfix in dk3sock: WSAEWOULDBLOCK is used for connect in progress.
+
+* Fri Sep 12 2014 Dirk Krause <krause.dirk@web.de> 3.17.1-0.0.1
+- Bugfix in archive creation: Permissions are correct now.
+
+* Wed Sep 03 2014 Dirk Krause <krause.dirk@web.de> 3.17.0-0.0.1
+- Appendices k, M, G for block size added for dkt blks/ dkt ed/dkt rnd.
+- Bugfix in fig2lat: EPS/PDF/PGF output driver, corner radius.
+- Bugfix in wxbmpp dk3paper module.
+- Bugfix in wxbmpp: Fitting to a paper size.
+
+* Thu Aug 07 2014 Dirk Krause <krause.dirk@web.de> 3.16.3-0.0.1
+- Changed build process for Linux/Unix.
+
+* Tue Aug 05 2014 Dirk Krause <krause.dirk@web.de> 3.16.2-0.0.1
+- Changed build process for Linux/Unix, removed options from configure.
+
+* Tue Aug 05 2014 Dirk Krause <krause.dirk@web.de> 3.16.1-0.0.1
+- Use wxFD_OPEN instead of wxOPEN.
+- Bugfix in makefile: CLFAGS was a typo.
+
+* Mon Jul 28 2014 Dirk Krause <krause.dirk@web.de> 3.16.0-0.0.1
+- New program plpdftex added, output driver for octpgfpl.
+- Prefer sigaction() over sigset().
+- Function-like macros replaced by functions.
+- Modified overflow check for conversion from unsigned long to size_t.
+- Modified dk3ma module: Splitted into several smaller modules.
+- Functions dk3strm_double_c8_no_sci()... added.
+- Function dk3pdf_write_double() treats small numbers as 0.
+
+* Sat Jun 28 2014 Dirk Krause <krause.dirk@web.de> 3.15.0-0.0.1
+- Source code reorganized.
+
+* Thu Jun 19 2014 Dirk Krause <krause.dirk@web.de> 3.14.0-0.0.1
+- Options -S... added to dkct and wxdkct.
+- Memory usage reorganized for bit matrices.
+- Cache friendly algorithm for bit matrix expansion.
+- dktools.spec file modified to build sub-packages lib and devel.
+
+* Tue May 27 2014 Dirk Krause <krause.dirk@web.de> 3.13.0-0.0.1
+- Modified htmlbook: Line numbering for source code.
+- Modified dkt html: Line numbering for source code.
+- Added *.desktop files for GUI programs.
+
+* Wed Apr 30 2014 Dirk Krause <krause.dirk@web.de> 3.12.0-0.0.1
+- New application wxdkhtb added to view help text files.
+- Modified htmlbook: enable/disable full text search in *.chm output.
+- Installation bugfix: Forgot to install libdk3wx.so.
+- HTML files for online help now created by htmlbook.
+- API change in DkWxFrame class: Methods added.
+
+* Wed Apr 23 2014 Dirk Krause <krause.dirk@web.de> 3.11.0-0.0.1
+- htmlbook: Writing project.xml file.
+- htmlbook: New option chm full text search.
+- htmlbook: Section number optional before section title in index and pos.
+- htmlbook: Titles for links in keyword index.
+- htmlbook: Bugfix, all *.html files listed in files section.
+- htmlbook: Bugfix, added missing closing OBJECT tag.
+- htmlbook: Bugfix, copy index.hhp, index.hhc and index.hhk to destination.
+- htmlbook: Bugfix, root object now in TOC as first object.
+- printqd: Attempt to remove existing local socket before creating new one.
+- printqd: Bugfix, endless loop.
+- wxdkclock: Save changed options immediately.
+
+* Mon Mar 31 2014 Dirk Krause <krause.dirk@web.de> 3.10.0-0.0.1
+- Modified fig2lat: Fast splines for arrowheads.
+- Modified fig2lat: Configurable base line width.
+
+* Mon Mar 24 2014 Dirk Krause <krause.dirk@web.de> 3.9.0-0.0.1
+- Bugfix in bmpp/wxbmpp: Bits per component analysis rewritten.
+
+* Sun Mar 02 2014 Dirk Krause <krause.dirk@web.de> 3.8.3-0.0.1
+- Bugfix bmpp/wxbmpp: Automatic bits per component analysis disabled.
+- Modified htmlbook: New classes for table cells added to style.css file.
+
+* Thu Feb 06 2014 Dirk Krause <krause.dirk@web.de> 3.8.2-0.0.1
+- Modified htmlbook: New no-vspace option for img special command.
+- Modified htmlbook: Shortcuts for images.
+
+* Wed Jan 29 2014 Dirk Krause <krause.dirk@web.de> 3.8.1.0.0.1
+- Modified htmlbook: Set permissions for destination directory contents.
+- Modified htmlbook: Change in style.css, added top and bottom margin.
+- Bugfix in htmlbook: Crashes on filenames without suffix.
+
+* Tue Jan 21 2014 Dirk Krause <krause.dirk@web.de> 3.8.0-0.0.1
+- New application htmlbook added.
+- Bugfix in dk3enc module: Wrong range delimiter for Unicode characters.
+
+* Fri Nov 29 2013 Dirk Krause <krause.dirk@web.de> 3.7.0-0.0.1
+- Modified dkt latex: Euro currency symbol added to translation table.
+- Modified dkma: long long, unsigned long long, intmax_t, uintmax_t.
+
+* Thu Nov 14 2013 Dirk Krause <krause.dirk@web.de> 3.6.0-0.0.1
+- Modified fig2lat: New cofop option for filled open graphics paths.
+- Bugfix in fig2lat: Must encode some characters.
+- Modified dk3ma: Function and constants names changed for consistent naming.
+
+* Wed Oct 23 2013 Dirk Krause <krause.dirk@web.de> 3.5.0-0.0.1
+- Modified wxbmpp: No automatic start when running on a directory.
+
+* Tue Oct 01 2013 Dirk Krause <krause.dirk@web.de> 3.4.0-0.0.1
+- Modified dkt blocksize: Performance optimizations, use memcpy().
+- Modified dk3sock module: Handle incomplete send requests.
+- Modified dk3str module: Use existing functions if available.
+
+* Fri Sep 20 2013 Dirk Krause <krause.dirk@web.de> 3.3.3-0.0.1
+- Option -s for dkt blocksize added.
+- Modified itadmin: Increased possible length for DHCP options values.
+- Bugfix in itadmin: DHCP options for hosts are written now.
+
+* Tue Jul 30 2013 Dirk Krause <krause.dirk@web.de> 3.3.2-0.0.1
+- Modified dk3sto module: Keyword const added to some functions.
+
+* Mon Jul 29 2013 Dirk Krause <krause.dirk@web.de> 3.3.1-0.0.1
+- Bugfix in distribution and build system.
+
+* Sun Jul 28 2013 Dirk Krause <krause.dirk@web.de> 3.3.0-0.0.1
+- API change, comparison and evaluation functions operate on const * pointers.
+
+* Wed Jul 24 2013 Dirk Krause <krause.dirk@web.de> 3.2.2-0.0.1
+- More useful error message for malformed path to dkt ls on Windows
+ (paths in double quotes where backslash escapes closing double quote).
+
+* Thu Mar 20 2013 Dirk Krause <krause.dirk@web.de> 3.0.6-0.0.1
+- dkct enhanced for unknown classes.
+
+* Wed Mar 20 2013 Dirk Krause <krause.dirk@web.de> 3.0.5-0.0.1
+- Bugfix: Use AddButton method of wxStdButtonSizer, not Add.
+
+* Sun Mar 17 2013 Dirk Krause <krause.dirk@web.de> 3.0.4-0.0.1
+- The dk3sock4 module was added.
+
+* Sat Mar 16 2013 Dirk Krause <krause.dirk@web.de> 3.0.3-0.0.1
+- Online documentation updated for the -f option in dknet.
+
+* Thu Mar 14 2013 Dirk Krause <krause.dirk@web.de> 3.0.2-0.0.1
+- The dknet program is more verbose now when run as sender.
+
+* Sun Feb 03 2013 Dirk Krause <krause.dirk@web.de> 3.0.1-0.0.1
+- The dkwxwiz program was added.
+- The winprint program (for Windows) was added.
+- The wprclean program (for Windows) was added.
+- The lprngcl program (for Windows) was added.
+- Option bbts for fig2lat.
+- Bugfix in Win32 setup: The dk3paper.conf file was not installed.
+
+* Thu Jan 31 2013 Dirk Krause <krause.dirk@web.de> 3.0.0-0.0.12
+- Code for 3.0.0 release finished.
+
+* Wed Nov 02 2011 Dirk Krause <krause.dirk@web.de> 2.2.22-0.0.1
+- Bugfix in the configure script: Unnecessary call to wx-config removed.
+
+* Tue Nov 01 2011 Dirk Krause <krause.dirk@web.de> 2.2.21-0.0.1
+- The hostsadm.pl script now adds a netgroup triple containing
+ the IP address to the netgroup.ldif file.
+- The "ctrl database-cleanup" operation for prqd now removes
+ print accounts and page counts with value 0.
+
+* Sun Jun 06 2011 Dirk Krause <krause.dirk@web.de> 2.2.20-0.0.1
+- Program imgsize renamed to chimgsize to avoid name conflicts
+ with perl-Image-Size RPM.
+
+* Sun Apr 19 2011 Dirk Krause <krause.dirk@web.de> 2.2.19-0.0.1
+- Bugfix in text2htm, wrong format specification.
+
+* Sun Nov 14 2010 Dirk Krause <krause.dirk@web.de> 2.2.18-0.0.1
+- The function dkstr_w_cat() (a fallback implementation for systems without
+ the wcscat() function) was added.
+- New programs kwintool and kwindown for Windows.
+
+* Tue Oct 26 2010 Dirk Krause <krause.dirk@web.de> 2.2.17-0.0.1
+- New option ``create accounts automatically'' for prqd. By default
+ we avoid to create personal print accounts automatically to keep
+ the database small.
+- Improvements in the GUI of the PrintLimit application.
+
+* Sun Oct 24 2010 Dirk Krause <krause.dirk@web.de> 2.2.16-0.0.1
+- New Java application PrintLimit for users of LPRng/prqd to show
+ users print quota information.
+- The dklibsj.html page was improved. Tutorial and short reference added.
+
+* Wed Oct 20 2010 Dirk Krause <krause.dirk@web.de> 2.2.15-0.0.1
+- The LANG environment variable is now tested for both ".UTF-8"
+ and ".utf8" to indicate the use of UTF-8 encoding.
+
+* Wed Sep 15 2010 Dirk Krause <krause.dirk@web.de> 2.2.14-0.0.1
+- Documentation update: Notes about differences in the appearance of
+ interpolated splines in Xfig/transfig and fig2vect. Recommendations how
+ to modify the sources of Xfig and transfig.
+
+* Tue Sep 14 2010 Dirk Krause <krause.dirk@web.de> 2.2.13-0.0.1
+- Corrected typographic errors in the DKrause::Diagram documentation.
+
+* Tue Sep 13 2010 Dirk Krause <krause.dirk@web.de> 2.2.12-0.0.1
+- The *.jar files were missing in the Windows executable setup of
+ 2.2.11. Here they are back.
+
+* Tue Aug 31 2010 Dirk Krause <krause.dirk@web.de> 2.2.11-0.0.1
+- Unnecessary line end correction removed from fig2vect.
+- New Perl module DKrause::Diagram added
+
+* Tue Jul 20 2010 Dirk Krause <krause.dirk@web.de> 2.2.10-0.0.1
+- Documentation corrections.
+
+* Fri Jul 16 2010 Dirk Krause <krause.dirk@web.de> 2.2.9-0.0.1
+- Bugfix in tracecc, application group name corrected.
+
+* Mon Jul 12 2010 Dirk Krause <krause.dirk@web.de> 2.2.8-0.0.1
+- Modifications in configure script for build process on Mac.
+
+* Sat Jun 26 2010 Dirk Krause <krause.dirk@web.de> 2.2.6-0.0.1
+- Bugfix in bmeps, bits per component reduction disabled.
+- Modifications in HTML documentation due to validation results.
+- New option "doxygen comments" for genau.
+- Script "make-pkg.sh" to build SVR4 packages.
+- Doxygen comments added.
+
+* Fri Jun 18 2010 Dirk Krause <krause.dirk@web.de> 2.2.5-0.0.1
+- Modified hostsadm: UTF-8 to ISO-LATIN-1 conversion.
+- Code cleanup.
+
+* Sun Jun 13 2010 Dirk Krause <krause.dirk@web.de> 2.2.4-0.0.1
+- File dktools.spec added.
+- Start scripts for prqd, rshdown, useraud now installed to /etc/init.d.
+
+* Sat Jun 12 2010 Dirk Krause <krause.dirk@web.de> 2.2.3-0.0.1
+- DESTDIR variable added to makefile for RPM builders.
+
+* Thu Jun 03 2010 Dirk Krause <krause.dirk@web.de> 2.2.2-0.0.1
+- Bugfix for preference file location.
+
diff --git a/support/dktools/dktools-el6.spec.in b/support/dktools/dktools-el6.spec.in
new file mode 100644
index 0000000000..743c4d3d26
--- /dev/null
+++ b/support/dktools/dktools-el6.spec.in
@@ -0,0 +1,673 @@
+#
+# If you think the *.spec files need corrections, please send me a
+# complete working *.spec file, not just a bug report.
+# I moved my laptop from Scientific Linux to Debian (they still
+# provide a 32 bit version with recent software), so I do no longer
+# have access to machines I could use to test *.spec files.
+#
+Name: dktools
+Version: VERSNO
+Source: file:///home/krause/work/dktools-VERSNO.tar.gz
+Release: 1%{?dist}
+Summary: Dirk Krause's tools and libraries
+Vendor: Dirk Krause
+# Packager: Dirk Krause
+Group: Applications/System
+License: BSD
+URL: http://dktools.sourceforge.net/index.html
+BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
+
+BuildRequires: mysql-devel zlib-devel bzip2-devel libpng-devel openssl-devel libjpeg-devel libtiff-devel net-snmp-devel wxGTK wxGTK-devel
+Requires: zlib bzip2 openssl mysql-libs libpng libjpeg libtiff net-snmp wxGTK
+Conflicts: dktools-rescue
+Prefix: %{_prefix}
+
+# ___PROVIDES___
+
+%description
+A set of tools for graphics conversion, text conversion, software
+development, administration and printing and some general-purpose tools.
+ bmpp / wxbmpp Convert PNG/JPEG/TIFF to PS/EPS/PDF
+ fig2lat Convert FIG to PGF,EPS+TeX,PDF+TeX,EPS,SVG
+ wximgsz Suggest good sizes to rescale bitmap images
+ htmlbook Publish HTML like a book
+ dkct / wxdkct Preprocessor for C, C++, Objective-C and Java
+ (debugging/tracing, state machines, wxWidgets GUIs)
+ dkwxwiz Create project skeleton for wxWidgets+dktools based programs
+ wxdkhtb Viewer for *.htb help files
+ itadmin Use a MySQL database to manage your IT
+ dk-ls ls clone, configurable column order
+ dk-fic File integrity checker
+ dk-bmm Backup media manager (10 tape rotation)
+ dk-blks Correct data stream blocksize (for use with dd)
+ dk-eradisk Create data stream to erase a disk
+ dk-hex Show data in hexadecimal or octal notation
+ dk-cat cat clone, recoding between ASCII/UTF-8/UTF-16
+ dk-sort sort clone, processes ASCII/UTF-8/UTF-16
+ dk-t2h Text to HTML converter
+ dk-t2l Text to LaTeX converter
+ dk-sqlsplit Split overlong SQL lines from mysqldump
+ dk-uid Find user ID in given range
+ dk-pwgen Create passwords, PINs and WiFi keys
+ dk-send Send data stream to one or multiple recipients over TCP
+ dk-recv Receive data stream from a dk-send process
+ dkdbt Tool for simple databases
+ printqd Print quota enforcement for LPRng print systems
+ wxpqdic GUI client to check print quota
+ addctrld Add CTRL-D to end of data stream if not yet present
+ wxdkclock Simple clock, one alert
+ plpdftex Output driver for octpgfpl
+
+%prep
+%setup -q
+# %setup
+
+
+%build
+%configure --enable-packaging
+make %{?_smp_mflags}
+
+%install
+rm -rf $RPM_BUILD_ROOT
+make install DESTDIR=$RPM_BUILD_ROOT
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+
+%files
+%defattr(-,root,root,-)
+%doc README bsdlic.txt
+%{_bindir}/*
+%{_libdir}/libdk3*.so.*
+%{_libdir}/libdk4*.so.*
+%{_datadir}/applications/*
+%{_datadir}/dktools
+%{_datadir}/dk4app
+%{_datadir}/man/man1/*
+%{_datadir}/man/man5/*
+%{_sysconfdir}/printqd/printqd.conf.sample
+%{_sysconfdir}/rshdown/rshdown.conf.sample
+%config %{_sysconfdir}/dk3app/dk3paper.conf
+
+%post
+# ##### ATTEMPT TO GUESS USER AND GROUP FOR LPRng LPD DAEMON
+#
+LPUSER=`getent passwd | grep '^daemon:' | cut -f 1 -d :`
+if [ "X$LPUSER" = "X" ]
+then
+ LPUSER=`getent passwd | grep '^lp:' | cut -f 1 -d :`
+fi
+if [ "X$LPUSER" = "X" ]
+then
+ LPUSER="root"
+fi
+LPGROUP=`getent group | grep '^daemon:' | cut -f 1 -d :`
+if [ "X$LPGROUP" = "X" ]
+then
+ LPGROUP=`getent group | grep '^lp:' | cut -f 1 -d :`
+fi
+if [ "X$LPGROUP" = "X" ]
+then
+ LPGROUP="root"
+fi
+#
+# #####
+#
+#
+#
+# ##### LINUX DISTRIBUTION PACKAGERS
+# ##### If your distribution contains the LPRng software, please
+# ##### uncomment the two lines below and set LPUSER and LPGROUP to
+# ##### the user and group used to run the LPRng lpd daemon on
+# ##### your distribution.
+# ##### Optionally remove the lines above attempting to guess these names.
+#
+# LPUSER="daemon"
+# LPGROUP="daemon"
+#
+# #####
+for i in /var/printqd /var/log/printqd /var/run/printqd
+do
+ [ -d $i ] || mkdir -p $i
+ chown -R ${LPUSER}:${LPGROUP} $i
+ chmod 770 $i
+done
+ldconfig
+
+%postun
+if [ "X$1" = "X0" ]
+then
+ [ ! -d /var/run/printqd ] || rm -fr /var/run/printqd
+ [ ! -d /var/log/printqd ] || rm -fr /var/log/printqd
+fi
+ldconfig
+
+
+
+#
+# The rescue sub-package installs only those binaries useful on
+# a rescue live system.
+#
+%package rescue
+#
+# The devel sub-package installs developer support.
+#
+Summary: Only those DK tools binaries useful on a rescue live system
+Group: Applications/System
+Requires: zlib bzip2 openssl
+Conflicts: dktools
+Prefix: %{_prefix}
+
+%description rescue
+On live systems for system rescue we only need the dknet and dkt program.
+
+%files rescue
+%defattr(-,root,root,-)
+%doc README bsdlic.txt
+%{_bindir}/dk-send
+%{_bindir}/dk-recv
+%{_bindir}/dk-blks
+%{_bindir}/dk-cat
+%{_bindir}/dk-eradisk
+%{_bindir}/dk-ls
+%{_libdir}/libdk4socka.so.*
+%{_libdir}/libdk4sock.so.*
+%{_libdir}/libdk4maiodh.so.*
+%{_libdir}/libdk4maio8h.so.*
+%{_libdir}/libdk4app.so.*
+%{_libdir}/libdk4c.so.*
+%{_libdir}/libdk4maiodd.so.*
+%{_libdir}/libdk4maiowd.so.*
+%{_libdir}/libdk4maio8d.so.*
+%{_libdir}/libdk4base.so.*
+%{_datadir}/dktools/en/dk-send.*
+%{_datadir}/dktools/en/dk-recv.*
+%{_datadir}/dktools/en/dk-cat.*
+%{_datadir}/dktools/en/dk-blks.*
+%{_datadir}/dktools/en/dk-ls.*
+%{_datadir}/dktools/de/dk-send.*
+%{_datadir}/dktools/de/dk-recv.*
+%{_datadir}/dktools/de/dk-cat.*
+%{_datadir}/dktools/de/dk-blks.*
+%{_datadir}/dktools/de/dk-ls.*
+
+
+%post rescue
+ldconfig
+
+%postun rescue
+ldconfig
+
+
+
+
+
+%package devel
+Summary: Development files for libraries from the DK tools project
+Group: Development/Libraries
+Requires: dktools = %{version}-%{release} mysql-devel zlib-devel bzip2-devel libpng-devel openssl-devel libjpeg-devel libtiff-devel net-snmp-devel gcc wxGTK wxGTK-devel
+Prefix: %{_prefix}
+
+%description devel
+If you want to use modules from the DK tools project in your programs,
+you need the libraries from the dktools-lib package and the header
+files provided by this project.
+
+%files devel
+%defattr(-,root,root,-)
+%{_includedir}/*
+%{_libdir}/pkgconfig/dktools.pc
+%{_libdir}/libdk3*.so
+%{_libdir}/libdk4*.so
+
+%changelog
+
+* Tue Mar 28 2017 Dirk Krause <krause.dirk@web.de> 4.8.3-0.0.1
+- Followed improvement suggestions from the CTAN team.
+
+* Fri Mar 24 2017 Dirk Krause <krause.dirk@web.de> 4.8.2-0.0.1
+- Modified bmpp to write a /CropBox in addition to /MediaBox in PDF output.
+
+* Wed Mar 22 2017 Dirk Krause <krause.dirk@web.de> 4.8.1-0.0.1
+- Modified dk-send to stop reading input if all clients disconnected
+ unexpectedly.
+
+* Sun Mar 19 2017 Dirk Krause <krause.dirk@web.de> 4.8.0-0.0.1
+- Library libdk4maioxd added (wxChar numbers input and output).
+- Package lshw added to package list for DKtoolian.
+- Configure script and Makefile.in modified to have less warnings from
+ Debian package building.
+
+* Fri Feb 03 2017 Dirk Krause <krause.dirk@web.de> 4.7.0-0.0.1
+- "xxxx" can be used as copyright end year in the "copyright year"
+ setting in options sections of *.ctr, *.wxc and *.cpt files.
+- New modules dk4paper and dk4papea to read papersizes configuration
+ files.
+
+* Sun Dec 11 2016 Dirk Krause <krause.dirk@web.de> 4.6.0-0.0.1
+- New functions in dk4memrs, dk4str8, dk4strw and dk4str to sanitize
+ buffers and strings.
+
+* Thu Oct 27 2016 Dirk Krause <krause.dirk@web.de> 4.5.0-0.0.1
+- Added support for meta/description and meta/keywords tags to htmlbook.
+- New modules for arithmetic operations on int16_t, uint16_t, int32_t, uint32_t.
+- New modules to serialize data to stream, unserialize from stream.
+- New module for compressed/encoded output on a dk4_stream_t.
+
+* Wed Sep 07 2016 Dirk Krause <krause.dirk@web.de> 4.4.0-0.0.1
+- Configuration option for itadmin to release lease on shutdown.
+- Markers in dhcpd.conf produced by itadmin for easier post-processing.
+- New module dk4strmw to open a file stream for writing.
+- New module dk4fpe to check for floating point exceptions.
+- New modules to read double from string and write double to string.
+- Mathematical operations on int16_t, int32_t, uint16_t and uint32_t
+ including error checking.
+- Inline functions or macros to copy, reset and compare memory buffers.
+- Modules dk4mai8dbl, dk4maiddbl, dk4maiwdbl, dk4mao8dbl, dk4maoddbl
+ and dk4maowdbl to read double from string and write double to string.
+- API change in dk4stream_write(): the buffer argument is const now.
+- Optimization in dk4stream_write().
+- Bugfixes in GUI applications: No wxXXX objects must survive OnExit().
+- Bugfixes in the dk4strw module.
+- Bugfixes in checking for mysql.h file.
+- Code cleanup in DkWxBmepsApp.cpt, DkWxImgszApp.cpt and DkWxTraceApp.cpt
+ to improve readability.
+
+* Tue Jul 12 2016 Dirk Krause <krause.dirk@web.de> 4.3.6-0.0.1
+- Bugfix for Windows (try multiple sources to get home directory).
+- Replacements for GetVersionEx() function in Windows.
+- Docu update for installation using stow.
+
+* Sat Jul 02 2016 Dirk Krause <krause.dirk@web.de> 4.3.5-0.0.1
+- New hint special command for htmlbook.
+- Scripts to produce live systems.
+
+* Fri Jun 10 2016 Dirk Krause <krause.dirk@web.de> 4.3.4-0.0.1
+- Added span.hint to style.css for htmlbook.
+- Smaller changes related to Debian packaging.
+
+* Sat May 28 2016 Dirk Krause <krause.dirk@web.de> 4.3.3-0.0.1
+- Debian packaging changed, developer package is dktools-lib-$(SOVERS)-dev.
+- RPM packaging changed, shared library symlinks now in devel package.
+- New script to generate debian/changelog from dktools-el6.spec.in file.
+
+* Fri May 27 2016 Dirk Krause <krause.dirk@web.de> 4.3.2-0.0.1
+- New special command "htmlname" in htmlbook program.
+- Directory structure in build process changed due to lintian complaints.
+- Bugfix in dktools.pc, Libs.private now set correctly.
+- Script itaclean.sh renamed to itaclean (due to lintian complaints).
+
+* Mon Apr 25 2016 Dirk Krause <krause.dirk@web.de> 4.3.1-0.0.1
+- Printqdc now accepts empty input lines.
+
+* Tue Apr 19 2016 Dirk Krause <krause.dirk@web.de> 4.3.0-0.0.1
+- Printqd and related programs rewritten completely.
+- Rshdown is back on a users request, ported to library version 4.
+- Print order character 'N' added to dk-ls (do not show symlink target).
+- Option -b for dk-pwgen on non-Windows systems (create binary random data).
+- New program dk-rand to generate binary random data.
+- Modifications to dk4_app_t and dk3_app_t modules: create log and tmp
+ directories only when needed.
+- Modified dk4inst.h header: Compiler constant texts for directories.
+- Module dk4dmt added, tool functions for standing daemons.
+- Modified dk4sock13 module, delete existing UNIX domain sockets.
+- Modified DkWxFrame and Dk4WxFrame, restore position when frame is shown.
+- Bugfix in dkwxwiz data files, typo corrected.
+- Bugfix in dk4dbi module, must set ulen, not size when retrieving data.
+- Retired dk3sock module, all networking programs use library version 4 now.
+
+* Fri Jan 22 2016 Dirk Krause <krause.dirk@web.de> 4.2.2-0.0.1
+- Modified dk-cat, dk-hex, dk-pwgen, dk-t2h, dk-t2l, dk-db2t:
+ No error message for SIGPIPE received.
+- Some modifications following suggestions from clang static code analysis.
+
+* Tue Jan 19 2016 Dirk Krause <krause.dirk@web.de> 4.2.1-0.0.1
+- Modifications in Makefile.in and scripts/dkmkproto.pl for SVR4 packaging.
+
+* Mon Jan 18 2016 Dirk Krause <krause.dirk@web.de> 4.2.0-0.0.1
+- Performance fix for dk-send/dk-recv: Use larger buffers.
+- Performance fix for dk-ls: Avoid unnecessary size calculations.
+- Programs dk-t2db, dk-db2t and dk-dbco to replace dkdbt.
+- Libraries dk4dbia and dk4dbi added to replace dk3dbi.
+- Bugfix in dk4loc module, set encoding even if no LANG variable available.
+
+* Mon Dec 14 2015 Dirk Krause <krause.dirk@web.de> 4.1.0-0.0.1
+- Added -s option to dk-ls, show summary at end.
+- Manpage installation avoided, when building on Debian
+ (manpage installation on Debian is done by package management).
+- New functions to retrieve and expand strings from Windows registry.
+- Changes in makefiles for Visual Studio for Desktop on Windows.
+- Bugfix in dk4user module: Must expand user profile string from registry.
+- Bugfix in DkClockFrame.wxc: Minimum size specified.
+- Bugfix in DkWxImgszFrame.wxc: Format specifier corrected.
+- Bugfix in DkWxImgszApp.cpt: Load all image handlers wxInitAllImageHandlers()
+
+* Fri Dec 04 2015 Dirk Krause <krause.dirk@web.de> 4.0.10-0.0.1
+- Man pages added, required for Debian packaging.
+- Build process on Windows can now use different library directories.
+- Bugfix in dkdbt program: No longer error messages for comment lines.
+- First release after changing Linux distribution to Debian on my laptop.
+
+* Tue Nov 10 2015 Dirk Krause <krause.dirk@web.de> 4.0.9-0.0.1
+- Bugfix in Makefile.in: Some programs were mentioned twice.
+
+* Sun Nov 08 2015 Dirk Krause <krause.dirk@web.de> 4.0.8-0.0.1
+- Number of duplicated files in source archive reduced by use of hard links.
+
+* Fri Oct 16 2015 Dirk Krause <krause.dirk@web.de> 4.0.7-0.0.1
+- Bugfix in dk4loc module: Use "en" as default language.
+- Bugfix in configure.ac: Install shared libraries for rescue systems too.
+
+* Sat Oct 10 2015 Dirk Krause <krause.dirk@web.de> 4.0.6-0.0.1
+- Added -t option to dk-sort.
+- Only one AC_OUTPUT line in Makefile.in.
+
+* Tue Oct 06 2015 Dirk Krause <krause.dirk@web.de> 4.0.5-0.0.1
+- Help text for dk-recv corrected, host and port are mandatory.
+- Compiler flags for wxcs added in Makefile.in.
+- Removed some dead assignments after static analysis.
+
+* Wed Sep 23 2015 Dirk Krause <krause.dirk@web.de> 4.0.4-0.0.1
+- Makefile.in: Use C++ compiler to drive linker if any C++ module in project.
+- Makefile.in: libdk4wx.a in the LIB_ST_GUI group, not LIB_ST_CLI.
+- dktools.pc.in: Correct variable for version number used now.
+- dk3strkv/dk-sqlsplit: S_ERROR replaced by ST_ERROR.
+- configure.ac: No -Bdynamic -dy -KPIC -D_REENTRANT for static builds.
+- configure.ac: Option --with-corrections for some Solaris systems.
+
+* Tue Aug 11 2015 Dirk Krause <krause.dirk@web.de> 4.0.3-0.0.1
+- Module dk3uc2l rewritten to use the *.t2l files.
+
+* Tue Aug 04 2015 Dirk Krause <krause.dirk@web.de> 4.0.2-0.0.1
+- Setting for tooltip flag added to dkct.
+
+* Tue Aug 04 2015 Dirk Krause <krause.dirk@web.de> 4.0.1-0.0.1
+- dkct: Special placeholders in $? format string.
+- dkct: Option -p added for portable debug output code.
+
+* Tue Aug 04 2015 Dirk Krause <krause.dirk@web.de> 4.0.0-0.0.1
+- New rewritten library modules dk4*.
+- Simplified error reporting from callee to caller via dk4_er_t structure.
+- Reduced use of runtime library on Windows systems.
+- Text stream processing functions recognize BOM at start of data.
+- Multiple dk4sock* modules instead of one large module.
+- wxdkfcs: GUI program to inspect file checksums.
+- dkt: Replaced by multiple smaller programs.
+- dkct: Cell contents for wxGrid in wx gui section.
+
+* Thu Jul 09 2015 Dirk Krause <krause.dirk@web.de> 3.18.10-0.0.1
+- dk-tape: Code simplified.
+
+* Thu Apr 02 2015 Dirk Krause <krause.dirk@web.de> 3.18.9-0.0.1
+- Modified configure script and Makefile for --enable-packaging option.
+
+* Fri Mar 13 2015 Dirk Krause <krause.dirk@web.de> 3.18.8-0.0.1
+- Modified configure script and Makefile.
+
+* Sat Feb 21 2015 Dirk Krause <krause.dirk@web.de> 3.18.7-0.0.1
+- dkct: Bugfix, doxygen allows pure @file lines.
+
+* Wed Jan 28 2015 Dirk Krause <krause.dirk@web.de> 3.18.6-0.0.1
+- Bugfix in plpdftex: smash used only for texts aligned by base line.
+
+* Thu Jan 22 2015 Dirk Krause <krause.dirk@web.de> 3.18.5-0.0.1
+- Bugfix in dkt tape: wrong number printed.
+- Bugfix in plpdftex: smash not for texts in boxes.
+- Modified pjsnmp: Added pjsnmpreadystates configuration option
+- Modified pjsnmp: Message texts modified, distinction errors/warnings.
+
+* Mon Dec 08 2014 Dirk Krause <krause.dirk@web.de> 3.18.4-0.0.1
+- Bugfix in plpdftex: sometimes invalid *.tex output.
+
+* Mon Dec 01 2014 Dirk Krause <krause.dirk@web.de> 3.18.3-0.0.1
+- Bugfix in UTF-16 encoding: Surrogate range was wrong.
+
+* Wed Nov 26 2014 Dirk Krause <krause.dirk@web.de> 3.18.2-0.0.1
+- Modified dkct: No @file line added if @file line is already present.
+- Data type dk3_c32_t changed to unsigned if unsigned is 4 bytes long.
+- Check whether password memory really was reset.
+
+* Tue Oct 21 2014 Dirk Krause <krause.dirk@web.de> 3.18.1-0.0.1
+- Bugfix in multiplication overflow detection in dk3mas/dk3mai/dk3mal modules.
+
+* Thu Oct 16 2014 Dirk Krause <krause.dirk@web.de> 3.18.0-0.0.1
+- Copyright year check in dkct.
+- API bugfix in dk3str32/dk3str16: Use correct character size now.
+- Bugfix in htmlbook for using dkChar.
+- Bugfix in dkdbt for using dkChar.
+- Splitted dk3mastr module into several modules.
+- Most uses of sscanf() and dk3sf_sscanf3() replaced by other functions.
+
+* Wed Sep 24 2014 Dirk Krause <krause.dirk@web.de> 3.17.2-0.0.1
+- Bugfix in dk3sock: WSAEWOULDBLOCK is used for connect in progress.
+
+* Fri Sep 12 2014 Dirk Krause <krause.dirk@web.de> 3.17.1-0.0.1
+- Bugfix in archive creation: Permissions are correct now.
+
+* Wed Sep 03 2014 Dirk Krause <krause.dirk@web.de> 3.17.0-0.0.1
+- Appendices k, M, G for block size added for dkt blks/ dkt ed/dkt rnd.
+- Bugfix in fig2lat: EPS/PDF/PGF output driver, corner radius.
+- Bugfix in wxbmpp dk3paper module.
+- Bugfix in wxbmpp: Fitting to a paper size.
+
+* Thu Aug 07 2014 Dirk Krause <krause.dirk@web.de> 3.16.3-0.0.1
+- Changed build process for Linux/Unix.
+
+* Tue Aug 05 2014 Dirk Krause <krause.dirk@web.de> 3.16.2-0.0.1
+- Changed build process for Linux/Unix, removed options from configure.
+
+* Tue Aug 05 2014 Dirk Krause <krause.dirk@web.de> 3.16.1-0.0.1
+- Use wxFD_OPEN instead of wxOPEN.
+- Bugfix in makefile: CLFAGS was a typo.
+
+* Mon Jul 28 2014 Dirk Krause <krause.dirk@web.de> 3.16.0-0.0.1
+- New program plpdftex added, output driver for octpgfpl.
+- Prefer sigaction() over sigset().
+- Function-like macros replaced by functions.
+- Modified overflow check for conversion from unsigned long to size_t.
+- Modified dk3ma module: Splitted into several smaller modules.
+- Functions dk3strm_double_c8_no_sci()... added.
+- Function dk3pdf_write_double() treats small numbers as 0.
+
+* Sat Jun 28 2014 Dirk Krause <krause.dirk@web.de> 3.15.0-0.0.1
+- Source code reorganized.
+
+* Thu Jun 19 2014 Dirk Krause <krause.dirk@web.de> 3.14.0-0.0.1
+- Options -S... added to dkct and wxdkct.
+- Memory usage reorganized for bit matrices.
+- Cache friendly algorithm for bit matrix expansion.
+- dktools.spec file modified to build sub-packages lib and devel.
+
+* Tue May 27 2014 Dirk Krause <krause.dirk@web.de> 3.13.0-0.0.1
+- Modified htmlbook: Line numbering for source code.
+- Modified dkt html: Line numbering for source code.
+- Added *.desktop files for GUI programs.
+
+* Wed Apr 30 2014 Dirk Krause <krause.dirk@web.de> 3.12.0-0.0.1
+- New application wxdkhtb added to view help text files.
+- Modified htmlbook: enable/disable full text search in *.chm output.
+- Installation bugfix: Forgot to install libdk3wx.so.
+- HTML files for online help now created by htmlbook.
+- API change in DkWxFrame class: Methods added.
+
+* Wed Apr 23 2014 Dirk Krause <krause.dirk@web.de> 3.11.0-0.0.1
+- htmlbook: Writing project.xml file.
+- htmlbook: New option chm full text search.
+- htmlbook: Section number optional before section title in index and pos.
+- htmlbook: Titles for links in keyword index.
+- htmlbook: Bugfix, all *.html files listed in files section.
+- htmlbook: Bugfix, added missing closing OBJECT tag.
+- htmlbook: Bugfix, copy index.hhp, index.hhc and index.hhk to destination.
+- htmlbook: Bugfix, root object now in TOC as first object.
+- printqd: Attempt to remove existing local socket before creating new one.
+- printqd: Bugfix, endless loop.
+- wxdkclock: Save changed options immediately.
+
+* Mon Mar 31 2014 Dirk Krause <krause.dirk@web.de> 3.10.0-0.0.1
+- Modified fig2lat: Fast splines for arrowheads.
+- Modified fig2lat: Configurable base line width.
+
+* Mon Mar 24 2014 Dirk Krause <krause.dirk@web.de> 3.9.0-0.0.1
+- Bugfix in bmpp/wxbmpp: Bits per component analysis rewritten.
+
+* Sun Mar 02 2014 Dirk Krause <krause.dirk@web.de> 3.8.3-0.0.1
+- Bugfix bmpp/wxbmpp: Automatic bits per component analysis disabled.
+- Modified htmlbook: New classes for table cells added to style.css file.
+
+* Thu Feb 06 2014 Dirk Krause <krause.dirk@web.de> 3.8.2-0.0.1
+- Modified htmlbook: New no-vspace option for img special command.
+- Modified htmlbook: Shortcuts for images.
+
+* Wed Jan 29 2014 Dirk Krause <krause.dirk@web.de> 3.8.1.0.0.1
+- Modified htmlbook: Set permissions for destination directory contents.
+- Modified htmlbook: Change in style.css, added top and bottom margin.
+- Bugfix in htmlbook: Crashes on filenames without suffix.
+
+* Tue Jan 21 2014 Dirk Krause <krause.dirk@web.de> 3.8.0-0.0.1
+- New application htmlbook added.
+- Bugfix in dk3enc module: Wrong range delimiter for Unicode characters.
+
+* Fri Nov 29 2013 Dirk Krause <krause.dirk@web.de> 3.7.0-0.0.1
+- Modified dkt latex: Euro currency symbol added to translation table.
+- Modified dkma: long long, unsigned long long, intmax_t, uintmax_t.
+
+* Thu Nov 14 2013 Dirk Krause <krause.dirk@web.de> 3.6.0-0.0.1
+- Modified fig2lat: New cofop option for filled open graphics paths.
+- Bugfix in fig2lat: Must encode some characters.
+- Modified dk3ma: Function and constants names changed for consistent naming.
+
+* Wed Oct 23 2013 Dirk Krause <krause.dirk@web.de> 3.5.0-0.0.1
+- Modified wxbmpp: No automatic start when running on a directory.
+
+* Tue Oct 01 2013 Dirk Krause <krause.dirk@web.de> 3.4.0-0.0.1
+- Modified dkt blocksize: Performance optimizations, use memcpy().
+- Modified dk3sock module: Handle incomplete send requests.
+- Modified dk3str module: Use existing functions if available.
+
+* Fri Sep 20 2013 Dirk Krause <krause.dirk@web.de> 3.3.3-0.0.1
+- Option -s for dkt blocksize added.
+- Modified itadmin: Increased possible length for DHCP options values.
+- Bugfix in itadmin: DHCP options for hosts are written now.
+
+* Tue Jul 30 2013 Dirk Krause <krause.dirk@web.de> 3.3.2-0.0.1
+- Modified dk3sto module: Keyword const added to some functions.
+
+* Mon Jul 29 2013 Dirk Krause <krause.dirk@web.de> 3.3.1-0.0.1
+- Bugfix in distribution and build system.
+
+* Sun Jul 28 2013 Dirk Krause <krause.dirk@web.de> 3.3.0-0.0.1
+- API change, comparison and evaluation functions operate on const * pointers.
+
+* Wed Jul 24 2013 Dirk Krause <krause.dirk@web.de> 3.2.2-0.0.1
+- More useful error message for malformed path to dkt ls on Windows
+ (paths in double quotes where backslash escapes closing double quote).
+
+* Thu Mar 20 2013 Dirk Krause <krause.dirk@web.de> 3.0.6-0.0.1
+- dkct enhanced for unknown classes.
+
+* Wed Mar 20 2013 Dirk Krause <krause.dirk@web.de> 3.0.5-0.0.1
+- Bugfix: Use AddButton method of wxStdButtonSizer, not Add.
+
+* Sun Mar 17 2013 Dirk Krause <krause.dirk@web.de> 3.0.4-0.0.1
+- The dk3sock4 module was added.
+
+* Sat Mar 16 2013 Dirk Krause <krause.dirk@web.de> 3.0.3-0.0.1
+- Online documentation updated for the -f option in dknet.
+
+* Thu Mar 14 2013 Dirk Krause <krause.dirk@web.de> 3.0.2-0.0.1
+- The dknet program is more verbose now when run as sender.
+
+* Sun Feb 03 2013 Dirk Krause <krause.dirk@web.de> 3.0.1-0.0.1
+- The dkwxwiz program was added.
+- The winprint program (for Windows) was added.
+- The wprclean program (for Windows) was added.
+- The lprngcl program (for Windows) was added.
+- Option bbts for fig2lat.
+- Bugfix in Win32 setup: The dk3paper.conf file was not installed.
+
+* Thu Jan 31 2013 Dirk Krause <krause.dirk@web.de> 3.0.0-0.0.12
+- Code for 3.0.0 release finished.
+
+* Wed Nov 02 2011 Dirk Krause <krause.dirk@web.de> 2.2.22-0.0.1
+- Bugfix in the configure script: Unnecessary call to wx-config removed.
+
+* Tue Nov 01 2011 Dirk Krause <krause.dirk@web.de> 2.2.21-0.0.1
+- The hostsadm.pl script now adds a netgroup triple containing
+ the IP address to the netgroup.ldif file.
+- The "ctrl database-cleanup" operation for prqd now removes
+ print accounts and page counts with value 0.
+
+* Sun Jun 06 2011 Dirk Krause <krause.dirk@web.de> 2.2.20-0.0.1
+- Program imgsize renamed to chimgsize to avoid name conflicts
+ with perl-Image-Size RPM.
+
+* Sun Apr 19 2011 Dirk Krause <krause.dirk@web.de> 2.2.19-0.0.1
+- Bugfix in text2htm, wrong format specification.
+
+* Sun Nov 14 2010 Dirk Krause <krause.dirk@web.de> 2.2.18-0.0.1
+- The function dkstr_w_cat() (a fallback implementation for systems without
+ the wcscat() function) was added.
+- New programs kwintool and kwindown for Windows.
+
+* Tue Oct 26 2010 Dirk Krause <krause.dirk@web.de> 2.2.17-0.0.1
+- New option ``create accounts automatically'' for prqd. By default
+ we avoid to create personal print accounts automatically to keep
+ the database small.
+- Improvements in the GUI of the PrintLimit application.
+
+* Sun Oct 24 2010 Dirk Krause <krause.dirk@web.de> 2.2.16-0.0.1
+- New Java application PrintLimit for users of LPRng/prqd to show
+ users print quota information.
+- The dklibsj.html page was improved. Tutorial and short reference added.
+
+* Wed Oct 20 2010 Dirk Krause <krause.dirk@web.de> 2.2.15-0.0.1
+- The LANG environment variable is now tested for both ".UTF-8"
+ and ".utf8" to indicate the use of UTF-8 encoding.
+
+* Wed Sep 15 2010 Dirk Krause <krause.dirk@web.de> 2.2.14-0.0.1
+- Documentation update: Notes about differences in the appearance of
+ interpolated splines in Xfig/transfig and fig2vect. Recommendations how
+ to modify the sources of Xfig and transfig.
+
+* Tue Sep 14 2010 Dirk Krause <krause.dirk@web.de> 2.2.13-0.0.1
+- Corrected typographic errors in the DKrause::Diagram documentation.
+
+* Tue Sep 13 2010 Dirk Krause <krause.dirk@web.de> 2.2.12-0.0.1
+- The *.jar files were missing in the Windows executable setup of
+ 2.2.11. Here they are back.
+
+* Tue Aug 31 2010 Dirk Krause <krause.dirk@web.de> 2.2.11-0.0.1
+- Unnecessary line end correction removed from fig2vect.
+- New Perl module DKrause::Diagram added
+
+* Tue Jul 20 2010 Dirk Krause <krause.dirk@web.de> 2.2.10-0.0.1
+- Documentation corrections.
+
+* Fri Jul 16 2010 Dirk Krause <krause.dirk@web.de> 2.2.9-0.0.1
+- Bugfix in tracecc, application group name corrected.
+
+* Mon Jul 12 2010 Dirk Krause <krause.dirk@web.de> 2.2.8-0.0.1
+- Modifications in configure script for build process on Mac.
+
+* Sat Jun 26 2010 Dirk Krause <krause.dirk@web.de> 2.2.6-0.0.1
+- Bugfix in bmeps, bits per component reduction disabled.
+- Modifications in HTML documentation due to validation results.
+- New option "doxygen comments" for genau.
+- Script "make-pkg.sh" to build SVR4 packages.
+- Doxygen comments added.
+
+* Fri Jun 18 2010 Dirk Krause <krause.dirk@web.de> 2.2.5-0.0.1
+- Modified hostsadm: UTF-8 to ISO-LATIN-1 conversion.
+- Code cleanup.
+
+* Sun Jun 13 2010 Dirk Krause <krause.dirk@web.de> 2.2.4-0.0.1
+- File dktools.spec added.
+- Start scripts for prqd, rshdown, useraud now installed to /etc/init.d.
+
+* Sat Jun 12 2010 Dirk Krause <krause.dirk@web.de> 2.2.3-0.0.1
+- DESTDIR variable added to makefile for RPM builders.
+
+* Thu Jun 03 2010 Dirk Krause <krause.dirk@web.de> 2.2.2-0.0.1
+- Bugfix for preference file location.
+
diff --git a/support/dktools/dktools-el7.spec b/support/dktools/dktools-el7.spec
new file mode 100644
index 0000000000..c4c97d5482
--- /dev/null
+++ b/support/dktools/dktools-el7.spec
@@ -0,0 +1,701 @@
+#
+# If you think the *.spec files need corrections, please send me a
+# complete working *.spec file, not just a bug report.
+# I moved my laptop from Scientific Linux to Debian (they still
+# provide a 32 bit version with recent software), so I do no longer
+# have access to machines I could use to test *.spec files.
+#
+Name: dktools
+Version: 4.8.3
+Source: file:///home/krause/work/dktools-4.8.3.tar.gz
+Release: 1%{?dist}
+Summary: Dirk Krause's tools and libraries
+Vendor: Dirk Krause
+# Packager: Dirk Krause
+Group: Applications/System
+License: BSD
+URL: http://dktools.sourceforge.net/index.html
+BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
+
+BuildRequires: mysql-devel zlib-devel bzip2-devel libpng-devel openssl-devel libjpeg-devel libtiff-devel net-snmp-devel wxGTK wxGTK-devel
+Requires: zlib bzip2 openssl mysql-libs libpng libjpeg libtiff net-snmp wxGTK
+Conflicts: dktools-rescue
+Prefix: %{_prefix}
+
+Provides: libdk3bif.so.4.8()(64bit)
+Provides: libdk3bmeps.so.4.8()(64bit)
+Provides: libdk3c.so.4.8()(64bit)
+Provides: libdk3csrnd.so.4.8()(64bit)
+Provides: libdk3dbi.so.4.8()(64bit)
+Provides: libdk3fig.so.4.8()(64bit)
+Provides: libdk3of.so.4.8()(64bit)
+Provides: libdk3trace.so.4.8()(64bit)
+Provides: libdk3wx.so.4.8()(64bit)
+Provides: libdk4app.so.4.8()(64bit)
+Provides: libdk4base.so.4.8()(64bit)
+Provides: libdk4c.so.4.8()(64bit)
+Provides: libdk4dbia.so.4.8()(64bit)
+Provides: libdk4dbi.so.4.8()(64bit)
+Provides: libdk4lat.so.4.8()(64bit)
+Provides: libdk4maio8d.so.4.8()(64bit)
+Provides: libdk4maio8h.so.4.8()(64bit)
+Provides: libdk4maiodd.so.4.8()(64bit)
+Provides: libdk4maiodh.so.4.8()(64bit)
+Provides: libdk4maiowd.so.4.8()(64bit)
+Provides: libdk4maiowh.so.4.8()(64bit)
+Provides: libdk4maioxd.so.4.8()(64bit)
+Provides: libdk4ma.so.4.8()(64bit)
+Provides: libdk4mdrnd.so.4.8()(64bit)
+Provides: libdk4pppta.so.4.8()(64bit)
+Provides: libdk4pppt.so.4.8()(64bit)
+Provides: libdk4socka.so.4.8()(64bit)
+Provides: libdk4sock.so.4.8()(64bit)
+Provides: libdk4wx.so.4.8()(64bit)
+
+%description
+A set of tools for graphics conversion, text conversion, software
+development, administration and printing and some general-purpose tools.
+ bmpp / wxbmpp Convert PNG/JPEG/TIFF to PS/EPS/PDF
+ fig2lat Convert FIG to PGF,EPS+TeX,PDF+TeX,EPS,SVG
+ wximgsz Suggest good sizes to rescale bitmap images
+ htmlbook Publish HTML like a book
+ dkct / wxdkct Preprocessor for C, C++, Objective-C and Java
+ (debugging/tracing, state machines, wxWidgets GUIs)
+ dkwxwiz Create project skeleton for wxWidgets+dktools based programs
+ wxdkhtb Viewer for *.htb help files
+ itadmin Use a MySQL database to manage your IT
+ dk-ls ls clone, configurable column order
+ dk-fic File integrity checker
+ dk-bmm Backup media manager (10 tape rotation)
+ dk-blks Correct data stream blocksize (for use with dd)
+ dk-eradisk Create data stream to erase a disk
+ dk-hex Show data in hexadecimal or octal notation
+ dk-cat cat clone, recoding between ASCII/UTF-8/UTF-16
+ dk-sort sort clone, processes ASCII/UTF-8/UTF-16
+ dk-t2h Text to HTML converter
+ dk-t2l Text to LaTeX converter
+ dk-sqlsplit Split overlong SQL lines from mysqldump
+ dk-uid Find user ID in given range
+ dk-pwgen Create passwords, PINs and WiFi keys
+ dk-send Send data stream to one or multiple recipients over TCP
+ dk-recv Receive data stream from a dk-send process
+ dkdbt Tool for simple databases
+ printqd Print quota enforcement for LPRng print systems
+ wxpqdic GUI client to check print quota
+ addctrld Add CTRL-D to end of data stream if not yet present
+ wxdkclock Simple clock, one alert
+ plpdftex Output driver for octpgfpl
+
+%prep
+%setup -q
+# %setup
+
+
+%build
+%configure --enable-packaging
+make %{?_smp_mflags}
+
+%install
+rm -rf $RPM_BUILD_ROOT
+make install DESTDIR=$RPM_BUILD_ROOT
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+
+%files
+%defattr(-,root,root,-)
+%doc README bsdlic.txt
+%{_bindir}/*
+%{_libdir}/libdk3*.so.*
+%{_libdir}/libdk4*.so.*
+%{_datadir}/applications/*
+%{_datadir}/dktools
+%{_datadir}/dk4app
+%{_datadir}/man/man1/*
+%{_datadir}/man/man5/*
+%{_sysconfdir}/printqd/printqd.conf.sample
+%{_sysconfdir}/rshdown/rshdown.conf.sample
+%config %{_sysconfdir}/dk3app/dk3paper.conf
+
+%post
+# ##### ATTEMPT TO GUESS USER AND GROUP FOR LPRng LPD DAEMON
+#
+LPUSER=`getent passwd | grep '^daemon:' | cut -f 1 -d :`
+if [ "X$LPUSER" = "X" ]
+then
+ LPUSER=`getent passwd | grep '^lp:' | cut -f 1 -d :`
+fi
+if [ "X$LPUSER" = "X" ]
+then
+ LPUSER="root"
+fi
+LPGROUP=`getent group | grep '^daemon:' | cut -f 1 -d :`
+if [ "X$LPGROUP" = "X" ]
+then
+ LPGROUP=`getent group | grep '^lp:' | cut -f 1 -d :`
+fi
+if [ "X$LPGROUP" = "X" ]
+then
+ LPGROUP="root"
+fi
+#
+# #####
+#
+#
+#
+# ##### LINUX DISTRIBUTION PACKAGERS
+# ##### If your distribution contains the LPRng software, please
+# ##### uncomment the two lines below and set LPUSER and LPGROUP to
+# ##### the user and group used to run the LPRng lpd daemon on
+# ##### your distribution.
+# ##### Optionally remove the lines above attempting to guess these names.
+#
+# LPUSER="daemon"
+# LPGROUP="daemon"
+#
+# #####
+for i in /var/printqd /var/log/printqd /var/run/printqd
+do
+ [ -d $i ] || mkdir -p $i
+ chown -R ${LPUSER}:${LPGROUP} $i
+ chmod 770 $i
+done
+ldconfig
+
+%postun
+if [ "X$1" = "X0" ]
+then
+ [ ! -d /var/run/printqd ] || rm -fr /var/run/printqd
+ [ ! -d /var/log/printqd ] || rm -fr /var/log/printqd
+fi
+ldconfig
+
+
+
+#
+# The rescue sub-package installs only those binaries useful on
+# a rescue live system.
+#
+%package rescue
+#
+# The devel sub-package installs developer support.
+#
+Summary: Only those DK tools binaries useful on a rescue live system
+Group: Applications/System
+Requires: zlib bzip2 openssl
+Conflicts: dktools
+Prefix: %{_prefix}
+
+%description rescue
+On live systems for system rescue we only need the dknet and dkt program.
+
+%files rescue
+%defattr(-,root,root,-)
+%doc README bsdlic.txt
+%{_bindir}/dk-send
+%{_bindir}/dk-recv
+%{_bindir}/dk-blks
+%{_bindir}/dk-cat
+%{_bindir}/dk-eradisk
+%{_bindir}/dk-ls
+%{_libdir}/libdk4socka.so.*
+%{_libdir}/libdk4sock.so.*
+%{_libdir}/libdk4maiodh.so.*
+%{_libdir}/libdk4maio8h.so.*
+%{_libdir}/libdk4app.so.*
+%{_libdir}/libdk4c.so.*
+%{_libdir}/libdk4maiodd.so.*
+%{_libdir}/libdk4maiowd.so.*
+%{_libdir}/libdk4maio8d.so.*
+%{_libdir}/libdk4base.so.*
+%{_datadir}/dktools/en/dk-send.*
+%{_datadir}/dktools/en/dk-recv.*
+%{_datadir}/dktools/en/dk-cat.*
+%{_datadir}/dktools/en/dk-blks.*
+%{_datadir}/dktools/en/dk-ls.*
+%{_datadir}/dktools/de/dk-send.*
+%{_datadir}/dktools/de/dk-recv.*
+%{_datadir}/dktools/de/dk-cat.*
+%{_datadir}/dktools/de/dk-blks.*
+%{_datadir}/dktools/de/dk-ls.*
+
+
+%post rescue
+ldconfig
+
+%postun rescue
+ldconfig
+
+
+
+
+
+%package devel
+Summary: Development files for libraries from the DK tools project
+Group: Development/Libraries
+Requires: dktools = %{version}-%{release} mysql-devel zlib-devel bzip2-devel libpng-devel openssl-devel libjpeg-devel libtiff-devel net-snmp-devel gcc wxGTK wxGTK-devel
+Prefix: %{_prefix}
+
+%description devel
+If you want to use modules from the DK tools project in your programs,
+you need the libraries from the dktools-lib package and the header
+files provided by this project.
+
+%files devel
+%defattr(-,root,root,-)
+%{_includedir}/*
+%{_libdir}/pkgconfig/dktools.pc
+%{_libdir}/libdk3*.so
+%{_libdir}/libdk4*.so
+
+%changelog
+
+* Tue Mar 28 2017 Dirk Krause <krause.dirk@web.de> 4.8.3-0.0.1
+- Followed improvement suggestions from the CTAN team.
+
+* Fri Mar 24 2017 Dirk Krause <krause.dirk@web.de> 4.8.2-0.0.1
+- Modified bmpp to write a /CropBox in addition to /MediaBox in PDF output.
+
+* Wed Mar 22 2017 Dirk Krause <krause.dirk@web.de> 4.8.1-0.0.1
+- Modified dk-send to stop reading input if all clients disconnected
+ unexpectedly.
+
+* Sun Mar 19 2017 Dirk Krause <krause.dirk@web.de> 4.8.0-0.0.1
+- Library libdk4maioxd added (wxChar numbers input and output).
+- Package lshw added to package list for DKtoolian.
+- Configure script and Makefile.in modified to have less warnings from
+ Debian package building.
+
+* Fri Feb 03 2017 Dirk Krause <krause.dirk@web.de> 4.7.0-0.0.1
+- "xxxx" can be used as copyright end year in the "copyright year"
+ setting in options sections of *.ctr, *.wxc and *.cpt files.
+- New modules dk4paper and dk4papea to read papersizes configuration
+ files.
+
+* Sun Dec 11 2016 Dirk Krause <krause.dirk@web.de> 4.6.0-0.0.1
+- New functions in dk4memrs, dk4str8, dk4strw and dk4str to sanitize
+ buffers and strings.
+
+* Thu Oct 27 2016 Dirk Krause <krause.dirk@web.de> 4.5.0-0.0.1
+- Added support for meta/description and meta/keywords tags to htmlbook.
+- New modules for arithmetic operations on int16_t, uint16_t, int32_t, uint32_t.
+- New modules to serialize data to stream, unserialize from stream.
+- New module for compressed/encoded output on a dk4_stream_t.
+
+* Wed Sep 07 2016 Dirk Krause <krause.dirk@web.de> 4.4.0-0.0.1
+- Configuration option for itadmin to release lease on shutdown.
+- Markers in dhcpd.conf produced by itadmin for easier post-processing.
+- New module dk4strmw to open a file stream for writing.
+- New module dk4fpe to check for floating point exceptions.
+- New modules to read double from string and write double to string.
+- Mathematical operations on int16_t, int32_t, uint16_t and uint32_t
+ including error checking.
+- Inline functions or macros to copy, reset and compare memory buffers.
+- Modules dk4mai8dbl, dk4maiddbl, dk4maiwdbl, dk4mao8dbl, dk4maoddbl
+ and dk4maowdbl to read double from string and write double to string.
+- API change in dk4stream_write(): the buffer argument is const now.
+- Optimization in dk4stream_write().
+- Bugfixes in GUI applications: No wxXXX objects must survive OnExit().
+- Bugfixes in the dk4strw module.
+- Bugfixes in checking for mysql.h file.
+- Code cleanup in DkWxBmepsApp.cpt, DkWxImgszApp.cpt and DkWxTraceApp.cpt
+ to improve readability.
+
+* Tue Jul 12 2016 Dirk Krause <krause.dirk@web.de> 4.3.6-0.0.1
+- Bugfix for Windows (try multiple sources to get home directory).
+- Replacements for GetVersionEx() function in Windows.
+- Docu update for installation using stow.
+
+* Sat Jul 02 2016 Dirk Krause <krause.dirk@web.de> 4.3.5-0.0.1
+- New hint special command for htmlbook.
+- Scripts to produce live systems.
+
+* Fri Jun 10 2016 Dirk Krause <krause.dirk@web.de> 4.3.4-0.0.1
+- Added span.hint to style.css for htmlbook.
+- Smaller changes related to Debian packaging.
+
+* Sat May 28 2016 Dirk Krause <krause.dirk@web.de> 4.3.3-0.0.1
+- Debian packaging changed, developer package is dktools-lib-$(4.8)-dev.
+- RPM packaging changed, shared library symlinks now in devel package.
+- New script to generate debian/changelog from dktools-el6.spec.in file.
+
+* Fri May 27 2016 Dirk Krause <krause.dirk@web.de> 4.3.2-0.0.1
+- New special command "htmlname" in htmlbook program.
+- Directory structure in build process changed due to lintian complaints.
+- Bugfix in dktools.pc, Libs.private now set correctly.
+- Script itaclean.sh renamed to itaclean (due to lintian complaints).
+
+* Mon Apr 25 2016 Dirk Krause <krause.dirk@web.de> 4.3.1-0.0.1
+- Printqdc now accepts empty input lines.
+
+* Tue Apr 19 2016 Dirk Krause <krause.dirk@web.de> 4.3.0-0.0.1
+- Printqd and related programs rewritten completely.
+- Rshdown is back on a users request, ported to library version 4.
+- Print order character 'N' added to dk-ls (do not show symlink target).
+- Option -b for dk-pwgen on non-Windows systems (create binary random data).
+- New program dk-rand to generate binary random data.
+- Modifications to dk4_app_t and dk3_app_t modules: create log and tmp
+ directories only when needed.
+- Modified dk4inst.h header: Compiler constant texts for directories.
+- Module dk4dmt added, tool functions for standing daemons.
+- Modified dk4sock13 module, delete existing UNIX domain sockets.
+- Modified DkWxFrame and Dk4WxFrame, restore position when frame is shown.
+- Bugfix in dkwxwiz data files, typo corrected.
+- Bugfix in dk4dbi module, must set ulen, not size when retrieving data.
+- Retired dk3sock module, all networking programs use library version 4 now.
+
+* Fri Jan 22 2016 Dirk Krause <krause.dirk@web.de> 4.2.2-0.0.1
+- Modified dk-cat, dk-hex, dk-pwgen, dk-t2h, dk-t2l, dk-db2t:
+ No error message for SIGPIPE received.
+- Some modifications following suggestions from clang static code analysis.
+
+* Tue Jan 19 2016 Dirk Krause <krause.dirk@web.de> 4.2.1-0.0.1
+- Modifications in Makefile.in and scripts/dkmkproto.pl for SVR4 packaging.
+
+* Mon Jan 18 2016 Dirk Krause <krause.dirk@web.de> 4.2.0-0.0.1
+- Performance fix for dk-send/dk-recv: Use larger buffers.
+- Performance fix for dk-ls: Avoid unnecessary size calculations.
+- Programs dk-t2db, dk-db2t and dk-dbco to replace dkdbt.
+- Libraries dk4dbia and dk4dbi added to replace dk3dbi.
+- Bugfix in dk4loc module, set encoding even if no LANG variable available.
+
+* Mon Dec 14 2015 Dirk Krause <krause.dirk@web.de> 4.1.0-0.0.1
+- Added -s option to dk-ls, show summary at end.
+- Manpage installation avoided, when building on Debian
+ (manpage installation on Debian is done by package management).
+- New functions to retrieve and expand strings from Windows registry.
+- Changes in makefiles for Visual Studio for Desktop on Windows.
+- Bugfix in dk4user module: Must expand user profile string from registry.
+- Bugfix in DkClockFrame.wxc: Minimum size specified.
+- Bugfix in DkWxImgszFrame.wxc: Format specifier corrected.
+- Bugfix in DkWxImgszApp.cpt: Load all image handlers wxInitAllImageHandlers()
+
+* Fri Dec 04 2015 Dirk Krause <krause.dirk@web.de> 4.0.10-0.0.1
+- Man pages added, required for Debian packaging.
+- Build process on Windows can now use different library directories.
+- Bugfix in dkdbt program: No longer error messages for comment lines.
+- First release after changing Linux distribution to Debian on my laptop.
+
+* Tue Nov 10 2015 Dirk Krause <krause.dirk@web.de> 4.0.9-0.0.1
+- Bugfix in Makefile.in: Some programs were mentioned twice.
+
+* Sun Nov 08 2015 Dirk Krause <krause.dirk@web.de> 4.0.8-0.0.1
+- Number of duplicated files in source archive reduced by use of hard links.
+
+* Fri Oct 16 2015 Dirk Krause <krause.dirk@web.de> 4.0.7-0.0.1
+- Bugfix in dk4loc module: Use "en" as default language.
+- Bugfix in configure.ac: Install shared libraries for rescue systems too.
+
+* Sat Oct 10 2015 Dirk Krause <krause.dirk@web.de> 4.0.6-0.0.1
+- Added -t option to dk-sort.
+- Only one AC_OUTPUT line in Makefile.in.
+
+* Tue Oct 06 2015 Dirk Krause <krause.dirk@web.de> 4.0.5-0.0.1
+- Help text for dk-recv corrected, host and port are mandatory.
+- Compiler flags for wxcs added in Makefile.in.
+- Removed some dead assignments after static analysis.
+
+* Wed Sep 23 2015 Dirk Krause <krause.dirk@web.de> 4.0.4-0.0.1
+- Makefile.in: Use C++ compiler to drive linker if any C++ module in project.
+- Makefile.in: libdk4wx.a in the LIB_ST_GUI group, not LIB_ST_CLI.
+- dktools.pc.in: Correct variable for version number used now.
+- dk3strkv/dk-sqlsplit: S_ERROR replaced by ST_ERROR.
+- configure.ac: No -Bdynamic -dy -KPIC -D_REENTRANT for static builds.
+- configure.ac: Option --with-corrections for some Solaris systems.
+
+* Tue Aug 11 2015 Dirk Krause <krause.dirk@web.de> 4.0.3-0.0.1
+- Module dk3uc2l rewritten to use the *.t2l files.
+
+* Tue Aug 04 2015 Dirk Krause <krause.dirk@web.de> 4.0.2-0.0.1
+- Setting for tooltip flag added to dkct.
+
+* Tue Aug 04 2015 Dirk Krause <krause.dirk@web.de> 4.0.1-0.0.1
+- dkct: Special placeholders in $? format string.
+- dkct: Option -p added for portable debug output code.
+
+* Tue Aug 04 2015 Dirk Krause <krause.dirk@web.de> 4.0.0-0.0.1
+- New rewritten library modules dk4*.
+- Simplified error reporting from callee to caller via dk4_er_t structure.
+- Reduced use of runtime library on Windows systems.
+- Text stream processing functions recognize BOM at start of data.
+- Multiple dk4sock* modules instead of one large module.
+- wxdkfcs: GUI program to inspect file checksums.
+- dkt: Replaced by multiple smaller programs.
+- dkct: Cell contents for wxGrid in wx gui section.
+
+* Thu Jul 09 2015 Dirk Krause <krause.dirk@web.de> 3.18.10-0.0.1
+- dk-tape: Code simplified.
+
+* Thu Apr 02 2015 Dirk Krause <krause.dirk@web.de> 3.18.9-0.0.1
+- Modified configure script and Makefile for --enable-packaging option.
+
+* Fri Mar 13 2015 Dirk Krause <krause.dirk@web.de> 3.18.8-0.0.1
+- Modified configure script and Makefile.
+
+* Sat Feb 21 2015 Dirk Krause <krause.dirk@web.de> 3.18.7-0.0.1
+- dkct: Bugfix, doxygen allows pure @file lines.
+
+* Wed Jan 28 2015 Dirk Krause <krause.dirk@web.de> 3.18.6-0.0.1
+- Bugfix in plpdftex: smash used only for texts aligned by base line.
+
+* Thu Jan 22 2015 Dirk Krause <krause.dirk@web.de> 3.18.5-0.0.1
+- Bugfix in dkt tape: wrong number printed.
+- Bugfix in plpdftex: smash not for texts in boxes.
+- Modified pjsnmp: Added pjsnmpreadystates configuration option
+- Modified pjsnmp: Message texts modified, distinction errors/warnings.
+
+* Mon Dec 08 2014 Dirk Krause <krause.dirk@web.de> 3.18.4-0.0.1
+- Bugfix in plpdftex: sometimes invalid *.tex output.
+
+* Mon Dec 01 2014 Dirk Krause <krause.dirk@web.de> 3.18.3-0.0.1
+- Bugfix in UTF-16 encoding: Surrogate range was wrong.
+
+* Wed Nov 26 2014 Dirk Krause <krause.dirk@web.de> 3.18.2-0.0.1
+- Modified dkct: No @file line added if @file line is already present.
+- Data type dk3_c32_t changed to unsigned if unsigned is 4 bytes long.
+- Check whether password memory really was reset.
+
+* Tue Oct 21 2014 Dirk Krause <krause.dirk@web.de> 3.18.1-0.0.1
+- Bugfix in multiplication overflow detection in dk3mas/dk3mai/dk3mal modules.
+
+* Thu Oct 16 2014 Dirk Krause <krause.dirk@web.de> 3.18.0-0.0.1
+- Copyright year check in dkct.
+- API bugfix in dk3str32/dk3str16: Use correct character size now.
+- Bugfix in htmlbook for using dkChar.
+- Bugfix in dkdbt for using dkChar.
+- Splitted dk3mastr module into several modules.
+- Most uses of sscanf() and dk3sf_sscanf3() replaced by other functions.
+
+* Wed Sep 24 2014 Dirk Krause <krause.dirk@web.de> 3.17.2-0.0.1
+- Bugfix in dk3sock: WSAEWOULDBLOCK is used for connect in progress.
+
+* Fri Sep 12 2014 Dirk Krause <krause.dirk@web.de> 3.17.1-0.0.1
+- Bugfix in archive creation: Permissions are correct now.
+
+* Wed Sep 03 2014 Dirk Krause <krause.dirk@web.de> 3.17.0-0.0.1
+- Appendices k, M, G for block size added for dkt blks/ dkt ed/dkt rnd.
+- Bugfix in fig2lat: EPS/PDF/PGF output driver, corner radius.
+- Bugfix in wxbmpp dk3paper module.
+- Bugfix in wxbmpp: Fitting to a paper size.
+
+* Thu Aug 07 2014 Dirk Krause <krause.dirk@web.de> 3.16.3-0.0.1
+- Changed build process for Linux/Unix.
+
+* Tue Aug 05 2014 Dirk Krause <krause.dirk@web.de> 3.16.2-0.0.1
+- Changed build process for Linux/Unix, removed options from configure.
+
+* Tue Aug 05 2014 Dirk Krause <krause.dirk@web.de> 3.16.1-0.0.1
+- Use wxFD_OPEN instead of wxOPEN.
+- Bugfix in makefile: CLFAGS was a typo.
+
+* Mon Jul 28 2014 Dirk Krause <krause.dirk@web.de> 3.16.0-0.0.1
+- New program plpdftex added, output driver for octpgfpl.
+- Prefer sigaction() over sigset().
+- Function-like macros replaced by functions.
+- Modified overflow check for conversion from unsigned long to size_t.
+- Modified dk3ma module: Splitted into several smaller modules.
+- Functions dk3strm_double_c8_no_sci()... added.
+- Function dk3pdf_write_double() treats small numbers as 0.
+
+* Sat Jun 28 2014 Dirk Krause <krause.dirk@web.de> 3.15.0-0.0.1
+- Source code reorganized.
+
+* Thu Jun 19 2014 Dirk Krause <krause.dirk@web.de> 3.14.0-0.0.1
+- Options -S... added to dkct and wxdkct.
+- Memory usage reorganized for bit matrices.
+- Cache friendly algorithm for bit matrix expansion.
+- dktools.spec file modified to build sub-packages lib and devel.
+
+* Tue May 27 2014 Dirk Krause <krause.dirk@web.de> 3.13.0-0.0.1
+- Modified htmlbook: Line numbering for source code.
+- Modified dkt html: Line numbering for source code.
+- Added *.desktop files for GUI programs.
+
+* Wed Apr 30 2014 Dirk Krause <krause.dirk@web.de> 3.12.0-0.0.1
+- New application wxdkhtb added to view help text files.
+- Modified htmlbook: enable/disable full text search in *.chm output.
+- Installation bugfix: Forgot to install libdk3wx.so.
+- HTML files for online help now created by htmlbook.
+- API change in DkWxFrame class: Methods added.
+
+* Wed Apr 23 2014 Dirk Krause <krause.dirk@web.de> 3.11.0-0.0.1
+- htmlbook: Writing project.xml file.
+- htmlbook: New option chm full text search.
+- htmlbook: Section number optional before section title in index and pos.
+- htmlbook: Titles for links in keyword index.
+- htmlbook: Bugfix, all *.html files listed in files section.
+- htmlbook: Bugfix, added missing closing OBJECT tag.
+- htmlbook: Bugfix, copy index.hhp, index.hhc and index.hhk to destination.
+- htmlbook: Bugfix, root object now in TOC as first object.
+- printqd: Attempt to remove existing local socket before creating new one.
+- printqd: Bugfix, endless loop.
+- wxdkclock: Save changed options immediately.
+
+* Mon Mar 31 2014 Dirk Krause <krause.dirk@web.de> 3.10.0-0.0.1
+- Modified fig2lat: Fast splines for arrowheads.
+- Modified fig2lat: Configurable base line width.
+
+* Mon Mar 24 2014 Dirk Krause <krause.dirk@web.de> 3.9.0-0.0.1
+- Bugfix in bmpp/wxbmpp: Bits per component analysis rewritten.
+
+* Sun Mar 02 2014 Dirk Krause <krause.dirk@web.de> 3.8.3-0.0.1
+- Bugfix bmpp/wxbmpp: Automatic bits per component analysis disabled.
+- Modified htmlbook: New classes for table cells added to style.css file.
+
+* Thu Feb 06 2014 Dirk Krause <krause.dirk@web.de> 3.8.2-0.0.1
+- Modified htmlbook: New no-vspace option for img special command.
+- Modified htmlbook: Shortcuts for images.
+
+* Wed Jan 29 2014 Dirk Krause <krause.dirk@web.de> 3.8.1.0.0.1
+- Modified htmlbook: Set permissions for destination directory contents.
+- Modified htmlbook: Change in style.css, added top and bottom margin.
+- Bugfix in htmlbook: Crashes on filenames without suffix.
+
+* Tue Jan 21 2014 Dirk Krause <krause.dirk@web.de> 3.8.0-0.0.1
+- New application htmlbook added.
+- Bugfix in dk3enc module: Wrong range delimiter for Unicode characters.
+
+* Fri Nov 29 2013 Dirk Krause <krause.dirk@web.de> 3.7.0-0.0.1
+- Modified dkt latex: Euro currency symbol added to translation table.
+- Modified dkma: long long, unsigned long long, intmax_t, uintmax_t.
+
+* Thu Nov 14 2013 Dirk Krause <krause.dirk@web.de> 3.6.0-0.0.1
+- Modified fig2lat: New cofop option for filled open graphics paths.
+- Bugfix in fig2lat: Must encode some characters.
+- Modified dk3ma: Function and constants names changed for consistent naming.
+
+* Wed Oct 23 2013 Dirk Krause <krause.dirk@web.de> 3.5.0-0.0.1
+- Modified wxbmpp: No automatic start when running on a directory.
+
+* Tue Oct 01 2013 Dirk Krause <krause.dirk@web.de> 3.4.0-0.0.1
+- Modified dkt blocksize: Performance optimizations, use memcpy().
+- Modified dk3sock module: Handle incomplete send requests.
+- Modified dk3str module: Use existing functions if available.
+
+* Fri Sep 20 2013 Dirk Krause <krause.dirk@web.de> 3.3.3-0.0.1
+- Option -s for dkt blocksize added.
+- Modified itadmin: Increased possible length for DHCP options values.
+- Bugfix in itadmin: DHCP options for hosts are written now.
+
+* Tue Jul 30 2013 Dirk Krause <krause.dirk@web.de> 3.3.2-0.0.1
+- Modified dk3sto module: Keyword const added to some functions.
+
+* Mon Jul 29 2013 Dirk Krause <krause.dirk@web.de> 3.3.1-0.0.1
+- Bugfix in distribution and build system.
+
+* Sun Jul 28 2013 Dirk Krause <krause.dirk@web.de> 3.3.0-0.0.1
+- API change, comparison and evaluation functions operate on const * pointers.
+
+* Wed Jul 24 2013 Dirk Krause <krause.dirk@web.de> 3.2.2-0.0.1
+- More useful error message for malformed path to dkt ls on Windows
+ (paths in double quotes where backslash escapes closing double quote).
+
+* Thu Mar 20 2013 Dirk Krause <krause.dirk@web.de> 3.0.6-0.0.1
+- dkct enhanced for unknown classes.
+
+* Wed Mar 20 2013 Dirk Krause <krause.dirk@web.de> 3.0.5-0.0.1
+- Bugfix: Use AddButton method of wxStdButtonSizer, not Add.
+
+* Sun Mar 17 2013 Dirk Krause <krause.dirk@web.de> 3.0.4-0.0.1
+- The dk3sock4 module was added.
+
+* Sat Mar 16 2013 Dirk Krause <krause.dirk@web.de> 3.0.3-0.0.1
+- Online documentation updated for the -f option in dknet.
+
+* Thu Mar 14 2013 Dirk Krause <krause.dirk@web.de> 3.0.2-0.0.1
+- The dknet program is more verbose now when run as sender.
+
+* Sun Feb 03 2013 Dirk Krause <krause.dirk@web.de> 3.0.1-0.0.1
+- The dkwxwiz program was added.
+- The winprint program (for Windows) was added.
+- The wprclean program (for Windows) was added.
+- The lprngcl program (for Windows) was added.
+- Option bbts for fig2lat.
+- Bugfix in Win32 setup: The dk3paper.conf file was not installed.
+
+* Thu Jan 31 2013 Dirk Krause <krause.dirk@web.de> 3.0.0-0.0.12
+- Code for 3.0.0 release finished.
+
+* Wed Nov 02 2011 Dirk Krause <krause.dirk@web.de> 2.2.22-0.0.1
+- Bugfix in the configure script: Unnecessary call to wx-config removed.
+
+* Tue Nov 01 2011 Dirk Krause <krause.dirk@web.de> 2.2.21-0.0.1
+- The hostsadm.pl script now adds a netgroup triple containing
+ the IP address to the netgroup.ldif file.
+- The "ctrl database-cleanup" operation for prqd now removes
+ print accounts and page counts with value 0.
+
+* Sun Jun 06 2011 Dirk Krause <krause.dirk@web.de> 2.2.20-0.0.1
+- Program imgsize renamed to chimgsize to avoid name conflicts
+ with perl-Image-Size RPM.
+
+* Sun Apr 19 2011 Dirk Krause <krause.dirk@web.de> 2.2.19-0.0.1
+- Bugfix in text2htm, wrong format specification.
+
+* Sun Nov 14 2010 Dirk Krause <krause.dirk@web.de> 2.2.18-0.0.1
+- The function dkstr_w_cat() (a fallback implementation for systems without
+ the wcscat() function) was added.
+- New programs kwintool and kwindown for Windows.
+
+* Tue Oct 26 2010 Dirk Krause <krause.dirk@web.de> 2.2.17-0.0.1
+- New option ``create accounts automatically'' for prqd. By default
+ we avoid to create personal print accounts automatically to keep
+ the database small.
+- Improvements in the GUI of the PrintLimit application.
+
+* Sun Oct 24 2010 Dirk Krause <krause.dirk@web.de> 2.2.16-0.0.1
+- New Java application PrintLimit for users of LPRng/prqd to show
+ users print quota information.
+- The dklibsj.html page was improved. Tutorial and short reference added.
+
+* Wed Oct 20 2010 Dirk Krause <krause.dirk@web.de> 2.2.15-0.0.1
+- The LANG environment variable is now tested for both ".UTF-8"
+ and ".utf8" to indicate the use of UTF-8 encoding.
+
+* Wed Sep 15 2010 Dirk Krause <krause.dirk@web.de> 2.2.14-0.0.1
+- Documentation update: Notes about differences in the appearance of
+ interpolated splines in Xfig/transfig and fig2vect. Recommendations how
+ to modify the sources of Xfig and transfig.
+
+* Tue Sep 14 2010 Dirk Krause <krause.dirk@web.de> 2.2.13-0.0.1
+- Corrected typographic errors in the DKrause::Diagram documentation.
+
+* Tue Sep 13 2010 Dirk Krause <krause.dirk@web.de> 2.2.12-0.0.1
+- The *.jar files were missing in the Windows executable setup of
+ 2.2.11. Here they are back.
+
+* Tue Aug 31 2010 Dirk Krause <krause.dirk@web.de> 2.2.11-0.0.1
+- Unnecessary line end correction removed from fig2vect.
+- New Perl module DKrause::Diagram added
+
+* Tue Jul 20 2010 Dirk Krause <krause.dirk@web.de> 2.2.10-0.0.1
+- Documentation corrections.
+
+* Fri Jul 16 2010 Dirk Krause <krause.dirk@web.de> 2.2.9-0.0.1
+- Bugfix in tracecc, application group name corrected.
+
+* Mon Jul 12 2010 Dirk Krause <krause.dirk@web.de> 2.2.8-0.0.1
+- Modifications in configure script for build process on Mac.
+
+* Sat Jun 26 2010 Dirk Krause <krause.dirk@web.de> 2.2.6-0.0.1
+- Bugfix in bmeps, bits per component reduction disabled.
+- Modifications in HTML documentation due to validation results.
+- New option "doxygen comments" for genau.
+- Script "make-pkg.sh" to build SVR4 packages.
+- Doxygen comments added.
+
+* Fri Jun 18 2010 Dirk Krause <krause.dirk@web.de> 2.2.5-0.0.1
+- Modified hostsadm: UTF-8 to ISO-LATIN-1 conversion.
+- Code cleanup.
+
+* Sun Jun 13 2010 Dirk Krause <krause.dirk@web.de> 2.2.4-0.0.1
+- File dktools.spec added.
+- Start scripts for prqd, rshdown, useraud now installed to /etc/init.d.
+
+* Sat Jun 12 2010 Dirk Krause <krause.dirk@web.de> 2.2.3-0.0.1
+- DESTDIR variable added to makefile for RPM builders.
+
+* Thu Jun 03 2010 Dirk Krause <krause.dirk@web.de> 2.2.2-0.0.1
+- Bugfix for preference file location.
+
diff --git a/support/dktools/dktools-fedora.spec b/support/dktools/dktools-fedora.spec
new file mode 100644
index 0000000000..4ba218a0e2
--- /dev/null
+++ b/support/dktools/dktools-fedora.spec
@@ -0,0 +1,673 @@
+#
+# If you think the *.spec files need corrections, please send me a
+# complete working *.spec file, not just a bug report.
+# I moved my laptop from Scientific Linux to Debian (they still
+# provide a 32 bit version with recent software), so I do no longer
+# have access to machines I could use to test *.spec files.
+#
+Name: dktools
+Version: 4.8.3
+Source: file:///home/krause/work/dktools-4.8.3.tar.gz
+Release: 1%{?dist}
+Summary: Dirk Krause's tools and libraries
+Vendor: Dirk Krause
+# Packager: Dirk Krause
+Group: Applications/System
+License: BSD
+URL: http://dktools.sourceforge.net/index.html
+BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
+
+BuildRequires: community-mysql-devel zlib-devel bzip2-devel libpng-devel openssl-devel libjpeg-devel libtiff-devel net-snmp-devel wxGTK wxGTK-devel
+Requires: zlib bzip2 openssl mysql-libs libpng libjpeg libtiff net-snmp wxGTK
+Conflicts: dktools-rescue
+Prefix: %{_prefix}
+
+# ___PROVIDES___
+
+%description
+A set of tools for graphics conversion, text conversion, software
+development, administration and printing and some general-purpose tools.
+ bmpp / wxbmpp Convert PNG/JPEG/TIFF to PS/EPS/PDF
+ fig2lat Convert FIG to PGF,EPS+TeX,PDF+TeX,EPS,SVG
+ wximgsz Suggest good sizes to rescale bitmap images
+ htmlbook Publish HTML like a book
+ dkct / wxdkct Preprocessor for C, C++, Objective-C and Java
+ (debugging/tracing, state machines, wxWidgets GUIs)
+ dkwxwiz Create project skeleton for wxWidgets+dktools based programs
+ wxdkhtb Viewer for *.htb help files
+ itadmin Use a MySQL database to manage your IT
+ dk-ls ls clone, configurable column order
+ dk-fic File integrity checker
+ dk-bmm Backup media manager (10 tape rotation)
+ dk-blks Correct data stream blocksize (for use with dd)
+ dk-eradisk Create data stream to erase a disk
+ dk-hex Show data in hexadecimal or octal notation
+ dk-cat cat clone, recoding between ASCII/UTF-8/UTF-16
+ dk-sort sort clone, processes ASCII/UTF-8/UTF-16
+ dk-t2h Text to HTML converter
+ dk-t2l Text to LaTeX converter
+ dk-sqlsplit Split overlong SQL lines from mysqldump
+ dk-uid Find user ID in given range
+ dk-pwgen Create passwords, PINs and WiFi keys
+ dk-send Send data stream to one or multiple recipients over TCP
+ dk-recv Receive data stream from a dk-send process
+ dkdbt Tool for simple databases
+ printqd Print quota enforcement for LPRng print systems
+ wxpqdic GUI client to check print quota
+ addctrld Add CTRL-D to end of data stream if not yet present
+ wxdkclock Simple clock, one alert
+ plpdftex Output driver for octpgfpl
+
+%prep
+%setup -q
+# %setup
+
+
+%build
+%configure --enable-packaging
+make %{?_smp_mflags}
+
+%install
+rm -rf $RPM_BUILD_ROOT
+make install DESTDIR=$RPM_BUILD_ROOT
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+
+%files
+%defattr(-,root,root,-)
+%doc README bsdlic.txt
+%{_bindir}/*
+%{_libdir}/libdk3*.so.*
+%{_libdir}/libdk4*.so.*
+%{_datadir}/applications/*
+%{_datadir}/dktools
+%{_datadir}/dk4app
+%{_datadir}/man/man1/*
+%{_datadir}/man/man5/*
+%{_sysconfdir}/printqd/printqd.conf.sample
+%{_sysconfdir}/rshdown/rshdown.conf.sample
+%config %{_sysconfdir}/dk3app/dk3paper.conf
+
+%post
+# ##### ATTEMPT TO GUESS USER AND GROUP FOR LPRng LPD DAEMON
+#
+LPUSER=`getent passwd | grep '^daemon:' | cut -f 1 -d :`
+if [ "X$LPUSER" = "X" ]
+then
+ LPUSER=`getent passwd | grep '^lp:' | cut -f 1 -d :`
+fi
+if [ "X$LPUSER" = "X" ]
+then
+ LPUSER="root"
+fi
+LPGROUP=`getent group | grep '^daemon:' | cut -f 1 -d :`
+if [ "X$LPGROUP" = "X" ]
+then
+ LPGROUP=`getent group | grep '^lp:' | cut -f 1 -d :`
+fi
+if [ "X$LPGROUP" = "X" ]
+then
+ LPGROUP="root"
+fi
+#
+# #####
+#
+#
+#
+# ##### LINUX DISTRIBUTION PACKAGERS
+# ##### If your distribution contains the LPRng software, please
+# ##### uncomment the two lines below and set LPUSER and LPGROUP to
+# ##### the user and group used to run the LPRng lpd daemon on
+# ##### your distribution.
+# ##### Optionally remove the lines above attempting to guess these names.
+#
+# LPUSER="daemon"
+# LPGROUP="daemon"
+#
+# #####
+for i in /var/printqd /var/log/printqd /var/run/printqd
+do
+ [ -d $i ] || mkdir -p $i
+ chown -R ${LPUSER}:${LPGROUP} $i
+ chmod 770 $i
+done
+ldconfig
+
+%postun
+if [ "X$1" = "X0" ]
+then
+ [ ! -d /var/run/printqd ] || rm -fr /var/run/printqd
+ [ ! -d /var/log/printqd ] || rm -fr /var/log/printqd
+fi
+ldconfig
+
+
+
+#
+# The rescue sub-package installs only those binaries useful on
+# a rescue live system.
+#
+%package rescue
+#
+# The devel sub-package installs developer support.
+#
+Summary: Only those DK tools binaries useful on a rescue live system
+Group: Applications/System
+Requires: zlib bzip2 openssl
+Conflicts: dktools
+Prefix: %{_prefix}
+
+%description rescue
+On live systems for system rescue we only need the dknet and dkt program.
+
+%files rescue
+%defattr(-,root,root,-)
+%doc README bsdlic.txt
+%{_bindir}/dk-send
+%{_bindir}/dk-recv
+%{_bindir}/dk-blks
+%{_bindir}/dk-cat
+%{_bindir}/dk-eradisk
+%{_bindir}/dk-ls
+%{_libdir}/libdk4socka.so.*
+%{_libdir}/libdk4sock.so.*
+%{_libdir}/libdk4maiodh.so.*
+%{_libdir}/libdk4maio8h.so.*
+%{_libdir}/libdk4app.so.*
+%{_libdir}/libdk4c.so.*
+%{_libdir}/libdk4maiodd.so.*
+%{_libdir}/libdk4maiowd.so.*
+%{_libdir}/libdk4maio8d.so.*
+%{_libdir}/libdk4base.so.*
+%{_datadir}/dktools/en/dk-send.*
+%{_datadir}/dktools/en/dk-recv.*
+%{_datadir}/dktools/en/dk-cat.*
+%{_datadir}/dktools/en/dk-blks.*
+%{_datadir}/dktools/en/dk-ls.*
+%{_datadir}/dktools/de/dk-send.*
+%{_datadir}/dktools/de/dk-recv.*
+%{_datadir}/dktools/de/dk-cat.*
+%{_datadir}/dktools/de/dk-blks.*
+%{_datadir}/dktools/de/dk-ls.*
+
+
+%post rescue
+ldconfig
+
+%postun rescue
+ldconfig
+
+
+
+
+
+%package devel
+Summary: Development files for libraries from the DK tools project
+Group: Development/Libraries
+Requires: dktools = %{version}-%{release} community-mysql-devel zlib-devel bzip2-devel libpng-devel openssl-devel libjpeg-devel libtiff-devel net-snmp-devel gcc wxGTK wxGTK-devel
+Prefix: %{_prefix}
+
+%description devel
+If you want to use modules from the DK tools project in your programs,
+you need the libraries from the dktools-lib package and the header
+files provided by this project.
+
+%files devel
+%defattr(-,root,root,-)
+%{_includedir}/*
+%{_libdir}/pkgconfig/dktools.pc
+%{_libdir}/libdk3*.so
+%{_libdir}/libdk4*.so
+
+%changelog
+
+* Tue Mar 28 2017 Dirk Krause <krause.dirk@web.de> 4.8.3-0.0.1
+- Followed improvement suggestions from the CTAN team.
+
+* Fri Mar 24 2017 Dirk Krause <krause.dirk@web.de> 4.8.2-0.0.1
+- Modified bmpp to write a /CropBox in addition to /MediaBox in PDF output.
+
+* Wed Mar 22 2017 Dirk Krause <krause.dirk@web.de> 4.8.1-0.0.1
+- Modified dk-send to stop reading input if all clients disconnected
+ unexpectedly.
+
+* Sun Mar 19 2017 Dirk Krause <krause.dirk@web.de> 4.8.0-0.0.1
+- Library libdk4maioxd added (wxChar numbers input and output).
+- Package lshw added to package list for DKtoolian.
+- Configure script and Makefile.in modified to have less warnings from
+ Debian package building.
+
+* Fri Feb 03 2017 Dirk Krause <krause.dirk@web.de> 4.7.0-0.0.1
+- "xxxx" can be used as copyright end year in the "copyright year"
+ setting in options sections of *.ctr, *.wxc and *.cpt files.
+- New modules dk4paper and dk4papea to read papersizes configuration
+ files.
+
+* Sun Dec 11 2016 Dirk Krause <krause.dirk@web.de> 4.6.0-0.0.1
+- New functions in dk4memrs, dk4str8, dk4strw and dk4str to sanitize
+ buffers and strings.
+
+* Thu Oct 27 2016 Dirk Krause <krause.dirk@web.de> 4.5.0-0.0.1
+- Added support for meta/description and meta/keywords tags to htmlbook.
+- New modules for arithmetic operations on int16_t, uint16_t, int32_t, uint32_t.
+- New modules to serialize data to stream, unserialize from stream.
+- New module for compressed/encoded output on a dk4_stream_t.
+
+* Wed Sep 07 2016 Dirk Krause <krause.dirk@web.de> 4.4.0-0.0.1
+- Configuration option for itadmin to release lease on shutdown.
+- Markers in dhcpd.conf produced by itadmin for easier post-processing.
+- New module dk4strmw to open a file stream for writing.
+- New module dk4fpe to check for floating point exceptions.
+- New modules to read double from string and write double to string.
+- Mathematical operations on int16_t, int32_t, uint16_t and uint32_t
+ including error checking.
+- Inline functions or macros to copy, reset and compare memory buffers.
+- Modules dk4mai8dbl, dk4maiddbl, dk4maiwdbl, dk4mao8dbl, dk4maoddbl
+ and dk4maowdbl to read double from string and write double to string.
+- API change in dk4stream_write(): the buffer argument is const now.
+- Optimization in dk4stream_write().
+- Bugfixes in GUI applications: No wxXXX objects must survive OnExit().
+- Bugfixes in the dk4strw module.
+- Bugfixes in checking for mysql.h file.
+- Code cleanup in DkWxBmepsApp.cpt, DkWxImgszApp.cpt and DkWxTraceApp.cpt
+ to improve readability.
+
+* Tue Jul 12 2016 Dirk Krause <krause.dirk@web.de> 4.3.6-0.0.1
+- Bugfix for Windows (try multiple sources to get home directory).
+- Replacements for GetVersionEx() function in Windows.
+- Docu update for installation using stow.
+
+* Sat Jul 02 2016 Dirk Krause <krause.dirk@web.de> 4.3.5-0.0.1
+- New hint special command for htmlbook.
+- Scripts to produce live systems.
+
+* Fri Jun 10 2016 Dirk Krause <krause.dirk@web.de> 4.3.4-0.0.1
+- Added span.hint to style.css for htmlbook.
+- Smaller changes related to Debian packaging.
+
+* Sat May 28 2016 Dirk Krause <krause.dirk@web.de> 4.3.3-0.0.1
+- Debian packaging changed, developer package is dktools-lib-$(4.8)-dev.
+- RPM packaging changed, shared library symlinks now in devel package.
+- New script to generate debian/changelog from dktools-el6.spec.in file.
+
+* Fri May 27 2016 Dirk Krause <krause.dirk@web.de> 4.3.2-0.0.1
+- New special command "htmlname" in htmlbook program.
+- Directory structure in build process changed due to lintian complaints.
+- Bugfix in dktools.pc, Libs.private now set correctly.
+- Script itaclean.sh renamed to itaclean (due to lintian complaints).
+
+* Mon Apr 25 2016 Dirk Krause <krause.dirk@web.de> 4.3.1-0.0.1
+- Printqdc now accepts empty input lines.
+
+* Tue Apr 19 2016 Dirk Krause <krause.dirk@web.de> 4.3.0-0.0.1
+- Printqd and related programs rewritten completely.
+- Rshdown is back on a users request, ported to library version 4.
+- Print order character 'N' added to dk-ls (do not show symlink target).
+- Option -b for dk-pwgen on non-Windows systems (create binary random data).
+- New program dk-rand to generate binary random data.
+- Modifications to dk4_app_t and dk3_app_t modules: create log and tmp
+ directories only when needed.
+- Modified dk4inst.h header: Compiler constant texts for directories.
+- Module dk4dmt added, tool functions for standing daemons.
+- Modified dk4sock13 module, delete existing UNIX domain sockets.
+- Modified DkWxFrame and Dk4WxFrame, restore position when frame is shown.
+- Bugfix in dkwxwiz data files, typo corrected.
+- Bugfix in dk4dbi module, must set ulen, not size when retrieving data.
+- Retired dk3sock module, all networking programs use library version 4 now.
+
+* Fri Jan 22 2016 Dirk Krause <krause.dirk@web.de> 4.2.2-0.0.1
+- Modified dk-cat, dk-hex, dk-pwgen, dk-t2h, dk-t2l, dk-db2t:
+ No error message for SIGPIPE received.
+- Some modifications following suggestions from clang static code analysis.
+
+* Tue Jan 19 2016 Dirk Krause <krause.dirk@web.de> 4.2.1-0.0.1
+- Modifications in Makefile.in and scripts/dkmkproto.pl for SVR4 packaging.
+
+* Mon Jan 18 2016 Dirk Krause <krause.dirk@web.de> 4.2.0-0.0.1
+- Performance fix for dk-send/dk-recv: Use larger buffers.
+- Performance fix for dk-ls: Avoid unnecessary size calculations.
+- Programs dk-t2db, dk-db2t and dk-dbco to replace dkdbt.
+- Libraries dk4dbia and dk4dbi added to replace dk3dbi.
+- Bugfix in dk4loc module, set encoding even if no LANG variable available.
+
+* Mon Dec 14 2015 Dirk Krause <krause.dirk@web.de> 4.1.0-0.0.1
+- Added -s option to dk-ls, show summary at end.
+- Manpage installation avoided, when building on Debian
+ (manpage installation on Debian is done by package management).
+- New functions to retrieve and expand strings from Windows registry.
+- Changes in makefiles for Visual Studio for Desktop on Windows.
+- Bugfix in dk4user module: Must expand user profile string from registry.
+- Bugfix in DkClockFrame.wxc: Minimum size specified.
+- Bugfix in DkWxImgszFrame.wxc: Format specifier corrected.
+- Bugfix in DkWxImgszApp.cpt: Load all image handlers wxInitAllImageHandlers()
+
+* Fri Dec 04 2015 Dirk Krause <krause.dirk@web.de> 4.0.10-0.0.1
+- Man pages added, required for Debian packaging.
+- Build process on Windows can now use different library directories.
+- Bugfix in dkdbt program: No longer error messages for comment lines.
+- First release after changing Linux distribution to Debian on my laptop.
+
+* Tue Nov 10 2015 Dirk Krause <krause.dirk@web.de> 4.0.9-0.0.1
+- Bugfix in Makefile.in: Some programs were mentioned twice.
+
+* Sun Nov 08 2015 Dirk Krause <krause.dirk@web.de> 4.0.8-0.0.1
+- Number of duplicated files in source archive reduced by use of hard links.
+
+* Fri Oct 16 2015 Dirk Krause <krause.dirk@web.de> 4.0.7-0.0.1
+- Bugfix in dk4loc module: Use "en" as default language.
+- Bugfix in configure.ac: Install shared libraries for rescue systems too.
+
+* Sat Oct 10 2015 Dirk Krause <krause.dirk@web.de> 4.0.6-0.0.1
+- Added -t option to dk-sort.
+- Only one AC_OUTPUT line in Makefile.in.
+
+* Tue Oct 06 2015 Dirk Krause <krause.dirk@web.de> 4.0.5-0.0.1
+- Help text for dk-recv corrected, host and port are mandatory.
+- Compiler flags for wxcs added in Makefile.in.
+- Removed some dead assignments after static analysis.
+
+* Wed Sep 23 2015 Dirk Krause <krause.dirk@web.de> 4.0.4-0.0.1
+- Makefile.in: Use C++ compiler to drive linker if any C++ module in project.
+- Makefile.in: libdk4wx.a in the LIB_ST_GUI group, not LIB_ST_CLI.
+- dktools.pc.in: Correct variable for version number used now.
+- dk3strkv/dk-sqlsplit: S_ERROR replaced by ST_ERROR.
+- configure.ac: No -Bdynamic -dy -KPIC -D_REENTRANT for static builds.
+- configure.ac: Option --with-corrections for some Solaris systems.
+
+* Tue Aug 11 2015 Dirk Krause <krause.dirk@web.de> 4.0.3-0.0.1
+- Module dk3uc2l rewritten to use the *.t2l files.
+
+* Tue Aug 04 2015 Dirk Krause <krause.dirk@web.de> 4.0.2-0.0.1
+- Setting for tooltip flag added to dkct.
+
+* Tue Aug 04 2015 Dirk Krause <krause.dirk@web.de> 4.0.1-0.0.1
+- dkct: Special placeholders in $? format string.
+- dkct: Option -p added for portable debug output code.
+
+* Tue Aug 04 2015 Dirk Krause <krause.dirk@web.de> 4.0.0-0.0.1
+- New rewritten library modules dk4*.
+- Simplified error reporting from callee to caller via dk4_er_t structure.
+- Reduced use of runtime library on Windows systems.
+- Text stream processing functions recognize BOM at start of data.
+- Multiple dk4sock* modules instead of one large module.
+- wxdkfcs: GUI program to inspect file checksums.
+- dkt: Replaced by multiple smaller programs.
+- dkct: Cell contents for wxGrid in wx gui section.
+
+* Thu Jul 09 2015 Dirk Krause <krause.dirk@web.de> 3.18.10-0.0.1
+- dk-tape: Code simplified.
+
+* Thu Apr 02 2015 Dirk Krause <krause.dirk@web.de> 3.18.9-0.0.1
+- Modified configure script and Makefile for --enable-packaging option.
+
+* Fri Mar 13 2015 Dirk Krause <krause.dirk@web.de> 3.18.8-0.0.1
+- Modified configure script and Makefile.
+
+* Sat Feb 21 2015 Dirk Krause <krause.dirk@web.de> 3.18.7-0.0.1
+- dkct: Bugfix, doxygen allows pure @file lines.
+
+* Wed Jan 28 2015 Dirk Krause <krause.dirk@web.de> 3.18.6-0.0.1
+- Bugfix in plpdftex: smash used only for texts aligned by base line.
+
+* Thu Jan 22 2015 Dirk Krause <krause.dirk@web.de> 3.18.5-0.0.1
+- Bugfix in dkt tape: wrong number printed.
+- Bugfix in plpdftex: smash not for texts in boxes.
+- Modified pjsnmp: Added pjsnmpreadystates configuration option
+- Modified pjsnmp: Message texts modified, distinction errors/warnings.
+
+* Mon Dec 08 2014 Dirk Krause <krause.dirk@web.de> 3.18.4-0.0.1
+- Bugfix in plpdftex: sometimes invalid *.tex output.
+
+* Mon Dec 01 2014 Dirk Krause <krause.dirk@web.de> 3.18.3-0.0.1
+- Bugfix in UTF-16 encoding: Surrogate range was wrong.
+
+* Wed Nov 26 2014 Dirk Krause <krause.dirk@web.de> 3.18.2-0.0.1
+- Modified dkct: No @file line added if @file line is already present.
+- Data type dk3_c32_t changed to unsigned if unsigned is 4 bytes long.
+- Check whether password memory really was reset.
+
+* Tue Oct 21 2014 Dirk Krause <krause.dirk@web.de> 3.18.1-0.0.1
+- Bugfix in multiplication overflow detection in dk3mas/dk3mai/dk3mal modules.
+
+* Thu Oct 16 2014 Dirk Krause <krause.dirk@web.de> 3.18.0-0.0.1
+- Copyright year check in dkct.
+- API bugfix in dk3str32/dk3str16: Use correct character size now.
+- Bugfix in htmlbook for using dkChar.
+- Bugfix in dkdbt for using dkChar.
+- Splitted dk3mastr module into several modules.
+- Most uses of sscanf() and dk3sf_sscanf3() replaced by other functions.
+
+* Wed Sep 24 2014 Dirk Krause <krause.dirk@web.de> 3.17.2-0.0.1
+- Bugfix in dk3sock: WSAEWOULDBLOCK is used for connect in progress.
+
+* Fri Sep 12 2014 Dirk Krause <krause.dirk@web.de> 3.17.1-0.0.1
+- Bugfix in archive creation: Permissions are correct now.
+
+* Wed Sep 03 2014 Dirk Krause <krause.dirk@web.de> 3.17.0-0.0.1
+- Appendices k, M, G for block size added for dkt blks/ dkt ed/dkt rnd.
+- Bugfix in fig2lat: EPS/PDF/PGF output driver, corner radius.
+- Bugfix in wxbmpp dk3paper module.
+- Bugfix in wxbmpp: Fitting to a paper size.
+
+* Thu Aug 07 2014 Dirk Krause <krause.dirk@web.de> 3.16.3-0.0.1
+- Changed build process for Linux/Unix.
+
+* Tue Aug 05 2014 Dirk Krause <krause.dirk@web.de> 3.16.2-0.0.1
+- Changed build process for Linux/Unix, removed options from configure.
+
+* Tue Aug 05 2014 Dirk Krause <krause.dirk@web.de> 3.16.1-0.0.1
+- Use wxFD_OPEN instead of wxOPEN.
+- Bugfix in makefile: CLFAGS was a typo.
+
+* Mon Jul 28 2014 Dirk Krause <krause.dirk@web.de> 3.16.0-0.0.1
+- New program plpdftex added, output driver for octpgfpl.
+- Prefer sigaction() over sigset().
+- Function-like macros replaced by functions.
+- Modified overflow check for conversion from unsigned long to size_t.
+- Modified dk3ma module: Splitted into several smaller modules.
+- Functions dk3strm_double_c8_no_sci()... added.
+- Function dk3pdf_write_double() treats small numbers as 0.
+
+* Sat Jun 28 2014 Dirk Krause <krause.dirk@web.de> 3.15.0-0.0.1
+- Source code reorganized.
+
+* Thu Jun 19 2014 Dirk Krause <krause.dirk@web.de> 3.14.0-0.0.1
+- Options -S... added to dkct and wxdkct.
+- Memory usage reorganized for bit matrices.
+- Cache friendly algorithm for bit matrix expansion.
+- dktools.spec file modified to build sub-packages lib and devel.
+
+* Tue May 27 2014 Dirk Krause <krause.dirk@web.de> 3.13.0-0.0.1
+- Modified htmlbook: Line numbering for source code.
+- Modified dkt html: Line numbering for source code.
+- Added *.desktop files for GUI programs.
+
+* Wed Apr 30 2014 Dirk Krause <krause.dirk@web.de> 3.12.0-0.0.1
+- New application wxdkhtb added to view help text files.
+- Modified htmlbook: enable/disable full text search in *.chm output.
+- Installation bugfix: Forgot to install libdk3wx.so.
+- HTML files for online help now created by htmlbook.
+- API change in DkWxFrame class: Methods added.
+
+* Wed Apr 23 2014 Dirk Krause <krause.dirk@web.de> 3.11.0-0.0.1
+- htmlbook: Writing project.xml file.
+- htmlbook: New option chm full text search.
+- htmlbook: Section number optional before section title in index and pos.
+- htmlbook: Titles for links in keyword index.
+- htmlbook: Bugfix, all *.html files listed in files section.
+- htmlbook: Bugfix, added missing closing OBJECT tag.
+- htmlbook: Bugfix, copy index.hhp, index.hhc and index.hhk to destination.
+- htmlbook: Bugfix, root object now in TOC as first object.
+- printqd: Attempt to remove existing local socket before creating new one.
+- printqd: Bugfix, endless loop.
+- wxdkclock: Save changed options immediately.
+
+* Mon Mar 31 2014 Dirk Krause <krause.dirk@web.de> 3.10.0-0.0.1
+- Modified fig2lat: Fast splines for arrowheads.
+- Modified fig2lat: Configurable base line width.
+
+* Mon Mar 24 2014 Dirk Krause <krause.dirk@web.de> 3.9.0-0.0.1
+- Bugfix in bmpp/wxbmpp: Bits per component analysis rewritten.
+
+* Sun Mar 02 2014 Dirk Krause <krause.dirk@web.de> 3.8.3-0.0.1
+- Bugfix bmpp/wxbmpp: Automatic bits per component analysis disabled.
+- Modified htmlbook: New classes for table cells added to style.css file.
+
+* Thu Feb 06 2014 Dirk Krause <krause.dirk@web.de> 3.8.2-0.0.1
+- Modified htmlbook: New no-vspace option for img special command.
+- Modified htmlbook: Shortcuts for images.
+
+* Wed Jan 29 2014 Dirk Krause <krause.dirk@web.de> 3.8.1.0.0.1
+- Modified htmlbook: Set permissions for destination directory contents.
+- Modified htmlbook: Change in style.css, added top and bottom margin.
+- Bugfix in htmlbook: Crashes on filenames without suffix.
+
+* Tue Jan 21 2014 Dirk Krause <krause.dirk@web.de> 3.8.0-0.0.1
+- New application htmlbook added.
+- Bugfix in dk3enc module: Wrong range delimiter for Unicode characters.
+
+* Fri Nov 29 2013 Dirk Krause <krause.dirk@web.de> 3.7.0-0.0.1
+- Modified dkt latex: Euro currency symbol added to translation table.
+- Modified dkma: long long, unsigned long long, intmax_t, uintmax_t.
+
+* Thu Nov 14 2013 Dirk Krause <krause.dirk@web.de> 3.6.0-0.0.1
+- Modified fig2lat: New cofop option for filled open graphics paths.
+- Bugfix in fig2lat: Must encode some characters.
+- Modified dk3ma: Function and constants names changed for consistent naming.
+
+* Wed Oct 23 2013 Dirk Krause <krause.dirk@web.de> 3.5.0-0.0.1
+- Modified wxbmpp: No automatic start when running on a directory.
+
+* Tue Oct 01 2013 Dirk Krause <krause.dirk@web.de> 3.4.0-0.0.1
+- Modified dkt blocksize: Performance optimizations, use memcpy().
+- Modified dk3sock module: Handle incomplete send requests.
+- Modified dk3str module: Use existing functions if available.
+
+* Fri Sep 20 2013 Dirk Krause <krause.dirk@web.de> 3.3.3-0.0.1
+- Option -s for dkt blocksize added.
+- Modified itadmin: Increased possible length for DHCP options values.
+- Bugfix in itadmin: DHCP options for hosts are written now.
+
+* Tue Jul 30 2013 Dirk Krause <krause.dirk@web.de> 3.3.2-0.0.1
+- Modified dk3sto module: Keyword const added to some functions.
+
+* Mon Jul 29 2013 Dirk Krause <krause.dirk@web.de> 3.3.1-0.0.1
+- Bugfix in distribution and build system.
+
+* Sun Jul 28 2013 Dirk Krause <krause.dirk@web.de> 3.3.0-0.0.1
+- API change, comparison and evaluation functions operate on const * pointers.
+
+* Wed Jul 24 2013 Dirk Krause <krause.dirk@web.de> 3.2.2-0.0.1
+- More useful error message for malformed path to dkt ls on Windows
+ (paths in double quotes where backslash escapes closing double quote).
+
+* Thu Mar 20 2013 Dirk Krause <krause.dirk@web.de> 3.0.6-0.0.1
+- dkct enhanced for unknown classes.
+
+* Wed Mar 20 2013 Dirk Krause <krause.dirk@web.de> 3.0.5-0.0.1
+- Bugfix: Use AddButton method of wxStdButtonSizer, not Add.
+
+* Sun Mar 17 2013 Dirk Krause <krause.dirk@web.de> 3.0.4-0.0.1
+- The dk3sock4 module was added.
+
+* Sat Mar 16 2013 Dirk Krause <krause.dirk@web.de> 3.0.3-0.0.1
+- Online documentation updated for the -f option in dknet.
+
+* Thu Mar 14 2013 Dirk Krause <krause.dirk@web.de> 3.0.2-0.0.1
+- The dknet program is more verbose now when run as sender.
+
+* Sun Feb 03 2013 Dirk Krause <krause.dirk@web.de> 3.0.1-0.0.1
+- The dkwxwiz program was added.
+- The winprint program (for Windows) was added.
+- The wprclean program (for Windows) was added.
+- The lprngcl program (for Windows) was added.
+- Option bbts for fig2lat.
+- Bugfix in Win32 setup: The dk3paper.conf file was not installed.
+
+* Thu Jan 31 2013 Dirk Krause <krause.dirk@web.de> 3.0.0-0.0.12
+- Code for 3.0.0 release finished.
+
+* Wed Nov 02 2011 Dirk Krause <krause.dirk@web.de> 2.2.22-0.0.1
+- Bugfix in the configure script: Unnecessary call to wx-config removed.
+
+* Tue Nov 01 2011 Dirk Krause <krause.dirk@web.de> 2.2.21-0.0.1
+- The hostsadm.pl script now adds a netgroup triple containing
+ the IP address to the netgroup.ldif file.
+- The "ctrl database-cleanup" operation for prqd now removes
+ print accounts and page counts with value 0.
+
+* Sun Jun 06 2011 Dirk Krause <krause.dirk@web.de> 2.2.20-0.0.1
+- Program imgsize renamed to chimgsize to avoid name conflicts
+ with perl-Image-Size RPM.
+
+* Sun Apr 19 2011 Dirk Krause <krause.dirk@web.de> 2.2.19-0.0.1
+- Bugfix in text2htm, wrong format specification.
+
+* Sun Nov 14 2010 Dirk Krause <krause.dirk@web.de> 2.2.18-0.0.1
+- The function dkstr_w_cat() (a fallback implementation for systems without
+ the wcscat() function) was added.
+- New programs kwintool and kwindown for Windows.
+
+* Tue Oct 26 2010 Dirk Krause <krause.dirk@web.de> 2.2.17-0.0.1
+- New option ``create accounts automatically'' for prqd. By default
+ we avoid to create personal print accounts automatically to keep
+ the database small.
+- Improvements in the GUI of the PrintLimit application.
+
+* Sun Oct 24 2010 Dirk Krause <krause.dirk@web.de> 2.2.16-0.0.1
+- New Java application PrintLimit for users of LPRng/prqd to show
+ users print quota information.
+- The dklibsj.html page was improved. Tutorial and short reference added.
+
+* Wed Oct 20 2010 Dirk Krause <krause.dirk@web.de> 2.2.15-0.0.1
+- The LANG environment variable is now tested for both ".UTF-8"
+ and ".utf8" to indicate the use of UTF-8 encoding.
+
+* Wed Sep 15 2010 Dirk Krause <krause.dirk@web.de> 2.2.14-0.0.1
+- Documentation update: Notes about differences in the appearance of
+ interpolated splines in Xfig/transfig and fig2vect. Recommendations how
+ to modify the sources of Xfig and transfig.
+
+* Tue Sep 14 2010 Dirk Krause <krause.dirk@web.de> 2.2.13-0.0.1
+- Corrected typographic errors in the DKrause::Diagram documentation.
+
+* Tue Sep 13 2010 Dirk Krause <krause.dirk@web.de> 2.2.12-0.0.1
+- The *.jar files were missing in the Windows executable setup of
+ 2.2.11. Here they are back.
+
+* Tue Aug 31 2010 Dirk Krause <krause.dirk@web.de> 2.2.11-0.0.1
+- Unnecessary line end correction removed from fig2vect.
+- New Perl module DKrause::Diagram added
+
+* Tue Jul 20 2010 Dirk Krause <krause.dirk@web.de> 2.2.10-0.0.1
+- Documentation corrections.
+
+* Fri Jul 16 2010 Dirk Krause <krause.dirk@web.de> 2.2.9-0.0.1
+- Bugfix in tracecc, application group name corrected.
+
+* Mon Jul 12 2010 Dirk Krause <krause.dirk@web.de> 2.2.8-0.0.1
+- Modifications in configure script for build process on Mac.
+
+* Sat Jun 26 2010 Dirk Krause <krause.dirk@web.de> 2.2.6-0.0.1
+- Bugfix in bmeps, bits per component reduction disabled.
+- Modifications in HTML documentation due to validation results.
+- New option "doxygen comments" for genau.
+- Script "make-pkg.sh" to build SVR4 packages.
+- Doxygen comments added.
+
+* Fri Jun 18 2010 Dirk Krause <krause.dirk@web.de> 2.2.5-0.0.1
+- Modified hostsadm: UTF-8 to ISO-LATIN-1 conversion.
+- Code cleanup.
+
+* Sun Jun 13 2010 Dirk Krause <krause.dirk@web.de> 2.2.4-0.0.1
+- File dktools.spec added.
+- Start scripts for prqd, rshdown, useraud now installed to /etc/init.d.
+
+* Sat Jun 12 2010 Dirk Krause <krause.dirk@web.de> 2.2.3-0.0.1
+- DESTDIR variable added to makefile for RPM builders.
+
+* Thu Jun 03 2010 Dirk Krause <krause.dirk@web.de> 2.2.2-0.0.1
+- Bugfix for preference file location.
+
diff --git a/support/dktools/dktools.pc.in b/support/dktools/dktools.pc.in
new file mode 100644
index 0000000000..4366c90d1d
--- /dev/null
+++ b/support/dktools/dktools.pc.in
@@ -0,0 +1,12 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: dktools
+Description: Dirk Krause's tools and libraries
+Version: @VERSNO@
+Requires: zlib libpng
+Libs: -L${libdir} -ldk3fig -ldk3bmeps -ldk3bif -ldk3csrnd -ldk3dbi -ldk3net -ldk3of -ldk3c -ldk4lat -ldk4mdrnd -ldk4socka -ldk4dbia -ldk4app -ldk4sock -ldk4dbi -ldk4c -ldk4ma -ldk4maiowd -ldk4maiodd -ldk4maiowh -ldk4maiowd -ldk4maio8h -ldk4maio8d -ldk4base
+Libs.private: @LIBSPRIVATE@ -lm
+Cflags: -I${includedir} @WXCPPFLAGS@
diff --git a/support/dktools/dktools/charmap/currency-europe.t2l b/support/dktools/dktools/charmap/currency-europe.t2l
new file mode 100644
index 0000000000..a1be35dbde
--- /dev/null
+++ b/support/dktools/dktools/charmap/currency-europe.t2l
@@ -0,0 +1 @@
+20AC t=\euro{} p=eurosym
diff --git a/support/dktools/dktools/charmap/dingbats.t2l b/support/dktools/dktools/charmap/dingbats.t2l
new file mode 100644
index 0000000000..4112d73e18
--- /dev/null
+++ b/support/dktools/dktools/charmap/dingbats.t2l
@@ -0,0 +1,162 @@
+2701 t=\ding{33} p=pifont
+2702 t=\ding{34} p=pifont
+2703 t=\ding{35} p=pifont
+2704 t=\ding{36} p=pifont
+2706 t=\ding{38} p=pifont
+2707 t=\ding{39} p=pifont
+2708 t=\ding{40} p=pifont
+2709 t=\ding{41} p=pifont
+270C t=\ding{44} p=pifont
+270D t=\ding{45} p=pifont
+270E t=\ding{46} p=pifont
+270F t=\ding{47} p=pifont
+2710 t=\ding{48} p=pifont
+2711 t=\ding{49} p=pifont
+2712 t=\ding{50} p=pifont
+2713 b=\checkmark{} t=\ding{51} p=pifont
+2714 t=\ding{52} p=pifont
+2715 t=\ding{53} p=pifont
+2716 t=\ding{54} p=pifont
+2717 t=\ding{55} p=pifont
+2718 t=\ding{56} p=pifont
+2719 t=\ding{57} p=pifont
+271A t=\ding{58} p=pifont
+271B t=\ding{59} p=pifont
+271C t=\ding{60} p=pifont
+271D t=\ding{61} p=pifont
+271E t=\ding{62} p=pifont
+271F t=\ding{63} p=pifont
+2720 b=\maltese{}
+2721 t=\ding{65} p=pifont
+2722 t=\ding{66} p=pifont
+2723 t=\ding{67} p=pifont
+2724 t=\ding{68} p=pifont
+2725 t=\ding{69} p=pifont
+2726 t=\ding{70} p=pifont
+2727 t=\ding{71} p=pifont
+2729 t=\ding{73} p=pifont
+272A t=\ding{74} p=pifont
+272B t=\ding{75} p=pifont
+272C t=\ding{76} p=pifont
+272D t=\ding{77} p=pifont
+272E t=\ding{78} p=pifont
+272F t=\ding{79} p=pifont
+2730 t=\ding{80} p=pifont
+2731 t=\ding{81} p=pifont
+2732 t=\ding{82} p=pifont
+2733 t=\ding{83} p=pifont
+2734 t=\ding{84} p=pifont
+2735 t=\ding{85} p=pifont
+2736 t=\ding{86} p=pifont
+2737 t=\ding{87} p=pifont
+2738 t=\ding{88} p=pifont
+2739 t=\ding{89} p=pifont
+273A t=\ding{90} p=pifont
+273B t=\ding{91} p=pifont
+273C t=\ding{92} p=pifont
+273D t=\ding{93} p=pifont
+273E t=\ding{94} p=pifont
+273F t=\ding{95} p=pifont
+2740 t=\ding{96} p=pifont
+2741 t=\ding{97} p=pifont
+2742 t=\ding{98} p=pifont
+2743 t=\ding{99} p=pifont
+2744 t=\ding{100} p=pifont
+2745 t=\ding{101} p=pifont
+2746 t=\ding{102} p=pifont
+2747 t=\ding{103} p=pifont
+2748 t=\ding{104} p=pifont
+2749 t=\ding{105} p=pifont
+274A t=\ding{106} p=pifont
+274B t=\ding{107} p=pifont
+274C t=\ding{53] p=pifont
+274D t=\ding{109} p=pifont
+274F t=\ding{111} p=pifont
+2750 t=\ding{112} p=pifont
+2751 t=\ding{113} p=pifont
+2752 t=\ding{114} p=pifont
+2756 t=\ding{118} p=pifont
+2758 t=\ding{120} p=pifont
+2759 t=\ding{121} p=pifont
+275A t=\dint{122} p=pifont
+275B t=\ding{123} p=pifont
+275C t=\ding{124} p=pifont
+275D t=\ding{125} p=pifont
+275E t=\ding{126} p=pifont
+2761 t=\ding{261} p=pifont
+2762 t=\ding{262} p=pifont
+2763 t=\ding{263} p=pifont
+2764 t=\ding{164} p=pifont
+2765 t=\ding{165} p=pifont
+2766 t=\ding{166} p=pifont
+2767 t=\ding{167} p=pifont
+2776 t=\ding{182} p=pifont
+2777 t=\ding{183} p=pifont
+2778 t=\ding{184} p=pifont
+2779 t=\ding{185} p=pifont
+277A t=\ding{186} p=pifont
+277B t=\ding{187} p=pifont
+277C t=\ding{188} p=pifont
+277D t=\ding{189} p=pifont
+277E t=\ding{190} p=pifont
+277F t=\ding{191} p=pifont
+2780 t=\ding{192} p=pifont
+2781 t=\ding{193} p=pifont
+2782 t=\ding{194} p=pifont
+2783 t=\ding{195} p=pifont
+2784 t=\ding{196} p=pifont
+2785 t=\ding{197} p=pifont
+2786 t=\ding{198} p=pifont
+2787 t=\ding{199} p=pifont
+2788 t=\ding{200} p=pifont
+2789 t=\ding{201} p=pifont
+278A t=\ding{202} p=pifont
+278B t=\ding{203} p=pifont
+278C t=\ding{204} p=pifont
+278D t=\ding{205} p=pifont
+278E t=\ding{206} p=pifont
+278F t=\ding{207} p=pifont
+2790 t=\ding{208} p=pifont
+2791 t=\ding{209} p=pifont
+2792 t=\ding{210} p=pifont
+2793 t=\ding{211} p=pifont
+2794 t=\ding{212} p=pifont
+2798 t=\ding{216} p=pifont
+2799 t=\ding{217} p=pifont
+279A t=\ding{218} p=pifont
+279B t=\ding{219} p=pifont
+279C t=\ding{220} p=pifont
+279D t=\ding{221} p=pifont
+279E t=\ding{222} p=pifont
+279F t=\ding{223} p=pifont
+27A0 t=\ding{224} p=pifont
+27A1 t=\ding{225} p=pifont
+27A2 t=\ding{226} p=pifont
+27A3 t=\ding{227} p=pifont
+27A4 t=\ding{228} p=pifont
+27A5 t=\ding{229} p=pifont
+27A6 t=\ding{230} p=pifont
+27A7 t=\ding{231} p=pifont
+27A8 t=\ding{232} p=pifont
+27A9 t=\ding{233} p=pifont
+27AA t=\ding{234} p=pifont
+27AB t=\ding{235} p=pifont
+27AC t=\ding{236} p=pifont
+27AD t=\ding{237} p=pifont
+27AE t=\ding{238} p=pifont
+27AF t=\ding{239} p=pifont
+27B1 t=\ding{241} p=pifont
+# ##### MISSING 27B0
+27B2 t=\ding{242} p=pifont
+27B3 t=\ding{243} p=pifont
+27B4 t=\ding{244} p=pifont
+27B5 t=\ding{245} p=pifont
+27B6 t=\ding{246} p=pifont
+27B7 t=\ding{247} p=pifont
+27B8 t=\ding{248} p=pifont
+27B9 t=\ding{249} p=pifont
+27BA t=\ding{250} p=pifont
+27BB t=\ding{251} p=pifont
+27BC t=\ding{252} p=pifont
+27BD t=\ding{253} p=pifont
+27BE t=\ding{254} p=pifont
diff --git a/support/dktools/dktools/charmap/iso-latin-1.t2l b/support/dktools/dktools/charmap/iso-latin-1.t2l
new file mode 100644
index 0000000000..0150a5b289
--- /dev/null
+++ b/support/dktools/dktools/charmap/iso-latin-1.t2l
@@ -0,0 +1,187 @@
+00 t=\keystroke{NUL} p=keystroke
+01 t=\SOH{} p=ascii
+02 t=\STX{} p=ascii
+03 t=\ETX{} p=ascii
+04 t=\EOT{} p=ascii
+05 t=\ENQ{} p=ascii
+06 t=\ACK{} p=ascii
+07 t=\BEL{} p=ascii
+08 t=\BS{} p=ascii
+09 t=\HT{} p=ascii
+0A b=\\*
+0B t=\VT{} p=ascii
+0C t=\FF{} p=ascii
+0D t=\CR{} p=ascii
+0E t=\SO{} p=ascii
+0F t=\SI{} p=ascii
+10 t=\DLE{} p=ascii
+11 t=\DCa{} p=ascii
+12 t=\DCb{} p=ascii
+13 t=\DCc{} p=ascii
+14 t=\DCd{} p=ascii
+15 t=\NAK{} p=ascii
+16 t=\SYN{} p=ascii
+17 t=\ETB{} p=ascii
+18 t=\CAN{} p=ascii
+19 t=\EM{} p=ascii
+1A t=\SUB{} p=ascii
+1B t=\Esc{} p=keystroke
+1C t=\FS{} p=ascii
+1D t=\GS{} p=ascii
+1E t=\RS{} p=ascii
+1F t=\US{} p=ascii
+22 t=\textquotedbl{}
+23 b=\#
+24 b=\$
+25 b=\%
+26 b=\&
+27 t=\textquoteright{}
+2A t=\textasteriskcentered{} m=*
+3C t=\textless{} m=<
+3E t=\textgreater{} m=>
+5B t=[ m=\lbrack{}
+5C t=\textbackslash{} m=\verb|\|
+5D t=] m=\rbrack{}
+5E t=\textasciicircum{} m=\^{}
+5F b=\_
+60 t=\textasciigrave{}
+7B b=\{
+7C t=\textbar{} m=|
+7D b=\}
+7E t=\textasciitilde{} m=\~{}
+7F t=\Del{} p=keystroke
+80 t=\keystroke{CTRL:0x80} p=keystroke
+81 t=\keystroke{CTRL:0x81} p=keystroke
+82 t=\keystroke{BPH} p=keystroke
+83 t=\keystroke{NBH} p=keystroke
+84 t=\keystroke{IND} p=keystroke
+85 t=\keystroke{NEL} p=keystroke
+86 t=\keystroke{SSA} p=keystroke
+87 t=\keystroke{ESA} p=keystroke
+88 t=\keystroke{HTS} p=keystroke
+89 t=\keystroke{HTJ} p=keystroke
+8A t=\keystroke{VTS} p=keystroke
+8B t=\keystroke{PLD} p=keystroke
+8C t=\keystroke{PLU} p=keystroke
+8D t=\keystroke{RI} p=keystroke
+8E t=\keystroke{SS2] p=keystroke
+8F t=\keystroke{SS3} p=keystroke
+90 t=\keystroke{DCS} p=keystroke
+91 t=\keystroke{PU1} p=keystroke
+92 t=\keystroke{PU2} p=keystroke
+93 t=\keystroke{STS} p=keystroke
+94 t=\keystroke{CCH} p=keystroke
+95 t=\keystroke{MW} p=keystroke
+96 t=\keystroke{SPA} p=keystroke
+97 t=\keystroke{EPA} p=keystroke
+98 t=\keystroke{SOS} p=keystroke
+99 t=\keystroke{CTRL:0x99} p=keystroke
+9A t=\keystroke{SCI} p=keystroke
+9B t=\keystroke{CSI} p=keystroke
+9C t=\keystroke{ST} p=keystroke
+9D t=\keystroke{OSC} p=keystroke
+9E t=\keystroke{PM} p=keystroke
+9F t=\keystroke{APC} p=keystroke
+A0 t=\NBSP{} p=ascii
+A1 b=!' t=\textexclamdown{}
+A2 b=\textcent{} p=textcomp
+A3 b=\pounds{}
+A4 t=\textcurrency{} p=textcomp
+A5 t=\textyen{} p=textcomp
+A6 t=\textbrokenbar{} p=textcomp
+A7 b=\S{}
+A8 t=\textasciidieresis{} p=textcomp
+A9 b=\copyright{} p=textcomp
+AA t=\textordfeminine p=textcomp
+AB t=\guillemotleft{} e=!ot1
+AC t=\textlnot{} p=textcomp
+AD t=\-
+AE t=\textregistered{} p=textcomp
+AF t=\textasciimacron{} p=textcomp
+B0 t=\textdegree m={}^\circ{} p=textcomp
+B1 t=\textpm{} m=\pm{} p=textcomp
+B2 t=\texttwosuperior{} m={}^2 p=textcomp
+B3 t=\textthreesuperior{} m={}^3 p=textcomp
+B4 t=\textasciiacute{} p=textcomp
+B5 t=\textmu{} m=\mu p=textcomp
+B6 b=\P{}
+B7 t=\textperiodcentered{} m=\cdotp{}
+B8 t=\c{}
+B9 t=\textonesuperior m={}^1 p=textcomp
+BA t=\textordmasculine{} p=textcomp
+BB t=\guillemotright{} e=!ot1
+BC t=\textonequarter{} p=textcomp
+BD t=\textonehalf{} p=textcomp
+BE t=\textthreequarters{} p=textcomp
+BF t=\textquestiondown{}
+C0 b=\`{A}
+C1 b=\'{A}
+C2 b=\^{A}
+C3 b=\~{A}
+C4 b=\"{A}
+C5 b=\AA{}
+C6 b=\AE{}
+C7 b=\c{C}
+C8 b=\`{E}
+C9 b=\'{E}
+CA b=\^{E}
+CB b=\"{E}
+CC b=\`{I}
+CD b=\'{I}
+CE b=\^{I}
+CF b=\"{I}
+D0 b=\DH{} e=!ot1
+D1 b=\~{N}
+D2 b=\`{O}
+D3 b=\'{O}
+D4 b=\^{O}
+D5 b=\~{O}
+D6 b=\"{O}
+D7 t=\texttimes{} m=\times{} p=textcomp
+D8 b=\O{}
+D9 b=\`{U}
+DA b=\'{U}
+DB b=\^{U}
+DC b=\"{U}
+DD b=\'{Y}
+DE b=\TH{} e=!ot1
+DF b=\ss{}
+E0 b=\`{a}
+E1 b=\'{a}
+E2 b=\^{a}
+E3 b=\~{a}
+E4 b=\"{a}
+E5 b=\aa{}
+E6 b=\ae{}
+E7 b=\c{c}
+E8 b=\`{e}
+E9 b=\'{e}
+EA b=\^{e}
+EB b=\"{e}
+EC b=\`{i}
+ED b=\'{i}
+EE b=\^{i}
+EF b=\"{i}
+F0 b=\dh{} e=!ot1
+F1 b=\~{n}
+F2 b=\`{o}
+F3 b=\'{o}
+F4 b=\^{o}
+F5 b=\~{o}
+F6 b=\"{o}
+F7 t=\textdiv{} m=\div{} p=textcomp
+F8 b=\o{}
+F9 b=\`{u}
+FA b=\'{u}
+FB b=\^{u}
+FC b=\"{u}
+FD b=\'{y}
+FE b=\th{} e=!ot1
+FF b=\"{y}
+FB00 t=ff
+FB01 t=fi
+FB02 t=fl
+FB03 t=ffi
+FB04 t=ffl
+FB05 t=ft
+FB06 t=st
diff --git a/support/dktools/dktools/charmap/latin-extended-a.t2l b/support/dktools/dktools/charmap/latin-extended-a.t2l
new file mode 100644
index 0000000000..cd26a1a71d
--- /dev/null
+++ b/support/dktools/dktools/charmap/latin-extended-a.t2l
@@ -0,0 +1,125 @@
+0100 t=\={A}
+0101 t=\={a}
+0102 t=\u{A}
+0103 t=\u{a}
+0104 t=\k{A} e=!ot1
+0105 t=\k{a} e=!ot1
+0106 t=\'{C}
+0107 t=\'{c}
+0108 t=\^{C}
+0109 t=\^{c}
+010A t=\.{C}
+010B t=\.{c}
+010C t=\v{C}
+010D t=\v{c}
+010E t=\v{D}
+010F t=d\textquoteright{}
+0110 t=\DJ{}
+0111 t=\dj{}
+0112 t=\={E}
+0113 t=\={e}
+0114 t=\u{E}
+0115 t=\u{e}
+0116 t=\.{E}
+0117 t=\.{e}
+0118 t=\k{E} e=!ot1
+0119 t=\k{e} e=!ot1
+011A t=\v{E}
+011B t=\v{e}
+011C t=\^{G}
+011D t=\^{g}
+011E t=\u{G}
+011F t=\u{g}
+0120 t=\.{G}
+0121 t=\.{g}
+0122 t=\cb{G} p=combelow
+0123 t=\cb{g} p=combelow
+0124 t=\^{H}
+0125 t=\^{h}
+0126 t=\B{H} e=t4 p=fc
+0127 t=\B{h} e=t4 p=fc
+0128 t=\~{I}
+0129 t=\~{\i}
+012A t=\={I}
+012B t=\={\i}
+012C t=\u{I}
+012D t=\u{\i}
+012E t=\k{I} e=!ot1
+012F t=\k{i} e=!ot1
+0130 t=\.{I}
+0131 t=\i{}
+0132 t=IJ
+0133 t=ij
+0134 t=\^{J}
+0135 t=\^{\j}
+0136 t=\cb{K} p=combelow
+0137 t=\cb{k} p=combelow
+0138 t=\m{k} e=t4 p=fc
+0139 t=\´{L}
+013A t=\´{l}
+013B t=\cb{L} p=combelow
+013C t=\cb{l} p=combelow
+013D t=L\textquoteright{}
+013E t=l\textquoteright{}
+013F t=L\textbullet{}
+0140 t=l\textbullet{}
+0141 t=\L{}
+0142 t=\l{}
+0143 t=\´{N}
+0144 t=\´{n}
+0145 t=\cb{N} p=combelow
+0146 t=\cb{n} p=combelow
+0147 t=\v{N}
+0148 t=\v{n}
+0149 t=\textquoteright{}n
+014B t=\engma p=phonetic
+014C t=\={O}
+014D t=\={o}
+014E t=\u{O}
+014F t=\u{o}
+0150 t=\H{O}
+0151 t=\H{o}
+0152 t=\OE{}
+0153 t=\oe{}
+0154 t=\´{R}
+0155 t=\´{r}
+0156 t=\cb{R} p=combelow
+0157 t=\cb{r} p=combelow
+0158 t=\v{R}
+0159 t=\v{r}
+015A t=\´{S}
+015B t=\´{s}
+015C t=\^{S}
+015D t=\^{s}
+015E t=\c{S}
+015F t=\c{s}
+0160 t=\v{S}
+0161 t=\v{s}
+0162 t=\c{T}
+0163 t=\c{t}
+0164 t=\v{T}
+0165 t=t\textquoteright{}
+0168 t=\~{U}
+0169 t=\~{u}
+016A t=\={U}
+016B t=\={u}
+016C t=\u{U}
+016D t=\u{u}
+016E t=\r{U}
+016F t=\r{u}
+0170 t=\H{U}
+0171 t=\H{u}
+0172 t=\k{U} e=!ot1
+0173 t=\k{u} e=!ot1
+0174 t=\^{W}
+0175 t=\^{w}
+0176 t=\^{Y}
+0177 t=\^{y}
+0178 t=\"{Y}
+0179 t=\´{Z}
+017A t=\´{z}
+017B t=\.{Z}
+017C t=\.{z}
+017D t=\v{Z}
+017E t=\v{z}
+# Missing: 017F: latin long s
diff --git a/support/dktools/dktools/charmap/textsym.t2l b/support/dktools/dktools/charmap/textsym.t2l
new file mode 100644
index 0000000000..5d6932cfa9
--- /dev/null
+++ b/support/dktools/dktools/charmap/textsym.t2l
@@ -0,0 +1,9 @@
+2013 t=\textendash{}
+2014 t=\textemdash{}
+2020 b=\dag{}
+2021 b=\ddag{}
+2026 b=\dots{}
+2031 t=\guilsinglright{} e=!ot1
+2039 t=\guilsinglleft{} e=!ot1
+2122 t=\texttrademark{} p=textcomp
+2423 t=\textvisiblespace{}
diff --git a/support/dktools/dktools/de/bmpp.txt b/support/dktools/dktools/de/bmpp.txt
new file mode 100644
index 0000000000..46947df211
--- /dev/null
+++ b/support/dktools/dktools/de/bmpp.txt
@@ -0,0 +1,243 @@
+
+BEZEICHNUNG
+
+ bmpp - Bitmap to PS/PDF converter
+
+ÃœBERSICHT
+
+ bmpp [-l<Treiber>[.<Mode>][,<Name>[=<Wert>]...]] [<Option(en)>] <Datei(en)>
+
+BESCHREIBUNG
+
+Das Programm wandelt Bitmap-Dateien in den Formaten PNG, JPEG und TIFF nach
+PS/EPS und PDF um.
+
+Treiber:
+- ps
+ Druckdatei zur Ausgabe auf PostScript-Druckern
+- eps
+ Encapsulated PostScript (EPS), Bild kan in Dokument eingebunden werden.
+- pdf
+ Portable document format (PDF).
+- bb
+ Bounding box, Angabe zu Bildgrenzen ohne Bildinhalt.
+
+Ausgabemodi:
+- Objekt (object)
+ Datei, die in einer Textverarbeitung oder in einem Graphikprogramm in eine
+ andere Datei eingebunden wird (ein Beispiel hierfür sind Dateien, die von
+ LaTeX-Dokumenten referenziert werden).
+- Bild (image)
+ Bild, das für sich allein stehend betrachtet wird.
+- Dokument (document)
+ Bildgröße wird für Ausdruck auf ein bestimmtes Papierformat angepasst.
+
+OPTIONEN
+
+-h
+--help
+ Hilfetext zeigen.
+
+-v
+--version
+ Versionsnummer zeigen.
+
+-L
+--license-terms
+ Lizenzbedingungen zeigen.
+
+-l <Treiber>[.<Mode>]
+ Treiber und Ausgabemodus.
+ Es stehen die Treiber "ps", "eps", "pdf" und "bb" zur Verfügung
+ sowie die Ausgabemodi "object", "image" und "document".
+
+-t <Typ>
+ Eingabe-Datei-Typ ("png", "jpeg" oder "tiff"), falls die
+ Standardeingabe verarbeitet wird oder der Typ nicht aus der Endung des
+ Dateinamens ermittelt werden kann.
+
+-m
+ Make mode: unnötige Konvertierungen vermeiden, wenn Ausgabedatei
+ bereits aktuell ist. Nur beim Verarbeiten eines Verzeichnisses aktiv.
+
+-s
+ Ausgabe in Standardausgabe, nicht in Datei.
+
+-o <Name>[=<Wert>]
+ Weitere Einstellungen.
+
+NAME=WERT-PAARE
+
+Mit diesen Optionen werden weitere Einstellungen getroffen. Bei boolschen
+Einstellungen kann der Wert entfallen, das Aufzählen des Namens setzt die
+Einstellung auf aktiv.
+Folgende Namen (und Werte) stehen zur Verfügung:
+
+level=<PS-Level>
+ PS-Sprachlevel, 2 oder 3. Standard: 3.
+
+color[=<Boolean>]
+ Farbige PS/EPS-Ausgabe erlauben. Standard: An.
+ Hinweis: Wenn DCT-codierte Daten aus JPEG-Dateien direkt verarbeitet
+ werden, wird diese Einstellung ignoriert.
+
+dsc[=<Boolean>]
+ Schreiben von DSC-Kommentaren (document
+ structuring conventions) in PS- oder EPS-Ausgabe erlauben oder
+ verbieten. Standard: Aus für Objekte und Images, ein für Dokumente.
+
+draft[=<Boolean>]
+ Entwurfs-Mode aktivieren/deaktivieren, dabei wird nur eine kleine
+ Platzhalter-Graphik erstellt.
+
+predictor=<Predictor>
+ Predictor für die flate-Komprimierung, entweder "tiff",
+ "sub", "up", "average" oder "paeth". Standard: Keiner.
+
+duplex[=<Boolean>]
+ Ausgabe für zweiseitigen Ausdruck (Vorder- und Rückseite)
+ vorbereiten. Standard: Aus.
+
+tumble[=<Boolean>]
+ Zweiseitigen Ausdruck als Kalender (ein) oder Buch (aus). Standard: Aus.
+
+dct[=<Boolean>]
+ DCT-codierte Daten aus JPEG-Dateien direkt wiederverwerten.
+ Standard: Ein.
+
+bg=<Zahl>:<Zahl>:<Zahl>[:<Boolean>]
+ Hintergrundfarbe, die Zahlenwerte für Rot, Grün und Blau
+ müssen im Bereich 0...255 liegen. Der Wahrheitswert gibt an, ob der
+ hier angegebene Hintergrund immer verwendet werden soll oder nur, wenn
+ in der Eingabedatei keine Informationen zur Hintergrundfarbe enthalten
+ sind. Standard: Weiß:nein.
+
+interpolation[=<Boolean>]
+ Interpolation-Flag. Ist das Flag gesetzt, dürfen Bildbetrachter
+ versuchen, die Darstellungsqualität zu verbessern. Standard: Ein.
+
+jpeg-interpolation[=<Boolean>]
+ Interpolation-Flag, wenn DCT-codierte Daten aus JPEG-Dateien direkt
+ verwendet werden. Standard: Aus.
+
+resolution=<Auflösung>
+ Auflösung:
+ - "1:1" verwendet für jeden Bildpunkt ein Quadrat von 1 x 1 PS-Point.
+ - "chunk" verwendet Auflösungsdaten aus der Eingabedatei, falls
+ vorhanden. Andernfalls wird auf 1:1 umgeschaltet.
+ - Zahlenwert (ganzzahlig) gibt die Auflösung in dpi (Bildpunkte pro
+ Zoll) an.
+ Standard: 1:1 für Objekte, chunk für Bilder, Anpassung an eine
+ Papiergröße für Dokumente.
+
+paper=<Name>
+ Papierformat, in das die Ausgabe eingepasst werden soll.
+ Das Format muss in einer dk3paper.conf-Datei definiert sein. Es kann
+ entweder resolution=... oder paper=... benutzt werden.
+
+make[=<Boolean>]
+ Entspricht der Option -m.
+ Standard: Aus.
+
+bpc[=<Boolean>]
+ Reduktion der Farbtiefe. Standard: Ein.
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+PRÄFERENZEN
+
+/print/ps/level
+ Standard-PS-Level: 2 oder 3.
+
+BEISPIELE
+
+bmpp -l ps.document,level=2,paper=A4,duplex fax.tif
+ erstellt eine PS-Datei fax.ps, die auf einem PS-2-Drucker ausgedruckt
+ werden kann.
+
+
+bmpp -l pdf.document,paper=A4,duplex fax.tif
+ erstellt eine PDF-Datei fax.pdf.
+
+
+bmpp -l ps.object screenshot.png
+ erstellt ein PS-Objekt screenshot.ps, das mit latex/dvips verwendet
+ werden kann.
+
+
+bmpp -l pdf.object screenshot.png
+ erstellt ein PDF-Objekt screenshot.pdf, das mit pdflatex verwendet
+ werden kann.
+
+
+bmpp -l ps.image file.png
+ erstellt ein PS-Bild file.ps.
+
+
+bmpp -l pdf.image file.png
+ erstellt eine Bild-Datei file.pdf.
+
+DATEIEN
+
+dk3paper.conf
+ ist die Konfigurationsdatei für die Papiergrößen. Wird paper=...
+ verwendet, muss die Papiergröße in einer Konfigurationsdatei
+ dk3paper.conf definiert sein.
+
+EINSCHRÄNKUNGEN
+
+Das Programm bmpp nutzt zum Lesen von TIFF-Dateien die Funktion
+TIFFReadRGBAImage() aus der libtiff-Bibliothek. Damit kann bmpp nur solche
+Dateien verarbeiten, die mit dieser Funktion gelesen werden können.
+Die Dateien müssen folgenden Bedingungen genügen:
+- Die Datei muss dem "TIFF baseline v6.0 standard" entsprechen.
+- Die Anzahl Bits pro Farbkomponente darf maximal 8 sein.
+- Jedes Frame darf nicht zu groß sein, das System muss den erforderlichen
+ Hauptspeicher von 4*w*h Bytes am Stück allozieren können.
+
+TIFF bezeichnet eine Gruppe verschiedener Komprimierungs- und
+Codierungsmechanismen. Eine TIFF-Datei besteht aus einer Folge von Datensätzen.
+Jeder Datensatz enthält eine Typangabe (Tag), der die Art des Datensatzes
+angibt. In den Standards - z.B. "TIFF baseline v6.0 standard" ist eine Reihe
+von Tags definiert. Darüber hinaus verwenden verschiedene Softwarehersteller
+auch herstellerspezifische oder (noch) nicht standardisierte Tags.
+Daher ist es nicht ungewöhnlich, wenn beim Einlesen von TIFF-Bildern
+Warnungen oder Fehlermeldungen über unbekannte Tags ausgegeben werden.
+Dies ist kein Fehler in bmpp oder der tifflib-Bibliothek.
+In vielen Fällen kann das Bild dennoch gelesen werden.
+Haben Sie beim Erstellen von Bitmap-Dateien die Möglichkeit, den Bitmap-Typ
+selbst festzulegen, sollten sie besser PNG verwenden, falls möglich.
+
+AUTOR
+
+Dirk Krause
+
+GESCHICHTE
+
+Das Programm bmpp ersetzt das in früheren Versionen des dktools-Projektes
+enthaltene bmeps.
+
+LIZENZBEDINGUNGEN
+
+Mit dem Kommando
+ bmpp --license-terms
+werden die Lizenzbedingungen angezeigt.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net/bmpp.html
+ Die Homepage des Projektes "DK tools and libraries" liefert weitere
+ Informationen zu bmpp und anderen Programmen.
+
+http://gxhints.sourceforge.net
+ Die Seite "Graphics Conversion Hints" empfiehlt Programme und
+ Vorgehensweisen für die Konvertierung heute gängiger
+ Vektorgraphik-Formate.
+
+http://netpbm.sourceforge.net (insbesondere pnmtops)
+ NetPBM ist ein Toolkit für Bilder, einschließlich Konvertierung
+ zwischen zahlreichen Graphikformaten, insbesondere für
+ Bitmap-Graphiken.
+
diff --git a/support/dktools/dktools/de/dk-blks.str b/support/dktools/dktools/de/dk-blks.str
new file mode 100644
index 0000000000..7fe6453344
--- /dev/null
+++ b/support/dktools/dktools/de/dk-blks.str
@@ -0,0 +1,37 @@
+#
+# 0 Error message: Not all bytes written
+#
+Schreiboperation nur teilweise ausgeführt!
+#
+# 1 Error message: Failed to clean up buffer
+#
+Puffer konnte nicht bereinigt werden!
+#
+# 2 Error message: Block size too large!
+#
+Die Blockgröße ist zu groß!
+#
+# 3 Error message: Block size must not be 0!
+#
+Die Blockgröße muss größer als 0 sein!
+#
+# 4 Error message: Failed to set up signal handlers!
+#
+Signal-Handler konnten nicht konfiguriert werden!
+#
+# 5 Error message: Failed to restore signal handlers!
+#
+Signal-Handler konnten nicht wiederhergestellt werden!
+#
+# 6 Error message: Signal SIGPIPE received!
+#
+Signal SIGPIPE empfangen, Schreib-Operation fehlgeschlagen!
+#
+# 7 Error message: Signal SIGINT received!
+#
+Signal SIGINT empfangen, Programm-Abbruch!
+#
+# 8 9 Error message: Unexpected command line argument ... ignored!
+#
+Unerwartetes Kommandozeilen-Argument "
+" ignoriert!
diff --git a/support/dktools/dktools/de/dk-blks.txt b/support/dktools/dktools/de/dk-blks.txt
new file mode 100644
index 0000000000..efead99e3f
--- /dev/null
+++ b/support/dktools/dktools/de/dk-blks.txt
@@ -0,0 +1,44 @@
+
+BEZEICHNUNG
+
+dk-blks - Blockgröße einstellen
+
+ÃœBERSICHT
+
+dk-blks [<Optionen>]
+
+BESCHREIBUNG
+
+Das Programm liest den Inhalt der Standardeingabe und gibt ihn auf die
+Standardausgabe aus. Die Ausgabe erfolgt in Blöcken vorgegebener Größe.
+
+Hiermit können Daten aus einer Netzwerkübertragung oder aus der Ausgabe
+eines Entschlüsselungs- oder Dekompressionsprogrammes für eine Verarbeitung
+mit dem Programm "dd" aufbereitet werden.
+
+OPTIONEN
+
+-b <Größe>, --block-size=<Größe>
+ Blockgröße, Standardwert ist 4096.
+ Sie können die Nachsätze "k", "m", "g" bzw. "t" für Kilo-, Mega-,
+ Giga- bzw. Terabyte verwenden, es handelt sich hierbei um
+ Potenzen von 1024. Beispiele: "-b 4k" bzw. "-b 1m".
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+AUTOR
+
+Dirk Krause
+
+COPYRIGHT UND LIZENZBESTIMMUNGEN
+
+Führen Sie
+ dk-blks --license
+aus, um Lizenz-Informationen anzuzeigen.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/de/dk-bmm.str b/support/dktools/dktools/de/dk-bmm.str
new file mode 100644
index 0000000000..34a26f463e
--- /dev/null
+++ b/support/dktools/dktools/de/dk-bmm.str
@@ -0,0 +1,56 @@
+#
+# 0 Error: Failed to set up signal handlers!
+#
+Signal-Handler konnten nicht eingerichtet werden!
+#
+# 1 Error: Failed to restore signal handlers!
+#
+Signal-Handler konnten nicht wiederhergestellt werden!
+#
+# 2 Error: Write attempt to standard output failed!
+#
+Schreiben auf Standardausgabe schlug fehl!
+#
+# 3 Error: SIGPIPE signal received!
+#
+SIGPIPE-Signal aufgetreten!
+#
+# 4 Error: Aborted by SIGINT signal!
+#
+Abbruch durch SIGINT-Signal!
+#
+# 5 Error: Aborted by SIGTERM signal!
+#
+Abbruch durch SIGTERM-Signal!
+#
+# 6 Hint: Tape was not used in this cycle yet.
+#
+ (vorheriger Zyklus)
+#
+# 7 Text: Media number for next backup
+#
+Medien-Nummer für nächstes Backup:
+#
+# 8 ERROR: Option -r is not available for a set names file.
+#
+Die Option -r ist nicht für Sets verfügbar!
+#
+# 9 ERROR: Failed to read file, probably not a dk-bmm file!
+#
+Datei nicht eingelesen, keine Medien-Nummern-Datei!
+#
+# 10 ERROR: Exactly one file name allowed!
+#
+Es muss genau ein Dateiname angegeben werden!
+#
+# 11 Info: Cycle completed, please renew media set!
+#
+Zyklus abgeschlossen, bitte Medien-Set austauschen!
+#
+# 12
+#
+Set-Namen-Datei konnte nicht geschrieben werden!
+#
+# 13
+#
+Keine Set-Namen-Datei!
diff --git a/support/dktools/dktools/de/dk-bmm.txt b/support/dktools/dktools/de/dk-bmm.txt
new file mode 100644
index 0000000000..9a36c5373e
--- /dev/null
+++ b/support/dktools/dktools/de/dk-bmm.txt
@@ -0,0 +1,63 @@
+
+BEZEICHNUNG
+
+dk-bmm - Backup-Medien-Management
+
+ÃœBERSICHT
+
+dk-bmm [<Option(en)>] [<Datei>]
+
+BESCHREIBUNG
+
+Das Program dk-bmm führt hauptsächlich die folgenden vier Operationen aus:
+
+* Namen des aktuellen Backup-Medien-Satzes ermitteln (Option -s)
+
+* Bestätigen, dass eine Backup für den aktuellen Backup-Medien-Satz
+ erfolgreich war (Optionen -s und -c=)
+
+* Nummer des aktuellen Mediums innerhalb des Satzes ermitteln
+ (Standard-Operation, keine Option erforderlich).
+
+* Bestätigen, dass das Backup auf das aktuelle Medium erfolgreich war
+ (Option -c).
+
+OPTIONEN
+
+-s Arbeit mit Backup-Medien-Satz (ohne diese Option werden
+--set Medien-Nummern bearbeitet).
+
+-c Bestätigen, dass das letzte Backup erfolgreich war.
+--confirm
+
+-r Report über Verwendung der Medien innerhalb eines
+--report Backup-Medien-Satzes erstellen.
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+EINSCHRÄNKUNGEN
+
+Unter Windows kann eine Erweiterung von Dateinamen mit Wildcards (* oder ?)
+nur für Dateinamen bis zu einer Länge von _MAX_PATH (260) erfolgen.
+
+AUTOR
+
+Dirk Krause
+
+GESCHICHTE
+
+In Version 2.x.x hieß das Programm "tape", in Version 3.x.x war die Funktion
+in "dkt tape" verfügbar.
+
+COPYRIGHT und LIZENZBESTIMMUNGEN
+
+Führen Sie
+ dk-bmm --license
+aus, um die Lizenzbedingungen anzuzeigen.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/de/dk-cat.str b/support/dktools/dktools/de/dk-cat.str
new file mode 100644
index 0000000000..39562451aa
--- /dev/null
+++ b/support/dktools/dktools/de/dk-cat.str
@@ -0,0 +1,68 @@
+#
+# 0 1 2 Decoding error
+#
+Fehler beim Decodieren!\n\tByte:
+Noch ein Fehler beim Decodieren!
+Weitere Fehler beim Decodieren!
+#
+# 3 4 5 Encoding error
+#
+Fehler beim Codieren!\n\tByte:
+Noch ein Fehler beim Codieren!
+Weitere Fehler beim Codieren!
+#
+# 6 7 8 Processing error
+#
+Fehler beim Verarbeiten!\n\tByte:
+Noch ein Fehler beim Verarbeiten!
+Weitere Fehler beim Verarbeiten!
+#
+# 9 10 Position in line
+#
+,\n\tZeichen:
+,\n\tPosition in Zeile:
+#
+# 11 12 13 Default messages
+#
+Fehler beim Decodieren!
+Fehler beim Codieren!
+Fehler beim Verarbeiten!
+#
+# 14 End of message.
+#
+.
+#
+# 15 16 17 18 Error messages for illegal encodings
+#
+Unzulässige Eingabe-Codierung: "
+"!
+Unzulässige Ausgabe-Codierung: "
+"!
+#
+# 19
+#
+Die Breite der Zeilennummern muss größer als 0 sein!
+#
+# 20
+#
+Text konnte nicht in die Ausgabe geschrieben werden!
+#
+# 21
+#
+Numerische Konvertierung fehlgeschlagen (sollte nicht passieren, evtl. Bug)!
+#
+# 22
+#
+Signal-Handler konnten nicht eingerichtet werden!
+#
+# 23
+#
+Signal-Handler konnten nicht wiederhergestellt werden!
+#
+# 24
+#
+Signal SIGPIPE erhalten!
+#
+# 25
+#
+Signal SIGINT erhalten!
diff --git a/support/dktools/dktools/de/dk-cat.txt b/support/dktools/dktools/de/dk-cat.txt
new file mode 100644
index 0000000000..102c229271
--- /dev/null
+++ b/support/dktools/dktools/de/dk-cat.txt
@@ -0,0 +1,91 @@
+
+BEZEICHNUNG
+
+ dk-cat - Text-Dateien anzeigen
+
+ÃœBERSICHT
+
+ dk-cat [<Optionen>] [<Datei(en)>]
+
+BESCHREIBUNG
+
+Das Programm dk-cat zeigt Textdateien an. Die Dateien werden im
+Standard-Encoding des Systems ausgebeben oder in dem mit der Option
+-o angegebenen Ausgabe-Encoding.
+Es wird erwartet, dass die Eingabe im Standard-Encoding des Systems vorliegt
+oder in dem mit der Option -i angegebenen Encoding.
+Enthält die Eingabe am Beginn einen BOM (Byte Order Marker), wird die Eingabe
+im Encoding entsprechend dem BOM verarbeitet.
+
+OPTIONEN
+
+-c <boolean>, --crnl=<boolean>
+ CR/NL-Sequenzen als Zeilenwechsel ein- oder ausschalten.
+ Ohne diese Option wird der systemweite Standard benutzt (CR/NL
+ unter Windows, NL auf allen anderen Systemen).
+
+-n, --line-numbers
+ Zeilennummern vor jede ausgegebene Zeile schreiben.
+
+--line-number-width=<integer>
+ Mindest-Breite für die Zeilennummern (Standard: 5).
+
+-w, --normalize
+ Text normalisieren, dabei werden führende und abschließende Leer-
+ zeichen bzw. Leerzeichenfolgen entfernt und alle anderen Folgen von
+ Leerzeichen jeweils durch ein einzelnes Leerzeichen ersetzt.
+
+-i <string>
+ Erwartetes Eingabe-Encoding:
+ plain ASCII
+ ascii Synonym für plain,
+ ansi ANSI,
+ utf-8 UTF-8,
+ utf-16 UTF-16 in System-Bytereihenfolge,
+ utf-16le UTF-16 mit LSB (least significant byte,
+ niederwertigstes Byte) zuerst,
+ utf-16be UTF-16 mit MSB (most significant byte,
+ höchstwertiges Byte) zuerst,
+ c32 32-Bit in System-Bytereihenfolge,
+ c32le 32-Bit mit LSB zuerst,
+ c32be 32-Bit mit MSB zuerst,
+ Enthält die Eingabe am Beginn einen BOM, wird das Encoding
+ entsprechend dem BOM verwendet und die Option -i ignoriert.
+
+-o <string>
+ Ausgabe-Encoding, siehe Option -i für mögliche Encodings.
+ Wird ,bom angehangen (z.B. utf-16be,bom), wird ein BOM
+ als Beginn der Ausgabe geschrieben.
+
+-p, --pass-through
+ UTF-8 codierte Daten direkt verwenden, wenn UTF-8-Ausgabe gewünscht
+ wird und die Eingabe als UTF-8 vorliegt.
+ Ohne diese Option werden die Daten einmal decodiert und anschließend
+ wieder codiert (Test auf korrekte UTF-8-Codierung).
+
+--verbose
+ Fehlermeldung anzeigen, wenn Abbruch wegen SIGPIPE erfolgte.
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+EINSCHRÄNKUNGEN
+
+Unter Windows kann eine Erweiterung von Dateinamen mit Wildcards (* oder ?)
+nur für Dateinamen bis zu einer Länge von _MAX_PATH (260) erfolgen.
+
+AUTOR
+
+Dirk Krause
+
+COPYRIGHT UND LIZENZBESTIMMUNGEN
+
+Führen Sie
+ dk-cat --license
+aus, um Lizenz-Informationen anzuzeigen.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/de/dk-db2t.str b/support/dktools/dktools/de/dk-db2t.str
new file mode 100644
index 0000000000..3d32ba4b74
--- /dev/null
+++ b/support/dktools/dktools/de/dk-db2t.str
@@ -0,0 +1,28 @@
+#
+# 0 Error: Failed to set up signal handlers!
+#
+Signal-Handler konnten nicht eingerichtet werden!
+#
+# 1 Error: Failed to restore previous signal handlers!
+#
+Alte Signal-Handler konnten nicht wiederhergestellt werden!
+#
+# 2 Error: Failed to traverse database!
+#
+Durchsuchen der Datenbank fehlgeschlagen!
+#
+# 3 Error: At least one database name required!
+#
+Es muss mindestens eine Datenbank angegeben werden!
+#
+# 4 Error: Write attempt to closed pipe!
+#
+Versuch, in bereits geschlossene Pipe zu schreiben!
+#
+# 5 Error: Interrupted by SIGINT signal!
+#
+Abbruch wegen SIGINT-Signal!
+#
+# 6 Error: Failed to write text to standard output!
+#
+Schreiben auf Standardausgabe schlug fehl!
diff --git a/support/dktools/dktools/de/dk-db2t.txt b/support/dktools/dktools/de/dk-db2t.txt
new file mode 100644
index 0000000000..9d1f60ae7f
--- /dev/null
+++ b/support/dktools/dktools/de/dk-db2t.txt
@@ -0,0 +1,107 @@
+
+BEZEICHNUNG
+
+dk-db2t - Einfache Datenbank als Text anzeigen
+
+ÃœBERSICHT
+
+dk-db2t [<Optionen>] <Datenbank(en)>
+
+BESCHREIBUNG
+
+Das Programm gibt eine einfache Text-Datenbank in Textform auf die
+Standardausgabe aus.
+
+Eine "einfache Datenbank" ist eine Berkeley-DB-, NDBM oder In-Memory-Datenbank.
+Die Einträge bestehen aus einem Schlüssel und einem Wert. Sowohl der Schlüssel
+als auch der Wert sind eine beliebige Byte-Folge. Anhand des Schlüssels kann
+nach einem bestimmten Eintrag gesucht werden. Der Schlüssel ist eindeutig,
+d.h. es können keine zwei Einträge mit demselben Schlüssel in der Datenbank
+vorkommen.
+
+Eine "einfache Text-Datenbank" ist eine einfache Datenbank, die als
+Schlüssel und Werte ausschließlich Text enthält. Das Nullzeichen, das das
+Textende markiert, wird mit in der Datenbank abgespeichert.
+
+Datenbanken werden in der Form Typ::Dateiname angebeben, d.h. Typ
+und Dateiname werden durch zwei Doppelpunkte getrennt.
+Folgende Typangaben sind möglich:
+bdb Berkeley-DB-Datenbank
+ndbm NDBM-Datenbank
+mem In-Memory-Datenbank
+
+OPTIONEN
+
+-k <Größe>, --key-buffer-size=<Größe>
+ Puffergröße für den Schlüssel, Standard: 1024.
+
+-v <Größe>, --value-buffer-size=<Größe>
+ Puffergröße für den Wert, Standard: 1024.
+
+-R, --reset
+ Präferenz-Werte für Puffergrößen ignorieren.
+
+--help
+ Kurzen Hilfetext anzeigen.
+
+--version
+ Version und Angaben zu unterstützten Datenbank-Backends anzeigen.
+
+--license
+ Lizenzbedingungen anzeigen.
+
+--manual
+ Diesen ausführlichen Hilfetext anzeigen.
+
+--verbose
+ Fehlermeldung anzeigen, wenn Abbruch wegen SIGPIPE erfolgte.
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+BEISPIELE
+
+* Inhalt der In-Memory-Datenbank file1.dat anzeigen:
+ dk-db2t mem::file1.dat
+
+* Inhalt der Berkeley-DB-Datenbank file2.dat anzeigen:
+ dk-db2t bdb::file2.dat
+
+* Inhalt der NDBM-Datenbank file3 (bestehend aus file3.dir und file3.pag)
+ anzeigen:
+ dk-db2t ndbm::file3
+
+PRÄFERENZEN
+
+text-db.key.max-size
+ Puffergröße für den Schlüssel, falls Option -k nicht verwendet
+ wird.
+
+text-db.value.max-size
+ Puffergröße für den Wert, falls Option -v nicht verwendet wird.
+
+EINSCHRÄNKUNGEN
+
+Unter Windows wird keine Wildcard-Erweiterung für die Dateinamen vorgenommen,
+d.h. in Dateinamen können * und ? nicht verwendet werden.
+
+AUTOR
+
+Dirk Krause
+
+GESCHICHTE
+
+In früheren Versionen wurde die Funktionalität durch "dkdbt text"
+bereitgestellt.
+
+COPYRIGHT UND LIZENZBESTIMMUNGEN
+
+Führen Sie
+ dk-db2t --license
+aus, um Lizenz-Informationen anzuzeigen.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/de/dk-dbco.str b/support/dktools/dktools/de/dk-dbco.str
new file mode 100644
index 0000000000..ffdad1ce74
--- /dev/null
+++ b/support/dktools/dktools/de/dk-dbco.str
@@ -0,0 +1,32 @@
+#
+# 0 Error: Failed to set up signal handlers!
+#
+Signal-Handler konnten nicht eingerichtet werden!
+#
+# 1 Error: Failed to restore previous signal handlers!
+#
+Signal-Handler konnten nicht wiederhergestellt werden!
+#
+# 2 Error: Failed to write record!
+#
+Datensatz konnte nicht geschrieben werden!
+#
+# 3 Error: Missing source database name!
+#
+Quell-Datenbank-Name fehlt!
+#
+# 4 Error: Missing destination database name!
+#
+Ziel-Datenbank-Name fehlt!
+#
+# 5 Error: Failed to close database (final write attempt failed)!
+#
+Datenbank wurde nicht auf Datenträger synchronisiert!
+#
+# 6 Error: Source and destination database are required!
+#
+Quell- und Ziel-Datenbank-Name müssen angegeben werden!
+#
+# 7 Error: Aborted by signal!
+#
+Abbruch durch Signal!
diff --git a/support/dktools/dktools/de/dk-dbco.txt b/support/dktools/dktools/de/dk-dbco.txt
new file mode 100644
index 0000000000..f4a0048dbb
--- /dev/null
+++ b/support/dktools/dktools/de/dk-dbco.txt
@@ -0,0 +1,89 @@
+
+BEZEICHNUNG
+
+dk-dbco - Einfache Datenbanken kopieren und konvertieren
+
+ÃœBERSICHT
+
+dk-dbco [<Optionen>] Quelldatenbank Zieldatenbank
+
+BESCHREIBUNG
+
+Das Programm kopiert den Inhalt einer einfachen Datenbank in eine andere.
+Dabei erfolgt eine Konvertierung zwischen verschiedenen Datenbanktypen,
+falls erforderlich.
+
+Eine "einfache Datenbank" ist eine Berkeley-DB-, NDBM oder In-Memory-Datenbank.
+Die Einträge bestehen aus einem Schlüssel und einem Wert. Sowohl der Schlüssel
+als auch der Wert sind eine beliebige Byte-Folge. Anhand des Schlüssels kann
+nach einem bestimmten Eintrag gesucht werden. Der Schlüssel ist eindeutig,
+d.h. es können keine zwei Einträge mit demselben Schlüssel in der Datenbank
+vorkommen.
+
+Datenbanken werden in der Form Typ::Dateiname angebeben, d.h. Typ
+und Dateiname werden durch zwei Doppelpunkte getrennt.
+Folgende Typangaben sind möglich:
+bdb Berkeley-DB-Datenbank
+ndbm NDBM-Datenbank
+mem In-Memory-Datenbank
+
+OPTIONEN
+
+-a, --add
+ ändert eine bestehende Datenbank (ändert Einträge bzw. fügt
+ Einträge hinzu).
+ Ohne diese Option wird eine neue Datenbank erstellt, zuvor wird
+ eine evtl. bereits vorhandene Datenbank gelöscht.
+
+-k <Größe>, --key-buffer-size=<Größe>
+ Puffergröße für den Schlüssel, Standard: 4096.
+
+-v <Größe>, --value-buffer-size=<Größe>
+ Puffergröße für den Wert, Standard: 4096.
+
+-R, --reset
+ ignoriert Präferenzen für Schlüssel- und Wert-Größe.
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+BEISPIELE
+
+* Berkely-DB-Datenbank db1.db zu In-Memory-Datenbank db2.dat kopieren,
+ bisherigen Inhalt von db2.dat verwerfen, falls vorhanden:
+ dk-dbco bdb::db1.db mem::db2.dat
+
+* NDBM-Datenbank db3 (bestehend aus den Dateien db3.dir und db3.pag)
+ zu In-Memory-Datenbank db4.dat kopieren, dabei die in db4.dat bereits
+ vorhandenen Datensätze beibehalten, für die kein entsprechender Eintrag
+ in db3 existiert:
+ dk-dbco -a ndbm::db3 mem::db4.dat
+
+PRÄFERENZEN
+
+db.key.max-size
+ Puffergröße für den Schlüssel, falls Option -k nicht benutzt.
+
+db.value.max-size
+ Puffergröße für den Wert, falls Option -v nicht benutzt.
+
+AUTOR
+
+Dirk Krause
+
+GESCHICHTE
+
+In früheren Versionen von DK-Tools wurde diese Funktionalität von
+"dkdbt copy" bereitgestellt.
+
+COPYRIGHT UND LIZENZBESTIMMUNGEN
+
+Führen Sie
+ dk-dbco --license
+aus, um Lizenz-Informationen anzuzeigen.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/de/dk-fic.str b/support/dktools/dktools/de/dk-fic.str
new file mode 100644
index 0000000000..74b091d28b
--- /dev/null
+++ b/support/dktools/dktools/de/dk-fic.str
@@ -0,0 +1,116 @@
+#
+# 0 Error message: Failed to set up signal handlers
+#
+Signal-Handler konnten nicht eingerichtet werden!
+#
+# 1 Error message: Failed to restore signal handlers
+#
+Signal-Handler konnten nicht wiederhergestellt werden!
+#
+# 2 Test passed
+#
+OK
+#
+# 3 Test failed
+#
+VERÄNDERT
+#
+# 4 Error message: Failed to read data from file!
+#
+Lesen von Daten fehlgeschlagen!
+#
+# 5 6 Error message: Failed to convert file size to text!
+#
+Dateigröße kann nicht zu Text konvertiert werden für Datei:\n\t"
+"!
+#
+# 7 8 Error message: Failed to finish at least one message digest!
+#
+Erstellung des Message Digest fehlgeschlagen für Datei:\n\t"
+"!
+#
+# 9 10 Error message: Failed to add data to message digest!
+#
+Erstellung des Message Digest fehlgeschlagen für Datei:\n\t"
+"!
+#
+# 11 12 Error message: Failed to initialize message digest!
+#
+Initialisierung des Message Digest Context fehlgeschlagen für Datei:\n\t"
+"!
+#
+# 13 14 Error message: not a regular file!
+#
+Keine reguläre Datei:\n\t"
+"!
+#
+# 15 16 Error message: Failed to obtain file size
+#
+Dateigröße konnte nicht ermittelt werden für Datei:\n\t"
+"!
+#
+# 17 Warning: SHA-512 not supported
+#
+SHA-512-Algorithmus nicht verfügbar, Checksummen werden ignoriert.
+#
+# 18 Syntax error
+#
+Syntax-Fehler, erste Zeile muss "# dk-fic 3" oder "# dk-fic 4" sein!
+#
+# 19 20 Syntax error, data line expected:
+#
+Syntax-Fehler, erwartet wird:\n\tmd5 sha-1 ripemd-160 sha-512 size name
+Syntax-Fehler, erwartet wird:\n\tmd5 sha-1 ripemd-160 size name
+#
+# 21 22 Syntax, error, invalid file size:
+#
+Syntax-Fehler, ungültige Dateigröße: "
+"!
+#
+# 23 Error message: Failed to set up text line processing!
+#
+Text-Datenstrom-Verarbeitung konnte nicht initialisiert werden!
+#
+# 24 Error message: Missing support for a message digest!
+#
+Build-Problem: Unterstützung für mindestens einen Message Digest fehlt!
+#
+# 25 Error message: Options -q and -v are mutually exclusive!
+#
+Die Optionen -q und -v schließen sich gegenseitig aus!
+#
+# 26 27 Error message: Encoding not found!
+#
+Unzulässiges Eingabe-Encoding: "
+"!
+#
+# 28 Error message: Problems while writing output!
+#
+Schreiben von Ausgabedaten schlug fehl!
+#
+# 29 Error message: Signal SIGPIPE received!
+#
+Signal SIGPIPE empfangen!
+#
+# 30 Error message: Aborted by SIGINT signal!
+#
+Abbruch durch SIGINT-Signal!
+#
+# 31 Error message: Aborted by SIGTERM signal!
+#
+Abbruch durch SIGTERM-Signal!
+#
+# 32 33 34 Decoding/encoding/processing error
+#
+Decoding-Fehler!
+Encoding-Fehler!
+Verarbeitungs-Fehler!
+#
+# 35 36 37 38 39 40 Decoding/encoding/processing error!
+#
+Decoding-Fehler!\n\tByte:
+Encoding-Fehler!\n\tByte:
+Verarbeitungs-Fehler!\n\tByte:
+,\n\tZeichen:
+,\n\tPosition in Zeile:
+.
diff --git a/support/dktools/dktools/de/dk-fic.txt b/support/dktools/dktools/de/dk-fic.txt
new file mode 100644
index 0000000000..731d6b1889
--- /dev/null
+++ b/support/dktools/dktools/de/dk-fic.txt
@@ -0,0 +1,95 @@
+
+BEZEICHNUNG
+
+dk-fic - File integrity checker
+
+ÃœBERSICHT
+
+dk-fic [<Option(en)>] [<Datei(en)>]
+
+BESCHREIBUNG
+
+Das Programm kann eine Prüfsummenliste erzeugen oder verifizieren,
+ob die in einer Prüfsummenliste aufgeführten Dateien unverändert sind.
+Die Prüfsummenliste enthält die Prüfsummen mittels der Algorithmen
+MD5, SHA-1, RIPEMP-160 und SHA-512 sowie Dateigröße und Dateinamen.
+Wurde beim Erstellen von dk-fic keine Unterstützung für den SHA-512-Algorithmus
+gefunden, so entfällt die SHA-512-Prüfsumme.
+Die Prüfsummen sind ASCII-85 codiert, nicht wie sonst üblich ASCII-Hex.
+Beim Erstellen einer Prüfsummenliste können als Kommandozeilenargumente
+Dateilisten angegeben werden (Dateien, die ihrerseits eine Liste mit
+Dateinamen enthalten). Werden keine Dateien als Kommandozeilenargumente
+angegeben, wird die Dateiliste von der Standardeingabe gelesen.
+Beim Verifizieren von Prüfsummen können Dateien mit Prüfsummenlisten als
+Kommandozeilenargumente angegeben werden. Ohne Kommandozeilenargumente
+wird die Prüfsummenliste von der Standardeingabe gelesen.
+
+
+OPTIONEN
+
+-c
+--check
+ Prüfsummenliste(n) verifizieren.
+ Ohne diese Option werden Prüfsummenlisten erstellt.
+
+-v
+--verbose
+ Meldungen auch für erfolgreich verifizierte Dateien schreiben.
+ Ohne diese Option werden nur Meldungen für fehlgeschlagene
+ Tests ausgegeben.
+
+-q
+--quiet
+ Keine Meldungen, weder für erfolgreiche noch für
+ fehlgeschlagene Tests.
+ Die Optionen -v und -q schließen sich gegenseitig aus.
+
+-l <size>
+--line-size=<size>
+ Puffergröße für Eingabezeilen.
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+PRÄFERENZEN
+
+line.size
+ Zeilenpuffer-Größe, falls die Option -l nicht benutzt wurde.
+
+BEISPIELE
+
+Erzeugung einer Prüfsummenliste unter Windows:
+ dk-ls -r -tf -pn <directory> | dk-fic > checklist.txt
+
+Erzeugung einer Prüfsummenliste auf Nicht-Windows-Systemen:
+ find <directory> -type f | dk-fic > checklist.txt
+
+Verifizierung einer Prüfsummenliste:
+ dk-fic -c < checklist.txt
+
+Beim Erzeugen einer Prüfsummenliste müssen Sie darauf achten, dass die
+Datei mit der Prüfsummenliste nicht selbst mit in die Prüfsummenliste
+aufgenommen wird.
+
+EINSCHRÄNKUNGEN
+
+Unter Windows kann eine Erweiterung von Dateinamen mit Wildcards (* oder ?)
+nur für Dateinamen bis zu einer Länge von _MAX_PATH (260) erfolgen.
+
+AUTOR
+
+Dirk Krause
+
+GESCHICHTE
+
+COPYRIGHT UND LIZENZBESTIMMUNGEN
+
+Führen Sie
+ dk-fic --license
+aus, um Lizenz-Informationen anzuzeigen.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/de/dk-hex.str b/support/dktools/dktools/de/dk-hex.str
new file mode 100644
index 0000000000..04f963fcee
--- /dev/null
+++ b/support/dktools/dktools/de/dk-hex.str
@@ -0,0 +1,24 @@
+#
+# 0 Error: Failed to set up signal handlers!
+#
+Signal-Handler konnten nicht eingerichtet werden!
+#
+# 1 Error: Failed to restore signal handlers!
+#
+Signal-Handler konnten nicht wiederhergestellt werden!
+#
+# 2 Error: Signal SIGPIPE received!
+#
+Signal SIGPIPE empfangen!
+#
+# 3 Error: Aborted by SIGINT signal!
+#
+Abbruch durch SIGINT-Signal!
+#
+# 4 Error: Aborted by SIGTERM signal!
+#
+Abbruch durch SIGTERM-Signal!
+#
+# 5 Error: Write attempts to standard output failed!
+#
+Schreibversuch auf Standardausgabe fehlgeschlagen!
diff --git a/support/dktools/dktools/de/dk-hex.txt b/support/dktools/dktools/de/dk-hex.txt
new file mode 100644
index 0000000000..5394a7eae9
--- /dev/null
+++ b/support/dktools/dktools/de/dk-hex.txt
@@ -0,0 +1,50 @@
+
+BEZEICHNUNG
+
+dk-hex - Datei hexadezimal oder oktal anzeigen
+
+ÃœBERSICHT
+
+dk-hex [<Option(en)>] [<Datei(en)>]
+
+BESCHREIBUNG
+
+Das Program dk-hex zeigt den Inhalt der angegebenen Dateien (bzw. der
+Standareingabe, falls keine Dateien angegeben wurden) hexadezimal oder
+oktal an.
+
+OPTIONEN
+
+-o Oktal-Darstellung.
+--octal
+
+-a Adressen mit anzeigen.
+--addresses
+
+-t Druckbare Zeichen mit anzeigen.
+--text
+
+--verbose Fehlermeldung anzeigen, wenn Abbruch wegen SIGPIPE erfolgte.
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+EINSCHRÄNKUNGEN
+
+Unter Windows kann eine Erweiterung von Dateinamen mit Wildcards (* oder ?)
+nur für Dateinamen bis zu einer Länge von _MAX_PATH (260) erfolgen.
+
+AUTOR
+
+Dirk Krause
+COPYRIGHT UND LIZENZBESTIMMUNGEN
+
+Führen Sie
+ dk-hex --license
+aus, um Lizenz-Informationen anzuzeigen.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/de/dk-ls.str b/support/dktools/dktools/de/dk-ls.str
new file mode 100644
index 0000000000..07c2ec92c3
--- /dev/null
+++ b/support/dktools/dktools/de/dk-ls.str
@@ -0,0 +1,93 @@
+#
+# 0 Error message: Failed to set up signal handlers!
+#
+Signal-Handler konnten nicht eingerichtet werden!
+#
+# 1 Error message: Failed to restore previous signal handlers!
+#
+Signal-Handler konnten nicht wiederhergestellt werden!
+#
+# 2 Text "OVERFLOW" to show instead of the size
+#
+ÃœBERLAUF
+#
+# 3 4 5 Failed to retrieve file size information.
+#
+Dateigröße für symbolischen Link nicht ermittelbar:\n\t"
+Dateigröße nicht ermittelbar:\n\t"
+"!\n\tInformation nicht verfügbar!
+#
+# 6 Path grows too long
+#
+Beim Verzeichnis-Durchsuchen entsteht ein zu langer Pfad!
+#
+# 7 8 9 Failed to obtain timestamp!
+#
+Zeitstempel für symbolischen Link nicht ermittelbar:\n\t"
+Zeitstempel nicht ermittelbar:\n\t"
+"!\nInformation nicht verfügbar!
+#
+# 10
+#
+Dateityp und Attribute konnten nicht ermittelt werden (Bug)!
+#
+# 11
+#
+Ungültiger Text in Ausgabe-Spezifikation!
+#
+# 12 13 Failed to find target for symbolic link!
+#
+Ziel für symbolischen Link nicht ermittelbar:\n\t"
+"!
+#
+# 14 15 Failed to find unique file identifier
+#
+Datei-Identifier nicht ermittelbar:\n\t"
+"!
+#
+# 16 17 18 File names too long in summary.
+#
+Dateinamen zu lang für Wildcard-Auflösung:\n\t"
+",\n\t"
+"!
+#
+# 19 Message digest type not supported!
+#
+Message-Digest-Typ wird nicht unterstützt!
+#
+# 20 21 Message digest type not supported!
+#
+Message-Digest-Typ wird nicht unterstützt: "
+"!
+#
+# 22 23 Not a message digest type name!
+#
+Ungültiger Name für Message-Digest-Typ: "
+"!
+#
+# 24 25 Invalid encoding for message digest!
+#
+Ungültige Codierung für Message-Digest: "
+"!
+#
+# 26 Error message: Failed to init digest ctx
+#
+Message-Digest-Context konnte nicht initialisiert werden (lib)!
+#
+# 27 Error message: Failed to init message digest ctx
+#
+Message-Digest-Context konnte nicht initialisiert werden!
+#
+# 28 Error message: Failed to add bytes to ctx
+#
+Daten konnten nicht zu Message-Digest hinzugefügt werden!
+#
+# 29 Error message: Failed to finish message digest
+#
+Message-Digest konnte nicht ermittelt werden!
+#
+# 30, 31, 32
+#
+\# Anzahl Verzeichnisse:
+\# Anzahl Dateien:
+\# Gesamtgröße in Bytes:
diff --git a/support/dktools/dktools/de/dk-ls.txt b/support/dktools/dktools/de/dk-ls.txt
new file mode 100644
index 0000000000..f499eca3c3
--- /dev/null
+++ b/support/dktools/dktools/de/dk-ls.txt
@@ -0,0 +1,288 @@
+
+BEZEICHNUNG
+
+ dk-ls - Dateien auflisten
+
+ÃœBERSICHT
+
+ dk-ls [<Optionen>] [<Datei(en)>]
+
+BESCHREIBUNG
+
+Das Programm dk-ls zeigt Informationen über Dateien an.
+
+OPTIONEN
+
+-r
+--recursive
+ Rekursives Listing, d.h. auch Listing von Unterverzeichnissen.
+
+-f
+--stay-on-filesystem
+ Aktuelles Filesystem nicht verlassen.
+
+-p <String>
+--print-order=<String>
+ Ausgabereihenfolge. Der String besteht aus Kennbuchstaben,
+ welche Informationen in welcher Reihenfolge auszugeben sind:
+ n Name
+ N Name, aber Symlink-Ziel nicht anzeigen
+ s Größe
+ t Typ
+ p Zugriffsrechte (auf Windows-Systemen: Dateiattribute)
+ c Erzeugungszeitpunkt
+ m Zeitpunkt der letzten Änderung
+ a Zeitpunkt des letzten Zugriffs
+ l Link-Anzahl
+ u UID des Eigentümers (nicht auf Windows-Systemen)
+ g GID der Eigentümer-Gruppe (nicht auf Windows-Systemen)
+ d Geräte-Nummer (auf Windows-Systemen: Volume-Nummer)
+ i Inode-Nummer (auf Windows-Systemen: Datei-Index-Nummer)
+ r Relative Geräte-Nummer für Spezial-Dateien
+ w Windows-Reparse-Tag (nur auf Windows-Systemen)
+ x Message-Digest (Prüfsumme)
+ Standardeinstellung ist "mtpn" auf Nicht-Windows-Systemen,
+ "mtn" auf Windows-Systemen.
+ Falls die Präferenz "print.order" gesetzt ist, legt diese die
+ Standardeinstellung fest.
+
+-t <String>
+--types=<String>
+ Dateitypen, für die Informationen ausgegeben werden sollen:
+ d Verzeichnisse
+ f Alle anderen Einträge (die keine Verzeichnisse sind).
+
+-s
+--summary
+ Am Ende eine Zusammenfassung ausgeben (Anzahl angezeigter Verzeichnisse
+ und Dateien, Größe in Bytes).
+
+-m <String>
+--message-digest=<String>
+ Message-Digest-Typ und dessen Text-Codierung, getrennt durch einen
+ Punkt.
+ Der Digest-Typ kann "md5", "sha-1", "sha-224",
+ "sha-256", "sha-384", "sha-512" oder "ripemd-160" sein.
+ Als Text-Codierung kann "hex" (ASCII-Hex-Umwandlung) oder
+ "a85" (ASCII-85-Umwandlung) verwendet werden.
+ Standardeinstellung ist "sha-1.hex", außer wenn die Präferenz
+ "message.digest" gesetzt ist.
+
+-R
+--reset
+ Präferenzen für Ausgabereihenfolge und Message-Digest-Typ ignorieren.
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+DIAGNOSE-AUSGABEN
+
+Falls für eine Datei die Geräte-Nummer, Volume-Nummer, Inode-Nummer,
+Datei-Index-Nummer nicht ermittelt werden kann, wird eine Folge von
+Fragezeichen ausgegeben.
+
+Kann die Link-Anzahl, die UID des Eigentümers oder die GID der
+Eigentümer-Gruppe nicht ermittelt werden, wird ein Fragezeichen ausgegeben.
+
+Kann die Datei nicht gelesen werden oder aus anderen Gründen kein
+Message-Digest gebildet werden (z.B. wenn es sich nicht um eine reguläre
+Datei handelt), wird eine Folge von 'x'-Buchstaben ausgegeben.
+
+TYP-AUSGABE AUF NICHT-WINDOWS-SYSTEMEN
+
+Die Ausgabe besteht aus zwei Stellen:
+
+* Link-Indikator, hierbei steht 'l' für einen symbolischen Link mit einem
+ Ziel innerhalb desselben Filesystems, 'L' für einen weiten Link (d.h.
+ das Ziel befindet sich in einem anderen Filesystem) und '!' für einen
+ toten Link (d.h. das Ziel des Links existiert nicht).
+ Falls es sich nicht um einen symbolischen Link handelt, wird dies durch
+ '-' kenntlich gemacht.
+
+* Datei-Typ:
+ d Verzeichnis
+ - Reguläre Datei
+ p Pipe (FIFO),
+ c Spezial-Datei für zeichenorientiertes Gerät
+ b Spezial-Datei für blockorientiertes Gerät
+ s Socket
+ C Spezial-Datei für gemultiplextes zeichenorientiertes Gerät
+ B Spezial-Datei für gemultiplextes blockorientiertes Gerät
+ D Name-Service-Door
+ e Event-Port
+ o Xenix Spezial-Datei
+ n Xenix Semaphor
+ m Xenix gemeinsam genutzte Daten
+ v VXFS-komprimierte Datei
+ n Netzwerk-Spezial-Datei
+ w Whiteout,
+ a ACL-Schatten-Eintrag
+
+BERECHTIGUNGEN AUF NICHT-WINDOWS-SYSTEMEN
+
+Die Ausgabe besteht aus 3 Gruppen: Berechtigungen für Eigentümer,
+Eigentümer-Gruppe und alle anderen Benutzer.
+Jede Gruppe besteht aus 3 Zeichen, die Lese-Recht ('r' oder '-'),
+Schreib-Recht ('w' oder '-') und Ausführungs-Recht ('x' oder '-') angeben.
+
+Ist das SUID-Bit gesetzt (d.h. beim Ausführen einer Datei hat der
+Prozess die effektive Berechtigung des Datei-Eigentümers), wird
+das Ausführungs-Recht des Eigentümers mit 's' anstelle von 'x' bzw.
+mit 'S' anstelle von '-' angezeigt.
+
+Ist das GSID-Bit gesetzt, wird das Ausführungsrecht der Eigentümer-Gruppe
+mit 's' 's' anstelle von 'x' bzw. mit 'S' anstelle von '-' angezeigt.
+
+Ist das Flag für eingeschränktes Löschen bzw. Sticky-Bit gesetzt,
+wird das Ausführungsrecht aller anderen Nutzer mit 't' anstelle von 'x'
+bzw. 'T' anstelle von '-' angezeigt.
+
+TYP-AUSGABE AUF WINDOWS-SYSTEMEN
+
+Die Ausgabe besteht aus 2 Stellen:
+
+* Indikator für Reparse-Point-Tag:
+ - Kein Reparse-Point
+ m Mount-Point
+ l Symbolischer Link
+ w WIM-Image
+ s SIS-Reparse-Point
+ n NFS-Reparse-Point
+ c CSV-Reparse-Point
+ d DFS-Reparse-Point
+ f DFSR-Reparse-Point
+ u Deduplizierungs-Reparse-Point
+ h HSM-Reparse-Point
+ 2 HSM2-Reparse-Point
+ r Anderer Reparse-Point
+
+* Datei-Typ:
+ d Verzeichnis (Directory)
+ - Reguläre Datei
+ b Gerät
+
+ATTRIBUT-AUSGABE AUF WINDOWS-SYSTEMEN
+
+Die Ausgabe besteht aus 10 Zeichen:
+
+* Read-Only-Attribut (Datei ist schreibgeschützt, d.h. nur lesbar):
+ R Schreibschutz aktiv
+ - nicht aktiv
+
+* System-Attribut (Systemdatei)
+ S Systemdatei
+ - keine Systemdatei
+
+* Hidden-Attribut (versteckte Datei)
+ H versteckt
+ - nicht versteckt
+
+* Not-Indexed-Attribut (Datei von Suchindex ausgenommen)
+ I Attribut gesetzt
+ - nicht gesetzt
+
+* Compressed-Attribut (komprimierte Datei)
+ C komprimiert
+ - nicht komprimiert
+
+* Encrypted-Attribut (verschlüsselte Datei)
+ E verschlüsselt
+ - nicht verschlüsselt
+
+* Offline-Attribut (ausgelagert auf externen Datenträger)
+ O offline
+ - nicht offline
+
+* Sparse-Attribut
+ P Attribut gesetzt
+ - nicht gesetzt
+
+* Temporary-Attribut (temporäre Datei)
+ T temporär
+ - nicht temporär
+
+* Virtual-Attribut (virtuelle Datei)
+ V virtuell
+ - nicht virtuell
+
+PRÄFERENZEN
+
+print.order
+ Standard-Ausgabereihenfolge, falls die Option -p nicht benutzt wurde.
+
+message.digest
+ Standard-Message-Digest-Typ und Text-Codierung, falls die
+ Option -m nicht benutzt wurde.
+
+EINSCHRÄNKUNGEN
+
+Unter Windows kann eine Erweiterung von Dateinamen mit Wildcards (* oder ?)
+nur für Dateinamen bis zu einer Länge von _MAX_PATH (260) erfolgen.
+
+Die Konzepte für Benutzermanagement und Zugriffsrechte auf Dateien
+unterscheiden sich signifikant zwischen Windows-Systemen einerseits
+und Linux/Unix-Systemen andererseits.
+Auf Windows-Systemen werden daher die Buchstaben 'u' und 'g' in der
+Ausgabereihenfolge ignoriert.
+
+Auf Windows-Systemen stehen verschiedene Funktionen zur Verfügung, um
+Informationen über Dateien zu erhalten. Diese liefern unterschiedlich
+detaillierte Angaben. Falls der aktuelle Prozess nur eingeschränkte
+Zugriffsrechte auf eine Datei hat (z.B. auf die Datei C:\Pagefile.sys),
+kann es vorkommen, dass gar keine bzw. nur ein Teil der gewünschten
+Informationen verfügbar ist.
+In derartigen Fällen werden Fragezeichen bzw. Fragezeichen-Sequenzen
+anstelle der gewünschten Informationen ausgegeben.
+
+Auf Nicht-Windows-Systemen gibt es keine Windows-Reparse-Points und
+somit auch keine Windows-Reparse-Tags, der Buchstabe 'w' in der
+Ausgabereihenfolge wird hier ignoriert.
+
+DATEIBEZEICHNUNGN IN ANFÃœHRUNGSZEICHEN UNTER WINDOWS
+
+Auf Windows-Systemen wird der Backslash für verschiedene Zwecke benutzt, u.a.:
+* als Trennzeichen zwischen Komponenten eines Pfadnamens und
+* für Backslash-Escape-Sequenzen in Strings.
+Anführungszeichen (") werden benutzt, um Text mit Leerzeichen zusammenzufassen.
+Dabei wird allerdings auch die Verarbeitung von Backslash-Escape-Sequenzen
+aktiviert.
+
+Eingabe in cmd.exe-Shell An ein Programm übergebenes Argument
+ C: C:
+ "C:" C:
+ C:\ C:\
+ "C:\" C:"
+ C:\\ C:\\
+ "C:\\" C:\
+
+Im vierten Beispiel wollen wir das Wurzelverzeichnis eines Laufwerkes
+angeben, eingeschlossen in Anführungszeichen. Unglücklicherweise wird
+in Strings die Folge von Backslash und Anführungszeichen als
+Backslash-Escape-Sequenz für die Eingabe eines Anführungszeichens
+als Bestandteil des Strings benutzt (nur ein Anführungszeichen würde den
+String beenden). Nach Verarbeitung der Backslash-Escape-Sequenz wird
+ein Anführungszeichen in den String eingebaut, der als Argument an das
+Programm übergeben wird.
+Wenn Sie also
+ dk-ls "C:\"
+eintippen, erhält dk-ls den Text C:" als Argument.
+Bei der Angabe von Dateinamen in Anführungszeichen sollten Sie für jeden
+gewünschten Backslash zwei Backslashes schreiben, hier wäre also
+ dk-ls "C:\\"
+richtig.
+
+AUTOR
+
+Dirk Krause
+
+COPYRIGHT UND LIZENZBESTIMMUNGEN
+
+Führen Sie
+ dk-ls --license
+aus, um Lizenz-Informationen anzuzeigen.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/de/dk-pwd.str b/support/dktools/dktools/de/dk-pwd.str
new file mode 100644
index 0000000000..4f67be14c6
--- /dev/null
+++ b/support/dktools/dktools/de/dk-pwd.str
@@ -0,0 +1,2 @@
+Aktuelles Verzeichnis konnte nicht ermittelt werden!
+
diff --git a/support/dktools/dktools/de/dk-pwd.txt b/support/dktools/dktools/de/dk-pwd.txt
new file mode 100644
index 0000000000..d288d5eb05
--- /dev/null
+++ b/support/dktools/dktools/de/dk-pwd.txt
@@ -0,0 +1,40 @@
+
+BEZEICHNUNG
+
+dk-pwd - Print working directory
+
+ÃœBERSICHT
+
+dk-pwd [<Option(en)>]
+
+BESCHREIBUNG
+
+Das Programm gibt den Namen des aktuellen Verzeichnisses auf die
+Standardausgabe aus.
+
+OPTIONEN
+
+-l Nur letzten Teil des Verzeichnisnamens ausgeben.
+
+-b Backslashes (unter Windows) durch Slashes ersetzen.
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+AUTOR
+
+Dirk Krause
+
+GESCHICHTE
+
+COPYRIGHT UND LIZENZBESTIMMUNGEN
+
+Führen Sie
+ dk-pwd --license
+aus, um Lizenz-Informationen anzuzeigen.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/de/dk-pwgen.str b/support/dktools/dktools/de/dk-pwgen.str
new file mode 100644
index 0000000000..2e6f83542a
--- /dev/null
+++ b/support/dktools/dktools/de/dk-pwgen.str
@@ -0,0 +1,110 @@
+#
+# 0 Error: OpenSSL PRNG not available!
+#
+Der OpenSSL-Zufallsgenerator ist nicht verfügbar!
+#
+# 1 Error: Failed to set up signal handlers!
+#
+Signal-Handler konnten nicht eingerichtet werden!
+#
+# 2 Error: Failed to restore signal handlers!
+#
+Signal-Handler konnten nicht wiederhergestellt werden!
+#
+# 3 Error: Numeric overflow while reading a size number!
+#
+Zahlenbereichsüberlauf beim Lesen einer Größenangabe!
+#
+# 4 5 Error: Not a size specification: "..."!
+#
+Keine Größenangabe: "
+"!
+#
+# 6 7 Error: Failed to retrieve size from text: "..."!
+#
+Keine Größenangabe in Text gefunden: "
+"!
+#
+# 8 Error: Options -h, -x, -X, and -p are mutually exclusive!
+#
+Die Optionen -h, -x, -X und -p schließen einander aus!
+#
+# 9 10 11 Error: Option -u ignored for this output type!
+#
+Option -u wird für diesen Ausgabe-Typ ignoriert!
+Option -d wird für diesen Ausgabe-Typ ignoriert!
+Option -s wird für diesen Ausgabe-Typ ignoriert!
+#
+# 12 Error: Illegal range combination for -l, -u, -d, -s!
+#
+Bereichsangaben für -l, -u, -d, -s passen nicht zueinander!
+#
+# 13 Error: Numeric overflow in password length calculation!
+#
+Zahlenbereichsüberlauf in Passwortlängen-Berechnung!
+#
+# 14 Error: Failed to obtain random data from cryptographic context!
+#
+Keine Zufallsdaten aus kryptographischen Kontext erhalten!
+#
+# 15 Error: Failed to acquire cryptographic context!
+#
+Kryptographischer Kontext konnte nicht angelegt werden!
+#
+# 16 Error: Failed to open /dev/random and /dev/urandom devices!
+#
+Weder /dev/random noch /dev/urandom nutzbar!
+#
+# 17 Error: Failed to obtain random data!
+#
+Gewinnung von Zufallsdaten fehlgeschlagen!
+#
+# 18 Error: Failed to seed OpenSSL PRNG!
+#
+Zufallsgenerator konnte nicht initialisiert werden!
+#
+# 19 20 21 Error: Aborted by SIGTERM signal!
+#
+Abbruch durch SIGTERM-Signal!
+Abbruch durch SIGINT-Signal!
+Abbruch durch SIGPIPE-Signal!
+#
+# 22 Error: Write attempt to standard output failed!
+#
+Schreiben auf Standardausgabe schlug fehl!
+#
+# 23 Debug: Seeding PRNG using OpenSSL builtin functions.
+#
+Initialisiere PRNG mittels OpenSSL-Funktionen.
+#
+# 24 Debug: Seeding PRNG from EGD socket.
+#
+Initialisiere PRNG von EGD-Socket.
+#
+# 25 Debug: Seeding PRNG from Windows cryptographic context.
+#
+Initialisiere PRNG von Windows-Kryptographie-Kontext.
+#
+# 26 Debug: Seeding PRNG from screen contents.
+#
+Initialisiere PRNG von Bildschirm-Inhalt.
+#
+# 27 Debug: Seeding PRNG from /dev/random or /dev/urandom device.
+#
+Initialisiere PRNG von /dev/random oder /dev/urandom.
+#
+# 28 Debug: Seeding PRNG from EGD socket specified by preference.
+#
+Initialisiere PRNG von EGD-Socket entsprechend Preferences.
+#
+# 29 ERROR: Options -b, -h, -x, -X, and -p are mutually exclusive!
+#
+Die Optionen -b, -h, -x, -X und -p schließen einander aus!
+#
+# 30 ERROR: Failed to reset used memory!
+#
+Der benutzte Hauptspeicher wurde nicht zurückgesetzt!
+#
+# 31 ERROR: The -b option is not supported on Windows!
+#
+Die Option -b ist unter Windows nicht verfügbar!
diff --git a/support/dktools/dktools/de/dk-pwgen.txt b/support/dktools/dktools/de/dk-pwgen.txt
new file mode 100644
index 0000000000..8ee348d2c7
--- /dev/null
+++ b/support/dktools/dktools/de/dk-pwgen.txt
@@ -0,0 +1,127 @@
+
+BEZEICHNUNG
+
+dk-pwgen - Passwörter, PINs und hexadecimale Keys generieren
+
+ÃœBERSICHT
+
+dk-pwgen [<Option(en)>]
+
+BESCHREIBUNG
+
+Das Programm dk-pwgen erzeugt Passwörter, PIN-Nummern oder hexadezimale
+Keys (z.B. für WLAN).
+Folgende Ausgabetypen sind möglich:
+
+* Normales Benutzer-Passwort
+ Dies ist der Standardausgabetyp. Geben Sie einen Bereich (oder einen
+ einzelnen Wert) für die Passwort-Länge an, sowie für die Anzahlen
+ an Großbuchstaben, Zahlen und Sonderzeichen.
+ Die minimale Passwort-Länge muss größer oder gleich der Summe der
+ Maximalwerte für Großbuchstaben, Zahlen und Sonderzeichen sein.
+
+* Hartes Passwort
+ Mit der Option -h wird auf die Bildung eines harten Passwortes umgeschalten.
+ Sie können hier nur die Länge angeben. Alle Zeichen werden aus dem gesamten
+ Bereich 0x00 ('!') bis 0x7A ('z') gewählt.
+
+* Zufällige Binärdaten
+ Mit der Option -b wird ein Block zufälliger Binärdaten erzeugt, die Größe
+ des Blocks kann angegeben werden.
+ Nicht verfügbar auf Windows-Systemen, dort kann das Programm dk-rand
+ verwendet werden.
+
+* PIN-Nummer
+ Mit der Option -p wird eine PIN-Nummer erzeugt, die Länge kann angegeben
+ werden.
+
+* Hexadezimaler Key
+ Mit den Optionen -x bzw. -X wird ein hexadezimaler Key mit einer vorgegebenen
+ Stellenzahl erzeugt. Mit -x werden Kleinbuchstaben für 'a' bis 'f' benutzt,
+ mit -X Großbuchstaben 'A' bis 'F'.
+
+OPTIONEN
+
+-h Hartes Passworte anstelle eines normalen
+--hard Benutzer-Passwortes erzeugen.
+
+-b Binäre Zufallsdaten anstelle von Passwörtern, Pins oder
+--binary Keys erzeugen. Nicht verfügbar unter Windows, dort gibt
+ es das Programm dk-rand.
+
+-x Hexadezimalen Key mit Kleinbuchstaben 'a' ... 'f'
+--hex erzeugen.
+
+-X Hexadezimalen Key mit Großbuchstaben 'A' ... 'F'
+--Hex erzeugen.
+
+-p PIN-Nummer erzeugen.
+--pin
+
+-l <Bereich> Passwort-Länge.
+--length=<Bereich> Ein Bereich wird durch zwei Zahlen angegeben, die
+ durch ein Minuszeichen getrennt sind, z.B. "6-8".
+
+-u <Bereich> Anzahl der Großbuchstaben in normalen
+--upper-case=<Bereich> Benutzer-Passwörtern.
+
+-d <Bereich> Anzahl der Ziffern in normalen Benutzer-Passwörtern.
+--digits=<Bereich>
+
+-s <Bereich> Anzahl der Sonderzeichen in normalen
+--special=<Bereich> Benutzer-Passwörtern.
+
+-n Newline-Ausgabe unterdrücken.
+--no-newline
+
+--verbose Fehlermeldung anzeigen, wenn Abbruch wegen SIGPIPE
+ erfolgte.
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+BEISPIELE
+
+Um ein normales Benutzer-Passwort mit einer Länge von 8 bis 10 Zeichen
+zu erzeugen mit 1 bis 3 Großbuchstaben, 1 bis 2 Ziffern und 1 bis 2
+Sonderzeichen:
+
+dk-pwgen -l 8-10 -u 1-3 -d 1-2 -s 1-2
+
+
+Um ein hartes Passwort mit einer Länge von 8 bis 10 Zeichen zu erzeugen:
+
+dk-pwgen -h -l 8-10
+
+
+Um eine PIN-Nummer mit 6 Stellen zu erzeugen:
+
+dk-pwgen -p -l 6
+
+
+Um einen hexadezimalen Key für WLAN-Verschlüsselung mit 64 Stellen zu erzeugen:
+
+dk-pwgen -x -l 64
+
+
+AUTOR
+
+Dirk Krause
+
+COPYRIGHT UND LIZENZBESTIMMUNGEN
+
+Führen Sie
+ dk-pwgen --license
+aus, um Lizenz-Informationen anzuzeigen.
+
+This product includes software developed by the OpenSSL Project for use in
+the OpenSSL Toolkit (http://www.openssl.org/).
+This product includes cryptographic software written by
+Eric Young (eay@cryptsoft.com).
+This product includes software written by Tim Hudson (tjh@cryptsoft.com).
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/de/dk-recv.str b/support/dktools/dktools/de/dk-recv.str
new file mode 100644
index 0000000000..1a5ab2f63a
--- /dev/null
+++ b/support/dktools/dktools/de/dk-recv.str
@@ -0,0 +1,35 @@
+#
+# 0 1 Error: Failed to set up / restore signal handlers!
+#
+Signal-Handler konnten nicht eingerichtet werden!
+Signal-Handler konnten nicht wiederhergestellt werden!
+#
+# 2 File name "stdin" for error message
+#
+Standardeingabe
+#
+# 3 Error: Failed to close file!
+#
+Schließen der Datei fehlgeschlagen!
+#
+# 4 Error: Timeout too large!
+#
+Timeout-Wert zu hoch!
+#
+# 5 Error: Timeout must not be negative!
+#
+Timeout darf nicht negativ sein!
+#
+# 6 Error: Timeout value not found!
+#
+Timeout-Wert nicht gefunden!
+#
+# 7 Error: Wrong number of arguments!
+#
+Fehlerhafte Argumente-Anzahl!\n\tHost Port [Dateiname]
+#
+# 8 9 10 Error: Interrupted by ... signal!
+#
+Abbruch durch INT-Signal!
+Abbruch durch TERM-Signal!
+Abbruch durch PIPE-Signal!
diff --git a/support/dktools/dktools/de/dk-recv.txt b/support/dktools/dktools/de/dk-recv.txt
new file mode 100644
index 0000000000..491f0e5087
--- /dev/null
+++ b/support/dktools/dktools/de/dk-recv.txt
@@ -0,0 +1,67 @@
+
+BEZEICHNUNG
+
+dk-recv - Daten von dk-send empfangen
+
+ÃœBERSICHT
+
+dk-recv [<Option(en)>] <Host> <Port> [<Zieldatei>]
+
+BESCHREIBUNG
+
+Das Programm stellt eine TCP-Verbindung zum angegebenen Host und Port
+her und empfängt über diese Verbindung Daten. Die Daten in die angegebene
+lokale Zieldatei geschrieben bzw. auf die Standardausgabe.
+
+OPTIONEN
+
+-t Aufforderung an den dk-send-Prozess, mit
+--transmission dem Senden der Daten zu beginnen.
+
+-l <Port> Lokale Portnummer, die verwendet werden soll.
+--local-port=<Port>
+
+-c <Timeout> Timeout für die Verbindungsherstellung,
+--connect-timeout=<Timeout> Angabe als ganze Zahl oder Gleitkommazahl.
+
+--help Kurzen Hilfebildschirm anzeigen.
+
+--manual Manual-Text anzeigen.
+
+--version Versionsnummer anzeigen.
+
+--license Lizenzbestimmungen anzeigen.
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+BEISPIELE
+
+* Daten empfangen und auf Festplatte (Partition) speichern:
+ dk-recv 192.0.2.103 9876 | dk-blks -b 4k | dd of=/dev/sda bs=4096
+
+EINSCHRÄNKUNGEN
+
+Unter Windows kann eine Erweiterung von Dateinamen mit Wildcards (* oder ?)
+nur für Dateinamen bis zu einer Länge von _MAX_PATH (260) erfolgen.
+
+AUTOR
+
+Dirk Krause
+
+GESCHICHTE
+
+In Version 3.x.x war die Funktionalität von dk-recv in "dknet -r"
+verfügbar.
+
+COPYRIGHT UND LIZENZBESTIMMUNGEN
+
+Führen Sie
+ dk-recv --license
+aus, um Lizenz-Informationen anzuzeigen.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/de/dk-send.str b/support/dktools/dktools/de/dk-send.str
new file mode 100644
index 0000000000..c52b405cf3
--- /dev/null
+++ b/support/dktools/dktools/de/dk-send.str
@@ -0,0 +1,71 @@
+#
+# 0 Error: Failed to set up signal handlers!
+#
+Signal-Handler konnten nicht eingerichtet werden!
+#
+# 1 Error: Failed to restore signal handlers!
+#
+Signal-Handler konnten nicht wiederhergestellt werden!
+#
+# 2 Name of input file just processed (default).
+#
+Standardeingabe
+#
+# 3 Progress: Accepting incoming connection requests.
+#
+Warte auf eingehende Verbindungsanfragen.
+#
+# 4 Error: Problem with peer address length!
+#
+Unzulässige Adresslänge!
+#
+# 5 Progress: Connected ...
+#
+Verbunden:
+#
+# 6 Debug: Rejected ...
+#
+Abgelehnt:
+#
+# 7 Progress: Starting data transfer.
+#
+Datentransfer beginnt.
+#
+# 8 Progress: Finished data transfer.
+#
+Datentransfer beendet.
+#
+# 9 ERROR: Disconnected ...
+#
+Verbindung vorzeitig abgebrochen:
+#
+# 10 11 ERROR: Invalid number of clients ...!
+#
+Unzulässige Client-Anzahl "
+"!
+#
+# 12 ERROR: Wrong number of command line arguments!
+#
+Falsche Anzahl Kommandozeilen-Argumente!
+#
+# 13 ERROR: Aborted by INT signal!
+#
+Abbruch durch INT-Signal!
+#
+# 14 ERROR: Aborted by TERM signal!
+#
+Abbruch durch TERM-Signal!
+#
+# 15 Debug: Not a dk-send client ...
+#
+Kein dk-send-Client:
+#
+# 16 17 18
+#
+Timeout-Wert zu groß!
+Timeout darf nicht negativ sein!
+Timeout-Wert nicht gefunden!
+#
+# 19
+#
+Abbruch, alle Verbindungen zu Empfängern wurden getrennt!
diff --git a/support/dktools/dktools/de/dk-send.txt b/support/dktools/dktools/de/dk-send.txt
new file mode 100644
index 0000000000..ca30c55704
--- /dev/null
+++ b/support/dktools/dktools/de/dk-send.txt
@@ -0,0 +1,79 @@
+
+BEZEICHNUNG
+
+dk-send - Daten an einen oder mehrere Empfänger (dk-recv-Prozesse) senden
+
+ÃœBERSICHT
+
+dk-send [<Option(en)>] <Port> [<Quelldatei>]
+
+BESCHREIBUNG
+
+Das Programm wartet auf eingehende Verbindungsanfragen und nimmt die
+Verbindungen an.
+Der Inhalt der Quelldatei (bzw. der Standardeingabe) wird über alle
+Verbindungen gesendet.
+
+OPTIONEN
+
+-n <Anzahl> Anzahl der Clients bzw. "unlimited"
+--number-of-clients=<Anzahl> für unbegrenzte Anzahl (letzter Client
+ muss Option -t verwenden).
+
+-a <Client(s)> Erlaubte Client-Adressen, durch Kommata
+--allow=<Client(s)> getrennt.
+ Jede erlaubte Client-Adresse besteht aus
+ einer IP-Adresse und optional einer durch
+ Schrägstrich abgetrennten Netzmaske.
+ Die Netzmaske kann als IP-Adresse oder
+ Bitanzahl angegeben werden.
+
+-l Nur auf lokalen Interfaces auf eingehende
+--local-only Verbindungen warten.
+
+-b <Anzahl> Anzahl der bei Bedarf in der Wartschlange
+--backlog=<Anzahl> zwischenzuspeichernden Verbindungsanfragen.
+
+-c <Timeout> Timeout für den Leseversuch nach Herstellen
+--connect-timeout=<Timeout> einer Verbindung, Angabe in Sekunden.
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+BEISPIELE
+
+* Daten einer kompletten Festplatte (Partition) senden
+ dd if=/dev/sda bs=4096 | dk-send 9876
+
+* ... an 3 Clients
+ dd if=/dev/sda bs=4096 | dk-send -n 3 9876
+
+* ... die nur aus Netz 192.0.2.0/255.255.255.0 kommen dürfen
+ dd if=/dev/sda bs=4096 | dk-send -n 3 -a 192.0.2.0/255.255.255.0 9876
+ oder
+ dd if=/dev/sda bs=4096 | dk-send -n 3 -a 192.0.2.0/24 9876
+
+EINSCHRÄNKUNGEN
+
+Unter Windows kann eine Erweiterung von Dateinamen mit Wildcards (* oder ?)
+nur für Dateinamen bis zu einer Länge von _MAX_PATH (260) erfolgen.
+
+AUTOR
+
+Dirk Krause
+
+GESCHICHTE
+
+In Version 3.x.x war die Funktionalität in "dknet -s" verfügbar.
+
+COPYRIGHT UND LIZENZBESTIMMUNGEN
+
+Führen Sie
+ dk-send --license
+aus, um Lizenz-Informationen anzuzeigen.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/de/dk-sort.str b/support/dktools/dktools/de/dk-sort.str
new file mode 100644
index 0000000000..a6a46d1282
--- /dev/null
+++ b/support/dktools/dktools/de/dk-sort.str
@@ -0,0 +1,36 @@
+#
+# 0 Error message: Failed to set up signal handlers!
+#
+Signal-Handler konnten nicht eingerichtet werden!
+#
+# 1 Error message: Failed to restore previous signal handlers!
+#
+Signal-Handler konnten nicht wiederhergestellt werden!
+#
+# 2 3 4 Error messages for encoding/decoding/processing errors
+#
+Fehler beim Codieren!
+Fehler beim Decodieren!
+Fehler beim Verarbeiten!
+#
+# 5 6 7 8 9 10 Error messages with detailed position
+#
+Fehler beim Codieren!\n\tByte:
+Fehler beim Decodieren!\n\tByte:
+Fehler beim Verarbeiten!\n\tByte:
+,\n\tZeichen:
+,\n\tPosition in Zeile:
+.
+#
+# 11 Options -u, -x, -f mutually exclusive!
+#
+Die Optionen -u, -x and -f schließen sich gegenseitig aus!
+#
+# 12 13 Error: Illegal input encoding!
+#
+Unzulässige Eingabe-Codierung: "
+"!
+#
+# 14 Error: Failed to initialize text stream processing!
+#
+Text-Datenstrom-Verarbeitung konnte nicht initialisiert werden!
diff --git a/support/dktools/dktools/de/dk-sort.txt b/support/dktools/dktools/de/dk-sort.txt
new file mode 100644
index 0000000000..2f2e5b4f44
--- /dev/null
+++ b/support/dktools/dktools/de/dk-sort.txt
@@ -0,0 +1,112 @@
+
+BEZEICHNUNG
+
+dk-sort - Text zeilenweise sortieren
+
+ÃœBERSICHT
+
+dk-sort [<Option(en)>] [<Datei(en)>]
+
+BESCHREIBUNG
+
+Das Programm dk-sort liest die Standardeingabe bzw. die angegebenen
+Dateien ein und gibt die Textzeilen in sortierter Reihenfolge auf die
+Standardausgabe aus.
+
+OPTIONEN
+
+-i <String>
+--input-encoding=<String>
+ Erwartetes Text-Encoding für die Eingabedaten an.
+ Ein Byte-Order-Marker (BOM) am Beginn der Eingabe überschreibt
+ das Encoding.
+
+-c
+--case-insensitive
+ Textvergleiche ohne Unterscheidung von Groß- und Kleinschreibung.
+
+-b
+--ignore-leading-blanks
+ Führende Leerzeichen entfernen.
+
+-w
+--normalize
+ Textzeilen normalisieren. Dabei werden führende und abschließende
+ Leerzeichenfolgen entfernt, alle anderen Leerzeichenfolgen
+ werden durch ein einzelnes Leerzeichen ersetzt.
+
+-e
+--suppress-empty-lines
+ Ausgabe von leeren Zeilen (Zeilen ohne Text) unterdrücken.
+
+-n
+--number
+ Textzeilen anhand eines Ganzzahl-Wertes am Zeilenanfang vergleichen.
+
+-u
+--unsigned
+ Textzeilen anhand eines vorzeichenlosen Ganzzahlwertes am Zeilenanfang
+ vergleichen.
+
+-x
+--hex
+ Textzeilen anhand eines Hexadezimal-Ganzzahlwertes am Zeilenanfang
+ vergleichen.
+
+-f
+--float
+ Textzeilen anhand eines Gleitkommawertes (C-Datentyp double) am
+ Zeilenanfang vergleichen.
+
+-v
+--value-lines-first
+ Zeilen mit Wert (für -n, -u, -x und -f) vor Zeilen ohne den
+ geforderten Wert schreiben.
+ Standardmäßig werden die Zeilen ohne den geforderten Wert zuerst
+ ausgegeben.
+
+-m
+--merge-equal-lines
+ Folge gleicher Zeilen auf eine Zeile reduzieren.
+
+-r
+--reverse
+ Umgekehrte Sortier-Reihenfolge.
+
+-l <Größe>
+--line-size=<Größe>
+ Größe des Zeilenpuffers für die Eingabezeilen.
+ Standard und Minimum ist 1024.
+
+-R
+--reset
+ Präferenz für die Größe des Zeilenpuffers ignorieren.
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+PRÄFERENZEN
+
+line.size
+ Größe des Zeilenpuffers, falls die Option -l nicht benutzt wurde.
+
+EINSCHRÄNKUNGEN
+
+Unter Windows kann eine Erweiterung von Dateinamen mit Wildcards (* oder ?)
+nur für Dateinamen bis zu einer Länge von _MAX_PATH (260) erfolgen.
+
+AUTOR
+
+Dirk Krause
+
+COPYRIGHT UND LIZENZBESTIMMUNGEN
+
+Führen Sie
+ dk-sort --license
+aus, um Lizenz-Informationen anzuzeigen.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/de/dk-sqlsplit.txt b/support/dktools/dktools/de/dk-sqlsplit.txt
new file mode 100644
index 0000000000..a6f72941f8
--- /dev/null
+++ b/support/dktools/dktools/de/dk-sqlsplit.txt
@@ -0,0 +1,45 @@
+
+BEZEICHNUNG
+
+ dk-sqlsplit - Ãœberlange Zeilen in SQL-Dateien splitten
+
+ÃœBERSICHT
+
+ dk-sqlsplit [<Datei(en)>]
+
+BESCHREIBUNG
+
+Das Programm splittet überlange Zeilen in SQL-Daten (wie sie z.B. von
+mysqldump erzeugt werden) an Datensatz-Grenzen.
+
+Die Grenze zwischen zwei Datensätzen wird erkannt, wenn außerhalb von
+Strings und Kommentaren auf ")," eine öffnende Klammer folgt.
+Strings können in einfache, doppelte oder rückwärts zeigende
+Anführungszeichen eingschlossen sein.
+
+Es werden entweder die angegebenen Dateien oder die Standardeingabe
+verarbeitet. Die Ausgabe erfolgt auf die Standardausgabe.
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+EINSCHRÄNKUNGEN
+
+Unter Windows kann eine Erweiterung von Dateinamen mit Wildcards (* oder ?)
+nur für Dateinamen bis zu einer Länge von _MAX_PATH (260) erfolgen.
+
+AUTOR
+
+Dirk Krause
+
+COPYRIGHT UND LIZENZBESTIMMUNGEN
+
+Führen Sie
+ dk-sqlsplit --license
+aus, um Lizenz-Informationen anzuzeigen.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/de/dk-t2db.str b/support/dktools/dktools/de/dk-t2db.str
new file mode 100644
index 0000000000..16d42fa8de
--- /dev/null
+++ b/support/dktools/dktools/de/dk-t2db.str
@@ -0,0 +1,76 @@
+#
+# 0 Error: Failed to set up signal handlers!
+#
+Signal-Handler konnten nicht eingerichtet werden!
+#
+# 1 Error: Failed to restore previous signal handlers!
+#
+Signal-Handler konnten nicht wiederhergestellt werden!
+#
+# 2 Default file name to be used for standard input.
+#
+<Standardeingabe>
+#
+# 3 4 5 Error: Failed to set database entry "key"="value"!
+#
+Datensatz konnte nicht erstellt werden:\n"
+"="
+"!
+#
+# 6 7 Error: Failed to delete database entry "key"!
+#
+Datensatz konnte nicht gelöscht werden:\n"
+"!
+#
+# 8 9 10 11 12 13
+#
+Decodierung fehlgeschlagen!
+Codierung fehlgeschlagen!
+Verarbeitung fehlgeschlagen!
+Weitere Decodierungs-Fehler!
+Weitere Codierungs-Fehler!
+Weitere Verarbeitungs-Fehler!
+#
+# 14 15 16 17 18 19
+#
+Decodierung fehlgeschlagen!\n\tByte:
+Codierung fehlgeschlagen!\n\tByte:
+Verarbeitung fehlgeschlagen!\n\tByte:
+,\n\tZeichen:
+,\n\tPosition in Zeile:
+.
+#
+# 20 ERROR: Failed to read from file!
+#
+Datei konnte nicht gelesen werden!
+#
+# 21 ERROR: Failed to set up text stream processor!
+#
+Text-Stream-Processing konnte nicht eingerichtet werden!
+#
+# 22 23 ERROR: Path too long for pattern "..."!
+#
+Pfad zu lang für Muster\n"
+"!
+#
+# 24 25 ERROR: No such file "..."!
+#
+Keine solche Datei:\n"
+"!
+#
+# 26 ERROR: Failed to close database!
+#
+Fehler beim Schließen (Schreiben) der Datenbank!
+#
+# 27 ERROR: Database name is required!
+#
+Datenbank muss angegeben werden!
+#
+# 28 29 ERROR: Illegal text encoding "..."!
+#
+Unzulässige Text-Codierung: "
+"!
+#
+# 30 ERROR: Aborted by signal
+#
+Abbruch durch Signal!
diff --git a/support/dktools/dktools/de/dk-t2db.txt b/support/dktools/dktools/de/dk-t2db.txt
new file mode 100644
index 0000000000..af22883fc5
--- /dev/null
+++ b/support/dktools/dktools/de/dk-t2db.txt
@@ -0,0 +1,124 @@
+
+BEZEICHNUNG
+
+dk-t2db - Konverter Text zu Datenbank
+
+ÃœBERSICHT
+
+dk-t2db [<Optionen>] [<Dateien>] <Datenbank>
+
+BESCHREIBUNG
+
+Das Programm konvertiert Text-Dateien (bzw. Text aus der Standardeingabe)
+in eine einfache Text-Datenbank.
+
+Eine "einfache Datenbank" ist eine Berkeley-DB-, NDBM oder In-Memory-Datenbank.
+Die Einträge bestehen aus einem Schlüssel und einem Wert. Sowohl der Schlüssel
+als auch der Wert sind eine beliebige Byte-Folge. Anhand des Schlüssels kann
+nach einem bestimmten Eintrag gesucht werden. Der Schlüssel ist eindeutig,
+d.h. es können keine zwei Einträge mit demselben Schlüssel in der Datenbank
+vorkommen.
+
+Eine "einfache Text-Datenbank" ist eine einfache Datenbank, die als
+Schlüssel und Werte ausschließlich Text enthält. Das Nullzeichen, das das
+Textende markiert, wird mit in der Datenbank abgespeichert.
+
+Datenbanken werden in der Form Typ::Dateiname angebeben, d.h. Typ
+und Dateiname werden durch zwei Doppelpunkte getrennt.
+Folgende Typangaben sind möglich:
+bdb Berkeley-DB-Datenbank
+ndbm NDBM-Datenbank
+mem In-Memory-Datenbank
+
+OPTIONEN
+
+-a, --add
+ ändert eine bestehende Datenbank (ändert Einträge bzw. fügt
+ hinzu).
+ Ohne diese Option wird eine neue Datenbank erstellt, zuvor wird
+ eine evtl. bereits vorhandene Datenbank gelöscht.
+
+-R, --reset
+ ignoriert Präferenzen für Zeilen-, Schlüssel- und Wert-Größe.
+
+-l <Größe>, --line-size=<Größe>
+ Größe des Zeilenpuffers (Anzahl Zeichen), Standard: 1024.
+
+-k <Größe>, --key-buffer-size=<Größe>
+ Größe des Schlüsselpuffers (Anzahl Zeichen), Standard: 512.
+
+-v <Größe>, --value-buffer-size=<Größe>
+ Größe des Wertpuffers (Anzahl Zeichen), Standard: 512.
+
+-i <String>, --input-encoding=<String>
+ Erwartetes Text-Encoding. Das hier angegebene Encoding wird
+ überschrieben, wenn am Text-Beginn ein Byte-Order-Marker (BOM)
+ gefunden wird.
+
+-c <String>, --comment=<String>
+ Optionale Angabe eines Kommentarzeichens. Alle Zeilen, die mit
+ dem Kommentarzeichen als erstes Nicht-Leerzeichen beginnen,
+ werden ignoriert.
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+BEISPIELE
+
+* Standardeingabe verarbeiten, in-memory-Datenbankdatei db.dat anlegen:
+ dk-t2db -c "#" mem::db.dat
+
+* Textdatei db.in verarbeiten, Berkeley-DB-Datenbankdatei bdb.dat anlegen:
+ dk-t2db -c "#" db.in bdb::bdb.dat
+
+* Textdatei db.in verarbeiten, NDBM-Datenbank ndbm.dat ändern:
+ dk-t2db -a -c "#" db.in ndbm::ndbm.dat
+
+PRÄFERENZEN
+
+line.size Puffergröße für Eingabezeilen
+
+text-db.key.max-size Puffergröße für den Schlüssel
+
+text-db.value.max-size Puffergröße für den Wert
+
+
+DATEIEN
+
+Der Eingabetext wird zeilenweise verarbeitet, jede Textzeile ergibt einen
+Datensatz.
+Das erste Wort am Zeilenanfang (die erste Folge von Nicht-Leerzeichen)
+ist der Schlüssel. Durch Leerzeichen bzw. eine Leerzeichenfolge wird
+der Wert abgetrennt.
+Der Schlüssel kann keine Leerzeichen enthalten, der Wert darf Leerzeichen
+enthalten.
+Enthält eine Zeile nur einen Schlüssel, aber keinen Wert, wird der entsprechende
+Datensatz aus der Datenbank gelöscht, falls vorhanden.
+
+EINSCHRÄNKUNGEN
+
+Unter Windows kann eine Erweiterung von Dateinamen mit Wildcards (* oder ?)
+nur für Dateinamen bis zu einer Länge von _MAX_PATH (260) erfolgen.
+
+Für die Datenbank ist die Verwendung von Wildcards nicht möglich.
+
+AUTOR
+
+Dirk Krause
+
+GESCHICHTE
+
+In früheren Versionen wurde die Funktionalität durch "dkdbt make"
+bereitgestellt.
+
+COPYRIGHT UND LIZENZBESTIMMUNGEN
+
+Führen Sie
+ dk-t2db --license
+aus, um Lizenz-Informationen anzuzeigen.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/de/dk-t2h.str b/support/dktools/dktools/de/dk-t2h.str
new file mode 100644
index 0000000000..a95c2eb9d9
--- /dev/null
+++ b/support/dktools/dktools/de/dk-t2h.str
@@ -0,0 +1,66 @@
+#
+# 0 Error: Failed to set up signal handlers!
+#
+Signal-Handler konnten nicht eingerichtet werden!
+#
+# 1 Error: Failed to restore signal handlers!
+#
+Signal-Handler konnten nicht wiederhergestellt werden!
+#
+# 2 3 Error: Illegal encoding!
+#
+Unzulässiges Encoding: "
+"!
+#
+# 4 Error: Conversion from number to text failed, probably bug!
+#
+Konvertierung einer Zahl nach Text schlug fehl, evtl. Bug!
+#
+# 5 Error: Failed to decode string from UTF-16!
+#
+UTF-16-Text konnte nicht decodiert werden!
+#
+# 6 Error: Failed to decode string from ANSI!
+#
+ANSI-Text konnte nicht decodiert werden!
+#
+# 7 Error: Failed to decode string from UTF-8!
+#
+UTF-8-Text konnte nicht decodiert werden!
+#
+# 8 Error: Too many input lines, line number overflow!
+#
+Zeilennummern-Ãœberlauf (zu viele Eingabezeilen)!
+#
+# 9 Error: No command line arguments specified!
+#
+Keine Kommandozeilenargumente angegeben!
+#
+# 10 11 12 13 Errors.
+#
+Abbruch durch SIGINT-Signal!
+Abbruch durch SIGTERM-Signal!
+Abbruch durch SIGPIPE-Signal!
+Schreiben auf Standardausgabe schlug fehl!
+#
+# 14
+#
+Option -t wird ignoriert, nur wirksam gemeinsam mit -f!
+#
+# 15 ... 20 Error messages
+#
+Decodierung fehlgeschlagen!\n\tByte:
+Codierungng fehlgeschlagen!\n\tByte:
+Verarbeitung fehlgeschlagen!\n\tByte:
+,\n\tZeichen:
+,\n\tPosition in Zeile:
+.
+#
+# 21 ... 26 Error messages
+#
+Decodierung fehlgeschlagen!
+Codierung fehlgeschlagen!
+Verarbeitung fehlgeschlagen!
+Weitere Decodierungs-Fehler!
+Weitere Codierungs-Fehler!
+Weitere Verarbeitungs-Fehler!
diff --git a/support/dktools/dktools/de/dk-t2h.txt b/support/dktools/dktools/de/dk-t2h.txt
new file mode 100644
index 0000000000..071d43052c
--- /dev/null
+++ b/support/dktools/dktools/de/dk-t2h.txt
@@ -0,0 +1,63 @@
+
+BEZEICHNUNG
+
+dk-t2h - Konverter von Text nach HTML
+
+ÃœBERSICHT
+
+dk-t2h [<Option(en)>] [<Datei(en)>]
+
+BESCHREIBUNG
+
+Das Programm wandelt Text nach HTML, entweder die angegebenen Dateien
+oder die Standardeingabe. Alternativ kann mit der Option -e auch Text
+konvertiert werden, der als Kommandozeilen-Argument angegeben wurde.
+
+OPTIONEN
+
+-i <String> Eingabe-Encoding, eines von:
+--input-encoding=<String> "ascii" (auch für ISO-LATIN-1),
+ "ansi", "utf-8",
+ "utf-16", "utf-16-le", "utf-16-be",
+ "c32", "c32-le" oder "c32-be".
+
+-l Alle Zeilen einschließen in
+--code-lines "<code title="001">...</code>".
+
+-e Text von Kommandozeile umwandeln.
+--echo
+
+-f Vollständige HTML-Datei erzeugen, nicht nur
+--full ein Fragment.
+ Die Optionen -e und -f schließen sich
+ gegenseitig aus.
+
+-t <String> Titel für HTML-Datei, wenn vollständige
+--title=<String> HTML-Datei erzeugt wird.
+
+--verbose Fehlermeldung anzeigen, wenn Abbruch wegen
+ SIGPIPE erfolgte.
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+EINSCHRÄNKUNGEN
+
+Unter Windows kann eine Erweiterung von Dateinamen mit Wildcards (* oder ?)
+nur für Dateinamen bis zu einer Länge von _MAX_PATH (260) erfolgen.
+
+AUTOR
+
+Dirk Krause
+
+COPYRIGHT UND LIZENZBESTIMMUNGEN
+
+Führen Sie
+ dk-t2h --license
+aus, um Lizenz-Inforomationen anzuzeigen.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/de/dk-t2l.str b/support/dktools/dktools/de/dk-t2l.str
new file mode 100644
index 0000000000..d7634fe0fa
--- /dev/null
+++ b/support/dktools/dktools/de/dk-t2l.str
@@ -0,0 +1,71 @@
+#
+# 0 Error: Failed to set up signal handlers!
+#
+Signal-Handler konnten nicht eingerichtet werden!
+#
+# 1 Error: Failed to restore signal handlers!
+#
+Signal-Handler konnten nicht wiederhergestellt werden!
+#
+# 2 3 Error: Illegal input encoding name: "..."!
+#
+Unzulässiger Name für Eingabe-Encoding: "
+"!
+#
+# 4 5 Temporarily unused.
+#
+Keine Hexadezimal-Zahl: "
+"!
+#
+# 6 7 8 Error: No data found for character 0x...!
+#
+Keine LaTeX-Sequenz für Zeichen 0x
+ gefunden!
+Keine LaTeX-Sequenz für zeichen gefunden!
+#
+# 9 Error: Overflow in line number count!
+#
+Numerischer Ãœberlauf in Zeilenzahl!
+#
+# 10 Error: Failed to setup character by character processing!
+#
+Byteweise Verarbeitung konnte nicht eingerichtet werden!
+#
+# 11 Error: Probably incorrect output due to problems ...
+#
+Ausgabe möglicherweise fehlerhaft (Probleme mit Daten-Dateien)!
+#
+# 12 .. 15 Error: Aborted by SIGINT signal!
+#
+Abbruch durch SIGINT-Signal!
+Abbruch durch SIGTERM-Signal!
+SIGPIPE-Signal aufgetreten!
+Schreiben auf Standardausgabe schlug fehl!
+#
+# 16 ... 21 Error messages.
+#
+Decodierung fehlgeschlagen!\n\tByte:
+Codierungng fehlgeschlagen!\n\tByte:
+Verarbeitung fehlgeschlagen!\n\tByte:
+,\n\tZeichen:
+,\n\tPosition in Zeile:
+.
+#
+# 22 ... 27 Error messages.
+#
+Decodierung fehlgeschlagen!
+Codierung fehlgeschlagen!
+Verarbeitung fehlgeschlagen!
+Weitere Decodierungs-Fehler!
+Weitere Codierungs-Fehler!
+Weitere Verarbeitungs-Fehler!
+#
+# 28 29 Error: Out of range!
+#
+Nicht im zulässigen Bereich: "
+"!
+#
+# 30 31 Error: Not a decimal number!
+#
+Keine Dezimal-Zahl: "
+"!
diff --git a/support/dktools/dktools/de/dk-t2l.txt b/support/dktools/dktools/de/dk-t2l.txt
new file mode 100644
index 0000000000..176b3b51c3
--- /dev/null
+++ b/support/dktools/dktools/de/dk-t2l.txt
@@ -0,0 +1,117 @@
+
+BEZEICHNUNG
+
+dk-t2l - Konverter von Text nach LaTeX
+
+ÃœBERSICHT
+
+dk-t2l [<Option(en)>] [<Datei(en)>]
+
+BESCHREIBUNG
+
+Das Programm wandelt Text aus den angegebenen Dateien bwz. der Standardeingabe
+in LaTeX-Sequenzen um und gibt diese auf die Standardausgabe aus.
+Alternativ können mit den Optionen -e, -n oder -h die umzuwandelnden Text
+bzw. Zeichen auch als Kommandozeilenargumente angegeben werden.
+
+OPTIONEN
+
+-i <string> Erwartetes Eingabe-Encoding, eines von:
+--input-encoding=<string> "ascii" (auch für ISO-LATIN-1),
+ "ansi", "utf-8", "utf-16", "utf-16-le",
+ "utf-16-be", "c32", "c32-le"
+ oder "c32-be".
+
+-e Kommandozeilen-Argumente sind der zu
+--echo konvertierende Text, keine Dateinamen.
+
+-n Kommandozeilen-Argumente sind dezimale
+--numeric Werte für umzuwandelnde UNICODE-Zeichen.
+
+-h Die Kommandozeilen-Argumente sind hexadezimale
+--hex Werte für umzuwandelnde UNICODE-Zeichen.
+
+-r Liste der nutzbaren Font-Encodings
+--recommendations und der zu benutzenden LaTeX-Pakete erstellen.
+
+-l \\ am Zeilenende schreiben
+--line-feed (Standard ist einfaches Newline).
+
+-t \HT{} für Tabulatoren schreiben
+--tabulator (Standard ist einfaches Leerzeichen).
+
+--verbose Fehlermeldung anzeigen, wenn Abbruch wegen
+ SIGPIPE erfolgte.
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+DATEIEN
+
+Das Programm benutzt Ãœbersetzungstabellen in *.t2l-Dateien, um LaTeX-Sequenzen
+für UNICODE-Zeichen zu finden. Die Übersetzungstabellen befinden sich
+normalerweise im Verzeichnis ${datadir}/dktools/charmap.
+
+Die Dateien bestehen aus Leerzeilen, Kommentarzeilen und Datenzeilen.
+Kommentarzeilen beginnen mit einer Raute ('#') als erstes Textzeichen.
+
+Datenzeilen bestehen aus mehreren Textstücken, die durch Leerzeichen
+bzw. Leerzeichenfolgen getrennt sind:
+- Hexadezimalwert des UNICODE-Zeichens (erforderlich).
+ Im neueren UNICODE-Standard haben Zeichen bis zu 24 Bit, im älteren
+ Standard bis zu 32.
+ Der Hexadezimalwert muss somit im Bereich 0...FFFFFFFF liegen.
+- Optionale Attribute der Form Name=Wert:
+ - b=<String>
+ LaTeX-Sequenz, die sowohl im Text- als auch im Mathematikmodus
+ benutzt werden kann.
+ - t=<String>
+ LaTeX-Sequenz, die im Textmodus benutzt werden kann.
+ - m=<String>
+ LaTeX-Sequenz, die im Mathematikmodus benutzt werden kann.
+ - e=<String>
+ Liste der Font-Encodings, getrennt durch Kommata.
+ Ist das erste Zeichen ein Ausrufezeichen ('!'), enthält die Liste die
+ auszuschließenden Font-Encodings, andernfalls die benutzbaren
+ Font-Encodings. Folgende Encodings sind möglich: "t1", "ot1",
+ "t4" oder "t5".
+ - p=<String>
+ Liste der benötigten Packages, getrennt durch Kommata.
+ Es können 1 bis 15 Packages angegeben werden.
+ Hinweis: Mindestens eines der Attribute b, t oder m muss angegeben sein.
+
+EINSCHRÄNKUNGEN
+
+Unter Windows kann eine Erweiterung von Dateinamen mit Wildcards (* oder ?)
+nur für Dateinamen bis zu einer Länge von _MAX_PATH (260) erfolgen.
+
+Das Programm benutzt Ãœbesetzungstabellen, um die LaTeX-Sequenzen zu finden.
+Da UNICODE laut Wikipedia-Artikel 1114112 Zeichen enthält
+(Stand: 12.05.2015), ist es mir nicht möglich, vollständige
+Ãœbersetzungstabellen zu erstellen. Da meine Muttersprache Deutsch ist,
+enthalten die Übersetzungstabellen derzeit hauptsächlich die in
+Mitteleuropa gebräuchlichen Zeichen.
+
+BEITRÄGE
+
+Wie bereits dargelegt, sind die Übersetzungstabellen nicht vollständig.
+Sie können weitere Übersetzungstabellen beisteuern, wenn Sie diese mit
+einer 3-Klausel-BSD-Lizenz versehen und über die SourceForge-Projektseite
+http://sourceforge.net/projects/dktools zur Verfügung stellen
+(im Foren- oder Patches-Bereich hochladen).
+
+AUTOR
+
+Dirk Krause
+
+COPYRIGHT UND LIZENZBESTIMMUNGEN
+
+Führen Sie
+ dk-t2l --license
+aus, um Lizenz-Inforomationen anzuzeigen.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/de/dk-uid.str b/support/dktools/dktools/de/dk-uid.str
new file mode 100644
index 0000000000..0e607448e2
--- /dev/null
+++ b/support/dktools/dktools/de/dk-uid.str
@@ -0,0 +1,49 @@
+#
+# 0 Error: Failed to install signal handlers!
+#
+Signal-Handler konnten nicht installiert werden!
+#
+# 1 Error: Failed to restore signal handlers!
+#
+Signal-Handler konnten nicht wiederhergestellt werden!
+#
+# 2 Error: Illegal number of command line arguments!
+#
+Unzulässige Anzahl an Kommandozeilenargumenten!\n\tMinimum und Maximum UID müssen angegeben werden!
+#
+# 3 Error: getpwent() function is not available on this platform!
+#
+Die Funktion getpwent() ist auf dieser Plattform nicht verfügbar!
+#
+# 4 Error: Failed to write text to standard output!
+#
+Schreiben von Text auf die Standardausgabe fehlgeschlagen!
+#
+# 5 Error: Failed to convert numeric value to string!
+#
+Numerischer Wert konnte nicht zu Text konvertiert werden, evtl. Bug!
+#
+# 6 Error: No unused UID in specified range!
+#
+Keine unbenutzte UID im angegebenen Bereich verfügbar!
+#
+# 7 Error: Failed to retrieve bit from bit field, probably bug!
+#
+Bit konnte nicht aus Bit-Feld gelesen werden, evtl. Bug!
+#
+# 8 Error: Aborted by signal!
+#
+Abbruch durch Signal!
+#
+# 9 Error: Failed to obtain command line arguments, probably bug!
+#
+Kommandozeilenargumente konnten nicht ermittelt werden, evtl. Bug!
+#
+# 10 11 Error: Command line argument "" is not a number!
+#
+Das Kommandozeilenargument "
+" ist keine Zahl!
+#
+# 12 Error: UID range too large!
+#
+UID-Bereich zu groß!
diff --git a/support/dktools/dktools/de/dk-uid.txt b/support/dktools/dktools/de/dk-uid.txt
new file mode 100644
index 0000000000..58b4665188
--- /dev/null
+++ b/support/dktools/dktools/de/dk-uid.txt
@@ -0,0 +1,38 @@
+
+BEZEICHNUNG
+
+dk-uid - Suche nach freier UID
+
+ÃœBERSICHT
+
+dk-uid <min> <max>
+
+BESCHREIBUNG
+
+Das Programm durchsucht den angegebenen UID-Bereich nach einer noch freien
+UID. Bei Erfolg wird die erste noch freie UID ausgegeben.
+
+ARGUMENTE
+
+<min> Minimale UID-Nummer.
+
+<max> Maximale UID-Nummer.
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+AUTOR
+
+Dirk Krause
+
+COPYRIGHT UND LIZENZBESTIMMUNGEN
+
+Führen Sie
+ dk-uid --license
+aus, um Lizenz-Informationen anzuzeigen.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/de/dk3app.str b/support/dktools/dktools/de/dk3app.str
new file mode 100644
index 0000000000..3031f247a5
--- /dev/null
+++ b/support/dktools/dktools/de/dk3app.str
@@ -0,0 +1,1362 @@
+# Test with german umlauts and ligatures: äöüÄÖÜß
+# PLEASE DO NOT REMOVE THE LINE ABOVE!
+# Good editors (like i.e. vim) recognize UTF-8 sequences
+# automatically when opening a file and set the encoding
+# for file save operations properly.
+# This requires the presence of some UTF-8 sequences in the
+# file to work, otherwise your systems default encoding
+# is used.
+#
+# 0: Newline
+#
+\n
+#
+# 1: Message type: Panic
+#
+PANIK
+#
+# 2: Message type: Fatal error
+#
+FATALER FEHLER
+#
+# 3: Message type: Error
+#
+FEHLER
+#
+# 4: Message type: Warning
+#
+Warnung
+#
+# 5: Message type: Information
+#
+Information
+#
+# 6: Message type: Progress
+#
+Fortschritt
+#
+# 7: Message type: Debug
+#
+Debug
+#
+# 8: Space, used to print messages
+#
+
+#
+# 9: Error: Not enough memory
+#
+Zu wenig Speicher (Hauptspeicher/Auslagerungsdatei)!
+#
+# 10: Start of message comment line for date and time
+#
+\#
+#
+# 11: Colon to separate mesage parts
+#
+:
+#
+# 12/13: Message: Memory allocation failed for xxx bytes!
+#
+Speicheranforderung (
+ Bytes) schlug fehl!
+#
+# 14: Message: Memory allocation failed!
+#
+Speicheranforderung schlug fehl!
+#
+# 15: Message: Overflow in size calculation!
+#
+Zahlenbereichsüberlauf bei Größenberechnung!
+#
+# 16/17/18: Message: Overflow in size calc xxx x xxx bytes!
+#
+Zahlenbereichsüberlauf in Größenberechnung(
+ x
+ Bytes)!
+#
+# 19/20: Message: Application xxx started
+#
+Start der Anwendung "
+".
+#
+# 21/22: Message: Application xxx finished.
+#
+Ende der Anwendung "
+".
+#
+# 23: Debug message at program start: Application name
+#
+Anwendungs-Name:
+#
+# 24: Debug message at program start: Application group name
+#
+Anwendungs-Gruppe:
+#
+# 25: Debug message at program start: Executable file
+#
+Ausführbare Datei:
+#
+# 26: Debug message at program start: "bin" directory
+#
+"bin"-Verzeichnis:
+#
+# 27: Debug message at program start: "etc" directory
+#
+"etc"-Verzeichnis:
+#
+# 28: Debug message at program start: "share" directory
+#
+"share"-Verzeichnis:
+#
+# 29: Debug message at program start: "var" directory
+#
+"var"-Verzeichnis:
+#
+# 30: Debug message at program start: Home directory
+#
+HOME-Verzeichnis:
+#
+# 31: Debug message at program start: Temporary directory
+#
+Temporäres Verzeichnis:
+#
+# 32: Debug message at program start: User name
+#
+Nutzer-Name:
+#
+# 33: Debug message at program start: Log file name
+#
+Log-Datei:
+#
+# 34: Debug message at program start: Language
+#
+Sprache:
+#
+# 35: Debug message at program start: Region/Country
+#
+Region/Land:
+#
+# 36: Debug message at program start: Text "<unknown>"
+#
+<unbekannt>
+#
+# 37: Error message: Name of temp directory too long!
+#
+Der Name für das Temporär-Verzeichnis wird zu lang!
+#
+# 38: Error message: Destination buffer too small!
+#
+Der Ziel-Puffer ist zu klein, um die Daten aufzunehmen!
+#
+# 39: Error message: LANG environment variable too long!
+#
+Der Wert der Umgebungsvariable "LANG" ist zu lang!
+#
+# 40: Error message: Failed to find name of executable file!
+#
+Der Dateiname für das ausgeführte Programm wurde nicht gefunden!
+#
+# 41: Error message: Too few directories in hierarchy!
+#
+Verzeichnis-Hierarchie zu flach!\nAusführbare Dateien sollten nicht im Wurzelverzeichnis stehen!
+#
+# 42: Error message: Name of executable file too long!
+#
+Der Dateiname für das ausgeführte Programm ist zu lang!
+#
+# 43: Error message: Failed to obtain users login name!
+#
+Der Login-Name konnte nicht ermittelt werden!
+#
+# 44: Error message: Failed to find HOME directory!
+#
+Das Home-Verzeichnis konnte nicht ermittelt werden!
+#
+# 45: Error message: File name for log file gets too long!
+#
+Dateiname für die Log-Datei zu lang!
+#
+# 46: Error message: Failed to create directory for log file!
+#
+Das Verzeichnis für die Log-Datei kann nicht angelegt werden!
+#
+# 47: Error message: Failed to convert PID to text!
+#
+Die Prozess-ID kann nicht zu Text konvertiert werden!
+#
+# 48: Failed to find application name!
+#
+Der Anwendungs-Name konnte nicht ermittelt werden!
+#
+# 49: Error message: Name of temporary directory too long!
+#
+Der Name für das Temporär-Verzeichnis ist zu lang!
+#
+# 50: Error message: Failed to find var directory!
+#
+Es konnte kein var-Verzeichnis ermittelt werden!
+#
+# 51: Error message: Preference name too long!
+#
+Ein Preference-Name ist zu lang!
+#
+# 52: Error message: Malformed preference entry on command!
+#
+Unzulässige Preference-Angabe in Kommandozeile!
+#
+# 53: Error message: Failed to find current working directory!
+#
+Das aktuelle Verzeichnis konnte nicht ermittelt werden!
+#
+# 54: Error message: Too many requests for temporary file names!
+#
+Es wurden zu viele Dateinamen für temporäre Dateien benötigt!
+#
+# 55: Error message: Internal error (bug): Missing names!
+#
+Interner Fehler (Bug): Datei/Verzeichnis-Namen unvollständig!
+#
+# 56/57/58: Error message: Failed to save preference entry!
+#
+Der Preference-Eintrag "
+"="
+" konnte nicht angelegt werden!
+#
+# 59/60: Error message: Directory name ... too long!
+#
+Der Verzeichnis-Name "
+" ist zu lang!
+#
+# 61/62: Error message: Failed to information about ... stat
+#
+Keine Informationen über Datei "
+"!
+#
+# 63/64: Error message: Failed to read directory ...!
+#
+Das Verzeichnis "
+" konnte nicht geöffnet werden!
+#
+# 65/66: Error message: File name ... too long!
+#
+Der Dateiname "
+" ist zu lang!
+#
+# 67: Error message: Illegal character(s) in source string!
+#
+Unzulässige Zeichen gefunden!
+#
+# 68: Error message: Failed to remove a directory!
+#
+Verzeichnis ließ sich nicht löschen!
+#
+# 69/70: Error message: Failed to remove directory ... !
+#
+Das Verzeichnis "
+" konnte nicht gelöscht werden!
+#
+# 71: Error message: Missing HOMEDRIVE environment variable.
+#
+Die Umgebungs-Variable HOMEDIR ist nicht definiert!
+#
+# 72: Error message: Missing HOMEPATH environment variable.
+#
+Die Umgebungs-Variable HOMEPATH ist nicht definiert!
+#
+# 73: Error message: Failed to obtain information about a file
+#
+Für eine Datei konnten keine Informationen abgerufen werden!
+#
+# 74/75: Error message: ... is a directory!
+#
+"
+" ist ein Verzeichnis!
+#
+# 76: Error message: Can not open file, is a directory!
+#
+Die Datei kann nicht geöffnet werden, keine Datei sondern Verzeichnis!
+#
+# 77/78: Error message: Failed to open ... for write access
+#
+Die Datei "
+" kann nicht zum Schreiben geöffnet werden!
+#
+# 79: Error message: Failed to open a file for writing!
+#
+Eine Datei konnte nicht zum Schreiben geöffnet werden!
+#
+# 80: Error message: Failed to find current time!
+#
+Die aktuelle Uhrzeit konnte nicht ermittelt werden!
+#
+# 81/82: Error message: File exists but isn't a directory!
+#
+Die Datei "
+" existiert, ist aber kein Verzeichnis!
+#
+# 83: Error message: File exists but isn't a directory!
+#
+Die Datei existiert, ist aber kein Verzeichnis!
+#
+# 84/85: Error message: Failed to create directory ...!
+#
+Das Verzeichnis "
+" konnte nicht angelegt werden!
+#
+# 86: Error message: Failed to create directory!
+#
+Das Verzeichnis konnte nicht angelegt werden!
+#
+# 87: Error message: Directory name too long!
+#
+Der Verzeichnis-Name ist zu lang!
+#
+# 88/89: Error message: Failed to remove file ...!
+#
+Die Datei "
+" konnte nicht gelöscht werden!
+#
+# 90: Error message: Failed to remove file
+#
+Die Datei konnte nicht gelöscht werden!
+#
+# 91: Error message: User record does not have a user name
+#
+Der Nutzer-Datensatz enthält keinen Nutzernamen!
+#
+# 92/93: Error message: No user record for ...!
+#
+Kein Nutzer-Datensatz für "
+" vorhanden!
+#
+# 94: Error message: No matching user record!
+#
+Kein passender Nutzer-Datensatz vorhanden!
+#
+# 95: Error message: No home directory in user record!
+#
+Der Nutzer-Datensatz enthält kein Homeverzeichnis!
+#
+# 96/97: Error message: No information about file ..., lstat
+#
+Keine Informationen über Datei "
+"!
+#
+# 98/99: Error message: No information about a file!
+#
+Für eine Datei konnten keine Informationen abgerufen werden!
+Für eine Datei konnten keine Informationen abgerufen werden!
+#
+# 100/101: Error message: Symlink owner is not file owner!
+#
+Eigentümer von Symlink "
+" und Zieldatei sind unterschiedlich!
+#
+# 102: Error message: Symlink owner is not file owner!
+#
+Symlink und Zieldatei haben unterschiedliche Eigentümer!
+#
+# 103/104: Error message: Command ... is too long!
+#
+Der Befehl "
+" ist zu lang!
+#
+# 105: Error message: Command too long!
+#
+Der Befehl ist zu lang!
+#
+# 106: Error message: PATH not defined!
+#
+Die Umgebungsvariable PATH ist nicht definiert!
+#
+# 107: Error message: No mkdir function!
+#
+Keine Funktion zum Verzeichnis-Erzeugen vorhanden!
+#
+# 108: Error message: String too long!
+#
+Der Text ist zu lang!
+#
+# 109: Error message: Command name too long!
+#
+Der Befehl ist zu lang!
+#
+# 110/111: Error message: Too many .. in command!
+#
+Der Befehl "
+" enthält zu viele ".."!
+#
+# 112: Error message: Illegal character(s) in source string!
+#
+Der Text enthält unzulässige Zeichen!
+#
+# 113: Error message: Illegal character(s) in source buffer!
+#
+Der Quell-Puffer enthält unzulässige Zeichen!
+#
+# 114: Error message: Illegal destination encoding!
+#
+Das Ziel-Encoding ist nicht zulässig!
+#
+# 115: Error message: Conversion to UTF-8 failed!
+#
+Umwandlung nach UTF-8 nicht möglich!
+#
+# 116: Error message: Conversion to UTF-16 failed!
+#
+Umwandlung nach UTF-16 nicht möglich!
+#
+# 117: Error message: Result character not available!
+#
+Im Ziel-Encoding sind nicht alle Zeichen abbildbar!
+#
+# 118: Error message: UTF-8 decoding failed!
+#
+Decodieren von UTF-8-Text fehlgeschlagen!
+#
+# 119: Error message: UTF-16 decoding failed!
+#
+Decodieren von UTF-16-Text fehlgeschlagen!
+#
+# 120: Error message: Failed to write output!
+#
+Schreiben von Daten fehlgeschlagen!
+#
+# 121: Error message: Failed to flush output!
+#
+Ende des Schreibvorganges fehlgeschlagen!
+#
+# 122: Error message: Failed to close data stream object!
+#
+Resourcenfreigabe für Datenstrom fehlgeschlagen!
+#
+# 123: Error message: Stream not opened for write ops!
+#
+Der Datenstrom wurde nicht zum Schreiben geöffnet!
+#
+# 124: Error message: Failed to read data!
+#
+Lesen von Daten fehlgeschlagen!
+#
+# 125: Error message: Mismatch encoding/character size!
+#
+Zeichengröße und Encoding sind unvereinbar!
+#
+# 126: Error message: Too many ".." in file name!
+#
+Zu viele ".." in Dateinamen!
+#
+# 127/128: Error message: Unknown message digest type!
+#
+Unbekannter Message-Digest-Typ "
+"!
+#
+# 129/130: Error message: Unknown encoding "..."!
+#
+Unbekanntes Encoding: "
+"!
+#
+# 131: Error message: Failed to find current host name!
+#
+Der Hostname konnte nicht ermittelt werden!
+#
+# 132: Debug message: Host:
+#
+Host-Name:
+#
+# 133/134: Error message: Option ... requires an argument!
+#
+Die Option "
+" erfordert ein Argument!
+#
+# 135/136: Error message: Option ... too long for processing!
+#
+Option zu lang zum verarbeiten:\n"
+"!
+#
+# 137/138: Error message: Ignoring irrelevant option argument ... !
+#
+Das überflüssige Argument in "
+" wird ignoriert!
+#
+# 139/140: Error message: Unknown option ...!
+#
+Unzulässige Option "
+"!
+#
+# 141/142: Error message: Not a numeric value ...!
+#
+Kein Zahlenwert: "
+"!
+#
+# 143/144: Error message: Failed to open file ...!
+#
+Die Datei "
+" kann nicht geöffnet werden!
+#
+# 145: Error message: Failed to open file!
+#
+Datei kann nicht geöffnet werden!
+#
+# 146/147: Error message: Not a boolean value ...!
+#
+Kein boolscher Wert: "
+"!
+#
+# 148/149: Debug message: Resource file ... found.
+#
+Resourcen-Datei "
+" gefunden.
+#
+# 150/151: Debug message: Resource file ... not found.
+#
+Resourcen-Datei "
+" nicht gefunden.
+#
+# 152/153: Debug message: Configuration file ... found.
+#
+Konfigurations-Datei "
+" gefunden
+#
+# 154/155: Debug message: Configuration file ... not found.
+#
+Konfigurations-Datei "
+" nicht gefunden.
+#
+# 156/157: Error message: No support for message digest type ...!
+#
+Der Message-Digest-Typ "
+" wird nicht unterstützt!
+#
+# 158: Error message: Illegal message digest or encoding number!
+#
+Unzulässiger Code für Message-Digest-Typ oder Encoding!
+#
+# 159: Error message: Checksumming is available for regular files only!
+#
+Checksummenbildung ist nur für reguläre Dateien möglich!
+#
+# 160/161: Error message: Key or option name missing: ...!
+#
+In langen Optionen muss ein Optionsname für "
+" angegeben werden!
+#
+# 162: Error message: Failed to convert a numeric value to text!
+#
+Ein numerischer Wert konnte nicht zu Text konvertiert werden!
+#
+# 163: Closing for 61
+#
+"!
+#
+# 164/165: Warning: Too many command line arguments...!
+#
+Überzählige Argumente ab "
+" werden ignoriert!
+#
+# 166/167: Error message: Internal error (bug) ...!
+#
+Interner Fehler (wahrscheinlich ein Bug)
+.
+#
+# 168/169: Error message: Too many file names match ...!
+#
+"
+" passt nicht eindeutig auf einen Dateinamen!
+#
+# 170-172: Error message: Write operation failed, ... of ... bytes written!
+#
+Schreiben schlug fehl,
+ von
+ Bytes wurden geschrieben!
+#
+# 173: Error message: Write operation failed!
+#
+Schreiben schlug fehl!
+#
+# 174-176: Error message: Write operation failed, ... of ... elements written!
+#
+Schreiben schlug fehl,
+ von
+ Elementen wurden geschrieben!
+#
+# 177: Error message: Failed to create random data!
+#
+Fehler beim Erzeugen von Zufalls-Daten!
+#
+# 178: Error message: Not usable PRNG found!
+#
+Kein benutzbarer PRNG wurde gefunden!
+#
+# 179: Error message: Failed to seed simple PRNG!
+#
+Initialisierung für srand()/rand() fehlgeschlagen!
+#
+# 180: Error message: Failed to seed lrand48() PRNG!
+#
+Initialisierung für lrand48() fehlgeschlagen!
+#
+# 181: Error message: Failed to seed random() PRNG!
+#
+Initialisierung für random() fehlgeschlagen!
+#
+# 182: Error message: Failed to seed OpenSSL PRNG!
+#
+Initialisierung für OpenSSL PRNG fehlgeschlagen!
+#
+# 183/184: Error message: Seed file ... not used (permissions)!
+#
+Seed-Datei "
+" nicht benutzbar (Berechtigungen zu locker)!
+#
+# 185/186: Error message: Seed file ... not used (symlink owner)!
+#
+Seed-Datei "
+" nicht benutzbar (Symlink-Besitzer ist nicht Datei-Besitzer)!
+#
+# 187/188: Error message: Unknown PRNG type ... !
+#
+Unbekannter PRNG-Typ: "
+"!
+#
+# 189-192: Error message: The ... PRNG type is not available!
+#
+Der rand()-PRNG ist nicht verfügbar!
+Der lrand48()-PRNG ist nicht verfügbar!
+Der random()-PRNG ist nicht verfügbar!
+Der OpenSSL-PRNG ist nicht verfügbar!
+#
+# 193: Error message: Failed to save random seed data!
+#
+Die Seed-Daten für den Zufallsgenerator konnten nicht gespeichert werden!
+#
+# 194: Error message: HOME directory name too long!
+#
+Der Name für das Home-Verzeichnis ist zu lang!
+#
+# 195: Info: System configuration files skipped by user.
+#
+System-Konfigurationsdateien werden nicht benutzt.
+#
+# 196-197: Debug message: Attempt to obtain seed data from ...
+#
+Versuche, Zufallsgenerator von "
+" zu initialisieren.
+#
+# 198-199: Debug message: Seed data: ... bytes found.
+#
+Zufallsgenerator-Initialisierung:
+ Bytes gefunden.
+#
+# 200: Error message: Index out of range!
+#
+Unzulässiger Index!
+#
+# 201: Error message: Matrix expansion requires a square matrix!
+#
+Matrix-Expansion ist nur für quadratische Matrizen möglich!
+#
+# 202-203: Error message: Not a directory: ...!
+#
+"
+" ist kein Verzeichnis!
+#
+# 204: Error message: Encoding not supported by C runtime library!
+#
+Encoding wird von C-Runtime-Library nicht unterstützt!
+#
+# 205: Error message: No directory containing LaTeX encoding tables found!
+#
+Kein Verzeichnis mit LaTeX-Encoding-Tabellen gefunden!
+#
+# 206-208: Warning: Redefinition, overwriting ... by ...!
+#
+Neudefinition:\n"
+" wird überschrieben mit "
+"!
+#
+# 209-210: Error message: Index ... is out of range 0...255!
+#
+Syntax-Fehler\nIndex
+ liegt außerhalb von 0...255!
+#
+# 211-212: Error message: Syntax error near ...!
+#
+Syntax-Fehler\nnahe "
+"!
+#
+# 213: Error message: Syntax error, missing LaTeX encoding!
+#
+Syntax-Fehler,\nLaTeX-Encoding fehlt!
+#
+# 214: Error message: Syntax error, missing index!
+#
+Syntax-Fehler,\nZeichen-Index fehlt!
+#
+# 215-216: Error message: No file name matching ...!
+#
+Kein Dateiname passt auf "
+"!
+#
+# 217: Error message: Missing name of long option!
+#
+Der Name für eine lange Option fehlt!
+#
+# 218: Error message: Incomplete input sequence!
+#
+Unvollständige Eingabedaten!
+#
+# 219: Error message: String contains non-ISO-LATIN-1 characters!
+#
+Text enthält nicht darstellbare Zeichen!
+#
+# 220: Error message: Misconfigured start/end for range!
+#
+Start/Ende-Angabe für Bereich ist fehlerhaft!
+#
+# 221: Error message: New range conflicts with existing one!
+#
+Neuer Bereich in Konflikt mit bereits existierendem Bereich!
+#
+# 222: Error message: Not a hex number!
+#
+Hexadezimal-Zahl nicht gefunden!
+#
+# 223: Error message: Syntax error!
+#
+Syntax-Fehler!
+#
+# 224: Error message: Character redefinition!
+#
+Zeichen-Neudefinition!
+#
+# 225: Error message: Range not declared in character directory!
+#
+Bereich in Zeichen-Directory nicht deklariert!
+#
+# 226: Error message: Package name conflicts with previous definition!
+#
+Paket-Name steht in Konflikt zu bereits angegebenem Paket!
+#
+# 227: Debug message: Attempt to obtain seed data from CryptoAPI
+#
+Seed-Daten von CryptoAPI
+#
+# 228: Debug message: Attempt to obtain seed data from screen.
+#
+Seed-Daten vom Bildschirm
+#
+# 229: Debug message: OpenSSL PRNG seeded successfully.
+#
+OpenSSL-PRNG wurde erfolgreich initialisiert.
+#
+# 230/231: Debug message: Attempt to read preferences file "...".
+#
+Versuch, Preferences-Datei "
+" zu lesen.
+#
+# 232/233: Debug message: LaTeX table directory "...".
+#
+LaTeX-Tabellen-Verzeichnis: "
+".
+#
+# 234/235: Debug message: Versuche LaTeX-Tabellen-Verzeichnis "...".
+#
+Teste LaTeX-Tabellen-Verzeichnis "
+".
+#
+# 236/237: Debug message: Reading LaTeX table dir: "...".
+#
+Lese LaTeX-Konvertierungs-Verzeichnis: "
+".
+#
+# 238/239: Debug message: Registering LaTeX conversion range ...
+#
+Bereich
+ wurde registriert.
+#
+# 240/241: Debug message: Loading LaTeX conversion data file "...".
+#
+Lade LaTeX-Konvertierungs-Tabelle "
+".
+#
+# 242/243: Error message: Failed to change into directory "..."!
+#
+Kann nicht in Verzeichnis "
+" wechseln!
+#
+# 244: Error message: Printer listing failed!
+#
+Die Drucker-Auflistung schlug fehl!
+#
+# 245: Error message: Record too large!
+#
+Datensatz zu groß!
+#
+# 246: Error message: File damaged or not a database file!
+#
+Datei beschädigt oder keine Datenbank-Datei!
+#
+# 247/248: Error message: No support for database type "..." available!
+#
+Datenbank-Typ "
+" wird nicht unterstützt!
+#
+# 249: Error message: Key not found in database!
+#
+Kein passender Eintrag in der Datenbank!
+#
+# 250: Error message: DB entry probably damaged - not a multibyte char string!
+#
+Datenbankeintrag ist kein Multibyte-String!
+#
+# 251: Error message: Database opened for read access only!
+#
+Datenbank wurde nur zum Lesen geöffnet!
+#
+# 252: Error message: Error(s) while processing command line arguments!
+#
+Fehler bei Verarbeitung der Kommandozeilenargumente!
+#
+# 253: Error message: Failed to retrieve current locale!
+#
+Aktuelle locale-Einstellung konnte nicht ermittelt werden!
+#
+# 254: Error message: Current locale too long!
+#
+Aktuelle locale-Einstellung zu lang!
+#
+# 255/256: Error message: Not a regular file "..."!
+#
+Keine reguläre Datei: "
+"!
+#
+# 257: Error message: Image file type unknown or not supported!
+#
+Image-Typ unbekannt bzw. nicht unterstützt!
+#
+# 258: Error message: Bits per component restricted to 16!
+#
+Maximal 16 bits per component erlaubt!
+#
+# 259: Error message: Incorrect page setup, no usable space between borders!
+#
+Seiten fehlerhaft eingerichtet, kein Platz zwischen den Rändern!
+#
+# 260: Error message: Mathematical error in size calculations!
+#
+Numerischer Fehler in Berechnung!
+#
+# 261: Error message: Failed to set bitmap image frame!
+#
+Bitmap-Frame konnte nicht angewählt werden!
+#
+# 262: Error message: Flate compression is not supported!
+#
+Flate-Kompression wird nicht unterstützt!
+#
+# 263: Error message: Illegal compression cell type used!
+#
+Illegaler Kompressions-Type benutzt!
+#
+# 264: Error message: Error during previous compression operations!
+#
+Fehler bei vorherigen Kompressions-Operationen!
+#
+# 265: Error message: Failed to retrieve console settings!
+#
+Die Terminal-Einstellungen konnten nicht gespeichert werden!
+#
+# 266: Error message: Failed to estore console settings!
+#
+Die Terminal-Einstellungen konnten nicht wiederhergestellt werden!
+#
+# 267: Error message: Failed to modify console settings!
+#
+Die Terminal-Einstellungen konnten nicht geändert werden!
+#
+# 268: Error message: Failed to convert timestamp to local time!
+#
+Ein Zeitpunkt konnte nicht in eine lokale Zeitangabe konvertiert werden!
+#
+# 269: Error message: No file name available for database!
+#
+Kein Dateiname für Datenbank vorhanden!
+#
+# 270/271: Error message: Failed to change file ownership!
+#
+Datei-Eigentümer konnte nicht geändert werden:\n"
+"!
+#
+# 272/273: Error message: Failed to change file permissions!
+#
+Datei-Zugriffsrechte konnten nicht geändert werden:\n"
+"!
+#
+# 274: Error message: Insufficient permissions!
+#
+Entsprechende Berechtigungen sind für Netzwerkverbindung erforderlich!
+#
+# 275: Error message: Unknown or illegal address family!
+#
+Unbekannte/unzulässige Adressfamilie!
+#
+# 276: Error message: Process table overflow!
+#
+Zu viele Prozesse, Prozesstabelle reicht nicht aus!
+#
+# 277: Error message: Too many open files
+#
+Zu viele Dateien geöffnet!
+#
+# 278: Error message: Protocol not supported!
+#
+Protokoll wird nicht unterstützt!
+#
+# 279: Error: Failed to open network socket!
+#
+Socket konnte nicht angelegt werden!
+#
+# 280: Error: Failed to close socket!
+#
+Socket konnte nicht geschlossen werden!
+#
+# 281: Error: Operation interrupted by signal!
+#
+Unterbrechung durch ein Signal!
+#
+# 282: Error: Failed to connect!
+#
+Verbindungsaufbau fehlgeschlagen!
+#
+# 283: Error: Listen failed!
+#
+Warten auf eingehende Verbindungen fehlgeschlagen!
+#
+# 284/285: Error: Failed to find IP address for "..."!
+#
+Für "
+" wurde keine IP-Adresse gefunden!
+#
+# 286: Error: Host not found!
+#
+Keine Daten für Host gefunden!
+#
+# 287: Error: Host exists, but no IP address assigned!
+#
+Host existiert, hat aber keine IP-Adresse!
+#
+# 288: Error: Problem on DNS server!
+#
+Problem beim DNS-Server!
+#
+# 289: Error: Temporary problem on DNS server, try again later!
+#
+Zeitweiliges Problem beim DNS-Server, evtl. später erneut probieren!
+#
+# 290: Error: Not gethostbyname() function available!
+#
+Funktion gethostbyname() auf diesem System nicht verfügbar!
+#
+# 291: Error: Can not connect to remote port 0!
+#
+Port 0 ist als Verbindungsziel nicht zulässig!
+#
+# 292: Error: Access denied by firewall or due to insufficient permissions!
+#
+Zugriff verboten (Firewall oder fehlende Berechtigungen)!
+#
+# 293: Error: Local address already in use!
+#
+Die lokale Adresse wird bereits verwendet!
+#
+# 294: Error: Resources shortage!
+#
+Resourcen-Problem!
+#
+# 295: Error: Previous connection attempt not yet completed!
+#
+Ein laufender Verbindungsversuch muss erst abgeschlossen werden!
+#
+# 296: Error: Connection refused.
+#
+Verbindungsversuch wurde abgewiesen,\nPort an Gegenstelle nicht geöffnet!
+#
+# 297: Error: Socket already connected!
+#
+Socket ist bereits verbunden!
+#
+# 298: Error: Network unreachable!
+#
+Netzwerk ist nicht erreichbar!
+#
+# 299: Error: Timeout!
+#
+Zeitüberschreitung (Timeout)!
+#
+# 300: Error: No select() function, timeout settings ignored!
+#
+Timeout-Einstellungen werden ignoriert,\nauf diesem System ist keine Funktion select() vorhanden!
+#
+# 301: Error: Failed to retrieve socket state!
+#
+Abfrage des Socket-Status fehlgeschlagen!
+#
+# 302/303: Error: Failed to bind local address "..."!
+#
+Lokale Adresse "
+" konnte nicht gebunden werden!
+#
+# 304: Error: Socket already bound to local address!
+#
+Socket ist bereits an eine lokale Adresse gebunden!
+#
+# 305
+#
+Fehler beim Senden von Daten!
+#
+# 306
+#
+Operation würde blockieren!
+#
+# 307
+#
+Verbindung von Gegenstelle beendet/abgewiesen!
+#
+# 308
+#
+Empfängeradresse fehlt!
+#
+# 309
+#
+Empfängeradresse nicht gestattet!
+#
+# 310
+#
+Zu viele Daten für Sendung in einer Nachricht!
+#
+# 311
+#
+Sende-Queue ist voll!
+#
+# 312
+#
+Kein Empfänger liest aus der Pipe.
+#
+# 313
+#
+Weniger Bytes geschrieben als gefordert!
+#
+# 314
+#
+Fehler beim Lesen aus Socket!
+#
+# 315
+#
+Fehler beim Herunterfahren der Socket!
+#
+# 316
+#
+Socket ist nicht verbunden!
+#
+# 317
+#
+Fehler beim Annehmen einer Verbindung!
+#
+# 318
+#
+Verbindung wurde abgebrochen!
+#
+# 319
+#
+Netzwerk-Protokoll-Fehler!
+#
+# 320
+#
+Netzwerk-Subsystem nicht verfügbar!
+#
+# 321
+#
+Windows-Sockets noch nicht initialisiert!
+#
+# 322
+#
+Eine blockierende Winsock-1.1-Operation läuft!
+#
+# 323
+#
+Socket-Typ passt nicht zur Adressfamilie!
+#
+# 324
+#
+Socket wurde nicht für Broadcasts konfiguriert!
+#
+# 325
+#
+Die angeforderte Adresse ist nicht verfügbar!
+#
+# 326
+#
+Host nicht erreichbar!
+#
+# 327
+#
+Windows-Sockets-Version ist nicht verfügbar!
+#
+# 328
+#
+Zu viele Prozesse benutzen Windows-Sockets!
+#
+# 329
+#
+Ein-/Ausgabefehler!
+#
+# 330
+#
+Zu viele symbolische Links im Pfad!
+#
+# 331
+#
+Unzulässiger Pfad (eines der übergeordneten Directories fehlt)!
+#
+# 332
+#
+Dateisystem ist nur zum Lesen gemountet!
+#
+# 333
+#
+NFS-Dateihandle fehlt!
+#
+# 334
+#
+Server für Datei nicht mehr verfügbar!
+#
+# 335
+#
+Kein freier Platz mehr auf dem Datenträger!
+#
+# 336
+#
+Fehler beim Warten auf Netzwerk-Sockets!
+#
+# 337
+#
+Adresse in Textform kann nicht verarbeitet werden!
+#
+# 338
+#
+Keine Adresse für Host gefunden!
+#
+# 339
+#
+Socket-Option konnte nicht gesetzt werden!
+#
+# 340
+#
+Fehler beim Schließen einer Datei!
+#
+# 341/342
+#
+Fehler beim Schließen der Datei\n"
+"!
+#
+# 343/344
+#
+Fehler beim Schreiben in Datei:\n"
+"!
+#
+# 345
+#
+Fehler beim Daten-Lesen aus Datei!
+#
+# 346/347
+#
+Fehler beim Lesen von Daten aus Datei: "
+"!
+#
+# 348/349
+#
+Keine IP-Adresse: "
+"!
+#
+# 350
+#
+Keine IP-Adresse!
+#
+# 351/352
+#
+Verbindung mit "
+" fehlgeschlagen!
+#
+# 353
+#
+Keine Funktion zum Prüfen auf Blockieren/Nicht-Blockieren verfügbar!
+#
+# 354
+#
+Die Netzmaske ist keine IP-Adresse!
+#
+# 355
+#
+Die Netzmaske ist keine Bit-Anzahl!
+#
+# 356
+#
+Die Netzmaske ist keine IPv6-Adresse!
+#
+# 357
+#
+Keine Namensauflösung verfügbar, bitte IP-Adresse angeben!
+#
+# 358
+#
+Keine select()-Funktion verfügbar!
+#
+# 359
+#
+Keine verwendbare Socket im Set!
+#
+# 360 361
+#
+Socket
+ verbunden mit Client:
+#
+# 362 363
+#
+Verbindungsaufbau von "
+" zurückgewiesen!
+#
+# 364
+#
+Es konnte keine Server-Socket für Socket-Satz erzeugt werden!
+#
+# 365
+#
+Der Wert von /threads/max ist größer als die ermittelte CPU-Core-Anzahl!
+#
+# 366 + 367
+#
+Eindeutige Datei-Kennung konnte nicht ermittelt werden für:\n"
+"!
+#
+# 368
+#
+Für eine Datei konnte keine eindeutige Kennung ermittelt werden!
+#
+# 369 + 370 Preference ... does not point to a directory.
+#
+Preference "
+" verweist nicht auf ein Verzeichnis!
+#
+# 371
+#
+
+#
+# 372 373 374
+#
+Socket
+ lauscht an Adresse:
+
+#
+# 375 376 377
+#
+Socket
+ ist verbunden mit Gegenstelle:
+
+#
+# 378 379 380
+#
+Verschieden Font-Encodings werden gefordert!
+Font-Encoding sowohl gefordert als auch verboten: "
+"!
+#
+# 381 382
+#
+Mögliches Font-Encoding: "
+"!
+#
+# 383 384
+#
+Font-Encoding "
+" kann nicht benutzt werden.
+#
+# 385
+#
+Kein Font-Encoding benutzbar!
+#
+# 386 387 388
+#
+Zu viele Einträge bei Position
+in Text-Zeile:\n"
+"
+#
+# 389 390
+#
+Unerwartetes String-Ende in Text:\n"
+"
+#
+# 391 392
+#
+UTF-8-Decodierung fehlgeschlagen für\n"
+UTF-16-Decodierung fehlgeschlagen für\n"
+#
+# 393 394
+#
+Nicht-ANSI-Zeichen in\n"
+Nicht-URL-Zeichen in\n"
+#
+# 395 396
+#
+Zeichen 0x
+bereits definiert!
+#
+# 397
+#
+Erneute Definition eines Zeichens!
+#
+# 398 399
+#
+Das erste Wort ist keine Hexadezimal-Zahl!
+_UNUSED_
+#
+# 400
+#
+Keine Daten für Zeichen gefunden!
+#
+# 401
+#
+Komprimierung mit zlib wird nicht unterstützt!
+#
+# 402
+#
+Komprimierung mit bzip2-Bibliothek wird nicht unterstützt!
+#
+# 403
+#
+Keine Konvertierungs-Daten gefunden!
+#
+# 404
+#
+Syntax-Fehler, unbekanntes Encoding!
+#
+# 405
+#
+Syntax-Fehler, keine Package-Namen gefunden!
+#
+# 406
+#
+Syntax-Fehler, Wert für Attribut fehlt!
+#
+# 407
+#
+Verzeichnis "share" nicht gefunden!
+#
+# 408 409 410
+#
+Keine Daten für Zeichen gefunden!
+Keine Daten für Zeichen 0x
+ gefunden!
+#
+# 411
+#
+Encoding-Anforderungen stehen in Konflikt miteinander!
diff --git a/support/dktools/dktools/de/dk3bifa.str b/support/dktools/dktools/de/dk3bifa.str
new file mode 100644
index 0000000000..6f9ba33233
--- /dev/null
+++ b/support/dktools/dktools/de/dk3bifa.str
@@ -0,0 +1,42 @@
+#
+# 0
+#
+Bildanalyse: Originalbild ist farbig.
+#
+# 1
+#
+Bildanalyse: Originalbild is nicht farbig.
+#
+# 2
+#
+Bildanalyse: Ausgabe kann in grau erfolgen.
+#
+# 3
+#
+Bildanalyse: Ausgabe sollte farbig erfolgen.
+#
+# 4
+#
+Bildanalyse: Originalbild enthält Alphakanal.
+#
+# 5
+#
+Bildanalyse: Originalbild enthält keinen Alphakanal.
+#
+# 6
+#
+Bildanalyse: Alphakanal enthält Daten.
+#
+# 7
+#
+Bildanalyse: Alphakanal nicht erforderlich.
+#
+# 8 9
+#
+Bildanalyse: Originalbild hat Bitbreite
+.
+#
+# 10 11
+#
+Bildanalyse: Ausgabe sollte mit Bitbreite
+ erfolgen.
diff --git a/support/dktools/dktools/de/dk3bmeps.str b/support/dktools/dktools/de/dk3bmeps.str
new file mode 100644
index 0000000000..40c86e8e9c
--- /dev/null
+++ b/support/dktools/dktools/de/dk3bmeps.str
@@ -0,0 +1,254 @@
+#
+# 0: Simple newline.
+#
+\n
+#
+# 1: Space.
+#
+
+#
+# 2: Error: Output mode object requires ps or pdf output!
+#
+Inkonsistente Einstellungen!\nAusgabe-Modus "object" kann nur für "ps" oder "pdf" benutzt werden!
+#
+# 3: Error: Illegal driver number!
+#
+Unzulässige Treiber-Nummer!
+#
+# 4: Error: Illegal mode, must be a placed object!
+#
+Unzulässiger Ausgabe-Modus, nur "object" zulässig!
+#
+# 5: Error: Illegal mode, must not be a placed object!
+#
+Unzulässiger Ausgabe-Modus, platziertes Object nicht verwendbar!
+#
+# 6: Error: Illegal mode, must be image, object or document!
+#
+Inkonsistente Einstellungen!\nAusgabe-Modus muss "image", "object" oder "document sein!
+#
+# 7: Error: Illegal mode, must be image or object!
+#
+Inkonsistente Einstellungen!\nAusgabe-Modus muss "image" oder "object" sein!
+#
+# 8: Error: Driver bb can produce objects only!
+#
+Inkonsistente Einstellungen!\nDer Treiber "bb" kann nur den Ausgabe-Modus "object" verwenden!
+#
+# 9: Error: Illegal size mode specified!
+#
+Unzulässige Größeneinstellung!
+#
+# 10: Error: Size mode must be 1px=1pt for objects!
+#
+Inkonsistente Einstellungen!\nFür den Ausgabe-Modus "object" kann nur die Einstellung "1:1" benutzt werden!
+#
+# 11: Warning: Draft can not be used when producing document!
+#
+Im Ausgabe-Modus "document" kann "draft" nicht verwendet werden!
+#
+# 12/13: Error: Option string "..." too long!
+#
+Options-String zu lang:\n"
+"!
+#
+# 14: Error: Empty language and options string!
+#
+Konfigurations-Text ist leer!
+#
+# 15/16: Error: Illegal driver!
+#
+Unzulässiger Ausgabe-Treiber: "
+"!
+#
+# 17/18: Error: Illegal mode!
+#
+Unzulässiger Ausgabe-Modus: "
+"!
+#
+# 19: Error: Empty configuration string!
+#
+Konfigurations-Text ist leer!
+#
+# 20/21: Error: Configuration string "..." too long!
+#
+Konfigurations-Text zu lang:\n"
+"!
+#
+# 22/23: Error: Unknown configuration option name!
+#
+Unzulässiger Options-Name: "
+"!
+#
+# 24/25: Error: Not a number!
+#
+Keine Zahl: "
+"!
+#
+# 26: Error: PS level must be 2 or 3!
+#
+PS-Level muss 2 oder 3 sein!
+#
+# 27/28: Error: Not a boolean value!
+#
+Kein boolscher Wert: "
+"!
+#
+# 29/30: Error: Unknown predictor!
+#
+Unzulässiger Predictor: "
+"!
+#
+# 31: Error: Empty background specification string!
+#
+Hintergrund-Konfigurations-Text ist leer!
+#
+# 32/33: Error: Syntax error in background specification!
+#
+Syntax-Fehler in Hintergrundangabe: "
+"!
+#
+# 34: Error: Option needs an argument!
+#
+Argument für Option "size" fehlt!
+#
+# 35/36: Error: Illegal size argument!
+#
+Unzulässige Größenangabe: "
+"!
+#
+# 37: Error: Option needs an argument!
+#
+Argument für Option "paper" fehlt!
+#
+# 38: Error: Setting a paper size is only allowed for document!
+#
+Inkonsistente Einstellungen!\nEine Papiergröße kann nur im Ausgabe-Modus "document" benutzt werden.
+#
+# 39/40: Error: Paper size not found!
+#
+Kein Angaben zur Papiergröße "
+" gefunden!
+#
+# 41/42: Progress: Processing file "...".
+#
+Datei "
+" wird verarbeitet.
+#
+# 43/44: Progress: Finished file "...".
+#
+Datei "
+" wurde verarbeitet.
+#
+# 45/46: Progress: Destination file is up to date.
+#
+Datei "
+" muss nicht verarbeitet werden.
+#
+# 47: Progress: Reading image data.
+#
+Bild-Daten werden gelesen.
+#
+# 48: Progress: Analysing image.
+#
+Bild wird analysiert.
+#
+# 49: Answer: yes
+#
+ja
+#
+# 50: Answer: no
+#
+nein
+#
+# 51: Color indicated
+#
+Farbe angegeben:
+#
+# 52: Color found
+#
+Farbe gefunden:
+#
+# 53: Alpha indicated
+#
+Transparenz angegeben:
+#
+# 54: Alpha found
+#
+Transparenz gefunden:
+#
+# 55: Bits per component indicated
+#
+Bits pro Komponente angegeben:
+#
+# 56: Bits per component found
+#
+Bits pro Komponente gefunden:
+#
+# 57: Bits per component used
+#
+Bits pro Komponente benutzt:
+#
+# 58: ERROR: Error while writing data!
+#
+Fehler beim Schreiben!
+#
+# 59: ERROR: Failed to start encoded chunk
+#
+Fehler beim Komprimieren!
+#
+# 60: ERROR: Invalid paper setup
+#
+Fehlerhafte Einstellungen für Papierformat!
+#
+# 61: ERROR: Failed to read image data!
+#
+Bild-Daten konnten nicht gelesen werden!
+#
+# 62: ERROR: Incorrect page setup, borders larger than page!
+#
+Fehlerhafte Einstellungen für Papierformat, Ränder zu groß!
+#
+# 63/64: ERROR: File type "..." unknown!
+#
+Unbekannter Dateityp: "
+"!
+#
+# 65/66: ERROR: Illegal file type "..."!
+#
+Unzulässiger Dateityp: "
+"!
+#
+# 67: ERROR: No file type specified for standard input!
+#
+Dateityp muss angegeben werden, wenn Standardeingabe benutzt wird!
+#
+# 68: ERROR: Inconsistent options found in option check!
+#
+Bei der Überprüfung wurden inkonsistente Einstellungen gefunden!
+#
+# 69/70: ERROR: Failed to read image file "..."!
+#
+Bild-Datei konnte nicht eingelesen werden:\n"
+"!
+#
+# 71: ERROR: PDF writer failed to open a new page!
+#
+Bei der PDF-Erzeugung konnte keine neue Seite geöffnet werden!
+#
+# 72: ERROR: Failed to write PDF output to file!
+#
+PDF-Datei konnte nicht erzeugt werden!
+#
+# 73: ERROR: Failed to add image to PDF page!
+#
+Bild konnte nicht zu PDF-Seite hinzugefügt werden!
+#
+# 74/75: ERROR: Unknown output language "..."!
+#
+Unzulässiger Ausgabe-Treiber "
+"!
+#
+# 76: PROGRESS: Writing output.
+#
+Ausgabe wird erzeugt.
diff --git a/support/dktools/dktools/de/dk3fig.str b/support/dktools/dktools/de/dk3fig.str
new file mode 100644
index 0000000000..0c7592906d
--- /dev/null
+++ b/support/dktools/dktools/de/dk3fig.str
@@ -0,0 +1,45 @@
+#
+# 0: File name.
+#
+dk3fig.str
+#
+# 1: Syntax error in Fig input!
+#
+Syntax-Fehler in Fig-Datei!
+#
+# 2: Color redefinition!
+#
+Mehrfache Definition einer Farbe!
+#
+# 3: Math problem in arc calculation!
+#
+Mathematische Probleme bei Kreisbogen-Berechnung!
+#
+# 4: Object processing failed!
+#
+Objekt konnte nicht verarbeitet werden!
+#
+# 5: Arrowhead calculation failed!
+#
+Pfeilspitzen-Berechnung fehlgeschlagen!
+#
+# 6: Error while reading input file!
+#
+Fehler beim Lesen der Eingabedatei!
+#
+# 7: Color not found, using black as default color!
+#
+Farbe nicht gefunden, Schwarz als Standardfarbe wird benutzt!
+#
+# 8: Unknown object type!
+#
+Unbekannter Objekt-Typ!
+#
+# 9: Can not fill open graphics path!
+#
+Offener Graphikpfad kann nicht gefüllt werden.
+#
+# 10: Converted to closed graphics path for filling.
+#
+Umwandlung zu geschlossenem Graphikpfad für Füllung.
+
diff --git a/support/dktools/dktools/de/dk3print.str b/support/dktools/dktools/de/dk3print.str
new file mode 100644
index 0000000000..0ff1f4c530
--- /dev/null
+++ b/support/dktools/dktools/de/dk3print.str
@@ -0,0 +1,223 @@
+#
+# 0
+#
+DRUCKER:
+#
+# 1
+#
+PRIMÄRE KONFIGURATION:
+#
+# 2
+#
+SEKUNDÄRE KONFIGURATION:
+#
+# 3
+#
+Drucker-Typ:
+#
+# 4
+#
+Host:
+#
+# 5
+#
+Queue:
+#
+# 6
+#
+Port:
+#
+# 7
+#
+Verbindungs-Timeout:
+#
+# 8
+#
+Sende-Timeout:
+#
+# 9
+#
+Empfangs-Timeout:
+#
+# 10
+#
+PS-Level:
+#
+# 11
+#
+Standard:
+#
+# 12
+#
+SNMP-Host:
+#
+# 13
+#
+SNMP-Community:
+#
+# 14
+#
+SNMP-Version:
+#
+# 15
+#
+Verbindungsabbau:
+#
+# 16
+#
+unbekannt
+#
+# 17
+#
+Windows
+#
+# 18
+#
+Socket
+#
+# 19
+#
+LPD
+#
+# 20
+#
+LPRng
+#
+# 21
+#
+ja
+#
+# 22
+#
+nein
+#
+# 23 24 25 26
+#
+1
+2c
+2p
+3
+#
+# 27
+#
+Schließende eckige Klammer fehlt!
+#
+# 28 29
+#
+"
+" ist hier nicht erlaubt, nur "host" oder "printer"!
+#
+# 30
+#
+Name für Host oder Drucker fehlt!
+#
+# 31 32
+#
+Drucker "
+" existiert bereits!
+#
+# 33 34
+#
+Drucker-Alias "
+" existiert bereits!
+#
+# 35 36
+#
+Wertangabe erforderlich für "
+"!
+#
+# 37
+#
+Der Queue-Typ ist bereits konfiguriert!
+#
+# 38 39
+#
+Unbekannter Queue-Typ "
+"!
+#
+# 40 41
+#
+Hostname "
+" wird überschrieben!
+#
+# 42 43
+#
+Option "
+" mit diesem Drucker-Typ nicht nutzbar!
+#
+# 44 45
+#
+Queue-Name "
+" wird überschrieben!
+#
+# 46 47
+#
+Port-Nummer
+ wird überschrieben!
+#
+# 48
+#
+Zahlenbereichsüberlauf!
+#
+# 49 50
+#
+Fehlerhaftes PS-Level "
+", muss 2 oder 3 sein!
+#
+# 51 52
+#
+SNMP-Host "
+" wird überschrieben!
+#
+# 53 54
+#
+SNMP-Community "
+" wird überschrieben!
+#
+# 55
+#
+SNMP-Version wird überschrieben!
+#
+# 56 57
+#
+Unbekannte SNMP-Version "
+"!
+#
+# 58 59
+#
+Empfangs-Timeout "
+" wird überschrieben!
+#
+# 60 61
+#
+Sende-Timeout "
+" wird überschrieben!
+#
+# 62 63
+#
+Verbindungs-Timeout "
+" wird überschrieben!
+#
+# 64 65
+#
+Unbekannte Konfigurations-Option "
+"!
+#
+# 66 67
+#
+Druck-Host "
+" ist bereits definiert!
+#
+# 68 69
+#
+Druck-Host-Alias "
+" ist bereits definiert!
+#
+# 70 71
+#
+Encoding "
+" entspricht nicht dem LPD-Protokoll!
+#
+# 72
+#
+Konfigurationszeile außerhalb aller Scopes!
diff --git a/support/dktools/dktools/de/dk3wreg.str b/support/dktools/dktools/de/dk3wreg.str
new file mode 100644
index 0000000000..a8d2f37fa7
--- /dev/null
+++ b/support/dktools/dktools/de/dk3wreg.str
@@ -0,0 +1,82 @@
+#
+# 0
+#
+dk3wreg.str
+#
+# 1
+#
+Registry-Key konnte nicht geöffnet werden!
+#
+# 2, 3
+#
+Registry-Key konnte nicht geöffnet werden:\n"
+"!
+#
+# 4, 5, 6
+#
+Registry-Key konnte nicht geöffnet bzw. angelegt werden!
+Registry-Key konnte nicht geöffnet bzw. angelegt werden:\n"
+"!
+#
+# 7, 8, 9
+#
+Registry-Key konnte nicht geschlossen werden!
+Registry-Key konnte nicht geschlossen werden:\n"
+"!
+#
+# 10, 11, 12
+#
+Registry-Wert konnte nicht geschrieben werden!
+Registry-Wert konnte nicht geschrieben werden:\n"
+"!
+#
+# 13, 14, 15
+#
+Registry-Wert konnte nicht gelesen werden!
+Registry-Wert konnte nicht gelesen werden:\n"
+"!
+#
+# 16, 17, 18
+#
+Registry-Wert ist kein String!
+Registry-Wert ist kein String:\n"
+"!
+#
+# 19, 20, 21
+#
+Registry-Wert ist kein DWORD!
+Registry-Wert ist kein DWORD:\n"
+"!
+#
+# 22, 23, 24
+#
+Registry-Wert ist unvollständiges DWORD!
+Registry-Wert ist unvollständiges DWORD:\n"
+"!
+#
+# 25, 26, 27
+#
+Registry-Teilbaum konnte nicht gelöscht werden!
+Registry-Teilbaum konnte nicht gelöscht werden:\n"
+"!
+#
+# 28, 29, 30
+#
+Registry-Wert konnte nicht gelöscht werden!
+Registry-Wert konnte nicht gelöscht werden:\n"
+"!
+#
+# 31
+#
+String zu lang für Ziel-Puffer!
+#
+# 32
+#
+Expansion der Umgebungsvariablen gescheitert!
+#
+# 33
+#
+Das Programm wurde für ältere Windows-Versionen compiliert.\nDas Löschen von Registry-Keys ist daher nicht möglich!
+#
+#
+#
diff --git a/support/dktools/dktools/de/dk4dbia.str b/support/dktools/dktools/de/dk4dbia.str
new file mode 100644
index 0000000000..1b56c298b9
--- /dev/null
+++ b/support/dktools/dktools/de/dk4dbia.str
@@ -0,0 +1,40 @@
+#
+# 0 Error: Failed to open database
+#
+Datenbank konnte nicht geöffnet werden!
+#
+# 1
+#
+\nFehlerhafte Argumente an Funktion zum Öffnen übergeben.
+#
+# 2
+#
+\nDer Datenbank-Typ wird nicht unterstützt.
+#
+# 3
+#
+\nMathematischer Überlauf in Größenberechnung.
+#
+# 4
+#
+\nNicht ausreichend Hauptspeicher verfügbar.
+#
+# 5
+#
+\nSyntax-Fehler (Datenbank-Name, Dateityp oder Dateiinhalt).
+#
+# 6
+#
+\nBerechtigungen für Zugriff fehlt.
+#
+# 7
+#
+\nDatei konnte nicht zum Lesen geöffnet werden.
+#
+# 8
+#
+\nDatei konnte nicht zum Schreiben geöffnet werden.
+#
+# 9
+#
+\nSchließen der Datei schlug fehl.
diff --git a/support/dktools/dktools/de/dk4info.str b/support/dktools/dktools/de/dk4info.str
new file mode 100644
index 0000000000..5201c9959e
--- /dev/null
+++ b/support/dktools/dktools/de/dk4info.str
@@ -0,0 +1,15 @@
+#
+# 0 1 Used directories:
+#
+Benutzte Verzeichnisse:
+-----------------------
+#
+# 2 3 Configured at built time:
+#
+Beim Compilieren angegebene Verzeichnisse:
+------------------------------------------
+#
+# 4 5 Definitions
+#
+Compiler-Definitionen:
+----------------------
diff --git a/support/dktools/dktools/de/dk4info.txt b/support/dktools/dktools/de/dk4info.txt
new file mode 100644
index 0000000000..c8df17c4cc
--- /dev/null
+++ b/support/dktools/dktools/de/dk4info.txt
@@ -0,0 +1,40 @@
+
+BEZEICHNUNG
+
+dk4info - Informationen zur Konfiguration
+
+ÃœBERSICHT
+
+dk4info [-l]
+
+BESCHREIBUNG
+
+Das Programm gibt Informationen darüber aus, welche Verzeichnisse aktuell
+benutzt werden und welche Verzeichnisse beim Compilieren angegeben wurden.
+Mit der Option -l werden die beim Compilieren benutzten Konstanten mit
+ausgegeben.
+
+OPTIONEN
+
+-l Konstanten des Build-Vorgangs (Ergebnisse von configure) mit anzeigen.
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+AUTOR
+
+Dirk Krause
+
+GESCHICHTE
+
+COPYRIGHT UND LIZENZBESTIMMUNGEN
+
+Führen Sie
+ dk4info --license
+aus, um Lizenz-Informationen anzuzeigen.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/de/dk4uc2l.str b/support/dktools/dktools/de/dk4uc2l.str
new file mode 100644
index 0000000000..76047dfd4d
--- /dev/null
+++ b/support/dktools/dktools/de/dk4uc2l.str
@@ -0,0 +1,67 @@
+#
+# 0 Error: Syntax
+#
+Syntax-Fehler!\n\tHexadezimal-Zahl am Zeilenanfang erwartet!
+#
+# 1 Error: Syntax
+#
+Syntax-Fehler!\n\tHexadezimal-Zahl außerhalb des 32-Bit-Bereiches!
+#
+# 2 3 4 Error: Syntax-Fehler! Redefintion of character!
+#
+Syntax-Fehler!\n\tErneute Definition von
+!
+Syntax-Fehler! Erneute Definition für Zeichen!
+#
+# 5 Error: Failed to set up text processing!
+#
+Text-Datenstrom-Verarbeitung konnte nicht eingerichtet werden!
+#
+# 6 7 Error: Failed to open file for reading: ...
+#
+Datei konnte nicht zum Lesen geöffnet werden:\n\t"
+"!
+#
+# 8 Error: Syntax-Fehler!\n\tIllegal font encoding name!
+#
+Syntax-Fehler!\n\tUnzulässiger Name für Font-Encoding!
+#
+# 9 Error: Syntax-Fehler!\n\t1 to 15 packages names are allowed!
+#
+Syntax-Fehler!\n\t1 bis 15 Paket-Namen erlaubt!
+#
+# 10 Error: Syntax-Fehler!\n\tIllegal attribute name!
+#
+Syntax-Fehler!\n\tUnzulässiger Attribut-Name!
+#
+# 11 Error: Syntax-Fehler!\n\tAttribute specified without value!
+#
+Syntax-Fehler!\n\tAttributname ohne Wert!
+#
+# 12 13 14 Error: Conversion to UTF-8 failed for a character!
+#
+Zeichen 0x
+ konnte nicht nach UTF-8 codiert werden!
+Zeichen konnte nicht nach UTF-8 codiert werden!
+#
+# 15 Error: No directory for character mapping information found!
+#
+Verzeichnis mit Konvertierungs-Daten nicht gefunden!
+#
+# 16 ... 21 Error messages.
+#
+Decodierung fehlgeschlagen!\n\tByte:
+Codierung fehlgeschlagen!\n\tByte:
+Verarbeitung fehlgeschlagen!\n\tByte:
+,\n\tZeichen:
+,\n\tPosition in Zeile:
+.
+#
+# 22 ... 27 Error messages.
+#
+Decodierung fehlgeschlagen!
+Codierung fehlgeschlagen!
+Verarbeitung fehlgeschlagen!
+Weitere Decodierungs-Fehler!
+Weitere Codierungs-Fehler!
+Weitere Verarbeitungs-Fehler!
diff --git a/support/dktools/dktools/de/dkct.txt b/support/dktools/dktools/de/dkct.txt
new file mode 100644
index 0000000000..db3e177658
--- /dev/null
+++ b/support/dktools/dktools/de/dkct.txt
@@ -0,0 +1,94 @@
+
+BEZEICHNUNG
+
+ dkct - Dirk Krauses C-Tool
+
+ÃœBERSICHT
+
+ dkct [<Option>] [<Dateien>]
+
+BESCHREIBUNG
+
+Das Programm beinhaltet folgende Funktionalität:
+- Präprozessor für Debug-Anweisungen,
+- Code-Generator für Automaten.
+- Code-Generator für GUIs mit Nutzung der wxWidgets-Bibliothek.
+
+Das Programm verarbeitet *.ctr, *.cpt, *.mtr und *.jtr-Dateien und erzeugt
+daraus *.c, *.cpp, *.m und *.java-Dateien. Die Quelldateien können
+Debug-Anweisungen in einer speziellen Notation enthalten, diese werden
+beim Erstellen von Release-Versionen ignoriert, beim Erstellen von
+Debug-Versionen zu Ausgabeoperationen umgewandelt.
+
+OPTIONEN
+
+-R
+--reset
+ Alle Einstellungen aus Konfigurationsdateien ignorieren.
+
+-d
+--debug
+ Debug-Ausgabe erzeugen (Standard: Keine Debug-Ausgabe).
+
+-s
+--debug-stdout
+ Debug-Ausgabe nach stdout.
+
+-t
+--timestamp
+ Debug-Ausgabe enthält Zeitstempel.
+
+-k
+--trace-keyword
+ Debug-Ausgabe enthält "trace"-Zeichenkette.
+
+-w
+--windows-wide-char
+ Debug-Ausgabe vorbereiten für wchar_t.
+
+-p
+--portable-output
+ Debug-Code portabel gestalten (schließt -w mit ein).
+
+-l
+--line-numbers
+ Präprozessor-Direktiven "#line ..." in die Ausgabe schreiben.
+
+-m
+--make
+ Make mode: Zieldateien nur dann neu erzeugen, wenn erforderlich.
+
+-b <Weite>
+--box-width=<Weite>
+ Box-Weite für Kommentarboxen festlegen.
+
+-h
+--help
+ Hilfe-Text anzeigen.
+
+-v
+--version
+ Versionsnummer anzeigen.
+
+-L
+--license-terms
+ Lizenzbedingungen anzeigen.
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
+AUTOR
+
+Dirk Krause
+
+LIZENZBEDINGUNGEN
+
+Mit
+ dkct --license-terms
+können die Lizenzbedingungen angezeigt werden.
+
diff --git a/support/dktools/dktools/de/dkct3.str b/support/dktools/dktools/de/dkct3.str
new file mode 100644
index 0000000000..850d0134bf
--- /dev/null
+++ b/support/dktools/dktools/de/dkct3.str
@@ -0,0 +1,389 @@
+#
+# 0 / 1: Error: Not an input file (wrong suffix): "..."!
+#
+Keine Eingabedatei (falsche Endung): "
+"!
+#
+# 2 / 3: Error: Illegal type: "..."!
+#
+Unzulässiger Typ: "
+"!
+#
+# 4: Error: Copyright owner redefined!
+#
+Redefinition von "copyright owner"!
+#
+# 5: Error: Copyright year redefined!
+#
+Redefinition von "copyright year"!
+#
+# 6: Error: License redefined!
+#
+Redefinition der Lizenz!
+#
+# 7 / 8: Error: Unknown license type: "..."!
+#
+Unbekannter Lizenz-Typ: "
+"!
+#
+# 9: Error: Syntax error, value expected!
+#
+Syntax-Fehler - Wert fehlt!
+#
+# 10 / 11: Error: Syntax error, unknown option "..."!
+#
+Syntax-Fehler\nUnzulässige Option: "
+"!
+#
+# 12 / 13: Error: Output file name contains non-ASCII: "..."!
+#
+Dateiname mit Nicht-ASCII-Zeichen: "
+"!
+#
+# 14: Error: Missing file name!
+#
+Dateiname fehlt!
+#
+# 15: Error: Failed to open pipe: "..."!
+#
+Pipe kann nicht geöffnet werden für Kommando:\n"
+"!
+#
+# 17: Error: No popen() function available here!
+#
+Dieses System unterstützt keine Pipes!
+#
+# 18: Error: Problem while writing output!
+#
+Problem beim Schreiben der Ausgabe.
+#
+# 19: Error: Either macro= or prefix= allowed, not both!
+#
+Die Einstellungen macro= und prefix= sind exklusiv!
+#
+# 20 / 21: Error: Failed to open file "..."!
+#
+Datei "
+" konnte nicht geöffnet werden!
+#
+# 22: Error: Source line too long!
+#
+Eingabezeile zu lang!
+#
+# 23 / 24: Error: No such built-in function: "..."!
+#
+Eingebaute Funktion nicht vorhanden: "
+"!
+#
+# 25: Error: Missing function name!
+#
+Funktionsname fehlt!
+#
+# 26 / 27: Error: File name too long: "..."!
+#
+Dateiname zu lang: "
+"!
+#
+# 28: Error: Redefinition of state machine name!
+#
+Name der state machine mehrfach gesetzt!
+#
+# 29: Error: Not enough memory!
+#
+Zu wenig Speicher!
+#
+# 30: Error: Syntax error (boolean expected)!
+#
+Syntax-Fehler - Boolean erwartet!
+#
+# 31: Error: Syntax error (not a number)!
+#
+Syntax-Fehler - Zahlenwert erwartet!
+#
+# 32: Error: Redefinition of state, input, or output!
+#
+Zustand, Eingabe oder Ausgabe mehrfach definiert!
+#
+# 33: Error: Syntax error!
+#
+Syntax-Fehler!
+#
+# 34 / 35: Error: Undeclared state, input, or output: "..."!
+#
+Zustand, Eingabe oder Ausgabe nicht deklariert: "
+"!
+#
+# 36 / 39: Error: Conflict with previous rule (line ...)!
+#
+Konflikt mit vorheriger Regel (Zeile
+#
+# 37: Error: Syntax error (incomplete section name)!
+#
+Syntax-Fehler - Abschnittsname unvollständig!
+#
+# 38: Error: Numeric overflow!
+#
+Zahlenbereichsüberlauf!
+#
+# 39: End of message 36
+#
+)!
+#
+# 40: Error: No states declared!
+#
+Keine Zustände definiert!
+#
+# 41: Error: No inputs declared!
+#
+Keine Eingaben definiert!
+#
+# 42: Error: Not outputs declared!
+#
+Keine Ausgaben definiert!
+#
+# 43 / 44: Error: Syntax error (unknown header ...)!
+#
+Syntax-Fehler!\nUnbekannte Kopfzeile "
+"!
+#
+# 45: Error: Class name already set!
+#
+Syntax-Fehler - Klassenname bereits definiert!
+#
+# 46: Error: Missing window ID for object!
+#
+Window-ID für Objekt fehlt!
+#
+# 47: Error: Splitter window requires exactly 2 children!
+#
+wxSplitterWindow muss genau 2 Kinder haben!
+#
+# 48: Error: Container element has no contents!
+#
+Inhalt für Container fehlt!
+#
+# 49: Error: Missing text attribute for object!
+#
+Attribut "text" fehlt!
+#
+# 50: Error: Grid setup invalid or missing for object!
+#
+Gitter ist nicht oder fehlerhaft konfiguriert!
+#
+# 51: Error: Missing bitmap attribute for object!
+#
+Attribut "bitmap" fehlt!
+#
+# 52: Error: Missing or invalid choices attribute for object!
+#
+Attribut "choices" fehlt bzw. ist fehlerhaft gesetzt!
+#
+# 53: Error: Missing or invalid size attribute for object!
+#
+Attribut "size" fehlt bzw. ist fehlerhaft gesetzt!
+#
+# 54: Error: Missing rows or columns attribute for radio box!
+#
+Attribut "rows" bzw. "columns" fehlt!
+#
+# 55: Warning: Attribute ignored (usable for root object only)!
+#
+Attribut wird ignoriert (nur für Top-Level-Element vorgesehen)!
+#
+# 56: Warning: Attribute ignored (not applicable to this class)!
+#
+Attribut wird ignoriert (für diese Klasse nicht vorgesehen)!
+#
+# 57: Error: Not enough memory!
+#
+Zu wenig Speicher!
+#
+# 58: Error: Syntax error - Missing object name!
+#
+Syntax-Fehler - Objekt-Name fehlt!
+#
+# 59: Error: Syntax error - Missing closing bracket!
+#
+Syntax-Fehler - "]" fehlt!
+#
+# 60: Error: Syntax error - Redefinition of id!
+#
+Attribut "id" wird überschrieben!
+#
+# 61: Error: Syntax error - ID undefined!
+#
+Attribut "id" fehlt!
+#
+# 62: Error: Syntax error - Redefinition of text!
+#
+Attribut "text" wird überschrieben!
+#
+# 63: Error: Syntax error - Unknown top level window type!
+#
+Syntax-Fehler - Unbekannter Typ für Top-Level-Element!
+#
+# 64/65: Error: Syntax error - Not a numeric value: "...."!
+#
+Syntax-Fehler!\nKein Zahlenwert: "
+"!
+#
+# 66: Error: Syntax error - Empty line!
+#
+Syntax-Fehler - Leerzeile!
+#
+# 67: Error: Syntax error!
+#
+Syntax-Fehler!
+#
+# 68: Error: Syntax error - No current element yet!
+#
+Syntax-Fehler - Kein aktuelles Element!
+#
+# 69: Error: Syntax error - Missing value!
+#
+Syntax-Fehler - Wert fehlt!
+#
+# 70: Error: Syntax error - Not a boolean value!
+#
+Syntax-Fehler - Kein Boolean-Wert!
+#
+# 71: Error: Syntax error - Empty ID!
+#
+Syntax-Fehler - Attribut "id" fehlt!
+#
+# 72: Error: Syntax error - Only one direction allowed here!
+#
+Syntax-Fehler - Nur eine Richtung erlaubt!
+#
+# 73: Error: Syntax error - Not a direction!
+#
+Syntax-Fehler - Richtungsangabe fehlt!
+#
+# 74/75: Warning: Attribute redefinition discards previous value!
+#
+Attribut-Neudefinition, der alte Wert "
+" wird verworfen!
+#
+# 76/77: Error: Unknown keyword "..."!
+#
+Syntax-Fehler!\n"
+" ist hier nicht zulässig!
+#
+# 78: Error: Missing class name for object!
+#
+Syntax-Fehler - Klassenname für Objekt fehlt!
+#
+# 79: Error: Dependency loop detected!
+#
+Syntax-Fehler - Abhängigkeits-Schleife!
+#
+# 80: Warning: Constructor specified, not recommended for this class!
+#
+Konstruktor-Angabe für diese Klasse nicht empfohlen!
+#
+# 81: ERROR: Don't know how to add object to parent!
+#
+Syntax-Fehler - Objekt kann nicht in Elternobjekt eingefügt werden!
+#
+# 82/83: Error: Number out of range: "..."!
+#
+Syntax-Fehler!\nNicht im erlaubten Bereich: "
+"!
+#
+# 84/85/86: Error: Can't add object "..." to parent object "..."!
+#
+Syntax-Fehler!\nObjekt "
+" kann nicht zu Elternobjekt "
+" hinzugefügt werden!
+#
+# 87: UNUSED Object/class name: Not specified.
+#
+
+#
+# 88/89/90: Illegal parent/child class combination: ".../..."!
+#
+Syntax-Fehler!\nUnzulässige Eltern/Kind-Kombination: "
+/
+"!
+#
+# 91: Error: Missing name for parent object!
+#
+Syntax-Fehler - Name für Elternobjekt fehlt!
+#
+# 92: Error: Missing parent object!
+#
+Syntax-Fehler - Elternobjekt fehlt!
+#
+# 93/94: Error: Syntax error - Missing class name for object "..."!
+#
+Syntax-Fehler!\nKlassenname für Objekt "
+" fehlt!
+#
+# 95/96: Warning: Redeclaration of object "..."!
+#
+Neudeklaration für Objekt "
+"!
+#
+# 97: Error: Root element must have exactly one sizer as contents!
+#
+Das Top-Level-Window muss genau einen Sizer haben!
+#
+# 98: Error: Command too long
+#
+Kommando zu lang!
+#
+# 99/100: Error: Illegal section name for state machine "..."!
+#
+Unzulässiger Abschnitt "
+"!
+#
+# 101: Error: File name too long in trace function!
+#
+Zu langer Dateiname in trace-Funktion!
+#
+# 102/103: Error: File name "..." contains non-ASCII-characters!
+#
+Dateiname "
+" enthält Nicht-ASCII-Zeichen!
+#
+# 104: Error: Pipe startet but not processing current directory!
+#
+Pipe-Befehl, aber nicht im aktuellen Verzeichnis!
+#
+# 105: Progress message: All output files up to date.
+#
+Alle Ausgabedateien sind aktuell.
+#
+# 106: Progress message: Start processing.
+#
+Verarbeitung beginnt.
+#
+# 107: Progress message: Processing finished.
+#
+Verarbeitung abgeschlossen.
+#
+# 108/109: Progress message: Writing file "...".
+#
+Datei "
+" wird geschrieben.
+#
+# 110/111: Progress message: File "..." is up to date.
+#
+Datei "
+" ist aktuell.
+#
+# 112: Error: Sizes must not be negative!
+#
+Größenangaben können nicht negativ sein!
+#
+# 113: Warning: Coypright time does not end in current year!
+#
+Copyright-Zeitraum endet nicht in aktuellem Jahr!
+#
+# 114: Warning: Preprocessor directives in $!text section with file=...
+#
+Präprozessor-Direktive in $!text mit file=...!
+#
+# 115: Warning: Redefinition of tooltip flag!
+#
+Neudefinition von "tooltip flag"!
diff --git a/support/dktools/dktools/de/dkdbtool.str b/support/dktools/dktools/de/dkdbtool.str
new file mode 100644
index 0000000000..8719a0a33f
--- /dev/null
+++ b/support/dktools/dktools/de/dkdbtool.str
@@ -0,0 +1,95 @@
+#
+# 0
+#
+Die folgenden Datenbank-Typen werden unterstützt:
+#
+# 1
+#
+mem Hauptspeicher-Datenbank des dktools-Projektes.
+#
+# 2
+#
+bdb Berkeley DB: Toolkit zur Programmierung eingebetteter Datenbanken
+#
+# 3
+#
+NDBM NDBM-Datenbank.
+#
+# 4: Error message: Missing dkdbt command!
+#
+Kommando für dkdbt fehlt!\n"dkdbt help" zeigt die verfügbaren Kommandos an.
+#
+# 5/6: Error message: Unknown command "..."!
+#
+Unzulässiges Kommando: "
+"!"dkdbt help" zeigt die verfügbaren Kommandos an.
+#
+# 7/8: Error message: Failed to expand file name pattern "..."!
+#
+Das Dateinamen-Muster "
+" kann nicht aufgelöst werden!
+#
+# 9: Error message: No input files found!
+#
+Keine Eingabedateien gefunden!
+#
+# 10: Error message: Wrong file type!
+#
+Unzulässiger Dateityp!
+#
+# 11: Error message: Error in SQL input!
+#
+Fehler in der SQL-Eingabe!
+#
+# 12: Error message: Error while traversing data!
+#
+Beim Durchsuchen der Datensätze traten Fehler auf!
+#
+# 13: Error message: Key data is no text!
+#
+Nicht-Text-Daten in Datensatz-Schlüssel!
+#
+# 14: Error message: Value data is no text!
+#
+Nicht-Text-Daten in Datensatz-Wert!
+#
+# 15: Error message: Failed to print key!
+#
+Schlüssel konnte nicht ausgegeben werden!
+#
+# 16: Error message: Failed to print space!
+#
+Leerzeichen konnte nicht ausgegeben werden!
+#
+# 17: Error message: Failed to print value!
+#
+Wert konnte nicht ausgegeben werden!
+#
+# 18: Error message: Failed to print newline!
+#
+Newline konnte nicht ausgegeben werden!
+#
+# 19: Error message: Missing destination database name!
+#
+Datenbank-Dateiname für die Zieldatenbank fehlt!
+#
+# 20: Error message: Errors occured while processing input!
+#
+Fehler bei der Eingabe-Verarbeitung!
+#
+# 21: Error message: Input and output database file name required!
+#
+Dateinamen für Quell- und Zieldatenbank werden benötigt!
+#
+# 22: Error message: Missing input file name!
+#
+Dateiname für Quelldatenbank fehlt!
+#
+# 23: Error message: Missing output file name!
+#
+Dateiname für Zieldatenbank fehlt!
+#
+# 24: Error message: Error(s) occured while copying data!
+#
+Fehler beim Kopieren der Daten!
+
diff --git a/support/dktools/dktools/de/dkdbtool.txt b/support/dktools/dktools/de/dkdbtool.txt
new file mode 100644
index 0000000000..5772d4b94c
--- /dev/null
+++ b/support/dktools/dktools/de/dkdbtool.txt
@@ -0,0 +1,111 @@
+
+BEZEICHNUNG
+
+ dkdbt - Dirk Krauses Datenbank-Tool
+
+
+ÃœBERSICHT
+
+ dkdbt copy [-a] <Quelldatenbank> <Zieldatenbank>
+ dkdbt make [-c <Zeichen>] [-a] [-i <Encoding>] <Zieldatenbank> [<Datei(en)>]
+ dkdbt text [-o <Encoding>] <Quelldatenbank> [<Datei>]
+ dkdbt split-sql-lines [<Eingabedatei> [<Ausgabedatei>]]
+
+ dkdbt help
+ dkdbt version
+ dkdbt license
+ dkdbt features
+
+BESCHREIBUNG
+
+Die copy-Operation erzeugt eine neue Kopie einer Datenbank, auf Wunsch
+mit einem anderen Datenbank-Typ. Standardmäßig wird die Zieldatenbank
+als leere Datenbank geöffnet, d.h. bestehender Inhalt der Zieldatenbank
+wird gelöscht. Damit erhält die Zieldatenbank exakt die gleichen Datensätze
+wie die Quelldatenbank.
+Mit der Option -a (add - hinzufügen) werden die evtl. bereits vorhandenen
+Datensätze zunächst beibehalten. Die in der Quelldatenbank vorhandenen
+Datensätze werden genutzt, um Datensätze der Zieldatenbank zu ändern bzw. neue
+Datensätze einzufügen.
+
+Die make-Operation erzeugt eine Datenbank aus einer Texteingabe.
+Jede Zeile der Texteingabe enthält einen Datensatz. Das erste Text-Wort in der
+Zeile ist der Datenbankschlüssel, der restliche Text beginnend mit dem
+zweiten Text-Wort ist der Wert.
+Mit der Option -c (comment - Kommentar) kann ein Zeichen angegeben werden, das
+Zeilenkommentare einleitet. Alle Zeilen, die mit diesem Zeichen beginnen,
+werden als Kommentare behandelt.
+Mit der Option -i (input encoding - Eingabe-Codierung) kann das
+Eingabe-Encoding angegeben werden.
+Nach dem Namen der Zieldatenbank können optional Dateinamen für Eingabedateien
+angegeben werden. Werden keine Dateinamen angegeben, wird die Standardeingabe
+verarbeitet.
+Mit der Option -a (add - hinzufügen) werden die evtl. bereits vorhandenen
+Datensätze zunächst beibehalten. Die in der Quelldatenbank vorhandenen
+Datensätze werden genutzt, um Datensätze der Zieldatenbank zu ändern bzw. neue
+Datensätze einzufügen.
+
+Die text-Operation kehrt die make-Operation um, d.h. der Inhalt einer
+Datenbank wird als Text ausgegeben.
+Mit der Option -o (output encoding - Ausgabe-Codierung) kann ein
+Zeichenencoding für die Ausgabe festgelegt werden.
+
+Die split-sql-lines-Operation splittet überlange Zeilen in der Ausgabe von
+mysqldump in mehrere Zeilen.
+
+Die help-Operation zeigt diesen Hilfetext.
+
+Die version-Operation zeigt die Versionsnummer.
+
+Die license-Operation zeigt die Lizenzbedingungen.
+
+Die features-Operation zeigt an, welche Datenbank-Typen vom Programm
+unterstützt werden.
+
+OPTIONEN
+
+-a
+ Datensätze zur Zieldatenbank hinzufügen, falls die Zieldatenbank
+ bereits existiert. Ohne die Option -a wird die Zieldatenbank neu angelegt,
+ dabei gehen evtl. bereits vorhandene Datensätze verloren.
+
+
+-c <Zeichen>
+ Kommentarzeichen. Zeilen, die mit diesem Zeichen beginnen,
+ werden als Kommentar behandelt.
+
+
+-i <Encoding>
+ Erwartete Standard-Zeichencodierung für die Eingabe.
+
+
+-o <Encoding>
+ Zeichencodierung für die Ausgabe.
+
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+DATEIEN
+
+Die Eingabedatei für "dkdbt make" enthält pro Zeile einen Datensatz.
+Das erste Textwort in der Zeile ist der Datensatz-Schlüssel (bzw. Name).
+Durch eine Folge von Leerzeichen und/oder Tabulatoren ist der Wert abgetrennt.
+Der Wert beginnt mit dem ersten Textzeichen und erstreckt sich bis zum
+Ende der Zeile (Newline oder Zeilenvorschub).
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
+AUTOR
+
+Dirk Krause
+
+LIZENZBEDINGUNGEN
+
+Mit
+ dkdbt -L
+werden die Lizenzbedingungen angezeigt.
+
diff --git a/support/dktools/dktools/de/dknet4.str b/support/dktools/dktools/de/dknet4.str
new file mode 100644
index 0000000000..45321b5935
--- /dev/null
+++ b/support/dktools/dktools/de/dknet4.str
@@ -0,0 +1,217 @@
+#
+# 0: File name <<standard input>> used if no file name specified
+#
+<<Standardeingabe>>
+#
+# 1/2: Progress message: Retrieving IP address for host "...".
+#
+Suche IP-Adresse für "
+".
+#
+# 3/4: Error: Host not found: "..."!
+#
+Keine IP-Adresse gefunden für: "
+"!
+#
+# 5: Progress message: Socket created.
+#
+Socket wurde erstellt.
+#
+# 6: Progress message: Local address bound.
+#
+Lokale Adresse erhalten.
+#
+# 7: Progress message: Listening for connection requests.
+#
+Warte auf Verbindungsanfragen.
+#
+# 8: Progress message: Waiting for next client to connect.
+#
+Warte auf Verbindungsanfrage vom nächsten Client.
+#
+# 9: Progress message: Initial data contains start command.
+#
+Start-Kommando erhalten.
+#
+# 10: Progress message: Initial data was read.
+#
+Verbindungsaufbau mit Client erfolgreich.
+#
+# 11: Error: Failed to read initial data!
+#
+Verbindungsaufbau mit Client fehlgeschlagen!
+#
+# 12: Progress message: Maximum number of clients reached.
+#
+Es sind alle Clients verbunden.
+#
+# 13: Error: Error while accepting next client!
+#
+Fehler in Systemfunktion beim Akzeptieren von Clients!
+#
+# 14: Error: Failed to listen for client connection requests!
+#
+Socket konnte nicht als Serversocket konfiguriert werden!
+#
+# 15: Progress message: Starting data transfer.
+#
+Beginn des Datentransfers.
+#
+# 16: Progress message: Data transfer finished.
+#
+Ende des Datentransfers.
+#
+# 17: Progress message: Releasing all connections.
+#
+Verbindungen werden geschlossen.
+#
+# 18: Progress message: Finished.
+#
+Fertig.
+#
+# 19: Error: Failed to bind local port!
+#
+Lokale Adresse nicht verfügbar!
+#
+# 20: Error: Failed to create socket!
+#
+Socket konnte nicht erstellt werden!
+#
+# 21: Progress message: Input file opened.
+#
+Eingabedatei geöffnet.
+#
+# 22: Progress message: Transferring data from standard input.
+#
+Standardeingabe wird verwendet.
+#
+# 23: Error: No port number specified!
+#
+Angabe zur Port-Nummer fehlt!
+#
+# 24: Error: Failed to receive data from sender!
+#
+Datenempfang fehlgeschlagen!
+#
+# 25: Progress message: End of data transfer.
+#
+Ende des Datentransfers.
+#
+# 26/27: Progress message: Output file "..." opened.
+#
+Ausgabedatei "
+" geöffnet.
+#
+# 28: Progress message: Writing output to standard output.
+#
+Standardausgabe wird verwendet.
+#
+# 29: Progress message: Connection established.
+#
+Verbindung hergestellt.
+#
+# 30: Progress message: Initial data was sent.
+#
+Verbindungsaufbau erfolgreich-
+#
+# 31: Error: Sender port not configured!
+#
+Sender-Portnummer fehlt!
+#
+# 32: Error: Sender host unknown!
+#
+Sender-Host fehlt!
+#
+# 33: Error: Range overflow in port number!
+#
+Bereichsüberlauf bei Port-Nummer!
+#
+# 34: Error: Illegal number of clients, must be non-negative!
+#
+Unzulässige Client-Anzahl, darf nicht negativ sein!
+#
+# 35: Error: Option -s requires an argument!
+#
+Die Option -s erfordert ein Argument!
+#
+# 36: Error: Option -r requires an argument!
+#
+Die Option -r erfordert ein Argument!
+#
+# 37: Error: Option -a requires an argument!
+#
+Die Option -a erfordert ein Argument!
+#
+# 38: Error: Option -c requires an argument!
+#
+Die Option -c erfordert ein Argument!
+#
+# 39/40: Error: Illegal option "-..."!
+#
+Unzulässige Option "-
+"!
+#
+# 41: Error: Only one file name allowed!
+#
+Es darf nur ein Dateiname angegeben werden!
+#
+# 42: Progress message: Command line processing finished.
+#
+Kommandozeilen-Argumente wurden verarbeitet.
+#
+# 43: Error: Options -r and -s are exclusive!
+#
+Die Optionen -r und -s schließen einander aus!
+#
+# 44: Error: At least one option from -r, -s, -h, or -v is required!
+#
+Mindestens eine der Optionen -r, -s, -h oder -v muss angegeben werden!
+#
+# 45: Progress message: Windows sockets initialized.
+#
+Windows-Sockets initialisiert.
+#
+# 46: Error: Failed to initialize Windows sockets!
+#
+Die Windows-Sockets konnten nicht initialisiert werden!
+#
+# 47/48: Progress message: IP address found: ...
+#
+IP-Adresse gefunden:
+.
+#
+# 49/50: Progress message: Connection accepted from: ...
+#
+Verbindung akzeptiert:
+.
+#
+# 51/52: Warning: Connection refused from: ...
+#
+Verbindung zurückgewiesen:
+.
+#
+# 53/54: Error: Failed to send data to ..., disconnected!
+#
+Fehler beim Senden an
+, Verbindung beendet!
+#
+# 55/56: Progress message: Releasing connection to ...
+#
+Verbindungsabbau:
+.
+#
+# 57/58: Progress message: Connecting to host ...
+#
+Verbindungsaufbau:
+.
+#
+# 59/60: Error: Failed to connect to: ...
+#
+Verbindungsaufbau fehlgeschlaagen:
+!
+#
+# 61/62: Error: Not an IP netmask: "..."!
+#
+Keine IP-Netzmaske: "
+"!
+
diff --git a/support/dktools/dktools/de/dknet4.txt b/support/dktools/dktools/de/dknet4.txt
new file mode 100644
index 0000000000..01e18d59ed
--- /dev/null
+++ b/support/dktools/dktools/de/dknet4.txt
@@ -0,0 +1,70 @@
+
+BEZEICHNUNG
+
+ dknet4 - Datentransfer über Netzwerk (nur mit IPv4)
+
+ÃœBERSICHT
+
+ dknet4 -s <Port> [-c <Anzahl>] [-a <Adresse>[/<Maske>]] [<Datei>]
+ dknet4 -r <Host>:<Port> [-t] [<Datei>]
+
+BESCHREIBUNG
+
+Das Programm überträgt Daten über das Netzwerk von einem Sender zu einem
+oder mehreren Empfängern. Das Programm ist beschränkt auf IPv4, dafür
+aber auch auf älteren Systemen compilierbar und lauffähig.
+Für IPv6 verwenden Sie bitte dknet.
+
+OPTIONEN
+
+-s <Port>
+ Sender-Modus, legt den Port fest, an dem der Sender auf
+ eingehende Verbindungsanfragen wartet.
+
+-c <Anzahl>
+ Maximale Anzahl von Clients (Standardwert: 1).
+ Wird 0 angegeben, ist die Client-Anzahl unlimitiert. In diesem Fall
+ muss für den letzten Client die Option -t verwendet werden, um die
+ Ãœbertragung zu starten.
+
+-a <Adresse>[/<Maske>]
+ Client-Adressen auf den angegebenen IP-Adressbereich beschränken.
+ Angegeben werden hier eine IP-Adresse und die zugehörige Netzmaske,
+ beide jeweils dargestellt durch 4 Dezimalzahlen, die durch Punkte
+ getrennt sind, z.B. "192.168.113.0/255.255.255.0".
+ Wird die Option -a nicht verwendet, dürfen sich beliebige Clients mit
+ dem Sender verbinden.
+
+-r <Host>:<Port>
+ Empfänger-Modus, Angabe, mit welchem Sender eine
+ Verbindung hergestellt werden soll. Für den Sender müssen
+ Hostname bzw. IP-Adresse und Portnummer angegeben werden.
+
+-t
+ Ãœbertragung starten, dazu dem Server mitteilen, dass der letzte Client
+ verbunden wurde.
+
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+AUTOR
+
+Dirk Krause
+
+GESCHICHTE
+
+Das Programm dknet4 ersetzt das Programm tcptool aus vorherigen Versionen
+von dktools.
+
+LIZENZBEDINGUNGEN
+
+Ein Aufruf von
+ xxx --license-terms
+zeigt die Lizenzbedingungen an.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/de/dkwt-boot.txt b/support/dktools/dktools/de/dkwt-boot.txt
new file mode 100644
index 0000000000..30f0d2ace4
--- /dev/null
+++ b/support/dktools/dktools/de/dkwt-boot.txt
@@ -0,0 +1,55 @@
+
+BEZEICHNUNG
+
+ dkwt boot - Aufräumen im System-Boot-Script
+
+ÃœBERSICHT
+
+ dkwt boot [-t]
+
+BESCHREIBUNG
+
+Ein Aufruf von "dkwt boot" kann in das System-Boot-Script von PCs in
+PC-Klassen eingetragen werden. Dies bewirkt ein automatisches Bereinigen
+beim Booten.
+
+OPTIONEN
+
+-t
+ Test-Mode, keine Dateien oder Verzeichnisse löschen. Nur Meldungen
+ ausgegeben, welche Dateien oder Verzeichnisse beim Bereinigen gelöscht
+ würden.
+
+EXIT-STATUS
+
+Es wird immer 0 zurückgegeben, unabhängig von evtl. aufgetretenen Fehlern.
+
+DATEIEN
+
+dkwt.conf
+ Die Datei dkwt.conf enthält die Konfigurationsangaben zum automatischen
+ Bereinigen des PCs.
+ Verwenden Sie
+ dkwt help
+ um nähere Informationen über diese Konfigurationsdatei zu erhalten.
+
+BEMERKUNGEN
+
+Nach Änderungen an dkwt.conf sollte
+ dkwt boot -t
+verwendet werden, um die Einstellungen zu prüfen.
+
+AUTOR
+
+Dirk Krause
+
+LIZENZBEDINGUNGEN
+
+Ein Aufruf von
+ dkwt --license-terms
+zeigt die Lizenzbedingungen an.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/de/dkwt-clp.txt b/support/dktools/dktools/de/dkwt-clp.txt
new file mode 100644
index 0000000000..8639bbd4be
--- /dev/null
+++ b/support/dktools/dktools/de/dkwt-clp.txt
@@ -0,0 +1,44 @@
+
+BEZEICHNUNG
+
+ dkwt cleanup-profiles - Benutzerprofile bereinigen.
+
+ÃœBERSICHT
+
+ dkwt cleanup-profiles
+ dkwt clp
+
+BESCHREIBUNG
+
+Unter Windows Vista and Nachfolgerversionen laufen die Skripte zum
+Hoch- und Herunterfahren sowie beim Ein- und Ausloggen unter einem
+Benutzeraccount, dessen Berechtigungen kein Bereinigen fremder Benutzer-
+profile erlauben.
+
+Daher muss hier eine Eingabeaufforderung *als Administrator* gestartet
+werden, in dieser kann dann "dkwt cleanup-profiles" gestartet werden.
+
+Das Programm verwendet zum Löschen von Verzeichnissen zunächst System-
+funktionen und ruft dann nochmals das Kommando "RD" auf.
+
+Die Datei dkwt.conf enthält Angaben, wo Benutzerprofile gespeichert werden
+und welche Profile beim Bereinigen nicht gelöscht werden sollen.
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+AUTOR
+
+Dirk Krause
+
+LIZENZBEDINGUNGEN
+
+Ein Aufruf von
+ dkwt --license-terms
+zeigt die Lizenzbedingungen an.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/de/dkwt-env.txt b/support/dktools/dktools/de/dkwt-env.txt
new file mode 100644
index 0000000000..db8996f59a
--- /dev/null
+++ b/support/dktools/dktools/de/dkwt-env.txt
@@ -0,0 +1,117 @@
+
+BEZEICHNUNG
+
+ dkwt env - Umgebungsvariablen bearbeiten
+
+ÃœBERSICHT
+
+ dkwt env [<Option(en)>] <Name> [<Wert>]
+ dkwt environment [<Option(en)>] <Name> [<Wert>]
+
+BESCHREIBUNG
+
+Diese Funktion bearbeitet Umgebungsvariablen, sowohl in der Systemumgebung
+als auch in der Umgebung des aktuellen Nutzers.
+Der Fokus liegt auf Variablen, die Datei- oder Verzeichnisnamen speichern
+wie z.B. PATH.
+Mit den Optionen -i oder -a kann sichergestellt werden, dass eine solche
+Variable ein bestimmtes Verzeichnis bzw. eine bestimmte Datei enthält.
+Der Pfad wird nur hinzugefügt, falls er noch nicht im Variablenwert
+aufgeführt ist.
+
+OPTIONEN
+
+-s
+ Systemumgebung bearbeiten.
+ Ohne diese Option wird die Umgebung des aktuellen Nutzers bearbeitet.
+
+-e
+ REG_EXPAND_SZ anstelle von REG_SZ für neue Registry-Einträge verwenden.
+ Beim Bearbeiten bestehender Registry-Einträge wird diese Option
+ ignoriert.
+
+-u
+ Registry-Eintrag für Variable komplett löschen.
+
+-i
+ Einfügen, falls Wert noch nicht enthalten.
+ Falls die Variable den angegebenen Wert (Verzeichnis- oder
+ Dateiname) noch nicht enthält, wird er am Beginn des Wertes
+ eingefügt.
+
+-a
+ Anhängen, falls Wert noch nicht enthalten.
+ Falls die Variable den angegebenen Wert (Verzeichnis- oder
+ Dateiname) noch nicht enthält, wird er am Ende des Wertes angehangen.
+
+-d
+ Pfad (Verzeichnis- oder Dateiname) aus Variable entfernen.
+ Falls der Wert der Variable dadurch leer wird, wird die
+ Variable komplett gelöscht.
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+BEISPIELE
+
+Wert der Variable TEMP aus der Nutzerumgebung anzeigen:
+
+ dkwt env TEMP
+
+Wert der Variable PATH aus der Systemumgebung anzeigen:
+
+ dkwt env -s PATH
+
+Variable FOO aus der Nutzerumgebung löschen:
+
+ dkwt env -u FOO
+
+Variable BAR aus der Systemumgebung löschen:
+
+ dkwt env -s -u BAR
+
+Variable FOO in der Nutzerumgebung setzen:
+
+ dkwt env FOO Alles nach dem Namen ist der neue Wert
+
+Variable BAR in der Systemumgebung setzen:
+
+ dkwt env -s BAR Und dies gilt fuer Systemvariablen genau so
+
+Sicherstellen, dass Variable PATH in der Systemumgebung das Verzeichnis
+"C:\Program Files\Tolles Programm" enthält (am Beginn einfügen, falls
+noch nicht enthalten):
+
+ dkwt env -s -i Path C:\Program Files\Tolles Programm
+
+Sicherstellen, dass dass Variable PATH in der Systemumgebung das Verzeichnis
+"C:\Program Files\Noch ein Programm" enthält (am Ende anhängen, falls noch
+nicht enthalten):
+
+ dkwt env -s -a Path C:\Program Files\Noch ein Programm
+
+Verzeichnis "C:\Program Files\Tolles Programm" aus System-Variable PATH
+entfernen:
+
+ dkwt env -s -d Path C:\Program Files\Tolles Programm
+
+BEMERKUNGEN
+
+Mit "dkwt env" durchgeführte Operationen wirken sich nicht auf bereits
+geöffnete Eingabeaufforderungs-Fenster aus.
+
+AUTOR
+
+Dirk Krause
+
+LIZENZBEDINGUNGEN
+
+Ein Aufruf von
+ dkwt --license-terms
+zeigt die Lizenzbedingungen an.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/de/dkwt-groups.txt b/support/dktools/dktools/de/dkwt-groups.txt
new file mode 100644
index 0000000000..d2cbbda4d8
--- /dev/null
+++ b/support/dktools/dktools/de/dkwt-groups.txt
@@ -0,0 +1,41 @@
+
+BEZEICHNUNG
+
+ dkwt groups - Gruppen auflisten
+
+ÃœBERSICHT
+
+ dkwt groups [<Option>]
+
+BESCHREIBUNG
+
+Das Kommando listet die im System eingerichteten Gruppen auf.
+
+OPTIONEN
+
+-l
+ Langes (ausführliches) Listing erstellen.
+
+-s
+ Kurzes Listing erstellen (nur die Gruppennamen).
+
+Die Optionen -l und -s können nicht gleichzeitig verwendet werden.
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+AUTOR
+
+Dirk Krause
+
+LIZENZBEDINGUNGEN
+
+Ein Aufruf von
+ dkwt --license-terms
+zeigt die Lizenzbedingungen an.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/de/dkwt-help.txt b/support/dktools/dktools/de/dkwt-help.txt
new file mode 100644
index 0000000000..ab50d7ced0
--- /dev/null
+++ b/support/dktools/dktools/de/dkwt-help.txt
@@ -0,0 +1,202 @@
+
+BEZEICHNUNG
+
+ dkwt - Dirk Krauses Windows-Tool
+
+ÃœBERSICHT
+
+ dkwt users [<Option(en)>]
+ dkwt groups [<Option(en)>]
+ dkwt printers [<Option(en)>]
+ dkwt print [<Option(en)>] [<Datei(en)>]
+ dkwt boot
+ dkwt login
+ dkwt logout
+ dkwt shutdown
+ dkwt cleanup-profiles
+ dkwt keep
+ dkwt unkeep
+ dkwt env [<Option(en)>] <Name> [<Wert>]
+ dkwt help <Kommando>
+ dkwt -h
+ dkwt -v
+ dkwt -L
+
+BESCHREIBUNG
+
+dkwt users Nutzer anzeigen.
+dkwt groups Gruppen anzeigen.
+dkwt printers Drucker anzeigen.
+dkwt print Datei drucken.
+dkwt boot Aufräumen (beim Booten).
+dkwt login Aufräumen (beim Anmelden eines Benutzers).
+dkwt logout Aufräumen (beim Abmelden eines Benutzers).
+dkwt shutdown Aufräumen (beim Herunterfahren).
+dkwt cleanup-profiles Benutzerprofile aufräumen.
+dkwt keep Aufräumen unterdrücken bis einschließlich nach der
+ nächsten Nutzeranmeldung.
+dkwt unkeep Normale Aufräum-Routinen wieder herstellen.
+dkwt help Hilfetext anzeigen. Wird ein Kommando als
+ zusätzliches Argument angegeben, wird ein Hilfetext für das Kommando angezeigt.
+dkwt -h Diesen Hilfetext anzeigen.
+dkwt -v Versionsnummer anzeigen.
+dkwt -L Lizenzbedingungen anzeigen.
+
+Die Kommandos boot, login, logout, shutdown, cleanup-profile, keep und
+unkeep sind zur Verwendung in PC-Klassenräumen gedacht, siehe BEMERKUNGEN
+weiter unten.
+
+OPTIONEN
+
+-s
+ Kurze Ausgabe beim Auflisten von Nutzern oder Gruppen.
+
+-l
+ Lange (ausführliche) Ausgabe beim Auflisten von Nutzern oder Gruppen.
+
+-d <Gerät>
+ Drucker (Anschluss- bzw. Gerätename) für das Ausdrucken von Dateien.
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+DATEIEN
+
+dkwt.conf
+ Die Datei dkwt.conf wird für die Kommandos boot, login, logout,
+ shutdown und cleanup-profiles verwendet.
+ Das empfohlene Verzeichnis für diese Datei ist
+ "C:\Program Files\Krause\etc\dkt-3-site" bzw.
+ "C:\Program Files (x86)\Krause\etc\dkt-3-site", je nach Windows-Version
+ (32- oder 64-Bit).
+ Die Datei besteht aus drei Abschnitten:
+ "options", "public" und "profiles", alle drei Abschnitte sind optional.
+
+ Im options-Abschnitt kann der Name für den Benutzer "System" und
+ den Benutzer "Jeder" in der Sprache der jeweiligen Installation
+ angegeben werden. Sind diese Angaben nicht vorhanden, werden die
+ Nutzernamen der SIDs "S-1-5-18" und "S-1-1-0" verwendet.
+
+ Im public-Abschnitt werden Verzeichnisse aufgelistet, die für alle
+ Nutzer schreibbar bzw. mit Vollzugriff versehen sind und die daher
+ regelmäßig aufgeräumt werden sollen.
+
+ Im profiles-Abschnitt wird in der Startanweisung das Basisverzeichnis
+ angegeben, in dem sich die Benutzerprofile befinden. Im Abschnitt
+ selbst werden alle Unterverzeichnisse dieses Verzeichnisses
+ aufgelistet, die beim Aufräumen erhalten werden sollen.
+
+ Beispiel:
+
+ [options]
+ system user = System
+ everyone use = Jeder
+
+ [public]
+ c:\temp
+
+ [profiles C:\Users]
+ All users
+ Default User
+ Public
+ Administrator
+ admin
+ sshd_server
+
+BEMERKUNGEN
+
+Die Kommandos boot, login, logout, shutdown und cleanup-profiles sind für die
+Verwendung in PC-Klassenräumen vorgesehen.
+Dabei wird von folgenden Annahmen ausgegangen:
+- Nutzeraccounts werden zentral gemanaget, z.B. im AD bzw. in einer Domäne.
+ Es existieren nur wenige lokale Benutzeraccounts, die bei der
+ Windows-Installation angelegt wurden oder für den Betrieb spezieller Dienste
+ erforderlich sind.
+- Jeder "normale" Nutzer hat ein Homeverzeichnis auf einem Fileserver und
+ speichert seine Daten dort.
+- Typischerweise melden sich an allen PCs die Nutzer mehr oder weniger
+ gleichzeitig an und ab (Beginn und Ende von Lehrveranstaltungen).
+Benutzerprofile werden aus folgenden Gründen nicht auf dem Server gespeichert:
+- Ein Großteil des Nutzerprofiles besteht aus Daten, die nichts mit den
+ Lehrveranstaltungen zu tun haben. Den Web-Browser-Cache aller Nutzer auf
+ dem Fileserver zu speichern wäre eine Verschwendung von TB...
+ Windows bietet zwar auch eine Blacklist für Profil-Unterverzeichnisse an,
+ die nicht mit dem Server synchronisiert werden sollen, aber die Pflege einer
+ solchen Blacklist bedeutet ständiges Hinterherputzen nach jedem Update und
+ jeder Softwareinstallation.
+- Bei der simultanen An- und Abmeldung der Nutzer an allen PCs hätte ein
+ Abgleich aller Profile mit dem Server Belastungsspitzen für Server und
+ Netzwerk zur Folge, die weit über die normale Benutzung hinausgehen.
+Somit werden folgende Einstellungen verwendet:
+- In den group policies werden nur lokale Benutzerprofile erlaubt,
+ Profilsynchronisierung mit dem Server wird deaktiviert.
+- Während der Lehrveranstaltung speichern die Nutzer ihre Daten in einem
+ für alle Nutzer schreibbaren Verzeichnis, z.B. C:\Temp oder C:\Lehre.
+- Am Ende der Lehrveranstaltung werden die noch benötigten Daten entweder in
+ das Homeverzeichnis und/oder auf private Medien wie USB-Sticks gesichert.
+ Dies erscheint auf den ersten Blick unkomfortabel, die Nutzer lernen aber
+ hierbei, wo ihre Daten gespeichert sind, die gesichert werden müssen.
+- Vor der Abmeldung löschen Nutzer ihre Daten aus dem für alle schreibbaren
+ Verzeichnis bzw. Verzeichnissen.
+- Beim Abmelden wird ein Abmeldescript benutzt, das für den gesamten noch
+ in den allgemein schreibbaren Verzeichnissen befindlichen Inhalt Vollzugriff
+ für jedermann erlaubt und anschließend versucht, diese Inhalte zu löschen.
+ Auch auf das Profilverzeichnis wird Vollzugriff für jeden gestattet,
+ anschließend wird versucht, dieses zu löschen.
+- Beim Abmelden können u.U. nicht alle Daten des Nutzers gelöscht werden,
+ daher wird bei der Anmeldung des nächsten Nutzers, beim Herunterfahren und
+ beim nächsten Systemstart ein erneuter Versuch unternommen. Beim
+ Systemstart sind die Aussichten auf erfolgreiches Löschen am besten.
+Um diese Aufräumarbeiten zu automatisieren, müssen Aufrufe von
+ dkwt boot
+ dkwt login
+ dkwt logout
+ dkwt shutdown
+in das System-Startup-Script, das Benutzer-Login-Script, das
+Benutzer-Logout-Script und das Herunterfahren-Script eingefügt werden
+(in dieser Reihenfolge).
+
+In Windows Vista, Windows 7 und den Nachfolgeversionen laufen die
+o.g. Skripte unter einem Benutzeraccount, der nicht die erforderlichen
+Berechtigungen zum Aufräumen der Benutzerprofile hat.
+Mit "dkwt boot", "dkwt login", "dkwt logout" und "dkwt shutdown" wird auf
+diesen Systemen keine Bereinigung der Benutzerprofile durchgeführt.
+Stattdessen können Sie manuell eine Eingabeaufforderung *als Administrator*
+öffnen und "dkwt cleanup-profiles" verwenden.
+Wenn Sie "dkwtadm cleanup-profiles" verwenden, wird die UAC benutzt,
+um entsprechende Berechtigungen zu erlangen.
+
+Werden Lehrveranstaltungen zur Systemprogrammierung (z.B. Erstellung eigener
+Treiber) durchgeführt, kann es beim Testen zu Abstürzen und Hängenbleiben
+des Systems kommen. Wird das Problem durch Neustart/Ausschalten gelöst, gehen
+beim Aufräumen die noch nicht gesicherten Daten verloren.
+Mit
+ dkwt keep
+kann das Aufräumen temporär außer Kraft gesetzt werden bis einschließlich zur
+nächsten Benutzeranmeldung. Der Befehl "dkwt keep" muss natürlich eingegeben
+werden, bevor riskante Experimente (z.B. Tests selbstgeschriebener
+systemnaher Software) erfolgen.
+Mit
+ dkwt unkeep
+wird der normale Aufräum-Betrieb wiederhergestellt. Dieser Befehl sollte
+unmittelbar vor dem Abmelden verwendet werden, nachdem alle Tests erfolgreich
+durchgeführt wurden und die Daten gespeichert wurden.
+Der Registry-Schlüssel HKEY_LOCAL_MACHINE\SOFTWARE\DKrause\Shared\dkwt muss
+vorhanden sein, Vollzugriff auf diesen Schlüssel muss entweder für "Jeder"
+oder "INTERAKTIV" eingerichtet sein.
+
+AUTOR
+
+Dirk Krause
+
+LIZENZBEDINGUNGEN
+
+Ein Aufruf von
+ dkwt --license-terms
+zeigt die Lizenzbedingungen an.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/de/dkwt-keep.txt b/support/dktools/dktools/de/dkwt-keep.txt
new file mode 100644
index 0000000000..a4789bbaf4
--- /dev/null
+++ b/support/dktools/dktools/de/dkwt-keep.txt
@@ -0,0 +1,42 @@
+
+BEZEICHNUNG
+
+ dkwt keep - Automatisches Bereinigen zeitweise außer Kraft setzen
+
+ÃœBERSICHT
+
+ dkwt keep
+
+BESCHREIBUNG
+
+Mit diesem Kommando wird das automatische Bereinigen zeitweise - bis
+einschließlich zur nächsten Benutzer-Anmeldung - außer Kraft gesetzt.
+Sie sollten dieses Kommando vor Aktionen verwenden, die zum Hängenbleiben
+oder Abstürzen des Systems führen können, insbesondere in Lehrveranstaltungen
+zur Mikroprozessortechnik oder Systemprogrammierung, beispielsweise wenn
+selbstentwickelte Treiber oder direkte Hardwarezugriffe getestet werden sollen.
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+REGISTRY
+
+Der Registry-Schlüssel HKEY_LOCAL_MACHINE\SOFTWARE\DKrause\Shared\dkwt muss
+vorhanden sein, Vollzugriff auf diesen Schlüssel muss entweder für "Jeder"
+oder "INTERAKTIV" eingerichtet sein.
+
+AUTOR
+
+Dirk Krause
+
+LIZENZBEDINGUNGEN
+
+Ein Aufruf von
+ dkwt --license-terms
+zeigt die Lizenzbedingungen an.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/de/dkwt-login.txt b/support/dktools/dktools/de/dkwt-login.txt
new file mode 100644
index 0000000000..f76556e901
--- /dev/null
+++ b/support/dktools/dktools/de/dkwt-login.txt
@@ -0,0 +1,55 @@
+
+BEZEICHNUNG
+
+ dkwt login - Aufräumen im Nutzer-Login-Script
+
+ÃœBERSICHT
+
+ dkwt login [-t]
+
+BESCHREIBUNG
+
+Ein Aufruf von "dkwt login" kann in das Nutzer-Login-Script von PCs in
+PC-Klassen eingetragen werden. Dies bewirkt ein automatisches Bereinigen
+beim Anmelden eines Nutzers.
+
+OPTIONEN
+
+-t
+ Test-Mode. Es werden keine Dateien oder Verzeichnisse gelöscht, sondern
+ nur Meldungen ausgegeben, welche Dateien oder Verzeichnisse
+ beim Bereinigen gelöscht werden.
+
+EXIT-STATUS
+
+Es wird immer 0 zurückgegeben, unabhängig von evtl. aufgetretenen Fehlern.
+
+DATEIEN
+
+dkwt.conf
+ Die Datei dkwt.conf enthält die Konfigurationsangaben zum automatischen
+ Bereinigen des PCs.
+ Verwenden Sie
+ dkwt help
+ um nähere Informationen über diese Konfigurationsdatei zu erhalten.
+
+BEMERKUNGEN
+
+Nach Änderungen an dkwt.conf sollte
+ dkwt login -t
+verwendet werden, um die Einstellungen zu prüfen.
+
+AUTOR
+
+Dirk Krause
+
+LIZENZBEDINGUNGEN
+
+Ein Aufruf von
+ dkwt --license-terms
+zeigt die Lizenzbedingungen an.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/de/dkwt-logout.txt b/support/dktools/dktools/de/dkwt-logout.txt
new file mode 100644
index 0000000000..4adb7e06bc
--- /dev/null
+++ b/support/dktools/dktools/de/dkwt-logout.txt
@@ -0,0 +1,55 @@
+
+BEZEICHNUNG
+
+ dkwt logout - Aufräumen im Nutzer-Logout-Script
+
+ÃœBERSICHT
+
+ dkwt logout [-t]
+
+BESCHREIBUNG
+
+Ein Aufruf von "dkwt logout" kann in das Nutzer-Logout-Script von PCs in
+PC-Klassen eingetragen werden. Dies bewirkt ein automatisches Bereinigen
+beim Abmelden eines Nutzers.
+
+OPTIONEN
+
+-t
+ Test-Mode. Es werden keine Dateien oder Verzeichnisse gelöscht, sondern
+ nur Meldungen ausgegeben, welche Dateien oder Verzeichnisse
+ beim Bereinigen gelöscht werden.
+
+EXIT-STATUS
+
+Es wird immer 0 zurückgegeben, unabhängig von evtl. aufgetretenen Fehlern.
+
+DATEIEN
+
+dkwt.conf
+ Die Datei dkwt.conf enthält die Konfigurationsangaben zum automatischen
+ Bereinigen des PCs.
+ Verwenden Sie
+ dkwt help
+ um nähere Informationen über diese Konfigurationsdatei zu erhalten.
+
+BEMERKUNGEN
+
+Nach Änderungen an dkwt.conf sollte
+ dkwt logout -t
+verwendet werden, um die Einstellungen zu prüfen.
+
+AUTOR
+
+Dirk Krause
+
+LIZENZBEDINGUNGEN
+
+Ein Aufruf von
+ dkwt --license-terms
+zeigt die Lizenzbedingungen an.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/de/dkwt-print.txt b/support/dktools/dktools/de/dkwt-print.txt
new file mode 100644
index 0000000000..3f351f8666
--- /dev/null
+++ b/support/dktools/dktools/de/dkwt-print.txt
@@ -0,0 +1,37 @@
+
+BEZEICHNUNG
+
+ dkwt print - Datei drucken
+
+ÃœBERSICHT
+
+ dkwt print [<Option>] [<Datei(en)>]
+
+BESCHREIBUNG
+
+Das Programm druckt die angegebene(n) Datei(en).
+
+OPTIONEN
+
+-d <Gerät>
+ Gerätename der Druckwarteschlange, *nicht* der Druckername.
+ Ohne diese Option erfolgt der Ausdruck auf dem Standarddrucker.
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+AUTOR
+
+Dirk Krause
+
+LIZENZBEDINGUNGEN
+
+Ein Aufruf von
+ dkwt --license-terms
+zeigt die Lizenzbedingungen an.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/de/dkwt-printers.txt b/support/dktools/dktools/de/dkwt-printers.txt
new file mode 100644
index 0000000000..91b29b0275
--- /dev/null
+++ b/support/dktools/dktools/de/dkwt-printers.txt
@@ -0,0 +1,37 @@
+
+BEZEICHNUNG
+
+ dkwt printers - Drucker auflisten
+
+ÃœBERSICHT
+
+ dkwt printers [<Option>]
+
+BESCHREIBUNG
+
+Das Kommando listet die im System vorhandenen Drucker auf.
+
+OPTIONEN
+
+-l
+ Langes (ausführliches) Listing. Ohne diese Option wird
+ nur der Druckername ausgegeben.
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+AUTOR
+
+Dirk Krause
+
+LIZENZBEDINGUNGEN
+
+Ein Aufruf von
+ dkwt --license-terms
+zeigt die Lizenzbedingungen an.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/de/dkwt-shutdown.txt b/support/dktools/dktools/de/dkwt-shutdown.txt
new file mode 100644
index 0000000000..a5927da0b8
--- /dev/null
+++ b/support/dktools/dktools/de/dkwt-shutdown.txt
@@ -0,0 +1,55 @@
+
+BEZEICHNUNG
+
+ dkwt shutdown - Aufräumen im System-Shutdown-Script
+
+ÃœBERSICHT
+
+ dkwt shutdown [-t]
+
+BESCHREIBUNG
+
+Ein Aufruf von "dkwt shutdown" kann in das System-Shutdown-Script von PCs in
+PC-Klassen eingetragen werden. Dies bewirkt ein automatisches Bereinigen
+beim Herunterfahren.
+
+OPTIONEN
+
+-t
+ Test-Mode, es werden keine Dateien oder Verzeichnisse gelöscht, sondern
+ nur Meldungen ausgegeben, welche Dateien oder Verzeichnisse beim
+ Bereinigen gelöscht werden.
+
+EXIT-STATUS
+
+Es wird immer 0 zurückgegeben, unabhängig von evtl. aufgetretenen Fehlern.
+
+DATEIEN
+
+dkwt.conf
+ Die Datei dkwt.conf enthält die Konfigurationsangaben zum automatischen
+ Bereinigen des PCs.
+ Verwenden Sie
+ dkwt help
+ um nähere Informationen über diese Konfigurationsdatei zu erhalten.
+
+BEMERKUNGEN
+
+Nach Änderungen an dkwt.conf sollte
+ dkwt shutdown -t
+verwendet werden, um die Einstellungen zu prüfen.
+
+AUTOR
+
+Dirk Krause
+
+LIZENZBEDINGUNGEN
+
+Ein Aufruf von
+ dkwt --license-terms
+zeigt die Lizenzbedingungen an.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/de/dkwt-unkeep.txt b/support/dktools/dktools/de/dkwt-unkeep.txt
new file mode 100644
index 0000000000..d679bc402e
--- /dev/null
+++ b/support/dktools/dktools/de/dkwt-unkeep.txt
@@ -0,0 +1,38 @@
+
+BEZEICHNUNG
+
+ dkwt unkeep - Automatisches Bereinigen wieder aktivieren
+
+ÃœBERSICHT
+
+ dkwt unkeep
+
+BESCHREIBUNG
+
+Mit diesem Kommando wird das automatische Bereinigen wieder eingeschaltet,
+nachdem es mit "dkwt keep" zeitweise deaktiviert wurde.
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+REGISTRY
+
+Der Registry-Schlüssel HKEY_LOCAL_MACHINE\SOFTWARE\DKrause\Shared\dkwt muss
+vorhanden sein, Vollzugriff auf diesen Schlüssel muss entweder für "Jeder"
+oder "INTERAKTIV" eingerichtet sein.
+
+AUTOR
+
+Dirk Krause
+
+LIZENZBEDINGUNGEN
+
+Ein Aufruf von
+ dkwt --license-terms
+zeigt die Lizenzbedingungen an.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/de/dkwt-users.txt b/support/dktools/dktools/de/dkwt-users.txt
new file mode 100644
index 0000000000..9432d74df3
--- /dev/null
+++ b/support/dktools/dktools/de/dkwt-users.txt
@@ -0,0 +1,41 @@
+
+BEZEICHNUNG
+
+ dkwt users - Nutzer auflisten
+
+ÃœBERSICHT
+
+ dkwt users [<Option>]
+
+BESCHREIBUNG
+
+Das Programm listet die im System vorhandenen Benutzer.
+
+OPTIONEN
+
+-l
+ Langes (ausführliches) Listing.
+
+-s
+ Kurzes Listing (nur Nutzername).
+
+Die Optionen -l und -s können nicht gleichzeitig verwendet werden.
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+AUTOR
+
+Dirk Krause
+
+LIZENZBEDINGUNGEN
+
+Ein Aufruf von
+ dkwt --license-terms
+zeigt die Lizenzbedingungen an.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/de/dkwt.str b/support/dktools/dktools/de/dkwt.str
new file mode 100644
index 0000000000..da80f6fa31
--- /dev/null
+++ b/support/dktools/dktools/de/dkwt.str
@@ -0,0 +1,501 @@
+#
+# 0: Attribute label: FUll user name
+#
+Name:
+#
+# 1: Attribute label: Comment for user
+#
+Kommentar:
+#
+# 2: Attribute label: User comment
+#
+Nutzer-Kommentar:
+#
+# 3: Attribute label: HOme directory
+#
+Homeverzeichnis:
+#
+# 4: Attribute label: User profile directory
+#
+Nutzerprofil:
+#
+# 5: Attribute label: User SID
+#
+SID:
+#
+# 6: Attribute label: User type
+#
+Typ:
+#
+# 7: User type: guest
+#
+Gast
+#
+# 8: User type: Normal user
+#
+Nutzer
+#
+# 9: User type: Administrator
+#
+Administrator
+#
+# 10: Attribute label: User flags.
+#
+Flags:
+#
+# 11: Account attribute: Login script executed
+#
+Login-Script ausgeführt.
+#
+# 12: Account attribute: Account disabled
+#
+Account deaktiviert.
+#
+# 13: Account attribute: Home directory required
+#
+Homeverzeichnis wird benötigt.
+#
+# 14: Account attribute: No password required
+#
+Kein Passwort notwendig.
+#
+# 15: Account attribute: Password can not be changed
+#
+Passwort kann nicht geändert werden.
+#
+# 16: Account attribute: Locked out
+#
+Account ausgesperrt.
+#
+# 17: Account attribute: Password does not expire
+#
+Passwort verfällt nicht.
+#
+# 18: Account attribute: Encrypted text password allowd
+#
+Verschlüsseltes Text-Passwort erlaubt.
+#
+# 19: Account attribute: Account is sensitive, no delegation
+#
+Wichtiger Account, keine Delegierung.
+#
+# 20: Account attribute: Smartcard required
+#
+Smartcard gefordert.
+#
+# 21: Account attribute: DES keys are allowed only
+#
+Nur DES-Keys.
+#
+# 22: Account attribute: No Kerberos pre-auth required
+#
+Keine Kerberos Pre-Authentication erforderlich.
+#
+# 23: Account attribute: Account is trusted for delegation
+#
+Dem Account wird für Delegierung vertraut.
+#
+# 24: Account attribute: Password is expired
+#
+Passwort ist abgelaufen.
+#
+# 25: Account attribute: Trusted to authenticate for delegation
+#
+Dem Account wird hinsichtlich der Authentifierung für Delegierung getraut.
+#
+# 26: Account type: Normal user account
+#
+Normaler Nutzer-Account.
+#
+# 27: Account type: Duplicated account for user from other domain
+#
+Duplizierter Account für Nutzer aus anderer Domäne.
+#
+# 28: Account type: Workstation trust account
+#
+Workstation-Trust-Account.
+#
+# 29: Account type: Server trust account
+#
+Server-Trust-Account.
+#
+# 30: Account type: Interdomain trust account
+#
+Interdomain-Trust-Account.
+#
+# 31: Empty string
+#
+
+#
+# 32: Operator privileges label
+#
+Operator:
+#
+# 33: Operator type: Accounts operator
+#
+Account-Operator.
+#
+# 34: Operator type: Server operator
+#
+Server-Operator.
+#
+# 35: Operator type: Communications operator
+#
+Kommunikations-Operator.
+#
+# 36: Operator type: Print operator
+#
+Druck-Operator.
+#
+# 37: Attribute label: Country code
+#
+Landes-Code:
+#
+# 38: Attribute label: Code page number
+#
+Codepage-Nummer:
+#
+# 39: Attribute label: Source
+#
+Quelle:
+#
+# 40: Attribute label: Comment
+#
+Kommentar:
+#
+# 41: Source type: Net
+#
+Netz
+#
+# 42: Source type: Local
+#
+Lokal
+#
+# 43: Attribute label: SID
+#
+SID:
+#
+# 44: Attribute label: Comment
+#
+Kommentar:
+#
+# 45: Attribute label: Description
+#
+Beschreibung:
+#
+# 46: Attribute label: Location
+#
+Herkunft:
+#
+# 47: Attribute label: Server
+#
+Server:
+#
+# 48: Attribute label: Share name
+#
+Freigabe:
+#
+# 49: Attribute label: Port
+#
+Port:
+#
+# 50: Attribute label: Driver
+#
+Treiber:
+#
+# 51: Attribute label: Device
+#
+Gerät:
+#
+# 52: Attribute label: Separator file
+#
+Trennseiten-Datei:
+#
+# 53: Attribute label: Print processor
+#
+Druck-Processor:
+#
+# 54: Attribute label: Data type
+#
+Datentyp:
+#
+# 55: Attribute label: Parameters
+#
+Parameter:
+#
+# 56/57: Error message: Failed to create print file "..."!
+#
+Die Druckdatei "
+" konnte nicht erzeugt werden!
+#
+# 58: Error message: Failed to schedule print job!
+#
+Der Druck-Job konnte nicht in die Warteschlange gestellt werden!
+#
+# 59: Error message: Failed to add print job!
+#
+Der Druck-Job konnte nicht gedruckt werden!
+#
+# 60/61: Error message: Failed to open printer "..."!
+#
+Keine Verbindung zum Drucker "
+" möglich!
+#
+# 62: Error message: Printer name too long!
+#
+Drucker-Name zu lang!
+#
+# 63/64: Error message: No printer found for device "..."!
+#
+Kein Drucker fpr Port "
+" gefunden!
+#
+# 65: Error message: Failed to find default printer!
+#
+Kein Standarddrucker vorhanden!
+#
+# 66: Error message: Redefinition of profile base directory!
+#
+Profil-Verzeichnis neu definiert!
+#
+# 67: Error message: No profile base directory specified!
+#
+Kein Profil-Verzeichnis bekannt!
+#
+# 68: Error message: Syntax - Unknown section type!
+#
+Syntax-Fehler - Unbekannter Abschnittstyp!
+#
+# 69: Error message: Syntax - Incomplete section header!
+#
+Syntax-Fehler - Unvollständiger Abschnittsbeginn!
+#
+# 70: Error message: Syntax - Missing section header!
+#
+Syntax-Fehler - Abschnittsbeginn fehlt!
+#
+# 71: Error message: Syntax - Redefinition of system user!
+#
+Syntax-Fehler - Nutzer "SYSTEM" neu definiert!
+#
+# 72: Error message: Syntax - Redefinition of everyone user!
+#
+Syntax-Fehler - Nutzer "Jeder" neu definiert!
+#
+# 73: Error message: Syntax - Unknown option!
+#
+Syntax-Fehler - Unbekannte Option!
+#
+# 74: Error message: Syntax - Not a key/value pair!
+#
+Syntax-Fehler - Kein Schlüssel/Wert-Paar!
+#
+# 75: Error message: Options -l and -s are exclusive!
+#
+Optionen -l und -s sind exklusiv!
+#
+# 76: Error message: Arguments are ignored!
+#
+Argumente werden ignoriert!
+#
+# 77: Error message: Failed to set keep-data flag.
+#
+DAS DATENERHALTUNGS-FLAG KONNTE NICHT GESETZT WERDEN!
+#
+# 78: Notice: Keep-data flag was set successfully.
+#
+Das Datenerhaltungs-Flag wurde gesetzt.
+#
+# 79/80: Execution of "..." indicated an error!
+#
+Kommando gab Statuscode für Fehler zurück: \n"
+"
+#
+# 81/82: Error: Failed to find name for SID "..."!
+#
+Für SID "
+" wurde kein Name gefunden!
+#
+# 83/84: Progress: Cleaning up local print queue ... .
+#
+Bereinige lokale Druckwarteschlange "
+".
+#
+# 85/86/87: Progress: Successfully deleted job ...: "...".
+#
+Druckauftrag
+: "
+" wurde gelöscht.
+#
+# 88: Unnamed print job
+#
+Druckauftrag ohne Namen
+#
+# 89/90/91: Error: Failed to delete job ...: "..."!
+#
+Druckauftrag
+: "
+" konnte nicht gelöscht werden!
+#
+# 92/93: Error: Failed to open printer ...!
+#
+Keine Verbindung zu Drucker "
+"!
+#
+# 94: Error: Failed to enumerate local printers!
+#
+Die installierten Drucker konnten nicht ermittelt werden!
+#
+# 95: Error: Missing user name!
+#
+Benutzername für Druckauftrag fehlt.
+#
+# 96: Progress: Print queue cleaned up successfully.
+#
+Druckwarteschlange wurde bereinigt.
+#
+# 97: ERROR: Failed to send request!
+#
+Löschbefehl konnte nicht gesendet werden!
+#
+# 98: ERROR: Failed to connect to remote host!
+#
+Keine Verbindung zum Server!
+#
+# 99: ERROR: Failed to create network socket!
+#
+Socket konnte nicht erzeugt werden!
+#
+# 100: ERROR: Failed to find IP address!
+#
+Keine IP-Adresse gefunden!
+#
+# 101/102: Progress: Cleaning up remote print queue ...
+#
+Bereinige Netzwerk-Druckwarteschlange "
+".
+#
+# 103: ERROR: Request too long for buffer!
+#
+Befehl zu lang für den Puffer!
+#
+# 104/105: ERROR: Empty queue name in "..."!
+#
+Wartschlangen-Name fehlt in "
+"!
+#
+# 106/107: ERROR: Empty host name in "..."!
+#
+Hostname fehlt in "
+"!
+#
+# 108/109: ERROR: Not a queue@host name: "..."!
+#
+Name entspricht nicht queue@host: "
+"!
+#
+# 110/111: ERROR: Queue name "..." too long!
+#
+Druckwarteschlangen-Name "
+" ist zu lang!
+#
+# 112: ERROR: Failed to initialize Windows sockets!
+#
+Winsock-Subsystem konnte nicht initialisiert werden!
+#
+# 113/114: Error: Error code: ...
+#
+Fehler-Code:
+.
+#
+# 115/116: IP address: ...
+#
+IP-Adresse:
+.
+#
+# 117
+#
+Auf diesem System läuft Windows Vista oder höher.\nNutzerprofile können hier nicht automatisch bereinigt werden!
+#
+# 118/119: Progress: Executing command: ...
+#
+Kommando wird ausgeführt:\n
+
+#
+# 120/121: Progress: Remove directory: ...
+#
+Verzeichnis wird gelöscht:\n
+
+#
+# 122/123: Progress: Remove file: ...
+#
+Datei wird gelöscht:\n
+
+#
+# 124/125/126: Progress: Delete Registry key ...
+#
+Registry-Key wird gelöscht:\n
+\\
+
+#
+# 127/128: DEBUG: Registry key "..." deleted.
+#
+Registry-Key "
+" gelöscht.
+#
+# 129/130/131: ERROR: Failed to remove registry key:
+#
+Registry-Key konnte nicht gelöscht werden:\n
+\\
+
+#
+# 132/133
+#
+Registry-Key konnte nicht geöffnet werden:\n
+
+#
+# 134
+#
+Profil-Verzeichnis wird bereinigt (Start).
+#
+# 135
+#
+Interner Fehler (Bug), kein Name für Verzeichniseintrag gefunden!
+#
+# 136/137
+#
+Umgebungsvariablen in String\n"
+",\nkonnten nicht expandiert werden, Puffer zu klein!
+#
+# 138/139
+#
+Subkey-Name zu lang:\n
+
+#
+# 140
+#
+Profil-Bereinigung wird wegen Fehlern nicht ausgeführt.
+#
+# 141
+#
+Profil-Verzeichnis wird bereinigt (Ende).
+#
+# 142
+#
+Nur eine der Optionen -u, -i, -a oder -d zulässig!
+#
+# 143
+#
+Mindestens ein Argument (Variablenname) muss angegeben werden!
+#
+# 144
+#
+Verzeichnis/Datei muss angegeben werden!
+#
+# 145
+#
+Administrator-Berechtigungen erforderlich!
+#
+# 146
+#
+Nur Administratoren können System-Umgebungsvariablen ändern!
diff --git a/support/dktools/dktools/de/dkwx.str b/support/dktools/dktools/de/dkwx.str
new file mode 100644
index 0000000000..cdda8a3f08
--- /dev/null
+++ b/support/dktools/dktools/de/dkwx.str
@@ -0,0 +1,45 @@
+#
+# 0: Log level: Worse than panic
+#
+Schlimmeres Problem als Panik
+#
+# 1: Log level: Panic
+#
+Panik
+#
+# 2: Log level: Fatal error
+#
+Fataler Fehler
+#
+# 3: Log level: Error
+#
+Fehler
+#
+# 4: Log level: Warning
+#
+Warnung
+#
+# 5: Log level: Information
+#
+Information
+#
+# 6: Log level: Progress message
+#
+Fortschritt
+#
+# 7: Log level: Debug message
+#
+Debug
+#
+# 8: Log level: Ignore message
+#
+Ignoriere
+#
+# 9: Error: Not enough memory!
+#
+Zu wenig Hauptspeicher!
+#
+# 10: Error: Help file not found!
+#
+Hilfe-Datei nicht gefunden!
+
diff --git a/support/dktools/dktools/de/dkwxpath.str b/support/dktools/dktools/de/dkwxpath.str
new file mode 100644
index 0000000000..a603707293
--- /dev/null
+++ b/support/dktools/dktools/de/dkwxpath.str
@@ -0,0 +1,88 @@
+#
+# 0: Program name
+#
+dkwxpath
+#
+# 1: Application group name
+#
+dkt-3
+#
+# 2: Software vendor name
+#
+Dirk Krause
+#
+# 3: Label text: Modifying PATH environment variable.
+#
+Umgebungsvariable PATH wird bearbeitet.
+#
+# 4: Window title
+#
+dktools setup
+#
+# 5: Dialog title: Failed to modify PATH variable.
+#
+PATH nicht bearbeitet!
+#
+# 6: Start of label text: Failed to modify PATH environment variable!
+#
+Die Umgebungsvariable PATH konnte nicht geändert werden!
+#
+# 7: Label text contents: Please add
+#
+Bitte fügen Sie
+#
+# 8: Label text contents: to the PATH environment variable
+#
+manuell zur Umgebungsvariable PATH hinzu
+#
+# 9: Label text contents: Please remove
+#
+Bitte entfernen Sie
+#
+# 10: Label text contents: from the PATH environment variable
+#
+aus der Umgebungsvariable PATH
+#
+# 11: Label text contents: and reboot the computer as soon as possible.
+#
+und starten Sie anschließend Ihren Computer neu.
+#
+# 12
+#
+WxBmpp - EPS-Bild
+#
+# 13
+#
+WxBmpp - PDF-Bild
+#
+# 14
+#
+WxBmpp - PDF-Objekt
+#
+# 15
+#
+WxBmpp - PDF-Dokument
+#
+# 16
+#
+WxBmpp - PS-Dokument
+#
+# 17
+#
+WinPrint - Standarddrucker
+#
+# 18
+#
+WinPrint - Drucker auswählen
+#
+# 19
+#
+Öffnen mit WxBmpp
+#
+# 20
+#
+Öffnen mit WxDkct
+#
+# 21
+#
+Prüfsummen
diff --git a/support/dktools/dktools/de/dkwxwiz.str b/support/dktools/dktools/de/dkwxwiz.str
new file mode 100644
index 0000000000..e57bf39b9a
--- /dev/null
+++ b/support/dktools/dktools/de/dkwxwiz.str
@@ -0,0 +1,66 @@
+#
+# 0: Program name.
+#
+dkwxwiz
+#
+# 1: Program group name.
+#
+dkt-3
+#
+# 2: String table file name.
+#
+dkwxwiz.str
+#
+# 3: Help file name.
+#
+dkwxwiz.txt
+#
+# 4: Copyright owner.
+#
+__CHANGE__ 001: Copyright-Eigentümer
+#
+# 5: License type.
+#
+__CHANGE__ 002: Lizenztyp
+#
+# 6 7 File base name too long!
+#
+Dateiname "
+" ist zu lang!
+#
+# 8 9 File already exists!
+#
+Datei "
+" existiert bereits!
+#
+# 10
+#
+Unbekanntes Macro in Template!
+#
+# 11
+#
+Zu wenig Kommandozeilenargumente!
+#
+# 12 13 14 15 16 17 18 19 20 21
+#
+Sie sollten die folgenden Dateien bereitstellen:
+Hilfe-Datei für Windows-Systeme: "
+Hilfe-Datei für andere Systeme: "
+Icon für Windows-Systeme: "
+Icon für andere Systeme: "
+".
+.chm
+.htb
+.ico
+.xpm
+#
+# 22 23
+#
+Text zu lang oder kein ASCII-Text: "
+"!
+#
+# 24 25
+#
+Kein C/C++ Identifier: "
+"!
+
diff --git a/support/dktools/dktools/de/dkwxwiz.txt b/support/dktools/dktools/de/dkwxwiz.txt
new file mode 100644
index 0000000000..f978764819
--- /dev/null
+++ b/support/dktools/dktools/de/dkwxwiz.txt
@@ -0,0 +1,89 @@
+
+BEZEICHNUNG
+
+ dkwxwiz - Wizard für wxWidgets+dkct basierte Projekte.
+
+ÃœBERSICHT
+
+ dkwxwiz [<Optionen>] <Programm> <Application> <Window>
+
+BESCHREIBUNG
+
+Das Programm erzeugt ein Code-Skelett für eine wxWidgets-basierte GUI-Anwendung,
+wobei die dktools-Bibliotheken und dkct im Projekt verwendet werden.
+
+Die folgenden Argumente müssen angegeben werden:
+
+* Der Name des zu erzeugenden Programmes (ohne eventuelle Endung .exe),
+ z.B. "myprog".
+
+* Der Name der von wxApp abgeleiteten Anwendungsklasse, z.B. "MyProgApp".
+
+* Der Name der Top-Level-Window-Klasse, z.B. "MyProgFrame".
+
+Alle drei Angaben müssen gültige C/C++-Identifier sein.
+
+OPTIONEN
+
+-h --help
+ Hilfetext anzeigen.
+
+-v --version
+ Versionsnummer anzeigen.
+
+-L --license-terms
+ Lizenzbedingungen anzeigen.
+
+-f --force
+ Ãœberschreiben bereits vorhandener Ausgabedateien erlauben. Vorsicht!
+
+-c <Copyright-Inhaber>
+ Copyright-Inhaber.
+
+-l <license type>
+ Lizenztyp ("bsd", "gpl", "lgpl" oder "commercial").
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+BEISPIEL
+
+Verwenden Sie
+ dkwxwiz testprog TestApp TestFrame
+in einem leeren Verzeichnis, um ein neues Projekt anzulegen.
+
+DATEIEN
+
+Die folgenden Dateien aus dem dkt-3 Resourcenverzeichnis werden benutzt:
+
+dkwxwizh.txt Template für Header-Datei *.h.
+
+dkwxwiza.txt Template für Application-Klasse *.cpt.
+
+dkwxwizf.txt Template für Top-Level-Window-Klasse *.wxc.
+
+dkwxwizc.txt Template für configure.ac für autoconf.
+
+dkwxwizm.txt Template für Makefile.in.
+
+dkwxwizx.txt Template für *.xpm-Icon.
+
+Sie können Kopien dieser Dateien in dkt-3-site bzw. dk3app-site
+platzieren und bearbeiten, z.B. um Standardwerte für Copyright-Inhaber
+und Lizenztyp festzulegen.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
+AUTOR
+
+Dirk Krause
+
+LIZENZ
+
+Mit
+ dkwxwiz --license-terms
+können Sie die Lizenzbedingungen einsehen.
+
diff --git a/support/dktools/dktools/de/fig2lat.str b/support/dktools/dktools/de/fig2lat.str
new file mode 100644
index 0000000000..8b2159b193
--- /dev/null
+++ b/support/dktools/dktools/de/fig2lat.str
@@ -0,0 +1,147 @@
+#
+# 0 1: Invalid PS level preference value!
+#
+PS-Level-Preference "
+" nicht verwendbar!
+#
+# 2 Input file name too long!
+#
+Name für Eingabedatei zu lang:\n
+#
+# 3 Failed to read input file!
+#
+Lesen der Eingabedatei fehlgeschlagen!
+#
+# 4 Failed to process input file!
+#
+Verarbeitung der Eingabedatei fehlgeschlagen!
+#
+# 5 No regular file, no directory!
+#
+Keine reguläre Datei und kein Verzeichnis!
+#
+# 6 Command line options processing failed!
+#
+Auswertung der Optionen fehlgeschlagen!
+#
+# 7 + 8 Unknown driver!
+#
+Unbekannter Treiber "
+"!
+#
+# 9 + 10 Invalid tf value!
+#
+Ungültiger Wert "
+" für tf, erlaubt sind "fig" oder "similar"!
+#
+# 11 + 12 Invalid font size!
+#
+Fehlerhafte Schriftgrößenangabe "
+"!
+#
+# 13 + 14 Invalid size specification!
+#
+Fehlerhafte Größenangabe "
+" (Bereichsüberlauf)!
+#
+# 15 + 16 + 17 + 18 Value below minimum, maximum!
+#
+Der Wert "
+" liegt unter dem gefordertem Minimum "
+"!
+" liegt über dem gefordertem Maximum"
+#
+# 19 + 20 Option requires positive argument!
+#
+Die Option "
+" erfordert einen positiven Wert!
+#
+# 21 + 22 Option requires a numeric argument!
+#
+Die Option "
+" erfordert eine Wert-Angabe!
+#
+# 23 Source type already set!
+#
+Der Quell-Datei-Typ wurde bereits gesetzt!
+#
+# 24 + 25 Option requires an unsigned numeric argument!
+#
+Die Option "
+" erfordert einen vorzeichenlosen Wert!
+#
+# 26 Can not handle negative font size!
+#
+Negative Schriftgrößen sind nicht zulässig!
+#
+# 27 + 28 Illegal option/key name!
+#
+Unzulässiger Name für Option "
+"!
+#
+# 29 + 30 Option too long!
+#
+Option zu lang:\n"
+"!
+#
+# 31 Option argument too long!
+#
+Options-Argument zu lang:\n"
+#
+# 32 Option -l requires an argument!
+#
+Zur Option "-l" muss ein Treibername angegeben werden!
+#
+# 33 PS level must be 2 or 3!
+#
+Das PostScript-Level muss 2 oder 3 sein!
+#
+# 34 Minimum of arrowhead segments corrected to 2!
+#
+Arrowhead-Segmente wurden auf Minimum 2 korrigiert!
+#
+# 35 Mathematical problem (coordinates transformation)!
+#
+Mathematisches Problem bei Koordinatentransformation!
+#
+# 36 Mathematical problem (spline calculation)!
+#
+Mathematisches Problem bei Spline-Berechnung!
+#
+# 37 Arrowhead too long for spline!
+#
+Pfeilspitze an Spline zu lang!
+#
+# 38 Mathematical problem (path construction)!
+#
+Mathematisches Problem bei Pfad-Generierung!
+#
+# 39 Arrowheads in summary too long for spline!
+#
+Pfeilspitzen an Spline sind in Summe zu lang!
+#
+# 40 Failed to calculate graphics state transformation!
+#
+Transformation des Graphics State nicht ermittelbar!
+#
+# 41 Failed to add instructions to PDF graphics!
+#
+Fehler beim Hinzufügen von Graphikbefehlen zu PDF-Datei!
+#
+# 42 Skipping special text!
+#
+LaTeX Special Text wird ignoriert!
+#
+# 43 Unknown object type!
+#
+Unbekannter Objekt-Typ!
+#
+# 44 Special text found!
+#
+Datei enthält LaTeX Special Text!
+#
+# 45 46
+#
+Keine Linienbreite: "
+"!
+
diff --git a/support/dktools/dktools/de/fig2lat.txt b/support/dktools/dktools/de/fig2lat.txt
new file mode 100644
index 0000000000..dfad2d9715
--- /dev/null
+++ b/support/dktools/dktools/de/fig2lat.txt
@@ -0,0 +1,265 @@
+
+BEZEICHNUNG
+
+fig2lat - Fig to LaTeX conversion
+
+KOMMANDOZEILE
+
+ fig2lat [-l <Treiber>] [<Optionen>] [-o <Key>=<Value>]* <Datei>
+
+BESCHREIBUNG
+
+Fig2lat wandelt *.fig-Dateien (mit XFig, jFig oder WinFIG erzeugt)
+in andere Graphik-Formate, hauptsächlich für die Verwendung mit
+LaTeX/pdfLaTeX.
+
+OPTIONEN
+
+-l <Treiber>
+ Treiber, einer der nachfolgenden:
+
+ Treiber, um Fig-Dateien mit latex oder pdflatex zu verwenden:
+
+ pdf.tex Erstelle ein Paar *.tex/*.pdf. Im LaTeX-Dokument
+ schließen Sie die *.tex per \input{...} ein, diese
+ importiert dann wiederum die *.pdf-Datei.
+
+ eps.tex Erstelle ein Paar *.tex/*.eps. Im LaTeX-Dokument
+ schließen Sie die *.tex per \input{...} ein, diese
+ importiert dann wiederum die *.eps-Datei.
+
+ pgf Erstelle eine *.pgf-Datei, die Sie mit \input{...}
+ in Ihr LaTeX-Dokument einbinden können.
+
+ Treiber um Standalone-Graphiken zu erzeugen:
+
+ tex.pdf Erstelle ein Paar *.tex/*-i.pdf. Die *.tex-Datei
+ können Sie mit pdfLaTeX übersetzen, dabei entsteht
+ dann eine PDF-Datei.
+
+ tex Erstelle eine *.tex-Datei, die Sie mit pdfLaTeX
+ übersetzen können. Dabei entsteht dann eine
+ PDF-Datei.
+
+ eps Erstelle eine EPS-Datei.
+
+ svg Erstelle eine SVG-Datei.
+
+-m
+ Make-Modus: Beim Verarbeiten eines Verzeichnisses
+ wird eine Konvertierung nur gestartet, wenn keine aktuellen
+ Zieldateien vorliegen.
+
+-o Key=Value
+ Schlüssel-Wert-Paare in der Konfiguration.
+ Die folgenden Schlüssel können benutzt werden:
+
+ Allgemeine Optionen:
+
+ lw[=<Breite>] Basis für die Linienbreite.
+ Standardmäßig wird für Fig-Dateien 1/80 Zoll
+ verwendet.
+ Mit folgenden Breitenangaben kann dies
+ geändert werden:
+ <Zahl>bp Angabe in bp (PS points).
+ <Zahl>pt Angabe in pt.
+ <Zahl>in Angabe in Zoll.
+ <Zahl>cm Angabe in cm.
+ <Zahl>mm Angabe in mm.
+ lighten 1/160 Zoll.
+ auto 0.4pt * Textgröße / 10.
+
+ Text-Optionen:
+
+ tf=<string> Schriftart-Auswahl für normalen
+ (nicht-special) Text.
+ Entweder "similar" oder "fig".
+
+ ts=<size> Schriftgröße für normalen Text. Entweder
+ "none" (LaTeX-Standardschriftgröße verwenden)
+ oder Skalierungsfaktor (typischerweise
+ 0.95 ... 1.0).
+
+ bbts=[<boolean>] Text-Größe in Bounding-Box-Berechnung
+ mit berücksichtigen.
+
+ smash[=<boolean>] Anweisung \smash in LaTeX-Ausgabe benutzen.
+
+ mbox[=<boolean>] Anweisung \mbox in LaTeX-Ausgabe benutzen.
+
+ reset@font[=<boolean>] Anweisung \reset@font in LaTeX-Ausgabe.
+
+ ste[=<encoding>] Encoding für Special-Text, entweder
+ "utf-8" oder "plain".
+
+
+ X-Spline- und Bezier-Spline-Optionen:
+
+ xsss[=<number>] Anzahl der Bezier-Spline-Segmente pro
+ X-Spline-Segment. Standard: 8, Minimum: 2.
+
+
+ Pfeilspitzen-Optionen:
+
+ ahas=<number> Anzahl der X-Spline-Segmente pro
+ 90-Grad-Winkelbereich für Pfeilspitzen an
+ Kreisbögen. Standard: 4.
+
+ ahss=<integer> Anzahl der X-Spline-Segmente der Pfeilspitze
+ pro Original-Spline-Segment für Pfeilspitzen
+ an Splines. Standard: 4.
+
+ ahms=<integer> Minimale Anzahl X-Spline-Segmente an jeder
+ Pfeilspitzen-Kante. Standard: 4.
+
+ ahip=<float> Iterations-Genauigkeit für Pfeilspitzen.
+ Standard: 0.04.
+
+
+ Ausgabe-Optionen:
+
+ codi=[<number>] Anzahl Nachkommastellen in Farbangaben.
+ Standard: 3.
+
+
+ Kompatibilitäts-Optionen (Kompatibilität mit fig2dev):
+
+ cosp[=<boolean>] Kompatible Splines.
+
+ coah[=<boolean>] Kompatible Pfeilspitzen.
+
+ xsah[=<boolean>] X-Spline-Pfeilspitzen (nur ohne coah).
+
+ cols[=<boolean>] Kompatible Linientypen verwenden.
+
+ cofop[=<boolean>] Füllung für offene Graphikpfade erlauben.
+
+
+ Erzeuger der Fig-Datei:
+
+ xfig Xfig.
+
+ jfig jFig.
+
+ winfig WinFIG.
+
+
+ Treiber-spezifische Optionen (tex, tex.pdf):
+
+ dcts[=<number>] Schriftgrößenangabe in pt in der
+ Dokumentenklasse.
+
+
+ Treiber-spezifische Optionen (eps, eps.tex):
+
+ showpage[=<boolean>] Operator showpage verwenden.
+
+ level=<integer> PS-Level, 2 oder 3.
+
+
+ Treiber-spezifische Optionen (svg)
+
+ css[=<boolean>] Style-Angaben mit CSS.
+
+ group[=<boolean>] Pfeilspitzen-Objekte mit dazugehöriger Line,
+ Spline oder Kreisbogen in einer Gruppe
+ zusammenfassen.
+
+ fragment[=<boolean>] SVG-Fragment anstelle einer kompletten Datei
+ erzeugen.
+
+ fontbase[=<string>] Verzeichnis für GhostScript-Fonts als
+ TTF-Dateien angeben, "none", "local" oder
+ "web".
+
+ replacementfonts[=<boolean>] Verwendung von Ersatz-Schrift-
+ familien erlauben oder verbieten.
+
+ miterlimit[=<boolean>] Verwendung der "stroke-miterlimit" Stil-
+ Angabe erlauben oder verbieten.
+
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+DATEIEN
+
+Fig2lat benutzt die folgenden Dateien aus dem aktuellen Verzeichnis:
+
+f2lfonts.tex wird bei tex- bzw. tex.pdf-Ausgabe in der Präambel
+ benutzt. Der Dateiinhalt ersetzt die Standardanweisungen
+ für die Schriftartauswahl und -einstellung.
+
+f2lother.tex wird bei tex- bzw. tex.pdf-Ausgabe in der Präambel
+ benutzt. Der Dateiinhalt ersetzt die Standardanweisungen
+ für "sonstiges Setup".
+
+HINWEISE
+
+Die Ausgabe von fig2lat unterscheidet sich von der Ausgabe von fig2dev.
+Dies ist beabsichtigt, denn sonst hätte fig2lat keine Existenzberechtigung.
+
+* Interpolierte Splines: Fig2lat berechnet q=-0.5*s korrekt wie in [BS1995]
+ angegeben.
+
+* Pfeilspitzen: Die mit Xfig 3.2.5 eingeführten - aber nicht dokumentierten -
+ Pfeilspitzen werden untersützt. An Splines und Kreisbögen werden
+ gekrümmte Pfeilspitzen angebracht. Zum Zeichnen der Pfeilspitze wird
+ dieselbe Linienbreite verwendet wie für die Original-Linie.
+ Die Angaben zur Linienbreite der Pfeilspitze aus der Fig-Datei werden
+ ignoriert.
+
+* Text: Für Treiber mit LaTeX-Bezug (tex, tex.pdf, pdf.tex, eps.tex, pgf)
+ wird aller Text durch LaTeX/pdfLaTeX verarbeitet. Die tf-Einstellung legt
+ fest, ob für normalen Text (nicht-special) ein PS-Font oder ein LaTeX-Font
+ mit gleichen Eigenschaften verwendet wird.
+ Für special Text werden keinerlei Anweisungen zu Schriftart und Schrift-
+ größe geschrieben, somit wird die Standard-Schrift des Dokumentes
+ verwendet.
+
+* Füllmuster: Füllmuster sind als Vektor-Graphik implementiert.
+
+* Splines: X-Splines werden durch eine Folge von Bezier-Spline-Segmenten
+ realisiert, nicht durch Linienzüge.
+
+
+BEKANNTE PROBLEME
+
+* Die gekrümmten Pfeilspitzen an Kreisbögen und Splines werden durch eine
+ Folge kurzer - manchmal sehr kurzer - Bezierkurven realisiert.
+ Verschiedene Anzeigeprogramme kommen mit diesen kurzen Bezierkurven
+ unterschiedlich gut zurecht.
+ Die Pfeilspitzen-Testdatei wird in manchen Programmen richtig angezeigt,
+ in anderen Programmen fehlerhaft.
+ Sollten derartige Probleme auftreten, gibt es zwei Lösungsansätze:
+ - Für Batik 1.7 Squiggle kann die SVG-Option mit der Option
+ "miterlimit=no" vorgenommen werden. Dabei wird das sonst verwendete
+ Miterlimit 20 nicht in die Ausgabe geschrieben, Squiggle verwendet
+ dann den Standardwert 4.
+ - Kompatible Pfeilspitzen können mit der Option "coah" erzeugt werden,
+ diese geraden Pfeilspitzen werden als Polygone realisiert.
+
+
+AUTOR
+
+Dirk Krause
+
+GESCHICHTE
+
+Dieses Programm ersetzt das Programm fig2vect aus früheren dktools-Versionen.
+
+COPYRIGHT UND LIZENZ
+
+Mit
+ fig2lat --license-terms
+können Sie die Lizenzbedingungen einsehen.
+
+SIEHE AUCH
+
+[BS1995] Carole Blanc, Christophe Schlick:
+ X-Splines: A Spline Model Designed for the End-User
+ Proceedings of the SIGGRAPH 1995
+
+[fig2lat] http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/de/htmlbook.str b/support/dktools/dktools/de/htmlbook.str
new file mode 100644
index 0000000000..7551a83305
--- /dev/null
+++ b/support/dktools/dktools/de/htmlbook.str
@@ -0,0 +1,313 @@
+#
+# 0: Title for impressum page
+#
+Impressum
+#
+# 1: Link title
+#
+Zur Startseite:
+#
+# 2: Link title
+#
+Auf der Startseite.
+#
+# 3: Link title
+#
+Zur vorherigen Seite:
+#
+# 4: Link title
+#
+Auf der ersten Seite.
+#
+# 5: Link title
+#
+Zur nächsten Seite:
+#
+# 6: Link title
+#
+Auf der letzten Seite.
+#
+# 7: Link title
+#
+Zum Stichwort-Index.
+#
+# 8: Syntax error, missing =
+#
+Syntax-Fehler, "=" fehlt!
+#
+# 9: Syntax error, empty value!
+#
+Syntax-Fehler, kein Wert angegeben!
+#
+# 10: Syntax error, only allowed in options section
+#
+Syntax-Fehler, Einstellung nur im options-Abschnitt möglich!
+#
+# 11: Syntax error, illegal character set
+#
+Syntax-Fehler, Zeichensatz muss "ascii" oder "utf-8" sein!
+#
+# 12: Syntax error, no path specification in file name allowed!
+#
+Syntax-Fehler, Pfadangabe in Dateinamen unzulässig!
+#
+# 13: Missing project file name
+#
+Kein Name für Projekt-Datei!
+#
+# 14: Too many project files specified, just one allowed!
+#
+Nur eine Projekt-Datei erlaubt!
+#
+# 15: No parent candidate found!
+#
+Kein Elternknoten gefunden (wahrscheinlich ein Bug)!
+#
+# 16
+#
+Syntax-Fehler, Name für Abschnitt fehlt!
+#
+# 17
+#
+Syntax-Fehler, schließende eckige Klammer fehlt!
+#
+# 18
+#
+Syntax-Fehler, unzulässiger Abschnitts-Name!
+#
+# 19
+#
+Kein Template angegeben!
+#
+# 20
+#
+Dateiname nicht gefunden (wahrscheinlich ein Bug)!
+#
+# 21 22
+#
+String "
+" enhält Zeichen, die in URL nicht verwendbar sind!
+#
+# 23 Header External links
+#
+Externe Links
+#
+# 24 Error: No source file
+#
+Keine Quelldatei angegeben!
+#
+# 25 26 Error: Illegal menu style
+#
+Syntax-Fehler, unzulässige Style-Angabe "
+"!
+#
+# 27 ERROR: Illegal key
+#
+Syntax-Fehler, unzulässiges Attribut: "
+#
+# 28 ERROR: Contents is allowed only in templates!
+#
+Syntax-Fehler, %%contents%% ist nur in Templates zulässig!
+#
+# 29 ERROR: Illegal special command
+#
+Syntax-Fehler, unbekanntes Spezial-Kommando "
+#
+# 30 ERROR: Parsing failed
+#
+Syntax-Fehler, Parsen des Spezial-Kommandos schlug fehl nahe:\n"
+#
+# 31 ERROR: Line too long
+#
+Zeile zu lang:\n"
+#
+# 32
+#
+Syntax-Fehler, Kopf-Daten fehlen!
+#
+# 33
+#
+Syntax-Fehler, schließendes @ fehlt!
+#
+# 34
+#
+Syntax-Fehler, Text nach @ fehlt!
+#
+# 35
+#
+Syntax-Fehler, Ãœberschriften-Level fehlt!
+#
+# 36
+#
+Syntax-Fehler, kein Text nach führendem Punkt in Zeile!
+#
+# 37
+#
+Ãœberschrift-Level korrigiert zu Maximalwert 6!
+#
+# 38
+#
+Syntax-Fehler, url kann nur in options-Abschnitt gesetzt werden!
+#
+# 39
+#
+Ausführung eines Spezial-Kommandos fehlgeschlagen!
+#
+# 40
+#
+Syntax-Fehler, Einlesen der Argumente fehlgeschlagen!
+#
+# 41
+#
+Syntax-Fehler, zu viele Menüeinträge angegeben!
+#
+# 42
+#
+Syntax-Fehler, kein Menüeintrag angegeben!
+#
+# 43 44
+#
+Syntax-Fehler, unzulässige Option: "
+"!
+#
+# 45
+#
+Inhaltsverzeichnis
+#
+# 46
+#
+Stichwort-Index
+#
+# 47
+#
+Kein Standard-Thema gefunden!
+#
+# 48
+#
+Das "text"-Attribut fehlt!
+#
+# 49
+#
+Das "file"-Attribut fehlt!
+#
+# 50
+#
+Spezial-Kommando "index" ist in Template nicht zulässig!
+#
+# 51
+#
+Kein Ziel für den Link gefunden!
+#
+# 52 53
+#
+Kein Text für Knoten:\n"
+"!
+#
+# 54 55 56 57
+#
+Aktuelle Position
+Inhaltsverzeichnis für aktuelle Seite
+Externe Links
+Inhaltsverzeichnis
+#
+# 58 59
+#
+Groß
+Bild
+#
+# 60
+#
+Menüeintrag
+#
+# 61 Text "Impressum" in head range of HTML page, link tag
+#
+Impressum
+#
+# 62 Error message, unfinished command!
+#
+Nicht abgeschlossenes "%%"-Kommando!
+#
+# 63 64 Error: Not a backslash sequence
+#
+Keine gültige Backslash-Sequenz: "
+"!
+#
+# 65
+#
+Bild
+#
+# 66
+#
+Einstellung "div" wird durch "table" überschrieben!
+#
+# 67 68
+#
+Kein Ausgabe-Verzeichnis konfiguriert!
+Kein Ausgabe-Script konfiguriert!
+#
+# 69 ... 83
+#
+Bisheriger Wert der Einstellung "author" überschrieben.
+Bisheriger Wert der Einstellung "title" überschrieben.
+Bisheriger Wert der Einstellung "output directory" überschrieben.
+Bisheriger Wert der Einstellung "output script" überschrieben.
+Bisheriger Wert der Einstellung "template" überschrieben.
+Bisheriger Wert der Einstellung "style" überschrieben.
+Bisheriger Wert der Einstellung "short" überschrieben.
+Bisheriger Wert der Einstellung "file" überschrieben.
+Bisheriger Wert der Einstellung "suffix" überschrieben.
+Bisheriger Wert der Einstellung "icon toc" überschrieben.
+Bisheriger Wert der Einstellung "icon previous" überschrieben.
+Bisheriger Wert der Einstellung "icon next" überschrieben.
+Bisheriger Wert der Einstellung "icon index" überschrieben.
+Bisheriger Wert der Einstellung "shortcut icon" überschrieben.
+Bisheriger Wert der Einstellung "var" überschrieben.
+#
+# 84 85
+#
+Datei nicht vorhanden: "
+"!
+#
+# 86
+#
+Bisheriger Wert der Einstellung "file" überschrieben.
+#
+# 87
+#
+Startseite
+#
+# 88
+#
+Zu viele Code-Zeilen, nur 999 am Stück erlaubt!
+#
+# 89 90
+#
+Syntax-Fehler, Unerwarteter %%hint%%-Key \"
+" ignoriert!
+#
+# 91
+#
+Syntax-Fehler, Text für %%hint%% fehlt!
+#
+# 92
+#
+Syntax-Fehler, Titel für %%hint%% fehlt!
+#
+# 93 94
+#
+Zum Inhaltsverzeichnis:
+Auf der Startseite.
+#
+# 95
+#
+Bisheriger Wert der Einstellung "icon home" überschrieben.
+#
+# 96
+#
+Syntax error, Wert fehlt!
+#
+# 97 98 99
+#
+Bisheriger Wert der Einstellung ``meta description'' überschrieben!
+Bisheriger Wert der Einstellung ``meta keywords'' überschrieben!
+Bisheriger Wert der Einstellung ``location'' überschrieben!
diff --git a/support/dktools/dktools/de/htmlbook.txt b/support/dktools/dktools/de/htmlbook.txt
new file mode 100644
index 0000000000..ad94361eef
--- /dev/null
+++ b/support/dktools/dktools/de/htmlbook.txt
@@ -0,0 +1,327 @@
+
+BEZEICHNUNG
+
+ htmlbook - HTML-Dateien für ein Buch-Äquivalent
+
+ÃœBERSICHT
+
+ htmlbook [<Optionen>] <Projekt>
+
+BESCHREIBUNG
+
+Das Programm erzeugt HTML-Dateien, die Struktur des erzeugten Webangebotes
+ähnelt einem Buch. Der Autor kann sich auf den Inhalt konzentrieren,
+das Programm htmlbook übernimmt die Erstellung von Navigationsmenü,
+Navigationsblock mit Icons, Inhaltsverzeichnis und Stichwortverzeichnis.
+
+OPTIONEN
+
+-i <encoding>
+--input-encoding=<encoding>
+ Erwartetes Eingabe-Encoding für die
+ Projektdatei.
+
+-o Name[,Name...]
+ Optionale Abschnitte der Projektdatei
+ aktivieren.
+
+-s Name=Wert
+--set=Name=Wert
+ Variable setzen, überschreibt
+ Variablen, die im options-Abschnitt der
+ Projektdatei gesetzt wurden.
+
+-h
+--help
+ Hilfetext anzeigen.
+
+-v
+--version
+ Versionsnummer anzeigen.
+
+-L
+--license
+ Lizenzbedingungen anzeigen.
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+DATEIEN
+
+Die Projektdatei ist der Startpunkt von htmlbook. Sie gibt an, welche
+Textdateien unter Zuhilfename welcher Templates benutzt werden.
+
+Projektdatei
+------------
+Die Projektdatei besteht aus den Abschnitten "[options]", "[files]"
+und "[contents]".
+Weiterhin sind optionale Abschnitte der Form "[options:<Name>]",
+"[files:<Name>]" und "[contents:<Name>]" möglich, diese Abschnitt werden
+nur dann verarbeitet, wenn sie beim Programmstart mit der Option -o
+aktiviert wurden. Auf Windows-Systemen werden optionale Abschnitte mit dem
+Namen "windows" immer verarbeitet, auf Nicht-Windows-Systemen
+optionale Abschnitte mit dem Namen "non-windows".
+
+Der options-Abschnitt enthält Zeilen der Form "Schlüssel=Wert", folgende
+Schlüssel können verwendet werden:
+
+ output directory Verzeichnis für die Ausgabedateien, muss leer
+ sein, wird bei jedem Aufruf des output script
+ gelöscht und neu angelegt.
+
+ output script Ausgabescript, legt das Ausgabeverzeichnis neu
+ an und kopiert die Daten dorthin.
+
+ title Titel-Angabe.
+
+ url URL unter der das Webangebot online steht.
+
+ index file Dateiname für Text auf Startseite.
+
+ html charset Zeichensatz für HTML-Dateien, "us-ascii",
+ "utf-8" oder "ascii".
+
+ template Dateiname für das Standard-Template ("web.hbt").
+
+ style Dateiname für die Standard-Style-Datei
+ ("style.css").
+
+ page toc Flag: Seiteninternes Inhaltsverzeichnis anlegen.
+
+ create toc Flag: Inhaltsverzeichnis anlegen (über alle
+ Seiten).
+
+ create index Flag: Stichwortverzeichnis (Index) anlegen.
+
+ section numbers in index Flag: Abschnittsnummer in Index anzeigen.
+
+ replace ampersand Flag: Zeichen & ersetzen (Standard: aus).
+
+ tidy Flag: tidy zur Kontrolle und Korrektur
+ verwenden.
+
+ ln Flag: ln anstelle von cp verwenden.
+
+ author Autor-Angabe.
+
+ location Ortsangabe.
+
+ write position Flag: Positionsangabe schreiben.
+
+ section numbers in position Flag: Abschnittsnummer in Positionsangabe.
+
+ shortcut icon URL zu favicon.
+
+ icon toc Dateinamen für Icons in Navigationsleiste
+ icon previous (Inhaltsverzeichnis, vorheriger Abschnitt,
+ icon next nächster Abschnitt, Index).
+ icon index
+
+ impressum link URL zu Impressum.
+
+ impressum page Text-Knoten für Impressum.
+ Es kann entweder ein Impressum-Link oder ein
+ Impressum-Knoten verwendet werden.
+
+ chm Flag: HTML erzeugen, aus dem später eine
+ CHM-Datei erstellt wird.
+
+ chm language Sprachangabe für CHM-Projekt
+ (Standard: "0x409 English (USA)").
+
+ js file Dateiname für JavaScript-Datei.
+
+ inherit js Flag: JavaScript-Dateien von Eltern... erben.
+
+ var Variable setzen (das erste Textwort auf der
+ rechten Seite ist der Variablenname, der Rest
+ der Zeile ist der Wert der Variablen).
+
+Der Abschnitt "[files]" listet die Namen zusätzlich zu kopierender
+Dateien, eine per Zeile.
+
+Der Abschnitt "[contents]" enthält die Baumstruktur für die Navigation.
+Jeder Unterabschnitt für einen Knoten beginnt mit dem Titel.
+Die Baumstruktur ergibt sich aus den Einrückungen. Gleich weit eingerückte
+Titel bezeichnen benachbarte Knoten innerhalb derselben Kollektion.
+Der Elternknoten eines jeden Knotens ist der letzte oberhalb befindliche
+Knoten, der weniger weit eingerückt ist.
+
+Auf einen Knoten-Titel können ein oder mehrere Zeilen folgen, die mit
+@ beginnen. Diese Zeilen enthalten Konfigurationsangaben zum Knoten:
+
+ file = Datei Dateiname der Textdatei.
+ input encoding = Encoding Encoding, falls kein BOM in Eingabedatei.
+ suffix = String Dateinamen-Endung für Ausgabedatei.
+ short = Kurztitel Kurzfassung des Titels für Navigationsmenü.
+
+Weiterhin sind die options-Angaben "html charset", "template", "style",
+"page toc", "write position", "replace ampersand", "tidy", "ln", "author",
+"location", "js file", "inherit js", "var", "icon toc", "icon previous",
+"icon next", "icon index" und "shortcut icon" erlaubt.
+
+Blätter (Knoten ohne weitere Unterknoten) müssen eine Angabe zur
+Textdatei haben, für andere Knoten ist dies optional.
+
+Template
+--------
+Das Template gibt an, was zwischen den Tags <BODY> und </BODY> steht.
+Über Spezial-Kommandos der Form %%Kommando%% können u.a. der Text eingebunden
+werden, das Navigationsmenü bzw Navigationsblöcke eingefügt werden.
+Folgende Spezial-Kommandos können verwendet werden:
+
+ %%contents%% fügt den Inhalt der Textdatei an dieser
+ Stelle ein.
+
+ %%title%% fügt den Titel des aktuellen Dokumentes ein.
+
+ %%img <Optionen>%% fügt ein Bild ein. Folgende Optionen
+ können verwendet werden:
+ div[=Bool] div-Tag um img-Tag
+ centered[=Bool] Bild zentriert zeigen, nicht linksbündig
+ src=Datei Dateiname für Bilddatei
+ alt="Text" Beschreibungstext
+ title[="Text"] Titel (Standard: alt)
+ caption[="Text"] Bildunterschrift (aktiviert div)
+ longdesc=Datei URL der ausführlichen Bildbeschreibung
+ border=Breite Bildrahmenbreite
+ height=Höhe Bildhöhe
+ width=Breite Bildbreite
+ svg=Datei URL der Vektorgraphik (SVG-Format)
+ svgwh[=Bool] Für SVG Abmessungen aus PNG/JPEG nutzen
+ object[=Bool] SVG-Objekt erzeugen
+ pdf=Datei URL der Vektorgraphik (PDF-Format)
+ larger=Datei URL einer hochauflösenden Bildvariante
+ ismap[=Bool] Flag: Bild ist eine Map
+ usemap=Datei URL der Map
+ name=name Name für das Bild
+ id=ID ID für CSS-Styling
+ class=Klasse Klasse für CSS-Styling
+ align=Ausrichtung Ausrichtung des Bildes
+ vspace=Abstand Vertikaler Abstand
+ hspace=Abstand Horizontaler Abstand
+ download[=Bool] Download-Links für Vektorgraphiken erzeugen
+ cache Bildgröße in Cache zwischenspeichern für
+ mehrmalige Verwendung desselben Bildes.
+ Automatisch aktiv, wenn %%img%% in Template
+ verwendet wird.
+
+ %%menu <Optionen>%% fügt das Navigationsmenü ein.
+ Folgende Optionen können verwendet werden:
+ style=Stil Menü-Stil, "reverse" (Standard), "full",
+ "current" oder "top".
+ sub[=Bool] Flag: Kind-Knoten der aktuellen Seite anzeigen.
+
+ %%navigation <Optionen>%% fügt einen Navigationsblock mit anklickbaren
+ Navigationsicons ein. Folgende Optionen
+ können verwendet werden:
+ itop=Datei Icon für Inhaltsverzeichnis ("toc.png").
+ iprev=Datei Icon für vorherigen Abschnitt ("prev.png").
+ inext=Datei Icon für nächsten Abschnitt ("next.png").
+ ikind=Datei Icon für Stichwortverzeichnis ("index.png").
+
+ %%author%% fügt die Angabe zum Autor ein.
+
+ %%location%% fügt die Angabe zum Ort ein.
+
+ %%date <Optionen>%% fügt das aktuelle Datum ein.
+ Folgende Optionen können verwendet werden:
+ style=Stil Datums-Stil (derzeit nur "german" unterstützt).
+
+ %%var <Name> <Optionen>%% fügt den Wert der angegebenen Variable ein.
+ Folgende Optionen können verwendet werden:
+ url[=Bool] Der Wert wird in einer Codierung passend
+ für URLs ausgegeben.
+
+ %%code <Optionen>%% schaltet das Code-Verhalten um.
+ Folgende Optionen können verwendet werden:
+ enable[=Bool] schaltet Code-Verarbeitung ein.
+ on[=Bool] schaltet Code-Verarbeitung ein.
+ disable[=Bool] schaltet Code-Verarbeitung aus.
+ off[=Bool] schaltet Code-Verarbeitung aus.
+ toggle schaltet Code-Verarbeitung um.
+
+ %%a <Optionen>%% fügt einen Link ein.
+ Folgende Optionen können verwendet werden:
+ href=URL Ziel-URL des Links.
+ name=Name Anker-Name (entweder href oder name erlaubt).
+ text="Text" Link-Text (Standard: href-Angabe).
+ title="Text" Link-Titel, wenn Maus über Link.
+ target=Ziel Zielfenster oder -frame.
+ type=Typ MIME-Typ.
+ external[=Bool] Flag: Externer Link, überschreibt die
+ automatische Erkennung.
+ id=ID ID für CSS-Styling.
+ class=Klasse Klasse für CSS-Styling.
+ style=Stilangabe Direkte Stil-Angaben.
+ hreflang=Sprache Sprache für die href-Angabe.
+ charset=Zeichensatz Zeichensatz des Links.
+ onblur=Script Script wenn Link den Fokus verliert.
+ onfocus=Script Script, wenn Link den Fokus erhält.
+ accesskey=Key Hotkey für den Link.
+ tabindex=Index Tabulator-Reihenfolge durch Zahlenangabe.
+ shape=Form Verweis-sensitiver Bereich bei Objekten.
+ coords=Koordinaten Verweis-sensitiver Bereich bei Objekten.
+ rel=Relation Vorwärts-Verknüpfung.
+ rev=Revision Rückwärts-Verknüpfung.
+
+ %%menuentry <Optionen>%% fügt die Darstellung eines Menüeintrages ein.
+ Folgende Optionen können verwendet werden:
+ item="Text" Mehrfach verwendbar bei hierarchischen
+ Menüs.
+
+ %%sourcefile <Optionen>%% stellt eine Datei in <PRE></PRE>-Umgebung
+ dar und bietet einen Download-Link an.
+ Folgende Optionen können verwendet werden:
+ file=Datei Darzustellende Datei, Pflichtangabe.
+ type=Typ MIME-Typ der Datei.
+ title="Text" Titel für Link.
+
+Textdatei
+---------
+Textdateien enthalten den eigentlichen Seiteninhalt.
+Zur Strukturierung können Überschriften der Form
+ .1 @name@ Ãœberschrift
+verwendet werden mit den Tiefen 1, 2, 3, 4 und 5. Aus diesen Tiefenangaben
+wird dann <h2>...<h6> erzeugt.
+Die Namensangabe ist optional. Ist sie vorhanden, wird ein mit Namen
+versehener Anker
+ <a name="name"></a>
+vor der Ãœberschrift angelegt. Ohne die Namensangabe wird automatisch ein
+Anker-Name gebildet.
+
+Text-Dateien können ebenfalls die unter "Template" aufgeführten
+Spezial-Kommandos enthalten, mit Ausnahme von %%contents%%. Zusätzlich
+ist in Textdateien noch das folgende Spezialkommando erlaubt:
+
+ %%index <Optionen>%% fügt einen Eintrag zum Stichwortverzeichnis
+ hinzu. Folgende Optionen sind möglich:
+ text="Text" Text (Pflichtangabe).
+ name=Name Anker-Name (optional).
+ reference[=Bool] Flag: Index-Eintrag bezieht sich auf einen
+ bereits vorhandenen Anker (z.B. eine
+ mit Namen versehene Ãœberschrift oder einen
+ explizit gesetzten Anker).
+
+HINWEISE
+
+Alle Textdateien, Templates, Style-Dateien und Bilder müssen lokale
+Dateien im aktuellen Verzeichnis sein.
+
+SIEHE AUCH
+
+ http://dktools.sourceforge.net
+
+AUTOR
+
+ Dirk Krause
+
+LIZENZ
+
+Mit dem Kommando
+
+ htmlbook -L
+
+werden die Lizenzbedingungen angezeigt.
+
diff --git a/support/dktools/dktools/de/itadmin.str b/support/dktools/dktools/de/itadmin.str
new file mode 100644
index 0000000000..3c4ea48e3f
--- /dev/null
+++ b/support/dktools/dktools/de/itadmin.str
@@ -0,0 +1,961 @@
+#
+# 0: Title for network documentation
+#
+Netzwerk-Dokumentation
+#
+# 1: Subject for network documentation
+#
+Netzwerk-Dokumentation
+#
+# 2: LaTeX packages for localization
+#
+\\usepackage{ngerman}
+#
+# 3: Hosts
+#
+Hosts
+#
+# 4: Other hosts
+#
+Andere Hosts
+#
+# 5: Overview
+#
+Ãœbersicht
+#
+# 6: Purpose:
+#
+Verwendungszweck:
+#
+# 7: Inventory ID:
+#
+Inventar-Nr.:
+#
+# 8: Serial no:
+#
+Seriennr.:
+#
+# 9: not specified (unknown)
+#
+nicht bekannt
+#
+# 10: Main user: (person responsible for host)
+#
+Systemverantwortlicher:
+#
+# 11: Place (building and room)
+#
+Aufstellungsort:
+#
+# 12: Network
+#
+Netzwerk
+#
+# 13: IP address
+#
+IP-Adresse:
+#
+# 14: DNS domain
+#
+DNS-Domäne:
+#
+# 15: MAC address
+#
+MAC-Adresse:
+#
+# 16: Ethernet socket (patch no)
+#
+Datendose:
+#
+# 17: DHCP class
+#
+DHCP-Klasse:
+#
+# 18: DHCP group
+#
+DHCP-Gruppe:
+#
+# 19: Netgroups
+#
+Netgroups
+#
+# 20: Notice, this is an address from a DHCP pool
+#
+IP-Adresse aus DHCP-Pool, dynamisch zugewiesen.
+#
+# 21: Short section header BYOD + DHCP
+#
+BYOD DHCP
+#
+# 22: Section header BYOD + DHCP
+#
+Privatgeräte, für DHCP zugelassen
+#
+# 23:
+#
+Dies ist ein Privatgerät ("`bring your own device"'), nicht Eigentum der
+#
+# 24:
+#
+Organisation bzw. Organisationseinheit.
+#
+# 25:
+#
+Dieser Computer gehört nicht zum Verantwortungsbereich der Organisationseinheit.
+#
+# 26:
+#
+Er ist in Konfigurationsdateien und in der Netzwerkdokumentation aufgeführt,
+#
+# 27:
+#
+weil Computer der Organisationseinheit mit diesem Computer kommunizieren.
+#
+# 28:
+#
+IP-Adresse, die dynamisch verschiedenen Computern zugewiesen wird.
+#
+# 29: Parent groups
+#
+Obergruppen
+#
+# 30: Subgroups
+#
+Untergruppen
+#
+# 31: Additional network interface
+#
+Zusätzliches Netzwerk-Interface an einem Computer.
+#
+# 32: Member hosts for netgroups
+#
+Mitglieder-Hosts
+#
+# 33: DHCP pools
+#
+DHCP-Pools
+#
+# 34: Start address
+#
+Start-Adresse:
+#
+# 35: End address
+#
+End-Adresse:
+#
+# 36: Allow unknown clients
+#
+Unbekannte Clients zugelassen:
+#
+# 37: Deny unknown clients
+#
+Unbekannte Clients verboten:
+#
+# 38: Allow members of group
+#
+Zugelassene DHCP-Klasse
+#
+# 39: yes
+#
+ja
+#
+# 40: no
+#
+nein
+#
+# 41: DHCP classes
+#
+DHCP-Klassen
+#
+# 42: Ethernet connectors
+#
+Datendosen
+#
+# 43: Connector
+#
+Datendose
+#
+# 44: Room
+#
+Raum
+#
+# 45: VLAN
+#
+VLAN
+#
+# 46: Speed
+#
+Geschwindigkeit
+#
+# 47: Hub port
+#
+Hub-Port
+#
+# 48: Available licenses
+#
+Verfügbare Lizenzen
+#
+# 49/50: Message to explain section contents
+#
+Die hier aufgeführten Lizenzen wurden erworben, aber (bisher) noch keinem
+Benutzer oder Computer zugeordnet.
+#
+# 51: LaTeX text for pdftitle
+#
+Lizenz-Report
+#
+# 52: LaTeX text for pdfsubject
+#
+Lizenzen
+#
+# 53: Default license type: Single computer license
+#
+Einzelplatz-Lizenz
+#
+# 54: LaTeX text: Purchase process ID
+#
+Beschaffungs-Vorgang:
+#
+# 55: LaTeX text: Delivery date
+#
+Liefer-Datum:
+#
+# 56: LaTeX text: Delivery note ID (Lieferschein-Nr)
+#
+Lieferschein-Nr.:
+#
+# 57: LaTeX text: Invoice date
+#
+Rechnungs-Datum:
+#
+# 58: LaTeX text: Invoice ID (Rechnungs-Nr)
+#
+Rechnungs-Nr.:
+#
+# 59: LaTeX text: Complete license list
+#
+Komplette Lizenz-Liste
+#
+# 60: LaTeX text: Host unknown
+#
+Computer nicht bekannt
+#
+# 61: LaTeX text: Assignment to host not specified.
+#
+Zuordnung zu Computer nicht bekannt
+#
+# 62: LaTeX text: Other people's hosts
+#
+Fremde Computer
+#
+# 63: LaTeX text: Licenses used on other people's hosts
+#
+Lizenzen, die auf fremden Computern genutzt werden
+#
+# 64: LaTeX text
+#
+Die hier aufgeführten Lizenzen wurden dem Nutzer zugewiesen.
+#
+# 65: LaTeX text
+#
+Die Angabe, auf welchem Computer die Lizenzen genutzt werden, ist
+#
+# 66: LaTeX text
+#
+(noch) nicht erfolgt.
+#
+# 67: LaTeX text
+#
+Die hier aufgeführten Lizenzen wurden dem Nutzer zugewiesen.
+#
+# 68: LaTeX text
+#
+Zur Zeit werden die Lizenzen auf Computern im Verantwortungsbereich
+#
+# 69: LaTeX text
+#
+anderer Benutzer verwendet.
+#
+# 70: LaTeX text
+#
+Hinweis:
+#
+# 71: LaTeX text
+#
+Diese Lizenzen werden hier im Lizenzreport zweimal aufgeführt:
+#
+# 72: LaTeX text
+#
+Einmal hier und einmal in dem Abschnitt für den betreffenden Computer.
+#
+# 73: LaTeX text
+#
+Im Abschnitt für den betreffenden Computer sind diese Lizenzen dadurch
+#
+# 74: LaTeX text
+#
+kenntlich gemacht, dass der Name des Lizenzinhabers in Kursivschrift im
+#
+# 75: LaTeX text
+#
+Lizenzeintrag zusätzlich zu den dort normalerweise vorhandenen Angaben erfolgt.
+#
+# 76: String separator in date, - for english, . for german
+#
+.
+#
+# 77: Progress message: Expanding netgroup dependencies.
+#
+Netgroup-Abhängigkeiten werden untersucht.
+#
+# 78: Progress message: Writing hosts file.
+#
+Datei "hosts" wird geschrieben.
+#
+# 79: Progress message: Writing hosts.ldif file.
+#
+Datei "hosts.ldif" wird geschrieben.
+#
+# 80: Progress message: Writing ethers files.
+#
+Datei "ethers" wird geschrieben.
+#
+# 81: Progress message: Writing ethers.ldif file.
+#
+Datei "ethers.ldif" wird geschrieben.
+#
+# 82: Progress message: Writing netgroup.ldif file.
+#
+Datei "netgroup.ldif" wird geschrieben.
+#
+# 83: Progress message: Writing dhcpd.conf file.
+#
+Datei "dhcpd.conf" wird geschrieben.
+#
+# 84: Progress message: Writing netdocu.tex file.
+#
+Datei "netdocu.tex" wird geschrieben.
+#
+# 85: Progress message: Writing licenses.tex file.
+#
+Datei "licenses.tex" wird geschrieben.
+#
+# 86: Progress message: Finished writing output files.
+#
+Die Ausgabedateien wurden erzeugt.
+#
+# 87: Progress message: Reading users table.
+#
+Benutzer-Tabelle wird gelesen.
+#
+# 88: Progress message: Reading buildings table.
+#
+Gebäude-Tabelle wird gelesen.
+#
+# 89: Progress message: Reading network speed types table.
+#
+Geschwindigkeits-Einstellungen-Tabelle wird gelesen.
+#
+# 90: Progress message: Reading VLANs table.
+#
+VLAN-Tabelle wird gelesen.
+#
+# 91: Progress message: Reading ethernet connectors table.
+#
+Datendosen-Tabelle wird gelesen.
+#
+# 92: Progress message: Reading netgroups table.
+#
+Netgroups-Tabelle wird gelesen.
+#
+# 93: Progress message: Reading netgroup dependencies table.
+#
+Netgroup-Abhängigkeits-Tabelle wird gelesen.
+#
+# 94: Progress message: Reading networks table.
+#
+Netzwerk-Tabelle wird gelesen.
+#
+# 95: Progress message: Reading DHCP classes table.
+#
+DHCP-Klassen-Tabelle wird gelesen.
+#
+# 96: Progress message: Reading DHCP groups table.
+#
+DHCP-Gruppen-Tabelle wird gelesen.
+#
+# 97: Progress message: Reading DHCP pools table.
+#
+DHCP-Pool-Tabelle wird gelesen.
+#
+# 98: Progress message: Reading hosts table.
+#
+Computer-Tabelle wird gelesen.
+#
+# 99: Progress message: Reading host name aliases table.
+#
+Host-Aliases-Tabelle wird gelesen.
+#
+# 100: Progress message: Reading DHCP options table.
+#
+DHCP-Optionen-Tabelle wird gelesen.
+#
+# 101: Progress message: Reading software manufacturers table.
+#
+Softwarehersteller-Tabelle wird gelesen.
+#
+# 102: Progress message: Reading software products table.
+#
+Softwareprodukte-Tabelle wird gelesen.
+#
+# 103: Progress message: Reading license types table.
+#
+Lizenztyp-Tabelle wird gelesen.
+#
+# 104: Progress message: Reading licenses table.
+#
+Lizenz-Tabelle wird gelesen.
+#
+# 105: Progress message: Finished reading input from database.
+#
+Die Daten wurden aus der Datenbank eingelesen.
+#
+# 106/107: ERROR: Not a boolean value "..."!
+#
+Kein boolscher Wert: "
+"!
+#
+# 108/109: ERROR: Configuration text "..." too long!
+#
+Konfigurationswert "
+" zu lang!
+#
+# 110/111: ERROR: No such database type: "..."!
+#
+Unzulässiger Datenbank-Typ: "
+"!
+#
+# 112: ERROR: A value text is required!
+#
+Textangabe erforderlich!
+#
+# 113/114: ERROR: Unknown configuration option "..."!
+#
+Unzulässige Konfigurationsoption "
+"!
+#
+# 115: ERROR: Syntax error - "=" and value required!
+#
+Syntax-Fehler: Wertangabe fehlt!
+#
+# 116: ERROR: Input line too long!
+#
+Ãœberlange Zeile gefunden!
+#
+# 117: ERROR: Missing end of section name!
+#
+Abschnittsname wird nicht beendet!
+#
+# 118/119: ERROR: File name contains wildcards, this is not allowed!
+#
+Der Dateiname "
+"\nenthält Leerzeichen, dies ist nicht erlaubt!
+#
+# 120/121: WARNING: File name "..." is not an absolute path name!
+#
+Der Dateiname "
+"\nist kein absoluter Dateiname!
+#
+# 122: ERROR: Missing database host name!
+#
+Der Hostname für die Datenbank fehlt!
+#
+# 123: ERROR: Missing database name!
+#
+Der Datenbank-Name fehlt!
+#
+# 124: WARNING: Missing DHCP VLAN name!
+#
+Der VLAN-Name für DHCP fehlt!
+#
+# 125: ERROR: Missing organization name!
+#
+Der Organisationsname fehlt!
+#
+# 126: ERROR: Missing organizational unit name!
+#
+Der Name für die Organisationseinheit fehlt!
+#
+# 127: ERROR: Missing administrator name!
+#
+Der Name des Administrators fehlt!
+#
+# 128: ERROR: Missing database credentials file name!
+#
+Der Dateiname für Datenbank-Nutzernamen und -passwort fehlt!
+#
+# 129: ERROR: Missing database user name!
+#
+Der Nutzername für die Datenbank fehlt!
+#
+# 130: ERROR: Missing database user password!
+#
+Das Passwort für die Datenbank fehlt!
+#
+# 131: ERROR: No configuration files found!
+#
+Keine Konfigurationsdatei "itadmin.conf" gefunden!
+#
+# 132: ERROR: Configuration problems!
+#
+Konfigurationsproblem(e),\nbitte die Datei(en) itadmin.conf überprüfen!
+#
+# 133: ERROR: Unsupported database type!
+#
+Unzulässiger Datenbank-Typ!
+#
+# 134: ERROR start: DHCP pool "
+#
+DHCP-Pool "
+#
+# 135: ERROR:
+#
+": Inkonsistentes Setup\nDer Zugriff für unbekannte Hosts kann enweder verboten oder erlaubt werden!
+#
+# 136: ERROR start DHCP class "
+#
+DHCP-Klasse "
+#
+# 137: ERROR: DHCP class assigned to pools in different networks!
+#
+"\nwurde DHCP-Pools in unterschiedlichen Netzwerken zugewiesen!
+#
+# 138: ERROR: DHCP pool "...": Missing allowed DHCP class name!
+#
+":\nDer Name der zugelassenen DHCP-Klasse fehlt!
+#
+# 139/140: ERROR: No such VLAN!
+#
+VLAN "
+" nicht vorhanden!
+#
+# 141: ERROR: Failed to obtain results list!
+#
+Ergebnis-Liste für Datenbank-Abfrage konnte nicht erstellt werden!
+#
+# 142: ERROR: Failed to query database!
+#
+Datenbank-Abfrage fehlgeschlagen!
+#
+# 143: ERROR: Primary key is not numeric!
+#
+Tabelle "licenses", Eintrag
+#
+# 144: ERROR: Primary key is not numeric!
+#
+\nPrimärschlüssel ist nicht numerisch!
+#
+# 145: ERROR: Missing primary key!
+#
+\nKein Primärschlüssel vorhanden!
+#
+# 146, 147, 148: License type "...": Not a number "..."!
+#
+Lizenz-Typ "
+":\nAnstatt "
+" wird eine Zahlenangabe erwartet!
+#
+# 149/150: ERROR: Tabel swm record ... Missing primary key!
+#
+Tabelle "swmanufacturers" Eintrag
+\nKein Primärschlüssel vorhanden!
+#
+# 151: ERROR start: Table "dhcpoptions" record ...
+#
+Tabelle "dhcpoptions" Eintrag
+#
+# 152: ERROR: Primary key is not numeric!
+#
+\nPrimärschlüssel ist nicht numerisch!
+#
+# 153: ERROR: Missing primary key!
+#
+\nKein Primärschlüssel vorhanden!
+#
+# 154: ERROR: Failed to set database encoding!
+#
+Zeichencodierung konnte nicht eingestellt werden!
+#
+# 155/156/157: ERROR: Failed to connect to database!
+#
+Verbindung zur Datenbank "
+" auf Host "
+" fehlgeschlagen!
+#
+# 158/159: ERROR: Illegal database name!
+#
+Unzulässiger Datenbank-Name: "
+"!
+#
+# 160: ERROR: Failed to convert database user password!
+#
+Datenbank-Passwort konnte nicht zu UTF-8 konvertiert werden!
+#
+# 161/162: ERROR: Failed to convert database user name to UTF-8!
+#
+Datenbank-Benutzername "
+"\nkonnte nicht zu UTF-8 konvertiert werden!
+#
+# 163/164: ERROR: Failed to convert database host name to UTF-8!
+#
+Datenbank-Hostname "
+"\nkonnte nicht zu UTF-8 konvertiert werden!
+#
+# 165: ERROR: Failed to initialize MySQL client object!
+#
+MySQL-Client-Objekt konnte nicht initialisiert werden!
+#
+# 166: ERROR: Failed to initialize MySQL client library!
+#
+MySQL-Client-Bibliothek konnte nicht initialisiert werden!
+#
+# 167: ERROR: MySQL database support not available!
+#
+MySQL-Unterstützung nicht verfügbar!
+#
+# 168/169: ERROR: User name "...": Duplicated entry!
+#
+Benutzer "
+" mehrfach vorhanden!
+#
+# 170/171: ERROR: Building "...": Duplicated entry!
+#
+Gebäude "
+": mehrfach vorhanden!
+#
+# 172/173: ERROR: Ethernet speed setting "...": Duplicated entry!
+#
+Geschwindigkeitseinstellung "
+": mehrfach vorhanden!
+#
+# 174/175: VLAN "...": Duplicated entry!
+#
+VLAN "
+": mehrfach vorhanden!
+#
+# 176/177: Computer "...": Duplicated entry!
+#
+Computer "
+": mehrfach vorhanden!
+#
+# 178/179: Software manufacturer "...": Duplicated entry!
+#
+Softwarehersteller "
+": mehrfach vorhanden!
+#
+# 180/181: Netgroup "...": Duplicated entry!
+#
+Netgroup "
+": mehrfach vorhanden!
+#
+# 182/183: Netgroup "..." not defined!
+#
+Netgroup "
+" nicht vorhanden!
+#
+# 184/185: Ethernet connector "...": Duplicated entry!
+#
+Datendose "
+": mehrfach vorhanden!
+#
+# 186/187: Ethernet speed setting "..." not defined!
+#
+Geschwindigkeitseinstellung "
+" nicht vorhanden!
+#
+# 188/189: VLAN "..." not defined!
+#
+VLAN "
+" nicht vorhanden!
+#
+# 190/191: Building "..." not defined!
+#
+Gebäude "
+" nicht vorhanden!
+#
+# 192/193: Failed to convert net mask "..."!
+#
+Netzwerkmaske "
+" konnte nicht gelesen werden!
+#
+# 194: Using default net mask 255.255.255.0!
+#
+Standard-Netzwerkmaske 255.255.255.0 wird benutzt!
+#
+# 195/196: Failed to convert default gateway "..."!
+#
+Netzwerk-Gateway "
+" konnte nicht gelesen werden!
+#
+# 197/198: Using default gateway ...
+#
+Standard-Gateway
+wird verwendet.
+#
+# 199/200: Failed to convert broadcast address!
+#
+Broadcast-Adresse "
+" konnte nicht gelesen werden!
+#
+# 201/202: Network "...": Duplicated entry!
+#
+Network "
+": mehrfach vorhanden!
+#
+# 203: Attempt to define IP network without specifying an IP address!
+#
+IP-Netzwerk-Definition ohne Basisadresse!
+#
+# 204/205: DHCP class "...": Duplicated entry!
+#
+DHCP-Klasse "
+": mehrfach vorhanden!
+#
+# 206/207: DHCP group "...": Duplicated entry!
+#
+DHCP-Gruppe "
+": mehrfach vorhanden!
+#
+# 208/209: Invalied network address "..."!
+#
+Netzwerkadresse "
+" ist fehlerhaft!
+#
+# 210/211: DHCP class "..." not defined!
+#
+DHCP-Klasse "
+" nicht vorhanden!
+#
+# 212/213: Network "..." not defined!
+#
+Netzwerk "
+" nicht vorhanden!
+#
+# 214/215: DHCP pool "...": Invalid end address!
+#
+DHCP-Pool "
+": Endadresse fehlerhaft!
+#
+# 216/217: DHCP pool "...": Missing end address!
+#
+DHCP-Pool "
+": Endadresse fehlt!
+#
+# 218/219: DHCP pool "...": Invalid start address!
+#
+DHCP-Pool "
+": Startadresse fehlerhaft!
+#
+# 220: DHCP pool definition attempted with empty start address!
+#
+DHCP-Pool mit leerer Startadresse!
+#
+# 221/222: Computer "...": Illegal MAC address!
+#
+Computer "
+": Unzulässige MAC-Adresse!
+#
+# 223/224: Computer "...": MAC address too long!
+#
+Computer "
+": MAC-Adresse zu lang!
+#
+# 225/226/227: Computer "...": User "..." not defined!
+#
+Computer "
+": Benutzer "
+" nicht vorhanden!
+#
+# 228/229/230: Computer "...": Netgroup "..." not defined!
+#
+Computer "
+": Netgroup "
+" nicht vorhanden!
+#
+# 231/232/233: Computer "...": DHCP class "..." not defined!
+#
+Computer "
+": DHCP-Klasse "
+" nicht vorhanden!
+#
+# 234/235/236: Computer "...": DHCP group "..." not defined!
+#
+Computer "
+": DHCP-Gruppe "
+" nicht vorhanden!
+#
+# 237/238/239: Computer "...": Ethernet connector "..." not defined!
+#
+Computer "
+": Datendose "
+" nicht vorhanden!
+#
+# 240/241/242: Computer "...": Building "..." not defined!
+#
+Computer "
+": Gebäude "
+" nicht vorhanden!
+#
+# 243/244: Computer "...": Both DHCP class and IP address defined!
+#
+Computer "
+":\nSowohl DHCP-Klasse als auch IP-Adresse zugewiesen!
+#
+# 245/246: Computer "...": DHCP class specified, but MAC address missing!
+#
+Computer "
+":\nDHCP-Klasse zugewiesen, aber keine MAC-Adresse!
+#
+# 247/248: Computer "...": Netgroup specified, but IP address missing!
+#
+Computer "
+":\nNetgroup zugewiesen, aber keine IP-Adresse!
+#
+# 249/250: Computer "...": Netgroup specified, but DNS domain missing!
+#
+Computer "
+":\nNetgroup zugewiesen, aber keine DNS-Domäne!
+#
+# 251/252: Computer "...": FQDN first flag set, but DNS domain missing!
+#
+Computer "
+":\nFQDN-Angabe gewünscht, aber keine DNS-Domäne angegeben!
+#
+# 253/254: Computer "...": Over expiration date, should be removed!
+#
+Computer "
+":\nZulassungszeitraum abgelaufen, entweder verlängern oder Computer löschen!
+#
+# 255: Attempt to define a computer without a host name!
+#
+Versuch, Computer ohne Hostnamen zu definieren!
+#
+# 256/257/258: Alias "...": Computer "..." not defined!
+#
+Alias "
+": Computer "
+" nicht vorhanden!
+#
+# 259/260/261: DHCP option ...: VLAN "..." not defined!
+#
+DHCP-Option
+: VLAN "
+" nicht vorhanden!
+#
+# 262/263/264: DHCP option ...: Network "..." not defined!
+#
+DHCP-Option
+: Netzwerk "
+" nicht vorhanden!
+#
+# 265/266/267: DHCP option ...: DHCP group "..." not defined!
+#
+DHCP-Option
+: DHCP-Gruppe "
+" nicht vorhanden!
+#
+# 268/269/270: DHCP option ...: DHCP pool "..." not defined!
+#
+DHCP-Option
+: DHCP-Pool "
+" nicht vorhanden!
+#
+# 271/272/273: DHCP option ...: Computer "..." not defined!
+#
+DHCP-Option
+: Computer "
+" nicht vorhanden!
+#
+# 274/275/276: DHCP option ...: Unknown scope type name "..."!
+#
+DHCP-Option
+: Unzulässiger Scope-Type "
+"!
+#
+# 277/278: Software product "...": Duplicated entry!
+#
+Softwareprodukt "
+": mehrfach vorhanden!
+#
+# 279/280/281: Software product "...": Manufacturer "..." not defined!
+#
+Softwareprodukt "
+": Softwarehersteller "
+" nicht vorhanden!
+#
+# 282/283: License type "...": Duplicated entry!
+#
+Lizenztyp "
+": mehrfach vorhanden!
+#
+# 284/285: License ...: Duplicated entry!
+#
+Lizenz
+: mehrfach vorhanden!
+#
+# 286/287/288: License ...: User "..." not defined!
+#
+Lizenz
+: Benutzer "
+" nicht vorhanden!
+#
+# 289/290/291: License ...: Computer "..." not defined!
+#
+Lizenz
+: Computer "
+" nicht vorhanden!
+#
+# 292/293/294: License ...: License type "..." not defined!
+#
+Lizenz
+: Lizenztyp "
+" nicht vorhanden!
+#
+# 295/296/297: License ... assigned to computer "..." but no user specified!
+#
+Lizenz
+ wurde dem Computer "
+" zugewiesen,\naber keinem Benutzer!
+#
+# 298/299: License ...: No software product specified!
+#
+Lizenz
+: Kein Softwareprodukt angegeben!
+#
+# 300/301: Illegal date specification "..."!
+#
+Unzulässige Datumsangabe: "
+"!
+#
+# 302: Koma-script suggestion
+#
+Die Verwendung von koma-script ist derzeit deaktiviert.\nNutzer in Europa - speziell in deutschsprachigen Ländern - sollten\nkoma-script aktivieren.
+#
+# 303/304
+#
+Unzulässiger Kurzname für Software-Hersteller: "
+"!
+#
+# 305/306
+#
+Unzulässiger Kurzname für Software: "
+"!
+#
+# 307/308
+#
+Unzulässiger Kurnzname für Lizenztyp: "
+"!
+#
+# 309
+#
+Sensitiver Speicherbereich nicht zurückgesetzt!
diff --git a/support/dktools/dktools/de/lprngcl.str b/support/dktools/dktools/de/lprngcl.str
new file mode 100644
index 0000000000..aaffda5d4c
--- /dev/null
+++ b/support/dktools/dktools/de/lprngcl.str
@@ -0,0 +1,53 @@
+#
+# 0 ERROR: Failed to set up signal handlers!
+#
+Signal-Handler konnten nicht eingerichtet werden!
+#
+# 1 ERROR: Failed to restore signal handlers!
+#
+Signal-Handler konnten nicht wiederhergestellt werden!
+#
+# 2 ERROR: Failed to set up text stream processor!
+#
+Text-Analyse konnte nicht initialisiert werden!
+#
+# 3 ERROR: Failed to construct request!
+#
+Request konnte nicht konstruiert werden!\nQueue- oder Nutzername zu lang!
+#
+# 4 ERROR: Failed to convert queue name to 8 bit text!
+#
+Queue-Name konnte nicht zu 8-Bit-Text konvertiert werden!
+#
+# 5 ERROR: No host name specified in queue!
+#
+Queue-Name enthält keinen Host-Namen!
+#
+# 6 ERROR: Queue name too long!
+#
+Der Queue-Name ist zu lang!
+#
+# 7 ERROR: Failed to obtain command line argument (bug)!
+#
+Fehler beim Durchsuchen der Kommandozeilen-Argumente (Bug)!
+#
+# 8 ERROR: Failed to convert user name to 8 bit text!
+#
+Nutzer-Name konnte nicht zu 8-Bit-Text konvertiert werden!
+#
+# 9 ERROR: Failed to find current user name!
+#
+Nutzer-Name konnte nicht ermittelt werden!
+#
+# 10 ERROR: Queue name(s) required!
+#
+Keine Queue-Namen angegeben, diese sind erforderlich!
+#
+# 11 ERROR: Failed to write to standard output!
+#
+Problem(e) beim Schreiben in Standardausgabe!
+#
+# 12 13
+#
+Request:\n"
+".
diff --git a/support/dktools/dktools/de/lprngcl.txt b/support/dktools/dktools/de/lprngcl.txt
new file mode 100644
index 0000000000..1edd5e39cb
--- /dev/null
+++ b/support/dktools/dktools/de/lprngcl.txt
@@ -0,0 +1,70 @@
+
+BEZEICHNUNG
+
+ lprngcl - Clean LPRng print queues
+
+ÃœBERSICHT
+
+ lprngcl [-a] [-v] [-t <Sekunden> [<Druckwarteschlange(n)>]
+ lprngcl [--help] [--version] [--license] [--manual]
+
+BESCHREIBUNG
+
+Das Programm löscht alle Druckaufträge, die vom aktuellen Benutzer
+erzeugt wurden aus den angegebenen LPD/LPRng-Druckwarteschlangen.
+Vorgesehen ist es für den Einsatz in PC-Laboren bzw. PC-Lehrklassen in
+Schulen oder Hochschulen.
+Meldet sich hier ein Nutzer vom Computer ab, kann davon ausgegangen werden,
+dass er den Raum verlässt und kein Interesse mehr an den ausgelösten
+Druckaufträgen besteht.
+
+OPTIONEN
+
+-a
+--ascii
+ Der LPRng-Host verwendet ASCII-Encoding. Standard: UTF-8.
+
+-t <Sekunden>
+--timeout=<Sekunden>
+ Timeout für Netzwerk-Operationen.
+
+-v
+--verbose
+ Ausführliche Ausgabe erzeugen, Antwort des LPRng-Servers
+ anzeigen.
+
+--help
+ Hilfetext anzeigen.
+
+--version
+ Versionshinweise anzeigen.
+
+--license
+ Lizenzbedingungen anzeigen.
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+HINWEISE
+
+In Version 4.3.0 und später verwendet lprngcl keine dk3print.conf-Datei mehr.
+Somit steht aber auch kein Standard-Host und keine Standard-Druckwarteschlange
+mehr zur Verfügung.
+Die aufzuräumenden Druckwarteschlangen müssen in der Form
+<Warteschlange>@<Host> als Kommandozeilenargumente angegeben werden.
+
+AUTOR
+
+Dirk Krause
+
+COPYRIGHT UND LIZENZ
+
+Run
+ lprngcl --license-terms
+to see the license conditions.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/de/pjsnmp.str b/support/dktools/dktools/de/pjsnmp.str
new file mode 100644
index 0000000000..7fa8812a69
--- /dev/null
+++ b/support/dktools/dktools/de/pjsnmp.str
@@ -0,0 +1,355 @@
+#
+# NOTE: Status messages from pjsnmp are shown by lpq as Filter_Status
+# lines. The lpq program or equivalents are run not only on the print
+# server but on print clients too.
+#
+# Print clients are not required to use the same encoding as the print
+# server. Some Linux/Unix clients use UTF-8 encoding, others don't.
+#
+# CONCLUSION: When localizing this string file stick to the ASCII
+# character set. Avoid any characters requiring UTF-8 encoding, i.e.
+# german umlauts.
+#
+#
+#
+# 0 Status: Printer ready.
+#
+Drucker bereit.
+#
+# 1 Status: Printer warming up.
+#
+Drucker-Aufwaermphase.
+#
+# 2 Status: Printing.
+#
+Es wird gedruckt.
+#
+# 3 Status: Waiting for printer to start printing.
+#
+Auf Beginn des Druckvorganges wird gewartet.
+#
+# 4 Status: Error on printer.
+#
+MANUELLES EINGREIFEN ERFORDERLICH! (PAPIERSTAU...)
+#
+# 5 Status: Printer in unknown state.
+#
+Unbekannter Drucker-Zustand.
+#
+# 6 Status: Printer does not respond.
+#
+DRUCKER NICHT ANSPRECHBAR! BITTE DRUCKER EINSCHALTEN!
+#
+# 7 Status: Failed to create SNMP request.
+#
+FEHLER: SNMP-Anfrage konnte nicht erstellt werden!
+#
+# 8 Status: Invalid SNMP response from printer!
+#
+FEHLER: Ungueltige SNMP-Antwort vom Drucker.
+#
+# 9 SNMP response:
+#
+SNMP-Antwort:
+#
+# 10 device=0
+#
+hrDeviceStatus=0,
+#
+# 11 device=unknown
+#
+hrDeviceStatus=unknown (1),
+#
+# 12 device=running
+#
+hrDeviceStatus=running (2),
+#
+# 13 device=warning
+#
+hrDeviceStatus=warning (3),
+#
+# 14 device=testing
+#
+hrDeviceStatus=testing (4),
+#
+# 15 device=down
+#
+hrDeviceStatus=down (5),
+#
+# 16 printer=0
+#
+hrPrinterStatus=0.
+#
+# 17 printer=other
+#
+hrPrinterStatus=other (1).
+#
+# 18 printer=unknown
+#
+hrPrinterStatus=unknown (2).
+#
+# 19 printer=idle
+#
+hrPrinterStatus=idle (3).
+#
+# 20 printer=printing
+#
+hrPrinterStatus=printing (4).
+#
+# 21 printer=warmup
+#
+hrPrinterStatus=warmup (5).
+#
+# 22 Error: Out of paper!
+#
+DRUCKER-FEHLER: KEIN PAPIER!
+#
+# 23 Information: Paper available.
+#
+Drucker-Fehler behoben: Papier vorhanden.
+#
+# 24 Error: Paper low.
+#
+Drucker-Warnung: Wenig Papier.
+#
+# 25 Information: No more paper low.
+#
+Drucker-Warnung behoben: Ausreichend Papier.
+#
+# 26 Error: Out of toner!
+#
+DRUCKER-FEHLER: KEIN TONER!
+#
+# 27 Information: Error condition resolved (no toner).
+#
+Drucker-Fehler behoben: Toner vorhanden.
+#
+# 28 Warning condition: toner low.
+#
+Drucker-Warnung: Wenig Toner.
+#
+# 29 Information: Printer conditions resolved (toner low).
+#
+Drucker-Warnung behoben: Ausreichend Toner.
+#
+# 30 Error: Output tray full!
+#
+DRUCKER-FEHLER: AUSGABESCHACHT VOLL!
+#
+# 31 Information: Error condition resolved (output tray full).
+#
+Drucker-Fehler behoben: Ausgabeschacht ok.
+#
+# 32 Warning: Output tray nearly full!
+#
+Drucker-Warnung: Ausgabeschacht fast voll!
+#
+# 33 Information: Warning condition resolved (output tray nearly full).
+#
+Drucker Warnung behoben: Ausgabeschacht ok.
+#
+# 34 Error: Door open!
+#
+DRUCKER-FEHLER: DRUCKER OFFEN!
+#
+# 35 Information: Door now closed.
+#
+Drucker-Fehler behoben: Nicht mehr offen.
+#
+# 36 Error: Paper jam!
+#
+DRUCKER-FEHLER: PAPIERSTAU!
+#
+# 37 Information: Error condition resolved (paper jam).
+#
+Drucker-Fehler behoben: Kein Papierstau.
+#
+# 38 Error: Printer offline!
+#
+DRUCKER-FEHLER: DRUCKER IST OFFLINE!
+#
+# 39 Information: Error condition resolved (printer offline).
+#
+Drucker-Fehler behoben: Nicht mehr offline.
+#
+# 40 Error: Service requested!
+#
+Drucker-Warning: Manuelles Eingreifen erforderlich.
+#
+# 41 Information: Error condition resolved (service requested).
+#
+Drucker-Warnung behoben: Kein Eingreifen erforderlich.
+#
+# 42 Error: Input tray missing!
+#
+DRUCKER-FEHLER: EINGABESCHACHT FEHLT!
+#
+# 43 Information: Error condition resolved (input tray missing).
+#
+Drucker-Fehler behoben: Eingabeschacht vorhanden.
+#
+# 44 Error: Output tray missing!
+#
+DRUCKER-FEHLER: AUSGABESCHACHT FEHLT!
+#
+# 45 Information: Error condition resolved (output tray missing).
+#
+Drucker-Fehler behoben: Ausgabeschacht vorhanden.
+#
+# 46 ERROR: Marker supply missing!
+#
+DRUCKER-FEHLER: MARKER-ZUBEHOER (FIXIEREINHEIT?) FEHLT!
+#
+# 47 Information: Error condition resolved (marker supply missing).
+#
+Drucker-Fehler behoben: Marker-Zubehoer vorhanden.
+#
+# 48 Error: Input tray empty!
+#
+Drucker-Warnung: Mindestens ein Eingabeschacht leer.
+#
+# 49 Information: Error condition resolved (input tray empty).
+#
+Drucker-Warnung behoben: Kein leerer Eingabeschacht.
+#
+# 50 Error: Overdue preventive maintenance!
+#
+Drucker-Warnung: Planmaessige Wartung durchfuehren.
+#
+# 51 Information: Error condition resolved (overdue preventive maintenance).
+#
+Drucker-Warnung behoben: Keine Wartung erforderlich.
+#
+# 52/53 Error: Configuration entry "..." needs an argument!
+#
+FEHLER: Argument für Konfigurationseintrag "
+" fehlt!
+#
+# 54
+#
+Druckjob beendet, es traten Fehler auf.
+#
+# 55
+#
+Druckjob erfolgreich fertiggestellt.
+#
+# 55/57
+#
+Druckjob erfolgreich fertiggestellt,
+ Seite(n).
+#
+# 58
+#
+Druckjob durch Signal abgebrochen.
+#
+# 59
+#
+FEHLER: Umgebungsvariable PRINTCAP_ENTRY fehlt!
+#
+# 60
+#
+FEHLER: Zu wenig Hauptspeicher!
+#
+# 61
+#
+FEHLER: Hostname fuer Drucker ist nicht konfiguriert!
+#
+# 62
+#
+FEHLER: Portnummer fuer Drucker ist nicht konfiguriert!
+#
+# 63/64
+#
+FEHLER: Unzulaessiger Accounting-Typ "
+" konfiguriert!
+#
+# 65/66
+#
+FEHLER: Unzulaessige SNMP-Version "
+" konfiguriert!
+#
+# 67/68
+#
+FEHLER: Unzulaessige Portnummern-Angabe "
+" konfiguriert (keine Zahl)!
+#
+# 69/70
+#
+FEHLER: Unzulaessige Portnummern-Angabe "
+" konfiguriert (Zahlenbereichsueberlauf)!
+#
+# 71
+#
+FEHLER: Standardeingabe-Daten konnten nicht in Datei gespeichert werden!
+#
+# 72
+#
+FEHLER: SNMP-Sitzung konnte nicht geoeffnet werden!
+#
+# 73
+#
+Warnung: SNMP-Sitzung konnte nicht geoeffnet werden!
+#
+# 74
+#
+FEHLER: Die temporaere Druckdaten-Datei konnte nicht gelesen werden.
+#
+# 75
+#
+FEHLER: Keine Verbindung zum Drucker herstellbar!
+#
+# 76
+#
+FEHLER: Daten-Senden zum Drucker fehlgeschlagen!
+#
+# 77
+#
+FEHLER: SNMP-Anfrage konnte nicht erstellt werden!
+#
+# 78
+#
+FEHLER: Accounting-Anfrage wird zu lang!
+#
+# 79
+#
+FEHLER: Kein Benutzername fuer aktuellen Druckjob gefunden!
+#
+# 80
+#
+FEHLER: Kein Druckername fuer aktuellen Druckjob gefunden!
+#
+# 81
+#
+FEHLER: Accounting-Datei ist keine UNIX-Domain-Socket.
+#
+# 82
+#
+FEHLER: Keine Berechtigung fuer diesen Drucker!
+#
+# 83
+#
+FEHLER: Verbindung zum Accounting-System nicht moeglich!
+#
+# 84
+#
+FEHLER: Daten-Senden zum Accounting-System fehlgeschlagen!
+#
+# 85
+#
+FEHLER: Shutdown der Accounting-Socket fehlgeschlagen!
+#
+# 86
+#
+Zaehlerstand vor Druckjob:
+#
+# 87
+#
+Zaehlerstand nach Druckjob:
+#
+# 88
+#
+Antwort vom Drucker:
+#
+# 89
+#
+FEHLER: Signal-Behandlung konnte nicht konfiguriert werden!
diff --git a/support/dktools/dktools/de/plpdftex.str b/support/dktools/dktools/de/plpdftex.str
new file mode 100644
index 0000000000..bb4c915f76
--- /dev/null
+++ b/support/dktools/dktools/de/plpdftex.str
@@ -0,0 +1,156 @@
+#
+# 0 Program name
+#
+plpdftex
+#
+# 1
+#
+Zu viele Argumente, nur ein Dateiname erlaubt!
+#
+# 2
+#
+Erstes Argument nicht gefunden (möglicherweise ein Bug)!
+#
+# 3
+#
+Erste Zeile enthält keine Ausgabedatei-Namen!
+#
+# 4
+#
+Dateiname in der ersten Zeile zu lang!
+#
+# 5
+#
+Dateinamens-Endung muss *.pdftex oder *.pdftexs sein!
+#
+# 6
+#
+Zweite Zeile mit Breiten- und Höhenangabe fehlt!
+#
+# 7
+#
+Breite und Höhe nicht angegeben!
+#
+# 8
+#
+Zahlenbereichsüberlauf, Breite und/oder Höhe zu groß!
+#
+# 9
+#
+PDF-Daten konnten nicht in Datei geschrieben werden!
+#
+# 10
+#
+PDF-Seite konnte nicht geöffnet werden!
+#
+# 11
+#
+PDF-Seite konnte nicht geschlossen werden!
+#
+# 12
+#
+Syntax-Fehler, Dokument bereits beendet!
+#
+# 13
+#
+Syntax-Fehler, Zeile muss mit "t", "p" oder "#" beginnen!
+#
+# 14
+#
+Syntax-Fehler, kein Kommando angegeben!
+#
+# 15
+#
+PDF-Clip-Operation fehlgeschlagen!
+#
+# 16
+#
+PDF-Fill-Operation fehlgeschlagen!
+#
+# 17
+#
+PDF-Stroke-Operation fehlgeschlagen!
+#
+# 18
+#
+PDF-Closepath-Operation fehlgeschlagen!
+#
+# 19
+#
+PDF-Curveto-Operation fehlgeschlagen!
+#
+# 20
+#
+Syntax-Fehler, Zahlenwert wird erwartet!
+#
+# 21
+#
+Syntax-Fehler, zu wenig Argumente für Kommando!
+#
+# 22
+#
+PDF-Moveto-Operation fehlgeschlagen!
+#
+# 23
+#
+Syntax-Fehler, negativer Radius!
+#
+# 24
+#
+PDF-Lineto-Operation fehlgeschlagen!
+#
+# 25
+#
+PDF-Operation zum Setzen der Füllfarbe fehlgeschlagen!
+#
+# 26
+#
+Syntax-Fehler, Farbe ist nicht bekannt!
+#
+# 27
+#
+PDF-Operation zum Setzen der Strichfarbe fehlgeschlagen!
+#
+# 28
+#
+PDF-Set-Dash-Operation fehlgeschlagen!
+#
+# 29
+#
+PDF-Set-Linejoin-Operation fehlgeschlagen!
+#
+# 30
+#
+PDF-Set-Linecap-Operation fehlgeschlagen!
+#
+# 31
+#
+Syntax-Fehler, negative Linienbreite!
+#
+# 32
+#
+PDF-Set-Linewidth-Operation fehlgeschlagen!
+#
+# 33
+#
+PDF-Grestore-Operation fehlgeschlagen!
+#
+# 34
+#
+PDF-Gsave-Operation fehlgeschlagen!
+#
+# 35
+#
+Daten konnten nicht in TeX-Ausgabedatei geschrieben werden!
+#
+# 36
+#
+Syntax-Fehler, ungültige Angabe für horizontale Ausrichtung!
+#
+# 37
+#
+Syntax-Fehler, ungültige Angabe für vertikale Ausrichtung!
+#
+# 38
+#
+Syntax-Fehler, falsche Reihenfolge von fs, font-setup, package, preamble, text!
diff --git a/support/dktools/dktools/de/printqd.str b/support/dktools/dktools/de/printqd.str
new file mode 100644
index 0000000000..3528623e61
--- /dev/null
+++ b/support/dktools/dktools/de/printqd.str
@@ -0,0 +1,60 @@
+#
+# 0 The string table name.
+#
+printqd.str
+#
+# 1,2 Request received:
+#
+REQUEST:\n
+
+#
+# 3,4 Response:
+#
+RESPONSE:\n
+
+#
+# 5,6,7
+#
+Limit=%lu used=%lu account=%lu job=%lu => used=%lu account=%lu
+ERGEBNIS:\n
+
+#
+# 8,9 ERROR: Database name too long!
+#
+Datenbank-Dateiname zu lang:\n"
+"!
+#
+# 10
+#
+Gruppenwechsel zu Nicht-root-Gruppe fehlgeschlagen!
+#
+# 11
+#
+Wechsel zu Nicht-root-Account fehlgeschlagen!
+#
+# 12,13
+#
+Name für Konfigurationsverzeichnis zu lang:\n"
+"!
+#
+# 14,15 ERROR: Failed to change owner for directory!
+#
+Verzeichniseigentümer konte nicht geändert werden für: "
+"!
+#
+# 16,17 ERROR: Failed to create directory!
+#
+Verzeichnis konnte nicht angelegt werden: "
+"!
+#
+# 18 Message: Exiting printqd normally.
+#
+Printqd wird normal beendet (durch Signal).
+#
+# 19 ERROR: Exiting due to errors.
+#
+Printqd wird wegen aufgetretenen Fehlern beendet!
+#
+# 20 ERROR: Failed to set up signal handling!
+#
+Signalbehandlung konnte nicht aktiviert werden!
diff --git a/support/dktools/dktools/de/printqda.str b/support/dktools/dktools/de/printqda.str
new file mode 100644
index 0000000000..f447633f6f
--- /dev/null
+++ b/support/dktools/dktools/de/printqda.str
@@ -0,0 +1,65 @@
+#
+# 0 Name of localized message texts file.
+#
+printqda.str
+#
+# 1 2 Option was already set!
+#
+Die Option wurde bereits gesetzt: "
+"!
+#
+# 3 4 Option not started by a character!
+#
+Option beginnt nicht mit einem Buchstaben: "
+"!
+#
+# 5 6 Empty option!
+#
+Leere option: "
+"!
+#
+# 7 Syntax error in request!
+#
+Syntax-Fehler in Request!
+#
+# 8 Syntax error, string not finalized!
+#
+Syntax-Fehler, String nicht abgeschlossen!
+#
+# 9 Request contents too long!
+#
+Request zu lang!
+#
+# 10 Incomplete request!
+#
+Unvollständiger Request!\nMindestens eine Angabe fehlt:\nNutzername, Druckername, Zählerstand, Jobname oder Job-Titel!
+#
+# 11 Too few arguments in request!
+#
+Zu wenige Angaben in Request!
+#
+# 12 Incomplete request!
+#
+Unvollständiger Request! Nutzer- oder Druckername fehlt!
+#
+# 13 14 Illegal control sub-request!
+#
+Unzulässiger Control-Request: "
+"!
+#
+# 15
+#
+Keine Verbindung, alle folgenden Eingaben werden ignoriert!
+#
+# 16 17
+#
+Dateiname für Konfigurationsverzeichnis zu lang:\n"
+"!
+#
+# 18
+#
+Dateiname für Konfigurationsverzeichnis nicht gefunden!
+#
+# 19
+#
+Nur printqda kann control-Requests verarbeiten, nicht printqdc!
diff --git a/support/dktools/dktools/de/printqdc.str b/support/dktools/dktools/de/printqdc.str
new file mode 100644
index 0000000000..ec5a41c8a8
--- /dev/null
+++ b/support/dktools/dktools/de/printqdc.str
@@ -0,0 +1,132 @@
+#
+# 0 String table file name
+#
+printqdc.str
+#
+# 1, 2 ERROR: Not a limit value!
+#
+Ungültige Limit-Angabe: "
+"!
+#
+# 3, 4 ERROR: Alias already exists!
+#
+Alias bereits vorhanden: "
+"!
+#
+# 5, 6 ERROR: Printer already exists!
+#
+Drucker bereits vorhanden: "
+"!
+#
+# 7, 8 ERROR: Class already defined!
+#
+Klasse bereits vorhanden: "
+"!
+#
+# 9 ERROR: Missing class name!
+#
+Klassenname fehlt!
+#
+# 10 ERROR: No argument allowed after section title!
+#
+Argumente nach diesem Abschnitts-Namen nicht erlaubt!
+#
+# 11, 12 ERROR: Illegal configuration section title!
+#
+Unzulässiger Abschnitts-Name: "
+"!
+#
+# 13 ERROR: Closing bracket is missing!
+#
+Schließende eckige Klammer fehlt!
+#
+# 14 ERROR: Printer already assigned to a class!
+#
+Der Drucker ist bereits einer Klasse zugeordnet!
+#
+# 15, 16 ERROR: No such class
+#
+Klasse nicht definiert: "
+"!
+#
+# 17, 18 ERROR: Illegal configuration key!
+#
+Unzulässiger Konfigurationseintrag: "
+"!
+#
+# 19, 20 ERROR: Limit for group already defined!
+#
+Für die Gruppe "
+" wurde bereits ein Limit festgelegt!
+#
+# 21
+#
+Die Limit-Angabe muss in der Form "Name:Limit" erfolgen!
+#
+# 22, 23 ERROR: Limit for user already defined!
+#
+Für Nutzer "
+" ist bereits ein Limit definiert!
+#
+# 24 25 ERROR: Illegal deny action!
+#
+Unzulässige Aktion: "
+"! Entweder "remove" oder "hold" erlaubt!
+#
+# 26 ERROR: Database file name already defined!
+#
+Dateiname für Datenbank wurde bereits angegeben!
+#
+# 27 ERROR: Socket file name already defined!
+#
+Dateiname für Socket wurde bereits angegeben!
+#
+# 28 ERROR: Info port already defined!
+#
+TCP-Port für info-Requests wurde bereits angegeben!
+#
+# 29, 30 ERROR: Range overflow in port number!
+#
+Zahlenbereichs-Überlauf für Port-Nummer: "
+"!\nDie Portnummer darf maximal 65535 sein!
+#
+# 30, 31 ERROR: Not a number!
+#
+Keine Zahl: "
+"!
+#
+# 32 ERROR: User account to run daemon is already defined!
+#
+Nutzer-Account wurde bereits angegeben!
+#
+# 33 ERROR: Group to run daemon is already defined!
+#
+Nutzer-Gruppe wurde bereits angegeben!
+#
+# 34, 35 ERROR: No such user!
+#
+Nutzer existiert nicht: "
+"!
+#
+# 36, 37 ERROR: No such group!
+#
+Gruppe existiert nicht: "
+"!
+#
+# 38 ERROR: Missing value!
+#
+Wert-Angabe fehlt!
+#
+# 39, 40 ERROR: Local state directory name too long!
+#
+Name für /var-Verzeichnis zu lang: "
+"!
+#
+# 41 ERROR: Failed to find local state directory name!
+#
+Zu benutzendes /var-Verzeichnis wurde nicht gefunden!
+#
+# 42, 43 ERROR: UNIX domain socket name too long!
+#
+Dateiname für UNIX-Domain-Socket zu lang: "
+"!
diff --git a/support/dktools/dktools/de/printqdi.str b/support/dktools/dktools/de/printqdi.str
new file mode 100644
index 0000000000..075c39e066
--- /dev/null
+++ b/support/dktools/dktools/de/printqdi.str
@@ -0,0 +1,56 @@
+#
+# 0
+#
+Thread-Attribute konnten nicht initialisiert werden!
+#
+# 1
+#
+Standard-Thread-Zustand konnte nicht auf "detached" gesetzt werden!
+#
+# 2
+#
+Mutex-Attribute konnten nicht initialisiert werden!
+#
+# 3
+#
+Standard-Mutex-Typ konnte nicht gesetzt weden.
+#
+# 4
+#
+Programm wird wegen Fehlern beendet.
+#
+# 5
+#
+Programm wird normal beendet (wegen Signal).
+#
+# 6
+#
+Konfigurationsdatei konnte nicht gelesen werden!
+#
+# 7
+#
+Konfigurations-Problem, Prüfung der Konfiguration fehlgeschlagen!
+#
+# 8
+#
+Server-Sockets konnten nicht erstellt werden!
+#
+# 9
+#
+Thread für neue Verbindung konnte nicht angelegt werden!
+#
+# 10
+#
+Wechsel zu Nicht-root-Account fehlgeschlagen!
+#
+# 11
+#
+Wechsel zu Nicht-root-Gruppe fehlgeschlagen!
+#
+# 12
+#
+Dateiname für Konfigurationsdatei nicht gefunden!
+#
+# 13
+#
+Signalbehandlung konnte nicht eingerichtet werden!
diff --git a/support/dktools/dktools/de/winprint.str b/support/dktools/dktools/de/winprint.str
new file mode 100644
index 0000000000..f7c493864a
--- /dev/null
+++ b/support/dktools/dktools/de/winprint.str
@@ -0,0 +1,184 @@
+#
+# 0: Menu "File"
+#
+Datei
+#
+# 1: Menu item "File/Exit"
+#
+Beenden
+#
+# 2: Tool tip text for menu item "File/Exit"
+#
+Anwendung beenden
+#
+# 3: Menu "Help"
+#
+Hilfe
+#
+# 4: Menu item "Help/About"
+#
+Ãœber...
+#
+# 5: Tooltip text for menu item "Help/About"
+#
+Versionsnummber anzeigen
+#
+# 6: Menu item "Help/Contents"
+#
+Inhalt
+#
+# 7: Tooltip text for menu item "Help/Contents"
+#
+Inhaltsverzeichnis der Online-Hilfe öffnen
+#
+# 8: Initial status text
+#
+Bereit
+#
+# 9: Copyright notice.
+#
+Copyright (c)
+#
+# 10: Dialog box title "About ..."
+#
+Ãœber winprint
+#
+# 11: This program uses the following libraries
+#
+Dieses Programm nutzt Bibliotheken aus folgenden Projekten:
+#
+# 12: See
+#
+Siehe:
+#
+# 13: __CHANGE__ 015: Text for dummy label, can be reused if lDummy removed.
+#
+Druckwarteschlangen-Namen werden ermittelt.
+#
+# 14
+#
+Erfolg, Programm wird beendet.
+#
+# 15
+#
+Drucken
+#
+# 16
+#
+Datei zu Drucker senden.
+#
+# 17
+#
+Druckdaten werden übertragen.
+#
+# 18
+#
+Datei auswählen
+#
+# 19
+#
+Abbruch durch Benutzer!
+#
+# 20
+#
+Datenübertragung
+#
+# 21
+#
+Abbrechen
+#
+# 22
+#
+Datenübertragung abbrechen
+#
+# 23
+#
+Datenübertragung wird abgebrochen, bitte warten...
+#
+# 24
+#
+FEHLER: Ungültiger Drucker-Name!
+#
+# 25
+#
+FEHLER: Kein Standarddrucker vorhanden!
+#
+# 26
+#
+FEHLER: Druck-Konfiguration nicht ermittelbar!
+#
+# 27
+#
+FEHLER: Hintergrund-Thread konnte nicht erstellt werden!
+#
+# 28
+#
+FEHLER: Fortschrittsanzeige konnte nicht erstellt werden!
+#
+# 29
+#
+Fehler beim Drucken
+#
+# 30
+#
+Drucker-Auswahl
+#
+# 31
+#
+Drucker auswählen:
+#
+# 32
+#
+OK
+#
+# 33
+#
+Den ausgewählten Drucker verwenden.
+#
+# 34
+#
+Abbrechen
+#
+# 35
+#
+Drucken abbrechen
+#
+# 36
+#
+Ziel-Drucker auswählen
+#
+# 37
+#
+Datenübertragung abgeschlossen.
+#
+# 38
+#
+FEHLER: Druck-Daten können nicht in Job-Datei geschrieben werden!
+#
+# 39
+#
+FEHLER: Eingabedatei kann nicht gelesen werden!
+#
+# 40
+#
+FEHLER: Job kann nicht in Druckwarteschlange eingefügt werden!
+#
+# 41
+#
+FEHLER: Job-Datei kann nicht erzeugt werden!
+#
+# 42
+#
+FEHLER: Job kann nicht in Druckwarteschlange eingefügt werden!
+#
+# 43
+#
+FEHLER: Druckwarteschlange kann nicht geöffnet werden!
+#
+# 44
+#
+FEHLER: Dateiname nicht verwendbar!
+#
+# 45
+#
+FEHLER: Druckername nicht verwendbar!
diff --git a/support/dktools/dktools/de/wprclean.str b/support/dktools/dktools/de/wprclean.str
new file mode 100644
index 0000000000..a2a553cd58
--- /dev/null
+++ b/support/dktools/dktools/de/wprclean.str
@@ -0,0 +1,21 @@
+#
+# 0 1
+#
+Druckjob
+ gelöscht.
+#
+# 2 3 4
+#
+Druckjob
+, konnte nicht gelöscht werden, Fehlercode:
+.
+#
+# 5 6
+#
+Auf Drucker "
+" kann nicht zugegriffen werden!
+#
+# 7 8
+#
+Der Drucker "
+" wurde nicht gefunden!
diff --git a/support/dktools/dktools/de/wprclean.txt b/support/dktools/dktools/de/wprclean.txt
new file mode 100644
index 0000000000..f2a6ce9b5a
--- /dev/null
+++ b/support/dktools/dktools/de/wprclean.txt
@@ -0,0 +1,66 @@
+
+BEZEICHNUNG
+
+ wprclean - Windows print cleanup
+
+ÃœBERSICHT
+
+ wprclean [-c] [<printers>]
+ wprclean [-h] [-v] [-L]
+
+BESCHREIBUNG
+
+Das Programm wprclean löscht alle Druckjobs, die vom aktuellen Nutzer
+erzeugt wurden. Vorgesehen ist es für den Einsatz in PC-Laboren bzw.
+PC-Lehrklassen in Schulen oder Hochschulen.
+Meldet sich hier ein Nutzer vom Computer ab, kann davon ausgegangen werden,
+dass er den Raum verlässt und kein Interesse mehr an den ausgelösten
+Druckaufträgen besteht.
+
+OPTIONEN
+
+-c
+--computer
+ Nur diejenigen Druckaufträge löschen, die auf dem aktuellen
+ Computer erzeugt wurden.
+
+-h
+--help
+ Hilfetext anzeigen.
+
+-v
+--version
+ Versionshinweise anzeigen.
+
+-L
+--license-terms
+ Lizenzbedingungen anzeigen.
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+DATEIEN
+
+Die Datei dk3print.conf kann benutzt werden, um kurze Alias-Namen für
+die Windows-Druckwarteschlangen zu konfigurieren.
+
+HINWEISE
+
+Wenn Sie sowohl wprclean als auch lprngcl verwenden, sollte wprclean
+vor lprngcl benutzt werden.
+
+AUTOR
+
+Dirk Krause
+
+COPYRIGHT UND LIZENZ
+
+Mit
+ wprclean --license
+werden die Lizenzbedingungen angezeigt.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/de/wxbmpp.str b/support/dktools/dktools/de/wxbmpp.str
new file mode 100644
index 0000000000..5fb653b329
--- /dev/null
+++ b/support/dktools/dktools/de/wxbmpp.str
@@ -0,0 +1,482 @@
+#
+# 0: Program name
+#
+wxbmpp
+#
+# 1: Application group name
+#
+dkt-3
+#
+# 2: Software vendor name
+#
+Dirk Krause
+#
+# 3: Empty text.
+#
+
+#
+# 4: Toolbar button text: Directory
+#
+Directory
+#
+# 5: Toolbar button tip text: Choose the directory to process.
+#
+Directory (Verzeichnis) zum Bearbeiten auswählen
+#
+# 6: Toolbar button text: Options
+#
+Optionen
+#
+# 7: Toolbar button tip text: Set conversion options.
+#
+Einstellungen für die Konvertierung vornehmen
+#
+# 8: Toolbar button text: Run
+#
+Start
+#
+# 9: Toolbar button tip text: Run conversion
+#
+Konvertierung starten
+#
+# 10: Toolbar button text: Exit
+#
+Beenden
+#
+# 11: Toolbar button tip text: Exit the application
+#
+Programm beenden
+#
+# 12: Menu text: File
+#
+&Datei
+#
+# 13: Menu text: Help
+#
+&Hilfe
+#
+# 14: Menu item text: Directory
+#
+&Directory... Alt-D
+#
+# 15: Menu item tip text: Choose directory
+#
+Directory (Verzeichnis) auswählen
+#
+# 16: Menu item text: Options
+#
+&Optionen Alt-O
+#
+# 17: Menu item tip text: Set conversion options
+#
+Einstellungen für die Konvertierung vornehmen
+#
+# 18: Menu item text: Run
+#
+&Start Alt-S
+#
+# 19: Menu item tip text: Run conversion
+#
+Konvertierung starten
+#
+# 20: Menu item text: Exit
+#
+&Beenden Alt-B
+#
+# 21: Menu item tip text: Exit the application
+#
+Programm beenden
+#
+# 22: Menu item: Contents
+#
+&Inhalt F1
+#
+# 23: Menu item tip text: Show table of contents
+#
+Inhaltsverzeichnis der Hilfe anzeigen
+#
+# 24: Menu item text: About
+#
+&Ãœber... Alt-I
+#
+# 25: Menu item tip text: Show version number
+#
+Informationen über wxbmpp
+#
+# 26: Label text: Directory:
+#
+Directory:
+#
+# 27: Empty string to indicate no directory name available
+#
+
+#
+# 28: Empty string for initial status text
+#
+
+#
+# 29: Directory dialog title: Choose directory
+#
+Directory auswählen
+#
+# 30: Autorun result: Processing succeeded, application will exit.
+#
+Verarbeitung war erfolgreich, Programm wird beendet.
+#
+# 31: ERROR: Automatic run canceled due to errors.
+#
+Kein automatischer Start wegen Fehler!
+#
+# 32: Progress dialog title: Conversion progress
+#
+Fortschritt der Konvertierung
+#
+# 33: Progress dialog button title: Cancel
+#
+Abbrechen
+#
+# 34: Progress dialog button tool tip: Abort after current file
+#
+Verarbeitung nach aktueller Datei abbrechen
+#
+# 35: Notification text: Cancel command scheduled... wait, please!
+#
+Abbruch eingeleitet... Bitte warten!
+#
+# 36: Options dialog box title
+#
+Konvertierungs-Optionen
+#
+# 37: Options dialog box paragraph: General
+#
+Allgemeine Einstellungen
+#
+# 38: Checkbox: Make mode
+#
+Make-Modus
+#
+# 39: Tool tip for checkbox make mode
+#
+Konvertierung nur starten, falls keine aktuelle Zieldatei vorhanden.
+#
+# 40: Dialog box paragraph: Output
+#
+Ausgabe
+#
+# 41: Label output format
+#
+Ausgabeformat:
+#
+# 42: Output format PS
+#
+PS
+#
+# 43: Output format EPS
+#
+EPS
+#
+# 44: Output format PDF
+#
+PDF
+#
+# 45: Output format: Bounding box
+#
+Bounding Box
+#
+# 46: Label output type
+#
+Ausgabe-Modus:
+#
+# 47: Output type image
+#
+Bild
+#
+# 48: Output type object
+#
+Objekt
+#
+# 49: Output type document
+#
+Dokument
+#
+# 50: Label finishing
+#
+Fertigstellung:
+#
+# 51: Finishing Single-side
+#
+Einseitig
+#
+# 52: Finishing duplex, no tumble
+#
+Zweiseitig (Buch)
+#
+# 53: Finishing duplex and tumble
+#
+Zweiseitig (Kalender)
+#
+# 54: Checkbox draft mode
+#
+Entwurf
+#
+# 55: Tool tip text for draft checkbox
+#
+Nur Platzhalter anstelle der Bilder erzeugen
+#
+# 56: Checkbox color
+#
+Farbe
+#
+# 57: Tool tip text for checkbox color
+#
+Farbige PS-Ausgabe erlauben
+#
+# 58: Paragraph output size
+#
+Größe
+#
+# 59: label resolution
+#
+Auflösung
+#
+# 60: Resolution 1 pixel = 1 point
+#
+1px=1pt
+#
+# 61: Resolution as specified in input file
+#
+Eingabedatei
+#
+# 62: Resolution as specified
+#
+Auflösung angeben:
+#
+# 63: Label paper size
+#
+Papiergröße:
+#
+# 64: Paragraph image quality
+#
+Bildqualität
+#
+# 65: Checkbox image interpolation
+#
+Interpolation
+#
+# 66: Tool tip text for checkbox image interpolation
+#
+Pixel-Interpolation erlauben
+#
+# 67: Checkbox image interpolation for JPEG
+#
+Interpolation auch für JPEG-Dateien
+#
+# 68: Tool tip text for checkbox image interpolation for JPEG files
+#
+Pixel-Interplation auch für DCT-Daten aus JPEG-Dateien erlauben
+#
+# 69: Paragraph transparency
+#
+Transparenz
+#
+# 70: Label background color
+#
+Hintergrund-Farbe:
+#
+# 71: Checkbox Force background color
+#
+Hintergrund-Farbe immer verwenden
+#
+# 72: Tool tip text for checkbox force background
+#
+Immer die angegebene Hintergrundfarbe verwenden, Angaben in Quelldatei ignorieren
+#
+# 73: Paragraph output format details
+#
+Details für Ausgabe
+#
+# 74: Label PS level
+#
+PS Level:
+#
+# 75: Label predictor
+#
+Predictor:
+#
+# 76: Predictor none
+#
+None
+#
+# 77: Predictor tiff
+#
+TIFF
+#
+# 78: Predictor sub
+#
+PNG-SUB
+#
+# 79: Predictor up
+#
+PNG-UP
+#
+# 80: Predictor average
+#
+PNG-AVERAGE
+#
+# 81: Predictor paeth
+#
+PNG-PAETH
+#
+# 82: Checkbox DSC
+#
+DSC
+#
+# 83: Tool tip text for checkbox dsc
+#
+DSC-Kommentare erzeugen
+#
+# 84: Button text OK
+#
+OK
+#
+# 85: Tool tip for OK button
+#
+Einstellungen übernehmen und Dialogbox verlassen
+#
+# 86: Button Cancel
+#
+Abbrechen
+#
+# 87: Tool tip for cancel button
+#
+Einstellungen verwerfen und Dialogbox verlassen
+#
+# 88: Tool tip for color viewer.
+#
+Klicken Sie hier, um die Hintergrundfarbe einzustellen
+#
+# 89: Check box: Use DCT compressed data from JPEGs directly
+#
+DCT-Daten aus JPEG-Dateien direkt benutzen
+#
+# 90: Tool tip text: Allow direct re-usse of DCT compressed data from JPEGs
+#
+DCT-komprimierte Daten aus JPEG-Dateien direkt benutzen
+#
+# 91: Tool tip: Choose output format
+#
+Ausgabeformat auswählen: PS / EPS / PDF oder Bounding Box
+#
+# 92: Tool tip: Choose output type
+#
+Ausgabe-Typ auswählen: Bild / Objekt / Dokument
+#
+# 93: Tool tip: Choose finishing
+#
+Fertigstellung auswählen: Einseitig / Doppelseitig (Buch) / Doppelseitig (Kalender)
+#
+# 94: Tool tip: Choose resolution handling
+#
+Auflösung festlegen: 1 pixel = 1 PS Point / Eingabedatei-Auflösung / Auflösung angeben / Papiergröße
+#
+# 95: Tool tip: Choose a paper size
+#
+Wählen Sie die Papiergröße. Großgeschriebene Papiergrößen-Namen verwenden das Blatt komplett, kleingeschriebene Namen lassen einen Rand
+#
+# 96: Tool tip: Choose a PS level
+#
+Wählen Sie den PS-Level (2 oder 3)
+#
+# 97: Tool tip: Choose a predictor for flate compression
+#
+Wählen Sie einen Predictor für die Flate-Kompression (im Zweifelsfall keinen)
+#
+# 98: Tool tip: Specify a resolution in dpi
+#
+Geben Sie die Auflösung in dpi (Pixel pro Inch) an
+#
+# 99: Menu item: Setup...
+#
+Einstellungen... Alt-E
+#
+# 100: Tool tip for menu item Setup
+#
+Einstellungen für die Konvertierung vornehmen
+#
+# 101: Menu item: Reset options
+#
+Reset... Alt-R
+#
+# 102: Tool tip for menu item Reset options
+#
+Einstellungen auf sinnvolle Standardwerte zurücksetzen
+#
+# 103: Question: Do you really want to reset all options to default values?
+#
+Wollen Sie wirklich alle Einstellungen auf die Standardwerte zurücksetzen?
+#
+# 104: Message box title: Reset all conversion options to default values
+#
+Sind Sie sicher?
+#
+# 105: Error: Not enough memory!
+#
+Zu wenig Hauptspeicher!
+#
+# 106/107: Message: Processing directory "..." (start).
+#
+Verzeichnis "
+" wird bearbeitet.
+#
+# 108/109: Message: Processing directory "..." (finished).
+#
+Verzeichnis "
+" wurde bearbeitet.
+#
+# 110: Newline
+#
+\n
+#
+# 111/112: Error: File name too long!
+#
+Dateiname zu lang:\n"
+"!
+#
+# 113: Error: No file found to convert
+#
+Keine in Frage kommenden Quelldateien gefunden!
+#
+# 114/115: Message: Processing file "..." (start).
+#
+Datei "
+" wird verarbeitet.
+#
+# 116/117: Message: Processing file "..." (finished).
+#
+Datei "
+" wurde verarbeitet.
+#
+# 118/119: Error: File name "..." contains unconvertable characters!
+#
+Der Dateiname "
+" enthält Zeichen, die nicht vearbeitet werden können!
+#
+# 120: Checkbox: Reduce bits per components
+#
+Bits per component reduzieren
+#
+# 121: Tool tip text: Reduce bits per component if possible
+#
+Versuchen, die Bits pro Farbkomponente zu reduzieren
+#
+# 122: Dialog box title: About wxbmpp
+#
+Ãœber wxbmpp
+#
+# 123: This program uses libraries from the following projects
+#
+Dieses Programm nutzt Bibliotheken aus den folgenden Projekten:\n
+#
+# 124: See:
+#
+Siehe:\n
diff --git a/support/dktools/dktools/de/wxdkclock.str b/support/dktools/dktools/de/wxdkclock.str
new file mode 100644
index 0000000000..829b045f6c
--- /dev/null
+++ b/support/dktools/dktools/de/wxdkclock.str
@@ -0,0 +1,116 @@
+#
+# 0: Menu "File"
+#
+Datei
+#
+# 1: Menu item "File/Exit"
+#
+Beenden
+#
+# 2: Tool tip text for menu item "File/Exit"
+#
+Anwendung beenden
+#
+# 3: Menu "Help"
+#
+Hilfe
+#
+# 4: Menu item "Help/About"
+#
+Ãœber
+#
+# 5: Tooltip text for menu item "Help/About"
+#
+Versions-Informationen anzeigen
+#
+# 6: Menu item "Help/Contents"
+#
+Inhalt
+#
+# 7: Tooltip text for menu item "Help/Contents"
+#
+Inhaltsverzeichnis der Online-Hilfe öffnen
+#
+# 8: Check box in options dialog
+#
+Wecken
+#
+# 9: Copyright notice.
+#
+Copyright (c)
+#
+# 10: Dialog box title "About ..."
+#
+Ãœber
+#
+# 11: This program uses the following libraries
+#
+Dieses Programm benutzt die folgenden Bibliotheken:
+#
+# 12: See
+#
+Siehe:
+#
+# 13: __CHANGE__ 015: Text for dummy label, can be reused if lDummy removed.
+#
+Optionen
+#
+# 14 15: Menu item: Options
+#
+Wecken
+Wecken ein- und ausschalten, Weckzeit einstellen
+#
+# 16: Dialog box title
+#
+Optionen
+#
+# 17 18: OK button
+#
+OK
+Einstellungen anwenden und Dialogbox schließen
+#
+# 19 20: Cancel button
+#
+Abbrechen
+Dialogbox schließen und Einstellungen verwerfen
+#
+# 21: Minute
+#
+Minute:
+#
+# 22: Hour
+#
+Stunde:
+#
+# 23: Tool tip "Enable or disable alert"
+#
+Wecken ein- und ausschalten
+#
+# 24 25: Tool tips Choose alert time.
+#
+Weckzeit (Stunde) auswählen
+Weckzeit (Minute) auswählen
+#
+# 26 27
+#
+Fenster wiederherstellen
+Anwendung beenden
+#
+# 28 29
+#
+Task-Leiste
+Hauptfenster hinter Task-Leisten-Icon verstecken
+#
+# 30 Menu: Colour
+#
+Farbe
+#
+# 31 32 Menu item: Normal state
+#
+Normal
+Uhr-Farbe im Normalzustand
+#
+# 33 34 Menu item: Alert state
+#
+Alarm
+Uhr-Farbe bei Weckruf
diff --git a/support/dktools/dktools/de/wxdkct.str b/support/dktools/dktools/de/wxdkct.str
new file mode 100644
index 0000000000..d6a5c07478
--- /dev/null
+++ b/support/dktools/dktools/de/wxdkct.str
@@ -0,0 +1,333 @@
+#
+# 0: Program name
+#
+wxdkct
+#
+# 1: Application group name
+#
+dkt-3
+#
+# 2: Software vendor name
+#
+Dirk Krause
+#
+# 3: Menu: File
+#
+&Datei
+#
+# 4: Menu: Help
+#
+&Hilfe
+#
+# 5: Menu: File / Exit
+#
+&Beenden Alt-X
+#
+# 6: Menu: Help / About
+#
+&Ãœber... Alt-A
+#
+# 7: Tip text for menu entry File / Exit
+#
+Anwendung beenden
+#
+# 8: Tip text for menu entry Help / About
+#
+Versionsinformation anzeigen
+#
+# 9: Menu Help / Contents
+#
+&Inhalt F1
+#
+# 10: Menu tool tip Help / Contents
+#
+Inhaltsverzeichnis der Online-Hilfe
+#
+# 11: Label text: Directory
+#
+Verzeichnis:
+#
+# 12: Menu text: Choose Directory
+#
+&Verzeichnis Alt-V
+#
+# 13: Menu tool tip: Choose source directory
+#
+Quelltext-Verzeichnis wählen...
+#
+# 14: Menu text: Setup
+#
+&Einstellungen Alt-E
+#
+# 15: Menu tool tip: Set conversion options
+#
+Einstellungen vornehmen
+#
+# 16 Label text: yes, to stdout
+#
+ja, auf Standardausgabe
+#
+# 17: Toolbar button text: Directory
+#
+Verzeichnis
+#
+# 18: Toolbar button text: Options
+#
+Einstellungen
+#
+# 19: Toolbar button text: Run
+#
+Start
+#
+# 20: Toolbar button text: Exit
+#
+Beenden
+#
+# 21: Toolbar button tooltip: Choose directory
+#
+Quelltext-Verzeichnis auswählen
+#
+# 22: Toolbar button tooltip: Set options.
+#
+Einstellungen vornehmen
+#
+# 23: Toolbar button tooltip: Run conversion
+#
+Konvertierung starten
+#
+# 24: Toolbar button tooltip: Exit the application
+#
+Anwendung beenden
+#
+# 25: Current directory.
+#
+.
+#
+# 26: Button text: OK
+#
+OK
+#
+# 27: Button text: Cancel
+#
+Abbrechen
+#
+# 28: Button tool tip for OK button.
+#
+Dialog schließen, Einstellungen anwenden
+#
+# 29: Button tool tip for cancel button.
+#
+Dialog schließen, Einstellungen verwerfen
+#
+# 30: Dialog title: Options
+#
+Einstellungen
+#
+# 31: Checkbox label: Use make mode
+#
+"make"-Modus
+#
+# 32: Checkbox tool tip: Run conversions only if necessary.
+#
+Nur konvertieren, falls nötig
+#
+# 33: Static box title: General options
+#
+Allgemeine Einstellungen
+#
+# 34: Static box title: Output
+#
+Ausgabe
+#
+# 35: Checkbox label: Line numbers
+#
+Zeilennummern
+#
+# 36: Static box title: Debug
+#
+Debugging
+#
+# 37: Checkbox label: Create debug output
+#
+Debug-Ausgaben erzeugen
+#
+# 38: Checkbox label: Debug to standard output
+#
+Debug-Ausgaben in die Standardausgabe
+#
+# 39: Checkbox label: Include timestamp
+#
+Debug-Ausgaben mit Zeitstempel
+#
+# 40: Checkbox label: Use trace keyword
+#
+Debug-Ausgaben mit Text "trace" beginnen
+#
+# 41: Checkbox label: Wide character support
+#
+Debug-Ausgaben mit Support für Windows-16-Bit-Text
+#
+# 42: Checkbox tool tip: Create line number directives
+#
+Zeilennummern-Direktiven für C-Compiler
+#
+# 43: Checkbox tool tip: Generate code for debug messages
+#
+Code mit Trace/Debug-Ausgaben erzeugen
+#
+# 44: Checkbox tool tip: Write trace/debug messages to standard output
+#
+Trace/Debug-Ausgaben in die Standardausgabe schreiben
+#
+# 45: Checkbox tool tip: Include a timestamp into debug messages
+#
+Trace/Debug-Ausgaben mit Uhrzeit versehen
+#
+# 46: Checkbox tool tip: Include "trace" keyword into debug messages
+#
+Trace/Debug-Ausgaben mit Schlüsselwort "trace" versehen
+#
+# 47: Checkbox tool tip: Add support for TRACE_WIDE
+#
+Trace/Debug-Ausgaben mit Support für 16-Bit-Text für Windows
+#
+# 48: Dialog title: Conversion progress
+#
+Fortschritt
+#
+# 49: File name (empty string)
+#
+
+#
+# 50: Button text: Cancel
+#
+Abbrechen
+#
+# 51: Button tool tip: Abort conversion after finishing current file
+#
+Abbruch nach Verarbeitung der gerade bearbeiteten Datei
+#
+# 52: Notification text: Cancel command scheduled... Wait, please!
+#
+Abbruch eingeleitet... Bitte warten!
+#
+# 53: Directory dialog title: Choose directory
+#
+Verzeichnis wählen
+#
+# 54: Message text: Directory:
+#
+Verzeichnis:
+#
+# 55: Message text: Destination files up to date.
+#
+Alle Zieldateien sind aktuell.
+#
+# 56: Message text: Processing succeeded.
+#
+Verarbeitung erfolgreich.
+#
+# 57: Message text:Processing failed!
+#
+Verarbeitung fehlgeschlagen!
+#
+# 58: Error: Can not handle directory name!
+#
+FEHLER: Der Verzeichnisname kann nicht verwendet werden!
+#
+# 59/60: Error: Failed to open directory "..."!
+#
+FEHLER: Verzeichnis "
+" kann nicht geöffnet werden!
+#
+# 61/62: Error: File name is not plain ASCII text: "..."!
+#
+FEHLER: Nicht-ASCII-Zeichen in Dateinamen: "
+"!
+#
+# 63: Error: Not enough memory!
+#
+FEHLER: Zu wenig Speicher!
+#
+# 64: Menu item: Run
+#
+&Start Alt-S
+#
+# 65: Menut tool tip: Start conversion
+#
+Konvertierung starten
+#
+# 66: About dialog title.
+#
+Ãœber wxdkct
+#
+# 67: Empty text (initial status text).
+#
+
+#
+# 68: Run result: Processing succeeded
+#
+Verarbeitung erfolgreich
+#
+# 69: Run result: Warnings occured
+#
+Warnungen
+#
+# 70: Run result: Errors occured
+#
+Fehler
+#
+# 71: ERROR: Automatic run cancelled due to errors.
+#
+Automatischer Start wegen Fehlern nicht möglich!
+#
+# 72: Autorun result: Processing succeeded, application will exit.
+#
+Verarbeitung erfolgreich, Anwendung wird beendet.
+#
+# 73: Newline
+#
+\n
+#
+# 74: This program uses libraries from the following projects:
+#
+Dieses Programm verwendet Bibliotheken aus folgenden Projekten:\n
+#
+# 75: See:
+#
+Siehe:\n
+#
+# 76-93: Special character candidates for splint.
+#
+@
+^
+°
+!
+"
+§
+$
+%
+&
+?
+~
+\#
+|
+,
+;
+.
+:
+_
+#
+# 94-95: Comments for splint
+#
+Kommentare für splint
+Schreibe Kommentare für splint
+#
+# 96: Choose comment character for splint
+#
+Kommentar-Zeichen für splint auswählen
+#
+# 97 98 Check box: Portable debug code and tool tip
+#
+Portabler Trace-Code
+Code für Trace-Ausgabe portabel gestalten
diff --git a/support/dktools/dktools/de/wxdkfcs.str b/support/dktools/dktools/de/wxdkfcs.str
new file mode 100644
index 0000000000..422c8176be
--- /dev/null
+++ b/support/dktools/dktools/de/wxdkfcs.str
@@ -0,0 +1,79 @@
+#
+# 0: Menu "File"
+#
+Datei
+#
+# 1: Menu item "File/Exit"
+#
+Beenden
+#
+# 2: Tool tip text for menu item "File/Exit"
+#
+Anwendung beenden
+#
+# 3: Menu "Help"
+#
+Hilfe
+#
+# 4: Menu item "Help/About"
+#
+Ãœber wxdkfcs
+#
+# 5: Tooltip text for menu item "Help/About"
+#
+Versions-Information anzeigen
+#
+# 6: Menu item "Help/Contents"
+#
+Inhalt
+#
+# 7: Tooltip text for menu item "Help/Contents"
+#
+Inhaltsverzeichnis der Online-Hilfe
+#
+# 8: Initial status text
+#
+Bereit
+#
+# 9: Copyright notice.
+#
+Copyright (c)
+#
+# 10: Dialog box title "About ..."
+#
+Ãœber wxdkfcs
+#
+# 11: This program uses the following libraries
+#
+Dieses Programm benutzt die folgenden Bibliotheken:
+#
+# 12: See
+#
+Siehe:
+#
+# 13: __CHANGE__ 015: Text for dummy label, can be reused if lDummy removed.
+#
+Datei:
+#
+# 14 ... 20: Label MD5
+#
+MD5
+RIPEMD-160
+SHA-1
+SHA-224
+SHA-256
+SHA-384
+SHA-512
+#
+# 21: Column head
+#
+Prüfsumme
+#
+# 22: wxFileDialog header line
+#
+Datei auswählen
+#
+# 23 24: Menu item File/Open
+#
+Öffnen
+Datei auswählen und öffnen
diff --git a/support/dktools/dktools/de/wxdkhtb.str b/support/dktools/dktools/de/wxdkhtb.str
new file mode 100644
index 0000000000..ea5114c2b7
--- /dev/null
+++ b/support/dktools/dktools/de/wxdkhtb.str
@@ -0,0 +1,76 @@
+#
+# 0: Menu "File"
+#
+Datei
+#
+# 1: Menu item "File/Exit"
+#
+Beenden
+#
+# 2: Tool tip text for menu item "File/Exit"
+#
+Anwendung beenden
+#
+# 3: Menu "Help"
+#
+?
+#
+# 4: Menu item "Help/About"
+#
+Ãœber
+#
+# 5: Tooltip text for menu item "Help/About"
+#
+Versionsnummer anzeigen
+#
+# 6: Menu item "Help/Contents"
+#
+Inhalt
+#
+# 7: Tooltip text for menu item "Help/Contents"
+#
+Inhaltsverzeichnis der *.htb-Datei öffnen
+#
+# 8: Initial status text
+#
+Bereit
+#
+# 9: Copyright notice.
+#
+Copyright (c)
+#
+# 10: Dialog box title "About ..."
+#
+Information
+#
+# 11: This program uses the following libraries
+#
+Dieses Programm benutzt die folgenden Bibliotheken:
+#
+# 12: See
+#
+Siehe auch:
+#
+# 13: Text for dummy label, can be reused if lDummy removed.
+#
+Hauptfenster des HTB-Viewers
+#
+# 14: No help controller created
+#
+Kein Hilfe-Controller wurde erstellt!
+#
+# 15: Error
+#
+Fehler
+#
+# 16
+#
+Auf der Kommandozeile wurde kein *.htb-Dateiname angegeben!
+#
+# 17
+#
+Die angegebene *.htb-Datei existiert nicht!
+#
+# 18
+#
+Hilfe-Controller konnte nicht angelegt werden, Speicher/Resourcen-Problem!
diff --git a/support/dktools/dktools/de/wxdkscrsz.str b/support/dktools/dktools/de/wxdkscrsz.str
new file mode 100644
index 0000000000..bcb5c74d29
--- /dev/null
+++ b/support/dktools/dktools/de/wxdkscrsz.str
@@ -0,0 +1,120 @@
+#
+# 0: Menu "File"
+#
+Datei
+#
+# 1: Menu item "File/Quit"
+#
+Beenden
+#
+# 2: Tool tip text for menu item "File/Exit"
+#
+Anwendung beenden
+#
+# 3: Menu "Help"
+#
+Hilfe
+#
+# 4: Menu item "Help/About"
+#
+Ãœber
+#
+# 5: Tooltip text for menu item "Help/About"
+#
+Version anzeigen
+#
+# 6: Menu item "Help/Contents"
+#
+Inhalt
+#
+# 7: Tooltip text for menu item "Help/Contents"
+#
+Inhaltsverzeichnis öffnen
+#
+# 8: Initial status text
+#
+Bereit
+#
+# 9: Copyright notice.
+#
+Copyright (c)
+#
+# 10: Dialog box title "About ..."
+#
+Ãœber
+#
+# 11: This program uses the following libraries
+#
+Dieses Programm benutzt folgende Bibliotheken:
+#
+# 12: See
+#
+Siehe:
+#
+# 13: __CHANGE__ 015: Text for dummy label, can be reused if lDummy removed.
+#
+Änderungsvorgang:
+#
+# __CHANGE__ 016: Add further texts as required.
+#
+# 14
+#
+Noch nicht gestartet
+#
+# 15
+#
+Gestartet
+#
+# 16
+#
+Erfolgreich
+#
+# 17
+#
+Fehlgeschlagen
+#
+# 18
+#
+Fehler
+#
+# 19
+#
+Die aktuellen Bildschirm-Einstellungen konnten nicht ermittelt werden!
+#
+# 20
+#
+Die Bildschirmgröße konnte nicht geändert werden!
+#
+# 21
+#
+Dieses Programm ist nur für Windows verfügbar!
+#
+# 22 23
+#
+Keine vorzeichenlose ganze Zahl: "
+"!
+#
+# 24
+#
+Kommandozeilenargumente erforderlich: Breit, Höhe
+#
+# 25
+#
+Alte Bildschirmgröße
+#
+# 26 27
+#
+Breite:
+Höhe:
+#
+# 28 Empty string
+#
+
+#
+# 29 New screen size
+#
+Neue Bildschirmgröße
+#
+# 30 Result
+#
+Ergebnis
diff --git a/support/dktools/dktools/de/wximgsz.str b/support/dktools/dktools/de/wximgsz.str
new file mode 100644
index 0000000000..94bcaa16e2
--- /dev/null
+++ b/support/dktools/dktools/de/wximgsz.str
@@ -0,0 +1,225 @@
+#
+# 0 Program name.
+#
+wximgsz
+#
+# 1 Menu name: File
+#
+Datei
+#
+# 2 Menu item: File => Exit
+#
+Beenden Alt-B
+#
+# 3 Data grid column head: Width
+#
+Breite
+#
+# 4 Data grid column head: Height
+#
+Höhe
+#
+# 5 Data grid column head: Factor
+#
+Faktor
+#
+# 6 Label text: Original image
+#
+Original-Bild
+#
+# 7 Label text: Results
+#
+Ergebnis
+#
+# 8 Label text: Width:
+#
+Breite:
+#
+# 9 Label text: Height:
+#
+Höhe:
+#
+# 10 Label text: Intended change
+#
+Gewünschte Änderung
+#
+# 11 Label text: Action:
+#
+Bearbeitung:
+#
+# 12 Choice: Decrease image
+#
+Bild verkleinern
+#
+# 13 Choice: Width range
+#
+Breitenbereich
+#
+# 14 Choice: Height range
+#
+Höhenbereich
+#
+# 15 Label: Minimum:
+#
+Minimum:
+#
+# 16 Label: Maximum:
+#
+Maximum:
+#
+# 17 Button label: Run
+#
+>>>
+#
+# 18 Empty text for initial status
+#
+
+#
+# 19 Tooltip: Exit the application
+#
+Anwendung beenden
+#
+# 20 Tooltip: Specify original image width
+#
+Original-Bildbreite eingeben (positiv ganzzahlig).
+#
+# 21 Tooltip: Specify original image height
+#
+Original-Bildhöhe eingeben (positiv ganzzahlig).
+#
+# 22 Tooltip: Choose type of modification
+#
+Gewünschte Bearbeitung auswählen.
+#
+# 23 Tooltip: Specify intended minimum for image width or height
+#
+Gewünschtes Minimum für Bildbreite bzw. -höhe eingeben.
+#
+# 24 Tooltip: Specify intended maximum for image width or height
+#
+Gewünschtes Maximum für Bildbreite bzw. -höhe eingeben.
+#
+# 25 Tooltip: Calculate new image sizes
+#
+Berechnung starten.
+#
+# 26 Spaces to initialize text fields
+#
+
+#
+# 27 Menu: Help
+#
+Hilfe
+#
+# 28 Menu item: Contents
+#
+Inhaltsverzeichnis
+#
+# 29 Menu item: About
+#
+Ãœber...
+#
+# 30 Menu tip: Open table of contents
+#
+Inhaltsverzeichnis der Online-Hilfe öffnen.
+#
+# 31 Menu tip: Show version number dialog box
+#
+Versionsnummer anzeigen.
+#
+# 32 Error message title: Incorrect input
+#
+Fehlerhafte Eingabe
+#
+# 33 Error message text: Please enter a postivie integer number.
+#
+Bitte geben Sie einen positiven ganzzahligen Wert ein!
+#
+# 34 Status message: No results found!
+#
+Keine Ergebnisse erzielt!
+#
+# 35 About box title.
+#
+Ãœber wximgsz
+#
+# 36 Indicator for best quality
+#
+++
+#
+# 37 Indicator for good quality
+#
++
+#
+# 38 Menu: Extras
+#
+Extras
+#
+# 39 Menu item: Options
+#
+Optionen
+#
+# 40 Tip: Set options
+#
+Einstellungen für das Programm ändern
+#
+# 41 Dialog box title: Options
+#
+Einstellungen
+#
+# 42 Checkbox text: Choose background color by scale factor quality
+#
+Hintergrundfarbe für Skalierungsfaktor
+#
+# 43 Tooltip text: Indicate scale factor quality by background colour.
+#
+Hintergrundfarbe entsprechend Qualität des Skalierungsfaktors verwenden.
+#
+# 44 Button: OK
+#
+OK
+#
+# 45 Button: Cancel
+#
+Abbrechen
+#
+# 46 Tool tip text: Apply settings and exit dialog.
+#
+Einstellungen anwenden und Dialog verlassen.
+#
+# 47 Tool tip text: Skip settings and exit dialog.
+#
+Einstellungen verwerfen und Dialog verlassen.
+#
+# 48
+#
+Bitmap-Datei auswählen
+#
+# 49
+#
+Öffnen Alt-O
+#
+# 50
+#
+Bildabmessungen aus Bilddatei verwenden.
+#
+# 51
+#
+Die Datei konnte nicht geladen werden!\nMöglicherweise ist die Datei beschädigt oder der Bildtyp wird von wximgsz nicht unterstützt.
+#
+# 52
+#
+Bilddatei nicht geladen!
+#
+# 53
+#
+\n
+#
+# 54
+#
+Dieses Programm benutzt Bibliotheken aus folgenden Projekten:\n
+#
+# 55
+#
+Siehe:\n
+
diff --git a/support/dktools/dktools/de/wxpqdc.str b/support/dktools/dktools/de/wxpqdc.str
new file mode 100644
index 0000000000..aefac35d3b
--- /dev/null
+++ b/support/dktools/dktools/de/wxpqdc.str
@@ -0,0 +1,189 @@
+#
+# 0: Menu "File"
+#
+Datei
+#
+# 1: Menu item "File/Quit"
+#
+Beenden
+#
+# 2: Tool tip text for menu item "File/Exit"
+#
+Die Anwendung beenden
+#
+# 3: Menu "Help"
+#
+Hilfe
+#
+# 4: Menu item "Help/About"
+#
+Ãœber
+#
+# 5: Tooltip text for menu item "Help/About"
+#
+Versionshinweise anzeigen
+#
+# 6: Menu item "Help/Contents"
+#
+Inhalt
+#
+# 7: Tooltip text for menu item "Help/Contents"
+#
+Inhaltsverzeichnis der Hilfe öffnen
+#
+# 8: Initial status text
+#
+Bereit
+#
+# 9: Copyright notice.
+#
+Copyright (c)
+#
+# 10: Dialog box title "About ..."
+#
+Ãœber
+#
+# 11: This program uses the following libraries
+#
+Dieses Programm benutzt die nachfolgenden Bibliotheken:
+#
+# 12: See
+#
+Siehe:
+#
+# 13: Label text "Limit:"
+#
+Limit:
+#
+# 14: Limit value "unlimited"
+#
+unbegrenzt
+#
+# 15: Label text "Used:"
+#
+Verbraucht:
+#
+# 16: Dummy label text to initialize number of used pages
+#
+00000000
+#
+# 17: Label text "Personal print account:"
+#
+Pers. Seiten-Guthaben:
+#
+# 18: Label text "Printing allowed:"
+#
+Drucken möglich:
+#
+# 19 20: Result text values
+#
+JA
+NEIN
+#
+# 21: Label text "Waiting for response from server."
+#
+Antwort vom Server wird erwartet.
+#
+# 22: Menu "View"
+#
+Anzeige
+#
+# 23: Menu item: View -> Update
+#
+Aktualisieren
+#
+# 24: Tool tip text for menu item: View -> Update
+#
+Informationen im Fenster aktualisieren
+#
+# 25: Toolbar button text "Update"
+#
+Aktualisieren
+#
+# 26: Toolbar button text "Exit"
+#
+Beenden
+#
+# 27: Information: unknown
+#
+unbekannt
+#
+# 28: Error: Failed to send request
+#
+Anfrage konnte nicht gesendet werden!
+#
+# 29: Error: No response from server!
+#
+Keine Antwort vom Server!
+#
+# 30 31
+#
+Kommandozeile
+Die angegebene Kommandozeile konnte nicht verarbeitet werden!
+#
+# 32 33
+#
+Speicher
+Nicht ausreichend Hauptspeicher vorhanden!
+#
+# 34 35
+#
+Unzulässiger Host-Name
+Der Host-Name konnte nicht verarbeitet werden!
+#
+# 36 37
+#
+Host-Name fehlt
+Bitte benutzen Sie\n-h host\num den Host-Namen anzugeben!
+#
+# 38 39
+#
+Unzulässiger Queue-Name
+Der Queue-Name konnte nicht verarbeitet werden!
+#
+# 40 41
+#
+Queue-Name fehlt
+Bitte benutzen Sie\n-q queue\num den Queue-Namen anzugeben!
+#
+# 42 43 44
+#
+Unzulässiger Remote-Port
+Die Portnummer ist zu groß (keine 16-Bit-Zahl)!
+Portnummer 0 kann nicht benutzt werden!
+#
+# 45 46
+#
+Unzulässiger Nutzer-Name
+Der Nutzer-Name konnte nicht verarbeitet werden!
+#
+# 47 48
+#
+Nutzer-Name fehlt
+Bitte benutzen Sie\n-u user\num den Nutzer-Namen anzugeben!
+#
+# 49 50 51
+#
+Unzulässiger lokaler Port
+Die Portnummer ist zu groß (keine 16-Bit-Zahl)!
+Portnummer 0 kann nicht benutzt werden!
+#
+# 52 53
+#
+Bug
+Der Request-String konnte nicht konstruiert werden!
+#
+# 54 55
+#
+Zahlenbereichs-Ãœberlauf
+Eine Größenberechnung schlug wegen Zahlenbereichs-Überlauf fehl!
+#
+# 56 57
+#
+Netzwerk-Fehler
+Die Socket zur Kommunikation mit dem Server konnte nicht erstellt werden!
+#
+# 58 59
+#
+Fehler
+Ein nicht näher bekannter Fehler trat auf!
diff --git a/support/dktools/dktools/de/x.txt b/support/dktools/dktools/de/x.txt
new file mode 100644
index 0000000000..b9c96c6538
--- /dev/null
+++ b/support/dktools/dktools/de/x.txt
@@ -0,0 +1,46 @@
+
+BEZEICHNUNG
+
+ÃœBERSICHT
+
+BESCHREIBUNG
+
+OPTIONEN
+
+EXIT-STATUS
+
+0 bei Erfolg, alle anderen Exit-Codes weisen auf Fehler hin.
+
+FEHLER
+
+DIAGNOSE-MELDUNGEN
+
+BEISPIELE
+
+ENVIRONMENT
+
+DATEIEN
+
+WARNUNGEN
+
+BUGS / FEHLER
+
+EINSCHRÄNKUNGEN
+
+HINWEISE
+
+AUTOR
+
+Dirk Krause
+
+GESCHICHTE
+
+COPYRIGHT UND LIZENZBESTIMMUNGEN
+
+Führen Sie
+ XXXXX --license
+aus, um Lizenz-Informationen anzuzeigen.
+
+SIEHE AUCH
+
+http://dktools.sourceforge.net
diff --git a/support/dktools/dktools/dkwxwiza.txt b/support/dktools/dktools/dkwxwiza.txt
new file mode 100644
index 0000000000..76837b34d1
--- /dev/null
+++ b/support/dktools/dktools/dkwxwiza.txt
@@ -0,0 +1,419 @@
+%% options
+
+# __CHANGE__ 001: Correct copyright owner if necessary.
+copyright owner = $copyrightowner$
+
+# __CHANGE__ 003: Correct copyright year(s) if necessary.
+copyright year = $year$
+
+# __CHANGE__ 002: Correct license type if necessary.
+# Use "bsd", "gpl", "lgpl", or "commercial".
+license = bsd
+
+
+
+%% header
+
+/** @file $application$.h The $application$ class.
+*/
+
+
+
+/** Application class, derived from wxApp, one instance per program.
+*/
+class $application$ : public wxApp
+{
+ protected:
+
+ /** Helper object.
+ */
+ Dk4WxApplicationHelper *pAh;
+
+ /** Controller fr online help.
+ */
+ Dk4WxHelpController *pHc;
+
+ /* __CHANGE__ 009: Add further members here.
+ */
+
+ protected:
+
+ /** Show error message if there is not enough memory available.
+ */
+ void
+ ShowMemoryErrorMessage(void);
+
+ public:
+
+ /** Application initialization.
+ @return true on success, false on error.
+ */
+ virtual
+ bool
+ OnInit();
+
+ /** Application shutdown.
+ @return 0 on success, any other value indicates an error.
+ */
+ virtual
+ int
+ OnExit();
+};
+
+
+
+/** Declaration as the wxApp object.
+*/
+DECLARE_APP($application$)
+
+
+
+/* vim: set ai sw=4 ts=4 : */
+%% module
+
+#include "$program$.h"
+
+
+
+$!trace-include
+
+
+
+/** Localized wxChar texts.
+*/
+static wxChar const * $program$_texts[] = {
+$!string-table macro=wxT
+#
+# 0: Menu "File"
+#
+File
+#
+# 1: Menu item "File/Quit"
+#
+Quit
+#
+# 2: Tool tip text for menu item "File/Exit"
+#
+Exit the application
+#
+# 3: Menu "Help"
+#
+Help
+#
+# 4: Menu item "Help/About"
+#
+About
+#
+# 5: Tooltip text for menu item "Help/About"
+#
+Show version information
+#
+# 6: Menu item "Help/Contents"
+#
+Contents
+#
+# 7: Tooltip text for menu item "Help/Contents"
+#
+Open table of contents
+#
+# 8: Initial status text
+#
+Ready
+#
+# 9: Copyright notice.
+#
+Copyright (c)
+#
+# 10: Dialog box title "About ..."
+#
+About
+#
+# 11: This program uses the following libraries
+#
+This program uses the following libraries:
+#
+# 12: See
+#
+See:
+#
+# 13: __CHANGE__ 015: Text for dummy label, can be reused if lDummy removed.
+#
+Dummy text to have at least one label in the frame
+#
+# __CHANGE__ 016: Add further texts as required.
+#
+$!end
+};
+
+
+
+/** Non-localized wxChar texts.
+*/
+static wxChar const * $program$_nl_wx[] = {
+$!string-table macro=wxT
+#
+# 0: Program name. __CHANGE__ 004: Correct program name.
+#
+$program$
+#
+# 1: Program version. __CHANGE__ 005: Correct program version.
+#
+1.0.0
+#
+# 2: Copyright owner name. __CHANGE__ 001: Correct copyright owner name.
+#
+Copyright owner
+#
+# 3: Software vendor name. __CHANGE__ 007: Correct software vendor name
+# if necessary. Must be one
+# string without spaces.
+#
+SoftwareVendor
+#
+# 4: Resource name of Windows icon
+#
+aaaaa
+#
+# 5: UNUSED (previously Windows chm help file name)
+#
+
+#
+# 6: UNUSED (previously non-Windows htb help file name)
+#
+
+#
+# 7: Space
+#
+
+#
+# 8: Newline
+#
+\n
+#
+# 9 10 11 12 13 14 15: List of libraries used.
+#
+DK tools, wxWidgets, libpng, libjpeg, libtiff, zlib.
+http://dktools.sourceforge.net
+http://www.wxwidgets.org
+http://www.libpng.org/pub/png/libpng.html
+http://www.ijg.org
+http://www.remotesensing.org/libtiff
+http://www.zlib.net
+#
+# 16 17
+#
+Error
+Not enough memory (RAM)!
+$!end
+};
+
+
+
+/** Non-localized dkChar texts.
+*/
+static dkChar const * $program$_nl_dk[] = {
+$!string-table macro=dkT
+#
+# 0: Program group name. __CHANGE__ 006: Correct program group name.
+#
+$program$-group
+#
+# 1: String table name.
+#
+$program$.str
+#
+# 2: CHM help file name
+#
+$program$.chm
+#
+# 3: HTB help file name
+#
+$program$.htb
+$!end
+};
+
+
+
+/** Implementation of the wxApp functionality.
+*/
+IMPLEMENT_APP($application$)
+
+
+bool
+$application$::OnInit()
+{
+ $frame$ *frame = NULL;
+ wxChar const * const *localizedTexts = NULL;
+ wxPNGHandler *phPng = NULL;
+ wxXPMHandler *phXpm = NULL;
+ wxICOHandler *phIco = NULL;
+ wxArchiveFSHandler *phArchiveFS = NULL;
+ bool back = false;
+
+ $? "+ $application$::OnInit"
+
+ /* Initialize members.
+ */
+ pAh = NULL;
+ pHc = NULL;
+
+ /* __CHANGE__ 009: Initialize further members here.
+ */
+
+ /* Set up helper object.
+ */
+ pAh = new Dk4WxApplicationHelper();
+ if (NULL == pAh) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ if (!(pAh->Initialize(argv[0], $program$_nl_wx[3], $program$_nl_dk[0]))) {
+ goto finished;
+ }
+
+ /* Add image and file system handlers for online help.
+ */
+ phPng = new wxPNGHandler();
+ if (NULL != phPng) {
+ wxImage::AddHandler(phPng);
+ }
+ else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ phXpm = new wxXPMHandler();
+ if (NULL != phXpm) {
+ wxImage::AddHandler(phXpm);
+ }
+ else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ phIco = new wxICOHandler();
+ if (NULL != phIco) {
+ wxImage::AddHandler(phIco);
+ }
+ else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ phArchiveFS = new wxArchiveFSHandler();
+ if (NULL != phArchiveFS) {
+ wxFileSystem::AddHandler(phArchiveFS);
+ }
+ else {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ /* Set up help controller.
+ */
+ pHc = new Dk4WxHelpController();
+ if (NULL == pHc) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+ if (!(pHc->Initialize(pAh, $program$_nl_dk[2], $program$_nl_dk[3]))) {
+ goto finished;
+ }
+
+ /* Attempt to obtain localized texts in users preferred language.
+ */
+ localizedTexts = pAh->GetStringTable($program$_nl_dk[1], $program$_texts);
+ if(!(localizedTexts)) {
+ localizedTexts = $program$_texts;
+ }
+
+ /* Create and show frame.
+ */
+ frame = new $frame$(
+ $frame$_MainWindow,
+ pAh,
+ pHc,
+ argc,
+ argv,
+ localizedTexts,
+ $program$_nl_wx,
+ $program$_nl_dk
+ );
+ if(!(frame)) {
+ ShowMemoryErrorMessage();
+ goto finished;
+ }
+
+ /* Show frame, restore position and indicate success.
+ */
+ frame->Show();
+ frame->RestorePosition();
+ back = true;
+
+ /* Release resources if initialization failed.
+ */
+ finished:
+ if(!(back)) {
+ if (NULL != pHc) {
+ pHc->Cleanup(); delete(pHc); pHc = NULL;
+ }
+ if (NULL != pAh) {
+ pAh->Cleanup(); delete(pAh); pAh = NULL;
+ }
+ }
+ $? "- $application$::OnInit %d", (back ? 1 : 0)
+ return back;
+}
+
+
+
+int
+$application$::OnExit()
+{
+ int back = 0;
+
+ $? "+ $application$::OnExit"
+
+ /* __CHANGE__ 009: Release resources allocated by further members.
+ */
+
+ /* Release resources.
+ */
+ if (NULL != pHc) {
+ pHc->Cleanup(); delete(pHc); pHc = NULL;
+ }
+ if (NULL != pAh) {
+ pAh->Cleanup(); delete(pAh); pAh = NULL;
+ }
+
+ /* __CHANGE__ 010: Set exit status code.
+ */
+ $? "- $application$::OnExit %d", back
+ return back;
+}
+
+
+
+void
+$application$::ShowMemoryErrorMessage(void)
+{
+ const wxChar *s_title = NULL;
+ const wxChar *s_text = NULL;
+
+ if (NULL != pAh) {
+ s_title = pAh->GetBasicString(6);
+ s_text = pAh->GetBasicString(7);
+ }
+ if (NULL == s_title) {
+ s_title = $program$_nl_wx[16];
+ }
+ if (NULL == s_text) {
+ s_text = $program$_nl_wx[17];
+ }
+ wxMessageBox(s_text, s_title, (wxOK | wxCENTRE | wxICON_ERROR));
+}
+
+
+
+/* vim: set ai sw=4 ts=4 : */
+
diff --git a/support/dktools/dktools/dkwxwizc.txt b/support/dktools/dktools/dkwxwizc.txt
new file mode 100644
index 0000000000..847a11a55e
--- /dev/null
+++ b/support/dktools/dktools/dkwxwizc.txt
@@ -0,0 +1,45 @@
+dnl configure-script
+AC_INIT($frame$.h)
+dnl AC_CONFIG_HEADER(config.h)
+AC_PROG_CC
+AC_PROG_CPP
+AC_C_BIGENDIAN
+
+WXCPPFLAGS=''
+WXCXXFLAGS=''
+WXCFLAGS=''
+WXLDFLAGS=''
+WXCPPFLAGS=`wx-config --cppflags`
+WXCXXFLAGS=`wx-config --cxxflags`
+WXCFLAGS=`wx-config --cflags`
+WXLDFLAGS=`wx-config --libs`
+
+if [[ -f dk4info.out ]]
+then
+ rm -fr dk4info.out
+fi
+dk4info -l > dk4info.out
+
+ZLIBFLAG=`cat dk4info.out | grep DK4_HAVE_ZLIB_H | sed -e 's/[[ \t]][[ \t]]*//g' | cut -f 2 -d '='`
+BZLIBFLAG=`cat dk4info.out | grep DK4_HAVE_BZLIB_H | sed -e 's/[[ \t]][[ \t]]*//g' | cut -f 2 -d '='`
+
+ZLIB=''
+if [[ "X$ZLIBFLAG" = "X1" ]]
+then
+ ZLIB='-lz'
+fi
+BZLIB=''
+if [[ "X$BZLIBFLAG" = "X1" ]]
+then
+ BZLIB='-lbz2'
+fi
+
+AC_SUBST(WXCPPFLAGS)
+AC_SUBST(WXCXXFLAGS)
+AC_SUBST(WXLDFLAGS)
+AC_SUBST(WXCFLAGS)
+AC_SUBST(BZLIB)
+AC_SUBST(ZLIB)
+
+AC_OUTPUT(Makefile)
+
diff --git a/support/dktools/dktools/dkwxwizf.txt b/support/dktools/dktools/dkwxwizf.txt
new file mode 100644
index 0000000000..b91f94add4
--- /dev/null
+++ b/support/dktools/dktools/dkwxwizf.txt
@@ -0,0 +1,371 @@
+%% options
+
+# __CHANGE__ 001: Correct copyright owner if necessary.
+copyright owner = $copyrightowner$
+
+# __CHANGE__ 003: Correct copyright year(s) if necessary.
+copyright year = $year$
+
+# __CHANGE__ 002: Correct license type if necessary.
+# Use "bsd", "gpl", "lgpl", or "commercial".
+license = bsd
+
+
+
+%% wx-gui
+
+type = frame
+contents = mainSizer
+icon = $program$_icon
+status bar = 1 sTexts[8]
+menu bar = mbMain
+
+[wxMenuBar mbMain]
+contents = menuFile
+contents = menuHelp
+
+[wxMenu menuFile]
+text = sTexts[0]
+contents = miFileExit
+
+[wxMenuItem miFileExit]
+id = $frame$_Quit
+text = sTexts[1]
+tip = sTexts[2]
+
+[wxMenu menuHelp]
+text = sTexts[3]
+contents = miHelpAbout
+contents = miHelpContents
+
+[wxMenuItem miHelpAbout]
+id = $frame$_Help_About
+text = sTexts[4]
+tip = sTexts[5]
+
+[wxMenuItem miHelpContents]
+id = $frame$_Help_Contents
+text = sTexts[6]
+tip = sTexts[7]
+
+[wxBoxSizer mainSizer]
+direction = horizontal
+contents = $space(10)
+contents = verticalSizer
+contents = $space(10)
+
+[wxBoxSizer verticalSizer]
+direction = vertical
+grow = yes
+proportion = 1
+contents = $space(10)
+contents = contentsSizer
+contents = $space(10)
+
+[wxGridBagSizer contentsSizer]
+grid = 5 5
+
+# __CHANGE__ 015: The dummy label was added to have at least
+# one GUI element in the sizer.
+# Remove lDummy (next 4 lines) and add the real
+# window contents here.
+contents = lDummy 0 0 1 1 left
+
+[wxStaticText lDummy]
+text = sTexts[13]
+
+
+
+%% header start
+
+
+
+%% class start
+class $frame$ : public Dk4WxFrame
+{
+ private:
+
+ /** Event table for frame.
+ */
+ DECLARE_EVENT_TABLE()
+
+ protected:
+
+ /** Localized texts.
+ */
+ wxChar const * const *sTexts;
+
+ /** Non-localized texts.
+ */
+ wxChar const * const *sNlWx;
+
+ /** Non-localized texts.
+ */
+ dkChar const * const *sNlDk;
+
+ /* __CHANGE__ 011: Add further member variables.
+ */
+
+%% class end
+
+ public:
+
+ /** Constructor.
+ @param wxid Window ID.
+ @param applicationHelper Application helper object.
+ @param hc Help controller for online help.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @param localizedTexts Localized wxChar texts.
+ @param nlWx Non-localized wxChar texts.
+ @param nlDk Non-localized dkChar texts.
+ */
+ $frame$(
+ int wxid,
+ Dk4WxApplicationHelper *applicationHelper,
+ Dk4WxHelpController *hc,
+ int argc,
+ wxChar **argv,
+ wxChar const * const *localizedTexts,
+ wxChar const * const *nlWx,
+ dkChar const * const *nlDk
+ );
+
+ /** Destructor.
+ */
+ ~$frame$();
+
+ /** Check whether we can close the window.
+ @param isLast Flag: Last main window to close.
+ */
+ bool
+ CanClose(bool isFinal);
+
+ /** Handler for File/Exit.
+ @param event Event to process.
+ */
+ void
+ OnQuit(wxCommandEvent & event);
+
+ /** Handler for Help/About.
+ @param event Event to process.
+ */
+ void
+ OnAbout(wxCommandEvent & event);
+
+ /** Handler for Help/Contents.
+ @param event Event to process.
+ */
+ void
+ OnHelpContents(wxCommandEvent & event);
+
+ /* __CHANGE__ 008: Remove OnIdle if no idle processing required.
+ */
+ /** Handler for idle events.
+ */
+ void
+ OnIdle(wxIdleEvent & event);
+
+ /* __CHANGE__ 017: Event handlers for further events.
+ */
+
+ /* __CHANGE__ 014: Add further methods.
+ */
+
+};
+
+%% header end
+
+
+/* vim: set ai sw=4 ts=4 : */
+%% module start
+
+#include "$program$.h"
+
+
+#if !defined(__WXMSW__)
+#include "$program$.xpm"
+#endif
+
+
+
+$!trace-include
+
+
+
+/* __CHANGE__ 017: Add further events. */
+/* __CHANGE__ 008: Remove OnIdle if no idle processing required. */
+BEGIN_EVENT_TABLE($frame$, wxFrame)
+ EVT_MENU($frame$_Quit, $frame$::OnQuit)
+ EVT_MENU($frame$_Help_About, $frame$::OnAbout)
+ EVT_MENU($frame$_Help_Contents, $frame$::OnHelpContents)
+ EVT_IDLE($frame$::OnIdle)
+END_EVENT_TABLE()
+
+
+
+%% constructor start
+$frame$::$frame$(
+ int wxid,
+ Dk4WxApplicationHelper *applicationHelper,
+ Dk4WxHelpController *hc,
+ int argc,
+ wxChar **argv,
+ wxChar const * const *localizedTexts,
+ wxChar const * const *nlWx,
+ dkChar const * const *nlDk
+) : Dk4WxFrame(nlWx[0], applicationHelper, hc, wxid)
+{
+ $? "+ $frame$::$frame$"
+ /* __CHANGE__ 012: Add further local variables.
+ */
+
+ /* __CHANGE__ 012: Initialize further local variables.
+ */
+
+ sTexts = localizedTexts;
+ sNlWx = nlWx;
+ sNlDk = nlDk;
+#if defined(__WXMSW__)
+ wxIcon $program$_icon(sNlWx[4]);
+#else
+ wxIcon $program$_icon($program$_xpm);
+#endif
+
+ /* __CHANGE__ 011: Initialize further class members.
+ */
+
+%% constructor end
+ if(dkctGUILayoutOK) {
+ SetTitle(nlWx[0]);
+#if 0
+ RestorePosition();
+#endif
+ }
+
+ /* __CHANGE__ 012: Release resources allocated by local variables.
+ */
+
+ $? "- $frame$::$frame$"
+}
+
+%% module end
+
+
+
+$frame$::~$frame$()
+{
+ $? "+ $frame$::~$frame$"
+
+ /* __CHANGE__ 011: Release resources allocated by further class members.
+ */
+
+ $? "- $frame$::~$frame$"
+}
+
+
+
+bool
+$frame$::CanClose(bool isLast)
+{
+ bool back = true;
+ $? "+ $frame$::CanClose isLast=%d", (isLast ? 1 : 0)
+
+ /* __CHANGE__ 013: Check for unsaved data.
+ */
+
+ $? "- $frame$::CanClose %d", (back ? 1 : 0)
+ return back;
+}
+
+
+void
+$frame$::OnQuit(wxCommandEvent & event)
+{
+ $? "+ $frame$::OnQuit"
+ $? "- $frame$::OnQuit"
+ Close();
+}
+
+
+
+void
+$frame$::OnAbout(wxCommandEvent & event)
+{
+ wxString text(wxT(""));
+ wxString title(wxT(""));
+ $? "+ $frame$::OnAbout"
+ /* Construct message text. */
+ text.Append(sNlWx[0]);
+ text.Append(sNlWx[7]);
+ text.Append(sNlWx[1]);
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[9]);
+ text.Append(sNlWx[2]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[11]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[9]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[8]);
+ text.Append(sTexts[12]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[10]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[11]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[12]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[13]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[14]);
+ text.Append(sNlWx[8]);
+ text.Append(sNlWx[15]);
+ text.Append(sNlWx[8]);
+
+ /* Construct dialog box title. */
+ title.Append(sTexts[10]);
+ title.Append(sNlWx[0]);
+
+ /* Show dialog box. */
+ wxMessageBox(text, title);
+
+ /* __CHANGE__ 019: Create better about box.
+ */
+ $? "- $frame$::OnAbout"
+}
+
+
+
+void
+$frame$::OnHelpContents(wxCommandEvent & event)
+{
+ $? "+ $frame$::OnHelpContents"
+ DisplayContents();
+ $? "- $frame$::OnHelpContents"
+}
+
+/* __CHANGE__ 017: Event handlers for further events.
+*/
+
+/* __CHANGE__ 014: Implementation of further methods.
+*/
+
+
+/* __CHANGE__ 008: Remove OnIdle if no idle processing required.
+*/
+
+void
+$frame$::OnIdle(wxIdleEvent & event)
+{
+ $? "+ $frame$::OnIdle"
+ /* __CHANGE__
+ */
+ $? "- $frame$::OnIdle"
+ event.RequestMore();
+ event.Skip();
+}
+
+
+/* vim: set ai sw=4 ts=4 : */
diff --git a/support/dktools/dktools/dkwxwizh.txt b/support/dktools/dktools/dkwxwizh.txt
new file mode 100644
index 0000000000..fe190c68a0
--- /dev/null
+++ b/support/dktools/dktools/dkwxwizh.txt
@@ -0,0 +1,131 @@
+#ifndef H_INCLUDED_$program$
+/** Include file only once.
+*/
+#define H_INCLUDED_$program$ 1
+
+#ifndef DK4CONF_H_INCLUDED
+#include <dk4conf.h>
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include <dk4types.h>
+#endif
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef WX_ARRSTR_H_INCLUDED
+#include <wx/arrstr.h>
+#define WX_ARRSTR_H_INCLUDED 1
+#endif
+
+#ifndef WX_CONFIG_H_INCLUDED
+#include <wx/config.h>
+#define WX_CONFIG_H_INCLUDED 1
+#endif
+
+#ifndef WX_FILENAME_H_INCLUDED
+#include <wx/filename.h>
+#define WX_FILENAME_H_INCLUDED 1
+#endif
+
+#ifndef WX_GBSIZER_H_INCLUDED
+#include <wx/gbsizer.h>
+#define WX_GBSIZER_H_INCLUDED 1
+#endif
+
+#ifndef WX_THREAD_H_INCLUDED
+#include <wx/thread.h>
+#define WX_THREAD_H_INCLUDED 1
+#endif
+
+#ifndef WX_GAUGE_H_INCLUDED
+#include <wx/gauge.h>
+#define WX_GAUGE_H_INCLUDED 1
+#endif
+
+#ifndef WX_HELP_H_INCLUDED
+#include <wx/help.h>
+#define WX_HELP_H_INCLUDED 1
+#endif
+
+#ifndef WX_FS_ZIP_H_INCLUDED
+#include <wx/fs_zip.h>
+#define WX_FS_ZIP_H_INCLUDED 1
+#endif
+
+#ifndef WX_CMDLINE_H_INCLUDED
+#include <wx/cmdline.h>
+#define WX_CMDLINE_H_INCLUDED 1
+#endif
+
+#ifndef WX_DIR_H_INCLUDED
+#include <wx/dir.h>
+#define WX_DIR_H_INCLUDED 1
+#endif
+
+/* __CHANGE__ 018: Add further wxWidgets header files.
+*/
+
+
+#ifndef DK4WXAPPLICTIONHELPER_H_INCLUDED
+#include <Dk4WxApplicationHelper.h>
+#endif
+
+#ifndef DK4WXFRAME_H_INCLUDED
+#include <Dk4WxFrame.h>
+#endif
+
+#ifndef DK4WXPROGRESSDIALOG_H_INCLUDED
+#include <Dk4WxProgressDialog.h>
+#endif
+
+#ifndef DK4WXHELPCONTROLLER_H_INCLUDED
+#include <Dk4WxHelpController.h>
+#endif
+
+#include "$application$.h"
+
+#include "$frame$.h"
+
+/* __CHANGE__ 018: Add header files for further classes and modules.
+*/
+
+/** IDs for menu items, buttons and other elements.
+*/
+enum {
+
+ /** Exit the application.
+ */
+ $frame$_Quit = wxID_EXIT ,
+
+ /** Main window ID.
+ */
+ $frame$_MainWindow = ((wxID_HIGHEST) + 1) ,
+
+ /** Show version dialog box.
+ */
+ $frame$_Help_About ,
+
+ /** Open table of conents for online help.
+ */
+ $frame$_Help_Contents
+};
+
+#endif
+
+/* vim: set ai sw=4 ts=4 : */
+
diff --git a/support/dktools/dktools/dkwxwizm.txt b/support/dktools/dktools/dkwxwizm.txt
new file mode 100644
index 0000000000..2a20b8d392
--- /dev/null
+++ b/support/dktools/dktools/dkwxwizm.txt
@@ -0,0 +1,85 @@
+# Package prefix
+DESTDIR=
+
+SOVERS=3.0
+
+# Compiler and linker
+
+CC=$(CXX)
+LD=$(CC)
+
+# Standard directory variables from autoconf
+prefix=@prefix@
+datarootdir=@datarootdir@
+exec_prefix=@exec_prefix@
+bindir=@bindir@
+sbindir=@sbindir@
+libexecdir=@libexecdir@
+datadir=${datarootdir}
+sysconfdir=@sysconfdir@
+scd=$(sysconfdir)
+libdir=@libdir@
+sharedlibdir=$(libdir)/shared
+mandir=@mandir@
+includedir=@includedir@
+localstatedir=@localstatedir@
+srcdir=@srcdir@
+top_srcdir=@top_srcdir@
+VPATH=@srcdir@
+
+# Compiler options for wxWidgets
+
+WXCPPFLAGS=@WXCPPFLAGS@
+WXCXXFLAGS=@WXCXXFLAGS@
+WXCFLAGS=@WXCFLAGS@
+WXLDFLAGS=@WXLDFLAGS@
+ZLIB=@ZLIB@
+BZLIB=@BZLIB@
+
+INCLUDES= -I. -I../.. -I../../gui
+
+COPTS= $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
+COMPILEC= $(CXX) $(COPTS) $(WXCXXFLAGS)
+COMPILEPP= $(CXX) $(COPTS) $(WXCXXFLAGS)
+
+# Use DK libraries
+
+DKLIBS=-ldk4wx -ldk4c -ldk4ma -ldk4maiodd -ldk4maiowd -ldk4maio8d -ldk4base $(BZLIB) $(ZLIB)
+
+.SUFFIXES:
+
+.SUFFIXES: .cpp .c .o
+
+.c.o:
+ @echo Compile $<
+ $(COMPILEC) -o $@ -c $<
+
+.cpp.o:
+ @echo Compile $<
+ $(COMPILEPP) -o $@ -c $<
+
+all: # Build example.
+all: $program$
+
+# __CHANGE__ 018: Add further modules.
+
+OBJ_$program$= \
+ $application$.o \
+ $frame$.o
+
+# __CHANGE__ 018: Add further libraries.
+
+$program$: # Test program.
+$program$: $(OBJ_$program$)
+ @echo Link $program$
+ $(LD) $(CFLAGS) $(LDFLAGS) $(WXCFLAGS) $(WXLDFLAGS) -o $program$ $(OBJ_$program$) $(DKLIBS) -lm
+ chmod 755 $program$
+
+.PHONY: help clean
+
+clean:
+ -rm $program$ *.o
+
+help:
+ -@egrep '^[^:;=. ]*::?[ ]*' Makefile | grep '#' | grep -v '^#'
+
diff --git a/support/dktools/dktools/dkwxwizr.txt b/support/dktools/dktools/dkwxwizr.txt
new file mode 100644
index 0000000000..12f485925d
--- /dev/null
+++ b/support/dktools/dktools/dkwxwizr.txt
@@ -0,0 +1,37 @@
+aaaaa ICON $program$.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,0
+ PRODUCTVERSION 1,0,0,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "$program$\0"
+ VALUE "CompanyName", "$copyrightowner$\0"
+ VALUE "FileDescription", "Program for this and that\0"
+ VALUE "FileVersion", "1.0.0\0"
+ VALUE "InternalName", "$program$\0"
+ VALUE "LegalCopyright", "Copyright © $year$ $copyrightowner$\0"
+ VALUE "ProductName", "$program$\0"
+ VALUE "ProductVersion", "1.0.0\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/dktools/dkwxwizv.txt b/support/dktools/dktools/dkwxwizv.txt
new file mode 100644
index 0000000000..70aae5d111
--- /dev/null
+++ b/support/dktools/dktools/dkwxwizv.txt
@@ -0,0 +1,404 @@
+# ##### START OF CONFIGURATION SECTION.
+#
+# __CHANGE__
+#
+# You may need to customize this section.
+#
+#
+#
+
+# 64-bit support
+# ==============
+# Uncomment the BITS64 line to build for 64-bit Windows platforms.
+
+# BITS64=1
+
+
+# Parent directory where programs reside
+# --------------------------------------
+
+# --- Programs folder on german Windows versions before Vista
+# PROGRAMS=C:\Programme
+
+# --- English versions and version on Vista and above
+PROGRAMS=C:\Program Files
+
+
+# Parent directory for 32-bit software
+# ------------------------------------
+
+!IFDEF BITS64
+PROGRAMSX86=C:\Program Files (x86)
+!ELSE
+PROGRAMSX86=C:\Program Files
+!ENDIF
+
+
+# Name of vendor subdirectory in the directory above.
+# ---------------------------------------------------
+# One string without spaces or tabulators!
+
+VENDOR=SoftwareVendor
+
+
+# Compiler and linker
+# ===================
+
+
+# Program names
+# -------------
+# Which programs to use for compiling and linking?
+
+CC=CL
+LD=LINK
+
+
+# Unicode settings
+# ----------------
+# DK tools wants the wxWidgets libraries with Unicode support,
+# release, static multi-threaded
+#
+UNICODE= /D_UNICODE=1 /DUNICODE=1
+# UNICODE=
+
+# Code generation
+# ---------------
+# MT Multi-Thread, Release, static -> LIBCMT.LIB
+# MTd ..., Debug, ... -> LIBCMTD.LIB
+# ML Single-Thread, Release, static -> LIBC.LIB
+# MLd ..., Debug, ... -> LIBCD.LIB
+# MD Multi-Thread, Release, DLL -> MSVCRT.LIB
+# MDd ..., Debug, ... -> MSVCRTD.LIB
+
+# --- Visual Studio 2005/2008 on Windows 7
+COPTIONS= /nologo /MT /W3 \
+ /D "WIN32" /D "_WIN32" /D "NDEBUG" /D "_CONSOLE" \
+ -D_CRT_SECURE_NO_WARNINGS=1 -D_CRT_SECURE_NO_DEPRECATE=1 \
+ $(UNICODE)
+
+DLLCOPTIONS= /nologo /MD /W3 \
+ /D "WIN32" /D "_WIN32" /D "NDEBUG" /D "_CONSOLE" \
+ -D_CRT_SECURE_NO_WARNINGS=1 -D_CRT_SECURE_NO_DEPRECATE=1 \
+ $(UNICODE)
+
+LINKMANIFEST= /MANIFEST
+
+
+
+# Visual Studio and Platform SDK location
+# ---------------------------------------
+
+# Where is Visual C?
+# Directories lib, include and bin must be beyound this.
+
+# --- Visual C++ 5
+# VC=$(PROGRAMS)\DevStudio\Vc
+
+# --- Visual Studio (Version 6?)
+# VC=$(PROGRAMS)\Microsoft Visual Studio\Vc98
+
+# --- Visual Studio 2003
+# VC=$(PROGRAMS)\Microsoft Visual Studio .NET 2003\Vc7
+
+# --- Visual Studio 2005
+# VC=$(PROGRAMS)\Microsoft Visual Studio 8\VC
+
+# --- Visual Studio 2005 when Platform SDK for Windows 7 is installed
+VC=$(PROGRAMSX86)\Microsoft Visual Studio 9.0\VC
+
+
+# Where is the Platform SDK for Windows 7
+
+# --- Older Platform SDKs
+# PLATFORMSDK=$(VC)\PlatformSDK
+
+# --- Use SDK shipped with Visual Studio
+# PLATFORMSDK=$(VC)
+
+# --- Platform SDK installed separately
+PLATFORMSDK=$(PROGRAMS)\Microsoft SDKs\Windows\v7.0
+
+
+# Directories
+# ===========
+# System configuration directory
+
+SCD= -DSYSCONFDIR=\"C:\\ETC\"
+
+
+
+# XCOPY overwrites
+# ================
+# does xcopy need a special option to overwrite
+# files without prompting.
+
+XCOPYFL= /Y
+
+
+
+# Required libraries
+# ==================
+
+# Location of required libraries
+# ------------------------------
+# Where do the libraries reside?
+
+LIBSRC=C:\P\LIB-STT
+
+
+# Bzip2 support
+# -------------
+BZL_DEF=-DDK4_HAVE_BZLIB_H=1
+BZL_DIR=-I$(LIBSRC)\Include
+BZL_LIB=libbz2.lib
+
+
+
+# Zlib support
+# ------------
+ZL_DEF=-DDK4_HAVE_ZLIB_H=1
+ZL_DIR=-I$(LIBSRC)\Include
+ZL_LIB=zlib.lib
+
+
+
+# Libpng support
+# --------------
+PNG_DEF=-DDK4_HAVE_LIBPNG=1 -DDK4_HAVE_PNG_H=1
+PNG_DIR=-I$(LIBSRC)\Include
+PNG_LIB=libpng.lib
+PNGEPSOBJ=pngeps.obj
+BMEPSEXE=bmeps.exe
+
+
+
+# Jpeg support
+# ------------
+JPG_DEF=-DDK4_HAVE_JPEGLIB_H=1
+JPG_DIR=-I$(LIBSRC)\Include
+JPG_LIB=libjpeg.lib
+JPGEPSOBJ=jpgeps.obj
+
+
+
+# TIFF support
+# ------------
+TIF_DEF=-DDK4_HAVE_TIFF_H=1
+TIF_DIR=-I$(LIBSRC)\Include
+TIF_LIB=libtiff.lib
+TIFEPSOBJ=tifeps.obj
+
+
+
+# wxWidgets support
+# ----------------
+WXDIR=C:\p\wxWidgets-2.8.12
+WXLIBS= \
+ $(WXDIR)\lib\vc_lib\wxbase28u.lib \
+ $(WXDIR)\lib\vc_lib\wxbase28u_net.lib \
+ $(WXDIR)\lib\vc_lib\wxbase28u_odbc.lib \
+ $(WXDIR)\lib\vc_lib\wxbase28u_xml.lib \
+ $(WXDIR)\lib\vc_lib\wxmsw28u_adv.lib \
+ $(WXDIR)\lib\vc_lib\wxmsw28u_aui.lib \
+ $(WXDIR)\lib\vc_lib\wxmsw28u_core.lib \
+ $(WXDIR)\lib\vc_lib\wxmsw28u_dbgrid.lib \
+ $(WXDIR)\lib\vc_lib\wxmsw28u_gl.lib \
+ $(WXDIR)\lib\vc_lib\wxmsw28u_html.lib \
+ $(WXDIR)\lib\vc_lib\wxmsw28u_media.lib \
+ $(WXDIR)\lib\vc_lib\wxmsw28u_qa.lib \
+ $(WXDIR)\lib\vc_lib\wxmsw28u_richtext.lib \
+ $(WXDIR)\lib\vc_lib\wxmsw28u_xrc.lib \
+ $(WXDIR)\lib\vc_lib\wxexpat.lib \
+ $(WXDIR)\lib\vc_lib\wxregexu.lib
+
+# We typically have newer variants of these libraries installed, so we
+# use $(IMGLIBS) $(ZL_LIB) instead of these libraries.
+WXIMGLIBS= $(WXDIR)\lib\vc_lib\wxpng.lib \
+ $(WXDIR)\lib\vc_lib\wxtiff.lib \
+ $(WXDIR)\lib\vc_lib\wxjpeg.lib \
+ $(WXDIR)\lib\vc_lib\wxzlib.lib
+
+
+# DK tools libraries
+# ------------------
+DK_BASE=$(PROGRAMS)\Krause
+DK_DIR=-I"$(DK_BASE)\include"
+DK_LIB=/LIBPATH:"$(DK_BASE)\lib" dk4wx.lib dk4c.lib dk4base.lib
+
+#
+#
+#
+# No changes should be necessary below this line.
+#
+# ##### END OF CONFIGURATION SECTION
+
+
+
+# ##### Start of internal setup section
+#
+#
+
+exec_prefix = $(PREFIX)
+bindir = $(exec_prefix)\bin
+sbindir = $(exec_prefix)\sbin
+libexecdir = $(exec_prefix)\libexec
+datadir = $(PREFIX)\share
+sysconfdir = $(PREFIX)\etc
+libdir = $(exec_prefix)\lib
+sharedlibdir = $(libdir)\shared
+mandir = $(PREFIX)\man
+includedir = $(PREFIX)\include
+srcdir = .
+top_srcdir = .
+
+# How to build an EXE file
+# ------------------------
+
+!IFDEF BITS64
+EXEFLAGS= /nologo /subsystem:console /incremental:no $(MACHINE) /release \
+ /LIBPATH:"$(PLATFORMSDK)\Lib\x64" /LIBPATH:"$(PLATFORMSDK)\Lib" \
+ /LIBPATH:"$(VC)\LIB\AMD64" /LIBPATH:"$(VC)\LIB" \
+ /LIBPATH:"$(LIBSRC)\LIB"
+!ELSE
+EXEFLAGS= /nologo /subsystem:console /incremental:no $(MACHINE) /release \
+ /LIBPATH:"$(PLATFORMSDK)\Lib" \
+ /LIBPATH:"$(VC)\LIB" \
+ /LIBPATH:"$(LIBSRC)\LIB"
+!ENDIF
+
+EXE= LINK $(EXEFLAGS) $(LINKMANIFEST)
+
+# How to build a GUI exe file with wxWidgets support
+# --------------------------------------------------
+!IFDEF BITS64
+GUIEXEFLAGS= /nologo /subsystem:WINDOWS /incremental:no $(MACHINE) /release \
+ /LIBPATH:"$(PLATFORMSDK)\Lib\x64" /LIBPATH:"$(VC)\LIB\AMD64" \
+ /LIBPATH:"$(PLATFORMSDK)\Lib" /LIBPATH:"$(VC)\LIB" \
+ /LIBPATH:"$(LIBSRC)\LIB"
+!ELSE
+GUIEXEFLAGS= /nologo /subsystem:WINDOWS /incremental:no $(MACHINE) /release \
+ /LIBPATH:"$(PLATFORMSDK)\Lib" \
+ /LIBPATH:"$(VC)\LIB" \
+ /LIBPATH:"$(LIBSRC)\LIB"
+!ENDIF
+
+GUIEXE= LINK $(GUIEXEFLAGS) $(LINKMANIFEST)
+
+LIB= LIB /nologo
+
+IMGLIBS= $(PNG_LIB) $(JPG_LIB) $(TIF_LIB)
+
+# compile .c to .obj
+#
+DEF1= $(BZL_DEF) $(BZL_DIR)
+DEF2= $(ZL_DEF) $(ZL_DIR)
+DEF3= $(PNG_DEF) $(PNG_DIR)
+DEF4= $(JPG_DEF) $(JPG_DIR)
+DEF5= $(TIF_DEF) $(TIF_DIR)
+DEF6= $(DK_DIR)
+DEF7= -DTRACE_WIDE=1
+
+DEFS= $(DEF1) \
+ $(DEF2) \
+ $(DEF3) \
+ $(DEF4) \
+ $(DEF5) \
+ $(DEF6) \
+ $(DEF7)
+
+COBJFLAGS= $(COPTIONS) $(DEFS) \
+ /I. /I.. /I"$(PLATFORMSDK)\Include" /I"$(VC)\Include" $(SCD)
+
+DLLCOBJFLAGS= $(DLLCOPTIONS) $(DEFS) \
+ /I. /I.. /I"$(PLATFORMSDK)\Include" /I"$(VC)\Include" $(SCD)
+
+LIB32= kernel32.lib \
+ gdi32.lib \
+ advapi32.lib \
+ user32.lib
+
+WXLIB32= ole32.lib \
+ oleaut32.lib \
+ shell32.lib \
+ comctl32.lib \
+ comdlg32.lib \
+ winspool.lib
+
+WSC32= ws2_32.lib
+NETAPI32= winspool.lib netapi32.lib
+
+VC_MANIFEST_EMBED_EXE= \
+if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1
+
+VC_MANIFEST_EMBED_DLL= \
+if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2
+
+#
+# ##### End of internal setup section
+
+
+# ##### Start of internal configuration
+#
+#
+
+MYDEFS=/I$(WXDIR)\lib\vc_lib\mswu \
+ /I$(WXDIR)\include\msvc \
+ /I$(WXDIR)\include \
+ -DDK4_USE_WX=1
+
+WXCOBJFLAGS=$(COBJFLAGS) $(MYDEFS) /EHsc /GF /Gy /fp:precise
+
+WXDEFS=$(DEFS) $(MYDEFS)
+
+.c.obj:
+ @echo Compile $*.c
+ $(CC) $(WXCOBJFLAGS) $(CFLAGS) /c $*.c
+
+.cpp.obj:
+ $(CC) $(WXCOBJFLAGS) $(CFLAGS) /c $*.cpp
+
+.rc.res:
+ RC $(WXDEFS) $*.rc
+
+WXEXE=$(GUIEXE) /LIBPATH:$(WXDIR)\lib\vc_lib /entry:"WinMainCRTStartup"
+
+#
+#
+# ##### End of internal configuration
+
+
+
+# ##### Start of targets
+#
+# __CHANGE__
+#
+# Modify this section as needed by your project.
+#
+#
+
+PROGRAMSTOBUILD= \
+ $program$.exe
+
+all: $(PROGRAMSTOBUILD)
+
+OBJ_$program$= \
+ $application$.obj \
+ $frame$.obj \
+ $program$.res
+
+$program$.exe: $(OBJ_$program$)
+ $(WXEXE) $(DK_LIB) $(LIB32) $(WXLIB32) /out:$program$.exe $(OBJ_$program$) $(WXLIBS) $(IMGLIBS) $(ZL_LIB)
+ $(VC_MANIFEST_EMBED_EXE)
+
+.PHONY: clean
+
+clean:
+ -DEL *.obj
+ -DEL *.exe
+ -DEL *.lib
+ -DEL *.deb
+
+#
+#
+# ##### End of targets
+
diff --git a/support/dktools/dktools/dkwxwizx.txt b/support/dktools/dktools/dkwxwizx.txt
new file mode 100644
index 0000000000..7b13ddb67f
--- /dev/null
+++ b/support/dktools/dktools/dkwxwizx.txt
@@ -0,0 +1,43 @@
+/* XPM */
+static const char *$program$_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"32 32 4 1",
+/* colors */
+" c #000000",
+". c #DFBB00",
+"X c #FFD600",
+"o c #C3A300",
+/* pixels */
+" .XXXXXXXXXXXXXXX",
+" .XXXXXXXXXXXXXXX",
+" .XXXXXXXXXXXXXXX",
+" .XXXXXXXXXXXXXXX",
+" .XXXXXXXXXXXXXXX",
+" .XXXXXXXXXXXXXXX",
+" .XXXXXXXXXXXXXXX",
+" .XXXXXXXXXXXXXXX",
+" .XXXXXXXXXXXXXXX",
+" .XXXXXXXXXXXXXXX",
+" .XXXXXXXXXXXXXXX",
+" .XXXXXXXXXXXXXXX",
+" .XXXXXXXXXXXXXXX",
+" .XXXXXXXXXXXXXXX",
+" .XXXXXXXXXXXXXXX",
+" o...............",
+"XXXXXXXXXXXXXXXX ",
+"XXXXXXXXXXXXXXXX ",
+"XXXXXXXXXXXXXXXX ",
+"XXXXXXXXXXXXXXXX ",
+"XXXXXXXXXXXXXXXX ",
+"XXXXXXXXXXXXXXXX ",
+"XXXXXXXXXXXXXXXX ",
+"XXXXXXXXXXXXXXXX ",
+"XXXXXXXXXXXXXXXX ",
+"XXXXXXXXXXXXXXXX ",
+"XXXXXXXXXXXXXXXX ",
+"XXXXXXXXXXXXXXXX ",
+"XXXXXXXXXXXXXXXX ",
+"XXXXXXXXXXXXXXXX ",
+"XXXXXXXXXXXXXXXX ",
+"XXXXXXXXXXXXXXXX "
+};
diff --git a/support/dktools/dktools/en/ChooseDirectory.png b/support/dktools/dktools/en/ChooseDirectory.png
new file mode 100644
index 0000000000..42c3d1b3f7
--- /dev/null
+++ b/support/dktools/dktools/en/ChooseDirectory.png
Binary files differ
diff --git a/support/dktools/dktools/en/Exit.png b/support/dktools/dktools/en/Exit.png
new file mode 100644
index 0000000000..27b641786b
--- /dev/null
+++ b/support/dktools/dktools/en/Exit.png
Binary files differ
diff --git a/support/dktools/dktools/en/Options.png b/support/dktools/dktools/en/Options.png
new file mode 100644
index 0000000000..7f5570cbd0
--- /dev/null
+++ b/support/dktools/dktools/en/Options.png
Binary files differ
diff --git a/support/dktools/dktools/en/Run.png b/support/dktools/dktools/en/Run.png
new file mode 100644
index 0000000000..0ae92ba9de
--- /dev/null
+++ b/support/dktools/dktools/en/Run.png
Binary files differ
diff --git a/support/dktools/dktools/en/dk-blks.txt b/support/dktools/dktools/en/dk-blks.txt
new file mode 100644
index 0000000000..983c5687e4
--- /dev/null
+++ b/support/dktools/dktools/en/dk-blks.txt
@@ -0,0 +1,42 @@
+
+NAME
+
+dk-blks - Adjust block size.
+
+SYNOPSIS
+
+dk-blks [<option>]
+
+DESCRIPTION
+
+The program reads a data stream from standard input and writes it to standard
+output using a specified block size.
+
+It is inteded to prepare a data stream for the ``dd'' program, source data
+may come from network transmission or a decryption or decompression program.
+
+OPTIONS
+
+-b <size>, --block-size=<size>
+ Block size (default: 4096).
+ You can append ``k'', ``m'', ``g'' or ``t'' for multiples of
+ 1024, 1024^2, 1024^3 or 1024^4, i.e. ``-b 4k'' or ``-b 1m''.
+
+EXIT STATUS
+
+0 on success, all other values indicate errors.
+
+AUTHOR
+
+Dirk Krause
+
+COPYRIGHT AND LICENSE
+
+Run
+ dk-blks --license
+to see license information.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/en/dk-bmm.txt b/support/dktools/dktools/en/dk-bmm.txt
new file mode 100644
index 0000000000..6b21405977
--- /dev/null
+++ b/support/dktools/dktools/en/dk-bmm.txt
@@ -0,0 +1,63 @@
+
+NAME
+
+dk-bmm - Backup media management
+
+SYNOPSIS
+
+dk-bmm [<option(s)>] [<file>]
+
+DESCRIPTION
+
+The dk-bmm program performs one of the following four operations:
+
+* Retrieve name of current backup media set (option -s).
+
+* Confirm that backup to current media set was finished successfully
+ (options -s and -c).
+
+* Retrieve number of current backup media (default operation, neither
+ -s nor -c required).
+
+* Confirm that backup to current media was finished successfully
+ (option -c).
+
+OPTIONS
+
+-s Process backup media sets.
+--set
+
+-c Confirm that previous backup was finished successfully.
+--confirm
+
+-r Write report for one media set.
+--report
+
+EXIT STATUS
+
+0 on success, all other values indicate errors.
+
+RESTRICTIONS
+
+On Windows the file name length is restricted to _MAX_PATH (260) characters
+if the file name contains a wildcard (* or ? character).
+
+AUTHOR
+
+Dirk Krause
+
+HISTORY
+
+This program was named ``tape'' in version 2.x.x, in version 3.x.x the
+functionality was availalbe in ``dkt tape''.
+
+COPYRIGHT AND LICENSE
+
+Run
+ dk-bmm --license
+ to see license information.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/en/dk-cat.txt b/support/dktools/dktools/en/dk-cat.txt
new file mode 100644
index 0000000000..b187701033
--- /dev/null
+++ b/support/dktools/dktools/en/dk-cat.txt
@@ -0,0 +1,85 @@
+
+NAME
+
+ dk-cat - Show text files.
+
+SYNOPSIS
+
+ dk-cat [<options>] [<file(s)>]
+
+DESCRIPTION
+
+The dk-cat program shows text files. If a BOM (byte order marker) at the
+start of file indicates an encoding, the file is recoded to the system
+encoding or the encoding required by command line options.
+
+OPTIONS
+
+-c <boolean>, --crnl=<boolean>
+ Enable/disable use of the CR/NL sequence.
+ Without this option the systems default is used.
+
+-n, --line-numbers
+ Line numbers before each line.
+
+--line-number-width=<integer>
+ Minimum number of digits to use for line numbers, default: 5.
+
+-w, --normalize
+ Normalize text lines (remove leading and trailing white spaces,
+ replace whitespace sequences by one space).
+
+-i <string>
+ Expected input encoding, one from:
+ plain ASCII text,
+ ascii synonym for plain,
+ ansi ANSI encoding,
+ utf-8 UTF-8 encoding,
+ utf-16 UTF-16 encoding in systems default endianness,
+ utf-16le UTF-16 encoding with least significant byte first,
+ utf-16be UTF-16 encoding with most significant byte first,
+ c32 32 bit characters in systems default endianness,
+ c32le 32 bit characters with least significant byte first,
+ c32be 32 bit characters with most significant byte first.
+ The encoding specified here is overwritten if a BOM is found at the
+ start of an input file.
+
+-o <string>
+ Output encoding, see above for encodings.
+ Use <encoding>[,bom] - i.e. utf-16be,bom - to require writing
+ a byte order marker at start of output.
+ The default is no BOM when writing to a terminal,
+ use BOM when writing to file.
+
+-p, --pass-through
+ Pass-through of UTF-8 encoded data when UTF-8 output
+ is wanted and UTF-8 input is found.
+ Without this option input is decoded to 32 bit characters
+ and encoded to UTF-8 (check for correct UTF-8 encoding).
+
+--verbose
+ Show error message on interrupt by SIGPIPE.
+
+EXIT STATUS
+
+0 on success, all other values indicate errors.
+
+RESTRICTIONS
+
+On Windows the file name length is restricted to _MAX_PATH (260) characters
+if the file name contains a wildcard (* or ? character).
+
+AUTHOR
+
+Dirk Krause
+
+COPYRIGHT AND LICENSE
+
+Run
+ dk-cat --license
+to see license information.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/en/dk-db2t.txt b/support/dktools/dktools/en/dk-db2t.txt
new file mode 100644
index 0000000000..b5be8fa521
--- /dev/null
+++ b/support/dktools/dktools/en/dk-db2t.txt
@@ -0,0 +1,102 @@
+
+NAME
+
+dk-db2t - Show simple database as text
+
+SYNOPSIS
+
+dk-db2t [<option>...] <database>
+
+DESCRIPTION
+
+The program shows a simple text database as text on standard output.
+
+A ``simple database'' is a Berkeley DB, NDBM or in-memory database.
+The records are key/value pairs, both key and value are a byte array.
+Keys are unique.
+
+In a ``simple text database'' all keys and values are text strings.
+The finalizing 0 character is saved in the database together with the
+texts.
+
+Use type::filename to specify databases (Type and file name are separated
+by two colons). The following type names can be used:
+bdb Berkeley DB
+ndbm NDBM database
+mem in-memory database
+
+OPTIONS
+
+-k <size>, --key-buffer-size=<size>
+ Size for key buffer (must be large enough to store the largest
+ string including the finalizing 0 character).
+
+-v <size>, --value-buffer-size=<size>
+ Size for value buffer (must be large enough to store the largest
+ value string including the finalizing 0 character).
+
+-R, --reset
+ Ignore preferences values for key and value buffer size.
+
+--help
+ Show short help text.
+
+--version
+ Show version and supported database backends.
+
+--license
+ Show license terms.
+
+--manual
+ Show this long help text.
+
+--verbose
+ Show error message on interrupt by SIGPIPE.
+
+EXIT STATUS
+
+0 on success, all other values indicate errors.
+
+EXAMPLES
+
+* Show in-memory database file1.dat
+ dk-db2t mem::file1.dat
+
+* Show Berkeley DB database file2.dat
+ dk-db2t bdb::file2.dat
+
+* Show NDBM database file3 (consisting of file3.dir and file3.pag)
+ dk-db2t ndbm::file3
+
+PREFERENCES
+
+text-db.key.max-size
+ Size of key buffer if option -k was not used.
+
+text-db.value.max-size
+ Size of value buffer if option -v was not used.
+
+RESTRICTIONS
+
+There is no wildcard expansion for file names on Windows, * and ? can not
+be used in file names.
+
+AUTHOR
+
+Dirk Krause
+
+HISTORY
+
+In previous DK tools versions the functionality was provided by the
+``dkdbt text'' command.
+
+COPYRIGHT AND LICENSE
+
+Run
+ dk-db2t --license
+to see license information.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/en/dk-dbco.txt b/support/dktools/dktools/en/dk-dbco.txt
new file mode 100644
index 0000000000..be22b76c9c
--- /dev/null
+++ b/support/dktools/dktools/en/dk-dbco.txt
@@ -0,0 +1,82 @@
+
+NAME
+
+dk-dbco - Copy and convert simple databases
+
+SYNOPSIS
+
+dk-dbco [<options>] <source> <destination>
+
+DESCRIPTION
+
+The program copies the records from a simple database into another
+simple database. The records are converted to the new database type
+if necessary.
+
+A ``simple database'' is a Berkeley DB, NDBM or in-memory database.
+The records are key/value pairs, both key and value are a byte array.
+Keys are unique.
+
+Use type::filename to specify databases (Type and file name are separated
+by two colons). The following type names can be used:
+bdb Berkeley DB
+ndbm NDBM database
+mem in-memory database
+
+OPTIONS
+
+-a, --add
+ adds data to an existing database (modifies or adds records).
+ Without this option the program deletes an existing database
+ and creates a new one.
+
+-k <size>, --key-buffer-size=<size>
+ Key buffer size (number of bytes), default: 4096.
+
+-v <size>, --value-buffer-size=<size>
+ Value buffer size (number of bytes), default: 4096.
+
+-R, --reset
+ Ignore preference values for key and value buffer size.
+
+EXIT STATUS
+
+0 on success, all other values indicate errors.
+
+EXAMPLES
+
+* Convert Berkeley DB database db1.db to in-memory database db2.dat,
+ truncate db2.dat if it already exists:
+ dk-dbco bdb::db1.db mem::db2.dat
+
+* Convert NDBM database db3 (consisting of files db3.dir and db3.pag)
+ to in-memory database db4.dat, keep existing records in db4.dat:
+ dk-dbco -a ndbm::db3 mem::db4.dat
+
+PREFERENCES
+
+db.key.max-size
+ Key buffer size if the -k option was not used.
+
+db.value.max-size
+ Value buffer size if the -v option was not used.
+
+AUTHOR
+
+Dirk Krause
+
+HISTORY
+
+In previous DK tools versions the funcionality was provided by the
+``dkdbt copy'' command.
+
+COPYRIGHT AND LICENSE
+
+Run
+ dk-dbco --license
+to see license information.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/en/dk-fic.txt b/support/dktools/dktools/en/dk-fic.txt
new file mode 100644
index 0000000000..e70748cdaf
--- /dev/null
+++ b/support/dktools/dktools/en/dk-fic.txt
@@ -0,0 +1,96 @@
+
+NAME
+
+dk-fic - File integrity checker
+
+SYNOPSIS
+
+dk-fic [<options>] [<file(s)>]
+
+DESCRIPTION
+
+The program can either build file checksum list or check (verify)
+checksum lists.
+A checksum list contains message digests (MD5, SHA-1, RIPEMD-160 and SHA-512),
+file size and file name.
+If support for the SHA-512 message digest algorithm was not found during
+build process, the SHA-512 message digest is skipped.
+Message digests are converted to text using ASCII-85 encoding, not
+ASCII-Hex.
+When building a file checksum list, the files specified as command line
+arguments contain lists of file names to produce checksums for. If no file
+is specified as argument, the list of file names is read from standard
+input.
+When verifying checksum lists, the files specified as command line arguments
+contain checksum lists previously produced. If no file is specified as
+argument, the checksum list is read from standard input.
+
+OPTIONS
+
+-c
+--check
+ Check (verify) a checksum list.
+ Without this option the program produces a checksum list.
+
+-v
+--verbose
+ Produce a message for succeeded tests too when checking.
+ By default a message is only produced for failed tests.
+
+-q
+--quiet
+ No output for failed tests when checking a checksum list.
+ Options -v and -q are mutually exclusive.
+
+-l <size>
+--line-size=<size>
+ Input line buffer size.
+
+EXIT STATUS
+
+0 on success, all other values indicate errors.
+
+PREFERENCES
+
+line.size
+ configures the line buffer size if the -l option was not used.
+
+EXAMPLES
+
+Produce a checksum list on Windows:
+ dk-ls -r -tf -pn <directory> | dk-fic > checklist.txt
+
+Produce a checksum list on non-Windows systems:
+ find <directory> -type f | dk-fic > checklist.txt
+
+Verify a checksum list:
+ dk-fic -c < checklist.txt
+
+When creating a checksum list, make sure the checksum list file is not
+included in the checksum list itself.
+
+RESTRICTIONS
+
+On Windows the file name length is restricted to _MAX_PATH (260) characters
+if the file name contains a wildcard (* or ? character).
+
+AUTHOR
+
+Dirk Krause
+
+HISTORY
+
+COPYRIGHT AND LICENSE
+
+Run
+ dk-fic --license
+to see license information.
+
+This product includes cryptographic software written by
+Eric Young (eay@cryptsoft.com).
+This product includes software written by Tim Hudson (tjh@cryptsoft.com).
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/en/dk-hex.txt b/support/dktools/dktools/en/dk-hex.txt
new file mode 100644
index 0000000000..52c678f280
--- /dev/null
+++ b/support/dktools/dktools/en/dk-hex.txt
@@ -0,0 +1,51 @@
+
+NAME
+
+dk-hex - Show file contents in hexadecimal notation
+
+SYNOPSIS
+
+dk-hex [<options>] [<file(s)>]
+
+DESCRIPTION
+
+The dk-hex program shows file contents in hexadecimal or octal notation.
+Input is read from the specified files or from standard input if no files
+are specified.
+
+OPTIONS
+
+-o Use octal notation instead of hexadecimal notation.
+--octal
+
+-a Show addresses too.
+--addresses
+
+-t Show printable text characters too.
+--text
+
+--verbose Show error message on interrupt by SIGPIPE.
+
+EXIT STATUS
+
+0 on success, all other values indicate errors.
+
+RESTRICTION
+
+On Windows the file name length is restricted to _MAX_PATH (260) characters
+if the file name contains a wildcard (* or ? character).
+
+AUTHOR
+
+Dirk Krause
+
+COPYRIGHT AND LICENSE
+
+Run
+ dk-hex --license
+to see license information.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/en/dk-ls.txt b/support/dktools/dktools/en/dk-ls.txt
new file mode 100644
index 0000000000..d78190e0d6
--- /dev/null
+++ b/support/dktools/dktools/en/dk-ls.txt
@@ -0,0 +1,271 @@
+
+NAME
+
+ dk-ls - List files
+
+SYNOPSIS
+
+ dk-ls [<options>] [<file(s)>]
+
+DESCRIPTION
+
+The dk-ls program shows information about files.
+
+OPTIONS
+
+-r
+--recursive
+ Recursive listing.
+
+-f
+--stay-on-filesystem
+ Stay in the current file system for recursive listings.
+
+-p <string>
+--print-order=<string>
+ Print order.
+ The string consists of key characters for information to print:
+ n Name
+ N Name, but do not show symbolic link target
+ s Size
+ t Type
+ p Permissions (attributes on Windows systems)
+ c Creation timestamp
+ m Modification timestamp
+ a Last access timestamp
+ l Number of links
+ u File owner user ID (not on Windows systems)
+ g File group ID (not on Windows systems)
+ d Device number (volume serial number on Windows systems)
+ i Inode number (file index on Windows systems)
+ r Relative device number for special files
+ w Windows reparse tag value (only on Windows systems)
+ x Message digest (file checksum)
+ The default is ``mtpn'' on non-Windows systems, ``mtn'' on Windows
+ unless the ``print.order'' preference is defined.
+
+-t <string>
+--types=<string>
+ Types to show information for:
+ d Directories
+ f Non-directory entries.
+
+-s
+--summary
+ Show summary at end (total number of reported directories, files
+ and sizes in bytes).
+
+-m <string>
+--message-digest=<string>
+ Message digest type and encoding, separated by dot.
+ The digest type can be one from ``md5'', ``sha-1'', ``sha-224'',
+ ``sha-256'', ``sha-384'', ``sha-512'', or ``ripemd-160''.
+ The encoding can be one from ``hex'' (ASCII-Hex encoding) or
+ ``a85'' (ASCII-85 encoding).
+ The default is ``sha-1.hex'' unless the ``message.digest''
+ preference is defined.
+
+-R
+--reset
+ Ignores all preference values for options (print order and
+ message digest type).
+
+EXIT STATUS
+
+0 on success, all other values indicate errors.
+
+DIAGNOSTICS
+
+A sequence of question marks is printed if the program fails to obtain
+device number, volume serial number, inode number, or file index number.
+
+A single question mark is printed if the program fails to obtain
+number of links, file owner UID, or file owner GID.
+
+A sequence of `x' characters is printed if a message digest is requested
+for anything else than a regular file or if the program failed to read
+the file.
+
+TYPE OUTPUT ON NON-WINDOWS SYSTEMS
+
+The output consists of 2 characters:
+
+* One link indicator character. `l' for symbolic links within the same
+ file system, `L' for far links (crossing file system boundaries),
+ `!' for dangling links (link target does not exist),
+ '-' for all other entries.
+
+* One file type character, one from:
+ d for directories,
+ - for regular files,
+ p for pipe (FIFO),
+ c for a character special device,
+ b for a block special device,
+ s for network sockets,
+ C for multiplexed character special device,
+ B for a multiplexed block special device,
+ D for a name service door,
+ e for event ports,
+ o for Xenix special files,
+ n for Xenix semaphores,
+ m for Xenix shared data,
+ v for VXFS compressed file,
+ n for a network special file,
+ w for a whiteout,
+ a for an ACL shadow entry.
+
+PERMISSIONS OUTPUT ON NON-WINDOWS SYSTEMS
+
+The output consists of 3 groups: Permissions for file owner user,
+file owner group and other persons. Each group consists of 3 characters
+indicating read, write, and execute permission.
+
+If the set user ID bit is set, the execution permission character
+for the user is changed from `x' to `s' or from `-' to `S'.
+If the set group ID bit is set, the execution permission character
+for the group is changed from `x' to `s' or from `-' to `S'.
+If the restricted deletion flag or sticky bit is set, the execution
+permission character for others is changed from `x' to `t' or from
+`-' to `T'.
+
+
+TYPE OUTPUT ON WINDOWS SYSTEMS
+
+The output consists of 2 characters:
+
+* One reparse point character:
+ - not a reparse point,
+ m for mount points,
+ l for symbolic links,
+ w for mounted WIM images,
+ s for SIS reparse points,
+ n for NFS reparse points,
+ c for CSV reparse points,
+ d for DFS reparse points,
+ f for DFSR reparse points,
+ u for deduplication reparse points,
+ h for HSM reparse points,
+ 2 for HSM2 reparse points,
+ r for all other reparse point types.
+
+* One file type character, one from:
+ d for directories
+ - for regular files
+ b for (block special) devices
+
+ATTRIBUTES OUTPUT ON WINDOWS SYSTEMS
+
+The output consists of 10 characters:
+
+* One character for ``read-only'' atribute,
+ R if file is read-only.
+ - otherwise.
+
+* One character for ``system'' attribute,
+ S for system files or directories,
+ - otherwise.
+
+* One character for ``hidden'' attribute,
+ H for hidden files,
+ - otherwise.
+
+* One character for ``not indexed'' attribute,
+ I for exclusion from indexing,
+ - otherwise.
+
+* One character for ``compressed'' attribute,
+ C for compressed files,
+ - otherwise.
+
+* One character for ``encrypted'' attribute,
+ E for encrypted files,
+ - otherwise.
+
+* One character for ``offline'' attribute,
+ O for offline files,
+ - otherwise.
+
+* One character for ``sparse'' attribute,
+ P for sparse files,
+ - otherwise.
+
+* One character for ``temporary'' attribute,
+ T for temporary files,
+ - otherwise.
+
+* One character for ``virtual'' attribute,
+ V for virtual files,
+ - otherwise.
+
+PREFERENCES
+
+print.order
+ Default value for the print order if the -p option was not specified.
+
+message.digest
+ Default value for the message digest type and encoding if
+ the -m option was not specified.
+
+RESTRICTIONS
+
+On Windows the file name length is restricted to _MAX_PATH (260) characters
+if the file name contains a wildcard (* or ? character).
+
+On Windows systems user management and file permission concepts differ
+significantly from the concepts on Linux and Unix systems.
+The characters `u' and `g' in the print order specification have no effect.
+
+On Windows there are different functions available to obtain information
+about files. Sometimes a function delivering less information succeeds
+for files where the default function delivering more information fails
+(i.e. when non-privileged processes ask for information about
+c:\pagefile.sys).
+In such situations we can not print volume serial number, file index
+or number of links. Question marks are shown instead.
+
+On non-Windows systems there is no reparse point tag, so a `w' in the
+print order specification has no effect.
+
+QUOTED FILE NAMES ON WINDOWS
+
+On Windows systems the backslash is used for two purposes:
+* as separator between path name components and
+* as escape character, i.e. in double quoted strings.
+Quotes are used around text containing spaces to pass the entire text as
+one argument to a command. Unfortunately quoting also activates processing
+of backslashes as start of escape sequences.
+
+Text typed in the shell Passed from the shell to the command
+ C: C:
+ "C:" C:
+ C:\ C:\
+ "C:\" C:"
+ C:\\ C:\\
+ "C:\\" C:\
+
+In the fourth example we want to specify the root directory of a disk drive,
+enclosed in double quotes. Unfortunately the end of the directory name
+(the backslash) and the closing quote are recognized as a backslash escape
+sequence by cmd.exe, as a result backslash escape sequence processing a
+double quote is passed to the command.
+So if you type
+ dk-ls "C:\"
+cmd.exe provides C:" as file name to dk-ls. When using double quotes
+for file names, take care of backslash escape sequence processing,
+ dk-ls "C:\\"
+would be the correct command here.
+
+AUTHOR
+
+Dirk Krause
+
+COPYRIGHT AND LICENSE
+
+Run
+ dk-ls --license
+to see license information.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/en/dk-pwd.txt b/support/dktools/dktools/en/dk-pwd.txt
new file mode 100644
index 0000000000..619aa9f613
--- /dev/null
+++ b/support/dktools/dktools/en/dk-pwd.txt
@@ -0,0 +1,39 @@
+
+NAME
+
+dk-pwd - Print working directory
+
+SYNOPSIS
+
+dkpwd [<option(s)>]
+
+DESCRIPTION
+
+The program shows the current working directory name on standard output.
+
+OPTIONS
+
+-l Last part of name only.
+
+-b Backslashes (on Windows) replaced by slashes.
+
+EXIT STATUS
+
+0 on success, all other values indicate errors.
+
+AUTHOR
+
+Dirk Krause
+
+HISTORY
+
+COPYRIGHT AND LICENSE
+
+Run
+ dk-pwd --license
+to see license information.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/en/dk-pwgen.txt b/support/dktools/dktools/en/dk-pwgen.txt
new file mode 100644
index 0000000000..495a24cc97
--- /dev/null
+++ b/support/dktools/dktools/en/dk-pwgen.txt
@@ -0,0 +1,139 @@
+
+NAME
+
+dk-pwgen - Password, pin, hexadecimal key generator
+
+SYNOPSIS
+
+dk-pwgen [<options>]
+
+DESCRIPTION
+
+The dk-pwgen program generates passwords, pins or hexadecimal keys
+(i.e. used for WiFi).
+The output type is one of the following:
+
+* Normal user password.
+ This is the default output type. Specify a range (or just a value)
+ for password length, number of uppercase characters in the password,
+ number of digits in the password and number of special characters
+ in the password. The minimum password length must be at least the
+ summary of uppercase, digits and special character maximum.
+
+* Hard password
+ Use -h to switch to hard passwords and specify the length (either value
+ or range). Characters are choosen in the range 0x33 (`!') to
+ 0x7A (`z').
+
+* Binary random data
+ Use -b to produce binary random data instead of a password, specify
+ the length (either value or range).
+ Not available on Windows platforms, use the dk-rand program instead.
+
+* Pin number
+ Use -p to switch to pin numbers and specify the length (either value
+ or range).
+
+* Hexadecimal key
+ Use -x or -X to switch to hexadecimal keys and specify the length (either
+ value or range).
+
+OPTIONS
+
+-h
+--hard
+ Hard password instead of normal user passwords.
+
+-b
+--binary
+ Binary random data instead of passwords, pins or keys.
+ Not available on Windows platforms, use the dk-rand
+ program instead.
+
+-x
+--hex
+ Hexadecimal key using `a'...`f' for 10...15.
+
+-X
+--Hex
+ Hexadecimal key using `A'...`F' for 10...15.
+
+-p
+--pin
+ PIN number.
+
+-l <range>
+--length=<range>
+ Output length.
+ Ranges are specified as <min>-<max>, i.e. ``6-8''.
+
+-u <range>
+--upper-case=<range>
+ Number of upper case characters for normal
+ user passwords.
+
+-d <range>
+--digits=<range>
+ Number of digits for normal user passwords.
+
+-s <range>
+--special=<range>
+ Number of special characters for normal user passwords.
+
+-n
+--no-newline
+ Suppress the newline at end of output.
+
+--verbose
+ Show error message on interrupt by SIGPIPE.
+
+EXIT STATUS
+
+0 on success, all other values indicate errors.
+
+EXAMPLES
+
+Create normal user password, 8 to 10 characters long, containing
+1 to 3 upper case characters, 1 to 2 digits and 1 to 2 special
+characters:
+
+dk-pwgen -l 8-10 -u 1-3 -d 1-2 -s 1-2
+
+
+Create a harder password, 8 to 10 characters long:
+
+dk-pwgen -h -l 8-10
+
+
+Create a numeric PIN, 6 characters long:
+
+dk-pwgen -p -l 6
+
+
+Create a hexadecimal key for WiFi, 64 characters long:
+
+dk-pwgen -x -l 64
+
+
+AUTHOR
+
+Dirk Krause
+
+COPYRIGHT AND LICENSE
+
+Run
+ dk-pwgen --license
+to see license information.
+
+#if DK4_HAVE_OPENSSL_RAND_H
+This product includes software developed by the OpenSSL Project for use in
+the OpenSSL Toolkit (http://www.openssl.org/).
+This product includes cryptographic software written by
+Eric Young (eay@cryptsoft.com).
+This product includes software written by Tim Hudson (tjh@cryptsoft.com).
+#endif
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/en/dk-recv.txt b/support/dktools/dktools/en/dk-recv.txt
new file mode 100644
index 0000000000..843dd1335d
--- /dev/null
+++ b/support/dktools/dktools/en/dk-recv.txt
@@ -0,0 +1,66 @@
+
+NAME
+
+dk-recv - Receive data from a dk-send process
+
+SYNOPSIS
+
+dk-recv [<option(s)>] <host> <port> [<file>]
+
+DESCRIPTION
+
+The program establishes a TCP connection to the given host and port
+and receives data. Output is written to the given file or standard output.
+
+OPTIONS
+
+-t Tell dk-send process to start transmission.
+--transmission
+
+-l <port> Local port number to use (service name
+--local-port=<port> allowed).
+
+-c <timeout> Timeout for connection (integer or floating
+--connect-timeout=<timeout> point number).
+
+--help Show short help screen.
+
+--manual Show manual text (this text).
+
+--version Show version information.
+
+--license Show license.
+
+EXIT STATUS
+
+0 on success, all other values indicate errors.
+
+EXAMPLES
+
+* Receive data and store on hard disk (or partition):
+ dk-recv 192.0.2.103 9876 | dk-blks -b 4k | dd of=/dev/sda bs=4096
+
+RESTRICTIONS
+
+On Windows the file name length is restricted to _MAX_PATH (260) characters
+if the file name contains a wildcard (* or ? character).
+
+AUTHOR
+
+Dirk Krause
+
+HISTORY
+
+The functionality of this program was available in ``dknet -r'' in version
+3.x.x.
+
+COPYRIGHT AND LICENSE
+
+Run
+ dk-recv --license
+to see license information.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/en/dk-send.txt b/support/dktools/dktools/en/dk-send.txt
new file mode 100644
index 0000000000..2f2d132b5a
--- /dev/null
+++ b/support/dktools/dktools/en/dk-send.txt
@@ -0,0 +1,77 @@
+
+NAME
+
+dk-send - Send data to one or multiple recipients (dk-recv processes)
+
+SYNOPSIS
+
+dk-send [<option(s)>] <port> [<file>]
+
+DESCRIPTION
+
+The program accepts incoming connection requests and establishes connections.
+The file contents (or data from standard input) is sent to all recipients.
+
+OPTIONS
+
+-n <number> Number of expected clients or ``unlimited''.
+--number-of-clients=<number> When specifying ``unlimited'' here, the
+ last client must use the -t option.
+
+-a <clients> Comma-separated list of allowed client
+--allow=<clients> addresses. Each client address consists
+ of an IP address (IPv4 or IPv6), optionally
+ followed by a netmask (IP address or bit
+ number). IP address and mask are separated
+ by a slash.
+
+-l Listen on local interfaces only.
+--local-only
+
+-b <number> Number of connection requests to queue
+--backlog=<number> if necessary.
+
+-c <timeout> Timeout in seconds for read attempt after
+--connect-timeout=<timeout> establishing a connection.
+
+EXIT STATUS
+
+0 on success, all other values indicate errors.
+
+EXAMPLES
+
+* Send an entire hard disk or partition
+ dd if=/dev/sda bs=4096 | dk-send 9876
+
+* ... to 3 recipients
+ dd if=/dev/sda bs=4096 | dk-send -n 3 9876
+
+* ... which must be in 192.0.2.0/255.255.255.0
+ dd if=/dev/sda bs=4096 | dk-send -n 3 -a 192.0.2.0/255.255.255.0 9876
+ or
+ dd if=/dev/sda bs=4096 | dk-send -n 3 -a 192.0.2.0/24 9876
+
+RESTRICTIONS
+
+On Windows the file name length is restricted to _MAX_PATH (260) characters
+if the file name contains a wildcard (* or ? character).
+
+AUTHOR
+
+Dirk Krause
+
+HISTORY
+
+The functionality of this program was available in ``dknet -s'' in version
+3.x.x.
+
+COPYRIGHT AND LICENSE
+
+Run
+ dk-send --license
+to see license information.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/en/dk-sort.txt b/support/dktools/dktools/en/dk-sort.txt
new file mode 100644
index 0000000000..b4769c9701
--- /dev/null
+++ b/support/dktools/dktools/en/dk-sort.txt
@@ -0,0 +1,106 @@
+
+NAME
+
+dk-sort - Sort text line by line
+
+SYNOPSIS
+
+dk-sort [<options>] [<file(s)>]
+
+DESCRIPTION
+
+The program sorts input text from the specified files (or from standard
+input if no file is specified) line by line.
+
+OPTIONS
+
+-i <string>
+--input-encoding=<string>
+ Expected input encoding. A byte order marker (BOM) at the beginning
+ of the file overwrites the encoding specified here.
+
+-c
+--case-insensitive
+ Case-insensitive comparisons.
+
+-b
+--ignore-leading-blanks
+ Ignore leading whitespace sequences at start of line.
+
+-w
+--normalize
+ Normalize lines (deletes leading and trailing whitespace
+ sequences and replaces other whitespace sequences by one space).
+
+-e
+--suppress-empty-lines
+ Suppress empty lines.
+
+-n
+--number
+ Compare lines by leading integer number.
+
+-u
+--unsigned
+ Compare lines by leading unsigned integer number.
+
+-x
+--hex
+ Compare lines by leading unsigned integer number in hexadecimal
+ notation.
+
+-f
+--float
+ Compare lines by leading floating point number (C data type
+ double is used).
+
+-v
+--value-lines-first
+ Write lines containing a value (-n, -u, -x, -f) before lines
+ containing no value. Default is to write the lines without
+ value first.
+
+-m
+--merge-equal-lines
+ Write only one line from a sequence of equal lines to output.
+
+-r
+--reverse
+ Reversed sort order.
+
+-l <size>
+--line-size=<size>
+ Line buffer size (default and minimum is 1024).
+
+-R
+--reset
+ Ignore preference settings for line buffer size.
+
+EXIT STATUS
+
+0 on success, all other values indicate errors.
+
+PREFERENCES
+
+line.size
+ Line buffer size if the -l option was not used.
+
+RESTRICTIONS
+
+On Windows the file name length is restricted to _MAX_PATH (260) characters
+if the file name contains a wildcard (* or ? character).
+
+AUTHOR
+
+Dirk Krause
+
+COPYRIGHT AND LICENSE
+
+Run
+ dk-sort --license
+to see license information.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/en/dk-sqlsplit.txt b/support/dktools/dktools/en/dk-sqlsplit.txt
new file mode 100644
index 0000000000..8f0b822aa7
--- /dev/null
+++ b/support/dktools/dktools/en/dk-sqlsplit.txt
@@ -0,0 +1,42 @@
+
+NAME
+
+dk-sqlsplit - Split overlong SQL lines
+
+SYNOPSIS
+
+dk-sqlsplit [<file(s)>]
+
+DESCRIPTION
+
+The program splits overlong SQL lines (i.e. produced by mysqldump)
+at record borders. Record borders are sequences of closing bracket,
+comma, and opening bracket outside single quoted, double quoted, or
+back-tick quoted strings or comments.
+
+The program reads input from standard input or from the specified files and
+writes output to standard output.
+
+EXIT STATUS
+
+0 on success, all other values indicate errors.
+
+RESTRICTIONS
+
+On Windows the file name length is restricted to _MAX_PATH (260) characters
+if the file name contains a wildcard (* or ? character).
+
+AUTHOR
+
+Dirk Krause
+
+COPYRIGHT AND LICENSE
+
+Run
+ dk-sqlsplit --license
+to see license information.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/en/dk-t2db.txt b/support/dktools/dktools/en/dk-t2db.txt
new file mode 100644
index 0000000000..185bfe476c
--- /dev/null
+++ b/support/dktools/dktools/en/dk-t2db.txt
@@ -0,0 +1,116 @@
+
+NAME
+
+dk-t2db - Text to database converter
+
+SYNOPSIS
+
+dk-t2db [<options>] [<file>...] <database>
+
+DESCRIPTION
+
+The program converts text from the specified files or standard input
+into a simple text database.
+
+A ``simple database'' is a Berkeley DB, NDBM or in-memory database.
+The records are key/value pairs, both key and value are a byte array.
+Keys are unique.
+
+In a ``simple text database'' all keys and values are text strings.
+The finalizing 0 character is saved in the database together with the
+texts.
+
+Use type::filename to specify databases (Type and file name are separated
+by two colons). The following type names can be used:
+bdb Berkeley DB
+ndbm NDBM database
+mem in-memory database
+
+OPTIONS
+
+-a, --add
+ adds data to an existing database (modifies or adds records).
+ Without this option the program deletes an existing database
+ and creates a new one.
+
+-R, --reset
+ ignores preference values for line, key and value buffer size.
+
+-l <size>, --line-size=<size>
+ Line buffer size (number of characters), default: 1024.
+
+-k <size>, --key-buffer-size=<size>
+ Key buffer size (number of characters), default: 512.
+
+-v <size>, --value-buffer-size=<size>
+ Value buffer size (number of characters), default: 512.
+
+-i <string>, --input-encoding=<string>
+ Expected input encoding. The encoding is overwritten if a
+ byte order marker (BOM) is found at the start of input.
+
+-c <string>, --comment=<string>
+ Optional comment character. All lines having the comment character
+ as first non-whitespace character are comments.
+
+EXIT STATUS
+
+0 on success, all other values indicate errors.
+
+EXAMPLES
+
+* Process standard input, create in-memory database file db.dat:
+ dk-t2db -c "#" mem::db.dat
+
+* Process text input file db.in, create Berkeley DB file bdb.dat:
+ dk-t2db -c "#" db.in bdb::bdb.dat
+
+* Process text input file db.in, modify existing NDBM database ndbm.dat:
+ dk-t2db -a -c "#" db.in ndbm::ndbm.dat
+
+PREFERENCES
+
+line.size Input line buffer size
+
+text-db.key.max-size Key buffer size
+
+text-db.value.max-size Value buffer size
+
+FILES
+
+Input files are text files. Each text line specifies one record.
+The first word in a line (first sequence of non-whitespace characters) is
+the key text. All further text started by the second word until the
+line end is used as value.
+
+The key can not contain spaces, the value can contain spaces.
+
+A line containing just a key but no value results in deletion of the
+specified record.
+
+RESTRICTIONS
+
+On Windows the file name length is restricted to _MAX_PATH (260) characters
+if the file name contains a wildcard (* or ? character).
+
+Wildcards can not be used to specify the database file name.
+
+AUTHOR
+
+Dirk Krause
+
+HISTORY
+
+In previous DK tools versions the functionality was provided by the
+``dkdbt make'' command.
+
+COPYRIGHT AND LICENSE
+
+Run
+ dk-t2db --license
+to see license information.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/en/dk-t2h.txt b/support/dktools/dktools/en/dk-t2h.txt
new file mode 100644
index 0000000000..db23c6e641
--- /dev/null
+++ b/support/dktools/dktools/en/dk-t2h.txt
@@ -0,0 +1,61 @@
+
+NAME
+
+dk-t2h - Text to HTML converter
+
+SYNOPSIS
+
+dk-t2h [<options>] [<file(s)>]
+
+DESCRIPTION
+
+The program converts text from the specified files or standard input
+to HTML. Alternatively you can use the -e option to convert text specified
+on the command line.
+
+OPTIONS
+
+-i <string> Input encoding, one from:
+--input-encoding=<string> ``ascii'' (use this for ISO-LATIN-1 too),
+ ``ansi'', ``utf-8'',
+ ``utf-16'', ``utf-16-le'', ``utf-16-be'',
+ ``c32'', ``c32-le'', or ``c32-be''.
+
+-l Wrap all lines into
+--code-lines ``<code title="001">...</code>''.
+
+-e Convert the command line arguments, do
+--echo not treat them as file names.
+
+-f Produce a full HTML file, not just a
+--full fragment.
+ Options -e and -f are mutually exclusive.
+
+-t <string> Title for full HTML file, ignored if
+--title=<string> the -f option is not present.
+
+--verbose Show error message on interrupt by SIGPIPE.
+
+EXIT STATUS
+
+0 on success, all other values indicate errors.
+
+RESTRICTIONS
+
+On Windows the file name length is restricted to _MAX_PATH (260) characters
+if the file name contains a wildcard (* or ? character).
+
+AUTHOR
+
+Dirk Krause
+
+COPYRIGHT AND LICENSE
+
+Run
+ dk-t2h --license
+to see license information.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/en/dk-t2l.txt b/support/dktools/dktools/en/dk-t2l.txt
new file mode 100644
index 0000000000..b0868c1202
--- /dev/null
+++ b/support/dktools/dktools/en/dk-t2l.txt
@@ -0,0 +1,114 @@
+
+NAME
+
+dk-t2l - Text to LaTeX converter
+
+SYNOPSIS
+
+dk-t2l [<options>] [<file(s)>]
+
+DESCRIPTION
+
+The program converts text from the specified files or standard input
+to LaTeX. Alternatively you can use the -e option to convert text specified
+on the command line.
+
+OPTIONS
+
+-i <string> Input encoding, one from:
+--input-encoding=<string> ``ascii'' (use this for ISO-LATIN-1 too),
+ ``ansi'', ``utf-8'',
+ ``utf-16'', ``utf-16-le'', ``utf-16-be'',
+ ``c32'', ``c32-le'', or ``c32-be''.
+
+-e Convert the command line arguments, do
+--echo not treat them as file names.
+
+-n Command line arguments are characters
+--numeric given as decimal numbers.
+
+-h Command line arguments are characters
+--hex given as hexadecimal numbers.
+
+-r Write usable font encodings and recommended
+--recommendations LaTeX packages list.
+
+-l Write \\ sequence before newline
+--line-feed (default is to simply write the newline).
+
+-t Write \HT{} for tabulators
+--tabulator (default is to write a space).
+
+--verbose Show error message on interrupt by SIGPIPE.
+
+EXIT STATUS
+
+0 on success, all other values indicate errors.
+
+FILES
+
+The program uses translation tables in *.t2l files to convert from UNICODE
+to LaTeX. Typically the files are stored in the ${datadir}/dktools/charmap
+directory.
+The files consist of empty lines, comment lines, and data lines.
+A comment line is started by a raute character `#' as first text character.
+A data line consists of several texts, separated by whitespaces or
+whitespace sequences. It contains the following components:
+- Hexadecimal character value (required).
+ The UNICODE standard uses 24 (newer versions) or 32 bits (older versions)
+ for characters.
+ The character value in a data line must be in the range 0...FFFFFFFF.
+- b=<string> (optional)
+ A LaTeX sequence that can be used in both math mode and non-math mode
+ for the character.
+- t=<string> (optional)
+ A LaTeX sequence that can be used in text mode (non-math mode) for the
+ character.
+- m=<string> (optional)
+ A LaTeX sequence that can be used in math mode for the characters.
+NOTE: At least one from b=..., t=..., m=... is required!
+- e=<string> (optional)
+ Information about font encodings.
+ You can either specify the font encodings usable in a comma-separated list
+ (``ot1'', ``t1'', ``t4'', ``t5''), i.e. ``t1,ot1'' or use an exclamation
+ mark to specify a list of denied encoding, i.e. ``!t4,t5''.
+- p=<string> (optional)
+ Information about LaTeX packages required.
+
+RESTRICTIONS
+
+On Windows the file name length is restricted to _MAX_PATH (260) characters
+if the file name contains a wildcard (* or ? character).
+
+The program uses translation tables in *.t2l files to convert from UNICODE
+to LaTeX. UNICODE contains 1,114,112 characters (wikipedia article, 2015-05-12),
+so I can not
+provide complete tables for all characters.
+As I am a native German speaker, the tables include support for some
+Central European languages.
+
+CONTRIBUTIONS
+
+You can provide further translation tables from UNICODE to LaTeX,
+please use the SourceForge project page
+http://sourceforge.net/projects/dktools
+to contact me (forums, patches).
+I can only accept your work if you use a 3 clauses BSD license.
+I think translation tables should be made by native speakers of a language
+(or at least people experienced in the language) with at least some
+LaTeX experience.
+
+AUTHOR
+
+Dirk Krause
+
+COPYRIGHT AND LICENSE
+
+Run
+ dk-t2l --license
+to see license information.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/en/dk-uid.txt b/support/dktools/dktools/en/dk-uid.txt
new file mode 100644
index 0000000000..fdb0b2c950
--- /dev/null
+++ b/support/dktools/dktools/en/dk-uid.txt
@@ -0,0 +1,38 @@
+
+NAME
+
+dk-uid - Find free user ID
+
+SYNOPSIS
+
+dk-uid <min> <max>
+
+DESCRIPTION
+
+The program searches for the first free UID in a given range and
+writes the number to standard output.
+
+ARGUMENTS
+
+<min> Minimum UID number.
+
+<max> Maximum UID number.
+
+EXIT STATUS
+
+0 on success, all other values indicate errors.
+
+AUTHOR
+
+Dirk Krause
+
+COPYRIGHT AND LICENSE
+
+Run
+ dk-uid --license
+to see license information.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/en/dk4info.txt b/support/dktools/dktools/en/dk4info.txt
new file mode 100644
index 0000000000..d56e3458cb
--- /dev/null
+++ b/support/dktools/dktools/en/dk4info.txt
@@ -0,0 +1,40 @@
+
+NAME
+
+dk4info - Information about directories and features
+
+SYNOPSIS
+
+dk4info [-l]
+
+DESCRIPTION
+
+The program shows the directories currently used and the directories
+configured during build process.
+Option -l additionally prints the compiler constants created by the
+configure script.
+
+OPTIONS
+
+-l Show compiler constants.
+
+EXIT STATUS
+
+0 on success, all other values indicate errors.
+
+AUTHOR
+
+Dirk Krause
+
+HISTORY
+
+COPYRIGHT AND LICENSE
+
+Run
+ dk4info --license
+to see license information.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/en/lprngcl.txt b/support/dktools/dktools/en/lprngcl.txt
new file mode 100644
index 0000000000..1b1bdd426f
--- /dev/null
+++ b/support/dktools/dktools/en/lprngcl.txt
@@ -0,0 +1,69 @@
+
+NAME
+
+ lprngcl - Clean LPRng print queues
+
+SYNOPSIS
+
+ lprngcl [-a] [-v] [-t <seconds> [<queue(s)>]
+ lprngcl [--help] [--version] [--license] [--manual]
+
+DESCRIPTION
+
+The lprng program deletes all print jobs submitted by the current user from
+the specified LPD/LPRng print queues.
+It is intended to be used in PC classrooms in schools or universities.
+If a user logs off from a computer, he will leave the room so we should skip
+her/his print jobs still in the queue.
+
+OPTIONS
+
+-a
+--ascii
+ The LPRng host uses ASCII encoding. Default: UTF-8.
+
+-t seconds
+--timeout=seconds
+ Timeout for network operations.
+
+
+-v
+--verbose
+ Produce verbose output, show the LPRng servers response.
+
+--help
+ Show short help text.
+
+--version
+ Show version information.
+
+--license
+ Show license terms.
+
+--manual
+ Show (this) longer help text.
+
+EXIT STATUS
+
+0 on success, all other values indicate errors.
+
+NOTES
+
+In version 4.3.0 and above lprngcl does not longer use a dk3print.conf file.
+There is no default host and no default queue, so all queues to clean up
+must be specified on the command line in queue@host notation.
+
+AUTHOR
+
+Dirk Krause
+
+COPYRIGHT AND LICENSE
+
+Run
+ lprngcl --license
+to see license information.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/en/x.txt b/support/dktools/dktools/en/x.txt
new file mode 100644
index 0000000000..ad8d98811b
--- /dev/null
+++ b/support/dktools/dktools/en/x.txt
@@ -0,0 +1,47 @@
+
+NAME
+
+SYNOPSIS
+
+DESCRIPTION
+
+OPTIONS
+
+EXIT STATUS
+
+0 on success, all other values indicate errors.
+
+ERRORS
+
+DIAGNOSTICS
+
+EXAMPLES
+
+ENVIRONMENT
+
+FILES
+
+CAVEATS
+
+BUGS
+
+RESTRICTIONS
+
+NOTES
+
+AUTHOR
+
+Dirk Krause
+
+HISTORY
+
+COPYRIGHT AND LICENSE
+
+Run
+ XXXXX --license
+to see license information.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
diff --git a/support/dktools/dktools/htmlbook/GNUmakefile b/support/dktools/dktools/htmlbook/GNUmakefile
new file mode 100644
index 0000000000..42e7d04a7a
--- /dev/null
+++ b/support/dktools/dktools/htmlbook/GNUmakefile
@@ -0,0 +1,145 @@
+#
+# CONFIGURATION:
+# Set language here.
+# If your LANG environment variable ends on ``.UTF-8'' or ``.utf8''
+# you have to use the same suffix here.
+#
+ifndef LANG
+LANG=en_US.utf8
+endif
+
+#
+# CONFIGURATION:
+# How to run the htmlbook program?
+#
+ifndef HTMLBOOK
+HTMLBOOK=htmlbook
+endif
+
+ifndef GXHCONVERT
+GXHCONVERT=LANG=C gxhconvert
+endif
+
+#
+# CONFIGURATION:
+# Resolution when converting from vector to bitmaps.
+# Higher values create larger images.
+#
+ifndef FIGPNGRES
+FIGPNGRES=96
+endif
+
+#
+# If one of the *.prj, *.hbt or *.txt files was modified,
+# we have to rebuild all.
+#
+TEXTFILES := $(wildcard *.txt)
+HBTFILES := $(wildcard *.hbt)
+PRJFILES := $(wildcard *.prj)
+
+#
+# All *.fig images, *.gp plots and *.tex files (formulas) are
+# converted to *.png, *.pdf and *.svg.
+#
+IMAGES := \
+ $(patsubst %.fig,%.png,$(wildcard *.fig)) \
+ $(patsubst %.fig,%.pdf,$(wildcard *.fig)) \
+ $(patsubst %.fig,%.svg,$(wildcard *.fig)) \
+ $(patsubst %.gp,%.png,$(wildcard *.gp)) \
+ $(patsubst %.gp,%.pdf,$(wildcard *.gp)) \
+ $(patsubst %.gp,%.svg,$(wildcard *.gp)) \
+ $(patsubst %.tex,%.png,$(wildcard *.tex)) \
+ $(patsubst %.tex,%.pdf,$(wildcard *.tex)) \
+ $(patsubst %.tex,%.svg,$(wildcard *.tex))
+
+#
+# Suffixes for graphics files
+#
+.SUFFIXES: .png .svg .pdf .tex .fig .gp
+
+#
+# Graphics conversion rules
+#
+.tex.pdf:
+ gxhconvert -o=pdf $<
+
+.fig.pdf:
+ gxhconvert -o=pdf $<
+
+.gp.pdf:
+ gxhconvert -o=pdf $<
+
+.pdf.svg:
+ gxhconvert -o=svg $<
+
+#
+# CONFIGURATION:
+# If you do not need transparency, remove the -a option from the
+# gxhconvert command below.
+#
+.svg.png:
+ gxhconvert -o=png -r=$(FIGPNGRES) -a $<
+ optipng -q -i1 -zc1-9 -zm1-9 -zs0-3 -f0-5 $@
+
+#
+# Names of icon files
+#
+ICONS= home.png toc.png prev.png next.png index.png
+
+#
+# The first target is the default target.
+#
+install: # Create HTML page set for local viewing and install
+install: $(TEXTFILES) $(HBTFILES) $(PRJFILES) $(IMAGES)
+ -[ ! -f htmlbook.sh ] || rm -f htmlbook.sh
+ LANG=$(LANG) $(HTMLBOOK) index.prj
+ chmod 755 htmlbook.sh
+ ./htmlbook.sh
+
+webinstall: # Create HTML page set for web server and install
+webinstall: $(TEXTFILES) $(HBTFILES) $(PRJFILES) $(IMAGES) $(ICONS)
+ -[ ! -f htmlbook.sh ] || rm -f htmlbook.sh
+ LANG=$(LANG) $(HTMLBOOK) -o web index.prj
+ chmod 755 htmlbook.sh
+ ./htmlbook.sh
+
+chminstall: # Create HTML page set for CHM file building
+chminstall: $(TEXTFILES) $(HBTFILES) $(PRJFILES) $(IMAGES)
+ -[ ! -f htmlbook.sh ] || rm -f htmlbook.sh
+ LANG=$(LANG) $(HTMLBOOK) -o chm index.prj
+ chmod 755 htmlbook.sh
+ ./htmlbook.sh
+
+#
+# Icons
+#
+
+home.png: # Icon to return to homepage
+home.png: home.fig
+ gxhconvert -o=png -r=36 -a $<
+ optipng -q -i1 -zc1-9 -zm1-9 -zs0-3 -f0-5 $@
+
+toc.png: # Icon for table of contents
+toc.png: toc.fig
+ gxhconvert -o=png -r=36 -a $<
+ optipng -q -i1 -zc1-9 -zm1-9 -zs0-3 -f0-5 $@
+
+prev.png: # Icon to go back to previous page
+prev.png: prev.fig
+ gxhconvert -o=png -r=36 -a $<
+ optipng -q -i1 -zc1-9 -zm1-9 -zs0-3 -f0-5 $@
+
+next.png: # Icon to go forward to next page
+next.png: next.fig
+ gxhconvert -o=png -r=36 -a $<
+ optipng -q -i1 -zc1-9 -zm1-9 -zs0-3 -f0-5 $@
+
+index.png: # Icon to go to keyword index
+index.png: index.fig
+ gxhconvert -o=png -r=36 -a $<
+ optipng -q -i1 -zc1-9 -zm1-9 -zs0-3 -f0-5 $@
+
+help: # Show targets in GNUmakefile
+ @echo 'Here is a list of the targets in this GNUmakefile:'
+ -@egrep '^[^:;= ]*::?[ ]*' GNUmakefile|grep '#'|grep -v '^#'
+
diff --git a/support/dktools/dktools/htmlbook/chm.hbt b/support/dktools/dktools/htmlbook/chm.hbt
new file mode 100644
index 0000000000..cbdd3b2108
--- /dev/null
+++ b/support/dktools/dktools/htmlbook/chm.hbt
@@ -0,0 +1 @@
+<div>%%contents%%</div>
diff --git a/support/dktools/dktools/htmlbook/home.fig b/support/dktools/dktools/htmlbook/home.fig
new file mode 100644
index 0000000000..25372f1f55
--- /dev/null
+++ b/support/dktools/dktools/htmlbook/home.fig
@@ -0,0 +1,22 @@
+#FIG 3.2
+Portrait
+Center
+Inches
+A4
+100.0
+Single
+-2
+1200 2
+0 32 #364e6d
+2 2 0 0 7 7 999 1 -1 1.00 0 0 0 0 0 5
+ 0 0 1200 0 1200 1200 0 1200 0 0
+2 4 0 0 0 0 105 1 5 0 0 0 19 0 0 5
+ 150 150 1125 150 1125 1125 150 1125 150 150
+2 4 0 0 0 0 104 1 10 0 0 0 19 0 0 5
+ 112 112 1087 112 1087 1087 112 1087 112 112
+2 4 0 0 4 4 103 1 20 0 0 0 16 0 0 5
+ 75 75 1050 75 1050 1050 75 1050 75 75
+2 4 0 0 6 6 102 1 20 0 0 0 16 0 0 5
+ 150 150 975 150 975 975 150 975 150 150
+2 3 0 0 4 4 100 1 20 0 0 0 12 0 0 4
+ 225 787 900 787 562 300 225 787
diff --git a/support/dktools/dktools/htmlbook/home.png b/support/dktools/dktools/htmlbook/home.png
new file mode 100644
index 0000000000..e368b62492
--- /dev/null
+++ b/support/dktools/dktools/htmlbook/home.png
Binary files differ
diff --git a/support/dktools/dktools/htmlbook/index.fig b/support/dktools/dktools/htmlbook/index.fig
new file mode 100644
index 0000000000..3d776a5db2
--- /dev/null
+++ b/support/dktools/dktools/htmlbook/index.fig
@@ -0,0 +1,24 @@
+#FIG 3.2
+Portrait
+Center
+Inches
+A4
+100.0
+Single
+-2
+1200 2
+0 32 #364e6d
+2 2 0 0 7 7 999 1 -1 1.00 0 0 0 0 0 5
+ 0 0 1200 0 1200 1200 0 1200 0 0
+2 4 0 0 0 0 105 1 5 0 0 0 19 0 0 5
+ 150 150 1125 150 1125 1125 150 1125 150 150
+2 4 0 0 0 0 104 1 10 0 0 0 19 0 0 5
+ 112 112 1087 112 1087 1087 112 1087 112 112
+2 4 0 0 4 4 103 1 20 0 0 0 16 0 0 5
+ 75 75 1050 75 1050 1050 75 1050 75 75
+2 4 0 0 6 6 102 1 20 0 0 0 16 0 0 5
+ 150 150 975 150 975 975 150 975 150 150
+1 1 0 0 0 0 100 1 20 0 1 0.0 524 524 318 319 206 205 842 843
+2 1 0 5 0 0 100 1 -1 0 0 0 12 0 0 2
+ 881 881 731 731
+1 1 0 0 7 7 99 1 20 0 1 0.0 525 525 262 262 263 263 787 787
diff --git a/support/dktools/dktools/htmlbook/index.png b/support/dktools/dktools/htmlbook/index.png
new file mode 100644
index 0000000000..6eb43e21de
--- /dev/null
+++ b/support/dktools/dktools/htmlbook/index.png
Binary files differ
diff --git a/support/dktools/dktools/htmlbook/index.prj b/support/dktools/dktools/htmlbook/index.prj
new file mode 100644
index 0000000000..7e5144e4da
--- /dev/null
+++ b/support/dktools/dktools/htmlbook/index.prj
@@ -0,0 +1,186 @@
+[options]
+
+# ##### START OF REQUIRED SETTINGS
+#
+#
+
+# Destination directory for our book release.
+# DO NOT USE THE CURRENT DIRECTORY OR
+# ANY DIRECTORY CONTAINING DATA!
+# The output script removes the directory completely,
+# creates the directory again and fills it with data.
+# Any existing data in this directory will be lost!
+# ---------------------------------------------------
+output directory = /home/joe/work/test-html
+
+# Book title.
+# -----------
+title = Introduction to something
+
+# URL where to publish the book.
+# ------------------------------
+url = http://www.my-server.org/something
+
+# Impressum included in contents.
+# Alternatively you could use "impressum page".
+# ---------------------------------------------
+impressum link = http://www.my-server.org/impressum.html
+# impressum page = impressum.txt
+
+# Authors name.
+# May be changed per node.
+# ------------------------
+author = Me, myself and I
+
+# Location where the book is produced.
+# May be changed per node.
+# ------------------------------------
+location = Somewhere
+
+#
+#
+# ##### END OF REQUIRED SETTINGS
+
+
+
+# Output character set, us-ascii or utf-8.
+# May be changed per node.
+# ----------------------------------------
+html charset = utf-8
+
+# Template used for all output files.
+# May be changed per node.
+# -----------------------------------
+template = web.hbt
+
+# Style used for all output files.
+# You may want to modify the stylesheet for a
+# color scheme corresponding to your corporate
+# identity colors.
+# May be changed per node.
+# --------------------------------------------
+style = style.css
+
+# Enable/disable page-internal table of contents.
+# May be changed per node.
+# -----------------------------------------------
+page toc = no
+
+# File used to build the index.html start page.
+# ---------------------------------------------
+index file = index.txt
+
+# Enable/disable clickable keywords index kw.html.
+# ------------------------------------------------
+create index = no
+
+# Enable/disable conversion of ampersands.
+# May be changed per node.
+# ----------------------------------------
+replace ampersand = no
+
+# Enable/disable use of tidy for inspection/correction.
+# May be changed per node.
+# -----------------------------------------------------
+tidy = yes
+
+# Enable/disable use of ln instead of cp (reduces
+# disk space consumption).
+# May be changed per node.
+# -----------------------------------------------
+ln = yes
+
+# Enable/disable position text on top of page.
+# May be changed per node.
+# --------------------------------------------
+write position = yes
+
+# Switch navigation between "icons", "text", "both".
+# This option was intended originally, but skipped.
+# --------------------------------------------------
+# navigation = icons
+
+# Shortcut icon.
+# May be changed per node.
+# -------------------------------------------
+shortcut icon = favicon.ico
+
+# Enable/disable HTML for CHM (othewise HTML for web).
+# ----------------------------------------------------
+chm = no
+
+# Output script name.
+# Run the script after running the htmlbook program.
+# --------------------------------------------------
+output script = htmlbook.sh
+
+# Enable/disable line numbers for code from sourcefile
+# and code special commands.
+# ----------------------------------------------------
+code line numbers = yes
+
+# Option for CHM production, activated by
+# "htmlbook -o chm index.prj", overwrites some
+# existing settings.
+# You can have multiple such settings, activate them
+# by "htmlbook -o chm,this,that,another index.prj"
+# --------------------------------------------------
+[options:chm]
+chm = yes
+template = chm.hbt
+code line numbers = no
+# The language setting for the CHM project, default is
+# 0x409 English (USA)
+# Should correspond to the LANG setting in Makefile/GNUmakefile.
+#
+# chm language = 0x407 Deutsch (Deutschland)
+#
+
+# Similar optional section for web publishing.
+# --------------------------------------------
+[options:web]
+chm = no
+template = web.hbt
+
+# Optional section, activated automatically on
+# Windows systems (no need for "-o windows").
+# A similar section on non-Windows systems would be
+# [options:non-windows]
+# -------------------------------------------------
+[options:windows]
+output script = htmlbook.cmd
+
+
+
+# Additional files to copy
+# ------------------------
+[files]
+example1.c
+
+
+
+# Book contents, structed by indent level of
+# node title lines.
+# ------------------------------------------
+[contents]
+Something
+ Install something on Linux/Unix
+ @short = Installation Linux/Unix
+ @file = installu.txt
+ Installation from source
+ @short = Source installation
+ @file = instalus.txt
+ Installation using program X
+ @short = Installation using X
+ @file = instalux.txt
+ Install something on Windows
+ @short = Windows installation
+ @file = installw.txt
+Start something
+ Start something on Linux/Unix
+ @short = Linux start
+ @file = startu.txt
+ Start something on Windows
+ @short = Windows start
+ @file = startw.txt
+
diff --git a/support/dktools/dktools/htmlbook/math-img.tex b/support/dktools/dktools/htmlbook/math-img.tex
new file mode 100644
index 0000000000..cb63f512fc
--- /dev/null
+++ b/support/dktools/dktools/htmlbook/math-img.tex
@@ -0,0 +1,34 @@
+\documentclass[12pt]{article}
+% begin font setup
+\usepackage[T1]{fontenc}
+\usepackage{mathptmx}
+\usepackage[scaled=.92]{helvet}
+\usepackage{courier}
+% end font setup
+% begin other packages
+\usepackage{textcomp}
+\usepackage[intlimits]{amsmath}
+% end other packages
+\usepackage{color}
+\setlength{\paperwidth}{20cm}
+\setlength{\paperheight}{20cm}
+\pagestyle{empty}
+\setlength{\voffset}{-0.9in}
+\setlength{\topmargin}{0bp}
+\setlength{\headheight}{0bp}
+\setlength{\headsep}{0bp}
+\setlength{\topskip}{0bp}
+\setlength{\hoffset}{-0.9in}
+\setlength{\oddsidemargin}{0bp}
+\setlength{\evensidemargin}{0bp}
+\setlength{\marginparwidth}{0bp}
+\setlength{\marginparsep}{0bp}
+\setlength{\textwidth}{\paperwidth}
+\setlength{\textheight}{\paperheight}
+\setlength{\parskip}{0bp}
+\setlength{\parindent}{0bp}
+\setlength{\pdfpagewidth}{\paperwidth}
+\setlength{\pdfpageheight}{\paperheight}
+\begin{document}% FORMULA GOES INTO NEXT LINE, REPLACE EXISTING ONE
+\(a^2+b^2=c^2\)
+\end{document}
diff --git a/support/dktools/dktools/htmlbook/next.fig b/support/dktools/dktools/htmlbook/next.fig
new file mode 100644
index 0000000000..b19114a8f9
--- /dev/null
+++ b/support/dktools/dktools/htmlbook/next.fig
@@ -0,0 +1,22 @@
+#FIG 3.2
+Portrait
+Center
+Inches
+A4
+100.0
+Single
+-2
+1200 2
+0 32 #364e6d
+2 2 0 0 7 7 999 1 -1 1.00 0 0 0 0 0 5
+ 0 0 1200 0 1200 1200 0 1200 0 0
+2 4 0 0 0 0 105 1 5 0 0 0 19 0 0 5
+ 150 150 1125 150 1125 1125 150 1125 150 150
+2 4 0 0 0 0 104 1 10 0 0 0 19 0 0 5
+ 112 112 1087 112 1087 1087 112 1087 112 112
+2 4 0 0 4 4 103 1 20 0 0 0 16 0 0 5
+ 75 75 1050 75 1050 1050 75 1050 75 75
+2 4 0 0 6 6 102 1 20 0 0 0 16 0 0 5
+ 150 150 975 150 975 975 150 975 150 150
+2 3 0 0 4 4 100 1 20 0 0 0 12 0 0 4
+ 338 225 338 900 825 562 338 225
diff --git a/support/dktools/dktools/htmlbook/next.png b/support/dktools/dktools/htmlbook/next.png
new file mode 100644
index 0000000000..c02bdaead9
--- /dev/null
+++ b/support/dktools/dktools/htmlbook/next.png
Binary files differ
diff --git a/support/dktools/dktools/htmlbook/prev.fig b/support/dktools/dktools/htmlbook/prev.fig
new file mode 100644
index 0000000000..6a1b4c467a
--- /dev/null
+++ b/support/dktools/dktools/htmlbook/prev.fig
@@ -0,0 +1,22 @@
+#FIG 3.2
+Portrait
+Center
+Inches
+A4
+100.0
+Single
+-2
+1200 2
+0 32 #364e6d
+2 2 0 0 7 7 999 1 -1 1.00 0 0 0 0 0 5
+ 0 0 1200 0 1200 1200 0 1200 0 0
+2 4 0 0 0 0 105 1 5 0 0 0 19 0 0 5
+ 150 150 1125 150 1125 1125 150 1125 150 150
+2 4 0 0 0 0 104 1 10 0 0 0 19 0 0 5
+ 112 112 1087 112 1087 1087 112 1087 112 112
+2 4 0 0 4 4 103 1 20 0 0 0 16 0 0 5
+ 75 75 1050 75 1050 1050 75 1050 75 75
+2 4 0 0 6 6 102 1 20 0 0 0 16 0 0 5
+ 150 150 975 150 975 975 150 975 150 150
+2 3 0 0 4 4 100 1 20 0 0 0 12 0 0 4
+ 787 225 787 900 300 562 787 225
diff --git a/support/dktools/dktools/htmlbook/prev.png b/support/dktools/dktools/htmlbook/prev.png
new file mode 100644
index 0000000000..2d41c5ec3f
--- /dev/null
+++ b/support/dktools/dktools/htmlbook/prev.png
Binary files differ
diff --git a/support/dktools/dktools/htmlbook/style.css b/support/dktools/dktools/htmlbook/style.css
new file mode 100644
index 0000000000..4df8742182
--- /dev/null
+++ b/support/dktools/dktools/htmlbook/style.css
@@ -0,0 +1,1295 @@
+@media screen {
+ /* General formats.
+ */
+ body {
+ background-color: white;
+ }
+ h1 {
+ font-size: 200%;
+ font-weight: bold;
+ }
+ h2 {
+ font-size: 180%;
+ font-weight: bold;
+ }
+ h3 {
+ font-size: 160%;
+ font-weight: bold;
+ }
+ h4 {
+ font-size: 140%;
+ font-weight: bold;
+ }
+ h5 {
+ font-size: 120%;
+ font-weight: bold;
+ }
+ h6 {
+ font-size: 100%;
+ font-weight: bold;
+ }
+ span.hint {
+ cursor: help;
+ border-bottom: 1px dotted;
+ }
+ pre {
+ background-color: #FFFFE8;
+ border-width: 1px;
+ border-style: solid;
+ border-color: black;
+ padding-top: 0.5em;
+ padding-left: 2em;
+ padding-right: 2em;
+ padding-bottom: 0.5em;
+ margin-top: 0.5em;
+ margin-left: 2em;
+ margin-right: 2em;
+ margin-bottom: 0.5em;
+ overflow: auto;
+ }
+ pre > i {
+ font-family: inherit;
+ font-style: italic;
+ }
+ pre code:before {
+ content: attr(title)':\20';
+ font-weight: bold;
+ color: #999999;
+ }
+ pre:hover code:before {
+ content: '\20\20\20\20\20';
+ }
+ /* Classes from the template
+ */
+ div.header {
+ margin: 5px;
+ }
+ div.headerleft {
+ float: left;
+ text-align: left;
+ }
+ div.headercenter {
+ text-align: center;
+ }
+ span.title {
+ font-size: 200%;
+ }
+ div.headerright {
+ float: right;
+ text-align: right;
+ }
+ div.navicon {
+ clear: both;
+ margin: 5px;
+ }
+ div.naviheader {
+ background-color: yellow;
+ text-align: center;
+ }
+ div.contents {
+ margin-top: 1em;
+ margin-bottom: 1em;
+ }
+ div.footer {
+ clear: both;
+ background-color: yellow;
+ border: 1px silver;
+ margin: 5px;
+ padding-left: 0.5em;
+ padding-right: 0.5em;
+ padding-top: 0.12em;
+ padding-bottom: 0.12em;
+ }
+ div.footerleft {
+ float: left;
+ text-align: left;
+ }
+ div.footercenter {
+ text-align: center;
+ }
+ div.footerright {
+ float: right;
+ text-align: right;
+ }
+ /* Classes produced by htmlbook
+ */
+ div.hb_nm_div {
+ float: right;
+ width: 23em;
+ background-color: yellow;
+ margin-left: 2em;
+ margin-bottom: 1em;
+ }
+ ul.hb_nm_ul {
+ margin-top: 1em;
+ margin-bottom: 1em;
+ }
+ li.hb_nm_li {
+ list-style: none;
+ }
+ a.hb_nm_a:link {
+ color: red;
+ text-decoration: none;
+ }
+ a.hb_nm_a:visited {
+ color: red;
+ text-decoration: none;
+ }
+ a.hb_nm_a:hover {
+ color: red;
+ text-decoration: underline;
+ }
+ a.hb_nm_a:focus {
+ color: red;
+ text-decoration: underline;
+ }
+ a.hb_nm_a_parent:link {
+ color: red;
+ font-weight: bold;
+ text-decoration: none;
+ }
+ a.hb_nm_a_parent:visited {
+ color: red;
+ font-weight: bold;
+ text-decoration: none;
+ }
+ a.hb_nm_a_parent:hover {
+ color: red;
+ font-weight: bold;
+ text-decoration: underline;
+ }
+ a.hb_nm_a_parent:focus {
+ color: red;
+ font-weight: bold;
+ text-decoration: underline;
+ }
+ li.hb_nm_c {
+ list-style: none;
+ color: red;
+ font-weight: bold;
+ }
+ li.hb_nm_sep {
+ list-style: none;
+ }
+ div.hb_navigation {
+ margin-top: 1em;
+ margin-bottom: 1em;
+ }
+ a.hb_navi_a {
+ }
+ img.hb_navi_img {
+ }
+ div.hb_pos_div {
+ }
+ table.hb_pos_ta {
+ }
+ tr.hb_pos_tr {
+ }
+ td.hb_pos_td_arrow {
+ font-family: sans-serif;
+ font-size: 75%;
+ text-align: center;
+ vertical-align: top;
+ }
+ td.hb_pos_td_text {
+ font-family: sans-serif;
+ font-size: 75%;
+ text-align: left;
+ vertical-align: top;
+ }
+ div.contents_from_text {
+ }
+ span.hb_link_number {
+ display: none;
+ }
+ table.hb_img_ta {
+ }
+ tr.hb_img_tr {
+ }
+ td.hb_img_td_img {
+ vertical-align: top;
+ text-align: center;
+ }
+ td.hb_img_td_empty {
+ width: 5ex;
+ }
+ td.hb_img_td_a {
+ vertical-align: top;
+ text-align: left;
+ }
+ a.hb_img_a_larger {
+ font-family: sans-serif;
+ font-size: 75%;
+ color: green;
+ text-decoration: none;
+ }
+ a.hb_img_a_larger:link {
+ font-family: sans-serif;
+ font-size: 75%;
+ color: green;
+ text-decoration: none;
+ }
+ a.hb_img_a_larger:visited {
+ font-family: sans-serif;
+ font-size: 75%;
+ color: green;
+ text-decoration: none;
+ }
+ a.hb_img_a_larger:hover {
+ font-family: sans-serif;
+ font-size: 75%;
+ color: green;
+ text-decoration: underline;
+ }
+ a.hb_img_a_larger:focus {
+ font-family: sans-serif;
+ font-size: 75%;
+ color: green;
+ text-decoration: underline;
+ }
+ a.hb_a_i:link {
+ color: green;
+ text-decoration: none;
+ }
+ a.hb_a_i:visited {
+ color: green;
+ text-decoration: none;
+ }
+ a.hb_a_i:focus {
+ color: green;
+ text-decoration: underline;
+ }
+ a.hb_a_i:hover {
+ color: green;
+ text-decoration: underline;
+ }
+ a.hb_a_e {
+ }
+ table.hb_me_ta {
+ background-color: silver;
+ }
+ tr.hb_me_tr {
+ }
+ td.hb_me_td_text {
+ font-family: sans-serif;
+ text-align: left;
+ vertical-align: top;
+ }
+ td.hb_me_td_arrow {
+ font-family: sans-serif;
+ text-align: center;
+ vertical-align: top;
+ }
+ table.hb_ptoc_ta {
+ }
+ tr.hb_ptoc_tr {
+ }
+ td.hb_ptoc_td_empty {
+ width: 3ex;
+ }
+ td.hb_ptoc_td_data {
+ font-family: sans-serif;
+ font-size: 75%;
+ text-align: left;
+ vertical-align: top;
+ }
+ a.hb_ptoc_a:link {
+ color: green;
+ text-decoration: none;
+ }
+ a.hb_ptoc_a:visited {
+ color: green;
+ text-decoration: none;
+ }
+ a.hb_ptoc_a:focus {
+ color: green;
+ text-decoration: underline;
+ }
+ a.hb_ptoc_a:hover {
+ color: green;
+ text-decoration: underline;
+ }
+ div.hb_link_div {
+ display: none;
+ }
+ table.hb_link_ta {
+ }
+ td.hb_link_td_number {
+ text-align: center;
+ vertical-align: top;
+ }
+ td.hb_link_td_url {
+ text-align: left;
+ vertical-align: top;
+ }
+ div.hb_dtoc_div {
+ }
+ table.hb_dtoc_ta {
+ }
+ tr.hb_dtoc_tr {
+ }
+ td.hb_dtoc_td_space {
+ }
+ td.hb_dtoc_td_entry {
+ font-family: sans-serif;
+ font-size: 75%;
+ }
+ a.hb_dtoc_a:link {
+ color: green;
+ text-decoration: none;
+ }
+ a.hb_dtoc_a:visited {
+ color: green;
+ text-decoration: none;
+ }
+ a.hb_dtoc_a:focus {
+ color: green;
+ text-decoration: underline;
+ }
+ a.hb_dtoc_a:hover {
+ color: green;
+ text-decoration: underline;
+ }
+ div.hb_ki_div {
+ }
+ h2.hb_ki_h2 {
+ }
+ dl.hb_ki_dl {
+ }
+ dt.hb_ki_dt {
+ font-weight: bold;
+ }
+ dd.hb_ki_dd {
+ }
+ ul.hb_ki_ul {
+ }
+ li.hb_ki_li {
+ list-style: none;
+ font-family: sans-serif;
+ font-size: 75%;
+ }
+ a.hb_ki_a:link {
+ color: green;
+ text-decoration: none;
+ }
+ a.hb_ki_a:visited {
+ color: green;
+ text-decoration: none;
+ }
+ a.hb_ki_a:focus {
+ color: green;
+ text-decoration: underline;
+ }
+ a.hb_ki_a:hover {
+ color: green;
+ text-decoration: underline;
+ }
+ div.hb_file_div {
+ background-color: #FFFFE8;
+ border-width: 1px;
+ border-style: solid;
+ border-color: black;
+ padding-top: 0.5em;
+ padding-left: 2em;
+ padding-right: 2em;
+ padding-bottom: 0.5em;
+ margin-top: 0.5em;
+ margin-left: 2em;
+ margin-right: 2em;
+ margin-bottom: 0.5em;
+ }
+ div.hb_file_div pre {
+ border-style: none;
+ padding-top: 0.5em;
+ padding-left: 0px;
+ padding-right: 0px;
+ padding-bottom: 0px;
+ margin-top: 0px;
+ margin-left: 0px;
+ margin-right: 0px;
+ margin-bottom: 0px;
+ overflow: auto;
+ }
+ div.hb_file_div pre > i {
+ font-family: inherit;
+ font-style: italic;
+ }
+ a.hb_file_a:link {
+ color: green;
+ font-weight: bold;
+ text-decoration: none;
+ }
+ a.hb_file_a:visited {
+ color: green;
+ font-weight: bold;
+ text-decoration: none;
+ }
+ a.hb_file_a:focus {
+ color: green;
+ font-weight: bold;
+ text-decoration: underline;
+ }
+ a.hb_file_a:hover {
+ color: green;
+ font-weight: bold;
+ text-decoration: underline;
+ }
+ div.hb_img_div_outer {
+ margin-top: 1.5em;
+ margin-bottom: 1.5em;
+ }
+ div.hb_img_div_no_vspace {
+ margin-top: 0.25em;
+ margin-bottom: 0.25em;
+ }
+ div.hb_img_div_inner_img {
+ float: left;
+ vertical-align: top;
+ text-align: left;
+ margin-right: 2em;
+ min-height: 3em;
+ }
+ div.hb_img_div_inner_img_centered {
+ float: left;
+ vertical-align: top;
+ text-align: center;
+ margin-right: 2em;
+ min-height: 3em;
+ }
+ p.hb_img_p_download {
+ }
+ span.hb_img_caption {
+ margin-top: 1em;
+ }
+ /* Classes for easier alignment.
+ */
+ .topleft {
+ vertical-align: top;
+ text-align: left;
+ }
+ .topcenter {
+ vertical-align: top;
+ text-align: center;
+ }
+ .topright {
+ vertical-align: top;
+ text-align: right;
+ }
+ .middleleft {
+ vertical-align: middle;
+ text-align: left;
+ }
+ .middlecenter {
+ vertical-align: middle;
+ text-align: center;
+ }
+ .middleright {
+ vertical-align: middle;
+ text-align: right;
+ }
+ .bottomleft {
+ vertical-align: bottom;
+ text-align: left;
+ }
+ .bottomcenter {
+ vertical-align: bottom;
+ text-align: center;
+ }
+ .bottomright {
+ vertical-align: bottom;
+ text-align: right;
+ }
+ .paddedtopleft {
+ vertical-align: top;
+ text-align: left;
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+ padding-top: 0.12em;
+ padding-bottom: 0.12em;
+ }
+ .paddedtopcenter {
+ vertical-align: top;
+ text-align: center;
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+ padding-top: 0.12em;
+ padding-bottom: 0.12em;
+ }
+ .paddedtopright {
+ vertical-align: top;
+ text-align: right;
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+ padding-top: 0.12em;
+ padding-bottom: 0.12em;
+ }
+ .paddedmiddleleft {
+ vertical-align: middle;
+ text-align: left;
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+ padding-top: 0.12em;
+ padding-bottom: 0.12em;
+ }
+ .paddedmiddlecenter {
+ vertical-align: middle;
+ text-align: center;
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+ padding-top: 0.12em;
+ padding-bottom: 0.12em;
+ }
+ .paddedmiddleright {
+ vertical-align: middle;
+ text-align: right;
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+ padding-top: 0.12em;
+ padding-bottom: 0.12em;
+ }
+ .paddedbottomleft {
+ vertical-align: bottom;
+ text-align: left;
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+ padding-top: 0.12em;
+ padding-bottom: 0.12em;
+ }
+ .paddedbottomcenter {
+ vertical-align: bottom;
+ text-align: center;
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+ padding-top: 0.12em;
+ padding-bottom: 0.12em;
+ }
+ .paddedbottomright {
+ vertical-align: bottom;
+ text-align: right;
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+ padding-top: 0.12em;
+ padding-bottom: 0.12em;
+ }
+ .paddedtop {
+ vertical-align: top;
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+ padding-top: 0.12em;
+ padding-bottom: 0.12em;
+ }
+ .paddedmiddle {
+ vertical-align: middle;
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+ padding-top: 0.12em;
+ padding-bottom: 0.12em;
+ }
+ .paddedbottom {
+ vertical-align: bottom;
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+ padding-top: 0.12em;
+ padding-bottom: 0.12em;
+ }
+ .paddedleft {
+ text-align: left;
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+ padding-top: 0.12em;
+ padding-bottom: 0.12em;
+ }
+ .paddedcenter {
+ text-align: center;
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+ padding-top: 0.12em;
+ padding-bottom: 0.12em;
+ }
+ .paddedright {
+ text-align: right;
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+ padding-top: 0.12em;
+ padding-bottom: 0.12em;
+ }
+ .padded {
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+ padding-top: 0.12em;
+ padding-bottom: 0.12em;
+ }
+ .floatleft {
+ float: left;
+ }
+ .marginfloatleft {
+ float: left;
+ margin-right: 2em;
+ margin-bottom: 1em;
+ }
+ .floatright {
+ float: right;
+ }
+ .clearboth {
+ clear: both;
+ }
+ table.overview {
+ background-color: yellow;
+ padding-top: 0.5em;
+ padding-left: 2em;
+ padding-right: 2em;
+ padding-bottom: 0.5em;
+ margin-top: 1em;
+ margin-bottom: 1em;
+ }
+}
+
+@media print {
+ /* General classes
+ */
+ /* In FF the TD element does not inherit the font size from body for print */
+ * {
+ font-size: 12pt;
+ }
+ body {
+ font-size: 12pt;
+ }
+ h1 {
+ font-size: 180%;
+ font-weight: bold;
+ }
+ h2 {
+ font-size: 160%;
+ font-weight: bold;
+ }
+ h3 {
+ font-size: 160%;
+ }
+ h4 {
+ font-size: 140%;
+ font-weight: bold;
+ }
+ h5 {
+ font-size: 140%;
+ }
+ h6 {
+ font-size: 120%;
+ font-weight: bold;
+ }
+ pre {
+ border-width: 1px;
+ border-style: solid;
+ border-color: black;
+ padding-top: 0.5em;
+ padding-left: 2em;
+ padding-right: 2em;
+ padding-bottom: 0.5em;
+ margin-top: 0.5em;
+ margin-left: 2em;
+ margin-right: 2em;
+ margin-bottom: 0.5em;
+ overflow: auto;
+ }
+ pre > i {
+ font-family: inherit;
+ font-style: italic;
+ }
+ pre code:before {
+ content: attr(title)':\20';
+ font-size: 50%;
+ }
+ /* Classes from the template
+ */
+ div.header {
+ margin: 5pt;
+ }
+ div.header div.headerleft {
+ float: left;
+ text-align: left;
+ }
+ div.header div.headercenter {
+ text-align: center;
+ }
+ div.header div.headercenter span.title {
+ font-size: 120%;
+ }
+ div.header div.headerright {
+ float: right;
+ text-align: right;
+ display: none;
+ }
+ div.navicon {
+ clear: both;
+ margin: 5pt;
+ }
+ div.navicon div.naviheader {
+ }
+ div.navicon div.contents: {
+ margin-top: 1em;
+ margin-bottom: 1em;
+ }
+ div.footer {
+ clear: both;
+ border-style: solid;
+ border-width: 0.12pt;
+ border-color: black;
+ margin: 5px;
+ padding-left: 0.5em;
+ padding-right: 0.5em;
+ padding-top: 0.12em;
+ padding-bottom: 0.12em;
+ }
+ div.footer div.footerleft {
+ float: left;
+ text-align: left;
+ }
+ div.footer div.footercenter {
+ text-align: center;
+ }
+ div.footer div.footerright {
+ float: right;
+ text-align: right;
+ }
+ /* Classes from htmlbook
+ */
+ div.hb_nm_div {
+ display: none;
+ float: right;
+ width: 23em;
+ }
+ ul.hb_nm_ul {
+ margin-top: 1em;
+ margin-bottom: 1em;
+ }
+ li.hb_nm_li {
+ list-style: none;
+ }
+ a.hb_nm_a:link {
+ color: black;
+ text-decoration: none;
+ }
+ a.hb_nm_a:visited {
+ color: black;
+ text-decoration: none;
+ }
+ a.hb_nm_a:hover {
+ color: black;
+ text-decoration: none;
+ }
+ a.hb_nm_a:focus {
+ color: black;
+ text-decoration: none;
+ }
+ a.hb_nm_a_parent:link {
+ color: black;
+ font-weight: bold;
+ text-decoration: none;
+ }
+ a.hb_nm_a_parent:visited {
+ color: black;
+ font-weight: bold;
+ text-decoration: none;
+ }
+ a.hb_nm_a_parent:hover {
+ color: black;
+ font-weight: bold;
+ text-decoration: none;
+ }
+ a.hb_nm_a_parent:focus {
+ color: black;
+ font-weight: bold;
+ text-decoration: none;
+ }
+ li.hb_nm_c {
+ list-style: none;
+ color: black;
+ font-weight: bold;
+ }
+ li.hb_nm_sep {
+ list-style: none;
+ }
+ div.hb_navigation {
+ display: none;
+ }
+ a.hb_navi_a {
+ }
+ img.hb_navi_img {
+ }
+ div.hb_pos_div {
+ }
+ table.hb_pos_ta {
+ }
+ tr.hb_pos_tr {
+ }
+ td.hb_pos_td_arrow {
+ font-family: sans-serif;
+ font-size: 75%;
+ text-align: center;
+ vertical-align: top;
+ }
+ td.hb_pos_td_text {
+ font-family: sans-serif;
+ font-size: 75%;
+ text-align: left;
+ vertical-align: top;
+ }
+ div.contents_from_text {
+ }
+ span.hb_link_number {
+ }
+ table.hb_img_ta {
+ }
+ tr.hb_img_tr {
+ }
+ td.hb_img_td_img {
+ vertical-align: top;
+ text-align: center;
+ }
+ td.hb_img_td_empty {
+ display: none;
+ }
+ td.hb_img_td_a {
+ display: none;
+ }
+ a.hb_img_a_larger:link {
+ font-family: sans-serif;
+ font-size: 75%;
+ color: black;
+ text-decoration: none;
+ }
+ a.hb_img_a_larger:visited {
+ font-family: sans-serif;
+ font-size: 75%;
+ color: black;
+ text-decoration: none;
+ }
+ a.hb_img_a_larger:hover {
+ font-family: sans-serif;
+ font-size: 75%;
+ color: black;
+ text-decoration: none;
+ }
+ a.hb_img_a_larger:focus {
+ font-family: sans-serif;
+ font-size: 75%;
+ color: black;
+ text-decoration: none;
+ }
+ a.hb_a_i:link {
+ color: black;
+ text-decoration: none;
+ }
+ a.hb_a_i:visited {
+ color: black;
+ text-decoration: none;
+ }
+ a.hb_a_i:focus {
+ color: black;
+ text-decoration: none;
+ }
+ a.hb_a_i:hover {
+ color: black;
+ text-decoration: none;
+ }
+ a.hb_a_e {
+ }
+ table.hb_me_ta {
+ border-width: thin;
+ border-style: solid;
+ border-color: black;
+ }
+ tr.hb_me_tr {
+ border-width: thin;
+ border-style: solid;
+ border-color: black;
+ }
+ td.hb_me_td_text {
+ font-family: sans-serif;
+ text-align: left;
+ vertical-align: top;
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+ }
+ td.hb_me_td_arrow {
+ font-family: sans-serif;
+ text-align: center;
+ vertical-align: top;
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+ }
+ table.hb_ptoc_ta {
+ display: none;
+ }
+ tr.hb_ptoc_tr {
+ }
+ td.hb_ptoc_td_empty {
+ width: 3ex;
+ }
+ td.hb_ptoc_td_data {
+ font-family: sans-serif;
+ font-size: 75%;
+ text-align: left;
+ vertical-align: top;
+ }
+ a.hb_ptoc_a:link {
+ color: black;
+ text-decoration: none;
+ }
+ a.hb_ptoc_a:visited {
+ color: black;
+ text-decoration: none;
+ }
+ a.hb_ptoc_a:focus {
+ color: black;
+ text-decoration: none;
+ }
+ a.hb_ptoc_a:hover {
+ color: black;
+ text-decoration: none;
+ }
+ div.hb_link_div {
+ }
+ table.hb_link_ta {
+ margin-bottom: 1em;
+ }
+ td.hb_link_td_number {
+ text-align: center;
+ vertical-align: top;
+ }
+ td.hb_link_td_url {
+ text-align: left;
+ vertical-align: top;
+ }
+ div.hb_dtoc_div {
+ }
+ table.hb_dtoc_ta {
+ }
+ tr.hb_dtoc_tr {
+ }
+ td.hb_dtoc_td_space {
+ }
+ td.hb_dtoc_td_entry {
+ font-family: sans-serif;
+ font-size: 75%;
+ }
+ a.hb_dtoc_a:link {
+ color: black;
+ text-decoration: none;
+ }
+ a.hb_dtoc_a:visited {
+ color: black;
+ text-decoration: none;
+ }
+ a.hb_dtoc_a:focus {
+ color: black;
+ text-decoration: none;
+ }
+ a.hb_dtoc_a:hover {
+ color: black;
+ text-decoration: none;
+ }
+ div.hb_ki_div {
+ display: none;
+ }
+ h2.hb_ki_h2 {
+ }
+ dl.hb_ki_dl {
+ }
+ dt.hb_ki_dt {
+ font-weight: bold;
+ }
+ dd.hb_ki_dd {
+ }
+ ul.hb_ki_ul {
+ }
+ li.hb_ki_li {
+ list-style: none;
+ font-family: sans-serif;
+ font-size: 75%;
+ }
+ a.hb_ki_a:link {
+ color: black;
+ text-decoration: none;
+ }
+ a.hb_ki_a:visited {
+ color: black;
+ text-decoration: none;
+ }
+ a.hb_ki_a:focus {
+ color: black;
+ text-decoration: none;
+ }
+ a.hb_ki_a:hover {
+ color: black;
+ text-decoration: none;
+ }
+ div.hb_file_div {
+ border-width: 1px;
+ border-style: solid;
+ border-color: black;
+ padding-top: 0.5em;
+ padding-left: 2em;
+ padding-right: 2em;
+ padding-bottom: 0.5em;
+ margin-top: 0.5em;
+ margin-left: 2em;
+ margin-right: 2em;
+ margin-bottom: 0.5em;
+ }
+ div.hb_file_div pre {
+ border-style: none;
+ padding-top: 0.5em;
+ padding-left: 0px;
+ padding-right: 0px;
+ padding-bottom: 0px;
+ margin-top: 0px;
+ margin-left: 0px;
+ margin-right: 0px;
+ margin-bottom: 0px;
+ overflow: auto;
+ }
+ div.hb_file_div pre > i {
+ font-family: inherit;
+ font-style: italic;
+ }
+ a.hb_file_a:link {
+ color: black;
+ font-weight: bold;
+ text-decoration: underline;
+ }
+ a.hb_file_a:visited {
+ color: black;
+ font-weight: bold;
+ text-decoration: underline;
+ }
+ a.hb_file_a:focus {
+ color: black;
+ font-weight: bold;
+ text-decoration: underline;
+ }
+ a.hb_file_a:hover {
+ color: black;
+ font-weight: bold;
+ text-decoration: underline;
+ }
+ div.hb_img_div_outer {
+ margin-top: 1.5em;
+ margin-bottom: 1.5em;
+ }
+ div.hb_img_div_no_vspace {
+ }
+ div.hb_img_div_inner_img {
+ float: left;
+ vertical-align: top;
+ text-align: left;
+ margin-right: 2em;
+ }
+ div.hb_img_div_inner_img_centered {
+ float: left;
+ vertical-align: top;
+ text-align: center;
+ margin-right: 2em;
+ }
+ p.hb_img_p_download {
+ display: none;
+ }
+ span.hb_img_caption {
+ margin-top: 1em;
+ }
+ /* Classes for easier alignment.
+ */
+ .topleft {
+ vertical-align: top;
+ text-align: left;
+ }
+ .topcenter {
+ vertical-align: top;
+ text-align: center;
+ }
+ .topright {
+ vertical-align: top;
+ text-align: right;
+ }
+ .middleleft {
+ vertical-align: middle;
+ text-align: left;
+ }
+ .middlecenter {
+ vertical-align: middle;
+ text-align: center;
+ }
+ .middleright {
+ vertical-align: middle;
+ text-align: right;
+ }
+ .bottomleft {
+ vertical-align: bottom;
+ text-align: left;
+ }
+ .bottomcenter {
+ vertical-align: bottom;
+ text-align: center;
+ }
+ .bottomright {
+ vertical-align: bottom;
+ text-align: right;
+ }
+ .paddedtopleft {
+ vertical-align: top;
+ text-align: left;
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+ padding-top: 0.12em;
+ padding-bottom: 0.12em;
+ }
+ .paddedtopcenter {
+ vertical-align: top;
+ text-align: center;
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+ padding-top: 0.12em;
+ padding-bottom: 0.12em;
+ }
+ .paddedtopright {
+ vertical-align: top;
+ text-align: right;
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+ padding-top: 0.12em;
+ padding-bottom: 0.12em;
+ }
+ .paddedmiddleleft {
+ vertical-align: middle;
+ text-align: left;
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+ padding-top: 0.12em;
+ padding-bottom: 0.12em;
+ }
+ .paddedmiddlecenter {
+ vertical-align: middle;
+ text-align: center;
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+ padding-top: 0.12em;
+ padding-bottom: 0.12em;
+ }
+ .paddedmiddleright {
+ vertical-align: middle;
+ text-align: right;
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+ padding-top: 0.12em;
+ padding-bottom: 0.12em;
+ }
+ .paddedbottomleft {
+ vertical-align: bottom;
+ text-align: left;
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+ padding-top: 0.12em;
+ padding-bottom: 0.12em;
+ }
+ .paddedbottomcenter {
+ vertical-align: bottom;
+ text-align: center;
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+ padding-top: 0.12em;
+ padding-bottom: 0.12em;
+ }
+ .paddedbottomright {
+ vertical-align: bottom;
+ text-align: right;
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+ padding-top: 0.12em;
+ padding-bottom: 0.12em;
+ }
+ .paddedtop {
+ vertical-align: top;
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+ padding-top: 0.12em;
+ padding-bottom: 0.12em;
+ }
+ .paddedmiddle {
+ vertical-align: middle;
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+ padding-top: 0.12em;
+ padding-bottom: 0.12em;
+ }
+ .paddedbottom {
+ vertical-align: bottom;
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+ padding-top: 0.12em;
+ padding-bottom: 0.12em;
+ }
+ .paddedleft {
+ text-align: left;
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+ padding-top: 0.12em;
+ padding-bottom: 0.12em;
+ }
+ .paddedcenter {
+ text-align: center;
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+ padding-top: 0.12em;
+ padding-bottom: 0.12em;
+ }
+ .paddedright {
+ text-align: right;
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+ padding-top: 0.12em;
+ padding-bottom: 0.12em;
+ }
+ .padded {
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+ padding-top: 0.12em;
+ padding-bottom: 0.12em;
+ }
+ .floatleft {
+ float: left;
+ }
+ .marginfloatleft {
+ float: left;
+ margin-right: 2em;
+ margin-bottom: 1em;
+ }
+ .floatright {
+ float: right;
+ }
+ .clearboth {
+ clear: both;
+ }
+ table.overview {
+ padding-top: 0.5em;
+ padding-left: 2em;
+ padding-right: 2em;
+ padding-bottom: 0.5em;
+ margin-top: 1em;
+ margin-bottom: 1em;
+ }
+}
+
+@page {
+ margin-top: 1.5cm;
+ margin-bottom: 1.5cm;
+}
+
+@page :left {
+ margin-left: 1.5cm;
+ margin-right: 2.5cm;
+}
+
+@page :right {
+ margin-left: 2.5cm;
+ margin-right: 1.5cm;
+}
+
diff --git a/support/dktools/dktools/htmlbook/toc.fig b/support/dktools/dktools/htmlbook/toc.fig
new file mode 100644
index 0000000000..102f7243a4
--- /dev/null
+++ b/support/dktools/dktools/htmlbook/toc.fig
@@ -0,0 +1,36 @@
+#FIG 3.2
+Portrait
+Center
+Inches
+A4
+100.0
+Single
+-2
+1200 2
+0 32 #364e6d
+2 2 0 0 7 7 999 1 -1 0 0 0 0 0 0 5
+ 0 0 1200 0 1200 1200 0 1200 0 0
+2 4 0 0 0 0 105 1 5 0 0 0 19 0 0 5
+ 150 150 1125 150 1125 1125 150 1125 150 150
+2 4 0 0 0 0 104 1 10 0 0 0 19 0 0 5
+ 112 112 1087 112 1087 1087 112 1087 112 112
+2 4 0 0 4 4 103 1 20 0 0 0 16 0 0 5
+ 75 75 1050 75 1050 1050 75 1050 75 75
+2 4 0 0 6 6 102 1 20 0 0 0 16 0 0 5
+ 150 150 975 150 975 975 150 975 150 150
+2 1 0 5 0 0 99 1 -1 0 0 0 12 0 0 2
+ 225 337 712 337
+2 1 0 5 0 0 99 1 -1 0 0 0 12 0 0 2
+ 900 337 825 337
+2 1 0 5 0 0 99 1 -1 0 0 0 12 0 0 2
+ 225 487 712 487
+2 1 0 5 0 0 99 1 -1 0 0 0 12 0 0 2
+ 900 487 825 487
+2 1 0 5 0 0 99 1 -1 0 0 0 12 0 0 2
+ 225 637 712 637
+2 1 0 5 0 0 99 1 -1 0 0 0 12 0 0 2
+ 900 637 825 637
+2 1 0 5 0 0 99 1 -1 0 0 0 12 0 0 2
+ 225 787 712 787
+2 1 0 5 0 0 99 1 -1 0 0 0 12 0 0 2
+ 900 787 825 787
diff --git a/support/dktools/dktools/htmlbook/toc.png b/support/dktools/dktools/htmlbook/toc.png
new file mode 100644
index 0000000000..6248f9a4b6
--- /dev/null
+++ b/support/dktools/dktools/htmlbook/toc.png
Binary files differ
diff --git a/support/dktools/dktools/htmlbook/web.hbt b/support/dktools/dktools/htmlbook/web.hbt
new file mode 100644
index 0000000000..9f59b60999
--- /dev/null
+++ b/support/dktools/dktools/htmlbook/web.hbt
@@ -0,0 +1,24 @@
+<div class="header">
+<div class="headerleft">
+%%img src=mylogo.png alt="My introduction to something" title%%
+</div><!-- class="headerleft" -->
+<div class="headerright">
+</div><!-- class="headerright" -->
+<div class="headercenter">
+<span class="title">%%title%%</span>
+</div><!-- class="headercenter" -->
+</div><!-- class="header" -->
+<div class="navicon">
+%%menu%%
+<div class="naviheader">&nbsp;</div>
+<div class="contents">
+%%navigation%%
+<div class="contents_from_text">%%contents%%</div><!-- class="contents_from_text" -->
+%%navigation%%
+</div><!-- class="contents" -->
+</div><!-- class="navicon" -->
+<div class="footer">
+<div class="footerleft">%%author%%</div>
+<div class="footerright">%%location%%, %%date style=german%%</div>
+<div class="footercenter">&nbsp;</div>
+</div><!-- class="footer" -->
diff --git a/support/dktools/dktools/itadmin/it-de.sql b/support/dktools/dktools/itadmin/it-de.sql
new file mode 100644
index 0000000000..ab58d7e4da
--- /dev/null
+++ b/support/dktools/dktools/itadmin/it-de.sql
@@ -0,0 +1,314 @@
+
+-- The database is named it
+
+create database it;
+
+use it;
+
+-- VLANs
+
+CREATE TABLE vlans (
+ vl_s char(8) NOT NULL default '', -- short VLAN type, i.e. 500
+ vl_l char(64) default 'mein Netzwerk', -- long type
+ vl_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY (vl_s)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+CREATE TABLE networks(
+ nw_ip char(18) NOT NULL default '', -- IP
+ nw_ma char(18) default '', -- Maske
+ nw_gw char(18) default '', -- Gateway
+ nw_bc char(18) default '', -- Broadcast-Adresse
+ vl_s char(8) default '', -- VLAN
+ nw_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ CONSTRAINT cf FOREIGN KEY(vl_s) REFERENCES vlans(vl_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ PRIMARY KEY(nw_ip),
+ INDEX(vl_s)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+-- Datendosen-Speed
+
+CREATE TABLE ddspeed (
+ sp_s char(12) NOT NULL default '', -- Kurze Bezeichnung
+ sp_l char(64) default NULL, -- ausfuerhliche Bezeichnung
+ sp_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(sp_s)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+INSERT INTO ddspeed (sp_s, sp_l ) VALUES
+('auto', 'Autonegotiation'),
+('10', '10 MBit/s halbduplex'),
+('100', '100 MBit/s halbduplex'),
+('10fd', '10 MBit/s vollduplex'),
+('100fd', '100 MBit/s vollduplex');
+
+-- Gebaeude
+
+CREATE TABLE buildings (
+ gb_s char(4) NOT NULL default '', -- Name kurz
+ gb_l char(64) default NULL, -- Name komplett
+ gb_a1 char(64) default NULL, -- Adresszeile 1
+ gb_a2 char(64) default NULL, -- Adresszeile 2
+ gb_a3 char(64) default NULL, -- Adresszeile 3
+ gb_a4 char(64) default NULL, -- Adresszeile 4
+ gb_plz char(32) default '12345', -- PLZ
+ gb_ort char(64) default 'Irgendwo', -- Ort
+ gb_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(gb_s)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+-- Datendosen
+
+CREATE TABLE patches (
+ dd_n char(16) NOT NULL default '', -- Kurze Bezeichnung der Dose, Aufdruck
+ sp_s char(12) default 'auto', -- Speed
+ vl_s char(8) default '-', -- VLAN type
+ dd_p char(16) default NULL, -- Port am Hub
+ gb_s char(4) default '', -- Haus
+ dd_r char(8) default NULL, -- Raumnummer
+ dd_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ CONSTRAINT c2 FOREIGN KEY (sp_s) REFERENCES ddspeed(sp_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT c3 FOREIGN KEY (vl_s) REFERENCES vlans(vl_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT c4 FOREIGN KEY (gb_s) REFERENCES buildings(gb_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ PRIMARY KEY(dd_n),
+ INDEX(sp_s),
+ INDEX(vl_s),
+ INDEX(gb_s)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+
+-- Personen (Systemverantwortliche, Lizenzinhaber...)
+
+CREATE TABLE users (
+ us_s char(12) NOT NULL default '-', -- Loginname
+ us_t char(32) default NULL, -- Titel
+ us_sn char(64) default '', -- Vorname
+ us_fn char(64) default '', -- Familienname
+ us_em char(64) default NULL, -- E-Mail-Adresse
+ us_ko char(16) default NULL, -- Kostenstelle
+ us_se char(16) default NULL, -- SE 1...
+ us_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(us_s)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+-- Netgroups
+
+CREATE TABLE netgroups (
+ ng_s char(12) NOT NULL default '-', -- Netgroup Name
+ ng_l char(64) default '', -- Beschreibung
+ ng_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(ng_s)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+-- Beziehungen zwischen Netgroups
+
+CREATE TABLE ngdeps (
+ nd_pk int(10) unsigned NOT NULL auto_increment,
+ nd_p char(12) default NULL, -- Elterngruppe
+ nd_c char(12) default NULL, -- Kind (in Eltern enthalten)
+ nd_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ CONSTRAINT c5 FOREIGN KEY (nd_p) REFERENCES netgroups(ng_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT c6 FOREIGN KEY (nd_c) REFERENCES netgroups(ng_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ PRIMARY KEY(nd_pk),
+ INDEX(nd_p),
+ INDEX(nd_c)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+-- DHCP-Klassen
+
+CREATE TABLE dhcpclasses (
+ dc_s char(16) NOT NULL default '-', -- DHCP class name
+ dc_d char(64) default NULL, -- description
+ nw_ip char(18) NOT NULL default '0.0.0.0', -- IP address range for class
+ dc_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ CONSTRAINT cm FOREIGN KEY (nw_ip) REFERENCES networks(nw_ip) ON UPDATE CASCADE ON DELETE RESTRICT;
+ PRIMARY KEY(dc_s),
+ INDEX(nw_ip)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+-- DHCP-Pools
+
+CREATE TABLE dhcppools(
+ dp_pk int(10) unsigned NOT NULL auto_increment, -- primary key
+ dp_st char(18) default NULL, -- start address
+ dp_en char(18) default NULL, -- end address
+ nw_ip char(18) default NULL, -- network
+ dp_al integer default 0, -- allow unknown clients
+ dp_dn integer default 1, -- deny unknown clients
+ dc_s char(16) default NULL, -- allowed DHCP class
+ dp_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ CONSTRAINT ci FOREIGN KEY(nw_ip) REFERENCES networks(nw_ip) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT cj FOREIGN KEY(dc_s) REFERENCES dhcpclasses(dc_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ PRIMARY KEY(dp_pk),
+ INDEX(nw_ip)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+-- DHCP-Groups
+CREATE TABLE dhcpgroups(
+ dg_s char(16) NOT NULL, -- Group name, primary key
+ dg_l char(64) default NULL, -- description
+ dg_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(dg_s)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+-- DHCP-Options
+CREATE TABLE dhcpoptions(
+ do_pk int(10) unsigned NOT NULL auto_increment, -- primary key
+ do_sc ENUM('server', 'vlan', 'network', 'group', 'pool', 'host') default 'server',
+ do_sn char(32) default NULL, -- scope name
+ do_n char(64) NOT NULL, -- option name
+ do_v char(128) NOT NULL, -- option value
+ do_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(do_pk),
+ INDEX(do_sc),
+ INDEX(do_sn),
+ INDEX(do_n)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+-- Hosts
+
+CREATE TABLE computers (
+ co_s char(16) NOT NULL default 'e__', -- Computername
+ us_s char(12) default '-', -- Systemverantwortlicher
+ co_ip char(18) default '192.168.101.1', -- IP-Adresse
+ co_mc char(18) default NULL, -- MAC-Adresse
+ ng_s char(12) default NULL, -- Netzgruppe
+ co_co char(64) default NULL, -- Kommentar
+ dc_s char(16) default NULL, -- DHCP-Klasse
+ dg_s char(16) default NULL, -- DHCP-Gruppe
+ dd_n char(16) default NULL, -- Datendose
+ gb_s char(4) default 'B', -- Gebaeude
+ co_r char(8) default '', -- Raumnummer
+ co_in char(12) default '0700000', -- Inventar-Nummer
+ co_sn char(64) default NULL, -- Seriennummer
+ co_dd char(64) default NULL, -- DNS Domain
+ co_ff integer default 0, -- full name first
+ co_gu integer default 0, -- guest PC
+ co_hi char(32) default NULL, -- Host-ID
+ co_ex DATE default NULL, -- Ablaufdatum Studenten-Laptops
+ co_nn integer default 0, -- skip when creating network docu
+ co_na integer default 0, -- skip in arpwatch
+ co_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ CONSTRAINT c7 FOREIGN KEY (us_s) REFERENCES users(us_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT c8 FOREIGN KEY (ng_s) REFERENCES netgroups(ng_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT cg FOREIGN KEY (gb_s) REFERENCES buildings(gb_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT ch FOREIGN KEY (dc_s) REFERENCES dhcpclasses(dc_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT ck FOREIGN KEY (dg_s) REFERENCES dhcpgroups(dg_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT cm FOREIGN KEY (dd_n) REFERENCES patches(dd_n) ON UPDATE CASCADE ON DELETE RESTRICT,
+ PRIMARY KEY (co_s),
+ INDEX(us_s),
+ INDEX(co_ip),
+ INDEX(ng_s),
+ INDEX(dc_s),
+ INDEX(dg_s),
+ INDEX(dd_n),
+ INDEX(gb_s),
+ INDEX(co_r),
+ INDEX(co_in),
+ INDEX(co_sn)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+-- Aliases
+
+CREATE TABLE aliases (
+ al_s char(80) NOT NULL, -- the alias
+ co_s char(16) default NULL, -- alias target
+ al_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ CONSTRAINT co FOREIGN KEY(co_s) REFERENCES computers(co_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ PRIMARY KEY(al_s),
+ INDEX(co_s)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+-- Software-Hersteller
+
+CREATE TABLE swmanufacturers (
+ sm_s char(16) NOT NULL, -- Hersteller kurz
+ sm_l char(64) default '', -- Hersteller lang
+ sm_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(sm_s)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+-- Software-Produkte
+
+CREATE TABLE swproducts (
+ sw_s char(16) NOT NULL, -- Produkt, kurz
+ sw_l char(64) default '', -- Produkt lang
+ sm_s char(16) default '', -- Hersteller kurz
+ sw_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ CONSTRAINT c9 FOREIGN KEY (sm_s) REFERENCES swmanufacturers(sm_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ PRIMARY KEY(sw_s),
+ INDEX(sm_s)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+-- Software-Verkaeufer
+
+CREATE TABLE swresellers (
+ sr_s char(16) NOT NULL, -- Verkaeufer kurz
+ sr_l char(64) default '', -- Voller Name
+ sr_a1 char(64) default NULL, -- Addresszeile 1
+ sr_a2 char(64) default NULL, -- Addresszeile 2
+ sr_a3 char(64) default NULL, -- Addresszeile 3
+ sr_a4 char(64) default NULL, -- Addresszeile 4
+ sr_plz char(8) default NULL, -- PLZ
+ sr_ort char(64) default NULL, -- Ort
+ sr_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(sr_s)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+-- Lizenztypen
+
+CREATE TABLE licensetypes (
+ lt_s char(16) NOT NULL, -- Kurzbezeichnung
+ lt_l char(64) default '', -- vollstaendige Bezeichnung
+ lt_i int default 1, -- Anzahl der Plaetze
+ lt_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(lt_s),
+ INDEX(lt_l)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+INSERT INTO licensetype(lt_s, lt_l, lt_i) VALUES
+('e', 'Einzelplatzlizenz (1 Nutzer auf 1 Computer)', 1),
+('c', 'Concurrent-Lizenz für 1 Nutzer', 1),
+('flexlm' 'Flexlm-Client-Installation', 1),
+('gpl2', 'GNU General Public License, Version 2', 1),
+('lgpl2', 'GNU Lesser General Public License, Version 2', 1),
+('gpl3', 'GNU General Public License, Version 3', 1),
+('lgpl3', 'GNU Lesser General Public License, Version 3', 1),
+('bsd', 'BSD-Lizenz', 1),
+('flexlm-s5', 'Flexlm-Lizenz-Server, 5 Nutzer', 5);
+
+-- Nachweis ueber erworbene und eingesetzte Lizenzen
+
+CREATE TABLE licenses (
+ li_pk int(10) unsigned NOT NULL auto_increment,
+ li_on char(24) default NULL, -- Auftragsnummer der Bestellung
+ sw_s char(16) default NULL, -- Software-Produkt
+ us_s char(12) default NULL, -- User Login Name
+ co_s char(16) default NULL, -- Computer, auf dem eingesetzt
+ lt_s char(16) default 's', -- Lizenztyp
+ li_no char(64) default NULL, -- Notes (Bemerkungen)
+ sr_s char(16) default NULL, -- Verkaeufer
+ li_dd char(16) default NULL, -- Datum Lieferschein
+ li_nd char(16) default NULL, -- Lieferschein-Nr
+ li_di char(16) default NULL, -- Rechnungsdatum
+ li_ni char(16) default NULL, -- Rechnungsnummer
+ li_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ CONSTRAINT ca FOREIGN KEY (sw_s) REFERENCES swproducts(sw_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT cb FOREIGN KEY (sr_s) REFERENCES swresellers(sr_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT cc FOREIGN KEY (lt_s) REFERENCES licensetypes(lt_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT cd FOREIGN KEY (us_s) REFERENCES users(us_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT ce FOREIGN KEY (co_s) REFERENCES computers(co_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ PRIMARY KEY(li_pk),
+ INDEX(li_on),
+ INDEX(sw_s),
+ INDEX(us_s),
+ INDEX(co_s),
+ INDEX(lt_s),
+ INDEX(sr_s),
+ INDEX(li_dd),
+ INDEX(li_nd),
+ INDEX(li_di),
+ INDEX(li_ni)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+
diff --git a/support/dktools/dktools/itadmin/it-latin1.sql b/support/dktools/dktools/itadmin/it-latin1.sql
new file mode 100644
index 0000000000..039e3eeac9
--- /dev/null
+++ b/support/dktools/dktools/itadmin/it-latin1.sql
@@ -0,0 +1,312 @@
+
+-- The database is named it
+
+create database it;
+
+use it;
+
+-- VLANs
+
+CREATE TABLE vlans (
+ vl_s char(8) NOT NULL default '', -- short VLAN type, i.e. 500
+ vl_l char(64) default 'my network', -- long type, description
+ vl_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY (vl_s)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+CREATE TABLE networks(
+ nw_ip char(18) NOT NULL default '', -- IP
+ nw_ma char(18) default '', -- network mask
+ nw_gw char(18) default '', -- default gateway
+ nw_bc char(18) default '', -- broadcast address
+ vl_s char(8) default '', -- VLAN
+ nw_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(nw_ip),
+ INDEX(vl_s),
+ CONSTRAINT cf FOREIGN KEY(vl_s) REFERENCES vlans(vl_s) ON UPDATE CASCADE ON DELETE RESTRICT
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+-- network connection speed setup
+
+CREATE TABLE ddspeed (
+ sp_s char(12) NOT NULL default '', -- short name (abbreviation)
+ sp_l char(64) default NULL, -- long name, description
+ sp_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(sp_s)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+INSERT INTO ddspeed (sp_s, sp_l ) VALUES
+('auto', 'Autonegotiation'),
+('10', '10 MBit/s half-duplex'),
+('100', '100 MBit/s half-duplex'),
+('10fd', '10 MBit/s full-duplex'),
+('100fd', '100 MBit/s full-duplex');
+
+-- buildings
+
+CREATE TABLE buildings (
+ gb_s char(4) NOT NULL default '', -- short name (abbreviation)
+ gb_l char(64) default NULL, -- complete name
+ gb_a1 char(64) default NULL, -- address line 1
+ gb_a2 char(64) default NULL, -- address line 2
+ gb_a3 char(64) default NULL, -- address line 3
+ gb_a4 char(64) default NULL, -- address line 4
+ gb_plz char(32) default '12345', -- ZIP code
+ gb_ort char(64) default 'Somewhere', -- location (town or city name)
+ gb_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(gb_s)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+-- network connections
+
+CREATE TABLE patches (
+ dd_n char(16) NOT NULL default '', -- short name, label on socket
+ sp_s char(12) default 'auto', -- speed setup
+ vl_s char(8) default '-', -- VLAN
+ dd_p char(16) default NULL, -- hub port used for socket
+ gb_s char(4) default '', -- building
+ dd_r char(8) default NULL, -- room
+ dd_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(dd_n),
+ INDEX(sp_s),
+ INDEX(vl_s),
+ INDEX(gb_s),
+ CONSTRAINT c2 FOREIGN KEY (sp_s) REFERENCES ddspeed(sp_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT c3 FOREIGN KEY (vl_s) REFERENCES vlans(vl_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT c4 FOREIGN KEY (gb_s) REFERENCES buildings(gb_s) ON UPDATE CASCADE ON DELETE RESTRICT
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+
+-- persons (computer owners, license owners)
+
+CREATE TABLE users (
+ us_s char(12) NOT NULL default '-', -- short name, i.e. login name
+ us_t char(32) default NULL, -- title
+ us_sn char(64) default '', -- surname
+ us_fn char(64) default '', -- name
+ us_em char(64) default NULL, -- e-mail address
+ us_ko char(16) default NULL, -- department (costs controlling ID)
+ us_se char(16) default NULL, -- staff ID number
+ us_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(us_s)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+-- netgroups
+
+CREATE TABLE netgroups (
+ ng_s char(12) NOT NULL default '-', -- name
+ ng_l char(64) default '', -- description
+ ng_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(ng_s)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+-- netgroup relations
+
+CREATE TABLE ngdeps (
+ nd_pk int(10) unsigned NOT NULL auto_increment,
+ nd_p char(12) default NULL, -- parent group
+ nd_c char(12) default NULL, -- child group
+ nd_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(nd_pk),
+ INDEX(nd_p),
+ INDEX(nd_c),
+ CONSTRAINT c5 FOREIGN KEY (nd_p) REFERENCES netgroups(ng_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT c6 FOREIGN KEY (nd_c) REFERENCES netgroups(ng_s) ON UPDATE CASCADE ON DELETE RESTRICT
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+-- DHCP classes
+
+CREATE TABLE dhcpclasses (
+ dc_s char(16) NOT NULL default '-', -- DHCP class name
+ dc_d char(64) default NULL, -- description
+ nw_ip char(18) NOT NULL default '0.0.0.0', -- IP network for class
+ dc_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(dc_s),
+ INDEX(nw_ip),
+ CONSTRAINT cm FOREIGN KEY (nw_ip) REFERENCES networks(nw_ip) ON UPDATE CASCADE ON DELETE RESTRICT
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+-- DHCP pools
+
+CREATE TABLE dhcppools(
+ dp_pk int(10) unsigned NOT NULL auto_increment, -- primary key
+ dp_st char(18) default NULL, -- start address
+ dp_en char(18) default NULL, -- end address
+ nw_ip char(18) default NULL, -- network
+ dp_al integer default 0, -- allow unknown clients
+ dp_dn integer default 1, -- deny unknown clients
+ dc_s char(16) default NULL, -- allowed DHCP class
+ dp_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(dp_pk),
+ INDEX(nw_ip),
+ CONSTRAINT ci FOREIGN KEY(nw_ip) REFERENCES networks(nw_ip) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT cj FOREIGN KEY(dc_s) REFERENCES dhcpclasses(dc_s) ON UPDATE CASCADE ON DELETE RESTRICT
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+-- DHCP groups
+CREATE TABLE dhcpgroups(
+ dg_s char(16) NOT NULL, -- group name, primary key
+ dg_l char(64) default NULL, -- description
+ dg_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(dg_s)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+-- DHCP options
+CREATE TABLE dhcpoptions(
+ do_pk int(10) unsigned NOT NULL auto_increment, -- primary key
+ do_sc ENUM('server', 'vlan', 'network', 'group', 'pool', 'host') default 'server', -- scope type
+ do_sn char(32) default NULL, -- scope name
+ do_n char(64) NOT NULL, -- option name
+ do_v char(128) NOT NULL, -- option value
+ do_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(do_pk),
+ INDEX(do_sc),
+ INDEX(do_sn),
+ INDEX(do_n)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+-- hosts
+
+CREATE TABLE computers (
+ co_s char(16) NOT NULL default 'e__', -- hostname
+ us_s char(12) default NULL, -- system owner
+ co_ip char(18) default NULL, -- IP address
+ co_mc char(18) default NULL, -- MAC address
+ ng_s char(12) default NULL, -- netgroup
+ co_co char(64) default NULL, -- comment, description
+ dc_s char(16) default NULL, -- DHCP class
+ dg_s char(16) default NULL, -- DHCP group
+ dd_n char(16) default NULL, -- network patch socket
+ gb_s char(4) default NULL, -- building
+ co_r char(8) default NULL, -- room
+ co_in char(12) default NULL, -- inventory number
+ co_sn char(64) default NULL, -- serial number
+ co_dd char(64) default NULL, -- DNS domain
+ co_ff integer default 0, -- full name first flag
+ co_gu integer default 0, -- guest PC flag
+ co_hi char(32) default NULL, -- host ID
+ co_ex DATE default NULL, -- expiration date (for guest PCs)
+ co_nn integer default 0, -- skip host when creating network docu
+ co_na integer default 0, -- skip in arpwatch
+ co_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY (co_s),
+ INDEX(us_s),
+ INDEX(co_ip),
+ INDEX(ng_s),
+ INDEX(dc_s),
+ INDEX(dg_s),
+ INDEX(dd_n),
+ INDEX(gb_s),
+ INDEX(co_r),
+ INDEX(co_in),
+ INDEX(co_sn),
+ CONSTRAINT c7 FOREIGN KEY (us_s) REFERENCES users(us_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT c8 FOREIGN KEY (ng_s) REFERENCES netgroups(ng_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT cg FOREIGN KEY (gb_s) REFERENCES buildings(gb_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT ch FOREIGN KEY (dc_s) REFERENCES dhcpclasses(dc_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT ck FOREIGN KEY (dg_s) REFERENCES dhcpgroups(dg_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT cn FOREIGN KEY (dd_n) REFERENCES patches(dd_n) ON UPDATE CASCADE ON DELETE RESTRICT
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+CREATE TABLE aliases (
+ al_s char(80) NOT NULL, -- the alias
+ co_s char(16) default NULL, -- alias target
+ co_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(al_s),
+ INDEX(co_s),
+ CONSTRAINT co FOREIGN KEY(co_s) REFERENCES computers(co_s) ON UPDATE CASCADE ON DELETE RESTRICT
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+-- software manufacturers
+
+CREATE TABLE swmanufacturers (
+ sm_s char(16) NOT NULL, -- short name (abbreviation, key)
+ sm_l char(64) default '', -- full name
+ sm_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(sm_s)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+-- software products
+
+CREATE TABLE swproducts (
+ sw_s char(16) NOT NULL, -- short name (order key or abbreviation)
+ sw_l char(64) default '', -- full product name
+ sm_s char(16) default '', -- software manufacturer
+ sw_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(sw_s),
+ INDEX(sm_s),
+ CONSTRAINT c9 FOREIGN KEY (sm_s) REFERENCES swmanufacturers(sm_s) ON UPDATE CASCADE ON DELETE RESTRICT
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+-- software resellers
+
+CREATE TABLE swresellers (
+ sr_s char(16) NOT NULL, -- short name (abbreviation, key)
+ sr_l char(64) default '', -- full name
+ sr_a1 char(64) default NULL, -- address line 1
+ sr_a2 char(64) default NULL, -- address line 2
+ sr_a3 char(64) default NULL, -- address line 3
+ sr_a4 char(64) default NULL, -- address line 4
+ sr_plz char(8) default NULL, -- ZIP code
+ sr_ort char(64) default NULL, -- location (town or city name)
+ sr_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(sr_s)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+-- license types
+
+CREATE TABLE licensetypes (
+ lt_s char(16) NOT NULL, -- short name (abbreviation, key)
+ lt_l char(64) default '', -- full name of license type
+ lt_i int default 1, -- number of places for concurrent use
+ lt_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(lt_s),
+ INDEX(lt_l)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+INSERT INTO licensetypes (lt_s, lt_l, lt_i) VALUES
+('s', 'Single user user license', 1),
+('c', 'Single user concurrent license', 1),
+('flexlm', 'Flexlm controlled client installation', 1),
+('gpl2', 'GNU General Public License, version 2', 1),
+('lgpl2', 'GNU Lesser General Public License, version 2', 1),
+('gpl3', 'GNU General Public License, version 3', 1),
+('lgpl3', 'GNU Lesser General Public License, version 3', 1),
+('bsd', 'BSD style license', 1),
+('flexlm-s5', 'Flexlm license server, 5 users', 5);
+
+
+-- list of obtained licenses/installations
+
+CREATE TABLE licenses (
+ li_pk int(10) unsigned NOT NULL auto_increment,
+ li_on char(24) default NULL, -- internal order ID
+ sw_s char(16) default NULL, -- software product
+ us_s char(12) default NULL, -- user name of license owner
+ co_s char(16) default NULL, -- computer where license is used
+ lt_s char(16) default 's', -- license type
+ li_no char(64) default NULL, -- notes
+ sr_s char(16) default NULL, -- software reseller
+ li_dd char(16) default NULL, -- date of delivery
+ li_nd char(16) default NULL, -- delivery letter ID
+ li_di char(16) default NULL, -- date of invoice
+ li_ni char(16) default NULL, -- invoice ID
+ li_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(li_pk),
+ INDEX(li_on),
+ INDEX(sw_s),
+ INDEX(us_s),
+ INDEX(co_s),
+ INDEX(lt_s),
+ INDEX(sr_s),
+ INDEX(li_dd),
+ INDEX(li_nd),
+ INDEX(li_di),
+ INDEX(li_ni),
+ CONSTRAINT ca FOREIGN KEY (sw_s) REFERENCES swproducts(sw_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT cb FOREIGN KEY (sr_s) REFERENCES swresellers(sr_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT cc FOREIGN KEY (lt_s) REFERENCES licensetypes(lt_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT cd FOREIGN KEY (us_s) REFERENCES users(us_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT ce FOREIGN KEY (co_s) REFERENCES computers(co_s) ON UPDATE CASCADE ON DELETE RESTRICT
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
diff --git a/support/dktools/dktools/itadmin/it-utf8.sql b/support/dktools/dktools/itadmin/it-utf8.sql
new file mode 100644
index 0000000000..fe6c9158ff
--- /dev/null
+++ b/support/dktools/dktools/itadmin/it-utf8.sql
@@ -0,0 +1,312 @@
+
+-- The database is named it
+
+create database it;
+
+use it;
+
+-- VLANs
+
+CREATE TABLE vlans (
+ vl_s varchar(8) NOT NULL default '', -- short VLAN type, i.e. 500
+ vl_l varchar(64) default 'my network', -- long type, description
+ vl_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY (vl_s)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE networks(
+ nw_ip varchar(18) NOT NULL default '', -- IP
+ nw_ma varchar(18) default '', -- network mask
+ nw_gw varchar(18) default '', -- default gateway
+ nw_bc varchar(18) default '', -- broadcast address
+ vl_s varchar(8) default '', -- VLAN
+ nw_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(nw_ip),
+ INDEX(vl_s),
+ CONSTRAINT cf FOREIGN KEY(vl_s) REFERENCES vlans(vl_s) ON UPDATE CASCADE ON DELETE RESTRICT
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- network connection speed setup
+
+CREATE TABLE ddspeed (
+ sp_s varchar(12) NOT NULL default '', -- short name (abbreviation)
+ sp_l varchar(64) default NULL, -- long name, description
+ sp_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(sp_s)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+INSERT INTO ddspeed (sp_s, sp_l ) VALUES
+('auto', 'Autonegotiation'),
+('10', '10 MBit/s half-duplex'),
+('100', '100 MBit/s half-duplex'),
+('10fd', '10 MBit/s full-duplex'),
+('100fd', '100 MBit/s full-duplex');
+
+-- buildings
+
+CREATE TABLE buildings (
+ gb_s varchar(4) NOT NULL default '', -- short name (abbreviation)
+ gb_l varchar(64) default NULL, -- complete name
+ gb_a1 varchar(64) default NULL, -- address line 1
+ gb_a2 varchar(64) default NULL, -- address line 2
+ gb_a3 varchar(64) default NULL, -- address line 3
+ gb_a4 varchar(64) default NULL, -- address line 4
+ gb_plz varchar(32) default '12345', -- ZIP code
+ gb_ort varchar(64) default 'Somewhere', -- location (town or city name)
+ gb_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(gb_s)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- network connections
+
+CREATE TABLE patches (
+ dd_n varchar(16) NOT NULL default '', -- short name, label on socket
+ sp_s varchar(12) default 'auto', -- speed setup
+ vl_s varchar(8) default '-', -- VLAN
+ dd_p varchar(16) default NULL, -- hub port used for socket
+ gb_s varchar(4) default '', -- building
+ dd_r varchar(8) default NULL, -- room
+ dd_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(dd_n),
+ INDEX(sp_s),
+ INDEX(vl_s),
+ INDEX(gb_s),
+ CONSTRAINT c2 FOREIGN KEY (sp_s) REFERENCES ddspeed(sp_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT c3 FOREIGN KEY (vl_s) REFERENCES vlans(vl_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT c4 FOREIGN KEY (gb_s) REFERENCES buildings(gb_s) ON UPDATE CASCADE ON DELETE RESTRICT
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+
+-- persons (computer owners, license owners)
+
+CREATE TABLE users (
+ us_s varchar(12) NOT NULL default '-', -- short name, i.e. login name
+ us_t varchar(32) default NULL, -- title
+ us_sn varchar(64) default '', -- surname
+ us_fn varchar(64) default '', -- name
+ us_em varchar(64) default NULL, -- e-mail address
+ us_ko varchar(16) default NULL, -- department (costs controlling ID)
+ us_se varchar(16) default NULL, -- staff ID number
+ us_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(us_s)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- netgroups
+
+CREATE TABLE netgroups (
+ ng_s varchar(12) NOT NULL default '-', -- name
+ ng_l varchar(64) default '', -- description
+ ng_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(ng_s)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- netgroup relations
+
+CREATE TABLE ngdeps (
+ nd_pk int(10) unsigned NOT NULL auto_increment,
+ nd_p varchar(12) default NULL, -- parent group
+ nd_c varchar(12) default NULL, -- child group
+ nd_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(nd_pk),
+ INDEX(nd_p),
+ INDEX(nd_c),
+ CONSTRAINT c5 FOREIGN KEY (nd_p) REFERENCES netgroups(ng_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT c6 FOREIGN KEY (nd_c) REFERENCES netgroups(ng_s) ON UPDATE CASCADE ON DELETE RESTRICT
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- DHCP classes
+
+CREATE TABLE dhcpclasses (
+ dc_s varchar(16) NOT NULL default '-', -- DHCP class name
+ dc_d varchar(64) default NULL, -- description
+ nw_ip varchar(18) NOT NULL default '0.0.0.0', -- IP network for class
+ dc_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(dc_s),
+ INDEX(nw_ip),
+ CONSTRAINT cm FOREIGN KEY (nw_ip) REFERENCES networks(nw_ip) ON UPDATE CASCADE ON DELETE RESTRICT
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- DHCP pools
+
+CREATE TABLE dhcppools(
+ dp_pk int(10) unsigned NOT NULL auto_increment, -- primary key
+ dp_st varchar(18) default NULL, -- start address
+ dp_en varchar(18) default NULL, -- end address
+ nw_ip varchar(18) default NULL, -- network
+ dp_al integer default 0, -- allow unknown clients
+ dp_dn integer default 1, -- deny unknown clients
+ dc_s varchar(16) default NULL, -- allowed DHCP class
+ dp_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(dp_pk),
+ INDEX(nw_ip),
+ CONSTRAINT ci FOREIGN KEY(nw_ip) REFERENCES networks(nw_ip) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT cj FOREIGN KEY(dc_s) REFERENCES dhcpclasses(dc_s) ON UPDATE CASCADE ON DELETE RESTRICT
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- DHCP groups
+CREATE TABLE dhcpgroups(
+ dg_s varchar(16) NOT NULL, -- group name, primary key
+ dg_l varchar(64) default NULL, -- description
+ dg_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(dg_s)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- DHCP options
+CREATE TABLE dhcpoptions(
+ do_pk int(10) unsigned NOT NULL auto_increment, -- primary key
+ do_sc ENUM('server', 'vlan', 'network', 'group', 'pool', 'host') default 'server', -- scope type
+ do_sn varchar(32) default NULL, -- scope name
+ do_n varchar(64) NOT NULL, -- option name
+ do_v varchar(128) NOT NULL, -- option value
+ do_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(do_pk),
+ INDEX(do_sc),
+ INDEX(do_sn),
+ INDEX(do_n)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- hosts
+
+CREATE TABLE computers (
+ co_s varchar(16) NOT NULL default 'e__', -- hostname
+ us_s varchar(12) default NULL, -- system owner
+ co_ip varchar(18) default NULL, -- IP address
+ co_mc varchar(18) default NULL, -- MAC address
+ ng_s varchar(12) default NULL, -- netgroup
+ co_co varchar(64) default NULL, -- comment, description
+ dc_s varchar(16) default NULL, -- DHCP class
+ dg_s varchar(16) default NULL, -- DHCP group
+ dd_n varchar(16) default NULL, -- network patch socket
+ gb_s varchar(4) default NULL, -- building
+ co_r varchar(8) default NULL, -- room
+ co_in varchar(12) default NULL, -- inventory number
+ co_sn varchar(64) default NULL, -- serial number
+ co_dd varchar(64) default NULL, -- DNS domain
+ co_ff integer default 0, -- full name first flag
+ co_gu integer default 0, -- guest PC flag
+ co_hi varchar(32) default NULL, -- host ID
+ co_ex DATE default NULL, -- expiration date (for guest PCs)
+ co_nn integer default 0, -- skip host when creating network docu
+ co_na integer default 0, -- skip in arpwatch
+ co_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY (co_s),
+ INDEX(us_s),
+ INDEX(co_ip),
+ INDEX(ng_s),
+ INDEX(dc_s),
+ INDEX(dg_s),
+ INDEX(dd_n),
+ INDEX(gb_s),
+ INDEX(co_r),
+ INDEX(co_in),
+ INDEX(co_sn),
+ CONSTRAINT c7 FOREIGN KEY (us_s) REFERENCES users(us_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT c8 FOREIGN KEY (ng_s) REFERENCES netgroups(ng_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT cg FOREIGN KEY (gb_s) REFERENCES buildings(gb_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT ch FOREIGN KEY (dc_s) REFERENCES dhcpclasses(dc_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT ck FOREIGN KEY (dg_s) REFERENCES dhcpgroups(dg_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT cn FOREIGN KEY (dd_n) REFERENCES patches(dd_n) ON UPDATE CASCADE ON DELETE RESTRICT
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE aliases (
+ al_s varchar(80) NOT NULL, -- the alias
+ co_s varchar(16) default NULL, -- alias target
+ co_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(al_s),
+ INDEX(co_s),
+ CONSTRAINT co FOREIGN KEY(co_s) REFERENCES computers(co_s) ON UPDATE CASCADE ON DELETE RESTRICT
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- software manufacturers
+
+CREATE TABLE swmanufacturers (
+ sm_s varchar(16) NOT NULL, -- short name (abbreviation, key)
+ sm_l varchar(64) default '', -- full name
+ sm_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(sm_s)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- software products
+
+CREATE TABLE swproducts (
+ sw_s varchar(16) NOT NULL, -- short name (order key or abbreviation)
+ sw_l varchar(64) default '', -- full product name
+ sm_s varchar(16) default '', -- software manufacturer
+ sw_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(sw_s),
+ INDEX(sm_s),
+ CONSTRAINT c9 FOREIGN KEY (sm_s) REFERENCES swmanufacturers(sm_s) ON UPDATE CASCADE ON DELETE RESTRICT
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- software resellers
+
+CREATE TABLE swresellers (
+ sr_s varchar(16) NOT NULL, -- short name (abbreviation, key)
+ sr_l varchar(64) default '', -- full name
+ sr_a1 varchar(64) default NULL, -- address line 1
+ sr_a2 varchar(64) default NULL, -- address line 2
+ sr_a3 varchar(64) default NULL, -- address line 3
+ sr_a4 varchar(64) default NULL, -- address line 4
+ sr_plz varchar(8) default NULL, -- ZIP code
+ sr_ort varchar(64) default NULL, -- location (town or city name)
+ sr_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(sr_s)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- license types
+
+CREATE TABLE licensetypes (
+ lt_s varchar(16) NOT NULL, -- short name (abbreviation, key)
+ lt_l varchar(64) default '', -- full name of license type
+ lt_i int default 1, -- number of places for concurrent use
+ lt_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(lt_s),
+ INDEX(lt_l)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+INSERT INTO licensetypes (lt_s, lt_l, lt_i) VALUES
+('s', 'Single user user license', 1),
+('c', 'Single user concurrent license', 1),
+('flexlm', 'Flexlm controlled client installation', 1),
+('gpl2', 'GNU General Public License, version 2', 1),
+('lgpl2', 'GNU Lesser General Public License, version 2', 1),
+('gpl3', 'GNU General Public License, version 3', 1),
+('lgpl3', 'GNU Lesser General Public License, version 3', 1),
+('bsd', 'BSD style license', 1),
+('flexlm-s5', 'Flexlm license server, 5 users', 5);
+
+
+-- list of obtained licenses/installations
+
+CREATE TABLE licenses (
+ li_pk int(10) unsigned NOT NULL auto_increment,
+ li_on varchar(24) default NULL, -- internal order ID
+ sw_s varchar(16) default NULL, -- software product
+ us_s varchar(12) default NULL, -- user name of license owner
+ co_s varchar(16) default NULL, -- computer where license is used
+ lt_s varchar(16) default 's', -- license type
+ li_no varchar(64) default NULL, -- notes
+ sr_s varchar(16) default NULL, -- software reseller
+ li_dd varchar(16) default NULL, -- date of delivery
+ li_nd varchar(16) default NULL, -- delivery letter ID
+ li_di varchar(16) default NULL, -- date of invoice
+ li_ni varchar(16) default NULL, -- invoice ID
+ li_m timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY(li_pk),
+ INDEX(li_on),
+ INDEX(sw_s),
+ INDEX(us_s),
+ INDEX(co_s),
+ INDEX(lt_s),
+ INDEX(sr_s),
+ INDEX(li_dd),
+ INDEX(li_nd),
+ INDEX(li_di),
+ INDEX(li_ni),
+ CONSTRAINT ca FOREIGN KEY (sw_s) REFERENCES swproducts(sw_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT cb FOREIGN KEY (sr_s) REFERENCES swresellers(sr_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT cc FOREIGN KEY (lt_s) REFERENCES licensetypes(lt_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT cd FOREIGN KEY (us_s) REFERENCES users(us_s) ON UPDATE CASCADE ON DELETE RESTRICT,
+ CONSTRAINT ce FOREIGN KEY (co_s) REFERENCES computers(co_s) ON UPDATE CASCADE ON DELETE RESTRICT
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
diff --git a/support/dktools/dktools/print-snmp.conf b/support/dktools/dktools/print-snmp.conf
new file mode 100644
index 0000000000..a32f8c45c5
--- /dev/null
+++ b/support/dktools/dktools/print-snmp.conf
@@ -0,0 +1,174 @@
+#
+# The first ``default'' entry shows the built-in default
+# configuration.
+# It may be used as a template to construct your own models.
+#
+
+[default]
+
+# Phase 1: Mapping device/printer status to summary states
+# --------------------------------------------------------
+
+map = unknown/other unknown
+map = unknown/unknown unknown
+map = unknown/idle unknown
+map = unknown/printing unknown
+map = unknown/warmup warmup
+
+map = running/other standby
+map = running/unknown unknown
+map = running/idle idle
+map = running/printing busy
+map = running/warmup warmup
+
+map = warning/other standby
+map = warning/unknown unknown
+map = warning/idle idle
+map = warning/printing busy
+map = warning/warmup warmup
+
+map = testing/other unknown
+map = testing/unknown unknown
+map = testing/idle unknown
+map = testing/printing unknown
+map = testing/warmup warmup
+
+map = down/other error
+map = down/unknown error
+map = down/idle error
+map = down/printing error
+map = down/warmup warmup
+
+# Phase 2: Setting summary state to error for specified conditions
+# ----------------------------------------------------------------
+
+# Appearance of an error condition will interrupt printing.
+
+# Printer attempts to print, but no paper available.
+error condition = no-paper
+
+# Printer attempts to print, but no toner available.
+error condition = no-toner
+
+# Printer opened.
+error condition = door-open
+
+# Paper jam.
+error condition = paper-jam
+
+# Printer is offline (not working).
+error condition = offline
+
+# Input tray removed (i.e. to fill it).
+error condition = input-tray-missing
+
+# Output tray removed.
+error condition = output-tray-missing
+
+# Marker removed.
+error condition = marker-supply-missing
+
+# Output tray is full.
+error condition = output-full
+
+
+# Although the following conditions are referred to as error conditions
+# in RFC, they will not interrupt printing.
+# So we see them as warnings, not errors.
+
+# Only low amount of paper available, will become ``out of paper'' soon.
+# error condition = low-paper
+
+# Only low amount of toner available, will become ``out of toner'' soon.
+# error condition = low-toner
+
+# At least one input tray is empty.
+# error condition = input-tray-empty
+
+# Output tray is nearly full, will become full soon.
+# error condition = output-near-full
+
+# Service is requested, may be you need to press a button on the printer.
+# error condition = service-requested
+
+# Preventive maintenance required.
+# error condition = overdue-preventive-maintenance
+
+
+# Phase 3: For summary unknown use the text status OID
+------------------------------------------------------
+
+# OID to inspect for status text, _must_ be numeric.
+status text oid = 1.3.6.1.2.1.43.16.5.1.2.1.1
+
+# No texts are set up here as the texts are vendor, model and
+# language specific.
+# Use ``text standby'', ``start standby'', ``text idle'' or ``start idle''
+# to specify texts indicating standby or idle summary state.
+# Use ``start'' if you do not specify the entire text, but only
+# the first part of the status text.
+# Specify the string either in double quotes or as a hexadecimal byte sequence.
+
+# text standby = "Power Save"
+# text standby = 50 6F 77 65 72 20 53 61 76 65
+# text idle = " Druckbereit"
+# start idle = 20 20 20 20 20 20 20 20 44 72 75 63 6B
+
+
+#
+# The following model is a Xerox Phaser 4622 configured
+# for german language.
+#
+
+[xph4622-de]
+
+# Map device status / printer status combinations to summary states.
+#
+map = unknown/other unknown
+map = unknown/unknown unknown
+map = unknown/idle unknown
+map = unknown/printing unknown
+map = unknown/warmup warmup
+map = running/other unknown
+map = running/unknown unknown
+map = running/idle unknown
+map = running/printing unknown
+map = running/warmup warmup
+map = warning/other unknown
+map = warning/unknown unknown
+map = warning/idle unknown
+map = warning/printing unknown
+map = warning/warmup warmup
+map = testing/other unknown
+map = testing/unknown unknown
+map = testing/idle unknown
+map = testing/printing unknown
+map = testing/warmup warmup
+map = down/other error
+map = down/unknown error
+map = down/idle error
+map = down/printing error
+map = down/warmup warmup
+
+text standby = "Power Save"
+
+text idle = " Druckbereit"
+
+# Druckbereit
+start idle = 20 20 20 20 20 20 20 20 44 72 75 63 6B
+
+text busy = "Drucken"
+
+# Behaelter 2
+start error = 42 65 68 C3 A4 6C 74 65 72 20 32
+
+# Behaelter 2 ...
+start error = 20 20 20 20 20 20 42 65 68 C3 A4 6C 74 65 72 20 32
+
+# Fehler
+text error = "Fehler"
+
+start error = " Schacht 1"
+
+start error = "Angehalten"
+
diff --git a/support/dktools/dkwt-ac.c b/support/dktools/dkwt-ac.c
new file mode 100644
index 0000000000..cf5c13f4b3
--- /dev/null
+++ b/support/dktools/dkwt-ac.c
@@ -0,0 +1,411 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dkwt-ac.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dkwt-ac.c The dkwt-ac module.
+*/
+
+
+#line 10 "dkwt-ac.ctr"
+
+#include "dk3all.h"
+#include "dkt.h"
+#include "dkwt.h"
+
+
+
+
+
+#line 18 "dkwt-ac.ctr"
+
+
+
+/** Job structure for dkwt accounts.
+*/
+typedef struct {
+ dk3_app_t *app; /**< Application structure. */
+ dkChar const * const *msg; /**< Localized message texts. */
+ dkChar const * const *kwnl; /**< Keywords, not localized. */
+ dk3_option_set_t *opt; /**< Options set. */
+ int f_long; /**< Flag: Long user listing. */
+ int exval; /**< Exit status code. */
+} DKWT_ACC_J;
+
+
+
+/** Account flag description.
+*/
+typedef struct {
+ DWORD dw; /**< Binary flag. */
+ size_t msgi; /**< Index of description text. */
+} DKWT_ACC_FLAG;
+
+
+
+/** Data for the option set.
+*/
+static dk3_option_t const dkwt_accounts_options[] = {
+ { dkT('l'), dkT("long"), 0 },
+ { dkT('s'), dkT("short"), 0 }
+};
+
+/** Number of options in the dkt_sort_options array.
+*/
+static size_t const dkwt_accounts_szoptions =
+sizeof(dkwt_accounts_options)/sizeof(dk3_option_t);
+
+
+
+/** Connection of account flags and text array indices.
+*/
+static const DKWT_ACC_FLAG dkwt_accounts_flags[] = {
+ { UF_NORMAL_ACCOUNT, 26 },
+ { UF_TEMP_DUPLICATE_ACCOUNT, 27 },
+ { UF_WORKSTATION_TRUST_ACCOUNT, 28 },
+ { UF_SERVER_TRUST_ACCOUNT, 29 },
+ { UF_INTERDOMAIN_TRUST_ACCOUNT, 30 },
+ { UF_TRUSTED_FOR_DELEGATION, 23 },
+ { UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION, 25 },
+ { UF_ACCOUNTDISABLE, 12 },
+ { UF_LOCKOUT, 16 },
+ { UF_PASSWD_NOTREQD, 14 },
+ { UF_PASSWD_CANT_CHANGE, 15 },
+ { UF_PASSWORD_EXPIRED, 24 },
+ { UF_DONT_EXPIRE_PASSWD, 17 },
+ { UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED, 18 },
+ { UF_NOT_DELEGATED, 19 },
+ { UF_SMARTCARD_REQUIRED, 20 },
+ { UF_USE_DES_KEY_ONLY, 21 },
+ { UF_DONT_REQUIRE_PREAUTH, 22 },
+ { UF_SCRIPT, 11 },
+ { UF_HOMEDIR_REQUIRED, 13 },
+};
+
+
+
+/** Connection of operator account flags and text array indices.
+*/
+static const DKWT_ACC_FLAG dkwt_accounts_operator[] = {
+ { AF_OP_ACCOUNTS, 33 },
+ { AF_OP_SERVER, 34 },
+ { AF_OP_COMM, 35 },
+ { AF_OP_PRINT, 36 }
+};
+
+
+/** Initialize job structure.
+ @param j Job structure.
+*/
+static
+void
+dkwt_accounts_job_init(DKWT_ACC_J *j)
+{
+ j->app = NULL; j->msg = NULL; j->kwnl = NULL; j->opt = NULL;
+ j->f_long = 1; j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+}
+
+
+
+
+/** Clean up job structure after use.
+ @param j Job structure.
+*/
+static
+void
+dkwt_accounts_job_cleanup(DKWT_ACC_J *j)
+{
+ if(j->opt) {
+ dk3opt_close(j->opt);
+ } j->opt = NULL;
+}
+
+
+
+/** Process command line arguments.
+ @param j Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkwt_accounts_process_argv(DKWT_ACC_J *j)
+{
+ int back = 0;
+ int xargc;
+ dkChar const * const *xargv;
+ xargc = dk3app_get_argc(j->app);
+ xargv = dk3app_get_argv(j->app);
+ xargv++; xargv++; xargc--; xargc--;
+ j->opt = dk3opt_open_app(
+ dkwt_accounts_options,
+ dkwt_accounts_szoptions,
+ dkT('\0'),
+ NULL,
+ xargc,
+ xargv,
+ j->app
+ );
+ if(j->opt) {
+ if(0 == dk3opt_get_error_code(j->opt)) {
+ back = 1;
+ if(dk3opt_is_set(j->opt, dkT('l'))) {
+ j->f_long = 2;
+ if(dk3opt_is_set(j->opt, dkT('s'))) {
+ back = 0;
+ /* ERROR: -l and -s are exclusive. */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 75);
+ }
+ } else {
+ if(dk3opt_is_set(j->opt, dkT('s'))) {
+ j->f_long = 0;
+ }
+ }
+ if(dk3opt_get_num_args(j->opt) > 0) {
+ /* Warning: Arguments ignored. */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 76);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Report one detail about an account.
+ @param msg Array containing localized texts.
+ @param imsg Index of attribute name.
+ @param dettxt Description text.
+*/
+static
+void
+dkwt_ac_detail(dkChar const * const *msg, size_t imsg, dkChar const *dettxt)
+{
+ dk3sf_fputs(msg[imsg], stdout);
+ dk3sf_fputc(dkT(' '), stdout);
+ dk3sf_fputs(dettxt, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+}
+
+
+
+/** Report user type for account.
+ @param j Job structure.
+ @param n Index of user type name in message text array.
+*/
+static
+void
+dkwt_accounts_user_type(DKWT_ACC_J *j, size_t n)
+{
+ dk3sf_fputs((j->msg)[6], stdout);
+ dk3sf_fputc(dkT(' '), stdout);
+ dk3sf_fputs((j->msg)[n], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+}
+
+
+
+/** Show flags for an account.
+ @param j Job structure.
+ @param dw Flag set for account.
+ @param jarr Private account flag set.
+ @param sarr Number of inspections.
+ @param itext Index in text array.
+*/
+static
+void
+dkwt_accounts_show_flags(
+ DKWT_ACC_J *j,
+ DWORD dw,
+ DKWT_ACC_FLAG const *jarr,
+ size_t sarr,
+ size_t itext
+)
+{
+ int is_first = 1;
+ DKWT_ACC_FLAG const *fptr;
+ size_t i;
+
+ fptr = jarr;
+ for(i = 0; i < sarr; i++) {
+ if((dw) & (fptr->dw)) {
+ dk3sf_fputs((j->msg)[(is_first) ? itext : 10], stdout);
+ dk3sf_fputc(dkT(' '), stdout);
+ dk3sf_fputs((j->msg)[fptr->msgi], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ is_first = 0;
+ }
+ fptr++;
+ }
+}
+
+
+
+/** Show a numeric value.
+ @param j Job structure.
+ @param imsg Index in message text array.
+ @param val Value to show.
+*/
+static
+void
+dkwt_ac_numeric(DKWT_ACC_J *j, size_t imsg, DWORD val)
+{
+ dkChar b1[64];
+ dkChar b2[DK3_SIZEOF(b1,dkChar)];
+
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(b1, dkT("%lu"), (unsigned long)val);
+ dk3sf_sprintf3(b2, dkT("(%lx)"), (unsigned long)val);
+#else
+ if (0 == dk3ma_um_to_string(b1, DK3_SIZEOF(b1,dkChar), (dk3_um_t)val)) {
+ b1[0] = dkT('\0');
+ }
+ if (0 == dk3ma_um_to_hex_string(b2, DK3_SIZEOF(b2,dkChar),(dk3_um_t)val,0)) {
+ b2[0] = dkT('\0');
+ }
+#endif
+ dk3sf_fputs((j->msg)[imsg], stdout);
+ dk3sf_fputc(dkT(' '), stdout);
+ dk3sf_fputs(b1, stdout);
+ dk3sf_fputc(dkT(' '), stdout);
+ dk3sf_fputs(b2, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+}
+
+
+
+/** Do the accounts listing.
+ @param j Job structure.
+*/
+static
+void
+dkwt_accounts_run(DKWT_ACC_J *j)
+{
+ dkwt_account_list_t *al;
+ dkwt_account_t *ac;
+ int found = 0;
+ size_t namelgt;
+ size_t i;
+ al = dkwt_tool_open_account_list(j->app, j->f_long);
+ if(al) {
+ j->exval = DKT_RESULT_OK;
+ dk3sf_initialize_stdout();
+ dkwt_tool_reset_account_list(al);
+ while((ac = dkwt_tool_get_account_from_list(al)) != NULL) {
+ if((found) && (j->f_long)) {
+ dk3sf_fputc(dkT('\n'), stdout);
+ } found = 1;
+ if(ac->logname) {
+ dk3sf_fputs(ac->logname, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ if(j->f_long) {
+ namelgt = dk3str_len(ac->logname);
+ for(i = 0; i < namelgt; i++) dk3sf_fputc(dkT('-'), stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ if(ac->textsid) {
+ dkwt_ac_detail(j->msg, 5, ac->textsid);
+ }
+ if((j->f_long > 1) && (ac->f_long)) {
+ switch(ac->priv) {
+ case USER_PRIV_GUEST: {
+ dkwt_accounts_user_type(j, 7);
+ } break;
+ case USER_PRIV_USER: {
+ dkwt_accounts_user_type(j, 8);
+ } break;
+ case USER_PRIV_ADMIN: {
+ dkwt_accounts_user_type(j, 9);
+ } break;
+ }
+ dkwt_accounts_show_flags(
+ j,
+ ac->flags,
+ dkwt_accounts_flags,
+ sizeof(dkwt_accounts_flags)/sizeof(DKWT_ACC_FLAG),
+ 10
+ );
+ dkwt_accounts_show_flags(
+ j,
+ ac->a_flags,
+ dkwt_accounts_operator,
+ sizeof(dkwt_accounts_operator)/sizeof(DKWT_ACC_FLAG),
+ 32
+ );
+ }
+ if(ac->fullname) {
+ dkwt_ac_detail(j->msg, 0, ac->fullname);
+ }
+ if(ac->comment) {
+ dkwt_ac_detail(j->msg, 1, ac->comment);
+ }
+ if(ac->usrcomment) {
+ dkwt_ac_detail(j->msg, 2, ac->usrcomment);
+ }
+ if(ac->homedir) {
+ dkwt_ac_detail(j->msg, 3, ac->homedir);
+ }
+ if(ac->profile) {
+ dkwt_ac_detail(j->msg, 4, ac->profile);
+ }
+ if((j->f_long > 1) && (ac->f_long)) {
+ dkwt_ac_numeric(j, 37, ac->coco);
+ dkwt_ac_numeric(j, 38, ac->codepage);
+ }
+ }
+ }
+ }
+ dkwt_tool_close_account_list(al);
+ }
+}
+
+
+
+int
+dkwt_accounts(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl
+)
+{
+ int back = DKT_RESULT_ERR_UNSPECIFIC;
+ DKWT_ACC_J j;
+ dkwt_accounts_job_init(&j);
+ j.app = app; j.msg = msg; j.kwnl = kwnl;
+ if(dkwt_accounts_process_argv(&j)) {
+ back = j.exval = DKT_RESULT_OK;
+ dkwt_accounts_run(&j);
+ }
+ dkwt_accounts_job_cleanup(&j);
+ return back;
+}
+
+
diff --git a/support/dktools/dkwt-ac.ctr b/support/dktools/dkwt-ac.ctr
new file mode 100644
index 0000000000..710076e19e
--- /dev/null
+++ b/support/dktools/dkwt-ac.ctr
@@ -0,0 +1,378 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk3all.h"
+#include "dkt.h"
+#include "dkwt.h"
+
+
+
+$!trace-include
+
+
+
+/** Job structure for dkwt accounts.
+*/
+typedef struct {
+ dk3_app_t *app; /**< Application structure. */
+ dkChar const * const *msg; /**< Localized message texts. */
+ dkChar const * const *kwnl; /**< Keywords, not localized. */
+ dk3_option_set_t *opt; /**< Options set. */
+ int f_long; /**< Flag: Long user listing. */
+ int exval; /**< Exit status code. */
+} DKWT_ACC_J;
+
+
+
+/** Account flag description.
+*/
+typedef struct {
+ DWORD dw; /**< Binary flag. */
+ size_t msgi; /**< Index of description text. */
+} DKWT_ACC_FLAG;
+
+
+
+/** Data for the option set.
+*/
+static dk3_option_t const dkwt_accounts_options[] = {
+ { dkT('l'), dkT("long"), 0 },
+ { dkT('s'), dkT("short"), 0 }
+};
+
+/** Number of options in the dkt_sort_options array.
+*/
+static size_t const dkwt_accounts_szoptions =
+sizeof(dkwt_accounts_options)/sizeof(dk3_option_t);
+
+
+
+/** Connection of account flags and text array indices.
+*/
+static const DKWT_ACC_FLAG dkwt_accounts_flags[] = {
+ { UF_NORMAL_ACCOUNT, 26 },
+ { UF_TEMP_DUPLICATE_ACCOUNT, 27 },
+ { UF_WORKSTATION_TRUST_ACCOUNT, 28 },
+ { UF_SERVER_TRUST_ACCOUNT, 29 },
+ { UF_INTERDOMAIN_TRUST_ACCOUNT, 30 },
+ { UF_TRUSTED_FOR_DELEGATION, 23 },
+ { UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION, 25 },
+ { UF_ACCOUNTDISABLE, 12 },
+ { UF_LOCKOUT, 16 },
+ { UF_PASSWD_NOTREQD, 14 },
+ { UF_PASSWD_CANT_CHANGE, 15 },
+ { UF_PASSWORD_EXPIRED, 24 },
+ { UF_DONT_EXPIRE_PASSWD, 17 },
+ { UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED, 18 },
+ { UF_NOT_DELEGATED, 19 },
+ { UF_SMARTCARD_REQUIRED, 20 },
+ { UF_USE_DES_KEY_ONLY, 21 },
+ { UF_DONT_REQUIRE_PREAUTH, 22 },
+ { UF_SCRIPT, 11 },
+ { UF_HOMEDIR_REQUIRED, 13 },
+};
+
+
+
+/** Connection of operator account flags and text array indices.
+*/
+static const DKWT_ACC_FLAG dkwt_accounts_operator[] = {
+ { AF_OP_ACCOUNTS, 33 },
+ { AF_OP_SERVER, 34 },
+ { AF_OP_COMM, 35 },
+ { AF_OP_PRINT, 36 }
+};
+
+
+/** Initialize job structure.
+ @param j Job structure.
+*/
+static
+void
+dkwt_accounts_job_init(DKWT_ACC_J *j)
+{
+ j->app = NULL; j->msg = NULL; j->kwnl = NULL; j->opt = NULL;
+ j->f_long = 1; j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+}
+
+
+
+
+/** Clean up job structure after use.
+ @param j Job structure.
+*/
+static
+void
+dkwt_accounts_job_cleanup(DKWT_ACC_J *j)
+{
+ if(j->opt) {
+ dk3opt_close(j->opt);
+ } j->opt = NULL;
+}
+
+
+
+/** Process command line arguments.
+ @param j Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkwt_accounts_process_argv(DKWT_ACC_J *j)
+{
+ int back = 0;
+ int xargc;
+ dkChar const * const *xargv;
+ xargc = dk3app_get_argc(j->app);
+ xargv = dk3app_get_argv(j->app);
+ xargv++; xargv++; xargc--; xargc--;
+ j->opt = dk3opt_open_app(
+ dkwt_accounts_options,
+ dkwt_accounts_szoptions,
+ dkT('\0'),
+ NULL,
+ xargc,
+ xargv,
+ j->app
+ );
+ if(j->opt) {
+ if(0 == dk3opt_get_error_code(j->opt)) {
+ back = 1;
+ if(dk3opt_is_set(j->opt, dkT('l'))) {
+ j->f_long = 2;
+ if(dk3opt_is_set(j->opt, dkT('s'))) {
+ back = 0;
+ /* ERROR: -l and -s are exclusive. */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 75);
+ }
+ } else {
+ if(dk3opt_is_set(j->opt, dkT('s'))) {
+ j->f_long = 0;
+ }
+ }
+ if(dk3opt_get_num_args(j->opt) > 0) {
+ /* Warning: Arguments ignored. */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 76);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Report one detail about an account.
+ @param msg Array containing localized texts.
+ @param imsg Index of attribute name.
+ @param dettxt Description text.
+*/
+static
+void
+dkwt_ac_detail(dkChar const * const *msg, size_t imsg, dkChar const *dettxt)
+{
+ dk3sf_fputs(msg[imsg], stdout);
+ dk3sf_fputc(dkT(' '), stdout);
+ dk3sf_fputs(dettxt, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+}
+
+
+
+/** Report user type for account.
+ @param j Job structure.
+ @param n Index of user type name in message text array.
+*/
+static
+void
+dkwt_accounts_user_type(DKWT_ACC_J *j, size_t n)
+{
+ dk3sf_fputs((j->msg)[6], stdout);
+ dk3sf_fputc(dkT(' '), stdout);
+ dk3sf_fputs((j->msg)[n], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+}
+
+
+
+/** Show flags for an account.
+ @param j Job structure.
+ @param dw Flag set for account.
+ @param jarr Private account flag set.
+ @param sarr Number of inspections.
+ @param itext Index in text array.
+*/
+static
+void
+dkwt_accounts_show_flags(
+ DKWT_ACC_J *j,
+ DWORD dw,
+ DKWT_ACC_FLAG const *jarr,
+ size_t sarr,
+ size_t itext
+)
+{
+ int is_first = 1;
+ DKWT_ACC_FLAG const *fptr;
+ size_t i;
+
+ fptr = jarr;
+ for(i = 0; i < sarr; i++) {
+ if((dw) & (fptr->dw)) {
+ dk3sf_fputs((j->msg)[(is_first) ? itext : 10], stdout);
+ dk3sf_fputc(dkT(' '), stdout);
+ dk3sf_fputs((j->msg)[fptr->msgi], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ is_first = 0;
+ }
+ fptr++;
+ }
+}
+
+
+
+/** Show a numeric value.
+ @param j Job structure.
+ @param imsg Index in message text array.
+ @param val Value to show.
+*/
+static
+void
+dkwt_ac_numeric(DKWT_ACC_J *j, size_t imsg, DWORD val)
+{
+ dkChar b1[64];
+ dkChar b2[DK3_SIZEOF(b1,dkChar)];
+
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(b1, dkT("%lu"), (unsigned long)val);
+ dk3sf_sprintf3(b2, dkT("(%lx)"), (unsigned long)val);
+#else
+ if (0 == dk3ma_um_to_string(b1, DK3_SIZEOF(b1,dkChar), (dk3_um_t)val)) {
+ b1[0] = dkT('\0');
+ }
+ if (0 == dk3ma_um_to_hex_string(b2, DK3_SIZEOF(b2,dkChar),(dk3_um_t)val,0)) {
+ b2[0] = dkT('\0');
+ }
+#endif
+ dk3sf_fputs((j->msg)[imsg], stdout);
+ dk3sf_fputc(dkT(' '), stdout);
+ dk3sf_fputs(b1, stdout);
+ dk3sf_fputc(dkT(' '), stdout);
+ dk3sf_fputs(b2, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+}
+
+
+
+/** Do the accounts listing.
+ @param j Job structure.
+*/
+static
+void
+dkwt_accounts_run(DKWT_ACC_J *j)
+{
+ dkwt_account_list_t *al;
+ dkwt_account_t *ac;
+ int found = 0;
+ size_t namelgt;
+ size_t i;
+ al = dkwt_tool_open_account_list(j->app, j->f_long);
+ if(al) {
+ j->exval = DKT_RESULT_OK;
+ dk3sf_initialize_stdout();
+ dkwt_tool_reset_account_list(al);
+ while((ac = dkwt_tool_get_account_from_list(al)) != NULL) {
+ if((found) && (j->f_long)) {
+ dk3sf_fputc(dkT('\n'), stdout);
+ } found = 1;
+ if(ac->logname) {
+ dk3sf_fputs(ac->logname, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ if(j->f_long) {
+ namelgt = dk3str_len(ac->logname);
+ for(i = 0; i < namelgt; i++) dk3sf_fputc(dkT('-'), stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ if(ac->textsid) {
+ dkwt_ac_detail(j->msg, 5, ac->textsid);
+ }
+ if((j->f_long > 1) && (ac->f_long)) {
+ switch(ac->priv) {
+ case USER_PRIV_GUEST: {
+ dkwt_accounts_user_type(j, 7);
+ } break;
+ case USER_PRIV_USER: {
+ dkwt_accounts_user_type(j, 8);
+ } break;
+ case USER_PRIV_ADMIN: {
+ dkwt_accounts_user_type(j, 9);
+ } break;
+ }
+ dkwt_accounts_show_flags(
+ j,
+ ac->flags,
+ dkwt_accounts_flags,
+ sizeof(dkwt_accounts_flags)/sizeof(DKWT_ACC_FLAG),
+ 10
+ );
+ dkwt_accounts_show_flags(
+ j,
+ ac->a_flags,
+ dkwt_accounts_operator,
+ sizeof(dkwt_accounts_operator)/sizeof(DKWT_ACC_FLAG),
+ 32
+ );
+ }
+ if(ac->fullname) {
+ dkwt_ac_detail(j->msg, 0, ac->fullname);
+ }
+ if(ac->comment) {
+ dkwt_ac_detail(j->msg, 1, ac->comment);
+ }
+ if(ac->usrcomment) {
+ dkwt_ac_detail(j->msg, 2, ac->usrcomment);
+ }
+ if(ac->homedir) {
+ dkwt_ac_detail(j->msg, 3, ac->homedir);
+ }
+ if(ac->profile) {
+ dkwt_ac_detail(j->msg, 4, ac->profile);
+ }
+ if((j->f_long > 1) && (ac->f_long)) {
+ dkwt_ac_numeric(j, 37, ac->coco);
+ dkwt_ac_numeric(j, 38, ac->codepage);
+ }
+ }
+ }
+ }
+ dkwt_tool_close_account_list(al);
+ }
+}
+
+
+
+int
+dkwt_accounts(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl
+)
+{
+ int back = DKT_RESULT_ERR_UNSPECIFIC;
+ DKWT_ACC_J j;
+ dkwt_accounts_job_init(&j);
+ j.app = app; j.msg = msg; j.kwnl = kwnl;
+ if(dkwt_accounts_process_argv(&j)) {
+ back = j.exval = DKT_RESULT_OK;
+ dkwt_accounts_run(&j);
+ }
+ dkwt_accounts_job_cleanup(&j);
+ return back;
+}
+
+
diff --git a/support/dktools/dkwt-cp.c b/support/dktools/dkwt-cp.c
new file mode 100644
index 0000000000..ea5e90fea5
--- /dev/null
+++ b/support/dktools/dkwt-cp.c
@@ -0,0 +1,793 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dkwt-cp.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dkwt-cp.c The dkwt-cp module.
+*/
+
+
+#line 10 "dkwt-cp.ctr"
+
+/** No warnings from WinSock about deprecated functions.
+*/
+#define _WINSOCK_DEPRECATED_NO_WARNINGS 1
+
+#include "dk3all.h"
+#include "dkt.h"
+#include "dkwt.h"
+
+
+
+
+
+#line 22 "dkwt-cp.ctr"
+
+
+/** Buffer size to enumerate printers.
+*/
+#define DKWT_PRINTER_ENUM_BUFFER_SIZE 1024
+
+/** Buffer size to enumerate print jobs.
+*/
+#define DKWT_PRINTER_ENUM_JOBS_SIZE 8192
+
+/** Number of print jobs to show in one request.
+*/
+#define DKWT_PRINTER_NUMBER_OF_JOBS 64
+
+
+/** Local print queue.
+*/
+typedef struct {
+ dkChar *qn; /**< Queue name. */
+} DKWT_CP_QUEUE;
+
+
+
+/** Print job.
+*/
+typedef struct {
+ DWORD jobId; /**< Job ID. */
+ DWORD pos; /**< Position in queue. */
+ dkChar const *docName; /**< Print job name. */
+} DKWT_CP_JOB;
+
+
+
+/** Compare two print queues by name.
+ @param l Left object.
+ @param r Right object.
+ @param cr Comparison criteria (0=queue/queue, 1=queue/name)
+ @return Comparison result.
+*/
+static
+int
+dkwt_cp_queue_comp(void const *l, void const *r, int cr)
+{
+ DKWT_CP_QUEUE const *ql;
+ DKWT_CP_QUEUE const *qr;
+ int back = 0;
+ if(l) {
+ if(r) {
+ ql = (DKWT_CP_QUEUE const *)l;
+ switch(cr) {
+ case 1: {
+ if(ql->qn) {
+ back = dk3str_casecmp(ql->qn, (dkChar const *)r);
+ if(back < -1) back = -1;
+ if(back > 1) back = 1;
+ } else back = -1;
+ } break;
+ default: {
+ qr = (DKWT_CP_QUEUE const *)r;
+ if(ql->qn) {
+ if(qr->qn) {
+ back = dk3str_casecmp(ql->qn, qr->qn);
+ if(back < -1) back = -1;
+ if(back > 1) back = 1;
+ } else back = 1;
+ } else {
+ if(qr->qn) back = -1;
+ }
+ } break;
+ }
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ }
+ return back;
+}
+
+
+
+/** Destroy queue structure, release memory.
+ @param q Queue structure to destroy.
+*/
+static
+void
+dkwt_cp_queue_del(DKWT_CP_QUEUE *q)
+{
+ if(q) {
+ dk3_release(q->qn);
+ dk3_delete(q);
+ }
+}
+
+
+
+/** Create queue structure, allocate memory.
+ @param app Application structure for diagnostics, may be NULL.
+ @param n Queue name.
+ @return Pointer to new structure on success, NULL on error.
+*/
+static
+DKWT_CP_QUEUE *
+dkwt_cp_queue_new(dk3_app_t *app, dkChar const *n)
+{
+ DKWT_CP_QUEUE *back = NULL;
+ if(n) {
+ back = dk3_new_app(DKWT_CP_QUEUE,1,app);
+ if(back) {
+ back->qn = NULL;
+ back->qn = dk3str_dup_app(n, app);
+ if(!(back->qn)) {
+ dkwt_cp_queue_del(back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Destroy job structure, release memory.
+ @param j Job structure to delete.
+*/
+static
+void
+dkwt_cp_job_del(DKWT_CP_JOB *j)
+{
+ if(j) {
+ dk3_release(j->docName);
+ j->jobId = 0;
+ j->pos = 0;
+ dk3_delete(j);
+ }
+}
+
+
+
+/** Create new job structure, allocate memory.
+ @param app Application structure for diagnostics.
+ @param jobid Job ID.
+ @param pos Job position in the queue.
+ @param dn Document name.
+ @return Pointer to new structure on success, NULL on error.
+*/
+static
+DKWT_CP_JOB *
+dkwt_cp_job_new(dk3_app_t *app, DWORD jobid, DWORD pos, dkChar const *dn)
+{
+ DKWT_CP_JOB *back = NULL;
+ back = dk3_new_app(DKWT_CP_JOB,1,app);
+ if(back) {
+ back->docName = NULL;
+ back->jobId = jobid;
+ back->pos = pos;
+ if(dn) {
+ back->docName = dk3str_dup_app(dn, app);
+ if(!(back->docName)) {
+ dkwt_cp_job_del(back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Compare 2 jobs to find which one to delete first.
+ @param l Left job.
+ @param r Right job.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result, jobs with higher position are deleted first.
+*/
+static
+int
+dkwt_cp_job_comp(void const *l, void const *r, int cr)
+{
+ DKWT_CP_JOB const *jl;
+ DKWT_CP_JOB const *jr;
+ int back = 0;
+ if(l) {
+ if(r) {
+ jl = (DKWT_CP_JOB const *)l;
+ jr = (DKWT_CP_JOB const *)r;
+ if(jl->pos < jr->pos) {
+ back = 1;
+ } else {
+ if(jl->pos > jr->pos) {
+ back = -1;
+ }
+ }
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ }
+ return back;
+}
+
+
+
+
+/** Remove all print jobs for one user from a single queue.
+ @param app Application structure for diagnostics.
+ @param msg Localized message texts.
+ @param kwnl Keywords, not localized.
+ @param userName User name.
+ @param hostName Host name.
+ @param queue Queue to modify.
+*/
+static
+void
+dkwt_cp_remove_all_jobs(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl,
+ dkChar const *userName,
+ dkChar const *hostName,
+ DKWT_CP_QUEUE *queue
+)
+{
+ char jeb[DKWT_PRINTER_ENUM_JOBS_SIZE]; /* Enum buffer. */
+ dkChar idbuf[64];
+ dk3_sto_t *s_j; /* Jobs storage. */
+ dk3_sto_it_t *i_j; /* Iterator for jobs storage. */
+ JOB_INFO_1 *ji1; /* Job information pointer. */
+ DKWT_CP_JOB *job; /* Current job. */
+ HANDLE hPrinter; /* Handle for printer. */
+ DWORD szjeb; /* Size of jeb buffer. */
+ DWORD bneed; /* Bytes needed. */
+ DWORD nj; /* Number of jobs found. */
+ DWORD i; /* Index of current job to process. */
+ int rmj; /* Flag: Remove this job. */
+ BOOL res; /* Operation result. */
+
+
+#line 256 "dkwt-cp.ctr"
+ s_j = NULL; i_j = NULL;
+ s_j = dk3sto_open_app(app);
+ if(s_j) {
+ dk3sto_set_comp(s_j, dkwt_cp_job_comp, 0);
+ i_j = dk3sto_it_open(s_j);
+ }
+ if((s_j) && (i_j)) {
+ /* PROGRESS: Cleaning up local queue... */
+ dk3app_log_3(app, DK3_LL_PROGRESS, msg, 83, 84, queue->qn);
+#if DK3_CHAR_SIZE > 1
+ res = OpenPrinterW(queue->qn, &hPrinter, NULL);
+#else
+ res = OpenPrinterA(queue->qn, &hPrinter, NULL);
+#endif
+ if(res) {
+ /* Enumerate print jobs, save jobs to delete.
+ */
+ szjeb = sizeof(jeb); bneed = 0; nj = 0;
+#if DK3_CHAR_SIZE > 1
+ res = EnumJobsW(
+ hPrinter, 0, DKWT_PRINTER_NUMBER_OF_JOBS, 1, (LPBYTE)jeb, szjeb,
+ &bneed, &nj
+ );
+#else
+ res = EnumJobsA(
+ hPrinter, 0, DKWT_PRINTER_NUMBER_OF_JOBS, 1, (LPBYTE)jeb, szjeb,
+ &bneed, &nj
+ );
+#endif
+ if(res) {
+
+#line 286 "dkwt-cp.ctr"
+ if(nj > 0) {
+
+#line 287 "dkwt-cp.ctr"
+ ji1 = (JOB_INFO_1 *)jeb;
+ for(i = 0; i < nj; i++) {
+ rmj = 0;
+ if(ji1[i].pUserName) {
+
+#line 291 "dkwt-cp.ctr"
+ if(0 == dk3str_casecmp(ji1[i].pUserName, userName)) {
+
+#line 292 "dkwt-cp.ctr"
+ rmj = 1;
+ if(hostName) {
+
+#line 294 "dkwt-cp.ctr"
+ rmj = 0;
+ if(ji1[i].pMachineName) {
+
+#line 296 "dkwt-cp.ctr"
+ if(0 == dk3str_casecmp(ji1[i].pMachineName, hostName)) {
+
+#line 297 "dkwt-cp.ctr"
+ rmj = 1;
+ } else {
+ if(dkT('\\') == (ji1[i].pMachineName)[0]) {
+ if(dkT('\\') == (ji1[i].pMachineName)[1]) {
+ if(0 == dk3str_casecmp(&((ji1[i].pMachineName)[2]), hostName)) {
+ rmj = 1;
+ }
+ }
+ }
+ }
+ } else {
+
+#line 308 "dkwt-cp.ctr"
+ rmj = 1;
+ }
+ } else {
+
+#line 311 "dkwt-cp.ctr"
+ }
+ } else {
+
+#line 313 "dkwt-cp.ctr"
+ }
+ }
+ if(rmj) {
+
+#line 316 "dkwt-cp.ctr"
+ job = dkwt_cp_job_new(app, ji1[i].JobId, ji1[i].Position, ji1[i].pDocument);
+ if(job) {
+ if(!dk3sto_add(s_j, (void *)job)) {
+
+#line 319 "dkwt-cp.ctr"
+ dkwt_cp_job_del(job);
+ } else {
+ }
+ } else {
+
+#line 323 "dkwt-cp.ctr"
+ }
+ }
+ }
+ } else {
+
+#line 327 "dkwt-cp.ctr"
+ }
+ } else {
+
+#line 329 "dkwt-cp.ctr"
+ }
+ /* Delete saved print jobs if any.
+ */
+ dk3sto_it_reset(i_j);
+ while(NULL != (job = (DKWT_CP_JOB *)dk3sto_it_next(i_j))) {
+
+
+#line 335 "dkwt-cp.ctr"
+#if VERSION_20140716
+ dk3sf_sprintf3(idbuf, dkT("%lu"), (unsigned long)(job->jobId));
+#else
+ if (!(dk3ma_um_to_string(idbuf, DK3_SIZEOF(idbuf,dkChar), (dk3_um_t)(job->jobId)))) {
+ idbuf[0] = dkT('\0');
+ }
+#endif
+ if(SetJob(hPrinter, job->jobId, 0, NULL, JOB_CONTROL_DELETE)) {
+ /* PROGRESS: Print job deleted. */
+
+#line 344 "dkwt-cp.ctr"
+ dk3app_log_5(
+ app, DK3_LL_PROGRESS, msg, 85, 86, 87, idbuf,
+ ((job->docName) ? (job->docName) : msg[88])
+ );
+ } else {
+
+#line 349 "dkwt-cp.ctr"
+ /* ERROR: Failed to delete print job! */
+ dk3app_log_5(
+ app, DK3_LL_ERROR, msg, 89, 90, 91, idbuf,
+ ((job->docName) ? (job->docName) : msg[88])
+ );
+ }
+ }
+ ClosePrinter(hPrinter);
+ } else {
+
+#line 358 "dkwt-cp.ctr"
+ /* ERROR: Failed to open printer! */
+ dk3app_log_3(app, DK3_LL_ERROR, msg, 92, 93, queue->qn);
+ }
+ } else {
+
+#line 362 "dkwt-cp.ctr"
+ }
+ /* Release memory.
+ */
+ if(s_j) {
+ if(i_j) {
+ dk3sto_it_reset(i_j);
+ while(NULL !=(job = (DKWT_CP_JOB *)dk3sto_it_next(i_j))) {
+ dkwt_cp_job_del(job);
+ }
+ dk3sto_it_close(i_j);
+ }
+ dk3sto_close(s_j);
+ }
+
+#line 375 "dkwt-cp.ctr"
+}
+
+
+
+void
+dkwt_clear_printers_local(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl,
+ dkChar const *userName
+)
+{
+ char peb[DKWT_PRINTER_ENUM_BUFFER_SIZE];
+ dkChar hn[256]; /* Host name. */
+ dk3_sto_t *s_q; /* Storage for print queues. */
+ dk3_sto_it_t *i_q; /* Iterator for print queues storage. */
+ DKWT_CP_QUEUE *q; /* Current queue to process. */
+ PRINTER_INFO_4 *pi4; /* Printer information array. */
+ DWORD szpeb; /* Size of peb buffer. */
+ DWORD bneed; /* Needed bytes. */
+ DWORD np; /* Number of printers found. */
+ DWORD i; /* Index of current printer. */
+ DWORD szhn; /* Size of host name. */
+ BOOL res; /* Result from printer enumeration. */
+ s_q = NULL; i_q = NULL;
+ if(userName) {
+ hn[0] = dkT('\0');
+ szhn = DK3_SIZEOF(hn,dkChar);
+#if DK3_CHAR_SIZE > 1
+ res = GetComputerNameExW(ComputerNameNetBIOS, hn, &szhn);
+#else
+ res = GetComputerNameExA(ComputerNameNetBIOS, hn, &szhn);
+#endif
+ if(res) {
+ hn[(szhn < (DK3_SIZEOF(hn,dkChar)-1)) ? szhn : (DK3_SIZEOF(hn,dkChar)-1)] = dkT('\0');
+ } else {
+ szhn = 0;
+ }
+ s_q = dk3sto_open_app(app);
+ if(s_q) {
+ dk3sto_set_comp(s_q, dkwt_cp_queue_comp, 0);
+ i_q = dk3sto_it_open(s_q);
+ }
+ if((s_q) && (i_q)) {
+ /* Enumerate printers, fill s_q
+ */
+ szpeb = sizeof(peb);
+ bneed = 0;
+ np = 0;
+#if DK3_CHAR_SIZE > 1
+ res = EnumPrintersW(
+ PRINTER_ENUM_LOCAL,
+ NULL,
+ 4,
+ (LPBYTE)peb,
+ szpeb,
+ &bneed,
+ &np
+ );
+#else
+ res = EnumPrintersA(
+ PRINTER_ENUM_LOCAL,
+ NULL,
+ 4,
+ (LPBYTE)peb,
+ szpeb,
+ &bneed,
+ &np
+ );
+#endif
+ if(res) {
+ pi4 = (PRINTER_INFO_4 *)peb;
+ if(np > 0) {
+ for(i = 0; i < np; i++) {
+ if(pi4[i].pPrinterName) {
+ q = dkwt_cp_queue_new(app, pi4[i].pPrinterName);
+ if(q) {
+ if(!dk3sto_add(s_q, (void *)q)) {
+ dkwt_cp_queue_del(q);
+ }
+ }
+ }
+ }
+ }
+ } else {
+ /* ERROR: Failed to enumerate local printers */
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 94);
+ }
+ /* Handle all the queues in i_q.
+ */
+ dk3sto_it_reset(i_q);
+ while(NULL != (q = (DKWT_CP_QUEUE *)dk3sto_it_next(i_q))) {
+ dkwt_cp_remove_all_jobs(app, msg, kwnl, userName, ((szhn > 0) ? hn : NULL), q);
+ }
+ }
+ /* Release memory.
+ */
+ if(s_q) {
+ if(i_q) {
+ dk3sto_it_reset(i_q);
+ while(NULL != (q = (DKWT_CP_QUEUE *)dk3sto_it_next(i_q))) {
+ dkwt_cp_queue_del(q);
+ }
+ dk3sto_it_close(i_q);
+ }
+ dk3sto_close(s_q);
+ }
+ } else {
+ /* ERROR: Missing user name! */
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 95);
+ }
+}
+
+
+
+/** Send request to host.
+ @param app Application structure.
+ @param msg Localized message texts.
+ @param kwnl Keywords, not localized.
+ @param rq Request to send.
+ @param hn Host name to send the request to.
+*/
+static
+void
+dkwt_cp_send_request(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl,
+ char const *rq,
+ dkChar const *hn
+)
+{
+ char buf[512];
+ dkChar eb[64];
+ struct sockaddr_in in;
+ struct hostent *he;
+ unsigned long ip;
+ unsigned long *ptr;
+ unsigned long **pptr;
+ size_t lgt;
+ SOCKET sock;
+ int res;
+ int cc;
+ int ie;
+
+ ip = 0UL;
+ dk3enc_ipaddr_to_ul_app(hn, &ip, app);
+ if(ip) {
+ ip = dk3enc_htonl(ip);
+ } else {
+ ie = dk3app_get_encoding(app);
+ if(dk3str_to_c8u_app(buf, sizeof(buf), hn, ie, app)) {
+ he = gethostbyname(buf);
+ if(he) {
+ if(he->h_addr_list) {
+ pptr = (unsigned long **)he->h_addr_list;
+ ptr = *pptr;
+ if(ptr) {
+ ip = *ptr;
+ }
+ }
+ }
+ } else {
+ /* ERROR: Failed to convert host name to UTF-8! */
+ }
+ }
+ if(ip) {
+ sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if(INVALID_SOCKET != sock) {
+ in.sin_family = AF_INET;
+ in.sin_addr.s_addr = ip; /* already in network byte order */
+ in.sin_port = dk3enc_htons(515);
+ ip = dk3enc_ntohl(ip);
+ sprintf(
+ buf, "%lu.%lu.%lu.%lu",
+ ((ip >> 24) & 0x000000FFUL),
+ ((ip >> 16) & 0x000000FFUL),
+ ((ip >> 8) & 0x000000FFUL),
+ ( ip & 0x000000FFUL)
+ );
+ if(dk3str_c8_to_str_simple_app(eb, DK3_SIZEOF(eb,dkChar), buf, app))
+ {
+ dk3app_log_3(app, DK3_LL_DEBUG, msg, 115, 116, eb);
+ }
+ res = connect(
+ sock,
+ (const struct sockaddr *)(&in),
+ sizeof(struct sockaddr_in)
+ );
+ if(0 == res) {
+ lgt = strlen(rq);
+ res = send(sock, rq, (int)lgt, 0);
+ if(res == lgt) {
+ shutdown(sock, SD_SEND);
+ cc = 1;
+ while(cc) {
+ cc = 0;
+ res = recv(sock, buf, sizeof(buf), 0);
+ if(res > 0) {
+ cc = 1;
+ }
+ }
+ /* PROGRESS: Print queue cleaned up successfully. */
+ dk3app_log_1(app, DK3_LL_PROGRESS, msg, 96);
+ } else {
+ /* ERROR: Failed to send request! */
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 97);
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(eb, dkT("%d"), WSAGetLastError());
+ dk3app_log_3(app, DK3_LL_ERROR, msg, 113, 114, eb);
+#else
+ if (dk3ma_im_to_string(eb, DK3_SIZEOF(eb,dkChar), (dk3_im_t)WSAGetLastError())) {
+ dk3app_log_3(app, DK3_LL_ERROR, msg, 113, 114, eb);
+ }
+#endif
+ }
+ } else {
+ /* ERROR: Failed to connect! */
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 98);
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(eb, dkT("%d"), WSAGetLastError());
+ dk3app_log_3(app, DK3_LL_ERROR, msg, 113, 114, eb);
+#else
+ if (dk3ma_im_to_string(eb, DK3_SIZEOF(eb,dkChar), (dk3_im_t)WSAGetLastError())) {
+ dk3app_log_3(app, DK3_LL_ERROR, msg, 113, 114, eb);
+ }
+#endif
+ }
+ closesocket(sock);
+ } else {
+ /* ERROR: Failed to obtain socket! */
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 99);
+ }
+ } else {
+ /* ERROR: Failed to find IP address for host! */
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 100);
+ }
+}
+
+
+
+/** Clean up one remote print queue.
+ @param app Application structure.
+ @param msg Localized message texts.
+ @param kwnl Keywords, not localized.
+ @param userName User name.
+ @param queueName Print queue name.
+*/
+static
+void
+dkwt_clear_one_remote_queue(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl,
+ dkChar const *userName,
+ dkChar const *queueName
+)
+{
+ dkChar qnb[256]; /* Copy of queue name. */
+ char qnc[256]; /* Queue name as char. */
+ char unc[256]; /* User name as char. */
+ char rqc[512]; /* Request. */
+ dkChar *p1; /* Host name part. */
+ size_t sz;
+ int ie; /* Used encoding. */
+ ie = dk3app_get_encoding(app);
+ if(dk3str_len(queueName) < DK3_SIZEOF(qnb,dkChar)) {
+ dk3str_cpy_not_overlapped(qnb, queueName);
+ p1 = dk3str_chr(qnb, dkT('@'));
+ if(p1) {
+ *(p1++) = dkT('\0');
+ p1 = dk3str_start(p1, NULL);
+ if(p1) {
+ dk3str_normalize(qnb, NULL, dkT(' '));
+ if(dk3str_len(qnb) > 0) {
+ if(dk3str_to_c8u_app(qnc, sizeof(qnc), qnb, ie, app)) {
+ if(dk3str_to_c8u_app(unc, sizeof(unc), userName, ie, app)) {
+ sz = strlen(qnc) + strlen(unc) + 8;
+ if(sz < sizeof(rqc)) {
+ sprintf(rqc, "%c%s %s all\n", 0x05, qnc, unc);
+ /* PROGRESS: Cleaning up remote print queue ... */
+ dk3app_log_3(app, DK3_LL_PROGRESS, msg, 101, 102, queueName);
+ dkwt_cp_send_request(app, msg, kwnl, rqc, p1);
+ } else {
+ /* ERROR: Reqeust becomes too long! */
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 103);
+ }
+ } else {
+ /* ERROR: Failed to re-encode user name to UTF-8! */
+ }
+ } else {
+ /* ERROR: Failed to re-encode the queue name to UTF-8! */
+ }
+ } else {
+ /* ERROR: Empty queue name! */
+ dk3app_log_3(app, DK3_LL_ERROR, msg, 104, 105, queueName);
+ }
+ } else {
+ /* ERROR: Empty host name! */
+ dk3app_log_3(app, DK3_LL_ERROR, msg, 106, 107, queueName);
+ }
+ } else {
+ /* ERROR: Not a queue@host name! */
+ dk3app_log_3(app, DK3_LL_ERROR, msg, 108, 109, queueName);
+ }
+ } else {
+ /* ERROR: Queue name too long! */
+ dk3app_log_3(app, DK3_LL_ERROR, msg, 110, 111, queueName);
+ }
+}
+
+
+
+void
+dkwt_clear_printers_remote(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl,
+ dkChar const *userName,
+ dk3_sto_it_t *iterator
+)
+{
+ WORD vrq;
+ WSADATA wsa;
+ dkChar const *qn;
+ vrq = MAKEWORD(2,0);
+ if(0 == WSAStartup(vrq, &wsa)) {
+ dk3sto_it_reset(iterator);
+ while(NULL != (qn = (dkChar const *)dk3sto_it_next(iterator))) {
+ dkwt_clear_one_remote_queue(app, msg, kwnl, userName, qn);
+ }
+ (void)WSACleanup();
+ } else {
+ /* ERROR: Failed to initialize Windows socket! */
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 112);
+ }
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dkwt-cp.ctr b/support/dktools/dkwt-cp.ctr
new file mode 100644
index 0000000000..ed1c92f196
--- /dev/null
+++ b/support/dktools/dkwt-cp.ctr
@@ -0,0 +1,716 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+
+
+%% module
+
+/** No warnings from WinSock about deprecated functions.
+*/
+#define _WINSOCK_DEPRECATED_NO_WARNINGS 1
+
+#include "dk3all.h"
+#include "dkt.h"
+#include "dkwt.h"
+
+
+
+$!trace-include
+
+
+/** Buffer size to enumerate printers.
+*/
+#define DKWT_PRINTER_ENUM_BUFFER_SIZE 1024
+
+/** Buffer size to enumerate print jobs.
+*/
+#define DKWT_PRINTER_ENUM_JOBS_SIZE 8192
+
+/** Number of print jobs to show in one request.
+*/
+#define DKWT_PRINTER_NUMBER_OF_JOBS 64
+
+
+/** Local print queue.
+*/
+typedef struct {
+ dkChar *qn; /**< Queue name. */
+} DKWT_CP_QUEUE;
+
+
+
+/** Print job.
+*/
+typedef struct {
+ DWORD jobId; /**< Job ID. */
+ DWORD pos; /**< Position in queue. */
+ dkChar const *docName; /**< Print job name. */
+} DKWT_CP_JOB;
+
+
+
+/** Compare two print queues by name.
+ @param l Left object.
+ @param r Right object.
+ @param cr Comparison criteria (0=queue/queue, 1=queue/name)
+ @return Comparison result.
+*/
+static
+int
+dkwt_cp_queue_comp(void const *l, void const *r, int cr)
+{
+ DKWT_CP_QUEUE const *ql;
+ DKWT_CP_QUEUE const *qr;
+ int back = 0;
+ if(l) {
+ if(r) {
+ ql = (DKWT_CP_QUEUE const *)l;
+ switch(cr) {
+ case 1: {
+ if(ql->qn) {
+ back = dk3str_casecmp(ql->qn, (dkChar const *)r);
+ if(back < -1) back = -1;
+ if(back > 1) back = 1;
+ } else back = -1;
+ } break;
+ default: {
+ qr = (DKWT_CP_QUEUE const *)r;
+ if(ql->qn) {
+ if(qr->qn) {
+ back = dk3str_casecmp(ql->qn, qr->qn);
+ if(back < -1) back = -1;
+ if(back > 1) back = 1;
+ } else back = 1;
+ } else {
+ if(qr->qn) back = -1;
+ }
+ } break;
+ }
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ }
+ return back;
+}
+
+
+
+/** Destroy queue structure, release memory.
+ @param q Queue structure to destroy.
+*/
+static
+void
+dkwt_cp_queue_del(DKWT_CP_QUEUE *q)
+{
+ if(q) {
+ dk3_release(q->qn);
+ dk3_delete(q);
+ }
+}
+
+
+
+/** Create queue structure, allocate memory.
+ @param app Application structure for diagnostics, may be NULL.
+ @param n Queue name.
+ @return Pointer to new structure on success, NULL on error.
+*/
+static
+DKWT_CP_QUEUE *
+dkwt_cp_queue_new(dk3_app_t *app, dkChar const *n)
+{
+ DKWT_CP_QUEUE *back = NULL;
+ if(n) {
+ back = dk3_new_app(DKWT_CP_QUEUE,1,app);
+ if(back) {
+ back->qn = NULL;
+ back->qn = dk3str_dup_app(n, app);
+ if(!(back->qn)) {
+ dkwt_cp_queue_del(back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Destroy job structure, release memory.
+ @param j Job structure to delete.
+*/
+static
+void
+dkwt_cp_job_del(DKWT_CP_JOB *j)
+{
+ if(j) {
+ dk3_release(j->docName);
+ j->jobId = 0;
+ j->pos = 0;
+ dk3_delete(j);
+ }
+}
+
+
+
+/** Create new job structure, allocate memory.
+ @param app Application structure for diagnostics.
+ @param jobid Job ID.
+ @param pos Job position in the queue.
+ @param dn Document name.
+ @return Pointer to new structure on success, NULL on error.
+*/
+static
+DKWT_CP_JOB *
+dkwt_cp_job_new(dk3_app_t *app, DWORD jobid, DWORD pos, dkChar const *dn)
+{
+ DKWT_CP_JOB *back = NULL;
+ back = dk3_new_app(DKWT_CP_JOB,1,app);
+ if(back) {
+ back->docName = NULL;
+ back->jobId = jobid;
+ back->pos = pos;
+ if(dn) {
+ back->docName = dk3str_dup_app(dn, app);
+ if(!(back->docName)) {
+ dkwt_cp_job_del(back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Compare 2 jobs to find which one to delete first.
+ @param l Left job.
+ @param r Right job.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result, jobs with higher position are deleted first.
+*/
+static
+int
+dkwt_cp_job_comp(void const *l, void const *r, int cr)
+{
+ DKWT_CP_JOB const *jl;
+ DKWT_CP_JOB const *jr;
+ int back = 0;
+ if(l) {
+ if(r) {
+ jl = (DKWT_CP_JOB const *)l;
+ jr = (DKWT_CP_JOB const *)r;
+ if(jl->pos < jr->pos) {
+ back = 1;
+ } else {
+ if(jl->pos > jr->pos) {
+ back = -1;
+ }
+ }
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ }
+ return back;
+}
+
+
+
+
+/** Remove all print jobs for one user from a single queue.
+ @param app Application structure for diagnostics.
+ @param msg Localized message texts.
+ @param kwnl Keywords, not localized.
+ @param userName User name.
+ @param hostName Host name.
+ @param queue Queue to modify.
+*/
+static
+void
+dkwt_cp_remove_all_jobs(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl,
+ dkChar const *userName,
+ dkChar const *hostName,
+ DKWT_CP_QUEUE *queue
+)
+{
+ char jeb[DKWT_PRINTER_ENUM_JOBS_SIZE]; /* Enum buffer. */
+ dkChar idbuf[64];
+ dk3_sto_t *s_j; /* Jobs storage. */
+ dk3_sto_it_t *i_j; /* Iterator for jobs storage. */
+ JOB_INFO_1 *ji1; /* Job information pointer. */
+ DKWT_CP_JOB *job; /* Current job. */
+ HANDLE hPrinter; /* Handle for printer. */
+ DWORD szjeb; /* Size of jeb buffer. */
+ DWORD bneed; /* Bytes needed. */
+ DWORD nj; /* Number of jobs found. */
+ DWORD i; /* Index of current job to process. */
+ int rmj; /* Flag: Remove this job. */
+ BOOL res; /* Operation result. */
+ $? "+ dkwt_cp_remove_all_jobs"
+ s_j = NULL; i_j = NULL;
+ s_j = dk3sto_open_app(app);
+ if(s_j) {
+ dk3sto_set_comp(s_j, dkwt_cp_job_comp, 0);
+ i_j = dk3sto_it_open(s_j);
+ }
+ if((s_j) && (i_j)) {
+ /* PROGRESS: Cleaning up local queue... */
+ dk3app_log_3(app, DK3_LL_PROGRESS, msg, 83, 84, queue->qn);
+#if DK3_CHAR_SIZE > 1
+ res = OpenPrinterW(queue->qn, &hPrinter, NULL);
+#else
+ res = OpenPrinterA(queue->qn, &hPrinter, NULL);
+#endif
+ if(res) {
+ /* Enumerate print jobs, save jobs to delete.
+ */
+ szjeb = sizeof(jeb); bneed = 0; nj = 0;
+#if DK3_CHAR_SIZE > 1
+ res = EnumJobsW(
+ hPrinter, 0, DKWT_PRINTER_NUMBER_OF_JOBS, 1, (LPBYTE)jeb, szjeb,
+ &bneed, &nj
+ );
+#else
+ res = EnumJobsA(
+ hPrinter, 0, DKWT_PRINTER_NUMBER_OF_JOBS, 1, (LPBYTE)jeb, szjeb,
+ &bneed, &nj
+ );
+#endif
+ if(res) { $? ". EnumJobs"
+ if(nj > 0) { $? ". nj=%d", (int)nj
+ ji1 = (JOB_INFO_1 *)jeb;
+ for(i = 0; i < nj; i++) {
+ rmj = 0;
+ if(ji1[i].pUserName) { $? ". job user \"%!ds\" / user \"%!ds\"", ji1[i].pUserName, userName
+ if(0 == dk3str_casecmp(ji1[i].pUserName, userName)) { $? ". equal"
+ rmj = 1;
+ if(hostName) { $? ". have host name \"%!ds\"", hostName
+ rmj = 0;
+ if(ji1[i].pMachineName) { $? ". job host \"%!ds\"", ji1[i].pMachineName
+ if(0 == dk3str_casecmp(ji1[i].pMachineName, hostName)) { $? ". ok"
+ rmj = 1;
+ } else {
+ if(dkT('\\') == (ji1[i].pMachineName)[0]) {
+ if(dkT('\\') == (ji1[i].pMachineName)[1]) {
+ if(0 == dk3str_casecmp(&((ji1[i].pMachineName)[2]), hostName)) {
+ rmj = 1;
+ }
+ }
+ }
+ }
+ } else { $? ". no job host name"
+ rmj = 1;
+ }
+ } else { $? ". host name not found"
+ }
+ } else { $? ". other user name"
+ }
+ }
+ if(rmj) { $? ". must remove job"
+ job = dkwt_cp_job_new(app, ji1[i].JobId, ji1[i].Position, ji1[i].pDocument);
+ if(job) {
+ if(!dk3sto_add(s_j, (void *)job)) { $? "! memory"
+ dkwt_cp_job_del(job);
+ } else {
+ }
+ } else { $? "! memory"
+ }
+ }
+ }
+ } else { $? ". no jobs in queue"
+ }
+ } else { $? "! EnumJobs"
+ }
+ /* Delete saved print jobs if any.
+ */
+ dk3sto_it_reset(i_j);
+ while(NULL != (job = (DKWT_CP_JOB *)dk3sto_it_next(i_j))) {
+ $? ". deleting print job %lu", (unsigned long)(job->jobId)
+#if VERSION_20140716
+ dk3sf_sprintf3(idbuf, dkT("%lu"), (unsigned long)(job->jobId));
+#else
+ if (!(dk3ma_um_to_string(idbuf, DK3_SIZEOF(idbuf,dkChar), (dk3_um_t)(job->jobId)))) {
+ idbuf[0] = dkT('\0');
+ }
+#endif
+ if(SetJob(hPrinter, job->jobId, 0, NULL, JOB_CONTROL_DELETE)) {
+ /* PROGRESS: Print job deleted. */ $? ". deleted"
+ dk3app_log_5(
+ app, DK3_LL_PROGRESS, msg, 85, 86, 87, idbuf,
+ ((job->docName) ? (job->docName) : msg[88])
+ );
+ } else { $? "! failed to delete"
+ /* ERROR: Failed to delete print job! */
+ dk3app_log_5(
+ app, DK3_LL_ERROR, msg, 89, 90, 91, idbuf,
+ ((job->docName) ? (job->docName) : msg[88])
+ );
+ }
+ }
+ ClosePrinter(hPrinter);
+ } else { $? "! failed to open printer"
+ /* ERROR: Failed to open printer! */
+ dk3app_log_3(app, DK3_LL_ERROR, msg, 92, 93, queue->qn);
+ }
+ } else { $? "! arguments"
+ }
+ /* Release memory.
+ */
+ if(s_j) {
+ if(i_j) {
+ dk3sto_it_reset(i_j);
+ while(NULL !=(job = (DKWT_CP_JOB *)dk3sto_it_next(i_j))) {
+ dkwt_cp_job_del(job);
+ }
+ dk3sto_it_close(i_j);
+ }
+ dk3sto_close(s_j);
+ } $? "- dkwt_cp_remove_all_jobs"
+}
+
+
+
+void
+dkwt_clear_printers_local(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl,
+ dkChar const *userName
+)
+{
+ char peb[DKWT_PRINTER_ENUM_BUFFER_SIZE];
+ dkChar hn[256]; /* Host name. */
+ dk3_sto_t *s_q; /* Storage for print queues. */
+ dk3_sto_it_t *i_q; /* Iterator for print queues storage. */
+ DKWT_CP_QUEUE *q; /* Current queue to process. */
+ PRINTER_INFO_4 *pi4; /* Printer information array. */
+ DWORD szpeb; /* Size of peb buffer. */
+ DWORD bneed; /* Needed bytes. */
+ DWORD np; /* Number of printers found. */
+ DWORD i; /* Index of current printer. */
+ DWORD szhn; /* Size of host name. */
+ BOOL res; /* Result from printer enumeration. */
+ s_q = NULL; i_q = NULL;
+ if(userName) {
+ hn[0] = dkT('\0');
+ szhn = DK3_SIZEOF(hn,dkChar);
+#if DK3_CHAR_SIZE > 1
+ res = GetComputerNameExW(ComputerNameNetBIOS, hn, &szhn);
+#else
+ res = GetComputerNameExA(ComputerNameNetBIOS, hn, &szhn);
+#endif
+ if(res) {
+ hn[(szhn < (DK3_SIZEOF(hn,dkChar)-1)) ? szhn : (DK3_SIZEOF(hn,dkChar)-1)] = dkT('\0');
+ } else {
+ szhn = 0;
+ }
+ s_q = dk3sto_open_app(app);
+ if(s_q) {
+ dk3sto_set_comp(s_q, dkwt_cp_queue_comp, 0);
+ i_q = dk3sto_it_open(s_q);
+ }
+ if((s_q) && (i_q)) {
+ /* Enumerate printers, fill s_q
+ */
+ szpeb = sizeof(peb);
+ bneed = 0;
+ np = 0;
+#if DK3_CHAR_SIZE > 1
+ res = EnumPrintersW(
+ PRINTER_ENUM_LOCAL,
+ NULL,
+ 4,
+ (LPBYTE)peb,
+ szpeb,
+ &bneed,
+ &np
+ );
+#else
+ res = EnumPrintersA(
+ PRINTER_ENUM_LOCAL,
+ NULL,
+ 4,
+ (LPBYTE)peb,
+ szpeb,
+ &bneed,
+ &np
+ );
+#endif
+ if(res) {
+ pi4 = (PRINTER_INFO_4 *)peb;
+ if(np > 0) {
+ for(i = 0; i < np; i++) {
+ if(pi4[i].pPrinterName) {
+ q = dkwt_cp_queue_new(app, pi4[i].pPrinterName);
+ if(q) {
+ if(!dk3sto_add(s_q, (void *)q)) {
+ dkwt_cp_queue_del(q);
+ }
+ }
+ }
+ }
+ }
+ } else {
+ /* ERROR: Failed to enumerate local printers */
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 94);
+ }
+ /* Handle all the queues in i_q.
+ */
+ dk3sto_it_reset(i_q);
+ while(NULL != (q = (DKWT_CP_QUEUE *)dk3sto_it_next(i_q))) {
+ dkwt_cp_remove_all_jobs(app, msg, kwnl, userName, ((szhn > 0) ? hn : NULL), q);
+ }
+ }
+ /* Release memory.
+ */
+ if(s_q) {
+ if(i_q) {
+ dk3sto_it_reset(i_q);
+ while(NULL != (q = (DKWT_CP_QUEUE *)dk3sto_it_next(i_q))) {
+ dkwt_cp_queue_del(q);
+ }
+ dk3sto_it_close(i_q);
+ }
+ dk3sto_close(s_q);
+ }
+ } else {
+ /* ERROR: Missing user name! */
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 95);
+ }
+}
+
+
+
+/** Send request to host.
+ @param app Application structure.
+ @param msg Localized message texts.
+ @param kwnl Keywords, not localized.
+ @param rq Request to send.
+ @param hn Host name to send the request to.
+*/
+static
+void
+dkwt_cp_send_request(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl,
+ char const *rq,
+ dkChar const *hn
+)
+{
+ char buf[512];
+ dkChar eb[64];
+ struct sockaddr_in in;
+ struct hostent *he;
+ unsigned long ip;
+ unsigned long *ptr;
+ unsigned long **pptr;
+ size_t lgt;
+ SOCKET sock;
+ int res;
+ int cc;
+ int ie;
+
+ ip = 0UL;
+ dk3enc_ipaddr_to_ul_app(hn, &ip, app);
+ if(ip) {
+ ip = dk3enc_htonl(ip);
+ } else {
+ ie = dk3app_get_encoding(app);
+ if(dk3str_to_c8u_app(buf, sizeof(buf), hn, ie, app)) {
+ he = gethostbyname(buf);
+ if(he) {
+ if(he->h_addr_list) {
+ pptr = (unsigned long **)he->h_addr_list;
+ ptr = *pptr;
+ if(ptr) {
+ ip = *ptr;
+ }
+ }
+ }
+ } else {
+ /* ERROR: Failed to convert host name to UTF-8! */
+ }
+ }
+ if(ip) {
+ sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if(INVALID_SOCKET != sock) {
+ in.sin_family = AF_INET;
+ in.sin_addr.s_addr = ip; /* already in network byte order */
+ in.sin_port = dk3enc_htons(515);
+ ip = dk3enc_ntohl(ip);
+ sprintf(
+ buf, "%lu.%lu.%lu.%lu",
+ ((ip >> 24) & 0x000000FFUL),
+ ((ip >> 16) & 0x000000FFUL),
+ ((ip >> 8) & 0x000000FFUL),
+ ( ip & 0x000000FFUL)
+ );
+ if(dk3str_c8_to_str_simple_app(eb, DK3_SIZEOF(eb,dkChar), buf, app))
+ {
+ dk3app_log_3(app, DK3_LL_DEBUG, msg, 115, 116, eb);
+ }
+ res = connect(
+ sock,
+ (const struct sockaddr *)(&in),
+ sizeof(struct sockaddr_in)
+ );
+ if(0 == res) {
+ lgt = strlen(rq);
+ res = send(sock, rq, (int)lgt, 0);
+ if(res == lgt) {
+ shutdown(sock, SD_SEND);
+ cc = 1;
+ while(cc) {
+ cc = 0;
+ res = recv(sock, buf, sizeof(buf), 0);
+ if(res > 0) {
+ cc = 1;
+ }
+ }
+ /* PROGRESS: Print queue cleaned up successfully. */
+ dk3app_log_1(app, DK3_LL_PROGRESS, msg, 96);
+ } else {
+ /* ERROR: Failed to send request! */
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 97);
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(eb, dkT("%d"), WSAGetLastError());
+ dk3app_log_3(app, DK3_LL_ERROR, msg, 113, 114, eb);
+#else
+ if (dk3ma_im_to_string(eb, DK3_SIZEOF(eb,dkChar), (dk3_im_t)WSAGetLastError())) {
+ dk3app_log_3(app, DK3_LL_ERROR, msg, 113, 114, eb);
+ }
+#endif
+ }
+ } else {
+ /* ERROR: Failed to connect! */
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 98);
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(eb, dkT("%d"), WSAGetLastError());
+ dk3app_log_3(app, DK3_LL_ERROR, msg, 113, 114, eb);
+#else
+ if (dk3ma_im_to_string(eb, DK3_SIZEOF(eb,dkChar), (dk3_im_t)WSAGetLastError())) {
+ dk3app_log_3(app, DK3_LL_ERROR, msg, 113, 114, eb);
+ }
+#endif
+ }
+ closesocket(sock);
+ } else {
+ /* ERROR: Failed to obtain socket! */
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 99);
+ }
+ } else {
+ /* ERROR: Failed to find IP address for host! */
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 100);
+ }
+}
+
+
+
+/** Clean up one remote print queue.
+ @param app Application structure.
+ @param msg Localized message texts.
+ @param kwnl Keywords, not localized.
+ @param userName User name.
+ @param queueName Print queue name.
+*/
+static
+void
+dkwt_clear_one_remote_queue(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl,
+ dkChar const *userName,
+ dkChar const *queueName
+)
+{
+ dkChar qnb[256]; /* Copy of queue name. */
+ char qnc[256]; /* Queue name as char. */
+ char unc[256]; /* User name as char. */
+ char rqc[512]; /* Request. */
+ dkChar *p1; /* Host name part. */
+ size_t sz;
+ int ie; /* Used encoding. */
+ ie = dk3app_get_encoding(app);
+ if(dk3str_len(queueName) < DK3_SIZEOF(qnb,dkChar)) {
+ dk3str_cpy_not_overlapped(qnb, queueName);
+ p1 = dk3str_chr(qnb, dkT('@'));
+ if(p1) {
+ *(p1++) = dkT('\0');
+ p1 = dk3str_start(p1, NULL);
+ if(p1) {
+ dk3str_normalize(qnb, NULL, dkT(' '));
+ if(dk3str_len(qnb) > 0) {
+ if(dk3str_to_c8u_app(qnc, sizeof(qnc), qnb, ie, app)) {
+ if(dk3str_to_c8u_app(unc, sizeof(unc), userName, ie, app)) {
+ sz = strlen(qnc) + strlen(unc) + 8;
+ if(sz < sizeof(rqc)) {
+ sprintf(rqc, "%c%s %s all\n", 0x05, qnc, unc);
+ /* PROGRESS: Cleaning up remote print queue ... */
+ dk3app_log_3(app, DK3_LL_PROGRESS, msg, 101, 102, queueName);
+ dkwt_cp_send_request(app, msg, kwnl, rqc, p1);
+ } else {
+ /* ERROR: Reqeust becomes too long! */
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 103);
+ }
+ } else {
+ /* ERROR: Failed to re-encode user name to UTF-8! */
+ }
+ } else {
+ /* ERROR: Failed to re-encode the queue name to UTF-8! */
+ }
+ } else {
+ /* ERROR: Empty queue name! */
+ dk3app_log_3(app, DK3_LL_ERROR, msg, 104, 105, queueName);
+ }
+ } else {
+ /* ERROR: Empty host name! */
+ dk3app_log_3(app, DK3_LL_ERROR, msg, 106, 107, queueName);
+ }
+ } else {
+ /* ERROR: Not a queue@host name! */
+ dk3app_log_3(app, DK3_LL_ERROR, msg, 108, 109, queueName);
+ }
+ } else {
+ /* ERROR: Queue name too long! */
+ dk3app_log_3(app, DK3_LL_ERROR, msg, 110, 111, queueName);
+ }
+}
+
+
+
+void
+dkwt_clear_printers_remote(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl,
+ dkChar const *userName,
+ dk3_sto_it_t *iterator
+)
+{
+ WORD vrq;
+ WSADATA wsa;
+ dkChar const *qn;
+ vrq = MAKEWORD(2,0);
+ if(0 == WSAStartup(vrq, &wsa)) {
+ dk3sto_it_reset(iterator);
+ while(NULL != (qn = (dkChar const *)dk3sto_it_next(iterator))) {
+ dkwt_clear_one_remote_queue(app, msg, kwnl, userName, qn);
+ }
+ (void)WSACleanup();
+ } else {
+ /* ERROR: Failed to initialize Windows socket! */
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 112);
+ }
+}
+
+
+
+/* vim: set ai sw=2 : */
+
diff --git a/support/dktools/dkwt-env.c b/support/dktools/dkwt-env.c
new file mode 100644
index 0000000000..caf0425177
--- /dev/null
+++ b/support/dktools/dkwt-env.c
@@ -0,0 +1,633 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dkwt-env.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dkwt-env.c The dkwt-env module.
+*/
+
+
+#line 10 "dkwt-env.ctr"
+
+#include "dk3all.h"
+#include "dkt.h"
+#include "dkwt.h"
+#include "dk3wreg.h"
+
+
+
+
+
+#line 19 "dkwt-env.ctr"
+
+
+
+/** @defgroup dkwt_env_cmd_types Commands for dkwt env. */
+/**@{*/
+
+/** Set or show variable.
+*/
+#define DKWT_ENV_CMD_NORMAL 0
+
+/** Unset variable (remove registry entry).
+*/
+#define DKWT_ENV_CMD_UNSET 1
+
+/** Insert directory at start of value if not yet present.
+*/
+#define DKWT_ENV_CMD_INSERT 2
+
+/** Append directory at end of value if not yet present.
+*/
+#define DKWT_ENV_CMD_APPEND 3
+
+/** Delete directory from value if present.
+*/
+#define DKWT_ENV_CMD_DELETE 4
+
+/** Illegal options combination found.
+*/
+#define DKWT_ENV_CMD_ERROR 5
+
+/**@}*/
+
+
+
+/** Job structure for dkwt env.
+*/
+typedef struct {
+ dk3_app_t *app; /**< Application structure. */
+ dkChar const * const *msg; /**< Localized message texts. */
+ dkChar const * const *kwnl; /**< Keywords, not localized. */
+ dkChar const *name; /**< Environment variable name. */
+ dkChar const *value; /**< Environment variable value. */
+ dk3_option_set_t *opt; /**< Options set. */
+ int exv; /**< Exit value. */
+ int cmd; /**< Command to execute. */
+ int sys; /**< Flag: Dealing with system variables. */
+ int exp; /**< Flag: Use REG_EXPAND_SZ for new entry. */
+} DKWT_ENV_J;
+
+
+
+/** Keywords used by the module.
+*/
+dkChar const * const dkwt_env_kw[] = {
+/* 0 */
+dkT(" "),
+
+/* 1 */
+dkT("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment"),
+
+/* 2 */
+dkT("Environment"),
+
+/* 3 */
+dkT(";"),
+
+NULL
+
+
+#line 91 "dkwt-env.ctr"
+};
+
+
+
+/** Options allowed for dkwt env.
+*/
+static dk3_option_t const dkwt_env_options[] = {
+ { dkT('s'), dkT("system"), 0 },
+ { dkT('u'), dkT("unset"), 0 },
+ { dkT('i'), dkT("insert"), 0 },
+ { dkT('a'), dkT("append"), 0 },
+ { dkT('d'), dkT("delete"), 0 },
+ { dkT('e'), dkT("expand"), 0 }
+};
+
+
+
+/** Number of elements in dkwt_env_options array.
+*/
+static size_t const dkwt_env_szoptions =
+sizeof(dkwt_env_options)/sizeof(dk3_option_t);
+
+
+
+/** Initialize job structure.
+ @param j Job structure to initialize.
+*/
+static
+void
+dkwt_env_job_init(DKWT_ENV_J *j)
+{
+ j->app = NULL;
+ j->msg = NULL;
+ j->kwnl = NULL;
+ j->opt = NULL;
+ j->name = NULL;
+ j->value = NULL;
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ j->cmd = DKWT_ENV_CMD_NORMAL;
+ j->sys = 0;
+ j->exp = 0;
+}
+
+
+
+/** Clean up job structure after processing.
+ @param j Job structure to clean up.
+*/
+static
+void
+dkwt_env_job_cleanup(DKWT_ENV_J *j)
+{
+ if (j->value) {
+ dk3_delete(j->value);
+ } j->value = NULL;
+ if (j->opt) {
+ dk3opt_close(j->opt);
+ } j->opt = NULL;
+}
+
+
+
+/** Process command line arguments.
+ @param j Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkwt_env_process_args(DKWT_ENV_J *j)
+{
+ int back = 0;
+ int xargc;
+ dkChar const * const *xargv;
+
+ xargc = dk3app_get_argc(j->app);
+ xargv = dk3app_get_argv(j->app);
+ if (1 < xargc) {
+ xargv++; xargv++; xargc--; xargc--;
+ j->opt = dk3opt_open_app(
+ dkwt_env_options,
+ dkwt_env_szoptions,
+ dkT('\0'),
+ NULL,
+ xargc,
+ xargv,
+ j->app
+ );
+ if (j->opt) {
+ if (0 == dk3opt_get_error_code(j->opt)) {
+ back = 1;
+ if (dk3opt_is_set(j->opt, dkT('s'))) {
+ j->sys = 1;
+ }
+ if (dk3opt_is_set(j->opt, dkT('e'))) {
+ j->exp = 1;
+ }
+ if (dk3opt_is_set(j->opt, dkT('u'))) {
+ j->cmd = DKWT_ENV_CMD_UNSET;
+ }
+ if (dk3opt_is_set(j->opt, dkT('i'))) {
+ if (j->cmd) {
+ j->cmd = DKWT_ENV_CMD_ERROR; back = 0;
+ /* ERROR: -u -i -a -d are mutual exclusive */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 142);
+ } else {
+ j->cmd = DKWT_ENV_CMD_INSERT;
+ }
+ }
+ if (dk3opt_is_set(j->opt, dkT('a'))) {
+ if (j->cmd) {
+ j->cmd = DKWT_ENV_CMD_ERROR; back = 0;
+ /* ERROR: Mutual exclusive */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 142);
+ } else {
+ j->cmd = DKWT_ENV_CMD_APPEND;
+ }
+ }
+ if (dk3opt_is_set(j->opt, dkT('d'))) {
+ if (j->cmd) {
+ j->cmd = DKWT_ENV_CMD_ERROR, back = 0;
+ /* ERROR: Mutual exlusive */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 142);
+ } else {
+ j->cmd = DKWT_ENV_CMD_DELETE;
+ }
+ }
+ if (back) {
+ if (0 >= dk3opt_get_num_args(j->opt)) {
+ j->cmd = DKWT_ENV_CMD_ERROR; back = 0;
+ /* ERROR: At least one argument required */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 143);
+ } else {
+ j->name = dk3opt_get_arg(j->opt, 0);
+ if (!(j->name)) {
+ j->cmd = DKWT_ENV_CMD_ERROR; back = 0;
+
+#line 226 "dkwt-env.ctr"
+ }
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+
+/** Check whether an environment variable value contains a directory.
+ @param valptr String to check for a directory name.
+ @param dir Directory name to search for.
+ @return 1 on success (directory found), 0 otherwise.
+*/
+static
+int
+dkwt_env_value_contains_dir(dkChar *valptr, dkChar const *dir)
+{
+ dkChar *pc;
+ dkChar *pn;
+ int back = 0;
+ pc = valptr;
+ while ((0 == back) && (pc)) {
+ pn = dk3str_chr(pc, dkT(';'));
+ if (pn) { *(pn++) = dkT('\0'); }
+ if (0 == dk3str_fncmp(pc, dir)) { back = 1; }
+ pc = pn;
+ }
+ return back;
+}
+
+
+
+/** Process the request.
+ @param j Job structure containing configuration.
+*/
+static
+void
+dkwt_env_do_processing(DKWT_ENV_J *j)
+{
+ dkChar *b1 = NULL; /* Original registry value */
+ dkChar *b2 = NULL; /* Second buffer */
+ dkChar *pc; /* Current part */
+ dkChar *pn; /* Next part */
+ DWORD_PTR dwrv = (DWORD)0UL; /* Return value for message */
+ DWORD dwtf = REG_SZ; /* Type found */
+ HKEY hk = (HKEY)0; /* Registry key */
+ size_t lgt; /* Length */
+ int fmod = 0; /* Flag: Modification */
+ int res = 0; /* Registry operation result */
+ int wre = 0; /* Write expanded */
+ int hco = 0; /* Flag: Contents in out buf */
+
+ switch (j->cmd) {
+ case DKWT_ENV_CMD_NORMAL:
+ case DKWT_ENV_CMD_UNSET:
+ case DKWT_ENV_CMD_INSERT:
+ case DKWT_ENV_CMD_APPEND:
+ case DKWT_ENV_CMD_DELETE:
+ {
+ b1 = dk3_new_app(dkChar, 8192, j->app);
+ if (b1) {
+ if ((DKWT_ENV_CMD_NORMAL == j->cmd) && (!(j->value))) {
+ if (j->sys) {
+ res = dk3wreg_key_open_read(
+ HKEY_LOCAL_MACHINE, dkwt_env_kw[1], &hk, j->app
+ );
+ } else {
+ res = dk3wreg_key_open_read(
+ HKEY_CURRENT_USER, dkwt_env_kw[2], &hk, j->app
+ );
+ }
+ } else {
+ if (j->sys) {
+ res = dk3wreg_key_open_modify(
+ HKEY_LOCAL_MACHINE, dkwt_env_kw[1], &hk, j->app
+ );
+ } else {
+ res = dk3wreg_key_open_modify(
+ HKEY_CURRENT_USER, dkwt_env_kw[2], &hk, j->app
+ );
+ }
+ }
+ if (res) {
+ switch (j->cmd) {
+ case DKWT_ENV_CMD_NORMAL: {
+ if (j->value) {
+ if (dk3wreg_get_expand_sz(hk, j->name, b1, 8191, &dwtf, NULL)) {
+ if (REG_EXPAND_SZ == dwtf) { wre = 1; }
+ } else {
+ if (j->exp) { wre = 1; }
+ }
+ if (wre) {
+ res = dk3wreg_set_expand_sz(hk, j->name, j->value, j->app);
+ } else {
+ res = dk3wreg_set_sz(hk, j->name, j->value, j->app);
+ }
+ if (res) {
+ fmod = 1;
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ } else {
+ if (dk3wreg_get_sz(hk, j->name, b1, 8191, j->app)) {
+ dk3sf_initialize_stdout();
+ dk3sf_fputs(b1, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ }
+ } break;
+ case DKWT_ENV_CMD_UNSET: {
+ if(dk3wreg_entry_delete(hk, j->name, j->app)) {
+ fmod = 1;
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ } break;
+ case DKWT_ENV_CMD_INSERT: {
+ if (j->value) {
+ if (dk3wreg_get_expand_sz(hk, j->name, b1, 8191, &dwtf, NULL)) {
+ lgt = dk3str_len(b1) + dk3str_len(j->value) + 2;
+ b2 = dk3_new_app(dkChar, lgt, j->app);
+ if (b2) {
+ dk3str_cpy(b2, b1);
+ if (!(dkwt_env_value_contains_dir(b2, j->value))) {
+ dk3str_cpy(b2, j->value);
+ dk3str_cat(b2, dkwt_env_kw[3]);
+ dk3str_cat(b2, b1);
+ if (REG_EXPAND_SZ == dwtf) {
+ res = dk3wreg_set_expand_sz(hk, j->name, b2, j->app);
+ } else {
+ res = dk3wreg_set_sz(hk, j->name, b2, j->app);
+ }
+ if (res) {
+ fmod = 1;
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ }
+ dk3_delete(b2);
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ } else {
+ if (j->exp) {
+ res = dk3wreg_set_expand_sz(hk, j->name, j->value, j->app);
+ } else {
+ res = dk3wreg_set_sz(hk, j->name, j->value, j->app);
+ }
+ if (res) {
+ fmod = 1;
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ }
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ /* ERROR: Value required! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 144);
+ }
+ } break;
+ case DKWT_ENV_CMD_APPEND: {
+ if (j->value) {
+ if (dk3wreg_get_expand_sz(hk, j->name, b1, 8191, &dwtf, NULL)) {
+ lgt = dk3str_len(b1) + dk3str_len(j->value) + 2;
+ b2 = dk3_new_app(dkChar, lgt, j->app);
+ if (b2) {
+ dk3str_cpy(b2, b1);
+ if (!(dkwt_env_value_contains_dir(b2, j->value))) {
+ dk3str_cpy(b2, b1);
+ dk3str_cat(b2, dkwt_env_kw[3]);
+ dk3str_cat(b2, j->value);
+ if (REG_EXPAND_SZ == dwtf) {
+ res = dk3wreg_set_expand_sz(hk, j->name, b2, j->app);
+ } else {
+ res = dk3wreg_set_sz(hk, j->name, b2, j->app);
+ }
+ if (res) {
+ fmod = 1;
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ }
+ dk3_delete(b2);
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ } else {
+ if (j->exp) {
+ res = dk3wreg_set_expand_sz(hk, j->name, j->value, j->app);
+ } else {
+ res = dk3wreg_set_sz(hk, j->name, j->value, j->app);
+ }
+ if (res) {
+ fmod = 1;
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ }
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ /* ERROR: Value required! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 144);
+ }
+ } break;
+ case DKWT_ENV_CMD_DELETE: {
+ if (j->value) {
+ if (dk3wreg_get_expand_sz(hk, j->name, b1, 8191, &dwtf, NULL)) {
+ lgt = 1 + dk3str_len(b1);
+ b2 = dk3_new_app(dkChar, lgt, j->app);
+ if (b2) {
+ b2[0] = dkT('\0');
+ pc = b1;
+ while (pc) {
+ pn = dk3str_chr(pc, dkT(';'));
+ if (pn) { *(pn++) = dkT('\0'); }
+ if (dk3str_fncmp(pc, j->value)) {
+ if (hco) {
+ dk3str_cat(b2, dkwt_env_kw[3]);
+ dk3str_cat(b2, pc);
+ } else {
+ dk3str_cpy(b2, pc);
+ }
+ hco = 1;
+ }
+ pc = pn;
+ }
+ if (hco) {
+ if (REG_EXPAND_SZ == dwtf) {
+ res = dk3wreg_set_expand_sz(hk, j->name, b2, j->app);
+ } else {
+ res = dk3wreg_set_sz(hk, j->name, b2, j->app);
+ }
+ if (res) {
+ fmod = 1;
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ } else {
+ if (dk3wreg_entry_delete(hk, j->name, j->app)) {
+ fmod = 1;
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ }
+ dk3_delete(b2);
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ }
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ /* ERROR: Value required! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 144);
+ }
+ } break;
+ }
+ RegCloseKey(hk);
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ dk3_delete(b1);
+ if (fmod) {
+ SendMessageTimeout(
+ HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)"Environment",
+ SMTO_ABORTIFHUNG, 5000, &dwrv
+ );
+ }
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ }
+ break;
+ default: {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ } break;
+ }
+}
+
+
+
+/** Do processing.
+ @param j Job structure containing configuration.
+*/
+static
+void
+dkwt_env_run(DKWT_ENV_J *j)
+{
+ dkChar const *p1; /* Part of the name */
+ dkChar *buffer = NULL; /* Buffer to construct value */
+ size_t vallgt = 0; /* Value length */
+ int i = 0; /* Traverse options */
+
+ j->exv = DKT_RESULT_OK;
+
+ /* Find value length.
+ */
+ vallgt = 0;
+ for (i = 1; i < dk3opt_get_num_args(j->opt); i++) {
+ if (1 < i) { vallgt++; }
+ p1 = dk3opt_get_arg(j->opt, i);
+ if (p1) {
+ vallgt += dk3str_len(p1);
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ }
+ if (vallgt) { vallgt++; }
+
+ /* Create value string.
+ */
+ if (DKT_RESULT_OK == j->exv) {
+ if (0 < vallgt) {
+ buffer = dk3_new_app(dkChar,vallgt,j->app);
+ if (buffer) {
+ j->value = buffer;
+ buffer[0] = dkT('\0');
+ for (i = 1; i < dk3opt_get_num_args(j->opt); i++) {
+ p1 = dk3opt_get_arg(j->opt, i);
+ if (1 < i) {
+ dk3str_cat(buffer, dkwt_env_kw[0]);
+ dk3str_cat(buffer, p1);
+ } else {
+ dk3str_cpy(buffer, p1);
+ }
+ }
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ }
+ }
+
+ /* Process the request.
+ */
+ if (DKT_RESULT_OK == j->exv) {
+ dkwt_env_do_processing(j);
+ }
+}
+
+
+
+int
+dkwt_env(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl
+)
+{
+ DKWT_ENV_J job;
+ int back = DKT_RESULT_ERR_UNSPECIFIC;
+
+
+#line 582 "dkwt-env.ctr"
+ dkwt_env_job_init(&job);
+ job.app = app; job.msg = msg; job.kwnl = kwnl;
+ if (dkwt_env_process_args(&job)) {
+ if ((0 != job.sys) && (1 != dkwt_is_admin())) {
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 146);
+ } else {
+ dkwt_env_run(&job);
+ }
+ }
+ back = job.exv;
+ dkwt_env_job_cleanup(&job);
+
+
+#line 594 "dkwt-env.ctr"
+ return back;
+}
+
diff --git a/support/dktools/dkwt-env.ctr b/support/dktools/dkwt-env.ctr
new file mode 100644
index 0000000000..bc08b2782b
--- /dev/null
+++ b/support/dktools/dkwt-env.ctr
@@ -0,0 +1,596 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2014-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk3all.h"
+#include "dkt.h"
+#include "dkwt.h"
+#include "dk3wreg.h"
+
+
+
+$!trace-include
+
+
+
+/** @defgroup dkwt_env_cmd_types Commands for dkwt env. */
+/**@{*/
+
+/** Set or show variable.
+*/
+#define DKWT_ENV_CMD_NORMAL 0
+
+/** Unset variable (remove registry entry).
+*/
+#define DKWT_ENV_CMD_UNSET 1
+
+/** Insert directory at start of value if not yet present.
+*/
+#define DKWT_ENV_CMD_INSERT 2
+
+/** Append directory at end of value if not yet present.
+*/
+#define DKWT_ENV_CMD_APPEND 3
+
+/** Delete directory from value if present.
+*/
+#define DKWT_ENV_CMD_DELETE 4
+
+/** Illegal options combination found.
+*/
+#define DKWT_ENV_CMD_ERROR 5
+
+/**@}*/
+
+
+
+/** Job structure for dkwt env.
+*/
+typedef struct {
+ dk3_app_t *app; /**< Application structure. */
+ dkChar const * const *msg; /**< Localized message texts. */
+ dkChar const * const *kwnl; /**< Keywords, not localized. */
+ dkChar const *name; /**< Environment variable name. */
+ dkChar const *value; /**< Environment variable value. */
+ dk3_option_set_t *opt; /**< Options set. */
+ int exv; /**< Exit value. */
+ int cmd; /**< Command to execute. */
+ int sys; /**< Flag: Dealing with system variables. */
+ int exp; /**< Flag: Use REG_EXPAND_SZ for new entry. */
+} DKWT_ENV_J;
+
+
+
+/** Keywords used by the module.
+*/
+dkChar const * const dkwt_env_kw[] = {
+$!string-table macro=dkT
+#
+# 0 Space
+#
+
+#
+# 1 Key name for system environment
+#
+SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment
+#
+# 2 Key name for user environment
+#
+Environment
+#
+# 3 Separator
+#
+;
+$!end
+};
+
+
+
+/** Options allowed for dkwt env.
+*/
+static dk3_option_t const dkwt_env_options[] = {
+ { dkT('s'), dkT("system"), 0 },
+ { dkT('u'), dkT("unset"), 0 },
+ { dkT('i'), dkT("insert"), 0 },
+ { dkT('a'), dkT("append"), 0 },
+ { dkT('d'), dkT("delete"), 0 },
+ { dkT('e'), dkT("expand"), 0 }
+};
+
+
+
+/** Number of elements in dkwt_env_options array.
+*/
+static size_t const dkwt_env_szoptions =
+sizeof(dkwt_env_options)/sizeof(dk3_option_t);
+
+
+
+/** Initialize job structure.
+ @param j Job structure to initialize.
+*/
+static
+void
+dkwt_env_job_init(DKWT_ENV_J *j)
+{
+ j->app = NULL;
+ j->msg = NULL;
+ j->kwnl = NULL;
+ j->opt = NULL;
+ j->name = NULL;
+ j->value = NULL;
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ j->cmd = DKWT_ENV_CMD_NORMAL;
+ j->sys = 0;
+ j->exp = 0;
+}
+
+
+
+/** Clean up job structure after processing.
+ @param j Job structure to clean up.
+*/
+static
+void
+dkwt_env_job_cleanup(DKWT_ENV_J *j)
+{
+ if (j->value) {
+ dk3_delete(j->value);
+ } j->value = NULL;
+ if (j->opt) {
+ dk3opt_close(j->opt);
+ } j->opt = NULL;
+}
+
+
+
+/** Process command line arguments.
+ @param j Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkwt_env_process_args(DKWT_ENV_J *j)
+{
+ int back = 0;
+ int xargc;
+ dkChar const * const *xargv;
+
+ xargc = dk3app_get_argc(j->app);
+ xargv = dk3app_get_argv(j->app);
+ if (1 < xargc) {
+ xargv++; xargv++; xargc--; xargc--;
+ j->opt = dk3opt_open_app(
+ dkwt_env_options,
+ dkwt_env_szoptions,
+ dkT('\0'),
+ NULL,
+ xargc,
+ xargv,
+ j->app
+ );
+ if (j->opt) {
+ if (0 == dk3opt_get_error_code(j->opt)) {
+ back = 1;
+ if (dk3opt_is_set(j->opt, dkT('s'))) {
+ j->sys = 1;
+ }
+ if (dk3opt_is_set(j->opt, dkT('e'))) {
+ j->exp = 1;
+ }
+ if (dk3opt_is_set(j->opt, dkT('u'))) {
+ j->cmd = DKWT_ENV_CMD_UNSET;
+ }
+ if (dk3opt_is_set(j->opt, dkT('i'))) {
+ if (j->cmd) {
+ j->cmd = DKWT_ENV_CMD_ERROR; back = 0;
+ /* ERROR: -u -i -a -d are mutual exclusive */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 142);
+ } else {
+ j->cmd = DKWT_ENV_CMD_INSERT;
+ }
+ }
+ if (dk3opt_is_set(j->opt, dkT('a'))) {
+ if (j->cmd) {
+ j->cmd = DKWT_ENV_CMD_ERROR; back = 0;
+ /* ERROR: Mutual exclusive */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 142);
+ } else {
+ j->cmd = DKWT_ENV_CMD_APPEND;
+ }
+ }
+ if (dk3opt_is_set(j->opt, dkT('d'))) {
+ if (j->cmd) {
+ j->cmd = DKWT_ENV_CMD_ERROR, back = 0;
+ /* ERROR: Mutual exlusive */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 142);
+ } else {
+ j->cmd = DKWT_ENV_CMD_DELETE;
+ }
+ }
+ if (back) {
+ if (0 >= dk3opt_get_num_args(j->opt)) {
+ j->cmd = DKWT_ENV_CMD_ERROR; back = 0;
+ /* ERROR: At least one argument required */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 143);
+ } else {
+ j->name = dk3opt_get_arg(j->opt, 0);
+ if (!(j->name)) {
+ j->cmd = DKWT_ENV_CMD_ERROR; back = 0; $? "! BUG"
+ }
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+
+/** Check whether an environment variable value contains a directory.
+ @param valptr String to check for a directory name.
+ @param dir Directory name to search for.
+ @return 1 on success (directory found), 0 otherwise.
+*/
+static
+int
+dkwt_env_value_contains_dir(dkChar *valptr, dkChar const *dir)
+{
+ dkChar *pc;
+ dkChar *pn;
+ int back = 0;
+ pc = valptr;
+ while ((0 == back) && (pc)) {
+ pn = dk3str_chr(pc, dkT(';'));
+ if (pn) { *(pn++) = dkT('\0'); }
+ if (0 == dk3str_fncmp(pc, dir)) { back = 1; }
+ pc = pn;
+ }
+ return back;
+}
+
+
+
+/** Process the request.
+ @param j Job structure containing configuration.
+*/
+static
+void
+dkwt_env_do_processing(DKWT_ENV_J *j)
+{
+ dkChar *b1 = NULL; /* Original registry value */
+ dkChar *b2 = NULL; /* Second buffer */
+ dkChar *pc; /* Current part */
+ dkChar *pn; /* Next part */
+ DWORD_PTR dwrv = (DWORD)0UL; /* Return value for message */
+ DWORD dwtf = REG_SZ; /* Type found */
+ HKEY hk = (HKEY)0; /* Registry key */
+ size_t lgt; /* Length */
+ int fmod = 0; /* Flag: Modification */
+ int res = 0; /* Registry operation result */
+ int wre = 0; /* Write expanded */
+ int hco = 0; /* Flag: Contents in out buf */
+
+ switch (j->cmd) {
+ case DKWT_ENV_CMD_NORMAL:
+ case DKWT_ENV_CMD_UNSET:
+ case DKWT_ENV_CMD_INSERT:
+ case DKWT_ENV_CMD_APPEND:
+ case DKWT_ENV_CMD_DELETE:
+ {
+ b1 = dk3_new_app(dkChar, 8192, j->app);
+ if (b1) {
+ if ((DKWT_ENV_CMD_NORMAL == j->cmd) && (!(j->value))) {
+ if (j->sys) {
+ res = dk3wreg_key_open_read(
+ HKEY_LOCAL_MACHINE, dkwt_env_kw[1], &hk, j->app
+ );
+ } else {
+ res = dk3wreg_key_open_read(
+ HKEY_CURRENT_USER, dkwt_env_kw[2], &hk, j->app
+ );
+ }
+ } else {
+ if (j->sys) {
+ res = dk3wreg_key_open_modify(
+ HKEY_LOCAL_MACHINE, dkwt_env_kw[1], &hk, j->app
+ );
+ } else {
+ res = dk3wreg_key_open_modify(
+ HKEY_CURRENT_USER, dkwt_env_kw[2], &hk, j->app
+ );
+ }
+ }
+ if (res) {
+ switch (j->cmd) {
+ case DKWT_ENV_CMD_NORMAL: {
+ if (j->value) {
+ if (dk3wreg_get_expand_sz(hk, j->name, b1, 8191, &dwtf, NULL)) {
+ if (REG_EXPAND_SZ == dwtf) { wre = 1; }
+ } else {
+ if (j->exp) { wre = 1; }
+ }
+ if (wre) {
+ res = dk3wreg_set_expand_sz(hk, j->name, j->value, j->app);
+ } else {
+ res = dk3wreg_set_sz(hk, j->name, j->value, j->app);
+ }
+ if (res) {
+ fmod = 1;
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ } else {
+ if (dk3wreg_get_sz(hk, j->name, b1, 8191, j->app)) {
+ dk3sf_initialize_stdout();
+ dk3sf_fputs(b1, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ }
+ } break;
+ case DKWT_ENV_CMD_UNSET: {
+ if(dk3wreg_entry_delete(hk, j->name, j->app)) {
+ fmod = 1;
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ } break;
+ case DKWT_ENV_CMD_INSERT: {
+ if (j->value) {
+ if (dk3wreg_get_expand_sz(hk, j->name, b1, 8191, &dwtf, NULL)) {
+ lgt = dk3str_len(b1) + dk3str_len(j->value) + 2;
+ b2 = dk3_new_app(dkChar, lgt, j->app);
+ if (b2) {
+ dk3str_cpy(b2, b1);
+ if (!(dkwt_env_value_contains_dir(b2, j->value))) {
+ dk3str_cpy(b2, j->value);
+ dk3str_cat(b2, dkwt_env_kw[3]);
+ dk3str_cat(b2, b1);
+ if (REG_EXPAND_SZ == dwtf) {
+ res = dk3wreg_set_expand_sz(hk, j->name, b2, j->app);
+ } else {
+ res = dk3wreg_set_sz(hk, j->name, b2, j->app);
+ }
+ if (res) {
+ fmod = 1;
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ }
+ dk3_delete(b2);
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ } else {
+ if (j->exp) {
+ res = dk3wreg_set_expand_sz(hk, j->name, j->value, j->app);
+ } else {
+ res = dk3wreg_set_sz(hk, j->name, j->value, j->app);
+ }
+ if (res) {
+ fmod = 1;
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ }
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ /* ERROR: Value required! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 144);
+ }
+ } break;
+ case DKWT_ENV_CMD_APPEND: {
+ if (j->value) {
+ if (dk3wreg_get_expand_sz(hk, j->name, b1, 8191, &dwtf, NULL)) {
+ lgt = dk3str_len(b1) + dk3str_len(j->value) + 2;
+ b2 = dk3_new_app(dkChar, lgt, j->app);
+ if (b2) {
+ dk3str_cpy(b2, b1);
+ if (!(dkwt_env_value_contains_dir(b2, j->value))) {
+ dk3str_cpy(b2, b1);
+ dk3str_cat(b2, dkwt_env_kw[3]);
+ dk3str_cat(b2, j->value);
+ if (REG_EXPAND_SZ == dwtf) {
+ res = dk3wreg_set_expand_sz(hk, j->name, b2, j->app);
+ } else {
+ res = dk3wreg_set_sz(hk, j->name, b2, j->app);
+ }
+ if (res) {
+ fmod = 1;
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ }
+ dk3_delete(b2);
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ } else {
+ if (j->exp) {
+ res = dk3wreg_set_expand_sz(hk, j->name, j->value, j->app);
+ } else {
+ res = dk3wreg_set_sz(hk, j->name, j->value, j->app);
+ }
+ if (res) {
+ fmod = 1;
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ }
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ /* ERROR: Value required! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 144);
+ }
+ } break;
+ case DKWT_ENV_CMD_DELETE: {
+ if (j->value) {
+ if (dk3wreg_get_expand_sz(hk, j->name, b1, 8191, &dwtf, NULL)) {
+ lgt = 1 + dk3str_len(b1);
+ b2 = dk3_new_app(dkChar, lgt, j->app);
+ if (b2) {
+ b2[0] = dkT('\0');
+ pc = b1;
+ while (pc) {
+ pn = dk3str_chr(pc, dkT(';'));
+ if (pn) { *(pn++) = dkT('\0'); }
+ if (dk3str_fncmp(pc, j->value)) {
+ if (hco) {
+ dk3str_cat(b2, dkwt_env_kw[3]);
+ dk3str_cat(b2, pc);
+ } else {
+ dk3str_cpy(b2, pc);
+ }
+ hco = 1;
+ }
+ pc = pn;
+ }
+ if (hco) {
+ if (REG_EXPAND_SZ == dwtf) {
+ res = dk3wreg_set_expand_sz(hk, j->name, b2, j->app);
+ } else {
+ res = dk3wreg_set_sz(hk, j->name, b2, j->app);
+ }
+ if (res) {
+ fmod = 1;
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ } else {
+ if (dk3wreg_entry_delete(hk, j->name, j->app)) {
+ fmod = 1;
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ }
+ dk3_delete(b2);
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ }
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ /* ERROR: Value required! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 144);
+ }
+ } break;
+ }
+ RegCloseKey(hk);
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ dk3_delete(b1);
+ if (fmod) {
+ SendMessageTimeout(
+ HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)"Environment",
+ SMTO_ABORTIFHUNG, 5000, &dwrv
+ );
+ }
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ }
+ break;
+ default: {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ } break;
+ }
+}
+
+
+
+/** Do processing.
+ @param j Job structure containing configuration.
+*/
+static
+void
+dkwt_env_run(DKWT_ENV_J *j)
+{
+ dkChar const *p1; /* Part of the name */
+ dkChar *buffer = NULL; /* Buffer to construct value */
+ size_t vallgt = 0; /* Value length */
+ int i = 0; /* Traverse options */
+
+ j->exv = DKT_RESULT_OK;
+
+ /* Find value length.
+ */
+ vallgt = 0;
+ for (i = 1; i < dk3opt_get_num_args(j->opt); i++) {
+ if (1 < i) { vallgt++; }
+ p1 = dk3opt_get_arg(j->opt, i);
+ if (p1) {
+ vallgt += dk3str_len(p1);
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ }
+ if (vallgt) { vallgt++; }
+
+ /* Create value string.
+ */
+ if (DKT_RESULT_OK == j->exv) {
+ if (0 < vallgt) {
+ buffer = dk3_new_app(dkChar,vallgt,j->app);
+ if (buffer) {
+ j->value = buffer;
+ buffer[0] = dkT('\0');
+ for (i = 1; i < dk3opt_get_num_args(j->opt); i++) {
+ p1 = dk3opt_get_arg(j->opt, i);
+ if (1 < i) {
+ dk3str_cat(buffer, dkwt_env_kw[0]);
+ dk3str_cat(buffer, p1);
+ } else {
+ dk3str_cpy(buffer, p1);
+ }
+ }
+ } else {
+ j->exv = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ }
+ }
+
+ /* Process the request.
+ */
+ if (DKT_RESULT_OK == j->exv) {
+ dkwt_env_do_processing(j);
+ }
+}
+
+
+
+int
+dkwt_env(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl
+)
+{
+ DKWT_ENV_J job;
+ int back = DKT_RESULT_ERR_UNSPECIFIC;
+ $? "+ dkwt_env"
+ dkwt_env_job_init(&job);
+ job.app = app; job.msg = msg; job.kwnl = kwnl;
+ if (dkwt_env_process_args(&job)) {
+ if ((0 != job.sys) && (1 != dkwt_is_admin())) {
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 146);
+ } else {
+ dkwt_env_run(&job);
+ }
+ }
+ back = job.exv;
+ dkwt_env_job_cleanup(&job);
+ $? "- dkwt_env %d", back
+ return back;
+}
+
diff --git a/support/dktools/dkwt-ev.c b/support/dktools/dkwt-ev.c
new file mode 100644
index 0000000000..ec6e6c72d3
--- /dev/null
+++ b/support/dktools/dkwt-ev.c
@@ -0,0 +1,2143 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dkwt-ev.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dkwt-ev.c The dkwt-ev module.
+*/
+
+
+#line 10 "dkwt-ev.ctr"
+
+#include "dk3all.h"
+#include "dkt.h"
+#include "dkwt.h"
+
+
+
+
+
+#line 18 "dkwt-ev.ctr"
+
+
+
+/** Job structure for dkwt boot/login/logout/shutdown.
+*/
+typedef struct {
+ dk3_app_t *app; /**< Application structure. */
+ dkChar const * const *msg; /**< Localized message texts. */
+ dkChar const * const *kwnl; /**< Keywords, not localized. */
+ dk3_option_set_t *opt; /**< Options set. */
+ dkChar const *userName; /**< User name. */
+ dkChar const *profBase; /**< Profile base directory. */
+ dkChar const *systemUser; /**< System user account. */
+ dkChar const *everyUser; /**< Everyone user account. */
+ dk3_sto_t *s_users; /**< Storage users. */
+ dk3_sto_it_t *i_users; /**< Iterator users. */
+ dk3_sto_t *s_pubdir; /**< Storage public directories. */
+ dk3_sto_it_t *i_pubdir; /**< Iterator public directories. */
+ dk3_sto_t *s_queues; /**< Remote queues to clean up. */
+ dk3_sto_it_t *i_queues; /**< Iterator for remote queues. */
+ int exval; /**< Exit status code. */
+ int event; /**< Event to process. */
+ int curSection; /**< Current configuration file sect. */
+ int useIcacls; /**< Flag: Use icalcs. */
+ int clrProfiles; /**< Flag: Clean profiles automatically. */
+ int testOnly; /**< Flag: Test only. */
+ int clp; /**< Flag: Clean up local print queues. */
+} DKWT_EV_J;
+
+
+/** Unknown section type.
+*/
+#define DKWT_EV_SECTION_UNKNOWN (-1)
+
+/** In the options section.
+*/
+#define DKWT_EV_SECTION_OPTIONS 0
+
+/** In the profiles section.
+*/
+#define DKWT_EV_SECTION_PROFILES 1
+
+/** In the public directories section.
+*/
+#define DKWT_EV_SECTION_PUBLIC 2
+
+
+
+/** Configuration file section names.
+*/
+static dkChar const * const dkwt_ev_section_names[] = {
+/* 0 */
+dkT("options"),
+
+/* 1 */
+dkT("profiles"),
+
+/* 2 */
+dkT("public"),
+
+NULL
+
+
+#line 77 "dkwt-ev.ctr"
+};
+
+
+
+/** Configuration file option names.
+*/
+static dkChar const * const dkwt_ev_option_names[] = {
+/* 0 */
+dkT("system-user"),
+
+/* 1 */
+dkT("everyone-user"),
+
+/* 2 */
+dkT("print-jobs"),
+
+NULL
+
+
+#line 92 "dkwt-ev.ctr"
+};
+
+
+
+/** Names of profiles to keep.
+*/
+static dkChar const * const dkwt_ev_profiles_to_keep[] = {
+dkT("All Users"),
+dkT("Default User"),
+dkT("Public"),
+dkT("LocalService"),
+dkT("NetworkService"),
+dkT("Administrator"),
+NULL
+
+
+#line 107 "dkwt-ev.ctr"
+};
+
+
+
+/** Options.
+*/
+static dk3_option_t const dkwt_ev_options[] = {
+ { dkT('t'), dkT("test"), 0 }
+};
+
+/** Number of options in the dkwt_ev_options array.
+*/
+static size_t const dkwt_ev_szoptions =
+sizeof(dkwt_ev_options)/sizeof(dk3_option_t);
+
+
+
+/** Print queue name for local printers.
+*/
+static dkChar const dkwt_pq_name_local[] = { dkT("local") };
+
+
+/** Retrieve value of keep flag.
+ @param app Application structure.
+ @param msg Localized message texts.
+ @param kwnl Keywords, not localized.
+ @param reset Reset the flag.
+ @return Flag value (before reset).
+*/
+static
+int
+dkwt_ev_get_keep_value(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl,
+ int reset
+)
+{
+ long result;
+ DWORD dw0;
+ DWORD dwType;
+ DWORD dwValue;
+ DWORD dwSz;
+ int back = 0;
+ HKEY hk;
+ REGSAM regsam;
+
+
+
+#line 155 "dkwt-ev.ctr"
+ dw0 = (DWORD)0;
+ dwType = REG_DWORD;
+ dwValue = 0;
+ dwSz = sizeof(DWORD);
+ regsam = KEY_QUERY_VALUE;
+ if(reset) {
+ regsam = (KEY_READ | KEY_WRITE);
+ }
+ result = dkwt_tool_reg_open_key(
+ HKEY_LOCAL_MACHINE, kwnl[15], KEY_QUERY_VALUE, &hk
+ );
+ if(result == ERROR_SUCCESS) {
+ result = dkwt_tool_reg_query_value(
+ hk, kwnl[16], &dwType, &dwValue, &dwSz
+ );
+ if(result == ERROR_SUCCESS) {
+ if(dwType == REG_DWORD) {
+ if(dwSz == sizeof(DWORD)) {
+ if(dwValue) {
+ back = 1;
+ }
+ }
+ }
+ }
+ if(reset) {
+ (void)dkwt_tool_reg_delete_value(hk, kwnl[16]);
+ }
+ RegCloseKey(hk);
+ }
+
+
+#line 185 "dkwt-ev.ctr"
+ return back;
+}
+
+
+
+/** Compare two strings.
+ @param l Left string.
+ @param r Right string.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+static
+int
+dkwt_ev_compare_string(void const *l, void const *r, int cr)
+{
+ dkChar const *pl;
+ dkChar const *pr;
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (dkChar const *)l; pr = (dkChar const *)r;
+ back = dk3str_casecmp(pl, pr);
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+ if(back > 1) back = 1;
+ if(back < -1) back = -1;
+ return back;
+}
+
+
+
+/** Initialize job structure.
+ @param j Structure to initialize.
+*/
+static
+void
+dkwt_ev_job_init(DKWT_EV_J *j)
+{
+#if (_MSC_VER < 1800) || DK4_WINDOWS_LEGACY
+ OSVERSIONINFO ovi;
+#endif
+
+ j->app = NULL; j->msg = NULL; j->kwnl = NULL;
+ j->profBase = NULL;
+ j->userName = NULL;
+ j->systemUser = NULL;
+ j->everyUser = NULL;
+ j->s_users = NULL; j->i_users = NULL;
+ j->s_pubdir = NULL; j->i_pubdir = NULL;
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ j->curSection = -1;
+ j->useIcacls = 0;
+ j->testOnly = 0;
+ j->clp = 0;
+ j->opt = NULL;
+ j->s_queues = NULL;
+ j->i_queues = NULL;
+ j->clrProfiles = 0;
+#if (_MSC_VER < 1800) || DK4_WINDOWS_LEGACY
+ ovi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ ovi.dwMajorVersion = 0L;
+ ovi.dwMinorVersion = 0L;
+ ovi.dwBuildNumber = 0L;
+ ovi.dwPlatformId = 0L;
+ if(GetVersionEx(&ovi)) {
+ if(ovi.dwMajorVersion > 5) {
+ j->useIcacls = 1;
+
+#line 258 "dkwt-ev.ctr"
+ } else {
+ if(ovi.dwMajorVersion == 5) {
+ if(ovi.dwMinorVersion > 1) {
+ j->useIcacls = 1;
+
+#line 262 "dkwt-ev.ctr"
+ }
+ }
+ }
+ if(ovi.dwMajorVersion < 6) {
+ j->clrProfiles = 1;
+ }
+ }
+#else
+ if (!IsWindowsVistaOrGreater()) {
+ j->clrProfiles = 1;
+ }
+ if (IsWindowsXPOrGreater()) {
+ j->useIcacls = 1;
+ }
+#endif
+}
+
+
+
+/** Clean up job structure, release memory.
+ @param j Job structure.
+*/
+static
+void
+dkwt_ev_job_cleanup(DKWT_EV_J *j)
+{
+ dkChar *un;
+ void *vp;
+ if(j) {
+ if(j->s_queues) {
+ if(j->i_queues) {
+ dk3sto_it_reset(j->i_queues);
+ while(NULL != (vp = dk3sto_it_next(j->i_queues))) {
+ dk3_delete(vp);
+ }
+ dk3sto_it_close(j->i_queues);
+ }
+ dk3sto_close(j->s_queues);
+ } j->s_queues = NULL; j->i_queues = NULL;
+ if(j->s_users) {
+ if(j->i_users) {
+ dk3sto_it_reset(j->i_users);
+ while((un = (dkChar *)dk3sto_it_next(j->i_users)) != NULL)
+ {
+ dk3_release(un);
+ }
+ dk3sto_it_close(j->i_users);
+ }
+ dk3sto_close(j->s_users);
+ } j->s_users = NULL; j->i_users = NULL;
+ if(j->s_pubdir) {
+ if(j->i_pubdir) {
+ dk3sto_it_reset(j->i_pubdir);
+ while((un = (dkChar *)dk3sto_it_next(j->i_pubdir)) != NULL)
+ {
+ dk3_release(un);
+ }
+ dk3sto_it_close(j->i_pubdir);
+ }
+ dk3sto_close(j->s_pubdir);
+ } j->s_pubdir = NULL; j->i_pubdir = NULL;
+ dk3_release(j->profBase);
+ dk3_release(j->userName);
+ dk3_release(j->systemUser);
+ dk3_release(j->everyUser);
+ if(j->opt) {
+ dk3opt_close(j->opt); j->opt = NULL;
+ }
+ }
+}
+
+
+
+/** Handler for one input line.
+ @param obj Job structure.
+ @param il Input line to process.
+ @return 1 on success, 0 on recoverable error, -1 to abort processing.
+*/
+static
+int
+dkwt_ev_line_handler(void *obj, dkChar *il)
+{
+ DKWT_EV_J *j;
+ dkChar *p1;
+ dkChar *p2;
+ dkChar *p3;
+ dkChar *nq;
+ int back = 1;
+
+
+#line 351 "dkwt-ev.ctr"
+ j = (DKWT_EV_J *)obj;
+ p1 = dk3str_start(il, NULL);
+ if(p1) {
+ if(*p1 != dkT('#')) {
+ back = -1;
+ dk3str_delnl(p1);
+ if(*p1 == dkT('[')) { /* New section header. */
+ p1++;
+ p1 = dk3str_start(p1, NULL);
+ if(p1) {
+ j->curSection = DKWT_EV_SECTION_UNKNOWN;
+ p2 = dk3str_rchr(p1, dkT(']'));
+ if(p2) {
+ *p2 = dkT('\0');
+ p2 = dk3str_next(p1, NULL);
+ switch(dk3str_array_index(dkwt_ev_section_names, p1, 0)) {
+ case 0: {
+ j->curSection = DKWT_EV_SECTION_OPTIONS;
+ back = 1;
+ } break;
+ case 1: {
+ j->curSection = DKWT_EV_SECTION_PROFILES;
+ if(p2) {
+ if(!(j->profBase)) {
+ j->profBase = dk3str_dup_app(p2, j->app);
+ if(j->profBase) {
+ back = 1;
+ } else {
+ back = -1;
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ }
+ } else {
+ back = -1;
+ j->exval = DKT_RESULT_ERR_INPUT;
+ /* ERROR: Redefinition of profile base dir! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 66);
+ }
+ } else {
+ j->exval = DKT_RESULT_ERR_INPUT;
+ /* ERROR: No profile base dir specified! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 67);
+ }
+ } break;
+ case 2: {
+ j->curSection = DKWT_EV_SECTION_PUBLIC; back = 1;
+ } break;
+ default: {
+ back = -1;
+ j->exval = DKT_RESULT_ERR_INPUT;
+ /* ERROR: Unknown section type. */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 68);
+ } break;
+ }
+ } else {
+ back = -1;
+ /* ERROR: Incomplete section header. */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 69);
+ j->exval = DKT_RESULT_ERR_INPUT;
+ }
+ } else {
+ back = -1;
+ /* ERROR: No section header! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 70);
+ j->exval = DKT_RESULT_ERR_INPUT;
+ }
+ } else { /* Section contents line. */
+ switch(j->curSection) {
+ case DKWT_EV_SECTION_OPTIONS: {
+ p2 = dk3str_chr(p1, dkT('='));
+ if(p2) {
+ *(p2++) = dkT('\0');
+ p2 = dk3str_start(p2, NULL);
+ if(p2) {
+ /* dk3str_chomp(p1, NULL); */
+ dk3str_normalize(p1, NULL, dkT('-'));
+#if 0
+ dk3str_normalize(p2, NULL, dkT('-'));
+#endif
+ switch(dk3str_array_index(dkwt_ev_option_names, p1, 0)) {
+ case 0: {
+ if(!(j->systemUser)) {
+ j->systemUser = dk3str_dup_app(p2, j->app);
+ if(j->systemUser) {
+ back = 1;
+ } else {
+ back = -1;
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ }
+ } else {
+ /* ERROR: Redefinition of system user! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 71);
+ back = -1;
+ j->exval = DKT_RESULT_ERR_INPUT;
+ }
+ } break;
+ case 1: {
+ if(!(j->everyUser)) {
+ j->everyUser = dk3str_dup_app(p2, j->app);
+ if(j->everyUser) {
+ back = 1;
+ } else {
+ back = -1;
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ }
+ } else {
+ /* ERROR: Redefinition of everyone user! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 72);
+ back = -1;
+ j->exval = DKT_RESULT_ERR_INPUT;
+ }
+ } break;
+ case 2: {
+ back = 1;
+ while(p2) {
+ p3 = dk3str_next(p2, NULL);
+ if(0 == dk3str_cmp(dkwt_pq_name_local, p2)) {
+ j->clp = 1;
+ } else {
+ if(!(j->s_queues)) {
+ j->s_queues = dk3sto_open_app(j->app);
+ }
+ if(!(j->i_queues)) {
+ if(j->s_queues) {
+ j->i_queues = dk3sto_it_open(j->s_queues);
+ }
+ }
+ if((j->s_queues) && (j->i_queues)) {
+ nq = dk3str_dup_app(p2, j->app);
+ if(nq) {
+ if(!dk3sto_add(j->s_queues, (void *)nq)) {
+ dk3_delete(nq);
+ back = 0;
+ }
+ } else {
+ back = 0;
+ }
+ } else {
+ back = 0;
+ }
+ }
+ p2 = p3;
+ }
+ } break;
+ default: {
+ /* ERROR: Unknown option! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 73);
+ back = -1;
+ j->exval = DKT_RESULT_ERR_INPUT;
+ } break;
+ }
+ } else {
+ /* ERROR: Not a key/value pair */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 74);
+ back = -1;
+ j->exval = DKT_RESULT_ERR_INPUT;
+ }
+ } else {
+ /* ERROR: Not a key/value pair */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 74);
+ back = -1;
+ j->exval = DKT_RESULT_ERR_INPUT;
+ }
+ } break;
+ case DKWT_EV_SECTION_PROFILES: {
+
+#line 515 "dkwt-ev.ctr"
+ dk3str_normalize(p1, NULL, dkT(' '));
+ p2 = dk3str_dup_app(p1, j->app);
+ if(p2) {
+ if(dk3sto_add(j->s_users, (void *)p2)) {
+ back = 1;
+
+#line 520 "dkwt-ev.ctr"
+ } else {
+
+#line 521 "dkwt-ev.ctr"
+ dk3_release(p2);
+ back = -1;
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ }
+ } else {
+
+#line 526 "dkwt-ev.ctr"
+ back = -1;
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ }
+ } break;
+ case DKWT_EV_SECTION_PUBLIC: {
+
+#line 531 "dkwt-ev.ctr"
+ dk3str_normalize(p1, NULL, dkT(' '));
+ p2 = dk3str_dup_app(p1, j->app);
+ if(p2) {
+
+#line 534 "dkwt-ev.ctr"
+ if(dk3sto_add(j->s_pubdir, (void *)p2)) {
+ back = 1;
+
+#line 536 "dkwt-ev.ctr"
+ } else {
+
+#line 537 "dkwt-ev.ctr"
+ dk3_release(p2);
+ back = -1;
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ }
+ } else {
+
+#line 542 "dkwt-ev.ctr"
+ back = -1;
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ }
+ } break;
+ default: {
+ back = -1;
+ j->exval = DKT_RESULT_ERR_INPUT;
+ } break;
+ }
+ }
+ } else {
+ /* Comment line ok. */
+ }
+ } else {
+ /* Empty line ok. */
+ }
+
+#line 558 "dkwt-ev.ctr"
+ return back;
+}
+
+
+
+/** Run a command.
+ @param j Job structure.
+ @param cmd Command to run.
+*/
+static
+void
+dkwt_ev_execute_command(DKWT_EV_J *j, dkChar const *cmd)
+{
+ int value = 0;
+ /* PROGRESS: Execute command ... */
+ dk3app_log_3(j->app, DK3_LL_PROGRESS, j->msg, 118, 119, cmd);
+ dk3sf_initialize_stdout();
+ dk3sf_fputs(cmd, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ if(!(j->testOnly)) {
+#if DK3_CHAR_SIZE > 1
+ value = _wsystem(cmd);
+#else
+ value = system(cmd);
+#endif
+ if(value != 0) {
+ /* ERROR: Command execution failed! */
+ dk3app_log_3(j->app, DK3_LL_ERROR, j->msg, 79, 80, cmd);
+ j->exval = DKT_RESULT_ERR_SYSEXEC;
+ }
+ }
+}
+
+
+
+/** Remove a directory.
+ First attempt to use the RD command, next use own routines.
+ @param j Job structure.
+ @param dn Directory name.
+ @param dolog Flag: Do logging in dk3dir_remove_app().
+*/
+static
+void
+dkwt_ev_remove_directory(DKWT_EV_J *j, dkChar const *dn, int dolog)
+{
+ dkChar bu[2 * DK3_MAX_PATH];
+ dk3_stat_t stb;
+ size_t sz;
+
+
+#line 607 "dkwt-ev.ctr"
+ /* PROGRESS: Remove directory ... */
+ dk3app_log_3(j->app, DK3_LL_PROGRESS, j->msg, 120, 121, dn);
+ if(!(j->testOnly)) {
+#if 0
+ dk3sf_remove_dir(dn);
+#endif
+ dk3dir_remove_app(dn, ((dolog) ? j->app : NULL));
+ if(dk3sf_stat_app(&stb, dn, NULL)) {
+ sz = dk3str_len(dn);
+ sz += dk3str_len((j->kwnl)[4]);
+ sz += dk3str_len((j->kwnl)[5]);
+ if(sz < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy_not_overlapped(bu, (j->kwnl)[4]);
+ dk3str_cat(bu, dn);
+ dk3str_cat(bu, (j->kwnl)[5]);
+ dkwt_ev_execute_command(j, bu);
+ } else {
+
+#line 624 "dkwt-ev.ctr"
+ /* ERROR: File name too long! */
+ dk3app_log_i3(j->app, DK3_LL_ERROR, 59, 60, dn);
+ j->exval = DKT_RESULT_ERR_FILENAME;
+ }
+ }
+ }
+
+
+#line 631 "dkwt-ev.ctr"
+}
+
+
+
+/** Remove a file.
+ First attempt to use the DEL command, next use own routines.
+ @param j Job structure.
+ @param fn File name.
+*/
+static
+void
+dkwt_ev_remove_file(DKWT_EV_J *j, dkChar const *fn)
+{
+ dkChar bu[2 * DK3_MAX_PATH];
+ dk3_stat_t stb;
+ size_t sz;
+
+ /* PROGRESS: Remove file ... */
+ dk3app_log_3(j->app, DK3_LL_PROGRESS, j->msg, 122, 123, fn);
+ if(!(j->testOnly)) {
+ dk3sf_remove_file_app(fn, NULL);
+ if(dk3sf_stat_app(&stb, fn, NULL)) {
+ sz = dk3str_len(fn);
+ sz += dk3str_len((j->kwnl)[6]);
+ sz += dk3str_len((j->kwnl)[5]);
+ if(sz < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy_not_overlapped(bu, (j->kwnl)[6]);
+ dk3str_cat(bu, fn);
+ dk3str_cat(bu, (j->kwnl)[5]);
+ dkwt_ev_execute_command(j, bu);
+ } else {
+ /* ERROR: File name too long! */
+ dk3app_log_i3(j->app, DK3_LL_ERROR, 65, 66, fn);
+ j->exval = DKT_RESULT_ERR_FILENAME;
+ }
+ }
+ }
+}
+
+
+
+/** Check whether or not to keep a profile subdirectory.
+ @param j Job structure.
+ @param un User name (short directory name).
+ @return 1 to keep the directory, 0 to delete it.
+*/
+static
+int
+dkwt_ev_must_keep(DKWT_EV_J *j, dkChar const *un)
+{
+ int back = 0;
+
+
+#line 683 "dkwt-ev.ctr"
+ if(j->userName) {
+ if(dk3str_casecmp(j->userName, un) == 0) {
+ back = 1;
+ }
+ }
+ if(!(back)) {
+ if(dk3sto_it_find_like(j->i_users, (void *)un, 0)) {
+ back = 1;
+ }
+ }
+ if(!(back)) {
+ if(dk3str_array_index(dkwt_ev_profiles_to_keep, un, 0) >= 0) {
+ back = 1;
+ }
+ }
+
+#line 698 "dkwt-ev.ctr"
+ return back;
+}
+
+
+
+#ifdef VERSION_BEFORE_20120320
+/** Clean up the profile directory.
+ @param j Job structure.
+*/
+static
+void
+dkwt_ev_cleanup_profiles(DKWT_EV_J *j)
+{
+ dkChar bu1[DK3_MAX_PATH];
+ dk3_dir_t *dir;
+ dkChar const *en;
+ dkChar const *es;
+ dkChar *ptr;
+ int must_delete = 1;
+
+
+#line 718 "dkwt-ev.ctr"
+ if(j->profBase) {
+ if(j->clrProfiles != 0) {
+ dir = dk3dir_open_app(j->profBase, j->app);
+ if(dir) {
+
+#line 722 "dkwt-ev.ctr"
+ while(dk3dir_get_next_directory(dir)) {
+ en = dk3dir_get_fullname(dir);
+ es = dk3dir_get_shortname(dir);
+ if((en) && (es)) {
+
+#line 726 "dkwt-ev.ctr"
+ must_delete = 1;
+ if(dkwt_ev_must_keep(j, es)) {
+ must_delete = 0;
+
+#line 729 "dkwt-ev.ctr"
+ } else {
+
+#line 730 "dkwt-ev.ctr"
+ if(dk3str_len(es) < DK3_SIZEOF(bu1,dkChar)) {
+ dk3str_cpy_not_overlapped(bu1, es);
+ ptr = dk3str_chr(bu1, dkT('.'));
+ if(ptr) {
+ *ptr = dkT('\0');
+ if(dkwt_ev_must_keep(j, bu1)) {
+ must_delete = 0;
+
+#line 737 "dkwt-ev.ctr"
+ } else {
+
+#line 738 "dkwt-ev.ctr"
+ }
+ } else {
+
+#line 740 "dkwt-ev.ctr"
+ }
+ } else {
+
+#line 742 "dkwt-ev.ctr"
+ must_delete = 0;
+ }
+ }
+
+#line 745 "dkwt-ev.ctr"
+ if(must_delete) {
+
+#line 746 "dkwt-ev.ctr"
+ dkwt_ev_remove_directory(j, en, 0);
+ }
+ }
+ }
+ dk3dir_close(dir);
+ }
+ } else {
+ }
+ }
+
+
+#line 756 "dkwt-ev.ctr"
+}
+#else
+
+
+
+/** Directory entry for deletion.
+*/
+typedef struct {
+ dkChar const *n; /**< Directory name. */
+ char f; /**< Flag: Can delete. */
+} DKWT_EV_DIR;
+
+
+
+/** Release directory name.
+ @param d Directory name entry to delete.
+*/
+static
+void
+dkwt_ev_ddel_del(DKWT_EV_DIR *d)
+{
+ if(d) {
+ dk3_release(d->n);
+ d->f = 0x00;
+ dk3_delete(d);
+ }
+}
+
+
+
+/** Create directory name entry.
+ @param j Job structure.
+ @param fn File name of directory.
+ @return New entry on success, NULL on error.
+*/
+static
+DKWT_EV_DIR *
+dkwt_ev_ddel_new(DKWT_EV_J *j, dkChar const *fn)
+{
+ DKWT_EV_DIR *back = NULL;
+ if(fn) {
+ back = dk3_new_app(DKWT_EV_DIR,1,j->app);
+ if(back) {
+ back->f = 0x01;
+ back->n = dk3str_dup_app(fn, j->app);
+ if(!(back->n)) {
+ dkwt_ev_ddel_del(back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Compare two entries for directories.
+ @param l Left directory object.
+ @param r Right directory object.
+ @param cr Comparison criteria (0=dir/dir, 1=dir/name).
+ @return Comparison result.
+*/
+static
+int
+dkwt_ev_ddel_comp(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ DKWT_EV_DIR const *pl;
+ DKWT_EV_DIR const *pr;
+ if(l) {
+ if(r) {
+ pl = (DKWT_EV_DIR const *)l;
+ switch(cr) {
+ case 1: {
+ if(pl->n) {
+ back = dk3str_casecmp(pl->n, (dkChar const *)r);
+ if(back < -1) back = -1;
+ if(back > 1) back = 1;
+ } else back = -1;
+ } break;
+ default: {
+ pr = (DKWT_EV_DIR const *)r;
+ if(pl->n) {
+ if(pr->n) {
+ back = dk3str_casecmp(pl->n, pr->n);
+ if(back < -1) back = -1;
+ if(back > 1) back = 1;
+ } else back = 1;
+ } else {
+ if(pr->n) back = -1;
+ }
+ } break;
+ }
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ }
+ return back;
+}
+
+
+
+/** Delete a registry key structure for a user profile.
+ @param j Job structure.
+ @param kn Key name (short name).
+*/
+static
+void
+dkwt_ev_del_rk_profile(DKWT_EV_J *j, dkChar const *kn)
+{
+ HKEY hk;
+ long res;
+
+
+#line 869 "dkwt-ev.ctr"
+ /*
+ Log message
+ */
+ /* PROGRESS: Deleting registry key ... */
+ dk3app_log_5(
+ j->app, DK3_LL_PROGRESS,
+ j->msg, 124, 125, 126, (j->kwnl)[19], kn
+ );
+ /*
+ Delete the key.
+ */
+ if(!(j->testOnly)) {
+ res = dkwt_tool_reg_open_key(
+ HKEY_LOCAL_MACHINE, (j->kwnl)[19], KEY_ALL_ACCESS, &hk
+ );
+ if(ERROR_SUCCESS == res) {
+
+#line 885 "dkwt-ev.ctr"
+ res = dkwt_tool_reg_delete_tree(hk, kn);
+ if(ERROR_SUCCESS == res) {
+
+#line 887 "dkwt-ev.ctr"
+ /* DEBUG: Registry key ... deleted. */
+ dk3app_log_3(j->app, DK3_LL_DEBUG, j->msg, 127, 128, kn);
+ } else {
+
+#line 890 "dkwt-ev.ctr"
+ /* ERROR: Failed to remove registry hierarchy ... */
+ dk3app_log_5(
+ j->app, DK3_LL_ERROR, j->msg,
+ 129, 130, 131, (j->kwnl)[19], kn
+ );
+ }
+ RegCloseKey(hk);
+ } else {
+
+#line 898 "dkwt-ev.ctr"
+ /* ERROR: Failed to open registry key ... */
+ dk3app_log_3(j->app, DK3_LL_ERROR, j->msg, 132, 133, (j->kwnl)[19]);
+ }
+ }
+
+
+#line 903 "dkwt-ev.ctr"
+}
+
+
+
+/** Clean up the profile directory.
+ @param j Job structure.
+*/
+static
+void
+dkwt_ev_cleanup_profiles(DKWT_EV_J *j)
+{
+ dkChar knb[DK3_MAX_PATH]; /* Buffer for key name. */
+ dkChar ppb[DK3_MAX_PATH]; /* Profile path buffer. */
+ dkChar esb[DK3_MAX_PATH]; /* Expanded string buffer. */
+ dkChar bu1[DK3_MAX_PATH]; /* Buffer for full file name. */
+ void *vp; /* void pointer for cleanup. */
+ dk3_sto_t *s_fn; /* Storage of directories to delete. */
+ dk3_sto_it_t *i_fn; /* Iterator for directory storage. */
+ dk3_sto_t *s_rk; /* Storage for registry keys. */
+ dk3_sto_it_t *i_rk; /* Iterator for registry keys storage. */
+ dk3_sto_t *s_rd; /* Storage for registry keys to delete. */
+ dk3_sto_it_t *i_rd; /* Iterator for keys to delete. `*/
+ dk3_dir_t *dir; /* Directory. */
+ dkChar const *en; /* Entry name. */
+ dkChar const *es; /* Short entry name. */
+ dkChar const *kn; /* Current key name, copy. */
+ dkChar *ptr; /* Pointer to dot in file name. */
+ DKWT_EV_DIR *ddel; /* Directory to delete. */
+ HKEY hk; /* Handle for registry key. */
+ REGSAM regs; /* Access type to registry key. */
+ long res; /* Result from operation. */
+ size_t stlgt; /* String length. */
+ DWORD dw0; /* Used to open registry keys. */
+ DWORD dwInd; /* INdex of current key. */
+ DWORD dwSz; /* Size of knb buffer. */
+ DWORD dwEx; /* Result from string expansion. */
+ DWORD dwTp; /* Result type. */
+ int md; /* Flag: Must delete this entry. */
+ int ec; /* Error code. */
+
+
+#line 943 "dkwt-ev.ctr"
+ ec = 0;
+ if(j->profBase) {
+ /* PROGRESS: Cleanin up profiles (start) */
+ dk3app_log_1(j->app, DK3_LL_PROGRESS, j->msg, 134);
+ s_fn = dk3sto_open_app(j->app);
+ if(s_fn) {
+ dk3sto_set_comp(s_fn, dkwt_ev_ddel_comp, 0);
+ i_fn = dk3sto_it_open(s_fn);
+ if(i_fn) {
+ s_rk = dk3sto_open_app(j->app);
+ if(s_rk) {
+ dk3sto_set_comp(s_rk, dkwt_ev_compare_string, 0);
+ i_rk = dk3sto_it_open(s_rk);
+ if(i_rk) {
+ s_rd = dk3sto_open_app(j->app);
+ if(s_rd) {
+ i_rd = dk3sto_it_open(s_rd);
+ if(i_rd) {
+ /* DEBUG: Storages ok. */
+ dir = dk3dir_open_app(j->profBase, j->app);
+ if(dir) {
+ /* DEBUG: Directory opened successfully. */
+ while(dk3dir_get_next_directory(dir)) {
+ en = dk3dir_get_fullname(dir);
+ es = dk3dir_get_shortname(dir);
+ if((en) && (es)) {
+
+#line 969 "dkwt-ev.ctr"
+ md = 1;
+ if(dkwt_ev_must_keep(j, es)) {
+ md = 0;
+ } else {
+ if(dk3str_len(es) < DK3_SIZEOF(bu1,dkChar)) {
+ dk3str_cpy_not_overlapped(bu1, es);
+ ptr = dk3str_chr(bu1, dkT('.'));
+ if(ptr) {
+ *ptr = dkT('\0');
+ if(dkwt_ev_must_keep(j, bu1)) {
+ md = 0;
+ }
+ }
+ } else {
+
+#line 983 "dkwt-ev.ctr"
+ /* ERROR: Name too long! */
+ dk3app_log_i3(j->app, DK3_LL_ERROR, 59, 60, es);
+ if(!(ec)) { ec = DK3_ERROR_TOO_LARGE; }
+ md = 0;
+ }
+ }
+
+#line 989 "dkwt-ev.ctr"
+ if(md) {
+ ddel = dkwt_ev_ddel_new(j, en);
+ if(ddel) {
+ if(!dk3sto_add(s_fn, (void *)ddel)) {
+
+#line 993 "dkwt-ev.ctr"
+ dkwt_ev_ddel_del(ddel);
+ if(!(ec)) { ec = DK3_ERROR_MEMORY; }
+ }
+ } else {
+
+#line 997 "dkwt-ev.ctr"
+ if(!(ec)) { ec = DK3_ERROR_MEMORY; }
+ }
+ }
+ } else {
+
+#line 1001 "dkwt-ev.ctr"
+ /* ERROR: Failed to obtain name for directory entry! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 135);
+ if(!(ec)) { ec = DK3_ERROR_SYSTEM; }
+ }
+ }
+ dk3dir_close(dir);
+ /*
+ Now search the registry keys
+ */
+ dw0 = (DWORD)0;
+ regs = KEY_READ;
+ res = dkwt_tool_reg_open_key(
+ HKEY_LOCAL_MACHINE, (j->kwnl)[19], KEY_READ, &hk
+ );
+ if(ERROR_SUCCESS == res) {
+ dwInd = 0;
+ do {
+ dwSz = DK3_SIZEOF(knb,dkChar);
+ res = dkwt_tool_reg_enum_key(
+ hk, dwInd, knb, &dwSz, NULL, NULL, NULL
+ );
+ if(ERROR_SUCCESS == res) {
+ if(dwSz > 0) {
+ kn = dk3str_dup_app(knb, j->app);
+ if(kn) {
+ if(!dk3sto_add(s_rk, (void *)kn)) {
+
+#line 1027 "dkwt-ev.ctr"
+ dk3_delete(kn);
+ if(!(ec)) { ec = DK3_ERROR_MEMORY; }
+ }
+ } else {
+
+#line 1031 "dkwt-ev.ctr"
+ if(!(ec)) { ec = DK3_ERROR_MEMORY; }
+ }
+ }
+ } else {
+
+#line 1035 "dkwt-ev.ctr"
+ if(res != ERROR_NO_MORE_ITEMS) {
+ if(!(ec)) { ec = DK3_ERROR_DURING_READ; }
+ }
+ }
+ dwInd++;
+ } while(res != ERROR_NO_MORE_ITEMS);
+ RegCloseKey(hk);
+ /*
+ For each key found check whether ProfileImagePath is in s_fn.
+ */
+ dk3sto_it_reset(i_rk);
+ while(NULL != (kn = (dkChar const *)dk3sto_it_next(i_rk))) {
+ stlgt = dk3str_len((j->kwnl)[19]);
+ stlgt++;
+ stlgt += dk3str_len(kn);
+ if(stlgt < DK3_SIZEOF(knb,dkChar)) {
+ dk3str_cpy_not_overlapped(knb, (j->kwnl)[19]);
+ dk3str_cat(knb, (j->kwnl)[20]);
+ dk3str_cat(knb, kn);
+ dw0 = 0;
+ regs = KEY_QUERY_VALUE;
+ res = dkwt_tool_reg_open_key(
+ HKEY_LOCAL_MACHINE, knb, KEY_QUERY_VALUE, &hk
+ );
+ if(ERROR_SUCCESS == res) {
+ dwTp = REG_EXPAND_SZ;
+ dwSz = sizeof(ppb);
+ res = dkwt_tool_reg_query_value(
+ hk, (j->kwnl)[21], &dwTp, ppb, &dwSz
+ );
+ if(ERROR_SUCCESS == res) {
+#if DK3_CHAR_SIZE > 1
+ if(dwSz < (sizeof(ppb) - 1)) {
+ ppb[dwSz] = '\0';
+ ppb[dwSz+1] = '\0';
+ } else {
+ ppb[sizeof(ppb)-2] = '\0';
+ ppb[sizeof(ppb)-1] = '\0';
+ }
+#else
+ if(dwSz < sizeof(ppb)) {
+ ppb[dwSz] = '\0';
+ } else {
+ ppb[sizeof(ppb)-1] = '\0';
+ }
+#endif
+ switch(dwTp) {
+ case REG_SZ: {
+ ddel = (DKWT_EV_DIR *)dk3sto_it_find_like(
+ i_fn, (void *)ppb, 1
+ );
+ if(ddel) {
+ /* Save kn as registry key to delete */
+ if(!dk3sto_add(s_rd, (void *)kn)) {
+
+#line 1089 "dkwt-ev.ctr"
+ ddel->f = 0x00;
+ if(!(ec)) { ec = DK3_ERROR_MEMORY; }
+ }
+ }
+ } break;
+ case REG_EXPAND_SZ: {
+ dwEx = ExpandEnvironmentStrings(
+ ppb,
+ esb,
+ DK3_SIZEOF(esb,dkChar)
+ );
+ if(dwEx > 0) {
+ if(dwEx < DK3_SIZEOF(esb,dkChar)) {
+ ddel = (DKWT_EV_DIR *)dk3sto_it_find_like(
+ i_fn, (void *)esb, 1
+ );
+ if(ddel) {
+ /* Save kn as registry key to delete */
+ if(!dk3sto_add(s_rd,(void *)kn)) {
+
+#line 1108 "dkwt-ev.ctr"
+ ddel->f = 0x00;
+ if(!(ec)) { ec = DK3_ERROR_MEMORY; }
+ }
+ }
+ } else {
+
+#line 1113 "dkwt-ev.ctr"
+ /* ERROR: String too long! */
+ dk3app_log_3(
+ j->app, DK3_LL_ERROR, j->msg,
+ 136, 137, ppb
+ );
+ if(!(ec)) { ec = DK3_ERROR_TOO_LARGE; }
+ }
+ } else {
+ ddel = (DKWT_EV_DIR *)dk3sto_it_find_like(
+ i_fn, (void *)ppb, 1
+ );
+ if(ddel) {
+ /* Save kn as registry key to delete */
+ if(!dk3sto_add(s_rd, (void *)kn)) {
+
+#line 1127 "dkwt-ev.ctr"
+ ddel->f = 0x00;
+ if(!(ec)) { ec = DK3_ERROR_MEMORY; }
+ }
+ }
+ }
+ } break;
+ }
+ }
+ RegCloseKey(hk);
+ } else {
+
+#line 1137 "dkwt-ev.ctr"
+ /* ERROR: Failed to open registry key ... */
+ dk3app_log_3(
+ j->app, DK3_LL_ERROR, j->msg, 132, 133, knb
+ );
+ if(!(ec)) { ec = DK3_ERROR_NOT_OPENED_FOR_READING; }
+ }
+ } else {
+
+#line 1144 "dkwt-ev.ctr"
+ /* ERROR: Key name too long! */
+ dk3app_log_3(j->app, DK3_LL_ERROR, j->msg, 138, 139, kn);
+ if(!(ec)) { ec = DK3_ERROR_TOO_LARGE; }
+ }
+ }
+ } else {
+
+#line 1150 "dkwt-ev.ctr"
+ /* ERROR: Failed to open registry key! */
+ dk3app_log_3(
+ j->app, DK3_LL_ERROR, j->msg, 132, 133, (j->kwnl)[19]
+ );
+ if(!(ec)) { ec = DK3_ERROR_NOT_OPENED_FOR_READING; }
+ }
+ } else {
+
+#line 1157 "dkwt-ev.ctr"
+ }
+ if(!(ec)) {
+
+#line 1159 "dkwt-ev.ctr"
+ dk3sto_it_reset(i_rd);
+ while(NULL != (kn = (dkChar const *)dk3sto_it_next(i_rd))) {
+ /*
+ */
+ dkwt_ev_del_rk_profile(j, kn);
+ }
+ } else {
+ /* ERROR: Skipping profile cleanup due to previous errors! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 140);
+ }
+ /*
+ In s_rd and i_rd we have copies of strings from s_rk and i_rk.
+ No deletion necessary.
+ */
+ dk3sto_it_close(i_rd);
+ } else {
+
+#line 1175 "dkwt-ev.ctr"
+ }
+ dk3sto_close(s_rd);
+ } else {
+
+#line 1178 "dkwt-ev.ctr"
+ }
+ dk3sto_it_reset(i_rk);
+ while(NULL != (vp = dk3sto_it_next(i_rk))) {
+ dk3_delete(vp);
+ }
+ dk3sto_it_close(i_rk);
+ } else {
+
+#line 1185 "dkwt-ev.ctr"
+ }
+ dk3sto_close(s_rk);
+ } else {
+
+#line 1188 "dkwt-ev.ctr"
+ }
+ dk3sto_it_reset(i_fn);
+ while(NULL != (ddel = (DKWT_EV_DIR *)dk3sto_it_next(i_fn))) {
+ /*
+ Remove the directory.
+ */
+ if(!(ec)) {
+ if(ddel->f) {
+ dkwt_ev_remove_directory(j, ddel->n, 0);
+ }
+ }
+ /*
+ Free list entry.
+ */
+ dkwt_ev_ddel_del(ddel);
+ }
+ dk3sto_it_close(i_fn); i_fn = NULL;
+ } else {
+
+#line 1206 "dkwt-ev.ctr"
+ }
+ dk3sto_close(s_fn); s_fn = NULL;
+ } else {
+
+#line 1209 "dkwt-ev.ctr"
+ }
+ /* PROGRESS: Cleaning up profiles (finished). */
+ dk3app_log_1(j->app, DK3_LL_PROGRESS, j->msg, 141);
+ } else {
+
+#line 1213 "dkwt-ev.ctr"
+ }
+
+
+#line 1215 "dkwt-ev.ctr"
+}
+
+
+#endif
+
+
+
+/** Clean up public directories.
+ @param j Job structure.
+*/
+static
+void
+dkwt_ev_cleanup_public(DKWT_EV_J *j)
+{
+ dkChar const *fn;
+ dkChar const *en;
+ dk3_dir_t *dir;
+
+
+#line 1233 "dkwt-ev.ctr"
+ dk3sto_it_reset(j->i_pubdir);
+ while((fn = (dkChar const *)dk3sto_it_next(j->i_pubdir)) != NULL) {
+ dir = dk3dir_open_app(fn, j->app);
+ if(dir) {
+ while(dk3dir_get_next_directory(dir)) {
+ en = dk3dir_get_fullname(dir);
+ if(en) {
+ dkwt_ev_remove_directory(j, en, 1);
+ }
+ }
+ while(dk3dir_get_next_file(dir)) {
+ en = dk3dir_get_fullname(dir);
+ if(en) {
+ dkwt_ev_remove_file(j, en);
+ }
+ }
+ dk3dir_close(dir);
+ }
+ }
+
+
+#line 1253 "dkwt-ev.ctr"
+}
+
+
+
+/** Change permissions for one path.
+ @param j Job structure.
+ @param fn File name.
+ @param un User name.
+ @param isdir Flag: Is directory.
+*/
+static
+void
+dkwt_ev_user_permissions(
+ DKWT_EV_J *j, dkChar const *fn, dkChar const *un, int isdir
+)
+{
+ dkChar bu[2 * DK3_MAX_PATH];
+ size_t sz = 0;
+
+
+#line 1272 "dkwt-ev.ctr"
+ if(j->useIcacls) {
+ if(isdir) {
+ sz = dk3str_len((j->kwnl)[10]);
+ sz += dk3str_len(fn);
+ sz += dk3str_len((j->kwnl)[11]);
+ sz += dk3str_len(un);
+ sz += dk3str_len((j->kwnl)[12]);
+ if(sz < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy_not_overlapped(bu, (j->kwnl)[10]);
+ dk3str_cat(bu, fn);
+ dk3str_cat(bu, (j->kwnl)[11]);
+ dk3str_cat(bu, un);
+ dk3str_cat(bu, (j->kwnl)[12]);
+ dkwt_ev_execute_command(j, bu);
+ } else {
+ /* ERROR: Line too long! */
+ dk3app_log_i3(j->app, DK3_LL_ERROR, 65, 66, fn);
+ j->exval = DKT_RESULT_ERR_FILENAME;
+ }
+ } else {
+ sz = dk3str_len((j->kwnl)[10]);
+ sz += dk3str_len(fn);
+ sz += dk3str_len((j->kwnl)[11]);
+ sz += dk3str_len(un);
+ sz += dk3str_len((j->kwnl)[13]);
+ if(sz < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy_not_overlapped(bu, (j->kwnl)[10]);
+ dk3str_cat(bu, fn);
+ dk3str_cat(bu, (j->kwnl)[11]);
+ dk3str_cat(bu, un);
+ dk3str_cat(bu, (j->kwnl)[13]);
+ dkwt_ev_execute_command(j, bu);
+ } else {
+ /* ERROR: Line too long! */
+ dk3app_log_i3(j->app, DK3_LL_ERROR, 65, 66, fn);
+ j->exval = DKT_RESULT_ERR_FILENAME;
+ }
+ }
+ } else {
+ if(isdir) {
+ sz = dk3str_len((j->kwnl)[7]);
+ sz += dk3str_len(fn);
+ sz += dk3str_len((j->kwnl)[8]);
+ sz += dk3str_len(un);
+ sz += dk3str_len((j->kwnl)[9]);
+ if(sz < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy_not_overlapped(bu, (j->kwnl)[7]);
+ dk3str_cat(bu, fn);
+ dk3str_cat(bu, (j->kwnl)[8]);
+ dk3str_cat(bu, un);
+ dk3str_cat(bu, (j->kwnl)[9]);
+ dkwt_ev_execute_command(j, bu);
+ } else {
+ /* ERROR: Line too long! */
+ dk3app_log_i3(j->app, DK3_LL_ERROR, 65, 66, fn);
+ j->exval = DKT_RESULT_ERR_FILENAME;
+ }
+ } else {
+ sz = dk3str_len((j->kwnl)[7]);
+ sz += dk3str_len(fn);
+ sz += dk3str_len((j->kwnl)[14]);
+ sz += dk3str_len(un);
+ sz += dk3str_len((j->kwnl)[9]);
+ if(sz < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy_not_overlapped(bu, (j->kwnl)[7]);
+ dk3str_cat(bu, fn);
+ dk3str_cat(bu, (j->kwnl)[14]);
+ dk3str_cat(bu, un);
+ dk3str_cat(bu, (j->kwnl)[9]);
+ dkwt_ev_execute_command(j, bu);
+ } else {
+ /* ERROR: Line too long! */
+ dk3app_log_i3(j->app, DK3_LL_ERROR, 65, 66, fn);
+ j->exval = DKT_RESULT_ERR_FILENAME;
+ }
+ }
+ }
+
+
+#line 1350 "dkwt-ev.ctr"
+}
+
+
+
+/** Change permissions for one path.
+ @param j Job structure.
+ @param fn File name.
+ @param isdir Flag: Is directory.
+*/
+static
+void
+dkwt_ev_permissions(DKWT_EV_J *j, dkChar const *fn, int isdir)
+{
+
+
+#line 1364 "dkwt-ev.ctr"
+ if(j->systemUser) {
+ dkwt_ev_user_permissions(j, fn, j->systemUser, isdir);
+ } else {
+ dkwt_ev_user_permissions(j, fn, (j->kwnl)[2], isdir);
+ }
+ if(j->everyUser) {
+ dkwt_ev_user_permissions(j, fn, j->everyUser, isdir);
+ } else {
+ dkwt_ev_user_permissions(j, fn, (j->kwnl)[3], isdir);
+ }
+
+
+#line 1375 "dkwt-ev.ctr"
+}
+
+
+
+/** Change permissions to own profile, grant full access
+ to system and everyone.
+ @param j Job structure.
+*/
+static
+void
+dkwt_ev_permissions_profile(DKWT_EV_J *j)
+{
+ dkChar bu[DK3_MAX_PATH];
+ size_t sz;
+
+
+#line 1390 "dkwt-ev.ctr"
+ if((j->profBase) && (j->userName)) {
+ sz = dk3str_len(j->profBase);
+ sz += dk3str_len(j->userName);
+ sz += 1;
+ if(sz < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy_not_overlapped(bu, j->profBase);
+ dk3str_cat(bu, dk3app_not_localized(20));
+ dk3str_cat(bu, j->userName);
+ dkwt_ev_permissions(j, bu, 1);
+ }
+ }
+
+
+#line 1402 "dkwt-ev.ctr"
+}
+
+
+
+/** Change permissions to public directory contents, grant full
+ access to system and everyone.
+ @param j Job structure.
+*/
+static
+void
+dkwt_ev_permissions_public(DKWT_EV_J *j)
+{
+ dkChar const *fn;
+ dkChar const *en;
+ dk3_dir_t *dir;
+
+
+#line 1418 "dkwt-ev.ctr"
+ dk3sto_it_reset(j->i_pubdir);
+ while((fn = (dkChar const *)dk3sto_it_next(j->i_pubdir)) != NULL) {
+ dir = dk3dir_open_app(fn, j->app);
+ if(dir) {
+ while(dk3dir_get_next_directory(dir)) {
+ en = dk3dir_get_fullname(dir);
+ if(en) {
+ dkwt_ev_permissions(j, en, 1);
+ }
+ }
+ while(dk3dir_get_next_file(dir)) {
+ en = dk3dir_get_fullname(dir);
+ if(en) {
+ dkwt_ev_permissions(j, en, 0);
+ }
+ }
+ dk3dir_close(dir);
+ }
+ }
+
+
+#line 1438 "dkwt-ev.ctr"
+}
+
+
+
+/** Do processing.
+ @param j Job structure.
+*/
+static
+void
+dkwt_ev_do_processing(DKWT_EV_J *j)
+{
+
+
+#line 1450 "dkwt-ev.ctr"
+ switch(j->event) {
+ case 0: {
+
+#line 1452 "dkwt-ev.ctr"
+ if(!dkwt_ev_get_keep_value(j->app, j->msg, j->kwnl, 0)) {
+ if(j->clrProfiles != 0) {
+ dkwt_ev_cleanup_profiles(j);
+ }
+ dkwt_ev_cleanup_public(j);
+ }
+ } break;
+ case 1: {
+
+#line 1460 "dkwt-ev.ctr"
+ if(!dkwt_ev_get_keep_value(j->app, j->msg, j->kwnl, 0)) {
+ if(j->clrProfiles != 0) {
+ dkwt_ev_cleanup_profiles(j);
+ }
+ dkwt_ev_cleanup_public(j);
+ }
+ } break;
+ case 2: {
+
+#line 1468 "dkwt-ev.ctr"
+ if(!dkwt_ev_get_keep_value(j->app, j->msg, j->kwnl, 1)) {
+ if(j->clrProfiles != 0) {
+ dkwt_ev_cleanup_profiles(j);
+ }
+ dkwt_ev_cleanup_public(j);
+ }
+ } break;
+ case 3: {
+
+#line 1476 "dkwt-ev.ctr"
+ if(j->clrProfiles != 0) {
+ dkwt_ev_permissions_profile(j);
+ }
+ dkwt_ev_permissions_public(j);
+ if(!dkwt_ev_get_keep_value(j->app, j->msg, j->kwnl, 0)) {
+ if(j->clrProfiles != 0) {
+ dkwt_ev_cleanup_profiles(j);
+ }
+ dkwt_ev_cleanup_public(j);
+ }
+ if(j->clp) {
+ dkwt_clear_printers_local(j->app, j->msg, j->kwnl, j->userName);
+ }
+ if((j->s_queues) && (j->i_queues)) {
+ dkwt_clear_printers_remote(j->app, j->msg, j->kwnl, j->userName, j->i_queues);
+ }
+ } break;
+ case 4: {
+
+#line 1494 "dkwt-ev.ctr"
+ if (1 == dkwt_is_admin()) {
+ dkwt_ev_cleanup_profiles(j);
+ } else {
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 145);
+ }
+ } break;
+ }
+
+
+#line 1502 "dkwt-ev.ctr"
+}
+
+
+
+/** Find account name for a SID.
+ @param j Job structure.
+ @param dp Destination buffer.
+ @param ind Index of string SID in message array.
+*/
+static
+void
+dkwt_find_account_name_for_sid(
+ DKWT_EV_J *j,
+ dkChar const * *dp,
+ size_t ind
+)
+{
+ dkChar b1[DK3_MAX_PATH];
+ dkChar b2[DK3_MAX_PATH];
+ PSID psid;
+ DWORD dwSz1;
+ DWORD dwSz2;
+ int success = 0;
+ BOOL res;
+ SID_NAME_USE sidNameUse;
+
+ dwSz1 = DK3_SIZEOF(b1,dkChar);
+ dwSz2 = DK3_SIZEOF(b2,dkChar);
+ psid = NULL;
+#if DK3_CHAR_SIZE > 1
+ res = ConvertStringSidToSidW((j->kwnl)[ind], &psid);
+#else
+ res = ConvertStringSidToSidA((j->kwnl)[ind], &psid);
+#endif
+ if(res) {
+ if(psid) {
+#if DK3_CHAR_SIZE > 1
+ res = LookupAccountSidW(
+ NULL,
+ psid,
+ b1,
+ &dwSz1,
+ b2,
+ &dwSz2,
+ &sidNameUse
+ );
+#else
+ res = LookupAccountSidA(
+ NULL,
+ psid,
+ b1,
+ &dwSz1,
+ b2,
+ &dwSz2,
+ &sidNameUse
+ );
+#endif
+ if(res) {
+ if(dwSz1 > 0) {
+ if(dwSz1 < DK3_SIZEOF(b1,dkChar)) {
+ b1[dwSz1] = dkT('\0');
+ } else {
+ b1[DK3_SIZEOF(b1,dkChar) - 1] = dkT('\0');
+ }
+ if(dk3str_len(b1) > 0) {
+ *dp = dk3str_dup_app(b1, NULL);
+ if(*dp) {
+ success = 1;
+ } else {
+
+#line 1571 "dkwt-ev.ctr"
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ }
+ } else {
+
+#line 1574 "dkwt-ev.ctr"
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ } else {
+
+#line 1577 "dkwt-ev.ctr"
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ } else {
+
+#line 1580 "dkwt-ev.ctr"
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ LocalFree(psid);
+ } else {
+
+#line 1584 "dkwt-ev.ctr"
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ } else {
+
+#line 1587 "dkwt-ev.ctr"
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ if(!(success)) {
+ /* ERROR: Failed to find Group name for SID! */
+ dk3app_log_3(j->app, DK3_LL_ERROR, j->msg, 80, 81, (j->kwnl)[ind]);
+ }
+}
+
+
+
+/** Complete account names for system and everyone user.
+ @param j Job structure.
+*/
+static
+void
+dkwt_complete_account_names(
+ DKWT_EV_J *j
+)
+{
+ if(!(j->systemUser)) {
+ dkwt_find_account_name_for_sid(j, &(j->systemUser), 18);
+ }
+ if(!(j->everyUser)) {
+ dkwt_find_account_name_for_sid(j, &(j->everyUser), 17);
+ }
+}
+
+
+
+/** Run with a found configuration file name.
+ Process the configuration file and call dkwt_ev_do_processing().
+ @param j Job structure.
+ @param fn Configuration file name.
+*/
+static
+void
+dkwt_ev_run_with_config_file_name(DKWT_EV_J *j, dkChar const *fn)
+{
+ dkChar bu[DK3_MAX_PATH];
+ dkwt_account_list_t *al;
+ dkwt_account_t *ac;
+ dkChar *p1;
+ int ok = 0;
+
+
+#line 1631 "dkwt-ev.ctr"
+ ok = dk3stream_process_filename_lines_app(
+ (void *)j,
+ dkwt_ev_line_handler,
+ fn,
+ bu,
+ DK3_SIZEOF(bu,dkChar),
+ dk3app_get_encoding(j->app),
+ dk3app_get_input_file_encoding(j->app),
+ j->app
+ );
+ if(ok) {
+
+#line 1642 "dkwt-ev.ctr"
+ dkwt_complete_account_names(j);
+ al = dkwt_tool_open_account_list(j->app, 0);
+ if(al) {
+
+#line 1645 "dkwt-ev.ctr"
+ dkwt_tool_reset_account_list(al);
+ while((ac = dkwt_tool_get_account_from_list(al)) != NULL) {
+ p1 = dk3str_dup_app(ac->logname, j->app);
+ if(p1) {
+
+#line 1649 "dkwt-ev.ctr"
+ if(!(dk3sto_add(j->s_users, (void *)p1))) {
+ ok = 0;
+
+#line 1651 "dkwt-ev.ctr"
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ dk3_release(p1);
+ }
+ } else {
+
+#line 1655 "dkwt-ev.ctr"
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ }
+ }
+ dkwt_tool_close_account_list(al);
+ if(ok) {
+
+#line 1660 "dkwt-ev.ctr"
+ dkwt_ev_do_processing(j);
+ } else {
+
+#line 1662 "dkwt-ev.ctr"
+ }
+ } else {
+
+#line 1664 "dkwt-ev.ctr"
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ } else {
+
+#line 1667 "dkwt-ev.ctr"
+ }
+
+#line 1668 "dkwt-ev.ctr"
+}
+
+
+
+/** Continue after allocating the storages.
+ Find the users login name if necessary and one configuration file
+ and call dkwt_ev_run_with_config_file_name().
+ @param j Job structure.
+*/
+static
+void
+dkwt_ev_run_with_storages(DKWT_EV_J *j)
+{
+ dkChar bu[DK3_MAX_PATH]; /* Buffer for user name. */
+ dkChar const *fn; /* Configuration file name. */
+ dk3_search_t *sr; /* Search result. */
+ int ok = 1; /* Flag: OK so far. */
+
+
+#line 1686 "dkwt-ev.ctr"
+ switch(j->event) {
+ case 2: case 3: {
+ ok = 0;
+ if(dk3sf_get_logname_app(bu, DK3_SIZEOF(bu,dkChar), j->app)) {
+ j->userName = dk3str_dup_app(bu, j->app);
+ if(j->userName) {
+ ok = 1;
+ } else {
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ }
+ } else {
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ } break;
+ }
+ if(ok) {
+
+#line 1702 "dkwt-ev.ctr"
+ sr = dk3app_find_config_file_revers(j->app, (j->kwnl)[1], 1);
+ if(sr) {
+
+#line 1704 "dkwt-ev.ctr"
+ dk3search_reset(sr);
+ fn = dk3search_next(sr);
+ if(fn) {
+
+#line 1707 "dkwt-ev.ctr"
+ dkwt_ev_run_with_config_file_name(j, fn);
+ } else {
+
+#line 1709 "dkwt-ev.ctr"
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ dk3search_close(sr);
+ } else {
+
+#line 1713 "dkwt-ev.ctr"
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ } else {
+
+#line 1716 "dkwt-ev.ctr"
+ }
+
+#line 1717 "dkwt-ev.ctr"
+}
+
+
+
+/** Run for event.
+ Allocate the storages needed later und call dkwt_ev_run_with_storages().
+ @param j Job structure.
+*/
+static
+void
+dkwt_ev_run(DKWT_EV_J *j)
+{
+ dkChar const * const *xargv;
+ int xargc;
+
+
+#line 1732 "dkwt-ev.ctr"
+ xargc = dk3app_get_argc(j->app);
+ xargv = dk3app_get_argv(j->app);
+ xargv++; xargv++; xargc--; xargc--;
+ j->opt = dk3opt_open_app(
+ dkwt_ev_options,
+ dkwt_ev_szoptions,
+ dkT('\0'),
+ NULL,
+ xargc,
+ xargv,
+ j->app
+ );
+ if(j->opt) {
+ if(0 == dk3opt_get_error_code(j->opt)) {
+ if(dk3opt_is_set(j->opt, dkT('t'))) {
+ j->testOnly = 1;
+ }
+ j->s_users = dk3sto_open_app(j->app);
+ if(j->s_users) {
+ dk3sto_set_comp(j->s_users, dkwt_ev_compare_string, 0);
+ j->i_users = dk3sto_it_open(j->s_users);
+ if(j->i_users) {
+ j->s_pubdir= dk3sto_open_app(j->app);
+ if(j->s_pubdir) {
+ dk3sto_set_comp(j->s_pubdir, dkwt_ev_compare_string, 0);
+ j->i_pubdir = dk3sto_it_open(j->s_pubdir);
+ if(j->i_pubdir) {
+ dkwt_ev_run_with_storages(j);
+ } else {
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ }
+ } else {
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ }
+ } else {
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ }
+ } else {
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ }
+ } else {
+ j->exval = DKT_RESULT_ERR_OPTION;
+ }
+ } else {
+ j->exval = DKT_RESULT_ERR_OPTION;
+ }
+
+
+#line 1779 "dkwt-ev.ctr"
+}
+
+
+
+int
+dkwt_event(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl,
+ int evt
+)
+{
+ DKWT_EV_J j;
+ int back = DKT_RESULT_ERR_UNSPECIFIC;
+
+
+#line 1794 "dkwt-ev.ctr"
+ dkwt_ev_job_init(&j);
+ j.app = app; j.msg = msg; j.kwnl = kwnl; j.event = evt;
+ back = j.exval = DKT_RESULT_OK;
+ dkwt_ev_run(&j);
+ back = j.exval;
+ dkwt_ev_job_cleanup(&j);
+ switch(evt) {
+ case 0: case 1: case 2: case 3: {
+ /*
+ Always indicate success, otherwise Windows might shut down
+ or log the user off.
+ */
+ back = 0;
+ } break;
+ }
+
+
+#line 1810 "dkwt-ev.ctr"
+ return back;
+}
+
+
+
+int
+dkwt_event_keep(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl
+)
+{
+ int back = 1;
+ long result;
+ DWORD dw0;
+ HKEY hk;
+ DWORD dwDisp;
+ DWORD dwType;
+ DWORD dwValue;
+ DWORD dwSize;
+
+ dwDisp = 0L;
+ dw0 = 0L;
+
+ result = dkwt_tool_reg_create_key(
+ HKEY_LOCAL_MACHINE, kwnl[15], dw0,
+ (KEY_READ | KEY_SET_VALUE), &hk, &dwDisp
+ );
+ if(result == ERROR_SUCCESS) {
+ dw0 = 0L;
+ dwType = REG_DWORD;
+ dwValue = 1L;
+ dwSize = sizeof(DWORD);
+ result = dkwt_ev_reg_set_value(
+ hk, kwnl[16], dwType, &dwValue, dwSize
+ );
+ if(result == ERROR_SUCCESS) {
+ back = 0;
+ }
+ }
+ dk3sf_initialize_stdout();
+ if(back) {
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 77);
+ if (1 != dkwt_is_admin()) {
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 145);
+ }
+ } else {
+ dk3sf_fputs(msg[78], stdout);
+ }
+ dk3sf_fputc(dkT('\n'), stdout);
+ fflush(stdout);
+ return back;
+}
+
+
+
+int
+dkwt_event_unkeep(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl
+)
+{
+ (void)dkwt_ev_get_keep_value(app, msg, kwnl, 1);
+ return 0;
+}
+
diff --git a/support/dktools/dkwt-ev.ctr b/support/dktools/dkwt-ev.ctr
new file mode 100644
index 0000000000..efdcb5e666
--- /dev/null
+++ b/support/dktools/dkwt-ev.ctr
@@ -0,0 +1,1876 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk3all.h"
+#include "dkt.h"
+#include "dkwt.h"
+
+
+
+$!trace-include
+
+
+
+/** Job structure for dkwt boot/login/logout/shutdown.
+*/
+typedef struct {
+ dk3_app_t *app; /**< Application structure. */
+ dkChar const * const *msg; /**< Localized message texts. */
+ dkChar const * const *kwnl; /**< Keywords, not localized. */
+ dk3_option_set_t *opt; /**< Options set. */
+ dkChar const *userName; /**< User name. */
+ dkChar const *profBase; /**< Profile base directory. */
+ dkChar const *systemUser; /**< System user account. */
+ dkChar const *everyUser; /**< Everyone user account. */
+ dk3_sto_t *s_users; /**< Storage users. */
+ dk3_sto_it_t *i_users; /**< Iterator users. */
+ dk3_sto_t *s_pubdir; /**< Storage public directories. */
+ dk3_sto_it_t *i_pubdir; /**< Iterator public directories. */
+ dk3_sto_t *s_queues; /**< Remote queues to clean up. */
+ dk3_sto_it_t *i_queues; /**< Iterator for remote queues. */
+ int exval; /**< Exit status code. */
+ int event; /**< Event to process. */
+ int curSection; /**< Current configuration file sect. */
+ int useIcacls; /**< Flag: Use icalcs. */
+ int clrProfiles; /**< Flag: Clean profiles automatically. */
+ int testOnly; /**< Flag: Test only. */
+ int clp; /**< Flag: Clean up local print queues. */
+} DKWT_EV_J;
+
+
+/** Unknown section type.
+*/
+#define DKWT_EV_SECTION_UNKNOWN (-1)
+
+/** In the options section.
+*/
+#define DKWT_EV_SECTION_OPTIONS 0
+
+/** In the profiles section.
+*/
+#define DKWT_EV_SECTION_PROFILES 1
+
+/** In the public directories section.
+*/
+#define DKWT_EV_SECTION_PUBLIC 2
+
+
+
+/** Configuration file section names.
+*/
+static dkChar const * const dkwt_ev_section_names[] = {
+$!string-table macro=dkT
+# 0
+options
+# 1
+profiles
+# 2
+public
+$!end
+};
+
+
+
+/** Configuration file option names.
+*/
+static dkChar const * const dkwt_ev_option_names[] = {
+$!string-table macro=dkT
+# 0
+system-user
+# 1
+everyone-user
+# 2
+print-jobs
+$!end
+};
+
+
+
+/** Names of profiles to keep.
+*/
+static dkChar const * const dkwt_ev_profiles_to_keep[] = {
+$!text macro=dkT
+All Users
+Default User
+Public
+LocalService
+NetworkService
+Administrator
+$!end
+};
+
+
+
+/** Options.
+*/
+static dk3_option_t const dkwt_ev_options[] = {
+ { dkT('t'), dkT("test"), 0 }
+};
+
+/** Number of options in the dkwt_ev_options array.
+*/
+static size_t const dkwt_ev_szoptions =
+sizeof(dkwt_ev_options)/sizeof(dk3_option_t);
+
+
+
+/** Print queue name for local printers.
+*/
+static dkChar const dkwt_pq_name_local[] = { dkT("local") };
+
+
+/** Retrieve value of keep flag.
+ @param app Application structure.
+ @param msg Localized message texts.
+ @param kwnl Keywords, not localized.
+ @param reset Reset the flag.
+ @return Flag value (before reset).
+*/
+static
+int
+dkwt_ev_get_keep_value(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl,
+ int reset
+)
+{
+ long result;
+ DWORD dw0;
+ DWORD dwType;
+ DWORD dwValue;
+ DWORD dwSz;
+ int back = 0;
+ HKEY hk;
+ REGSAM regsam;
+
+ $? "+ dkwt_ev_get_keep_value"
+ dw0 = (DWORD)0;
+ dwType = REG_DWORD;
+ dwValue = 0;
+ dwSz = sizeof(DWORD);
+ regsam = KEY_QUERY_VALUE;
+ if(reset) {
+ regsam = (KEY_READ | KEY_WRITE);
+ }
+ result = dkwt_tool_reg_open_key(
+ HKEY_LOCAL_MACHINE, kwnl[15], KEY_QUERY_VALUE, &hk
+ );
+ if(result == ERROR_SUCCESS) {
+ result = dkwt_tool_reg_query_value(
+ hk, kwnl[16], &dwType, &dwValue, &dwSz
+ );
+ if(result == ERROR_SUCCESS) {
+ if(dwType == REG_DWORD) {
+ if(dwSz == sizeof(DWORD)) {
+ if(dwValue) {
+ back = 1;
+ }
+ }
+ }
+ }
+ if(reset) {
+ (void)dkwt_tool_reg_delete_value(hk, kwnl[16]);
+ }
+ RegCloseKey(hk);
+ }
+ $? "- dkwt_et_get_keep_value %d", back
+ return back;
+}
+
+
+
+/** Compare two strings.
+ @param l Left string.
+ @param r Right string.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+static
+int
+dkwt_ev_compare_string(void const *l, void const *r, int cr)
+{
+ dkChar const *pl;
+ dkChar const *pr;
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (dkChar const *)l; pr = (dkChar const *)r;
+ back = dk3str_casecmp(pl, pr);
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+ if(back > 1) back = 1;
+ if(back < -1) back = -1;
+ return back;
+}
+
+
+
+/** Initialize job structure.
+ @param j Structure to initialize.
+*/
+static
+void
+dkwt_ev_job_init(DKWT_EV_J *j)
+{
+#if (_MSC_VER < 1800) || DK4_WINDOWS_LEGACY
+ OSVERSIONINFO ovi;
+#endif
+
+ j->app = NULL; j->msg = NULL; j->kwnl = NULL;
+ j->profBase = NULL;
+ j->userName = NULL;
+ j->systemUser = NULL;
+ j->everyUser = NULL;
+ j->s_users = NULL; j->i_users = NULL;
+ j->s_pubdir = NULL; j->i_pubdir = NULL;
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ j->curSection = -1;
+ j->useIcacls = 0;
+ j->testOnly = 0;
+ j->clp = 0;
+ j->opt = NULL;
+ j->s_queues = NULL;
+ j->i_queues = NULL;
+ j->clrProfiles = 0;
+#if (_MSC_VER < 1800) || DK4_WINDOWS_LEGACY
+ ovi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ ovi.dwMajorVersion = 0L;
+ ovi.dwMinorVersion = 0L;
+ ovi.dwBuildNumber = 0L;
+ ovi.dwPlatformId = 0L;
+ if(GetVersionEx(&ovi)) {
+ if(ovi.dwMajorVersion > 5) {
+ j->useIcacls = 1; $? ". icacls"
+ } else {
+ if(ovi.dwMajorVersion == 5) {
+ if(ovi.dwMinorVersion > 1) {
+ j->useIcacls = 1; $? ". icacls"
+ }
+ }
+ }
+ if(ovi.dwMajorVersion < 6) {
+ j->clrProfiles = 1;
+ }
+ }
+#else
+ if (!IsWindowsVistaOrGreater()) {
+ j->clrProfiles = 1;
+ }
+ if (IsWindowsXPOrGreater()) {
+ j->useIcacls = 1;
+ }
+#endif
+}
+
+
+
+/** Clean up job structure, release memory.
+ @param j Job structure.
+*/
+static
+void
+dkwt_ev_job_cleanup(DKWT_EV_J *j)
+{
+ dkChar *un;
+ void *vp;
+ if(j) {
+ if(j->s_queues) {
+ if(j->i_queues) {
+ dk3sto_it_reset(j->i_queues);
+ while(NULL != (vp = dk3sto_it_next(j->i_queues))) {
+ dk3_delete(vp);
+ }
+ dk3sto_it_close(j->i_queues);
+ }
+ dk3sto_close(j->s_queues);
+ } j->s_queues = NULL; j->i_queues = NULL;
+ if(j->s_users) {
+ if(j->i_users) {
+ dk3sto_it_reset(j->i_users);
+ while((un = (dkChar *)dk3sto_it_next(j->i_users)) != NULL)
+ {
+ dk3_release(un);
+ }
+ dk3sto_it_close(j->i_users);
+ }
+ dk3sto_close(j->s_users);
+ } j->s_users = NULL; j->i_users = NULL;
+ if(j->s_pubdir) {
+ if(j->i_pubdir) {
+ dk3sto_it_reset(j->i_pubdir);
+ while((un = (dkChar *)dk3sto_it_next(j->i_pubdir)) != NULL)
+ {
+ dk3_release(un);
+ }
+ dk3sto_it_close(j->i_pubdir);
+ }
+ dk3sto_close(j->s_pubdir);
+ } j->s_pubdir = NULL; j->i_pubdir = NULL;
+ dk3_release(j->profBase);
+ dk3_release(j->userName);
+ dk3_release(j->systemUser);
+ dk3_release(j->everyUser);
+ if(j->opt) {
+ dk3opt_close(j->opt); j->opt = NULL;
+ }
+ }
+}
+
+
+
+/** Handler for one input line.
+ @param obj Job structure.
+ @param il Input line to process.
+ @return 1 on success, 0 on recoverable error, -1 to abort processing.
+*/
+static
+int
+dkwt_ev_line_handler(void *obj, dkChar *il)
+{
+ DKWT_EV_J *j;
+ dkChar *p1;
+ dkChar *p2;
+ dkChar *p3;
+ dkChar *nq;
+ int back = 1;
+ $? "+ dkwt_ev_line_handler \"%!ds\"", TR_STR(il)
+ j = (DKWT_EV_J *)obj;
+ p1 = dk3str_start(il, NULL);
+ if(p1) {
+ if(*p1 != dkT('#')) {
+ back = -1;
+ dk3str_delnl(p1);
+ if(*p1 == dkT('[')) { /* New section header. */
+ p1++;
+ p1 = dk3str_start(p1, NULL);
+ if(p1) {
+ j->curSection = DKWT_EV_SECTION_UNKNOWN;
+ p2 = dk3str_rchr(p1, dkT(']'));
+ if(p2) {
+ *p2 = dkT('\0');
+ p2 = dk3str_next(p1, NULL);
+ switch(dk3str_array_index(dkwt_ev_section_names, p1, 0)) {
+ case 0: {
+ j->curSection = DKWT_EV_SECTION_OPTIONS;
+ back = 1;
+ } break;
+ case 1: {
+ j->curSection = DKWT_EV_SECTION_PROFILES;
+ if(p2) {
+ if(!(j->profBase)) {
+ j->profBase = dk3str_dup_app(p2, j->app);
+ if(j->profBase) {
+ back = 1;
+ } else {
+ back = -1;
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ }
+ } else {
+ back = -1;
+ j->exval = DKT_RESULT_ERR_INPUT;
+ /* ERROR: Redefinition of profile base dir! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 66);
+ }
+ } else {
+ j->exval = DKT_RESULT_ERR_INPUT;
+ /* ERROR: No profile base dir specified! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 67);
+ }
+ } break;
+ case 2: {
+ j->curSection = DKWT_EV_SECTION_PUBLIC; back = 1;
+ } break;
+ default: {
+ back = -1;
+ j->exval = DKT_RESULT_ERR_INPUT;
+ /* ERROR: Unknown section type. */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 68);
+ } break;
+ }
+ } else {
+ back = -1;
+ /* ERROR: Incomplete section header. */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 69);
+ j->exval = DKT_RESULT_ERR_INPUT;
+ }
+ } else {
+ back = -1;
+ /* ERROR: No section header! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 70);
+ j->exval = DKT_RESULT_ERR_INPUT;
+ }
+ } else { /* Section contents line. */
+ switch(j->curSection) {
+ case DKWT_EV_SECTION_OPTIONS: {
+ p2 = dk3str_chr(p1, dkT('='));
+ if(p2) {
+ *(p2++) = dkT('\0');
+ p2 = dk3str_start(p2, NULL);
+ if(p2) {
+ /* dk3str_chomp(p1, NULL); */
+ dk3str_normalize(p1, NULL, dkT('-'));
+#if 0
+ dk3str_normalize(p2, NULL, dkT('-'));
+#endif
+ switch(dk3str_array_index(dkwt_ev_option_names, p1, 0)) {
+ case 0: {
+ if(!(j->systemUser)) {
+ j->systemUser = dk3str_dup_app(p2, j->app);
+ if(j->systemUser) {
+ back = 1;
+ } else {
+ back = -1;
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ }
+ } else {
+ /* ERROR: Redefinition of system user! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 71);
+ back = -1;
+ j->exval = DKT_RESULT_ERR_INPUT;
+ }
+ } break;
+ case 1: {
+ if(!(j->everyUser)) {
+ j->everyUser = dk3str_dup_app(p2, j->app);
+ if(j->everyUser) {
+ back = 1;
+ } else {
+ back = -1;
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ }
+ } else {
+ /* ERROR: Redefinition of everyone user! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 72);
+ back = -1;
+ j->exval = DKT_RESULT_ERR_INPUT;
+ }
+ } break;
+ case 2: {
+ back = 1;
+ while(p2) {
+ p3 = dk3str_next(p2, NULL);
+ if(0 == dk3str_cmp(dkwt_pq_name_local, p2)) {
+ j->clp = 1;
+ } else {
+ if(!(j->s_queues)) {
+ j->s_queues = dk3sto_open_app(j->app);
+ }
+ if(!(j->i_queues)) {
+ if(j->s_queues) {
+ j->i_queues = dk3sto_it_open(j->s_queues);
+ }
+ }
+ if((j->s_queues) && (j->i_queues)) {
+ nq = dk3str_dup_app(p2, j->app);
+ if(nq) {
+ if(!dk3sto_add(j->s_queues, (void *)nq)) {
+ dk3_delete(nq);
+ back = 0;
+ }
+ } else {
+ back = 0;
+ }
+ } else {
+ back = 0;
+ }
+ }
+ p2 = p3;
+ }
+ } break;
+ default: {
+ /* ERROR: Unknown option! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 73);
+ back = -1;
+ j->exval = DKT_RESULT_ERR_INPUT;
+ } break;
+ }
+ } else {
+ /* ERROR: Not a key/value pair */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 74);
+ back = -1;
+ j->exval = DKT_RESULT_ERR_INPUT;
+ }
+ } else {
+ /* ERROR: Not a key/value pair */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 74);
+ back = -1;
+ j->exval = DKT_RESULT_ERR_INPUT;
+ }
+ } break;
+ case DKWT_EV_SECTION_PROFILES: { $? ". add user name to list"
+ dk3str_normalize(p1, NULL, dkT(' '));
+ p2 = dk3str_dup_app(p1, j->app);
+ if(p2) {
+ if(dk3sto_add(j->s_users, (void *)p2)) {
+ back = 1; $? ". added user name \"%!ds\"", TR_STR(p2)
+ } else { $? "! failed to add"
+ dk3_release(p2);
+ back = -1;
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ }
+ } else { $? "! empty user name"
+ back = -1;
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ }
+ } break;
+ case DKWT_EV_SECTION_PUBLIC: { $? ". add public dir to list"
+ dk3str_normalize(p1, NULL, dkT(' '));
+ p2 = dk3str_dup_app(p1, j->app);
+ if(p2) { $? ". p2"
+ if(dk3sto_add(j->s_pubdir, (void *)p2)) {
+ back = 1; $? ". added"
+ } else { $? "! failed to add"
+ dk3_release(p2);
+ back = -1;
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ }
+ } else { $? "! p2"
+ back = -1;
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ }
+ } break;
+ default: {
+ back = -1;
+ j->exval = DKT_RESULT_ERR_INPUT;
+ } break;
+ }
+ }
+ } else {
+ /* Comment line ok. */
+ }
+ } else {
+ /* Empty line ok. */
+ } $? "- dkwt_ev_line_handler %d", back
+ return back;
+}
+
+
+
+/** Run a command.
+ @param j Job structure.
+ @param cmd Command to run.
+*/
+static
+void
+dkwt_ev_execute_command(DKWT_EV_J *j, dkChar const *cmd)
+{
+ int value = 0;
+ /* PROGRESS: Execute command ... */
+ dk3app_log_3(j->app, DK3_LL_PROGRESS, j->msg, 118, 119, cmd);
+ dk3sf_initialize_stdout();
+ dk3sf_fputs(cmd, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ if(!(j->testOnly)) {
+#if DK3_CHAR_SIZE > 1
+ value = _wsystem(cmd);
+#else
+ value = system(cmd);
+#endif
+ if(value != 0) {
+ /* ERROR: Command execution failed! */
+ dk3app_log_3(j->app, DK3_LL_ERROR, j->msg, 79, 80, cmd);
+ j->exval = DKT_RESULT_ERR_SYSEXEC;
+ }
+ }
+}
+
+
+
+/** Remove a directory.
+ First attempt to use the RD command, next use own routines.
+ @param j Job structure.
+ @param dn Directory name.
+ @param dolog Flag: Do logging in dk3dir_remove_app().
+*/
+static
+void
+dkwt_ev_remove_directory(DKWT_EV_J *j, dkChar const *dn, int dolog)
+{
+ dkChar bu[2 * DK3_MAX_PATH];
+ dk3_stat_t stb;
+ size_t sz;
+ $? "+ dkwt_ev_remove_directory \"%ls\"", dn
+ /* PROGRESS: Remove directory ... */
+ dk3app_log_3(j->app, DK3_LL_PROGRESS, j->msg, 120, 121, dn);
+ if(!(j->testOnly)) {
+#if 0
+ dk3sf_remove_dir(dn);
+#endif
+ dk3dir_remove_app(dn, ((dolog) ? j->app : NULL));
+ if(dk3sf_stat_app(&stb, dn, NULL)) {
+ sz = dk3str_len(dn);
+ sz += dk3str_len((j->kwnl)[4]);
+ sz += dk3str_len((j->kwnl)[5]);
+ if(sz < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy_not_overlapped(bu, (j->kwnl)[4]);
+ dk3str_cat(bu, dn);
+ dk3str_cat(bu, (j->kwnl)[5]);
+ dkwt_ev_execute_command(j, bu);
+ } else { $? "! name too long"
+ /* ERROR: File name too long! */
+ dk3app_log_i3(j->app, DK3_LL_ERROR, 59, 60, dn);
+ j->exval = DKT_RESULT_ERR_FILENAME;
+ }
+ }
+ }
+ $? "- dkwt_ev_remove_directory"
+}
+
+
+
+/** Remove a file.
+ First attempt to use the DEL command, next use own routines.
+ @param j Job structure.
+ @param fn File name.
+*/
+static
+void
+dkwt_ev_remove_file(DKWT_EV_J *j, dkChar const *fn)
+{
+ dkChar bu[2 * DK3_MAX_PATH];
+ dk3_stat_t stb;
+ size_t sz;
+
+ /* PROGRESS: Remove file ... */
+ dk3app_log_3(j->app, DK3_LL_PROGRESS, j->msg, 122, 123, fn);
+ if(!(j->testOnly)) {
+ dk3sf_remove_file_app(fn, NULL);
+ if(dk3sf_stat_app(&stb, fn, NULL)) {
+ sz = dk3str_len(fn);
+ sz += dk3str_len((j->kwnl)[6]);
+ sz += dk3str_len((j->kwnl)[5]);
+ if(sz < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy_not_overlapped(bu, (j->kwnl)[6]);
+ dk3str_cat(bu, fn);
+ dk3str_cat(bu, (j->kwnl)[5]);
+ dkwt_ev_execute_command(j, bu);
+ } else {
+ /* ERROR: File name too long! */
+ dk3app_log_i3(j->app, DK3_LL_ERROR, 65, 66, fn);
+ j->exval = DKT_RESULT_ERR_FILENAME;
+ }
+ }
+ }
+}
+
+
+
+/** Check whether or not to keep a profile subdirectory.
+ @param j Job structure.
+ @param un User name (short directory name).
+ @return 1 to keep the directory, 0 to delete it.
+*/
+static
+int
+dkwt_ev_must_keep(DKWT_EV_J *j, dkChar const *un)
+{
+ int back = 0;
+ $? "+ dkwt_ev_must_keep"
+ if(j->userName) {
+ if(dk3str_casecmp(j->userName, un) == 0) {
+ back = 1;
+ }
+ }
+ if(!(back)) {
+ if(dk3sto_it_find_like(j->i_users, (void *)un, 0)) {
+ back = 1;
+ }
+ }
+ if(!(back)) {
+ if(dk3str_array_index(dkwt_ev_profiles_to_keep, un, 0) >= 0) {
+ back = 1;
+ }
+ } $? "- dkwt_ev_must_keep %d", back
+ return back;
+}
+
+
+
+#ifdef VERSION_BEFORE_20120320
+/** Clean up the profile directory.
+ @param j Job structure.
+*/
+static
+void
+dkwt_ev_cleanup_profiles(DKWT_EV_J *j)
+{
+ dkChar bu1[DK3_MAX_PATH];
+ dk3_dir_t *dir;
+ dkChar const *en;
+ dkChar const *es;
+ dkChar *ptr;
+ int must_delete = 1;
+ $? "+ dkwt_ev_cleanup_profiles %d", must_delete
+ if(j->profBase) {
+ if(j->clrProfiles != 0) {
+ dir = dk3dir_open_app(j->profBase, j->app);
+ if(dir) { $? ". directory opened"
+ while(dk3dir_get_next_directory(dir)) {
+ en = dk3dir_get_fullname(dir);
+ es = dk3dir_get_shortname(dir);
+ if((en) && (es)) { $? ". entry \"%ls\"", es
+ must_delete = 1;
+ if(dkwt_ev_must_keep(j, es)) {
+ must_delete = 0; $? ". must keep"
+ } else { $? ". can delete"
+ if(dk3str_len(es) < DK3_SIZEOF(bu1,dkChar)) {
+ dk3str_cpy_not_overlapped(bu1, es);
+ ptr = dk3str_chr(bu1, dkT('.'));
+ if(ptr) {
+ *ptr = dkT('\0');
+ if(dkwt_ev_must_keep(j, bu1)) {
+ must_delete = 0; $? ". must keep"
+ } else { $? ". can delete"
+ }
+ } else { $? ". no need to test again"
+ }
+ } else { $? "! name too long for test"
+ must_delete = 0;
+ }
+ } $? ". must_delete=%d", must_delete
+ if(must_delete) { $? ". must delete \"%ls\"", en
+ dkwt_ev_remove_directory(j, en, 0);
+ }
+ }
+ }
+ dk3dir_close(dir);
+ }
+ } else {
+ }
+ }
+ $? "- dkwt_ev_cleanup_profiles"
+}
+#else
+
+
+
+/** Directory entry for deletion.
+*/
+typedef struct {
+ dkChar const *n; /**< Directory name. */
+ char f; /**< Flag: Can delete. */
+} DKWT_EV_DIR;
+
+
+
+/** Release directory name.
+ @param d Directory name entry to delete.
+*/
+static
+void
+dkwt_ev_ddel_del(DKWT_EV_DIR *d)
+{
+ if(d) {
+ dk3_release(d->n);
+ d->f = 0x00;
+ dk3_delete(d);
+ }
+}
+
+
+
+/** Create directory name entry.
+ @param j Job structure.
+ @param fn File name of directory.
+ @return New entry on success, NULL on error.
+*/
+static
+DKWT_EV_DIR *
+dkwt_ev_ddel_new(DKWT_EV_J *j, dkChar const *fn)
+{
+ DKWT_EV_DIR *back = NULL;
+ if(fn) {
+ back = dk3_new_app(DKWT_EV_DIR,1,j->app);
+ if(back) {
+ back->f = 0x01;
+ back->n = dk3str_dup_app(fn, j->app);
+ if(!(back->n)) {
+ dkwt_ev_ddel_del(back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Compare two entries for directories.
+ @param l Left directory object.
+ @param r Right directory object.
+ @param cr Comparison criteria (0=dir/dir, 1=dir/name).
+ @return Comparison result.
+*/
+static
+int
+dkwt_ev_ddel_comp(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ DKWT_EV_DIR const *pl;
+ DKWT_EV_DIR const *pr;
+ if(l) {
+ if(r) {
+ pl = (DKWT_EV_DIR const *)l;
+ switch(cr) {
+ case 1: {
+ if(pl->n) {
+ back = dk3str_casecmp(pl->n, (dkChar const *)r);
+ if(back < -1) back = -1;
+ if(back > 1) back = 1;
+ } else back = -1;
+ } break;
+ default: {
+ pr = (DKWT_EV_DIR const *)r;
+ if(pl->n) {
+ if(pr->n) {
+ back = dk3str_casecmp(pl->n, pr->n);
+ if(back < -1) back = -1;
+ if(back > 1) back = 1;
+ } else back = 1;
+ } else {
+ if(pr->n) back = -1;
+ }
+ } break;
+ }
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ }
+ return back;
+}
+
+
+
+/** Delete a registry key structure for a user profile.
+ @param j Job structure.
+ @param kn Key name (short name).
+*/
+static
+void
+dkwt_ev_del_rk_profile(DKWT_EV_J *j, dkChar const *kn)
+{
+ HKEY hk;
+ long res;
+ $? "+ dkwt_ev_del_rk_profile \"%!ds\"", kn
+ /*
+ Log message
+ */
+ /* PROGRESS: Deleting registry key ... */
+ dk3app_log_5(
+ j->app, DK3_LL_PROGRESS,
+ j->msg, 124, 125, 126, (j->kwnl)[19], kn
+ );
+ /*
+ Delete the key.
+ */
+ if(!(j->testOnly)) {
+ res = dkwt_tool_reg_open_key(
+ HKEY_LOCAL_MACHINE, (j->kwnl)[19], KEY_ALL_ACCESS, &hk
+ );
+ if(ERROR_SUCCESS == res) { $? ". parent key opened"
+ res = dkwt_tool_reg_delete_tree(hk, kn);
+ if(ERROR_SUCCESS == res) { $? ". deleted successfully"
+ /* DEBUG: Registry key ... deleted. */
+ dk3app_log_3(j->app, DK3_LL_DEBUG, j->msg, 127, 128, kn);
+ } else { $? "! failed to delete"
+ /* ERROR: Failed to remove registry hierarchy ... */
+ dk3app_log_5(
+ j->app, DK3_LL_ERROR, j->msg,
+ 129, 130, 131, (j->kwnl)[19], kn
+ );
+ }
+ RegCloseKey(hk);
+ } else { $? "! failed to open parent"
+ /* ERROR: Failed to open registry key ... */
+ dk3app_log_3(j->app, DK3_LL_ERROR, j->msg, 132, 133, (j->kwnl)[19]);
+ }
+ }
+ $? "- dkwt_ev_del_rk_profile"
+}
+
+
+
+/** Clean up the profile directory.
+ @param j Job structure.
+*/
+static
+void
+dkwt_ev_cleanup_profiles(DKWT_EV_J *j)
+{
+ dkChar knb[DK3_MAX_PATH]; /* Buffer for key name. */
+ dkChar ppb[DK3_MAX_PATH]; /* Profile path buffer. */
+ dkChar esb[DK3_MAX_PATH]; /* Expanded string buffer. */
+ dkChar bu1[DK3_MAX_PATH]; /* Buffer for full file name. */
+ void *vp; /* void pointer for cleanup. */
+ dk3_sto_t *s_fn; /* Storage of directories to delete. */
+ dk3_sto_it_t *i_fn; /* Iterator for directory storage. */
+ dk3_sto_t *s_rk; /* Storage for registry keys. */
+ dk3_sto_it_t *i_rk; /* Iterator for registry keys storage. */
+ dk3_sto_t *s_rd; /* Storage for registry keys to delete. */
+ dk3_sto_it_t *i_rd; /* Iterator for keys to delete. `*/
+ dk3_dir_t *dir; /* Directory. */
+ dkChar const *en; /* Entry name. */
+ dkChar const *es; /* Short entry name. */
+ dkChar const *kn; /* Current key name, copy. */
+ dkChar *ptr; /* Pointer to dot in file name. */
+ DKWT_EV_DIR *ddel; /* Directory to delete. */
+ HKEY hk; /* Handle for registry key. */
+ REGSAM regs; /* Access type to registry key. */
+ long res; /* Result from operation. */
+ size_t stlgt; /* String length. */
+ DWORD dw0; /* Used to open registry keys. */
+ DWORD dwInd; /* INdex of current key. */
+ DWORD dwSz; /* Size of knb buffer. */
+ DWORD dwEx; /* Result from string expansion. */
+ DWORD dwTp; /* Result type. */
+ int md; /* Flag: Must delete this entry. */
+ int ec; /* Error code. */
+ $? "+ dkwt_ev_cleanup_profiles"
+ ec = 0;
+ if(j->profBase) {
+ /* PROGRESS: Cleanin up profiles (start) */
+ dk3app_log_1(j->app, DK3_LL_PROGRESS, j->msg, 134);
+ s_fn = dk3sto_open_app(j->app);
+ if(s_fn) {
+ dk3sto_set_comp(s_fn, dkwt_ev_ddel_comp, 0);
+ i_fn = dk3sto_it_open(s_fn);
+ if(i_fn) {
+ s_rk = dk3sto_open_app(j->app);
+ if(s_rk) {
+ dk3sto_set_comp(s_rk, dkwt_ev_compare_string, 0);
+ i_rk = dk3sto_it_open(s_rk);
+ if(i_rk) {
+ s_rd = dk3sto_open_app(j->app);
+ if(s_rd) {
+ i_rd = dk3sto_it_open(s_rd);
+ if(i_rd) {
+ /* DEBUG: Storages ok. */
+ dir = dk3dir_open_app(j->profBase, j->app);
+ if(dir) {
+ /* DEBUG: Directory opened successfully. */
+ while(dk3dir_get_next_directory(dir)) {
+ en = dk3dir_get_fullname(dir);
+ es = dk3dir_get_shortname(dir);
+ if((en) && (es)) { $? ". entry \"%!ds\"", es
+ md = 1;
+ if(dkwt_ev_must_keep(j, es)) {
+ md = 0;
+ } else {
+ if(dk3str_len(es) < DK3_SIZEOF(bu1,dkChar)) {
+ dk3str_cpy_not_overlapped(bu1, es);
+ ptr = dk3str_chr(bu1, dkT('.'));
+ if(ptr) {
+ *ptr = dkT('\0');
+ if(dkwt_ev_must_keep(j, bu1)) {
+ md = 0;
+ }
+ }
+ } else { $? "! name too long"
+ /* ERROR: Name too long! */
+ dk3app_log_i3(j->app, DK3_LL_ERROR, 59, 60, es);
+ if(!(ec)) { ec = DK3_ERROR_TOO_LARGE; }
+ md = 0;
+ }
+ } $? ". md = %d", md
+ if(md) {
+ ddel = dkwt_ev_ddel_new(j, en);
+ if(ddel) {
+ if(!dk3sto_add(s_fn, (void *)ddel)) { $? "! add"
+ dkwt_ev_ddel_del(ddel);
+ if(!(ec)) { ec = DK3_ERROR_MEMORY; }
+ }
+ } else { $? "! ddel_new"
+ if(!(ec)) { ec = DK3_ERROR_MEMORY; }
+ }
+ }
+ } else { $? "! bug"
+ /* ERROR: Failed to obtain name for directory entry! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 135);
+ if(!(ec)) { ec = DK3_ERROR_SYSTEM; }
+ }
+ }
+ dk3dir_close(dir);
+ /*
+ Now search the registry keys
+ */
+ dw0 = (DWORD)0;
+ regs = KEY_READ;
+ res = dkwt_tool_reg_open_key(
+ HKEY_LOCAL_MACHINE, (j->kwnl)[19], KEY_READ, &hk
+ );
+ if(ERROR_SUCCESS == res) {
+ dwInd = 0;
+ do {
+ dwSz = DK3_SIZEOF(knb,dkChar);
+ res = dkwt_tool_reg_enum_key(
+ hk, dwInd, knb, &dwSz, NULL, NULL, NULL
+ );
+ if(ERROR_SUCCESS == res) {
+ if(dwSz > 0) {
+ kn = dk3str_dup_app(knb, j->app);
+ if(kn) {
+ if(!dk3sto_add(s_rk, (void *)kn)) { $? "! add"
+ dk3_delete(kn);
+ if(!(ec)) { ec = DK3_ERROR_MEMORY; }
+ }
+ } else { $? "! strdup"
+ if(!(ec)) { ec = DK3_ERROR_MEMORY; }
+ }
+ }
+ } else { $? "! reg_enum_key"
+ if(res != ERROR_NO_MORE_ITEMS) {
+ if(!(ec)) { ec = DK3_ERROR_DURING_READ; }
+ }
+ }
+ dwInd++;
+ } while(res != ERROR_NO_MORE_ITEMS);
+ RegCloseKey(hk);
+ /*
+ For each key found check whether ProfileImagePath is in s_fn.
+ */
+ dk3sto_it_reset(i_rk);
+ while(NULL != (kn = (dkChar const *)dk3sto_it_next(i_rk))) {
+ stlgt = dk3str_len((j->kwnl)[19]);
+ stlgt++;
+ stlgt += dk3str_len(kn);
+ if(stlgt < DK3_SIZEOF(knb,dkChar)) {
+ dk3str_cpy_not_overlapped(knb, (j->kwnl)[19]);
+ dk3str_cat(knb, (j->kwnl)[20]);
+ dk3str_cat(knb, kn);
+ dw0 = 0;
+ regs = KEY_QUERY_VALUE;
+ res = dkwt_tool_reg_open_key(
+ HKEY_LOCAL_MACHINE, knb, KEY_QUERY_VALUE, &hk
+ );
+ if(ERROR_SUCCESS == res) {
+ dwTp = REG_EXPAND_SZ;
+ dwSz = sizeof(ppb);
+ res = dkwt_tool_reg_query_value(
+ hk, (j->kwnl)[21], &dwTp, ppb, &dwSz
+ );
+ if(ERROR_SUCCESS == res) {
+#if DK3_CHAR_SIZE > 1
+ if(dwSz < (sizeof(ppb) - 1)) {
+ ppb[dwSz] = '\0';
+ ppb[dwSz+1] = '\0';
+ } else {
+ ppb[sizeof(ppb)-2] = '\0';
+ ppb[sizeof(ppb)-1] = '\0';
+ }
+#else
+ if(dwSz < sizeof(ppb)) {
+ ppb[dwSz] = '\0';
+ } else {
+ ppb[sizeof(ppb)-1] = '\0';
+ }
+#endif
+ switch(dwTp) {
+ case REG_SZ: {
+ ddel = (DKWT_EV_DIR *)dk3sto_it_find_like(
+ i_fn, (void *)ppb, 1
+ );
+ if(ddel) {
+ /* Save kn as registry key to delete */
+ if(!dk3sto_add(s_rd, (void *)kn)) { $? "! add"
+ ddel->f = 0x00;
+ if(!(ec)) { ec = DK3_ERROR_MEMORY; }
+ }
+ }
+ } break;
+ case REG_EXPAND_SZ: {
+ dwEx = ExpandEnvironmentStrings(
+ ppb,
+ esb,
+ DK3_SIZEOF(esb,dkChar)
+ );
+ if(dwEx > 0) {
+ if(dwEx < DK3_SIZEOF(esb,dkChar)) {
+ ddel = (DKWT_EV_DIR *)dk3sto_it_find_like(
+ i_fn, (void *)esb, 1
+ );
+ if(ddel) {
+ /* Save kn as registry key to delete */
+ if(!dk3sto_add(s_rd,(void *)kn)) { $? "! add"
+ ddel->f = 0x00;
+ if(!(ec)) { ec = DK3_ERROR_MEMORY; }
+ }
+ }
+ } else { $? "! ExpandEnvironmentStrings"
+ /* ERROR: String too long! */
+ dk3app_log_3(
+ j->app, DK3_LL_ERROR, j->msg,
+ 136, 137, ppb
+ );
+ if(!(ec)) { ec = DK3_ERROR_TOO_LARGE; }
+ }
+ } else {
+ ddel = (DKWT_EV_DIR *)dk3sto_it_find_like(
+ i_fn, (void *)ppb, 1
+ );
+ if(ddel) {
+ /* Save kn as registry key to delete */
+ if(!dk3sto_add(s_rd, (void *)kn)) { $? "! add"
+ ddel->f = 0x00;
+ if(!(ec)) { ec = DK3_ERROR_MEMORY; }
+ }
+ }
+ }
+ } break;
+ }
+ }
+ RegCloseKey(hk);
+ } else { $? "! registry open key"
+ /* ERROR: Failed to open registry key ... */
+ dk3app_log_3(
+ j->app, DK3_LL_ERROR, j->msg, 132, 133, knb
+ );
+ if(!(ec)) { ec = DK3_ERROR_NOT_OPENED_FOR_READING; }
+ }
+ } else { $? "! key name too long \"%!ds\"", kn
+ /* ERROR: Key name too long! */
+ dk3app_log_3(j->app, DK3_LL_ERROR, j->msg, 138, 139, kn);
+ if(!(ec)) { ec = DK3_ERROR_TOO_LARGE; }
+ }
+ }
+ } else { $? "! failed to open registry key"
+ /* ERROR: Failed to open registry key! */
+ dk3app_log_3(
+ j->app, DK3_LL_ERROR, j->msg, 132, 133, (j->kwnl)[19]
+ );
+ if(!(ec)) { ec = DK3_ERROR_NOT_OPENED_FOR_READING; }
+ }
+ } else { $? "! dir"
+ }
+ if(!(ec)) { $? ". no error, delete registry keys"
+ dk3sto_it_reset(i_rd);
+ while(NULL != (kn = (dkChar const *)dk3sto_it_next(i_rd))) {
+ /*
+ */
+ dkwt_ev_del_rk_profile(j, kn);
+ }
+ } else {
+ /* ERROR: Skipping profile cleanup due to previous errors! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 140);
+ }
+ /*
+ In s_rd and i_rd we have copies of strings from s_rk and i_rk.
+ No deletion necessary.
+ */
+ dk3sto_it_close(i_rd);
+ } else { $? "! i_rd"
+ }
+ dk3sto_close(s_rd);
+ } else { $? "! s_rd"
+ }
+ dk3sto_it_reset(i_rk);
+ while(NULL != (vp = dk3sto_it_next(i_rk))) {
+ dk3_delete(vp);
+ }
+ dk3sto_it_close(i_rk);
+ } else { $? "! i_rk"
+ }
+ dk3sto_close(s_rk);
+ } else { $? "! s_rk"
+ }
+ dk3sto_it_reset(i_fn);
+ while(NULL != (ddel = (DKWT_EV_DIR *)dk3sto_it_next(i_fn))) {
+ /*
+ Remove the directory.
+ */
+ if(!(ec)) {
+ if(ddel->f) {
+ dkwt_ev_remove_directory(j, ddel->n, 0);
+ }
+ }
+ /*
+ Free list entry.
+ */
+ dkwt_ev_ddel_del(ddel);
+ }
+ dk3sto_it_close(i_fn); i_fn = NULL;
+ } else { $? "! i_fn"
+ }
+ dk3sto_close(s_fn); s_fn = NULL;
+ } else { $? "! s_fn"
+ }
+ /* PROGRESS: Cleaning up profiles (finished). */
+ dk3app_log_1(j->app, DK3_LL_PROGRESS, j->msg, 141);
+ } else { $? ". no profile base configured"
+ }
+ $? "- dkwt_ev_cleanup_profiles"
+}
+
+
+#endif
+
+
+
+/** Clean up public directories.
+ @param j Job structure.
+*/
+static
+void
+dkwt_ev_cleanup_public(DKWT_EV_J *j)
+{
+ dkChar const *fn;
+ dkChar const *en;
+ dk3_dir_t *dir;
+ $? "+ dkwt_ev_cleanup_public"
+ dk3sto_it_reset(j->i_pubdir);
+ while((fn = (dkChar const *)dk3sto_it_next(j->i_pubdir)) != NULL) {
+ dir = dk3dir_open_app(fn, j->app);
+ if(dir) {
+ while(dk3dir_get_next_directory(dir)) {
+ en = dk3dir_get_fullname(dir);
+ if(en) {
+ dkwt_ev_remove_directory(j, en, 1);
+ }
+ }
+ while(dk3dir_get_next_file(dir)) {
+ en = dk3dir_get_fullname(dir);
+ if(en) {
+ dkwt_ev_remove_file(j, en);
+ }
+ }
+ dk3dir_close(dir);
+ }
+ }
+ $? "- dkwt_ev_cleanup_public"
+}
+
+
+
+/** Change permissions for one path.
+ @param j Job structure.
+ @param fn File name.
+ @param un User name.
+ @param isdir Flag: Is directory.
+*/
+static
+void
+dkwt_ev_user_permissions(
+ DKWT_EV_J *j, dkChar const *fn, dkChar const *un, int isdir
+)
+{
+ dkChar bu[2 * DK3_MAX_PATH];
+ size_t sz = 0;
+ $? "+ dkwt_ev_user_permissions"
+ if(j->useIcacls) {
+ if(isdir) {
+ sz = dk3str_len((j->kwnl)[10]);
+ sz += dk3str_len(fn);
+ sz += dk3str_len((j->kwnl)[11]);
+ sz += dk3str_len(un);
+ sz += dk3str_len((j->kwnl)[12]);
+ if(sz < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy_not_overlapped(bu, (j->kwnl)[10]);
+ dk3str_cat(bu, fn);
+ dk3str_cat(bu, (j->kwnl)[11]);
+ dk3str_cat(bu, un);
+ dk3str_cat(bu, (j->kwnl)[12]);
+ dkwt_ev_execute_command(j, bu);
+ } else {
+ /* ERROR: Line too long! */
+ dk3app_log_i3(j->app, DK3_LL_ERROR, 65, 66, fn);
+ j->exval = DKT_RESULT_ERR_FILENAME;
+ }
+ } else {
+ sz = dk3str_len((j->kwnl)[10]);
+ sz += dk3str_len(fn);
+ sz += dk3str_len((j->kwnl)[11]);
+ sz += dk3str_len(un);
+ sz += dk3str_len((j->kwnl)[13]);
+ if(sz < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy_not_overlapped(bu, (j->kwnl)[10]);
+ dk3str_cat(bu, fn);
+ dk3str_cat(bu, (j->kwnl)[11]);
+ dk3str_cat(bu, un);
+ dk3str_cat(bu, (j->kwnl)[13]);
+ dkwt_ev_execute_command(j, bu);
+ } else {
+ /* ERROR: Line too long! */
+ dk3app_log_i3(j->app, DK3_LL_ERROR, 65, 66, fn);
+ j->exval = DKT_RESULT_ERR_FILENAME;
+ }
+ }
+ } else {
+ if(isdir) {
+ sz = dk3str_len((j->kwnl)[7]);
+ sz += dk3str_len(fn);
+ sz += dk3str_len((j->kwnl)[8]);
+ sz += dk3str_len(un);
+ sz += dk3str_len((j->kwnl)[9]);
+ if(sz < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy_not_overlapped(bu, (j->kwnl)[7]);
+ dk3str_cat(bu, fn);
+ dk3str_cat(bu, (j->kwnl)[8]);
+ dk3str_cat(bu, un);
+ dk3str_cat(bu, (j->kwnl)[9]);
+ dkwt_ev_execute_command(j, bu);
+ } else {
+ /* ERROR: Line too long! */
+ dk3app_log_i3(j->app, DK3_LL_ERROR, 65, 66, fn);
+ j->exval = DKT_RESULT_ERR_FILENAME;
+ }
+ } else {
+ sz = dk3str_len((j->kwnl)[7]);
+ sz += dk3str_len(fn);
+ sz += dk3str_len((j->kwnl)[14]);
+ sz += dk3str_len(un);
+ sz += dk3str_len((j->kwnl)[9]);
+ if(sz < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy_not_overlapped(bu, (j->kwnl)[7]);
+ dk3str_cat(bu, fn);
+ dk3str_cat(bu, (j->kwnl)[14]);
+ dk3str_cat(bu, un);
+ dk3str_cat(bu, (j->kwnl)[9]);
+ dkwt_ev_execute_command(j, bu);
+ } else {
+ /* ERROR: Line too long! */
+ dk3app_log_i3(j->app, DK3_LL_ERROR, 65, 66, fn);
+ j->exval = DKT_RESULT_ERR_FILENAME;
+ }
+ }
+ }
+ $? "- dkwt_ev_user_permissions"
+}
+
+
+
+/** Change permissions for one path.
+ @param j Job structure.
+ @param fn File name.
+ @param isdir Flag: Is directory.
+*/
+static
+void
+dkwt_ev_permissions(DKWT_EV_J *j, dkChar const *fn, int isdir)
+{
+ $? "+ dkwt_ev_permissions"
+ if(j->systemUser) {
+ dkwt_ev_user_permissions(j, fn, j->systemUser, isdir);
+ } else {
+ dkwt_ev_user_permissions(j, fn, (j->kwnl)[2], isdir);
+ }
+ if(j->everyUser) {
+ dkwt_ev_user_permissions(j, fn, j->everyUser, isdir);
+ } else {
+ dkwt_ev_user_permissions(j, fn, (j->kwnl)[3], isdir);
+ }
+ $? "- dkwt_ev_permissions"
+}
+
+
+
+/** Change permissions to own profile, grant full access
+ to system and everyone.
+ @param j Job structure.
+*/
+static
+void
+dkwt_ev_permissions_profile(DKWT_EV_J *j)
+{
+ dkChar bu[DK3_MAX_PATH];
+ size_t sz;
+ $? "+ dkwt_ev_permissions_profile"
+ if((j->profBase) && (j->userName)) {
+ sz = dk3str_len(j->profBase);
+ sz += dk3str_len(j->userName);
+ sz += 1;
+ if(sz < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy_not_overlapped(bu, j->profBase);
+ dk3str_cat(bu, dk3app_not_localized(20));
+ dk3str_cat(bu, j->userName);
+ dkwt_ev_permissions(j, bu, 1);
+ }
+ }
+ $? "- dkwt_ev_permissions_profile"
+}
+
+
+
+/** Change permissions to public directory contents, grant full
+ access to system and everyone.
+ @param j Job structure.
+*/
+static
+void
+dkwt_ev_permissions_public(DKWT_EV_J *j)
+{
+ dkChar const *fn;
+ dkChar const *en;
+ dk3_dir_t *dir;
+ $? "+ dkwt_ev_permissions_public"
+ dk3sto_it_reset(j->i_pubdir);
+ while((fn = (dkChar const *)dk3sto_it_next(j->i_pubdir)) != NULL) {
+ dir = dk3dir_open_app(fn, j->app);
+ if(dir) {
+ while(dk3dir_get_next_directory(dir)) {
+ en = dk3dir_get_fullname(dir);
+ if(en) {
+ dkwt_ev_permissions(j, en, 1);
+ }
+ }
+ while(dk3dir_get_next_file(dir)) {
+ en = dk3dir_get_fullname(dir);
+ if(en) {
+ dkwt_ev_permissions(j, en, 0);
+ }
+ }
+ dk3dir_close(dir);
+ }
+ }
+ $? "- dkwt_ev_permissions_public"
+}
+
+
+
+/** Do processing.
+ @param j Job structure.
+*/
+static
+void
+dkwt_ev_do_processing(DKWT_EV_J *j)
+{
+ $? "+ dkwt_ev_do_processing"
+ switch(j->event) {
+ case 0: { $? ". boot"
+ if(!dkwt_ev_get_keep_value(j->app, j->msg, j->kwnl, 0)) {
+ if(j->clrProfiles != 0) {
+ dkwt_ev_cleanup_profiles(j);
+ }
+ dkwt_ev_cleanup_public(j);
+ }
+ } break;
+ case 1: { $? ". shutdown"
+ if(!dkwt_ev_get_keep_value(j->app, j->msg, j->kwnl, 0)) {
+ if(j->clrProfiles != 0) {
+ dkwt_ev_cleanup_profiles(j);
+ }
+ dkwt_ev_cleanup_public(j);
+ }
+ } break;
+ case 2: { $? ". login"
+ if(!dkwt_ev_get_keep_value(j->app, j->msg, j->kwnl, 1)) {
+ if(j->clrProfiles != 0) {
+ dkwt_ev_cleanup_profiles(j);
+ }
+ dkwt_ev_cleanup_public(j);
+ }
+ } break;
+ case 3: { $? ". logout"
+ if(j->clrProfiles != 0) {
+ dkwt_ev_permissions_profile(j);
+ }
+ dkwt_ev_permissions_public(j);
+ if(!dkwt_ev_get_keep_value(j->app, j->msg, j->kwnl, 0)) {
+ if(j->clrProfiles != 0) {
+ dkwt_ev_cleanup_profiles(j);
+ }
+ dkwt_ev_cleanup_public(j);
+ }
+ if(j->clp) {
+ dkwt_clear_printers_local(j->app, j->msg, j->kwnl, j->userName);
+ }
+ if((j->s_queues) && (j->i_queues)) {
+ dkwt_clear_printers_remote(j->app, j->msg, j->kwnl, j->userName, j->i_queues);
+ }
+ } break;
+ case 4: { $? ". cleanup_profiles"
+ if (1 == dkwt_is_admin()) {
+ dkwt_ev_cleanup_profiles(j);
+ } else {
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 145);
+ }
+ } break;
+ }
+ $? "- dkwt_ev_do_processing"
+}
+
+
+
+/** Find account name for a SID.
+ @param j Job structure.
+ @param dp Destination buffer.
+ @param ind Index of string SID in message array.
+*/
+static
+void
+dkwt_find_account_name_for_sid(
+ DKWT_EV_J *j,
+ dkChar const * *dp,
+ size_t ind
+)
+{
+ dkChar b1[DK3_MAX_PATH];
+ dkChar b2[DK3_MAX_PATH];
+ PSID psid;
+ DWORD dwSz1;
+ DWORD dwSz2;
+ int success = 0;
+ BOOL res;
+ SID_NAME_USE sidNameUse;
+
+ dwSz1 = DK3_SIZEOF(b1,dkChar);
+ dwSz2 = DK3_SIZEOF(b2,dkChar);
+ psid = NULL;
+#if DK3_CHAR_SIZE > 1
+ res = ConvertStringSidToSidW((j->kwnl)[ind], &psid);
+#else
+ res = ConvertStringSidToSidA((j->kwnl)[ind], &psid);
+#endif
+ if(res) {
+ if(psid) {
+#if DK3_CHAR_SIZE > 1
+ res = LookupAccountSidW(
+ NULL,
+ psid,
+ b1,
+ &dwSz1,
+ b2,
+ &dwSz2,
+ &sidNameUse
+ );
+#else
+ res = LookupAccountSidA(
+ NULL,
+ psid,
+ b1,
+ &dwSz1,
+ b2,
+ &dwSz2,
+ &sidNameUse
+ );
+#endif
+ if(res) {
+ if(dwSz1 > 0) {
+ if(dwSz1 < DK3_SIZEOF(b1,dkChar)) {
+ b1[dwSz1] = dkT('\0');
+ } else {
+ b1[DK3_SIZEOF(b1,dkChar) - 1] = dkT('\0');
+ }
+ if(dk3str_len(b1) > 0) {
+ *dp = dk3str_dup_app(b1, NULL);
+ if(*dp) {
+ success = 1;
+ } else { $? "! memory"
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ }
+ } else { $? "! size"
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ } else { $? "! Size"
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ } else { $? "! LookupAccountSid"
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ LocalFree(psid);
+ } else { $? "! NULL pointer"
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ } else { $? "! ConvertStringSidToSid"
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ if(!(success)) {
+ /* ERROR: Failed to find Group name for SID! */
+ dk3app_log_3(j->app, DK3_LL_ERROR, j->msg, 80, 81, (j->kwnl)[ind]);
+ }
+}
+
+
+
+/** Complete account names for system and everyone user.
+ @param j Job structure.
+*/
+static
+void
+dkwt_complete_account_names(
+ DKWT_EV_J *j
+)
+{
+ if(!(j->systemUser)) {
+ dkwt_find_account_name_for_sid(j, &(j->systemUser), 18);
+ }
+ if(!(j->everyUser)) {
+ dkwt_find_account_name_for_sid(j, &(j->everyUser), 17);
+ }
+}
+
+
+
+/** Run with a found configuration file name.
+ Process the configuration file and call dkwt_ev_do_processing().
+ @param j Job structure.
+ @param fn Configuration file name.
+*/
+static
+void
+dkwt_ev_run_with_config_file_name(DKWT_EV_J *j, dkChar const *fn)
+{
+ dkChar bu[DK3_MAX_PATH];
+ dkwt_account_list_t *al;
+ dkwt_account_t *ac;
+ dkChar *p1;
+ int ok = 0;
+ $? "+ dkwt_ev_run_with_config_file_name"
+ ok = dk3stream_process_filename_lines_app(
+ (void *)j,
+ dkwt_ev_line_handler,
+ fn,
+ bu,
+ DK3_SIZEOF(bu,dkChar),
+ dk3app_get_encoding(j->app),
+ dk3app_get_input_file_encoding(j->app),
+ j->app
+ );
+ if(ok) { $? ". ok"
+ dkwt_complete_account_names(j);
+ al = dkwt_tool_open_account_list(j->app, 0);
+ if(al) { $? ". al"
+ dkwt_tool_reset_account_list(al);
+ while((ac = dkwt_tool_get_account_from_list(al)) != NULL) {
+ p1 = dk3str_dup_app(ac->logname, j->app);
+ if(p1) { $? ". p1"
+ if(!(dk3sto_add(j->s_users, (void *)p1))) {
+ ok = 0; $? "! dk3sto_add"
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ dk3_release(p1);
+ }
+ } else { $? "! p1"
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ }
+ }
+ dkwt_tool_close_account_list(al);
+ if(ok) { $? ". ok"
+ dkwt_ev_do_processing(j);
+ } else { $? "! ok"
+ }
+ } else { $? "! al"
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ } else { $? "! ok"
+ } $? "- dkwt_ev_run_with_config_file_name"
+}
+
+
+
+/** Continue after allocating the storages.
+ Find the users login name if necessary and one configuration file
+ and call dkwt_ev_run_with_config_file_name().
+ @param j Job structure.
+*/
+static
+void
+dkwt_ev_run_with_storages(DKWT_EV_J *j)
+{
+ dkChar bu[DK3_MAX_PATH]; /* Buffer for user name. */
+ dkChar const *fn; /* Configuration file name. */
+ dk3_search_t *sr; /* Search result. */
+ int ok = 1; /* Flag: OK so far. */
+ $? "+ dkwt_ev_run_with_storages"
+ switch(j->event) {
+ case 2: case 3: {
+ ok = 0;
+ if(dk3sf_get_logname_app(bu, DK3_SIZEOF(bu,dkChar), j->app)) {
+ j->userName = dk3str_dup_app(bu, j->app);
+ if(j->userName) {
+ ok = 1;
+ } else {
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ }
+ } else {
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ } break;
+ }
+ if(ok) { $? ". ok"
+ sr = dk3app_find_config_file_revers(j->app, (j->kwnl)[1], 1);
+ if(sr) { $? ". sr"
+ dk3search_reset(sr);
+ fn = dk3search_next(sr);
+ if(fn) { $? ". fn"
+ dkwt_ev_run_with_config_file_name(j, fn);
+ } else { $? "! fn"
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ dk3search_close(sr);
+ } else { $? "! sr"
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ } else { $? "! ok"
+ } $? "- dkwt_ev_run_with_storages"
+}
+
+
+
+/** Run for event.
+ Allocate the storages needed later und call dkwt_ev_run_with_storages().
+ @param j Job structure.
+*/
+static
+void
+dkwt_ev_run(DKWT_EV_J *j)
+{
+ dkChar const * const *xargv;
+ int xargc;
+ $? "+ dkwt_ev_run"
+ xargc = dk3app_get_argc(j->app);
+ xargv = dk3app_get_argv(j->app);
+ xargv++; xargv++; xargc--; xargc--;
+ j->opt = dk3opt_open_app(
+ dkwt_ev_options,
+ dkwt_ev_szoptions,
+ dkT('\0'),
+ NULL,
+ xargc,
+ xargv,
+ j->app
+ );
+ if(j->opt) {
+ if(0 == dk3opt_get_error_code(j->opt)) {
+ if(dk3opt_is_set(j->opt, dkT('t'))) {
+ j->testOnly = 1;
+ }
+ j->s_users = dk3sto_open_app(j->app);
+ if(j->s_users) {
+ dk3sto_set_comp(j->s_users, dkwt_ev_compare_string, 0);
+ j->i_users = dk3sto_it_open(j->s_users);
+ if(j->i_users) {
+ j->s_pubdir= dk3sto_open_app(j->app);
+ if(j->s_pubdir) {
+ dk3sto_set_comp(j->s_pubdir, dkwt_ev_compare_string, 0);
+ j->i_pubdir = dk3sto_it_open(j->s_pubdir);
+ if(j->i_pubdir) {
+ dkwt_ev_run_with_storages(j);
+ } else {
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ }
+ } else {
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ }
+ } else {
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ }
+ } else {
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ }
+ } else {
+ j->exval = DKT_RESULT_ERR_OPTION;
+ }
+ } else {
+ j->exval = DKT_RESULT_ERR_OPTION;
+ }
+ $? "- dkwt_ev_run"
+}
+
+
+
+int
+dkwt_event(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl,
+ int evt
+)
+{
+ DKWT_EV_J j;
+ int back = DKT_RESULT_ERR_UNSPECIFIC;
+ $? "+ dkwt_event"
+ dkwt_ev_job_init(&j);
+ j.app = app; j.msg = msg; j.kwnl = kwnl; j.event = evt;
+ back = j.exval = DKT_RESULT_OK;
+ dkwt_ev_run(&j);
+ back = j.exval;
+ dkwt_ev_job_cleanup(&j);
+ switch(evt) {
+ case 0: case 1: case 2: case 3: {
+ /*
+ Always indicate success, otherwise Windows might shut down
+ or log the user off.
+ */
+ back = 0;
+ } break;
+ }
+ $? "- dkwt_event"
+ return back;
+}
+
+
+
+int
+dkwt_event_keep(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl
+)
+{
+ int back = 1;
+ long result;
+ DWORD dw0;
+ HKEY hk;
+ DWORD dwDisp;
+ DWORD dwType;
+ DWORD dwValue;
+ DWORD dwSize;
+
+ dwDisp = 0L;
+ dw0 = 0L;
+
+ result = dkwt_tool_reg_create_key(
+ HKEY_LOCAL_MACHINE, kwnl[15], dw0,
+ (KEY_READ | KEY_SET_VALUE), &hk, &dwDisp
+ );
+ if(result == ERROR_SUCCESS) {
+ dw0 = 0L;
+ dwType = REG_DWORD;
+ dwValue = 1L;
+ dwSize = sizeof(DWORD);
+ result = dkwt_ev_reg_set_value(
+ hk, kwnl[16], dwType, &dwValue, dwSize
+ );
+ if(result == ERROR_SUCCESS) {
+ back = 0;
+ }
+ }
+ dk3sf_initialize_stdout();
+ if(back) {
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 77);
+ if (1 != dkwt_is_admin()) {
+ dk3app_log_1(app, DK3_LL_ERROR, msg, 145);
+ }
+ } else {
+ dk3sf_fputs(msg[78], stdout);
+ }
+ dk3sf_fputc(dkT('\n'), stdout);
+ fflush(stdout);
+ return back;
+}
+
+
+
+int
+dkwt_event_unkeep(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl
+)
+{
+ (void)dkwt_ev_get_keep_value(app, msg, kwnl, 1);
+ return 0;
+}
+
diff --git a/support/dktools/dkwt-gr.c b/support/dktools/dkwt-gr.c
new file mode 100644
index 0000000000..8ee012ccc0
--- /dev/null
+++ b/support/dktools/dkwt-gr.c
@@ -0,0 +1,226 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dkwt-gr.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dkwt-gr.c The dkwt-gr module.
+*/
+
+
+#line 10 "dkwt-gr.ctr"
+
+#include "dk3all.h"
+#include "dkt.h"
+#include "dkwt.h"
+
+
+
+
+
+#line 18 "dkwt-gr.ctr"
+
+
+
+/** Job structure for dkwt groups.
+*/
+typedef struct {
+ dk3_app_t *app; /**< Application structure. */
+ dkChar const * const *msg; /**< Localized message texts. */
+ dkChar const * const *kwnl; /**< Keywords, not localized. */
+ dk3_option_set_t *opt; /**< Options set. */
+ int f_long; /**< Flag: Long user listing. */
+ int exval; /**< Exit status code. */
+} DKWT_GRP_J;
+
+
+
+/** Data for the option set.
+*/
+static dk3_option_t const dkwt_groups_options[] = {
+ { dkT('l'), dkT("long"), 0 },
+ { dkT('s'), dkT("short"), 0 }
+};
+
+/** Number of options in the dkt_sort_options array.
+*/
+static size_t const dkwt_groups_szoptions =
+sizeof(dkwt_groups_options)/sizeof(dk3_option_t);
+
+
+
+/** Initialize job structure.
+ @param j Job structure.
+*/
+static
+void
+dkwt_groups_job_init(DKWT_GRP_J *j)
+{
+ j->app = NULL; j->msg = NULL; j->kwnl = NULL; j->opt = NULL;
+ j->f_long = 1; j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+}
+
+
+
+
+/** Clean up job structure after use.
+ @param j Job structure.
+*/
+static
+void
+dkwt_groups_job_cleanup(DKWT_GRP_J *j)
+{
+ if(j->opt) {
+ dk3opt_close(j->opt);
+ } j->opt = NULL;
+}
+
+
+
+/** Process command line arguments.
+ @param j Job structure.
+ @return 1 on success (can continue), 0 on error.
+*/
+static
+int
+dkwt_groups_process_argv(DKWT_GRP_J *j)
+{
+ int back = 0;
+ int xargc;
+ dkChar const * const *xargv;
+
+ xargc = dk3app_get_argc(j->app);
+ xargv = dk3app_get_argv(j->app);
+ xargv++; xargv++; xargc--; xargc--;
+ j->opt = dk3opt_open_app(
+ dkwt_groups_options,
+ dkwt_groups_szoptions,
+ dkT('\0'),
+ NULL,
+ xargc,
+ xargv,
+ j->app
+ );
+ if(j->opt) {
+ if(0 == dk3opt_get_error_code(j->opt)) {
+ back = 1;
+ if(dk3opt_is_set(j->opt, dkT('l'))) {
+ j->f_long = 2;
+ if(dk3opt_is_set(j->opt, dkT('s'))) {
+ back = 0;
+ /* ERROR: -l and -s are exclusive */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 76);
+ }
+ } else {
+ if(dk3opt_is_set(j->opt, dkT('s'))) {
+ j->f_long = 0;
+ }
+ }
+ if(dk3opt_get_num_args(j->opt) > 0) {
+ /* Warning: Arguments ignored. */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 76);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Run the "list groups" operation.
+ @param j Job structure.
+*/
+static
+void
+dkwt_groups_run(DKWT_GRP_J *j)
+{
+ dkwt_group_list_t *gl;
+ dkwt_group_t *gp;
+ int is_first = 1;
+ dkChar const *ptr;
+
+ gl = dkwt_tool_open_group_list(j->app, j->f_long);
+ if(gl) {
+ dkwt_tool_reset_group_list(gl);
+ dk3sf_initialize_stdout();
+ while((gp = (dkwt_group_t *)dk3sto_it_next(gl->i_grp)) != NULL) {
+ if(gp->groupname) {
+ if((j->f_long) && (!(is_first))) {
+ dk3sf_fputc(dkT('\n'), stdout);
+ } is_first = 0;
+ dk3sf_fputs(gp->groupname, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ if(j->f_long) {
+ ptr = gp->groupname;
+ while(*(ptr++)) { dk3sf_fputc(dkT('-'), stdout); }
+ dk3sf_fputc(dkT('\n'), stdout);
+ dk3sf_fputs((j->msg)[39], stdout);
+ dk3sf_fputs((j->msg)[(gp->gtype) ? 42 : 41], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ if(gp->comment) {
+ dk3sf_fputs((j->msg)[40], stdout);
+ dk3sf_fputs(gp->comment, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ if(gp->textsid) {
+ dk3sf_fputs((j->msg)[43], stdout);
+ dk3sf_fputs(gp->textsid, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ }
+ }
+ }
+ dkwt_tool_close_group_list(gl);
+ }
+}
+
+
+
+int
+dkwt_groups(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl
+)
+{
+ int back = DKT_RESULT_ERR_UNSPECIFIC;
+ DKWT_GRP_J j;
+ dkwt_groups_job_init(&j);
+ j.app = app; j.msg = msg; j.kwnl = kwnl;
+ if(dkwt_groups_process_argv(&j)) {
+ back = j.exval = DKT_RESULT_OK;
+ dkwt_groups_run(&j);
+ }
+ dkwt_groups_job_cleanup(&j);
+ return back;
+}
+
diff --git a/support/dktools/dkwt-gr.ctr b/support/dktools/dkwt-gr.ctr
new file mode 100644
index 0000000000..45e73fe951
--- /dev/null
+++ b/support/dktools/dkwt-gr.ctr
@@ -0,0 +1,193 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk3all.h"
+#include "dkt.h"
+#include "dkwt.h"
+
+
+
+$!trace-include
+
+
+
+/** Job structure for dkwt groups.
+*/
+typedef struct {
+ dk3_app_t *app; /**< Application structure. */
+ dkChar const * const *msg; /**< Localized message texts. */
+ dkChar const * const *kwnl; /**< Keywords, not localized. */
+ dk3_option_set_t *opt; /**< Options set. */
+ int f_long; /**< Flag: Long user listing. */
+ int exval; /**< Exit status code. */
+} DKWT_GRP_J;
+
+
+
+/** Data for the option set.
+*/
+static dk3_option_t const dkwt_groups_options[] = {
+ { dkT('l'), dkT("long"), 0 },
+ { dkT('s'), dkT("short"), 0 }
+};
+
+/** Number of options in the dkt_sort_options array.
+*/
+static size_t const dkwt_groups_szoptions =
+sizeof(dkwt_groups_options)/sizeof(dk3_option_t);
+
+
+
+/** Initialize job structure.
+ @param j Job structure.
+*/
+static
+void
+dkwt_groups_job_init(DKWT_GRP_J *j)
+{
+ j->app = NULL; j->msg = NULL; j->kwnl = NULL; j->opt = NULL;
+ j->f_long = 1; j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+}
+
+
+
+
+/** Clean up job structure after use.
+ @param j Job structure.
+*/
+static
+void
+dkwt_groups_job_cleanup(DKWT_GRP_J *j)
+{
+ if(j->opt) {
+ dk3opt_close(j->opt);
+ } j->opt = NULL;
+}
+
+
+
+/** Process command line arguments.
+ @param j Job structure.
+ @return 1 on success (can continue), 0 on error.
+*/
+static
+int
+dkwt_groups_process_argv(DKWT_GRP_J *j)
+{
+ int back = 0;
+ int xargc;
+ dkChar const * const *xargv;
+
+ xargc = dk3app_get_argc(j->app);
+ xargv = dk3app_get_argv(j->app);
+ xargv++; xargv++; xargc--; xargc--;
+ j->opt = dk3opt_open_app(
+ dkwt_groups_options,
+ dkwt_groups_szoptions,
+ dkT('\0'),
+ NULL,
+ xargc,
+ xargv,
+ j->app
+ );
+ if(j->opt) {
+ if(0 == dk3opt_get_error_code(j->opt)) {
+ back = 1;
+ if(dk3opt_is_set(j->opt, dkT('l'))) {
+ j->f_long = 2;
+ if(dk3opt_is_set(j->opt, dkT('s'))) {
+ back = 0;
+ /* ERROR: -l and -s are exclusive */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 76);
+ }
+ } else {
+ if(dk3opt_is_set(j->opt, dkT('s'))) {
+ j->f_long = 0;
+ }
+ }
+ if(dk3opt_get_num_args(j->opt) > 0) {
+ /* Warning: Arguments ignored. */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 76);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Run the "list groups" operation.
+ @param j Job structure.
+*/
+static
+void
+dkwt_groups_run(DKWT_GRP_J *j)
+{
+ dkwt_group_list_t *gl;
+ dkwt_group_t *gp;
+ int is_first = 1;
+ dkChar const *ptr;
+
+ gl = dkwt_tool_open_group_list(j->app, j->f_long);
+ if(gl) {
+ dkwt_tool_reset_group_list(gl);
+ dk3sf_initialize_stdout();
+ while((gp = (dkwt_group_t *)dk3sto_it_next(gl->i_grp)) != NULL) {
+ if(gp->groupname) {
+ if((j->f_long) && (!(is_first))) {
+ dk3sf_fputc(dkT('\n'), stdout);
+ } is_first = 0;
+ dk3sf_fputs(gp->groupname, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ if(j->f_long) {
+ ptr = gp->groupname;
+ while(*(ptr++)) { dk3sf_fputc(dkT('-'), stdout); }
+ dk3sf_fputc(dkT('\n'), stdout);
+ dk3sf_fputs((j->msg)[39], stdout);
+ dk3sf_fputs((j->msg)[(gp->gtype) ? 42 : 41], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ if(gp->comment) {
+ dk3sf_fputs((j->msg)[40], stdout);
+ dk3sf_fputs(gp->comment, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ if(gp->textsid) {
+ dk3sf_fputs((j->msg)[43], stdout);
+ dk3sf_fputs(gp->textsid, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ }
+ }
+ }
+ dkwt_tool_close_group_list(gl);
+ }
+}
+
+
+
+int
+dkwt_groups(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl
+)
+{
+ int back = DKT_RESULT_ERR_UNSPECIFIC;
+ DKWT_GRP_J j;
+ dkwt_groups_job_init(&j);
+ j.app = app; j.msg = msg; j.kwnl = kwnl;
+ if(dkwt_groups_process_argv(&j)) {
+ back = j.exval = DKT_RESULT_OK;
+ dkwt_groups_run(&j);
+ }
+ dkwt_groups_job_cleanup(&j);
+ return back;
+}
+
diff --git a/support/dktools/dkwt-pr.c b/support/dktools/dkwt-pr.c
new file mode 100644
index 0000000000..95d4cef2c4
--- /dev/null
+++ b/support/dktools/dkwt-pr.c
@@ -0,0 +1,665 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dkwt-pr.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dkwt-pr.c The dkwt-pr module.
+*/
+
+
+#line 10 "dkwt-pr.ctr"
+
+#include "dk3all.h"
+#include "dkt.h"
+#include "dkwt.h"
+
+
+
+
+
+#line 18 "dkwt-pr.ctr"
+
+
+
+
+/** Job structure for dkwt printers.
+*/
+typedef struct {
+ dk3_app_t *app; /**< Application structure. */
+ dkChar const * const *msg; /**< Localized message texts. */
+ dkChar const * const *kwnl; /**< Keywords, not localized. */
+ dk3_option_set_t *opt; /**< Command line options. */
+ int exval; /**< Exit status code. */
+ int f_long; /**< Flag: Long output. */
+} DKWT_PRINTERS_J;
+
+
+
+/** Data for the option set.
+*/
+static dk3_option_t const dkwt_printers_options[] = {
+ { dkT('l'), dkT("long"), 0 }
+};
+
+/** Number of options in the dkt_sort_options array.
+*/
+static size_t const dkwt_printers_szoptions =
+sizeof(dkwt_printers_options)/sizeof(dk3_option_t);
+
+
+
+/** Initialize job structure.
+ @param j Job structure to initialize.
+*/
+static
+void
+dkwt_printers_job_init(DKWT_PRINTERS_J *j)
+{
+ j->app = NULL; j->msg = NULL; j->kwnl = NULL; j->opt = NULL;
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ j->f_long = 0;
+}
+
+
+
+/** Clean up job structure.
+ @param j Job structure to clean up.
+*/
+static
+void
+dkwt_printers_job_cleanup(DKWT_PRINTERS_J *j)
+{
+ if(j) {
+ if(j->opt) {
+ dk3opt_close(j->opt);
+ } j->opt = NULL;
+ }
+}
+
+
+
+/** Process command line arguments.
+ @param j Job structure.
+ @return 1 on success (can continue), 0 on error.
+*/
+static
+int
+dkwt_printers_process_argv(DKWT_PRINTERS_J *j)
+{
+ int back = 0;
+ int xargc;
+ dkChar const * const *xargv;
+ xargc = dk3app_get_argc(j->app);
+ xargv = dk3app_get_argv(j->app);
+
+
+#line 92 "dkwt-pr.ctr"
+ xargv++; xargv++; xargc--; xargc--;
+ j->opt = dk3opt_open_app(
+ dkwt_printers_options,
+ dkwt_printers_szoptions,
+ dkT('\0'),
+ NULL,
+ xargc,
+ xargv,
+ j->app
+ );
+ if(j->opt) {
+ if(0 == dk3opt_get_error_code(j->opt)) {
+ back = 1;
+ if(dk3opt_is_set(j->opt, dkT('l'))) {
+ j->f_long = 1;
+ }
+ } else { j->exval = DKT_RESULT_ERR_OPTION; }
+ } else { j->exval = DKT_RESULT_ERR_OPTION; }
+ return back;
+}
+
+
+
+/** Show details about a printer.
+ @param j Job structure.
+ @param txt Detail value.
+ @param mi Index of detail name in message array.
+*/
+static
+void
+dkwt_pr_details(DKWT_PRINTERS_J *j, dkChar const *txt, size_t mi)
+{
+ if(txt) {
+ if(dk3str_len(txt)) {
+ dk3sf_fputs((j->msg)[mi], stdout);
+ dk3sf_fputs(txt, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ }
+}
+
+
+
+/** Run the "list printers" command.
+ @param j Job structure.
+*/
+static
+void
+dkwt_printers_run(DKWT_PRINTERS_J *j)
+{
+ dkwt_printer_list_t *pl;
+ dkwt_printer_t *pr;
+ int not_first = 0;
+ dkChar const *ptr;
+
+ pl = dkwt_tool_open_printer_list(j->app, j->f_long);
+ if(pl) {
+ dkwt_tool_printer_list_reset(pl);
+ dk3sf_initialize_stdout();
+ while((pr = dkwt_tool_printer_list_next(pl)) != NULL) {
+ if((j->f_long) && (not_first)) {
+ dk3sf_fputc(dkT('\n'), stdout);
+ } not_first = 1;
+ if(pr->printerName) {
+ dk3sf_fputs(pr->printerName, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ if(j->f_long) {
+ ptr = pr->printerName;
+ while(*(ptr++)) { dk3sf_fputc(dkT('-'), stdout); }
+ dk3sf_fputc(dkT('\n'), stdout);
+ dkwt_pr_details(j, pr->comment, 44);
+ dkwt_pr_details(j, pr->description, 45);
+ dkwt_pr_details(j, pr->location, 46);
+ dkwt_pr_details(j, pr->serverName, 47);
+ dkwt_pr_details(j, pr->shareName, 48);
+ dkwt_pr_details(j, pr->portName, 49);
+ dkwt_pr_details(j, pr->driverName, 50);
+ dkwt_pr_details(j, pr->deviceName, 51);
+ dkwt_pr_details(j, pr->separatorFile, 52);
+ dkwt_pr_details(j, pr->printProcessor, 53);
+ dkwt_pr_details(j, pr->dataType, 54);
+ dkwt_pr_details(j, pr->parameters, 55);
+ }
+ }
+ }
+ dkwt_tool_close_printer_list(pl);
+ } else {
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ }
+}
+
+
+
+int
+dkwt_printers(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl
+)
+{
+ int back = DKT_RESULT_ERR_UNSPECIFIC;
+ DKWT_PRINTERS_J j;
+
+ dkwt_printers_job_init(&j);
+ j.app = app; j.msg = msg; j.kwnl = kwnl;
+ if(dkwt_printers_process_argv(&j)) {
+ back = j.exval = DKT_RESULT_OK;
+ dkwt_printers_run(&j);
+ }
+ dkwt_printers_job_cleanup(&j);
+ return back;
+}
+
+
+
+
+/** Job structure for dkwt print.
+*/
+typedef struct {
+ dkChar const *deviceName; /**< Device name from command line. */
+ dkChar const *printerName; /**< Printer name to use. */
+ dk3_app_t *app; /**< Application structure. */
+ dkChar const * const *msg; /**< Localized message texts. */
+ dkChar const * const *kwnl; /**< Keywords, not localized. */
+ dk3_option_set_t *opt; /**< Command line options. */
+ int exval; /**< Exit status code. */
+} DKWT_PRINT_J;
+
+
+
+/** Data for the option set.
+*/
+static dk3_option_t const dkwt_print_options[] = {
+ { dkT('d'), dkT("device"), 1 }
+};
+
+/** Number of options in the dkt_print_options array.
+*/
+static size_t const dkwt_print_szoptions =
+sizeof(dkwt_print_options)/sizeof(dk3_option_t);
+
+
+
+/** Initialize job structure.
+ @param j Job structure to initialize.
+*/
+static
+void
+dkwt_print_job_init(DKWT_PRINT_J *j)
+{
+ j->deviceName = NULL; j->printerName = NULL;
+ j->app = NULL; j->msg = NULL; j->kwnl = NULL;
+ j->opt = NULL;
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+}
+
+
+
+/** Clean up job structure.
+ @param j Job structure to clean up.
+*/
+static
+void
+dkwt_print_job_cleanup(DKWT_PRINT_J *j)
+{
+ if(j->opt) {
+ dk3opt_close(j->opt);
+ } j->opt = NULL;
+}
+
+
+
+/** Process command line arguments.
+ @param j Job structure.
+ @return 1 on success (can continue), 0 on error.
+*/
+static
+int
+dkwt_print_process_argv(DKWT_PRINT_J *j)
+{
+ int back = 0;
+ int xargc;
+ dkChar const * const *xargv;
+
+
+#line 276 "dkwt-pr.ctr"
+ xargc = dk3app_get_argc(j->app);
+ xargv = dk3app_get_argv(j->app);
+ xargv++; xargv++; xargc--; xargc--;
+ j->opt = dk3opt_open_app(
+ dkwt_print_options,
+ dkwt_print_szoptions,
+ dkT('\0'),
+ NULL,
+ xargc,
+ xargv,
+ j->app
+ );
+ if(j->opt) {
+
+#line 289 "dkwt-pr.ctr"
+ if(0 == dk3opt_get_error_code(j->opt)) {
+
+#line 290 "dkwt-pr.ctr"
+ back = 1;
+ if(dk3opt_is_set(j->opt, dkT('d'))) {
+
+#line 292 "dkwt-pr.ctr"
+ j->deviceName = dk3opt_get_short_arg(j->opt, dkT('d'));
+ if(!(j->deviceName)) {
+
+#line 294 "dkwt-pr.ctr"
+ j->exval = DKT_RESULT_ERR_OPTION;
+ back = 0;
+ }
+ }
+ } else {
+ j->exval = DKT_RESULT_ERR_OPTION;
+ }
+ } else {
+ j->exval = DKT_RESULT_ERR_OPTION;
+ }
+
+#line 304 "dkwt-pr.ctr"
+ return back;
+}
+
+
+
+/** Schedule a file to a printer.
+ @param j Job structure.
+ @param hFile Destination file handle.
+ @param fn Source file name.
+*/
+static
+void
+dkwt_print_schedule_file(DKWT_PRINT_J *j, HANDLE hFile, dkChar const *fn)
+{
+ FILE *fipo;
+ char buffer[4096];
+ size_t bytes;
+ DWORD written;
+
+
+#line 323 "dkwt-pr.ctr"
+ fipo = dk3sf_fopen_app(fn, dk3app_not_localized(36), j->app);
+ if(fipo) {
+ do {
+ bytes = dk3sf_fread_app(buffer, 1, sizeof(buffer), fipo, j->app);
+ if(bytes > 0) {
+ written = 0;
+ if(!WriteFile(
+ hFile, (void const *)buffer, (DWORD)bytes, &written, NULL
+ )
+ )
+ {
+ dk3app_log_i1(j->app, DK3_LL_ERROR, 120);
+ j->exval = DKT_RESULT_ERR_OUTPUT;
+ }
+ }
+ } while(bytes > 0);
+ fclose(fipo);
+ } else {
+ j->exval = DKT_RESULT_ERR_FILENAME;
+ }
+
+#line 343 "dkwt-pr.ctr"
+}
+
+
+
+/** Print to a printer.
+ @param j Job structure.
+ @param pn Printer name.
+*/
+static
+void
+dkwt_print_to_printer(DKWT_PRINT_J *j, dkChar *pn)
+{
+ HANDLE hPr;
+ HANDLE hFile;
+ char ajbu[sizeof(ADDJOB_INFO_1) + (sizeof(dkChar)*DK3_MAX_PATH)];
+ DWORD dwLev = (DWORD)1;
+ DWORD dwSz;
+ DWORD dwNeeded;
+ ADDJOB_INFO_1 *aji1;
+ int ok;
+ DWORD dwAcc;
+ DWORD dwSh;
+ DWORD dwDisp;
+ DWORD dwAttr;
+ int oldmode;
+ char db[4096];
+ int bytes;
+ DWORD written;
+ int nfn; /* Number of file names. */
+ int i; /* Current file name index. */
+ dkChar const *curarg; /* Current argument. */
+ dkChar const *curfn; /* Current file name. */
+ dk3_dir_t *fne; /* File name expander. */
+
+
+#line 377 "dkwt-pr.ctr"
+ ok = 0;
+ if(OpenPrinter(pn, &hPr, NULL)) {
+
+#line 379 "dkwt-pr.ctr"
+ dwSz = sizeof(ajbu);
+ dwNeeded = (DWORD)0UL;
+ if(AddJob(hPr, dwLev, (LPBYTE)ajbu, dwSz, &dwNeeded)) {
+ aji1 = (ADDJOB_INFO_1 *)ajbu;
+
+#line 383 "dkwt-pr.ctr"
+ if(aji1->Path) {
+
+#line 384 "dkwt-pr.ctr"
+ hFile = INVALID_HANDLE_VALUE;
+ dwAcc = GENERIC_WRITE;
+ dwSh = FILE_SHARE_READ;
+ dwDisp = CREATE_ALWAYS;
+ dwAttr = FILE_ATTRIBUTE_NORMAL;
+ hFile = CreateFile(aji1->Path,dwAcc,dwSh,NULL,dwDisp,dwAttr,NULL);
+ if(hFile != INVALID_HANDLE_VALUE) {
+
+#line 391 "dkwt-pr.ctr"
+ if(dk3opt_get_num_args(j->opt) > 0) {
+
+#line 392 "dkwt-pr.ctr"
+ nfn = dk3opt_get_num_args(j->opt);
+ for(i = 0; i < nfn; i++) {
+ curarg = dk3opt_get_arg(j->opt, i);
+ if(curarg) {
+
+#line 396 "dkwt-pr.ctr"
+ if(dk3sf_must_expand(curarg)) {
+
+#line 397 "dkwt-pr.ctr"
+ fne = dk3dir_fne_open_app(curarg, j->app);
+ if(fne) {
+ if(dk3dir_get_number_of_files(fne) > 0) {
+ while(dk3dir_get_next_file(fne)) {
+ curfn = dk3dir_get_fullname(fne);
+ if(curfn) {
+
+#line 403 "dkwt-pr.ctr"
+ dkwt_print_schedule_file(j, hFile, curfn);
+ } else {
+ /* BUG */
+ }
+ }
+ } else {
+ /* ERROR: No such file */
+ dk3app_log_i3(j->app, DK3_LL_ERROR, 215, 216, curarg);
+ j->exval = DKT_RESULT_ERR_FILENAME;
+ }
+ dk3dir_close(fne);
+ } else {
+ /* ERROR: No file name expander. */
+ j->exval = DKT_RESULT_ERR_FILENAME;
+ }
+ } else {
+
+#line 419 "dkwt-pr.ctr"
+ dkwt_print_schedule_file(j, hFile, curarg);
+ }
+ } else {
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ }
+ } else {
+
+#line 426 "dkwt-pr.ctr"
+ oldmode = _setmode(0, _O_BINARY);
+ do {
+ bytes = _read(0, db, sizeof(db));
+ if(bytes > 0) {
+
+#line 430 "dkwt-pr.ctr"
+ written = 0;
+ if(!WriteFile(
+ hFile, (void const *)db, (DWORD)bytes, &written, NULL
+ )
+ )
+ {
+ /* ERROR: Failed to write bytes! */
+ dk3app_log_i1(j->app, DK3_LL_ERROR, 120);
+ j->exval = DKT_RESULT_ERR_OUTPUT;
+ }
+ }
+ } while(bytes > 0);
+ _setmode(0, oldmode);
+ }
+ ok = 1;
+ CloseHandle(hFile);
+ } else {
+
+#line 447 "dkwt-pr.ctr"
+ /* ERROR: Failed to create print file! */
+ dk3app_log_3(j->app, DK3_LL_ERROR, j->msg, 56, 57, aji1->Path);
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ if(ok) {
+ if(ScheduleJob(hPr, aji1->JobId)) {
+ } else {
+ /* ERROR: Failed to schedule job */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 58);
+ }
+ }
+ } else {
+
+#line 459 "dkwt-pr.ctr"
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ } else {
+
+#line 462 "dkwt-pr.ctr"
+ /* ERROR: AddJob failed! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 59);
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ ClosePrinter(hPr);
+ } else {
+
+#line 468 "dkwt-pr.ctr"
+ /* ERROR: Failed to open printer! */
+ dk3app_log_3(j->app, DK3_LL_ERROR, j->msg, 60, 61, pn);
+ j->exval = DKT_RESULT_ERR_OPTION;
+ }
+
+#line 472 "dkwt-pr.ctr"
+}
+
+
+
+/** Run the "dkwt print" command.
+ @param j Job structure.
+*/
+static
+void
+dkwt_print_run(DKWT_PRINT_J *j)
+{
+ dkwt_printer_list_t *pl;
+ dkwt_printer_t *pr;
+ dkChar bu[DK3_MAX_PATH];
+ DWORD dwSz;
+ int found = 0;
+
+
+#line 489 "dkwt-pr.ctr"
+ pl = dkwt_tool_open_printer_list(j->app, 1);
+ if(pl) {
+
+#line 491 "dkwt-pr.ctr"
+ if(j->deviceName) {
+
+#line 492 "dkwt-pr.ctr"
+ dkwt_tool_printer_list_reset(pl);
+ do {
+ pr = dkwt_tool_printer_list_next(pl);
+ if(pr) {
+ if((pr->portName) && (pr->printerName)) {
+ if(dk3str_cmp(pr->portName, j->deviceName) == 0) {
+ found = -1;
+ if(dk3str_len(pr->printerName) < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy_not_overlapped(bu, pr->printerName);
+ found = 1;
+ } else {
+ /* ERROR: Printer name too long! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 62);
+ }
+ }
+ }
+ }
+ } while((pr) && (found == 0));
+ if(found == 1) {
+ dkwt_print_to_printer(j, bu);
+ } else {
+ if(found == 0) {
+ /* ERROR: No printer found for device! */
+ dk3app_log_3(j->app, DK3_LL_ERROR, j->msg, 63, 64, j->deviceName);
+ j->exval = DKT_RESULT_ERR_OPTION;
+ }
+ }
+ } else {
+
+#line 520 "dkwt-pr.ctr"
+ dwSz = DK3_SIZEOF(bu,dkChar);
+ if(GetDefaultPrinter(bu, &dwSz)) {
+
+#line 522 "dkwt-pr.ctr"
+ if(dwSz < DK3_SIZEOF(bu,dkChar)) {
+ bu[dwSz] = dkT('\0');
+ } else {
+ bu[DK3_SIZEOF(bu,dkChar)-1] = dkT('\0');
+ }
+
+#line 527 "dkwt-pr.ctr"
+ dkwt_print_to_printer(j, bu);
+ } else {
+ /* ERROR: Failed to find default printer. */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 65);
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ }
+ dkwt_tool_close_printer_list(pl);
+ } else {
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ }
+
+#line 538 "dkwt-pr.ctr"
+}
+
+
+int
+dkwt_print(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl
+)
+{
+ int back = DKT_RESULT_ERR_UNSPECIFIC;
+ DKWT_PRINT_J j;
+
+
+#line 551 "dkwt-pr.ctr"
+ dkwt_print_job_init(&j);
+ j.app = app; j.msg = msg; j.kwnl = kwnl;
+ if(dkwt_print_process_argv(&j)) {
+ back = j.exval = DKT_RESULT_OK;
+ dkwt_print_run(&j);
+ }
+ dkwt_print_job_cleanup(&j);
+ back = j.exval;
+
+
+#line 560 "dkwt-pr.ctr"
+ return back;
+}
+
diff --git a/support/dktools/dkwt-pr.ctr b/support/dktools/dkwt-pr.ctr
new file mode 100644
index 0000000000..9a1081ba1b
--- /dev/null
+++ b/support/dktools/dkwt-pr.ctr
@@ -0,0 +1,562 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk3all.h"
+#include "dkt.h"
+#include "dkwt.h"
+
+
+
+$!trace-include
+
+
+
+
+/** Job structure for dkwt printers.
+*/
+typedef struct {
+ dk3_app_t *app; /**< Application structure. */
+ dkChar const * const *msg; /**< Localized message texts. */
+ dkChar const * const *kwnl; /**< Keywords, not localized. */
+ dk3_option_set_t *opt; /**< Command line options. */
+ int exval; /**< Exit status code. */
+ int f_long; /**< Flag: Long output. */
+} DKWT_PRINTERS_J;
+
+
+
+/** Data for the option set.
+*/
+static dk3_option_t const dkwt_printers_options[] = {
+ { dkT('l'), dkT("long"), 0 }
+};
+
+/** Number of options in the dkt_sort_options array.
+*/
+static size_t const dkwt_printers_szoptions =
+sizeof(dkwt_printers_options)/sizeof(dk3_option_t);
+
+
+
+/** Initialize job structure.
+ @param j Job structure to initialize.
+*/
+static
+void
+dkwt_printers_job_init(DKWT_PRINTERS_J *j)
+{
+ j->app = NULL; j->msg = NULL; j->kwnl = NULL; j->opt = NULL;
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ j->f_long = 0;
+}
+
+
+
+/** Clean up job structure.
+ @param j Job structure to clean up.
+*/
+static
+void
+dkwt_printers_job_cleanup(DKWT_PRINTERS_J *j)
+{
+ if(j) {
+ if(j->opt) {
+ dk3opt_close(j->opt);
+ } j->opt = NULL;
+ }
+}
+
+
+
+/** Process command line arguments.
+ @param j Job structure.
+ @return 1 on success (can continue), 0 on error.
+*/
+static
+int
+dkwt_printers_process_argv(DKWT_PRINTERS_J *j)
+{
+ int back = 0;
+ int xargc;
+ dkChar const * const *xargv;
+ xargc = dk3app_get_argc(j->app);
+ xargv = dk3app_get_argv(j->app);
+ $? "+ dkwt_printers_process_argv argc=%d", xargc
+ xargv++; xargv++; xargc--; xargc--;
+ j->opt = dk3opt_open_app(
+ dkwt_printers_options,
+ dkwt_printers_szoptions,
+ dkT('\0'),
+ NULL,
+ xargc,
+ xargv,
+ j->app
+ );
+ if(j->opt) {
+ if(0 == dk3opt_get_error_code(j->opt)) {
+ back = 1;
+ if(dk3opt_is_set(j->opt, dkT('l'))) {
+ j->f_long = 1;
+ }
+ } else { j->exval = DKT_RESULT_ERR_OPTION; }
+ } else { j->exval = DKT_RESULT_ERR_OPTION; }
+ return back;
+}
+
+
+
+/** Show details about a printer.
+ @param j Job structure.
+ @param txt Detail value.
+ @param mi Index of detail name in message array.
+*/
+static
+void
+dkwt_pr_details(DKWT_PRINTERS_J *j, dkChar const *txt, size_t mi)
+{
+ if(txt) {
+ if(dk3str_len(txt)) {
+ dk3sf_fputs((j->msg)[mi], stdout);
+ dk3sf_fputs(txt, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ }
+}
+
+
+
+/** Run the "list printers" command.
+ @param j Job structure.
+*/
+static
+void
+dkwt_printers_run(DKWT_PRINTERS_J *j)
+{
+ dkwt_printer_list_t *pl;
+ dkwt_printer_t *pr;
+ int not_first = 0;
+ dkChar const *ptr;
+
+ pl = dkwt_tool_open_printer_list(j->app, j->f_long);
+ if(pl) {
+ dkwt_tool_printer_list_reset(pl);
+ dk3sf_initialize_stdout();
+ while((pr = dkwt_tool_printer_list_next(pl)) != NULL) {
+ if((j->f_long) && (not_first)) {
+ dk3sf_fputc(dkT('\n'), stdout);
+ } not_first = 1;
+ if(pr->printerName) {
+ dk3sf_fputs(pr->printerName, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ if(j->f_long) {
+ ptr = pr->printerName;
+ while(*(ptr++)) { dk3sf_fputc(dkT('-'), stdout); }
+ dk3sf_fputc(dkT('\n'), stdout);
+ dkwt_pr_details(j, pr->comment, 44);
+ dkwt_pr_details(j, pr->description, 45);
+ dkwt_pr_details(j, pr->location, 46);
+ dkwt_pr_details(j, pr->serverName, 47);
+ dkwt_pr_details(j, pr->shareName, 48);
+ dkwt_pr_details(j, pr->portName, 49);
+ dkwt_pr_details(j, pr->driverName, 50);
+ dkwt_pr_details(j, pr->deviceName, 51);
+ dkwt_pr_details(j, pr->separatorFile, 52);
+ dkwt_pr_details(j, pr->printProcessor, 53);
+ dkwt_pr_details(j, pr->dataType, 54);
+ dkwt_pr_details(j, pr->parameters, 55);
+ }
+ }
+ }
+ dkwt_tool_close_printer_list(pl);
+ } else {
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ }
+}
+
+
+
+int
+dkwt_printers(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl
+)
+{
+ int back = DKT_RESULT_ERR_UNSPECIFIC;
+ DKWT_PRINTERS_J j;
+
+ dkwt_printers_job_init(&j);
+ j.app = app; j.msg = msg; j.kwnl = kwnl;
+ if(dkwt_printers_process_argv(&j)) {
+ back = j.exval = DKT_RESULT_OK;
+ dkwt_printers_run(&j);
+ }
+ dkwt_printers_job_cleanup(&j);
+ return back;
+}
+
+
+
+
+/** Job structure for dkwt print.
+*/
+typedef struct {
+ dkChar const *deviceName; /**< Device name from command line. */
+ dkChar const *printerName; /**< Printer name to use. */
+ dk3_app_t *app; /**< Application structure. */
+ dkChar const * const *msg; /**< Localized message texts. */
+ dkChar const * const *kwnl; /**< Keywords, not localized. */
+ dk3_option_set_t *opt; /**< Command line options. */
+ int exval; /**< Exit status code. */
+} DKWT_PRINT_J;
+
+
+
+/** Data for the option set.
+*/
+static dk3_option_t const dkwt_print_options[] = {
+ { dkT('d'), dkT("device"), 1 }
+};
+
+/** Number of options in the dkt_print_options array.
+*/
+static size_t const dkwt_print_szoptions =
+sizeof(dkwt_print_options)/sizeof(dk3_option_t);
+
+
+
+/** Initialize job structure.
+ @param j Job structure to initialize.
+*/
+static
+void
+dkwt_print_job_init(DKWT_PRINT_J *j)
+{
+ j->deviceName = NULL; j->printerName = NULL;
+ j->app = NULL; j->msg = NULL; j->kwnl = NULL;
+ j->opt = NULL;
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+}
+
+
+
+/** Clean up job structure.
+ @param j Job structure to clean up.
+*/
+static
+void
+dkwt_print_job_cleanup(DKWT_PRINT_J *j)
+{
+ if(j->opt) {
+ dk3opt_close(j->opt);
+ } j->opt = NULL;
+}
+
+
+
+/** Process command line arguments.
+ @param j Job structure.
+ @return 1 on success (can continue), 0 on error.
+*/
+static
+int
+dkwt_print_process_argv(DKWT_PRINT_J *j)
+{
+ int back = 0;
+ int xargc;
+ dkChar const * const *xargv;
+ $? "+ dkwt_print_process_argv"
+ xargc = dk3app_get_argc(j->app);
+ xargv = dk3app_get_argv(j->app);
+ xargv++; xargv++; xargc--; xargc--;
+ j->opt = dk3opt_open_app(
+ dkwt_print_options,
+ dkwt_print_szoptions,
+ dkT('\0'),
+ NULL,
+ xargc,
+ xargv,
+ j->app
+ );
+ if(j->opt) { $? ". options ok"
+ if(0 == dk3opt_get_error_code(j->opt)) { $? ". options, no error"
+ back = 1;
+ if(dk3opt_is_set(j->opt, dkT('d'))) { $? ". -d option"
+ j->deviceName = dk3opt_get_short_arg(j->opt, dkT('d'));
+ if(!(j->deviceName)) { $? "! missing device name"
+ j->exval = DKT_RESULT_ERR_OPTION;
+ back = 0;
+ }
+ }
+ } else {
+ j->exval = DKT_RESULT_ERR_OPTION;
+ }
+ } else {
+ j->exval = DKT_RESULT_ERR_OPTION;
+ } $? "- dkwt_print_process_argv %d", back
+ return back;
+}
+
+
+
+/** Schedule a file to a printer.
+ @param j Job structure.
+ @param hFile Destination file handle.
+ @param fn Source file name.
+*/
+static
+void
+dkwt_print_schedule_file(DKWT_PRINT_J *j, HANDLE hFile, dkChar const *fn)
+{
+ FILE *fipo;
+ char buffer[4096];
+ size_t bytes;
+ DWORD written;
+ $? "+ schedule file \"%ls\"", fn
+ fipo = dk3sf_fopen_app(fn, dk3app_not_localized(36), j->app);
+ if(fipo) {
+ do {
+ bytes = dk3sf_fread_app(buffer, 1, sizeof(buffer), fipo, j->app);
+ if(bytes > 0) {
+ written = 0;
+ if(!WriteFile(
+ hFile, (void const *)buffer, (DWORD)bytes, &written, NULL
+ )
+ )
+ {
+ dk3app_log_i1(j->app, DK3_LL_ERROR, 120);
+ j->exval = DKT_RESULT_ERR_OUTPUT;
+ }
+ }
+ } while(bytes > 0);
+ fclose(fipo);
+ } else {
+ j->exval = DKT_RESULT_ERR_FILENAME;
+ } $? "- dkwt_print_schedule_file"
+}
+
+
+
+/** Print to a printer.
+ @param j Job structure.
+ @param pn Printer name.
+*/
+static
+void
+dkwt_print_to_printer(DKWT_PRINT_J *j, dkChar *pn)
+{
+ HANDLE hPr;
+ HANDLE hFile;
+ char ajbu[sizeof(ADDJOB_INFO_1) + (sizeof(dkChar)*DK3_MAX_PATH)];
+ DWORD dwLev = (DWORD)1;
+ DWORD dwSz;
+ DWORD dwNeeded;
+ ADDJOB_INFO_1 *aji1;
+ int ok;
+ DWORD dwAcc;
+ DWORD dwSh;
+ DWORD dwDisp;
+ DWORD dwAttr;
+ int oldmode;
+ char db[4096];
+ int bytes;
+ DWORD written;
+ int nfn; /* Number of file names. */
+ int i; /* Current file name index. */
+ dkChar const *curarg; /* Current argument. */
+ dkChar const *curfn; /* Current file name. */
+ dk3_dir_t *fne; /* File name expander. */
+ $? "+ dkwt_print_to_print \"%ls\"", pn
+ ok = 0;
+ if(OpenPrinter(pn, &hPr, NULL)) { $? ". printer opened"
+ dwSz = sizeof(ajbu);
+ dwNeeded = (DWORD)0UL;
+ if(AddJob(hPr, dwLev, (LPBYTE)ajbu, dwSz, &dwNeeded)) {
+ aji1 = (ADDJOB_INFO_1 *)ajbu; $? ". AddJob ok"
+ if(aji1->Path) { $? ". path ok"
+ hFile = INVALID_HANDLE_VALUE;
+ dwAcc = GENERIC_WRITE;
+ dwSh = FILE_SHARE_READ;
+ dwDisp = CREATE_ALWAYS;
+ dwAttr = FILE_ATTRIBUTE_NORMAL;
+ hFile = CreateFile(aji1->Path,dwAcc,dwSh,NULL,dwDisp,dwAttr,NULL);
+ if(hFile != INVALID_HANDLE_VALUE) { $? ". create file ok"
+ if(dk3opt_get_num_args(j->opt) > 0) { $? ". have arguments"
+ nfn = dk3opt_get_num_args(j->opt);
+ for(i = 0; i < nfn; i++) {
+ curarg = dk3opt_get_arg(j->opt, i);
+ if(curarg) { $? ". arg = \"%ls\"", curarg
+ if(dk3sf_must_expand(curarg)) { $? ". must expand"
+ fne = dk3dir_fne_open_app(curarg, j->app);
+ if(fne) {
+ if(dk3dir_get_number_of_files(fne) > 0) {
+ while(dk3dir_get_next_file(fne)) {
+ curfn = dk3dir_get_fullname(fne);
+ if(curfn) { $? ". curfn = \"%ls\"", curfn
+ dkwt_print_schedule_file(j, hFile, curfn);
+ } else {
+ /* BUG */
+ }
+ }
+ } else {
+ /* ERROR: No such file */
+ dk3app_log_i3(j->app, DK3_LL_ERROR, 215, 216, curarg);
+ j->exval = DKT_RESULT_ERR_FILENAME;
+ }
+ dk3dir_close(fne);
+ } else {
+ /* ERROR: No file name expander. */
+ j->exval = DKT_RESULT_ERR_FILENAME;
+ }
+ } else { $? ". no expansion"
+ dkwt_print_schedule_file(j, hFile, curarg);
+ }
+ } else {
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ }
+ } else { $? ". no arguments, use stdin"
+ oldmode = _setmode(0, _O_BINARY);
+ do {
+ bytes = _read(0, db, sizeof(db));
+ if(bytes > 0) { $? ". bytes = %d", bytes
+ written = 0;
+ if(!WriteFile(
+ hFile, (void const *)db, (DWORD)bytes, &written, NULL
+ )
+ )
+ {
+ /* ERROR: Failed to write bytes! */
+ dk3app_log_i1(j->app, DK3_LL_ERROR, 120);
+ j->exval = DKT_RESULT_ERR_OUTPUT;
+ }
+ }
+ } while(bytes > 0);
+ _setmode(0, oldmode);
+ }
+ ok = 1;
+ CloseHandle(hFile);
+ } else { $? "! CreateFile failed"
+ /* ERROR: Failed to create print file! */
+ dk3app_log_3(j->app, DK3_LL_ERROR, j->msg, 56, 57, aji1->Path);
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ if(ok) {
+ if(ScheduleJob(hPr, aji1->JobId)) {
+ } else {
+ /* ERROR: Failed to schedule job */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 58);
+ }
+ }
+ } else { $? "! no path"
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ } else { $? "! AddJob failed"
+ /* ERROR: AddJob failed! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 59);
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ ClosePrinter(hPr);
+ } else { $? "! failed to open printer"
+ /* ERROR: Failed to open printer! */
+ dk3app_log_3(j->app, DK3_LL_ERROR, j->msg, 60, 61, pn);
+ j->exval = DKT_RESULT_ERR_OPTION;
+ } $? "- dkwt_print_to_printer"
+}
+
+
+
+/** Run the "dkwt print" command.
+ @param j Job structure.
+*/
+static
+void
+dkwt_print_run(DKWT_PRINT_J *j)
+{
+ dkwt_printer_list_t *pl;
+ dkwt_printer_t *pr;
+ dkChar bu[DK3_MAX_PATH];
+ DWORD dwSz;
+ int found = 0;
+ $? "+ dkwt_print_run"
+ pl = dkwt_tool_open_printer_list(j->app, 1);
+ if(pl) { $? ". printer list ok"
+ if(j->deviceName) { $? ". device name \"%ls\"", j->deviceName
+ dkwt_tool_printer_list_reset(pl);
+ do {
+ pr = dkwt_tool_printer_list_next(pl);
+ if(pr) {
+ if((pr->portName) && (pr->printerName)) {
+ if(dk3str_cmp(pr->portName, j->deviceName) == 0) {
+ found = -1;
+ if(dk3str_len(pr->printerName) < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy_not_overlapped(bu, pr->printerName);
+ found = 1;
+ } else {
+ /* ERROR: Printer name too long! */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 62);
+ }
+ }
+ }
+ }
+ } while((pr) && (found == 0));
+ if(found == 1) {
+ dkwt_print_to_printer(j, bu);
+ } else {
+ if(found == 0) {
+ /* ERROR: No printer found for device! */
+ dk3app_log_3(j->app, DK3_LL_ERROR, j->msg, 63, 64, j->deviceName);
+ j->exval = DKT_RESULT_ERR_OPTION;
+ }
+ }
+ } else { $? "! no device name, use default printer"
+ dwSz = DK3_SIZEOF(bu,dkChar);
+ if(GetDefaultPrinter(bu, &dwSz)) { $? ". default printer found"
+ if(dwSz < DK3_SIZEOF(bu,dkChar)) {
+ bu[dwSz] = dkT('\0');
+ } else {
+ bu[DK3_SIZEOF(bu,dkChar)-1] = dkT('\0');
+ } $? ". default printer \"%ls\"", bu
+ dkwt_print_to_printer(j, bu);
+ } else {
+ /* ERROR: Failed to find default printer. */
+ dk3app_log_1(j->app, DK3_LL_ERROR, j->msg, 65);
+ j->exval = DKT_RESULT_ERR_UNSPECIFIC;
+ }
+ }
+ dkwt_tool_close_printer_list(pl);
+ } else {
+ j->exval = DKT_RESULT_ERR_MEMORY;
+ } $? "- dkwt_print_run"
+}
+
+
+int
+dkwt_print(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl
+)
+{
+ int back = DKT_RESULT_ERR_UNSPECIFIC;
+ DKWT_PRINT_J j;
+ $? "+ dkwt_print"
+ dkwt_print_job_init(&j);
+ j.app = app; j.msg = msg; j.kwnl = kwnl;
+ if(dkwt_print_process_argv(&j)) {
+ back = j.exval = DKT_RESULT_OK;
+ dkwt_print_run(&j);
+ }
+ dkwt_print_job_cleanup(&j);
+ back = j.exval;
+ $? "- dkwt_print %d", back
+ return back;
+}
+
diff --git a/support/dktools/dkwt-to.c b/support/dktools/dkwt-to.c
new file mode 100644
index 0000000000..1bec540ace
--- /dev/null
+++ b/support/dktools/dkwt-to.c
@@ -0,0 +1,1450 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dkwt-to.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dkwt-to.c The dkwt-to module.
+*/
+
+
+#line 10 "dkwt-to.ctr"
+
+
+#include "dk3all.h"
+#include "dkt.h"
+#include "dkwt.h"
+
+
+
+
+
+#line 19 "dkwt-to.ctr"
+
+
+
+/** Compare 2 accounts.
+ @param l Left account pointer.
+ @param r Right account pointer.
+ @param cr Comparison criteria (0=account/account, 1=account/name).
+ @return Comparison result.
+*/
+static
+int
+dkwt_tool_compare_accounts(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dkwt_account_t const *pl;
+ dkwt_account_t const *pr;
+ pl = (dkwt_account_t const *)l; pr = (dkwt_account_t const *)r;
+ if(l) {
+ if(r) {
+ switch(cr) {
+ case 1: {
+ if(pl->logname) {
+ back = dk3str_casecmp(pl->logname, (dkChar const *)r);
+ } else {
+ back = -1;
+ }
+ } break;
+ default: {
+ if(pl->logname) {
+ if(pr->logname) {
+ back = dk3str_casecmp(pl->logname, pr->logname);
+ } else {
+ back = 1;
+ }
+ } else {
+ if(pr->logname) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+ if(back > 1) back = 1;
+ if(back < -1) back = -1;
+ return back;
+}
+
+
+
+/** Compare two group entries.
+ @param l Left entry.
+ @param r Right entry.
+ @param cr Comparison criteria
+ (1=structure/name, other=sructure/structure).
+ @return Comparison result.
+*/
+static
+int
+dkwt_tool_compare_groups(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dkwt_group_t const *pl;
+ dkwt_group_t const *pr;
+
+ pl = (dkwt_group_t const *)l; pr = (dkwt_group_t const *)r;
+ if(l) {
+ if(r) {
+ switch(cr) {
+ case 1: {
+ if(pl->groupname) {
+ back = dk3str_casecmp(pl->groupname, (dkChar const *)r);
+ } else { back = -1; }
+ } break;
+ default: {
+ if(pl->groupname) {
+ if(pr->groupname) {
+ back = dk3str_casecmp(pl->groupname, pr->groupname);
+ } else { back = 1; }
+ } else {
+ if(pr->groupname) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+/** Change a dynamically allocated text.
+ @param destination Pointer to string pointer.
+ @param source Source text.
+ @param app Application structure for diagnostics.
+ @param returnValue Pointer to result variable.
+*/
+static
+void
+dkwt_tool_save_text(
+ dkChar const **destination,
+ dkChar const *source,
+ dk3_app_t *app,
+ int *returnValue
+)
+{
+ dkChar *np;
+
+
+#line 135 "dkwt-to.ctr"
+ if(source) {
+
+#line 136 "dkwt-to.ctr"
+ if(dk3str_len(source) > 0) {
+
+#line 137 "dkwt-to.ctr"
+ np = dk3str_dup_app(source, app);
+ if(np) {
+
+#line 139 "dkwt-to.ctr"
+ if(*destination) {
+ dk3_delete(*destination);
+ }
+ *destination = np;
+
+#line 143 "dkwt-to.ctr"
+ } else {
+ if(returnValue) {
+ *returnValue = 0;
+ }
+ }
+ }
+ }
+
+#line 150 "dkwt-to.ctr"
+}
+
+
+
+
+void
+dkwt_tool_close_account(dkwt_account_t *ap)
+{
+ if(ap) {
+ dk3_release(ap->textsid);
+ dk3_release(ap->profile);
+ dk3_release(ap->homedir);
+ dk3_release(ap->usrcomment);
+ dk3_release(ap->comment);
+ dk3_release(ap->fullname);
+ dk3_release(ap->logname);
+ dk3_delete(ap);
+ }
+}
+
+
+
+dkwt_account_t *
+dkwt_tool_open_account(dkChar const *logname, dk3_app_t *app)
+{
+ dkwt_account_t *back = NULL;
+ if(logname) {
+ back = dk3_new_app(dkwt_account_t,1,app);
+ if(back) {
+ back->logname = NULL; back->fullname = NULL;
+ back->comment = NULL; back->textsid = NULL;
+ back->usrcomment = NULL; back->homedir = NULL;
+ back->profile = NULL; back->f_long = 0;
+ back->logname = dk3str_dup_app(logname, app);
+ back->priv = (DWORD)0UL;
+ back->flags = (DWORD)0UL;
+ back->a_flags = (DWORD)0UL;
+ back->coco = (DWORD)0UL;
+ back->codepage = (DWORD)0UL;
+ if(!(back->logname)) {
+ dkwt_tool_close_account(back); back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void
+dkwt_tool_close_account_list(dkwt_account_list_t *lp)
+{
+ dkwt_account_t *ap;
+ if(lp) {
+ if(lp->s_acc) {
+ if(lp->i_acc) {
+ dk3sto_it_reset(lp->i_acc);
+ while((ap = (dkwt_account_t *)dk3sto_it_next(lp->i_acc)) != NULL) {
+ dkwt_tool_close_account(ap);
+ }
+ dk3sto_it_close(lp->i_acc);
+ }
+ dk3sto_close(lp->s_acc);
+ }
+ lp->s_acc = NULL;
+ lp->i_acc = NULL;
+ dk3_delete(lp);
+ }
+}
+
+
+
+dkwt_account_list_t *
+dkwt_tool_open_account_list(dk3_app_t *app, int f_long)
+{
+ dkwt_account_list_t *back = NULL;
+ dkwt_account_t *ap = NULL;
+ int ok = 0;
+ NET_API_STATUS nStatus;
+ LPUSER_INFO_0 pBuf = NULL;
+ LPUSER_INFO_0 pTmpBuf = NULL;
+ LPUSER_INFO_4 pb4 = NULL;
+ DWORD dwLevel = 0;
+ DWORD dwEntriesRead = 0;
+ DWORD dwTotalEntries = 0;
+ DWORD dwResumeHandle = 0;
+ DWORD dwPreferredLength = MAX_PREFERRED_LENGTH;
+ DWORD dwFilter = 0; /* FILTER_NORMAL_ACCOUNT */
+ DWORD i = 0;
+ LPTSTR pStringSid;
+
+
+#line 241 "dkwt-to.ctr"
+ back = dk3_new_app(dkwt_account_list_t,1,app);
+ if(back) {
+
+#line 243 "dkwt-to.ctr"
+ back->s_acc = NULL; back->i_acc = NULL;
+ back->s_acc = dk3sto_open_app(app);
+ if(back->s_acc) {
+
+#line 246 "dkwt-to.ctr"
+ dk3sto_set_comp(back->s_acc, dkwt_tool_compare_accounts, 0);
+ back->i_acc = dk3sto_it_open(back->s_acc);
+ if(back->i_acc) {
+
+#line 249 "dkwt-to.ctr"
+ ok = 1;
+ do {
+ pBuf = NULL;
+ dwEntriesRead = 0;
+ nStatus = NetUserEnum(
+ NULL, /* Local machine */
+ dwLevel, /* Level 0 */
+ dwFilter, /* Normal users */
+ (LPBYTE *)(&pBuf), /* Destination */
+ dwPreferredLength, /* Preferred length */
+ &dwEntriesRead,
+ &dwTotalEntries,
+ &dwResumeHandle
+ );
+
+#line 263 "dkwt-to.ctr"
+ if((NERR_Success == nStatus) || (ERROR_MORE_DATA == nStatus)) {
+
+
+#line 265 "dkwt-to.ctr"
+ if(pBuf != NULL) {
+
+#line 266 "dkwt-to.ctr"
+ pTmpBuf = pBuf;
+ for(i = 0; i < dwEntriesRead; i++) {
+
+
+#line 269 "dkwt-to.ctr"
+ if(pTmpBuf->usri0_name) {
+
+#line 270 "dkwt-to.ctr"
+ ap = dkwt_tool_open_account(pTmpBuf->usri0_name, app);
+ if(ap) {
+
+#line 272 "dkwt-to.ctr"
+ if(!dk3sto_add(back->s_acc, (void *)ap)) {
+ ok = 0;
+ dkwt_tool_close_account(ap);
+ }
+ } else {
+
+#line 277 "dkwt-to.ctr"
+ ok = 0;
+ }
+ } else {
+
+#line 280 "dkwt-to.ctr"
+ }
+ pTmpBuf++;
+ }
+ } else {
+
+#line 284 "dkwt-to.ctr"
+ }
+ } else {
+
+#line 286 "dkwt-to.ctr"
+ }
+ if(pBuf != NULL) {
+ NetApiBufferFree(pBuf);
+ pBuf = NULL;
+ }
+ } while(ERROR_MORE_DATA == nStatus);
+ if(pBuf != NULL) {
+ NetApiBufferFree(pBuf);
+ }
+ if(ok) {
+ if(f_long) {
+ dk3sto_it_reset(back->i_acc);
+ while((ap = (dkwt_account_t *)dk3sto_it_next(back->i_acc)) != NULL) {
+ pb4 = NULL;
+ nStatus = NetUserGetInfo(NULL, ap->logname, (DWORD)4, (LPBYTE *)(&pb4));
+ if(NERR_Success == nStatus)
+ {
+ if(pb4) {
+
+#line 304 "dkwt-to.ctr"
+ ap->f_long = 1;
+ ap->priv = pb4->usri4_priv;
+ ap->flags = pb4->usri4_flags;
+ ap->a_flags = pb4->usri4_auth_flags;
+ ap->coco = pb4->usri4_country_code;
+ ap->codepage = pb4->usri4_code_page;
+ if(pb4->usri4_full_name) {
+
+#line 311 "dkwt-to.ctr"
+ ap->fullname = dk3str_dup_app(pb4->usri4_full_name, app);
+ if(!(ap->fullname)) {
+ ok = 0;
+ }
+ }
+ if(pb4->usri4_comment) {
+
+#line 317 "dkwt-to.ctr"
+ ap->comment = dk3str_dup_app(pb4->usri4_comment, app);
+ if(!(ap->comment)) {
+ ok = 0;
+ }
+ }
+ if(pb4->usri4_usr_comment) {
+ ap->usrcomment = dk3str_dup_app(pb4->usri4_usr_comment, app);
+ if(!(ap->usrcomment)) {
+ ok = 0;
+ }
+ }
+ if(pb4->usri4_home_dir) {
+ ap->homedir = dk3str_dup_app(pb4->usri4_home_dir, app);
+ if(!(ap->homedir)) {
+ ok = 0;
+ }
+ }
+ if(pb4->usri4_profile) {
+ ap->profile = dk3str_dup_app(pb4->usri4_profile, app);
+ if(!(ap->profile)) {
+ ok = 0;
+ }
+ }
+ if(pb4->usri4_user_sid) {
+
+#line 341 "dkwt-to.ctr"
+ pStringSid = NULL;
+ if(ConvertSidToStringSid(pb4->usri4_user_sid, &pStringSid))
+ {
+ if(pStringSid) {
+ ap->textsid = dk3str_dup_app(pStringSid, app);
+ if(!(ap->textsid)) {
+ ok = 0;
+ }
+ }
+ }
+ if(pStringSid) { LocalFree(pStringSid); }
+
+ }
+ } else {
+
+#line 355 "dkwt-to.ctr"
+ }
+ } else {
+
+#line 357 "dkwt-to.ctr"
+ }
+ if(pb4) {
+ NetApiBufferFree(pb4);
+ }
+ }
+ }
+ }
+ } else {
+
+#line 365 "dkwt-to.ctr"
+ }
+ } else {
+
+#line 367 "dkwt-to.ctr"
+ }
+ if(!ok) {
+ dkwt_tool_close_account_list(back); back = NULL;
+ }
+ } else {
+
+#line 372 "dkwt-to.ctr"
+ }
+
+#line 373 "dkwt-to.ctr"
+ return back;
+}
+
+
+
+void
+dkwt_tool_reset_account_list(dkwt_account_list_t *lp)
+{
+ if(lp) {
+ if(lp->i_acc) {
+ dk3sto_it_reset(lp->i_acc);
+ }
+ }
+}
+
+
+
+dkwt_account_t *
+dkwt_tool_get_account_from_list(dkwt_account_list_t *lp)
+{
+ dkwt_account_t *back = NULL;
+ if(lp) {
+ if(lp->i_acc) {
+ back = (dkwt_account_t *)dk3sto_it_next(lp->i_acc);
+ }
+ }
+ return back;
+}
+
+
+
+/** Compare two group entries.
+ @param l Left entry.
+ @param r Right entry.
+ @param cr Comparison criteria (0=data/data, 1=data/name).
+ @return Comparison result.
+*/
+static
+int
+dkwt_group_compare(void *l, void *r, int cr)
+{
+ int back = 0;
+ dkwt_group_t *pl;
+ dkwt_group_t *pr;
+
+ pl = (dkwt_group_t *)l; pr = (dkwt_group_t *)r;
+ if(l) {
+ if(r) {
+ switch(cr) {
+ case 1: {
+ if(pl->groupname) {
+ back = dk3str_casecmp(pl->groupname, (dkChar const *)r);
+ } else {
+ back = -1;
+ }
+ } break;
+ default: {
+ if(pl->groupname) {
+ if(pr->groupname) {
+ back = dk3str_casecmp(pl->groupname, pr->groupname);
+ } else back = 1;
+ } else {
+ if(pr->groupname) back = -1;
+ }
+ } break;
+ }
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ }
+ return back;
+}
+
+
+
+
+/** Close group structure, release memory.
+ @param gp Group structure to close.
+*/
+static
+void
+dkwt_tool_close_group(dkwt_group_t *gp)
+{
+ if(gp) {
+ dk3_release(gp->groupname);
+ dk3_release(gp->comment);
+ dk3_release(gp->textsid);
+ gp->attributes = (DWORD)0UL;
+ dk3_delete(gp);
+ }
+}
+
+
+
+/** Open new group structure, allocate memory.
+ @param gn Group name.
+ @param app Application structure for diagnostics.
+ @return Pointer on success, NULL on error.
+*/
+static
+dkwt_group_t *
+dkwt_tool_open_group(dkChar const *gn, dk3_app_t *app)
+{
+ dkwt_group_t *back = NULL;
+ back = dk3_new_app(dkwt_group_t,1,app);
+ if(back) {
+ back->comment = NULL;
+ back->textsid = NULL;
+ back->attributes = (DWORD)0UL;
+ back->groupname = dk3str_dup_app(gn, app);
+ if(!(back->groupname)) {
+ dkwt_tool_close_group(back); back = NULL;
+ }
+ }
+ return back;
+}
+
+
+void
+dkwt_tool_reset_group_list(dkwt_group_list_t *glp)
+{
+ if(glp) {
+ if(glp->i_grp) {
+ dk3sto_it_reset(glp->i_grp);
+ }
+ }
+}
+
+
+
+dkwt_group_t *
+dkwt_tool_get_group_from_list(dkwt_group_list_t *glp)
+{
+ dkwt_group_t *back = NULL;
+ if(glp) {
+ if(glp->i_grp) {
+ back = (dkwt_group_t *)dk3sto_it_next(glp->i_grp);
+ }
+ }
+ return back;
+}
+
+
+
+
+
+void
+dkwt_tool_close_group_list(dkwt_group_list_t *glp)
+{
+ dkwt_group_t *gp;
+ if(glp) {
+ if(glp->s_grp) {
+ if(glp->i_grp) {
+ dk3sto_it_reset(glp->i_grp);
+ while((gp = (dkwt_group_t *)dk3sto_it_next(glp->i_grp)) != NULL) {
+ dkwt_tool_close_group(gp);
+ }
+ dk3sto_it_close(glp->i_grp);
+ }
+ dk3sto_close(glp->s_grp);
+ } glp->s_grp = NULL; glp->i_grp = NULL;
+ dk3_delete(glp);
+ }
+}
+
+
+
+/** Destroy group, release memory.
+ @param gp Group to destroy.
+*/
+static
+void
+dkwt_tool_group_close(dkwt_group_t *gp)
+{
+ if(gp) {
+ dk3_release(gp->groupname);
+ dk3_release(gp->comment);
+ dk3_release(gp->textsid);
+ gp->attributes = (DWORD)0UL;
+ dk3_delete(gp);
+ }
+}
+
+
+
+/** Create group, allocate memory.
+ @param gn Group name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new group structure on success, NULL on error.
+*/
+static
+dkwt_group_t *
+dkwt_tool_group_open(dkChar const *gn, dk3_app_t *app)
+{
+ dkwt_group_t *back = NULL;
+ if(gn) {
+ back = dk3_new_app(dkwt_group_t,1,app);
+ if(back) {
+ back->comment = NULL;
+ back->textsid = NULL;
+ back->attributes = (DWORD)0UL;
+ back->gtype = DKWT_GROUP_NET;
+ back->groupname = dk3str_dup_app(gn,app);
+ if(!(back->groupname)) {
+ dkwt_tool_group_close(back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Read group list from system.
+ @param gl Group list (destination).
+ @param app Application structure for diagnostics.
+ @param f_long Flag: Detailed (non-zero) or short (0).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkwt_tool_read_group_list(dkwt_group_list_t *gl, dk3_app_t *app, int f_long)
+{
+ int back = 1;
+ NET_API_STATUS nStatus;
+ DWORD dwLevel = 0;
+ DWORD dwPrefmaxlen = MAX_PREFERRED_LENGTH;
+ DWORD dwEntries = 0;
+ DWORD dwTotal = 0;
+ DWORD_PTR dwResumeHandle = 0;
+ DWORD i;
+ LPBYTE pBuf;
+ GROUP_INFO_0 *grptr;
+ GROUP_INFO_3 *gr3ptr;
+ LOCALGROUP_INFO_0 *lgrptr;
+ LOCALGROUP_INFO_1 *lgr1ptr;
+ dkwt_group_t *newgroup;
+ LPTSTR stringsid;
+
+
+#line 613 "dkwt-to.ctr"
+ /*
+ Group information for network groups
+ */
+ do {
+ pBuf = NULL;
+ dwEntries = 0;
+ nStatus = NetGroupEnum(
+ NULL,
+ dwLevel,
+ &pBuf,
+ dwPrefmaxlen,
+ &dwEntries,
+ &dwTotal,
+ &dwResumeHandle
+ );
+ if((ERROR_MORE_DATA == nStatus) || (NERR_Success == nStatus)) {
+ if(pBuf) {
+
+#line 630 "dkwt-to.ctr"
+ grptr = (GROUP_INFO_0 *)pBuf;
+ for(i = 0; i < dwEntries; i++) {
+ if(grptr->grpi0_name) {
+
+#line 633 "dkwt-to.ctr"
+ newgroup = dkwt_tool_group_open(grptr->grpi0_name, app);
+ if(newgroup) {
+ if(!dk3sto_add(gl->s_grp, newgroup)) {
+ back = 0;
+ dkwt_tool_group_close(newgroup);
+ }
+ } else {
+ back = 0;
+ }
+ }
+ grptr++;
+ }
+ }
+ }
+ if(pBuf) {
+ NetApiBufferFree(pBuf); pBuf = NULL;
+ }
+ } while(ERROR_MORE_DATA == nStatus);
+ /*
+ Group information for local groups.
+ */
+ dwLevel = (DWORD)0;
+ dwResumeHandle = 0;
+ do {
+ pBuf = NULL;
+ dwEntries = (DWORD)0UL;
+ nStatus = NetLocalGroupEnum(
+ NULL,
+ dwLevel,
+ &pBuf,
+ dwPrefmaxlen,
+ &dwEntries,
+ &dwTotal,
+ &dwResumeHandle
+ );
+ if((ERROR_MORE_DATA == nStatus) || (NERR_Success == nStatus)) {
+ if(pBuf) {
+ lgrptr = (LOCALGROUP_INFO_0 *)pBuf;
+ for(i = 0; i < dwEntries; i++) {
+ if(lgrptr->lgrpi0_name) {
+ newgroup = dkwt_tool_group_open(lgrptr->lgrpi0_name, app);
+ if(newgroup) {
+ newgroup->gtype = DKWT_GROUP_LOCAL;
+ if(!dk3sto_add(gl->s_grp, newgroup)) {
+ back = 0;
+ dkwt_tool_group_close(newgroup);
+ }
+ } else {
+ back = 0;
+ }
+ }
+ lgrptr ++;
+ }
+ }
+ }
+ if(pBuf) {
+ NetApiBufferFree(pBuf); pBuf = NULL;
+ }
+ } while(ERROR_MORE_DATA == nStatus);
+ if(f_long) {
+ if(back) {
+ dk3sto_it_reset(gl->i_grp);
+ while((newgroup = (dkwt_group_t *)dk3sto_it_next(gl->i_grp)) != NULL) {
+ pBuf = NULL;
+
+#line 697 "dkwt-to.ctr"
+ if(newgroup->gtype == DKWT_GROUP_LOCAL) {
+
+#line 698 "dkwt-to.ctr"
+ dwLevel = 1;
+ pBuf = NULL;
+ nStatus = NetLocalGroupGetInfo(
+ NULL,
+ newgroup->groupname,
+ dwLevel,
+ &pBuf
+ );
+ if(NERR_Success == nStatus) {
+
+#line 707 "dkwt-to.ctr"
+ if(pBuf) {
+ lgr1ptr = (LOCALGROUP_INFO_1 *)pBuf;
+ if(lgr1ptr->lgrpi1_comment) {
+ newgroup->comment = dk3str_dup_app(lgr1ptr->lgrpi1_comment, app);
+ if(!(newgroup->comment)) {
+ back = 0;
+ }
+ }
+ }
+ } else {
+ back = 0;
+ }
+ if(pBuf) {
+ NetApiBufferFree(pBuf); pBuf = NULL;
+ }
+ } else {
+
+#line 723 "dkwt-to.ctr"
+ dwLevel = 3;
+ pBuf = NULL;
+ nStatus = NetGroupGetInfo(
+ NULL,
+ newgroup->groupname,
+ dwLevel,
+ &pBuf
+ );
+ if(NERR_Success == nStatus) {
+
+#line 732 "dkwt-to.ctr"
+ if(pBuf) {
+ gr3ptr = (GROUP_INFO_3 *)pBuf;
+ if(gr3ptr->grpi3_comment) {
+ newgroup->comment = dk3str_dup_app(gr3ptr->grpi3_comment, app);
+ if(!(newgroup->comment)) { back = 0; }
+ }
+ if(gr3ptr->grpi3_group_sid) {
+ stringsid = NULL;
+ if(ConvertSidToStringSid(gr3ptr->grpi3_group_sid, &stringsid)) {
+ if(stringsid) {
+ newgroup->textsid = dk3str_dup_app(stringsid, app);
+ if(!(newgroup->textsid)) { back = 0; }
+ }
+ }
+ if(stringsid) { LocalFree(stringsid); }
+ }
+ newgroup->attributes = gr3ptr->grpi3_attributes;
+ }
+ } else {
+ back = 0;
+ }
+ if(pBuf) {
+ NetApiBufferFree(pBuf); pBuf = NULL;
+ }
+ }
+ }
+ }
+ }
+
+#line 760 "dkwt-to.ctr"
+ return back;
+}
+
+
+
+dkwt_group_list_t *
+dkwt_tool_open_group_list(dk3_app_t *app, int f_long)
+{
+ dkwt_group_list_t *back = NULL;
+ int ok = 0;
+
+
+#line 771 "dkwt-to.ctr"
+ back = dk3_new_app(dkwt_group_list_t,1,app);
+ if(back) {
+ back->i_grp = NULL;
+ back->s_grp = dk3sto_open_app(app);
+ if(back->s_grp) {
+ dk3sto_set_comp(back->s_grp, dkwt_tool_compare_groups, 0);
+ back->i_grp = dk3sto_it_open(back->s_grp);
+ if(back->i_grp) {
+ ok = dkwt_tool_read_group_list(back, app, f_long);
+ }
+ }
+ if(!(ok)) {
+ dkwt_tool_close_group_list(back); back = NULL;
+ }
+ }
+
+#line 786 "dkwt-to.ctr"
+ return back;
+}
+
+
+
+/** Compare printer entries.
+ @param l Left printer.
+ @param r Right printer.
+ @param cr Comparison criteria
+ (1=structure/name, other=structure/structure).
+ @return Comparison result.
+*/
+static
+int
+dkwt_to_compare_printers(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dkwt_printer_t const *pl;
+ dkwt_printer_t const *pr;
+ pl = (dkwt_printer_t *)l; pr = (dkwt_printer_t *)r;
+
+ if(l) {
+ if(r) {
+ switch(cr) {
+ case 1: {
+ if(pl->printerName) {
+ back = dk3str_casecmp(pl->printerName, (dkChar const *)r);
+ } else back = -1;
+ } break;
+ default: {
+ if(pl->printerName) {
+ if(pr->printerName) {
+ back = dk3str_casecmp(pl->printerName, pr->printerName);
+ } else { back = 1; }
+ } else {
+ if(pr->printerName) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ if(back > 1) back = 1;
+ if(back < -1) back = -1;
+ return back;
+}
+
+
+
+/** Delete printer structure, release memory.
+ @param pr Structure to delete.
+*/
+static
+void
+dkwt_tool_printer_delete(dkwt_printer_t *pr)
+{
+ if(pr) {
+ dk3_release(pr->printerName);
+ dk3_release(pr->comment);
+ dk3_release(pr->location);
+ dk3_release(pr->serverName);
+ dk3_release(pr->shareName);
+ dk3_release(pr->portName);
+ dk3_release(pr->driverName);
+ dk3_release(pr->deviceName);
+ dk3_release(pr->separatorFile);
+ dk3_release(pr->printProcessor);
+ dk3_release(pr->dataType);
+ dk3_release(pr->parameters);
+ dk3_release(pr->description);
+ pr->attributes = pr->status = pr->nJobs = (DWORD)0UL;
+ dk3_delete(pr);
+ }
+}
+
+
+
+/** Create printer structure, allocate memory.
+ @param pn Printer name.
+ @param app Application structure for diagnostics.
+ @return Pointer to new structure on success, NULL on error.
+*/
+static
+dkwt_printer_t *
+dkwt_tool_printer_new(dkChar const *pn, dk3_app_t *app)
+{
+ dkwt_printer_t *back = NULL;
+ back = dk3_new_app(dkwt_printer_t,1,app);
+ if(back) {
+ back->description = NULL;
+ back->comment = NULL;
+ back->location = NULL;
+ back->serverName = NULL;
+ back->shareName = NULL;
+ back->portName = NULL;
+ back->driverName = NULL;
+ back->deviceName = NULL;
+ back->separatorFile = NULL;
+ back->printProcessor = NULL;
+ back->dataType = NULL;
+ back->parameters = NULL;
+ back->attributes = back->status = back->nJobs = (DWORD)0UL;
+ back->printerName = dk3str_dup_app(pn, app);
+ if(!(back->printerName)) {
+ dkwt_tool_printer_delete(back); back = NULL;
+ }
+ }
+ return back;
+}
+
+
+
+void
+dkwt_tool_close_printer_list(dkwt_printer_list_t *pl)
+{
+ dkwt_printer_t *pr;
+
+ if(pl) {
+ if(pl->s_prn) {
+ if(pl->i_prn) {
+ dk3sto_it_reset(pl->i_prn);
+ while((pr = (dkwt_printer_t *)dk3sto_it_next(pl->i_prn)) != NULL) {
+ dkwt_tool_printer_delete(pr);
+ }
+ dk3sto_it_close(pl->i_prn);
+ } pl->i_prn = NULL;
+ dk3sto_close(pl->s_prn);
+ } pl->s_prn = NULL;
+ dk3_delete(pl);
+ }
+}
+
+
+
+/** Read printer list from system.
+ @param pl Printer list (destination).
+ @param app Application structure for diagnostics.
+ @param f_long Flag: Detailed (non-zero) or short (0).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkwt_tool_read_printer_list(
+ dkwt_printer_list_t *pl,
+ dk3_app_t *app,
+ int f_long
+)
+{
+ int back = 0;
+ char *peb = NULL;
+ DWORD szpeb;
+ DWORD cbNeeded;
+ DWORD cbReturned;
+ DWORD i;
+ PRINTER_INFO_2 *pi2;
+ dkwt_printer_t *pr;
+ cbNeeded = (DWORD)0UL;
+ cbReturned = (DWORD)0UL;
+
+
+#line 946 "dkwt-to.ctr"
+ EnumPrinters(
+ PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &cbNeeded, &cbReturned
+ );
+ if(cbNeeded > 0) {
+ peb = dk3_new_app(char,(size_t)cbNeeded,app);
+ if(peb) {
+ szpeb = cbNeeded;
+ cbNeeded = (DWORD)0UL;
+ cbReturned = (DWORD)0UL;
+ if(EnumPrinters(
+ PRINTER_ENUM_LOCAL, NULL, 2, (LPBYTE)peb, szpeb, &cbNeeded, &cbReturned
+ )
+ )
+ {
+ if(cbReturned > (DWORD)0UL) {
+ pi2 = (PRINTER_INFO_2 *)peb;
+ back = 1;
+ for(i = 0; i < cbReturned; i++) {
+ if(pi2->pPrinterName) {
+
+#line 965 "dkwt-to.ctr"
+ pr = dkwt_tool_printer_new(pi2->pPrinterName, app);
+ if(pr) {
+
+#line 967 "dkwt-to.ctr"
+ if(dk3sto_add(pl->s_prn, (void *)pr)) {
+
+#line 968 "dkwt-to.ctr"
+ if(f_long) {
+
+#line 969 "dkwt-to.ctr"
+ dkwt_tool_save_text(
+ &(pr->comment),
+ pi2->pComment,
+ app,
+ &back
+ );
+ dkwt_tool_save_text(
+ &(pr->location),
+ pi2->pLocation,
+ app,
+ &back
+ );
+ dkwt_tool_save_text(
+ &(pr->serverName),
+ pi2->pServerName,
+ app,
+ &back
+ );
+ dkwt_tool_save_text(
+ &(pr->shareName),
+ pi2->pShareName,
+ app,
+ &back
+ );
+ dkwt_tool_save_text(
+ &(pr->portName),
+ pi2->pPortName,
+ app,
+ &back
+ );
+ dkwt_tool_save_text(
+ &(pr->driverName),
+ pi2->pDriverName,
+ app,
+ &back
+ );
+#if 0
+ dkwt_tool_save_text(
+ &(pr->deviceName),
+ pi2->pDeviceName,
+ app,
+ &back
+ );
+#endif
+ dkwt_tool_save_text(
+ &(pr->separatorFile),
+ pi2->pSepFile,
+ app,
+ &back
+ );
+ dkwt_tool_save_text(
+ &(pr->printProcessor),
+ pi2->pPrintProcessor,
+ app,
+ &back
+ );
+ dkwt_tool_save_text(
+ &(pr->dataType),
+ pi2->pDatatype,
+ app,
+ &back
+ );
+ dkwt_tool_save_text(
+ &(pr->parameters),
+ pi2->pParameters,
+ app,
+ &back
+ );
+ pr->attributes = pi2->Attributes;
+ pr->status = pi2->Status;
+ pr->nJobs = pi2->cJobs;
+ } else {
+
+#line 1041 "dkwt-to.ctr"
+ }
+ } else {
+ dkwt_tool_printer_delete(pr);
+ back = 0;
+ }
+ } else {
+ back = 0;
+ }
+ }
+ pi2++;
+ }
+ }
+ }
+ dk3_delete(peb);
+ }
+ } else {
+ /* ERROR: Failed to obtain byte number. */
+ dk3app_log_i1(app, DK3_LL_ERROR, 244);
+ }
+
+#line 1060 "dkwt-to.ctr"
+ return back;
+}
+
+
+
+dkwt_printer_list_t *
+dkwt_tool_open_printer_list(dk3_app_t *app, int f_long)
+{
+ dkwt_printer_list_t *back = NULL;
+ back = dk3_new_app(dkwt_printer_list_t,1,app);
+ if(back) {
+ back->i_prn = NULL;
+ back->s_prn = dk3sto_open_app(app);
+ if(back->s_prn) {
+ dk3sto_set_comp(back->s_prn, dkwt_to_compare_printers, 0);
+ back->i_prn = dk3sto_it_open(back->s_prn);
+ }
+ if((back->s_prn) && (back->i_prn)) {
+ if(!dkwt_tool_read_printer_list(back, app, f_long)) {
+ dkwt_tool_close_printer_list(back); back = NULL;
+ }
+ } else {
+ dkwt_tool_close_printer_list(back); back = NULL;
+ }
+ }
+ return back;
+}
+
+
+void
+dkwt_tool_printer_list_reset(dkwt_printer_list_t *pl)
+{
+ if(pl) {
+ if(pl->i_prn) {
+ dk3sto_it_reset(pl->i_prn);
+ }
+ }
+}
+
+
+
+dkwt_printer_t *
+dkwt_tool_printer_list_next(dkwt_printer_list_t *pl)
+{
+ dkwt_printer_t *back = NULL;
+ if(pl) {
+ if(pl->i_prn) {
+ back = (dkwt_printer_t *)dk3sto_it_next(pl->i_prn);
+ }
+ }
+ return back;
+}
+
+
+
+long
+dkwt_tool_reg_open_key(
+ HKEY key,
+ dkChar const *skn,
+ REGSAM sam,
+ PHKEY phk
+)
+{
+ long res;
+ DWORD dw0;
+
+ dw0 = (DWORD)0;
+#if DK3_CHAR_SIZE > 1
+ res = RegOpenKeyExW(key, skn, dw0, sam, phk);
+#else
+ res = RegOpenKeyExA(key, skn, dw0, sam, phk);
+#endif
+ return res;
+}
+
+
+
+long
+dkwt_tool_reg_query_value(
+ HKEY hk,
+ dkChar const *vn,
+ DWORD *pDwTp,
+ void *buf,
+ DWORD *pDwSz
+)
+{
+ long res;
+#if DK3_CHAR_SIZE > 1
+ res = RegQueryValueExW(
+ hk, vn, NULL, pDwTp, (LPBYTE)buf, pDwSz
+ );
+#else
+ res = RegQueryValueExA(
+ hk, vn, NULL, pDwTp, (LPBYTE)buf, pDwSz
+ );
+#endif
+ return res;
+}
+
+
+
+long
+dkwt_tool_reg_delete_value(
+ HKEY hk,
+ dkChar const *en
+)
+{
+ long res;
+#if DK3_CHAR_SIZE > 1
+ res = RegDeleteValueW(hk, en);
+#else
+ res = RegDeleteValueA(hk, en);
+#endif
+ return res;
+}
+
+
+
+long
+dkwt_tool_reg_delete_tree(
+ HKEY hk,
+ dkChar const *tn
+)
+{
+ long res = ERROR_NOT_SUPPORTED;
+#if _MSC_VER >= 1700 && (!(DK4_WINDOWS_LEGACY))
+#if DK3_CHAR_SIZE > 1
+ res = RegDeleteTreeW(hk, tn);
+#else
+ res = RegDeleteTreeA(hk, tn);
+#endif
+#endif
+ return res;
+}
+
+
+long
+dkwt_tool_reg_enum_key(
+ HKEY hk,
+ DWORD dwIndex,
+ dkChar *pResult,
+ DWORD *pDwSzResult,
+ dkChar *pClass,
+ DWORD *pDwSzClass,
+ PFILETIME pLastWrite
+)
+{
+ long res;
+
+
+#line 1209 "dkwt-to.ctr"
+#if DK3_CHAR_SIZE > 1
+ res = RegEnumKeyExW(
+ hk, dwIndex, pResult, pDwSzResult,
+ NULL, pClass, pDwSzClass, pLastWrite
+ );
+#else
+ res = RegEnumKeyExA(
+ hk, dwIndex, pResult, pDwSzResult,
+ NULL, pClass, pDwSzClass, pLastWrite
+ );
+#endif
+
+
+#line 1221 "dkwt-to.ctr"
+ return res;
+}
+
+
+
+long
+dkwt_tool_reg_create_key(
+ HKEY hk,
+ dkChar const *kn,
+ DWORD dwOptions,
+ REGSAM sam,
+ PHKEY pHkeyResult,
+ LPDWORD lpDwDisposition
+)
+{
+ long res;
+ DWORD dw0;
+
+ dw0 = 0;
+#if DK3_CHAR_SIZE > 1
+ res = RegCreateKeyExW(
+ hk, kn, dw0, NULL, dwOptions, sam,
+ NULL, pHkeyResult, lpDwDisposition
+ );
+#else
+ res = RegCreateKeyExA(
+ hk, kn, dw0, NULL, dwOptions, sam,
+ NULL, pHkeyResult, lpDwDisposition
+ );
+#endif
+ return res;
+}
+
+
+long
+dkwt_ev_reg_set_value(
+ HKEY hk,
+ dkChar const *vn,
+ DWORD dwType,
+ void *pData,
+ DWORD szData
+)
+{
+ long res;
+ DWORD dw0;
+
+ dw0 = 0;
+#if DK3_CHAR_SIZE > 1
+ res = RegSetValueExW(
+ hk, vn, dw0, dwType, (BYTE const *)pData, szData
+ );
+#else
+ res = RegSetValueExA(
+ hk, vn, dw0, dwType, (BYTE const *)pData, szData
+ );
+#endif
+ return res;
+}
+
+
+
+
+int
+dkwt_is_admin(void)
+{
+ PSID pAdmGroup = NULL;
+ SID_IDENTIFIER_AUTHORITY ntAuthority = SECURITY_NT_AUTHORITY;
+ BOOL bres = FALSE;
+ BOOL isadm = FALSE;
+ int back = 0;
+ back = -1;
+ bres = AllocateAndInitializeSid(
+ &ntAuthority, 2,
+ SECURITY_BUILTIN_DOMAIN_RID, /* sub-authority 0 */
+ DOMAIN_ALIAS_RID_ADMINS, /* sub-authority 1 */
+ (DWORD)0, /* sub-authority 2 */
+ (DWORD)0, /* sub-authority 3 */
+ (DWORD)0, /* sub-authority 4 */
+ (DWORD)0, /* sub-authority 5 */
+ (DWORD)0, /* sub-authority 6 */
+ (DWORD)0, /* sub-authority 7 */
+ &pAdmGroup
+ );
+ if (bres) {
+ if (CheckTokenMembership(NULL, pAdmGroup, &isadm)) {
+ if (isadm) {
+ back = 1;
+ } else {
+ back = 0;
+ }
+ }
+ }
+ if (NULL != pAdmGroup) {
+ FreeSid(pAdmGroup);
+ }
+ return back;
+}
diff --git a/support/dktools/dkwt-to.ctr b/support/dktools/dkwt-to.ctr
new file mode 100644
index 0000000000..7b79b5c271
--- /dev/null
+++ b/support/dktools/dkwt-to.ctr
@@ -0,0 +1,1317 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% module
+
+
+#include "dk3all.h"
+#include "dkt.h"
+#include "dkwt.h"
+
+
+
+$!trace-include
+
+
+
+/** Compare 2 accounts.
+ @param l Left account pointer.
+ @param r Right account pointer.
+ @param cr Comparison criteria (0=account/account, 1=account/name).
+ @return Comparison result.
+*/
+static
+int
+dkwt_tool_compare_accounts(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dkwt_account_t const *pl;
+ dkwt_account_t const *pr;
+ pl = (dkwt_account_t const *)l; pr = (dkwt_account_t const *)r;
+ if(l) {
+ if(r) {
+ switch(cr) {
+ case 1: {
+ if(pl->logname) {
+ back = dk3str_casecmp(pl->logname, (dkChar const *)r);
+ } else {
+ back = -1;
+ }
+ } break;
+ default: {
+ if(pl->logname) {
+ if(pr->logname) {
+ back = dk3str_casecmp(pl->logname, pr->logname);
+ } else {
+ back = 1;
+ }
+ } else {
+ if(pr->logname) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+ if(back > 1) back = 1;
+ if(back < -1) back = -1;
+ return back;
+}
+
+
+
+/** Compare two group entries.
+ @param l Left entry.
+ @param r Right entry.
+ @param cr Comparison criteria
+ (1=structure/name, other=sructure/structure).
+ @return Comparison result.
+*/
+static
+int
+dkwt_tool_compare_groups(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dkwt_group_t const *pl;
+ dkwt_group_t const *pr;
+
+ pl = (dkwt_group_t const *)l; pr = (dkwt_group_t const *)r;
+ if(l) {
+ if(r) {
+ switch(cr) {
+ case 1: {
+ if(pl->groupname) {
+ back = dk3str_casecmp(pl->groupname, (dkChar const *)r);
+ } else { back = -1; }
+ } break;
+ default: {
+ if(pl->groupname) {
+ if(pr->groupname) {
+ back = dk3str_casecmp(pl->groupname, pr->groupname);
+ } else { back = 1; }
+ } else {
+ if(pr->groupname) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+/** Change a dynamically allocated text.
+ @param destination Pointer to string pointer.
+ @param source Source text.
+ @param app Application structure for diagnostics.
+ @param returnValue Pointer to result variable.
+*/
+static
+void
+dkwt_tool_save_text(
+ dkChar const **destination,
+ dkChar const *source,
+ dk3_app_t *app,
+ int *returnValue
+)
+{
+ dkChar *np;
+ $? "+ dkwt_tool_save_text"
+ if(source) { $? ". source ok"
+ if(dk3str_len(source) > 0) { $? ". length ok"
+ np = dk3str_dup_app(source, app);
+ if(np) { $? ". dup ok"
+ if(*destination) {
+ dk3_delete(*destination);
+ }
+ *destination = np; $? ". result saved"
+ } else {
+ if(returnValue) {
+ *returnValue = 0;
+ }
+ }
+ }
+ } $? "- dkwt_tool_save_text"
+}
+
+
+
+
+void
+dkwt_tool_close_account(dkwt_account_t *ap)
+{
+ if(ap) {
+ dk3_release(ap->textsid);
+ dk3_release(ap->profile);
+ dk3_release(ap->homedir);
+ dk3_release(ap->usrcomment);
+ dk3_release(ap->comment);
+ dk3_release(ap->fullname);
+ dk3_release(ap->logname);
+ dk3_delete(ap);
+ }
+}
+
+
+
+dkwt_account_t *
+dkwt_tool_open_account(dkChar const *logname, dk3_app_t *app)
+{
+ dkwt_account_t *back = NULL;
+ if(logname) {
+ back = dk3_new_app(dkwt_account_t,1,app);
+ if(back) {
+ back->logname = NULL; back->fullname = NULL;
+ back->comment = NULL; back->textsid = NULL;
+ back->usrcomment = NULL; back->homedir = NULL;
+ back->profile = NULL; back->f_long = 0;
+ back->logname = dk3str_dup_app(logname, app);
+ back->priv = (DWORD)0UL;
+ back->flags = (DWORD)0UL;
+ back->a_flags = (DWORD)0UL;
+ back->coco = (DWORD)0UL;
+ back->codepage = (DWORD)0UL;
+ if(!(back->logname)) {
+ dkwt_tool_close_account(back); back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void
+dkwt_tool_close_account_list(dkwt_account_list_t *lp)
+{
+ dkwt_account_t *ap;
+ if(lp) {
+ if(lp->s_acc) {
+ if(lp->i_acc) {
+ dk3sto_it_reset(lp->i_acc);
+ while((ap = (dkwt_account_t *)dk3sto_it_next(lp->i_acc)) != NULL) {
+ dkwt_tool_close_account(ap);
+ }
+ dk3sto_it_close(lp->i_acc);
+ }
+ dk3sto_close(lp->s_acc);
+ }
+ lp->s_acc = NULL;
+ lp->i_acc = NULL;
+ dk3_delete(lp);
+ }
+}
+
+
+
+dkwt_account_list_t *
+dkwt_tool_open_account_list(dk3_app_t *app, int f_long)
+{
+ dkwt_account_list_t *back = NULL;
+ dkwt_account_t *ap = NULL;
+ int ok = 0;
+ NET_API_STATUS nStatus;
+ LPUSER_INFO_0 pBuf = NULL;
+ LPUSER_INFO_0 pTmpBuf = NULL;
+ LPUSER_INFO_4 pb4 = NULL;
+ DWORD dwLevel = 0;
+ DWORD dwEntriesRead = 0;
+ DWORD dwTotalEntries = 0;
+ DWORD dwResumeHandle = 0;
+ DWORD dwPreferredLength = MAX_PREFERRED_LENGTH;
+ DWORD dwFilter = 0; /* FILTER_NORMAL_ACCOUNT */
+ DWORD i = 0;
+ LPTSTR pStringSid;
+ $? "+ dkwt_tool_open_account_list"
+ back = dk3_new_app(dkwt_account_list_t,1,app);
+ if(back) { $? ". back ok"
+ back->s_acc = NULL; back->i_acc = NULL;
+ back->s_acc = dk3sto_open_app(app);
+ if(back->s_acc) { $? ". storage ok"
+ dk3sto_set_comp(back->s_acc, dkwt_tool_compare_accounts, 0);
+ back->i_acc = dk3sto_it_open(back->s_acc);
+ if(back->i_acc) { $? ". iterator ok"
+ ok = 1;
+ do {
+ pBuf = NULL;
+ dwEntriesRead = 0;
+ nStatus = NetUserEnum(
+ NULL, /* Local machine */
+ dwLevel, /* Level 0 */
+ dwFilter, /* Normal users */
+ (LPBYTE *)(&pBuf), /* Destination */
+ dwPreferredLength, /* Preferred length */
+ &dwEntriesRead,
+ &dwTotalEntries,
+ &dwResumeHandle
+ ); $? ". NetUserEnum returned %u", nStatus
+ if((NERR_Success == nStatus) || (ERROR_MORE_DATA == nStatus)) {
+ $? ". status ok"
+ if(pBuf != NULL) { $? ". buffer ok"
+ pTmpBuf = pBuf;
+ for(i = 0; i < dwEntriesRead; i++) {
+ $? ". entry %u / %u", (unsigned)i, (unsigned)dwEntriesRead
+ if(pTmpBuf->usri0_name) { $? ". name ok"
+ ap = dkwt_tool_open_account(pTmpBuf->usri0_name, app);
+ if(ap) { $? ". open account ok"
+ if(!dk3sto_add(back->s_acc, (void *)ap)) {
+ ok = 0;
+ dkwt_tool_close_account(ap);
+ }
+ } else { $? "! failed to open account"
+ ok = 0;
+ }
+ } else { $? "! entry without a name"
+ }
+ pTmpBuf++;
+ }
+ } else { $? "! no data buffer"
+ }
+ } else { $? "! nStatus indicates error"
+ }
+ if(pBuf != NULL) {
+ NetApiBufferFree(pBuf);
+ pBuf = NULL;
+ }
+ } while(ERROR_MORE_DATA == nStatus);
+ if(pBuf != NULL) {
+ NetApiBufferFree(pBuf);
+ }
+ if(ok) {
+ if(f_long) {
+ dk3sto_it_reset(back->i_acc);
+ while((ap = (dkwt_account_t *)dk3sto_it_next(back->i_acc)) != NULL) {
+ pb4 = NULL;
+ nStatus = NetUserGetInfo(NULL, ap->logname, (DWORD)4, (LPBYTE *)(&pb4));
+ if(NERR_Success == nStatus)
+ {
+ if(pb4) { $? ". NetUserGetInfo() ok"
+ ap->f_long = 1;
+ ap->priv = pb4->usri4_priv;
+ ap->flags = pb4->usri4_flags;
+ ap->a_flags = pb4->usri4_auth_flags;
+ ap->coco = pb4->usri4_country_code;
+ ap->codepage = pb4->usri4_code_page;
+ if(pb4->usri4_full_name) { $? ". full name ok"
+ ap->fullname = dk3str_dup_app(pb4->usri4_full_name, app);
+ if(!(ap->fullname)) {
+ ok = 0;
+ }
+ }
+ if(pb4->usri4_comment) { $? ". comment ok"
+ ap->comment = dk3str_dup_app(pb4->usri4_comment, app);
+ if(!(ap->comment)) {
+ ok = 0;
+ }
+ }
+ if(pb4->usri4_usr_comment) {
+ ap->usrcomment = dk3str_dup_app(pb4->usri4_usr_comment, app);
+ if(!(ap->usrcomment)) {
+ ok = 0;
+ }
+ }
+ if(pb4->usri4_home_dir) {
+ ap->homedir = dk3str_dup_app(pb4->usri4_home_dir, app);
+ if(!(ap->homedir)) {
+ ok = 0;
+ }
+ }
+ if(pb4->usri4_profile) {
+ ap->profile = dk3str_dup_app(pb4->usri4_profile, app);
+ if(!(ap->profile)) {
+ ok = 0;
+ }
+ }
+ if(pb4->usri4_user_sid) { $? ". sid ok"
+ pStringSid = NULL;
+ if(ConvertSidToStringSid(pb4->usri4_user_sid, &pStringSid))
+ {
+ if(pStringSid) {
+ ap->textsid = dk3str_dup_app(pStringSid, app);
+ if(!(ap->textsid)) {
+ ok = 0;
+ }
+ }
+ }
+ if(pStringSid) { LocalFree(pStringSid); }
+
+ }
+ } else { $? "! no result from NetUserGetInfo()"
+ }
+ } else { $? "! NetUserGetInfo() failed %u", (unsigned)nStatus
+ }
+ if(pb4) {
+ NetApiBufferFree(pb4);
+ }
+ }
+ }
+ }
+ } else { $? "! allocation failed for iterator"
+ }
+ } else { $? "! allocation failed for storage"
+ }
+ if(!ok) {
+ dkwt_tool_close_account_list(back); back = NULL;
+ }
+ } else { $? "! allocation failed"
+ } $? "- dkwt_tool_open_account_list PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+void
+dkwt_tool_reset_account_list(dkwt_account_list_t *lp)
+{
+ if(lp) {
+ if(lp->i_acc) {
+ dk3sto_it_reset(lp->i_acc);
+ }
+ }
+}
+
+
+
+dkwt_account_t *
+dkwt_tool_get_account_from_list(dkwt_account_list_t *lp)
+{
+ dkwt_account_t *back = NULL;
+ if(lp) {
+ if(lp->i_acc) {
+ back = (dkwt_account_t *)dk3sto_it_next(lp->i_acc);
+ }
+ }
+ return back;
+}
+
+
+
+/** Compare two group entries.
+ @param l Left entry.
+ @param r Right entry.
+ @param cr Comparison criteria (0=data/data, 1=data/name).
+ @return Comparison result.
+*/
+static
+int
+dkwt_group_compare(void *l, void *r, int cr)
+{
+ int back = 0;
+ dkwt_group_t *pl;
+ dkwt_group_t *pr;
+
+ pl = (dkwt_group_t *)l; pr = (dkwt_group_t *)r;
+ if(l) {
+ if(r) {
+ switch(cr) {
+ case 1: {
+ if(pl->groupname) {
+ back = dk3str_casecmp(pl->groupname, (dkChar const *)r);
+ } else {
+ back = -1;
+ }
+ } break;
+ default: {
+ if(pl->groupname) {
+ if(pr->groupname) {
+ back = dk3str_casecmp(pl->groupname, pr->groupname);
+ } else back = 1;
+ } else {
+ if(pr->groupname) back = -1;
+ }
+ } break;
+ }
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ }
+ return back;
+}
+
+
+
+
+/** Close group structure, release memory.
+ @param gp Group structure to close.
+*/
+static
+void
+dkwt_tool_close_group(dkwt_group_t *gp)
+{
+ if(gp) {
+ dk3_release(gp->groupname);
+ dk3_release(gp->comment);
+ dk3_release(gp->textsid);
+ gp->attributes = (DWORD)0UL;
+ dk3_delete(gp);
+ }
+}
+
+
+
+/** Open new group structure, allocate memory.
+ @param gn Group name.
+ @param app Application structure for diagnostics.
+ @return Pointer on success, NULL on error.
+*/
+static
+dkwt_group_t *
+dkwt_tool_open_group(dkChar const *gn, dk3_app_t *app)
+{
+ dkwt_group_t *back = NULL;
+ back = dk3_new_app(dkwt_group_t,1,app);
+ if(back) {
+ back->comment = NULL;
+ back->textsid = NULL;
+ back->attributes = (DWORD)0UL;
+ back->groupname = dk3str_dup_app(gn, app);
+ if(!(back->groupname)) {
+ dkwt_tool_close_group(back); back = NULL;
+ }
+ }
+ return back;
+}
+
+
+void
+dkwt_tool_reset_group_list(dkwt_group_list_t *glp)
+{
+ if(glp) {
+ if(glp->i_grp) {
+ dk3sto_it_reset(glp->i_grp);
+ }
+ }
+}
+
+
+
+dkwt_group_t *
+dkwt_tool_get_group_from_list(dkwt_group_list_t *glp)
+{
+ dkwt_group_t *back = NULL;
+ if(glp) {
+ if(glp->i_grp) {
+ back = (dkwt_group_t *)dk3sto_it_next(glp->i_grp);
+ }
+ }
+ return back;
+}
+
+
+
+
+
+void
+dkwt_tool_close_group_list(dkwt_group_list_t *glp)
+{
+ dkwt_group_t *gp;
+ if(glp) {
+ if(glp->s_grp) {
+ if(glp->i_grp) {
+ dk3sto_it_reset(glp->i_grp);
+ while((gp = (dkwt_group_t *)dk3sto_it_next(glp->i_grp)) != NULL) {
+ dkwt_tool_close_group(gp);
+ }
+ dk3sto_it_close(glp->i_grp);
+ }
+ dk3sto_close(glp->s_grp);
+ } glp->s_grp = NULL; glp->i_grp = NULL;
+ dk3_delete(glp);
+ }
+}
+
+
+
+/** Destroy group, release memory.
+ @param gp Group to destroy.
+*/
+static
+void
+dkwt_tool_group_close(dkwt_group_t *gp)
+{
+ if(gp) {
+ dk3_release(gp->groupname);
+ dk3_release(gp->comment);
+ dk3_release(gp->textsid);
+ gp->attributes = (DWORD)0UL;
+ dk3_delete(gp);
+ }
+}
+
+
+
+/** Create group, allocate memory.
+ @param gn Group name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new group structure on success, NULL on error.
+*/
+static
+dkwt_group_t *
+dkwt_tool_group_open(dkChar const *gn, dk3_app_t *app)
+{
+ dkwt_group_t *back = NULL;
+ if(gn) {
+ back = dk3_new_app(dkwt_group_t,1,app);
+ if(back) {
+ back->comment = NULL;
+ back->textsid = NULL;
+ back->attributes = (DWORD)0UL;
+ back->gtype = DKWT_GROUP_NET;
+ back->groupname = dk3str_dup_app(gn,app);
+ if(!(back->groupname)) {
+ dkwt_tool_group_close(back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Read group list from system.
+ @param gl Group list (destination).
+ @param app Application structure for diagnostics.
+ @param f_long Flag: Detailed (non-zero) or short (0).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkwt_tool_read_group_list(dkwt_group_list_t *gl, dk3_app_t *app, int f_long)
+{
+ int back = 1;
+ NET_API_STATUS nStatus;
+ DWORD dwLevel = 0;
+ DWORD dwPrefmaxlen = MAX_PREFERRED_LENGTH;
+ DWORD dwEntries = 0;
+ DWORD dwTotal = 0;
+ DWORD_PTR dwResumeHandle = 0;
+ DWORD i;
+ LPBYTE pBuf;
+ GROUP_INFO_0 *grptr;
+ GROUP_INFO_3 *gr3ptr;
+ LOCALGROUP_INFO_0 *lgrptr;
+ LOCALGROUP_INFO_1 *lgr1ptr;
+ dkwt_group_t *newgroup;
+ LPTSTR stringsid;
+ $? "+ dkwt_tool_read_group_list"
+ /*
+ Group information for network groups
+ */
+ do {
+ pBuf = NULL;
+ dwEntries = 0;
+ nStatus = NetGroupEnum(
+ NULL,
+ dwLevel,
+ &pBuf,
+ dwPrefmaxlen,
+ &dwEntries,
+ &dwTotal,
+ &dwResumeHandle
+ );
+ if((ERROR_MORE_DATA == nStatus) || (NERR_Success == nStatus)) {
+ if(pBuf) { $? ". found"
+ grptr = (GROUP_INFO_0 *)pBuf;
+ for(i = 0; i < dwEntries; i++) {
+ if(grptr->grpi0_name) { $? ". yet another group \"%ls\"", grptr->grpi0_name
+ newgroup = dkwt_tool_group_open(grptr->grpi0_name, app);
+ if(newgroup) {
+ if(!dk3sto_add(gl->s_grp, newgroup)) {
+ back = 0;
+ dkwt_tool_group_close(newgroup);
+ }
+ } else {
+ back = 0;
+ }
+ }
+ grptr++;
+ }
+ }
+ }
+ if(pBuf) {
+ NetApiBufferFree(pBuf); pBuf = NULL;
+ }
+ } while(ERROR_MORE_DATA == nStatus);
+ /*
+ Group information for local groups.
+ */
+ dwLevel = (DWORD)0;
+ dwResumeHandle = 0;
+ do {
+ pBuf = NULL;
+ dwEntries = (DWORD)0UL;
+ nStatus = NetLocalGroupEnum(
+ NULL,
+ dwLevel,
+ &pBuf,
+ dwPrefmaxlen,
+ &dwEntries,
+ &dwTotal,
+ &dwResumeHandle
+ );
+ if((ERROR_MORE_DATA == nStatus) || (NERR_Success == nStatus)) {
+ if(pBuf) {
+ lgrptr = (LOCALGROUP_INFO_0 *)pBuf;
+ for(i = 0; i < dwEntries; i++) {
+ if(lgrptr->lgrpi0_name) {
+ newgroup = dkwt_tool_group_open(lgrptr->lgrpi0_name, app);
+ if(newgroup) {
+ newgroup->gtype = DKWT_GROUP_LOCAL;
+ if(!dk3sto_add(gl->s_grp, newgroup)) {
+ back = 0;
+ dkwt_tool_group_close(newgroup);
+ }
+ } else {
+ back = 0;
+ }
+ }
+ lgrptr ++;
+ }
+ }
+ }
+ if(pBuf) {
+ NetApiBufferFree(pBuf); pBuf = NULL;
+ }
+ } while(ERROR_MORE_DATA == nStatus);
+ if(f_long) {
+ if(back) {
+ dk3sto_it_reset(gl->i_grp);
+ while((newgroup = (dkwt_group_t *)dk3sto_it_next(gl->i_grp)) != NULL) {
+ pBuf = NULL; $? ". Retrieve \"%ls\"", TR_LSTR(newgroup->groupname)
+ if(newgroup->gtype == DKWT_GROUP_LOCAL) { $? ". local group"
+ dwLevel = 1;
+ pBuf = NULL;
+ nStatus = NetLocalGroupGetInfo(
+ NULL,
+ newgroup->groupname,
+ dwLevel,
+ &pBuf
+ );
+ if(NERR_Success == nStatus) { $? ". success 1"
+ if(pBuf) {
+ lgr1ptr = (LOCALGROUP_INFO_1 *)pBuf;
+ if(lgr1ptr->lgrpi1_comment) {
+ newgroup->comment = dk3str_dup_app(lgr1ptr->lgrpi1_comment, app);
+ if(!(newgroup->comment)) {
+ back = 0;
+ }
+ }
+ }
+ } else {
+ back = 0;
+ }
+ if(pBuf) {
+ NetApiBufferFree(pBuf); pBuf = NULL;
+ }
+ } else { $? ". network group"
+ dwLevel = 3;
+ pBuf = NULL;
+ nStatus = NetGroupGetInfo(
+ NULL,
+ newgroup->groupname,
+ dwLevel,
+ &pBuf
+ );
+ if(NERR_Success == nStatus) { $? ". success 3"
+ if(pBuf) {
+ gr3ptr = (GROUP_INFO_3 *)pBuf;
+ if(gr3ptr->grpi3_comment) {
+ newgroup->comment = dk3str_dup_app(gr3ptr->grpi3_comment, app);
+ if(!(newgroup->comment)) { back = 0; }
+ }
+ if(gr3ptr->grpi3_group_sid) {
+ stringsid = NULL;
+ if(ConvertSidToStringSid(gr3ptr->grpi3_group_sid, &stringsid)) {
+ if(stringsid) {
+ newgroup->textsid = dk3str_dup_app(stringsid, app);
+ if(!(newgroup->textsid)) { back = 0; }
+ }
+ }
+ if(stringsid) { LocalFree(stringsid); }
+ }
+ newgroup->attributes = gr3ptr->grpi3_attributes;
+ }
+ } else {
+ back = 0;
+ }
+ if(pBuf) {
+ NetApiBufferFree(pBuf); pBuf = NULL;
+ }
+ }
+ }
+ }
+ } $? "- dkwt_tool_read_group_list %d", back
+ return back;
+}
+
+
+
+dkwt_group_list_t *
+dkwt_tool_open_group_list(dk3_app_t *app, int f_long)
+{
+ dkwt_group_list_t *back = NULL;
+ int ok = 0;
+ $? "+ dkwt_tool_open_group_list"
+ back = dk3_new_app(dkwt_group_list_t,1,app);
+ if(back) {
+ back->i_grp = NULL;
+ back->s_grp = dk3sto_open_app(app);
+ if(back->s_grp) {
+ dk3sto_set_comp(back->s_grp, dkwt_tool_compare_groups, 0);
+ back->i_grp = dk3sto_it_open(back->s_grp);
+ if(back->i_grp) {
+ ok = dkwt_tool_read_group_list(back, app, f_long);
+ }
+ }
+ if(!(ok)) {
+ dkwt_tool_close_group_list(back); back = NULL;
+ }
+ } $? "- dkwt_tool_open_group_list %d", ((back) ? 1 : 0)
+ return back;
+}
+
+
+
+/** Compare printer entries.
+ @param l Left printer.
+ @param r Right printer.
+ @param cr Comparison criteria
+ (1=structure/name, other=structure/structure).
+ @return Comparison result.
+*/
+static
+int
+dkwt_to_compare_printers(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ dkwt_printer_t const *pl;
+ dkwt_printer_t const *pr;
+ pl = (dkwt_printer_t *)l; pr = (dkwt_printer_t *)r;
+
+ if(l) {
+ if(r) {
+ switch(cr) {
+ case 1: {
+ if(pl->printerName) {
+ back = dk3str_casecmp(pl->printerName, (dkChar const *)r);
+ } else back = -1;
+ } break;
+ default: {
+ if(pl->printerName) {
+ if(pr->printerName) {
+ back = dk3str_casecmp(pl->printerName, pr->printerName);
+ } else { back = 1; }
+ } else {
+ if(pr->printerName) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ if(back > 1) back = 1;
+ if(back < -1) back = -1;
+ return back;
+}
+
+
+
+/** Delete printer structure, release memory.
+ @param pr Structure to delete.
+*/
+static
+void
+dkwt_tool_printer_delete(dkwt_printer_t *pr)
+{
+ if(pr) {
+ dk3_release(pr->printerName);
+ dk3_release(pr->comment);
+ dk3_release(pr->location);
+ dk3_release(pr->serverName);
+ dk3_release(pr->shareName);
+ dk3_release(pr->portName);
+ dk3_release(pr->driverName);
+ dk3_release(pr->deviceName);
+ dk3_release(pr->separatorFile);
+ dk3_release(pr->printProcessor);
+ dk3_release(pr->dataType);
+ dk3_release(pr->parameters);
+ dk3_release(pr->description);
+ pr->attributes = pr->status = pr->nJobs = (DWORD)0UL;
+ dk3_delete(pr);
+ }
+}
+
+
+
+/** Create printer structure, allocate memory.
+ @param pn Printer name.
+ @param app Application structure for diagnostics.
+ @return Pointer to new structure on success, NULL on error.
+*/
+static
+dkwt_printer_t *
+dkwt_tool_printer_new(dkChar const *pn, dk3_app_t *app)
+{
+ dkwt_printer_t *back = NULL;
+ back = dk3_new_app(dkwt_printer_t,1,app);
+ if(back) {
+ back->description = NULL;
+ back->comment = NULL;
+ back->location = NULL;
+ back->serverName = NULL;
+ back->shareName = NULL;
+ back->portName = NULL;
+ back->driverName = NULL;
+ back->deviceName = NULL;
+ back->separatorFile = NULL;
+ back->printProcessor = NULL;
+ back->dataType = NULL;
+ back->parameters = NULL;
+ back->attributes = back->status = back->nJobs = (DWORD)0UL;
+ back->printerName = dk3str_dup_app(pn, app);
+ if(!(back->printerName)) {
+ dkwt_tool_printer_delete(back); back = NULL;
+ }
+ }
+ return back;
+}
+
+
+
+void
+dkwt_tool_close_printer_list(dkwt_printer_list_t *pl)
+{
+ dkwt_printer_t *pr;
+
+ if(pl) {
+ if(pl->s_prn) {
+ if(pl->i_prn) {
+ dk3sto_it_reset(pl->i_prn);
+ while((pr = (dkwt_printer_t *)dk3sto_it_next(pl->i_prn)) != NULL) {
+ dkwt_tool_printer_delete(pr);
+ }
+ dk3sto_it_close(pl->i_prn);
+ } pl->i_prn = NULL;
+ dk3sto_close(pl->s_prn);
+ } pl->s_prn = NULL;
+ dk3_delete(pl);
+ }
+}
+
+
+
+/** Read printer list from system.
+ @param pl Printer list (destination).
+ @param app Application structure for diagnostics.
+ @param f_long Flag: Detailed (non-zero) or short (0).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkwt_tool_read_printer_list(
+ dkwt_printer_list_t *pl,
+ dk3_app_t *app,
+ int f_long
+)
+{
+ int back = 0;
+ char *peb = NULL;
+ DWORD szpeb;
+ DWORD cbNeeded;
+ DWORD cbReturned;
+ DWORD i;
+ PRINTER_INFO_2 *pi2;
+ dkwt_printer_t *pr;
+ cbNeeded = (DWORD)0UL;
+ cbReturned = (DWORD)0UL;
+ $? "+ dkwt_tool_read_printer_list %d", f_long
+ EnumPrinters(
+ PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &cbNeeded, &cbReturned
+ );
+ if(cbNeeded > 0) {
+ peb = dk3_new_app(char,(size_t)cbNeeded,app);
+ if(peb) {
+ szpeb = cbNeeded;
+ cbNeeded = (DWORD)0UL;
+ cbReturned = (DWORD)0UL;
+ if(EnumPrinters(
+ PRINTER_ENUM_LOCAL, NULL, 2, (LPBYTE)peb, szpeb, &cbNeeded, &cbReturned
+ )
+ )
+ {
+ if(cbReturned > (DWORD)0UL) {
+ pi2 = (PRINTER_INFO_2 *)peb;
+ back = 1;
+ for(i = 0; i < cbReturned; i++) {
+ if(pi2->pPrinterName) { $? ". \"%ls\"", pi2->pPrinterName
+ pr = dkwt_tool_printer_new(pi2->pPrinterName, app);
+ if(pr) { $? ". pr ok"
+ if(dk3sto_add(pl->s_prn, (void *)pr)) { $? ". add ok"
+ if(f_long) { $? ". long"
+ dkwt_tool_save_text(
+ &(pr->comment),
+ pi2->pComment,
+ app,
+ &back
+ );
+ dkwt_tool_save_text(
+ &(pr->location),
+ pi2->pLocation,
+ app,
+ &back
+ );
+ dkwt_tool_save_text(
+ &(pr->serverName),
+ pi2->pServerName,
+ app,
+ &back
+ );
+ dkwt_tool_save_text(
+ &(pr->shareName),
+ pi2->pShareName,
+ app,
+ &back
+ );
+ dkwt_tool_save_text(
+ &(pr->portName),
+ pi2->pPortName,
+ app,
+ &back
+ );
+ dkwt_tool_save_text(
+ &(pr->driverName),
+ pi2->pDriverName,
+ app,
+ &back
+ );
+#if 0
+ dkwt_tool_save_text(
+ &(pr->deviceName),
+ pi2->pDeviceName,
+ app,
+ &back
+ );
+#endif
+ dkwt_tool_save_text(
+ &(pr->separatorFile),
+ pi2->pSepFile,
+ app,
+ &back
+ );
+ dkwt_tool_save_text(
+ &(pr->printProcessor),
+ pi2->pPrintProcessor,
+ app,
+ &back
+ );
+ dkwt_tool_save_text(
+ &(pr->dataType),
+ pi2->pDatatype,
+ app,
+ &back
+ );
+ dkwt_tool_save_text(
+ &(pr->parameters),
+ pi2->pParameters,
+ app,
+ &back
+ );
+ pr->attributes = pi2->Attributes;
+ pr->status = pi2->Status;
+ pr->nJobs = pi2->cJobs;
+ } else { $? ". short info enough"
+ }
+ } else {
+ dkwt_tool_printer_delete(pr);
+ back = 0;
+ }
+ } else {
+ back = 0;
+ }
+ }
+ pi2++;
+ }
+ }
+ }
+ dk3_delete(peb);
+ }
+ } else {
+ /* ERROR: Failed to obtain byte number. */
+ dk3app_log_i1(app, DK3_LL_ERROR, 244);
+ } $? "- dkwt_tool_read_printer_list %d", back
+ return back;
+}
+
+
+
+dkwt_printer_list_t *
+dkwt_tool_open_printer_list(dk3_app_t *app, int f_long)
+{
+ dkwt_printer_list_t *back = NULL;
+ back = dk3_new_app(dkwt_printer_list_t,1,app);
+ if(back) {
+ back->i_prn = NULL;
+ back->s_prn = dk3sto_open_app(app);
+ if(back->s_prn) {
+ dk3sto_set_comp(back->s_prn, dkwt_to_compare_printers, 0);
+ back->i_prn = dk3sto_it_open(back->s_prn);
+ }
+ if((back->s_prn) && (back->i_prn)) {
+ if(!dkwt_tool_read_printer_list(back, app, f_long)) {
+ dkwt_tool_close_printer_list(back); back = NULL;
+ }
+ } else {
+ dkwt_tool_close_printer_list(back); back = NULL;
+ }
+ }
+ return back;
+}
+
+
+void
+dkwt_tool_printer_list_reset(dkwt_printer_list_t *pl)
+{
+ if(pl) {
+ if(pl->i_prn) {
+ dk3sto_it_reset(pl->i_prn);
+ }
+ }
+}
+
+
+
+dkwt_printer_t *
+dkwt_tool_printer_list_next(dkwt_printer_list_t *pl)
+{
+ dkwt_printer_t *back = NULL;
+ if(pl) {
+ if(pl->i_prn) {
+ back = (dkwt_printer_t *)dk3sto_it_next(pl->i_prn);
+ }
+ }
+ return back;
+}
+
+
+
+long
+dkwt_tool_reg_open_key(
+ HKEY key,
+ dkChar const *skn,
+ REGSAM sam,
+ PHKEY phk
+)
+{
+ long res;
+ DWORD dw0;
+
+ dw0 = (DWORD)0;
+#if DK3_CHAR_SIZE > 1
+ res = RegOpenKeyExW(key, skn, dw0, sam, phk);
+#else
+ res = RegOpenKeyExA(key, skn, dw0, sam, phk);
+#endif
+ return res;
+}
+
+
+
+long
+dkwt_tool_reg_query_value(
+ HKEY hk,
+ dkChar const *vn,
+ DWORD *pDwTp,
+ void *buf,
+ DWORD *pDwSz
+)
+{
+ long res;
+#if DK3_CHAR_SIZE > 1
+ res = RegQueryValueExW(
+ hk, vn, NULL, pDwTp, (LPBYTE)buf, pDwSz
+ );
+#else
+ res = RegQueryValueExA(
+ hk, vn, NULL, pDwTp, (LPBYTE)buf, pDwSz
+ );
+#endif
+ return res;
+}
+
+
+
+long
+dkwt_tool_reg_delete_value(
+ HKEY hk,
+ dkChar const *en
+)
+{
+ long res;
+#if DK3_CHAR_SIZE > 1
+ res = RegDeleteValueW(hk, en);
+#else
+ res = RegDeleteValueA(hk, en);
+#endif
+ return res;
+}
+
+
+
+long
+dkwt_tool_reg_delete_tree(
+ HKEY hk,
+ dkChar const *tn
+)
+{
+ long res = ERROR_NOT_SUPPORTED;
+#if _MSC_VER >= 1700 && (!(DK4_WINDOWS_LEGACY))
+#if DK3_CHAR_SIZE > 1
+ res = RegDeleteTreeW(hk, tn);
+#else
+ res = RegDeleteTreeA(hk, tn);
+#endif
+#endif
+ return res;
+}
+
+
+long
+dkwt_tool_reg_enum_key(
+ HKEY hk,
+ DWORD dwIndex,
+ dkChar *pResult,
+ DWORD *pDwSzResult,
+ dkChar *pClass,
+ DWORD *pDwSzClass,
+ PFILETIME pLastWrite
+)
+{
+ long res;
+ $? "+ dkwt_tool_reg_enum_key %ld", (long)dwIndex
+#if DK3_CHAR_SIZE > 1
+ res = RegEnumKeyExW(
+ hk, dwIndex, pResult, pDwSzResult,
+ NULL, pClass, pDwSzClass, pLastWrite
+ );
+#else
+ res = RegEnumKeyExA(
+ hk, dwIndex, pResult, pDwSzResult,
+ NULL, pClass, pDwSzClass, pLastWrite
+ );
+#endif
+ $? "- dkwt_tool_reg_enum_key %ld", res
+ return res;
+}
+
+
+
+long
+dkwt_tool_reg_create_key(
+ HKEY hk,
+ dkChar const *kn,
+ DWORD dwOptions,
+ REGSAM sam,
+ PHKEY pHkeyResult,
+ LPDWORD lpDwDisposition
+)
+{
+ long res;
+ DWORD dw0;
+
+ dw0 = 0;
+#if DK3_CHAR_SIZE > 1
+ res = RegCreateKeyExW(
+ hk, kn, dw0, NULL, dwOptions, sam,
+ NULL, pHkeyResult, lpDwDisposition
+ );
+#else
+ res = RegCreateKeyExA(
+ hk, kn, dw0, NULL, dwOptions, sam,
+ NULL, pHkeyResult, lpDwDisposition
+ );
+#endif
+ return res;
+}
+
+
+long
+dkwt_ev_reg_set_value(
+ HKEY hk,
+ dkChar const *vn,
+ DWORD dwType,
+ void *pData,
+ DWORD szData
+)
+{
+ long res;
+ DWORD dw0;
+
+ dw0 = 0;
+#if DK3_CHAR_SIZE > 1
+ res = RegSetValueExW(
+ hk, vn, dw0, dwType, (BYTE const *)pData, szData
+ );
+#else
+ res = RegSetValueExA(
+ hk, vn, dw0, dwType, (BYTE const *)pData, szData
+ );
+#endif
+ return res;
+}
+
+
+
+
+int
+dkwt_is_admin(void)
+{
+ PSID pAdmGroup = NULL;
+ SID_IDENTIFIER_AUTHORITY ntAuthority = SECURITY_NT_AUTHORITY;
+ BOOL bres = FALSE;
+ BOOL isadm = FALSE;
+ int back = 0;
+ back = -1;
+ bres = AllocateAndInitializeSid(
+ &ntAuthority, 2,
+ SECURITY_BUILTIN_DOMAIN_RID, /* sub-authority 0 */
+ DOMAIN_ALIAS_RID_ADMINS, /* sub-authority 1 */
+ (DWORD)0, /* sub-authority 2 */
+ (DWORD)0, /* sub-authority 3 */
+ (DWORD)0, /* sub-authority 4 */
+ (DWORD)0, /* sub-authority 5 */
+ (DWORD)0, /* sub-authority 6 */
+ (DWORD)0, /* sub-authority 7 */
+ &pAdmGroup
+ );
+ if (bres) {
+ if (CheckTokenMembership(NULL, pAdmGroup, &isadm)) {
+ if (isadm) {
+ back = 1;
+ } else {
+ back = 0;
+ }
+ }
+ }
+ if (NULL != pAdmGroup) {
+ FreeSid(pAdmGroup);
+ }
+ return back;
+}
diff --git a/support/dktools/dkwt.c b/support/dktools/dkwt.c
new file mode 100644
index 0000000000..ba1e7e08bf
--- /dev/null
+++ b/support/dktools/dkwt.c
@@ -0,0 +1,1828 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dkwt.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dkwt.c The dkwt module.
+*/
+
+
+#line 10 "dkwt.ctr"
+
+#include "dk3all.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4vers.h"
+#include "dkt.h"
+#include "dkwt.h"
+
+
+
+
+
+#line 22 "dkwt.ctr"
+
+
+
+/** File name for string table file.
+*/
+static dkChar const dkwt_string_table_file_name[] = { dkT("dkwt.str") };
+
+
+
+/** Version number string.
+*/
+static dkChar const dkwt_version[] = {
+dkT("dkwt ") DKT_VERSION_DK
+};
+
+
+
+/** License terms.
+*/
+static dkChar const * const dkwt_license[] = {
+dkT(""),
+dkT("Copyright (c) 2011-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms,"),
+dkT("with or without modification, are permitted provided"),
+dkT("that the following conditions are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above"),
+dkT(" copyright notice, this list of conditions and the"),
+dkT(" following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above "),
+dkT(" copyright notice, this list of conditions and the following"),
+dkT(" disclaimer in the documentation and/or other materials"),
+dkT(" provided with the distribution."),
+dkT("* Neither the name of the copyright holder(s) nor the names of"),
+dkT(" contributors may be used to endorse or promote"),
+dkT(" products derived from this software without specific"),
+dkT(" prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND"),
+dkT("CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,"),
+dkT("INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF"),
+dkT("MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE"),
+dkT("DISCLAIMED."),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE"),
+dkT("LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,"),
+dkT("EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT"),
+dkT("LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;"),
+dkT("LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)"),
+dkT("HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN"),
+dkT("CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE"),
+dkT("OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS"),
+dkT("SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH"),
+dkT("DAMAGE."),
+dkT(""),
+NULL
+
+
+#line 80 "dkwt.ctr"
+};
+
+
+
+/** Message texts used by the program, localized.
+*/
+static dkChar const * const dkwt_message_texts[] = {
+/* 0 */
+dkT("Full name: "),
+
+/* 1 */
+dkT("Comment: "),
+
+/* 2 */
+dkT("User comment: "),
+
+/* 3 */
+dkT("Home directory:"),
+
+/* 4 */
+dkT("User profile: "),
+
+/* 5 */
+dkT("SID: "),
+
+/* 6 */
+dkT("Type: "),
+
+/* 7 */
+dkT("Guest"),
+
+/* 8 */
+dkT("User"),
+
+/* 9 */
+dkT("Administrator"),
+
+/* 10 */
+dkT("Flags: "),
+
+/* 11 */
+dkT("Login script executed."),
+
+/* 12 */
+dkT("Account disabled."),
+
+/* 13 */
+dkT("Home directory required."),
+
+/* 14 */
+dkT("No password required."),
+
+/* 15 */
+dkT("Password can not be changed."),
+
+/* 16 */
+dkT("Account locked out."),
+
+/* 17 */
+dkT("Password does not expire."),
+
+/* 18 */
+dkT("Encrypted text password allowed."),
+
+/* 19 */
+dkT("Sensitive account, no delegation."),
+
+/* 20 */
+dkT("Smartcard required."),
+
+/* 21 */
+dkT("DES keys only."),
+
+/* 22 */
+dkT("No Kerberos pre-authentication required."),
+
+/* 23 */
+dkT("Trusted for delegation."),
+
+/* 24 */
+dkT("Password expired."),
+
+/* 25 */
+dkT("Trusted to authenticate for delegation."),
+
+/* 26 */
+dkT("Normal user account."),
+
+/* 27 */
+dkT("Duplicated account for user from another domain."),
+
+/* 28 */
+dkT("Workstation trust account."),
+
+/* 29 */
+dkT("Server trust account."),
+
+/* 30 */
+dkT("Interdomain trust account."),
+
+/* 31 */
+dkT(""),
+
+/* 32 */
+dkT("Operator: "),
+
+/* 33 */
+dkT("Accounts operator."),
+
+/* 34 */
+dkT("Server operator."),
+
+/* 35 */
+dkT("Communications operator."),
+
+/* 36 */
+dkT("Print operator."),
+
+/* 37 */
+dkT("Country code: "),
+
+/* 38 */
+dkT("Code page no.: "),
+
+/* 39 */
+dkT("Source: "),
+
+/* 40 */
+dkT("Comment: "),
+
+/* 41 */
+dkT("Net"),
+
+/* 42 */
+dkT("Local"),
+
+/* 43 */
+dkT("SID: "),
+
+/* 44 */
+dkT("Comment: "),
+
+/* 45 */
+dkT("Description: "),
+
+/* 46 */
+dkT("Location: "),
+
+/* 47 */
+dkT("Server: "),
+
+/* 48 */
+dkT("Share name: "),
+
+/* 49 */
+dkT("Port: "),
+
+/* 50 */
+dkT("Driver: "),
+
+/* 51 */
+dkT("Device: "),
+
+/* 52 */
+dkT("Separator file: "),
+
+/* 53 */
+dkT("Print processor: "),
+
+/* 54 */
+dkT("Data type: "),
+
+/* 55 */
+dkT("Parameters: "),
+
+/* 56 */
+dkT("Failed to create print file \""),
+
+/* 57 */
+dkT("\"!"),
+
+/* 58 */
+dkT("Failed to schedule print job!"),
+
+/* 59 */
+dkT("Failed to add print job!"),
+
+/* 60 */
+dkT("Failed to open printer \""),
+
+/* 61 */
+dkT("\"!"),
+
+/* 62 */
+dkT("Printer name too long!"),
+
+/* 63 */
+dkT("No printer found for device \""),
+
+/* 64 */
+dkT("\"!"),
+
+/* 65 */
+dkT("Failed to find default printer!"),
+
+/* 66 */
+dkT("Redefinition of profile base directory!"),
+
+/* 67 */
+dkT("No profile base directory specified!"),
+
+/* 68 */
+dkT("Syntax error - Unknown section type!"),
+
+/* 69 */
+dkT("Syntax error - Incomplete section header!"),
+
+/* 70 */
+dkT("Syntax error - Missing section header!"),
+
+/* 71 */
+dkT("Syntax error - Redefinition of system user!"),
+
+/* 72 */
+dkT("Syntax error - Redefinition of everyone user!"),
+
+/* 73 */
+dkT("Syntax error - Unknown option!"),
+
+/* 74 */
+dkT("Syntax error - Not a key/value pair!"),
+
+/* 75 */
+dkT("Options -l and -s are exclusive!"),
+
+/* 76 */
+dkT("Arguments are ignored!"),
+
+/* 77 */
+dkT("FAILED TO SET KEEP-DATA FLAG!"),
+
+/* 78 */
+dkT("Keep-data flag was set successfully."),
+
+/* 79 */
+dkT("Exit status code indicates an error, program:\n\""),
+
+/* 80 */
+dkT(""),
+
+/* 81 */
+dkT("Failed to find name for SID \""),
+
+/* 82 */
+dkT("\"!"),
+
+/* 83 */
+dkT("Cleaning up local print queue \""),
+
+/* 84 */
+dkT("\"."),
+
+/* 85 */
+dkT("Successfully deleted job "),
+
+/* 86 */
+dkT(": \""),
+
+/* 87 */
+dkT("\"."),
+
+/* 88 */
+dkT("Unnamed print job"),
+
+/* 89 */
+dkT("Failed to delete job "),
+
+/* 90 */
+dkT(": \""),
+
+/* 91 */
+dkT("\"!"),
+
+/* 92 */
+dkT("Failed to open printer \""),
+
+/* 93 */
+dkT("\"!"),
+
+/* 94 */
+dkT("Failed to enumerate local printers!"),
+
+/* 95 */
+dkT("Missing user name!"),
+
+/* 96 */
+dkT("Print queue cleaned up successfully."),
+
+/* 97 */
+dkT("Failed to send request!"),
+
+/* 98 */
+dkT("Failed to connect to remote host!"),
+
+/* 99 */
+dkT("Failed to create network socket!"),
+
+/* 100 */
+dkT("Failed to find IP address for remote host!"),
+
+/* 101 */
+dkT("Cleaning up remote print queue \""),
+
+/* 102 */
+dkT("\"."),
+
+/* 103 */
+dkT("Request too long for buffer!"),
+
+/* 104 */
+dkT("Empty queue name in \""),
+
+/* 105 */
+dkT("\"!"),
+
+/* 106 */
+dkT("Empty host name in \""),
+
+/* 107 */
+dkT("\"!"),
+
+/* 108 */
+dkT("Not a queue@host name: \""),
+
+/* 109 */
+dkT("\"!"),
+
+/* 110 */
+dkT("Queue name \""),
+
+/* 111 */
+dkT("\" too long!"),
+
+/* 112 */
+dkT("Failed to initialize Windows sockets!"),
+
+/* 113 */
+dkT("Error code: "),
+
+/* 114 */
+dkT("."),
+
+/* 115 */
+dkT("IP address: "),
+
+/* 116 */
+dkT("."),
+
+/* 117 */
+dkT("User profile cleanup is disabled on Windows Vista and above!"),
+
+/* 118 */
+dkT("Executing command:\n"),
+
+/* 119 */
+dkT(""),
+
+/* 120 */
+dkT("Remove directory:\n"),
+
+/* 121 */
+dkT(""),
+
+/* 122 */
+dkT("Remove file:\n"),
+
+/* 123 */
+dkT(""),
+
+/* 124 */
+dkT("Delete registry key:\n"),
+
+/* 125 */
+dkT("\\"),
+
+/* 126 */
+dkT(""),
+
+/* 127 */
+dkT("Registry key \""),
+
+/* 128 */
+dkT("\" deleted."),
+
+/* 129 */
+dkT("Failed to remove registry key:\n"),
+
+/* 130 */
+dkT("\\"),
+
+/* 131 */
+dkT(""),
+
+/* 132 */
+dkT("Failed to open registry key:\n"),
+
+/* 133 */
+dkT(""),
+
+/* 134 */
+dkT("Cleaning up profiles (start)."),
+
+/* 135 */
+dkT("Internal error while retrieving directory entry name!"),
+
+/* 136 */
+dkT("Failed to expand string\n\""),
+
+/* 137 */
+dkT("\",\nresult would become too long for buffer!"),
+
+/* 138 */
+dkT("Subkey name too long:\n"),
+
+/* 139 */
+dkT(""),
+
+/* 140 */
+dkT("Skipping profile cleanup due to previous errors!"),
+
+/* 141 */
+dkT("Cleaning up profiles (finished)."),
+
+/* 142 */
+dkT("Options -u, -i, -a, and -d are mutually exlusive!"),
+
+/* 143 */
+dkT("At least one argument required!"),
+
+/* 144 */
+dkT("Missing file/directory name!"),
+
+/* 145 */
+dkT("Administrative privileges are required!"),
+
+/* 146 */
+dkT("Administrative privileges are required to modify system environment!"),
+
+NULL
+
+
+#line 590 "dkwt.ctr"
+};
+
+
+
+/** Keywords used by the program, not localized.
+*/
+static dkChar const * const dkwt_no_loc[] = {
+/* 0 */
+dkT(""),
+
+/* 1 */
+dkT("dkwt.conf"),
+
+/* 2 */
+dkT("System"),
+
+/* 3 */
+dkT("Jeder"),
+
+/* 4 */
+dkT("RD /S /Q \""),
+
+/* 5 */
+dkT("\""),
+
+/* 6 */
+dkT("DEL /Q /F \""),
+
+/* 7 */
+dkT("CACLS.EXE \""),
+
+/* 8 */
+dkT("\" /T /E /C /G"),
+
+/* 9 */
+dkT(":F"),
+
+/* 10 */
+dkT("ICACLS.EXE \""),
+
+/* 11 */
+dkT("\" /grant "),
+
+/* 12 */
+dkT(":F /T /C /Q"),
+
+/* 13 */
+dkT(":F /C /Q"),
+
+/* 14 */
+dkT("\" /E /C /G "),
+
+/* 15 */
+dkT("SOFTWARE\\DKrause\\Shared\\dkwt"),
+
+/* 16 */
+dkT("keep"),
+
+/* 17 */
+dkT("S-1-1-0"),
+
+/* 18 */
+dkT("S-1-5-18"),
+
+/* 19 */
+dkT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList"),
+
+/* 20 */
+dkT("\\"),
+
+/* 21 */
+dkT("ProfileImagePath"),
+
+NULL
+
+
+#line 687 "dkwt.ctr"
+};
+
+
+
+/** Subcommand names.
+*/
+static dkChar const * const dkwt_commands[] = {
+/* 0 */ dkT("boot"),
+/* 1 */ dkT("shutdown"),
+/* 2 */ dkT("login"),
+/* 3 */ dkT("logout"),
+/* 4 */ dkT("users"),
+/* 5 */ dkT("groups"),
+/* 6 */ dkT("printers"),
+/* 7 */ dkT("print"),
+/* 8 */ dkT("help"),
+/* 9 */ dkT("version"),
+/* 10 */ dkT("license-terms"),
+/* 11 */ dkT("keep"),
+/* 12 */ dkT("unkeep"),
+/* 13 */ dkT("--help"),
+/* 14 */ dkT("--version"),
+/* 15 */ dkT("--license-terms"),
+/* 16 */ dkT("--license"),
+/* 17 */ dkT("license"),
+/* 18 */ dkT("-h"),
+/* 19 */ dkT("-v"),
+/* 20 */ dkT("-L"),
+/* 21 */ dkT("cleanup-profiles"),
+/* 22 */ dkT("clp"),
+/* 23 */ dkT("env"),
+/* 24 */ dkT("environment"),
+NULL
+};
+
+
+
+/** Help file names.
+*/
+static dkChar const * const dkwt_help_file_names[] = {
+/* 0 */ dkT("dkwt-boot.txt"),
+/* 1 */ dkT("dkwt-shutdown.txt"),
+/* 2 */ dkT("dkwt-login.txt"),
+/* 3 */ dkT("dkwt-logout.txt"),
+/* 4 */ dkT("dkwt-users.txt"),
+/* 5 */ dkT("dkwt-groups.txt"),
+/* 6 */ dkT("dkwt-printers.txt"),
+/* 7 */ dkT("dkwt-print.txt"),
+/* 8 */ dkT("dkwt-help.txt"),
+/* 9 */ dkT(""), /* unused */
+/* 10 */ dkT(""), /* unused */
+/* 11 */ dkT("dkwt-keep.txt"),
+/* 12 */ dkT("dkwt-unkeep.txt"),
+/* 13 */ dkT("dkwt-clp.txt"),
+/* 14 */ dkT("dkwt-env.txt"),
+NULL
+};
+
+
+
+/** Help text for the boot command.
+*/
+static dkChar const * const dkwt_help_boot[] = {
+dkT(""),
+dkT("NAME"),
+dkT(""),
+dkT(" dkwt boot - Boot cleanup"),
+dkT(""),
+dkT("SYNOPSIS"),
+dkT(" "),
+dkT(" dkwt boot [-t]"),
+dkT(""),
+dkT("DESCRIPTION"),
+dkT(""),
+dkT("The \"dkwt boot\" program should be run from the system boot script to do"),
+dkT("cleanup at boot time in PC classrooms."),
+dkT(""),
+dkT("OPTIONS"),
+dkT(""),
+dkT("-t"),
+dkT("\tTest mode. The program does not perform cleanup, it only writes"),
+dkT("\tmessages about files and directories to delete."),
+dkT(""),
+dkT("EXIT STATUS"),
+dkT(""),
+dkT("The exit status code is always 0, regardless of any error occured."),
+dkT(""),
+dkT("FILES"),
+dkT(""),
+dkT("dkwt.conf"),
+dkT("\tConfiguration file for cleanup operations."),
+dkT(""),
+dkT("\tRun"),
+dkT("\t\tdkwt -h"),
+dkT("\tto view detailed information about the dkwt.conf file."),
+dkT(""),
+dkT("NOTES"),
+dkT(""),
+dkT("After changing the dkwt.conf file you should run"),
+dkT(" dkwt boot -t"),
+dkT("to test the dkwt.conf file."),
+dkT(""),
+dkT("AUTHOR"),
+dkT(""),
+dkT("Dirk Krause"),
+dkT(""),
+dkT("COPYRIGHT AND LICENSE"),
+dkT(""),
+dkT("Run"),
+dkT(" dkwt --license-terms"),
+dkT("to see the license conditions."),
+dkT(""),
+dkT("SEE ALSO"),
+dkT(""),
+dkT("http://dktools.sourceforge.net"),
+dkT(""),
+NULL
+
+
+#line 805 "dkwt.ctr"
+};
+
+
+
+/** Help text for the shutdown command.
+*/
+static dkChar const * const dkwt_help_shutdown[] = {
+dkT(""),
+dkT("NAME"),
+dkT(""),
+dkT(" dkwt shutdown - Shutdown cleanup"),
+dkT(""),
+dkT("SYNOPSIS"),
+dkT(" "),
+dkT(" dkwt shutdown [-t]"),
+dkT(""),
+dkT("DESCRIPTION"),
+dkT(""),
+dkT("The \"dkwt shutdown\" program should be run from the system shutdown script to do"),
+dkT("cleanup at shutdown time in PC classrooms."),
+dkT(""),
+dkT("OPTIONS"),
+dkT(""),
+dkT("-t"),
+dkT("\truns in test mode. The program does not perform cleanup, it only writes"),
+dkT("\tmessages about files and directories to delete."),
+dkT(""),
+dkT("EXIT STATUS"),
+dkT(""),
+dkT("The exit status code is always 0, regardless of any error occured."),
+dkT(""),
+dkT("FILES"),
+dkT(""),
+dkT("dkwt.conf"),
+dkT("\tConfiguration file for cleanup operations."),
+dkT("\tRun"),
+dkT("\t\tdkwt -h"),
+dkT("\tto view detailed information about the dkwt.conf file."),
+dkT(""),
+dkT("NOTES"),
+dkT(""),
+dkT("After changing the dkwt.conf file you should run"),
+dkT(" dkwt shutdown -t"),
+dkT("to test the dkwt.conf file."),
+dkT(""),
+dkT("AUTHOR"),
+dkT(""),
+dkT("Dirk Krause"),
+dkT(""),
+dkT("COPYRIGHT AND LICENSE"),
+dkT(""),
+dkT("Run"),
+dkT(" dkwt --license-terms"),
+dkT("to see the license conditions."),
+dkT(""),
+dkT("SEE ALSO"),
+dkT(""),
+dkT("http://dktools.sourceforge.net"),
+dkT(""),
+NULL
+
+
+#line 866 "dkwt.ctr"
+};
+
+
+
+/** Help text for the login command.
+*/
+static dkChar const * const dkwt_help_login[] = {
+dkT(""),
+dkT("NAME"),
+dkT(""),
+dkT(" dkwt login - Login cleanup"),
+dkT(""),
+dkT("SYNOPSIS"),
+dkT(" "),
+dkT(" dkwt login [-t]"),
+dkT(""),
+dkT("DESCRIPTION"),
+dkT(""),
+dkT("The \"dkwt login\" program should be run from the user login script to do"),
+dkT("cleanup at login time in PC classrooms."),
+dkT(""),
+dkT("OPTIONS"),
+dkT(""),
+dkT("-t"),
+dkT("\truns in test mode. The program does not perform cleanup, it only writes"),
+dkT("\tmessages about files and directories to delete."),
+dkT(""),
+dkT("EXIT STATUS"),
+dkT(""),
+dkT("The exit status code is always 0, regardless of any error occured."),
+dkT(""),
+dkT("FILES"),
+dkT(""),
+dkT("dkwt.conf"),
+dkT("\tConfiguration file for cleanup operations."),
+dkT("\tRun"),
+dkT("\t\tdkwt -h"),
+dkT("\tto view detailed information about the dkwt.conf file."),
+dkT(""),
+dkT("NOTES"),
+dkT(""),
+dkT("After changing the dkwt.conf file you should run"),
+dkT(" dkwt login -t"),
+dkT("to test the dkwt.conf file."),
+dkT(""),
+dkT("AUTHOR"),
+dkT(""),
+dkT("Dirk Krause"),
+dkT(""),
+dkT("COPYRIGHT AND LICENSE"),
+dkT(""),
+dkT("Run"),
+dkT(" dkwt --license-terms"),
+dkT("to see the license conditions."),
+dkT(""),
+dkT("SEE ALSO"),
+dkT(""),
+dkT("http://dktools.sourceforge.net"),
+dkT(""),
+NULL
+
+
+#line 927 "dkwt.ctr"
+};
+
+
+
+/** Help text for the logout command.
+*/
+static dkChar const * const dkwt_help_logout[] = {
+dkT(""),
+dkT("NAME"),
+dkT(""),
+dkT(" dkwt logout - Logout cleanup"),
+dkT(""),
+dkT("SYNOPSIS"),
+dkT(" "),
+dkT(" dkwt logout [-t]"),
+dkT(""),
+dkT("DESCRIPTION"),
+dkT(""),
+dkT("The \"dkwt logout\" program should be run from the user logout script to do"),
+dkT("cleanup at logout time in PC classrooms."),
+dkT(""),
+dkT("OPTIONS"),
+dkT(""),
+dkT("-t"),
+dkT("\truns in test mode. The program does not perform cleanup, it only writes"),
+dkT("\tmessages about files and directories to delete."),
+dkT(""),
+dkT("EXIT STATUS"),
+dkT(""),
+dkT("The exit status code is always 0, regardless of any error occured."),
+dkT(""),
+dkT("FILES"),
+dkT(""),
+dkT("dkwt.conf"),
+dkT("\tConfiguration file for cleanup operations."),
+dkT("\tRun"),
+dkT("\t\tdkwt -h"),
+dkT("\tto view detailed information about the dkwt.conf file."),
+dkT(""),
+dkT("NOTES"),
+dkT(""),
+dkT("After changing the dkwt.conf file you should run"),
+dkT(" dkwt logout -t"),
+dkT("to test the dkwt.conf file."),
+dkT(""),
+dkT("AUTHOR"),
+dkT(""),
+dkT("Dirk Krause"),
+dkT(""),
+dkT("COPYRIGHT AND LICENSE"),
+dkT(""),
+dkT("Run"),
+dkT(" dkwt --license-terms"),
+dkT("to see the license conditions."),
+dkT(""),
+dkT("SEE ALSO"),
+dkT(""),
+dkT("http://dktools.sourceforge.net"),
+dkT(""),
+NULL
+
+
+#line 988 "dkwt.ctr"
+};
+
+
+
+/** Help text for the keep command.
+*/
+static dkChar const * const dkwt_help_keep[] = {
+dkT(""),
+dkT("NAME"),
+dkT(""),
+dkT(" dkwt keep - Temporarily disable automatic cleanup"),
+dkT(""),
+dkT("SYNOPSIS"),
+dkT(""),
+dkT(" dkwt keep"),
+dkT(""),
+dkT("DESCRIPTION"),
+dkT(""),
+dkT("Use this program to disable automatic cleanup until (including) the next"),
+dkT("user login."),
+dkT("You should use this command in lectures about system programming before"),
+dkT("starting to test self-made system software, drivers..."),
+dkT("Use the"),
+dkT(" dkwt unkeep"),
+dkT("command to restore normal automatic cleanup when you are done with the tests."),
+dkT(""),
+dkT("EXIT STATUS"),
+dkT(""),
+dkT("0 on success, all other exit status codes indicate an error."),
+dkT(""),
+dkT("REGISTRY"),
+dkT(""),
+dkT("The HKEY_LOCAL_MACHINE\\SOFTWARE\\DKrause\\Shared\\dkwt must exist, full access"),
+dkT("must be possible for \"Everyone\" or \"INTERACTIVE\"."),
+dkT(""),
+dkT("AUTHOR"),
+dkT(""),
+dkT("Dirk Krause"),
+dkT(""),
+dkT("COPYRIGHT AND LICENSE"),
+dkT(""),
+dkT("Run"),
+dkT(" dkwt --license-terms"),
+dkT("to see the license conditions."),
+dkT(""),
+dkT("SEE ALSO"),
+dkT(""),
+dkT("http://dktools.sourceforge.net"),
+dkT(""),
+NULL
+
+
+#line 1039 "dkwt.ctr"
+};
+
+
+
+/** Help text for the keep command.
+*/
+static dkChar const * const dkwt_help_unkeep[] = {
+dkT(""),
+dkT("NAME"),
+dkT(""),
+dkT(" dkwt unkeep - Restore automatic cleanup"),
+dkT(""),
+dkT("SYNOPSIS"),
+dkT(""),
+dkT(" dkwt unkeep"),
+dkT(""),
+dkT("DESCRIPTION"),
+dkT(""),
+dkT("After disabling automatic cleanup temporarily using \"dkwt keep\" you can use"),
+dkT("this command to restore normal automatic cleanup."),
+dkT(""),
+dkT("EXIT STATUS"),
+dkT(""),
+dkT("0 on success, all other exit status codes indicate an error."),
+dkT(""),
+dkT("REGISTRY"),
+dkT(""),
+dkT("The HKEY_LOCAL_MACHINE\\SOFTWARE\\DKrause\\Shared\\dkwt must exist, full access"),
+dkT("must be possible for \"Everyone\" or \"INTERACTIVE\"."),
+dkT(""),
+dkT("AUTHOR"),
+dkT(""),
+dkT("Dirk Krause"),
+dkT(""),
+dkT("COPYRIGHT AND LICENSE"),
+dkT(""),
+dkT("Run"),
+dkT(" dkwt --license-terms"),
+dkT("to see the license conditions."),
+dkT(""),
+dkT("SEE ALSO"),
+dkT(""),
+dkT("http://dktools.sourceforge.net"),
+dkT(""),
+NULL
+
+
+#line 1085 "dkwt.ctr"
+};
+
+
+/** Help text for the cleanup-profiles command.
+*/
+static dkChar const * const dkwt_help_clp[] = {
+dkT(""),
+dkT("NAME"),
+dkT(""),
+dkT(" dkwt cleanup-profiles - Clean up profiles directories."),
+dkT(""),
+dkT("SYNOPSIS"),
+dkT(""),
+dkT(" dkwt cleanup-profiles"),
+dkT(" dkwt clp"),
+dkT(""),
+dkT("DESCRIPTION"),
+dkT(""),
+dkT("On Windows Vista and above we can not clean up profile directories"),
+dkT("from boot/shutdown/logon/logoff scripts as these scripts are run from"),
+dkT("a user account with insufficient permissions. User profiles cleanup"),
+dkT("is skipped in \"dkwt boot\", \"dkwt login\", \"dkwt logout\", and \"dkwt shutdown\"."),
+dkT(""),
+dkT("You can start a command prompt *as administrator* instead and run"),
+dkT("\"dkwt cleanup-profiles\" from there."),
+dkT("The program first attempts to use system functions to delete"),
+dkT("directories, additionally it uses the \"RD\" command."),
+dkT(""),
+dkT("Alternatively run \"dkwtadm cleanup-profiles\", this variant of dkwt uses"),
+dkT("the UAC to obtain administrative permissions."),
+dkT(""),
+dkT("EXIT STATUS"),
+dkT(""),
+dkT("0 on success, all other exit status codes indicate an error."),
+dkT(""),
+dkT("AUTHOR"),
+dkT(""),
+dkT("Dirk Krause"),
+dkT(""),
+dkT("HISTORY"),
+dkT(""),
+dkT("COPYRIGHT AND LICENSE"),
+dkT(""),
+dkT("Run"),
+dkT(" dkwt --license-terms"),
+dkT("to see the license conditions."),
+dkT(""),
+dkT("SEE ALSO"),
+dkT(""),
+dkT("http://dktools.sourceforge.net"),
+dkT(""),
+NULL
+
+
+#line 1138 "dkwt.ctr"
+};
+
+
+
+/** Help text for dkwt env.
+*/
+static dkChar const * const dkwt_help_env[] = {
+dkT(""),
+dkT("NAME"),
+dkT(""),
+dkT(" dkwt env - Modify environment variables"),
+dkT(""),
+dkT("SYNOPSIS"),
+dkT(""),
+dkT(" dkwt env [<options>] <name> [<value>]"),
+dkT(" dkwt environment [<options>] <name> [<value>]"),
+dkT(""),
+dkT("DESCRIPTION"),
+dkT(""),
+dkT("This function can modify environment variables, both system and"),
+dkT("user variables."),
+dkT("This function is mainly intended for environment variables storing"),
+dkT("names of directories or files (i.e. the PATH variable)."),
+dkT("You can make sure a directory is listed in a variable by inserting"),
+dkT("or appending the directory only if it is not yet present."),
+dkT(""),
+dkT("OPTIONS"),
+dkT(""),
+dkT("-s"),
+dkT("\tProcess system environment variables."),
+dkT("\tWithout this option the program processes the user environment."),
+dkT(""),
+dkT("-e"),
+dkT("\tWhen creating a new registry value, use type REG_EXPAND_SZ"),
+dkT("\tinstead of default REG_SZ."),
+dkT("\tThis option is ignored when processing existing registry values."),
+dkT(""),
+dkT("-u"),
+dkT("\tDelete registry value completely, unset variable."),
+dkT(""),
+dkT("-i"),
+dkT("\tEnsure the variable lists the specified directory or file,"),
+dkT("\tinsert at start if not present."),
+dkT(""),
+dkT("-a"),
+dkT("\tEnsure the variable lists the specified directory or file,"),
+dkT("\tappend at end if not present."),
+dkT(""),
+dkT("-d"),
+dkT("\tRemove a directory or file from a variable listing one"),
+dkT("\tor multiple directories or files."),
+dkT("\tIf the variable value is empty after removal, the registry"),
+dkT("\tvalue is deleted."),
+dkT(""),
+dkT("EXIT STATUS"),
+dkT(""),
+dkT("0 on success, all other exit status codes indicate an error."),
+dkT(""),
+dkT("EXAMPLES"),
+dkT(""),
+dkT("Show value of user environment variable TEMP:"),
+dkT(""),
+dkT("\tdkwt env TEMP"),
+dkT(""),
+dkT("Show value of system environment variable PATH:"),
+dkT(""),
+dkT("\tdkwt env -s PATH"),
+dkT(""),
+dkT("Completely delete user environment variable FOO:"),
+dkT(""),
+dkT("\tdkwt env -u FOO"),
+dkT(""),
+dkT("Completely delete system environment variable BAR:"),
+dkT(""),
+dkT("\tdkwt env -s -u BAR"),
+dkT(""),
+dkT("Set user environment variable FOO:"),
+dkT(""),
+dkT("\tdkwt env FOO All text after variable name goes into value"),
+dkT(""),
+dkT("Set system environment variable BAR:"),
+dkT(""),
+dkT("\tdkwt env -s BAR Same procedure for system variables"),
+dkT(""),
+dkT("Make sure system PATH contains ``C:\\Program Files\\Nice Program''"),
+dkT("(insert at start if not present):"),
+dkT(""),
+dkT("\tdkwt env -s -i Path C:\\Program Files\\Nice Program"),
+dkT(""),
+dkT("Make sure system PATH contains ``C:\\Program Files\\Other Program''"),
+dkT("(append at end if not present):"),
+dkT(""),
+dkT("\tdkwt env -s -a Path C:\\Program Files\\Other Program"),
+dkT(""),
+dkT("Remove ``C:\\Program Files\\Nice Program'' from system PATH:"),
+dkT(""),
+dkT("\tdkwt env -s -d Path C:\\Program Files\\Nice Program"),
+dkT(""),
+dkT("NOTES"),
+dkT(""),
+dkT("``dkwt env'' does not change environment variables in cmd.exe windows"),
+dkT("already opened."),
+dkT(""),
+dkT("AUTHOR"),
+dkT(""),
+dkT("Dirk Krause"),
+dkT(""),
+dkT("HISTORY"),
+dkT(""),
+dkT("COPYRIGHT AND LICENSE"),
+dkT(""),
+dkT("Run"),
+dkT(" dkwt --license-terms"),
+dkT("to see the license conditions."),
+dkT(""),
+dkT("SEE ALSO"),
+dkT(""),
+dkT("http://dktools.sourceforge.net"),
+dkT(""),
+NULL
+
+
+#line 1259 "dkwt.ctr"
+};
+
+
+
+/** Help text for the users command.
+*/
+static dkChar const * const dkwt_help_users[] = {
+dkT(""),
+dkT("NAME"),
+dkT(""),
+dkT(" dkwt users - List users"),
+dkT(""),
+dkT("SYNOPSIS"),
+dkT(""),
+dkT(" dkwt users [<option>]"),
+dkT(""),
+dkT("DESCRIPTION"),
+dkT(""),
+dkT("The program lists the users configured on the system."),
+dkT(""),
+dkT("OPTIONS"),
+dkT(""),
+dkT("-l"),
+dkT("\tcreates a long (detailed) listing."),
+dkT(""),
+dkT("-s"),
+dkT("\tcreates a short listing (just the user names)."),
+dkT(""),
+dkT("Either -l or -s can be used, not both."),
+dkT(""),
+dkT("EXIT STATUS"),
+dkT(""),
+dkT("0 on success, all other exit status codes indicate an error."),
+dkT(""),
+dkT("AUTHOR"),
+dkT(""),
+dkT("Dirk Krause"),
+dkT(""),
+dkT("COPYRIGHT AND LICENSE"),
+dkT(""),
+dkT("Run"),
+dkT(" dkwt --license-terms"),
+dkT("to see the license conditions."),
+dkT(""),
+dkT("SEE ALSO"),
+dkT(""),
+dkT("http://dktools.sourceforge.net"),
+dkT(""),
+NULL
+
+
+#line 1309 "dkwt.ctr"
+};
+
+
+
+/** Help text for the groups command.
+*/
+static dkChar const * const dkwt_help_groups[] = {
+dkT(""),
+dkT("NAME"),
+dkT(""),
+dkT(" dkwt groups - List groups"),
+dkT(""),
+dkT("SYNOPSIS"),
+dkT(""),
+dkT(" dkwt groups <option>"),
+dkT(""),
+dkT("DESCRIPTION"),
+dkT(""),
+dkT("The command lists the group on the current system."),
+dkT(""),
+dkT("OPTIONS"),
+dkT(""),
+dkT("-l"),
+dkT("\tcreates a long (detailed) listing."),
+dkT(""),
+dkT("-s"),
+dkT("\tcreates aa short listing (just the group names)."),
+dkT(""),
+dkT("The options -l and -s can not be used together."),
+dkT(""),
+dkT("EXIT STATUS"),
+dkT(""),
+dkT("0 on success, all other exit status codes indicate an error."),
+dkT(""),
+dkT("AUTHOR"),
+dkT(""),
+dkT("Dirk Krause"),
+dkT(""),
+dkT("COPYRIGHT AND LICENSE"),
+dkT(""),
+dkT("Run"),
+dkT(" dkwt --license-terms"),
+dkT("to see the license conditions."),
+dkT(""),
+dkT("SEE ALSO"),
+dkT(""),
+dkT("http://dktools.sourceforge.net"),
+dkT(""),
+NULL
+
+
+#line 1359 "dkwt.ctr"
+};
+
+
+
+/** Help text for dkwt help printers.
+*/
+static dkChar const * const dkwt_help_printers[] = {
+dkT(""),
+dkT("NAME"),
+dkT(""),
+dkT(" dkwt printers - List printers"),
+dkT(""),
+dkT("SYNOPSIS"),
+dkT(""),
+dkT(" dkwt printers [<option>]"),
+dkT(""),
+dkT("DESCRIPTION"),
+dkT(""),
+dkT("The command lists the printers installed on the system."),
+dkT(""),
+dkT("OPTIONS"),
+dkT(""),
+dkT("-l"),
+dkT("\tcreates a long (detailed) listing. Without this option the listing"),
+dkT("\tonly shows the printer names."),
+dkT(""),
+dkT("EXIT STATUS"),
+dkT(""),
+dkT("0 on success, all other exit status codes indicate an error."),
+dkT(""),
+dkT("AUTHOR"),
+dkT(""),
+dkT("Dirk Krause"),
+dkT(""),
+dkT("COPYRIGHT AND LICENSE"),
+dkT(""),
+dkT("Run"),
+dkT(" dkwt --license-terms"),
+dkT("to see the license conditions."),
+dkT(""),
+dkT("SEE ALSO"),
+dkT(""),
+dkT("http://dktools.sourceforge.net"),
+dkT(""),
+NULL
+
+
+#line 1405 "dkwt.ctr"
+};
+
+
+/** Help text for the print command.
+*/
+static dkChar const * const dkwt_help_print[] = {
+dkT(""),
+dkT("NAME"),
+dkT(""),
+dkT(" dkwt print - Print a file"),
+dkT(""),
+dkT("SYNOPSIS"),
+dkT(""),
+dkT(" dkwt print [<option>] [<file(s)>]"),
+dkT(""),
+dkT("DESCRIPTION"),
+dkT(""),
+dkT("The program prints the specified files or the contents read from standard"),
+dkT("input if no file name is specified."),
+dkT(""),
+dkT("OPTIONS"),
+dkT(""),
+dkT("-d <device>"),
+dkT("\tchooses a printer by the device name. The device name must be specified"),
+dkT("\there, not the printer name."),
+dkT("\tWithout this option the system's default printer is used."),
+dkT(""),
+dkT("EXIT STATUS"),
+dkT(""),
+dkT("0 on success, all other exit status codes indicate an error."),
+dkT(""),
+dkT("AUTHOR"),
+dkT(""),
+dkT("Dirk Krause"),
+dkT(""),
+dkT("COPYRIGHT AND LICENSE"),
+dkT(""),
+dkT("Run"),
+dkT(" dkwt --license-terms"),
+dkT("to see the license conditions."),
+dkT(""),
+dkT("SEE ALSO"),
+dkT(""),
+dkT("http://dktools.sourceforge.net"),
+dkT(""),
+NULL
+
+
+#line 1452 "dkwt.ctr"
+};
+
+
+
+/** General help text.
+*/
+static dkChar const * const dkwt_help_help[] = {
+dkT(""),
+dkT("NAME"),
+dkT(""),
+dkT(" dkwt - Dirk Krause's Windows tool"),
+dkT(""),
+dkT("SYNOPSIS"),
+dkT(""),
+dkT(" dkwt users [<option(s)>]"),
+dkT(" dkwt groups [<option(s)>]"),
+dkT(" dkwt printers [<option(s)>]"),
+dkT(" dkwt print [<option(s)>] [<file(s)>]"),
+dkT(" dkwt boot"),
+dkT(" dkwt login"),
+dkT(" dkwt logout"),
+dkT(" dkwt shutdown"),
+dkT(" dkwt keep"),
+dkT(" dkwt unkeep"),
+dkT(" dkwt cleanup-profiles"),
+dkT(" dkwt env [<options>] <name> [<value>]"),
+dkT(" dkwt help <command>"),
+dkT(" dkwt -h"),
+dkT(" dkwt -v"),
+dkT(" dkwt -L"),
+dkT(""),
+dkT("DESCRIPTION"),
+dkT(""),
+dkT("dkwt users\t\tlists the users."),
+dkT("dkwt groups\t\tlists the user groups."),
+dkT("dkwt printers\t\tlists the available printers."),
+dkT("dkwt print\t\tprints the specified file(s)."),
+dkT("dkwt boot\t\tdoes cleanup during boot."),
+dkT("dkwt login\t\tdoes cleanup during user login."),
+dkT("dkwt logout\t\tdoes cleanup during user logout."),
+dkT("dkwt shutdown\t\tdoes cleanup during shutdown."),
+dkT("dkwt keep\t\tdisables automatic cleanup temporarily until"),
+dkT("\t\t\tthe next user login is completed."),
+dkT("dkwt unkeep\t\trestores normal cleanup mechanisms."),
+dkT("dkwt cleanup-profiles cleans up user profiles."),
+dkT("dkwt help <command>\tprints a help text for a specific command."),
+dkT("dkwt -h\t\t\tshows this help text."),
+dkT("dkwt -v\t\t\tshows version information."),
+dkT("dkwt -L\t\t\tshows the license conditions."),
+dkT(""),
+dkT("The boot, login, logout, shutdown, keep, and unkeep commands are intended for"),
+dkT("use in PC classrooms, see NOTES below."),
+dkT(""),
+dkT("OPTIONS"),
+dkT(""),
+dkT("-s"),
+dkT("\tswitches to short listings for the users, and groups command."),
+dkT(""),
+dkT("-l"),
+dkT("\tswitches to long (detailed) listings for users, groups, and"),
+dkT("\tprinters command."),
+dkT(""),
+dkT("-d <device>"),
+dkT("\tchooses the printer for the print command."),
+dkT(""),
+dkT("EXIT STATUS"),
+dkT(""),
+dkT("0 on success, all other exit status codes indicate an error."),
+dkT(""),
+dkT("FILES"),
+dkT(""),
+dkT("dkwt.conf"),
+dkT("\tThe dkwt.conf file is used to configure automatic cleanup for the boot,"),
+dkT("\tlogin, logout, shutdown, and cleanup-profiles command."),
+dkT("\tThe file should be placed in \"C:\\Program Files\\Krause\\etc\\dktools-site\""),
+dkT("\tor \"C:\\Program Files (x86)\\Krause\\etc\\dktools-site\" depending on your"),
+dkT("\tWindows version (32 or 64 bit)."),
+dkT("\tThe file consists of three sections: \"options\", \"public\", and"),
+dkT("\t\"profiles\"."),
+dkT(""),
+dkT("\tIn the options section you can configure the name for the \"System\""),
+dkT("\tand \"Everyone\" account, the name differs depending on the language"),
+dkT("\tconfigured for your system. These settings are optional, the program"),
+dkT("\tretrieves the names for SIDs \"S-1-5-18\" and \"S-1-1-0\" if the settings"),
+dkT("\tare omitted."),
+dkT(""),
+dkT("\tIn the public section you can list public writable directories to"),
+dkT("\tbe cleaned up automatically."),
+dkT(""),
+dkT("\tIn the start of the profiles section you configure the profile base"),
+dkT("\tdirectory (the parent directory where the profile directories live in)."),
+dkT("\tEach section line lists one directory to be left untouched by"),
+dkT("\tautomatic cleanup."),
+dkT("\tNOTE: On Windows 7 I do not recommend to manage user profile directories"),
+dkT("\tusing dkwt. Use the group policy configured in gpedit.msc to remove"),
+dkT("\texpired user profiles instead. Just omit the \"[profiles...]\" section."),
+dkT(""),
+dkT("\tExample:"),
+dkT(""),
+dkT("\t\t[options]"),
+dkT("\t\tsystem user\t=\tSystem"),
+dkT("\t\teveryone user\t=\tEveryone"),
+dkT(""),
+dkT("\t\t[public]"),
+dkT("\t\tc:\\temp"),
+dkT("\t\tc:\\lecture"),
+dkT(""),
+dkT("\t\t[profiles C:\\Users]"),
+dkT("\t\tAll Users"),
+dkT("\t\tDefault User"),
+dkT("\t\tPublic"),
+dkT("\t\tAdministrator"),
+dkT("\t\tadmin"),
+dkT("\t\tsshd_server"),
+dkT(""),
+dkT("NOTES"),
+dkT(""),
+dkT("The boot, login, logout, shutdown, and cleanup-profiles commands are"),
+dkT("intended for use in computer classrooms and other educational environments."),
+dkT("We assume the following:"),
+dkT("- User accounts are managed centrally, i.e. in AD or a Windows domain."),
+dkT(" There is only a few local accounts on each system required by the Windows"),
+dkT(" system itself or by services running."),
+dkT("- Each \"normal\" user has a home directory on a file server."),
+dkT("- Typically all users in a class room log in and out nearly at the same time"),
+dkT(" (begin and end of a lecture)."),
+dkT("For the following reasons we do not store user profiles on a file server:"),
+dkT("- Large parts of the user profile are not related to the lectures, saving"),
+dkT(" them on a file server would be waste of disk space."),
+dkT(" Although Windows allows you to exclude profile subdirectories from"),
+dkT(" profile replication we don't want to use this feature. Blacklist mechanisms"),
+dkT(" require research for new directories to exclude after each software"),
+dkT(" installation or update."),
+dkT("- Due to the simultaneous login and logout of all users there would be"),
+dkT(" load peaks on server and networks on begin and end of lectures significantly"),
+dkT(" higher than average load."),
+dkT("So we use a setup as follows:"),
+dkT("- In the group policies we allow local user profiles only, profile"),
+dkT(" synchronization or propagation to the server is disabled."),
+dkT("- During the lectures users write data to a public writable directory, i.e."),
+dkT(" C:\\Temp or C:\\Lecture. At the end of the lecture they save valuable data"),
+dkT(" to the home directory or to private storage media (i.e. USB device)."),
+dkT(" After saving the data the users deletes all contents he created in the"),
+dkT(" public writable directory."),
+dkT("- During logout a logout script is run. This script first changes the"),
+dkT(" permissions to all contents still found in the public writable directories"),
+dkT(" to grant full access for everyone. Next it attempts to remove the contents."),
+dkT(" The same is done for the users home directory."),
+dkT("- Not all contents can be deleted during logout as some files still might be"),
+dkT(" in use (i.e. the HKCU registry hive file in the user profile). So we attempt"),
+dkT(" to delete these contents again at the next users login, at shutdown and"),
+dkT(" at next reboot."),
+dkT("To have this cleanup automatically we add"),
+dkT(" dkwt boot"),
+dkT("to the system boot script,"),
+dkT(" dkwt login"),
+dkT("to the user login script,"),
+dkT(" dkwt logout"),
+dkT("to the user logout script, and"),
+dkT(" dkwt shutdown"),
+dkT("to the system shutdown script."),
+dkT(""),
+dkT("On Windows Vista and above the boot, login, logout, and shutdown commands"),
+dkT("do not attempt to clean up user profiles. Login scripts here do not"),
+dkT("have sufficient permissions to clean up. You can start the command"),
+dkT("prompt as administrator and run \"dkwt cleanup-profiles\" manually instead."),
+dkT(""),
+dkT("Lectures about system programming (i.e. \"How do I build a driver?\") need a"),
+dkT("special setup. When testing self-made system software the system may crash"),
+dkT("or hang, so a reboot with a new login will be necessary."),
+dkT("We need to deactivate the automatic cleanup, otherwise all changes we made"),
+dkT("in the public writable directories would be lost."),
+dkT("Before starting experiments we run"),
+dkT(" dkwt keep"),
+dkT("to disable automatic cleanup temporarily until the next user login is finished."),
+dkT("If all experiments succeeded we can run"),
+dkT(" dkwt unkeep"),
+dkT("after saving all our changes before logging off."),
+dkT("The HKEY_LOCAL_MACHINE\\SOFTWARE\\DKrause\\Shared\\dkwt must exist, full access"),
+dkT("must be possible for \"Everyone\" or \"INTERACTIVE\"."),
+dkT(""),
+dkT("AUTHOR"),
+dkT(""),
+dkT("Dirk Krause"),
+dkT(""),
+dkT("HISTORY"),
+dkT(""),
+dkT("COPYRIGHT AND LICENSE"),
+dkT(""),
+dkT("Run"),
+dkT(" dkwt --license-terms"),
+dkT("to see the license conditions."),
+dkT(""),
+dkT("SEE ALSO"),
+dkT(""),
+dkT("http://dktools.sourceforge.net"),
+dkT(""),
+NULL
+
+
+#line 1651 "dkwt.ctr"
+};
+
+
+
+/** Application group name.
+*/
+static dkChar const dkwt_group_name[] = { dkT("dktools") };
+
+
+
+/** Print help text.
+ @param app Application structure.
+ @param msg Array containing localized texts.
+ @param noloc Array containing non-localized texts.
+ @param topic Help topic ID.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkwt_help(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *noloc,
+ int topic
+)
+{
+ switch(topic) {
+ case 0: {
+ dk3app_help(app, dkwt_help_file_names[topic], dkwt_help_boot);
+ } break;
+ case 1: {
+ dk3app_help(app, dkwt_help_file_names[topic], dkwt_help_shutdown);
+ } break;
+ case 2: {
+ dk3app_help(app, dkwt_help_file_names[topic], dkwt_help_login);
+ } break;
+ case 3: {
+ dk3app_help(app, dkwt_help_file_names[topic], dkwt_help_logout);
+ } break;
+ case 4: {
+ dk3app_help(app, dkwt_help_file_names[topic], dkwt_help_users);
+ } break;
+ case 5: {
+ dk3app_help(app, dkwt_help_file_names[topic], dkwt_help_groups);
+ } break;
+ case 6: {
+ dk3app_help(app, dkwt_help_file_names[topic], dkwt_help_printers);
+ } break;
+ case 7: {
+ dk3app_help(app, dkwt_help_file_names[topic], dkwt_help_print);
+ } break;
+ case 8: {
+ dk3app_help(app, dkwt_help_file_names[topic], dkwt_help_help);
+ } break;
+ case 11: {
+ dk3app_help(app, dkwt_help_file_names[topic], dkwt_help_keep);
+ } break;
+ case 12: {
+ dk3app_help(app, dkwt_help_file_names[topic], dkwt_help_unkeep);
+ } break;
+ case 21: case 22: {
+ dk3app_help(app, dkwt_help_file_names[13], dkwt_help_clp);
+ } break;
+ case 23: case 24: {
+ dk3app_help(app, dkwt_help_file_names[14], dkwt_help_env);
+ } break;
+ }
+ return 0;
+}
+
+
+
+/** The main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, any other value indicates an error.
+*/
+DK3_MAIN
+{
+ int exval = DKT_RESULT_ERR_UNSPECIFIC;
+ dk3_app_t *app = NULL;
+ dkChar const * const *msg = NULL;
+ int xargc = 0;
+ int topic = 0;
+ dkChar const * const *xargv = NULL;
+
+
+#line 1737 "dkwt.ctr"
+
+
+#line 1738 "dkwt.ctr"
+ if((sizeof(dkChar) != 2) || (sizeof(TCHAR) != 2)) {
+ fprintf(stderr, "Wrong compiler options were used to build this program!\n");
+ fprintf(stderr, "Size of dkChar: %u\n", (unsigned)sizeof(dkChar));
+ fprintf(stderr, "Size of TCHAR: %u\n", (unsigned)sizeof(TCHAR));
+ fprintf(stderr, "Please re-compile with -DDK3_CHAR_SIZE=2 -D_UNICODE=1\n");
+ fflush(stderr);
+ exit(DKT_RESULT_ERR_UNSPECIFIC);
+ }
+ app = dk3app_open_command(
+ argc, (dkChar const * const *)argv, dkwt_group_name
+ );
+ if(app) {
+ msg = dk3app_messages(
+ app, dkwt_string_table_file_name, (dkChar const **)dkwt_message_texts
+ );
+ xargc = dk3app_get_argc(app);
+ xargv = dk3app_get_argv(app);
+ if(xargc > 1) {
+ switch(dk3str_array_index(dkwt_commands, xargv[1], 0)) {
+ case 0: {
+
+#line 1758 "dkwt.ctr"
+ exval = dkwt_event(app, msg, dkwt_no_loc, 0);
+ } break;
+ case 1: {
+
+#line 1761 "dkwt.ctr"
+ exval = dkwt_event(app, msg, dkwt_no_loc, 1);
+ } break;
+ case 2: {
+
+#line 1764 "dkwt.ctr"
+ exval = dkwt_event(app, msg, dkwt_no_loc, 2);
+ } break;
+ case 3: {
+
+#line 1767 "dkwt.ctr"
+ exval = dkwt_event(app, msg, dkwt_no_loc, 3);
+ } break;
+ case 4: {
+
+#line 1770 "dkwt.ctr"
+ exval = dkwt_accounts(app, msg, dkwt_no_loc);
+ } break;
+ case 5: {
+ exval = dkwt_groups(app, msg, dkwt_no_loc);
+ } break;
+ case 6: {
+ exval = dkwt_printers(app, msg, dkwt_no_loc);
+ } break;
+ case 7: {
+ exval = dkwt_print(app, msg, dkwt_no_loc);
+ } break;
+ case 8: case 13: case 18: {
+ topic = 8;
+ if(xargc > 2) {
+ topic = dk3str_array_index(dkwt_commands, xargv[2], 0);
+ if(topic < 0) topic = 8;
+ }
+ exval = dkwt_help(app, msg, dkwt_no_loc, topic);
+ } break;
+ case 9: case 14: case 19: { /* version */
+ dk3sf_initialize_stdout();
+ dk3sf_fputs(dkwt_version, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ } break;
+ case 10: case 15: case 16: case 17: case 20: { /* license */
+ dkChar const * const *sptr;
+ sptr = dkwt_license;
+ dk3sf_initialize_stdout();
+ while(*sptr) {
+ dk3sf_fputs(*(sptr++), stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ } break;
+ case 11: {
+ exval = dkwt_event_keep(app, msg, dkwt_no_loc);
+ } break;
+ case 12: {
+ exval = dkwt_event_unkeep(app, msg, dkwt_no_loc);
+ } break;
+ case 21: case 22: {
+ exval = dkwt_event(app, msg, dkwt_no_loc, 4);
+ } break;
+ case 23: case 24: {
+ exval = dkwt_env(app, msg, dkwt_no_loc);
+ } break;
+ }
+ }
+ dk3app_close(app);
+ } else {
+ fprintf(stderr, "ERROR: Not enough memory!\n");
+ fflush(stderr);
+ }
+
+
+#line 1823 "dkwt.ctr"
+
+
+#line 1824 "dkwt.ctr"
+ fflush(stdout);
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/dkwt.ctr b/support/dktools/dkwt.ctr
new file mode 100644
index 0000000000..1404208a77
--- /dev/null
+++ b/support/dktools/dkwt.ctr
@@ -0,0 +1,1827 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk3all.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4vers.h"
+#include "dkt.h"
+#include "dkwt.h"
+
+
+
+$!trace-include
+
+
+
+/** File name for string table file.
+*/
+static dkChar const dkwt_string_table_file_name[] = { dkT("dkwt.str") };
+
+
+
+/** Version number string.
+*/
+static dkChar const dkwt_version[] = {
+dkT("dkwt ") DKT_VERSION_DK
+};
+
+
+
+/** License terms.
+*/
+static dkChar const * const dkwt_license[] = {
+$!text macro=dkT
+
+Copyright (c) 2011-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms,
+with or without modification, are permitted provided
+that the following conditions are met:
+
+* Redistributions of source code must retain the above
+ copyright notice, this list of conditions and the
+ following disclaimer.
+* Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials
+ provided with the distribution.
+* Neither the name of the copyright holder(s) nor the names of
+ contributors may be used to endorse or promote
+ products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+
+$!end
+};
+
+
+
+/** Message texts used by the program, localized.
+*/
+static dkChar const * const dkwt_message_texts[] = {
+$!string-table macro=dkT
+#
+# 0: Attribute label: FUll user name
+#
+Full name:
+#
+# 1: Attribute label: Comment for user
+#
+Comment:
+#
+# 2: Attribute label: User comment
+#
+User comment:
+#
+# 3: Attribute label: HOme directory
+#
+Home directory:
+#
+# 4: Attribute label: User profile directory
+#
+User profile:
+#
+# 5: Attribute label: User SID
+#
+SID:
+#
+# 6: Attribute label: User type
+#
+Type:
+#
+# 7: User type: guest
+#
+Guest
+#
+# 8: User type: Normal user
+#
+User
+#
+# 9: User type: Administrator
+#
+Administrator
+#
+# 10: Attribute label: User flags.
+#
+Flags:
+#
+# 11: Account attribute: Login script executed
+#
+Login script executed.
+#
+# 12: Account attribute: Account disabled
+#
+Account disabled.
+#
+# 13: Account attribute: Home directory required
+#
+Home directory required.
+#
+# 14: Account attribute: No password required
+#
+No password required.
+#
+# 15: Account attribute: Password can not be changed
+#
+Password can not be changed.
+#
+# 16: Account attribute: Locked out
+#
+Account locked out.
+#
+# 17: Account attribute: Password does not expire
+#
+Password does not expire.
+#
+# 18: Account attribute: Encrypted text password allowd
+#
+Encrypted text password allowed.
+#
+# 19: Account attribute: Account is sensitive, no delegation
+#
+Sensitive account, no delegation.
+#
+# 20: Account attribute: Smartcard required
+#
+Smartcard required.
+#
+# 21: Account attribute: DES keys are allowed only
+#
+DES keys only.
+#
+# 22: Account attribute: No Kerberos pre-auth required
+#
+No Kerberos pre-authentication required.
+#
+# 23: Account attribute: Account is trusted for delegation
+#
+Trusted for delegation.
+#
+# 24: Account attribute: Password is expired
+#
+Password expired.
+#
+# 25: Account attribute: Trusted to authenticate for delegation
+#
+Trusted to authenticate for delegation.
+#
+# 26: Account type: Normal user account
+#
+Normal user account.
+#
+# 27: Account type: Duplicated account for user from other domain
+#
+Duplicated account for user from another domain.
+#
+# 28: Account type: Workstation trust account
+#
+Workstation trust account.
+#
+# 29: Account type: Server trust account
+#
+Server trust account.
+#
+# 30: Account type: Interdomain trust account
+#
+Interdomain trust account.
+#
+# 31: Empty string
+#
+
+#
+# 32: Operator privileges label
+#
+Operator:
+#
+# 33: Operator type: Accounts operator
+#
+Accounts operator.
+#
+# 34: Operator type: Server operator
+#
+Server operator.
+#
+# 35: Operator type: Communications operator
+#
+Communications operator.
+#
+# 36: Operator type: Print operator
+#
+Print operator.
+#
+# 37: Attribute label: Country code
+#
+Country code:
+#
+# 38: Attribute label: Code page number
+#
+Code page no.:
+#
+# 39: Attribute label: Source
+#
+Source:
+#
+# 40: Attribute label: Comment
+#
+Comment:
+#
+# 41: Source type: Net
+#
+Net
+#
+# 42: Source type: Local
+#
+Local
+#
+# 43: Attribute label: SID
+#
+SID:
+#
+# 44: Attribute label: Comment
+#
+Comment:
+#
+# 45: Attribute label: Description
+#
+Description:
+#
+# 46: Attribute label: Location
+#
+Location:
+#
+# 47: Attribute label: Server
+#
+Server:
+#
+# 48: Attribute label: Share name
+#
+Share name:
+#
+# 49: Attribute label: Port
+#
+Port:
+#
+# 50: Attribute label: Driver
+#
+Driver:
+#
+# 51: Attribute label: Device
+#
+Device:
+#
+# 52: Attribute label: Separator file
+#
+Separator file:
+#
+# 53: Attribute label: Print processor
+#
+Print processor:
+#
+# 54: Attribute label: Data type
+#
+Data type:
+#
+# 55: Attribute label: Parameters
+#
+Parameters:
+#
+# 56/57: Error message: Failed to create print file "..."!
+#
+Failed to create print file "
+"!
+#
+# 58: Error message: Failed to schedule print job!
+#
+Failed to schedule print job!
+#
+# 59: Error message: Failed to add print job!
+#
+Failed to add print job!
+#
+# 60/61: Error message: Failed to open printer "..."!
+#
+Failed to open printer "
+"!
+#
+# 62: Error message: Printer name too long!
+#
+Printer name too long!
+#
+# 63/64: Error message: No printer found for device "..."!
+#
+No printer found for device "
+"!
+#
+# 65: Error message: Failed to find default printer!
+#
+Failed to find default printer!
+#
+# 66: Error message: Redefinition of profile base directory!
+#
+Redefinition of profile base directory!
+#
+# 67: Error message: No profile base directory specified!
+#
+No profile base directory specified!
+#
+# 68: Error message: Syntax - Unknown section type!
+#
+Syntax error - Unknown section type!
+#
+# 69: Error message: Syntax - Incomplete section header!
+#
+Syntax error - Incomplete section header!
+#
+# 70: Error message: Syntax - Missing section header!
+#
+Syntax error - Missing section header!
+#
+# 71: Error message: Syntax - Redefinition of system user!
+#
+Syntax error - Redefinition of system user!
+#
+# 72: Error message: Syntax - Redefinition of everyone user!
+#
+Syntax error - Redefinition of everyone user!
+#
+# 73: Error message: Syntax - Unknown option!
+#
+Syntax error - Unknown option!
+#
+# 74: Error message: Syntax - Not a key/value pair!
+#
+Syntax error - Not a key/value pair!
+#
+# 75: Error message: Options -l and -s are exclusive!
+#
+Options -l and -s are exclusive!
+#
+# 76: Error message: Arguments are ignored!
+#
+Arguments are ignored!
+#
+# 77: Error message: Failed to set keep-data flag.
+#
+FAILED TO SET KEEP-DATA FLAG!
+#
+# 78: Notice: Keep-data flag was set successfully.
+#
+Keep-data flag was set successfully.
+#
+# 79/80: Execution of "..." indicated an error!
+#
+Exit status code indicates an error, program:\n"
+
+#
+# 81/82: Error: Failed to find name for SID "..."!
+#
+Failed to find name for SID "
+"!
+#
+# 83/84: Progress: Cleaning up local print queue ... .
+#
+Cleaning up local print queue "
+".
+#
+# 85/86/87: Progress: Successfully deleted job ...: "...".
+#
+Successfully deleted job
+: "
+".
+#
+# 88: Unnamed print job
+#
+Unnamed print job
+#
+# 89/90/91: Error: Failed to delete job ...: "..."!
+#
+Failed to delete job
+: "
+"!
+#
+# 92/93: Error: Failed to open printer ...!
+#
+Failed to open printer "
+"!
+#
+# 94: Error: Failed to enumerate local printers!
+#
+Failed to enumerate local printers!
+#
+# 95: Error: Missing user name!
+#
+Missing user name!
+#
+# 96: Progress: Print queue cleaned up successfully.
+#
+Print queue cleaned up successfully.
+#
+# 97: ERROR: Failed to send request!
+#
+Failed to send request!
+#
+# 98: ERROR: Failed to connect to remote host!
+#
+Failed to connect to remote host!
+#
+# 99: ERROR: Failed to create network socket!
+#
+Failed to create network socket!
+#
+# 100: ERROR: Failed to find IP address!
+#
+Failed to find IP address for remote host!
+#
+# 101/102: Progress: Cleaning up remote print queue ...
+#
+Cleaning up remote print queue "
+".
+#
+# 103: ERROR: Request too long for buffer!
+#
+Request too long for buffer!
+#
+# 104/105: ERROR: Empty queue name in "..."!
+#
+Empty queue name in "
+"!
+#
+# 106/107: ERROR: Empty host name in "..."!
+#
+Empty host name in "
+"!
+#
+# 108/109: ERROR: Not a queue@host name: "..."!
+#
+Not a queue@host name: "
+"!
+#
+# 110/111: ERROR: Queue name "..." too long!
+#
+Queue name "
+" too long!
+#
+# 112: ERROR: Failed to initialize Windows sockets!
+#
+Failed to initialize Windows sockets!
+#
+# 113/114: Error: Error code: ...
+#
+Error code:
+.
+#
+# 115/116: IP address: ...
+#
+IP address:
+.
+#
+# 117: Warning: User profile cleanup is disabled on Windows Vista and above!
+#
+User profile cleanup is disabled on Windows Vista and above!
+#
+# 118/119: Progress: Executing command: ...
+#
+Executing command:\n
+
+#
+# 120/121: Progress: Remove directory: ...
+#
+Remove directory:\n
+
+#
+# 122/123: Progress: Remove file: ...
+#
+Remove file:\n
+
+#
+# 124/125/126: Progress: Delete Registry key ...
+#
+Delete registry key:\n
+\\
+
+#
+# 127/128: DEBUG: Registry key "..." deleted.
+#
+Registry key "
+" deleted.
+#
+# 129/130/131: ERROR: Failed to remove registry key:
+#
+Failed to remove registry key:\n
+\\
+
+#
+# 132/133
+#
+Failed to open registry key:\n
+
+#
+# 134
+#
+Cleaning up profiles (start).
+#
+# 135
+#
+Internal error while retrieving directory entry name!
+#
+# 136/137
+#
+Failed to expand string\n"
+",\nresult would become too long for buffer!
+#
+# 138/139
+#
+Subkey name too long:\n
+
+#
+# 140
+#
+Skipping profile cleanup due to previous errors!
+#
+# 141
+#
+Cleaning up profiles (finished).
+#
+# 142
+#
+Options -u, -i, -a, and -d are mutually exlusive!
+#
+# 143
+#
+At least one argument required!
+#
+# 144
+#
+Missing file/directory name!
+#
+# 145
+#
+Administrative privileges are required!
+#
+# 146
+#
+Administrative privileges are required to modify system environment!
+$!end
+};
+
+
+
+/** Keywords used by the program, not localized.
+*/
+static dkChar const * const dkwt_no_loc[] = {
+$!string-table macro=dkT
+#
+# 0
+#
+
+#
+# 1
+#
+dkwt.conf
+#
+# 2
+#
+System
+#
+# 3
+#
+Jeder
+#
+# 4
+#
+RD /S /Q "
+#
+# 5
+#
+"
+#
+# 6
+#
+DEL /Q /F "
+#
+# 7
+#
+CACLS.EXE "
+#
+# 8
+#
+" /T /E /C /G
+#
+# 9
+#
+:F
+#
+# 10
+#
+ICACLS.EXE "
+#
+# 11
+#
+" /grant
+#
+# 12
+#
+:F /T /C /Q
+#
+# 13
+#
+:F /C /Q
+#
+# 14
+#
+" /E /C /G
+#
+# 15: Registry key name
+#
+SOFTWARE\\DKrause\\Shared\\dkwt
+#
+# 16: Registry value name: keep (for keep-directories flag)
+#
+keep
+#
+# 17: Text SID for Everyone user/group
+#
+S-1-1-0
+#
+# 18: Text SID for SYSTEM user/group
+#
+S-1-5-18
+#
+# 19: Registry key for profile list.
+#
+SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList
+#
+# 20: Backslash as separator.
+#
+\\
+#
+# 21: Registry enty name.
+#
+ProfileImagePath
+$!end
+};
+
+
+
+/** Subcommand names.
+*/
+static dkChar const * const dkwt_commands[] = {
+/* 0 */ dkT("boot"),
+/* 1 */ dkT("shutdown"),
+/* 2 */ dkT("login"),
+/* 3 */ dkT("logout"),
+/* 4 */ dkT("users"),
+/* 5 */ dkT("groups"),
+/* 6 */ dkT("printers"),
+/* 7 */ dkT("print"),
+/* 8 */ dkT("help"),
+/* 9 */ dkT("version"),
+/* 10 */ dkT("license-terms"),
+/* 11 */ dkT("keep"),
+/* 12 */ dkT("unkeep"),
+/* 13 */ dkT("--help"),
+/* 14 */ dkT("--version"),
+/* 15 */ dkT("--license-terms"),
+/* 16 */ dkT("--license"),
+/* 17 */ dkT("license"),
+/* 18 */ dkT("-h"),
+/* 19 */ dkT("-v"),
+/* 20 */ dkT("-L"),
+/* 21 */ dkT("cleanup-profiles"),
+/* 22 */ dkT("clp"),
+/* 23 */ dkT("env"),
+/* 24 */ dkT("environment"),
+NULL
+};
+
+
+
+/** Help file names.
+*/
+static dkChar const * const dkwt_help_file_names[] = {
+/* 0 */ dkT("dkwt-boot.txt"),
+/* 1 */ dkT("dkwt-shutdown.txt"),
+/* 2 */ dkT("dkwt-login.txt"),
+/* 3 */ dkT("dkwt-logout.txt"),
+/* 4 */ dkT("dkwt-users.txt"),
+/* 5 */ dkT("dkwt-groups.txt"),
+/* 6 */ dkT("dkwt-printers.txt"),
+/* 7 */ dkT("dkwt-print.txt"),
+/* 8 */ dkT("dkwt-help.txt"),
+/* 9 */ dkT(""), /* unused */
+/* 10 */ dkT(""), /* unused */
+/* 11 */ dkT("dkwt-keep.txt"),
+/* 12 */ dkT("dkwt-unkeep.txt"),
+/* 13 */ dkT("dkwt-clp.txt"),
+/* 14 */ dkT("dkwt-env.txt"),
+NULL
+};
+
+
+
+/** Help text for the boot command.
+*/
+static dkChar const * const dkwt_help_boot[] = {
+$!text macro=dkT
+
+NAME
+
+ dkwt boot - Boot cleanup
+
+SYNOPSIS
+
+ dkwt boot [-t]
+
+DESCRIPTION
+
+The "dkwt boot" program should be run from the system boot script to do
+cleanup at boot time in PC classrooms.
+
+OPTIONS
+
+-t
+ Test mode. The program does not perform cleanup, it only writes
+ messages about files and directories to delete.
+
+EXIT STATUS
+
+The exit status code is always 0, regardless of any error occured.
+
+FILES
+
+dkwt.conf
+ Configuration file for cleanup operations.
+
+ Run
+ dkwt -h
+ to view detailed information about the dkwt.conf file.
+
+NOTES
+
+After changing the dkwt.conf file you should run
+ dkwt boot -t
+to test the dkwt.conf file.
+
+AUTHOR
+
+Dirk Krause
+
+COPYRIGHT AND LICENSE
+
+Run
+ dkwt --license-terms
+to see the license conditions.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
+$!end
+};
+
+
+
+/** Help text for the shutdown command.
+*/
+static dkChar const * const dkwt_help_shutdown[] = {
+$!text macro=dkT
+
+NAME
+
+ dkwt shutdown - Shutdown cleanup
+
+SYNOPSIS
+
+ dkwt shutdown [-t]
+
+DESCRIPTION
+
+The "dkwt shutdown" program should be run from the system shutdown script to do
+cleanup at shutdown time in PC classrooms.
+
+OPTIONS
+
+-t
+ runs in test mode. The program does not perform cleanup, it only writes
+ messages about files and directories to delete.
+
+EXIT STATUS
+
+The exit status code is always 0, regardless of any error occured.
+
+FILES
+
+dkwt.conf
+ Configuration file for cleanup operations.
+ Run
+ dkwt -h
+ to view detailed information about the dkwt.conf file.
+
+NOTES
+
+After changing the dkwt.conf file you should run
+ dkwt shutdown -t
+to test the dkwt.conf file.
+
+AUTHOR
+
+Dirk Krause
+
+COPYRIGHT AND LICENSE
+
+Run
+ dkwt --license-terms
+to see the license conditions.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
+$!end
+};
+
+
+
+/** Help text for the login command.
+*/
+static dkChar const * const dkwt_help_login[] = {
+$!text macro=dkT
+
+NAME
+
+ dkwt login - Login cleanup
+
+SYNOPSIS
+
+ dkwt login [-t]
+
+DESCRIPTION
+
+The "dkwt login" program should be run from the user login script to do
+cleanup at login time in PC classrooms.
+
+OPTIONS
+
+-t
+ runs in test mode. The program does not perform cleanup, it only writes
+ messages about files and directories to delete.
+
+EXIT STATUS
+
+The exit status code is always 0, regardless of any error occured.
+
+FILES
+
+dkwt.conf
+ Configuration file for cleanup operations.
+ Run
+ dkwt -h
+ to view detailed information about the dkwt.conf file.
+
+NOTES
+
+After changing the dkwt.conf file you should run
+ dkwt login -t
+to test the dkwt.conf file.
+
+AUTHOR
+
+Dirk Krause
+
+COPYRIGHT AND LICENSE
+
+Run
+ dkwt --license-terms
+to see the license conditions.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
+$!end
+};
+
+
+
+/** Help text for the logout command.
+*/
+static dkChar const * const dkwt_help_logout[] = {
+$!text macro=dkT
+
+NAME
+
+ dkwt logout - Logout cleanup
+
+SYNOPSIS
+
+ dkwt logout [-t]
+
+DESCRIPTION
+
+The "dkwt logout" program should be run from the user logout script to do
+cleanup at logout time in PC classrooms.
+
+OPTIONS
+
+-t
+ runs in test mode. The program does not perform cleanup, it only writes
+ messages about files and directories to delete.
+
+EXIT STATUS
+
+The exit status code is always 0, regardless of any error occured.
+
+FILES
+
+dkwt.conf
+ Configuration file for cleanup operations.
+ Run
+ dkwt -h
+ to view detailed information about the dkwt.conf file.
+
+NOTES
+
+After changing the dkwt.conf file you should run
+ dkwt logout -t
+to test the dkwt.conf file.
+
+AUTHOR
+
+Dirk Krause
+
+COPYRIGHT AND LICENSE
+
+Run
+ dkwt --license-terms
+to see the license conditions.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
+$!end
+};
+
+
+
+/** Help text for the keep command.
+*/
+static dkChar const * const dkwt_help_keep[] = {
+$!text macro=dkT
+
+NAME
+
+ dkwt keep - Temporarily disable automatic cleanup
+
+SYNOPSIS
+
+ dkwt keep
+
+DESCRIPTION
+
+Use this program to disable automatic cleanup until (including) the next
+user login.
+You should use this command in lectures about system programming before
+starting to test self-made system software, drivers...
+Use the
+ dkwt unkeep
+command to restore normal automatic cleanup when you are done with the tests.
+
+EXIT STATUS
+
+0 on success, all other exit status codes indicate an error.
+
+REGISTRY
+
+The HKEY_LOCAL_MACHINE\SOFTWARE\DKrause\Shared\dkwt must exist, full access
+must be possible for "Everyone" or "INTERACTIVE".
+
+AUTHOR
+
+Dirk Krause
+
+COPYRIGHT AND LICENSE
+
+Run
+ dkwt --license-terms
+to see the license conditions.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
+$!end
+};
+
+
+
+/** Help text for the keep command.
+*/
+static dkChar const * const dkwt_help_unkeep[] = {
+$!text macro=dkT
+
+NAME
+
+ dkwt unkeep - Restore automatic cleanup
+
+SYNOPSIS
+
+ dkwt unkeep
+
+DESCRIPTION
+
+After disabling automatic cleanup temporarily using "dkwt keep" you can use
+this command to restore normal automatic cleanup.
+
+EXIT STATUS
+
+0 on success, all other exit status codes indicate an error.
+
+REGISTRY
+
+The HKEY_LOCAL_MACHINE\SOFTWARE\DKrause\Shared\dkwt must exist, full access
+must be possible for "Everyone" or "INTERACTIVE".
+
+AUTHOR
+
+Dirk Krause
+
+COPYRIGHT AND LICENSE
+
+Run
+ dkwt --license-terms
+to see the license conditions.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
+$!end
+};
+
+
+/** Help text for the cleanup-profiles command.
+*/
+static dkChar const * const dkwt_help_clp[] = {
+$!text macro=dkT
+
+NAME
+
+ dkwt cleanup-profiles - Clean up profiles directories.
+
+SYNOPSIS
+
+ dkwt cleanup-profiles
+ dkwt clp
+
+DESCRIPTION
+
+On Windows Vista and above we can not clean up profile directories
+from boot/shutdown/logon/logoff scripts as these scripts are run from
+a user account with insufficient permissions. User profiles cleanup
+is skipped in "dkwt boot", "dkwt login", "dkwt logout", and "dkwt shutdown".
+
+You can start a command prompt *as administrator* instead and run
+"dkwt cleanup-profiles" from there.
+The program first attempts to use system functions to delete
+directories, additionally it uses the "RD" command.
+
+Alternatively run "dkwtadm cleanup-profiles", this variant of dkwt uses
+the UAC to obtain administrative permissions.
+
+EXIT STATUS
+
+0 on success, all other exit status codes indicate an error.
+
+AUTHOR
+
+Dirk Krause
+
+HISTORY
+
+COPYRIGHT AND LICENSE
+
+Run
+ dkwt --license-terms
+to see the license conditions.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
+$!end
+};
+
+
+
+/** Help text for dkwt env.
+*/
+static dkChar const * const dkwt_help_env[] = {
+$!text macro=dkT
+
+NAME
+
+ dkwt env - Modify environment variables
+
+SYNOPSIS
+
+ dkwt env [<options>] <name> [<value>]
+ dkwt environment [<options>] <name> [<value>]
+
+DESCRIPTION
+
+This function can modify environment variables, both system and
+user variables.
+This function is mainly intended for environment variables storing
+names of directories or files (i.e. the PATH variable).
+You can make sure a directory is listed in a variable by inserting
+or appending the directory only if it is not yet present.
+
+OPTIONS
+
+-s
+ Process system environment variables.
+ Without this option the program processes the user environment.
+
+-e
+ When creating a new registry value, use type REG_EXPAND_SZ
+ instead of default REG_SZ.
+ This option is ignored when processing existing registry values.
+
+-u
+ Delete registry value completely, unset variable.
+
+-i
+ Ensure the variable lists the specified directory or file,
+ insert at start if not present.
+
+-a
+ Ensure the variable lists the specified directory or file,
+ append at end if not present.
+
+-d
+ Remove a directory or file from a variable listing one
+ or multiple directories or files.
+ If the variable value is empty after removal, the registry
+ value is deleted.
+
+EXIT STATUS
+
+0 on success, all other exit status codes indicate an error.
+
+EXAMPLES
+
+Show value of user environment variable TEMP:
+
+ dkwt env TEMP
+
+Show value of system environment variable PATH:
+
+ dkwt env -s PATH
+
+Completely delete user environment variable FOO:
+
+ dkwt env -u FOO
+
+Completely delete system environment variable BAR:
+
+ dkwt env -s -u BAR
+
+Set user environment variable FOO:
+
+ dkwt env FOO All text after variable name goes into value
+
+Set system environment variable BAR:
+
+ dkwt env -s BAR Same procedure for system variables
+
+Make sure system PATH contains ``C:\Program Files\Nice Program''
+(insert at start if not present):
+
+ dkwt env -s -i Path C:\Program Files\Nice Program
+
+Make sure system PATH contains ``C:\Program Files\Other Program''
+(append at end if not present):
+
+ dkwt env -s -a Path C:\Program Files\Other Program
+
+Remove ``C:\Program Files\Nice Program'' from system PATH:
+
+ dkwt env -s -d Path C:\Program Files\Nice Program
+
+NOTES
+
+``dkwt env'' does not change environment variables in cmd.exe windows
+already opened.
+
+AUTHOR
+
+Dirk Krause
+
+HISTORY
+
+COPYRIGHT AND LICENSE
+
+Run
+ dkwt --license-terms
+to see the license conditions.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
+$!end
+};
+
+
+
+/** Help text for the users command.
+*/
+static dkChar const * const dkwt_help_users[] = {
+$!text macro=dkT
+
+NAME
+
+ dkwt users - List users
+
+SYNOPSIS
+
+ dkwt users [<option>]
+
+DESCRIPTION
+
+The program lists the users configured on the system.
+
+OPTIONS
+
+-l
+ creates a long (detailed) listing.
+
+-s
+ creates a short listing (just the user names).
+
+Either -l or -s can be used, not both.
+
+EXIT STATUS
+
+0 on success, all other exit status codes indicate an error.
+
+AUTHOR
+
+Dirk Krause
+
+COPYRIGHT AND LICENSE
+
+Run
+ dkwt --license-terms
+to see the license conditions.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
+$!end
+};
+
+
+
+/** Help text for the groups command.
+*/
+static dkChar const * const dkwt_help_groups[] = {
+$!text macro=dkT
+
+NAME
+
+ dkwt groups - List groups
+
+SYNOPSIS
+
+ dkwt groups <option>
+
+DESCRIPTION
+
+The command lists the group on the current system.
+
+OPTIONS
+
+-l
+ creates a long (detailed) listing.
+
+-s
+ creates aa short listing (just the group names).
+
+The options -l and -s can not be used together.
+
+EXIT STATUS
+
+0 on success, all other exit status codes indicate an error.
+
+AUTHOR
+
+Dirk Krause
+
+COPYRIGHT AND LICENSE
+
+Run
+ dkwt --license-terms
+to see the license conditions.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
+$!end
+};
+
+
+
+/** Help text for dkwt help printers.
+*/
+static dkChar const * const dkwt_help_printers[] = {
+$!text macro=dkT
+
+NAME
+
+ dkwt printers - List printers
+
+SYNOPSIS
+
+ dkwt printers [<option>]
+
+DESCRIPTION
+
+The command lists the printers installed on the system.
+
+OPTIONS
+
+-l
+ creates a long (detailed) listing. Without this option the listing
+ only shows the printer names.
+
+EXIT STATUS
+
+0 on success, all other exit status codes indicate an error.
+
+AUTHOR
+
+Dirk Krause
+
+COPYRIGHT AND LICENSE
+
+Run
+ dkwt --license-terms
+to see the license conditions.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
+$!end
+};
+
+
+/** Help text for the print command.
+*/
+static dkChar const * const dkwt_help_print[] = {
+$!text macro=dkT
+
+NAME
+
+ dkwt print - Print a file
+
+SYNOPSIS
+
+ dkwt print [<option>] [<file(s)>]
+
+DESCRIPTION
+
+The program prints the specified files or the contents read from standard
+input if no file name is specified.
+
+OPTIONS
+
+-d <device>
+ chooses a printer by the device name. The device name must be specified
+ here, not the printer name.
+ Without this option the system's default printer is used.
+
+EXIT STATUS
+
+0 on success, all other exit status codes indicate an error.
+
+AUTHOR
+
+Dirk Krause
+
+COPYRIGHT AND LICENSE
+
+Run
+ dkwt --license-terms
+to see the license conditions.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
+$!end
+};
+
+
+
+/** General help text.
+*/
+static dkChar const * const dkwt_help_help[] = {
+$!text macro=dkT
+
+NAME
+
+ dkwt - Dirk Krause's Windows tool
+
+SYNOPSIS
+
+ dkwt users [<option(s)>]
+ dkwt groups [<option(s)>]
+ dkwt printers [<option(s)>]
+ dkwt print [<option(s)>] [<file(s)>]
+ dkwt boot
+ dkwt login
+ dkwt logout
+ dkwt shutdown
+ dkwt keep
+ dkwt unkeep
+ dkwt cleanup-profiles
+ dkwt env [<options>] <name> [<value>]
+ dkwt help <command>
+ dkwt -h
+ dkwt -v
+ dkwt -L
+
+DESCRIPTION
+
+dkwt users lists the users.
+dkwt groups lists the user groups.
+dkwt printers lists the available printers.
+dkwt print prints the specified file(s).
+dkwt boot does cleanup during boot.
+dkwt login does cleanup during user login.
+dkwt logout does cleanup during user logout.
+dkwt shutdown does cleanup during shutdown.
+dkwt keep disables automatic cleanup temporarily until
+ the next user login is completed.
+dkwt unkeep restores normal cleanup mechanisms.
+dkwt cleanup-profiles cleans up user profiles.
+dkwt help <command> prints a help text for a specific command.
+dkwt -h shows this help text.
+dkwt -v shows version information.
+dkwt -L shows the license conditions.
+
+The boot, login, logout, shutdown, keep, and unkeep commands are intended for
+use in PC classrooms, see NOTES below.
+
+OPTIONS
+
+-s
+ switches to short listings for the users, and groups command.
+
+-l
+ switches to long (detailed) listings for users, groups, and
+ printers command.
+
+-d <device>
+ chooses the printer for the print command.
+
+EXIT STATUS
+
+0 on success, all other exit status codes indicate an error.
+
+FILES
+
+dkwt.conf
+ The dkwt.conf file is used to configure automatic cleanup for the boot,
+ login, logout, shutdown, and cleanup-profiles command.
+ The file should be placed in "C:\Program Files\Krause\etc\dktools-site"
+ or "C:\Program Files (x86)\Krause\etc\dktools-site" depending on your
+ Windows version (32 or 64 bit).
+ The file consists of three sections: "options", "public", and
+ "profiles".
+
+ In the options section you can configure the name for the "System"
+ and "Everyone" account, the name differs depending on the language
+ configured for your system. These settings are optional, the program
+ retrieves the names for SIDs "S-1-5-18" and "S-1-1-0" if the settings
+ are omitted.
+
+ In the public section you can list public writable directories to
+ be cleaned up automatically.
+
+ In the start of the profiles section you configure the profile base
+ directory (the parent directory where the profile directories live in).
+ Each section line lists one directory to be left untouched by
+ automatic cleanup.
+ NOTE: On Windows 7 I do not recommend to manage user profile directories
+ using dkwt. Use the group policy configured in gpedit.msc to remove
+ expired user profiles instead. Just omit the "[profiles...]" section.
+
+ Example:
+
+ [options]
+ system user = System
+ everyone user = Everyone
+
+ [public]
+ c:\temp
+ c:\lecture
+
+ [profiles C:\Users]
+ All Users
+ Default User
+ Public
+ Administrator
+ admin
+ sshd_server
+
+NOTES
+
+The boot, login, logout, shutdown, and cleanup-profiles commands are
+intended for use in computer classrooms and other educational environments.
+We assume the following:
+- User accounts are managed centrally, i.e. in AD or a Windows domain.
+ There is only a few local accounts on each system required by the Windows
+ system itself or by services running.
+- Each "normal" user has a home directory on a file server.
+- Typically all users in a class room log in and out nearly at the same time
+ (begin and end of a lecture).
+For the following reasons we do not store user profiles on a file server:
+- Large parts of the user profile are not related to the lectures, saving
+ them on a file server would be waste of disk space.
+ Although Windows allows you to exclude profile subdirectories from
+ profile replication we don't want to use this feature. Blacklist mechanisms
+ require research for new directories to exclude after each software
+ installation or update.
+- Due to the simultaneous login and logout of all users there would be
+ load peaks on server and networks on begin and end of lectures significantly
+ higher than average load.
+So we use a setup as follows:
+- In the group policies we allow local user profiles only, profile
+ synchronization or propagation to the server is disabled.
+- During the lectures users write data to a public writable directory, i.e.
+ C:\Temp or C:\Lecture. At the end of the lecture they save valuable data
+ to the home directory or to private storage media (i.e. USB device).
+ After saving the data the users deletes all contents he created in the
+ public writable directory.
+- During logout a logout script is run. This script first changes the
+ permissions to all contents still found in the public writable directories
+ to grant full access for everyone. Next it attempts to remove the contents.
+ The same is done for the users home directory.
+- Not all contents can be deleted during logout as some files still might be
+ in use (i.e. the HKCU registry hive file in the user profile). So we attempt
+ to delete these contents again at the next users login, at shutdown and
+ at next reboot.
+To have this cleanup automatically we add
+ dkwt boot
+to the system boot script,
+ dkwt login
+to the user login script,
+ dkwt logout
+to the user logout script, and
+ dkwt shutdown
+to the system shutdown script.
+
+On Windows Vista and above the boot, login, logout, and shutdown commands
+do not attempt to clean up user profiles. Login scripts here do not
+have sufficient permissions to clean up. You can start the command
+prompt as administrator and run "dkwt cleanup-profiles" manually instead.
+
+Lectures about system programming (i.e. "How do I build a driver?") need a
+special setup. When testing self-made system software the system may crash
+or hang, so a reboot with a new login will be necessary.
+We need to deactivate the automatic cleanup, otherwise all changes we made
+in the public writable directories would be lost.
+Before starting experiments we run
+ dkwt keep
+to disable automatic cleanup temporarily until the next user login is finished.
+If all experiments succeeded we can run
+ dkwt unkeep
+after saving all our changes before logging off.
+The HKEY_LOCAL_MACHINE\SOFTWARE\DKrause\Shared\dkwt must exist, full access
+must be possible for "Everyone" or "INTERACTIVE".
+
+AUTHOR
+
+Dirk Krause
+
+HISTORY
+
+COPYRIGHT AND LICENSE
+
+Run
+ dkwt --license-terms
+to see the license conditions.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
+$!end
+};
+
+
+
+/** Application group name.
+*/
+static dkChar const dkwt_group_name[] = { dkT("dktools") };
+
+
+
+/** Print help text.
+ @param app Application structure.
+ @param msg Array containing localized texts.
+ @param noloc Array containing non-localized texts.
+ @param topic Help topic ID.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkwt_help(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *noloc,
+ int topic
+)
+{
+ switch(topic) {
+ case 0: {
+ dk3app_help(app, dkwt_help_file_names[topic], dkwt_help_boot);
+ } break;
+ case 1: {
+ dk3app_help(app, dkwt_help_file_names[topic], dkwt_help_shutdown);
+ } break;
+ case 2: {
+ dk3app_help(app, dkwt_help_file_names[topic], dkwt_help_login);
+ } break;
+ case 3: {
+ dk3app_help(app, dkwt_help_file_names[topic], dkwt_help_logout);
+ } break;
+ case 4: {
+ dk3app_help(app, dkwt_help_file_names[topic], dkwt_help_users);
+ } break;
+ case 5: {
+ dk3app_help(app, dkwt_help_file_names[topic], dkwt_help_groups);
+ } break;
+ case 6: {
+ dk3app_help(app, dkwt_help_file_names[topic], dkwt_help_printers);
+ } break;
+ case 7: {
+ dk3app_help(app, dkwt_help_file_names[topic], dkwt_help_print);
+ } break;
+ case 8: {
+ dk3app_help(app, dkwt_help_file_names[topic], dkwt_help_help);
+ } break;
+ case 11: {
+ dk3app_help(app, dkwt_help_file_names[topic], dkwt_help_keep);
+ } break;
+ case 12: {
+ dk3app_help(app, dkwt_help_file_names[topic], dkwt_help_unkeep);
+ } break;
+ case 21: case 22: {
+ dk3app_help(app, dkwt_help_file_names[13], dkwt_help_clp);
+ } break;
+ case 23: case 24: {
+ dk3app_help(app, dkwt_help_file_names[14], dkwt_help_env);
+ } break;
+ }
+ return 0;
+}
+
+
+
+/** The main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, any other value indicates an error.
+*/
+DK3_MAIN
+{
+ int exval = DKT_RESULT_ERR_UNSPECIFIC;
+ dk3_app_t *app = NULL;
+ dkChar const * const *msg = NULL;
+ int xargc = 0;
+ int topic = 0;
+ dkChar const * const *xargv = NULL;
+ $!trace-init dkwt.deb
+ $? "+ main"
+ if((sizeof(dkChar) != 2) || (sizeof(TCHAR) != 2)) {
+ fprintf(stderr, "Wrong compiler options were used to build this program!\n");
+ fprintf(stderr, "Size of dkChar: %u\n", (unsigned)sizeof(dkChar));
+ fprintf(stderr, "Size of TCHAR: %u\n", (unsigned)sizeof(TCHAR));
+ fprintf(stderr, "Please re-compile with -DDK3_CHAR_SIZE=2 -D_UNICODE=1\n");
+ fflush(stderr);
+ exit(DKT_RESULT_ERR_UNSPECIFIC);
+ }
+ app = dk3app_open_command(
+ argc, (dkChar const * const *)argv, dkwt_group_name
+ );
+ if(app) {
+ msg = dk3app_messages(
+ app, dkwt_string_table_file_name, (dkChar const **)dkwt_message_texts
+ );
+ xargc = dk3app_get_argc(app);
+ xargv = dk3app_get_argv(app);
+ if(xargc > 1) {
+ switch(dk3str_array_index(dkwt_commands, xargv[1], 0)) {
+ case 0: { $? ". boot"
+ exval = dkwt_event(app, msg, dkwt_no_loc, 0);
+ } break;
+ case 1: { $? ". shutdown"
+ exval = dkwt_event(app, msg, dkwt_no_loc, 1);
+ } break;
+ case 2: { $? ". login"
+ exval = dkwt_event(app, msg, dkwt_no_loc, 2);
+ } break;
+ case 3: { $? ". logout"
+ exval = dkwt_event(app, msg, dkwt_no_loc, 3);
+ } break;
+ case 4: { $? ". accounts"
+ exval = dkwt_accounts(app, msg, dkwt_no_loc);
+ } break;
+ case 5: {
+ exval = dkwt_groups(app, msg, dkwt_no_loc);
+ } break;
+ case 6: {
+ exval = dkwt_printers(app, msg, dkwt_no_loc);
+ } break;
+ case 7: {
+ exval = dkwt_print(app, msg, dkwt_no_loc);
+ } break;
+ case 8: case 13: case 18: {
+ topic = 8;
+ if(xargc > 2) {
+ topic = dk3str_array_index(dkwt_commands, xargv[2], 0);
+ if(topic < 0) topic = 8;
+ }
+ exval = dkwt_help(app, msg, dkwt_no_loc, topic);
+ } break;
+ case 9: case 14: case 19: { /* version */
+ dk3sf_initialize_stdout();
+ dk3sf_fputs(dkwt_version, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ } break;
+ case 10: case 15: case 16: case 17: case 20: { /* license */
+ dkChar const * const *sptr;
+ sptr = dkwt_license;
+ dk3sf_initialize_stdout();
+ while(*sptr) {
+ dk3sf_fputs(*(sptr++), stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ } break;
+ case 11: {
+ exval = dkwt_event_keep(app, msg, dkwt_no_loc);
+ } break;
+ case 12: {
+ exval = dkwt_event_unkeep(app, msg, dkwt_no_loc);
+ } break;
+ case 21: case 22: {
+ exval = dkwt_event(app, msg, dkwt_no_loc, 4);
+ } break;
+ case 23: case 24: {
+ exval = dkwt_env(app, msg, dkwt_no_loc);
+ } break;
+ }
+ }
+ dk3app_close(app);
+ } else {
+ fprintf(stderr, "ERROR: Not enough memory!\n");
+ fflush(stderr);
+ }
+ $? "- main %d", exval
+ $!trace-end
+ fflush(stdout);
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/dkwt.h b/support/dktools/dkwt.h
new file mode 100644
index 0000000000..e0d1a2123e
--- /dev/null
+++ b/support/dktools/dkwt.h
@@ -0,0 +1,463 @@
+
+/** @file dkwt.h Header file for the dkwt program.
+*/
+
+#ifndef DKWT_H_INCLUDED
+#define DKT3_H_INCLUDED 1
+
+#include <lm.h>
+#include <Sddl.h>
+
+#if (_MSC_VER >= 1800) && (!(DK4_WINDOWS_LEGACY))
+#include <VersionHelpers.h>
+#endif
+
+/** Description for one Windows account.
+*/
+typedef struct {
+ dkChar const *logname; /**< Login name. */
+ dkChar const *fullname; /**< Full name. */
+ dkChar const *comment; /**< Account comment. */
+ dkChar const *usrcomment; /**< User comment. */
+ dkChar const *homedir; /**< Home directory. */
+ dkChar const *profile; /**< User profile. */
+ dkChar const *textsid; /**< SID as text. */
+ DWORD priv; /**< usri4_priv. */
+ DWORD flags; /**< usri4_flags. */
+ DWORD a_flags; /**< usri4_authflags. */
+ DWORD coco; /**< Country code. */
+ DWORD codepage; /**< Code page. */
+ int f_long; /**< Flag: Long information was found. */
+} dkwt_account_t;
+
+
+
+/** Windows group.
+*/
+typedef struct {
+ dkChar const *groupname; /**< Group name. */
+ dkChar const *comment; /**< Comment. */
+ dkChar const *textsid; /**< SID as text. */
+ DWORD attributes; /**< Attributes. */
+ int gtype; /**< Group type (net or local). */
+} dkwt_group_t;
+
+
+
+/** List of Windows accounts.
+*/
+typedef struct {
+ dk3_sto_t *s_acc; /**< Accounts storage. */
+ dk3_sto_it_t *i_acc; /**< Accounts iterator. */
+} dkwt_account_list_t;
+
+
+
+/** List of Windows groups.
+*/
+typedef struct {
+ dk3_sto_t *s_grp; /**< Groups storage. */
+ dk3_sto_it_t *i_grp; /**< Groups iterator. */
+} dkwt_group_list_t;
+
+
+
+/** Printer information.
+*/
+typedef struct {
+ dkChar const *printerName; /**< Printer name. */
+ dkChar const *comment; /**< Comment for the printer. */
+ dkChar const *description; /**< Printer description text. */
+ dkChar const *location; /**< Printer location. */
+ dkChar const *serverName; /**< Print server managing queue. */
+ dkChar const *shareName; /**< Share name of the printer. */
+ dkChar const *portName; /**< Port name. */
+ dkChar const *driverName; /**< Driver name. */
+ dkChar const *deviceName; /**< Device name. */
+ dkChar const *separatorFile; /**< File printed to separate jobs. */
+ dkChar const *printProcessor; /**< Print processor name. */
+ dkChar const *dataType; /**< Print data type. */
+ dkChar const *parameters; /**< Printer parameters. */
+ DWORD attributes; /**< Printer attributes. */
+ DWORD status; /**< Printer status. */
+ DWORD nJobs; /**< Number of jobs in queue. */
+} dkwt_printer_t;
+
+
+
+/** List of printers.
+*/
+typedef struct {
+ dk3_sto_t *s_prn; /**< Storage containing the printers. */
+ dk3_sto_it_t *i_prn; /**< Iterator through @a s_prn storage. */
+} dkwt_printer_list_t;
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Function for dkwt boot|shutdown|login|logout.
+ @param app Application structure.
+ @param msg Localized message texts.
+ @param kwnl Keywords, not localized.
+ @param evt Event type: 0=boot, 1=shutdown, 2=login, 3=logout
+ @return 0 on success, DKT_RESULT_ERR_xxx on error.
+*/
+int
+dkwt_event(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl,
+ int evt
+);
+
+/** Show or modify environment.
+ @param app Application structure.
+ @param msg Localized message texts.
+ @param kwnl Keywords, not localized.
+ @return 0 on success, DKT_RESULT_ERR_xxx on error.
+*/
+int
+dkwt_env(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl
+);
+
+/** Function to keep data while boot/login/logout/shutdown.
+ @param app Application structure.
+ @param msg Localized message texts.
+ @param kwnl Keywords, not localized.
+ @return 0 on success, DKT_RESULT_ERR_xxx on error.
+*/
+int
+dkwt_event_keep(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl
+);
+
+/** Function to reset keep flag for boot/login/logout/shutdown.
+ @param app Application structure.
+ @param msg Localized message texts.
+ @param kwnl Keywords, not localized.
+ @return 0 on success, DKT_RESULT_ERR_xxx on error.
+*/
+int
+dkwt_event_unkeep(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl
+);
+
+/** Function for dkwt accounts.
+ @param app Application structure.
+ @param msg Localized message texts.
+ @param kwnl Keywords, not localized.
+ @return 0 on success, DKT_RESULT_ERR_xxx on error.
+*/
+int
+dkwt_accounts(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl
+);
+
+/** Create account, allocate memory.
+ @param logname Login name of user.
+ @param app Application structure for diagnostics.
+ @return Pointer to new account on success, NULL on error.
+*/
+dkwt_account_t *
+dkwt_tool_open_account(dkChar const *logname, dk3_app_t *app);
+
+/** Destroy account, release memory.
+ @param ap Account to destroy.
+*/
+void
+dkwt_tool_close_account(dkwt_account_t *ap);
+
+/** Create account list, allocate memory.
+ @param app Application structure for diagnostics.
+ @param f_long Flag: Long listing required.
+ @return Pointer to new list on success, NULL on error.
+*/
+dkwt_account_list_t *
+dkwt_tool_open_account_list(dk3_app_t *app, int f_long);
+
+/** Destroy account list, release memory.
+ @param lp List to destroy.
+*/
+void
+dkwt_tool_close_account_list(dkwt_account_list_t *lp);
+
+/** Reset account list before traversing it.
+ @param lp List to reset.
+*/
+void
+dkwt_tool_reset_account_list(dkwt_account_list_t *lp);
+
+/** Get next account from list.
+ @param lp List to traverse.
+ @return Pointer to next account or NULL (list end).
+*/
+dkwt_account_t *
+dkwt_tool_get_account_from_list(dkwt_account_list_t *lp);
+
+/** The dkwt groups command.
+ @param app Application structure.
+ @param msg Localized messages texts,
+ @param kwnl Keywords, not localized.
+*/
+int
+dkwt_groups(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl
+);
+
+/** The dkwt printers command.
+ @param app Application structure.
+ @param msg Localized messages texts,
+ @param kwnl Keywords, not localized.
+*/
+int
+dkwt_printers(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl
+);
+
+/** The dkwt print command.
+ @param app Application structure.
+ @param msg Localized message texts.
+ @param kwnl Keywords, not localized.
+*/
+int
+dkwt_print(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl
+);
+
+/** Create a new group list.
+ @param app Application structure.
+ @param f_long Flag: Long (full) listing.
+ @return Pointer to new group list on success, NULL on error.
+*/
+dkwt_group_list_t *
+dkwt_tool_open_group_list(dk3_app_t *app, int f_long);
+
+/** Reset a group list.
+ @param glp Group list to reset.
+*/
+void
+dkwt_tool_reset_group_list(dkwt_group_list_t *glp);
+
+/** Retrieve next group from list.
+ @param glp Group list to traverse.
+ @return Pointer to next group on success, NULL on error.
+*/
+dkwt_group_t *
+dkwt_tool_get_group_from_list(dkwt_group_list_t *glp);
+
+/** Close group list, release memory.
+ @param glp Group list to close.
+*/
+void
+dkwt_tool_close_group_list(dkwt_group_list_t *glp);
+
+/** Open printer list.
+ @param app Application structure.
+ @param f_long Flag: Long information about printers.
+ @return Pointer to new printer list on success, NULL on errors.
+*/
+dkwt_printer_list_t *
+dkwt_tool_open_printer_list(dk3_app_t *app, int f_long);
+
+/** Close printer list, release memory.
+ @param pl List to close.
+*/
+void
+dkwt_tool_close_printer_list(dkwt_printer_list_t *pl);
+
+/** Reset printer list.
+ @param pl Printer list to reset.
+*/
+void
+dkwt_tool_printer_list_reset(dkwt_printer_list_t *pl);
+
+/** Get next printer description from list.
+ @param pl Printer list.
+ @return Pointer to next printer on success, NULL on error.
+*/
+dkwt_printer_t *
+dkwt_tool_printer_list_next(dkwt_printer_list_t *pl);
+
+/** Open a registry key.
+ @param key
+ @param skn
+ @param sam
+ @param phk
+ @return ERROR_SUCCESS on success, any other value indicates
+ an error.
+*/
+long
+dkwt_tool_reg_open_key(
+ HKEY key,
+ dkChar const *skn,
+ REGSAM sam,
+ PHKEY phk
+);
+
+/** Query a registry value.
+ @param hk Registry key.
+ @param vn Value name.
+ @param pDwTp Pointer to type variable (in/out).
+ @param buf Pointer to result buffer.
+ @param pDwSz Result buffer length available/used.
+ @return ERROR_SUCCESS on success, any other value indicates
+ an error.
+*/
+long
+dkwt_tool_reg_query_value(
+ HKEY hk,
+ dkChar const *vn,
+ DWORD *pDwTp,
+ void *buf,
+ DWORD *pDwSz
+);
+
+/** Delete a registry entry (value).
+ @param hk Registry key.
+ @param en Name of entry to delete.
+ @return ERROR_SUCCESS on success, any other value indicates an error.
+*/
+long
+dkwt_tool_reg_delete_value(
+ HKEY hk,
+ dkChar const *en
+);
+
+/** Delete subkey hierarchy.
+ @param hk Parent registry key.
+ @param tn Name of subkey to delete.
+ @return ERROR_SUCCESS on success, any other value indicates an error.
+*/
+long
+dkwt_tool_reg_delete_tree(
+ HKEY hk,
+ dkChar const *tn
+);
+
+/** Enumerate subkeys of a key.
+ @param hk Registry key.
+ @param dwIndex Index of subkey to enumerate.
+ @param pResult Pointer to result buffer.
+ @param pDwSzResult Pointer to buffer length / result length.
+ @param pClass Subkey class name, may be NULL.
+ @param pDwSzClass Subkey class name length, may be NULL.
+ @param pLastWrite Pointer to timestamp, may be NULL.
+ @return ERROR_SUCCESS on success, ERROR_NO_MORE_DATA on end,
+ any other value indicates an error.
+*/
+long
+dkwt_tool_reg_enum_key(
+ HKEY hk,
+ DWORD dwIndex,
+ dkChar *pResult,
+ DWORD *pDwSzResult,
+ dkChar *pClass,
+ DWORD *pDwSzClass,
+ PFILETIME pLastWrite
+);
+
+/** Create a registry key.
+ @param hk Parent key.
+ @param kn Subkey name.
+ @param dwOptions Options (0 is a good choice).
+ @param sam Access mask.
+ @param pHkeyResult Pointer to result HKEY.
+ @param lpDwDisposition Pointer to disposition DWORD, may be NULL.
+ @return ERROR_SUCCESS on success, any other value indicates an error.
+*/
+long
+dkwt_tool_reg_create_key(
+ HKEY hk,
+ dkChar const *kn,
+ DWORD dwOptions,
+ REGSAM sam,
+ PHKEY pHkeyResult,
+ LPDWORD lpDwDisposition
+);
+
+/** Set a registry value.
+ @param hk Handle for registry key.
+ @param vn Value name.
+ @param dwType Value type.
+ @param pData Value data.
+ @param szData Length of value data.
+ @return ERROR_SUCCESS on success, any other value indicates an error.
+*/
+long
+dkwt_ev_reg_set_value(
+ HKEY hk,
+ dkChar const *vn,
+ DWORD dwType,
+ void *pData,
+ DWORD szData
+);
+
+/** Clear local print queues.
+ @param app Application structure for diagnostics.
+ @param msg Localized message texts.
+ @param kwnl Keywords, not localized.
+ @param userName User for which to delete print jobs.
+*/
+void
+dkwt_clear_printers_local(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl,
+ dkChar const *userName
+);
+
+/** Clear LPRng/LPD remote print queues.
+ @param app Application structure for diagnostics.
+ @param msg Localized message texts.
+ @param kwnl Keywords, not localized.
+ @param userName User name for print jobs.
+ @param iterator Iterator for print queue names storage.
+*/
+void
+dkwt_clear_printers_remote(
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl,
+ dkChar const *userName,
+ dk3_sto_it_t *iterator
+);
+
+/** Check whether the current process runs with administrative privileges.
+ @return 1 for administrative process, 0 for non-administrative
+ process, -1 for failed check.
+*/
+int
+dkwt_is_admin(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** Show groups found on network server.
+*/
+#define DKWT_GROUP_NET 0
+
+/** Show groups found on local computer.
+*/
+#define DKWT_GROUP_LOCAL 1
+
+#endif
+
diff --git a/support/dktools/dkwt.rc b/support/dktools/dkwt.rc
new file mode 100644
index 0000000000..70db260225
--- /dev/null
+++ b/support/dktools/dkwt.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Dirk Krause's Windows tool\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "Dirk Krause's Windows tool\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "dkwt\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/dkwtadm.rc b/support/dktools/dkwtadm.rc
new file mode 100644
index 0000000000..c02ffb6b0d
--- /dev/null
+++ b/support/dktools/dkwtadm.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Dirk Krause's Windows adm tool\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "Dirk Krause's Windows adm tool\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "dkwtadm\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/dkwxpath.h b/support/dktools/dkwxpath.h
new file mode 100644
index 0000000000..2185bcc73b
--- /dev/null
+++ b/support/dktools/dkwxpath.h
@@ -0,0 +1,46 @@
+
+#ifndef DKWXPATH_H_INCLUDED
+#define DKWXPATH_H_INCLUDED 1
+
+#ifdef DK3_USE_WX
+#undef DK3_USE_WX
+#endif
+/** Use wxWidgets libraries to build GUI programs.
+*/
+#define DK3_USE_WX 1
+
+#include <dk3all.h>
+
+#include <wx/wxprec.h>
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#include <wx/wx.h>
+#endif
+#include <wx/config.h>
+#include <wx/filename.h>
+#include <wx/gbsizer.h>
+#include <wx/thread.h>
+#include <wx/gauge.h>
+#include <wx/help.h>
+#include <wx/fs_zip.h>
+#include <wx/cmdline.h>
+
+#include "dk3wxs.h"
+#include "DkWxAppHelper.h"
+#include "DkWxFrame.h"
+#include "DkWxCommunicator.h"
+#include "DkWxProgressDialog.h"
+#include "DkWxHelpController.h"
+
+#include "DkWxPathApp.h"
+#include "DkWxPathFrame.h"
+
+/** Main window ID.
+*/
+#define DkWxPath_MainWindow (wxID_HIGHEST + 1)
+
+#endif
+/* ifndef DKWXPATH_H_INCLUDED */
+
diff --git a/support/dktools/dkwxpath.rc b/support/dktools/dkwxpath.rc
new file mode 100644
index 0000000000..40a8e37a83
--- /dev/null
+++ b/support/dktools/dkwxpath.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkctinst.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Path setup during installation\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "Path setup during installation\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "dkwxpath\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/dkwxpqdc.h b/support/dktools/dkwxpqdc.h
new file mode 100644
index 0000000000..12963cf0ef
--- /dev/null
+++ b/support/dktools/dkwxpqdc.h
@@ -0,0 +1,153 @@
+
+#ifndef DKWXPQDC_H_INCLUDED
+#define DKWXPQDC_H_INCLUDED 1
+
+#ifdef DK3_USE_WX
+#undef DK3_USE_WX
+#endif
+/** Use wxWidgets libraries to build GUI programs.
+*/
+#define DK3_USE_WX 1
+
+#include <dk3all.h>
+#include <dk3sock.h>
+#include <printqds.h>
+#if 0
+#include <dkt-version.h>
+#endif
+#include "dk4verswx.h"
+
+/** Data returned from quota information server.
+*/
+typedef struct {
+ unsigned long li; /**< Pages limit. */
+ unsigned long pa; /**< Pages used from limit. */
+ unsigned long ac; /**< Pages in personal print account. */
+ int lt; /**< Limit type: 0=denied, 1=pages, 2=unlimited. */
+ int su; /**< Summary: 1=can print, 0=no printing. */
+ int ec; /**< Error code: 0=no error, 1=connect failed. */
+} wxpqdic_t;
+
+#include <wx/wxprec.h>
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#include <wx/wx.h>
+#endif
+#include <wx/config.h>
+#include <wx/filename.h>
+#include <wx/gbsizer.h>
+#include <wx/thread.h>
+#include <wx/gauge.h>
+#include <wx/help.h>
+#include <wx/fs_zip.h>
+#include <wx/cmdline.h>
+#include <wx/socket.h>
+
+#include "dk3wxs.h"
+#include "DkWxAppHelper.h"
+#include "DkWxFrame.h"
+#include "DkWxCommunicator.h"
+#include "DkWxProgressDialog.h"
+#include "DkWxHelpController.h"
+
+#include "DkWxPrintqdcApp.h"
+#include "DkWxPrintqdcFrame.h"
+#include "DkWxPrintqdcThread.h"
+
+
+/** @defgroup wxdkpqdicevents Event and other IDs. */
+/**@{*/
+
+/** Event ID: Quit program.
+*/
+#define DkWxPrintqdc_Quit wxID_EXIT
+
+/** Event ID: Show about box.
+*/
+#define DkWxPrintqdc_About wxID_ABOUT
+
+/** Event ID: Widget ID for main window.
+*/
+#define DkWxPrintqdc_MainWindow (wxID_HIGHEST + 1)
+
+/** Event ID: Update view.
+*/
+#define DkWxPrintqdc_Update (DkWxPrintqdc_MainWindow + 1)
+
+/** Event ID: Timer event.
+*/
+#define DkWxPrintqdc_Timer (DkWxPrintqdc_Update + 1)
+
+/** Event ID: Open help.
+*/
+#define DkWxPrintqdc_Help (DkWxPrintqdc_About + 1)
+/**@}*/
+
+/** @defgroup wxpqdicerrors Error codes in wxpqdic. */
+/**@{*/
+
+/** No error occured.
+*/
+#define WXPQDIC_ERROR_NONE 0
+
+/** Failed to set up internal data structures.
+*/
+#define WXPQDIC_ERROR_INIT 1
+
+/** Failed to find user name (not found or too long)!
+*/
+#define WXPQDIC_ERROR_NO_USER_NAME 2
+
+/** Host name not configured.
+*/
+#define WXPQDIC_ERROR_NO_HOST_NAME 3
+
+/** Port number not conifgured.
+*/
+#define WXPQDIC_ERROR_NO_PORT_NUMBER 4
+
+/** Queue name not configured.
+*/
+#define WXPQDIC_ERROR_NO_QUEUE_NAME 5
+
+/** Not enough memory.
+*/
+#define WXPQDIC_ERROR_MEMORY 6
+
+/** No request configured.
+*/
+#define WXPQDIC_ERROR_NO_REQUEST 7
+
+/** Failed to connect to server.
+*/
+#define WXPQDIC_ERROR_CONNECT_FAILED 8
+
+/** Failed to send request to server.
+*/
+#define WXPQDIC_ERROR_SEND_FAILED 9
+
+/** Failed to shutdown server socket.
+*/
+#define WXPQDIC_ERROR_SHUTDOWN 10
+
+/** Server did not send a response.
+*/
+#define WXPQDIC_ERROR_NO_RESPONSE 11
+
+/** Response from server invalid.
+*/
+#define WXPQDIC_ERROR_INVALID_RESPONSE 12
+
+/**@}*/
+
+
+
+#define WXPQDI_USER_NAME_SIZE 64
+
+#define WXPQDI_QUEUE_NAME_SIZE 64
+
+#endif
+/* ifndef DKWXPQDC_H_INCLUDED */
+
diff --git a/support/dktools/dkwxtrace.h b/support/dktools/dkwxtrace.h
new file mode 100644
index 0000000000..62b543728c
--- /dev/null
+++ b/support/dktools/dkwxtrace.h
@@ -0,0 +1,96 @@
+
+/** @file dkwxtrace.h Header file for dkwxtrace.
+*/
+
+
+#ifndef DKWXTRACE_H_INCLUDED
+#define DKWXTRACE_H_INCLUDED
+
+#ifdef DK3_USE_WX
+#undef DK3_USE_WX
+#endif
+/** Use wxWidgets libraries to build GUI programs.
+*/
+#define DK3_USE_WX 1
+
+
+#include <dk3all.h>
+
+#include <wx/wxprec.h>
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#include <wx/wx.h>
+#endif
+#include <wx/config.h>
+#include <wx/filename.h>
+#include <wx/gbsizer.h>
+#include <wx/thread.h>
+#include <wx/gauge.h>
+#include <wx/help.h>
+#include <wx/fs_zip.h>
+#include <wx/cmdline.h>
+
+#include "dk3wxs.h"
+#include "DkWxAppHelper.h"
+#include "DkWxFrame.h"
+#include "DkWxCommunicator.h"
+#include "DkWxProgressDialog.h"
+#include "DkWxHelpController.h"
+
+#include "dkct.h"
+
+#include "DkWxTraceThread.h"
+#include "DkWxTraceApp.h"
+#include "DkWxTraceFrame.h"
+#include "DkWxTraceOptionsDialog.h"
+
+
+
+/** @defgroup wxdkcteventids Event ids. */
+/**@{*/
+/** File / Exit menu item.
+*/
+#define DkWxTrace_Quit wxID_EXIT
+
+/** Help / About menu item.
+*/
+#define DkWxTrace_About wxID_ABOUT
+
+/** Id for main frame.
+*/
+#define DkWxTrace_MainWindow (wxID_HIGHEST + 1)
+
+/** File / Directory menu item.
+*/
+#define DkWxTrace_ChooseDirectory (DkWxTrace_MainWindow + 1)
+
+/** File / Options menu item.
+*/
+#define DkWxTrace_SetOptions (DkWxTrace_ChooseDirectory + 1)
+
+/** File / Run menu item.
+*/
+#define DkWxTrace_Run (DkWxTrace_SetOptions + 1)
+
+/** ID for debug checkbox.
+*/
+#define DkWxTrace_Debug (DkWxTrace_Run + 1)
+
+/** Help / Contents menu.
+*/
+#define DkWxTrace_Help_Contents (DkWxTrace_Debug + 1)
+
+/** Use splint.
+*/
+#define DkWxTrace_UseSplint (DkWxTrace_Help_Contents + 1)
+
+/** Choose splint comment character.
+*/
+#define DkWxTrace_SplintChar (DkWxTrace_UseSplint + 1)
+
+/**@}*/
+
+#endif
+
diff --git a/support/dktools/dkwxwiz.c b/support/dktools/dkwxwiz.c
new file mode 100644
index 0000000000..2c1ae67791
--- /dev/null
+++ b/support/dktools/dkwxwiz.c
@@ -0,0 +1,1393 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: dkwxwiz.ctr
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file dkwxwiz.c The dkwxwiz module.
+*/
+
+
+#line 9 "dkwxwiz.ctr"
+
+#include "dk3all.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4vers.h"
+
+
+
+
+#line 18 "dkwxwiz.ctr"
+
+
+
+/** @defgroup dkwxwizcmd Commands for dkwxwiz.
+*/
+/**@{*/
+
+/** Show help text.
+*/
+#define DKWXWIZ_CMD_HELP 1
+
+/** Show version information.
+*/
+#define DKWXWIZ_CMD_VERSION 2
+
+/** Show license terms.
+*/
+#define DKWXWIZ_CMD_LICENSE 4
+
+/**@}*/
+
+
+/** Job structure for dkwxwiz.
+*/
+typedef struct {
+ dk3_app_t *app; /**< Application structure. */
+ dkChar const * const *msg; /**< Localized messages texts. */
+ dk3_option_set_t *opt; /**< Command line options. */
+ dkChar const *con; /**< Copyright holder name. */
+ dkChar const *lin; /**< License name. */
+ dkChar const *pName; /**< Program name. */
+ dkChar const *aName; /**< Application class name. */
+ dkChar const *fName; /**< Frame class name. */
+ dkChar const *xfn; /**< XPM file name (allocated). */
+ dkChar const *pfn; /**< Program header file name. */
+ dkChar const *afn; /**< Application class file name. */
+ dkChar const *ffn; /**< Frame class file name. */
+ dkChar const *ifn; /**< Icon file name. */
+ dkChar const *rfn; /**< RC file name. */
+ int exv; /**< Exit value. */
+ int cmd; /**< Command to execute. */
+ int frc; /**< Force overwriting existing files. */
+ int obj; /**< Flag: Use object modules, not libs. */
+} DKWXWIZ_JOB;
+
+
+
+/** Macros like $program$ are allowed in the templates.
+*/
+static char const * const dkwxwiz_macros[] = {
+/* 0 */
+"program",
+
+/* 1 */
+"application",
+
+/* 2 */
+"frame",
+
+/* 3 */
+"year",
+
+/* 4 */
+"copyrightowner",
+
+/* 5 */
+"licensetype",
+
+NULL
+
+
+#line 94 "dkwxwiz.ctr"
+};
+
+
+
+/** Constant dkChar strings, not localized.
+*/
+static dkChar const * const dkwxwiz_nl[] = {
+/* 0 */
+dkT(".h"),
+
+/* 1 */
+dkT(".cpt"),
+
+/* 2 */
+dkT(".wxc"),
+
+/* 3 */
+dkT("dkwxwizh.txt"),
+
+/* 4 */
+dkT("dkwxwiza.txt"),
+
+/* 5 */
+dkT("dkwxwizf.txt"),
+
+/* 6 */
+dkT("r"),
+
+/* 7 */
+dkT("w"),
+
+/* 8 */
+dkT("Makefile.in"),
+
+/* 9 */
+dkT("configure.ac"),
+
+/* 10 */
+dkT("dkwxwizm.txt"),
+
+/* 11 */
+dkT("dkwxwizc.txt"),
+
+/* 12 */
+dkT("wb"),
+
+/* 13 */
+dkT("\r\n"),
+
+/* 14 */
+dkT("\n"),
+
+/* 15 */
+dkT(".xpm"),
+
+/* 16 */
+dkT("dkwxwizx.txt"),
+
+/* 17 */
+dkT(".ico"),
+
+/* 18 */
+dkT("dkwxwiz.ico"),
+
+/* 19 */
+dkT("rb"),
+
+/* 20 */
+dkT(".rc"),
+
+/* 21 */
+dkT("dkwxwizr.txt"),
+
+/* 22 */
+dkT("makefile.vc"),
+
+/* 23 */
+dkT("dkwxwizv.txt"),
+
+NULL
+
+
+#line 199 "dkwxwiz.ctr"
+};
+
+
+
+/** Constant dkChar strings, localized versions are used if found.
+*/
+static dkChar const * const dkwxwiz_msg[] = {
+/* 0 */
+dkT("dkwxwiz"),
+
+/* 1 */
+dkT("dktools"),
+
+/* 2 */
+dkT("dkwxwiz.str"),
+
+/* 3 */
+dkT("dkwxwiz.txt"),
+
+/* 4 */
+dkT("__CHANGE__ 001:\tCopyright owner"),
+
+/* 5 */
+dkT("bsd"),
+
+/* 6 */
+dkT("File base name \""),
+
+/* 7 */
+dkT("\" too long!"),
+
+/* 8 */
+dkT("File \""),
+
+/* 9 */
+dkT("\" already exists!"),
+
+/* 10 */
+dkT("Unknown macro in line!"),
+
+/* 11 */
+dkT("Too few command line arguments!"),
+
+/* 12 */
+dkT("You should create/modify the following files:"),
+
+/* 13 */
+dkT("Windows help file: \""),
+
+/* 14 */
+dkT("non-Windows help file: \""),
+
+/* 15 */
+dkT("Windows icon file: \""),
+
+/* 16 */
+dkT("non-Windows icon file: \""),
+
+/* 17 */
+dkT("\"."),
+
+/* 18 */
+dkT(".chm"),
+
+/* 19 */
+dkT(".htb"),
+
+/* 20 */
+dkT(".ico"),
+
+/* 21 */
+dkT(".xpm"),
+
+/* 22 */
+dkT("Text too long or not ASCII: \""),
+
+/* 23 */
+dkT("\"!"),
+
+/* 24 */
+dkT("Not a C/C++ identifier: \""),
+
+/* 25 */
+dkT("\"!"),
+
+NULL
+
+
+#line 279 "dkwxwiz.ctr"
+};
+
+
+
+/** License conditions shown for dkwxwiz --license-terms.
+*/
+static dkChar const * const dkwxwiz_license[] = {
+dkT(""),
+dkT("Copyright (c) 2013-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above copyright notice,"),
+dkT(" this list of conditions and the following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("* Neither the name of the copyright holder(s) nor the names of"),
+dkT(" contributors may be used to endorse or promote products derived from"),
+dkT(" this software without specific prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS"),
+dkT("\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT"),
+dkT("LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A"),
+dkT("PARTICULAR PURPOSE ARE DISCLAIMED."),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS"),
+dkT("OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)"),
+dkT("HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,"),
+dkT("STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN"),
+dkT("ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE"),
+dkT("POSSIBILITY OF SUCH DAMAGE."),
+dkT(""),
+NULL
+
+
+#line 317 "dkwxwiz.ctr"
+};
+
+
+/** Options allowed for dkwxwiz.
+*/
+static dk3_option_t const dkwxwiz_options[] = {
+ { dkT('h'), dkT("help"), 0 },
+ { dkT('v'), dkT("version"), 0 },
+ { dkT('L'), dkT("license-terms"), 0 },
+ { dkT('f'), dkT("force"), 0},
+ { dkT('l'), dkT("license"), 1 },
+ { dkT('c'), dkT("copyright-owner"), 1 },
+ { dkT('o'), dkT("object-modules"), 0 },
+};
+
+
+/** Number of options in the dkwxwiz_options array.
+*/
+static size_t dkwxwiz_sz_options =
+sizeof(dkwxwiz_options)/sizeof(dk3_option_t);
+
+
+
+/** Default help text, shown if no help file is found.
+*/
+static dkChar const * dkwxwiz_help_text[] = {
+dkT(""),
+dkT("NAME"),
+dkT(""),
+dkT(" dkwxwiz - Wizard to create a wxWidgets + dkct based project."),
+dkT(""),
+dkT("SYNOPSIS"),
+dkT(""),
+dkT(" dkwxwiz [<options>] <program> <application> <window>"),
+dkT(""),
+dkT("DESCRIPTION"),
+dkT(""),
+dkT("The program creates source code skeletons for a new GUI application based"),
+dkT("on wxWidgets assuming you use the dktools libraries and the dkct program"),
+dkT("during development."),
+dkT("As arguments you have to specify:"),
+dkT(""),
+dkT("* Name of the final program (i.e. \"myprog\")."),
+dkT(""),
+dkT("* Name of the application class derived from wxApp (i.e, \"MyProgApp\")."),
+dkT(""),
+dkT("* Name of the main window class (i.e. \"MyProgFrame\")."),
+dkT(""),
+dkT("Valid C/C++ identifiers are required for all three names."),
+dkT(""),
+dkT("OPTIONS"),
+dkT(""),
+dkT("-h\t--help"),
+dkT(" Show a help text."),
+dkT(""),
+dkT("-v\t--version"),
+dkT(" Show the program version."),
+dkT(""),
+dkT("-L\t--license-terms"),
+dkT(" Show the license conditions."),
+dkT(""),
+dkT("-f\t--force"),
+dkT(" Force the program to overwrite existing files."),
+dkT(""),
+dkT("-c <copyright owner name>"),
+dkT(" Name of the copyright owner."),
+dkT(""),
+dkT("-l <license type>"),
+dkT(" License type (i.e. \"bsd\")."),
+dkT(""),
+dkT("EXIT STATUS"),
+dkT(""),
+dkT("0 on success, all other exit status codes indicate an error."),
+dkT(""),
+dkT("EXAMPLES"),
+dkT(""),
+dkT("Run"),
+dkT(" dkwxwiz testprog TestApp TestFrame"),
+dkT("in an empty directory to create a new project."),
+dkT(""),
+dkT("FILES"),
+dkT(""),
+dkT("The following files from the dktools resource directory are used:"),
+dkT(""),
+dkT("dkwxwizh.txt\tTemplate for project header file *.h."),
+dkT(""),
+dkT("dkwxwiza.txt\tTemplate for application class source *.cpt"),
+dkT(""),
+dkT("dkwxwizf.txt\tTemplate for top-level window class source *.wxc."),
+dkT(""),
+dkT("dkwxwizc.txt\tTemplate for configure.ac file for autoconf."),
+dkT(""),
+dkT("dkwxwizm.txt\tTemplate for the Makefile.in file."),
+dkT(""),
+dkT("dkwxwizx.txt\tTemplate for the *.xpm icon file."),
+dkT(""),
+dkT("You can create copies of these files in dkt-3-site and modify them"),
+dkT("i.e. to set a default copyright owner and a default license type."),
+dkT(""),
+dkT("SEE ALSO"),
+dkT(""),
+dkT("http://dktools.sourceforge.net"),
+dkT(""),
+dkT("AUTHOR"),
+dkT(""),
+dkT("Dirk Krause"),
+dkT(""),
+dkT("LICENSE"),
+dkT(""),
+dkT("Use"),
+dkT(" dkwxwiz --license-terms"),
+dkT("to view the license conditions."),
+NULL
+
+
+#line 431 "dkwxwiz.ctr"
+};
+
+
+/** Initialize job structure.
+ @param job Job structure to initialize.
+ @param app Application structure.
+ @param msg Localized message texts.
+*/
+static
+void
+dkwxwiz_job_init(DKWXWIZ_JOB *job, dk3_app_t *app, dkChar const * const *msg)
+{
+ job->app = app;
+ job->msg = msg;
+ job->opt = NULL;
+ job->pName = NULL;
+ job->aName = NULL;
+ job->fName = NULL;
+ job->xfn = NULL;
+ job->pfn = NULL;
+ job->afn = NULL;
+ job->ffn = NULL;
+ job->ifn = NULL;
+ job->rfn = NULL;
+ job->exv = 1;
+ job->cmd = 0;
+ job->frc = 0;
+ job->obj = 0;
+ job->con = NULL;
+ job->lin = NULL;
+}
+
+
+
+/** Concatenate base name and file suffix.
+ @param job Job structure.
+ @param bn Base file name.
+ @param sf File name suffix.
+ @return Pointer to new allocated file name on success, NULL on error.
+*/
+static
+dkChar const *
+dkwxwiz_concatenate(DKWXWIZ_JOB *job, dkChar const *bn, dkChar const *sf)
+{
+ dkChar buf[DK3_MAX_PATH]; /* Temporary name buffer. */
+ dkChar const *back = NULL;
+
+
+#line 478 "dkwxwiz.ctr"
+ if(DK3_SIZEOF(buf,dkChar) > (dk3str_len(bn) + dk3str_len(sf))) {
+ dk3str_cpy_not_overlapped(buf, bn);
+ dk3str_cat(buf, sf);
+ back = (dkChar const *)dk3str_dup_app(buf, job->app);
+ } else {
+ /* ERROR: Base name too long! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 6, 7, bn);
+ }
+
+#line 486 "dkwxwiz.ctr"
+ return back;
+}
+
+
+
+/** Build file names for output files.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkwxwiz_build_file_names(DKWXWIZ_JOB *job)
+{
+ int back = 0;
+
+
+#line 501 "dkwxwiz.ctr"
+ job->pfn = dkwxwiz_concatenate(job, job->pName, dkwxwiz_nl[0]);
+ job->afn = dkwxwiz_concatenate(job, job->aName, dkwxwiz_nl[1]);
+ job->ffn = dkwxwiz_concatenate(job, job->fName, dkwxwiz_nl[2]);
+ job->xfn = dkwxwiz_concatenate(job, job->pName, dkwxwiz_nl[15]);
+ job->ifn = dkwxwiz_concatenate(job, job->pName, dkwxwiz_nl[17]);
+ job->rfn = dkwxwiz_concatenate(job, job->pName, dkwxwiz_nl[20]);
+ if((job->pfn) && (job->afn) && (job->ffn) && (job->xfn) && (job->ifn)) {
+ if(job->rfn) {
+ back = 1;
+ }
+ }
+
+#line 512 "dkwxwiz.ctr"
+ return back;
+}
+
+
+
+/** Check one file name whether we can write the file.
+ @param job Job structure.
+ @param fn Output file name.
+ @return 1 if allowed to write the file, 0 otherwise.
+*/
+static
+int
+dkwxwiz_check_one_filename(DKWXWIZ_JOB *job, dkChar const *fn)
+{
+ dk3_stat_t stb; /* File information. */
+ int back = 0;
+
+
+#line 529 "dkwxwiz.ctr"
+ if(0 == dk3sf_stat_app(&stb, fn, NULL)) {
+ back = 1;
+ } else {
+ /* ERROR: File already exists! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 8, 9, fn);
+ }
+
+#line 535 "dkwxwiz.ctr"
+ return back;
+}
+
+
+
+/** Check whether we can write all files.
+ @param job Job structure.
+ @return 1 if we are allowed to write/overwrite the files, 0 otherwise.
+*/
+static
+int
+dkwxwiz_check_filenames(DKWXWIZ_JOB *job)
+{
+ int back = 0;
+
+
+#line 550 "dkwxwiz.ctr"
+ if(job->frc) {
+ back = 1;
+ } else {
+ back = 1;
+ if(!dkwxwiz_check_one_filename(job, job->pfn)) {
+ back = 0;
+ }
+ if(!dkwxwiz_check_one_filename(job, job->afn)) {
+ back = 0;
+ }
+ if(!dkwxwiz_check_one_filename(job, job->ffn)) {
+ back = 0;
+ }
+ if(!dkwxwiz_check_one_filename(job, job->xfn)) {
+ back = 0;
+ }
+ if(!dkwxwiz_check_one_filename(job, dkwxwiz_nl[8])) {
+ back = 0;
+ }
+ if(!dkwxwiz_check_one_filename(job, dkwxwiz_nl[9])) {
+ back = 0;
+ }
+ if(!dkwxwiz_check_one_filename(job, job->ifn)) {
+ back = 0;
+ }
+ if(!dkwxwiz_check_one_filename(job, job->rfn)) {
+ back = 0;
+ }
+ if(!dkwxwiz_check_one_filename(job, dkwxwiz_nl[22])) {
+ back = 0;
+ }
+ }
+
+#line 582 "dkwxwiz.ctr"
+ return back;
+}
+
+
+
+/** Write one string as 8-bit character text to output.
+ @param job Job structure.
+ @param dfile Destination file.
+ @param txt Text to write.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkwxwiz_write_c8_string(DKWXWIZ_JOB *job, FILE *dfile, dkChar const *txt)
+{
+#if DK3_CHAR_SIZE > 1
+ char buf[1024]; /* Temporary buffer for output. */
+#endif
+ int back = 0;
+#if DK3_CHAR_SIZE > 1
+ int res = 0;
+
+
+#line 604 "dkwxwiz.ctr"
+ res = dk3str_to_c8p_app(
+ buf, sizeof(buf), txt, dk3app_get_encoding(job->app), job->app
+ );
+ if(res) {
+ fputs(buf, dfile);
+ back = 1;
+ }
+
+#line 611 "dkwxwiz.ctr"
+#else
+
+
+#line 613 "dkwxwiz.ctr"
+ fputs(txt, dfile);
+ back = 1;
+
+#line 615 "dkwxwiz.ctr"
+#endif
+ return back;
+}
+
+
+
+/** Process one macro.
+ @param job Job structure.
+ @param dfile Output (destination) file.
+ @param sfile Input (source) file.
+ @param cptr Start of text.
+ @param p1 First '$' character.
+ @param p2 Second '$' character.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkwxwiz_one_macro(
+ DKWXWIZ_JOB *job,
+ FILE *dfile,
+ FILE *sfile,
+ char *cptr,
+ char *p1,
+ char *p2
+)
+{
+ dk3_tm_t tm; /* Local time. */
+ dkChar const *vptr; /* Pointer to value text. */
+ dk3_time_t timer; /* Current time. */
+ int action; /* Macro action to perform. */
+ int back = 1;
+ *p1 = '\0';
+ fputs(cptr, dfile);
+ *p2 = '\0';
+#if VERSION_BEFORE_20150821
+ cptr = &(p2[1]);
+#endif
+ p1++;
+ action = dk3str_c8_array_index(dkwxwiz_macros, p1, 0);
+ switch(action) {
+ case 0: { /* program */
+ if(!dkwxwiz_write_c8_string(job, dfile, job->pName)) {
+ back = 0;
+ }
+ } break;
+ case 1: { /* application */
+ if(!dkwxwiz_write_c8_string(job, dfile, job->aName)) {
+ back = 0;
+ }
+ } break;
+ case 2: { /* frame */
+ if(!dkwxwiz_write_c8_string(job, dfile, job->fName)) {
+ back = 0;
+ }
+ } break;
+ case 3: { /* year */
+ if(dk3sf_time(&timer)) {
+ if(dk3sf_localtime_app(&tm, &timer, job->app)) {
+ fprintf(dfile, "%04d", tm.Y);
+ } else {
+ back = 0;
+ }
+ } else {
+ /* ERROR: Failed to obtain current time. */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 80);
+ back = 0;
+ }
+ } break;
+ case 4: { /* copyrightowner */
+ vptr = job->con;
+ if(!(vptr)) { vptr = (job->msg)[4]; }
+ if(!dkwxwiz_write_c8_string(job, dfile, vptr)) {
+ back = 0;
+ }
+ } break;
+ case 5: { /* licensetype */
+ vptr = job->lin;
+ if(!(vptr)) { vptr = (job->msg)[5]; }
+ if(!dkwxwiz_write_c8_string(job, dfile, vptr)) {
+ back = 0;
+ }
+ } break;
+ default: {
+ /* ERROR: Unknown macro */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 10);
+ fputc('$', dfile);
+ fputs(p1, dfile);
+ fputc('$', dfile);
+ back = 0;
+ } break;
+ }
+ return back;
+}
+
+
+
+/** Find '$' character starting a dkwxwiz macro.
+ @param txt Text to search for macro.
+ @return Pointer to first macro found on success, NULL if no macro found.
+*/
+static
+char *
+dkwxwiz_find_macro_start(char *txt)
+{
+ char *p1; /* Probably start of new macro. */
+ char *back = NULL;
+ p1 = dk3str_c8_chr(txt, '$');
+ while((p1) && (!(back))) {
+ switch(p1[1]) {
+ case '!': case '?':
+ case '(': case '{':
+ case '@': case '*':
+ case '<': case '>':{
+ p1 = dk3str_c8_chr(&(p1[1]), '$');
+ } break;
+ default: {
+ back = p1;
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+/** Transfer one source file contents to destination file.
+ @param job Job structure.
+ @param dfile Destination file.
+ @param sfile Template file.
+ @param iswin Flag: Insist on Windows line ends.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkwxwiz_transfer_file(DKWXWIZ_JOB *job, FILE *dfile, FILE *sfile, int iswin)
+{
+ char buf[4096]; /* Line buffer. */
+ char *cptr; /* Remaining line to process. */
+ char *p1; /* Start of macro. */
+ char *p2; /* End of macro. */
+ unsigned long oldsourceline; /* Old source line number. */
+ unsigned long lineno = 0UL; /* Current source line. */
+ int back = 1;
+
+
+#line 759 "dkwxwiz.ctr"
+ oldsourceline = dk3app_get_source_line(job->app);
+ while(fgets(buf, sizeof(buf), sfile)) {
+ lineno++;
+ dk3app_set_source_line(job->app, lineno);
+ dk3str_c8_delnl(buf);
+ cptr = buf;
+#if 0
+ while(cptr) {
+ p1 = dk3str_c8_chr(cptr, '$');
+ if(p1) {
+ switch(p1[1]) {
+ case '!': case '?': case '(': case '{': {
+ p1 = dk3str_c8_chr(&(p1[1]), '$');
+ if(p1) {
+ p2 = dk3str_c8_chr(&(p1[1]), '$');
+ if(p2) {
+ if(!dkwxwiz_one_macro(job, dfile, sfile, cptr, p1, p2)) {
+ back = 0;
+ }
+ cptr = ++p2;
+ } else {
+ fputs(cptr, dfile);
+ cptr = NULL;
+ }
+ } else {
+ fputs(cptr, dfile);
+ cptr = NULL;
+ }
+ } break;
+ default: {
+ p2 = dk3str_c8_chr(&(p1[1]), '$');
+ if(p2) {
+ if(!dkwxwiz_one_macro(job, dfile, sfile, cptr, p1, p2)) {
+ back = 0;
+ }
+ cptr = ++p2;
+ } else {
+ fputs(cptr, dfile);
+ cptr = NULL;
+ }
+ } break;
+ }
+ } else {
+ fputs(cptr, dfile);
+ cptr = NULL;
+ }
+ }
+#else
+ while(cptr) {
+ p1 = dkwxwiz_find_macro_start(cptr);
+ if(p1) {
+ p2 = dk3str_c8_chr(&(p1[1]), '$');
+ if(p2) {
+ if(!dkwxwiz_one_macro(job, dfile, sfile, cptr, p1, p2)) {
+ back = 0;
+ }
+ cptr = p2;
+ cptr++;
+ } else {
+ fputs(cptr, dfile);
+ cptr = NULL;
+ }
+ } else {
+ fputs(cptr, dfile),
+ cptr = NULL;
+ }
+ }
+#endif
+ /* fputs(dkwxwiz_nl[(iswin) ? 13 : 14], dfile); */
+ if(iswin) {
+ fputc(0x0d, dfile);
+ }
+ fputc(0x0a, dfile);
+ }
+ dk3app_set_source_line(job->app, oldsourceline);
+
+
+#line 835 "dkwxwiz.ctr"
+ return back;
+}
+
+
+
+/** Produce one output file.
+ @param job Job structure.
+ @param dn Destination file name.
+ @param sn Source file name (template).
+ @param isbin Flag: Open output for binary writing.
+ @param iswin Flag: Use Windows line ends.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkwxwiz_one_output_file(
+ DKWXWIZ_JOB *job,
+ dkChar const *dn,
+ dkChar const *sn,
+ int isbin,
+ int iswin
+)
+{
+ dk3_search_t *sres; /* Search result set. */
+ FILE *sfile; /* Source file. */
+ FILE *dfile; /* Destination file. */
+ dkChar const *srcname; /* Source file name. */
+ dkChar const *oldsourcename; /* Old source file name. */
+ int back = 0;
+
+
+#line 865 "dkwxwiz.ctr"
+ oldsourcename = dk3app_get_source_file(job->app);
+ sres = dk3app_find_config_file_revers(job->app, sn, 0);
+ if(sres) {
+
+#line 868 "dkwxwiz.ctr"
+ dk3search_reset(sres);
+ srcname = dk3search_next(sres);
+ if(srcname) {
+
+#line 871 "dkwxwiz.ctr"
+ sfile = dk3sf_fopen_app(srcname, dkwxwiz_nl[6], job->app);
+ if(sfile) {
+
+#line 873 "dkwxwiz.ctr"
+ dfile = dk3sf_fopen_app(dn, dkwxwiz_nl[(isbin) ? 12 : 7], job->app);
+ if(dfile) {
+
+#line 875 "dkwxwiz.ctr"
+ dk3app_set_source_file(job->app, sn);
+ back = dkwxwiz_transfer_file(job, dfile, sfile, iswin);
+ if(!dk3sf_fclose_fn_app(dfile, dn, job->app)) {
+ back = 0;
+ }
+ } else {
+
+#line 881 "dkwxwiz.ctr"
+ }
+ fclose(sfile);
+ } else {
+
+#line 884 "dkwxwiz.ctr"
+ }
+ } else {
+
+#line 886 "dkwxwiz.ctr"
+ /* ERROR: File sn not found! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 150, 151, sn);
+ }
+ dk3search_close(sres);
+ } else {
+
+#line 891 "dkwxwiz.ctr"
+ }
+ dk3app_set_source_file(job->app, oldsourcename);
+
+
+#line 894 "dkwxwiz.ctr"
+ return back;
+}
+
+
+
+/** Copy a binary file directly.
+ @param job Job structure.
+ @param dn Destination file name.
+ @param sn Source file name.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkwxwiz_copy_binary(DKWXWIZ_JOB *job, dkChar const *dn, dkChar const *sn)
+{
+ char buf[4096]; /* Data buffer for copying. */
+ dk3_search_t *sres; /* Search result set. */
+ dkChar const *srcname; /* Source file name. */
+ FILE *sfile; /* Source file. */
+ FILE *dfile; /* Destination file. */
+ size_t rdbytes; /* Number of bytes read. */
+ size_t wrbytes; /* Number of bytes written. */
+ int back = 0;
+
+ sres = dk3app_find_config_file_revers(job->app, sn, 0);
+ if(sres) {
+ dk3search_reset(sres);
+ srcname = dk3search_next(sres);
+ if(srcname) {
+ sfile = dk3sf_fopen_app(srcname, dkwxwiz_nl[19], job->app);
+ if(sfile) {
+ dfile = dk3sf_fopen_app(dn, dkwxwiz_nl[12], job->app);
+ if(dfile) {
+ back = 1;
+ do {
+ rdbytes = fread(buf, 1, sizeof(buf), sfile);
+ if(rdbytes > 0) {
+ wrbytes = fwrite(buf, 1, rdbytes, dfile);
+ if(wrbytes != rdbytes) {
+ back = 0;
+ /* ERROR: Write operation failed! */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 120);
+ }
+ }
+ } while((rdbytes > 0) && (1 == back));
+ if(!dk3sf_fclose_fn_app(dfile, dn, job->app)) {
+ back = 0;
+ }
+ }
+ fclose(sfile);
+ }
+ } else {
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 150, 151, sn);
+ }
+ dk3search_close(sres);
+ }
+ return back;
+}
+
+
+
+/** Produce output files.
+ @param job Job structure.
+*/
+static
+void
+dkwxwiz_produce_output(DKWXWIZ_JOB *job)
+{
+
+
+#line 963 "dkwxwiz.ctr"
+ if(dkwxwiz_one_output_file(job, job->pfn, dkwxwiz_nl[3], 0, 0))
+ {
+ if(dkwxwiz_one_output_file(job, job->afn, dkwxwiz_nl[4], 0, 0))
+ {
+ if(dkwxwiz_one_output_file(job, job->ffn, dkwxwiz_nl[5], 0, 0))
+ {
+ if(dkwxwiz_one_output_file(job, dkwxwiz_nl[8], dkwxwiz_nl[10], 0, 0))
+ {
+ if(dkwxwiz_one_output_file(job, dkwxwiz_nl[9], dkwxwiz_nl[11],0,0))
+ {
+ if(dkwxwiz_one_output_file(job, job->xfn, dkwxwiz_nl[16], 1, 0))
+ {
+ if(dkwxwiz_copy_binary(job, job->ifn, dkwxwiz_nl[18])) {
+ if(dkwxwiz_one_output_file(job,dkwxwiz_nl[22],dkwxwiz_nl[23],1,1))
+ {
+ if(dkwxwiz_one_output_file(job,job->rfn,dkwxwiz_nl[21],1,1)) {
+ job->exv = 0;
+ /* You should provide the following files: */
+ dk3sf_initialize_stdout();
+ dk3sf_fputs((job->msg)[12], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ /* Windows help file: */
+ dk3sf_fputs((job->msg)[13], stdout);
+ dk3sf_fputs(job->aName, stdout);
+ dk3sf_fputs((job->msg)[18], stdout);
+ dk3sf_fputs((job->msg)[17], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ /* non-Windows help file: */
+ dk3sf_fputs((job->msg)[14], stdout);
+ dk3sf_fputs(job->aName, stdout);
+ dk3sf_fputs((job->msg)[19], stdout);
+ dk3sf_fputs((job->msg)[17], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ /* Windows icon file (ico) */
+ dk3sf_fputs((job->msg)[15], stdout);
+ dk3sf_fputs(job->aName, stdout);
+ dk3sf_fputs((job->msg)[20], stdout);
+ dk3sf_fputs((job->msg)[17], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ /* non-Windows icon file (xpm) */
+ dk3sf_fputs((job->msg)[16], stdout);
+ dk3sf_fputs(job->aName, stdout);
+ dk3sf_fputs((job->msg)[21], stdout);
+ dk3sf_fputs((job->msg)[17], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+#line 1017 "dkwxwiz.ctr"
+}
+
+
+
+
+/** Check whether character starts or continues an identifier.
+ @param c Character to process.
+ @param isfirst Flag: Is start of string.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkwxwiz_valid_identifier_char(char c, int isfirst)
+{
+ int back = 0;
+ if('_' == c) {
+ back = 1;
+ } else {
+ if(('a' <= c) && ('z' >= c)) {
+ back = 1;
+ } else {
+ if(('A' <= c) && ('Z' >= c)) {
+ back = 1;
+ } else {
+ if(!(isfirst)) {
+ if('0' == c) {
+ back = 1;
+ } else {
+ if(('1' <= c) && ('9' >= c)) {
+ back = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Check ASCII string whether it contains a C/C++ identifier
+ @param job Job structure.
+ @param txt Text to check.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkwxwiz_check_ascii_c_identifier(DKWXWIZ_JOB *job, char const *txt)
+{
+ char const *cptr; /* Current character to process. */
+ int isfirst = 1; /* Flag: Is first character. */
+ int back = 1;
+
+ cptr = txt;
+ while((*cptr) && (back)) {
+ if(!dkwxwiz_valid_identifier_char(*cptr, isfirst)) {
+ back = 0;
+ }
+ isfirst = 0;
+ cptr++;
+ }
+ return back;
+}
+
+
+
+/** Check one name whether or not it is a C/C++ identifier.
+ @param job Job structure.
+ @param txt Text to check.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkwxwiz_check_one_c_identifier(DKWXWIZ_JOB *job, dkChar const *txt)
+{
+ char buf[DK3_MAX_PATH]; /* Conversion buffer. */
+ int res; /* Conversion result. */
+ int back = 0;
+
+ res = dk3str_to_c8p_app(
+ buf, sizeof(buf), txt, dk3app_get_encoding(job->app), NULL
+ );
+ if(res) {
+ if(dkwxwiz_check_ascii_c_identifier(job, buf)) {
+ back = 1;
+ } else {
+ /* ERROR: Not a C/C++ identifier! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 24, 25, txt);
+ }
+ } else {
+ /* ERROR: Text is too long or contains non-ASCII characters! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 22, 23, txt);
+ }
+ return back;
+}
+
+
+
+/** Check program name, application class name, window class name.
+ @param job Job structure.
+ @return 1 on success (all names are valid C/C++ identifiers),
+ 0 on error.
+*/
+static
+int
+dkwxwiz_check_c_identifiers(DKWXWIZ_JOB *job)
+{
+ int back = 1;
+ if(!dkwxwiz_check_one_c_identifier(job, job->pName)) {
+ back = 0;
+ }
+ if(!dkwxwiz_check_one_c_identifier(job, job->aName)) {
+ back = 0;
+ }
+ if(!dkwxwiz_check_one_c_identifier(job, job->fName)) {
+ back = 0;
+ }
+ return back;
+}
+
+
+
+/** Run with known program, application and frame name.
+ @param job Job structure.
+*/
+static
+void
+dkwxwiz_run_with_names(DKWXWIZ_JOB *job)
+{
+
+
+#line 1148 "dkwxwiz.ctr"
+ if(dkwxwiz_build_file_names(job)) {
+ if(dkwxwiz_check_filenames(job)) {
+ if(dkwxwiz_check_c_identifiers(job)) {
+ dkwxwiz_produce_output(job);
+ }
+ }
+ }
+ dk3_release(job->ffn);
+ dk3_release(job->afn);
+ dk3_release(job->pfn);
+ dk3_release(job->xfn);
+ dk3_release(job->ifn);
+ dk3_release(job->rfn);
+
+
+#line 1162 "dkwxwiz.ctr"
+}
+
+
+
+/** Run the program normally (no help/version/license).
+ @param job Job structure.
+*/
+static
+void
+dkwxwiz_run_normally(DKWXWIZ_JOB *job)
+{
+ int nargs; /* Number of command line arguments. */
+
+
+#line 1175 "dkwxwiz.ctr"
+ nargs = dk3opt_get_num_args(job->opt);
+ if(3 <= nargs) {
+ job->pName = dk3opt_get_arg(job->opt, 0);
+ job->aName = dk3opt_get_arg(job->opt, 1);
+ job->fName = dk3opt_get_arg(job->opt, 2);
+ if((job->pName) && (job->aName) && (job->fName)) {
+ if(dk3opt_is_set(job->opt, dkT('f'))) {
+ job->frc = 1;
+ }
+ if(dk3opt_is_set(job->opt, dkT('o'))) {
+ job->obj = 1;
+ }
+ job->con = dk3opt_get_short_arg(job->opt, dkT('c'));
+ job->lin = dk3opt_get_short_arg(job->opt, dkT('l'));
+ dkwxwiz_run_with_names(job);
+ } else {
+ /* ERROR: Too few arguments. */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 11);
+ dk3app_help(job->app, dkwxwiz_msg[3], dkwxwiz_help_text);
+ }
+ } else {
+ /* ERROR: Too few arguments. */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 11);
+ dk3app_help(job->app, dkwxwiz_msg[3], dkwxwiz_help_text);
+ }
+
+#line 1200 "dkwxwiz.ctr"
+}
+
+
+
+/** Run the program.
+ @param job Job structure.
+*/
+static
+void
+dkwxwiz_run(DKWXWIZ_JOB *job)
+{
+ dkChar const * const *sptr; /* Pointer to traverse text. */
+
+
+#line 1213 "dkwxwiz.ctr"
+ job->opt = dk3opt_open_from_app(
+ dkwxwiz_options,
+ dkwxwiz_sz_options,
+ 0x00,
+ NULL,
+ job->app
+ );
+ if(job->opt) {
+ if(dk3opt_get_error_code(job->opt) == 0) {
+ if(dk3opt_is_set(job->opt, dkT('h'))) {
+ job->cmd |= DKWXWIZ_CMD_HELP;
+ }
+ if(dk3opt_is_set(job->opt, dkT('v'))) {
+ job->cmd |= DKWXWIZ_CMD_VERSION;
+ }
+ if(dk3opt_is_set(job->opt, dkT('L'))) {
+ job->cmd |= DKWXWIZ_CMD_LICENSE;
+ }
+ if(job->cmd) {
+ /* Version.
+ */
+ dk3sf_initialize_stdout();
+ dk3sf_fputs(dkwxwiz_msg[0], stdout);
+ dk3sf_fputc(dkT(' '), stdout);
+ dk3sf_fputs( DKT_VERSION_DK , stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ /* Help text.
+ */
+ if(DKWXWIZ_CMD_HELP & (job->cmd)) {
+ dk3app_help(job->app, dkwxwiz_msg[3], dkwxwiz_help_text);
+ }
+ /* License.
+ */
+ if(DKWXWIZ_CMD_LICENSE & (job->cmd)) {
+ sptr = dkwxwiz_license;
+ while(*sptr) {
+ dk3sf_fputs(*(sptr++), stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ }
+ } else {
+ dkwxwiz_run_normally(job);
+ }
+ }
+ dk3opt_close(job->opt);
+ job->opt = NULL;
+ }
+
+#line 1260 "dkwxwiz.ctr"
+}
+
+
+
+/** Program entry point.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, any other value indicates an error.
+*/
+DK3_MAIN
+{
+ DKWXWIZ_JOB job; /* Job structure. */
+ dk3_app_t *app = NULL; /* Application structure. */
+ dkChar const * const *msg = NULL; /* Localized messages. */
+ int exval; /* No success yet. */
+
+
+
+#line 1277 "dkwxwiz.ctr"
+
+
+#line 1278 "dkwxwiz.ctr"
+#if DK3_HAVE_TZSET
+ tzset();
+#endif
+ job.exv = 1;
+ app = dk3app_open_command(
+ argc, (dkChar const * const *)argv, dkwxwiz_msg[1]
+ );
+ if(app) {
+ msg = dk3app_messages(app, dkwxwiz_msg[2], (dkChar const **)dkwxwiz_msg);
+ dkwxwiz_job_init(&job, app, msg);
+ dkwxwiz_run(&job);
+ dk3app_close(app);
+ } else {
+ fputs("dkwxwiz: ERROR: Not enough memory!\n", stderr);
+ fflush(stderr);
+ }
+ exval = job.exv;
+
+
+#line 1296 "dkwxwiz.ctr"
+
+
+#line 1297 "dkwxwiz.ctr"
+ fflush(stdout);
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/dkwxwiz.ctr b/support/dktools/dkwxwiz.ctr
new file mode 100644
index 0000000000..2c3b7f03cf
--- /dev/null
+++ b/support/dktools/dkwxwiz.ctr
@@ -0,0 +1,1300 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2013-xxxx
+license = bsd
+
+
+%% module
+
+#include "dk3all.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4vers.h"
+
+
+$!trace-include
+
+
+
+/** @defgroup dkwxwizcmd Commands for dkwxwiz.
+*/
+/**@{*/
+
+/** Show help text.
+*/
+#define DKWXWIZ_CMD_HELP 1
+
+/** Show version information.
+*/
+#define DKWXWIZ_CMD_VERSION 2
+
+/** Show license terms.
+*/
+#define DKWXWIZ_CMD_LICENSE 4
+
+/**@}*/
+
+
+/** Job structure for dkwxwiz.
+*/
+typedef struct {
+ dk3_app_t *app; /**< Application structure. */
+ dkChar const * const *msg; /**< Localized messages texts. */
+ dk3_option_set_t *opt; /**< Command line options. */
+ dkChar const *con; /**< Copyright holder name. */
+ dkChar const *lin; /**< License name. */
+ dkChar const *pName; /**< Program name. */
+ dkChar const *aName; /**< Application class name. */
+ dkChar const *fName; /**< Frame class name. */
+ dkChar const *xfn; /**< XPM file name (allocated). */
+ dkChar const *pfn; /**< Program header file name. */
+ dkChar const *afn; /**< Application class file name. */
+ dkChar const *ffn; /**< Frame class file name. */
+ dkChar const *ifn; /**< Icon file name. */
+ dkChar const *rfn; /**< RC file name. */
+ int exv; /**< Exit value. */
+ int cmd; /**< Command to execute. */
+ int frc; /**< Force overwriting existing files. */
+ int obj; /**< Flag: Use object modules, not libs. */
+} DKWXWIZ_JOB;
+
+
+
+/** Macros like $program$ are allowed in the templates.
+*/
+static char const * const dkwxwiz_macros[] = {
+$!string-table
+#
+# 0
+#
+program
+#
+# 1
+#
+application
+#
+# 2
+#
+frame
+#
+# 3
+#
+year
+#
+# 4
+#
+copyrightowner
+#
+# 5
+#
+licensetype
+$!end
+};
+
+
+
+/** Constant dkChar strings, not localized.
+*/
+static dkChar const * const dkwxwiz_nl[] = {
+$!string-table macro=dkT
+#
+# 0: Suffix .h
+#
+.h
+#
+# 1: Suffix .cpt
+#
+.cpt
+#
+# 2: Suffix .wxc
+#
+.wxc
+#
+# 3: Program header file name.
+#
+dkwxwizh.txt
+#
+# 4: Application class file name.
+#
+dkwxwiza.txt
+#
+# 5: Frame class file name.
+#
+dkwxwizf.txt
+#
+# 6: Open mode read
+#
+r
+#
+# 7: Open mode write
+#
+w
+#
+# 8: Makefile name Makefile.in
+#
+Makefile.in
+#
+# 9: Autoconf file configure.ac
+#
+configure.ac
+#
+# 10: Souce for Makefile.in
+#
+dkwxwizm.txt
+#
+# 11: Source for configure.ac
+#
+dkwxwizc.txt
+#
+# 12: Write mode binary
+#
+wb
+#
+# 13: Windows line end.
+#
+\r\n
+#
+# 14: Normal line end.
+#
+\n
+#
+# 15: XPM file name suffix
+#
+.xpm
+#
+# 16: XPM file template
+#
+dkwxwizx.txt
+#
+# 17: Icon file name suffix
+#
+.ico
+#
+# 18: Icon file
+#
+dkwxwiz.ico
+#
+# 19: File open mode read binary.
+#
+rb
+#
+# 20: Suffix for rc file
+#
+.rc
+#
+# 21: Resource file template file name.
+#
+dkwxwizr.txt
+#
+# 22: VC makefile name
+#
+makefile.vc
+#
+# 23: VC makefile template file name.
+#
+dkwxwizv.txt
+$!end
+};
+
+
+
+/** Constant dkChar strings, localized versions are used if found.
+*/
+static dkChar const * const dkwxwiz_msg[] = {
+$!string-table macro=dkT
+#
+# 0: Program name.
+#
+dkwxwiz
+#
+# 1: Program group name.
+#
+dktools
+#
+# 2: String table file name.
+#
+dkwxwiz.str
+#
+# 3: Help file name.
+#
+dkwxwiz.txt
+#
+# 4: Copyright owner.
+#
+__CHANGE__ 001: Copyright owner
+#
+# 5: License type.
+#
+bsd
+#
+# 6 7 File base name too long!
+#
+File base name "
+" too long!
+#
+# 8 9 File already exists!
+#
+File "
+" already exists!
+#
+# 10
+#
+Unknown macro in line!
+#
+# 11
+#
+Too few command line arguments!
+#
+# 12
+#
+You should create/modify the following files:
+#
+# 13 14 15 16 17
+#
+Windows help file: "
+non-Windows help file: "
+Windows icon file: "
+non-Windows icon file: "
+".
+#
+# 18 19 20 21
+#
+.chm
+.htb
+.ico
+.xpm
+#
+# 22 23
+#
+Text too long or not ASCII: "
+"!
+#
+# 24 25
+#
+Not a C/C++ identifier: "
+"!
+$!end
+};
+
+
+
+/** License conditions shown for dkwxwiz --license-terms.
+*/
+static dkChar const * const dkwxwiz_license[] = {
+$!text macro=dkT
+
+Copyright (c) 2013-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the copyright holder(s) nor the names of
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+$!end
+};
+
+
+/** Options allowed for dkwxwiz.
+*/
+static dk3_option_t const dkwxwiz_options[] = {
+ { dkT('h'), dkT("help"), 0 },
+ { dkT('v'), dkT("version"), 0 },
+ { dkT('L'), dkT("license-terms"), 0 },
+ { dkT('f'), dkT("force"), 0},
+ { dkT('l'), dkT("license"), 1 },
+ { dkT('c'), dkT("copyright-owner"), 1 },
+ { dkT('o'), dkT("object-modules"), 0 },
+};
+
+
+/** Number of options in the dkwxwiz_options array.
+*/
+static size_t dkwxwiz_sz_options =
+sizeof(dkwxwiz_options)/sizeof(dk3_option_t);
+
+
+
+/** Default help text, shown if no help file is found.
+*/
+static dkChar const * dkwxwiz_help_text[] = {
+$!text macro=dkT
+
+NAME
+
+ dkwxwiz - Wizard to create a wxWidgets + dkct based project.
+
+SYNOPSIS
+
+ dkwxwiz [<options>] <program> <application> <window>
+
+DESCRIPTION
+
+The program creates source code skeletons for a new GUI application based
+on wxWidgets assuming you use the dktools libraries and the dkct program
+during development.
+As arguments you have to specify:
+
+* Name of the final program (i.e. "myprog").
+
+* Name of the application class derived from wxApp (i.e, "MyProgApp").
+
+* Name of the main window class (i.e. "MyProgFrame").
+
+Valid C/C++ identifiers are required for all three names.
+
+OPTIONS
+
+-h --help
+ Show a help text.
+
+-v --version
+ Show the program version.
+
+-L --license-terms
+ Show the license conditions.
+
+-f --force
+ Force the program to overwrite existing files.
+
+-c <copyright owner name>
+ Name of the copyright owner.
+
+-l <license type>
+ License type (i.e. "bsd").
+
+EXIT STATUS
+
+0 on success, all other exit status codes indicate an error.
+
+EXAMPLES
+
+Run
+ dkwxwiz testprog TestApp TestFrame
+in an empty directory to create a new project.
+
+FILES
+
+The following files from the dktools resource directory are used:
+
+dkwxwizh.txt Template for project header file *.h.
+
+dkwxwiza.txt Template for application class source *.cpt
+
+dkwxwizf.txt Template for top-level window class source *.wxc.
+
+dkwxwizc.txt Template for configure.ac file for autoconf.
+
+dkwxwizm.txt Template for the Makefile.in file.
+
+dkwxwizx.txt Template for the *.xpm icon file.
+
+You can create copies of these files in dkt-3-site and modify them
+i.e. to set a default copyright owner and a default license type.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
+AUTHOR
+
+Dirk Krause
+
+LICENSE
+
+Use
+ dkwxwiz --license-terms
+to view the license conditions.
+$!end
+};
+
+
+/** Initialize job structure.
+ @param job Job structure to initialize.
+ @param app Application structure.
+ @param msg Localized message texts.
+*/
+static
+void
+dkwxwiz_job_init(DKWXWIZ_JOB *job, dk3_app_t *app, dkChar const * const *msg)
+{
+ job->app = app;
+ job->msg = msg;
+ job->opt = NULL;
+ job->pName = NULL;
+ job->aName = NULL;
+ job->fName = NULL;
+ job->xfn = NULL;
+ job->pfn = NULL;
+ job->afn = NULL;
+ job->ffn = NULL;
+ job->ifn = NULL;
+ job->rfn = NULL;
+ job->exv = 1;
+ job->cmd = 0;
+ job->frc = 0;
+ job->obj = 0;
+ job->con = NULL;
+ job->lin = NULL;
+}
+
+
+
+/** Concatenate base name and file suffix.
+ @param job Job structure.
+ @param bn Base file name.
+ @param sf File name suffix.
+ @return Pointer to new allocated file name on success, NULL on error.
+*/
+static
+dkChar const *
+dkwxwiz_concatenate(DKWXWIZ_JOB *job, dkChar const *bn, dkChar const *sf)
+{
+ dkChar buf[DK3_MAX_PATH]; /* Temporary name buffer. */
+ dkChar const *back = NULL;
+ $? "+ dkwxwiz_concatenate"
+ if(DK3_SIZEOF(buf,dkChar) > (dk3str_len(bn) + dk3str_len(sf))) {
+ dk3str_cpy_not_overlapped(buf, bn);
+ dk3str_cat(buf, sf);
+ back = (dkChar const *)dk3str_dup_app(buf, job->app);
+ } else {
+ /* ERROR: Base name too long! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 6, 7, bn);
+ } $? "- dkwxwiz_concatenate PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/** Build file names for output files.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkwxwiz_build_file_names(DKWXWIZ_JOB *job)
+{
+ int back = 0;
+ $? "+ dkwxwiz_build_file_names"
+ job->pfn = dkwxwiz_concatenate(job, job->pName, dkwxwiz_nl[0]);
+ job->afn = dkwxwiz_concatenate(job, job->aName, dkwxwiz_nl[1]);
+ job->ffn = dkwxwiz_concatenate(job, job->fName, dkwxwiz_nl[2]);
+ job->xfn = dkwxwiz_concatenate(job, job->pName, dkwxwiz_nl[15]);
+ job->ifn = dkwxwiz_concatenate(job, job->pName, dkwxwiz_nl[17]);
+ job->rfn = dkwxwiz_concatenate(job, job->pName, dkwxwiz_nl[20]);
+ if((job->pfn) && (job->afn) && (job->ffn) && (job->xfn) && (job->ifn)) {
+ if(job->rfn) {
+ back = 1;
+ }
+ } $? "- dkwxwiz_build_file_names %d", back
+ return back;
+}
+
+
+
+/** Check one file name whether we can write the file.
+ @param job Job structure.
+ @param fn Output file name.
+ @return 1 if allowed to write the file, 0 otherwise.
+*/
+static
+int
+dkwxwiz_check_one_filename(DKWXWIZ_JOB *job, dkChar const *fn)
+{
+ dk3_stat_t stb; /* File information. */
+ int back = 0;
+ $? "+ dkwxwiz_check_one_filename"
+ if(0 == dk3sf_stat_app(&stb, fn, NULL)) {
+ back = 1;
+ } else {
+ /* ERROR: File already exists! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 8, 9, fn);
+ } $? "- dkwxwiz_check_one_filename %d", back
+ return back;
+}
+
+
+
+/** Check whether we can write all files.
+ @param job Job structure.
+ @return 1 if we are allowed to write/overwrite the files, 0 otherwise.
+*/
+static
+int
+dkwxwiz_check_filenames(DKWXWIZ_JOB *job)
+{
+ int back = 0;
+ $? "+ dkwxwiz_check_filenames"
+ if(job->frc) {
+ back = 1;
+ } else {
+ back = 1;
+ if(!dkwxwiz_check_one_filename(job, job->pfn)) {
+ back = 0;
+ }
+ if(!dkwxwiz_check_one_filename(job, job->afn)) {
+ back = 0;
+ }
+ if(!dkwxwiz_check_one_filename(job, job->ffn)) {
+ back = 0;
+ }
+ if(!dkwxwiz_check_one_filename(job, job->xfn)) {
+ back = 0;
+ }
+ if(!dkwxwiz_check_one_filename(job, dkwxwiz_nl[8])) {
+ back = 0;
+ }
+ if(!dkwxwiz_check_one_filename(job, dkwxwiz_nl[9])) {
+ back = 0;
+ }
+ if(!dkwxwiz_check_one_filename(job, job->ifn)) {
+ back = 0;
+ }
+ if(!dkwxwiz_check_one_filename(job, job->rfn)) {
+ back = 0;
+ }
+ if(!dkwxwiz_check_one_filename(job, dkwxwiz_nl[22])) {
+ back = 0;
+ }
+ } $? "- dkwxwiz_check_filenames %d", back
+ return back;
+}
+
+
+
+/** Write one string as 8-bit character text to output.
+ @param job Job structure.
+ @param dfile Destination file.
+ @param txt Text to write.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkwxwiz_write_c8_string(DKWXWIZ_JOB *job, FILE *dfile, dkChar const *txt)
+{
+#if DK3_CHAR_SIZE > 1
+ char buf[1024]; /* Temporary buffer for output. */
+#endif
+ int back = 0;
+#if DK3_CHAR_SIZE > 1
+ int res = 0;
+ $? "+ dkwxwiz_write_c8_string"
+ res = dk3str_to_c8p_app(
+ buf, sizeof(buf), txt, dk3app_get_encoding(job->app), job->app
+ );
+ if(res) {
+ fputs(buf, dfile);
+ back = 1;
+ } $? "- dkwxwiz_write_c8_string %d", back
+#else
+ $? "+ dkwxwiz_write_c8_string PTR=%d", TR_IPTR(txt)
+ fputs(txt, dfile);
+ back = 1; $? "- dkwxwiz_write_c8_string %d", back
+#endif
+ return back;
+}
+
+
+
+/** Process one macro.
+ @param job Job structure.
+ @param dfile Output (destination) file.
+ @param sfile Input (source) file.
+ @param cptr Start of text.
+ @param p1 First '$' character.
+ @param p2 Second '$' character.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkwxwiz_one_macro(
+ DKWXWIZ_JOB *job,
+ FILE *dfile,
+ FILE *sfile,
+ char *cptr,
+ char *p1,
+ char *p2
+)
+{
+ dk3_tm_t tm; /* Local time. */
+ dkChar const *vptr; /* Pointer to value text. */
+ dk3_time_t timer; /* Current time. */
+ int action; /* Macro action to perform. */
+ int back = 1;
+ *p1 = '\0';
+ fputs(cptr, dfile);
+ *p2 = '\0';
+#if VERSION_BEFORE_20150821
+ cptr = &(p2[1]);
+#endif
+ p1++;
+ action = dk3str_c8_array_index(dkwxwiz_macros, p1, 0);
+ switch(action) {
+ case 0: { /* program */
+ if(!dkwxwiz_write_c8_string(job, dfile, job->pName)) {
+ back = 0;
+ }
+ } break;
+ case 1: { /* application */
+ if(!dkwxwiz_write_c8_string(job, dfile, job->aName)) {
+ back = 0;
+ }
+ } break;
+ case 2: { /* frame */
+ if(!dkwxwiz_write_c8_string(job, dfile, job->fName)) {
+ back = 0;
+ }
+ } break;
+ case 3: { /* year */
+ if(dk3sf_time(&timer)) {
+ if(dk3sf_localtime_app(&tm, &timer, job->app)) {
+ fprintf(dfile, "%04d", tm.Y);
+ } else {
+ back = 0;
+ }
+ } else {
+ /* ERROR: Failed to obtain current time. */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 80);
+ back = 0;
+ }
+ } break;
+ case 4: { /* copyrightowner */
+ vptr = job->con;
+ if(!(vptr)) { vptr = (job->msg)[4]; }
+ if(!dkwxwiz_write_c8_string(job, dfile, vptr)) {
+ back = 0;
+ }
+ } break;
+ case 5: { /* licensetype */
+ vptr = job->lin;
+ if(!(vptr)) { vptr = (job->msg)[5]; }
+ if(!dkwxwiz_write_c8_string(job, dfile, vptr)) {
+ back = 0;
+ }
+ } break;
+ default: {
+ /* ERROR: Unknown macro */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 10);
+ fputc('$', dfile);
+ fputs(p1, dfile);
+ fputc('$', dfile);
+ back = 0;
+ } break;
+ }
+ return back;
+}
+
+
+
+/** Find '$' character starting a dkwxwiz macro.
+ @param txt Text to search for macro.
+ @return Pointer to first macro found on success, NULL if no macro found.
+*/
+static
+char *
+dkwxwiz_find_macro_start(char *txt)
+{
+ char *p1; /* Probably start of new macro. */
+ char *back = NULL;
+ p1 = dk3str_c8_chr(txt, '$');
+ while((p1) && (!(back))) {
+ switch(p1[1]) {
+ case '!': case '?':
+ case '(': case '{':
+ case '@': case '*':
+ case '<': case '>':{
+ p1 = dk3str_c8_chr(&(p1[1]), '$');
+ } break;
+ default: {
+ back = p1;
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+/** Transfer one source file contents to destination file.
+ @param job Job structure.
+ @param dfile Destination file.
+ @param sfile Template file.
+ @param iswin Flag: Insist on Windows line ends.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkwxwiz_transfer_file(DKWXWIZ_JOB *job, FILE *dfile, FILE *sfile, int iswin)
+{
+ char buf[4096]; /* Line buffer. */
+ char *cptr; /* Remaining line to process. */
+ char *p1; /* Start of macro. */
+ char *p2; /* End of macro. */
+ unsigned long oldsourceline; /* Old source line number. */
+ unsigned long lineno = 0UL; /* Current source line. */
+ int back = 1;
+ $? "+ dkwxwiz_transfer_file"
+ oldsourceline = dk3app_get_source_line(job->app);
+ while(fgets(buf, sizeof(buf), sfile)) {
+ lineno++;
+ dk3app_set_source_line(job->app, lineno);
+ dk3str_c8_delnl(buf);
+ cptr = buf;
+#if 0
+ while(cptr) {
+ p1 = dk3str_c8_chr(cptr, '$');
+ if(p1) {
+ switch(p1[1]) {
+ case '!': case '?': case '(': case '{': {
+ p1 = dk3str_c8_chr(&(p1[1]), '$');
+ if(p1) {
+ p2 = dk3str_c8_chr(&(p1[1]), '$');
+ if(p2) {
+ if(!dkwxwiz_one_macro(job, dfile, sfile, cptr, p1, p2)) {
+ back = 0;
+ }
+ cptr = ++p2;
+ } else {
+ fputs(cptr, dfile);
+ cptr = NULL;
+ }
+ } else {
+ fputs(cptr, dfile);
+ cptr = NULL;
+ }
+ } break;
+ default: {
+ p2 = dk3str_c8_chr(&(p1[1]), '$');
+ if(p2) {
+ if(!dkwxwiz_one_macro(job, dfile, sfile, cptr, p1, p2)) {
+ back = 0;
+ }
+ cptr = ++p2;
+ } else {
+ fputs(cptr, dfile);
+ cptr = NULL;
+ }
+ } break;
+ }
+ } else {
+ fputs(cptr, dfile);
+ cptr = NULL;
+ }
+ }
+#else
+ while(cptr) {
+ p1 = dkwxwiz_find_macro_start(cptr);
+ if(p1) {
+ p2 = dk3str_c8_chr(&(p1[1]), '$');
+ if(p2) {
+ if(!dkwxwiz_one_macro(job, dfile, sfile, cptr, p1, p2)) {
+ back = 0;
+ }
+ cptr = p2;
+ cptr++;
+ } else {
+ fputs(cptr, dfile);
+ cptr = NULL;
+ }
+ } else {
+ fputs(cptr, dfile),
+ cptr = NULL;
+ }
+ }
+#endif
+ /* fputs(dkwxwiz_nl[(iswin) ? 13 : 14], dfile); */
+ if(iswin) {
+ fputc(0x0d, dfile);
+ }
+ fputc(0x0a, dfile);
+ }
+ dk3app_set_source_line(job->app, oldsourceline);
+ $? "- dkwxwiz_transfer_file %d", back
+ return back;
+}
+
+
+
+/** Produce one output file.
+ @param job Job structure.
+ @param dn Destination file name.
+ @param sn Source file name (template).
+ @param isbin Flag: Open output for binary writing.
+ @param iswin Flag: Use Windows line ends.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkwxwiz_one_output_file(
+ DKWXWIZ_JOB *job,
+ dkChar const *dn,
+ dkChar const *sn,
+ int isbin,
+ int iswin
+)
+{
+ dk3_search_t *sres; /* Search result set. */
+ FILE *sfile; /* Source file. */
+ FILE *dfile; /* Destination file. */
+ dkChar const *srcname; /* Source file name. */
+ dkChar const *oldsourcename; /* Old source file name. */
+ int back = 0;
+ $? "+ dkwxwiz_one_output_file"
+ oldsourcename = dk3app_get_source_file(job->app);
+ sres = dk3app_find_config_file_revers(job->app, sn, 0);
+ if(sres) { $? ". source found"
+ dk3search_reset(sres);
+ srcname = dk3search_next(sres);
+ if(srcname) { $? ". srcname"
+ sfile = dk3sf_fopen_app(srcname, dkwxwiz_nl[6], job->app);
+ if(sfile) { $? ". sfile"
+ dfile = dk3sf_fopen_app(dn, dkwxwiz_nl[(isbin) ? 12 : 7], job->app);
+ if(dfile) { $? ". dfile"
+ dk3app_set_source_file(job->app, sn);
+ back = dkwxwiz_transfer_file(job, dfile, sfile, iswin);
+ if(!dk3sf_fclose_fn_app(dfile, dn, job->app)) {
+ back = 0;
+ }
+ } else { $? "! dfile"
+ }
+ fclose(sfile);
+ } else { $? "! sfile"
+ }
+ } else { $? "! srcname"
+ /* ERROR: File sn not found! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 150, 151, sn);
+ }
+ dk3search_close(sres);
+ } else { $? "! sres"
+ }
+ dk3app_set_source_file(job->app, oldsourcename);
+ $? "- dkwxwiz_one_output_file %d", back
+ return back;
+}
+
+
+
+/** Copy a binary file directly.
+ @param job Job structure.
+ @param dn Destination file name.
+ @param sn Source file name.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkwxwiz_copy_binary(DKWXWIZ_JOB *job, dkChar const *dn, dkChar const *sn)
+{
+ char buf[4096]; /* Data buffer for copying. */
+ dk3_search_t *sres; /* Search result set. */
+ dkChar const *srcname; /* Source file name. */
+ FILE *sfile; /* Source file. */
+ FILE *dfile; /* Destination file. */
+ size_t rdbytes; /* Number of bytes read. */
+ size_t wrbytes; /* Number of bytes written. */
+ int back = 0;
+
+ sres = dk3app_find_config_file_revers(job->app, sn, 0);
+ if(sres) {
+ dk3search_reset(sres);
+ srcname = dk3search_next(sres);
+ if(srcname) {
+ sfile = dk3sf_fopen_app(srcname, dkwxwiz_nl[19], job->app);
+ if(sfile) {
+ dfile = dk3sf_fopen_app(dn, dkwxwiz_nl[12], job->app);
+ if(dfile) {
+ back = 1;
+ do {
+ rdbytes = fread(buf, 1, sizeof(buf), sfile);
+ if(rdbytes > 0) {
+ wrbytes = fwrite(buf, 1, rdbytes, dfile);
+ if(wrbytes != rdbytes) {
+ back = 0;
+ /* ERROR: Write operation failed! */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 120);
+ }
+ }
+ } while((rdbytes > 0) && (1 == back));
+ if(!dk3sf_fclose_fn_app(dfile, dn, job->app)) {
+ back = 0;
+ }
+ }
+ fclose(sfile);
+ }
+ } else {
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 150, 151, sn);
+ }
+ dk3search_close(sres);
+ }
+ return back;
+}
+
+
+
+/** Produce output files.
+ @param job Job structure.
+*/
+static
+void
+dkwxwiz_produce_output(DKWXWIZ_JOB *job)
+{
+ $? "+ dkwxwiz_produce_output"
+ if(dkwxwiz_one_output_file(job, job->pfn, dkwxwiz_nl[3], 0, 0))
+ {
+ if(dkwxwiz_one_output_file(job, job->afn, dkwxwiz_nl[4], 0, 0))
+ {
+ if(dkwxwiz_one_output_file(job, job->ffn, dkwxwiz_nl[5], 0, 0))
+ {
+ if(dkwxwiz_one_output_file(job, dkwxwiz_nl[8], dkwxwiz_nl[10], 0, 0))
+ {
+ if(dkwxwiz_one_output_file(job, dkwxwiz_nl[9], dkwxwiz_nl[11],0,0))
+ {
+ if(dkwxwiz_one_output_file(job, job->xfn, dkwxwiz_nl[16], 1, 0))
+ {
+ if(dkwxwiz_copy_binary(job, job->ifn, dkwxwiz_nl[18])) {
+ if(dkwxwiz_one_output_file(job,dkwxwiz_nl[22],dkwxwiz_nl[23],1,1))
+ {
+ if(dkwxwiz_one_output_file(job,job->rfn,dkwxwiz_nl[21],1,1)) {
+ job->exv = 0;
+ /* You should provide the following files: */
+ dk3sf_initialize_stdout();
+ dk3sf_fputs((job->msg)[12], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ /* Windows help file: */
+ dk3sf_fputs((job->msg)[13], stdout);
+ dk3sf_fputs(job->aName, stdout);
+ dk3sf_fputs((job->msg)[18], stdout);
+ dk3sf_fputs((job->msg)[17], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ /* non-Windows help file: */
+ dk3sf_fputs((job->msg)[14], stdout);
+ dk3sf_fputs(job->aName, stdout);
+ dk3sf_fputs((job->msg)[19], stdout);
+ dk3sf_fputs((job->msg)[17], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ /* Windows icon file (ico) */
+ dk3sf_fputs((job->msg)[15], stdout);
+ dk3sf_fputs(job->aName, stdout);
+ dk3sf_fputs((job->msg)[20], stdout);
+ dk3sf_fputs((job->msg)[17], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ /* non-Windows icon file (xpm) */
+ dk3sf_fputs((job->msg)[16], stdout);
+ dk3sf_fputs(job->aName, stdout);
+ dk3sf_fputs((job->msg)[21], stdout);
+ dk3sf_fputs((job->msg)[17], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } $? "- dkwxwiz_produce_output"
+}
+
+
+
+
+/** Check whether character starts or continues an identifier.
+ @param c Character to process.
+ @param isfirst Flag: Is start of string.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkwxwiz_valid_identifier_char(char c, int isfirst)
+{
+ int back = 0;
+ if('_' == c) {
+ back = 1;
+ } else {
+ if(('a' <= c) && ('z' >= c)) {
+ back = 1;
+ } else {
+ if(('A' <= c) && ('Z' >= c)) {
+ back = 1;
+ } else {
+ if(!(isfirst)) {
+ if('0' == c) {
+ back = 1;
+ } else {
+ if(('1' <= c) && ('9' >= c)) {
+ back = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Check ASCII string whether it contains a C/C++ identifier
+ @param job Job structure.
+ @param txt Text to check.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkwxwiz_check_ascii_c_identifier(DKWXWIZ_JOB *job, char const *txt)
+{
+ char const *cptr; /* Current character to process. */
+ int isfirst = 1; /* Flag: Is first character. */
+ int back = 1;
+
+ cptr = txt;
+ while((*cptr) && (back)) {
+ if(!dkwxwiz_valid_identifier_char(*cptr, isfirst)) {
+ back = 0;
+ }
+ isfirst = 0;
+ cptr++;
+ }
+ return back;
+}
+
+
+
+/** Check one name whether or not it is a C/C++ identifier.
+ @param job Job structure.
+ @param txt Text to check.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dkwxwiz_check_one_c_identifier(DKWXWIZ_JOB *job, dkChar const *txt)
+{
+ char buf[DK3_MAX_PATH]; /* Conversion buffer. */
+ int res; /* Conversion result. */
+ int back = 0;
+
+ res = dk3str_to_c8p_app(
+ buf, sizeof(buf), txt, dk3app_get_encoding(job->app), NULL
+ );
+ if(res) {
+ if(dkwxwiz_check_ascii_c_identifier(job, buf)) {
+ back = 1;
+ } else {
+ /* ERROR: Not a C/C++ identifier! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 24, 25, txt);
+ }
+ } else {
+ /* ERROR: Text is too long or contains non-ASCII characters! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 22, 23, txt);
+ }
+ return back;
+}
+
+
+
+/** Check program name, application class name, window class name.
+ @param job Job structure.
+ @return 1 on success (all names are valid C/C++ identifiers),
+ 0 on error.
+*/
+static
+int
+dkwxwiz_check_c_identifiers(DKWXWIZ_JOB *job)
+{
+ int back = 1;
+ if(!dkwxwiz_check_one_c_identifier(job, job->pName)) {
+ back = 0;
+ }
+ if(!dkwxwiz_check_one_c_identifier(job, job->aName)) {
+ back = 0;
+ }
+ if(!dkwxwiz_check_one_c_identifier(job, job->fName)) {
+ back = 0;
+ }
+ return back;
+}
+
+
+
+/** Run with known program, application and frame name.
+ @param job Job structure.
+*/
+static
+void
+dkwxwiz_run_with_names(DKWXWIZ_JOB *job)
+{
+ $? "+ dkwxwiz_run_with_names"
+ if(dkwxwiz_build_file_names(job)) {
+ if(dkwxwiz_check_filenames(job)) {
+ if(dkwxwiz_check_c_identifiers(job)) {
+ dkwxwiz_produce_output(job);
+ }
+ }
+ }
+ dk3_release(job->ffn);
+ dk3_release(job->afn);
+ dk3_release(job->pfn);
+ dk3_release(job->xfn);
+ dk3_release(job->ifn);
+ dk3_release(job->rfn);
+ $? "- dkwxwiz_run_with_names"
+}
+
+
+
+/** Run the program normally (no help/version/license).
+ @param job Job structure.
+*/
+static
+void
+dkwxwiz_run_normally(DKWXWIZ_JOB *job)
+{
+ int nargs; /* Number of command line arguments. */
+ $? "+ dkwxwiz_run_normally"
+ nargs = dk3opt_get_num_args(job->opt);
+ if(3 <= nargs) {
+ job->pName = dk3opt_get_arg(job->opt, 0);
+ job->aName = dk3opt_get_arg(job->opt, 1);
+ job->fName = dk3opt_get_arg(job->opt, 2);
+ if((job->pName) && (job->aName) && (job->fName)) {
+ if(dk3opt_is_set(job->opt, dkT('f'))) {
+ job->frc = 1;
+ }
+ if(dk3opt_is_set(job->opt, dkT('o'))) {
+ job->obj = 1;
+ }
+ job->con = dk3opt_get_short_arg(job->opt, dkT('c'));
+ job->lin = dk3opt_get_short_arg(job->opt, dkT('l'));
+ dkwxwiz_run_with_names(job);
+ } else {
+ /* ERROR: Too few arguments. */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 11);
+ dk3app_help(job->app, dkwxwiz_msg[3], dkwxwiz_help_text);
+ }
+ } else {
+ /* ERROR: Too few arguments. */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 11);
+ dk3app_help(job->app, dkwxwiz_msg[3], dkwxwiz_help_text);
+ } $? "- dkwxwiz_run_normally"
+}
+
+
+
+/** Run the program.
+ @param job Job structure.
+*/
+static
+void
+dkwxwiz_run(DKWXWIZ_JOB *job)
+{
+ dkChar const * const *sptr; /* Pointer to traverse text. */
+ $? "+ dkwxwiz_run"
+ job->opt = dk3opt_open_from_app(
+ dkwxwiz_options,
+ dkwxwiz_sz_options,
+ 0x00,
+ NULL,
+ job->app
+ );
+ if(job->opt) {
+ if(dk3opt_get_error_code(job->opt) == 0) {
+ if(dk3opt_is_set(job->opt, dkT('h'))) {
+ job->cmd |= DKWXWIZ_CMD_HELP;
+ }
+ if(dk3opt_is_set(job->opt, dkT('v'))) {
+ job->cmd |= DKWXWIZ_CMD_VERSION;
+ }
+ if(dk3opt_is_set(job->opt, dkT('L'))) {
+ job->cmd |= DKWXWIZ_CMD_LICENSE;
+ }
+ if(job->cmd) {
+ /* Version.
+ */
+ dk3sf_initialize_stdout();
+ dk3sf_fputs(dkwxwiz_msg[0], stdout);
+ dk3sf_fputc(dkT(' '), stdout);
+ dk3sf_fputs( DKT_VERSION_DK , stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ /* Help text.
+ */
+ if(DKWXWIZ_CMD_HELP & (job->cmd)) {
+ dk3app_help(job->app, dkwxwiz_msg[3], dkwxwiz_help_text);
+ }
+ /* License.
+ */
+ if(DKWXWIZ_CMD_LICENSE & (job->cmd)) {
+ sptr = dkwxwiz_license;
+ while(*sptr) {
+ dk3sf_fputs(*(sptr++), stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ }
+ } else {
+ dkwxwiz_run_normally(job);
+ }
+ }
+ dk3opt_close(job->opt);
+ job->opt = NULL;
+ } $? "- dkwxwiz_run"
+}
+
+
+
+/** Program entry point.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, any other value indicates an error.
+*/
+DK3_MAIN
+{
+ DKWXWIZ_JOB job; /* Job structure. */
+ dk3_app_t *app = NULL; /* Application structure. */
+ dkChar const * const *msg = NULL; /* Localized messages. */
+ int exval; /* No success yet. */
+
+ $!trace-init dkwxwiz.deb
+ $? "+ main"
+#if DK3_HAVE_TZSET
+ tzset();
+#endif
+ job.exv = 1;
+ app = dk3app_open_command(
+ argc, (dkChar const * const *)argv, dkwxwiz_msg[1]
+ );
+ if(app) {
+ msg = dk3app_messages(app, dkwxwiz_msg[2], (dkChar const **)dkwxwiz_msg);
+ dkwxwiz_job_init(&job, app, msg);
+ dkwxwiz_run(&job);
+ dk3app_close(app);
+ } else {
+ fputs("dkwxwiz: ERROR: Not enough memory!\n", stderr);
+ fflush(stderr);
+ }
+ exval = job.exv;
+ $? "- main %d", exval
+ $!trace-end
+ fflush(stdout);
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/dkwxwiz.rc b/support/dktools/dkwxwiz.rc
new file mode 100644
index 0000000000..9ba1da2cd9
--- /dev/null
+++ b/support/dktools/dkwxwiz.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Project wizard\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "Project wizard\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "dkwxwiz\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/etc-dk3app/dk3paper.conf b/support/dktools/etc-dk3app/dk3paper.conf
new file mode 100644
index 0000000000..21eb0e5a1e
--- /dev/null
+++ b/support/dktools/etc-dk3app/dk3paper.conf
@@ -0,0 +1,25 @@
+A3 = 842 1190
+A5 = 420 595
+A6 = 297 420
+Legal = 612 1008
+Tabloid = 792 1224
+Ledger = 1224 792
+Statement = 396 612
+Executive = 540 720
+Folio = 612 936
+Quarto = 610 780
+10X14 = 720 1008
+A3landscape = 1190 842
+A4landscape = 842 595
+A5landscape = 595 420
+A6landscape = 420 297
+a3 = 842 1190 56 28 14 14
+a5 = 420 595 42 28 14 14
+a6 = 297 420 42 28 14 14
+legal = 612 1008 56 28 14 14
+tabloid = 792 1224 56 28 14 14
+statement = 396 612 42 28 14 14
+executive = 540 720 56 28 14 14
+folio = 612 936 56 28 14 14
+quarto = 610 780 56 28 14 14
+10x14 = 720 1008 56 28 14 14
diff --git a/support/dktools/ex-sto.c b/support/dktools/ex-sto.c
new file mode 100644
index 0000000000..9686117dfc
--- /dev/null
+++ b/support/dktools/ex-sto.c
@@ -0,0 +1,616 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: ex-sto.ctr
+*/
+
+/*
+Copyright (C) 2011-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#line 10 "ex-sto.ctr"
+
+
+/** @file
+ Test program for storage containers.
+
+The ex-sto program is a test and demonstration program for
+storage containers.
+
+The program stores information about persons:
+- surname,
+- family name and
+- age.
+
+The program reads input line by line, each input line is a command.
+The following commands can be used:
+- add _surname_ _family-name_ _age_
+- del f _family-name_
+- del s _surname_
+- del a _age_
+- read _filename_
+- print
+- tree
+- find f _family-name_
+- find s _surname_
+- find a _age_
+- quit
+
+The add command can be used to add persons.
+
+The del command deletes one or multiple records matching the specified
+family name, surname or age.
+
+The read command reads an input file typically containing add commands.
+
+The find command searches for the record for a given family name,
+surname or age.
+
+The print command prints all records beginning at the current record
+(the first record in the container or the element found in the last
+find command) until the end of the container.
+
+The tree command command prints the tree structures of a container.
+
+The quit command can be used to exit the application.
+
+Input to the program might look like
+@code
+add Erwin Unsinn 30
+add David Zeppelin 40
+add Johann Unfug 50
+add Alter Sack 99
+add Bla Blubb 33
+print
+find a 40
+find a 45
+del s Johann
+print
+tree
+quit
+@endcode
+
+@see ex-sto.c
+
+@example ex-sto.c
+*/
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4mem.h"
+#include "dk4sto.h"
+#include "dk4str8.h"
+
+#include <string.h>
+
+
+
+
+#line 85 "ex-sto.ctr"
+
+
+
+/** Description of a person.
+*/
+typedef struct {
+ char *famname; /**< Family name */
+ char *surname; /**< Surname */
+ unsigned long age; /**< Age in years */
+} Person;
+
+/** Storage, persons sorted by family name. */
+static dk4_sto_t *s1;
+
+/** Storage, persons sorted by surname. */
+static dk4_sto_t *s2;
+
+/** Storage, persons sorted by age. */
+static dk4_sto_t *s3;
+
+/** Storage, persons unsorted. */
+static dk4_sto_t *s4;
+
+/** Iterator for storage sorted by family name. */
+static dk4_sto_it_t *i1;
+
+/** Iterator for storage sorted by surname. */
+static dk4_sto_it_t *i2;
+
+/** Iterator for storage sorted by age. */
+static dk4_sto_it_t *i3;
+
+/** Iterator for unsorted storage. */
+static dk4_sto_it_t *i4;
+
+/** Flag, input processing can be continued. */
+static int can_continue;
+
+/** Flag, stdin is connected to terminal. */
+static int stdin_is_tty = 1;
+
+static void read_file(FILE *);
+
+
+
+/** Retrieve age from pointer.
+ The function retrieves an age evaluation of a pointer.
+ The pointer target is either a struct Person or an
+ unsigned long.
+ @param p Pointer to person or unsigned long.
+ @param cr Pointer object type:
+ - 1: \a p points to a struct Person,
+ - anything else: \a p points to an unsigned long.
+ @return The age.
+*/
+unsigned long age_fct(void const *p, int cr)
+{
+ unsigned long back;
+ switch(cr) {
+ case 1: {
+ back = *((unsigned long const *)p);
+ } break;
+ default: {
+ back = ((Person const *)p)->age;
+ } break;
+ }
+ return back;
+}
+
+
+
+/** Compare object against other object or text.
+ @param p1 Left pointer (from storage).
+ @param p2 Right pointer (from dk4sto_it_find_like()).
+ @param cr Comparison criteria:
+ - 0 indicates: p1 and p2 are pointers to struct Person,
+ compare by family name.
+ - 1 indicates: p1 is a pointer to a struct Person, p2 is a
+ pointer to a string. Compare the family name of p1
+ against the string.
+ - 2 indicates: p1 and p2 are pointers to struct Person,
+ compare by surname.
+ - 3 indicates: p1 is a pointer to a struct person, p2 is a
+ pointer to a string. Compare the surname of p1 against
+ the string.
+ @return Comparison result:
+ - Positive value, if left pointer is larger (or behind),
+ - Negative value, if left pointer is smaller (or before),
+ - 0 if both pointers evaluate equal.
+*/
+int compare_fct(void const *p1, void const *p2, int cr)
+{
+ int back = 0;
+ switch(cr) {
+ case 0: {
+ back = strcmp(((Person *)p1)->famname, ((Person *)p2)->famname);
+ } break;
+ case 1: {
+ back = strcmp(((Person *)p1)->famname, (char *)p2);
+ } break;
+ case 2: {
+ back = strcmp(((Person *)p1)->surname, ((Person *)p2)->surname);
+ } break;
+ case 3: {
+ back = strcmp(((Person *)p1)->surname, (char *)p2);
+ } break;
+ }
+ return back;
+}
+
+
+
+/** Print a prompt.
+*/
+static void print_prompt(void)
+{
+ if(stdin_is_tty) {
+ printf("\nstotest: ");
+ }
+}
+
+
+
+/** Print one persons record.
+ @param pers Person structure.
+ @param fout Output file.
+*/
+static void print_person(Person *pers, FILE *fout)
+{
+ fprintf(
+ fout,
+ "%s %s %lu\n",
+ ((pers->surname) ? pers->surname : "-"),
+ ((pers->famname) ? pers->famname : "-"),
+ pers->age
+ );
+}
+
+
+
+/** Print persons record from an iterators current
+ position until the end of the container.
+ @param i Storage iterator.
+ @param fout Output file.
+*/
+static void print_it(dk4_sto_it_t *i, FILE *fout)
+{
+ void *p;
+ dk4sto_it_reset(i);
+ while((p = dk4sto_it_next(i)) != NULL) {
+ print_person((Person *)p, fout);
+ fprintf(fout, "\n");
+ }
+}
+
+
+
+/** Print storage tree node including subtree.
+ This function is used to show the tree structure.
+ In your applications you should not access the internal
+ members of a dk4_sto_t or dk4_sto_node_t directly.
+ @param n Storage node.
+ @param num Indent depth.
+ @param f Output file.
+ @param c Key character for node.
+*/
+void print_node(dk4_sto_node_t *n, int num, FILE *f, char c)
+{
+ int i;
+ Person *pers;
+ if(n) {
+ for(i = 0; i < num; i++) {
+ fprintf(f, " ");
+ }
+ fprintf(f, "%c %5d (%d)", c, num, n->b);
+ pers = (Person *)(n->o);
+ if(pers) {
+ if(pers->surname) fprintf(f, " %s ", pers->surname);
+ else fprintf(f, " - ");
+ if(pers->famname) fprintf(f, " %s ", pers->famname);
+ else fprintf(f, " - ");
+ fprintf(f, " %lu", pers->age);
+ }
+ fprintf(f, " \tparent:");
+ if(n->p) {
+ if((n->p)->o) {
+ pers = (Person *)((n->p)->o);
+ if(pers->surname) fprintf(f, " %s ", pers->surname);
+ else fprintf(f, " - ");
+ if(pers->famname) fprintf(f, "%s ", pers->famname);
+ else fprintf(f, "- ");
+ fprintf(f, " %lu", pers->age);
+ }
+ }
+ fprintf(f, "\n");
+ print_node(n->l, (num+1), f, 'l');
+ print_node(n->r, (num+1), f, 'r');
+ }
+}
+
+
+
+/** Print the tree structure.
+ In your applications you should not access the internal
+ members of a dk4_sto_t or dk4_sto_node_t directly.
+ @param s Storage to print.
+ @param f Output file.
+*/
+void print_tree(dk4_sto_t *s, FILE *f)
+{
+ if((s->h) && (s->t)) {
+ print_node(s->r, 0, f, '+');
+ }
+}
+
+
+
+/** Free a persons record (release memory.)
+ @param pers Pointer to record to release.
+*/
+static void free_person(Person *pers)
+{
+ char *cptr;
+ if(pers) {
+ cptr = pers->famname;
+ dk4mem_free(cptr);
+ cptr = pers->surname;
+ dk4mem_free(cptr);
+ pers->famname = pers->surname = NULL;
+ dk4mem_free(pers);
+ }
+}
+
+
+
+/** Handle command without arguments.
+ @param str Command (first text in input line).
+*/
+static
+void
+handle_cmd_1(char *str)
+{
+ if(strcasecmp(str, "quit") == 0) {
+ can_continue = 0;
+ }
+ if(strcasecmp(str, "print") == 0) {
+ fprintf(stdout, "Sorted by family name:\n");
+ print_it(i1, stdout);
+ fprintf(stdout, "Sorted by surname:\n");
+ print_it(i2, stdout);
+ fprintf(stdout, "Sorted by age:\n");
+ print_it(i3, stdout);
+ fprintf(stdout, "Unsorted:\n");
+ print_it(i4, stdout);
+ }
+ if(strcasecmp(str, "tree") == 0) {
+ fprintf(stdout, "Sorted by family name:\n");
+ print_tree(s1, stdout);
+ fprintf(stdout, "Sorted by surname:\n");
+ print_tree(s2, stdout);
+ fprintf(stdout, "Sorted by age:\n");
+ print_tree(s3, stdout);
+ fprintf(stdout, "Unsorted:\n");
+ print_tree(s4, stdout);
+ }
+}
+
+
+
+/** Handle command with one argument.
+ @param cmd Command to handle.
+ @param arg1 Command argument.
+*/
+static void handle_cmd_2(char *cmd, char *arg1)
+{
+ if(strcasecmp(cmd, "read") == 0) {
+ FILE *in;
+ in = fopen(arg1, "r");
+ if(in) {
+ read_file(in);
+ fclose(in);
+ }
+ }
+}
+
+
+
+/** Handle command with 2 arguments.
+ @param cmd Command to handle.
+ @param arg1 Command argument 1.
+ @param arg2 Command argument 2.
+*/
+static void handle_cmd_3(char *cmd, char *arg1, char *arg2)
+{
+ void *p;
+ if(strcasecmp(cmd, "find") == 0) {
+ if(strcasecmp(arg1, "f") == 0) {
+ p = dk4sto_it_find_like(i1, arg2, 1);
+ if(p) {
+ print_person(p,stdout); printf("\n");
+ }
+ printf("Followers:\n");
+ while((p = (Person *)dk4sto_it_next(i1)) != NULL) {
+ print_person(p,stdout); printf("\n");
+ }
+ }
+ if(strcasecmp(arg1, "s") == 0) {
+ p = dk4sto_it_find_like(i2, arg2, 3);
+ if(p) {
+ print_person(p,stdout); printf("\n");
+ }
+ printf("Followers:\n");
+ while((p = (Person *)dk4sto_it_next(i2)) != NULL) {
+ print_person(p,stdout); printf("\n");
+ }
+ }
+ if(strcasecmp(arg1, "a") == 0) {
+ unsigned long age;
+ if(sscanf(arg2, "%lu", &age) == 1) {
+ p = dk4sto_it_find_like(i3, (void *)(&age), 1);
+ if(p) {
+ print_person(p,stdout); printf("\n");
+ }
+ printf("Followers:\n");
+ while((p = (Person *)dk4sto_it_next(i3)) != NULL) {
+ print_person(p,stdout); printf("\n");
+ }
+ }
+ }
+ }
+ if(strcasecmp(cmd, "del") == 0) {
+ if(strcasecmp(arg1, "f") == 0) {
+ while((p = dk4sto_it_find_like(i1, arg2, 1)) != NULL) {
+ dk4sto_remove(s1,p,NULL);
+ dk4sto_remove(s2,p,NULL);
+ dk4sto_remove(s3,p,NULL);
+ dk4sto_remove(s4,p,NULL);
+ free_person(p);
+ }
+ }
+ if(strcasecmp(arg1, "s") == 0) {
+ while((p = dk4sto_it_find_like(i2, arg2, 3)) != NULL) {
+ dk4sto_remove(s1,p,NULL);
+ dk4sto_remove(s2,p,NULL);
+ dk4sto_remove(s3,p,NULL);
+ dk4sto_remove(s4,p,NULL);
+ free_person(p);
+ }
+ }
+ if(strcasecmp(arg1, "a") == 0) {
+ unsigned long age;
+ if(sscanf(arg2, "%lu", &age) == 1) {
+ while((p = dk4sto_it_find_like(i3, (void *)(&age), 1)) != NULL) {
+ dk4sto_remove(s1,p,NULL);
+ dk4sto_remove(s2,p,NULL);
+ dk4sto_remove(s3,p,NULL);
+ dk4sto_remove(s4,p,NULL);
+ free_person(p);
+ }
+ }
+ }
+ }
+}
+
+
+
+/** Handle command with 3 arguments.
+ @param cmd Command to handle.
+ @param arg1 Command argument 1.
+ @param arg2 Command argument 2.
+ @param arg3 Command argument 3.
+*/
+static void handle_cmd_4(char *cmd, char *arg1, char *arg2, char *arg3)
+{
+ if(strcasecmp(cmd, "add") == 0) {
+ unsigned long age;
+ Person *pers;
+ if(sscanf(arg3, "%lu", &age) == 1) {
+ pers = dk4mem_new(Person,1,NULL);
+ if(pers) {
+ pers->famname = dk4str8_dup(arg2, NULL);
+ pers->surname = dk4str8_dup(arg1, NULL);
+ pers->age = age;
+ if(!((pers->famname) && (pers->surname))) {
+ free_person(pers);
+ } else {
+ if(!dk4sto_add(s4, (void *)pers, NULL)) {
+ free_person(pers);
+ } else {
+ dk4sto_add(s1, (void *)pers, NULL);
+ dk4sto_add(s2, (void *)pers, NULL);
+ dk4sto_add(s3, (void *)pers, NULL);
+ }
+ }
+ }
+ }
+ }
+}
+
+
+
+/** Read input file.
+ @param in File to read from.
+*/
+void read_file(FILE *in)
+{
+
+ char line[1024];
+ char *lbegin;
+ int i;
+ char str1[sizeof(line)];
+ char str2[sizeof(line)];
+ char str3[sizeof(line)];
+ char str4[sizeof(line)];
+ int old_can_continue;
+ old_can_continue = can_continue;
+ can_continue = 1;
+ while(can_continue) {
+ if(in == stdin) print_prompt();
+ if(fgets(line, sizeof(line), in)) {
+ lbegin = dk4str8_start(line, NULL);
+ if(lbegin) {
+ dk4str8_normalize(lbegin, NULL);
+ printf("# Processing \"%s\"\n", lbegin);
+ i = sscanf(lbegin, "%s %s %s %s", str1, str2, str3, str4);
+ switch(i) {
+ case 1: {
+ handle_cmd_1(str1);
+ } break;
+ case 2: {
+ handle_cmd_2(str1, str2);
+ } break;
+ case 3: {
+ handle_cmd_3(str1, str2, str3);
+ } break;
+ case 4: {
+ handle_cmd_4(str1, str2, str3, str4);
+ } break;
+ }
+ }
+ } else {
+ can_continue = 0;
+ }
+ }
+ can_continue = old_can_continue;
+}
+
+
+
+/** Main program.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return Exit status code.
+*/
+int main(int arg, char *argv[])
+{
+ void *p; Person *pers; char *cptr;
+ /* Check whether or not we are connected to a terminal */
+ /* stdin_is_tty = dksf_echo_test_tty(); */
+ stdin_is_tty = 1;
+ /* Create storage containers */
+ s1 = dk4sto_open(NULL);
+ s2 = dk4sto_open(NULL);
+ s3 = dk4sto_open(NULL);
+ s4 = dk4sto_open(NULL);
+ /* Check whether all containers were created successfully */
+ if(s1 && s2 && s3 && s4) {
+ /* Set comparison and evaluation functions */
+ dk4sto_set_comp(s1, compare_fct, 0);
+ dk4sto_set_comp(s2, compare_fct, 2);
+ dk4sto_set_eval_ul(s3, age_fct, 0);
+ /* Create storage container iterators */
+ i1 = dk4sto_it_open(s1, NULL);
+ i2 = dk4sto_it_open(s2, NULL);
+ i3 = dk4sto_it_open(s3, NULL);
+ i4 = dk4sto_it_open(s4, NULL);
+ /* Check whether all iterators were created successfully */
+ if(i1 && i2 && i3 && i4) {
+ /* Process input */
+ read_file(stdin);
+ /* Release all the records */
+ dk4sto_it_reset(i4);
+ while((p = dk4sto_it_next(i4)) != NULL) {
+ free_person((Person *)p);
+ }
+ }
+ }
+ /* Release the iterators */
+ if(i1) dk4sto_it_close(i1);
+ if(i2) dk4sto_it_close(i2);
+ if(i3) dk4sto_it_close(i3);
+ if(i4) dk4sto_it_close(i4);
+ /* Release the storage containers */
+ if(s1) dk4sto_close(s1);
+ if(s2) dk4sto_close(s2);
+ if(s3) dk4sto_close(s3);
+ if(s4) dk4sto_close(s4);
+ exit(0); return 0;
+}
+
+
diff --git a/support/dktools/ex-sto.ctr b/support/dktools/ex-sto.ctr
new file mode 100644
index 0000000000..5290392b4e
--- /dev/null
+++ b/support/dktools/ex-sto.ctr
@@ -0,0 +1,585 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% module
+
+
+/** @file
+ Test program for storage containers.
+
+The ex-sto program is a test and demonstration program for
+storage containers.
+
+The program stores information about persons:
+- surname,
+- family name and
+- age.
+
+The program reads input line by line, each input line is a command.
+The following commands can be used:
+- add _surname_ _family-name_ _age_
+- del f _family-name_
+- del s _surname_
+- del a _age_
+- read _filename_
+- print
+- tree
+- find f _family-name_
+- find s _surname_
+- find a _age_
+- quit
+
+The add command can be used to add persons.
+
+The del command deletes one or multiple records matching the specified
+family name, surname or age.
+
+The read command reads an input file typically containing add commands.
+
+The find command searches for the record for a given family name,
+surname or age.
+
+The print command prints all records beginning at the current record
+(the first record in the container or the element found in the last
+find command) until the end of the container.
+
+The tree command command prints the tree structures of a container.
+
+The quit command can be used to exit the application.
+
+Input to the program might look like
+@code
+add Erwin Unsinn 30
+add David Zeppelin 40
+add Johann Unfug 50
+add Alter Sack 99
+add Bla Blubb 33
+print
+find a 40
+find a 45
+del s Johann
+print
+tree
+quit
+@endcode
+
+@see ex-sto.c
+
+@example ex-sto.c
+*/
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4mem.h"
+#include "dk4sto.h"
+#include "dk4str8.h"
+
+#include <string.h>
+
+$(trace-include)
+
+
+
+/** Description of a person.
+*/
+typedef struct {
+ char *famname; /**< Family name */
+ char *surname; /**< Surname */
+ unsigned long age; /**< Age in years */
+} Person;
+
+/** Storage, persons sorted by family name. */
+static dk4_sto_t *s1;
+
+/** Storage, persons sorted by surname. */
+static dk4_sto_t *s2;
+
+/** Storage, persons sorted by age. */
+static dk4_sto_t *s3;
+
+/** Storage, persons unsorted. */
+static dk4_sto_t *s4;
+
+/** Iterator for storage sorted by family name. */
+static dk4_sto_it_t *i1;
+
+/** Iterator for storage sorted by surname. */
+static dk4_sto_it_t *i2;
+
+/** Iterator for storage sorted by age. */
+static dk4_sto_it_t *i3;
+
+/** Iterator for unsorted storage. */
+static dk4_sto_it_t *i4;
+
+/** Flag, input processing can be continued. */
+static int can_continue;
+
+/** Flag, stdin is connected to terminal. */
+static int stdin_is_tty = 1;
+
+static void read_file(FILE *);
+
+
+
+/** Retrieve age from pointer.
+ The function retrieves an age evaluation of a pointer.
+ The pointer target is either a struct Person or an
+ unsigned long.
+ @param p Pointer to person or unsigned long.
+ @param cr Pointer object type:
+ - 1: \a p points to a struct Person,
+ - anything else: \a p points to an unsigned long.
+ @return The age.
+*/
+unsigned long age_fct(void const *p, int cr)
+{
+ unsigned long back;
+ switch(cr) {
+ case 1: {
+ back = *((unsigned long const *)p);
+ } break;
+ default: {
+ back = ((Person const *)p)->age;
+ } break;
+ }
+ return back;
+}
+
+
+
+/** Compare object against other object or text.
+ @param p1 Left pointer (from storage).
+ @param p2 Right pointer (from dk4sto_it_find_like()).
+ @param cr Comparison criteria:
+ - 0 indicates: p1 and p2 are pointers to struct Person,
+ compare by family name.
+ - 1 indicates: p1 is a pointer to a struct Person, p2 is a
+ pointer to a string. Compare the family name of p1
+ against the string.
+ - 2 indicates: p1 and p2 are pointers to struct Person,
+ compare by surname.
+ - 3 indicates: p1 is a pointer to a struct person, p2 is a
+ pointer to a string. Compare the surname of p1 against
+ the string.
+ @return Comparison result:
+ - Positive value, if left pointer is larger (or behind),
+ - Negative value, if left pointer is smaller (or before),
+ - 0 if both pointers evaluate equal.
+*/
+int compare_fct(void const *p1, void const *p2, int cr)
+{
+ int back = 0;
+ switch(cr) {
+ case 0: {
+ back = strcmp(((Person *)p1)->famname, ((Person *)p2)->famname);
+ } break;
+ case 1: {
+ back = strcmp(((Person *)p1)->famname, (char *)p2);
+ } break;
+ case 2: {
+ back = strcmp(((Person *)p1)->surname, ((Person *)p2)->surname);
+ } break;
+ case 3: {
+ back = strcmp(((Person *)p1)->surname, (char *)p2);
+ } break;
+ }
+ return back;
+}
+
+
+
+/** Print a prompt.
+*/
+static void print_prompt(void)
+{
+ if(stdin_is_tty) {
+ printf("\nstotest: ");
+ }
+}
+
+
+
+/** Print one persons record.
+ @param pers Person structure.
+ @param fout Output file.
+*/
+static void print_person(Person *pers, FILE *fout)
+{
+ fprintf(
+ fout,
+ "%s %s %lu\n",
+ ((pers->surname) ? pers->surname : "-"),
+ ((pers->famname) ? pers->famname : "-"),
+ pers->age
+ );
+}
+
+
+
+/** Print persons record from an iterators current
+ position until the end of the container.
+ @param i Storage iterator.
+ @param fout Output file.
+*/
+static void print_it(dk4_sto_it_t *i, FILE *fout)
+{
+ void *p;
+ dk4sto_it_reset(i);
+ while((p = dk4sto_it_next(i)) != NULL) {
+ print_person((Person *)p, fout);
+ fprintf(fout, "\n");
+ }
+}
+
+
+
+/** Print storage tree node including subtree.
+ This function is used to show the tree structure.
+ In your applications you should not access the internal
+ members of a dk4_sto_t or dk4_sto_node_t directly.
+ @param n Storage node.
+ @param num Indent depth.
+ @param f Output file.
+ @param c Key character for node.
+*/
+void print_node(dk4_sto_node_t *n, int num, FILE *f, char c)
+{
+ int i;
+ Person *pers;
+ if(n) {
+ for(i = 0; i < num; i++) {
+ fprintf(f, " ");
+ }
+ fprintf(f, "%c %5d (%d)", c, num, n->b);
+ pers = (Person *)(n->o);
+ if(pers) {
+ if(pers->surname) fprintf(f, " %s ", pers->surname);
+ else fprintf(f, " - ");
+ if(pers->famname) fprintf(f, " %s ", pers->famname);
+ else fprintf(f, " - ");
+ fprintf(f, " %lu", pers->age);
+ }
+ fprintf(f, " \tparent:");
+ if(n->p) {
+ if((n->p)->o) {
+ pers = (Person *)((n->p)->o);
+ if(pers->surname) fprintf(f, " %s ", pers->surname);
+ else fprintf(f, " - ");
+ if(pers->famname) fprintf(f, "%s ", pers->famname);
+ else fprintf(f, "- ");
+ fprintf(f, " %lu", pers->age);
+ }
+ }
+ fprintf(f, "\n");
+ print_node(n->l, (num+1), f, 'l');
+ print_node(n->r, (num+1), f, 'r');
+ }
+}
+
+
+
+/** Print the tree structure.
+ In your applications you should not access the internal
+ members of a dk4_sto_t or dk4_sto_node_t directly.
+ @param s Storage to print.
+ @param f Output file.
+*/
+void print_tree(dk4_sto_t *s, FILE *f)
+{
+ if((s->h) && (s->t)) {
+ print_node(s->r, 0, f, '+');
+ }
+}
+
+
+
+/** Free a persons record (release memory.)
+ @param pers Pointer to record to release.
+*/
+static void free_person(Person *pers)
+{
+ char *cptr;
+ if(pers) {
+ cptr = pers->famname;
+ dk4mem_free(cptr);
+ cptr = pers->surname;
+ dk4mem_free(cptr);
+ pers->famname = pers->surname = NULL;
+ dk4mem_free(pers);
+ }
+}
+
+
+
+/** Handle command without arguments.
+ @param str Command (first text in input line).
+*/
+static
+void
+handle_cmd_1(char *str)
+{
+ if(strcasecmp(str, "quit") == 0) {
+ can_continue = 0;
+ }
+ if(strcasecmp(str, "print") == 0) {
+ fprintf(stdout, "Sorted by family name:\n");
+ print_it(i1, stdout);
+ fprintf(stdout, "Sorted by surname:\n");
+ print_it(i2, stdout);
+ fprintf(stdout, "Sorted by age:\n");
+ print_it(i3, stdout);
+ fprintf(stdout, "Unsorted:\n");
+ print_it(i4, stdout);
+ }
+ if(strcasecmp(str, "tree") == 0) {
+ fprintf(stdout, "Sorted by family name:\n");
+ print_tree(s1, stdout);
+ fprintf(stdout, "Sorted by surname:\n");
+ print_tree(s2, stdout);
+ fprintf(stdout, "Sorted by age:\n");
+ print_tree(s3, stdout);
+ fprintf(stdout, "Unsorted:\n");
+ print_tree(s4, stdout);
+ }
+}
+
+
+
+/** Handle command with one argument.
+ @param cmd Command to handle.
+ @param arg1 Command argument.
+*/
+static void handle_cmd_2(char *cmd, char *arg1)
+{
+ if(strcasecmp(cmd, "read") == 0) {
+ FILE *in;
+ in = fopen(arg1, "r");
+ if(in) {
+ read_file(in);
+ fclose(in);
+ }
+ }
+}
+
+
+
+/** Handle command with 2 arguments.
+ @param cmd Command to handle.
+ @param arg1 Command argument 1.
+ @param arg2 Command argument 2.
+*/
+static void handle_cmd_3(char *cmd, char *arg1, char *arg2)
+{
+ void *p;
+ if(strcasecmp(cmd, "find") == 0) {
+ if(strcasecmp(arg1, "f") == 0) {
+ p = dk4sto_it_find_like(i1, arg2, 1);
+ if(p) {
+ print_person(p,stdout); printf("\n");
+ }
+ printf("Followers:\n");
+ while((p = (Person *)dk4sto_it_next(i1)) != NULL) {
+ print_person(p,stdout); printf("\n");
+ }
+ }
+ if(strcasecmp(arg1, "s") == 0) {
+ p = dk4sto_it_find_like(i2, arg2, 3);
+ if(p) {
+ print_person(p,stdout); printf("\n");
+ }
+ printf("Followers:\n");
+ while((p = (Person *)dk4sto_it_next(i2)) != NULL) {
+ print_person(p,stdout); printf("\n");
+ }
+ }
+ if(strcasecmp(arg1, "a") == 0) {
+ unsigned long age;
+ if(sscanf(arg2, "%lu", &age) == 1) {
+ p = dk4sto_it_find_like(i3, (void *)(&age), 1);
+ if(p) {
+ print_person(p,stdout); printf("\n");
+ }
+ printf("Followers:\n");
+ while((p = (Person *)dk4sto_it_next(i3)) != NULL) {
+ print_person(p,stdout); printf("\n");
+ }
+ }
+ }
+ }
+ if(strcasecmp(cmd, "del") == 0) {
+ if(strcasecmp(arg1, "f") == 0) {
+ while((p = dk4sto_it_find_like(i1, arg2, 1)) != NULL) {
+ dk4sto_remove(s1,p,NULL);
+ dk4sto_remove(s2,p,NULL);
+ dk4sto_remove(s3,p,NULL);
+ dk4sto_remove(s4,p,NULL);
+ free_person(p);
+ }
+ }
+ if(strcasecmp(arg1, "s") == 0) {
+ while((p = dk4sto_it_find_like(i2, arg2, 3)) != NULL) {
+ dk4sto_remove(s1,p,NULL);
+ dk4sto_remove(s2,p,NULL);
+ dk4sto_remove(s3,p,NULL);
+ dk4sto_remove(s4,p,NULL);
+ free_person(p);
+ }
+ }
+ if(strcasecmp(arg1, "a") == 0) {
+ unsigned long age;
+ if(sscanf(arg2, "%lu", &age) == 1) {
+ while((p = dk4sto_it_find_like(i3, (void *)(&age), 1)) != NULL) {
+ dk4sto_remove(s1,p,NULL);
+ dk4sto_remove(s2,p,NULL);
+ dk4sto_remove(s3,p,NULL);
+ dk4sto_remove(s4,p,NULL);
+ free_person(p);
+ }
+ }
+ }
+ }
+}
+
+
+
+/** Handle command with 3 arguments.
+ @param cmd Command to handle.
+ @param arg1 Command argument 1.
+ @param arg2 Command argument 2.
+ @param arg3 Command argument 3.
+*/
+static void handle_cmd_4(char *cmd, char *arg1, char *arg2, char *arg3)
+{
+ if(strcasecmp(cmd, "add") == 0) {
+ unsigned long age;
+ Person *pers;
+ if(sscanf(arg3, "%lu", &age) == 1) {
+ pers = dk4mem_new(Person,1,NULL);
+ if(pers) {
+ pers->famname = dk4str8_dup(arg2, NULL);
+ pers->surname = dk4str8_dup(arg1, NULL);
+ pers->age = age;
+ if(!((pers->famname) && (pers->surname))) {
+ free_person(pers);
+ } else {
+ if(!dk4sto_add(s4, (void *)pers, NULL)) {
+ free_person(pers);
+ } else {
+ dk4sto_add(s1, (void *)pers, NULL);
+ dk4sto_add(s2, (void *)pers, NULL);
+ dk4sto_add(s3, (void *)pers, NULL);
+ }
+ }
+ }
+ }
+ }
+}
+
+
+
+/** Read input file.
+ @param in File to read from.
+*/
+void read_file(FILE *in)
+{
+
+ char line[1024];
+ char *lbegin;
+ int i;
+ char str1[sizeof(line)];
+ char str2[sizeof(line)];
+ char str3[sizeof(line)];
+ char str4[sizeof(line)];
+ int old_can_continue;
+ old_can_continue = can_continue;
+ can_continue = 1;
+ while(can_continue) {
+ if(in == stdin) print_prompt();
+ if(fgets(line, sizeof(line), in)) {
+ lbegin = dk4str8_start(line, NULL);
+ if(lbegin) {
+ dk4str8_normalize(lbegin, NULL);
+ printf("# Processing \"%s\"\n", lbegin);
+ i = sscanf(lbegin, "%s %s %s %s", str1, str2, str3, str4);
+ switch(i) {
+ case 1: {
+ handle_cmd_1(str1);
+ } break;
+ case 2: {
+ handle_cmd_2(str1, str2);
+ } break;
+ case 3: {
+ handle_cmd_3(str1, str2, str3);
+ } break;
+ case 4: {
+ handle_cmd_4(str1, str2, str3, str4);
+ } break;
+ }
+ }
+ } else {
+ can_continue = 0;
+ }
+ }
+ can_continue = old_can_continue;
+}
+
+
+
+/** Main program.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return Exit status code.
+*/
+int main(int arg, char *argv[])
+{
+ void *p; Person *pers; char *cptr;
+ /* Check whether or not we are connected to a terminal */
+ /* stdin_is_tty = dksf_echo_test_tty(); */
+ stdin_is_tty = 1;
+ /* Create storage containers */
+ s1 = dk4sto_open(NULL);
+ s2 = dk4sto_open(NULL);
+ s3 = dk4sto_open(NULL);
+ s4 = dk4sto_open(NULL);
+ /* Check whether all containers were created successfully */
+ if(s1 && s2 && s3 && s4) {
+ /* Set comparison and evaluation functions */
+ dk4sto_set_comp(s1, compare_fct, 0);
+ dk4sto_set_comp(s2, compare_fct, 2);
+ dk4sto_set_eval_ul(s3, age_fct, 0);
+ /* Create storage container iterators */
+ i1 = dk4sto_it_open(s1, NULL);
+ i2 = dk4sto_it_open(s2, NULL);
+ i3 = dk4sto_it_open(s3, NULL);
+ i4 = dk4sto_it_open(s4, NULL);
+ /* Check whether all iterators were created successfully */
+ if(i1 && i2 && i3 && i4) {
+ /* Process input */
+ read_file(stdin);
+ /* Release all the records */
+ dk4sto_it_reset(i4);
+ while((p = dk4sto_it_next(i4)) != NULL) {
+ free_person((Person *)p);
+ }
+ }
+ }
+ /* Release the iterators */
+ if(i1) dk4sto_it_close(i1);
+ if(i2) dk4sto_it_close(i2);
+ if(i3) dk4sto_it_close(i3);
+ if(i4) dk4sto_it_close(i4);
+ /* Release the storage containers */
+ if(s1) dk4sto_close(s1);
+ if(s2) dk4sto_close(s2);
+ if(s3) dk4sto_close(s3);
+ if(s4) dk4sto_close(s4);
+ exit(0); return 0;
+}
+
+
diff --git a/support/dktools/ex-sto.in b/support/dktools/ex-sto.in
new file mode 100644
index 0000000000..4d3c4fc27b
--- /dev/null
+++ b/support/dktools/ex-sto.in
@@ -0,0 +1,12 @@
+add Erwin Unsinn 30
+add David Zeppelin 40
+add Johann Unfug 50
+add Alter Sack 99
+add Bla Blubb 33
+print
+find a 40
+find a 45
+del s Johann
+print
+tree
+quit
diff --git a/support/dktools/exit-program.xpm b/support/dktools/exit-program.xpm
new file mode 100644
index 0000000000..8bb58d67fb
--- /dev/null
+++ b/support/dktools/exit-program.xpm
@@ -0,0 +1,39 @@
+/* XPM */
+static const char *xpm_exit_program[] = {
+/* width height ncolors chars_per_pixel */
+"16 15 17 1",
+/* colors */
+" c #AFAFAF",
+". c #FEF9F9",
+"X c #E88787",
+"o c #D31919",
+"O c #8E0000",
+"+ c #642525",
+"@ c #CF0000",
+"# c #A39393",
+"$ c #A6A6A6",
+"% c #880505",
+"& c #5E0303",
+"* c #727272",
+"= c #FFFFFF",
+"- c #F2BABA",
+"; c #EBEBEB",
+": c #BFBFBF",
+"> c None",
+/* pixels */
+">>>>>>>>>>>>>>>>",
+">>>>>>>>>>>>>>>>",
+">>>>&%%%%$$*>>>>",
+">>>>O@@@@== >>>>",
+">>>>O@@@@== >>>>",
+">>>>O@@@@== >>>>",
+">>>>O@@@@== >>>>",
+">>>>O@@@@== >>>>",
+">>>>O@@@@== >>>>",
+">>>>O@@@@== >>>>",
+">>>>O@@o-== >>>>",
+">>>>O@X.=== >>>>",
+">>>>+#$$$$$*>>>>",
+">>>>>>>>>>>>>>>>",
+">>>>>>>>>>>>>>>>"
+};
diff --git a/support/dktools/f2leps.c b/support/dktools/f2leps.c
new file mode 100644
index 0000000000..aea321a2c2
--- /dev/null
+++ b/support/dktools/f2leps.c
@@ -0,0 +1,1831 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: f2leps.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file f2leps.c The f2leps module.
+*/
+
+
+#line 686 "f2leps.ctr"
+
+#include "dk3all.h"
+#include "dk3bezcu.h"
+#include "fig2lat.h"
+#include "f2lud.h"
+#include "f2lsvg.h"
+#include "f2leps.h"
+#include "dk3figto.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4vers.h"
+#include "dk3font.h"
+#include "dk3bm.h"
+#include "dk3bmeps.h"
+
+
+
+
+#line 704 "f2leps.ctr"
+
+
+
+/** Drawing-related information for EPS output.
+*/
+typedef struct {
+ char const *shortOutFile; /**< Short output file name. */
+ dk3_sto_t *sFonts; /**< Fonts and sizes (dk3_fig_font_t). */
+ dk3_sto_it_t *iFonts; /**< Fonts storage iterator. */
+ int *fonts; /**< 35 flags: Font used. */
+ unsigned long nFonts; /**< Number of fonts in sFonts. */
+ int havetext; /**< Flag: Text to show as PS text. */
+ int alignedright; /**< Flag: Right-aligned text found. */
+ int alignedcenter; /**< Flag: Centered text found. */
+ int dictsize; /**< Size of dictionary. */
+} f2leps_drawing_info_t;
+
+
+
+#if 0
+/** Font reencoding to write ISO-LATIN-1 encoded strings.
+*/
+static char const * const f2leps_font_reencode_2[] = {
+"/FontReEncode\t\t% originalname encodedname --",
+"{",
+" 5 dict begin /nn exch def /an exch def an findfont dup",
+" length dict /nf exch def",
+" {",
+" 1 index /FID ne",
+" { nf 3 1 roll put }",
+" { pop pop }",
+" ifelse",
+" }",
+" forall",
+" nf /Encoding ISOLatin1Encoding put nn nf end definefont pop",
+"}",
+"def",
+NULL
+
+
+#line 743 "f2leps.ctr"
+};
+#else
+/** Font reencoding to write ISO-LATIN-1 encoded strings.
+*/
+static char const * const f2leps_font_reencode_2[] = {
+"/FontReEncode\t\t\t\t% originalname newname --",
+"{\t\t\t\t\t% on nn",
+" exch\t\t\t\t\t% nn on",
+" findfont\t\t\t\t% nn of",
+" dup\t\t\t\t\t% nn of of",
+" length\t\t\t\t% nn of length",
+" 1 add\t\t\t\t\t% nn of length",
+" dict\t\t\t\t\t% nn of nf",
+" exch\t\t\t\t\t% nn nf of",
+" {\t\t\t\t\t% nn nf key value",
+" 1 index\t\t\t\t% nn nf key value key",
+" /FID eq\t\t\t\t% nn nf key value flag",
+" {\t\t\t\t\t% nn nf key value",
+" pop pop\t\t\t\t% nn nf",
+" }",
+" {\t\t\t\t\t% nn nf key value",
+" 2 index\t\t\t\t% nn nf key value nf",
+" 3 1 roll\t\t\t\t% nn nf nf key value",
+" put\t\t\t\t% nn nf",
+" }",
+" ifelse\t\t\t\t% nn nf",
+" }",
+" forall\t\t\t\t% nn nf",
+" dup\t\t\t\t\t% nn nf nf",
+" /Encoding ISOLatin1Encoding put\t% nn nf",
+" definefont\t\t\t\t% nf",
+" pop\t\t\t\t\t%",
+"}",
+"def",
+NULL
+
+
+#line 779 "f2leps.ctr"
+};
+#endif
+
+#if 0
+
+/** Procedure for right aligned text.
+*/
+static char const * const f2leps_right_aligned_text[] = {
+"/TextAlignedRight \t% text --",
+"{",
+" currentpoint\t\t% text x y",
+" 3 -1 roll\t\t% x y text",
+" dup\t\t\t% x y text text",
+" true charpath\t\t% x y text",
+" flattenpath\t\t% x y text",
+" pathbbox\t\t% x y text x1 y1 x2 y2",
+" pop exch pop\t\t% x y text x1 x2",
+" exch sub abs\t\t% x y text length",
+" newpath 4 -2 roll\t% text length x y",
+" moveto\t\t% text length",
+" 0 exch sub\t\t% text distance",
+" 0 rmoveto\t\t% text",
+" show\t\t\t%",
+"} def",
+NULL
+
+
+#line 805 "f2leps.ctr"
+};
+
+
+
+/** Procedure for centered text.
+*/
+static char const * const f2leps_centered_aligned_text[] = {
+"/TextAlignedCentered \t% text --",
+"{",
+" currentpoint\t\t% text x y",
+" 3 -1 roll\t\t% x y text",
+" dup\t\t\t% x y text text",
+" true charpath\t\t% x y text",
+" flattenpath\t\t% x y text",
+" pathbbox\t\t% x y text x1 y1 x2 y2",
+" pop exch pop\t\t% x y text x1 x2",
+" exch sub abs\t\t% x y text length",
+" newpath 4 -2 roll\t% text length x y",
+" moveto\t\t% text length",
+" 0.5 mul\t\t% text distance",
+" 0 exch sub\t\t% text xshift",
+" 0 rmoveto\t\t% text",
+" show\t\t\t%",
+"} def",
+NULL
+
+
+#line 831 "f2leps.ctr"
+};
+
+#else
+
+/** Procedure for right aligned text.
+*/
+static char const * const f2leps_right_aligned_text[] = {
+"/TextAlignedRight \t% x y text --",
+"{",
+" dup\t\t\t% x y text text",
+" newpath\t\t% x y text text",
+" 0 0 moveto\t\t% x y text text",
+" true charpath\t\t% x y text",
+" pathbbox\t\t% x y text x1 y1 x2 y2",
+" pop\t\t\t% x y text x1 y1 x2",
+" exch\t\t\t% x y text x1 x2 y1",
+" pop\t\t\t% x y text x1 x2",
+" exch\t\t\t% x y text x2 x1",
+" pop\t\t\t% x y text width",
+" newpath\t\t% x y text width",
+" 4 3 roll\t\t% y text width x",
+" exch\t\t\t% y text x width",
+" sub\t\t\t% y text x",
+" 3 2 roll\t\t% text x y",
+" moveto\t\t% text",
+" show\t\t\t% -",
+"} def",
+NULL
+
+
+#line 860 "f2leps.ctr"
+};
+
+
+
+/** Procedure for centered text.
+*/
+static char const * const f2leps_centered_aligned_text[] = {
+"/TextAlignedCentered \t% x y text --",
+"{",
+" dup\t\t\t% x y text text",
+" newpath\t\t% x y text text",
+" 0 0 moveto\t\t% x y text text",
+" true charpath\t\t% x y text",
+" pathbbox\t\t% x y text x1 y1 x2 y2",
+" pop\t\t\t% x y text x1 y1 x2",
+" exch\t\t\t% x y text x1 x2 y1",
+" pop\t\t\t% x y text x1 x2",
+" exch\t\t\t% x y text x2 x1",
+" pop\t\t\t% x y text width",
+" 0.5 mul\t\t% x y text width/2",
+" newpath\t\t% x y text width/2",
+" 4 3 roll\t\t% y text width/2 x",
+" exch\t\t\t% y text x width/2",
+" sub\t\t\t% y text x",
+" 3 2 roll\t\t% text x y",
+" moveto\t\t% text",
+" show\t\t\t% -",
+"} def",
+NULL
+
+
+#line 890 "f2leps.ctr"
+};
+
+#endif
+
+
+
+/** Keywords used by the module.
+*/
+static
+char const * const f2leps_c8_kw[] = {
+/* 0 */
+"\n",
+
+/* 1 */
+" ",
+
+/* 2 */
+"%!PS-Adobe-3.0 EPSF-3.0\n",
+
+/* 3 */
+"%!PS-Adobe-2.0 EPSF-2.0\n",
+
+/* 4 */
+"%%LanguageLevel: 3\n",
+
+/* 5 */
+"%%LanguageLevel: 2\n",
+
+/* 6 */
+"%%BoundingBox: ",
+
+/* 7 */
+"0 0 %ld %ld\n",
+
+/* 8 */
+"%%Creator: http://dktools.sourceforge.net\n",
+
+/* 9 */
+"%%Title: Converted Fig image\n",
+
+/* 10 */
+"%%Pages: 1\n",
+
+/* 11 */
+"%%PageOrder: Ascend\n",
+
+/* 12 */
+"%%DocumentData: Clean7Bit\n",
+
+/* 13 */
+"%%EndComments\n",
+
+/* 14 */
+"%%Page: 1 1\n",
+
+/* 15 */
+"gsave\n",
+
+/* 16 */
+"grestore\n",
+
+/* 17 */
+"%d dict begin\n",
+
+/* 18 */
+"end\n",
+
+/* 19 */
+"showpage\n",
+
+/* 20 */
+"%%Trailer\n%%EOF\n",
+
+/* 21 */
+"newpath\n",
+
+/* 22 */
+"0 0 moveto %ld 0 lineto %ld %ld lineto 0 %ld lineto 0 0 lineto\n",
+
+/* 23 */
+"closepath clip\n",
+
+/* 24 */
+"/%s /fnt%02d FontReEncode\n",
+
+/* 25 */
+"%g %g moveto\n",
+
+/* 26 */
+"%g %g lineto\n",
+
+/* 27 */
+"%g %g %g %g %g %g curveto\n",
+
+/* 28 */
+"closepath\n",
+
+/* 29 */
+"eofill\n",
+
+/* 30 */
+"eoclip\n",
+
+/* 31 */
+"stroke\n",
+
+/* 32 */
+"%g %g %g setrgbcolor\n",
+
+/* 33 */
+"%g setlinewidth\n",
+
+/* 34 */
+"%d setlinecap\n",
+
+/* 35 */
+"%d setlinejoin\n",
+
+/* 36 */
+"[] 0 setdash\n",
+
+/* 37 */
+"[%g %g] 0 setdash\n",
+
+/* 38 */
+"[%g %g %g %g] 0 setdash\n",
+
+/* 39 */
+"[%g %g %g %g %g %g] 0 setdash\n",
+
+/* 40 */
+"[%g %g %g %g %g %g %g %g] 0 setdash\n",
+
+/* 41 */
+"(",
+
+/* 42 */
+")",
+
+/* 43 */
+"/fnt%02d findfont %g scalefont setfont\n",
+
+/* 44 */
+" show\n",
+
+/* 45 */
+" TextAlignedCentered\n",
+
+/* 46 */
+" TextAlignedRight\n",
+
+/* 47 */
+"%g %g translate\n",
+
+/* 48 */
+"%g rotate\n",
+
+/* 49 */
+"0 0 moveto\n",
+
+/* 50 */
+" 3 -2 roll newpath moveto show\n",
+
+/* 51 */
+"0 0 ",
+
+/* 52 */
+"% ",
+
+NULL
+
+
+#line 1114 "f2leps.ctr"
+};
+
+
+/* ************************************************************************ */
+/* * * */
+/* * Tool functions * */
+/* * * */
+/* ************************************************************************ */
+
+
+#line 1120 "f2leps.ctr"
+
+
+
+/** Destroy drawing info structure.
+ @param pdi Structure to destroy.
+*/
+static
+void
+f2leps_drawing_info_delete(
+ f2leps_drawing_info_t *pdi
+)
+{
+ void *ptr; /* Current text handling information to delete. */
+
+ if(pdi) {
+ dk3_release(pdi->shortOutFile);
+ if(pdi->sFonts) {
+ if(pdi->iFonts) {
+ dk3sto_it_reset(pdi->iFonts);
+ while(NULL != (ptr = dk3sto_it_next(pdi->iFonts))) {
+ dk3_delete(ptr);
+ }
+ dk3sto_it_close(pdi->iFonts);
+ }
+ dk3sto_close(pdi->sFonts);
+ } pdi->sFonts = NULL; pdi->iFonts = NULL;
+ dk3_release(pdi->fonts);
+ dk3_delete(pdi);
+ }
+}
+
+
+
+/** Create drawing information structure.
+ @param job Job structure.
+ @param withFonts Flag: Gather LaTeX font information.
+ This flag is set to 1 for EPS/LaTeX and set to 0 for
+ pure EPS.
+ @return Pointer to new structure on success, NULL on error.
+*/
+static
+f2leps_drawing_info_t *
+f2leps_drawing_info_new(
+ f2l_job_t *job,
+ int withFonts
+)
+{
+ f2leps_drawing_info_t *back;
+ int ok = 0;
+ back = dk3_new_app(f2leps_drawing_info_t,1,job->app);
+ if(back) {
+ back->nFonts = 0UL;
+ back->sFonts = NULL;
+ back->iFonts = NULL;
+ back->fonts = NULL;
+ back->havetext = 0;
+ back->alignedright = 0;
+ back->alignedcenter = 0;
+ back->dictsize = 0;
+ back->shortOutFile = NULL;
+ if(withFonts) {
+ back->sFonts = dk3sto_open_app(job->app);
+ if(back->sFonts) {
+ dk3sto_set_comp(back->sFonts, dk3fig_tool_font_compare, 0);
+ back->iFonts = dk3sto_it_open(back->sFonts);
+ if(back->iFonts) {
+ ok = 1;
+ }
+ }
+ } else {
+ back->fonts = dk3_new_app(int,35,job->app);
+ if(back->fonts) {
+ ok = 1;
+ }
+ }
+ if(!(ok)) {
+ f2leps_drawing_info_delete(back);
+ back = NULL;
+ }
+ }
+ return back;
+}
+
+
+
+/** Write a text section to the output file.
+ @param of Output file.
+ @param ta String array to write.
+*/
+static
+void
+f2leps_write_text_section(
+ FILE *of,
+ char const * const *ta
+)
+{
+ char const * const *ptr;
+ ptr = ta;
+ while(*ptr) {
+ fputs(*(ptr++), of);
+ fputc('\n', of);
+ }
+}
+
+
+
+/** Write EPS file header.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param of Output file.
+ @param pure Flag: Pure EPS (1) or EPS/LaTeX (0).
+*/
+static
+void
+f2leps_file_header(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ FILE *of,
+ int pure
+)
+{
+ f2leps_drawing_info_t *pdi;
+ int i;
+ pdi = (f2leps_drawing_info_t *)(drw->dsd);
+ /* %!PS-Adobe-3.0 EPSF-3.0 */
+ if(2 < job->pslevel) {
+ fputs(f2leps_c8_kw[2], of);
+ fputs(f2leps_c8_kw[4], of);
+ } else {
+ fputs(f2leps_c8_kw[3], of);
+ fputs(f2leps_c8_kw[5], of);
+ }
+ /* bounding box */
+ fputs(f2leps_c8_kw[6], of);
+ fprintf(of, f2leps_c8_kw[7], job->lwidth, job->lheight);
+ if(job->dsc) {
+ /* Creator */
+ fputs(f2leps_c8_kw[8], of);
+ /* Title */
+ fputs(f2leps_c8_kw[9], of);
+ /* Pages */
+ fputs(f2leps_c8_kw[10], of);
+ /* PageOrder */
+ fputs(f2leps_c8_kw[11], of);
+ /* DocumentData */
+ fputs(f2leps_c8_kw[12], of);
+ if(pure) {
+ /* ##### HIER WEITER: DocumentNeededFonts */
+ }
+ /* EndComments */
+ fputs(f2leps_c8_kw[13], of);
+ /* Page */
+ fputs(f2leps_c8_kw[14], of);
+ }
+ fputs(f2leps_c8_kw[15], of);
+ fputs(f2leps_c8_kw[21], of);
+ fprintf(
+ of, f2leps_c8_kw[22],
+ job->lwidth, job->lwidth, job->lheight, job->lheight
+ );
+ fputs(f2leps_c8_kw[23], of);
+ if(pure) {
+ /* xxx dict begin */
+ fprintf(of, f2leps_c8_kw[17], pdi->dictsize);
+ }
+ /* Text procedures */
+ if(pdi->havetext) {
+ f2leps_write_text_section(of, f2leps_font_reencode_2);
+ if(pdi->alignedcenter) {
+ f2leps_write_text_section(of, f2leps_centered_aligned_text);
+ }
+ if(pdi->alignedright) {
+ f2leps_write_text_section(of, f2leps_right_aligned_text);
+ }
+ /* Font reencodings */
+ for(i = 0; i < 35; i++) {
+ if((pdi->fonts)[i]) {
+ fprintf(of, f2leps_c8_kw[24], dk3font_get_ps_font_name(i), i);
+ }
+ }
+ }
+}
+
+
+
+/** Write EPS file header.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param of Output file.
+ @param pure Flag: Pure EPS (1) or EPS/LaTeX (0).
+*/
+static
+void
+f2leps_file_footer(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ FILE *of,
+ int pure
+)
+{
+ if(pure) {
+ /* end */
+ fputs(f2leps_c8_kw[18], of);
+ }
+ /* grestore */
+ fputs(f2leps_c8_kw[16], of);
+ if(job->showpage) {
+ /* showpage */
+ fputs(f2leps_c8_kw[19], of);
+ }
+ if(job->dsc) {
+ /* Trailer, EOF */
+ fputs(f2leps_c8_kw[20], of);
+ }
+}
+
+
+
+/** Check whether a text character is literal.
+ @param c Character to check.
+ @return 1 to issue character as is, 0 for octal encoding.
+*/
+static
+int
+f2leps_is_literal(char c)
+{
+ int back = 0;
+ if(('A' <= c) && ('Z' >= c)) {
+ back = 1;
+ } else {
+ if(('a' <= c) && ('z' >= c)) {
+ back = 1;
+ } else {
+ if(('0' <= c) && ('9' >= c)) {
+ back = 1;
+ } else {
+ switch(c) {
+ case ' ':
+ {
+ back = 1;
+ } break;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Write string PS-encoded to output.
+ @param of Output file.
+ @param str String to write.
+*/
+static
+void
+f2leps_encode_string(
+ FILE *of,
+ char const *str
+)
+{
+ char buf[32];
+ char const *ptr;
+ char c;
+ unsigned char uc;
+ unsigned u;
+ ptr = str;
+ fputs(f2leps_c8_kw[41], of);
+ while(*ptr) {
+ c = *(ptr++);
+ if(f2leps_is_literal(c)) {
+ fputc(c, of);
+ } else {
+ uc = (unsigned char)c;
+ u = (unsigned)uc;
+ while(255 < u) { u = u - 256; }
+ sprintf(buf, "\\%03o", u);
+ fputs(buf, of);
+ }
+ }
+ fputs(f2leps_c8_kw[42], of);
+}
+
+
+
+/** Process an embedded bitmap image.
+ @param of Output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Image object.
+ @param outbb Destination image area.
+ @param drawdir Drawing direction / coordinates origin.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2leps_image_object(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int drawdir,
+ int *ec
+)
+{
+ int res = 0;
+ res = dk3bm_ps_place_object(
+ of,outbb,drawdir,(obj->dt).pol.fn,job->app,job->pslevel,ec
+ );
+ if(!(res)) {
+ job->exval = FIG2LAT_EXIT_ERROR_UNKNOWN;
+
+#line 1432 "f2leps.ctr"
+ }
+}
+
+
+
+/** Set line style.
+ @param of Output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object using the line style.
+ @param ls Line style.
+ @param sv Style value (gap length).
+ @param lw Line width.
+*/
+static
+void
+f2leps_set_line_style(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int ls,
+ double sv,
+ double lw
+)
+{
+ double gw; /* Gap width. */
+ gw = f2lto_find_gap_length(job, lw, sv);
+ switch(ls) {
+ case DK3_FIG_LS_DASHED: {
+ fprintf(of, f2leps_c8_kw[37], sv, gw);
+ } break;
+ case DK3_FIG_LS_DOTTED: {
+ fprintf(of, f2leps_c8_kw[37], lw, gw);
+ } break;
+ case DK3_FIG_LS_DASH_DOTTED: {
+ fprintf(of, f2leps_c8_kw[38], sv, gw, lw, gw);
+ } break;
+ case DK3_FIG_LS_DASH_DOUBLE_DOTTED: {
+ fprintf(of, f2leps_c8_kw[39], sv, gw, lw, gw, lw, gw);
+ } break;
+ case DK3_FIG_LS_DASH_TRIPLE_DOTTED: {
+ fprintf(of, f2leps_c8_kw[40], sv, gw, lw, gw, lw, gw, lw, gw);
+ } break;
+ default: {
+ fputs(f2leps_c8_kw[36], of);
+ } break;
+ }
+}
+
+
+
+/** Write debug line to output.
+ @param of Output file.
+ @param job Job structure.
+ @param msg Message text to write.
+*/
+static
+void
+f2leps_debug(
+ FILE *of,
+ f2l_job_t *job,
+ char const *msg
+)
+{
+ if((job) && (msg)) {
+ fputs(f2leps_c8_kw[52], of);
+ fputs(msg, of);
+ fputs(f2leps_c8_kw[0], of);
+ }
+}
+
+
+
+/* ************************************************************************ */
+/* * * */
+/* * Driver: EPS with LaTeX * */
+/* * * */
+/* ************************************************************************ */
+
+
+#line 1509 "f2leps.ctr"
+
+
+int
+f2leps_eps_with_tex_initialize(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ f2leps_drawing_info_t *pdi;
+ dk3_fig_obj_t *pobj;
+ dkChar const *oldsourcename = NULL;
+ unsigned long oldsourceline = 0UL;
+ int back = 0;
+ int ff;
+
+
+#line 1521 "f2leps.ctr"
+ drw->dsd = (void *)(pdi = f2leps_drawing_info_new(job, 1));
+ if(drw->dsd) {
+
+#line 1523 "f2leps.ctr"
+ oldsourcename = dk3app_get_source_file(job->app);
+ oldsourceline = dk3app_get_source_line(job->app);
+ pdi->shortOutFile = dk3fig_tool_short_output_file_name(job->on2, job->app);
+ if(pdi->shortOutFile) {
+
+#line 1527 "f2leps.ctr"
+ back = 1;
+
+#line 1528 "f2leps.ctr"
+ dk3sto_it_reset(drw->iobj);
+ while(NULL != (pobj = (dk3_fig_obj_t *)dk3sto_it_next(drw->iobj))) {
+
+
+#line 1531 "f2leps.ctr"
+ dk3app_set_source_line(job->app, pobj->li);
+ switch(pobj->ot) {
+ case DK3_FIG_OBJ_TEXT: {
+
+#line 1534 "f2leps.ctr"
+ ff = (pobj->dt).txt.ff;
+ if(!(ff & DK3_FIG_FONT_FLAG_HIDDEN)) {
+
+#line 1536 "f2leps.ctr"
+ if(!(ff & DK3_FIG_FONT_FLAG_SPECIAL)) {
+
+#line 1537 "f2leps.ctr"
+ if(ff & DK3_FIG_FONT_FLAG_PS) {
+
+#line 1538 "f2leps.ctr"
+ if(job->ntf) {
+
+#line 1539 "f2leps.ctr"
+ pobj->dsd = (void *)f2l_tool_register_font(
+ pdi->sFonts, pdi->iFonts, &(pdi->nFonts),
+ (pobj->dt).txt.fo, (pobj->dt).txt.fs, job->app
+ );
+ if(!(pobj->dsd)) {
+ back = 0;
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1546 "f2leps.ctr"
+ }
+ } else {
+
+#line 1548 "f2leps.ctr"
+ }
+ }
+ }
+ }
+ } break;
+ }
+ }
+ } else {
+
+#line 1556 "f2leps.ctr"
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1557 "f2leps.ctr"
+ }
+ dk3app_set_source_file(job->app, oldsourcename);
+ dk3app_set_source_line(job->app, oldsourceline);
+ } else {
+
+#line 1561 "f2leps.ctr"
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1562 "f2leps.ctr"
+ }
+
+#line 1563 "f2leps.ctr"
+ return back;
+}
+
+
+
+void
+f2leps_eps_with_tex_end(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+
+
+#line 1572 "f2leps.ctr"
+ if(drw->dsd) {
+ f2leps_drawing_info_delete((f2leps_drawing_info_t *)(drw->dsd));
+ }
+
+
+#line 1576 "f2leps.ctr"
+}
+
+
+
+int
+f2leps_eps_with_tex_open_output_files(f2l_job_t *job)
+{
+ int back = 0;
+
+
+#line 1585 "f2leps.ctr"
+ job->of1 = dk3sf_fopen_app(job->on1, dkT("w"), job->app);
+ if(job->of1) {
+ job->of2 = dk3sf_fopen_app(job->on2, dkT("wb"), job->app);
+ if(job->of2) {
+ back = 1;
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1592 "f2leps.ctr"
+ }
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1595 "f2leps.ctr"
+ }
+
+
+#line 1597 "f2leps.ctr"
+ return back;
+}
+
+
+
+void
+f2leps_eps_with_tex_close_output_files(f2l_job_t *job)
+{
+
+
+#line 1606 "f2leps.ctr"
+ if(job->of2) {
+ dk3sf_fclose_app(job->of2, job->app);
+ } job->of2 = NULL;
+ if(job->of1) {
+ dk3sf_fclose_app(job->of1, job->app);
+ } job->of1 = NULL;
+
+
+#line 1613 "f2leps.ctr"
+}
+
+
+
+int
+f2leps_eps_with_tex_start_processing(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ f2leps_drawing_info_t *pdi;
+ int back = 1;
+
+
+#line 1623 "f2leps.ctr"
+ pdi = (f2leps_drawing_info_t *)(drw->dsd);
+ f2leps_file_header(job, drw, job->of2, 0);
+ f2l_tool_start_tex_part(
+ job->of1, job, drw, pdi->shortOutFile, pdi->iFonts, pdi->nFonts
+ );
+
+
+#line 1629 "f2leps.ctr"
+ return back;
+}
+
+
+
+void
+f2leps_eps_with_tex_end_processing(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+
+
+#line 1638 "f2leps.ctr"
+ f2leps_file_footer(job, drw, job->of2, 0);
+ f2l_tool_end_tex_part(job->of1);
+
+
+#line 1641 "f2leps.ctr"
+}
+
+
+
+void
+f2leps_eps_with_tex_text_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+ f2leps_drawing_info_t *pdi;
+ pdi = (f2leps_drawing_info_t *)(drw->dsd);
+ f2l_tool_text_object(job->of1, job, drw, obj, x, y, pdi->nFonts);
+}
+
+
+
+void
+f2leps_eps_with_tex_image_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int drawdir,
+ int *ec
+)
+{
+ f2leps_image_object(job->of2, job, drw, obj, outbb, drawdir, ec);
+}
+
+
+void
+f2leps_eps_with_tex_newpath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ fputs(f2leps_c8_kw[21], job->of2);
+}
+
+
+
+void
+f2leps_eps_with_tex_moveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+ fprintf(job->of2, f2leps_c8_kw[25], x, y);
+}
+
+
+
+void
+f2leps_eps_with_tex_lineto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+ fprintf(job->of2, f2leps_c8_kw[26], x, y);
+}
+
+
+
+void
+f2leps_eps_with_tex_curveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double xcs,
+ double ycs,
+ double xce,
+ double yce,
+ double xe,
+ double ye
+)
+{
+ fprintf(job->of2, f2leps_c8_kw[27], xcs, ycs, xce, yce, xe, ye);
+}
+
+
+
+void
+f2leps_eps_with_tex_closepath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ fputs(f2leps_c8_kw[28], job->of2);
+}
+
+
+
+void
+f2leps_eps_with_tex_fill(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ fputs(f2leps_c8_kw[29], job->of2);
+}
+
+
+
+void
+f2leps_eps_with_tex_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ fputs(f2leps_c8_kw[30], job->of2);
+}
+
+
+
+void
+f2leps_eps_with_tex_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ fputs(f2leps_c8_kw[31], job->of2);
+}
+
+
+
+void
+f2leps_eps_with_tex_gsave(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ fputs(f2leps_c8_kw[15], job->of2);
+}
+
+
+
+void
+f2leps_eps_with_tex_grestore(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ fputs(f2leps_c8_kw[16], job->of2);
+}
+
+
+
+void
+f2leps_eps_with_tex_setcolor(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double r,
+ double g,
+ double b
+)
+{
+ fprintf(job->of2, f2leps_c8_kw[32], r, g, b);
+}
+
+
+
+void
+f2leps_eps_with_tex_set_line_width(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double lw
+)
+{
+ fprintf(job->of2, f2leps_c8_kw[33], lw);
+}
+
+
+void
+f2leps_eps_with_tex_set_line_style(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int ls,
+ double sv,
+ double lw
+)
+{
+ f2leps_set_line_style(job->of2, job, drw, obj, ls, sv, lw);
+}
+
+
+
+void
+f2leps_eps_with_tex_set_line_end(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int le
+)
+{
+ fprintf(job->of2, f2leps_c8_kw[34], le);
+}
+
+
+
+void
+f2leps_eps_with_tex_set_line_join(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int lj
+)
+{
+ fprintf(job->of2, f2leps_c8_kw[35], lj);
+}
+
+
+
+void
+f2leps_eps_with_tex_set_color_1(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+)
+{
+ fprintf(job->of2, f2leps_c8_kw[32], rgb->r, rgb->g, rgb->b);
+}
+
+
+
+void
+f2leps_eps_with_tex_set_color_2(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+)
+{
+ fprintf(job->of2, f2leps_c8_kw[32], rgb->r, rgb->g, rgb->b);
+}
+
+
+
+void
+f2leps_eps_with_tex_debug(
+ f2l_job_t *job,
+ char const *msg
+)
+{
+ f2leps_debug(job->of2, job, msg);
+}
+
+
+/* ************************************************************************ */
+/* * * */
+/* * Driver: EPS standalone file * */
+/* * * */
+/* ************************************************************************ */
+
+
+#line 1910 "f2leps.ctr"
+
+
+int
+f2leps_eps_pure_initialize(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ f2leps_drawing_info_t *pdi;
+ dk3_fig_obj_t *pobj;
+ int back = 0;
+ int fn;
+ int i;
+ int ff;
+ drw->dsd = (void *)(pdi = f2leps_drawing_info_new(job, 0));
+ if(drw->dsd) {
+ back = 1;
+ /* Inspect all elements.
+ */
+ dk3sto_it_reset(drw->iobj);
+ while(NULL != (pobj = (dk3_fig_obj_t *)dk3sto_it_next(drw->iobj))) {
+ switch(pobj->ot) {
+ case DK3_FIG_OBJ_TEXT: {
+ ff = (pobj->dt).txt.ff;
+ if(!(ff & DK3_FIG_FONT_FLAG_HIDDEN)) {
+ if(!(ff & DK3_FIG_FONT_FLAG_SPECIAL)) {
+ pdi->havetext = 1;
+ switch(pobj->st) {
+ case 1: {
+ pdi->alignedcenter = 1;
+ } break;
+ case 2: {
+ pdi->alignedright = 1;
+ } break;
+ }
+ fn = dk3fig_tool_ps_font_number(pobj);
+ if(-1 < fn) {
+ if(35 > fn) {
+ (pdi->fonts)[fn] = 1;
+ }
+ }
+ }
+ }
+ } break;
+ case DK3_FIG_OBJ_ELLIPSE:
+ case DK3_FIG_OBJ_POLYLINE:
+ case DK3_FIG_OBJ_SPLINE:
+ case DK3_FIG_OBJ_ARC: {
+ } break;
+ }
+ }
+ /* Calculate dictionary size.
+ */
+ for(i = 0; i < 35; i++) {
+ if((pdi->fonts)[i]) { /* Fonts */
+ pdi->dictsize += 1;
+ }
+ }
+ if(pdi->havetext) { /* Font reencode procedure */
+ pdi->dictsize += 1;
+ }
+ if(pdi->alignedcenter) { /* Procedure to show centered text. */
+ pdi->dictsize += 1;
+ }
+ if(pdi->alignedright) { /* Procedure to show right-algigned. */
+ pdi->dictsize += 1;
+ }
+ pdi->dictsize += 5; /* Reserve. */
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1977 "f2leps.ctr"
+ }
+ return back;
+}
+
+
+
+void
+f2leps_eps_pure_end(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ if(drw->dsd) {
+ f2leps_drawing_info_delete((f2leps_drawing_info_t *)(drw->dsd));
+ }
+}
+
+
+
+int
+f2leps_eps_pure_open_output_files(f2l_job_t *job)
+{
+ int back = 0;
+ job->of1 = dk3sf_fopen_app(job->on1, dkT("wb"), job->app);
+ if(job->of1) {
+ back = 1;
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 2002 "f2leps.ctr"
+ }
+ return back;
+}
+
+
+
+void
+f2leps_eps_pure_close_output_files(f2l_job_t *job)
+{
+ if(job->of1) {
+ dk3sf_fclose_app(job->of1, job->app);
+ } job->of1 = NULL;
+}
+
+
+
+int
+f2leps_eps_pure_start_processing(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ int back = 1;
+ f2leps_file_header(job, drw, job->of1, 1);
+ return back;
+}
+
+
+
+void
+f2leps_eps_pure_end_processing(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ f2leps_file_footer(job, drw, job->of1, 1);
+}
+
+
+
+void
+f2leps_eps_pure_text_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+ dk3_rgb_color_t rgb;
+ double fs;
+ int ff;
+ int fn;
+ int muc;
+ ff = (obj->dt).txt.ff;
+ if(!(ff & DK3_FIG_FONT_FLAG_HIDDEN)) {
+ if(!(ff & DK3_FIG_FONT_FLAG_SPECIAL)) {
+ fn = dk3fig_tool_ps_font_number(obj);
+ if(-1 < fn) {
+ if((obj->dt).txt.st) {
+ /* Set color */
+ dk3fig_tool_find_color(&rgb, drw, (obj->pc), 20);
+ muc = dk3fig_tool_must_set_color(
+ (job->gs).hc1, (job->gs).c1.r, (job->gs).c1.g, (job->gs).c1.b,
+ rgb.r, rgb.g, rgb.b
+ );
+ if(muc) {
+ fprintf(job->of1, f2leps_c8_kw[32], rgb.r, rgb.g, rgb.b);
+ (job->gs).c1.r = rgb.r;
+ (job->gs).c1.g = rgb.g;
+ (job->gs).c1.b = rgb.b;
+ (job->gs).c2.r = rgb.r;
+ (job->gs).c2.g = rgb.g;
+ (job->gs).c2.b = rgb.b;
+ (job->gs).hc1 = 1;
+ (job->gs).hc2 = 1;
+ }
+ /* Set font */
+ fs = (obj->dt).txt.fs;
+ if(0.0 < job->nts) { fs = fs * job->nts; }
+ muc = dk3fig_tool_must_set_font(
+ (job->gs).hfn, (job->gs).fn, (job->gs).fs, fn, fs
+ );
+ if(muc) {
+ fprintf(job->of1, f2leps_c8_kw[43], fn, fs);
+ (job->gs).hfn = 1;
+ (job->gs).fn = fn;
+ (job->gs).fs = fs;
+ }
+ if(1.0e-6 < fabs((obj->dt).txt.an)) { /* rotated */
+ /* gsave */
+ fputs(f2leps_c8_kw[15], job->of1);
+ /* translate */
+ fprintf(job->of1, f2leps_c8_kw[47], x, y);
+ /* rotate */
+ fprintf(
+ job->of1, f2leps_c8_kw[48],
+ ((180.0 * (obj->dt).txt.an) / M_PI)
+ );
+#if 0
+ /* newpath */
+ fputs(f2leps_c8_kw[21], job->of1);
+ /* 0 0 moveto */
+ fputs(f2leps_c8_kw[49], job->of1);
+ /* string */
+ f2leps_encode_string(job->of1, (obj->dt).txt.st);
+ /* show/show aligned */
+ switch(obj->st) {
+ case 2: {
+ fputs(f2leps_c8_kw[46], job->of1);
+ } break;
+ case 1: {
+ fputs(f2leps_c8_kw[45], job->of1);
+ } break;
+ default: {
+ fputs(f2leps_c8_kw[44], job->of1);
+ } break;
+ }
+#else
+ fputs(f2leps_c8_kw[51], job->of1);
+ /* string */
+ f2leps_encode_string(job->of1, (obj->dt).txt.st);
+ /* show/show aligned */
+ switch(obj->st) {
+ case 2: {
+ fputs(f2leps_c8_kw[46], job->of1);
+ } break;
+ case 1: {
+ fputs(f2leps_c8_kw[45], job->of1);
+ } break;
+ default: {
+ fputs(f2leps_c8_kw[50], job->of1);
+ } break;
+ }
+#endif
+ /* grestore */
+ fputs(f2leps_c8_kw[16], job->of1);
+ } else { /* not rotated */
+#if 0
+ /* newpath */
+ fputs(f2leps_c8_kw[21], job->of1);
+ /* moveto */
+ fprintf(job->of1, f2leps_c8_kw[25], x, y);
+ /* string */
+ f2leps_encode_string(job->of1, (obj->dt).txt.st);
+ /* show/show aligned */
+ switch(obj->st) {
+ case 2: {
+ fputs(f2leps_c8_kw[46], job->of1);
+ } break;
+ case 1: {
+ fputs(f2leps_c8_kw[45], job->of1);
+ } break;
+ default: {
+ fputs(f2leps_c8_kw[44], job->of1);
+ } break;
+ }
+#else
+ fprintf(job->of1, "%g %g\n", x, y);
+ /* string */
+ f2leps_encode_string(job->of1, (obj->dt).txt.st);
+ /* show/show aligned */
+ switch(obj->st) {
+ case 2: {
+ fputs(f2leps_c8_kw[46], job->of1);
+ } break;
+ case 1: {
+ fputs(f2leps_c8_kw[45], job->of1);
+ } break;
+ default: {
+ fputs(f2leps_c8_kw[50], job->of1);
+ } break;
+ }
+#endif
+ }
+ } else {
+ /* ##### BUG: No string */
+ }
+ } else {
+ /* ##### BUG: No font number found! */
+ }
+ } else {
+ /* Warning: Skipping special text! */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYNTAX);
+
+#line 2181 "f2leps.ctr"
+ }
+ }
+}
+
+
+
+void
+f2leps_eps_pure_image_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int drawdir,
+ int *ec
+)
+{
+ f2leps_image_object(job->of1, job, drw, obj, outbb, drawdir, ec);
+}
+
+
+void
+f2leps_eps_pure_newpath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ fputs(f2leps_c8_kw[21], job->of1);
+}
+
+
+
+void
+f2leps_eps_pure_moveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+ fprintf(job->of1, f2leps_c8_kw[25], x, y);
+}
+
+
+
+void
+f2leps_eps_pure_lineto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+ fprintf(job->of1, f2leps_c8_kw[26], x, y);
+}
+
+
+
+void
+f2leps_eps_pure_curveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double xcs,
+ double ycs,
+ double xce,
+ double yce,
+ double xe,
+ double ye
+)
+{
+ fprintf(job->of1, f2leps_c8_kw[27], xcs, ycs, xce, yce, xe, ye);
+}
+
+
+
+void
+f2leps_eps_pure_closepath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ fputs(f2leps_c8_kw[28], job->of1);
+}
+
+
+
+void
+f2leps_eps_pure_fill(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ fputs(f2leps_c8_kw[29], job->of1);
+}
+
+
+
+void
+f2leps_eps_pure_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ fputs(f2leps_c8_kw[30], job->of1);
+}
+
+
+
+void
+f2leps_eps_pure_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ fputs(f2leps_c8_kw[31], job->of1);
+}
+
+
+
+void
+f2leps_eps_pure_gsave(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ fputs(f2leps_c8_kw[15], job->of1);
+}
+
+
+
+void
+f2leps_eps_pure_grestore(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ fputs(f2leps_c8_kw[16], job->of1);
+}
+
+
+
+void
+f2leps_eps_pure_setcolor(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double r,
+ double g,
+ double b
+)
+{
+ fprintf(job->of1, f2leps_c8_kw[32], r, g, b);
+}
+
+
+
+void
+f2leps_eps_pure_set_line_width(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double lw
+)
+{
+ fprintf(job->of1, f2leps_c8_kw[33], lw);
+}
+
+
+
+void
+f2leps_eps_pure_set_line_style(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int ls,
+ double sv,
+ double lw
+)
+{
+ f2leps_set_line_style(job->of1, job, drw, obj, ls, sv, lw);
+}
+
+
+
+void
+f2leps_eps_pure_set_line_end(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int le
+)
+{
+ fprintf(job->of1, f2leps_c8_kw[34], le);
+}
+
+
+
+void
+f2leps_eps_pure_set_line_join(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int lj
+)
+{
+ fprintf(job->of1, f2leps_c8_kw[35], lj);
+}
+
+
+
+void
+f2leps_eps_pure_set_color_1(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+)
+{
+ fprintf(job->of1, f2leps_c8_kw[32], rgb->r, rgb->g, rgb->b);
+}
+
+
+
+void
+f2leps_eps_pure_set_color_2(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+)
+{
+ fprintf(job->of1, f2leps_c8_kw[32], rgb->r, rgb->g, rgb->b);
+}
+
+
+
+void
+f2leps_eps_pure_debug(
+ f2l_job_t *job,
+ char const *msg
+)
+{
+ f2leps_debug(job->of1, job, msg);
+}
+
diff --git a/support/dktools/f2leps.ctr b/support/dktools/f2leps.ctr
new file mode 100644
index 0000000000..6f88bf8ceb
--- /dev/null
+++ b/support/dktools/f2leps.ctr
@@ -0,0 +1,2432 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Driver initialization for pdf with tex driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+int
+f2leps_eps_with_tex_initialize(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Driver cleanup for pdf with tex driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+void
+f2leps_eps_with_tex_end(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Write start of output for eps with tex driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+int
+f2leps_eps_with_tex_start_processing(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Write end of output for eps with tex driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+void
+f2leps_eps_with_tex_end_processing(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Open output files for eps with tex driver.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+f2leps_eps_with_tex_open_output_files(f2l_job_t *job);
+
+/** Close output files for eps with tex driver.
+ @param job Job structure.
+*/
+void
+f2leps_eps_with_tex_close_output_files(f2l_job_t *job);
+
+/** Process one text object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x Point x.
+ @param y Point y.
+*/
+void
+f2leps_eps_with_tex_text_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Process one image object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param outbb Bounding box for image.
+ @param drawdir Drawing direction.
+ @param ec Pointer to error code variable, may be NULL.
+*/
+void
+f2leps_eps_with_tex_image_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int drawdir,
+ int *ec
+);
+
+/** Start new path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2leps_eps_with_tex_newpath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Move to point.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x Point x.
+ @param y Point y.
+*/
+void
+f2leps_eps_with_tex_moveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Draw line to point.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x Point x.
+ @param y Point y.
+*/
+void
+f2leps_eps_with_tex_lineto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Draw curve to point.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param xcs Start control point y.
+ @param ycs Start control point y.
+ @param xce End control point x.
+ @param yce End control point y.
+ @param xe End point x.
+ @param ye End point y.
+*/
+void
+f2leps_eps_with_tex_curveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double xcs,
+ double ycs,
+ double xce,
+ double yce,
+ double xe,
+ double ye
+);
+
+/** Close path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2leps_eps_with_tex_closepath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Fill path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2leps_eps_with_tex_fill(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Clip drawing operations to path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2leps_eps_with_tex_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Stroke path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2leps_eps_with_tex_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Save graphics state.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2leps_eps_with_tex_gsave(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Restore graphics state.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2leps_eps_with_tex_grestore(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Set color.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param r Red.
+ @param g Green.
+ @param b Blue.
+*/
+void
+f2leps_eps_with_tex_setcolor(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double r,
+ double g,
+ double b
+);
+
+/** Set line width.
+ The line width is not set again if we already
+ have a current line width equal to the new line width.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig Object.
+ @param lw New line width in output coordinates.
+*/
+void
+f2leps_eps_with_tex_set_line_width(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double lw
+);
+
+/** Set line style.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object to set up.
+ @param ls Line style, see @ref dk3figlinestyles.
+ @param sv Style value in output coordinates.
+ @param lw Dot length in output coordinates.
+*/
+void
+f2leps_eps_with_tex_set_line_style(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int ls,
+ double sv,
+ double lw
+);
+
+/** Set line end.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param le Line end, see @ref dk3figlinecap.
+*/
+void
+f2leps_eps_with_tex_set_line_end(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int le
+);
+
+/** Set line join.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param lj Line join style, see @ref dk3figlinejoin.
+*/
+void
+f2leps_eps_with_tex_set_line_join(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int lj
+);
+
+/** Set current color or stroking color (PGF, PDF).
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param rgb New color value.
+*/
+void
+f2leps_eps_with_tex_set_color_1(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+);
+
+/** Set non-stroking color (PGF, PDF).
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param rgb New color value.
+*/
+void
+f2leps_eps_with_tex_set_color_2(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+);
+
+
+/** Write debugging line to output file.
+ @param job Job structure.
+ @param msg Message to write to output file.
+*/
+void
+f2leps_eps_with_tex_debug(
+ f2l_job_t *job,
+ char const *msg
+);
+
+/** Driver initialization for tex with pdf driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+int
+f2leps_eps_pure_initialize(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Driver cleanup for tex with pdf driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+void
+f2leps_eps_pure_end(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Write start of output for eps driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+int
+f2leps_eps_pure_start_processing(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Write end of output for eps driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+void
+f2leps_eps_pure_end_processing(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Open output files for eps driver.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+f2leps_eps_pure_open_output_files(f2l_job_t *job);
+
+/** Close output files for eps driver.
+ @param job Job structure.
+*/
+void
+f2leps_eps_pure_close_output_files(f2l_job_t *job);
+
+/** Process one text object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x Point x.
+ @param y Point y.
+*/
+void
+f2leps_eps_pure_text_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Process one image object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param outbb Bounding box for image.
+ @param drawdir Drawing direction.
+ @param ec Pointer to error code variable, may be NULL.
+*/
+void
+f2leps_eps_pure_image_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int drawdir,
+ int *ec
+);
+
+/** Start new path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2leps_eps_pure_newpath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Move to point.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x Point x.
+ @param y Point y.
+*/
+void
+f2leps_eps_pure_moveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Draw line to point.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x Point x.
+ @param y Point y.
+*/
+void
+f2leps_eps_pure_lineto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Draw curve to point.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param xcs Start control point y.
+ @param ycs Start control point y.
+ @param xce End control point x.
+ @param yce End control point y.
+ @param xe End point x.
+ @param ye End point y.
+*/
+void
+f2leps_eps_pure_curveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double xcs,
+ double ycs,
+ double xce,
+ double yce,
+ double xe,
+ double ye
+);
+
+/** Close path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2leps_eps_pure_closepath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Fill path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2leps_eps_pure_fill(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Clip drawing operations to path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2leps_eps_pure_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Stroke path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2leps_eps_pure_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Save graphics state.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2leps_eps_pure_gsave(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Restore graphics state.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2leps_eps_pure_grestore(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Set color.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param r Red.
+ @param g Green.
+ @param b Blue.
+*/
+void
+f2leps_eps_pure_setcolor(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double r,
+ double g,
+ double b
+);
+
+
+/** Set line width.
+ The line width is not set again if we already
+ have a current line width equal to the new line width.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param lw New line width in output coordinates.
+*/
+void
+f2leps_eps_pure_set_line_width(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double lw
+);
+
+/** Set line style.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object to set up.
+ @param ls Line style, see @ref dk3figlinestyles.
+ @param sv Style value in output coordinates.
+ @param lw Dot length in output coordinates.
+*/
+void
+f2leps_eps_pure_set_line_style(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int ls,
+ double sv,
+ double lw
+);
+
+/** Set line end.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param le Line end, see @ref dk3figlinecap.
+*/
+void
+f2leps_eps_pure_set_line_end(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int le
+);
+
+/** Set line join.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param lj Line join style, see @ref dk3figlinejoin.
+*/
+void
+f2leps_eps_pure_set_line_join(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int lj
+);
+
+/** Set current color or stroking color (PGF, PDF).
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param rgb New color value.
+*/
+void
+f2leps_eps_pure_set_color_1(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+);
+
+/** Set non-stroking color (PGF, PDF).
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param rgb New color value.
+*/
+void
+f2leps_eps_pure_set_color_2(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+);
+
+/** Write debugging line to output file.
+ @param job Job structure.
+ @param msg Message to write to output file.
+*/
+void
+f2leps_eps_pure_debug(
+ f2l_job_t *job,
+ char const *msg
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk3all.h"
+#include "dk3bezcu.h"
+#include "fig2lat.h"
+#include "f2lud.h"
+#include "f2lsvg.h"
+#include "f2leps.h"
+#include "dk3figto.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4vers.h"
+#include "dk3font.h"
+#include "dk3bm.h"
+#include "dk3bmeps.h"
+
+
+$!trace-include
+
+
+
+/** Drawing-related information for EPS output.
+*/
+typedef struct {
+ char const *shortOutFile; /**< Short output file name. */
+ dk3_sto_t *sFonts; /**< Fonts and sizes (dk3_fig_font_t). */
+ dk3_sto_it_t *iFonts; /**< Fonts storage iterator. */
+ int *fonts; /**< 35 flags: Font used. */
+ unsigned long nFonts; /**< Number of fonts in sFonts. */
+ int havetext; /**< Flag: Text to show as PS text. */
+ int alignedright; /**< Flag: Right-aligned text found. */
+ int alignedcenter; /**< Flag: Centered text found. */
+ int dictsize; /**< Size of dictionary. */
+} f2leps_drawing_info_t;
+
+
+
+#if 0
+/** Font reencoding to write ISO-LATIN-1 encoded strings.
+*/
+static char const * const f2leps_font_reencode_2[] = {
+$!text
+/FontReEncode % originalname encodedname --
+{
+ 5 dict begin /nn exch def /an exch def an findfont dup
+ length dict /nf exch def
+ {
+ 1 index /FID ne
+ { nf 3 1 roll put }
+ { pop pop }
+ ifelse
+ }
+ forall
+ nf /Encoding ISOLatin1Encoding put nn nf end definefont pop
+}
+def
+$!end
+};
+#else
+/** Font reencoding to write ISO-LATIN-1 encoded strings.
+*/
+static char const * const f2leps_font_reencode_2[] = {
+$!text
+/FontReEncode % originalname newname --
+{ % on nn
+ exch % nn on
+ findfont % nn of
+ dup % nn of of
+ length % nn of length
+ 1 add % nn of length
+ dict % nn of nf
+ exch % nn nf of
+ { % nn nf key value
+ 1 index % nn nf key value key
+ /FID eq % nn nf key value flag
+ { % nn nf key value
+ pop pop % nn nf
+ }
+ { % nn nf key value
+ 2 index % nn nf key value nf
+ 3 1 roll % nn nf nf key value
+ put % nn nf
+ }
+ ifelse % nn nf
+ }
+ forall % nn nf
+ dup % nn nf nf
+ /Encoding ISOLatin1Encoding put % nn nf
+ definefont % nf
+ pop %
+}
+def
+$!end
+};
+#endif
+
+#if 0
+
+/** Procedure for right aligned text.
+*/
+static char const * const f2leps_right_aligned_text[] = {
+$!text
+/TextAlignedRight % text --
+{
+ currentpoint % text x y
+ 3 -1 roll % x y text
+ dup % x y text text
+ true charpath % x y text
+ flattenpath % x y text
+ pathbbox % x y text x1 y1 x2 y2
+ pop exch pop % x y text x1 x2
+ exch sub abs % x y text length
+ newpath 4 -2 roll % text length x y
+ moveto % text length
+ 0 exch sub % text distance
+ 0 rmoveto % text
+ show %
+} def
+$!end
+};
+
+
+
+/** Procedure for centered text.
+*/
+static char const * const f2leps_centered_aligned_text[] = {
+$!text
+/TextAlignedCentered % text --
+{
+ currentpoint % text x y
+ 3 -1 roll % x y text
+ dup % x y text text
+ true charpath % x y text
+ flattenpath % x y text
+ pathbbox % x y text x1 y1 x2 y2
+ pop exch pop % x y text x1 x2
+ exch sub abs % x y text length
+ newpath 4 -2 roll % text length x y
+ moveto % text length
+ 0.5 mul % text distance
+ 0 exch sub % text xshift
+ 0 rmoveto % text
+ show %
+} def
+$!end
+};
+
+#else
+
+/** Procedure for right aligned text.
+*/
+static char const * const f2leps_right_aligned_text[] = {
+$!text
+/TextAlignedRight % x y text --
+{
+ dup % x y text text
+ newpath % x y text text
+ 0 0 moveto % x y text text
+ true charpath % x y text
+ pathbbox % x y text x1 y1 x2 y2
+ pop % x y text x1 y1 x2
+ exch % x y text x1 x2 y1
+ pop % x y text x1 x2
+ exch % x y text x2 x1
+ pop % x y text width
+ newpath % x y text width
+ 4 3 roll % y text width x
+ exch % y text x width
+ sub % y text x
+ 3 2 roll % text x y
+ moveto % text
+ show % -
+} def
+$!end
+};
+
+
+
+/** Procedure for centered text.
+*/
+static char const * const f2leps_centered_aligned_text[] = {
+$!text
+/TextAlignedCentered % x y text --
+{
+ dup % x y text text
+ newpath % x y text text
+ 0 0 moveto % x y text text
+ true charpath % x y text
+ pathbbox % x y text x1 y1 x2 y2
+ pop % x y text x1 y1 x2
+ exch % x y text x1 x2 y1
+ pop % x y text x1 x2
+ exch % x y text x2 x1
+ pop % x y text width
+ 0.5 mul % x y text width/2
+ newpath % x y text width/2
+ 4 3 roll % y text width/2 x
+ exch % y text x width/2
+ sub % y text x
+ 3 2 roll % text x y
+ moveto % text
+ show % -
+} def
+$!end
+};
+
+#endif
+
+
+
+/** Keywords used by the module.
+*/
+static
+char const * const f2leps_c8_kw[] = {
+$!string-table
+#
+# 0: Newline
+#
+\n
+#
+# 1: Space
+#
+
+#
+# 2: File header for PS level 3
+#
+\%!PS-Adobe-3.0 EPSF-3.0\n
+#
+# 3: File header for PS level 2
+#
+\%!PS-Adobe-2.0 EPSF-2.0\n
+#
+# 4: Language level 3
+#
+\%%LanguageLevel: 3\n
+#
+# 5: Language level 2
+#
+\%%LanguageLevel: 2\n
+#
+# 6: Bounding box
+#
+\%%BoundingBox:
+#
+# 7: Format string for bounding box data.
+#
+0 0 %ld %ld\n
+#
+# 8: Creator string
+#
+\%%Creator: http://dktools.sourceforge.net\n
+#
+# 9: Title string.
+#
+\%%Title: Converted Fig image\n
+#
+# 10: Pages
+#
+\%%Pages: 1\n
+#
+# 11: PageOrder
+#
+\%%PageOrder: Ascend\n
+#
+# 12: DocumentData
+#
+\%%DocumentData: Clean7Bit\n
+#
+# 13: EndComments
+#
+\%%EndComments\n
+#
+# 14: Page
+#
+\%%Page: 1 1\n
+#
+# 15: gsave
+#
+gsave\n
+#
+# 16: grestore
+#
+grestore\n
+#
+# 17: xxx dict begin
+#
+\%d dict begin\n
+#
+# 18: end
+#
+end\n
+#
+# 19: showpage
+#
+showpage\n
+#
+# 20: Trailer and EOF
+#
+\%%Trailer\n%%EOF\n
+#
+# 21: newpath
+#
+newpath\n
+#
+# 22: clip to bounding box
+#
+0 0 moveto %ld 0 lineto %ld %ld lineto 0 %ld lineto 0 0 lineto\n
+#
+# 23: Close path and clip
+#
+closepath clip\n
+#
+# 24: Font reencoding
+#
+/%s /fnt%02d FontReEncode\n
+#
+# 25: Move to
+#
+\%g %g moveto\n
+#
+# 26: Line to
+#
+\%g %g lineto\n
+#
+# 27: Curve to
+#
+\%g %g %g %g %g %g curveto\n
+#
+# 28: Close path
+#
+closepath\n
+#
+# 29: Fill using even/odd rule
+#
+eofill\n
+#
+# 30: Clip using even/odd rule
+#
+eoclip\n
+#
+# 31: Stroke
+#
+stroke\n
+#
+# 32: Set RGB color
+#
+\%g %g %g setrgbcolor\n
+#
+# 33: Set line width
+#
+\%g setlinewidth\n
+#
+# 34: Set line cap
+#
+\%d setlinecap\n
+#
+# 35: Set line join
+#
+\%d setlinejoin\n
+#
+# 36: Dash for solid line.
+#
+[] 0 setdash\n
+#
+# 37: Dashed line.
+#
+[%g %g] 0 setdash\n
+#
+# 38: Dash-dotted line
+#
+[%g %g %g %g] 0 setdash\n
+#
+# 39: Dash-double-dotted line
+#
+[%g %g %g %g %g %g] 0 setdash\n
+#
+# 40: Dash-triple-dotted line
+#
+[%g %g %g %g %g %g %g %g] 0 setdash\n
+#
+# 41: Start of string.
+#
+(
+#
+# 42: End of string.
+#
+)
+#
+# 43: Font setup
+#
+/fnt%02d findfont %g scalefont setfont\n
+#
+# 44: Show left-justified text
+#
+ show\n
+#
+# 45: Show centered text
+#
+ TextAlignedCentered\n
+#
+# 46: Show right-justified text
+#
+ TextAlignedRight\n
+#
+# 47: Translate
+#
+\%g %g translate\n
+#
+# 48: Rotate
+#
+\%g rotate\n
+#
+# 49: Go to origin
+#
+0 0 moveto\n
+#
+# 50: Procedure to show string.
+#
+ 3 -2 roll newpath moveto show\n
+#
+# 51: Origin coordinates
+#
+0 0
+#
+# 52: Start of debug line.
+#
+%
+$!end
+};
+
+
+$*
+Tool functions
+$*
+
+
+
+/** Destroy drawing info structure.
+ @param pdi Structure to destroy.
+*/
+static
+void
+f2leps_drawing_info_delete(
+ f2leps_drawing_info_t *pdi
+)
+{
+ void *ptr; /* Current text handling information to delete. */
+
+ if(pdi) {
+ dk3_release(pdi->shortOutFile);
+ if(pdi->sFonts) {
+ if(pdi->iFonts) {
+ dk3sto_it_reset(pdi->iFonts);
+ while(NULL != (ptr = dk3sto_it_next(pdi->iFonts))) {
+ dk3_delete(ptr);
+ }
+ dk3sto_it_close(pdi->iFonts);
+ }
+ dk3sto_close(pdi->sFonts);
+ } pdi->sFonts = NULL; pdi->iFonts = NULL;
+ dk3_release(pdi->fonts);
+ dk3_delete(pdi);
+ }
+}
+
+
+
+/** Create drawing information structure.
+ @param job Job structure.
+ @param withFonts Flag: Gather LaTeX font information.
+ This flag is set to 1 for EPS/LaTeX and set to 0 for
+ pure EPS.
+ @return Pointer to new structure on success, NULL on error.
+*/
+static
+f2leps_drawing_info_t *
+f2leps_drawing_info_new(
+ f2l_job_t *job,
+ int withFonts
+)
+{
+ f2leps_drawing_info_t *back;
+ int ok = 0;
+ back = dk3_new_app(f2leps_drawing_info_t,1,job->app);
+ if(back) {
+ back->nFonts = 0UL;
+ back->sFonts = NULL;
+ back->iFonts = NULL;
+ back->fonts = NULL;
+ back->havetext = 0;
+ back->alignedright = 0;
+ back->alignedcenter = 0;
+ back->dictsize = 0;
+ back->shortOutFile = NULL;
+ if(withFonts) {
+ back->sFonts = dk3sto_open_app(job->app);
+ if(back->sFonts) {
+ dk3sto_set_comp(back->sFonts, dk3fig_tool_font_compare, 0);
+ back->iFonts = dk3sto_it_open(back->sFonts);
+ if(back->iFonts) {
+ ok = 1;
+ }
+ }
+ } else {
+ back->fonts = dk3_new_app(int,35,job->app);
+ if(back->fonts) {
+ ok = 1;
+ }
+ }
+ if(!(ok)) {
+ f2leps_drawing_info_delete(back);
+ back = NULL;
+ }
+ }
+ return back;
+}
+
+
+
+/** Write a text section to the output file.
+ @param of Output file.
+ @param ta String array to write.
+*/
+static
+void
+f2leps_write_text_section(
+ FILE *of,
+ char const * const *ta
+)
+{
+ char const * const *ptr;
+ ptr = ta;
+ while(*ptr) {
+ fputs(*(ptr++), of);
+ fputc('\n', of);
+ }
+}
+
+
+
+/** Write EPS file header.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param of Output file.
+ @param pure Flag: Pure EPS (1) or EPS/LaTeX (0).
+*/
+static
+void
+f2leps_file_header(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ FILE *of,
+ int pure
+)
+{
+ f2leps_drawing_info_t *pdi;
+ int i;
+ pdi = (f2leps_drawing_info_t *)(drw->dsd);
+ /* %!PS-Adobe-3.0 EPSF-3.0 */
+ if(2 < job->pslevel) {
+ fputs(f2leps_c8_kw[2], of);
+ fputs(f2leps_c8_kw[4], of);
+ } else {
+ fputs(f2leps_c8_kw[3], of);
+ fputs(f2leps_c8_kw[5], of);
+ }
+ /* bounding box */
+ fputs(f2leps_c8_kw[6], of);
+ fprintf(of, f2leps_c8_kw[7], job->lwidth, job->lheight);
+ if(job->dsc) {
+ /* Creator */
+ fputs(f2leps_c8_kw[8], of);
+ /* Title */
+ fputs(f2leps_c8_kw[9], of);
+ /* Pages */
+ fputs(f2leps_c8_kw[10], of);
+ /* PageOrder */
+ fputs(f2leps_c8_kw[11], of);
+ /* DocumentData */
+ fputs(f2leps_c8_kw[12], of);
+ if(pure) {
+ /* ##### HIER WEITER: DocumentNeededFonts */
+ }
+ /* EndComments */
+ fputs(f2leps_c8_kw[13], of);
+ /* Page */
+ fputs(f2leps_c8_kw[14], of);
+ }
+ fputs(f2leps_c8_kw[15], of);
+ fputs(f2leps_c8_kw[21], of);
+ fprintf(
+ of, f2leps_c8_kw[22],
+ job->lwidth, job->lwidth, job->lheight, job->lheight
+ );
+ fputs(f2leps_c8_kw[23], of);
+ if(pure) {
+ /* xxx dict begin */
+ fprintf(of, f2leps_c8_kw[17], pdi->dictsize);
+ }
+ /* Text procedures */
+ if(pdi->havetext) {
+ f2leps_write_text_section(of, f2leps_font_reencode_2);
+ if(pdi->alignedcenter) {
+ f2leps_write_text_section(of, f2leps_centered_aligned_text);
+ }
+ if(pdi->alignedright) {
+ f2leps_write_text_section(of, f2leps_right_aligned_text);
+ }
+ /* Font reencodings */
+ for(i = 0; i < 35; i++) {
+ if((pdi->fonts)[i]) {
+ fprintf(of, f2leps_c8_kw[24], dk3font_get_ps_font_name(i), i);
+ }
+ }
+ }
+}
+
+
+
+/** Write EPS file header.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param of Output file.
+ @param pure Flag: Pure EPS (1) or EPS/LaTeX (0).
+*/
+static
+void
+f2leps_file_footer(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ FILE *of,
+ int pure
+)
+{
+ if(pure) {
+ /* end */
+ fputs(f2leps_c8_kw[18], of);
+ }
+ /* grestore */
+ fputs(f2leps_c8_kw[16], of);
+ if(job->showpage) {
+ /* showpage */
+ fputs(f2leps_c8_kw[19], of);
+ }
+ if(job->dsc) {
+ /* Trailer, EOF */
+ fputs(f2leps_c8_kw[20], of);
+ }
+}
+
+
+
+/** Check whether a text character is literal.
+ @param c Character to check.
+ @return 1 to issue character as is, 0 for octal encoding.
+*/
+static
+int
+f2leps_is_literal(char c)
+{
+ int back = 0;
+ if(('A' <= c) && ('Z' >= c)) {
+ back = 1;
+ } else {
+ if(('a' <= c) && ('z' >= c)) {
+ back = 1;
+ } else {
+ if(('0' <= c) && ('9' >= c)) {
+ back = 1;
+ } else {
+ switch(c) {
+ case ' ':
+ {
+ back = 1;
+ } break;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Write string PS-encoded to output.
+ @param of Output file.
+ @param str String to write.
+*/
+static
+void
+f2leps_encode_string(
+ FILE *of,
+ char const *str
+)
+{
+ char buf[32];
+ char const *ptr;
+ char c;
+ unsigned char uc;
+ unsigned u;
+ ptr = str;
+ fputs(f2leps_c8_kw[41], of);
+ while(*ptr) {
+ c = *(ptr++);
+ if(f2leps_is_literal(c)) {
+ fputc(c, of);
+ } else {
+ uc = (unsigned char)c;
+ u = (unsigned)uc;
+ while(255 < u) { u = u - 256; }
+ sprintf(buf, "\\%03o", u);
+ fputs(buf, of);
+ }
+ }
+ fputs(f2leps_c8_kw[42], of);
+}
+
+
+
+/** Process an embedded bitmap image.
+ @param of Output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Image object.
+ @param outbb Destination image area.
+ @param drawdir Drawing direction / coordinates origin.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2leps_image_object(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int drawdir,
+ int *ec
+)
+{
+ int res = 0;
+ res = dk3bm_ps_place_object(
+ of,outbb,drawdir,(obj->dt).pol.fn,job->app,job->pslevel,ec
+ );
+ if(!(res)) {
+ job->exval = FIG2LAT_EXIT_ERROR_UNKNOWN; $? ". exitcode"
+ }
+}
+
+
+
+/** Set line style.
+ @param of Output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object using the line style.
+ @param ls Line style.
+ @param sv Style value (gap length).
+ @param lw Line width.
+*/
+static
+void
+f2leps_set_line_style(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int ls,
+ double sv,
+ double lw
+)
+{
+ double gw; /* Gap width. */
+ gw = f2lto_find_gap_length(job, lw, sv);
+ switch(ls) {
+ case DK3_FIG_LS_DASHED: {
+ fprintf(of, f2leps_c8_kw[37], sv, gw);
+ } break;
+ case DK3_FIG_LS_DOTTED: {
+ fprintf(of, f2leps_c8_kw[37], lw, gw);
+ } break;
+ case DK3_FIG_LS_DASH_DOTTED: {
+ fprintf(of, f2leps_c8_kw[38], sv, gw, lw, gw);
+ } break;
+ case DK3_FIG_LS_DASH_DOUBLE_DOTTED: {
+ fprintf(of, f2leps_c8_kw[39], sv, gw, lw, gw, lw, gw);
+ } break;
+ case DK3_FIG_LS_DASH_TRIPLE_DOTTED: {
+ fprintf(of, f2leps_c8_kw[40], sv, gw, lw, gw, lw, gw, lw, gw);
+ } break;
+ default: {
+ fputs(f2leps_c8_kw[36], of);
+ } break;
+ }
+}
+
+
+
+/** Write debug line to output.
+ @param of Output file.
+ @param job Job structure.
+ @param msg Message text to write.
+*/
+static
+void
+f2leps_debug(
+ FILE *of,
+ f2l_job_t *job,
+ char const *msg
+)
+{
+ if((job) && (msg)) {
+ fputs(f2leps_c8_kw[52], of);
+ fputs(msg, of);
+ fputs(f2leps_c8_kw[0], of);
+ }
+}
+
+
+
+$*
+Driver: EPS with LaTeX
+$*
+
+
+int
+f2leps_eps_with_tex_initialize(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ f2leps_drawing_info_t *pdi;
+ dk3_fig_obj_t *pobj;
+ dkChar const *oldsourcename = NULL;
+ unsigned long oldsourceline = 0UL;
+ int back = 0;
+ int ff;
+ $? "+ f2leps_eps_with_tex_initialize"
+ drw->dsd = (void *)(pdi = f2leps_drawing_info_new(job, 1));
+ if(drw->dsd) { $? ". dsd"
+ oldsourcename = dk3app_get_source_file(job->app);
+ oldsourceline = dk3app_get_source_line(job->app);
+ pdi->shortOutFile = dk3fig_tool_short_output_file_name(job->on2, job->app);
+ if(pdi->shortOutFile) { $? ". shortOutFile"
+ back = 1; $? ". back = 1"
+ dk3sto_it_reset(drw->iobj);
+ while(NULL != (pobj = (dk3_fig_obj_t *)dk3sto_it_next(drw->iobj))) {
+ $? ". object found %d %d", pobj->ot, pobj->st
+ dk3app_set_source_line(job->app, pobj->li);
+ switch(pobj->ot) {
+ case DK3_FIG_OBJ_TEXT: { $? ". text"
+ ff = (pobj->dt).txt.ff;
+ if(!(ff & DK3_FIG_FONT_FLAG_HIDDEN)) { $? ". not hidden"
+ if(!(ff & DK3_FIG_FONT_FLAG_SPECIAL)) { $? ". not special"
+ if(ff & DK3_FIG_FONT_FLAG_PS) { $? ". PS font"
+ if(job->ntf) { $? ". ntf"
+ pobj->dsd = (void *)f2l_tool_register_font(
+ pdi->sFonts, pdi->iFonts, &(pdi->nFonts),
+ (pobj->dt).txt.fo, (pobj->dt).txt.fs, job->app
+ );
+ if(!(pobj->dsd)) {
+ back = 0;
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ } else { $? ". no ntf"
+ }
+ }
+ }
+ }
+ } break;
+ }
+ }
+ } else { $? "! shortOutFile"
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ dk3app_set_source_file(job->app, oldsourcename);
+ dk3app_set_source_line(job->app, oldsourceline);
+ } else { $? "! dsd"
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ } $? "- f2leps_eps_with_tex_initialize %d", back
+ return back;
+}
+
+
+
+void
+f2leps_eps_with_tex_end(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ $? "+ f2leps_eps_with_tex_end"
+ if(drw->dsd) {
+ f2leps_drawing_info_delete((f2leps_drawing_info_t *)(drw->dsd));
+ }
+ $? "- f2leps_eps_with_tex_end"
+}
+
+
+
+int
+f2leps_eps_with_tex_open_output_files(f2l_job_t *job)
+{
+ int back = 0;
+ $? "+ f2leps_eps_with_tex_open_output_files"
+ job->of1 = dk3sf_fopen_app(job->on1, dkT("w"), job->app);
+ if(job->of1) {
+ job->of2 = dk3sf_fopen_app(job->on2, dkT("wb"), job->app);
+ if(job->of2) {
+ back = 1;
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ $? "- f2leps_eps_with_tex_open_output_files %d", back
+ return back;
+}
+
+
+
+void
+f2leps_eps_with_tex_close_output_files(f2l_job_t *job)
+{
+ $? "+ f2leps_eps_with_tex_close_output_files"
+ if(job->of2) {
+ dk3sf_fclose_app(job->of2, job->app);
+ } job->of2 = NULL;
+ if(job->of1) {
+ dk3sf_fclose_app(job->of1, job->app);
+ } job->of1 = NULL;
+ $? "- f2leps_eps_with_tex_close_output_files"
+}
+
+
+
+int
+f2leps_eps_with_tex_start_processing(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ f2leps_drawing_info_t *pdi;
+ int back = 1;
+ $? "+ f2leps_eps_with_tex_start_processing"
+ pdi = (f2leps_drawing_info_t *)(drw->dsd);
+ f2leps_file_header(job, drw, job->of2, 0);
+ f2l_tool_start_tex_part(
+ job->of1, job, drw, pdi->shortOutFile, pdi->iFonts, pdi->nFonts
+ );
+ $? "- f2leps_eps_with_tex_start_processing %d", back
+ return back;
+}
+
+
+
+void
+f2leps_eps_with_tex_end_processing(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ $? "+ f2leps_eps_with_tex_end_processing"
+ f2leps_file_footer(job, drw, job->of2, 0);
+ f2l_tool_end_tex_part(job->of1);
+ $? "- f2leps_eps_with_tex_end_processing"
+}
+
+
+
+void
+f2leps_eps_with_tex_text_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+ f2leps_drawing_info_t *pdi;
+ pdi = (f2leps_drawing_info_t *)(drw->dsd);
+ f2l_tool_text_object(job->of1, job, drw, obj, x, y, pdi->nFonts);
+}
+
+
+
+void
+f2leps_eps_with_tex_image_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int drawdir,
+ int *ec
+)
+{
+ f2leps_image_object(job->of2, job, drw, obj, outbb, drawdir, ec);
+}
+
+
+void
+f2leps_eps_with_tex_newpath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ fputs(f2leps_c8_kw[21], job->of2);
+}
+
+
+
+void
+f2leps_eps_with_tex_moveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+ fprintf(job->of2, f2leps_c8_kw[25], x, y);
+}
+
+
+
+void
+f2leps_eps_with_tex_lineto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+ fprintf(job->of2, f2leps_c8_kw[26], x, y);
+}
+
+
+
+void
+f2leps_eps_with_tex_curveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double xcs,
+ double ycs,
+ double xce,
+ double yce,
+ double xe,
+ double ye
+)
+{
+ fprintf(job->of2, f2leps_c8_kw[27], xcs, ycs, xce, yce, xe, ye);
+}
+
+
+
+void
+f2leps_eps_with_tex_closepath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ fputs(f2leps_c8_kw[28], job->of2);
+}
+
+
+
+void
+f2leps_eps_with_tex_fill(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ fputs(f2leps_c8_kw[29], job->of2);
+}
+
+
+
+void
+f2leps_eps_with_tex_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ fputs(f2leps_c8_kw[30], job->of2);
+}
+
+
+
+void
+f2leps_eps_with_tex_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ fputs(f2leps_c8_kw[31], job->of2);
+}
+
+
+
+void
+f2leps_eps_with_tex_gsave(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ fputs(f2leps_c8_kw[15], job->of2);
+}
+
+
+
+void
+f2leps_eps_with_tex_grestore(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ fputs(f2leps_c8_kw[16], job->of2);
+}
+
+
+
+void
+f2leps_eps_with_tex_setcolor(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double r,
+ double g,
+ double b
+)
+{
+ fprintf(job->of2, f2leps_c8_kw[32], r, g, b);
+}
+
+
+
+void
+f2leps_eps_with_tex_set_line_width(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double lw
+)
+{
+ fprintf(job->of2, f2leps_c8_kw[33], lw);
+}
+
+
+void
+f2leps_eps_with_tex_set_line_style(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int ls,
+ double sv,
+ double lw
+)
+{
+ f2leps_set_line_style(job->of2, job, drw, obj, ls, sv, lw);
+}
+
+
+
+void
+f2leps_eps_with_tex_set_line_end(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int le
+)
+{
+ fprintf(job->of2, f2leps_c8_kw[34], le);
+}
+
+
+
+void
+f2leps_eps_with_tex_set_line_join(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int lj
+)
+{
+ fprintf(job->of2, f2leps_c8_kw[35], lj);
+}
+
+
+
+void
+f2leps_eps_with_tex_set_color_1(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+)
+{
+ fprintf(job->of2, f2leps_c8_kw[32], rgb->r, rgb->g, rgb->b);
+}
+
+
+
+void
+f2leps_eps_with_tex_set_color_2(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+)
+{
+ fprintf(job->of2, f2leps_c8_kw[32], rgb->r, rgb->g, rgb->b);
+}
+
+
+
+void
+f2leps_eps_with_tex_debug(
+ f2l_job_t *job,
+ char const *msg
+)
+{
+ f2leps_debug(job->of2, job, msg);
+}
+
+
+$*
+Driver: EPS standalone file
+$*
+
+
+int
+f2leps_eps_pure_initialize(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ f2leps_drawing_info_t *pdi;
+ dk3_fig_obj_t *pobj;
+ int back = 0;
+ int fn;
+ int i;
+ int ff;
+ drw->dsd = (void *)(pdi = f2leps_drawing_info_new(job, 0));
+ if(drw->dsd) {
+ back = 1;
+ /* Inspect all elements.
+ */
+ dk3sto_it_reset(drw->iobj);
+ while(NULL != (pobj = (dk3_fig_obj_t *)dk3sto_it_next(drw->iobj))) {
+ switch(pobj->ot) {
+ case DK3_FIG_OBJ_TEXT: {
+ ff = (pobj->dt).txt.ff;
+ if(!(ff & DK3_FIG_FONT_FLAG_HIDDEN)) {
+ if(!(ff & DK3_FIG_FONT_FLAG_SPECIAL)) {
+ pdi->havetext = 1;
+ switch(pobj->st) {
+ case 1: {
+ pdi->alignedcenter = 1;
+ } break;
+ case 2: {
+ pdi->alignedright = 1;
+ } break;
+ }
+ fn = dk3fig_tool_ps_font_number(pobj);
+ if(-1 < fn) {
+ if(35 > fn) {
+ (pdi->fonts)[fn] = 1;
+ }
+ }
+ }
+ }
+ } break;
+ case DK3_FIG_OBJ_ELLIPSE:
+ case DK3_FIG_OBJ_POLYLINE:
+ case DK3_FIG_OBJ_SPLINE:
+ case DK3_FIG_OBJ_ARC: {
+ } break;
+ }
+ }
+ /* Calculate dictionary size.
+ */
+ for(i = 0; i < 35; i++) {
+ if((pdi->fonts)[i]) { /* Fonts */
+ pdi->dictsize += 1;
+ }
+ }
+ if(pdi->havetext) { /* Font reencode procedure */
+ pdi->dictsize += 1;
+ }
+ if(pdi->alignedcenter) { /* Procedure to show centered text. */
+ pdi->dictsize += 1;
+ }
+ if(pdi->alignedright) { /* Procedure to show right-algigned. */
+ pdi->dictsize += 1;
+ }
+ pdi->dictsize += 5; /* Reserve. */
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ return back;
+}
+
+
+
+void
+f2leps_eps_pure_end(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ if(drw->dsd) {
+ f2leps_drawing_info_delete((f2leps_drawing_info_t *)(drw->dsd));
+ }
+}
+
+
+
+int
+f2leps_eps_pure_open_output_files(f2l_job_t *job)
+{
+ int back = 0;
+ job->of1 = dk3sf_fopen_app(job->on1, dkT("wb"), job->app);
+ if(job->of1) {
+ back = 1;
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ return back;
+}
+
+
+
+void
+f2leps_eps_pure_close_output_files(f2l_job_t *job)
+{
+ if(job->of1) {
+ dk3sf_fclose_app(job->of1, job->app);
+ } job->of1 = NULL;
+}
+
+
+
+int
+f2leps_eps_pure_start_processing(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ int back = 1;
+ f2leps_file_header(job, drw, job->of1, 1);
+ return back;
+}
+
+
+
+void
+f2leps_eps_pure_end_processing(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ f2leps_file_footer(job, drw, job->of1, 1);
+}
+
+
+
+void
+f2leps_eps_pure_text_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+ dk3_rgb_color_t rgb;
+ double fs;
+ int ff;
+ int fn;
+ int muc;
+ ff = (obj->dt).txt.ff;
+ if(!(ff & DK3_FIG_FONT_FLAG_HIDDEN)) {
+ if(!(ff & DK3_FIG_FONT_FLAG_SPECIAL)) {
+ fn = dk3fig_tool_ps_font_number(obj);
+ if(-1 < fn) {
+ if((obj->dt).txt.st) {
+ /* Set color */
+ dk3fig_tool_find_color(&rgb, drw, (obj->pc), 20);
+ muc = dk3fig_tool_must_set_color(
+ (job->gs).hc1, (job->gs).c1.r, (job->gs).c1.g, (job->gs).c1.b,
+ rgb.r, rgb.g, rgb.b
+ );
+ if(muc) {
+ fprintf(job->of1, f2leps_c8_kw[32], rgb.r, rgb.g, rgb.b);
+ (job->gs).c1.r = rgb.r;
+ (job->gs).c1.g = rgb.g;
+ (job->gs).c1.b = rgb.b;
+ (job->gs).c2.r = rgb.r;
+ (job->gs).c2.g = rgb.g;
+ (job->gs).c2.b = rgb.b;
+ (job->gs).hc1 = 1;
+ (job->gs).hc2 = 1;
+ }
+ /* Set font */
+ fs = (obj->dt).txt.fs;
+ if(0.0 < job->nts) { fs = fs * job->nts; }
+ muc = dk3fig_tool_must_set_font(
+ (job->gs).hfn, (job->gs).fn, (job->gs).fs, fn, fs
+ );
+ if(muc) {
+ fprintf(job->of1, f2leps_c8_kw[43], fn, fs);
+ (job->gs).hfn = 1;
+ (job->gs).fn = fn;
+ (job->gs).fs = fs;
+ }
+ if(1.0e-6 < fabs((obj->dt).txt.an)) { /* rotated */
+ /* gsave */
+ fputs(f2leps_c8_kw[15], job->of1);
+ /* translate */
+ fprintf(job->of1, f2leps_c8_kw[47], x, y);
+ /* rotate */
+ fprintf(
+ job->of1, f2leps_c8_kw[48],
+ ((180.0 * (obj->dt).txt.an) / M_PI)
+ );
+#if 0
+ /* newpath */
+ fputs(f2leps_c8_kw[21], job->of1);
+ /* 0 0 moveto */
+ fputs(f2leps_c8_kw[49], job->of1);
+ /* string */
+ f2leps_encode_string(job->of1, (obj->dt).txt.st);
+ /* show/show aligned */
+ switch(obj->st) {
+ case 2: {
+ fputs(f2leps_c8_kw[46], job->of1);
+ } break;
+ case 1: {
+ fputs(f2leps_c8_kw[45], job->of1);
+ } break;
+ default: {
+ fputs(f2leps_c8_kw[44], job->of1);
+ } break;
+ }
+#else
+ fputs(f2leps_c8_kw[51], job->of1);
+ /* string */
+ f2leps_encode_string(job->of1, (obj->dt).txt.st);
+ /* show/show aligned */
+ switch(obj->st) {
+ case 2: {
+ fputs(f2leps_c8_kw[46], job->of1);
+ } break;
+ case 1: {
+ fputs(f2leps_c8_kw[45], job->of1);
+ } break;
+ default: {
+ fputs(f2leps_c8_kw[50], job->of1);
+ } break;
+ }
+#endif
+ /* grestore */
+ fputs(f2leps_c8_kw[16], job->of1);
+ } else { /* not rotated */
+#if 0
+ /* newpath */
+ fputs(f2leps_c8_kw[21], job->of1);
+ /* moveto */
+ fprintf(job->of1, f2leps_c8_kw[25], x, y);
+ /* string */
+ f2leps_encode_string(job->of1, (obj->dt).txt.st);
+ /* show/show aligned */
+ switch(obj->st) {
+ case 2: {
+ fputs(f2leps_c8_kw[46], job->of1);
+ } break;
+ case 1: {
+ fputs(f2leps_c8_kw[45], job->of1);
+ } break;
+ default: {
+ fputs(f2leps_c8_kw[44], job->of1);
+ } break;
+ }
+#else
+ fprintf(job->of1, "%g %g\n", x, y);
+ /* string */
+ f2leps_encode_string(job->of1, (obj->dt).txt.st);
+ /* show/show aligned */
+ switch(obj->st) {
+ case 2: {
+ fputs(f2leps_c8_kw[46], job->of1);
+ } break;
+ case 1: {
+ fputs(f2leps_c8_kw[45], job->of1);
+ } break;
+ default: {
+ fputs(f2leps_c8_kw[50], job->of1);
+ } break;
+ }
+#endif
+ }
+ } else {
+ /* ##### BUG: No string */
+ }
+ } else {
+ /* ##### BUG: No font number found! */
+ }
+ } else {
+ /* Warning: Skipping special text! */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYNTAX); $? ". exitcode"
+ }
+ }
+}
+
+
+
+void
+f2leps_eps_pure_image_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int drawdir,
+ int *ec
+)
+{
+ f2leps_image_object(job->of1, job, drw, obj, outbb, drawdir, ec);
+}
+
+
+void
+f2leps_eps_pure_newpath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ fputs(f2leps_c8_kw[21], job->of1);
+}
+
+
+
+void
+f2leps_eps_pure_moveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+ fprintf(job->of1, f2leps_c8_kw[25], x, y);
+}
+
+
+
+void
+f2leps_eps_pure_lineto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+ fprintf(job->of1, f2leps_c8_kw[26], x, y);
+}
+
+
+
+void
+f2leps_eps_pure_curveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double xcs,
+ double ycs,
+ double xce,
+ double yce,
+ double xe,
+ double ye
+)
+{
+ fprintf(job->of1, f2leps_c8_kw[27], xcs, ycs, xce, yce, xe, ye);
+}
+
+
+
+void
+f2leps_eps_pure_closepath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ fputs(f2leps_c8_kw[28], job->of1);
+}
+
+
+
+void
+f2leps_eps_pure_fill(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ fputs(f2leps_c8_kw[29], job->of1);
+}
+
+
+
+void
+f2leps_eps_pure_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ fputs(f2leps_c8_kw[30], job->of1);
+}
+
+
+
+void
+f2leps_eps_pure_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ fputs(f2leps_c8_kw[31], job->of1);
+}
+
+
+
+void
+f2leps_eps_pure_gsave(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ fputs(f2leps_c8_kw[15], job->of1);
+}
+
+
+
+void
+f2leps_eps_pure_grestore(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ fputs(f2leps_c8_kw[16], job->of1);
+}
+
+
+
+void
+f2leps_eps_pure_setcolor(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double r,
+ double g,
+ double b
+)
+{
+ fprintf(job->of1, f2leps_c8_kw[32], r, g, b);
+}
+
+
+
+void
+f2leps_eps_pure_set_line_width(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double lw
+)
+{
+ fprintf(job->of1, f2leps_c8_kw[33], lw);
+}
+
+
+
+void
+f2leps_eps_pure_set_line_style(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int ls,
+ double sv,
+ double lw
+)
+{
+ f2leps_set_line_style(job->of1, job, drw, obj, ls, sv, lw);
+}
+
+
+
+void
+f2leps_eps_pure_set_line_end(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int le
+)
+{
+ fprintf(job->of1, f2leps_c8_kw[34], le);
+}
+
+
+
+void
+f2leps_eps_pure_set_line_join(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int lj
+)
+{
+ fprintf(job->of1, f2leps_c8_kw[35], lj);
+}
+
+
+
+void
+f2leps_eps_pure_set_color_1(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+)
+{
+ fprintf(job->of1, f2leps_c8_kw[32], rgb->r, rgb->g, rgb->b);
+}
+
+
+
+void
+f2leps_eps_pure_set_color_2(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+)
+{
+ fprintf(job->of1, f2leps_c8_kw[32], rgb->r, rgb->g, rgb->b);
+}
+
+
+
+void
+f2leps_eps_pure_debug(
+ f2l_job_t *job,
+ char const *msg
+)
+{
+ f2leps_debug(job->of1, job, msg);
+}
+
diff --git a/support/dktools/f2leps.h b/support/dktools/f2leps.h
new file mode 100644
index 0000000000..2832e7255a
--- /dev/null
+++ b/support/dktools/f2leps.h
@@ -0,0 +1,721 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: f2leps.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file f2leps.h Header file for the f2leps module.
+*/
+
+#ifndef F2LEPS_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define F2LEPS_H_INCLUDED 1
+
+
+#line 10 "f2leps.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Driver initialization for pdf with tex driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+int
+f2leps_eps_with_tex_initialize(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Driver cleanup for pdf with tex driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+void
+f2leps_eps_with_tex_end(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Write start of output for eps with tex driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+int
+f2leps_eps_with_tex_start_processing(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Write end of output for eps with tex driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+void
+f2leps_eps_with_tex_end_processing(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Open output files for eps with tex driver.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+f2leps_eps_with_tex_open_output_files(f2l_job_t *job);
+
+/** Close output files for eps with tex driver.
+ @param job Job structure.
+*/
+void
+f2leps_eps_with_tex_close_output_files(f2l_job_t *job);
+
+/** Process one text object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x Point x.
+ @param y Point y.
+*/
+void
+f2leps_eps_with_tex_text_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Process one image object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param outbb Bounding box for image.
+ @param drawdir Drawing direction.
+ @param ec Pointer to error code variable, may be NULL.
+*/
+void
+f2leps_eps_with_tex_image_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int drawdir,
+ int *ec
+);
+
+/** Start new path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2leps_eps_with_tex_newpath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Move to point.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x Point x.
+ @param y Point y.
+*/
+void
+f2leps_eps_with_tex_moveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Draw line to point.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x Point x.
+ @param y Point y.
+*/
+void
+f2leps_eps_with_tex_lineto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Draw curve to point.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param xcs Start control point y.
+ @param ycs Start control point y.
+ @param xce End control point x.
+ @param yce End control point y.
+ @param xe End point x.
+ @param ye End point y.
+*/
+void
+f2leps_eps_with_tex_curveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double xcs,
+ double ycs,
+ double xce,
+ double yce,
+ double xe,
+ double ye
+);
+
+/** Close path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2leps_eps_with_tex_closepath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Fill path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2leps_eps_with_tex_fill(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Clip drawing operations to path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2leps_eps_with_tex_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Stroke path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2leps_eps_with_tex_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Save graphics state.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2leps_eps_with_tex_gsave(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Restore graphics state.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2leps_eps_with_tex_grestore(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Set color.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param r Red.
+ @param g Green.
+ @param b Blue.
+*/
+void
+f2leps_eps_with_tex_setcolor(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double r,
+ double g,
+ double b
+);
+
+/** Set line width.
+ The line width is not set again if we already
+ have a current line width equal to the new line width.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig Object.
+ @param lw New line width in output coordinates.
+*/
+void
+f2leps_eps_with_tex_set_line_width(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double lw
+);
+
+/** Set line style.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object to set up.
+ @param ls Line style, see @ref dk3figlinestyles.
+ @param sv Style value in output coordinates.
+ @param lw Dot length in output coordinates.
+*/
+void
+f2leps_eps_with_tex_set_line_style(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int ls,
+ double sv,
+ double lw
+);
+
+/** Set line end.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param le Line end, see @ref dk3figlinecap.
+*/
+void
+f2leps_eps_with_tex_set_line_end(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int le
+);
+
+/** Set line join.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param lj Line join style, see @ref dk3figlinejoin.
+*/
+void
+f2leps_eps_with_tex_set_line_join(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int lj
+);
+
+/** Set current color or stroking color (PGF, PDF).
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param rgb New color value.
+*/
+void
+f2leps_eps_with_tex_set_color_1(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+);
+
+/** Set non-stroking color (PGF, PDF).
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param rgb New color value.
+*/
+void
+f2leps_eps_with_tex_set_color_2(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+);
+
+
+/** Write debugging line to output file.
+ @param job Job structure.
+ @param msg Message to write to output file.
+*/
+void
+f2leps_eps_with_tex_debug(
+ f2l_job_t *job,
+ char const *msg
+);
+
+/** Driver initialization for tex with pdf driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+int
+f2leps_eps_pure_initialize(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Driver cleanup for tex with pdf driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+void
+f2leps_eps_pure_end(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Write start of output for eps driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+int
+f2leps_eps_pure_start_processing(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Write end of output for eps driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+void
+f2leps_eps_pure_end_processing(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Open output files for eps driver.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+f2leps_eps_pure_open_output_files(f2l_job_t *job);
+
+/** Close output files for eps driver.
+ @param job Job structure.
+*/
+void
+f2leps_eps_pure_close_output_files(f2l_job_t *job);
+
+/** Process one text object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x Point x.
+ @param y Point y.
+*/
+void
+f2leps_eps_pure_text_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Process one image object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param outbb Bounding box for image.
+ @param drawdir Drawing direction.
+ @param ec Pointer to error code variable, may be NULL.
+*/
+void
+f2leps_eps_pure_image_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int drawdir,
+ int *ec
+);
+
+/** Start new path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2leps_eps_pure_newpath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Move to point.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x Point x.
+ @param y Point y.
+*/
+void
+f2leps_eps_pure_moveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Draw line to point.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x Point x.
+ @param y Point y.
+*/
+void
+f2leps_eps_pure_lineto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Draw curve to point.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param xcs Start control point y.
+ @param ycs Start control point y.
+ @param xce End control point x.
+ @param yce End control point y.
+ @param xe End point x.
+ @param ye End point y.
+*/
+void
+f2leps_eps_pure_curveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double xcs,
+ double ycs,
+ double xce,
+ double yce,
+ double xe,
+ double ye
+);
+
+/** Close path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2leps_eps_pure_closepath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Fill path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2leps_eps_pure_fill(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Clip drawing operations to path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2leps_eps_pure_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Stroke path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2leps_eps_pure_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Save graphics state.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2leps_eps_pure_gsave(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Restore graphics state.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2leps_eps_pure_grestore(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Set color.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param r Red.
+ @param g Green.
+ @param b Blue.
+*/
+void
+f2leps_eps_pure_setcolor(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double r,
+ double g,
+ double b
+);
+
+
+/** Set line width.
+ The line width is not set again if we already
+ have a current line width equal to the new line width.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param lw New line width in output coordinates.
+*/
+void
+f2leps_eps_pure_set_line_width(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double lw
+);
+
+/** Set line style.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object to set up.
+ @param ls Line style, see @ref dk3figlinestyles.
+ @param sv Style value in output coordinates.
+ @param lw Dot length in output coordinates.
+*/
+void
+f2leps_eps_pure_set_line_style(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int ls,
+ double sv,
+ double lw
+);
+
+/** Set line end.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param le Line end, see @ref dk3figlinecap.
+*/
+void
+f2leps_eps_pure_set_line_end(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int le
+);
+
+/** Set line join.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param lj Line join style, see @ref dk3figlinejoin.
+*/
+void
+f2leps_eps_pure_set_line_join(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int lj
+);
+
+/** Set current color or stroking color (PGF, PDF).
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param rgb New color value.
+*/
+void
+f2leps_eps_pure_set_color_1(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+);
+
+/** Set non-stroking color (PGF, PDF).
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param rgb New color value.
+*/
+void
+f2leps_eps_pure_set_color_2(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+);
+
+/** Write debugging line to output file.
+ @param job Job structure.
+ @param msg Message to write to output file.
+*/
+void
+f2leps_eps_pure_debug(
+ f2l_job_t *job,
+ char const *msg
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/f2ll2l.c b/support/dktools/f2ll2l.c
new file mode 100644
index 0000000000..832a49d707
--- /dev/null
+++ b/support/dktools/f2ll2l.c
@@ -0,0 +1,353 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: f2ll2l.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file f2ll2l.c The f2ll2l module.
+*/
+
+
+#line 35 "f2ll2l.ctr"
+
+
+#include "dk3all.h"
+
+
+
+
+
+#line 42 "f2ll2l.ctr"
+
+
+
+/** Encodings for 0x00-0xFF.
+*/
+static char const * const f2ll2l_encodings[] = {
+/* 000 00 */ "",
+/* 001 01 */ "",
+/* 002 02 */ "",
+/* 003 03 */ "",
+/* 004 04 */ "",
+/* 005 05 */ "",
+/* 006 06 */ "",
+/* 007 07 */ "",
+/* 008 08 */ "",
+/* 009 09 */ "\t",
+/* 010 0a */ "\\\\*",
+/* 011 0b */ "",
+/* 012 0c */ "",
+/* 013 0d */ "",
+/* 014 0e */ "",
+/* 015 0f */ "",
+/* 016 10 */ "",
+/* 017 11 */ "",
+/* 018 12 */ "",
+/* 019 13 */ "",
+/* 020 14 */ "",
+/* 021 15 */ "",
+/* 022 16 */ "",
+/* 023 17 */ "",
+/* 024 18 */ "",
+/* 025 19 */ "",
+/* 026 1a */ "",
+/* 027 1b */ "",
+/* 028 1c */ "",
+/* 029 1d */ "",
+/* 030 1e */ "",
+/* 031 1f */ "",
+/* 032 20 */ " ",
+/* 033 21 */ "!",
+/* 034 22 */ "\\textquotedbl{}",
+/* 035 23 */ "\\#",
+/* 036 24 */ "\\textdollar{}",
+/* 037 25 */ "\\%",
+/* 038 26 */ "\\&",
+/* 039 27 */ "\\textquoteright{}",
+/* 040 28 */ "(",
+/* 041 29 */ ")",
+/* 042 2a */ "\\textasteriskcentered{}",
+/* 043 2b */ "+",
+/* 044 2c */ ",",
+/* 045 2d */ "-",
+/* 046 2e */ ".",
+/* 047 2f */ "/",
+/* 048 30 */ "0",
+/* 049 31 */ "1",
+/* 050 32 */ "2",
+/* 051 33 */ "3",
+/* 052 34 */ "4",
+/* 053 35 */ "5",
+/* 054 36 */ "6",
+/* 055 37 */ "7",
+/* 056 38 */ "8",
+/* 057 39 */ "9",
+/* 058 3a */ ":",
+/* 059 3b */ ";",
+/* 060 3c */ "\\textless{}",
+/* 061 3d */ "=",
+/* 062 3e */ "\\textgreater{}",
+/* 063 3f */ "?",
+/* 064 40 */ "@",
+/* 065 41 */ "A",
+/* 066 42 */ "B",
+/* 067 43 */ "C",
+/* 068 44 */ "D",
+/* 069 45 */ "E",
+/* 070 46 */ "F",
+/* 071 47 */ "G",
+/* 072 48 */ "H",
+/* 073 49 */ "I",
+/* 074 4a */ "J",
+/* 075 4b */ "K",
+/* 076 4c */ "L",
+/* 077 4d */ "M",
+/* 078 4e */ "N",
+/* 079 4f */ "O",
+/* 080 50 */ "P",
+/* 081 51 */ "Q",
+/* 082 52 */ "R",
+/* 083 53 */ "S",
+/* 084 54 */ "T",
+/* 085 55 */ "U",
+/* 086 56 */ "V",
+/* 087 57 */ "W",
+/* 088 58 */ "X",
+/* 089 59 */ "Y",
+/* 090 5a */ "Z",
+/* 091 5b */ "[",
+/* 092 5c */ "\\textbackslash{}",
+/* 093 5d */ "]",
+/* 094 5e */ "\\textasciicircum{}",
+/* 095 5f */ "\\textunderscore{}",
+/* 096 60 */ "\\textasciigrave{}",
+/* 097 61 */ "a",
+/* 098 62 */ "b",
+/* 099 63 */ "c",
+/* 100 64 */ "d",
+/* 101 65 */ "e",
+/* 102 66 */ "f",
+/* 103 67 */ "g",
+/* 104 68 */ "h",
+/* 105 69 */ "i",
+/* 106 6a */ "j",
+/* 107 6b */ "k",
+/* 108 6c */ "l",
+/* 109 6d */ "m",
+/* 110 6e */ "n",
+/* 111 6f */ "o",
+/* 112 70 */ "p",
+/* 113 71 */ "q",
+/* 114 72 */ "r",
+/* 115 73 */ "s",
+/* 116 74 */ "t",
+/* 117 75 */ "u",
+/* 118 76 */ "v",
+/* 119 77 */ "w",
+/* 120 78 */ "x",
+/* 121 79 */ "y",
+/* 122 7a */ "z",
+/* 123 7b */ "\\textbraceleft{}",
+/* 124 7c */ "\\textbar{}",
+/* 125 7d */ "\\textbraceright{}",
+/* 126 7e */ "\\textasciitilde{}",
+/* 127 7f */ "",
+/* 128 80 */ "",
+/* 129 81 */ "",
+/* 130 82 */ "",
+/* 131 83 */ "",
+/* 132 84 */ "",
+/* 133 85 */ "",
+/* 134 86 */ "",
+/* 135 87 */ "",
+/* 136 88 */ "",
+/* 137 89 */ "",
+/* 138 8a */ "",
+/* 139 8b */ "",
+/* 140 8c */ "",
+/* 141 8d */ "",
+/* 142 8e */ "",
+/* 143 8f */ "",
+/* 144 90 */ "",
+/* 145 91 */ "",
+/* 146 92 */ "",
+/* 147 93 */ "",
+/* 148 94 */ "",
+/* 149 95 */ "",
+/* 150 96 */ "",
+/* 151 97 */ "",
+/* 152 98 */ "",
+/* 153 99 */ "",
+/* 154 9a */ "",
+/* 155 9b */ "",
+/* 156 9c */ "",
+/* 157 9d */ "",
+/* 158 9e */ "",
+/* 159 9f */ "",
+/* 160 a0 */ "",
+/* 161 a1 */ "\\textexclamdown{}",
+/* 162 a2 */ "\\textcentoldstyle{}",
+/* 163 a3 */ "\\textstirling{}",
+/* 164 a4 */ "\\textcurrency{}",
+/* 165 a5 */ "\\textyen{}",
+/* 166 a6 */ "\\textbrokenbar{}",
+/* 167 a7 */ "\\textsection{}",
+/* 168 a8 */ "\\textasciidieresis{}",
+/* 169 a9 */ "\\textcopyright{}",
+/* 170 aa */ "\\textordfeminine{}",
+/* 171 ab */ "\\quillemotleft{}",
+/* 172 ac */ "\\textlnot{}",
+/* 173 ad */ "",
+/* 174 ae */ "\\textregistered{}",
+/* 175 af */ "\\textasciimacron{}",
+/* 176 b0 */ "\\textdegree{}",
+/* 177 b1 */ "\\textpm{}",
+/* 178 b2 */ "\\texttwosuperior{}",
+/* 179 b3 */ "\\textthreesuperior{}",
+/* 180 b4 */ "\\textasciiacute{}",
+/* 181 b5 */ "\\textmu{}",
+/* 182 b6 */ "\\P{}",
+/* 183 b7 */ "\\textperiodcentered{}",
+/* 184 b8 */ "\\c{}",
+/* 185 b9 */ "\\textonesuperior{}",
+/* 186 ba */ "\\textordmasculine{}",
+/* 187 bb */ "\\quillemotright{}",
+/* 188 bc */ "\\textonequarter{}",
+/* 189 bd */ "\\textonehalf{}",
+/* 190 be */ "\\textthreequarters{}",
+/* 191 bf */ "?`",
+/* 192 c0 */ "\\`{A}",
+/* 193 c1 */ "\\'{A}",
+/* 194 c2 */ "\\^{A}",
+/* 195 c3 */ "\\~{A}",
+/* 196 c4 */ "\\\"{A}",
+/* 197 c5 */ "\\AA{}",
+/* 198 c6 */ "\\AE{}",
+/* 199 c7 */ "\\c{C}",
+/* 200 c8 */ "\\`{E}",
+/* 201 c9 */ "\\'{E}",
+/* 202 ca */ "\\^{E}",
+/* 203 cb */ "\\\"{E}",
+/* 204 cc */ "\\`{I}",
+/* 205 cd */ "\\'{I}",
+/* 206 ce */ "\\^{I}",
+/* 207 cf */ "\\\"{I}",
+/* 208 d0 */ "\\DH{}",
+/* 209 d1 */ "\\~{N}",
+/* 210 d2 */ "\\`{O}",
+/* 211 d3 */ "\\'{O}",
+/* 212 d4 */ "\\^{O}",
+/* 213 d5 */ "\\~{O}",
+/* 214 d6 */ "\\\"{O}",
+/* 215 d7 */ "\\texttimes{}",
+/* 216 d8 */ "\\O{}",
+/* 217 d9 */ "\\`{U}",
+/* 218 da */ "\\'{U}",
+/* 219 db */ "\\^{U}",
+/* 220 dc */ "\\\"{U}",
+/* 221 dd */ "\\'{Y}",
+/* 222 de */ "\\TH{}",
+/* 223 df */ "\\ss{}",
+/* 224 e0 */ "\\`{a}",
+/* 225 e1 */ "\\'{a}",
+/* 226 e2 */ "\\^{a}",
+/* 227 e3 */ "\\~{a}",
+/* 228 e4 */ "\\\"{a}",
+/* 229 e5 */ "\\aa{}",
+/* 230 e6 */ "\\ae{}",
+/* 231 e7 */ "\\c{c}",
+/* 232 e8 */ "\\`{e}",
+/* 233 e9 */ "\\'{e}",
+/* 234 ea */ "\\^{e}",
+/* 235 eb */ "\\\"{e}",
+/* 236 ec */ "\\`{i}",
+/* 237 ed */ "\\'{i}",
+/* 238 ee */ "\\^{i}",
+/* 239 ef */ "\\\"{i}",
+/* 240 f0 */ "\\dh{}",
+/* 241 f1 */ "\\~{n}",
+/* 242 f2 */ "\\`{o}",
+/* 243 f3 */ "\\'{o}",
+/* 244 f4 */ "\\^{o}",
+/* 245 f5 */ "\\~{o}",
+/* 246 f6 */ "\\\"{o}",
+/* 247 f7 */ "\\textdiv{}",
+/* 248 f8 */ "\\o{}",
+/* 249 f9 */ "\\`{u}",
+/* 250 fa */ "\\'{u}",
+/* 251 fb */ "\\^{u}",
+/* 252 fc */ "\\\"{u}",
+/* 253 fd */ "\\'{y}",
+/* 254 fe */ "\\th{}",
+/* 255 ff */ "\\\"{y}"
+};
+
+
+
+char const *
+f2ll2l_get_encoding(char c)
+{
+ char const * back = NULL;
+ size_t s; /* c converted to an index. */
+ unsigned char uc; /* c converted to unsigned char. */
+
+ uc = (unsigned char)c;
+ s = (size_t)uc;
+ s &= 0x00FF;
+ back = f2ll2l_encodings[s];
+ return back;
+}
+
+
+
+void
+f2ll2l_write_string(FILE *fipo, char const *str)
+{
+ char const *ptr; /* Current character to process. */
+ char const *xptr; /* Encoding for current character. */
+ char c; /* Current character to process. */
+
+ if((fipo) && (str)) {
+ ptr = str;
+ while(*ptr) {
+ c = *(ptr++);
+ xptr = f2ll2l_get_encoding(c);
+ if(xptr) {
+ fputs(xptr, fipo);
+ } else {
+ fputc(c, fipo);
+ }
+ }
+ }
+}
+
+
diff --git a/support/dktools/f2ll2l.ctr b/support/dktools/f2ll2l.ctr
new file mode 100644
index 0000000000..890e04f262
--- /dev/null
+++ b/support/dktools/f2ll2l.ctr
@@ -0,0 +1,345 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve encoding for one character.
+ @param c Character to retrieve encoding for.
+ @return LaTeX encoding for character or NULL.
+*/
+char const *
+f2ll2l_get_encoding(char c);
+
+/** Write ISO-LATIN-1 encoded string to LaTeX source,
+ recode characters if necessary.
+ @param fipo Output file.
+ @param str String to write.
+*/
+void
+f2ll2l_write_string(FILE *fipo, char const *str);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+
+#include "dk3all.h"
+
+
+
+$!trace-include
+
+
+
+/** Encodings for 0x00-0xFF.
+*/
+static char const * const f2ll2l_encodings[] = {
+/* 000 00 */ "",
+/* 001 01 */ "",
+/* 002 02 */ "",
+/* 003 03 */ "",
+/* 004 04 */ "",
+/* 005 05 */ "",
+/* 006 06 */ "",
+/* 007 07 */ "",
+/* 008 08 */ "",
+/* 009 09 */ "\t",
+/* 010 0a */ "\\\\*",
+/* 011 0b */ "",
+/* 012 0c */ "",
+/* 013 0d */ "",
+/* 014 0e */ "",
+/* 015 0f */ "",
+/* 016 10 */ "",
+/* 017 11 */ "",
+/* 018 12 */ "",
+/* 019 13 */ "",
+/* 020 14 */ "",
+/* 021 15 */ "",
+/* 022 16 */ "",
+/* 023 17 */ "",
+/* 024 18 */ "",
+/* 025 19 */ "",
+/* 026 1a */ "",
+/* 027 1b */ "",
+/* 028 1c */ "",
+/* 029 1d */ "",
+/* 030 1e */ "",
+/* 031 1f */ "",
+/* 032 20 */ " ",
+/* 033 21 */ "!",
+/* 034 22 */ "\\textquotedbl{}",
+/* 035 23 */ "\\#",
+/* 036 24 */ "\\textdollar{}",
+/* 037 25 */ "\\%",
+/* 038 26 */ "\\&",
+/* 039 27 */ "\\textquoteright{}",
+/* 040 28 */ "(",
+/* 041 29 */ ")",
+/* 042 2a */ "\\textasteriskcentered{}",
+/* 043 2b */ "+",
+/* 044 2c */ ",",
+/* 045 2d */ "-",
+/* 046 2e */ ".",
+/* 047 2f */ "/",
+/* 048 30 */ "0",
+/* 049 31 */ "1",
+/* 050 32 */ "2",
+/* 051 33 */ "3",
+/* 052 34 */ "4",
+/* 053 35 */ "5",
+/* 054 36 */ "6",
+/* 055 37 */ "7",
+/* 056 38 */ "8",
+/* 057 39 */ "9",
+/* 058 3a */ ":",
+/* 059 3b */ ";",
+/* 060 3c */ "\\textless{}",
+/* 061 3d */ "=",
+/* 062 3e */ "\\textgreater{}",
+/* 063 3f */ "?",
+/* 064 40 */ "@",
+/* 065 41 */ "A",
+/* 066 42 */ "B",
+/* 067 43 */ "C",
+/* 068 44 */ "D",
+/* 069 45 */ "E",
+/* 070 46 */ "F",
+/* 071 47 */ "G",
+/* 072 48 */ "H",
+/* 073 49 */ "I",
+/* 074 4a */ "J",
+/* 075 4b */ "K",
+/* 076 4c */ "L",
+/* 077 4d */ "M",
+/* 078 4e */ "N",
+/* 079 4f */ "O",
+/* 080 50 */ "P",
+/* 081 51 */ "Q",
+/* 082 52 */ "R",
+/* 083 53 */ "S",
+/* 084 54 */ "T",
+/* 085 55 */ "U",
+/* 086 56 */ "V",
+/* 087 57 */ "W",
+/* 088 58 */ "X",
+/* 089 59 */ "Y",
+/* 090 5a */ "Z",
+/* 091 5b */ "[",
+/* 092 5c */ "\\textbackslash{}",
+/* 093 5d */ "]",
+/* 094 5e */ "\\textasciicircum{}",
+/* 095 5f */ "\\textunderscore{}",
+/* 096 60 */ "\\textasciigrave{}",
+/* 097 61 */ "a",
+/* 098 62 */ "b",
+/* 099 63 */ "c",
+/* 100 64 */ "d",
+/* 101 65 */ "e",
+/* 102 66 */ "f",
+/* 103 67 */ "g",
+/* 104 68 */ "h",
+/* 105 69 */ "i",
+/* 106 6a */ "j",
+/* 107 6b */ "k",
+/* 108 6c */ "l",
+/* 109 6d */ "m",
+/* 110 6e */ "n",
+/* 111 6f */ "o",
+/* 112 70 */ "p",
+/* 113 71 */ "q",
+/* 114 72 */ "r",
+/* 115 73 */ "s",
+/* 116 74 */ "t",
+/* 117 75 */ "u",
+/* 118 76 */ "v",
+/* 119 77 */ "w",
+/* 120 78 */ "x",
+/* 121 79 */ "y",
+/* 122 7a */ "z",
+/* 123 7b */ "\\textbraceleft{}",
+/* 124 7c */ "\\textbar{}",
+/* 125 7d */ "\\textbraceright{}",
+/* 126 7e */ "\\textasciitilde{}",
+/* 127 7f */ "",
+/* 128 80 */ "",
+/* 129 81 */ "",
+/* 130 82 */ "",
+/* 131 83 */ "",
+/* 132 84 */ "",
+/* 133 85 */ "",
+/* 134 86 */ "",
+/* 135 87 */ "",
+/* 136 88 */ "",
+/* 137 89 */ "",
+/* 138 8a */ "",
+/* 139 8b */ "",
+/* 140 8c */ "",
+/* 141 8d */ "",
+/* 142 8e */ "",
+/* 143 8f */ "",
+/* 144 90 */ "",
+/* 145 91 */ "",
+/* 146 92 */ "",
+/* 147 93 */ "",
+/* 148 94 */ "",
+/* 149 95 */ "",
+/* 150 96 */ "",
+/* 151 97 */ "",
+/* 152 98 */ "",
+/* 153 99 */ "",
+/* 154 9a */ "",
+/* 155 9b */ "",
+/* 156 9c */ "",
+/* 157 9d */ "",
+/* 158 9e */ "",
+/* 159 9f */ "",
+/* 160 a0 */ "",
+/* 161 a1 */ "\\textexclamdown{}",
+/* 162 a2 */ "\\textcentoldstyle{}",
+/* 163 a3 */ "\\textstirling{}",
+/* 164 a4 */ "\\textcurrency{}",
+/* 165 a5 */ "\\textyen{}",
+/* 166 a6 */ "\\textbrokenbar{}",
+/* 167 a7 */ "\\textsection{}",
+/* 168 a8 */ "\\textasciidieresis{}",
+/* 169 a9 */ "\\textcopyright{}",
+/* 170 aa */ "\\textordfeminine{}",
+/* 171 ab */ "\\quillemotleft{}",
+/* 172 ac */ "\\textlnot{}",
+/* 173 ad */ "",
+/* 174 ae */ "\\textregistered{}",
+/* 175 af */ "\\textasciimacron{}",
+/* 176 b0 */ "\\textdegree{}",
+/* 177 b1 */ "\\textpm{}",
+/* 178 b2 */ "\\texttwosuperior{}",
+/* 179 b3 */ "\\textthreesuperior{}",
+/* 180 b4 */ "\\textasciiacute{}",
+/* 181 b5 */ "\\textmu{}",
+/* 182 b6 */ "\\P{}",
+/* 183 b7 */ "\\textperiodcentered{}",
+/* 184 b8 */ "\\c{}",
+/* 185 b9 */ "\\textonesuperior{}",
+/* 186 ba */ "\\textordmasculine{}",
+/* 187 bb */ "\\quillemotright{}",
+/* 188 bc */ "\\textonequarter{}",
+/* 189 bd */ "\\textonehalf{}",
+/* 190 be */ "\\textthreequarters{}",
+/* 191 bf */ "?`",
+/* 192 c0 */ "\\`{A}",
+/* 193 c1 */ "\\'{A}",
+/* 194 c2 */ "\\^{A}",
+/* 195 c3 */ "\\~{A}",
+/* 196 c4 */ "\\\"{A}",
+/* 197 c5 */ "\\AA{}",
+/* 198 c6 */ "\\AE{}",
+/* 199 c7 */ "\\c{C}",
+/* 200 c8 */ "\\`{E}",
+/* 201 c9 */ "\\'{E}",
+/* 202 ca */ "\\^{E}",
+/* 203 cb */ "\\\"{E}",
+/* 204 cc */ "\\`{I}",
+/* 205 cd */ "\\'{I}",
+/* 206 ce */ "\\^{I}",
+/* 207 cf */ "\\\"{I}",
+/* 208 d0 */ "\\DH{}",
+/* 209 d1 */ "\\~{N}",
+/* 210 d2 */ "\\`{O}",
+/* 211 d3 */ "\\'{O}",
+/* 212 d4 */ "\\^{O}",
+/* 213 d5 */ "\\~{O}",
+/* 214 d6 */ "\\\"{O}",
+/* 215 d7 */ "\\texttimes{}",
+/* 216 d8 */ "\\O{}",
+/* 217 d9 */ "\\`{U}",
+/* 218 da */ "\\'{U}",
+/* 219 db */ "\\^{U}",
+/* 220 dc */ "\\\"{U}",
+/* 221 dd */ "\\'{Y}",
+/* 222 de */ "\\TH{}",
+/* 223 df */ "\\ss{}",
+/* 224 e0 */ "\\`{a}",
+/* 225 e1 */ "\\'{a}",
+/* 226 e2 */ "\\^{a}",
+/* 227 e3 */ "\\~{a}",
+/* 228 e4 */ "\\\"{a}",
+/* 229 e5 */ "\\aa{}",
+/* 230 e6 */ "\\ae{}",
+/* 231 e7 */ "\\c{c}",
+/* 232 e8 */ "\\`{e}",
+/* 233 e9 */ "\\'{e}",
+/* 234 ea */ "\\^{e}",
+/* 235 eb */ "\\\"{e}",
+/* 236 ec */ "\\`{i}",
+/* 237 ed */ "\\'{i}",
+/* 238 ee */ "\\^{i}",
+/* 239 ef */ "\\\"{i}",
+/* 240 f0 */ "\\dh{}",
+/* 241 f1 */ "\\~{n}",
+/* 242 f2 */ "\\`{o}",
+/* 243 f3 */ "\\'{o}",
+/* 244 f4 */ "\\^{o}",
+/* 245 f5 */ "\\~{o}",
+/* 246 f6 */ "\\\"{o}",
+/* 247 f7 */ "\\textdiv{}",
+/* 248 f8 */ "\\o{}",
+/* 249 f9 */ "\\`{u}",
+/* 250 fa */ "\\'{u}",
+/* 251 fb */ "\\^{u}",
+/* 252 fc */ "\\\"{u}",
+/* 253 fd */ "\\'{y}",
+/* 254 fe */ "\\th{}",
+/* 255 ff */ "\\\"{y}"
+};
+
+
+
+char const *
+f2ll2l_get_encoding(char c)
+{
+ char const * back = NULL;
+ size_t s; /* c converted to an index. */
+ unsigned char uc; /* c converted to unsigned char. */
+
+ uc = (unsigned char)c;
+ s = (size_t)uc;
+ s &= 0x00FF;
+ back = f2ll2l_encodings[s];
+ return back;
+}
+
+
+
+void
+f2ll2l_write_string(FILE *fipo, char const *str)
+{
+ char const *ptr; /* Current character to process. */
+ char const *xptr; /* Encoding for current character. */
+ char c; /* Current character to process. */
+
+ if((fipo) && (str)) {
+ ptr = str;
+ while(*ptr) {
+ c = *(ptr++);
+ xptr = f2ll2l_get_encoding(c);
+ if(xptr) {
+ fputs(xptr, fipo);
+ } else {
+ fputc(c, fipo);
+ }
+ }
+ }
+}
+
+
diff --git a/support/dktools/f2ll2l.h b/support/dktools/f2ll2l.h
new file mode 100644
index 0000000000..cef1a155d9
--- /dev/null
+++ b/support/dktools/f2ll2l.h
@@ -0,0 +1,71 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: f2ll2l.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file f2ll2l.h Header file for the f2ll2l module.
+*/
+
+#ifndef F2LL2L_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define F2LL2L_H_INCLUDED 1
+
+
+#line 9 "f2ll2l.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve encoding for one character.
+ @param c Character to retrieve encoding for.
+ @return LaTeX encoding for character or NULL.
+*/
+char const *
+f2ll2l_get_encoding(char c);
+
+/** Write ISO-LATIN-1 encoded string to LaTeX source,
+ recode characters if necessary.
+ @param fipo Output file.
+ @param str String to write.
+*/
+void
+f2ll2l_write_string(FILE *fipo, char const *str);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/f2lopt.c b/support/dktools/f2lopt.c
new file mode 100644
index 0000000000..a1c75c82fc
--- /dev/null
+++ b/support/dktools/f2lopt.c
@@ -0,0 +1,1365 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: f2lopt.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file f2lopt.c The f2lopt module.
+*/
+
+
+#line 29 "f2lopt.ctr"
+
+#include "fig2lat.h"
+
+
+
+
+
+#line 35 "f2lopt.ctr"
+
+
+
+/** Options for the fig2lat program.
+*/
+static dk3_option_t const f2lopt_options[] = {
+ { dkT('h'), dkT("help"), 0 },
+ { dkT('v'), dkT("version"), 0 },
+ { dkT('L'), dkT("license-terms"), 0 },
+ { dkT('l'), dkT("language"), 1 },
+ { dkT('m'), dkT("make"), 0 }
+};
+
+/** Number of options in f2lopt_options.
+*/
+static size_t const f2lopt_sz_options =
+sizeof(f2lopt_options)/sizeof(dk3_option_t);
+
+
+
+/** Key names for key/value pairs.
+*/
+static dkChar const * f2lopt_key_names[] = {
+/* 0 */
+dkT("tf"),
+
+/* 1 */
+dkT("ts"),
+
+/* 2 */
+dkT("cosp"),
+
+/* 3 */
+dkT("coah"),
+
+/* 4 */
+dkT("xsss"),
+
+/* 5 */
+dkT("qbs"),
+
+/* 6 */
+dkT("lw"),
+
+/* 7 */
+dkT("debug"),
+
+/* 8 */
+dkT("showpage"),
+
+/* 9 */
+dkT("level"),
+
+/* 10 */
+dkT("dsc"),
+
+/* 11 */
+dkT("xfig"),
+
+/* 12 */
+dkT("jfig"),
+
+/* 13 */
+dkT("winfig"),
+
+/* 14 */
+dkT("ahas"),
+
+/* 15 */
+dkT("ahss"),
+
+/* 16 */
+dkT("ahms"),
+
+/* 17 */
+dkT("ahip"),
+
+/* 18 */
+dkT("smash"),
+
+/* 19 */
+dkT("mbox"),
+
+/* 20 */
+dkT("reset@font"),
+
+/* 21 */
+dkT("codi"),
+
+/* 22 */
+dkT("dcts"),
+
+/* 23 */
+dkT("css"),
+
+/* 24 */
+dkT("fragment"),
+
+/* 25 */
+dkT("fontbase"),
+
+/* 26 */
+dkT("group"),
+
+/* 27 */
+dkT("miterlimit"),
+
+/* 28 */
+dkT("cols"),
+
+/* 29 */
+dkT("replacementfonts"),
+
+/* 30 */
+dkT("bbts"),
+
+/* 31 */
+dkT("ste"),
+
+/* 32 */
+dkT("cofop"),
+
+/* 33 */
+dkT("xsah"),
+
+NULL
+
+
+#line 197 "f2lopt.ctr"
+};
+
+
+
+/** Values for font base choices.
+*/
+static dkChar const * const f2lopt_svg_font_bases[] = {
+/* 0 */
+dkT("none"),
+
+/* 1 */
+dkT("local"),
+
+/* 2 */
+dkT("web"),
+
+NULL
+
+
+#line 209 "f2lopt.ctr"
+};
+
+
+/** Fixed keywords used by the module, not localized.
+*/
+static dkChar const * const f2lopt_kw[] = {
+/* 0 */
+dkT("none"),
+
+/* 1 */
+dkT("lighten"),
+
+/* 2 */
+dkT("auto$matic"),
+
+NULL
+
+
+#line 229 "f2lopt.ctr"
+};
+
+
+
+/** Units for line width specification.
+*/
+static dkChar const * const f2lopt_units[] = {
+/* 0 */
+dkT("bp"),
+
+/* 1 */
+dkT("pt"),
+
+/* 2 */
+dkT("in"),
+
+/* 3 */
+dkT("mm"),
+
+/* 4 */
+dkT("cm"),
+
+NULL
+
+
+#line 243 "f2lopt.ctr"
+};
+
+
+/** Language (output driver) names.
+ The order of names must correspond the the numbers defined
+ in fig2lat.ctr, see @ref fig2latdrivers.
+*/
+static dkChar const * const f2lopt_language_names[] = {
+/* 0 */
+dkT("pgf"),
+
+/* 1 */
+dkT("tex"),
+
+/* 2 */
+dkT("tex.pdf"),
+
+/* 3 */
+dkT("eps.tex"),
+
+/* 4 */
+dkT("pdf.tex"),
+
+/* 5 */
+dkT("eps"),
+
+/* 6 */
+dkT("svg"),
+
+NULL
+
+
+#line 264 "f2lopt.ctr"
+};
+
+
+
+/** Keywords for font name decision.
+*/
+static dkChar const * f2lopt_text_font_names[] = {
+/* 0 */
+dkT("similar"),
+
+/* 1 */
+dkT("fig"),
+
+NULL
+
+
+#line 281 "f2lopt.ctr"
+};
+
+
+
+/** Set default options depending on the driver just configured.
+ @param job Job structure.
+*/
+static
+void
+f2lopt_set_default_options_for_language(f2l_job_t *job)
+{
+
+
+#line 293 "f2lopt.ctr"
+ job->ntf = 0;
+ job->nts = -1.0;
+ job->showpage = 0;
+ job->dsc = 0;
+ job->smash = 1;
+ job->mbox = 0;
+ job->resfont = 0;
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ job->ntf = 1;
+ job->showpage = 1;
+ job->dsc = 1;
+ job->smash = 0;
+ job->mbox = 0;
+ job->resfont = 0;
+ } break;
+ case FIG2LAT_DRIVER_SVG_STANDALONE:
+ {
+ job->smash = 0; job->mbox = 0; job->resfont = 0;
+ }
+ case FIG2LAT_DRIVER_TEX_FULL_PGF:
+ case FIG2LAT_DRIVER_TEX_FULL_PDF:
+ {
+ job->ntf = 1;
+ } break;
+ }
+
+
+#line 320 "f2lopt.ctr"
+}
+
+
+
+/** Set language.
+ @param job Job structure to configure.
+ @param lstr Language name without trailing options.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lopt_apply_language(f2l_job_t *job, dkChar const *lstr)
+{
+ int back = 0;
+
+
+#line 335 "f2lopt.ctr"
+ job->dr = dk3str_array_index(f2lopt_language_names, lstr, 0);
+ if(job->dr > -1) {
+ back = 1;
+ f2lopt_set_default_options_for_language(job);
+ } else {
+
+#line 340 "f2lopt.ctr"
+ /* ERROR: Unknown language ... */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 7, 8, lstr);
+ job->exval = FIG2LAT_EXIT_ERROR_SYNTAX;
+
+#line 343 "f2lopt.ctr"
+ }
+
+#line 344 "f2lopt.ctr"
+ return back;
+}
+
+
+
+/** Set text font.
+ @param job Job structure.
+ @param vptr Font specification (similar or fig).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lopt_set_text_font(f2l_job_t *job, dkChar const *vptr)
+{
+ int i; /* Decision for font handling. */
+ int back = 0;
+
+
+#line 361 "f2lopt.ctr"
+ switch((i = dk3str_array_index(f2lopt_text_font_names, vptr, 0))) {
+ case 0: case 1: {
+
+#line 363 "f2lopt.ctr"
+ job->ntf = i;
+ back = 1;
+ } break;
+ default: {
+
+#line 367 "f2lopt.ctr"
+ /* ERROR: No such text font selection! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 9, 10, vptr);
+ } break;
+ }
+
+
+#line 372 "f2lopt.ctr"
+ return back;
+}
+
+
+
+/** Set text size.
+ @param job Job structure.
+ @param vptr Text size as string (none or scale factor).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lopt_set_text_size(f2l_job_t *job, dkChar const *vptr)
+{
+ double d; /* Font size factor. */
+ int back = 0;
+
+
+#line 389 "f2lopt.ctr"
+ if(dk3str_cmp(vptr, f2lopt_kw[0]) == 0) {
+
+#line 390 "f2lopt.ctr"
+ job->nts = -1.0;
+ back = 1;
+ } else {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(vptr, dkT("%lf"), &d) == 1)
+#else
+ if (0 != dk3ma_d_from_string(&d, vptr, NULL))
+#endif
+ {
+
+#line 399 "f2lopt.ctr"
+ job->nts = d;
+ back = 1;
+ } else {
+
+#line 402 "f2lopt.ctr"
+ /* ERROR: Invalid font size specification! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 11, 12, vptr);
+ }
+ }
+
+
+#line 407 "f2lopt.ctr"
+ return back;
+}
+
+
+
+/** Read a size_t from text.
+ @param dptr Pointer to destination variable.
+ @param vptr Source text.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lopt_read_size_t(size_t *dptr, dkChar const *vptr, f2l_job_t *job)
+{
+#if VERSION_BEFORE_20140809
+ unsigned u; /* Conversion result. */
+ int back = 0;
+ if(1 == dk3sf_sscanf3(vptr, dkT("%u"), &u)) {
+ *dptr = (size_t)u;
+ back = 1;
+ if((unsigned)(*dptr) != u) {
+ back = 0;
+ /* ERROR: Range overflow */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 13, 14, vptr);
+ }
+ } else {
+ /* ERRROR: Not a number! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 141, 142, vptr);
+ }
+ return back;
+#else
+ dk3_um_t um = DK3_UM_0;
+ int back = 0;
+ int mec = 0;
+
+ if (dk3ma_um_from_string(&um, vptr, NULL)) { /* OK: Number */
+ *dptr = dk3ma_um_to_sz(um, &mec);
+ if (0 == mec) { /* OK: Converted */
+ back = 1;
+ } else { /* Overflow */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 13, 14, vptr);
+ }
+ } else { /* Not a number */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 141, 142, vptr);
+ }
+ return back;
+#endif
+}
+
+
+
+/** Read double value from string to configuration variable.
+ @param job Job structure.
+ @param dvar Pointer to destination variable.
+ @param src Source text.
+ @param min Minimum value.
+ @param max Maximum value.
+ @param tp Type (1=check minimum, 2=positive number + check max).
+ @param optnr Option index, used for error messages.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lopt_read_double(
+ f2l_job_t *job,
+ double *dvar,
+ dkChar const *src,
+ double min,
+ double max,
+ int tp,
+ size_t optnr
+)
+{
+ dkChar buf[128]; /* Conversion buffer. */
+ double dval = 0.0; /* Conversion result. */
+ int back = 0;
+ if(src) {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(src, dkT("%lg"), &dval) == 1)
+#else
+ if (0 != dk3ma_d_from_string(&dval, src, NULL))
+#endif
+ {
+ switch(tp) {
+ case 1: {
+ if(dval >= min) {
+ *dvar = dval;
+ back = 1;
+ } else {
+ /* ERROR: Minimum for option ... is ...! */
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(buf, dkT("%g"), min);
+ dk3app_log_5(
+ job->app, DK3_LL_ERROR, job->msg, 15, 16, 17, src, buf
+ );
+#else
+ if (0 != dk3ma_d_to_string(buf, DK3_SIZEOF(buf,dkChar), min)) {
+ dk3app_log_5(
+ job->app, DK3_LL_ERROR, job->msg, 15, 16, 17, src, buf
+ );
+ }
+#endif
+ }
+ } break;
+ case 2: {
+ if(dval > 0) {
+ if(dval < max) {
+ *dvar = dval;
+ back = 1;
+ } else {
+ /* ERROR: Maximum for option ... is ...! */
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(buf, dkT("%g"), max);
+ dk3app_log_5(job->app,DK3_LL_ERROR,job->msg,15,18,17,src,buf);
+#else
+ if (0 != dk3ma_d_to_string(buf, DK3_SIZEOF(buf,dkChar), max)) {
+ dk3app_log_5(job->app,DK3_LL_ERROR,job->msg,15,18,17,src,buf);
+ }
+#endif
+ }
+ } else {
+ /* ERROR: Option ... requires positive value! */
+ dk3app_log_3(
+ job->app, DK3_LL_ERROR, job->msg, 19, 20,
+ f2lopt_key_names[optnr]
+ );
+ }
+ } break;
+ }
+ } else {
+ /* ERROR: Option argument is not numeric! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 141, 142, src);
+ }
+ } else {
+ /* ERROR: Option requires an argument. */
+ dk3app_log_3(
+ job->app, DK3_LL_ERROR, job->msg, 21, 22,
+ f2lopt_key_names[optnr]
+ );
+ }
+ return back;
+}
+
+
+/** Process one option.
+ @param job Job structure to configure.
+ @param str Key=value text.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lopt_apply_option(f2l_job_t *job, dkChar const *str)
+{
+ dkChar bu[1024]; /* Private copy of str. */
+ dkChar *kptr; /* Key pointer. */
+ dkChar *vptr; /* Value pointer. */
+ int back = 0;
+
+
+#line 566 "f2lopt.ctr"
+ if(dk3str_len(str) < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy_not_overlapped(bu, str);
+ kptr = dk3str_start(bu, NULL);
+ if(kptr) {
+ vptr = dk3str_chr(kptr, dkT('='));
+ if(vptr) {
+ *(vptr++) = dkT('\0');
+ vptr = dk3str_start(vptr, NULL);
+ }
+ switch(dk3str_array_index(f2lopt_key_names, kptr, 0)) {
+ case 0: {
+
+#line 577 "f2lopt.ctr"
+ if(vptr) {
+ back = f2lopt_set_text_font(job, vptr);
+ } else {
+ /* ERRROR: Key needs an argument! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 21, 22, kptr);
+ }
+ } break;
+ case 1: {
+
+#line 585 "f2lopt.ctr"
+ if(vptr) {
+ back = f2lopt_set_text_size(job, vptr);
+ } else {
+ job->nts = -1.0;
+ back = 1;
+ }
+ } break;
+ case 2: {
+
+#line 593 "f2lopt.ctr"
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ job->cosp = (dk3str_is_on(vptr) ? 1 : 0);
+ back = 1;
+ } else {
+ /* ERROR: Not a boolean */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
+ }
+ } else {
+ job->cosp = 1; back = 1;
+ }
+ } break;
+ case 3: {
+
+#line 606 "f2lopt.ctr"
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ job->coah = (dk3str_is_on(vptr) ? 1 : 0);
+ back = 1;
+ } else {
+ /* ERROR: Not a boolean */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
+ }
+ } else {
+ job->coah = 1; back = 1;
+ }
+ } break;
+ case 4: {
+
+#line 619 "f2lopt.ctr"
+ if(vptr) {
+ back = f2lopt_read_size_t(&(job->xssbs), vptr, job);
+ } else {
+ /* ERROR: Argument required! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 133, 134, kptr);
+ }
+ } break;
+ case 5: {
+
+#line 627 "f2lopt.ctr"
+ if(vptr) {
+ back = f2lopt_read_size_t(&(job->qbs), vptr, job);
+ } else {
+ /* ERROR: Argument required! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 133, 134, kptr);
+ }
+ } break;
+ case 6: {
+#if VERSION_BEFORE_20140330
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ job->lighten = ((dk3str_is_on(vptr)) ? 1 : 0);
+ back = 1;
+ } else {
+ /* ERROR: Not a boolean value! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
+ }
+ } else {
+ back = 1;
+ job->lighten = 1;
+ }
+#else
+ job->lwbp = 0.9;
+ job->lwauto = 0;
+ if (vptr) {
+ double x;
+ size_t vplen;
+ vplen = dk3str_len(vptr);
+ if (0 == dk3str_cmp(f2lopt_kw[1], vptr)) {
+ job->lwbp = 0.45;
+ job->lwauto = 0;
+ back = 1;
+ } else {
+ if (dk3str_is_abbr(vptr,f2lopt_kw[2],dkT('$'), 0)) {
+ job->lwauto = 1;
+ back = 1;
+ } else {
+ if (2 < vplen) {
+ switch (dk3str_array_index(f2lopt_units, &(vptr[vplen-2]), 0))
+ {
+ case 0: { /* bp */
+ vptr[vplen - 2] = dkT('\0');
+#if VERSION_BEFORE_20140716
+ if (dk3sf_sscanf3(vptr, dkT("%lg"), &x) == 1)
+#else
+ if (0 != dk3ma_d_from_string(&x, vptr, NULL))
+#endif
+ {
+ job->lwbp = x;
+ back = 1;
+ } else {
+ /* ERROR: Failed to process */
+ dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,45,46,vptr);
+ }
+ } break;
+ case 1: { /* pt */
+ vptr[vplen - 2] = dkT('\0');
+#if VERSION_BEFORE_20140716
+ if (dk3sf_sscanf3(vptr, dkT("%lg"), &x) == 1)
+#else
+ if (0 != dk3ma_d_from_string(&x, vptr, NULL))
+#endif
+ {
+ job->lwbp = x * 72.0 / 72.27;
+ back = 1;
+ } else {
+ /* ERROR: Failed to process */
+ dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,45,46,vptr);
+ }
+ } break;
+ case 2: { /* in */
+ vptr[vplen - 2] = dkT('\0');
+#if VERSION_BEFORE_20140716
+ if (dk3sf_sscanf3(vptr, dkT("%lg"), &x) == 1)
+#else
+ if (0 != dk3ma_d_from_string(&x, vptr, NULL))
+#endif
+ {
+ job->lwbp = x * 72.0;
+ back = 1;
+ } else {
+ /* ERROR: Failed to process */
+ dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,45,46,vptr);
+ }
+ } break;
+ case 3: { /* mm */
+ vptr[vplen - 2] = dkT('\0');
+#if VERSION_BEFORE_20140716
+ if (dk3sf_sscanf3(vptr, dkT("%lg"), &x) == 1)
+#else
+ if (0 != dk3ma_d_from_string(&x, vptr, NULL))
+#endif
+ {
+ job->lwbp = x * 72.0 / 25.4;
+ back = 1;
+ } else {
+ /* ERROR: Failed to process */
+ dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,45,46,vptr);
+ }
+ } break;
+ case 4: { /* cm */
+ vptr[vplen - 2] = dkT('\0');
+#if VERSION_BEFORE_20140716
+ if (dk3sf_sscanf3(vptr, dkT("%lg"), &x) == 1)
+#else
+ if (0 != dk3ma_d_from_string(&x, vptr, NULL))
+#endif
+ {
+ job->lwbp = x * 72.0 / 2.54;
+ back = 1;
+ } else {
+ /* ERROR: Failed to process */
+ dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,45,46,vptr);
+ }
+ } break;
+ default: {
+#if VERSION_BEFORE_20140716
+ if (dk3sf_sscanf3(vptr, dkT("%lg"), &x) == 1)
+#else
+ if (0 != dk3ma_d_from_string(&x, vptr, NULL))
+#endif
+ {
+ job->lwbp = x;
+ back = 1;
+ } else {
+ /* ERROR: Failed to process */
+ dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,45,46,vptr);
+ }
+ } break;
+ }
+ } else {
+#if VERSION_BEFORE_20140716
+ if (dk3sf_sscanf3(vptr, dkT("%lg"), &x) == 1)
+#else
+ if (0 != dk3ma_d_from_string(&x, vptr, NULL))
+#endif
+ {
+ job->lwbp = x;
+ back = 1;
+ } else {
+ /* ERROR: Failed to process */
+ dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,45,46,vptr);
+ }
+ }
+ }
+ }
+ } else {
+ job->lwbp = 0.9;
+ job->lwauto = 1;
+ back = 1;
+ if (job->lwbp < 0.001) {
+ job->lwbp = 0.001;
+ }
+ }
+
+#line 781 "f2lopt.ctr"
+#endif
+ } break;
+ case 7: {
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ back = 1;
+ job->debug = ((dk3str_is_on(vptr)) ? 1 : 0);
+ } else {
+ /* ERROR: Not a boolean value! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
+ }
+ } else {
+ back = 1;
+ job->debug = 1;
+ }
+ } break;
+ case 8: {
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ job->showpage = ((dk3str_is_on(vptr)) ? 1 : 0);
+ back = 1;
+ } else {
+ /* ERROR: Not a boolean value! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
+ }
+ } else {
+ job->showpage = 1;
+ back = 1;
+ }
+ } break;
+ case 9: {
+ if(vptr) {
+ int i;
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(vptr, dkT("%d"), &i) == 1)
+#else
+ if (0 != dk3ma_i_from_string(&i, vptr, NULL))
+#endif
+ {
+ if((i >= 2) && (i <= 3)) {
+ job->pslevel = i;
+ } else {
+ /* ERROR: Must be 2 or 3! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 33);
+ }
+ } else {
+ /* ERROR: Argument not a number! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 141, 142, vptr);
+ }
+ } else {
+ /* ERROR: Argument required! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 133, 134, kptr);
+ }
+ } break;
+ case 10: {
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ job->dsc = ((dk3str_is_on(vptr)) ? 1 : 0);
+ back = 1;
+ } else {
+ /* ERROR: Not a boolean argument. */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
+ }
+ } else {
+ job->dsc = 1;
+ back = 1;
+ }
+ } break;
+ case 11: {
+ if(DK3_FIG_SRCTYPE_UNKNOWN == job->srctype) {
+ job->srctype = DK3_FIG_SRCTYPE_XFIG;
+ back = 1;
+ } else {
+ /* ERROR: Source type already set! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 23);
+ }
+ } break;
+ case 12: {
+ if(DK3_FIG_SRCTYPE_UNKNOWN == job->srctype) {
+ job->srctype = DK3_FIG_SRCTYPE_JFIG;
+ back = 1;
+ } else {
+ /* ERROR: Source type already set! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 23);
+ }
+ } break;
+ case 13: {
+ if(DK3_FIG_SRCTYPE_UNKNOWN == job->srctype) {
+ job->srctype = DK3_FIG_SRCTYPE_WINFIG;
+ back = 1;
+ } else {
+ /* ERROR: Source type already set! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 23);
+ }
+ } break;
+ case 14: { /* Arrowhead arc segments */
+ back = f2lopt_read_double(job,&(job->arcspp),vptr,2.0,-1.0,1,14);
+ } break;
+ case 15: { /* Arrowhead spline segments */
+ back = f2lopt_read_double(job,&(job->splspp),vptr,2.0,-1.0,1,15);
+ } break;
+ case 16: { /* Arrowhead min segments. */
+ unsigned u = 2;
+ if(vptr) {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(vptr, dkT("%u"), &u) == 1)
+#else
+ if (0 != dk3ma_ui_from_string(&u, vptr, NULL))
+#endif
+ {
+ if(2 <= u) {
+ job->minspp = (size_t)u;
+ back = 1;
+ } else {
+ /* Warning: Must be at least 2! */
+ job->minspp = 2;
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 34);
+ back = 1;
+ }
+ } else {
+ /* ERROR: Argument is not numeric */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 141, 142, vptr);
+ }
+ } else {
+ /* ERROR: Option requires an argument! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 133, 134, kptr);
+ }
+ } break;
+ case 17: { /* Arrowhead interpolation precision. */
+ back = f2lopt_read_double(job,&(job->xsprec),vptr,0.0,0.1,2,17);
+ } break;
+ case 18: { /* smash */
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ job->smash = ((dk3str_is_on(vptr)) ? 1 : 0);
+ back = 1;
+ } else {
+ /* ERROR: Option requires boolean argument */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
+ }
+ } else {
+ job->smash = 1;
+ back = 1;
+ }
+ } break;
+ case 19: { /* mbox */
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ job->mbox = ((dk3str_is_on(vptr)) ? 1 : 0);
+ back = 1;
+ } else {
+ /* ERROR: Option requires boolean argument! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
+ }
+ } else {
+ job->mbox = 1;
+ back = 1;
+ }
+ } break;
+ case 20: {
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ job->resfont = ((dk3str_is_on(vptr)) ? 1 : 0);
+ back = 1;
+ } else {
+ /* ERROR: Option requires boolean argument! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
+ }
+ } else {
+ job->resfont = 1;
+ back = 1;
+ }
+ } break;
+ case 21: {
+ if(vptr) {
+ unsigned u;
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(vptr, dkT("%u"), &u) == 1)
+#else
+ if (0 != dk3ma_ui_from_string(&u, vptr, NULL))
+#endif
+ {
+ job->codi = (size_t)u;
+ back = 1;
+ } else {
+ /* ERROR: Option requires an unsigned numeric argument! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 24, 25, kptr);
+ }
+ } else {
+ job->codi = 0;
+ back = 1;
+ }
+ } break;
+ case 22: {
+ if(vptr) {
+ double d;
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(vptr, dkT("%lg"), &d) == 1)
+#else
+ if (0 != dk3ma_d_from_string(&d, vptr, NULL))
+#endif
+ {
+ if(d > 0.0) {
+ job->tts = d; back = 1;
+ } else {
+ /* ERROR: Cannot handle negative font size! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 26);
+ }
+ } else {
+ /* ERROR: Option requires a floating point number arg! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 12, 22, kptr);
+ }
+ } else {
+ job->tts = 12.0; back = 1;
+ }
+ } break;
+ case 23: {
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ job->css = ((dk3str_is_on(vptr)) ? 1 : 0); back = 1;
+ } else {
+ /* ERROR: Option requires boolean argument! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
+ }
+ } else {
+ job->css = 1; back = 1;
+ }
+ } break;
+ case 24: {
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ job->fragment = ((dk3str_is_on(vptr)) ? 1 : 0); back = 1;
+ } else {
+ /* ERROR: Option requires boolean argument! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
+ }
+ } else {
+ job->fragment = 1; back = 1;
+ }
+ } break;
+ case 25: {
+ if(vptr) {
+ job->svgfontbase = dk3str_array_index(f2lopt_svg_font_bases, vptr, 0);
+ if(0 <= job->svgfontbase) {
+ back = 1;
+ } else {
+ /* ##### ERROR: Illegal font base name! */
+ }
+ } else {
+ job->svgfontbase = 0; back = 1;
+ }
+ } break;
+ case 26: {
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ job->group = ((dk3str_is_on(vptr)) ? 1 : 0); back = 1;
+ } else {
+ /* ERROR: Option requires boolean argument! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
+ }
+ } else {
+ job->group = 1; back = 1;
+ }
+ } break;
+ case 27: {
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ job->miterlim = ((dk3str_is_on(vptr)) ? 1 : 0); back = 1;
+ } else {
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
+ }
+ } else {
+ job->miterlim = 1; back = 1;
+ }
+ } break;
+ case 28: {
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ job->cols = ((dk3str_is_on(vptr)) ? 1 : 0); back = 1;
+ } else {
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
+ }
+ } else {
+ job->cols = 1; back = 1;
+ }
+ } break;
+ case 29: {
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ job->otherfonts = ((dk3str_is_on(vptr)) ? 1 : 0); back = 1;
+ } else {
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
+ }
+ } else {
+ job->otherfonts = 1; back = 1;
+ }
+ } break;
+ case 30: {
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ job->bbts = ((dk3str_is_on(vptr)) ? 1 : 0); back = 1;
+ } else {
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
+ }
+ } else {
+ job->bbts = 1; back = 1;
+ }
+ } break;
+ case 31: {
+ int enc;
+ if(vptr) {
+ enc = dk3enc_get_text_encoding_app(vptr, job->app);
+ } else {
+ if(DK3_ENCODING_UTF8 == dk3app_get_encoding(job->app)) {
+ enc = DK3_ENCODING_PLAIN;
+ } else {
+ enc = DK3_ENCODING_UTF8;
+ }
+ }
+ back = 1;
+ switch(enc) {
+ case DK3_ENCODING_UTF8: {
+ job->stu8 = 1;
+ } break;
+ case DK3_ENCODING_PLAIN: {
+ job->stu8 = 0;
+ } break;
+ default: {
+ job->stu8 = 0;
+ /* ##### WARNING Only ascii and utf-8 allowed. */
+ } break;
+ }
+ } break;
+ case 32: {
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ job->cofop = ((dk3str_is_on(vptr)) ? 1 : 0);
+ back = 1;
+ } else {
+ /* ERROR: Not a boolean! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
+ }
+ } else {
+ job->cofop = 1;
+ back = 1;
+ }
+ } break;
+ case 33: {
+ if (vptr) {
+ if(dk3str_is_bool(vptr)) {
+ job->xsah = ((dk3str_is_on(vptr)) ? 1 : 0);
+ back = 1;
+ } else {
+ /* ERROR: Not a boolean! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
+ }
+ } else {
+ job->xsah = 1;
+ back = 1;
+ }
+ } break;
+ default: {
+ /* ERROR: Unknown key name! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 27, 28, kptr);
+ } break;
+ }
+ } else {
+
+#line 1148 "f2lopt.ctr"
+ back = 1;
+ }
+ if(!(back)) {
+ job->exval = FIG2LAT_EXIT_ERROR_SYNTAX;
+
+#line 1152 "f2lopt.ctr"
+ }
+ } else {
+ /* ERROR: Option ... too long! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 29, 30, str);
+ job->exval = FIG2LAT_EXIT_ERROR_SYNTAX;
+
+#line 1157 "f2lopt.ctr"
+ }
+
+#line 1158 "f2lopt.ctr"
+ return back;
+}
+
+
+
+/** Set language, apply options if any.
+ @param job Job structure to set up.
+ @param optarg Language, optionally with further options.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lopt_set_language(f2l_job_t *job, dkChar const *optarg)
+{
+ dkChar bu[1024]; /* Private copy of optarg. */
+ dkChar *pc; /* Current string. */
+ dkChar *pn; /* Next string. */
+ int back = 0;
+
+
+#line 1177 "f2lopt.ctr"
+ if(dk3str_len(optarg) < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy_not_overlapped(bu, optarg);
+ pc = dk3str_chr(bu, dkT(','));
+ if(pc) {
+ *(pc++) = dkT('\0');
+ pc = dk3str_start(pc, NULL);
+ }
+ if(f2lopt_apply_language(job, bu)) {
+ back = 1;
+ while(pc) {
+
+#line 1187 "f2lopt.ctr"
+ pn = dk3str_chr(pc, dkT(','));
+ if(pn) { *(pn++) = dkT('\0'); pn = dk3str_start(pn, NULL); }
+ if(!f2lopt_apply_option(job, pc)) {
+ back = 0;
+
+#line 1191 "f2lopt.ctr"
+ pn = NULL;
+ }
+ pc = pn;
+ }
+ }
+ } else {
+ /* ERROR: Option argument too long! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 31, 30, optarg);
+ }
+
+#line 1200 "f2lopt.ctr"
+ return back;
+}
+
+
+
+int
+f2lopt_process(f2l_job_t *job)
+{
+ dkChar const *optarg; /* Option argument. */
+ int back = 0;
+ int i; /* Current file name. */
+
+
+#line 1212 "f2lopt.ctr"
+ job->opt = dk3opt_open_from_app(
+ f2lopt_options, f2lopt_sz_options,
+ dkT('o'), dkT("option"),
+ job->app
+ );
+ if(job->opt) {
+
+#line 1218 "f2lopt.ctr"
+ if(0 == dk3opt_get_error_code(job->opt)) {
+
+#line 1219 "f2lopt.ctr"
+ back = 1;
+ if(dk3opt_is_set(job->opt, dkT('h'))) {
+ job->cmd |= DK3_APP_CMD_HELP;
+ }
+ if(dk3opt_is_set(job->opt, dkT('v'))) {
+ job->cmd |= DK3_APP_CMD_VERSION;
+ }
+ if(dk3opt_is_set(job->opt, dkT('L'))) {
+ job->cmd |= DK3_APP_CMD_LICENSE;
+ }
+ if(0 == job->cmd) {
+ if(dk3opt_is_set(job->opt, dkT('m'))) {
+ job->mm = 1;
+ }
+ if(dk3opt_is_set(job->opt, dkT('l'))) {
+ optarg = dk3opt_get_short_arg(job->opt, dkT('l'));
+ if(optarg) {
+
+#line 1236 "f2lopt.ctr"
+ if(f2lopt_set_language(job, optarg)) {
+ for(i = 0; i < dk3opt_get_num_fo(job->opt); i++) {
+ optarg = dk3opt_get_fo(job->opt, i);
+ if(optarg) {
+ if(!f2lopt_apply_option(job, optarg)) {
+ back = 0;
+ }
+ }
+ }
+ } else {
+ back = 0;
+ }
+ } else {
+
+#line 1249 "f2lopt.ctr"
+ back = 0;
+ /* ERROR: Option requires an argument! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 32);
+ }
+ } else {
+ }
+ }
+ /* Automatically calculate line width in points
+ from TeX text size.
+ */
+ if (job->lwauto) {
+ job->lwbp = 0.4 * 72.0 * job->tts / (10 * 72.27);
+
+
+#line 1262 "f2lopt.ctr"
+ }
+ } else {
+
+#line 1264 "f2lopt.ctr"
+ }
+ } else {
+
+#line 1266 "f2lopt.ctr"
+ job->exval = FIG2LAT_EXIT_ERROR_SYSTEM;
+
+#line 1267 "f2lopt.ctr"
+ }
+
+#line 1268 "f2lopt.ctr"
+ return back;
+}
+
+
diff --git a/support/dktools/f2lopt.ctr b/support/dktools/f2lopt.ctr
new file mode 100644
index 0000000000..f3a1c376b0
--- /dev/null
+++ b/support/dktools/f2lopt.ctr
@@ -0,0 +1,1271 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Process command line arguments.
+ @param job Job to process.
+ @return 1 on success, 0 on error.
+*/
+int
+f2lopt_process(f2l_job_t *job);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "fig2lat.h"
+
+
+
+$!trace-include
+
+
+
+/** Options for the fig2lat program.
+*/
+static dk3_option_t const f2lopt_options[] = {
+ { dkT('h'), dkT("help"), 0 },
+ { dkT('v'), dkT("version"), 0 },
+ { dkT('L'), dkT("license-terms"), 0 },
+ { dkT('l'), dkT("language"), 1 },
+ { dkT('m'), dkT("make"), 0 }
+};
+
+/** Number of options in f2lopt_options.
+*/
+static size_t const f2lopt_sz_options =
+sizeof(f2lopt_options)/sizeof(dk3_option_t);
+
+
+
+/** Key names for key/value pairs.
+*/
+static dkChar const * f2lopt_key_names[] = {
+$!string-table macro=dkT
+#
+# 0: Text font (similar or fig)
+#
+tf
+#
+# 1: Text size (none or scale factor).
+#
+ts
+#
+# 2: Compatibility for splines.
+#
+cosp
+#
+# 3: Compatibility for arrowheads.
+#
+coah
+#
+# 4: X-spline segments Bezier segments.
+#
+xsss
+#
+# 5: Quadrant Bezier segments.
+#
+qbs
+#
+# 6: Lighten look.
+#
+# lighten
+lw
+#
+# 7: Write debug information.
+#
+debug
+#
+# 8: Write showpage operator at end of EPS files.
+#
+showpage
+#
+# 9: PS level.
+#
+level
+#
+# 10: DSC comments.
+#
+dsc
+#
+# 11:
+#
+xfig
+#
+# 12:
+#
+jfig
+#
+# 13:
+#
+winfig
+#
+# 14: Arrowhead arc segments
+#
+ahas
+#
+# 15: Arrowhead spline segments
+#
+ahss
+#
+# 16: Arrowhead min segments
+#
+ahms
+#
+# 17: Arrowhead interpolation precision
+#
+ahip
+#
+# 18: Use smash in LaTeX output
+#
+smash
+#
+# 19: Use mbox in LaTeX output
+#
+mbox
+#
+# 20: Use reset@font in LaTeX output
+#
+reset@font
+#
+# 21: Number of color digits.
+#
+codi
+#
+# 22: TeX text size.
+#
+dcts
+#
+# 23: Align SVG output to grid.
+#
+css
+#
+# 24: Write SVG fragment
+#
+fragment
+#
+# 25: Where to obtain SVG fonts
+#
+fontbase
+#
+# 26: Group SVG object with its arrowheads
+#
+group
+#
+# 27: Miterlimit
+#
+miterlimit
+#
+# 28: Compatible line styles.
+#
+cols
+#
+# 29: Use replacement fonts
+#
+replacementfonts
+#
+# 30: Use text size for bounding box.
+#
+bbts
+#
+# 31: Special text encoding.
+#
+ste
+#
+# 32: Compatible fill open paths.
+#
+cofop
+#
+# 33: X-spline arrowheads.
+#
+xsah
+$!end
+};
+
+
+
+/** Values for font base choices.
+*/
+static dkChar const * const f2lopt_svg_font_bases[] = {
+$!string-table macro=dkT
+none
+local
+web
+$!end
+};
+
+
+/** Fixed keywords used by the module, not localized.
+*/
+static dkChar const * const f2lopt_kw[] = {
+$!string-table macro=dkT
+#
+# 0: none (used to specify the font size).
+#
+none
+#
+# 1: lighten
+#
+lighten
+#
+# 2: automatic
+#
+auto$matic
+$!end
+};
+
+
+
+/** Units for line width specification.
+*/
+static dkChar const * const f2lopt_units[] = {
+$!string-table macro=dkT
+bp
+pt
+in
+mm
+cm
+$!end
+};
+
+
+/** Language (output driver) names.
+ The order of names must correspond the the numbers defined
+ in fig2lat.ctr, see @ref fig2latdrivers.
+*/
+static dkChar const * const f2lopt_language_names[] = {
+$!string-table macro=dkT
+pgf
+tex
+tex.pdf
+eps.tex
+pdf.tex
+eps
+svg
+# @DRIVER@
+# Add name of new driver above this comment section
+# The order of driver names must correspond to the
+# driver names defined in fig2lat.ctr.
+$!end
+};
+
+
+
+/** Keywords for font name decision.
+*/
+static dkChar const * f2lopt_text_font_names[] = {
+$!string-table macro=dkT
+#
+# 0: similar
+#
+similar
+#
+# 1: fig
+#
+fig
+$!end
+};
+
+
+
+/** Set default options depending on the driver just configured.
+ @param job Job structure.
+*/
+static
+void
+f2lopt_set_default_options_for_language(f2l_job_t *job)
+{
+ $? "+ f2lopt_set_default_options_for_language"
+ job->ntf = 0;
+ job->nts = -1.0;
+ job->showpage = 0;
+ job->dsc = 0;
+ job->smash = 1;
+ job->mbox = 0;
+ job->resfont = 0;
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ job->ntf = 1;
+ job->showpage = 1;
+ job->dsc = 1;
+ job->smash = 0;
+ job->mbox = 0;
+ job->resfont = 0;
+ } break;
+ case FIG2LAT_DRIVER_SVG_STANDALONE:
+ {
+ job->smash = 0; job->mbox = 0; job->resfont = 0;
+ }
+ case FIG2LAT_DRIVER_TEX_FULL_PGF:
+ case FIG2LAT_DRIVER_TEX_FULL_PDF:
+ {
+ job->ntf = 1;
+ } break;
+ }
+ $? "- f2lopt_set_default_options_for_language"
+}
+
+
+
+/** Set language.
+ @param job Job structure to configure.
+ @param lstr Language name without trailing options.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lopt_apply_language(f2l_job_t *job, dkChar const *lstr)
+{
+ int back = 0;
+ $? "+ f2lopt_apply_language \"%!ds\"", TR_STR(lstr)
+ job->dr = dk3str_array_index(f2lopt_language_names, lstr, 0);
+ if(job->dr > -1) {
+ back = 1;
+ f2lopt_set_default_options_for_language(job);
+ } else { $? "! unknown language"
+ /* ERROR: Unknown language ... */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 7, 8, lstr);
+ job->exval = FIG2LAT_EXIT_ERROR_SYNTAX; $? ". exitcode"
+ } $? "- f2lopt_apply_language %d", back
+ return back;
+}
+
+
+
+/** Set text font.
+ @param job Job structure.
+ @param vptr Font specification (similar or fig).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lopt_set_text_font(f2l_job_t *job, dkChar const *vptr)
+{
+ int i; /* Decision for font handling. */
+ int back = 0;
+ $? "+ f2lopt_set_text_font \"%!ds\"", TR_STR(vptr)
+ switch((i = dk3str_array_index(f2lopt_text_font_names, vptr, 0))) {
+ case 0: case 1: { $? ". font selection = %d", i
+ job->ntf = i;
+ back = 1;
+ } break;
+ default: { $? "! wrong font selection"
+ /* ERROR: No such text font selection! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 9, 10, vptr);
+ } break;
+ }
+ $? "- f2lopt_set_text_font %d", back
+ return back;
+}
+
+
+
+/** Set text size.
+ @param job Job structure.
+ @param vptr Text size as string (none or scale factor).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lopt_set_text_size(f2l_job_t *job, dkChar const *vptr)
+{
+ double d; /* Font size factor. */
+ int back = 0;
+ $? "+ f2lopt_set_text_font \"%!ds\"", vptr
+ if(dk3str_cmp(vptr, f2lopt_kw[0]) == 0) { $? ". no size"
+ job->nts = -1.0;
+ back = 1;
+ } else {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(vptr, dkT("%lf"), &d) == 1)
+#else
+ if (0 != dk3ma_d_from_string(&d, vptr, NULL))
+#endif
+ { $? ". size %lg", d
+ job->nts = d;
+ back = 1;
+ } else { $? "! invalid size"
+ /* ERROR: Invalid font size specification! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 11, 12, vptr);
+ }
+ }
+ $? "- f2lopt_set_text_font %d", back
+ return back;
+}
+
+
+
+/** Read a size_t from text.
+ @param dptr Pointer to destination variable.
+ @param vptr Source text.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lopt_read_size_t(size_t *dptr, dkChar const *vptr, f2l_job_t *job)
+{
+#if VERSION_BEFORE_20140809
+ unsigned u; /* Conversion result. */
+ int back = 0;
+ if(1 == dk3sf_sscanf3(vptr, dkT("%u"), &u)) {
+ *dptr = (size_t)u;
+ back = 1;
+ if((unsigned)(*dptr) != u) {
+ back = 0;
+ /* ERROR: Range overflow */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 13, 14, vptr);
+ }
+ } else {
+ /* ERRROR: Not a number! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 141, 142, vptr);
+ }
+ return back;
+#else
+ dk3_um_t um = DK3_UM_0;
+ int back = 0;
+ int mec = 0;
+
+ if (dk3ma_um_from_string(&um, vptr, NULL)) { /* OK: Number */
+ *dptr = dk3ma_um_to_sz(um, &mec);
+ if (0 == mec) { /* OK: Converted */
+ back = 1;
+ } else { /* Overflow */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 13, 14, vptr);
+ }
+ } else { /* Not a number */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 141, 142, vptr);
+ }
+ return back;
+#endif
+}
+
+
+
+/** Read double value from string to configuration variable.
+ @param job Job structure.
+ @param dvar Pointer to destination variable.
+ @param src Source text.
+ @param min Minimum value.
+ @param max Maximum value.
+ @param tp Type (1=check minimum, 2=positive number + check max).
+ @param optnr Option index, used for error messages.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lopt_read_double(
+ f2l_job_t *job,
+ double *dvar,
+ dkChar const *src,
+ double min,
+ double max,
+ int tp,
+ size_t optnr
+)
+{
+ dkChar buf[128]; /* Conversion buffer. */
+ double dval = 0.0; /* Conversion result. */
+ int back = 0;
+ if(src) {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(src, dkT("%lg"), &dval) == 1)
+#else
+ if (0 != dk3ma_d_from_string(&dval, src, NULL))
+#endif
+ {
+ switch(tp) {
+ case 1: {
+ if(dval >= min) {
+ *dvar = dval;
+ back = 1;
+ } else {
+ /* ERROR: Minimum for option ... is ...! */
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(buf, dkT("%g"), min);
+ dk3app_log_5(
+ job->app, DK3_LL_ERROR, job->msg, 15, 16, 17, src, buf
+ );
+#else
+ if (0 != dk3ma_d_to_string(buf, DK3_SIZEOF(buf,dkChar), min)) {
+ dk3app_log_5(
+ job->app, DK3_LL_ERROR, job->msg, 15, 16, 17, src, buf
+ );
+ }
+#endif
+ }
+ } break;
+ case 2: {
+ if(dval > 0) {
+ if(dval < max) {
+ *dvar = dval;
+ back = 1;
+ } else {
+ /* ERROR: Maximum for option ... is ...! */
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(buf, dkT("%g"), max);
+ dk3app_log_5(job->app,DK3_LL_ERROR,job->msg,15,18,17,src,buf);
+#else
+ if (0 != dk3ma_d_to_string(buf, DK3_SIZEOF(buf,dkChar), max)) {
+ dk3app_log_5(job->app,DK3_LL_ERROR,job->msg,15,18,17,src,buf);
+ }
+#endif
+ }
+ } else {
+ /* ERROR: Option ... requires positive value! */
+ dk3app_log_3(
+ job->app, DK3_LL_ERROR, job->msg, 19, 20,
+ f2lopt_key_names[optnr]
+ );
+ }
+ } break;
+ }
+ } else {
+ /* ERROR: Option argument is not numeric! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 141, 142, src);
+ }
+ } else {
+ /* ERROR: Option requires an argument. */
+ dk3app_log_3(
+ job->app, DK3_LL_ERROR, job->msg, 21, 22,
+ f2lopt_key_names[optnr]
+ );
+ }
+ return back;
+}
+
+
+/** Process one option.
+ @param job Job structure to configure.
+ @param str Key=value text.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lopt_apply_option(f2l_job_t *job, dkChar const *str)
+{
+ dkChar bu[1024]; /* Private copy of str. */
+ dkChar *kptr; /* Key pointer. */
+ dkChar *vptr; /* Value pointer. */
+ int back = 0;
+ $? "+ f2lopt_apply_option \"%!ds\"", TR_STR(str)
+ if(dk3str_len(str) < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy_not_overlapped(bu, str);
+ kptr = dk3str_start(bu, NULL);
+ if(kptr) {
+ vptr = dk3str_chr(kptr, dkT('='));
+ if(vptr) {
+ *(vptr++) = dkT('\0');
+ vptr = dk3str_start(vptr, NULL);
+ }
+ switch(dk3str_array_index(f2lopt_key_names, kptr, 0)) {
+ case 0: { $? ". tf"
+ if(vptr) {
+ back = f2lopt_set_text_font(job, vptr);
+ } else {
+ /* ERRROR: Key needs an argument! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 21, 22, kptr);
+ }
+ } break;
+ case 1: { $? ". ts"
+ if(vptr) {
+ back = f2lopt_set_text_size(job, vptr);
+ } else {
+ job->nts = -1.0;
+ back = 1;
+ }
+ } break;
+ case 2: { $? ". cosp"
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ job->cosp = (dk3str_is_on(vptr) ? 1 : 0);
+ back = 1;
+ } else {
+ /* ERROR: Not a boolean */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
+ }
+ } else {
+ job->cosp = 1; back = 1;
+ }
+ } break;
+ case 3: { $? ". coah"
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ job->coah = (dk3str_is_on(vptr) ? 1 : 0);
+ back = 1;
+ } else {
+ /* ERROR: Not a boolean */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
+ }
+ } else {
+ job->coah = 1; back = 1;
+ }
+ } break;
+ case 4: { $? ". xssbs"
+ if(vptr) {
+ back = f2lopt_read_size_t(&(job->xssbs), vptr, job);
+ } else {
+ /* ERROR: Argument required! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 133, 134, kptr);
+ }
+ } break;
+ case 5: { $? ". qbs"
+ if(vptr) {
+ back = f2lopt_read_size_t(&(job->qbs), vptr, job);
+ } else {
+ /* ERROR: Argument required! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 133, 134, kptr);
+ }
+ } break;
+ case 6: {
+#if VERSION_BEFORE_20140330
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ job->lighten = ((dk3str_is_on(vptr)) ? 1 : 0);
+ back = 1;
+ } else {
+ /* ERROR: Not a boolean value! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
+ }
+ } else {
+ back = 1;
+ job->lighten = 1;
+ }
+#else
+ job->lwbp = 0.9;
+ job->lwauto = 0;
+ if (vptr) {
+ double x;
+ size_t vplen;
+ vplen = dk3str_len(vptr);
+ if (0 == dk3str_cmp(f2lopt_kw[1], vptr)) {
+ job->lwbp = 0.45;
+ job->lwauto = 0;
+ back = 1;
+ } else {
+ if (dk3str_is_abbr(vptr,f2lopt_kw[2],dkT('$'), 0)) {
+ job->lwauto = 1;
+ back = 1;
+ } else {
+ if (2 < vplen) {
+ switch (dk3str_array_index(f2lopt_units, &(vptr[vplen-2]), 0))
+ {
+ case 0: { /* bp */
+ vptr[vplen - 2] = dkT('\0');
+#if VERSION_BEFORE_20140716
+ if (dk3sf_sscanf3(vptr, dkT("%lg"), &x) == 1)
+#else
+ if (0 != dk3ma_d_from_string(&x, vptr, NULL))
+#endif
+ {
+ job->lwbp = x;
+ back = 1;
+ } else {
+ /* ERROR: Failed to process */
+ dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,45,46,vptr);
+ }
+ } break;
+ case 1: { /* pt */
+ vptr[vplen - 2] = dkT('\0');
+#if VERSION_BEFORE_20140716
+ if (dk3sf_sscanf3(vptr, dkT("%lg"), &x) == 1)
+#else
+ if (0 != dk3ma_d_from_string(&x, vptr, NULL))
+#endif
+ {
+ job->lwbp = x * 72.0 / 72.27;
+ back = 1;
+ } else {
+ /* ERROR: Failed to process */
+ dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,45,46,vptr);
+ }
+ } break;
+ case 2: { /* in */
+ vptr[vplen - 2] = dkT('\0');
+#if VERSION_BEFORE_20140716
+ if (dk3sf_sscanf3(vptr, dkT("%lg"), &x) == 1)
+#else
+ if (0 != dk3ma_d_from_string(&x, vptr, NULL))
+#endif
+ {
+ job->lwbp = x * 72.0;
+ back = 1;
+ } else {
+ /* ERROR: Failed to process */
+ dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,45,46,vptr);
+ }
+ } break;
+ case 3: { /* mm */
+ vptr[vplen - 2] = dkT('\0');
+#if VERSION_BEFORE_20140716
+ if (dk3sf_sscanf3(vptr, dkT("%lg"), &x) == 1)
+#else
+ if (0 != dk3ma_d_from_string(&x, vptr, NULL))
+#endif
+ {
+ job->lwbp = x * 72.0 / 25.4;
+ back = 1;
+ } else {
+ /* ERROR: Failed to process */
+ dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,45,46,vptr);
+ }
+ } break;
+ case 4: { /* cm */
+ vptr[vplen - 2] = dkT('\0');
+#if VERSION_BEFORE_20140716
+ if (dk3sf_sscanf3(vptr, dkT("%lg"), &x) == 1)
+#else
+ if (0 != dk3ma_d_from_string(&x, vptr, NULL))
+#endif
+ {
+ job->lwbp = x * 72.0 / 2.54;
+ back = 1;
+ } else {
+ /* ERROR: Failed to process */
+ dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,45,46,vptr);
+ }
+ } break;
+ default: {
+#if VERSION_BEFORE_20140716
+ if (dk3sf_sscanf3(vptr, dkT("%lg"), &x) == 1)
+#else
+ if (0 != dk3ma_d_from_string(&x, vptr, NULL))
+#endif
+ {
+ job->lwbp = x;
+ back = 1;
+ } else {
+ /* ERROR: Failed to process */
+ dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,45,46,vptr);
+ }
+ } break;
+ }
+ } else {
+#if VERSION_BEFORE_20140716
+ if (dk3sf_sscanf3(vptr, dkT("%lg"), &x) == 1)
+#else
+ if (0 != dk3ma_d_from_string(&x, vptr, NULL))
+#endif
+ {
+ job->lwbp = x;
+ back = 1;
+ } else {
+ /* ERROR: Failed to process */
+ dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,45,46,vptr);
+ }
+ }
+ }
+ }
+ } else {
+ job->lwbp = 0.9;
+ job->lwauto = 1;
+ back = 1;
+ if (job->lwbp < 0.001) {
+ job->lwbp = 0.001;
+ }
+ } $? ". lwbp=%lg lwauto=%d", job->lwbp, job->lwauto
+#endif
+ } break;
+ case 7: {
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ back = 1;
+ job->debug = ((dk3str_is_on(vptr)) ? 1 : 0);
+ } else {
+ /* ERROR: Not a boolean value! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
+ }
+ } else {
+ back = 1;
+ job->debug = 1;
+ }
+ } break;
+ case 8: {
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ job->showpage = ((dk3str_is_on(vptr)) ? 1 : 0);
+ back = 1;
+ } else {
+ /* ERROR: Not a boolean value! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
+ }
+ } else {
+ job->showpage = 1;
+ back = 1;
+ }
+ } break;
+ case 9: {
+ if(vptr) {
+ int i;
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(vptr, dkT("%d"), &i) == 1)
+#else
+ if (0 != dk3ma_i_from_string(&i, vptr, NULL))
+#endif
+ {
+ if((i >= 2) && (i <= 3)) {
+ job->pslevel = i;
+ } else {
+ /* ERROR: Must be 2 or 3! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 33);
+ }
+ } else {
+ /* ERROR: Argument not a number! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 141, 142, vptr);
+ }
+ } else {
+ /* ERROR: Argument required! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 133, 134, kptr);
+ }
+ } break;
+ case 10: {
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ job->dsc = ((dk3str_is_on(vptr)) ? 1 : 0);
+ back = 1;
+ } else {
+ /* ERROR: Not a boolean argument. */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
+ }
+ } else {
+ job->dsc = 1;
+ back = 1;
+ }
+ } break;
+ case 11: {
+ if(DK3_FIG_SRCTYPE_UNKNOWN == job->srctype) {
+ job->srctype = DK3_FIG_SRCTYPE_XFIG;
+ back = 1;
+ } else {
+ /* ERROR: Source type already set! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 23);
+ }
+ } break;
+ case 12: {
+ if(DK3_FIG_SRCTYPE_UNKNOWN == job->srctype) {
+ job->srctype = DK3_FIG_SRCTYPE_JFIG;
+ back = 1;
+ } else {
+ /* ERROR: Source type already set! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 23);
+ }
+ } break;
+ case 13: {
+ if(DK3_FIG_SRCTYPE_UNKNOWN == job->srctype) {
+ job->srctype = DK3_FIG_SRCTYPE_WINFIG;
+ back = 1;
+ } else {
+ /* ERROR: Source type already set! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 23);
+ }
+ } break;
+ case 14: { /* Arrowhead arc segments */
+ back = f2lopt_read_double(job,&(job->arcspp),vptr,2.0,-1.0,1,14);
+ } break;
+ case 15: { /* Arrowhead spline segments */
+ back = f2lopt_read_double(job,&(job->splspp),vptr,2.0,-1.0,1,15);
+ } break;
+ case 16: { /* Arrowhead min segments. */
+ unsigned u = 2;
+ if(vptr) {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(vptr, dkT("%u"), &u) == 1)
+#else
+ if (0 != dk3ma_ui_from_string(&u, vptr, NULL))
+#endif
+ {
+ if(2 <= u) {
+ job->minspp = (size_t)u;
+ back = 1;
+ } else {
+ /* Warning: Must be at least 2! */
+ job->minspp = 2;
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 34);
+ back = 1;
+ }
+ } else {
+ /* ERROR: Argument is not numeric */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 141, 142, vptr);
+ }
+ } else {
+ /* ERROR: Option requires an argument! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 133, 134, kptr);
+ }
+ } break;
+ case 17: { /* Arrowhead interpolation precision. */
+ back = f2lopt_read_double(job,&(job->xsprec),vptr,0.0,0.1,2,17);
+ } break;
+ case 18: { /* smash */
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ job->smash = ((dk3str_is_on(vptr)) ? 1 : 0);
+ back = 1;
+ } else {
+ /* ERROR: Option requires boolean argument */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
+ }
+ } else {
+ job->smash = 1;
+ back = 1;
+ }
+ } break;
+ case 19: { /* mbox */
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ job->mbox = ((dk3str_is_on(vptr)) ? 1 : 0);
+ back = 1;
+ } else {
+ /* ERROR: Option requires boolean argument! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
+ }
+ } else {
+ job->mbox = 1;
+ back = 1;
+ }
+ } break;
+ case 20: {
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ job->resfont = ((dk3str_is_on(vptr)) ? 1 : 0);
+ back = 1;
+ } else {
+ /* ERROR: Option requires boolean argument! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
+ }
+ } else {
+ job->resfont = 1;
+ back = 1;
+ }
+ } break;
+ case 21: {
+ if(vptr) {
+ unsigned u;
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(vptr, dkT("%u"), &u) == 1)
+#else
+ if (0 != dk3ma_ui_from_string(&u, vptr, NULL))
+#endif
+ {
+ job->codi = (size_t)u;
+ back = 1;
+ } else {
+ /* ERROR: Option requires an unsigned numeric argument! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 24, 25, kptr);
+ }
+ } else {
+ job->codi = 0;
+ back = 1;
+ }
+ } break;
+ case 22: {
+ if(vptr) {
+ double d;
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(vptr, dkT("%lg"), &d) == 1)
+#else
+ if (0 != dk3ma_d_from_string(&d, vptr, NULL))
+#endif
+ {
+ if(d > 0.0) {
+ job->tts = d; back = 1;
+ } else {
+ /* ERROR: Cannot handle negative font size! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 26);
+ }
+ } else {
+ /* ERROR: Option requires a floating point number arg! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 12, 22, kptr);
+ }
+ } else {
+ job->tts = 12.0; back = 1;
+ }
+ } break;
+ case 23: {
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ job->css = ((dk3str_is_on(vptr)) ? 1 : 0); back = 1;
+ } else {
+ /* ERROR: Option requires boolean argument! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
+ }
+ } else {
+ job->css = 1; back = 1;
+ }
+ } break;
+ case 24: {
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ job->fragment = ((dk3str_is_on(vptr)) ? 1 : 0); back = 1;
+ } else {
+ /* ERROR: Option requires boolean argument! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
+ }
+ } else {
+ job->fragment = 1; back = 1;
+ }
+ } break;
+ case 25: {
+ if(vptr) {
+ job->svgfontbase = dk3str_array_index(f2lopt_svg_font_bases, vptr, 0);
+ if(0 <= job->svgfontbase) {
+ back = 1;
+ } else {
+ /* ##### ERROR: Illegal font base name! */
+ }
+ } else {
+ job->svgfontbase = 0; back = 1;
+ }
+ } break;
+ case 26: {
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ job->group = ((dk3str_is_on(vptr)) ? 1 : 0); back = 1;
+ } else {
+ /* ERROR: Option requires boolean argument! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
+ }
+ } else {
+ job->group = 1; back = 1;
+ }
+ } break;
+ case 27: {
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ job->miterlim = ((dk3str_is_on(vptr)) ? 1 : 0); back = 1;
+ } else {
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
+ }
+ } else {
+ job->miterlim = 1; back = 1;
+ }
+ } break;
+ case 28: {
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ job->cols = ((dk3str_is_on(vptr)) ? 1 : 0); back = 1;
+ } else {
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
+ }
+ } else {
+ job->cols = 1; back = 1;
+ }
+ } break;
+ case 29: {
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ job->otherfonts = ((dk3str_is_on(vptr)) ? 1 : 0); back = 1;
+ } else {
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
+ }
+ } else {
+ job->otherfonts = 1; back = 1;
+ }
+ } break;
+ case 30: {
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ job->bbts = ((dk3str_is_on(vptr)) ? 1 : 0); back = 1;
+ } else {
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
+ }
+ } else {
+ job->bbts = 1; back = 1;
+ }
+ } break;
+ case 31: {
+ int enc;
+ if(vptr) {
+ enc = dk3enc_get_text_encoding_app(vptr, job->app);
+ } else {
+ if(DK3_ENCODING_UTF8 == dk3app_get_encoding(job->app)) {
+ enc = DK3_ENCODING_PLAIN;
+ } else {
+ enc = DK3_ENCODING_UTF8;
+ }
+ }
+ back = 1;
+ switch(enc) {
+ case DK3_ENCODING_UTF8: {
+ job->stu8 = 1;
+ } break;
+ case DK3_ENCODING_PLAIN: {
+ job->stu8 = 0;
+ } break;
+ default: {
+ job->stu8 = 0;
+ /* ##### WARNING Only ascii and utf-8 allowed. */
+ } break;
+ }
+ } break;
+ case 32: {
+ if(vptr) {
+ if(dk3str_is_bool(vptr)) {
+ job->cofop = ((dk3str_is_on(vptr)) ? 1 : 0);
+ back = 1;
+ } else {
+ /* ERROR: Not a boolean! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
+ }
+ } else {
+ job->cofop = 1;
+ back = 1;
+ }
+ } break;
+ case 33: {
+ if (vptr) {
+ if(dk3str_is_bool(vptr)) {
+ job->xsah = ((dk3str_is_on(vptr)) ? 1 : 0);
+ back = 1;
+ } else {
+ /* ERROR: Not a boolean! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 147, kptr);
+ }
+ } else {
+ job->xsah = 1;
+ back = 1;
+ }
+ } break;
+ default: {
+ /* ERROR: Unknown key name! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 27, 28, kptr);
+ } break;
+ }
+ } else { $? "! empty option"
+ back = 1;
+ }
+ if(!(back)) {
+ job->exval = FIG2LAT_EXIT_ERROR_SYNTAX; $? ". exitcode"
+ }
+ } else {
+ /* ERROR: Option ... too long! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 29, 30, str);
+ job->exval = FIG2LAT_EXIT_ERROR_SYNTAX; $? ". exitcode"
+ } $? "- f2lopt_apply_option %d", back
+ return back;
+}
+
+
+
+/** Set language, apply options if any.
+ @param job Job structure to set up.
+ @param optarg Language, optionally with further options.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lopt_set_language(f2l_job_t *job, dkChar const *optarg)
+{
+ dkChar bu[1024]; /* Private copy of optarg. */
+ dkChar *pc; /* Current string. */
+ dkChar *pn; /* Next string. */
+ int back = 0;
+ $? "+ f2lopt_set_language \"%!ds\"", TR_STR(optarg)
+ if(dk3str_len(optarg) < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy_not_overlapped(bu, optarg);
+ pc = dk3str_chr(bu, dkT(','));
+ if(pc) {
+ *(pc++) = dkT('\0');
+ pc = dk3str_start(pc, NULL);
+ }
+ if(f2lopt_apply_language(job, bu)) {
+ back = 1;
+ while(pc) { $? ". pc = \"%!ds\"", TR_STR(pc)
+ pn = dk3str_chr(pc, dkT(','));
+ if(pn) { *(pn++) = dkT('\0'); pn = dk3str_start(pn, NULL); }
+ if(!f2lopt_apply_option(job, pc)) {
+ back = 0; $? "! f2lopt_apply_option"
+ pn = NULL;
+ }
+ pc = pn;
+ }
+ }
+ } else {
+ /* ERROR: Option argument too long! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 31, 30, optarg);
+ } $? "- f2lopt_set_language %d", back
+ return back;
+}
+
+
+
+int
+f2lopt_process(f2l_job_t *job)
+{
+ dkChar const *optarg; /* Option argument. */
+ int back = 0;
+ int i; /* Current file name. */
+ $? "+ f2lopt_process"
+ job->opt = dk3opt_open_from_app(
+ f2lopt_options, f2lopt_sz_options,
+ dkT('o'), dkT("option"),
+ job->app
+ );
+ if(job->opt) { $? ". option set"
+ if(0 == dk3opt_get_error_code(job->opt)) { $? ". error check"
+ back = 1;
+ if(dk3opt_is_set(job->opt, dkT('h'))) {
+ job->cmd |= DK3_APP_CMD_HELP;
+ }
+ if(dk3opt_is_set(job->opt, dkT('v'))) {
+ job->cmd |= DK3_APP_CMD_VERSION;
+ }
+ if(dk3opt_is_set(job->opt, dkT('L'))) {
+ job->cmd |= DK3_APP_CMD_LICENSE;
+ }
+ if(0 == job->cmd) {
+ if(dk3opt_is_set(job->opt, dkT('m'))) {
+ job->mm = 1;
+ }
+ if(dk3opt_is_set(job->opt, dkT('l'))) {
+ optarg = dk3opt_get_short_arg(job->opt, dkT('l'));
+ if(optarg) { $? ". optarg"
+ if(f2lopt_set_language(job, optarg)) {
+ for(i = 0; i < dk3opt_get_num_fo(job->opt); i++) {
+ optarg = dk3opt_get_fo(job->opt, i);
+ if(optarg) {
+ if(!f2lopt_apply_option(job, optarg)) {
+ back = 0;
+ }
+ }
+ }
+ } else {
+ back = 0;
+ }
+ } else { $? "! optarg"
+ back = 0;
+ /* ERROR: Option requires an argument! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 32);
+ }
+ } else {
+ }
+ }
+ /* Automatically calculate line width in points
+ from TeX text size.
+ */
+ if (job->lwauto) {
+ job->lwbp = 0.4 * 72.0 * job->tts / (10 * 72.27);
+ $? ". lwbp=%lg", job->lwbp
+ }
+ } else { $? "! error check"
+ }
+ } else { $? "! option set"
+ job->exval = FIG2LAT_EXIT_ERROR_SYSTEM; $? ". exitcode"
+ } $? "- f2lopt_process %d", back
+ return back;
+}
+
+
diff --git a/support/dktools/f2lopt.h b/support/dktools/f2lopt.h
new file mode 100644
index 0000000000..3a1368615f
--- /dev/null
+++ b/support/dktools/f2lopt.h
@@ -0,0 +1,64 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: f2lopt.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file f2lopt.h Header file for the f2lopt module.
+*/
+
+#ifndef F2LOPT_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define F2LOPT_H_INCLUDED 1
+
+
+#line 10 "f2lopt.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Process command line arguments.
+ @param job Job to process.
+ @return 1 on success, 0 on error.
+*/
+int
+f2lopt_process(f2l_job_t *job);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/f2lpara.c b/support/dktools/f2lpara.c
new file mode 100644
index 0000000000..4d69ad73ec
--- /dev/null
+++ b/support/dktools/f2lpara.c
@@ -0,0 +1,97 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: f2lpara.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file f2lpara.c The f2lpara module.
+*/
+
+
+#line 54 "f2lpara.ctr"
+
+
+#include "dk3ma.h"
+#include "f2lpara.h"
+
+
+double
+f2lpara_derived_left(double yneg, double y0, double ypos, int *ec)
+{
+ double back = 0.0;
+ int myec = 0;
+ /* back = 2 * y0 - 0.5 * ypos - 1.5 * yneg */
+ back = dk3ma_d_sub_ok(
+ dk3ma_d_mul_ok(2.0, y0, &myec),
+ dk3ma_d_add_ok(
+ (0.5 * ypos),
+ dk3ma_d_mul_ok(1.5, yneg, &myec),
+ &myec
+ ),
+ &myec
+ );
+ if (myec) { if (ec) { *ec = myec; } }
+ return back;
+}
+
+
+double
+f2lpara_derived_center(double yneg, double y0, double ypos, int *ec)
+{
+ double back = 0.0;
+ int myec = 0;
+ /* back = 0.5 * (ypos - yneg) */
+ back = 0.5 * dk3ma_d_sub_ok(ypos, yneg, &myec);
+ if (myec) { if (ec) { *ec = myec; } }
+ return back;
+}
+
+
+double
+f2lpara_derived_right(double yneg, double y0, double ypos, int *ec)
+{
+ double back = 0.0;
+ int myec = 0;
+ /* back = 1.5 * ypos + 0.5 * yneg - 2 * y0 */
+ back = dk3ma_d_sub_ok(
+ dk3ma_d_add_ok(
+ dk3ma_d_mul_ok(1.5, ypos, &myec),
+ (0.5 * yneg),
+ &myec
+ ),
+ dk3ma_d_mul_ok(2.0, y0, &myec),
+ &myec
+ );
+ if (myec) { if (ec) { *ec = myec; } }
+ return back;
+}
+
diff --git a/support/dktools/f2lpara.ctr b/support/dktools/f2lpara.ctr
new file mode 100644
index 0000000000..c38387ab30
--- /dev/null
+++ b/support/dktools/f2lpara.ctr
@@ -0,0 +1,110 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2014-xxxx
+license = bsd
+
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Get left point first derivative value for parabola
+ through x=-1, x=0, and x=1.
+ @param yneg Y value for x=-1.
+ @param y0 Y value for x=0.
+ @param ypos Y value for x=1.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Result.
+*/
+double
+f2lpara_derived_left(double yneg, double y0, double ypos, int *ec);
+
+/** Get center point first derivative value for parabola
+ through x=-1, x=0, and x=1.
+ @param yneg Y value for x=-1.
+ @param y0 Y value for x=0.
+ @param ypos Y value for x=1.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Result.
+*/
+double
+f2lpara_derived_center(double yneg, double y0, double ypos, int *ec);
+
+/** Get right point first derivative value for parabola
+ through x=-1, x=0, and x=1.
+ @param yneg Y value for x=-1.
+ @param y0 Y value for x=0.
+ @param ypos Y value for x=1.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Result.
+*/
+double
+f2lpara_derived_right(double yneg, double y0, double ypos, int *ec);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+
+#include "dk3ma.h"
+#include "f2lpara.h"
+
+
+double
+f2lpara_derived_left(double yneg, double y0, double ypos, int *ec)
+{
+ double back = 0.0;
+ int myec = 0;
+ /* back = 2 * y0 - 0.5 * ypos - 1.5 * yneg */
+ back = dk3ma_d_sub_ok(
+ dk3ma_d_mul_ok(2.0, y0, &myec),
+ dk3ma_d_add_ok(
+ (0.5 * ypos),
+ dk3ma_d_mul_ok(1.5, yneg, &myec),
+ &myec
+ ),
+ &myec
+ );
+ if (myec) { if (ec) { *ec = myec; } }
+ return back;
+}
+
+
+double
+f2lpara_derived_center(double yneg, double y0, double ypos, int *ec)
+{
+ double back = 0.0;
+ int myec = 0;
+ /* back = 0.5 * (ypos - yneg) */
+ back = 0.5 * dk3ma_d_sub_ok(ypos, yneg, &myec);
+ if (myec) { if (ec) { *ec = myec; } }
+ return back;
+}
+
+
+double
+f2lpara_derived_right(double yneg, double y0, double ypos, int *ec)
+{
+ double back = 0.0;
+ int myec = 0;
+ /* back = 1.5 * ypos + 0.5 * yneg - 2 * y0 */
+ back = dk3ma_d_sub_ok(
+ dk3ma_d_add_ok(
+ dk3ma_d_mul_ok(1.5, ypos, &myec),
+ (0.5 * yneg),
+ &myec
+ ),
+ dk3ma_d_mul_ok(2.0, y0, &myec),
+ &myec
+ );
+ if (myec) { if (ec) { *ec = myec; } }
+ return back;
+}
+
diff --git a/support/dktools/f2lpara.h b/support/dktools/f2lpara.h
new file mode 100644
index 0000000000..d91bbea4f8
--- /dev/null
+++ b/support/dktools/f2lpara.h
@@ -0,0 +1,89 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: f2lpara.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file f2lpara.h Header file for the f2lpara module.
+*/
+
+#ifndef F2LPARA_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define F2LPARA_H_INCLUDED 1
+
+
+#line 10 "f2lpara.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Get left point first derivative value for parabola
+ through x=-1, x=0, and x=1.
+ @param yneg Y value for x=-1.
+ @param y0 Y value for x=0.
+ @param ypos Y value for x=1.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Result.
+*/
+double
+f2lpara_derived_left(double yneg, double y0, double ypos, int *ec);
+
+/** Get center point first derivative value for parabola
+ through x=-1, x=0, and x=1.
+ @param yneg Y value for x=-1.
+ @param y0 Y value for x=0.
+ @param ypos Y value for x=1.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Result.
+*/
+double
+f2lpara_derived_center(double yneg, double y0, double ypos, int *ec);
+
+/** Get right point first derivative value for parabola
+ through x=-1, x=0, and x=1.
+ @param yneg Y value for x=-1.
+ @param y0 Y value for x=0.
+ @param ypos Y value for x=1.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Result.
+*/
+double
+f2lpara_derived_right(double yneg, double y0, double ypos, int *ec);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/f2lpdf.c b/support/dktools/f2lpdf.c
new file mode 100644
index 0000000000..45e44416e7
--- /dev/null
+++ b/support/dktools/f2lpdf.c
@@ -0,0 +1,1493 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: f2lpdf.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file f2lpdf.c The f2lpdf module.
+*/
+
+
+#line 699 "f2lpdf.ctr"
+
+#include "dk3all.h"
+#include "dk3bezcu.h"
+#include "fig2lat.h"
+#include "f2lud.h"
+#include "f2lsvg.h"
+#include "f2lpdf.h"
+#include "dk3figto.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4vers.h"
+#include "dk3bmeo.h"
+#include "dk3bm.h"
+#include "dk3pdf.h"
+#include "dk3bif.h"
+
+
+
+
+
+#line 719 "f2lpdf.ctr"
+
+
+
+/** Driver specific details for entire drawing.
+*/
+typedef struct {
+ dk3_pdf_t *opdf; /**< Output PDF. */
+ dk3_sto_t *sFonts; /**< Storage for fonts. */
+ dk3_sto_it_t *iFonts; /**< Iterator for font storage. */
+ dk3_sto_t *sImages; /**< Storage for image data. */
+ dk3_sto_it_t *iImages; /**< Iterator for images storage. */
+ char const *shortOutFile; /**< Short output file name. */
+ unsigned long nFonts; /**< Number of fonts in sFonts. */
+ unsigned long nImages; /**< Number of images in sImages. */
+} f2l_pdf_drawing_info_t;
+
+
+
+
+
+
+/* ************************************************************************ */
+/* * * */
+/* * Tool functions. * */
+/* * * */
+/* ************************************************************************ */
+
+
+#line 743 "f2lpdf.ctr"
+
+
+
+/** Delete driver-specific details.
+ @param ptr Structure to delete.
+*/
+static
+void
+f2lpdf_drawing_info_delete(f2l_pdf_drawing_info_t *ptr)
+{
+ f2l_text_handling_t *th;
+ f2l_image_t *im;
+
+
+#line 756 "f2lpdf.ctr"
+ if(ptr) {
+ dk3_release(ptr->shortOutFile);
+ if(ptr->opdf) {
+ dk3pdf_close(ptr->opdf);
+ } ptr->opdf = NULL;
+ if(ptr->sFonts) {
+ if(ptr->iFonts) {
+ dk3sto_it_reset(ptr->iFonts);
+ while(NULL != (th = (f2l_text_handling_t *)dk3sto_it_next(ptr->iFonts)))
+ {
+ dk3_delete(th);
+ }
+ dk3sto_it_close(ptr->iFonts);
+ }
+ dk3sto_close(ptr->sFonts);
+ } ptr->sFonts = NULL; ptr->iFonts = NULL;
+ if(ptr->sImages) {
+ if(ptr->iImages) {
+ dk3sto_it_reset(ptr->iImages);
+ while(NULL != (im = (f2l_image_t *)dk3sto_it_next(ptr->iImages))) {
+ f2l_tool_image_delete(im);
+ }
+ dk3sto_it_close(ptr->iImages);
+ }
+ dk3sto_close(ptr->sImages);
+ } ptr->sImages = NULL; ptr->iImages = NULL;
+ ptr->nFonts = 0UL;
+ ptr->nImages = 0UL;
+ dk3_delete(ptr);
+ }
+
+#line 786 "f2lpdf.ctr"
+}
+
+
+
+/** Create structure for driver-specific details.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return Pointer to new structure on success, NULL on error.
+*/
+static
+f2l_pdf_drawing_info_t *
+f2lpdf_drawing_info_new(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw
+)
+{
+ f2l_pdf_drawing_info_t *back = NULL;
+ int ok = 0; /* Flag: No error. */
+
+
+#line 805 "f2lpdf.ctr"
+ if((job) && (drw)) {
+ back = dk3_new_app(f2l_pdf_drawing_info_t,1,job->app);
+ if(back) {
+ back->shortOutFile = NULL;
+ back->opdf = NULL;
+ back->sFonts = NULL;
+ back->iFonts = NULL;
+ back->sImages = NULL;
+ back->iImages = NULL;
+ back->nFonts = 0UL;
+ back->nImages = 0UL;
+ back->sFonts = dk3sto_open_app(job->app);
+ if(back->sFonts) {
+ dk3sto_set_comp(back->sFonts, dk3fig_tool_text_handling_compare, 0);
+ back->iFonts = dk3sto_it_open(back->sFonts);
+ if(back->iFonts) {
+ back->sImages = dk3sto_open_app(job->app);
+ if(back->sImages) {
+ dk3sto_set_comp(back->sImages, f2l_tool_compare_images, 0);
+ back->iImages = dk3sto_it_open(back->sImages);
+ if(back->iImages) {
+ back->opdf = dk3pdf_open_app(job->app);
+ if(back->opdf) {
+ ok = 1;
+ }
+ }
+ }
+ }
+ }
+ if(!(ok)) {
+ f2lpdf_drawing_info_delete(back);
+ back = NULL;
+ }
+ } else {
+ }
+ }
+
+#line 841 "f2lpdf.ctr"
+ return back;
+}
+
+
+
+/* ************************************************************************ */
+/* * * */
+/* * PDF with LaTeX output driver. * */
+/* * This driver creates .tex/.pdf combinations to be included * */
+/* * in a .tex source. * */
+/* * * */
+/* ************************************************************************ */
+
+
+#line 851 "f2lpdf.ctr"
+
+
+
+/** Register image file name in pdi for later use.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param pdi PDF information structure.
+ @param fn Image file name to add.
+ @param li Line number of image object definition.
+ @return 1 on success, 0 on error.
+*/
+static
+f2l_image_t *
+f2lpdf_register_image(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_pdf_drawing_info_t *pdi,
+ char const *fn,
+ unsigned long li
+)
+{
+ dk3_ufi_t ufi; /* Unique file identifier. */
+ f2l_image_t *back = NULL; /* Image information structure. */
+
+ if(dk3ufi_c8_get_app(&ufi, fn, job->app)) {
+ back = (f2l_image_t *)dk3sto_it_find_like(pdi->iImages, (void *)(&ufi), 1);
+ if(!(back)) {
+ back = f2l_tool_image_new(fn, job->app, li);
+ if(back) {
+ if(dk3sto_add(pdi->sImages, (void *)back)) {
+ back->imageNumber = pdi->nImages;
+ pdi->nImages += 1UL;
+ } else {
+ f2l_tool_image_delete(back);
+ back = NULL;
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 887 "f2lpdf.ctr"
+ }
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 890 "f2lpdf.ctr"
+ }
+ }
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 894 "f2lpdf.ctr"
+ }
+ return back;
+}
+
+
+
+/** Add image XObject data to PDF.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param pdi PDF information structure.
+ @param im Image information to add.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lpdf_add_image_to_pdf(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_pdf_drawing_info_t *pdi,
+ f2l_image_t *im
+)
+{
+ dk3_bm_eps_options_t options; /* Options for PDF conversion. */
+ dk3_bif_t *bif; /* Bitmap image file. */
+ int back = 0;
+
+
+#line 920 "f2lpdf.ctr"
+ bif = dk3bif_open_c8_filename_app(
+ im->filename, DK3_BIF_IMAGE_TYPE_UNKNOWN, job->app
+ );
+ if(bif) {
+ dk3bmeo_init(&options);
+ options.app = job->app;
+ options.ip = 1;
+ options.jip = 0;
+ options.mode = DK3_BMEPS_MODE_PLACED_OBJECT;
+ options.szmode = DK3_BMEPS_SIZE_1_1;
+
+#line 930 "f2lpdf.ctr"
+ options.dr = DK3_BMEPS_DRIVER_PDF;
+ options.rbpc = 1;
+ options.dct = 1;
+ options.color = 1;
+ if(dk3bif_read_data(bif)) {
+ im->xo = dk3pdf_create_ixobject_progress(pdi->opdf,bif,&options,NULL,0,0);
+ im->width = dk3bif_get_width(bif);
+ im->height = dk3bif_get_height(bif);
+ im->xres = dk3bif_get_xres(bif);
+ im->yres = dk3bif_get_yres(bif);
+ if(im->xo) {
+ back = 1;
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 944 "f2lpdf.ctr"
+ }
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 947 "f2lpdf.ctr"
+ }
+ dk3bif_close(bif);
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 951 "f2lpdf.ctr"
+ }
+
+
+#line 953 "f2lpdf.ctr"
+ return back;
+}
+
+
+
+int
+f2lpdf_pdf_with_tex_initialize(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver spec det. */
+ dk3_fig_obj_t *pobj; /* Current object. */
+ f2l_image_t *im; /* Current image. */
+ dkChar const *oldsourcefile = NULL; /* Old source file. */
+ unsigned long oldsourceline = 0UL; /* Old source line. */
+ int back = 0;
+ int ff; /* Font flags. */
+
+
+#line 969 "f2lpdf.ctr"
+ pdi = f2lpdf_drawing_info_new(job, drw);
+ if(pdi) {
+ drw->dsd = (void *)pdi;
+ pdi->shortOutFile = dk3fig_tool_short_output_file_name(job->on2, job->app);
+ if(pdi->shortOutFile) {
+ back = 1;
+ dk3pdf_set_next_mediabox(pdi->opdf, 0L, job->lwidth, 0L, job->lheight);
+ oldsourcefile = dk3app_get_source_file(job->app);
+ oldsourceline = dk3app_get_source_line(job->app);
+ dk3sto_it_reset(drw->iobj);
+ while(NULL != (pobj = (dk3_fig_obj_t *)dk3sto_it_next(drw->iobj))) {
+
+
+#line 981 "f2lpdf.ctr"
+ dk3app_set_source_line(job->app, pobj->li);
+ switch(pobj->ot) {
+ case DK3_FIG_OBJ_TEXT: {
+ ff = (pobj->dt).txt.ff;
+ if(!(ff & DK3_FIG_FONT_FLAG_HIDDEN)) {
+
+#line 986 "f2lpdf.ctr"
+ if(!(ff & DK3_FIG_FONT_FLAG_SPECIAL)) {
+
+#line 987 "f2lpdf.ctr"
+ if(ff & DK3_FIG_FONT_FLAG_PS) {
+
+#line 988 "f2lpdf.ctr"
+ if(job->ntf) {
+
+#line 989 "f2lpdf.ctr"
+ pobj->dsd = (void *)f2l_tool_register_font(
+ pdi->sFonts, pdi->iFonts, &(pdi->nFonts),
+ (pobj->dt).txt.fo, (pobj->dt).txt.fs, job->app
+ );
+ if(!(pobj->dsd)) {
+ back = 0;
+
+#line 995 "f2lpdf.ctr"
+ f2l_tool_set_exit_status(job,FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 996 "f2lpdf.ctr"
+ }
+ } else {
+
+#line 998 "f2lpdf.ctr"
+ }
+ }
+ }
+ }
+ } break;
+ case DK3_FIG_OBJ_POLYLINE: {
+ if(5 == pobj->st) {
+
+#line 1005 "f2lpdf.ctr"
+ pobj->dsd =
+ (void *)f2lpdf_register_image(
+ job, drw, pdi, (pobj->dt).pol.fn, pobj->li
+ );
+ if(!(pobj->dsd)) {
+ back = 0;
+ f2l_tool_set_exit_status(job,FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1012 "f2lpdf.ctr"
+ }
+ }
+ } break;
+ }
+ }
+ dk3sto_it_reset(pdi->iImages);
+ while(NULL != (im = (f2l_image_t *)dk3sto_it_next(pdi->iImages))) {
+ if(!f2lpdf_add_image_to_pdf(job, drw, pdi, im)) {
+
+#line 1020 "f2lpdf.ctr"
+ back = 0;
+ f2l_tool_set_exit_status(job,FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1022 "f2lpdf.ctr"
+ }
+ }
+ dk3app_set_source_file(job->app, oldsourcefile);
+ dk3app_set_source_line(job->app, oldsourceline);
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1028 "f2lpdf.ctr"
+ }
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1031 "f2lpdf.ctr"
+ }
+
+#line 1032 "f2lpdf.ctr"
+ return back;
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_end(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ if(drw->dsd) {
+ f2lpdf_drawing_info_delete((f2l_pdf_drawing_info_t *)(drw->dsd));
+ drw->dsd = NULL;
+ }
+}
+
+
+
+int
+f2lpdf_pdf_with_tex_open_output_files(f2l_job_t *job)
+{
+ int back = 0;
+ job->of1 = dk3sf_fopen_app(job->on1, dkT("w"), job->app);
+ if(job->of1) {
+ job->of2 = dk3sf_fopen_app(job->on2, dkT("wb"), job->app);
+ if(job->of2) {
+ back = 1;
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1059 "f2lpdf.ctr"
+ }
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1062 "f2lpdf.ctr"
+ }
+ return back;
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_close_output_files(f2l_job_t *job)
+{
+ if(job->of2) {
+ dk3sf_fclose_app(job->of2, job->app);
+ }
+ if(job->of1) {
+ dk3sf_fclose_app(job->of1, job->app);
+ }
+}
+
+
+
+int
+f2lpdf_pdf_with_tex_start_processing(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ int back = 0;
+
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ f2l_tool_start_tex_part(
+ job->of1, job, drw, pdi->shortOutFile, pdi->iFonts, pdi->nFonts
+ );
+ if(dk3pdf_open_page_with_clip(pdi->opdf, 1)) {
+ back = 1;
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1096 "f2lpdf.ctr"
+ }
+ return back;
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_end_processing(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ f2l_tool_end_tex_part(job->of1);
+ dk3pdf_close_page(pdi->opdf);
+ if(!dk3pdf_write_file(pdi->opdf, job->of2)) {
+ /* ERROR: Failed to write PDF output file! */
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1113 "f2lpdf.ctr"
+ }
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_text_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ if(pdi) {
+ f2l_tool_text_object(job->of1, job, drw, obj, x, y, pdi->nFonts);
+ }
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_image_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int drawdir,
+ int *ec
+)
+{
+ dk3_coordinates_transformation_t trans; /* Graphics state transform. */
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ f2l_image_t *im; /* Current image. */
+ int res; /* Search result. */
+
+
+#line 1152 "f2lpdf.ctr"
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ im = (f2l_image_t *)(obj->dsd);
+ if((im) && (pdi)) {
+
+#line 1155 "f2lpdf.ctr"
+ if(im->xo) {
+
+#line 1156 "f2lpdf.ctr"
+ res = dk3bm_find_transformation(
+ &trans, outbb, drawdir, (double)(im->width), (double)(im->height),
+ im->xres, im->yres, ec
+ );
+ if(res) {
+
+#line 1161 "f2lpdf.ctr"
+ res = dk3pdf_gsave(pdi->opdf);
+ if(!(res)) {
+
+#line 1163 "f2lpdf.ctr"
+ /* ERROR */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1166 "f2lpdf.ctr"
+ }
+ res =
+ dk3pdf_translate_double(pdi->opdf,trans.x_translate,trans.y_translate);
+ if(!(res)) {
+
+#line 1170 "f2lpdf.ctr"
+ /* ERROR */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1173 "f2lpdf.ctr"
+ }
+ if(trans.rot) {
+ res = dk3pdf_rotate_int(pdi->opdf, (90 * trans.rot));
+ if(!(res)) {
+
+#line 1177 "f2lpdf.ctr"
+ /* ERROR */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1180 "f2lpdf.ctr"
+ }
+ }
+ res = dk3pdf_scale_double(pdi->opdf, trans.x_scale, trans.y_scale);
+ if(!(res)) {
+
+#line 1184 "f2lpdf.ctr"
+ /* ERROR */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1187 "f2lpdf.ctr"
+ }
+ res = dk3pdf_add_xobject_to_page(pdi->opdf, im->xo);
+ if(!(res)) {
+
+#line 1190 "f2lpdf.ctr"
+ /* ERROR */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1193 "f2lpdf.ctr"
+ }
+ res = dk3pdf_grestore(pdi->opdf);
+ if(!(res)) {
+
+#line 1196 "f2lpdf.ctr"
+ /* ERROR */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1199 "f2lpdf.ctr"
+ }
+ } else {
+
+#line 1201 "f2lpdf.ctr"
+ /* ERROR: Math error while searching transformation! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
+
+#line 1204 "f2lpdf.ctr"
+ }
+ } else {
+
+#line 1206 "f2lpdf.ctr"
+ }
+ } else {
+
+#line 1208 "f2lpdf.ctr"
+ }
+
+#line 1209 "f2lpdf.ctr"
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_newpath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ /* Do nothing, in PDF the moveto operator includes newpath. */
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_moveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ int res; /* Output operation result. */
+
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ if(pdi) {
+ res = dk3pdf_newpath_moveto(pdi->opdf, x, y);
+ if(!(res)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1243 "f2lpdf.ctr"
+ }
+ }
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_lineto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ int res; /* Ouutput operation result. */
+
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ if(pdi) {
+ res = dk3pdf_lineto(pdi->opdf, x, y);
+ if(!(res)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1267 "f2lpdf.ctr"
+ }
+ }
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_curveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double xcs,
+ double ycs,
+ double xce,
+ double yce,
+ double xe,
+ double ye
+)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ int res; /* Output operation result. */
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ if(pdi) {
+ res = dk3pdf_curveto(pdi->opdf, xcs, ycs, xce, yce, xe, ye);
+ if(!(res)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1294 "f2lpdf.ctr"
+ }
+ }
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_closepath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ int res; /* Output operation result. */
+
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ if(pdi) {
+ res = dk3pdf_closepath(pdi->opdf);
+ if(!(res)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1316 "f2lpdf.ctr"
+ }
+ }
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_fill(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ int res; /* Output operation result. */
+
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ if(pdi) {
+ res = dk3pdf_fill_eo(pdi->opdf);
+ if(!(res)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1338 "f2lpdf.ctr"
+ }
+ }
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ int res; /* Output operation result. */
+
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ if(pdi) {
+ res = dk3pdf_clip_eo(pdi->opdf);
+ if(!(res)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1360 "f2lpdf.ctr"
+ }
+ }
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ int res; /* Output operation result. */
+
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ if(pdi) {
+ res = dk3pdf_stroke(pdi->opdf);
+ if(!(res)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1382 "f2lpdf.ctr"
+ }
+ }
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_gsave(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ int res; /* Output operation result. */
+
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ if(pdi) {
+ res = dk3pdf_gsave(pdi->opdf);
+ if(!(res)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1404 "f2lpdf.ctr"
+ }
+ }
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_grestore(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ int res; /* Output operation result. */
+
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ if(pdi) {
+ res = dk3pdf_grestore(pdi->opdf);
+ if(!(res)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1426 "f2lpdf.ctr"
+ }
+ }
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_setcolor(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double r,
+ double g,
+ double b
+)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ int res; /* Output operation result. */
+
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ if(pdi) {
+ res = dk3pdf_nonstroking_rgb(pdi->opdf, r, g, b);
+ if(!(res)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1451 "f2lpdf.ctr"
+ }
+ res = dk3pdf_stroking_rgb(pdi->opdf, r, g, b);
+ if(!(res)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1456 "f2lpdf.ctr"
+ }
+ }
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_set_line_width(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double lw
+)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ int res; /* Output operation result. */
+
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ if(pdi) {
+ res = dk3pdf_set_linewidth(pdi->opdf, lw);
+ if(!(res)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1479 "f2lpdf.ctr"
+ }
+ }
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_set_line_style(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int ls,
+ double sv,
+ double lw
+)
+{
+ double xsv[32]; /* Strokes and gaps lengths. */
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ double ph; /* Phase. */
+ double gw; /* Gap width. */
+ size_t nsv; /* Number of elements xsv. */
+ int res; /* Output operation result. */
+
+ ph = 0.0;
+ nsv = 0;
+ xsv[0] = 0.0;
+ gw = f2lto_find_gap_length(job, lw, sv);
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ if(pdi) {
+ switch(ls) {
+ case DK3_FIG_LS_DASH_TRIPLE_DOTTED: {
+ xsv[0] = sv;
+ xsv[1] = gw;
+ xsv[2] = lw;
+ xsv[3] = gw;
+ xsv[4] = lw;
+ xsv[5] = gw;
+ xsv[6] = lw;
+ xsv[7] = gw;
+ nsv = 8;
+ } break;
+ case DK3_FIG_LS_DASH_DOUBLE_DOTTED: {
+ xsv[0] = sv;
+ xsv[1] = gw;
+ xsv[2] = lw;
+ xsv[3] = gw;
+ xsv[4] = lw;
+ xsv[5] = gw;
+ nsv = 6;
+ } break;
+ case DK3_FIG_LS_DASH_DOTTED: {
+ xsv[0] = sv;
+ xsv[1] = gw;
+ xsv[2] = lw;
+ xsv[3] = gw;
+ nsv = 4;
+ } break;
+ case DK3_FIG_LS_DOTTED: {
+ xsv[0] = lw; xsv[1] = gw;
+ nsv = 2;
+ } break;
+ case DK3_FIG_LS_DASHED: {
+ xsv[0] = sv; xsv[1] = gw;
+ nsv = 2;
+ } break;
+ }
+ res = dk3pdf_set_line_dash(pdi->opdf, xsv, nsv, ph);
+ if(!(res)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1549 "f2lpdf.ctr"
+ }
+ }
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_set_line_end(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int le
+)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ int res; /* Output operation result. */
+
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ if(pdi) {
+ res = dk3pdf_set_linecap(pdi->opdf, le);
+ if(!(res)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1572 "f2lpdf.ctr"
+ }
+ }
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_set_line_join(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int lj
+)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ int res; /* Output operation result. */
+
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ if(pdi) {
+ res = dk3pdf_set_linejoin(pdi->opdf, lj);
+ if(!(res)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1595 "f2lpdf.ctr"
+ }
+ }
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_set_color_1(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ int res; /* Output operation result. */
+
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ if(pdi) {
+ res = dk3pdf_stroking_rgb(pdi->opdf, rgb->r, rgb->g, rgb->b);
+ if(!(res)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1617 "f2lpdf.ctr"
+ }
+ }
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_set_color_2(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ int res; /* Output operation result. */
+
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ if(pdi) {
+ res = dk3pdf_nonstroking_rgb(pdi->opdf, rgb->r, rgb->g, rgb->b);
+ if(!(res)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1639 "f2lpdf.ctr"
+ }
+ }
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_debug(
+ f2l_job_t *job,
+ char const *msg
+)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ int res; /* Output operation result. */
+
+ pdi = (f2l_pdf_drawing_info_t *)((job->drw)->dsd);
+ if(pdi) {
+ res = dk3pdf_write_debug_line(pdi->opdf, msg);
+ if(!(res)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1660 "f2lpdf.ctr"
+ }
+ }
+}
+
+
+
+/* ************************************************************************ */
+/* * * */
+/* * LaTeX with PDF output driver. * */
+/* * This driver combines .tex/.pdf combinations to be * */
+/* * processed with pdflatex directly. * */
+/* * * */
+/* ************************************************************************ */
+
+
+#line 1671 "f2lpdf.ctr"
+
+
+
+int
+f2lpdf_tex_with_pdf_initialize(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ int back = 0;
+ back = f2lpdf_pdf_with_tex_initialize(job, drw);
+ return back;
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_end(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ f2lpdf_pdf_with_tex_end(job, drw);
+}
+
+
+
+int
+f2lpdf_tex_with_pdf_open_output_files(f2l_job_t *job)
+{
+ int back = 0;
+ back = f2lpdf_pdf_with_tex_open_output_files(job);
+ return back;
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_close_output_files(f2l_job_t *job)
+{
+ f2lpdf_pdf_with_tex_close_output_files(job);
+}
+
+
+
+int
+f2lpdf_tex_with_pdf_start_processing(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ int back = 0;
+ f2l_tool_begin_latex_document(job->of1, job, drw);
+ back = f2lpdf_pdf_with_tex_start_processing(job, drw);
+ return back;
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_end_processing(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ f2lpdf_pdf_with_tex_end_processing(job, drw);
+ f2l_tool_end_latex_document(job->of1, job, drw);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_text_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+ f2lpdf_pdf_with_tex_text_object(job, drw, obj, x, y);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_image_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int drawdir,
+ int *ec
+)
+{
+ f2lpdf_pdf_with_tex_image_object(job, drw, obj, outbb, drawdir, ec);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_newpath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2lpdf_pdf_with_tex_newpath(job, drw, obj);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_moveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+ f2lpdf_pdf_with_tex_moveto(job, drw, obj, x, y);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_lineto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+ f2lpdf_pdf_with_tex_lineto(job, drw, obj, x, y);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_curveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double xcs,
+ double ycs,
+ double xce,
+ double yce,
+ double xe,
+ double ye
+)
+{
+ f2lpdf_pdf_with_tex_curveto(job, drw, obj, xcs, ycs, xce, yce, xe, ye);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_closepath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2lpdf_pdf_with_tex_closepath(job, drw, obj);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_fill(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2lpdf_pdf_with_tex_fill(job, drw, obj);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2lpdf_pdf_with_tex_clip(job, drw, obj);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2lpdf_pdf_with_tex_stroke(job, drw, obj);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_gsave(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2lpdf_pdf_with_tex_gsave(job, drw, obj);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_grestore(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2lpdf_pdf_with_tex_grestore(job, drw, obj);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_setcolor(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double r,
+ double g,
+ double b
+)
+{
+ f2lpdf_pdf_with_tex_setcolor(job, drw, obj, r, g, b);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_set_line_width(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double lw
+)
+{
+ f2lpdf_pdf_with_tex_set_line_width(job, drw, obj, lw);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_set_line_style(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int ls,
+ double sv,
+ double lw
+)
+{
+ f2lpdf_pdf_with_tex_set_line_style(job, drw, obj, ls, sv, lw);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_set_line_end(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int le
+)
+{
+ f2lpdf_pdf_with_tex_set_line_end(job, drw, obj, le);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_set_line_join(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int lj
+)
+{
+ f2lpdf_pdf_with_tex_set_line_join(job, drw, obj, lj);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_set_color_1(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+)
+{
+ f2lpdf_pdf_with_tex_set_color_1(job, drw, rgb);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_set_color_2(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+)
+{
+ f2lpdf_pdf_with_tex_set_color_2(job, drw, rgb);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_debug(
+ f2l_job_t *job,
+ char const *msg
+)
+{
+ f2lpdf_pdf_with_tex_debug(job, msg);
+}
+
diff --git a/support/dktools/f2lpdf.ctr b/support/dktools/f2lpdf.ctr
new file mode 100644
index 0000000000..8ac91c9c6f
--- /dev/null
+++ b/support/dktools/f2lpdf.ctr
@@ -0,0 +1,1990 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Driver initialization for pdf with tex driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+int
+f2lpdf_pdf_with_tex_initialize(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Driver cleanup for pdf with tex driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+void
+f2lpdf_pdf_with_tex_end(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Open output files for pdf with tex driver.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+f2lpdf_pdf_with_tex_open_output_files(f2l_job_t *job);
+
+/** Close output files for pdf with tex driver.
+ @param job Job structure.
+*/
+void
+f2lpdf_pdf_with_tex_close_output_files(f2l_job_t *job);
+
+/** Write start of output for pdf with tex driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+int
+f2lpdf_pdf_with_tex_start_processing(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Write end of output for pdf with tex driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+void
+f2lpdf_pdf_with_tex_end_processing(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Process one text object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x Point x.
+ @param y Point y.
+*/
+void
+f2lpdf_pdf_with_tex_text_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Process one image object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param outbb Bounding box for image.
+ @param drawdir Drawing direction.
+ @param ec Pointer to error code variable, may be NULL.
+*/
+void
+f2lpdf_pdf_with_tex_image_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int drawdir,
+ int *ec
+);
+
+/** Start new path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpdf_pdf_with_tex_newpath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Move to point.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x Point x.
+ @param y Point y.
+*/
+void
+f2lpdf_pdf_with_tex_moveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Draw line to point.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x Point x.
+ @param y Point y.
+*/
+void
+f2lpdf_pdf_with_tex_lineto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Draw curve to point.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param xcs Start control point y.
+ @param ycs Start control point y.
+ @param xce End control point x.
+ @param yce End control point y.
+ @param xe End point x.
+ @param ye End point y.
+*/
+void
+f2lpdf_pdf_with_tex_curveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double xcs,
+ double ycs,
+ double xce,
+ double yce,
+ double xe,
+ double ye
+);
+
+/** Close path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpdf_pdf_with_tex_closepath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Fill path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpdf_pdf_with_tex_fill(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Clip drawing operations to path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpdf_pdf_with_tex_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Stroke path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpdf_pdf_with_tex_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Save graphics state.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpdf_pdf_with_tex_gsave(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Restore graphics state.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpdf_pdf_with_tex_grestore(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Set color.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param r Red.
+ @param g Green.
+ @param b Blue.
+*/
+void
+f2lpdf_pdf_with_tex_setcolor(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double r,
+ double g,
+ double b
+);
+
+/** Set line width.
+ The line width is not set again if we already
+ have a current line width equal to the new line width.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param lw New line width in output coordinates.
+*/
+void
+f2lpdf_pdf_with_tex_set_line_width(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double lw
+);
+
+/** Set line style.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object to set up.
+ @param ls Line style, see @ref dk3figlinestyles.
+ @param sv Style value in output coordinates.
+ @param lw Dot length in output coordinates.
+*/
+void
+f2lpdf_pdf_with_tex_set_line_style(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int ls,
+ double sv,
+ double lw
+);
+
+/** Set line end.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param le Line end, see @ref dk3figlinecap.
+*/
+void
+f2lpdf_pdf_with_tex_set_line_end(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int le
+);
+
+/** Set line join.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param lj Line join style, see @ref dk3figlinejoin.
+*/
+void
+f2lpdf_pdf_with_tex_set_line_join(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int lj
+);
+
+/** Set current color or stroking color (PGF, PDF).
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param rgb New color value.
+*/
+void
+f2lpdf_pdf_with_tex_set_color_1(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+);
+
+/** Set non-stroking color (PGF, PDF).
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param rgb New color value.
+*/
+void
+f2lpdf_pdf_with_tex_set_color_2(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+);
+
+/** Set non-stroking color (PGF, PDF).
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param rgb New color value.
+*/
+void
+f2lpdf_pdf_with_tex_set_color_2(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+);
+
+/** Write debugging line to output file.
+ @param job Job structure.
+ @param msg Message to write to output file.
+*/
+void
+f2lpdf_pdf_with_tex_debug(
+ f2l_job_t *job,
+ char const *msg
+);
+
+/** Driver initialization for tex with pdf driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+int
+f2lpdf_tex_with_pdf_initialize(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Driver cleanup for tex with pdf driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+void
+f2lpdf_tex_with_pdf_end(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Open output files for tex with pdf driver.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+f2lpdf_tex_with_pdf_open_output_files(f2l_job_t *job);
+
+/** Close output files for tex with pdf driver.
+ @param job Job structure.
+*/
+void
+f2lpdf_tex_with_pdf_close_output_files(f2l_job_t *job);
+
+/** Write start of output for tex with pdf driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+int
+f2lpdf_tex_with_pdf_start_processing(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+
+/** Write end of output for tex with pdf driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+void
+f2lpdf_tex_with_pdf_end_processing(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+
+/** Process one text object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x Point x.
+ @param y Point y.
+*/
+void
+f2lpdf_tex_with_pdf_text_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Process one image object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param outbb Bounding box for image.
+ @param drawdir Drawing direction.
+ @param ec Pointer to error code variable, may be NULL.
+*/
+void
+f2lpdf_tex_with_pdf_image_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int drawdir,
+ int *ec
+);
+
+/** Start new path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpdf_tex_with_pdf_newpath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Move to point.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x Point x.
+ @param y Point y.
+*/
+void
+f2lpdf_tex_with_pdf_moveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Draw line to point.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x Point x.
+ @param y Point y.
+*/
+void
+f2lpdf_tex_with_pdf_lineto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Draw curve to point.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param xcs Start control point y.
+ @param ycs Start control point y.
+ @param xce End control point x.
+ @param yce End control point y.
+ @param xe End point x.
+ @param ye End point y.
+*/
+void
+f2lpdf_tex_with_pdf_curveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double xcs,
+ double ycs,
+ double xce,
+ double yce,
+ double xe,
+ double ye
+);
+
+/** Close path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpdf_tex_with_pdf_closepath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Fill path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpdf_tex_with_pdf_fill(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Clip drawing operations to path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpdf_tex_with_pdf_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Stroke path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpdf_tex_with_pdf_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Save graphics state.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpdf_tex_with_pdf_gsave(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Restore graphics state.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpdf_tex_with_pdf_grestore(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Set color.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param r Red.
+ @param g Green.
+ @param b Blue.
+*/
+void
+f2lpdf_tex_with_pdf_setcolor(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double r,
+ double g,
+ double b
+);
+
+
+/** Set line width.
+ The line width is not set again if we already
+ have a current line width equal to the new line width.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param lw New line width in output coordinates.
+*/
+void
+f2lpdf_tex_with_pdf_set_line_width(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double lw
+);
+
+/** Set line style.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object to set up.
+ @param ls Line style, see @ref dk3figlinestyles.
+ @param sv Style value in output coordinates.
+ @param lw Dot length in output coordinates.
+*/
+void
+f2lpdf_tex_with_pdf_set_line_style(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int ls,
+ double sv,
+ double lw
+);
+
+/** Set line end.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param le Line end, see @ref dk3figlinecap.
+*/
+void
+f2lpdf_tex_with_pdf_set_line_end(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int le
+);
+
+/** Set line join.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param lj Line join style, see @ref dk3figlinejoin.
+*/
+void
+f2lpdf_tex_with_pdf_set_line_join(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int lj
+);
+
+/** Set current color or stroking color (PGF, PDF).
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param rgb New color value.
+*/
+void
+f2lpdf_tex_with_pdf_set_color_1(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+);
+
+/** Set non-stroking color (PGF, PDF).
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param rgb New color value.
+*/
+void
+f2lpdf_tex_with_pdf_set_color_2(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+);
+
+/** Write debugging line to output file.
+ @param job Job structure.
+ @param msg Message to write to output file.
+*/
+void
+f2lpdf_tex_with_pdf_debug(
+ f2l_job_t *job,
+ char const *msg
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk3all.h"
+#include "dk3bezcu.h"
+#include "fig2lat.h"
+#include "f2lud.h"
+#include "f2lsvg.h"
+#include "f2lpdf.h"
+#include "dk3figto.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4vers.h"
+#include "dk3bmeo.h"
+#include "dk3bm.h"
+#include "dk3pdf.h"
+#include "dk3bif.h"
+
+
+
+$!trace-include
+
+
+
+/** Driver specific details for entire drawing.
+*/
+typedef struct {
+ dk3_pdf_t *opdf; /**< Output PDF. */
+ dk3_sto_t *sFonts; /**< Storage for fonts. */
+ dk3_sto_it_t *iFonts; /**< Iterator for font storage. */
+ dk3_sto_t *sImages; /**< Storage for image data. */
+ dk3_sto_it_t *iImages; /**< Iterator for images storage. */
+ char const *shortOutFile; /**< Short output file name. */
+ unsigned long nFonts; /**< Number of fonts in sFonts. */
+ unsigned long nImages; /**< Number of images in sImages. */
+} f2l_pdf_drawing_info_t;
+
+
+
+
+
+
+$*
+ Tool functions.
+$*
+
+
+
+/** Delete driver-specific details.
+ @param ptr Structure to delete.
+*/
+static
+void
+f2lpdf_drawing_info_delete(f2l_pdf_drawing_info_t *ptr)
+{
+ f2l_text_handling_t *th;
+ f2l_image_t *im;
+ $? "+ f2lpdf_drawing_info_delete"
+ if(ptr) {
+ dk3_release(ptr->shortOutFile);
+ if(ptr->opdf) {
+ dk3pdf_close(ptr->opdf);
+ } ptr->opdf = NULL;
+ if(ptr->sFonts) {
+ if(ptr->iFonts) {
+ dk3sto_it_reset(ptr->iFonts);
+ while(NULL != (th = (f2l_text_handling_t *)dk3sto_it_next(ptr->iFonts)))
+ {
+ dk3_delete(th);
+ }
+ dk3sto_it_close(ptr->iFonts);
+ }
+ dk3sto_close(ptr->sFonts);
+ } ptr->sFonts = NULL; ptr->iFonts = NULL;
+ if(ptr->sImages) {
+ if(ptr->iImages) {
+ dk3sto_it_reset(ptr->iImages);
+ while(NULL != (im = (f2l_image_t *)dk3sto_it_next(ptr->iImages))) {
+ f2l_tool_image_delete(im);
+ }
+ dk3sto_it_close(ptr->iImages);
+ }
+ dk3sto_close(ptr->sImages);
+ } ptr->sImages = NULL; ptr->iImages = NULL;
+ ptr->nFonts = 0UL;
+ ptr->nImages = 0UL;
+ dk3_delete(ptr);
+ } $? "- f2lpdf_drawing_info_delete"
+}
+
+
+
+/** Create structure for driver-specific details.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return Pointer to new structure on success, NULL on error.
+*/
+static
+f2l_pdf_drawing_info_t *
+f2lpdf_drawing_info_new(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw
+)
+{
+ f2l_pdf_drawing_info_t *back = NULL;
+ int ok = 0; /* Flag: No error. */
+ $? "+ f2lpdf_drawing_info_new"
+ if((job) && (drw)) {
+ back = dk3_new_app(f2l_pdf_drawing_info_t,1,job->app);
+ if(back) {
+ back->shortOutFile = NULL;
+ back->opdf = NULL;
+ back->sFonts = NULL;
+ back->iFonts = NULL;
+ back->sImages = NULL;
+ back->iImages = NULL;
+ back->nFonts = 0UL;
+ back->nImages = 0UL;
+ back->sFonts = dk3sto_open_app(job->app);
+ if(back->sFonts) {
+ dk3sto_set_comp(back->sFonts, dk3fig_tool_text_handling_compare, 0);
+ back->iFonts = dk3sto_it_open(back->sFonts);
+ if(back->iFonts) {
+ back->sImages = dk3sto_open_app(job->app);
+ if(back->sImages) {
+ dk3sto_set_comp(back->sImages, f2l_tool_compare_images, 0);
+ back->iImages = dk3sto_it_open(back->sImages);
+ if(back->iImages) {
+ back->opdf = dk3pdf_open_app(job->app);
+ if(back->opdf) {
+ ok = 1;
+ }
+ }
+ }
+ }
+ }
+ if(!(ok)) {
+ f2lpdf_drawing_info_delete(back);
+ back = NULL;
+ }
+ } else {
+ }
+ } $? "- f2lpdf_drawing_info_new PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+$*
+ PDF with LaTeX output driver.
+ This driver creates .tex/.pdf combinations to be included
+ in a .tex source.
+$*
+
+
+
+/** Register image file name in pdi for later use.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param pdi PDF information structure.
+ @param fn Image file name to add.
+ @param li Line number of image object definition.
+ @return 1 on success, 0 on error.
+*/
+static
+f2l_image_t *
+f2lpdf_register_image(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_pdf_drawing_info_t *pdi,
+ char const *fn,
+ unsigned long li
+)
+{
+ dk3_ufi_t ufi; /* Unique file identifier. */
+ f2l_image_t *back = NULL; /* Image information structure. */
+
+ if(dk3ufi_c8_get_app(&ufi, fn, job->app)) {
+ back = (f2l_image_t *)dk3sto_it_find_like(pdi->iImages, (void *)(&ufi), 1);
+ if(!(back)) {
+ back = f2l_tool_image_new(fn, job->app, li);
+ if(back) {
+ if(dk3sto_add(pdi->sImages, (void *)back)) {
+ back->imageNumber = pdi->nImages;
+ pdi->nImages += 1UL;
+ } else {
+ f2l_tool_image_delete(back);
+ back = NULL;
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ }
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ return back;
+}
+
+
+
+/** Add image XObject data to PDF.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param pdi PDF information structure.
+ @param im Image information to add.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lpdf_add_image_to_pdf(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_pdf_drawing_info_t *pdi,
+ f2l_image_t *im
+)
+{
+ dk3_bm_eps_options_t options; /* Options for PDF conversion. */
+ dk3_bif_t *bif; /* Bitmap image file. */
+ int back = 0;
+ $? "+ f2lpdf_add_image_to_pdf"
+ bif = dk3bif_open_c8_filename_app(
+ im->filename, DK3_BIF_IMAGE_TYPE_UNKNOWN, job->app
+ );
+ if(bif) {
+ dk3bmeo_init(&options);
+ options.app = job->app;
+ options.ip = 1;
+ options.jip = 0;
+ options.mode = DK3_BMEPS_MODE_PLACED_OBJECT;
+ options.szmode = DK3_BMEPS_SIZE_1_1; $? ". szmode = 1:1"
+ options.dr = DK3_BMEPS_DRIVER_PDF;
+ options.rbpc = 1;
+ options.dct = 1;
+ options.color = 1;
+ if(dk3bif_read_data(bif)) {
+ im->xo = dk3pdf_create_ixobject_progress(pdi->opdf,bif,&options,NULL,0,0);
+ im->width = dk3bif_get_width(bif);
+ im->height = dk3bif_get_height(bif);
+ im->xres = dk3bif_get_xres(bif);
+ im->yres = dk3bif_get_yres(bif);
+ if(im->xo) {
+ back = 1;
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ dk3bif_close(bif);
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ $? "- f2lpdf_add_image_to_pdf %d", back
+ return back;
+}
+
+
+
+int
+f2lpdf_pdf_with_tex_initialize(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver spec det. */
+ dk3_fig_obj_t *pobj; /* Current object. */
+ f2l_image_t *im; /* Current image. */
+ dkChar const *oldsourcefile = NULL; /* Old source file. */
+ unsigned long oldsourceline = 0UL; /* Old source line. */
+ int back = 0;
+ int ff; /* Font flags. */
+ $? "+ f2lpdf_pdf_with_tex_initialize"
+ pdi = f2lpdf_drawing_info_new(job, drw);
+ if(pdi) {
+ drw->dsd = (void *)pdi;
+ pdi->shortOutFile = dk3fig_tool_short_output_file_name(job->on2, job->app);
+ if(pdi->shortOutFile) {
+ back = 1;
+ dk3pdf_set_next_mediabox(pdi->opdf, 0L, job->lwidth, 0L, job->lheight);
+ oldsourcefile = dk3app_get_source_file(job->app);
+ oldsourceline = dk3app_get_source_line(job->app);
+ dk3sto_it_reset(drw->iobj);
+ while(NULL != (pobj = (dk3_fig_obj_t *)dk3sto_it_next(drw->iobj))) {
+ $? ". object found %d %d", pobj->ot, pobj->st
+ dk3app_set_source_line(job->app, pobj->li);
+ switch(pobj->ot) {
+ case DK3_FIG_OBJ_TEXT: {
+ ff = (pobj->dt).txt.ff;
+ if(!(ff & DK3_FIG_FONT_FLAG_HIDDEN)) { $? ". not hidden"
+ if(!(ff & DK3_FIG_FONT_FLAG_SPECIAL)) { $? ". not special"
+ if(ff & DK3_FIG_FONT_FLAG_PS) { $? ". PS font"
+ if(job->ntf) { $? ". ntf"
+ pobj->dsd = (void *)f2l_tool_register_font(
+ pdi->sFonts, pdi->iFonts, &(pdi->nFonts),
+ (pobj->dt).txt.fo, (pobj->dt).txt.fs, job->app
+ );
+ if(!(pobj->dsd)) {
+ back = 0; $? "! reg txt"
+ f2l_tool_set_exit_status(job,FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ } else { $? ". no ntf"
+ }
+ }
+ }
+ }
+ } break;
+ case DK3_FIG_OBJ_POLYLINE: {
+ if(5 == pobj->st) { $? ". image"
+ pobj->dsd =
+ (void *)f2lpdf_register_image(
+ job, drw, pdi, (pobj->dt).pol.fn, pobj->li
+ );
+ if(!(pobj->dsd)) {
+ back = 0;
+ f2l_tool_set_exit_status(job,FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ }
+ } break;
+ }
+ }
+ dk3sto_it_reset(pdi->iImages);
+ while(NULL != (im = (f2l_image_t *)dk3sto_it_next(pdi->iImages))) {
+ if(!f2lpdf_add_image_to_pdf(job, drw, pdi, im)) { $? "! add img"
+ back = 0;
+ f2l_tool_set_exit_status(job,FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ }
+ dk3app_set_source_file(job->app, oldsourcefile);
+ dk3app_set_source_line(job->app, oldsourceline);
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ } $? "- f2lpdf_pdf_with_tex_initialize %d", back
+ return back;
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_end(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ if(drw->dsd) {
+ f2lpdf_drawing_info_delete((f2l_pdf_drawing_info_t *)(drw->dsd));
+ drw->dsd = NULL;
+ }
+}
+
+
+
+int
+f2lpdf_pdf_with_tex_open_output_files(f2l_job_t *job)
+{
+ int back = 0;
+ job->of1 = dk3sf_fopen_app(job->on1, dkT("w"), job->app);
+ if(job->of1) {
+ job->of2 = dk3sf_fopen_app(job->on2, dkT("wb"), job->app);
+ if(job->of2) {
+ back = 1;
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ return back;
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_close_output_files(f2l_job_t *job)
+{
+ if(job->of2) {
+ dk3sf_fclose_app(job->of2, job->app);
+ }
+ if(job->of1) {
+ dk3sf_fclose_app(job->of1, job->app);
+ }
+}
+
+
+
+int
+f2lpdf_pdf_with_tex_start_processing(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ int back = 0;
+
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ f2l_tool_start_tex_part(
+ job->of1, job, drw, pdi->shortOutFile, pdi->iFonts, pdi->nFonts
+ );
+ if(dk3pdf_open_page_with_clip(pdi->opdf, 1)) {
+ back = 1;
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ return back;
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_end_processing(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ f2l_tool_end_tex_part(job->of1);
+ dk3pdf_close_page(pdi->opdf);
+ if(!dk3pdf_write_file(pdi->opdf, job->of2)) {
+ /* ERROR: Failed to write PDF output file! */
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_text_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ if(pdi) {
+ f2l_tool_text_object(job->of1, job, drw, obj, x, y, pdi->nFonts);
+ }
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_image_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int drawdir,
+ int *ec
+)
+{
+ dk3_coordinates_transformation_t trans; /* Graphics state transform. */
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ f2l_image_t *im; /* Current image. */
+ int res; /* Search result. */
+ $? "+ f2lpdf_pdf_with_tex_image_object"
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ im = (f2l_image_t *)(obj->dsd);
+ if((im) && (pdi)) { $? ". im and pdi ok"
+ if(im->xo) { $? ". xo ok"
+ res = dk3bm_find_transformation(
+ &trans, outbb, drawdir, (double)(im->width), (double)(im->height),
+ im->xres, im->yres, ec
+ );
+ if(res) { $? ". transformation"
+ res = dk3pdf_gsave(pdi->opdf);
+ if(!(res)) { $? "! gsave"
+ /* ERROR */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ res =
+ dk3pdf_translate_double(pdi->opdf,trans.x_translate,trans.y_translate);
+ if(!(res)) { $? "! translate"
+ /* ERROR */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ if(trans.rot) {
+ res = dk3pdf_rotate_int(pdi->opdf, (90 * trans.rot));
+ if(!(res)) { $? "! rotate"
+ /* ERROR */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ }
+ res = dk3pdf_scale_double(pdi->opdf, trans.x_scale, trans.y_scale);
+ if(!(res)) { $? "! scale"
+ /* ERROR */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ res = dk3pdf_add_xobject_to_page(pdi->opdf, im->xo);
+ if(!(res)) { $? "! add xobject to page"
+ /* ERROR */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ res = dk3pdf_grestore(pdi->opdf);
+ if(!(res)) { $? "! grestore"
+ /* ERROR */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ } else { $? "! failed to find transformation"
+ /* ERROR: Math error while searching transformation! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH); $? ". exitcode"
+ }
+ } else { $? "! xo"
+ }
+ } else { $? "! im or pdi problem"
+ } $? "- f2lpdf_pdf_with_tex_image_object"
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_newpath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ /* Do nothing, in PDF the moveto operator includes newpath. */
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_moveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ int res; /* Output operation result. */
+
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ if(pdi) {
+ res = dk3pdf_newpath_moveto(pdi->opdf, x, y);
+ if(!(res)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ }
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_lineto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ int res; /* Ouutput operation result. */
+
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ if(pdi) {
+ res = dk3pdf_lineto(pdi->opdf, x, y);
+ if(!(res)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ }
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_curveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double xcs,
+ double ycs,
+ double xce,
+ double yce,
+ double xe,
+ double ye
+)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ int res; /* Output operation result. */
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ if(pdi) {
+ res = dk3pdf_curveto(pdi->opdf, xcs, ycs, xce, yce, xe, ye);
+ if(!(res)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ }
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_closepath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ int res; /* Output operation result. */
+
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ if(pdi) {
+ res = dk3pdf_closepath(pdi->opdf);
+ if(!(res)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ }
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_fill(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ int res; /* Output operation result. */
+
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ if(pdi) {
+ res = dk3pdf_fill_eo(pdi->opdf);
+ if(!(res)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ }
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ int res; /* Output operation result. */
+
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ if(pdi) {
+ res = dk3pdf_clip_eo(pdi->opdf);
+ if(!(res)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ }
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ int res; /* Output operation result. */
+
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ if(pdi) {
+ res = dk3pdf_stroke(pdi->opdf);
+ if(!(res)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ }
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_gsave(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ int res; /* Output operation result. */
+
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ if(pdi) {
+ res = dk3pdf_gsave(pdi->opdf);
+ if(!(res)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ }
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_grestore(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ int res; /* Output operation result. */
+
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ if(pdi) {
+ res = dk3pdf_grestore(pdi->opdf);
+ if(!(res)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ }
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_setcolor(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double r,
+ double g,
+ double b
+)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ int res; /* Output operation result. */
+
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ if(pdi) {
+ res = dk3pdf_nonstroking_rgb(pdi->opdf, r, g, b);
+ if(!(res)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ res = dk3pdf_stroking_rgb(pdi->opdf, r, g, b);
+ if(!(res)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ }
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_set_line_width(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double lw
+)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ int res; /* Output operation result. */
+
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ if(pdi) {
+ res = dk3pdf_set_linewidth(pdi->opdf, lw);
+ if(!(res)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ }
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_set_line_style(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int ls,
+ double sv,
+ double lw
+)
+{
+ double xsv[32]; /* Strokes and gaps lengths. */
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ double ph; /* Phase. */
+ double gw; /* Gap width. */
+ size_t nsv; /* Number of elements xsv. */
+ int res; /* Output operation result. */
+
+ ph = 0.0;
+ nsv = 0;
+ xsv[0] = 0.0;
+ gw = f2lto_find_gap_length(job, lw, sv);
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ if(pdi) {
+ switch(ls) {
+ case DK3_FIG_LS_DASH_TRIPLE_DOTTED: {
+ xsv[0] = sv;
+ xsv[1] = gw;
+ xsv[2] = lw;
+ xsv[3] = gw;
+ xsv[4] = lw;
+ xsv[5] = gw;
+ xsv[6] = lw;
+ xsv[7] = gw;
+ nsv = 8;
+ } break;
+ case DK3_FIG_LS_DASH_DOUBLE_DOTTED: {
+ xsv[0] = sv;
+ xsv[1] = gw;
+ xsv[2] = lw;
+ xsv[3] = gw;
+ xsv[4] = lw;
+ xsv[5] = gw;
+ nsv = 6;
+ } break;
+ case DK3_FIG_LS_DASH_DOTTED: {
+ xsv[0] = sv;
+ xsv[1] = gw;
+ xsv[2] = lw;
+ xsv[3] = gw;
+ nsv = 4;
+ } break;
+ case DK3_FIG_LS_DOTTED: {
+ xsv[0] = lw; xsv[1] = gw;
+ nsv = 2;
+ } break;
+ case DK3_FIG_LS_DASHED: {
+ xsv[0] = sv; xsv[1] = gw;
+ nsv = 2;
+ } break;
+ }
+ res = dk3pdf_set_line_dash(pdi->opdf, xsv, nsv, ph);
+ if(!(res)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ }
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_set_line_end(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int le
+)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ int res; /* Output operation result. */
+
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ if(pdi) {
+ res = dk3pdf_set_linecap(pdi->opdf, le);
+ if(!(res)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ }
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_set_line_join(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int lj
+)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ int res; /* Output operation result. */
+
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ if(pdi) {
+ res = dk3pdf_set_linejoin(pdi->opdf, lj);
+ if(!(res)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ }
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_set_color_1(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ int res; /* Output operation result. */
+
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ if(pdi) {
+ res = dk3pdf_stroking_rgb(pdi->opdf, rgb->r, rgb->g, rgb->b);
+ if(!(res)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ }
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_set_color_2(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ int res; /* Output operation result. */
+
+ pdi = (f2l_pdf_drawing_info_t *)(drw->dsd);
+ if(pdi) {
+ res = dk3pdf_nonstroking_rgb(pdi->opdf, rgb->r, rgb->g, rgb->b);
+ if(!(res)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ }
+}
+
+
+
+void
+f2lpdf_pdf_with_tex_debug(
+ f2l_job_t *job,
+ char const *msg
+)
+{
+ f2l_pdf_drawing_info_t *pdi; /* Driver specific details. */
+ int res; /* Output operation result. */
+
+ pdi = (f2l_pdf_drawing_info_t *)((job->drw)->dsd);
+ if(pdi) {
+ res = dk3pdf_write_debug_line(pdi->opdf, msg);
+ if(!(res)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ }
+}
+
+
+
+$*
+ LaTeX with PDF output driver.
+ This driver combines .tex/.pdf combinations to be
+ processed with pdflatex directly.
+$*
+
+
+
+int
+f2lpdf_tex_with_pdf_initialize(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ int back = 0;
+ back = f2lpdf_pdf_with_tex_initialize(job, drw);
+ return back;
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_end(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ f2lpdf_pdf_with_tex_end(job, drw);
+}
+
+
+
+int
+f2lpdf_tex_with_pdf_open_output_files(f2l_job_t *job)
+{
+ int back = 0;
+ back = f2lpdf_pdf_with_tex_open_output_files(job);
+ return back;
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_close_output_files(f2l_job_t *job)
+{
+ f2lpdf_pdf_with_tex_close_output_files(job);
+}
+
+
+
+int
+f2lpdf_tex_with_pdf_start_processing(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ int back = 0;
+ f2l_tool_begin_latex_document(job->of1, job, drw);
+ back = f2lpdf_pdf_with_tex_start_processing(job, drw);
+ return back;
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_end_processing(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ f2lpdf_pdf_with_tex_end_processing(job, drw);
+ f2l_tool_end_latex_document(job->of1, job, drw);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_text_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+ f2lpdf_pdf_with_tex_text_object(job, drw, obj, x, y);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_image_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int drawdir,
+ int *ec
+)
+{
+ f2lpdf_pdf_with_tex_image_object(job, drw, obj, outbb, drawdir, ec);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_newpath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2lpdf_pdf_with_tex_newpath(job, drw, obj);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_moveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+ f2lpdf_pdf_with_tex_moveto(job, drw, obj, x, y);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_lineto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+ f2lpdf_pdf_with_tex_lineto(job, drw, obj, x, y);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_curveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double xcs,
+ double ycs,
+ double xce,
+ double yce,
+ double xe,
+ double ye
+)
+{
+ f2lpdf_pdf_with_tex_curveto(job, drw, obj, xcs, ycs, xce, yce, xe, ye);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_closepath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2lpdf_pdf_with_tex_closepath(job, drw, obj);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_fill(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2lpdf_pdf_with_tex_fill(job, drw, obj);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2lpdf_pdf_with_tex_clip(job, drw, obj);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2lpdf_pdf_with_tex_stroke(job, drw, obj);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_gsave(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2lpdf_pdf_with_tex_gsave(job, drw, obj);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_grestore(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2lpdf_pdf_with_tex_grestore(job, drw, obj);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_setcolor(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double r,
+ double g,
+ double b
+)
+{
+ f2lpdf_pdf_with_tex_setcolor(job, drw, obj, r, g, b);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_set_line_width(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double lw
+)
+{
+ f2lpdf_pdf_with_tex_set_line_width(job, drw, obj, lw);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_set_line_style(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int ls,
+ double sv,
+ double lw
+)
+{
+ f2lpdf_pdf_with_tex_set_line_style(job, drw, obj, ls, sv, lw);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_set_line_end(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int le
+)
+{
+ f2lpdf_pdf_with_tex_set_line_end(job, drw, obj, le);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_set_line_join(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int lj
+)
+{
+ f2lpdf_pdf_with_tex_set_line_join(job, drw, obj, lj);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_set_color_1(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+)
+{
+ f2lpdf_pdf_with_tex_set_color_1(job, drw, rgb);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_set_color_2(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+)
+{
+ f2lpdf_pdf_with_tex_set_color_2(job, drw, rgb);
+}
+
+
+
+void
+f2lpdf_tex_with_pdf_debug(
+ f2l_job_t *job,
+ char const *msg
+)
+{
+ f2lpdf_pdf_with_tex_debug(job, msg);
+}
+
diff --git a/support/dktools/f2lpdf.h b/support/dktools/f2lpdf.h
new file mode 100644
index 0000000000..23ad01922d
--- /dev/null
+++ b/support/dktools/f2lpdf.h
@@ -0,0 +1,734 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: f2lpdf.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file f2lpdf.h Header file for the f2lpdf module.
+*/
+
+#ifndef F2LPDF_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define F2LPDF_H_INCLUDED 1
+
+
+#line 10 "f2lpdf.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Driver initialization for pdf with tex driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+int
+f2lpdf_pdf_with_tex_initialize(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Driver cleanup for pdf with tex driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+void
+f2lpdf_pdf_with_tex_end(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Open output files for pdf with tex driver.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+f2lpdf_pdf_with_tex_open_output_files(f2l_job_t *job);
+
+/** Close output files for pdf with tex driver.
+ @param job Job structure.
+*/
+void
+f2lpdf_pdf_with_tex_close_output_files(f2l_job_t *job);
+
+/** Write start of output for pdf with tex driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+int
+f2lpdf_pdf_with_tex_start_processing(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Write end of output for pdf with tex driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+void
+f2lpdf_pdf_with_tex_end_processing(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Process one text object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x Point x.
+ @param y Point y.
+*/
+void
+f2lpdf_pdf_with_tex_text_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Process one image object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param outbb Bounding box for image.
+ @param drawdir Drawing direction.
+ @param ec Pointer to error code variable, may be NULL.
+*/
+void
+f2lpdf_pdf_with_tex_image_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int drawdir,
+ int *ec
+);
+
+/** Start new path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpdf_pdf_with_tex_newpath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Move to point.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x Point x.
+ @param y Point y.
+*/
+void
+f2lpdf_pdf_with_tex_moveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Draw line to point.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x Point x.
+ @param y Point y.
+*/
+void
+f2lpdf_pdf_with_tex_lineto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Draw curve to point.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param xcs Start control point y.
+ @param ycs Start control point y.
+ @param xce End control point x.
+ @param yce End control point y.
+ @param xe End point x.
+ @param ye End point y.
+*/
+void
+f2lpdf_pdf_with_tex_curveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double xcs,
+ double ycs,
+ double xce,
+ double yce,
+ double xe,
+ double ye
+);
+
+/** Close path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpdf_pdf_with_tex_closepath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Fill path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpdf_pdf_with_tex_fill(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Clip drawing operations to path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpdf_pdf_with_tex_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Stroke path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpdf_pdf_with_tex_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Save graphics state.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpdf_pdf_with_tex_gsave(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Restore graphics state.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpdf_pdf_with_tex_grestore(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Set color.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param r Red.
+ @param g Green.
+ @param b Blue.
+*/
+void
+f2lpdf_pdf_with_tex_setcolor(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double r,
+ double g,
+ double b
+);
+
+/** Set line width.
+ The line width is not set again if we already
+ have a current line width equal to the new line width.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param lw New line width in output coordinates.
+*/
+void
+f2lpdf_pdf_with_tex_set_line_width(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double lw
+);
+
+/** Set line style.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object to set up.
+ @param ls Line style, see @ref dk3figlinestyles.
+ @param sv Style value in output coordinates.
+ @param lw Dot length in output coordinates.
+*/
+void
+f2lpdf_pdf_with_tex_set_line_style(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int ls,
+ double sv,
+ double lw
+);
+
+/** Set line end.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param le Line end, see @ref dk3figlinecap.
+*/
+void
+f2lpdf_pdf_with_tex_set_line_end(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int le
+);
+
+/** Set line join.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param lj Line join style, see @ref dk3figlinejoin.
+*/
+void
+f2lpdf_pdf_with_tex_set_line_join(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int lj
+);
+
+/** Set current color or stroking color (PGF, PDF).
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param rgb New color value.
+*/
+void
+f2lpdf_pdf_with_tex_set_color_1(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+);
+
+/** Set non-stroking color (PGF, PDF).
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param rgb New color value.
+*/
+void
+f2lpdf_pdf_with_tex_set_color_2(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+);
+
+/** Set non-stroking color (PGF, PDF).
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param rgb New color value.
+*/
+void
+f2lpdf_pdf_with_tex_set_color_2(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+);
+
+/** Write debugging line to output file.
+ @param job Job structure.
+ @param msg Message to write to output file.
+*/
+void
+f2lpdf_pdf_with_tex_debug(
+ f2l_job_t *job,
+ char const *msg
+);
+
+/** Driver initialization for tex with pdf driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+int
+f2lpdf_tex_with_pdf_initialize(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Driver cleanup for tex with pdf driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+void
+f2lpdf_tex_with_pdf_end(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Open output files for tex with pdf driver.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+f2lpdf_tex_with_pdf_open_output_files(f2l_job_t *job);
+
+/** Close output files for tex with pdf driver.
+ @param job Job structure.
+*/
+void
+f2lpdf_tex_with_pdf_close_output_files(f2l_job_t *job);
+
+/** Write start of output for tex with pdf driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+int
+f2lpdf_tex_with_pdf_start_processing(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+
+/** Write end of output for tex with pdf driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+void
+f2lpdf_tex_with_pdf_end_processing(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+
+/** Process one text object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x Point x.
+ @param y Point y.
+*/
+void
+f2lpdf_tex_with_pdf_text_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Process one image object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param outbb Bounding box for image.
+ @param drawdir Drawing direction.
+ @param ec Pointer to error code variable, may be NULL.
+*/
+void
+f2lpdf_tex_with_pdf_image_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int drawdir,
+ int *ec
+);
+
+/** Start new path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpdf_tex_with_pdf_newpath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Move to point.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x Point x.
+ @param y Point y.
+*/
+void
+f2lpdf_tex_with_pdf_moveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Draw line to point.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x Point x.
+ @param y Point y.
+*/
+void
+f2lpdf_tex_with_pdf_lineto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Draw curve to point.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param xcs Start control point y.
+ @param ycs Start control point y.
+ @param xce End control point x.
+ @param yce End control point y.
+ @param xe End point x.
+ @param ye End point y.
+*/
+void
+f2lpdf_tex_with_pdf_curveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double xcs,
+ double ycs,
+ double xce,
+ double yce,
+ double xe,
+ double ye
+);
+
+/** Close path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpdf_tex_with_pdf_closepath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Fill path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpdf_tex_with_pdf_fill(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Clip drawing operations to path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpdf_tex_with_pdf_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Stroke path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpdf_tex_with_pdf_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Save graphics state.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpdf_tex_with_pdf_gsave(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Restore graphics state.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpdf_tex_with_pdf_grestore(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Set color.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param r Red.
+ @param g Green.
+ @param b Blue.
+*/
+void
+f2lpdf_tex_with_pdf_setcolor(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double r,
+ double g,
+ double b
+);
+
+
+/** Set line width.
+ The line width is not set again if we already
+ have a current line width equal to the new line width.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param lw New line width in output coordinates.
+*/
+void
+f2lpdf_tex_with_pdf_set_line_width(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double lw
+);
+
+/** Set line style.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object to set up.
+ @param ls Line style, see @ref dk3figlinestyles.
+ @param sv Style value in output coordinates.
+ @param lw Dot length in output coordinates.
+*/
+void
+f2lpdf_tex_with_pdf_set_line_style(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int ls,
+ double sv,
+ double lw
+);
+
+/** Set line end.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param le Line end, see @ref dk3figlinecap.
+*/
+void
+f2lpdf_tex_with_pdf_set_line_end(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int le
+);
+
+/** Set line join.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param lj Line join style, see @ref dk3figlinejoin.
+*/
+void
+f2lpdf_tex_with_pdf_set_line_join(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int lj
+);
+
+/** Set current color or stroking color (PGF, PDF).
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param rgb New color value.
+*/
+void
+f2lpdf_tex_with_pdf_set_color_1(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+);
+
+/** Set non-stroking color (PGF, PDF).
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param rgb New color value.
+*/
+void
+f2lpdf_tex_with_pdf_set_color_2(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+);
+
+/** Write debugging line to output file.
+ @param job Job structure.
+ @param msg Message to write to output file.
+*/
+void
+f2lpdf_tex_with_pdf_debug(
+ f2l_job_t *job,
+ char const *msg
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/f2lpgf.c b/support/dktools/f2lpgf.c
new file mode 100644
index 0000000000..62b6c5a2ef
--- /dev/null
+++ b/support/dktools/f2lpgf.c
@@ -0,0 +1,1630 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: f2lpgf.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file f2lpgf.c The f2lpgf module.
+*/
+
+
+#line 756 "f2lpgf.ctr"
+
+#include "dk3all.h"
+#include "dk3bezcu.h"
+#include "fig2lat.h"
+#include "f2lud.h"
+#include "f2lsvg.h"
+#include "f2lpgf.h"
+#include "dk3figto.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4vers.h"
+#include "dk3bif.h"
+#include "dk3bm.h"
+#include "dk3figto.h"
+
+
+
+
+
+#line 775 "f2lpgf.ctr"
+
+
+
+/** Driver specific details for entire drawing.
+*/
+typedef struct {
+ dk3_sto_t *sFonts; /**< Storage for fonts. */
+ dk3_sto_it_t *iFonts; /**< Iterator for font storage. */
+ unsigned long nFonts; /**< Number of fonts in sFonts. */
+} f2l_pgf_drawing_info_t;
+
+
+
+/** Keywords used by the module.
+*/
+static char const * const f2lpgf_c8_kw[] = {
+/* 0 */
+"\n",
+
+/* 1 */
+" ",
+
+/* 2 */
+"\\begin{pgfpicture}\n",
+
+/* 3 */
+"\\end{pgfpicture}%\n",
+
+/* 4 */
+"\\begin{pgfscope}\n",
+
+/* 5 */
+"\\end{pgfscope}\n",
+
+/* 6 */
+"\\pgfpathrectangle{\\pgfpointorigin}{",
+
+/* 7 */
+"}\n",
+
+/* 8 */
+"\\pgfpoint{",
+
+/* 9 */
+",",
+
+/* 10 */
+"}",
+
+/* 11 */
+"\\pgfpoint{%ldbp}{%ldbp}",
+
+/* 12 */
+"bp",
+
+/* 13 */
+"\\pgfusepath{use as bounding box}\n",
+
+/* 14 */
+"\\pgfusepath{clip}\n",
+
+/* 15 */
+"\\pgfseteorule\n",
+
+/* 16 */
+"\\pgfpathmoveto{",
+
+/* 17 */
+"\\pgfpathlineto{",
+
+/* 18 */
+"\\pgfpathcurveto{",
+
+/* 19 */
+"}{",
+
+/* 20 */
+"\\pgfpathclose\n",
+
+/* 21 */
+"\\pgfusepath{fill}\n",
+
+/* 22 */
+"\\pgfusepath{fill,stroke}\n",
+
+/* 23 */
+"\\pgfusepath{fill,clip}\n",
+
+/* 24 */
+"\\pgfusepath{fill,stroke,clip}\n",
+
+/* 25 */
+"\\pgfusepath{stroke}\n",
+
+/* 26 */
+"\\pgfsetlinewidth{",
+
+/* 27 */
+"\\pgfsetdash{",
+
+/* 28 */
+"{",
+
+/* 29 */
+"\\pgfsetrectcap\n",
+
+/* 30 */
+"\\pgfsetroundcap\n",
+
+/* 31 */
+"\\pgfsetbuttcap\n",
+
+/* 32 */
+"\\pgfsetbeveljoin\n",
+
+/* 33 */
+"\\pgfsetroundjoin\n",
+
+/* 34 */
+"\\pgfsetmiterjoin\n",
+
+/* 35 */
+"\\definecolor{FigToLatColorS}{rgb}{",
+
+/* 36 */
+"\\definecolor{FigToLatColorN}{rgb}{",
+
+/* 37 */
+"\\pgfsetstrokecolor{FigToLatColorS}\n",
+
+/* 38 */
+"\\pgfsetfillcolor{FigToLatColorN}\n",
+
+/* 39 */
+"% ",
+
+/* 40 */
+"\\pgftransformshift{",
+
+/* 41 */
+"\\pgftransformrotate{%d}\n",
+
+/* 42 */
+"\\pgftransformxscale{",
+
+/* 43 */
+"\\pgftransformyscale{",
+
+/* 44 */
+"\\pgftext[left,base,at={\\pgfpointorigin}]{\\pgfimage[interpolate=true,width=1bp,height=1bp]{",
+
+/* 45 */
+"}}\n",
+
+/* 46 */
+"\\pgftext[",
+
+/* 47 */
+"]{",
+
+/* 48 */
+"base,left",
+
+/* 49 */
+"base",
+
+/* 50 */
+"base,right",
+
+/* 51 */
+",at={",
+
+/* 52 */
+",rotate=",
+
+NULL
+
+
+#line 1005 "f2lpgf.ctr"
+};
+
+
+/* ************************************************************************ */
+/* * * */
+/* * Tool functions * */
+/* * * */
+/* ************************************************************************ */
+
+
+#line 1011 "f2lpgf.ctr"
+
+
+
+/** Delete driver-specific details.
+ @param ptr Details structure to delete.
+*/
+static
+void
+f2lpgf_pdi_delete(f2l_pgf_drawing_info_t *ptr)
+{
+ void *vptr; /* Current text handling structure to delete. */
+
+ if(ptr) {
+ if(ptr->sFonts) {
+ if(ptr->iFonts) {
+ dk3sto_it_reset(ptr->iFonts);
+ while(NULL != (vptr = dk3sto_it_next(ptr->iFonts))) {
+ dk3_delete(vptr);
+ }
+ dk3sto_it_close(ptr->iFonts);
+ }
+ dk3sto_close(ptr->sFonts);
+ } ptr->sFonts = NULL; ptr->iFonts = NULL; ptr->nFonts = 0UL;
+ dk3_delete(ptr);
+ }
+}
+
+
+
+/** Create structure for driver-specific details.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return Pointer to new structure on success, NULL on error.
+*/
+static
+f2l_pgf_drawing_info_t *
+f2lpgf_pdi_new(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ f2l_pgf_drawing_info_t *back = NULL;
+ int ok = 0;
+ back = dk3_new_app(f2l_pgf_drawing_info_t,1,job->app);
+ if(back) {
+ back->sFonts = NULL; back->iFonts = NULL; back->nFonts = 0UL;
+ back->sFonts = dk3sto_open_app(job->app);
+ if(back->sFonts) {
+ dk3sto_set_comp(back->sFonts, dk3fig_tool_text_handling_compare, 0);
+ back->iFonts = dk3sto_it_open(back->sFonts);
+ if(back->iFonts) {
+ ok = 1;
+ }
+ }
+ if(!(ok)) {
+ f2lpgf_pdi_delete(back);
+ back = NULL;
+ }
+ } else {
+ }
+ return back;
+}
+
+
+
+/** Write point (long coordinates).
+ @param of Output file.
+ @param x X position.
+ @param y X position.
+*/
+static
+void
+f2lpgf_write_point_long(FILE *of, long x, long y)
+{
+ fprintf(of, f2lpgf_c8_kw[11], x, y);
+}
+
+
+
+/** Write point (double coordinates).
+ @param of Output file.
+ @param x X position.
+ @param y Y position.
+*/
+static
+void
+f2lpgf_write_point_double(FILE *of, double x, double y)
+{
+ fputs(f2lpgf_c8_kw[8], of);
+ dk3ma_print_double_c8_no_sci(of, x);
+ fputs(f2lpgf_c8_kw[12], of);
+ fputs(f2lpgf_c8_kw[19], of);
+ dk3ma_print_double_c8_no_sci(of, y);
+ fputs(f2lpgf_c8_kw[12], of);
+ fputs(f2lpgf_c8_kw[10], of);
+}
+
+
+
+/** Set line dash.
+ @param of Output file.
+ @param xsv Stroke and gap lengths.
+ @param nsv Number of elements in xsv.
+ @param ph Phase (Used length at start of line).
+*/
+static
+void
+f2lpgf_set_line_dash(FILE *of, double *xsv, size_t nsv, double ph)
+{
+ size_t i; /* Index to traverse xsv. */
+
+ fputs(f2lpgf_c8_kw[27], of);
+ for(i = 0; i < nsv; i++) {
+ fputs(f2lpgf_c8_kw[28], of);
+ dk3ma_print_double_c8_no_sci(of, xsv[i]);
+ fputs(f2lpgf_c8_kw[12], of);
+ fputs(f2lpgf_c8_kw[10], of);
+ }
+ fputs(f2lpgf_c8_kw[19], of);
+ dk3ma_print_double_c8_no_sci(of, ph);
+ fputs(f2lpgf_c8_kw[12], of);
+ fputs(f2lpgf_c8_kw[7], of);
+}
+
+
+
+/** Define current color.
+ @param of Output file.
+ @param tp Color type.
+ @param rgb RGB color structure.
+*/
+static
+void
+f2lpgf_define_color(FILE *of, int tp, dk3_rgb_color_t *rgb)
+{
+ fputs(f2lpgf_c8_kw[((tp) ? 36 : 35)], of);
+ dk3ma_print_double_c8_no_sci(of, rgb->r);
+ fputs(f2lpgf_c8_kw[9], of);
+ dk3ma_print_double_c8_no_sci(of, rgb->g);
+ fputs(f2lpgf_c8_kw[9], of);
+ dk3ma_print_double_c8_no_sci(of, rgb->b);
+ fputs(f2lpgf_c8_kw[10], of);
+}
+
+
+
+/** Write image file name to output file.
+ @param of Output file.
+ @param fn File name.
+*/
+static
+void
+fl2pgf_image_file_name(FILE *of, char const *fn)
+{
+ char const *ptr; /* Current character to process. */
+
+ ptr = fn;
+ while(*ptr) {
+ switch(*ptr) {
+ case '\\': {
+ fputc('/', of);
+ } break;
+ default: {
+ fputc(*ptr, of);
+ } break;
+ }
+ ptr++;
+ }
+}
+
+
+
+/** Write text rotation angle.
+ @param of Output file.
+ @param rot Rotation in radians.
+ @param job Job structure.
+*/
+static
+void
+f2lpgf_write_text_rotation(FILE *of, double rot, f2l_job_t *job)
+{
+ int ec = 0; /* Mathematical error code. */
+ double an; /* Rotation in degree. */
+ double ri; /* Integer value of an. */
+
+ if(1.0e-6 < fabs(rot)) {
+ an = dk3ma_d_mul_ok(rot, 180.0, &ec) / M_PI;
+ ri = dk3ma_d_rint(an);
+#if 0
+ if(1.0e-3 > fabs(dk3ma_d_rint(dk3ma_d_sub_ok(an, ri, &ec)))) {
+ an = ri;
+ }
+#else
+ /* 2013-01-27: The rint result in the code above is always 0.
+ */
+ if(1.0e-3 > fabs(dk3ma_d_sub_ok(an, ri, &ec))) {
+ an = ri;
+ }
+#endif
+ fputs(f2lpgf_c8_kw[52], of);
+ dk3ma_print_double_c8_no_sci(of, an);
+ if(ec) {
+ /* ERROR: Math error */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
+
+#line 1213 "f2lpgf.ctr"
+ }
+ }
+}
+
+
+
+/* ************************************************************************ */
+/* * * */
+/* * PGF output driver functions * */
+/* * * */
+/* ************************************************************************ */
+
+
+#line 1222 "f2lpgf.ctr"
+
+int
+f2lpgf_pgf_initialize(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+
+ f2l_pgf_drawing_info_t *pdi = NULL; /* Driver spec det. */
+ dkChar const *oldsourcefile = NULL; /* Source file name. */
+ dk3_fig_obj_t *pobj; /* Current object. */
+ unsigned long oldsourceline = 0UL; /* Source file line. */
+ int ff = 0; /* Font flags. */
+ int back = 0;
+
+
+#line 1234 "f2lpgf.ctr"
+ if((job) && (drw)) {
+ pdi = f2lpgf_pdi_new(job, drw);
+ if(pdi) {
+ drw->dsd = (void *)pdi;
+ back = 1;
+ oldsourcefile = dk3app_get_source_file(job->app);
+ oldsourceline = dk3app_get_source_line(job->app);
+ dk3sto_it_reset(drw->iobj);
+ while(NULL != (pobj = (dk3_fig_obj_t *)dk3sto_it_next(drw->iobj))) {
+ dk3app_set_source_line(job->app, pobj->li);
+ switch(pobj->ot) {
+ case DK3_FIG_OBJ_TEXT: {
+
+#line 1246 "f2lpgf.ctr"
+ ff = (pobj->dt).txt.ff;
+ if(!(ff & DK3_FIG_FONT_FLAG_HIDDEN)) {
+
+#line 1248 "f2lpgf.ctr"
+ if(!(ff & DK3_FIG_FONT_FLAG_SPECIAL)) {
+
+#line 1249 "f2lpgf.ctr"
+ if(ff & DK3_FIG_FONT_FLAG_PS) {
+
+#line 1250 "f2lpgf.ctr"
+ if(job->ntf) {
+
+#line 1251 "f2lpgf.ctr"
+ pobj->dsd = (void *)f2l_tool_register_font(
+ pdi->sFonts, pdi->iFonts, &(pdi->nFonts),
+ (pobj->dt).txt.fo, (pobj->dt).txt.fs, job->app
+ );
+ if(!(pobj->dsd)) {
+ back = 0;
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1258 "f2lpgf.ctr"
+ }
+ } else {
+
+#line 1260 "f2lpgf.ctr"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ dk3app_set_source_file(job->app, oldsourcefile);
+ dk3app_set_source_line(job->app, oldsourceline);
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1271 "f2lpgf.ctr"
+ }
+ }
+
+#line 1273 "f2lpgf.ctr"
+ return back;
+}
+
+
+
+void
+f2lpgf_pgf_end(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+
+
+#line 1282 "f2lpgf.ctr"
+ if((job) && (drw)) {
+ if(drw->dsd) {
+ f2lpgf_pdi_delete((f2l_pgf_drawing_info_t *)(drw->dsd));
+ }
+ }
+
+#line 1287 "f2lpgf.ctr"
+}
+
+
+
+int
+f2lpgf_pgf_open_output_files(f2l_job_t *job)
+{
+ int back = 0;
+
+
+#line 1296 "f2lpgf.ctr"
+ job->of1 = dk3sf_fopen_app(job->on1, dkT("w"), job->app);
+ if(job->of1) {
+ back = 1;
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1301 "f2lpgf.ctr"
+ }
+
+
+#line 1303 "f2lpgf.ctr"
+ return back;
+}
+
+
+
+void
+f2lpgf_pgf_close_output_files(f2l_job_t *job)
+{
+
+
+#line 1312 "f2lpgf.ctr"
+ if(job->of1) {
+ dk3sf_fclose_app(job->of1, job->app);
+ }
+
+
+#line 1316 "f2lpgf.ctr"
+}
+
+
+
+int
+f2lpgf_pgf_start_processing(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ f2l_pgf_drawing_info_t *pdi; /* Driver specific details. */
+ int back = 0;
+
+
+#line 1326 "f2lpgf.ctr"
+ pdi = (f2l_pgf_drawing_info_t *)(drw->dsd);
+ if(pdi) {
+
+#line 1328 "f2lpgf.ctr"
+ back = 1;
+ /* Font definitions */
+ f2l_tool_start_tex_part_with_picture(
+ job->of1, job, drw, NULL, pdi->iFonts, pdi->nFonts, 0
+ );
+ } else {
+
+#line 1334 "f2lpgf.ctr"
+ }
+ fputs(f2lpgf_c8_kw[2], job->of1);
+ /* Bounding box */
+ fputs(f2lpgf_c8_kw[6], job->of1);
+ f2lpgf_write_point_long(job->of1, job->lwidth, job->lheight);
+ fputs(f2lpgf_c8_kw[7], job->of1);
+ fputs(f2lpgf_c8_kw[13], job->of1);
+ fputs(f2lpgf_c8_kw[15], job->of1);
+ /* Begin PGF scope */
+ fputs(f2lpgf_c8_kw[4], job->of1);
+ /* Clip path */
+ fputs(f2lpgf_c8_kw[6], job->of1);
+ f2lpgf_write_point_long(job->of1, job->lwidth, job->lheight);
+ fputs(f2lpgf_c8_kw[7], job->of1);
+ fputs(f2lpgf_c8_kw[14], job->of1);
+
+
+#line 1350 "f2lpgf.ctr"
+ return back;
+}
+
+
+
+void
+f2lpgf_pgf_end_processing(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+
+
+#line 1359 "f2lpgf.ctr"
+ /* End PGF scope */
+ fputs(f2lpgf_c8_kw[5], job->of1);
+ /* End PGF picture */
+ fputs(f2lpgf_c8_kw[3], job->of1);
+
+
+#line 1364 "f2lpgf.ctr"
+}
+
+
+
+void
+f2lpgf_pgf_text_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+ f2l_pgf_drawing_info_t *pdi = NULL; /* Driver specific details. */
+ unsigned long nFonts = 0UL; /* Number of text handlings. */
+
+
+#line 1380 "f2lpgf.ctr"
+ pdi = (f2l_pgf_drawing_info_t *)(drw->dsd);
+ if(pdi) { nFonts = pdi->nFonts; }
+ fputs(f2lpgf_c8_kw[46], job->of1);
+ /* align */
+ switch(obj->st) {
+ case 2: {
+ fputs(f2lpgf_c8_kw[50], job->of1);
+ } break;
+ case 1: {
+ fputs(f2lpgf_c8_kw[49], job->of1);
+ } break;
+ default: {
+ fputs(f2lpgf_c8_kw[48], job->of1);
+ } break;
+ }
+ /* position */
+ fputs(f2lpgf_c8_kw[51], job->of1);
+ f2lpgf_write_point_double(job->of1, x, y);
+ fputs(f2lpgf_c8_kw[10], job->of1);
+ /* rotation */
+ f2lpgf_write_text_rotation(job->of1, (obj->dt).txt.an, job);
+ fputs(f2lpgf_c8_kw[47], job->of1);
+ /* text */
+ f2l_tool_inner_text_object(job->of1, job, drw, obj, nFonts);
+ fputs(f2lpgf_c8_kw[7], job->of1);
+ (job->gs).hc1 = 0; (job->gs).hc2 = 0;
+
+
+#line 1407 "f2lpgf.ctr"
+}
+
+
+
+void
+f2lpgf_pgf_image_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int drawdir,
+ int *ec
+)
+{
+ dk3_coordinates_transformation_t trans; /* Graphics state tr. */
+ dk3_bif_t *bif; /* Bitmap image file. */
+ double w = 0.0; /* Image width. */
+ double h = 0.0; /* Image height. */
+ double xres = -1.0; /* X resolution, none by default. */
+ double yres = -1.0; /* Y resolution, none by default. */
+ int res = 0; /* Result from transformation search. */
+
+
+#line 1429 "f2lpgf.ctr"
+ if((obj->dt).pol.fn) {
+ bif = dk3bif_open_c8_filename_app(
+ (obj->dt).pol.fn, DK3_BIF_IMAGE_TYPE_UNKNOWN, job->app
+ );
+ if(bif) {
+ w = (double)dk3bif_get_width(bif);
+ h = (double)dk3bif_get_height(bif);
+ xres = dk3bif_get_xres(bif);
+ yres = dk3bif_get_yres(bif);
+ dk3bif_close(bif);
+ res = dk3bm_find_transformation(
+ &trans, outbb, drawdir, w, h, xres, yres, ec
+ );
+ if(res) {
+ /* gsave */
+ fputs(f2lpgf_c8_kw[4], job->of1);
+ /* translate */
+ fputs(f2lpgf_c8_kw[40], job->of1);
+ f2lpgf_write_point_double(
+ job->of1, trans.x_translate, trans.y_translate
+ );
+ fputs(f2lpgf_c8_kw[7], job->of1);
+ /* rotate */
+ if(trans.rot) {
+ fprintf(job->of1, f2lpgf_c8_kw[41], 90 * trans.rot);
+ }
+ /* scale */
+ fputs(f2lpgf_c8_kw[42], job->of1);
+ dk3ma_print_double_c8_no_sci(job->of1, trans.x_scale);
+ fputs(f2lpgf_c8_kw[7], job->of1);
+ fputs(f2lpgf_c8_kw[43], job->of1);
+ dk3ma_print_double_c8_no_sci(job->of1, trans.y_scale);
+ fputs(f2lpgf_c8_kw[7], job->of1);
+ /* image */
+ fputs(f2lpgf_c8_kw[44], job->of1);
+ fl2pgf_image_file_name(job->of1, (obj->dt).pol.fn);
+ fputs(f2lpgf_c8_kw[45], job->of1);
+ /* grestore */
+ fputs(f2lpgf_c8_kw[5], job->of1);
+ } else {
+ /* ERROR: Failed to calculate graphics state transformation */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 40);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
+
+#line 1472 "f2lpgf.ctr"
+ }
+ } else {
+ /* ERROR: Failed to open bitmap image! */
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1476 "f2lpgf.ctr"
+ }
+ }
+
+
+#line 1479 "f2lpgf.ctr"
+}
+
+
+
+void
+f2lpgf_pgf_newpath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+
+
+#line 1491 "f2lpgf.ctr"
+ /* Nothing to do here, new paths are automatically started by moveto. */
+
+
+#line 1493 "f2lpgf.ctr"
+}
+
+
+
+void
+f2lpgf_pgf_moveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+
+
+#line 1507 "f2lpgf.ctr"
+ fputs(f2lpgf_c8_kw[16], job->of1);
+ f2lpgf_write_point_double(job->of1, x, y);
+ fputs(f2lpgf_c8_kw[7], job->of1);
+
+
+#line 1511 "f2lpgf.ctr"
+}
+
+
+
+void
+f2lpgf_pgf_lineto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+
+
+#line 1525 "f2lpgf.ctr"
+ fputs(f2lpgf_c8_kw[17], job->of1);
+ f2lpgf_write_point_double(job->of1, x, y);
+ fputs(f2lpgf_c8_kw[7], job->of1);
+
+
+#line 1529 "f2lpgf.ctr"
+}
+
+
+
+void
+f2lpgf_pgf_curveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double xcs,
+ double ycs,
+ double xce,
+ double yce,
+ double xe,
+ double ye
+)
+{
+
+
+#line 1547 "f2lpgf.ctr"
+ fputs(f2lpgf_c8_kw[18], job->of1);
+ f2lpgf_write_point_double(job->of1, xcs, ycs);
+ fputs(f2lpgf_c8_kw[19], job->of1);
+ f2lpgf_write_point_double(job->of1, xce, yce);
+ fputs(f2lpgf_c8_kw[19], job->of1);
+ f2lpgf_write_point_double(job->of1, xe, ye);
+ fputs(f2lpgf_c8_kw[7], job->of1);
+
+
+#line 1555 "f2lpgf.ctr"
+}
+
+
+
+void
+f2lpgf_pgf_closepath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+
+
+#line 1567 "f2lpgf.ctr"
+ fputs(f2lpgf_c8_kw[20], job->of1);
+
+
+#line 1569 "f2lpgf.ctr"
+}
+
+
+
+void
+f2lpgf_pgf_fill(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+
+
+#line 1581 "f2lpgf.ctr"
+ fputs(f2lpgf_c8_kw[21], job->of1);
+
+
+#line 1583 "f2lpgf.ctr"
+}
+
+
+
+void
+f2lpgf_pgf_fill_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+
+
+#line 1595 "f2lpgf.ctr"
+ fputs(f2lpgf_c8_kw[22], job->of1);
+
+
+#line 1597 "f2lpgf.ctr"
+}
+
+
+
+void
+f2lpgf_pgf_fill_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+
+
+#line 1609 "f2lpgf.ctr"
+ fputs(f2lpgf_c8_kw[23], job->of1);
+
+
+#line 1611 "f2lpgf.ctr"
+}
+
+
+
+void
+f2lpgf_pgf_fill_stroke_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+
+
+#line 1623 "f2lpgf.ctr"
+ fputs(f2lpgf_c8_kw[24], job->of1);
+
+
+#line 1625 "f2lpgf.ctr"
+}
+
+
+
+void
+f2lpgf_pgf_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+
+
+#line 1637 "f2lpgf.ctr"
+ fputs(f2lpgf_c8_kw[14], job->of1);
+
+
+#line 1639 "f2lpgf.ctr"
+}
+
+
+
+void
+f2lpgf_pgf_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+
+
+#line 1651 "f2lpgf.ctr"
+ fputs(f2lpgf_c8_kw[25], job->of1);
+
+
+#line 1653 "f2lpgf.ctr"
+}
+
+
+
+void
+f2lpgf_pgf_gsave(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+
+
+#line 1665 "f2lpgf.ctr"
+ fputs(f2lpgf_c8_kw[4], job->of1);
+
+
+#line 1667 "f2lpgf.ctr"
+}
+
+
+
+void
+f2lpgf_pgf_grestore(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+
+
+#line 1679 "f2lpgf.ctr"
+ fputs(f2lpgf_c8_kw[5], job->of1);
+
+
+#line 1681 "f2lpgf.ctr"
+}
+
+
+
+void
+f2lpgf_pgf_set_line_width(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double lw
+)
+{
+
+
+#line 1694 "f2lpgf.ctr"
+
+ fputs(f2lpgf_c8_kw[26], job->of1);
+ dk3ma_print_double_c8_no_sci(job->of1, lw);
+ fputs(f2lpgf_c8_kw[12], job->of1);
+ fputs(f2lpgf_c8_kw[7], job->of1);
+
+
+#line 1700 "f2lpgf.ctr"
+}
+
+
+
+void
+f2lpgf_pgf_set_line_style(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int ls,
+ double sv,
+ double lw
+)
+{
+ double xsv[32]; /* Lengths of strokes and gaps. */
+ double ph; /* Phase (used length at start). */
+ double gw; /* Gap width. */
+ size_t nsv; /* Number of elements in xsv. */
+
+
+#line 1719 "f2lpgf.ctr"
+ ph = 0.0; nsv = 0; xsv[0] = 0.0;
+ gw = f2lto_find_gap_length(job, lw, sv);
+ switch(ls) {
+ case DK3_FIG_LS_DASH_TRIPLE_DOTTED: {
+ xsv[0] = sv;
+ xsv[1] = gw;
+ xsv[2] = lw;
+ xsv[3] = gw;
+ xsv[4] = lw;
+ xsv[5] = gw;
+ xsv[6] = lw;
+ xsv[7] = gw;
+ nsv = 8;
+ } break;
+ case DK3_FIG_LS_DASH_DOUBLE_DOTTED: {
+ xsv[0] = sv;
+ xsv[1] = gw;
+ xsv[2] = lw;
+ xsv[3] = gw;
+ xsv[4] = lw;
+ xsv[5] = gw;
+ nsv = 6;
+ } break;
+ case DK3_FIG_LS_DASH_DOTTED: {
+ xsv[0] = sv;
+ xsv[1] = gw;
+ xsv[2] = lw;
+ xsv[3] = gw;
+ nsv = 4;
+ } break;
+ case DK3_FIG_LS_DOTTED: {
+ xsv[0] = lw; xsv[1] = gw;
+ nsv = 2;
+ } break;
+ case DK3_FIG_LS_DASHED: {
+ xsv[0] = sv; xsv[1] = gw;
+ nsv = 2;
+ } break;
+ }
+ f2lpgf_set_line_dash(job->of1, xsv, nsv, ph);
+
+
+#line 1760 "f2lpgf.ctr"
+}
+
+
+
+void
+f2lpgf_pgf_set_line_end(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int le
+)
+{
+
+
+#line 1773 "f2lpgf.ctr"
+ switch(le) {
+ case DK3_FIG_LC_PROJECTING: {
+ fputs(f2lpgf_c8_kw[29], job->of1);
+ } break;
+ case DK3_FIG_LC_ROUND: {
+ fputs(f2lpgf_c8_kw[30], job->of1);
+ } break;
+ default: {
+ fputs(f2lpgf_c8_kw[31], job->of1);
+ } break;
+ }
+
+
+#line 1785 "f2lpgf.ctr"
+}
+
+
+
+void
+f2lpgf_pgf_set_line_join(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int lj
+)
+{
+
+
+#line 1798 "f2lpgf.ctr"
+ switch(lj) {
+ case DK3_FIG_LJ_BEVEL: {
+ fputs(f2lpgf_c8_kw[32], job->of1);
+ } break;
+ case DK3_FIG_LJ_ROUND: {
+ fputs(f2lpgf_c8_kw[33], job->of1);
+ } break;
+ default: {
+ fputs(f2lpgf_c8_kw[34], job->of1);
+ } break;
+ }
+
+
+#line 1810 "f2lpgf.ctr"
+}
+
+
+
+void
+f2lpgf_pgf_set_color_1(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+)
+{
+
+
+#line 1822 "f2lpgf.ctr"
+ f2lpgf_define_color(job->of1, 0, rgb);
+ fputs(f2lpgf_c8_kw[37], job->of1);
+
+
+#line 1825 "f2lpgf.ctr"
+}
+
+
+
+void
+f2lpgf_pgf_set_color_2(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+)
+{
+
+
+#line 1837 "f2lpgf.ctr"
+ f2lpgf_define_color(job->of1, 1, rgb);
+ fputs(f2lpgf_c8_kw[38], job->of1);
+
+
+#line 1840 "f2lpgf.ctr"
+}
+
+
+
+void
+f2lpgf_pgf_setcolor(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double r,
+ double g,
+ double b
+)
+{
+ dk3_rgb_color_t rgb; /* Color cell. */
+
+
+#line 1856 "f2lpgf.ctr"
+ rgb.r = r; rgb.g = g; rgb.b = b;
+ f2lpgf_pgf_set_color_1(job, drw, &rgb);
+ rgb.r = r; rgb.g = g; rgb.b = b;
+ f2lpgf_pgf_set_color_2(job, drw, &rgb);
+
+
+#line 1861 "f2lpgf.ctr"
+}
+
+
+void
+f2lpgf_pgf_debug(
+ f2l_job_t *job,
+ char const *msg
+)
+{
+
+
+#line 1871 "f2lpgf.ctr"
+ fputs(f2lpgf_c8_kw[39], job->of1);
+ fputs(msg, job->of1);
+ fputc('\n', job->of1);
+
+
+#line 1875 "f2lpgf.ctr"
+}
+
+
+
+/* ************************************************************************ */
+/* * * */
+/* * TeX output driver functions. * */
+/* * * */
+/* ************************************************************************ */
+
+
+#line 1882 "f2lpgf.ctr"
+
+int
+f2lpgf_tex_initialize(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ int back = 0;
+ back = f2lpgf_pgf_initialize(job, drw);
+ return back;
+}
+
+
+
+void
+f2lpgf_tex_end(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ f2lpgf_pgf_end(job, drw);
+}
+
+
+
+int
+f2lpgf_tex_open_output_files(f2l_job_t *job)
+{
+ int back = 0;
+ back = f2lpgf_pgf_open_output_files(job);
+ return back;
+}
+
+
+
+void
+f2lpgf_tex_close_output_files(f2l_job_t *job)
+{
+ f2lpgf_pgf_close_output_files(job);
+}
+
+
+
+int
+f2lpgf_tex_start_processing(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ int back = 0;
+ f2l_tool_begin_latex_document(job->of1, job, drw);
+ back = f2lpgf_pgf_start_processing(job, drw);
+ return back;
+}
+
+
+
+void
+f2lpgf_tex_end_processing(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ f2lpgf_pgf_end_processing(job, drw);
+ f2l_tool_end_latex_document(job->of1, job, drw);
+}
+
+
+
+void
+f2lpgf_tex_text_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+ f2lpgf_pgf_text_object(job, drw, obj, x, y);
+}
+
+
+
+void
+f2lpgf_tex_image_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int drawdir,
+ int *ec
+)
+{
+ f2lpgf_pgf_image_object(job, drw, obj, outbb, drawdir, ec);
+}
+
+
+
+void
+f2lpgf_tex_newpath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2lpgf_pgf_newpath(job, drw, obj);
+}
+
+
+
+void
+f2lpgf_tex_moveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+ f2lpgf_pgf_moveto(job, drw, obj, x, y);
+}
+
+
+
+void
+f2lpgf_tex_lineto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+ f2lpgf_pgf_lineto(job, drw, obj, x, y);
+}
+
+
+
+void
+f2lpgf_tex_curveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double xcs,
+ double ycs,
+ double xce,
+ double yce,
+ double xe,
+ double ye
+)
+{
+ f2lpgf_pgf_curveto(job, drw, obj, xcs, ycs, xce, yce, xe, ye);
+}
+
+
+
+void
+f2lpgf_tex_closepath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2lpgf_pgf_closepath(job, drw, obj);
+}
+
+
+
+void
+f2lpgf_tex_fill(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2lpgf_pgf_fill(job, drw, obj);
+}
+
+
+
+void
+f2lpgf_tex_fill_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2lpgf_pgf_fill_stroke(job, drw, obj);
+}
+
+
+
+void
+f2lpgf_tex_fill_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2lpgf_pgf_fill_clip(job, drw, obj);
+}
+
+
+
+void
+f2lpgf_tex_fill_stroke_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2lpgf_pgf_fill_stroke_clip(job, drw, obj);
+}
+
+
+
+void
+f2lpgf_tex_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2lpgf_pgf_clip(job, drw, obj);
+}
+
+
+
+void
+f2lpgf_tex_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2lpgf_pgf_stroke(job, drw, obj);
+}
+
+
+
+void
+f2lpgf_tex_gsave(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2lpgf_pgf_gsave(job, drw, obj);
+}
+
+
+
+void
+f2lpgf_tex_grestore(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2lpgf_pgf_grestore(job, drw, obj);
+}
+
+
+
+void
+f2lpgf_tex_setcolor(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double r,
+ double g,
+ double b
+)
+{
+ f2lpgf_pgf_setcolor(job, drw, obj, r, g, b);
+}
+
+
+
+void
+f2lpgf_tex_set_line_width(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double lw
+)
+{
+ f2lpgf_pgf_set_line_width(job, drw, obj, lw);
+}
+
+
+
+void
+f2lpgf_tex_set_line_style(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int ls,
+ double sv,
+ double lw
+)
+{
+ f2lpgf_pgf_set_line_style(job, drw, obj, ls, sv, lw);
+}
+
+
+
+void
+f2lpgf_tex_set_line_end(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int le
+)
+{
+ f2lpgf_pgf_set_line_end(job, drw, obj, le);
+}
+
+
+
+void
+f2lpgf_tex_set_line_join(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int lj
+)
+{
+ f2lpgf_pgf_set_line_join(job, drw, obj, lj);
+}
+
+
+
+void
+f2lpgf_tex_set_color_1(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+)
+{
+ f2lpgf_pgf_set_color_1(job, drw, rgb);
+}
+
+
+
+void
+f2lpgf_tex_set_color_2(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+)
+{
+ f2lpgf_pgf_set_color_2(job, drw, rgb);
+}
+
+
+
+void
+f2lpgf_tex_debug(
+ f2l_job_t *job,
+ char const *msg
+)
+{
+ f2lpgf_pgf_debug(job, msg);
+}
+
diff --git a/support/dktools/f2lpgf.ctr b/support/dktools/f2lpgf.ctr
new file mode 100644
index 0000000000..6e3a5d955b
--- /dev/null
+++ b/support/dktools/f2lpgf.ctr
@@ -0,0 +1,2235 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Driver initialization for tex output.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+int
+f2lpgf_tex_initialize(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Driver cleanup for tex driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+void
+f2lpgf_tex_end(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Open output files for tex driver.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+f2lpgf_tex_open_output_files(f2l_job_t *job);
+
+/** Close output files for tex driver.
+ @param job Job structure.
+*/
+void
+f2lpgf_tex_close_output_files(f2l_job_t *job);
+
+/** Write start of output for tex driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+int
+f2lpgf_tex_start_processing(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Write end of output for tex driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+void
+f2lpgf_tex_end_processing(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Process one text object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x Point x.
+ @param y Point y.
+*/
+void
+f2lpgf_tex_text_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Process one image object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param outbb Bounding box for image.
+ @param drawdir Drawing direction.
+ @param ec Pointer to error code variable, may be NULL.
+*/
+void
+f2lpgf_tex_image_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int drawdir,
+ int *ec
+);
+
+/** Start new path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_tex_newpath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Move to point.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x Point x.
+ @param y Point y.
+*/
+void
+f2lpgf_tex_moveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Draw line to point.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x Point x.
+ @param y Point y.
+*/
+void
+f2lpgf_tex_lineto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Draw curve to point.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param xcs Start control point y.
+ @param ycs Start control point y.
+ @param xce End control point x.
+ @param yce End control point y.
+ @param xe End point x.
+ @param ye End point y.
+*/
+void
+f2lpgf_tex_curveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double xcs,
+ double ycs,
+ double xce,
+ double yce,
+ double xe,
+ double ye
+);
+
+/** Close path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_tex_closepath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Fill path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_tex_fill(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Fill and stroke path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_tex_fill_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Fill and clip path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_tex_fill_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Fill, stroke and clip path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_tex_fill_stroke_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Clip drawing operations to path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_tex_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Stroke path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_tex_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Save graphics state.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_tex_gsave(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Restore graphics state.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_tex_grestore(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Set color.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param r Red.
+ @param g Green.
+ @param b Blue.
+*/
+void
+f2lpgf_tex_setcolor(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double r,
+ double g,
+ double b
+);
+
+/** Set line width.
+ The line width is not set again if we already
+ have a current line width equal to the new line width.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param lw New line width in output coordinates.
+*/
+void
+f2lpgf_tex_set_line_width(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double lw
+);
+
+/** Set line style.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object to set up.
+ @param ls Line style, see @ref dk3figlinestyles.
+ @param sv Style value in output coordinates.
+ @param lw Dot length in output coordinates.
+*/
+void
+f2lpgf_tex_set_line_style(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int ls,
+ double sv,
+ double lw
+);
+
+/** Set line end.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param le Line end, see @ref dk3figlinecap.
+*/
+void
+f2lpgf_tex_set_line_end(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int le
+);
+
+/** Set line join.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param lj Line join style, see @ref dk3figlinejoin.
+*/
+void
+f2lpgf_tex_set_line_join(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int lj
+);
+
+/** Set current color or stroking color (PGF, PDF).
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param rgb New color value.
+*/
+void
+f2lpgf_tex_set_color_1(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+);
+
+/** Set non-stroking color (PGF, PDF).
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param rgb New color value.
+*/
+void
+f2lpgf_tex_set_color_2(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+);
+
+/** Write debugging line to output file.
+ @param job Job structure.
+ @param msg Message to write to output file.
+*/
+void
+f2lpgf_tex_debug(
+ f2l_job_t *job,
+ char const *msg
+);
+
+/** Driver initialization for pgf output.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+int
+f2lpgf_pgf_initialize(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Driver cleanup for pgf driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+void
+f2lpgf_pgf_end(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Open output files for pgf driver.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+f2lpgf_pgf_open_output_files(f2l_job_t *job);
+
+/** Close output files for tex driver.
+ @param job Job structure.
+*/
+void
+f2lpgf_pgf_close_output_files(f2l_job_t *job);
+
+/** Write start of output for pgf driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+int
+f2lpgf_pgf_start_processing(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Write end of output for pgf driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+void
+f2lpgf_pgf_end_processing(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Process one text object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x Point x.
+ @param y Point y.
+*/
+void
+f2lpgf_pgf_text_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Process one image object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param outbb Bounding box for image.
+ @param drawdir Drawing direction.
+ @param ec Pointer to error code variable, may be NULL.
+*/
+void
+f2lpgf_pgf_image_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int drawdir,
+ int *ec
+);
+
+/** Start new path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_pgf_newpath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Move to point.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x Point x.
+ @param y Point y.
+*/
+void
+f2lpgf_pgf_moveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Draw line to point.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x Point x.
+ @param y Point y.
+*/
+void
+f2lpgf_pgf_lineto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Draw curve to point.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param xcs Start control point y.
+ @param ycs Start control point y.
+ @param xce End control point x.
+ @param yce End control point y.
+ @param xe End point x.
+ @param ye End point y.
+*/
+void
+f2lpgf_pgf_curveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double xcs,
+ double ycs,
+ double xce,
+ double yce,
+ double xe,
+ double ye
+);
+
+/** Close path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_pgf_closepath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Fill path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_pgf_fill(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Fill and stroke path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_pgf_fill_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Fill and clip path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_pgf_fill_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Fill,stroke and clip path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_pgf_fill_stroke_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Clip drawing operations to path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_pgf_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Stroke path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_pgf_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Save graphics state.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_pgf_gsave(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Restore graphics state.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_pgf_grestore(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Set color.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param r Red.
+ @param g Green.
+ @param b Blue.
+*/
+void
+f2lpgf_pgf_setcolor(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double r,
+ double g,
+ double b
+);
+
+/** Set line width.
+ The line width is not set again if we already
+ have a current line width equal to the new line width.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param lw New line width in output coordinates.
+*/
+void
+f2lpgf_pgf_set_line_width(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double lw
+);
+
+/** Set line style.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object to set up.
+ @param ls Line style, see @ref dk3figlinestyles.
+ @param sv Style value in output coordinates.
+ @param lw Dot length in output coordinates.
+*/
+void
+f2lpgf_pgf_set_line_style(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int ls,
+ double sv,
+ double lw
+);
+
+/** Set line end.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param le Line end, see @ref dk3figlinecap.
+*/
+void
+f2lpgf_pgf_set_line_end(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int le
+);
+
+/** Set line join.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param lj Line join style, see @ref dk3figlinejoin.
+*/
+void
+f2lpgf_pgf_set_line_join(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int lj
+);
+
+/** Set current color or stroking color (PGF, PDF).
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param rgb New color value.
+*/
+void
+f2lpgf_pgf_set_color_1(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+);
+
+/** Set non-stroking color (PGF, PDF).
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param rgb New color value.
+*/
+void
+f2lpgf_pgf_set_color_2(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+);
+
+/** Write debugging line to output file.
+ @param job Job structure.
+ @param msg Message to write to output file.
+*/
+void
+f2lpgf_pgf_debug(
+ f2l_job_t *job,
+ char const *msg
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk3all.h"
+#include "dk3bezcu.h"
+#include "fig2lat.h"
+#include "f2lud.h"
+#include "f2lsvg.h"
+#include "f2lpgf.h"
+#include "dk3figto.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4vers.h"
+#include "dk3bif.h"
+#include "dk3bm.h"
+#include "dk3figto.h"
+
+
+
+$!trace-include
+
+
+
+/** Driver specific details for entire drawing.
+*/
+typedef struct {
+ dk3_sto_t *sFonts; /**< Storage for fonts. */
+ dk3_sto_it_t *iFonts; /**< Iterator for font storage. */
+ unsigned long nFonts; /**< Number of fonts in sFonts. */
+} f2l_pgf_drawing_info_t;
+
+
+
+/** Keywords used by the module.
+*/
+static char const * const f2lpgf_c8_kw[] = {
+$!string-table
+#
+# 0: Newline
+#
+\n
+#
+# 1: Space
+#
+
+#
+# 2: Begin of PGF picture
+#
+\\begin{pgfpicture}\n
+#
+# 3: End of PGF picture
+#
+\\end{pgfpicture}%\n
+#
+# 4: Begin PGF scope
+#
+\\begin{pgfscope}\n
+#
+# 5: End PGF scope
+#
+\\end{pgfscope}\n
+#
+# 6: Begin of rectangle path
+#
+\\pgfpathrectangle{\\pgfpointorigin}{
+#
+# 7: End of rectangle path
+#
+}\n
+#
+# 8: Start of pgfpoint command
+#
+\\pgfpoint{
+#
+# 9: Middle of pgfpoint command
+#
+,
+#
+# 10: End of command
+#
+}
+#
+# 11: pgfpoint command for long values
+#
+\\pgfpoint{%ldbp}{%ldbp}
+#
+# 12: Unit bp
+#
+bp
+#
+# 13: Use path as bounding box
+#
+\\pgfusepath{use as bounding box}\n
+#
+# 14: Clip to path
+#
+\\pgfusepath{clip}\n
+#
+# 15: Set even/odd winding rule
+#
+\\pgfseteorule\n
+#
+# 16: moveto command
+#
+\\pgfpathmoveto{
+#
+# 17: lineto command
+#
+\\pgfpathlineto{
+#
+# 18: curveto command
+#
+\\pgfpathcurveto{
+#
+# 19: next argument
+#
+}{
+#
+# 20: closepath command
+#
+\\pgfpathclose\n
+#
+# 21: fill command
+#
+\\pgfusepath{fill}\n
+#
+# 22: fill and stroke command
+#
+\\pgfusepath{fill,stroke}\n
+#
+# 23: fill and clip command
+#
+\\pgfusepath{fill,clip}\n
+#
+# 24: fill, stroke and clip command
+#
+\\pgfusepath{fill,stroke,clip}\n
+#
+# 25: stroke command
+#
+\\pgfusepath{stroke}\n
+#
+# 26: setlinewidth command
+#
+\\pgfsetlinewidth{
+#
+# 27: Dash style: solid line
+#
+\\pgfsetdash{
+#
+# 28: Opening curly bracket
+#
+{
+#
+# 29: projecting line cap
+#
+\\pgfsetrectcap\n
+#
+# 30: round line cap
+#
+\\pgfsetroundcap\n
+#
+# 31: Butted line cap
+#
+\\pgfsetbuttcap\n
+#
+# 32: Bevel line join
+#
+\\pgfsetbeveljoin\n
+#
+# 33: Round line join
+#
+\\pgfsetroundjoin\n
+#
+# 34: Miter line join
+#
+\\pgfsetmiterjoin\n
+#
+# 35: Define stroke color command
+#
+\\definecolor{FigToLatColorS}{rgb}{
+#
+# 36: Define non-stroke color command
+#
+\\definecolor{FigToLatColorN}{rgb}{
+#
+# 37: Set stroke color
+#
+\\pgfsetstrokecolor{FigToLatColorS}\n
+#
+# 38: Set non-stroke color
+#
+\\pgfsetfillcolor{FigToLatColorN}\n
+#
+# 39: Start of comment
+#
+%
+#
+# 40: Translate
+#
+\\pgftransformshift{
+#
+# 41: Rotate
+#
+\\pgftransformrotate{%d}\n
+#
+# 42: X scale
+#
+\\pgftransformxscale{
+#
+# 43: Y scale
+#
+\\pgftransformyscale{
+#
+# 44: Text start for image inclusion
+#
+\\pgftext[left,base,at={\\pgfpointorigin}]{\\pgfimage[interpolate=true,width=1bp,height=1bp]{
+#
+# 45: Image end
+#
+}}\n
+#
+# 46: Start pgftext command
+#
+\\pgftext[
+#
+# 47: Center of pgftext command
+#
+]{
+#
+# 48: Left aligned text
+#
+base,left
+#
+# 49: Centered text
+#
+base
+#
+# 50: Right aligned text
+#
+base,right
+#
+# 51: at option for text
+#
+,at={
+#
+# 52: rotation option for text
+#
+,rotate=
+$!end
+};
+
+
+$*
+ Tool functions
+$*
+
+
+
+/** Delete driver-specific details.
+ @param ptr Details structure to delete.
+*/
+static
+void
+f2lpgf_pdi_delete(f2l_pgf_drawing_info_t *ptr)
+{
+ void *vptr; /* Current text handling structure to delete. */
+
+ if(ptr) {
+ if(ptr->sFonts) {
+ if(ptr->iFonts) {
+ dk3sto_it_reset(ptr->iFonts);
+ while(NULL != (vptr = dk3sto_it_next(ptr->iFonts))) {
+ dk3_delete(vptr);
+ }
+ dk3sto_it_close(ptr->iFonts);
+ }
+ dk3sto_close(ptr->sFonts);
+ } ptr->sFonts = NULL; ptr->iFonts = NULL; ptr->nFonts = 0UL;
+ dk3_delete(ptr);
+ }
+}
+
+
+
+/** Create structure for driver-specific details.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return Pointer to new structure on success, NULL on error.
+*/
+static
+f2l_pgf_drawing_info_t *
+f2lpgf_pdi_new(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ f2l_pgf_drawing_info_t *back = NULL;
+ int ok = 0;
+ back = dk3_new_app(f2l_pgf_drawing_info_t,1,job->app);
+ if(back) {
+ back->sFonts = NULL; back->iFonts = NULL; back->nFonts = 0UL;
+ back->sFonts = dk3sto_open_app(job->app);
+ if(back->sFonts) {
+ dk3sto_set_comp(back->sFonts, dk3fig_tool_text_handling_compare, 0);
+ back->iFonts = dk3sto_it_open(back->sFonts);
+ if(back->iFonts) {
+ ok = 1;
+ }
+ }
+ if(!(ok)) {
+ f2lpgf_pdi_delete(back);
+ back = NULL;
+ }
+ } else {
+ }
+ return back;
+}
+
+
+
+/** Write point (long coordinates).
+ @param of Output file.
+ @param x X position.
+ @param y X position.
+*/
+static
+void
+f2lpgf_write_point_long(FILE *of, long x, long y)
+{
+ fprintf(of, f2lpgf_c8_kw[11], x, y);
+}
+
+
+
+/** Write point (double coordinates).
+ @param of Output file.
+ @param x X position.
+ @param y Y position.
+*/
+static
+void
+f2lpgf_write_point_double(FILE *of, double x, double y)
+{
+ fputs(f2lpgf_c8_kw[8], of);
+ dk3ma_print_double_c8_no_sci(of, x);
+ fputs(f2lpgf_c8_kw[12], of);
+ fputs(f2lpgf_c8_kw[19], of);
+ dk3ma_print_double_c8_no_sci(of, y);
+ fputs(f2lpgf_c8_kw[12], of);
+ fputs(f2lpgf_c8_kw[10], of);
+}
+
+
+
+/** Set line dash.
+ @param of Output file.
+ @param xsv Stroke and gap lengths.
+ @param nsv Number of elements in xsv.
+ @param ph Phase (Used length at start of line).
+*/
+static
+void
+f2lpgf_set_line_dash(FILE *of, double *xsv, size_t nsv, double ph)
+{
+ size_t i; /* Index to traverse xsv. */
+
+ fputs(f2lpgf_c8_kw[27], of);
+ for(i = 0; i < nsv; i++) {
+ fputs(f2lpgf_c8_kw[28], of);
+ dk3ma_print_double_c8_no_sci(of, xsv[i]);
+ fputs(f2lpgf_c8_kw[12], of);
+ fputs(f2lpgf_c8_kw[10], of);
+ }
+ fputs(f2lpgf_c8_kw[19], of);
+ dk3ma_print_double_c8_no_sci(of, ph);
+ fputs(f2lpgf_c8_kw[12], of);
+ fputs(f2lpgf_c8_kw[7], of);
+}
+
+
+
+/** Define current color.
+ @param of Output file.
+ @param tp Color type.
+ @param rgb RGB color structure.
+*/
+static
+void
+f2lpgf_define_color(FILE *of, int tp, dk3_rgb_color_t *rgb)
+{
+ fputs(f2lpgf_c8_kw[((tp) ? 36 : 35)], of);
+ dk3ma_print_double_c8_no_sci(of, rgb->r);
+ fputs(f2lpgf_c8_kw[9], of);
+ dk3ma_print_double_c8_no_sci(of, rgb->g);
+ fputs(f2lpgf_c8_kw[9], of);
+ dk3ma_print_double_c8_no_sci(of, rgb->b);
+ fputs(f2lpgf_c8_kw[10], of);
+}
+
+
+
+/** Write image file name to output file.
+ @param of Output file.
+ @param fn File name.
+*/
+static
+void
+fl2pgf_image_file_name(FILE *of, char const *fn)
+{
+ char const *ptr; /* Current character to process. */
+
+ ptr = fn;
+ while(*ptr) {
+ switch(*ptr) {
+ case '\\': {
+ fputc('/', of);
+ } break;
+ default: {
+ fputc(*ptr, of);
+ } break;
+ }
+ ptr++;
+ }
+}
+
+
+
+/** Write text rotation angle.
+ @param of Output file.
+ @param rot Rotation in radians.
+ @param job Job structure.
+*/
+static
+void
+f2lpgf_write_text_rotation(FILE *of, double rot, f2l_job_t *job)
+{
+ int ec = 0; /* Mathematical error code. */
+ double an; /* Rotation in degree. */
+ double ri; /* Integer value of an. */
+
+ if(1.0e-6 < fabs(rot)) {
+ an = dk3ma_d_mul_ok(rot, 180.0, &ec) / M_PI;
+ ri = dk3ma_d_rint(an);
+#if 0
+ if(1.0e-3 > fabs(dk3ma_d_rint(dk3ma_d_sub_ok(an, ri, &ec)))) {
+ an = ri;
+ }
+#else
+ /* 2013-01-27: The rint result in the code above is always 0.
+ */
+ if(1.0e-3 > fabs(dk3ma_d_sub_ok(an, ri, &ec))) {
+ an = ri;
+ }
+#endif
+ fputs(f2lpgf_c8_kw[52], of);
+ dk3ma_print_double_c8_no_sci(of, an);
+ if(ec) {
+ /* ERROR: Math error */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH); $? ". exitcode"
+ }
+ }
+}
+
+
+
+$*
+ PGF output driver functions
+$*
+
+int
+f2lpgf_pgf_initialize(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+
+ f2l_pgf_drawing_info_t *pdi = NULL; /* Driver spec det. */
+ dkChar const *oldsourcefile = NULL; /* Source file name. */
+ dk3_fig_obj_t *pobj; /* Current object. */
+ unsigned long oldsourceline = 0UL; /* Source file line. */
+ int ff = 0; /* Font flags. */
+ int back = 0;
+ $? "+ f2lpgf_pgf_initialize"
+ if((job) && (drw)) {
+ pdi = f2lpgf_pdi_new(job, drw);
+ if(pdi) {
+ drw->dsd = (void *)pdi;
+ back = 1;
+ oldsourcefile = dk3app_get_source_file(job->app);
+ oldsourceline = dk3app_get_source_line(job->app);
+ dk3sto_it_reset(drw->iobj);
+ while(NULL != (pobj = (dk3_fig_obj_t *)dk3sto_it_next(drw->iobj))) {
+ dk3app_set_source_line(job->app, pobj->li);
+ switch(pobj->ot) {
+ case DK3_FIG_OBJ_TEXT: { $? ". text"
+ ff = (pobj->dt).txt.ff;
+ if(!(ff & DK3_FIG_FONT_FLAG_HIDDEN)) { $? ". not hidden"
+ if(!(ff & DK3_FIG_FONT_FLAG_SPECIAL)) { $? ". not special"
+ if(ff & DK3_FIG_FONT_FLAG_PS) { $? ". PS font"
+ if(job->ntf) { $? ". ntf"
+ pobj->dsd = (void *)f2l_tool_register_font(
+ pdi->sFonts, pdi->iFonts, &(pdi->nFonts),
+ (pobj->dt).txt.fo, (pobj->dt).txt.fs, job->app
+ );
+ if(!(pobj->dsd)) {
+ back = 0;
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ } else { $? ". no ntf"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ dk3app_set_source_file(job->app, oldsourcefile);
+ dk3app_set_source_line(job->app, oldsourceline);
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ } $? "- f2lpgf_pgf_initialize %d", back
+ return back;
+}
+
+
+
+void
+f2lpgf_pgf_end(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ $? "+ f2lpgf_pgf_end"
+ if((job) && (drw)) {
+ if(drw->dsd) {
+ f2lpgf_pdi_delete((f2l_pgf_drawing_info_t *)(drw->dsd));
+ }
+ } $? "- f2lpgf_pgf_end"
+}
+
+
+
+int
+f2lpgf_pgf_open_output_files(f2l_job_t *job)
+{
+ int back = 0;
+ $? "+ f2lpgf_pgf_open_output_files"
+ job->of1 = dk3sf_fopen_app(job->on1, dkT("w"), job->app);
+ if(job->of1) {
+ back = 1;
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ $? "- f2lpgf_pgf_open_output_files %d", back
+ return back;
+}
+
+
+
+void
+f2lpgf_pgf_close_output_files(f2l_job_t *job)
+{
+ $? "+ f2lpgf_pgf_close_output_files"
+ if(job->of1) {
+ dk3sf_fclose_app(job->of1, job->app);
+ }
+ $? "- f2lpgf_pgf_close_output_files"
+}
+
+
+
+int
+f2lpgf_pgf_start_processing(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ f2l_pgf_drawing_info_t *pdi; /* Driver specific details. */
+ int back = 0;
+ $? "+ f2lpgf_pgf_start_processing"
+ pdi = (f2l_pgf_drawing_info_t *)(drw->dsd);
+ if(pdi) { $? ". have pdi"
+ back = 1;
+ /* Font definitions */
+ f2l_tool_start_tex_part_with_picture(
+ job->of1, job, drw, NULL, pdi->iFonts, pdi->nFonts, 0
+ );
+ } else { $? "! no pdi"
+ }
+ fputs(f2lpgf_c8_kw[2], job->of1);
+ /* Bounding box */
+ fputs(f2lpgf_c8_kw[6], job->of1);
+ f2lpgf_write_point_long(job->of1, job->lwidth, job->lheight);
+ fputs(f2lpgf_c8_kw[7], job->of1);
+ fputs(f2lpgf_c8_kw[13], job->of1);
+ fputs(f2lpgf_c8_kw[15], job->of1);
+ /* Begin PGF scope */
+ fputs(f2lpgf_c8_kw[4], job->of1);
+ /* Clip path */
+ fputs(f2lpgf_c8_kw[6], job->of1);
+ f2lpgf_write_point_long(job->of1, job->lwidth, job->lheight);
+ fputs(f2lpgf_c8_kw[7], job->of1);
+ fputs(f2lpgf_c8_kw[14], job->of1);
+ $? "- f2lpgf_pgf_start_processing %d", back
+ return back;
+}
+
+
+
+void
+f2lpgf_pgf_end_processing(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ $? "+ f2lpgf_pgf_end_processing"
+ /* End PGF scope */
+ fputs(f2lpgf_c8_kw[5], job->of1);
+ /* End PGF picture */
+ fputs(f2lpgf_c8_kw[3], job->of1);
+ $? "- f2lpgf_pgf_end_processing"
+}
+
+
+
+void
+f2lpgf_pgf_text_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+ f2l_pgf_drawing_info_t *pdi = NULL; /* Driver specific details. */
+ unsigned long nFonts = 0UL; /* Number of text handlings. */
+ $? "+ f2lpgf_pgf_text_object"
+ pdi = (f2l_pgf_drawing_info_t *)(drw->dsd);
+ if(pdi) { nFonts = pdi->nFonts; }
+ fputs(f2lpgf_c8_kw[46], job->of1);
+ /* align */
+ switch(obj->st) {
+ case 2: {
+ fputs(f2lpgf_c8_kw[50], job->of1);
+ } break;
+ case 1: {
+ fputs(f2lpgf_c8_kw[49], job->of1);
+ } break;
+ default: {
+ fputs(f2lpgf_c8_kw[48], job->of1);
+ } break;
+ }
+ /* position */
+ fputs(f2lpgf_c8_kw[51], job->of1);
+ f2lpgf_write_point_double(job->of1, x, y);
+ fputs(f2lpgf_c8_kw[10], job->of1);
+ /* rotation */
+ f2lpgf_write_text_rotation(job->of1, (obj->dt).txt.an, job);
+ fputs(f2lpgf_c8_kw[47], job->of1);
+ /* text */
+ f2l_tool_inner_text_object(job->of1, job, drw, obj, nFonts);
+ fputs(f2lpgf_c8_kw[7], job->of1);
+ (job->gs).hc1 = 0; (job->gs).hc2 = 0;
+ $? "- f2lpgf_pgf_text_object"
+}
+
+
+
+void
+f2lpgf_pgf_image_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int drawdir,
+ int *ec
+)
+{
+ dk3_coordinates_transformation_t trans; /* Graphics state tr. */
+ dk3_bif_t *bif; /* Bitmap image file. */
+ double w = 0.0; /* Image width. */
+ double h = 0.0; /* Image height. */
+ double xres = -1.0; /* X resolution, none by default. */
+ double yres = -1.0; /* Y resolution, none by default. */
+ int res = 0; /* Result from transformation search. */
+ $? "+ f2lpgf_pgf_image_object"
+ if((obj->dt).pol.fn) {
+ bif = dk3bif_open_c8_filename_app(
+ (obj->dt).pol.fn, DK3_BIF_IMAGE_TYPE_UNKNOWN, job->app
+ );
+ if(bif) {
+ w = (double)dk3bif_get_width(bif);
+ h = (double)dk3bif_get_height(bif);
+ xres = dk3bif_get_xres(bif);
+ yres = dk3bif_get_yres(bif);
+ dk3bif_close(bif);
+ res = dk3bm_find_transformation(
+ &trans, outbb, drawdir, w, h, xres, yres, ec
+ );
+ if(res) {
+ /* gsave */
+ fputs(f2lpgf_c8_kw[4], job->of1);
+ /* translate */
+ fputs(f2lpgf_c8_kw[40], job->of1);
+ f2lpgf_write_point_double(
+ job->of1, trans.x_translate, trans.y_translate
+ );
+ fputs(f2lpgf_c8_kw[7], job->of1);
+ /* rotate */
+ if(trans.rot) {
+ fprintf(job->of1, f2lpgf_c8_kw[41], 90 * trans.rot);
+ }
+ /* scale */
+ fputs(f2lpgf_c8_kw[42], job->of1);
+ dk3ma_print_double_c8_no_sci(job->of1, trans.x_scale);
+ fputs(f2lpgf_c8_kw[7], job->of1);
+ fputs(f2lpgf_c8_kw[43], job->of1);
+ dk3ma_print_double_c8_no_sci(job->of1, trans.y_scale);
+ fputs(f2lpgf_c8_kw[7], job->of1);
+ /* image */
+ fputs(f2lpgf_c8_kw[44], job->of1);
+ fl2pgf_image_file_name(job->of1, (obj->dt).pol.fn);
+ fputs(f2lpgf_c8_kw[45], job->of1);
+ /* grestore */
+ fputs(f2lpgf_c8_kw[5], job->of1);
+ } else {
+ /* ERROR: Failed to calculate graphics state transformation */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 40);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH); $? ". exitcode"
+ }
+ } else {
+ /* ERROR: Failed to open bitmap image! */
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ }
+ $? "- f2lpgf_pgf_image_object"
+}
+
+
+
+void
+f2lpgf_pgf_newpath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ $? "+ f2lpgf_pgf_newpath"
+ /* Nothing to do here, new paths are automatically started by moveto. */
+ $? "- f2lpgf_pgf_newpath"
+}
+
+
+
+void
+f2lpgf_pgf_moveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+ $? "+ f2lpgf_pgf_moveto"
+ fputs(f2lpgf_c8_kw[16], job->of1);
+ f2lpgf_write_point_double(job->of1, x, y);
+ fputs(f2lpgf_c8_kw[7], job->of1);
+ $? "- f2lpgf_pgf_moveto"
+}
+
+
+
+void
+f2lpgf_pgf_lineto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+ $? "+ f2lpgf_pgf_lineto"
+ fputs(f2lpgf_c8_kw[17], job->of1);
+ f2lpgf_write_point_double(job->of1, x, y);
+ fputs(f2lpgf_c8_kw[7], job->of1);
+ $? "- f2lpgf_pgf_lineto"
+}
+
+
+
+void
+f2lpgf_pgf_curveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double xcs,
+ double ycs,
+ double xce,
+ double yce,
+ double xe,
+ double ye
+)
+{
+ $? "+ f2lpgf_pgf_curveto"
+ fputs(f2lpgf_c8_kw[18], job->of1);
+ f2lpgf_write_point_double(job->of1, xcs, ycs);
+ fputs(f2lpgf_c8_kw[19], job->of1);
+ f2lpgf_write_point_double(job->of1, xce, yce);
+ fputs(f2lpgf_c8_kw[19], job->of1);
+ f2lpgf_write_point_double(job->of1, xe, ye);
+ fputs(f2lpgf_c8_kw[7], job->of1);
+ $? "- f2lpgf_pgf_curveto"
+}
+
+
+
+void
+f2lpgf_pgf_closepath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ $? "+ f2lpgf_pgf_closepath"
+ fputs(f2lpgf_c8_kw[20], job->of1);
+ $? "- f2lpgf_pgf_closepath"
+}
+
+
+
+void
+f2lpgf_pgf_fill(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ $? "+ f2lpgf_pgf_fill"
+ fputs(f2lpgf_c8_kw[21], job->of1);
+ $? "- f2lpgf_pgf_fill"
+}
+
+
+
+void
+f2lpgf_pgf_fill_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ $? "+ f2lpgf_pgf_fill_stroke"
+ fputs(f2lpgf_c8_kw[22], job->of1);
+ $? "- f2lpgf_pgf_fill_stroke"
+}
+
+
+
+void
+f2lpgf_pgf_fill_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ $? "+ f2lpgf_pgf_fill_clip"
+ fputs(f2lpgf_c8_kw[23], job->of1);
+ $? "- f2lpgf_pgf_fill_clip"
+}
+
+
+
+void
+f2lpgf_pgf_fill_stroke_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ $? "+ f2lpgf_pgf_fill_stroke_clip"
+ fputs(f2lpgf_c8_kw[24], job->of1);
+ $? "- f2lpgf_pgf_fill_stroke_clip"
+}
+
+
+
+void
+f2lpgf_pgf_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ $? "+ f2lpgf_pgf_clip"
+ fputs(f2lpgf_c8_kw[14], job->of1);
+ $? "- f2lpgf_pgf_clip"
+}
+
+
+
+void
+f2lpgf_pgf_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ $? "+ f2lpgf_pgf_stroke"
+ fputs(f2lpgf_c8_kw[25], job->of1);
+ $? "- f2lpgf_pgf_stroke"
+}
+
+
+
+void
+f2lpgf_pgf_gsave(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ $? "+ f2lpgf_pgf_gsave"
+ fputs(f2lpgf_c8_kw[4], job->of1);
+ $? "- f2lpgf_pgf_gsave"
+}
+
+
+
+void
+f2lpgf_pgf_grestore(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ $? "+ f2lpgf_pgf_grestore"
+ fputs(f2lpgf_c8_kw[5], job->of1);
+ $? "- f2lpgf_pgf_grestore"
+}
+
+
+
+void
+f2lpgf_pgf_set_line_width(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double lw
+)
+{
+ $? "+ f2lpgf_pgf_set_line_width"
+
+ fputs(f2lpgf_c8_kw[26], job->of1);
+ dk3ma_print_double_c8_no_sci(job->of1, lw);
+ fputs(f2lpgf_c8_kw[12], job->of1);
+ fputs(f2lpgf_c8_kw[7], job->of1);
+ $? "- f2lpgf_pgf_set_line_width"
+}
+
+
+
+void
+f2lpgf_pgf_set_line_style(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int ls,
+ double sv,
+ double lw
+)
+{
+ double xsv[32]; /* Lengths of strokes and gaps. */
+ double ph; /* Phase (used length at start). */
+ double gw; /* Gap width. */
+ size_t nsv; /* Number of elements in xsv. */
+ $? "+ f2lpgf_pgf_set_line_style"
+ ph = 0.0; nsv = 0; xsv[0] = 0.0;
+ gw = f2lto_find_gap_length(job, lw, sv);
+ switch(ls) {
+ case DK3_FIG_LS_DASH_TRIPLE_DOTTED: {
+ xsv[0] = sv;
+ xsv[1] = gw;
+ xsv[2] = lw;
+ xsv[3] = gw;
+ xsv[4] = lw;
+ xsv[5] = gw;
+ xsv[6] = lw;
+ xsv[7] = gw;
+ nsv = 8;
+ } break;
+ case DK3_FIG_LS_DASH_DOUBLE_DOTTED: {
+ xsv[0] = sv;
+ xsv[1] = gw;
+ xsv[2] = lw;
+ xsv[3] = gw;
+ xsv[4] = lw;
+ xsv[5] = gw;
+ nsv = 6;
+ } break;
+ case DK3_FIG_LS_DASH_DOTTED: {
+ xsv[0] = sv;
+ xsv[1] = gw;
+ xsv[2] = lw;
+ xsv[3] = gw;
+ nsv = 4;
+ } break;
+ case DK3_FIG_LS_DOTTED: {
+ xsv[0] = lw; xsv[1] = gw;
+ nsv = 2;
+ } break;
+ case DK3_FIG_LS_DASHED: {
+ xsv[0] = sv; xsv[1] = gw;
+ nsv = 2;
+ } break;
+ }
+ f2lpgf_set_line_dash(job->of1, xsv, nsv, ph);
+ $? "- f2lpgf_pgf_set_line_style"
+}
+
+
+
+void
+f2lpgf_pgf_set_line_end(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int le
+)
+{
+ $? "+ f2lpgf_pgf_set_line_end"
+ switch(le) {
+ case DK3_FIG_LC_PROJECTING: {
+ fputs(f2lpgf_c8_kw[29], job->of1);
+ } break;
+ case DK3_FIG_LC_ROUND: {
+ fputs(f2lpgf_c8_kw[30], job->of1);
+ } break;
+ default: {
+ fputs(f2lpgf_c8_kw[31], job->of1);
+ } break;
+ }
+ $? "- f2lpgf_pgf_set_line_end"
+}
+
+
+
+void
+f2lpgf_pgf_set_line_join(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int lj
+)
+{
+ $? "+ f2lpgf_pgf_set_line_join"
+ switch(lj) {
+ case DK3_FIG_LJ_BEVEL: {
+ fputs(f2lpgf_c8_kw[32], job->of1);
+ } break;
+ case DK3_FIG_LJ_ROUND: {
+ fputs(f2lpgf_c8_kw[33], job->of1);
+ } break;
+ default: {
+ fputs(f2lpgf_c8_kw[34], job->of1);
+ } break;
+ }
+ $? "- f2lpgf_pgf_set_line_join"
+}
+
+
+
+void
+f2lpgf_pgf_set_color_1(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+)
+{
+ $? "+ f2lpgf_pgf_set_color_1"
+ f2lpgf_define_color(job->of1, 0, rgb);
+ fputs(f2lpgf_c8_kw[37], job->of1);
+ $? "- f2lpgf_pgf_set_color_1"
+}
+
+
+
+void
+f2lpgf_pgf_set_color_2(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+)
+{
+ $? "+ f2lpgf_pgf_set_color_2"
+ f2lpgf_define_color(job->of1, 1, rgb);
+ fputs(f2lpgf_c8_kw[38], job->of1);
+ $? "- f2lpgf_pgf_set_color_2"
+}
+
+
+
+void
+f2lpgf_pgf_setcolor(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double r,
+ double g,
+ double b
+)
+{
+ dk3_rgb_color_t rgb; /* Color cell. */
+ $? "+ f2lpgf_pgf_setcolor"
+ rgb.r = r; rgb.g = g; rgb.b = b;
+ f2lpgf_pgf_set_color_1(job, drw, &rgb);
+ rgb.r = r; rgb.g = g; rgb.b = b;
+ f2lpgf_pgf_set_color_2(job, drw, &rgb);
+ $? "- f2lpgf_pgf_setcolor"
+}
+
+
+void
+f2lpgf_pgf_debug(
+ f2l_job_t *job,
+ char const *msg
+)
+{
+ $? "+ f2lpgf_pgf_debug"
+ fputs(f2lpgf_c8_kw[39], job->of1);
+ fputs(msg, job->of1);
+ fputc('\n', job->of1);
+ $? "- f2lpgf_pgf_debug"
+}
+
+
+
+$*
+ TeX output driver functions.
+$*
+
+int
+f2lpgf_tex_initialize(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ int back = 0;
+ back = f2lpgf_pgf_initialize(job, drw);
+ return back;
+}
+
+
+
+void
+f2lpgf_tex_end(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ f2lpgf_pgf_end(job, drw);
+}
+
+
+
+int
+f2lpgf_tex_open_output_files(f2l_job_t *job)
+{
+ int back = 0;
+ back = f2lpgf_pgf_open_output_files(job);
+ return back;
+}
+
+
+
+void
+f2lpgf_tex_close_output_files(f2l_job_t *job)
+{
+ f2lpgf_pgf_close_output_files(job);
+}
+
+
+
+int
+f2lpgf_tex_start_processing(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ int back = 0;
+ f2l_tool_begin_latex_document(job->of1, job, drw);
+ back = f2lpgf_pgf_start_processing(job, drw);
+ return back;
+}
+
+
+
+void
+f2lpgf_tex_end_processing(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ f2lpgf_pgf_end_processing(job, drw);
+ f2l_tool_end_latex_document(job->of1, job, drw);
+}
+
+
+
+void
+f2lpgf_tex_text_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+ f2lpgf_pgf_text_object(job, drw, obj, x, y);
+}
+
+
+
+void
+f2lpgf_tex_image_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int drawdir,
+ int *ec
+)
+{
+ f2lpgf_pgf_image_object(job, drw, obj, outbb, drawdir, ec);
+}
+
+
+
+void
+f2lpgf_tex_newpath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2lpgf_pgf_newpath(job, drw, obj);
+}
+
+
+
+void
+f2lpgf_tex_moveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+ f2lpgf_pgf_moveto(job, drw, obj, x, y);
+}
+
+
+
+void
+f2lpgf_tex_lineto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+ f2lpgf_pgf_lineto(job, drw, obj, x, y);
+}
+
+
+
+void
+f2lpgf_tex_curveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double xcs,
+ double ycs,
+ double xce,
+ double yce,
+ double xe,
+ double ye
+)
+{
+ f2lpgf_pgf_curveto(job, drw, obj, xcs, ycs, xce, yce, xe, ye);
+}
+
+
+
+void
+f2lpgf_tex_closepath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2lpgf_pgf_closepath(job, drw, obj);
+}
+
+
+
+void
+f2lpgf_tex_fill(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2lpgf_pgf_fill(job, drw, obj);
+}
+
+
+
+void
+f2lpgf_tex_fill_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2lpgf_pgf_fill_stroke(job, drw, obj);
+}
+
+
+
+void
+f2lpgf_tex_fill_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2lpgf_pgf_fill_clip(job, drw, obj);
+}
+
+
+
+void
+f2lpgf_tex_fill_stroke_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2lpgf_pgf_fill_stroke_clip(job, drw, obj);
+}
+
+
+
+void
+f2lpgf_tex_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2lpgf_pgf_clip(job, drw, obj);
+}
+
+
+
+void
+f2lpgf_tex_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2lpgf_pgf_stroke(job, drw, obj);
+}
+
+
+
+void
+f2lpgf_tex_gsave(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2lpgf_pgf_gsave(job, drw, obj);
+}
+
+
+
+void
+f2lpgf_tex_grestore(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2lpgf_pgf_grestore(job, drw, obj);
+}
+
+
+
+void
+f2lpgf_tex_setcolor(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double r,
+ double g,
+ double b
+)
+{
+ f2lpgf_pgf_setcolor(job, drw, obj, r, g, b);
+}
+
+
+
+void
+f2lpgf_tex_set_line_width(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double lw
+)
+{
+ f2lpgf_pgf_set_line_width(job, drw, obj, lw);
+}
+
+
+
+void
+f2lpgf_tex_set_line_style(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int ls,
+ double sv,
+ double lw
+)
+{
+ f2lpgf_pgf_set_line_style(job, drw, obj, ls, sv, lw);
+}
+
+
+
+void
+f2lpgf_tex_set_line_end(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int le
+)
+{
+ f2lpgf_pgf_set_line_end(job, drw, obj, le);
+}
+
+
+
+void
+f2lpgf_tex_set_line_join(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int lj
+)
+{
+ f2lpgf_pgf_set_line_join(job, drw, obj, lj);
+}
+
+
+
+void
+f2lpgf_tex_set_color_1(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+)
+{
+ f2lpgf_pgf_set_color_1(job, drw, rgb);
+}
+
+
+
+void
+f2lpgf_tex_set_color_2(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+)
+{
+ f2lpgf_pgf_set_color_2(job, drw, rgb);
+}
+
+
+
+void
+f2lpgf_tex_debug(
+ f2l_job_t *job,
+ char const *msg
+)
+{
+ f2lpgf_pgf_debug(job, msg);
+}
+
diff --git a/support/dktools/f2lpgf.h b/support/dktools/f2lpgf.h
new file mode 100644
index 0000000000..460b790b12
--- /dev/null
+++ b/support/dktools/f2lpgf.h
@@ -0,0 +1,791 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: f2lpgf.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file f2lpgf.h Header file for the f2lpgf module.
+*/
+
+#ifndef F2LPGF_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define F2LPGF_H_INCLUDED 1
+
+
+#line 10 "f2lpgf.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Driver initialization for tex output.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+int
+f2lpgf_tex_initialize(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Driver cleanup for tex driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+void
+f2lpgf_tex_end(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Open output files for tex driver.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+f2lpgf_tex_open_output_files(f2l_job_t *job);
+
+/** Close output files for tex driver.
+ @param job Job structure.
+*/
+void
+f2lpgf_tex_close_output_files(f2l_job_t *job);
+
+/** Write start of output for tex driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+int
+f2lpgf_tex_start_processing(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Write end of output for tex driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+void
+f2lpgf_tex_end_processing(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Process one text object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x Point x.
+ @param y Point y.
+*/
+void
+f2lpgf_tex_text_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Process one image object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param outbb Bounding box for image.
+ @param drawdir Drawing direction.
+ @param ec Pointer to error code variable, may be NULL.
+*/
+void
+f2lpgf_tex_image_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int drawdir,
+ int *ec
+);
+
+/** Start new path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_tex_newpath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Move to point.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x Point x.
+ @param y Point y.
+*/
+void
+f2lpgf_tex_moveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Draw line to point.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x Point x.
+ @param y Point y.
+*/
+void
+f2lpgf_tex_lineto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Draw curve to point.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param xcs Start control point y.
+ @param ycs Start control point y.
+ @param xce End control point x.
+ @param yce End control point y.
+ @param xe End point x.
+ @param ye End point y.
+*/
+void
+f2lpgf_tex_curveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double xcs,
+ double ycs,
+ double xce,
+ double yce,
+ double xe,
+ double ye
+);
+
+/** Close path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_tex_closepath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Fill path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_tex_fill(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Fill and stroke path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_tex_fill_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Fill and clip path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_tex_fill_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Fill, stroke and clip path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_tex_fill_stroke_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Clip drawing operations to path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_tex_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Stroke path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_tex_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Save graphics state.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_tex_gsave(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Restore graphics state.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_tex_grestore(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Set color.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param r Red.
+ @param g Green.
+ @param b Blue.
+*/
+void
+f2lpgf_tex_setcolor(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double r,
+ double g,
+ double b
+);
+
+/** Set line width.
+ The line width is not set again if we already
+ have a current line width equal to the new line width.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param lw New line width in output coordinates.
+*/
+void
+f2lpgf_tex_set_line_width(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double lw
+);
+
+/** Set line style.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object to set up.
+ @param ls Line style, see @ref dk3figlinestyles.
+ @param sv Style value in output coordinates.
+ @param lw Dot length in output coordinates.
+*/
+void
+f2lpgf_tex_set_line_style(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int ls,
+ double sv,
+ double lw
+);
+
+/** Set line end.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param le Line end, see @ref dk3figlinecap.
+*/
+void
+f2lpgf_tex_set_line_end(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int le
+);
+
+/** Set line join.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param lj Line join style, see @ref dk3figlinejoin.
+*/
+void
+f2lpgf_tex_set_line_join(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int lj
+);
+
+/** Set current color or stroking color (PGF, PDF).
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param rgb New color value.
+*/
+void
+f2lpgf_tex_set_color_1(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+);
+
+/** Set non-stroking color (PGF, PDF).
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param rgb New color value.
+*/
+void
+f2lpgf_tex_set_color_2(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+);
+
+/** Write debugging line to output file.
+ @param job Job structure.
+ @param msg Message to write to output file.
+*/
+void
+f2lpgf_tex_debug(
+ f2l_job_t *job,
+ char const *msg
+);
+
+/** Driver initialization for pgf output.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+int
+f2lpgf_pgf_initialize(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Driver cleanup for pgf driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+void
+f2lpgf_pgf_end(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Open output files for pgf driver.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+f2lpgf_pgf_open_output_files(f2l_job_t *job);
+
+/** Close output files for tex driver.
+ @param job Job structure.
+*/
+void
+f2lpgf_pgf_close_output_files(f2l_job_t *job);
+
+/** Write start of output for pgf driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+int
+f2lpgf_pgf_start_processing(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Write end of output for pgf driver.
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+void
+f2lpgf_pgf_end_processing(f2l_job_t *job, dk3_fig_drawing_t *drw);
+
+/** Process one text object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x Point x.
+ @param y Point y.
+*/
+void
+f2lpgf_pgf_text_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Process one image object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param outbb Bounding box for image.
+ @param drawdir Drawing direction.
+ @param ec Pointer to error code variable, may be NULL.
+*/
+void
+f2lpgf_pgf_image_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int drawdir,
+ int *ec
+);
+
+/** Start new path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_pgf_newpath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Move to point.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x Point x.
+ @param y Point y.
+*/
+void
+f2lpgf_pgf_moveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Draw line to point.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x Point x.
+ @param y Point y.
+*/
+void
+f2lpgf_pgf_lineto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Draw curve to point.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param xcs Start control point y.
+ @param ycs Start control point y.
+ @param xce End control point x.
+ @param yce End control point y.
+ @param xe End point x.
+ @param ye End point y.
+*/
+void
+f2lpgf_pgf_curveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double xcs,
+ double ycs,
+ double xce,
+ double yce,
+ double xe,
+ double ye
+);
+
+/** Close path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_pgf_closepath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Fill path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_pgf_fill(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Fill and stroke path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_pgf_fill_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Fill and clip path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_pgf_fill_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Fill,stroke and clip path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_pgf_fill_stroke_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Clip drawing operations to path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_pgf_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Stroke path.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_pgf_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Save graphics state.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_pgf_gsave(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Restore graphics state.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lpgf_pgf_grestore(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Set color.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param r Red.
+ @param g Green.
+ @param b Blue.
+*/
+void
+f2lpgf_pgf_setcolor(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double r,
+ double g,
+ double b
+);
+
+/** Set line width.
+ The line width is not set again if we already
+ have a current line width equal to the new line width.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param lw New line width in output coordinates.
+*/
+void
+f2lpgf_pgf_set_line_width(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double lw
+);
+
+/** Set line style.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object to set up.
+ @param ls Line style, see @ref dk3figlinestyles.
+ @param sv Style value in output coordinates.
+ @param lw Dot length in output coordinates.
+*/
+void
+f2lpgf_pgf_set_line_style(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int ls,
+ double sv,
+ double lw
+);
+
+/** Set line end.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param le Line end, see @ref dk3figlinecap.
+*/
+void
+f2lpgf_pgf_set_line_end(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int le
+);
+
+/** Set line join.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param lj Line join style, see @ref dk3figlinejoin.
+*/
+void
+f2lpgf_pgf_set_line_join(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int lj
+);
+
+/** Set current color or stroking color (PGF, PDF).
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param rgb New color value.
+*/
+void
+f2lpgf_pgf_set_color_1(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+);
+
+/** Set non-stroking color (PGF, PDF).
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param rgb New color value.
+*/
+void
+f2lpgf_pgf_set_color_2(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_rgb_color_t *rgb
+);
+
+/** Write debugging line to output file.
+ @param job Job structure.
+ @param msg Message to write to output file.
+*/
+void
+f2lpgf_pgf_debug(
+ f2l_job_t *job,
+ char const *msg
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/f2lsvg.c b/support/dktools/f2lsvg.c
new file mode 100644
index 0000000000..f8d8442269
--- /dev/null
+++ b/support/dktools/f2lsvg.c
@@ -0,0 +1,3590 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: f2lsvg.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file f2lsvg.c The f2lsvg module.
+*/
+
+
+#line 28 "f2lsvg.ctr"
+
+#include "dk3all.h"
+#include "dk3bezcu.h"
+#include "dk3font.h"
+#include "fig2lat.h"
+#include "f2lud.h"
+#include "f2lsvg.h"
+#include "f2lsvgst.h"
+#include "f2lpara.h"
+#include "dk3figto.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4vers.h"
+#include "dk3xsp.h"
+#include "dk3font.h"
+#include "dk3bif.h"
+
+
+
+
+
+#line 49 "f2lsvg.ctr"
+
+
+
+/** Keywords used by the module.
+*/
+static char const * const f2lsvg_c8_kw[] = {
+/* 0 */
+"\n",
+
+/* 1 */
+" ",
+
+/* 2 */
+"<?xml version=\"1.0\" encoding=\"iso-8859-1\" standalone=\"no\"?>\n",
+
+/* 3 */
+"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 20010904//EN\"\n",
+
+/* 4 */
+"\"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\"\n",
+
+/* 5 */
+">\n",
+
+/* 6 */
+"<",
+
+/* 7 */
+"svg:",
+
+/* 8 */
+"/",
+
+/* 9 */
+">",
+
+/* 10 */
+"svg",
+
+/* 11 */
+"width=\"%lgin\" height=\"%lgin\" viewBox=\"0 0 %ld %ld\"",
+
+/* 12 */
+"xmlns=\"http://www.w3.org/2000/svg\"\n",
+
+/* 13 */
+"xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n",
+
+/* 14 */
+"title",
+
+/* 15 */
+"desc",
+
+/* 16 */
+"Fig file converted by fig2lat",
+
+/* 17 */
+"http://dktools.sourceforge.net/fig2lat.html",
+
+/* 18 */
+"defs",
+
+/* 19 */
+"style",
+
+/* 20 */
+"type=\"text/css\"",
+
+/* 21 */
+"<![CDATA[",
+
+/* 22 */
+"]]>",
+
+/* 23 */
+"@font-face {\n",
+
+/* 24 */
+"}\n",
+
+/* 25 */
+"font-family: \"",
+
+/* 26 */
+"\";\n",
+
+/* 27 */
+"font-style: oblique;\n",
+
+/* 28 */
+"font-style: italic;\n",
+
+/* 29 */
+"font-style: normal;\n",
+
+/* 30 */
+"font-weight: %d;\n",
+
+/* 31 */
+"src: url(\"",
+
+/* 32 */
+".ttf",
+
+/* 33 */
+"\");\n",
+
+/* 34 */
+"file://",
+
+/* 35 */
+"g",
+
+/* 36 */
+"/>\n",
+
+/* 37 */
+"rect",
+
+/* 38 */
+"x=\"%lg\" y=\"%lg\" width=\"%lg\" height=\"%lg\"",
+
+/* 39 */
+" rx=\"%lg\" ry=\"%lg\"",
+
+/* 40 */
+"polygon",
+
+/* 41 */
+"points=\"",
+
+/* 42 */
+"\"\n",
+
+/* 43 */
+"%lg,%lg",
+
+/* 44 */
+"polyline",
+
+/* 45 */
+"circle",
+
+/* 46 */
+"ellipse",
+
+/* 47 */
+"\ncx=\"%lg\" cy=\"%lg\" r=\"%lg\"\n",
+
+/* 48 */
+"\ntransform=\"translate(%lg %lg) rotate(%lg)\" rx=\"%lg\" ry=\"%lg\"\n",
+
+/* 49 */
+"\ncx=\"%lg\" cy=\"%lg\" rx=\"%lg\" ry=\"%lg\"\n",
+
+/* 50 */
+"text",
+
+/* 51 */
+">",
+
+/* 52 */
+"\nx=\"%lg\" y=\"%lg\" ",
+
+/* 53 */
+"\ntransform=\"translate(%lg %lg) rotate(%lg)\" x=\"0\" y=\"0\"\n",
+
+/* 54 */
+"path",
+
+/* 55 */
+"\nd=\"",
+
+/* 56 */
+"M%lg,%lg\n",
+
+/* 57 */
+"C%lg,%lg %lg,%lg %lg,%lg",
+
+/* 58 */
+"L%lg,%lg\n",
+
+/* 59 */
+"Z",
+
+/* 60 */
+"\ntransform=\"translate(%lg %lg)",
+
+/* 61 */
+" rotate(%d)",
+
+/* 62 */
+" scale(",
+
+/* 63 */
+"1",
+
+/* 64 */
+"-1",
+
+/* 65 */
+")",
+
+/* 66 */
+"image",
+
+/* 67 */
+"\nx=\"0\" y=\"0\" width=\"%lg\" height=\"%lg\"\nxlink:href=\"",
+
+NULL
+
+
+#line 239 "f2lsvg.ctr"
+};
+
+
+
+/** Translation table for ASCII characters.
+*/
+static char const * const f2lsvg_html_translation_table[] = {
+/* 0 00 */ NULL,
+/* 1 01 */ NULL,
+/* 2 02 */ NULL,
+/* 3 03 */ NULL,
+/* 4 04 */ NULL,
+/* 5 05 */ NULL,
+/* 6 06 */ NULL,
+/* 7 07 */ NULL,
+/* 8 08 */ NULL,
+/* 9 09 */ "\t",
+/* 10 0a */ NULL,
+/* 11 0b */ NULL,
+/* 12 0c */ NULL,
+/* 13 0d */ NULL,
+/* 14 0e */ NULL,
+/* 15 0f */ NULL,
+/* 16 10 */ NULL,
+/* 17 11 */ NULL,
+/* 18 12 */ NULL,
+/* 19 13 */ NULL,
+/* 20 14 */ NULL,
+/* 21 15 */ NULL,
+/* 22 16 */ NULL,
+/* 23 17 */ NULL,
+/* 24 18 */ NULL,
+/* 25 19 */ NULL,
+/* 26 1a */ NULL,
+/* 27 1b */ NULL,
+/* 28 1c */ NULL,
+/* 29 1d */ NULL,
+/* 30 1e */ NULL,
+/* 31 1f */ NULL,
+/* 32 20 */ " ",
+/* 33 21 */ "!",
+/* 34 22 */ "\"",
+/* 35 23 */ "#",
+/* 36 24 */ "$",
+/* 37 25 */ "%",
+/* 38 26 */ "&amp;",
+/* 39 27 */ "'",
+/* 40 28 */ "(",
+/* 41 29 */ ")",
+/* 42 2a */ "*",
+/* 43 2b */ "+",
+/* 44 2c */ ",",
+/* 45 2d */ "-",
+/* 46 2e */ ".",
+/* 47 2f */ "/",
+/* 48 30 */ "0",
+/* 49 31 */ "1",
+/* 50 32 */ "2",
+/* 51 33 */ "3",
+/* 52 34 */ "4",
+/* 53 35 */ "5",
+/* 54 36 */ "6",
+/* 55 37 */ "7",
+/* 56 38 */ "8",
+/* 57 39 */ "9",
+/* 58 3a */ ":",
+/* 59 3b */ ";",
+/* 60 3c */ "&lt;",
+/* 61 3d */ "=",
+/* 62 3e */ "&gt;",
+/* 63 3f */ "?",
+/* 64 40 */ "@",
+/* 65 41 */ "A",
+/* 66 42 */ "B",
+/* 67 43 */ "C",
+/* 68 44 */ "D",
+/* 69 45 */ "E",
+/* 70 46 */ "F",
+/* 71 47 */ "G",
+/* 72 48 */ "H",
+/* 73 49 */ "I",
+/* 74 4a */ "J",
+/* 75 4b */ "K",
+/* 76 4c */ "L",
+/* 77 4d */ "M",
+/* 78 4e */ "N",
+/* 79 4f */ "O",
+/* 80 50 */ "P",
+/* 81 51 */ "Q",
+/* 82 52 */ "R",
+/* 83 53 */ "S",
+/* 84 54 */ "T",
+/* 85 55 */ "U",
+/* 86 56 */ "V",
+/* 87 57 */ "W",
+/* 88 58 */ "X",
+/* 89 59 */ "Y",
+/* 90 5a */ "Z",
+/* 91 5b */ "[",
+/* 92 5c */ "\\",
+/* 93 5d */ "]",
+/* 94 5e */ "^",
+/* 95 5f */ "_",
+/* 96 60 */ "`",
+/* 97 61 */ "a",
+/* 98 62 */ "b",
+/* 99 63 */ "c",
+/* 100 64 */ "d",
+/* 101 65 */ "e",
+/* 102 66 */ "f",
+/* 103 67 */ "g",
+/* 104 68 */ "h",
+/* 105 69 */ "i",
+/* 106 6a */ "j",
+/* 107 6b */ "k",
+/* 108 6c */ "l",
+/* 109 6d */ "m",
+/* 110 6e */ "n",
+/* 111 6f */ "o",
+/* 112 70 */ "p",
+/* 113 71 */ "q",
+/* 114 72 */ "r",
+/* 115 73 */ "s",
+/* 116 74 */ "t",
+/* 117 75 */ "u",
+/* 118 76 */ "v",
+/* 119 77 */ "w",
+/* 120 78 */ "x",
+/* 121 79 */ "y",
+/* 122 7a */ "z",
+/* 123 7b */ "{",
+/* 124 7c */ "|",
+/* 125 7d */ "}",
+/* 126 7e */ "~",
+/* 127 7f */ NULL,
+/* 128 80 */ NULL,
+/* 129 81 */ NULL,
+/* 130 82 */ NULL,
+/* 131 83 */ NULL,
+/* 132 84 */ NULL,
+/* 133 85 */ NULL,
+/* 134 86 */ NULL,
+/* 135 87 */ NULL,
+/* 136 88 */ NULL,
+/* 137 89 */ NULL,
+/* 138 8a */ NULL,
+/* 139 8b */ NULL,
+/* 140 8c */ NULL,
+/* 141 8d */ NULL,
+/* 142 8e */ NULL,
+/* 143 8f */ NULL,
+/* 144 90 */ NULL,
+/* 145 91 */ NULL,
+/* 146 92 */ NULL,
+/* 147 93 */ NULL,
+/* 148 94 */ NULL,
+/* 149 95 */ NULL,
+/* 150 96 */ NULL,
+/* 151 97 */ NULL,
+/* 152 98 */ NULL,
+/* 153 99 */ NULL,
+/* 154 9a */ NULL,
+/* 155 9b */ NULL,
+/* 156 9c */ NULL,
+/* 157 9d */ NULL,
+/* 158 9e */ NULL,
+/* 159 9f */ NULL,
+/* 160 a0 */ "&nbsp;",
+/* 161 a1 */ "&iexcl;",
+/* 162 a2 */ "&cent;",
+/* 163 a3 */ "&pound;",
+/* 164 a4 */ "&curren;",
+/* 165 a5 */ "&yen;",
+/* 166 a6 */ "&brvbar;",
+/* 167 a7 */ "&sect;",
+/* 168 a8 */ "&uml;",
+/* 169 a9 */ "&copy;",
+/* 170 aa */ "&ordf;",
+/* 171 ab */ "&laquo;",
+/* 172 ac */ "&not;",
+/* 173 ad */ "&shy;",
+/* 174 ae */ "&reg;",
+/* 175 af */ "&macr;",
+/* 176 b0 */ "&deg;",
+/* 177 b1 */ "&plusmn;",
+/* 178 b2 */ "&sup2;",
+/* 179 b3 */ "&sup3;",
+/* 180 b4 */ "&acute;",
+/* 181 b5 */ "&micro;",
+/* 182 b6 */ "&para;",
+/* 183 b7 */ "&middot;",
+/* 184 b8 */ "&cedil;",
+/* 185 b9 */ "&sup1;",
+/* 186 ba */ "&ordm;",
+/* 187 bb */ "&raquo;",
+/* 188 bc */ "&frac14;",
+/* 189 bd */ "&frac12;",
+/* 190 be */ "&frac34;",
+/* 191 bf */ "&iquest;",
+/* 192 c0 */ "&Agrave;",
+/* 193 c1 */ "&Aacute;",
+/* 194 c2 */ "&Acirc;",
+/* 195 c3 */ "&Atilde;",
+/* 196 c4 */ "&Auml;",
+/* 197 c5 */ "&Aring;",
+/* 198 c6 */ "&AElig;",
+/* 199 c7 */ "&Ccedil;",
+/* 200 c8 */ "&Egrave;",
+/* 201 c9 */ "&Eacute;",
+/* 202 ca */ "&Ecirc;",
+/* 203 cb */ "&Euml;",
+/* 204 cc */ "/Igrave;",
+/* 205 cd */ "&Iacute;",
+/* 206 ce */ "&Icirc;",
+/* 207 cf */ "&Iuml;",
+/* 208 d0 */ "&ETH;",
+/* 209 d1 */ "&Ntilde;",
+/* 210 d2 */ "&Ograve;",
+/* 211 d3 */ "&Oacute;",
+/* 212 d4 */ "&Ocirc;",
+/* 213 d5 */ "&Otilde;",
+/* 214 d6 */ "&Ouml;",
+/* 215 d7 */ "&times;",
+/* 216 d8 */ "&Oslash;",
+/* 217 d9 */ "&Ugrave;",
+/* 218 da */ "&Uacute;",
+/* 219 db */ "&Ucirc;",
+/* 220 dc */ "&Uuml;",
+/* 221 dd */ "&Yacute;",
+/* 222 de */ "&THORN;",
+/* 223 df */ "&szlig;",
+/* 224 e0 */ "&agrave;",
+/* 225 e1 */ "&aacute;",
+/* 226 e2 */ "&acirc;",
+/* 227 e3 */ "&atilde;",
+/* 228 e4 */ "&auml;",
+/* 229 e5 */ "&aring;",
+/* 230 e6 */ "&aelig;",
+/* 231 e7 */ "&ccedil;",
+/* 232 e8 */ "&egrave;",
+/* 233 e9 */ "&eacute;",
+/* 234 ea */ "&ecirc;",
+/* 235 eb */ "&euml;",
+/* 236 ec */ "&igrave;",
+/* 237 ed */ "&iacute;",
+/* 238 ee */ "&icirc;",
+/* 239 ef */ "&iuml;",
+/* 240 f0 */ "&eth;",
+/* 241 f1 */ "&ntilde;",
+/* 242 f2 */ "&ograve;",
+/* 243 f3 */ "&oacute;",
+/* 244 f4 */ "&ocirc;",
+/* 245 f5 */ "&otilde;",
+/* 246 f6 */ "&ouml;",
+/* 247 f7 */ "&divide;",
+/* 248 f8 */ "&oslash;",
+/* 249 f9 */ "&ugrave;",
+/* 250 fa */ "&uacute;",
+/* 251 fb */ "&ucirc;",
+/* 252 fc */ "&uuml;",
+/* 253 fd */ "&yacute;",
+/* 254 fe */ "&thorn;",
+/* 255 ff */ "&yuml;"
+};
+
+
+/* ************************************************************************ */
+/* * * */
+/* * Tool functions * */
+/* * * */
+/* ************************************************************************ */
+
+
+#line 508 "f2lsvg.ctr"
+
+
+
+/** Write one text line, use special HTML notation for characters
+ if necessary.
+ @param str String to write.
+ @param of Output file.
+*/
+static
+void
+f2lsvg_fputs_translate(char const *str, FILE *of)
+{
+ char const *ptr;
+ char const *opt;
+ char c;
+ unsigned char uc;
+ unsigned u;
+ ptr = str;
+ while(*ptr) {
+ c = *(ptr++);
+ uc = (unsigned char)c;
+ u = (unsigned)uc;
+ while(255 < u) {
+ u -= 256;
+ }
+ opt = f2lsvg_html_translation_table[u];
+ if(opt) {
+ fputs(opt, of);
+ } else {
+ fputc(c, of);
+ }
+ }
+}
+
+
+
+/** Write SVG tag name.
+ For full SVG write the tag name directly, when producing an SVG
+ fragment we prepend svg:.
+ @param job Job structure.
+ @param ind Index of tag name in f2lsvg_c8_kw.
+*/
+static
+void
+f2lsvg_tag_name(f2l_job_t *job, size_t ind)
+{
+ if(job->fragment) {
+ fputs(f2lsvg_c8_kw[7], job->of1);
+ }
+ fputs(f2lsvg_c8_kw[ind], job->of1);
+}
+
+
+
+/** Start opening tag.
+ @param job Job structure.
+ @param ind Index of tag name in f2lsvg_c8_kw.
+*/
+static
+void
+f2lsvg_tag_open_start(f2l_job_t *job, size_t ind)
+{
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ if(job->fragment) {
+ fputs(f2lsvg_c8_kw[7], job->of1);
+ }
+ fputs(f2lsvg_c8_kw[ind], job->of1);
+ fputs(f2lsvg_c8_kw[1], job->of1);
+}
+
+
+
+/** End a tag.
+ @param job Job structure.
+*/
+static
+void
+f2lsvg_tag_end(f2l_job_t *job)
+{
+ fputs(f2lsvg_c8_kw[9], job->of1);
+}
+
+
+
+/** Opening tag.
+ @param job Job structure.
+ @param ind Index of tag name in f2lsvg_c8_kw.
+*/
+static
+void
+f2lsvg_tag_open(f2l_job_t *job, size_t ind)
+{
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ if(job->fragment) {
+ fputs(f2lsvg_c8_kw[7], job->of1);
+ }
+ fputs(f2lsvg_c8_kw[ind], job->of1);
+ f2lsvg_tag_end(job);
+}
+
+
+
+
+/** Write a closing tag.
+ @param job Job structure.
+ @param ind Index of tag name in f2lsvg_c8_kw.
+*/
+static
+void
+f2lsvg_tag_close(f2l_job_t *job, size_t ind)
+{
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ fputs(f2lsvg_c8_kw[8], job->of1);
+ if(job->fragment) {
+ fputs(f2lsvg_c8_kw[7], job->of1);
+ }
+ fputs(f2lsvg_c8_kw[ind], job->of1);
+ fputs(f2lsvg_c8_kw[9], job->of1);
+ fputs(f2lsvg_c8_kw[0], job->of1);
+}
+
+
+
+/** Calculate factors for coordinates transformations.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lsvg_coordinates_transformation(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ double xmin;
+ double xmax;
+ double ymin;
+ double ymax;
+ int back = 1;
+ int mec = 0;
+
+
+#line 647 "f2lsvg.ctr"
+ (job->ct2d).mx = (job->ct2d).my = dk3ma_d_div_ok(72.0, drw->res, &mec);
+ xmin = dk3ma_d_mul_ok((job->ct2d).mx, (drw->bb).xmin, &mec);
+ xmax = dk3ma_d_mul_ok((job->ct2d).mx, (drw->bb).xmax, &mec);
+ ymin = dk3ma_d_mul_ok((job->ct2d).my, (drw->bb).ymin, &mec);
+ ymax = dk3ma_d_mul_ok((job->ct2d).my, (drw->bb).ymax, &mec);
+ /* Align to 1/8 inch grid.
+ */
+ xmin = xmin / 9.0; xmin = floor(xmin);
+ xmin = dk3ma_d_mul_ok(9.0, xmin, &mec);
+ xmax = xmax / 9.0; xmax = ceil(xmax);
+ xmax = dk3ma_d_mul_ok(9.0, xmax, &mec);
+ ymin = ymin / 9.0; ymin = floor(ymin);
+ ymin = dk3ma_d_mul_ok(9.0, ymin, &mec);
+ ymax = ymax / 9.0; ymax = ceil(ymax);
+ ymax = dk3ma_d_mul_ok(9.0, ymax, &mec);
+ (job->ct2d).nx = -1.0 * xmin;
+ (job->ct2d).ny = -1.0 * ymin;
+ job->width = dk3ma_d_sub_ok(xmax, xmin, &mec);
+ job->height = dk3ma_d_sub_ok(ymax, ymin, &mec);
+ job->lwidth = dk3ma_d_to_l_ok(job->width, &mec);
+ job->lheight = dk3ma_d_to_l_ok(job->height, &mec);
+
+
+#line 669 "f2lsvg.ctr"
+
+
+#line 670 "f2lsvg.ctr"
+ if(mec) {
+ back = 0;
+ /* ERROR: Math problem */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 38);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
+
+#line 675 "f2lsvg.ctr"
+ }
+
+#line 676 "f2lsvg.ctr"
+ return back;
+}
+
+
+
+/** Collect style information for a text object,
+ add to SVG style collection if necessary.
+ @param job Job structure.
+ @param drw Fig drawing.
+ @param psvg SVG style collection.
+ @param pobj Object to add.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lsvg_text_object_style(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *pobj
+)
+{
+ f2l_svg_style_t sty; /* Style. */
+ dk3_fig_color_t fc; /* Fill color. */
+ int back = 1;
+
+
+#line 702 "f2lsvg.ctr"
+ if(!(DK3_FIG_FONT_FLAG_HIDDEN & ((pobj->dt).txt.ff))) {
+ f2lsvgst_style_initialize(&sty);
+ /* Fill color.
+ */
+ dk3fig_tool_find_int_color(&fc, drw, pobj->pc, 20);
+ f2lsvgst_style_set_fill_color(&sty, fc.r, fc.g, fc.b);
+ /* Text font.
+ */
+ f2lsvgst_style_set_text(
+ psvg, &sty,
+ ((((pobj->dt).txt.ff) & DK3_FIG_FONT_FLAG_PS) ? 1 : 0),
+ (pobj->dt).txt.fo,
+ (pobj->dt).txt.fs
+ );
+ /* Text alignment.
+ */
+ f2lsvgst_style_set_text_align(&sty, pobj->st);
+ pobj->dsd = (void *)f2lsvgst_style_add(psvg, &sty);
+ if(!(pobj->dsd)) {
+ back = 0;
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 723 "f2lsvg.ctr"
+ }
+ }
+
+
+#line 726 "f2lsvg.ctr"
+ return back;
+}
+
+
+
+/** Collect style information for a non-text object,
+ add to SVG style collection if necessary.
+ @param job Job structure.
+ @param drw Fig drawing.
+ @param psvg SVG style collection.
+ @param pobj Object to add.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lsvg_path_object_style(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *pobj
+)
+{
+ f2l_svg_style_t sty; /* Style. */
+ f2l_svg_fill_pattern_t pat; /* Pattern. */
+ dk3_fig_color_t fc; /* Fill color. */
+ dk3_fig_color_t sc; /* Stroke color. */
+ double lw; /* Line width in SVG units. */
+ double lsv; /* Line style value in SVG units. */
+ int res; /* Operation result. */
+ int mec = 0; /* Mathematical error code. */
+ int any = 0; /* Flag: Any settings applied to style. */
+ int op = 0; /* Draw operation. */
+ int back = 1 ;
+
+
+#line 760 "f2lsvg.ctr"
+ op = dk3fig_tool_get_operation(drw, pobj);
+ f2lsvgst_style_initialize(&sty);
+ if(op & DK3_FIG_OP_PATTERN) {
+ /* Fill pattern.
+ */
+ any = 1;
+ dk3fig_tool_find_int_color(&fc, drw, pobj->fc, 20);
+ dk3fig_tool_find_int_color(&sc, drw, pobj->pc, 20);
+ pat.pn = 0UL;
+ pat.fn = pobj->fi;
+ pat.sr = sc.r; pat.sg = sc.g; pat.sb = sc.b;
+ pat.fr = fc.r; pat.fg = fc.g; pat.fb = fc.b;
+ res = f2lsvgst_style_set_pattern(psvg, &sty, &pat);
+ if(!(res)) {
+ back = 0;
+ switch(psvg->ec) {
+ case DK3_ERROR_MEMORY: {
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 9);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 779 "f2lsvg.ctr"
+ } break;
+ default: {
+ /* ERROR: Mathematical error. */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 38);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
+
+#line 784 "f2lsvg.ctr"
+ } break;
+ }
+ }
+ } else {
+ if(op & DK3_FIG_OP_FILL) {
+ /* Fill color.
+ */
+ dk3fig_tool_find_int_color(&fc, drw, pobj->fc, pobj->fi);
+ f2lsvgst_style_set_fill_color(&sty, fc.r, fc.g, fc.b);
+ any = 1;
+ }
+ }
+ if(op & DK3_FIG_OP_STROKE) {
+ any = 1;
+ /* Line width.
+ */
+ lw = dk3fig_tool_get_lw(drw, pobj, &mec);
+ lw = dk3ct_2d_r(&(job->ct2d), lw, &mec);
+ f2lsvgst_style_set_line_width(&sty, lw);
+ if(mec) {
+ back = 0;
+ /* ERROR: Mathematical error. */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 38);
+ mec = 0;
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
+
+#line 809 "f2lsvg.ctr"
+ }
+ /* Line style.
+ */
+ /* lsv = dk3ct_2d_r(&(job->ct2d), pobj->sv, &mec); */
+ lsv = 0.9 * pobj->sv;
+ f2lsvgst_style_set_line_style(&sty, pobj->ls, lsv);
+ /* Stroke color.
+ */
+ dk3fig_tool_find_int_color(&sc, drw, pobj->pc, 20);
+ f2lsvgst_style_set_line_color(&sty, sc.r, sc.g, sc.b);
+ if(!(pobj->cl)) {
+ /* Line cap.
+ */
+ f2lsvgst_style_set_text_line_cap(&sty, pobj->cs);
+ }
+ }
+ if(op) {
+ if(DK3_FIG_OBJ_ELLIPSE != pobj->ot) {
+ if(!((DK3_FIG_OBJ_ARC == pobj->ot) && (1 == pobj->st))) {
+ /* Line join.
+ */
+ any = 1;
+ f2lsvgst_style_set_text_line_join(&sty, pobj->js);
+ }
+ }
+ }
+ if(any) {
+ pobj->dsd = (void *)f2lsvgst_style_add(psvg, &sty);
+ if(!(pobj->dsd)) {
+ back = 0;
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 840 "f2lsvg.ctr"
+ }
+ }
+
+
+#line 843 "f2lsvg.ctr"
+ return back;
+}
+
+
+
+/** Collect style information for one object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pobj Current object.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lsvg_object_style_collection(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *pobj
+)
+{
+ int back = 1;
+ switch(pobj->ot) {
+ case DK3_FIG_OBJ_PSEUDO_HALF_CIRCLE: {
+ if(!f2lsvg_path_object_style(job, drw, psvg, pobj)) { back = 0; }
+ } break;
+ case DK3_FIG_OBJ_ELLIPSE: {
+ if(!f2lsvg_path_object_style(job, drw, psvg, pobj)) { back = 0; }
+ } break;
+ case DK3_FIG_OBJ_POLYLINE: {
+ if(5 != pobj->st) {
+ if(!f2lsvg_path_object_style(job, drw, psvg, pobj)) { back = 0; }
+ }
+ } break;
+ case DK3_FIG_OBJ_SPLINE: {
+ if(!f2lsvg_path_object_style(job, drw, psvg, pobj)) { back = 0; }
+ } break;
+ case DK3_FIG_OBJ_ARC: {
+ if(!f2lsvg_path_object_style(job, drw, psvg, pobj)) { back = 0; }
+ } break;
+ case DK3_FIG_OBJ_TEXT: {
+ if(!f2lsvg_text_object_style(job, drw, psvg, pobj)) { back = 0; }
+ } break;
+ }
+ if(!(back)) {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN);
+
+#line 889 "f2lsvg.ctr"
+ }
+ return back;
+}
+
+
+
+/** Collect style information for all objects in drawing,
+ add styles to style collection.
+ @param job Job structure.
+ @param drw Fig drawing.
+ @param psvg SVG style collection.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lsvg_collect_styles(f2l_job_t *job, dk3_fig_drawing_t *drw, f2l_svg_t *psvg)
+{
+ dk3_fig_obj_t *pobj;
+ unsigned long objno = 0UL;
+ unsigned long oldsourceline;
+ int res;
+ int back = 1;
+
+
+#line 912 "f2lsvg.ctr"
+ oldsourceline = dk3app_get_source_line(job->app);
+ dk3sto_it_reset(drw->iobj);
+ while(NULL != (pobj = (dk3_fig_obj_t *)dk3sto_it_next(drw->iobj))) {
+ if(!dk3fig_tool_is_bgrect(pobj, objno)) {
+ dk3app_set_source_line(job->app, pobj->li);
+ if(!f2lsvg_object_style_collection(job, drw, psvg, pobj)) {
+ back = 0;
+ }
+ if(pobj->af) {
+ if((pobj->af)->o1) {
+ res = f2lsvg_object_style_collection(
+ job, drw, psvg, (dk3_fig_obj_t *)((pobj->af)->o1)
+ );
+ if(!(res)) { back = 0; }
+ }
+ if((pobj->af)->o2) {
+ res = f2lsvg_object_style_collection(
+ job, drw, psvg, (dk3_fig_obj_t *)((pobj->af)->o2)
+ );
+ if(!(res)) { back = 0; }
+ }
+ }
+ if(pobj->ab) {
+ if((pobj->ab)->o1) {
+ res = f2lsvg_object_style_collection(
+ job, drw, psvg, (dk3_fig_obj_t *)((pobj->ab)->o1)
+ );
+ if(!(res)) { back = 0; }
+ }
+ if((pobj->ab)->o2) {
+ res = f2lsvg_object_style_collection(
+ job, drw, psvg, (dk3_fig_obj_t *)((pobj->ab)->o2)
+ );
+ if(!(res)) { back = 0; }
+ }
+ }
+ }
+ objno++;
+ }
+ dk3app_set_source_line(job->app, oldsourceline);
+
+
+#line 953 "f2lsvg.ctr"
+ return back;
+}
+
+
+
+/** Check whether or not we must append a slash to the font base
+ directory.
+ @param bn Font base directory name.
+ @return 1 to add a slash, 0 for no slash needed.
+*/
+static
+int
+f2lsvg_must_add_slash_to_font_base(char const *bn)
+{
+ char const *ptr;
+ int back = 1;
+ ptr = bn;
+ while(*ptr) {
+ if('/' == *ptr) {
+ back = 0;
+ } else {
+ back = 1;
+ }
+ ptr++;
+ }
+ return back;
+}
+
+
+
+/** Write font face definitions.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+*/
+static
+void
+f2lsvg_write_font_faces(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg
+)
+{
+ dkChar dkb[DK3_MAX_PATH]; /* Font base (dkChars). */
+ char chb[DK3_MAX_PATH]; /* Font base (8-bit chars). */
+ size_t i; /* Walk through the 35 fonts. */
+ int fs; /* Font style. */
+ int res = 0;
+
+
+#line 1002 "f2lsvg.ctr"
+ if(0 < job->svgfontbase) {
+
+#line 1003 "f2lsvg.ctr"
+ switch(job->svgfontbase) {
+ case 2: {
+ res = dk3font_gs_base_web(job->app, dkb, DK3_SIZEOF(dkb,dkChar));
+ } break;
+ default: {
+ res = dk3font_gs_base_local(job->app, dkb, DK3_SIZEOF(dkb,dkChar));
+ } break;
+ }
+ if(res) {
+
+#line 1012 "f2lsvg.ctr"
+ res = dk3str_to_c8p_app(
+ chb, sizeof(chb), dkb, dk3app_get_encoding(job->app), job->app
+ );
+
+#line 1015 "f2lsvg.ctr"
+ }
+ for(i = 0; i < 35; i++) {
+
+#line 1017 "f2lsvg.ctr"
+ if((psvg->psFontsUsed)[i]) {
+ fputs(f2lsvg_c8_kw[23], job->of1);
+ /* Font family.
+ */
+ fputs(f2lsvg_c8_kw[25], job->of1);
+ fputs(dk3font_get_svg_family((int)i), job->of1);
+ fputs(f2lsvg_c8_kw[26], job->of1);
+
+#line 1024 "f2lsvg.ctr"
+ /* Font style
+ */
+ fs = dk3font_get_svg_features((int)i);
+ if(fs & DK3_FONT_OBLIQUE) {
+ fputs(f2lsvg_c8_kw[27], job->of1);
+ } else {
+ if(fs & DK3_FONT_ITALIC) {
+ fputs(f2lsvg_c8_kw[28], job->of1);
+ } else {
+ fputs(f2lsvg_c8_kw[29], job->of1);
+ }
+ }
+
+#line 1036 "f2lsvg.ctr"
+ /* Font weight
+ */
+ fprintf(job->of1,f2lsvg_c8_kw[30],dk3font_get_svg_font_weight((int)i));
+
+
+#line 1040 "f2lsvg.ctr"
+ /* Source
+ */
+ fputs(f2lsvg_c8_kw[31], job->of1);
+ if(res) {
+#if 0
+ /* 2013-01-30 No file:// prefix
+ */
+ if(1 == job->svgfontbase) {
+ fputs(f2lsvg_c8_kw[34], job->of1);
+ }
+#endif
+ fputs(chb, job->of1);
+ if(f2lsvg_must_add_slash_to_font_base(chb)) {
+ fputs(f2lsvg_c8_kw[8], job->of1);
+ }
+ }
+
+#line 1056 "f2lsvg.ctr"
+ fputs(dk3font_get_gs_old_file((int)i), job->of1);
+
+#line 1057 "f2lsvg.ctr"
+ fputs(f2lsvg_c8_kw[32], job->of1);
+#if 0
+ /* 2013-01-30 No font id for TTF fonts
+ */
+ fputs(dk3font_get_svg_fontid((int)i), job->of1);
+
+#line 1062 "f2lsvg.ctr"
+#endif
+ fputs(f2lsvg_c8_kw[33], job->of1);
+
+#line 1064 "f2lsvg.ctr"
+ fputs(f2lsvg_c8_kw[24], job->of1);
+
+#line 1065 "f2lsvg.ctr"
+ }
+
+#line 1066 "f2lsvg.ctr"
+ }
+
+#line 1067 "f2lsvg.ctr"
+ }
+
+#line 1068 "f2lsvg.ctr"
+}
+
+
+
+/* ************************************************************************ */
+/* * * */
+/* * Driver functions * */
+/* * * */
+/* ************************************************************************ */
+
+
+#line 1075 "f2lsvg.ctr"
+
+
+/** Driver-specific initialization.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lsvg_driver_initialize(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ f2l_svg_t *psvg;
+ int back = 0;
+
+
+#line 1089 "f2lsvg.ctr"
+ if(f2lsvg_coordinates_transformation(job, drw)) {
+ psvg = f2lsvgst_new_app(job->app);
+ if(psvg) {
+ drw->dsd = (void *)psvg;
+ back = f2lsvg_collect_styles(job, drw, psvg);
+ }
+ }
+
+#line 1096 "f2lsvg.ctr"
+ return back;
+}
+
+
+
+/** Release resources allocated by f2lud_driver_initialize().
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+static
+void
+f2lsvg_driver_end(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+
+
+#line 1110 "f2lsvg.ctr"
+ if(drw->dsd) {
+ f2lsvgst_delete((f2l_svg_t *)(drw->dsd));
+ } drw->dsd = NULL;
+
+
+#line 1114 "f2lsvg.ctr"
+}
+
+
+
+/** Open output file.
+ @param job Jobs structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lsvg_open_output_files(f2l_job_t *job)
+{
+ int back = 0;
+ job->of1 = dk3sf_fopen_app(job->on1, dkT("w"), job->app);
+ if(job->of1) {
+ back = 1;
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1132 "f2lsvg.ctr"
+ }
+ return back;
+}
+
+
+
+/** Close output file.
+ @param job Job structure.
+*/
+static
+void
+f2lsvg_close_output_files(f2l_job_t *job)
+{
+ if(job->of1) {
+ dk3sf_fclose_app(job->of1, job->app);
+ } job->of1 = NULL;
+}
+
+
+
+/** Check whether we must write a style tag for font faces or style
+ definitions.
+ @param job Job structure.
+ @param psvg SVG style collection structure.
+ @return 1 to write a style tag, 0 otherwise.
+*/
+static
+int
+f2lsvg_must_write_style(f2l_job_t *job, f2l_svg_t *psvg)
+{
+ int back = 0;
+ if(job->css) {
+ if(psvg->nStyles) {
+ back = 1;
+ }
+ }
+ if(0 < job->svgfontbase) {
+ if(f2lsvgst_any_ps_font_used(psvg)) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Check whether we must write a defs tag for fill patterns,
+ font faces, or style definitions.
+ @param job Job structure.
+ @param psvg SVG style collection structure.
+ @return 1 to write a defs tag, 0 otherwise.
+*/
+static
+int
+f2lsvg_must_write_defs(f2l_job_t *job, f2l_svg_t *psvg)
+{
+ int back;
+ back = f2lsvg_must_write_style(job, psvg);
+ if(0 == back) {
+ if(psvg->nPatterns) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Write start of output file.
+ @param job Job strucure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lsvg_start_processing(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ f2l_svg_t *psvg;
+ int back = 1;
+
+
+#line 1212 "f2lsvg.ctr"
+ psvg = (f2l_svg_t *)(drw->dsd);
+ /* XML header and doctype.
+ */
+ if(!(job->fragment)) {
+ fputs(f2lsvg_c8_kw[2], job->of1);
+ fputs(f2lsvg_c8_kw[3], job->of1);
+ fputs(f2lsvg_c8_kw[4], job->of1);
+ fputs(f2lsvg_c8_kw[5], job->of1);
+ }
+ /* Opening svg tag.
+ */
+ f2lsvg_tag_open_start(job, 10);
+ fprintf(
+ job->of1, f2lsvg_c8_kw[11],
+ (job->width / 72.0), (job->height / 72.0), job->lwidth, job->lheight
+ );
+ if(!(job->fragment)) {
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ fputs(f2lsvg_c8_kw[12], job->of1);
+ fputs(f2lsvg_c8_kw[13], job->of1);
+ }
+ f2lsvg_tag_end(job);
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ /* Title.
+ */
+ f2lsvg_tag_open(job, 14);
+ fputs(f2lsvg_c8_kw[16], job->of1);
+ f2lsvg_tag_close(job, 14);
+ /* Description.
+ */
+ f2lsvg_tag_open(job, 15);
+ fputs(f2lsvg_c8_kw[17], job->of1);
+ f2lsvg_tag_close(job, 15);
+ /* Definitions and style.
+ */
+ if(f2lsvg_must_write_defs(job, psvg)) {
+ f2lsvg_tag_open(job, 18);
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ /* Pattern definitions.
+ */
+ f2lsvgst_write_patterns(job, drw, psvg);
+ if(f2lsvg_must_write_style(job, psvg)) {
+ f2lsvg_tag_open_start(job, 19);
+ fputs(f2lsvg_c8_kw[20], job->of1);
+ f2lsvg_tag_end(job);
+ fputs(f2lsvg_c8_kw[21], job->of1);
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ /* Font face definitions if any.
+ */
+ f2lsvg_write_font_faces(job, drw, psvg);
+ /* Style definitions.
+ */
+ if(job->css) {
+ f2lsvgst_write_styles(job, drw, psvg);
+ }
+ fputs(f2lsvg_c8_kw[22], job->of1);
+ f2lsvg_tag_close(job, 19);
+ }
+ f2lsvg_tag_close(job, 18);
+ }
+
+#line 1272 "f2lsvg.ctr"
+ return back;
+}
+
+
+
+/** Write end of output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+static
+void
+f2lsvg_end_processing(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ f2lsvg_tag_close(job, 10);
+}
+
+
+
+/** Process ellipse object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_ellipse(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ double rotation = 0.0; /* Rotation in degree. */
+ double irot; /* Rotation as integer. */
+ double x; /* Center X. */
+ double y; /* Center Y. */
+ double rx; /* Radius X. */
+ double ry; /* Radius Y. */
+ int isEllipse = 0; /* Flag: Is ellipse. */
+ int isRotated = 0; /* Flag: Is rotated. */
+ int mec = 0; /* Mathematical error code. */
+
+ switch(obj->st) {
+ case 1: case 2: {
+ if(fabs(dk3ma_d_sub_ok((obj->dt).ell.rx,(obj->dt).ell.ry,&mec)) > 1.0e-6)
+ {
+ isEllipse = 1;
+ if(fabs((obj->dt).ell.an) > 1.0e-6) {
+ isRotated = 1;
+ rotation = dk3ma_d_mul_ok(180.0, ((obj->dt).ell.an / M_PI), &mec);
+ irot = dk3ma_d_rint(rotation);
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok(rotation, irot, &mec))) {
+ rotation = irot;
+ }
+ rotation = -1.0 * rotation;
+ }
+ }
+ } break;
+ }
+ x = dk3ct_2d_x(&(job->ct2d), (obj->dt).ell.cx, &mec);
+ y = dk3ct_2d_y(&(job->ct2d), (obj->dt).ell.cy, &mec);
+ rx = ry = dk3ct_2d_r(&(job->ct2d), (obj->dt).ell.rx, &mec);
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ if(isEllipse) {
+ ry = dk3ct_2d_r(&(job->ct2d), (obj->dt).ell.ry, &mec);
+ f2lsvg_tag_name(job, 46);
+ if(isRotated) {
+ fprintf(job->of1, f2lsvg_c8_kw[48], x, y, rotation, rx, ry);
+ } else {
+ fprintf(job->of1, f2lsvg_c8_kw[49], x, y, rx, ry);
+ }
+ } else {
+ f2lsvg_tag_name(job, 45);
+ fprintf(job->of1, f2lsvg_c8_kw[47], x, y, rx);
+ }
+ f2lsvgst_write_style_for_object(job, drw, psvg, obj);
+ fputs(f2lsvg_c8_kw[36], job->of1);
+ if(mec) { *ec = mec; }
+}
+
+
+
+/** Process box object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param arcbox Flag: Rounded corners.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_box(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int arcbox,
+ int *ec
+)
+{
+ dk3_bb_t outbb;
+ dk3_fig_poly_point_t *po;
+ double x;
+ double y;
+ double w;
+ double h;
+ double r;
+ size_t i;
+ int mec = 0;
+
+
+#line 1386 "f2lsvg.ctr"
+ po = (obj->dt).pol.po;
+ if(po) {
+ dk3bb_reset(&outbb);
+ for(i = 0; i < (obj->dt).pol.np; i++) {
+ dk3bb_add_x(&outbb, dk3ct_2d_x(&(job->ct2d), po->x, &mec));
+ dk3bb_add_y(&outbb, dk3ct_2d_y(&(job->ct2d), po->y, &mec));
+ po++;
+ }
+ x = outbb.xmin;
+ y = outbb.ymin;
+ w = fabs(dk3ma_d_sub_ok(outbb.xmax, outbb.xmin, &mec));
+ h = fabs(dk3ma_d_sub_ok(outbb.ymax, outbb.ymin, &mec));
+ r = -1.0;
+ if(arcbox) {
+
+#line 1400 "f2lsvg.ctr"
+ r = fabs(0.9 * (obj->dt).pol.ra);
+
+#line 1401 "f2lsvg.ctr"
+ if(r > (0.5 * w)) { r = 0.5 * w; }
+ if(r > (0.5 * h)) { r = 0.5 * h; }
+
+#line 1403 "f2lsvg.ctr"
+ }
+ if(0 == mec) {
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 37);
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ fprintf(job->of1, f2lsvg_c8_kw[38], x, y, w, h);
+ if(arcbox) {
+ fprintf(job->of1, f2lsvg_c8_kw[39], r, r);
+ }
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ f2lsvgst_write_style_for_object(job, drw, psvg, obj);
+ fputs(f2lsvg_c8_kw[36], job->of1);
+ }
+ }
+ dk3bb_reset(&outbb);
+ if(mec) { *ec = mec; }
+
+
+#line 1420 "f2lsvg.ctr"
+}
+
+
+
+/** Process polygon object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param primary Flag: Primary object.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_pl_polygon(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+ dk3_fig_poly_point_t *po;
+ size_t np;
+ size_t i;
+ int mec = 0;
+
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 40);
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ fputs(f2lsvg_c8_kw[41], job->of1);
+ po = (obj->dt).pol.po;
+ np = (obj->dt).pol.np;
+ if(primary) {
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok(po[0].x, po[np - 1].x, &mec))) {
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok(po[0].y, po[np - 1].y, &mec))) {
+ np--;
+ }
+ }
+ }
+ for(i = 0; i < np; i++) {
+ fprintf(
+ job->of1, f2lsvg_c8_kw[43],
+ dk3ct_2d_x(&(job->ct2d), po->x, &mec),
+ dk3ct_2d_y(&(job->ct2d), po->y, &mec)
+ );
+ if(i != (np - 1)) {
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ }
+ po++;
+ }
+ fputs(f2lsvg_c8_kw[42], job->of1);
+ f2lsvgst_write_style_for_object(job, drw, psvg, obj);
+ fputs(f2lsvg_c8_kw[36], job->of1);
+ if(mec) { *ec = mec; }
+}
+
+
+
+/** Process polygon object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_pl_polyline(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ dk3_fig_poly_point_t *po;
+ size_t np;
+ size_t i;
+ int mec = 0;
+
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 44);
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ fputs(f2lsvg_c8_kw[41], job->of1);
+ po = (obj->dt).pol.po;
+ np = (obj->dt).pol.np;
+ for(i = 0; i < np; i++) {
+ fprintf(
+ job->of1, f2lsvg_c8_kw[43],
+ dk3ct_2d_x(&(job->ct2d), po->x, &mec),
+ dk3ct_2d_y(&(job->ct2d), po->y, &mec)
+ );
+ if(i != (np - 1)) {
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ }
+ po++;
+ }
+ fputs(f2lsvg_c8_kw[42], job->of1);
+ f2lsvgst_write_style_for_object(job, drw, psvg, obj);
+ fputs(f2lsvg_c8_kw[36], job->of1);
+ if(mec) { *ec = mec; }
+}
+
+
+
+/** Process image object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_image(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ dk3_bb_t outbb; /* Output range. */
+ dk3_bif_t *bif; /* Image to process. */
+ dk3_fig_poly_point_t *po; /* Coordinates points. */
+ double tx; /* X translation. */
+ double ty; /* Y translation. */
+ double xres; /* Image resolution in x direction. */
+ double yres; /* Image resolution in y direction. */
+ double w; /* Image width (resolution used). */
+ double h; /* Image height (resolution used). */
+ double qx; /* Usable stretch factor for x. */
+ double qy; /* Usable stretch factor for y. */
+ double ow = 0.0; /* Output width. */
+ double oh = 0.0; /* Output height. */
+ double x1; /* Smallest x value. */
+ double x2; /* Largest x value. */
+ double y1; /* Smallest y value. */
+ double y2; /* Largest y value. */
+ dk3_bif_coord_t imw; /* Image width (number of pixels). */
+ dk3_bif_coord_t imh; /* Image height (number of pixels). */
+ size_t np; /* Number of coordinates points. */
+ size_t i; /* Traverse coordinates points. */
+ int drawdir; /* Drawing direction. */
+ int rotation = 0; /* Rotation in degree. */
+ int doScaleX = 0; /* Flag: Scale x=-1. */
+ int doScaleY = 0; /* Flag: Sclae y=-1. */
+
+ if((obj->dt).pol.fn) {
+ bif = dk3bif_open_c8_filename_app(
+ (obj->dt).pol.fn, DK3_BIF_IMAGE_TYPE_UNKNOWN, job->app
+ );
+ if(bif) {
+ /* Find image dimensions.
+ */
+ imw = dk3bif_get_width(bif);
+ imh = dk3bif_get_height(bif);
+ xres = dk3bif_get_xres(bif);
+ yres = dk3bif_get_yres(bif);
+ dk3bif_close(bif);
+ /* Find output area.
+ */
+ dk3bb_reset(&outbb);
+ po = (obj->dt).pol.po;
+ np = (obj->dt).pol.np;
+ for(i = 0; i < np; i++) {
+ dk3bb_add_x(&outbb, dk3ct_2d_x(&(job->ct2d), po->x, ec));
+ dk3bb_add_y(&outbb, dk3ct_2d_y(&(job->ct2d), po->y, ec));
+ po++;
+ }
+ x1 = outbb.xmin; x2 = outbb.xmax;
+ y1 = outbb.ymin; y2 = outbb.ymax;
+ /* Find drawing direction.
+ */
+ drawdir = f2lto_find_draw_direction(job, drw, obj, ec);
+ /* Find real image width and height.
+ */
+ if((xres > 0.0) && (yres > 0.0)) {
+ switch(drawdir) {
+ case DK3_IMAGE_ORIGIN_LEFT_BOTTOM:
+ case DK3_IMAGE_ORIGIN_RIGHT_TOP:
+ case DK3_IMAGE_ORIGIN_LEFT_TOP_FLIPPED:
+ case DK3_IMAGE_ORIGIN_RIGHT_BOTTOM_FLIPPED: {
+ w = dk3ma_d_div_ok((double)imh, yres, ec);
+ h = dk3ma_d_div_ok((double)imw, xres, ec);
+ } break;
+ default: {
+ w = dk3ma_d_div_ok((double)imw, xres, ec);
+ h = dk3ma_d_div_ok((double)imh, yres, ec);
+ } break;
+ }
+ } else {
+ switch(drawdir) {
+ case DK3_IMAGE_ORIGIN_LEFT_BOTTOM:
+ case DK3_IMAGE_ORIGIN_RIGHT_TOP:
+ case DK3_IMAGE_ORIGIN_LEFT_TOP_FLIPPED:
+ case DK3_IMAGE_ORIGIN_RIGHT_BOTTOM_FLIPPED: {
+ w = (double)imh;
+ h = (double)imw;
+ } break;
+ default: {
+ w = (double)imw;
+ h = (double)imh;
+ } break;
+ }
+ }
+ /* Find the stretch factors and used regions.
+ */
+ qx = dk3ma_d_div_ok(dk3ma_d_sub_ok(outbb.xmax, outbb.xmin, ec), w, ec);
+ qy = dk3ma_d_div_ok(dk3ma_d_sub_ok(outbb.ymax, outbb.ymin, ec), h, ec);
+ qx = fabs(qx);
+ qy = fabs(qy);
+#if VERSION_BEFORE_20150821
+ ow = oh = 0.0;
+#endif
+ if(qy >= qx) { /* Image too wide, can not use all height. */
+ ow = dk3ma_d_sub_ok(outbb.xmax, outbb.xmin, ec);
+ oh = dk3ma_d_mul_ok(qx, h, ec);
+ y1 = dk3ma_d_add_ok(
+ outbb.ymin,
+ (
+ 0.5 *
+ dk3ma_d_sub_ok(dk3ma_d_sub_ok(outbb.ymax, outbb.ymin, ec), oh, ec)
+ ),
+ ec
+ );
+ y2 = dk3ma_d_add_ok(y1, oh, ec);
+ } else { /* Image too high, can not use all width. */
+ oh = dk3ma_d_sub_ok(outbb.ymax, outbb.ymin, ec);
+ ow = dk3ma_d_mul_ok(qy, w, ec);
+ x1 = dk3ma_d_add_ok(
+ outbb.xmin,
+ (
+ 0.5 *
+ dk3ma_d_sub_ok(dk3ma_d_sub_ok(outbb.xmax, outbb.xmin, ec), ow, ec)
+ ),
+ ec
+ );
+ x2 = dk3ma_d_add_ok(x1, ow, ec);
+ }
+ /* Find coordinates transformations.
+ */
+ switch(drawdir) {
+ case DK3_IMAGE_ORIGIN_RIGHT_BOTTOM_FLIPPED: {
+ tx = x2; ty = y2; rotation = -90; doScaleY = 1;
+ } break;
+ case DK3_IMAGE_ORIGIN_RIGHT_TOP_FLIPPED: {
+ tx = x2; ty = y1; doScaleX = 1;
+ } break;
+ case DK3_IMAGE_ORIGIN_LEFT_BOTTOM_FLIPPED: {
+ tx = x1; ty = y2; doScaleY = 1;
+ } break;
+ case DK3_IMAGE_ORIGIN_LEFT_TOP_FLIPPED: {
+ tx = x1; ty = y1; rotation = -90; doScaleX = 1;
+ } break;
+ case DK3_IMAGE_ORIGIN_RIGHT_BOTTOM: {
+ tx = x2; ty = y2; rotation = 180;
+ } break;
+ case DK3_IMAGE_ORIGIN_RIGHT_TOP: {
+ tx = x2; ty = y1; rotation = 90;
+ } break;
+ case DK3_IMAGE_ORIGIN_LEFT_BOTTOM: {
+ tx = x1; ty = y2; rotation = -90;
+ } break;
+ default: {
+ tx = x1; ty = y1;
+ } break;
+ }
+ /* Write output.
+ */
+ /* <g transform="..."> */
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 35);
+ fprintf(job->of1, f2lsvg_c8_kw[60], tx, ty);
+ if(0 != rotation) {
+ fprintf(job->of1, f2lsvg_c8_kw[61], rotation);
+ }
+ if((doScaleX) || (doScaleY)) {
+ fputs(f2lsvg_c8_kw[62], job->of1);
+ fputs(f2lsvg_c8_kw[(doScaleX) ? 64 : 63], job->of1);
+ fputs(f2lsvg_c8_kw[1], job->of1);
+ fputs(f2lsvg_c8_kw[(doScaleY) ? 64 : 63], job->of1);
+ fputs(f2lsvg_c8_kw[65], job->of1);
+ }
+ fputs(f2lsvg_c8_kw[42], job->of1);
+ fputs(f2lsvg_c8_kw[5], job->of1);
+ /* <image ... /> */
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 66);
+ fprintf(job->of1, f2lsvg_c8_kw[67], ow, oh);
+ fputs((obj->dt).pol.fn, job->of1);
+ fputs(f2lsvg_c8_kw[42], job->of1);
+ fputs(f2lsvg_c8_kw[36], job->of1);
+ /* </g> */
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ fputs(f2lsvg_c8_kw[8], job->of1);
+ f2lsvg_tag_name(job, 35);
+ fputs(f2lsvg_c8_kw[5], job->of1);
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1722 "f2lsvg.ctr"
+ }
+ }
+}
+
+
+
+/** Process polyline object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param primary Flag: Primary object.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_polyline(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+ switch(obj->st) {
+ case 5: { /* imported image */
+ f2lsvg_process_image(job, drw, psvg, obj, ec);
+ } break;
+ case 4: { /* arc box */
+ f2lsvg_process_box(job, drw, psvg, obj, 1, ec);
+ } break;
+ case 3: { /* polygon */
+ f2lsvg_process_pl_polygon(job, drw, psvg, obj, primary, ec);
+ } break;
+ case 2: { /* box */
+ f2lsvg_process_box(job, drw, psvg, obj, 0, ec);
+ } break;
+ default: { /* polyline */
+ f2lsvg_process_pl_polyline(job, drw, psvg, obj, ec);
+ } break;
+ }
+}
+
+
+
+/** Process open spline object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param sp Spline points.
+ @param np Total number of points
+ @param cp Current point/segment.
+ @param isfirst Flag: Moveto needed.
+ @param iscl Flag: Closed (1) or open (0) spline.
+ @param primary Flag: Primary object (1=object, 0=arrowhead).
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_full_spline_segment(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_spline_point_t *sp,
+ size_t np,
+ size_t cp,
+ int isfirst,
+ int iscl,
+ int primary,
+ int *ec
+)
+{
+ dk3_xspline_segment_t seg;
+ dk3_fig_spline_point_t *pa = NULL;
+ dk3_fig_spline_point_t *pb = NULL;
+ dk3_fig_spline_point_t *pc = NULL;
+ dk3_fig_spline_point_t *pd = NULL;
+ double factor;
+ double t;
+ double x;
+ double y;
+ double dxdt;
+ double dydt;
+ double lastx = 0.0;
+ double lasty = 0.0;
+ double lastdxdt = 0.0;
+ double lastdydt = 0.0;
+ size_t xsss;
+ size_t iseg;
+ size_t ic;
+ size_t id;
+ int res;
+ int mec = 0;
+
+
+#line 1817 "f2lsvg.ctr"
+ if(cp < ((iscl) ? (np) : (np - 1))) {
+ pb = &(sp[cp]);
+
+#line 1819 "f2lsvg.ctr"
+ ic = cp + 1;
+ while(ic >= np) { ic = ic - np; }
+
+#line 1821 "f2lsvg.ctr"
+ pc = &(sp[ic]);
+ if(cp > 0) {
+
+#line 1823 "f2lsvg.ctr"
+ pa = &(sp[cp - 1]);
+ } else {
+ if(iscl) {
+
+#line 1826 "f2lsvg.ctr"
+ pa = &(sp[np - 1]);
+ }
+ }
+ if(cp < (np - 2)) {
+
+#line 1830 "f2lsvg.ctr"
+ pd = &(sp[cp + 2]);
+ } else {
+ if(iscl) {
+ id = cp + 2;
+ while(id >= np) { id = id - np; }
+
+#line 1835 "f2lsvg.ctr"
+ pd = &(sp[id]);
+ }
+ }
+ xsss = dk3fig_tool_xssbs(drw, primary);
+
+#line 1839 "f2lsvg.ctr"
+ factor = 1.0 / (double)xsss;
+ dk3xsp_reset(&seg);
+ if(job->cosp) { dk3xsp_set_cb(&seg, 1); }
+ dk3xsp_set(&seg, pa, pb, pc, pd);
+
+#line 1843 "f2lsvg.ctr"
+ if(dk3xsp_calculate(&seg, 0.0, 1)) {
+
+#line 1844 "f2lsvg.ctr"
+ lastx = dk3xsp_get_x(&seg);
+ lasty = dk3xsp_get_y(&seg);
+ lastdxdt = dk3xsp_get_dxdt(&seg);
+ lastdydt = dk3xsp_get_dydt(&seg);
+ lastdxdt = (factor * lastdxdt) / 3.0;
+ lastdydt = (factor * lastdydt) / 3.0;
+ if(isfirst) {
+
+#line 1851 "f2lsvg.ctr"
+ /* MOVETO lastx lasty */
+ fprintf(
+ job->of1, f2lsvg_c8_kw[56],
+ dk3ct_2d_x(&(job->ct2d), lastx, &mec),
+ dk3ct_2d_y(&(job->ct2d), lasty, &mec)
+ );
+ }
+ for(iseg = 0; iseg < xsss; iseg++) {
+
+#line 1859 "f2lsvg.ctr"
+ if(iseg < (xsss - 1)) {
+ t = (double)(iseg + 1) / (double)xsss;
+ } else {
+ t = 1.0;
+ }
+
+#line 1864 "f2lsvg.ctr"
+ res = dk3xsp_calculate(&seg, t, 1);
+
+#line 1865 "f2lsvg.ctr"
+ if(!(res)) { mec = DK3_ERROR_MATH_OVERFLOW; }
+ x = dk3xsp_get_x(&seg);
+ y = dk3xsp_get_y(&seg);
+ dxdt = dk3xsp_get_dxdt(&seg);
+ dydt = dk3xsp_get_dydt(&seg);
+ dxdt = (factor * dxdt) / 3.0;
+ dydt = (factor * dydt) / 3.0;
+
+#line 1872 "f2lsvg.ctr"
+ fprintf(
+ job->of1, f2lsvg_c8_kw[57],
+ dk3ct_2d_x(&(job->ct2d), dk3ma_d_add_ok(lastx, lastdxdt, &mec), &mec),
+ dk3ct_2d_y(&(job->ct2d), dk3ma_d_add_ok(lasty, lastdydt, &mec), &mec),
+ dk3ct_2d_x(&(job->ct2d), dk3ma_d_sub_ok(x, dxdt, &mec), &mec),
+ dk3ct_2d_y(&(job->ct2d), dk3ma_d_sub_ok(y, dydt, &mec), &mec),
+ dk3ct_2d_x(&(job->ct2d), x, &mec),
+ dk3ct_2d_y(&(job->ct2d), y, &mec)
+ );
+ lastx = x; lasty = y; lastdxdt = dxdt; lastdydt = dydt;
+ if(iseg < (xsss - 1)) {
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ } else {
+ if(cp < (np - 1)) {
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ } else {
+ if(iscl) {
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ }
+ }
+ }
+
+#line 1893 "f2lsvg.ctr"
+ }
+ } else {
+ mec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ if(mec) { *ec = mec; }
+
+
+#line 1900 "f2lsvg.ctr"
+}
+
+
+
+/** Create path for the first partial X-spline segment from closed X-spline.
+ @param job Job structure.
+ @param drw Fig drawing.
+ @param obj Fig object.
+ @param sp Spline points array.
+ @param np Number of spline points.
+ @param i Current segment index.
+ @param ts Parameter t for start point.
+ @param isfirst Flag: First segment.
+ @param iscl Flag: Closed spline.
+ @param primary Flag: Primary (1=primary object, 0=arrowhead).
+ @param ec Pointer to error code variable, may be NULL.
+*/
+static
+void
+f2lsvg_first_spline_segment(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_spline_point_t *sp,
+ size_t np,
+ size_t i,
+ double ts,
+ int isfirst,
+ int iscl,
+ int primary,
+ int *ec
+)
+{
+ dk3_xspline_segment_t seg; /* Segment for caluclation. */
+ dk3_fig_spline_point_t *pa = NULL; /* Left neighbour. */
+ dk3_fig_spline_point_t *pb = NULL; /* Start. */
+ dk3_fig_spline_point_t *pc = NULL; /* End. */
+ dk3_fig_spline_point_t *pd = NULL; /* Right neighbour. */
+ double myts; /* t for start. */
+ double dnumsegs; /* Number of segments. */
+ double factor; /* Scale factor for deriv. */
+ double t; /* Current t. */
+ double x; /* Bezier end x. */
+ double y; /* Bezier end y. */
+ double dxdt; /* Bezier dx/dt at end. */
+ double dydt; /* Bezier dy/dt at end. */
+ double lastx = 0.0; /* Bezier start x. */
+ double lasty = 0.0; /* Bezier start y. */
+ double lastdxdt = 0.0; /* dx/dt at start. */
+ double lastdydt = 0.0; /* dy/dt at end. */
+ size_t nsegs; /* Number of segments. */
+ size_t iseg; /* Current segment. */
+ int res; /* Calculation result. */
+
+
+#line 1954 "f2lsvg.ctr"
+ myts = dk3ma_d_sub_ok(ts, floor(ts), ec);
+
+#line 1955 "f2lsvg.ctr"
+ dnumsegs = (1.0 - myts) * dk3fig_tool_xssbs(drw, primary);
+ dnumsegs = ceil(dnumsegs);
+
+#line 1957 "f2lsvg.ctr"
+ nsegs = dk3ma_d_to_sz_ok(dnumsegs, ec);
+
+#line 1958 "f2lsvg.ctr"
+ pb = &(sp[i]);
+ pc = &(sp[i + 1]);
+ if(0 < i) {
+ pa = &(sp[i - 1]);
+ }
+ if(i < (np - 2)) {
+ pd = &(sp[i + 2]);
+ }
+ factor = (1.0 - myts) / (double)nsegs;
+
+#line 1967 "f2lsvg.ctr"
+ dk3xsp_reset(&seg);
+ if(job->cosp) { dk3xsp_set_cb(&seg, 1); }
+ dk3xsp_set(&seg, pa, pb, pc, pd);
+ if(dk3xsp_calculate(&seg, myts, 1)) {
+ /* If necessary move to the start point.
+ */
+ lastx = dk3xsp_get_x(&seg);
+ lasty = dk3xsp_get_y(&seg);
+ lastdxdt = dk3xsp_get_dxdt(&seg);
+ lastdydt = dk3xsp_get_dydt(&seg);
+ lastdxdt = (factor * lastdxdt) / 3.0;
+ lastdydt = (factor * lastdydt) / 3.0;
+ if(isfirst) {
+ fprintf(
+ job->of1, f2lsvg_c8_kw[56],
+ dk3ct_2d_x(&(job->ct2d), lastx, ec),
+ dk3ct_2d_y(&(job->ct2d), lasty, ec)
+ );
+ }
+ if(1.0e-6 < (1.0 - myts)) {
+ for(iseg = 0; iseg < nsegs; iseg++) {
+ if(iseg < (nsegs - 1)) {
+ t = myts + (((1.0 - myts) * ((double)(iseg + 1))) / ((double)nsegs));
+ } else {
+ t = 1.0;
+ }
+ res = dk3xsp_calculate(&seg, t, 1);
+ if(!(res)) {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ x = dk3xsp_get_x(&seg);
+ y = dk3xsp_get_y(&seg);
+ dxdt = dk3xsp_get_dxdt(&seg);
+ dydt = dk3xsp_get_dydt(&seg);
+ dxdt = (factor * dxdt) / 3.0;
+ dydt = (factor * dydt) / 3.0;
+ fprintf(
+ job->of1, f2lsvg_c8_kw[57],
+ dk3ct_2d_x(&(job->ct2d), dk3ma_d_add_ok(lastx, lastdxdt, ec), ec),
+ dk3ct_2d_y(&(job->ct2d), dk3ma_d_add_ok(lasty, lastdydt, ec), ec),
+ dk3ct_2d_x(&(job->ct2d), dk3ma_d_sub_ok(x, dxdt, ec), ec),
+ dk3ct_2d_y(&(job->ct2d), dk3ma_d_sub_ok(y, dydt, ec), ec),
+ dk3ct_2d_x(&(job->ct2d), x, ec),
+ dk3ct_2d_y(&(job->ct2d), y, ec)
+ );
+ lastx = x; lasty = y; lastdxdt = dxdt; lastdydt = dydt;
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ }
+ } else {
+ res = dk3xsp_calculate(&seg, 1.0, 0);
+ if(!(res)) {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ /* ERROR: Math */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 36);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
+
+#line 2022 "f2lsvg.ctr"
+ }
+ x = dk3xsp_get_x(&seg);
+ y = dk3xsp_get_y(&seg);
+ fprintf(
+ job->of1, f2lsvg_c8_kw[58],
+ dk3ct_2d_x(&(job->ct2d), x, ec),
+ dk3ct_2d_y(&(job->ct2d), y, ec)
+ );
+ }
+ } else {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
+
+#line 2034 "f2lsvg.ctr"
+ }
+
+
+#line 2036 "f2lsvg.ctr"
+}
+
+
+
+/** Create path for the last partial X-spline segment from closed X-spline.
+ @param job Job structure.
+ @param drw Fig drawing.
+ @param obj Fig object.
+ @param sp Spline points array.
+ @param np Number of spline points.
+ @param i Current segment index.
+ @param te Parameter t for end point.
+ @param isfirst Flag: First segment.
+ @param iscl Flag: Closed spline.
+ @param primary Flag: Primary (1=primary object, 0=arrowhead).
+ @param ec Pointer to error code variable, may be NULL.
+*/
+static
+void
+f2lsvg_final_spline_segment(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_spline_point_t *sp,
+ size_t np,
+ size_t i,
+ double te,
+ int isfirst,
+ int iscl,
+ int primary,
+ int *ec
+)
+{
+ dk3_xspline_segment_t seg; /* Segment for caluclation. */
+ dk3_fig_spline_point_t *pa = NULL; /* Left neighbour. */
+ dk3_fig_spline_point_t *pb = NULL; /* Start. */
+ dk3_fig_spline_point_t *pc = NULL; /* End. */
+ dk3_fig_spline_point_t *pd = NULL; /* Right neighbour. */
+ double myte; /* t for end. */
+ double dnumsegs; /* Number of segments. */
+ double factor; /* Scale factor for deriv. */
+ double t; /* Current t. */
+ double x; /* Bezier end x. */
+ double y; /* Bezier end y. */
+ double dxdt; /* Bezier dx/dt at end. */
+ double dydt; /* Bezier dy/dt at end. */
+ double lastx = 0.0; /* Bezier start x. */
+ double lasty = 0.0; /* Bezier start y. */
+ double lastdxdt = 0.0; /* dx/dt at start. */
+ double lastdydt = 0.0; /* dy/dt at end. */
+ size_t nsegs; /* Number of segments. */
+ size_t iseg; /* Current segment. */
+ int res; /* Calculation result. */
+
+
+#line 2090 "f2lsvg.ctr"
+ myte = dk3ma_d_sub_ok(te, floor(te), ec);
+
+#line 2091 "f2lsvg.ctr"
+ dnumsegs = myte * dk3fig_tool_xssbs(drw, primary);
+ dnumsegs = ceil(dnumsegs);
+
+#line 2093 "f2lsvg.ctr"
+ nsegs = dk3ma_d_to_sz_ok(dnumsegs, ec);
+
+#line 2094 "f2lsvg.ctr"
+ pb = &(sp[i]);
+ pc = &(sp[i + 1]);
+ if(0 < i) {
+ pa = &(sp[i - 1]);
+ }
+ if(i < (np - 2)) {
+ pd = &(sp[i + 2]);
+ }
+ factor = myte / (double)nsegs;
+
+#line 2103 "f2lsvg.ctr"
+ dk3xsp_reset(&seg);
+ if(job->cosp) { dk3xsp_set_cb(&seg, 1); }
+ dk3xsp_set(&seg, pa, pb, pc, pd);
+ if(dk3xsp_calculate(&seg, 0.0, 1)) {
+ lastx = dk3xsp_get_x(&seg);
+ lasty = dk3xsp_get_y(&seg);
+ lastdxdt = dk3xsp_get_dxdt(&seg);
+ lastdydt = dk3xsp_get_dydt(&seg);
+ lastdxdt = (factor * lastdxdt) / 3.0;
+ lastdydt = (factor * lastdydt) / 3.0;
+ /* Move to start point.
+ */
+ if(isfirst) {
+ fprintf(
+ job->of1, f2lsvg_c8_kw[56],
+ dk3ct_2d_x(&(job->ct2d), lastx, ec),
+ dk3ct_2d_y(&(job->ct2d), lasty, ec)
+ );
+ }
+ /* Further curve only if te > 1.0e-6.
+ For smaller te draw straight line.
+ */
+ if(1.0e-6 < myte) {
+
+#line 2126 "f2lsvg.ctr"
+ for(iseg = 0; iseg < nsegs; iseg++) {
+ if(iseg < (nsegs - 1)) {
+
+#line 2128 "f2lsvg.ctr"
+ t = (double)(iseg + 1) / (double)nsegs;
+ t = t * myte;
+ } else {
+
+#line 2131 "f2lsvg.ctr"
+ t = myte;
+ }
+
+#line 2133 "f2lsvg.ctr"
+ res = dk3xsp_calculate(&seg, t, 1);
+ if(!(res)) {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ x = dk3xsp_get_x(&seg);
+ y = dk3xsp_get_y(&seg);
+ dxdt = dk3xsp_get_dxdt(&seg);
+ dydt = dk3xsp_get_dydt(&seg);
+ dxdt = (factor * dxdt) / 3.0;
+ dydt = (factor * dydt) / 3.0;
+ fprintf(
+ job->of1, f2lsvg_c8_kw[57],
+ dk3ct_2d_x(&(job->ct2d), dk3ma_d_add_ok(lastx, lastdxdt, ec), ec),
+ dk3ct_2d_y(&(job->ct2d), dk3ma_d_add_ok(lasty, lastdydt, ec), ec),
+ dk3ct_2d_x(&(job->ct2d), dk3ma_d_sub_ok(x, dxdt, ec), ec),
+ dk3ct_2d_y(&(job->ct2d), dk3ma_d_sub_ok(y, dydt, ec), ec),
+ dk3ct_2d_x(&(job->ct2d), x, ec),
+ dk3ct_2d_y(&(job->ct2d), y, ec)
+ );
+ lastx = x; lasty = y; lastdxdt = dxdt; lastdydt = dydt;
+ if(iseg < (nsegs - 1)) {
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ }
+ }
+ } else {
+
+#line 2158 "f2lsvg.ctr"
+ res = dk3xsp_calculate(&seg, myte, 0);
+ if(!(res)) {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ /* ERROR: Math */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 36);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
+
+#line 2164 "f2lsvg.ctr"
+ }
+ x = dk3xsp_get_x(&seg);
+ y = dk3xsp_get_y(&seg);
+ fprintf(
+ job->of1, f2lsvg_c8_kw[58],
+ dk3ct_2d_x(&(job->ct2d), x, ec),
+ dk3ct_2d_y(&(job->ct2d), y, ec)
+ );
+ }
+ } else {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
+
+#line 2176 "f2lsvg.ctr"
+ }
+
+
+#line 2178 "f2lsvg.ctr"
+}
+
+
+
+/** Create path for the single partial X-spline segment cutted on both ends
+ from closed X-spline.
+ @param job Job structure.
+ @param drw Fig drawing.
+ @param obj Fig object.
+ @param sp Spline points array.
+ @param np Number of spline points.
+ @param i Current segment index.
+ @param ts Parameter t for start point.
+ @param te Parameter t for end point.
+ @param isfirst Flag: First segment.
+ @param iscl Flag: Closed spline.
+ @param primary Flag: Primary (1=primary object, 0=arrowhead).
+ @param ec Pointer to error code variable, may be NULL.
+*/
+static
+void
+f2lsvg_single_spline_segment(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_spline_point_t *sp,
+ size_t np,
+ size_t i,
+ double ts,
+ double te,
+ int isfirst,
+ int iscl,
+ int primary,
+ int *ec
+)
+{
+ dk3_xspline_segment_t seg; /* Segment for caluclation. */
+ dk3_fig_spline_point_t *pa = NULL; /* Left neighbour. */
+ dk3_fig_spline_point_t *pb = NULL; /* Start. */
+ dk3_fig_spline_point_t *pc = NULL; /* End. */
+ dk3_fig_spline_point_t *pd = NULL; /* Right neighbour. */
+ double myte; /* t for end. */
+ double myts; /* t for start. */
+ double dnumsegs; /* Number of segments. */
+ double factor; /* Scale factor for deriv. */
+ double t; /* Current t. */
+ double x; /* Bezier end x. */
+ double y; /* Bezier end y. */
+ double dxdt; /* Bezier dx/dt at end. */
+ double dydt; /* Bezier dy/dt at end. */
+ double lastx = 0.0; /* Bezier start x. */
+ double lasty = 0.0; /* Bezier start y. */
+ double lastdxdt = 0.0; /* dx/dt at start. */
+ double lastdydt = 0.0; /* dy/dt at end. */
+ size_t nsegs; /* Number of segments. */
+ size_t iseg; /* Current segment. */
+ int res; /* Calculation result. */
+
+
+#line 2236 "f2lsvg.ctr"
+ myte = dk3ma_d_sub_ok(te, floor(te), ec);
+ myts = dk3ma_d_sub_ok(ts, floor(ts), ec);
+ dnumsegs = (myte - myts) * dk3fig_tool_xssbs(drw, primary);
+ dnumsegs = ceil(dnumsegs);
+ nsegs = dk3ma_d_to_sz_ok(dnumsegs, ec);
+ pb = &(sp[i]);
+ pc = &(sp[i + 1]);
+ if(0 < i) {
+ pa = &(sp[i - 1]);
+ }
+ if(i < (np - 2)) {
+ pd = &(sp[i + 2]);
+ }
+ factor = (myte - myts) / ((double)nsegs);
+ dk3xsp_reset(&seg);
+ if(job->cosp) { dk3xsp_set_cb(&seg, 1); }
+ dk3xsp_set(&seg, pa, pb, pc, pd);
+ if(dk3xsp_calculate(&seg, myts, 1)) {
+ lastx = dk3xsp_get_x(&seg);
+ lasty = dk3xsp_get_y(&seg);
+ lastdxdt = dk3xsp_get_dxdt(&seg);
+ lastdydt = dk3xsp_get_dydt(&seg);
+ lastdxdt = (factor * lastdxdt) / 3.0;
+ lastdydt = (factor * lastdydt) / 3.0;
+ if(isfirst) {
+ fprintf(
+ job->of1, f2lsvg_c8_kw[56],
+ dk3ct_2d_x(&(job->ct2d), lastx, ec),
+ dk3ct_2d_y(&(job->ct2d), lasty, ec)
+ );
+ }
+ if(1.0e-6 < (myte - myts)) {
+ for(iseg = 0; iseg < nsegs; iseg++) {
+ if(iseg < (nsegs - 1)) {
+ t = myts + (((myte - myts) * ((double)(iseg + 1))) / ((double)nsegs));
+ } else {
+ t = myte;
+ }
+ res = dk3xsp_calculate(&seg, t, 1);
+ if(!(res)) {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ x = dk3xsp_get_x(&seg);
+ y = dk3xsp_get_y(&seg);
+ dxdt = dk3xsp_get_dxdt(&seg);
+ dydt = dk3xsp_get_dydt(&seg);
+ dxdt = (factor * dxdt) / 3.0;
+ dydt = (factor * dydt) / 3.0;
+ fprintf(
+ job->of1, f2lsvg_c8_kw[57],
+ dk3ct_2d_x(&(job->ct2d), dk3ma_d_add_ok(lastx, lastdxdt, ec), ec),
+ dk3ct_2d_y(&(job->ct2d), dk3ma_d_add_ok(lasty, lastdydt, ec), ec),
+ dk3ct_2d_x(&(job->ct2d), dk3ma_d_sub_ok(x, dxdt, ec), ec),
+ dk3ct_2d_y(&(job->ct2d), dk3ma_d_sub_ok(y, dydt, ec), ec),
+ dk3ct_2d_x(&(job->ct2d), x, ec),
+ dk3ct_2d_y(&(job->ct2d), y, ec)
+ );
+ lastx = x; lasty = y; lastdxdt = dxdt; lastdydt = dydt;
+ if(iseg < (nsegs - 1)) {
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ }
+ }
+ } else {
+ res = dk3xsp_calculate(&seg, myte, 0);
+ if(!(res)) {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ /* ERROR: Calculation failed! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 36);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
+
+#line 2305 "f2lsvg.ctr"
+ }
+ x = dk3xsp_get_x(&seg);
+ y = dk3xsp_get_y(&seg);
+ fprintf(
+ job->of1, f2lsvg_c8_kw[58],
+ dk3ct_2d_x(&(job->ct2d), x, ec),
+ dk3ct_2d_y(&(job->ct2d), y, ec)
+ );
+ }
+ } else {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ /* ERROR: Calculation failed! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 36);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
+
+#line 2319 "f2lsvg.ctr"
+ }
+
+
+#line 2321 "f2lsvg.ctr"
+}
+
+
+
+/** Process open spline object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param primary Flag: Primary object (1=object, 0=arrowhead).
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_open_spline(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+ dk3_fig_spline_point_t *sp;
+ size_t np;
+ size_t i;
+ size_t min;
+ size_t max;
+
+ sp = (obj->dt).spl.po;
+ np = (obj->dt).spl.np;
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 54);
+ fputs(f2lsvg_c8_kw[55], job->of1);
+ if(job->coah) {
+ for(i = 0; i < (np - 1); i++) {
+ f2lsvg_process_full_spline_segment(
+ job, drw, obj, sp, np, i, ((0 == i) ? 1 : 0), 0, primary, ec
+ );
+ }
+ } else {
+ if(obj->ab) {
+
+#line 2363 "f2lsvg.ctr"
+ /* 2013-11-23
+ ROUNDING DOWNWARDS INTENDED.
+ We want to find the start segment.
+ */
+ min = dk3ma_d_to_sz_ok(floor((obj->dt).spl.ts), ec);
+ if(obj->af) {
+
+#line 2369 "f2lsvg.ctr"
+ if((obj->dt).spl.te >= (obj->dt).spl.ts) {
+ /* 2013-11-23
+ ROUNDING DOWNWARDS INTENDED.
+ We want to find the last full segment to draw.
+ */
+ max = dk3ma_d_to_sz_ok(floor((obj->dt).spl.te), ec);
+ if(max > min) {
+ f2lsvg_first_spline_segment(
+ job, drw, obj, sp, np, min, (obj->dt).spl.ts, 1, 0, primary, ec
+ );
+ for(i = (min + 1); i < max; i++) {
+ f2lsvg_process_full_spline_segment(
+ job, drw, obj, sp, np, i, 0, 0, primary, ec
+ );
+ }
+ f2lsvg_final_spline_segment(
+ job, drw, obj, sp, np, max, (obj->dt).spl.te, 0, 0, primary, ec
+ );
+ } else {
+ f2lsvg_single_spline_segment(
+ job, drw, obj, sp, np, min, (obj->dt).spl.ts, (obj->dt).spl.te,
+ 1, 0, primary, ec
+ );
+ }
+ } else {
+ /* ERROR: Arrowheads in summary too long for spline */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 37);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYNTAX);
+
+#line 2397 "f2lsvg.ctr"
+ }
+ } else {
+
+#line 2399 "f2lsvg.ctr"
+ f2lsvg_first_spline_segment(
+ job, drw, obj, sp, np, min, (obj->dt).spl.ts, 1, 0, primary, ec
+ );
+ for(i = (min + 1); i < (np - 1); i++) {
+ f2lsvg_process_full_spline_segment(
+ job, drw, obj, sp, np, i, 0, 0, primary, ec
+ );
+ }
+ }
+ } else {
+
+#line 2409 "f2lsvg.ctr"
+ if(obj->af) {
+
+#line 2410 "f2lsvg.ctr"
+ /* 2013-11-23
+ ROUNDING DOWNWARDS INTENDED.
+ We want to find the last full segment to draw.
+ */
+ max = dk3ma_d_to_sz_ok(floor((obj->dt).spl.te), ec);
+ if(max < (np - 1)) {
+ if(max > 0) {
+ for(i = 0; i < max; i++) {
+ f2lsvg_process_full_spline_segment(
+ job, drw, obj, sp, np, i, ((0 == i) ? 1 : 0), 0, primary, ec
+ );
+ }
+ f2lsvg_final_spline_segment(
+ job, drw, obj, sp, np, max, (obj->dt).spl.te, 0, 0, primary, ec
+ );
+ } else {
+ f2lsvg_final_spline_segment(
+ job, drw, obj, sp, np, max, (obj->dt).spl.te, 1, 0, primary, ec
+ );
+ }
+ } else {
+ /* ERROR: Illegal max value! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 39);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN);
+
+#line 2434 "f2lsvg.ctr"
+ }
+ } else {
+
+#line 2436 "f2lsvg.ctr"
+ for(i = 0; i < (np - 1); i++) {
+ f2lsvg_process_full_spline_segment(
+ job, drw, obj, sp, np, i, ((0 == i) ? 1 : 0), 0, primary, ec
+ );
+ }
+ }
+ }
+ }
+ fputs(f2lsvg_c8_kw[42], job->of1);
+ f2lsvgst_write_style_for_object(job, drw, psvg, obj);
+ fputs(f2lsvg_c8_kw[36], job->of1);
+}
+
+
+
+/** Process fast open spline object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_fast_open_spline(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ dk3_fig_spline_point_t *po;
+ double dxdtb;
+ double dydtb;
+ double dxdtc;
+ double dydtc;
+ size_t np;
+ size_t ib;
+ size_t ic;
+
+
+#line 2477 "f2lsvg.ctr"
+ po = (obj->dt).spl.po;
+ np = (obj->dt).spl.np;
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 54);
+ fputs(f2lsvg_c8_kw[55], job->of1);
+ if (1 < np) {
+ for (ib = 0; ib < (np - 1); ib++) {
+ ic = ib + 1;
+ if (0 == ib) {
+ /* MOVETO */
+ fprintf(
+ job->of1, f2lsvg_c8_kw[56],
+ dk3ct_2d_x(&(job->ct2d), po[ib].x, ec),
+ dk3ct_2d_y(&(job->ct2d), po[ib].y, ec)
+ );
+ }
+ if ((fabs(po[ib].s) < 1.0e-6) && (fabs(po[ic].s) < 1.0e-6)) {
+ /* LINETO */
+ fprintf(
+ job->of1, f2lsvg_c8_kw[58],
+ dk3ct_2d_x(&(job->ct2d), po[ib].x, ec),
+ dk3ct_2d_y(&(job->ct2d), po[ib].y, ec)
+ );
+ } else {
+ dxdtb = dxdtc = dk3ma_d_sub_ok(po[ic].x, po[ib].x, ec);
+ dydtb = dydtc = dk3ma_d_sub_ok(po[ic].y, po[ib].y, ec);
+ if ((0 < ib) && (fabs(1.0 + po[ib].s) < 1.0e-6)) {
+ dxdtb = f2lpara_derived_center(po[ib-1].x, po[ib].x, po[ic].x, ec);
+ dydtb = f2lpara_derived_center(po[ib-1].y, po[ib].y, po[ic].y, ec);
+ } else {
+ if ((ic < (np - 1)) && (fabs(1.0 + po[ic].s) < 1.0e-6)) {
+ dxdtb = f2lpara_derived_left(po[ib].x, po[ic].x, po[ic+1].x, ec);
+ dydtb = f2lpara_derived_left(po[ib].y, po[ic].y, po[ic+1].y, ec);
+ }
+ }
+ if ((ic < (np - 1)) && (fabs(1.0 + po[ic].s) < 1.0e-6)) {
+ dxdtc = f2lpara_derived_center(po[ib].x, po[ic].x, po[ic+1].x, ec);
+ dydtc = f2lpara_derived_center(po[ib].y, po[ic].y, po[ic+1].y, ec);
+ } else {
+ if ((0 < ib) && (fabs(1.0 + po[ib].s) < 1.0e-6)) {
+ dxdtc = f2lpara_derived_right(po[ib-1].x, po[ib].x, po[ic].x, ec);
+ dydtc = f2lpara_derived_right(po[ib-1].y, po[ib].y, po[ic].y, ec);
+ }
+ }
+ /* CURVETO */
+ fprintf(
+ job->of1, f2lsvg_c8_kw[57],
+ dk3ct_2d_x(
+ &(job->ct2d),
+ dk3ma_d_add_ok(po[ib].x, (dxdtb / 3.0), ec),
+ ec
+ ),
+ dk3ct_2d_y(
+ &(job->ct2d),
+ dk3ma_d_add_ok(po[ib].y, (dydtb / 3.0), ec),
+ ec
+ ),
+ dk3ct_2d_x(
+ &(job->ct2d),
+ dk3ma_d_sub_ok(po[ic].x, (dxdtc / 3.0), ec),
+ ec
+ ),
+ dk3ct_2d_y(
+ &(job->ct2d),
+ dk3ma_d_sub_ok(po[ic].y, (dydtc / 3.0), ec),
+ ec
+ ),
+ dk3ct_2d_x( &(job->ct2d), po[ic].x, ec),
+ dk3ct_2d_y( &(job->ct2d), po[ic].y, ec)
+ );
+ }
+ }
+ } else {
+ /* Too few points in X-spline */
+ }
+ fputs(f2lsvg_c8_kw[42], job->of1);
+ f2lsvgst_write_style_for_object(job, drw, psvg, obj);
+ fputs(f2lsvg_c8_kw[36], job->of1);
+
+
+#line 2556 "f2lsvg.ctr"
+}
+
+
+
+/** Process closed spline object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param primary Flag: Primary object (1=object, 0=arrowhead).
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_closed_spline(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+ dk3_fig_spline_point_t *sp;
+ size_t np;
+ size_t i;
+
+ sp = (obj->dt).spl.po;
+ np = (obj->dt).spl.np;
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 54);
+ fputs(f2lsvg_c8_kw[55], job->of1);
+ for(i = 0; i < np; i++) {
+ f2lsvg_process_full_spline_segment(
+ job, drw, obj, sp, np, i, ((0 == i) ? 1 : 0), 1, primary, ec
+ );
+ }
+ fputs(f2lsvg_c8_kw[59], job->of1);
+ fputs(f2lsvg_c8_kw[42], job->of1);
+ f2lsvgst_write_style_for_object(job, drw, psvg, obj);
+ fputs(f2lsvg_c8_kw[36], job->of1);
+}
+
+
+
+/** Process fast closed spline object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_fast_closed_spline(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ dk3_fig_spline_point_t *po;
+ double dxdtb;
+ double dydtb;
+ double dxdtc;
+ double dydtc;
+ size_t np;
+ size_t ia;
+ size_t ib;
+ size_t ic;
+ size_t id;
+
+
+
+#line 2630 "f2lsvg.ctr"
+ po = (obj->dt).spl.po;
+ np = (obj->dt).spl.np;
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 54);
+ fputs(f2lsvg_c8_kw[55], job->of1);
+ if (2 < np) {
+ for (ib = 0; ib < np; ib++) {
+ ic = ib + 1;
+ id = ib + 2;
+ if (ic >= np) { ic = ic - np; }
+ if (id >= np) { id = id - np; }
+ if (0 < ib) {
+ ia = ib - 1;
+ } else {
+ ia = np - 1;
+ }
+ if (0 == ib) {
+ /* MOVETO */
+ fprintf(
+ job->of1, f2lsvg_c8_kw[56],
+ dk3ct_2d_x(&(job->ct2d), po[ib].x, ec),
+ dk3ct_2d_y(&(job->ct2d), po[ib].y, ec)
+ );
+ }
+ if ((fabs(po[ib].s) < 1.0e-6) && (fabs(po[ic].s) < 1.0e-6)) {
+ /* LINETO */
+ fprintf(
+ job->of1, f2lsvg_c8_kw[58],
+ dk3ct_2d_x(&(job->ct2d), po[ib].x, ec),
+ dk3ct_2d_y(&(job->ct2d), po[ib].y, ec)
+ );
+ } else {
+ dxdtb = dxdtc = dk3ma_d_sub_ok(po[ic].x, po[ib].x, ec);
+ dydtb = dydtc = dk3ma_d_sub_ok(po[ic].y, po[ib].y, ec);
+ if (fabs(1.0 + po[ib].s) < 1.0e-6) {
+ dxdtb = f2lpara_derived_center(po[ia].x, po[ib].x, po[ic].x, ec);
+ dydtb = f2lpara_derived_center(po[ia].y, po[ib].y, po[ic].y, ec);
+ } else {
+ if (fabs(1.0 + po[ic].s) < 1.0e-6) {
+ dxdtb = f2lpara_derived_left(po[ib].x, po[ic].x, po[id].x, ec);
+ dydtb = f2lpara_derived_left(po[ib].y, po[ic].y, po[id].y, ec);
+ }
+ }
+ if (fabs(1.0 + po[ic].s) < 1.0e-6) {
+ dxdtc = f2lpara_derived_center(po[ib].x, po[ic].x, po[id].x, ec);
+ dydtc = f2lpara_derived_center(po[ib].y, po[ic].y, po[id].y, ec);
+ } else {
+ if (fabs(1.0 + po[ib].s) < 1.0e-6) {
+ dxdtc = f2lpara_derived_right(po[ia].x, po[ib].x, po[ic].x, ec);
+ dydtc = f2lpara_derived_right(po[ia].y, po[ib].y, po[ic].y, ec);
+ }
+ }
+ /* CURVETO */
+ fprintf(
+ job->of1, f2lsvg_c8_kw[57],
+ dk3ct_2d_x(
+ &(job->ct2d),
+ dk3ma_d_add_ok(po[ib].x, (dxdtb / 3.0), ec),
+ ec
+ ),
+ dk3ct_2d_y(
+ &(job->ct2d),
+ dk3ma_d_add_ok(po[ib].y, (dydtb / 3.0), ec),
+ ec
+ ),
+ dk3ct_2d_x(
+ &(job->ct2d),
+ dk3ma_d_sub_ok(po[ic].x, (dxdtc / 3.0), ec),
+ ec
+ ),
+ dk3ct_2d_y(
+ &(job->ct2d),
+ dk3ma_d_sub_ok(po[ic].y, (dydtc / 3.0), ec),
+ ec
+ ),
+ dk3ct_2d_x( &(job->ct2d), po[ic].x, ec),
+ dk3ct_2d_y( &(job->ct2d), po[ic].y, ec)
+ );
+ }
+ }
+ } else {
+ /* ERROR: Too few points */
+ }
+ fputs(f2lsvg_c8_kw[59], job->of1);
+ fputs(f2lsvg_c8_kw[42], job->of1);
+ f2lsvgst_write_style_for_object(job, drw, psvg, obj);
+ fputs(f2lsvg_c8_kw[36], job->of1);
+
+
+#line 2718 "f2lsvg.ctr"
+}
+
+
+
+/** Process spline object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param primary Flag: Primary object (1=object, 0=arrowhead).
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_spline(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+ switch(obj->st) {
+ case 1: case 3: case 5: { /* closed spline */
+ f2lsvg_process_closed_spline(job, drw, psvg, obj, primary, ec);
+ } break;
+ default: { /* open spline */
+ f2lsvg_process_open_spline(job, drw, psvg, obj, primary, ec);
+ } break;
+ }
+}
+
+
+
+/** Process text object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_text(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ double rotation = 0.0; /* Rotation in degree. */
+ double irot = 0.0; /* Rotation as integer. */
+ double x; /* Text x position. */
+ double y; /* Text y position. */
+ int isRotated = 0; /* Flag: Text is rotated. */
+ int mec = 0; /* Mathematical error code. */
+
+ if(!(DK3_FIG_FONT_FLAG_HIDDEN & ((obj->dt).txt.ff))) {
+ rotation = (obj->dt).txt.an;
+ if(1.0e-6 < fabs(rotation)) {
+ isRotated = 1;
+ rotation = dk3ma_d_mul_ok(180.0, (rotation / M_PI), &mec);
+ irot = dk3ma_d_rint(rotation);
+ if(fabs(dk3ma_d_sub_ok(rotation, irot, &mec)) < 1.0e-3) {
+ rotation = irot;
+ }
+ rotation = -1.0 * rotation;
+ }
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 50);
+ x = dk3ct_2d_x(&(job->ct2d), (obj->dt).txt.x, &mec);
+ y = dk3ct_2d_y(&(job->ct2d), (obj->dt).txt.y, &mec);
+ if(isRotated) {
+ fprintf(job->of1, f2lsvg_c8_kw[53], x, y, rotation);
+ } else {
+ fprintf(job->of1, f2lsvg_c8_kw[52], x, y);
+ }
+ f2lsvgst_write_style_for_object(job, drw, psvg, obj);
+ fputs(f2lsvg_c8_kw[51], job->of1);
+ if((obj->dt).txt.st) {
+#if VERSION_BEFORE_2013_11_10
+ fputs((obj->dt).txt.st, job->of1);
+#else
+ f2lsvg_fputs_translate((obj->dt).txt.st, job->of1);
+#endif
+ }
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ fputs(f2lsvg_c8_kw[8], job->of1);
+ f2lsvg_tag_name(job, 50);
+ fputs(f2lsvg_c8_kw[5], job->of1);
+ if(mec) { *ec = mec; }
+ if(DK3_FIG_FONT_FLAG_SPECIAL & ((obj->dt).txt.ff)) {
+ /* WARNING: Special text was found! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 44);
+ }
+ }
+}
+
+
+
+/** Process arc object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_arc(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ double sx; /* Start x. */
+ double sy; /* Start y. */
+ double cx; /* Center x. */
+ double cy; /* Center y. */
+ double r; /* Radius. */
+ double as; /* Arc start angle in radians. */
+ double ae; /* Arc end angle in radians. */
+ double lastx; /* Segment start x. */
+ double lasty; /* Segment start y. */
+ double lastkdxdt; /* X difference to first control. */
+ double lastkdydt; /* Y difference to first control. */
+ double x; /* Segment end x. */
+ double y; /* Segment end y. */
+ double kdxdt; /* X difference to last control. */
+ double kdydt; /* Y difference to last control. */
+ double dnumsegs; /* Number of segments. */
+ double alpha; /* Arc angle in radians. */
+ double alphaseg; /* Segment angle in radians. */
+ double kappa; /* Factor for derivative. */
+ double alphaend; /* Segment end angle in radians. */
+ size_t nsegs; /* Number of segments. */
+ size_t i; /* Index of current segment. */
+
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 54);
+ fputs(f2lsvg_c8_kw[55], job->of1);
+
+ cx = (obj->dt).arc.xc;
+ cy = (obj->dt).arc.yc;
+ r = (obj->dt).arc.ra;
+ if((obj->dt).arc.as < (obj->dt).arc.ae) {
+ as = (obj->dt).arc.as;
+ ae = (obj->dt).arc.ae;
+ } else {
+ as = (obj->dt).arc.ae;
+ ae = (obj->dt).arc.as;
+ }
+ alpha = dk3ma_d_sub_ok(ae, as, ec);
+ dnumsegs = ceil(dk3ma_d_mul_ok(4.0, (alpha / M_PI), ec));
+ nsegs = dk3ma_d_to_sz_ok(dnumsegs, ec);
+ alphaseg = alpha / ((double)nsegs);
+ kappa = dk3fig_tool_arc_kappa(alphaseg, ec);
+ sx = lastx = dk3ma_d_add_ok(cx, (r * cos(as)), ec);
+ sy = lasty = dk3ma_d_add_ok(cy, (r * sin(as)), ec);
+ fprintf(
+ job->of1, f2lsvg_c8_kw[56],
+ dk3ct_2d_x(&(job->ct2d), lastx, ec),
+ dk3ct_2d_y(&(job->ct2d), lasty, ec)
+ );
+ lastkdxdt = dk3ma_d_mul_ok(
+ kappa,
+ (-1.0 * dk3ma_d_mul_ok(r, alphaseg, ec) * sin(as)),
+ ec
+ );
+ lastkdydt = dk3ma_d_mul_ok(
+ kappa,
+ (dk3ma_d_mul_ok(r, alphaseg, ec) * cos(as)),
+ ec
+ );
+ for(i = 0; i < nsegs; i++) {
+ if(i < (nsegs - 1)) {
+ alphaend = dk3ma_d_add_ok(
+ as,
+ dk3ma_d_mul_ok(dk3ma_d_add_ok(1.0, (double)i, ec), alphaseg, ec),
+ ec
+ );
+ } else {
+ alphaend = ae;
+ }
+ x = dk3ma_d_add_ok(cx, (r * cos(alphaend)), ec);
+ y = dk3ma_d_add_ok(cy, (r * sin(alphaend)), ec);
+ kdxdt = dk3ma_d_mul_ok(
+ kappa,
+ (-1.0 * dk3ma_d_mul_ok(r, alphaseg, ec) * sin(alphaend)),
+ ec
+ );
+ kdydt = dk3ma_d_mul_ok(
+ kappa,
+ (dk3ma_d_mul_ok(r, alphaseg, ec) * cos(alphaend)),
+ ec
+ );
+ fprintf(
+ job->of1, f2lsvg_c8_kw[57],
+ dk3ct_2d_x(&(job->ct2d), dk3ma_d_add_ok(lastx, lastkdxdt, ec), ec),
+ dk3ct_2d_y(&(job->ct2d), dk3ma_d_add_ok(lasty, lastkdydt, ec), ec),
+ dk3ct_2d_x(&(job->ct2d), dk3ma_d_sub_ok(x, kdxdt, ec), ec),
+ dk3ct_2d_y(&(job->ct2d), dk3ma_d_sub_ok(y, kdydt, ec), ec),
+ dk3ct_2d_x(&(job->ct2d), x, ec),
+ dk3ct_2d_y(&(job->ct2d), y, ec)
+ );
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ lastx = x; lasty = y; lastkdxdt = kdxdt; lastkdydt = kdydt;
+ }
+ /* For closed arc draw the lines.
+ */
+ if(1 != obj->st) {
+ fprintf(
+ job->of1, f2lsvg_c8_kw[58],
+ dk3ct_2d_x(&(job->ct2d), cx, ec),
+ dk3ct_2d_y(&(job->ct2d), cy, ec)
+ );
+ fprintf(
+ job->of1, f2lsvg_c8_kw[58],
+ dk3ct_2d_x(&(job->ct2d), sx, ec),
+ dk3ct_2d_y(&(job->ct2d), sy, ec)
+ );
+ fputs(f2lsvg_c8_kw[59], job->of1);
+ }
+ fputs(f2lsvg_c8_kw[42], job->of1);
+ f2lsvgst_write_style_for_object(job, drw, psvg, obj);
+ fputs(f2lsvg_c8_kw[36], job->of1);
+}
+
+
+
+/** Process half-circle object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_half_circle(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ dk3_fig_poly_point_t po[7];
+ size_t i; /* Traverse po. */
+ int mec = 0; /* Mathematical error code. */
+
+
+#line 2973 "f2lsvg.ctr"
+ po[0].x = 0.0;
+ po[0].y = (obj->dt).hci.ra;
+ po[1].x = -1.0 * FIG2LAT_CIRCLE_QUADRANT_BEZIER * (obj->dt).hci.ra;
+ po[1].y = (obj->dt).hci.ra;
+ po[2].x = -1.0 * (obj->dt).hci.ra;
+ po[2].y = FIG2LAT_CIRCLE_QUADRANT_BEZIER * (obj->dt).hci.ra;
+ po[3].x = -1.0 * (obj->dt).hci.ra;
+ po[3].y = 0.0;
+ po[4].x = -1.0 * (obj->dt).hci.ra;
+ po[4].y = -1.0 * FIG2LAT_CIRCLE_QUADRANT_BEZIER * (obj->dt).hci.ra;
+ po[5].x = -1.0 * FIG2LAT_CIRCLE_QUADRANT_BEZIER * (obj->dt).hci.ra;
+ po[5].y = -1.0 * (obj->dt).hci.ra;
+ po[6].x = 0.0;
+ po[6].y = -1.0 * (obj->dt).hci.ra;
+ if(1.0e-6 < fabs((obj->dt).hci.an)) {
+ for(i = 0; i < 7; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), (obj->dt).hci.an, &mec);
+ }
+ }
+ for(i = 0; i < 7; i++) {
+ dk3fig_tool_shift_point(&(po[i]), (obj->dt).hci.cx, (obj->dt).hci.cy, &mec);
+ }
+ for(i = 0; i < 7; i++) {
+ po[i].x = dk3ct_2d_x(&(job->ct2d), po[i].x, &mec);
+ po[i].y = dk3ct_2d_y(&(job->ct2d), po[i].y, &mec);
+ }
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 54);
+ fputs(f2lsvg_c8_kw[55], job->of1);
+ fprintf(job->of1, f2lsvg_c8_kw[56], po[0].x, po[0].y);
+ fprintf(
+ job->of1, f2lsvg_c8_kw[57],
+ po[1].x, po[1].y, po[2].x, po[2].y, po[3].x, po[3].y
+ );
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ fprintf(
+ job->of1, f2lsvg_c8_kw[57],
+ po[4].x, po[4].y, po[5].x, po[5].y, po[6].x, po[6].y
+ );
+ if(obj->st) {
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ fprintf(job->of1, f2lsvg_c8_kw[58], po[0].x, po[0].y);
+ fputs(f2lsvg_c8_kw[59], job->of1);
+ }
+ fputs(f2lsvg_c8_kw[42], job->of1);
+ f2lsvgst_write_style_for_object(job, drw, psvg, obj);
+ fputs(f2lsvg_c8_kw[36], job->of1);
+ if(mec) { *ec = mec; }
+
+
+#line 3022 "f2lsvg.ctr"
+}
+
+
+
+/** Process object and arrowheads.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param primary Flag: primary (1=primary object, 0=arrowhead).
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_one(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+ int op;
+
+
+#line 3047 "f2lsvg.ctr"
+ op = dk3fig_tool_get_operation(drw, obj);
+
+#line 3048 "f2lsvg.ctr"
+ switch(obj->ot) {
+ case DK3_FIG_OBJ_ELLIPSE: {
+ if(op) { f2lsvg_process_ellipse(job, drw, psvg, obj, ec); }
+ } break;
+ case DK3_FIG_OBJ_POLYLINE: {
+ if(op) {f2lsvg_process_polyline(job, drw, psvg, obj, primary, ec); }
+ } break;
+ case DK3_FIG_OBJ_SPLINE: {
+ if(op) {f2lsvg_process_spline(job, drw, psvg, obj, primary, ec); }
+ } break;
+ case DK3_FIG_OBJ_TEXT: {
+ f2lsvg_process_text(job, drw, psvg, obj, ec);
+ } break;
+ case DK3_FIG_OBJ_ARC: {
+ if(op) {f2lsvg_process_arc(job, drw, psvg, obj, ec); }
+ } break;
+ case DK3_FIG_OBJ_PSEUDO_HALF_CIRCLE: {
+
+#line 3065 "f2lsvg.ctr"
+ if(op) {f2lsvg_process_half_circle(job, drw, psvg, obj, ec); }
+ } break;
+ case DK3_FIG_OBJ_PSEUDO_FAST_SPLINE: {
+ if(op) {
+ /* f2lsvg_process_spline(job, drw, psvg, obj, primary, ec); */
+ switch(obj->st) {
+ case 1: case 3: case 5: {
+ f2lsvg_process_fast_closed_spline(job, drw, psvg, obj, ec);
+ } break;
+ default: {
+ f2lsvg_process_fast_open_spline(job, drw, psvg, obj, ec);
+ } break;
+ }
+ }
+ } break;
+ }
+
+
+#line 3082 "f2lsvg.ctr"
+}
+
+
+
+/** Check whether we must use a g instruction to group
+ the object with its arrowheads.
+ @param job Job structure.
+ @param obj Current object to process.
+ @return 1 to group, 0 for no group.
+*/
+static
+int
+f2lsvg_check_must_group(f2l_job_t *job, dk3_fig_obj_t *obj)
+{
+ int back = 0;
+
+
+#line 3098 "f2lsvg.ctr"
+ if(job->group) {
+
+#line 3099 "f2lsvg.ctr"
+ if(obj->af) {
+
+#line 3100 "f2lsvg.ctr"
+ if((obj->af)->o1) {
+
+#line 3101 "f2lsvg.ctr"
+ back = 1;
+ }
+ if((obj->af)->o2) {
+
+#line 3104 "f2lsvg.ctr"
+ back = 1;
+ }
+ }
+ if(obj->ab) {
+
+#line 3108 "f2lsvg.ctr"
+ if((obj->ab)->o1) {
+
+#line 3109 "f2lsvg.ctr"
+ back = 1;
+ }
+ if((obj->ab)->o2) {
+
+#line 3112 "f2lsvg.ctr"
+ back = 1;
+ }
+ }
+ }
+
+#line 3116 "f2lsvg.ctr"
+ return back;
+}
+
+
+
+/** Process arrowhead object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_ah_one(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ switch (obj->ot) {
+ case DK3_FIG_OBJ_SPLINE: {
+ if ((!(job->xsah)) && (f2lud_is_interpolated_spline(obj))) {
+ obj->ot = DK3_FIG_OBJ_PSEUDO_FAST_SPLINE;
+ f2lsvg_process_one(job, drw, psvg, obj, 0, ec);
+ obj->ot = DK3_FIG_OBJ_SPLINE;
+ } else {
+ f2lsvg_process_one(job, drw, psvg, obj, 0, ec);
+ }
+ } break;
+ default: {
+ f2lsvg_process_one(job, drw, psvg, obj, 0, ec);
+ } break;
+ }
+}
+
+
+
+/** Process object and arrowheads.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+static
+void
+f2lsvg_process_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2l_svg_t *psvg; /* SVG style collection. */
+ int mg; /* Flag: Must group */
+ int mec = 0; /* Mathematical error code. */
+
+
+
+#line 3174 "f2lsvg.ctr"
+ psvg = (f2l_svg_t *)(drw->dsd);
+ mg = f2lsvg_check_must_group(job, obj);
+ /*
+ Process object itself.
+ */
+ if(mg) {
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 35);
+ fputs(f2lsvg_c8_kw[5], job->of1);
+ }
+
+
+#line 3185 "f2lsvg.ctr"
+ f2lsvg_process_one(job, drw, psvg, obj, 1, &mec);
+ /*
+ Process arrowheads.
+ */
+ if(obj->af) {
+
+#line 3190 "f2lsvg.ctr"
+ if((obj->af)->o1) {
+
+#line 3191 "f2lsvg.ctr"
+#if VERSION_BEFORE_20140329
+ f2lsvg_process_one(job,drw,psvg,(dk3_fig_obj_t *)((obj->af)->o1),0,&mec);
+#else
+ f2lsvg_process_ah_one(job,drw,psvg,(dk3_fig_obj_t *)((obj->af)->o1),&mec);
+#endif
+ }
+ if((obj->af)->o2) {
+
+#line 3198 "f2lsvg.ctr"
+#if VERSION_BEFORE_20140329
+ f2lsvg_process_one(job,drw,psvg,(dk3_fig_obj_t *)((obj->af)->o2),0,&mec);
+#else
+ f2lsvg_process_ah_one(job,drw,psvg,(dk3_fig_obj_t *)((obj->af)->o2),&mec);
+#endif
+ }
+
+#line 3204 "f2lsvg.ctr"
+ }
+ if(obj->ab) {
+
+#line 3206 "f2lsvg.ctr"
+ if((obj->ab)->o1) {
+
+#line 3207 "f2lsvg.ctr"
+#if VERSION_BEFORE_20140329
+ f2lsvg_process_one(job,drw,psvg,(dk3_fig_obj_t *)((obj->ab)->o1),0,&mec);
+#else
+ f2lsvg_process_ah_one(job,drw,psvg,(dk3_fig_obj_t *)((obj->ab)->o1),&mec);
+#endif
+ }
+ if((obj->ab)->o2) {
+
+#line 3214 "f2lsvg.ctr"
+#if VERSION_BEFORE_20140329
+ f2lsvg_process_one(job,drw,psvg,(dk3_fig_obj_t *)((obj->ab)->o2),0,&mec);
+#else
+ f2lsvg_process_ah_one(job,drw,psvg,(dk3_fig_obj_t *)((obj->ab)->o2),&mec);
+#endif
+ }
+
+#line 3220 "f2lsvg.ctr"
+ }
+
+
+#line 3222 "f2lsvg.ctr"
+ if(mg) {
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ fputs(f2lsvg_c8_kw[8], job->of1);
+ f2lsvg_tag_name(job, 35);
+ fputs(f2lsvg_c8_kw[5], job->of1);
+ }
+ if(mec) {
+ /* ERROR: Mathematical error occured. */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 38);
+ job->exval = FIG2LAT_EXIT_ERROR_MATH;
+
+#line 3232 "f2lsvg.ctr"
+ }
+
+
+#line 3234 "f2lsvg.ctr"
+}
+
+
+
+void
+f2lsvg_output(f2l_job_t *job)
+{
+ dk3_fig_drawing_t *drw;
+ dk3_fig_obj_t *obj;
+ unsigned long objno = 0UL;
+ unsigned long oldsrcline = 0UL;
+
+
+#line 3246 "f2lsvg.ctr"
+ oldsrcline = dk3app_get_source_line(job->app);
+ dk3app_set_source_line(job->app, 0UL);
+ drw = job->drw; objno = 0UL;
+ if(f2lsvg_driver_initialize(job, drw)) {
+ if(f2lsvg_open_output_files(job)) {
+ if(f2lsvg_start_processing(job, drw)) {
+ dk3sto_it_reset(drw->iobj);
+ while(NULL != (obj = (dk3_fig_obj_t *)dk3sto_it_next(drw->iobj))) {
+ dk3app_set_source_line(job->app, obj->li);
+ if(!dk3fig_tool_is_bgrect(obj, objno)) {
+ f2lsvg_process_object(job, drw, obj);
+ }
+ objno++;
+ }
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN);
+
+#line 3262 "f2lsvg.ctr"
+ }
+ f2lsvg_end_processing(job, drw);
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN);
+
+#line 3266 "f2lsvg.ctr"
+ }
+ f2lsvg_close_output_files(job);
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN);
+
+#line 3270 "f2lsvg.ctr"
+ }
+ dk3app_set_source_line(job->app, oldsrcline);
+
+
+#line 3273 "f2lsvg.ctr"
+ f2lsvg_driver_end(job, drw);
+}
+
diff --git a/support/dktools/f2lsvg.ctr b/support/dktools/f2lsvg.ctr
new file mode 100644
index 0000000000..7c4a116c3c
--- /dev/null
+++ b/support/dktools/f2lsvg.ctr
@@ -0,0 +1,3275 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Produce output.
+ @param job Job structure.
+*/
+void
+f2lsvg_output(f2l_job_t *job);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk3all.h"
+#include "dk3bezcu.h"
+#include "dk3font.h"
+#include "fig2lat.h"
+#include "f2lud.h"
+#include "f2lsvg.h"
+#include "f2lsvgst.h"
+#include "f2lpara.h"
+#include "dk3figto.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4vers.h"
+#include "dk3xsp.h"
+#include "dk3font.h"
+#include "dk3bif.h"
+
+
+
+$!trace-include
+
+
+
+/** Keywords used by the module.
+*/
+static char const * const f2lsvg_c8_kw[] = {
+$!string-table
+#
+# 0: Newline
+#
+\n
+#
+# 1: Space
+#
+
+#
+# 2 3 4 5: XML header line.
+#
+<?xml version="1.0" encoding="iso-8859-1" standalone="no"?>\n
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"\n
+"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"\n
+>\n
+#
+# 6: Opening a tag.
+#
+<
+#
+# 7: Tag start for fragments
+#
+svg:
+#
+# 8: Closing a tag.
+#
+/
+#
+# 9: End of a tag.
+#
+>
+#
+# 10: Tag name svg
+#
+svg
+#
+# 11: Arguments for svg tag
+#
+width="%lgin" height="%lgin" viewBox="0 0 %ld %ld"
+#
+# 12 13: Attributes of complete svg tag.
+#
+xmlns="http://www.w3.org/2000/svg"\n
+xmlns:xlink="http://www.w3.org/1999/xlink"\n
+#
+# 14: Title tag
+#
+title
+#
+# 15: Desc tag
+#
+desc
+#
+# 16: Description
+#
+Fig file converted by fig2lat
+#
+# 17: Additional comment after description
+#
+http://dktools.sourceforge.net/fig2lat.html
+#
+# 18: defs
+#
+defs
+#
+# 19: style
+#
+style
+#
+# 20: Style type
+#
+type="text/css"
+#
+# 21: Start CDATA
+#
+<![CDATA[
+#
+# 22: End CDATA
+#
+]]>
+#
+# 23 24: Start and end of font face
+#
+@font-face {\n
+}\n
+#
+# 25: Font family
+#
+font-family: "
+#
+# 26: End of original font family
+#
+";\n
+#
+# 27: Oblique
+#
+font-style: oblique;\n
+#
+# 28: Italic
+#
+font-style: italic;\n
+#
+# 29: Normal
+#
+font-style: normal;\n
+#
+# 30: Font weight
+#
+font-weight: %d;\n
+#
+# 31 32 33: Font source
+#
+src: url("
+.ttf
+");\n
+#
+# 34 Prefix (no longer used)
+#
+file://
+#
+# 35
+#
+g
+#
+# 36
+#
+/>\n
+#
+# 37 38 39
+#
+rect
+x="%lg" y="%lg" width="%lg" height="%lg"
+ rx="%lg" ry="%lg"
+#
+# 40 41 42 43
+#
+polygon
+points="
+"\n
+%lg,%lg
+#
+# 44
+#
+polyline
+#
+# 45 46 47 48 49
+#
+circle
+ellipse
+\ncx="%lg" cy="%lg" r="%lg"\n
+\ntransform="translate(%lg %lg) rotate(%lg)" rx="%lg" ry="%lg"\n
+\ncx="%lg" cy="%lg" rx="%lg" ry="%lg"\n
+#
+# 50 51 52 53
+#
+text
+>
+\nx="%lg" y="%lg"
+\ntransform="translate(%lg %lg) rotate(%lg)" x="0" y="0"\n
+#
+# 54 55 56 57 58 59
+#
+path
+\nd="
+M%lg,%lg\n
+C%lg,%lg %lg,%lg %lg,%lg
+L%lg,%lg\n
+Z
+#
+# 60 61 62 63 64 65
+#
+\ntransform="translate(%lg %lg)
+ rotate(%d)
+ scale(
+1
+-1
+)
+#
+# 66 67
+#
+image
+\nx="0" y="0" width="%lg" height="%lg"\nxlink:href="
+$!end
+};
+
+
+
+/** Translation table for ASCII characters.
+*/
+static char const * const f2lsvg_html_translation_table[] = {
+/* 0 00 */ NULL,
+/* 1 01 */ NULL,
+/* 2 02 */ NULL,
+/* 3 03 */ NULL,
+/* 4 04 */ NULL,
+/* 5 05 */ NULL,
+/* 6 06 */ NULL,
+/* 7 07 */ NULL,
+/* 8 08 */ NULL,
+/* 9 09 */ "\t",
+/* 10 0a */ NULL,
+/* 11 0b */ NULL,
+/* 12 0c */ NULL,
+/* 13 0d */ NULL,
+/* 14 0e */ NULL,
+/* 15 0f */ NULL,
+/* 16 10 */ NULL,
+/* 17 11 */ NULL,
+/* 18 12 */ NULL,
+/* 19 13 */ NULL,
+/* 20 14 */ NULL,
+/* 21 15 */ NULL,
+/* 22 16 */ NULL,
+/* 23 17 */ NULL,
+/* 24 18 */ NULL,
+/* 25 19 */ NULL,
+/* 26 1a */ NULL,
+/* 27 1b */ NULL,
+/* 28 1c */ NULL,
+/* 29 1d */ NULL,
+/* 30 1e */ NULL,
+/* 31 1f */ NULL,
+/* 32 20 */ " ",
+/* 33 21 */ "!",
+/* 34 22 */ "\"",
+/* 35 23 */ "#",
+/* 36 24 */ "$",
+/* 37 25 */ "%",
+/* 38 26 */ "&amp;",
+/* 39 27 */ "'",
+/* 40 28 */ "(",
+/* 41 29 */ ")",
+/* 42 2a */ "*",
+/* 43 2b */ "+",
+/* 44 2c */ ",",
+/* 45 2d */ "-",
+/* 46 2e */ ".",
+/* 47 2f */ "/",
+/* 48 30 */ "0",
+/* 49 31 */ "1",
+/* 50 32 */ "2",
+/* 51 33 */ "3",
+/* 52 34 */ "4",
+/* 53 35 */ "5",
+/* 54 36 */ "6",
+/* 55 37 */ "7",
+/* 56 38 */ "8",
+/* 57 39 */ "9",
+/* 58 3a */ ":",
+/* 59 3b */ ";",
+/* 60 3c */ "&lt;",
+/* 61 3d */ "=",
+/* 62 3e */ "&gt;",
+/* 63 3f */ "?",
+/* 64 40 */ "@",
+/* 65 41 */ "A",
+/* 66 42 */ "B",
+/* 67 43 */ "C",
+/* 68 44 */ "D",
+/* 69 45 */ "E",
+/* 70 46 */ "F",
+/* 71 47 */ "G",
+/* 72 48 */ "H",
+/* 73 49 */ "I",
+/* 74 4a */ "J",
+/* 75 4b */ "K",
+/* 76 4c */ "L",
+/* 77 4d */ "M",
+/* 78 4e */ "N",
+/* 79 4f */ "O",
+/* 80 50 */ "P",
+/* 81 51 */ "Q",
+/* 82 52 */ "R",
+/* 83 53 */ "S",
+/* 84 54 */ "T",
+/* 85 55 */ "U",
+/* 86 56 */ "V",
+/* 87 57 */ "W",
+/* 88 58 */ "X",
+/* 89 59 */ "Y",
+/* 90 5a */ "Z",
+/* 91 5b */ "[",
+/* 92 5c */ "\\",
+/* 93 5d */ "]",
+/* 94 5e */ "^",
+/* 95 5f */ "_",
+/* 96 60 */ "`",
+/* 97 61 */ "a",
+/* 98 62 */ "b",
+/* 99 63 */ "c",
+/* 100 64 */ "d",
+/* 101 65 */ "e",
+/* 102 66 */ "f",
+/* 103 67 */ "g",
+/* 104 68 */ "h",
+/* 105 69 */ "i",
+/* 106 6a */ "j",
+/* 107 6b */ "k",
+/* 108 6c */ "l",
+/* 109 6d */ "m",
+/* 110 6e */ "n",
+/* 111 6f */ "o",
+/* 112 70 */ "p",
+/* 113 71 */ "q",
+/* 114 72 */ "r",
+/* 115 73 */ "s",
+/* 116 74 */ "t",
+/* 117 75 */ "u",
+/* 118 76 */ "v",
+/* 119 77 */ "w",
+/* 120 78 */ "x",
+/* 121 79 */ "y",
+/* 122 7a */ "z",
+/* 123 7b */ "{",
+/* 124 7c */ "|",
+/* 125 7d */ "}",
+/* 126 7e */ "~",
+/* 127 7f */ NULL,
+/* 128 80 */ NULL,
+/* 129 81 */ NULL,
+/* 130 82 */ NULL,
+/* 131 83 */ NULL,
+/* 132 84 */ NULL,
+/* 133 85 */ NULL,
+/* 134 86 */ NULL,
+/* 135 87 */ NULL,
+/* 136 88 */ NULL,
+/* 137 89 */ NULL,
+/* 138 8a */ NULL,
+/* 139 8b */ NULL,
+/* 140 8c */ NULL,
+/* 141 8d */ NULL,
+/* 142 8e */ NULL,
+/* 143 8f */ NULL,
+/* 144 90 */ NULL,
+/* 145 91 */ NULL,
+/* 146 92 */ NULL,
+/* 147 93 */ NULL,
+/* 148 94 */ NULL,
+/* 149 95 */ NULL,
+/* 150 96 */ NULL,
+/* 151 97 */ NULL,
+/* 152 98 */ NULL,
+/* 153 99 */ NULL,
+/* 154 9a */ NULL,
+/* 155 9b */ NULL,
+/* 156 9c */ NULL,
+/* 157 9d */ NULL,
+/* 158 9e */ NULL,
+/* 159 9f */ NULL,
+/* 160 a0 */ "&nbsp;",
+/* 161 a1 */ "&iexcl;",
+/* 162 a2 */ "&cent;",
+/* 163 a3 */ "&pound;",
+/* 164 a4 */ "&curren;",
+/* 165 a5 */ "&yen;",
+/* 166 a6 */ "&brvbar;",
+/* 167 a7 */ "&sect;",
+/* 168 a8 */ "&uml;",
+/* 169 a9 */ "&copy;",
+/* 170 aa */ "&ordf;",
+/* 171 ab */ "&laquo;",
+/* 172 ac */ "&not;",
+/* 173 ad */ "&shy;",
+/* 174 ae */ "&reg;",
+/* 175 af */ "&macr;",
+/* 176 b0 */ "&deg;",
+/* 177 b1 */ "&plusmn;",
+/* 178 b2 */ "&sup2;",
+/* 179 b3 */ "&sup3;",
+/* 180 b4 */ "&acute;",
+/* 181 b5 */ "&micro;",
+/* 182 b6 */ "&para;",
+/* 183 b7 */ "&middot;",
+/* 184 b8 */ "&cedil;",
+/* 185 b9 */ "&sup1;",
+/* 186 ba */ "&ordm;",
+/* 187 bb */ "&raquo;",
+/* 188 bc */ "&frac14;",
+/* 189 bd */ "&frac12;",
+/* 190 be */ "&frac34;",
+/* 191 bf */ "&iquest;",
+/* 192 c0 */ "&Agrave;",
+/* 193 c1 */ "&Aacute;",
+/* 194 c2 */ "&Acirc;",
+/* 195 c3 */ "&Atilde;",
+/* 196 c4 */ "&Auml;",
+/* 197 c5 */ "&Aring;",
+/* 198 c6 */ "&AElig;",
+/* 199 c7 */ "&Ccedil;",
+/* 200 c8 */ "&Egrave;",
+/* 201 c9 */ "&Eacute;",
+/* 202 ca */ "&Ecirc;",
+/* 203 cb */ "&Euml;",
+/* 204 cc */ "/Igrave;",
+/* 205 cd */ "&Iacute;",
+/* 206 ce */ "&Icirc;",
+/* 207 cf */ "&Iuml;",
+/* 208 d0 */ "&ETH;",
+/* 209 d1 */ "&Ntilde;",
+/* 210 d2 */ "&Ograve;",
+/* 211 d3 */ "&Oacute;",
+/* 212 d4 */ "&Ocirc;",
+/* 213 d5 */ "&Otilde;",
+/* 214 d6 */ "&Ouml;",
+/* 215 d7 */ "&times;",
+/* 216 d8 */ "&Oslash;",
+/* 217 d9 */ "&Ugrave;",
+/* 218 da */ "&Uacute;",
+/* 219 db */ "&Ucirc;",
+/* 220 dc */ "&Uuml;",
+/* 221 dd */ "&Yacute;",
+/* 222 de */ "&THORN;",
+/* 223 df */ "&szlig;",
+/* 224 e0 */ "&agrave;",
+/* 225 e1 */ "&aacute;",
+/* 226 e2 */ "&acirc;",
+/* 227 e3 */ "&atilde;",
+/* 228 e4 */ "&auml;",
+/* 229 e5 */ "&aring;",
+/* 230 e6 */ "&aelig;",
+/* 231 e7 */ "&ccedil;",
+/* 232 e8 */ "&egrave;",
+/* 233 e9 */ "&eacute;",
+/* 234 ea */ "&ecirc;",
+/* 235 eb */ "&euml;",
+/* 236 ec */ "&igrave;",
+/* 237 ed */ "&iacute;",
+/* 238 ee */ "&icirc;",
+/* 239 ef */ "&iuml;",
+/* 240 f0 */ "&eth;",
+/* 241 f1 */ "&ntilde;",
+/* 242 f2 */ "&ograve;",
+/* 243 f3 */ "&oacute;",
+/* 244 f4 */ "&ocirc;",
+/* 245 f5 */ "&otilde;",
+/* 246 f6 */ "&ouml;",
+/* 247 f7 */ "&divide;",
+/* 248 f8 */ "&oslash;",
+/* 249 f9 */ "&ugrave;",
+/* 250 fa */ "&uacute;",
+/* 251 fb */ "&ucirc;",
+/* 252 fc */ "&uuml;",
+/* 253 fd */ "&yacute;",
+/* 254 fe */ "&thorn;",
+/* 255 ff */ "&yuml;"
+};
+
+
+$*
+ Tool functions
+$*
+
+
+
+/** Write one text line, use special HTML notation for characters
+ if necessary.
+ @param str String to write.
+ @param of Output file.
+*/
+static
+void
+f2lsvg_fputs_translate(char const *str, FILE *of)
+{
+ char const *ptr;
+ char const *opt;
+ char c;
+ unsigned char uc;
+ unsigned u;
+ ptr = str;
+ while(*ptr) {
+ c = *(ptr++);
+ uc = (unsigned char)c;
+ u = (unsigned)uc;
+ while(255 < u) {
+ u -= 256;
+ }
+ opt = f2lsvg_html_translation_table[u];
+ if(opt) {
+ fputs(opt, of);
+ } else {
+ fputc(c, of);
+ }
+ }
+}
+
+
+
+/** Write SVG tag name.
+ For full SVG write the tag name directly, when producing an SVG
+ fragment we prepend svg:.
+ @param job Job structure.
+ @param ind Index of tag name in f2lsvg_c8_kw.
+*/
+static
+void
+f2lsvg_tag_name(f2l_job_t *job, size_t ind)
+{
+ if(job->fragment) {
+ fputs(f2lsvg_c8_kw[7], job->of1);
+ }
+ fputs(f2lsvg_c8_kw[ind], job->of1);
+}
+
+
+
+/** Start opening tag.
+ @param job Job structure.
+ @param ind Index of tag name in f2lsvg_c8_kw.
+*/
+static
+void
+f2lsvg_tag_open_start(f2l_job_t *job, size_t ind)
+{
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ if(job->fragment) {
+ fputs(f2lsvg_c8_kw[7], job->of1);
+ }
+ fputs(f2lsvg_c8_kw[ind], job->of1);
+ fputs(f2lsvg_c8_kw[1], job->of1);
+}
+
+
+
+/** End a tag.
+ @param job Job structure.
+*/
+static
+void
+f2lsvg_tag_end(f2l_job_t *job)
+{
+ fputs(f2lsvg_c8_kw[9], job->of1);
+}
+
+
+
+/** Opening tag.
+ @param job Job structure.
+ @param ind Index of tag name in f2lsvg_c8_kw.
+*/
+static
+void
+f2lsvg_tag_open(f2l_job_t *job, size_t ind)
+{
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ if(job->fragment) {
+ fputs(f2lsvg_c8_kw[7], job->of1);
+ }
+ fputs(f2lsvg_c8_kw[ind], job->of1);
+ f2lsvg_tag_end(job);
+}
+
+
+
+
+/** Write a closing tag.
+ @param job Job structure.
+ @param ind Index of tag name in f2lsvg_c8_kw.
+*/
+static
+void
+f2lsvg_tag_close(f2l_job_t *job, size_t ind)
+{
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ fputs(f2lsvg_c8_kw[8], job->of1);
+ if(job->fragment) {
+ fputs(f2lsvg_c8_kw[7], job->of1);
+ }
+ fputs(f2lsvg_c8_kw[ind], job->of1);
+ fputs(f2lsvg_c8_kw[9], job->of1);
+ fputs(f2lsvg_c8_kw[0], job->of1);
+}
+
+
+
+/** Calculate factors for coordinates transformations.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lsvg_coordinates_transformation(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ double xmin;
+ double xmax;
+ double ymin;
+ double ymax;
+ int back = 1;
+ int mec = 0;
+ $? "+ f2lsvg_coordinates_transformation"
+ (job->ct2d).mx = (job->ct2d).my = dk3ma_d_div_ok(72.0, drw->res, &mec);
+ xmin = dk3ma_d_mul_ok((job->ct2d).mx, (drw->bb).xmin, &mec);
+ xmax = dk3ma_d_mul_ok((job->ct2d).mx, (drw->bb).xmax, &mec);
+ ymin = dk3ma_d_mul_ok((job->ct2d).my, (drw->bb).ymin, &mec);
+ ymax = dk3ma_d_mul_ok((job->ct2d).my, (drw->bb).ymax, &mec);
+ /* Align to 1/8 inch grid.
+ */
+ xmin = xmin / 9.0; xmin = floor(xmin);
+ xmin = dk3ma_d_mul_ok(9.0, xmin, &mec);
+ xmax = xmax / 9.0; xmax = ceil(xmax);
+ xmax = dk3ma_d_mul_ok(9.0, xmax, &mec);
+ ymin = ymin / 9.0; ymin = floor(ymin);
+ ymin = dk3ma_d_mul_ok(9.0, ymin, &mec);
+ ymax = ymax / 9.0; ymax = ceil(ymax);
+ ymax = dk3ma_d_mul_ok(9.0, ymax, &mec);
+ (job->ct2d).nx = -1.0 * xmin;
+ (job->ct2d).ny = -1.0 * ymin;
+ job->width = dk3ma_d_sub_ok(xmax, xmin, &mec);
+ job->height = dk3ma_d_sub_ok(ymax, ymin, &mec);
+ job->lwidth = dk3ma_d_to_l_ok(job->width, &mec);
+ job->lheight = dk3ma_d_to_l_ok(job->height, &mec);
+ $? ". mx=%lg nx=%lg my=%lg ny=%lg", (job->ct2d).mx, (job->ct2d).nx, (job->ct2d).my, (job->ct2d).ny
+ $? ". bb=%ld %ld (%lg %lg)", job->lwidth, job->lheight, (job->width / 72.0), (job->height / 72.0)
+ if(mec) {
+ back = 0;
+ /* ERROR: Math problem */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 38);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH); $? ". exitcode"
+ } $? "- f2lsvg_coordinates_transformation %d", back
+ return back;
+}
+
+
+
+/** Collect style information for a text object,
+ add to SVG style collection if necessary.
+ @param job Job structure.
+ @param drw Fig drawing.
+ @param psvg SVG style collection.
+ @param pobj Object to add.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lsvg_text_object_style(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *pobj
+)
+{
+ f2l_svg_style_t sty; /* Style. */
+ dk3_fig_color_t fc; /* Fill color. */
+ int back = 1;
+ $? "+ f2lsvg_text_object_style %lu", pobj->li
+ if(!(DK3_FIG_FONT_FLAG_HIDDEN & ((pobj->dt).txt.ff))) {
+ f2lsvgst_style_initialize(&sty);
+ /* Fill color.
+ */
+ dk3fig_tool_find_int_color(&fc, drw, pobj->pc, 20);
+ f2lsvgst_style_set_fill_color(&sty, fc.r, fc.g, fc.b);
+ /* Text font.
+ */
+ f2lsvgst_style_set_text(
+ psvg, &sty,
+ ((((pobj->dt).txt.ff) & DK3_FIG_FONT_FLAG_PS) ? 1 : 0),
+ (pobj->dt).txt.fo,
+ (pobj->dt).txt.fs
+ );
+ /* Text alignment.
+ */
+ f2lsvgst_style_set_text_align(&sty, pobj->st);
+ pobj->dsd = (void *)f2lsvgst_style_add(psvg, &sty);
+ if(!(pobj->dsd)) {
+ back = 0;
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ }
+ $? "- f2lsvg_text_object_style %d", back
+ return back;
+}
+
+
+
+/** Collect style information for a non-text object,
+ add to SVG style collection if necessary.
+ @param job Job structure.
+ @param drw Fig drawing.
+ @param psvg SVG style collection.
+ @param pobj Object to add.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lsvg_path_object_style(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *pobj
+)
+{
+ f2l_svg_style_t sty; /* Style. */
+ f2l_svg_fill_pattern_t pat; /* Pattern. */
+ dk3_fig_color_t fc; /* Fill color. */
+ dk3_fig_color_t sc; /* Stroke color. */
+ double lw; /* Line width in SVG units. */
+ double lsv; /* Line style value in SVG units. */
+ int res; /* Operation result. */
+ int mec = 0; /* Mathematical error code. */
+ int any = 0; /* Flag: Any settings applied to style. */
+ int op = 0; /* Draw operation. */
+ int back = 1 ;
+ $? "+ f2lsvg_path_object_style %lu", pobj->li
+ op = dk3fig_tool_get_operation(drw, pobj);
+ f2lsvgst_style_initialize(&sty);
+ if(op & DK3_FIG_OP_PATTERN) {
+ /* Fill pattern.
+ */
+ any = 1;
+ dk3fig_tool_find_int_color(&fc, drw, pobj->fc, 20);
+ dk3fig_tool_find_int_color(&sc, drw, pobj->pc, 20);
+ pat.pn = 0UL;
+ pat.fn = pobj->fi;
+ pat.sr = sc.r; pat.sg = sc.g; pat.sb = sc.b;
+ pat.fr = fc.r; pat.fg = fc.g; pat.fb = fc.b;
+ res = f2lsvgst_style_set_pattern(psvg, &sty, &pat);
+ if(!(res)) {
+ back = 0;
+ switch(psvg->ec) {
+ case DK3_ERROR_MEMORY: {
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 9);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ } break;
+ default: {
+ /* ERROR: Mathematical error. */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 38);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH); $? ". exitcode"
+ } break;
+ }
+ }
+ } else {
+ if(op & DK3_FIG_OP_FILL) {
+ /* Fill color.
+ */
+ dk3fig_tool_find_int_color(&fc, drw, pobj->fc, pobj->fi);
+ f2lsvgst_style_set_fill_color(&sty, fc.r, fc.g, fc.b);
+ any = 1;
+ }
+ }
+ if(op & DK3_FIG_OP_STROKE) {
+ any = 1;
+ /* Line width.
+ */
+ lw = dk3fig_tool_get_lw(drw, pobj, &mec);
+ lw = dk3ct_2d_r(&(job->ct2d), lw, &mec);
+ f2lsvgst_style_set_line_width(&sty, lw);
+ if(mec) {
+ back = 0;
+ /* ERROR: Mathematical error. */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 38);
+ mec = 0;
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH); $? ". exitcode"
+ }
+ /* Line style.
+ */
+ /* lsv = dk3ct_2d_r(&(job->ct2d), pobj->sv, &mec); */
+ lsv = 0.9 * pobj->sv;
+ f2lsvgst_style_set_line_style(&sty, pobj->ls, lsv);
+ /* Stroke color.
+ */
+ dk3fig_tool_find_int_color(&sc, drw, pobj->pc, 20);
+ f2lsvgst_style_set_line_color(&sty, sc.r, sc.g, sc.b);
+ if(!(pobj->cl)) {
+ /* Line cap.
+ */
+ f2lsvgst_style_set_text_line_cap(&sty, pobj->cs);
+ }
+ }
+ if(op) {
+ if(DK3_FIG_OBJ_ELLIPSE != pobj->ot) {
+ if(!((DK3_FIG_OBJ_ARC == pobj->ot) && (1 == pobj->st))) {
+ /* Line join.
+ */
+ any = 1;
+ f2lsvgst_style_set_text_line_join(&sty, pobj->js);
+ }
+ }
+ }
+ if(any) {
+ pobj->dsd = (void *)f2lsvgst_style_add(psvg, &sty);
+ if(!(pobj->dsd)) {
+ back = 0;
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ }
+ $? "- f2lsvg_path_object_style %d", back
+ return back;
+}
+
+
+
+/** Collect style information for one object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pobj Current object.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lsvg_object_style_collection(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *pobj
+)
+{
+ int back = 1;
+ switch(pobj->ot) {
+ case DK3_FIG_OBJ_PSEUDO_HALF_CIRCLE: {
+ if(!f2lsvg_path_object_style(job, drw, psvg, pobj)) { back = 0; }
+ } break;
+ case DK3_FIG_OBJ_ELLIPSE: {
+ if(!f2lsvg_path_object_style(job, drw, psvg, pobj)) { back = 0; }
+ } break;
+ case DK3_FIG_OBJ_POLYLINE: {
+ if(5 != pobj->st) {
+ if(!f2lsvg_path_object_style(job, drw, psvg, pobj)) { back = 0; }
+ }
+ } break;
+ case DK3_FIG_OBJ_SPLINE: {
+ if(!f2lsvg_path_object_style(job, drw, psvg, pobj)) { back = 0; }
+ } break;
+ case DK3_FIG_OBJ_ARC: {
+ if(!f2lsvg_path_object_style(job, drw, psvg, pobj)) { back = 0; }
+ } break;
+ case DK3_FIG_OBJ_TEXT: {
+ if(!f2lsvg_text_object_style(job, drw, psvg, pobj)) { back = 0; }
+ } break;
+ }
+ if(!(back)) {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN); $? ". exitcode"
+ }
+ return back;
+}
+
+
+
+/** Collect style information for all objects in drawing,
+ add styles to style collection.
+ @param job Job structure.
+ @param drw Fig drawing.
+ @param psvg SVG style collection.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lsvg_collect_styles(f2l_job_t *job, dk3_fig_drawing_t *drw, f2l_svg_t *psvg)
+{
+ dk3_fig_obj_t *pobj;
+ unsigned long objno = 0UL;
+ unsigned long oldsourceline;
+ int res;
+ int back = 1;
+ $? "+ f2lsvg_collect_styles"
+ oldsourceline = dk3app_get_source_line(job->app);
+ dk3sto_it_reset(drw->iobj);
+ while(NULL != (pobj = (dk3_fig_obj_t *)dk3sto_it_next(drw->iobj))) {
+ if(!dk3fig_tool_is_bgrect(pobj, objno)) {
+ dk3app_set_source_line(job->app, pobj->li);
+ if(!f2lsvg_object_style_collection(job, drw, psvg, pobj)) {
+ back = 0;
+ }
+ if(pobj->af) {
+ if((pobj->af)->o1) {
+ res = f2lsvg_object_style_collection(
+ job, drw, psvg, (dk3_fig_obj_t *)((pobj->af)->o1)
+ );
+ if(!(res)) { back = 0; }
+ }
+ if((pobj->af)->o2) {
+ res = f2lsvg_object_style_collection(
+ job, drw, psvg, (dk3_fig_obj_t *)((pobj->af)->o2)
+ );
+ if(!(res)) { back = 0; }
+ }
+ }
+ if(pobj->ab) {
+ if((pobj->ab)->o1) {
+ res = f2lsvg_object_style_collection(
+ job, drw, psvg, (dk3_fig_obj_t *)((pobj->ab)->o1)
+ );
+ if(!(res)) { back = 0; }
+ }
+ if((pobj->ab)->o2) {
+ res = f2lsvg_object_style_collection(
+ job, drw, psvg, (dk3_fig_obj_t *)((pobj->ab)->o2)
+ );
+ if(!(res)) { back = 0; }
+ }
+ }
+ }
+ objno++;
+ }
+ dk3app_set_source_line(job->app, oldsourceline);
+ $? "- f2lsvg_collect_styles %d", back
+ return back;
+}
+
+
+
+/** Check whether or not we must append a slash to the font base
+ directory.
+ @param bn Font base directory name.
+ @return 1 to add a slash, 0 for no slash needed.
+*/
+static
+int
+f2lsvg_must_add_slash_to_font_base(char const *bn)
+{
+ char const *ptr;
+ int back = 1;
+ ptr = bn;
+ while(*ptr) {
+ if('/' == *ptr) {
+ back = 0;
+ } else {
+ back = 1;
+ }
+ ptr++;
+ }
+ return back;
+}
+
+
+
+/** Write font face definitions.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+*/
+static
+void
+f2lsvg_write_font_faces(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg
+)
+{
+ dkChar dkb[DK3_MAX_PATH]; /* Font base (dkChars). */
+ char chb[DK3_MAX_PATH]; /* Font base (8-bit chars). */
+ size_t i; /* Walk through the 35 fonts. */
+ int fs; /* Font style. */
+ int res = 0;
+ $? "+ f2lsvg_write_font_faces"
+ if(0 < job->svgfontbase) { $? ". fontbase"
+ switch(job->svgfontbase) {
+ case 2: {
+ res = dk3font_gs_base_web(job->app, dkb, DK3_SIZEOF(dkb,dkChar));
+ } break;
+ default: {
+ res = dk3font_gs_base_local(job->app, dkb, DK3_SIZEOF(dkb,dkChar));
+ } break;
+ }
+ if(res) { $? ". res (1) = 1"
+ res = dk3str_to_c8p_app(
+ chb, sizeof(chb), dkb, dk3app_get_encoding(job->app), job->app
+ ); $? ". res (2) = %d", res
+ }
+ for(i = 0; i < 35; i++) { $? ". font %u", (unsigned)i
+ if((psvg->psFontsUsed)[i]) {
+ fputs(f2lsvg_c8_kw[23], job->of1);
+ /* Font family.
+ */
+ fputs(f2lsvg_c8_kw[25], job->of1);
+ fputs(dk3font_get_svg_family((int)i), job->of1);
+ fputs(f2lsvg_c8_kw[26], job->of1); $? ". font family finished"
+ /* Font style
+ */
+ fs = dk3font_get_svg_features((int)i);
+ if(fs & DK3_FONT_OBLIQUE) {
+ fputs(f2lsvg_c8_kw[27], job->of1);
+ } else {
+ if(fs & DK3_FONT_ITALIC) {
+ fputs(f2lsvg_c8_kw[28], job->of1);
+ } else {
+ fputs(f2lsvg_c8_kw[29], job->of1);
+ }
+ } $? ". font style finished"
+ /* Font weight
+ */
+ fprintf(job->of1,f2lsvg_c8_kw[30],dk3font_get_svg_font_weight((int)i));
+ $? ". font weight finished"
+ /* Source
+ */
+ fputs(f2lsvg_c8_kw[31], job->of1);
+ if(res) {
+#if 0
+ /* 2013-01-30 No file:// prefix
+ */
+ if(1 == job->svgfontbase) {
+ fputs(f2lsvg_c8_kw[34], job->of1);
+ }
+#endif
+ fputs(chb, job->of1);
+ if(f2lsvg_must_add_slash_to_font_base(chb)) {
+ fputs(f2lsvg_c8_kw[8], job->of1);
+ }
+ } $? ". chb"
+ fputs(dk3font_get_gs_old_file((int)i), job->of1); $? ". old file"
+ fputs(f2lsvg_c8_kw[32], job->of1);
+#if 0
+ /* 2013-01-30 No font id for TTF fonts
+ */
+ fputs(dk3font_get_svg_fontid((int)i), job->of1); $? ". font id"
+#endif
+ fputs(f2lsvg_c8_kw[33], job->of1); $? ". 1"
+ fputs(f2lsvg_c8_kw[24], job->of1); $? ". 2"
+ } $? ". 3"
+ } $? ". 4"
+ } $? "- f2lsvg_write_font_faces"
+}
+
+
+
+$*
+ Driver functions
+$*
+
+
+/** Driver-specific initialization.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lsvg_driver_initialize(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ f2l_svg_t *psvg;
+ int back = 0;
+ $? "+ f2lsvg_driver_initialize"
+ if(f2lsvg_coordinates_transformation(job, drw)) {
+ psvg = f2lsvgst_new_app(job->app);
+ if(psvg) {
+ drw->dsd = (void *)psvg;
+ back = f2lsvg_collect_styles(job, drw, psvg);
+ }
+ } $? "- f2lsvg_driver_initialize %d", back
+ return back;
+}
+
+
+
+/** Release resources allocated by f2lud_driver_initialize().
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+static
+void
+f2lsvg_driver_end(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ $? "+ f2lsvg_driver_end"
+ if(drw->dsd) {
+ f2lsvgst_delete((f2l_svg_t *)(drw->dsd));
+ } drw->dsd = NULL;
+ $? "- f2lsvg_driver_end"
+}
+
+
+
+/** Open output file.
+ @param job Jobs structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lsvg_open_output_files(f2l_job_t *job)
+{
+ int back = 0;
+ job->of1 = dk3sf_fopen_app(job->on1, dkT("w"), job->app);
+ if(job->of1) {
+ back = 1;
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ return back;
+}
+
+
+
+/** Close output file.
+ @param job Job structure.
+*/
+static
+void
+f2lsvg_close_output_files(f2l_job_t *job)
+{
+ if(job->of1) {
+ dk3sf_fclose_app(job->of1, job->app);
+ } job->of1 = NULL;
+}
+
+
+
+/** Check whether we must write a style tag for font faces or style
+ definitions.
+ @param job Job structure.
+ @param psvg SVG style collection structure.
+ @return 1 to write a style tag, 0 otherwise.
+*/
+static
+int
+f2lsvg_must_write_style(f2l_job_t *job, f2l_svg_t *psvg)
+{
+ int back = 0;
+ if(job->css) {
+ if(psvg->nStyles) {
+ back = 1;
+ }
+ }
+ if(0 < job->svgfontbase) {
+ if(f2lsvgst_any_ps_font_used(psvg)) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Check whether we must write a defs tag for fill patterns,
+ font faces, or style definitions.
+ @param job Job structure.
+ @param psvg SVG style collection structure.
+ @return 1 to write a defs tag, 0 otherwise.
+*/
+static
+int
+f2lsvg_must_write_defs(f2l_job_t *job, f2l_svg_t *psvg)
+{
+ int back;
+ back = f2lsvg_must_write_style(job, psvg);
+ if(0 == back) {
+ if(psvg->nPatterns) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Write start of output file.
+ @param job Job strucure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lsvg_start_processing(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ f2l_svg_t *psvg;
+ int back = 1;
+ $? "+ f2lsvg_start_processing"
+ psvg = (f2l_svg_t *)(drw->dsd);
+ /* XML header and doctype.
+ */
+ if(!(job->fragment)) {
+ fputs(f2lsvg_c8_kw[2], job->of1);
+ fputs(f2lsvg_c8_kw[3], job->of1);
+ fputs(f2lsvg_c8_kw[4], job->of1);
+ fputs(f2lsvg_c8_kw[5], job->of1);
+ }
+ /* Opening svg tag.
+ */
+ f2lsvg_tag_open_start(job, 10);
+ fprintf(
+ job->of1, f2lsvg_c8_kw[11],
+ (job->width / 72.0), (job->height / 72.0), job->lwidth, job->lheight
+ );
+ if(!(job->fragment)) {
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ fputs(f2lsvg_c8_kw[12], job->of1);
+ fputs(f2lsvg_c8_kw[13], job->of1);
+ }
+ f2lsvg_tag_end(job);
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ /* Title.
+ */
+ f2lsvg_tag_open(job, 14);
+ fputs(f2lsvg_c8_kw[16], job->of1);
+ f2lsvg_tag_close(job, 14);
+ /* Description.
+ */
+ f2lsvg_tag_open(job, 15);
+ fputs(f2lsvg_c8_kw[17], job->of1);
+ f2lsvg_tag_close(job, 15);
+ /* Definitions and style.
+ */
+ if(f2lsvg_must_write_defs(job, psvg)) {
+ f2lsvg_tag_open(job, 18);
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ /* Pattern definitions.
+ */
+ f2lsvgst_write_patterns(job, drw, psvg);
+ if(f2lsvg_must_write_style(job, psvg)) {
+ f2lsvg_tag_open_start(job, 19);
+ fputs(f2lsvg_c8_kw[20], job->of1);
+ f2lsvg_tag_end(job);
+ fputs(f2lsvg_c8_kw[21], job->of1);
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ /* Font face definitions if any.
+ */
+ f2lsvg_write_font_faces(job, drw, psvg);
+ /* Style definitions.
+ */
+ if(job->css) {
+ f2lsvgst_write_styles(job, drw, psvg);
+ }
+ fputs(f2lsvg_c8_kw[22], job->of1);
+ f2lsvg_tag_close(job, 19);
+ }
+ f2lsvg_tag_close(job, 18);
+ } $? "- f2lsvg_start_processing %d", back
+ return back;
+}
+
+
+
+/** Write end of output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+static
+void
+f2lsvg_end_processing(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ f2lsvg_tag_close(job, 10);
+}
+
+
+
+/** Process ellipse object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_ellipse(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ double rotation = 0.0; /* Rotation in degree. */
+ double irot; /* Rotation as integer. */
+ double x; /* Center X. */
+ double y; /* Center Y. */
+ double rx; /* Radius X. */
+ double ry; /* Radius Y. */
+ int isEllipse = 0; /* Flag: Is ellipse. */
+ int isRotated = 0; /* Flag: Is rotated. */
+ int mec = 0; /* Mathematical error code. */
+
+ switch(obj->st) {
+ case 1: case 2: {
+ if(fabs(dk3ma_d_sub_ok((obj->dt).ell.rx,(obj->dt).ell.ry,&mec)) > 1.0e-6)
+ {
+ isEllipse = 1;
+ if(fabs((obj->dt).ell.an) > 1.0e-6) {
+ isRotated = 1;
+ rotation = dk3ma_d_mul_ok(180.0, ((obj->dt).ell.an / M_PI), &mec);
+ irot = dk3ma_d_rint(rotation);
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok(rotation, irot, &mec))) {
+ rotation = irot;
+ }
+ rotation = -1.0 * rotation;
+ }
+ }
+ } break;
+ }
+ x = dk3ct_2d_x(&(job->ct2d), (obj->dt).ell.cx, &mec);
+ y = dk3ct_2d_y(&(job->ct2d), (obj->dt).ell.cy, &mec);
+ rx = ry = dk3ct_2d_r(&(job->ct2d), (obj->dt).ell.rx, &mec);
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ if(isEllipse) {
+ ry = dk3ct_2d_r(&(job->ct2d), (obj->dt).ell.ry, &mec);
+ f2lsvg_tag_name(job, 46);
+ if(isRotated) {
+ fprintf(job->of1, f2lsvg_c8_kw[48], x, y, rotation, rx, ry);
+ } else {
+ fprintf(job->of1, f2lsvg_c8_kw[49], x, y, rx, ry);
+ }
+ } else {
+ f2lsvg_tag_name(job, 45);
+ fprintf(job->of1, f2lsvg_c8_kw[47], x, y, rx);
+ }
+ f2lsvgst_write_style_for_object(job, drw, psvg, obj);
+ fputs(f2lsvg_c8_kw[36], job->of1);
+ if(mec) { *ec = mec; }
+}
+
+
+
+/** Process box object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param arcbox Flag: Rounded corners.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_box(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int arcbox,
+ int *ec
+)
+{
+ dk3_bb_t outbb;
+ dk3_fig_poly_point_t *po;
+ double x;
+ double y;
+ double w;
+ double h;
+ double r;
+ size_t i;
+ int mec = 0;
+ $? "+ f2lsvg_process_box"
+ po = (obj->dt).pol.po;
+ if(po) {
+ dk3bb_reset(&outbb);
+ for(i = 0; i < (obj->dt).pol.np; i++) {
+ dk3bb_add_x(&outbb, dk3ct_2d_x(&(job->ct2d), po->x, &mec));
+ dk3bb_add_y(&outbb, dk3ct_2d_y(&(job->ct2d), po->y, &mec));
+ po++;
+ }
+ x = outbb.xmin;
+ y = outbb.ymin;
+ w = fabs(dk3ma_d_sub_ok(outbb.xmax, outbb.xmin, &mec));
+ h = fabs(dk3ma_d_sub_ok(outbb.ymax, outbb.ymin, &mec));
+ r = -1.0;
+ if(arcbox) { $? ". r=%lg", (obj->dt).pol.ra
+ r = fabs(0.9 * (obj->dt).pol.ra); $? ". r=%lg", r
+ if(r > (0.5 * w)) { r = 0.5 * w; }
+ if(r > (0.5 * h)) { r = 0.5 * h; } $? ". r=%lg", r
+ }
+ if(0 == mec) {
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 37);
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ fprintf(job->of1, f2lsvg_c8_kw[38], x, y, w, h);
+ if(arcbox) {
+ fprintf(job->of1, f2lsvg_c8_kw[39], r, r);
+ }
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ f2lsvgst_write_style_for_object(job, drw, psvg, obj);
+ fputs(f2lsvg_c8_kw[36], job->of1);
+ }
+ }
+ dk3bb_reset(&outbb);
+ if(mec) { *ec = mec; }
+ $? "- f2lsvg_process_box"
+}
+
+
+
+/** Process polygon object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param primary Flag: Primary object.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_pl_polygon(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+ dk3_fig_poly_point_t *po;
+ size_t np;
+ size_t i;
+ int mec = 0;
+
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 40);
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ fputs(f2lsvg_c8_kw[41], job->of1);
+ po = (obj->dt).pol.po;
+ np = (obj->dt).pol.np;
+ if(primary) {
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok(po[0].x, po[np - 1].x, &mec))) {
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok(po[0].y, po[np - 1].y, &mec))) {
+ np--;
+ }
+ }
+ }
+ for(i = 0; i < np; i++) {
+ fprintf(
+ job->of1, f2lsvg_c8_kw[43],
+ dk3ct_2d_x(&(job->ct2d), po->x, &mec),
+ dk3ct_2d_y(&(job->ct2d), po->y, &mec)
+ );
+ if(i != (np - 1)) {
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ }
+ po++;
+ }
+ fputs(f2lsvg_c8_kw[42], job->of1);
+ f2lsvgst_write_style_for_object(job, drw, psvg, obj);
+ fputs(f2lsvg_c8_kw[36], job->of1);
+ if(mec) { *ec = mec; }
+}
+
+
+
+/** Process polygon object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_pl_polyline(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ dk3_fig_poly_point_t *po;
+ size_t np;
+ size_t i;
+ int mec = 0;
+
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 44);
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ fputs(f2lsvg_c8_kw[41], job->of1);
+ po = (obj->dt).pol.po;
+ np = (obj->dt).pol.np;
+ for(i = 0; i < np; i++) {
+ fprintf(
+ job->of1, f2lsvg_c8_kw[43],
+ dk3ct_2d_x(&(job->ct2d), po->x, &mec),
+ dk3ct_2d_y(&(job->ct2d), po->y, &mec)
+ );
+ if(i != (np - 1)) {
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ }
+ po++;
+ }
+ fputs(f2lsvg_c8_kw[42], job->of1);
+ f2lsvgst_write_style_for_object(job, drw, psvg, obj);
+ fputs(f2lsvg_c8_kw[36], job->of1);
+ if(mec) { *ec = mec; }
+}
+
+
+
+/** Process image object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_image(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ dk3_bb_t outbb; /* Output range. */
+ dk3_bif_t *bif; /* Image to process. */
+ dk3_fig_poly_point_t *po; /* Coordinates points. */
+ double tx; /* X translation. */
+ double ty; /* Y translation. */
+ double xres; /* Image resolution in x direction. */
+ double yres; /* Image resolution in y direction. */
+ double w; /* Image width (resolution used). */
+ double h; /* Image height (resolution used). */
+ double qx; /* Usable stretch factor for x. */
+ double qy; /* Usable stretch factor for y. */
+ double ow = 0.0; /* Output width. */
+ double oh = 0.0; /* Output height. */
+ double x1; /* Smallest x value. */
+ double x2; /* Largest x value. */
+ double y1; /* Smallest y value. */
+ double y2; /* Largest y value. */
+ dk3_bif_coord_t imw; /* Image width (number of pixels). */
+ dk3_bif_coord_t imh; /* Image height (number of pixels). */
+ size_t np; /* Number of coordinates points. */
+ size_t i; /* Traverse coordinates points. */
+ int drawdir; /* Drawing direction. */
+ int rotation = 0; /* Rotation in degree. */
+ int doScaleX = 0; /* Flag: Scale x=-1. */
+ int doScaleY = 0; /* Flag: Sclae y=-1. */
+
+ if((obj->dt).pol.fn) {
+ bif = dk3bif_open_c8_filename_app(
+ (obj->dt).pol.fn, DK3_BIF_IMAGE_TYPE_UNKNOWN, job->app
+ );
+ if(bif) {
+ /* Find image dimensions.
+ */
+ imw = dk3bif_get_width(bif);
+ imh = dk3bif_get_height(bif);
+ xres = dk3bif_get_xres(bif);
+ yres = dk3bif_get_yres(bif);
+ dk3bif_close(bif);
+ /* Find output area.
+ */
+ dk3bb_reset(&outbb);
+ po = (obj->dt).pol.po;
+ np = (obj->dt).pol.np;
+ for(i = 0; i < np; i++) {
+ dk3bb_add_x(&outbb, dk3ct_2d_x(&(job->ct2d), po->x, ec));
+ dk3bb_add_y(&outbb, dk3ct_2d_y(&(job->ct2d), po->y, ec));
+ po++;
+ }
+ x1 = outbb.xmin; x2 = outbb.xmax;
+ y1 = outbb.ymin; y2 = outbb.ymax;
+ /* Find drawing direction.
+ */
+ drawdir = f2lto_find_draw_direction(job, drw, obj, ec);
+ /* Find real image width and height.
+ */
+ if((xres > 0.0) && (yres > 0.0)) {
+ switch(drawdir) {
+ case DK3_IMAGE_ORIGIN_LEFT_BOTTOM:
+ case DK3_IMAGE_ORIGIN_RIGHT_TOP:
+ case DK3_IMAGE_ORIGIN_LEFT_TOP_FLIPPED:
+ case DK3_IMAGE_ORIGIN_RIGHT_BOTTOM_FLIPPED: {
+ w = dk3ma_d_div_ok((double)imh, yres, ec);
+ h = dk3ma_d_div_ok((double)imw, xres, ec);
+ } break;
+ default: {
+ w = dk3ma_d_div_ok((double)imw, xres, ec);
+ h = dk3ma_d_div_ok((double)imh, yres, ec);
+ } break;
+ }
+ } else {
+ switch(drawdir) {
+ case DK3_IMAGE_ORIGIN_LEFT_BOTTOM:
+ case DK3_IMAGE_ORIGIN_RIGHT_TOP:
+ case DK3_IMAGE_ORIGIN_LEFT_TOP_FLIPPED:
+ case DK3_IMAGE_ORIGIN_RIGHT_BOTTOM_FLIPPED: {
+ w = (double)imh;
+ h = (double)imw;
+ } break;
+ default: {
+ w = (double)imw;
+ h = (double)imh;
+ } break;
+ }
+ }
+ /* Find the stretch factors and used regions.
+ */
+ qx = dk3ma_d_div_ok(dk3ma_d_sub_ok(outbb.xmax, outbb.xmin, ec), w, ec);
+ qy = dk3ma_d_div_ok(dk3ma_d_sub_ok(outbb.ymax, outbb.ymin, ec), h, ec);
+ qx = fabs(qx);
+ qy = fabs(qy);
+#if VERSION_BEFORE_20150821
+ ow = oh = 0.0;
+#endif
+ if(qy >= qx) { /* Image too wide, can not use all height. */
+ ow = dk3ma_d_sub_ok(outbb.xmax, outbb.xmin, ec);
+ oh = dk3ma_d_mul_ok(qx, h, ec);
+ y1 = dk3ma_d_add_ok(
+ outbb.ymin,
+ (
+ 0.5 *
+ dk3ma_d_sub_ok(dk3ma_d_sub_ok(outbb.ymax, outbb.ymin, ec), oh, ec)
+ ),
+ ec
+ );
+ y2 = dk3ma_d_add_ok(y1, oh, ec);
+ } else { /* Image too high, can not use all width. */
+ oh = dk3ma_d_sub_ok(outbb.ymax, outbb.ymin, ec);
+ ow = dk3ma_d_mul_ok(qy, w, ec);
+ x1 = dk3ma_d_add_ok(
+ outbb.xmin,
+ (
+ 0.5 *
+ dk3ma_d_sub_ok(dk3ma_d_sub_ok(outbb.xmax, outbb.xmin, ec), ow, ec)
+ ),
+ ec
+ );
+ x2 = dk3ma_d_add_ok(x1, ow, ec);
+ }
+ /* Find coordinates transformations.
+ */
+ switch(drawdir) {
+ case DK3_IMAGE_ORIGIN_RIGHT_BOTTOM_FLIPPED: {
+ tx = x2; ty = y2; rotation = -90; doScaleY = 1;
+ } break;
+ case DK3_IMAGE_ORIGIN_RIGHT_TOP_FLIPPED: {
+ tx = x2; ty = y1; doScaleX = 1;
+ } break;
+ case DK3_IMAGE_ORIGIN_LEFT_BOTTOM_FLIPPED: {
+ tx = x1; ty = y2; doScaleY = 1;
+ } break;
+ case DK3_IMAGE_ORIGIN_LEFT_TOP_FLIPPED: {
+ tx = x1; ty = y1; rotation = -90; doScaleX = 1;
+ } break;
+ case DK3_IMAGE_ORIGIN_RIGHT_BOTTOM: {
+ tx = x2; ty = y2; rotation = 180;
+ } break;
+ case DK3_IMAGE_ORIGIN_RIGHT_TOP: {
+ tx = x2; ty = y1; rotation = 90;
+ } break;
+ case DK3_IMAGE_ORIGIN_LEFT_BOTTOM: {
+ tx = x1; ty = y2; rotation = -90;
+ } break;
+ default: {
+ tx = x1; ty = y1;
+ } break;
+ }
+ /* Write output.
+ */
+ /* <g transform="..."> */
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 35);
+ fprintf(job->of1, f2lsvg_c8_kw[60], tx, ty);
+ if(0 != rotation) {
+ fprintf(job->of1, f2lsvg_c8_kw[61], rotation);
+ }
+ if((doScaleX) || (doScaleY)) {
+ fputs(f2lsvg_c8_kw[62], job->of1);
+ fputs(f2lsvg_c8_kw[(doScaleX) ? 64 : 63], job->of1);
+ fputs(f2lsvg_c8_kw[1], job->of1);
+ fputs(f2lsvg_c8_kw[(doScaleY) ? 64 : 63], job->of1);
+ fputs(f2lsvg_c8_kw[65], job->of1);
+ }
+ fputs(f2lsvg_c8_kw[42], job->of1);
+ fputs(f2lsvg_c8_kw[5], job->of1);
+ /* <image ... /> */
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 66);
+ fprintf(job->of1, f2lsvg_c8_kw[67], ow, oh);
+ fputs((obj->dt).pol.fn, job->of1);
+ fputs(f2lsvg_c8_kw[42], job->of1);
+ fputs(f2lsvg_c8_kw[36], job->of1);
+ /* </g> */
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ fputs(f2lsvg_c8_kw[8], job->of1);
+ f2lsvg_tag_name(job, 35);
+ fputs(f2lsvg_c8_kw[5], job->of1);
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ }
+}
+
+
+
+/** Process polyline object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param primary Flag: Primary object.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_polyline(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+ switch(obj->st) {
+ case 5: { /* imported image */
+ f2lsvg_process_image(job, drw, psvg, obj, ec);
+ } break;
+ case 4: { /* arc box */
+ f2lsvg_process_box(job, drw, psvg, obj, 1, ec);
+ } break;
+ case 3: { /* polygon */
+ f2lsvg_process_pl_polygon(job, drw, psvg, obj, primary, ec);
+ } break;
+ case 2: { /* box */
+ f2lsvg_process_box(job, drw, psvg, obj, 0, ec);
+ } break;
+ default: { /* polyline */
+ f2lsvg_process_pl_polyline(job, drw, psvg, obj, ec);
+ } break;
+ }
+}
+
+
+
+/** Process open spline object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param sp Spline points.
+ @param np Total number of points
+ @param cp Current point/segment.
+ @param isfirst Flag: Moveto needed.
+ @param iscl Flag: Closed (1) or open (0) spline.
+ @param primary Flag: Primary object (1=object, 0=arrowhead).
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_full_spline_segment(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_spline_point_t *sp,
+ size_t np,
+ size_t cp,
+ int isfirst,
+ int iscl,
+ int primary,
+ int *ec
+)
+{
+ dk3_xspline_segment_t seg;
+ dk3_fig_spline_point_t *pa = NULL;
+ dk3_fig_spline_point_t *pb = NULL;
+ dk3_fig_spline_point_t *pc = NULL;
+ dk3_fig_spline_point_t *pd = NULL;
+ double factor;
+ double t;
+ double x;
+ double y;
+ double dxdt;
+ double dydt;
+ double lastx = 0.0;
+ double lasty = 0.0;
+ double lastdxdt = 0.0;
+ double lastdydt = 0.0;
+ size_t xsss;
+ size_t iseg;
+ size_t ic;
+ size_t id;
+ int res;
+ int mec = 0;
+ $? "+ f2lsvg_process_full_spline_segment %u / %u", (unsigned)cp, (unsigned)np
+ if(cp < ((iscl) ? (np) : (np - 1))) {
+ pb = &(sp[cp]); $? ". b = %u", (unsigned)cp
+ ic = cp + 1;
+ while(ic >= np) { ic = ic - np; } $? ". c = %u", (unsigned)ic
+ pc = &(sp[ic]);
+ if(cp > 0) { $? ". a = %u", (unsigned)(cp - 1)
+ pa = &(sp[cp - 1]);
+ } else {
+ if(iscl) { $? ". a = %u", (unsigned)(np - 1)
+ pa = &(sp[np - 1]);
+ }
+ }
+ if(cp < (np - 2)) { $? ". d = %u", (unsigned)(cp + 2)
+ pd = &(sp[cp + 2]);
+ } else {
+ if(iscl) {
+ id = cp + 2;
+ while(id >= np) { id = id - np; } $? ". d = %u", (unsigned)id
+ pd = &(sp[id]);
+ }
+ }
+ xsss = dk3fig_tool_xssbs(drw, primary); $? ". xsss = %u", (unsigned)xsss
+ factor = 1.0 / (double)xsss;
+ dk3xsp_reset(&seg);
+ if(job->cosp) { dk3xsp_set_cb(&seg, 1); }
+ dk3xsp_set(&seg, pa, pb, pc, pd); $? ". dk3xsp_set"
+ if(dk3xsp_calculate(&seg, 0.0, 1)) { $? ". dk3xsp_calculate"
+ lastx = dk3xsp_get_x(&seg);
+ lasty = dk3xsp_get_y(&seg);
+ lastdxdt = dk3xsp_get_dxdt(&seg);
+ lastdydt = dk3xsp_get_dydt(&seg);
+ lastdxdt = (factor * lastdxdt) / 3.0;
+ lastdydt = (factor * lastdydt) / 3.0;
+ if(isfirst) { $? ". M %lg %lg", lastx, lasty
+ /* MOVETO lastx lasty */
+ fprintf(
+ job->of1, f2lsvg_c8_kw[56],
+ dk3ct_2d_x(&(job->ct2d), lastx, &mec),
+ dk3ct_2d_y(&(job->ct2d), lasty, &mec)
+ );
+ }
+ for(iseg = 0; iseg < xsss; iseg++) { $? ", iseg = %u", (unsigned)iseg
+ if(iseg < (xsss - 1)) {
+ t = (double)(iseg + 1) / (double)xsss;
+ } else {
+ t = 1.0;
+ } $? ". t = %lg", t
+ res = dk3xsp_calculate(&seg, t, 1); $? ". res = %d", res
+ if(!(res)) { mec = DK3_ERROR_MATH_OVERFLOW; }
+ x = dk3xsp_get_x(&seg);
+ y = dk3xsp_get_y(&seg);
+ dxdt = dk3xsp_get_dxdt(&seg);
+ dydt = dk3xsp_get_dydt(&seg);
+ dxdt = (factor * dxdt) / 3.0;
+ dydt = (factor * dydt) / 3.0; $? ". x=%lg y=%lg", x, y
+ fprintf(
+ job->of1, f2lsvg_c8_kw[57],
+ dk3ct_2d_x(&(job->ct2d), dk3ma_d_add_ok(lastx, lastdxdt, &mec), &mec),
+ dk3ct_2d_y(&(job->ct2d), dk3ma_d_add_ok(lasty, lastdydt, &mec), &mec),
+ dk3ct_2d_x(&(job->ct2d), dk3ma_d_sub_ok(x, dxdt, &mec), &mec),
+ dk3ct_2d_y(&(job->ct2d), dk3ma_d_sub_ok(y, dydt, &mec), &mec),
+ dk3ct_2d_x(&(job->ct2d), x, &mec),
+ dk3ct_2d_y(&(job->ct2d), y, &mec)
+ );
+ lastx = x; lasty = y; lastdxdt = dxdt; lastdydt = dydt;
+ if(iseg < (xsss - 1)) {
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ } else {
+ if(cp < (np - 1)) {
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ } else {
+ if(iscl) {
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ }
+ }
+ } $? ". end of for loop"
+ }
+ } else {
+ mec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ if(mec) { *ec = mec; }
+ $? "- f2lsvg_process_full_spline_segment"
+}
+
+
+
+/** Create path for the first partial X-spline segment from closed X-spline.
+ @param job Job structure.
+ @param drw Fig drawing.
+ @param obj Fig object.
+ @param sp Spline points array.
+ @param np Number of spline points.
+ @param i Current segment index.
+ @param ts Parameter t for start point.
+ @param isfirst Flag: First segment.
+ @param iscl Flag: Closed spline.
+ @param primary Flag: Primary (1=primary object, 0=arrowhead).
+ @param ec Pointer to error code variable, may be NULL.
+*/
+static
+void
+f2lsvg_first_spline_segment(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_spline_point_t *sp,
+ size_t np,
+ size_t i,
+ double ts,
+ int isfirst,
+ int iscl,
+ int primary,
+ int *ec
+)
+{
+ dk3_xspline_segment_t seg; /* Segment for caluclation. */
+ dk3_fig_spline_point_t *pa = NULL; /* Left neighbour. */
+ dk3_fig_spline_point_t *pb = NULL; /* Start. */
+ dk3_fig_spline_point_t *pc = NULL; /* End. */
+ dk3_fig_spline_point_t *pd = NULL; /* Right neighbour. */
+ double myts; /* t for start. */
+ double dnumsegs; /* Number of segments. */
+ double factor; /* Scale factor for deriv. */
+ double t; /* Current t. */
+ double x; /* Bezier end x. */
+ double y; /* Bezier end y. */
+ double dxdt; /* Bezier dx/dt at end. */
+ double dydt; /* Bezier dy/dt at end. */
+ double lastx = 0.0; /* Bezier start x. */
+ double lasty = 0.0; /* Bezier start y. */
+ double lastdxdt = 0.0; /* dx/dt at start. */
+ double lastdydt = 0.0; /* dy/dt at end. */
+ size_t nsegs; /* Number of segments. */
+ size_t iseg; /* Current segment. */
+ int res; /* Calculation result. */
+ $? "+ f2lud_first_spline_segment ts=%lg", ts
+ myts = dk3ma_d_sub_ok(ts, floor(ts), ec); $? ". myts = %lg", myts
+ dnumsegs = (1.0 - myts) * dk3fig_tool_xssbs(drw, primary);
+ dnumsegs = ceil(dnumsegs); $? ". dnumsegs = %lg", dnumsegs
+ nsegs = dk3ma_d_to_sz_ok(dnumsegs, ec); $? ". nsegs = %u", (unsigned)nsegs
+ pb = &(sp[i]);
+ pc = &(sp[i + 1]);
+ if(0 < i) {
+ pa = &(sp[i - 1]);
+ }
+ if(i < (np - 2)) {
+ pd = &(sp[i + 2]);
+ }
+ factor = (1.0 - myts) / (double)nsegs; $? ". factor = %lg", factor
+ dk3xsp_reset(&seg);
+ if(job->cosp) { dk3xsp_set_cb(&seg, 1); }
+ dk3xsp_set(&seg, pa, pb, pc, pd);
+ if(dk3xsp_calculate(&seg, myts, 1)) {
+ /* If necessary move to the start point.
+ */
+ lastx = dk3xsp_get_x(&seg);
+ lasty = dk3xsp_get_y(&seg);
+ lastdxdt = dk3xsp_get_dxdt(&seg);
+ lastdydt = dk3xsp_get_dydt(&seg);
+ lastdxdt = (factor * lastdxdt) / 3.0;
+ lastdydt = (factor * lastdydt) / 3.0;
+ if(isfirst) {
+ fprintf(
+ job->of1, f2lsvg_c8_kw[56],
+ dk3ct_2d_x(&(job->ct2d), lastx, ec),
+ dk3ct_2d_y(&(job->ct2d), lasty, ec)
+ );
+ }
+ if(1.0e-6 < (1.0 - myts)) {
+ for(iseg = 0; iseg < nsegs; iseg++) {
+ if(iseg < (nsegs - 1)) {
+ t = myts + (((1.0 - myts) * ((double)(iseg + 1))) / ((double)nsegs));
+ } else {
+ t = 1.0;
+ }
+ res = dk3xsp_calculate(&seg, t, 1);
+ if(!(res)) {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ x = dk3xsp_get_x(&seg);
+ y = dk3xsp_get_y(&seg);
+ dxdt = dk3xsp_get_dxdt(&seg);
+ dydt = dk3xsp_get_dydt(&seg);
+ dxdt = (factor * dxdt) / 3.0;
+ dydt = (factor * dydt) / 3.0;
+ fprintf(
+ job->of1, f2lsvg_c8_kw[57],
+ dk3ct_2d_x(&(job->ct2d), dk3ma_d_add_ok(lastx, lastdxdt, ec), ec),
+ dk3ct_2d_y(&(job->ct2d), dk3ma_d_add_ok(lasty, lastdydt, ec), ec),
+ dk3ct_2d_x(&(job->ct2d), dk3ma_d_sub_ok(x, dxdt, ec), ec),
+ dk3ct_2d_y(&(job->ct2d), dk3ma_d_sub_ok(y, dydt, ec), ec),
+ dk3ct_2d_x(&(job->ct2d), x, ec),
+ dk3ct_2d_y(&(job->ct2d), y, ec)
+ );
+ lastx = x; lasty = y; lastdxdt = dxdt; lastdydt = dydt;
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ }
+ } else {
+ res = dk3xsp_calculate(&seg, 1.0, 0);
+ if(!(res)) {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ /* ERROR: Math */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 36);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH); $? ". exitcode"
+ }
+ x = dk3xsp_get_x(&seg);
+ y = dk3xsp_get_y(&seg);
+ fprintf(
+ job->of1, f2lsvg_c8_kw[58],
+ dk3ct_2d_x(&(job->ct2d), x, ec),
+ dk3ct_2d_y(&(job->ct2d), y, ec)
+ );
+ }
+ } else {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH); $? ". exitcode"
+ }
+ $? "- f2lud_first_spline_segment"
+}
+
+
+
+/** Create path for the last partial X-spline segment from closed X-spline.
+ @param job Job structure.
+ @param drw Fig drawing.
+ @param obj Fig object.
+ @param sp Spline points array.
+ @param np Number of spline points.
+ @param i Current segment index.
+ @param te Parameter t for end point.
+ @param isfirst Flag: First segment.
+ @param iscl Flag: Closed spline.
+ @param primary Flag: Primary (1=primary object, 0=arrowhead).
+ @param ec Pointer to error code variable, may be NULL.
+*/
+static
+void
+f2lsvg_final_spline_segment(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_spline_point_t *sp,
+ size_t np,
+ size_t i,
+ double te,
+ int isfirst,
+ int iscl,
+ int primary,
+ int *ec
+)
+{
+ dk3_xspline_segment_t seg; /* Segment for caluclation. */
+ dk3_fig_spline_point_t *pa = NULL; /* Left neighbour. */
+ dk3_fig_spline_point_t *pb = NULL; /* Start. */
+ dk3_fig_spline_point_t *pc = NULL; /* End. */
+ dk3_fig_spline_point_t *pd = NULL; /* Right neighbour. */
+ double myte; /* t for end. */
+ double dnumsegs; /* Number of segments. */
+ double factor; /* Scale factor for deriv. */
+ double t; /* Current t. */
+ double x; /* Bezier end x. */
+ double y; /* Bezier end y. */
+ double dxdt; /* Bezier dx/dt at end. */
+ double dydt; /* Bezier dy/dt at end. */
+ double lastx = 0.0; /* Bezier start x. */
+ double lasty = 0.0; /* Bezier start y. */
+ double lastdxdt = 0.0; /* dx/dt at start. */
+ double lastdydt = 0.0; /* dy/dt at end. */
+ size_t nsegs; /* Number of segments. */
+ size_t iseg; /* Current segment. */
+ int res; /* Calculation result. */
+ $? "+ f2lud_final_spline_segment %lg", te
+ myte = dk3ma_d_sub_ok(te, floor(te), ec); $? ". myte = %lg", myte
+ dnumsegs = myte * dk3fig_tool_xssbs(drw, primary);
+ dnumsegs = ceil(dnumsegs); $? ". dnumsegs = %lg", dnumsegs
+ nsegs = dk3ma_d_to_sz_ok(dnumsegs, ec); $? ". nsegs = %u", (unsigned)nsegs
+ pb = &(sp[i]);
+ pc = &(sp[i + 1]);
+ if(0 < i) {
+ pa = &(sp[i - 1]);
+ }
+ if(i < (np - 2)) {
+ pd = &(sp[i + 2]);
+ }
+ factor = myte / (double)nsegs; $? ". factor = %lg", factor
+ dk3xsp_reset(&seg);
+ if(job->cosp) { dk3xsp_set_cb(&seg, 1); }
+ dk3xsp_set(&seg, pa, pb, pc, pd);
+ if(dk3xsp_calculate(&seg, 0.0, 1)) {
+ lastx = dk3xsp_get_x(&seg);
+ lasty = dk3xsp_get_y(&seg);
+ lastdxdt = dk3xsp_get_dxdt(&seg);
+ lastdydt = dk3xsp_get_dydt(&seg);
+ lastdxdt = (factor * lastdxdt) / 3.0;
+ lastdydt = (factor * lastdydt) / 3.0;
+ /* Move to start point.
+ */
+ if(isfirst) {
+ fprintf(
+ job->of1, f2lsvg_c8_kw[56],
+ dk3ct_2d_x(&(job->ct2d), lastx, ec),
+ dk3ct_2d_y(&(job->ct2d), lasty, ec)
+ );
+ }
+ /* Further curve only if te > 1.0e-6.
+ For smaller te draw straight line.
+ */
+ if(1.0e-6 < myte) { $? ". segments size ok"
+ for(iseg = 0; iseg < nsegs; iseg++) {
+ if(iseg < (nsegs - 1)) { $? ". not last sub-segment"
+ t = (double)(iseg + 1) / (double)nsegs;
+ t = t * myte;
+ } else { $? ". last sub-segment"
+ t = myte;
+ } $? ". t = %lg", t
+ res = dk3xsp_calculate(&seg, t, 1);
+ if(!(res)) {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ x = dk3xsp_get_x(&seg);
+ y = dk3xsp_get_y(&seg);
+ dxdt = dk3xsp_get_dxdt(&seg);
+ dydt = dk3xsp_get_dydt(&seg);
+ dxdt = (factor * dxdt) / 3.0;
+ dydt = (factor * dydt) / 3.0;
+ fprintf(
+ job->of1, f2lsvg_c8_kw[57],
+ dk3ct_2d_x(&(job->ct2d), dk3ma_d_add_ok(lastx, lastdxdt, ec), ec),
+ dk3ct_2d_y(&(job->ct2d), dk3ma_d_add_ok(lasty, lastdydt, ec), ec),
+ dk3ct_2d_x(&(job->ct2d), dk3ma_d_sub_ok(x, dxdt, ec), ec),
+ dk3ct_2d_y(&(job->ct2d), dk3ma_d_sub_ok(y, dydt, ec), ec),
+ dk3ct_2d_x(&(job->ct2d), x, ec),
+ dk3ct_2d_y(&(job->ct2d), y, ec)
+ );
+ lastx = x; lasty = y; lastdxdt = dxdt; lastdydt = dydt;
+ if(iseg < (nsegs - 1)) {
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ }
+ }
+ } else { $? ". very small segment"
+ res = dk3xsp_calculate(&seg, myte, 0);
+ if(!(res)) {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ /* ERROR: Math */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 36);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH); $? ". exitcode"
+ }
+ x = dk3xsp_get_x(&seg);
+ y = dk3xsp_get_y(&seg);
+ fprintf(
+ job->of1, f2lsvg_c8_kw[58],
+ dk3ct_2d_x(&(job->ct2d), x, ec),
+ dk3ct_2d_y(&(job->ct2d), y, ec)
+ );
+ }
+ } else {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH); $? ". exitcode"
+ }
+ $? "- f2lud_final_spline_segment"
+}
+
+
+
+/** Create path for the single partial X-spline segment cutted on both ends
+ from closed X-spline.
+ @param job Job structure.
+ @param drw Fig drawing.
+ @param obj Fig object.
+ @param sp Spline points array.
+ @param np Number of spline points.
+ @param i Current segment index.
+ @param ts Parameter t for start point.
+ @param te Parameter t for end point.
+ @param isfirst Flag: First segment.
+ @param iscl Flag: Closed spline.
+ @param primary Flag: Primary (1=primary object, 0=arrowhead).
+ @param ec Pointer to error code variable, may be NULL.
+*/
+static
+void
+f2lsvg_single_spline_segment(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_spline_point_t *sp,
+ size_t np,
+ size_t i,
+ double ts,
+ double te,
+ int isfirst,
+ int iscl,
+ int primary,
+ int *ec
+)
+{
+ dk3_xspline_segment_t seg; /* Segment for caluclation. */
+ dk3_fig_spline_point_t *pa = NULL; /* Left neighbour. */
+ dk3_fig_spline_point_t *pb = NULL; /* Start. */
+ dk3_fig_spline_point_t *pc = NULL; /* End. */
+ dk3_fig_spline_point_t *pd = NULL; /* Right neighbour. */
+ double myte; /* t for end. */
+ double myts; /* t for start. */
+ double dnumsegs; /* Number of segments. */
+ double factor; /* Scale factor for deriv. */
+ double t; /* Current t. */
+ double x; /* Bezier end x. */
+ double y; /* Bezier end y. */
+ double dxdt; /* Bezier dx/dt at end. */
+ double dydt; /* Bezier dy/dt at end. */
+ double lastx = 0.0; /* Bezier start x. */
+ double lasty = 0.0; /* Bezier start y. */
+ double lastdxdt = 0.0; /* dx/dt at start. */
+ double lastdydt = 0.0; /* dy/dt at end. */
+ size_t nsegs; /* Number of segments. */
+ size_t iseg; /* Current segment. */
+ int res; /* Calculation result. */
+ $? "+ f2lud_single_spline_segment"
+ myte = dk3ma_d_sub_ok(te, floor(te), ec);
+ myts = dk3ma_d_sub_ok(ts, floor(ts), ec);
+ dnumsegs = (myte - myts) * dk3fig_tool_xssbs(drw, primary);
+ dnumsegs = ceil(dnumsegs);
+ nsegs = dk3ma_d_to_sz_ok(dnumsegs, ec);
+ pb = &(sp[i]);
+ pc = &(sp[i + 1]);
+ if(0 < i) {
+ pa = &(sp[i - 1]);
+ }
+ if(i < (np - 2)) {
+ pd = &(sp[i + 2]);
+ }
+ factor = (myte - myts) / ((double)nsegs);
+ dk3xsp_reset(&seg);
+ if(job->cosp) { dk3xsp_set_cb(&seg, 1); }
+ dk3xsp_set(&seg, pa, pb, pc, pd);
+ if(dk3xsp_calculate(&seg, myts, 1)) {
+ lastx = dk3xsp_get_x(&seg);
+ lasty = dk3xsp_get_y(&seg);
+ lastdxdt = dk3xsp_get_dxdt(&seg);
+ lastdydt = dk3xsp_get_dydt(&seg);
+ lastdxdt = (factor * lastdxdt) / 3.0;
+ lastdydt = (factor * lastdydt) / 3.0;
+ if(isfirst) {
+ fprintf(
+ job->of1, f2lsvg_c8_kw[56],
+ dk3ct_2d_x(&(job->ct2d), lastx, ec),
+ dk3ct_2d_y(&(job->ct2d), lasty, ec)
+ );
+ }
+ if(1.0e-6 < (myte - myts)) {
+ for(iseg = 0; iseg < nsegs; iseg++) {
+ if(iseg < (nsegs - 1)) {
+ t = myts + (((myte - myts) * ((double)(iseg + 1))) / ((double)nsegs));
+ } else {
+ t = myte;
+ }
+ res = dk3xsp_calculate(&seg, t, 1);
+ if(!(res)) {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ x = dk3xsp_get_x(&seg);
+ y = dk3xsp_get_y(&seg);
+ dxdt = dk3xsp_get_dxdt(&seg);
+ dydt = dk3xsp_get_dydt(&seg);
+ dxdt = (factor * dxdt) / 3.0;
+ dydt = (factor * dydt) / 3.0;
+ fprintf(
+ job->of1, f2lsvg_c8_kw[57],
+ dk3ct_2d_x(&(job->ct2d), dk3ma_d_add_ok(lastx, lastdxdt, ec), ec),
+ dk3ct_2d_y(&(job->ct2d), dk3ma_d_add_ok(lasty, lastdydt, ec), ec),
+ dk3ct_2d_x(&(job->ct2d), dk3ma_d_sub_ok(x, dxdt, ec), ec),
+ dk3ct_2d_y(&(job->ct2d), dk3ma_d_sub_ok(y, dydt, ec), ec),
+ dk3ct_2d_x(&(job->ct2d), x, ec),
+ dk3ct_2d_y(&(job->ct2d), y, ec)
+ );
+ lastx = x; lasty = y; lastdxdt = dxdt; lastdydt = dydt;
+ if(iseg < (nsegs - 1)) {
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ }
+ }
+ } else {
+ res = dk3xsp_calculate(&seg, myte, 0);
+ if(!(res)) {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ /* ERROR: Calculation failed! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 36);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH); $? ". exitcode"
+ }
+ x = dk3xsp_get_x(&seg);
+ y = dk3xsp_get_y(&seg);
+ fprintf(
+ job->of1, f2lsvg_c8_kw[58],
+ dk3ct_2d_x(&(job->ct2d), x, ec),
+ dk3ct_2d_y(&(job->ct2d), y, ec)
+ );
+ }
+ } else {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ /* ERROR: Calculation failed! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 36);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH); $? ". exitcode"
+ }
+ $? "- f2lud_single_spline_segment"
+}
+
+
+
+/** Process open spline object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param primary Flag: Primary object (1=object, 0=arrowhead).
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_open_spline(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+ dk3_fig_spline_point_t *sp;
+ size_t np;
+ size_t i;
+ size_t min;
+ size_t max;
+
+ sp = (obj->dt).spl.po;
+ np = (obj->dt).spl.np;
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 54);
+ fputs(f2lsvg_c8_kw[55], job->of1);
+ if(job->coah) {
+ for(i = 0; i < (np - 1); i++) {
+ f2lsvg_process_full_spline_segment(
+ job, drw, obj, sp, np, i, ((0 == i) ? 1 : 0), 0, primary, ec
+ );
+ }
+ } else {
+ if(obj->ab) { $? ". have backward arrow"
+ /* 2013-11-23
+ ROUNDING DOWNWARDS INTENDED.
+ We want to find the start segment.
+ */
+ min = dk3ma_d_to_sz_ok(floor((obj->dt).spl.ts), ec);
+ if(obj->af) { $? ". have forward arrow"
+ if((obj->dt).spl.te >= (obj->dt).spl.ts) {
+ /* 2013-11-23
+ ROUNDING DOWNWARDS INTENDED.
+ We want to find the last full segment to draw.
+ */
+ max = dk3ma_d_to_sz_ok(floor((obj->dt).spl.te), ec);
+ if(max > min) {
+ f2lsvg_first_spline_segment(
+ job, drw, obj, sp, np, min, (obj->dt).spl.ts, 1, 0, primary, ec
+ );
+ for(i = (min + 1); i < max; i++) {
+ f2lsvg_process_full_spline_segment(
+ job, drw, obj, sp, np, i, 0, 0, primary, ec
+ );
+ }
+ f2lsvg_final_spline_segment(
+ job, drw, obj, sp, np, max, (obj->dt).spl.te, 0, 0, primary, ec
+ );
+ } else {
+ f2lsvg_single_spline_segment(
+ job, drw, obj, sp, np, min, (obj->dt).spl.ts, (obj->dt).spl.te,
+ 1, 0, primary, ec
+ );
+ }
+ } else {
+ /* ERROR: Arrowheads in summary too long for spline */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 37);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYNTAX); $? ". exitcode"
+ }
+ } else { $? ". no forward arrow"
+ f2lsvg_first_spline_segment(
+ job, drw, obj, sp, np, min, (obj->dt).spl.ts, 1, 0, primary, ec
+ );
+ for(i = (min + 1); i < (np - 1); i++) {
+ f2lsvg_process_full_spline_segment(
+ job, drw, obj, sp, np, i, 0, 0, primary, ec
+ );
+ }
+ }
+ } else { $? ". no backward arrow"
+ if(obj->af) { $? ". have forward arrow"
+ /* 2013-11-23
+ ROUNDING DOWNWARDS INTENDED.
+ We want to find the last full segment to draw.
+ */
+ max = dk3ma_d_to_sz_ok(floor((obj->dt).spl.te), ec);
+ if(max < (np - 1)) {
+ if(max > 0) {
+ for(i = 0; i < max; i++) {
+ f2lsvg_process_full_spline_segment(
+ job, drw, obj, sp, np, i, ((0 == i) ? 1 : 0), 0, primary, ec
+ );
+ }
+ f2lsvg_final_spline_segment(
+ job, drw, obj, sp, np, max, (obj->dt).spl.te, 0, 0, primary, ec
+ );
+ } else {
+ f2lsvg_final_spline_segment(
+ job, drw, obj, sp, np, max, (obj->dt).spl.te, 1, 0, primary, ec
+ );
+ }
+ } else {
+ /* ERROR: Illegal max value! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 39);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN); $? ". exitcode"
+ }
+ } else { $? ". no forward arrow"
+ for(i = 0; i < (np - 1); i++) {
+ f2lsvg_process_full_spline_segment(
+ job, drw, obj, sp, np, i, ((0 == i) ? 1 : 0), 0, primary, ec
+ );
+ }
+ }
+ }
+ }
+ fputs(f2lsvg_c8_kw[42], job->of1);
+ f2lsvgst_write_style_for_object(job, drw, psvg, obj);
+ fputs(f2lsvg_c8_kw[36], job->of1);
+}
+
+
+
+/** Process fast open spline object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_fast_open_spline(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ dk3_fig_spline_point_t *po;
+ double dxdtb;
+ double dydtb;
+ double dxdtc;
+ double dydtc;
+ size_t np;
+ size_t ib;
+ size_t ic;
+ $? "+ f2lsvg_process_fast_open_spline %lu", obj->li
+ po = (obj->dt).spl.po;
+ np = (obj->dt).spl.np;
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 54);
+ fputs(f2lsvg_c8_kw[55], job->of1);
+ if (1 < np) {
+ for (ib = 0; ib < (np - 1); ib++) {
+ ic = ib + 1;
+ if (0 == ib) {
+ /* MOVETO */
+ fprintf(
+ job->of1, f2lsvg_c8_kw[56],
+ dk3ct_2d_x(&(job->ct2d), po[ib].x, ec),
+ dk3ct_2d_y(&(job->ct2d), po[ib].y, ec)
+ );
+ }
+ if ((fabs(po[ib].s) < 1.0e-6) && (fabs(po[ic].s) < 1.0e-6)) {
+ /* LINETO */
+ fprintf(
+ job->of1, f2lsvg_c8_kw[58],
+ dk3ct_2d_x(&(job->ct2d), po[ib].x, ec),
+ dk3ct_2d_y(&(job->ct2d), po[ib].y, ec)
+ );
+ } else {
+ dxdtb = dxdtc = dk3ma_d_sub_ok(po[ic].x, po[ib].x, ec);
+ dydtb = dydtc = dk3ma_d_sub_ok(po[ic].y, po[ib].y, ec);
+ if ((0 < ib) && (fabs(1.0 + po[ib].s) < 1.0e-6)) {
+ dxdtb = f2lpara_derived_center(po[ib-1].x, po[ib].x, po[ic].x, ec);
+ dydtb = f2lpara_derived_center(po[ib-1].y, po[ib].y, po[ic].y, ec);
+ } else {
+ if ((ic < (np - 1)) && (fabs(1.0 + po[ic].s) < 1.0e-6)) {
+ dxdtb = f2lpara_derived_left(po[ib].x, po[ic].x, po[ic+1].x, ec);
+ dydtb = f2lpara_derived_left(po[ib].y, po[ic].y, po[ic+1].y, ec);
+ }
+ }
+ if ((ic < (np - 1)) && (fabs(1.0 + po[ic].s) < 1.0e-6)) {
+ dxdtc = f2lpara_derived_center(po[ib].x, po[ic].x, po[ic+1].x, ec);
+ dydtc = f2lpara_derived_center(po[ib].y, po[ic].y, po[ic+1].y, ec);
+ } else {
+ if ((0 < ib) && (fabs(1.0 + po[ib].s) < 1.0e-6)) {
+ dxdtc = f2lpara_derived_right(po[ib-1].x, po[ib].x, po[ic].x, ec);
+ dydtc = f2lpara_derived_right(po[ib-1].y, po[ib].y, po[ic].y, ec);
+ }
+ }
+ /* CURVETO */
+ fprintf(
+ job->of1, f2lsvg_c8_kw[57],
+ dk3ct_2d_x(
+ &(job->ct2d),
+ dk3ma_d_add_ok(po[ib].x, (dxdtb / 3.0), ec),
+ ec
+ ),
+ dk3ct_2d_y(
+ &(job->ct2d),
+ dk3ma_d_add_ok(po[ib].y, (dydtb / 3.0), ec),
+ ec
+ ),
+ dk3ct_2d_x(
+ &(job->ct2d),
+ dk3ma_d_sub_ok(po[ic].x, (dxdtc / 3.0), ec),
+ ec
+ ),
+ dk3ct_2d_y(
+ &(job->ct2d),
+ dk3ma_d_sub_ok(po[ic].y, (dydtc / 3.0), ec),
+ ec
+ ),
+ dk3ct_2d_x( &(job->ct2d), po[ic].x, ec),
+ dk3ct_2d_y( &(job->ct2d), po[ic].y, ec)
+ );
+ }
+ }
+ } else {
+ /* Too few points in X-spline */
+ }
+ fputs(f2lsvg_c8_kw[42], job->of1);
+ f2lsvgst_write_style_for_object(job, drw, psvg, obj);
+ fputs(f2lsvg_c8_kw[36], job->of1);
+ $? "- f2lsvg_process_fast_open_spline"
+}
+
+
+
+/** Process closed spline object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param primary Flag: Primary object (1=object, 0=arrowhead).
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_closed_spline(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+ dk3_fig_spline_point_t *sp;
+ size_t np;
+ size_t i;
+
+ sp = (obj->dt).spl.po;
+ np = (obj->dt).spl.np;
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 54);
+ fputs(f2lsvg_c8_kw[55], job->of1);
+ for(i = 0; i < np; i++) {
+ f2lsvg_process_full_spline_segment(
+ job, drw, obj, sp, np, i, ((0 == i) ? 1 : 0), 1, primary, ec
+ );
+ }
+ fputs(f2lsvg_c8_kw[59], job->of1);
+ fputs(f2lsvg_c8_kw[42], job->of1);
+ f2lsvgst_write_style_for_object(job, drw, psvg, obj);
+ fputs(f2lsvg_c8_kw[36], job->of1);
+}
+
+
+
+/** Process fast closed spline object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_fast_closed_spline(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ dk3_fig_spline_point_t *po;
+ double dxdtb;
+ double dydtb;
+ double dxdtc;
+ double dydtc;
+ size_t np;
+ size_t ia;
+ size_t ib;
+ size_t ic;
+ size_t id;
+
+ $? "+ f2lsvg_process_fast_closed_spline %lu", obj->li
+ po = (obj->dt).spl.po;
+ np = (obj->dt).spl.np;
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 54);
+ fputs(f2lsvg_c8_kw[55], job->of1);
+ if (2 < np) {
+ for (ib = 0; ib < np; ib++) {
+ ic = ib + 1;
+ id = ib + 2;
+ if (ic >= np) { ic = ic - np; }
+ if (id >= np) { id = id - np; }
+ if (0 < ib) {
+ ia = ib - 1;
+ } else {
+ ia = np - 1;
+ }
+ if (0 == ib) {
+ /* MOVETO */
+ fprintf(
+ job->of1, f2lsvg_c8_kw[56],
+ dk3ct_2d_x(&(job->ct2d), po[ib].x, ec),
+ dk3ct_2d_y(&(job->ct2d), po[ib].y, ec)
+ );
+ }
+ if ((fabs(po[ib].s) < 1.0e-6) && (fabs(po[ic].s) < 1.0e-6)) {
+ /* LINETO */
+ fprintf(
+ job->of1, f2lsvg_c8_kw[58],
+ dk3ct_2d_x(&(job->ct2d), po[ib].x, ec),
+ dk3ct_2d_y(&(job->ct2d), po[ib].y, ec)
+ );
+ } else {
+ dxdtb = dxdtc = dk3ma_d_sub_ok(po[ic].x, po[ib].x, ec);
+ dydtb = dydtc = dk3ma_d_sub_ok(po[ic].y, po[ib].y, ec);
+ if (fabs(1.0 + po[ib].s) < 1.0e-6) {
+ dxdtb = f2lpara_derived_center(po[ia].x, po[ib].x, po[ic].x, ec);
+ dydtb = f2lpara_derived_center(po[ia].y, po[ib].y, po[ic].y, ec);
+ } else {
+ if (fabs(1.0 + po[ic].s) < 1.0e-6) {
+ dxdtb = f2lpara_derived_left(po[ib].x, po[ic].x, po[id].x, ec);
+ dydtb = f2lpara_derived_left(po[ib].y, po[ic].y, po[id].y, ec);
+ }
+ }
+ if (fabs(1.0 + po[ic].s) < 1.0e-6) {
+ dxdtc = f2lpara_derived_center(po[ib].x, po[ic].x, po[id].x, ec);
+ dydtc = f2lpara_derived_center(po[ib].y, po[ic].y, po[id].y, ec);
+ } else {
+ if (fabs(1.0 + po[ib].s) < 1.0e-6) {
+ dxdtc = f2lpara_derived_right(po[ia].x, po[ib].x, po[ic].x, ec);
+ dydtc = f2lpara_derived_right(po[ia].y, po[ib].y, po[ic].y, ec);
+ }
+ }
+ /* CURVETO */
+ fprintf(
+ job->of1, f2lsvg_c8_kw[57],
+ dk3ct_2d_x(
+ &(job->ct2d),
+ dk3ma_d_add_ok(po[ib].x, (dxdtb / 3.0), ec),
+ ec
+ ),
+ dk3ct_2d_y(
+ &(job->ct2d),
+ dk3ma_d_add_ok(po[ib].y, (dydtb / 3.0), ec),
+ ec
+ ),
+ dk3ct_2d_x(
+ &(job->ct2d),
+ dk3ma_d_sub_ok(po[ic].x, (dxdtc / 3.0), ec),
+ ec
+ ),
+ dk3ct_2d_y(
+ &(job->ct2d),
+ dk3ma_d_sub_ok(po[ic].y, (dydtc / 3.0), ec),
+ ec
+ ),
+ dk3ct_2d_x( &(job->ct2d), po[ic].x, ec),
+ dk3ct_2d_y( &(job->ct2d), po[ic].y, ec)
+ );
+ }
+ }
+ } else {
+ /* ERROR: Too few points */
+ }
+ fputs(f2lsvg_c8_kw[59], job->of1);
+ fputs(f2lsvg_c8_kw[42], job->of1);
+ f2lsvgst_write_style_for_object(job, drw, psvg, obj);
+ fputs(f2lsvg_c8_kw[36], job->of1);
+ $? "- f2lsvg_process_fast_closed_spline"
+}
+
+
+
+/** Process spline object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param primary Flag: Primary object (1=object, 0=arrowhead).
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_spline(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+ switch(obj->st) {
+ case 1: case 3: case 5: { /* closed spline */
+ f2lsvg_process_closed_spline(job, drw, psvg, obj, primary, ec);
+ } break;
+ default: { /* open spline */
+ f2lsvg_process_open_spline(job, drw, psvg, obj, primary, ec);
+ } break;
+ }
+}
+
+
+
+/** Process text object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_text(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ double rotation = 0.0; /* Rotation in degree. */
+ double irot = 0.0; /* Rotation as integer. */
+ double x; /* Text x position. */
+ double y; /* Text y position. */
+ int isRotated = 0; /* Flag: Text is rotated. */
+ int mec = 0; /* Mathematical error code. */
+
+ if(!(DK3_FIG_FONT_FLAG_HIDDEN & ((obj->dt).txt.ff))) {
+ rotation = (obj->dt).txt.an;
+ if(1.0e-6 < fabs(rotation)) {
+ isRotated = 1;
+ rotation = dk3ma_d_mul_ok(180.0, (rotation / M_PI), &mec);
+ irot = dk3ma_d_rint(rotation);
+ if(fabs(dk3ma_d_sub_ok(rotation, irot, &mec)) < 1.0e-3) {
+ rotation = irot;
+ }
+ rotation = -1.0 * rotation;
+ }
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 50);
+ x = dk3ct_2d_x(&(job->ct2d), (obj->dt).txt.x, &mec);
+ y = dk3ct_2d_y(&(job->ct2d), (obj->dt).txt.y, &mec);
+ if(isRotated) {
+ fprintf(job->of1, f2lsvg_c8_kw[53], x, y, rotation);
+ } else {
+ fprintf(job->of1, f2lsvg_c8_kw[52], x, y);
+ }
+ f2lsvgst_write_style_for_object(job, drw, psvg, obj);
+ fputs(f2lsvg_c8_kw[51], job->of1);
+ if((obj->dt).txt.st) {
+#if VERSION_BEFORE_2013_11_10
+ fputs((obj->dt).txt.st, job->of1);
+#else
+ f2lsvg_fputs_translate((obj->dt).txt.st, job->of1);
+#endif
+ }
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ fputs(f2lsvg_c8_kw[8], job->of1);
+ f2lsvg_tag_name(job, 50);
+ fputs(f2lsvg_c8_kw[5], job->of1);
+ if(mec) { *ec = mec; }
+ if(DK3_FIG_FONT_FLAG_SPECIAL & ((obj->dt).txt.ff)) {
+ /* WARNING: Special text was found! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 44);
+ }
+ }
+}
+
+
+
+/** Process arc object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_arc(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ double sx; /* Start x. */
+ double sy; /* Start y. */
+ double cx; /* Center x. */
+ double cy; /* Center y. */
+ double r; /* Radius. */
+ double as; /* Arc start angle in radians. */
+ double ae; /* Arc end angle in radians. */
+ double lastx; /* Segment start x. */
+ double lasty; /* Segment start y. */
+ double lastkdxdt; /* X difference to first control. */
+ double lastkdydt; /* Y difference to first control. */
+ double x; /* Segment end x. */
+ double y; /* Segment end y. */
+ double kdxdt; /* X difference to last control. */
+ double kdydt; /* Y difference to last control. */
+ double dnumsegs; /* Number of segments. */
+ double alpha; /* Arc angle in radians. */
+ double alphaseg; /* Segment angle in radians. */
+ double kappa; /* Factor for derivative. */
+ double alphaend; /* Segment end angle in radians. */
+ size_t nsegs; /* Number of segments. */
+ size_t i; /* Index of current segment. */
+
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 54);
+ fputs(f2lsvg_c8_kw[55], job->of1);
+
+ cx = (obj->dt).arc.xc;
+ cy = (obj->dt).arc.yc;
+ r = (obj->dt).arc.ra;
+ if((obj->dt).arc.as < (obj->dt).arc.ae) {
+ as = (obj->dt).arc.as;
+ ae = (obj->dt).arc.ae;
+ } else {
+ as = (obj->dt).arc.ae;
+ ae = (obj->dt).arc.as;
+ }
+ alpha = dk3ma_d_sub_ok(ae, as, ec);
+ dnumsegs = ceil(dk3ma_d_mul_ok(4.0, (alpha / M_PI), ec));
+ nsegs = dk3ma_d_to_sz_ok(dnumsegs, ec);
+ alphaseg = alpha / ((double)nsegs);
+ kappa = dk3fig_tool_arc_kappa(alphaseg, ec);
+ sx = lastx = dk3ma_d_add_ok(cx, (r * cos(as)), ec);
+ sy = lasty = dk3ma_d_add_ok(cy, (r * sin(as)), ec);
+ fprintf(
+ job->of1, f2lsvg_c8_kw[56],
+ dk3ct_2d_x(&(job->ct2d), lastx, ec),
+ dk3ct_2d_y(&(job->ct2d), lasty, ec)
+ );
+ lastkdxdt = dk3ma_d_mul_ok(
+ kappa,
+ (-1.0 * dk3ma_d_mul_ok(r, alphaseg, ec) * sin(as)),
+ ec
+ );
+ lastkdydt = dk3ma_d_mul_ok(
+ kappa,
+ (dk3ma_d_mul_ok(r, alphaseg, ec) * cos(as)),
+ ec
+ );
+ for(i = 0; i < nsegs; i++) {
+ if(i < (nsegs - 1)) {
+ alphaend = dk3ma_d_add_ok(
+ as,
+ dk3ma_d_mul_ok(dk3ma_d_add_ok(1.0, (double)i, ec), alphaseg, ec),
+ ec
+ );
+ } else {
+ alphaend = ae;
+ }
+ x = dk3ma_d_add_ok(cx, (r * cos(alphaend)), ec);
+ y = dk3ma_d_add_ok(cy, (r * sin(alphaend)), ec);
+ kdxdt = dk3ma_d_mul_ok(
+ kappa,
+ (-1.0 * dk3ma_d_mul_ok(r, alphaseg, ec) * sin(alphaend)),
+ ec
+ );
+ kdydt = dk3ma_d_mul_ok(
+ kappa,
+ (dk3ma_d_mul_ok(r, alphaseg, ec) * cos(alphaend)),
+ ec
+ );
+ fprintf(
+ job->of1, f2lsvg_c8_kw[57],
+ dk3ct_2d_x(&(job->ct2d), dk3ma_d_add_ok(lastx, lastkdxdt, ec), ec),
+ dk3ct_2d_y(&(job->ct2d), dk3ma_d_add_ok(lasty, lastkdydt, ec), ec),
+ dk3ct_2d_x(&(job->ct2d), dk3ma_d_sub_ok(x, kdxdt, ec), ec),
+ dk3ct_2d_y(&(job->ct2d), dk3ma_d_sub_ok(y, kdydt, ec), ec),
+ dk3ct_2d_x(&(job->ct2d), x, ec),
+ dk3ct_2d_y(&(job->ct2d), y, ec)
+ );
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ lastx = x; lasty = y; lastkdxdt = kdxdt; lastkdydt = kdydt;
+ }
+ /* For closed arc draw the lines.
+ */
+ if(1 != obj->st) {
+ fprintf(
+ job->of1, f2lsvg_c8_kw[58],
+ dk3ct_2d_x(&(job->ct2d), cx, ec),
+ dk3ct_2d_y(&(job->ct2d), cy, ec)
+ );
+ fprintf(
+ job->of1, f2lsvg_c8_kw[58],
+ dk3ct_2d_x(&(job->ct2d), sx, ec),
+ dk3ct_2d_y(&(job->ct2d), sy, ec)
+ );
+ fputs(f2lsvg_c8_kw[59], job->of1);
+ }
+ fputs(f2lsvg_c8_kw[42], job->of1);
+ f2lsvgst_write_style_for_object(job, drw, psvg, obj);
+ fputs(f2lsvg_c8_kw[36], job->of1);
+}
+
+
+
+/** Process half-circle object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_half_circle(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ dk3_fig_poly_point_t po[7];
+ size_t i; /* Traverse po. */
+ int mec = 0; /* Mathematical error code. */
+ $? "+ f2lsvg_process_half_circle"
+ po[0].x = 0.0;
+ po[0].y = (obj->dt).hci.ra;
+ po[1].x = -1.0 * FIG2LAT_CIRCLE_QUADRANT_BEZIER * (obj->dt).hci.ra;
+ po[1].y = (obj->dt).hci.ra;
+ po[2].x = -1.0 * (obj->dt).hci.ra;
+ po[2].y = FIG2LAT_CIRCLE_QUADRANT_BEZIER * (obj->dt).hci.ra;
+ po[3].x = -1.0 * (obj->dt).hci.ra;
+ po[3].y = 0.0;
+ po[4].x = -1.0 * (obj->dt).hci.ra;
+ po[4].y = -1.0 * FIG2LAT_CIRCLE_QUADRANT_BEZIER * (obj->dt).hci.ra;
+ po[5].x = -1.0 * FIG2LAT_CIRCLE_QUADRANT_BEZIER * (obj->dt).hci.ra;
+ po[5].y = -1.0 * (obj->dt).hci.ra;
+ po[6].x = 0.0;
+ po[6].y = -1.0 * (obj->dt).hci.ra;
+ if(1.0e-6 < fabs((obj->dt).hci.an)) {
+ for(i = 0; i < 7; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), (obj->dt).hci.an, &mec);
+ }
+ }
+ for(i = 0; i < 7; i++) {
+ dk3fig_tool_shift_point(&(po[i]), (obj->dt).hci.cx, (obj->dt).hci.cy, &mec);
+ }
+ for(i = 0; i < 7; i++) {
+ po[i].x = dk3ct_2d_x(&(job->ct2d), po[i].x, &mec);
+ po[i].y = dk3ct_2d_y(&(job->ct2d), po[i].y, &mec);
+ }
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 54);
+ fputs(f2lsvg_c8_kw[55], job->of1);
+ fprintf(job->of1, f2lsvg_c8_kw[56], po[0].x, po[0].y);
+ fprintf(
+ job->of1, f2lsvg_c8_kw[57],
+ po[1].x, po[1].y, po[2].x, po[2].y, po[3].x, po[3].y
+ );
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ fprintf(
+ job->of1, f2lsvg_c8_kw[57],
+ po[4].x, po[4].y, po[5].x, po[5].y, po[6].x, po[6].y
+ );
+ if(obj->st) {
+ fputs(f2lsvg_c8_kw[0], job->of1);
+ fprintf(job->of1, f2lsvg_c8_kw[58], po[0].x, po[0].y);
+ fputs(f2lsvg_c8_kw[59], job->of1);
+ }
+ fputs(f2lsvg_c8_kw[42], job->of1);
+ f2lsvgst_write_style_for_object(job, drw, psvg, obj);
+ fputs(f2lsvg_c8_kw[36], job->of1);
+ if(mec) { *ec = mec; }
+ $? "- f2lsvg_process_half_circle"
+}
+
+
+
+/** Process object and arrowheads.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param primary Flag: primary (1=primary object, 0=arrowhead).
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_one(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+ int op;
+ $? "+ f2lsvg_process_one type=%d primary=%d", obj->ot, primary
+ op = dk3fig_tool_get_operation(drw, obj); $? ". op = %d", op
+ switch(obj->ot) {
+ case DK3_FIG_OBJ_ELLIPSE: {
+ if(op) { f2lsvg_process_ellipse(job, drw, psvg, obj, ec); }
+ } break;
+ case DK3_FIG_OBJ_POLYLINE: {
+ if(op) {f2lsvg_process_polyline(job, drw, psvg, obj, primary, ec); }
+ } break;
+ case DK3_FIG_OBJ_SPLINE: {
+ if(op) {f2lsvg_process_spline(job, drw, psvg, obj, primary, ec); }
+ } break;
+ case DK3_FIG_OBJ_TEXT: {
+ f2lsvg_process_text(job, drw, psvg, obj, ec);
+ } break;
+ case DK3_FIG_OBJ_ARC: {
+ if(op) {f2lsvg_process_arc(job, drw, psvg, obj, ec); }
+ } break;
+ case DK3_FIG_OBJ_PSEUDO_HALF_CIRCLE: { $? ". half-circle %d", op
+ if(op) {f2lsvg_process_half_circle(job, drw, psvg, obj, ec); }
+ } break;
+ case DK3_FIG_OBJ_PSEUDO_FAST_SPLINE: {
+ if(op) {
+ /* f2lsvg_process_spline(job, drw, psvg, obj, primary, ec); */
+ switch(obj->st) {
+ case 1: case 3: case 5: {
+ f2lsvg_process_fast_closed_spline(job, drw, psvg, obj, ec);
+ } break;
+ default: {
+ f2lsvg_process_fast_open_spline(job, drw, psvg, obj, ec);
+ } break;
+ }
+ }
+ } break;
+ }
+ $? "- f2lsvg_process_one"
+}
+
+
+
+/** Check whether we must use a g instruction to group
+ the object with its arrowheads.
+ @param job Job structure.
+ @param obj Current object to process.
+ @return 1 to group, 0 for no group.
+*/
+static
+int
+f2lsvg_check_must_group(f2l_job_t *job, dk3_fig_obj_t *obj)
+{
+ int back = 0;
+ $? "+ f2lsvg_check_must_group"
+ if(job->group) { $? ". grouping required"
+ if(obj->af) { $? ". forward arrowhead"
+ if((obj->af)->o1) { $? ". object found"
+ back = 1;
+ }
+ if((obj->af)->o2) { $? ". object found"
+ back = 1;
+ }
+ }
+ if(obj->ab) { $? ". backward arrowhead"
+ if((obj->ab)->o1) { $? ". object found"
+ back = 1;
+ }
+ if((obj->ab)->o2) { $? ". object found"
+ back = 1;
+ }
+ }
+ } $? "- f2lsvg_check_must_group %d", back
+ return back;
+}
+
+
+
+/** Process arrowhead object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param obj Current object to process.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lsvg_process_ah_one(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ switch (obj->ot) {
+ case DK3_FIG_OBJ_SPLINE: {
+ if ((!(job->xsah)) && (f2lud_is_interpolated_spline(obj))) {
+ obj->ot = DK3_FIG_OBJ_PSEUDO_FAST_SPLINE;
+ f2lsvg_process_one(job, drw, psvg, obj, 0, ec);
+ obj->ot = DK3_FIG_OBJ_SPLINE;
+ } else {
+ f2lsvg_process_one(job, drw, psvg, obj, 0, ec);
+ }
+ } break;
+ default: {
+ f2lsvg_process_one(job, drw, psvg, obj, 0, ec);
+ } break;
+ }
+}
+
+
+
+/** Process object and arrowheads.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+static
+void
+f2lsvg_process_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ f2l_svg_t *psvg; /* SVG style collection. */
+ int mg; /* Flag: Must group */
+ int mec = 0; /* Mathematical error code. */
+
+ $? "+ f2lsvg_process_object"
+ psvg = (f2l_svg_t *)(drw->dsd);
+ mg = f2lsvg_check_must_group(job, obj);
+ /*
+ Process object itself.
+ */
+ if(mg) {
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ f2lsvg_tag_name(job, 35);
+ fputs(f2lsvg_c8_kw[5], job->of1);
+ }
+ $? ". START OBJECT"
+ f2lsvg_process_one(job, drw, psvg, obj, 1, &mec);
+ /*
+ Process arrowheads.
+ */
+ if(obj->af) { $? ". forward arrowhead"
+ if((obj->af)->o1) { $? ". forward o1"
+#if VERSION_BEFORE_20140329
+ f2lsvg_process_one(job,drw,psvg,(dk3_fig_obj_t *)((obj->af)->o1),0,&mec);
+#else
+ f2lsvg_process_ah_one(job,drw,psvg,(dk3_fig_obj_t *)((obj->af)->o1),&mec);
+#endif
+ }
+ if((obj->af)->o2) { $? ". forward o2"
+#if VERSION_BEFORE_20140329
+ f2lsvg_process_one(job,drw,psvg,(dk3_fig_obj_t *)((obj->af)->o2),0,&mec);
+#else
+ f2lsvg_process_ah_one(job,drw,psvg,(dk3_fig_obj_t *)((obj->af)->o2),&mec);
+#endif
+ } $? ". forward arrowhead finished"
+ }
+ if(obj->ab) { $? ". backward arrowhead"
+ if((obj->ab)->o1) { $? ". backward o1"
+#if VERSION_BEFORE_20140329
+ f2lsvg_process_one(job,drw,psvg,(dk3_fig_obj_t *)((obj->ab)->o1),0,&mec);
+#else
+ f2lsvg_process_ah_one(job,drw,psvg,(dk3_fig_obj_t *)((obj->ab)->o1),&mec);
+#endif
+ }
+ if((obj->ab)->o2) { $? ". backward o2"
+#if VERSION_BEFORE_20140329
+ f2lsvg_process_one(job,drw,psvg,(dk3_fig_obj_t *)((obj->ab)->o2),0,&mec);
+#else
+ f2lsvg_process_ah_one(job,drw,psvg,(dk3_fig_obj_t *)((obj->ab)->o2),&mec);
+#endif
+ } $? ". backward arrowhead finished"
+ }
+ $? ". END OBJECT"
+ if(mg) {
+ fputs(f2lsvg_c8_kw[6], job->of1);
+ fputs(f2lsvg_c8_kw[8], job->of1);
+ f2lsvg_tag_name(job, 35);
+ fputs(f2lsvg_c8_kw[5], job->of1);
+ }
+ if(mec) {
+ /* ERROR: Mathematical error occured. */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 38);
+ job->exval = FIG2LAT_EXIT_ERROR_MATH; $? ". exitcode"
+ }
+ $? "- f2lsvg_process_object"
+}
+
+
+
+void
+f2lsvg_output(f2l_job_t *job)
+{
+ dk3_fig_drawing_t *drw;
+ dk3_fig_obj_t *obj;
+ unsigned long objno = 0UL;
+ unsigned long oldsrcline = 0UL;
+ $? "+ f2lsvg_output"
+ oldsrcline = dk3app_get_source_line(job->app);
+ dk3app_set_source_line(job->app, 0UL);
+ drw = job->drw; objno = 0UL;
+ if(f2lsvg_driver_initialize(job, drw)) {
+ if(f2lsvg_open_output_files(job)) {
+ if(f2lsvg_start_processing(job, drw)) {
+ dk3sto_it_reset(drw->iobj);
+ while(NULL != (obj = (dk3_fig_obj_t *)dk3sto_it_next(drw->iobj))) {
+ dk3app_set_source_line(job->app, obj->li);
+ if(!dk3fig_tool_is_bgrect(obj, objno)) {
+ f2lsvg_process_object(job, drw, obj);
+ }
+ objno++;
+ }
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN); $? ". exitcode"
+ }
+ f2lsvg_end_processing(job, drw);
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN); $? ". exitcode"
+ }
+ f2lsvg_close_output_files(job);
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN); $? ". exitcode"
+ }
+ dk3app_set_source_line(job->app, oldsrcline);
+ $? "- f2lsvg_output"
+ f2lsvg_driver_end(job, drw);
+}
+
diff --git a/support/dktools/f2lsvg.h b/support/dktools/f2lsvg.h
new file mode 100644
index 0000000000..8b7b81478a
--- /dev/null
+++ b/support/dktools/f2lsvg.h
@@ -0,0 +1,63 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: f2lsvg.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file f2lsvg.h Header file for the f2lsvg module.
+*/
+
+#ifndef F2LSVG_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define F2LSVG_H_INCLUDED 1
+
+
+#line 10 "f2lsvg.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Produce output.
+ @param job Job structure.
+*/
+void
+f2lsvg_output(f2l_job_t *job);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/f2lsvgst.c b/support/dktools/f2lsvgst.c
new file mode 100644
index 0000000000..df5f40d422
--- /dev/null
+++ b/support/dktools/f2lsvgst.c
@@ -0,0 +1,3412 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: f2lsvgst.ctr
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file f2lsvgst.c The f2lsvgst module.
+*/
+
+
+#line 410 "f2lsvgst.ctr"
+
+#include "f2lsvgst.h"
+
+
+
+
+
+#line 416 "f2lsvgst.ctr"
+
+
+
+/** Keywords used by the module.
+*/
+static char const * const f2lsvgst_c8_kw[] = {
+/* 0 */
+"\n",
+
+/* 1 */
+"svg:",
+
+/* 2 */
+"<",
+
+/* 3 */
+"pattern",
+
+/* 4 */
+"/",
+
+/* 5 */
+">",
+
+/* 6 */
+"<",
+
+/* 7 */
+" id=\"",
+
+/* 8 */
+"p",
+
+/* 9 */
+"\" x=\"0\" y=\"0\" width=\"%g\" height=\"%g\"\npatternUnits=\"userSpaceOnUse\"\n>\n",
+
+/* 10 */
+"rect",
+
+/* 11 */
+" x=\"0\" y=\"0\" width=\"%g\" height=\"%g\"\n",
+
+/* 12 */
+"style=\"fill: #%02X%02X%02X; stroke: none;\"\n",
+
+/* 13 */
+"/>\n",
+
+/* 14 */
+" style=\"stroke: none; fill: #%02X%02X%02X;\"\n",
+
+/* 15 */
+"points=\"0,0 0.9,0 7.2,3.64 7.2,4.16 6.3,4.16 0,0.52\"",
+
+/* 16 */
+"points=\"0,3.64 0.9,4.16 0,4.16\"",
+
+/* 17 */
+"points=\"6.3,0 7.2,0.52 7.2,0\"",
+
+/* 18 */
+"polyline",
+
+/* 19 */
+"points=\"0,4.16 0.9,4.16 7.2,0.52 7.2,0 6.3,0 0,3.64\"",
+
+/* 20 */
+"points=\"0,0.52 0.9,0 0,0\"",
+
+/* 21 */
+"points=\"6.3,4.16 7.2,4.16 7.2,3.64\"",
+
+/* 22 */
+"style=\"fill: none; stroke: #%02X%02X%02X; stroke-width: 0.9; stroke-linecap: round;\"",
+
+/* 23 */
+"points=\"0,0 7.2,4.16\"",
+
+/* 24 */
+"points=\"0,4.16 7.2,0\"",
+
+/* 25 */
+"points=\"0,0 0.64,0 10.18,9.54 10.18,10.18 9.54,10.18 0,0.64\"",
+
+/* 26 */
+"points=\"0,9.54 0.64,10.18 0,10.18\"",
+
+/* 27 */
+"points=\"9.54,0 10.18,0.64 10.18,0\"",
+
+/* 28 */
+"points=\"0,10.18 0.64,10.18 10.18,0.64 10.18,0 9.54,0 0,9.54\"",
+
+/* 29 */
+"points=\"0,0.64 0.64,0 0,0\"",
+
+/* 30 */
+"points=\"9.54,10.18 10.18,10.18 10.18,9.54\"",
+
+/* 31 */
+"points=\"0,0 10.18,10.18\"",
+
+/* 32 */
+"points=\"0,10.18 10.18,0\"",
+
+/* 33 */
+"points=\"3.6,0 3.6,7.2\"",
+
+/* 34 */
+"points=\"18,0 18,7.2\"",
+
+/* 35 */
+"points=\"10.8,7.2 10.8,14.4\"",
+
+/* 36 */
+"points=\"25.2,7.2 25.2,14.4\"",
+
+/* 37 */
+"points=\"0,0 28.8,0\"",
+
+/* 38 */
+"points=\"0,14.4 28.8,14.4\"",
+
+/* 39 */
+"points=\"0,7.2 28.8,7.2\"",
+
+/* 40 */
+"points=\"0,3.6 7.2,3.6\"",
+
+/* 41 */
+"points=\"0,18 7.2,18\"",
+
+/* 42 */
+"points=\"7.2,10.8 14.4,10.8\"",
+
+/* 43 */
+"points=\"7.2,25.2 14.4,25.2\"",
+
+/* 44 */
+"points=\"0,0 0,28.8\"",
+
+/* 45 */
+"points=\"7.2,0 7.2,28.8\"",
+
+/* 46 */
+"points=\"14.4,0 14.4,28.8\"",
+
+/* 47 */
+"points=\"0,0 3.6,0\"",
+
+/* 48 */
+"points=\"0,3.6 3.6,3.6\"",
+
+/* 49 */
+"points=\"0,0 0,3.6\"",
+
+/* 50 */
+"points=\"3.6,0 3.6,3.6\"",
+
+/* 51 */
+"polygon",
+
+/* 52 */
+"points=\"0,0 0,3.6 3.6,3.6 3.6,0\"",
+
+/* 53 */
+"points=\"0.45,7.2 3.15,0\"",
+
+/* 54 */
+"points=\"4.05,14.4 6.75,7.2\"",
+
+/* 55 */
+"points=\"7.65,21.6 10.35,14.4\"",
+
+/* 56 */
+"points=\"11.25,28.8 13.95,21.6\"",
+
+/* 57 */
+"points=\"0,0 14.4,0\"",
+
+/* 58 */
+"points=\"0,7.2 14.4,7.2\"",
+
+/* 59 */
+"points=\"0,14.4 14.4,14.4\"",
+
+/* 60 */
+"points=\"0,21.6 14.4,21.6\"",
+
+/* 61 */
+"points=\"0,28.8 14.4,28.8\"",
+
+/* 62 */
+"points=\"0,0 3.6,7.2\"",
+
+/* 63 */
+"points=\"10.8,7.2 14.4,14.4\"",
+
+/* 64 */
+"points=\"7.2,14.4 10.8,21.6\"",
+
+/* 65 */
+"points=\"3.6,21.6 7.2,28.8\"",
+
+/* 66 */
+"points=\"0,0 14.4,0\"",
+
+/* 67 */
+"points=\"0,7.2 14.4,7.2\"",
+
+/* 68 */
+"points=\"0,14.4 14.4,14.4\"",
+
+/* 69 */
+"points=\"0,21.6 14.4,21.6\"",
+
+/* 70 */
+"points=\"0,28.8 14.4,28.8\"",
+
+/* 71 */
+"points=\"0,10.8 7.2,14.4\"",
+
+/* 72 */
+"points=\"7.2,7.2 14.4,10.8\"",
+
+/* 73 */
+"points=\"14.4,3.6 21.6,7.2\"",
+
+/* 74 */
+"points=\"21.6,0 28.8,3.6\"",
+
+/* 75 */
+"points=\"0,0 0,14.4\"",
+
+/* 76 */
+"points=\"7.2,0 7.2,14.4\"",
+
+/* 77 */
+"points=\"14.4,0 14.4,14.4\"",
+
+/* 78 */
+"points=\"21.6,0 21.6,14.4\"",
+
+/* 79 */
+"points=\"28.8,0 28.8,14.4\"",
+
+/* 80 */
+"points=\"0,14.4 7.2,10.8\"",
+
+/* 81 */
+"points=\"7.2,3.6 14.4,0\"",
+
+/* 82 */
+"points=\"14.4,7.2 21.6,3.6\"",
+
+/* 83 */
+"points=\"21.6,10.8 28.8,7.2\"",
+
+/* 84 */
+"points=\"0,0 0,14.4\"",
+
+/* 85 */
+"points=\"7.2,0 7.2,14.4\"",
+
+/* 86 */
+"points=\"14.4,0 14.4,14.4\"",
+
+/* 87 */
+"points=\"21.6,0 21.6,14.4\"",
+
+/* 88 */
+"points=\"28.8,0 28.8,14.4\"",
+
+/* 89 */
+"path",
+
+/* 90 */
+"d=\"M0,0A9 9 0 0 0 14.54,0\"",
+
+/* 91 */
+"d=\"M0,7.4A9 9 0 0 0 7.27,3.7\"",
+
+/* 92 */
+"d=\"M7.27,3.7A9 9 0 0 0 14.54,7.4\"",
+
+/* 93 */
+"d=\"M0,0A9 9 0 0 0 7.27,-3.7\"",
+
+/* 94 */
+"d=\"M7.27,-3.7A9 9 0 0 0 14.54,0\"",
+
+/* 95 */
+"d=\"M0,0A3.6 3.6 0 0 0 7.2,0\"",
+
+/* 96 */
+"d=\"M0,7.2A3.6 3.6 0 0 0 3.6,3.6\"",
+
+/* 97 */
+"d=\"M3.6,3.6A3.6 3.6 0 0 0 7.2,7.2\"",
+
+/* 98 */
+"d=\"M0,0A3.6 3.6 0 0 0 3.6,-3.6\"",
+
+/* 99 */
+"d=\"M3.6,-3.6A3.6 3.6 0 0 0 7.2,0\"",
+
+/* 100 */
+"circle",
+
+/* 101 */
+"style=\"fill: none; stroke: #%02X%02X%02X; stroke-width: 0.9;\"",
+
+/* 102 */
+" cx=\"7.2\" cy=\"7.2\" r=\"7.2\"",
+
+/* 103 */
+"points=\"3.6,0 0,6.24 3.6,12.47 10.8,12.47 14.4,6.24 10.8,0\"",
+
+/* 104 */
+"points=\"14.4,6.24 21.6,6.24\"",
+
+/* 105 */
+"points=\"21.6,6.24 25.2,0\"",
+
+/* 106 */
+"points=\"21.6,6.24 25.2,12.47\"",
+
+/* 107 */
+"points=\"0,4.22 4.22,0 10.18,0 14.4,4.22",
+
+/* 108 */
+"14.4,10.18 10.18,14.4 4.22,14.4 0,10.18\"",
+
+/* 109 */
+"points=\"0,1.8 3.6,5.4 7.2,1.8\"",
+
+/* 110 */
+"points=\"1.8,0 5.4,3.6 1.8,7.2\"",
+
+/* 111 */
+"s",
+
+/* 112 */
+".",
+
+/* 113 */
+" {\n",
+
+/* 114 */
+"}\n",
+
+/* 115 */
+"font-family: \"",
+
+/* 116 */
+"\",serif;\n",
+
+/* 117 */
+"\",sans-serif;\n",
+
+/* 118 */
+"\",monospace;\n",
+
+/* 119 */
+"font-style: normal;\n",
+
+/* 120 */
+"font-style: italic;\n",
+
+/* 121 */
+"font-style: oblique;\n",
+
+/* 122 */
+"font-weight: %d;\n",
+
+/* 123 */
+"font-family: serif;\n",
+
+/* 124 */
+"font-family: sans-serif;\n",
+
+/* 125 */
+"font-family: monospace;\n",
+
+/* 126 */
+"font-style: normal;\n",
+
+/* 127 */
+"font-style: italic;\n",
+
+/* 128 */
+"font-weight: normal;\n",
+
+/* 129 */
+"font-weight: bold;\n",
+
+/* 130 */
+"font-size: %gpt;\n",
+
+/* 131 */
+"text-anchor: start;\n",
+
+/* 132 */
+"text-anchor: middle;\n",
+
+/* 133 */
+"text-anchor: end;\n",
+
+/* 134 */
+"fill: url(#",
+
+/* 135 */
+");\nfillrule: evenodd;\n",
+
+/* 136 */
+"fill: #%02X%02X%02X;\nfillrule: evenodd;\n",
+
+/* 137 */
+"fill: none;\n",
+
+/* 138 */
+"stroke: #%02X%02X%02X;\n",
+
+/* 139 */
+"stroke-width: %g;\n",
+
+/* 140 */
+"stroke-linecap: square;\n",
+
+/* 141 */
+"stroke-linecap: round;\n",
+
+/* 142 */
+"stroke-linecap: butt;\n",
+
+/* 143 */
+"stroke-linejoin: bevel;\n",
+
+/* 144 */
+"stroke-linejoin: round;\n",
+
+/* 145 */
+"stroke-linejoin: miter;\n",
+
+/* 146 */
+"stroke-dasharray: ",
+
+/* 147 */
+";\n",
+
+/* 148 */
+"none",
+
+/* 149 */
+"%g,%g",
+
+/* 150 */
+"%g,%g,%g,%g",
+
+/* 151 */
+"%g,%g,%g,%g,%g,%g",
+
+/* 152 */
+"%g,%g,%g,%g,%g,%g,%g,%g",
+
+/* 153 */
+"font-family=\"'",
+
+/* 154 */
+"',serif\"\n",
+
+/* 155 */
+"',sans-serif\"\n",
+
+/* 156 */
+"',monospace\"\n",
+
+/* 157 */
+"font-style=\"oblique\"\n",
+
+/* 158 */
+"font-style=\"italic\"\n",
+
+/* 159 */
+"font-weight=\"%d\"\n",
+
+/* 160 */
+"font-size=\"%gpt\"\n",
+
+/* 161 */
+"font-family=\"serif\"\n",
+
+/* 162 */
+"font-family=\"sans-serif\"\n",
+
+/* 163 */
+"font-family=\"monospace\"\n",
+
+/* 164 */
+"font-weight=\"bold\"\n",
+
+/* 165 */
+"text-anchor=\"middle\"\n",
+
+/* 166 */
+"text-anchor=\"end\"\n",
+
+/* 167 */
+"fill=\"url(#",
+
+/* 168 */
+")\"\n",
+
+/* 169 */
+"fill=\"#%02X%02X%02X\"\n",
+
+/* 170 */
+"fill=\"none\"\n",
+
+/* 171 */
+"stroke=\"#%02X%02X%02X\"\n",
+
+/* 172 */
+"stroke-width=\"%g\"\n",
+
+/* 173 */
+"stroke-dasharray=\"%g,%g\"\n",
+
+/* 174 */
+"stroke-dasharray=\"%g,%g,%g,%g\"\n",
+
+/* 175 */
+"stroke-dasharray=\"%g,%g,%g,%g,%g,%g\"\n",
+
+/* 176 */
+"stroke-dasharray=\"%g,%g,%g,%g,%g,%g,%g,%g\"\n",
+
+/* 177 */
+"stroke-linecap=\"square\"\n",
+
+/* 178 */
+"stroke-linecap=\"round\"\n",
+
+/* 179 */
+"stroke-linejoin=\"bevel\"\n",
+
+/* 180 */
+"stroke-linejoin=\"round\"\n",
+
+/* 181 */
+"class=\"",
+
+/* 182 */
+"\"\n",
+
+/* 183 */
+"fill: #%02X%02X%02X;\n",
+
+/* 184 */
+"fill=\"#%02X%02X%02X\"\nfillrule=\"evenodd\"\n",
+
+/* 185 */
+"stroke-miterlimit: 20;\n",
+
+/* 186 */
+"stroke-miterlimit=\"20\"\n",
+
+/* 187 */
+"\",\"",
+
+/* 188 */
+"','",
+
+NULL
+
+
+#line 889 "f2lsvgst.ctr"
+};
+
+
+
+/** Compare two integer values.
+ @param x Left value.
+ @param y Right value.
+ @return Comparison result.
+*/
+int
+f2lsvgst_compare_int(int x, int y)
+{
+ int back = 0;
+
+
+#line 903 "f2lsvgst.ctr"
+ if(x > y) {
+ back = 1;
+ } else {
+ if(x < y) {
+ back = -1;
+ }
+ }
+
+#line 910 "f2lsvgst.ctr"
+ return back;
+}
+
+
+
+int
+f2lsvgst_compare_pattern(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ f2l_svg_fill_pattern_t const *pl;
+ f2l_svg_fill_pattern_t const *pr;
+ if(l) {
+ if(r) {
+ pl = (f2l_svg_fill_pattern_t const *)l;
+ pr = (f2l_svg_fill_pattern_t const *)r;
+ back = f2lsvgst_compare_int(pl->fn, pr->fn);
+ if(0 == back) {
+ back = f2lsvgst_compare_int(pl->sr, pr->sr);
+ if(0 == back) {
+ back = f2lsvgst_compare_int(pl->sg, pr->sg);
+ if(0 == back) {
+ back = f2lsvgst_compare_int(pl->sb, pr->sb);
+ if(0 == back) {
+ back = f2lsvgst_compare_int(pl->fr, pr->fr);
+ if(0 == back) {
+ back = f2lsvgst_compare_int(pl->fg, pr->fg);
+ if(0 == back) {
+ back = f2lsvgst_compare_int(pl->fb, pr->fb);
+ }
+ }
+ }
+ }
+ }
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+int
+f2lsvgst_compare_object_styles(void const *l, void const *r, int cr)
+{
+ f2l_svg_style_t const *pl;
+ f2l_svg_style_t const *pr;
+ int back = 0;
+
+
+#line 960 "f2lsvgst.ctr"
+ if(l) {
+ if(r) {
+ pl = (f2l_svg_style_t const *)l;
+ pr = (f2l_svg_style_t const *)r;
+ /* Stroke color.
+ */
+
+#line 966 "f2lsvgst.ctr"
+ if((pl->flags) & DK3_SVG_FLAGS_COLOR_STROKE) {
+ if((pr->flags) & DK3_SVG_FLAGS_COLOR_STROKE) {
+ back = f2lsvgst_compare_int(pl->sr, pr->sr);
+
+
+#line 970 "f2lsvgst.ctr"
+ if(0 == back) {
+ back = f2lsvgst_compare_int(pl->sg, pr->sg);
+
+
+#line 973 "f2lsvgst.ctr"
+ if(0 == back) {
+ back = f2lsvgst_compare_int(pl->sb, pr->sb);
+
+
+#line 976 "f2lsvgst.ctr"
+ }
+ }
+ } else {
+ back = 1;
+
+#line 980 "f2lsvgst.ctr"
+ }
+ } else {
+ if((pr->flags) & DK3_SVG_FLAGS_COLOR_STROKE) {
+ back = -1;
+
+#line 984 "f2lsvgst.ctr"
+ }
+ }
+ /* Line width.
+ */
+ if(0 == back) {
+
+#line 989 "f2lsvgst.ctr"
+ if((pl->flags) & DK3_SVG_FLAGS_LINEWIDTH) {
+ if((pr->flags) & DK3_SVG_FLAGS_LINEWIDTH) {
+ if(pl->lw > (pr->lw + 1.0e-6)) {
+ back = 1;
+
+#line 993 "f2lsvgst.ctr"
+ } else {
+ if(pr->lw > (pl->lw + 1.0e-6)) {
+ back = -1;
+
+#line 996 "f2lsvgst.ctr"
+ }
+ }
+ } else {
+ back = 1;
+
+#line 1000 "f2lsvgst.ctr"
+ }
+ } else {
+ if((pr->flags) & DK3_SVG_FLAGS_LINEWIDTH) {
+ back = -1;
+
+#line 1004 "f2lsvgst.ctr"
+ }
+ }
+ }
+ /* Line cap.
+ */
+ if(0 == back) {
+
+#line 1010 "f2lsvgst.ctr"
+ if((pl->flags) & DK3_SVG_FLAGS_LINE_CAP) {
+ if((pr->flags) & DK3_SVG_FLAGS_LINE_CAP) {
+ back = f2lsvgst_compare_int(pl->lc, pr->lc);
+
+
+#line 1014 "f2lsvgst.ctr"
+ } else {
+ back = 1;
+
+#line 1016 "f2lsvgst.ctr"
+ }
+ } else {
+ if((pr->flags) & DK3_SVG_FLAGS_LINE_CAP) {
+ back = -1;
+
+#line 1020 "f2lsvgst.ctr"
+ }
+ }
+ }
+ /* Line join.
+ */
+ if(0 == back) {
+
+#line 1026 "f2lsvgst.ctr"
+ if((pl->flags) & DK3_SVG_FLAGS_LINE_JOIN) {
+ if((pr->flags) & DK3_SVG_FLAGS_LINE_JOIN) {
+ back = f2lsvgst_compare_int(pl->lj, pr->lj);
+
+
+#line 1030 "f2lsvgst.ctr"
+ } else {
+ back = 1;
+
+#line 1032 "f2lsvgst.ctr"
+ }
+ } else {
+ if((pr->flags) & DK3_SVG_FLAGS_LINE_JOIN) {
+ back = -1;
+
+#line 1036 "f2lsvgst.ctr"
+ }
+ }
+ }
+ /* Line style.
+ */
+ if(0 == back) {
+
+#line 1042 "f2lsvgst.ctr"
+ if((pl->flags) & DK3_SVG_FLAGS_LINESTYLE) {
+ if((pr->flags) & DK3_SVG_FLAGS_LINESTYLE) {
+ if(pl->ls > pr->ls) {
+ back = 1;
+
+#line 1046 "f2lsvgst.ctr"
+ } else {
+ if(pr->ls > pl->ls) {
+ back = -1;
+
+#line 1049 "f2lsvgst.ctr"
+ } else {
+ if((0 != pl->ls) && (0 != pr->ls)) {
+ if(pl->lsv > (pr->lsv + 1.0e-6)) {
+ back = 1;
+
+#line 1053 "f2lsvgst.ctr"
+ } else {
+ if(pr->lsv > (pl->lsv + 1.0e-6)) {
+ back = -1;
+
+#line 1056 "f2lsvgst.ctr"
+ }
+ }
+ }
+ }
+ }
+ } else {
+ back = 1;
+
+#line 1063 "f2lsvgst.ctr"
+ }
+ } else {
+ if((pr->flags) & DK3_SVG_FLAGS_LINESTYLE) {
+ back = -1;
+
+#line 1067 "f2lsvgst.ctr"
+ }
+ }
+ }
+ /* Fill pattern or fill color.
+ */
+ if(0 == back) {
+
+#line 1073 "f2lsvgst.ctr"
+ if(pl->fp) {
+ if(pr->fp) {
+ back =
+ f2lsvgst_compare_pattern((void *)(pl->fp),(void *)(pr->fp),0);
+
+
+#line 1078 "f2lsvgst.ctr"
+ } else {
+ back = 1;
+
+#line 1080 "f2lsvgst.ctr"
+ }
+ } else {
+ if(pr->fp) {
+ back = -1;
+
+#line 1084 "f2lsvgst.ctr"
+ }
+ else {
+ /* Fill color only if both objects do not have fill patterns.
+ */
+ if(0 == back) {
+ if((pl->flags) & DK3_SVG_FLAGS_COLOR_FILL) {
+ if((pr->flags) & DK3_SVG_FLAGS_COLOR_FILL) {
+ back = f2lsvgst_compare_int(pl->fr, pr->fr);
+
+
+#line 1093 "f2lsvgst.ctr"
+ if(0 == back) {
+ back = f2lsvgst_compare_int(pl->fg, pr->fg);
+
+
+#line 1096 "f2lsvgst.ctr"
+ if(0 == back) {
+ back = f2lsvgst_compare_int(pl->fb, pr->fb);
+
+
+#line 1099 "f2lsvgst.ctr"
+ }
+ }
+ } else {
+ back = 1;
+
+#line 1103 "f2lsvgst.ctr"
+ }
+ } else {
+ if((pr->flags) & DK3_SVG_FLAGS_COLOR_FILL) {
+ back = -1;
+
+#line 1107 "f2lsvgst.ctr"
+ }
+ }
+ }
+ }
+ }
+ }
+ /* Font.
+ */
+ if(0 == back) {
+
+#line 1116 "f2lsvgst.ctr"
+ if((pl->flags) & DK3_SVG_FLAGS_FONT) {
+ if((pr->flags) & DK3_SVG_FLAGS_FONT) {
+ if((pl->flags) & DK3_SVG_FLAGS_PS_FONT) {
+ if((pr->flags) & DK3_SVG_FLAGS_PS_FONT) {
+ back = f2lsvgst_compare_int(pl->tf, pr->tf);
+
+
+#line 1122 "f2lsvgst.ctr"
+ if(0 == back) {
+ if(pl->ts > (pr->ts + 1.0e-6)) {
+ back = 1;
+
+#line 1125 "f2lsvgst.ctr"
+ } else {
+ if(pl->ts < (pr->ts - 1.0e-6)) {
+ back = -1;
+
+#line 1128 "f2lsvgst.ctr"
+ }
+ }
+ }
+ } else {
+ back = 1;
+
+#line 1133 "f2lsvgst.ctr"
+ }
+ } else {
+ if((pr->flags) & DK3_SVG_FLAGS_PS_FONT) {
+ back = -1;
+
+#line 1137 "f2lsvgst.ctr"
+ } else {
+ back = f2lsvgst_compare_int(pl->tf, pr->tf);
+
+
+#line 1140 "f2lsvgst.ctr"
+ if(0 == back) {
+ if(pl->ts > (pr->ts + 1.0e-6)) {
+ back = 1;
+
+#line 1143 "f2lsvgst.ctr"
+ } else {
+ if(pl->ts < (pr->ts - 1.0e-6)) {
+ back = -1;
+
+#line 1146 "f2lsvgst.ctr"
+ }
+ }
+ }
+ }
+ }
+ } else {
+ back = 1;
+
+#line 1153 "f2lsvgst.ctr"
+ }
+ } else {
+ if((pr->flags) & DK3_SVG_FLAGS_FONT) {
+ back = -1;
+
+#line 1157 "f2lsvgst.ctr"
+ }
+ }
+ }
+ /* Text align.
+ */
+ if(0 == back) {
+
+#line 1163 "f2lsvgst.ctr"
+ if((pl->flags) & DK3_SVG_FLAGS_TEXT_ALIGN) {
+ if((pr->flags) & DK3_SVG_FLAGS_TEXT_ALIGN) {
+ back = f2lsvgst_compare_int(pl->al, pr->al);
+
+
+#line 1167 "f2lsvgst.ctr"
+ } else {
+ back = 1;
+
+#line 1169 "f2lsvgst.ctr"
+ }
+ } else {
+ if((pr->flags) & DK3_SVG_FLAGS_TEXT_ALIGN) {
+ back = -1;
+
+#line 1173 "f2lsvgst.ctr"
+ }
+ }
+ }
+ } else {
+
+#line 1177 "f2lsvgst.ctr"
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+
+#line 1182 "f2lsvgst.ctr"
+ }
+ }
+
+#line 1184 "f2lsvgst.ctr"
+ return back;
+}
+
+
+
+void
+f2lsvgst_pattern_delete(f2l_svg_fill_pattern_t *pa)
+{
+
+
+#line 1193 "f2lsvgst.ctr"
+ if(pa) {
+
+
+#line 1195 "f2lsvgst.ctr"
+ }
+ dk3_delete(pa);
+
+
+#line 1198 "f2lsvgst.ctr"
+}
+
+
+
+f2l_svg_fill_pattern_t *
+f2lsvgst_pattern_new(f2l_svg_t *psvg)
+{
+ f2l_svg_fill_pattern_t *back = NULL;
+
+
+#line 1207 "f2lsvgst.ctr"
+ if(psvg) {
+ back = dk3_new(f2l_svg_fill_pattern_t,1);
+ if(back) {
+ back->pn = 0UL;
+ back->fn = 0;
+ back->sr = 0; back->sg = 0; back->sb = 0;
+ back->fr = 0; back->fg = 0; back->fb = 0;
+ } else {
+ psvg->ec = DK3_ERROR_MEMORY;
+ }
+ }
+
+#line 1218 "f2lsvgst.ctr"
+ return back;
+}
+
+
+
+void
+f2lsvgst_style_initialize(f2l_svg_style_t *st)
+{
+
+
+#line 1227 "f2lsvgst.ctr"
+ if(st) {
+ /* 2013-01-25: Same order as in typedef makes completeness checking easier.
+ */
+ st->fp = NULL;
+ st->ts = 0.0;
+ st->lw = 0.0;
+ st->lsv = 0.0;
+ st->sn = 0UL;
+ st->tf = 0;
+ st->flags = 0;
+ st->sr = 0; st->sg = 0; st->sb = 0;
+ st->fr = 0; st->fg = 0; st->fb = 0;
+ st->ls = 0;
+ st->al = 0;
+ st->lc = 0;
+ st->lj = 0;
+ }
+
+#line 1244 "f2lsvgst.ctr"
+}
+
+
+#if 0
+/** Report style contents.
+ @param pst SVG style to report.
+*/
+static
+void
+f2lsvgst_style_report(f2l_svg_style_t *pst)
+{
+ FILE *tf;
+ tf = dktrace_file();
+ if(tf) {
+ if((pst->flags) & DK3_SVG_FLAGS_COLOR_STROKE) {
+ fprintf(tf, "Stroke: #%02X%02X%02X\n", pst->sr, pst->sg, pst->sb);
+ }
+ if((pst->flags) & DK3_SVG_FLAGS_LINEWIDTH) {
+ fprintf(tf, "Line width: %g\n", pst->lw);
+ }
+ if((pst->flags) & DK3_SVG_FLAGS_LINESTYLE) {
+ fprintf(tf, "Line style: %d %g\n", pst->ls, pst->lsv);
+ }
+ if((pst->flags) & DK3_SVG_FLAGS_LINE_CAP) {
+ fprintf(tf, "Line cap: %d\n", pst->lc);
+ }
+ if((pst->flags) & DK3_SVG_FLAGS_LINE_JOIN) {
+ fprintf(tf, "Line join: %d\n", pst->lj);
+ }
+ if(pst->fp) {
+ fprintf(tf, "Fill: pattern\n");
+ } else {
+ if((pst->flags) & DK3_SVG_FLAGS_COLOR_FILL) {
+ fprintf(tf, "Fill: #%02X%02X%02X", pst->fr, pst->fg, pst->fb);
+ }
+ }
+ if((pst->flags) & DK3_SVG_FLAGS_FONT) {
+ fprintf(tf, "Font: PS=%d NUMBER=%d SIZE=%g\n", (((pst->flags) & DK3_SVG_FLAGS_PS_FONT) ? 1 : 0), pst->tf, pst->ts);
+ }
+ if((pst->flags) & DK3_SVG_FLAGS_TEXT_ALIGN) {
+ fprintf(tf, "Text align: %d\n", pst->al);
+ }
+ }
+}
+#endif
+
+
+void
+f2lsvgst_style_delete(f2l_svg_style_t *st)
+{
+
+
+#line 1295 "f2lsvgst.ctr"
+ if(st) {
+ f2lsvgst_style_initialize(st);
+ dk3_delete(st);
+ }
+
+#line 1299 "f2lsvgst.ctr"
+}
+
+
+
+f2l_svg_style_t *
+f2lsvgst_style_new(f2l_svg_t *psvg)
+{
+ f2l_svg_style_t *back = NULL;
+
+
+#line 1308 "f2lsvgst.ctr"
+ if(psvg) {
+ back = dk3_new(f2l_svg_style_t,1);
+ if(back) {
+ f2lsvgst_style_initialize(back);
+ } else {
+ psvg->ec = DK3_ERROR_MEMORY;
+ }
+ }
+
+#line 1316 "f2lsvgst.ctr"
+ return back;
+}
+
+
+
+void
+f2lsvgst_delete(f2l_svg_t *psvg)
+{
+ f2l_svg_style_t *st;
+ f2l_svg_fill_pattern_t *pa;
+
+
+#line 1327 "f2lsvgst.ctr"
+ if(psvg) {
+ dk3_release(psvg->psFontsUsed);
+ if(psvg->sStyles) {
+ if(psvg->iStyles) {
+ dk3sto_it_reset(psvg->iStyles);
+ while(NULL != (st = (f2l_svg_style_t *)dk3sto_it_next(psvg->iStyles))) {
+ f2lsvgst_style_delete(st);
+ }
+ dk3sto_it_close(psvg->iStyles);
+ }
+ dk3sto_close(psvg->sStyles);
+ } psvg->sStyles = NULL; psvg->iStyles = NULL;
+ if(psvg->sPatterns) {
+ if(psvg->iPatterns) {
+ dk3sto_it_reset(psvg->iPatterns);
+ do {
+ pa = (f2l_svg_fill_pattern_t *)dk3sto_it_next(psvg->iPatterns);
+ if(pa) {
+ f2lsvgst_pattern_delete(pa);
+ }
+ } while(pa);
+ dk3sto_it_close(psvg->iPatterns);
+ }
+ dk3sto_close(psvg->sPatterns);
+ } psvg->sPatterns = NULL; psvg->iPatterns = NULL;
+ dk3_delete(psvg);
+ }
+
+#line 1354 "f2lsvgst.ctr"
+}
+
+
+
+f2l_svg_t *
+f2lsvgst_new_app(dk3_app_t *app)
+{
+ f2l_svg_t *back = NULL;
+ size_t i;
+ int ok = 0;
+
+
+#line 1365 "f2lsvgst.ctr"
+ back = dk3_new_app(f2l_svg_t,1,app);
+ if(back) {
+ back->sPatterns = NULL;
+ back->iPatterns = NULL;
+ back->sStyles = NULL;
+ back->iStyles = NULL;
+ back->nPatterns = 0UL;
+ back->nStyles = 0UL;
+ back->psFontsUsed = NULL;
+ back->ec = 0;
+ back->sPatterns = dk3sto_open_app(app);
+ if(back->sPatterns) {
+ dk3sto_set_comp(back->sPatterns, f2lsvgst_compare_pattern, 0);
+ back->iPatterns = dk3sto_it_open(back->sPatterns);
+ if(back->iPatterns) {
+ back->sStyles = dk3sto_open_app(app);
+ if(back->sStyles) {
+ dk3sto_set_comp(back->sStyles, f2lsvgst_compare_object_styles, 0);
+ back->iStyles = dk3sto_it_open(back->sStyles);
+ if(back->iStyles) {
+ back->psFontsUsed = dk3_new_app(int,35,app);
+ if(back) {
+ for(i = 0; i < 35; i++) { (back->psFontsUsed)[i] = 0; }
+ ok = 1;
+ }
+ }
+ }
+ }
+ }
+ if(!(ok)) {
+ f2lsvgst_delete(back);
+ back = NULL;
+ }
+ }
+
+#line 1399 "f2lsvgst.ctr"
+ return back;
+}
+
+
+
+int
+f2lsvgst_get_error_code(f2l_svg_t *psvg)
+{
+ int back = 0;
+ if(psvg) {
+ back = psvg->ec;
+ psvg->ec = 0;
+ }
+
+#line 1412 "f2lsvgst.ctr"
+ return back;
+}
+
+
+f2l_svg_fill_pattern_t *
+f2lsvgst_pattern_add(f2l_svg_t *psvg, f2l_svg_fill_pattern_t *src)
+{
+ f2l_svg_fill_pattern_t *back = NULL;
+
+
+#line 1421 "f2lsvgst.ctr"
+ if((psvg) && (src)) {
+ back = (f2l_svg_fill_pattern_t *)dk3sto_it_find_like(
+ psvg->iPatterns, (void *)src, 0
+ );
+ if(!(back)) {
+ if(0UL != (1UL + psvg->nPatterns)) {
+ back = f2lsvgst_pattern_new(psvg);
+ if(back) {
+ dk3mem_cpy((void *)back, (void *)src, sizeof(f2l_svg_fill_pattern_t));
+ if(dk3sto_add(psvg->sPatterns, (void *)back)) {
+ back->pn = psvg->nPatterns;
+ psvg->nPatterns += 1UL;
+ } else {
+ f2lsvgst_pattern_delete(back);
+ back = NULL;
+ }
+ }
+ } else {
+ psvg->ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ }
+
+#line 1443 "f2lsvgst.ctr"
+ return back;
+}
+
+
+
+f2l_svg_style_t *
+f2lsvgst_style_add(f2l_svg_t *psvg, f2l_svg_style_t *src)
+{
+ f2l_svg_style_t *back = NULL;
+
+
+#line 1453 "f2lsvgst.ctr"
+ if((psvg) && (src)) {
+ back = (f2l_svg_style_t *)dk3sto_it_find_like(
+ psvg->iStyles, (void *)src, 0
+ );
+ if(!(back)) {
+
+#line 1458 "f2lsvgst.ctr"
+ if(0UL != (1UL + psvg->nStyles)) {
+
+#line 1459 "f2lsvgst.ctr"
+ back = f2lsvgst_style_new(psvg);
+ if(back) {
+
+#line 1461 "f2lsvgst.ctr"
+ dk3mem_cpy((void *)back, (void *)src, sizeof(f2l_svg_style_t));
+ if(dk3sto_add(psvg->sStyles, (void *)back)) {
+ back->sn = psvg->nStyles;
+ psvg->nStyles += 1UL;
+ } else {
+ f2lsvgst_style_delete(back);
+ back = NULL;
+ }
+ } else {
+
+#line 1470 "f2lsvgst.ctr"
+ }
+ } else {
+ psvg->ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else {
+
+#line 1475 "f2lsvgst.ctr"
+ }
+ }
+
+#line 1477 "f2lsvgst.ctr"
+ return back;
+}
+
+
+
+int
+f2lsvgst_style_set_pattern(
+ f2l_svg_t *psvg,
+ f2l_svg_style_t *pst,
+ f2l_svg_fill_pattern_t *ppat
+)
+{
+ int back = 0;
+
+
+#line 1491 "f2lsvgst.ctr"
+ if((psvg) && (pst) && (ppat)) {
+ if(!(pst->fp)) {
+ pst->fp = f2lsvgst_pattern_add(psvg, ppat);
+ if(pst->fp) {
+ back = 1;
+ }
+ }
+ }
+
+#line 1499 "f2lsvgst.ctr"
+ return back;
+}
+
+
+
+void
+f2lsvgst_style_set_text(
+ f2l_svg_t *psvg,
+ f2l_svg_style_t *pst,
+ int ps,
+ int tf,
+ double ts
+)
+{
+
+
+#line 1514 "f2lsvgst.ctr"
+ if(pst) {
+ pst->tf = tf;
+ pst->ts = ts;
+ pst->flags |= (DK3_SVG_FLAGS_FONT);
+ if(ps) {
+ pst->flags |= (DK3_SVG_FLAGS_PS_FONT);
+ } else {
+ pst->flags &= (~(DK3_SVG_FLAGS_PS_FONT));
+ }
+ }
+ if((psvg) && (ps)) {
+ if((0 <= tf) && (tf < 35)) {
+ (psvg->psFontsUsed)[tf] = 1;
+ }
+ }
+
+#line 1529 "f2lsvgst.ctr"
+}
+
+
+
+void
+f2lsvgst_style_set_line_width(
+ f2l_svg_style_t *pst,
+ double lw
+)
+{
+
+
+#line 1540 "f2lsvgst.ctr"
+ if(pst) {
+ pst->lw = lw;
+ pst->flags |= (DK3_SVG_FLAGS_LINEWIDTH);
+ }
+
+#line 1544 "f2lsvgst.ctr"
+}
+
+
+
+void
+f2lsvgst_style_set_line_style(
+ f2l_svg_style_t *pst,
+ int ls,
+ double lsv
+)
+{
+
+
+#line 1556 "f2lsvgst.ctr"
+ if(pst) {
+ pst->ls = ls; pst->lsv = lsv;
+ pst->flags|= (DK3_SVG_FLAGS_LINESTYLE);
+ }
+
+#line 1560 "f2lsvgst.ctr"
+}
+
+
+
+void
+f2lsvgst_style_set_line_color(
+ f2l_svg_style_t *pst,
+ int r,
+ int g,
+ int b
+)
+{
+
+
+#line 1573 "f2lsvgst.ctr"
+ if(pst) {
+ pst->sr = r; pst->sg = g; pst->sb = b;
+ pst->flags |= (DK3_SVG_FLAGS_COLOR_STROKE);
+ }
+
+#line 1577 "f2lsvgst.ctr"
+}
+
+
+
+void
+f2lsvgst_style_set_fill_color(
+ f2l_svg_style_t *pst,
+ int r,
+ int g,
+ int b
+)
+{
+
+
+#line 1590 "f2lsvgst.ctr"
+ if(pst) {
+ pst->fr = r; pst->fg = g; pst->fb = b;
+ pst->flags |= (DK3_SVG_FLAGS_COLOR_FILL);
+ }
+
+#line 1594 "f2lsvgst.ctr"
+}
+
+
+
+int
+f2lsvgst_any_ps_font_used(f2l_svg_t *psvg)
+{
+ size_t i;
+ int back = 0;
+ for(i = 0; i < 35; i++) {
+ if((psvg->psFontsUsed)[i]) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+void
+f2lsvgst_style_set_text_align(f2l_svg_style_t *pst, int al)
+{
+ if(pst) {
+ pst->al = al;
+ pst->flags |= (DK3_SVG_FLAGS_TEXT_ALIGN);
+ }
+}
+
+
+
+void
+f2lsvgst_style_set_text_line_cap(f2l_svg_style_t *pst, int lc)
+{
+ if(pst) {
+ pst->lc = lc;
+ pst->flags |= (DK3_SVG_FLAGS_LINE_CAP);
+ }
+}
+
+
+
+void
+f2lsvgst_style_set_text_line_join(f2l_svg_style_t *pst, int lj)
+{
+ if(pst) {
+ pst->lj = lj;
+ pst->flags |= (DK3_SVG_FLAGS_LINE_JOIN);
+ }
+}
+
+
+
+/** Write one tag name, either with or without svg: prefix.
+ @param job Job structure.
+ @param ind Index of tag name in f2lsvgst_c8_kw.
+*/
+static
+void
+f2lsvgst_tag(
+ f2l_job_t *job,
+ size_t ind
+)
+{
+ if(job->fragment) {
+ fputs(f2lsvgst_c8_kw[1], job->of1);
+ }
+ fputs(f2lsvgst_c8_kw[ind], job->of1);
+}
+
+
+
+/** Write a number as string.
+ @param job Job structure.
+ @param current Current value.
+ @param max Maximum value.
+*/
+static
+void
+f2lsvgst_write_id(
+ f2l_job_t *job,
+ unsigned long current,
+ unsigned long max
+)
+{
+ char buf[128];
+ char *ptr;
+ size_t maxlgt;
+ size_t lgt;
+ size_t i;
+
+ sprintf(buf, "%lu", max);
+ maxlgt = strlen(buf);
+ sprintf(buf, "%lu", current);
+ lgt = strlen(buf);
+ for(i = lgt; i < maxlgt; i++) {
+ fputc('A', job->of1);
+ }
+ ptr = buf;
+ while(*ptr) {
+ switch(*ptr) {
+ case '0': { *ptr = 'A'; } break;
+ case '1': { *ptr = 'B'; } break;
+ case '2': { *ptr = 'C'; } break;
+ case '3': { *ptr = 'D'; } break;
+ case '4': { *ptr = 'E'; } break;
+ case '5': { *ptr = 'F'; } break;
+ case '6': { *ptr = 'G'; } break;
+ case '7': { *ptr = 'H'; } break;
+ case '8': { *ptr = 'I'; } break;
+ case '9': { *ptr = 'J'; } break;
+ }
+ ptr++;
+ }
+ fputs(buf, job->of1);
+}
+
+
+
+void
+f2lsvgst_write_pattern_id(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+
+
+#line 1721 "f2lsvgst.ctr"
+ fputs(f2lsvgst_c8_kw[8], job->of1);
+ f2lsvgst_write_id(job, pat->pn, psvg->nPatterns);
+
+
+#line 1724 "f2lsvgst.ctr"
+}
+
+
+
+void
+f2lsvgst_write_style_id(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_style_t *pst
+)
+{
+
+
+#line 1737 "f2lsvgst.ctr"
+ fputs(f2lsvgst_c8_kw[111], job->of1);
+ f2lsvgst_write_id(job, pst->sn, psvg->nStyles);
+
+
+#line 1740 "f2lsvgst.ctr"
+}
+
+
+/** Write opening pattern tag.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+ @param w Pattern width.
+ @param h Pattern height.
+*/
+static
+void
+f2lsvgst_write_opening_pattern_tag(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat,
+ double w,
+ double h
+)
+{
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[7], job->of1);
+ f2lsvgst_write_pattern_id(job, drw, psvg, pat);
+ fprintf(job->of1, f2lsvgst_c8_kw[9], w, h);
+}
+
+
+
+/** Write opening pattern tag.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+ @param w Pattern width.
+ @param h Pattern height.
+*/
+static
+void
+f2lsvgst_pattern_background(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat,
+ double w,
+ double h
+)
+{
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ f2lsvgst_tag(job, 10);
+ fprintf(job->of1, f2lsvgst_c8_kw[11], w, h);
+ fprintf(job->of1, f2lsvgst_c8_kw[12], pat->fr, pat->fg, pat->fb);
+ fputs(f2lsvgst_c8_kw[13], job->of1);
+}
+
+
+
+/** Draw foreground line in pattern.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+ @param ind Index of points line in f2lsvgst_c8_kw.
+*/
+static
+void
+f2lsvgst_pattern_foreground_line(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat,
+ size_t ind
+)
+{
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ f2lsvgst_tag(job, 18);
+ fprintf(job->of1, f2lsvgst_c8_kw[14], pat->sr, pat->sg, pat->sb);
+ fputs(f2lsvgst_c8_kw[ind], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+ fputs(f2lsvgst_c8_kw[13], job->of1);
+}
+
+
+
+/** Draw foreground line in pattern.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+ @param ind Index of points line in f2lsvgst_c8_kw.
+*/
+static
+void
+f2lsvgst_pattern_foreground_line_lcr(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat,
+ size_t ind
+)
+{
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ f2lsvgst_tag(job, 18);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+ fprintf(job->of1, f2lsvgst_c8_kw[22], pat->sr, pat->sg, pat->sb);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+ fputs(f2lsvgst_c8_kw[ind], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+ fputs(f2lsvgst_c8_kw[13], job->of1);
+}
+
+
+
+/** Draw foreground polygon in pattern.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+ @param ind Index of points line in f2lsvgst_c8_kw.
+*/
+static
+void
+f2lsvgst_pattern_foreground_polygon_lcr(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat,
+ size_t ind
+)
+{
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ f2lsvgst_tag(job, 51);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+ fprintf(job->of1, f2lsvgst_c8_kw[22], pat->sr, pat->sg, pat->sb);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+ fputs(f2lsvgst_c8_kw[ind], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+ fputs(f2lsvgst_c8_kw[13], job->of1);
+}
+
+
+
+/** Draw foreground polygon in pattern, 2 data lines.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+ @param i1 Index of points line in f2lsvgst_c8_kw.
+ @param i2 Index of points line 2.
+*/
+static
+void
+f2lsvgst_pattern_foreground_polygon_lcr_l2(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat,
+ size_t i1,
+ size_t i2
+)
+{
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ f2lsvgst_tag(job, 51);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+ fprintf(job->of1, f2lsvgst_c8_kw[22], pat->sr, pat->sg, pat->sb);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+ fputs(f2lsvgst_c8_kw[i1], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+ fputs(f2lsvgst_c8_kw[i2], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+ fputs(f2lsvgst_c8_kw[13], job->of1);
+}
+
+
+
+/** Draw foreground path in pattern
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+ @param ind Index of data line in f2lsvgst_c8_kw.
+*/
+static
+void
+f2lsvgst_pattern_foreground_path_lcr(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat,
+ size_t ind
+)
+{
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ f2lsvgst_tag(job, 89);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+ fprintf(job->of1, f2lsvgst_c8_kw[22], pat->sr, pat->sg, pat->sb);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+ fputs(f2lsvgst_c8_kw[ind], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+ fputs(f2lsvgst_c8_kw[13], job->of1);
+}
+
+
+
+/** Draw foreground circle in pattern
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_foreground_circle_lcr(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ f2lsvgst_tag(job, 100);
+ fputs(f2lsvgst_c8_kw[102], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+ fprintf(job->of1, f2lsvgst_c8_kw[101], pat->sr, pat->sg, pat->sb);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+ fputs(f2lsvgst_c8_kw[13], job->of1);
+}
+
+
+
+/** Write pattern 41 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_41(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 7.2, 4.16);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 7.2, 4.16);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 15);
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 16);
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 17);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 42 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_42(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 7.2, 4.16);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 7.2, 4.16);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 19);
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 20);
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 21);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 43 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_43(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 7.2, 4.16);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 7.2, 4.16);
+ /* Pattern contents 2: lines.
+ */
+#if 1
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 23);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 24);
+#else
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 15);
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 16);
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 17);
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 19);
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 20);
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 21);
+#endif
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 44 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_44(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 10.18, 10.18);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 10.18, 10.18);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 25);
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 26);
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 27);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 45 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_45(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 10.18, 10.18);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 10.18, 10.18);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 28);
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 29);
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 30);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 46 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_46(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 10.18, 10.18);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 10.18, 10.18);
+ /* Pattern contents 2: lines.
+ */
+#if 1
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 31);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 32);
+#else
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 25);
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 26);
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 27);
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 28);
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 29);
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 30);
+#endif
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 47 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_47(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 28.8, 14.4);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 28.8, 14.4);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 33);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 34);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 35);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 36);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 37);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 38);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 39);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 48 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_48(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 14.4, 28.8);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 14.4, 28.8);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 40);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 41);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 42);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 43);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 44);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 45);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 46);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 49 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_49(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 3.6, 3.6);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 3.6, 3.6);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 47);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 48);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 50 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_50(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 3.6, 3.6);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 3.6, 3.6);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 49);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 50);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 51 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_51(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 3.6, 3.6);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 3.6, 3.6);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_polygon_lcr(job, drw, psvg, pat, 52);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 52 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_52(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 14.4, 28.8);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 14.4, 28.8);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 53);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 54);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 55);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 56);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 57);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 58);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 59);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 60);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 61);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 53 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_53(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 14.4, 28.8);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 14.4, 28.8);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 62);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 63);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 64);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 65);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 66);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 67);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 68);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 69);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 70);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 54 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_54(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 28.8, 14.4);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 28.8, 14.4);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 71);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 72);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 73);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 74);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 75);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 76);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 77);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 78);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 79);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 55 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_55(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 28.8, 14.4);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 28.8, 14.4);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 80);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 81);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 82);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 83);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 84);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 85);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 86);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 87);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 88);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 56 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_56(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 14.54, 7.4);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 14.54, 7.4);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_path_lcr(job, drw, psvg, pat, 90);
+ f2lsvgst_pattern_foreground_path_lcr(job, drw, psvg, pat, 91);
+ f2lsvgst_pattern_foreground_path_lcr(job, drw, psvg, pat, 92);
+ f2lsvgst_pattern_foreground_path_lcr(job, drw, psvg, pat, 93);
+ f2lsvgst_pattern_foreground_path_lcr(job, drw, psvg, pat, 94);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 57 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_57(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 7.2, 7.2);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 7.2, 7.2);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_path_lcr(job, drw, psvg, pat, 95);
+ f2lsvgst_pattern_foreground_path_lcr(job, drw, psvg, pat, 96);
+ f2lsvgst_pattern_foreground_path_lcr(job, drw, psvg, pat, 97);
+ f2lsvgst_pattern_foreground_path_lcr(job, drw, psvg, pat, 98);
+ f2lsvgst_pattern_foreground_path_lcr(job, drw, psvg, pat, 99);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 58 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_58(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 14.4, 14.4);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 14.4, 14.4);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_circle_lcr(job, drw, psvg, pat);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 59 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_59(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 21.6, 12.47);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 21.6, 12.47);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_polygon_lcr(job, drw, psvg, pat, 103);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 104);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 105);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 106);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 60 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_60(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 14.4, 14.4);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 14.4, 14.4);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_polygon_lcr_l2(job, drw, psvg, pat, 107, 108);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 61 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_61(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 7.2, 7.2);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 7.2, 7.2);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 109);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 62 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_62(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 7.2, 7.2);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 7.2, 7.2);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 110);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write one pattern definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_write_one_pattern(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ switch(pat->fn) {
+ case 41: {
+ f2lsvgst_pattern_41(job, drw, psvg, pat);
+ } break;
+ case 42: {
+ f2lsvgst_pattern_42(job, drw, psvg, pat);
+ } break;
+ case 43: {
+ f2lsvgst_pattern_43(job, drw, psvg, pat);
+ } break;
+ case 44: {
+ f2lsvgst_pattern_44(job, drw, psvg, pat);
+ } break;
+ case 45: {
+ f2lsvgst_pattern_45(job, drw, psvg, pat);
+ } break;
+ case 46: {
+ f2lsvgst_pattern_46(job, drw, psvg, pat);
+ } break;
+ case 47: {
+ f2lsvgst_pattern_47(job, drw, psvg, pat);
+ } break;
+ case 48: {
+ f2lsvgst_pattern_48(job, drw, psvg, pat);
+ } break;
+ case 49: {
+ f2lsvgst_pattern_49(job, drw, psvg, pat);
+ } break;
+ case 50: {
+ f2lsvgst_pattern_50(job, drw, psvg, pat);
+ } break;
+ case 51: {
+ f2lsvgst_pattern_51(job, drw, psvg, pat);
+ } break;
+ case 52: {
+ f2lsvgst_pattern_52(job, drw, psvg, pat);
+ } break;
+ case 53: {
+ f2lsvgst_pattern_53(job, drw, psvg, pat);
+ } break;
+ case 54: {
+ f2lsvgst_pattern_54(job, drw, psvg, pat);
+ } break;
+ case 55: {
+ f2lsvgst_pattern_55(job, drw, psvg, pat);
+ } break;
+ case 56: {
+ f2lsvgst_pattern_56(job, drw, psvg, pat);
+ } break;
+ case 57: {
+ f2lsvgst_pattern_57(job, drw, psvg, pat);
+ } break;
+ case 58: {
+ f2lsvgst_pattern_58(job, drw, psvg, pat);
+ } break;
+ case 59: {
+ f2lsvgst_pattern_59(job, drw, psvg, pat);
+ } break;
+ case 60: {
+ f2lsvgst_pattern_60(job, drw, psvg, pat);
+ } break;
+ case 61: {
+ f2lsvgst_pattern_61(job, drw, psvg, pat);
+ } break;
+ case 62: {
+ f2lsvgst_pattern_62(job, drw, psvg, pat);
+ } break;
+ }
+}
+
+
+
+void
+f2lsvgst_write_patterns(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg
+)
+{
+ f2l_svg_fill_pattern_t *pat;
+ if((psvg->sPatterns) && (psvg->iPatterns)) {
+ dk3sto_it_reset(psvg->iPatterns);
+ do {
+ pat = (f2l_svg_fill_pattern_t *)dk3sto_it_next(psvg->iPatterns);
+ if(pat) {
+ f2lsvgst_write_one_pattern(job, drw, psvg, pat);
+ }
+ } while(pat);
+ }
+}
+
+
+
+/** Write one style to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pst Style definition to write.
+*/
+static
+void
+f2lsvgst_write_one_style(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_style_t *pst
+)
+{
+ char const * const *rffn; /* Replacement font family name. */
+ double ts; /* Text size. */
+ double gw; /* Gap width in line styles. */
+ int ff; /* Font family */
+
+ if(pst->tf < 0) { pst->tf = 0; }
+ if(pst->tf > 34) { pst->tf = 34; }
+ fputs(f2lsvgst_c8_kw[112], job->of1);
+ f2lsvgst_write_style_id(job, drw, psvg, pst);
+ fputs(f2lsvgst_c8_kw[113], job->of1);
+ if((pst->flags) & DK3_SVG_FLAGS_FONT) {
+ if((pst->flags) & DK3_SVG_FLAGS_PS_FONT) {
+ /* Font family
+ */
+ fputs(f2lsvgst_c8_kw[115], job->of1);
+ fputs(dk3font_get_svg_family(pst->tf), job->of1);
+ if(job->otherfonts) {
+ /* PS family name.
+ */
+ fputs(f2lsvgst_c8_kw[187], job->of1);
+ fputs(dk3font_get_ps_family(pst->tf), job->of1);
+ /* Replacement family names.
+ */
+ rffn = dk3font_get_replacement_families(pst->tf);
+ while(*rffn) {
+ fputs(f2lsvgst_c8_kw[187], job->of1);
+ fputs(*rffn, job->of1);
+ rffn++;
+ }
+ }
+ ff = dk3font_get_svg_features(pst->tf);
+ switch(ff & DK3_FONT_FAMILY) {
+ case DK3_FONT_TYPEWRITER: {
+ fputs(f2lsvgst_c8_kw[118], job->of1);
+ } break;
+ case DK3_FONT_SANS_SERIF: {
+ fputs(f2lsvgst_c8_kw[117], job->of1);
+ } break;
+ default: {
+ fputs(f2lsvgst_c8_kw[116], job->of1);
+ } break;
+ }
+ /* Font style
+ */
+ if(ff & DK3_FONT_OBLIQUE) {
+ fputs(f2lsvgst_c8_kw[121], job->of1);
+ } else {
+ if(ff & DK3_FONT_ITALIC) {
+ fputs(f2lsvgst_c8_kw[120], job->of1);
+ } else {
+#if 0
+ /* 2013-01-27: This is the default.
+ */
+ fputs(f2lsvgst_c8_kw[119], job->of1);
+#endif
+ }
+ }
+ /* Font weight
+ */
+ ff = dk3font_get_svg_font_weight(pst->tf);
+ fprintf(job->of1, f2lsvgst_c8_kw[122], ff);
+ } else {
+ /* Font family, style, weight
+ */
+ switch(pst->tf) {
+ case 5: { /* Typewriter */
+ fputs(f2lsvgst_c8_kw[125], job->of1);
+#if 0
+ /* 2013-01-27: This is the default.
+ */
+ fputs(f2lsvgst_c8_kw[126], job->of1);
+ fputs(f2lsvgst_c8_kw[128], job->of1);
+#endif
+ } break;
+ case 4: { /* Sans-serif */
+ fputs(f2lsvgst_c8_kw[124], job->of1);
+#if 0
+ /* 2013-01-27: This is the default.
+ */
+ fputs(f2lsvgst_c8_kw[126], job->of1);
+ fputs(f2lsvgst_c8_kw[128], job->of1);
+#endif
+ } break;
+ case 3: { /* Italic serif */
+ fputs(f2lsvgst_c8_kw[123], job->of1);
+ fputs(f2lsvgst_c8_kw[127], job->of1);
+#if 0
+ /* 2013-01-27: This is the default.
+ */
+ fputs(f2lsvgst_c8_kw[128], job->of1);
+#endif
+ } break;
+ case 2: { /* Bold serif */
+ fputs(f2lsvgst_c8_kw[123], job->of1);
+#if 0
+ /* 2013-01-27: This is the default.
+ */
+ fputs(f2lsvgst_c8_kw[126], job->of1);
+#endif
+ fputs(f2lsvgst_c8_kw[129], job->of1);
+ } break;
+ default: { /* Default font (serif) */
+ fputs(f2lsvgst_c8_kw[123], job->of1);
+#if 0
+ /* 2013-01-27: This is the default.
+ */
+ fputs(f2lsvgst_c8_kw[126], job->of1);
+ fputs(f2lsvgst_c8_kw[128], job->of1);
+#endif
+ } break;
+ }
+ }
+ /* Font size
+ */
+ ts = pst->ts;
+ if(0.0 < job->nts) {
+ ts = ts * job->nts;
+ }
+ fprintf(job->of1, f2lsvgst_c8_kw[130], ts);
+ }
+ /* Text align
+ */
+ if((pst->flags) & DK3_SVG_FLAGS_TEXT_ALIGN) {
+ switch(pst->al) {
+ case 2: {
+ fputs(f2lsvgst_c8_kw[133], job->of1);
+ } break;
+ case 1: {
+ fputs(f2lsvgst_c8_kw[132], job->of1);
+ } break;
+ default: {
+#if 0
+ /* 2013-01-27: This is the default.
+ */
+ fputs(f2lsvgst_c8_kw[131], job->of1);
+#endif
+ } break;
+ }
+ }
+ /* Fill pattern or color fill
+ */
+ if(pst->fp) {
+ fputs(f2lsvgst_c8_kw[134], job->of1);
+ f2lsvgst_write_pattern_id(job, drw, psvg, pst->fp);
+ fputs(f2lsvgst_c8_kw[135], job->of1);
+ } else {
+ if((pst->flags) & DK3_SVG_FLAGS_COLOR_FILL) {
+ if((pst->flags) & DK3_SVG_FLAGS_FONT) {
+ fprintf(job->of1, f2lsvgst_c8_kw[183], pst->fr, pst->fg, pst->fb);
+ } else {
+ fprintf(job->of1, f2lsvgst_c8_kw[136], pst->fr, pst->fg, pst->fb);
+ }
+ } else { /* No fill */
+ fputs(f2lsvgst_c8_kw[137], job->of1);
+ }
+ }
+ /* Stroke color stroke
+ */
+ if((pst->flags) & DK3_SVG_FLAGS_COLOR_STROKE) {
+ fprintf(job->of1, f2lsvgst_c8_kw[138], pst->sr, pst->sg, pst->sb);
+ }
+ /* Stroke linewidth stroke-width
+ */
+ if((pst->flags) & DK3_SVG_FLAGS_LINEWIDTH) {
+ fprintf(job->of1, f2lsvgst_c8_kw[139], pst->lw);
+ }
+ /* Stroke linestyle stroke-dasharray
+ */
+ if((pst->flags) & DK3_SVG_FLAGS_LINESTYLE) {
+ if((pst->flags) & DK3_SVG_FLAGS_LINEWIDTH) {
+ if(0 != pst->ls) {
+ gw = f2lto_find_gap_length(job, pst->lw, pst->lsv);
+ fputs(f2lsvgst_c8_kw[146], job->of1);
+ switch(pst->ls) {
+ case DK3_FIG_LS_DASH_TRIPLE_DOTTED: {
+ fprintf(
+ job->of1,
+ f2lsvgst_c8_kw[152],
+ pst->lsv, gw, pst->lw, gw, pst->lw, gw,
+ pst->lw, gw
+ );
+ } break;
+ case DK3_FIG_LS_DASH_DOUBLE_DOTTED: {
+ fprintf(
+ job->of1,
+ f2lsvgst_c8_kw[151],
+ pst->lsv, gw, pst->lw, gw, pst->lw, gw
+ );
+ } break;
+ case DK3_FIG_LS_DASH_DOTTED: {
+ fprintf(
+ job->of1,
+ f2lsvgst_c8_kw[150],
+ pst->lsv, gw, pst->lw, gw
+ );
+ } break;
+ case DK3_FIG_LS_DOTTED: {
+ fprintf(
+ job->of1,
+ f2lsvgst_c8_kw[149],
+ pst->lw, gw
+ );
+ } break;
+ case DK3_FIG_LS_DASHED: {
+ fprintf(
+ job->of1,
+ f2lsvgst_c8_kw[149],
+ pst->lsv, gw
+ );
+ } break;
+ default: {
+ fputs(f2lsvgst_c8_kw[148], job->of1);
+ } break;
+ }
+ fputs(f2lsvgst_c8_kw[147], job->of1);
+ }
+ }
+ }
+ /* Linecap stroke-linecap
+ */
+ if((pst->flags) & DK3_SVG_FLAGS_LINE_CAP) {
+ if(DK3_FIG_LC_BUTT != pst->lc) {
+ switch(pst->lc) {
+ case DK3_FIG_LC_PROJECTING: {
+ fputs(f2lsvgst_c8_kw[140], job->of1);
+ } break;
+ case DK3_FIG_LC_ROUND: {
+ fputs(f2lsvgst_c8_kw[141], job->of1);
+ } break;
+ default: {
+#if 0
+ /* 2013-01-27: This is the default.
+ */
+ fputs(f2lsvgst_c8_kw[142], job->of1);
+#endif
+ } break;
+ }
+ }
+ }
+ /* Linejoin stroke-linejoin
+ */
+ if((pst->flags) & DK3_SVG_FLAGS_LINE_JOIN) {
+ switch(pst->lj) {
+ case DK3_FIG_LJ_BEVEL: {
+ fputs(f2lsvgst_c8_kw[143], job->of1);
+ } break;
+ case DK3_FIG_LJ_ROUND: {
+ fputs(f2lsvgst_c8_kw[144], job->of1);
+ } break;
+ default: {
+#if 0
+ /* 2013-01-27: This is the default.
+ */
+ fputs(f2lsvgst_c8_kw[145], job->of1);
+#endif
+ if(job->miterlim) {
+ fputs(f2lsvgst_c8_kw[185], job->of1);
+ }
+ } break;
+ }
+ }
+ /* End
+ */
+ fputs(f2lsvgst_c8_kw[114], job->of1);
+}
+
+
+
+/** Write attributes for one style to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pst Style definition to write.
+*/
+static
+void
+f2lsvgst_write_attributes_for_one_style(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_style_t *pst
+)
+{
+ char const * const *rffn; /* Replacement font family names. */
+ int ff; /* Font family and flags. */
+ double ts; /* Font size. */
+ double gw; /* Gap width in line styles. */
+
+ if((pst->flags) & DK3_SVG_FLAGS_FONT) {
+ ff = dk3font_get_svg_features(pst->tf);
+ ts = pst->ts;
+ if(0.0 < job->nts) {
+ ts = ts * job->nts;
+ }
+ /* Font family, font style, font weight, text size.
+ */
+ if((pst->flags) & DK3_SVG_FLAGS_PS_FONT) {
+ fputs(f2lsvgst_c8_kw[153], job->of1);
+ fputs(dk3font_get_svg_family(pst->tf), job->of1);
+ if(job->otherfonts) {
+ /* PS family name.
+ */
+ fputs(f2lsvgst_c8_kw[188], job->of1);
+ fputs(dk3font_get_ps_family(pst->tf), job->of1);
+ /* Replacement family names.
+ */
+ rffn = dk3font_get_replacement_families(pst->tf);
+ while(*rffn) {
+ fputs(f2lsvgst_c8_kw[188], job->of1);
+ fputs(*rffn, job->of1);
+ rffn++;
+ }
+ }
+ switch(ff & DK3_FONT_FAMILY) {
+ case DK3_FONT_TYPEWRITER: {
+ fputs(f2lsvgst_c8_kw[156], job->of1);
+ } break;
+ case DK3_FONT_SANS_SERIF: {
+ fputs(f2lsvgst_c8_kw[155], job->of1);
+ } break;
+ default: {
+ fputs(f2lsvgst_c8_kw[154], job->of1);
+ } break;
+ }
+ if(ff & DK3_FONT_OBLIQUE) {
+ fputs(f2lsvgst_c8_kw[157], job->of1);
+ } else {
+ if(ff & DK3_FONT_ITALIC) {
+ fputs(f2lsvgst_c8_kw[158], job->of1);
+ }
+ }
+ fprintf(
+ job->of1, f2lsvgst_c8_kw[159], dk3font_get_svg_font_weight(pst->tf)
+ );
+ } else {
+ switch(pst->tf) {
+ case 5: { /* typewriter */
+ fputs(f2lsvgst_c8_kw[163], job->of1);
+ } break;
+ case 4: { /* sans-serif */
+ fputs(f2lsvgst_c8_kw[162], job->of1);
+ } break;
+ case 3: { /* serif italic */
+ fputs(f2lsvgst_c8_kw[161], job->of1);
+ fputs(f2lsvgst_c8_kw[158], job->of1);
+ } break;
+ case 2: { /* serif bold */
+ fputs(f2lsvgst_c8_kw[161], job->of1);
+ fputs(f2lsvgst_c8_kw[164], job->of1);
+ } break;
+ default: { /* serif */
+ fputs(f2lsvgst_c8_kw[161], job->of1);
+ } break;
+ }
+ }
+ fprintf(job->of1, f2lsvgst_c8_kw[160], ts);
+ /* Text align.
+ */
+ if((pst->flags) & DK3_SVG_FLAGS_TEXT_ALIGN) {
+ switch(pst->al) {
+ case 2: {
+ fputs(f2lsvgst_c8_kw[166], job->of1);
+ } break;
+ case 1: {
+ fputs(f2lsvgst_c8_kw[165], job->of1);
+ } break;
+ }
+ }
+ }
+ /* Fill pattern or color.
+ */
+ if(pst->fp) {
+ fputs(f2lsvgst_c8_kw[167], job->of1);
+ f2lsvgst_write_pattern_id(job, drw, psvg, pst->fp);
+ fputs(f2lsvgst_c8_kw[168], job->of1);
+ } else {
+ if((pst->flags) & DK3_SVG_FLAGS_COLOR_FILL) {
+ if((pst->flags) & DK3_SVG_FLAGS_FONT) {
+ fprintf(job->of1, f2lsvgst_c8_kw[169], pst->fr, pst->fg, pst->fb);
+ } else {
+ fprintf(job->of1, f2lsvgst_c8_kw[184], pst->fr, pst->fg, pst->fb);
+ }
+ } else {
+ fputs(f2lsvgst_c8_kw[170], job->of1);
+ }
+ }
+ /* Stroke color
+ */
+ if((pst->flags) & DK3_SVG_FLAGS_COLOR_STROKE) {
+ fprintf(job->of1, f2lsvgst_c8_kw[171], pst->sr, pst->sg, pst->sb);
+ }
+ /* Stroke linewidth.
+ */
+ if((pst->flags) & DK3_SVG_FLAGS_LINEWIDTH) {
+ fprintf(job->of1, f2lsvgst_c8_kw[172], pst->lw);
+ }
+ /* Stroke linestyle.
+ */
+ if((pst->flags) & DK3_SVG_FLAGS_LINESTYLE) {
+ if((pst->flags) & DK3_SVG_FLAGS_LINEWIDTH) {
+ gw = f2lto_find_gap_length(job, pst->lw, pst->lsv);
+ switch(pst->ls) {
+ case DK3_FIG_LS_DASH_TRIPLE_DOTTED: {
+ fprintf(
+ job->of1, f2lsvgst_c8_kw[176],
+ pst->lsv, gw, pst->lw, gw, pst->lw, gw,
+ pst->lw, gw
+ );
+ } break;
+ case DK3_FIG_LS_DASH_DOUBLE_DOTTED: {
+ fprintf(
+ job->of1, f2lsvgst_c8_kw[175],
+ pst->lsv, gw, pst->lw, gw, pst->lw, gw
+ );
+ } break;
+ case DK3_FIG_LS_DASH_DOTTED: {
+ fprintf(
+ job->of1, f2lsvgst_c8_kw[174],
+ pst->lsv, gw, pst->lw, gw
+ );
+ } break;
+ case DK3_FIG_LS_DOTTED: {
+ fprintf(
+ job->of1, f2lsvgst_c8_kw[173],
+ pst->lw, gw
+ );
+ } break;
+ case DK3_FIG_LS_DASHED: {
+ fprintf(
+ job->of1, f2lsvgst_c8_kw[173],
+ pst->lsv, gw
+ );
+ } break;
+ }
+ }
+ }
+ /* Linecap.
+ */
+ if((pst->flags) & DK3_SVG_FLAGS_LINE_CAP) {
+ switch(pst->lc) {
+ case DK3_FIG_LC_PROJECTING: {
+ fputs(f2lsvgst_c8_kw[178], job->of1);
+ } break;
+ case DK3_FIG_LC_ROUND: {
+ fputs(f2lsvgst_c8_kw[177], job->of1);
+ } break;
+ }
+ }
+ /* Linejoin.
+ */
+ if((pst->flags) & DK3_SVG_FLAGS_LINE_JOIN) {
+ switch(pst->lj) {
+ case DK3_FIG_LJ_BEVEL: {
+ fputs(f2lsvgst_c8_kw[180], job->of1);
+ } break;
+ case DK3_FIG_LJ_ROUND: {
+ fputs(f2lsvgst_c8_kw[179], job->of1);
+ } break;
+ default: {
+ if(job->miterlim) {
+ fputs(f2lsvgst_c8_kw[186], job->of1);
+ }
+ } break;
+ }
+ }
+}
+
+
+
+void
+f2lsvgst_write_style_for_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *pobj
+)
+{
+ f2l_svg_style_t *pst;
+
+
+#line 3429 "f2lsvgst.ctr"
+ if((job) && (drw) && (psvg) && (pobj)) {
+ pst = (f2l_svg_style_t *)(pobj->dsd);
+ if(pst) {
+
+#line 3432 "f2lsvgst.ctr"
+ if(job->css) {
+
+#line 3433 "f2lsvgst.ctr"
+ fputs(f2lsvgst_c8_kw[181], job->of1);
+ f2lsvgst_write_style_id(job, drw, psvg, pst);
+ fputs(f2lsvgst_c8_kw[182], job->of1);
+ } else {
+
+#line 3437 "f2lsvgst.ctr"
+ f2lsvgst_write_attributes_for_one_style(job, drw, psvg, pst);
+ }
+ } else {
+
+#line 3440 "f2lsvgst.ctr"
+ }
+ } else {
+
+#line 3442 "f2lsvgst.ctr"
+ }
+
+#line 3443 "f2lsvgst.ctr"
+}
+
+
+
+void
+f2lsvgst_write_styles(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg
+)
+{
+ f2l_svg_style_t *pst;
+ if((psvg->sStyles) && (psvg->iStyles)) {
+ dk3sto_it_reset(psvg->iStyles);
+ do {
+ pst = (f2l_svg_style_t *)dk3sto_it_next(psvg->iStyles);
+ if(pst) {
+ f2lsvgst_write_one_style(job, drw, psvg, pst);
+ }
+ } while(pst);
+ }
+}
+
+
+
diff --git a/support/dktools/f2lsvgst.ctr b/support/dktools/f2lsvgst.ctr
new file mode 100644
index 0000000000..f7115ad452
--- /dev/null
+++ b/support/dktools/f2lsvgst.ctr
@@ -0,0 +1,3467 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2013-xxxx
+license = bsd
+
+
+
+%% header
+
+#include "dk3all.h"
+#include "dk3font.h"
+#include "fig2lat.h"
+#include "f2lsvg.h"
+#include "f2lsvgst.h"
+#include "dk3figto.h"
+
+
+
+/** @defgroup svgstyleflags SVG style flags */
+/**@{*/
+
+/** Stroke color defined.
+*/
+#define DK3_SVG_FLAGS_COLOR_STROKE 1
+
+/** Fill color defined.
+*/
+#define DK3_SVG_FLAGS_COLOR_FILL 2
+
+/** Text align defined.
+*/
+#define DK3_SVG_FLAGS_TEXT_ALIGN 4
+
+/** Font defined.
+*/
+#define DK3_SVG_FLAGS_FONT 8
+
+/** Font is a PS font (LaTeX font otherwise).
+*/
+#define DK3_SVG_FLAGS_PS_FONT 16
+
+/** Line width defined.
+*/
+#define DK3_SVG_FLAGS_LINEWIDTH 32
+
+/** Line style defined.
+*/
+#define DK3_SVG_FLAGS_LINESTYLE 64
+
+/** Line cap defined.
+*/
+#define DK3_SVG_FLAGS_LINE_CAP 128
+
+/** Line join defined.
+*/
+#define DK3_SVG_FLAGS_LINE_JOIN 256
+
+/**@}*/
+
+
+/** Fill pattern.
+*/
+typedef struct {
+ unsigned long pn; /**< Pattern number. */
+ int fn; /**< Fig pattern number 41 - 62. */
+ int sr; /**< Stroke color red. */
+ int sg; /**< Stroke color green. */
+ int sb; /**< Stroke color blue. */
+ int fr; /**< Fill color red. */
+ int fg; /**< Fill color green. */
+ int fb; /**< Fill color blue. */
+} f2l_svg_fill_pattern_t;
+
+
+
+/** SVG object style information.
+*/
+typedef struct {
+ f2l_svg_fill_pattern_t *fp; /**< Fill pattern. */
+ double ts; /**< Text size. */
+ double lw; /**< Line width. */
+ double lsv; /**< Line style value. */
+ unsigned long sn; /**< Style number. */
+ int tf; /**< Text font. */
+ int flags; /**< Flags, see @ref svgstyleflags. */
+ int sr; /**< Stroke color red. */
+ int sg; /**< Stroke color green. */
+ int sb; /**< Stroke color blue. */
+ int fr; /**< Fill color red. */
+ int fg; /**< Fill color green. */
+ int fb; /**< Fill color blue. */
+ int ls; /**< Line style. */
+ int al; /**< Text align. */
+ int lc; /**< Line cap. */
+ int lj; /**< Line join. */
+} f2l_svg_style_t;
+
+
+
+/** Complete collection of style information for an SVG object.
+*/
+typedef struct {
+ dk3_sto_t *sPatterns; /**< Storage for fill patterns. */
+ dk3_sto_it_t *iPatterns; /**< Iterator through fill patterns storage. */
+ dk3_sto_t *sStyles; /**< Storage for object styles. */
+ dk3_sto_it_t *iStyles; /**< Iterator through object styles storage. */
+ unsigned long nPatterns; /**< Number of patterns in storage. */
+ unsigned long nStyles; /**< Number of styles in storage. */
+ int *psFontsUsed; /**< Flag for 35 PS fonts, used or not. */
+ int ec; /**< Error code. */
+} f2l_svg_t;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Compare two fill pattern structures.
+ @param l Left fill pattern structure.
+ @param r Right fill pattern structure.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+int
+f2lsvgst_compare_pattern(void const *l, void const *r, int cr);
+
+/** Compare two object styles.
+ @param l Left object.
+ @param r Right object.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+int
+f2lsvgst_compare_object_styles(void const *l, void const *r, int cr);
+
+/** Create new SVG structure.
+ @param app Application structure for diagnostics.
+ @return Pointer to new structure on success, NULL on error.
+*/
+f2l_svg_t *
+f2lsvgst_new_app(dk3_app_t *app);
+
+/** Delete SVG structure.
+ @param psvg Structure to delete.
+*/
+void
+f2lsvgst_delete(f2l_svg_t *psvg);
+
+/** Retrieve error code for last error and reset error code.
+ @param psvg SVG structure to retrieve error for.
+*/
+int
+f2lsvgst_get_error_code(f2l_svg_t *psvg);
+
+/** Create fill pattern structure, allocate memory.
+ @param psvg Pointer to SVG structure.
+ @return Pointer to new structure on success, NULL on error.
+*/
+f2l_svg_fill_pattern_t *
+f2lsvgst_pattern_new(f2l_svg_t *psvg);
+
+/** Destroy fill pattern structure, release memory.
+ @param pa Structure to release.
+*/
+void
+f2lsvgst_pattern_delete(f2l_svg_fill_pattern_t *pa);
+
+/** Create object style structure, allocate memory.
+ @param psvg Pointer to SVG structure.
+ @return Pointer to new structure on success, NULL on error.
+*/
+f2l_svg_style_t *
+f2lsvgst_style_new(f2l_svg_t *psvg);
+
+/** Destroy object style structure, release memory.
+ @param st Structure to release.
+*/
+void
+f2lsvgst_style_delete(f2l_svg_style_t *st);
+
+/** Initialize style structure.
+ @param st Style structure to initialize.
+*/
+void
+f2lsvgst_style_initialize(f2l_svg_style_t *st);
+
+/** Add new pattern to SVG structure if necessary.
+ @param psvg SVG structure to modify.
+ @param src New pattern.
+ @return Pointer to new or existing pattern on success, NULL on error.
+*/
+f2l_svg_fill_pattern_t *
+f2lsvgst_pattern_add(f2l_svg_t *psvg, f2l_svg_fill_pattern_t *src);
+
+/** Add new style to SVG structure if necessary.
+ @param psvg SVG structure to modify.
+ @param src New style.
+ @return Pointer to new or existing style on success, NULL on error.
+*/
+f2l_svg_style_t *
+f2lsvgst_style_add(f2l_svg_t *psvg, f2l_svg_style_t *src);
+
+/** Set font for style.
+ @param psvg SVG style collection.
+ @param pst SVG style to modify.
+ @param ps Flag: PS font (1) or LaTeX font (0).
+ @param tf Text font (PS font or LaTeX font, depending on ps).
+ @param ts Text size.
+*/
+void
+f2lsvgst_style_set_text(
+ f2l_svg_t *psvg,
+ f2l_svg_style_t *pst,
+ int ps,
+ int tf,
+ double ts
+);
+
+/** Set text align for a style.
+ @param pst SVG style to modify.
+ @param al New text alignment value.
+*/
+void
+f2lsvgst_style_set_text_align(f2l_svg_style_t *pst, int al);
+
+/** Set line width for strokes.
+ @param pst Style to modify.
+ @param lw New line width.
+*/
+void
+f2lsvgst_style_set_line_width(
+ f2l_svg_style_t *pst,
+ double lw
+);
+
+/** Set line style for strokes.
+ @param pst Style to modify.
+ @param ls New line style.
+ @param lsv Style value (gap and segment length).
+*/
+void
+f2lsvgst_style_set_line_style(
+ f2l_svg_style_t *pst,
+ int ls,
+ double lsv
+);
+
+/** Set line color for strokes.
+ @param pst Style to modify.
+ @param r Red.
+ @param g Green.
+ @param b Blue.
+*/
+void
+f2lsvgst_style_set_line_color(
+ f2l_svg_style_t *pst,
+ int r,
+ int g,
+ int b
+);
+
+/** Set fill color.
+ @param pst Style to modify.
+ @param r Red.
+ @param g Green.
+ @param b Blue.
+*/
+void
+f2lsvgst_style_set_fill_color(
+ f2l_svg_style_t *pst,
+ int r,
+ int g,
+ int b
+);
+
+/** Set fill pattern.
+ @param psvg SVG structure to modify.
+ @param pst Style to modify.
+ @param ppat Pattern for fill operations.
+ @return 1 on success, 0 on error.
+*/
+int
+f2lsvgst_style_set_pattern(
+ f2l_svg_t *psvg,
+ f2l_svg_style_t *pst,
+ f2l_svg_fill_pattern_t *ppat
+);
+
+/** Set line cap for a style.
+ @param pst SVG style to modify.
+ @param lc New line cap value.
+*/
+void
+f2lsvgst_style_set_text_line_cap(f2l_svg_style_t *pst, int lc);
+
+/** Set line join for a style.
+ @param pst SVG style to modify.
+ @param lj New line joint style.
+*/
+void
+f2lsvgst_style_set_text_line_join(f2l_svg_style_t *pst, int lj);
+
+/** Check whether any PS font is used in an SVG style collection.
+ @param psvg SVG style collection.
+ @return 1 if any PS font is in use, 0 otherwise.
+*/
+int
+f2lsvgst_any_ps_font_used(f2l_svg_t *psvg);
+
+/** Write all patterns used to the SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+*/
+void
+f2lsvgst_write_patterns(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg
+);
+
+/** Write pattern ID.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+void
+f2lsvgst_pattern_id(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+);
+
+/** Write styles to output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+*/
+void
+f2lsvgst_write_styles(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg
+);
+
+/** Write style ID.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pst Style.
+*/
+void
+f2lsvgst_style_id(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_style_t *pst
+);
+
+/** Write style information for current object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pobj Current object in processing.
+*/
+void
+f2lsvgst_write_style_for_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *pobj
+);
+
+/** Write pattern ID.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern used for current object.
+*/
+void
+f2lsvgst_write_pattern_id(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+);
+
+/** Write style ID.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pst Style used by current object.
+*/
+void
+f2lsvgst_write_style_id(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_style_t *pst
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "f2lsvgst.h"
+
+
+
+$!trace-include
+
+
+
+/** Keywords used by the module.
+*/
+static char const * const f2lsvgst_c8_kw[] = {
+$!string-table
+#
+# 0: Newline.
+#
+\n
+#
+# 1
+#
+svg:
+#
+# 2
+#
+<
+#
+# 3
+#
+pattern
+#
+# 4
+#
+/
+#
+# 5
+#
+>
+#
+# 6
+#
+<
+#
+# 7
+#
+ id="
+#
+# 8
+#
+p
+#
+# 9
+#
+" x="0" y="0" width="%g" height="%g"\npatternUnits="userSpaceOnUse"\n>\n
+#
+# 10
+#
+rect
+#
+# 11
+#
+ x="0" y="0" width="%g" height="%g"\n
+#
+# 12
+#
+style="fill: #%02X%02X%02X; stroke: none;"\n
+#
+# 13
+#
+/>\n
+#
+# 14
+#
+ style="stroke: none; fill: #%02X%02X%02X;"\n
+#
+# 15
+#
+points="0,0 0.9,0 7.2,3.64 7.2,4.16 6.3,4.16 0,0.52"
+#
+# 16
+#
+points="0,3.64 0.9,4.16 0,4.16"
+#
+# 17
+#
+points="6.3,0 7.2,0.52 7.2,0"
+#
+# 18
+#
+polyline
+#
+# 19 20 21
+#
+points="0,4.16 0.9,4.16 7.2,0.52 7.2,0 6.3,0 0,3.64"
+points="0,0.52 0.9,0 0,0"
+points="6.3,4.16 7.2,4.16 7.2,3.64"
+#
+# 22
+#
+style="fill: none; stroke: #%02X%02X%02X; stroke-width: 0.9; stroke-linecap: round;"
+#
+# 23 24
+#
+points="0,0 7.2,4.16"
+points="0,4.16 7.2,0"
+#
+# 25 26 27
+#
+points="0,0 0.64,0 10.18,9.54 10.18,10.18 9.54,10.18 0,0.64"
+points="0,9.54 0.64,10.18 0,10.18"
+points="9.54,0 10.18,0.64 10.18,0"
+#
+# 28 29 30
+#
+points="0,10.18 0.64,10.18 10.18,0.64 10.18,0 9.54,0 0,9.54"
+points="0,0.64 0.64,0 0,0"
+points="9.54,10.18 10.18,10.18 10.18,9.54"
+#
+# 31 32
+#
+points="0,0 10.18,10.18"
+points="0,10.18 10.18,0"
+#
+# 33 34 35 36 37 38 39
+#
+points="3.6,0 3.6,7.2"
+points="18,0 18,7.2"
+points="10.8,7.2 10.8,14.4"
+points="25.2,7.2 25.2,14.4"
+points="0,0 28.8,0"
+points="0,14.4 28.8,14.4"
+points="0,7.2 28.8,7.2"
+#
+# 40 41 42 43 44 45 46
+#
+points="0,3.6 7.2,3.6"
+points="0,18 7.2,18"
+points="7.2,10.8 14.4,10.8"
+points="7.2,25.2 14.4,25.2"
+points="0,0 0,28.8"
+points="7.2,0 7.2,28.8"
+points="14.4,0 14.4,28.8"
+#
+# 47 48
+#
+points="0,0 3.6,0"
+points="0,3.6 3.6,3.6"
+#
+# 49 50
+#
+points="0,0 0,3.6"
+points="3.6,0 3.6,3.6"
+#
+# 51
+#
+polygon
+#
+# 52
+#
+points="0,0 0,3.6 3.6,3.6 3.6,0"
+#
+# 53 54 55 56 57 58 59 60 61
+#
+points="0.45,7.2 3.15,0"
+points="4.05,14.4 6.75,7.2"
+points="7.65,21.6 10.35,14.4"
+points="11.25,28.8 13.95,21.6"
+points="0,0 14.4,0"
+points="0,7.2 14.4,7.2"
+points="0,14.4 14.4,14.4"
+points="0,21.6 14.4,21.6"
+points="0,28.8 14.4,28.8"
+#
+# 62 63 64 65 66 67 68 69 70
+#
+points="0,0 3.6,7.2"
+points="10.8,7.2 14.4,14.4"
+points="7.2,14.4 10.8,21.6"
+points="3.6,21.6 7.2,28.8"
+points="0,0 14.4,0"
+points="0,7.2 14.4,7.2"
+points="0,14.4 14.4,14.4"
+points="0,21.6 14.4,21.6"
+points="0,28.8 14.4,28.8"
+#
+# 71 72 73 74 75 76 77 78 79
+#
+points="0,10.8 7.2,14.4"
+points="7.2,7.2 14.4,10.8"
+points="14.4,3.6 21.6,7.2"
+points="21.6,0 28.8,3.6"
+points="0,0 0,14.4"
+points="7.2,0 7.2,14.4"
+points="14.4,0 14.4,14.4"
+points="21.6,0 21.6,14.4"
+points="28.8,0 28.8,14.4"
+#
+# 80 81 82 83 84 85 86 87 88
+#
+points="0,14.4 7.2,10.8"
+points="7.2,3.6 14.4,0"
+points="14.4,7.2 21.6,3.6"
+points="21.6,10.8 28.8,7.2"
+points="0,0 0,14.4"
+points="7.2,0 7.2,14.4"
+points="14.4,0 14.4,14.4"
+points="21.6,0 21.6,14.4"
+points="28.8,0 28.8,14.4"
+#
+# 89
+#
+path
+#
+# 90 91 92 93 94
+#
+d="M0,0A9 9 0 0 0 14.54,0"
+d="M0,7.4A9 9 0 0 0 7.27,3.7"
+d="M7.27,3.7A9 9 0 0 0 14.54,7.4"
+d="M0,0A9 9 0 0 0 7.27,-3.7"
+d="M7.27,-3.7A9 9 0 0 0 14.54,0"
+#
+# 95 96 97 98 99
+#
+d="M0,0A3.6 3.6 0 0 0 7.2,0"
+d="M0,7.2A3.6 3.6 0 0 0 3.6,3.6"
+d="M3.6,3.6A3.6 3.6 0 0 0 7.2,7.2"
+d="M0,0A3.6 3.6 0 0 0 3.6,-3.6"
+d="M3.6,-3.6A3.6 3.6 0 0 0 7.2,0"
+#
+# 100
+#
+circle
+#
+# 101
+#
+style="fill: none; stroke: #%02X%02X%02X; stroke-width: 0.9;"
+#
+# 102
+#
+ cx="7.2" cy="7.2" r="7.2"
+#
+# 103 104 105 106
+#
+points="3.6,0 0,6.24 3.6,12.47 10.8,12.47 14.4,6.24 10.8,0"
+points="14.4,6.24 21.6,6.24"
+points="21.6,6.24 25.2,0"
+points="21.6,6.24 25.2,12.47"
+#
+# 107 108
+#
+points="0,4.22 4.22,0 10.18,0 14.4,4.22
+14.4,10.18 10.18,14.4 4.22,14.4 0,10.18"
+#
+# 109
+#
+points="0,1.8 3.6,5.4 7.2,1.8"
+#
+# 110
+#
+points="1.8,0 5.4,3.6 1.8,7.2"
+#
+# 111
+#
+s
+#
+# 112
+#
+.
+#
+# 113
+#
+ {\n
+#
+# 114
+#
+}\n
+#
+# 115
+#
+font-family: "
+#
+# 116
+#
+",serif;\n
+#
+# 117
+#
+",sans-serif;\n
+#
+# 118
+#
+",monospace;\n
+#
+# 119
+#
+font-style: normal;\n
+#
+# 120
+#
+font-style: italic;\n
+#
+# 121
+#
+font-style: oblique;\n
+#
+# 122
+#
+font-weight: %d;\n
+#
+# 123 124 125
+#
+font-family: serif;\n
+font-family: sans-serif;\n
+font-family: monospace;\n
+#
+# 126 127
+#
+font-style: normal;\n
+font-style: italic;\n
+#
+# 128 129
+#
+font-weight: normal;\n
+font-weight: bold;\n
+#
+# 130
+#
+font-size: %gpt;\n
+#
+# 131 132 133
+#
+text-anchor: start;\n
+text-anchor: middle;\n
+text-anchor: end;\n
+#
+# 134 135
+#
+fill: url(#
+);\nfillrule: evenodd;\n
+#
+# 136
+#
+fill: #%02X%02X%02X;\nfillrule: evenodd;\n
+#
+# 137
+#
+fill: none;\n
+#
+# 138
+#
+stroke: #%02X%02X%02X;\n
+#
+# 139
+#
+stroke-width: %g;\n
+#
+# 140 141 142
+#
+stroke-linecap: square;\n
+stroke-linecap: round;\n
+stroke-linecap: butt;\n
+#
+# 143 144 145
+#
+stroke-linejoin: bevel;\n
+stroke-linejoin: round;\n
+stroke-linejoin: miter;\n
+#
+# 146 147
+#
+stroke-dasharray:
+;\n
+#
+# 148
+#
+none
+#
+# 149 150 151 152
+#
+%g,%g
+%g,%g,%g,%g
+%g,%g,%g,%g,%g,%g
+%g,%g,%g,%g,%g,%g,%g,%g
+#
+# 153 154 155 156
+#
+font-family="'
+',serif"\n
+',sans-serif"\n
+',monospace"\n
+#
+# 157 158
+#
+font-style="oblique"\n
+font-style="italic"\n
+#
+# 159
+#
+font-weight="%d"\n
+#
+# 160
+#
+font-size="%gpt"\n
+#
+# 161 162 163
+#
+font-family="serif"\n
+font-family="sans-serif"\n
+font-family="monospace"\n
+#
+# 164
+#
+font-weight="bold"\n
+#
+# 165 166
+#
+text-anchor="middle"\n
+text-anchor="end"\n
+#
+# 167 168
+#
+fill="url(#
+)"\n
+#
+# 169
+#
+fill="#%02X%02X%02X"\n
+#
+# 170
+#
+fill="none"\n
+#
+# 171
+#
+stroke="#%02X%02X%02X"\n
+#
+# 172
+#
+stroke-width="%g"\n
+#
+# 173 174 175 176
+#
+stroke-dasharray="%g,%g"\n
+stroke-dasharray="%g,%g,%g,%g"\n
+stroke-dasharray="%g,%g,%g,%g,%g,%g"\n
+stroke-dasharray="%g,%g,%g,%g,%g,%g,%g,%g"\n
+#
+# 177 178
+#
+stroke-linecap="square"\n
+stroke-linecap="round"\n
+#
+# 179 180
+#
+stroke-linejoin="bevel"\n
+stroke-linejoin="round"\n
+#
+# 181 182
+#
+class="
+"\n
+#
+# 183
+#
+fill: #%02X%02X%02X;\n
+#
+# 184
+#
+fill="#%02X%02X%02X"\nfillrule="evenodd"\n
+#
+# 185 186
+#
+stroke-miterlimit: 20;\n
+stroke-miterlimit="20"\n
+#
+# 187 188
+#
+","
+','
+$!end
+};
+
+
+
+/** Compare two integer values.
+ @param x Left value.
+ @param y Right value.
+ @return Comparison result.
+*/
+int
+f2lsvgst_compare_int(int x, int y)
+{
+ int back = 0;
+ $? "+ f2lsvgst_compare_int %d %d", x, y
+ if(x > y) {
+ back = 1;
+ } else {
+ if(x < y) {
+ back = -1;
+ }
+ } $? "- f2lsvgst_compare_int %d", back
+ return back;
+}
+
+
+
+int
+f2lsvgst_compare_pattern(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ f2l_svg_fill_pattern_t const *pl;
+ f2l_svg_fill_pattern_t const *pr;
+ if(l) {
+ if(r) {
+ pl = (f2l_svg_fill_pattern_t const *)l;
+ pr = (f2l_svg_fill_pattern_t const *)r;
+ back = f2lsvgst_compare_int(pl->fn, pr->fn);
+ if(0 == back) {
+ back = f2lsvgst_compare_int(pl->sr, pr->sr);
+ if(0 == back) {
+ back = f2lsvgst_compare_int(pl->sg, pr->sg);
+ if(0 == back) {
+ back = f2lsvgst_compare_int(pl->sb, pr->sb);
+ if(0 == back) {
+ back = f2lsvgst_compare_int(pl->fr, pr->fr);
+ if(0 == back) {
+ back = f2lsvgst_compare_int(pl->fg, pr->fg);
+ if(0 == back) {
+ back = f2lsvgst_compare_int(pl->fb, pr->fb);
+ }
+ }
+ }
+ }
+ }
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+int
+f2lsvgst_compare_object_styles(void const *l, void const *r, int cr)
+{
+ f2l_svg_style_t const *pl;
+ f2l_svg_style_t const *pr;
+ int back = 0;
+ $? "+ f2lsvgst_compare_object_styles"
+ if(l) {
+ if(r) {
+ pl = (f2l_svg_style_t const *)l;
+ pr = (f2l_svg_style_t const *)r;
+ /* Stroke color.
+ */ $? ". by stroke color"
+ if((pl->flags) & DK3_SVG_FLAGS_COLOR_STROKE) {
+ if((pr->flags) & DK3_SVG_FLAGS_COLOR_STROKE) {
+ back = f2lsvgst_compare_int(pl->sr, pr->sr);
+ $? ". %d", back
+ if(0 == back) {
+ back = f2lsvgst_compare_int(pl->sg, pr->sg);
+ $? ". %d", back
+ if(0 == back) {
+ back = f2lsvgst_compare_int(pl->sb, pr->sb);
+ $? ". %d", back
+ }
+ }
+ } else {
+ back = 1; $? ". 1"
+ }
+ } else {
+ if((pr->flags) & DK3_SVG_FLAGS_COLOR_STROKE) {
+ back = -1; $? ". -1"
+ }
+ }
+ /* Line width.
+ */
+ if(0 == back) { $? ". by line width"
+ if((pl->flags) & DK3_SVG_FLAGS_LINEWIDTH) {
+ if((pr->flags) & DK3_SVG_FLAGS_LINEWIDTH) {
+ if(pl->lw > (pr->lw + 1.0e-6)) {
+ back = 1; $? ". 1"
+ } else {
+ if(pr->lw > (pl->lw + 1.0e-6)) {
+ back = -1; $? ". -1"
+ }
+ }
+ } else {
+ back = 1; $? ". 1"
+ }
+ } else {
+ if((pr->flags) & DK3_SVG_FLAGS_LINEWIDTH) {
+ back = -1; $? ". -1"
+ }
+ }
+ }
+ /* Line cap.
+ */
+ if(0 == back) { $? ". by line cap"
+ if((pl->flags) & DK3_SVG_FLAGS_LINE_CAP) {
+ if((pr->flags) & DK3_SVG_FLAGS_LINE_CAP) {
+ back = f2lsvgst_compare_int(pl->lc, pr->lc);
+ $? ". %d", back
+ } else {
+ back = 1; $? ". 1"
+ }
+ } else {
+ if((pr->flags) & DK3_SVG_FLAGS_LINE_CAP) {
+ back = -1; $? ". -1"
+ }
+ }
+ }
+ /* Line join.
+ */
+ if(0 == back) { $? ". by line join"
+ if((pl->flags) & DK3_SVG_FLAGS_LINE_JOIN) {
+ if((pr->flags) & DK3_SVG_FLAGS_LINE_JOIN) {
+ back = f2lsvgst_compare_int(pl->lj, pr->lj);
+ $? ". %d", back
+ } else {
+ back = 1; $? ". 1"
+ }
+ } else {
+ if((pr->flags) & DK3_SVG_FLAGS_LINE_JOIN) {
+ back = -1; $? ". -1"
+ }
+ }
+ }
+ /* Line style.
+ */
+ if(0 == back) { $? ". by line style"
+ if((pl->flags) & DK3_SVG_FLAGS_LINESTYLE) {
+ if((pr->flags) & DK3_SVG_FLAGS_LINESTYLE) {
+ if(pl->ls > pr->ls) {
+ back = 1; $? ". 1"
+ } else {
+ if(pr->ls > pl->ls) {
+ back = -1; $? ". -1"
+ } else {
+ if((0 != pl->ls) && (0 != pr->ls)) {
+ if(pl->lsv > (pr->lsv + 1.0e-6)) {
+ back = 1; $? ". 1"
+ } else {
+ if(pr->lsv > (pl->lsv + 1.0e-6)) {
+ back = -1; $? ". -1"
+ }
+ }
+ }
+ }
+ }
+ } else {
+ back = 1; $? ". 1"
+ }
+ } else {
+ if((pr->flags) & DK3_SVG_FLAGS_LINESTYLE) {
+ back = -1; $? ". -1"
+ }
+ }
+ }
+ /* Fill pattern or fill color.
+ */
+ if(0 == back) { $? ". by filling"
+ if(pl->fp) {
+ if(pr->fp) {
+ back =
+ f2lsvgst_compare_pattern((void *)(pl->fp),(void *)(pr->fp),0);
+ $? ". %d", back
+ } else {
+ back = 1; $? ". 1"
+ }
+ } else {
+ if(pr->fp) {
+ back = -1; $? ". -1"
+ }
+ else {
+ /* Fill color only if both objects do not have fill patterns.
+ */
+ if(0 == back) {
+ if((pl->flags) & DK3_SVG_FLAGS_COLOR_FILL) {
+ if((pr->flags) & DK3_SVG_FLAGS_COLOR_FILL) {
+ back = f2lsvgst_compare_int(pl->fr, pr->fr);
+ $? ". %d", back
+ if(0 == back) {
+ back = f2lsvgst_compare_int(pl->fg, pr->fg);
+ $? ". %d", back
+ if(0 == back) {
+ back = f2lsvgst_compare_int(pl->fb, pr->fb);
+ $? ". %d", back
+ }
+ }
+ } else {
+ back = 1; $? ". 1"
+ }
+ } else {
+ if((pr->flags) & DK3_SVG_FLAGS_COLOR_FILL) {
+ back = -1; $? ". -1"
+ }
+ }
+ }
+ }
+ }
+ }
+ /* Font.
+ */
+ if(0 == back) { $? ". by font"
+ if((pl->flags) & DK3_SVG_FLAGS_FONT) {
+ if((pr->flags) & DK3_SVG_FLAGS_FONT) {
+ if((pl->flags) & DK3_SVG_FLAGS_PS_FONT) {
+ if((pr->flags) & DK3_SVG_FLAGS_PS_FONT) {
+ back = f2lsvgst_compare_int(pl->tf, pr->tf);
+ $? ". %d", back
+ if(0 == back) {
+ if(pl->ts > (pr->ts + 1.0e-6)) {
+ back = 1; $? ". 1"
+ } else {
+ if(pl->ts < (pr->ts - 1.0e-6)) {
+ back = -1; $? ". -1"
+ }
+ }
+ }
+ } else {
+ back = 1; $? ". 1"
+ }
+ } else {
+ if((pr->flags) & DK3_SVG_FLAGS_PS_FONT) {
+ back = -1; $? ". -1"
+ } else {
+ back = f2lsvgst_compare_int(pl->tf, pr->tf);
+ $? ". %d", back
+ if(0 == back) {
+ if(pl->ts > (pr->ts + 1.0e-6)) {
+ back = 1; $? ". 1"
+ } else {
+ if(pl->ts < (pr->ts - 1.0e-6)) {
+ back = -1; $? ". -1"
+ }
+ }
+ }
+ }
+ }
+ } else {
+ back = 1; $? ". 1"
+ }
+ } else {
+ if((pr->flags) & DK3_SVG_FLAGS_FONT) {
+ back = -1; $? ". -1"
+ }
+ }
+ }
+ /* Text align.
+ */
+ if(0 == back) { $? ". by text align"
+ if((pl->flags) & DK3_SVG_FLAGS_TEXT_ALIGN) {
+ if((pr->flags) & DK3_SVG_FLAGS_TEXT_ALIGN) {
+ back = f2lsvgst_compare_int(pl->al, pr->al);
+ $? ". %d", back
+ } else {
+ back = 1; $? ". 1"
+ }
+ } else {
+ if((pr->flags) & DK3_SVG_FLAGS_TEXT_ALIGN) {
+ back = -1; $? ". -1"
+ }
+ }
+ }
+ } else { $? ". 1"
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1; $? ". -1"
+ }
+ } $? "- f2lsvgst_compare_object_styles %d", back
+ return back;
+}
+
+
+
+void
+f2lsvgst_pattern_delete(f2l_svg_fill_pattern_t *pa)
+{
+ $? "+ f2lsvgst_pattern_delete PTR=%d", TR_IPTR(pa)
+ if(pa) {
+ $? ". pa = %lu %d %d %d %d %d %d %d", pa->pn, pa->fn, pa->sr, pa->sg, pa->sb, pa->fr, pa->fg, pa->fb
+ }
+ dk3_delete(pa);
+ $? "- f2lsvgst_pattern_delete"
+}
+
+
+
+f2l_svg_fill_pattern_t *
+f2lsvgst_pattern_new(f2l_svg_t *psvg)
+{
+ f2l_svg_fill_pattern_t *back = NULL;
+ $? "+ f2lsvgst_pattern_new PTR=%d", TR_IPTR(psvg)
+ if(psvg) {
+ back = dk3_new(f2l_svg_fill_pattern_t,1);
+ if(back) {
+ back->pn = 0UL;
+ back->fn = 0;
+ back->sr = 0; back->sg = 0; back->sb = 0;
+ back->fr = 0; back->fg = 0; back->fb = 0;
+ } else {
+ psvg->ec = DK3_ERROR_MEMORY;
+ }
+ } $? "- f2lsvgst_pattern_new PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+void
+f2lsvgst_style_initialize(f2l_svg_style_t *st)
+{
+ $? "+ f2lsvgst_style_initialize PTR=%d", TR_IPTR(st)
+ if(st) {
+ /* 2013-01-25: Same order as in typedef makes completeness checking easier.
+ */
+ st->fp = NULL;
+ st->ts = 0.0;
+ st->lw = 0.0;
+ st->lsv = 0.0;
+ st->sn = 0UL;
+ st->tf = 0;
+ st->flags = 0;
+ st->sr = 0; st->sg = 0; st->sb = 0;
+ st->fr = 0; st->fg = 0; st->fb = 0;
+ st->ls = 0;
+ st->al = 0;
+ st->lc = 0;
+ st->lj = 0;
+ } $? "- f2lsvgst_style_initialize"
+}
+
+
+#if 0
+/** Report style contents.
+ @param pst SVG style to report.
+*/
+static
+void
+f2lsvgst_style_report(f2l_svg_style_t *pst)
+{
+ FILE *tf;
+ tf = dktrace_file();
+ if(tf) {
+ if((pst->flags) & DK3_SVG_FLAGS_COLOR_STROKE) {
+ fprintf(tf, "Stroke: #%02X%02X%02X\n", pst->sr, pst->sg, pst->sb);
+ }
+ if((pst->flags) & DK3_SVG_FLAGS_LINEWIDTH) {
+ fprintf(tf, "Line width: %g\n", pst->lw);
+ }
+ if((pst->flags) & DK3_SVG_FLAGS_LINESTYLE) {
+ fprintf(tf, "Line style: %d %g\n", pst->ls, pst->lsv);
+ }
+ if((pst->flags) & DK3_SVG_FLAGS_LINE_CAP) {
+ fprintf(tf, "Line cap: %d\n", pst->lc);
+ }
+ if((pst->flags) & DK3_SVG_FLAGS_LINE_JOIN) {
+ fprintf(tf, "Line join: %d\n", pst->lj);
+ }
+ if(pst->fp) {
+ fprintf(tf, "Fill: pattern\n");
+ } else {
+ if((pst->flags) & DK3_SVG_FLAGS_COLOR_FILL) {
+ fprintf(tf, "Fill: #%02X%02X%02X", pst->fr, pst->fg, pst->fb);
+ }
+ }
+ if((pst->flags) & DK3_SVG_FLAGS_FONT) {
+ fprintf(tf, "Font: PS=%d NUMBER=%d SIZE=%g\n", (((pst->flags) & DK3_SVG_FLAGS_PS_FONT) ? 1 : 0), pst->tf, pst->ts);
+ }
+ if((pst->flags) & DK3_SVG_FLAGS_TEXT_ALIGN) {
+ fprintf(tf, "Text align: %d\n", pst->al);
+ }
+ }
+}
+#endif
+
+
+void
+f2lsvgst_style_delete(f2l_svg_style_t *st)
+{
+ $? "+ f2lsvgst_style_delete"
+ if(st) {
+ f2lsvgst_style_initialize(st);
+ dk3_delete(st);
+ } $? "- f2lsvgst_style_delete"
+}
+
+
+
+f2l_svg_style_t *
+f2lsvgst_style_new(f2l_svg_t *psvg)
+{
+ f2l_svg_style_t *back = NULL;
+ $? "+ f2lsvgst_style_new PTR=%d", TR_IPTR(psvg)
+ if(psvg) {
+ back = dk3_new(f2l_svg_style_t,1);
+ if(back) {
+ f2lsvgst_style_initialize(back);
+ } else {
+ psvg->ec = DK3_ERROR_MEMORY;
+ }
+ } $? "- f2lsvgst_style_new PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+void
+f2lsvgst_delete(f2l_svg_t *psvg)
+{
+ f2l_svg_style_t *st;
+ f2l_svg_fill_pattern_t *pa;
+ $? "+ f2lsvgst_delete"
+ if(psvg) {
+ dk3_release(psvg->psFontsUsed);
+ if(psvg->sStyles) {
+ if(psvg->iStyles) {
+ dk3sto_it_reset(psvg->iStyles);
+ while(NULL != (st = (f2l_svg_style_t *)dk3sto_it_next(psvg->iStyles))) {
+ f2lsvgst_style_delete(st);
+ }
+ dk3sto_it_close(psvg->iStyles);
+ }
+ dk3sto_close(psvg->sStyles);
+ } psvg->sStyles = NULL; psvg->iStyles = NULL;
+ if(psvg->sPatterns) {
+ if(psvg->iPatterns) {
+ dk3sto_it_reset(psvg->iPatterns);
+ do {
+ pa = (f2l_svg_fill_pattern_t *)dk3sto_it_next(psvg->iPatterns);
+ if(pa) {
+ f2lsvgst_pattern_delete(pa);
+ }
+ } while(pa);
+ dk3sto_it_close(psvg->iPatterns);
+ }
+ dk3sto_close(psvg->sPatterns);
+ } psvg->sPatterns = NULL; psvg->iPatterns = NULL;
+ dk3_delete(psvg);
+ } $? "- f2lsvgst_delete"
+}
+
+
+
+f2l_svg_t *
+f2lsvgst_new_app(dk3_app_t *app)
+{
+ f2l_svg_t *back = NULL;
+ size_t i;
+ int ok = 0;
+ $? "+ f2lsvgst_new_app PTR=%d", TR_IPTR(app)
+ back = dk3_new_app(f2l_svg_t,1,app);
+ if(back) {
+ back->sPatterns = NULL;
+ back->iPatterns = NULL;
+ back->sStyles = NULL;
+ back->iStyles = NULL;
+ back->nPatterns = 0UL;
+ back->nStyles = 0UL;
+ back->psFontsUsed = NULL;
+ back->ec = 0;
+ back->sPatterns = dk3sto_open_app(app);
+ if(back->sPatterns) {
+ dk3sto_set_comp(back->sPatterns, f2lsvgst_compare_pattern, 0);
+ back->iPatterns = dk3sto_it_open(back->sPatterns);
+ if(back->iPatterns) {
+ back->sStyles = dk3sto_open_app(app);
+ if(back->sStyles) {
+ dk3sto_set_comp(back->sStyles, f2lsvgst_compare_object_styles, 0);
+ back->iStyles = dk3sto_it_open(back->sStyles);
+ if(back->iStyles) {
+ back->psFontsUsed = dk3_new_app(int,35,app);
+ if(back) {
+ for(i = 0; i < 35; i++) { (back->psFontsUsed)[i] = 0; }
+ ok = 1;
+ }
+ }
+ }
+ }
+ }
+ if(!(ok)) {
+ f2lsvgst_delete(back);
+ back = NULL;
+ }
+ } $? "- f2lsvgst_new_app PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+int
+f2lsvgst_get_error_code(f2l_svg_t *psvg)
+{
+ int back = 0;
+ if(psvg) {
+ back = psvg->ec;
+ psvg->ec = 0;
+ } $? "= f2lsvgst_get_error_code %d", back
+ return back;
+}
+
+
+f2l_svg_fill_pattern_t *
+f2lsvgst_pattern_add(f2l_svg_t *psvg, f2l_svg_fill_pattern_t *src)
+{
+ f2l_svg_fill_pattern_t *back = NULL;
+ $? "+ f2lsvgst_pattern_add PTR=%d PTR=%d", TR_IPTR(psvg), TR_IPTR(src)
+ if((psvg) && (src)) {
+ back = (f2l_svg_fill_pattern_t *)dk3sto_it_find_like(
+ psvg->iPatterns, (void *)src, 0
+ );
+ if(!(back)) {
+ if(0UL != (1UL + psvg->nPatterns)) {
+ back = f2lsvgst_pattern_new(psvg);
+ if(back) {
+ dk3mem_cpy((void *)back, (void *)src, sizeof(f2l_svg_fill_pattern_t));
+ if(dk3sto_add(psvg->sPatterns, (void *)back)) {
+ back->pn = psvg->nPatterns;
+ psvg->nPatterns += 1UL;
+ } else {
+ f2lsvgst_pattern_delete(back);
+ back = NULL;
+ }
+ }
+ } else {
+ psvg->ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ }
+ } $? "- f2lsvgst_pattern_add PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+f2l_svg_style_t *
+f2lsvgst_style_add(f2l_svg_t *psvg, f2l_svg_style_t *src)
+{
+ f2l_svg_style_t *back = NULL;
+ $? "+ f2lsvgst_style_add PTR=%d PTR=%d", TR_IPTR(psvg), TR_IPTR(src)
+ if((psvg) && (src)) {
+ back = (f2l_svg_style_t *)dk3sto_it_find_like(
+ psvg->iStyles, (void *)src, 0
+ );
+ if(!(back)) { $? ". must create new style"
+ if(0UL != (1UL + psvg->nStyles)) { $? ". no overflow"
+ back = f2lsvgst_style_new(psvg);
+ if(back) { $? ". allocated"
+ dk3mem_cpy((void *)back, (void *)src, sizeof(f2l_svg_style_t));
+ if(dk3sto_add(psvg->sStyles, (void *)back)) {
+ back->sn = psvg->nStyles;
+ psvg->nStyles += 1UL;
+ } else {
+ f2lsvgst_style_delete(back);
+ back = NULL;
+ }
+ } else { $? "! memory"
+ }
+ } else {
+ psvg->ec = DK3_ERROR_MATH_OVERFLOW;
+ }
+ } else { $? ". style already found"
+ }
+ } $? "- f2lsvgst_style_add PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+int
+f2lsvgst_style_set_pattern(
+ f2l_svg_t *psvg,
+ f2l_svg_style_t *pst,
+ f2l_svg_fill_pattern_t *ppat
+)
+{
+ int back = 0;
+ $? "+ f2lsvgst_style_set_pattern PTRS= %d %d %d", TR_IPTR(psvg), TR_IPTR(pst), TR_IPTR(ppat)
+ if((psvg) && (pst) && (ppat)) {
+ if(!(pst->fp)) {
+ pst->fp = f2lsvgst_pattern_add(psvg, ppat);
+ if(pst->fp) {
+ back = 1;
+ }
+ }
+ } $? "- f2lsvgst_style_set_pattern %d", back
+ return back;
+}
+
+
+
+void
+f2lsvgst_style_set_text(
+ f2l_svg_t *psvg,
+ f2l_svg_style_t *pst,
+ int ps,
+ int tf,
+ double ts
+)
+{
+ $? "+ f2lsvgst_style_set_text PTR=%d PTR=%d %d %lg", TR_IPTR(psvg), TR_IPTR(pst), tf, ts
+ if(pst) {
+ pst->tf = tf;
+ pst->ts = ts;
+ pst->flags |= (DK3_SVG_FLAGS_FONT);
+ if(ps) {
+ pst->flags |= (DK3_SVG_FLAGS_PS_FONT);
+ } else {
+ pst->flags &= (~(DK3_SVG_FLAGS_PS_FONT));
+ }
+ }
+ if((psvg) && (ps)) {
+ if((0 <= tf) && (tf < 35)) {
+ (psvg->psFontsUsed)[tf] = 1;
+ }
+ } $? "- f2lsvgst_style_set_text"
+}
+
+
+
+void
+f2lsvgst_style_set_line_width(
+ f2l_svg_style_t *pst,
+ double lw
+)
+{
+ $? "+ f2lsvgst_style_set_line_width PTR=%d %lg", TR_IPTR(pst), lw
+ if(pst) {
+ pst->lw = lw;
+ pst->flags |= (DK3_SVG_FLAGS_LINEWIDTH);
+ } $? "- f2lsvgst_style_set_line_width"
+}
+
+
+
+void
+f2lsvgst_style_set_line_style(
+ f2l_svg_style_t *pst,
+ int ls,
+ double lsv
+)
+{
+ $? "+ f2lsvgst_style_set_line_style PTR=%d %d %lg", TR_IPTR(pst), ls, lsv
+ if(pst) {
+ pst->ls = ls; pst->lsv = lsv;
+ pst->flags|= (DK3_SVG_FLAGS_LINESTYLE);
+ } $? "- f2lsvgst_style_set_line_style"
+}
+
+
+
+void
+f2lsvgst_style_set_line_color(
+ f2l_svg_style_t *pst,
+ int r,
+ int g,
+ int b
+)
+{
+ $? "+ f2lsvgst_style_set_line_color PTR=%d %d %d %d", TR_IPTR(pst), r, g, b
+ if(pst) {
+ pst->sr = r; pst->sg = g; pst->sb = b;
+ pst->flags |= (DK3_SVG_FLAGS_COLOR_STROKE);
+ } $? "- f2lsvgst_style_set_line_color"
+}
+
+
+
+void
+f2lsvgst_style_set_fill_color(
+ f2l_svg_style_t *pst,
+ int r,
+ int g,
+ int b
+)
+{
+ $? "+ f2lsvgst_style_set_fill_color PTR=%d %d %d %d", TR_IPTR(pst), r, g, b
+ if(pst) {
+ pst->fr = r; pst->fg = g; pst->fb = b;
+ pst->flags |= (DK3_SVG_FLAGS_COLOR_FILL);
+ } $? "- f2lsvgst_style_set_fill_color"
+}
+
+
+
+int
+f2lsvgst_any_ps_font_used(f2l_svg_t *psvg)
+{
+ size_t i;
+ int back = 0;
+ for(i = 0; i < 35; i++) {
+ if((psvg->psFontsUsed)[i]) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+void
+f2lsvgst_style_set_text_align(f2l_svg_style_t *pst, int al)
+{
+ if(pst) {
+ pst->al = al;
+ pst->flags |= (DK3_SVG_FLAGS_TEXT_ALIGN);
+ }
+}
+
+
+
+void
+f2lsvgst_style_set_text_line_cap(f2l_svg_style_t *pst, int lc)
+{
+ if(pst) {
+ pst->lc = lc;
+ pst->flags |= (DK3_SVG_FLAGS_LINE_CAP);
+ }
+}
+
+
+
+void
+f2lsvgst_style_set_text_line_join(f2l_svg_style_t *pst, int lj)
+{
+ if(pst) {
+ pst->lj = lj;
+ pst->flags |= (DK3_SVG_FLAGS_LINE_JOIN);
+ }
+}
+
+
+
+/** Write one tag name, either with or without svg: prefix.
+ @param job Job structure.
+ @param ind Index of tag name in f2lsvgst_c8_kw.
+*/
+static
+void
+f2lsvgst_tag(
+ f2l_job_t *job,
+ size_t ind
+)
+{
+ if(job->fragment) {
+ fputs(f2lsvgst_c8_kw[1], job->of1);
+ }
+ fputs(f2lsvgst_c8_kw[ind], job->of1);
+}
+
+
+
+/** Write a number as string.
+ @param job Job structure.
+ @param current Current value.
+ @param max Maximum value.
+*/
+static
+void
+f2lsvgst_write_id(
+ f2l_job_t *job,
+ unsigned long current,
+ unsigned long max
+)
+{
+ char buf[128];
+ char *ptr;
+ size_t maxlgt;
+ size_t lgt;
+ size_t i;
+
+ sprintf(buf, "%lu", max);
+ maxlgt = strlen(buf);
+ sprintf(buf, "%lu", current);
+ lgt = strlen(buf);
+ for(i = lgt; i < maxlgt; i++) {
+ fputc('A', job->of1);
+ }
+ ptr = buf;
+ while(*ptr) {
+ switch(*ptr) {
+ case '0': { *ptr = 'A'; } break;
+ case '1': { *ptr = 'B'; } break;
+ case '2': { *ptr = 'C'; } break;
+ case '3': { *ptr = 'D'; } break;
+ case '4': { *ptr = 'E'; } break;
+ case '5': { *ptr = 'F'; } break;
+ case '6': { *ptr = 'G'; } break;
+ case '7': { *ptr = 'H'; } break;
+ case '8': { *ptr = 'I'; } break;
+ case '9': { *ptr = 'J'; } break;
+ }
+ ptr++;
+ }
+ fputs(buf, job->of1);
+}
+
+
+
+void
+f2lsvgst_write_pattern_id(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ $? "+ f2lsvgst_pattern_id %lu %lu", pat->pn, psvg->nPatterns
+ fputs(f2lsvgst_c8_kw[8], job->of1);
+ f2lsvgst_write_id(job, pat->pn, psvg->nPatterns);
+ $? "- f2lsvgst_pattern_id"
+}
+
+
+
+void
+f2lsvgst_write_style_id(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_style_t *pst
+)
+{
+ $? "+ f2lsvgst_style_id %lu %lu", pst->sn, psvg->nStyles
+ fputs(f2lsvgst_c8_kw[111], job->of1);
+ f2lsvgst_write_id(job, pst->sn, psvg->nStyles);
+ $? "- f2lsvgst_style_id"
+}
+
+
+/** Write opening pattern tag.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+ @param w Pattern width.
+ @param h Pattern height.
+*/
+static
+void
+f2lsvgst_write_opening_pattern_tag(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat,
+ double w,
+ double h
+)
+{
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[7], job->of1);
+ f2lsvgst_write_pattern_id(job, drw, psvg, pat);
+ fprintf(job->of1, f2lsvgst_c8_kw[9], w, h);
+}
+
+
+
+/** Write opening pattern tag.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+ @param w Pattern width.
+ @param h Pattern height.
+*/
+static
+void
+f2lsvgst_pattern_background(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat,
+ double w,
+ double h
+)
+{
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ f2lsvgst_tag(job, 10);
+ fprintf(job->of1, f2lsvgst_c8_kw[11], w, h);
+ fprintf(job->of1, f2lsvgst_c8_kw[12], pat->fr, pat->fg, pat->fb);
+ fputs(f2lsvgst_c8_kw[13], job->of1);
+}
+
+
+
+/** Draw foreground line in pattern.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+ @param ind Index of points line in f2lsvgst_c8_kw.
+*/
+static
+void
+f2lsvgst_pattern_foreground_line(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat,
+ size_t ind
+)
+{
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ f2lsvgst_tag(job, 18);
+ fprintf(job->of1, f2lsvgst_c8_kw[14], pat->sr, pat->sg, pat->sb);
+ fputs(f2lsvgst_c8_kw[ind], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+ fputs(f2lsvgst_c8_kw[13], job->of1);
+}
+
+
+
+/** Draw foreground line in pattern.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+ @param ind Index of points line in f2lsvgst_c8_kw.
+*/
+static
+void
+f2lsvgst_pattern_foreground_line_lcr(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat,
+ size_t ind
+)
+{
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ f2lsvgst_tag(job, 18);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+ fprintf(job->of1, f2lsvgst_c8_kw[22], pat->sr, pat->sg, pat->sb);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+ fputs(f2lsvgst_c8_kw[ind], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+ fputs(f2lsvgst_c8_kw[13], job->of1);
+}
+
+
+
+/** Draw foreground polygon in pattern.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+ @param ind Index of points line in f2lsvgst_c8_kw.
+*/
+static
+void
+f2lsvgst_pattern_foreground_polygon_lcr(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat,
+ size_t ind
+)
+{
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ f2lsvgst_tag(job, 51);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+ fprintf(job->of1, f2lsvgst_c8_kw[22], pat->sr, pat->sg, pat->sb);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+ fputs(f2lsvgst_c8_kw[ind], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+ fputs(f2lsvgst_c8_kw[13], job->of1);
+}
+
+
+
+/** Draw foreground polygon in pattern, 2 data lines.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+ @param i1 Index of points line in f2lsvgst_c8_kw.
+ @param i2 Index of points line 2.
+*/
+static
+void
+f2lsvgst_pattern_foreground_polygon_lcr_l2(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat,
+ size_t i1,
+ size_t i2
+)
+{
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ f2lsvgst_tag(job, 51);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+ fprintf(job->of1, f2lsvgst_c8_kw[22], pat->sr, pat->sg, pat->sb);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+ fputs(f2lsvgst_c8_kw[i1], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+ fputs(f2lsvgst_c8_kw[i2], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+ fputs(f2lsvgst_c8_kw[13], job->of1);
+}
+
+
+
+/** Draw foreground path in pattern
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+ @param ind Index of data line in f2lsvgst_c8_kw.
+*/
+static
+void
+f2lsvgst_pattern_foreground_path_lcr(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat,
+ size_t ind
+)
+{
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ f2lsvgst_tag(job, 89);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+ fprintf(job->of1, f2lsvgst_c8_kw[22], pat->sr, pat->sg, pat->sb);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+ fputs(f2lsvgst_c8_kw[ind], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+ fputs(f2lsvgst_c8_kw[13], job->of1);
+}
+
+
+
+/** Draw foreground circle in pattern
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_foreground_circle_lcr(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ f2lsvgst_tag(job, 100);
+ fputs(f2lsvgst_c8_kw[102], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+ fprintf(job->of1, f2lsvgst_c8_kw[101], pat->sr, pat->sg, pat->sb);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+ fputs(f2lsvgst_c8_kw[13], job->of1);
+}
+
+
+
+/** Write pattern 41 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_41(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 7.2, 4.16);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 7.2, 4.16);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 15);
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 16);
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 17);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 42 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_42(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 7.2, 4.16);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 7.2, 4.16);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 19);
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 20);
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 21);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 43 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_43(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 7.2, 4.16);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 7.2, 4.16);
+ /* Pattern contents 2: lines.
+ */
+#if 1
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 23);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 24);
+#else
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 15);
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 16);
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 17);
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 19);
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 20);
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 21);
+#endif
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 44 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_44(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 10.18, 10.18);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 10.18, 10.18);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 25);
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 26);
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 27);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 45 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_45(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 10.18, 10.18);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 10.18, 10.18);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 28);
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 29);
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 30);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 46 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_46(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 10.18, 10.18);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 10.18, 10.18);
+ /* Pattern contents 2: lines.
+ */
+#if 1
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 31);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 32);
+#else
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 25);
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 26);
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 27);
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 28);
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 29);
+ f2lsvgst_pattern_foreground_line(job, drw, psvg, pat, 30);
+#endif
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 47 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_47(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 28.8, 14.4);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 28.8, 14.4);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 33);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 34);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 35);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 36);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 37);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 38);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 39);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 48 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_48(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 14.4, 28.8);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 14.4, 28.8);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 40);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 41);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 42);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 43);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 44);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 45);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 46);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 49 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_49(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 3.6, 3.6);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 3.6, 3.6);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 47);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 48);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 50 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_50(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 3.6, 3.6);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 3.6, 3.6);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 49);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 50);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 51 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_51(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 3.6, 3.6);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 3.6, 3.6);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_polygon_lcr(job, drw, psvg, pat, 52);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 52 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_52(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 14.4, 28.8);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 14.4, 28.8);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 53);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 54);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 55);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 56);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 57);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 58);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 59);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 60);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 61);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 53 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_53(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 14.4, 28.8);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 14.4, 28.8);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 62);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 63);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 64);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 65);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 66);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 67);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 68);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 69);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 70);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 54 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_54(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 28.8, 14.4);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 28.8, 14.4);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 71);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 72);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 73);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 74);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 75);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 76);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 77);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 78);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 79);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 55 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_55(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 28.8, 14.4);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 28.8, 14.4);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 80);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 81);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 82);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 83);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 84);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 85);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 86);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 87);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 88);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 56 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_56(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 14.54, 7.4);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 14.54, 7.4);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_path_lcr(job, drw, psvg, pat, 90);
+ f2lsvgst_pattern_foreground_path_lcr(job, drw, psvg, pat, 91);
+ f2lsvgst_pattern_foreground_path_lcr(job, drw, psvg, pat, 92);
+ f2lsvgst_pattern_foreground_path_lcr(job, drw, psvg, pat, 93);
+ f2lsvgst_pattern_foreground_path_lcr(job, drw, psvg, pat, 94);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 57 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_57(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 7.2, 7.2);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 7.2, 7.2);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_path_lcr(job, drw, psvg, pat, 95);
+ f2lsvgst_pattern_foreground_path_lcr(job, drw, psvg, pat, 96);
+ f2lsvgst_pattern_foreground_path_lcr(job, drw, psvg, pat, 97);
+ f2lsvgst_pattern_foreground_path_lcr(job, drw, psvg, pat, 98);
+ f2lsvgst_pattern_foreground_path_lcr(job, drw, psvg, pat, 99);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 58 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_58(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 14.4, 14.4);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 14.4, 14.4);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_circle_lcr(job, drw, psvg, pat);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 59 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_59(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 21.6, 12.47);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 21.6, 12.47);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_polygon_lcr(job, drw, psvg, pat, 103);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 104);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 105);
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 106);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 60 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_60(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 14.4, 14.4);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 14.4, 14.4);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_polygon_lcr_l2(job, drw, psvg, pat, 107, 108);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 61 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_61(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 7.2, 7.2);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 7.2, 7.2);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 109);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write pattern 62 definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_pattern_62(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ /* Opening pattern tag.
+ */
+ f2lsvgst_write_opening_pattern_tag(job, drw, psvg, pat, 7.2, 7.2);
+ /* Pattern contents 1: background.
+ */
+ f2lsvgst_pattern_background(job, drw, psvg, pat, 7.2, 7.2);
+ /* Pattern contents 2: lines.
+ */
+ f2lsvgst_pattern_foreground_line_lcr(job, drw, psvg, pat, 110);
+ /* Close pattern tag.
+ */
+ fputs(f2lsvgst_c8_kw[6], job->of1);
+ fputs(f2lsvgst_c8_kw[4], job->of1);
+ f2lsvgst_tag(job, 3);
+ fputs(f2lsvgst_c8_kw[5], job->of1);
+ fputs(f2lsvgst_c8_kw[0], job->of1);
+}
+
+
+
+/** Write one pattern definition to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+static
+void
+f2lsvgst_write_one_pattern(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+)
+{
+ switch(pat->fn) {
+ case 41: {
+ f2lsvgst_pattern_41(job, drw, psvg, pat);
+ } break;
+ case 42: {
+ f2lsvgst_pattern_42(job, drw, psvg, pat);
+ } break;
+ case 43: {
+ f2lsvgst_pattern_43(job, drw, psvg, pat);
+ } break;
+ case 44: {
+ f2lsvgst_pattern_44(job, drw, psvg, pat);
+ } break;
+ case 45: {
+ f2lsvgst_pattern_45(job, drw, psvg, pat);
+ } break;
+ case 46: {
+ f2lsvgst_pattern_46(job, drw, psvg, pat);
+ } break;
+ case 47: {
+ f2lsvgst_pattern_47(job, drw, psvg, pat);
+ } break;
+ case 48: {
+ f2lsvgst_pattern_48(job, drw, psvg, pat);
+ } break;
+ case 49: {
+ f2lsvgst_pattern_49(job, drw, psvg, pat);
+ } break;
+ case 50: {
+ f2lsvgst_pattern_50(job, drw, psvg, pat);
+ } break;
+ case 51: {
+ f2lsvgst_pattern_51(job, drw, psvg, pat);
+ } break;
+ case 52: {
+ f2lsvgst_pattern_52(job, drw, psvg, pat);
+ } break;
+ case 53: {
+ f2lsvgst_pattern_53(job, drw, psvg, pat);
+ } break;
+ case 54: {
+ f2lsvgst_pattern_54(job, drw, psvg, pat);
+ } break;
+ case 55: {
+ f2lsvgst_pattern_55(job, drw, psvg, pat);
+ } break;
+ case 56: {
+ f2lsvgst_pattern_56(job, drw, psvg, pat);
+ } break;
+ case 57: {
+ f2lsvgst_pattern_57(job, drw, psvg, pat);
+ } break;
+ case 58: {
+ f2lsvgst_pattern_58(job, drw, psvg, pat);
+ } break;
+ case 59: {
+ f2lsvgst_pattern_59(job, drw, psvg, pat);
+ } break;
+ case 60: {
+ f2lsvgst_pattern_60(job, drw, psvg, pat);
+ } break;
+ case 61: {
+ f2lsvgst_pattern_61(job, drw, psvg, pat);
+ } break;
+ case 62: {
+ f2lsvgst_pattern_62(job, drw, psvg, pat);
+ } break;
+ }
+}
+
+
+
+void
+f2lsvgst_write_patterns(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg
+)
+{
+ f2l_svg_fill_pattern_t *pat;
+ if((psvg->sPatterns) && (psvg->iPatterns)) {
+ dk3sto_it_reset(psvg->iPatterns);
+ do {
+ pat = (f2l_svg_fill_pattern_t *)dk3sto_it_next(psvg->iPatterns);
+ if(pat) {
+ f2lsvgst_write_one_pattern(job, drw, psvg, pat);
+ }
+ } while(pat);
+ }
+}
+
+
+
+/** Write one style to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pst Style definition to write.
+*/
+static
+void
+f2lsvgst_write_one_style(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_style_t *pst
+)
+{
+ char const * const *rffn; /* Replacement font family name. */
+ double ts; /* Text size. */
+ double gw; /* Gap width in line styles. */
+ int ff; /* Font family */
+
+ if(pst->tf < 0) { pst->tf = 0; }
+ if(pst->tf > 34) { pst->tf = 34; }
+ fputs(f2lsvgst_c8_kw[112], job->of1);
+ f2lsvgst_write_style_id(job, drw, psvg, pst);
+ fputs(f2lsvgst_c8_kw[113], job->of1);
+ if((pst->flags) & DK3_SVG_FLAGS_FONT) {
+ if((pst->flags) & DK3_SVG_FLAGS_PS_FONT) {
+ /* Font family
+ */
+ fputs(f2lsvgst_c8_kw[115], job->of1);
+ fputs(dk3font_get_svg_family(pst->tf), job->of1);
+ if(job->otherfonts) {
+ /* PS family name.
+ */
+ fputs(f2lsvgst_c8_kw[187], job->of1);
+ fputs(dk3font_get_ps_family(pst->tf), job->of1);
+ /* Replacement family names.
+ */
+ rffn = dk3font_get_replacement_families(pst->tf);
+ while(*rffn) {
+ fputs(f2lsvgst_c8_kw[187], job->of1);
+ fputs(*rffn, job->of1);
+ rffn++;
+ }
+ }
+ ff = dk3font_get_svg_features(pst->tf);
+ switch(ff & DK3_FONT_FAMILY) {
+ case DK3_FONT_TYPEWRITER: {
+ fputs(f2lsvgst_c8_kw[118], job->of1);
+ } break;
+ case DK3_FONT_SANS_SERIF: {
+ fputs(f2lsvgst_c8_kw[117], job->of1);
+ } break;
+ default: {
+ fputs(f2lsvgst_c8_kw[116], job->of1);
+ } break;
+ }
+ /* Font style
+ */
+ if(ff & DK3_FONT_OBLIQUE) {
+ fputs(f2lsvgst_c8_kw[121], job->of1);
+ } else {
+ if(ff & DK3_FONT_ITALIC) {
+ fputs(f2lsvgst_c8_kw[120], job->of1);
+ } else {
+#if 0
+ /* 2013-01-27: This is the default.
+ */
+ fputs(f2lsvgst_c8_kw[119], job->of1);
+#endif
+ }
+ }
+ /* Font weight
+ */
+ ff = dk3font_get_svg_font_weight(pst->tf);
+ fprintf(job->of1, f2lsvgst_c8_kw[122], ff);
+ } else {
+ /* Font family, style, weight
+ */
+ switch(pst->tf) {
+ case 5: { /* Typewriter */
+ fputs(f2lsvgst_c8_kw[125], job->of1);
+#if 0
+ /* 2013-01-27: This is the default.
+ */
+ fputs(f2lsvgst_c8_kw[126], job->of1);
+ fputs(f2lsvgst_c8_kw[128], job->of1);
+#endif
+ } break;
+ case 4: { /* Sans-serif */
+ fputs(f2lsvgst_c8_kw[124], job->of1);
+#if 0
+ /* 2013-01-27: This is the default.
+ */
+ fputs(f2lsvgst_c8_kw[126], job->of1);
+ fputs(f2lsvgst_c8_kw[128], job->of1);
+#endif
+ } break;
+ case 3: { /* Italic serif */
+ fputs(f2lsvgst_c8_kw[123], job->of1);
+ fputs(f2lsvgst_c8_kw[127], job->of1);
+#if 0
+ /* 2013-01-27: This is the default.
+ */
+ fputs(f2lsvgst_c8_kw[128], job->of1);
+#endif
+ } break;
+ case 2: { /* Bold serif */
+ fputs(f2lsvgst_c8_kw[123], job->of1);
+#if 0
+ /* 2013-01-27: This is the default.
+ */
+ fputs(f2lsvgst_c8_kw[126], job->of1);
+#endif
+ fputs(f2lsvgst_c8_kw[129], job->of1);
+ } break;
+ default: { /* Default font (serif) */
+ fputs(f2lsvgst_c8_kw[123], job->of1);
+#if 0
+ /* 2013-01-27: This is the default.
+ */
+ fputs(f2lsvgst_c8_kw[126], job->of1);
+ fputs(f2lsvgst_c8_kw[128], job->of1);
+#endif
+ } break;
+ }
+ }
+ /* Font size
+ */
+ ts = pst->ts;
+ if(0.0 < job->nts) {
+ ts = ts * job->nts;
+ }
+ fprintf(job->of1, f2lsvgst_c8_kw[130], ts);
+ }
+ /* Text align
+ */
+ if((pst->flags) & DK3_SVG_FLAGS_TEXT_ALIGN) {
+ switch(pst->al) {
+ case 2: {
+ fputs(f2lsvgst_c8_kw[133], job->of1);
+ } break;
+ case 1: {
+ fputs(f2lsvgst_c8_kw[132], job->of1);
+ } break;
+ default: {
+#if 0
+ /* 2013-01-27: This is the default.
+ */
+ fputs(f2lsvgst_c8_kw[131], job->of1);
+#endif
+ } break;
+ }
+ }
+ /* Fill pattern or color fill
+ */
+ if(pst->fp) {
+ fputs(f2lsvgst_c8_kw[134], job->of1);
+ f2lsvgst_write_pattern_id(job, drw, psvg, pst->fp);
+ fputs(f2lsvgst_c8_kw[135], job->of1);
+ } else {
+ if((pst->flags) & DK3_SVG_FLAGS_COLOR_FILL) {
+ if((pst->flags) & DK3_SVG_FLAGS_FONT) {
+ fprintf(job->of1, f2lsvgst_c8_kw[183], pst->fr, pst->fg, pst->fb);
+ } else {
+ fprintf(job->of1, f2lsvgst_c8_kw[136], pst->fr, pst->fg, pst->fb);
+ }
+ } else { /* No fill */
+ fputs(f2lsvgst_c8_kw[137], job->of1);
+ }
+ }
+ /* Stroke color stroke
+ */
+ if((pst->flags) & DK3_SVG_FLAGS_COLOR_STROKE) {
+ fprintf(job->of1, f2lsvgst_c8_kw[138], pst->sr, pst->sg, pst->sb);
+ }
+ /* Stroke linewidth stroke-width
+ */
+ if((pst->flags) & DK3_SVG_FLAGS_LINEWIDTH) {
+ fprintf(job->of1, f2lsvgst_c8_kw[139], pst->lw);
+ }
+ /* Stroke linestyle stroke-dasharray
+ */
+ if((pst->flags) & DK3_SVG_FLAGS_LINESTYLE) {
+ if((pst->flags) & DK3_SVG_FLAGS_LINEWIDTH) {
+ if(0 != pst->ls) {
+ gw = f2lto_find_gap_length(job, pst->lw, pst->lsv);
+ fputs(f2lsvgst_c8_kw[146], job->of1);
+ switch(pst->ls) {
+ case DK3_FIG_LS_DASH_TRIPLE_DOTTED: {
+ fprintf(
+ job->of1,
+ f2lsvgst_c8_kw[152],
+ pst->lsv, gw, pst->lw, gw, pst->lw, gw,
+ pst->lw, gw
+ );
+ } break;
+ case DK3_FIG_LS_DASH_DOUBLE_DOTTED: {
+ fprintf(
+ job->of1,
+ f2lsvgst_c8_kw[151],
+ pst->lsv, gw, pst->lw, gw, pst->lw, gw
+ );
+ } break;
+ case DK3_FIG_LS_DASH_DOTTED: {
+ fprintf(
+ job->of1,
+ f2lsvgst_c8_kw[150],
+ pst->lsv, gw, pst->lw, gw
+ );
+ } break;
+ case DK3_FIG_LS_DOTTED: {
+ fprintf(
+ job->of1,
+ f2lsvgst_c8_kw[149],
+ pst->lw, gw
+ );
+ } break;
+ case DK3_FIG_LS_DASHED: {
+ fprintf(
+ job->of1,
+ f2lsvgst_c8_kw[149],
+ pst->lsv, gw
+ );
+ } break;
+ default: {
+ fputs(f2lsvgst_c8_kw[148], job->of1);
+ } break;
+ }
+ fputs(f2lsvgst_c8_kw[147], job->of1);
+ }
+ }
+ }
+ /* Linecap stroke-linecap
+ */
+ if((pst->flags) & DK3_SVG_FLAGS_LINE_CAP) {
+ if(DK3_FIG_LC_BUTT != pst->lc) {
+ switch(pst->lc) {
+ case DK3_FIG_LC_PROJECTING: {
+ fputs(f2lsvgst_c8_kw[140], job->of1);
+ } break;
+ case DK3_FIG_LC_ROUND: {
+ fputs(f2lsvgst_c8_kw[141], job->of1);
+ } break;
+ default: {
+#if 0
+ /* 2013-01-27: This is the default.
+ */
+ fputs(f2lsvgst_c8_kw[142], job->of1);
+#endif
+ } break;
+ }
+ }
+ }
+ /* Linejoin stroke-linejoin
+ */
+ if((pst->flags) & DK3_SVG_FLAGS_LINE_JOIN) {
+ switch(pst->lj) {
+ case DK3_FIG_LJ_BEVEL: {
+ fputs(f2lsvgst_c8_kw[143], job->of1);
+ } break;
+ case DK3_FIG_LJ_ROUND: {
+ fputs(f2lsvgst_c8_kw[144], job->of1);
+ } break;
+ default: {
+#if 0
+ /* 2013-01-27: This is the default.
+ */
+ fputs(f2lsvgst_c8_kw[145], job->of1);
+#endif
+ if(job->miterlim) {
+ fputs(f2lsvgst_c8_kw[185], job->of1);
+ }
+ } break;
+ }
+ }
+ /* End
+ */
+ fputs(f2lsvgst_c8_kw[114], job->of1);
+}
+
+
+
+/** Write attributes for one style to SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pst Style definition to write.
+*/
+static
+void
+f2lsvgst_write_attributes_for_one_style(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_style_t *pst
+)
+{
+ char const * const *rffn; /* Replacement font family names. */
+ int ff; /* Font family and flags. */
+ double ts; /* Font size. */
+ double gw; /* Gap width in line styles. */
+
+ if((pst->flags) & DK3_SVG_FLAGS_FONT) {
+ ff = dk3font_get_svg_features(pst->tf);
+ ts = pst->ts;
+ if(0.0 < job->nts) {
+ ts = ts * job->nts;
+ }
+ /* Font family, font style, font weight, text size.
+ */
+ if((pst->flags) & DK3_SVG_FLAGS_PS_FONT) {
+ fputs(f2lsvgst_c8_kw[153], job->of1);
+ fputs(dk3font_get_svg_family(pst->tf), job->of1);
+ if(job->otherfonts) {
+ /* PS family name.
+ */
+ fputs(f2lsvgst_c8_kw[188], job->of1);
+ fputs(dk3font_get_ps_family(pst->tf), job->of1);
+ /* Replacement family names.
+ */
+ rffn = dk3font_get_replacement_families(pst->tf);
+ while(*rffn) {
+ fputs(f2lsvgst_c8_kw[188], job->of1);
+ fputs(*rffn, job->of1);
+ rffn++;
+ }
+ }
+ switch(ff & DK3_FONT_FAMILY) {
+ case DK3_FONT_TYPEWRITER: {
+ fputs(f2lsvgst_c8_kw[156], job->of1);
+ } break;
+ case DK3_FONT_SANS_SERIF: {
+ fputs(f2lsvgst_c8_kw[155], job->of1);
+ } break;
+ default: {
+ fputs(f2lsvgst_c8_kw[154], job->of1);
+ } break;
+ }
+ if(ff & DK3_FONT_OBLIQUE) {
+ fputs(f2lsvgst_c8_kw[157], job->of1);
+ } else {
+ if(ff & DK3_FONT_ITALIC) {
+ fputs(f2lsvgst_c8_kw[158], job->of1);
+ }
+ }
+ fprintf(
+ job->of1, f2lsvgst_c8_kw[159], dk3font_get_svg_font_weight(pst->tf)
+ );
+ } else {
+ switch(pst->tf) {
+ case 5: { /* typewriter */
+ fputs(f2lsvgst_c8_kw[163], job->of1);
+ } break;
+ case 4: { /* sans-serif */
+ fputs(f2lsvgst_c8_kw[162], job->of1);
+ } break;
+ case 3: { /* serif italic */
+ fputs(f2lsvgst_c8_kw[161], job->of1);
+ fputs(f2lsvgst_c8_kw[158], job->of1);
+ } break;
+ case 2: { /* serif bold */
+ fputs(f2lsvgst_c8_kw[161], job->of1);
+ fputs(f2lsvgst_c8_kw[164], job->of1);
+ } break;
+ default: { /* serif */
+ fputs(f2lsvgst_c8_kw[161], job->of1);
+ } break;
+ }
+ }
+ fprintf(job->of1, f2lsvgst_c8_kw[160], ts);
+ /* Text align.
+ */
+ if((pst->flags) & DK3_SVG_FLAGS_TEXT_ALIGN) {
+ switch(pst->al) {
+ case 2: {
+ fputs(f2lsvgst_c8_kw[166], job->of1);
+ } break;
+ case 1: {
+ fputs(f2lsvgst_c8_kw[165], job->of1);
+ } break;
+ }
+ }
+ }
+ /* Fill pattern or color.
+ */
+ if(pst->fp) {
+ fputs(f2lsvgst_c8_kw[167], job->of1);
+ f2lsvgst_write_pattern_id(job, drw, psvg, pst->fp);
+ fputs(f2lsvgst_c8_kw[168], job->of1);
+ } else {
+ if((pst->flags) & DK3_SVG_FLAGS_COLOR_FILL) {
+ if((pst->flags) & DK3_SVG_FLAGS_FONT) {
+ fprintf(job->of1, f2lsvgst_c8_kw[169], pst->fr, pst->fg, pst->fb);
+ } else {
+ fprintf(job->of1, f2lsvgst_c8_kw[184], pst->fr, pst->fg, pst->fb);
+ }
+ } else {
+ fputs(f2lsvgst_c8_kw[170], job->of1);
+ }
+ }
+ /* Stroke color
+ */
+ if((pst->flags) & DK3_SVG_FLAGS_COLOR_STROKE) {
+ fprintf(job->of1, f2lsvgst_c8_kw[171], pst->sr, pst->sg, pst->sb);
+ }
+ /* Stroke linewidth.
+ */
+ if((pst->flags) & DK3_SVG_FLAGS_LINEWIDTH) {
+ fprintf(job->of1, f2lsvgst_c8_kw[172], pst->lw);
+ }
+ /* Stroke linestyle.
+ */
+ if((pst->flags) & DK3_SVG_FLAGS_LINESTYLE) {
+ if((pst->flags) & DK3_SVG_FLAGS_LINEWIDTH) {
+ gw = f2lto_find_gap_length(job, pst->lw, pst->lsv);
+ switch(pst->ls) {
+ case DK3_FIG_LS_DASH_TRIPLE_DOTTED: {
+ fprintf(
+ job->of1, f2lsvgst_c8_kw[176],
+ pst->lsv, gw, pst->lw, gw, pst->lw, gw,
+ pst->lw, gw
+ );
+ } break;
+ case DK3_FIG_LS_DASH_DOUBLE_DOTTED: {
+ fprintf(
+ job->of1, f2lsvgst_c8_kw[175],
+ pst->lsv, gw, pst->lw, gw, pst->lw, gw
+ );
+ } break;
+ case DK3_FIG_LS_DASH_DOTTED: {
+ fprintf(
+ job->of1, f2lsvgst_c8_kw[174],
+ pst->lsv, gw, pst->lw, gw
+ );
+ } break;
+ case DK3_FIG_LS_DOTTED: {
+ fprintf(
+ job->of1, f2lsvgst_c8_kw[173],
+ pst->lw, gw
+ );
+ } break;
+ case DK3_FIG_LS_DASHED: {
+ fprintf(
+ job->of1, f2lsvgst_c8_kw[173],
+ pst->lsv, gw
+ );
+ } break;
+ }
+ }
+ }
+ /* Linecap.
+ */
+ if((pst->flags) & DK3_SVG_FLAGS_LINE_CAP) {
+ switch(pst->lc) {
+ case DK3_FIG_LC_PROJECTING: {
+ fputs(f2lsvgst_c8_kw[178], job->of1);
+ } break;
+ case DK3_FIG_LC_ROUND: {
+ fputs(f2lsvgst_c8_kw[177], job->of1);
+ } break;
+ }
+ }
+ /* Linejoin.
+ */
+ if((pst->flags) & DK3_SVG_FLAGS_LINE_JOIN) {
+ switch(pst->lj) {
+ case DK3_FIG_LJ_BEVEL: {
+ fputs(f2lsvgst_c8_kw[180], job->of1);
+ } break;
+ case DK3_FIG_LJ_ROUND: {
+ fputs(f2lsvgst_c8_kw[179], job->of1);
+ } break;
+ default: {
+ if(job->miterlim) {
+ fputs(f2lsvgst_c8_kw[186], job->of1);
+ }
+ } break;
+ }
+ }
+}
+
+
+
+void
+f2lsvgst_write_style_for_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *pobj
+)
+{
+ f2l_svg_style_t *pst;
+ $? "+ f2lsvgst_write_style_for_object"
+ if((job) && (drw) && (psvg) && (pobj)) {
+ pst = (f2l_svg_style_t *)(pobj->dsd);
+ if(pst) { $? ". style"
+ if(job->css) { $? ". css"
+ fputs(f2lsvgst_c8_kw[181], job->of1);
+ f2lsvgst_write_style_id(job, drw, psvg, pst);
+ fputs(f2lsvgst_c8_kw[182], job->of1);
+ } else { $? ". simple attributes"
+ f2lsvgst_write_attributes_for_one_style(job, drw, psvg, pst);
+ }
+ } else { $? "! style"
+ }
+ } else { $? "! args"
+ } $? "- f2lsvgst_write_style_for_object"
+}
+
+
+
+void
+f2lsvgst_write_styles(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg
+)
+{
+ f2l_svg_style_t *pst;
+ if((psvg->sStyles) && (psvg->iStyles)) {
+ dk3sto_it_reset(psvg->iStyles);
+ do {
+ pst = (f2l_svg_style_t *)dk3sto_it_next(psvg->iStyles);
+ if(pst) {
+ f2lsvgst_write_one_style(job, drw, psvg, pst);
+ }
+ } while(pst);
+ }
+}
+
+
+
diff --git a/support/dktools/f2lsvgst.h b/support/dktools/f2lsvgst.h
new file mode 100644
index 0000000000..86b1c17fb6
--- /dev/null
+++ b/support/dktools/f2lsvgst.h
@@ -0,0 +1,445 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: f2lsvgst.ctr
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file f2lsvgst.h Header file for the f2lsvgst module.
+*/
+
+#ifndef F2LSVGST_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define F2LSVGST_H_INCLUDED 1
+
+
+#line 10 "f2lsvgst.ctr"
+
+#include "dk3all.h"
+#include "dk3font.h"
+#include "fig2lat.h"
+#include "f2lsvg.h"
+#include "f2lsvgst.h"
+#include "dk3figto.h"
+
+
+
+/** @defgroup svgstyleflags SVG style flags */
+/**@{*/
+
+/** Stroke color defined.
+*/
+#define DK3_SVG_FLAGS_COLOR_STROKE 1
+
+/** Fill color defined.
+*/
+#define DK3_SVG_FLAGS_COLOR_FILL 2
+
+/** Text align defined.
+*/
+#define DK3_SVG_FLAGS_TEXT_ALIGN 4
+
+/** Font defined.
+*/
+#define DK3_SVG_FLAGS_FONT 8
+
+/** Font is a PS font (LaTeX font otherwise).
+*/
+#define DK3_SVG_FLAGS_PS_FONT 16
+
+/** Line width defined.
+*/
+#define DK3_SVG_FLAGS_LINEWIDTH 32
+
+/** Line style defined.
+*/
+#define DK3_SVG_FLAGS_LINESTYLE 64
+
+/** Line cap defined.
+*/
+#define DK3_SVG_FLAGS_LINE_CAP 128
+
+/** Line join defined.
+*/
+#define DK3_SVG_FLAGS_LINE_JOIN 256
+
+/**@}*/
+
+
+/** Fill pattern.
+*/
+typedef struct {
+ unsigned long pn; /**< Pattern number. */
+ int fn; /**< Fig pattern number 41 - 62. */
+ int sr; /**< Stroke color red. */
+ int sg; /**< Stroke color green. */
+ int sb; /**< Stroke color blue. */
+ int fr; /**< Fill color red. */
+ int fg; /**< Fill color green. */
+ int fb; /**< Fill color blue. */
+} f2l_svg_fill_pattern_t;
+
+
+
+/** SVG object style information.
+*/
+typedef struct {
+ f2l_svg_fill_pattern_t *fp; /**< Fill pattern. */
+ double ts; /**< Text size. */
+ double lw; /**< Line width. */
+ double lsv; /**< Line style value. */
+ unsigned long sn; /**< Style number. */
+ int tf; /**< Text font. */
+ int flags; /**< Flags, see @ref svgstyleflags. */
+ int sr; /**< Stroke color red. */
+ int sg; /**< Stroke color green. */
+ int sb; /**< Stroke color blue. */
+ int fr; /**< Fill color red. */
+ int fg; /**< Fill color green. */
+ int fb; /**< Fill color blue. */
+ int ls; /**< Line style. */
+ int al; /**< Text align. */
+ int lc; /**< Line cap. */
+ int lj; /**< Line join. */
+} f2l_svg_style_t;
+
+
+
+/** Complete collection of style information for an SVG object.
+*/
+typedef struct {
+ dk3_sto_t *sPatterns; /**< Storage for fill patterns. */
+ dk3_sto_it_t *iPatterns; /**< Iterator through fill patterns storage. */
+ dk3_sto_t *sStyles; /**< Storage for object styles. */
+ dk3_sto_it_t *iStyles; /**< Iterator through object styles storage. */
+ unsigned long nPatterns; /**< Number of patterns in storage. */
+ unsigned long nStyles; /**< Number of styles in storage. */
+ int *psFontsUsed; /**< Flag for 35 PS fonts, used or not. */
+ int ec; /**< Error code. */
+} f2l_svg_t;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Compare two fill pattern structures.
+ @param l Left fill pattern structure.
+ @param r Right fill pattern structure.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+int
+f2lsvgst_compare_pattern(void const *l, void const *r, int cr);
+
+/** Compare two object styles.
+ @param l Left object.
+ @param r Right object.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+int
+f2lsvgst_compare_object_styles(void const *l, void const *r, int cr);
+
+/** Create new SVG structure.
+ @param app Application structure for diagnostics.
+ @return Pointer to new structure on success, NULL on error.
+*/
+f2l_svg_t *
+f2lsvgst_new_app(dk3_app_t *app);
+
+/** Delete SVG structure.
+ @param psvg Structure to delete.
+*/
+void
+f2lsvgst_delete(f2l_svg_t *psvg);
+
+/** Retrieve error code for last error and reset error code.
+ @param psvg SVG structure to retrieve error for.
+*/
+int
+f2lsvgst_get_error_code(f2l_svg_t *psvg);
+
+/** Create fill pattern structure, allocate memory.
+ @param psvg Pointer to SVG structure.
+ @return Pointer to new structure on success, NULL on error.
+*/
+f2l_svg_fill_pattern_t *
+f2lsvgst_pattern_new(f2l_svg_t *psvg);
+
+/** Destroy fill pattern structure, release memory.
+ @param pa Structure to release.
+*/
+void
+f2lsvgst_pattern_delete(f2l_svg_fill_pattern_t *pa);
+
+/** Create object style structure, allocate memory.
+ @param psvg Pointer to SVG structure.
+ @return Pointer to new structure on success, NULL on error.
+*/
+f2l_svg_style_t *
+f2lsvgst_style_new(f2l_svg_t *psvg);
+
+/** Destroy object style structure, release memory.
+ @param st Structure to release.
+*/
+void
+f2lsvgst_style_delete(f2l_svg_style_t *st);
+
+/** Initialize style structure.
+ @param st Style structure to initialize.
+*/
+void
+f2lsvgst_style_initialize(f2l_svg_style_t *st);
+
+/** Add new pattern to SVG structure if necessary.
+ @param psvg SVG structure to modify.
+ @param src New pattern.
+ @return Pointer to new or existing pattern on success, NULL on error.
+*/
+f2l_svg_fill_pattern_t *
+f2lsvgst_pattern_add(f2l_svg_t *psvg, f2l_svg_fill_pattern_t *src);
+
+/** Add new style to SVG structure if necessary.
+ @param psvg SVG structure to modify.
+ @param src New style.
+ @return Pointer to new or existing style on success, NULL on error.
+*/
+f2l_svg_style_t *
+f2lsvgst_style_add(f2l_svg_t *psvg, f2l_svg_style_t *src);
+
+/** Set font for style.
+ @param psvg SVG style collection.
+ @param pst SVG style to modify.
+ @param ps Flag: PS font (1) or LaTeX font (0).
+ @param tf Text font (PS font or LaTeX font, depending on ps).
+ @param ts Text size.
+*/
+void
+f2lsvgst_style_set_text(
+ f2l_svg_t *psvg,
+ f2l_svg_style_t *pst,
+ int ps,
+ int tf,
+ double ts
+);
+
+/** Set text align for a style.
+ @param pst SVG style to modify.
+ @param al New text alignment value.
+*/
+void
+f2lsvgst_style_set_text_align(f2l_svg_style_t *pst, int al);
+
+/** Set line width for strokes.
+ @param pst Style to modify.
+ @param lw New line width.
+*/
+void
+f2lsvgst_style_set_line_width(
+ f2l_svg_style_t *pst,
+ double lw
+);
+
+/** Set line style for strokes.
+ @param pst Style to modify.
+ @param ls New line style.
+ @param lsv Style value (gap and segment length).
+*/
+void
+f2lsvgst_style_set_line_style(
+ f2l_svg_style_t *pst,
+ int ls,
+ double lsv
+);
+
+/** Set line color for strokes.
+ @param pst Style to modify.
+ @param r Red.
+ @param g Green.
+ @param b Blue.
+*/
+void
+f2lsvgst_style_set_line_color(
+ f2l_svg_style_t *pst,
+ int r,
+ int g,
+ int b
+);
+
+/** Set fill color.
+ @param pst Style to modify.
+ @param r Red.
+ @param g Green.
+ @param b Blue.
+*/
+void
+f2lsvgst_style_set_fill_color(
+ f2l_svg_style_t *pst,
+ int r,
+ int g,
+ int b
+);
+
+/** Set fill pattern.
+ @param psvg SVG structure to modify.
+ @param pst Style to modify.
+ @param ppat Pattern for fill operations.
+ @return 1 on success, 0 on error.
+*/
+int
+f2lsvgst_style_set_pattern(
+ f2l_svg_t *psvg,
+ f2l_svg_style_t *pst,
+ f2l_svg_fill_pattern_t *ppat
+);
+
+/** Set line cap for a style.
+ @param pst SVG style to modify.
+ @param lc New line cap value.
+*/
+void
+f2lsvgst_style_set_text_line_cap(f2l_svg_style_t *pst, int lc);
+
+/** Set line join for a style.
+ @param pst SVG style to modify.
+ @param lj New line joint style.
+*/
+void
+f2lsvgst_style_set_text_line_join(f2l_svg_style_t *pst, int lj);
+
+/** Check whether any PS font is used in an SVG style collection.
+ @param psvg SVG style collection.
+ @return 1 if any PS font is in use, 0 otherwise.
+*/
+int
+f2lsvgst_any_ps_font_used(f2l_svg_t *psvg);
+
+/** Write all patterns used to the SVG output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+*/
+void
+f2lsvgst_write_patterns(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg
+);
+
+/** Write pattern ID.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern to write.
+*/
+void
+f2lsvgst_pattern_id(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+);
+
+/** Write styles to output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+*/
+void
+f2lsvgst_write_styles(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg
+);
+
+/** Write style ID.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pst Style.
+*/
+void
+f2lsvgst_style_id(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_style_t *pst
+);
+
+/** Write style information for current object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pobj Current object in processing.
+*/
+void
+f2lsvgst_write_style_for_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ dk3_fig_obj_t *pobj
+);
+
+/** Write pattern ID.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pat Pattern used for current object.
+*/
+void
+f2lsvgst_write_pattern_id(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_fill_pattern_t *pat
+);
+
+/** Write style ID.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param psvg SVG style collection.
+ @param pst Style used by current object.
+*/
+void
+f2lsvgst_write_style_id(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ f2l_svg_t *psvg,
+ f2l_svg_style_t *pst
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/f2lto.c b/support/dktools/f2lto.c
new file mode 100644
index 0000000000..dac9ee1518
--- /dev/null
+++ b/support/dktools/f2lto.c
@@ -0,0 +1,1424 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: f2lto.ctr
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file f2lto.c The f2lto module.
+*/
+
+
+#line 262 "f2lto.ctr"
+
+#include "dk3all.h"
+#include "dk3bezcu.h"
+#include "fig2lat.h"
+#include "f2lud.h"
+#include "f2lsvg.h"
+#include "dk3figto.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4vers.h"
+#include "dk3font.h"
+#include "dk3bm.h"
+#include "dk3bmeps.h"
+
+
+
+
+#line 279 "f2lto.ctr"
+
+
+
+/** LaTeX encodings for 0x00-0xFF.
+*/
+static char const * const f2l_tool_l2l_enc[] = {
+/* 000 00 */ "",
+/* 001 01 */ "",
+/* 002 02 */ "",
+/* 003 03 */ "",
+/* 004 04 */ "",
+/* 005 05 */ "",
+/* 006 06 */ "",
+/* 007 07 */ "",
+/* 008 08 */ "",
+/* 009 09 */ "\t",
+/* 010 0a */ "\\\\*",
+/* 011 0b */ "",
+/* 012 0c */ "",
+/* 013 0d */ "",
+/* 014 0e */ "",
+/* 015 0f */ "",
+/* 016 10 */ "",
+/* 017 11 */ "",
+/* 018 12 */ "",
+/* 019 13 */ "",
+/* 020 14 */ "",
+/* 021 15 */ "",
+/* 022 16 */ "",
+/* 023 17 */ "",
+/* 024 18 */ "",
+/* 025 19 */ "",
+/* 026 1a */ "",
+/* 027 1b */ "",
+/* 028 1c */ "",
+/* 029 1d */ "",
+/* 030 1e */ "",
+/* 031 1f */ "",
+/* 032 20 */ " ",
+/* 033 21 */ "!",
+/* 034 22 */ "\\textquotedbl{}",
+/* 035 23 */ "\\#",
+/* 036 24 */ "\\textdollar{}",
+/* 037 25 */ "\\%",
+/* 038 26 */ "\\&",
+/* 039 27 */ "\\textquoteright{}",
+/* 040 28 */ "(",
+/* 041 29 */ ")",
+/* 042 2a */ "\\textasteriskcentered{}",
+/* 043 2b */ "+",
+/* 044 2c */ ",",
+/* 045 2d */ "-",
+/* 046 2e */ ".",
+/* 047 2f */ "/",
+/* 048 30 */ "0",
+/* 049 31 */ "1",
+/* 050 32 */ "2",
+/* 051 33 */ "3",
+/* 052 34 */ "4",
+/* 053 35 */ "5",
+/* 054 36 */ "6",
+/* 055 37 */ "7",
+/* 056 38 */ "8",
+/* 057 39 */ "9",
+/* 058 3a */ ":",
+/* 059 3b */ ";",
+/* 060 3c */ "\\textless{}",
+/* 061 3d */ "=",
+/* 062 3e */ "\\textgreater{}",
+/* 063 3f */ "?",
+/* 064 40 */ "@",
+/* 065 41 */ "A",
+/* 066 42 */ "B",
+/* 067 43 */ "C",
+/* 068 44 */ "D",
+/* 069 45 */ "E",
+/* 070 46 */ "F",
+/* 071 47 */ "G",
+/* 072 48 */ "H",
+/* 073 49 */ "I",
+/* 074 4a */ "J",
+/* 075 4b */ "K",
+/* 076 4c */ "L",
+/* 077 4d */ "M",
+/* 078 4e */ "N",
+/* 079 4f */ "O",
+/* 080 50 */ "P",
+/* 081 51 */ "Q",
+/* 082 52 */ "R",
+/* 083 53 */ "S",
+/* 084 54 */ "T",
+/* 085 55 */ "U",
+/* 086 56 */ "V",
+/* 087 57 */ "W",
+/* 088 58 */ "X",
+/* 089 59 */ "Y",
+/* 090 5a */ "Z",
+/* 091 5b */ "[",
+/* 092 5c */ "\\textbackslash{}",
+/* 093 5d */ "]",
+/* 094 5e */ "\\textasciicircum{}",
+/* 095 5f */ "\\textunderscore{}",
+/* 096 60 */ "\\textasciigrave{}",
+/* 097 61 */ "a",
+/* 098 62 */ "b",
+/* 099 63 */ "c",
+/* 100 64 */ "d",
+/* 101 65 */ "e",
+/* 102 66 */ "f",
+/* 103 67 */ "g",
+/* 104 68 */ "h",
+/* 105 69 */ "i",
+/* 106 6a */ "j",
+/* 107 6b */ "k",
+/* 108 6c */ "l",
+/* 109 6d */ "m",
+/* 110 6e */ "n",
+/* 111 6f */ "o",
+/* 112 70 */ "p",
+/* 113 71 */ "q",
+/* 114 72 */ "r",
+/* 115 73 */ "s",
+/* 116 74 */ "t",
+/* 117 75 */ "u",
+/* 118 76 */ "v",
+/* 119 77 */ "w",
+/* 120 78 */ "x",
+/* 121 79 */ "y",
+/* 122 7a */ "z",
+/* 123 7b */ "\\textbraceleft{}",
+/* 124 7c */ "\\textbar{}",
+/* 125 7d */ "\\textbraceright{}",
+/* 126 7e */ "\\textasciitilde{}",
+/* 127 7f */ "",
+/* 128 80 */ "",
+/* 129 81 */ "",
+/* 130 82 */ "",
+/* 131 83 */ "",
+/* 132 84 */ "",
+/* 133 85 */ "",
+/* 134 86 */ "",
+/* 135 87 */ "",
+/* 136 88 */ "",
+/* 137 89 */ "",
+/* 138 8a */ "",
+/* 139 8b */ "",
+/* 140 8c */ "",
+/* 141 8d */ "",
+/* 142 8e */ "",
+/* 143 8f */ "",
+/* 144 90 */ "",
+/* 145 91 */ "",
+/* 146 92 */ "",
+/* 147 93 */ "",
+/* 148 94 */ "",
+/* 149 95 */ "",
+/* 150 96 */ "",
+/* 151 97 */ "",
+/* 152 98 */ "",
+/* 153 99 */ "",
+/* 154 9a */ "",
+/* 155 9b */ "",
+/* 156 9c */ "",
+/* 157 9d */ "",
+/* 158 9e */ "",
+/* 159 9f */ "",
+/* 160 a0 */ "",
+/* 161 a1 */ "\\textexclamdown{}",
+/* 162 a2 */ "\\textcentoldstyle{}",
+/* 163 a3 */ "\\textstirling{}",
+/* 164 a4 */ "\\textcurrency{}",
+/* 165 a5 */ "\\textyen{}",
+/* 166 a6 */ "\\textbrokenbar{}",
+/* 167 a7 */ "\\textsection{}",
+/* 168 a8 */ "\\textasciidieresis{}",
+/* 169 a9 */ "\\textcopyright{}",
+/* 170 aa */ "\\textordfeminine{}",
+/* 171 ab */ "\\quillemotleft{}",
+/* 172 ac */ "\\textlnot{}",
+/* 173 ad */ "",
+/* 174 ae */ "\\textregistered{}",
+/* 175 af */ "\\textasciimacron{}",
+/* 176 b0 */ "\\textdegree{}",
+/* 177 b1 */ "\\textpm{}",
+/* 178 b2 */ "\\texttwosuperior{}",
+/* 179 b3 */ "\\textthreesuperior{}",
+/* 180 b4 */ "\\textasciiacute{}",
+/* 181 b5 */ "\\textmu{}",
+/* 182 b6 */ "\\P{}",
+/* 183 b7 */ "\\textperiodcentered{}",
+/* 184 b8 */ "\\c{}",
+/* 185 b9 */ "\\textonesuperior{}",
+/* 186 ba */ "\\textordmasculine{}",
+/* 187 bb */ "\\quillemotright{}",
+/* 188 bc */ "\\textonequarter{}",
+/* 189 bd */ "\\textonehalf{}",
+/* 190 be */ "\\textthreequarters{}",
+/* 191 bf */ "?`",
+/* 192 c0 */ "\\`{A}",
+/* 193 c1 */ "\\'{A}",
+/* 194 c2 */ "\\^{A}",
+/* 195 c3 */ "\\~{A}",
+/* 196 c4 */ "\\\"{A}",
+/* 197 c5 */ "\\AA{}",
+/* 198 c6 */ "\\AE{}",
+/* 199 c7 */ "\\c{C}",
+/* 200 c8 */ "\\`{E}",
+/* 201 c9 */ "\\'{E}",
+/* 202 ca */ "\\^{E}",
+/* 203 cb */ "\\\"{E}",
+/* 204 cc */ "\\`{I}",
+/* 205 cd */ "\\'{I}",
+/* 206 ce */ "\\^{I}",
+/* 207 cf */ "\\\"{I}",
+/* 208 d0 */ "\\DH{}",
+/* 209 d1 */ "\\~{N}",
+/* 210 d2 */ "\\`{O}",
+/* 211 d3 */ "\\'{O}",
+/* 212 d4 */ "\\^{O}",
+/* 213 d5 */ "\\~{O}",
+/* 214 d6 */ "\\\"{O}",
+/* 215 d7 */ "\\texttimes{}",
+/* 216 d8 */ "\\O{}",
+/* 217 d9 */ "\\`{U}",
+/* 218 da */ "\\'{U}",
+/* 219 db */ "\\^{U}",
+/* 220 dc */ "\\\"{U}",
+/* 221 dd */ "\\'{Y}",
+/* 222 de */ "\\TH{}",
+/* 223 df */ "\\ss{}",
+/* 224 e0 */ "\\`{a}",
+/* 225 e1 */ "\\'{a}",
+/* 226 e2 */ "\\^{a}",
+/* 227 e3 */ "\\~{a}",
+/* 228 e4 */ "\\\"{a}",
+/* 229 e5 */ "\\aa{}",
+/* 230 e6 */ "\\ae{}",
+/* 231 e7 */ "\\c{c}",
+/* 232 e8 */ "\\`{e}",
+/* 233 e9 */ "\\'{e}",
+/* 234 ea */ "\\^{e}",
+/* 235 eb */ "\\\"{e}",
+/* 236 ec */ "\\`{i}",
+/* 237 ed */ "\\'{i}",
+/* 238 ee */ "\\^{i}",
+/* 239 ef */ "\\\"{i}",
+/* 240 f0 */ "\\dh{}",
+/* 241 f1 */ "\\~{n}",
+/* 242 f2 */ "\\`{o}",
+/* 243 f3 */ "\\'{o}",
+/* 244 f4 */ "\\^{o}",
+/* 245 f5 */ "\\~{o}",
+/* 246 f6 */ "\\\"{o}",
+/* 247 f7 */ "\\textdiv{}",
+/* 248 f8 */ "\\o{}",
+/* 249 f9 */ "\\`{u}",
+/* 250 fa */ "\\'{u}",
+/* 251 fb */ "\\^{u}",
+/* 252 fc */ "\\\"{u}",
+/* 253 fd */ "\\'{y}",
+/* 254 fe */ "\\th{}",
+/* 255 ff */ "\\\"{y}"
+};
+
+
+/** Keywords used by the module.
+*/
+static char const * const f2lto_c8_kw[] = {
+/* 0 */
+"\\begin{picture}(0,0)\n",
+
+/* 1 */
+"\\end{picture}%\n",
+
+/* 2 */
+"\\includegraphics{",
+
+/* 3 */
+"}\n",
+
+/* 4 */
+"\\setlength{\\unitlength}{1bp}%\n",
+
+/* 5 */
+"\\begin{picture}(%ld,%ld)\n",
+
+/* 6 */
+"\\newfont{",
+
+/* 7 */
+"}{",
+
+/* 8 */
+"}%\n",
+
+/* 9 */
+"\\FigToLatFont",
+
+/* 10 */
+"ptmr",
+
+/* 11 */
+" at ",
+
+/* 12 */
+"pt",
+
+/* 13 */
+"\\put(",
+
+/* 14 */
+",",
+
+/* 15 */
+"){",
+
+/* 16 */
+"}",
+
+/* 17 */
+"\\rotatebox{",
+
+/* 18 */
+"\\makebox(0,0)[",
+
+/* 19 */
+"]{",
+
+/* 20 */
+"lb",
+
+/* 21 */
+"b",
+
+/* 22 */
+"rb",
+
+/* 23 */
+"\\smash{",
+
+/* 24 */
+"\\mbox{",
+
+/* 25 */
+"\\color[rgb]{",
+
+/* 26 */
+"\n",
+
+/* 27 */
+"\\reset@font",
+
+/* 28 */
+"\\selectfont",
+
+/* 29 */
+"\\fontsize{",
+
+/* 30 */
+"\\fontfamily{\\rmdefault}",
+
+/* 31 */
+"\\fontfamily{\\sfdefault}",
+
+/* 32 */
+"\\fontfamily{\\ttdefault}",
+
+/* 33 */
+"\\fontseries{\\mddefault}",
+
+/* 34 */
+"\\fontseries{\\bfdefault}",
+
+/* 35 */
+"\\fontshape{\\updefault}",
+
+/* 36 */
+"\\fontshape{\\itdefault}",
+
+/* 37 */
+"\\fontfamily{\\familydefault}",
+
+/* 38 */
+"{",
+
+/* 39 */
+"\\end{document}\n",
+
+/* 40 */
+"\\documentclass[%lgpt]{article}\n",
+
+/* 41 */
+"\\setlength{\\paperwidth}{%ldbp}\n",
+
+/* 42 */
+"\\setlength{\\paperheight}{%ldbp}\n",
+
+/* 43 */
+"\\usepackage{pgfcore}\n",
+
+/* 44 */
+"f2lfonts.tex",
+
+/* 45 */
+"f2lother.tex",
+
+/* 46 */
+"r",
+
+NULL
+
+
+#line 737 "f2lto.ctr"
+};
+
+
+
+/** LaTeX preamble, part 1 (font encoding and font selection packages).
+*/
+static char const * const f2l_tool_preamble_1[] = {
+"% begin font setup",
+"\\usepackage[T1]{fontenc}",
+"\\usepackage{mathptmx}",
+"\\usepackage[scaled=.92]{helvet}",
+"\\usepackage{courier}",
+"% end font setup",
+NULL
+
+
+#line 752 "f2lto.ctr"
+};
+
+
+
+/** LaTex preamble, part 2 (other packages).
+*/
+static char const * const f2l_tool_preamble_2[] = {
+"% begin other packages",
+"\\usepackage{textcomp}",
+"\\usepackage[intlimits]{amsmath}",
+"% end other packages",
+NULL
+
+
+#line 765 "f2lto.ctr"
+};
+
+
+
+/** LaTeX preamble, part 3 (graphics and color).
+*/
+static char const * const f2l_tool_preamble_3[] = {
+"\\usepackage{graphicx}",
+"\\usepackage{color}",
+NULL
+
+
+#line 776 "f2lto.ctr"
+};
+
+
+
+/** LaTeX preamble, part 4 (set borders to 0).
+*/
+static char const * const f2l_tool_preamble_4[] = {
+"\\pagestyle{empty}",
+"\\setlength{\\voffset}{-1in}",
+"\\setlength{\\topmargin}{0bp}",
+"\\setlength{\\headheight}{0bp}",
+"\\setlength{\\headsep}{0bp}",
+"\\setlength{\\topskip}{0bp}",
+"\\setlength{\\hoffset}{-1in}",
+"\\setlength{\\oddsidemargin}{0bp}",
+"\\setlength{\\evensidemargin}{0bp}",
+"\\setlength{\\marginparwidth}{0bp}",
+"\\setlength{\\marginparsep}{0bp}",
+"\\setlength{\\textwidth}{\\paperwidth}",
+"\\setlength{\\textheight}{\\paperheight}",
+"\\setlength{\\parskip}{0bp}",
+"\\setlength{\\parindent}{0bp}",
+"\\setlength{\\pdfpagewidth}{\\paperwidth}",
+"\\setlength{\\pdfpageheight}{\\paperheight}",
+"\\begin{document}%",
+NULL
+
+
+#line 803 "f2lto.ctr"
+};
+
+
+
+f2l_text_handling_t *
+f2l_tool_register_font(
+ dk3_sto_t *sFonts,
+ dk3_sto_it_t *iFonts,
+ unsigned long *nFonts,
+ int fontno,
+ double fontsize,
+ dk3_app_t *app
+)
+{
+ f2l_text_handling_t myth; /* New text handling. */
+ f2l_text_handling_t *back = NULL;
+
+
+#line 820 "f2lto.ctr"
+ if((sFonts) && (iFonts) && (nFonts)) {
+ myth.fontSize = fontsize;
+
+#line 822 "f2lto.ctr"
+ myth.fontNumber = 0UL;
+ myth.psFontNo = fontno;
+
+#line 824 "f2lto.ctr"
+ back = (f2l_text_handling_t *)dk3sto_it_find_like(iFonts,(void *)(&myth),0);
+ if(!(back)) {
+
+#line 826 "f2lto.ctr"
+ back = dk3_new_app(f2l_text_handling_t,1,app);
+ if(back) {
+
+#line 828 "f2lto.ctr"
+ back->fontSize = fontsize;
+ back->fontNumber = *(nFonts);
+ back->psFontNo = fontno;
+ if(fontno < 0) { back->psFontNo = 0; }
+ if(fontno > 34) { back->psFontNo = 34; }
+ if(dk3sto_add(sFonts, (void *)back)) {
+
+#line 834 "f2lto.ctr"
+ *nFonts += 1UL;
+ if(0UL == *nFonts) {
+ back = NULL; /* Overflow */
+ }
+ } else {
+
+#line 839 "f2lto.ctr"
+ dk3_delete(back);
+ back = NULL;
+ }
+ } else {
+
+#line 843 "f2lto.ctr"
+ }
+ } else {
+
+#line 845 "f2lto.ctr"
+ }
+ }
+
+#line 847 "f2lto.ctr"
+ return back;
+}
+
+
+
+void
+f2l_tool_write_font_name(
+ FILE *of,
+ unsigned long fontno,
+ unsigned long nFonts
+)
+{
+ char buffer[64]; /* Buffer for number converted to string. */
+ char *ptr; /* Current character in buffer. */
+ size_t lgt; /* Length of current number. */
+ size_t l1; /* Length of maximum number. */
+ size_t i; /* Used to write leading zeros. */
+
+ if(of) {
+ fputs(f2lto_c8_kw[9], of);
+ sprintf(buffer, "%lu", nFonts);
+ lgt = strlen(buffer);
+ sprintf(buffer, "%lu", fontno);
+ l1 = strlen(buffer);
+ for(i = l1; i < lgt; i++) { fputc('A', of); }
+ ptr = buffer;
+ while(*ptr) {
+ switch(*ptr) {
+ case '9': { fputc('J', of); } break;
+ case '8': { fputc('I', of); } break;
+ case '7': { fputc('H', of); } break;
+ case '6': { fputc('G', of); } break;
+ case '5': { fputc('F', of); } break;
+ case '4': { fputc('E', of); } break;
+ case '3': { fputc('D', of); } break;
+ case '2': { fputc('C', of); } break;
+ case '1': { fputc('B', of); } break;
+ default: { fputc('A', of); } break;
+ }
+ ptr++;
+ }
+ }
+}
+
+
+
+void
+f2l_tool_start_tex_part_with_picture(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ char const *shortOutFile,
+ dk3_sto_it_t *iFonts,
+ unsigned long nFonts,
+ int wp
+)
+{
+ f2l_text_handling_t *th; /* Current text handling. */
+ char const *psfontname; /* PS font name. */
+ double fs; /* Font size. */
+
+ if(wp) {
+ /* begin{picture}(0,0) */
+ fputs(f2lto_c8_kw[0], of);
+ fputs(f2lto_c8_kw[2], of);
+ fputs(shortOutFile, of);
+ fputs(f2lto_c8_kw[3], of);
+ /* end{picture} */
+ fputs(f2lto_c8_kw[1], of);
+ fputs(f2lto_c8_kw[4], of);
+ }
+ if((iFonts) && (nFonts)) {
+ dk3sto_it_reset(iFonts);
+ while(NULL != (th = (f2l_text_handling_t *)dk3sto_it_next(iFonts))) {
+ fputs(f2lto_c8_kw[6], of);
+ /* Write font name */
+ f2l_tool_write_font_name(of, th->fontNumber, nFonts);
+ fputs(f2lto_c8_kw[7], of);
+ /* Write font description */
+ psfontname = dk3font_get_tex_font_name(th->psFontNo);
+ if(!(psfontname)) { psfontname = f2lto_c8_kw[10]; }
+ fputs(psfontname, of);
+ fputs(f2lto_c8_kw[11], of);
+ fs = th->fontSize;
+ if(job->nts > 0.0) {
+ fs = fs * job->nts;
+ }
+ fs = dk3ma_d_restrict_digits(fs, 2);
+ dk3ma_print_double_c8_no_sci(of, fs);
+ fputs(f2lto_c8_kw[12], of);
+ fputs(f2lto_c8_kw[8], of);
+ }
+ }
+ if(wp) {
+ fprintf(of, f2lto_c8_kw[5], job->lwidth, job->lheight);
+ }
+}
+
+
+
+
+void
+f2l_tool_start_tex_part(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ char const *shortOutFile,
+ dk3_sto_it_t *iFonts,
+ unsigned long nFonts
+)
+{
+ f2l_tool_start_tex_part_with_picture(
+ of, job, drw, shortOutFile, iFonts, nFonts, 1
+ );
+}
+
+
+
+void
+f2l_tool_end_tex_part(
+ FILE *of
+)
+{
+ fputs(f2lto_c8_kw[1], of);
+}
+
+
+
+/** Write font size to output file.
+ @param of Output file.
+ @param fs Font size.
+ @param sp Line base to line base distance.
+*/
+static
+void
+f2l_tool_write_font_size(
+ FILE *of,
+ double fs,
+ double sp
+)
+{
+
+ fputs(f2lto_c8_kw[29], of);
+ dk3ma_print_double_c8_no_sci(of, fs);
+ fputs(f2lto_c8_kw[12], of);
+ fputs(f2lto_c8_kw[7], of);
+ dk3ma_print_double_c8_no_sci(of, sp);
+ fputs(f2lto_c8_kw[12], of);
+ fputs(f2lto_c8_kw[16], of);
+}
+
+
+
+void
+f2l_tool_font_select_by_features(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double fontSize,
+ int fontFeatures,
+ int useFamily
+)
+{
+ double fs; /* Font size. */
+ double sp; /* Line base to line base distance. */
+
+ fs = fontSize;
+ if(job->nts > 0.0) {
+ fs = fs * job->nts;
+ }
+ sp = 1.2 * fs;
+ fs = dk3ma_d_restrict_digits(fs, 2);
+ sp = dk3ma_d_restrict_digits(sp, 2);
+ if(useFamily) {
+ /*
+ Complete font selection.
+ */
+ if(job->resfont) {
+ fputs(f2lto_c8_kw[27], of);
+ }
+ /* Font size. */
+ f2l_tool_write_font_size(of, fs, sp);
+ /* Font family */
+ switch(fontFeatures & DK3_FONT_FAMILY) {
+ case DK3_FONT_TYPEWRITER: {
+ fputs(f2lto_c8_kw[32], of);
+ } break;
+ case DK3_FONT_SANS_SERIF: {
+ fputs(f2lto_c8_kw[31], of);
+ } break;
+ default: {
+ fputs(f2lto_c8_kw[30], of);
+ } break;
+ }
+ /* Font series */
+ fputs(f2lto_c8_kw[(fontFeatures & DK3_FONT_BOLD) ? 34 : 33], of);
+ /* Font shape */
+ /* 2013-01-22 Correction to test with DK3_FONT_ITOB.
+ */
+ fputs(f2lto_c8_kw[(fontFeatures & DK3_FONT_ITOB) ? 36 : 35], of);
+ } else {
+ /*
+ Adjust the size only.
+ */
+ f2l_tool_write_font_size(of, fs, sp);
+ fputs(f2lto_c8_kw[37], of);
+ fputs(f2lto_c8_kw[33], of);
+ fputs(f2lto_c8_kw[35], of);
+ }
+ fputs(f2lto_c8_kw[28], of);
+}
+
+
+
+void
+f2l_tool_font_selection(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ unsigned long nFonts
+)
+{
+ f2l_text_handling_t *th; /* Text handling. */
+ int ff; /* Font flags. */
+ int fontFeatures; /* Font features. */
+
+ ff = (obj->dt).txt.ff;
+ /*
+ No font selection... for special text.
+ */
+ if(!(ff & DK3_FIG_FONT_FLAG_SPECIAL)) {
+ if((ff & DK3_FIG_FONT_FLAG_PS) && (obj->dsd)) {
+ /*
+ Use one of the defined fonts.
+ */
+ th = (f2l_text_handling_t *)(obj->dsd);
+ f2l_tool_write_font_name(of, th->fontNumber, nFonts);
+ } else {
+ /*
+ Select font by features.
+ */
+ fontFeatures = DK3_FONT_ROMAN;
+ if(ff & DK3_FIG_FONT_FLAG_PS) {
+ /*
+ Switch from PS font to font with similar features.
+ */
+ fontFeatures = dk3font_get_features((obj->dt).txt.fo);
+ f2l_tool_font_select_by_features(
+ of, job, drw, obj, (obj->dt).txt.fs, fontFeatures, 1
+ );
+ } else {
+ /*
+ Use LaTeX font with specified features.
+ */
+ switch((obj->dt).txt.fo) {
+ case 0: {
+ f2l_tool_font_select_by_features(
+ of, job, drw, obj, (obj->dt).txt.fs, fontFeatures, 0
+ );
+ } break;
+ case 1: {
+ f2l_tool_font_select_by_features(
+ of, job, drw, obj, (obj->dt).txt.fs, fontFeatures, 1
+ );
+ } break;
+ case 2: {
+ fontFeatures |= DK3_FONT_BOLD;
+ f2l_tool_font_select_by_features(
+ of, job, drw, obj, (obj->dt).txt.fs, fontFeatures, 1
+ );
+ } break;
+ case 3: {
+ fontFeatures |= DK3_FONT_ITALIC;
+ f2l_tool_font_select_by_features(
+ of, job, drw, obj, (obj->dt).txt.fs, fontFeatures, 1
+ );
+ } break;
+ case 4: {
+ fontFeatures = DK3_FONT_SANS_SERIF;
+ f2l_tool_font_select_by_features(
+ of, job, drw, obj, (obj->dt).txt.fs, fontFeatures, 1
+ );
+ } break;
+ case 5: {
+ fontFeatures = DK3_FONT_TYPEWRITER;
+ f2l_tool_font_select_by_features(
+ of, job, drw, obj, (obj->dt).txt.fs, fontFeatures, 1
+ );
+ } break;
+ default: {
+ f2l_tool_font_select_by_features(
+ of, job, drw, obj, (obj->dt).txt.fs, fontFeatures, 1
+ );
+ } break;
+ }
+ }
+ }
+ }
+}
+
+
+
+void
+f2l_tool_tex_string(
+ FILE *of,
+ char const *txt
+)
+{
+ char const *ptr; /* Current input character to process. */
+ char const *sptr; /* Output string for current input character. */
+ char c; /* Current input character. */
+ unsigned char uc; /* Current input character conv to unsigned char. */
+ unsigned un; /* Current input character converted to unsigned. */
+
+ ptr = txt;
+ while(*ptr) {
+ c = *(ptr++);
+ uc = (unsigned char)c;
+ un = (unsigned)uc;
+ while(un > 255) {
+ un = un - 256;
+ }
+ sptr = f2l_tool_l2l_enc[un];
+ if(sptr) {
+ fputs(sptr, of);
+ }
+ }
+}
+
+
+
+/** Write string, convert to UTF-8 if necessary.
+ @param txt String to write.
+ @param fipo Output file.
+*/
+static
+void
+f2lto_utf8_out(char const *txt, FILE *fipo)
+{
+ unsigned char buf[16];
+ char const *cptr;
+ dk3_c32_t c32;
+ size_t sz;
+ size_t i;
+ char c;
+
+ cptr = txt;
+ while(*cptr) {
+ c = *(cptr++);
+ c32 = (dk3_c32_t)c;
+ c32 &= 0x000000FFUL;
+ if(c32 < 128UL) {
+ fputc(c, fipo);
+ } else {
+ sz = dk3enc_uc2utf8(c32, buf, sizeof(buf));
+ if(0 < sz) {
+ for(i = 0; i < sz; i++) {
+ fputc(buf[i], fipo);
+ }
+ }
+ }
+ }
+}
+
+
+
+void
+f2l_tool_inner_text_object(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ unsigned long nFonts
+)
+{
+ dk3_rgb_color_t rgb; /* Color cell for text color. */
+
+ rgb.r = rgb.g = rgb.b = 0.0;
+ dk3fig_tool_find_color(&rgb, drw, obj->pc, 20);
+ if(job->smash) {
+ /* \smash{ */
+ fputs(f2lto_c8_kw[23], of);
+ }
+ if(job->mbox) {
+ /* \mbox{ */
+ fputs(f2lto_c8_kw[24], of);
+ }
+ fputs(f2lto_c8_kw[38], of);
+ /* font selection */
+ f2l_tool_font_selection(of, job, drw, obj, nFonts);
+ fputs(f2lto_c8_kw[25], of);
+ /* red */
+ dk3ma_print_double_c8_no_sci(of, rgb.r);
+ fputs(f2lto_c8_kw[14], of);
+ /* green */
+ dk3ma_print_double_c8_no_sci(of, rgb.g);
+ fputs(f2lto_c8_kw[14], of);
+ /* blue */
+ dk3ma_print_double_c8_no_sci(of, rgb.b);
+ fputs(f2lto_c8_kw[16], of);
+ /* text */
+ if(((obj->dt).txt.ff) & DK3_FIG_FONT_FLAG_SPECIAL) {
+ if(job->stu8) {
+ f2lto_utf8_out((obj->dt).txt.st, of);
+ } else {
+ fputs((obj->dt).txt.st, of);
+ }
+ } else {
+ f2l_tool_tex_string(of, (obj->dt).txt.st);
+ }
+ fputs(f2lto_c8_kw[16], of);
+ if(job->mbox) {
+ /* } */
+ fputs(f2lto_c8_kw[16], of);
+ }
+ if(job->smash) {
+ /* } */
+ fputs(f2lto_c8_kw[16], of);
+ }
+}
+
+
+void
+f2l_tool_text_object(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y,
+ unsigned long nFonts
+)
+{
+ double an; /* Rotation in degree. */
+ double ian; /* Rotation as integer. */
+ int haverotation = 0; /* Flag: Have rotation. */
+
+ /* \put( */
+ fputs(f2lto_c8_kw[13], of);
+ /* x position */
+ dk3ma_print_double_c8_no_sci(of, x);
+ /* , */
+ fputs(f2lto_c8_kw[14], of);
+ /* y position */
+ dk3ma_print_double_c8_no_sci(of, y);
+ /* ){ */
+ fputs(f2lto_c8_kw[15], of);
+ if(fabs((obj->dt).txt.an) > 1.0e-6) {
+ haverotation = 1;
+ an = ((obj->dt).txt.an * 180.0) / M_PI;
+ ian = dk3ma_d_rint(an);
+ if(fabs(an - ian) < 1.0e-3) {
+ an = ian;
+ }
+ /* \rotatebox{ */
+ fputs(f2lto_c8_kw[17], of);
+ /* degrees */
+ dk3ma_print_double_c8_no_sci(of, an);
+ /* }{ */
+ fputs(f2lto_c8_kw[7], of);
+ }
+ /* \makebox(0,0)[ */
+ fputs(f2lto_c8_kw[18], of);
+ /* justification */
+ switch(obj->st) {
+ case 2: {
+ fputs(f2lto_c8_kw[22], of);
+ } break;
+ case 1: {
+ fputs(f2lto_c8_kw[21], of);
+ } break;
+ default: {
+ fputs(f2lto_c8_kw[20], of);
+ } break;
+ }
+ /* ]{ */
+ fputs(f2lto_c8_kw[19], of);
+ f2l_tool_inner_text_object(of, job, drw, obj, nFonts);
+ /* } */
+ fputs(f2lto_c8_kw[16], of);
+ if(haverotation) {
+ /* } */
+ fputs(f2lto_c8_kw[16], of);
+ }
+ /* } */
+ fputs(f2lto_c8_kw[16], of);
+ fputs(f2lto_c8_kw[26], of);
+}
+
+
+
+void
+f2l_tool_image_delete(f2l_image_t *im)
+{
+
+
+#line 1344 "f2lto.ctr"
+ if(im) {
+
+#line 1345 "f2lto.ctr"
+ dk3_release(im->filename);
+ im->xo = NULL;
+ im->width = 0UL;
+ im->height = 0UL;
+ im->xres = 0.0;
+ im->yres = 0.0;
+ im->imageNumber = 0UL;
+ im->lineno = 0UL;
+ dk3_delete(im);
+ }
+
+#line 1355 "f2lto.ctr"
+}
+
+
+
+f2l_image_t *
+f2l_tool_image_new(char const *filename, dk3_app_t *app, unsigned long li)
+{
+ dk3_ufi_t ufi; /* Unique file identifier. */
+ f2l_image_t *back = NULL;
+
+
+#line 1365 "f2lto.ctr"
+ if((filename) && (app)) {
+ if(dk3ufi_c8_get(&ufi, filename)) {
+ back = dk3_new_app(f2l_image_t,1,app);
+ if(back) {
+ dk3mem_cpy((void *)(&(back->ufi)), (void *)(&ufi), sizeof(dk3_ufi_t));
+ back->xo = NULL;
+ back->width = 0UL;
+ back->height = 0UL;
+ back->xres = 0.0;
+ back->yres = 0.0;
+ back->imageNumber = 0UL;
+ back->lineno = li;
+ back->filename = dk3str_c8_dup_app(filename, app);
+ if(!(back->filename)) {
+ f2l_tool_image_delete(back);
+ back = NULL;
+ }
+ }
+ }
+ }
+
+#line 1385 "f2lto.ctr"
+ return back;
+}
+
+
+
+int
+f2l_tool_compare_images(void const *l, void const *r, int cr)
+{
+ f2l_image_t const *pl; /* Left object. */
+ f2l_image_t const *pr; /* Right object. */
+ int back = 0;
+
+ if(l) {
+ if(r) {
+ pl = (f2l_image_t const *)l;
+ pr = (f2l_image_t const *)r;
+ switch(cr) {
+ case 1: {
+ back = dk3ufi_compare((void *)(&(pl->ufi)), r, 0);
+ } break;
+ default: {
+ back = dk3ufi_compare((void *)(&(pl->ufi)), (void *)(&(pr->ufi)), 0);
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+void
+f2l_tool_set_exit_status(f2l_job_t *job, int exval)
+{
+ if(job) {
+ if(0 == job->exval) {
+ job->exval = exval;
+ }
+ }
+}
+
+
+
+/** Write entire section of text to output file.
+ @param of Output file.
+ @param txt Pointer to array of text lines, NULL-finalized.
+*/
+static
+void
+f2l_tool_add_text_section_to_file(FILE *of, char const * const *txt)
+{
+ char const * const *ptr; /* Current line to add. */
+
+ ptr = txt;
+ while(*ptr) {
+ fputs(*ptr, of);
+ fputc('\n', of);
+ ptr++;
+ }
+}
+
+
+
+/** Write preamble part to output file, either the contents of a
+ file (if found) or a default text.
+ @param of Output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param fileName Name of file containing the preamble part.
+ @param preamble Default preamble text if fileName is not found.
+*/
+static
+void
+fl2_tool_write_preamble_part_or_file(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ char const *fileName,
+ char const * const *preamble
+)
+{
+ char line[1024]; /* Line buffer to read input file. */
+ FILE *fipo; /* Input file. */
+ int done = 0; /* Flag: Successfully handled file. */
+
+
+#line 1472 "f2lto.ctr"
+ fipo = fopen(fileName, f2lto_c8_kw[46]);
+ if(fipo) {
+
+#line 1474 "f2lto.ctr"
+ done = 1;
+ while(fgets(line, sizeof(line), fipo)) {
+
+#line 1476 "f2lto.ctr"
+ dk3str_c8_chomp(line, NULL);
+
+#line 1477 "f2lto.ctr"
+ fputs(line, of);
+
+#line 1478 "f2lto.ctr"
+ fputc('\n', of);
+
+#line 1479 "f2lto.ctr"
+ }
+ fclose(fipo);
+ } else {
+
+#line 1482 "f2lto.ctr"
+ }
+ if(!(done)) {
+
+#line 1484 "f2lto.ctr"
+ f2l_tool_add_text_section_to_file(of, preamble);
+ }
+
+
+#line 1487 "f2lto.ctr"
+}
+
+
+
+void
+f2l_tool_begin_latex_document(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw
+)
+{
+ fprintf(of, f2lto_c8_kw[40], job->tts);
+#if 0
+ f2l_tool_add_text_section_to_file(of, f2l_tool_preamble_1);
+#else
+ fl2_tool_write_preamble_part_or_file(
+ of, job, drw, f2lto_c8_kw[44], f2l_tool_preamble_1
+ );
+#endif
+#if 0
+ f2l_tool_add_text_section_to_file(of, f2l_tool_preamble_2);
+#else
+ fl2_tool_write_preamble_part_or_file(
+ of, job, drw, f2lto_c8_kw[45], f2l_tool_preamble_2
+ );
+#endif
+ f2l_tool_add_text_section_to_file(of, f2l_tool_preamble_3);
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_PGF:
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ fputs(f2lto_c8_kw[43], of);
+ } break;
+ }
+ fprintf(of, f2lto_c8_kw[41], job->lwidth);
+ fprintf(of, f2lto_c8_kw[42], job->lheight);
+ f2l_tool_add_text_section_to_file(of, f2l_tool_preamble_4);
+}
+
+
+
+void
+f2l_tool_end_latex_document(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw
+)
+{
+ fputs(f2lto_c8_kw[39], of);
+}
+
+
+
+int
+f2lto_find_draw_direction(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ dk3_fig_poly_point_t *po; /* Point set. */
+ size_t np; /* Number of points. */
+ int back = 0;
+
+
+#line 1551 "f2lto.ctr"
+ if(DK3_FIG_SRCTYPE_JFIG != drw->srctype) {
+
+#line 1552 "f2lto.ctr"
+ po = (obj->dt).pol.po;
+ np = (obj->dt).pol.np;
+ if(4 <= np) {
+
+#line 1555 "f2lto.ctr"
+ if(po[1].x > (dk3ma_d_add_ok(po[0].x, 0.5, ec))) {
+ /* 0 on the left, 1 on the right */
+ if(po[3].y > (dk3ma_d_add_ok(po[0].y, 0.5, ec))) {
+ back = 0;
+ } else {
+ back = 1;
+ }
+ } else {
+ if(po[1].x < (dk3ma_d_sub_ok(po[0].x, 0.5, ec))) {
+ /* 0 on the right, 1 on the left. */
+ if(po[3].y > (dk3ma_d_add_ok(po[0].y, 0.5, ec))) {
+ back = 2;
+ } else {
+ back = 3;
+ }
+ } else {
+ /* 0 and 1 in one row. */
+ if(po[2].x > (dk3ma_d_add_ok(po[0].x, 0.5, ec))) {
+ /* 0 and 1 left */
+ if(po[1].y > (dk3ma_d_add_ok(po[0].y, 0.5, ec))) {
+ back = 0;
+ } else {
+ back = 1;
+ }
+ } else {
+ /* 0 and 1 right */
+ if(po[1].y > (dk3ma_d_add_ok(po[0].y, 0.5, ec))) {
+ back = 2;
+ } else {
+ back = 3;
+ }
+ }
+ }
+ }
+ if((obj->dt).pol.flf) {
+
+#line 1590 "f2lto.ctr"
+ back += 4;
+ } else {
+
+#line 1592 "f2lto.ctr"
+ }
+ } else {
+
+#line 1594 "f2lto.ctr"
+ }
+ } else {
+
+#line 1596 "f2lto.ctr"
+ }
+
+#line 1597 "f2lto.ctr"
+ return back;
+}
+
+
+
+double
+f2lto_find_gap_length(f2l_job_t *job, double lw, double lsv)
+{
+ double back;
+ if(job->cols) {
+ back = lsv;
+ } else {
+ back = 0.5 * lw + 0.5 * lsv;
+ if((0.5 * back) > lw) {
+ back = 2.0 * lw;
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/f2lto.ctr b/support/dktools/f2lto.ctr
new file mode 100644
index 0000000000..7cfcf35eb9
--- /dev/null
+++ b/support/dktools/f2lto.ctr
@@ -0,0 +1,1616 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2013-xxxx
+license = bsd
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Register PS font in a storage.
+ @param sFonts Fonts storage.
+ @param iFonts Storage iterator.
+ @param nFonts Pointer to variable for total number of used
+ fonts.
+ @param fontno PS font number.
+ @param fontsize Font size.
+ @param app Application structure for diagnostics.
+ @return Pointer to text handling on success, NULL on error.
+*/
+f2l_text_handling_t *
+f2l_tool_register_font(
+ dk3_sto_t *sFonts,
+ dk3_sto_it_t *iFonts,
+ unsigned long *nFonts,
+ int fontno,
+ double fontsize,
+ dk3_app_t *app
+);
+
+/** Start LaTeX part of EPS+TEX or PDF+TEX.
+ @param of Output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param shortOutFile Short output file name of EPS or PDF file.
+ @param iFonts Font storage iterator.
+ @param nFonts Total number of fonts.
+*/
+void
+f2l_tool_start_tex_part(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ char const *shortOutFile,
+ dk3_sto_it_t *iFonts,
+ unsigned long nFonts
+);
+
+/** Start LaTeX part of EPS+TEX, PDF+TEX or PGF.
+ @param of Output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param shortOutFile Short output file name of EPS or PDF file.
+ @param iFonts Font storage iterator.
+ @param nFonts Total number of fonts.
+ @param wp Flag: With picture environments.
+*/
+void
+f2l_tool_start_tex_part_with_picture(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ char const *shortOutFile,
+ dk3_sto_it_t *iFonts,
+ unsigned long nFonts,
+ int wp
+);
+
+/** End LaTeX part of EPS+TEX or PDF+TEX.
+ @param of Output file.
+*/
+void
+f2l_tool_end_tex_part(
+ FILE *of
+);
+
+/** Write one font name.
+ @param of Output file.
+ @param fontno Number of font to write.
+ @param nFonts Total number of font definitions.
+*/
+void
+f2l_tool_write_font_name(
+ FILE *of,
+ unsigned long fontno,
+ unsigned long nFonts
+);
+
+/** Write inner part of text object.
+ This function is used both for writing to a picture environment
+ in a *.tex file and pgf text labels.
+ @param of Output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Text object.
+ @param nFonts Total number of PS fonts.
+*/
+void
+f2l_tool_inner_text_object(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ unsigned long nFonts
+);
+
+/** Write one text object to LaTeX output in a picture environment.
+ @param of Output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Text object.
+ @param x X position.
+ @param y Y position.
+ @param nFonts Total number of PS fonts.
+*/
+void
+f2l_tool_text_object(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y,
+ unsigned long nFonts
+);
+
+/** Write commands to choose a font.
+ @param of Output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Text object.
+ @param nFonts Total number of PS fonts.
+*/
+void
+f2l_tool_font_selection(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ unsigned long nFonts
+);
+
+/** Write string to LaTeX output.
+ @param of Output file.
+ @param txt String, ISO-LATIN-1 encoded.
+*/
+void
+f2l_tool_tex_string(
+ FILE *of,
+ char const *txt
+);
+
+/** Write instruction to select a font by features to LaTeX output.
+ @param of Output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Text object.
+ @param fontSize Font size.
+ @param fontFeatures Font features.
+ @param useFamily Flag: Choose font family.
+*/
+void
+f2l_tool_font_select_by_features(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double fontSize,
+ int fontFeatures,
+ int useFamily
+);
+
+/** Create image file data.
+ @param filename File name.
+ @param app Application structure for diagnostics.
+ @param li Line number of object definition.
+ @return Pointer to image file data on success, NULL on error.
+*/
+f2l_image_t *
+f2l_tool_image_new(char const *filename, dk3_app_t *app, unsigned long li);
+
+/** Destroy image data.
+ @param im Image data to destroy.
+*/
+void
+f2l_tool_image_delete(f2l_image_t *im);
+
+/** Compare two image entries.
+ @param l Left image entry.
+ @param r Right image entry or unique file identifier.
+ @param cr Comparison criteria (0=image/image, 1=image/ufi).
+ @return Comparison result.
+*/
+int
+f2l_tool_compare_images(void const *l, void const *r, int cr);
+
+/** Set exit status code to error code if exit status indicates success.
+ @param job Job structure.
+ @param exval Error code.
+*/
+void
+f2l_tool_set_exit_status(f2l_job_t *job, int exval);
+
+/** Begin LaTeX document (write document preamble and begin document line).
+ @param of Output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+void
+f2l_tool_begin_latex_document(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw
+);
+
+/** End LaTeX document (write end document line).
+ @param of Output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+void
+f2l_tool_end_latex_document(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw
+);
+
+/** Find drawing direction for embedded image.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Drawing direction.
+*/
+int
+f2lto_find_draw_direction(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int *ec
+);
+
+/** Find suitable length for gaps in line styles.
+ @param job Job structure.
+ @param lw Line width.
+ @param lsv Style value.
+ @return Gap length.
+*/
+double
+f2lto_find_gap_length(f2l_job_t *job, double lw, double lsv);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk3all.h"
+#include "dk3bezcu.h"
+#include "fig2lat.h"
+#include "f2lud.h"
+#include "f2lsvg.h"
+#include "dk3figto.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4vers.h"
+#include "dk3font.h"
+#include "dk3bm.h"
+#include "dk3bmeps.h"
+
+
+$!trace-include
+
+
+
+/** LaTeX encodings for 0x00-0xFF.
+*/
+static char const * const f2l_tool_l2l_enc[] = {
+/* 000 00 */ "",
+/* 001 01 */ "",
+/* 002 02 */ "",
+/* 003 03 */ "",
+/* 004 04 */ "",
+/* 005 05 */ "",
+/* 006 06 */ "",
+/* 007 07 */ "",
+/* 008 08 */ "",
+/* 009 09 */ "\t",
+/* 010 0a */ "\\\\*",
+/* 011 0b */ "",
+/* 012 0c */ "",
+/* 013 0d */ "",
+/* 014 0e */ "",
+/* 015 0f */ "",
+/* 016 10 */ "",
+/* 017 11 */ "",
+/* 018 12 */ "",
+/* 019 13 */ "",
+/* 020 14 */ "",
+/* 021 15 */ "",
+/* 022 16 */ "",
+/* 023 17 */ "",
+/* 024 18 */ "",
+/* 025 19 */ "",
+/* 026 1a */ "",
+/* 027 1b */ "",
+/* 028 1c */ "",
+/* 029 1d */ "",
+/* 030 1e */ "",
+/* 031 1f */ "",
+/* 032 20 */ " ",
+/* 033 21 */ "!",
+/* 034 22 */ "\\textquotedbl{}",
+/* 035 23 */ "\\#",
+/* 036 24 */ "\\textdollar{}",
+/* 037 25 */ "\\%",
+/* 038 26 */ "\\&",
+/* 039 27 */ "\\textquoteright{}",
+/* 040 28 */ "(",
+/* 041 29 */ ")",
+/* 042 2a */ "\\textasteriskcentered{}",
+/* 043 2b */ "+",
+/* 044 2c */ ",",
+/* 045 2d */ "-",
+/* 046 2e */ ".",
+/* 047 2f */ "/",
+/* 048 30 */ "0",
+/* 049 31 */ "1",
+/* 050 32 */ "2",
+/* 051 33 */ "3",
+/* 052 34 */ "4",
+/* 053 35 */ "5",
+/* 054 36 */ "6",
+/* 055 37 */ "7",
+/* 056 38 */ "8",
+/* 057 39 */ "9",
+/* 058 3a */ ":",
+/* 059 3b */ ";",
+/* 060 3c */ "\\textless{}",
+/* 061 3d */ "=",
+/* 062 3e */ "\\textgreater{}",
+/* 063 3f */ "?",
+/* 064 40 */ "@",
+/* 065 41 */ "A",
+/* 066 42 */ "B",
+/* 067 43 */ "C",
+/* 068 44 */ "D",
+/* 069 45 */ "E",
+/* 070 46 */ "F",
+/* 071 47 */ "G",
+/* 072 48 */ "H",
+/* 073 49 */ "I",
+/* 074 4a */ "J",
+/* 075 4b */ "K",
+/* 076 4c */ "L",
+/* 077 4d */ "M",
+/* 078 4e */ "N",
+/* 079 4f */ "O",
+/* 080 50 */ "P",
+/* 081 51 */ "Q",
+/* 082 52 */ "R",
+/* 083 53 */ "S",
+/* 084 54 */ "T",
+/* 085 55 */ "U",
+/* 086 56 */ "V",
+/* 087 57 */ "W",
+/* 088 58 */ "X",
+/* 089 59 */ "Y",
+/* 090 5a */ "Z",
+/* 091 5b */ "[",
+/* 092 5c */ "\\textbackslash{}",
+/* 093 5d */ "]",
+/* 094 5e */ "\\textasciicircum{}",
+/* 095 5f */ "\\textunderscore{}",
+/* 096 60 */ "\\textasciigrave{}",
+/* 097 61 */ "a",
+/* 098 62 */ "b",
+/* 099 63 */ "c",
+/* 100 64 */ "d",
+/* 101 65 */ "e",
+/* 102 66 */ "f",
+/* 103 67 */ "g",
+/* 104 68 */ "h",
+/* 105 69 */ "i",
+/* 106 6a */ "j",
+/* 107 6b */ "k",
+/* 108 6c */ "l",
+/* 109 6d */ "m",
+/* 110 6e */ "n",
+/* 111 6f */ "o",
+/* 112 70 */ "p",
+/* 113 71 */ "q",
+/* 114 72 */ "r",
+/* 115 73 */ "s",
+/* 116 74 */ "t",
+/* 117 75 */ "u",
+/* 118 76 */ "v",
+/* 119 77 */ "w",
+/* 120 78 */ "x",
+/* 121 79 */ "y",
+/* 122 7a */ "z",
+/* 123 7b */ "\\textbraceleft{}",
+/* 124 7c */ "\\textbar{}",
+/* 125 7d */ "\\textbraceright{}",
+/* 126 7e */ "\\textasciitilde{}",
+/* 127 7f */ "",
+/* 128 80 */ "",
+/* 129 81 */ "",
+/* 130 82 */ "",
+/* 131 83 */ "",
+/* 132 84 */ "",
+/* 133 85 */ "",
+/* 134 86 */ "",
+/* 135 87 */ "",
+/* 136 88 */ "",
+/* 137 89 */ "",
+/* 138 8a */ "",
+/* 139 8b */ "",
+/* 140 8c */ "",
+/* 141 8d */ "",
+/* 142 8e */ "",
+/* 143 8f */ "",
+/* 144 90 */ "",
+/* 145 91 */ "",
+/* 146 92 */ "",
+/* 147 93 */ "",
+/* 148 94 */ "",
+/* 149 95 */ "",
+/* 150 96 */ "",
+/* 151 97 */ "",
+/* 152 98 */ "",
+/* 153 99 */ "",
+/* 154 9a */ "",
+/* 155 9b */ "",
+/* 156 9c */ "",
+/* 157 9d */ "",
+/* 158 9e */ "",
+/* 159 9f */ "",
+/* 160 a0 */ "",
+/* 161 a1 */ "\\textexclamdown{}",
+/* 162 a2 */ "\\textcentoldstyle{}",
+/* 163 a3 */ "\\textstirling{}",
+/* 164 a4 */ "\\textcurrency{}",
+/* 165 a5 */ "\\textyen{}",
+/* 166 a6 */ "\\textbrokenbar{}",
+/* 167 a7 */ "\\textsection{}",
+/* 168 a8 */ "\\textasciidieresis{}",
+/* 169 a9 */ "\\textcopyright{}",
+/* 170 aa */ "\\textordfeminine{}",
+/* 171 ab */ "\\quillemotleft{}",
+/* 172 ac */ "\\textlnot{}",
+/* 173 ad */ "",
+/* 174 ae */ "\\textregistered{}",
+/* 175 af */ "\\textasciimacron{}",
+/* 176 b0 */ "\\textdegree{}",
+/* 177 b1 */ "\\textpm{}",
+/* 178 b2 */ "\\texttwosuperior{}",
+/* 179 b3 */ "\\textthreesuperior{}",
+/* 180 b4 */ "\\textasciiacute{}",
+/* 181 b5 */ "\\textmu{}",
+/* 182 b6 */ "\\P{}",
+/* 183 b7 */ "\\textperiodcentered{}",
+/* 184 b8 */ "\\c{}",
+/* 185 b9 */ "\\textonesuperior{}",
+/* 186 ba */ "\\textordmasculine{}",
+/* 187 bb */ "\\quillemotright{}",
+/* 188 bc */ "\\textonequarter{}",
+/* 189 bd */ "\\textonehalf{}",
+/* 190 be */ "\\textthreequarters{}",
+/* 191 bf */ "?`",
+/* 192 c0 */ "\\`{A}",
+/* 193 c1 */ "\\'{A}",
+/* 194 c2 */ "\\^{A}",
+/* 195 c3 */ "\\~{A}",
+/* 196 c4 */ "\\\"{A}",
+/* 197 c5 */ "\\AA{}",
+/* 198 c6 */ "\\AE{}",
+/* 199 c7 */ "\\c{C}",
+/* 200 c8 */ "\\`{E}",
+/* 201 c9 */ "\\'{E}",
+/* 202 ca */ "\\^{E}",
+/* 203 cb */ "\\\"{E}",
+/* 204 cc */ "\\`{I}",
+/* 205 cd */ "\\'{I}",
+/* 206 ce */ "\\^{I}",
+/* 207 cf */ "\\\"{I}",
+/* 208 d0 */ "\\DH{}",
+/* 209 d1 */ "\\~{N}",
+/* 210 d2 */ "\\`{O}",
+/* 211 d3 */ "\\'{O}",
+/* 212 d4 */ "\\^{O}",
+/* 213 d5 */ "\\~{O}",
+/* 214 d6 */ "\\\"{O}",
+/* 215 d7 */ "\\texttimes{}",
+/* 216 d8 */ "\\O{}",
+/* 217 d9 */ "\\`{U}",
+/* 218 da */ "\\'{U}",
+/* 219 db */ "\\^{U}",
+/* 220 dc */ "\\\"{U}",
+/* 221 dd */ "\\'{Y}",
+/* 222 de */ "\\TH{}",
+/* 223 df */ "\\ss{}",
+/* 224 e0 */ "\\`{a}",
+/* 225 e1 */ "\\'{a}",
+/* 226 e2 */ "\\^{a}",
+/* 227 e3 */ "\\~{a}",
+/* 228 e4 */ "\\\"{a}",
+/* 229 e5 */ "\\aa{}",
+/* 230 e6 */ "\\ae{}",
+/* 231 e7 */ "\\c{c}",
+/* 232 e8 */ "\\`{e}",
+/* 233 e9 */ "\\'{e}",
+/* 234 ea */ "\\^{e}",
+/* 235 eb */ "\\\"{e}",
+/* 236 ec */ "\\`{i}",
+/* 237 ed */ "\\'{i}",
+/* 238 ee */ "\\^{i}",
+/* 239 ef */ "\\\"{i}",
+/* 240 f0 */ "\\dh{}",
+/* 241 f1 */ "\\~{n}",
+/* 242 f2 */ "\\`{o}",
+/* 243 f3 */ "\\'{o}",
+/* 244 f4 */ "\\^{o}",
+/* 245 f5 */ "\\~{o}",
+/* 246 f6 */ "\\\"{o}",
+/* 247 f7 */ "\\textdiv{}",
+/* 248 f8 */ "\\o{}",
+/* 249 f9 */ "\\`{u}",
+/* 250 fa */ "\\'{u}",
+/* 251 fb */ "\\^{u}",
+/* 252 fc */ "\\\"{u}",
+/* 253 fd */ "\\'{y}",
+/* 254 fe */ "\\th{}",
+/* 255 ff */ "\\\"{y}"
+};
+
+
+/** Keywords used by the module.
+*/
+static char const * const f2lto_c8_kw[] = {
+$!string-table
+#
+# 0: Begin a picture.
+#
+\\begin{picture}(0,0)\n
+#
+# 1: End the picture.
+#
+\\end{picture}%\n
+#
+# 2: Include a graphics file.
+#
+\\includegraphics{
+#
+# 3: End of graphics file inclusion.
+#
+}\n
+#
+# 4: Switch length unit to 1 bp.
+#
+\\setlength{\\unitlength}{1bp}%\n
+#
+# 5: Begin picture of given width and height.
+#
+\\begin{picture}(%ld,%ld)\n
+#
+# 6: Newfont instruction.
+#
+\\newfont{
+#
+# 7: Between font name and definition.
+#
+}{
+#
+# 8: End of font definition.
+#
+}%\n
+#
+# 9: Start of all font names.
+#
+\\FigToLatFont
+#
+# 10: Default font: ptmr
+#
+ptmr
+#
+# 11: Keyword at.
+#
+ at
+#
+# 12: Font size unit pt.
+#
+pt
+#
+# 13: Put instruction.
+#
+\\put(
+#
+# 14: Comma.
+#
+,
+#
+# 15: In put instruction.
+#
+){
+#
+# 16: Closing curly bracket.
+#
+}
+#
+# 17: rotatebox
+#
+\\rotatebox{
+#
+# 18: makebox
+#
+\\makebox(0,0)[
+#
+# 19: in makebox
+#
+]{
+#
+# 20: Text position: left
+#
+lb
+#
+# 21: Text position: centered
+#
+b
+#
+# 22: Text position: right
+#
+rb
+#
+# 23: smash instruction
+#
+\\smash{
+#
+# 24: mbox instruction
+#
+\\mbox{
+#
+# 25: Color instruction
+#
+\\color[rgb]{
+#
+# 26: Newline
+#
+\n
+#
+# 27: Reset font.
+#
+\\reset@font
+#
+# 28: Select this font.
+#
+\\selectfont
+#
+# 29: Font size.
+#
+\\fontsize{
+#
+# 30: Font family: roman
+#
+\\fontfamily{\\rmdefault}
+#
+# 31: Font family: sans-serif
+#
+\\fontfamily{\\sfdefault}
+#
+# 32: Font family: typewriter
+#
+\\fontfamily{\\ttdefault}
+#
+# 33: Font series: medium density
+#
+\\fontseries{\\mddefault}
+#
+# 34: Font series: bold font
+#
+\\fontseries{\\bfdefault}
+#
+# 35: Font shape: upright
+#
+\\fontshape{\\updefault}
+#
+# 36: Font shape: italic
+#
+\\fontshape{\\itdefault}
+#
+# 37: Font family: Default font family.
+#
+\\fontfamily{\\familydefault}
+#
+# 38: Open a LaTeX group.
+#
+{
+#
+# 39: End LaTeX document.
+#
+\\end{document}\n
+#
+# 40: LaTeX document class
+#
+\\documentclass[%lgpt]{article}\n
+#
+# 41: Paper width
+#
+\\setlength{\\paperwidth}{%ldbp}\n
+#
+# 42: Paper height
+#
+\\setlength{\\paperheight}{%ldbp}\n
+#
+# 43: Use package PGF core
+#
+\\usepackage{pgfcore}\n
+#
+# 44: File name: f2lfonts.tex
+#
+f2lfonts.tex
+#
+# 45: File name: f2lother.tex
+#
+f2lother.tex
+#
+# 46: File opening mode: Read
+#
+r
+$!end
+};
+
+
+
+/** LaTeX preamble, part 1 (font encoding and font selection packages).
+*/
+static char const * const f2l_tool_preamble_1[] = {
+$!text
+% begin font setup
+\usepackage[T1]{fontenc}
+\usepackage{mathptmx}
+\usepackage[scaled=.92]{helvet}
+\usepackage{courier}
+% end font setup
+$!end
+};
+
+
+
+/** LaTex preamble, part 2 (other packages).
+*/
+static char const * const f2l_tool_preamble_2[] = {
+$!text
+% begin other packages
+\usepackage{textcomp}
+\usepackage[intlimits]{amsmath}
+% end other packages
+$!end
+};
+
+
+
+/** LaTeX preamble, part 3 (graphics and color).
+*/
+static char const * const f2l_tool_preamble_3[] = {
+$!text
+\usepackage{graphicx}
+\usepackage{color}
+$!end
+};
+
+
+
+/** LaTeX preamble, part 4 (set borders to 0).
+*/
+static char const * const f2l_tool_preamble_4[] = {
+$!text
+\pagestyle{empty}
+\setlength{\voffset}{-1in}
+\setlength{\topmargin}{0bp}
+\setlength{\headheight}{0bp}
+\setlength{\headsep}{0bp}
+\setlength{\topskip}{0bp}
+\setlength{\hoffset}{-1in}
+\setlength{\oddsidemargin}{0bp}
+\setlength{\evensidemargin}{0bp}
+\setlength{\marginparwidth}{0bp}
+\setlength{\marginparsep}{0bp}
+\setlength{\textwidth}{\paperwidth}
+\setlength{\textheight}{\paperheight}
+\setlength{\parskip}{0bp}
+\setlength{\parindent}{0bp}
+\setlength{\pdfpagewidth}{\paperwidth}
+\setlength{\pdfpageheight}{\paperheight}
+\begin{document}%
+$!end
+};
+
+
+
+f2l_text_handling_t *
+f2l_tool_register_font(
+ dk3_sto_t *sFonts,
+ dk3_sto_it_t *iFonts,
+ unsigned long *nFonts,
+ int fontno,
+ double fontsize,
+ dk3_app_t *app
+)
+{
+ f2l_text_handling_t myth; /* New text handling. */
+ f2l_text_handling_t *back = NULL;
+ $? "+ f2l_tool_register_font %d %lg", fontno, fontsize
+ if((sFonts) && (iFonts) && (nFonts)) {
+ myth.fontSize = fontsize; $? ". font size %lg", fontsize
+ myth.fontNumber = 0UL;
+ myth.psFontNo = fontno; $? ". PS font no %d", fontno
+ back = (f2l_text_handling_t *)dk3sto_it_find_like(iFonts,(void *)(&myth),0);
+ if(!(back)) { $? ". font not yet found"
+ back = dk3_new_app(f2l_text_handling_t,1,app);
+ if(back) { $? ". new font ok"
+ back->fontSize = fontsize;
+ back->fontNumber = *(nFonts);
+ back->psFontNo = fontno;
+ if(fontno < 0) { back->psFontNo = 0; }
+ if(fontno > 34) { back->psFontNo = 34; }
+ if(dk3sto_add(sFonts, (void *)back)) { $? ". add"
+ *nFonts += 1UL;
+ if(0UL == *nFonts) {
+ back = NULL; /* Overflow */
+ }
+ } else { $? "! add"
+ dk3_delete(back);
+ back = NULL;
+ }
+ } else { $? "! memory"
+ }
+ } else { $? ". font found %d %lg", back->psFontNo, back->fontSize
+ }
+ } $? "- f2l_tool_register_font PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+void
+f2l_tool_write_font_name(
+ FILE *of,
+ unsigned long fontno,
+ unsigned long nFonts
+)
+{
+ char buffer[64]; /* Buffer for number converted to string. */
+ char *ptr; /* Current character in buffer. */
+ size_t lgt; /* Length of current number. */
+ size_t l1; /* Length of maximum number. */
+ size_t i; /* Used to write leading zeros. */
+
+ if(of) {
+ fputs(f2lto_c8_kw[9], of);
+ sprintf(buffer, "%lu", nFonts);
+ lgt = strlen(buffer);
+ sprintf(buffer, "%lu", fontno);
+ l1 = strlen(buffer);
+ for(i = l1; i < lgt; i++) { fputc('A', of); }
+ ptr = buffer;
+ while(*ptr) {
+ switch(*ptr) {
+ case '9': { fputc('J', of); } break;
+ case '8': { fputc('I', of); } break;
+ case '7': { fputc('H', of); } break;
+ case '6': { fputc('G', of); } break;
+ case '5': { fputc('F', of); } break;
+ case '4': { fputc('E', of); } break;
+ case '3': { fputc('D', of); } break;
+ case '2': { fputc('C', of); } break;
+ case '1': { fputc('B', of); } break;
+ default: { fputc('A', of); } break;
+ }
+ ptr++;
+ }
+ }
+}
+
+
+
+void
+f2l_tool_start_tex_part_with_picture(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ char const *shortOutFile,
+ dk3_sto_it_t *iFonts,
+ unsigned long nFonts,
+ int wp
+)
+{
+ f2l_text_handling_t *th; /* Current text handling. */
+ char const *psfontname; /* PS font name. */
+ double fs; /* Font size. */
+
+ if(wp) {
+ /* begin{picture}(0,0) */
+ fputs(f2lto_c8_kw[0], of);
+ fputs(f2lto_c8_kw[2], of);
+ fputs(shortOutFile, of);
+ fputs(f2lto_c8_kw[3], of);
+ /* end{picture} */
+ fputs(f2lto_c8_kw[1], of);
+ fputs(f2lto_c8_kw[4], of);
+ }
+ if((iFonts) && (nFonts)) {
+ dk3sto_it_reset(iFonts);
+ while(NULL != (th = (f2l_text_handling_t *)dk3sto_it_next(iFonts))) {
+ fputs(f2lto_c8_kw[6], of);
+ /* Write font name */
+ f2l_tool_write_font_name(of, th->fontNumber, nFonts);
+ fputs(f2lto_c8_kw[7], of);
+ /* Write font description */
+ psfontname = dk3font_get_tex_font_name(th->psFontNo);
+ if(!(psfontname)) { psfontname = f2lto_c8_kw[10]; }
+ fputs(psfontname, of);
+ fputs(f2lto_c8_kw[11], of);
+ fs = th->fontSize;
+ if(job->nts > 0.0) {
+ fs = fs * job->nts;
+ }
+ fs = dk3ma_d_restrict_digits(fs, 2);
+ dk3ma_print_double_c8_no_sci(of, fs);
+ fputs(f2lto_c8_kw[12], of);
+ fputs(f2lto_c8_kw[8], of);
+ }
+ }
+ if(wp) {
+ fprintf(of, f2lto_c8_kw[5], job->lwidth, job->lheight);
+ }
+}
+
+
+
+
+void
+f2l_tool_start_tex_part(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ char const *shortOutFile,
+ dk3_sto_it_t *iFonts,
+ unsigned long nFonts
+)
+{
+ f2l_tool_start_tex_part_with_picture(
+ of, job, drw, shortOutFile, iFonts, nFonts, 1
+ );
+}
+
+
+
+void
+f2l_tool_end_tex_part(
+ FILE *of
+)
+{
+ fputs(f2lto_c8_kw[1], of);
+}
+
+
+
+/** Write font size to output file.
+ @param of Output file.
+ @param fs Font size.
+ @param sp Line base to line base distance.
+*/
+static
+void
+f2l_tool_write_font_size(
+ FILE *of,
+ double fs,
+ double sp
+)
+{
+
+ fputs(f2lto_c8_kw[29], of);
+ dk3ma_print_double_c8_no_sci(of, fs);
+ fputs(f2lto_c8_kw[12], of);
+ fputs(f2lto_c8_kw[7], of);
+ dk3ma_print_double_c8_no_sci(of, sp);
+ fputs(f2lto_c8_kw[12], of);
+ fputs(f2lto_c8_kw[16], of);
+}
+
+
+
+void
+f2l_tool_font_select_by_features(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double fontSize,
+ int fontFeatures,
+ int useFamily
+)
+{
+ double fs; /* Font size. */
+ double sp; /* Line base to line base distance. */
+
+ fs = fontSize;
+ if(job->nts > 0.0) {
+ fs = fs * job->nts;
+ }
+ sp = 1.2 * fs;
+ fs = dk3ma_d_restrict_digits(fs, 2);
+ sp = dk3ma_d_restrict_digits(sp, 2);
+ if(useFamily) {
+ /*
+ Complete font selection.
+ */
+ if(job->resfont) {
+ fputs(f2lto_c8_kw[27], of);
+ }
+ /* Font size. */
+ f2l_tool_write_font_size(of, fs, sp);
+ /* Font family */
+ switch(fontFeatures & DK3_FONT_FAMILY) {
+ case DK3_FONT_TYPEWRITER: {
+ fputs(f2lto_c8_kw[32], of);
+ } break;
+ case DK3_FONT_SANS_SERIF: {
+ fputs(f2lto_c8_kw[31], of);
+ } break;
+ default: {
+ fputs(f2lto_c8_kw[30], of);
+ } break;
+ }
+ /* Font series */
+ fputs(f2lto_c8_kw[(fontFeatures & DK3_FONT_BOLD) ? 34 : 33], of);
+ /* Font shape */
+ /* 2013-01-22 Correction to test with DK3_FONT_ITOB.
+ */
+ fputs(f2lto_c8_kw[(fontFeatures & DK3_FONT_ITOB) ? 36 : 35], of);
+ } else {
+ /*
+ Adjust the size only.
+ */
+ f2l_tool_write_font_size(of, fs, sp);
+ fputs(f2lto_c8_kw[37], of);
+ fputs(f2lto_c8_kw[33], of);
+ fputs(f2lto_c8_kw[35], of);
+ }
+ fputs(f2lto_c8_kw[28], of);
+}
+
+
+
+void
+f2l_tool_font_selection(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ unsigned long nFonts
+)
+{
+ f2l_text_handling_t *th; /* Text handling. */
+ int ff; /* Font flags. */
+ int fontFeatures; /* Font features. */
+
+ ff = (obj->dt).txt.ff;
+ /*
+ No font selection... for special text.
+ */
+ if(!(ff & DK3_FIG_FONT_FLAG_SPECIAL)) {
+ if((ff & DK3_FIG_FONT_FLAG_PS) && (obj->dsd)) {
+ /*
+ Use one of the defined fonts.
+ */
+ th = (f2l_text_handling_t *)(obj->dsd);
+ f2l_tool_write_font_name(of, th->fontNumber, nFonts);
+ } else {
+ /*
+ Select font by features.
+ */
+ fontFeatures = DK3_FONT_ROMAN;
+ if(ff & DK3_FIG_FONT_FLAG_PS) {
+ /*
+ Switch from PS font to font with similar features.
+ */
+ fontFeatures = dk3font_get_features((obj->dt).txt.fo);
+ f2l_tool_font_select_by_features(
+ of, job, drw, obj, (obj->dt).txt.fs, fontFeatures, 1
+ );
+ } else {
+ /*
+ Use LaTeX font with specified features.
+ */
+ switch((obj->dt).txt.fo) {
+ case 0: {
+ f2l_tool_font_select_by_features(
+ of, job, drw, obj, (obj->dt).txt.fs, fontFeatures, 0
+ );
+ } break;
+ case 1: {
+ f2l_tool_font_select_by_features(
+ of, job, drw, obj, (obj->dt).txt.fs, fontFeatures, 1
+ );
+ } break;
+ case 2: {
+ fontFeatures |= DK3_FONT_BOLD;
+ f2l_tool_font_select_by_features(
+ of, job, drw, obj, (obj->dt).txt.fs, fontFeatures, 1
+ );
+ } break;
+ case 3: {
+ fontFeatures |= DK3_FONT_ITALIC;
+ f2l_tool_font_select_by_features(
+ of, job, drw, obj, (obj->dt).txt.fs, fontFeatures, 1
+ );
+ } break;
+ case 4: {
+ fontFeatures = DK3_FONT_SANS_SERIF;
+ f2l_tool_font_select_by_features(
+ of, job, drw, obj, (obj->dt).txt.fs, fontFeatures, 1
+ );
+ } break;
+ case 5: {
+ fontFeatures = DK3_FONT_TYPEWRITER;
+ f2l_tool_font_select_by_features(
+ of, job, drw, obj, (obj->dt).txt.fs, fontFeatures, 1
+ );
+ } break;
+ default: {
+ f2l_tool_font_select_by_features(
+ of, job, drw, obj, (obj->dt).txt.fs, fontFeatures, 1
+ );
+ } break;
+ }
+ }
+ }
+ }
+}
+
+
+
+void
+f2l_tool_tex_string(
+ FILE *of,
+ char const *txt
+)
+{
+ char const *ptr; /* Current input character to process. */
+ char const *sptr; /* Output string for current input character. */
+ char c; /* Current input character. */
+ unsigned char uc; /* Current input character conv to unsigned char. */
+ unsigned un; /* Current input character converted to unsigned. */
+
+ ptr = txt;
+ while(*ptr) {
+ c = *(ptr++);
+ uc = (unsigned char)c;
+ un = (unsigned)uc;
+ while(un > 255) {
+ un = un - 256;
+ }
+ sptr = f2l_tool_l2l_enc[un];
+ if(sptr) {
+ fputs(sptr, of);
+ }
+ }
+}
+
+
+
+/** Write string, convert to UTF-8 if necessary.
+ @param txt String to write.
+ @param fipo Output file.
+*/
+static
+void
+f2lto_utf8_out(char const *txt, FILE *fipo)
+{
+ unsigned char buf[16];
+ char const *cptr;
+ dk3_c32_t c32;
+ size_t sz;
+ size_t i;
+ char c;
+
+ cptr = txt;
+ while(*cptr) {
+ c = *(cptr++);
+ c32 = (dk3_c32_t)c;
+ c32 &= 0x000000FFUL;
+ if(c32 < 128UL) {
+ fputc(c, fipo);
+ } else {
+ sz = dk3enc_uc2utf8(c32, buf, sizeof(buf));
+ if(0 < sz) {
+ for(i = 0; i < sz; i++) {
+ fputc(buf[i], fipo);
+ }
+ }
+ }
+ }
+}
+
+
+
+void
+f2l_tool_inner_text_object(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ unsigned long nFonts
+)
+{
+ dk3_rgb_color_t rgb; /* Color cell for text color. */
+
+ rgb.r = rgb.g = rgb.b = 0.0;
+ dk3fig_tool_find_color(&rgb, drw, obj->pc, 20);
+ if(job->smash) {
+ /* \smash{ */
+ fputs(f2lto_c8_kw[23], of);
+ }
+ if(job->mbox) {
+ /* \mbox{ */
+ fputs(f2lto_c8_kw[24], of);
+ }
+ fputs(f2lto_c8_kw[38], of);
+ /* font selection */
+ f2l_tool_font_selection(of, job, drw, obj, nFonts);
+ fputs(f2lto_c8_kw[25], of);
+ /* red */
+ dk3ma_print_double_c8_no_sci(of, rgb.r);
+ fputs(f2lto_c8_kw[14], of);
+ /* green */
+ dk3ma_print_double_c8_no_sci(of, rgb.g);
+ fputs(f2lto_c8_kw[14], of);
+ /* blue */
+ dk3ma_print_double_c8_no_sci(of, rgb.b);
+ fputs(f2lto_c8_kw[16], of);
+ /* text */
+ if(((obj->dt).txt.ff) & DK3_FIG_FONT_FLAG_SPECIAL) {
+ if(job->stu8) {
+ f2lto_utf8_out((obj->dt).txt.st, of);
+ } else {
+ fputs((obj->dt).txt.st, of);
+ }
+ } else {
+ f2l_tool_tex_string(of, (obj->dt).txt.st);
+ }
+ fputs(f2lto_c8_kw[16], of);
+ if(job->mbox) {
+ /* } */
+ fputs(f2lto_c8_kw[16], of);
+ }
+ if(job->smash) {
+ /* } */
+ fputs(f2lto_c8_kw[16], of);
+ }
+}
+
+
+void
+f2l_tool_text_object(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y,
+ unsigned long nFonts
+)
+{
+ double an; /* Rotation in degree. */
+ double ian; /* Rotation as integer. */
+ int haverotation = 0; /* Flag: Have rotation. */
+
+ /* \put( */
+ fputs(f2lto_c8_kw[13], of);
+ /* x position */
+ dk3ma_print_double_c8_no_sci(of, x);
+ /* , */
+ fputs(f2lto_c8_kw[14], of);
+ /* y position */
+ dk3ma_print_double_c8_no_sci(of, y);
+ /* ){ */
+ fputs(f2lto_c8_kw[15], of);
+ if(fabs((obj->dt).txt.an) > 1.0e-6) {
+ haverotation = 1;
+ an = ((obj->dt).txt.an * 180.0) / M_PI;
+ ian = dk3ma_d_rint(an);
+ if(fabs(an - ian) < 1.0e-3) {
+ an = ian;
+ }
+ /* \rotatebox{ */
+ fputs(f2lto_c8_kw[17], of);
+ /* degrees */
+ dk3ma_print_double_c8_no_sci(of, an);
+ /* }{ */
+ fputs(f2lto_c8_kw[7], of);
+ }
+ /* \makebox(0,0)[ */
+ fputs(f2lto_c8_kw[18], of);
+ /* justification */
+ switch(obj->st) {
+ case 2: {
+ fputs(f2lto_c8_kw[22], of);
+ } break;
+ case 1: {
+ fputs(f2lto_c8_kw[21], of);
+ } break;
+ default: {
+ fputs(f2lto_c8_kw[20], of);
+ } break;
+ }
+ /* ]{ */
+ fputs(f2lto_c8_kw[19], of);
+ f2l_tool_inner_text_object(of, job, drw, obj, nFonts);
+ /* } */
+ fputs(f2lto_c8_kw[16], of);
+ if(haverotation) {
+ /* } */
+ fputs(f2lto_c8_kw[16], of);
+ }
+ /* } */
+ fputs(f2lto_c8_kw[16], of);
+ fputs(f2lto_c8_kw[26], of);
+}
+
+
+
+void
+f2l_tool_image_delete(f2l_image_t *im)
+{
+ $? "+ f2l_tool_image_delete"
+ if(im) { $? ". number = %lu", im->imageNumber
+ dk3_release(im->filename);
+ im->xo = NULL;
+ im->width = 0UL;
+ im->height = 0UL;
+ im->xres = 0.0;
+ im->yres = 0.0;
+ im->imageNumber = 0UL;
+ im->lineno = 0UL;
+ dk3_delete(im);
+ } $? "- f2l_tool_image_delete"
+}
+
+
+
+f2l_image_t *
+f2l_tool_image_new(char const *filename, dk3_app_t *app, unsigned long li)
+{
+ dk3_ufi_t ufi; /* Unique file identifier. */
+ f2l_image_t *back = NULL;
+ $? "+ f2l_tool_image_new"
+ if((filename) && (app)) {
+ if(dk3ufi_c8_get(&ufi, filename)) {
+ back = dk3_new_app(f2l_image_t,1,app);
+ if(back) {
+ dk3mem_cpy((void *)(&(back->ufi)), (void *)(&ufi), sizeof(dk3_ufi_t));
+ back->xo = NULL;
+ back->width = 0UL;
+ back->height = 0UL;
+ back->xres = 0.0;
+ back->yres = 0.0;
+ back->imageNumber = 0UL;
+ back->lineno = li;
+ back->filename = dk3str_c8_dup_app(filename, app);
+ if(!(back->filename)) {
+ f2l_tool_image_delete(back);
+ back = NULL;
+ }
+ }
+ }
+ } $? "- f2l_tool_image_new PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+int
+f2l_tool_compare_images(void const *l, void const *r, int cr)
+{
+ f2l_image_t const *pl; /* Left object. */
+ f2l_image_t const *pr; /* Right object. */
+ int back = 0;
+
+ if(l) {
+ if(r) {
+ pl = (f2l_image_t const *)l;
+ pr = (f2l_image_t const *)r;
+ switch(cr) {
+ case 1: {
+ back = dk3ufi_compare((void *)(&(pl->ufi)), r, 0);
+ } break;
+ default: {
+ back = dk3ufi_compare((void *)(&(pl->ufi)), (void *)(&(pr->ufi)), 0);
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+void
+f2l_tool_set_exit_status(f2l_job_t *job, int exval)
+{
+ if(job) {
+ if(0 == job->exval) {
+ job->exval = exval;
+ }
+ }
+}
+
+
+
+/** Write entire section of text to output file.
+ @param of Output file.
+ @param txt Pointer to array of text lines, NULL-finalized.
+*/
+static
+void
+f2l_tool_add_text_section_to_file(FILE *of, char const * const *txt)
+{
+ char const * const *ptr; /* Current line to add. */
+
+ ptr = txt;
+ while(*ptr) {
+ fputs(*ptr, of);
+ fputc('\n', of);
+ ptr++;
+ }
+}
+
+
+
+/** Write preamble part to output file, either the contents of a
+ file (if found) or a default text.
+ @param of Output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param fileName Name of file containing the preamble part.
+ @param preamble Default preamble text if fileName is not found.
+*/
+static
+void
+fl2_tool_write_preamble_part_or_file(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ char const *fileName,
+ char const * const *preamble
+)
+{
+ char line[1024]; /* Line buffer to read input file. */
+ FILE *fipo; /* Input file. */
+ int done = 0; /* Flag: Successfully handled file. */
+ $? "+ fl2_tool_write_preamble_part_or_file \"%!8s\"", TR_8STR(fileName)
+ fipo = fopen(fileName, f2lto_c8_kw[46]);
+ if(fipo) { $? ". fipo ok"
+ done = 1;
+ while(fgets(line, sizeof(line), fipo)) { $? ". line \"%!8s\"", line
+ dk3str_c8_chomp(line, NULL); $? ". chomp"
+ fputs(line, of); $? ". fputs"
+ fputc('\n', of); $? ". fputc"
+ }
+ fclose(fipo);
+ } else { $? "! failed to open file"
+ }
+ if(!(done)) { $? ". not yet done"
+ f2l_tool_add_text_section_to_file(of, preamble);
+ }
+ $? "- fl2_tool_write_preamble_part_or_file"
+}
+
+
+
+void
+f2l_tool_begin_latex_document(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw
+)
+{
+ fprintf(of, f2lto_c8_kw[40], job->tts);
+#if 0
+ f2l_tool_add_text_section_to_file(of, f2l_tool_preamble_1);
+#else
+ fl2_tool_write_preamble_part_or_file(
+ of, job, drw, f2lto_c8_kw[44], f2l_tool_preamble_1
+ );
+#endif
+#if 0
+ f2l_tool_add_text_section_to_file(of, f2l_tool_preamble_2);
+#else
+ fl2_tool_write_preamble_part_or_file(
+ of, job, drw, f2lto_c8_kw[45], f2l_tool_preamble_2
+ );
+#endif
+ f2l_tool_add_text_section_to_file(of, f2l_tool_preamble_3);
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_PGF:
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ fputs(f2lto_c8_kw[43], of);
+ } break;
+ }
+ fprintf(of, f2lto_c8_kw[41], job->lwidth);
+ fprintf(of, f2lto_c8_kw[42], job->lheight);
+ f2l_tool_add_text_section_to_file(of, f2l_tool_preamble_4);
+}
+
+
+
+void
+f2l_tool_end_latex_document(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw
+)
+{
+ fputs(f2lto_c8_kw[39], of);
+}
+
+
+
+int
+f2lto_find_draw_direction(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ dk3_fig_poly_point_t *po; /* Point set. */
+ size_t np; /* Number of points. */
+ int back = 0;
+ $? "+ f2lud_find_draw_direction"
+ if(DK3_FIG_SRCTYPE_JFIG != drw->srctype) { $? ". xfig/winfig"
+ po = (obj->dt).pol.po;
+ np = (obj->dt).pol.np;
+ if(4 <= np) { $? ". enough points"
+ if(po[1].x > (dk3ma_d_add_ok(po[0].x, 0.5, ec))) {
+ /* 0 on the left, 1 on the right */
+ if(po[3].y > (dk3ma_d_add_ok(po[0].y, 0.5, ec))) {
+ back = 0;
+ } else {
+ back = 1;
+ }
+ } else {
+ if(po[1].x < (dk3ma_d_sub_ok(po[0].x, 0.5, ec))) {
+ /* 0 on the right, 1 on the left. */
+ if(po[3].y > (dk3ma_d_add_ok(po[0].y, 0.5, ec))) {
+ back = 2;
+ } else {
+ back = 3;
+ }
+ } else {
+ /* 0 and 1 in one row. */
+ if(po[2].x > (dk3ma_d_add_ok(po[0].x, 0.5, ec))) {
+ /* 0 and 1 left */
+ if(po[1].y > (dk3ma_d_add_ok(po[0].y, 0.5, ec))) {
+ back = 0;
+ } else {
+ back = 1;
+ }
+ } else {
+ /* 0 and 1 right */
+ if(po[1].y > (dk3ma_d_add_ok(po[0].y, 0.5, ec))) {
+ back = 2;
+ } else {
+ back = 3;
+ }
+ }
+ }
+ }
+ if((obj->dt).pol.flf) { $? ". flip flag on"
+ back += 4;
+ } else { $? ". flip flag off"
+ }
+ } else { $? "! too few points"
+ }
+ } else { $? ". jFig file"
+ } $? "- f2lud_find_draw_direction %d", back
+ return back;
+}
+
+
+
+double
+f2lto_find_gap_length(f2l_job_t *job, double lw, double lsv)
+{
+ double back;
+ if(job->cols) {
+ back = lsv;
+ } else {
+ back = 0.5 * lw + 0.5 * lsv;
+ if((0.5 * back) > lw) {
+ back = 2.0 * lw;
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/f2lto.h b/support/dktools/f2lto.h
new file mode 100644
index 0000000000..b2d5b54a63
--- /dev/null
+++ b/support/dktools/f2lto.h
@@ -0,0 +1,298 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: f2lto.ctr
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file f2lto.h Header file for the f2lto module.
+*/
+
+#ifndef F2LTO_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define F2LTO_H_INCLUDED 1
+
+
+#line 9 "f2lto.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Register PS font in a storage.
+ @param sFonts Fonts storage.
+ @param iFonts Storage iterator.
+ @param nFonts Pointer to variable for total number of used
+ fonts.
+ @param fontno PS font number.
+ @param fontsize Font size.
+ @param app Application structure for diagnostics.
+ @return Pointer to text handling on success, NULL on error.
+*/
+f2l_text_handling_t *
+f2l_tool_register_font(
+ dk3_sto_t *sFonts,
+ dk3_sto_it_t *iFonts,
+ unsigned long *nFonts,
+ int fontno,
+ double fontsize,
+ dk3_app_t *app
+);
+
+/** Start LaTeX part of EPS+TEX or PDF+TEX.
+ @param of Output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param shortOutFile Short output file name of EPS or PDF file.
+ @param iFonts Font storage iterator.
+ @param nFonts Total number of fonts.
+*/
+void
+f2l_tool_start_tex_part(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ char const *shortOutFile,
+ dk3_sto_it_t *iFonts,
+ unsigned long nFonts
+);
+
+/** Start LaTeX part of EPS+TEX, PDF+TEX or PGF.
+ @param of Output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param shortOutFile Short output file name of EPS or PDF file.
+ @param iFonts Font storage iterator.
+ @param nFonts Total number of fonts.
+ @param wp Flag: With picture environments.
+*/
+void
+f2l_tool_start_tex_part_with_picture(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ char const *shortOutFile,
+ dk3_sto_it_t *iFonts,
+ unsigned long nFonts,
+ int wp
+);
+
+/** End LaTeX part of EPS+TEX or PDF+TEX.
+ @param of Output file.
+*/
+void
+f2l_tool_end_tex_part(
+ FILE *of
+);
+
+/** Write one font name.
+ @param of Output file.
+ @param fontno Number of font to write.
+ @param nFonts Total number of font definitions.
+*/
+void
+f2l_tool_write_font_name(
+ FILE *of,
+ unsigned long fontno,
+ unsigned long nFonts
+);
+
+/** Write inner part of text object.
+ This function is used both for writing to a picture environment
+ in a *.tex file and pgf text labels.
+ @param of Output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Text object.
+ @param nFonts Total number of PS fonts.
+*/
+void
+f2l_tool_inner_text_object(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ unsigned long nFonts
+);
+
+/** Write one text object to LaTeX output in a picture environment.
+ @param of Output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Text object.
+ @param x X position.
+ @param y Y position.
+ @param nFonts Total number of PS fonts.
+*/
+void
+f2l_tool_text_object(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y,
+ unsigned long nFonts
+);
+
+/** Write commands to choose a font.
+ @param of Output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Text object.
+ @param nFonts Total number of PS fonts.
+*/
+void
+f2l_tool_font_selection(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ unsigned long nFonts
+);
+
+/** Write string to LaTeX output.
+ @param of Output file.
+ @param txt String, ISO-LATIN-1 encoded.
+*/
+void
+f2l_tool_tex_string(
+ FILE *of,
+ char const *txt
+);
+
+/** Write instruction to select a font by features to LaTeX output.
+ @param of Output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Text object.
+ @param fontSize Font size.
+ @param fontFeatures Font features.
+ @param useFamily Flag: Choose font family.
+*/
+void
+f2l_tool_font_select_by_features(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double fontSize,
+ int fontFeatures,
+ int useFamily
+);
+
+/** Create image file data.
+ @param filename File name.
+ @param app Application structure for diagnostics.
+ @param li Line number of object definition.
+ @return Pointer to image file data on success, NULL on error.
+*/
+f2l_image_t *
+f2l_tool_image_new(char const *filename, dk3_app_t *app, unsigned long li);
+
+/** Destroy image data.
+ @param im Image data to destroy.
+*/
+void
+f2l_tool_image_delete(f2l_image_t *im);
+
+/** Compare two image entries.
+ @param l Left image entry.
+ @param r Right image entry or unique file identifier.
+ @param cr Comparison criteria (0=image/image, 1=image/ufi).
+ @return Comparison result.
+*/
+int
+f2l_tool_compare_images(void const *l, void const *r, int cr);
+
+/** Set exit status code to error code if exit status indicates success.
+ @param job Job structure.
+ @param exval Error code.
+*/
+void
+f2l_tool_set_exit_status(f2l_job_t *job, int exval);
+
+/** Begin LaTeX document (write document preamble and begin document line).
+ @param of Output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+void
+f2l_tool_begin_latex_document(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw
+);
+
+/** End LaTeX document (write end document line).
+ @param of Output file.
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+void
+f2l_tool_end_latex_document(
+ FILE *of,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw
+);
+
+/** Find drawing direction for embedded image.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param ec Pointer to error code variable, may be NULL.
+ @return Drawing direction.
+*/
+int
+f2lto_find_draw_direction(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int *ec
+);
+
+/** Find suitable length for gaps in line styles.
+ @param job Job structure.
+ @param lw Line width.
+ @param lsv Style value.
+ @return Gap length.
+*/
+double
+f2lto_find_gap_length(f2l_job_t *job, double lw, double lsv);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/f2lud.c b/support/dktools/f2lud.c
new file mode 100644
index 0000000000..c01721f5fd
--- /dev/null
+++ b/support/dktools/f2lud.c
@@ -0,0 +1,4012 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: f2lud.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file f2lud.c The f2lud module.
+*/
+
+
+#line 203 "f2lud.ctr"
+
+#include "dk3all.h"
+#include "dk3bezcu.h"
+#include "fig2lat.h"
+#include "dk3xsp.h"
+#include "f2lud.h"
+#include "f2lsvg.h"
+#include "f2lpgf.h"
+#include "f2lpdf.h"
+#include "f2leps.h"
+#include "dk3figto.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4vers.h"
+#include "f2ludpat.h"
+#include "f2lpara.h"
+
+
+
+
+
+#line 224 "f2lud.ctr"
+
+
+
+/** Keywords used by the module.
+*/
+static char const * const f2lud_c8_kw[] = {
+/* 0 */
+"fig object begin %lu, line %lu, type %ld %ld, layer %d",
+
+/* 1 */
+"fig object end %lu",
+
+/* 2 */
+"arrowhead forward begin, type=%d, fill=%d, length=%lg, width=%lg",
+
+/* 3 */
+"arrowhead forward end",
+
+/* 4 */
+"arrowhead backward begin, type=%d, fill=%d, length=%lg, width=%lg",
+
+/* 5 */
+"arrowhead backward end",
+
+/* 6 */
+"path object begin, type %ld %ld",
+
+/* 7 */
+"path object end",
+
+NULL
+
+
+#line 264 "f2lud.ctr"
+};
+
+
+
+/** Write debug line to output file.
+ @param job Job structure.
+ @param msg Text line without newline at end.
+*/
+static
+void
+f2lud_debug(
+ f2l_job_t *job,
+ char const *msg
+)
+{
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_debug(job, msg);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_debug(job, msg);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_debug(job, msg);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_debug(job, msg);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_debug(job, msg);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ f2lpgf_pgf_debug(job, msg);
+ } break;
+ }
+}
+
+
+
+/** Calculate factors for coordinates transformations.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lud_coordinates_transformation(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ double xmin; /* Minimum x in output space. */
+ double xmax; /* Maximum x in output space. */
+ double ymin; /* Minimum y in output space. */
+ double ymax; /* Maximum y in output space. */
+ double xdelta; /* Used width in output space. */
+ double ydelta; /* Used height in output space. */
+ double width; /* Bounding box width in output space. */
+ double height; /* Bounding box height in output space. */
+ int mec = 0; /* Mathematical error code. */
+ int back = 1;
+
+
+#line 324 "f2lud.ctr"
+ (job->ct2d).mx = dk3ma_d_div_ok( 72.0, drw->res, &mec);
+ (job->ct2d).my = dk3ma_d_div_ok(-72.0, drw->res, &mec);
+ xmin = dk3ma_d_mul_ok((job->ct2d).mx, (drw->bb).xmin, &mec);
+ xmax = dk3ma_d_mul_ok((job->ct2d).mx, (drw->bb).xmax, &mec);
+ ymax = dk3ma_d_mul_ok((job->ct2d).my, (drw->bb).ymin, &mec);
+ ymin = dk3ma_d_mul_ok((job->ct2d).my, (drw->bb).ymax, &mec);
+ xdelta = dk3ma_d_sub_ok(xmax, xmin, &mec);
+ ydelta = dk3ma_d_sub_ok(ymax, ymin, &mec);
+ job->width = width = ceil(xdelta);
+ job->height = height = ceil(ydelta);
+ job->lwidth = dk3ma_d_to_l_ok(width, &mec);
+ job->lheight = dk3ma_d_to_l_ok(height, &mec);
+ (job->ct2d).nx = 0.5 * dk3ma_d_sub_ok(width, xdelta, &mec);
+ (job->ct2d).ny = 0.5 * dk3ma_d_sub_ok(height, ydelta, &mec);
+ (job->ct2d).nx = dk3ma_d_sub_ok((job->ct2d).nx, xmin, &mec);
+ (job->ct2d).ny = dk3ma_d_sub_ok((job->ct2d).ny, ymin, &mec);
+
+
+#line 341 "f2lud.ctr"
+
+
+#line 342 "f2lud.ctr"
+ if(mec) {
+ back = 0;
+ /* ERROR: Math problem */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
+
+#line 347 "f2lud.ctr"
+ }
+
+#line 348 "f2lud.ctr"
+ return back;
+}
+
+
+
+/** Driver-specific initialization.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lud_driver_initialize(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ int back;
+
+
+#line 364 "f2lud.ctr"
+ back = f2lud_coordinates_transformation(job, drw);
+ if(back) {
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ back = f2lpgf_tex_initialize(job, drw);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ back = f2lpdf_tex_with_pdf_initialize(job, drw);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ back = f2lpdf_pdf_with_tex_initialize(job, drw);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ back = f2leps_eps_with_tex_initialize(job, drw);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ back = f2leps_eps_pure_initialize(job, drw);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ back = f2lpgf_pgf_initialize(job, drw);
+ } break;
+ }
+ }
+
+#line 388 "f2lud.ctr"
+ return back;
+}
+
+
+
+/** Release resources allocated by f2lud_driver_initialize().
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+static
+void
+f2lud_driver_end(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+
+
+#line 402 "f2lud.ctr"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_end(job, drw);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_end(job, drw);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_end(job, drw);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_end(job, drw);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_end(job, drw);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ f2lpgf_pgf_end(job, drw);
+ } break;
+ }
+
+
+#line 424 "f2lud.ctr"
+}
+
+
+
+/** Open output files.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lud_open_output_files(f2l_job_t *job)
+{
+ int back = 0;
+
+
+#line 438 "f2lud.ctr"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ back = f2lpgf_tex_open_output_files(job);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ back = f2lpdf_tex_with_pdf_open_output_files(job);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ back = f2lpdf_pdf_with_tex_open_output_files(job);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ back = f2leps_eps_with_tex_open_output_files(job);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ back = f2leps_eps_pure_open_output_files(job);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ back = f2lpgf_pgf_open_output_files(job);
+ } break;
+ }
+
+#line 459 "f2lud.ctr"
+ return back;
+}
+
+
+
+/** Close output files.
+ @param job Job structure.
+*/
+static
+void
+f2lud_close_output_files(f2l_job_t *job)
+{
+
+
+#line 472 "f2lud.ctr"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_close_output_files(job);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_close_output_files(job);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_close_output_files(job);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_close_output_files(job);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_close_output_files(job);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ f2lpgf_pgf_close_output_files(job);
+ } break;
+ }
+
+#line 493 "f2lud.ctr"
+}
+
+
+
+/** Write start of output.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lud_start_processing(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ int back = 0;
+
+
+#line 508 "f2lud.ctr"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ back = f2lpgf_tex_start_processing(job, drw);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ back = f2lpdf_tex_with_pdf_start_processing(job, drw);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ back = f2lpdf_pdf_with_tex_start_processing(job, drw);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ back = f2leps_eps_with_tex_start_processing(job, drw);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ back = f2leps_eps_pure_start_processing(job, drw);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ back = f2lpgf_pgf_start_processing(job, drw);
+ } break;
+ }
+
+#line 529 "f2lud.ctr"
+ return back;
+}
+
+
+
+/** Write end of output.
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+static
+void
+f2lud_end_processing(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+
+
+#line 543 "f2lud.ctr"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_end_processing(job, drw);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_end_processing(job, drw);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_end_processing(job, drw);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_end_processing(job, drw);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_end_processing(job, drw);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ f2lpgf_pgf_end_processing(job, drw);
+ } break;
+ }
+
+#line 564 "f2lud.ctr"
+}
+
+
+
+/** Process one text object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+static
+void
+f2lud_text_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ double x; /* X position of text object. */
+ double y; /* Y position of text object. */
+ int ec = 0; /* Mathematical error code. */
+
+
+#line 585 "f2lud.ctr"
+ if(!(DK3_FIG_FONT_FLAG_HIDDEN & ((obj->dt).txt.ff))) {
+ x = dk3ct_2d_x(&(job->ct2d), (obj->dt).txt.x, &ec);
+ y = dk3ct_2d_y(&(job->ct2d), (obj->dt).txt.y, &ec);
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_text_object(job, drw, obj, x, y);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_text_object(job, drw, obj, x, y);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_text_object(job, drw, obj, x, y);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_text_object(job, drw, obj, x, y);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_text_object(job, drw, obj, x, y);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ f2lpgf_pgf_text_object(job, drw, obj, x, y);
+ } break;
+ }
+ }
+ if(ec) {
+ /* ERROR: Math problem! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
+
+#line 614 "f2lud.ctr"
+ }
+
+
+#line 616 "f2lud.ctr"
+}
+
+
+
+/** Find bounding box for output coordinates.
+ @param bb Bounding box to set up.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Polygon/polyline object.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lud_find_bounding_box(
+ dk3_bb_t *bb,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ dk3_fig_poly_point_t *po; /* Current point. */
+ size_t np; /* Number of points. */
+ size_t i; /* Index of current point. */
+
+
+#line 641 "f2lud.ctr"
+ po = (obj->dt).pol.po;
+ np = (obj->dt).pol.np;
+ dk3bb_reset(bb);
+ for(i = 0; i < np; i++) {
+ dk3bb_add_x(bb, dk3ct_2d_x(&(job->ct2d), po->x, ec));
+ dk3bb_add_y(bb, dk3ct_2d_y(&(job->ct2d), po->y, ec));
+ po++;
+ }
+
+#line 649 "f2lud.ctr"
+}
+
+
+
+/** Process one image object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+static
+void
+f2lud_image_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ dk3_bb_t outbb; /* Image bounding box in output space. */
+ int ec = 0; /* Error code variable. */
+ int drawdir = 0; /* Drawing direction for embedded image. */
+
+
+#line 670 "f2lud.ctr"
+ dk3bb_reset(&outbb);
+ f2lud_find_bounding_box(&outbb, job, drw, obj, &ec);
+ drawdir = f2lto_find_draw_direction(job, drw, obj, &ec);
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_image_object(job, drw, obj, &outbb, drawdir, &ec);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_image_object(job, drw, obj, &outbb, drawdir, &ec);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_image_object(job, drw, obj, &outbb, drawdir, &ec);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_image_object(job, drw, obj, &outbb, drawdir, &ec);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_image_object(job, drw, obj, &outbb, drawdir, &ec);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ f2lpgf_pgf_image_object(job, drw, obj, &outbb, drawdir, &ec);
+ } break;
+ }
+ if(ec) {
+ /* ERROR: Math error! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
+
+#line 698 "f2lud.ctr"
+ }
+
+#line 699 "f2lud.ctr"
+}
+
+
+
+void
+f2lud_newpath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+
+
+#line 711 "f2lud.ctr"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_newpath(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_newpath(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_newpath(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_newpath(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_newpath(job, drw, obj);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ f2lpgf_pgf_newpath(job, drw, obj);
+ } break;
+ }
+
+#line 732 "f2lud.ctr"
+}
+
+
+
+void
+f2lud_moveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+
+
+#line 746 "f2lud.ctr"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_moveto(job, drw, obj, x, y);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_moveto(job, drw, obj, x, y);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_moveto(job, drw, obj, x, y);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_moveto(job, drw, obj, x, y);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_moveto(job, drw, obj, x, y);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ f2lpgf_pgf_moveto(job, drw, obj, x, y);
+ } break;
+ }
+
+#line 767 "f2lud.ctr"
+}
+
+
+
+void
+f2lud_lineto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+
+
+#line 781 "f2lud.ctr"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_lineto(job, drw, obj, x, y);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_lineto(job, drw, obj, x, y);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_lineto(job, drw, obj, x, y);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_lineto(job, drw, obj, x, y);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_lineto(job, drw, obj, x, y);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ f2lpgf_pgf_lineto(job, drw, obj, x, y);
+ } break;
+ }
+
+#line 802 "f2lud.ctr"
+}
+
+
+
+void
+f2lud_curveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double xcs,
+ double ycs,
+ double xce,
+ double yce,
+ double xe,
+ double ye
+)
+{
+
+
+#line 820 "f2lud.ctr"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_curveto(job, drw, obj, xcs, ycs, xce, yce, xe, ye);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_curveto(job, drw, obj, xcs, ycs, xce, yce, xe, ye);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_curveto(job, drw, obj, xcs, ycs, xce, yce, xe, ye);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_curveto(job, drw, obj, xcs, ycs, xce, yce, xe, ye);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_curveto(job, drw, obj, xcs, ycs, xce, yce, xe, ye);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ f2lpgf_pgf_curveto(job, drw, obj, xcs, ycs, xce, yce, xe, ye);
+ } break;
+ }
+
+#line 841 "f2lud.ctr"
+}
+
+
+
+void
+f2lud_fig_moveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y,
+ int *ec
+)
+{
+ double nx; /* Destination x in output space. */
+ double ny; /* Destination y in output space. */
+
+
+#line 858 "f2lud.ctr"
+ nx = dk3ct_2d_x(&(job->ct2d), x, ec);
+ ny = dk3ct_2d_y(&(job->ct2d), y, ec);
+ f2lud_moveto(job, drw, obj, nx, ny);
+
+
+#line 862 "f2lud.ctr"
+}
+
+
+
+void
+f2lud_fig_lineto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y,
+ int *ec
+)
+{
+ double nx; /* Destination x in output space. */
+ double ny; /* Destination y in output space. */
+
+
+#line 879 "f2lud.ctr"
+ nx = dk3ct_2d_x(&(job->ct2d), x, ec);
+ ny = dk3ct_2d_y(&(job->ct2d), y, ec);
+ f2lud_lineto(job, drw, obj, nx, ny);
+
+
+#line 883 "f2lud.ctr"
+}
+
+
+
+void
+f2lud_fig_curveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double xcs,
+ double ycs,
+ double xce,
+ double yce,
+ double xe,
+ double ye,
+ int *ec
+)
+{
+ double nxcs; /* First control point x in output space. */
+ double nycs; /* First control point y in output space. */
+ double nxce; /* Second control point x in output space. */
+ double nyce; /* Second control point y in output space. */
+ double nxe; /* End point x in output space. */
+ double nye; /* End point y in output space. */
+
+
+#line 908 "f2lud.ctr"
+ nxcs = dk3ct_2d_x(&(job->ct2d), xcs, ec);
+ nycs = dk3ct_2d_y(&(job->ct2d), ycs, ec);
+ nxce = dk3ct_2d_x(&(job->ct2d), xce, ec);
+ nyce = dk3ct_2d_y(&(job->ct2d), yce, ec);
+ nxe = dk3ct_2d_x(&(job->ct2d), xe, ec);
+ nye = dk3ct_2d_y(&(job->ct2d), ye, ec);
+ f2lud_curveto(job, drw, obj, nxcs, nycs, nxce, nyce, nxe, nye);
+
+
+#line 916 "f2lud.ctr"
+}
+
+
+
+void
+f2lud_closepath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+
+
+#line 928 "f2lud.ctr"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_closepath(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_closepath(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_closepath(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_closepath(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_closepath(job, drw, obj);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ f2lpgf_pgf_closepath(job, drw, obj);
+ } break;
+ }
+
+#line 949 "f2lud.ctr"
+}
+
+
+
+/** Issue "fill" command.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lud_fill(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+
+
+#line 966 "f2lud.ctr"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_fill(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_fill(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_fill(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_fill(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_fill(job, drw, obj);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ f2lpgf_pgf_fill(job, drw, obj);
+ } break;
+ }
+
+#line 987 "f2lud.ctr"
+}
+
+
+
+/** Issue combined "fill" and "clip" command.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+static
+void
+f2lud_fill_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+
+
+#line 1005 "f2lud.ctr"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_fill_clip(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_PGF: {
+ f2lpgf_pgf_fill_clip(job, drw, obj);
+ } break;
+ /* @DRIVER@ universal */
+ }
+
+#line 1014 "f2lud.ctr"
+}
+
+
+
+/** Issue combined "fill", "stroke", and "clip" command.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+static
+void
+f2lud_fill_stroke_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+
+
+#line 1032 "f2lud.ctr"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_fill_stroke_clip(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_PGF: {
+ f2lpgf_pgf_fill_stroke_clip(job, drw, obj);
+ } break;
+ /* @DRIVER@ universal */
+ }
+
+#line 1041 "f2lud.ctr"
+}
+
+
+
+/** Issue combined "fill" and "stroke" command.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+static
+void
+f2lud_fill_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+
+
+#line 1059 "f2lud.ctr"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_fill_stroke(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_PGF: {
+ f2lpgf_pgf_fill_stroke(job, drw, obj);
+ } break;
+ /* @DRIVER@ universal */
+ }
+
+#line 1068 "f2lud.ctr"
+}
+
+
+
+void
+f2lud_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+
+
+#line 1080 "f2lud.ctr"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_stroke(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_stroke(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_stroke(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_stroke(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_stroke(job, drw, obj);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ f2lpgf_pgf_stroke(job, drw, obj);
+ } break;
+ }
+
+#line 1101 "f2lud.ctr"
+}
+
+
+
+/** Issue "clip" command.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+static
+void
+f2lud_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+
+
+#line 1119 "f2lud.ctr"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_clip(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_clip(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_clip(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_clip(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_clip(job, drw, obj);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ f2lpgf_pgf_clip(job, drw, obj);
+ } break;
+ }
+
+#line 1140 "f2lud.ctr"
+}
+
+
+
+/** Issue "gsave" command.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+static
+void
+f2lud_gsave(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+
+
+#line 1158 "f2lud.ctr"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_gsave(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_gsave(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_gsave(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_gsave(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_gsave(job, drw, obj);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ f2lpgf_pgf_gsave(job, drw, obj);
+ } break;
+ }
+
+#line 1179 "f2lud.ctr"
+}
+
+
+
+/** Issue "grestore" command.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+static
+void
+f2lud_grestore(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+
+
+#line 1197 "f2lud.ctr"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_grestore(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_grestore(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_grestore(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_grestore(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_grestore(job, drw, obj);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ f2lpgf_pgf_grestore(job, drw, obj);
+ } break;
+ }
+
+#line 1218 "f2lud.ctr"
+}
+
+
+
+/** Create path for ellipse object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param ec Pointe to error code variable, may be NULL.
+*/
+static
+void
+f2lud_create_ellipse_path(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ dk3_fig_poly_point_t po[12]; /* Points in Fig space. */
+ double myan; /* Rotation angle in Fig space. */
+ size_t i; /* Index of current point to modify. */
+
+
+#line 1241 "f2lud.ctr"
+ po[0].x = (obj->dt).ell.rx;
+ po[0].y = 0.0;
+ po[1].x = (obj->dt).ell.rx;
+ po[1].y = FIG2LAT_CIRCLE_QUADRANT_BEZIER * (obj->dt).ell.ry;
+ po[2].x = FIG2LAT_CIRCLE_QUADRANT_BEZIER * (obj->dt).ell.rx;
+ po[2].y = (obj->dt).ell.ry;
+ po[3].x = 0.0;
+ po[3].y = (obj->dt).ell.ry;
+ po[4].x = 0.0 - po[2].x;
+ po[4].y = po[2].y;
+ po[5].x = 0.0 - po[1].x;
+ po[5].y = po[1].y;
+ po[6].x = 0.0 - po[0].x;
+ po[6].y = 0.0;
+ po[7].x = po[6].x;
+ po[7].y = 0.0 - po[5].y;
+ po[8].x = po[4].x;
+ po[8].y = 0.0 - po[2].y;
+ po[9].x = 0.0;
+ po[9].y = 0.0 - po[3].y;
+ po[10].x = po[2].x;
+ po[10].y = po[9].y;
+ po[11].x = po[1].x;
+ po[11].y = po[7].y;
+ switch(obj->st) {
+ case 1: case 2: {
+ if(1.0e-6 < fabs((obj->dt).ell.an)) {
+ if(1.0e-6 < fabs(dk3ma_d_sub_ok((obj->dt).ell.rx,(obj->dt).ell.ry,ec)))
+ {
+ myan = -1.0 * (obj->dt).ell.an;
+ for(i = 0; i < 12; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), myan, ec);
+ }
+ }
+ }
+ } break;
+ }
+ for(i = 0; i < 12; i++) {
+ dk3fig_tool_shift_point(&(po[i]), (obj->dt).ell.cx, (obj->dt).ell.cy, ec);
+ }
+ f2lud_fig_moveto(job, drw, obj, po[0].x, po[0].y, ec);
+ f2lud_fig_curveto(
+ job, drw, obj,
+ po[1].x, po[1].y, po[2].x, po[2].y, po[3].x, po[3].y,
+ ec
+ );
+ f2lud_fig_curveto(
+ job, drw, obj,
+ po[4].x, po[4].y, po[5].x, po[5].y, po[6].x, po[6].y,
+ ec
+ );
+ f2lud_fig_curveto(
+ job, drw, obj,
+ po[7].x, po[7].y, po[8].x, po[8].y, po[9].x, po[9].y,
+ ec
+ );
+ f2lud_fig_curveto(
+ job, drw, obj,
+ po[10].x, po[10].y, po[11].x, po[11].y, po[0].x, po[0].y,
+ ec
+ );
+
+
+#line 1303 "f2lud.ctr"
+}
+
+
+
+/** Create path for polygon object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param ec Pointe to error code variable, may be NULL.
+*/
+static
+void
+f2lud_create_polygon_path(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ dk3_fig_poly_point_t *po; /* Current point to process. */
+ size_t np; /* Number of points. */
+ size_t i; /* Index of current point. */
+
+
+#line 1326 "f2lud.ctr"
+ po = (obj->dt).pol.po;
+ np = (obj->dt).pol.np;
+ for(i = 0; i < np; i++) {
+ if(0 == i) {
+ f2lud_fig_moveto(job, drw, obj, po->x, po->y, ec);
+ } else {
+ f2lud_fig_lineto(job, drw, obj, po->x, po->y, ec);
+ }
+ po++;
+ }
+ if(obj->cl) {
+ po = (obj->dt).pol.po;
+ f2lud_fig_lineto(job, drw, obj, po->x, po->y, ec);
+ }
+
+#line 1340 "f2lud.ctr"
+}
+
+
+
+/** Create path for box object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param ec Pointe to error code variable, may be NULL.
+*/
+static
+void
+f2lud_create_box_path(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ dk3_bb_t outbb; /* Box coordinates in output space. */
+
+
+#line 1361 "f2lud.ctr"
+ dk3bb_reset(&outbb);
+ f2lud_find_bounding_box(&outbb, job, drw, obj, ec);
+ f2lud_moveto(job, drw, obj, outbb.xmin, outbb.ymin);
+ f2lud_lineto(job, drw, obj, outbb.xmax, outbb.ymin);
+ f2lud_lineto(job, drw, obj, outbb.xmax, outbb.ymax);
+ f2lud_lineto(job, drw, obj, outbb.xmin, outbb.ymax);
+ f2lud_lineto(job, drw, obj, outbb.xmin, outbb.ymin);
+
+
+#line 1369 "f2lud.ctr"
+}
+
+
+
+/** Create path for arc box object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param ec Pointe to error code variable, may be NULL.
+*/
+static
+void
+f2lud_create_arc_box_path(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ dk3_fig_poly_point_t po[16]; /* Box points in output space. */
+ dk3_bb_t outbb; /* Box coordinates in output space. */
+ double r; /* Corner radius in output space. */
+ double maxr; /* Maximum value for corner radius. */
+ double corner; /* Factor control to end. */
+ double rc; /* Dist of control to end in output space. */
+
+
+#line 1395 "f2lud.ctr"
+ dk3bb_reset(&outbb);
+ f2lud_find_bounding_box(&outbb, job, drw, obj, ec);
+#if VERSION_BEFORE_20140808
+ r = dk3ct_2d_r(&(job->ct2d), (obj->dt).pol.ra, ec);
+
+#line 1399 "f2lud.ctr"
+#else
+ r = 0.9 * (obj->dt).pol.ra;
+
+#line 1401 "f2lud.ctr"
+#endif
+ maxr = 0.49 * fabs(dk3ma_d_sub_ok(outbb.xmax, outbb.xmin, ec));
+ if(r > maxr) r = maxr;
+ maxr = 0.49 * fabs(dk3ma_d_sub_ok(outbb.ymax, outbb.ymin, ec));
+ if(r > maxr) r = maxr;
+ corner = 1.0 - FIG2LAT_CIRCLE_QUADRANT_BEZIER;
+ rc = r * corner;
+ /* Bottom line */
+ po[0].x = dk3ma_d_add_ok(outbb.xmin, r, ec);
+ po[0].y = outbb.ymin;
+ po[1].x = dk3ma_d_sub_ok(outbb.xmax, r, ec);
+ po[1].y = po[0].y;
+ /* Lower right corner control points */
+ po[2].x = dk3ma_d_sub_ok(outbb.xmax, rc, ec);
+ po[2].y = po[0].y;
+ po[3].x = outbb.xmax;
+ po[3].y = dk3ma_d_add_ok(outbb.ymin, rc, ec);
+ /* Right line */
+ po[4].x = outbb.xmax;
+ po[4].y = dk3ma_d_add_ok(outbb.ymin, r, ec);
+ po[5].x = outbb.xmax;
+ po[5].y = dk3ma_d_sub_ok(outbb.ymax, r, ec);
+ /* Upper right corner control points */
+ po[6].x = outbb.xmax;
+ po[6].y = dk3ma_d_sub_ok(outbb.ymax, rc, ec);
+ po[7].x = dk3ma_d_sub_ok(outbb.xmax, rc, ec);
+ po[7].y = outbb.ymax;
+ /* Top line */
+ po[8].x = dk3ma_d_sub_ok(outbb.xmax, r, ec);
+ po[8].y = outbb.ymax;
+ po[9].x = dk3ma_d_add_ok(outbb.xmin, r, ec);
+ po[9].y = outbb.ymax;
+ /* Upper left corner control points */
+ po[10].x = dk3ma_d_add_ok(outbb.xmin, rc, ec);
+ po[10].y = outbb.ymax;
+ po[11].x = outbb.xmin;
+ po[11].y = dk3ma_d_sub_ok(outbb.ymax, rc, ec);
+ /* Left line */
+ po[12].x = outbb.xmin;
+ po[12].y = dk3ma_d_sub_ok(outbb.ymax, r, ec);
+ po[13].x = outbb.xmin;
+ po[13].y = dk3ma_d_add_ok(outbb.ymin, r, ec);
+ /* Lower left corner control points */
+ po[14].x = outbb.xmin;
+ po[14].y = dk3ma_d_add_ok(outbb.ymin, rc, ec);
+ po[15].x = dk3ma_d_add_ok(outbb.xmin, rc, ec);
+ po[15].y = outbb.ymin;
+ f2lud_moveto(job, drw, obj, po[0].x, po[0].y);
+ f2lud_lineto(job, drw, obj, po[1].x, po[1].y);
+ f2lud_curveto(
+ job, drw, obj,
+ po[2].x, po[2].y, po[3].x, po[3].y, po[4].x, po[4].y
+ );
+ f2lud_lineto(job, drw, obj, po[5].x, po[5].y);
+ f2lud_curveto(
+ job, drw, obj,
+ po[6].x, po[6].y, po[7].x, po[7].y, po[8].x, po[8].y
+ );
+ f2lud_lineto(job, drw, obj, po[9].x, po[9].y);
+ f2lud_curveto(
+ job, drw, obj,
+ po[10].x, po[10].y, po[11].x, po[11].y, po[12].x, po[12].y
+ );
+ f2lud_lineto(job, drw, obj, po[13].x, po[13].y);
+ f2lud_curveto(
+ job, drw, obj,
+ po[14].x, po[14].y, po[15].x, po[15].y, po[0].x, po[0].y
+ );
+
+
+#line 1470 "f2lud.ctr"
+}
+
+
+
+/** Create path for the last partial X-spline segment from closed X-spline.
+ @param job Job structure.
+ @param drw Fig drawing.
+ @param obj Fig object.
+ @param sp Spline points array.
+ @param np Number of spline points.
+ @param i Current segment index.
+ @param te Parameter t for end point.
+ @param isfirst Flag: First segment.
+ @param iscl Flag: Closed spline.
+ @param primary Flag: Primary (1=primary object, 0=arrowhead).
+ @param ec Pointer to error code variable, may be NULL.
+*/
+static
+void
+f2lud_final_spline_segment(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_spline_point_t *sp,
+ size_t np,
+ size_t i,
+ double te,
+ int isfirst,
+ int iscl,
+ int primary,
+ int *ec
+)
+{
+ dk3_xspline_segment_t seg; /* Segment for caluclation. */
+ dk3_fig_spline_point_t *pa = NULL; /* Left neighbour. */
+ dk3_fig_spline_point_t *pb = NULL; /* Start. */
+ dk3_fig_spline_point_t *pc = NULL; /* End. */
+ dk3_fig_spline_point_t *pd = NULL; /* Right neighbour. */
+ double myte; /* t for end. */
+ double dnumsegs; /* Number of segments. */
+ double factor; /* Scale factor for deriv. */
+ double t; /* Current t. */
+ double x; /* Bezier end x. */
+ double y; /* Bezier end y. */
+ double dxdt; /* Bezier dx/dt at end. */
+ double dydt; /* Bezier dy/dt at end. */
+ double lastx = 0.0; /* Bezier start x. */
+ double lasty = 0.0; /* Bezier start y. */
+ double lastdxdt = 0.0; /* dx/dt at start. */
+ double lastdydt = 0.0; /* dy/dt at end. */
+ size_t nsegs; /* Number of segments. */
+ size_t iseg; /* Current segment. */
+ int res; /* Calculation result. */
+
+
+#line 1524 "f2lud.ctr"
+ myte = dk3ma_d_sub_ok(te, floor(te), ec);
+
+#line 1525 "f2lud.ctr"
+ dnumsegs = myte * dk3fig_tool_xssbs(drw, primary);
+ dnumsegs = ceil(dnumsegs);
+
+#line 1527 "f2lud.ctr"
+ nsegs = dk3ma_d_to_sz_ok(dnumsegs, ec);
+
+#line 1528 "f2lud.ctr"
+ pb = &(sp[i]);
+ pc = &(sp[i + 1]);
+ if(0 < i) {
+ pa = &(sp[i - 1]);
+ }
+ if(i < (np - 2)) {
+ pd = &(sp[i + 2]);
+ }
+ factor = myte / (double)nsegs;
+
+#line 1537 "f2lud.ctr"
+ dk3xsp_reset(&seg);
+ if(job->cosp) { dk3xsp_set_cb(&seg, 1); }
+ dk3xsp_set(&seg, pa, pb, pc, pd);
+ if(dk3xsp_calculate(&seg, 0.0, 1)) {
+ lastx = dk3xsp_get_x(&seg);
+ lasty = dk3xsp_get_y(&seg);
+ lastdxdt = dk3xsp_get_dxdt(&seg);
+ lastdydt = dk3xsp_get_dydt(&seg);
+ lastdxdt = (factor * lastdxdt) / 3.0;
+ lastdydt = (factor * lastdydt) / 3.0;
+ /* Move to start point.
+ */
+ if(isfirst) {
+ f2lud_fig_moveto(job, drw, obj, lastx, lasty, ec);
+ }
+ /* Further curve only if te > 1.0e-6.
+ For smaller te draw straight line.
+ */
+ if(1.0e-6 < myte) {
+
+#line 1556 "f2lud.ctr"
+ for(iseg = 0; iseg < nsegs; iseg++) {
+ if(iseg < (nsegs - 1)) {
+
+#line 1558 "f2lud.ctr"
+ t = (double)(iseg + 1) / (double)nsegs;
+ t = t * myte;
+ } else {
+
+#line 1561 "f2lud.ctr"
+ t = myte;
+ }
+
+#line 1563 "f2lud.ctr"
+ res = dk3xsp_calculate(&seg, t, 1);
+ if(!(res)) {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ x = dk3xsp_get_x(&seg);
+ y = dk3xsp_get_y(&seg);
+ dxdt = dk3xsp_get_dxdt(&seg);
+ dydt = dk3xsp_get_dydt(&seg);
+ dxdt = (factor * dxdt) / 3.0;
+ dydt = (factor * dydt) / 3.0;
+ f2lud_fig_curveto(
+ job, drw, obj,
+ dk3ma_d_add_ok(lastx, lastdxdt, ec),
+ dk3ma_d_add_ok(lasty, lastdydt, ec),
+ dk3ma_d_sub_ok(x, dxdt, ec),
+ dk3ma_d_sub_ok(y, dydt, ec),
+ x, y,
+ ec
+ );
+ lastx = x; lasty = y; lastdxdt = dxdt; lastdydt = dydt;
+ }
+ } else {
+
+#line 1585 "f2lud.ctr"
+ res = dk3xsp_calculate(&seg, myte, 0);
+ if(!(res)) {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ /* ERROR: Math */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 36);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
+
+#line 1591 "f2lud.ctr"
+ }
+ x = dk3xsp_get_x(&seg);
+ y = dk3xsp_get_y(&seg);
+ f2lud_fig_lineto(job, drw, obj, x, y, ec);
+ }
+ } else {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
+
+#line 1599 "f2lud.ctr"
+ }
+
+
+#line 1601 "f2lud.ctr"
+}
+
+
+
+/** Create path for the first partial X-spline segment from closed X-spline.
+ @param job Job structure.
+ @param drw Fig drawing.
+ @param obj Fig object.
+ @param sp Spline points array.
+ @param np Number of spline points.
+ @param i Current segment index.
+ @param ts Parameter t for start point.
+ @param isfirst Flag: First segment.
+ @param iscl Flag: Closed spline.
+ @param primary Flag: Primary (1=primary object, 0=arrowhead).
+ @param ec Pointer to error code variable, may be NULL.
+*/
+static
+void
+f2lud_first_spline_segment(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_spline_point_t *sp,
+ size_t np,
+ size_t i,
+ double ts,
+ int isfirst,
+ int iscl,
+ int primary,
+ int *ec
+)
+{
+ dk3_xspline_segment_t seg; /* Segment for caluclation. */
+ dk3_fig_spline_point_t *pa = NULL; /* Left neighbour. */
+ dk3_fig_spline_point_t *pb = NULL; /* Start. */
+ dk3_fig_spline_point_t *pc = NULL; /* End. */
+ dk3_fig_spline_point_t *pd = NULL; /* Right neighbour. */
+ double myts; /* t for start. */
+ double dnumsegs; /* Number of segments. */
+ double factor; /* Scale factor for deriv. */
+ double t; /* Current t. */
+ double x; /* Bezier end x. */
+ double y; /* Bezier end y. */
+ double dxdt; /* Bezier dx/dt at end. */
+ double dydt; /* Bezier dy/dt at end. */
+ double lastx = 0.0; /* Bezier start x. */
+ double lasty = 0.0; /* Bezier start y. */
+ double lastdxdt = 0.0; /* dx/dt at start. */
+ double lastdydt = 0.0; /* dy/dt at end. */
+ size_t nsegs; /* Number of segments. */
+ size_t iseg; /* Current segment. */
+ int res; /* Calculation result. */
+
+
+#line 1655 "f2lud.ctr"
+ myts = dk3ma_d_sub_ok(ts, floor(ts), ec);
+
+#line 1656 "f2lud.ctr"
+ dnumsegs = (1.0 - myts) * dk3fig_tool_xssbs(drw, primary);
+ dnumsegs = ceil(dnumsegs);
+
+#line 1658 "f2lud.ctr"
+ nsegs = dk3ma_d_to_sz_ok(dnumsegs, ec);
+
+#line 1659 "f2lud.ctr"
+ pb = &(sp[i]);
+ pc = &(sp[i + 1]);
+ if(0 < i) {
+ pa = &(sp[i - 1]);
+ }
+ if(i < (np - 2)) {
+ pd = &(sp[i + 2]);
+ }
+ factor = (1.0 - myts) / (double)nsegs;
+
+#line 1668 "f2lud.ctr"
+ dk3xsp_reset(&seg);
+ if(job->cosp) { dk3xsp_set_cb(&seg, 1); }
+ dk3xsp_set(&seg, pa, pb, pc, pd);
+ if(dk3xsp_calculate(&seg, myts, 1)) {
+ /* If necessary move to the start point.
+ */
+ lastx = dk3xsp_get_x(&seg);
+ lasty = dk3xsp_get_y(&seg);
+ lastdxdt = dk3xsp_get_dxdt(&seg);
+ lastdydt = dk3xsp_get_dydt(&seg);
+ lastdxdt = (factor * lastdxdt) / 3.0;
+ lastdydt = (factor * lastdydt) / 3.0;
+ if(isfirst) {
+ f2lud_fig_moveto(job, drw, obj, lastx, lasty, ec);
+ }
+ if(1.0e-6 < (1.0 - myts)) {
+ for(iseg = 0; iseg < nsegs; iseg++) {
+ if(iseg < (nsegs - 1)) {
+ t = myts + (((1.0 - myts) * ((double)(iseg + 1))) / ((double)nsegs));
+ } else {
+ t = 1.0;
+ }
+ res = dk3xsp_calculate(&seg, t, 1);
+ if(!(res)) {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ x = dk3xsp_get_x(&seg);
+ y = dk3xsp_get_y(&seg);
+ dxdt = dk3xsp_get_dxdt(&seg);
+ dydt = dk3xsp_get_dydt(&seg);
+ dxdt = (factor * dxdt) / 3.0;
+ dydt = (factor * dydt) / 3.0;
+ f2lud_fig_curveto(
+ job, drw, obj,
+ dk3ma_d_add_ok(lastx, lastdxdt, ec),
+ dk3ma_d_add_ok(lasty, lastdydt, ec),
+ dk3ma_d_sub_ok(x, dxdt, ec),
+ dk3ma_d_sub_ok(y, dydt, ec),
+ x, y,
+ ec
+ );
+ lastx = x; lasty = y; lastdxdt = dxdt; lastdydt = dydt;
+ }
+ } else {
+ res = dk3xsp_calculate(&seg, 1.0, 0);
+ if(!(res)) {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ /* ERROR: Math */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 36);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
+
+#line 1718 "f2lud.ctr"
+ }
+ x = dk3xsp_get_x(&seg);
+ y = dk3xsp_get_y(&seg);
+ f2lud_fig_lineto(job, drw, obj, x, y, ec);
+ }
+ } else {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
+
+#line 1726 "f2lud.ctr"
+ }
+
+
+#line 1728 "f2lud.ctr"
+}
+
+
+
+
+/** Create path for the single partial X-spline segment cutted on both ends
+ from closed X-spline.
+ @param job Job structure.
+ @param drw Fig drawing.
+ @param obj Fig object.
+ @param sp Spline points array.
+ @param np Number of spline points.
+ @param i Current segment index.
+ @param ts Parameter t for start point.
+ @param te Parameter t for end point.
+ @param isfirst Flag: First segment.
+ @param iscl Flag: Closed spline.
+ @param primary Flag: Primary (1=primary object, 0=arrowhead).
+ @param ec Pointer to error code variable, may be NULL.
+*/
+static
+void
+f2lud_single_spline_segment(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_spline_point_t *sp,
+ size_t np,
+ size_t i,
+ double ts,
+ double te,
+ int isfirst,
+ int iscl,
+ int primary,
+ int *ec
+)
+{
+ dk3_xspline_segment_t seg; /* Segment for caluclation. */
+ dk3_fig_spline_point_t *pa = NULL; /* Left neighbour. */
+ dk3_fig_spline_point_t *pb = NULL; /* Start. */
+ dk3_fig_spline_point_t *pc = NULL; /* End. */
+ dk3_fig_spline_point_t *pd = NULL; /* Right neighbour. */
+ double myte; /* t for end. */
+ double myts; /* t for start. */
+ double dnumsegs; /* Number of segments. */
+ double factor; /* Scale factor for deriv. */
+ double t; /* Current t. */
+ double x; /* Bezier end x. */
+ double y; /* Bezier end y. */
+ double dxdt; /* Bezier dx/dt at end. */
+ double dydt; /* Bezier dy/dt at end. */
+ double lastx = 0.0; /* Bezier start x. */
+ double lasty = 0.0; /* Bezier start y. */
+ double lastdxdt = 0.0; /* dx/dt at start. */
+ double lastdydt = 0.0; /* dy/dt at end. */
+ size_t nsegs; /* Number of segments. */
+ size_t iseg; /* Current segment. */
+ int res; /* Calculation result. */
+
+
+#line 1787 "f2lud.ctr"
+ myte = dk3ma_d_sub_ok(te, floor(te), ec);
+ myts = dk3ma_d_sub_ok(ts, floor(ts), ec);
+ dnumsegs = (myte - myts) * dk3fig_tool_xssbs(drw, primary);
+ dnumsegs = ceil(dnumsegs);
+
+#line 1791 "f2lud.ctr"
+ nsegs = dk3ma_d_to_sz_ok(dnumsegs, ec);
+ pb = &(sp[i]);
+ pc = &(sp[i + 1]);
+ if(0 < i) {
+ pa = &(sp[i - 1]);
+ }
+ if(i < (np - 2)) {
+ pd = &(sp[i + 2]);
+ }
+ factor = (myte - myts) / ((double)nsegs);
+ dk3xsp_reset(&seg);
+ if(job->cosp) { dk3xsp_set_cb(&seg, 1); }
+ dk3xsp_set(&seg, pa, pb, pc, pd);
+ if(dk3xsp_calculate(&seg, myts, 1)) {
+ lastx = dk3xsp_get_x(&seg);
+ lasty = dk3xsp_get_y(&seg);
+ lastdxdt = dk3xsp_get_dxdt(&seg);
+ lastdydt = dk3xsp_get_dydt(&seg);
+ lastdxdt = (factor * lastdxdt) / 3.0;
+ lastdydt = (factor * lastdydt) / 3.0;
+ if(isfirst) {
+ f2lud_fig_moveto(job, drw, obj, lastx, lasty, ec);
+ }
+ if(1.0e-6 < (myte - myts)) {
+ for(iseg = 0; iseg < nsegs; iseg++) {
+ if(iseg < (nsegs - 1)) {
+ t = myts + (((myte - myts) * ((double)(iseg + 1))) / ((double)nsegs));
+ } else {
+ t = myte;
+ }
+ res = dk3xsp_calculate(&seg, t, 1);
+ if(!(res)) {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ x = dk3xsp_get_x(&seg);
+ y = dk3xsp_get_y(&seg);
+ dxdt = dk3xsp_get_dxdt(&seg);
+ dydt = dk3xsp_get_dydt(&seg);
+ dxdt = (factor * dxdt) / 3.0;
+ dydt = (factor * dydt) / 3.0;
+ f2lud_fig_curveto(
+ job, drw, obj,
+ dk3ma_d_add_ok(lastx, lastdxdt, ec),
+ dk3ma_d_add_ok(lasty, lastdydt, ec),
+ dk3ma_d_sub_ok(x, dxdt, ec),
+ dk3ma_d_sub_ok(y, dydt, ec),
+ x, y,
+ ec
+ );
+ lastx = x; lasty = y; lastdxdt = dxdt; lastdydt = dydt;
+ }
+ } else {
+ res = dk3xsp_calculate(&seg, myte, 0);
+ if(!(res)) {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ /* ERROR: Calculation failed! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 36);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
+
+#line 1849 "f2lud.ctr"
+ }
+ x = dk3xsp_get_x(&seg);
+ y = dk3xsp_get_y(&seg);
+ f2lud_fig_lineto(job, drw, obj, x, y, ec);
+ }
+ } else {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ /* ERROR: Calculation failed! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 36);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
+
+#line 1859 "f2lud.ctr"
+ }
+
+
+#line 1861 "f2lud.ctr"
+}
+
+
+
+
+/** Create path for one complete X-spline segment from closed X-spline.
+ @param job Job structure.
+ @param drw Fig drawing.
+ @param obj Fig object.
+ @param sp Spline points array.
+ @param np Number of spline points.
+ @param i Current segment index.
+ @param isfirst Flag: First segment.
+ @param iscl Flag: Closed spline.
+ @param primary Flag: Primary (1=primary object, 0=arrowhead).
+ @param ec Pointer to error code variable, may be NULL.
+*/
+static
+void
+f2lud_full_spline_segment(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_spline_point_t *sp,
+ size_t np,
+ size_t i,
+ int isfirst,
+ int iscl,
+ int primary,
+ int *ec
+)
+{
+ dk3_xspline_segment_t seg; /* Segment for caluclation. */
+ dk3_fig_spline_point_t *pa = NULL; /* Left neighbour. */
+ dk3_fig_spline_point_t *pb = NULL; /* Start. */
+ dk3_fig_spline_point_t *pc = NULL; /* End. */
+ dk3_fig_spline_point_t *pd = NULL; /* Right neighbour. */
+ double factor; /* Scale factor for deriv. */
+ double t; /* Current t. */
+ double x; /* Bezier end x. */
+ double y; /* Bezier end y. */
+ double dxdt; /* Bezier dx/dt at end. */
+ double dydt; /* Bezier dy/dt at end. */
+ double lastx = 0.0; /* Bezier start x. */
+ double lasty = 0.0; /* Bezier start y. */
+ double lastdxdt = 0.0; /* dx/dt at start. */
+ double lastdydt = 0.0; /* dy/dt at end. */
+ size_t xsss; /* Number of segments. */
+ size_t iseg; /* Current segment. */
+ size_t ic;
+ size_t id;
+ int res; /* Calculation result. */
+
+
+#line 1914 "f2lud.ctr"
+ if(i < ((iscl) ? np : (np - 1))) {
+ pb = &(sp[i]);
+ ic = i + 1; while(ic >= np) { ic = ic - np; }
+ pc = &(sp[ic]);
+ if(i > 0) {
+ pa = &(sp[i - 1]);
+ } else {
+ if(iscl) {
+ pa = &(sp[np - 1]);
+ }
+ }
+ if(i < (np - 2)) {
+ pd = &(sp[i + 2]);
+ } else {
+ if(iscl) {
+ id = i + 2; while(id >= np) { id = id - np; }
+ pd = &(sp[id]);
+ }
+ }
+ xsss = dk3fig_tool_xssbs(drw, primary);
+ factor = 1.0 / (double)xsss;
+ dk3xsp_reset(&seg);
+ if(job->cosp) { dk3xsp_set_cb(&seg, 1); }
+ dk3xsp_set(&seg, pa, pb, pc, pd);
+ if(dk3xsp_calculate(&seg, 0.0, 1)) {
+ lastx = dk3xsp_get_x(&seg);
+ lasty = dk3xsp_get_y(&seg);
+ lastdxdt = dk3xsp_get_dxdt(&seg);
+ lastdydt = dk3xsp_get_dydt(&seg);
+ lastdxdt = (factor * lastdxdt) / 3.0;
+ lastdydt = (factor * lastdydt) / 3.0;
+ if(isfirst) {
+ f2lud_fig_moveto(job, drw, obj, lastx, lasty, ec);
+ }
+ for(iseg = 0; iseg < xsss; iseg++) {
+ if(iseg < (xsss - 1)) {
+ t = (double)(iseg + 1) / (double)xsss;
+ } else {
+ t = 1.0;
+ }
+ res = dk3xsp_calculate(&seg, t, 1);
+ if(!(res)) {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ x = dk3xsp_get_x(&seg);
+ y = dk3xsp_get_y(&seg);
+ dxdt = dk3xsp_get_dxdt(&seg);
+ dydt = dk3xsp_get_dydt(&seg);
+ dxdt = (factor * dxdt) / 3.0;
+ dydt = (factor * dydt) / 3.0;
+ f2lud_fig_curveto(
+ job, drw, obj,
+ dk3ma_d_add_ok(lastx, lastdxdt, ec),
+ dk3ma_d_add_ok(lasty, lastdydt, ec),
+ dk3ma_d_sub_ok(x, dxdt, ec),
+ dk3ma_d_sub_ok(y, dydt, ec),
+ x,
+ y,
+ ec
+ );
+ lastx = x; lasty = y; lastdxdt = dxdt; lastdydt = dydt;
+ }
+ } else {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ /* ERROR: BUG: Wrong i */
+ }
+
+#line 1982 "f2lud.ctr"
+}
+
+
+
+/** Create path for open spline object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param primary Flag: Primary object (1=object, 0=arrowhead).
+ @param ec Pointe to error code variable, may be NULL.
+*/
+static
+void
+f2lud_create_open_spline_path(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+ dk3_fig_spline_point_t *sp; /* Spline points. */
+ size_t np; /* Number of points. */
+ size_t i; /* Current segment index. */
+ size_t min; /* Minimum t value. */
+ size_t max; /* Maximum t value. */
+
+
+#line 2009 "f2lud.ctr"
+ sp = (obj->dt).spl.po;
+ np = (obj->dt).spl.np;
+
+ if(job->coah) {
+
+#line 2013 "f2lud.ctr"
+ for(i = 0; i < (np - 1); i++) {
+ f2lud_full_spline_segment(
+ job, drw, obj, sp, np, i, ((0 == i) ? 1 : 0), 0, primary, ec
+ );
+ }
+ } else {
+
+#line 2019 "f2lud.ctr"
+ if(obj->ab) {
+
+#line 2020 "f2lud.ctr"
+ /* 2013-11-23
+ ROUNDING DOWNWARDS INTENDED.
+ We want to find the start segment.
+ */
+ min = dk3ma_d_to_sz_ok(floor((obj->dt).spl.ts), ec);
+ if(obj->af) {
+
+#line 2026 "f2lud.ctr"
+ if((obj->dt).spl.te >= (obj->dt).spl.ts) {
+
+#line 2027 "f2lud.ctr"
+ /* 2013-11-23
+ ROUNDING DOWNWARDS INTENDED.
+ We want to find the last full segment to draw.
+ */
+ max = dk3ma_d_to_sz_ok(floor((obj->dt).spl.te), ec);
+ if(max > min) {
+
+#line 2033 "f2lud.ctr"
+ f2lud_first_spline_segment(
+ job, drw, obj, sp, np, min, (obj->dt).spl.ts, 1, 0, primary, ec
+ );
+ /* 2012-12-04 Bugfix: Only to max.
+ */
+#if VERSION_BEFORE_20121204
+ for(i = (min + 1); i < (np - 1); i++) {
+ f2lud_full_spline_segment(
+ job, drw, obj, sp, np, i, 0, 0, primary, ec
+ );
+ }
+#else
+ for(i = (min + 1); i < max; i++) {
+ f2lud_full_spline_segment(
+ job, drw, obj, sp, np, i, 0, 0, primary, ec
+ );
+ }
+#endif
+ f2lud_final_spline_segment(
+ job, drw, obj, sp, np, max, (obj->dt).spl.te, 0, 0, primary, ec
+ );
+ } else {
+
+#line 2055 "f2lud.ctr"
+ f2lud_single_spline_segment(
+ job, drw, obj, sp, np, min, (obj->dt).spl.ts, (obj->dt).spl.te,
+ 1, 0, primary, ec
+ );
+ }
+ } else {
+
+#line 2061 "f2lud.ctr"
+ /* ERROR: Arrowheads too long for spline! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 37);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYNTAX);
+
+#line 2064 "f2lud.ctr"
+ }
+ } else {
+
+#line 2066 "f2lud.ctr"
+ f2lud_first_spline_segment(
+ job, drw, obj, sp, np, min, (obj->dt).spl.ts, 1, 0, primary, ec
+ );
+ for(i = (min + 1); i < (np - 1); i++) {
+ f2lud_full_spline_segment(
+ job, drw, obj, sp, np, i, 0, 0, primary, ec
+ );
+ }
+ }
+ } else {
+
+#line 2076 "f2lud.ctr"
+ if(obj->af) {
+
+#line 2077 "f2lud.ctr"
+ /* 2013-11-23
+ ROUNDING DOWNWARDS INTENDED.
+ We want to find the last full segment.
+ */
+ max = dk3ma_d_to_sz_ok(floor((obj->dt).spl.te), ec);
+ if(max < (np - 1)) {
+
+#line 2083 "f2lud.ctr"
+ if(max > 0) {
+
+#line 2084 "f2lud.ctr"
+ for(i = 0; i < max; i++) {
+ f2lud_full_spline_segment(
+ job, drw, obj, sp, np, i, ((0 == i) ? 1 : 0), 0, primary, ec
+ );
+ }
+ f2lud_final_spline_segment(
+ job, drw, obj, sp, np, max, (obj->dt).spl.te, 0, 0, primary, ec
+ );
+ } else {
+
+#line 2093 "f2lud.ctr"
+ f2lud_final_spline_segment(
+ job, drw, obj, sp, np, max, (obj->dt).spl.te, 1, 0, primary, ec
+ );
+ }
+ } else {
+
+#line 2098 "f2lud.ctr"
+ /* ERROR: Illegal max value! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 39);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN);
+
+#line 2101 "f2lud.ctr"
+ }
+ } else {
+
+#line 2103 "f2lud.ctr"
+ for(i = 0; i < (np - 1); i++) {
+ f2lud_full_spline_segment(
+ job, drw, obj, sp, np, i, ((0 == i) ? 1 : 0), 0, primary, ec
+ );
+ }
+ }
+ }
+ }
+
+
+#line 2112 "f2lud.ctr"
+}
+
+
+
+/** Create path for open spline object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param primary Flag: Primary object (1=object, 0=arrowhead).
+ @param ec Pointe to error code variable, may be NULL.
+*/
+static
+void
+f2lud_create_open_fast_spline_path(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+ dk3_fig_spline_point_t *po;
+ size_t np;
+ size_t ib;
+ size_t ic;
+ double dxdtb;
+ double dydtb;
+ double dxdtc;
+ double dydtc;
+
+
+#line 2142 "f2lud.ctr"
+ po = (obj->dt).spl.po;
+ np = (obj->dt).spl.np;
+ if (np > 1) {
+ for (ib = 0; ib < (np - 1); ib++) {
+ ic = ib + 1;
+ if (0 == ib) {
+ /* MOVETO */
+ f2lud_fig_moveto(job, drw, obj, po[ib].x, po[ib].y, ec);
+ }
+ if ((fabs(po[ib].s) < 1.0e-6) && (fabs(po[ic].s) < 1.0e-6)) {
+ /* LINETO */
+ f2lud_fig_lineto(job, drw, obj, po[ic].x, po[ic].y, ec);
+ } else {
+ dxdtb = dxdtc = dk3ma_d_sub_ok(po[ic].x, po[ib].x, ec);
+ dydtb = dydtc = dk3ma_d_sub_ok(po[ic].y, po[ib].y, ec);
+ if ((0 < ib) && (fabs(1.0 + po[ib].s) < 1.0e-6)) {
+ dxdtb = f2lpara_derived_center(po[ib-1].x, po[ib].x, po[ic].x, ec);
+ dydtb = f2lpara_derived_center(po[ib-1].y, po[ib].y, po[ic].y, ec);
+ } else {
+ if ((ic < (np - 1)) && (fabs(1.0 + po[ic].s) < 1.0e-6)) {
+ dxdtb = f2lpara_derived_left(po[ib].x, po[ic].x, po[ic+1].x, ec);
+ dydtb = f2lpara_derived_left(po[ib].y, po[ic].y, po[ic+1].y, ec);
+ }
+ }
+ if ((ic < (np - 1)) && (1.0 + fabs(po[ic].s) < 1.0e-6)) {
+ dxdtc = f2lpara_derived_center(po[ib].x, po[ic].x, po[ic+1].x, ec);
+ dydtc = f2lpara_derived_center(po[ib].y, po[ic].y, po[ic+1].y, ec);
+ } else {
+ if ((0 < ib) && (fabs(1.0 + po[ib].s) < 1.0e-6)) {
+ dxdtc = f2lpara_derived_right(po[ib-1].x, po[ib].x, po[ic].x, ec);
+ dydtc = f2lpara_derived_right(po[ib-1].y, po[ib].y, po[ic].y, ec);
+ }
+ }
+ /* CURVETO */
+ f2lud_fig_curveto(
+ job, drw, obj,
+ dk3ma_d_add_ok(po[ib].x, (dxdtb / 3.0), ec),
+ dk3ma_d_add_ok(po[ib].y, (dydtb / 3.0), ec),
+ dk3ma_d_sub_ok(po[ic].x, (dxdtc / 3.0), ec),
+ dk3ma_d_sub_ok(po[ic].y, (dydtc / 3.0), ec),
+ po[ic].x,
+ po[ic].y,
+ ec
+ );
+ }
+ }
+ }
+
+#line 2189 "f2lud.ctr"
+}
+
+
+
+/** Create path for closed spline object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param primary Flag: Primary object (1=object, 0=arrowhead).
+ @param ec Pointe to error code variable, may be NULL.
+*/
+static
+void
+f2lud_create_closed_spline_path(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+ dk3_fig_spline_point_t *sp; /* Spline points. */
+ size_t np; /* Number of points. */
+ size_t i; /* Current segment index. */
+
+
+#line 2214 "f2lud.ctr"
+ sp = (obj->dt).spl.po;
+ np = (obj->dt).spl.np;
+ for(i = 0; i < np; i++) {
+ f2lud_full_spline_segment(
+ job, drw, obj, sp, np, i, ((0 == i) ? 1 : 0), 1, primary, ec
+ );
+ }
+
+
+#line 2222 "f2lud.ctr"
+}
+
+/** Create path for closed spline object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param primary Flag: Primary object (1=object, 0=arrowhead).
+ @param ec Pointe to error code variable, may be NULL.
+*/
+static
+void
+f2lud_create_closed_fast_spline_path(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+ dk3_fig_spline_point_t *po;
+ size_t np;
+ size_t ib;
+ size_t ic;
+ size_t ia;
+ size_t id;
+ double dxdtb;
+ double dydtb;
+ double dxdtc;
+ double dydtc;
+
+
+#line 2252 "f2lud.ctr"
+ po = (obj->dt).spl.po;
+ np = (obj->dt).spl.np;
+ if (2 < np) {
+ for (ib = 0; ib < np; ib++) {
+ ic = ib + 1;
+ id = ib + 2;
+ if (ic >= np) { ic = ic - np; }
+ if (id >= np) { id = id - np; }
+ if (0 < ib) {
+ ia = ib - 1;
+ } else {
+ ia = np - 1;
+ }
+ if (0 == ib) {
+ /* MOVETO */
+ f2lud_fig_moveto(job, drw, obj, po[ib].x, po[ib].y, ec);
+ }
+ if ((fabs(po[ib].s) < 1.0e-6) && (fabs(po[ic].s) < 1.0e-6)) {
+ /* LINETO */
+ f2lud_fig_lineto(job, drw, obj, po[ic].x, po[ic].y, ec);
+ } else {
+ dxdtb = dxdtc = dk3ma_d_sub_ok(po[ic].x, po[ib].x, ec);
+ dydtb = dydtc = dk3ma_d_sub_ok(po[ic].y, po[ib].y, ec);
+ if (fabs(1.0 + po[ib].s) < 1.0e-6) {
+ dxdtb = f2lpara_derived_center(po[ia].x, po[ib].x, po[ic].x, ec);
+ dydtb = f2lpara_derived_center(po[ia].y, po[ib].y, po[ic].y, ec);
+ } else {
+ if (fabs(1.0 + po[ic].s) < 1.0e-6) {
+ dxdtb = f2lpara_derived_left(po[ib].x, po[ic].x, po[id].x, ec);
+ dydtb = f2lpara_derived_left(po[ib].y, po[ic].y, po[id].y, ec);
+ }
+ }
+ if (fabs(1.0 + po[ic].s) < 1.0e-6) {
+ dxdtc = f2lpara_derived_center(po[ib].x, po[ic].x, po[id].x, ec);
+ dydtc = f2lpara_derived_center(po[ib].y, po[ic].y, po[id].y, ec);
+ } else {
+ if (fabs(1.0 + po[ib].s) < 1.0e-6) {
+ dxdtc = f2lpara_derived_right(po[ia].x, po[ib].x, po[ic].x, ec);
+ dydtc = f2lpara_derived_right(po[ia].y, po[ib].y, po[ic].y, ec);
+ }
+ }
+ /* CURVETO */
+ f2lud_fig_curveto(
+ job, drw, obj,
+ dk3ma_d_add_ok(po[ib].x, (dxdtb / 3.0), ec),
+ dk3ma_d_add_ok(po[ib].y, (dydtb / 3.0), ec),
+ dk3ma_d_sub_ok(po[ic].x, (dxdtc / 3.0), ec),
+ dk3ma_d_sub_ok(po[ic].y, (dydtc / 3.0), ec),
+ po[ic].x,
+ po[ic].y,
+ ec
+ );
+ }
+ }
+ }
+
+
+#line 2308 "f2lud.ctr"
+}
+
+
+
+/** Create path for open arc object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param iscl Flag: Closed arc.
+ @param ec Pointe to error code variable, may be NULL.
+*/
+static
+void
+f2lud_create_arc_path(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int iscl,
+ int *ec
+)
+{
+ double sx; /* Start x. */
+ double sy; /* Start y. */
+ double cx; /* Center x. */
+ double cy; /* Center y. */
+ double r; /* Radius. */
+ double as; /* Arc start angle in radians. */
+ double ae; /* Arc end angle in radians. */
+ double lastx; /* Segment start x. */
+ double lasty; /* Segment start y. */
+ double lastkdxdt; /* X difference to first control. */
+ double lastkdydt; /* Y difference to first control. */
+ double x; /* Segment end x. */
+ double y; /* Segment end y. */
+ double kdxdt; /* X difference to last control. */
+ double kdydt; /* Y difference to last control. */
+ double dnumsegs; /* Number of segments. */
+ double alpha; /* Arc angle in radians. */
+ double alphaseg; /* Segment angle in radians. */
+ double kappa; /* Factor for derivative. */
+ double alphaend; /* Segment end angle in radians. */
+ size_t nsegs; /* Number of segments. */
+ size_t i; /* Index of current segment. */
+
+
+#line 2352 "f2lud.ctr"
+ cx = (obj->dt).arc.xc;
+ cy = (obj->dt).arc.yc;
+ r = (obj->dt).arc.ra;
+ if((obj->dt).arc.as < (obj->dt).arc.ae) {
+ as = (obj->dt).arc.as;
+ ae = (obj->dt).arc.ae;
+ } else {
+ as = (obj->dt).arc.ae;
+ ae = (obj->dt).arc.as;
+ }
+ alpha = dk3ma_d_sub_ok(ae, as, ec);
+ dnumsegs = ceil(dk3ma_d_mul_ok(4.0, (alpha / M_PI), ec));
+
+
+#line 2365 "f2lud.ctr"
+ nsegs = dk3ma_d_to_sz_ok(dnumsegs, ec);
+ alphaseg = alpha / ((double)nsegs);
+ kappa = dk3fig_tool_arc_kappa(alphaseg, ec);
+ sx = lastx = dk3ma_d_add_ok(cx, (r * cos(as)), ec);
+ sy = lasty = dk3ma_d_add_ok(cy, (r * sin(as)), ec);
+ f2lud_fig_moveto(job, drw, obj, lastx, lasty, ec);
+ lastkdxdt = dk3ma_d_mul_ok(
+ kappa,
+ (-1.0 * dk3ma_d_mul_ok(r, alphaseg, ec) * sin(as)),
+ ec
+ );
+ lastkdydt = dk3ma_d_mul_ok(
+ kappa,
+ (dk3ma_d_mul_ok(r, alphaseg, ec) * cos(as)),
+ ec
+ );
+ for(i = 0; i < nsegs; i++) {
+ if(i < (nsegs - 1)) {
+ alphaend = dk3ma_d_add_ok(
+ as,
+ dk3ma_d_mul_ok(dk3ma_d_add_ok(1.0, (double)i, ec), alphaseg, ec),
+ ec
+ );
+ } else {
+ alphaend = ae;
+ }
+ x = dk3ma_d_add_ok(cx, (r * cos(alphaend)), ec);
+ y = dk3ma_d_add_ok(cy, (r * sin(alphaend)), ec);
+ kdxdt = dk3ma_d_mul_ok(
+ kappa,
+ (-1.0 * dk3ma_d_mul_ok(r, alphaseg, ec) * sin(alphaend)),
+ ec
+ );
+ kdydt = dk3ma_d_mul_ok(
+ kappa,
+ (dk3ma_d_mul_ok(r, alphaseg, ec) * cos(alphaend)),
+ ec
+ );
+ f2lud_fig_curveto(
+ job, drw, obj,
+ dk3ma_d_add_ok(lastx, lastkdxdt, ec),
+ dk3ma_d_add_ok(lasty, lastkdydt, ec),
+ dk3ma_d_sub_ok(x, kdxdt, ec),
+ dk3ma_d_sub_ok(y, kdydt, ec),
+ x, y,
+ ec
+ );
+ lastx = x; lasty = y; lastkdxdt = kdxdt; lastkdydt = kdydt;
+ }
+ /* For closed arc draw the lines.
+ */
+ if(iscl) {
+ f2lud_fig_lineto(job, drw, obj, cx, cy, ec);
+ f2lud_fig_lineto(job, drw, obj, sx, sy, ec);
+ }
+
+
+#line 2421 "f2lud.ctr"
+}
+
+
+
+/** Create path for half circle object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param ec Pointe to error code variable, may be NULL.
+*/
+static
+void
+f2lud_create_half_circle_path(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ dk3_fig_poly_point_t po[7]; /* Points to construct path. */
+ size_t i; /* Current point index */
+
+
+#line 2443 "f2lud.ctr"
+ po[0].x = 0.0;
+ po[0].y = (obj->dt).hci.ra;
+ po[1].x = -1.0 * FIG2LAT_CIRCLE_QUADRANT_BEZIER * (obj->dt).hci.ra;
+ po[1].y = (obj->dt).hci.ra;
+ po[2].x = -1.0 * (obj->dt).hci.ra;
+ po[2].y = FIG2LAT_CIRCLE_QUADRANT_BEZIER * (obj->dt).hci.ra;
+ po[3].x = -1.0 * (obj->dt).hci.ra;
+ po[3].y = 0.0;
+ po[4].x = -1.0 * (obj->dt).hci.ra;
+ po[4].y = -1.0 * FIG2LAT_CIRCLE_QUADRANT_BEZIER * (obj->dt).hci.ra;
+ po[5].x = -1.0 * FIG2LAT_CIRCLE_QUADRANT_BEZIER * (obj->dt).hci.ra;
+ po[5].y = -1.0 * (obj->dt).hci.ra;
+ po[6].x = 0.0;
+ po[6].y = -1.0 * (obj->dt).hci.ra;
+ if(1.0e-6 < fabs((obj->dt).hci.an)) {
+ for(i = 0; i < 7; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), (obj->dt).hci.an, ec);
+ }
+ }
+ for(i = 0; i < 7; i++) {
+ dk3fig_tool_shift_point(&(po[i]), (obj->dt).hci.cx, (obj->dt).hci.cy, ec);
+ }
+ f2lud_fig_moveto(job, drw, obj, po[0].x, po[0].y, ec);
+ f2lud_fig_curveto(
+ job, drw, obj, po[1].x, po[1].y, po[2].x, po[2].y, po[3].x, po[3].y, ec
+ );
+ f2lud_fig_curveto(
+ job, drw, obj, po[4].x, po[4].y, po[5].x, po[5].y, po[6].x, po[6].y, ec
+ );
+ if(obj->st) {
+ f2lud_fig_lineto(job, drw, obj, po[0].x, po[0].y, ec);
+ }
+
+
+#line 2476 "f2lud.ctr"
+}
+
+
+
+/** Create path for object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param ec Pointe to error code variable, may be NULL.
+ @param primary Flag: Primary object (1=object, 0=arrowhead).
+*/
+static
+void
+f2lud_create_path(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+
+
+#line 2498 "f2lud.ctr"
+ switch(obj->ot) {
+ case DK3_FIG_OBJ_ELLIPSE: {
+ f2lud_create_ellipse_path(job, drw, obj, ec);
+ } break;
+ case DK3_FIG_OBJ_POLYLINE: {
+ switch(obj->st) {
+ case 1: { /* Polyline */
+ f2lud_create_polygon_path(job, drw, obj, ec);
+ } break;
+ case 2: { /* Box */
+ f2lud_create_box_path(job, drw, obj, ec);
+ } break;
+ case 3: { /* Polygon */
+ f2lud_create_polygon_path(job, drw, obj, ec);
+ } break;
+ case 4: { /* Arc-box */
+ f2lud_create_arc_box_path(job, drw, obj, ec);
+ } break;
+ }
+ } break;
+ case DK3_FIG_OBJ_SPLINE: {
+ switch(obj->st) {
+ case 0: case 2: case 4: { /* open spline */
+ f2lud_create_open_spline_path(job, drw, obj, primary, ec);
+ } break;
+ case 1: case 3: case 5: { /* closed spline */
+ f2lud_create_closed_spline_path(job, drw, obj, primary, ec);
+ } break;
+ }
+ } break;
+ case DK3_FIG_OBJ_ARC: {
+ switch(obj->st) {
+ case 1: { /* open arc */
+ f2lud_create_arc_path(job, drw, obj, 0, ec);
+ } break;
+ default: { /* closed arc */
+ f2lud_create_arc_path(job, drw, obj, 1, ec);
+ } break;
+ }
+ } break;
+ case DK3_FIG_OBJ_PSEUDO_HALF_CIRCLE: {
+ f2lud_create_half_circle_path(job, drw, obj, ec);
+ } break;
+ case DK3_FIG_OBJ_PSEUDO_FAST_SPLINE: {
+ switch(obj->st) {
+ case 0: case 2: case 4: { /* open spline */
+ f2lud_create_open_fast_spline_path(job, drw, obj, primary, ec);
+ } break;
+ case 1: case 3: case 5: { /* closed spline */
+ f2lud_create_closed_fast_spline_path(job, drw, obj, primary, ec);
+ } break;
+ }
+ } break;
+ }
+
+#line 2552 "f2lud.ctr"
+}
+
+
+
+/** Set color (stroke color for pdf/pgf).
+ If we already have a color 1 equal to the new color
+ the operation is skipped.
+ @param job Conversion job structure.
+ @param drw Drawing structure.
+ @param colno Color number.
+ @param fillstyle Fill style used in the object.
+ Depending on the fillstyle it might be necessary
+ to create a shade of the color.
+*/
+static
+void
+f2lud_set_color_1(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ int colno,
+ int fillstyle
+)
+{
+ dk3_rgb_color_t rgb; /* Color structure to fill. */
+ int muc = 1; /* Flag: Must configure. */
+#if 0
+ int ec = 0; /* Error code variable. */
+#endif
+
+
+#line 2581 "f2lud.ctr"
+ dk3fig_tool_find_color(&rgb, drw, colno, fillstyle);
+#if 0
+ if((job->gs).hc1) {
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok(rgb.r, (job->gs).c1.r, &ec))) {
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok(rgb.g, (job->gs).c1.g, &ec))) {
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok(rgb.b, (job->gs).c1.b, &ec))) {
+ if(0 == ec) {
+ muc = 0;
+ }
+ }
+ }
+ }
+ }
+#else
+ muc = dk3fig_tool_must_set_color(
+ (job->gs).hc1, (job->gs).c1.r, (job->gs).c1.g, (job->gs).c1.b,
+ rgb.r, rgb.g, rgb.b
+ );
+#endif
+ if(muc) {
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_set_color_1(job, drw, &rgb);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_set_color_1(job, drw, &rgb);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_set_color_1(job, drw, &rgb);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_set_color_1(job, drw, &rgb);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_set_color_1(job, drw, &rgb);
+ } break;
+ /* @DRIVER@ universal */
+ default: {
+ f2lpgf_pgf_set_color_1(job, drw, &rgb);
+ } break;
+ }
+ (job->gs).c1.r = rgb.r;
+ (job->gs).c1.g = rgb.g;
+ (job->gs).c1.b = rgb.b;
+ (job->gs).hc1 = 1;
+ }
+
+
+#line 2628 "f2lud.ctr"
+}
+
+
+
+/** Set non-stroking color for pdf/pgf.
+ If we already have a color 2 equal to the new color
+ the operation is skipped.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param colno Color number.
+ @param fillstyle Fill style used in the object.
+ Depending on the fillstyle it might be necessary
+ to create a shade of the color.
+*/
+static
+void
+f2lud_set_color_2(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ int colno,
+ int fillstyle
+)
+{
+ dk3_rgb_color_t rgb; /* Color structure to fill. */
+#if 0
+ int ec = 0; /* Error code variable. */
+#endif
+ int muc = 1; /* Flag: Must configure. */
+
+
+#line 2657 "f2lud.ctr"
+
+ dk3fig_tool_find_color(&rgb, drw, colno, fillstyle);
+#if 0
+ if((job->gs).hc2) {
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok(rgb.r, (job->gs).c2.r, &ec))) {
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok(rgb.g, (job->gs).c2.g, &ec))) {
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok(rgb.b, (job->gs).c2.b, &ec))) {
+ if(0 == ec) {
+ muc = 0;
+ }
+ }
+ }
+ }
+ }
+#else
+ muc = dk3fig_tool_must_set_color(
+ (job->gs).hc2, (job->gs).c2.r, (job->gs).c2.g, (job->gs).c2.b,
+ rgb.r, rgb.g, rgb.b
+ );
+#endif
+ if(muc) {
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_set_color_2(job, drw, &rgb);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_set_color_2(job, drw, &rgb);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_set_color_2(job, drw, &rgb);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_set_color_2(job, drw, &rgb);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_set_color_2(job, drw, &rgb);
+ } break;
+ /* @DRIVER@ universal */
+ default: {
+ f2lpgf_pgf_set_color_2(job, drw, &rgb);
+ } break;
+ }
+ (job->gs).c2.r = rgb.r;
+ (job->gs).c2.g = rgb.g;
+ (job->gs).c2.b = rgb.b;
+ (job->gs).hc2 = 1;
+ }
+
+
+#line 2705 "f2lud.ctr"
+}
+
+
+
+/** Internal function to set line width.
+ The line width is not set again if we already
+ have a current line width equal to the new line width.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object.
+ @param lw New line width in output coordinates.
+*/
+static
+void
+f2lud_internal_set_line_width(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double lw
+)
+{
+ int mc = 1; /* Flag: Must configure. */
+ int ec = 0; /* Error code variable. */
+
+
+#line 2729 "f2lud.ctr"
+ if((job->gs).hlw) {
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok(lw, (job->gs).lw, &ec))) {
+ if(0 == ec) {
+ mc = 0;
+ }
+ }
+ }
+ if(mc) {
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_set_line_width(job, drw, obj, lw);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_set_line_width(job, drw, obj, lw);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_set_line_width(job, drw, obj, lw);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_set_line_width(job, drw, obj, lw);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_set_line_width(job, drw, obj, lw);
+ } break;
+ /* @DRIVER@ universal */
+ default: {
+ f2lpgf_pgf_set_line_width(job, drw, obj, lw);
+ } break;
+ }
+ (job->gs).lw = lw;
+ (job->gs).hlw = 1;
+ }
+
+
+#line 2762 "f2lud.ctr"
+}
+
+
+
+/** Set line dash (line style and dash/gap length).
+ The operation is skipped if the current line style and style
+ value is equal to the new one.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param ls Line style.
+ @param sv Style value (dash/gap) length in output units.
+*/
+static
+void
+f2lud_internal_set_line_dash(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int ls,
+ double sv
+)
+{
+ double mysv; /* Style value converted to output space. */
+ double mylw; /* Line width in Fig and output space. */
+ int mc = 1; /* Flag: Must configure. */
+ int ec = 0; /* Error code variable. */
+
+
+#line 2790 "f2lud.ctr"
+ mysv = 0.9 * sv;
+ mylw = dk3fig_tool_get_lw(drw, obj, &ec);
+ /* Convert line width to output space.
+ */
+ mylw = dk3ct_2d_r(&(job->ct2d), mylw, &ec);
+ if((job->gs).hls) {
+ if((job->gs).ls == ls) {
+ if(DK3_FIG_LS_SOLID == ls) {
+ mc = 0;
+ } else {
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok((job->gs).sv, mysv, &ec))) {
+ if(0 == ec) {
+ if(DK3_FIG_LS_DASHED == ls) {
+ mc = 0;
+ } else {
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok((job->gs).slw, mylw, &ec))) {
+ if(0 == ec) {
+ mc = 0;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if(mc) {
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_set_line_style(job, drw, obj, ls, mysv, mylw);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_set_line_style(job, drw, obj, ls, mysv, mylw);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_set_line_style(job, drw, obj, ls, mysv, mylw);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_set_line_style(job, drw, obj, ls, mysv, mylw);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_set_line_style(job, drw, obj, ls, mysv, mylw);
+ } break;
+ /* @DRIVER@ universal */
+ default: {
+ f2lpgf_pgf_set_line_style(job, drw, obj, ls, mysv, mylw);
+ } break;
+ }
+ (job->gs).ls = ls; (job->gs).sv = mysv; (job->gs).slw = mylw;
+ (job->gs).hls = 1;
+ }
+
+
+#line 2842 "f2lud.ctr"
+}
+
+
+
+/** Set line ends.
+ The operation is skipped if the current line end is equal
+ to the new one.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object.
+ @param le Line end style.
+*/
+static
+void
+f2lud_set_line_end(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int le
+)
+{
+ int mc = 1; /* Flag: Must configure. */
+
+
+#line 2865 "f2lud.ctr"
+ if((job->gs).hlc) {
+ if((job->gs).lc == le) {
+ mc = 0;
+ }
+ }
+ if(mc) {
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_set_line_end(job, drw, obj, le);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_set_line_end(job, drw, obj, le);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_set_line_end(job, drw, obj, le);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_set_line_end(job, drw, obj, le);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_set_line_end(job, drw, obj, le);
+ } break;
+ /* @DRIVER@ universal */
+ default: {
+ f2lpgf_pgf_set_line_end(job, drw, obj, le);
+ } break;
+ }
+ (job->gs).lc = le; (job->gs).hlc = 1;
+ }
+
+
+#line 2895 "f2lud.ctr"
+}
+
+
+
+/** Set line join.
+ The operation is skipped if the current line join is equal
+ to the new one.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object.
+ @param lj Line end style.
+*/
+static
+void
+f2lud_set_line_join(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int lj
+)
+{
+ int mc = 1; /* Flag: Must configure. */
+
+
+#line 2918 "f2lud.ctr"
+ if((job->gs).hlj) {
+ if((job->gs).lj == lj) {
+ mc = 0;
+ }
+ }
+ if(mc) {
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_set_line_join(job, drw, obj, lj);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_set_line_join(job, drw, obj, lj);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_set_line_join(job, drw, obj, lj);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_set_line_join(job, drw, obj, lj);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_set_line_join(job, drw, obj, lj);
+ } break;
+ /* @DRIVER@ universal */
+ default: {
+ f2lpgf_pgf_set_line_join(job, drw, obj, lj);
+ } break;
+ }
+ (job->gs).lj = lj; (job->gs).hlj = 1;
+ }
+
+
+#line 2948 "f2lud.ctr"
+}
+
+
+
+/** Set up line style, line width, line ends and line join for pattern.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+static
+void
+f2lud_set_pattern_line_style(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+
+
+#line 2966 "f2lud.ctr"
+#if VERSION_BEFORE_20140330
+ f2lud_internal_set_line_width(job, drw, obj, ((job->lighten) ? 0.45 : 0.9));
+#else
+ f2lud_internal_set_line_width(job, drw, obj, job->lwbp);
+#endif
+ f2lud_internal_set_line_dash(job, drw, obj, DK3_FIG_LS_SOLID, -1.0);
+ f2lud_set_line_end(job, drw, obj, DK3_FIG_LC_BUTT);
+ f2lud_set_line_join(job, drw, obj, DK3_FIG_LJ_MITER);
+#if 0
+ /* 2012/11/18
+ In fishscale patterns we draw arc by arc, not a sequence
+ of arcs. So we do not need to care about line join
+ of arcs.
+ */
+ switch(obj->fi) {
+ case 56: case 57: {
+ f2lud_set_line_join(job, drw, obj, DK3_FIG_LJ_BEVEL);
+ } break;
+ default: {
+ f2lud_set_line_join(job, drw, obj, DK3_FIG_LJ_MITER);
+ } break;
+ }
+#endif
+
+
+#line 2990 "f2lud.ctr"
+}
+
+
+
+/** Set line width.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+static
+void
+f2lud_set_line_width(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ double lw; /* Line width in Fig space. */
+ int ec = 0; /* Error code variable. */
+
+
+#line 3010 "f2lud.ctr"
+ lw = dk3fig_tool_get_lw(drw, obj, &ec);
+ lw = dk3ct_2d_r(&(job->ct2d), lw, &ec);
+ if(0 == ec) {
+ f2lud_internal_set_line_width(job, drw, obj, lw);
+ }
+
+#line 3015 "f2lud.ctr"
+}
+
+
+
+/** Set line dash (line style and dash/gap length).
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+*/
+static
+void
+f2lud_set_line_dash(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+
+
+#line 3033 "f2lud.ctr"
+ f2lud_internal_set_line_dash(job, drw, obj, obj->ls, (0.9 * obj->sv));
+
+
+#line 3035 "f2lud.ctr"
+}
+
+
+
+/** Draw operations for object: stroke.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param ec Pointe to error code variable, may be NULL.
+ @param primary Flag: primary (1=primary object, 0=arrowhead).
+*/
+static
+void
+f2lud_path_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+
+
+#line 3057 "f2lud.ctr"
+ f2lud_set_color_1(job, drw, obj->pc, 20);
+ f2lud_set_line_width(job, drw, obj);
+ f2lud_set_line_dash(job, drw, obj);
+ f2lud_set_line_end(job, drw, obj, obj->cs);
+ f2lud_set_line_join(job, drw, obj, obj->js);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ if(obj->cl) {
+ f2lud_closepath(job, drw, obj);
+ }
+ f2lud_stroke(job, drw, obj);
+
+
+#line 3069 "f2lud.ctr"
+}
+
+
+
+/** Draw operations for object: fill.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param ec Pointe to error code variable, may be NULL.
+ @param primary Flag: primary (1=primary object, 0=arrowhead).
+*/
+static
+void
+f2lud_path_fill(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+
+
+#line 3091 "f2lud.ctr"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_PGF:
+ case FIG2LAT_DRIVER_TEX_FULL_PGF:
+ case FIG2LAT_DRIVER_TEX_FULL_PDF:
+ case FIG2LAT_DRIVER_PDF_WITH_TEX:
+ {
+ f2lud_set_color_2(job, drw, obj->fc, obj->fi);
+ } break;
+ default: {
+ f2lud_set_color_1(job, drw, obj->fc, obj->fi);
+ } break;
+ }
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_fill(job, drw, obj);
+
+
+#line 3108 "f2lud.ctr"
+}
+
+
+
+/** Draw operations for object: fill and stroke.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param ec Pointe to error code variable, may be NULL.
+ @param primary Flag: primary (1=primary object, 0=arrowhead).
+*/
+static
+void
+f2lud_path_fill_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+
+
+#line 3130 "f2lud.ctr"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_PGF:
+ case FIG2LAT_DRIVER_TEX_FULL_PGF:
+ {
+ f2lud_set_color_2(job, drw, obj->fc, obj->fi);
+ f2lud_set_color_1(job, drw, obj->pc, 20);
+ f2lud_set_line_width(job, drw, obj);
+ f2lud_set_line_dash(job, drw, obj);
+ f2lud_set_line_end(job, drw, obj, obj->cs);
+ f2lud_set_line_join(job, drw, obj, obj->js);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_fill_stroke(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF:
+ case FIG2LAT_DRIVER_PDF_WITH_TEX:
+ {
+ f2lud_set_color_2(job, drw, obj->fc, obj->fi);
+ f2lud_set_color_1(job, drw, obj->pc, 20);
+ f2lud_set_line_width(job, drw, obj);
+ f2lud_set_line_dash(job, drw, obj);
+ f2lud_set_line_end(job, drw, obj, obj->cs);
+ f2lud_set_line_join(job, drw, obj, obj->js);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_fill(job, drw, obj);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_stroke(job, drw, obj);
+ } break;
+ default: {
+ f2lud_set_line_width(job, drw, obj);
+ f2lud_set_line_dash(job, drw, obj);
+ f2lud_set_line_end(job, drw, obj, obj->cs);
+ f2lud_set_line_join(job, drw, obj, obj->js);
+ f2lud_set_color_1(job, drw, obj->fc, obj->fi);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_fill(job, drw, obj);
+ f2lud_set_color_1(job, drw, obj->pc, obj->fi);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_stroke(job, drw, obj);
+ } break;
+ }
+
+#line 3180 "f2lud.ctr"
+}
+
+
+
+/** Draw operations for object: pattern.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param ec Pointe to error code variable, may be NULL.
+ @param primary Flag: primary (1=primary object, 0=arrowhead).
+*/
+static
+void
+f2lud_path_pattern(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+
+
+#line 3202 "f2lud.ctr"
+ f2lud_set_pattern_line_style(job, drw, obj);
+ f2lud_set_color_1(job, drw, obj->pc, 20);
+ f2lud_gsave(job, drw, obj);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_clip(job, drw, obj);
+ f2lud_pattern(job, drw, obj, ec);
+ f2lud_grestore(job, drw, obj);
+
+
+#line 3212 "f2lud.ctr"
+}
+
+
+
+/** Draw operations for object: pattern and stroke.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param ec Pointe to error code variable, may be NULL.
+ @param primary Flag: primary (1=primary object, 0=arrowhead).
+*/
+static
+void
+f2lud_path_pattern_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+
+
+#line 3234 "f2lud.ctr"
+ f2lud_set_color_1(job, drw, obj->pc, 20);
+ f2lud_set_pattern_line_style(job, drw, obj);
+ f2lud_gsave(job, drw, obj);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_clip(job, drw, obj);
+ f2lud_pattern(job, drw, obj, ec);
+ f2lud_grestore(job, drw, obj);
+ f2lud_set_line_width(job, drw, obj);
+ f2lud_set_line_dash(job, drw, obj);
+ f2lud_set_line_end(job, drw, obj, obj->cs);
+ f2lud_set_line_join(job, drw, obj, obj->js);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_stroke(job, drw, obj);
+
+
+#line 3252 "f2lud.ctr"
+}
+
+
+
+/** Draw operations for object: fill and pattern.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param ec Pointe to error code variable, may be NULL.
+ @param primary Flag: primary (1=primary object, 0=arrowhead).
+*/
+static
+void
+f2lud_path_fill_pattern(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+
+
+#line 3274 "f2lud.ctr"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_PGF:
+ case FIG2LAT_DRIVER_TEX_FULL_PGF:
+ {
+ f2lud_set_color_2(job, drw, obj->fc, obj->fi);
+ f2lud_set_color_1(job, drw, obj->pc, 20);
+ f2lud_set_pattern_line_style(job, drw, obj);
+ f2lud_gsave(job, drw, obj);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_fill_clip(job, drw, obj);
+ f2lud_pattern(job, drw, obj, ec);
+ f2lud_grestore(job, drw, obj);
+ } break;
+ default: {
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PDF:
+ case FIG2LAT_DRIVER_PDF_WITH_TEX:
+ {
+ f2lud_set_color_2(job, drw, obj->fc, obj->fi);
+ f2lud_set_color_1(job, drw, obj->pc, 20);
+ f2lud_set_pattern_line_style(job, drw, obj);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_fill(job, drw, obj);
+ f2lud_gsave(job, drw, obj);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_clip(job, drw, obj);
+ f2lud_pattern(job, drw, obj, ec);
+ f2lud_grestore(job, drw, obj);
+ } break;
+ default: {
+ f2lud_set_color_1(job, drw, obj->fc, obj->fi);
+ f2lud_set_pattern_line_style(job, drw, obj);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_fill(job, drw, obj);
+ f2lud_set_color_1(job, drw, obj->pc, 20);
+ f2lud_gsave(job, drw, obj);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_clip(job, drw, obj);
+ f2lud_pattern(job, drw, obj, ec);
+ f2lud_grestore(job, drw, obj);
+ } break;
+ }
+ } break;
+ }
+
+#line 3328 "f2lud.ctr"
+}
+
+
+
+/** Check whether on object line style and line width
+ matches style and width configured in a dk3_graphics_state_t.
+ @param gs dk3_graphics_state_t to test.
+ @param ct2d Coordinates transformation data.
+ @param drw Drawing containing the Fig object.
+ @param obj Fig object.
+ @return 1 for equal line width and style, 0 otherwise.
+*/
+static
+int
+f2lud_style_equal(
+ dk3_graphics_state_t *gs,
+ dk3_ct_2d_t *ct2d,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ double lw; /* Line width in Fig space. */
+ int back = 0;
+ int ec = 0; /* Error code variable. */
+#if 0
+ if((gs->hlw) && (gs->hls) && (gs->hlc) && (gs->hlj)) {
+ if((gs->ls = obj->ls) && (gs->lc == obj->cs) && (gs->lj == obj->js)) {
+ lw = dk3fig_tool_get_lw(drw, obj, &ec);
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok(gs->lw, lw, &ec))) {
+ if(0 == ec) {
+ if(DK3_FIG_LS_SOLID == obj->ls) {
+ back = 1;
+ } else {
+ sv = 0.9 * obj->sv;
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok(gs->sv, sv, &ec))) {
+ if(0 == ec) {
+ back = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+#else
+ /* 2012/11/15 As this operation is applied to closed path objects
+ only, there is no need to check line ends.
+ As fill patterns are drawn as solid lines, we only have
+ to check the object line style, whether it is solid.
+ For solid lines the style value is ignored.
+ */
+ if((gs->hlw) && (gs->hls) && (gs->hlj)) {
+ if(DK3_FIG_LS_SOLID == obj->ls) {
+ if(gs->lj == obj->js) {
+ lw = dk3fig_tool_get_lw(drw, obj, &ec);
+ lw = dk3ct_2d_r(ct2d, lw, &ec);
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok(gs->lw, lw, &ec))) {
+ if(0 == ec) {
+ back = 1;
+ }
+ }
+ }
+ }
+ }
+#endif
+ return back;
+}
+
+
+
+/** Draw operations for object: fill, pattern and stroke.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param ec Pointe to error code variable, may be NULL.
+ @param primary Flag: primary (1=primary object, 0=arrowhead).
+*/
+static
+void
+f2lud_path_fill_pattern_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+
+
+#line 3416 "f2lud.ctr"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_PGF:
+ case FIG2LAT_DRIVER_TEX_FULL_PGF:
+ {
+ f2lud_set_color_2(job, drw, obj->fc, obj->fi);
+ f2lud_set_color_1(job, drw, obj->pc, 20);
+ f2lud_set_pattern_line_style(job, drw, obj);
+ if(f2lud_style_equal(&(job->gs), &(job->ct2d), drw, obj)) {
+ f2lud_gsave(job, drw, obj);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_fill_stroke_clip(job, drw, obj);
+ f2lud_pattern(job, drw, obj, ec);
+ f2lud_grestore(job, drw, obj);
+ } else {
+ f2lud_gsave(job, drw, obj);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_fill_clip(job, drw, obj);
+ f2lud_pattern(job, drw, obj, ec);
+ f2lud_grestore(job, drw, obj);
+ f2lud_set_line_width(job, drw, obj);
+ f2lud_set_line_dash(job, drw, obj);
+ f2lud_set_line_end(job, drw, obj, obj->cs);
+ f2lud_set_line_join(job, drw, obj, obj->js);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_stroke(job, drw, obj);
+ }
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF:
+ case FIG2LAT_DRIVER_PDF_WITH_TEX:
+ {
+ f2lud_set_color_2(job, drw, obj->fc, obj->fi);
+ f2lud_set_color_1(job, drw, obj->pc, 20);
+ f2lud_set_pattern_line_style(job, drw, obj);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_fill(job, drw, obj);
+ f2lud_gsave(job, drw, obj);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_clip(job, drw, obj);
+ f2lud_pattern(job, drw, obj, ec);
+ f2lud_grestore(job, drw, obj);
+ f2lud_set_line_width(job, drw, obj);
+ f2lud_set_line_dash(job, drw, obj);
+ f2lud_set_line_end(job, drw, obj, obj->cs);
+ f2lud_set_line_join(job, drw, obj, obj->js);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_stroke(job, drw, obj);
+ } break;
+ default: {
+ f2lud_set_color_1(job, drw, obj->fc, obj->fi);
+ f2lud_set_pattern_line_style(job, drw, obj);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_fill(job, drw, obj);
+ f2lud_set_color_1(job, drw, obj->pc, 20);
+ f2lud_gsave(job, drw, obj);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_clip(job, drw, obj);
+ f2lud_pattern(job, drw, obj, ec);
+ f2lud_grestore(job, drw, obj);
+ f2lud_set_line_width(job, drw, obj);
+ f2lud_set_line_dash(job, drw, obj);
+ f2lud_set_line_end(job, drw, obj, obj->cs);
+ f2lud_set_line_join(job, drw, obj, obj->js);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_stroke(job, drw, obj);
+ } break;
+ }
+
+#line 3500 "f2lud.ctr"
+}
+
+
+
+/** Process path object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param primary Flag: primary (1=primary object, 0=arrowhead).
+*/
+static
+void
+f2lud_path_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int primary
+)
+{
+ int drawop; /* Operations to perform. */
+ int ec = 0; /* Error code variable. */
+
+
+#line 3522 "f2lud.ctr"
+ drawop = dk3fig_tool_get_operation(drw, obj);
+ if(obj->cl) {
+ switch(drawop) {
+ case DK3_FIG_OP_STROKE: {
+ f2lud_path_stroke(job, drw, obj, primary, &ec);
+ } break;
+ case DK3_FIG_OP_FILL: {
+ f2lud_path_fill(job, drw, obj, primary, &ec);
+ } break;
+ case (DK3_FIG_OP_FILL | DK3_FIG_OP_STROKE): {
+ f2lud_path_fill_stroke(job, drw, obj, primary, &ec);
+ } break;
+ case DK3_FIG_OP_PATTERN: {
+ f2lud_path_pattern(job, drw, obj, primary, &ec);
+ } break;
+ case (DK3_FIG_OP_PATTERN | DK3_FIG_OP_STROKE): {
+ f2lud_path_pattern_stroke(job, drw, obj, primary, &ec);
+ } break;
+ case (DK3_FIG_OP_PATTERN | DK3_FIG_OP_FILL): {
+ f2lud_path_fill_pattern(job, drw, obj, primary, &ec);
+ } break;
+ case (DK3_FIG_OP_PATTERN | DK3_FIG_OP_FILL | DK3_FIG_OP_STROKE): {
+ f2lud_path_fill_pattern_stroke(job, drw, obj, primary, &ec);
+ } break;
+ }
+ } else {
+ if(DK3_FIG_OP_STROKE & drawop) {
+ f2lud_path_stroke(job, drw, obj, primary, &ec);
+ }
+ }
+ if(ec) {
+ /* ERROR: Math error in object! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 38);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH);
+
+#line 3556 "f2lud.ctr"
+ }
+
+#line 3557 "f2lud.ctr"
+}
+
+
+
+/** Process one object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param primary Flag: primary (1=primary object, 0=arrowhead).
+*/
+static
+void
+f2lud_process_one(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int primary
+)
+{
+ char debbuf[256]; /* Buffer for debug messages. */
+
+
+#line 3578 "f2lud.ctr"
+ if(job->debug) {
+ sprintf(debbuf, f2lud_c8_kw[6], obj->ot, obj->st);
+ f2lud_debug(job, debbuf);
+ }
+ switch(obj->ot) {
+ case DK3_FIG_OBJ_TEXT: {
+ f2lud_text_object(job, drw, obj);
+ } break;
+ case DK3_FIG_OBJ_ELLIPSE:
+ case DK3_FIG_OBJ_SPLINE:
+ case DK3_FIG_OBJ_ARC:
+ case DK3_FIG_OBJ_PSEUDO_HALF_CIRCLE:
+ case DK3_FIG_OBJ_PSEUDO_FAST_SPLINE:
+ {
+ f2lud_path_object(job, drw, obj, primary);
+ } break;
+ case DK3_FIG_OBJ_POLYLINE: {
+ switch(obj->st) {
+ case 5: {
+ f2lud_image_object(job, drw, obj);
+ } break;
+ default: {
+ f2lud_path_object(job, drw, obj, primary);
+ } break;
+ }
+ } break;
+ }
+ if(job->debug) {
+ f2lud_debug(job, f2lud_c8_kw[7]);
+ }
+
+#line 3608 "f2lud.ctr"
+}
+
+
+
+int
+f2lud_is_interpolated_spline(dk3_fig_obj_t *obj)
+{
+ dk3_fig_spline_point_t *po; /* Points to test */
+ size_t np; /* Number of points */
+ size_t i; /* Traverse all points */
+ int back = 1;
+
+
+#line 3620 "f2lud.ctr"
+ po = (obj->dt).spl.po;
+ np = (obj->dt).spl.np;
+ for (i = 0; ((i < np) && (1 == back)); i++) {
+
+
+#line 3624 "f2lud.ctr"
+ if (fabs(po->s) > 1.0e-6) {
+ if (fabs(1.0 + po->s) > 1.0e-6) {
+ back = 0;
+ }
+ }
+ po++;
+ }
+
+#line 3631 "f2lud.ctr"
+ return back;
+}
+
+
+
+/** Process one arrowhead object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+static
+void
+f2lud_process_ah_one(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ switch (obj->ot) {
+ case DK3_FIG_OBJ_SPLINE: {
+ if ((!(job->xsah)) && (f2lud_is_interpolated_spline(obj))) {
+ obj->ot = DK3_FIG_OBJ_PSEUDO_FAST_SPLINE;
+ f2lud_process_one(job, drw, obj, 0);
+ obj->ot = DK3_FIG_OBJ_SPLINE;
+ } else {
+ f2lud_process_one(job, drw, obj, 0);
+ }
+ } break;
+ default: {
+ f2lud_process_one(job, drw, obj, 0);
+ } break;
+ }
+}
+
+
+
+/** Process object and arrowheads.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param objno Number of current object.
+*/
+static
+void
+f2lud_process_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ unsigned long objno
+)
+{
+ char debbuf[256]; /* Buffer for debug messages. */
+
+
+#line 3684 "f2lud.ctr"
+ /*
+ Process object itself.
+ */
+
+
+#line 3688 "f2lud.ctr"
+ if(job->debug) {
+ sprintf(debbuf, f2lud_c8_kw[0], objno, obj->li, obj->ot, obj->st, obj->la);
+ f2lud_debug(job, debbuf);
+ }
+ f2lud_process_one(job, drw, obj, 1);
+
+
+#line 3694 "f2lud.ctr"
+ /*
+ For primary objects process the arrowheads.
+ */
+ if(obj->af) {
+
+
+#line 3699 "f2lud.ctr"
+ if(job->debug) {
+
+#line 3700 "f2lud.ctr"
+ sprintf(
+ debbuf, f2lud_c8_kw[2],
+ (obj->af)->as,
+ (obj->af)->af,
+ (obj->af)->he,
+ (obj->af)->wi
+ );
+ f2lud_debug(job, debbuf);
+ }
+ if((obj->af)->o1) {
+
+#line 3710 "f2lud.ctr"
+#if VERSION_BEFORE_20140329
+ f2lud_process_one(job,drw,(dk3_fig_obj_t *)((obj->af)->o1),0);
+#else
+ f2lud_process_ah_one(job, drw, (dk3_fig_obj_t *)((obj->af)->o1));
+#endif
+ }
+ if((obj->af)->o2) {
+
+#line 3717 "f2lud.ctr"
+#if VERSION_BEFORE_20140329
+ f2lud_process_one(job,drw,(dk3_fig_obj_t *)((obj->af)->o2),0);
+#else
+ f2lud_process_ah_one(job, drw, (dk3_fig_obj_t *)((obj->af)->o2));
+#endif
+ }
+ if(job->debug) {
+
+#line 3724 "f2lud.ctr"
+ f2lud_debug(job, f2lud_c8_kw[3]);
+ }
+
+
+#line 3727 "f2lud.ctr"
+ }
+ if(obj->ab) {
+
+
+#line 3730 "f2lud.ctr"
+ if(job->debug) {
+
+#line 3731 "f2lud.ctr"
+ sprintf(
+ debbuf, f2lud_c8_kw[4],
+ (obj->ab)->as,
+ (obj->ab)->af,
+ (obj->ab)->he,
+ (obj->ab)->wi
+ );
+ f2lud_debug(job, debbuf);
+ }
+ if((obj->ab)->o1) {
+
+#line 3741 "f2lud.ctr"
+#if VERSION_BEFORE_20140329
+ f2lud_process_one(job,drw,(dk3_fig_obj_t *)((obj->ab)->o1),0);
+#else
+ f2lud_process_ah_one(job, drw, (dk3_fig_obj_t *)((obj->ab)->o1));
+#endif
+ }
+ if((obj->ab)->o2) {
+
+#line 3748 "f2lud.ctr"
+#if VERSION_BEFORE_20140329
+ f2lud_process_one(job,drw,(dk3_fig_obj_t *)((obj->ab)->o2),0);
+#else
+ f2lud_process_ah_one(job, drw, (dk3_fig_obj_t *)((obj->ab)->o2));
+#endif
+ }
+ if(job->debug) {
+
+#line 3755 "f2lud.ctr"
+ f2lud_debug(job, f2lud_c8_kw[5]);
+ }
+
+
+#line 3758 "f2lud.ctr"
+ }
+ if(job->debug) {
+ sprintf(debbuf, f2lud_c8_kw[1], objno);
+ f2lud_debug(job, debbuf);
+ }
+
+
+#line 3764 "f2lud.ctr"
+}
+
+
+
+void
+f2lud_output(f2l_job_t *job)
+{
+ dk3_fig_obj_t *obj; /* Current object to process. */
+ dk3_fig_drawing_t *drw; /* Drawing to process. */
+ unsigned long objno; /* Current object number. */
+
+
+#line 3775 "f2lud.ctr"
+ drw = job->drw;
+ objno = 0UL;
+ if(f2lud_driver_initialize(job, drw)) {
+ if(f2lud_open_output_files(job)) {
+ if(f2lud_start_processing(job, drw)) {
+ dk3sto_it_reset(drw->iobj);
+ while(NULL != (obj = (dk3_fig_obj_t *)dk3sto_it_next(drw->iobj))) {
+ if(!dk3fig_tool_is_bgrect(obj, objno)) {
+ f2lud_process_object(job, drw, obj, objno);
+ }
+ objno++;
+ }
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN);
+
+#line 3789 "f2lud.ctr"
+ }
+ f2lud_end_processing(job, drw);
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN);
+
+#line 3793 "f2lud.ctr"
+ }
+ f2lud_close_output_files(job);
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN);
+
+#line 3797 "f2lud.ctr"
+ }
+ f2lud_driver_end(job, drw);
+
+#line 3799 "f2lud.ctr"
+}
+
diff --git a/support/dktools/f2lud.ctr b/support/dktools/f2lud.ctr
new file mode 100644
index 0000000000..fb6bd3dcba
--- /dev/null
+++ b/support/dktools/f2lud.ctr
@@ -0,0 +1,3800 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Produce output.
+ @param job Job structure.
+*/
+void
+f2lud_output(f2l_job_t *job);
+
+/** Issue "newpath" command.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lud_newpath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Issue "moveto" command.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x New point x in output space.
+ @param y New point y in output space.
+*/
+void
+f2lud_moveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Issue "lineto" command.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x New point x in output space.
+ @param y New point y in output space.
+*/
+void
+f2lud_lineto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Issue "curveto" command.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param xcs Control point at start x in output space.
+ @param ycs Control point at start y in output space.
+ @param xce Control point at end x in output space.
+ @param yce Control point at end y in output space.
+ @param xe End point x in output space.
+ @param ye End point y in output space.
+
+*/
+void
+f2lud_curveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double xcs,
+ double ycs,
+ double xce,
+ double yce,
+ double xe,
+ double ye
+);
+
+/** Issue "moveto" command.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x New point x in Fig space.
+ @param y New point y in Fig space.
+ @param ec Pointer to error code variable, may be NULL.
+*/
+void
+f2lud_fig_moveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y,
+ int *ec
+);
+
+/** Issue "lineto" command.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x New point x in Fig space.
+ @param y New point y in Fig space.
+ @param ec Pointer to error code variable, may be NULL.
+*/
+void
+f2lud_fig_lineto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y,
+ int *ec
+);
+
+/** Issue "curveto" command.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param xcs Control point at start x in Fig space.
+ @param ycs Control point at start y in Fig space.
+ @param xce Control point at end x in Fig space.
+ @param yce Control point at end y in Fig space.
+ @param xe End point x in Fig space.
+ @param ye End point y in Fig space.
+ @param ec Pointer to error code variable, may be NULL.
+*/
+void
+f2lud_fig_curveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double xcs,
+ double ycs,
+ double xce,
+ double yce,
+ double xe,
+ double ye,
+ int *ec
+);
+
+/** Issue "closepath" command.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lud_closepath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Issue "stroke" command.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lud_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Issue "fill" command.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lud_fill(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Check whether a spline object is an interpolated spline
+ (only s=-1 and/or s=0 points).
+ @param obj Object to check.
+ @return 1 for pure interpolated spline, 0 otherwise.
+*/
+int
+f2lud_is_interpolated_spline(dk3_fig_obj_t *obj);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk3all.h"
+#include "dk3bezcu.h"
+#include "fig2lat.h"
+#include "dk3xsp.h"
+#include "f2lud.h"
+#include "f2lsvg.h"
+#include "f2lpgf.h"
+#include "f2lpdf.h"
+#include "f2leps.h"
+#include "dk3figto.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4vers.h"
+#include "f2ludpat.h"
+#include "f2lpara.h"
+
+
+
+$!trace-include
+
+
+
+/** Keywords used by the module.
+*/
+static char const * const f2lud_c8_kw[] = {
+$!string-table
+#
+# 0: Debug message.
+#
+fig object begin %lu, line %lu, type %ld %ld, layer %d
+#
+# 1: Debug message.
+#
+fig object end %lu
+#
+# 2
+#
+arrowhead forward begin, type=%d, fill=%d, length=%lg, width=%lg
+#
+# 3
+#
+arrowhead forward end
+#
+# 4
+#
+arrowhead backward begin, type=%d, fill=%d, length=%lg, width=%lg
+#
+# 5
+#
+arrowhead backward end
+#
+# 6
+#
+path object begin, type %ld %ld
+#
+# 7
+#
+path object end
+$!end
+};
+
+
+
+/** Write debug line to output file.
+ @param job Job structure.
+ @param msg Text line without newline at end.
+*/
+static
+void
+f2lud_debug(
+ f2l_job_t *job,
+ char const *msg
+)
+{
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_debug(job, msg);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_debug(job, msg);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_debug(job, msg);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_debug(job, msg);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_debug(job, msg);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ f2lpgf_pgf_debug(job, msg);
+ } break;
+ }
+}
+
+
+
+/** Calculate factors for coordinates transformations.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lud_coordinates_transformation(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ double xmin; /* Minimum x in output space. */
+ double xmax; /* Maximum x in output space. */
+ double ymin; /* Minimum y in output space. */
+ double ymax; /* Maximum y in output space. */
+ double xdelta; /* Used width in output space. */
+ double ydelta; /* Used height in output space. */
+ double width; /* Bounding box width in output space. */
+ double height; /* Bounding box height in output space. */
+ int mec = 0; /* Mathematical error code. */
+ int back = 1;
+ $? "+ f2lud_coordinates_transformation"
+ (job->ct2d).mx = dk3ma_d_div_ok( 72.0, drw->res, &mec);
+ (job->ct2d).my = dk3ma_d_div_ok(-72.0, drw->res, &mec);
+ xmin = dk3ma_d_mul_ok((job->ct2d).mx, (drw->bb).xmin, &mec);
+ xmax = dk3ma_d_mul_ok((job->ct2d).mx, (drw->bb).xmax, &mec);
+ ymax = dk3ma_d_mul_ok((job->ct2d).my, (drw->bb).ymin, &mec);
+ ymin = dk3ma_d_mul_ok((job->ct2d).my, (drw->bb).ymax, &mec);
+ xdelta = dk3ma_d_sub_ok(xmax, xmin, &mec);
+ ydelta = dk3ma_d_sub_ok(ymax, ymin, &mec);
+ job->width = width = ceil(xdelta);
+ job->height = height = ceil(ydelta);
+ job->lwidth = dk3ma_d_to_l_ok(width, &mec);
+ job->lheight = dk3ma_d_to_l_ok(height, &mec);
+ (job->ct2d).nx = 0.5 * dk3ma_d_sub_ok(width, xdelta, &mec);
+ (job->ct2d).ny = 0.5 * dk3ma_d_sub_ok(height, ydelta, &mec);
+ (job->ct2d).nx = dk3ma_d_sub_ok((job->ct2d).nx, xmin, &mec);
+ (job->ct2d).ny = dk3ma_d_sub_ok((job->ct2d).ny, ymin, &mec);
+ $? ". mx=%lg nx=%lg my=%lg ny=%lg", (job->ct2d).mx, (job->ct2d).nx, (job->ct2d).my, (job->ct2d).ny
+ $? ". bb=%ld %ld (%lg %lg)", job->lwidth, job->lheight, (job->width) / 72.0, (job->height / 72.0)
+ if(mec) {
+ back = 0;
+ /* ERROR: Math problem */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH); $? ". exitcode"
+ } $? "- f2lud_coordinates_transformation"
+ return back;
+}
+
+
+
+/** Driver-specific initialization.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lud_driver_initialize(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ int back;
+ $? "+ f2lud_driver_initialize"
+ back = f2lud_coordinates_transformation(job, drw);
+ if(back) {
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ back = f2lpgf_tex_initialize(job, drw);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ back = f2lpdf_tex_with_pdf_initialize(job, drw);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ back = f2lpdf_pdf_with_tex_initialize(job, drw);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ back = f2leps_eps_with_tex_initialize(job, drw);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ back = f2leps_eps_pure_initialize(job, drw);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ back = f2lpgf_pgf_initialize(job, drw);
+ } break;
+ }
+ } $? "- f2lud_driver_initialize %d", back
+ return back;
+}
+
+
+
+/** Release resources allocated by f2lud_driver_initialize().
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+static
+void
+f2lud_driver_end(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ $? "+ f2lud_driver_end"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_end(job, drw);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_end(job, drw);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_end(job, drw);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_end(job, drw);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_end(job, drw);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ f2lpgf_pgf_end(job, drw);
+ } break;
+ }
+ $? "- f2lud_driver_end"
+}
+
+
+
+/** Open output files.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lud_open_output_files(f2l_job_t *job)
+{
+ int back = 0;
+ $? "+ f2lud_open_output_files"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ back = f2lpgf_tex_open_output_files(job);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ back = f2lpdf_tex_with_pdf_open_output_files(job);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ back = f2lpdf_pdf_with_tex_open_output_files(job);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ back = f2leps_eps_with_tex_open_output_files(job);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ back = f2leps_eps_pure_open_output_files(job);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ back = f2lpgf_pgf_open_output_files(job);
+ } break;
+ } $? "- f2lud_open_output_files %d", back
+ return back;
+}
+
+
+
+/** Close output files.
+ @param job Job structure.
+*/
+static
+void
+f2lud_close_output_files(f2l_job_t *job)
+{
+ $? "+ f2lud_close_output_files"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_close_output_files(job);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_close_output_files(job);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_close_output_files(job);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_close_output_files(job);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_close_output_files(job);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ f2lpgf_pgf_close_output_files(job);
+ } break;
+ } $? "- f2lud_close_output_files"
+}
+
+
+
+/** Write start of output.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+f2lud_start_processing(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ int back = 0;
+ $? "+ f2lud_start_processing"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ back = f2lpgf_tex_start_processing(job, drw);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ back = f2lpdf_tex_with_pdf_start_processing(job, drw);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ back = f2lpdf_pdf_with_tex_start_processing(job, drw);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ back = f2leps_eps_with_tex_start_processing(job, drw);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ back = f2leps_eps_pure_start_processing(job, drw);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ back = f2lpgf_pgf_start_processing(job, drw);
+ } break;
+ } $? "- f2lud_start_processing %d", back
+ return back;
+}
+
+
+
+/** Write end of output.
+ @param job Job structure.
+ @param drw Drawing structure.
+*/
+static
+void
+f2lud_end_processing(f2l_job_t *job, dk3_fig_drawing_t *drw)
+{
+ $? "+ f2lud_end_processing"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_end_processing(job, drw);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_end_processing(job, drw);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_end_processing(job, drw);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_end_processing(job, drw);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_end_processing(job, drw);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ f2lpgf_pgf_end_processing(job, drw);
+ } break;
+ } $? "- f2lud_end_processing"
+}
+
+
+
+/** Process one text object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+static
+void
+f2lud_text_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ double x; /* X position of text object. */
+ double y; /* Y position of text object. */
+ int ec = 0; /* Mathematical error code. */
+ $? "+ f2lud_text_object"
+ if(!(DK3_FIG_FONT_FLAG_HIDDEN & ((obj->dt).txt.ff))) {
+ x = dk3ct_2d_x(&(job->ct2d), (obj->dt).txt.x, &ec);
+ y = dk3ct_2d_y(&(job->ct2d), (obj->dt).txt.y, &ec);
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_text_object(job, drw, obj, x, y);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_text_object(job, drw, obj, x, y);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_text_object(job, drw, obj, x, y);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_text_object(job, drw, obj, x, y);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_text_object(job, drw, obj, x, y);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ f2lpgf_pgf_text_object(job, drw, obj, x, y);
+ } break;
+ }
+ }
+ if(ec) {
+ /* ERROR: Math problem! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH); $? ". exitcode"
+ }
+ $? "- f2lud_text_object"
+}
+
+
+
+/** Find bounding box for output coordinates.
+ @param bb Bounding box to set up.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Polygon/polyline object.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2lud_find_bounding_box(
+ dk3_bb_t *bb,
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ dk3_fig_poly_point_t *po; /* Current point. */
+ size_t np; /* Number of points. */
+ size_t i; /* Index of current point. */
+ $? "+ f2lud_find_bounding_box"
+ po = (obj->dt).pol.po;
+ np = (obj->dt).pol.np;
+ dk3bb_reset(bb);
+ for(i = 0; i < np; i++) {
+ dk3bb_add_x(bb, dk3ct_2d_x(&(job->ct2d), po->x, ec));
+ dk3bb_add_y(bb, dk3ct_2d_y(&(job->ct2d), po->y, ec));
+ po++;
+ } $? "- f2lud_find_bounding_box"
+}
+
+
+
+/** Process one image object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+static
+void
+f2lud_image_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ dk3_bb_t outbb; /* Image bounding box in output space. */
+ int ec = 0; /* Error code variable. */
+ int drawdir = 0; /* Drawing direction for embedded image. */
+ $? "+ f2lud_image_object"
+ dk3bb_reset(&outbb);
+ f2lud_find_bounding_box(&outbb, job, drw, obj, &ec);
+ drawdir = f2lto_find_draw_direction(job, drw, obj, &ec);
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_image_object(job, drw, obj, &outbb, drawdir, &ec);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_image_object(job, drw, obj, &outbb, drawdir, &ec);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_image_object(job, drw, obj, &outbb, drawdir, &ec);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_image_object(job, drw, obj, &outbb, drawdir, &ec);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_image_object(job, drw, obj, &outbb, drawdir, &ec);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ f2lpgf_pgf_image_object(job, drw, obj, &outbb, drawdir, &ec);
+ } break;
+ }
+ if(ec) {
+ /* ERROR: Math error! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH); $? ". exitcode"
+ } $? "- f2lud_image_object"
+}
+
+
+
+void
+f2lud_newpath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ $? "+ f2lud_newpath"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_newpath(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_newpath(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_newpath(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_newpath(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_newpath(job, drw, obj);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ f2lpgf_pgf_newpath(job, drw, obj);
+ } break;
+ } $? "- f2lud_newpath"
+}
+
+
+
+void
+f2lud_moveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+ $? "+ f2lud_moveto %lg %lg", x, y
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_moveto(job, drw, obj, x, y);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_moveto(job, drw, obj, x, y);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_moveto(job, drw, obj, x, y);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_moveto(job, drw, obj, x, y);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_moveto(job, drw, obj, x, y);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ f2lpgf_pgf_moveto(job, drw, obj, x, y);
+ } break;
+ } $? "- f2lud_moveto"
+}
+
+
+
+void
+f2lud_lineto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+)
+{
+ $? "+ f2lud_lineto %lg %lg", x, y
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_lineto(job, drw, obj, x, y);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_lineto(job, drw, obj, x, y);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_lineto(job, drw, obj, x, y);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_lineto(job, drw, obj, x, y);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_lineto(job, drw, obj, x, y);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ f2lpgf_pgf_lineto(job, drw, obj, x, y);
+ } break;
+ } $? "- f2lud_lineto"
+}
+
+
+
+void
+f2lud_curveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double xcs,
+ double ycs,
+ double xce,
+ double yce,
+ double xe,
+ double ye
+)
+{
+ $? "+ f2lud_curveto %lg %lg %lg %lg %lg %lg", xcs, ycs, xce, yce, xe, ye
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_curveto(job, drw, obj, xcs, ycs, xce, yce, xe, ye);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_curveto(job, drw, obj, xcs, ycs, xce, yce, xe, ye);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_curveto(job, drw, obj, xcs, ycs, xce, yce, xe, ye);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_curveto(job, drw, obj, xcs, ycs, xce, yce, xe, ye);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_curveto(job, drw, obj, xcs, ycs, xce, yce, xe, ye);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ f2lpgf_pgf_curveto(job, drw, obj, xcs, ycs, xce, yce, xe, ye);
+ } break;
+ } $? "- f2lud_curveto"
+}
+
+
+
+void
+f2lud_fig_moveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y,
+ int *ec
+)
+{
+ double nx; /* Destination x in output space. */
+ double ny; /* Destination y in output space. */
+ $? "+ f2lud_fig_moveto %lg %lg", x, y
+ nx = dk3ct_2d_x(&(job->ct2d), x, ec);
+ ny = dk3ct_2d_y(&(job->ct2d), y, ec);
+ f2lud_moveto(job, drw, obj, nx, ny);
+ $? "- f2lud_fig_moveto"
+}
+
+
+
+void
+f2lud_fig_lineto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y,
+ int *ec
+)
+{
+ double nx; /* Destination x in output space. */
+ double ny; /* Destination y in output space. */
+ $? "+ f2lud_fig_lineto %lg %lg", x, y
+ nx = dk3ct_2d_x(&(job->ct2d), x, ec);
+ ny = dk3ct_2d_y(&(job->ct2d), y, ec);
+ f2lud_lineto(job, drw, obj, nx, ny);
+ $? "- f2lud_fig_lineto"
+}
+
+
+
+void
+f2lud_fig_curveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double xcs,
+ double ycs,
+ double xce,
+ double yce,
+ double xe,
+ double ye,
+ int *ec
+)
+{
+ double nxcs; /* First control point x in output space. */
+ double nycs; /* First control point y in output space. */
+ double nxce; /* Second control point x in output space. */
+ double nyce; /* Second control point y in output space. */
+ double nxe; /* End point x in output space. */
+ double nye; /* End point y in output space. */
+ $? "+ f2lud_fig_curveto %lg %lg %lg %lg %lg %lg", xcs, ycs, xce, yce, xe, ye
+ nxcs = dk3ct_2d_x(&(job->ct2d), xcs, ec);
+ nycs = dk3ct_2d_y(&(job->ct2d), ycs, ec);
+ nxce = dk3ct_2d_x(&(job->ct2d), xce, ec);
+ nyce = dk3ct_2d_y(&(job->ct2d), yce, ec);
+ nxe = dk3ct_2d_x(&(job->ct2d), xe, ec);
+ nye = dk3ct_2d_y(&(job->ct2d), ye, ec);
+ f2lud_curveto(job, drw, obj, nxcs, nycs, nxce, nyce, nxe, nye);
+ $? "- f2lud_fig_curveto"
+}
+
+
+
+void
+f2lud_closepath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ $? "+ f2lud_closepath"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_closepath(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_closepath(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_closepath(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_closepath(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_closepath(job, drw, obj);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ f2lpgf_pgf_closepath(job, drw, obj);
+ } break;
+ } $? "- f2lud_closepath"
+}
+
+
+
+/** Issue "fill" command.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lud_fill(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ $? "+ f2lud_fill"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_fill(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_fill(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_fill(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_fill(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_fill(job, drw, obj);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ f2lpgf_pgf_fill(job, drw, obj);
+ } break;
+ } $? "- f2lud_fill"
+}
+
+
+
+/** Issue combined "fill" and "clip" command.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+static
+void
+f2lud_fill_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ $? "+ f2lud_fill_clip"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_fill_clip(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_PGF: {
+ f2lpgf_pgf_fill_clip(job, drw, obj);
+ } break;
+ /* @DRIVER@ universal */
+ } $? "- f2lud_fill_clip"
+}
+
+
+
+/** Issue combined "fill", "stroke", and "clip" command.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+static
+void
+f2lud_fill_stroke_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ $? "+ f2lud_fill_clip"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_fill_stroke_clip(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_PGF: {
+ f2lpgf_pgf_fill_stroke_clip(job, drw, obj);
+ } break;
+ /* @DRIVER@ universal */
+ } $? "- f2lud_fill_clip"
+}
+
+
+
+/** Issue combined "fill" and "stroke" command.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+static
+void
+f2lud_fill_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ $? "+ f2lud_fill_stroke"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_fill_stroke(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_PGF: {
+ f2lpgf_pgf_fill_stroke(job, drw, obj);
+ } break;
+ /* @DRIVER@ universal */
+ } $? "- f2lud_fill_stroke"
+}
+
+
+
+void
+f2lud_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ $? "+ f2lud_stroke"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_stroke(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_stroke(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_stroke(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_stroke(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_stroke(job, drw, obj);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ f2lpgf_pgf_stroke(job, drw, obj);
+ } break;
+ } $? "- f2lud_stroke"
+}
+
+
+
+/** Issue "clip" command.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+static
+void
+f2lud_clip(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ $? "+ f2lud_clip"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_clip(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_clip(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_clip(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_clip(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_clip(job, drw, obj);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ f2lpgf_pgf_clip(job, drw, obj);
+ } break;
+ } $? "- f2lud_clip"
+}
+
+
+
+/** Issue "gsave" command.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+static
+void
+f2lud_gsave(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ $? "+ f2lud_gsave"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_gsave(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_gsave(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_gsave(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_gsave(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_gsave(job, drw, obj);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ f2lpgf_pgf_gsave(job, drw, obj);
+ } break;
+ } $? "- f2lud_gsave"
+}
+
+
+
+/** Issue "grestore" command.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+static
+void
+f2lud_grestore(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ $? "+ f2lud_grestore"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_grestore(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_grestore(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_grestore(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_grestore(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_grestore(job, drw, obj);
+ } break;
+ /* @DRIVER@ universal */
+ default: { /* PGF */
+ f2lpgf_pgf_grestore(job, drw, obj);
+ } break;
+ } $? "- f2lud_grestore"
+}
+
+
+
+/** Create path for ellipse object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param ec Pointe to error code variable, may be NULL.
+*/
+static
+void
+f2lud_create_ellipse_path(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ dk3_fig_poly_point_t po[12]; /* Points in Fig space. */
+ double myan; /* Rotation angle in Fig space. */
+ size_t i; /* Index of current point to modify. */
+ $? "+ f2lud_create_ellipse_path"
+ po[0].x = (obj->dt).ell.rx;
+ po[0].y = 0.0;
+ po[1].x = (obj->dt).ell.rx;
+ po[1].y = FIG2LAT_CIRCLE_QUADRANT_BEZIER * (obj->dt).ell.ry;
+ po[2].x = FIG2LAT_CIRCLE_QUADRANT_BEZIER * (obj->dt).ell.rx;
+ po[2].y = (obj->dt).ell.ry;
+ po[3].x = 0.0;
+ po[3].y = (obj->dt).ell.ry;
+ po[4].x = 0.0 - po[2].x;
+ po[4].y = po[2].y;
+ po[5].x = 0.0 - po[1].x;
+ po[5].y = po[1].y;
+ po[6].x = 0.0 - po[0].x;
+ po[6].y = 0.0;
+ po[7].x = po[6].x;
+ po[7].y = 0.0 - po[5].y;
+ po[8].x = po[4].x;
+ po[8].y = 0.0 - po[2].y;
+ po[9].x = 0.0;
+ po[9].y = 0.0 - po[3].y;
+ po[10].x = po[2].x;
+ po[10].y = po[9].y;
+ po[11].x = po[1].x;
+ po[11].y = po[7].y;
+ switch(obj->st) {
+ case 1: case 2: {
+ if(1.0e-6 < fabs((obj->dt).ell.an)) {
+ if(1.0e-6 < fabs(dk3ma_d_sub_ok((obj->dt).ell.rx,(obj->dt).ell.ry,ec)))
+ {
+ myan = -1.0 * (obj->dt).ell.an;
+ for(i = 0; i < 12; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), myan, ec);
+ }
+ }
+ }
+ } break;
+ }
+ for(i = 0; i < 12; i++) {
+ dk3fig_tool_shift_point(&(po[i]), (obj->dt).ell.cx, (obj->dt).ell.cy, ec);
+ }
+ f2lud_fig_moveto(job, drw, obj, po[0].x, po[0].y, ec);
+ f2lud_fig_curveto(
+ job, drw, obj,
+ po[1].x, po[1].y, po[2].x, po[2].y, po[3].x, po[3].y,
+ ec
+ );
+ f2lud_fig_curveto(
+ job, drw, obj,
+ po[4].x, po[4].y, po[5].x, po[5].y, po[6].x, po[6].y,
+ ec
+ );
+ f2lud_fig_curveto(
+ job, drw, obj,
+ po[7].x, po[7].y, po[8].x, po[8].y, po[9].x, po[9].y,
+ ec
+ );
+ f2lud_fig_curveto(
+ job, drw, obj,
+ po[10].x, po[10].y, po[11].x, po[11].y, po[0].x, po[0].y,
+ ec
+ );
+ $? "- f2lud_create_ellipse_path"
+}
+
+
+
+/** Create path for polygon object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param ec Pointe to error code variable, may be NULL.
+*/
+static
+void
+f2lud_create_polygon_path(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ dk3_fig_poly_point_t *po; /* Current point to process. */
+ size_t np; /* Number of points. */
+ size_t i; /* Index of current point. */
+ $? "+ f2lud_create_polygon_path"
+ po = (obj->dt).pol.po;
+ np = (obj->dt).pol.np;
+ for(i = 0; i < np; i++) {
+ if(0 == i) {
+ f2lud_fig_moveto(job, drw, obj, po->x, po->y, ec);
+ } else {
+ f2lud_fig_lineto(job, drw, obj, po->x, po->y, ec);
+ }
+ po++;
+ }
+ if(obj->cl) {
+ po = (obj->dt).pol.po;
+ f2lud_fig_lineto(job, drw, obj, po->x, po->y, ec);
+ } $? "- f2lud_create_polygon_path"
+}
+
+
+
+/** Create path for box object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param ec Pointe to error code variable, may be NULL.
+*/
+static
+void
+f2lud_create_box_path(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ dk3_bb_t outbb; /* Box coordinates in output space. */
+ $? "+ f2lud_create_box_path"
+ dk3bb_reset(&outbb);
+ f2lud_find_bounding_box(&outbb, job, drw, obj, ec);
+ f2lud_moveto(job, drw, obj, outbb.xmin, outbb.ymin);
+ f2lud_lineto(job, drw, obj, outbb.xmax, outbb.ymin);
+ f2lud_lineto(job, drw, obj, outbb.xmax, outbb.ymax);
+ f2lud_lineto(job, drw, obj, outbb.xmin, outbb.ymax);
+ f2lud_lineto(job, drw, obj, outbb.xmin, outbb.ymin);
+ $? "- f2lud_create_box_path"
+}
+
+
+
+/** Create path for arc box object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param ec Pointe to error code variable, may be NULL.
+*/
+static
+void
+f2lud_create_arc_box_path(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ dk3_fig_poly_point_t po[16]; /* Box points in output space. */
+ dk3_bb_t outbb; /* Box coordinates in output space. */
+ double r; /* Corner radius in output space. */
+ double maxr; /* Maximum value for corner radius. */
+ double corner; /* Factor control to end. */
+ double rc; /* Dist of control to end in output space. */
+ $? "+ f2lud_create_arc_box_path"
+ dk3bb_reset(&outbb);
+ f2lud_find_bounding_box(&outbb, job, drw, obj, ec);
+#if VERSION_BEFORE_20140808
+ r = dk3ct_2d_r(&(job->ct2d), (obj->dt).pol.ra, ec); $? ". r=%lg", r
+#else
+ r = 0.9 * (obj->dt).pol.ra; $? ". r=%lg", r
+#endif
+ maxr = 0.49 * fabs(dk3ma_d_sub_ok(outbb.xmax, outbb.xmin, ec));
+ if(r > maxr) r = maxr;
+ maxr = 0.49 * fabs(dk3ma_d_sub_ok(outbb.ymax, outbb.ymin, ec));
+ if(r > maxr) r = maxr;
+ corner = 1.0 - FIG2LAT_CIRCLE_QUADRANT_BEZIER;
+ rc = r * corner;
+ /* Bottom line */
+ po[0].x = dk3ma_d_add_ok(outbb.xmin, r, ec);
+ po[0].y = outbb.ymin;
+ po[1].x = dk3ma_d_sub_ok(outbb.xmax, r, ec);
+ po[1].y = po[0].y;
+ /* Lower right corner control points */
+ po[2].x = dk3ma_d_sub_ok(outbb.xmax, rc, ec);
+ po[2].y = po[0].y;
+ po[3].x = outbb.xmax;
+ po[3].y = dk3ma_d_add_ok(outbb.ymin, rc, ec);
+ /* Right line */
+ po[4].x = outbb.xmax;
+ po[4].y = dk3ma_d_add_ok(outbb.ymin, r, ec);
+ po[5].x = outbb.xmax;
+ po[5].y = dk3ma_d_sub_ok(outbb.ymax, r, ec);
+ /* Upper right corner control points */
+ po[6].x = outbb.xmax;
+ po[6].y = dk3ma_d_sub_ok(outbb.ymax, rc, ec);
+ po[7].x = dk3ma_d_sub_ok(outbb.xmax, rc, ec);
+ po[7].y = outbb.ymax;
+ /* Top line */
+ po[8].x = dk3ma_d_sub_ok(outbb.xmax, r, ec);
+ po[8].y = outbb.ymax;
+ po[9].x = dk3ma_d_add_ok(outbb.xmin, r, ec);
+ po[9].y = outbb.ymax;
+ /* Upper left corner control points */
+ po[10].x = dk3ma_d_add_ok(outbb.xmin, rc, ec);
+ po[10].y = outbb.ymax;
+ po[11].x = outbb.xmin;
+ po[11].y = dk3ma_d_sub_ok(outbb.ymax, rc, ec);
+ /* Left line */
+ po[12].x = outbb.xmin;
+ po[12].y = dk3ma_d_sub_ok(outbb.ymax, r, ec);
+ po[13].x = outbb.xmin;
+ po[13].y = dk3ma_d_add_ok(outbb.ymin, r, ec);
+ /* Lower left corner control points */
+ po[14].x = outbb.xmin;
+ po[14].y = dk3ma_d_add_ok(outbb.ymin, rc, ec);
+ po[15].x = dk3ma_d_add_ok(outbb.xmin, rc, ec);
+ po[15].y = outbb.ymin;
+ f2lud_moveto(job, drw, obj, po[0].x, po[0].y);
+ f2lud_lineto(job, drw, obj, po[1].x, po[1].y);
+ f2lud_curveto(
+ job, drw, obj,
+ po[2].x, po[2].y, po[3].x, po[3].y, po[4].x, po[4].y
+ );
+ f2lud_lineto(job, drw, obj, po[5].x, po[5].y);
+ f2lud_curveto(
+ job, drw, obj,
+ po[6].x, po[6].y, po[7].x, po[7].y, po[8].x, po[8].y
+ );
+ f2lud_lineto(job, drw, obj, po[9].x, po[9].y);
+ f2lud_curveto(
+ job, drw, obj,
+ po[10].x, po[10].y, po[11].x, po[11].y, po[12].x, po[12].y
+ );
+ f2lud_lineto(job, drw, obj, po[13].x, po[13].y);
+ f2lud_curveto(
+ job, drw, obj,
+ po[14].x, po[14].y, po[15].x, po[15].y, po[0].x, po[0].y
+ );
+ $? "- f2lud_create_arc_box_path"
+}
+
+
+
+/** Create path for the last partial X-spline segment from closed X-spline.
+ @param job Job structure.
+ @param drw Fig drawing.
+ @param obj Fig object.
+ @param sp Spline points array.
+ @param np Number of spline points.
+ @param i Current segment index.
+ @param te Parameter t for end point.
+ @param isfirst Flag: First segment.
+ @param iscl Flag: Closed spline.
+ @param primary Flag: Primary (1=primary object, 0=arrowhead).
+ @param ec Pointer to error code variable, may be NULL.
+*/
+static
+void
+f2lud_final_spline_segment(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_spline_point_t *sp,
+ size_t np,
+ size_t i,
+ double te,
+ int isfirst,
+ int iscl,
+ int primary,
+ int *ec
+)
+{
+ dk3_xspline_segment_t seg; /* Segment for caluclation. */
+ dk3_fig_spline_point_t *pa = NULL; /* Left neighbour. */
+ dk3_fig_spline_point_t *pb = NULL; /* Start. */
+ dk3_fig_spline_point_t *pc = NULL; /* End. */
+ dk3_fig_spline_point_t *pd = NULL; /* Right neighbour. */
+ double myte; /* t for end. */
+ double dnumsegs; /* Number of segments. */
+ double factor; /* Scale factor for deriv. */
+ double t; /* Current t. */
+ double x; /* Bezier end x. */
+ double y; /* Bezier end y. */
+ double dxdt; /* Bezier dx/dt at end. */
+ double dydt; /* Bezier dy/dt at end. */
+ double lastx = 0.0; /* Bezier start x. */
+ double lasty = 0.0; /* Bezier start y. */
+ double lastdxdt = 0.0; /* dx/dt at start. */
+ double lastdydt = 0.0; /* dy/dt at end. */
+ size_t nsegs; /* Number of segments. */
+ size_t iseg; /* Current segment. */
+ int res; /* Calculation result. */
+ $? "+ f2lud_final_spline_segment %lg", te
+ myte = dk3ma_d_sub_ok(te, floor(te), ec); $? ". myte = %lg", myte
+ dnumsegs = myte * dk3fig_tool_xssbs(drw, primary);
+ dnumsegs = ceil(dnumsegs); $? ". dnumsegs = %lg", dnumsegs
+ nsegs = dk3ma_d_to_sz_ok(dnumsegs, ec); $? ". nsegs = %u", (unsigned)nsegs
+ pb = &(sp[i]);
+ pc = &(sp[i + 1]);
+ if(0 < i) {
+ pa = &(sp[i - 1]);
+ }
+ if(i < (np - 2)) {
+ pd = &(sp[i + 2]);
+ }
+ factor = myte / (double)nsegs; $? ". factor = %lg", factor
+ dk3xsp_reset(&seg);
+ if(job->cosp) { dk3xsp_set_cb(&seg, 1); }
+ dk3xsp_set(&seg, pa, pb, pc, pd);
+ if(dk3xsp_calculate(&seg, 0.0, 1)) {
+ lastx = dk3xsp_get_x(&seg);
+ lasty = dk3xsp_get_y(&seg);
+ lastdxdt = dk3xsp_get_dxdt(&seg);
+ lastdydt = dk3xsp_get_dydt(&seg);
+ lastdxdt = (factor * lastdxdt) / 3.0;
+ lastdydt = (factor * lastdydt) / 3.0;
+ /* Move to start point.
+ */
+ if(isfirst) {
+ f2lud_fig_moveto(job, drw, obj, lastx, lasty, ec);
+ }
+ /* Further curve only if te > 1.0e-6.
+ For smaller te draw straight line.
+ */
+ if(1.0e-6 < myte) { $? ". segments size ok"
+ for(iseg = 0; iseg < nsegs; iseg++) {
+ if(iseg < (nsegs - 1)) { $? ". not last sub-segment"
+ t = (double)(iseg + 1) / (double)nsegs;
+ t = t * myte;
+ } else { $? ". last sub-segment"
+ t = myte;
+ } $? ". t = %lg", t
+ res = dk3xsp_calculate(&seg, t, 1);
+ if(!(res)) {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ x = dk3xsp_get_x(&seg);
+ y = dk3xsp_get_y(&seg);
+ dxdt = dk3xsp_get_dxdt(&seg);
+ dydt = dk3xsp_get_dydt(&seg);
+ dxdt = (factor * dxdt) / 3.0;
+ dydt = (factor * dydt) / 3.0;
+ f2lud_fig_curveto(
+ job, drw, obj,
+ dk3ma_d_add_ok(lastx, lastdxdt, ec),
+ dk3ma_d_add_ok(lasty, lastdydt, ec),
+ dk3ma_d_sub_ok(x, dxdt, ec),
+ dk3ma_d_sub_ok(y, dydt, ec),
+ x, y,
+ ec
+ );
+ lastx = x; lasty = y; lastdxdt = dxdt; lastdydt = dydt;
+ }
+ } else { $? ". very small segment"
+ res = dk3xsp_calculate(&seg, myte, 0);
+ if(!(res)) {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ /* ERROR: Math */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 36);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH); $? ". exitcode"
+ }
+ x = dk3xsp_get_x(&seg);
+ y = dk3xsp_get_y(&seg);
+ f2lud_fig_lineto(job, drw, obj, x, y, ec);
+ }
+ } else {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH); $? ". exitcode"
+ }
+ $? "- f2lud_final_spline_segment"
+}
+
+
+
+/** Create path for the first partial X-spline segment from closed X-spline.
+ @param job Job structure.
+ @param drw Fig drawing.
+ @param obj Fig object.
+ @param sp Spline points array.
+ @param np Number of spline points.
+ @param i Current segment index.
+ @param ts Parameter t for start point.
+ @param isfirst Flag: First segment.
+ @param iscl Flag: Closed spline.
+ @param primary Flag: Primary (1=primary object, 0=arrowhead).
+ @param ec Pointer to error code variable, may be NULL.
+*/
+static
+void
+f2lud_first_spline_segment(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_spline_point_t *sp,
+ size_t np,
+ size_t i,
+ double ts,
+ int isfirst,
+ int iscl,
+ int primary,
+ int *ec
+)
+{
+ dk3_xspline_segment_t seg; /* Segment for caluclation. */
+ dk3_fig_spline_point_t *pa = NULL; /* Left neighbour. */
+ dk3_fig_spline_point_t *pb = NULL; /* Start. */
+ dk3_fig_spline_point_t *pc = NULL; /* End. */
+ dk3_fig_spline_point_t *pd = NULL; /* Right neighbour. */
+ double myts; /* t for start. */
+ double dnumsegs; /* Number of segments. */
+ double factor; /* Scale factor for deriv. */
+ double t; /* Current t. */
+ double x; /* Bezier end x. */
+ double y; /* Bezier end y. */
+ double dxdt; /* Bezier dx/dt at end. */
+ double dydt; /* Bezier dy/dt at end. */
+ double lastx = 0.0; /* Bezier start x. */
+ double lasty = 0.0; /* Bezier start y. */
+ double lastdxdt = 0.0; /* dx/dt at start. */
+ double lastdydt = 0.0; /* dy/dt at end. */
+ size_t nsegs; /* Number of segments. */
+ size_t iseg; /* Current segment. */
+ int res; /* Calculation result. */
+ $? "+ f2lud_first_spline_segment ts=%lg", ts
+ myts = dk3ma_d_sub_ok(ts, floor(ts), ec); $? ". myts = %lg", myts
+ dnumsegs = (1.0 - myts) * dk3fig_tool_xssbs(drw, primary);
+ dnumsegs = ceil(dnumsegs); $? ". dnumsegs = %lg", dnumsegs
+ nsegs = dk3ma_d_to_sz_ok(dnumsegs, ec); $? ". nsegs = %u", (unsigned)nsegs
+ pb = &(sp[i]);
+ pc = &(sp[i + 1]);
+ if(0 < i) {
+ pa = &(sp[i - 1]);
+ }
+ if(i < (np - 2)) {
+ pd = &(sp[i + 2]);
+ }
+ factor = (1.0 - myts) / (double)nsegs; $? ". factor = %lg", factor
+ dk3xsp_reset(&seg);
+ if(job->cosp) { dk3xsp_set_cb(&seg, 1); }
+ dk3xsp_set(&seg, pa, pb, pc, pd);
+ if(dk3xsp_calculate(&seg, myts, 1)) {
+ /* If necessary move to the start point.
+ */
+ lastx = dk3xsp_get_x(&seg);
+ lasty = dk3xsp_get_y(&seg);
+ lastdxdt = dk3xsp_get_dxdt(&seg);
+ lastdydt = dk3xsp_get_dydt(&seg);
+ lastdxdt = (factor * lastdxdt) / 3.0;
+ lastdydt = (factor * lastdydt) / 3.0;
+ if(isfirst) {
+ f2lud_fig_moveto(job, drw, obj, lastx, lasty, ec);
+ }
+ if(1.0e-6 < (1.0 - myts)) {
+ for(iseg = 0; iseg < nsegs; iseg++) {
+ if(iseg < (nsegs - 1)) {
+ t = myts + (((1.0 - myts) * ((double)(iseg + 1))) / ((double)nsegs));
+ } else {
+ t = 1.0;
+ }
+ res = dk3xsp_calculate(&seg, t, 1);
+ if(!(res)) {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ x = dk3xsp_get_x(&seg);
+ y = dk3xsp_get_y(&seg);
+ dxdt = dk3xsp_get_dxdt(&seg);
+ dydt = dk3xsp_get_dydt(&seg);
+ dxdt = (factor * dxdt) / 3.0;
+ dydt = (factor * dydt) / 3.0;
+ f2lud_fig_curveto(
+ job, drw, obj,
+ dk3ma_d_add_ok(lastx, lastdxdt, ec),
+ dk3ma_d_add_ok(lasty, lastdydt, ec),
+ dk3ma_d_sub_ok(x, dxdt, ec),
+ dk3ma_d_sub_ok(y, dydt, ec),
+ x, y,
+ ec
+ );
+ lastx = x; lasty = y; lastdxdt = dxdt; lastdydt = dydt;
+ }
+ } else {
+ res = dk3xsp_calculate(&seg, 1.0, 0);
+ if(!(res)) {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ /* ERROR: Math */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 36);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH); $? ". exitcode"
+ }
+ x = dk3xsp_get_x(&seg);
+ y = dk3xsp_get_y(&seg);
+ f2lud_fig_lineto(job, drw, obj, x, y, ec);
+ }
+ } else {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH); $? ". exitcode"
+ }
+ $? "- f2lud_first_spline_segment"
+}
+
+
+
+
+/** Create path for the single partial X-spline segment cutted on both ends
+ from closed X-spline.
+ @param job Job structure.
+ @param drw Fig drawing.
+ @param obj Fig object.
+ @param sp Spline points array.
+ @param np Number of spline points.
+ @param i Current segment index.
+ @param ts Parameter t for start point.
+ @param te Parameter t for end point.
+ @param isfirst Flag: First segment.
+ @param iscl Flag: Closed spline.
+ @param primary Flag: Primary (1=primary object, 0=arrowhead).
+ @param ec Pointer to error code variable, may be NULL.
+*/
+static
+void
+f2lud_single_spline_segment(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_spline_point_t *sp,
+ size_t np,
+ size_t i,
+ double ts,
+ double te,
+ int isfirst,
+ int iscl,
+ int primary,
+ int *ec
+)
+{
+ dk3_xspline_segment_t seg; /* Segment for caluclation. */
+ dk3_fig_spline_point_t *pa = NULL; /* Left neighbour. */
+ dk3_fig_spline_point_t *pb = NULL; /* Start. */
+ dk3_fig_spline_point_t *pc = NULL; /* End. */
+ dk3_fig_spline_point_t *pd = NULL; /* Right neighbour. */
+ double myte; /* t for end. */
+ double myts; /* t for start. */
+ double dnumsegs; /* Number of segments. */
+ double factor; /* Scale factor for deriv. */
+ double t; /* Current t. */
+ double x; /* Bezier end x. */
+ double y; /* Bezier end y. */
+ double dxdt; /* Bezier dx/dt at end. */
+ double dydt; /* Bezier dy/dt at end. */
+ double lastx = 0.0; /* Bezier start x. */
+ double lasty = 0.0; /* Bezier start y. */
+ double lastdxdt = 0.0; /* dx/dt at start. */
+ double lastdydt = 0.0; /* dy/dt at end. */
+ size_t nsegs; /* Number of segments. */
+ size_t iseg; /* Current segment. */
+ int res; /* Calculation result. */
+ $? "+ f2lud_single_spline_segment"
+ myte = dk3ma_d_sub_ok(te, floor(te), ec);
+ myts = dk3ma_d_sub_ok(ts, floor(ts), ec);
+ dnumsegs = (myte - myts) * dk3fig_tool_xssbs(drw, primary);
+ dnumsegs = ceil(dnumsegs); $? ". dnumsegs = %lg", dnumsegs
+ nsegs = dk3ma_d_to_sz_ok(dnumsegs, ec);
+ pb = &(sp[i]);
+ pc = &(sp[i + 1]);
+ if(0 < i) {
+ pa = &(sp[i - 1]);
+ }
+ if(i < (np - 2)) {
+ pd = &(sp[i + 2]);
+ }
+ factor = (myte - myts) / ((double)nsegs);
+ dk3xsp_reset(&seg);
+ if(job->cosp) { dk3xsp_set_cb(&seg, 1); }
+ dk3xsp_set(&seg, pa, pb, pc, pd);
+ if(dk3xsp_calculate(&seg, myts, 1)) {
+ lastx = dk3xsp_get_x(&seg);
+ lasty = dk3xsp_get_y(&seg);
+ lastdxdt = dk3xsp_get_dxdt(&seg);
+ lastdydt = dk3xsp_get_dydt(&seg);
+ lastdxdt = (factor * lastdxdt) / 3.0;
+ lastdydt = (factor * lastdydt) / 3.0;
+ if(isfirst) {
+ f2lud_fig_moveto(job, drw, obj, lastx, lasty, ec);
+ }
+ if(1.0e-6 < (myte - myts)) {
+ for(iseg = 0; iseg < nsegs; iseg++) {
+ if(iseg < (nsegs - 1)) {
+ t = myts + (((myte - myts) * ((double)(iseg + 1))) / ((double)nsegs));
+ } else {
+ t = myte;
+ }
+ res = dk3xsp_calculate(&seg, t, 1);
+ if(!(res)) {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ x = dk3xsp_get_x(&seg);
+ y = dk3xsp_get_y(&seg);
+ dxdt = dk3xsp_get_dxdt(&seg);
+ dydt = dk3xsp_get_dydt(&seg);
+ dxdt = (factor * dxdt) / 3.0;
+ dydt = (factor * dydt) / 3.0;
+ f2lud_fig_curveto(
+ job, drw, obj,
+ dk3ma_d_add_ok(lastx, lastdxdt, ec),
+ dk3ma_d_add_ok(lasty, lastdydt, ec),
+ dk3ma_d_sub_ok(x, dxdt, ec),
+ dk3ma_d_sub_ok(y, dydt, ec),
+ x, y,
+ ec
+ );
+ lastx = x; lasty = y; lastdxdt = dxdt; lastdydt = dydt;
+ }
+ } else {
+ res = dk3xsp_calculate(&seg, myte, 0);
+ if(!(res)) {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ /* ERROR: Calculation failed! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 36);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH); $? ". exitcode"
+ }
+ x = dk3xsp_get_x(&seg);
+ y = dk3xsp_get_y(&seg);
+ f2lud_fig_lineto(job, drw, obj, x, y, ec);
+ }
+ } else {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ /* ERROR: Calculation failed! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 36);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH); $? ". exitcode"
+ }
+ $? "- f2lud_single_spline_segment"
+}
+
+
+
+
+/** Create path for one complete X-spline segment from closed X-spline.
+ @param job Job structure.
+ @param drw Fig drawing.
+ @param obj Fig object.
+ @param sp Spline points array.
+ @param np Number of spline points.
+ @param i Current segment index.
+ @param isfirst Flag: First segment.
+ @param iscl Flag: Closed spline.
+ @param primary Flag: Primary (1=primary object, 0=arrowhead).
+ @param ec Pointer to error code variable, may be NULL.
+*/
+static
+void
+f2lud_full_spline_segment(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_fig_spline_point_t *sp,
+ size_t np,
+ size_t i,
+ int isfirst,
+ int iscl,
+ int primary,
+ int *ec
+)
+{
+ dk3_xspline_segment_t seg; /* Segment for caluclation. */
+ dk3_fig_spline_point_t *pa = NULL; /* Left neighbour. */
+ dk3_fig_spline_point_t *pb = NULL; /* Start. */
+ dk3_fig_spline_point_t *pc = NULL; /* End. */
+ dk3_fig_spline_point_t *pd = NULL; /* Right neighbour. */
+ double factor; /* Scale factor for deriv. */
+ double t; /* Current t. */
+ double x; /* Bezier end x. */
+ double y; /* Bezier end y. */
+ double dxdt; /* Bezier dx/dt at end. */
+ double dydt; /* Bezier dy/dt at end. */
+ double lastx = 0.0; /* Bezier start x. */
+ double lasty = 0.0; /* Bezier start y. */
+ double lastdxdt = 0.0; /* dx/dt at start. */
+ double lastdydt = 0.0; /* dy/dt at end. */
+ size_t xsss; /* Number of segments. */
+ size_t iseg; /* Current segment. */
+ size_t ic;
+ size_t id;
+ int res; /* Calculation result. */
+ $? "+ f2lud_full_spline_segment %u", (unsigned)i
+ if(i < ((iscl) ? np : (np - 1))) {
+ pb = &(sp[i]);
+ ic = i + 1; while(ic >= np) { ic = ic - np; }
+ pc = &(sp[ic]);
+ if(i > 0) {
+ pa = &(sp[i - 1]);
+ } else {
+ if(iscl) {
+ pa = &(sp[np - 1]);
+ }
+ }
+ if(i < (np - 2)) {
+ pd = &(sp[i + 2]);
+ } else {
+ if(iscl) {
+ id = i + 2; while(id >= np) { id = id - np; }
+ pd = &(sp[id]);
+ }
+ }
+ xsss = dk3fig_tool_xssbs(drw, primary);
+ factor = 1.0 / (double)xsss;
+ dk3xsp_reset(&seg);
+ if(job->cosp) { dk3xsp_set_cb(&seg, 1); }
+ dk3xsp_set(&seg, pa, pb, pc, pd);
+ if(dk3xsp_calculate(&seg, 0.0, 1)) {
+ lastx = dk3xsp_get_x(&seg);
+ lasty = dk3xsp_get_y(&seg);
+ lastdxdt = dk3xsp_get_dxdt(&seg);
+ lastdydt = dk3xsp_get_dydt(&seg);
+ lastdxdt = (factor * lastdxdt) / 3.0;
+ lastdydt = (factor * lastdydt) / 3.0;
+ if(isfirst) {
+ f2lud_fig_moveto(job, drw, obj, lastx, lasty, ec);
+ }
+ for(iseg = 0; iseg < xsss; iseg++) {
+ if(iseg < (xsss - 1)) {
+ t = (double)(iseg + 1) / (double)xsss;
+ } else {
+ t = 1.0;
+ }
+ res = dk3xsp_calculate(&seg, t, 1);
+ if(!(res)) {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ x = dk3xsp_get_x(&seg);
+ y = dk3xsp_get_y(&seg);
+ dxdt = dk3xsp_get_dxdt(&seg);
+ dydt = dk3xsp_get_dydt(&seg);
+ dxdt = (factor * dxdt) / 3.0;
+ dydt = (factor * dydt) / 3.0;
+ f2lud_fig_curveto(
+ job, drw, obj,
+ dk3ma_d_add_ok(lastx, lastdxdt, ec),
+ dk3ma_d_add_ok(lasty, lastdydt, ec),
+ dk3ma_d_sub_ok(x, dxdt, ec),
+ dk3ma_d_sub_ok(y, dydt, ec),
+ x,
+ y,
+ ec
+ );
+ lastx = x; lasty = y; lastdxdt = dxdt; lastdydt = dydt;
+ }
+ } else {
+ if(ec) { *ec = DK3_ERROR_MATH_OVERFLOW; }
+ }
+ } else {
+ /* ERROR: BUG: Wrong i */
+ } $? "- f2lud_full_spline_segment %u", (unsigned)i
+}
+
+
+
+/** Create path for open spline object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param primary Flag: Primary object (1=object, 0=arrowhead).
+ @param ec Pointe to error code variable, may be NULL.
+*/
+static
+void
+f2lud_create_open_spline_path(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+ dk3_fig_spline_point_t *sp; /* Spline points. */
+ size_t np; /* Number of points. */
+ size_t i; /* Current segment index. */
+ size_t min; /* Minimum t value. */
+ size_t max; /* Maximum t value. */
+ $? "+ f2lud_create_open_spline_path"
+ sp = (obj->dt).spl.po;
+ np = (obj->dt).spl.np;
+
+ if(job->coah) { $? ". compatible arrowheads"
+ for(i = 0; i < (np - 1); i++) {
+ f2lud_full_spline_segment(
+ job, drw, obj, sp, np, i, ((0 == i) ? 1 : 0), 0, primary, ec
+ );
+ }
+ } else { $? ". shorten spline if necessary"
+ if(obj->ab) { $? ". have backward arrow"
+ /* 2013-11-23
+ ROUNDING DOWNWARDS INTENDED.
+ We want to find the start segment.
+ */
+ min = dk3ma_d_to_sz_ok(floor((obj->dt).spl.ts), ec);
+ if(obj->af) { $? ". have forward arrow"
+ if((obj->dt).spl.te >= (obj->dt).spl.ts) { $? ". te/ts ok"
+ /* 2013-11-23
+ ROUNDING DOWNWARDS INTENDED.
+ We want to find the last full segment to draw.
+ */
+ max = dk3ma_d_to_sz_ok(floor((obj->dt).spl.te), ec);
+ if(max > min) { $? ". start and end in different segments"
+ f2lud_first_spline_segment(
+ job, drw, obj, sp, np, min, (obj->dt).spl.ts, 1, 0, primary, ec
+ );
+ /* 2012-12-04 Bugfix: Only to max.
+ */
+#if VERSION_BEFORE_20121204
+ for(i = (min + 1); i < (np - 1); i++) {
+ f2lud_full_spline_segment(
+ job, drw, obj, sp, np, i, 0, 0, primary, ec
+ );
+ }
+#else
+ for(i = (min + 1); i < max; i++) {
+ f2lud_full_spline_segment(
+ job, drw, obj, sp, np, i, 0, 0, primary, ec
+ );
+ }
+#endif
+ f2lud_final_spline_segment(
+ job, drw, obj, sp, np, max, (obj->dt).spl.te, 0, 0, primary, ec
+ );
+ } else { $? ". start and end in same segment"
+ f2lud_single_spline_segment(
+ job, drw, obj, sp, np, min, (obj->dt).spl.ts, (obj->dt).spl.te,
+ 1, 0, primary, ec
+ );
+ }
+ } else { $? "! te=%lg < ts=%lg",(obj->dt).spl.te,(obj->dt).spl.ts
+ /* ERROR: Arrowheads too long for spline! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 37);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYNTAX); $? ". exitcode"
+ }
+ } else { $? ". no forward arrow"
+ f2lud_first_spline_segment(
+ job, drw, obj, sp, np, min, (obj->dt).spl.ts, 1, 0, primary, ec
+ );
+ for(i = (min + 1); i < (np - 1); i++) {
+ f2lud_full_spline_segment(
+ job, drw, obj, sp, np, i, 0, 0, primary, ec
+ );
+ }
+ }
+ } else { $? ". no backward arrow"
+ if(obj->af) { $? ". forward arrow"
+ /* 2013-11-23
+ ROUNDING DOWNWARDS INTENDED.
+ We want to find the last full segment.
+ */
+ max = dk3ma_d_to_sz_ok(floor((obj->dt).spl.te), ec);
+ if(max < (np - 1)) { $? ". max ok"
+ if(max > 0) { $? ". max ok"
+ for(i = 0; i < max; i++) {
+ f2lud_full_spline_segment(
+ job, drw, obj, sp, np, i, ((0 == i) ? 1 : 0), 0, primary, ec
+ );
+ }
+ f2lud_final_spline_segment(
+ job, drw, obj, sp, np, max, (obj->dt).spl.te, 0, 0, primary, ec
+ );
+ } else { $? "! max too small"
+ f2lud_final_spline_segment(
+ job, drw, obj, sp, np, max, (obj->dt).spl.te, 1, 0, primary, ec
+ );
+ }
+ } else { $? "! max too large"
+ /* ERROR: Illegal max value! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 39);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN); $? ". exitcode"
+ }
+ } else { $? ". no forward arrow"
+ for(i = 0; i < (np - 1); i++) {
+ f2lud_full_spline_segment(
+ job, drw, obj, sp, np, i, ((0 == i) ? 1 : 0), 0, primary, ec
+ );
+ }
+ }
+ }
+ }
+ $? "- f2lud_create_open_spline_path"
+}
+
+
+
+/** Create path for open spline object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param primary Flag: Primary object (1=object, 0=arrowhead).
+ @param ec Pointe to error code variable, may be NULL.
+*/
+static
+void
+f2lud_create_open_fast_spline_path(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+ dk3_fig_spline_point_t *po;
+ size_t np;
+ size_t ib;
+ size_t ic;
+ double dxdtb;
+ double dydtb;
+ double dxdtc;
+ double dydtc;
+ $? "+ f2lud_create_open_fast_spline_path"
+ po = (obj->dt).spl.po;
+ np = (obj->dt).spl.np;
+ if (np > 1) {
+ for (ib = 0; ib < (np - 1); ib++) {
+ ic = ib + 1;
+ if (0 == ib) {
+ /* MOVETO */
+ f2lud_fig_moveto(job, drw, obj, po[ib].x, po[ib].y, ec);
+ }
+ if ((fabs(po[ib].s) < 1.0e-6) && (fabs(po[ic].s) < 1.0e-6)) {
+ /* LINETO */
+ f2lud_fig_lineto(job, drw, obj, po[ic].x, po[ic].y, ec);
+ } else {
+ dxdtb = dxdtc = dk3ma_d_sub_ok(po[ic].x, po[ib].x, ec);
+ dydtb = dydtc = dk3ma_d_sub_ok(po[ic].y, po[ib].y, ec);
+ if ((0 < ib) && (fabs(1.0 + po[ib].s) < 1.0e-6)) {
+ dxdtb = f2lpara_derived_center(po[ib-1].x, po[ib].x, po[ic].x, ec);
+ dydtb = f2lpara_derived_center(po[ib-1].y, po[ib].y, po[ic].y, ec);
+ } else {
+ if ((ic < (np - 1)) && (fabs(1.0 + po[ic].s) < 1.0e-6)) {
+ dxdtb = f2lpara_derived_left(po[ib].x, po[ic].x, po[ic+1].x, ec);
+ dydtb = f2lpara_derived_left(po[ib].y, po[ic].y, po[ic+1].y, ec);
+ }
+ }
+ if ((ic < (np - 1)) && (1.0 + fabs(po[ic].s) < 1.0e-6)) {
+ dxdtc = f2lpara_derived_center(po[ib].x, po[ic].x, po[ic+1].x, ec);
+ dydtc = f2lpara_derived_center(po[ib].y, po[ic].y, po[ic+1].y, ec);
+ } else {
+ if ((0 < ib) && (fabs(1.0 + po[ib].s) < 1.0e-6)) {
+ dxdtc = f2lpara_derived_right(po[ib-1].x, po[ib].x, po[ic].x, ec);
+ dydtc = f2lpara_derived_right(po[ib-1].y, po[ib].y, po[ic].y, ec);
+ }
+ }
+ /* CURVETO */
+ f2lud_fig_curveto(
+ job, drw, obj,
+ dk3ma_d_add_ok(po[ib].x, (dxdtb / 3.0), ec),
+ dk3ma_d_add_ok(po[ib].y, (dydtb / 3.0), ec),
+ dk3ma_d_sub_ok(po[ic].x, (dxdtc / 3.0), ec),
+ dk3ma_d_sub_ok(po[ic].y, (dydtc / 3.0), ec),
+ po[ic].x,
+ po[ic].y,
+ ec
+ );
+ }
+ }
+ } $? "- f2lud_create_open_fast_spline_path"
+}
+
+
+
+/** Create path for closed spline object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param primary Flag: Primary object (1=object, 0=arrowhead).
+ @param ec Pointe to error code variable, may be NULL.
+*/
+static
+void
+f2lud_create_closed_spline_path(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+ dk3_fig_spline_point_t *sp; /* Spline points. */
+ size_t np; /* Number of points. */
+ size_t i; /* Current segment index. */
+ $? "+ f2lud_create_closed_spline_path"
+ sp = (obj->dt).spl.po;
+ np = (obj->dt).spl.np;
+ for(i = 0; i < np; i++) {
+ f2lud_full_spline_segment(
+ job, drw, obj, sp, np, i, ((0 == i) ? 1 : 0), 1, primary, ec
+ );
+ }
+ $? "- f2lud_create_closed_spline_path"
+}
+
+/** Create path for closed spline object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param primary Flag: Primary object (1=object, 0=arrowhead).
+ @param ec Pointe to error code variable, may be NULL.
+*/
+static
+void
+f2lud_create_closed_fast_spline_path(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+ dk3_fig_spline_point_t *po;
+ size_t np;
+ size_t ib;
+ size_t ic;
+ size_t ia;
+ size_t id;
+ double dxdtb;
+ double dydtb;
+ double dxdtc;
+ double dydtc;
+ $? "+ f2lud_create_closed_fast_spline_path"
+ po = (obj->dt).spl.po;
+ np = (obj->dt).spl.np;
+ if (2 < np) {
+ for (ib = 0; ib < np; ib++) {
+ ic = ib + 1;
+ id = ib + 2;
+ if (ic >= np) { ic = ic - np; }
+ if (id >= np) { id = id - np; }
+ if (0 < ib) {
+ ia = ib - 1;
+ } else {
+ ia = np - 1;
+ }
+ if (0 == ib) {
+ /* MOVETO */
+ f2lud_fig_moveto(job, drw, obj, po[ib].x, po[ib].y, ec);
+ }
+ if ((fabs(po[ib].s) < 1.0e-6) && (fabs(po[ic].s) < 1.0e-6)) {
+ /* LINETO */
+ f2lud_fig_lineto(job, drw, obj, po[ic].x, po[ic].y, ec);
+ } else {
+ dxdtb = dxdtc = dk3ma_d_sub_ok(po[ic].x, po[ib].x, ec);
+ dydtb = dydtc = dk3ma_d_sub_ok(po[ic].y, po[ib].y, ec);
+ if (fabs(1.0 + po[ib].s) < 1.0e-6) {
+ dxdtb = f2lpara_derived_center(po[ia].x, po[ib].x, po[ic].x, ec);
+ dydtb = f2lpara_derived_center(po[ia].y, po[ib].y, po[ic].y, ec);
+ } else {
+ if (fabs(1.0 + po[ic].s) < 1.0e-6) {
+ dxdtb = f2lpara_derived_left(po[ib].x, po[ic].x, po[id].x, ec);
+ dydtb = f2lpara_derived_left(po[ib].y, po[ic].y, po[id].y, ec);
+ }
+ }
+ if (fabs(1.0 + po[ic].s) < 1.0e-6) {
+ dxdtc = f2lpara_derived_center(po[ib].x, po[ic].x, po[id].x, ec);
+ dydtc = f2lpara_derived_center(po[ib].y, po[ic].y, po[id].y, ec);
+ } else {
+ if (fabs(1.0 + po[ib].s) < 1.0e-6) {
+ dxdtc = f2lpara_derived_right(po[ia].x, po[ib].x, po[ic].x, ec);
+ dydtc = f2lpara_derived_right(po[ia].y, po[ib].y, po[ic].y, ec);
+ }
+ }
+ /* CURVETO */
+ f2lud_fig_curveto(
+ job, drw, obj,
+ dk3ma_d_add_ok(po[ib].x, (dxdtb / 3.0), ec),
+ dk3ma_d_add_ok(po[ib].y, (dydtb / 3.0), ec),
+ dk3ma_d_sub_ok(po[ic].x, (dxdtc / 3.0), ec),
+ dk3ma_d_sub_ok(po[ic].y, (dydtc / 3.0), ec),
+ po[ic].x,
+ po[ic].y,
+ ec
+ );
+ }
+ }
+ }
+ $? "+ f2lud_create_closed_fast_spline_path"
+}
+
+
+
+/** Create path for open arc object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param iscl Flag: Closed arc.
+ @param ec Pointe to error code variable, may be NULL.
+*/
+static
+void
+f2lud_create_arc_path(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int iscl,
+ int *ec
+)
+{
+ double sx; /* Start x. */
+ double sy; /* Start y. */
+ double cx; /* Center x. */
+ double cy; /* Center y. */
+ double r; /* Radius. */
+ double as; /* Arc start angle in radians. */
+ double ae; /* Arc end angle in radians. */
+ double lastx; /* Segment start x. */
+ double lasty; /* Segment start y. */
+ double lastkdxdt; /* X difference to first control. */
+ double lastkdydt; /* Y difference to first control. */
+ double x; /* Segment end x. */
+ double y; /* Segment end y. */
+ double kdxdt; /* X difference to last control. */
+ double kdydt; /* Y difference to last control. */
+ double dnumsegs; /* Number of segments. */
+ double alpha; /* Arc angle in radians. */
+ double alphaseg; /* Segment angle in radians. */
+ double kappa; /* Factor for derivative. */
+ double alphaend; /* Segment end angle in radians. */
+ size_t nsegs; /* Number of segments. */
+ size_t i; /* Index of current segment. */
+ $? "+ f2lud_create_open_arc_path"
+ cx = (obj->dt).arc.xc;
+ cy = (obj->dt).arc.yc;
+ r = (obj->dt).arc.ra;
+ if((obj->dt).arc.as < (obj->dt).arc.ae) {
+ as = (obj->dt).arc.as;
+ ae = (obj->dt).arc.ae;
+ } else {
+ as = (obj->dt).arc.ae;
+ ae = (obj->dt).arc.as;
+ }
+ alpha = dk3ma_d_sub_ok(ae, as, ec);
+ dnumsegs = ceil(dk3ma_d_mul_ok(4.0, (alpha / M_PI), ec));
+ $? ". dnumsegs = %lg", dnumsegs
+ nsegs = dk3ma_d_to_sz_ok(dnumsegs, ec);
+ alphaseg = alpha / ((double)nsegs);
+ kappa = dk3fig_tool_arc_kappa(alphaseg, ec);
+ sx = lastx = dk3ma_d_add_ok(cx, (r * cos(as)), ec);
+ sy = lasty = dk3ma_d_add_ok(cy, (r * sin(as)), ec);
+ f2lud_fig_moveto(job, drw, obj, lastx, lasty, ec);
+ lastkdxdt = dk3ma_d_mul_ok(
+ kappa,
+ (-1.0 * dk3ma_d_mul_ok(r, alphaseg, ec) * sin(as)),
+ ec
+ );
+ lastkdydt = dk3ma_d_mul_ok(
+ kappa,
+ (dk3ma_d_mul_ok(r, alphaseg, ec) * cos(as)),
+ ec
+ );
+ for(i = 0; i < nsegs; i++) {
+ if(i < (nsegs - 1)) {
+ alphaend = dk3ma_d_add_ok(
+ as,
+ dk3ma_d_mul_ok(dk3ma_d_add_ok(1.0, (double)i, ec), alphaseg, ec),
+ ec
+ );
+ } else {
+ alphaend = ae;
+ }
+ x = dk3ma_d_add_ok(cx, (r * cos(alphaend)), ec);
+ y = dk3ma_d_add_ok(cy, (r * sin(alphaend)), ec);
+ kdxdt = dk3ma_d_mul_ok(
+ kappa,
+ (-1.0 * dk3ma_d_mul_ok(r, alphaseg, ec) * sin(alphaend)),
+ ec
+ );
+ kdydt = dk3ma_d_mul_ok(
+ kappa,
+ (dk3ma_d_mul_ok(r, alphaseg, ec) * cos(alphaend)),
+ ec
+ );
+ f2lud_fig_curveto(
+ job, drw, obj,
+ dk3ma_d_add_ok(lastx, lastkdxdt, ec),
+ dk3ma_d_add_ok(lasty, lastkdydt, ec),
+ dk3ma_d_sub_ok(x, kdxdt, ec),
+ dk3ma_d_sub_ok(y, kdydt, ec),
+ x, y,
+ ec
+ );
+ lastx = x; lasty = y; lastkdxdt = kdxdt; lastkdydt = kdydt;
+ }
+ /* For closed arc draw the lines.
+ */
+ if(iscl) {
+ f2lud_fig_lineto(job, drw, obj, cx, cy, ec);
+ f2lud_fig_lineto(job, drw, obj, sx, sy, ec);
+ }
+ $? "- f2lud_create_open_arc_path"
+}
+
+
+
+/** Create path for half circle object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param ec Pointe to error code variable, may be NULL.
+*/
+static
+void
+f2lud_create_half_circle_path(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ dk3_fig_poly_point_t po[7]; /* Points to construct path. */
+ size_t i; /* Current point index */
+ $? "+ f2lud_create_half_circle_path"
+ po[0].x = 0.0;
+ po[0].y = (obj->dt).hci.ra;
+ po[1].x = -1.0 * FIG2LAT_CIRCLE_QUADRANT_BEZIER * (obj->dt).hci.ra;
+ po[1].y = (obj->dt).hci.ra;
+ po[2].x = -1.0 * (obj->dt).hci.ra;
+ po[2].y = FIG2LAT_CIRCLE_QUADRANT_BEZIER * (obj->dt).hci.ra;
+ po[3].x = -1.0 * (obj->dt).hci.ra;
+ po[3].y = 0.0;
+ po[4].x = -1.0 * (obj->dt).hci.ra;
+ po[4].y = -1.0 * FIG2LAT_CIRCLE_QUADRANT_BEZIER * (obj->dt).hci.ra;
+ po[5].x = -1.0 * FIG2LAT_CIRCLE_QUADRANT_BEZIER * (obj->dt).hci.ra;
+ po[5].y = -1.0 * (obj->dt).hci.ra;
+ po[6].x = 0.0;
+ po[6].y = -1.0 * (obj->dt).hci.ra;
+ if(1.0e-6 < fabs((obj->dt).hci.an)) {
+ for(i = 0; i < 7; i++) {
+ dk3fig_tool_rotate_point(&(po[i]), (obj->dt).hci.an, ec);
+ }
+ }
+ for(i = 0; i < 7; i++) {
+ dk3fig_tool_shift_point(&(po[i]), (obj->dt).hci.cx, (obj->dt).hci.cy, ec);
+ }
+ f2lud_fig_moveto(job, drw, obj, po[0].x, po[0].y, ec);
+ f2lud_fig_curveto(
+ job, drw, obj, po[1].x, po[1].y, po[2].x, po[2].y, po[3].x, po[3].y, ec
+ );
+ f2lud_fig_curveto(
+ job, drw, obj, po[4].x, po[4].y, po[5].x, po[5].y, po[6].x, po[6].y, ec
+ );
+ if(obj->st) {
+ f2lud_fig_lineto(job, drw, obj, po[0].x, po[0].y, ec);
+ }
+ $? "- f2lud_create_half_circle_path"
+}
+
+
+
+/** Create path for object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param ec Pointe to error code variable, may be NULL.
+ @param primary Flag: Primary object (1=object, 0=arrowhead).
+*/
+static
+void
+f2lud_create_path(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+ $? "+ f2lud_create_path"
+ switch(obj->ot) {
+ case DK3_FIG_OBJ_ELLIPSE: {
+ f2lud_create_ellipse_path(job, drw, obj, ec);
+ } break;
+ case DK3_FIG_OBJ_POLYLINE: {
+ switch(obj->st) {
+ case 1: { /* Polyline */
+ f2lud_create_polygon_path(job, drw, obj, ec);
+ } break;
+ case 2: { /* Box */
+ f2lud_create_box_path(job, drw, obj, ec);
+ } break;
+ case 3: { /* Polygon */
+ f2lud_create_polygon_path(job, drw, obj, ec);
+ } break;
+ case 4: { /* Arc-box */
+ f2lud_create_arc_box_path(job, drw, obj, ec);
+ } break;
+ }
+ } break;
+ case DK3_FIG_OBJ_SPLINE: {
+ switch(obj->st) {
+ case 0: case 2: case 4: { /* open spline */
+ f2lud_create_open_spline_path(job, drw, obj, primary, ec);
+ } break;
+ case 1: case 3: case 5: { /* closed spline */
+ f2lud_create_closed_spline_path(job, drw, obj, primary, ec);
+ } break;
+ }
+ } break;
+ case DK3_FIG_OBJ_ARC: {
+ switch(obj->st) {
+ case 1: { /* open arc */
+ f2lud_create_arc_path(job, drw, obj, 0, ec);
+ } break;
+ default: { /* closed arc */
+ f2lud_create_arc_path(job, drw, obj, 1, ec);
+ } break;
+ }
+ } break;
+ case DK3_FIG_OBJ_PSEUDO_HALF_CIRCLE: {
+ f2lud_create_half_circle_path(job, drw, obj, ec);
+ } break;
+ case DK3_FIG_OBJ_PSEUDO_FAST_SPLINE: {
+ switch(obj->st) {
+ case 0: case 2: case 4: { /* open spline */
+ f2lud_create_open_fast_spline_path(job, drw, obj, primary, ec);
+ } break;
+ case 1: case 3: case 5: { /* closed spline */
+ f2lud_create_closed_fast_spline_path(job, drw, obj, primary, ec);
+ } break;
+ }
+ } break;
+ } $? "- f2lud_create_path"
+}
+
+
+
+/** Set color (stroke color for pdf/pgf).
+ If we already have a color 1 equal to the new color
+ the operation is skipped.
+ @param job Conversion job structure.
+ @param drw Drawing structure.
+ @param colno Color number.
+ @param fillstyle Fill style used in the object.
+ Depending on the fillstyle it might be necessary
+ to create a shade of the color.
+*/
+static
+void
+f2lud_set_color_1(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ int colno,
+ int fillstyle
+)
+{
+ dk3_rgb_color_t rgb; /* Color structure to fill. */
+ int muc = 1; /* Flag: Must configure. */
+#if 0
+ int ec = 0; /* Error code variable. */
+#endif
+ $? "+ f2lud_set_color_1"
+ dk3fig_tool_find_color(&rgb, drw, colno, fillstyle);
+#if 0
+ if((job->gs).hc1) {
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok(rgb.r, (job->gs).c1.r, &ec))) {
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok(rgb.g, (job->gs).c1.g, &ec))) {
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok(rgb.b, (job->gs).c1.b, &ec))) {
+ if(0 == ec) {
+ muc = 0;
+ }
+ }
+ }
+ }
+ }
+#else
+ muc = dk3fig_tool_must_set_color(
+ (job->gs).hc1, (job->gs).c1.r, (job->gs).c1.g, (job->gs).c1.b,
+ rgb.r, rgb.g, rgb.b
+ );
+#endif
+ if(muc) {
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_set_color_1(job, drw, &rgb);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_set_color_1(job, drw, &rgb);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_set_color_1(job, drw, &rgb);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_set_color_1(job, drw, &rgb);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_set_color_1(job, drw, &rgb);
+ } break;
+ /* @DRIVER@ universal */
+ default: {
+ f2lpgf_pgf_set_color_1(job, drw, &rgb);
+ } break;
+ }
+ (job->gs).c1.r = rgb.r;
+ (job->gs).c1.g = rgb.g;
+ (job->gs).c1.b = rgb.b;
+ (job->gs).hc1 = 1;
+ }
+ $? "- f2lud_set_color_1"
+}
+
+
+
+/** Set non-stroking color for pdf/pgf.
+ If we already have a color 2 equal to the new color
+ the operation is skipped.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param colno Color number.
+ @param fillstyle Fill style used in the object.
+ Depending on the fillstyle it might be necessary
+ to create a shade of the color.
+*/
+static
+void
+f2lud_set_color_2(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ int colno,
+ int fillstyle
+)
+{
+ dk3_rgb_color_t rgb; /* Color structure to fill. */
+#if 0
+ int ec = 0; /* Error code variable. */
+#endif
+ int muc = 1; /* Flag: Must configure. */
+ $? "+ f2lud_set_color_2"
+
+ dk3fig_tool_find_color(&rgb, drw, colno, fillstyle);
+#if 0
+ if((job->gs).hc2) {
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok(rgb.r, (job->gs).c2.r, &ec))) {
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok(rgb.g, (job->gs).c2.g, &ec))) {
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok(rgb.b, (job->gs).c2.b, &ec))) {
+ if(0 == ec) {
+ muc = 0;
+ }
+ }
+ }
+ }
+ }
+#else
+ muc = dk3fig_tool_must_set_color(
+ (job->gs).hc2, (job->gs).c2.r, (job->gs).c2.g, (job->gs).c2.b,
+ rgb.r, rgb.g, rgb.b
+ );
+#endif
+ if(muc) {
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_set_color_2(job, drw, &rgb);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_set_color_2(job, drw, &rgb);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_set_color_2(job, drw, &rgb);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_set_color_2(job, drw, &rgb);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_set_color_2(job, drw, &rgb);
+ } break;
+ /* @DRIVER@ universal */
+ default: {
+ f2lpgf_pgf_set_color_2(job, drw, &rgb);
+ } break;
+ }
+ (job->gs).c2.r = rgb.r;
+ (job->gs).c2.g = rgb.g;
+ (job->gs).c2.b = rgb.b;
+ (job->gs).hc2 = 1;
+ }
+ $? "- f2lud_set_color_2"
+}
+
+
+
+/** Internal function to set line width.
+ The line width is not set again if we already
+ have a current line width equal to the new line width.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object.
+ @param lw New line width in output coordinates.
+*/
+static
+void
+f2lud_internal_set_line_width(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double lw
+)
+{
+ int mc = 1; /* Flag: Must configure. */
+ int ec = 0; /* Error code variable. */
+ $? "+ f2lud_internal_set_line_width %lg", lw
+ if((job->gs).hlw) {
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok(lw, (job->gs).lw, &ec))) {
+ if(0 == ec) {
+ mc = 0;
+ }
+ }
+ }
+ if(mc) {
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_set_line_width(job, drw, obj, lw);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_set_line_width(job, drw, obj, lw);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_set_line_width(job, drw, obj, lw);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_set_line_width(job, drw, obj, lw);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_set_line_width(job, drw, obj, lw);
+ } break;
+ /* @DRIVER@ universal */
+ default: {
+ f2lpgf_pgf_set_line_width(job, drw, obj, lw);
+ } break;
+ }
+ (job->gs).lw = lw;
+ (job->gs).hlw = 1;
+ }
+ $? "- f2lud_internal_set_line_width"
+}
+
+
+
+/** Set line dash (line style and dash/gap length).
+ The operation is skipped if the current line style and style
+ value is equal to the new one.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+ @param ls Line style.
+ @param sv Style value (dash/gap) length in output units.
+*/
+static
+void
+f2lud_internal_set_line_dash(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int ls,
+ double sv
+)
+{
+ double mysv; /* Style value converted to output space. */
+ double mylw; /* Line width in Fig and output space. */
+ int mc = 1; /* Flag: Must configure. */
+ int ec = 0; /* Error code variable. */
+ $? "+ f2lud_internal_set_line_dash"
+ mysv = 0.9 * sv;
+ mylw = dk3fig_tool_get_lw(drw, obj, &ec);
+ /* Convert line width to output space.
+ */
+ mylw = dk3ct_2d_r(&(job->ct2d), mylw, &ec);
+ if((job->gs).hls) {
+ if((job->gs).ls == ls) {
+ if(DK3_FIG_LS_SOLID == ls) {
+ mc = 0;
+ } else {
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok((job->gs).sv, mysv, &ec))) {
+ if(0 == ec) {
+ if(DK3_FIG_LS_DASHED == ls) {
+ mc = 0;
+ } else {
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok((job->gs).slw, mylw, &ec))) {
+ if(0 == ec) {
+ mc = 0;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if(mc) {
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_set_line_style(job, drw, obj, ls, mysv, mylw);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_set_line_style(job, drw, obj, ls, mysv, mylw);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_set_line_style(job, drw, obj, ls, mysv, mylw);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_set_line_style(job, drw, obj, ls, mysv, mylw);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_set_line_style(job, drw, obj, ls, mysv, mylw);
+ } break;
+ /* @DRIVER@ universal */
+ default: {
+ f2lpgf_pgf_set_line_style(job, drw, obj, ls, mysv, mylw);
+ } break;
+ }
+ (job->gs).ls = ls; (job->gs).sv = mysv; (job->gs).slw = mylw;
+ (job->gs).hls = 1;
+ }
+ $? "- f2lud_internal_set_line_dash"
+}
+
+
+
+/** Set line ends.
+ The operation is skipped if the current line end is equal
+ to the new one.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object.
+ @param le Line end style.
+*/
+static
+void
+f2lud_set_line_end(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int le
+)
+{
+ int mc = 1; /* Flag: Must configure. */
+ $? "+ f2lud_set_line_end"
+ if((job->gs).hlc) {
+ if((job->gs).lc == le) {
+ mc = 0;
+ }
+ }
+ if(mc) {
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_set_line_end(job, drw, obj, le);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_set_line_end(job, drw, obj, le);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_set_line_end(job, drw, obj, le);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_set_line_end(job, drw, obj, le);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_set_line_end(job, drw, obj, le);
+ } break;
+ /* @DRIVER@ universal */
+ default: {
+ f2lpgf_pgf_set_line_end(job, drw, obj, le);
+ } break;
+ }
+ (job->gs).lc = le; (job->gs).hlc = 1;
+ }
+ $? "- f2lud_set_line_end"
+}
+
+
+
+/** Set line join.
+ The operation is skipped if the current line join is equal
+ to the new one.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object.
+ @param lj Line end style.
+*/
+static
+void
+f2lud_set_line_join(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int lj
+)
+{
+ int mc = 1; /* Flag: Must configure. */
+ $? "+ f2lud_set_line_join"
+ if((job->gs).hlj) {
+ if((job->gs).lj == lj) {
+ mc = 0;
+ }
+ }
+ if(mc) {
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ f2lpgf_tex_set_line_join(job, drw, obj, lj);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ f2lpdf_tex_with_pdf_set_line_join(job, drw, obj, lj);
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ f2leps_eps_with_tex_set_line_join(job, drw, obj, lj);
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ f2lpdf_pdf_with_tex_set_line_join(job, drw, obj, lj);
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ f2leps_eps_pure_set_line_join(job, drw, obj, lj);
+ } break;
+ /* @DRIVER@ universal */
+ default: {
+ f2lpgf_pgf_set_line_join(job, drw, obj, lj);
+ } break;
+ }
+ (job->gs).lj = lj; (job->gs).hlj = 1;
+ }
+ $? "- f2lud_set_line_join"
+}
+
+
+
+/** Set up line style, line width, line ends and line join for pattern.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+static
+void
+f2lud_set_pattern_line_style(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ $? "+ f2lud_set_pattern_line_style"
+#if VERSION_BEFORE_20140330
+ f2lud_internal_set_line_width(job, drw, obj, ((job->lighten) ? 0.45 : 0.9));
+#else
+ f2lud_internal_set_line_width(job, drw, obj, job->lwbp);
+#endif
+ f2lud_internal_set_line_dash(job, drw, obj, DK3_FIG_LS_SOLID, -1.0);
+ f2lud_set_line_end(job, drw, obj, DK3_FIG_LC_BUTT);
+ f2lud_set_line_join(job, drw, obj, DK3_FIG_LJ_MITER);
+#if 0
+ /* 2012/11/18
+ In fishscale patterns we draw arc by arc, not a sequence
+ of arcs. So we do not need to care about line join
+ of arcs.
+ */
+ switch(obj->fi) {
+ case 56: case 57: {
+ f2lud_set_line_join(job, drw, obj, DK3_FIG_LJ_BEVEL);
+ } break;
+ default: {
+ f2lud_set_line_join(job, drw, obj, DK3_FIG_LJ_MITER);
+ } break;
+ }
+#endif
+ $? "- f2lud_set_pattern_line_style"
+}
+
+
+
+/** Set line width.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+static
+void
+f2lud_set_line_width(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ double lw; /* Line width in Fig space. */
+ int ec = 0; /* Error code variable. */
+ $? "+ f2lud_set_line_width"
+ lw = dk3fig_tool_get_lw(drw, obj, &ec);
+ lw = dk3ct_2d_r(&(job->ct2d), lw, &ec);
+ if(0 == ec) {
+ f2lud_internal_set_line_width(job, drw, obj, lw);
+ } $? "- f2lud_set_line_width"
+}
+
+
+
+/** Set line dash (line style and dash/gap length).
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Fig object.
+*/
+static
+void
+f2lud_set_line_dash(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ $? "+ f2lud_set_line_dash"
+ f2lud_internal_set_line_dash(job, drw, obj, obj->ls, (0.9 * obj->sv));
+ $? "- f2lud_set_line_dash"
+}
+
+
+
+/** Draw operations for object: stroke.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param ec Pointe to error code variable, may be NULL.
+ @param primary Flag: primary (1=primary object, 0=arrowhead).
+*/
+static
+void
+f2lud_path_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+ $? "+ f2lud_path_stroke"
+ f2lud_set_color_1(job, drw, obj->pc, 20);
+ f2lud_set_line_width(job, drw, obj);
+ f2lud_set_line_dash(job, drw, obj);
+ f2lud_set_line_end(job, drw, obj, obj->cs);
+ f2lud_set_line_join(job, drw, obj, obj->js);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ if(obj->cl) {
+ f2lud_closepath(job, drw, obj);
+ }
+ f2lud_stroke(job, drw, obj);
+ $? "- f2lud_path_stroke"
+}
+
+
+
+/** Draw operations for object: fill.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param ec Pointe to error code variable, may be NULL.
+ @param primary Flag: primary (1=primary object, 0=arrowhead).
+*/
+static
+void
+f2lud_path_fill(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+ $? "+ f2lud_path_fill"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_PGF:
+ case FIG2LAT_DRIVER_TEX_FULL_PGF:
+ case FIG2LAT_DRIVER_TEX_FULL_PDF:
+ case FIG2LAT_DRIVER_PDF_WITH_TEX:
+ {
+ f2lud_set_color_2(job, drw, obj->fc, obj->fi);
+ } break;
+ default: {
+ f2lud_set_color_1(job, drw, obj->fc, obj->fi);
+ } break;
+ }
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_fill(job, drw, obj);
+ $? "- f2lud_path_fill"
+}
+
+
+
+/** Draw operations for object: fill and stroke.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param ec Pointe to error code variable, may be NULL.
+ @param primary Flag: primary (1=primary object, 0=arrowhead).
+*/
+static
+void
+f2lud_path_fill_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+ $? "+ f2lud_path_fill_stroke"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_PGF:
+ case FIG2LAT_DRIVER_TEX_FULL_PGF:
+ {
+ f2lud_set_color_2(job, drw, obj->fc, obj->fi);
+ f2lud_set_color_1(job, drw, obj->pc, 20);
+ f2lud_set_line_width(job, drw, obj);
+ f2lud_set_line_dash(job, drw, obj);
+ f2lud_set_line_end(job, drw, obj, obj->cs);
+ f2lud_set_line_join(job, drw, obj, obj->js);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_fill_stroke(job, drw, obj);
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF:
+ case FIG2LAT_DRIVER_PDF_WITH_TEX:
+ {
+ f2lud_set_color_2(job, drw, obj->fc, obj->fi);
+ f2lud_set_color_1(job, drw, obj->pc, 20);
+ f2lud_set_line_width(job, drw, obj);
+ f2lud_set_line_dash(job, drw, obj);
+ f2lud_set_line_end(job, drw, obj, obj->cs);
+ f2lud_set_line_join(job, drw, obj, obj->js);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_fill(job, drw, obj);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_stroke(job, drw, obj);
+ } break;
+ default: {
+ f2lud_set_line_width(job, drw, obj);
+ f2lud_set_line_dash(job, drw, obj);
+ f2lud_set_line_end(job, drw, obj, obj->cs);
+ f2lud_set_line_join(job, drw, obj, obj->js);
+ f2lud_set_color_1(job, drw, obj->fc, obj->fi);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_fill(job, drw, obj);
+ f2lud_set_color_1(job, drw, obj->pc, obj->fi);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_stroke(job, drw, obj);
+ } break;
+ } $? "- f2lud_path_fill_stroke"
+}
+
+
+
+/** Draw operations for object: pattern.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param ec Pointe to error code variable, may be NULL.
+ @param primary Flag: primary (1=primary object, 0=arrowhead).
+*/
+static
+void
+f2lud_path_pattern(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+ $? "+ f2lud_path_pattern"
+ f2lud_set_pattern_line_style(job, drw, obj);
+ f2lud_set_color_1(job, drw, obj->pc, 20);
+ f2lud_gsave(job, drw, obj);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_clip(job, drw, obj);
+ f2lud_pattern(job, drw, obj, ec);
+ f2lud_grestore(job, drw, obj);
+ $? "- f2lud_path_pattern"
+}
+
+
+
+/** Draw operations for object: pattern and stroke.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param ec Pointe to error code variable, may be NULL.
+ @param primary Flag: primary (1=primary object, 0=arrowhead).
+*/
+static
+void
+f2lud_path_pattern_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+ $? "+ f2lud_path_pattern_stroke"
+ f2lud_set_color_1(job, drw, obj->pc, 20);
+ f2lud_set_pattern_line_style(job, drw, obj);
+ f2lud_gsave(job, drw, obj);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_clip(job, drw, obj);
+ f2lud_pattern(job, drw, obj, ec);
+ f2lud_grestore(job, drw, obj);
+ f2lud_set_line_width(job, drw, obj);
+ f2lud_set_line_dash(job, drw, obj);
+ f2lud_set_line_end(job, drw, obj, obj->cs);
+ f2lud_set_line_join(job, drw, obj, obj->js);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_stroke(job, drw, obj);
+ $? "- f2lud_path_pattern_stroke"
+}
+
+
+
+/** Draw operations for object: fill and pattern.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param ec Pointe to error code variable, may be NULL.
+ @param primary Flag: primary (1=primary object, 0=arrowhead).
+*/
+static
+void
+f2lud_path_fill_pattern(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+ $? "+ f2lud_path_fill_pattern"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_PGF:
+ case FIG2LAT_DRIVER_TEX_FULL_PGF:
+ {
+ f2lud_set_color_2(job, drw, obj->fc, obj->fi);
+ f2lud_set_color_1(job, drw, obj->pc, 20);
+ f2lud_set_pattern_line_style(job, drw, obj);
+ f2lud_gsave(job, drw, obj);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_fill_clip(job, drw, obj);
+ f2lud_pattern(job, drw, obj, ec);
+ f2lud_grestore(job, drw, obj);
+ } break;
+ default: {
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PDF:
+ case FIG2LAT_DRIVER_PDF_WITH_TEX:
+ {
+ f2lud_set_color_2(job, drw, obj->fc, obj->fi);
+ f2lud_set_color_1(job, drw, obj->pc, 20);
+ f2lud_set_pattern_line_style(job, drw, obj);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_fill(job, drw, obj);
+ f2lud_gsave(job, drw, obj);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_clip(job, drw, obj);
+ f2lud_pattern(job, drw, obj, ec);
+ f2lud_grestore(job, drw, obj);
+ } break;
+ default: {
+ f2lud_set_color_1(job, drw, obj->fc, obj->fi);
+ f2lud_set_pattern_line_style(job, drw, obj);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_fill(job, drw, obj);
+ f2lud_set_color_1(job, drw, obj->pc, 20);
+ f2lud_gsave(job, drw, obj);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_clip(job, drw, obj);
+ f2lud_pattern(job, drw, obj, ec);
+ f2lud_grestore(job, drw, obj);
+ } break;
+ }
+ } break;
+ } $? "- f2lud_path_fill_pattern"
+}
+
+
+
+/** Check whether on object line style and line width
+ matches style and width configured in a dk3_graphics_state_t.
+ @param gs dk3_graphics_state_t to test.
+ @param ct2d Coordinates transformation data.
+ @param drw Drawing containing the Fig object.
+ @param obj Fig object.
+ @return 1 for equal line width and style, 0 otherwise.
+*/
+static
+int
+f2lud_style_equal(
+ dk3_graphics_state_t *gs,
+ dk3_ct_2d_t *ct2d,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ double lw; /* Line width in Fig space. */
+ int back = 0;
+ int ec = 0; /* Error code variable. */
+#if 0
+ if((gs->hlw) && (gs->hls) && (gs->hlc) && (gs->hlj)) {
+ if((gs->ls = obj->ls) && (gs->lc == obj->cs) && (gs->lj == obj->js)) {
+ lw = dk3fig_tool_get_lw(drw, obj, &ec);
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok(gs->lw, lw, &ec))) {
+ if(0 == ec) {
+ if(DK3_FIG_LS_SOLID == obj->ls) {
+ back = 1;
+ } else {
+ sv = 0.9 * obj->sv;
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok(gs->sv, sv, &ec))) {
+ if(0 == ec) {
+ back = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+#else
+ /* 2012/11/15 As this operation is applied to closed path objects
+ only, there is no need to check line ends.
+ As fill patterns are drawn as solid lines, we only have
+ to check the object line style, whether it is solid.
+ For solid lines the style value is ignored.
+ */
+ if((gs->hlw) && (gs->hls) && (gs->hlj)) {
+ if(DK3_FIG_LS_SOLID == obj->ls) {
+ if(gs->lj == obj->js) {
+ lw = dk3fig_tool_get_lw(drw, obj, &ec);
+ lw = dk3ct_2d_r(ct2d, lw, &ec);
+ if(1.0e-6 > fabs(dk3ma_d_sub_ok(gs->lw, lw, &ec))) {
+ if(0 == ec) {
+ back = 1;
+ }
+ }
+ }
+ }
+ }
+#endif
+ return back;
+}
+
+
+
+/** Draw operations for object: fill, pattern and stroke.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param ec Pointe to error code variable, may be NULL.
+ @param primary Flag: primary (1=primary object, 0=arrowhead).
+*/
+static
+void
+f2lud_path_fill_pattern_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int primary,
+ int *ec
+)
+{
+ $? "+ f2lud_path_fill_pattern_stroke"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_PGF:
+ case FIG2LAT_DRIVER_TEX_FULL_PGF:
+ {
+ f2lud_set_color_2(job, drw, obj->fc, obj->fi);
+ f2lud_set_color_1(job, drw, obj->pc, 20);
+ f2lud_set_pattern_line_style(job, drw, obj);
+ if(f2lud_style_equal(&(job->gs), &(job->ct2d), drw, obj)) {
+ f2lud_gsave(job, drw, obj);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_fill_stroke_clip(job, drw, obj);
+ f2lud_pattern(job, drw, obj, ec);
+ f2lud_grestore(job, drw, obj);
+ } else {
+ f2lud_gsave(job, drw, obj);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_fill_clip(job, drw, obj);
+ f2lud_pattern(job, drw, obj, ec);
+ f2lud_grestore(job, drw, obj);
+ f2lud_set_line_width(job, drw, obj);
+ f2lud_set_line_dash(job, drw, obj);
+ f2lud_set_line_end(job, drw, obj, obj->cs);
+ f2lud_set_line_join(job, drw, obj, obj->js);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_stroke(job, drw, obj);
+ }
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF:
+ case FIG2LAT_DRIVER_PDF_WITH_TEX:
+ {
+ f2lud_set_color_2(job, drw, obj->fc, obj->fi);
+ f2lud_set_color_1(job, drw, obj->pc, 20);
+ f2lud_set_pattern_line_style(job, drw, obj);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_fill(job, drw, obj);
+ f2lud_gsave(job, drw, obj);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_clip(job, drw, obj);
+ f2lud_pattern(job, drw, obj, ec);
+ f2lud_grestore(job, drw, obj);
+ f2lud_set_line_width(job, drw, obj);
+ f2lud_set_line_dash(job, drw, obj);
+ f2lud_set_line_end(job, drw, obj, obj->cs);
+ f2lud_set_line_join(job, drw, obj, obj->js);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_stroke(job, drw, obj);
+ } break;
+ default: {
+ f2lud_set_color_1(job, drw, obj->fc, obj->fi);
+ f2lud_set_pattern_line_style(job, drw, obj);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_fill(job, drw, obj);
+ f2lud_set_color_1(job, drw, obj->pc, 20);
+ f2lud_gsave(job, drw, obj);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_clip(job, drw, obj);
+ f2lud_pattern(job, drw, obj, ec);
+ f2lud_grestore(job, drw, obj);
+ f2lud_set_line_width(job, drw, obj);
+ f2lud_set_line_dash(job, drw, obj);
+ f2lud_set_line_end(job, drw, obj, obj->cs);
+ f2lud_set_line_join(job, drw, obj, obj->js);
+ f2lud_newpath(job, drw, obj);
+ f2lud_create_path(job, drw, obj, primary, ec);
+ f2lud_closepath(job, drw, obj);
+ f2lud_stroke(job, drw, obj);
+ } break;
+ } $? "- f2lud_path_fill_pattern_stroke"
+}
+
+
+
+/** Process path object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param primary Flag: primary (1=primary object, 0=arrowhead).
+*/
+static
+void
+f2lud_path_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int primary
+)
+{
+ int drawop; /* Operations to perform. */
+ int ec = 0; /* Error code variable. */
+ $? "+ f2lud_path_object"
+ drawop = dk3fig_tool_get_operation(drw, obj);
+ if(obj->cl) {
+ switch(drawop) {
+ case DK3_FIG_OP_STROKE: {
+ f2lud_path_stroke(job, drw, obj, primary, &ec);
+ } break;
+ case DK3_FIG_OP_FILL: {
+ f2lud_path_fill(job, drw, obj, primary, &ec);
+ } break;
+ case (DK3_FIG_OP_FILL | DK3_FIG_OP_STROKE): {
+ f2lud_path_fill_stroke(job, drw, obj, primary, &ec);
+ } break;
+ case DK3_FIG_OP_PATTERN: {
+ f2lud_path_pattern(job, drw, obj, primary, &ec);
+ } break;
+ case (DK3_FIG_OP_PATTERN | DK3_FIG_OP_STROKE): {
+ f2lud_path_pattern_stroke(job, drw, obj, primary, &ec);
+ } break;
+ case (DK3_FIG_OP_PATTERN | DK3_FIG_OP_FILL): {
+ f2lud_path_fill_pattern(job, drw, obj, primary, &ec);
+ } break;
+ case (DK3_FIG_OP_PATTERN | DK3_FIG_OP_FILL | DK3_FIG_OP_STROKE): {
+ f2lud_path_fill_pattern_stroke(job, drw, obj, primary, &ec);
+ } break;
+ }
+ } else {
+ if(DK3_FIG_OP_STROKE & drawop) {
+ f2lud_path_stroke(job, drw, obj, primary, &ec);
+ }
+ }
+ if(ec) {
+ /* ERROR: Math error in object! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 38);
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_MATH); $? ". exitcode"
+ } $? "- f2lud_path_object"
+}
+
+
+
+/** Process one object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param primary Flag: primary (1=primary object, 0=arrowhead).
+*/
+static
+void
+f2lud_process_one(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int primary
+)
+{
+ char debbuf[256]; /* Buffer for debug messages. */
+ $? "+ f2lud_process_one"
+ if(job->debug) {
+ sprintf(debbuf, f2lud_c8_kw[6], obj->ot, obj->st);
+ f2lud_debug(job, debbuf);
+ }
+ switch(obj->ot) {
+ case DK3_FIG_OBJ_TEXT: {
+ f2lud_text_object(job, drw, obj);
+ } break;
+ case DK3_FIG_OBJ_ELLIPSE:
+ case DK3_FIG_OBJ_SPLINE:
+ case DK3_FIG_OBJ_ARC:
+ case DK3_FIG_OBJ_PSEUDO_HALF_CIRCLE:
+ case DK3_FIG_OBJ_PSEUDO_FAST_SPLINE:
+ {
+ f2lud_path_object(job, drw, obj, primary);
+ } break;
+ case DK3_FIG_OBJ_POLYLINE: {
+ switch(obj->st) {
+ case 5: {
+ f2lud_image_object(job, drw, obj);
+ } break;
+ default: {
+ f2lud_path_object(job, drw, obj, primary);
+ } break;
+ }
+ } break;
+ }
+ if(job->debug) {
+ f2lud_debug(job, f2lud_c8_kw[7]);
+ } $? "- f2lud_process_one"
+}
+
+
+
+int
+f2lud_is_interpolated_spline(dk3_fig_obj_t *obj)
+{
+ dk3_fig_spline_point_t *po; /* Points to test */
+ size_t np; /* Number of points */
+ size_t i; /* Traverse all points */
+ int back = 1;
+ $? "+ f2lud_is_interpolated_spline closed=%u", (unsigned)(obj->cl)
+ po = (obj->dt).spl.po;
+ np = (obj->dt).spl.np;
+ for (i = 0; ((i < np) && (1 == back)); i++) {
+ $? ". point %u: x=%lg y=%lg s=%lg", (unsigned)i, po->x, po->y, po->s
+ if (fabs(po->s) > 1.0e-6) {
+ if (fabs(1.0 + po->s) > 1.0e-6) {
+ back = 0;
+ }
+ }
+ po++;
+ } $? "- f2lud_is_interpolated_spline %d", back
+ return back;
+}
+
+
+
+/** Process one arrowhead object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+static
+void
+f2lud_process_ah_one(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+)
+{
+ switch (obj->ot) {
+ case DK3_FIG_OBJ_SPLINE: {
+ if ((!(job->xsah)) && (f2lud_is_interpolated_spline(obj))) {
+ obj->ot = DK3_FIG_OBJ_PSEUDO_FAST_SPLINE;
+ f2lud_process_one(job, drw, obj, 0);
+ obj->ot = DK3_FIG_OBJ_SPLINE;
+ } else {
+ f2lud_process_one(job, drw, obj, 0);
+ }
+ } break;
+ default: {
+ f2lud_process_one(job, drw, obj, 0);
+ } break;
+ }
+}
+
+
+
+/** Process object and arrowheads.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param objno Number of current object.
+*/
+static
+void
+f2lud_process_object(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ unsigned long objno
+)
+{
+ char debbuf[256]; /* Buffer for debug messages. */
+ $? "+ f2lud_process_object"
+ /*
+ Process object itself.
+ */
+ $? ". process main object"
+ if(job->debug) {
+ sprintf(debbuf, f2lud_c8_kw[0], objno, obj->li, obj->ot, obj->st, obj->la);
+ f2lud_debug(job, debbuf);
+ }
+ f2lud_process_one(job, drw, obj, 1);
+ $? ". main object finished"
+ /*
+ For primary objects process the arrowheads.
+ */
+ if(obj->af) {
+ $? ". process forward arrowhead"
+ if(job->debug) { $? ". create debug messages"
+ sprintf(
+ debbuf, f2lud_c8_kw[2],
+ (obj->af)->as,
+ (obj->af)->af,
+ (obj->af)->he,
+ (obj->af)->wi
+ );
+ f2lud_debug(job, debbuf);
+ }
+ if((obj->af)->o1) { $? ". use arrowhead object 1"
+#if VERSION_BEFORE_20140329
+ f2lud_process_one(job,drw,(dk3_fig_obj_t *)((obj->af)->o1),0);
+#else
+ f2lud_process_ah_one(job, drw, (dk3_fig_obj_t *)((obj->af)->o1));
+#endif
+ }
+ if((obj->af)->o2) { $? ". use arrowhead object 2"
+#if VERSION_BEFORE_20140329
+ f2lud_process_one(job,drw,(dk3_fig_obj_t *)((obj->af)->o2),0);
+#else
+ f2lud_process_ah_one(job, drw, (dk3_fig_obj_t *)((obj->af)->o2));
+#endif
+ }
+ if(job->debug) { $? ". create final debug message"
+ f2lud_debug(job, f2lud_c8_kw[3]);
+ }
+ $? ". forward arrowhead finished"
+ }
+ if(obj->ab) {
+ $? ". process backward arrowhead"
+ if(job->debug) { $? ". create debug messages"
+ sprintf(
+ debbuf, f2lud_c8_kw[4],
+ (obj->ab)->as,
+ (obj->ab)->af,
+ (obj->ab)->he,
+ (obj->ab)->wi
+ );
+ f2lud_debug(job, debbuf);
+ }
+ if((obj->ab)->o1) { $? ". use arrowhead object 1"
+#if VERSION_BEFORE_20140329
+ f2lud_process_one(job,drw,(dk3_fig_obj_t *)((obj->ab)->o1),0);
+#else
+ f2lud_process_ah_one(job, drw, (dk3_fig_obj_t *)((obj->ab)->o1));
+#endif
+ }
+ if((obj->ab)->o2) { $? ". use arrowhead object 2"
+#if VERSION_BEFORE_20140329
+ f2lud_process_one(job,drw,(dk3_fig_obj_t *)((obj->ab)->o2),0);
+#else
+ f2lud_process_ah_one(job, drw, (dk3_fig_obj_t *)((obj->ab)->o2));
+#endif
+ }
+ if(job->debug) { $? ". create final debug message"
+ f2lud_debug(job, f2lud_c8_kw[5]);
+ }
+ $? ". backward arrowhead finished"
+ }
+ if(job->debug) {
+ sprintf(debbuf, f2lud_c8_kw[1], objno);
+ f2lud_debug(job, debbuf);
+ }
+ $? "- f2lud_process_object"
+}
+
+
+
+void
+f2lud_output(f2l_job_t *job)
+{
+ dk3_fig_obj_t *obj; /* Current object to process. */
+ dk3_fig_drawing_t *drw; /* Drawing to process. */
+ unsigned long objno; /* Current object number. */
+ $? "+ f2lud_output"
+ drw = job->drw;
+ objno = 0UL;
+ if(f2lud_driver_initialize(job, drw)) {
+ if(f2lud_open_output_files(job)) {
+ if(f2lud_start_processing(job, drw)) {
+ dk3sto_it_reset(drw->iobj);
+ while(NULL != (obj = (dk3_fig_obj_t *)dk3sto_it_next(drw->iobj))) {
+ if(!dk3fig_tool_is_bgrect(obj, objno)) {
+ f2lud_process_object(job, drw, obj, objno);
+ }
+ objno++;
+ }
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN); $? ". exitcode"
+ }
+ f2lud_end_processing(job, drw);
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN); $? ". exitcode"
+ }
+ f2lud_close_output_files(job);
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN); $? ". exitcode"
+ }
+ f2lud_driver_end(job, drw); $? "- f2lud_output"
+}
+
diff --git a/support/dktools/f2lud.h b/support/dktools/f2lud.h
new file mode 100644
index 0000000000..831bb7eb18
--- /dev/null
+++ b/support/dktools/f2lud.h
@@ -0,0 +1,238 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: f2lud.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file f2lud.h Header file for the f2lud module.
+*/
+
+#ifndef F2LUD_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define F2LUD_H_INCLUDED 1
+
+
+#line 10 "f2lud.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Produce output.
+ @param job Job structure.
+*/
+void
+f2lud_output(f2l_job_t *job);
+
+/** Issue "newpath" command.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lud_newpath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Issue "moveto" command.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x New point x in output space.
+ @param y New point y in output space.
+*/
+void
+f2lud_moveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Issue "lineto" command.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x New point x in output space.
+ @param y New point y in output space.
+*/
+void
+f2lud_lineto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y
+);
+
+/** Issue "curveto" command.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param xcs Control point at start x in output space.
+ @param ycs Control point at start y in output space.
+ @param xce Control point at end x in output space.
+ @param yce Control point at end y in output space.
+ @param xe End point x in output space.
+ @param ye End point y in output space.
+
+*/
+void
+f2lud_curveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double xcs,
+ double ycs,
+ double xce,
+ double yce,
+ double xe,
+ double ye
+);
+
+/** Issue "moveto" command.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x New point x in Fig space.
+ @param y New point y in Fig space.
+ @param ec Pointer to error code variable, may be NULL.
+*/
+void
+f2lud_fig_moveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y,
+ int *ec
+);
+
+/** Issue "lineto" command.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param x New point x in Fig space.
+ @param y New point y in Fig space.
+ @param ec Pointer to error code variable, may be NULL.
+*/
+void
+f2lud_fig_lineto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double x,
+ double y,
+ int *ec
+);
+
+/** Issue "curveto" command.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+ @param xcs Control point at start x in Fig space.
+ @param ycs Control point at start y in Fig space.
+ @param xce Control point at end x in Fig space.
+ @param yce Control point at end y in Fig space.
+ @param xe End point x in Fig space.
+ @param ye End point y in Fig space.
+ @param ec Pointer to error code variable, may be NULL.
+*/
+void
+f2lud_fig_curveto(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ double xcs,
+ double ycs,
+ double xce,
+ double yce,
+ double xe,
+ double ye,
+ int *ec
+);
+
+/** Issue "closepath" command.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lud_closepath(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Issue "stroke" command.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lud_stroke(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Issue "fill" command.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Current object to process.
+*/
+void
+f2lud_fill(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj
+);
+
+/** Check whether a spline object is an interpolated spline
+ (only s=-1 and/or s=0 points).
+ @param obj Object to check.
+ @return 1 for pure interpolated spline, 0 otherwise.
+*/
+int
+f2lud_is_interpolated_spline(dk3_fig_obj_t *obj);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/f2ludpat.c b/support/dktools/f2ludpat.c
new file mode 100644
index 0000000000..dd40cecb6f
--- /dev/null
+++ b/support/dktools/f2ludpat.c
@@ -0,0 +1,1598 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: f2ludpat.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file f2ludpat.c The f2ludpat module.
+*/
+
+
+#line 36 "f2ludpat.ctr"
+
+#include "dk3all.h"
+#include "dk3bezcu.h"
+#include "fig2lat.h"
+#include "f2lud.h"
+#include "f2lsvg.h"
+#include "f2lpgf.h"
+#include "f2lpdf.h"
+#include "f2leps.h"
+#include "dk3figto.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4vers.h"
+#include "f2ludpat.h"
+
+
+
+
+
+#line 55 "f2ludpat.ctr"
+
+
+
+/** One falling line.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param y0 Y value at x=0.
+ @param m Tangens alpha.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_one_falling_line(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ double y0,
+ double m,
+ int *ec
+)
+{
+ double xs; /* Start point x. */
+ double ys; /* Start point y. */
+ double xe; /* End point x. */
+ double ye; /* End point y. */
+ int hs = 0; /* Flag: Have start point. */
+ int he = 0; /* Flag: Have end point. */
+
+ ys = dk3ma_d_sub_ok(y0, dk3ma_d_mul_ok(m, outbb->xmin, ec), ec);
+ if(ys > outbb->ymin) {
+ if(ys <= outbb->ymax) {
+ xs = outbb->xmin; hs = 1;
+ } else {
+ ys = outbb->ymax;
+ xs = dk3ma_d_div_ok(dk3ma_d_sub_ok(y0, outbb->ymax, ec), m, ec);
+ if(xs < outbb->xmax) {
+ hs = 1;
+ }
+ }
+ ye = dk3ma_d_sub_ok(y0, dk3ma_d_mul_ok(m, outbb->xmax, ec), ec);
+ xe = xs;
+ if(ye < outbb->ymax) {
+ if(ye < outbb->ymin) {
+ ye = outbb->ymin;
+ xe = dk3ma_d_div_ok(dk3ma_d_sub_ok(y0, outbb->ymin, ec), m, ec);
+ if(xe > outbb->xmin) {
+ he = 1;
+ }
+ } else {
+ xe = outbb->xmax; he = 1;
+ }
+ }
+ if((hs) && (he)) {
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, xs, ys);
+ f2lud_lineto(job, drw, obj, xe, ye);
+ f2lud_stroke(job, drw, obj);
+ }
+ }
+}
+
+
+
+/** One rising line.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param y0 Y value at x=0.
+ @param m Tangens alpha.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_one_rising_line(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ double y0,
+ double m,
+ int *ec
+)
+{
+ double xs; /* Start point x. */
+ double ys; /* Start point y. */
+ double xe; /* End point x. */
+ double ye; /* End point y. */
+ int hs = 0; /* Flag: Have start point. */
+ int he = 0; /* Flag: Have end point. */
+
+ ye = dk3ma_d_add_ok(
+ y0,
+ dk3ma_d_mul_ok(m, outbb->xmax, ec),
+ ec
+ );
+ ys = ye;
+ if(ye > outbb->ymin) {
+ if(ye <= outbb->ymax) {
+ xe = outbb->xmax; he = 1;
+ } else {
+ ye = outbb->ymax;
+ xe = dk3ma_d_div_ok(dk3ma_d_sub_ok(outbb->ymax, y0, ec), m, ec);
+ if((xe > outbb->xmin) && (xe < outbb->xmax)) {
+ he = 1;
+ }
+ }
+ xs = xe;
+ if(he) {
+ ys = dk3ma_d_add_ok(
+ y0,
+ dk3ma_d_mul_ok(m, outbb->xmin, ec),
+ ec
+ );
+ if(ys < outbb->ymax) {
+ if(ys >= outbb->ymin) {
+ xs = outbb->xmin; hs = 1;
+ } else {
+ ys = outbb->ymin;
+ xs = dk3ma_d_div_ok(dk3ma_d_sub_ok(outbb->ymin, y0, ec), m, ec);
+ if((xs > outbb->xmin) && (xs < outbb->xmax)) {
+ hs = 1;
+ }
+ }
+ }
+ }
+ if((hs) && (he)) {
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, xs, ys);
+ f2lud_lineto(job, drw, obj, xe, ye);
+ f2lud_stroke(job, drw, obj);
+ }
+ }
+}
+
+
+
+/** Falling lines.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param dy Y step.
+ @param m Tangens alpha.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_falling_lines(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ double dy,
+ double m,
+ int *ec
+)
+{
+ double ys; /* Start y. */
+ double ye; /* End y. */
+ double y; /* Current y. */
+
+ ys = dk3ma_d_add_ok(
+ outbb->ymin,
+ dk3ma_d_mul_ok(m, outbb->xmin, ec),
+ ec
+ );
+ ye = dk3ma_d_add_ok(
+ outbb->ymax,
+ dk3ma_d_mul_ok(m, outbb->xmax, ec),
+ ec
+ );
+ ys = dk3ma_d_mul_ok(
+ dy,
+ floor(dk3ma_d_div_ok(ys, dy, ec)),
+ ec
+ );
+ y = ys;
+ while(y < ye) {
+ f2ludpat_one_falling_line(job, drw, obj, outbb, y, m, ec);
+ y = dk3ma_d_add_ok(y, dy, ec);
+ }
+}
+
+
+
+/** Rising lines.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param dy Y step.
+ @param m Tangens alpha.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_rising_lines(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ double dy,
+ double m,
+ int *ec
+)
+{
+ double ys; /* Start y. */
+ double ye; /* End y. */
+ double y; /* Current y. */
+
+ ys = dk3ma_d_sub_ok(
+ outbb->ymin,
+ dk3ma_d_mul_ok(m, outbb->xmax, ec),
+ ec
+ );
+ ye = dk3ma_d_sub_ok(
+ outbb->ymax,
+ dk3ma_d_mul_ok(m, outbb->xmin, ec),
+ ec
+ );
+ ys = dk3ma_d_mul_ok(
+ dy,
+ floor(dk3ma_d_div_ok(ys, dy, ec)),
+ ec
+ );
+ y = ys;
+ while(y < ye) {
+ f2ludpat_one_rising_line(job, drw, obj, outbb, y, m, ec);
+ y = dk3ma_d_add_ok(y, dy, ec);
+ }
+}
+
+
+
+/** 30 degree falling lines.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_30_falling_lines(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ f2ludpat_falling_lines(
+ job, drw, obj, outbb,
+ dk3ma_d_div_ok(3.6, cos(M_PI / 6.0), ec),
+ (1.0 / sqrt(3.0)),
+ ec
+ );
+}
+
+
+
+/** 30 degree rising lines.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_30_rising_lines(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ f2ludpat_rising_lines(
+ job, drw, obj, outbb,
+ dk3ma_d_div_ok(3.6, cos(M_PI / 6.0), ec),
+ (1.0 / sqrt(3.0)),
+ ec
+ );
+}
+
+
+
+/** 45 degree falling lines.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_45_falling_lines(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ f2ludpat_falling_lines(job, drw, obj, outbb, (7.2 * sqrt(2.0)), 1.0, ec);
+}
+
+
+
+/** 45 degree rising lines.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_45_rising_lines(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ f2ludpat_rising_lines(job, drw, obj, outbb, (7.2 * sqrt(2.0)), 1.0, ec);
+}
+
+
+
+/** Horizontal bricks.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_horizontal_bricks(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ double x; /* Current x. */
+ double y; /* Current y. */
+ double ys; /* Start y. */
+ double xs; /* Start x. */
+ double dy; /* Y delta. */
+ double dx; /* X delta. */
+ int lineno; /* Flag: Odd (1) or even (0) line. */
+
+ dy = 7.2;
+ dx = 14.4;
+ ys = outbb->ymin;
+ xs = outbb->xmin;
+ lineno = 0;
+ ys = dk3ma_d_mul_ok(
+ (2.0 * dy),
+ floor(dk3ma_d_div_ok(ys, (2.0 * dy), ec)),
+ ec
+ );
+ y = ys;
+ while(y < outbb->ymax) {
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, outbb->xmin, y);
+ f2lud_lineto(job, drw, obj, outbb->xmax, y);
+ f2lud_stroke(job, drw, obj);
+ x = dk3ma_d_add_ok(xs, (((lineno) ? 0.75 : 0.25) * dx), ec);
+ while(x < outbb->xmax) {
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, x, y);
+ f2lud_lineto(job, drw, obj, x, dk3ma_d_add_ok(y, dy, ec));
+ f2lud_stroke(job, drw, obj);
+ x = dk3ma_d_add_ok(x, dx, ec);
+ }
+ y = dk3ma_d_add_ok(y, dy, ec);
+ lineno++;
+ if(lineno > 1) { lineno = 0; }
+ }
+}
+
+
+
+/** Vertical bricks.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_vertical_bricks(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ double x; /* Current x value. */
+ double y; /* Current y value. */
+ double xs; /* Start x. */
+ double ys; /* Start y. */
+ double dx; /* Delta x. */
+ double dy; /* Delta y. */
+ int lineno; /* Flag: Odd (1) or even (0) line. */
+
+ lineno = 0;
+ dy = 14.4;
+ dx = 7.2;
+ xs = outbb->xmin;
+ xs = dk3ma_d_mul_ok(
+ (2.0 * dx),
+ floor(dk3ma_d_div_ok(xs, (2.0 * dx), ec)),
+ ec
+ );
+ ys = outbb->ymin;
+ ys = dk3ma_d_mul_ok(
+ dy,
+ floor(dk3ma_d_div_ok(ys, dy, ec)),
+ ec
+ );
+ x = xs;
+ while(x < outbb->xmax) {
+ x = dk3ma_d_add_ok(x, dx, ec);
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, x, outbb->ymin);
+ f2lud_lineto(job, drw, obj, x, outbb->ymax);
+ f2lud_stroke(job, drw, obj);
+ y = dk3ma_d_add_ok(ys, (((lineno) ? 0.75 : 0.25) * dy), ec);
+ while(y < outbb->ymax) {
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, x, y);
+ f2lud_lineto(job, drw, obj, dk3ma_d_add_ok(x, dx, ec), y);
+ f2lud_stroke(job, drw, obj);
+ y = dk3ma_d_add_ok(y, dy, ec);
+ }
+ lineno++;
+ if(lineno > 1) { lineno = 0; }
+ }
+}
+
+
+
+/** Horizontal lines.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_horizontal_lines(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ double y; /* Current y. */
+ double ys; /* Start y. */
+ double dy; /* Delta y per pass. */
+
+ dy = 3.6;
+ ys = outbb->ymin;
+ ys = dk3ma_d_mul_ok(
+ dy,
+ floor(dk3ma_d_div_ok(ys, dy, ec)),
+ ec
+ );
+ y = ys;
+ while(y < outbb->ymax) {
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, outbb->xmin, y);
+ f2lud_lineto(job, drw, obj, outbb->xmax, y);
+ f2lud_stroke(job, drw, obj);
+ y = dk3ma_d_add_ok(y, dy, ec);
+ }
+}
+
+
+
+/** Vertical lines.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_vertical_lines(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ double x; /* Current x. */
+ double xs; /* Start x. */
+ double dx; /* Delta x. */
+
+ dx = 3.6;
+ xs = outbb->xmin;
+ xs = dk3ma_d_mul_ok(
+ dx,
+ floor(dk3ma_d_div_ok(xs, dx, ec)),
+ ec
+ );
+ x = xs;
+ while(x < outbb->xmax) {
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, x, outbb->ymin);
+ f2lud_lineto(job, drw, obj, x, outbb->ymax);
+ f2lud_stroke(job, drw, obj);
+ x = dk3ma_d_add_ok(x, dx, ec);
+ }
+}
+
+
+
+/** Horizontal tire treads.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_horizontal_tire_treads(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ double x; /* Current x. */
+ double y; /* Current y. */
+ double dx; /* Delta x per step. */
+ double dy; /* Delta y per pass. */
+ double xs; /* Start x. */
+ double ys; /* Start y. */
+
+ dy = 7.2;
+ dx = 3.6;
+ xs = outbb->xmin; ys = outbb->ymin;
+ xs = dk3ma_d_mul_ok(
+ dy,
+ floor(dk3ma_d_div_ok(xs, dy, ec)),
+ ec
+ );
+ ys = dk3ma_d_mul_ok(
+ dy,
+ floor(dk3ma_d_div_ok(ys, dy, ec)),
+ ec
+ );
+ y = ys;
+ while(y < outbb->ymax) {
+ x = xs;
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, x, y);
+ f2lud_lineto(
+ job, drw, obj,
+ dk3ma_d_add_ok(x, dx, ec), dk3ma_d_add_ok(y, dx, ec)
+ );
+ f2lud_lineto(
+ job, drw, obj,
+ dk3ma_d_add_ok(x, dy, ec), y
+ );
+ x = dk3ma_d_add_ok(x, dy, ec);
+ while(x < outbb->xmax) {
+ f2lud_lineto(
+ job, drw, obj,
+ dk3ma_d_add_ok(x, dx, ec), dk3ma_d_add_ok(y, dx, ec)
+ );
+ f2lud_lineto(
+ job, drw, obj,
+ dk3ma_d_add_ok(x, dy, ec), y
+ );
+ x = dk3ma_d_add_ok(x, dy, ec);
+ }
+ f2lud_stroke(job, drw, obj);
+ y = dk3ma_d_add_ok(y, dy, ec);
+ }
+}
+
+
+
+/** Vertical tire treads.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_vertical_tire_treads(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ double x; /* Current x. */
+ double y; /* Current y. */
+ double dx; /* Delta x per pass. */
+ double dy; /* Delta y per step. */
+ double xs; /* Start x. */
+ double ys; /* Start y. */
+
+ dx = 7.2;
+ dy = 3.6;
+ xs = outbb->xmin; ys = outbb->ymin;
+ xs = dk3ma_d_mul_ok(
+ dy,
+ floor(dk3ma_d_div_ok(xs, dy, ec)),
+ ec
+ );
+ ys = dk3ma_d_mul_ok(
+ dy,
+ floor(dk3ma_d_div_ok(ys, dy, ec)),
+ ec
+ );
+ x = xs;
+ while(x < outbb->xmax) {
+ y = ys;
+
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, x, y);
+ f2lud_lineto(job, drw, obj,
+ dk3ma_d_add_ok(x, dy, ec), dk3ma_d_add_ok(y, dy, ec)
+ );
+ f2lud_lineto(job, drw, obj,
+ x, dk3ma_d_add_ok(y, dx, ec)
+ );
+ y = dk3ma_d_add_ok(y, dx, ec);
+ while(y < outbb->ymax) {
+ f2lud_lineto(job, drw, obj,
+ dk3ma_d_add_ok(x, dy, ec), dk3ma_d_add_ok(y, dy, ec)
+ );
+ f2lud_lineto(job, drw, obj,
+ x, dk3ma_d_add_ok(y, dx, ec)
+ );
+ y = dk3ma_d_add_ok(y, dx, ec);
+ }
+ f2lud_stroke(job, drw, obj);
+ x = dk3ma_d_add_ok(x, dx, ec);
+ }
+}
+
+
+
+
+/** Circles.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_circles(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ dk3_fig_poly_point_t p[12]; /* Points for circle around origin. */
+ dk3_fig_poly_point_t q[12]; /* Points shifted to the specified center. */
+ double x; /* Current x. */
+ double y; /* Current y. */
+ double dx; /* Delta x. */
+ double dy; /* Delta y. */
+ double xs; /* Start x. */
+ double ys; /* Start y. */
+ double r; /* Circle radius. */
+ size_t i; /* Index to traverse p and q. */
+
+ r = 7.2;
+ dx = dy = 2.0 * r;
+ xs = outbb->xmin; ys = outbb->ymin;
+ xs = dk3ma_d_mul_ok(
+ dx,
+ floor(dk3ma_d_div_ok(xs, dx, ec)),
+ ec
+ );
+ ys = dk3ma_d_mul_ok(
+ dy,
+ floor(dk3ma_d_div_ok(ys, dy, ec)),
+ ec
+ );
+ p[ 0].x = dx;
+ p[ 0].y = r;
+ p[ 1].x = dx;
+ p[ 1].y = (1.0 + FIG2LAT_CIRCLE_QUADRANT_BEZIER) * r;
+ p[ 2].x = (1.0 + FIG2LAT_CIRCLE_QUADRANT_BEZIER) * r;
+ p[ 2].y = dx;
+ p[ 3].x = r;
+ p[ 3].y = dx;
+ p[ 4].x = (1.0 - FIG2LAT_CIRCLE_QUADRANT_BEZIER) * r;
+ p[ 4].y = dx;
+ p[ 5].x = 0.0;
+ p[ 5].y = (1.0 + FIG2LAT_CIRCLE_QUADRANT_BEZIER) * r;
+ p[ 6].x = 0.0;
+ p[ 6].y = r;
+ p[ 7].x = 0.0;
+ p[ 7].y = (1.0 - FIG2LAT_CIRCLE_QUADRANT_BEZIER) * r;
+ p[ 8].x = (1.0 - FIG2LAT_CIRCLE_QUADRANT_BEZIER) * r;
+ p[ 8].y = 0.0;
+ p[ 9].x = r;
+ p[ 9].y = 0.0;
+ p[10].x = (1.0 + FIG2LAT_CIRCLE_QUADRANT_BEZIER) * r;
+ p[10].y = 0.0;
+ p[11].x = dx;
+ p[11].y = (1.0 - FIG2LAT_CIRCLE_QUADRANT_BEZIER) * r;
+ y = ys;
+ while(y < outbb->ymax) {
+ x = xs;
+ while(x < outbb->xmax) {
+ dk3mem_cpy((void *)q, (void *)p, sizeof(p));
+ for(i = 0; i < 12; i++) {
+ dk3fig_tool_shift_point(&(q[i]), x, y, ec);
+ }
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, q[0].x, q[0].y);
+ f2lud_curveto(
+ job, drw, obj, q[1].x, q[1].y, q[2].x, q[2].y, q[3].x, q[3].y
+ );
+ f2lud_curveto(
+ job, drw, obj, q[4].x, q[4].y, q[5].x, q[5].y, q[6].x, q[6].y
+ );
+ f2lud_curveto(
+ job, drw, obj, q[7].x, q[7].y, q[8].x, q[8].y, q[9].x, q[9].y
+ );
+ f2lud_curveto(
+ job, drw, obj, q[10].x, q[10].y, q[11].x, q[11].y, q[0].x, q[0].y
+ );
+ f2lud_closepath(job, drw, obj);
+ f2lud_stroke(job, drw, obj);
+ x = dk3ma_d_add_ok(x, dx, ec);
+ }
+ y = dk3ma_d_add_ok(y, dy, ec);
+ }
+}
+
+
+
+/** Hexagons.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_hexagons(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ dk3_fig_poly_point_t p[6]; /* Hexagon near origin. */
+ dk3_fig_poly_point_t q[6]; /* Hexagon shifted to current x, y. */
+ double r; /* Radius. */
+ double y1; /* Y position of help line. */
+ double x1; /* X position of help line. */
+ double dy; /* Delta y. */
+ double dx; /* Delta x. */
+ double xs; /* Start x. */
+ double ys; /* Start y. */
+ double x; /* Current x. */
+ double y; /* Current y. */
+ size_t i; /* Index to traverse p and q. */
+
+ r = 16.2 / (2.0 * sin(M_PI / 3.0));
+ y1 = r * sin(M_PI / 3.0);
+ x1 = r * (1.0 - cos(M_PI / 3.0));
+ dx = 2.0 * (r + x1);
+ dy = 2.0 * y1;
+ xs = outbb->xmin;
+ ys = outbb->ymin;
+ xs = dk3ma_d_mul_ok(
+ dx,
+ floor(dk3ma_d_div_ok(xs, dx, ec)),
+ ec
+ );
+ ys = dk3ma_d_mul_ok(
+ dy,
+ floor(dk3ma_d_div_ok(ys, dy, ec)),
+ ec
+ );
+ p[0].x = 0.0;
+ p[0].y = y1;
+ p[1].x = x1;
+ p[1].y = 0.0;
+ p[2].x = x1 + r;
+ p[2].y = 0.0;
+ p[3].x = 2.0 * r;
+ p[3].y = y1;
+ p[4].x = p[2].x;
+ p[4].y = 2.0 * y1;
+ p[5].x = p[1].x;
+ p[5].y = p[4].y;
+ y = ys;
+ while(y < outbb->ymax) {
+ x = xs;
+ while(x < outbb->xmax) {
+ dk3mem_cpy((void *)q, (void *)p, sizeof(p));
+ for(i = 0; i < 6; i++) {
+ dk3fig_tool_shift_point(&(q[i]), x, y, ec);
+ }
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, q[0].x, q[0].y);
+ f2lud_lineto(job, drw, obj, q[1].x, q[1].y);
+ f2lud_lineto(job, drw, obj, q[2].x, q[2].y);
+ f2lud_lineto(job, drw, obj, q[3].x, q[3].y);
+ f2lud_lineto(job, drw, obj, q[4].x, q[4].y);
+ f2lud_lineto(job, drw, obj, q[5].x, q[5].y);
+ f2lud_lineto(job, drw, obj, q[0].x, q[0].y);
+ f2lud_closepath(job, drw, obj);
+ f2lud_stroke(job, drw, obj);
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, q[3].x, q[3].y);
+ f2lud_lineto(job, drw, obj, dk3ma_d_add_ok(q[3].x, r, ec), q[3].y);
+ f2lud_stroke(job, drw, obj);
+ x = dk3ma_d_add_ok(x, dx, ec);
+ }
+ y = dk3ma_d_add_ok(y, dy, ec);
+ }
+}
+
+
+
+/** Octagons.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_octagons(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ dk3_fig_poly_point_t p[8]; /* Octagon near origin. */
+ dk3_fig_poly_point_t q[8]; /* Octagon shifted to final position. */
+ double dx; /* Delta x. */
+ double dy; /* Delta y. */
+ double xs; /* Start x. */
+ double ys; /* Start y. */
+ double x; /* Current x. */
+ double y; /* Current y. */
+ double l; /* Factor for corner length. */
+ double x1; /* X position of help line 1. */
+ double x2; /* X position of help line 2. */
+ size_t i; /* Index to traverse p and q. */
+
+ dx = dy = 4.0 * 3.6;
+ xs = outbb->xmin; ys = outbb->ymin;
+ xs = dk3ma_d_mul_ok(
+ dx,
+ floor(dk3ma_d_div_ok(xs, dx, ec)),
+ ec
+ );
+ ys = dk3ma_d_mul_ok(
+ dy,
+ floor(dk3ma_d_div_ok(ys, dy, ec)),
+ ec
+ );
+
+#line 954 "f2ludpat.ctr"
+ l = dx / (1.0 + sqrt(2.0));
+
+#line 955 "f2ludpat.ctr"
+ x1 = (dx - l) / 2.0;
+
+#line 956 "f2ludpat.ctr"
+ x2 = x1 + l;
+
+#line 957 "f2ludpat.ctr"
+ p[0].x = x1;
+
+#line 958 "f2ludpat.ctr"
+ p[0].y = 0.0;
+
+#line 959 "f2ludpat.ctr"
+ p[1].x = x2;
+
+#line 960 "f2ludpat.ctr"
+ p[1].y = 0.0;
+
+#line 961 "f2ludpat.ctr"
+ p[2].x = dx;
+
+#line 962 "f2ludpat.ctr"
+ p[2].y = x1;
+
+#line 963 "f2ludpat.ctr"
+ p[3].x = dx;
+
+#line 964 "f2ludpat.ctr"
+ p[3].y = x2;
+
+#line 965 "f2ludpat.ctr"
+ p[4].x = x2;
+
+#line 966 "f2ludpat.ctr"
+ p[4].y = dy;
+
+#line 967 "f2ludpat.ctr"
+ p[5].x = x1;
+
+#line 968 "f2ludpat.ctr"
+ p[5].y = dy;
+
+#line 969 "f2ludpat.ctr"
+ p[6].x = 0.0;
+
+#line 970 "f2ludpat.ctr"
+ p[6].y = x2;
+
+#line 971 "f2ludpat.ctr"
+ p[7].x = 0.0;
+
+#line 972 "f2ludpat.ctr"
+ p[7].y = x1;
+
+#line 973 "f2ludpat.ctr"
+ y = ys;
+ while(y < outbb->ymax) {
+ x = xs;
+ while(x < outbb->xmax) {
+ dk3mem_cpy((void *)q, (void *)p, sizeof(p));
+ for(i = 0; i < 8; i++) {
+ dk3fig_tool_shift_point(&(q[i]), x, y, ec);
+ }
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, q[0].x, q[0].y);
+ f2lud_lineto(job, drw, obj, q[1].x, q[1].y);
+ f2lud_lineto(job, drw, obj, q[2].x, q[2].y);
+ f2lud_lineto(job, drw, obj, q[3].x, q[3].y);
+ f2lud_lineto(job, drw, obj, q[4].x, q[4].y);
+ f2lud_lineto(job, drw, obj, q[5].x, q[5].y);
+ f2lud_lineto(job, drw, obj, q[6].x, q[6].y);
+ f2lud_lineto(job, drw, obj, q[7].x, q[7].y);
+ f2lud_lineto(job, drw, obj, q[0].x, q[0].y);
+ f2lud_closepath(job, drw, obj);
+ f2lud_stroke(job, drw, obj);
+ x = dk3ma_d_add_ok(x, dx, ec);
+ }
+ y = dk3ma_d_add_ok(y, dy, ec);
+ }
+}
+
+
+
+/** Fish scale.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+ @param points Curve control points near origin.
+ @param dx X delta.
+ @param dy Y delta.
+*/
+static
+void
+f2ludpat_fish_scale(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec,
+ dk3_fig_poly_point_t *points,
+ double dx,
+ double dy
+)
+{
+ dk3_fig_poly_point_t q[7]; /* Points shifted to final position. */
+ double xs; /* Start x. */
+ double ys; /* Start y. */
+ double y1; /* Y position of help line. */
+ double x; /* Current x. */
+ double y; /* Current y. */
+ size_t i; /* Index to traverse npoints and q. */
+
+ xs = outbb->xmin; ys = outbb->ymin;
+ xs = dk3ma_d_mul_ok(
+ dx,
+ floor(dk3ma_d_div_ok(xs, dx, ec)),
+ ec
+ );
+ ys = dk3ma_d_mul_ok(
+ dy,
+ floor(dk3ma_d_div_ok(ys, dy, ec)),
+ ec
+ );
+ y = ys;
+ while(y < outbb->ymax) {
+ x = xs;
+ while(x < outbb->xmax) {
+ dk3mem_cpy((void *)q, (void *)points, sizeof(q));
+ for(i = 0; i < 7; i++) {
+ dk3fig_tool_shift_point(&(q[i]), x, y, ec);
+ }
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, q[0].x, q[0].y);
+ f2lud_curveto(
+ job, drw, obj,
+ q[1].x, q[1].y, q[2].x, q[2].y, q[3].x, q[3].y
+ );
+ f2lud_curveto(
+ job, drw, obj,
+ q[4].x, q[4].y, q[5].x, q[5].y, q[6].x, q[6].y
+ );
+ f2lud_stroke(job, drw, obj);
+ x = dk3ma_d_add_ok(x, dx, ec);
+ }
+ y1 = dk3ma_d_add_ok(y, 0.5 * dy, ec);
+ x = dk3ma_d_sub_ok(xs, 0.5 * dx, ec);
+ while(x < outbb->xmax) {
+ dk3mem_cpy((void *)q, (void *)points, sizeof(q));
+ for(i = 0; i < 7; i++) {
+ dk3fig_tool_shift_point(&(q[i]), x, y1, ec);
+ }
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, q[0].x, q[0].y);
+ f2lud_curveto(
+ job, drw, obj,
+ q[1].x, q[1].y, q[2].x, q[2].y, q[3].x, q[3].y
+ );
+ f2lud_curveto(
+ job, drw, obj,
+ q[4].x, q[4].y, q[5].x, q[5].y, q[6].x, q[6].y
+ );
+ f2lud_stroke(job, drw, obj);
+ x = dk3ma_d_add_ok(x, dx, ec);
+ }
+ y = dk3ma_d_add_ok(y, dy, ec);
+ }
+}
+
+
+
+/** Large fish scale.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_large_fish_scale(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ dk3_fig_poly_point_t p[7]; /* Curve points of segment near origin. */
+ double alpha; /* Opening angle. */
+ double kappa; /* Factor to construct Bezier control points. */
+ double pat; /* Normal pattern distance. */
+ double dx; /* Delta x. */
+ double dy; /* Delta y. */
+ double r; /* Fishscale radius. */
+ double as; /* Start angle. */
+
+ pat = 3.6;
+ dx = 4.0 * pat;
+ dy = 2.0 * pat;
+ alpha = 0.9272952; /* from iteration in Scilab */
+ kappa = dk3fig_tool_arc_kappa(alpha, ec);
+ r = dk3ma_d_div_ok(pat, (1.0 - cos(alpha)), ec);
+ as = 1.5 * M_PI - alpha;
+ p[0].x = 0.0;
+ p[0].y = pat;
+ p[1].x = -1.0 * dk3ma_d_mul_ok(r, alpha, ec) * sin(as);
+ p[1].y = dk3ma_d_mul_ok(r, alpha, ec) * cos(as);
+ p[1].x = dk3ma_d_mul_ok(kappa, p[1].x, ec);
+ p[1].y = dk3ma_d_mul_ok(kappa, p[1].y, ec);
+ p[1].y = dk3ma_d_add_ok(p[1].y, p[0].y, ec);
+ p[2].x = dk3ma_d_mul_ok(r, alpha, ec);
+ p[2].x = dk3ma_d_mul_ok(p[2].x, kappa, ec);
+ p[2].x = dk3ma_d_sub_ok(2.0 * pat, p[2].x, ec);
+ p[2].y = 0.0;
+ p[3].x = 2.0 * pat;
+ p[3].y = 0.0;
+ p[4].x = dk3ma_d_sub_ok(dx, p[2].x, ec);
+ p[4].y = 0.0;
+ p[5].x = dk3ma_d_sub_ok(dx, p[1].x, ec);
+ p[5].y = p[1].y;
+ p[6].x = dx;
+ p[6].y = pat;
+ f2ludpat_fish_scale(job, drw, obj, outbb, ec, p, dx, dy);
+}
+
+
+
+
+/** Small fish scale.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_small_fish_scale(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ dk3_fig_poly_point_t p[7]; /* Curve points of segment near origin. */
+ double pat; /* Normal pattern distance. */
+ double dx; /* Delta x. */
+ double dy; /* Delta y. */
+
+ pat = 3.6;
+ p[0].x = 0.0;
+ p[0].y = pat;
+ p[1].x = 0.0;
+ p[1].y = pat * (1.0 - FIG2LAT_CIRCLE_QUADRANT_BEZIER);
+ p[2].x = p[1].y;
+ p[2].y = 0.0;
+ p[3].x = pat;
+ p[3].y = 0.0;
+ p[4].x = pat * (1.0 + FIG2LAT_CIRCLE_QUADRANT_BEZIER);
+ p[4].y = 0.0;
+ p[5].x = 2.0 * pat;
+ p[5].y = p[1].y;
+ p[6].x = p[5].x;
+ p[6].y = pat;
+ dx = 2.0 * pat;
+ dy = 2.0 * pat;
+ f2ludpat_fish_scale(job, drw, obj, outbb, ec, p, dx, dy);
+}
+
+
+
+/** Horizontal shingles right.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_horizontal_shingles_right(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ double pat; /* Normal pattern distance. */
+ double x; /* Current x. */
+ double y; /* Current y. */
+ double xs; /* Start x. */
+ double dy; /* Start y. */
+ double dx; /* Delta x. */
+ int lineno; /* Flag: Odd (1) or even (0) line. */
+
+ pat = 3.6;
+ dy = 2.0 * pat;
+ dx = 3.0 * dy;
+ xs = outbb->xmin;
+ xs = dk3ma_d_mul_ok(dx, floor(dk3ma_d_div_ok(xs, dx, ec)), ec);
+ y = outbb->ymin;
+ y = dk3ma_d_mul_ok((3.0 * dy), floor(dk3ma_d_div_ok(y, (3.0 * dy), ec)), ec);
+ lineno = 0;
+ while(y < outbb->ymax) {
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, outbb->xmin, y);
+ f2lud_lineto(job, drw, obj, outbb->xmax, y);
+ f2lud_stroke(job, drw, obj);
+ x = xs;
+ switch(lineno) {
+ case 1: {
+ x = dk3ma_d_add_ok(x, (2.0 * dy), ec);
+ } break;
+ case 2: {
+ x = dk3ma_d_add_ok(x, dy, ec);
+ } break;
+ }
+ while(x < outbb->xmax) {
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, x, y);
+ f2lud_lineto(
+ job, drw, obj,
+ dk3ma_d_add_ok(x, pat, ec), dk3ma_d_add_ok(y, dy, ec)
+ );
+ f2lud_stroke(job, drw, obj);
+ x = dk3ma_d_add_ok(x, dx, ec);
+ }
+ y = dk3ma_d_add_ok(y, dy, ec);
+ lineno++; if(lineno >= 3) { lineno = 0; }
+ }
+}
+
+
+
+/** Horizontal shingles left.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_horizontal_shingles_left(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ double pat; /* Normal pattern distance. */
+ double x; /* Current x. */
+ double y; /* Current y. */
+ double xs; /* Start x. */
+ double dy; /* Delta y. */
+ double dx; /* Delta x. */
+ int lineno; /* Flag: Odd (1) or even (0) line. */
+
+ pat = 3.6;
+ dy = 2.0 * pat;
+ dx = 3.0 * dy;
+ xs = outbb->xmin;
+ xs = dk3ma_d_mul_ok(dx, floor(dk3ma_d_div_ok(xs, dx, ec)), ec);
+ y = outbb->ymin;
+ y = dk3ma_d_mul_ok((3.0 * dy), floor(dk3ma_d_div_ok(y, (3.0 * dy), ec)), ec);
+ lineno = 0;
+ while(y < outbb->ymax) {
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, outbb->xmin, y);
+ f2lud_lineto(job, drw, obj, outbb->xmax, y);
+ f2lud_stroke(job, drw, obj);
+ x = xs;
+ switch(lineno) {
+ case 2: {
+ x = dk3ma_d_add_ok(x, (2.0 * dy), ec);
+ } break;
+ case 1: {
+ x = dk3ma_d_add_ok(x, dy, ec);
+ } break;
+ }
+ while(x < outbb->xmax) {
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, x, dk3ma_d_add_ok(y, dy, ec));
+ f2lud_lineto( job, drw, obj, dk3ma_d_add_ok(x, pat, ec), y);
+ f2lud_stroke(job, drw, obj);
+ x = dk3ma_d_add_ok(x, dx, ec);
+ }
+ y = dk3ma_d_add_ok(y, dy, ec);
+ lineno++; if(lineno >= 3) { lineno = 0; }
+ }
+}
+
+
+
+/** Vertical shingles falling.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_vertical_shingles_falling(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ double x; /* Current x. */
+ double y; /* Current y. */
+ double pat; /* Normal pattern distance. */
+ double dx; /* Delta x. */
+ double dy; /* Delta y. */
+ double ys; /* Start y. */
+ int lineno; /* Flag: Odd (1) or even (0) line. */
+
+ pat = 3.6;
+ dx = 2.0 * pat;
+ dy = 3.0 * dx;
+
+ ys = outbb->ymin;
+ ys = dk3ma_d_mul_ok(dy, floor(dk3ma_d_div_ok(ys, dy, ec)), ec);
+ x = outbb->xmin;
+ x = dk3ma_d_mul_ok((3.0 * dx), floor(dk3ma_d_div_ok(x, (3.0 * dx), ec)), ec);
+ lineno = 0;
+ while(x < outbb->xmax) {
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, x, outbb->ymin);
+ f2lud_lineto(job, drw, obj, x, outbb->ymax);
+ f2lud_stroke(job, drw, obj);
+ y = ys;
+ switch(lineno) {
+ case 2: {
+ y = dk3ma_d_add_ok(y, (2.0 * dx), ec);
+ } break;
+ case 1: {
+ y = dk3ma_d_add_ok(y, dx, ec);
+ } break;
+ }
+ while(y < outbb->ymax) {
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, x, dk3ma_d_add_ok(y, pat, ec));
+ f2lud_lineto(job, drw, obj, dk3ma_d_add_ok(x, dx, ec), y);
+ f2lud_stroke(job, drw, obj);
+ y = dk3ma_d_add_ok(y, dy, ec);
+ }
+ x = dk3ma_d_add_ok(x, dx, ec);
+ lineno++; if(lineno >= 3) { lineno = 0; }
+ }
+}
+
+
+
+/** Vertical shingles rising.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_vertical_shingles_rising(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ double x; /* Current x. */
+ double y; /* Current y. */
+ double pat; /* Normal pattern distance. */
+ double dx; /* Delta x. */
+ double dy; /* Delta y. */
+ double ys; /* Start y. */
+ int lineno; /* Flag: Odd (1) or even (0) line. */
+
+ pat = 3.6;
+ dx = 2.0 * pat;
+ dy = 3.0 * dx;
+
+ ys = outbb->ymin;
+ ys = dk3ma_d_mul_ok(dy, floor(dk3ma_d_div_ok(ys, dy, ec)), ec);
+ x = outbb->xmin;
+ x = dk3ma_d_mul_ok((3.0 * dx), floor(dk3ma_d_div_ok(x, (3.0 * dx), ec)), ec);
+ lineno = 0;
+ while(x < outbb->xmax) {
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, x, outbb->ymin);
+ f2lud_lineto(job, drw, obj, x, outbb->ymax);
+ f2lud_stroke(job, drw, obj);
+ y = ys;
+ switch(lineno) {
+ case 2: {
+ y = dk3ma_d_add_ok(y, dx, ec);
+ } break;
+ case 1: {
+ y = dk3ma_d_add_ok(y, 2.0 * dx, ec);
+ } break;
+ }
+ while(y < outbb->ymax) {
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, x, y);
+ f2lud_lineto(
+ job, drw, obj,
+ dk3ma_d_add_ok(x, dx, ec), dk3ma_d_add_ok(y, pat, ec)
+ );
+ f2lud_stroke(job, drw, obj);
+ y = dk3ma_d_add_ok(y, dy, ec);
+ }
+ x = dk3ma_d_add_ok(x, dx, ec);
+ lineno++; if(lineno >= 3) { lineno = 0; }
+ }
+}
+
+
+
+void
+f2lud_pattern(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ dk3_bb_t mybb; /* Bounding box of object. */
+ dk3_bb_t outbb; /* Box to fill. */
+ double lw2; /* Half line width. */
+
+ dk3bb_reset(&mybb);
+ dk3bb_reset(&outbb);
+ if(dk3fig_prepare_obj_bb(&mybb, drw, obj, 1)) {
+ dk3bb_add_x(&outbb, dk3ct_2d_x(&(job->ct2d), mybb.xmin, ec));
+ dk3bb_add_x(&outbb, dk3ct_2d_x(&(job->ct2d), mybb.xmax, ec));
+ dk3bb_add_y(&outbb, dk3ct_2d_y(&(job->ct2d), mybb.ymin, ec));
+ dk3bb_add_y(&outbb, dk3ct_2d_y(&(job->ct2d), mybb.ymax, ec));
+#if VERSION_BEFORE_20140330
+ lw2 = 0.45;
+ if(job->lighten) { lw2 = 0.5 * lw2; }
+#else
+ lw2 = job->lwbp / 2.0;
+#endif
+ outbb.xmin = dk3ma_d_sub_ok(outbb.xmin, lw2, ec);
+ outbb.xmax = dk3ma_d_add_ok(outbb.xmax, lw2, ec);
+ outbb.ymin = dk3ma_d_sub_ok(outbb.ymin, lw2, ec);
+ outbb.ymax = dk3ma_d_add_ok(outbb.ymax, lw2, ec);
+ switch(obj->fi) {
+ case 41: {
+ f2ludpat_30_falling_lines(job, drw, obj, &outbb, ec);
+ } break;
+ case 42: {
+ f2ludpat_30_rising_lines(job, drw, obj, &outbb, ec);
+ } break;
+ case 43: {
+ f2ludpat_30_falling_lines(job, drw, obj, &outbb, ec);
+ f2ludpat_30_rising_lines(job, drw, obj, &outbb, ec);
+ } break;
+ case 44: {
+ f2ludpat_45_falling_lines(job, drw, obj, &outbb, ec);
+ } break;
+ case 45: {
+ f2ludpat_45_rising_lines(job, drw, obj, &outbb, ec);
+ } break;
+ case 46: {
+ f2ludpat_45_falling_lines(job, drw, obj, &outbb, ec);
+ f2ludpat_45_rising_lines(job, drw, obj, &outbb, ec);
+ } break;
+ case 47: {
+ f2ludpat_horizontal_bricks(job, drw, obj, &outbb, ec);
+ } break;
+ case 48: {
+ f2ludpat_vertical_bricks(job, drw, obj, &outbb, ec);
+ } break;
+ case 49: {
+ f2ludpat_horizontal_lines(job, drw, obj, &outbb, ec);
+ } break;
+ case 50: {
+ f2ludpat_vertical_lines(job, drw, obj, &outbb, ec);
+ } break;
+ case 51: {
+ f2ludpat_horizontal_lines(job, drw, obj, &outbb, ec);
+ f2ludpat_vertical_lines(job, drw, obj, &outbb, ec);
+ } break;
+ case 52: {
+ f2ludpat_horizontal_shingles_right(job, drw, obj, &outbb, ec);
+ } break;
+ case 53: {
+ f2ludpat_horizontal_shingles_left(job, drw, obj, &outbb, ec);
+ } break;
+ case 54: {
+ f2ludpat_vertical_shingles_falling(job, drw, obj, &outbb, ec);
+ } break;
+ case 55: {
+ f2ludpat_vertical_shingles_rising(job, drw, obj, &outbb, ec);
+ } break;
+ case 56: {
+ f2ludpat_large_fish_scale(job, drw, obj, &outbb, ec);
+ } break;
+ case 57: {
+ f2ludpat_small_fish_scale(job, drw, obj, &outbb, ec);
+ } break;
+ case 58: {
+ f2ludpat_circles(job, drw, obj, &outbb, ec);
+ } break;
+ case 59: {
+ f2ludpat_hexagons(job, drw, obj, &outbb, ec);
+ } break;
+ case 60: {
+ f2ludpat_octagons(job, drw, obj, &outbb, ec);
+ } break;
+ case 61: {
+ f2ludpat_horizontal_tire_treads(job, drw, obj, &outbb, ec);
+ } break;
+ case 62: {
+ f2ludpat_vertical_tire_treads(job, drw, obj, &outbb, ec);
+ } break;
+ }
+ } else {
+
+#line 1545 "f2ludpat.ctr"
+ }
+}
+
+
+
diff --git a/support/dktools/f2ludpat.ctr b/support/dktools/f2ludpat.ctr
new file mode 100644
index 0000000000..f5dec56e00
--- /dev/null
+++ b/support/dktools/f2ludpat.ctr
@@ -0,0 +1,1549 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Draw fill patterns for object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object to process.
+ @param ec Pointer to mathematical error code variable.
+*/
+void
+f2lud_pattern(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int *ec
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk3all.h"
+#include "dk3bezcu.h"
+#include "fig2lat.h"
+#include "f2lud.h"
+#include "f2lsvg.h"
+#include "f2lpgf.h"
+#include "f2lpdf.h"
+#include "f2leps.h"
+#include "dk3figto.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4vers.h"
+#include "f2ludpat.h"
+
+
+
+$!trace-include
+
+
+
+/** One falling line.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param y0 Y value at x=0.
+ @param m Tangens alpha.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_one_falling_line(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ double y0,
+ double m,
+ int *ec
+)
+{
+ double xs; /* Start point x. */
+ double ys; /* Start point y. */
+ double xe; /* End point x. */
+ double ye; /* End point y. */
+ int hs = 0; /* Flag: Have start point. */
+ int he = 0; /* Flag: Have end point. */
+
+ ys = dk3ma_d_sub_ok(y0, dk3ma_d_mul_ok(m, outbb->xmin, ec), ec);
+ if(ys > outbb->ymin) {
+ if(ys <= outbb->ymax) {
+ xs = outbb->xmin; hs = 1;
+ } else {
+ ys = outbb->ymax;
+ xs = dk3ma_d_div_ok(dk3ma_d_sub_ok(y0, outbb->ymax, ec), m, ec);
+ if(xs < outbb->xmax) {
+ hs = 1;
+ }
+ }
+ ye = dk3ma_d_sub_ok(y0, dk3ma_d_mul_ok(m, outbb->xmax, ec), ec);
+ xe = xs;
+ if(ye < outbb->ymax) {
+ if(ye < outbb->ymin) {
+ ye = outbb->ymin;
+ xe = dk3ma_d_div_ok(dk3ma_d_sub_ok(y0, outbb->ymin, ec), m, ec);
+ if(xe > outbb->xmin) {
+ he = 1;
+ }
+ } else {
+ xe = outbb->xmax; he = 1;
+ }
+ }
+ if((hs) && (he)) {
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, xs, ys);
+ f2lud_lineto(job, drw, obj, xe, ye);
+ f2lud_stroke(job, drw, obj);
+ }
+ }
+}
+
+
+
+/** One rising line.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param y0 Y value at x=0.
+ @param m Tangens alpha.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_one_rising_line(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ double y0,
+ double m,
+ int *ec
+)
+{
+ double xs; /* Start point x. */
+ double ys; /* Start point y. */
+ double xe; /* End point x. */
+ double ye; /* End point y. */
+ int hs = 0; /* Flag: Have start point. */
+ int he = 0; /* Flag: Have end point. */
+
+ ye = dk3ma_d_add_ok(
+ y0,
+ dk3ma_d_mul_ok(m, outbb->xmax, ec),
+ ec
+ );
+ ys = ye;
+ if(ye > outbb->ymin) {
+ if(ye <= outbb->ymax) {
+ xe = outbb->xmax; he = 1;
+ } else {
+ ye = outbb->ymax;
+ xe = dk3ma_d_div_ok(dk3ma_d_sub_ok(outbb->ymax, y0, ec), m, ec);
+ if((xe > outbb->xmin) && (xe < outbb->xmax)) {
+ he = 1;
+ }
+ }
+ xs = xe;
+ if(he) {
+ ys = dk3ma_d_add_ok(
+ y0,
+ dk3ma_d_mul_ok(m, outbb->xmin, ec),
+ ec
+ );
+ if(ys < outbb->ymax) {
+ if(ys >= outbb->ymin) {
+ xs = outbb->xmin; hs = 1;
+ } else {
+ ys = outbb->ymin;
+ xs = dk3ma_d_div_ok(dk3ma_d_sub_ok(outbb->ymin, y0, ec), m, ec);
+ if((xs > outbb->xmin) && (xs < outbb->xmax)) {
+ hs = 1;
+ }
+ }
+ }
+ }
+ if((hs) && (he)) {
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, xs, ys);
+ f2lud_lineto(job, drw, obj, xe, ye);
+ f2lud_stroke(job, drw, obj);
+ }
+ }
+}
+
+
+
+/** Falling lines.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param dy Y step.
+ @param m Tangens alpha.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_falling_lines(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ double dy,
+ double m,
+ int *ec
+)
+{
+ double ys; /* Start y. */
+ double ye; /* End y. */
+ double y; /* Current y. */
+
+ ys = dk3ma_d_add_ok(
+ outbb->ymin,
+ dk3ma_d_mul_ok(m, outbb->xmin, ec),
+ ec
+ );
+ ye = dk3ma_d_add_ok(
+ outbb->ymax,
+ dk3ma_d_mul_ok(m, outbb->xmax, ec),
+ ec
+ );
+ ys = dk3ma_d_mul_ok(
+ dy,
+ floor(dk3ma_d_div_ok(ys, dy, ec)),
+ ec
+ );
+ y = ys;
+ while(y < ye) {
+ f2ludpat_one_falling_line(job, drw, obj, outbb, y, m, ec);
+ y = dk3ma_d_add_ok(y, dy, ec);
+ }
+}
+
+
+
+/** Rising lines.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param dy Y step.
+ @param m Tangens alpha.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_rising_lines(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ double dy,
+ double m,
+ int *ec
+)
+{
+ double ys; /* Start y. */
+ double ye; /* End y. */
+ double y; /* Current y. */
+
+ ys = dk3ma_d_sub_ok(
+ outbb->ymin,
+ dk3ma_d_mul_ok(m, outbb->xmax, ec),
+ ec
+ );
+ ye = dk3ma_d_sub_ok(
+ outbb->ymax,
+ dk3ma_d_mul_ok(m, outbb->xmin, ec),
+ ec
+ );
+ ys = dk3ma_d_mul_ok(
+ dy,
+ floor(dk3ma_d_div_ok(ys, dy, ec)),
+ ec
+ );
+ y = ys;
+ while(y < ye) {
+ f2ludpat_one_rising_line(job, drw, obj, outbb, y, m, ec);
+ y = dk3ma_d_add_ok(y, dy, ec);
+ }
+}
+
+
+
+/** 30 degree falling lines.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_30_falling_lines(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ f2ludpat_falling_lines(
+ job, drw, obj, outbb,
+ dk3ma_d_div_ok(3.6, cos(M_PI / 6.0), ec),
+ (1.0 / sqrt(3.0)),
+ ec
+ );
+}
+
+
+
+/** 30 degree rising lines.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_30_rising_lines(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ f2ludpat_rising_lines(
+ job, drw, obj, outbb,
+ dk3ma_d_div_ok(3.6, cos(M_PI / 6.0), ec),
+ (1.0 / sqrt(3.0)),
+ ec
+ );
+}
+
+
+
+/** 45 degree falling lines.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_45_falling_lines(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ f2ludpat_falling_lines(job, drw, obj, outbb, (7.2 * sqrt(2.0)), 1.0, ec);
+}
+
+
+
+/** 45 degree rising lines.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_45_rising_lines(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ f2ludpat_rising_lines(job, drw, obj, outbb, (7.2 * sqrt(2.0)), 1.0, ec);
+}
+
+
+
+/** Horizontal bricks.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_horizontal_bricks(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ double x; /* Current x. */
+ double y; /* Current y. */
+ double ys; /* Start y. */
+ double xs; /* Start x. */
+ double dy; /* Y delta. */
+ double dx; /* X delta. */
+ int lineno; /* Flag: Odd (1) or even (0) line. */
+
+ dy = 7.2;
+ dx = 14.4;
+ ys = outbb->ymin;
+ xs = outbb->xmin;
+ lineno = 0;
+ ys = dk3ma_d_mul_ok(
+ (2.0 * dy),
+ floor(dk3ma_d_div_ok(ys, (2.0 * dy), ec)),
+ ec
+ );
+ y = ys;
+ while(y < outbb->ymax) {
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, outbb->xmin, y);
+ f2lud_lineto(job, drw, obj, outbb->xmax, y);
+ f2lud_stroke(job, drw, obj);
+ x = dk3ma_d_add_ok(xs, (((lineno) ? 0.75 : 0.25) * dx), ec);
+ while(x < outbb->xmax) {
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, x, y);
+ f2lud_lineto(job, drw, obj, x, dk3ma_d_add_ok(y, dy, ec));
+ f2lud_stroke(job, drw, obj);
+ x = dk3ma_d_add_ok(x, dx, ec);
+ }
+ y = dk3ma_d_add_ok(y, dy, ec);
+ lineno++;
+ if(lineno > 1) { lineno = 0; }
+ }
+}
+
+
+
+/** Vertical bricks.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_vertical_bricks(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ double x; /* Current x value. */
+ double y; /* Current y value. */
+ double xs; /* Start x. */
+ double ys; /* Start y. */
+ double dx; /* Delta x. */
+ double dy; /* Delta y. */
+ int lineno; /* Flag: Odd (1) or even (0) line. */
+
+ lineno = 0;
+ dy = 14.4;
+ dx = 7.2;
+ xs = outbb->xmin;
+ xs = dk3ma_d_mul_ok(
+ (2.0 * dx),
+ floor(dk3ma_d_div_ok(xs, (2.0 * dx), ec)),
+ ec
+ );
+ ys = outbb->ymin;
+ ys = dk3ma_d_mul_ok(
+ dy,
+ floor(dk3ma_d_div_ok(ys, dy, ec)),
+ ec
+ );
+ x = xs;
+ while(x < outbb->xmax) {
+ x = dk3ma_d_add_ok(x, dx, ec);
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, x, outbb->ymin);
+ f2lud_lineto(job, drw, obj, x, outbb->ymax);
+ f2lud_stroke(job, drw, obj);
+ y = dk3ma_d_add_ok(ys, (((lineno) ? 0.75 : 0.25) * dy), ec);
+ while(y < outbb->ymax) {
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, x, y);
+ f2lud_lineto(job, drw, obj, dk3ma_d_add_ok(x, dx, ec), y);
+ f2lud_stroke(job, drw, obj);
+ y = dk3ma_d_add_ok(y, dy, ec);
+ }
+ lineno++;
+ if(lineno > 1) { lineno = 0; }
+ }
+}
+
+
+
+/** Horizontal lines.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_horizontal_lines(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ double y; /* Current y. */
+ double ys; /* Start y. */
+ double dy; /* Delta y per pass. */
+
+ dy = 3.6;
+ ys = outbb->ymin;
+ ys = dk3ma_d_mul_ok(
+ dy,
+ floor(dk3ma_d_div_ok(ys, dy, ec)),
+ ec
+ );
+ y = ys;
+ while(y < outbb->ymax) {
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, outbb->xmin, y);
+ f2lud_lineto(job, drw, obj, outbb->xmax, y);
+ f2lud_stroke(job, drw, obj);
+ y = dk3ma_d_add_ok(y, dy, ec);
+ }
+}
+
+
+
+/** Vertical lines.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_vertical_lines(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ double x; /* Current x. */
+ double xs; /* Start x. */
+ double dx; /* Delta x. */
+
+ dx = 3.6;
+ xs = outbb->xmin;
+ xs = dk3ma_d_mul_ok(
+ dx,
+ floor(dk3ma_d_div_ok(xs, dx, ec)),
+ ec
+ );
+ x = xs;
+ while(x < outbb->xmax) {
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, x, outbb->ymin);
+ f2lud_lineto(job, drw, obj, x, outbb->ymax);
+ f2lud_stroke(job, drw, obj);
+ x = dk3ma_d_add_ok(x, dx, ec);
+ }
+}
+
+
+
+/** Horizontal tire treads.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_horizontal_tire_treads(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ double x; /* Current x. */
+ double y; /* Current y. */
+ double dx; /* Delta x per step. */
+ double dy; /* Delta y per pass. */
+ double xs; /* Start x. */
+ double ys; /* Start y. */
+
+ dy = 7.2;
+ dx = 3.6;
+ xs = outbb->xmin; ys = outbb->ymin;
+ xs = dk3ma_d_mul_ok(
+ dy,
+ floor(dk3ma_d_div_ok(xs, dy, ec)),
+ ec
+ );
+ ys = dk3ma_d_mul_ok(
+ dy,
+ floor(dk3ma_d_div_ok(ys, dy, ec)),
+ ec
+ );
+ y = ys;
+ while(y < outbb->ymax) {
+ x = xs;
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, x, y);
+ f2lud_lineto(
+ job, drw, obj,
+ dk3ma_d_add_ok(x, dx, ec), dk3ma_d_add_ok(y, dx, ec)
+ );
+ f2lud_lineto(
+ job, drw, obj,
+ dk3ma_d_add_ok(x, dy, ec), y
+ );
+ x = dk3ma_d_add_ok(x, dy, ec);
+ while(x < outbb->xmax) {
+ f2lud_lineto(
+ job, drw, obj,
+ dk3ma_d_add_ok(x, dx, ec), dk3ma_d_add_ok(y, dx, ec)
+ );
+ f2lud_lineto(
+ job, drw, obj,
+ dk3ma_d_add_ok(x, dy, ec), y
+ );
+ x = dk3ma_d_add_ok(x, dy, ec);
+ }
+ f2lud_stroke(job, drw, obj);
+ y = dk3ma_d_add_ok(y, dy, ec);
+ }
+}
+
+
+
+/** Vertical tire treads.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_vertical_tire_treads(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ double x; /* Current x. */
+ double y; /* Current y. */
+ double dx; /* Delta x per pass. */
+ double dy; /* Delta y per step. */
+ double xs; /* Start x. */
+ double ys; /* Start y. */
+
+ dx = 7.2;
+ dy = 3.6;
+ xs = outbb->xmin; ys = outbb->ymin;
+ xs = dk3ma_d_mul_ok(
+ dy,
+ floor(dk3ma_d_div_ok(xs, dy, ec)),
+ ec
+ );
+ ys = dk3ma_d_mul_ok(
+ dy,
+ floor(dk3ma_d_div_ok(ys, dy, ec)),
+ ec
+ );
+ x = xs;
+ while(x < outbb->xmax) {
+ y = ys;
+
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, x, y);
+ f2lud_lineto(job, drw, obj,
+ dk3ma_d_add_ok(x, dy, ec), dk3ma_d_add_ok(y, dy, ec)
+ );
+ f2lud_lineto(job, drw, obj,
+ x, dk3ma_d_add_ok(y, dx, ec)
+ );
+ y = dk3ma_d_add_ok(y, dx, ec);
+ while(y < outbb->ymax) {
+ f2lud_lineto(job, drw, obj,
+ dk3ma_d_add_ok(x, dy, ec), dk3ma_d_add_ok(y, dy, ec)
+ );
+ f2lud_lineto(job, drw, obj,
+ x, dk3ma_d_add_ok(y, dx, ec)
+ );
+ y = dk3ma_d_add_ok(y, dx, ec);
+ }
+ f2lud_stroke(job, drw, obj);
+ x = dk3ma_d_add_ok(x, dx, ec);
+ }
+}
+
+
+
+
+/** Circles.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_circles(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ dk3_fig_poly_point_t p[12]; /* Points for circle around origin. */
+ dk3_fig_poly_point_t q[12]; /* Points shifted to the specified center. */
+ double x; /* Current x. */
+ double y; /* Current y. */
+ double dx; /* Delta x. */
+ double dy; /* Delta y. */
+ double xs; /* Start x. */
+ double ys; /* Start y. */
+ double r; /* Circle radius. */
+ size_t i; /* Index to traverse p and q. */
+
+ r = 7.2;
+ dx = dy = 2.0 * r;
+ xs = outbb->xmin; ys = outbb->ymin;
+ xs = dk3ma_d_mul_ok(
+ dx,
+ floor(dk3ma_d_div_ok(xs, dx, ec)),
+ ec
+ );
+ ys = dk3ma_d_mul_ok(
+ dy,
+ floor(dk3ma_d_div_ok(ys, dy, ec)),
+ ec
+ );
+ p[ 0].x = dx;
+ p[ 0].y = r;
+ p[ 1].x = dx;
+ p[ 1].y = (1.0 + FIG2LAT_CIRCLE_QUADRANT_BEZIER) * r;
+ p[ 2].x = (1.0 + FIG2LAT_CIRCLE_QUADRANT_BEZIER) * r;
+ p[ 2].y = dx;
+ p[ 3].x = r;
+ p[ 3].y = dx;
+ p[ 4].x = (1.0 - FIG2LAT_CIRCLE_QUADRANT_BEZIER) * r;
+ p[ 4].y = dx;
+ p[ 5].x = 0.0;
+ p[ 5].y = (1.0 + FIG2LAT_CIRCLE_QUADRANT_BEZIER) * r;
+ p[ 6].x = 0.0;
+ p[ 6].y = r;
+ p[ 7].x = 0.0;
+ p[ 7].y = (1.0 - FIG2LAT_CIRCLE_QUADRANT_BEZIER) * r;
+ p[ 8].x = (1.0 - FIG2LAT_CIRCLE_QUADRANT_BEZIER) * r;
+ p[ 8].y = 0.0;
+ p[ 9].x = r;
+ p[ 9].y = 0.0;
+ p[10].x = (1.0 + FIG2LAT_CIRCLE_QUADRANT_BEZIER) * r;
+ p[10].y = 0.0;
+ p[11].x = dx;
+ p[11].y = (1.0 - FIG2LAT_CIRCLE_QUADRANT_BEZIER) * r;
+ y = ys;
+ while(y < outbb->ymax) {
+ x = xs;
+ while(x < outbb->xmax) {
+ dk3mem_cpy((void *)q, (void *)p, sizeof(p));
+ for(i = 0; i < 12; i++) {
+ dk3fig_tool_shift_point(&(q[i]), x, y, ec);
+ }
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, q[0].x, q[0].y);
+ f2lud_curveto(
+ job, drw, obj, q[1].x, q[1].y, q[2].x, q[2].y, q[3].x, q[3].y
+ );
+ f2lud_curveto(
+ job, drw, obj, q[4].x, q[4].y, q[5].x, q[5].y, q[6].x, q[6].y
+ );
+ f2lud_curveto(
+ job, drw, obj, q[7].x, q[7].y, q[8].x, q[8].y, q[9].x, q[9].y
+ );
+ f2lud_curveto(
+ job, drw, obj, q[10].x, q[10].y, q[11].x, q[11].y, q[0].x, q[0].y
+ );
+ f2lud_closepath(job, drw, obj);
+ f2lud_stroke(job, drw, obj);
+ x = dk3ma_d_add_ok(x, dx, ec);
+ }
+ y = dk3ma_d_add_ok(y, dy, ec);
+ }
+}
+
+
+
+/** Hexagons.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_hexagons(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ dk3_fig_poly_point_t p[6]; /* Hexagon near origin. */
+ dk3_fig_poly_point_t q[6]; /* Hexagon shifted to current x, y. */
+ double r; /* Radius. */
+ double y1; /* Y position of help line. */
+ double x1; /* X position of help line. */
+ double dy; /* Delta y. */
+ double dx; /* Delta x. */
+ double xs; /* Start x. */
+ double ys; /* Start y. */
+ double x; /* Current x. */
+ double y; /* Current y. */
+ size_t i; /* Index to traverse p and q. */
+
+ r = 16.2 / (2.0 * sin(M_PI / 3.0));
+ y1 = r * sin(M_PI / 3.0);
+ x1 = r * (1.0 - cos(M_PI / 3.0));
+ dx = 2.0 * (r + x1);
+ dy = 2.0 * y1;
+ xs = outbb->xmin;
+ ys = outbb->ymin;
+ xs = dk3ma_d_mul_ok(
+ dx,
+ floor(dk3ma_d_div_ok(xs, dx, ec)),
+ ec
+ );
+ ys = dk3ma_d_mul_ok(
+ dy,
+ floor(dk3ma_d_div_ok(ys, dy, ec)),
+ ec
+ );
+ p[0].x = 0.0;
+ p[0].y = y1;
+ p[1].x = x1;
+ p[1].y = 0.0;
+ p[2].x = x1 + r;
+ p[2].y = 0.0;
+ p[3].x = 2.0 * r;
+ p[3].y = y1;
+ p[4].x = p[2].x;
+ p[4].y = 2.0 * y1;
+ p[5].x = p[1].x;
+ p[5].y = p[4].y;
+ y = ys;
+ while(y < outbb->ymax) {
+ x = xs;
+ while(x < outbb->xmax) {
+ dk3mem_cpy((void *)q, (void *)p, sizeof(p));
+ for(i = 0; i < 6; i++) {
+ dk3fig_tool_shift_point(&(q[i]), x, y, ec);
+ }
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, q[0].x, q[0].y);
+ f2lud_lineto(job, drw, obj, q[1].x, q[1].y);
+ f2lud_lineto(job, drw, obj, q[2].x, q[2].y);
+ f2lud_lineto(job, drw, obj, q[3].x, q[3].y);
+ f2lud_lineto(job, drw, obj, q[4].x, q[4].y);
+ f2lud_lineto(job, drw, obj, q[5].x, q[5].y);
+ f2lud_lineto(job, drw, obj, q[0].x, q[0].y);
+ f2lud_closepath(job, drw, obj);
+ f2lud_stroke(job, drw, obj);
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, q[3].x, q[3].y);
+ f2lud_lineto(job, drw, obj, dk3ma_d_add_ok(q[3].x, r, ec), q[3].y);
+ f2lud_stroke(job, drw, obj);
+ x = dk3ma_d_add_ok(x, dx, ec);
+ }
+ y = dk3ma_d_add_ok(y, dy, ec);
+ }
+}
+
+
+
+/** Octagons.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_octagons(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ dk3_fig_poly_point_t p[8]; /* Octagon near origin. */
+ dk3_fig_poly_point_t q[8]; /* Octagon shifted to final position. */
+ double dx; /* Delta x. */
+ double dy; /* Delta y. */
+ double xs; /* Start x. */
+ double ys; /* Start y. */
+ double x; /* Current x. */
+ double y; /* Current y. */
+ double l; /* Factor for corner length. */
+ double x1; /* X position of help line 1. */
+ double x2; /* X position of help line 2. */
+ size_t i; /* Index to traverse p and q. */
+
+ dx = dy = 4.0 * 3.6;
+ xs = outbb->xmin; ys = outbb->ymin;
+ xs = dk3ma_d_mul_ok(
+ dx,
+ floor(dk3ma_d_div_ok(xs, dx, ec)),
+ ec
+ );
+ ys = dk3ma_d_mul_ok(
+ dy,
+ floor(dk3ma_d_div_ok(ys, dy, ec)),
+ ec
+ ); $? ". dx = %lg", dx
+ l = dx / (1.0 + sqrt(2.0)); $? ". l = %lg", l
+ x1 = (dx - l) / 2.0; $? ". x1 = %lg", x1
+ x2 = x1 + l; $? ". x2 = %lg", x2
+ p[0].x = x1; $? ". 0x = %lg", p[0].x
+ p[0].y = 0.0; $? ". 0y = %lg", p[0].y
+ p[1].x = x2; $? ". 1x = %lg", p[1].x
+ p[1].y = 0.0; $? ". 1y = %lg", p[1].y
+ p[2].x = dx; $? ". 2x = %lg", p[2].x
+ p[2].y = x1; $? ". 2y = %lg", p[2].y
+ p[3].x = dx; $? ". 3x = %lg", p[3].x
+ p[3].y = x2; $? ". 3y = %lg", p[3].y
+ p[4].x = x2; $? ". 4x = %lg", p[4].x
+ p[4].y = dy; $? ". 4y = %lg", p[4].y
+ p[5].x = x1; $? ". 5x = %lg", p[5].x
+ p[5].y = dy; $? ". 5y = %lg", p[5].y
+ p[6].x = 0.0; $? ". 6x = %lg", p[6].x
+ p[6].y = x2; $? ". 6y = %lg", p[6].y
+ p[7].x = 0.0; $? ". 7x = %lg", p[7].x
+ p[7].y = x1; $? ". 7y = %lg", p[7].y
+ y = ys;
+ while(y < outbb->ymax) {
+ x = xs;
+ while(x < outbb->xmax) {
+ dk3mem_cpy((void *)q, (void *)p, sizeof(p));
+ for(i = 0; i < 8; i++) {
+ dk3fig_tool_shift_point(&(q[i]), x, y, ec);
+ }
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, q[0].x, q[0].y);
+ f2lud_lineto(job, drw, obj, q[1].x, q[1].y);
+ f2lud_lineto(job, drw, obj, q[2].x, q[2].y);
+ f2lud_lineto(job, drw, obj, q[3].x, q[3].y);
+ f2lud_lineto(job, drw, obj, q[4].x, q[4].y);
+ f2lud_lineto(job, drw, obj, q[5].x, q[5].y);
+ f2lud_lineto(job, drw, obj, q[6].x, q[6].y);
+ f2lud_lineto(job, drw, obj, q[7].x, q[7].y);
+ f2lud_lineto(job, drw, obj, q[0].x, q[0].y);
+ f2lud_closepath(job, drw, obj);
+ f2lud_stroke(job, drw, obj);
+ x = dk3ma_d_add_ok(x, dx, ec);
+ }
+ y = dk3ma_d_add_ok(y, dy, ec);
+ }
+}
+
+
+
+/** Fish scale.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+ @param points Curve control points near origin.
+ @param dx X delta.
+ @param dy Y delta.
+*/
+static
+void
+f2ludpat_fish_scale(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec,
+ dk3_fig_poly_point_t *points,
+ double dx,
+ double dy
+)
+{
+ dk3_fig_poly_point_t q[7]; /* Points shifted to final position. */
+ double xs; /* Start x. */
+ double ys; /* Start y. */
+ double y1; /* Y position of help line. */
+ double x; /* Current x. */
+ double y; /* Current y. */
+ size_t i; /* Index to traverse npoints and q. */
+
+ xs = outbb->xmin; ys = outbb->ymin;
+ xs = dk3ma_d_mul_ok(
+ dx,
+ floor(dk3ma_d_div_ok(xs, dx, ec)),
+ ec
+ );
+ ys = dk3ma_d_mul_ok(
+ dy,
+ floor(dk3ma_d_div_ok(ys, dy, ec)),
+ ec
+ );
+ y = ys;
+ while(y < outbb->ymax) {
+ x = xs;
+ while(x < outbb->xmax) {
+ dk3mem_cpy((void *)q, (void *)points, sizeof(q));
+ for(i = 0; i < 7; i++) {
+ dk3fig_tool_shift_point(&(q[i]), x, y, ec);
+ }
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, q[0].x, q[0].y);
+ f2lud_curveto(
+ job, drw, obj,
+ q[1].x, q[1].y, q[2].x, q[2].y, q[3].x, q[3].y
+ );
+ f2lud_curveto(
+ job, drw, obj,
+ q[4].x, q[4].y, q[5].x, q[5].y, q[6].x, q[6].y
+ );
+ f2lud_stroke(job, drw, obj);
+ x = dk3ma_d_add_ok(x, dx, ec);
+ }
+ y1 = dk3ma_d_add_ok(y, 0.5 * dy, ec);
+ x = dk3ma_d_sub_ok(xs, 0.5 * dx, ec);
+ while(x < outbb->xmax) {
+ dk3mem_cpy((void *)q, (void *)points, sizeof(q));
+ for(i = 0; i < 7; i++) {
+ dk3fig_tool_shift_point(&(q[i]), x, y1, ec);
+ }
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, q[0].x, q[0].y);
+ f2lud_curveto(
+ job, drw, obj,
+ q[1].x, q[1].y, q[2].x, q[2].y, q[3].x, q[3].y
+ );
+ f2lud_curveto(
+ job, drw, obj,
+ q[4].x, q[4].y, q[5].x, q[5].y, q[6].x, q[6].y
+ );
+ f2lud_stroke(job, drw, obj);
+ x = dk3ma_d_add_ok(x, dx, ec);
+ }
+ y = dk3ma_d_add_ok(y, dy, ec);
+ }
+}
+
+
+
+/** Large fish scale.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_large_fish_scale(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ dk3_fig_poly_point_t p[7]; /* Curve points of segment near origin. */
+ double alpha; /* Opening angle. */
+ double kappa; /* Factor to construct Bezier control points. */
+ double pat; /* Normal pattern distance. */
+ double dx; /* Delta x. */
+ double dy; /* Delta y. */
+ double r; /* Fishscale radius. */
+ double as; /* Start angle. */
+
+ pat = 3.6;
+ dx = 4.0 * pat;
+ dy = 2.0 * pat;
+ alpha = 0.9272952; /* from iteration in Scilab */
+ kappa = dk3fig_tool_arc_kappa(alpha, ec);
+ r = dk3ma_d_div_ok(pat, (1.0 - cos(alpha)), ec);
+ as = 1.5 * M_PI - alpha;
+ p[0].x = 0.0;
+ p[0].y = pat;
+ p[1].x = -1.0 * dk3ma_d_mul_ok(r, alpha, ec) * sin(as);
+ p[1].y = dk3ma_d_mul_ok(r, alpha, ec) * cos(as);
+ p[1].x = dk3ma_d_mul_ok(kappa, p[1].x, ec);
+ p[1].y = dk3ma_d_mul_ok(kappa, p[1].y, ec);
+ p[1].y = dk3ma_d_add_ok(p[1].y, p[0].y, ec);
+ p[2].x = dk3ma_d_mul_ok(r, alpha, ec);
+ p[2].x = dk3ma_d_mul_ok(p[2].x, kappa, ec);
+ p[2].x = dk3ma_d_sub_ok(2.0 * pat, p[2].x, ec);
+ p[2].y = 0.0;
+ p[3].x = 2.0 * pat;
+ p[3].y = 0.0;
+ p[4].x = dk3ma_d_sub_ok(dx, p[2].x, ec);
+ p[4].y = 0.0;
+ p[5].x = dk3ma_d_sub_ok(dx, p[1].x, ec);
+ p[5].y = p[1].y;
+ p[6].x = dx;
+ p[6].y = pat;
+ f2ludpat_fish_scale(job, drw, obj, outbb, ec, p, dx, dy);
+}
+
+
+
+
+/** Small fish scale.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_small_fish_scale(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ dk3_fig_poly_point_t p[7]; /* Curve points of segment near origin. */
+ double pat; /* Normal pattern distance. */
+ double dx; /* Delta x. */
+ double dy; /* Delta y. */
+
+ pat = 3.6;
+ p[0].x = 0.0;
+ p[0].y = pat;
+ p[1].x = 0.0;
+ p[1].y = pat * (1.0 - FIG2LAT_CIRCLE_QUADRANT_BEZIER);
+ p[2].x = p[1].y;
+ p[2].y = 0.0;
+ p[3].x = pat;
+ p[3].y = 0.0;
+ p[4].x = pat * (1.0 + FIG2LAT_CIRCLE_QUADRANT_BEZIER);
+ p[4].y = 0.0;
+ p[5].x = 2.0 * pat;
+ p[5].y = p[1].y;
+ p[6].x = p[5].x;
+ p[6].y = pat;
+ dx = 2.0 * pat;
+ dy = 2.0 * pat;
+ f2ludpat_fish_scale(job, drw, obj, outbb, ec, p, dx, dy);
+}
+
+
+
+/** Horizontal shingles right.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_horizontal_shingles_right(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ double pat; /* Normal pattern distance. */
+ double x; /* Current x. */
+ double y; /* Current y. */
+ double xs; /* Start x. */
+ double dy; /* Start y. */
+ double dx; /* Delta x. */
+ int lineno; /* Flag: Odd (1) or even (0) line. */
+
+ pat = 3.6;
+ dy = 2.0 * pat;
+ dx = 3.0 * dy;
+ xs = outbb->xmin;
+ xs = dk3ma_d_mul_ok(dx, floor(dk3ma_d_div_ok(xs, dx, ec)), ec);
+ y = outbb->ymin;
+ y = dk3ma_d_mul_ok((3.0 * dy), floor(dk3ma_d_div_ok(y, (3.0 * dy), ec)), ec);
+ lineno = 0;
+ while(y < outbb->ymax) {
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, outbb->xmin, y);
+ f2lud_lineto(job, drw, obj, outbb->xmax, y);
+ f2lud_stroke(job, drw, obj);
+ x = xs;
+ switch(lineno) {
+ case 1: {
+ x = dk3ma_d_add_ok(x, (2.0 * dy), ec);
+ } break;
+ case 2: {
+ x = dk3ma_d_add_ok(x, dy, ec);
+ } break;
+ }
+ while(x < outbb->xmax) {
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, x, y);
+ f2lud_lineto(
+ job, drw, obj,
+ dk3ma_d_add_ok(x, pat, ec), dk3ma_d_add_ok(y, dy, ec)
+ );
+ f2lud_stroke(job, drw, obj);
+ x = dk3ma_d_add_ok(x, dx, ec);
+ }
+ y = dk3ma_d_add_ok(y, dy, ec);
+ lineno++; if(lineno >= 3) { lineno = 0; }
+ }
+}
+
+
+
+/** Horizontal shingles left.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_horizontal_shingles_left(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ double pat; /* Normal pattern distance. */
+ double x; /* Current x. */
+ double y; /* Current y. */
+ double xs; /* Start x. */
+ double dy; /* Delta y. */
+ double dx; /* Delta x. */
+ int lineno; /* Flag: Odd (1) or even (0) line. */
+
+ pat = 3.6;
+ dy = 2.0 * pat;
+ dx = 3.0 * dy;
+ xs = outbb->xmin;
+ xs = dk3ma_d_mul_ok(dx, floor(dk3ma_d_div_ok(xs, dx, ec)), ec);
+ y = outbb->ymin;
+ y = dk3ma_d_mul_ok((3.0 * dy), floor(dk3ma_d_div_ok(y, (3.0 * dy), ec)), ec);
+ lineno = 0;
+ while(y < outbb->ymax) {
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, outbb->xmin, y);
+ f2lud_lineto(job, drw, obj, outbb->xmax, y);
+ f2lud_stroke(job, drw, obj);
+ x = xs;
+ switch(lineno) {
+ case 2: {
+ x = dk3ma_d_add_ok(x, (2.0 * dy), ec);
+ } break;
+ case 1: {
+ x = dk3ma_d_add_ok(x, dy, ec);
+ } break;
+ }
+ while(x < outbb->xmax) {
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, x, dk3ma_d_add_ok(y, dy, ec));
+ f2lud_lineto( job, drw, obj, dk3ma_d_add_ok(x, pat, ec), y);
+ f2lud_stroke(job, drw, obj);
+ x = dk3ma_d_add_ok(x, dx, ec);
+ }
+ y = dk3ma_d_add_ok(y, dy, ec);
+ lineno++; if(lineno >= 3) { lineno = 0; }
+ }
+}
+
+
+
+/** Vertical shingles falling.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_vertical_shingles_falling(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ double x; /* Current x. */
+ double y; /* Current y. */
+ double pat; /* Normal pattern distance. */
+ double dx; /* Delta x. */
+ double dy; /* Delta y. */
+ double ys; /* Start y. */
+ int lineno; /* Flag: Odd (1) or even (0) line. */
+
+ pat = 3.6;
+ dx = 2.0 * pat;
+ dy = 3.0 * dx;
+
+ ys = outbb->ymin;
+ ys = dk3ma_d_mul_ok(dy, floor(dk3ma_d_div_ok(ys, dy, ec)), ec);
+ x = outbb->xmin;
+ x = dk3ma_d_mul_ok((3.0 * dx), floor(dk3ma_d_div_ok(x, (3.0 * dx), ec)), ec);
+ lineno = 0;
+ while(x < outbb->xmax) {
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, x, outbb->ymin);
+ f2lud_lineto(job, drw, obj, x, outbb->ymax);
+ f2lud_stroke(job, drw, obj);
+ y = ys;
+ switch(lineno) {
+ case 2: {
+ y = dk3ma_d_add_ok(y, (2.0 * dx), ec);
+ } break;
+ case 1: {
+ y = dk3ma_d_add_ok(y, dx, ec);
+ } break;
+ }
+ while(y < outbb->ymax) {
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, x, dk3ma_d_add_ok(y, pat, ec));
+ f2lud_lineto(job, drw, obj, dk3ma_d_add_ok(x, dx, ec), y);
+ f2lud_stroke(job, drw, obj);
+ y = dk3ma_d_add_ok(y, dy, ec);
+ }
+ x = dk3ma_d_add_ok(x, dx, ec);
+ lineno++; if(lineno >= 3) { lineno = 0; }
+ }
+}
+
+
+
+/** Vertical shingles rising.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object requiring the fill pattern.
+ @param outbb Bounding box to fill with pattern.
+ @param ec Pointer to error code variable.
+*/
+static
+void
+f2ludpat_vertical_shingles_rising(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ dk3_bb_t *outbb,
+ int *ec
+)
+{
+ double x; /* Current x. */
+ double y; /* Current y. */
+ double pat; /* Normal pattern distance. */
+ double dx; /* Delta x. */
+ double dy; /* Delta y. */
+ double ys; /* Start y. */
+ int lineno; /* Flag: Odd (1) or even (0) line. */
+
+ pat = 3.6;
+ dx = 2.0 * pat;
+ dy = 3.0 * dx;
+
+ ys = outbb->ymin;
+ ys = dk3ma_d_mul_ok(dy, floor(dk3ma_d_div_ok(ys, dy, ec)), ec);
+ x = outbb->xmin;
+ x = dk3ma_d_mul_ok((3.0 * dx), floor(dk3ma_d_div_ok(x, (3.0 * dx), ec)), ec);
+ lineno = 0;
+ while(x < outbb->xmax) {
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, x, outbb->ymin);
+ f2lud_lineto(job, drw, obj, x, outbb->ymax);
+ f2lud_stroke(job, drw, obj);
+ y = ys;
+ switch(lineno) {
+ case 2: {
+ y = dk3ma_d_add_ok(y, dx, ec);
+ } break;
+ case 1: {
+ y = dk3ma_d_add_ok(y, 2.0 * dx, ec);
+ } break;
+ }
+ while(y < outbb->ymax) {
+ f2lud_newpath(job, drw, obj);
+ f2lud_moveto(job, drw, obj, x, y);
+ f2lud_lineto(
+ job, drw, obj,
+ dk3ma_d_add_ok(x, dx, ec), dk3ma_d_add_ok(y, pat, ec)
+ );
+ f2lud_stroke(job, drw, obj);
+ y = dk3ma_d_add_ok(y, dy, ec);
+ }
+ x = dk3ma_d_add_ok(x, dx, ec);
+ lineno++; if(lineno >= 3) { lineno = 0; }
+ }
+}
+
+
+
+void
+f2lud_pattern(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int *ec
+)
+{
+ dk3_bb_t mybb; /* Bounding box of object. */
+ dk3_bb_t outbb; /* Box to fill. */
+ double lw2; /* Half line width. */
+
+ dk3bb_reset(&mybb);
+ dk3bb_reset(&outbb);
+ if(dk3fig_prepare_obj_bb(&mybb, drw, obj, 1)) {
+ dk3bb_add_x(&outbb, dk3ct_2d_x(&(job->ct2d), mybb.xmin, ec));
+ dk3bb_add_x(&outbb, dk3ct_2d_x(&(job->ct2d), mybb.xmax, ec));
+ dk3bb_add_y(&outbb, dk3ct_2d_y(&(job->ct2d), mybb.ymin, ec));
+ dk3bb_add_y(&outbb, dk3ct_2d_y(&(job->ct2d), mybb.ymax, ec));
+#if VERSION_BEFORE_20140330
+ lw2 = 0.45;
+ if(job->lighten) { lw2 = 0.5 * lw2; }
+#else
+ lw2 = job->lwbp / 2.0;
+#endif
+ outbb.xmin = dk3ma_d_sub_ok(outbb.xmin, lw2, ec);
+ outbb.xmax = dk3ma_d_add_ok(outbb.xmax, lw2, ec);
+ outbb.ymin = dk3ma_d_sub_ok(outbb.ymin, lw2, ec);
+ outbb.ymax = dk3ma_d_add_ok(outbb.ymax, lw2, ec);
+ switch(obj->fi) {
+ case 41: {
+ f2ludpat_30_falling_lines(job, drw, obj, &outbb, ec);
+ } break;
+ case 42: {
+ f2ludpat_30_rising_lines(job, drw, obj, &outbb, ec);
+ } break;
+ case 43: {
+ f2ludpat_30_falling_lines(job, drw, obj, &outbb, ec);
+ f2ludpat_30_rising_lines(job, drw, obj, &outbb, ec);
+ } break;
+ case 44: {
+ f2ludpat_45_falling_lines(job, drw, obj, &outbb, ec);
+ } break;
+ case 45: {
+ f2ludpat_45_rising_lines(job, drw, obj, &outbb, ec);
+ } break;
+ case 46: {
+ f2ludpat_45_falling_lines(job, drw, obj, &outbb, ec);
+ f2ludpat_45_rising_lines(job, drw, obj, &outbb, ec);
+ } break;
+ case 47: {
+ f2ludpat_horizontal_bricks(job, drw, obj, &outbb, ec);
+ } break;
+ case 48: {
+ f2ludpat_vertical_bricks(job, drw, obj, &outbb, ec);
+ } break;
+ case 49: {
+ f2ludpat_horizontal_lines(job, drw, obj, &outbb, ec);
+ } break;
+ case 50: {
+ f2ludpat_vertical_lines(job, drw, obj, &outbb, ec);
+ } break;
+ case 51: {
+ f2ludpat_horizontal_lines(job, drw, obj, &outbb, ec);
+ f2ludpat_vertical_lines(job, drw, obj, &outbb, ec);
+ } break;
+ case 52: {
+ f2ludpat_horizontal_shingles_right(job, drw, obj, &outbb, ec);
+ } break;
+ case 53: {
+ f2ludpat_horizontal_shingles_left(job, drw, obj, &outbb, ec);
+ } break;
+ case 54: {
+ f2ludpat_vertical_shingles_falling(job, drw, obj, &outbb, ec);
+ } break;
+ case 55: {
+ f2ludpat_vertical_shingles_rising(job, drw, obj, &outbb, ec);
+ } break;
+ case 56: {
+ f2ludpat_large_fish_scale(job, drw, obj, &outbb, ec);
+ } break;
+ case 57: {
+ f2ludpat_small_fish_scale(job, drw, obj, &outbb, ec);
+ } break;
+ case 58: {
+ f2ludpat_circles(job, drw, obj, &outbb, ec);
+ } break;
+ case 59: {
+ f2ludpat_hexagons(job, drw, obj, &outbb, ec);
+ } break;
+ case 60: {
+ f2ludpat_octagons(job, drw, obj, &outbb, ec);
+ } break;
+ case 61: {
+ f2ludpat_horizontal_tire_treads(job, drw, obj, &outbb, ec);
+ } break;
+ case 62: {
+ f2ludpat_vertical_tire_treads(job, drw, obj, &outbb, ec);
+ } break;
+ }
+ } else { $? "! bb"
+ }
+}
+
+
+
diff --git a/support/dktools/f2ludpat.h b/support/dktools/f2ludpat.h
new file mode 100644
index 0000000000..2522230723
--- /dev/null
+++ b/support/dktools/f2ludpat.h
@@ -0,0 +1,71 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: f2ludpat.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file f2ludpat.h Header file for the f2ludpat module.
+*/
+
+#ifndef F2LUDPAT_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define F2LUDPAT_H_INCLUDED 1
+
+
+#line 10 "f2ludpat.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Draw fill patterns for object.
+ @param job Job structure.
+ @param drw Drawing structure.
+ @param obj Object to process.
+ @param ec Pointer to mathematical error code variable.
+*/
+void
+f2lud_pattern(
+ f2l_job_t *job,
+ dk3_fig_drawing_t *drw,
+ dk3_fig_obj_t *obj,
+ int *ec
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/favicon.ico b/support/dktools/favicon.ico
new file mode 100644
index 0000000000..c07cdafd81
--- /dev/null
+++ b/support/dktools/favicon.ico
Binary files differ
diff --git a/support/dktools/fig2lat.c b/support/dktools/fig2lat.c
new file mode 100644
index 0000000000..78a5ec4674
--- /dev/null
+++ b/support/dktools/fig2lat.c
@@ -0,0 +1,1484 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: fig2lat.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file fig2lat.c The fig2lat module.
+*/
+
+
+#line 209 "fig2lat.ctr"
+
+
+/** Test flag to show Beziervalues.
+*/
+#define FIG2LAT_TEST_BEZIER 0
+
+
+
+#include "dk3all.h"
+#include "dk3bezcu.h"
+#include "fig2lat.h"
+#include "f2lud.h"
+#include "f2lsvg.h"
+#include "dk3figto.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4vers.h"
+
+
+
+
+#line 230 "fig2lat.ctr"
+
+
+
+/** Keywords used by the module, not localized.
+*/
+static dkChar const * const f2l_kw[] = {
+/* 0 */
+dkT("dktools"),
+
+/* 1 */
+dkT("fig2lat.str"),
+
+/* 2 */
+dkT("fig2lat.txt"),
+
+/* 3 */
+dkT(".fig"),
+
+/* 4 */
+dkT(".pgf"),
+
+/* 5 */
+dkT(".svg"),
+
+/* 6 */
+dkT(".eps"),
+
+/* 7 */
+dkT(".tex"),
+
+/* 8 */
+dkT(".pdf"),
+
+/* 9 */
+dkT("-i.pdf"),
+
+NULL
+
+
+#line 278 "fig2lat.ctr"
+};
+
+
+
+/** Version number.
+*/
+static dkChar const *fig2lat_version[] = {
+ dkT("fig2lat "),
+ DKT_VERSION_DK
+};
+
+
+
+/** License conditions.
+*/
+static dkChar const * const fig2lat_license[] = {
+dkT(""),
+dkT("Copyright (c) 2013-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms,"),
+dkT("with or without modification, are permitted provided"),
+dkT("that the following conditions are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above"),
+dkT(" copyright notice, this list of conditions and the"),
+dkT(" following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above "),
+dkT(" copyright notice, this list of conditions and the following"),
+dkT(" disclaimer in the documentation and/or other materials"),
+dkT(" provided with the distribution."),
+dkT("* Neither the name of the copyright holder(s) nor the names of"),
+dkT(" contributors may be used to endorse or promote"),
+dkT(" products derived from this software without specific"),
+dkT(" prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\""),
+dkT("AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED."),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES"),
+dkT("(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR"),
+dkT("SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER"),
+dkT("CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,"),
+dkT("STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN"),
+dkT("ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE"),
+dkT("POSSIBILITY OF SUCH DAMAGE."),
+dkT(""),
+NULL
+
+
+#line 329 "fig2lat.ctr"
+};
+
+
+
+/** Default help text, shown if no help file is found.
+*/
+static dkChar const * const fig2lat_help_text[] = {
+dkT(""),
+dkT("NAME"),
+dkT(""),
+dkT("fig2lat - Fig to LaTeX conversion"),
+dkT(""),
+dkT("SYNOPSIS"),
+dkT(""),
+dkT(" fig2lat [-l <driver>] [<options>] [-o <key>=<value>]* <file>"),
+dkT(""),
+dkT("DESCRIPTION"),
+dkT(""),
+dkT("Fig2lat converts *.fig drawings created using XFig or jFig"),
+dkT("to other graphics formats, mainly for use with the LaTeX typesetting"),
+dkT("system."),
+dkT(""),
+dkT("OPTIONS"),
+dkT(""),
+dkT("-l <driver>"),
+dkT(" \tDriver, one from the following:"),
+dkT(""),
+dkT("\tDrivers to use a Fig file with latex or pdflatex:"),
+dkT(""),
+dkT("\tpdf.tex\t\tProduce a *.tex/*.pdf file pair."),
+dkT("\t\t\tInclude the *.tex file in your LaTeX source, the"),
+dkT("\t\t\t*.tex file includes the *.pdf file."),
+dkT(""),
+dkT("\teps.tex\t\tProduce a *.tex/*.eps file pair."),
+dkT("\t\t\tInclude the *.tex file in your LaTeX source, the"),
+dkT("\t\t\t*.tex file includes the *.eps file."),
+dkT(""),
+dkT("\tpgf\t\tProduce a *.pgf file for inclusion in a *.tex"),
+dkT("\t\t\tsource."),
+dkT(""),
+dkT("\tDrivers to produce a standalone image:"),
+dkT(""),
+dkT("\ttex.pdf\t\tProduce a full *.tex file for use with pdflatex."),
+dkT("\t\t\tA file file-i.pdf is produced additionally,"),
+dkT("\t\t\tthis file is included by the *.tex file."),
+dkT(""),
+dkT("\ttex\t\tProduce a full *.tex file for use with pdflatex."),
+dkT("\t\t\tThe image is embedded as a PGF image."),
+dkT(""),
+dkT("\teps\t\tProduce a standalone EPS file."),
+dkT(""),
+dkT("\tsvg\t\tProduce a standalone SVG file."),
+dkT(""),
+dkT("-m"),
+dkT("\tMake mode when running on a directory: Convert"),
+dkT("\tfiles only if no destination files up to date are found."),
+dkT(""),
+dkT("-o key=value"),
+dkT("\tKey/value options, may be used multiple times."),
+dkT("\tThe following keys can be used:"),
+dkT(""),
+dkT(""),
+dkT("\tGeneral options:"),
+dkT(""),
+dkT("\tlw=<width>\t\tLine width base."),
+dkT("\t\t\t\tThe default for Fig files is 1/80 inch."),
+dkT("\t\t\t\tWidth can be one of the following:"),
+dkT("\t\t\t\t<number>bp\tPS points"),
+dkT("\t\t\t\t<number>pt\tWidth in pt"),
+dkT("\t\t\t\t<number>in\tWidth in inch"),
+dkT("\t\t\t\t<number>cm\tWidth in cm"),
+dkT("\t\t\t\t<number>mm\tWidth in mm"),
+dkT("\t\t\t\tlighten\t\tUse 1/160 inch"),
+dkT("\t\t\t\tauto\t\t0.4pt * textsize / 10"),
+dkT(""),
+dkT("\tText handling options"),
+dkT(""),
+dkT("\ttf=<string>\t\tText font selection for normal (non-special)"),
+dkT("\t\t\t\ttext. Either ``similar'' or ``fig''."),
+dkT(""),
+dkT("\tts=<size>\t\tFont size factor for normal (non-special) text."),
+dkT("\t\t\t\tEither the keyword ``none'' or a scale factor"),
+dkT("\t\t\t\t(typically in the range 0.95 ... 1.0)."),
+dkT(""),
+dkT("\tbbts[=<boolean>]\tUse text size in bounding box calculaion."),
+dkT(""),
+dkT("\tsmash[=<boolean>]\tUse \\smash instruction in LaTeX output."),
+dkT(""),
+dkT("\tmbox[=<boolean>]\tUse \\mbos instruction in LaTeX output."),
+dkT(""),
+dkT("\treset@font[=<boolean>]\tUse \\reset@font instruction in LaTeX output."),
+dkT(""),
+dkT("\tste[=<encoding>]\tEncoding used when writing special text"),
+dkT("\t\t\t\tto output file. Either ``plain'' or"),
+dkT("\t\t\t\t``utf-8''."),
+dkT(""),
+dkT(""),
+dkT("\tX-Spline and Bezier-Spline options"),
+dkT(""),
+dkT("\txsss[=<number>]\t\tNumber of Bezier-Spline subsegments per"),
+dkT("\t\t\t\tX-spline segment. Default: 8, minimum: 2."),
+dkT(""),
+dkT(""),
+dkT("\tArrowhead options:"),
+dkT(""),
+dkT("\tahas=<number>\t\tNumber of X-spline segments for a 90 degree"),
+dkT("\t\t\t\tangle on arcs. Default: 4."),
+dkT(""),
+dkT("\tahss=<integer>\t\tNumber of arrowhead X-spline segments"),
+dkT("\t\t\t\tfor each original X-spline segment for"),
+dkT("\t\t\t\tarrowheads on splines. Default: 4."),
+dkT(""),
+dkT("\tahms=<integer>\t\tMinimum number of X-spline segments for"),
+dkT("\t\t\t\teach arrowhead edge. Default: 4"),
+dkT(""),
+dkT("\tahip=<float>\t\tArrowhead iteration precision. Default: 0.04."),
+dkT(""),
+dkT(""),
+dkT("\tOutput options:"),
+dkT(""),
+dkT("\tcodi=[<number>]\t\tNumber of digits used for colors. Default: 3."),
+dkT(""),
+dkT(""),
+dkT("\tCompatibilty options (compatibility to fig2dev):"),
+dkT(""),
+dkT("\tcosp[=<boolean>]\tCompatible splines."),
+dkT(""),
+dkT("\tcoah[=<boolean>]\tCompatible arrowheads."),
+dkT(""),
+dkT("\txsah[=<boolean>]\tX-spline arrowheads (not together with coah)."),
+dkT(""),
+dkT("\tcols[=<boolean>]\tCompatible line styles."),
+dkT(""),
+dkT("\tcofop[=<boolean>]\tCompatible fill for open paths."),
+dkT(""),
+dkT(""),
+dkT("\tSource type (mutually exclusive):"),
+dkT(""),
+dkT("\txfig\t\t\tFile produced by XFig"),
+dkT(""),
+dkT("\tjfig\t\t\tFile produced by jFig."),
+dkT(""),
+dkT("\twinfig\t\t\tFile produced by WinFIG."),
+dkT(""),
+dkT(""),
+dkT("\tDriver specific options (tex, tex.pdf):"),
+dkT(""),
+dkT("\tdcts[=<number>]\t\tFont size in pt used in the document class."),
+dkT(""),
+dkT(""),
+dkT("\tDriver specific options (eps, eps.tex):"),
+dkT(""),
+dkT("\tshowpage[=<boolean>]\tUse showpage operator."),
+dkT(""),
+dkT("\tlevel=<integer>\t\tPS level, 2 or 3."),
+dkT(""),
+dkT("\tDriver specific options (svg)"),
+dkT(""),
+dkT("\tcss[=<boolean>]\t\tUse CSS styling."),
+dkT(""),
+dkT("\tgroup[=<boolean>]\tGroup arrowhead objects with the object they"),
+dkT("\t\t\t\tare attached to."),
+dkT(""),
+dkT("\tfragment[=<boolean>]\tWrite an SVG fragment instead of a complete"),
+dkT("\t\t\t\tfile."),
+dkT(""),
+dkT("\tfontbase[=<string>]\tSpecify source for GhostScript fonts"),
+dkT("\t\t\t\tconverted to TTF, \"none\", \"local\", or \"web\"."),
+dkT(""),
+dkT("\treplacementfonts=[<boolean>]\tenables/disables use of replacement"),
+dkT("\t\t\t\t\tfont families."),
+dkT(""),
+dkT("\tmiterlimit[=<boolean>]\tEnables or disables use of \"stroke-miterlimit\""),
+dkT("\t\t\t\tstyle setting."),
+dkT(""),
+dkT(""),
+dkT("EXIT STATUS"),
+dkT(""),
+dkT("0 on success, all other exit status codes indicate an error."),
+dkT(""),
+dkT("FILES"),
+dkT(""),
+dkT("Fig2lat uses the following files from the current working directory:"),
+dkT(""),
+dkT("f2lfonts.tex\tis used in the preamble of tex and tex.pdf output, the file"),
+dkT("\t\tcontents replaces the font selection packages."),
+dkT(""),
+dkT("f2lother.tex\tis used in the preamble of tex and tex.pdf output, the file"),
+dkT("\t\tcontents replaces the packages for \"other setup\"."),
+dkT(""),
+dkT("NOTES"),
+dkT(""),
+dkT("There are differences between the output from fig2lat and the output"),
+dkT("from fig2dev. This is intended, otherwise we would not need an additional"),
+dkT("program."),
+dkT(""),
+dkT("* Interpolated X-splines: Fig2lat uses the correct formula q=-0.5*s"),
+dkT(" as described in [BS1995]."),
+dkT(""),
+dkT("* Arrowheads: All arrowhead types introduced in xfig 3.2.5 are supported."),
+dkT(" On splines and arcs we have curved arrowheads. The same line width as"),
+dkT(" for the original line is used for the arrowhead too, the arrowhead"),
+dkT(" linewidth specified in the Fig file is ignored."),
+dkT(""),
+dkT("* Text: When using LaTeX/pdfLaTeX related drivers (tex, tex.pdf, pdf.tex,"),
+dkT(" eps.tex, pgf) all text is handled by LaTeX/pdfLaTeX. The tf setting"),
+dkT(" controls whether to use PS fonts or similar feature LaTeX fonts for"),
+dkT(" normal text. For special text no font selection instructions are written"),
+dkT(" at all, so document default fonts are used."),
+dkT(""),
+dkT("* Fill patterns: Fill patterns are vector graphics in fig2lat."),
+dkT(""),
+dkT("* Splines: X-splines are converted to a sequence of Bezier splines instead"),
+dkT(" of polylines."),
+dkT(""),
+dkT("KNOWN ISSUES"),
+dkT(""),
+dkT("* The curved arrowheads on arcs and splines are implemented as sequences"),
+dkT(" of short - sometimes very short - Bezier curves."),
+dkT(" At least for my arrowtest.fig test file I saw malformed arrowheads"),
+dkT(" in some renderers although the same graphics were shown fine in other"),
+dkT(" renderers."),
+dkT(" You can avoid the problem by using the coah option (compatible arrowheads)."),
+dkT(" For Batik 1.7 Squiggle you can also attempt the miterlimit=no option."),
+dkT(""),
+dkT("AUTHOR"),
+dkT(""),
+dkT("Dirk Krause"),
+dkT(""),
+dkT("HISTORY"),
+dkT(""),
+dkT("This program replaces the fig2vect program seen in previous versions"),
+dkT("of dktools."),
+dkT(""),
+dkT("COPYRIGHT AND LICENSE"),
+dkT(""),
+dkT("Run"),
+dkT(" fig2lat --license-terms"),
+dkT("to see the license conditions."),
+dkT(""),
+dkT("SEE ALSO"),
+dkT(""),
+dkT("[BS1995]\tCarole Blanc, Christophe Schlick:"),
+dkT("\t\tX-Splines: A Spline Model Designed for the End-User"),
+dkT("\t\tProceedings of the SIGGRAPH 1995"),
+dkT(""),
+dkT("[fig2lat]\thttp://dktools.sourceforge.net"),
+dkT(""),
+NULL
+
+
+#line 579 "fig2lat.ctr"
+};
+
+
+
+/** Default texts, used if localized texts are not found.
+*/
+static dkChar const * const f2l_default_messages[] = {
+/* 0 */
+dkT("Invalid PS level preference value \""),
+
+/* 1 */
+dkT("\"!"),
+
+/* 2 */
+dkT("Input file name too long:\n"),
+
+/* 3 */
+dkT("Failed to read input file!"),
+
+/* 4 */
+dkT("Failed to process input file!"),
+
+/* 5 */
+dkT("Not a regular file, not a directory!"),
+
+/* 6 */
+dkT("Command line options processing failed!"),
+
+/* 7 */
+dkT("Unknown driver \""),
+
+/* 8 */
+dkT("\"!"),
+
+/* 9 */
+dkT("Invalid value \""),
+
+/* 10 */
+dkT("\" for tf, use \"fig\" or \"similar\"!"),
+
+/* 11 */
+dkT("Invalid font size specification \""),
+
+/* 12 */
+dkT("\"!"),
+
+/* 13 */
+dkT("Invalid size specification \""),
+
+/* 14 */
+dkT("\" (overflow)!"),
+
+/* 15 */
+dkT("Value \""),
+
+/* 16 */
+dkT("\" is below the required minimum \""),
+
+/* 17 */
+dkT("\"!"),
+
+/* 18 */
+dkT("\" is above the required maximum \""),
+
+/* 19 */
+dkT("Option \""),
+
+/* 20 */
+dkT("\" requires a positive argument!"),
+
+/* 21 */
+dkT("Option \""),
+
+/* 22 */
+dkT("\" requires a numeric argument!"),
+
+/* 23 */
+dkT("Source type already set!"),
+
+/* 24 */
+dkT("Option \""),
+
+/* 25 */
+dkT("\" requires an unsigned numeric argument!"),
+
+/* 26 */
+dkT("Can not handle negative font size!"),
+
+/* 27 */
+dkT("Illegal option/key name \""),
+
+/* 28 */
+dkT("\"!"),
+
+/* 29 */
+dkT("Option too long:\n\""),
+
+/* 30 */
+dkT("\""),
+
+/* 31 */
+dkT("Option argument too long:\n\""),
+
+/* 32 */
+dkT("Option -l requires an argument!"),
+
+/* 33 */
+dkT("PS level must be 2 or 3!"),
+
+/* 34 */
+dkT("Minimum of arrowhead segments corrected to 2!"),
+
+/* 35 */
+dkT("Mathematical problem (coordinates transformation)!"),
+
+/* 36 */
+dkT("Mathematical problem (spline calculation)!"),
+
+/* 37 */
+dkT("Arrowhead too long for spline!"),
+
+/* 38 */
+dkT("Mathematical problem (path construction)!"),
+
+/* 39 */
+dkT("Arrowheads in summary too long for spline!"),
+
+/* 40 */
+dkT("Failed to calculate graphics state transformation!"),
+
+/* 41 */
+dkT("Failed to add instructions to PDF graphics!"),
+
+/* 42 */
+dkT("Skipping special text!"),
+
+/* 43 */
+dkT("Unknown object type!"),
+
+/* 44 */
+dkT("Special text found!"),
+
+/* 45 */
+dkT("Not a line width: \""),
+
+/* 46 */
+dkT("\"!"),
+
+NULL
+
+
+#line 734 "fig2lat.ctr"
+};
+
+
+
+/** PS level preference name.
+*/
+static dkChar const fig2lat_pref_psl[] = {
+ dkT("/print/ps/level")
+};
+
+
+
+#if 0
+/** Initialize a configuration structure.
+ @param conf Structure to initialize.
+*/
+static
+void
+fig2lat_config_init(fig2lat_config_t *conf)
+{
+
+
+#line 755 "fig2lat.ctr"
+ dk3mem_res((void *)conf, sizeof(fig2lat_config_t));
+ conf->nts = 1.0;
+ conf->ntf = 0;
+
+
+#line 759 "fig2lat.ctr"
+}
+#endif
+
+
+
+/** Set PS level from preferences.
+ @param job Job structure.
+*/
+static
+void
+fig2lat_set_ps_level_from_preferences(f2l_job_t *job)
+{
+ dkChar buf[256]; /* Buffer to retrieve preference value. */
+ int i; /* Conversion result. */
+ if(dk3app_get_pref(job->app,fig2lat_pref_psl,buf,DK3_SIZEOF(buf,dkChar))) {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(buf, dkT("%d"), &i))
+#else
+ if (0 != dk3ma_i_from_string(&i, buf, NULL))
+#endif
+ {
+ if((i >= 2) && (i <= 3)) {
+ job->pslevel = i;
+ } else {
+ /* Warning: Preference value is not a number! */
+ dk3app_log_3(job->app, DK3_LL_WARNING, job->msg, 0, 1, buf);
+ }
+ } else {
+ /* Warning: Preference value is not a number! */
+ dk3app_log_3(job->app, DK3_LL_WARNING, job->msg, 0, 1, buf);
+ }
+ }
+}
+
+
+
+/** Initialize job structure.
+ @param job Job structure to initialize.
+ @param app Application structure for diagnostics.
+ @param msg Localized message texts.
+ @param figmsg Localized message texts for the dk3fig module.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+fig2lat_job_init(
+ f2l_job_t *job,
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *figmsg
+)
+{
+ int back = 0;
+
+
+#line 813 "fig2lat.ctr"
+ dk3mem_res((void*)job, sizeof(f2l_job_t));
+ dk3fig_gs_init(&(job->gs));
+ job->app = app;
+ job->msg = msg;
+ job->figmsg = figmsg;
+ job->opt = NULL;
+ job->drw = NULL;
+ job->on1 = NULL;
+ job->on2 = NULL;
+ job->of1 = NULL;
+ job->of2 = NULL;
+ job->nts = 1.0;
+ job->tts = 12.0;
+#if 0
+ fig2lat_config_init(&(job->confProgram));
+ fig2lat_config_init(&(job->confFile));
+ fig2lat_config_init(&(job->confObject));
+#endif
+ job->dr = FIG2LAT_DRIVER_PDF_WITH_TEX;
+ job->exval = FIG2LAT_EXIT_ERROR_UNKNOWN;
+ job->mm = 0;
+ job->cmd = 0;
+ job->cosp = 0;
+ job->coah = 0;
+ job->xsah = 0;
+ job->xssbs = 8;
+ job->qbs = 4;
+ job->debug = 0;
+ job->showpage = 0;
+ job->pslevel = 3;
+ job->dsc = 0;
+ job->arcspp = 8.0;
+ job->splspp = 8.0;
+ job->minspp = 4;
+ job->xsprec = 0.04; /* originally 1200 / 25400 */
+ job->srctype = DK3_FIG_SRCTYPE_UNKNOWN;
+ job->smash = 1;
+ job->mbox = 0;
+ job->resfont = 1;
+ job->codi = 3;
+ job->css = 1;
+ job->fragment = 0;
+ job->svgfontbase = 0;
+ job->group = 0;
+ job->miterlim = 1;
+ job->cols = 0;
+ job->otherfonts = 1;
+ job->bbts = 0;
+ job->stu8 = 0;
+ job->cofop = 1;
+ job->lwbp = 0.9; /* 1/80 inch */
+ job->lwauto = 0;
+ if(dk3app_get_encoding(app) == DK3_ENCODING_UTF8) {
+ job->stu8 = 1;
+ }
+ fig2lat_set_ps_level_from_preferences(job);
+ (job->ct2d).mx = (job->ct2d).my = (job->ct2d).nx = (job->ct2d).ny = 0.0;
+ job->width = job->height = job->w2 = job->h2 = 0.0;
+ job->lwidth = job->lheight = 0L;
+ /* @DRIVER@
+ If you added components to the f2l_job_t structure, initialize
+ them to default values here.
+ */
+ back = 1;
+
+
+#line 878 "fig2lat.ctr"
+ return back;
+}
+
+
+
+/** Clean up job structure.
+ @param job Job structure to clean up.
+*/
+static
+void
+fig2lat_job_end(f2l_job_t *job)
+{
+
+
+#line 891 "fig2lat.ctr"
+ /* @DRIVER@
+ If you added components to the f2l_job_t structure
+ make sure to release resources here.
+ */
+ if(job->opt) {
+ dk3opt_close(job->opt); job->opt = NULL;
+ }
+
+
+#line 899 "fig2lat.ctr"
+}
+
+
+
+/** Show version information.
+ @param job Job structure.
+*/
+static
+void
+fig2lat_show_version(f2l_job_t *job)
+{
+ dk3sf_initialize_stdout();
+ dk3sf_fputs(fig2lat_version[0], stdout);
+ dk3sf_fputs(fig2lat_version[1], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+}
+
+
+
+/** Show license terms.
+ @param job Job structure.
+*/
+static
+void
+fig2lat_show_license(f2l_job_t *job)
+{
+ dkChar const * const *ptr; /* Pointer to traverse all text lines. */
+ ptr = fig2lat_license;
+ dk3sf_initialize_stdout();
+ while(*ptr) {
+ dk3sf_fputs(*(ptr++), stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+}
+
+
+
+/** Show help text.
+ @param job Job structure.
+*/
+static
+void
+fig2lat_show_help(f2l_job_t *job)
+{
+ dk3app_help(job->app, f2l_kw[2], fig2lat_help_text);
+}
+
+
+
+/** Check whether a file has a fig suffix.
+ @param fn File name.
+ @return 1 for fig files, 0 for other or no suffix.
+*/
+static
+int
+fig2lat_is_fig_file(dkChar const *fn)
+{
+ dkChar const *sp; /* Suffix found in file name. */
+ int back = 0;
+ sp = dk3str_get_suffix(fn);
+ if(sp) {
+ if(0 == dk3str_cmp(sp, f2l_kw[3])) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Create output file name.
+ @param job Job structure.
+ @param ifn Input file name.
+ @param osf Output suffix.
+ @return Valid pointer to new output name on success, NULL on error.
+*/
+static
+dkChar const *
+fig2lat_set_one_output_name(
+ f2l_job_t *job, dkChar const *ifn, dkChar const *osf
+)
+{
+ dkChar buf[DK3_MAX_PATH]; /* Buffer for modification. */
+ dkChar *sp; /* File name suffix in buffer. */
+ dkChar const *back = NULL;
+
+
+
+#line 986 "fig2lat.ctr"
+ if(dk3str_len(ifn) < DK3_SIZEOF(buf,dkChar)) {
+ dk3str_cpy_not_overlapped(buf, ifn);
+ sp = dk3str_get_suffix(buf);
+ if(sp) { *sp = dkT('\0'); }
+ if((dk3str_len(buf) + dk3str_len(osf)) < DK3_SIZEOF(buf,dkChar)) {
+ dk3str_cat(buf, osf);
+ back = dk3str_dup_app(buf, job->app);
+ if(!(back)) {
+ job->exval = FIG2LAT_EXIT_ERROR_SYSTEM;
+
+#line 995 "fig2lat.ctr"
+ }
+ } else {
+
+#line 997 "fig2lat.ctr"
+ /* ERROR: Input file name too long! */
+ job->exval = FIG2LAT_EXIT_FILENAME_TOO_LONG;
+
+#line 999 "fig2lat.ctr"
+ dk3app_log_2(job->app, DK3_LL_ERROR, job->msg, 2, buf);
+ }
+ } else {
+
+#line 1002 "fig2lat.ctr"
+ /* ERROR: Input file name too long! */
+ job->exval = FIG2LAT_EXIT_FILENAME_TOO_LONG;
+
+#line 1004 "fig2lat.ctr"
+ dk3app_log_2(job->app, DK3_LL_ERROR, job->msg, 2, ifn);
+ }
+
+#line 1006 "fig2lat.ctr"
+ return back;
+}
+
+
+
+/** Set output file name(s) depending on input name and output driver.
+ @param job Job structure.
+ @param ifn Input file name.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+fig2lat_set_output_names(f2l_job_t *job, dkChar const *ifn)
+{
+ int back = 0;
+
+
+#line 1022 "fig2lat.ctr"
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ job->on1 = fig2lat_set_one_output_name(job, ifn, f2l_kw[7]);
+ if(job->on1) { back = 1; }
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ job->on1 = fig2lat_set_one_output_name(job, ifn, f2l_kw[7]);
+ job->on2 = fig2lat_set_one_output_name(job, ifn, f2l_kw[9]);
+ if((job->on1) && (job->on2)) { back = 1; }
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ job->on1 = fig2lat_set_one_output_name(job, ifn, f2l_kw[7]);
+ job->on2 = fig2lat_set_one_output_name(job, ifn, f2l_kw[6]);
+ if((job->on1) && (job->on2)) { back = 1; }
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ job->on1 = fig2lat_set_one_output_name(job, ifn, f2l_kw[7]);
+ job->on2 = fig2lat_set_one_output_name(job, ifn, f2l_kw[8]);
+ if((job->on1) && (job->on2)) { back = 1; }
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ job->on1 = fig2lat_set_one_output_name(job, ifn, f2l_kw[6]);
+ if(job->on1) { back = 1; }
+ } break;
+ case FIG2LAT_DRIVER_SVG_STANDALONE: {
+ job->on1 = fig2lat_set_one_output_name(job, ifn, f2l_kw[5]);
+ if(job->on1) { back = 1; }
+ } break;
+ default: { /* PGF */
+ job->on1 = fig2lat_set_one_output_name(job, ifn, f2l_kw[4]);
+ if(job->on1) { back = 1; }
+ } break;
+ }
+
+
+#line 1056 "fig2lat.ctr"
+
+
+#line 1057 "fig2lat.ctr"
+ if(!(back)) {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN);
+
+#line 1059 "fig2lat.ctr"
+ }
+
+
+#line 1061 "fig2lat.ctr"
+ return back;
+}
+
+
+
+/** Run for one file.
+ @param job Job structure.
+ @param fn File name (no wildcards contained).
+*/
+static
+void
+fig2lat_run_for_file(f2l_job_t *job, dkChar const *fn)
+{
+ dkChar const *oldsrcname; /* Saved source file name. */
+#if DK3_HAVE_SETLOCALE && defined(LC_NUMERIC) && DK3_HAVE_LOCALE_H
+ char *oldlocale; /* Old locale setting. */
+#endif
+ unsigned long oldsrcline; /* Saved source file line number. */
+
+
+#line 1080 "fig2lat.ctr"
+ oldsrcname = dk3app_get_source_file(job->app);
+ oldsrcline = dk3app_get_source_line(job->app);
+ dk3app_set_source_file(job->app, fn);
+ dk3app_set_source_line(job->app, 0UL);
+#if 0
+ /*
+ Copy program configuration to file configuration.
+ */
+ dk3mem_cpy(
+ (void *)(&(job->confFile)),
+ (void *)(&(job->confProgram)),
+ sizeof(fig2lat_config_t)
+ );
+#endif
+ job->on1 = NULL;
+ job->on2 = NULL;
+ if(fig2lat_set_output_names(job, fn)) {
+ job->drw = dk3fig_drawing_new(job->app, job->figmsg);
+ if(job->drw) {
+ dk3fig_set_options_bsegs(job->drw, job->xssbs, job->qbs);
+ dk3fig_set_options_lwbp(job->drw, job->lwbp);
+ dk3fig_set_options_coah(job->drw, job->coah);
+ dk3fig_set_options_xsah(job->drw, job->xsah);
+ dk3fig_set_options_cosp(job->drw, job->cosp);
+ dk3fig_set_options_bbts(job->drw, job->bbts);
+ dk3fig_set_options_srctype(job->drw, job->srctype);
+ dk3fig_set_options_arrows(job->drw,job->arcspp,job->splspp,job->minspp);
+ dk3fig_set_options_iteration_precision(job->drw, job->xsprec);
+ dk3fig_set_options_codi(job->drw, job->codi);
+ dk3fig_set_options_cofop(job->drw, job->cofop);
+ if(dk3fig_read_file_name(job->drw, fn)) {
+
+#line 1111 "fig2lat.ctr"
+ if(dk3fig_prepare(job->drw)) {
+
+#line 1112 "fig2lat.ctr"
+#if DK3_HAVE_SETLOCALE && defined(LC_NUMERIC) && DK3_HAVE_LOCALE_H
+ oldlocale = setlocale(LC_NUMERIC, "C");
+#endif
+ dk3fig_gs_init(&(job->gs));
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_SVG_STANDALONE: {
+ f2lsvg_output(job);
+ } break;
+ /* @DRIVER@
+ Add a case branch to call your output driver here.
+ If any error occurs in the driver function, set
+ job->exval to indicate the error.
+ */
+ default: {
+ f2lud_output(job);
+ } break;
+ }
+#if DK3_HAVE_SETLOCALE && defined(LC_NUMERIC) && DK3_HAVE_LOCALE_H
+ setlocale(LC_NUMERIC, oldlocale);
+#endif
+ } else {
+
+#line 1133 "fig2lat.ctr"
+ /* ERROR while preparing drawing! */
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN);
+
+#line 1135 "fig2lat.ctr"
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 4);
+ }
+ } else {
+
+#line 1138 "fig2lat.ctr"
+ /* ERROR while reading input file! */
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN);
+
+#line 1140 "fig2lat.ctr"
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 3);
+ }
+ dk3fig_drawing_delete(job->drw); job->drw = NULL;
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1145 "fig2lat.ctr"
+ }
+ }
+ dk3_release(job->on1);
+ dk3_release(job->on2);
+ dk3app_set_source_file(job->app, oldsrcname);
+ dk3app_set_source_line(job->app, oldsrcline);
+
+
+#line 1152 "fig2lat.ctr"
+}
+
+
+
+/** Check whether there is an up-to-date output file for the given
+ file name and output suffix.
+ @param job Job structure.
+ @param fn Source file name.
+ @param sn Suffix for output file name.
+ @return 1 if output file is available, 0 otherwise.
+*/
+static
+int
+fig2lat_up_to_date_output(f2l_job_t *job, dkChar const *fn, dkChar const *sn)
+{
+ dk3_stat_t stbs; /* Source file information. */
+ dk3_stat_t stbd; /* Destination file information. */
+ dkChar fnb[DK3_MAX_PATH]; /* File name buffer. */
+ dkChar *sp; /* File name suffix in buffer. */
+ int back = 0;
+
+
+#line 1173 "fig2lat.ctr"
+ if(dk3str_len(fn) < DK3_SIZEOF(fnb,dkChar)) {
+ dk3str_cpy_not_overlapped(fnb, fn);
+ sp = dk3str_get_suffix(fnb);
+ if(sp) {
+ *sp = dkT('\0');
+ if((dk3str_len(fnb) + dk3str_len(sn)) < DK3_SIZEOF(fnb,dkChar)) {
+ dk3str_cpy_not_overlapped(sp, sn);
+ if(dk3sf_stat_app(&stbs, fn, job->app)) {
+ if(dk3sf_stat_app(&stbd, fnb, NULL)) {
+ if(stbd.mod > stbs.mod) {
+ back = 1;
+
+#line 1184 "fig2lat.ctr"
+ }
+ }
+ }
+ }
+ }
+ }
+
+#line 1190 "fig2lat.ctr"
+ return back;
+}
+
+
+
+/** Check whether we need to process a fig file found in a directory.
+ @param job Job structure.
+ @param fn File name to check.
+ @return 1 to process the file, 0 to skip processing.
+*/
+static
+int
+fig2lat_must_process_file(f2l_job_t *job, dkChar const *fn)
+{
+ int back = 1;
+
+
+#line 1206 "fig2lat.ctr"
+ if(job->mm) {
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ if(fig2lat_up_to_date_output(job, fn, f2l_kw[7])) {
+ back = 0;
+ }
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ if(fig2lat_up_to_date_output(job, fn, f2l_kw[7])) {
+ if(fig2lat_up_to_date_output(job, fn, f2l_kw[9])) {
+ back = 0;
+ }
+ }
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ if(fig2lat_up_to_date_output(job, fn, f2l_kw[6])) {
+ if(fig2lat_up_to_date_output(job, fn, f2l_kw[7])) {
+ back = 0;
+ }
+ }
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ if(fig2lat_up_to_date_output(job, fn, f2l_kw[7])) {
+ if(fig2lat_up_to_date_output(job, fn, f2l_kw[8])) {
+ back = 0;
+ }
+ }
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ if(fig2lat_up_to_date_output(job, fn, f2l_kw[6])) {
+ back = 0;
+ }
+ } break;
+ case FIG2LAT_DRIVER_SVG_STANDALONE: {
+ if(fig2lat_up_to_date_output(job, fn, f2l_kw[5])) {
+ back = 0;
+ }
+ } break;
+ default: { /* PGF */
+ if(fig2lat_up_to_date_output(job, fn, f2l_kw[4])) {
+ back = 0;
+ }
+ } break;
+ }
+ }
+
+#line 1251 "fig2lat.ctr"
+ return back;
+}
+
+
+
+/** Process a directory.
+ @param job Job structure.
+ @param fn Directory name.
+*/
+static
+void
+fig2lat_run_for_directory(f2l_job_t *job, dkChar const *fn)
+{
+ dk3_dir_t *dir; /* Directory traversal. */
+ dkChar const *filename; /* Found file name. */
+
+
+#line 1267 "fig2lat.ctr"
+ dir = dk3dir_open_app(fn, job->app);
+ if(dir) {
+ while(dk3dir_get_next_file(dir)) {
+ filename = dk3dir_get_fullname(dir);
+ if(filename) {
+ if(fig2lat_is_fig_file(filename)) {
+ if(fig2lat_must_process_file(job, filename)) {
+ fig2lat_run_for_file(job, filename);
+ }
+ }
+ } else {
+
+#line 1278 "fig2lat.ctr"
+ }
+ }
+ dk3dir_close(dir);
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1283 "fig2lat.ctr"
+ }
+
+
+#line 1285 "fig2lat.ctr"
+}
+
+
+
+/** Run for file or directory name directly (no wildcards).
+ @param job Job structure.
+ @param fn File name (wildcards already resolved).
+*/
+static
+void
+fig2lat_run_for_file_directly(f2l_job_t *job, dkChar const *fn)
+{
+ dk3_stat_t stb; /* File information. */
+
+
+#line 1299 "fig2lat.ctr"
+ if(dk3sf_stat_app(&stb, fn, job->app)) {
+ switch((stb.ft) & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_REGULAR: {
+ fig2lat_run_for_file(job, fn);
+ } break;
+ case DK3_FT_DIRECTORY: {
+ fig2lat_run_for_directory(job, fn);
+ } break;
+ default: {
+ /* ERROR: Neither directory nor regular file! */
+ job->exval = FIG2LAT_EXIT_ERROR_NO_SUCH_FILE;
+
+#line 1310 "fig2lat.ctr"
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 5);
+ } break;
+ }
+ } else {
+
+#line 1314 "fig2lat.ctr"
+ job->exval = FIG2LAT_EXIT_ERROR_NO_SUCH_FILE;
+
+#line 1315 "fig2lat.ctr"
+ }
+
+
+#line 1317 "fig2lat.ctr"
+}
+
+
+
+/** Run for file or directory name (may contain wildcards).
+ @param job Job structure.
+ @param fn File name (may contain wildcards).
+*/
+static
+void
+fig2lat_run_for_name(f2l_job_t *job, dkChar const *fn)
+{
+ dkChar fnb[DK3_MAX_PATH]; /* Name buffer for modification. */
+ dkChar const *filename; /* File name found. */
+ dk3_dir_t *dir; /* Expander for wildcards. */
+ int found; /* Flag: Source file found. */
+
+
+#line 1334 "fig2lat.ctr"
+ if(dk3str_len(fn) < DK3_SIZEOF(fnb,dkChar)) {
+ dk3str_cpy_not_overlapped(fnb, fn);
+ dk3str_correct_filename(fnb);
+ if(dk3sf_must_expand(fnb)) {
+ dir = dk3dir_fne_open_app(fnb, job->app);
+ if(dir) {
+ found = 0;
+ while(dk3dir_get_next_file(dir)) {
+ filename = dk3dir_get_fullname(dir);
+ if(filename) {
+ if(fig2lat_is_fig_file(filename)) {
+
+#line 1345 "fig2lat.ctr"
+ found = 1;
+ fig2lat_run_for_file(job, filename);
+ } else {
+
+#line 1348 "fig2lat.ctr"
+ }
+ } else {
+
+#line 1350 "fig2lat.ctr"
+ }
+ }
+ if(0 == found) {
+ job->exval = FIG2LAT_EXIT_ERROR_NO_SUCH_FILE;
+
+#line 1354 "fig2lat.ctr"
+ }
+ dk3dir_close(dir);
+ } else {
+
+#line 1357 "fig2lat.ctr"
+ job->exval = FIG2LAT_EXIT_ERROR_SYSTEM;
+
+#line 1358 "fig2lat.ctr"
+ }
+ } else {
+ fig2lat_run_for_file_directly(job, fnb);
+ }
+ } else {
+
+#line 1363 "fig2lat.ctr"
+ /* ERROR: File name too long! */
+ job->exval = FIG2LAT_EXIT_FILENAME_TOO_LONG;
+
+#line 1365 "fig2lat.ctr"
+ dk3app_log_2(job->app, DK3_LL_ERROR, job->msg, 2, fn);
+ }
+
+#line 1367 "fig2lat.ctr"
+}
+
+
+
+/** Run for current directory.
+ @param job Job structure.
+*/
+static
+void
+fig2lat_run_for_current_directory(f2l_job_t *job)
+{
+ dkChar cwdbu[DK3_MAX_PATH]; /* Buffer for current working directory. */
+
+
+#line 1380 "fig2lat.ctr"
+ if(dk3sf_getcwd_app(cwdbu, DK3_SIZEOF(cwdbu,dkChar), job->app)) {
+ fig2lat_run_for_file_directly(job, cwdbu);
+ } else {
+
+#line 1383 "fig2lat.ctr"
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM);
+
+#line 1384 "fig2lat.ctr"
+ }
+
+
+#line 1386 "fig2lat.ctr"
+}
+
+
+
+/** Run conversion as indicated by command line arguments.
+ @param job Job structure.
+*/
+static
+void
+fig2lat_run(f2l_job_t *job)
+{
+ dkChar const *fn; /* File name. */
+ int argc; /* Number of command line arguments. */
+ int i; /* Current command line argument processed. */
+
+
+#line 1401 "fig2lat.ctr"
+ if((argc = dk3opt_get_num_args(job->opt)) > 0) {
+
+#line 1402 "fig2lat.ctr"
+ job->exval = FIG2LAT_EXIT_SUCCESS;
+
+#line 1403 "fig2lat.ctr"
+ for(i = 0; i < argc; i++) {
+ fn = dk3opt_get_arg(job->opt, i);
+ if(fn) {
+ fig2lat_run_for_name(job, fn);
+ } else {
+ job->exval = FIG2LAT_EXIT_ERROR_NO_SUCH_FILE;
+
+#line 1409 "fig2lat.ctr"
+ }
+ }
+ } else {
+
+#line 1412 "fig2lat.ctr"
+ fig2lat_run_for_current_directory(job);
+ }
+
+
+#line 1415 "fig2lat.ctr"
+}
+
+
+
+#if TRACE_DEBUG
+#if FIG2LAT_TEST_BEZIER
+static
+void
+fig2lat_test_bezier(void)
+{
+ double t;
+ size_t i;
+ t = 0.0;
+ for(i = 0; i <= 10; i++) {
+ printf("%g\t%g\n",t,dk3bezier_value(0.0,1.0,9.0,10.0,t,NULL));
+ t += 0.1;
+ }
+}
+#endif
+#endif
+
+
+/** Entry point.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, any other value indicates an error.
+*/
+DK3_MAIN
+{
+ f2l_job_t job; /* Job structure. */
+ dk3_app_t *app = NULL; /* Application structure. */
+ dkChar const * const *msg = NULL; /* Localized texts. */
+ dkChar const * const *figmsg = NULL; /* dk3fig module localized texts. */
+ int exval = FIG2LAT_EXIT_ERROR_UNKNOWN; /* Exit code. */
+ int testcmd; /* Mask for help/version/license. */
+
+
+#line 1451 "fig2lat.ctr"
+
+
+#line 1452 "fig2lat.ctr"
+#if VERSION_BEFORE_20150821
+ exval = FIG2LAT_EXIT_ERROR_UNKNOWN;
+#endif
+ job.opt = NULL;
+ app = dk3app_open_command(
+ argc, (dkChar const * const *)argv, f2l_kw[0]
+ );
+ if(app) {
+
+#line 1460 "fig2lat.ctr"
+ msg = dk3app_messages(
+ app, f2l_kw[1], (dkChar const **)f2l_default_messages
+ );
+ figmsg = dk3fig_get_localized_messages(app);
+#if TRACE_DEBUG
+#if FIG2LAT_TEST_BEZIER
+ fig2lat_test_bezier();
+#endif
+#endif
+ if(fig2lat_job_init(&job,app,msg,figmsg)) {
+
+#line 1470 "fig2lat.ctr"
+ if(f2lopt_process(&job)) {
+
+#line 1471 "fig2lat.ctr"
+ testcmd = DK3_APP_CMD_HELP | DK3_APP_CMD_VERSION | DK3_APP_CMD_LICENSE;
+ if((job.cmd) & testcmd) {
+
+#line 1473 "fig2lat.ctr"
+ if(job.cmd) {
+
+#line 1474 "fig2lat.ctr"
+ fig2lat_show_version(&job);
+ }
+ if((job.cmd) & DK3_APP_CMD_LICENSE) {
+
+#line 1477 "fig2lat.ctr"
+ fig2lat_show_license(&job);
+ }
+ if((job.cmd) & DK3_APP_CMD_HELP) {
+
+#line 1480 "fig2lat.ctr"
+ fig2lat_show_help(&job);
+ }
+ job.exval = FIG2LAT_EXIT_SUCCESS;
+ } else {
+
+#line 1484 "fig2lat.ctr"
+ fig2lat_run(&job);
+ }
+ } else {
+
+#line 1487 "fig2lat.ctr"
+ dk3app_log_1(job.app, DK3_LL_ERROR, job.msg, 6);
+ }
+ } else {
+
+#line 1490 "fig2lat.ctr"
+ }
+ exval = job.exval;
+ dk3app_close(app); app = NULL;
+ } else {
+
+#line 1494 "fig2lat.ctr"
+ fputs("fig2lat: ERROR: Not enough memory (RAM/swap)!\n", stderr);
+ fflush(stderr);
+ exval = FIG2LAT_EXIT_ERROR_SYSTEM;
+ }
+ fig2lat_job_end(&job);
+
+
+#line 1500 "fig2lat.ctr"
+
+
+#line 1501 "fig2lat.ctr"
+ fflush(stdout);
+ exit(exval); return exval;
+}
+
+
diff --git a/support/dktools/fig2lat.ctr b/support/dktools/fig2lat.ctr
new file mode 100644
index 0000000000..22658a4b6a
--- /dev/null
+++ b/support/dktools/fig2lat.ctr
@@ -0,0 +1,1505 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+# splint comment character = @
+
+
+%% header
+
+#include "dk3fig.h"
+#include "dk3figrd.h"
+#include "dk3figpr.h"
+
+
+/** To draw a quadrant of a circle we do not use 1/3 of the
+ derivative, we use another factor instead.
+*/
+#define FIG2LAT_CIRCLE_QUADRANT_BEZIER 0.5522847498307932
+
+
+
+/** Conversion configuration.
+*/
+typedef struct {
+ double nts; /**< Normal text size (scale factor or -1.0). */
+ int ntf; /**< Normal text font (0=similar, 1=fig). */
+} fig2lat_config_t;
+
+
+
+/** How to handle a text.
+*/
+typedef struct {
+ double fontSize; /**< Font size in pt. */
+ unsigned long fontNumber; /**< Unique font number for LaTeX output. */
+ int psFontNo; /**< PS font number. */
+} f2l_text_handling_t;
+
+
+
+/** Image structure.
+*/
+typedef struct {
+ dk3_ufi_t ufi; /**< Unique file identifier image. */
+ char const *filename; /**< Image file name. */
+ dk3_pdf_xobject_t *xo; /**< PDF X object. */
+ dk3_bif_coord_t width; /**< Image width. */
+ dk3_bif_coord_t height; /**< Image height. */
+ double xres; /**< X resolution. */
+ double yres; /**< Y resolution. */
+ unsigned long imageNumber; /**< Unique number of image. */
+ unsigned long lineno; /**< Line number of object. */
+} f2l_image_t;
+
+
+
+/** Fig2lat job structure.
+*/
+typedef struct {
+ /* @DRIVER@
+ You can add driver-specific configuration compomenents here.
+ For alignment reasons the order of elements is in decreasing
+ type size.
+ Remember to re-compile all modules after changing data types.
+ Initialize the new components in fig2lat_job_init(),
+ release allocated resources in fig2lat_job_end().
+ */
+ dk3_graphics_state_t gs; /**< Graphics state. */
+ dk3_ct_2d_t ct2d; /**< Coordinates transformation data. */
+ dk3_fig_drawing_t *drw; /**< Fig drawing to convert. */
+ dk3_app_t *app; /**< Application structure. */
+ dk3_option_set_t *opt; /**< Options and cmd arguments. */
+ FILE *of1; /**< Output file 1. */
+ FILE *of2; /**< Output file 2. */
+ dkChar const *on1; /**< Output file name 1. */
+ dkChar const *on2; /**< Output file name 2. */
+ dkChar const * const *msg; /**< Localized text messages. */
+ dkChar const * const *figmsg; /**< Localized messages dk3fig mod. */
+ double width; /**< Width (typically in bp). */
+ double height; /**< Height (typically in bp). */
+ double w2; /**< Secondary width information. */
+ double h2; /**< Secondary height information. */
+ double nts; /**< Normal text size. */
+ double tts; /**< TeX text size. */
+ double arcspp; /**< Spline points per arc. */
+ double splspp; /**< Spline points per interval. */
+ double xsprec; /**< Iteration precision. */
+ double lwbp; /**< Line width in bp. */
+ long lwidth; /**< Width in bp. */
+ long lheight; /**< Height in bp. */
+ size_t xssbs; /**< X-spline segement Bezier segs. */
+ size_t minspp; /**< Minimum spline points. */
+ size_t qbs; /**< Quadrant Bezier segments. */
+ size_t codi; /**< Color digits. */
+ int ntf; /**< Text font (0=similar, 1=fig). */
+ int dr; /**< Driver, see @ref fig2latdrivers. */
+ int exval; /**< Exit, see @ref fig2latexitcodes. */
+ int mm; /**< Flag: Make mode. */
+ int cmd; /**< Command to execute. */
+ int cosp; /**< Flag: Spline compatibility. */
+ int coah; /**< Flag: Arrowhead compatibility. */
+ int xsah; /**< Flag: X-spline arrowhead. */
+ int debug; /**< Flag: Write debug information. */
+ int showpage; /**< Flag: Write showpage operator. */
+ int pslevel; /**< PS language level. */
+ int dsc; /**< Flag: Write PS DSC. */
+ int srctype; /**< Source file type. */
+ int smash; /**< Flag: Use smash instruction. */
+ int mbox; /**< Flag: Use mbox instruction. */
+ int resfont; /**< Flag: Use reset@font. */
+ int css; /**< Flag: CSS-styled SVG. */
+ int fragment; /**< Flag: Write SVG fragment only. */
+ int svgfontbase; /**< SVG font base: 0=none, 1=local, 2=web. */
+ int group; /**< Flag: Group SVG object with ahs. */
+ int miterlim; /**< Flag: Write miterlimit. */
+ int cols; /**< Flag: Compatible line styles. */
+ int otherfonts; /**< Flag: Use additional fonts SVG. */
+ int bbts; /**< Flag: Use text size for bb. */
+ int stu8; /**< Flag: Special text uses UTF-8. */
+ int cofop; /**< Flag: Compat fill open paths. */
+ int lwauto; /**< Flag: Automatic line width. */
+} f2l_job_t;
+
+
+
+/** @defgroup fig2latexitcodes Exit codes for fig2lat.
+*/
+/**@{*/
+
+/** Program succeeded.
+*/
+#define FIG2LAT_EXIT_SUCCESS 0
+
+/** Error occured, no detailed description.
+*/
+#define FIG2LAT_EXIT_ERROR_UNKNOWN 1
+
+/** Error, no file found to convert.
+*/
+#define FIG2LAT_EXIT_ERROR_NO_SUCH_FILE 2
+
+/** File name is too long for processing.
+*/
+#define FIG2LAT_EXIT_FILENAME_TOO_LONG 3
+
+/** Resources problem or system error.
+*/
+#define FIG2LAT_EXIT_ERROR_SYSTEM 4
+
+/** Mathematical error.
+*/
+#define FIG2LAT_EXIT_ERROR_MATH 5
+
+/** Syntax error in input file.
+*/
+#define FIG2LAT_EXIT_ERROR_SYNTAX 6
+/**@}*/
+
+
+
+/** @defgroup fig2latdrivers Fig2lat output drivers.
+*/
+
+/**@{*/
+
+/** Produce PGF output file (default driver).
+*/
+#define FIG2LAT_DRIVER_PGF 0
+
+/** Produce full *.tex file, image as embedded PGF.
+*/
+#define FIG2LAT_DRIVER_TEX_FULL_PGF 1
+
+/** Produce full *.tex file, image as included external PDF.
+*/
+#define FIG2LAT_DRIVER_TEX_FULL_PDF 2
+
+/** Produce *.tex file including an external EPS.
+*/
+#define FIG2LAT_DRIVER_EPS_WITH_TEX 3
+
+/** Produce *.tex file including an external PDF.
+*/
+#define FIG2LAT_DRIVER_PDF_WITH_TEX 4
+
+/** Produce standalone EPS file.
+*/
+#define FIG2LAT_DRIVER_EPS_STANDALONE 5
+
+/** Produce standalone SVG file.
+*/
+#define FIG2LAT_DRIVER_SVG_STANDALONE 6
+
+/* @DRIVER@
+ Add new driver numbers above this comment.
+ The driver numbers must correspond to the order of
+ driver names in f2lopt.ctr in the f2lopt_language_names array.
+*/
+
+/**@}*/
+
+
+
+#include "f2lopt.h"
+#include "f2lto.h"
+
+%% module
+
+
+/** Test flag to show Beziervalues.
+*/
+#define FIG2LAT_TEST_BEZIER 0
+
+
+
+#include "dk3all.h"
+#include "dk3bezcu.h"
+#include "fig2lat.h"
+#include "f2lud.h"
+#include "f2lsvg.h"
+#include "dk3figto.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4vers.h"
+
+
+$!trace-include
+
+
+
+/** Keywords used by the module, not localized.
+*/
+static dkChar const * const f2l_kw[] = {
+$!string-table macro=dkT
+#
+# 0: Application group name.
+#
+dktools
+#
+# 1: String table file name.
+#
+fig2lat.str
+#
+# 2: Help file name.
+#
+fig2lat.txt
+#
+# 3: Source file name suffix.
+#
+.fig
+#
+# 4: Output suffix.
+#
+.pgf
+#
+# 5: Ouptut suffix.
+#
+.svg
+#
+# 6: Output suffix.
+#
+.eps
+#
+# 7: Output suffix.
+#
+.tex
+#
+# 8: Output suffix.
+#
+.pdf
+#
+# 9: File end for PDF file.
+#
+-i.pdf
+$!end
+};
+
+
+
+/** Version number.
+*/
+static dkChar const *fig2lat_version[] = {
+ dkT("fig2lat "),
+ DKT_VERSION_DK
+};
+
+
+
+/** License conditions.
+*/
+static dkChar const * const fig2lat_license[] = {
+$!text macro=dkT
+
+Copyright (c) 2013-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms,
+with or without modification, are permitted provided
+that the following conditions are met:
+
+* Redistributions of source code must retain the above
+ copyright notice, this list of conditions and the
+ following disclaimer.
+* Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials
+ provided with the distribution.
+* Neither the name of the copyright holder(s) nor the names of
+ contributors may be used to endorse or promote
+ products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+$!end
+};
+
+
+
+/** Default help text, shown if no help file is found.
+*/
+static dkChar const * const fig2lat_help_text[] = {
+$!text macro=dkT
+
+NAME
+
+fig2lat - Fig to LaTeX conversion
+
+SYNOPSIS
+
+ fig2lat [-l <driver>] [<options>] [-o <key>=<value>]* <file>
+
+DESCRIPTION
+
+Fig2lat converts *.fig drawings created using XFig or jFig
+to other graphics formats, mainly for use with the LaTeX typesetting
+system.
+
+OPTIONS
+
+-l <driver>
+ Driver, one from the following:
+
+ Drivers to use a Fig file with latex or pdflatex:
+
+ pdf.tex Produce a *.tex/*.pdf file pair.
+ Include the *.tex file in your LaTeX source, the
+ *.tex file includes the *.pdf file.
+
+ eps.tex Produce a *.tex/*.eps file pair.
+ Include the *.tex file in your LaTeX source, the
+ *.tex file includes the *.eps file.
+
+ pgf Produce a *.pgf file for inclusion in a *.tex
+ source.
+
+ Drivers to produce a standalone image:
+
+ tex.pdf Produce a full *.tex file for use with pdflatex.
+ A file file-i.pdf is produced additionally,
+ this file is included by the *.tex file.
+
+ tex Produce a full *.tex file for use with pdflatex.
+ The image is embedded as a PGF image.
+
+ eps Produce a standalone EPS file.
+
+ svg Produce a standalone SVG file.
+
+-m
+ Make mode when running on a directory: Convert
+ files only if no destination files up to date are found.
+
+-o key=value
+ Key/value options, may be used multiple times.
+ The following keys can be used:
+
+
+ General options:
+
+ lw=<width> Line width base.
+ The default for Fig files is 1/80 inch.
+ Width can be one of the following:
+ <number>bp PS points
+ <number>pt Width in pt
+ <number>in Width in inch
+ <number>cm Width in cm
+ <number>mm Width in mm
+ lighten Use 1/160 inch
+ auto 0.4pt * textsize / 10
+
+ Text handling options
+
+ tf=<string> Text font selection for normal (non-special)
+ text. Either ``similar'' or ``fig''.
+
+ ts=<size> Font size factor for normal (non-special) text.
+ Either the keyword ``none'' or a scale factor
+ (typically in the range 0.95 ... 1.0).
+
+ bbts[=<boolean>] Use text size in bounding box calculaion.
+
+ smash[=<boolean>] Use \smash instruction in LaTeX output.
+
+ mbox[=<boolean>] Use \mbos instruction in LaTeX output.
+
+ reset@font[=<boolean>] Use \reset@font instruction in LaTeX output.
+
+ ste[=<encoding>] Encoding used when writing special text
+ to output file. Either ``plain'' or
+ ``utf-8''.
+
+
+ X-Spline and Bezier-Spline options
+
+ xsss[=<number>] Number of Bezier-Spline subsegments per
+ X-spline segment. Default: 8, minimum: 2.
+
+
+ Arrowhead options:
+
+ ahas=<number> Number of X-spline segments for a 90 degree
+ angle on arcs. Default: 4.
+
+ ahss=<integer> Number of arrowhead X-spline segments
+ for each original X-spline segment for
+ arrowheads on splines. Default: 4.
+
+ ahms=<integer> Minimum number of X-spline segments for
+ each arrowhead edge. Default: 4
+
+ ahip=<float> Arrowhead iteration precision. Default: 0.04.
+
+
+ Output options:
+
+ codi=[<number>] Number of digits used for colors. Default: 3.
+
+
+ Compatibilty options (compatibility to fig2dev):
+
+ cosp[=<boolean>] Compatible splines.
+
+ coah[=<boolean>] Compatible arrowheads.
+
+ xsah[=<boolean>] X-spline arrowheads (not together with coah).
+
+ cols[=<boolean>] Compatible line styles.
+
+ cofop[=<boolean>] Compatible fill for open paths.
+
+
+ Source type (mutually exclusive):
+
+ xfig File produced by XFig
+
+ jfig File produced by jFig.
+
+ winfig File produced by WinFIG.
+
+
+ Driver specific options (tex, tex.pdf):
+
+ dcts[=<number>] Font size in pt used in the document class.
+
+
+ Driver specific options (eps, eps.tex):
+
+ showpage[=<boolean>] Use showpage operator.
+
+ level=<integer> PS level, 2 or 3.
+
+ Driver specific options (svg)
+
+ css[=<boolean>] Use CSS styling.
+
+ group[=<boolean>] Group arrowhead objects with the object they
+ are attached to.
+
+ fragment[=<boolean>] Write an SVG fragment instead of a complete
+ file.
+
+ fontbase[=<string>] Specify source for GhostScript fonts
+ converted to TTF, "none", "local", or "web".
+
+ replacementfonts=[<boolean>] enables/disables use of replacement
+ font families.
+
+ miterlimit[=<boolean>] Enables or disables use of "stroke-miterlimit"
+ style setting.
+
+
+EXIT STATUS
+
+0 on success, all other exit status codes indicate an error.
+
+FILES
+
+Fig2lat uses the following files from the current working directory:
+
+f2lfonts.tex is used in the preamble of tex and tex.pdf output, the file
+ contents replaces the font selection packages.
+
+f2lother.tex is used in the preamble of tex and tex.pdf output, the file
+ contents replaces the packages for "other setup".
+
+NOTES
+
+There are differences between the output from fig2lat and the output
+from fig2dev. This is intended, otherwise we would not need an additional
+program.
+
+* Interpolated X-splines: Fig2lat uses the correct formula q=-0.5*s
+ as described in [BS1995].
+
+* Arrowheads: All arrowhead types introduced in xfig 3.2.5 are supported.
+ On splines and arcs we have curved arrowheads. The same line width as
+ for the original line is used for the arrowhead too, the arrowhead
+ linewidth specified in the Fig file is ignored.
+
+* Text: When using LaTeX/pdfLaTeX related drivers (tex, tex.pdf, pdf.tex,
+ eps.tex, pgf) all text is handled by LaTeX/pdfLaTeX. The tf setting
+ controls whether to use PS fonts or similar feature LaTeX fonts for
+ normal text. For special text no font selection instructions are written
+ at all, so document default fonts are used.
+
+* Fill patterns: Fill patterns are vector graphics in fig2lat.
+
+* Splines: X-splines are converted to a sequence of Bezier splines instead
+ of polylines.
+
+KNOWN ISSUES
+
+* The curved arrowheads on arcs and splines are implemented as sequences
+ of short - sometimes very short - Bezier curves.
+ At least for my arrowtest.fig test file I saw malformed arrowheads
+ in some renderers although the same graphics were shown fine in other
+ renderers.
+ You can avoid the problem by using the coah option (compatible arrowheads).
+ For Batik 1.7 Squiggle you can also attempt the miterlimit=no option.
+
+AUTHOR
+
+Dirk Krause
+
+HISTORY
+
+This program replaces the fig2vect program seen in previous versions
+of dktools.
+
+COPYRIGHT AND LICENSE
+
+Run
+ fig2lat --license-terms
+to see the license conditions.
+
+SEE ALSO
+
+[BS1995] Carole Blanc, Christophe Schlick:
+ X-Splines: A Spline Model Designed for the End-User
+ Proceedings of the SIGGRAPH 1995
+
+[fig2lat] http://dktools.sourceforge.net
+
+$!end
+};
+
+
+
+/** Default texts, used if localized texts are not found.
+*/
+static dkChar const * const f2l_default_messages[] = {
+$!string-table macro=dkT
+#
+# 0 1: Invalid PS level preference value!
+#
+Invalid PS level preference value "
+"!
+#
+# 2 Input file name too long!
+#
+Input file name too long:\n
+#
+# 3 Failed to read input file!
+#
+Failed to read input file!
+#
+# 4 Failed to process input file!
+#
+Failed to process input file!
+#
+# 5 No regular file, no directory!
+#
+Not a regular file, not a directory!
+#
+# 6 Command line options processing failed!
+#
+Command line options processing failed!
+#
+# 7 + 8 Unknown driver!
+#
+Unknown driver "
+"!
+#
+# 9 + 10 Invalid tf value!
+#
+Invalid value "
+" for tf, use "fig" or "similar"!
+#
+# 11 + 12 Invalid font size!
+#
+Invalid font size specification "
+"!
+#
+# 13 + 14 Invalid size specification!
+#
+Invalid size specification "
+" (overflow)!
+#
+# 15 + 16 + 17 + 18 Value below minimum, maximum!
+#
+Value "
+" is below the required minimum "
+"!
+" is above the required maximum "
+#
+# 19 + 20 Option requires positive argument!
+#
+Option "
+" requires a positive argument!
+#
+# 21 + 22 Option requires a numeric argument!
+#
+Option "
+" requires a numeric argument!
+#
+# 23 Source type already set!
+#
+Source type already set!
+#
+# 24 + 25 Option requires an unsigned numeric argument!
+#
+Option "
+" requires an unsigned numeric argument!
+#
+# 26 Can not handle negative font size!
+#
+Can not handle negative font size!
+#
+# 27 + 28 Illegal option/key name!
+#
+Illegal option/key name "
+"!
+#
+# 29 + 30 Option too long!
+#
+Option too long:\n"
+"
+#
+# 31 Option argument too long!
+#
+Option argument too long:\n"
+#
+# 32 Option -l requires an argument!
+#
+Option -l requires an argument!
+#
+# 33 PS level must be 2 or 3!
+#
+PS level must be 2 or 3!
+#
+# 34 Minimum of arrowhead segments corrected to 2!
+#
+Minimum of arrowhead segments corrected to 2!
+#
+# 35 Mathematical problem (coordinates transformation)!
+#
+Mathematical problem (coordinates transformation)!
+#
+# 36 Mathematical problem (spline calculation)!
+#
+Mathematical problem (spline calculation)!
+#
+# 37 Arrowhead too long for spline!
+#
+Arrowhead too long for spline!
+#
+# 38 Mathematical problem (path construction)!
+#
+Mathematical problem (path construction)!
+#
+# 39 Arrowheads in summary too long for spline!
+#
+Arrowheads in summary too long for spline!
+#
+# 40 Failed to calculate graphics state transformation!
+#
+Failed to calculate graphics state transformation!
+#
+# 41 Failed to add instructions to PDF graphics!
+#
+Failed to add instructions to PDF graphics!
+#
+# 42 Skipping special text!
+#
+Skipping special text!
+#
+# 43 Unknown object type!
+#
+Unknown object type!
+#
+# 44
+#
+Special text found!
+#
+# 45 46
+#
+Not a line width: "
+"!
+$!end
+};
+
+
+
+/** PS level preference name.
+*/
+static dkChar const fig2lat_pref_psl[] = {
+ dkT("/print/ps/level")
+};
+
+
+
+#if 0
+/** Initialize a configuration structure.
+ @param conf Structure to initialize.
+*/
+static
+void
+fig2lat_config_init(fig2lat_config_t *conf)
+{
+ $? "+ fig2lat_config_init PTR=%d", TR_IPTR(conf)
+ dk3mem_res((void *)conf, sizeof(fig2lat_config_t));
+ conf->nts = 1.0;
+ conf->ntf = 0;
+ $? "- fig2lat_config_init"
+}
+#endif
+
+
+
+/** Set PS level from preferences.
+ @param job Job structure.
+*/
+static
+void
+fig2lat_set_ps_level_from_preferences(f2l_job_t *job)
+{
+ dkChar buf[256]; /* Buffer to retrieve preference value. */
+ int i; /* Conversion result. */
+ if(dk3app_get_pref(job->app,fig2lat_pref_psl,buf,DK3_SIZEOF(buf,dkChar))) {
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(buf, dkT("%d"), &i))
+#else
+ if (0 != dk3ma_i_from_string(&i, buf, NULL))
+#endif
+ {
+ if((i >= 2) && (i <= 3)) {
+ job->pslevel = i;
+ } else {
+ /* Warning: Preference value is not a number! */
+ dk3app_log_3(job->app, DK3_LL_WARNING, job->msg, 0, 1, buf);
+ }
+ } else {
+ /* Warning: Preference value is not a number! */
+ dk3app_log_3(job->app, DK3_LL_WARNING, job->msg, 0, 1, buf);
+ }
+ }
+}
+
+
+
+/** Initialize job structure.
+ @param job Job structure to initialize.
+ @param app Application structure for diagnostics.
+ @param msg Localized message texts.
+ @param figmsg Localized message texts for the dk3fig module.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+fig2lat_job_init(
+ f2l_job_t *job,
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *figmsg
+)
+{
+ int back = 0;
+ $? "+ fig2lat_job_init PTR=%d", TR_IPTR(job)
+ dk3mem_res((void*)job, sizeof(f2l_job_t));
+ dk3fig_gs_init(&(job->gs));
+ job->app = app;
+ job->msg = msg;
+ job->figmsg = figmsg;
+ job->opt = NULL;
+ job->drw = NULL;
+ job->on1 = NULL;
+ job->on2 = NULL;
+ job->of1 = NULL;
+ job->of2 = NULL;
+ job->nts = 1.0;
+ job->tts = 12.0;
+#if 0
+ fig2lat_config_init(&(job->confProgram));
+ fig2lat_config_init(&(job->confFile));
+ fig2lat_config_init(&(job->confObject));
+#endif
+ job->dr = FIG2LAT_DRIVER_PDF_WITH_TEX;
+ job->exval = FIG2LAT_EXIT_ERROR_UNKNOWN;
+ job->mm = 0;
+ job->cmd = 0;
+ job->cosp = 0;
+ job->coah = 0;
+ job->xsah = 0;
+ job->xssbs = 8;
+ job->qbs = 4;
+ job->debug = 0;
+ job->showpage = 0;
+ job->pslevel = 3;
+ job->dsc = 0;
+ job->arcspp = 8.0;
+ job->splspp = 8.0;
+ job->minspp = 4;
+ job->xsprec = 0.04; /* originally 1200 / 25400 */
+ job->srctype = DK3_FIG_SRCTYPE_UNKNOWN;
+ job->smash = 1;
+ job->mbox = 0;
+ job->resfont = 1;
+ job->codi = 3;
+ job->css = 1;
+ job->fragment = 0;
+ job->svgfontbase = 0;
+ job->group = 0;
+ job->miterlim = 1;
+ job->cols = 0;
+ job->otherfonts = 1;
+ job->bbts = 0;
+ job->stu8 = 0;
+ job->cofop = 1;
+ job->lwbp = 0.9; /* 1/80 inch */
+ job->lwauto = 0;
+ if(dk3app_get_encoding(app) == DK3_ENCODING_UTF8) {
+ job->stu8 = 1;
+ }
+ fig2lat_set_ps_level_from_preferences(job);
+ (job->ct2d).mx = (job->ct2d).my = (job->ct2d).nx = (job->ct2d).ny = 0.0;
+ job->width = job->height = job->w2 = job->h2 = 0.0;
+ job->lwidth = job->lheight = 0L;
+ /* @DRIVER@
+ If you added components to the f2l_job_t structure, initialize
+ them to default values here.
+ */
+ back = 1;
+ $? "- fig2lat_job_init %d", back
+ return back;
+}
+
+
+
+/** Clean up job structure.
+ @param job Job structure to clean up.
+*/
+static
+void
+fig2lat_job_end(f2l_job_t *job)
+{
+ $? "+ fig2lat_job_end PTR=%d", TR_IPTR(job)
+ /* @DRIVER@
+ If you added components to the f2l_job_t structure
+ make sure to release resources here.
+ */
+ if(job->opt) {
+ dk3opt_close(job->opt); job->opt = NULL;
+ }
+ $? "- fig2lat_job_end"
+}
+
+
+
+/** Show version information.
+ @param job Job structure.
+*/
+static
+void
+fig2lat_show_version(f2l_job_t *job)
+{
+ dk3sf_initialize_stdout();
+ dk3sf_fputs(fig2lat_version[0], stdout);
+ dk3sf_fputs(fig2lat_version[1], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+}
+
+
+
+/** Show license terms.
+ @param job Job structure.
+*/
+static
+void
+fig2lat_show_license(f2l_job_t *job)
+{
+ dkChar const * const *ptr; /* Pointer to traverse all text lines. */
+ ptr = fig2lat_license;
+ dk3sf_initialize_stdout();
+ while(*ptr) {
+ dk3sf_fputs(*(ptr++), stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+}
+
+
+
+/** Show help text.
+ @param job Job structure.
+*/
+static
+void
+fig2lat_show_help(f2l_job_t *job)
+{
+ dk3app_help(job->app, f2l_kw[2], fig2lat_help_text);
+}
+
+
+
+/** Check whether a file has a fig suffix.
+ @param fn File name.
+ @return 1 for fig files, 0 for other or no suffix.
+*/
+static
+int
+fig2lat_is_fig_file(dkChar const *fn)
+{
+ dkChar const *sp; /* Suffix found in file name. */
+ int back = 0;
+ sp = dk3str_get_suffix(fn);
+ if(sp) {
+ if(0 == dk3str_cmp(sp, f2l_kw[3])) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Create output file name.
+ @param job Job structure.
+ @param ifn Input file name.
+ @param osf Output suffix.
+ @return Valid pointer to new output name on success, NULL on error.
+*/
+static
+dkChar const *
+fig2lat_set_one_output_name(
+ f2l_job_t *job, dkChar const *ifn, dkChar const *osf
+)
+{
+ dkChar buf[DK3_MAX_PATH]; /* Buffer for modification. */
+ dkChar *sp; /* File name suffix in buffer. */
+ dkChar const *back = NULL;
+
+ $? "+ fig2lat_set_one_output_name \"%!ds\" \"%!ds\"", TR_STR(ifn), TR_STR(osf)
+ if(dk3str_len(ifn) < DK3_SIZEOF(buf,dkChar)) {
+ dk3str_cpy_not_overlapped(buf, ifn);
+ sp = dk3str_get_suffix(buf);
+ if(sp) { *sp = dkT('\0'); }
+ if((dk3str_len(buf) + dk3str_len(osf)) < DK3_SIZEOF(buf,dkChar)) {
+ dk3str_cat(buf, osf);
+ back = dk3str_dup_app(buf, job->app);
+ if(!(back)) {
+ job->exval = FIG2LAT_EXIT_ERROR_SYSTEM; $? ". exitcode"
+ }
+ } else { $? "! too long"
+ /* ERROR: Input file name too long! */
+ job->exval = FIG2LAT_EXIT_FILENAME_TOO_LONG; $? ". exitcode"
+ dk3app_log_2(job->app, DK3_LL_ERROR, job->msg, 2, buf);
+ }
+ } else { $? "! ifn too long"
+ /* ERROR: Input file name too long! */
+ job->exval = FIG2LAT_EXIT_FILENAME_TOO_LONG; $? ". exitcode"
+ dk3app_log_2(job->app, DK3_LL_ERROR, job->msg, 2, ifn);
+ } $? "- fig2lat_set_one_output_name %!ds", TR_STR(back)
+ return back;
+}
+
+
+
+/** Set output file name(s) depending on input name and output driver.
+ @param job Job structure.
+ @param ifn Input file name.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+fig2lat_set_output_names(f2l_job_t *job, dkChar const *ifn)
+{
+ int back = 0;
+ $? "+ fig2lat_set_output_names \"%!ds\"", TR_STR(ifn)
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ job->on1 = fig2lat_set_one_output_name(job, ifn, f2l_kw[7]);
+ if(job->on1) { back = 1; }
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ job->on1 = fig2lat_set_one_output_name(job, ifn, f2l_kw[7]);
+ job->on2 = fig2lat_set_one_output_name(job, ifn, f2l_kw[9]);
+ if((job->on1) && (job->on2)) { back = 1; }
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ job->on1 = fig2lat_set_one_output_name(job, ifn, f2l_kw[7]);
+ job->on2 = fig2lat_set_one_output_name(job, ifn, f2l_kw[6]);
+ if((job->on1) && (job->on2)) { back = 1; }
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ job->on1 = fig2lat_set_one_output_name(job, ifn, f2l_kw[7]);
+ job->on2 = fig2lat_set_one_output_name(job, ifn, f2l_kw[8]);
+ if((job->on1) && (job->on2)) { back = 1; }
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ job->on1 = fig2lat_set_one_output_name(job, ifn, f2l_kw[6]);
+ if(job->on1) { back = 1; }
+ } break;
+ case FIG2LAT_DRIVER_SVG_STANDALONE: {
+ job->on1 = fig2lat_set_one_output_name(job, ifn, f2l_kw[5]);
+ if(job->on1) { back = 1; }
+ } break;
+ default: { /* PGF */
+ job->on1 = fig2lat_set_one_output_name(job, ifn, f2l_kw[4]);
+ if(job->on1) { back = 1; }
+ } break;
+ }
+ $? ". on1 = \"%!ds\"", TR_STR(job->on1)
+ $? ". on2 = \"%!ds\"", TR_STR(job->on2)
+ if(!(back)) {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN); $? ". exitcode"
+ }
+ $? "- fig2lat_set_output_names %d \"%!ds\"", back, TR_STR(ifn)
+ return back;
+}
+
+
+
+/** Run for one file.
+ @param job Job structure.
+ @param fn File name (no wildcards contained).
+*/
+static
+void
+fig2lat_run_for_file(f2l_job_t *job, dkChar const *fn)
+{
+ dkChar const *oldsrcname; /* Saved source file name. */
+#if DK3_HAVE_SETLOCALE && defined(LC_NUMERIC) && DK3_HAVE_LOCALE_H
+ char *oldlocale; /* Old locale setting. */
+#endif
+ unsigned long oldsrcline; /* Saved source file line number. */
+ $? "+ fig2lat_run_for_file \"%!ds\"", TR_STR(fn)
+ oldsrcname = dk3app_get_source_file(job->app);
+ oldsrcline = dk3app_get_source_line(job->app);
+ dk3app_set_source_file(job->app, fn);
+ dk3app_set_source_line(job->app, 0UL);
+#if 0
+ /*
+ Copy program configuration to file configuration.
+ */
+ dk3mem_cpy(
+ (void *)(&(job->confFile)),
+ (void *)(&(job->confProgram)),
+ sizeof(fig2lat_config_t)
+ );
+#endif
+ job->on1 = NULL;
+ job->on2 = NULL;
+ if(fig2lat_set_output_names(job, fn)) {
+ job->drw = dk3fig_drawing_new(job->app, job->figmsg);
+ if(job->drw) {
+ dk3fig_set_options_bsegs(job->drw, job->xssbs, job->qbs);
+ dk3fig_set_options_lwbp(job->drw, job->lwbp);
+ dk3fig_set_options_coah(job->drw, job->coah);
+ dk3fig_set_options_xsah(job->drw, job->xsah);
+ dk3fig_set_options_cosp(job->drw, job->cosp);
+ dk3fig_set_options_bbts(job->drw, job->bbts);
+ dk3fig_set_options_srctype(job->drw, job->srctype);
+ dk3fig_set_options_arrows(job->drw,job->arcspp,job->splspp,job->minspp);
+ dk3fig_set_options_iteration_precision(job->drw, job->xsprec);
+ dk3fig_set_options_codi(job->drw, job->codi);
+ dk3fig_set_options_cofop(job->drw, job->cofop);
+ if(dk3fig_read_file_name(job->drw, fn)) { $? ". drawing read"
+ if(dk3fig_prepare(job->drw)) { $? ". drawing prepared"
+#if DK3_HAVE_SETLOCALE && defined(LC_NUMERIC) && DK3_HAVE_LOCALE_H
+ oldlocale = setlocale(LC_NUMERIC, "C");
+#endif
+ dk3fig_gs_init(&(job->gs));
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_SVG_STANDALONE: {
+ f2lsvg_output(job);
+ } break;
+ /* @DRIVER@
+ Add a case branch to call your output driver here.
+ If any error occurs in the driver function, set
+ job->exval to indicate the error.
+ */
+ default: {
+ f2lud_output(job);
+ } break;
+ }
+#if DK3_HAVE_SETLOCALE && defined(LC_NUMERIC) && DK3_HAVE_LOCALE_H
+ setlocale(LC_NUMERIC, oldlocale);
+#endif
+ } else { $? "! failed to prepare drw"
+ /* ERROR while preparing drawing! */
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN); $? ". exitcode"
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 4);
+ }
+ } else { $? "! failed to read drawing"
+ /* ERROR while reading input file! */
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_UNKNOWN); $? ". exitcode"
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 3);
+ }
+ dk3fig_drawing_delete(job->drw); job->drw = NULL;
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ }
+ dk3_release(job->on1);
+ dk3_release(job->on2);
+ dk3app_set_source_file(job->app, oldsrcname);
+ dk3app_set_source_line(job->app, oldsrcline);
+ $? "- fig2lat_run_for_file"
+}
+
+
+
+/** Check whether there is an up-to-date output file for the given
+ file name and output suffix.
+ @param job Job structure.
+ @param fn Source file name.
+ @param sn Suffix for output file name.
+ @return 1 if output file is available, 0 otherwise.
+*/
+static
+int
+fig2lat_up_to_date_output(f2l_job_t *job, dkChar const *fn, dkChar const *sn)
+{
+ dk3_stat_t stbs; /* Source file information. */
+ dk3_stat_t stbd; /* Destination file information. */
+ dkChar fnb[DK3_MAX_PATH]; /* File name buffer. */
+ dkChar *sp; /* File name suffix in buffer. */
+ int back = 0;
+ $? "+ fig2lat_up_to_date_output \"%!ds\" \"%!ds\"", TR_STR(fn), TR_STR(sn)
+ if(dk3str_len(fn) < DK3_SIZEOF(fnb,dkChar)) {
+ dk3str_cpy_not_overlapped(fnb, fn);
+ sp = dk3str_get_suffix(fnb);
+ if(sp) {
+ *sp = dkT('\0');
+ if((dk3str_len(fnb) + dk3str_len(sn)) < DK3_SIZEOF(fnb,dkChar)) {
+ dk3str_cpy_not_overlapped(sp, sn);
+ if(dk3sf_stat_app(&stbs, fn, job->app)) {
+ if(dk3sf_stat_app(&stbd, fnb, NULL)) {
+ if(stbd.mod > stbs.mod) {
+ back = 1; $? ". output file ok"
+ }
+ }
+ }
+ }
+ }
+ } $? "- fig2lat_up_to_date_output %d", back
+ return back;
+}
+
+
+
+/** Check whether we need to process a fig file found in a directory.
+ @param job Job structure.
+ @param fn File name to check.
+ @return 1 to process the file, 0 to skip processing.
+*/
+static
+int
+fig2lat_must_process_file(f2l_job_t *job, dkChar const *fn)
+{
+ int back = 1;
+ $? "+ fig2lat_must_process_file \"%!ds\"", TR_STR(fn)
+ if(job->mm) {
+ switch(job->dr) {
+ case FIG2LAT_DRIVER_TEX_FULL_PGF: {
+ if(fig2lat_up_to_date_output(job, fn, f2l_kw[7])) {
+ back = 0;
+ }
+ } break;
+ case FIG2LAT_DRIVER_TEX_FULL_PDF: {
+ if(fig2lat_up_to_date_output(job, fn, f2l_kw[7])) {
+ if(fig2lat_up_to_date_output(job, fn, f2l_kw[9])) {
+ back = 0;
+ }
+ }
+ } break;
+ case FIG2LAT_DRIVER_EPS_WITH_TEX: {
+ if(fig2lat_up_to_date_output(job, fn, f2l_kw[6])) {
+ if(fig2lat_up_to_date_output(job, fn, f2l_kw[7])) {
+ back = 0;
+ }
+ }
+ } break;
+ case FIG2LAT_DRIVER_PDF_WITH_TEX: {
+ if(fig2lat_up_to_date_output(job, fn, f2l_kw[7])) {
+ if(fig2lat_up_to_date_output(job, fn, f2l_kw[8])) {
+ back = 0;
+ }
+ }
+ } break;
+ case FIG2LAT_DRIVER_EPS_STANDALONE: {
+ if(fig2lat_up_to_date_output(job, fn, f2l_kw[6])) {
+ back = 0;
+ }
+ } break;
+ case FIG2LAT_DRIVER_SVG_STANDALONE: {
+ if(fig2lat_up_to_date_output(job, fn, f2l_kw[5])) {
+ back = 0;
+ }
+ } break;
+ default: { /* PGF */
+ if(fig2lat_up_to_date_output(job, fn, f2l_kw[4])) {
+ back = 0;
+ }
+ } break;
+ }
+ } $? "- fig2lat_must_process_file %d", back
+ return back;
+}
+
+
+
+/** Process a directory.
+ @param job Job structure.
+ @param fn Directory name.
+*/
+static
+void
+fig2lat_run_for_directory(f2l_job_t *job, dkChar const *fn)
+{
+ dk3_dir_t *dir; /* Directory traversal. */
+ dkChar const *filename; /* Found file name. */
+ $? "+ fig2lat_run_for_directory \"%!ds\"", TR_STR(fn)
+ dir = dk3dir_open_app(fn, job->app);
+ if(dir) {
+ while(dk3dir_get_next_file(dir)) {
+ filename = dk3dir_get_fullname(dir);
+ if(filename) {
+ if(fig2lat_is_fig_file(filename)) {
+ if(fig2lat_must_process_file(job, filename)) {
+ fig2lat_run_for_file(job, filename);
+ }
+ }
+ } else { $? "! bug"
+ }
+ }
+ dk3dir_close(dir);
+ } else {
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ $? "- fig2lat_run_for_directory"
+}
+
+
+
+/** Run for file or directory name directly (no wildcards).
+ @param job Job structure.
+ @param fn File name (wildcards already resolved).
+*/
+static
+void
+fig2lat_run_for_file_directly(f2l_job_t *job, dkChar const *fn)
+{
+ dk3_stat_t stb; /* File information. */
+ $? "+ fig2lat_run_for_file_directly \"%!ds\"", TR_STR(fn)
+ if(dk3sf_stat_app(&stb, fn, job->app)) {
+ switch((stb.ft) & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_REGULAR: {
+ fig2lat_run_for_file(job, fn);
+ } break;
+ case DK3_FT_DIRECTORY: {
+ fig2lat_run_for_directory(job, fn);
+ } break;
+ default: {
+ /* ERROR: Neither directory nor regular file! */
+ job->exval = FIG2LAT_EXIT_ERROR_NO_SUCH_FILE; $? ". exitcode"
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 5);
+ } break;
+ }
+ } else { $? "! stat failed"
+ job->exval = FIG2LAT_EXIT_ERROR_NO_SUCH_FILE; $? ". exitcode"
+ }
+ $? "- fig2lat_run_for_file_directly"
+}
+
+
+
+/** Run for file or directory name (may contain wildcards).
+ @param job Job structure.
+ @param fn File name (may contain wildcards).
+*/
+static
+void
+fig2lat_run_for_name(f2l_job_t *job, dkChar const *fn)
+{
+ dkChar fnb[DK3_MAX_PATH]; /* Name buffer for modification. */
+ dkChar const *filename; /* File name found. */
+ dk3_dir_t *dir; /* Expander for wildcards. */
+ int found; /* Flag: Source file found. */
+ $? "+ fig2lat_run_for_name \"%!ds\"", TR_STR(fn)
+ if(dk3str_len(fn) < DK3_SIZEOF(fnb,dkChar)) {
+ dk3str_cpy_not_overlapped(fnb, fn);
+ dk3str_correct_filename(fnb);
+ if(dk3sf_must_expand(fnb)) {
+ dir = dk3dir_fne_open_app(fnb, job->app);
+ if(dir) {
+ found = 0;
+ while(dk3dir_get_next_file(dir)) {
+ filename = dk3dir_get_fullname(dir);
+ if(filename) {
+ if(fig2lat_is_fig_file(filename)) { $? ". fig file"
+ found = 1;
+ fig2lat_run_for_file(job, filename);
+ } else { $? ". other file"
+ }
+ } else { $? "! bug, no filename"
+ }
+ }
+ if(0 == found) {
+ job->exval = FIG2LAT_EXIT_ERROR_NO_SUCH_FILE; $? ". exitcode"
+ }
+ dk3dir_close(dir);
+ } else { $? "! fne_open"
+ job->exval = FIG2LAT_EXIT_ERROR_SYSTEM; $? ". exitcode"
+ }
+ } else {
+ fig2lat_run_for_file_directly(job, fnb);
+ }
+ } else { $? "! too long"
+ /* ERROR: File name too long! */
+ job->exval = FIG2LAT_EXIT_FILENAME_TOO_LONG; $? ". exitcode"
+ dk3app_log_2(job->app, DK3_LL_ERROR, job->msg, 2, fn);
+ } $? "- fig2lat_run_for_name"
+}
+
+
+
+/** Run for current directory.
+ @param job Job structure.
+*/
+static
+void
+fig2lat_run_for_current_directory(f2l_job_t *job)
+{
+ dkChar cwdbu[DK3_MAX_PATH]; /* Buffer for current working directory. */
+ $? "+ fig2lat_run_for_current_directory"
+ if(dk3sf_getcwd_app(cwdbu, DK3_SIZEOF(cwdbu,dkChar), job->app)) {
+ fig2lat_run_for_file_directly(job, cwdbu);
+ } else { $? "! getcwd"
+ f2l_tool_set_exit_status(job, FIG2LAT_EXIT_ERROR_SYSTEM); $? ". exitcode"
+ }
+ $? "- fig2lat_run_for_current_directory"
+}
+
+
+
+/** Run conversion as indicated by command line arguments.
+ @param job Job structure.
+*/
+static
+void
+fig2lat_run(f2l_job_t *job)
+{
+ dkChar const *fn; /* File name. */
+ int argc; /* Number of command line arguments. */
+ int i; /* Current command line argument processed. */
+ $? "+ fig2lat_run"
+ if((argc = dk3opt_get_num_args(job->opt)) > 0) { $? ". have arguments"
+ job->exval = FIG2LAT_EXIT_SUCCESS; $? ". exitcode-success"
+ for(i = 0; i < argc; i++) {
+ fn = dk3opt_get_arg(job->opt, i);
+ if(fn) {
+ fig2lat_run_for_name(job, fn);
+ } else {
+ job->exval = FIG2LAT_EXIT_ERROR_NO_SUCH_FILE; $? ". exitcode"
+ }
+ }
+ } else { $? ". no arguments"
+ fig2lat_run_for_current_directory(job);
+ }
+ $? "- fig2lat_run"
+}
+
+
+
+#if TRACE_DEBUG
+#if FIG2LAT_TEST_BEZIER
+static
+void
+fig2lat_test_bezier(void)
+{
+ double t;
+ size_t i;
+ t = 0.0;
+ for(i = 0; i <= 10; i++) {
+ printf("%g\t%g\n",t,dk3bezier_value(0.0,1.0,9.0,10.0,t,NULL));
+ t += 0.1;
+ }
+}
+#endif
+#endif
+
+
+/** Entry point.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, any other value indicates an error.
+*/
+DK3_MAIN
+{
+ f2l_job_t job; /* Job structure. */
+ dk3_app_t *app = NULL; /* Application structure. */
+ dkChar const * const *msg = NULL; /* Localized texts. */
+ dkChar const * const *figmsg = NULL; /* dk3fig module localized texts. */
+ int exval = FIG2LAT_EXIT_ERROR_UNKNOWN; /* Exit code. */
+ int testcmd; /* Mask for help/version/license. */
+ $!trace-init fig2lat.deb
+ $? "+ main"
+#if VERSION_BEFORE_20150821
+ exval = FIG2LAT_EXIT_ERROR_UNKNOWN;
+#endif
+ job.opt = NULL;
+ app = dk3app_open_command(
+ argc, (dkChar const * const *)argv, f2l_kw[0]
+ );
+ if(app) { $? ". app"
+ msg = dk3app_messages(
+ app, f2l_kw[1], (dkChar const **)f2l_default_messages
+ );
+ figmsg = dk3fig_get_localized_messages(app);
+#if TRACE_DEBUG
+#if FIG2LAT_TEST_BEZIER
+ fig2lat_test_bezier();
+#endif
+#endif
+ if(fig2lat_job_init(&job,app,msg,figmsg)) { $? ". init"
+ if(f2lopt_process(&job)) { $? ". option processing"
+ testcmd = DK3_APP_CMD_HELP | DK3_APP_CMD_VERSION | DK3_APP_CMD_LICENSE;
+ if((job.cmd) & testcmd) { $? ". help version license"
+ if(job.cmd) { $? ". show version information"
+ fig2lat_show_version(&job);
+ }
+ if((job.cmd) & DK3_APP_CMD_LICENSE) { $? ". show license"
+ fig2lat_show_license(&job);
+ }
+ if((job.cmd) & DK3_APP_CMD_HELP) { $? ". show help text"
+ fig2lat_show_help(&job);
+ }
+ job.exval = FIG2LAT_EXIT_SUCCESS;
+ } else { $? ". normal processing"
+ fig2lat_run(&job);
+ }
+ } else { $? "! option processing"
+ dk3app_log_1(job.app, DK3_LL_ERROR, job.msg, 6);
+ }
+ } else { $? "! init"
+ }
+ exval = job.exval;
+ dk3app_close(app); app = NULL;
+ } else { $? "! app"
+ fputs("fig2lat: ERROR: Not enough memory (RAM/swap)!\n", stderr);
+ fflush(stderr);
+ exval = FIG2LAT_EXIT_ERROR_SYSTEM;
+ }
+ fig2lat_job_end(&job);
+ $? "- main %d", exval
+ $!trace-end
+ fflush(stdout);
+ exit(exval); return exval;
+}
+
+
diff --git a/support/dktools/fig2lat.h b/support/dktools/fig2lat.h
new file mode 100644
index 0000000000..7a0ecd9113
--- /dev/null
+++ b/support/dktools/fig2lat.h
@@ -0,0 +1,244 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: fig2lat.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file fig2lat.h Header file for the fig2lat module.
+*/
+
+#ifndef FIG2LAT_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define FIG2LAT_H_INCLUDED 1
+
+
+#line 10 "fig2lat.ctr"
+
+#include "dk3fig.h"
+#include "dk3figrd.h"
+#include "dk3figpr.h"
+
+
+/** To draw a quadrant of a circle we do not use 1/3 of the
+ derivative, we use another factor instead.
+*/
+#define FIG2LAT_CIRCLE_QUADRANT_BEZIER 0.5522847498307932
+
+
+
+/** Conversion configuration.
+*/
+typedef struct {
+ double nts; /**< Normal text size (scale factor or -1.0). */
+ int ntf; /**< Normal text font (0=similar, 1=fig). */
+} fig2lat_config_t;
+
+
+
+/** How to handle a text.
+*/
+typedef struct {
+ double fontSize; /**< Font size in pt. */
+ unsigned long fontNumber; /**< Unique font number for LaTeX output. */
+ int psFontNo; /**< PS font number. */
+} f2l_text_handling_t;
+
+
+
+/** Image structure.
+*/
+typedef struct {
+ dk3_ufi_t ufi; /**< Unique file identifier image. */
+ char const *filename; /**< Image file name. */
+ dk3_pdf_xobject_t *xo; /**< PDF X object. */
+ dk3_bif_coord_t width; /**< Image width. */
+ dk3_bif_coord_t height; /**< Image height. */
+ double xres; /**< X resolution. */
+ double yres; /**< Y resolution. */
+ unsigned long imageNumber; /**< Unique number of image. */
+ unsigned long lineno; /**< Line number of object. */
+} f2l_image_t;
+
+
+
+/** Fig2lat job structure.
+*/
+typedef struct {
+ /* @DRIVER@
+ You can add driver-specific configuration compomenents here.
+ For alignment reasons the order of elements is in decreasing
+ type size.
+ Remember to re-compile all modules after changing data types.
+ Initialize the new components in fig2lat_job_init(),
+ release allocated resources in fig2lat_job_end().
+ */
+ dk3_graphics_state_t gs; /**< Graphics state. */
+ dk3_ct_2d_t ct2d; /**< Coordinates transformation data. */
+ dk3_fig_drawing_t *drw; /**< Fig drawing to convert. */
+ dk3_app_t *app; /**< Application structure. */
+ dk3_option_set_t *opt; /**< Options and cmd arguments. */
+ FILE *of1; /**< Output file 1. */
+ FILE *of2; /**< Output file 2. */
+ dkChar const *on1; /**< Output file name 1. */
+ dkChar const *on2; /**< Output file name 2. */
+ dkChar const * const *msg; /**< Localized text messages. */
+ dkChar const * const *figmsg; /**< Localized messages dk3fig mod. */
+ double width; /**< Width (typically in bp). */
+ double height; /**< Height (typically in bp). */
+ double w2; /**< Secondary width information. */
+ double h2; /**< Secondary height information. */
+ double nts; /**< Normal text size. */
+ double tts; /**< TeX text size. */
+ double arcspp; /**< Spline points per arc. */
+ double splspp; /**< Spline points per interval. */
+ double xsprec; /**< Iteration precision. */
+ double lwbp; /**< Line width in bp. */
+ long lwidth; /**< Width in bp. */
+ long lheight; /**< Height in bp. */
+ size_t xssbs; /**< X-spline segement Bezier segs. */
+ size_t minspp; /**< Minimum spline points. */
+ size_t qbs; /**< Quadrant Bezier segments. */
+ size_t codi; /**< Color digits. */
+ int ntf; /**< Text font (0=similar, 1=fig). */
+ int dr; /**< Driver, see @ref fig2latdrivers. */
+ int exval; /**< Exit, see @ref fig2latexitcodes. */
+ int mm; /**< Flag: Make mode. */
+ int cmd; /**< Command to execute. */
+ int cosp; /**< Flag: Spline compatibility. */
+ int coah; /**< Flag: Arrowhead compatibility. */
+ int xsah; /**< Flag: X-spline arrowhead. */
+ int debug; /**< Flag: Write debug information. */
+ int showpage; /**< Flag: Write showpage operator. */
+ int pslevel; /**< PS language level. */
+ int dsc; /**< Flag: Write PS DSC. */
+ int srctype; /**< Source file type. */
+ int smash; /**< Flag: Use smash instruction. */
+ int mbox; /**< Flag: Use mbox instruction. */
+ int resfont; /**< Flag: Use reset@font. */
+ int css; /**< Flag: CSS-styled SVG. */
+ int fragment; /**< Flag: Write SVG fragment only. */
+ int svgfontbase; /**< SVG font base: 0=none, 1=local, 2=web. */
+ int group; /**< Flag: Group SVG object with ahs. */
+ int miterlim; /**< Flag: Write miterlimit. */
+ int cols; /**< Flag: Compatible line styles. */
+ int otherfonts; /**< Flag: Use additional fonts SVG. */
+ int bbts; /**< Flag: Use text size for bb. */
+ int stu8; /**< Flag: Special text uses UTF-8. */
+ int cofop; /**< Flag: Compat fill open paths. */
+ int lwauto; /**< Flag: Automatic line width. */
+} f2l_job_t;
+
+
+
+/** @defgroup fig2latexitcodes Exit codes for fig2lat.
+*/
+/**@{*/
+
+/** Program succeeded.
+*/
+#define FIG2LAT_EXIT_SUCCESS 0
+
+/** Error occured, no detailed description.
+*/
+#define FIG2LAT_EXIT_ERROR_UNKNOWN 1
+
+/** Error, no file found to convert.
+*/
+#define FIG2LAT_EXIT_ERROR_NO_SUCH_FILE 2
+
+/** File name is too long for processing.
+*/
+#define FIG2LAT_EXIT_FILENAME_TOO_LONG 3
+
+/** Resources problem or system error.
+*/
+#define FIG2LAT_EXIT_ERROR_SYSTEM 4
+
+/** Mathematical error.
+*/
+#define FIG2LAT_EXIT_ERROR_MATH 5
+
+/** Syntax error in input file.
+*/
+#define FIG2LAT_EXIT_ERROR_SYNTAX 6
+/**@}*/
+
+
+
+/** @defgroup fig2latdrivers Fig2lat output drivers.
+*/
+
+/**@{*/
+
+/** Produce PGF output file (default driver).
+*/
+#define FIG2LAT_DRIVER_PGF 0
+
+/** Produce full *.tex file, image as embedded PGF.
+*/
+#define FIG2LAT_DRIVER_TEX_FULL_PGF 1
+
+/** Produce full *.tex file, image as included external PDF.
+*/
+#define FIG2LAT_DRIVER_TEX_FULL_PDF 2
+
+/** Produce *.tex file including an external EPS.
+*/
+#define FIG2LAT_DRIVER_EPS_WITH_TEX 3
+
+/** Produce *.tex file including an external PDF.
+*/
+#define FIG2LAT_DRIVER_PDF_WITH_TEX 4
+
+/** Produce standalone EPS file.
+*/
+#define FIG2LAT_DRIVER_EPS_STANDALONE 5
+
+/** Produce standalone SVG file.
+*/
+#define FIG2LAT_DRIVER_SVG_STANDALONE 6
+
+/* @DRIVER@
+ Add new driver numbers above this comment.
+ The driver numbers must correspond to the order of
+ driver names in f2lopt.ctr in the f2lopt_language_names array.
+*/
+
+/**@}*/
+
+
+
+#include "f2lopt.h"
+#include "f2lto.h"
+
+
+#endif
diff --git a/support/dktools/fig2lat.rc b/support/dktools/fig2lat.rc
new file mode 100644
index 0000000000..ea406270ca
--- /dev/null
+++ b/support/dktools/fig2lat.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Fig to LaTeX converter\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "Fig to LaTeX converter\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "fig2lat\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/filelist.txt b/support/dktools/filelist.txt
new file mode 100644
index 0000000000..dad3dd1fde
--- /dev/null
+++ b/support/dktools/filelist.txt
@@ -0,0 +1,2472 @@
+README
+INSTALL
+version.txt
+dk4pref.conf
+etc-dk3app/dk3paper.conf
+addctrld.ctr
+bmeps3.ctr
+bsdlic.txt
+changes.dox
+libdk4pppt.dox
+config.h.in
+configure
+configure.ac
+configure.out
+conf.vc
+dk3all.h
+dk3app.ctr
+dk3appr.ctr
+dk3bb.ctr
+dk3bezcu.ctr
+dk3bf.ctr
+dk3bifa.ctr
+dk3bif.ctr
+dk3bits.ctr
+dk3bm.ctr
+dk3bmeo.ctr
+dk3bmep.ctr
+dk3bmeps.ctr
+dk3bmj.ctr
+dk3bom.ctr
+dk3chks.ctr
+dk3confd.h
+dk3conf.h
+dk3config.c
+dk3conft.h
+dk3const.h
+dk3cores.ctr
+dk3ct.ctr
+dk3dbi.ctr
+dk3dir.ctr
+dk3echo.ctr
+dk3enc.ctr
+dk3figah.ctr
+dk3figbb.ctr
+dk3fig.ctr
+dk3figpr.ctr
+dk3figrd.ctr
+dk3figto.ctr
+dk3font.ctr
+dk3.h
+dk3info1.c
+dk3info.ctr
+dk3inst.c
+dk3inst.h
+dk3kv.ctr
+dk3mad.ctr
+dk3madfo.ctr
+dk3madic.ctr
+dk3madlc.ctr
+dk3madsc.ctr
+dk3madsi.ctr
+dk3madso.ctr
+dk3mafpe.ctr
+dk3ma.h
+dk3mai.ctr
+dk3maid8.ctr
+dk3maidd.ctr
+dk3maih8.ctr
+dk3maihd.ctr
+dk3mal.ctr
+dk3maod8.ctr
+dk3maodd.ctr
+dk3maoh8.ctr
+dk3maohd.ctr
+dk3mas.ctr
+dk3masts.ctr
+dk3maui.ctr
+dk3maul.ctr
+dk3maus.ctr
+dk3md.ctr
+dk3mem.ctr
+dk3nettp.h
+dk3numco.h
+dk3of.ctr
+dk3opt.ctr
+dk3paper.ctr
+dk3pdf.ctr
+dk3pixre.ctr
+dk3prcfg.ctr
+dk3print.ctr
+dk3prreq.ctr
+dk3range.h
+dk3se.ctr
+dk3sf.ctr
+dk3signl.ctr
+dk3sock4.ctr
+dk3sock.ctr
+dk3srch.ctr
+dk3stm.h
+dk3sto.ctr
+dk3str.ctr
+dk3strkv.ctr
+dk3strmb.ctr
+dk3strm.ctr
+dk3strmg.ctr
+dk3trace.ctr
+dk3types.h
+dk3uc2l.ctr
+dk3ufi.ctr
+dk3usewx.c
+dk3wreg.ctr
+dk3wxcs.h
+dk3wxs.cpt
+dk3xsp.ctr
+dk4a85d.ctr
+dk4a85e.ctr
+dk4ahd.ctr
+dk4align.h
+dk4ansi.c
+dk4ansi.ctr
+dk4ansi.h
+dk4aopt01.c
+dk4aopt01.ctr
+dk4aopt02.c
+dk4aopt02.ctr
+dk4aopt03.c
+dk4aopt03.ctr
+dk4aopt04.c
+dk4aopt04.ctr
+dk4aopt05.c
+dk4aopt05.ctr
+dk4aopt06.c
+dk4aopt06.ctr
+dk4aopt07.c
+dk4aopt07.ctr
+dk4aopt08.c
+dk4aopt08.ctr
+dk4aopt09.c
+dk4aopt09.ctr
+dk4aopt10.c
+dk4aopt10.ctr
+dk4aopt11.c
+dk4aopt11.ctr
+dk4aopt12.c
+dk4aopt12.ctr
+dk4aopt13.c
+dk4aopt13.ctr
+dk4aopt14.c
+dk4aopt14.ctr
+dk4aopt15.ctr
+dk4aopt16.ctr
+dk4aopt.h
+dk4appargs.c
+dk4appargs.ctr
+dk4app/de/dk4base.str
+dk4app/de/dk4sock.str
+dk4app/de/dk4wxbase.str
+dk4app/de/dk4debug.str
+dk4appdeldir.c
+dk4appdeldir.ctr
+dk4appdelfile.c
+dk4appdelfile.ctr
+dk4appdeltree.c
+dk4appdeltree.ctr
+dk4appenc.c
+dk4appenc.ctr
+dk4appfne.c
+dk4appfne.ctr
+dk4appfs01.c
+dk4appfs01.ctr
+dk4appfs02.c
+dk4appfs02.ctr
+dk4appfs03.c
+dk4appfs03.ctr
+dk4appfs04.c
+dk4appfs04.ctr
+dk4app.h
+dk4apphlv.c
+dk4apphlv.ctr
+dk4appi.c
+dk4applog.c
+dk4applog.ctr
+dk4appmkdh.c
+dk4appmkdh.ctr
+dk4appmkdh.h
+dk4appop.c
+dk4appop.ctr
+dk4appstt.c
+dk4appstt.ctr
+dk4apref.c
+dk4apref.ctr
+dk4aprgs.c
+dk4aprgs.ctr
+dk4bf.ctr
+dk4binenc.ctr
+dk4bitsh.ctr
+dk4bom.c
+dk4bom.ctr
+dk4bom.h
+dk4c32.c
+dk4c32.ctr
+dk4c32.h
+dk4c8dbl.ctr
+Dk4Comparable.cpt
+dk4conf.h
+dk4config.cpp
+dk4const.h
+Dk4Container.cpt
+dk4ctime.c
+dk4ctime.ctr
+dk4ctime.h
+dk4dblc8.c
+dk4dblc8.ctr
+dk4dblc8.h
+dk4dbldk.c
+dk4dbldk.ctr
+dk4dbldk.h
+dk4dblwc.c
+dk4dblwc.ctr
+dk4dblwc.h
+dk4dec.h
+dk4deldir08.c
+dk4deldir08.ctr
+dk4deldir08.h
+dk4deldir.c
+dk4deldir.ctr
+dk4deldir.h
+dk4deldirwc.c
+dk4deldirwc.ctr
+dk4deldirwc.h
+dk4delfile08.c
+dk4delfile08.ctr
+dk4delfile08.h
+dk4delfile.c
+dk4delfile.ctr
+dk4delfile.h
+dk4delfilewc.c
+dk4delfilewc.ctr
+dk4delfilewc.h
+dk4dir08.c
+dk4dir08.ctr
+dk4dir08.h
+dk4dira.ctr
+dk4dir.c
+dk4dir.ctr
+dk4dir.h
+dk4dirwc.c
+dk4dirwc.ctr
+dk4dirwc.h
+dk4.dox
+libdk4app.dox
+splash-dktoolian.eps
+sttfiles.dox
+conceptions.dox
+libdk4lat.dox
+dk4edstm.h
+dk4enc.c
+dk4enc.ctr
+dk4enc.h
+dk4error.c
+dk4error.ctr
+dk4error.h
+dk4exep8.c
+dk4exep8.ctr
+dk4exep8.h
+dk4exep.c
+dk4exepd.c
+dk4exepd.ctr
+dk4exepd.h
+dk4exepw.c
+dk4exepw.ctr
+dk4exepw.h
+Dk4FcsApp.cpt
+Dk4FcsFrame.wxc
+Dk4FcsThread.cpp
+Dk4FcsThread.h
+dk4fd.c
+dk4fd.ctr
+dk4fd.h
+dk4fdrda.c
+dk4fdrda.ctr
+dk4fdrda.h
+dk4fdrde.c
+dk4fdrde.ctr
+dk4fdrde.h
+dk4fdwre.c
+dk4fdwre.ctr
+dk4fdwre.h
+dk4file8.c
+dk4file8.ctr
+dk4file8.h
+dk4filed.c
+dk4filed.ctr
+dk4filed.h
+dk4filei8.c
+dk4filei8.ctr
+dk4filei8.h
+dk4fileia.ctr
+dk4filei.c
+dk4filei.ctr
+dk4fileid.c
+dk4fileid.ctr
+dk4fileid.h
+dk4fileig8.c
+dk4fileig8.ctr
+dk4fileig8.h
+dk4fileigd.c
+dk4fileigd.ctr
+dk4fileigw.c
+dk4fileigw.ctr
+dk4filei.h
+dk4fileit.h
+dk4fileiu.c
+dk4fileiu.ctr
+dk4fileiu.h
+dk4fileiw.c
+dk4fileiw.ctr
+dk4fileiw.h
+dk4filew.c
+dk4filew.ctr
+dk4filew.h
+dk4fne08.c
+dk4fne08.ctr
+dk4fne08.h
+dk4fne.c
+dk4fne.ctr
+dk4fne.h
+dk4fnewc.c
+dk4fnewc.ctr
+dk4fnewc.h
+dk4font.ctr
+dk4fopc8.c
+dk4fopc8.ctr
+dk4fopc8.h
+dk4fopda.c
+dk4fopda.ctr
+dk4fopda.h
+dk4fopd.c
+dk4fopd.ctr
+dk4fopd.h
+dk4fopt.h
+dk4fopwc.c
+dk4fopwc.ctr
+dk4fopwc.h
+dk4fput.c
+dk4fput.ctr
+dk4fput.h
+dk4fs.c
+dk4fs.ctr
+dk4fs.h
+dk4ft.h
+dk4ftime08.c
+dk4ftime08.ctr
+dk4ftime.c
+dk4ftime.ctr
+dk4ftimedk.c
+dk4ftimedk.ctr
+dk4ftime.h
+dk4ftimewc.c
+dk4ftimewc.ctr
+dk4fwra.ctr
+dk4getcwd8.ctr
+dk4getcwdd.ctr
+dk4getcwdw.ctr
+dk4getpid.c
+dk4getpid.ctr
+dk4getpid.h
+dk4.h
+dk4hname8.c
+dk4hname8.ctr
+dk4hname8.h
+dk4hnamed.c
+dk4hnamed.ctr
+dk4hnamed.h
+dk4hnamew.c
+dk4hnamew.ctr
+dk4hnamew.h
+dk4info1.c
+dk4info.ctr
+dk4inst.c
+dk4inst.h
+dk4isadm.ctr
+dk4istty.c
+dk4istty.ctr
+dk4istty.h
+dk4loc.c
+dk4loc.ctr
+dk4loc.h
+dk4lzwe.ctr
+dk4maac.c
+dk4maac.ctr
+dk4maac.h
+dk4maadi.c
+dk4maadi.ctr
+dk4maadi.h
+dk4maadu.c
+dk4maadu.ctr
+dk4maadu.h
+dk4maai.c
+dk4maai.ctr
+dk4maai.h
+dk4maal.c
+dk4maal.ctr
+dk4maal.h
+dk4maall.c
+dk4maall.ctr
+dk4maall.h
+dk4maalu.c
+dk4maalu.ctr
+dk4maalu.h
+dk4maami.c
+dk4maami.ctr
+dk4maami.h
+dk4maamu.c
+dk4maamu.ctr
+dk4maamu.h
+dk4maas.c
+dk4maas.ctr
+dk4maas.h
+dk4maasz.c
+dk4maasz.ctr
+dk4maasz.h
+dk4maauc.c
+dk4maauc.ctr
+dk4maauc.h
+dk4maaui.c
+dk4maaui.ctr
+dk4maaui.h
+dk4maaul.c
+dk4maaul.ctr
+dk4maaul.h
+dk4maaus.c
+dk4maaus.ctr
+dk4maaus.h
+dk4macc.c
+dk4macc.ctr
+dk4macc.h
+dk4macd.c
+dk4macd.ctr
+dk4macd.h
+dk4maci.c
+dk4maci.ctr
+dk4maci.h
+dk4macl.c
+dk4macl.ctr
+dk4macl.h
+dk4macll.c
+dk4macll.ctr
+dk4macll.h
+dk4macm.c
+dk4macm.ctr
+dk4macm.h
+dk4macs.c
+dk4macs.ctr
+dk4macs.h
+dk4ma.h
+dk4mai8dbl.c
+dk4mai8dbl.ctr
+dk4mai8dbl.h
+dk4mai8ddi.c
+dk4mai8ddi.ctr
+dk4mai8ddi.h
+dk4mai8ddu.c
+dk4mai8ddu.ctr
+dk4mai8ddu.h
+dk4mai8dic.c
+dk4mai8dic.ctr
+dk4mai8dic.h
+dk4mai8dii.c
+dk4mai8dii.ctr
+dk4mai8dii.h
+dk4mai8dil.c
+dk4mai8dil.ctr
+dk4mai8dil.h
+dk4mai8dis.c
+dk4mai8dis.ctr
+dk4mai8dis.h
+dk4mai8dli.c
+dk4mai8dli.ctr
+dk4mai8dli.h
+dk4mai8dlu.c
+dk4mai8dlu.ctr
+dk4mai8dlu.h
+dk4mai8dmi.c
+dk4mai8dmi.ctr
+dk4mai8dmi.h
+dk4mai8dmu.c
+dk4mai8dmu.ctr
+dk4mai8dmu.h
+dk4mai8dsz.c
+dk4mai8dsz.ctr
+dk4mai8dsz.h
+dk4mai8duc.c
+dk4mai8duc.ctr
+dk4mai8duc.h
+dk4mai8dui.c
+dk4mai8dui.ctr
+dk4mai8dui.h
+dk4mai8dul.c
+dk4mai8dul.ctr
+dk4mai8dul.h
+dk4mai8dus.c
+dk4mai8dus.ctr
+dk4mai8dus.h
+dk4mai8hdi.c
+dk4mai8hdi.ctr
+dk4mai8hdi.h
+dk4mai8hdu.c
+dk4mai8hdu.ctr
+dk4mai8hdu.h
+dk4mai8hic.c
+dk4mai8hic.ctr
+dk4mai8hic.h
+dk4mai8hii.c
+dk4mai8hii.ctr
+dk4mai8hii.h
+dk4mai8hil.c
+dk4mai8hil.ctr
+dk4mai8hil.h
+dk4mai8his.c
+dk4mai8his.ctr
+dk4mai8his.h
+dk4mai8hli.c
+dk4mai8hli.ctr
+dk4mai8hli.h
+dk4mai8hlu.c
+dk4mai8hlu.ctr
+dk4mai8hlu.h
+dk4mai8hmi.c
+dk4mai8hmi.ctr
+dk4mai8hmi.h
+dk4mai8hmu.c
+dk4mai8hmu.ctr
+dk4mai8hmu.h
+dk4mai8huc.c
+dk4mai8huc.ctr
+dk4mai8huc.h
+dk4mai8hui.c
+dk4mai8hui.ctr
+dk4mai8hui.h
+dk4mai8hul.c
+dk4mai8hul.ctr
+dk4mai8hul.h
+dk4mai8hus.c
+dk4mai8hus.ctr
+dk4mai8hus.h
+dk4maiddbl.c
+dk4maiddbl.ctr
+dk4maiddbl.h
+dk4maidddi.c
+dk4maidddi.ctr
+dk4maidddi.h
+dk4maidddu.c
+dk4maidddu.ctr
+dk4maidddu.h
+dk4maiddic.c
+dk4maiddic.ctr
+dk4maiddic.h
+dk4maiddii.c
+dk4maiddii.ctr
+dk4maiddii.h
+dk4maiddil.c
+dk4maiddil.ctr
+dk4maiddil.h
+dk4maiddis.c
+dk4maiddis.ctr
+dk4maiddis.h
+dk4maiddli.c
+dk4maiddli.ctr
+dk4maiddli.h
+dk4maiddlu.c
+dk4maiddlu.ctr
+dk4maiddlu.h
+dk4maiddmi.c
+dk4maiddmi.ctr
+dk4maiddmi.h
+dk4maiddmu.c
+dk4maiddmu.ctr
+dk4maiddmu.h
+dk4maiddsz.c
+dk4maiddsz.ctr
+dk4maiddsz.h
+dk4maidduc.c
+dk4maidduc.ctr
+dk4maidduc.h
+dk4maiddui.c
+dk4maiddui.ctr
+dk4maiddui.h
+dk4maiddul.c
+dk4maiddul.ctr
+dk4maiddul.h
+dk4maiddus.c
+dk4maiddus.ctr
+dk4maiddus.h
+dk4maidhdi.c
+dk4maidhdi.ctr
+dk4maidhdi.h
+dk4maidhdu.c
+dk4maidhdu.ctr
+dk4maidhdu.h
+dk4maidhic.c
+dk4maidhic.ctr
+dk4maidhic.h
+dk4maidhii.c
+dk4maidhii.ctr
+dk4maidhii.h
+dk4maidhil.c
+dk4maidhil.ctr
+dk4maidhil.h
+dk4maidhis.c
+dk4maidhis.ctr
+dk4maidhis.h
+dk4maidhli.c
+dk4maidhli.ctr
+dk4maidhli.h
+dk4maidhlu.c
+dk4maidhlu.ctr
+dk4maidhlu.h
+dk4maidhmi.c
+dk4maidhmi.ctr
+dk4maidhmi.h
+dk4maidhmu.c
+dk4maidhmu.ctr
+dk4maidhmu.h
+dk4maidhsz.c
+dk4maidhsz.ctr
+dk4maidhsz.h
+dk4maidhuc.c
+dk4maidhuc.ctr
+dk4maidhuc.h
+dk4maidhui.c
+dk4maidhui.ctr
+dk4maidhui.h
+dk4maidhul.c
+dk4maidhul.ctr
+dk4maidhul.h
+dk4maidhus.c
+dk4maidhus.ctr
+dk4maidhus.h
+dk4maiwdbl.c
+dk4maiwdbl.ctr
+dk4maiwdbl.h
+dk4maiwddi.c
+dk4maiwddi.ctr
+dk4maiwddi.h
+dk4maiwddu.c
+dk4maiwddu.ctr
+dk4maiwddu.h
+dk4maiwdic.c
+dk4maiwdic.ctr
+dk4maiwdic.h
+dk4maiwdii.c
+dk4maiwdii.ctr
+dk4maiwdii.h
+dk4maiwdil.c
+dk4maiwdil.ctr
+dk4maiwdil.h
+dk4maiwdis.c
+dk4maiwdis.ctr
+dk4maiwdis.h
+dk4maiwdli.c
+dk4maiwdli.ctr
+dk4maiwdli.h
+dk4maiwdlu.c
+dk4maiwdlu.ctr
+dk4maiwdlu.h
+dk4maiwdmi.c
+dk4maiwdmi.ctr
+dk4maiwdmi.h
+dk4maiwdmu.c
+dk4maiwdmu.ctr
+dk4maiwdmu.h
+dk4maiwdsz.c
+dk4maiwdsz.ctr
+dk4maiwdsz.h
+dk4maiwduc.c
+dk4maiwduc.ctr
+dk4maiwduc.h
+dk4maiwdui.c
+dk4maiwdui.ctr
+dk4maiwdui.h
+dk4maiwdul.c
+dk4maiwdul.ctr
+dk4maiwdul.h
+dk4maiwdus.c
+dk4maiwdus.ctr
+dk4maiwdus.h
+dk4maiwhdi.c
+dk4maiwhdi.ctr
+dk4maiwhdi.h
+dk4maiwhdu.c
+dk4maiwhdu.ctr
+dk4maiwhdu.h
+dk4maiwhic.c
+dk4maiwhic.ctr
+dk4maiwhic.h
+dk4maiwhii.c
+dk4maiwhii.ctr
+dk4maiwhii.h
+dk4maiwhil.c
+dk4maiwhil.ctr
+dk4maiwhil.h
+dk4maiwhis.c
+dk4maiwhis.ctr
+dk4maiwhis.h
+dk4maiwhli.c
+dk4maiwhli.ctr
+dk4maiwhli.h
+dk4maiwhlu.c
+dk4maiwhlu.ctr
+dk4maiwhlu.h
+dk4maiwhmi.c
+dk4maiwhmi.ctr
+dk4maiwhmi.h
+dk4maiwhmu.c
+dk4maiwhmu.ctr
+dk4maiwhmu.h
+dk4maiwhuc.c
+dk4maiwhuc.ctr
+dk4maiwhuc.h
+dk4maiwhui.c
+dk4maiwhui.ctr
+dk4maiwhui.h
+dk4maiwhul.c
+dk4maiwhul.ctr
+dk4maiwhul.h
+dk4maiwhus.c
+dk4maiwhus.ctr
+dk4maiwhus.h
+dk4maixdbl.cpt
+dk4maixddi.cpt
+dk4maixddu.cpt
+dk4maixdic.cpt
+dk4maixdii.cpt
+dk4maixdil.cpt
+dk4maixdis.cpt
+dk4maixdli.cpt
+dk4maixdlu.cpt
+dk4maixdmi.cpt
+dk4maixdmu.cpt
+dk4maixdsz.cpt
+dk4maixduc.cpt
+dk4maixdui.cpt
+dk4maixdul.cpt
+dk4maixdus.cpt
+dk4maoxdbl.cpt
+dk4maoxd.cpt
+dk4mao8d.c
+dk4mao8d.ctr
+dk4mao8d.h
+dk4mao8h.c
+dk4mao8h.ctr
+dk4mao8h.h
+dk4maodd.c
+dk4maodd.ctr
+dk4maodd.h
+dk4maodh.c
+dk4maodh.ctr
+dk4maodh.h
+dk4maodo.ctr
+dk4maowd.c
+dk4maowd.ctr
+dk4maowd.h
+dk4maowh.c
+dk4maowh.ctr
+dk4maowh.h
+dk4mbstrm.ctr
+dk4fpe.ctr
+dk4maai16.ctr
+dk4maai32.ctr
+dk4maau16.ctr
+dk4maau32.ctr
+dk4maci16.ctr
+dk4maci32.ctr
+dk4mao8dbl.ctr
+dk4maoddbl.ctr
+dk4maowdbl.ctr
+dk4papea.ctr
+dk4paper.ctr
+dk4serf.ctr
+dk4strmco.ctr
+dk4strms.ctr
+dk4strmu.ctr
+dk4svbufa.ctr
+dk4svbuf.ctr
+dk4userf.ctr
+dk4strmw.ctr
+dk4svg.ctr
+dk4svgop.ctr
+dk4masz.c
+dk4masz.ctr
+dk4masz.h
+dk4mdch.ctr
+dk4md.ctr
+dk4mema.c
+dk4mema.ctr
+dk4mema.h
+dk4membf.ctr
+dk4membs.ctr
+dk4membuf.ctr
+dk4mem.c
+dk4memcpl.ctr
+dk4mem.ctr
+dk4mem.h
+dk4memrs.c
+dk4memrs.ctr
+dk4memrs.h
+dk4mkdh8.c
+dk4mkdh8.ctr
+dk4mkdh8.h
+dk4mkdh.c
+dk4mkdh.ctr
+dk4mkdh.h
+dk4mkdhw.c
+dk4mkdhw.ctr
+dk4mkdhw.h
+dk4mm.ctr
+dk4mm.h
+dk4mm.c
+dk4mpl.h
+dk4numco.h
+dk4numl.c
+dk4numl.ctr
+dk4numl.h
+dk4opt01.c
+dk4opt01.ctr
+dk4opt02.c
+dk4opt02.ctr
+dk4opt03.c
+dk4opt03.ctr
+dk4opt04.c
+dk4opt04.ctr
+dk4opt05.c
+dk4opt05.ctr
+dk4opt06.c
+dk4opt06.ctr
+dk4opt07.c
+dk4opt07.ctr
+dk4opt.c
+dk4opt.ctr
+dk4opt.h
+dk4path8.c
+dk4path8.ctr
+dk4path8.h
+dk4path.c
+dk4path.ctr
+dk4pathd.c
+dk4pathd.ctr
+dk4pathd.h
+dk4pathw.c
+dk4pathw.ctr
+dk4pathw.h
+dk4pref.c
+dk4pref.ctr
+dk4pref.h
+dk4rec01.c
+dk4rec01.ctr
+dk4rec01.h
+dk4rec02.c
+dk4rec02.ctr
+dk4rec02.h
+dk4rec03.c
+dk4rec03.ctr
+dk4rec03.h
+dk4rec04.c
+dk4rec04.ctr
+dk4rec04.h
+dk4rec05.c
+dk4rec05.ctr
+dk4rec05.h
+dk4rec06.c
+dk4rec06.ctr
+dk4rec06.h
+dk4rec07.c
+dk4rec07.ctr
+dk4rec07.h
+dk4rec08.c
+dk4rec08.ctr
+dk4rec08.h
+dk4rec09.c
+dk4rec09.ctr
+dk4rec09.h
+dk4rec10.c
+dk4rec10.ctr
+dk4rec10.h
+dk4rec11.c
+dk4rec11.ctr
+dk4rec11.h
+dk4rec12.c
+dk4rec12.ctr
+dk4rec12.h
+dk4rec13.c
+dk4rec13.ctr
+dk4rec13.h
+dk4rec14.c
+dk4rec14.ctr
+dk4rec14.h
+dk4rec15.c
+dk4rec15.ctr
+dk4rec15.h
+dk4rec16.c
+dk4rec16.ctr
+dk4rec16.h
+dk4rec17.c
+dk4rec17.ctr
+dk4rec17.h
+dk4rec18.c
+dk4rec18.ctr
+dk4rec18.h
+dk4rec19.c
+dk4rec19.ctr
+dk4rec19.h
+dk4rec20.c
+dk4rec20.ctr
+dk4rec20.h
+dk4rec21.c
+dk4rec21.ctr
+dk4rec21.h
+dk4rec22.c
+dk4rec22.ctr
+dk4rec22.h
+dk4rec23.c
+dk4rec23.ctr
+dk4rec23.h
+dk4rec24.ctr
+dk4rec25.ctr
+dk4rec.h
+dk4recwx.cpt
+dk4rld.ctr
+dk4rle.ctr
+dk4sock01.ctr
+dk4sock02.ctr
+dk4sock03.ctr
+dk4sock04.ctr
+dk4sock05.ctr
+dk4sock06.ctr
+dk4sock07.ctr
+dk4sock08.ctr
+dk4sock09.ctr
+dk4sock10.ctr
+dk4sock11.ctr
+dk4sock12.ctr
+dk4sock13.ctr
+dk4sock14.ctr
+dk4sock15.ctr
+dk4sock16.ctr
+dk4sock17.ctr
+dk4sock18.ctr
+dk4sock19.ctr
+dk4sock20.ctr
+dk4sock21.ctr
+dk4sock22.ctr
+dk4sock23.ctr
+dk4sock24.ctr
+dk4sock25.ctr
+dk4sock26.ctr
+dk4sock27.ctr
+dk4sock28.ctr
+dk4sock29.ctr
+dk4sock30.ctr
+dk4sock31.ctr
+dk4sock32.ctr
+dk4sock33.ctr
+dk4sock34.ctr
+dk4sock35.ctr
+dk4sock36.ctr
+dk4sock37.ctr
+
+dk4sock3.ctr
+dk4socka01.ctr
+dk4socka02.ctr
+dk4socka03.ctr
+dk4socka04.ctr
+dk4socka05.ctr
+dk4socka06.ctr
+dk4socka07.ctr
+dk4socka08.ctr
+dk4socka09.ctr
+dk4socka.h
+dk4sock.h
+libdk4sock.dox
+libdk4socka.dox
+libdk4mdrnd.dox
+libdk4dbia.dox
+dk4stat8.c
+dk4stat8.ctr
+dk4stat8.h
+dk4stat.c
+dk4stat.ctr
+dk4statd.c
+dk4statd.ctr
+dk4statd.h
+dk4stat.h
+dk4statt.h
+dk4statw.c
+dk4statw.ctr
+dk4statw.h
+dk4sto.c
+dk4sto.ctr
+dk4sto.h
+dk4str8.c
+dk4str8.ctr
+dk4str8.h
+dk4str.c
+dk4strda.c
+dk4strda.ctr
+dk4strda.h
+dk4strd.c
+dk4strd.ctr
+dk4strd.h
+dk4strmb.c
+dk4strmb.ctr
+dk4strmb.h
+dk4strm.c
+dk4strm.ctr
+dk4strmf.c
+dk4strmf.ctr
+dk4strmf.h
+dk4strmg.c
+dk4strmg.ctr
+dk4strmg.h
+dk4strm.h
+dk4strmh.c
+dk4strmh.ctr
+dk4strmh.h
+dk4strmo08.c
+dk4strmo08.ctr
+dk4strmo08.h
+dk4strmo16.c
+dk4strmo16.ctr
+dk4strmo16.h
+dk4strmo32.c
+dk4strmo32.ctr
+dk4strmo32.h
+dk4strmodk.c
+dk4strmodk.ctr
+dk4strmodk.h
+dk4strmr.c
+dk4strmr.ctr
+dk4strmr.h
+dk4strw.c
+dk4strw.ctr
+dk4strw.h
+dk4strx.cpt
+dk4stt.c
+dk4stt.ctr
+dk4stt.h
+dk4symlink.ctr
+dk4time08.c
+dk4time08.ctr
+dk4time08.h
+dk4time.c
+dk4timec.h
+dk4time.ctr
+dk4timedk.c
+dk4timedk.ctr
+dk4timedk.h
+dk4time.h
+dk4timewc.c
+dk4timewc.ctr
+dk4timewc.h
+dk4tsp08.c
+dk4tsp08.ctr
+dk4tsp08.h
+dk4tsp16.c
+dk4tsp16.ctr
+dk4tsp16.h
+dk4tsp32.c
+dk4tsp32.ctr
+dk4tsp32.h
+dk4tspdk.c
+dk4tspdk.ctr
+dk4tspdk.h
+dk4tsp.h
+dk4tspwx.cpt
+dk4types.h
+dk4uc2l.ctr
+dk4ufi08.c
+dk4ufi08.ctr
+dk4ufi08.h
+dk4ufi.c
+dk4ufic.c
+dk4ufic.ctr
+dk4ufic.h
+dk4ufi.ctr
+dk4ufi.h
+dk4ufit.h
+dk4ufiwc.c
+dk4ufiwc.ctr
+dk4ufiwc.h
+dk4user.c
+dk4user.ctr
+dk4user.h
+dk4utf16.c
+dk4utf16.ctr
+dk4utf16.h
+dk4utf8.c
+dk4utf8.ctr
+dk4utf8.h
+dk4vers.h
+dk4verswx.h
+dk4wreg8.c
+dk4wreg8.ctr
+dk4wreg8.h
+dk4wreg.c
+dk4wregc.c
+dk4wregc.ctr
+dk4wregc.h
+dk4wregd.c
+dk4wregd.ctr
+dk4wregd.h
+dk4wregk.h
+dk4wregt.h
+dk4wregw.c
+dk4wregw.ctr
+dk4wregw.h
+Dk4WxApplicationHelper.cpt
+Dk4WxAutostartController.cpt
+Dk4WxControl.cpt
+dk4wxcs.h
+libdk4wx.dox
+Dk4WxFrame.cpt
+Dk4WxHelpController.cpt
+dk4wxpref.cpt
+Dk4WxProgressControllerBase.h
+Dk4WxProgressDialog.wxc
+dk4wxstt.cpt
+dk4wxtypes.h
+dk-blks.c
+dk-blks.ctr
+dk-bmm.ctr
+dk-cat.c
+dk-cat.ctr
+dk-cat.exe.manifest
+DkClockApp.cpt
+DkClockData.cpt
+DkClockFrame.wxc
+DkClockOptionsDialog.wxc
+DkClockTaskbarIcon.cpt
+DkClockView.cpt
+dkconfig.cpp
+dkct-au.ctr
+dkct.ctr
+dkct-gui.ctr
+dkct.h
+dkct-str.ctr
+dkct-to.ctr
+dkct-tr.ctr
+dkct-tr.h
+dkdbt.ctr
+dk-eradisk.ctr
+dk-fic.ctr
+dk-hex.ctr
+rshdown.ctr
+prmonsnmp.ctr
+dk-ls.ctr
+dk-ls-to.ctr
+dk-pwd.ctr
+dk-pwgen.ctr
+dk-pwg-rnd.ctr
+dk-recv.ctr
+dk-send.ctr
+dk-sort.ctr
+dk-sqlsplit.c
+dk-sqlsplit.ctr
+dk-t2h.ctr
+dk-t2l.ctr
+dkt.h
+dktools.pc.in
+dkt-version.h
+dk-uid.ctr
+dkwt-ac.ctr
+dkwtadm.exe.manifest.in
+dkwt-cp.ctr
+dkwt.ctr
+dkwt-env.ctr
+dkwt-ev.ctr
+dkwt-gr.ctr
+dkwt.h
+dkwt-pr.ctr
+dkwt-to.ctr
+DkWxAppHelper.cpt
+DkWxBmepsApp.cpt
+DkWxBmepsFrame.wxc
+DkWxBmepsOptionsDialog.wxc
+DkWxBmepsThread.cpt
+DkWxBufferedControl.cpt
+DkWxColorView.cpt
+DkWxCommunicator.cpt
+DkWxDialog.cpt
+DkWxFrame.cpt
+DkWxHelpController.cpt
+DkWxHtbApp.cpt
+DkWxHtbFrame.wxc
+DkWxImgszApp.cpt
+DkWxImgszFrame.wxc
+DkWxImgszOptionsDialog.wxc
+DkWxPathApp.cpt
+DkWxPathFrame.wxc
+dkwxpath.h
+dkwxpqdc.h
+WxpqdicApp.cpt
+DkWxProcessingController.cpt
+DkWxProcessingIdleController.cpt
+DkWxProgressDialog.wxc
+DkWxTraceApp.cpt
+DkWxTraceFrame.wxc
+dkwxtrace.h
+DkWxTraceOptionsDialog.wxc
+DkWxTraceOptionsDialog.wxc.1
+DkWxTraceThread.cpt
+dkwxwiz.ctr
+Doxyfile
+ex-sto.ctr
+ex-sto.in
+f2leps.ctr
+f2ll2l.ctr
+f2lopt.ctr
+f2lpara.ctr
+f2lpdf.ctr
+f2lpgf.ctr
+f2lsvg.ctr
+f2lsvgst.ctr
+f2lto.ctr
+f2lud.ctr
+f2ludpat.ctr
+fig2lat.ctr
+filelist.txt
+hbchm.ctr
+hbconf.ctr
+hbcont.ctr
+hbhtml.ctr
+hbimgdim.ctr
+hbindex.ctr
+hbnode.ctr
+hbtool.ctr
+htmlbook.ctr
+initd-printqd.in
+itaclean.sh
+itacomp.ctr
+itaconf.ctr
+itadata.ctr
+itadhcp.ctr
+itadmin.ctr
+itaether.ctr
+itahosts.ctr
+italic.ctr
+itamem.ctr
+itamysql.ctr
+itanetd.ctr
+itange.ctr
+itareg.ctr
+itatool.ctr
+libdk4base.dox
+libdk4c.dox
+libdk4ma.dox
+libdk4maiowd.dox
+libdk4maio8d.dox
+libdk4maiodd.dox
+libdk4maio8h.dox
+libdk4maiowh.dox
+libdk4maiodh.dox
+lprngcl.ctr
+Makefile
+Makefile.in
+makefile.vc
+mod-dkconfig.sed
+modsnmp.sed
+pjsnmp.ctr
+pjsnmp.h
+dk4dmt.ctr
+wxpqdic.h
+plpdftex.ctr
+plptcol.ctr
+pqdconf.ctr
+pqdconf.c
+pqdproto.ctr
+pqdstr.ctr
+pqdtool.ctr
+printqda.ctr
+printqd.ctr
+printqdc.ctr
+printqdi.ctr
+printqds.h
+dk4lprng.h
+sep.txt
+standard-headers.txt
+ScreenSizeApp.cpt
+ScreenSizeFrame.wxc
+test-opt.ctr
+test-udpa.ctr
+test-home.ctr
+test-skip.ctr
+test-a85d.ctr
+test-a85e.ctr
+test-binenc.ctr
+test-bool.ctr
+test-container.cpt
+test-deldir.ctr
+test-deltree.ctr
+test-dk4c8dbl.ctr
+test-dk4dir08.ctr
+test-dk4dir.ctr
+test-dk4enc.ctr
+test-dk4exep8.ctr
+test-dk4loc.ctr
+test-dk4maac.ctr
+test-dk4maai.ctr
+test-dk4maal.ctr
+test-dk4maall.ctr
+test-dk4maami.ctr
+test-dk4maamu.ctr
+test-dk4maas.ctr
+test-dk4maauc.ctr
+test-dk4maaui.ctr
+test-dk4maaul.ctr
+test-dk4maaull.ctr
+test-dk4maaus.ctr
+test-dk4mai8dbl.ctr
+test-dk4mai8ddi.ctr
+test-dk4mai8ddu.ctr
+test-dk4mai8dsz.ctr
+test-dk4mai8sz.c
+test-dk4numl.ctr
+test-dk4path8.ctr
+test-dk4str8.ctr
+test-dk4strm.ctr
+test-dk4strmco.ctr
+test-dk4time08.ctr
+test-dk4time.ctr
+test-dk4tsp08.ctr
+test-dk4user.ctr
+test-dk4wxah
+test-dk4wxah.cpt
+test-eradisk.ctr
+test-filei.ctr
+test-fne.ctr
+test-inet-pton.ctr
+test-membuf.ctr
+test-mbstr.ctr
+test-mkdir.ctr
+test-paper.ctr
+test-peer.ctr
+test-rld.ctr
+test-rle.ctr
+test-rle-rld.sh
+test-sock.ctr
+test-strms.ctr
+test-strmu.ctr
+testlzw.ctr
+testlzws.ctr
+TODO
+translate.vc
+translate-wxcs.pl
+WinprintApp.cpt
+WinprintChooserDialog.wxc
+WinprintFrame.wxc
+WxpqdicFrame.wxc
+winprint.h
+WinprintThread.cpt
+wprclean.ctr
+wprclean2.ctr
+wprclean.h
+wxbmeps.h
+wxbmpp.desktop
+wxcs.cpp
+wxdkclock.desktop
+wxdkclock.h
+wxdkct.desktop
+wxdkfcs.desktop
+wxdkfcs.h
+wxdkhtb.h
+wxdkscrsz.h
+wximgsz.desktop
+wximgsz.h
+x.sed
+livesys-data/sed_isolinux.txt
+livesys-data/pkg_lang_desktop.txt
+livesys-data/sed_menu.txt
+livesys-data/pkg_xfce.txt
+livesys-data/pkg_base.txt
+livesys-data/sed_nobeep.txt
+livesys-data/root/usr/share/dktoolian/ntp.conf.template
+livesys-data/root/usr/share/dktoolian/etc-files.sed
+livesys-data/root/usr/local/bin/dktoolian-ntp
+livesys-data/root/usr/local/bin/dktoolian-etc
+livesys-data/hook_etcfiles.txt
+livesys-data/root-cli/usr/share/dktoolian/getty.sed
+livesys-data/msg_nonfree.txt
+livesys-data/apt_pinning.txt
+livesys-data/apt-pinning.txt
+livesys-data/pkg_firmware.txt
+livesys-data/pkg_lang_base.txt
+livesys-data/pkg_local.txt
+livesys-data/hook_autologin.txt
+livesys-data/hook_bootbeep.txt
+win32/dk3conf.h
+win32/dk3wxcs.h
+win32/dk4conf.h
+win32/dk4wxcs.h
+win32/user32.iss
+win32/user64.iss
+win32/user64.iss.in
+scripts/show-dependencies.pl
+scripts/create-debian-changelog.pl
+scripts/build-help.sh
+scripts/clean-for-fig.sh
+scripts/clean-for-tex.sh
+scripts/clean-help-doc.sh
+scripts/clean.sh
+scripts/create-desktop-files.sh.in
+scripts/create-distribution.sh
+scripts/create-iss.sed
+scripts/create-spec-iss.sh
+scripts/distrenew.sh
+scripts/filechk.pl
+scripts/find-headers-without-modules.sh
+scripts/git-add.sh
+scripts/install-libs-shared.sh
+scripts/install-libs-static.sh
+scripts/install-mkdir.sh
+scripts/install-programs.sh
+scripts/mkrc.pl
+scripts/transform-config.pl
+scripts/update-doxyfile.sh
+scripts/wr-dk3inst.sh.in
+scripts/wr-dk4inst.sh
+scripts/wr-dk4inst.sh.in
+
+contrib/gs-fonts-svg/COPYING
+contrib/gs-fonts-svg/crpfb.cmd
+contrib/gs-fonts-svg/crpfb.sh
+contrib/gs-fonts-svg/crsvg.sh
+contrib/gs-fonts-svg/crttf.sh
+contrib/gs-fonts-svg/index.html
+contrib/gs-fonts-svg/INSTALL
+contrib/gs-fonts-svg/metadata.sed
+contrib/gs-fonts-svg/pfb2svg.pe
+contrib/gs-fonts-svg/README
+contrib/README
+
+dktools/charmap/currency-europe.t2l
+dktools/charmap/dingbats.t2l
+dktools/charmap/iso-latin-1.t2l
+dktools/charmap/latin-extended-a.t2l
+dktools/charmap/textsym.t2l
+dktools/charmap/x.pl
+dktools/de/bmpp.txt
+dktools/de/dk3app.str
+dktools/de/dk3bifa.str
+dktools/de/dk3bmeps.str
+dktools/de/dk3fig.str
+dktools/de/dk3print.str
+dktools/de/dk3wreg.str
+dktools/de/dk4debug.str
+dktools/de/dk4info.str
+dktools/de/dk4info.txt
+dktools/de/dk4uc2l.str
+dktools/de/dk-blks.str
+dktools/de/dk-blks.txt
+dktools/de/dk-bmm.str
+dktools/de/dk-bmm.txt
+dktools/de/dk-cat.str
+dktools/de/dk-cat.txt
+dktools/de/dkct3.str
+dktools/de/dkct.txt
+dktools/de/dkdbtool.str
+dktools/de/dkdbtool.txt
+dktools/de/dk-fic.str
+dktools/de/dk-fic.txt
+dktools/de/dk-hex.str
+dktools/de/dk-hex.txt
+dktools/de/dk-ls.str
+dktools/de/dk-ls.txt
+dktools/de/dknet4.str
+dktools/de/dknet4.txt
+dktools/de/dk-pwd.str
+dktools/de/dk-pwd.txt
+dktools/de/dk-pwgen.str
+dktools/de/dk-pwgen.txt
+dktools/de/dk-recv.str
+dktools/de/dk-recv.txt
+dktools/de/dk-send.str
+dktools/de/dk-send.txt
+dktools/de/dk-sort.str
+dktools/de/dk-sort.txt
+dktools/de/dk-sqlsplit.txt
+dktools/de/dk-t2h.str
+dktools/de/dk-t2h.txt
+dktools/de/dk-t2l.str
+dktools/de/dk-t2l.txt
+dktools/de/dk-uid.str
+dktools/de/dk-uid.txt
+dktools/de/dkwt-boot.txt
+dktools/de/dkwt-clp.txt
+dktools/de/dkwt-env.txt
+dktools/de/dkwt-groups.txt
+dktools/de/dkwt-help.txt
+dktools/de/dkwt-keep.txt
+dktools/de/dkwt-login.txt
+dktools/de/dkwt-logout.txt
+dktools/de/dkwt-printers.txt
+dktools/de/dkwt-print.txt
+dktools/de/dkwt-shutdown.txt
+dktools/de/dkwt.str
+dktools/de/dkwt-unkeep.txt
+dktools/de/dkwt-users.txt
+dktools/de/dkwxpath.str
+dktools/de/dkwx.str
+dktools/de/dkwxwiz.str
+dktools/de/dkwxwiz.txt
+dktools/de/fig2lat.str
+dktools/de/fig2lat.txt
+dktools/de/htmlbook.str
+dktools/de/htmlbook.txt
+dktools/de/itadmin.str
+dktools/de/lprngcl.str
+dktools/de/lprngcl.txt
+dktools/de/pjsnmp.str
+dktools/de/plpdftex.str
+dktools/de/printqda.str
+dktools/de/printqdc.str
+dktools/de/printqdi.str
+dktools/de/printqd.str
+dktools/de/winprint.str
+dktools/de/wprclean.str
+dktools/de/wprclean.txt
+dktools/de/wxbmpp.str
+dktools/de/wxdkclock.str
+dktools/de/wxdkct.str
+dktools/de/wxdkfcs.str
+dktools/de/wxdkhtb.str
+dktools/de/wxdkscrsz.str
+dktools/de/wximgsz.str
+dktools/de/wxpqdc.str
+dktools/de/x.txt
+dktools/dkwxwiza.txt
+dktools/dkwxwizc.txt
+dktools/dkwxwizf.txt
+dktools/dkwxwizh.txt
+dktools/dkwxwizm.txt
+dktools/dkwxwizr.txt
+dktools/dkwxwiz.tar.gz
+dktools/dkwxwizv.txt
+dktools/dkwxwizx.txt
+dktools-el6.spec
+dktools-el6.spec.in
+dktools-el7.spec
+dktools-el.spec
+dktools/en/ChooseDirectory.png
+dktools/en/dk4info.txt
+dktools/en/dk-blks.txt
+dktools/en/dk-bmm.txt
+dktools/en/dk-cat.txt
+dktools/en/dk-fic.txt
+dktools/en/dk-hex.txt
+dktools/en/dk-ls.txt
+dktools/en/dk-pwd.txt
+dktools/en/dk-pwgen.txt
+dktools/en/dk-recv.txt
+dktools/en/dk-send.txt
+dktools/en/dk-sort.txt
+dktools/en/dk-sqlsplit.txt
+dktools/en/dk-t2h.txt
+dktools/en/dk-t2l.txt
+dktools/en/dk-uid.txt
+dktools/en/Exit.png
+dktools/en/Options.png
+dktools/en/Run.png
+dktools/en/x.txt
+dktools-fedora.spec
+dktools/htmlbook/chm.hbt
+dktools/htmlbook/GNUmakefile
+dktools/htmlbook/home.fig
+dktools/htmlbook/home.png
+dktools/htmlbook/index.fig
+dktools/htmlbook/index.png
+dktools/htmlbook/index.prj
+dktools/htmlbook/math-img.tex
+dktools/htmlbook/next.fig
+dktools/htmlbook/next.png
+dktools/htmlbook/prev.fig
+dktools/htmlbook/prev.png
+dktools/htmlbook/style.css
+dktools/htmlbook/toc.fig
+dktools/htmlbook/toc.png
+dktools/htmlbook/web.hbt
+dktools/itadmin/it-de.sql
+dktools/itadmin/it-latin1.sql
+dktools/itadmin/it-utf8.sql
+
+resources/choose-dir.fig
+resources/dkclock.fig
+resources/dkctinst.fig
+resources/dkctunin.fig
+resources/dkicon.fig
+resources/exit-program.fig
+resources/favicon.fig
+resources/GNUmakefile
+resources/run2.fig
+resources/run-conversion.fig
+resources/set-options.fig
+resources/toolbase.fig
+resources/wxdkscrsz.fig
+
+help-src/winprint/de/chm.hbt
+help-src/winprint/de/config-file.txt
+help-src/winprint/de/de-lic-libjpeg.txt
+help-src/winprint/de/de-lic-libpng.txt
+help-src/winprint/de/de-lic-libtiff.txt
+help-src/winprint/de/de-lic-winprint.txt
+help-src/winprint/de/de-lic-wxwidgets.txt
+help-src/winprint/de/de-lic-zlib.txt
+help-src/winprint/de/home.png
+help-src/winprint/en/home.png
+help-src/winprint/de/GNUmakefile
+help-src/winprint/de/htmlbook.sh
+help-src/winprint/de/index.fig
+help-src/winprint/de/index.png
+help-src/winprint/de/index.prj
+help-src/winprint/de/index.txt
+help-src/winprint/de/next.fig
+help-src/winprint/de/next.png
+help-src/winprint/de/prev.fig
+help-src/winprint/de/previous.fig
+help-src/winprint/de/previous.png
+help-src/winprint/de/prev.png
+help-src/winprint/de/project.xml
+help-src/winprint/de/sc01.png
+help-src/winprint/de/sc02.png
+help-src/winprint/de/sc03.png
+help-src/winprint/de/sc04.png
+help-src/winprint/de/sc05.png
+help-src/winprint/de/sc06.png
+help-src/winprint/de/sc07.png
+help-src/winprint/de/sc08.png
+help-src/winprint/de/sc10.png
+help-src/winprint/de/sc11.png
+help-src/winprint/de/sc12.png
+help-src/winprint/de/sc13.png
+help-src/winprint/de/sc14.png
+help-src/winprint/de/sc15.png
+help-src/winprint/de/start.txt
+help-src/winprint/de/style.css
+help-src/winprint/de/toc.fig
+help-src/winprint/de/toc.png
+help-src/winprint/de/web.hbt
+help-src/winprint/en/chm.hbt
+help-src/winprint/en/config-file.txt
+help-src/winprint/en/en-lic-libjpeg.txt
+help-src/winprint/en/en-lic-libpng.txt
+help-src/winprint/en/en-lic-libtiff.txt
+help-src/winprint/en/en-lic-winprint.txt
+help-src/winprint/en/en-lic-wxwidgets.txt
+help-src/winprint/en/en-lic-zlib.txt
+help-src/winprint/en/GNUmakefile
+help-src/winprint/en/htmlbook.sh
+help-src/winprint/en/index.fig
+help-src/winprint/en/index.png
+help-src/winprint/en/index.prj
+help-src/winprint/en/index.txt
+help-src/winprint/en/next.fig
+help-src/winprint/en/next.png
+help-src/winprint/en/prev.fig
+help-src/winprint/en/previous.fig
+help-src/winprint/en/previous.png
+help-src/winprint/en/prev.png
+help-src/winprint/en/project.xml
+help-src/winprint/en/sc01.png
+help-src/winprint/en/sc02.png
+help-src/winprint/en/sc03.png
+help-src/winprint/en/sc04.png
+help-src/winprint/en/sc05.png
+help-src/winprint/en/sc06.png
+help-src/winprint/en/sc07.png
+help-src/winprint/en/sc08.png
+help-src/winprint/en/sc10.png
+help-src/winprint/en/sc11.png
+help-src/winprint/en/sc12.png
+help-src/winprint/en/sc13.png
+help-src/winprint/en/sc14.png
+help-src/winprint/en/sc15.png
+help-src/winprint/en/start.txt
+help-src/winprint/en/style.css
+help-src/winprint/en/toc.fig
+help-src/winprint/en/toc.png
+help-src/winprint/en/web.hbt
+help-src/wxbmpp/de/chm.hbt
+help-src/wxbmpp/de/config.txt
+help-src/wxbmpp/de/de-lic-libjpeg.txt
+help-src/wxbmpp/de/de-lic-libpng.txt
+help-src/wxbmpp/de/de-lic-libtiff.txt
+help-src/wxbmpp/de/de-lic-wxbmpp.txt
+help-src/wxbmpp/de/de-lic-wxwidgets.txt
+help-src/wxbmpp/de/de-lic-zlib.txt
+help-src/wxbmpp/de/directory.txt
+help-src/wxbmpp/de/exit.txt
+help-src/wxbmpp/de/GNUmakefile
+help-src/wxbmpp/de/home.png
+help-src/wxbmpp/en/home.png
+help-src/wxbmpp/de/htmlbook.sh
+help-src/wxbmpp/de/index.fig
+help-src/wxbmpp/de/index.png
+help-src/wxbmpp/de/index.prj
+help-src/wxbmpp/de/index.txt
+help-src/wxbmpp/de/next.fig
+help-src/wxbmpp/de/next.png
+help-src/wxbmpp/de/prev.fig
+help-src/wxbmpp/de/previous.fig
+help-src/wxbmpp/de/previous.png
+help-src/wxbmpp/de/prev.png
+help-src/wxbmpp/de/project.xml
+help-src/wxbmpp/de/run.txt
+help-src/wxbmpp/de/sc01.png
+help-src/wxbmpp/de/sc02.png
+help-src/wxbmpp/de/sc03.png
+help-src/wxbmpp/de/sc04.png
+help-src/wxbmpp/de/sc05.png
+help-src/wxbmpp/de/sc06.png
+help-src/wxbmpp/de/sc07.png
+help-src/wxbmpp/de/sc08.png
+help-src/wxbmpp/de/sc09.png
+help-src/wxbmpp/de/sc10.png
+help-src/wxbmpp/de/sc11.png
+help-src/wxbmpp/de/sc12.png
+help-src/wxbmpp/de/sc13.png
+help-src/wxbmpp/de/sc14.png
+help-src/wxbmpp/de/start.txt
+help-src/wxbmpp/de/style.css
+help-src/wxbmpp/de/toc.fig
+help-src/wxbmpp/de/toc.png
+help-src/wxbmpp/de/web.hbt
+help-src/wxbmpp/en/chm.hbt
+help-src/wxbmpp/en/config.txt
+help-src/wxbmpp/en/directory.txt
+help-src/wxbmpp/en/en-lic-libjpeg.txt
+help-src/wxbmpp/en/en-lic-libpng.txt
+help-src/wxbmpp/en/en-lic-libtiff.txt
+help-src/wxbmpp/en/en-lic-wxbmpp.txt
+help-src/wxbmpp/en/en-lic-wxwidgets.txt
+help-src/wxbmpp/en/en-lic-zlib.txt
+help-src/wxbmpp/en/exit.txt
+help-src/wxbmpp/en/GNUmakefile
+help-src/wxbmpp/en/htmlbook.sh
+help-src/wxbmpp/en/index.fig
+help-src/wxbmpp/en/index.png
+help-src/wxbmpp/en/index.prj
+help-src/wxbmpp/en/index.txt
+help-src/wxbmpp/en/next.fig
+help-src/wxbmpp/en/next.png
+help-src/wxbmpp/en/prev.fig
+help-src/wxbmpp/en/previous.fig
+help-src/wxbmpp/en/previous.png
+help-src/wxbmpp/en/prev.png
+help-src/wxbmpp/en/project.xml
+help-src/wxbmpp/en/run.txt
+help-src/wxbmpp/en/sc01.png
+help-src/wxbmpp/en/sc02.png
+help-src/wxbmpp/en/sc03.png
+help-src/wxbmpp/en/sc04.png
+help-src/wxbmpp/en/sc05.png
+help-src/wxbmpp/en/sc06.png
+help-src/wxbmpp/en/sc07.png
+help-src/wxbmpp/en/sc08.png
+help-src/wxbmpp/en/sc09.png
+help-src/wxbmpp/en/sc10.png
+help-src/wxbmpp/en/sc11.png
+help-src/wxbmpp/en/sc12.png
+help-src/wxbmpp/en/sc13.png
+help-src/wxbmpp/en/sc14.png
+help-src/wxbmpp/en/start.txt
+help-src/wxbmpp/en/style.css
+help-src/wxbmpp/en/toc.fig
+help-src/wxbmpp/en/toc.png
+help-src/wxbmpp/en/web.hbt
+help-src/wxdkclock/de/chm.hbt
+help-src/wxdkclock/de/de-lic-libjpeg.txt
+help-src/wxdkclock/de/de-lic-libpng.txt
+help-src/wxdkclock/de/de-lic-libtiff.txt
+help-src/wxdkclock/de/de-lic-wxdkclock.txt
+help-src/wxdkclock/de/de-lic-wxwidgets.txt
+help-src/wxdkclock/de/de-lic-zlib.txt
+help-src/wxdkclock/de/end-alert.txt
+help-src/wxdkclock/de/home.png
+help-src/wxdkclock/en/home.png
+help-src/wxdkclock/de/GNUmakefile
+help-src/wxdkclock/de/htmlbook.sh
+help-src/wxdkclock/de/index.fig
+help-src/wxdkclock/de/index.png
+help-src/wxdkclock/de/index.prj
+help-src/wxdkclock/de/index.txt
+help-src/wxdkclock/de/next.fig
+help-src/wxdkclock/de/next.png
+help-src/wxdkclock/de/prev.fig
+help-src/wxdkclock/de/previous.fig
+help-src/wxdkclock/de/previous.png
+help-src/wxdkclock/de/prev.png
+help-src/wxdkclock/de/project.xml
+help-src/wxdkclock/de/sc01.png
+help-src/wxdkclock/de/sc02.png
+help-src/wxdkclock/de/sc03.png
+help-src/wxdkclock/de/sc04.png
+help-src/wxdkclock/de/sc05.png
+help-src/wxdkclock/de/sc06.png
+help-src/wxdkclock/de/sc08.png
+help-src/wxdkclock/de/set-alert.txt
+help-src/wxdkclock/de/start.txt
+help-src/wxdkclock/de/style.css
+help-src/wxdkclock/de/taskbar.txt
+help-src/wxdkclock/de/toc.fig
+help-src/wxdkclock/de/toc.png
+help-src/wxdkclock/de/web.hbt
+help-src/wxdkclock/en/chm.hbt
+help-src/wxdkclock/en/end-alert.txt
+help-src/wxdkclock/en/en-lic-libjpeg.txt
+help-src/wxdkclock/en/en-lic-libpng.txt
+help-src/wxdkclock/en/en-lic-libtiff.txt
+help-src/wxdkclock/en/en-lic-wxdkclock.txt
+help-src/wxdkclock/en/en-lic-wxwidgets.txt
+help-src/wxdkclock/en/en-lic-zlib.txt
+help-src/wxdkclock/en/GNUmakefile
+help-src/wxdkclock/en/htmlbook.sh
+help-src/wxdkclock/en/index.fig
+help-src/wxdkclock/en/index.png
+help-src/wxdkclock/en/index.prj
+help-src/wxdkclock/en/index.txt
+help-src/wxdkclock/en/next.fig
+help-src/wxdkclock/en/next.png
+help-src/wxdkclock/en/prev.fig
+help-src/wxdkclock/en/previous.fig
+help-src/wxdkclock/en/previous.png
+help-src/wxdkclock/en/prev.png
+help-src/wxdkclock/en/project.xml
+help-src/wxdkclock/en/sc01.png
+help-src/wxdkclock/en/sc02.png
+help-src/wxdkclock/en/sc03.png
+help-src/wxdkclock/en/sc04.png
+help-src/wxdkclock/en/sc05.png
+help-src/wxdkclock/en/sc06.png
+help-src/wxdkclock/en/sc08.png
+help-src/wxdkclock/en/set-alert.txt
+help-src/wxdkclock/en/start.txt
+help-src/wxdkclock/en/style.css
+help-src/wxdkclock/en/taskbar.txt
+help-src/wxdkclock/en/toc.fig
+help-src/wxdkclock/en/toc.png
+help-src/wxdkclock/en/web.hbt
+help-src/wxdkct/de/chm.hbt
+help-src/wxdkct/de/config.txt
+help-src/wxdkct/de/de-lic-libjpeg.txt
+help-src/wxdkct/de/de-lic-libpng.txt
+help-src/wxdkct/de/de-lic-libtiff.txt
+help-src/wxdkct/de/de-lic-wxdkct.txt
+help-src/wxdkct/de/de-lic-wxwidgets.txt
+help-src/wxdkct/de/de-lic-zlib.txt
+help-src/wxdkct/de/GNUmakefile
+help-src/wxdkct/de/home.png
+help-src/wxdkct/en/home.png
+help-src/wxdkct/de/htmlbook.sh
+help-src/wxdkct/de/index.fig
+help-src/wxdkct/de/index.png
+help-src/wxdkct/de/index.prj
+help-src/wxdkct/de/index.txt
+help-src/wxdkct/de/next.fig
+help-src/wxdkct/de/next.png
+help-src/wxdkct/de/prev.fig
+help-src/wxdkct/de/previous.fig
+help-src/wxdkct/de/previous.png
+help-src/wxdkct/de/prev.png
+help-src/wxdkct/de/project.xml
+help-src/wxdkct/de/run.txt
+help-src/wxdkct/de/sc-done.png
+help-src/wxdkct/de/sc-options.png
+help-src/wxdkct/de/sc-progress.png
+help-src/wxdkct/de/style.css
+help-src/wxdkct/de/toc.fig
+help-src/wxdkct/de/toc.png
+help-src/wxdkct/de/web.hbt
+help-src/wxdkct/en/chm.hbt
+help-src/wxdkct/en/config.txt
+help-src/wxdkct/en/en-lic-libjpeg.txt
+help-src/wxdkct/en/en-lic-libpng.txt
+help-src/wxdkct/en/en-lic-libtiff.txt
+help-src/wxdkct/en/en-lic-wxdkct.txt
+help-src/wxdkct/en/en-lic-wxwidgets.txt
+help-src/wxdkct/en/en-lic-zlib.txt
+help-src/wxdkct/en/GNUmakefile
+help-src/wxdkct/en/htmlbook.sh
+help-src/wxdkct/en/index.fig
+help-src/wxdkct/en/index.png
+help-src/wxdkct/en/index.prj
+help-src/wxdkct/en/index.txt
+help-src/wxdkct/en/next.fig
+help-src/wxdkct/en/next.png
+help-src/wxdkct/en/prev.fig
+help-src/wxdkct/en/previous.fig
+help-src/wxdkct/en/previous.png
+help-src/wxdkct/en/prev.png
+help-src/wxdkct/en/project.xml
+help-src/wxdkct/en/run.txt
+help-src/wxdkct/en/sc-done.png
+help-src/wxdkct/en/sc-options.png
+help-src/wxdkct/en/sc-progress.png
+help-src/wxdkct/en/style.css
+help-src/wxdkct/en/toc.fig
+help-src/wxdkct/en/toc.png
+help-src/wxdkct/en/web.hbt
+help-src/wxdkfcs/de/chm.hbt
+help-src/wxdkfcs/de/de-lic-libjpeg.txt
+help-src/wxdkfcs/de/de-lic-libpng.txt
+help-src/wxdkfcs/de/de-lic-libtiff.txt
+help-src/wxdkfcs/de/de-lic-openssl.txt
+help-src/wxdkfcs/de/de-lic-wxdkfcs.txt
+help-src/wxdkfcs/de/de-lic-wxwidgets.txt
+help-src/wxdkfcs/de/de-lic-zlib.txt
+help-src/wxdkfcs/de/GNUmakefile
+help-src/wxdkfcs/de/home.png
+help-src/wxdkfcs/en/home.png
+help-src/wxdkfcs/de/htmlbook.sh
+help-src/wxdkfcs/de/index.png
+help-src/wxdkfcs/de/index.prj
+help-src/wxdkfcs/de/index.txt
+help-src/wxdkfcs/de/install.txt
+help-src/wxdkfcs/de/intro.txt
+help-src/wxdkfcs/de/math-img.log
+help-src/wxdkfcs/de/math-img.pdf
+help-src/wxdkfcs/de/math-img.png
+help-src/wxdkfcs/de/math-img.svg
+help-src/wxdkfcs/de/next.png
+help-src/wxdkfcs/de/previous.png
+help-src/wxdkfcs/de/prev.png
+help-src/wxdkfcs/de/project.xml
+help-src/wxdkfcs/de/style.css
+help-src/wxdkfcs/de/toc.png
+help-src/wxdkfcs/de/use.txt
+help-src/wxdkfcs/de/web.hbt
+help-src/wxdkfcs/en/chm.hbt
+help-src/wxdkfcs/en/en-lic-libjpeg.txt
+help-src/wxdkfcs/en/en-lic-libpng.txt
+help-src/wxdkfcs/en/en-lic-libtiff.txt
+help-src/wxdkfcs/en/en-lic-openssl.txt
+help-src/wxdkfcs/en/en-lic-wxdkfcs.txt
+help-src/wxdkfcs/en/en-lic-wxwidgets.txt
+help-src/wxdkfcs/en/en-lic-zlib.txt
+help-src/wxdkfcs/en/GNUmakefile
+help-src/wxdkfcs/en/htmlbook.sh
+help-src/wxdkfcs/en/index.png
+help-src/wxdkfcs/en/index.prj
+help-src/wxdkfcs/en/index.txt
+help-src/wxdkfcs/en/install.txt
+help-src/wxdkfcs/en/intro.txt
+help-src/wxdkfcs/en/math-img.png
+help-src/wxdkfcs/en/next.png
+help-src/wxdkfcs/en/previous.png
+help-src/wxdkfcs/en/prev.png
+help-src/wxdkfcs/en/project.xml
+help-src/wxdkfcs/en/style.css
+help-src/wxdkfcs/en/toc.png
+help-src/wxdkfcs/en/use.txt
+help-src/wxdkfcs/en/web.hbt
+
+help-src/wxdkscrsz/en/config-file.txt
+help-src/wxdkscrsz/en/sc03.png
+help-src/wxdkscrsz/en/home.png
+help-src/wxdkscrsz/en/index.png
+help-src/wxdkscrsz/en/index.html
+help-src/wxdkscrsz/en/sc10.png
+help-src/wxdkscrsz/en/htmlbook.sh
+help-src/wxdkscrsz/en/index.prj
+help-src/wxdkscrsz/en/en-lic-winprint.txt
+help-src/wxdkscrsz/en/sc07.png
+help-src/wxdkscrsz/en/sc08.png
+help-src/wxdkscrsz/en/en-lic-wxwidgets.txt
+help-src/wxdkscrsz/en/en-lic-libtiff.html
+help-src/wxdkscrsz/en/en-lic-libjpeg.html
+help-src/wxdkscrsz/en/next.png
+help-src/wxdkscrsz/en/start.txt
+help-src/wxdkscrsz/en/project.hhp
+help-src/wxdkscrsz/en/sc02.png
+help-src/wxdkscrsz/en/sc11.png
+help-src/wxdkscrsz/en/toc.png
+help-src/wxdkscrsz/en/index.txt
+help-src/wxdkscrsz/en/web.hbt
+help-src/wxdkscrsz/en/sc01.png
+help-src/wxdkscrsz/en/en-lic-libpng.html
+help-src/wxdkscrsz/en/sc13.png
+help-src/wxdkscrsz/en/sc04.png
+help-src/wxdkscrsz/en/contents.hhc
+help-src/wxdkscrsz/en/sc12.png
+help-src/wxdkscrsz/en/sc14.png
+help-src/wxdkscrsz/en/en-lic-zlib.html
+help-src/wxdkscrsz/en/en-lic-libtiff.txt
+help-src/wxdkscrsz/en/start.html
+help-src/wxdkscrsz/en/en-lic-libjpeg.txt
+help-src/wxdkscrsz/en/GNUmakefile
+help-src/wxdkscrsz/en/sc05.png
+help-src/wxdkscrsz/en/en-lic-zlib.txt
+help-src/wxdkscrsz/en/sc15.png
+help-src/wxdkscrsz/en/style.css
+help-src/wxdkscrsz/en/chm.hbt
+help-src/wxdkscrsz/en/prev.png
+help-src/wxdkscrsz/en/en-lic-wxdkscrsz.txt
+help-src/wxdkscrsz/en/sc06.png
+help-src/wxdkscrsz/en/en-lic-wxdkscrsz.html
+help-src/wxdkscrsz/en/en-lic-libpng.txt
+help-src/wxdkscrsz/en/en-lic-wxwidgets.html
+help-src/wxdkscrsz/en/project.xml
+help-src/wxdkscrsz/en/favicon.ico
+help-src/wxdkscrsz/de/config-file.txt
+help-src/wxdkscrsz/de/de-lic-wxwidgets.html
+help-src/wxdkscrsz/de/home.png
+help-src/wxdkscrsz/de/index.png
+help-src/wxdkscrsz/de/index.html
+help-src/wxdkscrsz/de/htmlbook.sh
+help-src/wxdkscrsz/de/index.prj
+help-src/wxdkscrsz/de/de-lic-zlib.txt
+help-src/wxdkscrsz/de/de-lic-wxdkscrsz.txt
+help-src/wxdkscrsz/de/de-lic-wxdkscrsz.html
+help-src/wxdkscrsz/de/next.png
+help-src/wxdkscrsz/de/start.txt
+help-src/wxdkscrsz/de/project.hhp
+help-src/wxdkscrsz/de/toc.png
+help-src/wxdkscrsz/de/index.txt
+help-src/wxdkscrsz/de/web.hbt
+help-src/wxdkscrsz/de/de-lic-libjpeg.html
+help-src/wxdkscrsz/de/contents.hhc
+help-src/wxdkscrsz/de/de-lic-zlib.html
+help-src/wxdkscrsz/de/de-lic-libpng.html
+help-src/wxdkscrsz/de/start.html
+help-src/wxdkscrsz/de/GNUmakefile
+help-src/wxdkscrsz/de/de-lic-wxwidgets.txt
+help-src/wxdkscrsz/de/de-lic-libtiff.txt
+help-src/wxdkscrsz/de/style.css
+help-src/wxdkscrsz/de/chm.hbt
+help-src/wxdkscrsz/de/de-lic-libtiff.html
+help-src/wxdkscrsz/de/de-lic-libjpeg.txt
+help-src/wxdkscrsz/de/prev.png
+help-src/wxdkscrsz/de/de-lic-libpng.txt
+help-src/wxdkscrsz/de/project.xml
+help-src/wxdkscrsz/de/favicon.ico
+
+help-src/wximgsz/de/chm.hbt
+help-src/wximgsz/de/de-lic-libjpeg.txt
+help-src/wximgsz/de/de-lic-libpng.txt
+help-src/wximgsz/de/de-lic-libtiff.txt
+help-src/wximgsz/de/de-lic-wximgsz.txt
+help-src/wximgsz/de/de-lic-wxwidgets.txt
+help-src/wximgsz/de/de-lic-zlib.txt
+help-src/wximgsz/de/GNUmakefile
+help-src/wximgsz/de/htmlbook.sh
+help-src/wximgsz/de/home.png
+help-src/wximgsz/en/home.png
+help-src/wximgsz/de/index.fig
+help-src/wximgsz/de/index.png
+help-src/wximgsz/de/index.prj
+help-src/wximgsz/de/index.txt
+help-src/wximgsz/de/next.fig
+help-src/wximgsz/de/next.png
+help-src/wximgsz/de/options.txt
+help-src/wximgsz/de/prev.fig
+help-src/wximgsz/de/previous.fig
+help-src/wximgsz/de/previous.png
+help-src/wximgsz/de/prev.png
+help-src/wximgsz/de/project.xml
+help-src/wximgsz/de/sc-main2.png
+help-src/wximgsz/de/sc-main.png
+help-src/wximgsz/de/style.css
+help-src/wximgsz/de/toc.fig
+help-src/wximgsz/de/toc.png
+help-src/wximgsz/de/usage.txt
+help-src/wximgsz/de/web.hbt
+help-src/wximgsz/en/chm.hbt
+help-src/wximgsz/en/en-lic-libjpeg.txt
+help-src/wximgsz/en/en-lic-libpng.txt
+help-src/wximgsz/en/en-lic-libtiff.txt
+help-src/wximgsz/en/en-lic-wximgsz.txt
+help-src/wximgsz/en/en-lic-wxwidgets.txt
+help-src/wximgsz/en/en-lic-zlib.txt
+help-src/wximgsz/en/GNUmakefile
+help-src/wximgsz/en/htmlbook.sh
+help-src/wximgsz/en/index.fig
+help-src/wximgsz/en/index.png
+help-src/wximgsz/en/index.prj
+help-src/wximgsz/en/index.txt
+help-src/wximgsz/en/next.fig
+help-src/wximgsz/en/next.png
+help-src/wximgsz/en/options.txt
+help-src/wximgsz/en/prev.fig
+help-src/wximgsz/en/previous.fig
+help-src/wximgsz/en/previous.png
+help-src/wximgsz/en/prev.png
+help-src/wximgsz/en/project.xml
+help-src/wximgsz/en/sc-main2.png
+help-src/wximgsz/en/sc-main.png
+help-src/wximgsz/en/style.css
+help-src/wximgsz/en/toc.fig
+help-src/wximgsz/en/toc.png
+help-src/wximgsz/en/usage.txt
+help-src/wximgsz/en/web.hbt
+help-src/wxpqdic/de/chm.hbt
+help-src/wxpqdic/de/de-lic-libjpeg.txt
+help-src/wxpqdic/de/de-lic-libpng.txt
+help-src/wxpqdic/de/de-lic-libtiff.txt
+help-src/wxpqdic/de/de-lic-wxpqdic.txt
+help-src/wxpqdic/de/de-lic-wxwidgets.txt
+help-src/wxpqdic/de/de-lic-zlib.txt
+help-src/wxpqdic/de/fehler.txt
+help-src/wxpqdic/de/fts-stop.txt
+help-src/wxpqdic/de/GNUmakefile
+help-src/wxpqdic/de/home.png
+help-src/wxpqdic/en/home.png
+help-src/wxpqdic/de/htmlbook.sh
+help-src/wxpqdic/de/index.fig
+help-src/wxpqdic/de/index.png
+help-src/wxpqdic/de/index.prj
+help-src/wxpqdic/de/index.txt
+help-src/wxpqdic/de/index.xml
+help-src/wxpqdic/de/konfig.txt
+help-src/wxpqdic/de/next.fig
+help-src/wxpqdic/de/next.png
+help-src/wxpqdic/de/prev.fig
+help-src/wxpqdic/de/previous.fig
+help-src/wxpqdic/de/previous.png
+help-src/wxpqdic/de/prev.png
+help-src/wxpqdic/de/project.xml
+help-src/wxpqdic/de/startbed.txt
+help-src/wxpqdic/de/stop.txt
+help-src/wxpqdic/de/style.css
+help-src/wxpqdic/de/style.css.old
+help-src/wxpqdic/de/toc.fig
+help-src/wxpqdic/de/toc.png
+help-src/wxpqdic/de/uebersicht.txt
+help-src/wxpqdic/de/web.hbt
+help-src/wxpqdic/en/chm.hbt
+help-src/wxpqdic/en/config.txt
+help-src/wxpqdic/en/en-lic-libjpeg.txt
+help-src/wxpqdic/en/en-lic-libpng.txt
+help-src/wxpqdic/en/en-lic-libtiff.txt
+help-src/wxpqdic/en/en-lic-wxpqdic.txt
+help-src/wxpqdic/en/en-lic-wxwidgets.txt
+help-src/wxpqdic/en/en-lic-zlib.txt
+help-src/wxpqdic/en/errors.txt
+help-src/wxpqdic/en/GNUmakefile
+help-src/wxpqdic/en/htmlbook.sh
+help-src/wxpqdic/en/index.fig
+help-src/wxpqdic/en/index.png
+help-src/wxpqdic/en/index.prj
+help-src/wxpqdic/en/index.txt
+help-src/wxpqdic/en/next.fig
+help-src/wxpqdic/en/next.png
+help-src/wxpqdic/en/overview.txt
+help-src/wxpqdic/en/prev.fig
+help-src/wxpqdic/en/previous.fig
+help-src/wxpqdic/en/previous.png
+help-src/wxpqdic/en/prev.png
+help-src/wxpqdic/en/project.xml
+help-src/wxpqdic/en/startus.txt
+help-src/wxpqdic/en/style.css
+help-src/wxpqdic/en/toc.fig
+help-src/wxpqdic/en/toc.png
+help-src/wxpqdic/en/web.hbt
+splash-dktoolian.png
+resources/splash-dktoolian.fig
+test-data/dk4maac.in
+test-data/dk4maac.out
+test-data/dk4maauc.in
+test-data/dk4maauc.out
+test-data/test1
+test-ser.ctr
+test-data/x.txt
+test-data/db.in
+test-deldirwc.ctr
+test-sqdbl.ctr
+test-strmw.ctr
+test-unser.ctr
+man/man5/htmlbook-text.5
+man/man5/dkct.5
+man/man5/htmlbook-template.5
+man/man5/htmlbook-project.5
+man/man5/dkct-wxgui.5
+man/man5/printqd.conf.5
+man/man5/printqd.db.5
+man/man5/printqd.protocol.5
+man/man1/itaclean.1
+man/man1/addctrld.1
+man/man1/dk-rand.1
+man/man1/rshdown.1
+man/man1/dk3info.1
+man/man1/prmonsnmp.1
+man/man1/dk-bmm.1
+man/man1/dk-t2h.1
+man/man1/dkwxwiz.1
+man/man1/printqdi.1
+man/man1/dk-pwgen.1
+man/man1/wxdkclock.1
+man/man1/dk-t2db.1
+man/man1/dk-dbco.1
+man/man1/dk-ls.1
+man/man1/printqdc.1
+man/man1/htmlbook.1
+man/man1/dkdbt.1
+man/man1/wxdkfcs.1
+man/man1/itadmin.1
+man/man1/dk-recv.1
+man/man1/dk-blks.1
+man/man1/printqda.1
+man/man1/lprngcl.1
+man/man1/dk-eradisk.1
+man/man1/pjsnmp.1
+man/man1/wxdkct.1
+man/man1/wxbmpp.1
+man/man1/dk-sort.1
+man/man1/dk-sqlsplit.1
+man/man1/dk-cat.1
+man/man1/dk-db2t.1
+man/man1/plpdftex.1
+man/man1/itaclean.sh.1
+man/man1/bmpp.1
+man/man1/dk4info.1
+man/man1/wxdkhtb.1
+man/man1/dk-uid.1
+man/man1/printqd.1
+man/man1/dk-send.1
+man/man1/dk-hex.1
+man/man1/wxpqdic.1
+man/man1/dk-fic.1
+man/man1/dkct.1
+man/man1/dktools.1
+man/man1/fig2lat.1
+man/man1/wximgsz.1
+man/man1/dk-pwd.1
+man/man1/dk-t2l.1
+config.guess
+debian-jessie-build-deb.sh
+debian-jessie-build-live.sh
+pkginfo
+aclocal.m4
+sl6-build-rpm.sh
+sl7-build-rpm.sh
+dk4dbitw.ctr
+scripts/clean-resources.sh
+scripts/doc-install.sh
+scripts/man-install.sh
+scripts/install-libs-shared.sh.in
+scripts/build-help.sh.in
+scripts/dkmkproto.pl
+scripts/make-resources.sh
+scripts/check_config_have.pl
+dk-dbco.ctr
+dk4conf.cross
+dk3conf.cross
+man-src/dkct-wxgui.5.adoc
+man-src/dktools.1.adoc
+man-src/dk-send.1.adoc
+man-src/htmlbook-project.5.adoc
+man-src/wximgsz.1.adoc
+man-src/dk-bmm.1
+man-src/dk-t2h.1.adoc
+man-src/dk-t2h.1
+man-src/htmlbook-text.5
+man-src/dkwxwiz.1
+man-src/dkwxwiz.1.adoc
+man-src/printqdi.1
+man-src/dk-pwgen.1
+man-src/htmlbook-text.5.adoc
+man-src/printqdi.1.adoc
+man-src/dk-bmm.1.adoc
+man-src/plpdftex.1.adoc
+man-src/wxdkfcs.1.adoc
+man-src/dk-uid.1.adoc
+man-src/dkct.1.adoc
+man-src/dk-pwd.1.adoc
+man-src/pjsnmp.1.adoc
+man-src/wxdkclock.1
+man-src/dk4info.1.adoc
+man-src/dk-blks.1.adoc
+man-src/dk-db2t.1.adoc
+man-src/x.1.adoc.template
+man-src/dk-t2db.1
+man-src/dk-dbco.1
+man-src/dk-ls.1
+man-src/bmpp.1.adoc
+man-src/dk-fic.1.adoc
+man-src/dk-pwgen.1.adoc
+man-src/printqdc.1
+man-src/dkct.5
+man-src/htmlbook.1
+man-src/dkdbt.1
+man-src/wxdkfcs.1
+man-src/wxbmpp.1.adoc
+man-src/itadmin.1
+man-src/dk-recv.1
+man-src/wxdkclock.1.adoc
+man-src/wxpqdic.1.adoc
+man-src/dk-hex.1.adoc
+man-src/dkdbt.1.adoc
+man-src/dk-blks.1
+man-src/htmlbook-template.5
+man-src/printqd.1.adoc
+man-src/printqda.1
+man-src/lprngcl.1
+man-src/dk-eradisk.1
+man-src/pjsnmp.1
+man-src/wxdkct.1
+man-src/htmlbook-project.5
+man-src/dk-t2db.1.adoc
+man-src/fig2lat.1.adoc
+man-src/wxbmpp.1
+man-src/dkct-wxgui.5
+man-src/dk-sort.1
+man-src/dk-eradisk.1.adoc
+man-src/dk-sqlsplit.1.adoc
+man-src/dk-sqlsplit.1
+man-src/dk-cat.1
+man-src/dk-dbco.1.adoc
+man-src/dk-recv.1.adoc
+man-src/printqd.conf.5.adoc
+man-src/dk-db2t.1
+man-src/printqd.conf.5
+man-src/plpdftex.1
+man-src/itaclean.sh.1
+man-src/dk-t2l.1.adoc
+man-src/itaclean.sh.1.adoc
+man-src/dk-sort.1.adoc
+man-src/GNUmakefile
+man-src/bmpp.1
+man-src/dk4info.1
+man-src/wxdkhtb.1
+man-src/dk-cat.1.adoc
+man-src/dk-uid.1
+man-src/itadmin.1.adoc
+man-src/printqd.1
+man-src/dk-send.1
+man-src/dk-hex.1
+man-src/wxdkct.1.adoc
+man-src/wxdkhtb.1.adoc
+man-src/wxpqdic.1
+man-src/dk-ls.1.adoc
+man-src/dk-fic.1
+man-src/dkct.1
+man-src/htmlbook.1.adoc
+man-src/dktools.1
+man-src/lprngcl.1.adoc
+man-src/printqdc.1.adoc
+man-src/fig2lat.1
+man-src/wximgsz.1
+man-src/dk-pwd.1
+man-src/printqda.1.adoc
+man-src/dkct.5.adoc
+man-src/htmlbook-template.5.adoc
+man-src/dk-t2l.1
+man-src/itaclean.1
+man-src/addctrld.1
+man-src/dk-rand.1
+man-src/itaclean.1.adoc
+man-src/prmonsnmp.1.adoc
+man-src/rshdown.1.adoc
+man-src/printqd.db.5.adoc
+man-src/dk3info.1.adoc
+man-src/printqd.1.adoc.old
+man-src/rshdown.1
+man-src/pjsnmp.1.adoc.test1
+man-src/dk-rand.1.adoc
+man-src/README.TXT
+man-src/dk3info.1
+man-src/printqd.db.5
+man-src/prmonsnmp.1
+man-src/printqd.protocol.5
+man-src/addctrld.1.adoc
+man-src/printqd.protocol.5.adoc
+dk-t2db.ctr
+sl6-prepare.sh
+dk4dbit8.ctr
+debian-jessie-prepare.sh
+dk4dbit.ctr
+dk4wxcs.cross
+install-sh
+pkginfo.in
+dkdbt2.ctr
+dk4dbia.ctr
+dk3conf.cross.in
+dktools/de/dk-t2db.str
+dktools/de/dk-dbco.str
+dktools/de/dk-db2t.txt
+dktools/de/dk-t2db.txt
+dktools/de/dk4dbia.str
+dktools/de/dk-dbco.txt
+dktools/de/dk-db2t.str
+dktools/en/dk-db2t.txt
+dktools/en/dk-t2db.txt
+dktools/en/dk-dbco.txt
+dktools/en/lprngcl.txt
+dktools/print-snmp.conf
+wxdkfcs.str
+dk-db2t.ctr
+dk-rand.ctr
+dk4dbi.ctr
+libdk4dbi.dox
+config.sub
+printqd.conf.sample
+rshdown.conf.sample
+debian/source/format
+debian/postinst.ex
+debian/copyright
+debian/manpage.sgml.ex
+debian/dktools-doc.install
+debian/rules
+debian/dktools.doc-base.EX
+debian/dktools.cron.d.ex
+debian/compat
+debian/prerm.ex
+debian/control
+debian/preinst.ex
+debian/manpage.xml.ex
+debian/dktools-doc.docs
+debian/manpage.1.ex
+debian/init.d.ex
+debian/menu.ex
+debian/postrm.ex
+debian/dktools.manpages
+debian/changelog.in
+debian/README.source
+debian/dktools.default.ex
+debian/watch.ex
+debian/docs
+debian/changelog
+debian/dktools-lib-dev.install.in
+debian/dktools.install
+debian/dktools-lib.postinst.in
+debian/control.in
+debian/dktools-lib.postrm.in
+debian/dktools-lib.install.in
+debian/dktools-lib-data.install
+debian/dktools-lib-4.8-dev.install
+debian/dktools-lib-4.8.install
+debian/dktools-lib-4.8.lintian-overrides
+debian/dktools-lib-4.8.postinst
+debian/dktools-lib-4.8.postrm
+debian/dktools-data.install
+bankian-data/pkg_local.txt
+bankian-data/root-install-packages.sh
+bankian-data/pkg_base.txt
+bankian-data/pkg_lang_desktop.txt
+bankian-data/pkg_firmware.txt
+bankian-data/livesys-build-kernel.sh
+bankian-data/livesys-repository.sh
+bankian-data/pkg_xfce.txt
+bankian-data/msg_nonfree.txt
+bankian-data/patch_ata_dev_enabled.txt
+bankian-data/hook_bootbeep.txt
+bankian-data/pkg_lang_base.txt
+bankian-data/hook_etcfiles.txt
+bankian-data/apt-pinning.txt
+bankian-data/root/usr/share/bankian/etc-files.sed
+bankian-data/root/usr/share/bankian/etc/ntp.conf
+bankian-data/root/usr/local/bin/bankian-ntp
+bankian-data/root/usr/local/bin/bankian-etc
+bankian-data/root-create-repodir.sh
+debian-jessie-build-bankian.sh
+resources/splash-surfian.fig
+resources/splash-bankian.fig
+splash-bankian.png
+splash-surfian.png
+sf-readme/readme.md
+bankian-data/apt-bankian.txt
+bankian-data/apt-pin-kernel.txt
+bankian-data/root/usr/local/bin/bankian-update
+bankian-data/sed_isolinux.txt
+bankian-data/sed_menu.txt
+bankian-data/sed_nobeep.txt
+LICENSE
+.gitignore
diff --git a/support/dktools/hbchm.c b/support/dktools/hbchm.c
new file mode 100644
index 0000000000..866abe93f4
--- /dev/null
+++ b/support/dktools/hbchm.c
@@ -0,0 +1,865 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: hbchm.ctr
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file hbchm.c The hbchm module.
+*/
+
+
+#line 34 "hbchm.ctr"
+
+
+#include "dk3all.h"
+#include "htmlbook.h"
+
+
+
+
+
+#line 42 "hbchm.ctr"
+
+
+
+/** 8-bit character keywords, not localized.
+*/
+static char const * const hbchm_c8_kw[] = {
+/* 0 */
+"\r\n",
+
+/* 1 */
+"[OPTIONS]",
+
+/* 2 */
+"Compiled file=index.chm",
+
+/* 3 */
+"Contents file=contents.hhc",
+
+/* 4 */
+"Index file=index.hhk",
+
+/* 5 */
+"Compatibility=1.1 or later",
+
+/* 6 */
+"Display compile progress=Yes",
+
+/* 7 */
+"Language=",
+
+/* 8 */
+"Title=",
+
+/* 9 */
+"Default topic=",
+
+/* 10 */
+"0x409 English (USA)",
+
+/* 11 */
+"[FILES]",
+
+/* 12 */
+"[INFOTYPES]",
+
+/* 13 */
+"<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">",
+
+/* 14 */
+"<HTML>",
+
+/* 15 */
+"<HEAD>",
+
+/* 16 */
+"<meta name=\"GENERATOR\" content=\"Microsoft&reg; HTML Help Workshop 4.1\">",
+
+/* 17 */
+"<!-- Sitemap 1.0 -->",
+
+/* 18 */
+"</HEAD><BODY>",
+
+/* 19 */
+"<UL>",
+
+/* 20 */
+"</UL>",
+
+/* 21 */
+"</BODY></HTML>",
+
+/* 22 */
+"<LI><OBJECT type=\"text/sitemap\">",
+
+/* 23 */
+"\t<param name=\"Name\" value=\"",
+
+/* 24 */
+"\t<param name=\"Local\" value=\"",
+
+/* 25 */
+"\">",
+
+/* 26 */
+"#",
+
+/* 27 */
+"<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">",
+
+/* 28 */
+"<HTML>",
+
+/* 29 */
+"<HEAD>",
+
+/* 30 */
+"<meta name=\"GENERATOR\" content=\"Microsoft&reg; HTML Help Workshop 4.1\">",
+
+/* 31 */
+"<!-- Sitemap 1.0 -->",
+
+/* 32 */
+"</HEAD><BODY>",
+
+/* 33 */
+"<OBJECT type=\"text/site properties\">",
+
+/* 34 */
+"\t<param name=\"Window Styles\" value=\"0x800025\">",
+
+/* 35 */
+"\t<param name=\"ImageType\" value=\"Folder\">",
+
+/* 36 */
+"</OBJECT>",
+
+/* 37 */
+"</BODY></HTML>",
+
+/* 38 */
+" ",
+
+/* 39 */
+"<LI><OBJECT type=\"text/sitemap\">",
+
+/* 40 */
+" </OBJECT>",
+
+/* 41 */
+" <param name=\"Name\" value=\"",
+
+/* 42 */
+" <param name=\"Local\" value=\"",
+
+/* 43 */
+"<UL>",
+
+/* 44 */
+"</UL>",
+
+/* 45 */
+"<?xml version=\"1.0\" encoding=\"utf-8\"?>",
+
+/* 46 */
+"<CONFIG>",
+
+/* 47 */
+"</CONFIG>",
+
+/* 48 */
+" <Files>",
+
+/* 49 */
+" </Files>",
+
+/* 50 */
+" <OtherFiles>",
+
+/* 51 */
+" </OtherFiles>",
+
+/* 52 */
+" <Count Value=\"0\"/>",
+
+/* 53 */
+" <Windows>",
+
+/* 54 */
+" </Windows>",
+
+/* 55 */
+" <MergeFiles>",
+
+/* 56 */
+" </MergeFiles>",
+
+/* 57 */
+" <Settings>",
+
+/* 58 */
+" </Settings>",
+
+/* 59 */
+" <IndexFile Value=\"",
+
+/* 60 */
+"\"/>",
+
+/* 61 */
+" <TOCFile Value=\"",
+
+/* 62 */
+" <MakeBinaryTOC Value=\"False\"/>",
+
+/* 63 */
+" <MakeBinaryIndex Value=\"True\"/>",
+
+/* 64 */
+" <AutoFollowLinks Value=\"False\"/>",
+
+/* 65 */
+" <MakeSearchable Value=\"True\"/>",
+
+/* 66 */
+" <DefaultPage Value=\"index.html\"/>",
+
+/* 67 */
+" <Title Value=\"",
+
+/* 68 */
+" <OutputFileName Value=\"index.chm\"/>",
+
+/* 69 */
+" <DefaultFont Value=\"\"/>",
+
+/* 70 */
+" <DefaultWindow Value=\"\"/>",
+
+/* 71 */
+" <ScanHtmlContents Value=\"True\"/>",
+
+/* 72 */
+" <Count Value=\"%lu\"/>",
+
+/* 73 */
+" <FileName%lu Value=\"",
+
+/* 74 */
+"\" ContextName=\"\" ContextNumber=\"0\"/>",
+
+/* 75 */
+"Test",
+
+/* 76 */
+" <param name=\"ID\" value=\"%ld\">",
+
+/* 77 */
+"Binary TOC=No",
+
+/* 78 */
+"Binary Index=Yes",
+
+/* 79 */
+"Default Window=",
+
+/* 80 */
+"Default Font=",
+
+/* 81 */
+"Full-text search=Yes",
+
+/* 82 */
+"Auto Index=Yes",
+
+/* 83 */
+"Create CHI file=No",
+
+/* 84 */
+"Full text search stop list file=",
+
+/* 85 */
+"Display compile progress=Yes",
+
+/* 86 */
+"Display compile notes=Yes",
+
+/* 87 */
+"Full-text search=No",
+
+NULL
+
+
+#line 234 "hbchm.ctr"
+};
+
+
+
+int
+hbchm_have_index_entries(hb_job_t *job)
+{
+ int back = 0;
+
+
+#line 243 "hbchm.ctr"
+ if ((job->i_index) && (job->s_index)) {
+ dk3sto_it_reset(job->i_index);
+ if(dk3sto_it_next(job->i_index)) { back = 1; }
+ }
+
+
+#line 248 "hbchm.ctr"
+ return back;
+}
+
+
+
+/** Write hhp file (project).
+ @param job Job structure.
+ @param haveindex Flag: Need to write an index file.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbchm_write_hhp(hb_job_t *job, int haveindex)
+{
+ dkChar fn[DK3_MAX_PATH]; /* Name of output file */
+ dkChar of[DK3_MAX_PATH]; /* Output file name */
+ dkChar const *onefn; /* Resource file name */
+ hb_node_t *nptr; /* Root node or first node */
+ int res; /* Operation result */
+ int back = 0;
+
+
+#line 269 "hbchm.ctr"
+ job->of = dk3sf_fopen_app((job->kwnl)[26], (job->kwnl)[30], job->app);
+ if(job->of) {
+ back = 1;
+ /* Write options section
+ */
+ fputs(hbchm_c8_kw[1], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[77], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[78], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[2], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[3], job->of); fputs(hbchm_c8_kw[0], job->of);
+ if(haveindex) {
+ fputs(hbchm_c8_kw[4], job->of); fputs(hbchm_c8_kw[0], job->of);
+ }
+ fputs(hbchm_c8_kw[79], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[80], job->of); fputs(hbchm_c8_kw[0], job->of);
+ if ((job->options) & HB_JOB_OPT_CHM_FULL_TEXT_SEARCH) {
+ fputs(hbchm_c8_kw[81], job->of);
+ } else {
+ fputs(hbchm_c8_kw[87], job->of);
+ }
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[82], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[83], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[84], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[85], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[86], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[5], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[6], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[7], job->of);
+ /* Language */
+ if(job->chmlang) {
+ res = dk3se_ansi_fputs(
+ job->chmlang, dk3app_get_encoding(job->app), job->of, job->app
+ );
+ if(!(res)) { back = 0; }
+ } else {
+ fputs(hbchm_c8_kw[10], job->of);
+ }
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[8], job->of);
+ if (job->rootnode) {
+ if ((job->rootnode)->title) {
+ res = dk3se_ansi_fputs(
+ (job->rootnode)->title, dk3app_get_encoding(job->app),
+ job->of, job->app
+ );
+ if(!(res)) { back = 0; }
+ } else {
+ fputs(hbchm_c8_kw[75], job->of);
+ }
+ } else {
+ fputs(hbchm_c8_kw[75], job->of);
+ }
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[9], job->of);
+ /* Default topic */
+ if (NULL != job->rootnode) {
+ nptr = job->rootnode;
+ if(!(nptr->filename)) { nptr = nptr->jumpnode; }
+ if(nptr) {
+ if(hbhtml_create_output_filename(fn,DK3_SIZEOF(fn,dkChar),job,nptr)) {
+ res = dk3se_ansi_fputs(
+ fn, dk3app_get_encoding(job->app), job->of, job->app
+ );
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ } else {
+ back = 0;
+ /* ERROR: No default topic found! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 47);
+ }
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ }
+ /* Write files section - files mentioned explicitly
+ */
+ fputs(hbchm_c8_kw[11], job->of); fputs(hbchm_c8_kw[0], job->of);
+ dk3sto_it_reset(job->i_files);
+ while(NULL != (onefn = (dkChar const *)dk3sto_it_next(job->i_files))) {
+ res = dk3se_ansi_fputs(
+ onefn, dk3app_get_encoding(job->app), job->of, job->app
+ );
+ if(!(res)) { back = 0; }
+ fputs(hbchm_c8_kw[0], job->of);
+ }
+#if (!(VERSION_BEFORE_20140416))
+ /* 2014-04-16
+ Write files section - HTML files not mentioned explicitly.
+ */
+ dk3sto_it_reset(job->i_pnodes);
+ while (NULL != (nptr = (hb_node_t *)dk3sto_it_next(job->i_pnodes))) {
+ if (!(nptr->jumpnode)) {
+ if (hbhtml_create_output_filename(of,DK3_SIZEOF(of,dkChar),job,nptr)) {
+ if (!(dk3sto_it_find_like(job->i_files, of, 0))) {
+ res = dk3se_ansi_fputs(
+ of, dk3app_get_encoding(job->app), job->of, job->app
+ );
+ if(!(res)) { back = 0; }
+ fputs(hbchm_c8_kw[0], job->of);
+ }
+ }
+ }
+ }
+#endif
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[12], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ if(!dk3sf_fclose_fn_app(job->of, (job->kwnl)[26], job->app)) { back = 0; }
+ }
+ if(!hbtool_add_file(job, (job->kwnl)[26])) { back = 0; }
+ if(!hbtool_add_file(job, (job->kwnl)[28])) { back = 0; }
+ if(haveindex) {
+ if(!hbtool_add_file(job, (job->kwnl)[29])) { back = 0; }
+ }
+
+#line 386 "hbchm.ctr"
+ return back;
+}
+
+
+
+/** Write hhc file (table of contents).
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbchm_write_hhc(hb_job_t *job)
+{
+ dkChar bu[DK3_MAX_PATH]; /* Name of output file */
+ hb_node_t *cnptr; /* Current node to process */
+ hb_node_t *nnptr; /* Next node to process */
+ int i; /* Used to print spaces */
+ int res; /* Operation result */
+ int mwrn = 1; /* Flag: Must write root node */
+ int back = 0;
+
+
+#line 407 "hbchm.ctr"
+ job->of = dk3sf_fopen_app((job->kwnl)[28], (job->kwnl)[30], job->app);
+ if(job->of) {
+ back = 1;
+ fputs(hbchm_c8_kw[27], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[28], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[29], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[30], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[31], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[32], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[33], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[34], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[35], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[36], job->of); fputs(hbchm_c8_kw[0], job->of);
+ dk3sto_it_reset(job->i_nodes);
+ while(NULL != (cnptr = (hb_node_t *)dk3sto_it_next(job->i_nodes))) {
+ cnptr->tocstate = HB_TOC_STATE_INIT;
+ }
+ cnptr = job->rootnode;
+ while(cnptr) {
+ switch(cnptr->tocstate) {
+ case HB_TOC_STATE_INIT: {
+ if(cnptr->parent) {
+ /* Write OBJECT for node */
+ for(i = 0;i < cnptr->depth;i++) { fputs(hbchm_c8_kw[38],job->of); }
+ fputs(hbchm_c8_kw[39],job->of); fputs(hbchm_c8_kw[0],job->of);
+ for(i = 0;i < cnptr->depth;i++) { fputs(hbchm_c8_kw[38],job->of); }
+ fputs(hbchm_c8_kw[41],job->of);
+ if(!hbhtml_output_for_text(job, cnptr->title)) { back = 0; }
+ fputs(hbchm_c8_kw[25],job->of);
+ fputs(hbchm_c8_kw[0],job->of);
+ if (0L != cnptr->contnum) {
+ fprintf(job->of, hbchm_c8_kw[76], cnptr->contnum);
+ fputs(hbchm_c8_kw[0],job->of);
+ }
+ if(cnptr->filename) {
+ res = hbhtml_create_output_filename(
+ bu, DK3_SIZEOF(bu,dkChar), job, cnptr
+ );
+ if(res) {
+ for(i = 0;i < cnptr->depth;i++) {
+ fputs(hbchm_c8_kw[38],job->of);
+ }
+ fputs(hbchm_c8_kw[42],job->of);
+ if(!hbhtml_url_output_for_text(job, bu)) { back = 0; }
+ fputs(hbchm_c8_kw[25],job->of);
+ fputs(hbchm_c8_kw[0],job->of);
+ } else {
+ back = 0;
+ }
+ }
+ for(i = 0;i < cnptr->depth;i++) { fputs(hbchm_c8_kw[38],job->of); }
+ fputs(hbchm_c8_kw[40],job->of); fputs(hbchm_c8_kw[0],job->of);
+ } else {
+
+#line 460 "hbchm.ctr"
+ }
+ dk3sto_it_reset(cnptr->i_subnodes);
+ nnptr = (hb_node_t *)dk3sto_it_next(cnptr->i_subnodes);
+ if(nnptr) {
+ /* Write UL */
+ for(i = 0;i < cnptr->depth;i++) {
+ fputs(hbchm_c8_kw[38],job->of);
+ }
+ fputs(hbchm_c8_kw[43],job->of);
+ fputs(hbchm_c8_kw[0],job->of);
+ if (mwrn) {
+ mwrn = 0;
+ if ((!(cnptr->parent)) && (job->rootnode)) {
+ if (cnptr->objno == (job->rootnode)->objno) {
+ if (cnptr->filename) {
+ res = hbhtml_create_output_filename(
+ bu, DK3_SIZEOF(bu,dkChar), job, cnptr
+ );
+ if (res) {
+ fputs(hbchm_c8_kw[38],job->of);
+ fputs(hbchm_c8_kw[39],job->of);
+ fputs(hbchm_c8_kw[0],job->of);
+ fputs(hbchm_c8_kw[38],job->of);
+ fputs(hbchm_c8_kw[41],job->of);
+ /* Title */
+ if (cnptr->title) {
+ if(!hbhtml_output_for_text(job, cnptr->title)) {
+ back = 0;
+ }
+ } else {
+ if(!hbhtml_output_for_text(job, (job->msg)[87])) {
+ back = 0;
+ }
+ }
+ fputs(hbchm_c8_kw[25],job->of);
+ fputs(hbchm_c8_kw[0],job->of);
+ fputs(hbchm_c8_kw[38],job->of);
+ fputs(hbchm_c8_kw[42],job->of);
+ /* File name */
+ if(!hbhtml_url_output_for_text(job, bu)) { back = 0; }
+ fputs(hbchm_c8_kw[25],job->of);
+ fputs(hbchm_c8_kw[0],job->of);
+ fputs(hbchm_c8_kw[38],job->of);
+ fputs(hbchm_c8_kw[40],job->of);
+ fputs(hbchm_c8_kw[0],job->of);
+ }
+ }
+ }
+ }
+ }
+ cnptr->tocstate = HB_TOC_STATE_IN_PROGRESS;
+ cnptr = nnptr;
+ } else {
+ cnptr->tocstate = HB_TOC_STATE_FINISHED;
+ cnptr = cnptr->parent;
+ }
+ } break;
+ case HB_TOC_STATE_IN_PROGRESS: {
+ nnptr = (hb_node_t *)dk3sto_it_next(cnptr->i_subnodes);
+ if(nnptr) {
+ cnptr = nnptr;
+ } else {
+ /* Write /UL */
+ for(i = 0;i < cnptr->depth;i++) {
+ fputs(hbchm_c8_kw[38],job->of);
+ }
+ fputs(hbchm_c8_kw[44],job->of);
+ fputs(hbchm_c8_kw[0],job->of);
+ cnptr->tocstate = HB_TOC_STATE_FINISHED;
+ cnptr = cnptr->parent;
+ }
+ } break;
+ case HB_TOC_STATE_FINISHED: {
+ cnptr = cnptr->parent;
+ } break;
+ }
+ }
+ fputs(hbchm_c8_kw[37], job->of); fputs(hbchm_c8_kw[0], job->of);
+ if(!dk3sf_fclose_fn_app(job->of, (job->kwnl)[28], job->app)) { back = 0; }
+ }
+
+#line 540 "hbchm.ctr"
+ return back;
+}
+
+
+
+/** Write hhk file (Keyword index).
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbchm_write_hhk(hb_job_t *job)
+{
+ hb_index_entry_t *ie; /* Current index entry to process */
+ int back = 0;
+
+
+#line 556 "hbchm.ctr"
+ job->of = dk3sf_fopen_app((job->kwnl)[29], (job->kwnl)[30], job->app);
+ if(job->of) {
+ back = 1;
+ fputs(hbchm_c8_kw[13], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[14], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[15], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[16], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[17], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[18], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[19], job->of); fputs(hbchm_c8_kw[0], job->of);
+ dk3sto_it_reset(job->i_index);
+ while(NULL != (ie = (hb_index_entry_t *)dk3sto_it_next(job->i_index))) {
+ fputs(hbchm_c8_kw[22], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[23], job->of);
+ if(!hbhtml_output_for_text(job, ie->tx)) { back = 0; }
+ fputs(hbchm_c8_kw[25], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[24], job->of);
+ if(ie->fn) {
+ if(!hbhtml_url_output_for_text(job, ie->fn)) { back = 0; }
+ }
+ fputs(hbchm_c8_kw[26], job->of);
+ if(!hb_index_write_anchor(job, ie)) { back = 0; }
+ fputs(hbchm_c8_kw[25], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[40], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ }
+ fputs(hbchm_c8_kw[20], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[21], job->of); fputs(hbchm_c8_kw[0], job->of);
+ if(!dk3sf_fclose_fn_app(job->of, (job->kwnl)[29], job->app)) { back = 0; }
+ }
+
+#line 588 "hbchm.ctr"
+ return back;
+}
+
+
+
+/** Write XML project file for chmcmd.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbchm_write_xml(hb_job_t *job)
+{
+ dkChar of[DK3_MAX_PATH]; /* XML output file name */
+ dkChar const *fn; /* File name in list */
+ hb_node_t *nptr; /* Current node */
+ unsigned long count; /* Number of files in list */
+ unsigned long cu; /* Current file number */
+ int back = 0;
+ job->of = dk3sf_fopen_app((job->kwnl)[36], (job->kwnl)[30], job->app);
+ if (job->of) {
+ back = 1;
+ /* xml */
+ fputs(hbchm_c8_kw[45], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ /* CONFIG */
+ fputs(hbchm_c8_kw[46], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ /* Files */
+ fputs(hbchm_c8_kw[48], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ count = 0UL;
+ cu = 0UL;
+ dk3sto_it_reset(job->i_files);
+ while (NULL != (fn = (dkChar const *)dk3sto_it_next(job->i_files))) {
+ count++;
+ }
+ dk3sto_it_reset(job->i_pnodes);
+ while (NULL != (nptr = (hb_node_t *)dk3sto_it_next(job->i_pnodes))) {
+ if (!(nptr->jumpnode)) {
+ if (hbhtml_create_output_filename(of,DK3_SIZEOF(of,dkChar),job,nptr)) {
+ if (!(dk3sto_it_find_like(job->i_files, of, 0))) {
+ count++;
+ }
+ }
+ }
+ }
+ fprintf(job->of, hbchm_c8_kw[72], count);
+ fputs(hbchm_c8_kw[0], job->of);
+ dk3sto_it_reset(job->i_files);
+ while (NULL != (fn = (dkChar const *)dk3sto_it_next(job->i_files))) {
+ fprintf(job->of, hbchm_c8_kw[73], cu++);
+ if (!(hbtool_write_text_utf(job, fn))) { back = 0; }
+ fputs(hbchm_c8_kw[74], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ }
+ dk3sto_it_reset(job->i_pnodes);
+ while (NULL != (nptr = (hb_node_t *)dk3sto_it_next(job->i_pnodes))) {
+ if (!(nptr->jumpnode)) {
+ if (hbhtml_create_output_filename(of,DK3_SIZEOF(of,dkChar),job,nptr)) {
+ if (!(dk3sto_it_find_like(job->i_files, of, 0))) {
+ fprintf(job->of, hbchm_c8_kw[73], cu++);
+ if (!(hbtool_write_text_utf(job, of))) { back = 0; }
+ fputs(hbchm_c8_kw[74], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ }
+ }
+ }
+ }
+ /* /Files */
+ fputs(hbchm_c8_kw[49], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ /* OtherFiles */
+ fputs(hbchm_c8_kw[50], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[52], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[51], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+
+ /* Windows */
+ fputs(hbchm_c8_kw[53], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[52], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[54], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+
+ /* MergeFiles */
+ fputs(hbchm_c8_kw[55], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[52], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[56], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+
+ /* Settings */
+ fputs(hbchm_c8_kw[57], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ if ((job->options) & HB_JOB_OPT_CREATE_INDEX) {
+ fputs(hbchm_c8_kw[59], job->of);
+ if (!(hbtool_write_text_utf(job, (job->kwnl)[29]))) { back = 0; }
+ fputs(hbchm_c8_kw[60], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ }
+ fputs(hbchm_c8_kw[61], job->of);
+ if (!(hbtool_write_text_utf(job, (job->kwnl)[28]))) { back = 0; }
+ fputs(hbchm_c8_kw[60], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[62], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[63], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[64], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[65], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[66], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[67], job->of);
+ if (job->rootnode) {
+ if ((job->rootnode)->title) {
+ if (!(hbtool_write_text_utf(job, (job->rootnode)->title))) { back = 0; }
+ }
+ }
+ fputs(hbchm_c8_kw[60], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[68], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[69], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[70], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[71], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[58], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ /* /CONFIG */
+ fputs(hbchm_c8_kw[47], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ if(!dk3sf_fclose_fn_app(job->of, (job->kwnl)[36], job->app)) { back = 0; }
+ } else {
+ }
+ return back;
+}
+
+
+
+int
+hbchm_write_project(hb_job_t *job)
+{
+ int haveindex; /* Flag: Must write index */
+ int back = 1;
+
+
+#line 742 "hbchm.ctr"
+ haveindex = hbchm_have_index_entries(job);
+ if(!hbchm_write_xml(job)) { back = 0; }
+ if(!hbchm_write_hhp(job, haveindex)) { back = 0; }
+ if(!hbchm_write_hhc(job)) { back = 0; }
+ if(haveindex) {
+ if(!hbchm_write_hhk(job)) { back = 0; }
+ }
+
+#line 749 "hbchm.ctr"
+ return back;
+}
+
+
diff --git a/support/dktools/hbchm.ctr b/support/dktools/hbchm.ctr
new file mode 100644
index 0000000000..5b35769bc1
--- /dev/null
+++ b/support/dktools/hbchm.ctr
@@ -0,0 +1,752 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2013-xxxx
+license = bsd
+
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Write files needed by the HTML help compiler.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+hbchm_write_project(hb_job_t *job);
+
+/** Check whether there are index entries available.
+ @param job Job structure.
+ @return 1 if we must write an index file, 0 otherwise.
+*/
+int
+hbchm_have_index_entries(hb_job_t *job);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+
+#include "dk3all.h"
+#include "htmlbook.h"
+
+
+
+$!trace-include
+
+
+
+/** 8-bit character keywords, not localized.
+*/
+static char const * const hbchm_c8_kw[] = {
+$!string-table
+#
+# 0 Newline for DOS text files
+#
+\r\n
+#
+# 1 2 3 4 5 6 7 8 9
+#
+[OPTIONS]
+Compiled file=index.chm
+Contents file=contents.hhc
+Index file=index.hhk
+Compatibility=1.1 or later
+Display compile progress=Yes
+Language=
+Title=
+Default topic=
+#
+# 10 Default language
+#
+0x409 English (USA)
+#
+# 11 Files section
+#
+[FILES]
+#
+# 12 Infotypes section
+#
+[INFOTYPES]
+#
+# 13 14 15 16 17 18 19 Header of index file
+#
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<HTML>
+<HEAD>
+<meta name="GENERATOR" content="Microsoft&reg; HTML Help Workshop 4.1">
+<!-- Sitemap 1.0 -->
+</HEAD><BODY>
+<UL>
+#
+# 20 21 Footer of index file.
+#
+</UL>
+</BODY></HTML>
+#
+# 22 23 24 25 Strings for entry
+#
+<LI><OBJECT type="text/sitemap">
+ <param name="Name" value="
+ <param name="Local" value="
+">
+#
+# 26
+#
+\#
+#
+# 27-36
+#
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<HTML>
+<HEAD>
+<meta name="GENERATOR" content="Microsoft&reg; HTML Help Workshop 4.1">
+<!-- Sitemap 1.0 -->
+</HEAD><BODY>
+<OBJECT type="text/site properties">
+ <param name="Window Styles" value="0x800025">
+ <param name="ImageType" value="Folder">
+</OBJECT>
+#
+# 37
+#
+</BODY></HTML>
+#
+# 38 (four spaces)
+#
+
+#
+# 39 40
+#
+<LI><OBJECT type="text/sitemap">
+ </OBJECT>
+#
+# 41 42
+#
+ <param name="Name" value="
+ <param name="Local" value="
+#
+# 43 44
+#
+<UL>
+</UL>
+#
+# 45
+#
+<?xml version="1.0" encoding="utf-8"?>
+#
+# 46 47
+#
+<CONFIG>
+</CONFIG>
+#
+# 48 49
+#
+ <Files>
+ </Files>
+#
+# 50 51
+#
+ <OtherFiles>
+ </OtherFiles>
+#
+# 52
+#
+ <Count Value="0"/>
+#
+# 53 54
+#
+ <Windows>
+ </Windows>
+#
+# 55 56
+#
+ <MergeFiles>
+ </MergeFiles>
+#
+# 57 58
+#
+ <Settings>
+ </Settings>
+#
+# 59 60
+#
+ <IndexFile Value="
+"/>
+#
+# 61
+#
+ <TOCFile Value="
+#
+# 62 ... 71
+#
+ <MakeBinaryTOC Value="False"/>
+ <MakeBinaryIndex Value="True"/>
+ <AutoFollowLinks Value="False"/>
+ <MakeSearchable Value="True"/>
+ <DefaultPage Value="index.html"/>
+ <Title Value="
+ <OutputFileName Value="index.chm"/>
+ <DefaultFont Value=""/>
+ <DefaultWindow Value=""/>
+ <ScanHtmlContents Value="True"/>
+#
+# 72
+#
+ <Count Value="%lu"/>
+#
+# 73 74
+#
+ <FileName%lu Value="
+" ContextName="" ContextNumber="0"/>
+#
+# 75
+#
+Test
+#
+# 76
+#
+ <param name="ID" value="%ld">
+#
+# 77 78 79 80 81 82 83 84 85 86
+#
+Binary TOC=No
+Binary Index=Yes
+Default Window=
+Default Font=
+Full-text search=Yes
+Auto Index=Yes
+Create CHI file=No
+Full text search stop list file=
+Display compile progress=Yes
+Display compile notes=Yes
+#
+# 87
+#
+Full-text search=No
+$!end
+};
+
+
+
+int
+hbchm_have_index_entries(hb_job_t *job)
+{
+ int back = 0;
+ $? "+ hbchm_have_index_entries"
+ if ((job->i_index) && (job->s_index)) {
+ dk3sto_it_reset(job->i_index);
+ if(dk3sto_it_next(job->i_index)) { back = 1; }
+ }
+ $? "- hbchm_have_index_entries %d", back
+ return back;
+}
+
+
+
+/** Write hhp file (project).
+ @param job Job structure.
+ @param haveindex Flag: Need to write an index file.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbchm_write_hhp(hb_job_t *job, int haveindex)
+{
+ dkChar fn[DK3_MAX_PATH]; /* Name of output file */
+ dkChar of[DK3_MAX_PATH]; /* Output file name */
+ dkChar const *onefn; /* Resource file name */
+ hb_node_t *nptr; /* Root node or first node */
+ int res; /* Operation result */
+ int back = 0;
+ $? "+ hbchm_write_hhp"
+ job->of = dk3sf_fopen_app((job->kwnl)[26], (job->kwnl)[30], job->app);
+ if(job->of) {
+ back = 1;
+ /* Write options section
+ */
+ fputs(hbchm_c8_kw[1], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[77], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[78], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[2], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[3], job->of); fputs(hbchm_c8_kw[0], job->of);
+ if(haveindex) {
+ fputs(hbchm_c8_kw[4], job->of); fputs(hbchm_c8_kw[0], job->of);
+ }
+ fputs(hbchm_c8_kw[79], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[80], job->of); fputs(hbchm_c8_kw[0], job->of);
+ if ((job->options) & HB_JOB_OPT_CHM_FULL_TEXT_SEARCH) {
+ fputs(hbchm_c8_kw[81], job->of);
+ } else {
+ fputs(hbchm_c8_kw[87], job->of);
+ }
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[82], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[83], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[84], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[85], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[86], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[5], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[6], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[7], job->of);
+ /* Language */
+ if(job->chmlang) {
+ res = dk3se_ansi_fputs(
+ job->chmlang, dk3app_get_encoding(job->app), job->of, job->app
+ );
+ if(!(res)) { back = 0; }
+ } else {
+ fputs(hbchm_c8_kw[10], job->of);
+ }
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[8], job->of);
+ if (job->rootnode) {
+ if ((job->rootnode)->title) {
+ res = dk3se_ansi_fputs(
+ (job->rootnode)->title, dk3app_get_encoding(job->app),
+ job->of, job->app
+ );
+ if(!(res)) { back = 0; }
+ } else {
+ fputs(hbchm_c8_kw[75], job->of);
+ }
+ } else {
+ fputs(hbchm_c8_kw[75], job->of);
+ }
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[9], job->of);
+ /* Default topic */
+ if (NULL != job->rootnode) {
+ nptr = job->rootnode;
+ if(!(nptr->filename)) { nptr = nptr->jumpnode; }
+ if(nptr) {
+ if(hbhtml_create_output_filename(fn,DK3_SIZEOF(fn,dkChar),job,nptr)) {
+ res = dk3se_ansi_fputs(
+ fn, dk3app_get_encoding(job->app), job->of, job->app
+ );
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ } else {
+ back = 0;
+ /* ERROR: No default topic found! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 47);
+ }
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ }
+ /* Write files section - files mentioned explicitly
+ */
+ fputs(hbchm_c8_kw[11], job->of); fputs(hbchm_c8_kw[0], job->of);
+ dk3sto_it_reset(job->i_files);
+ while(NULL != (onefn = (dkChar const *)dk3sto_it_next(job->i_files))) {
+ res = dk3se_ansi_fputs(
+ onefn, dk3app_get_encoding(job->app), job->of, job->app
+ );
+ if(!(res)) { back = 0; }
+ fputs(hbchm_c8_kw[0], job->of);
+ }
+#if (!(VERSION_BEFORE_20140416))
+ /* 2014-04-16
+ Write files section - HTML files not mentioned explicitly.
+ */
+ dk3sto_it_reset(job->i_pnodes);
+ while (NULL != (nptr = (hb_node_t *)dk3sto_it_next(job->i_pnodes))) {
+ if (!(nptr->jumpnode)) {
+ if (hbhtml_create_output_filename(of,DK3_SIZEOF(of,dkChar),job,nptr)) {
+ if (!(dk3sto_it_find_like(job->i_files, of, 0))) {
+ res = dk3se_ansi_fputs(
+ of, dk3app_get_encoding(job->app), job->of, job->app
+ );
+ if(!(res)) { back = 0; }
+ fputs(hbchm_c8_kw[0], job->of);
+ }
+ }
+ }
+ }
+#endif
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[12], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ if(!dk3sf_fclose_fn_app(job->of, (job->kwnl)[26], job->app)) { back = 0; }
+ }
+ if(!hbtool_add_file(job, (job->kwnl)[26])) { back = 0; }
+ if(!hbtool_add_file(job, (job->kwnl)[28])) { back = 0; }
+ if(haveindex) {
+ if(!hbtool_add_file(job, (job->kwnl)[29])) { back = 0; }
+ } $? "- hbchm_write_hhp %d", back
+ return back;
+}
+
+
+
+/** Write hhc file (table of contents).
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbchm_write_hhc(hb_job_t *job)
+{
+ dkChar bu[DK3_MAX_PATH]; /* Name of output file */
+ hb_node_t *cnptr; /* Current node to process */
+ hb_node_t *nnptr; /* Next node to process */
+ int i; /* Used to print spaces */
+ int res; /* Operation result */
+ int mwrn = 1; /* Flag: Must write root node */
+ int back = 0;
+ $? "+ hbchm_write_hhc"
+ job->of = dk3sf_fopen_app((job->kwnl)[28], (job->kwnl)[30], job->app);
+ if(job->of) {
+ back = 1;
+ fputs(hbchm_c8_kw[27], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[28], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[29], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[30], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[31], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[32], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[33], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[34], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[35], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[36], job->of); fputs(hbchm_c8_kw[0], job->of);
+ dk3sto_it_reset(job->i_nodes);
+ while(NULL != (cnptr = (hb_node_t *)dk3sto_it_next(job->i_nodes))) {
+ cnptr->tocstate = HB_TOC_STATE_INIT;
+ }
+ cnptr = job->rootnode;
+ while(cnptr) {
+ switch(cnptr->tocstate) {
+ case HB_TOC_STATE_INIT: {
+ if(cnptr->parent) {
+ /* Write OBJECT for node */
+ for(i = 0;i < cnptr->depth;i++) { fputs(hbchm_c8_kw[38],job->of); }
+ fputs(hbchm_c8_kw[39],job->of); fputs(hbchm_c8_kw[0],job->of);
+ for(i = 0;i < cnptr->depth;i++) { fputs(hbchm_c8_kw[38],job->of); }
+ fputs(hbchm_c8_kw[41],job->of);
+ if(!hbhtml_output_for_text(job, cnptr->title)) { back = 0; }
+ fputs(hbchm_c8_kw[25],job->of);
+ fputs(hbchm_c8_kw[0],job->of);
+ if (0L != cnptr->contnum) {
+ fprintf(job->of, hbchm_c8_kw[76], cnptr->contnum);
+ fputs(hbchm_c8_kw[0],job->of);
+ }
+ if(cnptr->filename) {
+ res = hbhtml_create_output_filename(
+ bu, DK3_SIZEOF(bu,dkChar), job, cnptr
+ );
+ if(res) {
+ for(i = 0;i < cnptr->depth;i++) {
+ fputs(hbchm_c8_kw[38],job->of);
+ }
+ fputs(hbchm_c8_kw[42],job->of);
+ if(!hbhtml_url_output_for_text(job, bu)) { back = 0; }
+ fputs(hbchm_c8_kw[25],job->of);
+ fputs(hbchm_c8_kw[0],job->of);
+ } else {
+ back = 0;
+ }
+ }
+ for(i = 0;i < cnptr->depth;i++) { fputs(hbchm_c8_kw[38],job->of); }
+ fputs(hbchm_c8_kw[40],job->of); fputs(hbchm_c8_kw[0],job->of);
+ } else { $? ". no parent, probably root node"
+ }
+ dk3sto_it_reset(cnptr->i_subnodes);
+ nnptr = (hb_node_t *)dk3sto_it_next(cnptr->i_subnodes);
+ if(nnptr) {
+ /* Write UL */
+ for(i = 0;i < cnptr->depth;i++) {
+ fputs(hbchm_c8_kw[38],job->of);
+ }
+ fputs(hbchm_c8_kw[43],job->of);
+ fputs(hbchm_c8_kw[0],job->of);
+ if (mwrn) {
+ mwrn = 0;
+ if ((!(cnptr->parent)) && (job->rootnode)) {
+ if (cnptr->objno == (job->rootnode)->objno) {
+ if (cnptr->filename) {
+ res = hbhtml_create_output_filename(
+ bu, DK3_SIZEOF(bu,dkChar), job, cnptr
+ );
+ if (res) {
+ fputs(hbchm_c8_kw[38],job->of);
+ fputs(hbchm_c8_kw[39],job->of);
+ fputs(hbchm_c8_kw[0],job->of);
+ fputs(hbchm_c8_kw[38],job->of);
+ fputs(hbchm_c8_kw[41],job->of);
+ /* Title */
+ if (cnptr->title) {
+ if(!hbhtml_output_for_text(job, cnptr->title)) {
+ back = 0;
+ }
+ } else {
+ if(!hbhtml_output_for_text(job, (job->msg)[87])) {
+ back = 0;
+ }
+ }
+ fputs(hbchm_c8_kw[25],job->of);
+ fputs(hbchm_c8_kw[0],job->of);
+ fputs(hbchm_c8_kw[38],job->of);
+ fputs(hbchm_c8_kw[42],job->of);
+ /* File name */
+ if(!hbhtml_url_output_for_text(job, bu)) { back = 0; }
+ fputs(hbchm_c8_kw[25],job->of);
+ fputs(hbchm_c8_kw[0],job->of);
+ fputs(hbchm_c8_kw[38],job->of);
+ fputs(hbchm_c8_kw[40],job->of);
+ fputs(hbchm_c8_kw[0],job->of);
+ }
+ }
+ }
+ }
+ }
+ cnptr->tocstate = HB_TOC_STATE_IN_PROGRESS;
+ cnptr = nnptr;
+ } else {
+ cnptr->tocstate = HB_TOC_STATE_FINISHED;
+ cnptr = cnptr->parent;
+ }
+ } break;
+ case HB_TOC_STATE_IN_PROGRESS: {
+ nnptr = (hb_node_t *)dk3sto_it_next(cnptr->i_subnodes);
+ if(nnptr) {
+ cnptr = nnptr;
+ } else {
+ /* Write /UL */
+ for(i = 0;i < cnptr->depth;i++) {
+ fputs(hbchm_c8_kw[38],job->of);
+ }
+ fputs(hbchm_c8_kw[44],job->of);
+ fputs(hbchm_c8_kw[0],job->of);
+ cnptr->tocstate = HB_TOC_STATE_FINISHED;
+ cnptr = cnptr->parent;
+ }
+ } break;
+ case HB_TOC_STATE_FINISHED: {
+ cnptr = cnptr->parent;
+ } break;
+ }
+ }
+ fputs(hbchm_c8_kw[37], job->of); fputs(hbchm_c8_kw[0], job->of);
+ if(!dk3sf_fclose_fn_app(job->of, (job->kwnl)[28], job->app)) { back = 0; }
+ } $? "- hbchm_write_hhc %d", back
+ return back;
+}
+
+
+
+/** Write hhk file (Keyword index).
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbchm_write_hhk(hb_job_t *job)
+{
+ hb_index_entry_t *ie; /* Current index entry to process */
+ int back = 0;
+ $? "+ hbchm_write_hhk"
+ job->of = dk3sf_fopen_app((job->kwnl)[29], (job->kwnl)[30], job->app);
+ if(job->of) {
+ back = 1;
+ fputs(hbchm_c8_kw[13], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[14], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[15], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[16], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[17], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[18], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[19], job->of); fputs(hbchm_c8_kw[0], job->of);
+ dk3sto_it_reset(job->i_index);
+ while(NULL != (ie = (hb_index_entry_t *)dk3sto_it_next(job->i_index))) {
+ fputs(hbchm_c8_kw[22], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[23], job->of);
+ if(!hbhtml_output_for_text(job, ie->tx)) { back = 0; }
+ fputs(hbchm_c8_kw[25], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[24], job->of);
+ if(ie->fn) {
+ if(!hbhtml_url_output_for_text(job, ie->fn)) { back = 0; }
+ }
+ fputs(hbchm_c8_kw[26], job->of);
+ if(!hb_index_write_anchor(job, ie)) { back = 0; }
+ fputs(hbchm_c8_kw[25], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[40], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ }
+ fputs(hbchm_c8_kw[20], job->of); fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[21], job->of); fputs(hbchm_c8_kw[0], job->of);
+ if(!dk3sf_fclose_fn_app(job->of, (job->kwnl)[29], job->app)) { back = 0; }
+ } $? "- hbchm_write_hhk %d", back
+ return back;
+}
+
+
+
+/** Write XML project file for chmcmd.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbchm_write_xml(hb_job_t *job)
+{
+ dkChar of[DK3_MAX_PATH]; /* XML output file name */
+ dkChar const *fn; /* File name in list */
+ hb_node_t *nptr; /* Current node */
+ unsigned long count; /* Number of files in list */
+ unsigned long cu; /* Current file number */
+ int back = 0;
+ job->of = dk3sf_fopen_app((job->kwnl)[36], (job->kwnl)[30], job->app);
+ if (job->of) {
+ back = 1;
+ /* xml */
+ fputs(hbchm_c8_kw[45], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ /* CONFIG */
+ fputs(hbchm_c8_kw[46], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ /* Files */
+ fputs(hbchm_c8_kw[48], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ count = 0UL;
+ cu = 0UL;
+ dk3sto_it_reset(job->i_files);
+ while (NULL != (fn = (dkChar const *)dk3sto_it_next(job->i_files))) {
+ count++;
+ }
+ dk3sto_it_reset(job->i_pnodes);
+ while (NULL != (nptr = (hb_node_t *)dk3sto_it_next(job->i_pnodes))) {
+ if (!(nptr->jumpnode)) {
+ if (hbhtml_create_output_filename(of,DK3_SIZEOF(of,dkChar),job,nptr)) {
+ if (!(dk3sto_it_find_like(job->i_files, of, 0))) {
+ count++;
+ }
+ }
+ }
+ }
+ fprintf(job->of, hbchm_c8_kw[72], count);
+ fputs(hbchm_c8_kw[0], job->of);
+ dk3sto_it_reset(job->i_files);
+ while (NULL != (fn = (dkChar const *)dk3sto_it_next(job->i_files))) {
+ fprintf(job->of, hbchm_c8_kw[73], cu++);
+ if (!(hbtool_write_text_utf(job, fn))) { back = 0; }
+ fputs(hbchm_c8_kw[74], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ }
+ dk3sto_it_reset(job->i_pnodes);
+ while (NULL != (nptr = (hb_node_t *)dk3sto_it_next(job->i_pnodes))) {
+ if (!(nptr->jumpnode)) {
+ if (hbhtml_create_output_filename(of,DK3_SIZEOF(of,dkChar),job,nptr)) {
+ if (!(dk3sto_it_find_like(job->i_files, of, 0))) {
+ fprintf(job->of, hbchm_c8_kw[73], cu++);
+ if (!(hbtool_write_text_utf(job, of))) { back = 0; }
+ fputs(hbchm_c8_kw[74], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ }
+ }
+ }
+ }
+ /* /Files */
+ fputs(hbchm_c8_kw[49], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ /* OtherFiles */
+ fputs(hbchm_c8_kw[50], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[52], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[51], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+
+ /* Windows */
+ fputs(hbchm_c8_kw[53], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[52], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[54], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+
+ /* MergeFiles */
+ fputs(hbchm_c8_kw[55], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[52], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[56], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+
+ /* Settings */
+ fputs(hbchm_c8_kw[57], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ if ((job->options) & HB_JOB_OPT_CREATE_INDEX) {
+ fputs(hbchm_c8_kw[59], job->of);
+ if (!(hbtool_write_text_utf(job, (job->kwnl)[29]))) { back = 0; }
+ fputs(hbchm_c8_kw[60], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ }
+ fputs(hbchm_c8_kw[61], job->of);
+ if (!(hbtool_write_text_utf(job, (job->kwnl)[28]))) { back = 0; }
+ fputs(hbchm_c8_kw[60], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[62], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[63], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[64], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[65], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[66], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[67], job->of);
+ if (job->rootnode) {
+ if ((job->rootnode)->title) {
+ if (!(hbtool_write_text_utf(job, (job->rootnode)->title))) { back = 0; }
+ }
+ }
+ fputs(hbchm_c8_kw[60], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[68], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[69], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[70], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[71], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ fputs(hbchm_c8_kw[58], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ /* /CONFIG */
+ fputs(hbchm_c8_kw[47], job->of);
+ fputs(hbchm_c8_kw[0], job->of);
+ if(!dk3sf_fclose_fn_app(job->of, (job->kwnl)[36], job->app)) { back = 0; }
+ } else {
+ }
+ return back;
+}
+
+
+
+int
+hbchm_write_project(hb_job_t *job)
+{
+ int haveindex; /* Flag: Must write index */
+ int back = 1;
+ $? "+ hbchm_write_project"
+ haveindex = hbchm_have_index_entries(job);
+ if(!hbchm_write_xml(job)) { back = 0; }
+ if(!hbchm_write_hhp(job, haveindex)) { back = 0; }
+ if(!hbchm_write_hhc(job)) { back = 0; }
+ if(haveindex) {
+ if(!hbchm_write_hhk(job)) { back = 0; }
+ } $? "- hbchm_write_project %d", back
+ return back;
+}
+
+
diff --git a/support/dktools/hbchm.h b/support/dktools/hbchm.h
new file mode 100644
index 0000000000..8debc4b18f
--- /dev/null
+++ b/support/dktools/hbchm.h
@@ -0,0 +1,69 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: hbchm.ctr
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file hbchm.h Header file for the hbchm module.
+*/
+
+#ifndef HBCHM_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define HBCHM_H_INCLUDED 1
+
+
+#line 10 "hbchm.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Write files needed by the HTML help compiler.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+hbchm_write_project(hb_job_t *job);
+
+/** Check whether there are index entries available.
+ @param job Job structure.
+ @return 1 if we must write an index file, 0 otherwise.
+*/
+int
+hbchm_have_index_entries(hb_job_t *job);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/hbconf.c b/support/dktools/hbconf.c
new file mode 100644
index 0000000000..aacf80d2c3
--- /dev/null
+++ b/support/dktools/hbconf.c
@@ -0,0 +1,1485 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: hbconf.ctr
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file hbconf.c The hbconf module.
+*/
+
+
+#line 100 "hbconf.ctr"
+
+#include "dk3all.h"
+#include "htmlbook.h"
+
+
+
+
+
+#line 107 "hbconf.ctr"
+
+
+
+/** Names of configuration file options.
+*/
+dkChar const * const hbconf_options[] = {
+/* 0 */
+dkT("author"),
+
+/* 1 */
+dkT("title"),
+
+/* 2 */
+dkT("url"),
+
+/* 3 */
+dkT("output directory"),
+
+/* 4 */
+dkT("output script"),
+
+/* 5 */
+dkT("html charset"),
+
+/* 6 */
+dkT("template"),
+
+/* 7 */
+dkT("style"),
+
+/* 8 */
+dkT("page toc"),
+
+/* 9 */
+dkT("index file"),
+
+/* 10 */
+dkT("create index"),
+
+/* 11 */
+dkT("replace ampersand"),
+
+/* 12 */
+dkT("tidy"),
+
+/* 13 */
+dkT("location"),
+
+/* 14 */
+dkT("write position"),
+
+/* 15 */
+dkT("navigation"),
+
+/* 16 */
+dkT("short"),
+
+/* 17 */
+dkT("file"),
+
+/* 18 */
+dkT("suffix"),
+
+/* 19 */
+dkT("icon toc"),
+
+/* 20 */
+dkT("icon previous"),
+
+/* 21 */
+dkT("icon next"),
+
+/* 22 */
+dkT("icon index"),
+
+/* 23 */
+dkT("create toc"),
+
+/* 24 */
+dkT("shortcut icon"),
+
+/* 25 */
+dkT("var"),
+
+/* 26 */
+dkT("impressum link"),
+
+/* 27 */
+dkT("impressum page"),
+
+/* 28 */
+dkT("chm"),
+
+/* 29 */
+dkT("ln"),
+
+/* 30 */
+dkT("input encoding"),
+
+/* 31 */
+dkT("chm language"),
+
+/* 32 */
+dkT("js file"),
+
+/* 33 */
+dkT("inherit js"),
+
+/* 34 */
+dkT("section numbers in position"),
+
+/* 35 */
+dkT("section numbers in index"),
+
+/* 36 */
+dkT("section numbers in page header"),
+
+/* 37 */
+dkT("context number"),
+
+/* 38 */
+dkT("chm full text search"),
+
+/* 39 */
+dkT("code line numbers"),
+
+/* 40 */
+dkT("icon home"),
+
+NULL
+
+
+#line 279 "hbconf.ctr"
+};
+
+
+
+/** Character sets for HTML output.
+*/
+dkChar const * const hbconf_charsets[] = {
+/* 0 */
+dkT("utf-8"),
+
+/* 1 */
+dkT("ascii"),
+
+/* 2 */
+dkT("us-ascii"),
+
+NULL
+
+
+#line 291 "hbconf.ctr"
+};
+
+
+
+/** Set jump node for the nodes parents.
+ @param nodeptr Text node.
+*/
+static
+void
+hbconf_set_jump_node(hb_node_t *nodeptr)
+{
+ hb_node_t *parent; /* Parent node */
+ int cc; /* Flag: Can continue */
+
+
+#line 305 "hbconf.ctr"
+ parent = nodeptr->parent;
+ cc = 1;
+ while(cc) {
+ if(parent) {
+ if(parent->jumpnode) {
+ cc = 0;
+ } else {
+ if(-1 != parent->indent) {
+ parent->jumpnode = nodeptr;
+ parent = parent->parent;
+ } else {
+ cc = 0;
+ }
+ }
+ } else {
+ cc = 0;
+ }
+ }
+
+#line 323 "hbconf.ctr"
+}
+
+
+
+/** Process one configuration line from configuration file.
+ @param job Job structure.
+ @param il Input line to process.
+ @param st Current section type, HB_SECTION_OPTIONS
+ or HB_SECTION_CONTENTS.
+ @return 1 on success, 0 on error (continue), -1 on error (exit).
+*/
+int
+hbconf_process_line(hb_job_t *job, dkChar *il, int st)
+{
+ dk3_key_value_t *kvp; /* New key value pair */
+ hb_link_t *linkptr; /* New data for JS file */
+ dkChar *kp; /* Key */
+ dkChar *vp; /* Value */
+ dkChar *ap; /* Argument */
+ dkChar *nc; /* New text for existing key/value */
+ dkChar *ptr; /* Traverse string */
+ int newie; /* Input encoding */
+ int back = 1;
+
+
+#line 347 "hbconf.ctr"
+ kp = dk3str_start(il, NULL);
+ if(kp) {
+ if(dkT('#') != *kp) {
+ vp = dk3str_chr(kp, dkT('='));
+ if(vp) {
+ *(vp++) = dkT('\0');
+ vp = dk3str_start(vp, NULL);
+ if(vp) {
+ dk3str_normalize(kp, NULL, dkT(' '));
+ dk3str_chomp(vp, NULL);
+ switch(dk3str_array_index(hbconf_options, kp, 0)) {
+ case 0: { /* author */
+ if(job->currentnode) {
+ ptr = dk3str_dup_app(vp,job->app);
+ if(ptr) {
+ if((job->currentnode)->author) {
+ if(0UL != (job->currentnode)->objno) {
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 69);
+ }
+ }
+ dk3_release((job->currentnode)->author);
+ (job->currentnode)->author = ptr;
+ } else {
+ back = -1; /* REPORTED */
+ }
+ }
+ } break;
+ case 1: { /* title */
+ if(job->currentnode) {
+ ptr = dk3str_dup_app(vp,job->app);
+ if(ptr) {
+
+#if VERSION_BEFORE_20161026
+ if((job->currentnode)->title) {
+ if(0UL != (job->currentnode)->objno) {
+ /* Overwriting title */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 70);
+ }
+ }
+ dk3_release((job->currentnode)->title);
+ (job->currentnode)->title = ptr;
+#else
+ if((job->currentnode)->title) {
+ if ((job->currentnode)->fulltitle) {
+ if (0UL != (job->currentnode)->objno) {
+ /* Overwriting title */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 70);
+ }
+ dk3mem_free((job->currentnode)->fulltitle);
+ }
+ (job->currentnode)->fulltitle = ptr;
+ } else {
+ (job->currentnode)->title = ptr;
+ }
+#endif
+ } else {
+ back = -1; /* REPORTED */
+ }
+ }
+ } break;
+ case 2: { /* url */
+ if(HB_SECTION_OPTIONS == st) {
+ ptr = dk3str_dup_app(vp,job->app);
+ if(ptr) {
+ dk3_release(job->url);
+ job->url = ptr;
+ } else {
+ back = -1; /* REPORTED */
+ }
+ } else {
+ /* ERROR: Only allowed in options section */
+ dk3app_log_1(job->app,DK3_LL_ERROR,job->msg,38);
+ back = -1;
+ }
+ } break;
+ case 3: { /* output directory */
+ if(HB_SECTION_OPTIONS == st) {
+ ptr = dk3str_dup_app(vp,job->app);
+ if(ptr) {
+ dk3str_correct_filename(ptr);
+ if(job->outputdir) {
+ /* Overwrite output directory */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 71);
+ }
+ dk3_release(job->outputdir);
+ job->outputdir = ptr;
+ /* CHECK FILENAME CHARACTERS */
+ if(!hbtool_check_filename_encoding(job, ptr)) {
+ back = -1;
+ }
+ } else {
+ back = -1; /* REPORTED */
+ }
+ } else {
+ /* ERROR: Only allowed in options section */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 10);
+ }
+ } break;
+ case 4: { /* output script */
+ if(HB_SECTION_OPTIONS == st) {
+ ptr = dk3str_dup_app(vp,job->app);
+ if(ptr) {
+ if(job->outputscript) {
+ /* Overwrite output script */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 72);
+ }
+ dk3_release(job->outputscript);
+ job->outputscript = ptr;
+ /* CHECK FILENAME CHARACTERS */
+ if(!hbtool_check_filename(job, ptr)) {
+ back = -1;
+ }
+ } else {
+ back = -1; /* REPORTED */
+ }
+ } else {
+ /* ERROR: Only allowed in options section */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 10);
+ }
+ } break;
+ case 5: { /* html charset */
+ if(job->currentnode) {
+ switch(dk3str_array_index(hbconf_charsets, vp, 0)) {
+ case 0: {
+ job->cs = HB_CS_UTF_8;
+ } break;
+ case 1: case 2: {
+ job->cs = HB_CS_ASCII;
+ } break;
+ default: {
+ /* WARNING: Unknown charset! */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 11);
+ } break;
+ }
+ }
+ } break;
+ case 6: { /* template */
+ if(job->currentnode) {
+ ptr = dk3str_dup_app(vp,job->app);
+ if(ptr) {
+ dk3str_correct_filename(ptr);
+ if((job->currentnode)->template) {
+ if(0UL != (job->currentnode)->objno) {
+ /* Overwriting template */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 73);
+ }
+ }
+ dk3_release((job->currentnode)->template);
+ (job->currentnode)->template = ptr;
+ } else {
+ back = -1; /* REPORTED */
+ }
+ }
+ } break;
+ case 7: { /* style */
+ if(job->currentnode) {
+ ptr = dk3str_dup_app(vp,job->app);
+ if(ptr) {
+ dk3str_correct_filename(ptr);
+ if(!hbtool_check_filename(job, ptr)) { back = -1; }
+ if((job->currentnode)->stylefile) {
+ if(0UL != (job->currentnode)->objno) {
+ /* Overwriting style */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 74);
+ }
+ }
+ dk3_release((job->currentnode)->stylefile);
+ (job->currentnode)->stylefile = ptr;
+ } else {
+ back = -1; /* REPORTED */
+ }
+ }
+ } break;
+ case 8: { /* page toc */
+ if(job->currentnode) {
+ if(dk3str_is_bool(vp)) {
+ if(dk3str_is_on(vp)) {
+ (job->currentnode)->options =
+ ((job->currentnode)->options) | HB_NODE_OPT_PAGE_TOC;
+ } else {
+ (job->currentnode)->options =
+ ((job->currentnode)->options) & (~(HB_NODE_OPT_PAGE_TOC));
+ }
+ } else {
+ /* WARNING: Not a boolean value! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 144, vp);
+ }
+ }
+ } break;
+ case 9: { /* toc file */
+ if(HB_SECTION_OPTIONS == st) {
+ if(job->rootnode) {
+ ptr = dk3str_dup_app(vp,job->app);
+ if(ptr) {
+ dk3str_correct_filename(ptr);
+ if(!hbtool_check_filename(job, ptr)) { back = -1; }
+ dk3_release((job->rootnode)->filename);
+ (job->rootnode)->filename = ptr;
+ } else {
+ back = -1; /* REPORTED */
+ }
+ }
+ } else {
+ /* ERROR: Only allowed in options section */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 10);
+ }
+ } break;
+ case 10: { /* create index */
+ if(HB_SECTION_OPTIONS == st) {
+ if(dk3str_is_bool(vp)) {
+ if(dk3str_is_on(vp)) {
+ job->options = (job->options) | HB_JOB_OPT_CREATE_INDEX;
+ } else {
+ job->options = (job->options) & (~(HB_JOB_OPT_CREATE_INDEX));
+ }
+ } else {
+ /* WARNING: Not a boolean */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 144, vp);
+ }
+ } else {
+ /* ERROR: Only allowed in options section */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 10);
+ }
+ } break;
+ case 11: { /* replace ampersand */
+ if(job->currentnode) {
+ if(dk3str_is_bool(vp)) {
+ if(dk3str_is_on(vp)) {
+ (job->currentnode)->options =
+ ((job->currentnode)->options)
+ | HB_NODE_OPT_REPLACE_AMPERSAND;
+ } else {
+ (job->currentnode)->options =
+ ((job->currentnode)->options)
+ & (~(HB_NODE_OPT_REPLACE_AMPERSAND));
+ }
+ } else {
+ /* WARNING: Not a boolean. */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 144, vp);
+ }
+ }
+ } break;
+ case 12: { /* use tidy */
+ if(job->currentnode) {
+ if(dk3str_is_bool(vp)) {
+ if(dk3str_is_on(vp)) {
+ (job->currentnode)->options =
+ ((job->currentnode)->options)
+ | HB_NODE_OPT_USE_TIDY;
+ } else {
+ (job->currentnode)->options =
+ ((job->currentnode)->options)
+ & (~(HB_NODE_OPT_USE_TIDY));
+ }
+ } else {
+ /* WARNING: Not a boolean. */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 144, vp);
+ }
+ }
+ } break;
+ case 13: { /* location */
+ if(job->currentnode) {
+ ptr = dk3str_dup_app(vp,job->app);
+ if(ptr) {
+ dk3_release((job->currentnode)->location);
+ (job->currentnode)->location = ptr;
+ } else {
+ back = -1; /* REPORTED */
+ }
+ }
+ } break;
+ case 14: { /* write header chain */
+ if(job->currentnode) {
+ if(dk3str_is_bool(vp)) {
+ if(dk3str_is_on(vp)) {
+ (job->currentnode)->options =
+ ((job->currentnode)->options)
+ | HB_NODE_OPT_HEADER_CHAIN;
+ } else {
+ (job->currentnode)->options =
+ ((job->currentnode)->options)
+ & (~(HB_NODE_OPT_HEADER_CHAIN));
+ }
+ } else {
+ /* WARNING: Not a boolean */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 144, vp);
+ }
+ }
+ } break;
+ case 15: { /* navigation */
+ /* navigation is now configured via arguments to special cmd */
+ } break;
+ case 16: { /* short */
+ if(job->currentnode) {
+ ptr = dk3str_dup_app(vp,job->app);
+ if(ptr) {
+ if((job->currentnode)->shorttitle) {
+ if(0UL != (job->currentnode)->objno) {
+ /* Overwriting short */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 75);
+ }
+ }
+ dk3_release((job->currentnode)->shorttitle);
+ (job->currentnode)->shorttitle = ptr;
+ } else {
+ back = -1; /* REPORTED */
+ }
+ }
+ } break;
+ case 17: { /* file */
+ if(job->currentnode) {
+ ptr = dk3str_dup_app(vp,job->app);
+ if(ptr) {
+ dk3str_correct_filename(ptr);
+ if(!hbtool_check_filename(job, ptr)) { back = -1; }
+ if((job->currentnode)->filename) {
+ if(0UL != (job->currentnode)->objno) {
+ /* Overwriting file */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 76);
+ }
+ }
+ dk3_release((job->currentnode)->filename);
+ (job->currentnode)->filename = ptr;
+ hbconf_set_jump_node(job->currentnode);
+ if(!(dk3sto_it_find_like(job->i_pnodes,job->currentnode,0))) {
+ if(!(dk3sto_add(job->s_pnodes, job->currentnode))) {
+ back = -1; /* REPORTED */
+ }
+ }
+ } else {
+ back = -1; /* REPORTED */
+ }
+ }
+ } break;
+ case 18: { /* suffix */
+ if(job->currentnode) {
+ ptr = dk3str_dup_app(vp,job->app);
+ if(ptr) {
+ if((job->currentnode)->suffix) {
+ if(0UL != (job->currentnode)->objno) {
+ /* Overwriting suffix */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 77);
+ }
+ }
+ dk3_release((job->currentnode)->suffix);
+ (job->currentnode)->suffix = ptr;
+ /* CHECK FILENAME CHARACTERS */
+ if(!hbtool_check_filename_encoding(job, ptr)) { back = -1; }
+ } else {
+ back = -1; /* REPORTED */
+ }
+ }
+ } break;
+ case 19: {
+ if(job->currentnode) {
+ ptr = dk3str_dup_app(vp,job->app);
+ if(ptr) {
+ dk3str_correct_filename(ptr);
+ if(!hbtool_check_filename(job, ptr)) { back = -1; }
+ if((job->currentnode)->icontoc) {
+ if(0UL != (job->currentnode)->objno) {
+ /* Overwriting icon toc */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 78);
+ }
+ }
+ dk3_release((job->currentnode)->icontoc);
+ (job->currentnode)->icontoc = ptr;
+ /* CHECK FILENAME CHARACTERS */
+ } else {
+ back = -1; /* REPORTED */
+ }
+ }
+ } break;
+ case 20: {
+ if(job->currentnode) {
+ ptr = dk3str_dup_app(vp,job->app);
+ if(ptr) {
+ dk3str_correct_filename(ptr);
+ if(!hbtool_check_filename(job, ptr)) { back = -1; }
+ if((job->currentnode)->iconprev) {
+ if(0UL != (job->currentnode)->objno) {
+ /* Overwriting icon previous */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 79);
+ }
+ }
+ dk3_release((job->currentnode)->iconprev);
+ (job->currentnode)->iconprev = ptr;
+ /* CHECK FILENAME CHARACTERS */
+ } else {
+ back = -1; /* REPORTED */
+ }
+ }
+ } break;
+ case 21: {
+ if(job->currentnode) {
+ ptr = dk3str_dup_app(vp,job->app);
+ if(ptr) {
+ dk3str_correct_filename(ptr);
+ if(!hbtool_check_filename(job, ptr)) { back = -1; }
+ if((job->currentnode)->iconnext) {
+ if(0UL != (job->currentnode)->objno) {
+ /* Overwriting icon next */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 80);
+ }
+ }
+ dk3_release((job->currentnode)->iconnext);
+ (job->currentnode)->iconnext = ptr;
+ /* CHECK FILENAME CHARACTERS */
+ } else {
+ back = -1; /* REPORTED */
+ }
+ }
+ } break;
+ case 22: {
+ if(job->currentnode) {
+ ptr = dk3str_dup_app(vp,job->app);
+ if(ptr) {
+ dk3str_correct_filename(ptr);
+ if(!hbtool_check_filename(job, ptr)) { back = -1; }
+ if((job->currentnode)->iconindex) {
+ if(0UL != (job->currentnode)->objno) {
+ /* Overwriting icon index */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 81);
+ }
+ }
+ dk3_release((job->currentnode)->iconindex);
+ (job->currentnode)->iconindex = ptr;
+ /* CHECK FILENAME CHARACTERS */
+ } else {
+ back = -1; /* REPORTED */
+ }
+ }
+ } break;
+ case 23: {
+ if(HB_SECTION_OPTIONS == st) {
+ if(dk3str_is_bool(vp)) {
+ if(dk3str_is_on(vp)) {
+ job->options = ((job->options) | HB_JOB_OPT_CREATE_TOC);
+ } else {
+ job->options =
+ ((job->options) & (~(HB_JOB_OPT_CREATE_TOC)));
+ }
+ } else {
+ /* Warning: Not a boolean! */
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, vp);
+ }
+ } else {
+ /* ERROR: Only allowed in options section */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 10);
+ }
+ } break;
+ case 24: {
+ if(job->currentnode) {
+ ptr = dk3str_dup_app(vp,job->app);
+ if(ptr) {
+ dk3str_correct_filename(ptr);
+ hbtool_correct_backslash_to_slash(ptr);
+ if((job->currentnode)->favicon) {
+ if(0UL != (job->currentnode)->objno) {
+ /* Overwriting shortcut icon */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 82);
+ }
+ }
+ dk3_release((job->currentnode)->favicon);
+ (job->currentnode)->favicon = ptr;
+ /* ADD TO LIST OF ADDITIONAL FILES */
+ if (!(hbtool_add_file(job, ptr))) {
+ back = -1;
+ }
+ /* CHECK FILENAME CHARACTERS */
+ if(!hbtool_check_filename_encoding(job, ptr)) { back = -1; }
+ } else {
+ back = -1; /* REPORTED */
+ }
+ }
+ } break;
+ case 25: {
+
+#line 824 "hbconf.ctr"
+ if(job->currentnode) {
+
+#line 825 "hbconf.ctr"
+ ap = dk3str_next(vp, NULL);
+ if(ap) {
+
+#line 827 "hbconf.ctr"
+ kvp = dk3sto_it_find_like(
+ (job->currentnode)->i_variables, vp, 1
+ );
+ if(kvp) {
+
+#line 831 "hbconf.ctr"
+ nc = dk3str_dup_app(ap, job->app);
+ if(nc) {
+
+#line 833 "hbconf.ctr"
+ if(kvp->val) {
+ if(0UL != (job->currentnode)->objno) {
+ /* Overwriting var */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 83);
+ }
+ }
+ dk3_release(kvp->val);
+ kvp->val = nc;
+ } else {
+
+#line 842 "hbconf.ctr"
+ back = -1; /* REPORTED */
+ }
+ } else {
+
+#line 845 "hbconf.ctr"
+ kvp = dk3kv_new_app(vp, ap, job->app);
+ if(kvp) {
+
+#line 847 "hbconf.ctr"
+ if(!(dk3sto_add((job->currentnode)->s_variables, kvp))) {
+ dk3kv_delete(kvp);
+
+#line 849 "hbconf.ctr"
+ back = -1; /* REPORTED */
+ }
+ } else {
+
+#line 852 "hbconf.ctr"
+ back = -1; /* REPORTED */
+ }
+ }
+ } else {
+
+#line 856 "hbconf.ctr"
+ kvp = dk3sto_it_find_like(
+ (job->currentnode)->i_variables, vp, 1
+ );
+ if(kvp) {
+
+#line 860 "hbconf.ctr"
+ dk3sto_remove((job->currentnode)->s_variables, kvp);
+ dk3kv_delete(kvp);
+ }
+ }
+ } else {
+
+#line 865 "hbconf.ctr"
+ }
+ } break;
+ case 26: {
+
+#line 868 "hbconf.ctr"
+ if(HB_SECTION_OPTIONS == st) {
+ ptr = dk3str_dup_app(vp, job->app);
+ if(ptr) {
+ dk3_release(job->impressumlink);
+ job->impressumlink = ptr;
+ } else {
+ back = -1; /* REPORTED */
+ }
+ } else {
+ /* ERROR: Only allowed in options section */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 10);
+ }
+ } break;
+ case 27: {
+
+#line 882 "hbconf.ctr"
+ if(HB_SECTION_OPTIONS == st) {
+
+#line 883 "hbconf.ctr"
+ job->impressumnode = hb_node_new(
+ job, job->rootnode, job->lineno, job->nextobj, 0
+ );
+ job->nextobj += 1UL;
+ if(job->impressumnode) {
+
+#line 888 "hbconf.ctr"
+ if((job->impressumnode)->depth > job->maxdepth) {
+ job->maxdepth = (job->impressumnode)->depth;
+ }
+ (job->impressumnode)->options |= HB_NODE_OPT_IMPRESSUM;
+ if(dk3sto_add(job->s_nodes, (void *)(job->impressumnode))) {
+
+
+#line 894 "hbconf.ctr"
+ (job->impressumnode)->title =
+ dk3str_dup_app((job->msg)[0], job->app);
+ if((job->impressumnode)->title) {
+
+#line 897 "hbconf.ctr"
+ dk3str_correct_filename(vp);
+ if(!hbtool_check_filename(job, vp)) { back = -1; }
+ /* CHECK FILENAME CHARACTERS */
+ (job->impressumnode)->filename =
+ dk3str_dup_app(vp, job->app);
+ if(!((job->impressumnode)->filename)) {
+ back = -1;
+ }
+ } else {
+
+#line 906 "hbconf.ctr"
+ back = -1; /* REPORTED */
+ }
+ if(1 == back) {
+
+#line 909 "hbconf.ctr"
+ if(!dk3sto_add(job->s_pnodes,(void*)(job->impressumnode)))
+ {
+
+#line 911 "hbconf.ctr"
+ back = -1; /* REPORTED */
+ }
+ }
+ } else {
+
+#line 915 "hbconf.ctr"
+ hb_node_delete(job->impressumnode);
+ job->impressumnode = NULL;
+ back = -1; /* REPORTED */
+ }
+ } else {
+
+#line 920 "hbconf.ctr"
+ back = -1; /* REPORTED */
+ }
+ } else {
+
+#line 923 "hbconf.ctr"
+ /* ERROR: Only allowed in options section */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 10);
+ }
+ } break;
+ case 28: {
+
+#line 928 "hbconf.ctr"
+ if(HB_SECTION_OPTIONS == st) {
+ if(dk3str_is_bool(vp)) {
+ if(dk3str_is_on(vp)) {
+ job->options |= HB_JOB_OPT_CHM;
+ } else {
+ job->options &= (~(HB_JOB_OPT_CHM));
+ }
+ } else {
+ /* Warning: Not a boolean */
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, vp);
+ }
+ } else {
+ /* ERROR: Only allowed in options section */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 10);
+ }
+ } break;
+ case 29: {
+
+#line 945 "hbconf.ctr"
+ if(HB_SECTION_OPTIONS == st) {
+ if(dk3str_is_bool(vp)) {
+ if(dk3str_is_on(vp)) {
+ job->options |= HB_JOB_OPT_LN;
+ } else {
+ job->options &= (~(HB_JOB_OPT_LN));
+ }
+ } else {
+ /* Warning: Not a boolean */
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, vp);
+ }
+ } else {
+ /* ERROR: Only allowed in options section */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 10);
+ }
+ } break;
+ case 30: {
+
+#line 962 "hbconf.ctr"
+ newie = dk3enc_get_text_encoding_app(vp, NULL);
+ if(0 <= newie) {
+ if(HB_SECTION_OPTIONS == st) {
+ job->iecmd = newie;
+ (job->rootnode)->inenc = newie;
+ }
+ (job->currentnode)->inenc = newie;
+ } else {
+ if(dk3str_casecmp((job->kwnl)[25], vp) == 0) {
+ if(HB_SECTION_OPTIONS == st) {
+ job->iecmd = -1;
+ (job->rootnode)->inenc = -1;
+ }
+ (job->currentnode)->inenc = -1;
+ } else {
+ back = 0;
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 129, 130, vp);
+ }
+ }
+ } break;
+ case 31: {
+
+#line 983 "hbconf.ctr"
+ if(HB_SECTION_OPTIONS == st) {
+ ptr = dk3str_dup_app(vp, job->app);
+ if(ptr) {
+ dk3_release(job->chmlang);
+ job->chmlang = ptr;
+ } else {
+ back = -1;
+ }
+ } else {
+ /* ERROR: Only allowed in options section */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 10);
+ }
+ } break;
+ case 32: {
+
+#line 997 "hbconf.ctr"
+ if((job->currentnode) && (vp)) {
+ if(!((job->currentnode)->s_jsfiles)) {
+ (job->currentnode)->s_jsfiles =
+ dk3sto_open_app(job->app);
+ if((job->currentnode)->s_jsfiles) {
+ dk3sto_set_comp(
+ (job->currentnode)->s_jsfiles,
+ hbnode_link_compare, 2
+ );
+ }
+ }
+ if(!((job->currentnode)->i_jsfiles)) {
+ if((job->currentnode)->s_jsfiles) {
+ (job->currentnode)->i_jsfiles = dk3sto_it_open(
+ (job->currentnode)->s_jsfiles
+ );
+ }
+ }
+ if((job->currentnode)->s_jsfiles) {
+ if((job->currentnode)->i_jsfiles) {
+ linkptr = hbnode_link_new(
+ vp, (job->currentnode)->nextjs, job->app
+ );
+ if(linkptr) {
+ if(dk3sto_add((job->currentnode)->s_jsfiles, linkptr)) {
+ (job->currentnode)->nextjs += 1UL;
+ } else {
+ hbnode_link_delete(linkptr);
+ back = -1;
+ }
+ } else {
+ back = -1;
+ }
+ } else {
+ back = -1;
+ }
+ } else {
+ back = -1;
+ }
+ }
+ if(vp) {
+ if(!hbtool_add_url(job, vp)) { back = -1; }
+ }
+ } break;
+ case 33: {
+
+#line 1042 "hbconf.ctr"
+ if(vp) {
+ if(dk3str_is_bool(vp)) {
+ if(dk3str_is_on(vp)) {
+ (job->currentnode)->options &=
+ (~(HB_NODE_OPT_STOP_JS_INHERITANCE));
+ } else {
+ (job->currentnode)->options |=
+ HB_NODE_OPT_STOP_JS_INHERITANCE;
+ }
+ } else {
+ /* Warning: Not a boolean */
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, vp);
+ }
+ } else {
+ if(job->currentnode) {
+ (job->currentnode)->options &=
+ (~(HB_NODE_OPT_STOP_JS_INHERITANCE));
+ }
+ }
+ } break;
+ case 34: {
+
+#line 1063 "hbconf.ctr"
+ if(HB_SECTION_OPTIONS == st) {
+ if (vp) {
+ if (dk3str_is_bool(vp)) {
+ if (dk3str_is_on(vp)) {
+ job->options |= HB_JOB_OPT_NUM_IN_POS;
+ } else {
+ job->options &= (~(HB_JOB_OPT_NUM_IN_POS));
+ }
+ } else {
+ /* Warning: Not a boolean */
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, vp);
+ }
+ } else {
+ job->options |= HB_JOB_OPT_NUM_IN_POS;
+ }
+ } else {
+ /* ERROR: Only allowed in options section */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 10);
+ }
+ } break;
+ case 35: {
+
+#line 1084 "hbconf.ctr"
+ if(HB_SECTION_OPTIONS == st) {
+ if (vp) {
+ if (dk3str_is_bool(vp)) {
+ if (dk3str_is_on(vp)) {
+ job->options |= HB_JOB_OPT_NUM_IN_IDX;
+ } else {
+ job->options &= (~(HB_JOB_OPT_NUM_IN_IDX));
+ }
+ } else {
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, vp);
+ }
+ } else {
+ job->options |= HB_JOB_OPT_NUM_IN_IDX;
+ }
+ } else {
+ /* ERROR: Only allowed in options section */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 10);
+ }
+ } break;
+ case 36: {
+ if(HB_SECTION_OPTIONS == st) {
+ if (vp) {
+ if (dk3str_is_bool(vp)) {
+ if (dk3str_is_on(vp)) {
+ job->options |= HB_JOB_OPT_NUM_IN_PAGE_HEADER;
+ } else {
+ job->options &= (~(HB_JOB_OPT_NUM_IN_PAGE_HEADER));
+ }
+ } else {
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, vp);
+ }
+ } else {
+ job->options |= HB_JOB_OPT_NUM_IN_PAGE_HEADER;
+ }
+ } else {
+ /* ERROR: Only allowed in options section */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 10);
+ }
+ } break;
+ case 37: {
+ long cn;
+ if (vp) {
+#if VERSION_BEFORE_20140716
+ if (1 == dk3sf_sscanf3(vp, dkT("%ld"), &cn))
+#else
+ if (0 != dk3ma_l_from_string(&cn, vp, NULL))
+#endif
+ {
+ if (job->currentnode) {
+ (job->currentnode)->contnum = cn;
+ } else {
+ /* BUG: No current node set! */
+ }
+ } else {
+ /* ERROR: Not a number */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 141);
+ }
+ } else {
+ /* ERROR: No context number specified */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 133, 134, kp);
+ }
+ } break;
+ case 38: {
+ if(HB_SECTION_OPTIONS == st) {
+ if (vp) {
+ if (dk3str_is_bool(vp)) {
+ if (dk3str_is_on(vp)) {
+ job->options |= HB_JOB_OPT_CHM_FULL_TEXT_SEARCH;
+ } else {
+ job->options &= (~(HB_JOB_OPT_CHM_FULL_TEXT_SEARCH));
+ }
+ } else {
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, vp);
+ }
+ } else {
+ job->options |= HB_JOB_OPT_CHM_FULL_TEXT_SEARCH;
+ }
+ } else {
+ /* ERROR: Only allowed in options section */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 10);
+ }
+ } break;
+ case 39: {
+ if(HB_SECTION_OPTIONS == st) {
+ if (vp) {
+ if (dk3str_is_bool(vp)) {
+ if (dk3str_is_on(vp)) {
+ job->options |= HB_JOB_OPT_CODE_LINE_NUMBERS;
+ } else {
+ job->options &= (~(HB_JOB_OPT_CODE_LINE_NUMBERS));
+ }
+ } else {
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, vp);
+ }
+ } else {
+ job->options |= HB_JOB_OPT_CODE_LINE_NUMBERS;
+ }
+ } else {
+ /* ERROR: Only allowed in options section */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 10);
+ }
+ } break;
+ case 40: {
+ if(job->currentnode) {
+ ptr = dk3str_dup_app(vp,job->app);
+ if(ptr) {
+ dk3str_correct_filename(ptr);
+ if(!hbtool_check_filename(job, ptr)) { back = -1; }
+ if((job->currentnode)->iconhome) {
+ if(0UL != (job->currentnode)->objno) {
+ /* Overwriting icon home */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 95);
+ }
+ }
+ dk3_release((job->currentnode)->iconhome);
+ (job->currentnode)->iconhome = ptr;
+ /* CHECK FILENAME CHARACTERS */
+ } else {
+ back = -1; /* REPORTED */
+ }
+ }
+ } break;
+ default: {
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 43, 44, kp);
+ } break;
+ }
+ } else {
+ /* Warning: Syntax error! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 9);
+ }
+ } else {
+ /* Warning: Syntax error in configuration file */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 8);
+ }
+ } else {
+
+#line 1219 "hbconf.ctr"
+ }
+ } else {
+
+#line 1221 "hbconf.ctr"
+ }
+
+
+#line 1223 "hbconf.ctr"
+ return back;
+}
+
+
+
+/** Line handler function to process a configuration file.
+ @param obj Pointer to a job structure.
+ @param il Input line to process.
+ @return 1 on success, 0 on error (continue), -1 on error (exit).
+*/
+static
+int
+hbconf_line_reader_handler(void *obj, dkChar *il)
+{
+ int back;
+
+
+#line 1239 "hbconf.ctr"
+ back = hbconf_process_line((hb_job_t *)obj, il, HB_SECTION_OPTIONS);
+
+
+#line 1241 "hbconf.ctr"
+ return back;
+}
+
+
+
+/** Process one configuration file.
+ @param job Job structure.
+ @param fn File name to process.
+ @return 1 on success, 0 on error (continue), -1 on error (exit).
+*/
+int
+hbconf_read_one_file(hb_job_t *job, dkChar const *fn)
+{
+ int back = 0;
+
+
+#line 1256 "hbconf.ctr"
+ back = dk3stream_process_filename_lines_app(
+ (void *)job, hbconf_line_reader_handler, fn,
+ job->ilfile, job->bs,
+ dk3app_get_encoding(job->app),
+ dk3app_get_input_file_encoding(job->app),
+ job->app
+ );
+ if(1 != back) { back = 0; /* REPORTED */ }
+
+
+#line 1265 "hbconf.ctr"
+ return back;
+}
+
+
+
+int
+hbconf_read_files(hb_job_t *job)
+{
+ dk3_search_t *sr = NULL; /* File search result */
+ dkChar const *fn; /* One config file name */
+ int back = 1;
+
+
+#line 1277 "hbconf.ctr"
+ sr = dk3app_find_config_file(job->app, (job->kwnl)[3], 0);
+ if(sr) {
+ dk3search_reset(sr);
+ while(NULL != (fn = dk3search_next(sr))) {
+ if(back) {
+ if(!hbconf_read_one_file(job, fn)) {
+ back = 0; /* REPORTED */
+ }
+ }
+ }
+ dk3search_close(sr);
+ }
+
+#line 1289 "hbconf.ctr"
+ return back;
+}
+
+
+
+dkChar const *
+hbconf_node_template(hb_job_t *job, hb_node_t *node)
+{
+ dkChar const *back = NULL;
+ hb_node_t *nptr; /* Traverse node and parent nodes */
+
+
+#line 1300 "hbconf.ctr"
+ nptr = node;
+ while((nptr) && (NULL == back)) {
+ if(nptr->template) {
+ back = nptr->template;
+ } else {
+ nptr = nptr->parent;
+ }
+ }
+
+#line 1308 "hbconf.ctr"
+ return back;
+}
+
+
+
+dkChar const *
+hbconf_node_icon(hb_job_t *job, hb_node_t *node, int icno)
+{
+ dkChar const *back = NULL;
+ hb_node_t *nptr; /* Traverse node and parent nodes */
+
+
+#line 1319 "hbconf.ctr"
+ nptr = node;
+ while((nptr) && (NULL == back)) {
+ switch(icno) {
+ case 0: {
+ if(nptr->icontoc) {
+ back = nptr->icontoc;
+ } else {
+ nptr = nptr->parent;
+ }
+ } break;
+ case 1: {
+ if(nptr->iconprev) {
+ back = nptr->iconprev;
+ } else {
+ nptr = nptr->parent;
+ }
+ } break;
+ case 2: {
+ if(nptr->iconnext) {
+ back = nptr->iconnext;
+ } else {
+ nptr = nptr->parent;
+ }
+ } break;
+ case 4: {
+ if(nptr->iconhome) {
+ back = nptr->iconhome;
+ } else {
+ nptr = nptr->parent;
+ }
+ } break;
+ default: {
+ if(nptr->iconindex) {
+ back = nptr->iconindex;
+ } else {
+ nptr = nptr->parent;
+ }
+ } break;
+ }
+ }
+ if(!(back)) {
+ back = (job->kwnl)[4 + icno];
+ }
+
+#line 1362 "hbconf.ctr"
+ return back;
+}
+
+
+
+dkChar const *
+hbconf_title(hb_node_t *node)
+{
+ dkChar const *back = NULL;
+
+
+#line 1372 "hbconf.ctr"
+ if (NULL != node->fulltitle) {
+ back = node->fulltitle;
+ } else {
+ while((NULL == back) && (node)) {
+ if(node->title) {
+ back = node->title;
+ } else {
+ node = node->parent;
+ }
+ }
+ }
+
+
+#line 1384 "hbconf.ctr"
+ return back;
+}
+
+
+
+dkChar const *
+hbconf_stylefile(hb_node_t *node)
+{
+ dkChar const *back = NULL;
+
+
+#line 1394 "hbconf.ctr"
+ while((NULL == back) && (node)) {
+ if(node->stylefile) {
+ back = node->stylefile;
+ } else {
+ node = node->parent;
+ }
+ }
+
+#line 1401 "hbconf.ctr"
+ return back;
+}
+
+
+
+dkChar const *
+hbconf_author(hb_node_t *node)
+{
+ dkChar const *back = NULL;
+
+
+#line 1411 "hbconf.ctr"
+ while((NULL == back) && (node)) {
+ if(node->author) {
+ back = node->author;
+ } else {
+ node = node->parent;
+ }
+ }
+
+#line 1418 "hbconf.ctr"
+ return back;
+}
+
+
+
+dkChar const *
+hbconf_location(hb_node_t *node)
+{
+ dkChar const *back = NULL;
+
+
+#line 1428 "hbconf.ctr"
+ while((NULL == back) && (node)) {
+ if(node->location) {
+ back = node->location;
+ } else {
+ node = node->parent;
+ }
+ }
+
+#line 1435 "hbconf.ctr"
+ return back;
+}
+
+
+
+dkChar const *
+hbconf_favicon(hb_node_t *node)
+{
+ dkChar const *back = NULL;
+
+
+#line 1445 "hbconf.ctr"
+ while((NULL == back) && (node)) {
+ if(node->favicon) {
+ back = node->favicon;
+ } else {
+ node = node->parent;
+ }
+ }
+
+#line 1452 "hbconf.ctr"
+ return back;
+}
+
+
diff --git a/support/dktools/hbconf.ctr b/support/dktools/hbconf.ctr
new file mode 100644
index 0000000000..5cacff78f2
--- /dev/null
+++ b/support/dktools/hbconf.ctr
@@ -0,0 +1,1455 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2013-xxxx
+license = bsd
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Read configuration files.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+hbconf_read_files(hb_job_t *job);
+
+/** Read one configuration file.
+ @param job Job structure.
+ @param fn Configuration file name.
+ @return 1 on success, 0 on error.
+*/
+int
+hbconf_read_one_file(hb_job_t *job, dkChar const *fn);
+
+/** Process one configuration line.
+ @param job Job structure.
+ @param il Input line to process, stored also in ilfile.
+ @param st Section type.
+ @return 1 on success, 0 on error (can continue), -1 on error (exit).
+*/
+int
+hbconf_process_line(hb_job_t *job, dkChar *il, int st);
+
+/** Find template name for a node.
+ @param job Job structure.
+ @param node Node to find template for.
+ @return Template file name on success, NULL on error.
+*/
+dkChar const *
+hbconf_node_template(hb_job_t *job, hb_node_t *node);
+
+/** Find icon file name.
+ @param job Job structure.
+ @param node Node to find icon for.
+ @param icno Icon number
+ (0=TOC, 1=previous, 2=next, 3=index, 4=home).
+ @return File name pointer.
+*/
+dkChar const *
+hbconf_node_icon(hb_job_t *job, hb_node_t *node, int icno);
+
+/** Find title for current node.
+ This function is used by the hbhtml_write_header() function
+ to find the title in the HTML head section.
+ We use the full title if available, the title or the title
+ from parent objets...
+ @param node Node to find title for.
+ @return Title on success, NULL on error.
+*/
+dkChar const *
+hbconf_title(hb_node_t *node);
+
+/** Find CSS style file for current node.
+ @param node Node to find style file for.
+ @return File name on success, NULL on error.
+*/
+dkChar const *
+hbconf_stylefile(hb_node_t *node);
+
+/** Find author for current node.
+ @param node Node to find author for.
+ @return Author name on success, NULL on error.
+*/
+dkChar const *
+hbconf_author(hb_node_t *node);
+
+/** Find shortcut icon file name.
+ @param node Node to find file name for.
+ @return File name on success, NULL on error.
+*/
+dkChar const *
+hbconf_favicon(hb_node_t *node);
+
+/** Find location (city).
+ @param node Node to find location for.
+ @return Location on success, NULL on error.
+*/
+dkChar const *
+hbconf_location(hb_node_t *node);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "dk3all.h"
+#include "htmlbook.h"
+
+
+
+$!trace-include
+
+
+
+/** Names of configuration file options.
+*/
+dkChar const * const hbconf_options[] = {
+$!string-table macro=dkT
+#
+# 0
+#
+author
+#
+# 1
+#
+title
+#
+# 2
+#
+url
+#
+# 3
+#
+output directory
+#
+# 4
+#
+output script
+#
+# 5
+#
+html charset
+#
+# 6
+#
+template
+#
+# 7
+#
+style
+#
+# 8
+#
+page toc
+#
+# 9
+#
+index file
+#
+# 10
+#
+create index
+#
+# 11
+#
+replace ampersand
+#
+# 12
+#
+tidy
+#
+# 13
+#
+location
+#
+# 14
+#
+write position
+#
+# 15
+#
+navigation
+#
+# 16
+#
+short
+#
+# 17
+#
+file
+#
+# 18
+#
+suffix
+#
+# 19
+#
+icon toc
+#
+# 20
+#
+icon previous
+#
+# 21
+#
+icon next
+#
+# 22
+#
+icon index
+#
+# 23
+#
+create toc
+#
+# 24
+#
+shortcut icon
+#
+# 25
+#
+var
+#
+# 26
+#
+impressum link
+#
+# 27
+#
+impressum page
+#
+# 28
+#
+chm
+#
+# 29
+#
+ln
+#
+# 30
+#
+input encoding
+#
+# 31
+#
+chm language
+#
+# 32
+#
+js file
+#
+# 33
+#
+inherit js
+#
+# 34
+#
+section numbers in position
+#
+# 35
+#
+section numbers in index
+#
+# 36
+#
+section numbers in page header
+#
+# 37
+#
+context number
+#
+# 38
+#
+chm full text search
+#
+# 39
+#
+code line numbers
+#
+# 40
+#
+icon home
+$!end
+};
+
+
+
+/** Character sets for HTML output.
+*/
+dkChar const * const hbconf_charsets[] = {
+$!string-table macro=dkT
+utf-8
+ascii
+us-ascii
+$!end
+};
+
+
+
+/** Set jump node for the nodes parents.
+ @param nodeptr Text node.
+*/
+static
+void
+hbconf_set_jump_node(hb_node_t *nodeptr)
+{
+ hb_node_t *parent; /* Parent node */
+ int cc; /* Flag: Can continue */
+ $? "+ hbconf_set_jump_node"
+ parent = nodeptr->parent;
+ cc = 1;
+ while(cc) {
+ if(parent) {
+ if(parent->jumpnode) {
+ cc = 0;
+ } else {
+ if(-1 != parent->indent) {
+ parent->jumpnode = nodeptr;
+ parent = parent->parent;
+ } else {
+ cc = 0;
+ }
+ }
+ } else {
+ cc = 0;
+ }
+ } $? "- hbconf_set_jump_node"
+}
+
+
+
+/** Process one configuration line from configuration file.
+ @param job Job structure.
+ @param il Input line to process.
+ @param st Current section type, HB_SECTION_OPTIONS
+ or HB_SECTION_CONTENTS.
+ @return 1 on success, 0 on error (continue), -1 on error (exit).
+*/
+int
+hbconf_process_line(hb_job_t *job, dkChar *il, int st)
+{
+ dk3_key_value_t *kvp; /* New key value pair */
+ hb_link_t *linkptr; /* New data for JS file */
+ dkChar *kp; /* Key */
+ dkChar *vp; /* Value */
+ dkChar *ap; /* Argument */
+ dkChar *nc; /* New text for existing key/value */
+ dkChar *ptr; /* Traverse string */
+ int newie; /* Input encoding */
+ int back = 1;
+ $? "+ hbconf_process_line %!ds", TR_STR(il)
+ kp = dk3str_start(il, NULL);
+ if(kp) {
+ if(dkT('#') != *kp) {
+ vp = dk3str_chr(kp, dkT('='));
+ if(vp) {
+ *(vp++) = dkT('\0');
+ vp = dk3str_start(vp, NULL);
+ if(vp) {
+ dk3str_normalize(kp, NULL, dkT(' '));
+ dk3str_chomp(vp, NULL);
+ switch(dk3str_array_index(hbconf_options, kp, 0)) {
+ case 0: { /* author */
+ if(job->currentnode) {
+ ptr = dk3str_dup_app(vp,job->app);
+ if(ptr) {
+ if((job->currentnode)->author) {
+ if(0UL != (job->currentnode)->objno) {
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 69);
+ }
+ }
+ dk3_release((job->currentnode)->author);
+ (job->currentnode)->author = ptr;
+ } else {
+ back = -1; /* REPORTED */
+ }
+ }
+ } break;
+ case 1: { /* title */
+ if(job->currentnode) {
+ ptr = dk3str_dup_app(vp,job->app);
+ if(ptr) {
+
+#if VERSION_BEFORE_20161026
+ if((job->currentnode)->title) {
+ if(0UL != (job->currentnode)->objno) {
+ /* Overwriting title */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 70);
+ }
+ }
+ dk3_release((job->currentnode)->title);
+ (job->currentnode)->title = ptr;
+#else
+ if((job->currentnode)->title) {
+ if ((job->currentnode)->fulltitle) {
+ if (0UL != (job->currentnode)->objno) {
+ /* Overwriting title */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 70);
+ }
+ dk3mem_free((job->currentnode)->fulltitle);
+ }
+ (job->currentnode)->fulltitle = ptr;
+ } else {
+ (job->currentnode)->title = ptr;
+ }
+#endif
+ } else {
+ back = -1; /* REPORTED */
+ }
+ }
+ } break;
+ case 2: { /* url */
+ if(HB_SECTION_OPTIONS == st) {
+ ptr = dk3str_dup_app(vp,job->app);
+ if(ptr) {
+ dk3_release(job->url);
+ job->url = ptr;
+ } else {
+ back = -1; /* REPORTED */
+ }
+ } else {
+ /* ERROR: Only allowed in options section */
+ dk3app_log_1(job->app,DK3_LL_ERROR,job->msg,38);
+ back = -1;
+ }
+ } break;
+ case 3: { /* output directory */
+ if(HB_SECTION_OPTIONS == st) {
+ ptr = dk3str_dup_app(vp,job->app);
+ if(ptr) {
+ dk3str_correct_filename(ptr);
+ if(job->outputdir) {
+ /* Overwrite output directory */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 71);
+ }
+ dk3_release(job->outputdir);
+ job->outputdir = ptr;
+ /* CHECK FILENAME CHARACTERS */
+ if(!hbtool_check_filename_encoding(job, ptr)) {
+ back = -1;
+ }
+ } else {
+ back = -1; /* REPORTED */
+ }
+ } else {
+ /* ERROR: Only allowed in options section */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 10);
+ }
+ } break;
+ case 4: { /* output script */
+ if(HB_SECTION_OPTIONS == st) {
+ ptr = dk3str_dup_app(vp,job->app);
+ if(ptr) {
+ if(job->outputscript) {
+ /* Overwrite output script */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 72);
+ }
+ dk3_release(job->outputscript);
+ job->outputscript = ptr;
+ /* CHECK FILENAME CHARACTERS */
+ if(!hbtool_check_filename(job, ptr)) {
+ back = -1;
+ }
+ } else {
+ back = -1; /* REPORTED */
+ }
+ } else {
+ /* ERROR: Only allowed in options section */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 10);
+ }
+ } break;
+ case 5: { /* html charset */
+ if(job->currentnode) {
+ switch(dk3str_array_index(hbconf_charsets, vp, 0)) {
+ case 0: {
+ job->cs = HB_CS_UTF_8;
+ } break;
+ case 1: case 2: {
+ job->cs = HB_CS_ASCII;
+ } break;
+ default: {
+ /* WARNING: Unknown charset! */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 11);
+ } break;
+ }
+ }
+ } break;
+ case 6: { /* template */
+ if(job->currentnode) {
+ ptr = dk3str_dup_app(vp,job->app);
+ if(ptr) {
+ dk3str_correct_filename(ptr);
+ if((job->currentnode)->template) {
+ if(0UL != (job->currentnode)->objno) {
+ /* Overwriting template */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 73);
+ }
+ }
+ dk3_release((job->currentnode)->template);
+ (job->currentnode)->template = ptr;
+ } else {
+ back = -1; /* REPORTED */
+ }
+ }
+ } break;
+ case 7: { /* style */
+ if(job->currentnode) {
+ ptr = dk3str_dup_app(vp,job->app);
+ if(ptr) {
+ dk3str_correct_filename(ptr);
+ if(!hbtool_check_filename(job, ptr)) { back = -1; }
+ if((job->currentnode)->stylefile) {
+ if(0UL != (job->currentnode)->objno) {
+ /* Overwriting style */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 74);
+ }
+ }
+ dk3_release((job->currentnode)->stylefile);
+ (job->currentnode)->stylefile = ptr;
+ } else {
+ back = -1; /* REPORTED */
+ }
+ }
+ } break;
+ case 8: { /* page toc */
+ if(job->currentnode) {
+ if(dk3str_is_bool(vp)) {
+ if(dk3str_is_on(vp)) {
+ (job->currentnode)->options =
+ ((job->currentnode)->options) | HB_NODE_OPT_PAGE_TOC;
+ } else {
+ (job->currentnode)->options =
+ ((job->currentnode)->options) & (~(HB_NODE_OPT_PAGE_TOC));
+ }
+ } else {
+ /* WARNING: Not a boolean value! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 144, vp);
+ }
+ }
+ } break;
+ case 9: { /* toc file */
+ if(HB_SECTION_OPTIONS == st) {
+ if(job->rootnode) {
+ ptr = dk3str_dup_app(vp,job->app);
+ if(ptr) {
+ dk3str_correct_filename(ptr);
+ if(!hbtool_check_filename(job, ptr)) { back = -1; }
+ dk3_release((job->rootnode)->filename);
+ (job->rootnode)->filename = ptr;
+ } else {
+ back = -1; /* REPORTED */
+ }
+ }
+ } else {
+ /* ERROR: Only allowed in options section */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 10);
+ }
+ } break;
+ case 10: { /* create index */
+ if(HB_SECTION_OPTIONS == st) {
+ if(dk3str_is_bool(vp)) {
+ if(dk3str_is_on(vp)) {
+ job->options = (job->options) | HB_JOB_OPT_CREATE_INDEX;
+ } else {
+ job->options = (job->options) & (~(HB_JOB_OPT_CREATE_INDEX));
+ }
+ } else {
+ /* WARNING: Not a boolean */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 144, vp);
+ }
+ } else {
+ /* ERROR: Only allowed in options section */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 10);
+ }
+ } break;
+ case 11: { /* replace ampersand */
+ if(job->currentnode) {
+ if(dk3str_is_bool(vp)) {
+ if(dk3str_is_on(vp)) {
+ (job->currentnode)->options =
+ ((job->currentnode)->options)
+ | HB_NODE_OPT_REPLACE_AMPERSAND;
+ } else {
+ (job->currentnode)->options =
+ ((job->currentnode)->options)
+ & (~(HB_NODE_OPT_REPLACE_AMPERSAND));
+ }
+ } else {
+ /* WARNING: Not a boolean. */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 144, vp);
+ }
+ }
+ } break;
+ case 12: { /* use tidy */
+ if(job->currentnode) {
+ if(dk3str_is_bool(vp)) {
+ if(dk3str_is_on(vp)) {
+ (job->currentnode)->options =
+ ((job->currentnode)->options)
+ | HB_NODE_OPT_USE_TIDY;
+ } else {
+ (job->currentnode)->options =
+ ((job->currentnode)->options)
+ & (~(HB_NODE_OPT_USE_TIDY));
+ }
+ } else {
+ /* WARNING: Not a boolean. */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 144, vp);
+ }
+ }
+ } break;
+ case 13: { /* location */
+ if(job->currentnode) {
+ ptr = dk3str_dup_app(vp,job->app);
+ if(ptr) {
+ dk3_release((job->currentnode)->location);
+ (job->currentnode)->location = ptr;
+ } else {
+ back = -1; /* REPORTED */
+ }
+ }
+ } break;
+ case 14: { /* write header chain */
+ if(job->currentnode) {
+ if(dk3str_is_bool(vp)) {
+ if(dk3str_is_on(vp)) {
+ (job->currentnode)->options =
+ ((job->currentnode)->options)
+ | HB_NODE_OPT_HEADER_CHAIN;
+ } else {
+ (job->currentnode)->options =
+ ((job->currentnode)->options)
+ & (~(HB_NODE_OPT_HEADER_CHAIN));
+ }
+ } else {
+ /* WARNING: Not a boolean */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 144, vp);
+ }
+ }
+ } break;
+ case 15: { /* navigation */
+ /* navigation is now configured via arguments to special cmd */
+ } break;
+ case 16: { /* short */
+ if(job->currentnode) {
+ ptr = dk3str_dup_app(vp,job->app);
+ if(ptr) {
+ if((job->currentnode)->shorttitle) {
+ if(0UL != (job->currentnode)->objno) {
+ /* Overwriting short */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 75);
+ }
+ }
+ dk3_release((job->currentnode)->shorttitle);
+ (job->currentnode)->shorttitle = ptr;
+ } else {
+ back = -1; /* REPORTED */
+ }
+ }
+ } break;
+ case 17: { /* file */
+ if(job->currentnode) {
+ ptr = dk3str_dup_app(vp,job->app);
+ if(ptr) {
+ dk3str_correct_filename(ptr);
+ if(!hbtool_check_filename(job, ptr)) { back = -1; }
+ if((job->currentnode)->filename) {
+ if(0UL != (job->currentnode)->objno) {
+ /* Overwriting file */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 76);
+ }
+ }
+ dk3_release((job->currentnode)->filename);
+ (job->currentnode)->filename = ptr;
+ hbconf_set_jump_node(job->currentnode);
+ if(!(dk3sto_it_find_like(job->i_pnodes,job->currentnode,0))) {
+ if(!(dk3sto_add(job->s_pnodes, job->currentnode))) {
+ back = -1; /* REPORTED */
+ }
+ }
+ } else {
+ back = -1; /* REPORTED */
+ }
+ }
+ } break;
+ case 18: { /* suffix */
+ if(job->currentnode) {
+ ptr = dk3str_dup_app(vp,job->app);
+ if(ptr) {
+ if((job->currentnode)->suffix) {
+ if(0UL != (job->currentnode)->objno) {
+ /* Overwriting suffix */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 77);
+ }
+ }
+ dk3_release((job->currentnode)->suffix);
+ (job->currentnode)->suffix = ptr;
+ /* CHECK FILENAME CHARACTERS */
+ if(!hbtool_check_filename_encoding(job, ptr)) { back = -1; }
+ } else {
+ back = -1; /* REPORTED */
+ }
+ }
+ } break;
+ case 19: {
+ if(job->currentnode) {
+ ptr = dk3str_dup_app(vp,job->app);
+ if(ptr) {
+ dk3str_correct_filename(ptr);
+ if(!hbtool_check_filename(job, ptr)) { back = -1; }
+ if((job->currentnode)->icontoc) {
+ if(0UL != (job->currentnode)->objno) {
+ /* Overwriting icon toc */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 78);
+ }
+ }
+ dk3_release((job->currentnode)->icontoc);
+ (job->currentnode)->icontoc = ptr;
+ /* CHECK FILENAME CHARACTERS */
+ } else {
+ back = -1; /* REPORTED */
+ }
+ }
+ } break;
+ case 20: {
+ if(job->currentnode) {
+ ptr = dk3str_dup_app(vp,job->app);
+ if(ptr) {
+ dk3str_correct_filename(ptr);
+ if(!hbtool_check_filename(job, ptr)) { back = -1; }
+ if((job->currentnode)->iconprev) {
+ if(0UL != (job->currentnode)->objno) {
+ /* Overwriting icon previous */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 79);
+ }
+ }
+ dk3_release((job->currentnode)->iconprev);
+ (job->currentnode)->iconprev = ptr;
+ /* CHECK FILENAME CHARACTERS */
+ } else {
+ back = -1; /* REPORTED */
+ }
+ }
+ } break;
+ case 21: {
+ if(job->currentnode) {
+ ptr = dk3str_dup_app(vp,job->app);
+ if(ptr) {
+ dk3str_correct_filename(ptr);
+ if(!hbtool_check_filename(job, ptr)) { back = -1; }
+ if((job->currentnode)->iconnext) {
+ if(0UL != (job->currentnode)->objno) {
+ /* Overwriting icon next */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 80);
+ }
+ }
+ dk3_release((job->currentnode)->iconnext);
+ (job->currentnode)->iconnext = ptr;
+ /* CHECK FILENAME CHARACTERS */
+ } else {
+ back = -1; /* REPORTED */
+ }
+ }
+ } break;
+ case 22: {
+ if(job->currentnode) {
+ ptr = dk3str_dup_app(vp,job->app);
+ if(ptr) {
+ dk3str_correct_filename(ptr);
+ if(!hbtool_check_filename(job, ptr)) { back = -1; }
+ if((job->currentnode)->iconindex) {
+ if(0UL != (job->currentnode)->objno) {
+ /* Overwriting icon index */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 81);
+ }
+ }
+ dk3_release((job->currentnode)->iconindex);
+ (job->currentnode)->iconindex = ptr;
+ /* CHECK FILENAME CHARACTERS */
+ } else {
+ back = -1; /* REPORTED */
+ }
+ }
+ } break;
+ case 23: {
+ if(HB_SECTION_OPTIONS == st) {
+ if(dk3str_is_bool(vp)) {
+ if(dk3str_is_on(vp)) {
+ job->options = ((job->options) | HB_JOB_OPT_CREATE_TOC);
+ } else {
+ job->options =
+ ((job->options) & (~(HB_JOB_OPT_CREATE_TOC)));
+ }
+ } else {
+ /* Warning: Not a boolean! */
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, vp);
+ }
+ } else {
+ /* ERROR: Only allowed in options section */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 10);
+ }
+ } break;
+ case 24: {
+ if(job->currentnode) {
+ ptr = dk3str_dup_app(vp,job->app);
+ if(ptr) {
+ dk3str_correct_filename(ptr);
+ hbtool_correct_backslash_to_slash(ptr);
+ if((job->currentnode)->favicon) {
+ if(0UL != (job->currentnode)->objno) {
+ /* Overwriting shortcut icon */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 82);
+ }
+ }
+ dk3_release((job->currentnode)->favicon);
+ (job->currentnode)->favicon = ptr;
+ /* ADD TO LIST OF ADDITIONAL FILES */
+ if (!(hbtool_add_file(job, ptr))) {
+ back = -1;
+ }
+ /* CHECK FILENAME CHARACTERS */
+ if(!hbtool_check_filename_encoding(job, ptr)) { back = -1; }
+ } else {
+ back = -1; /* REPORTED */
+ }
+ }
+ } break;
+ case 25: { $? ". set variable"
+ if(job->currentnode) { $? ". have current node"
+ ap = dk3str_next(vp, NULL);
+ if(ap) { $? ". value specified (add,change)"
+ kvp = dk3sto_it_find_like(
+ (job->currentnode)->i_variables, vp, 1
+ );
+ if(kvp) { $? ". existing value found, change"
+ nc = dk3str_dup_app(ap, job->app);
+ if(nc) { $? ". replace previous value"
+ if(kvp->val) {
+ if(0UL != (job->currentnode)->objno) {
+ /* Overwriting var */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 83);
+ }
+ }
+ dk3_release(kvp->val);
+ kvp->val = nc;
+ } else { $? "! allocation failed"
+ back = -1; /* REPORTED */
+ }
+ } else { $? ". no existing value, create"
+ kvp = dk3kv_new_app(vp, ap, job->app);
+ if(kvp) { $? ". allocation ok"
+ if(!(dk3sto_add((job->currentnode)->s_variables, kvp))) {
+ dk3kv_delete(kvp); $? "! add"
+ back = -1; /* REPORTED */
+ }
+ } else { $? "! allocation"
+ back = -1; /* REPORTED */
+ }
+ }
+ } else { $? ". no value (delete)"
+ kvp = dk3sto_it_find_like(
+ (job->currentnode)->i_variables, vp, 1
+ );
+ if(kvp) { $? ". found, removing"
+ dk3sto_remove((job->currentnode)->s_variables, kvp);
+ dk3kv_delete(kvp);
+ }
+ }
+ } else { $? "! no current node"
+ }
+ } break;
+ case 26: { $? ". impressum link"
+ if(HB_SECTION_OPTIONS == st) {
+ ptr = dk3str_dup_app(vp, job->app);
+ if(ptr) {
+ dk3_release(job->impressumlink);
+ job->impressumlink = ptr;
+ } else {
+ back = -1; /* REPORTED */
+ }
+ } else {
+ /* ERROR: Only allowed in options section */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 10);
+ }
+ } break;
+ case 27: { $? ". impressum page"
+ if(HB_SECTION_OPTIONS == st) { $? ". options section"
+ job->impressumnode = hb_node_new(
+ job, job->rootnode, job->lineno, job->nextobj, 0
+ );
+ job->nextobj += 1UL;
+ if(job->impressumnode) { $? ". impressumnode"
+ if((job->impressumnode)->depth > job->maxdepth) {
+ job->maxdepth = (job->impressumnode)->depth;
+ }
+ (job->impressumnode)->options |= HB_NODE_OPT_IMPRESSUM;
+ if(dk3sto_add(job->s_nodes, (void *)(job->impressumnode))) {
+ $? ". added"
+ (job->impressumnode)->title =
+ dk3str_dup_app((job->msg)[0], job->app);
+ if((job->impressumnode)->title) { $? ". title"
+ dk3str_correct_filename(vp);
+ if(!hbtool_check_filename(job, vp)) { back = -1; }
+ /* CHECK FILENAME CHARACTERS */
+ (job->impressumnode)->filename =
+ dk3str_dup_app(vp, job->app);
+ if(!((job->impressumnode)->filename)) {
+ back = -1;
+ }
+ } else { $? "! title"
+ back = -1; /* REPORTED */
+ }
+ if(1 == back) { $? ". success so far"
+ if(!dk3sto_add(job->s_pnodes,(void*)(job->impressumnode)))
+ { $? "! adding to pnodes failed"
+ back = -1; /* REPORTED */
+ }
+ }
+ } else { $? "! failed to add"
+ hb_node_delete(job->impressumnode);
+ job->impressumnode = NULL;
+ back = -1; /* REPORTED */
+ }
+ } else { $? "! impressumnode"
+ back = -1; /* REPORTED */
+ }
+ } else { $? "! wrong section"
+ /* ERROR: Only allowed in options section */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 10);
+ }
+ } break;
+ case 28: { $? ". chm"
+ if(HB_SECTION_OPTIONS == st) {
+ if(dk3str_is_bool(vp)) {
+ if(dk3str_is_on(vp)) {
+ job->options |= HB_JOB_OPT_CHM;
+ } else {
+ job->options &= (~(HB_JOB_OPT_CHM));
+ }
+ } else {
+ /* Warning: Not a boolean */
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, vp);
+ }
+ } else {
+ /* ERROR: Only allowed in options section */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 10);
+ }
+ } break;
+ case 29: { $? ". ln"
+ if(HB_SECTION_OPTIONS == st) {
+ if(dk3str_is_bool(vp)) {
+ if(dk3str_is_on(vp)) {
+ job->options |= HB_JOB_OPT_LN;
+ } else {
+ job->options &= (~(HB_JOB_OPT_LN));
+ }
+ } else {
+ /* Warning: Not a boolean */
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, vp);
+ }
+ } else {
+ /* ERROR: Only allowed in options section */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 10);
+ }
+ } break;
+ case 30: { $? ". input encoding"
+ newie = dk3enc_get_text_encoding_app(vp, NULL);
+ if(0 <= newie) {
+ if(HB_SECTION_OPTIONS == st) {
+ job->iecmd = newie;
+ (job->rootnode)->inenc = newie;
+ }
+ (job->currentnode)->inenc = newie;
+ } else {
+ if(dk3str_casecmp((job->kwnl)[25], vp) == 0) {
+ if(HB_SECTION_OPTIONS == st) {
+ job->iecmd = -1;
+ (job->rootnode)->inenc = -1;
+ }
+ (job->currentnode)->inenc = -1;
+ } else {
+ back = 0;
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 129, 130, vp);
+ }
+ }
+ } break;
+ case 31: { $? ". chm language"
+ if(HB_SECTION_OPTIONS == st) {
+ ptr = dk3str_dup_app(vp, job->app);
+ if(ptr) {
+ dk3_release(job->chmlang);
+ job->chmlang = ptr;
+ } else {
+ back = -1;
+ }
+ } else {
+ /* ERROR: Only allowed in options section */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 10);
+ }
+ } break;
+ case 32: { $? ". js file"
+ if((job->currentnode) && (vp)) {
+ if(!((job->currentnode)->s_jsfiles)) {
+ (job->currentnode)->s_jsfiles =
+ dk3sto_open_app(job->app);
+ if((job->currentnode)->s_jsfiles) {
+ dk3sto_set_comp(
+ (job->currentnode)->s_jsfiles,
+ hbnode_link_compare, 2
+ );
+ }
+ }
+ if(!((job->currentnode)->i_jsfiles)) {
+ if((job->currentnode)->s_jsfiles) {
+ (job->currentnode)->i_jsfiles = dk3sto_it_open(
+ (job->currentnode)->s_jsfiles
+ );
+ }
+ }
+ if((job->currentnode)->s_jsfiles) {
+ if((job->currentnode)->i_jsfiles) {
+ linkptr = hbnode_link_new(
+ vp, (job->currentnode)->nextjs, job->app
+ );
+ if(linkptr) {
+ if(dk3sto_add((job->currentnode)->s_jsfiles, linkptr)) {
+ (job->currentnode)->nextjs += 1UL;
+ } else {
+ hbnode_link_delete(linkptr);
+ back = -1;
+ }
+ } else {
+ back = -1;
+ }
+ } else {
+ back = -1;
+ }
+ } else {
+ back = -1;
+ }
+ }
+ if(vp) {
+ if(!hbtool_add_url(job, vp)) { back = -1; }
+ }
+ } break;
+ case 33: { $? ". inherit js"
+ if(vp) {
+ if(dk3str_is_bool(vp)) {
+ if(dk3str_is_on(vp)) {
+ (job->currentnode)->options &=
+ (~(HB_NODE_OPT_STOP_JS_INHERITANCE));
+ } else {
+ (job->currentnode)->options |=
+ HB_NODE_OPT_STOP_JS_INHERITANCE;
+ }
+ } else {
+ /* Warning: Not a boolean */
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, vp);
+ }
+ } else {
+ if(job->currentnode) {
+ (job->currentnode)->options &=
+ (~(HB_NODE_OPT_STOP_JS_INHERITANCE));
+ }
+ }
+ } break;
+ case 34: { $? ". numbers in position"
+ if(HB_SECTION_OPTIONS == st) {
+ if (vp) {
+ if (dk3str_is_bool(vp)) {
+ if (dk3str_is_on(vp)) {
+ job->options |= HB_JOB_OPT_NUM_IN_POS;
+ } else {
+ job->options &= (~(HB_JOB_OPT_NUM_IN_POS));
+ }
+ } else {
+ /* Warning: Not a boolean */
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, vp);
+ }
+ } else {
+ job->options |= HB_JOB_OPT_NUM_IN_POS;
+ }
+ } else {
+ /* ERROR: Only allowed in options section */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 10);
+ }
+ } break;
+ case 35: { $? ". numbers in index"
+ if(HB_SECTION_OPTIONS == st) {
+ if (vp) {
+ if (dk3str_is_bool(vp)) {
+ if (dk3str_is_on(vp)) {
+ job->options |= HB_JOB_OPT_NUM_IN_IDX;
+ } else {
+ job->options &= (~(HB_JOB_OPT_NUM_IN_IDX));
+ }
+ } else {
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, vp);
+ }
+ } else {
+ job->options |= HB_JOB_OPT_NUM_IN_IDX;
+ }
+ } else {
+ /* ERROR: Only allowed in options section */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 10);
+ }
+ } break;
+ case 36: {
+ if(HB_SECTION_OPTIONS == st) {
+ if (vp) {
+ if (dk3str_is_bool(vp)) {
+ if (dk3str_is_on(vp)) {
+ job->options |= HB_JOB_OPT_NUM_IN_PAGE_HEADER;
+ } else {
+ job->options &= (~(HB_JOB_OPT_NUM_IN_PAGE_HEADER));
+ }
+ } else {
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, vp);
+ }
+ } else {
+ job->options |= HB_JOB_OPT_NUM_IN_PAGE_HEADER;
+ }
+ } else {
+ /* ERROR: Only allowed in options section */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 10);
+ }
+ } break;
+ case 37: {
+ long cn;
+ if (vp) {
+#if VERSION_BEFORE_20140716
+ if (1 == dk3sf_sscanf3(vp, dkT("%ld"), &cn))
+#else
+ if (0 != dk3ma_l_from_string(&cn, vp, NULL))
+#endif
+ {
+ if (job->currentnode) {
+ (job->currentnode)->contnum = cn;
+ } else {
+ /* BUG: No current node set! */
+ }
+ } else {
+ /* ERROR: Not a number */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 141);
+ }
+ } else {
+ /* ERROR: No context number specified */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 133, 134, kp);
+ }
+ } break;
+ case 38: {
+ if(HB_SECTION_OPTIONS == st) {
+ if (vp) {
+ if (dk3str_is_bool(vp)) {
+ if (dk3str_is_on(vp)) {
+ job->options |= HB_JOB_OPT_CHM_FULL_TEXT_SEARCH;
+ } else {
+ job->options &= (~(HB_JOB_OPT_CHM_FULL_TEXT_SEARCH));
+ }
+ } else {
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, vp);
+ }
+ } else {
+ job->options |= HB_JOB_OPT_CHM_FULL_TEXT_SEARCH;
+ }
+ } else {
+ /* ERROR: Only allowed in options section */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 10);
+ }
+ } break;
+ case 39: {
+ if(HB_SECTION_OPTIONS == st) {
+ if (vp) {
+ if (dk3str_is_bool(vp)) {
+ if (dk3str_is_on(vp)) {
+ job->options |= HB_JOB_OPT_CODE_LINE_NUMBERS;
+ } else {
+ job->options &= (~(HB_JOB_OPT_CODE_LINE_NUMBERS));
+ }
+ } else {
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, vp);
+ }
+ } else {
+ job->options |= HB_JOB_OPT_CODE_LINE_NUMBERS;
+ }
+ } else {
+ /* ERROR: Only allowed in options section */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 10);
+ }
+ } break;
+ case 40: {
+ if(job->currentnode) {
+ ptr = dk3str_dup_app(vp,job->app);
+ if(ptr) {
+ dk3str_correct_filename(ptr);
+ if(!hbtool_check_filename(job, ptr)) { back = -1; }
+ if((job->currentnode)->iconhome) {
+ if(0UL != (job->currentnode)->objno) {
+ /* Overwriting icon home */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 95);
+ }
+ }
+ dk3_release((job->currentnode)->iconhome);
+ (job->currentnode)->iconhome = ptr;
+ /* CHECK FILENAME CHARACTERS */
+ } else {
+ back = -1; /* REPORTED */
+ }
+ }
+ } break;
+ default: {
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 43, 44, kp);
+ } break;
+ }
+ } else {
+ /* Warning: Syntax error! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 9);
+ }
+ } else {
+ /* Warning: Syntax error in configuration file */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 8);
+ }
+ } else { $? ". comment line, ok"
+ }
+ } else { $? ". empty line, always ok"
+ }
+ $? "- hbconf_process_line %d", back
+ return back;
+}
+
+
+
+/** Line handler function to process a configuration file.
+ @param obj Pointer to a job structure.
+ @param il Input line to process.
+ @return 1 on success, 0 on error (continue), -1 on error (exit).
+*/
+static
+int
+hbconf_line_reader_handler(void *obj, dkChar *il)
+{
+ int back;
+ $? "+ hbconf_line_reader_handler %!ds", TR_STR(il)
+ back = hbconf_process_line((hb_job_t *)obj, il, HB_SECTION_OPTIONS);
+ $? "- hbconf_line_reader_handler %d", back
+ return back;
+}
+
+
+
+/** Process one configuration file.
+ @param job Job structure.
+ @param fn File name to process.
+ @return 1 on success, 0 on error (continue), -1 on error (exit).
+*/
+int
+hbconf_read_one_file(hb_job_t *job, dkChar const *fn)
+{
+ int back = 0;
+ $? "+ hbconf_read_one_file %!ds", TR_STR(fn)
+ back = dk3stream_process_filename_lines_app(
+ (void *)job, hbconf_line_reader_handler, fn,
+ job->ilfile, job->bs,
+ dk3app_get_encoding(job->app),
+ dk3app_get_input_file_encoding(job->app),
+ job->app
+ );
+ if(1 != back) { back = 0; /* REPORTED */ }
+ $? "- hbconf_read_one_file %d", back
+ return back;
+}
+
+
+
+int
+hbconf_read_files(hb_job_t *job)
+{
+ dk3_search_t *sr = NULL; /* File search result */
+ dkChar const *fn; /* One config file name */
+ int back = 1;
+ $? "+ hbconf_read_files"
+ sr = dk3app_find_config_file(job->app, (job->kwnl)[3], 0);
+ if(sr) {
+ dk3search_reset(sr);
+ while(NULL != (fn = dk3search_next(sr))) {
+ if(back) {
+ if(!hbconf_read_one_file(job, fn)) {
+ back = 0; /* REPORTED */
+ }
+ }
+ }
+ dk3search_close(sr);
+ } $? "- hbconf_read_files %d", back
+ return back;
+}
+
+
+
+dkChar const *
+hbconf_node_template(hb_job_t *job, hb_node_t *node)
+{
+ dkChar const *back = NULL;
+ hb_node_t *nptr; /* Traverse node and parent nodes */
+ $? "+ hbconf_node_template"
+ nptr = node;
+ while((nptr) && (NULL == back)) {
+ if(nptr->template) {
+ back = nptr->template;
+ } else {
+ nptr = nptr->parent;
+ }
+ } $? "- hbconf_node_template \"%!ds\"", TR_STR(back)
+ return back;
+}
+
+
+
+dkChar const *
+hbconf_node_icon(hb_job_t *job, hb_node_t *node, int icno)
+{
+ dkChar const *back = NULL;
+ hb_node_t *nptr; /* Traverse node and parent nodes */
+ $? "+ hbconf_node_icon"
+ nptr = node;
+ while((nptr) && (NULL == back)) {
+ switch(icno) {
+ case 0: {
+ if(nptr->icontoc) {
+ back = nptr->icontoc;
+ } else {
+ nptr = nptr->parent;
+ }
+ } break;
+ case 1: {
+ if(nptr->iconprev) {
+ back = nptr->iconprev;
+ } else {
+ nptr = nptr->parent;
+ }
+ } break;
+ case 2: {
+ if(nptr->iconnext) {
+ back = nptr->iconnext;
+ } else {
+ nptr = nptr->parent;
+ }
+ } break;
+ case 4: {
+ if(nptr->iconhome) {
+ back = nptr->iconhome;
+ } else {
+ nptr = nptr->parent;
+ }
+ } break;
+ default: {
+ if(nptr->iconindex) {
+ back = nptr->iconindex;
+ } else {
+ nptr = nptr->parent;
+ }
+ } break;
+ }
+ }
+ if(!(back)) {
+ back = (job->kwnl)[4 + icno];
+ } $? "- hbconf_node_icon \"%!ds\"", TR_STR(back)
+ return back;
+}
+
+
+
+dkChar const *
+hbconf_title(hb_node_t *node)
+{
+ dkChar const *back = NULL;
+ $? "+ hbconf_title"
+ if (NULL != node->fulltitle) {
+ back = node->fulltitle;
+ } else {
+ while((NULL == back) && (node)) {
+ if(node->title) {
+ back = node->title;
+ } else {
+ node = node->parent;
+ }
+ }
+ }
+ $? "- hbconf_title \"%!ds\"", TR_STR(back)
+ return back;
+}
+
+
+
+dkChar const *
+hbconf_stylefile(hb_node_t *node)
+{
+ dkChar const *back = NULL;
+ $? "+ hbconf_stylefile"
+ while((NULL == back) && (node)) {
+ if(node->stylefile) {
+ back = node->stylefile;
+ } else {
+ node = node->parent;
+ }
+ } $? "- hbconf_stylefile \"%!ds\"", TR_STR(back)
+ return back;
+}
+
+
+
+dkChar const *
+hbconf_author(hb_node_t *node)
+{
+ dkChar const *back = NULL;
+ $? "+ hbconf_author"
+ while((NULL == back) && (node)) {
+ if(node->author) {
+ back = node->author;
+ } else {
+ node = node->parent;
+ }
+ } $? "- hbconf_author \"%!ds\"", TR_STR(back)
+ return back;
+}
+
+
+
+dkChar const *
+hbconf_location(hb_node_t *node)
+{
+ dkChar const *back = NULL;
+ $? "+ hbconf_location"
+ while((NULL == back) && (node)) {
+ if(node->location) {
+ back = node->location;
+ } else {
+ node = node->parent;
+ }
+ } $? "- hbconf_location \"%!ds\"", TR_STR(back)
+ return back;
+}
+
+
+
+dkChar const *
+hbconf_favicon(hb_node_t *node)
+{
+ dkChar const *back = NULL;
+ $? "+ hbconf_favicon"
+ while((NULL == back) && (node)) {
+ if(node->favicon) {
+ back = node->favicon;
+ } else {
+ node = node->parent;
+ }
+ } $? "- hbconf_favicon \"%!ds\"", TR_STR(back)
+ return back;
+}
+
+
diff --git a/support/dktools/hbconf.h b/support/dktools/hbconf.h
new file mode 100644
index 0000000000..f98601f98c
--- /dev/null
+++ b/support/dktools/hbconf.h
@@ -0,0 +1,136 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: hbconf.ctr
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file hbconf.h Header file for the hbconf module.
+*/
+
+#ifndef HBCONF_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define HBCONF_H_INCLUDED 1
+
+
+#line 9 "hbconf.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Read configuration files.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+hbconf_read_files(hb_job_t *job);
+
+/** Read one configuration file.
+ @param job Job structure.
+ @param fn Configuration file name.
+ @return 1 on success, 0 on error.
+*/
+int
+hbconf_read_one_file(hb_job_t *job, dkChar const *fn);
+
+/** Process one configuration line.
+ @param job Job structure.
+ @param il Input line to process, stored also in ilfile.
+ @param st Section type.
+ @return 1 on success, 0 on error (can continue), -1 on error (exit).
+*/
+int
+hbconf_process_line(hb_job_t *job, dkChar *il, int st);
+
+/** Find template name for a node.
+ @param job Job structure.
+ @param node Node to find template for.
+ @return Template file name on success, NULL on error.
+*/
+dkChar const *
+hbconf_node_template(hb_job_t *job, hb_node_t *node);
+
+/** Find icon file name.
+ @param job Job structure.
+ @param node Node to find icon for.
+ @param icno Icon number
+ (0=TOC, 1=previous, 2=next, 3=index, 4=home).
+ @return File name pointer.
+*/
+dkChar const *
+hbconf_node_icon(hb_job_t *job, hb_node_t *node, int icno);
+
+/** Find title for current node.
+ This function is used by the hbhtml_write_header() function
+ to find the title in the HTML head section.
+ We use the full title if available, the title or the title
+ from parent objets...
+ @param node Node to find title for.
+ @return Title on success, NULL on error.
+*/
+dkChar const *
+hbconf_title(hb_node_t *node);
+
+/** Find CSS style file for current node.
+ @param node Node to find style file for.
+ @return File name on success, NULL on error.
+*/
+dkChar const *
+hbconf_stylefile(hb_node_t *node);
+
+/** Find author for current node.
+ @param node Node to find author for.
+ @return Author name on success, NULL on error.
+*/
+dkChar const *
+hbconf_author(hb_node_t *node);
+
+/** Find shortcut icon file name.
+ @param node Node to find file name for.
+ @return File name on success, NULL on error.
+*/
+dkChar const *
+hbconf_favicon(hb_node_t *node);
+
+/** Find location (city).
+ @param node Node to find location for.
+ @return Location on success, NULL on error.
+*/
+dkChar const *
+hbconf_location(hb_node_t *node);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/hbcont.c b/support/dktools/hbcont.c
new file mode 100644
index 0000000000..5f8663761b
--- /dev/null
+++ b/support/dktools/hbcont.c
@@ -0,0 +1,1415 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: hbcont.ctr
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file hbcont.c The hbcont module.
+*/
+
+
+#line 58 "hbcont.ctr"
+
+#include "dk3all.h"
+#include "htmlbook.h"
+
+
+
+
+
+#line 65 "hbcont.ctr"
+
+
+
+/** Object to process a contents line.
+*/
+typedef struct {
+ hb_job_t *job; /**< Job structure. */
+ hb_node_t *nptr; /**< Current node. */
+ unsigned long lineno; /**< Current line number. */
+ unsigned long nheader; /**< Next header number. */
+ unsigned maxheader; /**< Maximum header number found. */
+} hb_contents_line_processor_t;
+
+
+
+/** Output keywords.
+*/
+static char const * const hbcont_c8_kw[] = {
+/* 0 */
+"\n",
+
+/* 1 */
+" ",
+
+/* 2 */
+"<h1>",
+
+/* 3 */
+"</h1>\n",
+
+/* 4 */
+"<table class=\"hb_pos_ta\" summary=\"",
+
+/* 5 */
+"</table>\n",
+
+/* 6 */
+"<tr class=\"hb_pos_tr\">\n",
+
+/* 7 */
+"</tr>\n",
+
+/* 8 */
+"<td class=\"hb_pos_td_arrow\">",
+
+/* 9 */
+"</td>\n",
+
+/* 10 */
+"&#8594;",
+
+/* 11 */
+"<td class=\"hb_pos_td_text\" colspan=\"%d\">",
+
+/* 12 */
+"<h%u>",
+
+/* 13 */
+"</h%u>\n",
+
+/* 14 */
+"<a name=\"",
+
+/* 15 */
+"\"></a>",
+
+/* 16 */
+"hb_h",
+
+/* 17 */
+"<table class=\"hb_ptoc_ta\" summary=\"",
+
+/* 18 */
+"</table>\n",
+
+/* 19 */
+"<tr class=\"hb_ptoc_tr\">",
+
+/* 20 */
+"</tr>\n",
+
+/* 21 */
+"<td class=\"hb_ptoc_td_empty\">&nbsp;&nbsp;&nbsp;</td>\n",
+
+/* 22 */
+"<td class=\"hb_ptoc_td_data\" colspan=\"%u\">",
+
+/* 23 */
+"</td>\n",
+
+/* 24 */
+"<a href=\"#",
+
+/* 25 */
+"\" title=\"",
+
+/* 26 */
+"\" class=\"hb_ptoc_a\">",
+
+/* 27 */
+"</a>",
+
+/* 28 */
+"<div class=\"hb_link_div\">\n<h2>",
+
+/* 29 */
+"</h2>\n",
+
+/* 30 */
+"</div>",
+
+/* 31 */
+"<table class=\"hb_link_ta\" summary=\"",
+
+/* 32 */
+"</table>\n",
+
+/* 33 */
+"<tr class=\"\">\n",
+
+/* 34 */
+"</tr>\n",
+
+/* 35 */
+"<td class=\"hb_link_td_number\">",
+
+/* 36 */
+"</td>\n",
+
+/* 37 */
+"&nbsp;%lu&nbsp;",
+
+/* 38 */
+"<td class=\"hb_link_td_url\">",
+
+/* 39 */
+"<div class=\"hb_dtoc_div\">\n<table class=\"hb_dtoc_ta\" summary=\"",
+
+/* 40 */
+"</table>\n</div><!-- class=\"hb_dtoc_div\" -->\n",
+
+/* 41 */
+"<tr class=\"hb_dtoc_tr\">\n",
+
+/* 42 */
+"</tr>\n",
+
+/* 43 */
+"<td class=\"hb_dtoc_td_space\">&nbsp;&nbsp;&nbsp;</td>\n",
+
+/* 44 */
+"<td class=\"hb_dtoc_td_entry\" colspan=\"%d\">",
+
+/* 45 */
+"<a class=\"hb_dtoc_a\" href=\"",
+
+/* 46 */
+"\">",
+
+/* 47 */
+"<a name=\"hb_toc\"></a><h2 class=\"hb_dtoc_h2\">",
+
+/* 48 */
+"</h2>\n",
+
+/* 49 */
+"<div class=\"hb_pos_div\">",
+
+/* 50 */
+"<div class=\"hb_ki_div\">",
+
+/* 51 */
+"<a name=\"hb_index\"></a><h2 class=\"hb_ki_h2\">",
+
+/* 52 */
+"<dl class=\"hb_ki_dl\">",
+
+/* 53 */
+"</dl>\n",
+
+/* 54 */
+"<dt class=\"hb_ki_dt\">",
+
+/* 55 */
+"</dt>\n",
+
+/* 56 */
+"<dd class=\"hb_ki_dd\">\n<ul class=\"hb_ki_ul\">\n",
+
+/* 57 */
+"</ul>\n</dd>\n",
+
+/* 58 */
+"<li class=\"hb_ki_li\">",
+
+/* 59 */
+"</li>\n",
+
+/* 60 */
+"<a class=\"hb_ki_a\" href=\"",
+
+/* 61 */
+"#",
+
+NULL
+
+
+#line 246 "hbcont.ctr"
+};
+
+
+
+/** Meta data names.
+*/
+const char * const hbcont_metadata_names[] = {
+/* 0 */ "meta-description",
+/* 1 */ "meta-keywords",
+/* 2 */ "author",
+/* 3 */ "title",
+/* 4 */ "short",
+/* 5 */ "location",
+/* 6 */ "page-toc",
+/* 7 */ "replace-ampersand",
+/* 8 */ "write-position",
+/* 9 */ "suffix",
+/* 10 */ "shortcut-icon",
+/* 11 */ "js-file",
+/* 12 */ "inherit-js",
+/* 13 */ "context-number",
+NULL
+};
+
+
+
+/** Number of elements in hbcont_metadata_names including final
+ NULL pointer.
+*/
+static const size_t sz_hbcont_metadata_names =
+sizeof(hbcont_metadata_names) / sizeof(DK3_PCCHAR);
+
+
+
+size_t
+hbcont_metadata_length(size_t idx)
+{
+ size_t back = 0;
+ if (idx < (sz_hbcont_metadata_names - 1)) {
+ back = strlen(hbcont_metadata_names[idx]);
+ }
+ return back;
+}
+
+
+
+void
+hbcont_line_delete(hb_line_t *lp)
+{
+
+
+#line 296 "hbcont.ctr"
+ if(lp) {
+ lp->aname = NULL;
+ lp->realtext = NULL;
+ lp->lineno = 0UL;
+ lp->header = 0UL;
+ lp->headlevel = 0;
+ lp->lt = 0;
+ dk3_release(lp->text);
+ dk3_delete(lp);
+ }
+
+#line 306 "hbcont.ctr"
+}
+
+
+
+hb_line_t *
+hbcont_line_new(dkChar const *il, unsigned long lineno, dk3_app_t *app)
+{
+ hb_line_t *back = NULL;
+
+
+#line 315 "hbcont.ctr"
+ if(il) {
+ back = dk3_new_app(hb_line_t,1,app);
+ if(back) {
+ back->text = NULL;
+ back->aname = NULL;
+ back->realtext = NULL;
+ back->lineno = lineno;
+ back->header = 0UL;
+ back->lt = 0;
+ back->text = dk3str_dup_app(il, app);
+ if(!(back->text)) {
+ hbcont_line_delete(back);
+ back = NULL;
+ }
+ }
+ }
+
+#line 331 "hbcont.ctr"
+ return back;
+}
+
+
+
+/** Compare two saved lines.
+ @param l Left line.
+ @param r Right line.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+static
+int
+hbcont_line_compare(void const *l, void const *r, int cr)
+{
+ hb_line_t *pl;
+ hb_line_t *pr;
+ int back = 0;
+
+
+#line 350 "hbcont.ctr"
+ if(l) {
+ if(r) {
+ pl = (hb_line_t *)l;
+ pr = (hb_line_t *)r;
+ if(pl->lineno > pr->lineno) {
+ back = 1;
+ } else {
+ if(pl->lineno < pr->lineno) {
+ back = -1;
+ }
+ }
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ }
+
+#line 365 "hbcont.ctr"
+ return back;
+}
+
+
+
+/** Prepare current node for content processing (allocate
+ storage and iterator for lines).
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbcont_prepare(hb_job_t *job)
+{
+ int back = 0;
+
+
+#line 381 "hbcont.ctr"
+ (job->currentnode)->s_lines = dk3sto_open_app(job->app);
+ if((job->currentnode)->s_lines) {
+ dk3sto_set_comp((job->currentnode)->s_lines, hbcont_line_compare, 0);
+ (job->currentnode)->i_lines = dk3sto_it_open((job->currentnode)->s_lines);
+ if((job->currentnode)->i_lines) {
+ back = 1;
+ }
+ }
+
+#line 389 "hbcont.ctr"
+ return back;
+}
+
+
+
+/** Clean up current node (release contents lines, storage and iterator).
+ @param job Job structure.
+*/
+static
+void
+hbcont_cleanup(hb_job_t *job)
+{
+ hb_line_t *lp;
+
+
+#line 403 "hbcont.ctr"
+ if((job->currentnode)->s_lines) {
+ if((job->currentnode)->i_lines) {
+ dk3sto_it_reset((job->currentnode)->i_lines);
+ do {
+ lp = (hb_line_t *)dk3sto_it_next((job->currentnode)->i_lines);
+ hbcont_line_delete(lp);
+ } while(lp);
+ dk3sto_it_close((job->currentnode)->i_lines);
+ }
+ dk3sto_close((job->currentnode)->s_lines);
+ }
+ (job->currentnode)->s_lines = NULL;
+ (job->currentnode)->i_lines = NULL;
+
+
+#line 417 "hbcont.ctr"
+}
+
+
+
+/** Check whether a line is a header line.
+ @param il Line to check.
+ @return 1 for headers, 0 for normal lines.
+*/
+static
+int
+hbcont_check_header(dkChar *il)
+{
+ int back = 0;
+
+
+#line 431 "hbcont.ctr"
+ if(dkT('.') == *il) {
+ il++;
+ il = dk3str_start(il, NULL);
+ if(il) {
+ switch(*il) {
+ case dkT('1'): case dkT('2'): case dkT('3'):
+ case dkT('4'): case dkT('5'): case dkT('6'): {
+ back = 1;
+ } break;
+ }
+ }
+ }
+
+#line 443 "hbcont.ctr"
+ return back;
+}
+
+
+
+#if 0
+
+/** Check whether a line is a special line.
+ @param il Input line to check.
+ @return 1 for special line, 0 for line to process normally.
+*/
+static
+int
+hbcont_is_special_line(const dkChar *il)
+{
+ int back = 0;
+ if (dkT('.') == il[0]) {
+ switch (il[1]) {
+ case dkT('d') : {
+ switch (il[2]) {
+ case dkT('e') : {
+ switch (il[3]) {
+ case dkT('s') : {
+ switch (il[4]) {
+ case dkT('c') : {
+ /* .desc
+ */
+ back = 1;
+ } break;
+ }
+ } break;
+ }
+ } break;
+ }
+ } break;
+ }
+ }
+ return back;
+}
+
+#endif
+
+
+
+
+/** Compare input line against one meta data name.
+ @param il Input line.
+ @param mdname Metadata name.
+ @return Comparison result.
+*/
+static
+int
+hbcont_compare_metadata(const dkChar *il, const char *mdname)
+{
+ int back = 0;
+
+
+#line 499 "hbcont.ctr"
+ do {
+ if (*il < (dkChar)(*mdname)) {
+ back = -1;
+ } else {
+ if (*il > (dkChar)(*mdname)) {
+ back = 1;
+ } else {
+ il++; mdname++;
+ }
+ }
+ } while(('\0' != *mdname) && (0 == back));
+
+
+#line 511 "hbcont.ctr"
+ return back;
+}
+
+
+
+/** Check whether input line is started by one meta data keyword.
+ @param il Input line to check.
+ @return Non-negative index on success, -1 if no meta data.
+*/
+static
+int
+hbcont_find_metadata_index(const dkChar *il)
+{
+ const char * const *nptr;
+ int back = -1;
+ int curi = 0;
+
+
+#line 528 "hbcont.ctr"
+ nptr = hbcont_metadata_names;
+ do {
+ if (0 == hbcont_compare_metadata(il, *(nptr++))) {
+ back = curi;
+ } else {
+ curi++;
+ }
+ } while ((NULL != *nptr) && (-1 == back));
+
+
+#line 537 "hbcont.ctr"
+ return back;
+}
+
+
+
+int
+hbcont_metadata_index(const dkChar *il)
+{
+ int back = -1;
+
+
+#line 547 "hbcont.ctr"
+ if (NULL != il) {
+ if (dkT('.') == il[0]) {
+ back = hbcont_find_metadata_index(&(il[1]));
+ }
+ }
+
+
+#line 553 "hbcont.ctr"
+ return back;
+}
+
+
+
+/** Line handler processing function.
+ @param obj Handler object.
+ @param il Input line to process.
+ @return 1 on success, 0 on error (continue), -1 on error (exit).
+*/
+static
+int
+hbcont_line_handler(void *obj, dkChar *il)
+{
+ hb_contents_line_processor_t *proc; /* Processor */
+ hb_job_t *job; /* Job structure */
+ hb_node_t *nptr; /* Current node */
+ hb_line_t *lptr; /* Current line structure */
+ dkChar *p1; /* Start of line */
+ dkChar *p2; /* Start of a name */
+ dkChar *p3; /* Start of real text */
+ unsigned u; /* Header level */
+ int back = 0;
+ dk3str_delnl(il);
+
+
+#line 578 "hbcont.ctr"
+ proc = (hb_contents_line_processor_t *)obj;
+ proc->lineno += 1UL;
+ job = proc->job;
+ nptr = job->currentnode;
+ if (0 > hbcont_metadata_index(il)) {
+ lptr = hbcont_line_new(il, proc->lineno, job->app);
+ if(lptr) {
+ if(dk3sto_add(nptr->s_lines, lptr)) {
+ back = 1;
+ p1 = dk3str_start(lptr->text, NULL);
+ if(p1) {
+ if(hbcont_check_header(p1)) {
+ back = 0;
+ p1++;
+ p1 = dk3str_start(p1, NULL);
+ if(p1) {
+ p2 = dk3str_next(p1, NULL);
+ if(p2) {
+ lptr->realtext = p2;
+ lptr->lt = 1;
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(p1, dkT("%u"), &u) == 1)
+#else
+ if (0 != dk3ma_ui_from_string(&u, p1, NULL))
+#endif
+ {
+ lptr->headlevel = u;
+ lptr->header = proc->nheader;
+ if(u > proc->maxheader) { proc->maxheader = u; }
+ proc->nheader += 1UL;
+ back = 1;
+ if(dkT('@') == *p2) {
+ back = 0;
+ *(p2++) = dkT('\0');
+ p2 = dk3str_start(p2, NULL);
+ if(p2) {
+ p3 = dk3str_chr(p2, dkT('@'));
+ if(p3) {
+ *(p3++) = dkT('\0');
+ p3 = dk3str_start(p3, NULL);
+ if(p3) {
+ lptr->aname = p2;
+ lptr->realtext = p3;
+ back = 1;
+ } else {
+
+#line 623 "hbcont.ctr"
+ /* ERROR: Missing heading text */
+ dk3app_log_1(job->app,DK3_LL_ERROR,job->msg,32);
+ }
+ } else {
+
+#line 627 "hbcont.ctr"
+ /* ERROR: Missing closing @ */
+ dk3app_log_1(job->app,DK3_LL_ERROR,job->msg,33);
+ }
+ } else {
+
+#line 631 "hbcont.ctr"
+ /* ERROR: No a name text */
+ dk3app_log_1(job->app,DK3_LL_ERROR,job->msg,34);
+ }
+ }
+ } else {
+
+#line 636 "hbcont.ctr"
+ /* ERROR: No header level */
+ dk3app_log_1(job->app,DK3_LL_ERROR,job->msg,35);
+ }
+ } else {
+
+#line 640 "hbcont.ctr"
+ /* ERROR: No header text */
+ dk3app_log_1(job->app,DK3_LL_ERROR,job->msg,32);
+ }
+ } else {
+
+#line 644 "hbcont.ctr"
+ /* ERROR: Syntax, no text after dot */
+ dk3app_log_1(job->app,DK3_LL_ERROR,job->msg,36);
+ }
+ }
+ }
+ } else {
+
+#line 650 "hbcont.ctr"
+ /* 2016-10-24: Destroy line structure when failed to save.
+ */
+ hbcont_line_delete(lptr);
+ }
+ } else {
+
+#line 655 "hbcont.ctr"
+ }
+ } else {
+
+#line 657 "hbcont.ctr"
+ back = 1;
+ }
+
+
+#line 660 "hbcont.ctr"
+ return back;
+}
+
+
+
+/** Read contents into storage.
+ @param job Job structure.
+ @param proc Line processing structure.
+ @return 1 on success, 0 on errors.
+*/
+static
+int
+hbcont_read(hb_job_t *job, hb_contents_line_processor_t *proc)
+{
+ int res; /* Result from file processing */
+ int inenc; /* Input encoding */
+ int back = 0;
+
+
+#line 678 "hbcont.ctr"
+ inenc = dk3app_get_input_file_encoding(job->app);
+ if(0 <= job->iecmd) { inenc = job->iecmd; }
+ if(0 <= (job->currentnode)->inenc) { inenc = (job->currentnode)->inenc; }
+ if((job->currentnode)->filename) {
+ res = dk3stream_process_filename_lines_app(
+ (void *)proc, hbcont_line_handler, (job->currentnode)->filename,
+ job->ilfile, job->bs,
+ dk3app_get_encoding(job->app),
+ inenc,
+ job->app
+ );
+ if(1 == res) { back = 1; }
+
+#line 690 "hbcont.ctr"
+ } else {
+ if(0UL == (job->currentnode)->objno) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Write HTML page title.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbcont_write_title(hb_job_t *job)
+{
+ int back = 0;
+
+
+#line 710 "hbcont.ctr"
+ fputs(hbcont_c8_kw[2], job->of);
+ if((job->currentnode)->title) {
+ if (((job->options) & HB_JOB_OPT_NUM_IN_PAGE_HEADER)) {
+ if (!((job->options) & HB_JOB_OPT_CHM)) {
+ if((job->currentnode)->depth < job->headlevels) {
+ if(hbtool_write_header_number(job, job->currentnode)) {
+ hbhtml_output_for_text(job, (job->kwnl[35]));
+ }
+ }
+ }
+ }
+ back = hbhtml_output_for_text(job, (job->currentnode)->title);
+ }
+ fputs(hbcont_c8_kw[3], job->of);
+
+
+#line 725 "hbcont.ctr"
+ return back;
+}
+
+
+
+/** Write position of current node.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbcont_write_position(hb_job_t *job)
+{
+ hb_node_t *nptr; /* Current node to handle. */
+ int i;
+ int rs; /* td width */
+ int curl = 0; /* Current level */
+ int maxl = 0; /* Maximum level */
+ int back = 1;
+
+
+#line 745 "hbcont.ctr"
+ nptr = job->rootnode;
+ while(nptr) {
+ if((nptr->parent) && (nptr->curchild)) {
+ maxl++;
+ }
+ nptr = nptr->curchild;
+ }
+#if TRACE_DEBUG
+ /* DEBUG */ fprintf(job->of , "<!-- maxl=%d -->\n", maxl);
+#endif
+ if(0 < maxl) {
+ fputs(hbcont_c8_kw[49], job->of);
+ fputs(hbcont_c8_kw[4], job->of);
+ if(!hbhtml_output_for_text(job, (job->msg)[54])) { back = 1; }
+ fputs(hbcont_c8_kw[46], job->of);
+ fputs(hbcont_c8_kw[0], job->of);
+ nptr = job->rootnode;
+ while(nptr) {
+ dk3app_set_source_line(job->app, nptr->lineno);
+ if((nptr->parent) && (nptr->curchild)) {
+#if TRACE_DEBUG
+ /* DEBUG */ fprintf(job->of, "<!-- curl=%d maxl=%d -->\n", curl, maxl);
+#endif
+ fputs(hbcont_c8_kw[6], job->of);
+ if(0 < curl) {
+ for(i = 0; i < (curl - 1); i++) {
+ fputs(hbcont_c8_kw[8], job->of);
+ fputs(hbcont_c8_kw[9], job->of);
+ }
+ fputs(hbcont_c8_kw[8], job->of);
+ fputs(hbcont_c8_kw[10], job->of);
+ fputs(hbcont_c8_kw[9], job->of);
+ }
+ rs = maxl - curl;
+ fprintf(job->of, hbcont_c8_kw[11], rs);
+ if(nptr->title) {
+#if (!(VERSION_BEFORE_20140412))
+ /* 2014-04-12
+ Also write header number in position.
+ */
+ if ((job->options) & HB_JOB_OPT_NUM_IN_POS) {
+ if (hbtool_write_header_number(job, nptr)) {
+ if (!hbhtml_output_for_text(job, dkT(" "))) {
+ back = 0;
+ }
+ }
+ }
+#endif
+ if(!hbhtml_output_for_text(job, nptr->title)) {
+ back = 0;
+ }
+ }
+ fputs(hbcont_c8_kw[9], job->of);
+ fputs(hbcont_c8_kw[7], job->of);
+ curl++;
+ }
+ nptr = nptr->curchild;
+ }
+ fputs(hbcont_c8_kw[5], job->of);
+ fputs(hbcont_c8_kw[30], job->of);
+ fputs(hbcont_c8_kw[0], job->of);
+ }
+
+#line 807 "hbcont.ctr"
+ return back;
+}
+
+
+
+/** Write anchor name for a header line.
+ @param job Job structure.
+ @param lptr Line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbcont_write_anchor_name_for_header(hb_job_t *job, hb_line_t *lptr)
+{
+ char buffer[64]; /* Buffer to convert number to text */
+ int back = 1;
+
+
+#line 824 "hbcont.ctr"
+ if(lptr->aname) {
+ if(!hbhtml_url_output_for_text(job, lptr->aname)) {
+ back = 0;
+ }
+ } else {
+#if DK3_SIZEOF_LONG > 4
+ sprintf(buffer, "%016lx", lptr->header);
+#else
+ sprintf(buffer, "%08lx", lptr->header);
+#endif
+ fputs(hbcont_c8_kw[16], job->of);
+ fputs(buffer, job->of);
+ }
+
+#line 837 "hbcont.ctr"
+ return back;
+}
+
+
+
+/** Process the content lines saved before.
+ @param job Job structure.
+ @param proc Line processing structure.
+ @param p Previous node.
+ @param n Next node.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbcont_write_contents(
+ hb_job_t *job,
+ hb_contents_line_processor_t *proc,
+ hb_node_t *p,
+ hb_node_t *n
+)
+{
+ hb_file_processor_t myproc;
+ hb_line_t *lptr; /* Current line to process */
+ hb_line_t *tocptr; /* Current TOC line to process */
+ hb_node_t *nptr; /* Current node to process */
+ dk3_sto_it_t *i_toc; /* Line traversal for TOC */
+ unsigned cs = 0; /* Column space */
+ unsigned sp = 0; /* Spaces before data field */
+ unsigned hl = 0; /* Header level */
+ unsigned i = 0; /* Create spaces */
+ int tocpr = 0; /* Flag: Page TOC already printed */
+ int back = 0;
+
+
+#line 870 "hbcont.ctr"
+ if((job->options) & HB_JOB_OPT_CHM) { tocpr = 1; }
+ nptr = job->currentnode;
+ i_toc = dk3sto_it_open(nptr->s_lines);
+ if(i_toc) {
+ dk3sto_it_reset(nptr->i_lines);
+ dk3sto_it_reset(i_toc);
+ back = 1;
+ do {
+ lptr = (hb_line_t *)dk3sto_it_next(nptr->i_lines);
+ if(lptr) {
+ dk3app_set_source_line(job->app, lptr->lineno);
+ if(lptr->lt) {
+ /* Header line */
+ if((0 == tocpr) && ((nptr->options) & HB_NODE_OPT_PAGE_TOC)) {
+ tocpr = 1;
+
+#line 885 "hbcont.ctr"
+ fputs(hbcont_c8_kw[17], job->of);
+ if(!hbhtml_output_for_text(job, (job->msg)[55])) { back = 0; }
+ fputs(hbcont_c8_kw[46], job->of);
+ fputs(hbcont_c8_kw[0], job->of);
+ do {
+ tocptr = (hb_line_t *)dk3sto_it_next(i_toc);
+ if(tocptr) {
+ if(tocptr->lt) {
+ dk3app_set_source_line(job->app, tocptr->lineno);
+ sp = 0;
+#if 0
+ if(tocptr->headlevel < proc->maxheader) {
+ sp = proc->maxheader - tocptr->headlevel;
+ }
+#endif
+ if(tocptr->headlevel > 0) {
+ sp = tocptr->headlevel - 1;
+ }
+ cs = proc->maxheader - sp;
+ fputs(hbcont_c8_kw[19], job->of);
+ for(i = 0; i < sp; i++) {
+ fputs(hbcont_c8_kw[21], job->of);
+ }
+ fprintf(job->of, hbcont_c8_kw[22], cs);
+ fputs(hbcont_c8_kw[24], job->of);
+ if(!hbcont_write_anchor_name_for_header(job, tocptr)) {
+ back = 0;
+ }
+ fputs(hbcont_c8_kw[25], job->of);
+ if(!hbhtml_output_for_text(job, tocptr->realtext)) {
+ back = 0;
+ }
+ fputs(hbcont_c8_kw[26], job->of);
+ if(!hbhtml_output_for_text(job, tocptr->realtext)) {
+ back = 0;
+ }
+ fputs(hbcont_c8_kw[27], job->of);
+ fputs(hbcont_c8_kw[23], job->of);
+ fputs(hbcont_c8_kw[20], job->of);
+ dk3app_set_source_line(job->app, lptr->lineno);
+ }
+ }
+ } while(tocptr);
+ fputs(hbcont_c8_kw[18], job->of);
+ }
+ hl = 1 + lptr->headlevel;
+ if(6 < hl) {
+ hl = 6;
+ /* Warning: Header level corrected to 6! */
+ dk3app_log_1(job->app,DK3_LL_ERROR,job->msg,37);
+ }
+ fprintf(job->of, hbcont_c8_kw[14], hl);
+ if(!hbcont_write_anchor_name_for_header(job, lptr)) {
+ back = 0;
+
+#line 939 "hbcont.ctr"
+ }
+ fprintf(job->of, hbcont_c8_kw[15], hl);
+ fprintf(job->of, hbcont_c8_kw[12], hl);
+ if(!hbhtml_output_for_text(job, lptr->realtext)) {
+ back = 0;
+
+#line 944 "hbcont.ctr"
+ }
+ fprintf(job->of, hbcont_c8_kw[13], hl);
+ } else {
+ myproc.job = job;
+ myproc.in_template = 0;
+ myproc.stm = 0;
+ myproc.p = p;
+ myproc.n = n;
+
+#line 952 "hbcont.ctr"
+ if(1 != hbhtml_line_handler((void *)(&myproc), lptr->text)) {
+ back = 0;
+
+#line 954 "hbcont.ctr"
+ }
+ }
+ }
+ } while(lptr);
+ dk3sto_it_close(i_toc);
+ }
+
+#line 960 "hbcont.ctr"
+ return back;
+}
+
+
+
+/** Write list of external links for current node.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbcont_write_link_list(hb_job_t *job)
+{
+ hb_link_t *linkptr; /* Current link to process */
+ hb_node_t *nptr; /* Current node to process */
+ int back = 1;
+
+
+#line 977 "hbcont.ctr"
+ nptr = job->currentnode;
+ if(nptr->nextlink) {
+ dk3sto_it_reset(nptr->i_lbylno);
+ fputs(hbcont_c8_kw[28], job->of);
+ if(!hbhtml_output_for_text(job, (job->msg)[23])) { back = 0; }
+ fputs(hbcont_c8_kw[29], job->of);
+ fputs(hbcont_c8_kw[31], job->of);
+ if(!hbhtml_output_for_text(job, (job->msg)[56])) { back = 0; }
+ fputs(hbcont_c8_kw[46], job->of);
+ fputs(hbcont_c8_kw[0], job->of);
+ while(NULL != (linkptr = (hb_link_t *)dk3sto_it_next(nptr->i_lbylno))) {
+ fputs(hbcont_c8_kw[33], job->of);
+ /* Number */
+ fputs(hbcont_c8_kw[35], job->of);
+ fprintf(job->of, hbcont_c8_kw[37], (1UL + linkptr->lno));
+ fputs(hbcont_c8_kw[36], job->of);
+ /* URL */
+ fputs(hbcont_c8_kw[38], job->of);
+ if(!hbhtml_url_output_for_text(job, linkptr->url)) { back = 1; }
+ fputs(hbcont_c8_kw[36], job->of);
+ fputs(hbcont_c8_kw[34], job->of);
+ }
+ fputs(hbcont_c8_kw[32], job->of);
+ fputs(hbcont_c8_kw[30], job->of);
+ }
+
+#line 1002 "hbcont.ctr"
+ return back;
+}
+
+
+
+/** Create project table of contents.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbcont_create_toc(hb_job_t *job)
+{
+ dkChar ofn[DK3_MAX_PATH]; /* Output file name */
+ hb_node_t *nptr; /* Current node to process */
+ hb_node_t *dest; /* Print node for cur node */
+ dkChar const *oldsourcefile; /* Old source file name saved */
+ unsigned long oldsourceline; /* Old source file line saved */
+ int res; /* Result from file name cr */
+ int i;
+ int back = 1;
+
+
+#line 1024 "hbcont.ctr"
+ oldsourcefile = dk3app_get_source_file(job->app);
+ oldsourceline = dk3app_get_source_line(job->app);
+ dk3app_set_source_file(job->app, job->infilename);
+ dk3app_set_source_line(job->app, 0UL);
+ fputs(hbcont_c8_kw[47], job->of);
+ if(!hbhtml_output_for_text(job, (job->msg)[45])) { back = 0; }
+ fputs(hbcont_c8_kw[48], job->of);
+ fputs(hbcont_c8_kw[39], job->of);
+ if(!hbhtml_output_for_text(job, (job->msg)[57])) { back = 0; }
+ fputs(hbcont_c8_kw[46], job->of);
+ fputs(hbcont_c8_kw[0], job->of);
+ nptr = job->rootnode;
+ while(nptr) {
+
+
+#line 1038 "hbcont.ctr"
+ dk3app_set_source_line(job->app, nptr->lineno);
+ switch(nptr->tocstate) {
+ case HB_TOC_STATE_INIT: {
+
+#line 1041 "hbcont.ctr"
+ if(nptr->parent) {
+ /* Write TOC entry */
+ dest = NULL;
+ if(nptr->filename) {
+ dest = nptr;
+ } else {
+ if(nptr->jumpnode) {
+ dest = nptr->jumpnode;
+ }
+ }
+ if(dest) {
+
+#line 1052 "hbcont.ctr"
+ res =
+ hbhtml_create_output_filename(ofn,DK3_SIZEOF(ofn,dkChar),job,dest);
+ if(res) {
+ fputs(hbcont_c8_kw[41], job->of);
+ for(i = 1; i < nptr->depth; i++) {
+ fputs(hbcont_c8_kw[43], job->of);
+ }
+ fprintf(
+ job->of, hbcont_c8_kw[44], ((job->maxdepth) - (nptr->depth) + 1)
+ );
+ fputs(hbcont_c8_kw[45], job->of);
+ if(!hbhtml_url_output_for_text(job, ofn)) { back = 0; }
+ fputs(hbcont_c8_kw[25], job->of);
+ if(hbtool_write_header_number(job, nptr)) {
+ fputs(hbcont_c8_kw[1], job->of);
+ }
+ if(!hbhtml_output_for_text(job, nptr->title)) { back = 0; }
+ fputs(hbcont_c8_kw[46], job->of);
+ if(hbtool_write_header_number(job, nptr)) {
+ fputs(hbcont_c8_kw[1], job->of);
+ }
+ if(!hbhtml_output_for_text(job, nptr->title)) { back = 0; }
+ fputs(hbcont_c8_kw[27], job->of);
+ fputs(hbcont_c8_kw[9], job->of);
+ fputs(hbcont_c8_kw[42], job->of);
+ } else {
+ /* ERROR: Failed to create output file name */
+ back = 0;
+ }
+ } else {
+
+#line 1082 "hbcont.ctr"
+ /* ERROR: No destination found */
+ back = 0;
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 51);
+ }
+ }
+ dk3sto_it_reset(nptr->i_subnodes);
+ nptr->tocstate = HB_TOC_STATE_IN_PROGRESS;
+ } break;
+ case HB_TOC_STATE_IN_PROGRESS: {
+
+#line 1091 "hbcont.ctr"
+ nptr->curchild = dk3sto_it_next(nptr->i_subnodes);
+ if(nptr->curchild) {
+ nptr = nptr->curchild;
+ } else {
+ nptr->tocstate = HB_TOC_STATE_FINISHED;
+ }
+ } break;
+ case HB_TOC_STATE_FINISHED: {
+
+#line 1099 "hbcont.ctr"
+ nptr = nptr->parent;
+ } break;
+ }
+ }
+ fputs(hbcont_c8_kw[40], job->of);
+ dk3app_set_source_file(job->app, oldsourcefile);
+ dk3app_set_source_line(job->app, oldsourceline);
+
+
+#line 1107 "hbcont.ctr"
+ return back;
+}
+
+
+
+/** Create keyword index.
+ @param job Job structure
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbcont_create_keyword_index(hb_job_t *job)
+{
+ hb_index_entry_t *pp = NULL; /* Previous pointer */
+ hb_index_entry_t *cp = NULL; /* Current pointer */
+#if VERSION_BEFORE_20150821
+ dk3_c32_t pstc = 0UL; /* Previous start character */
+ dk3_c32_t cstc = 0UL; /* Start character */
+#endif
+ int nkw = 0; /* Flag: Open new keyword */
+ int hh2 = 0; /* Flag: Have division and h2 */
+ int back = 1;
+
+
+#line 1130 "hbcont.ctr"
+ dk3sto_it_reset(job->i_index);
+ while(NULL != (cp = (hb_index_entry_t *)dk3sto_it_next(job->i_index))) {
+
+
+#line 1133 "hbcont.ctr"
+ if(!(hh2)) {
+
+#line 1134 "hbcont.ctr"
+ hh2 = 1;
+ fputs(hbcont_c8_kw[50], job->of);
+ fputs(hbcont_c8_kw[51], job->of);
+ if(!hbhtml_output_for_text(job, (job->msg)[46])) { back = 0; }
+ fputs(hbcont_c8_kw[29], job->of);
+ fputs(hbcont_c8_kw[52], job->of);
+ }
+ /* Process entry.
+ */
+ nkw = 0;
+ if(pp) {
+
+#line 1145 "hbcont.ctr"
+ if(dk3str_cmp(pp->tx, cp->tx)) {
+
+#line 1146 "hbcont.ctr"
+ nkw = 1;
+ fputs(hbcont_c8_kw[57], job->of);
+ }
+ } else {
+ nkw = 1;
+ }
+ if(nkw) {
+ fputs(hbcont_c8_kw[54], job->of);
+ if(!hbhtml_output_for_text(job, cp->tx)) { back = 0; }
+ fputs(hbcont_c8_kw[55], job->of);
+ fputs(hbcont_c8_kw[56], job->of);
+ }
+ fputs(hbcont_c8_kw[58], job->of);
+ fputs(hbcont_c8_kw[60], job->of);
+ if(!hbhtml_url_output_for_text(job, cp->fn)) { back = 0; }
+ fputs(hbcont_c8_kw[61], job->of);
+ if(!hb_index_write_anchor(job, cp)) { back = 0; }
+#if (!(VERSION_BEFORE_20140412))
+ fputs(hbcont_c8_kw[25], job->of);
+ (void)hbtool_write_all_titles(job, cp->no, 1);
+#endif
+ fputs(hbcont_c8_kw[46], job->of);
+ if(cp->no) {
+ if((cp->no)->title) {
+#if (!(VERSION_BEFORE_20140412))
+ if ((job->options) & HB_JOB_OPT_NUM_IN_IDX) {
+ if (hbtool_write_header_number(job, cp->no)) {
+ hbhtml_output_for_text(job, dkT(" "));
+ }
+ }
+#endif
+ if(!hbhtml_output_for_text(job, (cp->no)->title)) { back = 0; }
+ } else back = 0;
+ } else { back = 0; }
+ fputs(hbcont_c8_kw[27], job->of);
+ fputs(hbcont_c8_kw[59], job->of);
+ pp = cp;
+#if VERSION_BEFORE_20150821
+ pstc = cstc;
+#endif
+ }
+ if(hh2) {
+ fputs(hbcont_c8_kw[57], job->of);
+ fputs(hbcont_c8_kw[53], job->of);
+ fputs(hbcont_c8_kw[30], job->of);
+ fputs(hbcont_c8_kw[0], job->of);
+ }
+
+#line 1193 "hbcont.ctr"
+ return back;
+}
+
+
+
+int
+hbcont_process(hb_job_t *job, hb_node_t *p, hb_node_t *n)
+{
+ hb_contents_line_processor_t proc;
+ dkChar const *oldsourcefile;
+ unsigned long oldsourceline;
+ int back = 0;
+
+
+#line 1206 "hbcont.ctr"
+ oldsourcefile = dk3app_get_source_file(job->app);
+ oldsourceline = dk3app_get_source_line(job->app);
+ proc.job = job;
+ proc.nptr = job->currentnode;
+ proc.lineno = 0UL;
+ proc.nheader = 0UL;
+ proc.maxheader = 0;
+
+ dk3app_set_source_file(job->app, job->infilename);
+ dk3app_set_source_line(job->app, (job->currentnode)->lineno);
+ if(hbcont_prepare(job)) {
+ dk3app_set_source_file(job->app, (job->currentnode)->filename);
+ dk3app_set_source_line(job->app, 0UL);
+ if(hbcont_read(job, &proc)) {
+ back = 1;
+
+ /* For the root node we do not write a position.
+ */
+ if((0UL != (job->currentnode)->objno) && ((job->currentnode)->filename)) {
+ if(!((job->options) & HB_JOB_OPT_CHM)) {
+ if(((job->currentnode)->options) & HB_NODE_OPT_HEADER_CHAIN) {
+ dk3app_set_source_file(job->app, job->infilename);
+ if(!hbcont_write_position(job)) { back = 0; }
+ }
+ }
+ }
+
+ dk3app_set_source_file(job->app, job->infilename);
+ dk3app_set_source_line(job->app, (job->currentnode)->lineno);
+ if(!hbcont_write_title(job)) { back = 0; }
+
+ /* We can write contents only if an input file is specified.
+ */
+ if((job->currentnode)->filename) {
+ dk3app_set_source_file(job->app, (job->currentnode)->filename);
+ dk3app_set_source_line(job->app, 0UL);
+ if(!hbcont_write_contents(job, &proc, p, n)) { back = 0; }
+
+ dk3app_set_source_file(job->app, (job->currentnode)->filename);
+ dk3app_set_source_line(job->app, 0UL);
+ if((job->currentnode)->nextlink) {
+ if(!hbcont_write_link_list(job)) { back = 0; }
+ }
+ }
+
+ if(0UL == (job->currentnode)->objno) {
+
+#line 1252 "hbcont.ctr"
+ if(!((job->options) & HB_JOB_OPT_CHM)) {
+ if((job->options) & HB_JOB_OPT_CREATE_TOC) {
+
+#line 1254 "hbcont.ctr"
+ if(!hbcont_create_toc(job)) { back = 0; }
+ }
+ if((job->options) & HB_JOB_OPT_CREATE_INDEX) {
+
+#line 1257 "hbcont.ctr"
+ /* Eventually create index */
+ if(!hbcont_create_keyword_index(job)) { back = 0; }
+ }
+ }
+ }
+ }
+ dk3app_set_source_file(job->app, job->infilename);
+ dk3app_set_source_line(job->app, (job->currentnode)->lineno);
+ }
+ hbcont_cleanup(job);
+ dk3app_set_source_file(job->app, oldsourcefile);
+ dk3app_set_source_line(job->app, oldsourceline);
+
+
+#line 1270 "hbcont.ctr"
+ return back;
+}
+
+
diff --git a/support/dktools/hbcont.ctr b/support/dktools/hbcont.ctr
new file mode 100644
index 0000000000..a30e6f6c4a
--- /dev/null
+++ b/support/dktools/hbcont.ctr
@@ -0,0 +1,1273 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2013-xxxx
+license = bsd
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Process the contents.
+ @param job Job structure, current node is set.
+ @param p Previous node (if any).
+ @param n Next node (if any).
+ @return 1 on success, 0 on error.
+*/
+int
+hbcont_process(hb_job_t *job, hb_node_t *p, hb_node_t *n);
+
+/** Create contents line structure.
+ @param il Input line to save.
+ @param lineno Line number of input line.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new line structure on success, NULL on error.
+*/
+hb_line_t *
+hbcont_line_new(dkChar const *il, unsigned long lineno, dk3_app_t *app);
+
+/** Delete one contents line.
+ @param lp Contents line to delete.
+*/
+void
+hbcont_line_delete(hb_line_t *lp);
+
+/** Check whether input line is started by dot and one meta data keyword.
+ @param il Input line to check.
+ @return Non-negative index on success, -1 if no meta data.
+*/
+int
+hbcont_metadata_index(const dkChar *il);
+
+/** Find length of metadata name.
+ @param idx Index of metadata name.
+ @return Positive length on success, 0 on error.
+*/
+size_t
+hbcont_metadata_length(size_t idx);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "dk3all.h"
+#include "htmlbook.h"
+
+
+
+$!trace-include
+
+
+
+/** Object to process a contents line.
+*/
+typedef struct {
+ hb_job_t *job; /**< Job structure. */
+ hb_node_t *nptr; /**< Current node. */
+ unsigned long lineno; /**< Current line number. */
+ unsigned long nheader; /**< Next header number. */
+ unsigned maxheader; /**< Maximum header number found. */
+} hb_contents_line_processor_t;
+
+
+
+/** Output keywords.
+*/
+static char const * const hbcont_c8_kw[] = {
+$!string-table
+#
+# 0 Newline
+#
+\n
+#
+# 1 Space
+#
+
+#
+# 2 3 H1 tags.
+#
+<h1>
+</h1>\n
+#
+# 4 5 Position table
+#
+<table class="hb_pos_ta" summary="
+</table>\n
+#
+# 6 7 Position table row
+#
+<tr class="hb_pos_tr">\n
+</tr>\n
+#
+# 8 9 Position table data
+#
+<td class="hb_pos_td_arrow">
+</td>\n
+#
+# 10 Right arrow
+#
+&#8594;
+#
+# 11 Position table data with colspan
+#
+<td class="hb_pos_td_text" colspan="%d">
+#
+# 12 13 Header in variable depth
+#
+<h%u>
+</h%u>\n
+#
+# 14 15 Named anchors before headers
+#
+<a name="
+"></a>
+#
+# 16 Start of anchor name for header
+#
+hb_h
+#
+# 17 18 Page TOC table
+#
+<table class="hb_ptoc_ta" summary="
+</table>\n
+#
+# 19 20 Page TOC row
+#
+<tr class="hb_ptoc_tr">
+</tr>\n
+#
+# 21 Page TOC space data
+#
+<td class="hb_ptoc_td_empty">&nbsp;&nbsp;&nbsp;</td>\n
+#
+# 22 23 Page TOC data field
+#
+<td class="hb_ptoc_td_data" colspan="%u">
+</td>\n
+#
+# 24 25 26 27 Link for page TOC entry
+#
+<a href="#
+" title="
+" class="hb_ptoc_a">
+</a>
+#
+# 28 29 30 Link division
+#
+<div class="hb_link_div">\n<h2>
+</h2>\n
+</div>
+#
+# 31 32 Table for links
+#
+<table class="hb_link_ta" summary="
+</table>\n
+#
+# 33 34 Table row for links
+#
+<tr class="">\n
+</tr>\n
+#
+# 35 36 37 Table data for number
+#
+<td class="hb_link_td_number">
+</td>\n
+&nbsp;%lu&nbsp;
+#
+# 38 Table data for URL
+#
+<td class="hb_link_td_url">
+#
+# 39 40 Table for TOC
+#
+<div class="hb_dtoc_div">\n<table class="hb_dtoc_ta" summary="
+</table>\n</div><!-- class="hb_dtoc_div" -->\n
+#
+# 41 42 43 44 Table row for TOC
+#
+<tr class="hb_dtoc_tr">\n
+</tr>\n
+<td class="hb_dtoc_td_space">&nbsp;&nbsp;&nbsp;</td>\n
+<td class="hb_dtoc_td_entry" colspan="%d">
+#
+# 45 46
+#
+<a class="hb_dtoc_a" href="
+">
+#
+# 47 48
+#
+<a name="hb_toc"></a><h2 class="hb_dtoc_h2">
+</h2>\n
+#
+# 49
+#
+<div class="hb_pos_div">
+#
+# 50
+#
+<div class="hb_ki_div">
+#
+# 51
+#
+<a name="hb_index"></a><h2 class="hb_ki_h2">
+#
+# 52 53
+#
+<dl class="hb_ki_dl">
+</dl>\n
+#
+# 54 55
+#
+<dt class="hb_ki_dt">
+</dt>\n
+#
+# 56 57
+#
+<dd class="hb_ki_dd">\n<ul class="hb_ki_ul">\n
+</ul>\n</dd>\n
+#
+# 58 59
+#
+<li class="hb_ki_li">
+</li>\n
+#
+# 60 61
+#
+<a class="hb_ki_a" href="
+\#
+$!end
+};
+
+
+
+/** Meta data names.
+*/
+const char * const hbcont_metadata_names[] = {
+/* 0 */ "meta-description",
+/* 1 */ "meta-keywords",
+/* 2 */ "author",
+/* 3 */ "title",
+/* 4 */ "short",
+/* 5 */ "location",
+/* 6 */ "page-toc",
+/* 7 */ "replace-ampersand",
+/* 8 */ "write-position",
+/* 9 */ "suffix",
+/* 10 */ "shortcut-icon",
+/* 11 */ "js-file",
+/* 12 */ "inherit-js",
+/* 13 */ "context-number",
+NULL
+};
+
+
+
+/** Number of elements in hbcont_metadata_names including final
+ NULL pointer.
+*/
+static const size_t sz_hbcont_metadata_names =
+sizeof(hbcont_metadata_names) / sizeof(DK3_PCCHAR);
+
+
+
+size_t
+hbcont_metadata_length(size_t idx)
+{
+ size_t back = 0;
+ if (idx < (sz_hbcont_metadata_names - 1)) {
+ back = strlen(hbcont_metadata_names[idx]);
+ }
+ return back;
+}
+
+
+
+void
+hbcont_line_delete(hb_line_t *lp)
+{
+ $? "+ hbcont_line_delete PTR=%d", TR_IPTR(lp)
+ if(lp) {
+ lp->aname = NULL;
+ lp->realtext = NULL;
+ lp->lineno = 0UL;
+ lp->header = 0UL;
+ lp->headlevel = 0;
+ lp->lt = 0;
+ dk3_release(lp->text);
+ dk3_delete(lp);
+ } $? "- hbcont_line_delete"
+}
+
+
+
+hb_line_t *
+hbcont_line_new(dkChar const *il, unsigned long lineno, dk3_app_t *app)
+{
+ hb_line_t *back = NULL;
+ $? "+ hbcont_line_new"
+ if(il) {
+ back = dk3_new_app(hb_line_t,1,app);
+ if(back) {
+ back->text = NULL;
+ back->aname = NULL;
+ back->realtext = NULL;
+ back->lineno = lineno;
+ back->header = 0UL;
+ back->lt = 0;
+ back->text = dk3str_dup_app(il, app);
+ if(!(back->text)) {
+ hbcont_line_delete(back);
+ back = NULL;
+ }
+ }
+ } $? "- hbcont_line_new PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/** Compare two saved lines.
+ @param l Left line.
+ @param r Right line.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+static
+int
+hbcont_line_compare(void const *l, void const *r, int cr)
+{
+ hb_line_t *pl;
+ hb_line_t *pr;
+ int back = 0;
+ $? "+ hbcont_line_compare PTR=%d PTR=%d", TR_IPTR(l), TR_IPTR(r)
+ if(l) {
+ if(r) {
+ pl = (hb_line_t *)l;
+ pr = (hb_line_t *)r;
+ if(pl->lineno > pr->lineno) {
+ back = 1;
+ } else {
+ if(pl->lineno < pr->lineno) {
+ back = -1;
+ }
+ }
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ } $? "- hbcont_line_compare %d", back
+ return back;
+}
+
+
+
+/** Prepare current node for content processing (allocate
+ storage and iterator for lines).
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbcont_prepare(hb_job_t *job)
+{
+ int back = 0;
+ $? "+ hbcont_prepare"
+ (job->currentnode)->s_lines = dk3sto_open_app(job->app);
+ if((job->currentnode)->s_lines) {
+ dk3sto_set_comp((job->currentnode)->s_lines, hbcont_line_compare, 0);
+ (job->currentnode)->i_lines = dk3sto_it_open((job->currentnode)->s_lines);
+ if((job->currentnode)->i_lines) {
+ back = 1;
+ }
+ } $? "- hbcont_prepare %d", back
+ return back;
+}
+
+
+
+/** Clean up current node (release contents lines, storage and iterator).
+ @param job Job structure.
+*/
+static
+void
+hbcont_cleanup(hb_job_t *job)
+{
+ hb_line_t *lp;
+ $? "+ hbcont_cleanup"
+ if((job->currentnode)->s_lines) {
+ if((job->currentnode)->i_lines) {
+ dk3sto_it_reset((job->currentnode)->i_lines);
+ do {
+ lp = (hb_line_t *)dk3sto_it_next((job->currentnode)->i_lines);
+ hbcont_line_delete(lp);
+ } while(lp);
+ dk3sto_it_close((job->currentnode)->i_lines);
+ }
+ dk3sto_close((job->currentnode)->s_lines);
+ }
+ (job->currentnode)->s_lines = NULL;
+ (job->currentnode)->i_lines = NULL;
+ $? "- hbcont_cleanup"
+}
+
+
+
+/** Check whether a line is a header line.
+ @param il Line to check.
+ @return 1 for headers, 0 for normal lines.
+*/
+static
+int
+hbcont_check_header(dkChar *il)
+{
+ int back = 0;
+ $? "+ hbcont_check_header \"%!ds\"", TR_STR(il)
+ if(dkT('.') == *il) {
+ il++;
+ il = dk3str_start(il, NULL);
+ if(il) {
+ switch(*il) {
+ case dkT('1'): case dkT('2'): case dkT('3'):
+ case dkT('4'): case dkT('5'): case dkT('6'): {
+ back = 1;
+ } break;
+ }
+ }
+ } $? "- hbcont_check_header %d", back
+ return back;
+}
+
+
+
+#if 0
+
+/** Check whether a line is a special line.
+ @param il Input line to check.
+ @return 1 for special line, 0 for line to process normally.
+*/
+static
+int
+hbcont_is_special_line(const dkChar *il)
+{
+ int back = 0;
+ if (dkT('.') == il[0]) {
+ switch (il[1]) {
+ case dkT('d') : {
+ switch (il[2]) {
+ case dkT('e') : {
+ switch (il[3]) {
+ case dkT('s') : {
+ switch (il[4]) {
+ case dkT('c') : {
+ /* .desc
+ */
+ back = 1;
+ } break;
+ }
+ } break;
+ }
+ } break;
+ }
+ } break;
+ }
+ }
+ return back;
+}
+
+#endif
+
+
+
+
+/** Compare input line against one meta data name.
+ @param il Input line.
+ @param mdname Metadata name.
+ @return Comparison result.
+*/
+static
+int
+hbcont_compare_metadata(const dkChar *il, const char *mdname)
+{
+ int back = 0;
+ $? "+ hbcont_compare_metadata \"%!ds\" \"%!8s\"", il, mdname
+ do {
+ if (*il < (dkChar)(*mdname)) {
+ back = -1;
+ } else {
+ if (*il > (dkChar)(*mdname)) {
+ back = 1;
+ } else {
+ il++; mdname++;
+ }
+ }
+ } while(('\0' != *mdname) && (0 == back));
+ $? "- hbcont_compare_metadata %d", back
+ return back;
+}
+
+
+
+/** Check whether input line is started by one meta data keyword.
+ @param il Input line to check.
+ @return Non-negative index on success, -1 if no meta data.
+*/
+static
+int
+hbcont_find_metadata_index(const dkChar *il)
+{
+ const char * const *nptr;
+ int back = -1;
+ int curi = 0;
+ $? "+ hbcont_find_metadata_index \"%!ds\"", il
+ nptr = hbcont_metadata_names;
+ do {
+ if (0 == hbcont_compare_metadata(il, *(nptr++))) {
+ back = curi;
+ } else {
+ curi++;
+ }
+ } while ((NULL != *nptr) && (-1 == back));
+ $? "- hbcont_find_metadata_index %d", back
+ return back;
+}
+
+
+
+int
+hbcont_metadata_index(const dkChar *il)
+{
+ int back = -1;
+ $? "+ hbcont_metadata_index \"%!ds\"", il
+ if (NULL != il) {
+ if (dkT('.') == il[0]) {
+ back = hbcont_find_metadata_index(&(il[1]));
+ }
+ }
+ $? "- hbcont_metadata_index %d", back
+ return back;
+}
+
+
+
+/** Line handler processing function.
+ @param obj Handler object.
+ @param il Input line to process.
+ @return 1 on success, 0 on error (continue), -1 on error (exit).
+*/
+static
+int
+hbcont_line_handler(void *obj, dkChar *il)
+{
+ hb_contents_line_processor_t *proc; /* Processor */
+ hb_job_t *job; /* Job structure */
+ hb_node_t *nptr; /* Current node */
+ hb_line_t *lptr; /* Current line structure */
+ dkChar *p1; /* Start of line */
+ dkChar *p2; /* Start of a name */
+ dkChar *p3; /* Start of real text */
+ unsigned u; /* Header level */
+ int back = 0;
+ dk3str_delnl(il);
+ $? "+ hbcont_line_handler \"%!ds\"", il
+ proc = (hb_contents_line_processor_t *)obj;
+ proc->lineno += 1UL;
+ job = proc->job;
+ nptr = job->currentnode;
+ if (0 > hbcont_metadata_index(il)) {
+ lptr = hbcont_line_new(il, proc->lineno, job->app);
+ if(lptr) {
+ if(dk3sto_add(nptr->s_lines, lptr)) {
+ back = 1;
+ p1 = dk3str_start(lptr->text, NULL);
+ if(p1) {
+ if(hbcont_check_header(p1)) {
+ back = 0;
+ p1++;
+ p1 = dk3str_start(p1, NULL);
+ if(p1) {
+ p2 = dk3str_next(p1, NULL);
+ if(p2) {
+ lptr->realtext = p2;
+ lptr->lt = 1;
+#if VERSION_BEFORE_20140716
+ if(dk3sf_sscanf3(p1, dkT("%u"), &u) == 1)
+#else
+ if (0 != dk3ma_ui_from_string(&u, p1, NULL))
+#endif
+ {
+ lptr->headlevel = u;
+ lptr->header = proc->nheader;
+ if(u > proc->maxheader) { proc->maxheader = u; }
+ proc->nheader += 1UL;
+ back = 1;
+ if(dkT('@') == *p2) {
+ back = 0;
+ *(p2++) = dkT('\0');
+ p2 = dk3str_start(p2, NULL);
+ if(p2) {
+ p3 = dk3str_chr(p2, dkT('@'));
+ if(p3) {
+ *(p3++) = dkT('\0');
+ p3 = dk3str_start(p3, NULL);
+ if(p3) {
+ lptr->aname = p2;
+ lptr->realtext = p3;
+ back = 1;
+ } else { $? "! Missing heading text"
+ /* ERROR: Missing heading text */
+ dk3app_log_1(job->app,DK3_LL_ERROR,job->msg,32);
+ }
+ } else { $? "! no closing @"
+ /* ERROR: Missing closing @ */
+ dk3app_log_1(job->app,DK3_LL_ERROR,job->msg,33);
+ }
+ } else { $? "! no text after @"
+ /* ERROR: No a name text */
+ dk3app_log_1(job->app,DK3_LL_ERROR,job->msg,34);
+ }
+ }
+ } else { $? "! sscanf3"
+ /* ERROR: No header level */
+ dk3app_log_1(job->app,DK3_LL_ERROR,job->msg,35);
+ }
+ } else { $? "! no header text"
+ /* ERROR: No header text */
+ dk3app_log_1(job->app,DK3_LL_ERROR,job->msg,32);
+ }
+ } else { $? "! no text after dot"
+ /* ERROR: Syntax, no text after dot */
+ dk3app_log_1(job->app,DK3_LL_ERROR,job->msg,36);
+ }
+ }
+ }
+ } else { $? "! dk3sto_add"
+ /* 2016-10-24: Destroy line structure when failed to save.
+ */
+ hbcont_line_delete(lptr);
+ }
+ } else { $? "! lptr"
+ }
+ } else { $? ". already handled"
+ back = 1;
+ }
+ $? "- hbcont_line_handler %d", back
+ return back;
+}
+
+
+
+/** Read contents into storage.
+ @param job Job structure.
+ @param proc Line processing structure.
+ @return 1 on success, 0 on errors.
+*/
+static
+int
+hbcont_read(hb_job_t *job, hb_contents_line_processor_t *proc)
+{
+ int res; /* Result from file processing */
+ int inenc; /* Input encoding */
+ int back = 0;
+ $? "+ hbcont_read"
+ inenc = dk3app_get_input_file_encoding(job->app);
+ if(0 <= job->iecmd) { inenc = job->iecmd; }
+ if(0 <= (job->currentnode)->inenc) { inenc = (job->currentnode)->inenc; }
+ if((job->currentnode)->filename) {
+ res = dk3stream_process_filename_lines_app(
+ (void *)proc, hbcont_line_handler, (job->currentnode)->filename,
+ job->ilfile, job->bs,
+ dk3app_get_encoding(job->app),
+ inenc,
+ job->app
+ );
+ if(1 == res) { back = 1; } $? "- hbcont_read %d", back
+ } else {
+ if(0UL == (job->currentnode)->objno) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Write HTML page title.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbcont_write_title(hb_job_t *job)
+{
+ int back = 0;
+ $? "+ hbcont_write_title"
+ fputs(hbcont_c8_kw[2], job->of);
+ if((job->currentnode)->title) {
+ if (((job->options) & HB_JOB_OPT_NUM_IN_PAGE_HEADER)) {
+ if (!((job->options) & HB_JOB_OPT_CHM)) {
+ if((job->currentnode)->depth < job->headlevels) {
+ if(hbtool_write_header_number(job, job->currentnode)) {
+ hbhtml_output_for_text(job, (job->kwnl[35]));
+ }
+ }
+ }
+ }
+ back = hbhtml_output_for_text(job, (job->currentnode)->title);
+ }
+ fputs(hbcont_c8_kw[3], job->of);
+ $? "- hbcont_write_title %d", back
+ return back;
+}
+
+
+
+/** Write position of current node.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbcont_write_position(hb_job_t *job)
+{
+ hb_node_t *nptr; /* Current node to handle. */
+ int i;
+ int rs; /* td width */
+ int curl = 0; /* Current level */
+ int maxl = 0; /* Maximum level */
+ int back = 1;
+ $? "+ hbcont_write_position"
+ nptr = job->rootnode;
+ while(nptr) {
+ if((nptr->parent) && (nptr->curchild)) {
+ maxl++;
+ }
+ nptr = nptr->curchild;
+ }
+#if TRACE_DEBUG
+ /* DEBUG */ fprintf(job->of , "<!-- maxl=%d -->\n", maxl);
+#endif
+ if(0 < maxl) {
+ fputs(hbcont_c8_kw[49], job->of);
+ fputs(hbcont_c8_kw[4], job->of);
+ if(!hbhtml_output_for_text(job, (job->msg)[54])) { back = 1; }
+ fputs(hbcont_c8_kw[46], job->of);
+ fputs(hbcont_c8_kw[0], job->of);
+ nptr = job->rootnode;
+ while(nptr) {
+ dk3app_set_source_line(job->app, nptr->lineno);
+ if((nptr->parent) && (nptr->curchild)) {
+#if TRACE_DEBUG
+ /* DEBUG */ fprintf(job->of, "<!-- curl=%d maxl=%d -->\n", curl, maxl);
+#endif
+ fputs(hbcont_c8_kw[6], job->of);
+ if(0 < curl) {
+ for(i = 0; i < (curl - 1); i++) {
+ fputs(hbcont_c8_kw[8], job->of);
+ fputs(hbcont_c8_kw[9], job->of);
+ }
+ fputs(hbcont_c8_kw[8], job->of);
+ fputs(hbcont_c8_kw[10], job->of);
+ fputs(hbcont_c8_kw[9], job->of);
+ }
+ rs = maxl - curl;
+ fprintf(job->of, hbcont_c8_kw[11], rs);
+ if(nptr->title) {
+#if (!(VERSION_BEFORE_20140412))
+ /* 2014-04-12
+ Also write header number in position.
+ */
+ if ((job->options) & HB_JOB_OPT_NUM_IN_POS) {
+ if (hbtool_write_header_number(job, nptr)) {
+ if (!hbhtml_output_for_text(job, dkT(" "))) {
+ back = 0;
+ }
+ }
+ }
+#endif
+ if(!hbhtml_output_for_text(job, nptr->title)) {
+ back = 0;
+ }
+ }
+ fputs(hbcont_c8_kw[9], job->of);
+ fputs(hbcont_c8_kw[7], job->of);
+ curl++;
+ }
+ nptr = nptr->curchild;
+ }
+ fputs(hbcont_c8_kw[5], job->of);
+ fputs(hbcont_c8_kw[30], job->of);
+ fputs(hbcont_c8_kw[0], job->of);
+ } $? "- hbcont_write_position %d", back
+ return back;
+}
+
+
+
+/** Write anchor name for a header line.
+ @param job Job structure.
+ @param lptr Line to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbcont_write_anchor_name_for_header(hb_job_t *job, hb_line_t *lptr)
+{
+ char buffer[64]; /* Buffer to convert number to text */
+ int back = 1;
+ $? "+ hbcont_write_anchor_name_for_header"
+ if(lptr->aname) {
+ if(!hbhtml_url_output_for_text(job, lptr->aname)) {
+ back = 0;
+ }
+ } else {
+#if DK3_SIZEOF_LONG > 4
+ sprintf(buffer, "%016lx", lptr->header);
+#else
+ sprintf(buffer, "%08lx", lptr->header);
+#endif
+ fputs(hbcont_c8_kw[16], job->of);
+ fputs(buffer, job->of);
+ } $? "- hbcont_write_anchor_name_for_header %d", back
+ return back;
+}
+
+
+
+/** Process the content lines saved before.
+ @param job Job structure.
+ @param proc Line processing structure.
+ @param p Previous node.
+ @param n Next node.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbcont_write_contents(
+ hb_job_t *job,
+ hb_contents_line_processor_t *proc,
+ hb_node_t *p,
+ hb_node_t *n
+)
+{
+ hb_file_processor_t myproc;
+ hb_line_t *lptr; /* Current line to process */
+ hb_line_t *tocptr; /* Current TOC line to process */
+ hb_node_t *nptr; /* Current node to process */
+ dk3_sto_it_t *i_toc; /* Line traversal for TOC */
+ unsigned cs = 0; /* Column space */
+ unsigned sp = 0; /* Spaces before data field */
+ unsigned hl = 0; /* Header level */
+ unsigned i = 0; /* Create spaces */
+ int tocpr = 0; /* Flag: Page TOC already printed */
+ int back = 0;
+ $? "+ hbcont_write_contents \"%!ds\"", TR_STR((job->currentnode)->title)
+ if((job->options) & HB_JOB_OPT_CHM) { tocpr = 1; }
+ nptr = job->currentnode;
+ i_toc = dk3sto_it_open(nptr->s_lines);
+ if(i_toc) {
+ dk3sto_it_reset(nptr->i_lines);
+ dk3sto_it_reset(i_toc);
+ back = 1;
+ do {
+ lptr = (hb_line_t *)dk3sto_it_next(nptr->i_lines);
+ if(lptr) {
+ dk3app_set_source_line(job->app, lptr->lineno);
+ if(lptr->lt) {
+ /* Header line */
+ if((0 == tocpr) && ((nptr->options) & HB_NODE_OPT_PAGE_TOC)) {
+ tocpr = 1; $? ". print page TOC"
+ fputs(hbcont_c8_kw[17], job->of);
+ if(!hbhtml_output_for_text(job, (job->msg)[55])) { back = 0; }
+ fputs(hbcont_c8_kw[46], job->of);
+ fputs(hbcont_c8_kw[0], job->of);
+ do {
+ tocptr = (hb_line_t *)dk3sto_it_next(i_toc);
+ if(tocptr) {
+ if(tocptr->lt) {
+ dk3app_set_source_line(job->app, tocptr->lineno);
+ sp = 0;
+#if 0
+ if(tocptr->headlevel < proc->maxheader) {
+ sp = proc->maxheader - tocptr->headlevel;
+ }
+#endif
+ if(tocptr->headlevel > 0) {
+ sp = tocptr->headlevel - 1;
+ }
+ cs = proc->maxheader - sp;
+ fputs(hbcont_c8_kw[19], job->of);
+ for(i = 0; i < sp; i++) {
+ fputs(hbcont_c8_kw[21], job->of);
+ }
+ fprintf(job->of, hbcont_c8_kw[22], cs);
+ fputs(hbcont_c8_kw[24], job->of);
+ if(!hbcont_write_anchor_name_for_header(job, tocptr)) {
+ back = 0;
+ }
+ fputs(hbcont_c8_kw[25], job->of);
+ if(!hbhtml_output_for_text(job, tocptr->realtext)) {
+ back = 0;
+ }
+ fputs(hbcont_c8_kw[26], job->of);
+ if(!hbhtml_output_for_text(job, tocptr->realtext)) {
+ back = 0;
+ }
+ fputs(hbcont_c8_kw[27], job->of);
+ fputs(hbcont_c8_kw[23], job->of);
+ fputs(hbcont_c8_kw[20], job->of);
+ dk3app_set_source_line(job->app, lptr->lineno);
+ }
+ }
+ } while(tocptr);
+ fputs(hbcont_c8_kw[18], job->of);
+ }
+ hl = 1 + lptr->headlevel;
+ if(6 < hl) {
+ hl = 6;
+ /* Warning: Header level corrected to 6! */
+ dk3app_log_1(job->app,DK3_LL_ERROR,job->msg,37);
+ }
+ fprintf(job->of, hbcont_c8_kw[14], hl);
+ if(!hbcont_write_anchor_name_for_header(job, lptr)) {
+ back = 0; $? "! ERROR"
+ }
+ fprintf(job->of, hbcont_c8_kw[15], hl);
+ fprintf(job->of, hbcont_c8_kw[12], hl);
+ if(!hbhtml_output_for_text(job, lptr->realtext)) {
+ back = 0; $? "! ERROR"
+ }
+ fprintf(job->of, hbcont_c8_kw[13], hl);
+ } else {
+ myproc.job = job;
+ myproc.in_template = 0;
+ myproc.stm = 0;
+ myproc.p = p;
+ myproc.n = n; $? ". text = \"%!ds\"", lptr->text
+ if(1 != hbhtml_line_handler((void *)(&myproc), lptr->text)) {
+ back = 0; $? "! processing failed"
+ }
+ }
+ }
+ } while(lptr);
+ dk3sto_it_close(i_toc);
+ } $? "- hbcont_write_contents %d", back
+ return back;
+}
+
+
+
+/** Write list of external links for current node.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbcont_write_link_list(hb_job_t *job)
+{
+ hb_link_t *linkptr; /* Current link to process */
+ hb_node_t *nptr; /* Current node to process */
+ int back = 1;
+ $? "+ hbcont_write_link_list \"%!ds\"", TR_STR((job->currentnode)->title)
+ nptr = job->currentnode;
+ if(nptr->nextlink) {
+ dk3sto_it_reset(nptr->i_lbylno);
+ fputs(hbcont_c8_kw[28], job->of);
+ if(!hbhtml_output_for_text(job, (job->msg)[23])) { back = 0; }
+ fputs(hbcont_c8_kw[29], job->of);
+ fputs(hbcont_c8_kw[31], job->of);
+ if(!hbhtml_output_for_text(job, (job->msg)[56])) { back = 0; }
+ fputs(hbcont_c8_kw[46], job->of);
+ fputs(hbcont_c8_kw[0], job->of);
+ while(NULL != (linkptr = (hb_link_t *)dk3sto_it_next(nptr->i_lbylno))) {
+ fputs(hbcont_c8_kw[33], job->of);
+ /* Number */
+ fputs(hbcont_c8_kw[35], job->of);
+ fprintf(job->of, hbcont_c8_kw[37], (1UL + linkptr->lno));
+ fputs(hbcont_c8_kw[36], job->of);
+ /* URL */
+ fputs(hbcont_c8_kw[38], job->of);
+ if(!hbhtml_url_output_for_text(job, linkptr->url)) { back = 1; }
+ fputs(hbcont_c8_kw[36], job->of);
+ fputs(hbcont_c8_kw[34], job->of);
+ }
+ fputs(hbcont_c8_kw[32], job->of);
+ fputs(hbcont_c8_kw[30], job->of);
+ } $? "- hbcont_write_link_list %d", back
+ return back;
+}
+
+
+
+/** Create project table of contents.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbcont_create_toc(hb_job_t *job)
+{
+ dkChar ofn[DK3_MAX_PATH]; /* Output file name */
+ hb_node_t *nptr; /* Current node to process */
+ hb_node_t *dest; /* Print node for cur node */
+ dkChar const *oldsourcefile; /* Old source file name saved */
+ unsigned long oldsourceline; /* Old source file line saved */
+ int res; /* Result from file name cr */
+ int i;
+ int back = 1;
+ $? "+ hbcont_create_toc"
+ oldsourcefile = dk3app_get_source_file(job->app);
+ oldsourceline = dk3app_get_source_line(job->app);
+ dk3app_set_source_file(job->app, job->infilename);
+ dk3app_set_source_line(job->app, 0UL);
+ fputs(hbcont_c8_kw[47], job->of);
+ if(!hbhtml_output_for_text(job, (job->msg)[45])) { back = 0; }
+ fputs(hbcont_c8_kw[48], job->of);
+ fputs(hbcont_c8_kw[39], job->of);
+ if(!hbhtml_output_for_text(job, (job->msg)[57])) { back = 0; }
+ fputs(hbcont_c8_kw[46], job->of);
+ fputs(hbcont_c8_kw[0], job->of);
+ nptr = job->rootnode;
+ while(nptr) {
+ $? ". Handling node %lu \"%!ds\"", nptr->objno, nptr->title
+ dk3app_set_source_line(job->app, nptr->lineno);
+ switch(nptr->tocstate) {
+ case HB_TOC_STATE_INIT: { $? ". initialize node %lu", nptr->objno
+ if(nptr->parent) {
+ /* Write TOC entry */
+ dest = NULL;
+ if(nptr->filename) {
+ dest = nptr;
+ } else {
+ if(nptr->jumpnode) {
+ dest = nptr->jumpnode;
+ }
+ }
+ if(dest) { $? ". dest = %lu \"%!ds\"", dest->objno, dest->title
+ res =
+ hbhtml_create_output_filename(ofn,DK3_SIZEOF(ofn,dkChar),job,dest);
+ if(res) {
+ fputs(hbcont_c8_kw[41], job->of);
+ for(i = 1; i < nptr->depth; i++) {
+ fputs(hbcont_c8_kw[43], job->of);
+ }
+ fprintf(
+ job->of, hbcont_c8_kw[44], ((job->maxdepth) - (nptr->depth) + 1)
+ );
+ fputs(hbcont_c8_kw[45], job->of);
+ if(!hbhtml_url_output_for_text(job, ofn)) { back = 0; }
+ fputs(hbcont_c8_kw[25], job->of);
+ if(hbtool_write_header_number(job, nptr)) {
+ fputs(hbcont_c8_kw[1], job->of);
+ }
+ if(!hbhtml_output_for_text(job, nptr->title)) { back = 0; }
+ fputs(hbcont_c8_kw[46], job->of);
+ if(hbtool_write_header_number(job, nptr)) {
+ fputs(hbcont_c8_kw[1], job->of);
+ }
+ if(!hbhtml_output_for_text(job, nptr->title)) { back = 0; }
+ fputs(hbcont_c8_kw[27], job->of);
+ fputs(hbcont_c8_kw[9], job->of);
+ fputs(hbcont_c8_kw[42], job->of);
+ } else {
+ /* ERROR: Failed to create output file name */
+ back = 0;
+ }
+ } else { $? "! no destination node"
+ /* ERROR: No destination found */
+ back = 0;
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 51);
+ }
+ }
+ dk3sto_it_reset(nptr->i_subnodes);
+ nptr->tocstate = HB_TOC_STATE_IN_PROGRESS;
+ } break;
+ case HB_TOC_STATE_IN_PROGRESS: { $? ". continue node %lu", nptr->objno
+ nptr->curchild = dk3sto_it_next(nptr->i_subnodes);
+ if(nptr->curchild) {
+ nptr = nptr->curchild;
+ } else {
+ nptr->tocstate = HB_TOC_STATE_FINISHED;
+ }
+ } break;
+ case HB_TOC_STATE_FINISHED: { $? ". finish node %lu", nptr->objno
+ nptr = nptr->parent;
+ } break;
+ }
+ }
+ fputs(hbcont_c8_kw[40], job->of);
+ dk3app_set_source_file(job->app, oldsourcefile);
+ dk3app_set_source_line(job->app, oldsourceline);
+ $? "- hbcont_create_toc %d", back
+ return back;
+}
+
+
+
+/** Create keyword index.
+ @param job Job structure
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbcont_create_keyword_index(hb_job_t *job)
+{
+ hb_index_entry_t *pp = NULL; /* Previous pointer */
+ hb_index_entry_t *cp = NULL; /* Current pointer */
+#if VERSION_BEFORE_20150821
+ dk3_c32_t pstc = 0UL; /* Previous start character */
+ dk3_c32_t cstc = 0UL; /* Start character */
+#endif
+ int nkw = 0; /* Flag: Open new keyword */
+ int hh2 = 0; /* Flag: Have division and h2 */
+ int back = 1;
+ $? "+ hbcont_create_keyword_index"
+ dk3sto_it_reset(job->i_index);
+ while(NULL != (cp = (hb_index_entry_t *)dk3sto_it_next(job->i_index))) {
+ $? ". have current entry \"%!ds\"", cp->tx
+ if(!(hh2)) { $? ". no header yet, write header"
+ hh2 = 1;
+ fputs(hbcont_c8_kw[50], job->of);
+ fputs(hbcont_c8_kw[51], job->of);
+ if(!hbhtml_output_for_text(job, (job->msg)[46])) { back = 0; }
+ fputs(hbcont_c8_kw[29], job->of);
+ fputs(hbcont_c8_kw[52], job->of);
+ }
+ /* Process entry.
+ */
+ nkw = 0;
+ if(pp) { $? ". have previous entry"
+ if(dk3str_cmp(pp->tx, cp->tx)) { $? ". entries differ"
+ nkw = 1;
+ fputs(hbcont_c8_kw[57], job->of);
+ }
+ } else {
+ nkw = 1;
+ }
+ if(nkw) {
+ fputs(hbcont_c8_kw[54], job->of);
+ if(!hbhtml_output_for_text(job, cp->tx)) { back = 0; }
+ fputs(hbcont_c8_kw[55], job->of);
+ fputs(hbcont_c8_kw[56], job->of);
+ }
+ fputs(hbcont_c8_kw[58], job->of);
+ fputs(hbcont_c8_kw[60], job->of);
+ if(!hbhtml_url_output_for_text(job, cp->fn)) { back = 0; }
+ fputs(hbcont_c8_kw[61], job->of);
+ if(!hb_index_write_anchor(job, cp)) { back = 0; }
+#if (!(VERSION_BEFORE_20140412))
+ fputs(hbcont_c8_kw[25], job->of);
+ (void)hbtool_write_all_titles(job, cp->no, 1);
+#endif
+ fputs(hbcont_c8_kw[46], job->of);
+ if(cp->no) {
+ if((cp->no)->title) {
+#if (!(VERSION_BEFORE_20140412))
+ if ((job->options) & HB_JOB_OPT_NUM_IN_IDX) {
+ if (hbtool_write_header_number(job, cp->no)) {
+ hbhtml_output_for_text(job, dkT(" "));
+ }
+ }
+#endif
+ if(!hbhtml_output_for_text(job, (cp->no)->title)) { back = 0; }
+ } else back = 0;
+ } else { back = 0; }
+ fputs(hbcont_c8_kw[27], job->of);
+ fputs(hbcont_c8_kw[59], job->of);
+ pp = cp;
+#if VERSION_BEFORE_20150821
+ pstc = cstc;
+#endif
+ }
+ if(hh2) {
+ fputs(hbcont_c8_kw[57], job->of);
+ fputs(hbcont_c8_kw[53], job->of);
+ fputs(hbcont_c8_kw[30], job->of);
+ fputs(hbcont_c8_kw[0], job->of);
+ } $? "- hbcont_create_keyword_index %d", back
+ return back;
+}
+
+
+
+int
+hbcont_process(hb_job_t *job, hb_node_t *p, hb_node_t *n)
+{
+ hb_contents_line_processor_t proc;
+ dkChar const *oldsourcefile;
+ unsigned long oldsourceline;
+ int back = 0;
+ $? "+ hbcont_process %lu", (job->currentnode)->objno
+ oldsourcefile = dk3app_get_source_file(job->app);
+ oldsourceline = dk3app_get_source_line(job->app);
+ proc.job = job;
+ proc.nptr = job->currentnode;
+ proc.lineno = 0UL;
+ proc.nheader = 0UL;
+ proc.maxheader = 0;
+
+ dk3app_set_source_file(job->app, job->infilename);
+ dk3app_set_source_line(job->app, (job->currentnode)->lineno);
+ if(hbcont_prepare(job)) {
+ dk3app_set_source_file(job->app, (job->currentnode)->filename);
+ dk3app_set_source_line(job->app, 0UL);
+ if(hbcont_read(job, &proc)) {
+ back = 1;
+
+ /* For the root node we do not write a position.
+ */
+ if((0UL != (job->currentnode)->objno) && ((job->currentnode)->filename)) {
+ if(!((job->options) & HB_JOB_OPT_CHM)) {
+ if(((job->currentnode)->options) & HB_NODE_OPT_HEADER_CHAIN) {
+ dk3app_set_source_file(job->app, job->infilename);
+ if(!hbcont_write_position(job)) { back = 0; }
+ }
+ }
+ }
+
+ dk3app_set_source_file(job->app, job->infilename);
+ dk3app_set_source_line(job->app, (job->currentnode)->lineno);
+ if(!hbcont_write_title(job)) { back = 0; }
+
+ /* We can write contents only if an input file is specified.
+ */
+ if((job->currentnode)->filename) {
+ dk3app_set_source_file(job->app, (job->currentnode)->filename);
+ dk3app_set_source_line(job->app, 0UL);
+ if(!hbcont_write_contents(job, &proc, p, n)) { back = 0; }
+
+ dk3app_set_source_file(job->app, (job->currentnode)->filename);
+ dk3app_set_source_line(job->app, 0UL);
+ if((job->currentnode)->nextlink) {
+ if(!hbcont_write_link_list(job)) { back = 0; }
+ }
+ }
+
+ if(0UL == (job->currentnode)->objno) { $? ". TOC node"
+ if(!((job->options) & HB_JOB_OPT_CHM)) {
+ if((job->options) & HB_JOB_OPT_CREATE_TOC) { $? ". create TOC"
+ if(!hbcont_create_toc(job)) { back = 0; }
+ }
+ if((job->options) & HB_JOB_OPT_CREATE_INDEX) { $? ". create index"
+ /* Eventually create index */
+ if(!hbcont_create_keyword_index(job)) { back = 0; }
+ }
+ }
+ }
+ }
+ dk3app_set_source_file(job->app, job->infilename);
+ dk3app_set_source_line(job->app, (job->currentnode)->lineno);
+ }
+ hbcont_cleanup(job);
+ dk3app_set_source_file(job->app, oldsourcefile);
+ dk3app_set_source_line(job->app, oldsourceline);
+ $? "- hbcont_process %d", back
+ return back;
+}
+
+
diff --git a/support/dktools/hbcont.h b/support/dktools/hbcont.h
new file mode 100644
index 0000000000..9687703616
--- /dev/null
+++ b/support/dktools/hbcont.h
@@ -0,0 +1,94 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: hbcont.ctr
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file hbcont.h Header file for the hbcont module.
+*/
+
+#ifndef HBCONT_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define HBCONT_H_INCLUDED 1
+
+
+#line 9 "hbcont.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Process the contents.
+ @param job Job structure, current node is set.
+ @param p Previous node (if any).
+ @param n Next node (if any).
+ @return 1 on success, 0 on error.
+*/
+int
+hbcont_process(hb_job_t *job, hb_node_t *p, hb_node_t *n);
+
+/** Create contents line structure.
+ @param il Input line to save.
+ @param lineno Line number of input line.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new line structure on success, NULL on error.
+*/
+hb_line_t *
+hbcont_line_new(dkChar const *il, unsigned long lineno, dk3_app_t *app);
+
+/** Delete one contents line.
+ @param lp Contents line to delete.
+*/
+void
+hbcont_line_delete(hb_line_t *lp);
+
+/** Check whether input line is started by dot and one meta data keyword.
+ @param il Input line to check.
+ @return Non-negative index on success, -1 if no meta data.
+*/
+int
+hbcont_metadata_index(const dkChar *il);
+
+/** Find length of metadata name.
+ @param idx Index of metadata name.
+ @return Positive length on success, 0 on error.
+*/
+size_t
+hbcont_metadata_length(size_t idx);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/hbhtml.c b/support/dktools/hbhtml.c
new file mode 100644
index 0000000000..ab10885cda
--- /dev/null
+++ b/support/dktools/hbhtml.c
@@ -0,0 +1,6882 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: hbhtml.ctr
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file hbhtml.c The hbhtml module.
+*/
+
+/** @defgroup dkct_state_machine_hbhtml_stm1 The hbhtml_stm1 state machine. */
+/**@{*/
+
+#ifndef STM1_ST_BS
+/** State: Backslash found */
+#line 92 "hbhtml.ctr"
+#define STM1_ST_BS 0
+#else
+#line 92 "hbhtml.ctr"
+#error "Redefinition of STM1_ST_BS"
+#endif
+
+#ifndef STM1_ST_ERROR
+/** State: Error occured */
+#line 91 "hbhtml.ctr"
+#define STM1_ST_ERROR 1
+#else
+#line 91 "hbhtml.ctr"
+#error "Redefinition of STM1_ST_ERROR"
+#endif
+
+#ifndef STM1_ST_PERCENT
+/** State: One percent sign found */
+#line 93 "hbhtml.ctr"
+#define STM1_ST_PERCENT 2
+#else
+#line 93 "hbhtml.ctr"
+#error "Redefinition of STM1_ST_PERCENT"
+#endif
+
+#ifndef STM1_ST_SPECIAL
+/** State: Recording a special */
+#line 94 "hbhtml.ctr"
+#define STM1_ST_SPECIAL 3
+#else
+#line 94 "hbhtml.ctr"
+#error "Redefinition of STM1_ST_SPECIAL"
+#endif
+
+#ifndef STM1_ST_SPEC_BS
+/** State: Backslash found in special */
+#line 95 "hbhtml.ctr"
+#define STM1_ST_SPEC_BS 4
+#else
+#line 95 "hbhtml.ctr"
+#error "Redefinition of STM1_ST_SPEC_BS"
+#endif
+
+#ifndef STM1_ST_SPEC_PC
+/** State: Percent found in special */
+#line 96 "hbhtml.ctr"
+#define STM1_ST_SPEC_PC 5
+#else
+#line 96 "hbhtml.ctr"
+#error "Redefinition of STM1_ST_SPEC_PC"
+#endif
+
+#ifndef STM1_ST_START
+/** State: Start state */
+#line 90 "hbhtml.ctr"
+#define STM1_ST_START 6
+#else
+#line 90 "hbhtml.ctr"
+#error "Redefinition of STM1_ST_START"
+#endif
+
+#ifndef STM1_I_ANY
+/** State machine input: Any character */
+#line 99 "hbhtml.ctr"
+#define STM1_I_ANY 0
+#else
+#line 99 "hbhtml.ctr"
+#error "Redefinition of STM1_I_ANY"
+#endif
+
+#ifndef STM1_I_BS
+/** State machine input: Backslash */
+#line 100 "hbhtml.ctr"
+#define STM1_I_BS 1
+#else
+#line 100 "hbhtml.ctr"
+#error "Redefinition of STM1_I_BS"
+#endif
+
+#ifndef STM1_I_PERCENT
+/** State machine input: Percent sign */
+#line 101 "hbhtml.ctr"
+#define STM1_I_PERCENT 2
+#else
+#line 101 "hbhtml.ctr"
+#error "Redefinition of STM1_I_PERCENT"
+#endif
+
+#ifndef STM1_O_BS_SHIPOUT
+/** State machine output: Shipout character after backslash */
+#line 107 "hbhtml.ctr"
+#define STM1_O_BS_SHIPOUT 0
+#else
+#line 107 "hbhtml.ctr"
+#error "Redefinition of STM1_O_BS_SHIPOUT"
+#endif
+
+#ifndef STM1_O_ERROR
+/** State machine output: Error, do nothing */
+#line 104 "hbhtml.ctr"
+#define STM1_O_ERROR 1
+#else
+#line 104 "hbhtml.ctr"
+#error "Redefinition of STM1_O_ERROR"
+#endif
+
+#ifndef STM1_O_EXECUTE
+/** State machine output: Execute special */
+#line 115 "hbhtml.ctr"
+#define STM1_O_EXECUTE 2
+#else
+#line 115 "hbhtml.ctr"
+#error "Redefinition of STM1_O_EXECUTE"
+#endif
+
+#ifndef STM1_O_NOTHING
+/** State machine output: Do nothing */
+#line 105 "hbhtml.ctr"
+#define STM1_O_NOTHING 3
+#else
+#line 105 "hbhtml.ctr"
+#error "Redefinition of STM1_O_NOTHING"
+#endif
+
+#ifndef STM1_O_PERCENT
+/** State machine output: Shipout just percent sign */
+#line 109 "hbhtml.ctr"
+#define STM1_O_PERCENT 4
+#else
+#line 109 "hbhtml.ctr"
+#error "Redefinition of STM1_O_PERCENT"
+#endif
+
+#ifndef STM1_O_PERCENT_SHIPOUT
+/** State machine output: Shipout percent sign and current character */
+#line 108 "hbhtml.ctr"
+#define STM1_O_PERCENT_SHIPOUT 5
+#else
+#line 108 "hbhtml.ctr"
+#error "Redefinition of STM1_O_PERCENT_SHIPOUT"
+#endif
+
+#ifndef STM1_O_SHIPOUT
+/** State machine output: Add character to shipout buffer */
+#line 106 "hbhtml.ctr"
+#define STM1_O_SHIPOUT 6
+#else
+#line 106 "hbhtml.ctr"
+#error "Redefinition of STM1_O_SHIPOUT"
+#endif
+
+#ifndef STM1_O_SPECIAL
+/** State machine output: Add current character to special */
+#line 111 "hbhtml.ctr"
+#define STM1_O_SPECIAL 7
+#else
+#line 111 "hbhtml.ctr"
+#error "Redefinition of STM1_O_SPECIAL"
+#endif
+
+#ifndef STM1_O_SPEC_BS
+/** State machine output: Add char after backslash to special */
+#line 112 "hbhtml.ctr"
+#define STM1_O_SPEC_BS 8
+#else
+#line 112 "hbhtml.ctr"
+#error "Redefinition of STM1_O_SPEC_BS"
+#endif
+
+#ifndef STM1_O_SPEC_PC
+/** State machine output: Add percent sign to special */
+#line 114 "hbhtml.ctr"
+#define STM1_O_SPEC_PC 9
+#else
+#line 114 "hbhtml.ctr"
+#error "Redefinition of STM1_O_SPEC_PC"
+#endif
+
+#ifndef STM1_O_SPEC_PC_ADD
+/** State machine output: Add percent and current char to special */
+#line 113 "hbhtml.ctr"
+#define STM1_O_SPEC_PC_ADD 10
+#else
+#line 113 "hbhtml.ctr"
+#error "Redefinition of STM1_O_SPEC_PC_ADD"
+#endif
+
+#ifndef STM1_O_SWITCH
+/** State machine output: Flush shipout and switch to saving special */
+#line 110 "hbhtml.ctr"
+#define STM1_O_SWITCH 11
+#else
+#line 110 "hbhtml.ctr"
+#error "Redefinition of STM1_O_SWITCH"
+#endif
+
+/**@}*/
+
+/** Reset hbhtml_stm1 state machine.
+ @param st Pointer to state variable.
+*/
+static
+void
+hbhtml_stm1_reset(int *st)
+{
+ if(st) { *st = STM1_ST_START; }
+}
+
+/** State machine hbhtml_stm1 step.
+ @param st Pointer to state variable.
+ @param in Input.
+ @return Transition output.
+*/
+static
+int
+hbhtml_stm1_step(int *st, int in)
+{
+ int back = STM1_O_ERROR;
+ if(st) {
+ int os;
+ int nf = 1;
+ int ns = STM1_ST_ERROR;
+ os = *st;
+ switch(os) {
+ case STM1_ST_PERCENT: {
+ switch(in) {
+ case STM1_I_BS: {
+ ns = STM1_ST_BS; back = STM1_O_PERCENT; nf = 0;
+ } break;
+ case STM1_I_PERCENT: {
+ ns = STM1_ST_SPECIAL; back = STM1_O_SWITCH; nf = 0;
+ } break;
+ }
+ } break;
+ case STM1_ST_SPECIAL: {
+ switch(in) {
+ case STM1_I_BS: {
+ ns = STM1_ST_SPEC_BS; back = STM1_O_NOTHING; nf = 0;
+ } break;
+ case STM1_I_PERCENT: {
+ ns = STM1_ST_SPEC_PC; back = STM1_O_NOTHING; nf = 0;
+ } break;
+ }
+ } break;
+ case STM1_ST_SPEC_PC: {
+ switch(in) {
+ case STM1_I_BS: {
+ ns = STM1_ST_SPEC_BS; back = STM1_O_SPEC_PC; nf = 0;
+ } break;
+ case STM1_I_PERCENT: {
+ ns = STM1_ST_START; back = STM1_O_EXECUTE; nf = 0;
+ } break;
+ }
+ } break;
+ case STM1_ST_START: {
+ switch(in) {
+ case STM1_I_BS: {
+ ns = STM1_ST_BS; back = STM1_O_NOTHING; nf = 0;
+ } break;
+ case STM1_I_PERCENT: {
+ ns = STM1_ST_PERCENT; back = STM1_O_NOTHING; nf = 0;
+ } break;
+ }
+ } break;
+ }
+ if(nf) {
+ if(os == STM1_ST_START) {
+ ns = STM1_ST_START; back = STM1_O_SHIPOUT;
+ } else {
+ if(os == STM1_ST_BS) {
+ ns = STM1_ST_START; back = STM1_O_BS_SHIPOUT;
+ } else {
+ if(os == STM1_ST_PERCENT) {
+ ns = STM1_ST_START; back = STM1_O_PERCENT_SHIPOUT;
+ } else {
+ if(os == STM1_ST_SPECIAL) {
+ ns = STM1_ST_SPECIAL; back = STM1_O_SPECIAL;
+ } else {
+ if(os == STM1_ST_SPEC_BS) {
+ ns = STM1_ST_SPECIAL; back = STM1_O_SPEC_BS;
+ } else {
+ if(os == STM1_ST_SPEC_PC) {
+ ns = STM1_ST_SPECIAL; back = STM1_O_SPEC_PC_ADD;
+ } else {
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ *st = ns;
+ } else {
+ }
+ return back;
+}
+
+/** @defgroup dkct_state_machine_hbhtml_stm3 The hbhtml_stm3 state machine. */
+/**@{*/
+
+#ifndef STM3_ST_COLON
+/** State: Colon found */
+#line 147 "hbhtml.ctr"
+#define STM3_ST_COLON 0
+#else
+#line 147 "hbhtml.ctr"
+#error "Redefinition of STM3_ST_COLON"
+#endif
+
+#ifndef STM3_ST_COLSL
+/** State: Colon and slash */
+#line 148 "hbhtml.ctr"
+#define STM3_ST_COLSL 1
+#else
+#line 148 "hbhtml.ctr"
+#error "Redefinition of STM3_ST_COLSL"
+#endif
+
+#ifndef STM3_ST_ERROR
+/** State: Not a protocol at start of text */
+#line 150 "hbhtml.ctr"
+#define STM3_ST_ERROR 2
+#else
+#line 150 "hbhtml.ctr"
+#error "Redefinition of STM3_ST_ERROR"
+#endif
+
+#ifndef STM3_ST_NAME
+/** State: ASCII characters (for protocol name) found */
+#line 146 "hbhtml.ctr"
+#define STM3_ST_NAME 3
+#else
+#line 146 "hbhtml.ctr"
+#error "Redefinition of STM3_ST_NAME"
+#endif
+
+#ifndef STM3_ST_START
+/** State: No character processed yet */
+#line 145 "hbhtml.ctr"
+#define STM3_ST_START 4
+#else
+#line 145 "hbhtml.ctr"
+#error "Redefinition of STM3_ST_START"
+#endif
+
+#ifndef STM3_ST_SUCCESS
+/** State: Colon and two slashes found */
+#line 149 "hbhtml.ctr"
+#define STM3_ST_SUCCESS 5
+#else
+#line 149 "hbhtml.ctr"
+#error "Redefinition of STM3_ST_SUCCESS"
+#endif
+
+#ifndef STM3_I_ANY
+/** State machine input: Anything not listed below */
+#line 152 "hbhtml.ctr"
+#define STM3_I_ANY 0
+#else
+#line 152 "hbhtml.ctr"
+#error "Redefinition of STM3_I_ANY"
+#endif
+
+#ifndef STM3_I_ASCII
+/** State machine input: a-zA-Z01-9_ */
+#line 153 "hbhtml.ctr"
+#define STM3_I_ASCII 1
+#else
+#line 153 "hbhtml.ctr"
+#error "Redefinition of STM3_I_ASCII"
+#endif
+
+#ifndef STM3_I_COLON
+/** State machine input: Colon */
+#line 154 "hbhtml.ctr"
+#define STM3_I_COLON 2
+#else
+#line 154 "hbhtml.ctr"
+#error "Redefinition of STM3_I_COLON"
+#endif
+
+#ifndef STM3_I_SLASH
+/** State machine input: Slash */
+#line 155 "hbhtml.ctr"
+#define STM3_I_SLASH 3
+#else
+#line 155 "hbhtml.ctr"
+#error "Redefinition of STM3_I_SLASH"
+#endif
+
+#ifndef STM3_O_ERROR
+/** State machine output: ERROR found */
+#line 158 "hbhtml.ctr"
+#define STM3_O_ERROR 0
+#else
+#line 158 "hbhtml.ctr"
+#error "Redefinition of STM3_O_ERROR"
+#endif
+
+#ifndef STM3_O_OK
+/** State machine output: OK so far */
+#line 157 "hbhtml.ctr"
+#define STM3_O_OK 1
+#else
+#line 157 "hbhtml.ctr"
+#error "Redefinition of STM3_O_OK"
+#endif
+
+/**@}*/
+
+/** Reset hbhtml_stm3 state machine.
+ @param st Pointer to state variable.
+*/
+static
+void
+hbhtml_stm3_reset(int *st)
+{
+ if(st) { *st = STM3_ST_START; }
+}
+
+/** State machine hbhtml_stm3 step.
+ @param st Pointer to state variable.
+ @param in Input.
+ @return Transition output.
+*/
+static
+int
+hbhtml_stm3_step(int *st, int in)
+{
+ int back = STM3_O_ERROR;
+ if(st) {
+ int os;
+ int nf = 1;
+ int ns = STM3_ST_ERROR;
+ os = *st;
+ switch(os) {
+ case STM3_ST_COLON: {
+ switch(in) {
+ case STM3_I_SLASH: {
+ ns = STM3_ST_COLSL; back = STM3_O_OK; nf = 0;
+ } break;
+ }
+ } break;
+ case STM3_ST_COLSL: {
+ switch(in) {
+ case STM3_I_SLASH: {
+ ns = STM3_ST_SUCCESS; back = STM3_O_OK; nf = 0;
+ } break;
+ }
+ } break;
+ case STM3_ST_NAME: {
+ switch(in) {
+ case STM3_I_ASCII: {
+ ns = STM3_ST_NAME; back = STM3_O_OK; nf = 0;
+ } break;
+ case STM3_I_COLON: {
+ ns = STM3_ST_COLON; back = STM3_O_OK; nf = 0;
+ } break;
+ }
+ } break;
+ case STM3_ST_START: {
+ switch(in) {
+ case STM3_I_ASCII: {
+ ns = STM3_ST_NAME; back = STM3_O_OK; nf = 0;
+ } break;
+ }
+ } break;
+ }
+ if(nf) {
+ if(os == STM3_ST_SUCCESS) {
+ ns = STM3_ST_SUCCESS; back = STM3_O_OK;
+ } else {
+ }
+ }
+ *st = ns;
+ } else {
+ }
+ return back;
+}
+
+
+#line 170 "hbhtml.ctr"
+
+
+#include "dk3all.h"
+#include "dk3strkv.h"
+#include "htmlbook.h"
+
+
+
+
+
+#line 179 "hbhtml.ctr"
+
+
+
+/** Object for line reader (special comments).
+*/
+typedef struct {
+ hb_job_t *job; /**< Job structure. */
+ hb_node_t *nodeptr; /**< Current node to process. */
+ unsigned long lineno; /**< Current line number to process. */
+} hb_spc_reader_t;
+
+
+
+/** Translation table for ASCII characters.
+*/
+static char const * const hbhtml_translation_table[] = {
+/* 0 00 */ NULL,
+/* 1 01 */ NULL,
+/* 2 02 */ NULL,
+/* 3 03 */ NULL,
+/* 4 04 */ NULL,
+/* 5 05 */ NULL,
+/* 6 06 */ NULL,
+/* 7 07 */ NULL,
+/* 8 08 */ NULL,
+/* 9 09 */ "\t",
+/* 10 0a */ NULL,
+/* 11 0b */ NULL,
+/* 12 0c */ NULL,
+/* 13 0d */ NULL,
+/* 14 0e */ NULL,
+/* 15 0f */ NULL,
+/* 16 10 */ NULL,
+/* 17 11 */ NULL,
+/* 18 12 */ NULL,
+/* 19 13 */ NULL,
+/* 20 14 */ NULL,
+/* 21 15 */ NULL,
+/* 22 16 */ NULL,
+/* 23 17 */ NULL,
+/* 24 18 */ NULL,
+/* 25 19 */ NULL,
+/* 26 1a */ NULL,
+/* 27 1b */ NULL,
+/* 28 1c */ NULL,
+/* 29 1d */ NULL,
+/* 30 1e */ NULL,
+/* 31 1f */ NULL,
+/* 32 20 */ " ",
+/* 33 21 */ "!",
+/* 34 22 */ "&quot;",
+/* 35 23 */ "#",
+/* 36 24 */ "$",
+/* 37 25 */ "%",
+/* 38 26 */ "&amp;",
+/* 39 27 */ "'",
+/* 40 28 */ "(",
+/* 41 29 */ ")",
+/* 42 2a */ "*",
+/* 43 2b */ "+",
+/* 44 2c */ ",",
+/* 45 2d */ "-",
+/* 46 2e */ ".",
+/* 47 2f */ "/",
+/* 48 30 */ "0",
+/* 49 31 */ "1",
+/* 50 32 */ "2",
+/* 51 33 */ "3",
+/* 52 34 */ "4",
+/* 53 35 */ "5",
+/* 54 36 */ "6",
+/* 55 37 */ "7",
+/* 56 38 */ "8",
+/* 57 39 */ "9",
+/* 58 3a */ ":",
+/* 59 3b */ ";",
+/* 60 3c */ "&lt;",
+/* 61 3d */ "=",
+/* 62 3e */ "&gt;",
+/* 63 3f */ "?",
+/* 64 40 */ "@",
+/* 65 41 */ "A",
+/* 66 42 */ "B",
+/* 67 43 */ "C",
+/* 68 44 */ "D",
+/* 69 45 */ "E",
+/* 70 46 */ "F",
+/* 71 47 */ "G",
+/* 72 48 */ "H",
+/* 73 49 */ "I",
+/* 74 4a */ "J",
+/* 75 4b */ "K",
+/* 76 4c */ "L",
+/* 77 4d */ "M",
+/* 78 4e */ "N",
+/* 79 4f */ "O",
+/* 80 50 */ "P",
+/* 81 51 */ "Q",
+/* 82 52 */ "R",
+/* 83 53 */ "S",
+/* 84 54 */ "T",
+/* 85 55 */ "U",
+/* 86 56 */ "V",
+/* 87 57 */ "W",
+/* 88 58 */ "X",
+/* 89 59 */ "Y",
+/* 90 5a */ "Z",
+/* 91 5b */ "[",
+/* 92 5c */ "\\",
+/* 93 5d */ "]",
+/* 94 5e */ "^",
+/* 95 5f */ "_",
+/* 96 60 */ "`",
+/* 97 61 */ "a",
+/* 98 62 */ "b",
+/* 99 63 */ "c",
+/* 100 64 */ "d",
+/* 101 65 */ "e",
+/* 102 66 */ "f",
+/* 103 67 */ "g",
+/* 104 68 */ "h",
+/* 105 69 */ "i",
+/* 106 6a */ "j",
+/* 107 6b */ "k",
+/* 108 6c */ "l",
+/* 109 6d */ "m",
+/* 110 6e */ "n",
+/* 111 6f */ "o",
+/* 112 70 */ "p",
+/* 113 71 */ "q",
+/* 114 72 */ "r",
+/* 115 73 */ "s",
+/* 116 74 */ "t",
+/* 117 75 */ "u",
+/* 118 76 */ "v",
+/* 119 77 */ "w",
+/* 120 78 */ "x",
+/* 121 79 */ "y",
+/* 122 7a */ "z",
+/* 123 7b */ "{",
+/* 124 7c */ "|",
+/* 125 7d */ "}",
+/* 126 7e */ "~",
+/* 127 7f */ NULL,
+/* 128 80 */ NULL,
+/* 129 81 */ NULL,
+/* 130 82 */ NULL,
+/* 131 83 */ NULL,
+/* 132 84 */ NULL,
+/* 133 85 */ NULL,
+/* 134 86 */ NULL,
+/* 135 87 */ NULL,
+/* 136 88 */ NULL,
+/* 137 89 */ NULL,
+/* 138 8a */ NULL,
+/* 139 8b */ NULL,
+/* 140 8c */ NULL,
+/* 141 8d */ NULL,
+/* 142 8e */ NULL,
+/* 143 8f */ NULL,
+/* 144 90 */ NULL,
+/* 145 91 */ NULL,
+/* 146 92 */ NULL,
+/* 147 93 */ NULL,
+/* 148 94 */ NULL,
+/* 149 95 */ NULL,
+/* 150 96 */ NULL,
+/* 151 97 */ NULL,
+/* 152 98 */ NULL,
+/* 153 99 */ NULL,
+/* 154 9a */ NULL,
+/* 155 9b */ NULL,
+/* 156 9c */ NULL,
+/* 157 9d */ NULL,
+/* 158 9e */ NULL,
+/* 159 9f */ NULL,
+/* 160 a0 */ "&nbsp;",
+/* 161 a1 */ "&iexcl;",
+/* 162 a2 */ "&cent;",
+/* 163 a3 */ "&pound;",
+/* 164 a4 */ "&curren;",
+/* 165 a5 */ "&yen;",
+/* 166 a6 */ "&brvbar;",
+/* 167 a7 */ "&sect;",
+/* 168 a8 */ "&uml;",
+/* 169 a9 */ "&copy;",
+/* 170 aa */ "&ordf;",
+/* 171 ab */ "&laquo;",
+/* 172 ac */ "&not;",
+/* 173 ad */ "&shy;",
+/* 174 ae */ "&reg;",
+/* 175 af */ "&macr;",
+/* 176 b0 */ "&deg;",
+/* 177 b1 */ "&plusmn;",
+/* 178 b2 */ "&sup2;",
+/* 179 b3 */ "&sup3;",
+/* 180 b4 */ "&acute;",
+/* 181 b5 */ "&micro;",
+/* 182 b6 */ "&para;",
+/* 183 b7 */ "&middot;",
+/* 184 b8 */ "&cedil;",
+/* 185 b9 */ "&sup1;",
+/* 186 ba */ "&ordm;",
+/* 187 bb */ "&raquo;",
+/* 188 bc */ "&frac14;",
+/* 189 bd */ "&frac12;",
+/* 190 be */ "&frac34;",
+/* 191 bf */ "&iquest;",
+/* 192 c0 */ "&Agrave;",
+/* 193 c1 */ "&Aacute;",
+/* 194 c2 */ "&Acirc;",
+/* 195 c3 */ "&Atilde;",
+/* 196 c4 */ "&Auml;",
+/* 197 c5 */ "&Aring;",
+/* 198 c6 */ "&AElig;",
+/* 199 c7 */ "&Ccedil;",
+/* 200 c8 */ "&Egrave;",
+/* 201 c9 */ "&Eacute;",
+/* 202 ca */ "&Ecirc;",
+/* 203 cb */ "&Euml;",
+/* 204 cc */ "/Igrave;",
+/* 205 cd */ "&Iacute;",
+/* 206 ce */ "&Icirc;",
+/* 207 cf */ "&Iuml;",
+/* 208 d0 */ "&ETH;",
+/* 209 d1 */ "&Ntilde;",
+/* 210 d2 */ "&Ograve;",
+/* 211 d3 */ "&Oacute;",
+/* 212 d4 */ "&Ocirc;",
+/* 213 d5 */ "&Otilde;",
+/* 214 d6 */ "&Ouml;",
+/* 215 d7 */ "&times;",
+/* 216 d8 */ "&Oslash;",
+/* 217 d9 */ "&Ugrave;",
+/* 218 da */ "&Uacute;",
+/* 219 db */ "&Ucirc;",
+/* 220 dc */ "&Uuml;",
+/* 221 dd */ "&Yacute;",
+/* 222 de */ "&THORN;",
+/* 223 df */ "&szlig;",
+/* 224 e0 */ "&agrave;",
+/* 225 e1 */ "&aacute;",
+/* 226 e2 */ "&acirc;",
+/* 227 e3 */ "&atilde;",
+/* 228 e4 */ "&auml;",
+/* 229 e5 */ "&aring;",
+/* 230 e6 */ "&aelig;",
+/* 231 e7 */ "&ccedil;",
+/* 232 e8 */ "&egrave;",
+/* 233 e9 */ "&eacute;",
+/* 234 ea */ "&ecirc;",
+/* 235 eb */ "&euml;",
+/* 236 ec */ "&igrave;",
+/* 237 ed */ "&iacute;",
+/* 238 ee */ "&icirc;",
+/* 239 ef */ "&iuml;",
+/* 240 f0 */ "&eth;",
+/* 241 f1 */ "&ntilde;",
+/* 242 f2 */ "&ograve;",
+/* 243 f3 */ "&oacute;",
+/* 244 f4 */ "&ocirc;",
+/* 245 f5 */ "&otilde;",
+/* 246 f6 */ "&ouml;",
+/* 247 f7 */ "&divide;",
+/* 248 f8 */ "&oslash;",
+/* 249 f9 */ "&ugrave;",
+/* 250 fa */ "&uacute;",
+/* 251 fb */ "&ucirc;",
+/* 252 fc */ "&uuml;",
+/* 253 fd */ "&yacute;",
+/* 254 fe */ "&thorn;",
+/* 255 ff */ "&yuml;"
+};
+
+
+
+/** Constant 8-bit character keywords.
+*/
+static char const * const hbhtml_c8_kw[] = {
+/* 0 */
+"\n",
+
+/* 1 */
+" ",
+
+/* 2 */
+"<img ",
+
+/* 3 */
+">",
+
+/* 4 */
+"src=\"",
+
+/* 5 */
+"\"",
+
+/* 6 */
+" alt=\"",
+
+/* 7 */
+" title=\"",
+
+/* 8 */
+" border=\"",
+
+/* 9 */
+" width=\"",
+
+/* 10 */
+" height=\"",
+
+/* 11 */
+"<html>\n",
+
+/* 12 */
+"</html>\n",
+
+/* 13 */
+"<body>\n",
+
+/* 14 */
+"</body>\n",
+
+/* 15 */
+"<head>\n",
+
+/* 16 */
+"</head>\n",
+
+/* 17 */
+"<!-- Generated by htmlbook (see http://dktools.sourceforge.net) -->\n",
+
+/* 18 */
+"<meta name=\"generator\" content=\"htmlbook\">\n",
+
+/* 19 */
+"<title>",
+
+/* 20 */
+"</title>\n",
+
+/* 21 */
+"<link rel=\"stylesheet\" type=\"text/css\" href=\"",
+
+/* 22 */
+"\">\n",
+
+/* 23 */
+"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=us-ascii\">\n",
+
+/* 24 */
+"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n",
+
+/* 25 */
+"<meta name=\"author\" content=\"",
+
+/* 26 */
+"\">\n",
+
+/* 27 */
+"<link rel=\"shortcut icon\" href=\"",
+
+/* 28 */
+"\">\n",
+
+/* 29 */
+"<div class=\"hb_nm_div\">\n",
+
+/* 30 */
+"</div><!-- class=hb_nm_div -->\n",
+
+/* 31 */
+"<ul class=\"hb_nm_ul\">\n",
+
+/* 32 */
+"</ul><!-- class=hb_nm_ul -->\n",
+
+/* 33 */
+"<li class=\"hb_nm_sep\">&nbsp;</li>\n",
+
+/* 34 */
+"<li class=\"hb_nm_c\"",
+
+/* 35 */
+"</li>\n",
+
+/* 36 */
+"<li class=\"hb_nm_li\">",
+
+/* 37 */
+"</li>\n",
+
+/* 38 */
+"hb_nm_a",
+
+/* 39 */
+"<a href=\"",
+
+/* 40 */
+">",
+
+/* 41 */
+"</a>",
+
+/* 42 */
+"\"",
+
+/* 43 */
+" class=\"",
+
+/* 44 */
+" title=\"",
+
+/* 45 */
+" type=\"",
+
+/* 46 */
+"<div class=\"hb_navigation\">",
+
+/* 47 */
+"</div>\n",
+
+/* 48 */
+"&nbsp;",
+
+/* 49 */
+"<a class=\"hb_navi_a\" href=\"",
+
+/* 50 */
+"\" title=\"",
+
+/* 51 */
+"\">",
+
+/* 52 */
+"</a>",
+
+/* 53 */
+"<img src=\"",
+
+/* 54 */
+"\" alt=\"",
+
+/* 55 */
+"\" title=\"",
+
+/* 56 */
+"\" class=\"hb_navi_img\" border=\"0\"",
+
+/* 57 */
+"0",
+
+/* 58 */
+" name=\"",
+
+/* 59 */
+" longdesc=\"",
+
+/* 60 */
+" class=\"",
+
+/* 61 */
+" id=\"",
+
+/* 62 */
+" usemap=\"",
+
+/* 63 */
+" align=\"",
+
+/* 64 */
+" hspace=\"",
+
+/* 65 */
+" vspace=\"",
+
+/* 66 */
+" ismap",
+
+/* 67 */
+" width=\"%lu\" height=\"%lu\"",
+
+/* 68 */
+"<a class=\"hb_img_a_larger\" href=\"",
+
+/* 69 */
+"\" target=\"_blank\"",
+
+/* 70 */
+"<object type=\"application/pdf\" data=\"",
+
+/* 71 */
+"\" width=\"",
+
+/* 72 */
+"\" height=\"",
+
+/* 73 */
+"</object>",
+
+/* 74 */
+"<a name=\"",
+
+/* 75 */
+"\" target=\"",
+
+/* 76 */
+"\" type=\"",
+
+/* 77 */
+"\" class=\"",
+
+/* 78 */
+"\" id=\"",
+
+/* 79 */
+"\" style=\"",
+
+/* 80 */
+"\" hreflang=\"",
+
+/* 81 */
+"\" title=\"",
+
+/* 82 */
+"\" onblur=\"",
+
+/* 83 */
+"\" onfocus=\"",
+
+/* 84 */
+"\" rel=\"",
+
+/* 85 */
+"\" rev=\"",
+
+/* 86 */
+"\" shape=\"",
+
+/* 87 */
+"\" tabindex=\"",
+
+/* 88 */
+"\" accesskey=\"",
+
+/* 89 */
+"\" charset=\"",
+
+/* 90 */
+"\" coords=\"",
+
+/* 91 */
+"<span class=\"hb_link_number\">&nbsp;&#9001;%lu&#9002;</span>",
+
+/* 92 */
+"<table class=\"hb_me_ta\" summary=\"",
+
+/* 93 */
+"</table>\n",
+
+/* 94 */
+"<tr class=\"hb_me_tr\">\n",
+
+/* 95 */
+"</tr>\n",
+
+/* 96 */
+"<td class=\"hb_me_td_text\" colspan=\"%u\">",
+
+/* 97 */
+"</td>\n",
+
+/* 98 */
+"<td></td>\n",
+
+/* 99 */
+"<td class=\"hb_me_td_arrow\">&nbsp;&#8594;&nbsp;</td>\n",
+
+/* 100 */
+"hb_a_i",
+
+/* 101 */
+"hb_a_e",
+
+/* 102 */
+"<div class=\"hb_file_div\">\n",
+
+/* 103 */
+"<a class=\"hb_file_a\" target=\"_blank\" href=\"",
+
+/* 104 */
+"text/plain",
+
+/* 105 */
+"<br>\n",
+
+/* 106 */
+"<pre>\n",
+
+/* 107 */
+"</pre>\n",
+
+/* 108 */
+"\" target=\"_blank",
+
+/* 109 */
+"<div class=\"hb_img_div_outer\">\n",
+
+/* 110 */
+"<div class=\"hb_img_div_inner_img\">\n",
+
+/* 111 */
+"<div class=\"hb_img_div_inner_img_centered\">\n",
+
+/* 112 */
+"<p class=\"hb_img_p_download\">\n",
+
+/* 113 */
+"<br class=\"clearboth\">\n</p>\n",
+
+/* 114 */
+"\n<object type=\"image/svg+xml\" data=\"",
+
+/* 115 */
+"<param name=\"src\" value=\"",
+
+/* 116 */
+"<br>\n<span class=\"hb_img_caption\">",
+
+/* 117 */
+"</span>",
+
+/* 118 */
+" type=\"image/svg+xml\"",
+
+/* 119 */
+" type=\"application/pdf\"",
+
+/* 120 */
+"<p><br class=\"clearboth\"></p>\n",
+
+/* 121 */
+"<script src=\"",
+
+/* 122 */
+"\" type=\"text/javascript\">\n</script>\n",
+
+/* 123 */
+"<link rel=\"",
+
+/* 124 */
+"\" title=\"",
+
+/* 125 */
+"\" href=\"",
+
+/* 126 */
+"\">\n",
+
+/* 127 */
+"author",
+
+/* 128 */
+"contents",
+
+/* 129 */
+"index",
+
+/* 130 */
+"top",
+
+/* 131 */
+"up",
+
+/* 132 */
+"first",
+
+/* 133 */
+"prev",
+
+/* 134 */
+"next",
+
+/* 135 */
+"last",
+
+/* 136 */
+"#hb_toc",
+
+/* 137 */
+"#hb_index",
+
+/* 138 */
+"<table class=\"hb_img_ta\" summary=\"",
+
+/* 139 */
+"<tr class=\"hb_img_tr\">\n",
+
+/* 140 */
+"<td class=\"hb_img_td_img\">\n",
+
+/* 141 */
+"<td class=\"hb_img_td_empty\">&nbsp;</td>\n",
+
+/* 142 */
+"<td class=\"hb_img_td_a\">\n",
+
+/* 143 */
+"\">\n",
+
+/* 144 */
+"hb_nm_a_parent",
+
+/* 145 */
+"<div class=\"hb_img_div_no_vspace\">\n",
+
+/* 146 */
+"<code title=\"",
+
+/* 147 */
+"\">",
+
+/* 148 */
+"</code>",
+
+/* 149 */
+" ",
+
+/* 150 */
+" ",
+
+/* 151 */
+"<span class=\"hint\" title=\"",
+
+/* 152 */
+"\">",
+
+/* 153 */
+"</span>",
+
+/* 154 */
+"<meta name=\"description\" content=\"",
+
+/* 155 */
+"<meta name=\"keywords\" content=\"",
+
+NULL
+
+
+#line 832 "hbhtml.ctr"
+};
+
+
+
+/** Special commands.
+*/
+dkChar const * const hbhtml_special_commands[] = {
+/* 0 */
+dkT("contents"),
+
+/* 1 */
+dkT("title"),
+
+/* 2 */
+dkT("img"),
+
+/* 3 */
+dkT("menu"),
+
+/* 4 */
+dkT("navigation"),
+
+/* 5 */
+dkT("links"),
+
+/* 6 */
+dkT("author"),
+
+/* 7 */
+dkT("location"),
+
+/* 8 */
+dkT("date"),
+
+/* 9 */
+dkT("var"),
+
+/* 10 */
+dkT("code"),
+
+/* 11 */
+dkT("a"),
+
+/* 12 */
+dkT("menuentry"),
+
+/* 13 */
+dkT("index"),
+
+/* 14 */
+dkT("sourcefile"),
+
+/* 15 */
+dkT("htmlname"),
+
+/* 16 */
+dkT("hint"),
+
+NULL
+
+
+#line 909 "hbhtml.ctr"
+};
+
+
+
+
+/** Attributes allowed in image special command.
+*/
+dkChar const * const hbhtml_img_keys[] = {
+/* 0 */
+dkT("ali$gn"),
+
+/* 1 */
+dkT("alt"),
+
+/* 2 */
+dkT("b$order"),
+
+/* 3 */
+dkT("he$ight"),
+
+/* 4 */
+dkT("hs$pace"),
+
+/* 5 */
+dkT("is$map"),
+
+/* 6 */
+dkT("lo$ngdesc"),
+
+/* 7 */
+dkT("n$ame"),
+
+/* 8 */
+dkT("sr$c"),
+
+/* 9 */
+dkT("u$semap"),
+
+/* 10 */
+dkT("v$space"),
+
+/* 11 */
+dkT("w$idth"),
+
+/* 12 */
+dkT("la$rger"),
+
+/* 13 */
+dkT("p$df"),
+
+/* 14 */
+dkT("cac$he"),
+
+/* 15 */
+dkT("ti$tle"),
+
+/* 16 */
+dkT("cl$ass"),
+
+/* 17 */
+dkT("id"),
+
+/* 18 */
+dkT("div"),
+
+/* 19 */
+dkT("cap$tion"),
+
+/* 20 */
+dkT("ce$ntered"),
+
+/* 21 */
+dkT("svg"),
+
+/* 22 */
+dkT("svgwh"),
+
+/* 23 */
+dkT("do$wnloads"),
+
+/* 24 */
+dkT("o$bject"),
+
+/* 25 */
+dkT("ta$ble"),
+
+/* 26 */
+dkT("no-v$space"),
+
+/* 27 */
+dkT("f$ile"),
+
+NULL
+
+
+#line 947 "hbhtml.ctr"
+};
+
+
+
+/** Keys for hint.
+*/
+dkChar const * const hbhtml_hint_keys[] = {
+/* 0 */
+dkT("te$xt"),
+
+/* 1 */
+dkT("ti$tle"),
+
+NULL
+
+
+#line 958 "hbhtml.ctr"
+};
+
+
+
+/** Attributes for menu.
+*/
+dkChar const * const hbhtml_menu_keys[] = {
+/* 0 */
+dkT("st$yle"),
+
+/* 1 */
+dkT("su$b"),
+
+NULL
+
+
+#line 969 "hbhtml.ctr"
+};
+
+
+
+/** Attributes for menuentry.
+*/
+dkChar const * const hbhtml_menuentry_keys[] = {
+/* 0 */
+dkT("i$tem"),
+
+NULL
+
+
+#line 979 "hbhtml.ctr"
+};
+
+
+
+/** Attributes for index entry.
+*/
+dkChar const * const hbhtml_index_keys[] = {
+/* 0 */
+dkT("t$ext"),
+
+/* 1 */
+dkT("n$ame"),
+
+/* 2 */
+dkT("ref$erence"),
+
+NULL
+
+
+#line 991 "hbhtml.ctr"
+};
+
+
+
+/** Attributes for sourcefile special command.
+*/
+dkChar const * const hbhtml_sourcef_keys[] = {
+/* 0 */
+dkT("f$ile"),
+
+/* 1 */
+dkT("ty$pe"),
+
+/* 2 */
+dkT("ti$tle"),
+
+/* 3 */
+dkT("l$ineno"),
+
+NULL
+
+
+#line 1004 "hbhtml.ctr"
+};
+
+
+/** Attributes for navigation.
+*/
+dkChar const * const hbhtml_navi_keys[] = {
+/* 0 */
+dkT("t$oc"),
+
+/* 1 */
+dkT("p$revious"),
+
+/* 2 */
+dkT("n$ext"),
+
+/* 3 */
+dkT("i$ndex"),
+
+/* 4 */
+dkT("h$ome"),
+
+NULL
+
+
+#line 1017 "hbhtml.ctr"
+};
+
+
+
+/** Attributes for code special command.
+*/
+dkChar const * const hbhtml_code_keys[] = {
+/* 0 */
+dkT("e$nable"),
+
+/* 1 */
+dkT("on"),
+
+/* 2 */
+dkT("d$isable"),
+
+/* 3 */
+dkT("of$f"),
+
+/* 4 */
+dkT("t$oggle"),
+
+/* 5 */
+dkT("l$ineno"),
+
+NULL
+
+
+#line 1032 "hbhtml.ctr"
+};
+
+
+
+/** Attribute for a.
+*/
+dkChar const * const hbhtml_a_keys[] = {
+/* 0 */
+dkT("te$xt"),
+
+/* 1 */
+dkT("ti$tle"),
+
+/* 2 */
+dkT("ac$cesskey"),
+
+/* 3 */
+dkT("ch$arset"),
+
+/* 4 */
+dkT("co$ords"),
+
+/* 5 */
+dkT("href"),
+
+/* 6 */
+dkT("hrefl$ang"),
+
+/* 7 */
+dkT("na$me"),
+
+/* 8 */
+dkT("onb$lur"),
+
+/* 9 */
+dkT("onf$ocus"),
+
+/* 10 */
+dkT("rel"),
+
+/* 11 */
+dkT("rev"),
+
+/* 12 */
+dkT("sh$ape"),
+
+/* 13 */
+dkT("tab$index"),
+
+/* 14 */
+dkT("tar$get"),
+
+/* 15 */
+dkT("ty$pe"),
+
+/* 16 */
+dkT("cl$ass"),
+
+/* 17 */
+dkT("id"),
+
+/* 18 */
+dkT("st$yle"),
+
+/* 19 */
+dkT("ext$ernal"),
+
+NULL
+
+
+#line 1061 "hbhtml.ctr"
+};
+
+
+
+/** The menu styles.
+*/
+dkChar const * const hbhtml_menu_styles[] = {
+/* 0 */
+dkT("r$everse"),
+
+/* 1 */
+dkT("f$ull"),
+
+/* 2 */
+dkT("c$urrent"),
+
+/* 3 */
+dkT("t$op"),
+
+NULL
+
+
+#line 1074 "hbhtml.ctr"
+};
+
+
+
+/** Attributes allowed in date special.
+*/
+dkChar const * const hbhtml_date_keys[] = {
+/* 0 */
+dkT("st$yle"),
+
+NULL
+
+
+#line 1084 "hbhtml.ctr"
+};
+
+
+
+/** Subcommands of img with not vertical space.
+*/
+dkChar const * const hbhtml_no_vspace_suffixes[] = {
+/* 0 */
+dkT("tex"),
+
+NULL
+
+
+#line 1094 "hbhtml.ctr"
+};
+
+
+
+/** File name suffixes.
+*/
+dkChar const * const hbhtml_image_filename_suffixes[] = {
+/* 0 */
+dkT(".png"),
+
+/* 1 */
+dkT(".pdf"),
+
+/* 2 */
+dkT(".svg"),
+
+NULL
+
+
+#line 1106 "hbhtml.ctr"
+};
+
+
+
+/** Check whether a character is useable in an URL.
+ RFC 1630 and 3986 allow only 8-bit characters (octets)
+ in URLs.
+ @param c32 Character to check.
+ @return 1 for usable character, 0 otherwise.
+*/
+static
+int
+hbhtml_url_useable(dk3_c32_t c32)
+{
+ int back = 1;
+
+
+#line 1122 "hbhtml.ctr"
+ if((dk3_c32_t)255 < c32) {
+ back = 0; /* NOT REPORTED */
+ }
+
+#line 1125 "hbhtml.ctr"
+ return back;
+}
+
+
+
+#if 0
+/** Check whether a character must be written hex-encoded to an URL.
+ See RFC 3986 for reserved and unreserved characters.
+ @param c32 Character to check.
+ @return 1 for hex-encoding, 0 for direct use.
+*/
+static
+int
+hbhtml_url_must_encode_normally(dk3_c32_t c32)
+{
+ int back = 1;
+ char c;
+ if((dk3_c32_t)128 > c32) {
+ c = (char)c32;
+ c &= 0x7F;
+ if(('a' <= c) && ('z' >= c)) {
+ back = 0;
+ } else {
+ if(('A' <= c) && ('Z' >= c)) {
+ back = 0;
+ } else {
+ if(('0' <= c) && ('9' >= c)) {
+ back = 0;
+ } else {
+ switch(c) {
+ case '-': case '_': case '.': case '~': {
+ back = 0;
+ } break;
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+#endif
+
+
+
+/** Check whether a character must be written hex-encoded to an URL.
+ See RFC 3986 for reserved and unreserved characters.
+ @param c32 Character to check.
+ @return 1 for hex-encoding, 0 for direct use.
+*/
+static
+int
+hbhtml_url_must_encode(dk3_c32_t c32)
+{
+ int back = 0;
+
+
+#line 1180 "hbhtml.ctr"
+ if((dk3_c32_t)126 < c32) {
+ back = 1;
+ } else {
+ if((dk3_c32_t)33 > c32) {
+ back = 1;
+ }
+ }
+
+#line 1187 "hbhtml.ctr"
+ return back;
+}
+
+
+
+/** Write one character in URL encoding, complain on problems.
+ Unusable characters (not in octect range 0...0xFF)
+ are UTF-8 encoded first and hex-converted for the URL.
+ Some ASCII characters have special meaning in URL encoding
+ (i.e. ampersand, question mark...). We assume the user
+ intended to use these characters and specified the URL
+ so we can use it "as is".
+
+ @param job Job structure.
+ @param c32 Character to print.
+*/
+static
+void
+hbhtml_url_c32(hb_job_t *job, dk3_c32_t c32)
+{
+ char buf[16]; /* Buffer for hexadecimal notation */
+ unsigned char ub[16]; /* Buffer for UTF-8 notation */
+ size_t sz; /* Number of bytes used in ub */
+ size_t i; /* Traverse ub */
+
+
+#line 1212 "hbhtml.ctr"
+ if(hbhtml_url_useable(c32)) {
+ if(hbhtml_url_must_encode(c32)) {
+ buf[0] = '%';
+ sprintf(&(buf[1]), "%02X", (unsigned)c32);
+ fputs(buf, job->of);
+ } else {
+ fputc((((char)c32) & ((char)0x7F)), job->of);
+ }
+ } else {
+ job->non_url = 1;
+ sz = dk3enc_uc2utf8(c32, ub, sizeof(ub));
+ for(i = 0; i < sz; i++) {
+ buf[0] = '%';
+ sprintf(&(buf[1]), "%02X", ((unsigned)(ub[i]) & 0x00FFU));
+ fputs(buf, job->of);
+ }
+ }
+
+#line 1229 "hbhtml.ctr"
+}
+
+
+
+/** Write shipout buffer in URL encoding.
+ @param job Job structure.
+*/
+static
+void
+hbhtml_url_flush_shipout(hb_job_t *job)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ size_t i;
+#else
+ dk3_c16_t const *sp; /* Source character pointer */
+ dk3_c32_t c32; /* 32-bit character */
+ size_t sl; /* Remaining source string length */
+ size_t used; /* Number of source chars used */
+#endif
+#else
+ unsigned char const *sp; /* Source character pointer */
+ dk3_c32_t c32; /* 32-bit character */
+ size_t sl; /* Remaining source string length */
+ size_t used; /* Number of source chars used */
+ size_t i; /* Process all source chars */
+ unsigned char c; /* Current source char to process */
+#endif
+
+
+#line 1258 "hbhtml.ctr"
+ if(job->shipused) {
+ job->non_url = 0;
+ if(job->shipused < job->bs) {
+ (job->shipbuffer)[job->shipused] = dkT('\0');
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ for(i = 0; i < (job->shipused); i++) {
+ hbhtml_url_c32(job, (job->shipused)[i]);
+ }
+#else
+ sp = (dk3_c16_t const *)(job->shipbuffer);
+ sl = job->shipused;
+ while(sl > 0) {
+ used = 0;
+ if(dk3enc_utf162uc(&c32, sp, sl, &used)) {
+ hbhtml_url_c32(job, c32);
+ if(used > 0) {
+ if(sl >= used) {
+ sl = sl - used;
+ sp = &(sp[used]);
+ } else {
+ sl = 0;
+ /* ERROR: Decoding */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 119);
+ }
+ } else {
+ sl = 0;
+ /* ERROR: Decoding */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 119);
+ }
+ } else {
+ sl = 0;
+ /* ERROR: Decoding */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 119);
+ }
+ }
+#endif
+#else
+
+
+#line 1297 "hbhtml.ctr"
+ if(dk3app_get_encoding(job->app) == DK3_ENCODING_UTF8) {
+
+
+#line 1299 "hbhtml.ctr"
+ sp = (unsigned char const *)(job->shipbuffer);
+ sl = job->shipused;
+ while(sl > 0) {
+ used = 0;
+ if(dk3enc_utf82uc(&c32, sp, sl, &used)) {
+ hbhtml_url_c32(job, c32);
+ if(used > 0) {
+ if(sl >= used) {
+ sl = sl - used;
+ sp = &(sp[used]);
+ } else {
+ sl = 0;
+ /* ERROR: Decoding problem */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 118);
+ }
+ } else {
+ sl = 0;
+ /* ERROR: Decoding problem */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 118);
+ }
+ } else {
+ sl = 0;
+ /* ERROR: Decoding problem */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 118);
+ }
+ }
+ } else {
+ sp = (unsigned char const *)(job->shipbuffer);
+ for(i = 0; i < (job->shipused); i++) {
+ c = sp[i];
+ c32 = (dk3_c32_t)c;
+ c32 &= 0x000000FFUL;
+ hbhtml_url_c32(job, c32);
+ }
+ }
+
+
+#line 1335 "hbhtml.ctr"
+#endif
+ if(job->non_url) {
+ /* WARNING: Non-URL characters in string! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 21, 22, job->shipbuffer);
+ }
+ }
+ job->non_url = 0;
+ }
+ job->shipused = 0;
+
+
+#line 1345 "hbhtml.ctr"
+}
+
+
+
+void
+hbhtml_c32(hb_job_t *job, dk3_c32_t c32)
+{
+ unsigned char ub[16]; /* Buffer for UTF-8 conversion */
+ size_t sz; /* Number of chars used in ub */
+ size_t i; /* Process all chars in ub */
+ char c; /* Current char from ub */
+
+
+#line 1357 "hbhtml.ctr"
+ if(((dk3_c32_t)128) > c32) {
+ c = (((char)c32) & ((char)0x7F));
+ switch(c) {
+ case '\n': {
+ fputc('\n', job->of);
+ } break;
+ case '&': {
+ if((job->options) & HB_JOB_OPT_CODE) {
+ fputs(hbhtml_translation_table[38], job->of);
+ } else {
+ if(((job->currentnode)->options) & HB_NODE_OPT_REPLACE_AMPERSAND) {
+ fputs(hbhtml_translation_table[38], job->of);
+ } else {
+ fputc('&', job->of);
+ }
+ }
+ } break;
+ case '<': {
+ if((job->options) & HB_JOB_OPT_CODE) {
+ fputs(hbhtml_translation_table[60], job->of);
+ } else {
+ fputc('<', job->of);
+ }
+ } break;
+ case '>': {
+ if((job->options) & HB_JOB_OPT_CODE) {
+ fputs(hbhtml_translation_table[62], job->of);
+ } else {
+ fputc('>', job->of);
+ }
+ } break;
+ case '"': {
+ if((job->options) & HB_JOB_OPT_CODE) {
+ fputs(hbhtml_translation_table[34], job->of);
+ } else {
+ fputc('"', job->of);
+ }
+ } break;
+ case '%': {
+ fputc('%', job->of); /* PROBABLY NEED A CODE */
+ } break;
+ default: {
+ sz = (size_t)c32;
+ sz &= (size_t)0x007FU;
+ if(hbhtml_translation_table[sz]) {
+ fputs(hbhtml_translation_table[sz], job->of);
+ } else {
+ fprintf(job->of, "&#x%02lx;", (unsigned long)c32);
+ }
+ } break;
+ }
+ } else {
+ if(((dk3_c32_t)256) > c32) {
+ sz = (size_t)c32;
+ sz &= (size_t)0x00FFU;
+ if(hbhtml_translation_table[sz]) {
+ fputs(hbhtml_translation_table[sz], job->of);
+ } else {
+ fprintf(job->of, "&#x%02lx;", (unsigned long)c32);
+ }
+ } else {
+ if(HB_CS_UTF_8 == job->cs) {
+ sz = dk3enc_uc2utf8(c32, ub, sizeof(ub));
+ for(i = 0; i < sz; i++) { fputc(ub[i], job->of); }
+ } else {
+ if(((dk3_c32_t)0x010000UL) > c32) {
+ fprintf(job->of, "&#x%04lx;", (unsigned long)c32);
+ } else {
+ if(((dk3_c32_t)0x01000000UL) > c32) {
+ fprintf(job->of, "&#x%06lx;", (unsigned long)c32);
+ } else {
+ fprintf(job->of, "&#x%08lx;", (unsigned long)c32);
+ }
+ }
+ }
+ }
+ }
+
+#line 1434 "hbhtml.ctr"
+}
+
+
+
+/** Flush the shipout buffer.
+ @param job Job structure.
+*/
+static
+void
+hbhtml_flush_shipout(hb_job_t *job)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ size_t i; /* Process all characters */
+#else
+ dk3_c16_t const *sp; /* Current source start */
+ dk3_c32_t c32; /* Current 32-bit char to process */
+ size_t sl; /* Remaining source length */
+ size_t used; /* Source chars used */
+#endif
+#else
+ unsigned char const *sp; /* Current source start */
+ dk3_c32_t c32; /* Current 32-bit char to process */
+ size_t sl; /* Remaining source length */
+ size_t used; /* Source chars used */
+ size_t i; /* Process all chars from buffer */
+ unsigned char c; /* Current char to process */
+#endif
+
+
+#line 1463 "hbhtml.ctr"
+ if(job->shipused) {
+ if(job->shipused < job->bs) {
+ (job->shipbuffer)[job->shipused] = dkT('\0');
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ for(i = 0; i < (job->shipused); i++) {
+ hbhtml_c32(job, (job->shipused)[i]);
+ }
+#else
+ sp = (dk3_c16_t const *)(job->shipbuffer);
+ sl = job->shipused;
+ while(sl > 0) {
+ used = 0;
+ if(dk3enc_utf162uc(&c32, sp, sl, &used)) {
+ hbhtml_c32(job, c32);
+ if(used > 0) {
+ if(sl >= used) {
+ sl = sl - used;
+ sp = &(sp[used]);
+ } else {
+ sl = 0;
+ /* ERROR: Decoding */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 119);
+ }
+ } else {
+ sl = 0;
+ /* ERROR: Decoding */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 119);
+ }
+ } else {
+ sl = 0;
+ /* ERROR: Decoding */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 119);
+ }
+ }
+#endif
+#else
+
+
+#line 1501 "hbhtml.ctr"
+ if(dk3app_get_encoding(job->app) == DK3_ENCODING_UTF8) {
+
+
+#line 1503 "hbhtml.ctr"
+ sp = (unsigned char const *)(job->shipbuffer);
+ sl = job->shipused;
+ while(sl > 0) {
+ used = 0;
+ if(dk3enc_utf82uc(&c32, sp, sl, &used)) {
+ hbhtml_c32(job, c32);
+ if(used > 0) {
+ if(sl >= used) {
+ sl = sl - used;
+ sp = &(sp[used]);
+ } else {
+ sl = 0;
+ /* ERROR: Decoding problem */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 118);
+ }
+ } else {
+ sl = 0;
+ /* ERROR: Decoding problem */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 118);
+ }
+ } else {
+ sl = 0;
+ /* ERROR: Decoding problem */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 118);
+ }
+ }
+ } else {
+ sp = (unsigned char const *)(job->shipbuffer);
+ for(i = 0; i < (job->shipused); i++) {
+ c = sp[i];
+ c32 = (dk3_c32_t)c;
+ c32 &= 0x000000FFUL;
+ hbhtml_c32(job, c32);
+ }
+ }
+
+
+#line 1539 "hbhtml.ctr"
+#endif
+ }
+ }
+ job->shipused = 0;
+
+
+#line 1544 "hbhtml.ctr"
+}
+
+
+
+/** Add one character to shipout buffer.
+ @param job Job structure.
+ @param c Character to add.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_shipout(hb_job_t *job, dkChar c)
+{
+ int back = 1;
+
+
+#line 1559 "hbhtml.ctr"
+ if((job->shipused) < (job->bs - 1)) {
+ (job->shipbuffer)[job->shipused] = c;
+ job->shipused += 1;
+ if(job->shipused >= job->bs) {
+ back = 0;
+ }
+ } else {
+ back = 0;
+ }
+
+#line 1568 "hbhtml.ctr"
+ return back;
+}
+
+
+
+/** Add one character to special command buffer.
+ @param job Job structure.
+ @param c Character to add.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_add_to_special(hb_job_t *job, dkChar c)
+{
+ int back = 1;
+
+
+#line 1584 "hbhtml.ctr"
+ if((job->spused) < (job->bs - 1)) {
+ (job->special)[job->spused] = c;
+ job->spused += 1;
+ if(job->spused >= job->bs) {
+ back = 0;
+ }
+ } else {
+ back = 0;
+ }
+
+#line 1593 "hbhtml.ctr"
+ return back;
+}
+
+
+
+/** Classify a character for processing by state machine 1.
+ @param c Character to classify.
+ @return Classification result.
+*/
+static
+int
+hbhtml_classify_for_stm1(dkChar c)
+{
+ int back = STM1_I_ANY;
+ switch(c) {
+ case dkT('%'): {
+ back = STM1_I_PERCENT;
+ } break;
+ case dkT('\\'): {
+ back = STM1_I_BS;
+ } break;
+ }
+ return back;
+}
+
+
+
+/** Write text to HTML output file.
+ @param job Job structure.
+ @param text Text to write.
+ @return 1 on success, 0 on error.
+*/
+int
+hbhtml_output_for_text(hb_job_t *job, dkChar const *text)
+{
+ size_t sz;
+#if VERSION_BEFORE_20131219
+ int oldcode;
+#endif
+ int back = 0;
+
+
+#line 1634 "hbhtml.ctr"
+ if((job) && (text)) {
+ sz = dk3str_len(text);
+ if(sz < job->bs) {
+
+#line 1637 "hbhtml.ctr"
+#if VERSION_BEFORE_20131219
+ oldcode = (((job->options) & HB_JOB_OPT_CODE) ? 1 : 0);
+ job->options &= (~(HB_JOB_OPT_CODE));
+#endif
+ dk3str_cpy(job->shipbuffer, text);
+ job->shipused = sz;
+
+#line 1643 "hbhtml.ctr"
+ hbhtml_flush_shipout(job);
+
+#line 1644 "hbhtml.ctr"
+ back = 1;
+ job->spused = 0;
+ job->shipused = 0;
+#if VERSION_BEFORE_20131219
+ if(oldcode) {
+ job->options |= HB_JOB_OPT_CODE;
+ }
+#endif
+ }
+ }
+
+#line 1654 "hbhtml.ctr"
+ return back;
+}
+
+
+
+/** Write text to URL output file.
+ @param job Job structure.
+ @param text Text to write.
+ @return 1 on success, 0 on error.
+*/
+int
+hbhtml_url_output_for_text(hb_job_t *job, dkChar const *text)
+{
+ size_t sz; /* Text length */
+ int back = 0;
+
+
+#line 1670 "hbhtml.ctr"
+ if((job) && (text)) {
+ sz = dk3str_len(text);
+ if(sz < job->bs) {
+ dk3str_cpy(job->shipbuffer, text);
+ job->shipused = sz;
+ hbhtml_url_flush_shipout(job);
+ back = 1;
+ job->spused = 0;
+ job->shipused = 0;
+ }
+ }
+
+#line 1681 "hbhtml.ctr"
+ return back;
+}
+
+
+
+/** Process the title special command.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_process_sp_title(hb_job_t *job)
+{
+ int back = 0;
+
+
+#line 1696 "hbhtml.ctr"
+ if(job->rootnode) {
+
+#line 1697 "hbhtml.ctr"
+ if((job->rootnode)->title) {
+
+#line 1698 "hbhtml.ctr"
+ if(hbhtml_output_for_text(job, (job->rootnode)->title)) {
+ back = 1;
+ }
+ }
+ }
+
+#line 1703 "hbhtml.ctr"
+ return back;
+}
+
+
+
+/** Build new file name if necessary.
+ @param oldname Existing file name.
+ @param fnb File name buffer.
+ @param fnbsz Size of file name buffer.
+ @param sc Sub command.
+ @param newsuffix New file name suffix.
+ @param job Job structure.
+ @param ecp Error code variable pointer.
+*/
+static
+dkChar *
+hbhtml_sc_fn(
+ dkChar *oldname,
+ dkChar *fnb,
+ size_t fnbsz,
+ dkChar *sc,
+ dkChar const *newsuffix,
+ hb_job_t *job,
+ int *ecp
+)
+{
+ dk3_stat_t stb;
+ dkChar *back;
+ dkChar *sp;
+
+
+#line 1733 "hbhtml.ctr"
+
+
+#line 1734 "hbhtml.ctr"
+
+
+#line 1735 "hbhtml.ctr"
+ back = oldname;
+ if(!(back)) {
+ /* Remove suffix if it matches subcommand.
+ */
+ sp = dk3str_get_suffix(fnb);
+ if(sp) {
+ if(0 == dk3str_casecmp(&(sp[1]), sc)) {
+ *sp = dkT('\0');
+ }
+ }
+ /* Add new suffix.
+ */
+ if(fnbsz > (dk3str_len(fnb) + dk3str_len(newsuffix))) {
+ dk3str_cat(fnb, newsuffix);
+ /* If file exists, use file name from fnb.
+ */
+ if(dk3sf_stat_app(&stb, fnb, NULL)) {
+ switch(stb.ft) {
+ case DK3_FT_REGULAR: {
+ back = fnb;
+ } break;
+ default: {
+ /* ERROR: Not a regular file */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 255, 256, fnb);
+ } break;
+ }
+ } else {
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 84, 85, fnb);
+ }
+ } else {
+ /* ERROR: File name too long */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 65, 66, fnb);
+ if(ecp) { *ecp = 1; }
+ }
+ }
+
+#line 1770 "hbhtml.ctr"
+ return back;
+}
+
+
+
+/** Process image special command.
+ @param job Job structure.
+ @param pa Pointer to arguments.
+ @param sc Subcommand, may be NULL.
+ @param in_template Flag: Processing the template.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_process_sp_image(hb_job_t *job, dkChar *pa, dkChar *sc, int in_template)
+{
+ dkChar svgnbuf[DK3_MAX_PATH]; /* SVG file name */
+ dkChar pdfnbuf[DK3_MAX_PATH]; /* PDF file name */
+ dkChar pngnbuf[DK3_MAX_PATH]; /* PNG file name */
+ dk3_key_value_t kv[30]; /* Parameters */
+ dkChar wbuf[64]; /* Width buffer */
+ dkChar hbuf[64]; /* Height buffer */
+ dkChar *align = NULL; /* Align specified */
+ dkChar *alt = NULL; /* Alternative text */
+ dkChar *border = NULL; /* Border specified */
+ dkChar *height = NULL; /* Height specified */
+ dkChar *hspace = NULL; /* Horiz space specified */
+ dkChar *longdesc = NULL; /* Longdesc specified */
+ dkChar *name = NULL; /* Name. */
+ dkChar *src = NULL; /* Image file name */
+ dkChar *usemap = NULL; /* Usemap text */
+ dkChar *vspace = NULL; /* Vertical space specified */
+ dkChar *width = NULL; /* Width specified */
+ dkChar *larger = NULL; /* File name large resolution */
+ dkChar *pdf = NULL; /* PDF file name */
+ dkChar *clptr = NULL; /* Image CSS class */
+ dkChar *idptr = NULL; /* Image CSS id */
+ dkChar *title = NULL; /* Image title */
+ dkChar *capt = NULL; /* Image caption */
+ dkChar *svg = NULL; /* SVG file name */
+ dkChar *fnptr = NULL; /* The file argument */
+ unsigned long xw = 0UL; /* Width found */
+ unsigned long xh = 0UL; /* Height found */
+ size_t sz; /* Size of key value array */
+ size_t i; /* Traverse key value array */
+ int cache = 0; /* Flag: Cache width+height */
+ int ismap = 0; /* Flag: Write isamp attrib */
+ int back = 0; /* Result */
+ int tispec = 0; /* Flag: Title specified */
+ int caspec = 0; /* Flag: Capction specified */
+ int svgwh = 0; /* Flag: For SVG width+height */
+ int dodiv = 0; /* Img in div(1) or table(2) */
+ int center = 0; /* Flag: Center image */
+ int downlo = 0; /* Flag: Create download div */
+ int haveli = 0; /* Already have written link */
+ int crobj = 1; /* Flag: Create object */
+ int novsp = 0; /* Flag: No vertical space. */
+ int fnerr = 0; /* Flag: Error related file */
+
+
+#line 1829 "hbhtml.ctr"
+ sz = DK3_SIZEOF(kv,dk3_key_value_t);
+ svgnbuf[0] = pdfnbuf[0] = pngnbuf[0] = dkT('\0');
+ if(dk3str_to_key_value(kv, &sz, pa, job->app)) {
+
+
+#line 1833 "hbhtml.ctr"
+ if(sc) {
+
+#line 1834 "hbhtml.ctr"
+ tispec = 1;
+ downlo = 1;
+ dodiv = 2;
+ if(-1 < dk3str_array_index(hbhtml_no_vspace_suffixes, sc, 0)) {
+ novsp = 1;
+ }
+ }
+ for(i = 0; i < sz; i++) {
+ if(kv[i].key) {
+
+#line 1843 "hbhtml.ctr"
+ switch(dk3str_array_abbr(hbhtml_img_keys, kv[i].key, dkT('$'), 0)) {
+ case 0: {
+
+#line 1845 "hbhtml.ctr"
+ align = kv[i].val;
+ } break;
+ case 1: {
+
+#line 1848 "hbhtml.ctr"
+ alt = kv[i].val;
+ } break;
+ case 2: {
+
+#line 1851 "hbhtml.ctr"
+ border = kv[i].val;
+ } break;
+ case 3: {
+
+#line 1854 "hbhtml.ctr"
+ height = kv[i].val;
+ } break;
+ case 4: {
+
+#line 1857 "hbhtml.ctr"
+ hspace = kv[i].val;
+ } break;
+ case 5: { /* ismap */
+
+#line 1860 "hbhtml.ctr"
+ if(kv[i].val) {
+ if(dk3str_is_bool(kv[i].val)) {
+ if(dk3str_is_on(kv[i].val)) {
+ ismap = 1;
+ } else {
+ ismap = 0;
+ }
+ }
+ } else {
+ ismap = 1;
+ }
+ } break;
+ case 6: {
+
+#line 1873 "hbhtml.ctr"
+ longdesc = kv[i].val;
+ } break;
+ case 7: {
+
+#line 1876 "hbhtml.ctr"
+ name = kv[i].val;
+ } break;
+ case 8: {
+
+#line 1879 "hbhtml.ctr"
+ src = kv[i].val;
+ } break;
+ case 9: {
+
+#line 1882 "hbhtml.ctr"
+ usemap = kv[i].val;
+ } break;
+ case 10: {
+
+#line 1885 "hbhtml.ctr"
+ vspace = kv[i].val;
+ } break;
+ case 11: {
+
+#line 1888 "hbhtml.ctr"
+ width = kv[i].val;
+ } break;
+ case 12: {
+
+#line 1891 "hbhtml.ctr"
+ larger = kv[i].val;
+ } break;
+ case 13: {
+
+#line 1894 "hbhtml.ctr"
+ pdf = kv[i].val;
+ } break;
+ case 14: { /* caching */
+
+#line 1897 "hbhtml.ctr"
+ if(kv[i].val) {
+ if(dk3str_is_bool(kv[i].val)) {
+ if(dk3str_is_on(kv[i].val)) {
+ cache = 1;
+ } else {
+ cache = 0;
+ }
+ }
+ } else {
+ cache = 1;
+ }
+ } break;
+ case 15: {
+
+#line 1910 "hbhtml.ctr"
+ title = kv[i].val;
+ tispec = 1;
+ } break;
+ case 16: {
+
+#line 1914 "hbhtml.ctr"
+ clptr = kv[i].val;
+ } break;
+ case 17: {
+
+#line 1917 "hbhtml.ctr"
+ idptr = kv[i].val;
+ } break;
+ case 18: { /* div */
+ if(kv[i].val) {
+ if(dk3str_is_bool(kv[i].val)) {
+ dodiv = ((dk3str_is_on(kv[i].val)) ? 1 : 0);
+ } else {
+ /* ERROR: Not boolean */
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, kv[i].val);
+ }
+ } else {
+ dodiv = 1;
+ }
+ } break;
+ case 19: { /* caption */
+ caspec = 1;
+ capt = kv[i].val;
+ } break;
+ case 20: { /* centered */
+ if(kv[i].val) {
+ if(dk3str_is_bool(kv[i].val)) {
+ center = ((dk3str_is_on(kv[i].val)) ? 1 : 0);
+ } else {
+ /* ERROR: Not boolean */
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, kv[i].val);
+ }
+ } else {
+ center = 1;
+ }
+ } break;
+ case 21: { /* svg */
+ svg = kv[i].val;
+ } break;
+ case 22: { /* svgwh */
+ if(kv[i].val) {
+ if(dk3str_is_bool(kv[i].val)) {
+ svgwh = ((dk3str_is_on(kv[i].val)) ? 1 : 0);
+ } else {
+ /* ERROR: Not boolean */
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, kv[i].val);
+ }
+ } else {
+ svgwh = 1;
+ }
+ } break;
+ case 23: { /* downloads */
+ if(kv[i].val) {
+ if(dk3str_is_bool(kv[i].val)) {
+ downlo = ((dk3str_is_on(kv[i].val)) ? 1 : 0);
+ } else {
+ /* ERROR: Not boolean */
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, kv[i].val);
+ }
+ } else {
+ downlo = 1;
+ }
+ } break;
+ case 24: {
+ if(kv[i].val) {
+ if(dk3str_is_bool(kv[i].val)) {
+ crobj = ((dk3str_is_on(kv[i].val)) ? 1 : 0);
+ } else {
+ /* ERROR: Not boolean */
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, kv[i].val);
+ }
+ } else {
+ crobj = 1;
+ }
+ } break;
+ case 25: {
+ if(kv[i].val) {
+ if(dk3str_is_bool(kv[i].val)) {
+ if(dk3str_is_on(kv[i].val)) {
+ if(1 == dodiv) {
+ /* Warning: Overwriting div by table */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 66);
+ }
+ dodiv = 2;
+ } else {
+ if(1 != dodiv) {
+ dodiv = 0;
+ }
+ }
+ } else {
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, kv[i].val);
+ }
+ } else {
+ if(1 == dodiv) {
+ /* Warning: Overwriting div by table */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 66);
+ }
+ dodiv = 2;
+ }
+ } break;
+ case 26: {
+ if(kv[i].val) {
+ if(dk3str_is_bool(kv[i].val)) {
+ novsp = ((dk3str_is_on(kv[i].val)) ? 1 : 0);
+ } else {
+ /* ERROR: Not a boolean */
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, kv[i].val);
+ }
+ } else {
+ novsp = 1;
+ }
+ } break;
+ case 27: {
+
+#line 2024 "hbhtml.ctr"
+ if(kv[i].val) {
+ if(fnptr) {
+
+#line 2026 "hbhtml.ctr"
+ /* WARNING: Overwriting file setting! */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 86);
+ }
+ fnptr = kv[i].val;
+ } else {
+
+#line 2031 "hbhtml.ctr"
+ /* ERROR: No file name specified */
+ }
+ } break;
+ }
+ }
+ }
+ if(fnptr) {
+
+#line 2038 "hbhtml.ctr"
+ if(dk3str_len(fnptr) < DK3_SIZEOF(svgnbuf,dkChar)) {
+ dk3str_cpy(svgnbuf, fnptr);
+ dk3str_cpy(pdfnbuf, fnptr);
+ dk3str_cpy(pngnbuf, fnptr);
+ src = hbhtml_sc_fn(
+ src, pngnbuf, DK3_SIZEOF(pngnbuf,dkChar), sc,
+ hbhtml_image_filename_suffixes[0], job, &fnerr
+ );
+ svg = hbhtml_sc_fn(
+ svg, svgnbuf, DK3_SIZEOF(svgnbuf,dkChar), sc,
+ hbhtml_image_filename_suffixes[2], job, &fnerr
+ );
+ pdf = hbhtml_sc_fn(
+ pdf, pdfnbuf, DK3_SIZEOF(pdfnbuf,dkChar), sc,
+ hbhtml_image_filename_suffixes[1], job, &fnerr
+ );
+ } else {
+ /* ERROR: Name too long */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 65, 66, fnptr);
+ fnerr = 1;
+ }
+ }
+ if(src) {
+ if(!hbtool_check_filename(job, src)) { src = NULL; }
+ }
+ if(src) {
+ if(0 == fnerr) { back = 1; }
+ if(larger) {
+
+#line 2066 "hbhtml.ctr"
+ if(!hbtool_check_filename(job, larger)) { larger = NULL; }
+ }
+ if(pdf) {
+
+#line 2069 "hbhtml.ctr"
+ if(!hbtool_check_filename(job, pdf)) { pdf = NULL; }
+ }
+ if(svg) {
+
+#line 2072 "hbhtml.ctr"
+ if(!hbtool_check_filename(job, svg)) { svg = NULL; }
+ }
+ if(tispec) {
+ if(!(title)) { title = alt; }
+ if(!(title)) { title = src; }
+ }
+ if(caspec) {
+ if(!(capt)) { capt = title; }
+ if(!(capt)) { capt = alt; }
+ }
+ if(!((width) && (height))) {
+ if(hbimgdim_find(job, src, &xw, &xh, cache)) {
+ if((xw) && (xh)) {
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(wbuf, dkT("%lu"), xw);
+ dk3sf_sprintf3(hbuf, dkT("%lu"), xh);
+ if(!(width)) { width = wbuf; }
+ if(!(height)) { height = hbuf; }
+#else
+ if(!(width)) {
+ if (dk3ma_um_to_string(wbuf,DK3_SIZEOF(wbuf,dkChar),(dk3_um_t)xw))
+ {
+ width = wbuf;
+ }
+ }
+ if(!(height)) {
+ if (dk3ma_um_to_string(hbuf,DK3_SIZEOF(hbuf,dkChar),(dk3_um_t)xh))
+ {
+ height = hbuf;
+ }
+ }
+#endif
+ }
+ }
+ }
+ if(capt) { if(!(dodiv)) { dodiv = 2; } }
+ if(downlo) { if(!(dodiv)) { dodiv = 2; } }
+
+ /* Output creation starts here.
+ */
+ if(dodiv) {
+ if(2 == dodiv) {
+ /* div Open outer div */
+ fputs(hbhtml_c8_kw[((novsp) ? (145) : (109))], job->of);
+ /* table */
+ fputs(hbhtml_c8_kw[138], job->of);
+ hbhtml_output_for_text(job, (job->msg)[65]);
+ fputs(hbhtml_c8_kw[143], job->of);
+ /* tr */
+ fputs(hbhtml_c8_kw[139], job->of);
+ /* td */
+ fputs(hbhtml_c8_kw[140], job->of);
+ } else {
+ /* div Open outer div */
+ fputs(hbhtml_c8_kw[109], job->of);
+ /* div Open image div */
+ fputs(hbhtml_c8_kw[(center) ? 111 : 110], job->of);
+ }
+ }
+
+ /* SVG object start.
+ */
+ if((svg) && (crobj)) {
+ /* Opening object tag */
+ fputs(hbhtml_c8_kw[114], job->of);
+ if(!hbhtml_url_output_for_text(job, svg)) { back = 0; }
+ if((svgwh) && (width) && (height)) {
+ fputs(hbhtml_c8_kw[71], job->of);
+ if(!hbhtml_url_output_for_text(job, width)) { back = 0; }
+ fputs(hbhtml_c8_kw[72], job->of);
+ if(!hbhtml_url_output_for_text(job, height)) { back = 0; }
+ }
+ fputs(hbhtml_c8_kw[51], job->of);
+ fputs(hbhtml_c8_kw[0], job->of);
+ /* Object param */
+ fputs(hbhtml_c8_kw[115], job->of);
+ if(!hbhtml_url_output_for_text(job, svg)) { back = 0; }
+ fputs(hbhtml_c8_kw[51], job->of);
+ fputs(hbhtml_c8_kw[0], job->of);
+ }
+
+ /* Image
+ */
+ fputs(hbhtml_c8_kw[2], job->of);
+ fputs(hbhtml_c8_kw[4], job->of);
+ if(!hbhtml_url_output_for_text(job, src)) {
+ back = 0;
+ }
+ fputs(hbhtml_c8_kw[5], job->of);
+ if(name) {
+ fputs(hbhtml_c8_kw[58], job->of);
+ if(!hbhtml_output_for_text(job, name)) {
+ back = 0;
+ }
+ fputs(hbhtml_c8_kw[5], job->of);
+ }
+ fputs(hbhtml_c8_kw[6], job->of);
+ if(alt) {
+ if(!hbhtml_output_for_text(job, alt)) {
+ back = 0;
+ }
+ }
+ fputs(hbhtml_c8_kw[5], job->of);
+ if(title) {
+ fputs(hbhtml_c8_kw[7], job->of);
+ if(!hbhtml_output_for_text(job, title)) {
+ back = 0;
+ }
+ fputs(hbhtml_c8_kw[5], job->of);
+ }
+ if(longdesc) {
+ fputs(hbhtml_c8_kw[59], job->of);
+ if(!hbhtml_url_output_for_text(job, longdesc)) {
+ back = 0;
+ }
+ fputs(hbhtml_c8_kw[5], job->of);
+ }
+ if((width) && (height)) {
+ fputs(hbhtml_c8_kw[9], job->of);
+ if(!hbhtml_url_output_for_text(job, width)) {
+ back = 0;
+ }
+ fputs(hbhtml_c8_kw[5], job->of);
+ fputs(hbhtml_c8_kw[10], job->of);
+ if(!hbhtml_url_output_for_text(job, height)) {
+ back = 0;
+ }
+ fputs(hbhtml_c8_kw[5], job->of);
+ }
+ fputs(hbhtml_c8_kw[8], job->of);
+ if(border) {
+ if(!hbhtml_url_output_for_text(job, border)) {
+ back = 0;
+ }
+ } else {
+ fputs(hbhtml_c8_kw[57], job->of);
+ }
+ fputs(hbhtml_c8_kw[5], job->of);
+ if(clptr) {
+ fputs(hbhtml_c8_kw[60], job->of);
+ if(!hbhtml_url_output_for_text(job, clptr)) {
+ back = 0;
+ }
+ fputs(hbhtml_c8_kw[5], job->of);
+ }
+ if(idptr) {
+ fputs(hbhtml_c8_kw[61], job->of);
+ if(!hbhtml_url_output_for_text(job, idptr)) {
+ back = 0;
+ }
+ fputs(hbhtml_c8_kw[5], job->of);
+ }
+ if(usemap) {
+ fputs(hbhtml_c8_kw[62], job->of);
+ if(!hbhtml_url_output_for_text(job, usemap)) {
+ back = 0;
+ }
+ fputs(hbhtml_c8_kw[5], job->of);
+ }
+ if(align) {
+ fputs(hbhtml_c8_kw[63], job->of);
+ if(!hbhtml_url_output_for_text(job, align)) {
+ back = 0;
+ }
+ fputs(hbhtml_c8_kw[5], job->of);
+ }
+ if(hspace) {
+ fputs(hbhtml_c8_kw[64], job->of);
+ if(!hbhtml_url_output_for_text(job, hspace)) {
+ back = 0;
+ }
+ fputs(hbhtml_c8_kw[5], job->of);
+ }
+ if(vspace) {
+ fputs(hbhtml_c8_kw[65], job->of);
+ if(!hbhtml_url_output_for_text(job, vspace)) {
+ back = 0;
+ }
+ fputs(hbhtml_c8_kw[5], job->of);
+ }
+ if(ismap) {
+ fputs(hbhtml_c8_kw[66], job->of);
+ }
+ fputs(hbhtml_c8_kw[3], job->of);
+ fputs(hbhtml_c8_kw[0], job->of);
+
+ /* SVG object end.
+ */
+ if((svg) && (crobj)) {
+ /* Closing object tag */
+ fputs(hbhtml_c8_kw[73], job->of);
+ fputs(hbhtml_c8_kw[0], job->of);
+ }
+
+ /* Table or div end
+ */
+ if(dodiv) {
+ if(capt) {
+ /* Print caption
+ */
+ fputs(hbhtml_c8_kw[116], job->of);
+ if(!hbhtml_output_for_text(job, capt)) { back = 0; }
+ fputs(hbhtml_c8_kw[117], job->of);
+ /* fputs(hbhtml_c8_kw[0], job->of); */
+ }
+ if(2 == dodiv) {
+ /* !td Close image td */
+ fputs(hbhtml_c8_kw[97], job->of);
+ } else {
+ /* !div Close inner div */
+ fputs(hbhtml_c8_kw[47], job->of);
+ }
+ if(downlo) {
+ if(2 == dodiv) {
+ /* td space !td Space div */
+ fputs(hbhtml_c8_kw[141], job->of);
+ /* td Open download td */
+ fputs(hbhtml_c8_kw[142], job->of);
+ } else {
+ /* p Open download p */
+ fputs(hbhtml_c8_kw[112], job->of);
+ }
+ /* Write download links */
+ {
+ haveli = 0;
+ if(svg) {
+
+#line 2298 "hbhtml.ctr"
+ haveli = 1;
+ fputs(hbhtml_c8_kw[68], job->of);
+ if(!hbhtml_url_output_for_text(job, svg)) { back = 0; }
+ fputs(hbhtml_c8_kw[69], job->of);
+ fputs(hbhtml_c8_kw[118], job->of);
+ fputs(hbhtml_c8_kw[40], job->of);
+ if(!hbhtml_output_for_text(job, (job->kwnl)[33])) { back = 0; }
+ fputs(hbhtml_c8_kw[41], job->of);
+ }
+ if(pdf) {
+
+#line 2308 "hbhtml.ctr"
+ if(haveli) {
+ fputs(hbhtml_c8_kw[105], job->of);
+ }
+ haveli = 1;
+ fputs(hbhtml_c8_kw[68], job->of);
+ if(!hbhtml_url_output_for_text(job, pdf)) { back = 0; }
+ fputs(hbhtml_c8_kw[69], job->of);
+ fputs(hbhtml_c8_kw[119], job->of);
+ fputs(hbhtml_c8_kw[40], job->of);
+ if(!hbhtml_output_for_text(job, (job->kwnl)[34])) { back = 0; }
+ fputs(hbhtml_c8_kw[41], job->of);
+ }
+ if(larger) {
+
+#line 2321 "hbhtml.ctr"
+ if(haveli) {
+ fputs(hbhtml_c8_kw[105], job->of);
+ }
+ haveli = 1;
+ fputs(hbhtml_c8_kw[68], job->of);
+ if(!hbhtml_url_output_for_text(job, larger)) { back = 0; }
+ fputs(hbhtml_c8_kw[69], job->of);
+ fputs(hbhtml_c8_kw[40], job->of);
+ if(!hbhtml_output_for_text(job, (job->msg)[58])) { back = 0; }
+ fputs(hbhtml_c8_kw[41], job->of);
+ }
+ if(haveli) {
+ fputs(hbhtml_c8_kw[105], job->of);
+ }
+ fputs(hbhtml_c8_kw[68], job->of);
+ if(!hbhtml_url_output_for_text(job, src)) { back = 0; }
+ fputs(hbhtml_c8_kw[69], job->of);
+ fputs(hbhtml_c8_kw[40], job->of);
+ if(!hbhtml_output_for_text(job, (job->msg)[59])) { back = 0; }
+ fputs(hbhtml_c8_kw[41], job->of);
+ }
+ if(2 == dodiv) {
+ /* !td Close download td */
+ fputs(hbhtml_c8_kw[97], job->of);
+ } else {
+ /* !p Close download p */
+ fputs(hbhtml_c8_kw[113], job->of);
+ }
+ } else {
+ if(2 == dodiv) {
+ } else {
+ fputs(hbhtml_c8_kw[120], job->of);
+ }
+ }
+ if(2 == dodiv) {
+ /* !tr */
+ fputs(hbhtml_c8_kw[95], job->of);
+ /* !table */
+ fputs(hbhtml_c8_kw[93], job->of);
+ /* !div Close outer div */
+ fputs(hbhtml_c8_kw[47], job->of);
+ } else {
+ /* !div Close outer div */
+ fputs(hbhtml_c8_kw[47], job->of);
+ }
+#if 0
+ if(2 == dodiv) {
+ } else {
+ /* Close image div
+ */
+ fputs(hbhtml_c8_kw[47], job->of);
+ if(downlo) {
+ /* Open outer download div */
+ fputs(hbhtml_c8_kw[112], job->of);
+ /* Download links */
+ {
+ haveli = 0;
+ if(svg) {
+
+#line 2379 "hbhtml.ctr"
+ haveli = 1;
+ fputs(hbhtml_c8_kw[68], job->of);
+ if(!hbhtml_url_output_for_text(job, svg)) { back = 0; }
+ fputs(hbhtml_c8_kw[69], job->of);
+ fputs(hbhtml_c8_kw[118], job->of);
+ fputs(hbhtml_c8_kw[40], job->of);
+ if(!hbhtml_output_for_text(job, (job->kwnl)[33])) { back = 0; }
+ fputs(hbhtml_c8_kw[41], job->of);
+ }
+ if(pdf) {
+
+#line 2389 "hbhtml.ctr"
+ if(haveli) {
+ fputs(hbhtml_c8_kw[105], job->of);
+ }
+ haveli = 1;
+ fputs(hbhtml_c8_kw[68], job->of);
+ if(!hbhtml_url_output_for_text(job, pdf)) { back = 0; }
+ fputs(hbhtml_c8_kw[69], job->of);
+ fputs(hbhtml_c8_kw[119], job->of);
+ fputs(hbhtml_c8_kw[40], job->of);
+ if(!hbhtml_output_for_text(job, (job->kwnl)[34])) { back = 0; }
+ fputs(hbhtml_c8_kw[41], job->of);
+ }
+ if(larger) {
+
+#line 2402 "hbhtml.ctr"
+ if(haveli) {
+ fputs(hbhtml_c8_kw[105], job->of);
+ }
+ haveli = 1;
+ fputs(hbhtml_c8_kw[68], job->of);
+ if(!hbhtml_url_output_for_text(job, larger)) { back = 0; }
+ fputs(hbhtml_c8_kw[69], job->of);
+ fputs(hbhtml_c8_kw[40], job->of);
+ if(!hbhtml_output_for_text(job, (job->msg)[58])) { back = 0; }
+ fputs(hbhtml_c8_kw[41], job->of);
+ }
+ if(haveli) {
+ fputs(hbhtml_c8_kw[105], job->of);
+ }
+ fputs(hbhtml_c8_kw[68], job->of);
+ if(!hbhtml_url_output_for_text(job, src)) { back = 0; }
+ fputs(hbhtml_c8_kw[69], job->of);
+ fputs(hbhtml_c8_kw[40], job->of);
+ if(!hbhtml_output_for_text(job, (job->msg)[59])) { back = 0; }
+ fputs(hbhtml_c8_kw[41], job->of);
+ }
+ /* Close output download div */
+ fputs(hbhtml_c8_kw[113], job->of);
+ } else {
+ fputs(hbhtml_c8_kw[120], job->of);
+ }
+ /* Close outer div
+ */
+ fputs(hbhtml_c8_kw[47], job->of);
+ }
+#endif
+ }
+
+ /* Output creation is finished here.
+ Now we add the files to copy to the list.
+ */
+ if(src) { if(!hbtool_add_url(job, src)) { back = 0; } }
+ if(larger) { if(!hbtool_add_url(job, larger)) { back = 0; } }
+ if(pdf) { if(!hbtool_add_url(job, pdf)) { back = 0; } }
+ if(svg) { if(!hbtool_add_url(job, svg)) { back = 0; } }
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 40);
+ }
+
+#line 2446 "hbhtml.ctr"
+ return back;
+}
+
+
+
+/** Write current node item to navigation menu.
+ @param job Job structure.
+ @param nptr Current node.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_link_to_current_node(hb_job_t *job, hb_node_t *nptr)
+{
+ dkChar *p; /* Text to show */
+ int back = 1;
+
+
+#line 2463 "hbhtml.ctr"
+ p = nptr->shorttitle;
+ if(!(p)) { p = nptr->title; }
+ if(p) {
+ fputs(hbhtml_c8_kw[34], job->of);
+ if(nptr->title) {
+ fputs(hbhtml_c8_kw[7], job->of);
+ if(hbtool_write_header_number(job, nptr)) {
+ fputs(hbhtml_c8_kw[1], job->of);
+ }
+ if(!hbhtml_output_for_text(job, nptr->title)) { back = 0; }
+ fputs(hbhtml_c8_kw[5], job->of);
+ }
+ fputs(hbhtml_c8_kw[3], job->of);
+ if (!hbhtml_output_for_text(job, p)) { back = 0; }
+ fputs(hbhtml_c8_kw[35], job->of);
+ } else {
+ back = 0;
+
+#line 2480 "hbhtml.ctr"
+ }
+
+#line 2481 "hbhtml.ctr"
+ return back;
+}
+
+
+
+/** Write opening link tag to HTML output.
+ @param job Job structure.
+ @param cl Class name.
+ @param ti Title.
+ @param dp Destination.
+ @param tp Type (optional).
+ @param nptr Current node.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_write_link_start(
+ hb_job_t *job,
+ char const *cl,
+ dkChar const *ti,
+ dkChar const *dp,
+ dkChar const *tp,
+ hb_node_t *nptr
+)
+{
+ int back = 0;
+
+
+#line 2508 "hbhtml.ctr"
+ if(dp) {
+ back = 1;
+ fputs(hbhtml_c8_kw[39], job->of);
+ if(!(hbhtml_url_output_for_text(job, dp))) {
+ back = 0;
+
+#line 2513 "hbhtml.ctr"
+ }
+ fputs(hbhtml_c8_kw[42], job->of);
+ if(cl) {
+ fputs(hbhtml_c8_kw[43], job->of);
+ if(EOF == fputs(cl, job->of)) { back = 0; }
+ fputs(hbhtml_c8_kw[42], job->of);
+ }
+ if(ti) {
+ fputs(hbhtml_c8_kw[44], job->of);
+ if(hbtool_write_header_number(job, nptr)) {
+ fputs(hbhtml_c8_kw[1], job->of);
+ }
+ if(!(hbhtml_output_for_text(job, ti))) {
+ back = 0;
+
+#line 2527 "hbhtml.ctr"
+ }
+ fputs(hbhtml_c8_kw[42], job->of);
+ }
+ if(tp) {
+ fputs(hbhtml_c8_kw[45], job->of);
+ if(!(hbhtml_output_for_text(job, tp))) {
+ back = 0;
+
+#line 2534 "hbhtml.ctr"
+ }
+ fputs(hbhtml_c8_kw[42], job->of);
+ }
+ fputs(hbhtml_c8_kw[40], job->of);
+ }
+
+#line 2539 "hbhtml.ctr"
+ return back;
+}
+
+
+
+/** Write closing link tag.
+ @param job Job structure.
+*/
+static
+void
+hbhtml_write_link_end(hb_job_t *job)
+{
+ fputs(hbhtml_c8_kw[41], job->of);
+
+
+#line 2553 "hbhtml.ctr"
+}
+
+
+
+
+/** Write a link to HTML output.
+ @param job Job structure.
+ @param cl Class name.
+ @param ti Title.
+ @param dp Destination.
+ @param tp Type (optional).
+ @param tx Link text.
+ @param nptr Current node.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_write_link(
+ hb_job_t *job,
+ char const *cl,
+ dkChar const *ti,
+ dkChar const *dp,
+ dkChar const *tp,
+ dkChar const *tx,
+ hb_node_t *nptr
+)
+{
+ int back = 0;
+
+
+#line 2582 "hbhtml.ctr"
+ if((tx) && (dp)) {
+ back = 1;
+ if(!(hbhtml_write_link_start(job, cl, ti, dp, tp, nptr))) {
+ back = 0;
+
+#line 2586 "hbhtml.ctr"
+ }
+ if(!(hbhtml_output_for_text(job, tx))) {
+ back = 0;
+
+#line 2589 "hbhtml.ctr"
+ }
+ hbhtml_write_link_end(job);
+ }
+
+#line 2592 "hbhtml.ctr"
+ return back;
+}
+
+
+
+int
+hbhtml_create_output_filename(
+ dkChar *dptr,
+ size_t sz,
+ hb_job_t *job,
+ hb_node_t *nptr
+)
+{
+ dkChar const *sptr; /* Suffix for output file */
+ dkChar *p1; /* Suffix position */
+ size_t nsz; /* Summary length name + new suffix */
+ int back = 0;
+
+
+#line 2610 "hbhtml.ctr"
+ if (nptr) {
+ dptr[0] = dkT('\0');
+ if(0UL == nptr->objno) {
+
+#line 2613 "hbhtml.ctr"
+ if(dk3str_len((job->kwnl)[8]) < sz) {
+ dk3str_cpy(dptr, (job->kwnl)[8]);
+ back = 1;
+ } else {
+ /* ERROR: Name too long! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 65, 66, (job->kwnl)[8]);
+ }
+ } else {
+
+#line 2621 "hbhtml.ctr"
+ if(nptr->filename) {
+
+#line 2622 "hbhtml.ctr"
+ if(dk3str_len(nptr->filename) < sz) {
+
+#line 2623 "hbhtml.ctr"
+ dk3str_cpy(dptr, nptr->filename);
+ p1 = dk3str_get_suffix(dptr);
+ if(p1) {
+ p1++;
+ *p1 = dkT('\0');
+ if(nptr->suffix) {
+ sptr = nptr->suffix;
+ } else {
+ sptr = (job->kwnl)[10];
+ }
+ nsz = dk3str_len(dptr) + dk3str_len(sptr);
+ if(nsz < sz) {
+ dk3str_cat(dptr, sptr);
+ back = 1;
+ } else {
+
+#line 2638 "hbhtml.ctr"
+ /* ERROR: File name too long! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 65, 66, nptr->filename);
+ }
+ } else {
+ if(nptr->suffix) {
+ sptr = nptr->suffix;
+ } else {
+ sptr = (job->kwnl)[10];
+ }
+ nsz = dk3str_len(dptr)+dk3str_len(sptr)+dk3str_len((job->kwnl)[9]);
+ if(nsz < sz) {
+ dk3str_cat(dptr, (job->kwnl)[9]);
+ dk3str_cat(dptr, sptr);
+ back = 1;
+ } else {
+
+#line 2653 "hbhtml.ctr"
+ /* File name too long! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 65, 66, nptr->filename);
+ }
+ }
+ } else {
+
+#line 2658 "hbhtml.ctr"
+ /* ERROR: Input file name too long! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 65, 66, nptr->filename);
+ }
+ } else {
+
+#line 2662 "hbhtml.ctr"
+ /* ERROR: No source file name! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 24);
+ }
+ }
+ } else {
+
+#line 2667 "hbhtml.ctr"
+ }
+
+
+#line 2669 "hbhtml.ctr"
+ return back;
+}
+
+
+
+/** Write link to one node to navigation menu.
+ @param job Job structure.
+ @param nptr Node to link to.
+ @param bold Flag: Make link bold.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_link_to_node(hb_job_t *job, hb_node_t *nptr, int bold)
+{
+ dkChar bu[DK3_MAX_PATH]; /* Buffer for destination name */
+ hb_node_t *jnode; /* Link jump destination */
+ dkChar *p1; /* Link title (full) */
+ dkChar *p2; /* Link title (short or full) */
+ int back = 0;
+
+
+#line 2690 "hbhtml.ctr"
+ jnode = nptr;
+ if(!(nptr->filename)) {
+ jnode = nptr->jumpnode;
+ }
+ p1 = nptr->title;
+ p2 = ((nptr->shorttitle) ? (nptr->shorttitle) : (nptr->title));
+ if((p1) && (p2)) {
+ if(jnode) {
+ if(hbhtml_create_output_filename(bu, DK3_SIZEOF(bu,dkChar), job, jnode)) {
+ fputs(hbhtml_c8_kw[36], job->of);
+ back = hbhtml_write_link(
+ job, hbhtml_c8_kw[(bold) ? 144 : 38], p1, bu, NULL, p2, nptr
+ );
+ fputs(hbhtml_c8_kw[37], job->of);
+ }
+ } else {
+ /* ERROR: No text node! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 52, 53, nptr->title);
+ }
+ }
+
+#line 2710 "hbhtml.ctr"
+ return back;
+}
+
+
+
+/** Write the menu entries for a node.
+ @param job Job structure.
+ @param nptr Node to write menu entries for.
+ @param sepreq Flag: Menu separator required.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_menu_entries_for_node(hb_job_t *job, hb_node_t *nptr, int sepreq)
+{
+ hb_node_t *subnode; /* Current node */
+ hb_node_t *jnptr; /* Jump node for subnode */
+ int active; /* Flag: Active node */
+ int sepdone = 0; /* Flag: Separator done */
+ int bold = 0; /* Flag: Make bold */
+ int back = 1;
+
+
+#line 2732 "hbhtml.ctr"
+ if(nptr) {
+
+#line 2733 "hbhtml.ctr"
+ dk3sto_it_reset(nptr->i_subnodes);
+ while(NULL != (subnode = (hb_node_t *)dk3sto_it_next(nptr->i_subnodes))) {
+ jnptr = subnode;
+ if(!(jnptr->filename)) { jnptr = jnptr->jumpnode; }
+ if(sepreq) {
+ if(!(sepdone)) {
+ sepdone = 1;
+ fputs(hbhtml_c8_kw[33], job->of);
+ }
+ }
+
+#line 2743 "hbhtml.ctr"
+ active = 1;
+ bold = 0;
+#if VERSION_BEFORE_20140109
+ if(nptr->curchild) {
+ if(((nptr->curchild)->objno) == (subnode->objno)) {
+ active = 0;
+ }
+ }
+#else
+ if(job->currentnode) {
+ if(jnptr) {
+ if(jnptr->objno == (job->currentnode)->objno) {
+ active = 0;
+ }
+ }
+ }
+ if(nptr->curchild) {
+ if(((nptr->curchild)->objno) == (subnode->objno)) {
+ bold = 1;
+ }
+ }
+#endif
+ if(active) {
+ hbhtml_link_to_node(job, subnode, bold);
+ } else {
+ hbhtml_link_to_current_node(job, subnode);
+ }
+ }
+ }
+
+#line 2772 "hbhtml.ctr"
+ return back;
+}
+
+
+
+/** Check whether a node has sub menu items.
+ @param ptr Node to check.
+ @return 1 if sub items are present, 0 otherwise.
+*/
+static
+int
+hbhtml_have_sub_menu_items(hb_node_t *ptr)
+{
+ int back = 0;
+
+
+#line 2787 "hbhtml.ctr"
+ dk3sto_it_reset(ptr->i_subnodes);
+ while(NULL != dk3sto_it_next(ptr->i_subnodes)) {
+ back = 1;
+ }
+
+#line 2791 "hbhtml.ctr"
+ return back;
+}
+
+
+
+/** Process menu special command.
+ @param job Job structure.
+ @param pa Special command arguments.
+ @return 1 on success, 0 on error (continue), -1 on error (exit).
+*/
+static
+int
+hbhtml_process_sp_menu(hb_job_t *job, dkChar *pa)
+{
+ dk3_key_value_t kv[10]; /* Key value pairs */
+ hb_node_t *mnptr; /* Menu node pointer */
+ size_t sz; /* Size of kv */
+ size_t i; /* Traverse kv */
+ int res; /* Result from writing link */
+ int sep = 0; /* Flag: Need separator */
+ int tv = 0; /* Test value */
+ int mnst = 0; /* Menu style (full) */
+ int sub = 1; /* Include sub menu of current node */
+ int back = 1;
+
+
+#line 2816 "hbhtml.ctr"
+ sz = DK3_SIZEOF(kv,dk3_key_value_t);
+ if(dk3str_to_key_value(kv, &sz, pa, job->app)) {
+ for(i = 0; i < sz; i++) {
+ if(kv[i].key) {
+ switch(dk3str_array_abbr(hbhtml_menu_keys, kv[i].key, dkT('$'), 0)) {
+ case 0: {
+ if(kv[i].val) {
+ tv = dk3str_array_abbr(hbhtml_menu_styles,kv[i].val,dkT('$'),0);
+ if(0 <= tv) {
+ mnst = tv;
+ } else {
+ /* ERROR: Illegal menu style */
+ dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,25,26,kv[i].val);
+ }
+ }
+ } break;
+ case 1: {
+ if(kv[i].val) {
+ sub = ((dk3str_is_on(kv[i].val)) ? 1 : 0);
+ } else {
+ sub = 1;
+ }
+ } break;
+ default: {
+ /* ERROR: Illegal key. */
+ dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,27,26,kv[i].key);
+ } break;
+ }
+ }
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 40);
+ }
+
+#line 2849 "hbhtml.ctr"
+ if(((job->currentnode)->options) & HB_NODE_OPT_IMPRESSUM) {
+ /* When we are writing the menu for the impressum page,
+ we print the top menu only.
+ */
+ mnst = 3;
+ sub = 0;
+ }
+
+#line 2856 "hbhtml.ctr"
+ fputs(hbhtml_c8_kw[29], job->of);
+ fputs(hbhtml_c8_kw[31], job->of);
+ /* Impressum node first, separator.
+ */
+ if(job->impressumnode) {
+
+#line 2861 "hbhtml.ctr"
+ if(((job->currentnode)->options) & HB_NODE_OPT_IMPRESSUM) {
+ if(!hbhtml_link_to_current_node(job, job->impressumnode)) {
+ back = 0;
+
+#line 2864 "hbhtml.ctr"
+ }
+ } else {
+ if(!hbhtml_link_to_node(job, job->impressumnode, 0)) {
+ back = 0;
+
+#line 2868 "hbhtml.ctr"
+ }
+ }
+ /* Separator */
+ fputs(hbhtml_c8_kw[33], job->of);
+ } else {
+ if(job->impressumlink) {
+
+#line 2874 "hbhtml.ctr"
+ fputs(hbhtml_c8_kw[36], job->of);
+ res = hbhtml_write_link(
+ job, hbhtml_c8_kw[38], (job->msg)[0], job->impressumlink,
+ NULL, (job->msg)[0], NULL
+ );
+ fputs(hbhtml_c8_kw[37], job->of);
+ if(!(res)) {
+ back = 0;
+
+#line 2882 "hbhtml.ctr"
+ }
+ /* Separator */
+ fputs(hbhtml_c8_kw[33], job->of);
+ } else {
+
+#line 2886 "hbhtml.ctr"
+ }
+ }
+ /* Now real menu(s)
+ 0=reverse, 1=full, 2=current, 3=top
+ */
+ mnptr = job->currentnode;
+ if(mnptr) {
+
+#line 2893 "hbhtml.ctr"
+ switch(mnst) {
+ case -1: case 0: case 2: {
+
+#line 2895 "hbhtml.ctr"
+ if(sub) {
+ if(hbhtml_have_sub_menu_items(mnptr)) {
+
+#line 2897 "hbhtml.ctr"
+ /* Menu for mnptr without leading space */
+
+
+#line 2899 "hbhtml.ctr"
+ hbhtml_menu_entries_for_node(job, mnptr, 0);
+ sep = 1;
+ }
+ }
+ mnptr = mnptr->parent;
+ if(mnptr) {
+ /* Menu for mnptr with leading space */
+
+
+#line 2907 "hbhtml.ctr"
+ hbhtml_menu_entries_for_node(job, mnptr, sep);
+ if(2 != mnst) {
+
+#line 2909 "hbhtml.ctr"
+ do {
+ mnptr = mnptr->parent;
+ if(mnptr) {
+ /* Menu for mnptr with leading space */
+
+
+#line 2914 "hbhtml.ctr"
+ hbhtml_menu_entries_for_node(job, mnptr, 1);
+ }
+ } while(mnptr);
+ }
+ }
+ } break;
+ case 1: case 3: {
+
+#line 2921 "hbhtml.ctr"
+ if(((job->currentnode)->options) & HB_NODE_OPT_IMPRESSUM) {
+ mnptr = job->rootnode;
+ sub = 0;
+ } else {
+ while(mnptr->parent) { mnptr = mnptr->parent; }
+ }
+ /* Menu for mnptr without leading space */
+
+
+#line 2929 "hbhtml.ctr"
+ hbhtml_menu_entries_for_node(job, mnptr, 0);
+ if(1 == mnst) {
+
+#line 2931 "hbhtml.ctr"
+ do {
+ mnptr = mnptr->curchild;
+ if(mnptr) {
+ if(mnptr->curchild) {
+ /* Menu for mnptr with leading space */
+
+
+#line 2937 "hbhtml.ctr"
+ hbhtml_menu_entries_for_node(job, mnptr, 1);
+ } else {
+ if(sub) {
+ /* Menu entry from current node */
+
+
+#line 2942 "hbhtml.ctr"
+ hbhtml_menu_entries_for_node(job, mnptr, 1);
+ }
+ }
+ }
+ } while(mnptr);
+ }
+ } break;
+ }
+ }
+ fputs(hbhtml_c8_kw[32], job->of);
+ fputs(hbhtml_c8_kw[30], job->of);
+
+#line 2953 "hbhtml.ctr"
+ return back;
+}
+
+
+
+/** Write image with link for one navigation icon.
+ @param job Job structure.
+ @param iconfile Icon file name.
+ @param dest Destination URL.
+ @param titlea1 Title part 1 when icon link is active.
+ @param titlea2 Title part 2 when icon link is active.
+ @param titlena Title when icon is not active.
+ @param act Flag: Link is active.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_one_navi_icon(
+ hb_job_t *job,
+ dkChar const *iconfile,
+ dkChar const *dest,
+ dkChar const *titlea1,
+ dkChar const *titlea2,
+ dkChar const *titlena,
+ int act
+)
+{
+ int back = 1;
+ unsigned long w = 0UL; /* Icon width */
+ unsigned long h = 0UL; /* Icon height */
+
+
+#line 2984 "hbhtml.ctr"
+
+
+#line 2985 "hbhtml.ctr"
+
+
+#line 2986 "hbhtml.ctr"
+
+
+#line 2987 "hbhtml.ctr"
+
+
+#line 2988 "hbhtml.ctr"
+
+
+#line 2989 "hbhtml.ctr"
+
+
+#line 2990 "hbhtml.ctr"
+ if(act) {
+
+#line 2991 "hbhtml.ctr"
+ fputs(hbhtml_c8_kw[49], job->of);
+ if(!(hbhtml_url_output_for_text(job, dest))) {
+ back = 0;
+ }
+
+#line 2995 "hbhtml.ctr"
+ fputs(hbhtml_c8_kw[50], job->of);
+ if(!(hbhtml_output_for_text(job, titlea1))) {
+ back = 0;
+ }
+
+#line 2999 "hbhtml.ctr"
+ if(titlea2) {
+ if(!(hbhtml_output_for_text(job, titlea2))) {
+ back = 0;
+ }
+ }
+
+#line 3004 "hbhtml.ctr"
+ fputs(hbhtml_c8_kw[51], job->of);
+ fputs(hbhtml_c8_kw[53], job->of);
+ if(!(hbhtml_url_output_for_text(job, iconfile))) {
+ back = 0;
+ }
+
+#line 3009 "hbhtml.ctr"
+ fputs(hbhtml_c8_kw[54], job->of);
+ if(!(hbhtml_output_for_text(job, titlea1))) {
+ back = 0;
+ }
+
+#line 3013 "hbhtml.ctr"
+ if(titlea2) {
+ if(!(hbhtml_output_for_text(job, titlea2))) {
+ back = 0;
+ }
+ }
+ fputs(hbhtml_c8_kw[55], job->of);
+ if(!(hbhtml_output_for_text(job, titlea1))) {
+ back = 0;
+ }
+
+#line 3022 "hbhtml.ctr"
+ if(titlea2) {
+ if(!(hbhtml_output_for_text(job, titlea2))) {
+ back = 0;
+ }
+ }
+ fputs(hbhtml_c8_kw[56], job->of);
+ if(hbimgdim_find(job, iconfile, &w, &h, 1)) {
+ if((w) && (h)) {
+ fprintf(job->of, hbhtml_c8_kw[67], w, h);
+ }
+ }
+ fputs(hbhtml_c8_kw[3], job->of);
+ fputs(hbhtml_c8_kw[52], job->of);
+
+#line 3035 "hbhtml.ctr"
+ } else {
+
+#line 3036 "hbhtml.ctr"
+ fputs(hbhtml_c8_kw[53], job->of);
+ if(!(hbhtml_url_output_for_text(job, iconfile))) {
+ back = 0;
+ }
+
+#line 3040 "hbhtml.ctr"
+ fputs(hbhtml_c8_kw[54], job->of);
+ if(!(hbhtml_output_for_text(job, titlea1))) {
+ back = 0;
+ }
+
+#line 3044 "hbhtml.ctr"
+ if(titlea2) {
+ if(!(hbhtml_output_for_text(job, titlea2))) {
+ back = 0;
+ }
+ }
+ fputs(hbhtml_c8_kw[55], job->of);
+ if(!(hbhtml_output_for_text(job, titlena))) {
+ back = 0;
+ }
+
+#line 3053 "hbhtml.ctr"
+ fputs(hbhtml_c8_kw[56], job->of);
+ if(hbimgdim_find(job, iconfile, &w, &h, 1)) {
+ if((w) && (h)) {
+ fprintf(job->of, hbhtml_c8_kw[67], w, h);
+ }
+ }
+ fputs(hbhtml_c8_kw[3], job->of);
+ }
+
+#line 3061 "hbhtml.ctr"
+ return back;
+}
+
+
+
+/** Process special command to build navigation div.
+ @param job Job structure.
+ @param pa Programm arguments (ignored).
+ @param p Previous node.
+ @param n Next node.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_process_sp_navigation(
+ hb_job_t *job,
+ dkChar *pa,
+ hb_node_t *p,
+ hb_node_t *n
+)
+{
+ dk3_key_value_t kv[10]; /* Command parameters */
+ dkChar bu[DK3_MAX_PATH]; /* Construct file name */
+ hb_node_t *nptr; /* Current node */
+ dkChar const *itop = NULL; /* TOC icon name */
+ dkChar const *iprev = NULL; /* Previous icon name */
+ dkChar const *inext = NULL; /* Next icon name */
+ dkChar const *ihome = NULL; /* Home icon name */
+ dkChar const *ikind = NULL; /* Index icon name */
+ dkChar const *ta1; /* Icon image title, node */
+ dkChar const *ta2; /* Icon image title */
+ dkChar const *tna; /* Icon image title start */
+ size_t sz; /* Number of command params */
+ size_t szurl; /* URL length */
+ size_t i; /* Traverse command params */
+ int res; /* Result create one icon */
+ int kind = 0; /* Flag: Keyword index */
+ int ptoc = 0; /* Flag: TOC */
+ int back = 1;
+
+
+#line 3101 "hbhtml.ctr"
+ sz = DK3_SIZEOF(kv,dk3_key_value_t);
+ if(dk3str_to_key_value(kv, &sz, pa, job->app)) {
+ for(i = 0; i < sz; i++) {
+ if(kv[i].key) {
+ switch(dk3str_array_abbr(hbhtml_navi_keys, kv[i].key, dkT('$'), 0)) {
+ case 0: {
+ itop = kv[i].val;
+ } break;
+ case 1: {
+ iprev = kv[i].val;
+ } break;
+ case 2: {
+ inext = kv[i].val;
+ } break;
+ case 3: {
+ ikind = kv[i].val;
+ } break;
+ case 4: {
+ ihome = kv[i].val;
+ } break;
+ }
+ }
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 40);
+ }
+ nptr = job->currentnode;
+ kind = (((job->options) & HB_JOB_OPT_CREATE_INDEX) ? 1 : 0);
+ ptoc = (((job->options) & HB_JOB_OPT_CREATE_TOC) ? 1 : 0);
+ while(
+ (nptr)
+ && (
+ !(
+ ((itop) || (!(ptoc)))
+ && (ihome)
+ && (iprev) && (inext)
+ && ((ikind) || (!(kind)))
+ )
+ )
+ )
+ {
+ if(!(itop)) itop = nptr->icontoc;
+ if(!(iprev)) iprev = nptr->iconprev;
+ if(!(inext)) inext = nptr->iconnext;
+ if(!(ikind)) ikind = nptr->iconindex;
+ if(!(ihome)) ihome = nptr->iconhome;
+ nptr = nptr->parent;
+ }
+
+
+#line 3150 "hbhtml.ctr"
+ if(!(itop)) itop = (job->kwnl)[14];
+ if(!(iprev)) iprev = (job->kwnl)[15];
+ if(!(inext)) inext = (job->kwnl)[16];
+ if(!(ikind)) ikind = (job->kwnl)[17];
+ if(!(ihome)) ihome = (job->kwnl)[37];
+
+
+#line 3156 "hbhtml.ctr"
+ if(
+ ((itop) || (!(ptoc)))
+ && (iprev) && (inext) && (ihome)
+ && ((ikind) || (!(kind)))
+ )
+ {
+ back = 1;
+ if(itop) { if(!hbtool_add_file(job, itop)) { back = 0; } }
+ if(iprev) { if(!hbtool_add_file(job, iprev)) { back = 0; } }
+ if(inext) { if(!hbtool_add_file(job, inext)) { back = 0; } }
+ if(ikind) { if(!hbtool_add_file(job, ikind)) { back = 0; } }
+ if(ihome) { if(!hbtool_add_file(job, ihome)) { back = 0; } }
+ fputs(hbhtml_c8_kw[46], job->of);
+
+ /* HOME */
+
+#line 3171 "hbhtml.ctr"
+ ta1 = (job->msg)[1];
+ ta2 = (job->rootnode)->title;
+ tna = (job->msg)[2];
+ res = hbhtml_create_output_filename(
+ bu, DK3_SIZEOF(bu,dkChar), job, job->rootnode
+ );
+ if(res) {
+
+#line 3178 "hbhtml.ctr"
+
+
+#line 3179 "hbhtml.ctr"
+ res = hbhtml_one_navi_icon(
+ job, ihome, bu, ta1, ta2, tna,
+ (
+ (0 != job->currentnode->havenavimenu)
+ ? (1)
+ : (((0UL == (job->currentnode)->objno) ? 0 : 1))
+ )
+ );
+ if(!(res)) { back = 0; }
+
+
+#line 3189 "hbhtml.ctr"
+ } else {
+
+#line 3190 "hbhtml.ctr"
+ back = 0;
+ }
+ /* Previous */
+
+#line 3193 "hbhtml.ctr"
+ ta1 = (job->msg)[3];
+ ta2 = NULL;
+ if(p) ta2 = p->title;
+ tna = (job->msg)[4];
+ if(p) {
+ res = hbhtml_create_output_filename(
+ bu, DK3_SIZEOF(bu,dkChar), job, p
+ );
+ if(res) {
+ fputs(hbhtml_c8_kw[48], job->of);
+ res = hbhtml_one_navi_icon(job, iprev, bu, ta1, ta2, tna, 1);
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ } else {
+ fputs(hbhtml_c8_kw[48], job->of);
+ res = hbhtml_one_navi_icon(job, iprev, NULL, ta1, ta2, tna, 0);
+ if(!(res)) { back = 0; }
+ }
+ /* Next */
+
+#line 3214 "hbhtml.ctr"
+ ta1 = (job->msg)[5];
+ ta2 = NULL;
+ if(n) ta2 = n->title;
+ tna = (job->msg)[6];
+ if(n) {
+ res = hbhtml_create_output_filename(
+ bu, DK3_SIZEOF(bu,dkChar), job, n
+ );
+ if(res) {
+ fputs(hbhtml_c8_kw[48], job->of);
+ res = hbhtml_one_navi_icon(job, inext, bu, ta1, ta2, tna, 1);
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ } else {
+ fputs(hbhtml_c8_kw[48], job->of);
+ res = hbhtml_one_navi_icon(job, inext, NULL, ta1, ta2, tna, 0);
+ if(!(res)) { back = 0; }
+ }
+ /* TOC */
+
+#line 3235 "hbhtml.ctr"
+ if(ptoc) {
+ ta1 = (job->msg)[93];
+ ta2 = (job->rootnode)->title;
+ tna = (job->msg)[94];
+ res = hbhtml_create_output_filename(
+ bu, DK3_SIZEOF(bu,dkChar), job, job->rootnode
+ );
+ if(res) {
+
+#line 3243 "hbhtml.ctr"
+ szurl = dk3str_len(bu);
+ szurl += dk3str_len((job->kwnl)[31]);
+ if(szurl < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cat(bu, (job->kwnl)[31]);
+ } else {
+ back = 0;
+ }
+
+
+#line 3251 "hbhtml.ctr"
+ fputs(hbhtml_c8_kw[48], job->of);
+ res = hbhtml_one_navi_icon(job, itop, bu, ta1, ta2, tna, 1);
+ if(!(res)) { back = 0; }
+
+
+#line 3255 "hbhtml.ctr"
+ } else {
+
+#line 3256 "hbhtml.ctr"
+ back = 0;
+ }
+ }
+ /* Key index */
+ if(kind) {
+
+#line 3261 "hbhtml.ctr"
+ ta1 = (job->msg)[7];
+ ta2 = NULL;
+ tna = NULL;
+ res = hbhtml_create_output_filename(
+ bu, DK3_SIZEOF(bu,dkChar), job, job->rootnode
+ );
+ if(res) {
+ if(dk3str_len(bu)+dk3str_len((job->kwnl)[13]) < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cat(bu, (job->kwnl)[13]);
+ fputs(hbhtml_c8_kw[48], job->of);
+ res = hbhtml_one_navi_icon(job, ikind, bu, ta1, ta2, tna, 1);
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ } else {
+ back = 0;
+ }
+ }
+ fputs(hbhtml_c8_kw[47], job->of);
+ job->currentnode->havenavimenu = 1;
+
+
+#line 3283 "hbhtml.ctr"
+ } else {
+
+#line 3284 "hbhtml.ctr"
+
+
+#line 3285 "hbhtml.ctr"
+
+
+#line 3286 "hbhtml.ctr"
+
+
+#line 3287 "hbhtml.ctr"
+
+
+#line 3288 "hbhtml.ctr"
+
+
+#line 3289 "hbhtml.ctr"
+ }
+
+
+#line 3291 "hbhtml.ctr"
+ return back;
+}
+
+
+
+/** Process author special command.
+ @param job Job structure.
+ @param pa Program arguments.
+ @return 1 on success, 0 on error (continue), -1 on error (exit).
+*/
+static
+int
+hbhtml_process_sp_author(hb_job_t *job, dkChar *pa)
+{
+ dkChar const *ptr; /* Author name */
+ int back = 0;
+
+
+#line 3308 "hbhtml.ctr"
+ ptr = hbconf_author(job->currentnode);
+ if(ptr) {
+ if(hbhtml_output_for_text(job, ptr)) {
+ back = 1;
+ }
+ }
+
+#line 3314 "hbhtml.ctr"
+ return back;
+}
+
+
+
+/** Process location special command.
+ @param job Job structure.
+ @param pa Program arguments.
+ @return 1 on success, 0 on error (continue), -1 on error (exit).
+*/
+static
+int
+hbhtml_process_sp_location(hb_job_t *job, dkChar *pa)
+{
+ dkChar const *ptr; /* Location name */
+ int back = 0;
+
+
+#line 3331 "hbhtml.ctr"
+ ptr = hbconf_location(job->currentnode);
+ if(ptr) {
+ if(hbhtml_output_for_text(job, ptr)) {
+ back = 1;
+ }
+ }
+
+#line 3337 "hbhtml.ctr"
+ return back;
+}
+
+
+
+/** Process date special command.
+ @param job Job structure.
+ @param pa Program arguments.
+ @return 1 on success, 0 on error (continue), -1 on error (exit).
+*/
+static
+int
+hbhtml_process_sp_date(hb_job_t *job, dkChar *pa)
+{
+ dk3_key_value_t kv[5]; /* Command parameters */
+ size_t sz; /* Number of command paramters */
+ size_t i; /* Traverse command paramters */
+ int german = 0; /* Flag: German style date */
+ int back = 1;
+
+
+#line 3357 "hbhtml.ctr"
+ sz = DK3_SIZEOF(kv,dk3_key_value_t);
+ if(dk3str_to_key_value(kv,&sz,pa,job->app)) {
+
+#line 3359 "hbhtml.ctr"
+ for(i = 0; i < sz; i++) {
+
+#line 3360 "hbhtml.ctr"
+ if(kv[i].key) {
+
+#line 3361 "hbhtml.ctr"
+ switch(dk3str_array_abbr(hbhtml_date_keys, kv[i].key, dkT('$'), 0)) {
+ case 0: {
+ if(kv[i].val) {
+ if(0 == dk3str_casecmp((job->kwnl)[11], kv[i].val)) {
+ german = 1;
+
+#line 3366 "hbhtml.ctr"
+ } else {
+ german = 0;
+
+#line 3368 "hbhtml.ctr"
+ }
+ }
+ } break;
+ default: {
+ /* ERROR: Illegal attribute! */
+ dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,27,26,kv[i].key);
+ back = 0;
+
+#line 3375 "hbhtml.ctr"
+ } break;
+ }
+ }
+ }
+ } else {
+
+#line 3380 "hbhtml.ctr"
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 40);
+ }
+ if(german) {
+ fprintf(
+ job->of, "%02d.%02d.%04d",
+ (job->starttime).D, (job->starttime).M, (job->starttime).Y
+ );
+ } else {
+ fprintf(
+ job->of, "%04d-%02d-%02d",
+ (job->starttime).Y, (job->starttime).M, (job->starttime).D
+ );
+ }
+
+#line 3393 "hbhtml.ctr"
+ return back;
+}
+
+
+
+/** Process special command to show variable.
+ @param job Job structure.
+ @param pa Pointer to arguments.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_process_sp_variable(hb_job_t *job, dkChar *pa)
+{
+ dk3_key_value_t kv[5]; /* Argument pairs */
+ dkChar const *varname; /* Variable name. */
+ dkChar const *varval; /* Variable value */
+ size_t sz; /* Size of kv */
+ size_t i; /* Traverse kv */
+ int urlm = 0; /* Flag: URL mode */
+ int back = 1;
+
+
+#line 3415 "hbhtml.ctr"
+ sz = DK3_SIZEOF(kv,dk3_key_value_t);
+ if(dk3str_to_key_value(kv,&sz,pa,job->app)) {
+ if(sz > 0) {
+ varname = kv[0].key;
+ for(i = 1; i < sz; i++) {
+ if(kv[i].key) {
+ if(dk3str_casecmp((job->kwnl)[12], kv[i].key) == 0) {
+ if(kv[i].val) {
+ urlm = ((dk3str_is_on(kv[i].val)) ? 1 : 0);
+ } else {
+ urlm = 1;
+ }
+ } else {
+ back = 0;
+
+#line 3429 "hbhtml.ctr"
+ /* ERROR: Illegal argument */
+ dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,27,26,kv[i].key);
+ }
+ }
+ }
+ varval = hbnode_variable(job->currentnode, varname);
+ if(varval) {
+ if(urlm) {
+ if(!hbhtml_url_output_for_text(job, varval)) {
+ back = 0;
+
+#line 3439 "hbhtml.ctr"
+ }
+ } else {
+ if(!hbhtml_output_for_text(job, varval)) {
+ back = 0;
+
+#line 3443 "hbhtml.ctr"
+ }
+ }
+ }
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 40);
+ }
+
+#line 3450 "hbhtml.ctr"
+ return back;
+}
+
+
+
+/** Process contents of one file.
+ @param job Job structure.
+ @param p Previous node.
+ @param n Next node.
+ @return 1 on success, 0 on error (can continue), -1 on error (exit).
+*/
+static
+int
+hbhtml_process_sp_contents(hb_job_t *job, hb_node_t *p, hb_node_t *n)
+{
+ int back = 1;
+ job->spused = 0;
+ job->shipused = 0;
+
+
+#line 3469 "hbhtml.ctr"
+ if(job->currentnode) {
+
+#line 3470 "hbhtml.ctr"
+ if((job->currentnode)->filename) {
+
+#line 3471 "hbhtml.ctr"
+ back = hbcont_process(job, p, n);
+ } else {
+
+#line 3473 "hbhtml.ctr"
+ if(0UL == (job->currentnode)->objno) {
+
+#line 3474 "hbhtml.ctr"
+ back = hbcont_process(job, p, n);
+ } else {
+
+#line 3476 "hbhtml.ctr"
+ }
+ }
+ }
+
+#line 3479 "hbhtml.ctr"
+ return back;
+}
+
+
+
+/** Open code tag for line number.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_coli_open(hb_job_t *job)
+{
+ int back = 1;
+ if (EOF == fputs(hbhtml_c8_kw[146], job->of)) { back = 0; }
+ if (1000 > job->coli) {
+ if (0 > fprintf(job->of, "%03d", job->coli)) { back = 0; }
+ job->coli += 1;
+ if (1000 == job->coli) {
+ back = 0;
+ /* WARNING: Too many code lines */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 88);
+ }
+ } else {
+ back = 0;
+ fputs(hbhtml_c8_kw[149], job->of);
+ }
+ if (EOF == fputs(hbhtml_c8_kw[147], job->of)) { back = 0; }
+ return back;
+}
+
+
+
+/** Close code tag for line number.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_coli_close(hb_job_t *job)
+{
+ int back = 1;
+ if (EOF == fputs(hbhtml_c8_kw[148], job->of)) { back = 0; }
+ return back;
+}
+
+
+
+/** Output dummy code line to avoid trimming emptry code tag.
+ @param job Job structure.
+ @return 1 on success, 0 on error
+*/
+static
+int
+hbhtml_coli_dummy(hb_job_t *job)
+{
+ int back = 1;
+ if (!hbhtml_coli_open(job)) { back = 0; }
+ if (EOF == fputs(hbhtml_c8_kw[150], job->of)) { back = 0; }
+ if (!hbhtml_coli_close(job)) { back = 0; }
+ return back;
+}
+
+
+
+/** Start of a code line found.
+ Invoked from the input line handler.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_code_line_start(hb_job_t *job)
+{
+ int back = 1;
+ if (((job->options) & HB_JOB_OPT_CODE) && (0 < job->coli)) {
+ switch (job->cols) {
+ case HB_COLIST_NONE: {
+ if (!hbhtml_coli_open(job)) { back = 0; }
+ job->cols = HB_COLIST_OPENED;
+ } break;
+ case HB_COLIST_NOT_OPENED: {
+ if (!hbhtml_coli_open(job)) { back = 0; }
+ job->cols = HB_COLIST_OPENED;
+ } break;
+#if 0
+ case HB_COLIST_OPENED: {
+ } break;
+#endif
+ }
+ }
+ return back;
+}
+
+
+
+/** Finalize a code line.
+ Invoked from the input line handler.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_code_line_end(hb_job_t *job)
+{
+ int back = 1;
+ if (((job->options) & HB_JOB_OPT_CODE) && (0 < job->coli)) {
+ switch (job->cols) {
+ case HB_COLIST_NONE: {
+ job->cols = HB_COLIST_NOT_OPENED;
+ } break;
+ case HB_COLIST_NOT_OPENED: {
+ if (!hbhtml_coli_dummy(job)) { back = 0; }
+ } break;
+ case HB_COLIST_OPENED: {
+ if (!hbhtml_coli_close(job)) { back = 0; }
+ job->cols = HB_COLIST_NOT_OPENED;
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+/** Start code line numbering.
+ Invoked from the input line handler.
+ Invoked from the code special command.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_start_code_line_numbers(hb_job_t *job)
+{
+ int back = 1;
+ job->coli = 1;
+ job->cols = HB_COLIST_NONE;
+ return back;
+}
+
+
+
+/** End code line numbering if it was started.
+ Invoked from the code special command.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_end_code_line_numbers(hb_job_t *job)
+{
+ int back = 1;
+ if (((job->options) & HB_JOB_OPT_CODE) && (0 < job->coli)) {
+ switch (job->cols) {
+ case HB_COLIST_OPENED: {
+ if (EOF == fputs(hbhtml_c8_kw[148], job->of)) { back = 0; }
+ } break;
+ }
+ }
+ job->coli = 0;
+ job->cols = HB_COLIST_NONE;
+ return back;
+}
+
+
+
+/** Process the code special command.
+ @param job Job structure.
+ @param pa Arguments
+*/
+static
+void
+hbhtml_process_sp_code(hb_job_t *job, dkChar *pa)
+{
+ dk3_key_value_t kv[10]; /* Command paramters */
+ size_t sz; /* Number of command parameters */
+ size_t i; /* Process all command parameters */
+ int act = 0; /* Action to take */
+ int lineno = 0; /* Flag: Write line numbers */
+
+
+
+#line 3661 "hbhtml.ctr"
+
+ /* Get configuration defaults
+ */
+ if ((job->options) & HB_JOB_OPT_CODE_LINE_NUMBERS) {
+ lineno = 1;
+ }
+
+ /* Use command options
+ */
+ sz = DK3_SIZEOF(kv,dk3_key_value_t);
+ if(dk3str_to_key_value(kv,&sz,pa,job->app)) {
+ if(sz > 0) {
+ for(i = 0; i < sz; i++) {
+ if(kv[i].key) {
+ switch(dk3str_array_abbr(hbhtml_code_keys, kv[i].key, dkT('$'), 0)) {
+ case 0: case 1: {
+ if(kv[i].val) {
+ if(dk3str_is_bool(kv[i].val)) {
+ if(dk3str_is_on(kv[i].val)) {
+ act = 1;
+ } else {
+ act = 2;
+ }
+ } else {
+ act = 1;
+ }
+ } else {
+ act = 1;
+ }
+ } break;
+ case 2: case 3: {
+ if(kv[i].val) {
+ if(dk3str_is_bool(kv[i].val)) {
+ if(dk3str_is_on(kv[i].val)) {
+ act = 2;
+ } else {
+ act = 1;
+ }
+ } else {
+ act = 2;
+ }
+ } else {
+ act = 2;
+ }
+ } break;
+ case 4: {
+ act = 0;
+ } break;
+ case 5: {
+ if (kv[i].val) {
+ if (dk3str_is_bool(kv[i].val)) {
+ lineno = ((dk3str_is_on(kv[i].val)) ? 1 : 0);
+ } else {
+ /* Warning: Not a boolean */
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, kv[i].val);
+ }
+ } else {
+ lineno = 1;
+ }
+ } break;
+ }
+ }
+ }
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 40);
+ }
+
+ /* Finish open code line numbering.
+ */
+ (void)hbhtml_end_code_line_numbers(job);
+
+ /* Turn code mode on or off.
+ */
+ switch(act) {
+ case 0: {
+ if((job->options) & HB_JOB_OPT_CODE) {
+ job->options &= (~(HB_JOB_OPT_CODE));
+ } else {
+ job->options |= HB_JOB_OPT_CODE;
+ if (lineno) {
+ (void)hbhtml_start_code_line_numbers(job);
+ }
+ }
+ } break;
+ case 1: {
+ job->options |= HB_JOB_OPT_CODE;
+ if (lineno) {
+ (void)hbhtml_start_code_line_numbers(job);
+ }
+ } break;
+ case 2: {
+ job->options &= (~(HB_JOB_OPT_CODE));
+ } break;
+ }
+
+#line 3756 "hbhtml.ctr"
+}
+
+
+
+#if 0
+static
+int
+hbhtml_check_link_for_external(dkChar *link, hb_job_t *job)
+{
+ size_t sz;
+ int back = 0;
+ if(link) {
+ sz = dk3str_len(link);
+ if(sz >= dk3str_len((job->kwnl)[20])) {
+ if(0 == dk3str_ncmp(link, (job->kwnl)[20], dk3str_len((job->kwnl)[20]))) {
+ back = 1;
+ }
+ }
+ if(sz >= dk3str_len((job->kwnl)[21])) {
+ if(0 == dk3str_ncmp(link, (job->kwnl)[21], dk3str_len((job->kwnl)[21]))) {
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+#endif
+
+
+
+int
+hbhtml_check_link_for_external(dkChar const *link)
+{
+ dkChar const *ptr; /* Traverse string */
+ dkChar c; /* Current character */
+ int stm3; /* State machine for traversal */
+ int i; /* Input classification */
+ int back = 0;
+
+
+#line 3795 "hbhtml.ctr"
+ hbhtml_stm3_reset(&stm3);
+ ptr = link;
+ while(*ptr) {
+ c = *(ptr++);
+ i = STM3_I_ANY;
+ switch(c) {
+ case dkT(':'): {
+ i = STM3_I_COLON;
+ } break;
+ case dkT('/'): {
+ i = STM3_I_SLASH;
+ } break;
+ case dkT('_'): {
+ i = STM3_I_ASCII;
+ } break;
+ default: {
+ if((dkT('a') <= c) && (dkT('z') >= c)) {
+ i = STM3_I_ASCII;
+ } else {
+ if((dkT('A') <= c) && (dkT('Z') >= c)) {
+ i = STM3_I_ASCII;
+ } else {
+ if((dkT('0') <= c) && (dkT('9') >= c)) {
+ i = STM3_I_ASCII;
+ }
+ }
+ }
+ } break;
+ }
+ hbhtml_stm3_step(&stm3, i);
+ }
+ if(STM3_ST_SUCCESS == stm3) {
+ back = 1;
+ }
+
+#line 3829 "hbhtml.ctr"
+ return back;
+}
+
+
+
+/** Process special command to build a link.
+ @param job Job structure.
+ @param pa Program arguments.
+ @return 1 on success, 0 on error (continue), -1 on error (exit).
+*/
+static
+int
+hbhtml_process_sp_a(hb_job_t *job, dkChar *pa)
+{
+ dk3_key_value_t kv[25]; /* Command parameters */
+ hb_link_t *linkptr; /* Link data for URL */
+ hb_node_t *nptr; /* Current node */
+ dkChar *text = NULL; /* Link text */
+ dkChar *title = NULL; /* Link title */
+ dkChar *accessk = NULL; /* Accesskey argument */
+ dkChar *charset = NULL; /* Charset argument */
+ dkChar *coords = NULL; /* Coords argument */
+ dkChar *href = NULL; /* href argument */
+ dkChar *hrefl = NULL; /* hreflang argument */
+ dkChar *name = NULL; /* name argument */
+ dkChar *onblur = NULL; /* onblur argument */
+ dkChar *onfocus = NULL; /* onfocus argument */
+ dkChar *rel = NULL; /* rel argument */
+ dkChar *rev = NULL; /* rev argument */
+ dkChar *shape = NULL; /* shape argument */
+ dkChar *tabind = NULL; /* tabindex argument */
+ dkChar *target = NULL; /* target argument */
+ dkChar *type = NULL; /* type argument */
+ dkChar *clptr = NULL; /* class argument */
+ dkChar *idptr = NULL; /* id argument */
+ dkChar *style = NULL; /* style argument */
+ size_t sz; /* Number of parameters */
+ size_t i; /* Traverse parameters */
+ int external = 0; /* Flag: External link */
+ int extspec = 0; /* Flag: External specified */
+ int titlespec = 0; /* Flag: Title specified */
+ int back = 0;
+
+
+#line 3872 "hbhtml.ctr"
+ nptr = job->currentnode;
+ sz = DK3_SIZEOF(kv,dk3_key_value_t);
+ if(dk3str_to_key_value(kv,&sz,pa,job->app)) {
+ if(sz > 0) {
+ for(i = 0; i < sz; i++) {
+ if(kv[i].key) {
+ switch(dk3str_array_abbr(hbhtml_a_keys, kv[i].key, dkT('$'), 0)) {
+ case 0: {
+
+#line 3880 "hbhtml.ctr"
+ text = kv[i].val;
+ } break;
+ case 1: {
+
+#line 3883 "hbhtml.ctr"
+ title = kv[i].val; titlespec = 1;
+ } break;
+ case 2: {
+
+#line 3886 "hbhtml.ctr"
+ accessk = kv[i].val;
+ } break;
+ case 3: {
+
+#line 3889 "hbhtml.ctr"
+ charset = kv[i].val;
+ } break;
+ case 4: {
+
+#line 3892 "hbhtml.ctr"
+ coords = kv[i].val;
+ } break;
+ case 5: {
+
+#line 3895 "hbhtml.ctr"
+ href= kv[i].val;
+ } break;
+ case 6: {
+
+#line 3898 "hbhtml.ctr"
+ hrefl = kv[i].val;
+ } break;
+ case 7: {
+
+#line 3901 "hbhtml.ctr"
+ name = kv[i].val;
+ } break;
+ case 8: {
+
+#line 3904 "hbhtml.ctr"
+ onblur = kv[i].val;
+ } break;
+ case 9: {
+
+#line 3907 "hbhtml.ctr"
+ onfocus = kv[i].val;
+ } break;
+ case 10: {
+
+#line 3910 "hbhtml.ctr"
+ rel = kv[i].val;
+ } break;
+ case 11: {
+
+#line 3913 "hbhtml.ctr"
+ rev = kv[i].val;
+ } break;
+ case 12: {
+
+#line 3916 "hbhtml.ctr"
+ shape = kv[i].val;
+ } break;
+ case 13: {
+
+#line 3919 "hbhtml.ctr"
+ tabind = kv[i].val;
+ } break;
+ case 14: {
+
+#line 3922 "hbhtml.ctr"
+ target = kv[i].val;
+ } break;
+ case 15: {
+
+#line 3925 "hbhtml.ctr"
+ type = kv[i].val;
+ } break;
+ case 16: {
+
+#line 3928 "hbhtml.ctr"
+ clptr = kv[i].val;
+ } break;
+ case 17: {
+
+#line 3931 "hbhtml.ctr"
+ idptr = kv[i].val;
+ } break;
+ case 18: {
+
+#line 3934 "hbhtml.ctr"
+ style = kv[i].val;
+ } break;
+ case 19: {
+ if(kv[i].val) {
+ if(dk3str_is_bool(kv[i].val)) {
+ if(dk3str_is_on(kv[i].val)) {
+ external = 1; extspec = 1;
+ } else {
+ external = 0; extspec = 1;
+ }
+ }
+ } else {
+ external = 1; extspec = 1;
+ }
+ } break;
+ default: {
+ dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,27,26,kv[i].key);
+ } break;
+ }
+ }
+ }
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 40);
+ }
+ if(href) {
+ if(!(extspec)) {
+ external = hbhtml_check_link_for_external(href);
+ }
+ if(titlespec) {
+ if(!(title)) { title = text; }
+ if(!(title)) { title = href; }
+ }
+ back = 1;
+ } else {
+ if(name) {
+ back = 1;
+ }
+ }
+ if(back) {
+ /* Write <a...> */
+ if(href) {
+ fputs(hbhtml_c8_kw[39], job->of);
+ if(!hbhtml_url_output_for_text(job, href)) { back = 0; }
+ } else {
+ fputs(hbhtml_c8_kw[74], job->of);
+ if(!hbhtml_url_output_for_text(job, name)) { back = 0; }
+ }
+ if(target) {
+ fputs(hbhtml_c8_kw[75], job->of);
+ if(!hbhtml_url_output_for_text(job, target)) { back = 0; }
+ } else {
+ if(external) {
+ fputs(hbhtml_c8_kw[108], job->of);
+ }
+ }
+ if(type) {
+ fputs(hbhtml_c8_kw[76], job->of);
+ if(!hbhtml_url_output_for_text(job, type)) { back = 0; }
+ }
+ fputs(hbhtml_c8_kw[77], job->of);
+ if(clptr) {
+ if(!hbhtml_url_output_for_text(job, clptr)) { back = 0; }
+ } else {
+ if(external) {
+ fputs(hbhtml_c8_kw[101], job->of);
+ } else {
+ fputs(hbhtml_c8_kw[100], job->of);
+ }
+ }
+ if(idptr) {
+ fputs(hbhtml_c8_kw[78], job->of);
+ if(!hbhtml_url_output_for_text(job, idptr)) { back = 0; }
+ }
+ if(style) {
+ fputs(hbhtml_c8_kw[79], job->of);
+ if(!hbhtml_url_output_for_text(job, style)) { back = 0; }
+ }
+ if(hrefl) {
+ fputs(hbhtml_c8_kw[80], job->of);
+ if(!hbhtml_url_output_for_text(job, hrefl)) { back = 0; }
+ }
+ if(title) {
+ fputs(hbhtml_c8_kw[81], job->of);
+ if(!hbhtml_output_for_text(job, title)) { back = 0; }
+ }
+ if(onblur) {
+ fputs(hbhtml_c8_kw[82], job->of);
+ if(!hbhtml_url_output_for_text(job, onblur)) { back = 0; }
+ }
+ if(onfocus) {
+ fputs(hbhtml_c8_kw[83], job->of);
+ if(!hbhtml_url_output_for_text(job, onfocus)) { back = 0; }
+ }
+ if(rel) {
+ fputs(hbhtml_c8_kw[84], job->of);
+ if(!hbhtml_url_output_for_text(job, rel)) { back = 0; }
+ }
+ if(rev) {
+ fputs(hbhtml_c8_kw[85], job->of);
+ if(!hbhtml_url_output_for_text(job, rev)) { back = 0; }
+ }
+ if(shape) {
+ fputs(hbhtml_c8_kw[86], job->of);
+ if(!hbhtml_url_output_for_text(job, shape)) { back = 0; }
+ }
+ if(tabind) {
+ fputs(hbhtml_c8_kw[87], job->of);
+ if(!hbhtml_url_output_for_text(job, tabind)) { back = 0; }
+ }
+ if(accessk) {
+ fputs(hbhtml_c8_kw[88], job->of);
+ if(!hbhtml_url_output_for_text(job, accessk)) { back = 0; }
+ }
+ if(charset) {
+ fputs(hbhtml_c8_kw[89], job->of);
+ if(!hbhtml_url_output_for_text(job, charset)) { back = 0; }
+ }
+ if(coords) {
+ fputs(hbhtml_c8_kw[90], job->of);
+ if(!hbhtml_url_output_for_text(job, coords)) { back = 0; }
+ }
+ fputs(hbhtml_c8_kw[5], job->of);
+ fputs(hbhtml_c8_kw[3], job->of);
+ if(href) {
+ if(text) {
+ if(!hbhtml_output_for_text(job, text)) { back = 0; }
+ } else {
+ if(!hbhtml_output_for_text(job, href)) { back = 0; }
+ }
+ }
+ fputs(hbhtml_c8_kw[41], job->of);
+ if((href) && (external) && (text)) {
+ /* Save link and write link number */
+ linkptr = dk3sto_it_find_like(nptr->i_lbyurl, href, 1);
+ if(linkptr) {
+ fprintf(job->of, hbhtml_c8_kw[91], (1UL + linkptr->lno));
+ } else {
+ linkptr = hbnode_link_new(href, nptr->nextlink, job->app);
+ if(linkptr) {
+ if(dk3sto_add(nptr->s_lbyurl, linkptr)) {
+ nptr->nextlink += 1UL;
+ if(dk3sto_add(nptr->s_lbylno, linkptr)) {
+ fprintf(job->of, hbhtml_c8_kw[91], (1UL + linkptr->lno));
+ } else {
+ back = 0;
+ }
+ } else {
+ back = 0;
+ hbnode_link_delete(linkptr);
+ linkptr = NULL;
+ }
+ } else {
+ back = 0;
+ }
+ }
+ }
+ if((!(href)) && (name)) {
+ if(text) {
+ if(!hbhtml_output_for_text(job, text)) { back = 0; }
+ }
+ }
+ if(href) {
+ if(!hbtool_add_url(job, href)) { back = 0; }
+ }
+ }
+
+#line 4100 "hbhtml.ctr"
+ return back;
+}
+
+
+
+/** Process menuentry special command.
+ @param job Job structure.
+ @param pa Arguments.
+ @return 1 on success, 0 on error (continue), -1 on error (exit).
+*/
+static
+int
+hbhtml_process_sp_menuentry(hb_job_t *job, dkChar *pa)
+{
+ dk3_key_value_t kv[20]; /* Command parameters */
+ dkChar *items[DK3_SIZEOF(kv,dk3_key_value_t)];
+ size_t sz; /* Number of command parameters */
+ size_t i; /* Traverse command parameters */
+ size_t n_items = 0; /* number of items */
+ size_t cr; /* Current item index */
+ int back = 0;
+
+
+#line 4122 "hbhtml.ctr"
+ sz = DK3_SIZEOF(kv,dk3_key_value_t);
+ if(dk3str_to_key_value(kv,&sz,pa,job->app)) {
+ if(sz > 0) {
+ for(i = 0; i < sz; i++) {
+ if(kv[i].key) {
+ switch(dk3str_array_abbr(hbhtml_menuentry_keys,kv[i].key,dkT('$'),0))
+ {
+ case 0: {
+ if(kv[i].val) {
+ if(n_items < DK3_SIZEOF(kv,dk3_key_value_t)) {
+ items[n_items++] = kv[i].val;
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ }
+ }
+ } break;
+ default: {
+ dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,27,26,kv[i].key);
+ back = 0;
+ } break;
+ }
+ }
+ }
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 40);
+ }
+ if(n_items) {
+ back = 1;
+ fputs(hbhtml_c8_kw[92], job->of);
+ if(!hbhtml_output_for_text(job, (job->msg)[60])) { back = 0; }
+ fputs(hbhtml_c8_kw[22], job->of);
+ for(cr = 0; cr < n_items; cr++) {
+ fputs(hbhtml_c8_kw[94], job->of);
+ if(cr) {
+ for(i = 0; i < (cr - 1); i++) {
+ fputs(hbhtml_c8_kw[98], job->of);
+ }
+ fputs(hbhtml_c8_kw[99], job->of);
+ fprintf(job->of, hbhtml_c8_kw[96], (unsigned)(n_items - cr));
+ if(!hbhtml_output_for_text(job, items[cr])) { back = 0; }
+ fputs(hbhtml_c8_kw[97], job->of);
+ } else {
+ fprintf(job->of, hbhtml_c8_kw[96], (unsigned)n_items);
+ if(!hbhtml_output_for_text(job, items[cr])) { back = 0; }
+ fputs(hbhtml_c8_kw[97], job->of);
+ }
+ fputs(hbhtml_c8_kw[95], job->of);
+ }
+ fputs(hbhtml_c8_kw[93], job->of);
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 42);
+ }
+
+#line 4175 "hbhtml.ctr"
+ return back;
+}
+
+
+
+/** Process index special command.
+ @param job Job structure.
+ @param pa Program arguments.
+ @return 1 on success, 0 on error (continue), -1 on error (exit).
+*/
+static
+int
+hbhtml_process_sp_index(hb_job_t *job, dkChar *pa)
+{
+ dk3_key_value_t kv[10]; /* Command parameters */
+ hb_node_t *nptr; /* Current node */
+ hb_index_entry_t *indptr; /* New index entry item */
+ dkChar *text = NULL; /* Text for index entry */
+ dkChar *name = NULL; /* Name for index entry */
+ size_t sz; /* Number of command paramters */
+ size_t i; /* Traverse command parameters */
+ int refer = 0; /* Flag: Refer to existing entry */
+ int back = 0;
+
+
+#line 4199 "hbhtml.ctr"
+ nptr = job->currentnode;
+ sz = DK3_SIZEOF(kv,dk3_key_value_t);
+ if(dk3str_to_key_value(kv,&sz,pa,job->app)) {
+ if(sz > 0) {
+ for(i = 0; i < sz; i++) {
+ if(kv[i].key) {
+ switch(dk3str_array_abbr(hbhtml_index_keys, kv[i].key, dkT('$'), 0)) {
+ case 0: {
+ text = kv[i].val;
+ } break;
+ case 1: {
+ name = kv[i].val;
+ } break;
+ case 2: {
+ if(kv[i].val) {
+ if(dk3str_is_bool(kv[i].val)) {
+ if(dk3str_is_on(kv[i].val)) {
+ refer = 1;
+ } else {
+ refer = 0;
+ }
+ } else {
+ /* ERROR: Not a boolean */
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, kv[i].val);
+ }
+ } else {
+ refer = 1;
+ }
+ } break;
+ }
+ }
+ }
+ if(text) {
+ if((job->options) & HB_JOB_OPT_CREATE_INDEX) {
+ indptr = hbindex_new(
+ text, nptr->outFileName, name, nptr->nextindex, job->app, nptr
+ );
+ if(indptr) {
+ if(dk3sto_add(job->s_index, indptr)) {
+ back = 1;
+ nptr->nextindex += 1UL;
+ if(!((name) && (refer))) {
+ fputs(hbhtml_c8_kw[74], job->of);
+ if(!hb_index_write_anchor(job, indptr)) { back = 0; }
+ fputs(hbhtml_c8_kw[51], job->of);
+ fputs(hbhtml_c8_kw[52], job->of);
+ }
+ } else {
+ hbindex_delete(indptr);
+ }
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ /* ERROR: Missing text attribute! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 48);
+ }
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 40);
+ }
+
+#line 4261 "hbhtml.ctr"
+ return back;
+}
+
+
+
+/** Handle one source code line.
+ @param obj Job structure.
+ @param il Input line.
+ @return 1 on success, 0 on error (continue), -1 on error (exit).
+*/
+static
+int
+hbhtml_sourcefile_line_handler(void *obj, dkChar *il)
+{
+ hb_job_t *job;
+ int back = 1;
+
+ job = (hb_job_t *)obj;
+ dk3str_delnl(il);
+
+
+#line 4281 "hbhtml.ctr"
+ if (job->coli) {
+ if (0 < dk3str_len(il)) {
+ if (!hbhtml_coli_open(job)) { back = 0; }
+ if(!hbhtml_output_for_text(job, il)) { back = 0; }
+ if (!hbhtml_coli_close(job)) { back = 0; }
+ } else {
+ if (!hbhtml_coli_dummy(job)) { back = 0; }
+ }
+ } else {
+ if(!hbhtml_output_for_text(job, il)) { back = 0; }
+ }
+ fputc('\n', job->of);
+
+
+#line 4294 "hbhtml.ctr"
+ return back;
+}
+
+
+
+/** Process sourcefile special command.
+ @param job Job structure.
+ @param pa Program arguemnts.
+ @return 1 on success, 0 on error (continue), -1 on error (exit).
+*/
+static
+int
+html_process_sp_sourcefile(hb_job_t *job, dkChar *pa)
+{
+ dkChar bu[4096]; /* Buffer for source file lines */
+ dk3_key_value_t kv[10]; /* Command parameters */
+ dkChar *file = NULL; /* Input file */
+ dkChar *type = NULL; /* Type argument */
+ dkChar *title = NULL; /* Title argument */
+ size_t sz; /* Number of command parameters */
+ size_t i; /* Traverse command parameters */
+ int lineno = 0; /* Flag: Write line numbers */
+ int back = 0;
+ int res; /* Result from processing file */
+ int oldcode; /* Old code flag value */
+
+
+#line 4320 "hbhtml.ctr"
+ if ((job->options) & HB_JOB_OPT_CODE_LINE_NUMBERS) {
+ lineno = 1;
+ }
+ sz = DK3_SIZEOF(kv,dk3_key_value_t);
+ if(dk3str_to_key_value(kv, &sz, pa, job->app)) {
+ if(sz > 0) {
+ for(i = 0; i < sz; i++) {
+ if(kv[i].key) {
+ switch(dk3str_array_abbr(hbhtml_sourcef_keys,kv[i].key,dkT('$'),0)) {
+ case 0: {
+ file = kv[i].val;
+ } break;
+ case 1: {
+ type = kv[i].val;
+ } break;
+ case 2: {
+ title = kv[i].val;
+ } break;
+ case 3: {
+ if (kv[i].val) {
+ if (dk3str_is_bool(kv[i].val)) {
+ lineno = ((dk3str_is_on(kv[i].val)) ? 1 : 0);
+ } else {
+ /* WARNING: Not a boolean */
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, kv[i].val);
+ }
+ } else {
+ lineno = 1;
+ }
+ } break;
+ }
+ }
+ }
+ }
+ if(file) {
+ back = 1;
+ if(hbtool_add_file(job, file)) {
+ fputs(hbhtml_c8_kw[102], job->of);
+ fputs(hbhtml_c8_kw[103], job->of);
+ if(!hbhtml_url_output_for_text(job, file)) { back = 0; }
+ fputs(hbhtml_c8_kw[81], job->of);
+ if(title) {
+ if(!hbhtml_output_for_text(job, title)) { back = 0; }
+ } else {
+ if(!hbhtml_output_for_text(job, file)) { back = 0; }
+ }
+ fputs(hbhtml_c8_kw[76], job->of);
+ if(type) {
+ if(!hbhtml_output_for_text(job, type)) { back = 0; }
+ } else {
+ fputs(hbhtml_c8_kw[104], job->of);
+ }
+ fputs(hbhtml_c8_kw[51], job->of);
+ if(!hbhtml_output_for_text(job, file)) { back = 0; }
+ fputs(hbhtml_c8_kw[52], job->of);
+ fputs(hbhtml_c8_kw[105], job->of);
+ fputs(hbhtml_c8_kw[106], job->of);
+ oldcode = (((job->options) & HB_JOB_OPT_CODE) ? 1 : 0);
+ job->options |= HB_JOB_OPT_CODE;
+ job->coli = ((lineno) ? 1 : 0);
+ res = dk3stream_process_filename_lines_app(
+ (void *)job, hbhtml_sourcefile_line_handler, file,
+ bu, DK3_SIZEOF(bu,dkChar),
+ dk3app_get_encoding(job->app),
+ dk3app_get_input_file_encoding(job->app),
+ job->app
+ );
+ job->coli = 0;
+ if(!(res)) { back = 0; }
+ if(oldcode) {
+ job->options |= HB_JOB_OPT_CODE;
+ } else {
+ job->options &= (~(HB_JOB_OPT_CODE));
+ }
+ fputs(hbhtml_c8_kw[107], job->of);
+ fputs(hbhtml_c8_kw[47], job->of);
+ } else {
+ back = 0;
+ }
+ } else {
+ /* ERROR: No file name specified! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 49);
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 40);
+ }
+
+#line 4406 "hbhtml.ctr"
+ return back;
+}
+
+
+
+/** Process sourcefile special command.
+ @param job Job structure.
+ @param pa Program arguemnts.
+ @return 1 on success, 0 on error (continue), -1 on error (exit).
+*/
+static
+int
+html_process_sp_htmlname(hb_job_t *job, dkChar *pa)
+{
+ dkChar buf[DK3_MAX_PATH];
+ size_t szbuf = DK3_SIZEOF(buf,dkChar);
+ int back = 0;
+
+
+#line 4424 "hbhtml.ctr"
+ if (NULL != job->currentnode) {
+ if (0 != hbhtml_create_output_filename(buf, szbuf, job, job->currentnode)) {
+ back = hbhtml_url_output_for_text(job, buf);
+ if (0 == back) {
+
+#line 4428 "hbhtml.ctr"
+ job->exv = 1;
+ }
+ } else {
+
+#line 4431 "hbhtml.ctr"
+ job->exv = 1;
+ }
+ } else {
+
+#line 4434 "hbhtml.ctr"
+ }
+
+
+#line 4436 "hbhtml.ctr"
+ return back;
+}
+
+
+
+/** Process sourcefile special command.
+ @param job Job structure.
+ @param pa Program arguemnts.
+ @return 1 on success, 0 on error (continue), -1 on error (exit).
+*/
+static
+int
+html_process_sp_hint(hb_job_t *job, dkChar *pa)
+{
+ dk3_key_value_t kv[30];
+ dkChar *hint_text = NULL;
+ dkChar *hint_title = NULL;
+ size_t sz;
+ size_t i;
+ int back = 0;
+
+ sz = DK3_SIZEOF(kv,dk3_key_value_t);
+ if (0 != dk3str_to_key_value(kv, &sz, pa, job->app)) {
+ for (i = 0; i < sz; i++) {
+ if (NULL != kv[i].key) {
+ switch (dk3str_array_abbr(hbhtml_hint_keys, kv[i].key, dkT('$'), 0)) {
+ case 0: {
+ hint_text = kv[i].val;
+ } break;
+ case 1: {
+ hint_title = kv[i].val;
+ } break;
+ default: {
+ /* Warning: Unusable key */
+ dk3app_log_3(job->app, DK3_LL_WARNING, job->msg, 89, 90, kv[i].key);
+ } break;
+ }
+ }
+ }
+ if (NULL != hint_text) {
+ back = 1;
+ if (NULL != hint_title) {
+ if (EOF == fputs(hbhtml_c8_kw[151], job->of)) {
+ back = 0;
+ }
+ if (0 ==hbhtml_output_for_text(job, hint_title)) {
+ back = 0;
+ }
+ if (EOF == fputs(hbhtml_c8_kw[152], job->of)) {
+ back = 0;
+ }
+ if (0 == hbhtml_output_for_text(job, hint_text)) {
+ back = 0;
+ }
+ if (EOF == fputs(hbhtml_c8_kw[153], job->of)) {
+ back = 0;
+ }
+ }
+ else {
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 92);
+ if (0 == hbhtml_output_for_text(job, hint_text)) {
+ back = 0;
+ }
+ }
+ }
+ else {
+ /* ERROR: No text */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 91);
+ }
+ }
+ else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 40);
+ }
+ if (0 == back) {
+ job->exv = 1;
+ }
+ return back;
+}
+
+
+
+/** Process a special command.
+ @param job Job structure.
+ @param in_template Flag: Processing a template.
+ @param p Previous node.
+ @param n Next node.
+ @return 1 on success, 0 on error (continue), -1 on error (exit).
+*/
+static
+int
+hbhtml_process_special(
+ hb_job_t *job,
+ int in_template,
+ hb_node_t *p,
+ hb_node_t *n
+)
+{
+ dkChar *pc; /* Special command name */
+ dkChar *pa; /* Start of command arguments */
+ dkChar *sc; /* Start of sub command. */
+ int ct; /* Command identifier */
+ int back = 0;
+
+
+#line 4539 "hbhtml.ctr"
+ pc = dk3str_start(job->special, NULL);
+ sc = NULL;
+ if(pc) {
+ pa = dk3str_next(pc, NULL);
+ if(pa) {
+ dk3str_chomp(pa, NULL);
+ }
+ sc = dk3str_chr(pc, dkT('.'));
+ if(sc) { *(sc++) = dkT('\0'); }
+ ct = dk3str_array_index(hbhtml_special_commands, pc, 0);
+
+
+#line 4550 "hbhtml.ctr"
+ switch(ct) {
+ case 0: {
+
+#line 4552 "hbhtml.ctr"
+ if(in_template) {
+ back = hbhtml_process_sp_contents(job, p, n);
+ } else {
+ /* ERROR: Contents special not allowed in contents! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 28);
+ }
+ } break;
+ case 1: {
+
+#line 4560 "hbhtml.ctr"
+ back = hbhtml_process_sp_title(job);
+ if(1 != back) { dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 39); }
+ } break;
+ case 2: {
+
+#line 4564 "hbhtml.ctr"
+ back = hbhtml_process_sp_image(job, pa, sc, in_template);
+ if(1 != back) { dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 39); }
+ } break;
+ case 3: {
+
+#line 4568 "hbhtml.ctr"
+ back = hbhtml_process_sp_menu(job, pa);
+ if(1 != back) { dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 39); }
+ } break;
+ case 4: {
+
+#line 4572 "hbhtml.ctr"
+ back = hbhtml_process_sp_navigation(job, pa, p, n);
+ if(1 != back) { dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 39); }
+ } break;
+ case 5: { /* links */
+ /* #### Probably not */
+ back = 1;
+ } break;
+ case 6: {
+
+#line 4580 "hbhtml.ctr"
+ back = hbhtml_process_sp_author(job, pa);
+ if(1 != back) { dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 39); }
+ } break;
+ case 7: {
+
+#line 4584 "hbhtml.ctr"
+ back = hbhtml_process_sp_location(job, pa);
+ if(1 != back) { dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 39); }
+ } break;
+ case 8: {
+
+#line 4588 "hbhtml.ctr"
+ back = hbhtml_process_sp_date(job, pa);
+ if(1 != back) { dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 39); }
+ } break;
+ case 9: {
+
+#line 4592 "hbhtml.ctr"
+ back = hbhtml_process_sp_variable(job, pa);
+ if(1 != back) { dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 39); }
+ } break;
+ case 10: {
+ hbhtml_process_sp_code(job, pa);
+ back = 1;
+ } break;
+ case 11: {
+ back = hbhtml_process_sp_a(job, pa);
+ if(1 != back) { dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 39); }
+ } break;
+ case 12: {
+ back = hbhtml_process_sp_menuentry(job, pa);
+ if(1 != back) { dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 39); }
+ } break;
+ case 13: {
+ if(0 == in_template) {
+ back = hbhtml_process_sp_index(job, pa);
+ if(1 != back) { dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 39); }
+ } else {
+ /* ERROR: Can not be used in template */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 50);
+ }
+ } break;
+ case 14: {
+ back = html_process_sp_sourcefile(job, pa);
+ if(1 != back) { dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 39); }
+ } break;
+ case 15: {
+ back = html_process_sp_htmlname(job, pa);
+ } break;
+ case 16: {
+ back = html_process_sp_hint(job, pa);
+ } break;
+ default: {
+
+#line 4627 "hbhtml.ctr"
+ back = 0;
+ /* ERROR: Unknown special command. */
+ dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,29,26,pc);
+ } break;
+ }
+ } else {
+ back = 1; /* Empty special */
+ }
+
+
+#line 4636 "hbhtml.ctr"
+ return back;
+}
+
+
+
+int
+hbhtml_line_handler(void *obj, dkChar *il)
+{
+ dkChar xmsg[8]; /* Array for diagnostics */
+ hb_file_processor_t *proc; /* Line processor */
+ hb_job_t *job; /* Job */
+ dkChar *p1; /* Start of input line */
+ size_t pos; /* Non-whitespace position */
+ int i; /* Input classification */
+ int o; /* Reaction from state machine */
+ int ltl = 0; /* Flag: Error from shipout */
+ int back = 1;
+ dkChar c; /* Character to ship out */
+
+
+#line 4655 "hbhtml.ctr"
+ pos = 0;
+ proc = (hb_file_processor_t *)obj;
+ job = proc->job;
+ dk3str_delnl(il);
+ hbhtml_stm1_reset(&(proc->stm));
+ job->shipused = 0;
+ job->spused = 0;
+ p1 = il;
+ while(*p1) {
+ c = *p1;
+ i = hbhtml_classify_for_stm1(c);
+ o = hbhtml_stm1_step(&(proc->stm), i);
+ switch(o) {
+ case STM1_O_ERROR: {
+ /* ERROR: Parse error */
+ dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,30,26,p1);
+ back = -1;
+
+#line 4672 "hbhtml.ctr"
+ } break;
+ case STM1_O_NOTHING: {
+ } break;
+ case STM1_O_SHIPOUT: {
+ if (!hbhtml_code_line_start(job)) { back = 0; }
+ if(!(hbhtml_shipout(job, c))) {
+ back = 0;
+
+#line 4679 "hbhtml.ctr"
+ if(0 == ltl) {
+ ltl = 1;
+ /* ERROR: Line too long! */
+ }
+ }
+ } break;
+ case STM1_O_BS_SHIPOUT: {
+ switch(c) {
+ case dkT('n'): {
+ if (!hbhtml_code_line_start(job)) { back = 0; }
+ if(!(hbhtml_shipout(job, dkT('\n')))) {
+ back = 0;
+
+#line 4691 "hbhtml.ctr"
+ if(0 == ltl) {
+ ltl = 1;
+ /* ERROR: Line too long! */
+ }
+ }
+ } break;
+ case dkT('r'): {
+ if (!hbhtml_code_line_start(job)) { back = 0; }
+ if(!(hbhtml_shipout(job, dkT('\r')))) {
+ back = 0;
+
+#line 4701 "hbhtml.ctr"
+ if(0 == ltl) {
+ ltl = 1;
+ /* ERROR: Line too long! */
+ }
+ }
+ } break;
+ case dkT('t'): {
+ if (!hbhtml_code_line_start(job)) { back = 0; }
+ if(!(hbhtml_shipout(job, dkT('\t')))) {
+ back = 0;
+
+#line 4711 "hbhtml.ctr"
+ if(0 == ltl) {
+ ltl = 1;
+ /* ERROR: Line too long! */
+ }
+ }
+ } break;
+ case dkT('%'): case dkT('\\'): {
+ if (!hbhtml_code_line_start(job)) { back = 0; }
+ if(!(hbhtml_shipout(job, c))) {
+ back = 0;
+
+#line 4721 "hbhtml.ctr"
+ if(0 == ltl) {
+ ltl = 1;
+ /* ERROR: Line too long! */
+ }
+ }
+ } break;
+ case dkT('.'): {
+ /* We can escape a leading dot.
+ */
+ if(1 < pos) {
+ xmsg[0] = dkT('\\');
+ xmsg[1] = c;
+ xmsg[2] = dkT('\0');
+ dk3app_log_3(job->app, DK3_LL_WARNING, job->msg, 63, 64, xmsg);
+ }
+ if (!hbhtml_code_line_start(job)) { back = 0; }
+ if(!(hbhtml_shipout(job, c))) {
+ back = 0;
+
+#line 4739 "hbhtml.ctr"
+ if(0 == ltl) {
+ ltl = 1;
+ /* ERROR: Line too long! */
+ }
+ }
+ } break;
+ default: {
+ xmsg[0] = dkT('\\');
+ xmsg[1] = c;
+ xmsg[2] = dkT('\0');
+ dk3app_log_3(job->app, DK3_LL_WARNING, job->msg, 63, 64, xmsg);
+ if (!hbhtml_code_line_start(job)) { back = 0; }
+ if(!(hbhtml_shipout(job, c))) {
+ back = 0;
+
+#line 4753 "hbhtml.ctr"
+ if(0 == ltl) {
+ ltl = 1;
+ /* ERROR: Line too long! */
+ }
+ }
+ } break;
+ }
+ } break;
+ case STM1_O_PERCENT_SHIPOUT: {
+ if (!hbhtml_code_line_start(job)) { back = 0; }
+ if(!(hbhtml_shipout(job, dkT('%')))) {
+ back = 0;
+
+#line 4765 "hbhtml.ctr"
+ if(0 == ltl) {
+ ltl = 1;
+ }
+ }
+ if(!(hbhtml_shipout(job, c))) {
+ back = 0;
+
+#line 4771 "hbhtml.ctr"
+ if(0 == ltl) {
+ ltl = 1;
+ }
+ }
+ } break;
+ case STM1_O_PERCENT: {
+ if (!hbhtml_code_line_start(job)) { back = 0; }
+ if(!(hbhtml_shipout(job, dkT('%')))) {
+ back = 0;
+
+#line 4780 "hbhtml.ctr"
+ if(0 == ltl) {
+ ltl = 1;
+ }
+ }
+ } break;
+ case STM1_O_SWITCH: {
+ hbhtml_flush_shipout(job);
+ job->spused = 0;
+ } break;
+ case STM1_O_SPECIAL: {
+ if(!hbhtml_add_to_special(job, c)) {
+ back = 0;
+
+#line 4792 "hbhtml.ctr"
+ if(0 == ltl) {
+ ltl = 1;
+ }
+ }
+ } break;
+ case STM1_O_SPEC_BS: {
+ switch(c) {
+ case dkT('n'): {
+ if(!hbhtml_add_to_special(job, dkT('\n'))) {
+ back = 0;
+
+#line 4802 "hbhtml.ctr"
+ if(0 == ltl) {
+ ltl = 1;
+ }
+ }
+ } break;
+ case dkT('r'): {
+ if(!hbhtml_add_to_special(job, dkT('\r'))) {
+ back = 0;
+
+#line 4810 "hbhtml.ctr"
+ if(0 == ltl) {
+ ltl = 1;
+ }
+ }
+ } break;
+ case dkT('t'): {
+ if(!hbhtml_add_to_special(job, dkT('\t'))) {
+ back = 0;
+
+#line 4818 "hbhtml.ctr"
+ if(0 == ltl) {
+ ltl = 1;
+ }
+ }
+ } break;
+ default: {
+ if(!hbhtml_add_to_special(job, c)) {
+ back = 0;
+
+#line 4826 "hbhtml.ctr"
+ if(0 == ltl) {
+ ltl = 1;
+ }
+ }
+ } break;
+ }
+ } break;
+ case STM1_O_SPEC_PC_ADD: {
+ if(!hbhtml_add_to_special(job, dkT('%'))) {
+ back = 0;
+
+#line 4836 "hbhtml.ctr"
+ if(0 == ltl) {
+ ltl = 1;
+ }
+ }
+ if(!hbhtml_add_to_special(job, c)) {
+ back = 0;
+
+#line 4842 "hbhtml.ctr"
+ if(0 == ltl) {
+ ltl = 1;
+ }
+ }
+ } break;
+ case STM1_O_SPEC_PC: {
+ if(!hbhtml_add_to_special(job, dkT('%'))) {
+ back = 0;
+
+#line 4850 "hbhtml.ctr"
+ if(0 == ltl) {
+ ltl = 1;
+ }
+ }
+ } break;
+ case STM1_O_EXECUTE: {
+ if((job->spused) < (job->bs)) {
+ (job->special)[job->spused] = dkT('\0');
+ back = hbhtml_process_special(job,proc->in_template,proc->p,proc->n);
+ } else {
+ back = 0;
+
+#line 4861 "hbhtml.ctr"
+ if(0 == ltl) {
+ ltl = 1;
+ }
+ }
+ job->spused = 0;
+ job->shipused = 0;
+ } break;
+ }
+ p1++;
+ if((dkT(' ') != c) && (dkT('\t') != c)) {
+ pos++;
+ }
+ }
+ switch(proc->stm) {
+ case STM1_ST_BS: {
+ if (!hbhtml_code_line_start(job)) { back = 0; }
+ if(!(hbhtml_shipout(job, dkT('\\')))) {
+ back = 0;
+ if(0 == ltl) { ltl = 1; }
+ }
+ } break;
+ case STM1_ST_PERCENT: {
+ if (!hbhtml_code_line_start(job)) { back = 0; }
+ if(!(hbhtml_shipout(job, dkT('%')))) {
+ back = 0;
+ if(0 == ltl) { ltl = 1; }
+ }
+ } break;
+ case STM1_ST_SPECIAL: case STM1_ST_SPEC_BS: case STM1_ST_SPEC_PC: {
+ /* ERROR: Unfinished special command! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 62);
+ back = 0;
+ } break;
+ }
+ if(ltl) {
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 31, 26, il);
+ }
+ hbhtml_flush_shipout(job);
+ if (!hbhtml_code_line_end(job)) { back = 0; }
+ if (EOF == fputc('\n', job->of)) {
+ back = 0;
+
+#line 4902 "hbhtml.ctr"
+ }
+
+
+#line 4904 "hbhtml.ctr"
+ return back;
+}
+
+
+
+/** Write JS files to HTML header.
+ @param job Job structure.
+ @param nptr
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_write_js_files(hb_job_t *job, hb_node_t *nptr)
+{
+ hb_link_t *linkptr; /* File name data for JavaScript file */
+ int back = 1;
+ /* Write parent JS files.
+ */
+ if(nptr->parent) {
+ if(!((nptr->options) & HB_NODE_OPT_STOP_JS_INHERITANCE)) {
+ hbhtml_write_js_files(job, nptr->parent);
+ }
+ }
+
+ /* Write node JS files.
+ */
+ if((nptr->s_jsfiles) && (nptr->i_jsfiles)) {
+ dk3sto_it_reset(nptr->i_jsfiles);
+ while(NULL != (linkptr = (hb_link_t *)dk3sto_it_next(nptr->i_jsfiles))) {
+ if(linkptr->url) {
+ fputs(hbhtml_c8_kw[121], job->of);
+ if(!hbhtml_url_output_for_text(job, linkptr->url)) { back = 0; }
+ fputs(hbhtml_c8_kw[122], job->of);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Write one head navigation entry.
+ @param job Job structure.
+ @param nptr Node (may be NULL for impressum).
+ @param url URL to use if nptr is NULL.
+ @param titleind Title index if nptr is NULL.
+ @param linkkwind Link keyword index.
+ @param appendind Index for keyword index.
+*/
+static
+void
+hbhtml_one_head_navigation(
+ hb_job_t *job,
+ hb_node_t *nptr,
+ dkChar const *url,
+ size_t titleind,
+ size_t linkkwind,
+ size_t appendind
+)
+{
+ dkChar bu[DK3_MAX_PATH]; /* Buffer for output file name */
+ hb_node_t *jnptr; /* Jump node */
+
+ if(nptr) {
+ jnptr = nptr;
+ if(!(jnptr->filename)) { jnptr = jnptr->jumpnode; }
+ if(hbhtml_create_output_filename(bu, DK3_SIZEOF(bu,dkChar), job, jnptr)) {
+ fputs(hbhtml_c8_kw[123], job->of);
+ fputs(hbhtml_c8_kw[linkkwind], job->of);
+ fputs(hbhtml_c8_kw[124], job->of);
+ if(!hbhtml_output_for_text(job, jnptr->title)) { job->exv = 1; }
+ fputs(hbhtml_c8_kw[125], job->of);
+ if(!hbhtml_url_output_for_text(job, bu)) { job->exv = 1; }
+ if(appendind) {
+ fputs(hbhtml_c8_kw[appendind], job->of);
+ }
+ fputs(hbhtml_c8_kw[126], job->of);
+ } else {
+ job->exv = 1;
+ }
+ } else {
+ fputs(hbhtml_c8_kw[123], job->of);
+ fputs(hbhtml_c8_kw[linkkwind], job->of);
+ fputs(hbhtml_c8_kw[124], job->of);
+ if(!hbhtml_output_for_text(job, (job->msg)[titleind])) { job->exv = 1; }
+ fputs(hbhtml_c8_kw[125], job->of);
+ if(!hbhtml_url_output_for_text(job, url)) { job->exv = 1; }
+ if(appendind) {
+ fputs(hbhtml_c8_kw[appendind], job->of);
+ }
+ fputs(hbhtml_c8_kw[126], job->of);
+ }
+}
+
+
+
+/** Write navigation entries to HTML header.
+ @param job Job structure.
+ @param node Current node to write.
+ @param prev Previous node.
+ @param next Next node.
+*/
+static
+void
+hbhtml_write_head_navigation(
+ hb_job_t *job,
+ hb_node_t *node,
+ hb_node_t *prev,
+ hb_node_t *next
+)
+{
+ hb_node_t *nptr; /* Current node to process */
+
+ /* Navigation (links)
+ author (impressum), contents, index, top, up, first, prev, next, last
+ link rel="..." title="..." href="..."
+ */
+ if(job->impressumnode) {
+ nptr = job->impressumnode;
+ hbhtml_one_head_navigation(job, nptr, NULL, 0, 127, 0);
+ } else {
+ if(job->impressumlink) {
+ hbhtml_one_head_navigation(job, NULL, job->impressumlink, 61, 127, 0);
+ }
+ }
+ if(job->rootnode) {
+ hbhtml_one_head_navigation(
+ job, job->rootnode, NULL, 0, 128,
+ (((job->options) & HB_JOB_OPT_CREATE_TOC) ? 136 : 0)
+ );
+ hbhtml_one_head_navigation(
+ job, job->rootnode, NULL, 0, 129,
+ (((job->options) & HB_JOB_OPT_CREATE_INDEX) ? 137 : 0)
+ );
+ hbhtml_one_head_navigation(job, job->rootnode, NULL, 0, 130, 0);
+ }
+ nptr = node;
+ nptr = nptr->parent;
+ if(nptr) {
+ while((!(nptr->filename)) && (nptr->parent)) { nptr = nptr->parent; }
+ if(nptr) {
+ hbhtml_one_head_navigation(job, nptr, NULL, 0, 131, 0);
+ }
+ }
+ if(job->firstnode) {
+ hbhtml_one_head_navigation(job, job->firstnode, NULL, 0, 132, 0);
+ }
+ if(prev) {
+ hbhtml_one_head_navigation(job, prev, NULL, 0, 133, 0);
+ }
+ if(next) {
+ hbhtml_one_head_navigation(job, next, NULL, 0, 134, 0);
+ }
+ if(job->lastnode) {
+ hbhtml_one_head_navigation(job, job->lastnode, NULL, 0, 135, 0);
+ }
+}
+
+
+
+/** Write HTML header
+ @param job Job structure.
+ @param nodeptr Current node to write.
+ @param prev Previous node.
+ @param next Next node.
+*/
+static
+void
+hbhtml_write_header(
+ hb_job_t *job, hb_node_t *nodeptr, hb_node_t *prev, hb_node_t *next
+)
+{
+ dkChar const *ptr; /* Multiple text elements */
+
+
+#line 5078 "hbhtml.ctr"
+ fputs(hbhtml_c8_kw[15], job->of);
+ /* Title
+ */
+ fputs(hbhtml_c8_kw[19], job->of);
+ hbhtml_output_for_text(job, hbconf_title(nodeptr));
+ fputs(hbhtml_c8_kw[20], job->of);
+ /* Generator (comment)
+ */
+ if((nodeptr->options) & HB_NODE_OPT_USE_TIDY) {
+ fputs(hbhtml_c8_kw[17], job->of);
+ }
+ /* Generator (meta)
+ */
+ fputs(hbhtml_c8_kw[18], job->of);
+ /* Style (link)
+ */
+ ptr = hbconf_stylefile(nodeptr);
+ if(ptr) {
+ if(!hbtool_add_file(job, ptr)) { job->exv = 1; }
+ fputs(hbhtml_c8_kw[21], job->of);
+ hbhtml_url_output_for_text(job, ptr);
+ fputs(hbhtml_c8_kw[22], job->of);
+ }
+ /* Shortcut icon (link)
+ */
+ ptr = hbconf_favicon(nodeptr);
+ if(ptr) {
+ fputs(hbhtml_c8_kw[27], job->of);
+ hbhtml_url_output_for_text(job, ptr);
+ fputs(hbhtml_c8_kw[28], job->of);
+ }
+ /* Navigation (links)
+ */
+ hbhtml_write_head_navigation(job, nodeptr, prev, next);
+ /* Character set (meta)
+ */
+ if(HB_CS_UTF_8 == job->cs) {
+ fputs(hbhtml_c8_kw[24], job->of);
+ } else {
+ fputs(hbhtml_c8_kw[23], job->of);
+ }
+ /* Author (meta)
+ */
+ ptr = hbconf_author(nodeptr);
+ if(ptr) {
+ fputs(hbhtml_c8_kw[25], job->of);
+ hbhtml_output_for_text(job, ptr);
+ fputs(hbhtml_c8_kw[26], job->of);
+ }
+ /* Meta description tag
+ */
+ if (NULL != nodeptr->metadesc) {
+ fputs(hbhtml_c8_kw[154], job->of);
+ hbhtml_output_for_text(job, nodeptr->metadesc);
+ fputs(hbhtml_c8_kw[26], job->of);
+ }
+ /* Meta keywords tag.
+ */
+ if (NULL != nodeptr->metakeyw) {
+ fputs(hbhtml_c8_kw[155], job->of);
+ hbhtml_output_for_text(job, nodeptr->metakeyw);
+ fputs(hbhtml_c8_kw[26], job->of);
+ }
+ /* JavaScript files.
+ */
+ (void)hbhtml_write_js_files(job, nodeptr);
+ fputs(hbhtml_c8_kw[16], job->of);
+
+#line 5145 "hbhtml.ctr"
+}
+
+
+
+/** Line handler processing function.
+ @param obj Handler object.
+ @param il Input line to process.
+ @return 1 on success, 0 on error (continue), -1 on error (exit).
+*/
+static
+int
+hbhtml_spcl_handler(void *obj, dkChar *il)
+{
+ hb_spc_reader_t *pspcr;
+ hb_job_t *job = NULL;
+ hb_node_t *nptr = NULL;
+ hb_link_t *linkptr= NULL;
+ dkChar *vptr = NULL;
+ dkChar *cptr = NULL;
+ size_t sl = 0;
+ int back = 1;
+ int idx = 0;
+
+
+#line 5168 "hbhtml.ctr"
+ pspcr = (hb_spc_reader_t *)obj;
+ if (NULL != pspcr) {
+ job = pspcr->job;
+ nptr = pspcr->nodeptr;
+ pspcr->lineno += 1UL;
+ dk3app_set_source_line(job->app, pspcr->lineno);
+ idx = hbcont_metadata_index(il);
+ if (0 <= idx) {
+
+
+#line 5177 "hbhtml.ctr"
+ dk3str_delnl(il);
+ sl = hbcont_metadata_length(idx);
+ if (0 < sl) {
+ sl++;
+ vptr = dk3str_start(&(il[sl]), NULL);
+
+
+#line 5183 "hbhtml.ctr"
+ }
+ switch (idx) {
+ case 0: {
+
+#line 5186 "hbhtml.ctr"
+ if (NULL != vptr) {
+
+
+#line 5188 "hbhtml.ctr"
+ cptr = dk3str_dup_app(vptr, job->app);
+ if (NULL != cptr) {
+
+
+#line 5191 "hbhtml.ctr"
+ if (NULL != nptr->metadesc) {
+ /* Warning: Overwriting description text */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 97);
+ dk3mem_free(nptr->metadesc);
+ }
+ nptr->metadesc = cptr;
+ }
+ } else {
+ /* ERROR: Missing description text */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 96);
+ back = -1;
+ }
+ } break;
+ case 1: {
+
+#line 5205 "hbhtml.ctr"
+ if (NULL != vptr) {
+
+
+#line 5207 "hbhtml.ctr"
+ cptr = dk3str_dup_app(vptr, job->app);
+ if (NULL != cptr) {
+
+
+#line 5210 "hbhtml.ctr"
+ if (NULL != nptr->metakeyw) {
+ /* Warning: Overwriting keywords */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 98);
+ dk3mem_free(nptr->metakeyw);
+ }
+ nptr->metakeyw = cptr;
+ }
+ } else {
+ /* ERROR: Missing keywords text */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 96);
+ back = -1;
+ }
+ } break;
+ case 2: {
+
+#line 5224 "hbhtml.ctr"
+ if (NULL != vptr) {
+ cptr = dk3str_dup_app(vptr, job->app);
+ if (NULL != cptr) {
+ if (NULL != nptr->author) {
+ if (0UL != nptr->objno) {
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 69);
+ }
+ dk3mem_free(nptr->author);
+ }
+ nptr->author = cptr;
+ } else {
+ back = -1;
+ }
+ } else {
+ /* ERROR: Missing author name */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 96);
+ back = -1;
+ }
+ } break;
+ case 3: {
+
+#line 5244 "hbhtml.ctr"
+ if (NULL != vptr) {
+ cptr = dk3str_dup_app(vptr, job->app);
+ if (NULL != cptr) {
+ if (NULL != nptr->fulltitle) {
+ /* Warning: Overwriting title */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 70);
+ dk3mem_free(nptr->fulltitle);
+ }
+ nptr->fulltitle = cptr;
+ } else {
+ back = -1;
+ }
+ } else {
+ /* ERROR: Missing title text */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 96);
+ back = -1;
+ }
+ } break;
+ case 4: {
+
+#line 5263 "hbhtml.ctr"
+ if (NULL != vptr) {
+ cptr = dk3str_dup_app(vptr, job->app);
+ if (NULL != cptr) {
+ if (NULL != nptr->shorttitle) {
+ /* Warning: Overwriting short title */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 75);
+ dk3mem_free(nptr->shorttitle);
+ }
+ nptr->shorttitle = cptr;
+ } else {
+ back = -1;
+ }
+ } else {
+ /* ERROR: Missing short title text */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 96);
+ back = -1;
+ }
+ } break;
+ case 5: {
+
+#line 5282 "hbhtml.ctr"
+ if (NULL != vptr) {
+ cptr = dk3str_dup_app(vptr, job->app);
+ if (NULL != cptr) {
+ if (NULL != nptr->location) {
+ /* Warning: Overwriting location */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 99);
+ dk3mem_free(nptr->location);
+ }
+ nptr->location = cptr;
+ } else {
+ back = -1;
+ }
+ } else {
+ /* ERROR: Missing location text */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 96);
+ back = -1;
+ }
+ } break;
+ case 6: {
+
+#line 5301 "hbhtml.ctr"
+ if (NULL != vptr) {
+ if (0 != dk3str_is_bool(vptr)) {
+ if (0 != dk3str_is_on(vptr)) {
+ (job->currentnode)->options |= HB_NODE_OPT_PAGE_TOC;
+ } else {
+ (job->currentnode)->options &= (~(HB_NODE_OPT_PAGE_TOC));
+ }
+ } else {
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 144, vptr);
+ back = -1;
+ }
+ } else {
+ (job->currentnode)->options |= HB_NODE_OPT_PAGE_TOC;
+ }
+ } break;
+ case 7: {
+
+#line 5317 "hbhtml.ctr"
+ if (NULL != vptr) {
+ if (0 != dk3str_is_bool(vptr)) {
+ if (0 != dk3str_is_on(vptr)) {
+ (job->currentnode)->options |= HB_NODE_OPT_REPLACE_AMPERSAND;
+ } else {
+ (job->currentnode)->options &=
+ (~(HB_NODE_OPT_REPLACE_AMPERSAND));
+ }
+ } else {
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 144, vptr);
+ back = -1;
+ }
+ } else {
+ (job->currentnode)->options |= HB_NODE_OPT_REPLACE_AMPERSAND;
+ }
+ } break;
+ case 8: {
+
+#line 5334 "hbhtml.ctr"
+ if (NULL != vptr) {
+ if (0 != dk3str_is_bool(vptr)) {
+ if (0 != dk3str_is_on(vptr)) {
+ (job->currentnode)->options |= HB_NODE_OPT_HEADER_CHAIN;
+ } else {
+ (job->currentnode)->options &= (~(HB_NODE_OPT_HEADER_CHAIN));
+ }
+ } else {
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 144, vptr);
+ back = -1;
+ }
+ } else {
+ (job->currentnode)->options |= HB_NODE_OPT_HEADER_CHAIN;
+ }
+ } break;
+ case 9: {
+
+#line 5350 "hbhtml.ctr"
+ if (NULL != vptr) {
+ cptr = dk3str_dup_app(vptr, job->app);
+ if (NULL != cptr) {
+ if (NULL != nptr->suffix) {
+ /* Warning: Overwriting suffix */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 77);
+ dk3mem_free(nptr->suffix);
+ }
+ nptr->suffix = cptr;
+ } else {
+ back = -1;
+ }
+ } else {
+ /* ERROR: Missing suffix */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 96);
+ back = -1;
+ }
+ } break;
+ case 10: {
+
+#line 5369 "hbhtml.ctr"
+ if (NULL != vptr) {
+ cptr = dk3str_dup_app(vptr, job->app);
+ if (NULL != cptr) {
+ dk3str_correct_filename(cptr);
+ hbtool_correct_backslash_to_slash(cptr);
+ if (NULL != nptr->favicon) {
+ /* Warning: Overwriting favicon */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 82);
+ dk3mem_free(nptr->favicon);
+ }
+ nptr->favicon = cptr;
+ if (!(hbtool_add_file(job, cptr))) {
+ back = -1;
+ }
+ if(!hbtool_check_filename_encoding(job, cptr)) { back = -1; }
+ } else {
+ back = -1;
+ }
+ } else {
+ /* ERROR: Missing icon name */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 96);
+ back = -1;
+ }
+ } break;
+ case 11: {
+
+#line 5394 "hbhtml.ctr"
+ if (NULL != vptr) {
+ if (NULL == nptr->s_jsfiles) {
+ nptr->s_jsfiles = dk3sto_open_app(job->app);
+ if (NULL != nptr->s_jsfiles) {
+ dk3sto_set_comp(nptr->s_jsfiles, hbnode_link_compare, 2);
+ }
+ }
+ if (NULL == nptr->i_jsfiles) {
+ if (NULL != nptr->s_jsfiles) {
+ nptr->i_jsfiles = dk3sto_it_open(nptr->s_jsfiles);
+ }
+ }
+ if ((NULL != nptr->s_jsfiles) && (NULL != nptr->i_jsfiles)) {
+ linkptr = hbnode_link_new(vptr, nptr->nextjs, job->app);
+ if (NULL != linkptr) {
+ if(dk3sto_add(nptr->s_jsfiles, linkptr)) {
+ nptr->nextjs += 1UL;
+ if(!hbtool_add_url(job, vptr)) { back = -1; }
+ } else {
+ hbnode_link_delete(linkptr);
+ back = -1;
+ }
+ } else {
+ back = -1;
+ }
+ } else {
+ back = -1;
+ }
+ } else {
+ /* ERROR: Missing file name */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 96);
+ back = -1;
+ }
+ } break;
+ case 12: {
+
+#line 5429 "hbhtml.ctr"
+ if (NULL != vptr) {
+ if (0 != dk3str_is_bool(vptr)) {
+ if (0 != dk3str_is_on(vptr)) {
+ (job->currentnode)->options &=
+ (~(HB_NODE_OPT_STOP_JS_INHERITANCE));
+ } else {
+ (job->currentnode)->options |= HB_NODE_OPT_STOP_JS_INHERITANCE;
+ }
+ } else {
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 144, vptr);
+ back = -1;
+ }
+ } else {
+ (job->currentnode)->options &= (~(HB_NODE_OPT_STOP_JS_INHERITANCE));
+ }
+ } break;
+ case 13: {
+
+#line 5446 "hbhtml.ctr"
+ long cn;
+ if (NULL != vptr) {
+ if (0 != dk3ma_l_from_string(&cn, vptr, NULL)) {
+ nptr->contnum = cn;
+ } else {
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 141);
+ back = -1;
+ }
+ } else {
+ /* ERROR: Missing number */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 96);
+ back = -1;
+ }
+ } break;
+ }
+ }
+ }
+
+
+#line 5464 "hbhtml.ctr"
+ return back;
+}
+
+
+
+/** Read special comments from input file for node.
+ @param job Job structure.
+ @param nodeptr Node to read file for.
+*/
+static
+void
+hbhtml_read_special_comments(hb_job_t *job, hb_node_t *nodeptr)
+{
+ hb_spc_reader_t spcr;
+ const dkChar *oldsourcefile;
+ unsigned long oldsourceline;
+ int inenc;
+
+
+#line 5482 "hbhtml.ctr"
+ if (NULL != nodeptr->filename) {
+
+#line 5483 "hbhtml.ctr"
+ spcr.job = job;
+ spcr.nodeptr = nodeptr;
+ spcr.lineno = 0UL;
+ inenc = dk3app_get_input_file_encoding(job->app);
+ if(0 <= job->iecmd) { inenc = job->iecmd; }
+ if(0 <= nodeptr->inenc) { inenc = nodeptr->inenc; }
+ oldsourcefile = dk3app_get_source_file(job->app);
+ oldsourceline = dk3app_get_source_line(job->app);
+ dk3app_set_source_file(job->app, nodeptr->filename);
+ dk3app_set_source_line(job->app, 0UL);
+ (void)dk3stream_process_filename_lines_app(
+ (void *)(&spcr), hbhtml_spcl_handler, nodeptr->filename,
+ job->ilfile, job->bs,
+ dk3app_get_encoding(job->app),
+ inenc,
+ job->app
+ );
+ dk3app_set_source_file(job->app, oldsourcefile);
+ dk3app_set_source_line(job->app, oldsourceline);
+ }
+
+
+#line 5504 "hbhtml.ctr"
+}
+
+
+
+/** Write one output file.
+ @param job Job structure.
+ @param nodeptr Current node to write.
+ @param fn Output file name.
+ @param p Previous node.
+ @param n Next node.
+*/
+static
+void
+hbhtml_write_named_file(
+ hb_job_t *job,
+ hb_node_t *nodeptr,
+ dkChar const *fn,
+ hb_node_t *p,
+ hb_node_t *n
+)
+{
+ hb_file_processor_t proc; /* Template file processor */
+ dkChar const *templateName; /* Template file name */
+ dkChar const *oldsourcefile; /* Old source file name */
+ unsigned long oldsourceline; /* Old source file line */
+ int inenc; /* Input encoding */
+ int res; /* Result from file processing */
+
+
+#line 5532 "hbhtml.ctr"
+
+
+#line 5533 "hbhtml.ctr"
+
+
+#line 5534 "hbhtml.ctr"
+ oldsourcefile = dk3app_get_source_file(job->app);
+ oldsourceline = dk3app_get_source_line(job->app);
+ dk3app_set_source_line(job->app, nodeptr->lineno);
+ nodeptr->outFileName = fn;
+ job->currentnode = nodeptr;
+ job->of = NULL;
+ templateName = hbconf_node_template(job, nodeptr);
+ if(templateName) {
+ dk3app_set_source_file(job->app, templateName);
+ job->options &= (~(HB_JOB_OPT_CODE));
+ job->of = dk3sf_fopen_app(fn, dkT("w"), job->app);
+ if(job->of) {
+ hbhtml_read_special_comments(job, nodeptr);
+ fputs(hbhtml_c8_kw[11], job->of);
+ hbhtml_write_header(job, nodeptr, p, n);
+ fputs(hbhtml_c8_kw[13], job->of);
+ proc.job = job;
+ proc.in_template = 1;
+ proc.stm = 0;
+ proc.p = p;
+ proc.n = n;
+ inenc = dk3app_get_input_file_encoding(job->app);
+ if(0 <= job->iecmd) { inenc = job->iecmd; }
+ res = dk3stream_process_filename_lines_app(
+ (void *)(&proc), hbhtml_line_handler, templateName,
+ job->iltemplate, job->bs,
+ dk3app_get_encoding(job->app),
+ inenc,
+ job->app
+ );
+ fputs(hbhtml_c8_kw[14], job->of);
+ fputs(hbhtml_c8_kw[12], job->of);
+ if(1 != res) {
+ job->exv = 1;
+
+#line 5568 "hbhtml.ctr"
+ }
+ if(!(dk3sf_fclose_fn_app(job->of, fn, job->app))) {
+ job->exv = 1;
+
+#line 5571 "hbhtml.ctr"
+ }
+ } else {
+ job->exv = 1;
+
+#line 5574 "hbhtml.ctr"
+ }
+ } else {
+ /* ERROR: No template! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 19);
+ job->exv = 1;
+
+#line 5579 "hbhtml.ctr"
+ }
+ nodeptr->outFileName = NULL;
+ dk3app_set_source_file(job->app, oldsourcefile);
+ dk3app_set_source_line(job->app, oldsourceline);
+
+
+#line 5584 "hbhtml.ctr"
+}
+
+
+
+/** Mark path to current node in parent nodes
+ (set the curchild element).
+ @param nodeptr Current node.
+*/
+static
+void
+hbhtml_mark_path(hb_node_t *nodeptr)
+{
+ hb_node_t *cp; /* Current node */
+
+
+#line 5598 "hbhtml.ctr"
+ cp = nodeptr;
+ cp->curchild = NULL;
+ while(cp) {
+ if(cp->parent) { (cp->parent)->curchild = cp; }
+ cp = cp->parent;
+ }
+
+#line 5604 "hbhtml.ctr"
+}
+
+
+
+void
+hbhtml_write_file(hb_job_t *job, hb_node_t *nodeptr, hb_node_t *p, hb_node_t *n)
+{
+ dkChar bu[DK3_MAX_PATH]; /* File name buffer. */
+
+
+#line 5613 "hbhtml.ctr"
+
+ /* Set things up for new file.
+ */
+ job->coli = 0;
+ job->cols = HB_COLIST_NONE;
+ job->options &= (~(HB_JOB_OPT_CODE));
+
+ /* Process the file.
+ */
+ hbhtml_mark_path(nodeptr);
+ if(hbhtml_create_output_filename(bu, DK3_SIZEOF(bu,dkChar), job, nodeptr)) {
+
+
+#line 5625 "hbhtml.ctr"
+ hbhtml_write_named_file(job, nodeptr, bu, p, n);
+ } else {
+ job->exv = 1;
+
+#line 5628 "hbhtml.ctr"
+ }
+
+
+
+#line 5631 "hbhtml.ctr"
+}
+
+
diff --git a/support/dktools/hbhtml.ctr b/support/dktools/hbhtml.ctr
new file mode 100644
index 0000000000..21031c7787
--- /dev/null
+++ b/support/dktools/hbhtml.ctr
@@ -0,0 +1,5633 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2013-xxxx
+license = bsd
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Write one HTML file.
+ @param job Job structure.
+ @param nodeptr Node for file to write.
+ @param p Previous node.
+ @param n Next node.
+*/
+void
+hbhtml_write_file(hb_job_t *job,hb_node_t *nodeptr,hb_node_t *p,hb_node_t *n);
+
+/** Write one 32-bit character to HTML output.
+ @param job Job structure.
+ @param c32 Character to write.
+*/
+void
+hbhtml_c32(hb_job_t *job, dk3_c32_t c32);
+
+/** Write some text as HTML.
+ @param job Job structure.
+ @param text Text to write.
+ @return 1 on success, 0 on error.
+*/
+int
+hbhtml_output_for_text(hb_job_t *job, dkChar const *text);
+
+/** Write some URL text as HTML.
+ @param job Job structure.
+ @param text Text to write.
+ @return 1 on success, 0 on error.
+*/
+int
+hbhtml_url_output_for_text(hb_job_t *job, dkChar const *text);
+
+/** Handle one input line, either from template or from text file.
+ @param obj Line processor structure.
+ @param il Input line to process.
+ @return 1 on success, 0 on error (continue), -1 on error (exit).
+*/
+int
+hbhtml_line_handler(void *obj, dkChar *il);
+
+/** Construct output file name.
+ @param dptr Destination buffer pointer.
+ @param sz Destination buffer size.
+ @param job Job structure.
+ @param nptr Node to process.
+ @return 1 on success, 0 on error.
+*/
+int
+hbhtml_create_output_filename(
+ dkChar *dptr,
+ size_t sz,
+ hb_job_t *job,
+ hb_node_t *nptr
+);
+
+/** Check whether a link is an external link (http:// or ftp://
+ at start).
+ @param link Link to check.
+ @return 1 for external links, 0 for internal links.
+*/
+int
+hbhtml_check_link_for_external(dkChar const *link);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% state machine
+
+[options]
+
+name = hbhtml_stm1
+write header = no
+
+[states]
+STM1_ST_START # Start state
+STM1_ST_ERROR # Error occured
+STM1_ST_BS # Backslash found
+STM1_ST_PERCENT # One percent sign found
+STM1_ST_SPECIAL # Recording a special
+STM1_ST_SPEC_BS # Backslash found in special
+STM1_ST_SPEC_PC # Percent found in special
+
+[inputs]
+STM1_I_ANY # Any character
+STM1_I_BS # Backslash
+STM1_I_PERCENT # Percent sign
+
+[outputs]
+STM1_O_ERROR # Error, do nothing
+STM1_O_NOTHING # Do nothing
+STM1_O_SHIPOUT # Add character to shipout buffer
+STM1_O_BS_SHIPOUT # Shipout character after backslash
+STM1_O_PERCENT_SHIPOUT # Shipout percent sign and current character
+STM1_O_PERCENT # Shipout just percent sign
+STM1_O_SWITCH # Flush shipout and switch to saving special
+STM1_O_SPECIAL # Add current character to special
+STM1_O_SPEC_BS # Add char after backslash to special
+STM1_O_SPEC_PC_ADD # Add percent and current char to special
+STM1_O_SPEC_PC # Add percent sign to special
+STM1_O_EXECUTE # Execute special
+
+[rules]
+* * STM1_ST_ERROR STM1_O_ERROR
+
+STM1_ST_START * STM1_ST_START STM1_O_SHIPOUT
+STM1_ST_START STM1_I_BS STM1_ST_BS STM1_O_NOTHING
+STM1_ST_START STM1_I_PERCENT STM1_ST_PERCENT STM1_O_NOTHING
+
+STM1_ST_BS * STM1_ST_START STM1_O_BS_SHIPOUT
+
+STM1_ST_PERCENT * STM1_ST_START STM1_O_PERCENT_SHIPOUT
+STM1_ST_PERCENT STM1_I_BS STM1_ST_BS STM1_O_PERCENT
+STM1_ST_PERCENT STM1_I_PERCENT STM1_ST_SPECIAL STM1_O_SWITCH
+
+STM1_ST_SPECIAL * STM1_ST_SPECIAL STM1_O_SPECIAL
+STM1_ST_SPECIAL STM1_I_BS STM1_ST_SPEC_BS STM1_O_NOTHING
+STM1_ST_SPECIAL STM1_I_PERCENT STM1_ST_SPEC_PC STM1_O_NOTHING
+
+STM1_ST_SPEC_BS * STM1_ST_SPECIAL STM1_O_SPEC_BS
+
+STM1_ST_SPEC_PC * STM1_ST_SPECIAL STM1_O_SPEC_PC_ADD
+STM1_ST_SPEC_PC STM1_I_BS STM1_ST_SPEC_BS STM1_O_SPEC_PC
+STM1_ST_SPEC_PC STM1_I_PERCENT STM1_ST_START STM1_O_EXECUTE
+
+%% state machine
+[options]
+ name = hbhtml_stm3
+ write header = no
+[states]
+ STM3_ST_START # No character processed yet
+ STM3_ST_NAME # ASCII characters (for protocol name) found
+ STM3_ST_COLON # Colon found
+ STM3_ST_COLSL # Colon and slash
+ STM3_ST_SUCCESS # Colon and two slashes found
+ STM3_ST_ERROR # Not a protocol at start of text
+[inputs]
+ STM3_I_ANY # Anything not listed below
+ STM3_I_ASCII # a-zA-Z01-9_
+ STM3_I_COLON # Colon
+ STM3_I_SLASH # Slash
+[outputs]
+ STM3_O_OK # OK so far
+ STM3_O_ERROR # ERROR found
+[rules]
+ * * STM3_ST_ERROR STM3_O_ERROR
+ STM3_ST_START STM3_I_ASCII STM3_ST_NAME STM3_O_OK
+ STM3_ST_NAME STM3_I_ASCII STM3_ST_NAME STM3_O_OK
+ STM3_ST_NAME STM3_I_COLON STM3_ST_COLON STM3_O_OK
+ STM3_ST_COLON STM3_I_SLASH STM3_ST_COLSL STM3_O_OK
+ STM3_ST_COLSL STM3_I_SLASH STM3_ST_SUCCESS STM3_O_OK
+ STM3_ST_SUCCESS * STM3_ST_SUCCESS STM3_O_OK
+
+
+%% module
+
+
+#include "dk3all.h"
+#include "dk3strkv.h"
+#include "htmlbook.h"
+
+
+
+$!trace-include
+
+
+
+/** Object for line reader (special comments).
+*/
+typedef struct {
+ hb_job_t *job; /**< Job structure. */
+ hb_node_t *nodeptr; /**< Current node to process. */
+ unsigned long lineno; /**< Current line number to process. */
+} hb_spc_reader_t;
+
+
+
+/** Translation table for ASCII characters.
+*/
+static char const * const hbhtml_translation_table[] = {
+/* 0 00 */ NULL,
+/* 1 01 */ NULL,
+/* 2 02 */ NULL,
+/* 3 03 */ NULL,
+/* 4 04 */ NULL,
+/* 5 05 */ NULL,
+/* 6 06 */ NULL,
+/* 7 07 */ NULL,
+/* 8 08 */ NULL,
+/* 9 09 */ "\t",
+/* 10 0a */ NULL,
+/* 11 0b */ NULL,
+/* 12 0c */ NULL,
+/* 13 0d */ NULL,
+/* 14 0e */ NULL,
+/* 15 0f */ NULL,
+/* 16 10 */ NULL,
+/* 17 11 */ NULL,
+/* 18 12 */ NULL,
+/* 19 13 */ NULL,
+/* 20 14 */ NULL,
+/* 21 15 */ NULL,
+/* 22 16 */ NULL,
+/* 23 17 */ NULL,
+/* 24 18 */ NULL,
+/* 25 19 */ NULL,
+/* 26 1a */ NULL,
+/* 27 1b */ NULL,
+/* 28 1c */ NULL,
+/* 29 1d */ NULL,
+/* 30 1e */ NULL,
+/* 31 1f */ NULL,
+/* 32 20 */ " ",
+/* 33 21 */ "!",
+/* 34 22 */ "&quot;",
+/* 35 23 */ "#",
+/* 36 24 */ "$",
+/* 37 25 */ "%",
+/* 38 26 */ "&amp;",
+/* 39 27 */ "'",
+/* 40 28 */ "(",
+/* 41 29 */ ")",
+/* 42 2a */ "*",
+/* 43 2b */ "+",
+/* 44 2c */ ",",
+/* 45 2d */ "-",
+/* 46 2e */ ".",
+/* 47 2f */ "/",
+/* 48 30 */ "0",
+/* 49 31 */ "1",
+/* 50 32 */ "2",
+/* 51 33 */ "3",
+/* 52 34 */ "4",
+/* 53 35 */ "5",
+/* 54 36 */ "6",
+/* 55 37 */ "7",
+/* 56 38 */ "8",
+/* 57 39 */ "9",
+/* 58 3a */ ":",
+/* 59 3b */ ";",
+/* 60 3c */ "&lt;",
+/* 61 3d */ "=",
+/* 62 3e */ "&gt;",
+/* 63 3f */ "?",
+/* 64 40 */ "@",
+/* 65 41 */ "A",
+/* 66 42 */ "B",
+/* 67 43 */ "C",
+/* 68 44 */ "D",
+/* 69 45 */ "E",
+/* 70 46 */ "F",
+/* 71 47 */ "G",
+/* 72 48 */ "H",
+/* 73 49 */ "I",
+/* 74 4a */ "J",
+/* 75 4b */ "K",
+/* 76 4c */ "L",
+/* 77 4d */ "M",
+/* 78 4e */ "N",
+/* 79 4f */ "O",
+/* 80 50 */ "P",
+/* 81 51 */ "Q",
+/* 82 52 */ "R",
+/* 83 53 */ "S",
+/* 84 54 */ "T",
+/* 85 55 */ "U",
+/* 86 56 */ "V",
+/* 87 57 */ "W",
+/* 88 58 */ "X",
+/* 89 59 */ "Y",
+/* 90 5a */ "Z",
+/* 91 5b */ "[",
+/* 92 5c */ "\\",
+/* 93 5d */ "]",
+/* 94 5e */ "^",
+/* 95 5f */ "_",
+/* 96 60 */ "`",
+/* 97 61 */ "a",
+/* 98 62 */ "b",
+/* 99 63 */ "c",
+/* 100 64 */ "d",
+/* 101 65 */ "e",
+/* 102 66 */ "f",
+/* 103 67 */ "g",
+/* 104 68 */ "h",
+/* 105 69 */ "i",
+/* 106 6a */ "j",
+/* 107 6b */ "k",
+/* 108 6c */ "l",
+/* 109 6d */ "m",
+/* 110 6e */ "n",
+/* 111 6f */ "o",
+/* 112 70 */ "p",
+/* 113 71 */ "q",
+/* 114 72 */ "r",
+/* 115 73 */ "s",
+/* 116 74 */ "t",
+/* 117 75 */ "u",
+/* 118 76 */ "v",
+/* 119 77 */ "w",
+/* 120 78 */ "x",
+/* 121 79 */ "y",
+/* 122 7a */ "z",
+/* 123 7b */ "{",
+/* 124 7c */ "|",
+/* 125 7d */ "}",
+/* 126 7e */ "~",
+/* 127 7f */ NULL,
+/* 128 80 */ NULL,
+/* 129 81 */ NULL,
+/* 130 82 */ NULL,
+/* 131 83 */ NULL,
+/* 132 84 */ NULL,
+/* 133 85 */ NULL,
+/* 134 86 */ NULL,
+/* 135 87 */ NULL,
+/* 136 88 */ NULL,
+/* 137 89 */ NULL,
+/* 138 8a */ NULL,
+/* 139 8b */ NULL,
+/* 140 8c */ NULL,
+/* 141 8d */ NULL,
+/* 142 8e */ NULL,
+/* 143 8f */ NULL,
+/* 144 90 */ NULL,
+/* 145 91 */ NULL,
+/* 146 92 */ NULL,
+/* 147 93 */ NULL,
+/* 148 94 */ NULL,
+/* 149 95 */ NULL,
+/* 150 96 */ NULL,
+/* 151 97 */ NULL,
+/* 152 98 */ NULL,
+/* 153 99 */ NULL,
+/* 154 9a */ NULL,
+/* 155 9b */ NULL,
+/* 156 9c */ NULL,
+/* 157 9d */ NULL,
+/* 158 9e */ NULL,
+/* 159 9f */ NULL,
+/* 160 a0 */ "&nbsp;",
+/* 161 a1 */ "&iexcl;",
+/* 162 a2 */ "&cent;",
+/* 163 a3 */ "&pound;",
+/* 164 a4 */ "&curren;",
+/* 165 a5 */ "&yen;",
+/* 166 a6 */ "&brvbar;",
+/* 167 a7 */ "&sect;",
+/* 168 a8 */ "&uml;",
+/* 169 a9 */ "&copy;",
+/* 170 aa */ "&ordf;",
+/* 171 ab */ "&laquo;",
+/* 172 ac */ "&not;",
+/* 173 ad */ "&shy;",
+/* 174 ae */ "&reg;",
+/* 175 af */ "&macr;",
+/* 176 b0 */ "&deg;",
+/* 177 b1 */ "&plusmn;",
+/* 178 b2 */ "&sup2;",
+/* 179 b3 */ "&sup3;",
+/* 180 b4 */ "&acute;",
+/* 181 b5 */ "&micro;",
+/* 182 b6 */ "&para;",
+/* 183 b7 */ "&middot;",
+/* 184 b8 */ "&cedil;",
+/* 185 b9 */ "&sup1;",
+/* 186 ba */ "&ordm;",
+/* 187 bb */ "&raquo;",
+/* 188 bc */ "&frac14;",
+/* 189 bd */ "&frac12;",
+/* 190 be */ "&frac34;",
+/* 191 bf */ "&iquest;",
+/* 192 c0 */ "&Agrave;",
+/* 193 c1 */ "&Aacute;",
+/* 194 c2 */ "&Acirc;",
+/* 195 c3 */ "&Atilde;",
+/* 196 c4 */ "&Auml;",
+/* 197 c5 */ "&Aring;",
+/* 198 c6 */ "&AElig;",
+/* 199 c7 */ "&Ccedil;",
+/* 200 c8 */ "&Egrave;",
+/* 201 c9 */ "&Eacute;",
+/* 202 ca */ "&Ecirc;",
+/* 203 cb */ "&Euml;",
+/* 204 cc */ "/Igrave;",
+/* 205 cd */ "&Iacute;",
+/* 206 ce */ "&Icirc;",
+/* 207 cf */ "&Iuml;",
+/* 208 d0 */ "&ETH;",
+/* 209 d1 */ "&Ntilde;",
+/* 210 d2 */ "&Ograve;",
+/* 211 d3 */ "&Oacute;",
+/* 212 d4 */ "&Ocirc;",
+/* 213 d5 */ "&Otilde;",
+/* 214 d6 */ "&Ouml;",
+/* 215 d7 */ "&times;",
+/* 216 d8 */ "&Oslash;",
+/* 217 d9 */ "&Ugrave;",
+/* 218 da */ "&Uacute;",
+/* 219 db */ "&Ucirc;",
+/* 220 dc */ "&Uuml;",
+/* 221 dd */ "&Yacute;",
+/* 222 de */ "&THORN;",
+/* 223 df */ "&szlig;",
+/* 224 e0 */ "&agrave;",
+/* 225 e1 */ "&aacute;",
+/* 226 e2 */ "&acirc;",
+/* 227 e3 */ "&atilde;",
+/* 228 e4 */ "&auml;",
+/* 229 e5 */ "&aring;",
+/* 230 e6 */ "&aelig;",
+/* 231 e7 */ "&ccedil;",
+/* 232 e8 */ "&egrave;",
+/* 233 e9 */ "&eacute;",
+/* 234 ea */ "&ecirc;",
+/* 235 eb */ "&euml;",
+/* 236 ec */ "&igrave;",
+/* 237 ed */ "&iacute;",
+/* 238 ee */ "&icirc;",
+/* 239 ef */ "&iuml;",
+/* 240 f0 */ "&eth;",
+/* 241 f1 */ "&ntilde;",
+/* 242 f2 */ "&ograve;",
+/* 243 f3 */ "&oacute;",
+/* 244 f4 */ "&ocirc;",
+/* 245 f5 */ "&otilde;",
+/* 246 f6 */ "&ouml;",
+/* 247 f7 */ "&divide;",
+/* 248 f8 */ "&oslash;",
+/* 249 f9 */ "&ugrave;",
+/* 250 fa */ "&uacute;",
+/* 251 fb */ "&ucirc;",
+/* 252 fc */ "&uuml;",
+/* 253 fd */ "&yacute;",
+/* 254 fe */ "&thorn;",
+/* 255 ff */ "&yuml;"
+};
+
+
+
+/** Constant 8-bit character keywords.
+*/
+static char const * const hbhtml_c8_kw[] = {
+$!string-table
+#
+# 0 Newline
+#
+\n
+#
+# 1 Space
+#
+
+#
+# 2 Start of an image
+#
+<img
+#
+# 3 General tag end
+#
+>
+#
+# 4 Image source
+#
+src="
+#
+# 5 End of attribute
+#
+"
+#
+# 6 alt attribute
+#
+ alt="
+#
+# 7 title attribute
+#
+ title="
+#
+# 8 border attribute
+#
+ border="
+#
+# 9 width attribute
+#
+ width="
+#
+# 10 height attribute
+#
+ height="
+#
+# 11 12 HTML tag
+#
+<html>\n
+</html>\n
+#
+# 13 14 BODY tag
+#
+<body>\n
+</body>\n
+#
+# 15 16 HEAD tag
+#
+<head>\n
+</head>\n
+#
+# 17 18 Generated by
+#
+<!-- Generated by htmlbook (see http://dktools.sourceforge.net) -->\n
+<meta name="generator" content="htmlbook">\n
+#
+# 19 20 TITLE tag
+#
+<title>
+</title>\n
+#
+# 21 22 Style sheet
+#
+<link rel="stylesheet" type="text/css" href="
+">\n
+#
+# 23 24 Charset specifications
+#
+<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">\n
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">\n
+#
+# 25 26 Author
+#
+<meta name="author" content="
+">\n
+#
+# 27 28 Shortcut icon
+#
+<link rel="shortcut icon" href="
+">\n
+#
+# 29 30 Navi menu div
+#
+<div class="hb_nm_div">\n
+</div><!-- class=hb_nm_div -->\n
+#
+# 31 32 Navi menu ul
+#
+<ul class="hb_nm_ul">\n
+</ul><!-- class=hb_nm_ul -->\n
+#
+# 33 Navi menu separator
+#
+<li class="hb_nm_sep">&nbsp;</li>\n
+#
+# 34 35 Navi menu current node entry
+#
+<li class="hb_nm_c"
+</li>\n
+#
+# 36 37 Navi menu current entry
+#
+<li class="hb_nm_li">
+</li>\n
+#
+# 38 Class name for navigation link
+#
+hb_nm_a
+#
+# 39 40 41 42 43 44 45 Link
+#
+<a href="
+>
+</a>
+"
+ class="
+ title="
+ type="
+#
+# 46 47 Navigation div
+#
+<div class="hb_navigation">
+</div>\n
+#
+# 48 Space between navigation images
+#
+&nbsp;
+#
+# 49 50 51 52 Navigation link
+#
+<a class="hb_navi_a" href="
+" title="
+">
+</a>
+#
+# 53 54 55 56 Image in navigation link
+#
+<img src="
+" alt="
+" title="
+" class="hb_navi_img" border="0"
+#
+# 57 Default border
+#
+0
+#
+# 58 Name attribute
+#
+ name="
+#
+# 59 longdesc attribute
+#
+ longdesc="
+#
+# 60 Class attribute
+#
+ class="
+#
+# 61 ID attribute
+#
+ id="
+#
+# 62 Usemap attribute
+#
+ usemap="
+#
+# 63 Align attribute
+#
+ align="
+#
+# 64 Hspace attribute
+#
+ hspace="
+#
+# 65 Vspace attribute
+#
+ vspace="
+#
+# 66 Ismap attribute
+#
+ ismap
+#
+# 67 Width and height attributes
+#
+ width="%lu" height="%lu"
+#
+# 68 Link to enlarge image
+#
+<a class="hb_img_a_larger" href="
+#
+# 69 Link target is a blank window
+#
+" target="_blank"
+#
+# 70 71 72 73 PDF object
+#
+<object type="application/pdf" data="
+" width="
+" height="
+</object>
+#
+# 74 Named anchor
+#
+<a name="
+#
+# 75 76 77 78 target type class id
+#
+" target="
+" type="
+" class="
+" id="
+#
+# 79 80 81 82 style hreflang title onblur
+#
+" style="
+" hreflang="
+" title="
+" onblur="
+#
+# 83 84 85 86 onfocus rel rev shape
+#
+" onfocus="
+" rel="
+" rev="
+" shape="
+#
+# 87 88 89 90 tabindex accesskey charset coords
+#
+" tabindex="
+" accesskey="
+" charset="
+" coords="
+#
+# 91
+#
+<span class="hb_link_number">&nbsp;&#9001;%lu&#9002;</span>
+#
+# 92 93 94 95 96 97 98 99 Menu entry table.
+#
+<table class="hb_me_ta" summary="
+</table>\n
+<tr class="hb_me_tr">\n
+</tr>\n
+<td class="hb_me_td_text" colspan="%u">
+</td>\n
+<td></td>\n
+<td class="hb_me_td_arrow">&nbsp;&#8594;&nbsp;</td>\n
+#
+# 100 101 Link classes
+#
+hb_a_i
+hb_a_e
+#
+# 102 103 104 105
+#
+<div class="hb_file_div">\n
+<a class="hb_file_a" target="_blank" href="
+text/plain
+<br>\n
+#
+# 106 107
+#
+<pre>\n
+</pre>\n
+#
+# 108
+#
+" target="_blank
+#
+# 109 110 111 112 113
+#
+<div class="hb_img_div_outer">\n
+<div class="hb_img_div_inner_img">\n
+<div class="hb_img_div_inner_img_centered">\n
+<p class="hb_img_p_download">\n
+<br class="clearboth">\n</p>\n
+#
+# 114 115
+#
+\n<object type="image/svg+xml" data="
+<param name="src" value="
+#
+# 116 117
+#
+<br>\n<span class="hb_img_caption">
+</span>
+#
+# 118 119
+#
+ type="image/svg+xml"
+ type="application/pdf"
+#
+# 120
+#
+<p><br class="clearboth"></p>\n
+#
+# 121 122
+#
+<script src="
+" type="text/javascript">\n</script>\n
+#
+# 123 124 125 126
+#
+<link rel="
+" title="
+" href="
+">\n
+#
+# 127 ... 135
+#
+author
+contents
+index
+top
+up
+first
+prev
+next
+last
+#
+# 136 137
+#
+\#hb_toc
+\#hb_index
+#
+# 138 139 140 141 142 143
+#
+<table class="hb_img_ta" summary="
+<tr class="hb_img_tr">\n
+<td class="hb_img_td_img">\n
+<td class="hb_img_td_empty">&nbsp;</td>\n
+<td class="hb_img_td_a">\n
+">\n
+#
+# 144
+#
+hb_nm_a_parent
+#
+# 145
+#
+<div class="hb_img_div_no_vspace">\n
+#
+# 146 147 148 149 150
+#
+<code title="
+">
+</code>
+
+
+#
+# 151 152 153
+#
+<span class="hint" title="
+">
+</span>
+#
+# 154
+#
+<meta name="description" content="
+#
+# 155
+#
+<meta name="keywords" content="
+$!end
+};
+
+
+
+/** Special commands.
+*/
+dkChar const * const hbhtml_special_commands[] = {
+$!string-table macro=dkT
+#
+# 0: Contents
+#
+contents
+#
+# 1: Title
+#
+title
+#
+# 2: Image
+#
+img
+#
+# 3: Menu
+#
+menu
+#
+# 4: Navigation
+#
+navigation
+#
+# 5: Links
+#
+links
+#
+# 6: Author
+#
+author
+#
+# 7: Location
+#
+location
+#
+# 8: Date
+#
+date
+#
+# 9: Variable
+#
+var
+#
+# 10: Code
+#
+code
+#
+# 11: a (link)
+#
+a
+#
+# 12: menuentry
+#
+menuentry
+#
+# 13: index (create keyword index entry)
+#
+index
+#
+# 14: source file
+#
+sourcefile
+#
+# 15: HTML file name
+#
+htmlname
+#
+# 16: Hint
+#
+hint
+$!end
+};
+
+
+
+
+/** Attributes allowed in image special command.
+*/
+dkChar const * const hbhtml_img_keys[] = {
+$!string-table macro=dkT
+ali$gn
+alt
+b$order
+he$ight
+hs$pace
+is$map
+lo$ngdesc
+n$ame
+sr$c
+u$semap
+v$space
+w$idth
+la$rger
+p$df
+cac$he
+ti$tle
+cl$ass
+id
+div
+cap$tion
+ce$ntered
+svg
+svgwh
+do$wnloads
+o$bject
+ta$ble
+no-v$space
+f$ile
+$!end
+};
+
+
+
+/** Keys for hint.
+*/
+dkChar const * const hbhtml_hint_keys[] = {
+$!string-table macro=dkT
+te$xt
+ti$tle
+$!end
+};
+
+
+
+/** Attributes for menu.
+*/
+dkChar const * const hbhtml_menu_keys[] = {
+$!string-table macro=dkT
+st$yle
+su$b
+$!end
+};
+
+
+
+/** Attributes for menuentry.
+*/
+dkChar const * const hbhtml_menuentry_keys[] = {
+$!string-table macro=dkT
+i$tem
+$!end
+};
+
+
+
+/** Attributes for index entry.
+*/
+dkChar const * const hbhtml_index_keys[] = {
+$!string-table macro=dkT
+t$ext
+n$ame
+ref$erence
+$!end
+};
+
+
+
+/** Attributes for sourcefile special command.
+*/
+dkChar const * const hbhtml_sourcef_keys[] = {
+$!string-table macro=dkT
+f$ile
+ty$pe
+ti$tle
+l$ineno
+$!end
+};
+
+
+/** Attributes for navigation.
+*/
+dkChar const * const hbhtml_navi_keys[] = {
+$!string-table macro=dkT
+t$oc
+p$revious
+n$ext
+i$ndex
+h$ome
+$!end
+};
+
+
+
+/** Attributes for code special command.
+*/
+dkChar const * const hbhtml_code_keys[] = {
+$!string-table macro=dkT
+e$nable
+on
+d$isable
+of$f
+t$oggle
+l$ineno
+$!end
+};
+
+
+
+/** Attribute for a.
+*/
+dkChar const * const hbhtml_a_keys[] = {
+$!string-table macro=dkT
+te$xt
+ti$tle
+ac$cesskey
+ch$arset
+co$ords
+href
+hrefl$ang
+na$me
+onb$lur
+onf$ocus
+rel
+rev
+sh$ape
+tab$index
+tar$get
+ty$pe
+cl$ass
+id
+st$yle
+ext$ernal
+$!end
+};
+
+
+
+/** The menu styles.
+*/
+dkChar const * const hbhtml_menu_styles[] = {
+$!string-table macro=dkT
+r$everse
+f$ull
+c$urrent
+t$op
+$!end
+};
+
+
+
+/** Attributes allowed in date special.
+*/
+dkChar const * const hbhtml_date_keys[] = {
+$!string-table macro=dkT
+st$yle
+$!end
+};
+
+
+
+/** Subcommands of img with not vertical space.
+*/
+dkChar const * const hbhtml_no_vspace_suffixes[] = {
+$!string-table macro=dkT
+tex
+$!end
+};
+
+
+
+/** File name suffixes.
+*/
+dkChar const * const hbhtml_image_filename_suffixes[] = {
+$!string-table macro=dkT
+.png
+.pdf
+.svg
+$!end
+};
+
+
+
+/** Check whether a character is useable in an URL.
+ RFC 1630 and 3986 allow only 8-bit characters (octets)
+ in URLs.
+ @param c32 Character to check.
+ @return 1 for usable character, 0 otherwise.
+*/
+static
+int
+hbhtml_url_useable(dk3_c32_t c32)
+{
+ int back = 1;
+ $? "+ hbhtml_url_useable %lx %lu", (unsigned long)c32, (unsigned long)c32
+ if((dk3_c32_t)255 < c32) {
+ back = 0; /* NOT REPORTED */
+ } $? "- hbhtml_url_useable %d", back
+ return back;
+}
+
+
+
+#if 0
+/** Check whether a character must be written hex-encoded to an URL.
+ See RFC 3986 for reserved and unreserved characters.
+ @param c32 Character to check.
+ @return 1 for hex-encoding, 0 for direct use.
+*/
+static
+int
+hbhtml_url_must_encode_normally(dk3_c32_t c32)
+{
+ int back = 1;
+ char c;
+ if((dk3_c32_t)128 > c32) {
+ c = (char)c32;
+ c &= 0x7F;
+ if(('a' <= c) && ('z' >= c)) {
+ back = 0;
+ } else {
+ if(('A' <= c) && ('Z' >= c)) {
+ back = 0;
+ } else {
+ if(('0' <= c) && ('9' >= c)) {
+ back = 0;
+ } else {
+ switch(c) {
+ case '-': case '_': case '.': case '~': {
+ back = 0;
+ } break;
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+#endif
+
+
+
+/** Check whether a character must be written hex-encoded to an URL.
+ See RFC 3986 for reserved and unreserved characters.
+ @param c32 Character to check.
+ @return 1 for hex-encoding, 0 for direct use.
+*/
+static
+int
+hbhtml_url_must_encode(dk3_c32_t c32)
+{
+ int back = 0;
+ $? "+ hbhtml_url_must_encode %lx %lu", (unsigned long)c32, (unsigned long)c32
+ if((dk3_c32_t)126 < c32) {
+ back = 1;
+ } else {
+ if((dk3_c32_t)33 > c32) {
+ back = 1;
+ }
+ } $? "- hbhtml_url_must_encode %d", back
+ return back;
+}
+
+
+
+/** Write one character in URL encoding, complain on problems.
+ Unusable characters (not in octect range 0...0xFF)
+ are UTF-8 encoded first and hex-converted for the URL.
+ Some ASCII characters have special meaning in URL encoding
+ (i.e. ampersand, question mark...). We assume the user
+ intended to use these characters and specified the URL
+ so we can use it "as is".
+
+ @param job Job structure.
+ @param c32 Character to print.
+*/
+static
+void
+hbhtml_url_c32(hb_job_t *job, dk3_c32_t c32)
+{
+ char buf[16]; /* Buffer for hexadecimal notation */
+ unsigned char ub[16]; /* Buffer for UTF-8 notation */
+ size_t sz; /* Number of bytes used in ub */
+ size_t i; /* Traverse ub */
+ $? "+ hbhtml_url_c32 0x%lx = %lu", (unsigned long)c32, (unsigned long)c32
+ if(hbhtml_url_useable(c32)) {
+ if(hbhtml_url_must_encode(c32)) {
+ buf[0] = '%';
+ sprintf(&(buf[1]), "%02X", (unsigned)c32);
+ fputs(buf, job->of);
+ } else {
+ fputc((((char)c32) & ((char)0x7F)), job->of);
+ }
+ } else {
+ job->non_url = 1;
+ sz = dk3enc_uc2utf8(c32, ub, sizeof(ub));
+ for(i = 0; i < sz; i++) {
+ buf[0] = '%';
+ sprintf(&(buf[1]), "%02X", ((unsigned)(ub[i]) & 0x00FFU));
+ fputs(buf, job->of);
+ }
+ } $? "- hbhtml_url_c32"
+}
+
+
+
+/** Write shipout buffer in URL encoding.
+ @param job Job structure.
+*/
+static
+void
+hbhtml_url_flush_shipout(hb_job_t *job)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ size_t i;
+#else
+ dk3_c16_t const *sp; /* Source character pointer */
+ dk3_c32_t c32; /* 32-bit character */
+ size_t sl; /* Remaining source string length */
+ size_t used; /* Number of source chars used */
+#endif
+#else
+ unsigned char const *sp; /* Source character pointer */
+ dk3_c32_t c32; /* 32-bit character */
+ size_t sl; /* Remaining source string length */
+ size_t used; /* Number of source chars used */
+ size_t i; /* Process all source chars */
+ unsigned char c; /* Current source char to process */
+#endif
+ $? "+ hbhtml_flush_shipout"
+ if(job->shipused) {
+ job->non_url = 0;
+ if(job->shipused < job->bs) {
+ (job->shipbuffer)[job->shipused] = dkT('\0');
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ for(i = 0; i < (job->shipused); i++) {
+ hbhtml_url_c32(job, (job->shipused)[i]);
+ }
+#else
+ sp = (dk3_c16_t const *)(job->shipbuffer);
+ sl = job->shipused;
+ while(sl > 0) {
+ used = 0;
+ if(dk3enc_utf162uc(&c32, sp, sl, &used)) {
+ hbhtml_url_c32(job, c32);
+ if(used > 0) {
+ if(sl >= used) {
+ sl = sl - used;
+ sp = &(sp[used]);
+ } else {
+ sl = 0;
+ /* ERROR: Decoding */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 119);
+ }
+ } else {
+ sl = 0;
+ /* ERROR: Decoding */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 119);
+ }
+ } else {
+ sl = 0;
+ /* ERROR: Decoding */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 119);
+ }
+ }
+#endif
+#else
+ $? "+ shipout ASCII"
+ if(dk3app_get_encoding(job->app) == DK3_ENCODING_UTF8) {
+ $? ". UTF-8"
+ sp = (unsigned char const *)(job->shipbuffer);
+ sl = job->shipused;
+ while(sl > 0) {
+ used = 0;
+ if(dk3enc_utf82uc(&c32, sp, sl, &used)) {
+ hbhtml_url_c32(job, c32);
+ if(used > 0) {
+ if(sl >= used) {
+ sl = sl - used;
+ sp = &(sp[used]);
+ } else {
+ sl = 0;
+ /* ERROR: Decoding problem */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 118);
+ }
+ } else {
+ sl = 0;
+ /* ERROR: Decoding problem */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 118);
+ }
+ } else {
+ sl = 0;
+ /* ERROR: Decoding problem */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 118);
+ }
+ }
+ } else {
+ sp = (unsigned char const *)(job->shipbuffer);
+ for(i = 0; i < (job->shipused); i++) {
+ c = sp[i];
+ c32 = (dk3_c32_t)c;
+ c32 &= 0x000000FFUL;
+ hbhtml_url_c32(job, c32);
+ }
+ }
+ $? "- shipout ASCII"
+#endif
+ if(job->non_url) {
+ /* WARNING: Non-URL characters in string! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 21, 22, job->shipbuffer);
+ }
+ }
+ job->non_url = 0;
+ }
+ job->shipused = 0;
+ $? "- hbhtml_flush_shipout"
+}
+
+
+
+void
+hbhtml_c32(hb_job_t *job, dk3_c32_t c32)
+{
+ unsigned char ub[16]; /* Buffer for UTF-8 conversion */
+ size_t sz; /* Number of chars used in ub */
+ size_t i; /* Process all chars in ub */
+ char c; /* Current char from ub */
+ $? "+ hbhtml_c32 0x%lx %lu", (unsigned long)c32, (unsigned long)c32
+ if(((dk3_c32_t)128) > c32) {
+ c = (((char)c32) & ((char)0x7F));
+ switch(c) {
+ case '\n': {
+ fputc('\n', job->of);
+ } break;
+ case '&': {
+ if((job->options) & HB_JOB_OPT_CODE) {
+ fputs(hbhtml_translation_table[38], job->of);
+ } else {
+ if(((job->currentnode)->options) & HB_NODE_OPT_REPLACE_AMPERSAND) {
+ fputs(hbhtml_translation_table[38], job->of);
+ } else {
+ fputc('&', job->of);
+ }
+ }
+ } break;
+ case '<': {
+ if((job->options) & HB_JOB_OPT_CODE) {
+ fputs(hbhtml_translation_table[60], job->of);
+ } else {
+ fputc('<', job->of);
+ }
+ } break;
+ case '>': {
+ if((job->options) & HB_JOB_OPT_CODE) {
+ fputs(hbhtml_translation_table[62], job->of);
+ } else {
+ fputc('>', job->of);
+ }
+ } break;
+ case '"': {
+ if((job->options) & HB_JOB_OPT_CODE) {
+ fputs(hbhtml_translation_table[34], job->of);
+ } else {
+ fputc('"', job->of);
+ }
+ } break;
+ case '%': {
+ fputc('%', job->of); /* PROBABLY NEED A CODE */
+ } break;
+ default: {
+ sz = (size_t)c32;
+ sz &= (size_t)0x007FU;
+ if(hbhtml_translation_table[sz]) {
+ fputs(hbhtml_translation_table[sz], job->of);
+ } else {
+ fprintf(job->of, "&#x%02lx;", (unsigned long)c32);
+ }
+ } break;
+ }
+ } else {
+ if(((dk3_c32_t)256) > c32) {
+ sz = (size_t)c32;
+ sz &= (size_t)0x00FFU;
+ if(hbhtml_translation_table[sz]) {
+ fputs(hbhtml_translation_table[sz], job->of);
+ } else {
+ fprintf(job->of, "&#x%02lx;", (unsigned long)c32);
+ }
+ } else {
+ if(HB_CS_UTF_8 == job->cs) {
+ sz = dk3enc_uc2utf8(c32, ub, sizeof(ub));
+ for(i = 0; i < sz; i++) { fputc(ub[i], job->of); }
+ } else {
+ if(((dk3_c32_t)0x010000UL) > c32) {
+ fprintf(job->of, "&#x%04lx;", (unsigned long)c32);
+ } else {
+ if(((dk3_c32_t)0x01000000UL) > c32) {
+ fprintf(job->of, "&#x%06lx;", (unsigned long)c32);
+ } else {
+ fprintf(job->of, "&#x%08lx;", (unsigned long)c32);
+ }
+ }
+ }
+ }
+ } $? "- hbhtml_c32"
+}
+
+
+
+/** Flush the shipout buffer.
+ @param job Job structure.
+*/
+static
+void
+hbhtml_flush_shipout(hb_job_t *job)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ size_t i; /* Process all characters */
+#else
+ dk3_c16_t const *sp; /* Current source start */
+ dk3_c32_t c32; /* Current 32-bit char to process */
+ size_t sl; /* Remaining source length */
+ size_t used; /* Source chars used */
+#endif
+#else
+ unsigned char const *sp; /* Current source start */
+ dk3_c32_t c32; /* Current 32-bit char to process */
+ size_t sl; /* Remaining source length */
+ size_t used; /* Source chars used */
+ size_t i; /* Process all chars from buffer */
+ unsigned char c; /* Current char to process */
+#endif
+ $? "+ hbhtml_flush_shipout"
+ if(job->shipused) {
+ if(job->shipused < job->bs) {
+ (job->shipbuffer)[job->shipused] = dkT('\0');
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ for(i = 0; i < (job->shipused); i++) {
+ hbhtml_c32(job, (job->shipused)[i]);
+ }
+#else
+ sp = (dk3_c16_t const *)(job->shipbuffer);
+ sl = job->shipused;
+ while(sl > 0) {
+ used = 0;
+ if(dk3enc_utf162uc(&c32, sp, sl, &used)) {
+ hbhtml_c32(job, c32);
+ if(used > 0) {
+ if(sl >= used) {
+ sl = sl - used;
+ sp = &(sp[used]);
+ } else {
+ sl = 0;
+ /* ERROR: Decoding */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 119);
+ }
+ } else {
+ sl = 0;
+ /* ERROR: Decoding */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 119);
+ }
+ } else {
+ sl = 0;
+ /* ERROR: Decoding */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 119);
+ }
+ }
+#endif
+#else
+ $? "+ shipout ASCII"
+ if(dk3app_get_encoding(job->app) == DK3_ENCODING_UTF8) {
+ $? ". UTF-8"
+ sp = (unsigned char const *)(job->shipbuffer);
+ sl = job->shipused;
+ while(sl > 0) {
+ used = 0;
+ if(dk3enc_utf82uc(&c32, sp, sl, &used)) {
+ hbhtml_c32(job, c32);
+ if(used > 0) {
+ if(sl >= used) {
+ sl = sl - used;
+ sp = &(sp[used]);
+ } else {
+ sl = 0;
+ /* ERROR: Decoding problem */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 118);
+ }
+ } else {
+ sl = 0;
+ /* ERROR: Decoding problem */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 118);
+ }
+ } else {
+ sl = 0;
+ /* ERROR: Decoding problem */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 118);
+ }
+ }
+ } else {
+ sp = (unsigned char const *)(job->shipbuffer);
+ for(i = 0; i < (job->shipused); i++) {
+ c = sp[i];
+ c32 = (dk3_c32_t)c;
+ c32 &= 0x000000FFUL;
+ hbhtml_c32(job, c32);
+ }
+ }
+ $? "- shipout ASCII"
+#endif
+ }
+ }
+ job->shipused = 0;
+ $? "- hbhtml_flush_shipout"
+}
+
+
+
+/** Add one character to shipout buffer.
+ @param job Job structure.
+ @param c Character to add.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_shipout(hb_job_t *job, dkChar c)
+{
+ int back = 1;
+ $? "+ hbhtml_shipout"
+ if((job->shipused) < (job->bs - 1)) {
+ (job->shipbuffer)[job->shipused] = c;
+ job->shipused += 1;
+ if(job->shipused >= job->bs) {
+ back = 0;
+ }
+ } else {
+ back = 0;
+ } $? "- hbhtml_shipout %d", back
+ return back;
+}
+
+
+
+/** Add one character to special command buffer.
+ @param job Job structure.
+ @param c Character to add.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_add_to_special(hb_job_t *job, dkChar c)
+{
+ int back = 1;
+ $? "+ hbhtml_add_to_special"
+ if((job->spused) < (job->bs - 1)) {
+ (job->special)[job->spused] = c;
+ job->spused += 1;
+ if(job->spused >= job->bs) {
+ back = 0;
+ }
+ } else {
+ back = 0;
+ } $? "- hbhtml_add_to_special %d", back
+ return back;
+}
+
+
+
+/** Classify a character for processing by state machine 1.
+ @param c Character to classify.
+ @return Classification result.
+*/
+static
+int
+hbhtml_classify_for_stm1(dkChar c)
+{
+ int back = STM1_I_ANY;
+ switch(c) {
+ case dkT('%'): {
+ back = STM1_I_PERCENT;
+ } break;
+ case dkT('\\'): {
+ back = STM1_I_BS;
+ } break;
+ }
+ return back;
+}
+
+
+
+/** Write text to HTML output file.
+ @param job Job structure.
+ @param text Text to write.
+ @return 1 on success, 0 on error.
+*/
+int
+hbhtml_output_for_text(hb_job_t *job, dkChar const *text)
+{
+ size_t sz;
+#if VERSION_BEFORE_20131219
+ int oldcode;
+#endif
+ int back = 0;
+ $? "+ hbhtml_output_for_text \"%!ds\"", TR_STR(text)
+ if((job) && (text)) {
+ sz = dk3str_len(text);
+ if(sz < job->bs) { $? ". size ok"
+#if VERSION_BEFORE_20131219
+ oldcode = (((job->options) & HB_JOB_OPT_CODE) ? 1 : 0);
+ job->options &= (~(HB_JOB_OPT_CODE));
+#endif
+ dk3str_cpy(job->shipbuffer, text);
+ job->shipused = sz; $? ". text copied to shipout buffer"
+ hbhtml_flush_shipout(job); $? ". flush completed"
+ back = 1;
+ job->spused = 0;
+ job->shipused = 0;
+#if VERSION_BEFORE_20131219
+ if(oldcode) {
+ job->options |= HB_JOB_OPT_CODE;
+ }
+#endif
+ }
+ } $? "- hbhtml_output_for_text %d", back
+ return back;
+}
+
+
+
+/** Write text to URL output file.
+ @param job Job structure.
+ @param text Text to write.
+ @return 1 on success, 0 on error.
+*/
+int
+hbhtml_url_output_for_text(hb_job_t *job, dkChar const *text)
+{
+ size_t sz; /* Text length */
+ int back = 0;
+ $? "+ hbhtml_url_output_for_text \"%!ds\"", TR_STR(text)
+ if((job) && (text)) {
+ sz = dk3str_len(text);
+ if(sz < job->bs) {
+ dk3str_cpy(job->shipbuffer, text);
+ job->shipused = sz;
+ hbhtml_url_flush_shipout(job);
+ back = 1;
+ job->spused = 0;
+ job->shipused = 0;
+ }
+ } $? "- hbhtml_url_output_for_text %d", back
+ return back;
+}
+
+
+
+/** Process the title special command.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_process_sp_title(hb_job_t *job)
+{
+ int back = 0;
+ $? "+ hbhtml_process_sp_title"
+ if(job->rootnode) { $? ". have node"
+ if((job->rootnode)->title) { $? ". have title"
+ if(hbhtml_output_for_text(job, (job->rootnode)->title)) {
+ back = 1;
+ }
+ }
+ } $? "- hbhtml_process_sp_title %d", back
+ return back;
+}
+
+
+
+/** Build new file name if necessary.
+ @param oldname Existing file name.
+ @param fnb File name buffer.
+ @param fnbsz Size of file name buffer.
+ @param sc Sub command.
+ @param newsuffix New file name suffix.
+ @param job Job structure.
+ @param ecp Error code variable pointer.
+*/
+static
+dkChar *
+hbhtml_sc_fn(
+ dkChar *oldname,
+ dkChar *fnb,
+ size_t fnbsz,
+ dkChar *sc,
+ dkChar const *newsuffix,
+ hb_job_t *job,
+ int *ecp
+)
+{
+ dk3_stat_t stb;
+ dkChar *back;
+ dkChar *sp;
+ $? "+ hbhtml_sc_fn \"%!ds\"", TR_STR(oldname)
+ $? ". sc=\"%!ds\"", TR_STR(sc)
+ $? ". newsuffix=\"%!ds\"", TR_STR(newsuffix)
+ back = oldname;
+ if(!(back)) {
+ /* Remove suffix if it matches subcommand.
+ */
+ sp = dk3str_get_suffix(fnb);
+ if(sp) {
+ if(0 == dk3str_casecmp(&(sp[1]), sc)) {
+ *sp = dkT('\0');
+ }
+ }
+ /* Add new suffix.
+ */
+ if(fnbsz > (dk3str_len(fnb) + dk3str_len(newsuffix))) {
+ dk3str_cat(fnb, newsuffix);
+ /* If file exists, use file name from fnb.
+ */
+ if(dk3sf_stat_app(&stb, fnb, NULL)) {
+ switch(stb.ft) {
+ case DK3_FT_REGULAR: {
+ back = fnb;
+ } break;
+ default: {
+ /* ERROR: Not a regular file */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 255, 256, fnb);
+ } break;
+ }
+ } else {
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 84, 85, fnb);
+ }
+ } else {
+ /* ERROR: File name too long */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 65, 66, fnb);
+ if(ecp) { *ecp = 1; }
+ }
+ } $? "- hbhtml_sc_fn \"%!ds\"", TR_STR(back)
+ return back;
+}
+
+
+
+/** Process image special command.
+ @param job Job structure.
+ @param pa Pointer to arguments.
+ @param sc Subcommand, may be NULL.
+ @param in_template Flag: Processing the template.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_process_sp_image(hb_job_t *job, dkChar *pa, dkChar *sc, int in_template)
+{
+ dkChar svgnbuf[DK3_MAX_PATH]; /* SVG file name */
+ dkChar pdfnbuf[DK3_MAX_PATH]; /* PDF file name */
+ dkChar pngnbuf[DK3_MAX_PATH]; /* PNG file name */
+ dk3_key_value_t kv[30]; /* Parameters */
+ dkChar wbuf[64]; /* Width buffer */
+ dkChar hbuf[64]; /* Height buffer */
+ dkChar *align = NULL; /* Align specified */
+ dkChar *alt = NULL; /* Alternative text */
+ dkChar *border = NULL; /* Border specified */
+ dkChar *height = NULL; /* Height specified */
+ dkChar *hspace = NULL; /* Horiz space specified */
+ dkChar *longdesc = NULL; /* Longdesc specified */
+ dkChar *name = NULL; /* Name. */
+ dkChar *src = NULL; /* Image file name */
+ dkChar *usemap = NULL; /* Usemap text */
+ dkChar *vspace = NULL; /* Vertical space specified */
+ dkChar *width = NULL; /* Width specified */
+ dkChar *larger = NULL; /* File name large resolution */
+ dkChar *pdf = NULL; /* PDF file name */
+ dkChar *clptr = NULL; /* Image CSS class */
+ dkChar *idptr = NULL; /* Image CSS id */
+ dkChar *title = NULL; /* Image title */
+ dkChar *capt = NULL; /* Image caption */
+ dkChar *svg = NULL; /* SVG file name */
+ dkChar *fnptr = NULL; /* The file argument */
+ unsigned long xw = 0UL; /* Width found */
+ unsigned long xh = 0UL; /* Height found */
+ size_t sz; /* Size of key value array */
+ size_t i; /* Traverse key value array */
+ int cache = 0; /* Flag: Cache width+height */
+ int ismap = 0; /* Flag: Write isamp attrib */
+ int back = 0; /* Result */
+ int tispec = 0; /* Flag: Title specified */
+ int caspec = 0; /* Flag: Capction specified */
+ int svgwh = 0; /* Flag: For SVG width+height */
+ int dodiv = 0; /* Img in div(1) or table(2) */
+ int center = 0; /* Flag: Center image */
+ int downlo = 0; /* Flag: Create download div */
+ int haveli = 0; /* Already have written link */
+ int crobj = 1; /* Flag: Create object */
+ int novsp = 0; /* Flag: No vertical space. */
+ int fnerr = 0; /* Flag: Error related file */
+ $? "+ hbhtml_process_sp_image pa=\"%!ds\" sc=\"%!ds\"", TR_STR(pa), TR_STR(sc)
+ sz = DK3_SIZEOF(kv,dk3_key_value_t);
+ svgnbuf[0] = pdfnbuf[0] = pngnbuf[0] = dkT('\0');
+ if(dk3str_to_key_value(kv, &sz, pa, job->app)) {
+ $? ". sz = %u", (unsigned)sz
+ if(sc) { $? ". sub command specified"
+ tispec = 1;
+ downlo = 1;
+ dodiv = 2;
+ if(-1 < dk3str_array_index(hbhtml_no_vspace_suffixes, sc, 0)) {
+ novsp = 1;
+ }
+ }
+ for(i = 0; i < sz; i++) {
+ if(kv[i].key) { $? ". key = \"%!ds\"", kv[i].key
+ switch(dk3str_array_abbr(hbhtml_img_keys, kv[i].key, dkT('$'), 0)) {
+ case 0: { $? ". align"
+ align = kv[i].val;
+ } break;
+ case 1: { $? ". alt"
+ alt = kv[i].val;
+ } break;
+ case 2: { $? ". border"
+ border = kv[i].val;
+ } break;
+ case 3: { $? ". height"
+ height = kv[i].val;
+ } break;
+ case 4: { $? ". hspace"
+ hspace = kv[i].val;
+ } break;
+ case 5: { /* ismap */ $? ". ismap"
+ if(kv[i].val) {
+ if(dk3str_is_bool(kv[i].val)) {
+ if(dk3str_is_on(kv[i].val)) {
+ ismap = 1;
+ } else {
+ ismap = 0;
+ }
+ }
+ } else {
+ ismap = 1;
+ }
+ } break;
+ case 6: { $? ". longdesc"
+ longdesc = kv[i].val;
+ } break;
+ case 7: { $? ". name"
+ name = kv[i].val;
+ } break;
+ case 8: { $? ". src"
+ src = kv[i].val;
+ } break;
+ case 9: { $? ". usemap"
+ usemap = kv[i].val;
+ } break;
+ case 10: { $? ". vspace"
+ vspace = kv[i].val;
+ } break;
+ case 11: { $? ". width"
+ width = kv[i].val;
+ } break;
+ case 12: { $? ". set larger to \"%!ds\"", TR_STR(kv[i].val)
+ larger = kv[i].val;
+ } break;
+ case 13: { $? ". pdf"
+ pdf = kv[i].val;
+ } break;
+ case 14: { /* caching */ $? ". cache"
+ if(kv[i].val) {
+ if(dk3str_is_bool(kv[i].val)) {
+ if(dk3str_is_on(kv[i].val)) {
+ cache = 1;
+ } else {
+ cache = 0;
+ }
+ }
+ } else {
+ cache = 1;
+ }
+ } break;
+ case 15: { $? ". title = \"%!ds\"", TR_STR(kv[i].val)
+ title = kv[i].val;
+ tispec = 1;
+ } break;
+ case 16: { $? ". class = \"%!ds\"", TR_STR(kv[i].val)
+ clptr = kv[i].val;
+ } break;
+ case 17: { $? ". id = \"%!ds\"", TR_STR(kv[i].val)
+ idptr = kv[i].val;
+ } break;
+ case 18: { /* div */
+ if(kv[i].val) {
+ if(dk3str_is_bool(kv[i].val)) {
+ dodiv = ((dk3str_is_on(kv[i].val)) ? 1 : 0);
+ } else {
+ /* ERROR: Not boolean */
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, kv[i].val);
+ }
+ } else {
+ dodiv = 1;
+ }
+ } break;
+ case 19: { /* caption */
+ caspec = 1;
+ capt = kv[i].val;
+ } break;
+ case 20: { /* centered */
+ if(kv[i].val) {
+ if(dk3str_is_bool(kv[i].val)) {
+ center = ((dk3str_is_on(kv[i].val)) ? 1 : 0);
+ } else {
+ /* ERROR: Not boolean */
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, kv[i].val);
+ }
+ } else {
+ center = 1;
+ }
+ } break;
+ case 21: { /* svg */
+ svg = kv[i].val;
+ } break;
+ case 22: { /* svgwh */
+ if(kv[i].val) {
+ if(dk3str_is_bool(kv[i].val)) {
+ svgwh = ((dk3str_is_on(kv[i].val)) ? 1 : 0);
+ } else {
+ /* ERROR: Not boolean */
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, kv[i].val);
+ }
+ } else {
+ svgwh = 1;
+ }
+ } break;
+ case 23: { /* downloads */
+ if(kv[i].val) {
+ if(dk3str_is_bool(kv[i].val)) {
+ downlo = ((dk3str_is_on(kv[i].val)) ? 1 : 0);
+ } else {
+ /* ERROR: Not boolean */
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, kv[i].val);
+ }
+ } else {
+ downlo = 1;
+ }
+ } break;
+ case 24: {
+ if(kv[i].val) {
+ if(dk3str_is_bool(kv[i].val)) {
+ crobj = ((dk3str_is_on(kv[i].val)) ? 1 : 0);
+ } else {
+ /* ERROR: Not boolean */
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, kv[i].val);
+ }
+ } else {
+ crobj = 1;
+ }
+ } break;
+ case 25: {
+ if(kv[i].val) {
+ if(dk3str_is_bool(kv[i].val)) {
+ if(dk3str_is_on(kv[i].val)) {
+ if(1 == dodiv) {
+ /* Warning: Overwriting div by table */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 66);
+ }
+ dodiv = 2;
+ } else {
+ if(1 != dodiv) {
+ dodiv = 0;
+ }
+ }
+ } else {
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, kv[i].val);
+ }
+ } else {
+ if(1 == dodiv) {
+ /* Warning: Overwriting div by table */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 66);
+ }
+ dodiv = 2;
+ }
+ } break;
+ case 26: {
+ if(kv[i].val) {
+ if(dk3str_is_bool(kv[i].val)) {
+ novsp = ((dk3str_is_on(kv[i].val)) ? 1 : 0);
+ } else {
+ /* ERROR: Not a boolean */
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, kv[i].val);
+ }
+ } else {
+ novsp = 1;
+ }
+ } break;
+ case 27: { $? ". file argument"
+ if(kv[i].val) {
+ if(fnptr) { $? ". overwriting"
+ /* WARNING: Overwriting file setting! */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 86);
+ }
+ fnptr = kv[i].val;
+ } else { $? "! missing file name"
+ /* ERROR: No file name specified */
+ }
+ } break;
+ }
+ }
+ }
+ if(fnptr) { $? ". file argument specified"
+ if(dk3str_len(fnptr) < DK3_SIZEOF(svgnbuf,dkChar)) {
+ dk3str_cpy(svgnbuf, fnptr);
+ dk3str_cpy(pdfnbuf, fnptr);
+ dk3str_cpy(pngnbuf, fnptr);
+ src = hbhtml_sc_fn(
+ src, pngnbuf, DK3_SIZEOF(pngnbuf,dkChar), sc,
+ hbhtml_image_filename_suffixes[0], job, &fnerr
+ );
+ svg = hbhtml_sc_fn(
+ svg, svgnbuf, DK3_SIZEOF(svgnbuf,dkChar), sc,
+ hbhtml_image_filename_suffixes[2], job, &fnerr
+ );
+ pdf = hbhtml_sc_fn(
+ pdf, pdfnbuf, DK3_SIZEOF(pdfnbuf,dkChar), sc,
+ hbhtml_image_filename_suffixes[1], job, &fnerr
+ );
+ } else {
+ /* ERROR: Name too long */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 65, 66, fnptr);
+ fnerr = 1;
+ }
+ }
+ if(src) {
+ if(!hbtool_check_filename(job, src)) { src = NULL; }
+ }
+ if(src) {
+ if(0 == fnerr) { back = 1; }
+ if(larger) { $? ". larger=\"%!ds\"", larger
+ if(!hbtool_check_filename(job, larger)) { larger = NULL; }
+ }
+ if(pdf) { $? ". pdf=\"%!ds\"", pdf
+ if(!hbtool_check_filename(job, pdf)) { pdf = NULL; }
+ }
+ if(svg) { $? ". svg=\"%!ds\"", svg
+ if(!hbtool_check_filename(job, svg)) { svg = NULL; }
+ }
+ if(tispec) {
+ if(!(title)) { title = alt; }
+ if(!(title)) { title = src; }
+ }
+ if(caspec) {
+ if(!(capt)) { capt = title; }
+ if(!(capt)) { capt = alt; }
+ }
+ if(!((width) && (height))) {
+ if(hbimgdim_find(job, src, &xw, &xh, cache)) {
+ if((xw) && (xh)) {
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(wbuf, dkT("%lu"), xw);
+ dk3sf_sprintf3(hbuf, dkT("%lu"), xh);
+ if(!(width)) { width = wbuf; }
+ if(!(height)) { height = hbuf; }
+#else
+ if(!(width)) {
+ if (dk3ma_um_to_string(wbuf,DK3_SIZEOF(wbuf,dkChar),(dk3_um_t)xw))
+ {
+ width = wbuf;
+ }
+ }
+ if(!(height)) {
+ if (dk3ma_um_to_string(hbuf,DK3_SIZEOF(hbuf,dkChar),(dk3_um_t)xh))
+ {
+ height = hbuf;
+ }
+ }
+#endif
+ }
+ }
+ }
+ if(capt) { if(!(dodiv)) { dodiv = 2; } }
+ if(downlo) { if(!(dodiv)) { dodiv = 2; } }
+
+ /* Output creation starts here.
+ */
+ if(dodiv) {
+ if(2 == dodiv) {
+ /* div Open outer div */
+ fputs(hbhtml_c8_kw[((novsp) ? (145) : (109))], job->of);
+ /* table */
+ fputs(hbhtml_c8_kw[138], job->of);
+ hbhtml_output_for_text(job, (job->msg)[65]);
+ fputs(hbhtml_c8_kw[143], job->of);
+ /* tr */
+ fputs(hbhtml_c8_kw[139], job->of);
+ /* td */
+ fputs(hbhtml_c8_kw[140], job->of);
+ } else {
+ /* div Open outer div */
+ fputs(hbhtml_c8_kw[109], job->of);
+ /* div Open image div */
+ fputs(hbhtml_c8_kw[(center) ? 111 : 110], job->of);
+ }
+ }
+
+ /* SVG object start.
+ */
+ if((svg) && (crobj)) {
+ /* Opening object tag */
+ fputs(hbhtml_c8_kw[114], job->of);
+ if(!hbhtml_url_output_for_text(job, svg)) { back = 0; }
+ if((svgwh) && (width) && (height)) {
+ fputs(hbhtml_c8_kw[71], job->of);
+ if(!hbhtml_url_output_for_text(job, width)) { back = 0; }
+ fputs(hbhtml_c8_kw[72], job->of);
+ if(!hbhtml_url_output_for_text(job, height)) { back = 0; }
+ }
+ fputs(hbhtml_c8_kw[51], job->of);
+ fputs(hbhtml_c8_kw[0], job->of);
+ /* Object param */
+ fputs(hbhtml_c8_kw[115], job->of);
+ if(!hbhtml_url_output_for_text(job, svg)) { back = 0; }
+ fputs(hbhtml_c8_kw[51], job->of);
+ fputs(hbhtml_c8_kw[0], job->of);
+ }
+
+ /* Image
+ */
+ fputs(hbhtml_c8_kw[2], job->of);
+ fputs(hbhtml_c8_kw[4], job->of);
+ if(!hbhtml_url_output_for_text(job, src)) {
+ back = 0;
+ }
+ fputs(hbhtml_c8_kw[5], job->of);
+ if(name) {
+ fputs(hbhtml_c8_kw[58], job->of);
+ if(!hbhtml_output_for_text(job, name)) {
+ back = 0;
+ }
+ fputs(hbhtml_c8_kw[5], job->of);
+ }
+ fputs(hbhtml_c8_kw[6], job->of);
+ if(alt) {
+ if(!hbhtml_output_for_text(job, alt)) {
+ back = 0;
+ }
+ }
+ fputs(hbhtml_c8_kw[5], job->of);
+ if(title) {
+ fputs(hbhtml_c8_kw[7], job->of);
+ if(!hbhtml_output_for_text(job, title)) {
+ back = 0;
+ }
+ fputs(hbhtml_c8_kw[5], job->of);
+ }
+ if(longdesc) {
+ fputs(hbhtml_c8_kw[59], job->of);
+ if(!hbhtml_url_output_for_text(job, longdesc)) {
+ back = 0;
+ }
+ fputs(hbhtml_c8_kw[5], job->of);
+ }
+ if((width) && (height)) {
+ fputs(hbhtml_c8_kw[9], job->of);
+ if(!hbhtml_url_output_for_text(job, width)) {
+ back = 0;
+ }
+ fputs(hbhtml_c8_kw[5], job->of);
+ fputs(hbhtml_c8_kw[10], job->of);
+ if(!hbhtml_url_output_for_text(job, height)) {
+ back = 0;
+ }
+ fputs(hbhtml_c8_kw[5], job->of);
+ }
+ fputs(hbhtml_c8_kw[8], job->of);
+ if(border) {
+ if(!hbhtml_url_output_for_text(job, border)) {
+ back = 0;
+ }
+ } else {
+ fputs(hbhtml_c8_kw[57], job->of);
+ }
+ fputs(hbhtml_c8_kw[5], job->of);
+ if(clptr) {
+ fputs(hbhtml_c8_kw[60], job->of);
+ if(!hbhtml_url_output_for_text(job, clptr)) {
+ back = 0;
+ }
+ fputs(hbhtml_c8_kw[5], job->of);
+ }
+ if(idptr) {
+ fputs(hbhtml_c8_kw[61], job->of);
+ if(!hbhtml_url_output_for_text(job, idptr)) {
+ back = 0;
+ }
+ fputs(hbhtml_c8_kw[5], job->of);
+ }
+ if(usemap) {
+ fputs(hbhtml_c8_kw[62], job->of);
+ if(!hbhtml_url_output_for_text(job, usemap)) {
+ back = 0;
+ }
+ fputs(hbhtml_c8_kw[5], job->of);
+ }
+ if(align) {
+ fputs(hbhtml_c8_kw[63], job->of);
+ if(!hbhtml_url_output_for_text(job, align)) {
+ back = 0;
+ }
+ fputs(hbhtml_c8_kw[5], job->of);
+ }
+ if(hspace) {
+ fputs(hbhtml_c8_kw[64], job->of);
+ if(!hbhtml_url_output_for_text(job, hspace)) {
+ back = 0;
+ }
+ fputs(hbhtml_c8_kw[5], job->of);
+ }
+ if(vspace) {
+ fputs(hbhtml_c8_kw[65], job->of);
+ if(!hbhtml_url_output_for_text(job, vspace)) {
+ back = 0;
+ }
+ fputs(hbhtml_c8_kw[5], job->of);
+ }
+ if(ismap) {
+ fputs(hbhtml_c8_kw[66], job->of);
+ }
+ fputs(hbhtml_c8_kw[3], job->of);
+ fputs(hbhtml_c8_kw[0], job->of);
+
+ /* SVG object end.
+ */
+ if((svg) && (crobj)) {
+ /* Closing object tag */
+ fputs(hbhtml_c8_kw[73], job->of);
+ fputs(hbhtml_c8_kw[0], job->of);
+ }
+
+ /* Table or div end
+ */
+ if(dodiv) {
+ if(capt) {
+ /* Print caption
+ */
+ fputs(hbhtml_c8_kw[116], job->of);
+ if(!hbhtml_output_for_text(job, capt)) { back = 0; }
+ fputs(hbhtml_c8_kw[117], job->of);
+ /* fputs(hbhtml_c8_kw[0], job->of); */
+ }
+ if(2 == dodiv) {
+ /* !td Close image td */
+ fputs(hbhtml_c8_kw[97], job->of);
+ } else {
+ /* !div Close inner div */
+ fputs(hbhtml_c8_kw[47], job->of);
+ }
+ if(downlo) {
+ if(2 == dodiv) {
+ /* td space !td Space div */
+ fputs(hbhtml_c8_kw[141], job->of);
+ /* td Open download td */
+ fputs(hbhtml_c8_kw[142], job->of);
+ } else {
+ /* p Open download p */
+ fputs(hbhtml_c8_kw[112], job->of);
+ }
+ /* Write download links */
+ {
+ haveli = 0;
+ if(svg) { $? ". svg = \"%!ds\"", svg
+ haveli = 1;
+ fputs(hbhtml_c8_kw[68], job->of);
+ if(!hbhtml_url_output_for_text(job, svg)) { back = 0; }
+ fputs(hbhtml_c8_kw[69], job->of);
+ fputs(hbhtml_c8_kw[118], job->of);
+ fputs(hbhtml_c8_kw[40], job->of);
+ if(!hbhtml_output_for_text(job, (job->kwnl)[33])) { back = 0; }
+ fputs(hbhtml_c8_kw[41], job->of);
+ }
+ if(pdf) { $? ". pdf = \"%!ds\"", pdf
+ if(haveli) {
+ fputs(hbhtml_c8_kw[105], job->of);
+ }
+ haveli = 1;
+ fputs(hbhtml_c8_kw[68], job->of);
+ if(!hbhtml_url_output_for_text(job, pdf)) { back = 0; }
+ fputs(hbhtml_c8_kw[69], job->of);
+ fputs(hbhtml_c8_kw[119], job->of);
+ fputs(hbhtml_c8_kw[40], job->of);
+ if(!hbhtml_output_for_text(job, (job->kwnl)[34])) { back = 0; }
+ fputs(hbhtml_c8_kw[41], job->of);
+ }
+ if(larger) { $? ". larger = \"%!ds\"", larger
+ if(haveli) {
+ fputs(hbhtml_c8_kw[105], job->of);
+ }
+ haveli = 1;
+ fputs(hbhtml_c8_kw[68], job->of);
+ if(!hbhtml_url_output_for_text(job, larger)) { back = 0; }
+ fputs(hbhtml_c8_kw[69], job->of);
+ fputs(hbhtml_c8_kw[40], job->of);
+ if(!hbhtml_output_for_text(job, (job->msg)[58])) { back = 0; }
+ fputs(hbhtml_c8_kw[41], job->of);
+ }
+ if(haveli) {
+ fputs(hbhtml_c8_kw[105], job->of);
+ }
+ fputs(hbhtml_c8_kw[68], job->of);
+ if(!hbhtml_url_output_for_text(job, src)) { back = 0; }
+ fputs(hbhtml_c8_kw[69], job->of);
+ fputs(hbhtml_c8_kw[40], job->of);
+ if(!hbhtml_output_for_text(job, (job->msg)[59])) { back = 0; }
+ fputs(hbhtml_c8_kw[41], job->of);
+ }
+ if(2 == dodiv) {
+ /* !td Close download td */
+ fputs(hbhtml_c8_kw[97], job->of);
+ } else {
+ /* !p Close download p */
+ fputs(hbhtml_c8_kw[113], job->of);
+ }
+ } else {
+ if(2 == dodiv) {
+ } else {
+ fputs(hbhtml_c8_kw[120], job->of);
+ }
+ }
+ if(2 == dodiv) {
+ /* !tr */
+ fputs(hbhtml_c8_kw[95], job->of);
+ /* !table */
+ fputs(hbhtml_c8_kw[93], job->of);
+ /* !div Close outer div */
+ fputs(hbhtml_c8_kw[47], job->of);
+ } else {
+ /* !div Close outer div */
+ fputs(hbhtml_c8_kw[47], job->of);
+ }
+#if 0
+ if(2 == dodiv) {
+ } else {
+ /* Close image div
+ */
+ fputs(hbhtml_c8_kw[47], job->of);
+ if(downlo) {
+ /* Open outer download div */
+ fputs(hbhtml_c8_kw[112], job->of);
+ /* Download links */
+ {
+ haveli = 0;
+ if(svg) { $? ". svg = \"%!ds\"", svg
+ haveli = 1;
+ fputs(hbhtml_c8_kw[68], job->of);
+ if(!hbhtml_url_output_for_text(job, svg)) { back = 0; }
+ fputs(hbhtml_c8_kw[69], job->of);
+ fputs(hbhtml_c8_kw[118], job->of);
+ fputs(hbhtml_c8_kw[40], job->of);
+ if(!hbhtml_output_for_text(job, (job->kwnl)[33])) { back = 0; }
+ fputs(hbhtml_c8_kw[41], job->of);
+ }
+ if(pdf) { $? ". pdf = \"%!ds\"", pdf
+ if(haveli) {
+ fputs(hbhtml_c8_kw[105], job->of);
+ }
+ haveli = 1;
+ fputs(hbhtml_c8_kw[68], job->of);
+ if(!hbhtml_url_output_for_text(job, pdf)) { back = 0; }
+ fputs(hbhtml_c8_kw[69], job->of);
+ fputs(hbhtml_c8_kw[119], job->of);
+ fputs(hbhtml_c8_kw[40], job->of);
+ if(!hbhtml_output_for_text(job, (job->kwnl)[34])) { back = 0; }
+ fputs(hbhtml_c8_kw[41], job->of);
+ }
+ if(larger) { $? ". larger = \"%!ds\"", larger
+ if(haveli) {
+ fputs(hbhtml_c8_kw[105], job->of);
+ }
+ haveli = 1;
+ fputs(hbhtml_c8_kw[68], job->of);
+ if(!hbhtml_url_output_for_text(job, larger)) { back = 0; }
+ fputs(hbhtml_c8_kw[69], job->of);
+ fputs(hbhtml_c8_kw[40], job->of);
+ if(!hbhtml_output_for_text(job, (job->msg)[58])) { back = 0; }
+ fputs(hbhtml_c8_kw[41], job->of);
+ }
+ if(haveli) {
+ fputs(hbhtml_c8_kw[105], job->of);
+ }
+ fputs(hbhtml_c8_kw[68], job->of);
+ if(!hbhtml_url_output_for_text(job, src)) { back = 0; }
+ fputs(hbhtml_c8_kw[69], job->of);
+ fputs(hbhtml_c8_kw[40], job->of);
+ if(!hbhtml_output_for_text(job, (job->msg)[59])) { back = 0; }
+ fputs(hbhtml_c8_kw[41], job->of);
+ }
+ /* Close output download div */
+ fputs(hbhtml_c8_kw[113], job->of);
+ } else {
+ fputs(hbhtml_c8_kw[120], job->of);
+ }
+ /* Close outer div
+ */
+ fputs(hbhtml_c8_kw[47], job->of);
+ }
+#endif
+ }
+
+ /* Output creation is finished here.
+ Now we add the files to copy to the list.
+ */
+ if(src) { if(!hbtool_add_url(job, src)) { back = 0; } }
+ if(larger) { if(!hbtool_add_url(job, larger)) { back = 0; } }
+ if(pdf) { if(!hbtool_add_url(job, pdf)) { back = 0; } }
+ if(svg) { if(!hbtool_add_url(job, svg)) { back = 0; } }
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 40);
+ } $? "- hbhtml_process_sp_image %d", back
+ return back;
+}
+
+
+
+/** Write current node item to navigation menu.
+ @param job Job structure.
+ @param nptr Current node.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_link_to_current_node(hb_job_t *job, hb_node_t *nptr)
+{
+ dkChar *p; /* Text to show */
+ int back = 1;
+ $? "+ hbhtml_link_to_current_node"
+ p = nptr->shorttitle;
+ if(!(p)) { p = nptr->title; }
+ if(p) {
+ fputs(hbhtml_c8_kw[34], job->of);
+ if(nptr->title) {
+ fputs(hbhtml_c8_kw[7], job->of);
+ if(hbtool_write_header_number(job, nptr)) {
+ fputs(hbhtml_c8_kw[1], job->of);
+ }
+ if(!hbhtml_output_for_text(job, nptr->title)) { back = 0; }
+ fputs(hbhtml_c8_kw[5], job->of);
+ }
+ fputs(hbhtml_c8_kw[3], job->of);
+ if (!hbhtml_output_for_text(job, p)) { back = 0; }
+ fputs(hbhtml_c8_kw[35], job->of);
+ } else {
+ back = 0; $? "! ERROR"
+ } $? "- hbhtml_link_to_current_node %d", back
+ return back;
+}
+
+
+
+/** Write opening link tag to HTML output.
+ @param job Job structure.
+ @param cl Class name.
+ @param ti Title.
+ @param dp Destination.
+ @param tp Type (optional).
+ @param nptr Current node.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_write_link_start(
+ hb_job_t *job,
+ char const *cl,
+ dkChar const *ti,
+ dkChar const *dp,
+ dkChar const *tp,
+ hb_node_t *nptr
+)
+{
+ int back = 0;
+ $? "+ hbhtml_write_link_start"
+ if(dp) {
+ back = 1;
+ fputs(hbhtml_c8_kw[39], job->of);
+ if(!(hbhtml_url_output_for_text(job, dp))) {
+ back = 0; $? "! ERROR"
+ }
+ fputs(hbhtml_c8_kw[42], job->of);
+ if(cl) {
+ fputs(hbhtml_c8_kw[43], job->of);
+ if(EOF == fputs(cl, job->of)) { back = 0; }
+ fputs(hbhtml_c8_kw[42], job->of);
+ }
+ if(ti) {
+ fputs(hbhtml_c8_kw[44], job->of);
+ if(hbtool_write_header_number(job, nptr)) {
+ fputs(hbhtml_c8_kw[1], job->of);
+ }
+ if(!(hbhtml_output_for_text(job, ti))) {
+ back = 0; $? "! ERROR"
+ }
+ fputs(hbhtml_c8_kw[42], job->of);
+ }
+ if(tp) {
+ fputs(hbhtml_c8_kw[45], job->of);
+ if(!(hbhtml_output_for_text(job, tp))) {
+ back = 0; $? "! ERROR"
+ }
+ fputs(hbhtml_c8_kw[42], job->of);
+ }
+ fputs(hbhtml_c8_kw[40], job->of);
+ } $? "- hbhtml_write_link_start %d", back
+ return back;
+}
+
+
+
+/** Write closing link tag.
+ @param job Job structure.
+*/
+static
+void
+hbhtml_write_link_end(hb_job_t *job)
+{
+ fputs(hbhtml_c8_kw[41], job->of);
+ $? "= hbhtml_write_link_end"
+}
+
+
+
+
+/** Write a link to HTML output.
+ @param job Job structure.
+ @param cl Class name.
+ @param ti Title.
+ @param dp Destination.
+ @param tp Type (optional).
+ @param tx Link text.
+ @param nptr Current node.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_write_link(
+ hb_job_t *job,
+ char const *cl,
+ dkChar const *ti,
+ dkChar const *dp,
+ dkChar const *tp,
+ dkChar const *tx,
+ hb_node_t *nptr
+)
+{
+ int back = 0;
+ $? "+ hbhtml_write_link"
+ if((tx) && (dp)) {
+ back = 1;
+ if(!(hbhtml_write_link_start(job, cl, ti, dp, tp, nptr))) {
+ back = 0; $? "! ERROR"
+ }
+ if(!(hbhtml_output_for_text(job, tx))) {
+ back = 0; $? "! ERROR"
+ }
+ hbhtml_write_link_end(job);
+ } $? "- hbhtml_write_link %d", back
+ return back;
+}
+
+
+
+int
+hbhtml_create_output_filename(
+ dkChar *dptr,
+ size_t sz,
+ hb_job_t *job,
+ hb_node_t *nptr
+)
+{
+ dkChar const *sptr; /* Suffix for output file */
+ dkChar *p1; /* Suffix position */
+ size_t nsz; /* Summary length name + new suffix */
+ int back = 0;
+ $? "+ hbhtml_create_output_filename dptr=PTR=%d sz=%u nptr=PTR:%d", TR_IPTR(dptr), (unsigned)sz, TR_IPTR(nptr)
+ if (nptr) {
+ dptr[0] = dkT('\0');
+ if(0UL == nptr->objno) { $? ". node 0"
+ if(dk3str_len((job->kwnl)[8]) < sz) {
+ dk3str_cpy(dptr, (job->kwnl)[8]);
+ back = 1;
+ } else {
+ /* ERROR: Name too long! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 65, 66, (job->kwnl)[8]);
+ }
+ } else { $? ". other node"
+ if(nptr->filename) { $? ". have source file name"
+ if(dk3str_len(nptr->filename) < sz) { $? ". length ok"
+ dk3str_cpy(dptr, nptr->filename);
+ p1 = dk3str_get_suffix(dptr);
+ if(p1) {
+ p1++;
+ *p1 = dkT('\0');
+ if(nptr->suffix) {
+ sptr = nptr->suffix;
+ } else {
+ sptr = (job->kwnl)[10];
+ }
+ nsz = dk3str_len(dptr) + dk3str_len(sptr);
+ if(nsz < sz) {
+ dk3str_cat(dptr, sptr);
+ back = 1;
+ } else { $? "! file name too long"
+ /* ERROR: File name too long! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 65, 66, nptr->filename);
+ }
+ } else {
+ if(nptr->suffix) {
+ sptr = nptr->suffix;
+ } else {
+ sptr = (job->kwnl)[10];
+ }
+ nsz = dk3str_len(dptr)+dk3str_len(sptr)+dk3str_len((job->kwnl)[9]);
+ if(nsz < sz) {
+ dk3str_cat(dptr, (job->kwnl)[9]);
+ dk3str_cat(dptr, sptr);
+ back = 1;
+ } else { $? "! file name too long"
+ /* File name too long! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 65, 66, nptr->filename);
+ }
+ }
+ } else { $? "! input file name to long"
+ /* ERROR: Input file name too long! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 65, 66, nptr->filename);
+ }
+ } else { $? "! no source file name"
+ /* ERROR: No source file name! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 24);
+ }
+ }
+ } else { $? "! missing nptr"
+ }
+ $? "- hbhtml_create_output_filename %d \"%!ds\"", back, dptr
+ return back;
+}
+
+
+
+/** Write link to one node to navigation menu.
+ @param job Job structure.
+ @param nptr Node to link to.
+ @param bold Flag: Make link bold.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_link_to_node(hb_job_t *job, hb_node_t *nptr, int bold)
+{
+ dkChar bu[DK3_MAX_PATH]; /* Buffer for destination name */
+ hb_node_t *jnode; /* Link jump destination */
+ dkChar *p1; /* Link title (full) */
+ dkChar *p2; /* Link title (short or full) */
+ int back = 0;
+ $? "+ hbhtml_link_to_node"
+ jnode = nptr;
+ if(!(nptr->filename)) {
+ jnode = nptr->jumpnode;
+ }
+ p1 = nptr->title;
+ p2 = ((nptr->shorttitle) ? (nptr->shorttitle) : (nptr->title));
+ if((p1) && (p2)) {
+ if(jnode) {
+ if(hbhtml_create_output_filename(bu, DK3_SIZEOF(bu,dkChar), job, jnode)) {
+ fputs(hbhtml_c8_kw[36], job->of);
+ back = hbhtml_write_link(
+ job, hbhtml_c8_kw[(bold) ? 144 : 38], p1, bu, NULL, p2, nptr
+ );
+ fputs(hbhtml_c8_kw[37], job->of);
+ }
+ } else {
+ /* ERROR: No text node! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 52, 53, nptr->title);
+ }
+ } $? "- hbhtml_link_to_node %d", back
+ return back;
+}
+
+
+
+/** Write the menu entries for a node.
+ @param job Job structure.
+ @param nptr Node to write menu entries for.
+ @param sepreq Flag: Menu separator required.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_menu_entries_for_node(hb_job_t *job, hb_node_t *nptr, int sepreq)
+{
+ hb_node_t *subnode; /* Current node */
+ hb_node_t *jnptr; /* Jump node for subnode */
+ int active; /* Flag: Active node */
+ int sepdone = 0; /* Flag: Separator done */
+ int bold = 0; /* Flag: Make bold */
+ int back = 1;
+ $? "+ hbhtml_menu_entries_for_node"
+ if(nptr) { $? ". current node \"%!ds\"", TR_STR(nptr->title)
+ dk3sto_it_reset(nptr->i_subnodes);
+ while(NULL != (subnode = (hb_node_t *)dk3sto_it_next(nptr->i_subnodes))) {
+ jnptr = subnode;
+ if(!(jnptr->filename)) { jnptr = jnptr->jumpnode; }
+ if(sepreq) {
+ if(!(sepdone)) {
+ sepdone = 1;
+ fputs(hbhtml_c8_kw[33], job->of);
+ }
+ } $? ". current subnode \"%!ds\"", TR_STR(subnode->title)
+ active = 1;
+ bold = 0;
+#if VERSION_BEFORE_20140109
+ if(nptr->curchild) {
+ if(((nptr->curchild)->objno) == (subnode->objno)) {
+ active = 0;
+ }
+ }
+#else
+ if(job->currentnode) {
+ if(jnptr) {
+ if(jnptr->objno == (job->currentnode)->objno) {
+ active = 0;
+ }
+ }
+ }
+ if(nptr->curchild) {
+ if(((nptr->curchild)->objno) == (subnode->objno)) {
+ bold = 1;
+ }
+ }
+#endif
+ if(active) {
+ hbhtml_link_to_node(job, subnode, bold);
+ } else {
+ hbhtml_link_to_current_node(job, subnode);
+ }
+ }
+ } $? "- hbhtml_menu_entries_for_node %d", back
+ return back;
+}
+
+
+
+/** Check whether a node has sub menu items.
+ @param ptr Node to check.
+ @return 1 if sub items are present, 0 otherwise.
+*/
+static
+int
+hbhtml_have_sub_menu_items(hb_node_t *ptr)
+{
+ int back = 0;
+ $? "+ hbhtml_have_sub_menu_items"
+ dk3sto_it_reset(ptr->i_subnodes);
+ while(NULL != dk3sto_it_next(ptr->i_subnodes)) {
+ back = 1;
+ } $? "- hbhtml_have_sub_menu_items %d", back
+ return back;
+}
+
+
+
+/** Process menu special command.
+ @param job Job structure.
+ @param pa Special command arguments.
+ @return 1 on success, 0 on error (continue), -1 on error (exit).
+*/
+static
+int
+hbhtml_process_sp_menu(hb_job_t *job, dkChar *pa)
+{
+ dk3_key_value_t kv[10]; /* Key value pairs */
+ hb_node_t *mnptr; /* Menu node pointer */
+ size_t sz; /* Size of kv */
+ size_t i; /* Traverse kv */
+ int res; /* Result from writing link */
+ int sep = 0; /* Flag: Need separator */
+ int tv = 0; /* Test value */
+ int mnst = 0; /* Menu style (full) */
+ int sub = 1; /* Include sub menu of current node */
+ int back = 1;
+ $? "+ hbhtml_process_sp_menu \"%!ds\"", pa
+ sz = DK3_SIZEOF(kv,dk3_key_value_t);
+ if(dk3str_to_key_value(kv, &sz, pa, job->app)) {
+ for(i = 0; i < sz; i++) {
+ if(kv[i].key) {
+ switch(dk3str_array_abbr(hbhtml_menu_keys, kv[i].key, dkT('$'), 0)) {
+ case 0: {
+ if(kv[i].val) {
+ tv = dk3str_array_abbr(hbhtml_menu_styles,kv[i].val,dkT('$'),0);
+ if(0 <= tv) {
+ mnst = tv;
+ } else {
+ /* ERROR: Illegal menu style */
+ dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,25,26,kv[i].val);
+ }
+ }
+ } break;
+ case 1: {
+ if(kv[i].val) {
+ sub = ((dk3str_is_on(kv[i].val)) ? 1 : 0);
+ } else {
+ sub = 1;
+ }
+ } break;
+ default: {
+ /* ERROR: Illegal key. */
+ dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,27,26,kv[i].key);
+ } break;
+ }
+ }
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 40);
+ } $? ". mnst=%d sub=%d", mnst, sub
+ if(((job->currentnode)->options) & HB_NODE_OPT_IMPRESSUM) {
+ /* When we are writing the menu for the impressum page,
+ we print the top menu only.
+ */
+ mnst = 3;
+ sub = 0;
+ } $? ". mnst=%d sub=%d", mnst, sub
+ fputs(hbhtml_c8_kw[29], job->of);
+ fputs(hbhtml_c8_kw[31], job->of);
+ /* Impressum node first, separator.
+ */
+ if(job->impressumnode) { $? ". have impressum node"
+ if(((job->currentnode)->options) & HB_NODE_OPT_IMPRESSUM) {
+ if(!hbhtml_link_to_current_node(job, job->impressumnode)) {
+ back = 0; $? "! ERROR"
+ }
+ } else {
+ if(!hbhtml_link_to_node(job, job->impressumnode, 0)) {
+ back = 0; $? "! ERROR"
+ }
+ }
+ /* Separator */
+ fputs(hbhtml_c8_kw[33], job->of);
+ } else {
+ if(job->impressumlink) { $? ". have impressum link"
+ fputs(hbhtml_c8_kw[36], job->of);
+ res = hbhtml_write_link(
+ job, hbhtml_c8_kw[38], (job->msg)[0], job->impressumlink,
+ NULL, (job->msg)[0], NULL
+ );
+ fputs(hbhtml_c8_kw[37], job->of);
+ if(!(res)) {
+ back = 0; $? "! ERROR"
+ }
+ /* Separator */
+ fputs(hbhtml_c8_kw[33], job->of);
+ } else { $? ". no impressum link"
+ }
+ }
+ /* Now real menu(s)
+ 0=reverse, 1=full, 2=current, 3=top
+ */
+ mnptr = job->currentnode;
+ if(mnptr) { $? ". current node: \"%!ds\"", TR_STR(mnptr->title)
+ switch(mnst) {
+ case -1: case 0: case 2: { $? ". reverse or current"
+ if(sub) {
+ if(hbhtml_have_sub_menu_items(mnptr)) { $? " current entry"
+ /* Menu for mnptr without leading space */
+ $? ". menu from current entry"
+ hbhtml_menu_entries_for_node(job, mnptr, 0);
+ sep = 1;
+ }
+ }
+ mnptr = mnptr->parent;
+ if(mnptr) {
+ /* Menu for mnptr with leading space */
+ $? ". menu from parent entry"
+ hbhtml_menu_entries_for_node(job, mnptr, sep);
+ if(2 != mnst) { $? ". grandparents"
+ do {
+ mnptr = mnptr->parent;
+ if(mnptr) {
+ /* Menu for mnptr with leading space */
+ $? ". menu from further parent entry"
+ hbhtml_menu_entries_for_node(job, mnptr, 1);
+ }
+ } while(mnptr);
+ }
+ }
+ } break;
+ case 1: case 3: { $? ". full or top"
+ if(((job->currentnode)->options) & HB_NODE_OPT_IMPRESSUM) {
+ mnptr = job->rootnode;
+ sub = 0;
+ } else {
+ while(mnptr->parent) { mnptr = mnptr->parent; }
+ }
+ /* Menu for mnptr without leading space */
+ $? ". menu entries from root node"
+ hbhtml_menu_entries_for_node(job, mnptr, 0);
+ if(1 == mnst) { $? ". full, continue with children"
+ do {
+ mnptr = mnptr->curchild;
+ if(mnptr) {
+ if(mnptr->curchild) {
+ /* Menu for mnptr with leading space */
+ $? ". menu entries form parents/grandparents of current node"
+ hbhtml_menu_entries_for_node(job, mnptr, 1);
+ } else {
+ if(sub) {
+ /* Menu entry from current node */
+ $? ". menu from current node"
+ hbhtml_menu_entries_for_node(job, mnptr, 1);
+ }
+ }
+ }
+ } while(mnptr);
+ }
+ } break;
+ }
+ }
+ fputs(hbhtml_c8_kw[32], job->of);
+ fputs(hbhtml_c8_kw[30], job->of); $? "- hbhtml_process_sp_menu %d", back
+ return back;
+}
+
+
+
+/** Write image with link for one navigation icon.
+ @param job Job structure.
+ @param iconfile Icon file name.
+ @param dest Destination URL.
+ @param titlea1 Title part 1 when icon link is active.
+ @param titlea2 Title part 2 when icon link is active.
+ @param titlena Title when icon is not active.
+ @param act Flag: Link is active.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_one_navi_icon(
+ hb_job_t *job,
+ dkChar const *iconfile,
+ dkChar const *dest,
+ dkChar const *titlea1,
+ dkChar const *titlea2,
+ dkChar const *titlena,
+ int act
+)
+{
+ int back = 1;
+ unsigned long w = 0UL; /* Icon width */
+ unsigned long h = 0UL; /* Icon height */
+ $? "+ hbhtml_one_navi_icon"
+ $? ". iconfile = \"%!ds\"", TR_STR(iconfile)
+ $? ". dest = \"%!ds\"", TR_STR(dest)
+ $? ". titlea1 = \"%!ds\"", TR_STR(titlea1)
+ $? ". titlea2 = \"%!ds\"", TR_STR(titlea2)
+ $? ". titlena = \"%!ds\"", TR_STR(titlena)
+ $? ". act = %d", act
+ if(act) { $? ". act"
+ fputs(hbhtml_c8_kw[49], job->of);
+ if(!(hbhtml_url_output_for_text(job, dest))) {
+ back = 0;
+ } $? ". 1"
+ fputs(hbhtml_c8_kw[50], job->of);
+ if(!(hbhtml_output_for_text(job, titlea1))) {
+ back = 0;
+ } $? ". 2"
+ if(titlea2) {
+ if(!(hbhtml_output_for_text(job, titlea2))) {
+ back = 0;
+ }
+ } $? ". 3"
+ fputs(hbhtml_c8_kw[51], job->of);
+ fputs(hbhtml_c8_kw[53], job->of);
+ if(!(hbhtml_url_output_for_text(job, iconfile))) {
+ back = 0;
+ } $? ". 4"
+ fputs(hbhtml_c8_kw[54], job->of);
+ if(!(hbhtml_output_for_text(job, titlea1))) {
+ back = 0;
+ } $? ". 6"
+ if(titlea2) {
+ if(!(hbhtml_output_for_text(job, titlea2))) {
+ back = 0;
+ }
+ }
+ fputs(hbhtml_c8_kw[55], job->of);
+ if(!(hbhtml_output_for_text(job, titlea1))) {
+ back = 0;
+ } $? ". 6"
+ if(titlea2) {
+ if(!(hbhtml_output_for_text(job, titlea2))) {
+ back = 0;
+ }
+ }
+ fputs(hbhtml_c8_kw[56], job->of);
+ if(hbimgdim_find(job, iconfile, &w, &h, 1)) {
+ if((w) && (h)) {
+ fprintf(job->of, hbhtml_c8_kw[67], w, h);
+ }
+ }
+ fputs(hbhtml_c8_kw[3], job->of);
+ fputs(hbhtml_c8_kw[52], job->of); $? ". 7"
+ } else { $? ". not act"
+ fputs(hbhtml_c8_kw[53], job->of);
+ if(!(hbhtml_url_output_for_text(job, iconfile))) {
+ back = 0;
+ } $? ". 8"
+ fputs(hbhtml_c8_kw[54], job->of);
+ if(!(hbhtml_output_for_text(job, titlea1))) {
+ back = 0;
+ } $? ". 6"
+ if(titlea2) {
+ if(!(hbhtml_output_for_text(job, titlea2))) {
+ back = 0;
+ }
+ }
+ fputs(hbhtml_c8_kw[55], job->of);
+ if(!(hbhtml_output_for_text(job, titlena))) {
+ back = 0;
+ } $? ". 10"
+ fputs(hbhtml_c8_kw[56], job->of);
+ if(hbimgdim_find(job, iconfile, &w, &h, 1)) {
+ if((w) && (h)) {
+ fprintf(job->of, hbhtml_c8_kw[67], w, h);
+ }
+ }
+ fputs(hbhtml_c8_kw[3], job->of);
+ } $? "- hbhtml_one_navi_icon %d", back
+ return back;
+}
+
+
+
+/** Process special command to build navigation div.
+ @param job Job structure.
+ @param pa Programm arguments (ignored).
+ @param p Previous node.
+ @param n Next node.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_process_sp_navigation(
+ hb_job_t *job,
+ dkChar *pa,
+ hb_node_t *p,
+ hb_node_t *n
+)
+{
+ dk3_key_value_t kv[10]; /* Command parameters */
+ dkChar bu[DK3_MAX_PATH]; /* Construct file name */
+ hb_node_t *nptr; /* Current node */
+ dkChar const *itop = NULL; /* TOC icon name */
+ dkChar const *iprev = NULL; /* Previous icon name */
+ dkChar const *inext = NULL; /* Next icon name */
+ dkChar const *ihome = NULL; /* Home icon name */
+ dkChar const *ikind = NULL; /* Index icon name */
+ dkChar const *ta1; /* Icon image title, node */
+ dkChar const *ta2; /* Icon image title */
+ dkChar const *tna; /* Icon image title start */
+ size_t sz; /* Number of command params */
+ size_t szurl; /* URL length */
+ size_t i; /* Traverse command params */
+ int res; /* Result create one icon */
+ int kind = 0; /* Flag: Keyword index */
+ int ptoc = 0; /* Flag: TOC */
+ int back = 1;
+ $? "+ hbhtml_process_sp_navigation"
+ sz = DK3_SIZEOF(kv,dk3_key_value_t);
+ if(dk3str_to_key_value(kv, &sz, pa, job->app)) {
+ for(i = 0; i < sz; i++) {
+ if(kv[i].key) {
+ switch(dk3str_array_abbr(hbhtml_navi_keys, kv[i].key, dkT('$'), 0)) {
+ case 0: {
+ itop = kv[i].val;
+ } break;
+ case 1: {
+ iprev = kv[i].val;
+ } break;
+ case 2: {
+ inext = kv[i].val;
+ } break;
+ case 3: {
+ ikind = kv[i].val;
+ } break;
+ case 4: {
+ ihome = kv[i].val;
+ } break;
+ }
+ }
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 40);
+ }
+ nptr = job->currentnode;
+ kind = (((job->options) & HB_JOB_OPT_CREATE_INDEX) ? 1 : 0);
+ ptoc = (((job->options) & HB_JOB_OPT_CREATE_TOC) ? 1 : 0);
+ while(
+ (nptr)
+ && (
+ !(
+ ((itop) || (!(ptoc)))
+ && (ihome)
+ && (iprev) && (inext)
+ && ((ikind) || (!(kind)))
+ )
+ )
+ )
+ {
+ if(!(itop)) itop = nptr->icontoc;
+ if(!(iprev)) iprev = nptr->iconprev;
+ if(!(inext)) inext = nptr->iconnext;
+ if(!(ikind)) ikind = nptr->iconindex;
+ if(!(ihome)) ihome = nptr->iconhome;
+ nptr = nptr->parent;
+ }
+ $? ". before corrections"
+ if(!(itop)) itop = (job->kwnl)[14];
+ if(!(iprev)) iprev = (job->kwnl)[15];
+ if(!(inext)) inext = (job->kwnl)[16];
+ if(!(ikind)) ikind = (job->kwnl)[17];
+ if(!(ihome)) ihome = (job->kwnl)[37];
+ $? ". after corrections"
+ if(
+ ((itop) || (!(ptoc)))
+ && (iprev) && (inext) && (ihome)
+ && ((ikind) || (!(kind)))
+ )
+ {
+ back = 1;
+ if(itop) { if(!hbtool_add_file(job, itop)) { back = 0; } }
+ if(iprev) { if(!hbtool_add_file(job, iprev)) { back = 0; } }
+ if(inext) { if(!hbtool_add_file(job, inext)) { back = 0; } }
+ if(ikind) { if(!hbtool_add_file(job, ikind)) { back = 0; } }
+ if(ihome) { if(!hbtool_add_file(job, ihome)) { back = 0; } }
+ fputs(hbhtml_c8_kw[46], job->of);
+
+ /* HOME */ $? ". home"
+ ta1 = (job->msg)[1];
+ ta2 = (job->rootnode)->title;
+ tna = (job->msg)[2];
+ res = hbhtml_create_output_filename(
+ bu, DK3_SIZEOF(bu,dkChar), job, job->rootnode
+ );
+ if(res) { $? ". fn ok \"%!ds\"", bu
+ $? ". icon = \"%!ds\"", itop
+ res = hbhtml_one_navi_icon(
+ job, ihome, bu, ta1, ta2, tna,
+ (
+ (0 != job->currentnode->havenavimenu)
+ ? (1)
+ : (((0UL == (job->currentnode)->objno) ? 0 : 1))
+ )
+ );
+ if(!(res)) { back = 0; }
+ $? ". navi icon completed"
+ } else { $? "! fn"
+ back = 0;
+ }
+ /* Previous */ $? ". prev"
+ ta1 = (job->msg)[3];
+ ta2 = NULL;
+ if(p) ta2 = p->title;
+ tna = (job->msg)[4];
+ if(p) {
+ res = hbhtml_create_output_filename(
+ bu, DK3_SIZEOF(bu,dkChar), job, p
+ );
+ if(res) {
+ fputs(hbhtml_c8_kw[48], job->of);
+ res = hbhtml_one_navi_icon(job, iprev, bu, ta1, ta2, tna, 1);
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ } else {
+ fputs(hbhtml_c8_kw[48], job->of);
+ res = hbhtml_one_navi_icon(job, iprev, NULL, ta1, ta2, tna, 0);
+ if(!(res)) { back = 0; }
+ }
+ /* Next */ $? ". next"
+ ta1 = (job->msg)[5];
+ ta2 = NULL;
+ if(n) ta2 = n->title;
+ tna = (job->msg)[6];
+ if(n) {
+ res = hbhtml_create_output_filename(
+ bu, DK3_SIZEOF(bu,dkChar), job, n
+ );
+ if(res) {
+ fputs(hbhtml_c8_kw[48], job->of);
+ res = hbhtml_one_navi_icon(job, inext, bu, ta1, ta2, tna, 1);
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ } else {
+ fputs(hbhtml_c8_kw[48], job->of);
+ res = hbhtml_one_navi_icon(job, inext, NULL, ta1, ta2, tna, 0);
+ if(!(res)) { back = 0; }
+ }
+ /* TOC */ $? ". toc"
+ if(ptoc) {
+ ta1 = (job->msg)[93];
+ ta2 = (job->rootnode)->title;
+ tna = (job->msg)[94];
+ res = hbhtml_create_output_filename(
+ bu, DK3_SIZEOF(bu,dkChar), job, job->rootnode
+ );
+ if(res) { $? ". fn ok \"%!ds\"", bu
+ szurl = dk3str_len(bu);
+ szurl += dk3str_len((job->kwnl)[31]);
+ if(szurl < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cat(bu, (job->kwnl)[31]);
+ } else {
+ back = 0;
+ }
+ $? ". icon = \"%!ds\"", itop
+ fputs(hbhtml_c8_kw[48], job->of);
+ res = hbhtml_one_navi_icon(job, itop, bu, ta1, ta2, tna, 1);
+ if(!(res)) { back = 0; }
+ $? ". navi icon completed"
+ } else { $? "! fn"
+ back = 0;
+ }
+ }
+ /* Key index */
+ if(kind) { $? ". kind"
+ ta1 = (job->msg)[7];
+ ta2 = NULL;
+ tna = NULL;
+ res = hbhtml_create_output_filename(
+ bu, DK3_SIZEOF(bu,dkChar), job, job->rootnode
+ );
+ if(res) {
+ if(dk3str_len(bu)+dk3str_len((job->kwnl)[13]) < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cat(bu, (job->kwnl)[13]);
+ fputs(hbhtml_c8_kw[48], job->of);
+ res = hbhtml_one_navi_icon(job, ikind, bu, ta1, ta2, tna, 1);
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ } else {
+ back = 0;
+ }
+ }
+ fputs(hbhtml_c8_kw[47], job->of);
+ job->currentnode->havenavimenu = 1;
+ $? ". finished"
+ } else { $? "! icons missing"
+ $? ". itop = \"%!ds\"", TR_STR(itop)
+ $? ". iprev = \"%!ds\"", TR_STR(iprev)
+ $? ". inext = \"%!ds\"", TR_STR(inext)
+ $? ". ikind = \"%!ds\"", TR_STR(ikind)
+ $? ". ihome = \"%!ds\"", TR_STR(ihome)
+ }
+ $? "- hbhtml_process_sp_navigation %d", back
+ return back;
+}
+
+
+
+/** Process author special command.
+ @param job Job structure.
+ @param pa Program arguments.
+ @return 1 on success, 0 on error (continue), -1 on error (exit).
+*/
+static
+int
+hbhtml_process_sp_author(hb_job_t *job, dkChar *pa)
+{
+ dkChar const *ptr; /* Author name */
+ int back = 0;
+ $? "+ hbhtml_process_sp_author"
+ ptr = hbconf_author(job->currentnode);
+ if(ptr) {
+ if(hbhtml_output_for_text(job, ptr)) {
+ back = 1;
+ }
+ } $? "- hbhtml_process_sp_author %d", back
+ return back;
+}
+
+
+
+/** Process location special command.
+ @param job Job structure.
+ @param pa Program arguments.
+ @return 1 on success, 0 on error (continue), -1 on error (exit).
+*/
+static
+int
+hbhtml_process_sp_location(hb_job_t *job, dkChar *pa)
+{
+ dkChar const *ptr; /* Location name */
+ int back = 0;
+ $? "+ hbhtml_process_sp_location"
+ ptr = hbconf_location(job->currentnode);
+ if(ptr) {
+ if(hbhtml_output_for_text(job, ptr)) {
+ back = 1;
+ }
+ } $? "- hbhtml_process_sp_location %d", back
+ return back;
+}
+
+
+
+/** Process date special command.
+ @param job Job structure.
+ @param pa Program arguments.
+ @return 1 on success, 0 on error (continue), -1 on error (exit).
+*/
+static
+int
+hbhtml_process_sp_date(hb_job_t *job, dkChar *pa)
+{
+ dk3_key_value_t kv[5]; /* Command parameters */
+ size_t sz; /* Number of command paramters */
+ size_t i; /* Traverse command paramters */
+ int german = 0; /* Flag: German style date */
+ int back = 1;
+ $? "+ hbhtml_process_sp_date \"%!ds\"", TR_STR(pa)
+ sz = DK3_SIZEOF(kv,dk3_key_value_t);
+ if(dk3str_to_key_value(kv,&sz,pa,job->app)) { $? ". to key value"
+ for(i = 0; i < sz; i++) { $? ". i=%u", (unsigned)i
+ if(kv[i].key) { $? ". key=\"%!ds\" val=\"%!ds\"", TR_STR(kv[i].key), TR_STR(kv[i].val)
+ switch(dk3str_array_abbr(hbhtml_date_keys, kv[i].key, dkT('$'), 0)) {
+ case 0: {
+ if(kv[i].val) {
+ if(0 == dk3str_casecmp((job->kwnl)[11], kv[i].val)) {
+ german = 1; $? ". german"
+ } else {
+ german = 0; $? ". not german"
+ }
+ }
+ } break;
+ default: {
+ /* ERROR: Illegal attribute! */
+ dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,27,26,kv[i].key);
+ back = 0; $? "! ERROR"
+ } break;
+ }
+ }
+ }
+ } else { $? "! dk3str_to_key_value"
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 40);
+ }
+ if(german) {
+ fprintf(
+ job->of, "%02d.%02d.%04d",
+ (job->starttime).D, (job->starttime).M, (job->starttime).Y
+ );
+ } else {
+ fprintf(
+ job->of, "%04d-%02d-%02d",
+ (job->starttime).Y, (job->starttime).M, (job->starttime).D
+ );
+ } $? "- hbhtml_process_sp_date %d", back
+ return back;
+}
+
+
+
+/** Process special command to show variable.
+ @param job Job structure.
+ @param pa Pointer to arguments.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_process_sp_variable(hb_job_t *job, dkChar *pa)
+{
+ dk3_key_value_t kv[5]; /* Argument pairs */
+ dkChar const *varname; /* Variable name. */
+ dkChar const *varval; /* Variable value */
+ size_t sz; /* Size of kv */
+ size_t i; /* Traverse kv */
+ int urlm = 0; /* Flag: URL mode */
+ int back = 1;
+ $? "+ hbhtml_process_sp_variable"
+ sz = DK3_SIZEOF(kv,dk3_key_value_t);
+ if(dk3str_to_key_value(kv,&sz,pa,job->app)) {
+ if(sz > 0) {
+ varname = kv[0].key;
+ for(i = 1; i < sz; i++) {
+ if(kv[i].key) {
+ if(dk3str_casecmp((job->kwnl)[12], kv[i].key) == 0) {
+ if(kv[i].val) {
+ urlm = ((dk3str_is_on(kv[i].val)) ? 1 : 0);
+ } else {
+ urlm = 1;
+ }
+ } else {
+ back = 0; $? "! ERROR"
+ /* ERROR: Illegal argument */
+ dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,27,26,kv[i].key);
+ }
+ }
+ }
+ varval = hbnode_variable(job->currentnode, varname);
+ if(varval) {
+ if(urlm) {
+ if(!hbhtml_url_output_for_text(job, varval)) {
+ back = 0; $? "! ERROR"
+ }
+ } else {
+ if(!hbhtml_output_for_text(job, varval)) {
+ back = 0; $? "! ERROR"
+ }
+ }
+ }
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 40);
+ } $? "- hbhtml_process_sp_variable %d", back
+ return back;
+}
+
+
+
+/** Process contents of one file.
+ @param job Job structure.
+ @param p Previous node.
+ @param n Next node.
+ @return 1 on success, 0 on error (can continue), -1 on error (exit).
+*/
+static
+int
+hbhtml_process_sp_contents(hb_job_t *job, hb_node_t *p, hb_node_t *n)
+{
+ int back = 1;
+ job->spused = 0;
+ job->shipused = 0;
+ $? "+ hbhtml_process_sp_contents %lu", (job->currentnode)->objno
+ if(job->currentnode) { $? ". have current node"
+ if((job->currentnode)->filename) { $? ". have input file name"
+ back = hbcont_process(job, p, n);
+ } else { $? "! no input file name"
+ if(0UL == (job->currentnode)->objno) { $? ". root node"
+ back = hbcont_process(job, p, n);
+ } else { $? "! not root node"
+ }
+ }
+ } $? "- hbhtml_process_sp_contents %d", back
+ return back;
+}
+
+
+
+/** Open code tag for line number.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_coli_open(hb_job_t *job)
+{
+ int back = 1;
+ if (EOF == fputs(hbhtml_c8_kw[146], job->of)) { back = 0; }
+ if (1000 > job->coli) {
+ if (0 > fprintf(job->of, "%03d", job->coli)) { back = 0; }
+ job->coli += 1;
+ if (1000 == job->coli) {
+ back = 0;
+ /* WARNING: Too many code lines */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 88);
+ }
+ } else {
+ back = 0;
+ fputs(hbhtml_c8_kw[149], job->of);
+ }
+ if (EOF == fputs(hbhtml_c8_kw[147], job->of)) { back = 0; }
+ return back;
+}
+
+
+
+/** Close code tag for line number.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_coli_close(hb_job_t *job)
+{
+ int back = 1;
+ if (EOF == fputs(hbhtml_c8_kw[148], job->of)) { back = 0; }
+ return back;
+}
+
+
+
+/** Output dummy code line to avoid trimming emptry code tag.
+ @param job Job structure.
+ @return 1 on success, 0 on error
+*/
+static
+int
+hbhtml_coli_dummy(hb_job_t *job)
+{
+ int back = 1;
+ if (!hbhtml_coli_open(job)) { back = 0; }
+ if (EOF == fputs(hbhtml_c8_kw[150], job->of)) { back = 0; }
+ if (!hbhtml_coli_close(job)) { back = 0; }
+ return back;
+}
+
+
+
+/** Start of a code line found.
+ Invoked from the input line handler.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_code_line_start(hb_job_t *job)
+{
+ int back = 1;
+ if (((job->options) & HB_JOB_OPT_CODE) && (0 < job->coli)) {
+ switch (job->cols) {
+ case HB_COLIST_NONE: {
+ if (!hbhtml_coli_open(job)) { back = 0; }
+ job->cols = HB_COLIST_OPENED;
+ } break;
+ case HB_COLIST_NOT_OPENED: {
+ if (!hbhtml_coli_open(job)) { back = 0; }
+ job->cols = HB_COLIST_OPENED;
+ } break;
+#if 0
+ case HB_COLIST_OPENED: {
+ } break;
+#endif
+ }
+ }
+ return back;
+}
+
+
+
+/** Finalize a code line.
+ Invoked from the input line handler.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_code_line_end(hb_job_t *job)
+{
+ int back = 1;
+ if (((job->options) & HB_JOB_OPT_CODE) && (0 < job->coli)) {
+ switch (job->cols) {
+ case HB_COLIST_NONE: {
+ job->cols = HB_COLIST_NOT_OPENED;
+ } break;
+ case HB_COLIST_NOT_OPENED: {
+ if (!hbhtml_coli_dummy(job)) { back = 0; }
+ } break;
+ case HB_COLIST_OPENED: {
+ if (!hbhtml_coli_close(job)) { back = 0; }
+ job->cols = HB_COLIST_NOT_OPENED;
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+/** Start code line numbering.
+ Invoked from the input line handler.
+ Invoked from the code special command.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_start_code_line_numbers(hb_job_t *job)
+{
+ int back = 1;
+ job->coli = 1;
+ job->cols = HB_COLIST_NONE;
+ return back;
+}
+
+
+
+/** End code line numbering if it was started.
+ Invoked from the code special command.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_end_code_line_numbers(hb_job_t *job)
+{
+ int back = 1;
+ if (((job->options) & HB_JOB_OPT_CODE) && (0 < job->coli)) {
+ switch (job->cols) {
+ case HB_COLIST_OPENED: {
+ if (EOF == fputs(hbhtml_c8_kw[148], job->of)) { back = 0; }
+ } break;
+ }
+ }
+ job->coli = 0;
+ job->cols = HB_COLIST_NONE;
+ return back;
+}
+
+
+
+/** Process the code special command.
+ @param job Job structure.
+ @param pa Arguments
+*/
+static
+void
+hbhtml_process_sp_code(hb_job_t *job, dkChar *pa)
+{
+ dk3_key_value_t kv[10]; /* Command paramters */
+ size_t sz; /* Number of command parameters */
+ size_t i; /* Process all command parameters */
+ int act = 0; /* Action to take */
+ int lineno = 0; /* Flag: Write line numbers */
+
+ $? "+ hbhtml_process_sp_code"
+
+ /* Get configuration defaults
+ */
+ if ((job->options) & HB_JOB_OPT_CODE_LINE_NUMBERS) {
+ lineno = 1;
+ }
+
+ /* Use command options
+ */
+ sz = DK3_SIZEOF(kv,dk3_key_value_t);
+ if(dk3str_to_key_value(kv,&sz,pa,job->app)) {
+ if(sz > 0) {
+ for(i = 0; i < sz; i++) {
+ if(kv[i].key) {
+ switch(dk3str_array_abbr(hbhtml_code_keys, kv[i].key, dkT('$'), 0)) {
+ case 0: case 1: {
+ if(kv[i].val) {
+ if(dk3str_is_bool(kv[i].val)) {
+ if(dk3str_is_on(kv[i].val)) {
+ act = 1;
+ } else {
+ act = 2;
+ }
+ } else {
+ act = 1;
+ }
+ } else {
+ act = 1;
+ }
+ } break;
+ case 2: case 3: {
+ if(kv[i].val) {
+ if(dk3str_is_bool(kv[i].val)) {
+ if(dk3str_is_on(kv[i].val)) {
+ act = 2;
+ } else {
+ act = 1;
+ }
+ } else {
+ act = 2;
+ }
+ } else {
+ act = 2;
+ }
+ } break;
+ case 4: {
+ act = 0;
+ } break;
+ case 5: {
+ if (kv[i].val) {
+ if (dk3str_is_bool(kv[i].val)) {
+ lineno = ((dk3str_is_on(kv[i].val)) ? 1 : 0);
+ } else {
+ /* Warning: Not a boolean */
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, kv[i].val);
+ }
+ } else {
+ lineno = 1;
+ }
+ } break;
+ }
+ }
+ }
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 40);
+ }
+
+ /* Finish open code line numbering.
+ */
+ (void)hbhtml_end_code_line_numbers(job);
+
+ /* Turn code mode on or off.
+ */
+ switch(act) {
+ case 0: {
+ if((job->options) & HB_JOB_OPT_CODE) {
+ job->options &= (~(HB_JOB_OPT_CODE));
+ } else {
+ job->options |= HB_JOB_OPT_CODE;
+ if (lineno) {
+ (void)hbhtml_start_code_line_numbers(job);
+ }
+ }
+ } break;
+ case 1: {
+ job->options |= HB_JOB_OPT_CODE;
+ if (lineno) {
+ (void)hbhtml_start_code_line_numbers(job);
+ }
+ } break;
+ case 2: {
+ job->options &= (~(HB_JOB_OPT_CODE));
+ } break;
+ } $? "- hbhtml_process_sp_code"
+}
+
+
+
+#if 0
+static
+int
+hbhtml_check_link_for_external(dkChar *link, hb_job_t *job)
+{
+ size_t sz;
+ int back = 0;
+ if(link) {
+ sz = dk3str_len(link);
+ if(sz >= dk3str_len((job->kwnl)[20])) {
+ if(0 == dk3str_ncmp(link, (job->kwnl)[20], dk3str_len((job->kwnl)[20]))) {
+ back = 1;
+ }
+ }
+ if(sz >= dk3str_len((job->kwnl)[21])) {
+ if(0 == dk3str_ncmp(link, (job->kwnl)[21], dk3str_len((job->kwnl)[21]))) {
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+#endif
+
+
+
+int
+hbhtml_check_link_for_external(dkChar const *link)
+{
+ dkChar const *ptr; /* Traverse string */
+ dkChar c; /* Current character */
+ int stm3; /* State machine for traversal */
+ int i; /* Input classification */
+ int back = 0;
+ $? "+ hbhtml_check_link_for_external \"%!ds\"", TR_STR(link)
+ hbhtml_stm3_reset(&stm3);
+ ptr = link;
+ while(*ptr) {
+ c = *(ptr++);
+ i = STM3_I_ANY;
+ switch(c) {
+ case dkT(':'): {
+ i = STM3_I_COLON;
+ } break;
+ case dkT('/'): {
+ i = STM3_I_SLASH;
+ } break;
+ case dkT('_'): {
+ i = STM3_I_ASCII;
+ } break;
+ default: {
+ if((dkT('a') <= c) && (dkT('z') >= c)) {
+ i = STM3_I_ASCII;
+ } else {
+ if((dkT('A') <= c) && (dkT('Z') >= c)) {
+ i = STM3_I_ASCII;
+ } else {
+ if((dkT('0') <= c) && (dkT('9') >= c)) {
+ i = STM3_I_ASCII;
+ }
+ }
+ }
+ } break;
+ }
+ hbhtml_stm3_step(&stm3, i);
+ }
+ if(STM3_ST_SUCCESS == stm3) {
+ back = 1;
+ } $? "- hbhtml_check_link_for_external %d", back
+ return back;
+}
+
+
+
+/** Process special command to build a link.
+ @param job Job structure.
+ @param pa Program arguments.
+ @return 1 on success, 0 on error (continue), -1 on error (exit).
+*/
+static
+int
+hbhtml_process_sp_a(hb_job_t *job, dkChar *pa)
+{
+ dk3_key_value_t kv[25]; /* Command parameters */
+ hb_link_t *linkptr; /* Link data for URL */
+ hb_node_t *nptr; /* Current node */
+ dkChar *text = NULL; /* Link text */
+ dkChar *title = NULL; /* Link title */
+ dkChar *accessk = NULL; /* Accesskey argument */
+ dkChar *charset = NULL; /* Charset argument */
+ dkChar *coords = NULL; /* Coords argument */
+ dkChar *href = NULL; /* href argument */
+ dkChar *hrefl = NULL; /* hreflang argument */
+ dkChar *name = NULL; /* name argument */
+ dkChar *onblur = NULL; /* onblur argument */
+ dkChar *onfocus = NULL; /* onfocus argument */
+ dkChar *rel = NULL; /* rel argument */
+ dkChar *rev = NULL; /* rev argument */
+ dkChar *shape = NULL; /* shape argument */
+ dkChar *tabind = NULL; /* tabindex argument */
+ dkChar *target = NULL; /* target argument */
+ dkChar *type = NULL; /* type argument */
+ dkChar *clptr = NULL; /* class argument */
+ dkChar *idptr = NULL; /* id argument */
+ dkChar *style = NULL; /* style argument */
+ size_t sz; /* Number of parameters */
+ size_t i; /* Traverse parameters */
+ int external = 0; /* Flag: External link */
+ int extspec = 0; /* Flag: External specified */
+ int titlespec = 0; /* Flag: Title specified */
+ int back = 0;
+ $? "+ hbhtml_process_sp_a"
+ nptr = job->currentnode;
+ sz = DK3_SIZEOF(kv,dk3_key_value_t);
+ if(dk3str_to_key_value(kv,&sz,pa,job->app)) {
+ if(sz > 0) {
+ for(i = 0; i < sz; i++) {
+ if(kv[i].key) {
+ switch(dk3str_array_abbr(hbhtml_a_keys, kv[i].key, dkT('$'), 0)) {
+ case 0: { $? ". text"
+ text = kv[i].val;
+ } break;
+ case 1: { $? ". title"
+ title = kv[i].val; titlespec = 1;
+ } break;
+ case 2: { $? ". accesskey"
+ accessk = kv[i].val;
+ } break;
+ case 3: { $? ". charset"
+ charset = kv[i].val;
+ } break;
+ case 4: { $? ". coords"
+ coords = kv[i].val;
+ } break;
+ case 5: { $? ". href"
+ href= kv[i].val;
+ } break;
+ case 6: { $? ". hreflang"
+ hrefl = kv[i].val;
+ } break;
+ case 7: { $? ". name"
+ name = kv[i].val;
+ } break;
+ case 8: { $? ". onblur"
+ onblur = kv[i].val;
+ } break;
+ case 9: { $? ". onfocus"
+ onfocus = kv[i].val;
+ } break;
+ case 10: { $? ". rel"
+ rel = kv[i].val;
+ } break;
+ case 11: { $? ". rev"
+ rev = kv[i].val;
+ } break;
+ case 12: { $? ". shape"
+ shape = kv[i].val;
+ } break;
+ case 13: { $? ". tabindex"
+ tabind = kv[i].val;
+ } break;
+ case 14: { $? ". target"
+ target = kv[i].val;
+ } break;
+ case 15: { $? ". type"
+ type = kv[i].val;
+ } break;
+ case 16: { $? ". class"
+ clptr = kv[i].val;
+ } break;
+ case 17: { $? ". id"
+ idptr = kv[i].val;
+ } break;
+ case 18: { $? ". style"
+ style = kv[i].val;
+ } break;
+ case 19: {
+ if(kv[i].val) {
+ if(dk3str_is_bool(kv[i].val)) {
+ if(dk3str_is_on(kv[i].val)) {
+ external = 1; extspec = 1;
+ } else {
+ external = 0; extspec = 1;
+ }
+ }
+ } else {
+ external = 1; extspec = 1;
+ }
+ } break;
+ default: {
+ dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,27,26,kv[i].key);
+ } break;
+ }
+ }
+ }
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 40);
+ }
+ if(href) {
+ if(!(extspec)) {
+ external = hbhtml_check_link_for_external(href);
+ }
+ if(titlespec) {
+ if(!(title)) { title = text; }
+ if(!(title)) { title = href; }
+ }
+ back = 1;
+ } else {
+ if(name) {
+ back = 1;
+ }
+ }
+ if(back) {
+ /* Write <a...> */
+ if(href) {
+ fputs(hbhtml_c8_kw[39], job->of);
+ if(!hbhtml_url_output_for_text(job, href)) { back = 0; }
+ } else {
+ fputs(hbhtml_c8_kw[74], job->of);
+ if(!hbhtml_url_output_for_text(job, name)) { back = 0; }
+ }
+ if(target) {
+ fputs(hbhtml_c8_kw[75], job->of);
+ if(!hbhtml_url_output_for_text(job, target)) { back = 0; }
+ } else {
+ if(external) {
+ fputs(hbhtml_c8_kw[108], job->of);
+ }
+ }
+ if(type) {
+ fputs(hbhtml_c8_kw[76], job->of);
+ if(!hbhtml_url_output_for_text(job, type)) { back = 0; }
+ }
+ fputs(hbhtml_c8_kw[77], job->of);
+ if(clptr) {
+ if(!hbhtml_url_output_for_text(job, clptr)) { back = 0; }
+ } else {
+ if(external) {
+ fputs(hbhtml_c8_kw[101], job->of);
+ } else {
+ fputs(hbhtml_c8_kw[100], job->of);
+ }
+ }
+ if(idptr) {
+ fputs(hbhtml_c8_kw[78], job->of);
+ if(!hbhtml_url_output_for_text(job, idptr)) { back = 0; }
+ }
+ if(style) {
+ fputs(hbhtml_c8_kw[79], job->of);
+ if(!hbhtml_url_output_for_text(job, style)) { back = 0; }
+ }
+ if(hrefl) {
+ fputs(hbhtml_c8_kw[80], job->of);
+ if(!hbhtml_url_output_for_text(job, hrefl)) { back = 0; }
+ }
+ if(title) {
+ fputs(hbhtml_c8_kw[81], job->of);
+ if(!hbhtml_output_for_text(job, title)) { back = 0; }
+ }
+ if(onblur) {
+ fputs(hbhtml_c8_kw[82], job->of);
+ if(!hbhtml_url_output_for_text(job, onblur)) { back = 0; }
+ }
+ if(onfocus) {
+ fputs(hbhtml_c8_kw[83], job->of);
+ if(!hbhtml_url_output_for_text(job, onfocus)) { back = 0; }
+ }
+ if(rel) {
+ fputs(hbhtml_c8_kw[84], job->of);
+ if(!hbhtml_url_output_for_text(job, rel)) { back = 0; }
+ }
+ if(rev) {
+ fputs(hbhtml_c8_kw[85], job->of);
+ if(!hbhtml_url_output_for_text(job, rev)) { back = 0; }
+ }
+ if(shape) {
+ fputs(hbhtml_c8_kw[86], job->of);
+ if(!hbhtml_url_output_for_text(job, shape)) { back = 0; }
+ }
+ if(tabind) {
+ fputs(hbhtml_c8_kw[87], job->of);
+ if(!hbhtml_url_output_for_text(job, tabind)) { back = 0; }
+ }
+ if(accessk) {
+ fputs(hbhtml_c8_kw[88], job->of);
+ if(!hbhtml_url_output_for_text(job, accessk)) { back = 0; }
+ }
+ if(charset) {
+ fputs(hbhtml_c8_kw[89], job->of);
+ if(!hbhtml_url_output_for_text(job, charset)) { back = 0; }
+ }
+ if(coords) {
+ fputs(hbhtml_c8_kw[90], job->of);
+ if(!hbhtml_url_output_for_text(job, coords)) { back = 0; }
+ }
+ fputs(hbhtml_c8_kw[5], job->of);
+ fputs(hbhtml_c8_kw[3], job->of);
+ if(href) {
+ if(text) {
+ if(!hbhtml_output_for_text(job, text)) { back = 0; }
+ } else {
+ if(!hbhtml_output_for_text(job, href)) { back = 0; }
+ }
+ }
+ fputs(hbhtml_c8_kw[41], job->of);
+ if((href) && (external) && (text)) {
+ /* Save link and write link number */
+ linkptr = dk3sto_it_find_like(nptr->i_lbyurl, href, 1);
+ if(linkptr) {
+ fprintf(job->of, hbhtml_c8_kw[91], (1UL + linkptr->lno));
+ } else {
+ linkptr = hbnode_link_new(href, nptr->nextlink, job->app);
+ if(linkptr) {
+ if(dk3sto_add(nptr->s_lbyurl, linkptr)) {
+ nptr->nextlink += 1UL;
+ if(dk3sto_add(nptr->s_lbylno, linkptr)) {
+ fprintf(job->of, hbhtml_c8_kw[91], (1UL + linkptr->lno));
+ } else {
+ back = 0;
+ }
+ } else {
+ back = 0;
+ hbnode_link_delete(linkptr);
+ linkptr = NULL;
+ }
+ } else {
+ back = 0;
+ }
+ }
+ }
+ if((!(href)) && (name)) {
+ if(text) {
+ if(!hbhtml_output_for_text(job, text)) { back = 0; }
+ }
+ }
+ if(href) {
+ if(!hbtool_add_url(job, href)) { back = 0; }
+ }
+ } $? "- hbhtml_process_sp_a %d", back
+ return back;
+}
+
+
+
+/** Process menuentry special command.
+ @param job Job structure.
+ @param pa Arguments.
+ @return 1 on success, 0 on error (continue), -1 on error (exit).
+*/
+static
+int
+hbhtml_process_sp_menuentry(hb_job_t *job, dkChar *pa)
+{
+ dk3_key_value_t kv[20]; /* Command parameters */
+ dkChar *items[DK3_SIZEOF(kv,dk3_key_value_t)];
+ size_t sz; /* Number of command parameters */
+ size_t i; /* Traverse command parameters */
+ size_t n_items = 0; /* number of items */
+ size_t cr; /* Current item index */
+ int back = 0;
+ $? "+ hbhtml_process_sp_menuentry"
+ sz = DK3_SIZEOF(kv,dk3_key_value_t);
+ if(dk3str_to_key_value(kv,&sz,pa,job->app)) {
+ if(sz > 0) {
+ for(i = 0; i < sz; i++) {
+ if(kv[i].key) {
+ switch(dk3str_array_abbr(hbhtml_menuentry_keys,kv[i].key,dkT('$'),0))
+ {
+ case 0: {
+ if(kv[i].val) {
+ if(n_items < DK3_SIZEOF(kv,dk3_key_value_t)) {
+ items[n_items++] = kv[i].val;
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 41);
+ }
+ }
+ } break;
+ default: {
+ dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,27,26,kv[i].key);
+ back = 0;
+ } break;
+ }
+ }
+ }
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 40);
+ }
+ if(n_items) {
+ back = 1;
+ fputs(hbhtml_c8_kw[92], job->of);
+ if(!hbhtml_output_for_text(job, (job->msg)[60])) { back = 0; }
+ fputs(hbhtml_c8_kw[22], job->of);
+ for(cr = 0; cr < n_items; cr++) {
+ fputs(hbhtml_c8_kw[94], job->of);
+ if(cr) {
+ for(i = 0; i < (cr - 1); i++) {
+ fputs(hbhtml_c8_kw[98], job->of);
+ }
+ fputs(hbhtml_c8_kw[99], job->of);
+ fprintf(job->of, hbhtml_c8_kw[96], (unsigned)(n_items - cr));
+ if(!hbhtml_output_for_text(job, items[cr])) { back = 0; }
+ fputs(hbhtml_c8_kw[97], job->of);
+ } else {
+ fprintf(job->of, hbhtml_c8_kw[96], (unsigned)n_items);
+ if(!hbhtml_output_for_text(job, items[cr])) { back = 0; }
+ fputs(hbhtml_c8_kw[97], job->of);
+ }
+ fputs(hbhtml_c8_kw[95], job->of);
+ }
+ fputs(hbhtml_c8_kw[93], job->of);
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 42);
+ } $? "- hbhtml_process_sp_menuentry %d", back
+ return back;
+}
+
+
+
+/** Process index special command.
+ @param job Job structure.
+ @param pa Program arguments.
+ @return 1 on success, 0 on error (continue), -1 on error (exit).
+*/
+static
+int
+hbhtml_process_sp_index(hb_job_t *job, dkChar *pa)
+{
+ dk3_key_value_t kv[10]; /* Command parameters */
+ hb_node_t *nptr; /* Current node */
+ hb_index_entry_t *indptr; /* New index entry item */
+ dkChar *text = NULL; /* Text for index entry */
+ dkChar *name = NULL; /* Name for index entry */
+ size_t sz; /* Number of command paramters */
+ size_t i; /* Traverse command parameters */
+ int refer = 0; /* Flag: Refer to existing entry */
+ int back = 0;
+ $? "+ hbhtml_process_sp_index"
+ nptr = job->currentnode;
+ sz = DK3_SIZEOF(kv,dk3_key_value_t);
+ if(dk3str_to_key_value(kv,&sz,pa,job->app)) {
+ if(sz > 0) {
+ for(i = 0; i < sz; i++) {
+ if(kv[i].key) {
+ switch(dk3str_array_abbr(hbhtml_index_keys, kv[i].key, dkT('$'), 0)) {
+ case 0: {
+ text = kv[i].val;
+ } break;
+ case 1: {
+ name = kv[i].val;
+ } break;
+ case 2: {
+ if(kv[i].val) {
+ if(dk3str_is_bool(kv[i].val)) {
+ if(dk3str_is_on(kv[i].val)) {
+ refer = 1;
+ } else {
+ refer = 0;
+ }
+ } else {
+ /* ERROR: Not a boolean */
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, kv[i].val);
+ }
+ } else {
+ refer = 1;
+ }
+ } break;
+ }
+ }
+ }
+ if(text) {
+ if((job->options) & HB_JOB_OPT_CREATE_INDEX) {
+ indptr = hbindex_new(
+ text, nptr->outFileName, name, nptr->nextindex, job->app, nptr
+ );
+ if(indptr) {
+ if(dk3sto_add(job->s_index, indptr)) {
+ back = 1;
+ nptr->nextindex += 1UL;
+ if(!((name) && (refer))) {
+ fputs(hbhtml_c8_kw[74], job->of);
+ if(!hb_index_write_anchor(job, indptr)) { back = 0; }
+ fputs(hbhtml_c8_kw[51], job->of);
+ fputs(hbhtml_c8_kw[52], job->of);
+ }
+ } else {
+ hbindex_delete(indptr);
+ }
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ /* ERROR: Missing text attribute! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 48);
+ }
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 40);
+ } $? "- hbhtml_process_sp_index %d", back
+ return back;
+}
+
+
+
+/** Handle one source code line.
+ @param obj Job structure.
+ @param il Input line.
+ @return 1 on success, 0 on error (continue), -1 on error (exit).
+*/
+static
+int
+hbhtml_sourcefile_line_handler(void *obj, dkChar *il)
+{
+ hb_job_t *job;
+ int back = 1;
+
+ job = (hb_job_t *)obj;
+ dk3str_delnl(il);
+ $? "+ hbhtml_sourcefile_line_handler \"%!ds\"", il
+ if (job->coli) {
+ if (0 < dk3str_len(il)) {
+ if (!hbhtml_coli_open(job)) { back = 0; }
+ if(!hbhtml_output_for_text(job, il)) { back = 0; }
+ if (!hbhtml_coli_close(job)) { back = 0; }
+ } else {
+ if (!hbhtml_coli_dummy(job)) { back = 0; }
+ }
+ } else {
+ if(!hbhtml_output_for_text(job, il)) { back = 0; }
+ }
+ fputc('\n', job->of);
+ $? "- hbhtml_sourcefile_line_handler %d", back
+ return back;
+}
+
+
+
+/** Process sourcefile special command.
+ @param job Job structure.
+ @param pa Program arguemnts.
+ @return 1 on success, 0 on error (continue), -1 on error (exit).
+*/
+static
+int
+html_process_sp_sourcefile(hb_job_t *job, dkChar *pa)
+{
+ dkChar bu[4096]; /* Buffer for source file lines */
+ dk3_key_value_t kv[10]; /* Command parameters */
+ dkChar *file = NULL; /* Input file */
+ dkChar *type = NULL; /* Type argument */
+ dkChar *title = NULL; /* Title argument */
+ size_t sz; /* Number of command parameters */
+ size_t i; /* Traverse command parameters */
+ int lineno = 0; /* Flag: Write line numbers */
+ int back = 0;
+ int res; /* Result from processing file */
+ int oldcode; /* Old code flag value */
+ $? "+ html_process_sp_sourcefile"
+ if ((job->options) & HB_JOB_OPT_CODE_LINE_NUMBERS) {
+ lineno = 1;
+ }
+ sz = DK3_SIZEOF(kv,dk3_key_value_t);
+ if(dk3str_to_key_value(kv, &sz, pa, job->app)) {
+ if(sz > 0) {
+ for(i = 0; i < sz; i++) {
+ if(kv[i].key) {
+ switch(dk3str_array_abbr(hbhtml_sourcef_keys,kv[i].key,dkT('$'),0)) {
+ case 0: {
+ file = kv[i].val;
+ } break;
+ case 1: {
+ type = kv[i].val;
+ } break;
+ case 2: {
+ title = kv[i].val;
+ } break;
+ case 3: {
+ if (kv[i].val) {
+ if (dk3str_is_bool(kv[i].val)) {
+ lineno = ((dk3str_is_on(kv[i].val)) ? 1 : 0);
+ } else {
+ /* WARNING: Not a boolean */
+ dk3app_log_i3(job->app, DK3_LL_WARNING, 146, 144, kv[i].val);
+ }
+ } else {
+ lineno = 1;
+ }
+ } break;
+ }
+ }
+ }
+ }
+ if(file) {
+ back = 1;
+ if(hbtool_add_file(job, file)) {
+ fputs(hbhtml_c8_kw[102], job->of);
+ fputs(hbhtml_c8_kw[103], job->of);
+ if(!hbhtml_url_output_for_text(job, file)) { back = 0; }
+ fputs(hbhtml_c8_kw[81], job->of);
+ if(title) {
+ if(!hbhtml_output_for_text(job, title)) { back = 0; }
+ } else {
+ if(!hbhtml_output_for_text(job, file)) { back = 0; }
+ }
+ fputs(hbhtml_c8_kw[76], job->of);
+ if(type) {
+ if(!hbhtml_output_for_text(job, type)) { back = 0; }
+ } else {
+ fputs(hbhtml_c8_kw[104], job->of);
+ }
+ fputs(hbhtml_c8_kw[51], job->of);
+ if(!hbhtml_output_for_text(job, file)) { back = 0; }
+ fputs(hbhtml_c8_kw[52], job->of);
+ fputs(hbhtml_c8_kw[105], job->of);
+ fputs(hbhtml_c8_kw[106], job->of);
+ oldcode = (((job->options) & HB_JOB_OPT_CODE) ? 1 : 0);
+ job->options |= HB_JOB_OPT_CODE;
+ job->coli = ((lineno) ? 1 : 0);
+ res = dk3stream_process_filename_lines_app(
+ (void *)job, hbhtml_sourcefile_line_handler, file,
+ bu, DK3_SIZEOF(bu,dkChar),
+ dk3app_get_encoding(job->app),
+ dk3app_get_input_file_encoding(job->app),
+ job->app
+ );
+ job->coli = 0;
+ if(!(res)) { back = 0; }
+ if(oldcode) {
+ job->options |= HB_JOB_OPT_CODE;
+ } else {
+ job->options &= (~(HB_JOB_OPT_CODE));
+ }
+ fputs(hbhtml_c8_kw[107], job->of);
+ fputs(hbhtml_c8_kw[47], job->of);
+ } else {
+ back = 0;
+ }
+ } else {
+ /* ERROR: No file name specified! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 49);
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 40);
+ } $? "- html_process_sp_sourcefile %d", back
+ return back;
+}
+
+
+
+/** Process sourcefile special command.
+ @param job Job structure.
+ @param pa Program arguemnts.
+ @return 1 on success, 0 on error (continue), -1 on error (exit).
+*/
+static
+int
+html_process_sp_htmlname(hb_job_t *job, dkChar *pa)
+{
+ dkChar buf[DK3_MAX_PATH];
+ size_t szbuf = DK3_SIZEOF(buf,dkChar);
+ int back = 0;
+ $? "+ html_process_sp_htmlname"
+ if (NULL != job->currentnode) {
+ if (0 != hbhtml_create_output_filename(buf, szbuf, job, job->currentnode)) {
+ back = hbhtml_url_output_for_text(job, buf);
+ if (0 == back) { $? "! failed to write text"
+ job->exv = 1;
+ }
+ } else { $? "! filename conversion"
+ job->exv = 1;
+ }
+ } else { $? "! no current node"
+ }
+ $? "- html_process_sp_htmlname %d", back
+ return back;
+}
+
+
+
+/** Process sourcefile special command.
+ @param job Job structure.
+ @param pa Program arguemnts.
+ @return 1 on success, 0 on error (continue), -1 on error (exit).
+*/
+static
+int
+html_process_sp_hint(hb_job_t *job, dkChar *pa)
+{
+ dk3_key_value_t kv[30];
+ dkChar *hint_text = NULL;
+ dkChar *hint_title = NULL;
+ size_t sz;
+ size_t i;
+ int back = 0;
+
+ sz = DK3_SIZEOF(kv,dk3_key_value_t);
+ if (0 != dk3str_to_key_value(kv, &sz, pa, job->app)) {
+ for (i = 0; i < sz; i++) {
+ if (NULL != kv[i].key) {
+ switch (dk3str_array_abbr(hbhtml_hint_keys, kv[i].key, dkT('$'), 0)) {
+ case 0: {
+ hint_text = kv[i].val;
+ } break;
+ case 1: {
+ hint_title = kv[i].val;
+ } break;
+ default: {
+ /* Warning: Unusable key */
+ dk3app_log_3(job->app, DK3_LL_WARNING, job->msg, 89, 90, kv[i].key);
+ } break;
+ }
+ }
+ }
+ if (NULL != hint_text) {
+ back = 1;
+ if (NULL != hint_title) {
+ if (EOF == fputs(hbhtml_c8_kw[151], job->of)) {
+ back = 0;
+ }
+ if (0 ==hbhtml_output_for_text(job, hint_title)) {
+ back = 0;
+ }
+ if (EOF == fputs(hbhtml_c8_kw[152], job->of)) {
+ back = 0;
+ }
+ if (0 == hbhtml_output_for_text(job, hint_text)) {
+ back = 0;
+ }
+ if (EOF == fputs(hbhtml_c8_kw[153], job->of)) {
+ back = 0;
+ }
+ }
+ else {
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 92);
+ if (0 == hbhtml_output_for_text(job, hint_text)) {
+ back = 0;
+ }
+ }
+ }
+ else {
+ /* ERROR: No text */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 91);
+ }
+ }
+ else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 40);
+ }
+ if (0 == back) {
+ job->exv = 1;
+ }
+ return back;
+}
+
+
+
+/** Process a special command.
+ @param job Job structure.
+ @param in_template Flag: Processing a template.
+ @param p Previous node.
+ @param n Next node.
+ @return 1 on success, 0 on error (continue), -1 on error (exit).
+*/
+static
+int
+hbhtml_process_special(
+ hb_job_t *job,
+ int in_template,
+ hb_node_t *p,
+ hb_node_t *n
+)
+{
+ dkChar *pc; /* Special command name */
+ dkChar *pa; /* Start of command arguments */
+ dkChar *sc; /* Start of sub command. */
+ int ct; /* Command identifier */
+ int back = 0;
+ $? "+ hbhtml_process_special"
+ pc = dk3str_start(job->special, NULL);
+ sc = NULL;
+ if(pc) {
+ pa = dk3str_next(pc, NULL);
+ if(pa) {
+ dk3str_chomp(pa, NULL);
+ }
+ sc = dk3str_chr(pc, dkT('.'));
+ if(sc) { *(sc++) = dkT('\0'); }
+ ct = dk3str_array_index(hbhtml_special_commands, pc, 0);
+ $? ". ct = %d", ct
+ switch(ct) {
+ case 0: { $? ". contents"
+ if(in_template) {
+ back = hbhtml_process_sp_contents(job, p, n);
+ } else {
+ /* ERROR: Contents special not allowed in contents! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 28);
+ }
+ } break;
+ case 1: { $? ". title"
+ back = hbhtml_process_sp_title(job);
+ if(1 != back) { dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 39); }
+ } break;
+ case 2: { $? ". image"
+ back = hbhtml_process_sp_image(job, pa, sc, in_template);
+ if(1 != back) { dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 39); }
+ } break;
+ case 3: { $? ". menu"
+ back = hbhtml_process_sp_menu(job, pa);
+ if(1 != back) { dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 39); }
+ } break;
+ case 4: { $? ". navigation"
+ back = hbhtml_process_sp_navigation(job, pa, p, n);
+ if(1 != back) { dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 39); }
+ } break;
+ case 5: { /* links */
+ /* #### Probably not */
+ back = 1;
+ } break;
+ case 6: { $? ". author"
+ back = hbhtml_process_sp_author(job, pa);
+ if(1 != back) { dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 39); }
+ } break;
+ case 7: { $? ". location"
+ back = hbhtml_process_sp_location(job, pa);
+ if(1 != back) { dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 39); }
+ } break;
+ case 8: { $? ". date"
+ back = hbhtml_process_sp_date(job, pa);
+ if(1 != back) { dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 39); }
+ } break;
+ case 9: { $? ". variable"
+ back = hbhtml_process_sp_variable(job, pa);
+ if(1 != back) { dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 39); }
+ } break;
+ case 10: {
+ hbhtml_process_sp_code(job, pa);
+ back = 1;
+ } break;
+ case 11: {
+ back = hbhtml_process_sp_a(job, pa);
+ if(1 != back) { dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 39); }
+ } break;
+ case 12: {
+ back = hbhtml_process_sp_menuentry(job, pa);
+ if(1 != back) { dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 39); }
+ } break;
+ case 13: {
+ if(0 == in_template) {
+ back = hbhtml_process_sp_index(job, pa);
+ if(1 != back) { dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 39); }
+ } else {
+ /* ERROR: Can not be used in template */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 50);
+ }
+ } break;
+ case 14: {
+ back = html_process_sp_sourcefile(job, pa);
+ if(1 != back) { dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 39); }
+ } break;
+ case 15: {
+ back = html_process_sp_htmlname(job, pa);
+ } break;
+ case 16: {
+ back = html_process_sp_hint(job, pa);
+ } break;
+ default: { $? "! unknown command"
+ back = 0;
+ /* ERROR: Unknown special command. */
+ dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,29,26,pc);
+ } break;
+ }
+ } else {
+ back = 1; /* Empty special */
+ }
+ $? "- hbhtml_process_special %d", back
+ return back;
+}
+
+
+
+int
+hbhtml_line_handler(void *obj, dkChar *il)
+{
+ dkChar xmsg[8]; /* Array for diagnostics */
+ hb_file_processor_t *proc; /* Line processor */
+ hb_job_t *job; /* Job */
+ dkChar *p1; /* Start of input line */
+ size_t pos; /* Non-whitespace position */
+ int i; /* Input classification */
+ int o; /* Reaction from state machine */
+ int ltl = 0; /* Flag: Error from shipout */
+ int back = 1;
+ dkChar c; /* Character to ship out */
+ $? "+ hbhtml_line_handler \"%!ds\"", il
+ pos = 0;
+ proc = (hb_file_processor_t *)obj;
+ job = proc->job;
+ dk3str_delnl(il);
+ hbhtml_stm1_reset(&(proc->stm));
+ job->shipused = 0;
+ job->spused = 0;
+ p1 = il;
+ while(*p1) {
+ c = *p1;
+ i = hbhtml_classify_for_stm1(c);
+ o = hbhtml_stm1_step(&(proc->stm), i);
+ switch(o) {
+ case STM1_O_ERROR: {
+ /* ERROR: Parse error */
+ dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,30,26,p1);
+ back = -1; $? "! FATAL ERROR"
+ } break;
+ case STM1_O_NOTHING: {
+ } break;
+ case STM1_O_SHIPOUT: {
+ if (!hbhtml_code_line_start(job)) { back = 0; }
+ if(!(hbhtml_shipout(job, c))) {
+ back = 0; $? "! ERROR"
+ if(0 == ltl) {
+ ltl = 1;
+ /* ERROR: Line too long! */
+ }
+ }
+ } break;
+ case STM1_O_BS_SHIPOUT: {
+ switch(c) {
+ case dkT('n'): {
+ if (!hbhtml_code_line_start(job)) { back = 0; }
+ if(!(hbhtml_shipout(job, dkT('\n')))) {
+ back = 0; $? "! ERROR"
+ if(0 == ltl) {
+ ltl = 1;
+ /* ERROR: Line too long! */
+ }
+ }
+ } break;
+ case dkT('r'): {
+ if (!hbhtml_code_line_start(job)) { back = 0; }
+ if(!(hbhtml_shipout(job, dkT('\r')))) {
+ back = 0; $? "! ERROR"
+ if(0 == ltl) {
+ ltl = 1;
+ /* ERROR: Line too long! */
+ }
+ }
+ } break;
+ case dkT('t'): {
+ if (!hbhtml_code_line_start(job)) { back = 0; }
+ if(!(hbhtml_shipout(job, dkT('\t')))) {
+ back = 0; $? "! ERROR"
+ if(0 == ltl) {
+ ltl = 1;
+ /* ERROR: Line too long! */
+ }
+ }
+ } break;
+ case dkT('%'): case dkT('\\'): {
+ if (!hbhtml_code_line_start(job)) { back = 0; }
+ if(!(hbhtml_shipout(job, c))) {
+ back = 0; $? "! ERROR"
+ if(0 == ltl) {
+ ltl = 1;
+ /* ERROR: Line too long! */
+ }
+ }
+ } break;
+ case dkT('.'): {
+ /* We can escape a leading dot.
+ */
+ if(1 < pos) {
+ xmsg[0] = dkT('\\');
+ xmsg[1] = c;
+ xmsg[2] = dkT('\0');
+ dk3app_log_3(job->app, DK3_LL_WARNING, job->msg, 63, 64, xmsg);
+ }
+ if (!hbhtml_code_line_start(job)) { back = 0; }
+ if(!(hbhtml_shipout(job, c))) {
+ back = 0; $? "! ERROR"
+ if(0 == ltl) {
+ ltl = 1;
+ /* ERROR: Line too long! */
+ }
+ }
+ } break;
+ default: {
+ xmsg[0] = dkT('\\');
+ xmsg[1] = c;
+ xmsg[2] = dkT('\0');
+ dk3app_log_3(job->app, DK3_LL_WARNING, job->msg, 63, 64, xmsg);
+ if (!hbhtml_code_line_start(job)) { back = 0; }
+ if(!(hbhtml_shipout(job, c))) {
+ back = 0; $? "! ERROR"
+ if(0 == ltl) {
+ ltl = 1;
+ /* ERROR: Line too long! */
+ }
+ }
+ } break;
+ }
+ } break;
+ case STM1_O_PERCENT_SHIPOUT: {
+ if (!hbhtml_code_line_start(job)) { back = 0; }
+ if(!(hbhtml_shipout(job, dkT('%')))) {
+ back = 0; $? "! ERROR"
+ if(0 == ltl) {
+ ltl = 1;
+ }
+ }
+ if(!(hbhtml_shipout(job, c))) {
+ back = 0; $? "! ERROR"
+ if(0 == ltl) {
+ ltl = 1;
+ }
+ }
+ } break;
+ case STM1_O_PERCENT: {
+ if (!hbhtml_code_line_start(job)) { back = 0; }
+ if(!(hbhtml_shipout(job, dkT('%')))) {
+ back = 0; $? "! ERROR"
+ if(0 == ltl) {
+ ltl = 1;
+ }
+ }
+ } break;
+ case STM1_O_SWITCH: {
+ hbhtml_flush_shipout(job);
+ job->spused = 0;
+ } break;
+ case STM1_O_SPECIAL: {
+ if(!hbhtml_add_to_special(job, c)) {
+ back = 0; $? "! ERROR"
+ if(0 == ltl) {
+ ltl = 1;
+ }
+ }
+ } break;
+ case STM1_O_SPEC_BS: {
+ switch(c) {
+ case dkT('n'): {
+ if(!hbhtml_add_to_special(job, dkT('\n'))) {
+ back = 0; $? "! ERROR"
+ if(0 == ltl) {
+ ltl = 1;
+ }
+ }
+ } break;
+ case dkT('r'): {
+ if(!hbhtml_add_to_special(job, dkT('\r'))) {
+ back = 0; $? "! ERROR"
+ if(0 == ltl) {
+ ltl = 1;
+ }
+ }
+ } break;
+ case dkT('t'): {
+ if(!hbhtml_add_to_special(job, dkT('\t'))) {
+ back = 0; $? "! ERROR"
+ if(0 == ltl) {
+ ltl = 1;
+ }
+ }
+ } break;
+ default: {
+ if(!hbhtml_add_to_special(job, c)) {
+ back = 0; $? "! ERROR"
+ if(0 == ltl) {
+ ltl = 1;
+ }
+ }
+ } break;
+ }
+ } break;
+ case STM1_O_SPEC_PC_ADD: {
+ if(!hbhtml_add_to_special(job, dkT('%'))) {
+ back = 0; $? "! ERROR"
+ if(0 == ltl) {
+ ltl = 1;
+ }
+ }
+ if(!hbhtml_add_to_special(job, c)) {
+ back = 0; $? "! ERROR"
+ if(0 == ltl) {
+ ltl = 1;
+ }
+ }
+ } break;
+ case STM1_O_SPEC_PC: {
+ if(!hbhtml_add_to_special(job, dkT('%'))) {
+ back = 0; $? "! ERROR"
+ if(0 == ltl) {
+ ltl = 1;
+ }
+ }
+ } break;
+ case STM1_O_EXECUTE: {
+ if((job->spused) < (job->bs)) {
+ (job->special)[job->spused] = dkT('\0');
+ back = hbhtml_process_special(job,proc->in_template,proc->p,proc->n);
+ } else {
+ back = 0; $? "! ERROR"
+ if(0 == ltl) {
+ ltl = 1;
+ }
+ }
+ job->spused = 0;
+ job->shipused = 0;
+ } break;
+ }
+ p1++;
+ if((dkT(' ') != c) && (dkT('\t') != c)) {
+ pos++;
+ }
+ }
+ switch(proc->stm) {
+ case STM1_ST_BS: {
+ if (!hbhtml_code_line_start(job)) { back = 0; }
+ if(!(hbhtml_shipout(job, dkT('\\')))) {
+ back = 0;
+ if(0 == ltl) { ltl = 1; }
+ }
+ } break;
+ case STM1_ST_PERCENT: {
+ if (!hbhtml_code_line_start(job)) { back = 0; }
+ if(!(hbhtml_shipout(job, dkT('%')))) {
+ back = 0;
+ if(0 == ltl) { ltl = 1; }
+ }
+ } break;
+ case STM1_ST_SPECIAL: case STM1_ST_SPEC_BS: case STM1_ST_SPEC_PC: {
+ /* ERROR: Unfinished special command! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 62);
+ back = 0;
+ } break;
+ }
+ if(ltl) {
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 31, 26, il);
+ }
+ hbhtml_flush_shipout(job);
+ if (!hbhtml_code_line_end(job)) { back = 0; }
+ if (EOF == fputc('\n', job->of)) {
+ back = 0; $? "! ERROR Newline"
+ }
+ $? "- hbhtml_line_handler %d", back
+ return back;
+}
+
+
+
+/** Write JS files to HTML header.
+ @param job Job structure.
+ @param nptr
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hbhtml_write_js_files(hb_job_t *job, hb_node_t *nptr)
+{
+ hb_link_t *linkptr; /* File name data for JavaScript file */
+ int back = 1;
+ /* Write parent JS files.
+ */
+ if(nptr->parent) {
+ if(!((nptr->options) & HB_NODE_OPT_STOP_JS_INHERITANCE)) {
+ hbhtml_write_js_files(job, nptr->parent);
+ }
+ }
+
+ /* Write node JS files.
+ */
+ if((nptr->s_jsfiles) && (nptr->i_jsfiles)) {
+ dk3sto_it_reset(nptr->i_jsfiles);
+ while(NULL != (linkptr = (hb_link_t *)dk3sto_it_next(nptr->i_jsfiles))) {
+ if(linkptr->url) {
+ fputs(hbhtml_c8_kw[121], job->of);
+ if(!hbhtml_url_output_for_text(job, linkptr->url)) { back = 0; }
+ fputs(hbhtml_c8_kw[122], job->of);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Write one head navigation entry.
+ @param job Job structure.
+ @param nptr Node (may be NULL for impressum).
+ @param url URL to use if nptr is NULL.
+ @param titleind Title index if nptr is NULL.
+ @param linkkwind Link keyword index.
+ @param appendind Index for keyword index.
+*/
+static
+void
+hbhtml_one_head_navigation(
+ hb_job_t *job,
+ hb_node_t *nptr,
+ dkChar const *url,
+ size_t titleind,
+ size_t linkkwind,
+ size_t appendind
+)
+{
+ dkChar bu[DK3_MAX_PATH]; /* Buffer for output file name */
+ hb_node_t *jnptr; /* Jump node */
+
+ if(nptr) {
+ jnptr = nptr;
+ if(!(jnptr->filename)) { jnptr = jnptr->jumpnode; }
+ if(hbhtml_create_output_filename(bu, DK3_SIZEOF(bu,dkChar), job, jnptr)) {
+ fputs(hbhtml_c8_kw[123], job->of);
+ fputs(hbhtml_c8_kw[linkkwind], job->of);
+ fputs(hbhtml_c8_kw[124], job->of);
+ if(!hbhtml_output_for_text(job, jnptr->title)) { job->exv = 1; }
+ fputs(hbhtml_c8_kw[125], job->of);
+ if(!hbhtml_url_output_for_text(job, bu)) { job->exv = 1; }
+ if(appendind) {
+ fputs(hbhtml_c8_kw[appendind], job->of);
+ }
+ fputs(hbhtml_c8_kw[126], job->of);
+ } else {
+ job->exv = 1;
+ }
+ } else {
+ fputs(hbhtml_c8_kw[123], job->of);
+ fputs(hbhtml_c8_kw[linkkwind], job->of);
+ fputs(hbhtml_c8_kw[124], job->of);
+ if(!hbhtml_output_for_text(job, (job->msg)[titleind])) { job->exv = 1; }
+ fputs(hbhtml_c8_kw[125], job->of);
+ if(!hbhtml_url_output_for_text(job, url)) { job->exv = 1; }
+ if(appendind) {
+ fputs(hbhtml_c8_kw[appendind], job->of);
+ }
+ fputs(hbhtml_c8_kw[126], job->of);
+ }
+}
+
+
+
+/** Write navigation entries to HTML header.
+ @param job Job structure.
+ @param node Current node to write.
+ @param prev Previous node.
+ @param next Next node.
+*/
+static
+void
+hbhtml_write_head_navigation(
+ hb_job_t *job,
+ hb_node_t *node,
+ hb_node_t *prev,
+ hb_node_t *next
+)
+{
+ hb_node_t *nptr; /* Current node to process */
+
+ /* Navigation (links)
+ author (impressum), contents, index, top, up, first, prev, next, last
+ link rel="..." title="..." href="..."
+ */
+ if(job->impressumnode) {
+ nptr = job->impressumnode;
+ hbhtml_one_head_navigation(job, nptr, NULL, 0, 127, 0);
+ } else {
+ if(job->impressumlink) {
+ hbhtml_one_head_navigation(job, NULL, job->impressumlink, 61, 127, 0);
+ }
+ }
+ if(job->rootnode) {
+ hbhtml_one_head_navigation(
+ job, job->rootnode, NULL, 0, 128,
+ (((job->options) & HB_JOB_OPT_CREATE_TOC) ? 136 : 0)
+ );
+ hbhtml_one_head_navigation(
+ job, job->rootnode, NULL, 0, 129,
+ (((job->options) & HB_JOB_OPT_CREATE_INDEX) ? 137 : 0)
+ );
+ hbhtml_one_head_navigation(job, job->rootnode, NULL, 0, 130, 0);
+ }
+ nptr = node;
+ nptr = nptr->parent;
+ if(nptr) {
+ while((!(nptr->filename)) && (nptr->parent)) { nptr = nptr->parent; }
+ if(nptr) {
+ hbhtml_one_head_navigation(job, nptr, NULL, 0, 131, 0);
+ }
+ }
+ if(job->firstnode) {
+ hbhtml_one_head_navigation(job, job->firstnode, NULL, 0, 132, 0);
+ }
+ if(prev) {
+ hbhtml_one_head_navigation(job, prev, NULL, 0, 133, 0);
+ }
+ if(next) {
+ hbhtml_one_head_navigation(job, next, NULL, 0, 134, 0);
+ }
+ if(job->lastnode) {
+ hbhtml_one_head_navigation(job, job->lastnode, NULL, 0, 135, 0);
+ }
+}
+
+
+
+/** Write HTML header
+ @param job Job structure.
+ @param nodeptr Current node to write.
+ @param prev Previous node.
+ @param next Next node.
+*/
+static
+void
+hbhtml_write_header(
+ hb_job_t *job, hb_node_t *nodeptr, hb_node_t *prev, hb_node_t *next
+)
+{
+ dkChar const *ptr; /* Multiple text elements */
+ $? "+ hbhtml_write_header"
+ fputs(hbhtml_c8_kw[15], job->of);
+ /* Title
+ */
+ fputs(hbhtml_c8_kw[19], job->of);
+ hbhtml_output_for_text(job, hbconf_title(nodeptr));
+ fputs(hbhtml_c8_kw[20], job->of);
+ /* Generator (comment)
+ */
+ if((nodeptr->options) & HB_NODE_OPT_USE_TIDY) {
+ fputs(hbhtml_c8_kw[17], job->of);
+ }
+ /* Generator (meta)
+ */
+ fputs(hbhtml_c8_kw[18], job->of);
+ /* Style (link)
+ */
+ ptr = hbconf_stylefile(nodeptr);
+ if(ptr) {
+ if(!hbtool_add_file(job, ptr)) { job->exv = 1; }
+ fputs(hbhtml_c8_kw[21], job->of);
+ hbhtml_url_output_for_text(job, ptr);
+ fputs(hbhtml_c8_kw[22], job->of);
+ }
+ /* Shortcut icon (link)
+ */
+ ptr = hbconf_favicon(nodeptr);
+ if(ptr) {
+ fputs(hbhtml_c8_kw[27], job->of);
+ hbhtml_url_output_for_text(job, ptr);
+ fputs(hbhtml_c8_kw[28], job->of);
+ }
+ /* Navigation (links)
+ */
+ hbhtml_write_head_navigation(job, nodeptr, prev, next);
+ /* Character set (meta)
+ */
+ if(HB_CS_UTF_8 == job->cs) {
+ fputs(hbhtml_c8_kw[24], job->of);
+ } else {
+ fputs(hbhtml_c8_kw[23], job->of);
+ }
+ /* Author (meta)
+ */
+ ptr = hbconf_author(nodeptr);
+ if(ptr) {
+ fputs(hbhtml_c8_kw[25], job->of);
+ hbhtml_output_for_text(job, ptr);
+ fputs(hbhtml_c8_kw[26], job->of);
+ }
+ /* Meta description tag
+ */
+ if (NULL != nodeptr->metadesc) {
+ fputs(hbhtml_c8_kw[154], job->of);
+ hbhtml_output_for_text(job, nodeptr->metadesc);
+ fputs(hbhtml_c8_kw[26], job->of);
+ }
+ /* Meta keywords tag.
+ */
+ if (NULL != nodeptr->metakeyw) {
+ fputs(hbhtml_c8_kw[155], job->of);
+ hbhtml_output_for_text(job, nodeptr->metakeyw);
+ fputs(hbhtml_c8_kw[26], job->of);
+ }
+ /* JavaScript files.
+ */
+ (void)hbhtml_write_js_files(job, nodeptr);
+ fputs(hbhtml_c8_kw[16], job->of); $? "- hbhtml_write_header"
+}
+
+
+
+/** Line handler processing function.
+ @param obj Handler object.
+ @param il Input line to process.
+ @return 1 on success, 0 on error (continue), -1 on error (exit).
+*/
+static
+int
+hbhtml_spcl_handler(void *obj, dkChar *il)
+{
+ hb_spc_reader_t *pspcr;
+ hb_job_t *job = NULL;
+ hb_node_t *nptr = NULL;
+ hb_link_t *linkptr= NULL;
+ dkChar *vptr = NULL;
+ dkChar *cptr = NULL;
+ size_t sl = 0;
+ int back = 1;
+ int idx = 0;
+ $? "+ hbhtml_spcl_handler \"%!ds\"", il
+ pspcr = (hb_spc_reader_t *)obj;
+ if (NULL != pspcr) {
+ job = pspcr->job;
+ nptr = pspcr->nodeptr;
+ pspcr->lineno += 1UL;
+ dk3app_set_source_line(job->app, pspcr->lineno);
+ idx = hbcont_metadata_index(il);
+ if (0 <= idx) {
+ $? ". meta data found"
+ dk3str_delnl(il);
+ sl = hbcont_metadata_length(idx);
+ if (0 < sl) {
+ sl++;
+ vptr = dk3str_start(&(il[sl]), NULL);
+ $? ". value \"%!ds\"", vptr
+ }
+ switch (idx) {
+ case 0: { $? ". description"
+ if (NULL != vptr) {
+ $? ". value ok"
+ cptr = dk3str_dup_app(vptr, job->app);
+ if (NULL != cptr) {
+ $? ". allocation ok"
+ if (NULL != nptr->metadesc) {
+ /* Warning: Overwriting description text */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 97);
+ dk3mem_free(nptr->metadesc);
+ }
+ nptr->metadesc = cptr;
+ }
+ } else {
+ /* ERROR: Missing description text */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 96);
+ back = -1;
+ }
+ } break;
+ case 1: { $? ". keywords"
+ if (NULL != vptr) {
+ $? ". value ok"
+ cptr = dk3str_dup_app(vptr, job->app);
+ if (NULL != cptr) {
+ $? ". allocation ok"
+ if (NULL != nptr->metakeyw) {
+ /* Warning: Overwriting keywords */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 98);
+ dk3mem_free(nptr->metakeyw);
+ }
+ nptr->metakeyw = cptr;
+ }
+ } else {
+ /* ERROR: Missing keywords text */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 96);
+ back = -1;
+ }
+ } break;
+ case 2: { $? ". author"
+ if (NULL != vptr) {
+ cptr = dk3str_dup_app(vptr, job->app);
+ if (NULL != cptr) {
+ if (NULL != nptr->author) {
+ if (0UL != nptr->objno) {
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 69);
+ }
+ dk3mem_free(nptr->author);
+ }
+ nptr->author = cptr;
+ } else {
+ back = -1;
+ }
+ } else {
+ /* ERROR: Missing author name */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 96);
+ back = -1;
+ }
+ } break;
+ case 3: { $? ". title"
+ if (NULL != vptr) {
+ cptr = dk3str_dup_app(vptr, job->app);
+ if (NULL != cptr) {
+ if (NULL != nptr->fulltitle) {
+ /* Warning: Overwriting title */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 70);
+ dk3mem_free(nptr->fulltitle);
+ }
+ nptr->fulltitle = cptr;
+ } else {
+ back = -1;
+ }
+ } else {
+ /* ERROR: Missing title text */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 96);
+ back = -1;
+ }
+ } break;
+ case 4: { $? ". short title"
+ if (NULL != vptr) {
+ cptr = dk3str_dup_app(vptr, job->app);
+ if (NULL != cptr) {
+ if (NULL != nptr->shorttitle) {
+ /* Warning: Overwriting short title */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 75);
+ dk3mem_free(nptr->shorttitle);
+ }
+ nptr->shorttitle = cptr;
+ } else {
+ back = -1;
+ }
+ } else {
+ /* ERROR: Missing short title text */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 96);
+ back = -1;
+ }
+ } break;
+ case 5: { $? ". location"
+ if (NULL != vptr) {
+ cptr = dk3str_dup_app(vptr, job->app);
+ if (NULL != cptr) {
+ if (NULL != nptr->location) {
+ /* Warning: Overwriting location */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 99);
+ dk3mem_free(nptr->location);
+ }
+ nptr->location = cptr;
+ } else {
+ back = -1;
+ }
+ } else {
+ /* ERROR: Missing location text */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 96);
+ back = -1;
+ }
+ } break;
+ case 6: { $? ". page-toc"
+ if (NULL != vptr) {
+ if (0 != dk3str_is_bool(vptr)) {
+ if (0 != dk3str_is_on(vptr)) {
+ (job->currentnode)->options |= HB_NODE_OPT_PAGE_TOC;
+ } else {
+ (job->currentnode)->options &= (~(HB_NODE_OPT_PAGE_TOC));
+ }
+ } else {
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 144, vptr);
+ back = -1;
+ }
+ } else {
+ (job->currentnode)->options |= HB_NODE_OPT_PAGE_TOC;
+ }
+ } break;
+ case 7: { $? ". replace-ampersand"
+ if (NULL != vptr) {
+ if (0 != dk3str_is_bool(vptr)) {
+ if (0 != dk3str_is_on(vptr)) {
+ (job->currentnode)->options |= HB_NODE_OPT_REPLACE_AMPERSAND;
+ } else {
+ (job->currentnode)->options &=
+ (~(HB_NODE_OPT_REPLACE_AMPERSAND));
+ }
+ } else {
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 144, vptr);
+ back = -1;
+ }
+ } else {
+ (job->currentnode)->options |= HB_NODE_OPT_REPLACE_AMPERSAND;
+ }
+ } break;
+ case 8: { $? ". write-position"
+ if (NULL != vptr) {
+ if (0 != dk3str_is_bool(vptr)) {
+ if (0 != dk3str_is_on(vptr)) {
+ (job->currentnode)->options |= HB_NODE_OPT_HEADER_CHAIN;
+ } else {
+ (job->currentnode)->options &= (~(HB_NODE_OPT_HEADER_CHAIN));
+ }
+ } else {
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 144, vptr);
+ back = -1;
+ }
+ } else {
+ (job->currentnode)->options |= HB_NODE_OPT_HEADER_CHAIN;
+ }
+ } break;
+ case 9: { $? ". suffix"
+ if (NULL != vptr) {
+ cptr = dk3str_dup_app(vptr, job->app);
+ if (NULL != cptr) {
+ if (NULL != nptr->suffix) {
+ /* Warning: Overwriting suffix */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 77);
+ dk3mem_free(nptr->suffix);
+ }
+ nptr->suffix = cptr;
+ } else {
+ back = -1;
+ }
+ } else {
+ /* ERROR: Missing suffix */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 96);
+ back = -1;
+ }
+ } break;
+ case 10: { $? ". shortcut-icon"
+ if (NULL != vptr) {
+ cptr = dk3str_dup_app(vptr, job->app);
+ if (NULL != cptr) {
+ dk3str_correct_filename(cptr);
+ hbtool_correct_backslash_to_slash(cptr);
+ if (NULL != nptr->favicon) {
+ /* Warning: Overwriting favicon */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 82);
+ dk3mem_free(nptr->favicon);
+ }
+ nptr->favicon = cptr;
+ if (!(hbtool_add_file(job, cptr))) {
+ back = -1;
+ }
+ if(!hbtool_check_filename_encoding(job, cptr)) { back = -1; }
+ } else {
+ back = -1;
+ }
+ } else {
+ /* ERROR: Missing icon name */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 96);
+ back = -1;
+ }
+ } break;
+ case 11: { $? ". js-file"
+ if (NULL != vptr) {
+ if (NULL == nptr->s_jsfiles) {
+ nptr->s_jsfiles = dk3sto_open_app(job->app);
+ if (NULL != nptr->s_jsfiles) {
+ dk3sto_set_comp(nptr->s_jsfiles, hbnode_link_compare, 2);
+ }
+ }
+ if (NULL == nptr->i_jsfiles) {
+ if (NULL != nptr->s_jsfiles) {
+ nptr->i_jsfiles = dk3sto_it_open(nptr->s_jsfiles);
+ }
+ }
+ if ((NULL != nptr->s_jsfiles) && (NULL != nptr->i_jsfiles)) {
+ linkptr = hbnode_link_new(vptr, nptr->nextjs, job->app);
+ if (NULL != linkptr) {
+ if(dk3sto_add(nptr->s_jsfiles, linkptr)) {
+ nptr->nextjs += 1UL;
+ if(!hbtool_add_url(job, vptr)) { back = -1; }
+ } else {
+ hbnode_link_delete(linkptr);
+ back = -1;
+ }
+ } else {
+ back = -1;
+ }
+ } else {
+ back = -1;
+ }
+ } else {
+ /* ERROR: Missing file name */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 96);
+ back = -1;
+ }
+ } break;
+ case 12: { $? ". inherit-js"
+ if (NULL != vptr) {
+ if (0 != dk3str_is_bool(vptr)) {
+ if (0 != dk3str_is_on(vptr)) {
+ (job->currentnode)->options &=
+ (~(HB_NODE_OPT_STOP_JS_INHERITANCE));
+ } else {
+ (job->currentnode)->options |= HB_NODE_OPT_STOP_JS_INHERITANCE;
+ }
+ } else {
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 146, 144, vptr);
+ back = -1;
+ }
+ } else {
+ (job->currentnode)->options &= (~(HB_NODE_OPT_STOP_JS_INHERITANCE));
+ }
+ } break;
+ case 13: { $? ". context-number"
+ long cn;
+ if (NULL != vptr) {
+ if (0 != dk3ma_l_from_string(&cn, vptr, NULL)) {
+ nptr->contnum = cn;
+ } else {
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 141);
+ back = -1;
+ }
+ } else {
+ /* ERROR: Missing number */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 96);
+ back = -1;
+ }
+ } break;
+ }
+ }
+ }
+ $? "- hbhtml_spcl_handler %d", back
+ return back;
+}
+
+
+
+/** Read special comments from input file for node.
+ @param job Job structure.
+ @param nodeptr Node to read file for.
+*/
+static
+void
+hbhtml_read_special_comments(hb_job_t *job, hb_node_t *nodeptr)
+{
+ hb_spc_reader_t spcr;
+ const dkChar *oldsourcefile;
+ unsigned long oldsourceline;
+ int inenc;
+ $? "+ hbhtml_read_special_comments"
+ if (NULL != nodeptr->filename) { $? ". have file name"
+ spcr.job = job;
+ spcr.nodeptr = nodeptr;
+ spcr.lineno = 0UL;
+ inenc = dk3app_get_input_file_encoding(job->app);
+ if(0 <= job->iecmd) { inenc = job->iecmd; }
+ if(0 <= nodeptr->inenc) { inenc = nodeptr->inenc; }
+ oldsourcefile = dk3app_get_source_file(job->app);
+ oldsourceline = dk3app_get_source_line(job->app);
+ dk3app_set_source_file(job->app, nodeptr->filename);
+ dk3app_set_source_line(job->app, 0UL);
+ (void)dk3stream_process_filename_lines_app(
+ (void *)(&spcr), hbhtml_spcl_handler, nodeptr->filename,
+ job->ilfile, job->bs,
+ dk3app_get_encoding(job->app),
+ inenc,
+ job->app
+ );
+ dk3app_set_source_file(job->app, oldsourcefile);
+ dk3app_set_source_line(job->app, oldsourceline);
+ }
+ $? "- hbhtml_read_special_comments"
+}
+
+
+
+/** Write one output file.
+ @param job Job structure.
+ @param nodeptr Current node to write.
+ @param fn Output file name.
+ @param p Previous node.
+ @param n Next node.
+*/
+static
+void
+hbhtml_write_named_file(
+ hb_job_t *job,
+ hb_node_t *nodeptr,
+ dkChar const *fn,
+ hb_node_t *p,
+ hb_node_t *n
+)
+{
+ hb_file_processor_t proc; /* Template file processor */
+ dkChar const *templateName; /* Template file name */
+ dkChar const *oldsourcefile; /* Old source file name */
+ unsigned long oldsourceline; /* Old source file line */
+ int inenc; /* Input encoding */
+ int res; /* Result from file processing */
+ $? "+ hbhtml_write_named_file"
+ $? ". input file \"%!ds\"", TR_STR(nodeptr->filename)
+ $? ". output file \"%!ds\"", fn
+ oldsourcefile = dk3app_get_source_file(job->app);
+ oldsourceline = dk3app_get_source_line(job->app);
+ dk3app_set_source_line(job->app, nodeptr->lineno);
+ nodeptr->outFileName = fn;
+ job->currentnode = nodeptr;
+ job->of = NULL;
+ templateName = hbconf_node_template(job, nodeptr);
+ if(templateName) {
+ dk3app_set_source_file(job->app, templateName);
+ job->options &= (~(HB_JOB_OPT_CODE));
+ job->of = dk3sf_fopen_app(fn, dkT("w"), job->app);
+ if(job->of) {
+ hbhtml_read_special_comments(job, nodeptr);
+ fputs(hbhtml_c8_kw[11], job->of);
+ hbhtml_write_header(job, nodeptr, p, n);
+ fputs(hbhtml_c8_kw[13], job->of);
+ proc.job = job;
+ proc.in_template = 1;
+ proc.stm = 0;
+ proc.p = p;
+ proc.n = n;
+ inenc = dk3app_get_input_file_encoding(job->app);
+ if(0 <= job->iecmd) { inenc = job->iecmd; }
+ res = dk3stream_process_filename_lines_app(
+ (void *)(&proc), hbhtml_line_handler, templateName,
+ job->iltemplate, job->bs,
+ dk3app_get_encoding(job->app),
+ inenc,
+ job->app
+ );
+ fputs(hbhtml_c8_kw[14], job->of);
+ fputs(hbhtml_c8_kw[12], job->of);
+ if(1 != res) {
+ job->exv = 1; $? "! ERROR"
+ }
+ if(!(dk3sf_fclose_fn_app(job->of, fn, job->app))) {
+ job->exv = 1; $? "! ERROR"
+ }
+ } else {
+ job->exv = 1; $? "! ERROR"
+ }
+ } else {
+ /* ERROR: No template! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 19);
+ job->exv = 1; $? "! ERROR"
+ }
+ nodeptr->outFileName = NULL;
+ dk3app_set_source_file(job->app, oldsourcefile);
+ dk3app_set_source_line(job->app, oldsourceline);
+ $? "- hbhtml_write_named_file"
+}
+
+
+
+/** Mark path to current node in parent nodes
+ (set the curchild element).
+ @param nodeptr Current node.
+*/
+static
+void
+hbhtml_mark_path(hb_node_t *nodeptr)
+{
+ hb_node_t *cp; /* Current node */
+ $? "+ hbhtml_mark_path"
+ cp = nodeptr;
+ cp->curchild = NULL;
+ while(cp) {
+ if(cp->parent) { (cp->parent)->curchild = cp; }
+ cp = cp->parent;
+ } $? "- hbhtml_mark_path"
+}
+
+
+
+void
+hbhtml_write_file(hb_job_t *job, hb_node_t *nodeptr, hb_node_t *p, hb_node_t *n)
+{
+ dkChar bu[DK3_MAX_PATH]; /* File name buffer. */
+ $? "+ hbhtml_write_file %lu \"%!ds\"", nodeptr->objno, TR_STR(nodeptr->title)
+
+ /* Set things up for new file.
+ */
+ job->coli = 0;
+ job->cols = HB_COLIST_NONE;
+ job->options &= (~(HB_JOB_OPT_CODE));
+
+ /* Process the file.
+ */
+ hbhtml_mark_path(nodeptr);
+ if(hbhtml_create_output_filename(bu, DK3_SIZEOF(bu,dkChar), job, nodeptr)) {
+ $? ". have output file name"
+ hbhtml_write_named_file(job, nodeptr, bu, p, n);
+ } else {
+ job->exv = 1; $? "! ERROR"
+ }
+
+ $? "- hbhtml_write_file"
+}
+
+
diff --git a/support/dktools/hbhtml.h b/support/dktools/hbhtml.h
new file mode 100644
index 0000000000..a0e8828d54
--- /dev/null
+++ b/support/dktools/hbhtml.h
@@ -0,0 +1,119 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: hbhtml.ctr
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file hbhtml.h Header file for the hbhtml module.
+*/
+
+#ifndef HBHTML_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define HBHTML_H_INCLUDED 1
+
+
+#line 9 "hbhtml.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Write one HTML file.
+ @param job Job structure.
+ @param nodeptr Node for file to write.
+ @param p Previous node.
+ @param n Next node.
+*/
+void
+hbhtml_write_file(hb_job_t *job,hb_node_t *nodeptr,hb_node_t *p,hb_node_t *n);
+
+/** Write one 32-bit character to HTML output.
+ @param job Job structure.
+ @param c32 Character to write.
+*/
+void
+hbhtml_c32(hb_job_t *job, dk3_c32_t c32);
+
+/** Write some text as HTML.
+ @param job Job structure.
+ @param text Text to write.
+ @return 1 on success, 0 on error.
+*/
+int
+hbhtml_output_for_text(hb_job_t *job, dkChar const *text);
+
+/** Write some URL text as HTML.
+ @param job Job structure.
+ @param text Text to write.
+ @return 1 on success, 0 on error.
+*/
+int
+hbhtml_url_output_for_text(hb_job_t *job, dkChar const *text);
+
+/** Handle one input line, either from template or from text file.
+ @param obj Line processor structure.
+ @param il Input line to process.
+ @return 1 on success, 0 on error (continue), -1 on error (exit).
+*/
+int
+hbhtml_line_handler(void *obj, dkChar *il);
+
+/** Construct output file name.
+ @param dptr Destination buffer pointer.
+ @param sz Destination buffer size.
+ @param job Job structure.
+ @param nptr Node to process.
+ @return 1 on success, 0 on error.
+*/
+int
+hbhtml_create_output_filename(
+ dkChar *dptr,
+ size_t sz,
+ hb_job_t *job,
+ hb_node_t *nptr
+);
+
+/** Check whether a link is an external link (http:// or ftp://
+ at start).
+ @param link Link to check.
+ @return 1 for external links, 0 for internal links.
+*/
+int
+hbhtml_check_link_for_external(dkChar const *link);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/hbimgdim.c b/support/dktools/hbimgdim.c
new file mode 100644
index 0000000000..59b5b8e333
--- /dev/null
+++ b/support/dktools/hbimgdim.c
@@ -0,0 +1,182 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: hbimgdim.ctr
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file hbimgdim.c The hbimgdim module.
+*/
+
+
+#line 69 "hbimgdim.ctr"
+
+
+#include "dk3all.h"
+#include "dk3bif.h"
+#include "htmlbook.h"
+
+
+
+
+
+#line 78 "hbimgdim.ctr"
+
+
+
+int
+hbimgdim_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ hb_img_dim_t *pl;
+ hb_img_dim_t *pr;
+
+
+#line 88 "hbimgdim.ctr"
+ if(l) {
+ if(r) {
+ pl = (hb_img_dim_t *)l;
+ switch(cr) {
+ case 1: {
+ back = dk3str_fncmp(pl->fn, (dkChar const *)r);
+ } break;
+ default: {
+ pr = (hb_img_dim_t *)r;
+ back = dk3str_fncmp(pl->fn, pr->fn);
+ } break;
+ }
+ if(-1 > back) { back = -1; }
+ if( 1 < back) { back = 1; }
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ }
+
+#line 106 "hbimgdim.ctr"
+ return back;
+}
+
+
+
+void
+hbimgdim_delete(hb_img_dim_t *ptr)
+{
+
+
+#line 115 "hbimgdim.ctr"
+ if(ptr) {
+ dk3_release(ptr->fn);
+ ptr->w = 0UL;
+ ptr->h = 0UL;
+ dk3_delete(ptr);
+ }
+
+#line 121 "hbimgdim.ctr"
+}
+
+
+
+hb_img_dim_t *
+hbimgdim_new(dkChar const *fn, unsigned long w, unsigned long h, dk3_app_t *app)
+{
+ hb_img_dim_t *back = NULL;
+
+
+#line 130 "hbimgdim.ctr"
+ back = dk3_new_app(hb_img_dim_t,1,app);
+ if(back) {
+ back->w = w;
+ back->h = h;
+ back->fn = dk3str_dup_app(fn,app);
+ if(!(back->fn)) {
+ hbimgdim_delete(back);
+ back = NULL;
+ }
+ }
+
+#line 140 "hbimgdim.ctr"
+ return back;
+}
+
+
+
+int
+hbimgdim_find(
+ hb_job_t *job,
+ dkChar const *fn,
+ unsigned long *w,
+ unsigned long *h,
+ int save
+)
+{
+ hb_img_dim_t *idptr; /* Image dimension found or new */
+ dk3_bif_t *bp; /* BIF object for graphics file */
+ unsigned long xw; /* Width read from file */
+ unsigned long xh; /* Height read from file */
+ int back = 0;
+
+
+#line 160 "hbimgdim.ctr"
+ if((job) && (fn) && (w) && (h)) {
+ idptr = dk3sto_it_find_like(job->i_imgdim, fn, 1);
+ if(idptr) {
+ *w = idptr->w;
+ *h = idptr->h;
+ back = 1;
+ } else {
+ bp = dk3bif_open_filename_app(fn, DK3_BIF_IMAGE_TYPE_UNKNOWN, job->app);
+ if(bp) {
+ xw = dk3bif_get_width(bp);
+ xh = dk3bif_get_height(bp);
+ dk3bif_close(bp);
+ if((xw) && (xh)) {
+ *w = xw;
+ *h = xh;
+ back = 1;
+ if(save) {
+ idptr = hbimgdim_new(fn, xw, xh, job->app);
+ if(idptr) {
+ if(!(dk3sto_add(job->s_imgdim, idptr))) {
+ hbimgdim_delete(idptr);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+#line 188 "hbimgdim.ctr"
+ return back;
+}
+
+
+
diff --git a/support/dktools/hbimgdim.ctr b/support/dktools/hbimgdim.ctr
new file mode 100644
index 0000000000..920d9950e2
--- /dev/null
+++ b/support/dktools/hbimgdim.ctr
@@ -0,0 +1,192 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2013-xxxx
+license = bsd
+
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Find image dimensions.
+ @param job Job structure.
+ @param fn Image file name.
+ @param w Pointer to result variable for width.
+ @param h Pointer to result variable for height.
+ @param save Flag: Save result to cache.
+ @return 1 on success, 0 on error.
+*/
+int
+hbimgdim_find(
+ hb_job_t *job,
+ dkChar const *fn,
+ unsigned long *w,
+ unsigned long *h,
+ int save
+);
+
+/** Create image dimension cache entry, allocate memory.
+ @param fn Image file name.
+ @param w Image width.
+ @param h Image height.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new entry on success, NULL on error.
+*/
+hb_img_dim_t *
+hbimgdim_new(
+ dkChar const *fn,
+ unsigned long w,
+ unsigned long h,
+ dk3_app_t *app
+);
+
+/** Delete image dimension cache entry, release memory.
+ @param ptr Cache entry to delete.
+*/
+void
+hbimgdim_delete(hb_img_dim_t *ptr);
+
+/** Compare two image dimension entries.
+ @param l Left entry pointer.
+ @param r Right entry pointer or file name pointer.
+ @param cr Comparison criteria (0=entry/entry, 1=entry/name).
+ @return Comparison result.
+*/
+int
+hbimgdim_compare(void const *l, void const *r, int cr);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+
+#include "dk3all.h"
+#include "dk3bif.h"
+#include "htmlbook.h"
+
+
+
+$!trace-include
+
+
+
+int
+hbimgdim_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ hb_img_dim_t *pl;
+ hb_img_dim_t *pr;
+ $? "+ hbimgdim_compare PTR=%d PTR=%d", TR_IPTR(l), TR_IPTR(r)
+ if(l) {
+ if(r) {
+ pl = (hb_img_dim_t *)l;
+ switch(cr) {
+ case 1: {
+ back = dk3str_fncmp(pl->fn, (dkChar const *)r);
+ } break;
+ default: {
+ pr = (hb_img_dim_t *)r;
+ back = dk3str_fncmp(pl->fn, pr->fn);
+ } break;
+ }
+ if(-1 > back) { back = -1; }
+ if( 1 < back) { back = 1; }
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ } $? "- hbimgdim_compare %d", back
+ return back;
+}
+
+
+
+void
+hbimgdim_delete(hb_img_dim_t *ptr)
+{
+ $? "+ hbimgdim_delete"
+ if(ptr) {
+ dk3_release(ptr->fn);
+ ptr->w = 0UL;
+ ptr->h = 0UL;
+ dk3_delete(ptr);
+ } $? "- hbimgdim_delete"
+}
+
+
+
+hb_img_dim_t *
+hbimgdim_new(dkChar const *fn, unsigned long w, unsigned long h, dk3_app_t *app)
+{
+ hb_img_dim_t *back = NULL;
+ $? "+ hbimgdim_new"
+ back = dk3_new_app(hb_img_dim_t,1,app);
+ if(back) {
+ back->w = w;
+ back->h = h;
+ back->fn = dk3str_dup_app(fn,app);
+ if(!(back->fn)) {
+ hbimgdim_delete(back);
+ back = NULL;
+ }
+ } $? "- hbimgdim_new PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+int
+hbimgdim_find(
+ hb_job_t *job,
+ dkChar const *fn,
+ unsigned long *w,
+ unsigned long *h,
+ int save
+)
+{
+ hb_img_dim_t *idptr; /* Image dimension found or new */
+ dk3_bif_t *bp; /* BIF object for graphics file */
+ unsigned long xw; /* Width read from file */
+ unsigned long xh; /* Height read from file */
+ int back = 0;
+ $? "+ hbimgdim_find"
+ if((job) && (fn) && (w) && (h)) {
+ idptr = dk3sto_it_find_like(job->i_imgdim, fn, 1);
+ if(idptr) {
+ *w = idptr->w;
+ *h = idptr->h;
+ back = 1;
+ } else {
+ bp = dk3bif_open_filename_app(fn, DK3_BIF_IMAGE_TYPE_UNKNOWN, job->app);
+ if(bp) {
+ xw = dk3bif_get_width(bp);
+ xh = dk3bif_get_height(bp);
+ dk3bif_close(bp);
+ if((xw) && (xh)) {
+ *w = xw;
+ *h = xh;
+ back = 1;
+ if(save) {
+ idptr = hbimgdim_new(fn, xw, xh, job->app);
+ if(idptr) {
+ if(!(dk3sto_add(job->s_imgdim, idptr))) {
+ hbimgdim_delete(idptr);
+ }
+ }
+ }
+ }
+ }
+ }
+ } $? "- hbimgdim_find %d", back
+ return back;
+}
+
+
+
diff --git a/support/dktools/hbimgdim.h b/support/dktools/hbimgdim.h
new file mode 100644
index 0000000000..0c1597513e
--- /dev/null
+++ b/support/dktools/hbimgdim.h
@@ -0,0 +1,104 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: hbimgdim.ctr
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file hbimgdim.h Header file for the hbimgdim module.
+*/
+
+#ifndef HBIMGDIM_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define HBIMGDIM_H_INCLUDED 1
+
+
+#line 10 "hbimgdim.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Find image dimensions.
+ @param job Job structure.
+ @param fn Image file name.
+ @param w Pointer to result variable for width.
+ @param h Pointer to result variable for height.
+ @param save Flag: Save result to cache.
+ @return 1 on success, 0 on error.
+*/
+int
+hbimgdim_find(
+ hb_job_t *job,
+ dkChar const *fn,
+ unsigned long *w,
+ unsigned long *h,
+ int save
+);
+
+/** Create image dimension cache entry, allocate memory.
+ @param fn Image file name.
+ @param w Image width.
+ @param h Image height.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new entry on success, NULL on error.
+*/
+hb_img_dim_t *
+hbimgdim_new(
+ dkChar const *fn,
+ unsigned long w,
+ unsigned long h,
+ dk3_app_t *app
+);
+
+/** Delete image dimension cache entry, release memory.
+ @param ptr Cache entry to delete.
+*/
+void
+hbimgdim_delete(hb_img_dim_t *ptr);
+
+/** Compare two image dimension entries.
+ @param l Left entry pointer.
+ @param r Right entry pointer or file name pointer.
+ @param cr Comparison criteria (0=entry/entry, 1=entry/name).
+ @return Comparison result.
+*/
+int
+hbimgdim_compare(void const *l, void const *r, int cr);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/hbindex.c b/support/dktools/hbindex.c
new file mode 100644
index 0000000000..e8f64f7dc2
--- /dev/null
+++ b/support/dktools/hbindex.c
@@ -0,0 +1,209 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: hbindex.ctr
+*/
+
+/** @file hbindex.c The hbindex module.
+*/
+
+
+#line 56 "hbindex.ctr"
+
+
+#include "dk3all.h"
+#include "htmlbook.h"
+
+
+
+
+
+#line 64 "hbindex.ctr"
+
+
+
+int
+hbindex_compare(void const *l, void const *r, int cr)
+{
+ hb_index_entry_t const *pl;
+ hb_index_entry_t const *pr;
+ int back = 0;
+
+
+#line 74 "hbindex.ctr"
+ if(l) {
+ if(r) {
+ pl = (hb_index_entry_t const *)l;
+ switch(cr) {
+ case 1: {
+ back = dk3str_casecmp(pl->tx, (dkChar const *)r);
+ } break;
+ default: {
+ pr = (hb_index_entry_t const *)r;
+ back = dk3str_casecmp(pl->tx, pr->tx);
+ if(0 == back) {
+#if VERSION_BEFORE_20140423
+ if(pl->fn) {
+ if(pr->fn) {
+ back = dk3str_fncmp(pl->fn, pr->fn);
+ } else back = 1;
+ } else {
+ if(pr->fn) back = -1;
+ }
+#else
+ if (pl->no) {
+ if (pr->no) {
+ if ((pl->no)->objno > (pr->no)->objno) {
+ back = 1;
+ } else {
+ if ((pr->no)->objno > (pl->no)->objno) {
+ back = -1;
+ }
+ }
+ } else back = 1;
+ } else {
+ if (pr->no) back = -1;
+ }
+#endif
+ }
+ if(0 == back) {
+ if(pl->an) {
+ if(pr->an) {
+ back = dk3str_cmp(pl->an, pr->an);
+ } else back = 1;
+ } else {
+ if(pr->an) back = -1;
+ else {
+ if(pl->ul > pr->ul) {
+ back = 1;
+ } else {
+ if(pl->ul < pr->ul) {
+ back = -1;
+ }
+ }
+ }
+ }
+ }
+ } break;
+ }
+ if(-1 > back) { back = -1; }
+ if( 1 < back) { back = 1; }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+
+#line 139 "hbindex.ctr"
+ return back;
+}
+
+
+
+void
+hbindex_delete(hb_index_entry_t *pi)
+{
+
+
+#line 148 "hbindex.ctr"
+ if(pi) {
+
+
+#line 150 "hbindex.ctr"
+
+
+#line 151 "hbindex.ctr"
+
+
+#line 152 "hbindex.ctr"
+
+
+#line 153 "hbindex.ctr"
+ pi->no = NULL;
+ dk3_release(pi->tx);
+ dk3_release(pi->fn);
+ dk3_release(pi->an);
+ pi->ul = 0UL;
+ dk3_delete(pi);
+ }
+
+#line 160 "hbindex.ctr"
+}
+
+
+hb_index_entry_t *
+hbindex_new(
+ dkChar const *tx,
+ dkChar const *fn,
+ dkChar const *an,
+ unsigned long const ul,
+ dk3_app_t *app,
+ hb_node_t *nptr
+)
+{
+ hb_index_entry_t *back = NULL; /* New index entry */
+ int ok = 0;
+
+
+#line 176 "hbindex.ctr"
+ if((tx) && (fn)) {
+ back = dk3_new_app(hb_index_entry_t,1,app);
+ if(back) {
+ back->no = nptr;
+ back->tx = NULL;
+ back->fn = NULL;
+ back->an = NULL;
+ back->ul = ul;
+ back->tx = dk3str_dup_app(tx,app);
+ back->fn = dk3str_dup_app(fn,app);
+ if((back->tx) && (back->fn)) {
+ ok = 1;
+ if(an) {
+ back->an = dk3str_dup_app(an,app);
+ if(!(back->an)) { ok = 0; }
+ }
+ }
+ if(!(ok)) {
+ hbindex_delete(back);
+ back = NULL;
+ }
+ }
+ }
+
+#line 199 "hbindex.ctr"
+ return back;
+}
+
+
+
+int
+hb_index_write_anchor(hb_job_t *job, hb_index_entry_t *in)
+{
+ int back = 0;
+
+
+#line 209 "hbindex.ctr"
+ if((job) && (in)) {
+ back = 1;
+ if(in->an) {
+ if(!hbhtml_url_output_for_text(job, in->an)) {
+ back = 0;
+ }
+ } else {
+#if DK3_SIZEOF_LONG > 4
+ fprintf(job->of, "hb_i%016lx", in->ul);
+#else
+ fprintf(job->of, "hb_i%08lx", in->ul);
+#endif
+ }
+ }
+
+#line 223 "hbindex.ctr"
+ return back;
+}
+
+
diff --git a/support/dktools/hbindex.ctr b/support/dktools/hbindex.ctr
new file mode 100644
index 0000000000..35b4396e30
--- /dev/null
+++ b/support/dktools/hbindex.ctr
@@ -0,0 +1,226 @@
+%% options
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Create index entry, allocate memory.
+ @param tx Index text.
+ @param fn File name.
+ @param an Anchor name (optional).
+ @param ul Anchor number, used if no anchor name specified.
+ @param app Application structure for diagnostics, may be NULL.
+ @param nptr Current node.
+ @return Pointer to new entry on success, NULL on error.
+*/
+hb_index_entry_t *
+hbindex_new(
+ dkChar const *tx,
+ dkChar const *fn,
+ dkChar const *an,
+ unsigned long const ul,
+ dk3_app_t *app,
+ hb_node_t *nptr
+);
+
+/** Destroy index entry, release memory.
+ @param pi Index entry to destroy.
+*/
+void
+hbindex_delete(hb_index_entry_t *pi);
+
+/** Compare two index entries.
+ @param l Left entry.
+ @param r Right entry or name.
+ @param cr Comparison criteria (0=object/object, 1=object/name).
+ @return Comparison result.
+*/
+int
+hbindex_compare(void const *l, void const *r, int cr);
+
+/** Write anchor name for index entry (either given name or number-based).
+ @param job Job structure.
+ @param in Index entry.
+ @return 1 on success, 0 on error.
+*/
+int
+hb_index_write_anchor(hb_job_t *job, hb_index_entry_t *in);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+
+#include "dk3all.h"
+#include "htmlbook.h"
+
+
+
+$!trace-include
+
+
+
+int
+hbindex_compare(void const *l, void const *r, int cr)
+{
+ hb_index_entry_t const *pl;
+ hb_index_entry_t const *pr;
+ int back = 0;
+ $? "+ hbindex_compare PTR=%d PTR=%d", TR_IPTR(l), TR_IPTR(r)
+ if(l) {
+ if(r) {
+ pl = (hb_index_entry_t const *)l;
+ switch(cr) {
+ case 1: {
+ back = dk3str_casecmp(pl->tx, (dkChar const *)r);
+ } break;
+ default: {
+ pr = (hb_index_entry_t const *)r;
+ back = dk3str_casecmp(pl->tx, pr->tx);
+ if(0 == back) {
+#if VERSION_BEFORE_20140423
+ if(pl->fn) {
+ if(pr->fn) {
+ back = dk3str_fncmp(pl->fn, pr->fn);
+ } else back = 1;
+ } else {
+ if(pr->fn) back = -1;
+ }
+#else
+ if (pl->no) {
+ if (pr->no) {
+ if ((pl->no)->objno > (pr->no)->objno) {
+ back = 1;
+ } else {
+ if ((pr->no)->objno > (pl->no)->objno) {
+ back = -1;
+ }
+ }
+ } else back = 1;
+ } else {
+ if (pr->no) back = -1;
+ }
+#endif
+ }
+ if(0 == back) {
+ if(pl->an) {
+ if(pr->an) {
+ back = dk3str_cmp(pl->an, pr->an);
+ } else back = 1;
+ } else {
+ if(pr->an) back = -1;
+ else {
+ if(pl->ul > pr->ul) {
+ back = 1;
+ } else {
+ if(pl->ul < pr->ul) {
+ back = -1;
+ }
+ }
+ }
+ }
+ }
+ } break;
+ }
+ if(-1 > back) { back = -1; }
+ if( 1 < back) { back = 1; }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ } $? "- hbindex_compare %d", back
+ return back;
+}
+
+
+
+void
+hbindex_delete(hb_index_entry_t *pi)
+{
+ $? "+ hbindex_delete"
+ if(pi) {
+ $? ". anchor = \"%!ds\"", TR_STR(pi->an)
+ $? ". number = %lu", pi->ul
+ $? ". file = \"%!ds\"", TR_STR(pi->fn)
+ $? ". text = \"%!ds\"", TR_STR(pi->tx)
+ pi->no = NULL;
+ dk3_release(pi->tx);
+ dk3_release(pi->fn);
+ dk3_release(pi->an);
+ pi->ul = 0UL;
+ dk3_delete(pi);
+ } $? "- hbindex_delete"
+}
+
+
+hb_index_entry_t *
+hbindex_new(
+ dkChar const *tx,
+ dkChar const *fn,
+ dkChar const *an,
+ unsigned long const ul,
+ dk3_app_t *app,
+ hb_node_t *nptr
+)
+{
+ hb_index_entry_t *back = NULL; /* New index entry */
+ int ok = 0;
+ $? "+ hbindex_new \"%!ds\" \"%!ds\" \"%!ds\", %lu", TR_STR(tx), TR_STR(fn), TR_STR(an), ul
+ if((tx) && (fn)) {
+ back = dk3_new_app(hb_index_entry_t,1,app);
+ if(back) {
+ back->no = nptr;
+ back->tx = NULL;
+ back->fn = NULL;
+ back->an = NULL;
+ back->ul = ul;
+ back->tx = dk3str_dup_app(tx,app);
+ back->fn = dk3str_dup_app(fn,app);
+ if((back->tx) && (back->fn)) {
+ ok = 1;
+ if(an) {
+ back->an = dk3str_dup_app(an,app);
+ if(!(back->an)) { ok = 0; }
+ }
+ }
+ if(!(ok)) {
+ hbindex_delete(back);
+ back = NULL;
+ }
+ }
+ } $? "- hbindex_new PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+int
+hb_index_write_anchor(hb_job_t *job, hb_index_entry_t *in)
+{
+ int back = 0;
+ $? "+ hb_index_write_anchor"
+ if((job) && (in)) {
+ back = 1;
+ if(in->an) {
+ if(!hbhtml_url_output_for_text(job, in->an)) {
+ back = 0;
+ }
+ } else {
+#if DK3_SIZEOF_LONG > 4
+ fprintf(job->of, "hb_i%016lx", in->ul);
+#else
+ fprintf(job->of, "hb_i%08lx", in->ul);
+#endif
+ }
+ } $? "- hb_index_write_anchor %d", back
+ return back;
+}
+
+
diff --git a/support/dktools/hbindex.h b/support/dktools/hbindex.h
new file mode 100644
index 0000000000..311319eb12
--- /dev/null
+++ b/support/dktools/hbindex.h
@@ -0,0 +1,69 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: hbindex.ctr
+*/
+
+/** @file hbindex.h Header file for the hbindex module.
+*/
+
+#ifndef HBINDEX_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define HBINDEX_H_INCLUDED 1
+
+
+#line 4 "hbindex.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Create index entry, allocate memory.
+ @param tx Index text.
+ @param fn File name.
+ @param an Anchor name (optional).
+ @param ul Anchor number, used if no anchor name specified.
+ @param app Application structure for diagnostics, may be NULL.
+ @param nptr Current node.
+ @return Pointer to new entry on success, NULL on error.
+*/
+hb_index_entry_t *
+hbindex_new(
+ dkChar const *tx,
+ dkChar const *fn,
+ dkChar const *an,
+ unsigned long const ul,
+ dk3_app_t *app,
+ hb_node_t *nptr
+);
+
+/** Destroy index entry, release memory.
+ @param pi Index entry to destroy.
+*/
+void
+hbindex_delete(hb_index_entry_t *pi);
+
+/** Compare two index entries.
+ @param l Left entry.
+ @param r Right entry or name.
+ @param cr Comparison criteria (0=object/object, 1=object/name).
+ @return Comparison result.
+*/
+int
+hbindex_compare(void const *l, void const *r, int cr);
+
+/** Write anchor name for index entry (either given name or number-based).
+ @param job Job structure.
+ @param in Index entry.
+ @return 1 on success, 0 on error.
+*/
+int
+hb_index_write_anchor(hb_job_t *job, hb_index_entry_t *in);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/hbnode.c b/support/dktools/hbnode.c
new file mode 100644
index 0000000000..0d246e06c9
--- /dev/null
+++ b/support/dktools/hbnode.c
@@ -0,0 +1,539 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: hbnode.ctr
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file hbnode.c The hbnode module.
+*/
+
+
+#line 85 "hbnode.ctr"
+
+#include "htmlbook.h"
+#include "dk3all.h"
+
+
+
+
+
+#line 92 "hbnode.ctr"
+
+
+
+void
+hbnode_link_delete(hb_link_t *ptr)
+{
+
+
+#line 99 "hbnode.ctr"
+ if(ptr) {
+ ptr->lno = 0UL;
+ dk3_release(ptr->url);
+ dk3_delete(ptr);
+ }
+
+#line 104 "hbnode.ctr"
+}
+
+
+
+hb_link_t *
+hbnode_link_new(dkChar const *url, unsigned long lno, dk3_app_t *app)
+{
+ hb_link_t *back = NULL;
+
+
+#line 113 "hbnode.ctr"
+ if(url) {
+ back = dk3_new_app(hb_link_t,1,app);
+ if(back) {
+ back->lno = lno;
+ back->url = dk3str_dup_app(url,app);
+ if(!(back->url)) {
+ hbnode_link_delete(back);
+ back = NULL;
+ }
+ }
+ }
+
+#line 124 "hbnode.ctr"
+ return back;
+}
+
+
+
+int
+hbnode_link_compare(const void *l, const void *r, int cr)
+{
+ hb_link_t *pl;
+ hb_link_t *pr;
+ int back = 0;
+
+
+#line 136 "hbnode.ctr"
+ if(l) {
+ if(r) {
+ pl = (hb_link_t *)l;
+ switch(cr) {
+ case 0: {
+ pr = (hb_link_t *)r;
+ back = dk3str_cmp(pl->url, pr->url);
+ } break;
+ case 1: {
+ back = dk3str_cmp(pl->url, (dkChar const *)r);
+ } break;
+ default: {
+ pr = (hb_link_t *)r;
+ if(pl->lno > pr->lno) {
+ back = 1;
+ } else {
+ if(pl->lno < pr->lno) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ if(-1 > back) { back = -1; }
+ if( 1 < back) { back = 1; }
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ }
+
+#line 164 "hbnode.ctr"
+ return back;
+}
+
+
+
+int
+hb_node_compare(void const *l, void const *r, int cr)
+{
+ hb_node_t const *pl;
+ hb_node_t const *pr;
+ int back = 0;
+
+
+#line 176 "hbnode.ctr"
+ if(l) {
+ if(r) {
+ pl = (hb_node_t const *)l;
+ pr = (hb_node_t const *)r;
+ if(pl->objno > pr->objno) {
+ back = 1;
+ } else {
+ if(pr->objno > pl->objno) {
+ back = -1;
+ }
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+
+#line 195 "hbnode.ctr"
+ return back;
+}
+
+
+
+void
+hb_node_delete(hb_node_t *ptr)
+{
+ hb_link_t *linkptr;
+ hb_line_t *hp;
+ dk3_key_value_t *kp;
+ if(ptr) {
+
+
+#line 208 "hbnode.ctr"
+ if(ptr->s_lbylno) {
+ if(ptr->i_lbylno) {
+ dk3sto_it_close(ptr->i_lbylno);
+ }
+ dk3sto_close(ptr->s_lbylno);
+ }
+ ptr->s_lbylno = NULL; ptr->i_lbylno = NULL;
+ if(ptr->s_lbyurl) {
+ if(ptr->i_lbyurl) {
+ dk3sto_it_reset(ptr->i_lbyurl);
+ while(NULL != (linkptr = (hb_link_t *)dk3sto_it_next(ptr->i_lbyurl))) {
+ hbnode_link_delete(linkptr);
+ }
+ dk3sto_it_close(ptr->i_lbyurl);
+ }
+ dk3sto_close(ptr->s_lbyurl);
+ }
+ ptr->s_lbyurl = NULL; ptr->i_lbyurl = NULL;
+ if(ptr->s_lines) {
+ if(ptr->i_lines) {
+ dk3sto_it_reset(ptr->i_lines);
+ while(NULL != (hp = (hb_line_t *)dk3sto_it_next(ptr->i_lines))) {
+ hbcont_line_delete(hp);
+ }
+ dk3sto_it_close(ptr->i_lines);
+ }
+ dk3sto_close(ptr->s_lines);
+ } ptr->s_lines = NULL; ptr->i_lines = NULL;
+ if(ptr->s_variables) {
+ if(ptr->i_variables) {
+ dk3sto_it_reset(ptr->i_variables);
+ do {
+ kp = (dk3_key_value_t *)dk3sto_it_next(ptr->i_variables);
+ if(kp) { dk3kv_delete(kp); }
+ } while(kp);
+ dk3sto_it_close(ptr->i_variables);
+ }
+ dk3sto_close(ptr->s_variables);
+ }
+ ptr->s_variables = NULL; ptr->i_variables = NULL;
+ if(ptr->s_jsfiles) {
+ if(ptr->i_jsfiles) {
+ dk3sto_it_reset(ptr->i_jsfiles);
+ while(NULL != (linkptr = (hb_link_t *)dk3sto_it_next(ptr->i_jsfiles))) {
+
+
+#line 253 "hbnode.ctr"
+ hbnode_link_delete(linkptr);
+ }
+ dk3sto_it_close(ptr->i_jsfiles);
+ }
+ dk3sto_close(ptr->s_jsfiles);
+ } ptr->s_jsfiles = NULL; ptr->i_jsfiles = NULL;
+ /* We can simply close the storage here, all nodes are listed
+ in the s_nodes storage of the job structure.
+ */
+ if(ptr->s_subnodes) {
+ if(ptr->i_subnodes) {
+ dk3sto_it_close(ptr->i_subnodes);
+ }
+ dk3sto_close(ptr->s_subnodes);
+ }
+ ptr->s_subnodes = NULL;
+ ptr->i_subnodes = NULL;
+ ptr->parent = NULL;
+ ptr->curchild = NULL;
+ ptr->jumpnode = NULL;
+#if TRACE_DEBUG
+
+
+#line 275 "hbnode.ctr"
+
+
+#line 276 "hbnode.ctr"
+
+
+#line 277 "hbnode.ctr"
+
+
+#line 278 "hbnode.ctr"
+ if(ptr->parent) {
+
+#line 279 "hbnode.ctr"
+ }
+ if(ptr->title) {
+
+#line 281 "hbnode.ctr"
+ }
+ if(ptr->shorttitle) {
+
+#line 283 "hbnode.ctr"
+ }
+ if(ptr->fulltitle) {
+
+#line 285 "hbnode.ctr"
+ }
+ if(ptr->filename) {
+
+#line 287 "hbnode.ctr"
+ }
+ if(ptr->suffix) {
+
+#line 289 "hbnode.ctr"
+ }
+ if(ptr->template) {
+
+#line 291 "hbnode.ctr"
+ }
+ if(ptr->stylefile) {
+
+#line 293 "hbnode.ctr"
+ }
+ if(ptr->author) {
+
+#line 295 "hbnode.ctr"
+ }
+ if(ptr->location) {
+
+#line 297 "hbnode.ctr"
+ }
+ if(ptr->icontoc) {
+
+#line 299 "hbnode.ctr"
+ }
+ if(ptr->iconprev) {
+
+#line 301 "hbnode.ctr"
+ }
+ if(ptr->iconnext) {
+
+#line 303 "hbnode.ctr"
+ }
+ if(ptr->iconhome) {
+
+#line 305 "hbnode.ctr"
+ }
+ if(ptr->iconindex) {
+
+#line 307 "hbnode.ctr"
+ }
+ if(ptr->favicon) {
+
+#line 309 "hbnode.ctr"
+ }
+ if(ptr->metadesc) {
+
+#line 311 "hbnode.ctr"
+ }
+ if(ptr->metakeyw) {
+
+#line 313 "hbnode.ctr"
+ }
+#endif
+ dk3_release(ptr->title);
+ dk3_release(ptr->shorttitle);
+ dk3_release(ptr->fulltitle);
+ dk3_release(ptr->filename);
+ dk3_release(ptr->suffix);
+ dk3_release(ptr->template);
+ dk3_release(ptr->stylefile);
+ dk3_release(ptr->author);
+ dk3_release(ptr->location);
+ dk3_release(ptr->icontoc);
+ dk3_release(ptr->iconprev);
+ dk3_release(ptr->iconnext);
+ dk3_release(ptr->iconindex);
+ dk3_release(ptr->iconhome);
+ dk3_release(ptr->favicon);
+ dk3_release(ptr->metadesc);
+ dk3_release(ptr->metakeyw);
+ ptr->lineno = 0UL;
+ ptr->objno = 0UL;
+ ptr->indent = 0;
+ ptr->inenc = 0;
+ ptr->options = 0U;
+ ptr->havenavimenu = 0;
+ dk3_delete(ptr);
+
+
+#line 340 "hbnode.ctr"
+ }
+}
+
+
+
+/** Find depth of a node.
+ @param ptr Node to inspect.
+ @return Node depth.
+*/
+static
+int
+hbnode_find_depth(hb_node_t *ptr)
+{
+ int back = 0;
+
+
+#line 355 "hbnode.ctr"
+ ptr = ptr->parent;
+ while(ptr) {
+ back++;
+ ptr = ptr->parent;
+ }
+
+#line 360 "hbnode.ctr"
+ return back;
+}
+
+
+
+hb_node_t *
+hb_node_new(
+ hb_job_t *job,
+ hb_node_t *parent,
+ unsigned long lineno,
+ unsigned long objno,
+ int indent
+)
+{
+ hb_node_t *back = NULL;
+ int ok = 0;
+
+
+#line 377 "hbnode.ctr"
+ back = dk3_new_app(hb_node_t,1,job->app);
+ if(back) {
+ back->parent = parent;
+ back->curchild = NULL;
+ back->jumpnode = NULL;
+ back->s_subnodes = NULL;
+ back->i_subnodes = NULL;
+ back->s_variables = NULL;
+ back->i_variables = NULL;
+ back->s_lines = NULL;
+ back->i_lines = NULL;
+ back->s_lbyurl = NULL;
+ back->i_lbyurl = NULL;
+ back->s_lbylno = NULL;
+ back->i_lbylno = NULL;
+ back->s_jsfiles = NULL;
+ back->i_jsfiles = NULL;
+ back->title = NULL;
+ back->shorttitle = NULL;
+ back->fulltitle = NULL;
+ back->filename = NULL;
+ back->suffix = NULL;
+ back->template = NULL;
+ back->stylefile = NULL;
+ back->author = NULL;
+ back->location = NULL;
+ back->icontoc = NULL;
+ back->iconprev = NULL;
+ back->iconnext = NULL;
+ back->iconindex = NULL;
+ back->iconhome = NULL;
+ back->favicon = NULL;
+ back->metadesc = NULL;
+ back->metakeyw = NULL;
+ back->lineno = lineno;
+ back->objno = objno;
+ back->pobjno = 0UL;
+ back->nextlink = 0UL;
+ back->nextindex = 0UL;
+ back->outFileName = NULL;
+ back->headno = 0UL;
+ back->nextsubheadno = 0UL;
+ back->nextjs = 0UL;
+ back->contnum = 0L;
+ back->havenavimenu = 0;
+ /* back->inenc = -1; */
+ if(parent) {
+ back->inenc = parent->inenc;
+ } else {
+ back->inenc = job->iecmd;
+ }
+ /* As each node is configured after the parent is finished we can
+ implement option inheritance by simply copying the parents options.
+ */
+ back->options = 0U; if(parent) { back->options = parent->options; }
+ back->indent = indent;
+ back->depth = 0;
+ back->tocstate = HB_TOC_STATE_INIT;
+ back->s_subnodes = dk3sto_open_app(job->app);
+ if(back->s_subnodes) {
+ dk3sto_set_comp(back->s_subnodes, hb_node_compare, 0);
+ back->i_subnodes = dk3sto_it_open(back->s_subnodes);
+ if(back->i_subnodes) {
+ back->s_variables = dk3sto_open_app(job->app);
+ if(back->s_variables) {
+ dk3sto_set_comp(back->s_variables, dk3kv_compare, 0);
+ back->i_variables = dk3sto_it_open(back->s_variables);
+ if(back->i_variables) {
+ back->s_lbyurl = dk3sto_open_app(job->app);
+ if(back->s_lbyurl) {
+ dk3sto_set_comp(back->s_lbyurl, hbnode_link_compare, 0);
+ back->i_lbyurl = dk3sto_it_open(back->s_lbyurl);
+ if(back->i_lbyurl) {
+ back->s_lbylno = dk3sto_open_app(job->app);
+ if(back->s_lbylno) {
+ dk3sto_set_comp(back->s_lbylno, hbnode_link_compare, 2);
+ back->i_lbylno = dk3sto_it_open(back->s_lbylno);
+ if(back->i_lbylno) {
+ ok = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if(!(ok)) {
+ hb_node_delete(back);
+ back = NULL;
+ }
+ if(back) {
+ back->depth = hbnode_find_depth(back);
+ }
+ }
+
+#line 472 "hbnode.ctr"
+ return back;
+}
+
+
+
+dkChar const *
+hbnode_variable(hb_node_t *node, dkChar const *name)
+{
+ dk3_key_value_t *kvp;
+ dkChar const *back = NULL;
+ int cc = 1;
+
+
+#line 484 "hbnode.ctr"
+ if((node) && (name)) {
+ while(cc) {
+ if(node) {
+ kvp = dk3sto_it_find_like(node->i_variables, name, 1);
+ if(kvp) {
+ cc = 0;
+ back = kvp->val;
+ } else {
+ node = node->parent;
+ }
+ } else {
+ cc = 0;
+ }
+ }
+ }
+
+#line 499 "hbnode.ctr"
+ return back;
+}
+
+
+
diff --git a/support/dktools/hbnode.ctr b/support/dktools/hbnode.ctr
new file mode 100644
index 0000000000..095b3abd6d
--- /dev/null
+++ b/support/dktools/hbnode.ctr
@@ -0,0 +1,503 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2013-xxxx
+license = bsd
+
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Compare two nodes.
+ @param l Pointer to left node.
+ @param r Pointer to right node.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+int
+hb_node_compare(void const *l, void const *r, int cr);
+
+/** Create node, allocate memory.
+ @param job Job structure.
+ @param parent Parent node.
+ @param lineno Line number where object was created.
+ @param objno Object number (in order of creation).
+ @param indent Line indent.
+ @return Pointer to new node on success, NULL on error.
+*/
+hb_node_t *
+hb_node_new(
+ hb_job_t *job,
+ hb_node_t *parent,
+ unsigned long lineno,
+ unsigned long objno,
+ int indent
+);
+
+/** Destroy node, release memory.
+ @param ptr Node to destroy.
+*/
+void
+hb_node_delete(hb_node_t *ptr);
+
+/** Search for variable in node and parents.
+ @param node Start node for search.
+ @param name Variable name.
+ @return Pointer to value on success, NULL on error.
+*/
+dkChar const *
+hbnode_variable(hb_node_t *node, dkChar const *name);
+
+/** Create link structure.
+ @param url URL to store.
+ @param lno Link number.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new link structure on success, NULL on error.
+*/
+hb_link_t *
+hbnode_link_new(dkChar const *url, unsigned long lno, dk3_app_t *app);
+
+/** Delete link structure.
+ @param ptr Link structure to delete.
+*/
+void
+hbnode_link_delete(hb_link_t *ptr);
+
+/** Compare two link structures.
+ @param l Left structure.
+ @param r Right structure or URL.
+ @param cr Comparison criteria
+ (0=obj/obj by URL, 1=obj/URL, 2=obj/obj by lno).
+ @return Comparison result.
+*/
+int
+hbnode_link_compare(const void *l, const void *r, int cr);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+#include "htmlbook.h"
+#include "dk3all.h"
+
+
+
+$!trace-include
+
+
+
+void
+hbnode_link_delete(hb_link_t *ptr)
+{
+ $? "+ hbnode_link_delete"
+ if(ptr) {
+ ptr->lno = 0UL;
+ dk3_release(ptr->url);
+ dk3_delete(ptr);
+ } $? "- hbnode_link_delete"
+}
+
+
+
+hb_link_t *
+hbnode_link_new(dkChar const *url, unsigned long lno, dk3_app_t *app)
+{
+ hb_link_t *back = NULL;
+ $? "+ hbnode_link_new"
+ if(url) {
+ back = dk3_new_app(hb_link_t,1,app);
+ if(back) {
+ back->lno = lno;
+ back->url = dk3str_dup_app(url,app);
+ if(!(back->url)) {
+ hbnode_link_delete(back);
+ back = NULL;
+ }
+ }
+ } $? "- hbnode_link_new PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+int
+hbnode_link_compare(const void *l, const void *r, int cr)
+{
+ hb_link_t *pl;
+ hb_link_t *pr;
+ int back = 0;
+ $? "+ hbnode_link_compare PTR=%d PTR=%d", TR_IPTR(l), TR_IPTR(r)
+ if(l) {
+ if(r) {
+ pl = (hb_link_t *)l;
+ switch(cr) {
+ case 0: {
+ pr = (hb_link_t *)r;
+ back = dk3str_cmp(pl->url, pr->url);
+ } break;
+ case 1: {
+ back = dk3str_cmp(pl->url, (dkChar const *)r);
+ } break;
+ default: {
+ pr = (hb_link_t *)r;
+ if(pl->lno > pr->lno) {
+ back = 1;
+ } else {
+ if(pl->lno < pr->lno) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ if(-1 > back) { back = -1; }
+ if( 1 < back) { back = 1; }
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ } $? "- hbnode_link_compare %d", back
+ return back;
+}
+
+
+
+int
+hb_node_compare(void const *l, void const *r, int cr)
+{
+ hb_node_t const *pl;
+ hb_node_t const *pr;
+ int back = 0;
+ $? "+ hb_node_compare PTR=%d PTR=%d", TR_IPTR(l), TR_IPTR(r)
+ if(l) {
+ if(r) {
+ pl = (hb_node_t const *)l;
+ pr = (hb_node_t const *)r;
+ if(pl->objno > pr->objno) {
+ back = 1;
+ } else {
+ if(pr->objno > pl->objno) {
+ back = -1;
+ }
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ } $? "- hb_node_compare %d", back
+ return back;
+}
+
+
+
+void
+hb_node_delete(hb_node_t *ptr)
+{
+ hb_link_t *linkptr;
+ hb_line_t *hp;
+ dk3_key_value_t *kp;
+ if(ptr) {
+ $? "+ hb_node_delete \"%!ds\"", TR_STR(ptr->title)
+ if(ptr->s_lbylno) {
+ if(ptr->i_lbylno) {
+ dk3sto_it_close(ptr->i_lbylno);
+ }
+ dk3sto_close(ptr->s_lbylno);
+ }
+ ptr->s_lbylno = NULL; ptr->i_lbylno = NULL;
+ if(ptr->s_lbyurl) {
+ if(ptr->i_lbyurl) {
+ dk3sto_it_reset(ptr->i_lbyurl);
+ while(NULL != (linkptr = (hb_link_t *)dk3sto_it_next(ptr->i_lbyurl))) {
+ hbnode_link_delete(linkptr);
+ }
+ dk3sto_it_close(ptr->i_lbyurl);
+ }
+ dk3sto_close(ptr->s_lbyurl);
+ }
+ ptr->s_lbyurl = NULL; ptr->i_lbyurl = NULL;
+ if(ptr->s_lines) {
+ if(ptr->i_lines) {
+ dk3sto_it_reset(ptr->i_lines);
+ while(NULL != (hp = (hb_line_t *)dk3sto_it_next(ptr->i_lines))) {
+ hbcont_line_delete(hp);
+ }
+ dk3sto_it_close(ptr->i_lines);
+ }
+ dk3sto_close(ptr->s_lines);
+ } ptr->s_lines = NULL; ptr->i_lines = NULL;
+ if(ptr->s_variables) {
+ if(ptr->i_variables) {
+ dk3sto_it_reset(ptr->i_variables);
+ do {
+ kp = (dk3_key_value_t *)dk3sto_it_next(ptr->i_variables);
+ if(kp) { dk3kv_delete(kp); }
+ } while(kp);
+ dk3sto_it_close(ptr->i_variables);
+ }
+ dk3sto_close(ptr->s_variables);
+ }
+ ptr->s_variables = NULL; ptr->i_variables = NULL;
+ if(ptr->s_jsfiles) {
+ if(ptr->i_jsfiles) {
+ dk3sto_it_reset(ptr->i_jsfiles);
+ while(NULL != (linkptr = (hb_link_t *)dk3sto_it_next(ptr->i_jsfiles))) {
+ $? ". js file %lu \"%!ds\"", linkptr->lno, linkptr->url
+ hbnode_link_delete(linkptr);
+ }
+ dk3sto_it_close(ptr->i_jsfiles);
+ }
+ dk3sto_close(ptr->s_jsfiles);
+ } ptr->s_jsfiles = NULL; ptr->i_jsfiles = NULL;
+ /* We can simply close the storage here, all nodes are listed
+ in the s_nodes storage of the job structure.
+ */
+ if(ptr->s_subnodes) {
+ if(ptr->i_subnodes) {
+ dk3sto_it_close(ptr->i_subnodes);
+ }
+ dk3sto_close(ptr->s_subnodes);
+ }
+ ptr->s_subnodes = NULL;
+ ptr->i_subnodes = NULL;
+ ptr->parent = NULL;
+ ptr->curchild = NULL;
+ ptr->jumpnode = NULL;
+#if TRACE_DEBUG
+ $? ". objno = %lu", ptr->objno
+ $? ". lineno = %lu", ptr->lineno
+ $? ". options = %u", ptr->options
+ $? ". indent = %d", ptr->indent
+ if(ptr->parent) { $? ". have parent"
+ }
+ if(ptr->title) { $? ". title = \"%!ds\"", ptr->title
+ }
+ if(ptr->shorttitle) { $? ". shorttitle = \"%!ds\"", ptr->shorttitle
+ }
+ if(ptr->fulltitle) { $? ". fulltitle= = \"%!ds\"", ptr->fulltitle
+ }
+ if(ptr->filename) { $? ". filename = \"%!ds\"", ptr->filename
+ }
+ if(ptr->suffix) { $? ". suffix = \"%!ds\"", ptr->suffix
+ }
+ if(ptr->template) { $? ". template = \"%!ds\"", ptr->template
+ }
+ if(ptr->stylefile) { $? ". stylefile = \"%!ds\"", ptr->stylefile
+ }
+ if(ptr->author) { $? ". author = \"%!ds\"", ptr->author
+ }
+ if(ptr->location) { $? ". location = \"%!ds\"", ptr->location
+ }
+ if(ptr->icontoc) { $? ". icontoc = \"%!ds\"", ptr->icontoc
+ }
+ if(ptr->iconprev) { $? ". iconprev = \"%!ds\"", ptr->iconprev
+ }
+ if(ptr->iconnext) { $? ". iconnext = \"%!ds\"", ptr->iconnext
+ }
+ if(ptr->iconhome) { $? ". iconhome = \"%!ds\"", ptr->iconhome
+ }
+ if(ptr->iconindex) { $? ". iconindex = \"%!ds\"", ptr->iconindex
+ }
+ if(ptr->favicon) { $? ". favicon = \"%!ds\"", ptr->favicon
+ }
+ if(ptr->metadesc) { $? ". metadesc = \"%!ds\"", ptr->metadesc
+ }
+ if(ptr->metakeyw) { $? ". metakeyw = \"%!ds\"", ptr->metakeyw
+ }
+#endif
+ dk3_release(ptr->title);
+ dk3_release(ptr->shorttitle);
+ dk3_release(ptr->fulltitle);
+ dk3_release(ptr->filename);
+ dk3_release(ptr->suffix);
+ dk3_release(ptr->template);
+ dk3_release(ptr->stylefile);
+ dk3_release(ptr->author);
+ dk3_release(ptr->location);
+ dk3_release(ptr->icontoc);
+ dk3_release(ptr->iconprev);
+ dk3_release(ptr->iconnext);
+ dk3_release(ptr->iconindex);
+ dk3_release(ptr->iconhome);
+ dk3_release(ptr->favicon);
+ dk3_release(ptr->metadesc);
+ dk3_release(ptr->metakeyw);
+ ptr->lineno = 0UL;
+ ptr->objno = 0UL;
+ ptr->indent = 0;
+ ptr->inenc = 0;
+ ptr->options = 0U;
+ ptr->havenavimenu = 0;
+ dk3_delete(ptr);
+ $? "- hb_node_delete"
+ }
+}
+
+
+
+/** Find depth of a node.
+ @param ptr Node to inspect.
+ @return Node depth.
+*/
+static
+int
+hbnode_find_depth(hb_node_t *ptr)
+{
+ int back = 0;
+ $? "+ hbnode_find_depth"
+ ptr = ptr->parent;
+ while(ptr) {
+ back++;
+ ptr = ptr->parent;
+ } $? "- hbnode_find_depth %d", back
+ return back;
+}
+
+
+
+hb_node_t *
+hb_node_new(
+ hb_job_t *job,
+ hb_node_t *parent,
+ unsigned long lineno,
+ unsigned long objno,
+ int indent
+)
+{
+ hb_node_t *back = NULL;
+ int ok = 0;
+ $? "+ hb_node_new"
+ back = dk3_new_app(hb_node_t,1,job->app);
+ if(back) {
+ back->parent = parent;
+ back->curchild = NULL;
+ back->jumpnode = NULL;
+ back->s_subnodes = NULL;
+ back->i_subnodes = NULL;
+ back->s_variables = NULL;
+ back->i_variables = NULL;
+ back->s_lines = NULL;
+ back->i_lines = NULL;
+ back->s_lbyurl = NULL;
+ back->i_lbyurl = NULL;
+ back->s_lbylno = NULL;
+ back->i_lbylno = NULL;
+ back->s_jsfiles = NULL;
+ back->i_jsfiles = NULL;
+ back->title = NULL;
+ back->shorttitle = NULL;
+ back->fulltitle = NULL;
+ back->filename = NULL;
+ back->suffix = NULL;
+ back->template = NULL;
+ back->stylefile = NULL;
+ back->author = NULL;
+ back->location = NULL;
+ back->icontoc = NULL;
+ back->iconprev = NULL;
+ back->iconnext = NULL;
+ back->iconindex = NULL;
+ back->iconhome = NULL;
+ back->favicon = NULL;
+ back->metadesc = NULL;
+ back->metakeyw = NULL;
+ back->lineno = lineno;
+ back->objno = objno;
+ back->pobjno = 0UL;
+ back->nextlink = 0UL;
+ back->nextindex = 0UL;
+ back->outFileName = NULL;
+ back->headno = 0UL;
+ back->nextsubheadno = 0UL;
+ back->nextjs = 0UL;
+ back->contnum = 0L;
+ back->havenavimenu = 0;
+ /* back->inenc = -1; */
+ if(parent) {
+ back->inenc = parent->inenc;
+ } else {
+ back->inenc = job->iecmd;
+ }
+ /* As each node is configured after the parent is finished we can
+ implement option inheritance by simply copying the parents options.
+ */
+ back->options = 0U; if(parent) { back->options = parent->options; }
+ back->indent = indent;
+ back->depth = 0;
+ back->tocstate = HB_TOC_STATE_INIT;
+ back->s_subnodes = dk3sto_open_app(job->app);
+ if(back->s_subnodes) {
+ dk3sto_set_comp(back->s_subnodes, hb_node_compare, 0);
+ back->i_subnodes = dk3sto_it_open(back->s_subnodes);
+ if(back->i_subnodes) {
+ back->s_variables = dk3sto_open_app(job->app);
+ if(back->s_variables) {
+ dk3sto_set_comp(back->s_variables, dk3kv_compare, 0);
+ back->i_variables = dk3sto_it_open(back->s_variables);
+ if(back->i_variables) {
+ back->s_lbyurl = dk3sto_open_app(job->app);
+ if(back->s_lbyurl) {
+ dk3sto_set_comp(back->s_lbyurl, hbnode_link_compare, 0);
+ back->i_lbyurl = dk3sto_it_open(back->s_lbyurl);
+ if(back->i_lbyurl) {
+ back->s_lbylno = dk3sto_open_app(job->app);
+ if(back->s_lbylno) {
+ dk3sto_set_comp(back->s_lbylno, hbnode_link_compare, 2);
+ back->i_lbylno = dk3sto_it_open(back->s_lbylno);
+ if(back->i_lbylno) {
+ ok = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if(!(ok)) {
+ hb_node_delete(back);
+ back = NULL;
+ }
+ if(back) {
+ back->depth = hbnode_find_depth(back);
+ }
+ } $? "- hb_node_new PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+dkChar const *
+hbnode_variable(hb_node_t *node, dkChar const *name)
+{
+ dk3_key_value_t *kvp;
+ dkChar const *back = NULL;
+ int cc = 1;
+ $? "+ hbnode_variable \"%!ds\"", TR_STR(name)
+ if((node) && (name)) {
+ while(cc) {
+ if(node) {
+ kvp = dk3sto_it_find_like(node->i_variables, name, 1);
+ if(kvp) {
+ cc = 0;
+ back = kvp->val;
+ } else {
+ node = node->parent;
+ }
+ } else {
+ cc = 0;
+ }
+ }
+ } $? "- hbnode_variable \"%!ds\"", TR_STR(back)
+ return back;
+}
+
+
+
diff --git a/support/dktools/hbnode.h b/support/dktools/hbnode.h
new file mode 100644
index 0000000000..dbd619af2b
--- /dev/null
+++ b/support/dktools/hbnode.h
@@ -0,0 +1,120 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: hbnode.ctr
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file hbnode.h Header file for the hbnode module.
+*/
+
+#ifndef HBNODE_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define HBNODE_H_INCLUDED 1
+
+
+#line 10 "hbnode.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Compare two nodes.
+ @param l Pointer to left node.
+ @param r Pointer to right node.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+int
+hb_node_compare(void const *l, void const *r, int cr);
+
+/** Create node, allocate memory.
+ @param job Job structure.
+ @param parent Parent node.
+ @param lineno Line number where object was created.
+ @param objno Object number (in order of creation).
+ @param indent Line indent.
+ @return Pointer to new node on success, NULL on error.
+*/
+hb_node_t *
+hb_node_new(
+ hb_job_t *job,
+ hb_node_t *parent,
+ unsigned long lineno,
+ unsigned long objno,
+ int indent
+);
+
+/** Destroy node, release memory.
+ @param ptr Node to destroy.
+*/
+void
+hb_node_delete(hb_node_t *ptr);
+
+/** Search for variable in node and parents.
+ @param node Start node for search.
+ @param name Variable name.
+ @return Pointer to value on success, NULL on error.
+*/
+dkChar const *
+hbnode_variable(hb_node_t *node, dkChar const *name);
+
+/** Create link structure.
+ @param url URL to store.
+ @param lno Link number.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Pointer to new link structure on success, NULL on error.
+*/
+hb_link_t *
+hbnode_link_new(dkChar const *url, unsigned long lno, dk3_app_t *app);
+
+/** Delete link structure.
+ @param ptr Link structure to delete.
+*/
+void
+hbnode_link_delete(hb_link_t *ptr);
+
+/** Compare two link structures.
+ @param l Left structure.
+ @param r Right structure or URL.
+ @param cr Comparison criteria
+ (0=obj/obj by URL, 1=obj/URL, 2=obj/obj by lno).
+ @return Comparison result.
+*/
+int
+hbnode_link_compare(const void *l, const void *r, int cr);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/hbtool.c b/support/dktools/hbtool.c
new file mode 100644
index 0000000000..bc77ec9830
--- /dev/null
+++ b/support/dktools/hbtool.c
@@ -0,0 +1,400 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: hbtool.ctr
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file hbtool.c The hbtool module.
+*/
+
+
+#line 113 "hbtool.ctr"
+
+
+#include "dk3all.h"
+#include "dk3se.h"
+#include "htmlbook.h"
+
+
+
+
+
+#line 122 "hbtool.ctr"
+
+
+
+int
+hbtool_add_file(hb_job_t *job, dkChar const *fn)
+{
+ dkChar bu[DK3_MAX_PATH]; /* File name buffer */
+ dkChar *p1; /* Start of file name */
+ int back = 0;
+
+
+#line 132 "hbtool.ctr"
+ if(fn) {
+ if(dk3str_len(fn) < DK3_SIZEOF(bu,dkChar)) {
+ p1 = dk3str_start(fn, NULL);
+ if(p1) {
+ dk3str_cpy(bu, p1);
+ dk3str_chomp(bu, NULL);
+ if(dk3sto_it_find_like(job->i_files, bu, 0)) {
+ back = 1;
+ } else {
+ p1 = dk3str_dup_app(bu, job->app);
+ if(p1) {
+ if(dk3sto_add(job->s_files, p1)) {
+ back = 1;
+ } else {
+ dk3_delete(p1);
+ }
+ }
+ }
+ }
+ } else {
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 65, 66, fn);
+ }
+ }
+
+#line 155 "hbtool.ctr"
+ return back;
+}
+
+
+
+int
+hbtool_check_filename_encoding(hb_job_t *job, dkChar const *fn)
+{
+ int back;
+ int se; /* Standard encoding to check */
+
+
+#line 166 "hbtool.ctr"
+#if DK3_ON_WINDOWS
+ se = (DK3SE_ANSI | DK3SE_URL);
+#else
+ if((job->options) & HB_JOB_OPT_CHM) {
+ se = (DK3SE_ANSI | DK3SE_URL);
+ } else {
+ se = DK3SE_URL;
+ }
+#endif
+ back = dk3se_check(fn,dk3app_get_encoding(job->app),se,NULL,NULL,job->app);
+
+
+#line 177 "hbtool.ctr"
+ return back;
+}
+
+
+
+int
+hbtool_check_filename(hb_job_t *job, dkChar const *fn)
+{
+ int back;
+
+
+#line 187 "hbtool.ctr"
+ back = hbtool_check_filename_encoding(job, fn);
+ if(dk3str_chr(fn, DK3_CHAR_SEP)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 12);
+ back = 0;
+ }
+
+#line 192 "hbtool.ctr"
+ return back;
+}
+
+
+
+
+dk3_c32_t
+hbtool_get_start_char(dkChar const *text, int enc)
+{
+ dk3_c32_t back = 0UL;
+ dk3_c32_t c32 = 0UL; /* Start character */
+ size_t sl; /* String length */
+ size_t used; /* Number of bytes used */
+#if DK3_CHAR_SIZE <= 1
+ char c; /* Result character */
+#endif
+
+
+#line 209 "hbtool.ctr"
+ if(text) {
+ sl = dk3str_len(text);
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ back = *text;
+#else
+ used = 0;
+ if(dk3enc_utf162uc(&c32, text, sl, &used)) {
+ back = c32;
+ }
+#endif
+#else
+ if(enc == DK3_ENCODING_UTF8) {
+ used = 0;
+ if(dk3enc_utf82uc(&c32, (unsigned char const *)text, sl, &used)) {
+ back = c32;
+ }
+ } else {
+ c = *text;
+ back = (dk3_c32_t)c;
+ back &= ((dk3_c32_t)0x000000FFUL);
+ }
+#endif
+ }
+
+#line 233 "hbtool.ctr"
+ return back;
+}
+
+
+
+void
+hbtool_enumerate(hb_job_t *job)
+{
+ hb_node_t *nptr; /* Next node */
+ hb_node_t *cptr; /* Current node */
+ dk3sto_it_reset(job->i_nodes);
+ while(NULL != (nptr = (hb_node_t *)dk3sto_it_next(job->i_nodes))) {
+ nptr->headno = 0UL; nptr->nextsubheadno = 0UL;
+ nptr->tocstate = HB_TOC_STATE_INIT;
+ }
+ cptr = job->rootnode;
+ while(cptr) {
+ switch(cptr->tocstate) {
+ case HB_TOC_STATE_INIT: {
+ dk3sto_it_reset(cptr->i_subnodes);
+ nptr = (hb_node_t *)dk3sto_it_next(cptr->i_subnodes);
+ if(nptr) {
+ cptr->tocstate = HB_TOC_STATE_IN_PROGRESS;
+ nptr->headno = cptr->nextsubheadno;
+ cptr->nextsubheadno += 1UL;
+ cptr = nptr;
+ } else {
+ cptr->tocstate = HB_TOC_STATE_FINISHED;
+ cptr = cptr->parent;
+ }
+ } break;
+ case HB_TOC_STATE_IN_PROGRESS: {
+ nptr = (hb_node_t *)dk3sto_it_next(cptr->i_subnodes);
+ if(nptr) {
+ nptr->headno = cptr->nextsubheadno;
+ cptr->nextsubheadno += 1UL;
+ cptr = nptr;
+ } else {
+ cptr->tocstate = HB_TOC_STATE_FINISHED;
+ cptr = cptr->parent;
+ }
+ } break;
+ case HB_TOC_STATE_FINISHED: {
+ cptr = cptr->parent;
+ } break;
+ }
+ }
+ dk3sto_it_reset(job->i_nodes);
+ while(NULL != (nptr = (hb_node_t *)dk3sto_it_next(job->i_nodes))) {
+ nptr->tocstate = HB_TOC_STATE_INIT;
+ }
+}
+
+
+
+int
+hbtool_write_header_number(hb_job_t *job, hb_node_t *nptr)
+{
+ dkChar bu[32];
+ int back = 0;
+
+
+#line 294 "hbtool.ctr"
+ if((job) && (nptr)) {
+ if(nptr->parent) {
+
+#line 296 "hbtool.ctr"
+ if(nptr->depth <= job->headlevels) {
+
+#line 297 "hbtool.ctr"
+ back = 1;
+ if(job->impressumnode) {
+ if((job->impressumnode)->objno == nptr->objno) {
+ back = 0;
+
+#line 301 "hbtool.ctr"
+ }
+ }
+ if(back) {
+
+#line 304 "hbtool.ctr"
+ hbtool_write_header_number(job, nptr->parent);
+ if(1 < nptr->depth) {
+
+#line 306 "hbtool.ctr"
+ hbhtml_output_for_text(job, dkT("."));
+ }
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(bu, dkT("%lu"), (1UL + nptr->headno));
+ hbhtml_output_for_text(job, bu);
+
+#line 311 "hbtool.ctr"
+#else
+ if (dk3ma_um_to_string(bu, DK3_SIZEOF(bu,dkChar), (dk3_um_t)(1UL + nptr->headno))) {
+ hbhtml_output_for_text(job, bu);
+ }
+#endif
+ } else {
+
+#line 317 "hbtool.ctr"
+ }
+ } else {
+
+#line 319 "hbtool.ctr"
+ }
+ } else {
+
+#line 321 "hbtool.ctr"
+ }
+ }
+
+#line 323 "hbtool.ctr"
+ return back;
+}
+
+
+
+int
+hbtool_add_url(hb_job_t *job, dkChar const *url)
+{
+ dkChar bu[DK3_MAX_PATH]; /* Copy of URL */
+ dkChar *p1; /* Start of text in url */
+ int back = 1;
+ if(!hbhtml_check_link_for_external(url)) {
+ if(dk3str_len(url) < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy(bu, url);
+ p1 = dk3str_chr(bu, dkT('?'));
+ if(p1) {
+ *p1 = dkT('\0');
+ } else {
+ p1 = dk3str_chr(bu, dkT('#'));
+ if(p1) {
+ *p1 = dkT('\0');
+ }
+ }
+ if(NULL == dk3str_chr(bu, dkT('/'))) {
+ if(0 < dk3str_len(bu)) {
+ back = hbtool_add_file(job, bu);
+ }
+ }
+ } else {
+ /* ERROR: File name too long! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 65, 66, url);
+ back = 0;
+ }
+ }
+ return back;
+}
+
+
+
+void
+hbtool_correct_backslash_to_slash(dkChar *str)
+{
+#if DK3_ON_WINDOWS
+ dkChar *ptr;
+ ptr = str;
+ while(*ptr) {
+ if(dkT('\\') == *ptr) { *ptr = dkT('/'); }
+ ptr++;
+ }
+#endif
+}
+
+
+
+int
+hbtool_write_all_titles(hb_job_t *job, hb_node_t *nptr, int isprim)
+{
+ int back = 0;
+ /* hbhtml_output_for_text(job, dkT(" ")); */
+ if ((job) && (nptr)) {
+ if (nptr->parent) {
+ back = 1;
+ if (job->impressumnode) {
+ if ((job->impressumnode)->objno == nptr->objno) {
+ back = 0;
+ }
+ }
+ if (back) {
+ if (hbtool_write_all_titles(job, nptr->parent, 0)) {
+ hbhtml_output_for_text(job, dkT(" &#8594; "));
+ }
+ if (isprim) {
+ if (nptr->title) {
+ hbhtml_output_for_text(job, nptr->title);
+ }
+ } else {
+ if (nptr->shorttitle) {
+ hbhtml_output_for_text(job, nptr->shorttitle);
+ } else {
+ if (nptr->title) {
+ hbhtml_output_for_text(job, nptr->title);
+ }
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+hbtool_write_text_utf(hb_job_t *job, dkChar const *src)
+{
+ char bu[(1024 < DK3_MAX_PATH) ? DK3_MAX_PATH : 1024];
+ int back = 0;
+ int ie;
+ if ((job) && (src)) {
+ ie = dk3app_get_encoding(job->app);
+ if (dk3str_to_c8u_app(bu, sizeof(bu), src, ie, job->app)) {
+ if (EOF != fputs(bu, job->of)) {
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/hbtool.ctr b/support/dktools/hbtool.ctr
new file mode 100644
index 0000000000..31075a254e
--- /dev/null
+++ b/support/dktools/hbtool.ctr
@@ -0,0 +1,432 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2013-xxxx
+license = bsd
+
+
+
+%% header
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Add one file name to the list of files to copy.
+ @param job Job structure.
+ @param fn File name.
+ @return 1 on success, 0 on error.
+*/
+int
+hbtool_add_file(hb_job_t *job, dkChar const *fn);
+
+/** Add one file (probably with CGI arguments) to list of files to copy.
+ The URL is only added if it references a local file name
+ in the current working directory without any protocol
+ specification, (src="filename.png"). For all other URLs we skip
+ adding and return 1.
+ @param job Job structure.
+ @param url URL as specified.
+ @return 1 on success, 0 on error.
+*/
+int
+hbtool_add_url(hb_job_t *job, dkChar const *url);
+
+/** Check file name. The file must be specified without a path.
+ The file name must be encodable as URL
+ so it must be in range 0x00000000 to 0x000000FF.
+ For Windows systems the file name must be encodable as ANSI,
+ so the following codes are excluded from the range above:
+ 0x80 to 0x8C, 0x8E, 0x91 to 0x9C, 0x9E to 0x9F.
+ @param job Job structure.
+ @param fn File name.
+ @return 1 on success, 0 on error.
+*/
+int
+hbtool_check_filename(hb_job_t *job, dkChar const *fn);
+
+/** Check file name encoding.
+ The file name must be encodable as URL
+ so it must be in range 0x00000000 to 0x000000FF.
+ For Windows systems the file name must be encodable as ANSI,
+ so the following codes are excluded from the range above:
+ 0x80 to 0x8C, 0x8E, 0x91 to 0x9C, 0x9E to 0x9F.
+ @param job Job structure.
+ @param fn File name.
+ @return 1 on success, 0 on error.
+*/
+int
+hbtool_check_filename_encoding(hb_job_t *job, dkChar const *fn);
+
+/** Retrieve start character from text.
+ @param text Text to obtain character from.
+ @param enc Text encoding.
+ @return Start character on success, 0UL on error.
+*/
+dk3_c32_t
+hbtool_get_start_char(dkChar const *text, int enc);
+
+/** Enumerate section and subsections.
+ @param job Job structure.
+*/
+void
+hbtool_enumerate(hb_job_t *job);
+
+/** Write hiearchical header number.
+ @param job Job structure.
+ @param nptr Node to write header for.
+ @return 1 if number was written, 0 otherwise.
+*/
+int
+hbtool_write_header_number(hb_job_t *job, hb_node_t *nptr);
+
+/** Write all titles, separated by arrows.
+ For the primary node we write the full header, for parent
+ nodes the short header.
+ @param job Job structure.
+ @param nptr Current node to write title for.
+ @param isprim Flag: Is primary node.
+*/
+int
+hbtool_write_all_titles(hb_job_t *job, hb_node_t *nptr, int isprim);
+
+/** Correct backslashes to slash on Windows systems.
+ @param str String to correct.
+*/
+void
+hbtool_correct_backslash_to_slash(dkChar *str);
+
+/** Write text (file name) UTF-8 encoded to jobs output file.
+ @param job Job structure.
+ @param src String to write.
+ @return 1 on success, 0 on error.
+*/
+int
+hbtool_write_text_utf(hb_job_t *job, dkChar const *src);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+
+#include "dk3all.h"
+#include "dk3se.h"
+#include "htmlbook.h"
+
+
+
+$!trace-include
+
+
+
+int
+hbtool_add_file(hb_job_t *job, dkChar const *fn)
+{
+ dkChar bu[DK3_MAX_PATH]; /* File name buffer */
+ dkChar *p1; /* Start of file name */
+ int back = 0;
+ $? "+ hbtool_add_file \"%!ds\"", TR_STR(fn)
+ if(fn) {
+ if(dk3str_len(fn) < DK3_SIZEOF(bu,dkChar)) {
+ p1 = dk3str_start(fn, NULL);
+ if(p1) {
+ dk3str_cpy(bu, p1);
+ dk3str_chomp(bu, NULL);
+ if(dk3sto_it_find_like(job->i_files, bu, 0)) {
+ back = 1;
+ } else {
+ p1 = dk3str_dup_app(bu, job->app);
+ if(p1) {
+ if(dk3sto_add(job->s_files, p1)) {
+ back = 1;
+ } else {
+ dk3_delete(p1);
+ }
+ }
+ }
+ }
+ } else {
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 65, 66, fn);
+ }
+ } $? "- hbtool_add_file %d", back
+ return back;
+}
+
+
+
+int
+hbtool_check_filename_encoding(hb_job_t *job, dkChar const *fn)
+{
+ int back;
+ int se; /* Standard encoding to check */
+ $? "+ hbtool_check_filename_encoding \"%!ds\"", TR_STR(fn)
+#if DK3_ON_WINDOWS
+ se = (DK3SE_ANSI | DK3SE_URL);
+#else
+ if((job->options) & HB_JOB_OPT_CHM) {
+ se = (DK3SE_ANSI | DK3SE_URL);
+ } else {
+ se = DK3SE_URL;
+ }
+#endif
+ back = dk3se_check(fn,dk3app_get_encoding(job->app),se,NULL,NULL,job->app);
+ $? "- hbtool_check_filename_encoding %d", back
+ return back;
+}
+
+
+
+int
+hbtool_check_filename(hb_job_t *job, dkChar const *fn)
+{
+ int back;
+ $? "+ hbtool_check_filename \"%!ds\"", TR_STR(fn)
+ back = hbtool_check_filename_encoding(job, fn);
+ if(dk3str_chr(fn, DK3_CHAR_SEP)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 12);
+ back = 0;
+ } $? "- hbtool_check_filename %d", back
+ return back;
+}
+
+
+
+
+dk3_c32_t
+hbtool_get_start_char(dkChar const *text, int enc)
+{
+ dk3_c32_t back = 0UL;
+ dk3_c32_t c32 = 0UL; /* Start character */
+ size_t sl; /* String length */
+ size_t used; /* Number of bytes used */
+#if DK3_CHAR_SIZE <= 1
+ char c; /* Result character */
+#endif
+ $? "+ hbtool_get_start_char"
+ if(text) {
+ sl = dk3str_len(text);
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ back = *text;
+#else
+ used = 0;
+ if(dk3enc_utf162uc(&c32, text, sl, &used)) {
+ back = c32;
+ }
+#endif
+#else
+ if(enc == DK3_ENCODING_UTF8) {
+ used = 0;
+ if(dk3enc_utf82uc(&c32, (unsigned char const *)text, sl, &used)) {
+ back = c32;
+ }
+ } else {
+ c = *text;
+ back = (dk3_c32_t)c;
+ back &= ((dk3_c32_t)0x000000FFUL);
+ }
+#endif
+ } $? "- hbtool_get_start_char 0x%lx %lu", (unsigned long)back, (unsigned long)back
+ return back;
+}
+
+
+
+void
+hbtool_enumerate(hb_job_t *job)
+{
+ hb_node_t *nptr; /* Next node */
+ hb_node_t *cptr; /* Current node */
+ dk3sto_it_reset(job->i_nodes);
+ while(NULL != (nptr = (hb_node_t *)dk3sto_it_next(job->i_nodes))) {
+ nptr->headno = 0UL; nptr->nextsubheadno = 0UL;
+ nptr->tocstate = HB_TOC_STATE_INIT;
+ }
+ cptr = job->rootnode;
+ while(cptr) {
+ switch(cptr->tocstate) {
+ case HB_TOC_STATE_INIT: {
+ dk3sto_it_reset(cptr->i_subnodes);
+ nptr = (hb_node_t *)dk3sto_it_next(cptr->i_subnodes);
+ if(nptr) {
+ cptr->tocstate = HB_TOC_STATE_IN_PROGRESS;
+ nptr->headno = cptr->nextsubheadno;
+ cptr->nextsubheadno += 1UL;
+ cptr = nptr;
+ } else {
+ cptr->tocstate = HB_TOC_STATE_FINISHED;
+ cptr = cptr->parent;
+ }
+ } break;
+ case HB_TOC_STATE_IN_PROGRESS: {
+ nptr = (hb_node_t *)dk3sto_it_next(cptr->i_subnodes);
+ if(nptr) {
+ nptr->headno = cptr->nextsubheadno;
+ cptr->nextsubheadno += 1UL;
+ cptr = nptr;
+ } else {
+ cptr->tocstate = HB_TOC_STATE_FINISHED;
+ cptr = cptr->parent;
+ }
+ } break;
+ case HB_TOC_STATE_FINISHED: {
+ cptr = cptr->parent;
+ } break;
+ }
+ }
+ dk3sto_it_reset(job->i_nodes);
+ while(NULL != (nptr = (hb_node_t *)dk3sto_it_next(job->i_nodes))) {
+ nptr->tocstate = HB_TOC_STATE_INIT;
+ }
+}
+
+
+
+int
+hbtool_write_header_number(hb_job_t *job, hb_node_t *nptr)
+{
+ dkChar bu[32];
+ int back = 0;
+ $? "+ hbtool_write_header_number"
+ if((job) && (nptr)) {
+ if(nptr->parent) { $? ". have parent"
+ if(nptr->depth <= job->headlevels) { $? ". within limit"
+ back = 1;
+ if(job->impressumnode) {
+ if((job->impressumnode)->objno == nptr->objno) {
+ back = 0; $? ". this is impressum"
+ }
+ }
+ if(back) { $? ". ok to write number"
+ hbtool_write_header_number(job, nptr->parent);
+ if(1 < nptr->depth) { $? ". write dot"
+ hbhtml_output_for_text(job, dkT("."));
+ }
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(bu, dkT("%lu"), (1UL + nptr->headno));
+ hbhtml_output_for_text(job, bu); $? ". number written"
+#else
+ if (dk3ma_um_to_string(bu, DK3_SIZEOF(bu,dkChar), (dk3_um_t)(1UL + nptr->headno))) {
+ hbhtml_output_for_text(job, bu);
+ }
+#endif
+ } else { $? ". do not write number"
+ }
+ } else { $? ". not in limit"
+ }
+ } else { $? ". no parent"
+ }
+ } $? "- hbtool_write_header_number %d", back
+ return back;
+}
+
+
+
+int
+hbtool_add_url(hb_job_t *job, dkChar const *url)
+{
+ dkChar bu[DK3_MAX_PATH]; /* Copy of URL */
+ dkChar *p1; /* Start of text in url */
+ int back = 1;
+ if(!hbhtml_check_link_for_external(url)) {
+ if(dk3str_len(url) < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy(bu, url);
+ p1 = dk3str_chr(bu, dkT('?'));
+ if(p1) {
+ *p1 = dkT('\0');
+ } else {
+ p1 = dk3str_chr(bu, dkT('#'));
+ if(p1) {
+ *p1 = dkT('\0');
+ }
+ }
+ if(NULL == dk3str_chr(bu, dkT('/'))) {
+ if(0 < dk3str_len(bu)) {
+ back = hbtool_add_file(job, bu);
+ }
+ }
+ } else {
+ /* ERROR: File name too long! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 65, 66, url);
+ back = 0;
+ }
+ }
+ return back;
+}
+
+
+
+void
+hbtool_correct_backslash_to_slash(dkChar *str)
+{
+#if DK3_ON_WINDOWS
+ dkChar *ptr;
+ ptr = str;
+ while(*ptr) {
+ if(dkT('\\') == *ptr) { *ptr = dkT('/'); }
+ ptr++;
+ }
+#endif
+}
+
+
+
+int
+hbtool_write_all_titles(hb_job_t *job, hb_node_t *nptr, int isprim)
+{
+ int back = 0;
+ /* hbhtml_output_for_text(job, dkT(" ")); */
+ if ((job) && (nptr)) {
+ if (nptr->parent) {
+ back = 1;
+ if (job->impressumnode) {
+ if ((job->impressumnode)->objno == nptr->objno) {
+ back = 0;
+ }
+ }
+ if (back) {
+ if (hbtool_write_all_titles(job, nptr->parent, 0)) {
+ hbhtml_output_for_text(job, dkT(" &#8594; "));
+ }
+ if (isprim) {
+ if (nptr->title) {
+ hbhtml_output_for_text(job, nptr->title);
+ }
+ } else {
+ if (nptr->shorttitle) {
+ hbhtml_output_for_text(job, nptr->shorttitle);
+ } else {
+ if (nptr->title) {
+ hbhtml_output_for_text(job, nptr->title);
+ }
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+hbtool_write_text_utf(hb_job_t *job, dkChar const *src)
+{
+ char bu[(1024 < DK3_MAX_PATH) ? DK3_MAX_PATH : 1024];
+ int back = 0;
+ int ie;
+ if ((job) && (src)) {
+ ie = dk3app_get_encoding(job->app);
+ if (dk3str_to_c8u_app(bu, sizeof(bu), src, ie, job->app)) {
+ if (EOF != fputs(bu, job->of)) {
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/hbtool.h b/support/dktools/hbtool.h
new file mode 100644
index 0000000000..7af06cca45
--- /dev/null
+++ b/support/dktools/hbtool.h
@@ -0,0 +1,148 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: hbtool.ctr
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file hbtool.h Header file for the hbtool module.
+*/
+
+#ifndef HBTOOL_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define HBTOOL_H_INCLUDED 1
+
+
+#line 10 "hbtool.ctr"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Add one file name to the list of files to copy.
+ @param job Job structure.
+ @param fn File name.
+ @return 1 on success, 0 on error.
+*/
+int
+hbtool_add_file(hb_job_t *job, dkChar const *fn);
+
+/** Add one file (probably with CGI arguments) to list of files to copy.
+ The URL is only added if it references a local file name
+ in the current working directory without any protocol
+ specification, (src="filename.png"). For all other URLs we skip
+ adding and return 1.
+ @param job Job structure.
+ @param url URL as specified.
+ @return 1 on success, 0 on error.
+*/
+int
+hbtool_add_url(hb_job_t *job, dkChar const *url);
+
+/** Check file name. The file must be specified without a path.
+ The file name must be encodable as URL
+ so it must be in range 0x00000000 to 0x000000FF.
+ For Windows systems the file name must be encodable as ANSI,
+ so the following codes are excluded from the range above:
+ 0x80 to 0x8C, 0x8E, 0x91 to 0x9C, 0x9E to 0x9F.
+ @param job Job structure.
+ @param fn File name.
+ @return 1 on success, 0 on error.
+*/
+int
+hbtool_check_filename(hb_job_t *job, dkChar const *fn);
+
+/** Check file name encoding.
+ The file name must be encodable as URL
+ so it must be in range 0x00000000 to 0x000000FF.
+ For Windows systems the file name must be encodable as ANSI,
+ so the following codes are excluded from the range above:
+ 0x80 to 0x8C, 0x8E, 0x91 to 0x9C, 0x9E to 0x9F.
+ @param job Job structure.
+ @param fn File name.
+ @return 1 on success, 0 on error.
+*/
+int
+hbtool_check_filename_encoding(hb_job_t *job, dkChar const *fn);
+
+/** Retrieve start character from text.
+ @param text Text to obtain character from.
+ @param enc Text encoding.
+ @return Start character on success, 0UL on error.
+*/
+dk3_c32_t
+hbtool_get_start_char(dkChar const *text, int enc);
+
+/** Enumerate section and subsections.
+ @param job Job structure.
+*/
+void
+hbtool_enumerate(hb_job_t *job);
+
+/** Write hiearchical header number.
+ @param job Job structure.
+ @param nptr Node to write header for.
+ @return 1 if number was written, 0 otherwise.
+*/
+int
+hbtool_write_header_number(hb_job_t *job, hb_node_t *nptr);
+
+/** Write all titles, separated by arrows.
+ For the primary node we write the full header, for parent
+ nodes the short header.
+ @param job Job structure.
+ @param nptr Current node to write title for.
+ @param isprim Flag: Is primary node.
+*/
+int
+hbtool_write_all_titles(hb_job_t *job, hb_node_t *nptr, int isprim);
+
+/** Correct backslashes to slash on Windows systems.
+ @param str String to correct.
+*/
+void
+hbtool_correct_backslash_to_slash(dkChar *str);
+
+/** Write text (file name) UTF-8 encoded to jobs output file.
+ @param job Job structure.
+ @param src String to write.
+ @return 1 on success, 0 on error.
+*/
+int
+hbtool_write_text_utf(hb_job_t *job, dkChar const *src);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/help-chm/de/winprint.chm b/support/dktools/help-chm/de/winprint.chm
new file mode 100644
index 0000000000..ffbbdb8423
--- /dev/null
+++ b/support/dktools/help-chm/de/winprint.chm
Binary files differ
diff --git a/support/dktools/help-chm/de/wxbmpp.chm b/support/dktools/help-chm/de/wxbmpp.chm
new file mode 100644
index 0000000000..b0050bd25a
--- /dev/null
+++ b/support/dktools/help-chm/de/wxbmpp.chm
Binary files differ
diff --git a/support/dktools/help-chm/de/wxdkclock.chm b/support/dktools/help-chm/de/wxdkclock.chm
new file mode 100644
index 0000000000..dce4e4f3be
--- /dev/null
+++ b/support/dktools/help-chm/de/wxdkclock.chm
Binary files differ
diff --git a/support/dktools/help-chm/de/wxdkct.chm b/support/dktools/help-chm/de/wxdkct.chm
new file mode 100644
index 0000000000..bc853157b4
--- /dev/null
+++ b/support/dktools/help-chm/de/wxdkct.chm
Binary files differ
diff --git a/support/dktools/help-chm/de/wxdkfcs.chm b/support/dktools/help-chm/de/wxdkfcs.chm
new file mode 100644
index 0000000000..746db278b0
--- /dev/null
+++ b/support/dktools/help-chm/de/wxdkfcs.chm
Binary files differ
diff --git a/support/dktools/help-chm/de/wxdkscrsz.chm b/support/dktools/help-chm/de/wxdkscrsz.chm
new file mode 100644
index 0000000000..6a832134d2
--- /dev/null
+++ b/support/dktools/help-chm/de/wxdkscrsz.chm
Binary files differ
diff --git a/support/dktools/help-chm/de/wximgsz.chm b/support/dktools/help-chm/de/wximgsz.chm
new file mode 100644
index 0000000000..fa98b4558e
--- /dev/null
+++ b/support/dktools/help-chm/de/wximgsz.chm
Binary files differ
diff --git a/support/dktools/help-chm/de/wxpqdic.chm b/support/dktools/help-chm/de/wxpqdic.chm
new file mode 100644
index 0000000000..c90d3337c2
--- /dev/null
+++ b/support/dktools/help-chm/de/wxpqdic.chm
Binary files differ
diff --git a/support/dktools/help-chm/en/winprint.chm b/support/dktools/help-chm/en/winprint.chm
new file mode 100644
index 0000000000..beaba050cd
--- /dev/null
+++ b/support/dktools/help-chm/en/winprint.chm
Binary files differ
diff --git a/support/dktools/help-chm/en/wxbmpp.chm b/support/dktools/help-chm/en/wxbmpp.chm
new file mode 100644
index 0000000000..441268c05e
--- /dev/null
+++ b/support/dktools/help-chm/en/wxbmpp.chm
Binary files differ
diff --git a/support/dktools/help-chm/en/wxdkclock.chm b/support/dktools/help-chm/en/wxdkclock.chm
new file mode 100644
index 0000000000..be3faffd2a
--- /dev/null
+++ b/support/dktools/help-chm/en/wxdkclock.chm
Binary files differ
diff --git a/support/dktools/help-chm/en/wxdkct.chm b/support/dktools/help-chm/en/wxdkct.chm
new file mode 100644
index 0000000000..b2211a8424
--- /dev/null
+++ b/support/dktools/help-chm/en/wxdkct.chm
Binary files differ
diff --git a/support/dktools/help-chm/en/wxdkfcs.chm b/support/dktools/help-chm/en/wxdkfcs.chm
new file mode 100644
index 0000000000..f4036439f0
--- /dev/null
+++ b/support/dktools/help-chm/en/wxdkfcs.chm
Binary files differ
diff --git a/support/dktools/help-chm/en/wxdkscrsz.chm b/support/dktools/help-chm/en/wxdkscrsz.chm
new file mode 100644
index 0000000000..5e9e3ffa65
--- /dev/null
+++ b/support/dktools/help-chm/en/wxdkscrsz.chm
Binary files differ
diff --git a/support/dktools/help-chm/en/wximgsz.chm b/support/dktools/help-chm/en/wximgsz.chm
new file mode 100644
index 0000000000..22aa060463
--- /dev/null
+++ b/support/dktools/help-chm/en/wximgsz.chm
Binary files differ
diff --git a/support/dktools/help-chm/en/wxpqdic.chm b/support/dktools/help-chm/en/wxpqdic.chm
new file mode 100644
index 0000000000..8ddca100c9
--- /dev/null
+++ b/support/dktools/help-chm/en/wxpqdic.chm
Binary files differ
diff --git a/support/dktools/help-htb/de/winprint.htb b/support/dktools/help-htb/de/winprint.htb
new file mode 100644
index 0000000000..9fb4017e3c
--- /dev/null
+++ b/support/dktools/help-htb/de/winprint.htb
Binary files differ
diff --git a/support/dktools/help-htb/de/wxbmpp.htb b/support/dktools/help-htb/de/wxbmpp.htb
new file mode 100644
index 0000000000..0af8775fb1
--- /dev/null
+++ b/support/dktools/help-htb/de/wxbmpp.htb
Binary files differ
diff --git a/support/dktools/help-htb/de/wxdkclock.htb b/support/dktools/help-htb/de/wxdkclock.htb
new file mode 100644
index 0000000000..aba3995a2b
--- /dev/null
+++ b/support/dktools/help-htb/de/wxdkclock.htb
Binary files differ
diff --git a/support/dktools/help-htb/de/wxdkct.htb b/support/dktools/help-htb/de/wxdkct.htb
new file mode 100644
index 0000000000..3c22d5e6f1
--- /dev/null
+++ b/support/dktools/help-htb/de/wxdkct.htb
Binary files differ
diff --git a/support/dktools/help-htb/de/wxdkfcs.htb b/support/dktools/help-htb/de/wxdkfcs.htb
new file mode 100644
index 0000000000..80d3e3affc
--- /dev/null
+++ b/support/dktools/help-htb/de/wxdkfcs.htb
Binary files differ
diff --git a/support/dktools/help-htb/de/wxdkscrsz.htb b/support/dktools/help-htb/de/wxdkscrsz.htb
new file mode 100644
index 0000000000..e9cf75cba6
--- /dev/null
+++ b/support/dktools/help-htb/de/wxdkscrsz.htb
Binary files differ
diff --git a/support/dktools/help-htb/de/wximgsz.htb b/support/dktools/help-htb/de/wximgsz.htb
new file mode 100644
index 0000000000..3921ac61cc
--- /dev/null
+++ b/support/dktools/help-htb/de/wximgsz.htb
Binary files differ
diff --git a/support/dktools/help-htb/de/wxpqdic.htb b/support/dktools/help-htb/de/wxpqdic.htb
new file mode 100644
index 0000000000..47a4af7781
--- /dev/null
+++ b/support/dktools/help-htb/de/wxpqdic.htb
Binary files differ
diff --git a/support/dktools/help-htb/en/winprint.htb b/support/dktools/help-htb/en/winprint.htb
new file mode 100644
index 0000000000..e60be08e16
--- /dev/null
+++ b/support/dktools/help-htb/en/winprint.htb
Binary files differ
diff --git a/support/dktools/help-htb/en/wxbmpp.htb b/support/dktools/help-htb/en/wxbmpp.htb
new file mode 100644
index 0000000000..f4918152a1
--- /dev/null
+++ b/support/dktools/help-htb/en/wxbmpp.htb
Binary files differ
diff --git a/support/dktools/help-htb/en/wxdkclock.htb b/support/dktools/help-htb/en/wxdkclock.htb
new file mode 100644
index 0000000000..2c16df212b
--- /dev/null
+++ b/support/dktools/help-htb/en/wxdkclock.htb
Binary files differ
diff --git a/support/dktools/help-htb/en/wxdkct.htb b/support/dktools/help-htb/en/wxdkct.htb
new file mode 100644
index 0000000000..740652af70
--- /dev/null
+++ b/support/dktools/help-htb/en/wxdkct.htb
Binary files differ
diff --git a/support/dktools/help-htb/en/wxdkfcs.htb b/support/dktools/help-htb/en/wxdkfcs.htb
new file mode 100644
index 0000000000..169201bcd9
--- /dev/null
+++ b/support/dktools/help-htb/en/wxdkfcs.htb
Binary files differ
diff --git a/support/dktools/help-htb/en/wxdkscrsz.htb b/support/dktools/help-htb/en/wxdkscrsz.htb
new file mode 100644
index 0000000000..c43e0addfc
--- /dev/null
+++ b/support/dktools/help-htb/en/wxdkscrsz.htb
Binary files differ
diff --git a/support/dktools/help-htb/en/wximgsz.htb b/support/dktools/help-htb/en/wximgsz.htb
new file mode 100644
index 0000000000..79cec3c0c2
--- /dev/null
+++ b/support/dktools/help-htb/en/wximgsz.htb
Binary files differ
diff --git a/support/dktools/help-htb/en/wxpqdic.htb b/support/dktools/help-htb/en/wxpqdic.htb
new file mode 100644
index 0000000000..40c87c2350
--- /dev/null
+++ b/support/dktools/help-htb/en/wxpqdic.htb
Binary files differ
diff --git a/support/dktools/htmlbook.c b/support/dktools/htmlbook.c
new file mode 100644
index 0000000000..4cd27ad7d3
--- /dev/null
+++ b/support/dktools/htmlbook.c
@@ -0,0 +1,2699 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: htmlbook.ctr
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file htmlbook.c The htmlbook module.
+*/
+
+
+#line 372 "htmlbook.ctr"
+
+#include "dk3all.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4vers.h"
+#include "htmlbook.h"
+
+
+/* Synopsis:
+ htmlbook -h | --help
+ htmlbook -v | --version
+ htmlbook -L | --license
+ htmlbook [<options>] <project>
+
+ Options:
+*/
+
+
+
+
+#line 392 "htmlbook.ctr"
+
+
+
+/** @defgroup hbcmd Commands for htmlbook. */
+/**@{*/
+/** Print help.
+*/
+#define HB_CMD_HELP 1
+/** Print version number.
+*/
+#define HB_CMD_VERSION 2
+/** Print license terms.
+*/
+#define HB_CMD_LICENSE 4
+/**@}*/
+
+
+
+/** Version information.
+*/
+static dkChar const *hb_version[] = {
+ dkT("htmlbook "),
+ DKT_VERSION_DK
+};
+
+
+
+/** License conditions.
+*/
+static dkChar const * const hb_license[] = {
+dkT(""),
+dkT("Copyright (c) 2013-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms,"),
+dkT("with or without modification, are permitted provided"),
+dkT("that the following conditions are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above"),
+dkT(" copyright notice, this list of conditions and the"),
+dkT(" following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above "),
+dkT(" copyright notice, this list of conditions and the following"),
+dkT(" disclaimer in the documentation and/or other materials"),
+dkT(" provided with the distribution."),
+dkT("* Neither the name of the copyright holder(s) nor the names of"),
+dkT(" contributors may be used to endorse or promote"),
+dkT(" products derived from this software without specific"),
+dkT(" prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\""),
+dkT("AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED."),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES"),
+dkT("(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR"),
+dkT("SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER"),
+dkT("CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,"),
+dkT("STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN"),
+dkT("ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE"),
+dkT("POSSIBILITY OF SUCH DAMAGE."),
+dkT(""),
+NULL
+
+
+#line 457 "htmlbook.ctr"
+};
+
+
+
+/** Help text shown if help file is not found.
+*/
+static dkChar const * const hb_help_text[] = {
+dkT(""),
+dkT("NAME"),
+dkT(""),
+dkT("htmlbook - Create HTML book structure"),
+dkT(""),
+dkT("SYNOPSIS"),
+dkT(""),
+dkT(" htmlbook [<option>] <file>"),
+dkT(" htmlbook -h"),
+dkT(" htmlbook -v"),
+dkT(" htmlbook -L"),
+dkT(""),
+dkT("DESCRIPTION"),
+dkT(""),
+dkT("The program creates a HTML book structure in a specified output directory."),
+dkT("Configuration is read from a project file specified on the command line."),
+dkT(""),
+dkT("OPTIONS"),
+dkT(""),
+dkT("-i <encoding> | --input-encoding=<encoding>"),
+dkT("\t\tInput encoding for project file to process."),
+dkT(""),
+dkT("-o name[,name...]"),
+dkT("\t\tActivate optional project file sections."),
+dkT(""),
+dkT("-s name=value | --set=name=value"),
+dkT("\t\tSet variables (overwrite variables from options section)."),
+dkT(""),
+dkT("-h | --help"),
+dkT("\t\tShow help text."),
+dkT(""),
+dkT("-v | --version"),
+dkT("\t\tShow version information."),
+dkT(""),
+dkT("-L | --license"),
+dkT("\t\tShow license terms."),
+dkT(""),
+dkT("EXIT STATUS"),
+dkT(""),
+dkT("0 on success, all other exit status codes indicate an error."),
+dkT(""),
+dkT("FILES"),
+dkT(""),
+dkT("The project file contains project settings and information about the"),
+dkT("document structure (text files and used template files)."),
+dkT(""),
+dkT("Project file"),
+dkT("------------"),
+dkT("A project file consists of three sections: ``[options]'', ``[files]'', and"),
+dkT("``[contents]''. A project file can contain optional sections"),
+dkT("``[options:<name>]'', ``[files:<name>]'', and ``[contents:<name>]''. Optional"),
+dkT("sections are only processed when activated by the -o command line option."),
+dkT("On Windows systems optional sections named ``windows'' are activated"),
+dkT("automatically, on non-Windows systems sections named ``non-windows'' are"),
+dkT("activated automatically."),
+dkT(""),
+dkT("The options section contains ``key=value'' lines for the following keys:"),
+dkT(""),
+dkT(" output directory\t\tName of output directory. This directory is"),
+dkT(" \t\t\t\tremoved completely and created again each"),
+dkT("\t\t\t\ttime the output script is run."),
+dkT(""),
+dkT(" output script\t\t\tScript to re-create the output directory and"),
+dkT(" \t\t\t\tcopy files into it."),
+dkT(""),
+dkT(" title\t\t\t\tDocument or collection title."),
+dkT(""),
+dkT(" url\t\t\t\tURL to access the document collection via web."),
+dkT(""),
+dkT(" index file\t\t\tName of file containing text for start page."),
+dkT(""),
+dkT(" html charset\t\t\tCharacter set for output HTML files"),
+dkT("\t\t\t\t(``us-ascii'', ``ascii'', or ``utf-8'')."),
+dkT(""),
+dkT(" template\t\t\tName of default template file (``web.hbt'')."),
+dkT(""),
+dkT(" style\t\t\t\tName of default style file (``style.css'')."),
+dkT(""),
+dkT(" page toc\t\t\tFlag: Create an intra-page table of contents."),
+dkT(""),
+dkT(" create toc\t\t\tFlag: Create table of contents."),
+dkT(""),
+dkT(" create index\t\t\tFlag: Create keyword index."),
+dkT(""),
+dkT(" section numbers in index\tFlag: Write section numbers in index."),
+dkT(""),
+dkT(" replace ampersand\t\tFlag: Replace ampersand in texts (no)."),
+dkT(""),
+dkT(" tidy\t\t\t\tFlag: Use tidy for inspection and correction"),
+dkT("\t\t\t\tof HTML output files."),
+dkT(""),
+dkT(" ln\t\t\t\tFlag: Use ln command instead of cp to save"),
+dkT("\t\t\t\tdisk space."),
+dkT(""),
+dkT(" author\t\t\tAuthor name."),
+dkT(""),
+dkT(" location\t\t\tLocation of author."),
+dkT(""),
+dkT(" write position\t\tFlag: Write position within the collection at"),
+dkT(" \t\t\t\tstart of page."),
+dkT(""),
+dkT(" section numbers in position\tFlag: Write section number in position."),
+dkT(""),
+dkT(" shortcut icon\t\t\tURL to shortcut icon."),
+dkT(""),
+dkT(" icon toc\t\t\tFile names for icons in navigation bar."),
+dkT(" icon previous"),
+dkT(" icon next"),
+dkT(" icon index"),
+dkT(""),
+dkT(" impressum link\t\tURL to impressum."),
+dkT(""),
+dkT(" impressum page\t\tName of text file for impressum (you can use"),
+dkT("\t\t\t\teither impressum link or impressum page)."),
+dkT(""),
+dkT(" chm\t\t\t\tFlag: Create HTML to produce a CHM file later."),
+dkT(""),
+dkT(" chm language\t\t\tLanguage setting for CHM project"),
+dkT(" \t\t\t\t(``0x409 English (USA)'')."),
+dkT(""),
+dkT(" js file\t\t\tFile name of JavaScript file."),
+dkT(""),
+dkT(" inherit js\t\t\tFlag: Inherit JavaScript files from parents."),
+dkT(""),
+dkT(" var\t\t\t\tSet variable (the first text word on the"),
+dkT("\t\t\t\tright side is the variable name, the"),
+dkT("\t\t\t\tremainder of the line is the variable value)."),
+dkT(""),
+dkT("The ``[files]'' section lists the name of additional files to copy,"),
+dkT("one per line."),
+dkT(""),
+dkT("The ``[contents]'' section contains the tree structure for navigation."),
+dkT("Each subsection for a node is started by a title line."),
+dkT("The indent level corresponds to the tree structure."),
+dkT("Title lines with same indent level are neighbours (sub-nodes of the same"),
+dkT("parent node). A nodes parent node is the next node above the node with"),
+dkT("smaller indent."),
+dkT("After the node title there are lines started by @ to configure the node:"),
+dkT(""),
+dkT(" file = <File>\t\t\tText file for the nodes contents."),
+dkT(" input encoding = <Encoding>\tDefault encoding to use if no BOM is found."),
+dkT(" suffix = <String>\t\tFile name suffix for output file."),
+dkT(" short = <Short title>\t\tShort title for use in the navigation menu."),
+dkT(""),
+dkT("Additionally you can use the ``html charset'', ``template'', ``style'',"),
+dkT("``page toc'', ``write position'', ``replace ampersand'', ``tidy'', ``ln'',"),
+dkT("``author'', ``location'', ``js file'', ``inherit js'', ``var'',"),
+dkT("``icon toc'', ``icon previous'', ``icon next'', ``icon index'', and"),
+dkT("``shortcut icon'' settings as shown for the options section."),
+dkT(""),
+dkT("Leafs (nodes without further subnodes) must have a text file configured,"),
+dkT("for other nodes it's optional."),
+dkT(""),
+dkT("Template file"),
+dkT("-------------"),
+dkT("The template file specifies the text between <BODY> and </BODY>."),
+dkT("Special commands %%command%% can be used to insert the text, the navigation"),
+dkT("menu, navigation blocks with clickable icons."),
+dkT("The following special commands are available:"),
+dkT(""),
+dkT(" %%contents%%\t\t\tInsert the text file contents."),
+dkT(""),
+dkT(" %%title%%\t\t\tInsert the node title."),
+dkT(""),
+dkT(" %%img <options>%%\t\tInsert an image. The following options"),
+dkT(" \t\t\t\tare available:"),
+dkT(" div[=bool]\t\t\tCreate <div> around <img>"),
+dkT(" centered[=bool]\t\tShow image centered, not left-aligned."),
+dkT(" src=file\t\t\tFile name for image."),
+dkT(" alt=\"text\"\t\t\tAlternative text for image."),
+dkT(" title[=\"text\"]\t\tTitle text (alt= is used as default)."),
+dkT(" caption[=\"text\"]\t\tImage caption."),
+dkT(" longdesc=URL\t\tFile containing long description of image."),
+dkT(" border=width\t\tBorder width."),
+dkT(" height=height\t\tImage height."),
+dkT(" width=width\t\t\tImage width."),
+dkT(" svg=file\t\t\tSVG version of image."),
+dkT(" svgwh[=bool]\t\tApply PNG/JPEG dimensions to SVG object."),
+dkT(" object[=bool]\t\tCreate object for SVG."),
+dkT(" pdf=file\t\t\tPDF version of image."),
+dkT(" larger=file\t\t\tLarger version of image."),
+dkT(" ismap[=bool]\t\tSet ismap attribute."),
+dkT(" usemap=file\t\t\tImage map file."),
+dkT(" name=name\t\t\tItem name."),
+dkT(" id=name\t\t\tID for CSS styling."),
+dkT(" class=name\t\t\tClass name for CSS styling."),
+dkT(" align=name\t\t\tAlignment."),
+dkT(" vspace=distance\t\tVertical space."),
+dkT(" hspace=distance\t\tHorizontal space."),
+dkT(" downloads[=bool]\t\tProvide links to download vector graphics"),
+dkT(" cache\t\t\tCache image dimensions for images used multiple"),
+dkT(" \t\t\t\ttimes. Image dimensions for images used in"),
+dkT("\t\t\t\ta template are cached automatically."),
+dkT(""),
+dkT(" %%menu <options>%%\t\tInsert the navigation menu."),
+dkT(" \t\t\t\tThe following options are available:"),
+dkT(" style=...\t\t\tOne from ``reverse'' (full menu in reverse"),
+dkT("\t\t\t\torder), ``full'' (full menu), ``top'' (show"),
+dkT("\t\t\t\tonly first hierarchy level) or ``current''"),
+dkT("\t\t\t\t(show only current hierarchy level)."),
+dkT(" sub[=bool]\t\t\tFlag: Show subnodes of current node."),
+dkT(""),
+dkT(" %%navigation <options>%%\tInsert a navigation block."),
+dkT(" \t\t\t\tThe following options are available:"),
+dkT(" itop=file\t\t\tIcon for table of contents (``toc.png'')."),
+dkT(" iprev=file\t\t\tIcon for previous section (``prev.png'')."),
+dkT(" inext=file\t\t\tIcon for next section (``next.png'')."),
+dkT(" ikind=file\t\t\tIcon for keyword index (``index.png'')."),
+dkT(""),
+dkT(" %%author%%\t\t\tInsert the author name."),
+dkT(""),
+dkT(" %%location%%\t\t\tInsert the authors location."),
+dkT(""),
+dkT(" %%date <options>%%\t\tInsert the current node."),
+dkT(" \t\t\t\tThe following options are available:"),
+dkT(" style=name\t\t\tDate style, currently only ``german'' is"),
+dkT("\t\t\t\tallowed to switch from the default"),
+dkT("\t\t\t\t``yyyy-mm-dd'' to ``dd.mm.yyyy''."),
+dkT(""),
+dkT(" %%var <name> <options>%%\tInsert a variable value."),
+dkT(" \t\t\t\tThe following options are available:"),
+dkT(" url[=bool]\t\t\tFlag: Encode as URL, not as text."),
+dkT(""),
+dkT(" %%code <options>%%\t\tOutput encoding. By default the"),
+dkT(" \t\t\t\t``<'', ``>'' are not replaced by ``&lt;'', and"),
+dkT("\t\t\t\t``&gt;'' as we expect to get correct HTML "),
+dkT("\t\t\t\tfrom the text files. Replacement of ``&''"),
+dkT("\t\t\t\tby ``&amp;'' is controlled by the"),
+dkT("\t\t\t\t``replace ampersand'' setting in the options"),
+dkT("\t\t\t\tsection."),
+dkT("\t\t\t\tIn code mode our text comes from a source"),
+dkT("\t\t\t\tcode file, so we have to encode these"),
+dkT("\t\t\t\tcharacters for HTML output."),
+dkT("\t\t\t\tThe following options are available:"),
+dkT(" enable[=bool]\t\tTurn code mode on."),
+dkT(" on[=bool]\t\t\tTurn code mode on."),
+dkT(" disable[=bool]\t\tTurn code mode off."),
+dkT(" off[=bool]\t\t\tTurn code mode off."),
+dkT(" toggle\t\t\tToggle code mode."),
+dkT(""),
+dkT(" %%a <options>%%\t\tInsert a named anchor or a hyperlink."),
+dkT(" \t\t\t\tThe following options are available:"),
+dkT(" name=name\t\t\tAnchor name."),
+dkT(" href=URL\t\t\tLink destination."),
+dkT(" title=``text''\t\tText to show when mouse is over link."),
+dkT(" text=``text''\t\tText for hyperlink."),
+dkT(" target=destination\t\tDestination windows or frame, i.e. ``_blank''."),
+dkT(" type=text\t\t\tMIME type."),
+dkT(" external[=bool]\t\tOverride result of internal/external test."),
+dkT(" id=text\t\t\tID for CSS styling."),
+dkT(" class=text\t\t\tClass name for CSS styling."),
+dkT(" style=text\t\t\tDirect style information."),
+dkT(" hreflang=text\t\tLanguage for href text."),
+dkT(" charset=text\t\tCharacter set."),
+dkT(" onblur=text\t\t\tScript to execute when link looses focus."),
+dkT(" onfocus=text\t\tScript to execute when link gets focus."),
+dkT(" accesskey=text\t\tHotkey for link."),
+dkT(" tabindex=number\t\tTabulator index."),
+dkT(" shape=text\t\t\tLink shape form."),
+dkT(" coords=text\t\t\tCoordinates."),
+dkT(" rel=text\t\t\tInformation for link to next element."),
+dkT(" rev=text\t\t\tInformation for link to previous element."),
+dkT(""),
+dkT(" %%menuentry <options>%%\tInsert code to visualize a menu entry."),
+dkT(" \t\t\t\tThe following options are available:"),
+dkT(" item=``text''\t\tText of the menu entry, can be used"),
+dkT(" \t\t\t\tmultiple times for hierarchical menus."),
+dkT(""),
+dkT(" %%sourcefile <options>%%\tShow a file contents in a <PRE></PRE>"),
+dkT(" \t\t\t\tenvironment and provide a download"),
+dkT("\t\t\t\thyperlink. The following options are available:"),
+dkT(" file=file\t\t\tFile name."),
+dkT(" type=text\t\t\tMIME type."),
+dkT(" title=``text''\t\tText shown when mouse is over hyperlink."),
+dkT(""),
+dkT("Text file"),
+dkT("---------"),
+dkT("Text files contain the page contents."),
+dkT("You can use headings like"),
+dkT(" .1\t@name@\tHeading text"),
+dkT("for a structural document. Depths 1, 2, 3, 4, or 5 are converted to"),
+dkT("<h2>...<h6> headers. A <h1> header is used for the page title."),
+dkT("The @name@ specification is optional, it results in a named anchor"),
+dkT(" <a name=\"name\"></a>"),
+dkT("before the heading. If the name specification is omitted, an anchor name"),
+dkT("is generated automatically."),
+dkT(""),
+dkT("Text files can use the special commands listed in ``Template file'', execpt"),
+dkT("%%contents%%. Additionally the following special command can be used"),
+dkT("in text files:"),
+dkT(""),
+dkT(" %%index <options>%%\t\tAdd an entry to the keyword index."),
+dkT(" \t\t\t\tThe following options can be used:"),
+dkT(" text=``text''\t\tKeyword."),
+dkT(" name=``text''\t\tName of a named anchor."),
+dkT(" reference[=bool]\t\tFlag: Use existing named anchor, do not"),
+dkT(" \t\t\t\tcreate an anchor."),
+dkT("NOTES"),
+dkT(""),
+dkT("All text files, style files and images must be local files"),
+dkT("in the current working directory."),
+dkT(""),
+dkT("AUTHOR"),
+dkT(""),
+dkT("Dirk krause"),
+dkT(""),
+dkT("COPYRIGHT AND LICENSE"),
+dkT(""),
+dkT("Run"),
+dkT(" htmlbook --license"),
+dkT("to see the license conditions."),
+dkT(""),
+dkT("SEE ALSO"),
+dkT(""),
+dkT("tidy"),
+dkT(""),
+NULL
+
+
+#line 782 "htmlbook.ctr"
+};
+
+
+
+/** 8-bit character keywords.
+*/
+static char const * const hb_c8_kw[] = {
+/* 0 */
+"\n",
+
+/* 1 */
+" ",
+
+/* 2 */
+"RD /S /Q \"",
+
+/* 3 */
+"\"\n",
+
+/* 4 */
+"rm -fr '",
+
+/* 5 */
+"'\n",
+
+/* 6 */
+"MKDIR \"",
+
+/* 7 */
+"mkdir -p '",
+
+/* 8 */
+"IF NOT EXIST \"",
+
+/* 9 */
+"\" ECHO ERROR File does not exist: ",
+
+/* 10 */
+"IF EXIST \"",
+
+/* 11 */
+"\" XCOPY \"",
+
+/* 12 */
+"\" \"",
+
+/* 13 */
+"\\\" /Y /Q\n",
+
+/* 14 */
+"if [ -f '",
+
+/* 15 */
+"' ]\n",
+
+/* 16 */
+"then\n",
+
+/* 17 */
+"else\n",
+
+/* 18 */
+"fi\n",
+
+/* 19 */
+"ln '",
+
+/* 20 */
+"cp '",
+
+/* 21 */
+"' '",
+
+/* 22 */
+"echo 'ERROR: File ",
+
+/* 23 */
+" does not exist'\n",
+
+/* 24 */
+"tidy -q -utf8 < \"",
+
+/* 25 */
+"tidy -q -ascii < \"",
+
+/* 26 */
+"\" > \"",
+
+/* 27 */
+"tidy -q -utf8 < '",
+
+/* 28 */
+"tidy -q -ascii < '",
+
+/* 29 */
+"' > '",
+
+/* 30 */
+"/",
+
+/* 31 */
+"@ECHO OFF\n",
+
+/* 32 */
+"#! /bin/sh\n",
+
+/* 33 */
+"EXITCODE=0\n",
+
+/* 34 */
+"exit $EXITCODE\n",
+
+/* 35 */
+"EXITCODE=1\n",
+
+/* 36 */
+"ECHO TIDY ",
+
+/* 37 */
+"echo TIDY ",
+
+/* 38 */
+"\" DEL /Q \"",
+
+/* 39 */
+"\"\n",
+
+/* 40 */
+"find '",
+
+/* 41 */
+"' -type d -exec chmod ugo+rx {} \\;\n",
+
+/* 42 */
+"' -type f -exec chmod ugo+r {} \\;\n",
+
+NULL
+
+
+#line 885 "htmlbook.ctr"
+};
+
+
+
+/** Fixed keywords (not localized).
+*/
+static dkChar const * const hb_kwnl[] = {
+/* 0 */
+dkT("dktools"),
+
+/* 1 */
+dkT("htmlbook.str"),
+
+/* 2 */
+dkT("htmlbook.txt"),
+
+/* 3 */
+dkT("htmlbook.conf"),
+
+/* 4 */
+dkT("toc.png"),
+
+/* 5 */
+dkT("prev.png"),
+
+/* 6 */
+dkT("next.png"),
+
+/* 7 */
+dkT("index.png"),
+
+/* 8 */
+dkT("index.html"),
+
+/* 9 */
+dkT("."),
+
+/* 10 */
+dkT("html"),
+
+/* 11 */
+dkT("german"),
+
+/* 12 */
+dkT("url"),
+
+/* 13 */
+dkT("#hb_index"),
+
+/* 14 */
+dkT("toc.png"),
+
+/* 15 */
+dkT("prev.png"),
+
+/* 16 */
+dkT("next.png"),
+
+/* 17 */
+dkT("index.png"),
+
+/* 18 */
+dkT("windows"),
+
+/* 19 */
+dkT("non-windows"),
+
+/* 20 */
+dkT("http://"),
+
+/* 21 */
+dkT("ftp://"),
+
+/* 22 */
+dkT("w"),
+
+/* 23 */
+dkT("html"),
+
+/* 24 */
+dkT("htm"),
+
+/* 25 */
+dkT("none"),
+
+/* 26 */
+dkT("project.hhp"),
+
+/* 27 */
+dkT("index.chm"),
+
+/* 28 */
+dkT("contents.hhc"),
+
+/* 29 */
+dkT("index.hhk"),
+
+/* 30 */
+dkT("wb"),
+
+/* 31 */
+dkT("#hb_toc"),
+
+/* 32 */
+dkT("set"),
+
+/* 33 */
+dkT("SVG"),
+
+/* 34 */
+dkT("PDF"),
+
+/* 35 */
+dkT(" "),
+
+/* 36 */
+dkT("project.xml"),
+
+/* 37 */
+dkT("home.png"),
+
+NULL
+
+
+#line 1025 "htmlbook.ctr"
+};
+
+
+
+/** Default message texts.
+*/
+static dkChar const * const hb_kw[] = {
+/* 0 */
+dkT("Impressum"),
+
+/* 1 */
+dkT("Go to start page: "),
+
+/* 2 */
+dkT("At start page."),
+
+/* 3 */
+dkT("Go to previous page: "),
+
+/* 4 */
+dkT("At first page."),
+
+/* 5 */
+dkT("Go to next page: "),
+
+/* 6 */
+dkT("At last page."),
+
+/* 7 */
+dkT("Go to keyword index."),
+
+/* 8 */
+dkT("Syntax error, missing \"=\"!"),
+
+/* 9 */
+dkT("Syntax error, empty value!"),
+
+/* 10 */
+dkT("Syntax error, setting only allowed in options section!"),
+
+/* 11 */
+dkT("Syntax error, illegal character set!\nOnly \"ascii\" or \"utf-8\" allowed."),
+
+/* 12 */
+dkT("Syntax error, no path specification in file name allowed!"),
+
+/* 13 */
+dkT("Missing project file name!"),
+
+/* 14 */
+dkT("Too many project file specified, just one allowed!"),
+
+/* 15 */
+dkT("No parent candidate found (probably a bug)!"),
+
+/* 16 */
+dkT("Syntax error, missing section name!"),
+
+/* 17 */
+dkT("Syntax error, missing closing square bracket!"),
+
+/* 18 */
+dkT("Syntax error, illegal section name!"),
+
+/* 19 */
+dkT("No template for node!"),
+
+/* 20 */
+dkT("Failed to obtain file name (probably a bug)!"),
+
+/* 21 */
+dkT("String \""),
+
+/* 22 */
+dkT("\" contains characters not usable in an URL!"),
+
+/* 23 */
+dkT("External links"),
+
+/* 24 */
+dkT("No source file specified!"),
+
+/* 25 */
+dkT("Syntax error, illegal menu style: \""),
+
+/* 26 */
+dkT("\"!"),
+
+/* 27 */
+dkT("Syntax error, illegal key (attribute name): \""),
+
+/* 28 */
+dkT("Syntax error, \"%%contents%%\" is only allowed in templates!"),
+
+/* 29 */
+dkT("Syntax error, illegal special command: \""),
+
+/* 30 */
+dkT("Syntax error, parsing special command failed near:\n\""),
+
+/* 31 */
+dkT("Line too long:\n\""),
+
+/* 32 */
+dkT("Syntax error, missing header text!"),
+
+/* 33 */
+dkT("Syntax error, missing closing ``@''!"),
+
+/* 34 */
+dkT("Syntax error, missing text after ``@''!"),
+
+/* 35 */
+dkT("Syntax error, missing header level!"),
+
+/* 36 */
+dkT("Syntax error, no text after leading ``.'' in line!"),
+
+/* 37 */
+dkT("Header level corrected to allowed maximum 6!"),
+
+/* 38 */
+dkT("Syntax error, ''url'' can be set in options section only!"),
+
+/* 39 */
+dkT("Failed to process a special command!"),
+
+/* 40 */
+dkT("Syntax error, parsing special command arguments failed!"),
+
+/* 41 */
+dkT("Syntax error, too many items for menu entry!"),
+
+/* 42 */
+dkT("Syntax error, no items for menu entry!"),
+
+/* 43 */
+dkT("Syntax error, illegal configuration key: \""),
+
+/* 44 */
+dkT("\"!"),
+
+/* 45 */
+dkT("Table of contents"),
+
+/* 46 */
+dkT("Keyword and key phrases index"),
+
+/* 47 */
+dkT("No default topic found!"),
+
+/* 48 */
+dkT("Missing ``text'' attribute!"),
+
+/* 49 */
+dkT("Missing ``file'' attribute!"),
+
+/* 50 */
+dkT("The ``index'' special command can not be used in template!"),
+
+/* 51 */
+dkT("No destination file for link found!"),
+
+/* 52 */
+dkT("No text node for title:\n\""),
+
+/* 53 */
+dkT("\"!"),
+
+/* 54 */
+dkT("Current position"),
+
+/* 55 */
+dkT("Page table of contents"),
+
+/* 56 */
+dkT("External links"),
+
+/* 57 */
+dkT("Table of contents"),
+
+/* 58 */
+dkT("Large"),
+
+/* 59 */
+dkT("Image"),
+
+/* 60 */
+dkT("Menu entry"),
+
+/* 61 */
+dkT("Impressum"),
+
+/* 62 */
+dkT("Unfinished ``%%'' command!"),
+
+/* 63 */
+dkT("Not a backslash escape sequence: ``"),
+
+/* 64 */
+dkT("''!"),
+
+/* 65 */
+dkT("Image"),
+
+/* 66 */
+dkT("Overwriting ``div'' option by ``table''!"),
+
+/* 67 */
+dkT("No output directory configured!"),
+
+/* 68 */
+dkT("No output script configured"),
+
+/* 69 */
+dkT("Overwriting previous setting for ``author''!"),
+
+/* 70 */
+dkT("Overwriting previous setting for ``title''!"),
+
+/* 71 */
+dkT("Overwriting previous setting for ``output directory''!"),
+
+/* 72 */
+dkT("Overwriting previous setting for ``output script''!"),
+
+/* 73 */
+dkT("Overwriting previous setting for ``template''!"),
+
+/* 74 */
+dkT("Overwriting previous setting for ``style''!"),
+
+/* 75 */
+dkT("Overwriting previous setting for ``short''!"),
+
+/* 76 */
+dkT("Overwriting previous setting for ``file''!"),
+
+/* 77 */
+dkT("Overwriting previous setting for ``suffix''!"),
+
+/* 78 */
+dkT("Overwriting previous setting for ``icon toc''!"),
+
+/* 79 */
+dkT("Overwriting previous setting for ``icon previous''!"),
+
+/* 80 */
+dkT("Overwriting previous setting for ``icon next''!"),
+
+/* 81 */
+dkT("Overwriting previous setting for ``icon index''!"),
+
+/* 82 */
+dkT("Overwriting previous setting for ``shortcut icon''!"),
+
+/* 83 */
+dkT("Overwriting previous setting for ``var''!"),
+
+/* 84 */
+dkT("File not found: \""),
+
+/* 85 */
+dkT("\"!"),
+
+/* 86 */
+dkT("Overwriting previous setting for ``file''!"),
+
+/* 87 */
+dkT("Start page"),
+
+/* 88 */
+dkT("Too many text lines, max. 999 allowed!"),
+
+/* 89 */
+dkT("Syntax error, ignoring unexpected %%hint%% key \""),
+
+/* 90 */
+dkT("\"!"),
+
+/* 91 */
+dkT("Syntax error, missing text for %%hint%%!"),
+
+/* 92 */
+dkT("Syntax error, missing title for %%hint%%!"),
+
+/* 93 */
+dkT("Go to table of contents: "),
+
+/* 94 */
+dkT("On start page."),
+
+/* 95 */
+dkT("Overwriting previous setting for ``icon home''!"),
+
+/* 96 */
+dkT("Syntax error, value required!"),
+
+/* 97 */
+dkT("Overwriting previous setting for ``meta description''!"),
+
+/* 98 */
+dkT("Overwriting previous setting for ``meta keywords''!"),
+
+/* 99 */
+dkT("Overwriting previous setting for ``location''!"),
+
+NULL
+
+
+#line 1347 "htmlbook.ctr"
+};
+
+
+
+/** Section names in project files.
+*/
+static dkChar const * const hb_section_names[] = {
+/* 0 */
+dkT("options"),
+
+/* 1 */
+dkT("files"),
+
+/* 2 */
+dkT("contents"),
+
+NULL
+
+
+#line 1359 "htmlbook.ctr"
+};
+
+
+
+/** Accepted program options.
+*/
+static dk3_option_t const hb_options[] = {
+ { dkT('h'), dkT("help"), 0 },
+ { dkT('v'), dkT("version"), 0 },
+ { dkT('L'), dkT("license"), 0 },
+ { dkT('o'), dkT("optional-sections"), 1 },
+ { dkT('i'), dkT("input-encoding"), 1 }
+};
+
+/** Number of elements in the hb_options array.
+*/
+static size_t const hb_sz_options = sizeof(hb_options)/sizeof(dk3_option_t);
+
+
+
+/** Initialize job structure.
+ @param job Job structure to initialize.
+ @param app Application structure.
+ @param msg Localized keywords.
+ @param kwnl Keywords not localized.
+*/
+static
+void
+hb_job_init(
+ hb_job_t *job,
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl
+)
+{
+
+
+#line 1395 "htmlbook.ctr"
+ job->app = app;
+ job->msg = msg;
+ job->kwnl = kwnl;
+ job->opt = NULL;
+ job->s_nodes = NULL;
+ job->i_nodes = NULL;
+ job->s_pnodes = NULL;
+ job->i_pnodes = NULL;
+ job->s_files = NULL;
+ job->i_files = NULL;
+ job->s_index = NULL;
+ job->i_index = NULL;
+ job->s_optsect = NULL;
+ job->i_optsect = NULL;
+ job->s_imgdim = NULL;
+ job->i_imgdim = NULL;
+ job->rootnode = NULL;
+ job->currentnode = NULL;
+ job->impressumnode = NULL;
+ job->firstnode = NULL;
+ job->lastnode = NULL;
+ job->infilename = NULL;
+ job->outputdir = NULL;
+ job->outputscript = NULL;
+ job->url = NULL;
+ job->indexfile = NULL;
+ job->impressumlink = NULL;
+ job->chmlang = NULL;
+ job->shipbuffer = NULL;
+ job->iltemplate = NULL;
+ job->ilfile = NULL;
+ job->special = NULL;
+ job->buffer32 = NULL;
+ job->of = NULL;
+ job->lineno = 0UL;
+ job->nextobj = 0UL;
+ job->npobjs = 0UL;
+ job->spused = 0;
+ job->shipused = 0;
+ job->options = HB_JOB_OPT_CREATE_TOC;
+ job->options |= HB_JOB_OPT_NUM_IN_POS;
+ job->options |= HB_JOB_OPT_NUM_IN_IDX;
+ job->options |= HB_JOB_OPT_NUM_IN_PAGE_HEADER;
+ job->options |= HB_JOB_OPT_CODE_LINE_NUMBERS;
+ job->actsect = 1;
+ job->iecmd = -1; /* No input encoding specified */
+ job->bs = 0;
+ job->cmd = 0;
+ job->exv = 1;
+
+#line 1444 "htmlbook.ctr"
+ job->cs = HB_CS_ASCII;
+ job->secttype = HB_SECTION_UNKNOWN;
+ job->non_url = 0;
+ job->maxdepth = 0;
+ job->coli = 0;
+ job->cols = HB_COLIST_NONE;
+#if DK3_SIZEOF_INT > 2
+#if Dk3_SIZEOF_INT > 4
+ job->headlevels = 9223372036854775807;
+#else
+ job->headlevels = 2147483647;
+#endif
+#else
+ job->headlevels = 32767;
+#endif
+
+
+#line 1460 "htmlbook.ctr"
+}
+
+
+
+/** Clean up job structure at end of program.
+ @param job Job structure to clean up.
+*/
+static
+void
+hb_job_end(hb_job_t *job)
+{
+ hb_img_dim_t *idptr; /* Current image dimension cache entry */
+ hb_index_entry_t *ie; /* Current index entry */
+ hb_node_t *cn; /* Current node */
+ dkChar *cfn; /* Current file name */
+
+
+#line 1476 "htmlbook.ctr"
+ /* Release options.
+ */
+ if(job->opt) {
+ dk3opt_close(job->opt); job->opt = NULL;
+ }
+
+ /* The s_nodes component contains a list of all nodes.
+ We traverse this container to release all nodes.
+ */
+ if(job->s_nodes) {
+ if(job->i_nodes) {
+ dk3sto_it_reset(job->i_nodes);
+ while(NULL != (cn = (hb_node_t *)dk3sto_it_next(job->i_nodes))) {
+ hb_node_delete(cn);
+ }
+ dk3sto_it_close(job->i_nodes); job->i_nodes = NULL;
+ }
+ dk3sto_close(job->s_nodes); job->s_nodes = NULL;
+ }
+
+ if(job->s_imgdim) {
+ if(job->i_imgdim) {
+ dk3sto_it_reset(job->i_imgdim);
+ while(NULL != (idptr = (hb_img_dim_t *)dk3sto_it_next(job->i_imgdim))) {
+ hbimgdim_delete(idptr);
+ }
+ dk3sto_it_close(job->i_imgdim);
+ }
+ dk3sto_close(job->s_imgdim);
+ } job->s_imgdim = NULL; job->i_imgdim = NULL;
+
+ if(job->s_optsect) {
+ if(job->i_optsect) {
+ dk3sto_it_reset(job->i_optsect);
+ while(NULL != (cfn = (dkChar *)dk3sto_it_next(job->i_optsect))) {
+
+
+#line 1512 "htmlbook.ctr"
+ dk3_release(cfn);
+ }
+ dk3sto_it_close(job->i_optsect);
+ }
+ dk3sto_close(job->s_optsect);
+ }
+ job->s_optsect = NULL; job->i_optsect = NULL;
+
+ if(job->s_index) {
+ if(job->i_index) {
+ dk3sto_it_reset(job->i_index);
+ while(NULL != (ie = (hb_index_entry_t *)dk3sto_it_next(job->i_index))) {
+ hbindex_delete(ie);
+ }
+ dk3sto_it_close(job->i_index);
+ }
+ dk3sto_close(job->s_index);
+ }
+ job->s_index = NULL; job->i_index = NULL;
+
+ /* We must free the list of additional files.
+ */
+ if(job->s_files) {
+ if(job->i_files) {
+ dk3sto_it_reset(job->i_files);
+ while(NULL != (cfn = (dkChar *)dk3sto_it_next(job->i_files))) {
+
+
+#line 1539 "htmlbook.ctr"
+ dk3_release(cfn);
+ }
+ dk3sto_it_close(job->i_files); job->i_files = NULL;
+ }
+ dk3sto_close(job->s_files); job->s_files = NULL;
+ }
+
+ /* The s_pnodes component contains a list of the leaf nodes
+ only (nodes to produce output for).
+ We already traversed s_nodes to release all the nodes, so
+ we can simply close s_pnodes and i_pnodes here.
+ */
+ if(job->s_pnodes) {
+ if(job->i_pnodes) {
+ dk3sto_it_close(job->i_pnodes);
+ }
+ dk3sto_close(job->s_pnodes); job->s_pnodes = NULL;
+ }
+
+ /* Release components allocated dynamically.
+ */
+ dk3_release(job->outputdir);
+ dk3_release(job->outputscript);
+ dk3_release(job->url);
+ dk3_release(job->impressumlink);
+ dk3_release(job->chmlang);
+ dk3_release(job->indexfile);
+ dk3_release(job->shipbuffer);
+ dk3_release(job->iltemplate);
+ dk3_release(job->ilfile);
+ dk3_release(job->special);
+ dk3_release(job->buffer32);
+
+ job->impressumnode = NULL;
+
+
+#line 1574 "htmlbook.ctr"
+}
+
+
+
+/** Save names of optional sections to process.
+ @param job Job structure.
+ @param sections Section names.
+ @return 1 on success, 0 on errors.
+*/
+static
+int
+hb_save_optional_sections(hb_job_t *job, dkChar const *sections)
+{
+ dkChar bu[1024]; /* Private copy of sections */
+ dkChar *p1; /* Current section name */
+ dkChar *p2; /* Next section name */
+ dkChar *p3; /* Copy of current section for storage */
+ int back = 0; /* Result */
+
+
+#line 1593 "htmlbook.ctr"
+ if((job) && (sections)) {
+ if(dk3str_len(sections) < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy(bu, sections);
+ back = 1;
+
+#line 1597 "htmlbook.ctr"
+ p1 = dk3str_start(bu, NULL);
+ while(p1) {
+ p2 = dk3str_chr(p1, dkT(','));
+ if(p2) {
+ *(p2++) = dkT('\0');
+ p2 = dk3str_start(p2, NULL);
+ }
+ dk3str_chomp(p1, NULL);
+
+
+#line 1606 "htmlbook.ctr"
+ p3 = dk3str_dup_app(p1, job->app);
+ if(p3) {
+ if(!dk3sto_add(job->s_optsect, p3)) {
+ dk3_release(p3);
+ back = 0; /* REPORTED */
+
+#line 1611 "htmlbook.ctr"
+ }
+ } else {
+ back = 0; /* REPORTED */
+
+#line 1614 "htmlbook.ctr"
+ }
+ p1 = p2;
+ }
+ } else {
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 135, 136, sections);
+ }
+ }
+
+#line 1621 "htmlbook.ctr"
+ return back;
+}
+
+
+
+/** Process command line options.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hb_process_options(hb_job_t *job)
+{
+ dkChar const *optarg; /* Option argument */
+ int back = 0;
+ job->opt = dk3opt_open_from_app(
+ hb_options, hb_sz_options, dkT('s'), hb_kwnl[32], job->app
+ );
+ if(job->opt) {
+ if(0 == dk3opt_get_error_code(job->opt)) {
+ back = 1;
+ if(dk3opt_is_set(job->opt, dkT('h'))) {
+ job->cmd |= HB_CMD_HELP;
+ }
+ if(dk3opt_is_set(job->opt, dkT('v'))) {
+ job->cmd |= HB_CMD_VERSION;
+ }
+ if(dk3opt_is_set(job->opt, dkT('L'))) {
+ job->cmd |= HB_CMD_LICENSE;
+ }
+ if(0 == (job->cmd)) {
+ if(dk3opt_is_set(job->opt, dkT('i'))) {
+ optarg = dk3opt_get_short_arg(job->opt, dkT('i'));
+ if(optarg) {
+ job->iecmd = dk3enc_get_text_encoding_app(optarg, job->app);
+ if(0 > job->iecmd) { job->iecmd = -1; }
+ }
+ }
+ if(1 > dk3opt_get_num_args(job->opt)) {
+
+#line 1660 "htmlbook.ctr"
+ /* ERROR: No project file specified! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 13);
+ back = 0;
+ } else {
+ if(1 < dk3opt_get_num_args(job->opt)) {
+
+#line 1665 "htmlbook.ctr"
+ /* WARNING: Too many project files, using just one! */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 14);
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Print help text, version information or license terms.
+ @param job Job structure.
+*/
+static
+void
+hb_help_version_license(hb_job_t *job)
+{
+ dkChar const * const *ptr; /* Current line to print */
+
+
+#line 1686 "htmlbook.ctr"
+ /* Show version
+ */
+ dk3sf_initialize_stdout();
+ dk3sf_fputs(hb_version[0], stdout);
+ dk3sf_fputs(hb_version[1], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+
+ if(HB_CMD_LICENSE & (job->cmd)) {
+ /* Show license
+ */
+ ptr = hb_license;
+ while(*ptr) {
+ dk3sf_fputs(*(ptr++), stdout); dk3sf_fputc(dkT('\n'), stdout);
+ }
+ }
+ if(HB_CMD_HELP & (job->cmd)) {
+ /* Show help
+ */
+ dk3app_help(job->app, hb_kwnl[2], hb_help_text);
+ }
+ job->exv = 0;
+
+#line 1707 "htmlbook.ctr"
+
+
+#line 1708 "htmlbook.ctr"
+}
+
+
+
+/** Compare two file names.
+ @param l Left pointer.
+ @param r Right pointer.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+static
+int
+hb_file_name_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+
+
+#line 1724 "htmlbook.ctr"
+ if(l) {
+ if(r) {
+ back = dk3str_fncmp((dkChar const *)l, (dkChar const *)r);
+ if(-1 > back) { back = -1; }
+ if( 1 < back) { back = 1; }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+
+#line 1737 "htmlbook.ctr"
+ return back;
+}
+
+
+
+/** Compare two strings.
+ @param l Left string.
+ @param r Right string.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+static
+int
+hb_compare_strings(void const *l, void const *r, int cr)
+{
+ int back = 0;
+
+
+#line 1754 "htmlbook.ctr"
+ if(l) {
+ if(r) {
+ back = dk3str_cmp((dkChar const *)l, (dkChar const *)r);
+ if(-1 > back) { back = -1; }
+ if( 1 < back) { back = 1; }
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ }
+
+#line 1763 "htmlbook.ctr"
+ return back;
+}
+
+
+
+/** Allocate memory for job structure.
+ @param job Job structure to initialize.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hb_job_allocate(hb_job_t *job)
+{
+ int back = 0;
+
+
+#line 1778 "htmlbook.ctr"
+ job->s_nodes = dk3sto_open_app(job->app);
+ if(job->s_nodes) {
+ dk3sto_set_comp(job->s_nodes, hb_node_compare, 0);
+ job->i_nodes = dk3sto_it_open(job->s_nodes);
+ if(job->i_nodes) {
+ job->s_pnodes = dk3sto_open_app(job->app);
+ if(job->s_pnodes) {
+ dk3sto_set_comp(job->s_pnodes, hb_node_compare, 0);
+ job->i_pnodes = dk3sto_it_open(job->s_pnodes);
+ if(job->i_pnodes) {
+ job->rootnode = hb_node_new(job, NULL, 0UL, 0UL, -1);
+ job->nextobj += 1UL;
+ if(job->rootnode) {
+ (job->rootnode)->depth = 0;
+ if(dk3sto_add(job->s_nodes, job->rootnode)) {
+ job->currentnode = job->rootnode;
+ job->shipbuffer = dk3_new_app(dkChar,HB_LINE_LENGTH,job->app);
+ job->iltemplate = dk3_new_app(dkChar,HB_LINE_LENGTH,job->app);
+ job->ilfile = dk3_new_app(dkChar,HB_LINE_LENGTH,job->app);
+ job->special = dk3_new_app(dkChar,HB_LINE_LENGTH,job->app);
+ job->buffer32 = dk3_new_app(dk3_c32_t,HB_LINE_LENGTH,job->app);
+ job->bs = HB_LINE_LENGTH;
+ job->spused = 0;
+ if(job->iltemplate) {
+ if(job->ilfile) {
+ if(job->special) {
+ if(job->buffer32) {
+ if(job->shipbuffer) {
+ job->s_files = dk3sto_open_app(job->app);
+ if(job->s_files) {
+ dk3sto_set_comp(job->s_files,hb_file_name_compare,0);
+ job->i_files = dk3sto_it_open(job->s_files);
+ if(job->i_files) {
+ if(dk3sto_add(job->s_pnodes, job->rootnode)) {
+ back = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } else {
+ hb_node_delete(job->rootnode);
+ job->rootnode = NULL;
+ }
+ }
+ }
+ }
+ }
+ }
+ if(back) {
+ back = 0;
+ job->s_index = dk3sto_open_app(job->app);
+ if(job->s_index) {
+ dk3sto_set_comp(job->s_index, hbindex_compare, 0);
+ job->i_index = dk3sto_it_open(job->s_index);
+ if(job->i_index) {
+ job->s_optsect = dk3sto_open_app(job->app);
+ if(job->s_optsect) {
+ dk3sto_set_comp(job->s_optsect, hb_compare_strings, 0);
+ job->i_optsect = dk3sto_it_open(job->s_optsect);
+ if(job->i_optsect) {
+ job->s_imgdim = dk3sto_open_app(job->app);
+ if(job->s_imgdim) {
+ dk3sto_set_comp(job->s_imgdim, hbimgdim_compare, 0);
+ job->i_imgdim = dk3sto_it_open(job->s_imgdim);
+ if(job->i_imgdim) {
+ back = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+#line 1855 "htmlbook.ctr"
+ return back;
+}
+
+
+
+#if 0
+/** Add one file to file list.
+ @param job Job structure.
+ @param il Input line to process, contains file name.
+ @return 1 on success, -1 on error.
+*/
+static
+int
+hb_add_file_to_file_list(hb_job_t *job, dkChar *il)
+{
+#if VERSION_BEFORE_20131207
+ dkChar *p1; /* Start of line */
+ dkChar *p2; /* Allocated memory */
+ int back = 1;
+ p1 = dk3str_start(il, NULL);
+ if(p1) {
+ dk3str_chomp(p1, NULL);
+ if(!(dk3sto_it_find_like(job->i_files, (void const *)il, 0))) {
+ p2 = dk3str_dup_app(il,job->app);
+ if(p2) {
+ if(!(dk3sto_add(job->s_files, (void *)p2))) {
+ back = -1;
+ dk3_release(p2);
+ }
+ } else {
+ back = -1;
+ }
+ }
+ }
+ return back;
+#else
+ return(hbtool_add_file(job,il));
+#endif
+}
+#endif
+
+
+
+/** Find indent level.
+ @param il Input line to process.
+ @return Number of leading spaces.
+*/
+static
+int
+hb_find_indent(dkChar *il)
+{
+ dkChar *p1; /* Traverse text line */
+ int back = 0;
+
+
+#line 1909 "htmlbook.ctr"
+ p1 = il;
+ while((dkT(' ') == *p1) || (dkT('\t') == *p1)) {
+ back++;
+ if(dkT('\t') == *p1) {
+ while(back % 8) { back++; }
+ }
+ p1++;
+ }
+
+#line 1917 "htmlbook.ctr"
+ return back;
+}
+
+
+
+/** Find parent candidate for new node.
+ @param current Current node to edit.
+ @param indent Indent of new node.
+ @return Pointer to node on success, NULL on error.
+*/
+static
+hb_node_t *
+hb_parent_candidate(hb_node_t *current, int indent)
+{
+ hb_node_t *back = NULL;
+ hb_node_t *ca; /* Candidate node */
+ int cc; /* Flag: Can continue */
+
+
+#line 1935 "htmlbook.ctr"
+ ca = current;
+ cc = 1;
+ while(cc) {
+ if(ca) {
+ if((ca->indent) < indent) {
+ back = ca;
+ cc = 0;
+ } else {
+ ca = ca->parent;
+ }
+ } else {
+ cc = 0;
+ }
+ }
+
+#line 1949 "htmlbook.ctr"
+ return back;
+}
+
+
+
+/** Process a line from the contents section.
+ @param job Job structure.
+ @param il Input line.
+ @return 1 on success, -1 on error.
+*/
+static
+int
+hb_add_contents(hb_job_t *job, dkChar *il)
+{
+ hb_node_t *pa; /* Parent node for new node */
+ hb_node_t *nn; /* New node */
+ dkChar *p1; /* Start of text line */
+ int indent; /* Indent level */
+ int back = 1;
+
+
+#line 1969 "htmlbook.ctr"
+ p1 = dk3str_start(il, NULL);
+ if(p1) {
+ if(dkT('@') == *p1) {
+ p1++;
+ back = hbconf_process_line(job, p1, HB_SECTION_CONTENTS);
+ } else {
+ /* Create new node. */
+ indent = hb_find_indent(il);
+ pa = hb_parent_candidate(job->currentnode, indent);
+ if(pa) {
+ nn = hb_node_new(job, pa, job->lineno, job->nextobj, indent);
+ job->nextobj += 1UL;
+ if(nn) {
+ if(nn->depth > job->maxdepth) { job->maxdepth = nn->depth; }
+ if(dk3sto_add(job->s_nodes, (void *)nn)) {
+ if(dk3sto_add(pa->s_subnodes, (void *)nn)) {
+ job->currentnode = nn;
+ nn->title = dk3str_dup_app(p1,job->app);
+ if(!(nn->title)) {
+ back = -1; /* REPORTED */
+ }
+ } else {
+ back = -1; /* REPORTED */
+ }
+ } else {
+ back = -1; /* REPORTED */
+ hb_node_delete(nn);
+ }
+ } else {
+ back = -1; /* REPORTED */
+ }
+ } else {
+ back = -1;
+ /* ERROR: No parent candidate found! */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 15);
+ }
+ }
+ }
+
+#line 2007 "htmlbook.ctr"
+ return back;
+}
+
+
+
+/** Process one line from project file.
+ @param job Job structure.
+ @param il Input line to process.
+ @return 1 on success, 0 on minor errors, -1 on fatal errors.
+*/
+static
+int
+hb_process_line(hb_job_t *job, dkChar *il)
+{
+ dkChar *p1; /* Start of line */
+ dkChar *p2; /* Next pointer */
+ int back = 1; /* Result */
+ int newst = HB_SECTION_UNKNOWN; /* New section type */
+
+
+#line 2026 "htmlbook.ctr"
+ job->lineno += 1UL;
+ p1 = dk3str_start(il, NULL);
+ if(p1) {
+ dk3str_chomp(p1,NULL);
+ if(dkT('#') != *p1) {
+ if(dkT('[') == *p1) {
+ job->actsect = 1;
+ job->secttype = HB_SECTION_UNKNOWN;
+ p1++;
+ p1 = dk3str_start(p1, NULL);
+ if(p1) {
+ p2 = dk3str_chr(p1, dkT(']'));
+ if(p2) {
+ *p2 = dkT('\0');
+ dk3str_chomp(p1, NULL);
+ p2 = dk3str_chr(p1, dkT(':'));
+ if(p2) {
+ *(p2++) = dkT('\0');
+ p2 = dk3str_start(p2, NULL);
+ dk3str_chomp(p2, NULL);
+ dk3str_chomp(p1, NULL);
+ }
+ newst = dk3str_array_index(hb_section_names, p1, 0);
+ if(0 <= newst) {
+ job->secttype = 1 + newst;
+ } else {
+ /* ERROR: Syntax (unknown section name) */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 18);
+ }
+ if(p2) {
+ if(!dk3sto_it_find_like(job->i_optsect, p2, 0)) {
+ job->actsect = 0;
+#if DK3_ON_WINDOWS
+ if(0 == dk3str_cmp(p2, (job->kwnl)[18])) {
+ job->actsect = 1;
+ }
+#else
+ if(0 == dk3str_cmp(p2, (job->kwnl)[19])) {
+ job->actsect = 1;
+ }
+#endif
+ }
+ }
+ } else {
+ /* ERROR: Syntax (missing closing bracket) */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 17);
+ }
+ } else {
+ /* ERROR: Syntax (no text in bracket) */
+ back = -1;
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 16);
+ }
+ } else {
+ if(job->actsect) {
+ switch(job->secttype) {
+ case HB_SECTION_OPTIONS: {
+ back = hbconf_process_line(job, il, HB_SECTION_OPTIONS);
+ } break;
+ case HB_SECTION_FILES: {
+ back = hbtool_add_file(job, il);
+ } break;
+ case HB_SECTION_CONTENTS: {
+ back = hb_add_contents(job, il);
+ } break;
+ }
+ }
+ }
+ }
+ }
+
+#line 2095 "htmlbook.ctr"
+ return back;
+}
+
+
+
+/** Line handler to process one line from project file.
+ @param obj Object to save data.
+ @param il Input line to process.
+ @return 1 on success, 0 on minor errors, -1 on fatal errors.
+*/
+static
+int
+hb_line_reader_handler(void *obj, dkChar *il)
+{
+ int back;
+
+
+#line 2111 "htmlbook.ctr"
+ back = hb_process_line((hb_job_t *)obj, il);
+
+
+#line 2113 "htmlbook.ctr"
+ return back;
+}
+
+
+
+/** Process command line variables, overwrite settings from
+ options section in project file.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hb_read_variables(hb_job_t *job)
+{
+ dkChar bu[1024]; /* Buffer for modification */
+ dk3_key_value_t *kvp; /* New key value pair */
+ dkChar const *optstr; /* Option string */
+ dkChar *p1; /* Start of option string (key) */
+ dkChar *p2; /* Start of value */
+ dkChar *p3; /* Copy of value */
+ int back = 1;
+ int nfo; /* Number of further arguments */
+ int i; /* Index of current argument */
+
+ if(0 < (nfo = dk3opt_get_num_fo(job->opt))) {
+ for(i = 0; i < nfo; i++) {
+ optstr = dk3opt_get_fo(job->opt, i);
+ if(optstr) {
+ if(dk3str_len(optstr) < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy(bu, optstr);
+ p1 = dk3str_start(bu, NULL);
+ if(p1) {
+ p2 = dk3str_chr(p1, dkT('='));
+ if(p2) {
+ *(p2++) = dkT('\0');
+ p2 = dk3str_start(p2, NULL);
+ }
+ if(p2) {
+ dk3str_chomp(p1, NULL);
+ dk3str_chomp(p2, NULL);
+ kvp = dk3sto_it_find_like(
+ (job->rootnode)->i_variables, p1, 1
+ );
+ if(kvp) {
+ p3 = dk3str_dup_app(p2, job->app);
+ if(p3) {
+ dk3_release(kvp->val);
+ kvp->val = p3;
+ } else {
+ back = 0;
+ }
+ } else {
+ kvp = dk3kv_new_app(p1, p2, job->app);
+ if(kvp) {
+ if(!dk3sto_add((job->rootnode)->s_variables, kvp)) {
+ dk3kv_delete(kvp);
+ back = 0;
+ }
+ } else {
+ back = 0;
+ }
+ }
+ } else {
+ kvp = dk3sto_it_find_like(
+ (job->rootnode)->i_variables, p1, 1
+ );
+ if(kvp) {
+ dk3sto_remove((job->rootnode)->s_variables, kvp);
+ dk3kv_delete(kvp);
+ }
+ }
+ } else {
+ /* Empty string is ok */
+ }
+ } else {
+ /* ERROR: String too long! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 135, 136, optstr);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Read the project file.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hb_read_project(hb_job_t *job)
+{
+ int back = 0;
+ int inenc; /* Input encoding */
+
+
+#line 2210 "htmlbook.ctr"
+ inenc = dk3app_get_input_file_encoding(job->app);
+ if(0 <= job->iecmd) { inenc = job->iecmd; }
+ back = dk3stream_process_filename_lines_app(
+ (void *)job, hb_line_reader_handler, job->infilename,
+ job->ilfile, job->bs,
+ dk3app_get_encoding(job->app),
+ inenc,
+ job->app
+ );
+ if(!hb_read_variables(job)) {
+ back = 0;
+ }
+ if((job->options) & HB_JOB_OPT_CHM) {
+ job->cs = HB_CS_ASCII;
+ }
+ if(1 != back) { back = 0; }
+
+
+#line 2227 "htmlbook.ctr"
+ return back;
+}
+
+
+
+/** Write all HTML files for the project.
+ @param job Job structure.
+*/
+static
+void
+hb_write_html_files(hb_job_t *job)
+{
+#if VERSION_BEFORE_20131206
+ hb_node_t *nptr;
+
+
+#line 2242 "htmlbook.ctr"
+ dk3sto_it_reset(job->i_pnodes);
+ while(NULL != (nptr = (hb_node_t *)dk3sto_it_next(job->i_pnodes))) {
+
+
+#line 2245 "htmlbook.ctr"
+ if(0UL != nptr->objno) {
+
+#line 2246 "htmlbook.ctr"
+ hbhtml_write_file(job, nptr);
+ }
+ }
+
+#line 2249 "htmlbook.ctr"
+#else
+ hb_node_t *c;
+ hb_node_t *p;
+ hb_node_t *n;
+
+
+#line 2254 "htmlbook.ctr"
+ p = c = n = NULL;
+ dk3sto_it_reset(job->i_pnodes);
+ c = dk3sto_it_next(job->i_pnodes);
+ while(c) {
+ n = dk3sto_it_next(job->i_pnodes);
+ if(0UL != c->objno) {
+ hbhtml_write_file(job, c, p, n);
+ }
+ p = c;
+ c = n;
+ }
+
+
+#line 2266 "htmlbook.ctr"
+#endif
+}
+
+
+
+/** Write index html file.
+ @param job Job structure.
+*/
+static
+void
+hb_write_index(hb_job_t *job)
+{
+ hb_node_t *n; /* Current index item */
+
+
+#line 2280 "htmlbook.ctr"
+ dk3sto_it_reset(job->i_pnodes);
+ if(dk3sto_it_next(job->i_pnodes)) {
+ n = (hb_node_t *)dk3sto_it_next(job->i_pnodes);
+ if(n) {
+ hbhtml_write_file(job, job->rootnode, NULL, n);
+ } else {
+/* 2014/02/05 We now allow an empty contents section to
+ produce just one file index.html.
+*/
+#if VERSION_BEFORE_20140205
+ job->exv = 1;
+
+#line 2291 "htmlbook.ctr"
+#else
+ hbhtml_write_file(job, job->rootnode, NULL, n);
+#endif
+ }
+ } else {
+ job->exv = 1;
+
+#line 2297 "htmlbook.ctr"
+ }
+
+#line 2298 "htmlbook.ctr"
+}
+
+
+
+#if TRACE_DEBUG && (DK3_CHAR_SIZE == 1)
+/** Show document tree structure at a node recursively.
+ @param job Job structure.
+ @param nptr Current node to show.
+ @param l Indent level.
+*/
+static
+void
+hb_show_tree_node(hb_job_t *job, hb_node_t *nptr, int l)
+{
+ hb_node_t *hbptr;
+ int i;
+ if(dktrace_file()) {
+ fputs("> ", dktrace_file());
+ for(i = 0; i < l; i++) {
+ fputs(" ", dktrace_file());
+ }
+ fputs(nptr->title, dktrace_file());
+ if(nptr->shorttitle) {
+ fputs(" (", dktrace_file());
+ fputs(nptr->shorttitle, dktrace_file());
+ fputs(")", dktrace_file());
+ }
+ fprintf(dktrace_file(), " depth=%d", nptr->depth);
+ fputc('\n', dktrace_file());
+ dk3sto_it_reset(nptr->i_subnodes);
+ while(NULL != (hbptr = (hb_node_t *)dk3sto_it_next(nptr->i_subnodes))) {
+ hb_show_tree_node(job, hbptr, (l+1));
+ }
+ }
+}
+
+/** Show document tree structure.
+ @param job Job structure.
+*/
+static
+void
+hb_show_structure(hb_job_t *job)
+{
+ hb_show_tree_node(job, job->rootnode, 0);
+}
+#endif
+
+
+
+#if (DK3_ON_WINDOWS) || (DK3_CHAR_SIZE > 1)
+/** Write file name to output file, ANSI encoded.
+ Set exit status code on error.
+ @param job Job structure.
+ @param fn File name.
+*/
+static
+void
+hb_write_ansi_filename(hb_job_t *job, dkChar const *fn)
+{
+
+
+#line 2358 "htmlbook.ctr"
+ if(!dk3se_ansi_fputs(fn, dk3app_get_encoding(job->app), job->of, job->app)) {
+ job->exv = 1;
+ }
+
+#line 2361 "htmlbook.ctr"
+}
+#endif
+
+
+#if !DK3_ON_WINDOWS
+/** Write a file name.
+ @param job Job structure.
+ @param fn File name to write.
+*/
+static
+void
+hb_write_filename(hb_job_t *job, dkChar const *fn)
+{
+#if DK3_CHAR_SIZE > 1
+ hb_write_ansi_filename(job, fn);
+#error "Not implemented!"
+#else
+ if(EOF == fputs(fn, job->of)) {
+ job->exv = 1;
+ /* ERROR: Write attempt failed! */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 120);
+ }
+#endif
+}
+#endif
+
+
+
+/** Check whether the output file for a node is a HTML file.
+ @param nptr Node to check.
+ @return 1 for HTML files, 0 otherwise.
+*/
+static
+int
+hb_htfile(hb_node_t *nptr)
+{
+ int back = 1;
+
+
+#line 2399 "htmlbook.ctr"
+ if(nptr->suffix) {
+ back = 0;
+ if(dk3str_fncmp(nptr->suffix, hb_kwnl[23]) == 0) { back = 1; }
+ if(dk3str_fncmp(nptr->suffix, hb_kwnl[24]) == 0) { back = 1; }
+ }
+
+#line 2404 "htmlbook.ctr"
+ return back;
+}
+
+
+
+/** Write instruction to copy one file to script.
+ @param job Job structure.
+ @param fn File name.
+*/
+static
+void
+hb_write_script_copy_file(hb_job_t *job, dkChar const *fn)
+{
+#if DK3_ON_WINDOWS
+ fputs(hb_c8_kw[8], job->of);
+ hb_write_ansi_filename(job, fn);
+ fputs(hb_c8_kw[9], job->of);
+ hb_write_ansi_filename(job, fn);
+ fputs(hb_c8_kw[0], job->of);
+ fputs(hb_c8_kw[10], job->of);
+ hb_write_ansi_filename(job, fn);
+ fputs(hb_c8_kw[11], job->of);
+ hb_write_ansi_filename(job, fn);
+ fputs(hb_c8_kw[12], job->of);
+ hb_write_ansi_filename(job, job->outputdir);
+ fputs(hb_c8_kw[13], job->of);
+#else
+ fputs(hb_c8_kw[14], job->of); /* if */
+ hb_write_filename(job, fn);
+ fputs(hb_c8_kw[15], job->of); /* then */
+ fputs(hb_c8_kw[16], job->of); /* else */
+ if((job->options) & HB_JOB_OPT_LN) {
+ fputs(hb_c8_kw[19], job->of);
+ } else {
+ fputs(hb_c8_kw[20], job->of);
+ }
+ hb_write_filename(job, fn);
+ fputs(hb_c8_kw[21], job->of);
+ hb_write_filename(job, job->outputdir);
+ fputs(hb_c8_kw[5], job->of);
+ fputs(hb_c8_kw[17], job->of); /* fi */
+ fputs(hb_c8_kw[22], job->of);
+ hb_write_filename(job, fn);
+ fputs(hb_c8_kw[23], job->of);
+ fputs(hb_c8_kw[35], job->of);
+ fputs(hb_c8_kw[18], job->of);
+#endif
+}
+
+
+
+/** Write the output script.
+ Set exit status code on errors.
+ @param job Job structure.
+*/
+static
+void
+hb_write_script(hb_job_t *job)
+{
+ dkChar of[DK3_MAX_PATH]; /* Output file name */
+ hb_node_t *nptr; /* Current print node */
+ dkChar const *fn; /* Current resource file name */
+
+
+#line 2467 "htmlbook.ctr"
+ if(job->outputscript) {
+ if(job->outputdir) {
+ job->of = dk3sf_fopen_app(job->outputscript, hb_kwnl[22], job->app);
+ if(job->of) {
+ /* Start of file
+ */
+#if DK3_ON_WINDOWS
+ fputs(hb_c8_kw[31], job->of);
+#else
+ fputs(hb_c8_kw[32], job->of);
+ fputs(hb_c8_kw[33], job->of);
+#endif
+ /* Remove existing directory completely.
+ */
+#if DK3_ON_WINDOWS
+ fputs(hb_c8_kw[2], job->of);
+ hb_write_ansi_filename(job, job->outputdir);
+ fputs(hb_c8_kw[3], job->of);
+#else
+ fputs(hb_c8_kw[4], job->of);
+ hb_write_filename(job, job->outputdir);
+ fputs(hb_c8_kw[5], job->of);
+#endif
+ /* Create new directory.
+ */
+#if DK3_ON_WINDOWS
+ fputs(hb_c8_kw[6], job->of);
+ hb_write_ansi_filename(job, job->outputdir);
+ fputs(hb_c8_kw[5], job->of);
+#else
+ fputs(hb_c8_kw[7], job->of);
+ hb_write_filename(job, job->outputdir);
+ fputs(hb_c8_kw[5], job->of);
+#endif
+ /* Copy resource files.
+ */
+ dk3sto_it_reset(job->i_files);
+ while(NULL != (fn = (dkChar const *)dk3sto_it_next(job->i_files))) {
+ /* 2014-04-17
+ Writinig the file copy instruction is now in the
+ hb_write_script_copy_file() function.
+ */
+ hb_write_script_copy_file(job, fn);
+ }
+ /* For CHM projects copy index.hhp, index.hhc and index.hhk
+ */
+ if ((job->options) & HB_JOB_OPT_CHM) {
+ hb_write_script_copy_file(job, hb_kwnl[36]);
+ hb_write_script_copy_file(job, hb_kwnl[26]);
+ hb_write_script_copy_file(job, hb_kwnl[28]);
+ if ((job->options) & HB_JOB_OPT_CREATE_INDEX) {
+ if (hbchm_have_index_entries(job)) {
+ hb_write_script_copy_file(job, hb_kwnl[29]);
+ }
+ }
+ }
+ /* Copy HTML files, use tidy if available.
+ */
+ dk3sto_it_reset(job->i_pnodes);
+ while(NULL != (nptr = (hb_node_t *)dk3sto_it_next(job->i_pnodes))) {
+ if(hbhtml_create_output_filename(of,DK3_SIZEOF(of,dkChar),job,nptr))
+ {
+ fn = of;
+#if DK3_ON_WINDOWS
+ /* Remove existing file.
+ */
+ fputs(hb_c8_kw[10], job->of);
+ hb_write_ansi_filename(job, job->outputdir);
+ fputc('\\', job->of);
+ hb_write_ansi_filename(job, fn);
+ fputs(hb_c8_kw[38], job->of);
+ hb_write_ansi_filename(job, job->outputdir);
+ fputc('\\', job->of);
+ hb_write_ansi_filename(job, fn);
+ fputs(hb_c8_kw[39], job->of);
+ /* Use tidy or xcopy to bring new file in place.
+ */
+ fputs(hb_c8_kw[8], job->of);
+ hb_write_ansi_filename(job, fn);
+ fputs(hb_c8_kw[9], job->of);
+ hb_write_ansi_filename(job, fn);
+ fputs(hb_c8_kw[0], job->of);
+ if(((nptr->options) & HB_NODE_OPT_USE_TIDY) && (hb_htfile(nptr))) {
+ fputs(hb_c8_kw[36], job->of);
+ hb_write_ansi_filename(job, fn);
+ fputs(hb_c8_kw[0], job->of);
+ if(HB_CS_UTF_8 == job->cs) {
+ fputs(hb_c8_kw[24], job->of);
+ hb_write_ansi_filename(job, fn);
+ fputs(hb_c8_kw[26], job->of);
+ hb_write_ansi_filename(job, job->outputdir);
+ fputc('\\', job->of);
+ hb_write_ansi_filename(job, fn);
+ fputs(hb_c8_kw[3], job->of);
+ } else {
+ fputs(hb_c8_kw[25], job->of);
+ hb_write_ansi_filename(job, fn);
+ fputs(hb_c8_kw[26], job->of);
+ hb_write_ansi_filename(job, job->outputdir);
+ fputc('\\', job->of);
+ hb_write_ansi_filename(job, fn);
+ fputs(hb_c8_kw[3], job->of);
+ }
+ } else {
+ fputs(hb_c8_kw[10], job->of);
+ hb_write_ansi_filename(job, fn);
+ fputs(hb_c8_kw[11], job->of);
+ hb_write_ansi_filename(job, fn);
+ fputs(hb_c8_kw[12], job->of);
+ hb_write_ansi_filename(job, job->outputdir);
+ fputs(hb_c8_kw[13], job->of);
+ }
+#else
+ /* Remove existing file.
+ */
+ fputs(hb_c8_kw[14], job->of); /* if */
+ hb_write_filename(job, job->outputdir);
+ fputs(hb_c8_kw[30], job->of);
+ hb_write_filename(job, fn);
+ fputs(hb_c8_kw[15], job->of);
+ fputs(hb_c8_kw[16], job->of); /* then */
+ fputs(hb_c8_kw[4], job->of);
+ hb_write_filename(job, job->outputdir);
+ fputs(hb_c8_kw[30], job->of);
+ hb_write_filename(job, fn);
+ fputs(hb_c8_kw[5], job->of);
+ fputs(hb_c8_kw[18], job->of); /* fi */
+ /* Use tidy, cp or ln to bring new file in place.
+ */
+ fputs(hb_c8_kw[14], job->of);
+ hb_write_filename(job, fn);
+ fputs(hb_c8_kw[15], job->of);
+ fputs(hb_c8_kw[16], job->of);
+ if(((nptr->options) & HB_NODE_OPT_USE_TIDY) && (hb_htfile(nptr))) {
+ fputs(hb_c8_kw[37], job->of);
+ hb_write_filename(job, fn);
+ fputs(hb_c8_kw[0], job->of);
+ if(HB_CS_UTF_8 == job->cs) {
+ fputs(hb_c8_kw[27], job->of);
+ } else {
+ fputs(hb_c8_kw[28], job->of);
+ }
+ hb_write_filename(job, fn);
+ fputs(hb_c8_kw[29], job->of);
+ hb_write_filename(job, job->outputdir);
+ fputs(hb_c8_kw[30], job->of);
+ hb_write_filename(job, fn);
+ fputs(hb_c8_kw[5], job->of);
+ } else {
+ if((job->options) & HB_JOB_OPT_LN) {
+ fputs(hb_c8_kw[19], job->of);
+ } else {
+ fputs(hb_c8_kw[20], job->of);
+ }
+ hb_write_filename(job, fn);
+ fputs(hb_c8_kw[21], job->of);
+ hb_write_filename(job, job->outputdir);
+ fputs(hb_c8_kw[5], job->of);
+ }
+ fputs(hb_c8_kw[17], job->of);
+ fputs(hb_c8_kw[22], job->of);
+ hb_write_filename(job, fn);
+ fputs(hb_c8_kw[23], job->of);
+ fputs(hb_c8_kw[35], job->of);
+ fputs(hb_c8_kw[18], job->of);
+#endif
+ }
+ }
+ /* End of file.
+ */
+#if !DK3_ON_WINDOWS
+ /* find ... -type d -exec chmod ugo+rx {} \; */
+ fputs(hb_c8_kw[40], job->of);
+ hb_write_filename(job, job->outputdir);
+ fputs(hb_c8_kw[41], job->of);
+ /* find ... -type f -exec chmod ugo+r {} \; */
+ fputs(hb_c8_kw[40], job->of);
+ hb_write_filename(job, job->outputdir);
+ fputs(hb_c8_kw[42], job->of);
+ /* exit EXITCODE */
+ fputs(hb_c8_kw[34], job->of);
+#endif
+ /* Close file.
+ */
+ if(!dk3sf_fclose_fn_app(job->of, job->outputscript, job->app)) {
+ job->exv = 1;
+ }
+ } else {
+ job->exv = 1;
+ }
+ } else {
+ job->exv = 1;
+ /* ERROR: No output directory configured! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 67);
+ }
+ } else {
+ job->exv = 1;
+ /* ERROR: No output script configured! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 68);
+ }
+
+#line 2667 "htmlbook.ctr"
+}
+
+
+
+/** Write output files.
+ Set exit status code on errors.
+ @param job Job structure.
+*/
+static
+void
+hb_write_output(hb_job_t *job)
+{
+
+
+#line 2680 "htmlbook.ctr"
+#if DK3_CHAR_SIZE == 1
+
+
+#line 2682 "htmlbook.ctr"
+#endif
+ hb_write_html_files(job);
+ hb_write_index(job);
+ hb_write_script(job);
+ if((job->options) & HB_JOB_OPT_CHM) {
+ if(!hbchm_write_project(job)) { job->exv = 1; }
+ }
+#if DK3_CHAR_SIZE == 1
+
+
+#line 2691 "htmlbook.ctr"
+#endif
+
+
+#line 2693 "htmlbook.ctr"
+}
+
+
+
+/** Check consistency of input data.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hb_check_data(hb_job_t *job)
+{
+ hb_node_t *nptr; /* Current node */
+ int back = 1;
+
+
+#line 2708 "htmlbook.ctr"
+ /* All printable nodes must have a template.
+ */
+ job->npobjs = 0UL;
+ dk3sto_it_reset(job->i_pnodes);
+ while(NULL != (nptr = (hb_node_t *)dk3sto_it_next(job->i_pnodes))) {
+ if(!(job->firstnode)) { job->firstnode = nptr; }
+ job->lastnode = nptr;
+ nptr->pobjno = job->npobjs;
+ job->npobjs += 1UL;
+ if(!hbconf_node_template(job, nptr)) {
+ back = 0;
+ /* ERROR: No template for node! */
+ dk3app_set_source_line(job->app, nptr->lineno);
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 19);
+ }
+ }
+ if(back) {
+ /* ##### Further tests. */
+ }
+
+#line 2727 "htmlbook.ctr"
+ return back;
+}
+
+
+
+/** Do normal processing for one specified project file.
+ @param job Job structure.
+*/
+static
+void
+hb_run_with_input_filename(hb_job_t *job)
+{
+ int res = 1;
+
+
+#line 2741 "htmlbook.ctr"
+ dk3app_set_source_file(job->app, job->infilename);
+ dk3app_set_source_line(job->app, 0UL);
+ if(hb_job_allocate(job)) {
+
+#line 2744 "htmlbook.ctr"
+ if(dk3opt_is_set(job->opt, dkT('o'))) {
+ res = hb_save_optional_sections(
+ job, dk3opt_get_short_arg(job->opt, dkT('o'))
+ );
+ }
+ if(res) {
+ if(hbconf_read_files(job)) {
+ if(hb_read_project(job)) {
+ if(hb_check_data(job)) {
+ hbtool_enumerate(job);
+ job->exv = 0;
+
+#line 2755 "htmlbook.ctr"
+ hb_write_output(job);
+ }
+ }
+ }
+ }
+ } else {
+
+#line 2761 "htmlbook.ctr"
+ }
+
+
+#line 2763 "htmlbook.ctr"
+}
+
+
+
+/** Run normally.
+ @param job Job structure.
+*/
+static
+void
+hb_run(hb_job_t *job)
+{
+ dkChar const *infilename; /* Input file name */
+ dk3_dir_t *fne; /* File name expander */
+ dk3_um_t numfiles; /* Number of files in expander */
+
+
+#line 2778 "htmlbook.ctr"
+ infilename = dk3opt_get_arg(job->opt, 0);
+ if(infilename) {
+ if(dk3sf_must_expand(infilename)) {
+ fne = dk3dir_fne_open_app(infilename, job->app);
+ if(fne) {
+ numfiles = dk3dir_get_number_of_files(fne);
+ if(DK3_UM_0 < numfiles) {
+ if(DK3_UM_1 < numfiles) {
+ /* ERROR: Too many file names match */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 168, 169, infilename);
+ } else {
+ if(dk3dir_get_next_file(fne)) {
+ job->infilename = dk3dir_get_fullname(fne);
+ if(job->infilename) {
+ hb_run_with_input_filename(job);
+ } else {
+ /* ERROR: Failed to obtain file name */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ }
+ } else {
+ /* ERROR: Failed to obtain file name */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ }
+ }
+ } else {
+ /* ERROR: No matching file name! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 215, 216, infilename);
+ }
+ dk3dir_close(fne);
+ }
+ } else {
+ job->infilename = infilename;
+ hb_run_with_input_filename(job);
+ }
+ } else {
+ /* ERROR: Missing project file name! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 13);
+ }
+
+
+#line 2817 "htmlbook.ctr"
+}
+
+
+
+/** Main function of the htmlbook program.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, any other value indicates an error.
+*/
+DK3_MAIN
+{
+ hb_job_t job; /* Job structure */
+ dk3_app_t *app = NULL; /* Application structure */
+ dkChar const * const *msg = NULL; /* Localized message texts */
+ dk3_time_t timer; /* Current time */
+ int exv = 1; /* Exit status code */
+
+
+
+#line 2835 "htmlbook.ctr"
+
+
+#line 2836 "htmlbook.ctr"
+#if DK3_HAVE_TZSET
+ tzset();
+#endif
+ app = dk3app_open_command(
+ argc, (dkChar const * const *)argv, hb_kwnl[0]
+ );
+ if(app) {
+ msg = dk3app_messages(app, hb_kwnl[1], (dkChar const **)hb_kw);
+ hb_job_init(&job, app, msg, hb_kwnl);
+ dk3sf_time(&timer);
+ dk3sf_localtime_app(&(job.starttime), &timer, app);
+ if(hb_process_options(&job)) {
+ if(job.cmd) {
+ hb_help_version_license(&job);
+ } else {
+ hb_run(&job);
+ }
+ }
+ exv = job.exv;
+ hb_job_end(&job);
+ dk3app_close(app); app = NULL;
+ } else {
+ fputs("htmlbook: ERROR: Not enough memory (RAM/swap)!\n", stderr);
+ fflush(stderr);
+ }
+
+
+#line 2862 "htmlbook.ctr"
+
+
+#line 2863 "htmlbook.ctr"
+ fflush(stdout);
+ exit(exv); return exv;
+}
+
+
diff --git a/support/dktools/htmlbook.ctr b/support/dktools/htmlbook.ctr
new file mode 100644
index 0000000000..fd679bcad8
--- /dev/null
+++ b/support/dktools/htmlbook.ctr
@@ -0,0 +1,2867 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2013-xxxx
+license = bsd
+
+
+
+%% header
+
+#include "dk3conf.h"
+#include "dk3types.h"
+#include "dk3numco.h"
+
+
+
+/** Image dimension cache entry.
+*/
+typedef struct {
+ dkChar *fn; /**< Image name. */
+ unsigned long w; /**< Image width. */
+ unsigned long h; /**< Image height. */
+} hb_img_dim_t;
+
+
+
+/** External link.
+*/
+typedef struct {
+ dkChar *url; /**< Link URL. */
+ unsigned long lno; /**< Link number within current page. */
+} hb_link_t;
+
+
+
+/** One contents line.
+*/
+typedef struct {
+ dkChar *text; /**< Allocated line text. */
+ dkChar *aname; /**< The a name text (if any). */
+ dkChar *realtext; /**< Real start of text for header. */
+ unsigned long lineno; /**< Line number. */
+ unsigned long header; /**< Running number of header. */
+ unsigned headlevel; /**< Header level (1 to 6). */
+ int lt; /**< Line type (0=normal, 1=header). */
+} hb_line_t;
+
+
+
+/** One node in the document tree.
+*/
+struct hb__node_t {
+ struct hb__node_t *parent; /**< Parent node. */
+ struct hb__node_t *curchild; /**< Current child to edit. */
+ struct hb__node_t *jumpnode; /**< Link target node. */
+ dk3_sto_t *s_subnodes; /**< Subnodes collection. */
+ dk3_sto_it_t *i_subnodes; /**< Subnodes iterator. */
+ dk3_sto_t *s_variables; /**< Variables storage. */
+ dk3_sto_it_t *i_variables; /**< Variables iterator. */
+ dk3_sto_t *s_lines; /**< Contents lines storage. */
+ dk3_sto_it_t *i_lines; /**< Contents lines iterator. */
+ dk3_sto_t *s_lbyurl; /**< Storage for links by URL. */
+ dk3_sto_it_t *i_lbyurl; /**< Iterator for links by URL. */
+ dk3_sto_t *s_lbylno; /**< Storage for links by number. */
+ dk3_sto_it_t *i_lbylno; /**< Iterator for links by number. */
+ dk3_sto_t *s_jsfiles; /**< Storage for JS files. */
+ dk3_sto_it_t *i_jsfiles; /**< Iterator for JS files. */
+ dkChar *title; /**< Node title. */
+ dkChar *shorttitle; /**< Short title (optional). */
+ dkChar *fulltitle; /**< Full title (browser title bar). */
+ dkChar *filename; /**< Text file name (optional). */
+ dkChar *suffix; /**< Output file name suffix (opt). */
+ dkChar *template; /**< Template file name (optional). */
+ dkChar *stylefile; /**< Style file. */
+ dkChar *author; /**< Name of author. */
+ dkChar *location; /**< Location (city) of author. */
+ dkChar *icontoc; /**< File name TOC icon. */
+ dkChar *iconprev; /**< File name previous section icon. */
+ dkChar *iconnext; /**< File name next section icon. */
+ dkChar *iconindex; /**< File name index icon. */
+ dkChar *iconhome; /**< File name home icon. */
+ dkChar *favicon; /**< favicon. */
+ dkChar *metadesc; /**< Meta description tag. */
+ dkChar *metakeyw; /**< Meta keywords tag. */
+ dkChar const *outFileName; /**< Output file name. */
+ unsigned long lineno; /**< Line number in project file. */
+ unsigned long objno; /**< Object index. */
+ unsigned long pobjno; /**< Printable object number. */
+ unsigned long nextlink; /**< Next link number. */
+ unsigned long nextindex; /**< Next index entry number. */
+ unsigned long headno; /**< Head number. */
+ unsigned long nextsubheadno; /**< Next head number for sub node. */
+ unsigned long nextjs; /**< Number of next js file. */
+ long contnum; /**< Context number. */
+ unsigned options; /**< Options for node. */
+ int indent; /**< Line indent (number o spaces). */
+ int depth; /**< Depth. */
+ int tocstate; /**< State when creating TOC. */
+ int inenc; /**< Text file input encoding. */
+ int havenavimenu; /**< Flag: Already have navi menu. */
+};
+
+/** One node in the document tree.
+*/
+typedef struct hb__node_t hb_node_t;
+
+
+
+/** Entry in keyword index.
+*/
+typedef struct {
+ dkChar *tx; /**< Keyword index text. */
+ dkChar *fn; /**< File name. */
+ dkChar *an; /**< Anchor name (optional). */
+ unsigned long ul; /**< Anchor number (if no name available). */
+ hb_node_t *no; /**< Node for file name (needed for title). */
+} hb_index_entry_t;
+
+
+
+/** Job type for the htmlbook program.
+ The s_nodes storage contains a plain list of all nodes,
+ this storage is used to release all nodes at the end of the program.
+ The s_pnodes storage contains a plain list of all nodes to
+ write output for.
+ The tree structure is below the rootnode element.
+*/
+typedef struct {
+ dk3_tm_t starttime; /**< Start time. */
+ dk3_app_t *app; /**< Application structure. */
+ dkChar const * const *msg; /**< Localized messages. */
+ dkChar const * const *kwnl; /**< Keywords, not localized. */
+ dk3_option_set_t *opt; /**< Command line options. */
+ dk3_sto_t *s_nodes; /**< All nodes storage. */
+ dk3_sto_it_t *i_nodes; /**< All nodes storage iterator. */
+ dk3_sto_t *s_pnodes; /**< Leaf nodes storage. */
+ dk3_sto_it_t *i_pnodes; /**< Leaf nodes storage iterator. */
+ dk3_sto_t *s_files; /**< Additional files storage. */
+ dk3_sto_it_t *i_files; /**< Additional files iterator. */
+ dk3_sto_t *s_index; /**< Index entries storage. */
+ dk3_sto_it_t *i_index; /**< Index entries storage iterator. */
+ dk3_sto_t *s_optsect; /**< Optional sections storage. */
+ dk3_sto_it_t *i_optsect; /**< Optional sections iterator. */
+ dk3_sto_t *s_imgdim; /**< Image dimension cache storage. */
+ dk3_sto_it_t *i_imgdim; /**< Image dimension cache iterator. */
+ hb_node_t *rootnode; /**< Root node. */
+ hb_node_t *currentnode; /**< Current node to modify. */
+ hb_node_t *impressumnode; /**< Impressum node. */
+ hb_node_t *firstnode; /**< First pnode. */
+ hb_node_t *lastnode; /**< Last pnode. */
+ dkChar const *infilename; /**< Input file name (project). */
+ dkChar const *outputdir; /**< Output directory (allocated). */
+ dkChar const *outputscript; /**< Name of script to produce. */
+ dkChar const *url; /**< URL to publish the results. */
+ dkChar const *indexfile; /**< Typically index html. */
+ dkChar const *impressumlink; /**< Link to impressum. */
+ dkChar const *chmlang; /**< Language setting for CHM. */
+ dkChar *shipbuffer; /**< Shipout buffer. */
+ dkChar *iltemplate; /**< Input line from template. */
+ dkChar *ilfile; /**< Input line from file. */
+ dkChar *special; /**< Buffer for current special. */
+ dk3_c32_t *buffer32; /**< Buffer for 32-bit characters. */
+ FILE *of; /**< Output file. */
+ unsigned long lineno; /**< Line number. */
+ unsigned long nextobj; /**< Next object number. */
+ unsigned long npobjs; /**< Number of printable objects. */
+ size_t bs; /**< Buffer size. */
+ size_t spused; /**< Number elements used in special. */
+ size_t shipused; /**< Shipout buffer used. */
+ unsigned options; /**< Job options. */
+ int iecmd; /**< Input encoding from cmd args. */
+ int actsect; /**< Flag: Active section. */
+ int cmd; /**< Option processing result. */
+ int exv; /**< Exit status code. */
+ int cs; /**< Character set for HTML output. */
+ int secttype; /**< Section type. */
+ int non_url; /**< Flag: Non-URL characters found. */
+ int maxdepth; /**< Maximum depth of a node. */
+ int headlevels; /**< Maximum depth to print header. */
+ int coli; /**< Current code line number. */
+ int cols; /**< Code line state. */
+} hb_job_t;
+
+
+
+/** File processing help structure.
+*/
+typedef struct {
+ hb_job_t *job; /**< Job structure. */
+ hb_node_t *p; /**< Previous node. */
+ hb_node_t *n; /**< Next node. */
+ int in_template; /**< Flag: Processing template. */
+ int stm; /**< State machine. */
+} hb_file_processor_t;
+
+
+
+/** @defgroup hboptions Node options from project file. */
+/**@{*/
+
+/** Write page TOC.
+*/
+#define HB_NODE_OPT_PAGE_TOC 0x0001U
+
+/** Replace ampersand.
+*/
+#define HB_NODE_OPT_REPLACE_AMPERSAND 0x0002U
+
+/** Use tidy while copying.
+*/
+#define HB_NODE_OPT_USE_TIDY 0x0004U
+
+/** Write header chain.
+*/
+#define HB_NODE_OPT_HEADER_CHAIN 0x0008U
+
+/** Indicate the impressum node.
+*/
+#define HB_NODE_OPT_IMPRESSUM 0x0010U
+
+/** Stop inheritance of JS files at this node.
+*/
+#define HB_NODE_OPT_STOP_JS_INHERITANCE 0x0020U
+
+/**@}*/
+
+
+
+/** @defgroup hbjoboptions Job options. */
+/**@{*/
+
+/** Create index file.
+*/
+#define HB_JOB_OPT_CREATE_INDEX 0x0001U
+
+/** Create table of contents.
+*/
+#define HB_JOB_OPT_CREATE_TOC 0x0002U
+
+/** Currently processing code.
+*/
+#define HB_JOB_OPT_CODE 0x0004U
+
+/** Produce output for building a chm file.
+*/
+#define HB_JOB_OPT_CHM 0x0008U
+
+/** Use ln instead of cp for resource files.
+*/
+#define HB_JOB_OPT_LN 0x0010U
+
+/** Write section number in positions table.
+*/
+#define HB_JOB_OPT_NUM_IN_POS 0x0020U
+
+/** Write section number in keyword index.
+*/
+#define HB_JOB_OPT_NUM_IN_IDX 0x0040U
+
+/** Write section number in page header.
+*/
+#define HB_JOB_OPT_NUM_IN_PAGE_HEADER 0x0080U
+
+/** Enable full text search in chm output.
+*/
+#define HB_JOB_OPT_CHM_FULL_TEXT_SEARCH 0x0100U
+
+/** Print line numbers for code.
+*/
+#define HB_JOB_OPT_CODE_LINE_NUMBERS 0x0200U
+
+/**@}*/
+
+
+
+/** @defgroup hbcharsets Character sets used by htmlbook. */
+/**@{*/
+
+/** Character set us-ascii.
+*/
+#define HB_CS_ASCII 0
+
+/** Character set UTF-8.
+*/
+#define HB_CS_UTF_8 1
+
+/**@}*/
+
+
+
+/** @defgroup hbsections Section types. */
+/**@{*/
+
+/** Section type not yet known.
+*/
+#define HB_SECTION_UNKNOWN 0
+
+/** Options section.
+*/
+#define HB_SECTION_OPTIONS 1
+
+/** Files section.
+*/
+#define HB_SECTION_FILES 2
+
+/** Contents section.
+*/
+#define HB_SECTION_CONTENTS 3
+
+/**@}*/
+
+
+
+/** @defgroup hbtocstate Node state when creating TOC. */
+/**@{*/
+
+/** Work on this node is not yet in progress.
+*/
+#define HB_TOC_STATE_INIT 0
+
+/** Work on this node is in progress.
+*/
+#define HB_TOC_STATE_IN_PROGRESS 1
+
+/** Work on this node is finished.
+*/
+#define HB_TOC_STATE_FINISHED 2
+
+/**@}*/
+
+
+
+/** @defgroup hbcolist Code line states. */
+/**@{*/
+
+/** Directly after code special command.
+*/
+#define HB_COLIST_NONE 0
+
+/** In a new line, no contents yet thus no opened code tag.
+*/
+#define HB_COLIST_NOT_OPENED 1
+
+/** Code tag was opened and must be closed.
+*/
+#define HB_COLIST_OPENED 2
+
+/**@}*/
+
+
+
+/** Maximum line length.
+*/
+#define HB_LINE_LENGTH 16383
+
+
+#include "hbnode.h"
+#include "hbconf.h"
+#include "hbhtml.h"
+#include "hbtool.h"
+#include "hbcont.h"
+#include "hbindex.h"
+#include "hbimgdim.h"
+#include "hbchm.h"
+#include "dk3strkv.h"
+#include "dk3kv.h"
+#include "dk3se.h"
+
+
+
+%% module
+
+#include "dk3all.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4vers.h"
+#include "htmlbook.h"
+
+
+/* Synopsis:
+ htmlbook -h | --help
+ htmlbook -v | --version
+ htmlbook -L | --license
+ htmlbook [<options>] <project>
+
+ Options:
+*/
+
+
+$!trace-include
+
+
+
+/** @defgroup hbcmd Commands for htmlbook. */
+/**@{*/
+/** Print help.
+*/
+#define HB_CMD_HELP 1
+/** Print version number.
+*/
+#define HB_CMD_VERSION 2
+/** Print license terms.
+*/
+#define HB_CMD_LICENSE 4
+/**@}*/
+
+
+
+/** Version information.
+*/
+static dkChar const *hb_version[] = {
+ dkT("htmlbook "),
+ DKT_VERSION_DK
+};
+
+
+
+/** License conditions.
+*/
+static dkChar const * const hb_license[] = {
+$!text macro=dkT
+
+Copyright (c) 2013-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms,
+with or without modification, are permitted provided
+that the following conditions are met:
+
+* Redistributions of source code must retain the above
+ copyright notice, this list of conditions and the
+ following disclaimer.
+* Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials
+ provided with the distribution.
+* Neither the name of the copyright holder(s) nor the names of
+ contributors may be used to endorse or promote
+ products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+$!end
+};
+
+
+
+/** Help text shown if help file is not found.
+*/
+static dkChar const * const hb_help_text[] = {
+$!text macro=dkT
+
+NAME
+
+htmlbook - Create HTML book structure
+
+SYNOPSIS
+
+ htmlbook [<option>] <file>
+ htmlbook -h
+ htmlbook -v
+ htmlbook -L
+
+DESCRIPTION
+
+The program creates a HTML book structure in a specified output directory.
+Configuration is read from a project file specified on the command line.
+
+OPTIONS
+
+-i <encoding> | --input-encoding=<encoding>
+ Input encoding for project file to process.
+
+-o name[,name...]
+ Activate optional project file sections.
+
+-s name=value | --set=name=value
+ Set variables (overwrite variables from options section).
+
+-h | --help
+ Show help text.
+
+-v | --version
+ Show version information.
+
+-L | --license
+ Show license terms.
+
+EXIT STATUS
+
+0 on success, all other exit status codes indicate an error.
+
+FILES
+
+The project file contains project settings and information about the
+document structure (text files and used template files).
+
+Project file
+------------
+A project file consists of three sections: ``[options]'', ``[files]'', and
+``[contents]''. A project file can contain optional sections
+``[options:<name>]'', ``[files:<name>]'', and ``[contents:<name>]''. Optional
+sections are only processed when activated by the -o command line option.
+On Windows systems optional sections named ``windows'' are activated
+automatically, on non-Windows systems sections named ``non-windows'' are
+activated automatically.
+
+The options section contains ``key=value'' lines for the following keys:
+
+ output directory Name of output directory. This directory is
+ removed completely and created again each
+ time the output script is run.
+
+ output script Script to re-create the output directory and
+ copy files into it.
+
+ title Document or collection title.
+
+ url URL to access the document collection via web.
+
+ index file Name of file containing text for start page.
+
+ html charset Character set for output HTML files
+ (``us-ascii'', ``ascii'', or ``utf-8'').
+
+ template Name of default template file (``web.hbt'').
+
+ style Name of default style file (``style.css'').
+
+ page toc Flag: Create an intra-page table of contents.
+
+ create toc Flag: Create table of contents.
+
+ create index Flag: Create keyword index.
+
+ section numbers in index Flag: Write section numbers in index.
+
+ replace ampersand Flag: Replace ampersand in texts (no).
+
+ tidy Flag: Use tidy for inspection and correction
+ of HTML output files.
+
+ ln Flag: Use ln command instead of cp to save
+ disk space.
+
+ author Author name.
+
+ location Location of author.
+
+ write position Flag: Write position within the collection at
+ start of page.
+
+ section numbers in position Flag: Write section number in position.
+
+ shortcut icon URL to shortcut icon.
+
+ icon toc File names for icons in navigation bar.
+ icon previous
+ icon next
+ icon index
+
+ impressum link URL to impressum.
+
+ impressum page Name of text file for impressum (you can use
+ either impressum link or impressum page).
+
+ chm Flag: Create HTML to produce a CHM file later.
+
+ chm language Language setting for CHM project
+ (``0x409 English (USA)'').
+
+ js file File name of JavaScript file.
+
+ inherit js Flag: Inherit JavaScript files from parents.
+
+ var Set variable (the first text word on the
+ right side is the variable name, the
+ remainder of the line is the variable value).
+
+The ``[files]'' section lists the name of additional files to copy,
+one per line.
+
+The ``[contents]'' section contains the tree structure for navigation.
+Each subsection for a node is started by a title line.
+The indent level corresponds to the tree structure.
+Title lines with same indent level are neighbours (sub-nodes of the same
+parent node). A nodes parent node is the next node above the node with
+smaller indent.
+After the node title there are lines started by @ to configure the node:
+
+ file = <File> Text file for the nodes contents.
+ input encoding = <Encoding> Default encoding to use if no BOM is found.
+ suffix = <String> File name suffix for output file.
+ short = <Short title> Short title for use in the navigation menu.
+
+Additionally you can use the ``html charset'', ``template'', ``style'',
+``page toc'', ``write position'', ``replace ampersand'', ``tidy'', ``ln'',
+``author'', ``location'', ``js file'', ``inherit js'', ``var'',
+``icon toc'', ``icon previous'', ``icon next'', ``icon index'', and
+``shortcut icon'' settings as shown for the options section.
+
+Leafs (nodes without further subnodes) must have a text file configured,
+for other nodes it's optional.
+
+Template file
+-------------
+The template file specifies the text between <BODY> and </BODY>.
+Special commands %%command%% can be used to insert the text, the navigation
+menu, navigation blocks with clickable icons.
+The following special commands are available:
+
+ \%%contents%% Insert the text file contents.
+
+ \%%title%% Insert the node title.
+
+ \%%img <options>%% Insert an image. The following options
+ are available:
+ div[=bool] Create <div> around <img>
+ centered[=bool] Show image centered, not left-aligned.
+ src=file File name for image.
+ alt="text" Alternative text for image.
+ title[="text"] Title text (alt= is used as default).
+ caption[="text"] Image caption.
+ longdesc=URL File containing long description of image.
+ border=width Border width.
+ height=height Image height.
+ width=width Image width.
+ svg=file SVG version of image.
+ svgwh[=bool] Apply PNG/JPEG dimensions to SVG object.
+ object[=bool] Create object for SVG.
+ pdf=file PDF version of image.
+ larger=file Larger version of image.
+ ismap[=bool] Set ismap attribute.
+ usemap=file Image map file.
+ name=name Item name.
+ id=name ID for CSS styling.
+ class=name Class name for CSS styling.
+ align=name Alignment.
+ vspace=distance Vertical space.
+ hspace=distance Horizontal space.
+ downloads[=bool] Provide links to download vector graphics
+ cache Cache image dimensions for images used multiple
+ times. Image dimensions for images used in
+ a template are cached automatically.
+
+ \%%menu <options>%% Insert the navigation menu.
+ The following options are available:
+ style=... One from ``reverse'' (full menu in reverse
+ order), ``full'' (full menu), ``top'' (show
+ only first hierarchy level) or ``current''
+ (show only current hierarchy level).
+ sub[=bool] Flag: Show subnodes of current node.
+
+ \%%navigation <options>%% Insert a navigation block.
+ The following options are available:
+ itop=file Icon for table of contents (``toc.png'').
+ iprev=file Icon for previous section (``prev.png'').
+ inext=file Icon for next section (``next.png'').
+ ikind=file Icon for keyword index (``index.png'').
+
+ \%%author%% Insert the author name.
+
+ \%%location%% Insert the authors location.
+
+ \%%date <options>%% Insert the current node.
+ The following options are available:
+ style=name Date style, currently only ``german'' is
+ allowed to switch from the default
+ ``yyyy-mm-dd'' to ``dd.mm.yyyy''.
+
+ \%%var <name> <options>%% Insert a variable value.
+ The following options are available:
+ url[=bool] Flag: Encode as URL, not as text.
+
+ \%%code <options>%% Output encoding. By default the
+ ``<'', ``>'' are not replaced by ``&lt;'', and
+ ``&gt;'' as we expect to get correct HTML
+ from the text files. Replacement of ``&''
+ by ``&amp;'' is controlled by the
+ ``replace ampersand'' setting in the options
+ section.
+ In code mode our text comes from a source
+ code file, so we have to encode these
+ characters for HTML output.
+ The following options are available:
+ enable[=bool] Turn code mode on.
+ on[=bool] Turn code mode on.
+ disable[=bool] Turn code mode off.
+ off[=bool] Turn code mode off.
+ toggle Toggle code mode.
+
+ \%%a <options>%% Insert a named anchor or a hyperlink.
+ The following options are available:
+ name=name Anchor name.
+ href=URL Link destination.
+ title=``text'' Text to show when mouse is over link.
+ text=``text'' Text for hyperlink.
+ target=destination Destination windows or frame, i.e. ``_blank''.
+ type=text MIME type.
+ external[=bool] Override result of internal/external test.
+ id=text ID for CSS styling.
+ class=text Class name for CSS styling.
+ style=text Direct style information.
+ hreflang=text Language for href text.
+ charset=text Character set.
+ onblur=text Script to execute when link looses focus.
+ onfocus=text Script to execute when link gets focus.
+ accesskey=text Hotkey for link.
+ tabindex=number Tabulator index.
+ shape=text Link shape form.
+ coords=text Coordinates.
+ rel=text Information for link to next element.
+ rev=text Information for link to previous element.
+
+ \%%menuentry <options>%% Insert code to visualize a menu entry.
+ The following options are available:
+ item=``text'' Text of the menu entry, can be used
+ multiple times for hierarchical menus.
+
+ \%%sourcefile <options>%% Show a file contents in a <PRE></PRE>
+ environment and provide a download
+ hyperlink. The following options are available:
+ file=file File name.
+ type=text MIME type.
+ title=``text'' Text shown when mouse is over hyperlink.
+
+Text file
+---------
+Text files contain the page contents.
+You can use headings like
+ .1 @name@ Heading text
+for a structural document. Depths 1, 2, 3, 4, or 5 are converted to
+<h2>...<h6> headers. A <h1> header is used for the page title.
+The @name@ specification is optional, it results in a named anchor
+ <a name="name"></a>
+before the heading. If the name specification is omitted, an anchor name
+is generated automatically.
+
+Text files can use the special commands listed in ``Template file'', execpt
+\%%contents%%. Additionally the following special command can be used
+in text files:
+
+ \%%index <options>%% Add an entry to the keyword index.
+ The following options can be used:
+ text=``text'' Keyword.
+ name=``text'' Name of a named anchor.
+ reference[=bool] Flag: Use existing named anchor, do not
+ create an anchor.
+NOTES
+
+All text files, style files and images must be local files
+in the current working directory.
+
+AUTHOR
+
+Dirk krause
+
+COPYRIGHT AND LICENSE
+
+Run
+ htmlbook --license
+to see the license conditions.
+
+SEE ALSO
+
+tidy
+
+$!end
+};
+
+
+
+/** 8-bit character keywords.
+*/
+static char const * const hb_c8_kw[] = {
+$!string-table
+#
+# 0 1 Newline and space
+#
+\n
+
+#
+# 2 3 DOS command to remove directory
+#
+RD /S /Q "
+"\n
+#
+# 4 5 UNIX command to remove directory
+#
+rm -fr '
+'\n
+#
+# 6 DOS command to create a directory
+#
+MKDIR "
+#
+# 7 Unix command to create a directory
+#
+mkdir -p '
+#
+# 8 9
+#
+IF NOT EXIST "
+" ECHO ERROR File does not exist:
+#
+# 10 11 12 13
+#
+IF EXIST "
+" XCOPY "
+" "
+\\" /Y /Q\n
+#
+# 14 15 16 17 18
+#
+if [ -f '
+' ]\n
+then\n
+else\n
+fi\n
+#
+# 19 20 21
+#
+ln '
+cp '
+' '
+#
+# 22 23
+#
+echo 'ERROR: File
+ does not exist'\n
+#
+# 24 25 26
+#
+tidy -q -utf8 < "
+tidy -q -ascii < "
+" > "
+#
+# 27 28 29 30
+#
+tidy -q -utf8 < '
+tidy -q -ascii < '
+' > '
+/
+#
+# 31 32 33 34 35
+#
+@ECHO OFF\n
+\#! /bin/sh\n
+EXITCODE=0\n
+exit $EXITCODE\n
+EXITCODE=1\n
+#
+# 36
+#
+ECHO TIDY
+#
+# 37
+#
+echo TIDY
+#
+# 38 39
+#
+" DEL /Q "
+"\n
+#
+# 40 41 42
+#
+find '
+' -type d -exec chmod ugo+rx {} \\;\n
+' -type f -exec chmod ugo+r {} \\;\n
+$!end
+};
+
+
+
+/** Fixed keywords (not localized).
+*/
+static dkChar const * const hb_kwnl[] = {
+$!string-table macro=dkT
+#
+# 0: Program group name
+#
+dktools
+#
+# 1: String table file name
+#
+htmlbook.str
+#
+# 2: Help text file name.
+#
+htmlbook.txt
+#
+# 3: Configuration file name
+#
+htmlbook.conf
+#
+# 4: File name for TOC icon
+#
+toc.png
+#
+# 5: File name for previous section icon
+#
+prev.png
+#
+# 6: File name for next section icon
+#
+next.png
+#
+# 7: File name for index icon
+#
+index.png
+#
+# 8: Name of root node output file
+#
+index.html
+#
+# 9: Dot for file name suffix.
+#
+.
+#
+# 10: Default suffix.
+#
+html
+#
+# 11: Alternative date style
+#
+german
+#
+# 12: url keyword var special command
+#
+url
+#
+# 13: internal anchor for keyword index
+#
+\#hb_index
+#
+# 14 15 16 17 Icon file names for navigation
+#
+toc.png
+prev.png
+next.png
+index.png
+#
+# 18 19 Section names
+#
+windows
+non-windows
+#
+# 20 21 Protocols
+#
+http://
+ftp://
+#
+# 22 File open mode write
+#
+w
+#
+# 23 24
+#
+html
+htm
+#
+# 25 Switch back to standard encoding
+#
+none
+#
+# 26 Name of hhc.exe project file
+#
+project.hhp
+#
+# 27 Name of hhc.exe output file
+#
+index.chm
+#
+# 28 Name of hhc.exe contents file
+#
+contents.hhc
+#
+# 29 Name of hhc.exe index file
+#
+index.hhk
+#
+# 30 File open mode
+#
+wb
+#
+# 31 Anchor name for TOC
+#
+\#hb_toc
+#
+# 32 Long option to set variables
+#
+set
+#
+# 33 34
+#
+SVG
+PDF
+#
+# 35 (space)
+#
+
+#
+# 36 (index.xml file name for chmcmd)
+#
+project.xml
+#
+# 37 (icon file name for home button)
+#
+home.png
+$!end
+};
+
+
+
+/** Default message texts.
+*/
+static dkChar const * const hb_kw[] = {
+$!string-table macro=dkT
+#
+# 0: Title for impressum page
+#
+Impressum
+#
+# 1: Link title
+#
+Go to start page:
+#
+# 2: Link title
+#
+At start page.
+#
+# 3: Link title
+#
+Go to previous page:
+#
+# 4: Link title
+#
+At first page.
+#
+# 5: Link title
+#
+Go to next page:
+#
+# 6: Link title
+#
+At last page.
+#
+# 7: Link title
+#
+Go to keyword index.
+#
+# 8: Syntax error, missing =
+#
+Syntax error, missing "="!
+#
+# 9: Syntax error, empty value!
+#
+Syntax error, empty value!
+#
+# 10: Syntax error, only allowed in options section
+#
+Syntax error, setting only allowed in options section!
+#
+# 11: Syntax error, illegal character set
+#
+Syntax error, illegal character set!\nOnly "ascii" or "utf-8" allowed.
+#
+# 12: Syntax error, no path specification in file name allowed!
+#
+Syntax error, no path specification in file name allowed!
+#
+# 13: Missing project file name
+#
+Missing project file name!
+#
+# 14: Too many project files specified, just one allowed!
+#
+Too many project file specified, just one allowed!
+#
+# 15: No parent candidate found!
+#
+No parent candidate found (probably a bug)!
+#
+# 16
+#
+Syntax error, missing section name!
+#
+# 17
+#
+Syntax error, missing closing square bracket!
+#
+# 18
+#
+Syntax error, illegal section name!
+#
+# 19
+#
+No template for node!
+#
+# 20
+#
+Failed to obtain file name (probably a bug)!
+#
+# 21 22
+#
+String "
+" contains characters not usable in an URL!
+#
+# 23 Header External links
+#
+External links
+#
+# 24 Error: No source file
+#
+No source file specified!
+#
+# 25 26 Error: Illegal menu style
+#
+Syntax error, illegal menu style: "
+"!
+#
+# 27 ERROR: Illegal key
+#
+Syntax error, illegal key (attribute name): "
+#
+# 28 ERROR: Contents is allowed only in templates!
+#
+Syntax error, "%%contents%%" is only allowed in templates!
+#
+# 29 ERROR: Illegal special command
+#
+Syntax error, illegal special command: "
+#
+# 30 ERROR: Parsing failed
+#
+Syntax error, parsing special command failed near:\n"
+#
+# 31 ERROR: Line too long
+#
+Line too long:\n"
+#
+# 32
+#
+Syntax error, missing header text!
+#
+# 33
+#
+Syntax error, missing closing ``@''!
+#
+# 34
+#
+Syntax error, missing text after ``@''!
+#
+# 35
+#
+Syntax error, missing header level!
+#
+# 36
+#
+Syntax error, no text after leading ``.'' in line!
+#
+# 37
+#
+Header level corrected to allowed maximum 6!
+#
+# 38
+#
+Syntax error, ''url'' can be set in options section only!
+#
+# 39
+#
+Failed to process a special command!
+#
+# 40
+#
+Syntax error, parsing special command arguments failed!
+#
+# 41
+#
+Syntax error, too many items for menu entry!
+#
+# 42
+#
+Syntax error, no items for menu entry!
+#
+# 43 44
+#
+Syntax error, illegal configuration key: "
+"!
+#
+# 45
+#
+Table of contents
+#
+# 46
+#
+Keyword and key phrases index
+#
+# 47
+#
+No default topic found!
+#
+# 48
+#
+Missing ``text'' attribute!
+#
+# 49
+#
+Missing ``file'' attribute!
+#
+# 50
+#
+The ``index'' special command can not be used in template!
+#
+# 51
+#
+No destination file for link found!
+#
+# 52 53
+#
+No text node for title:\n"
+"!
+#
+# 54 55 56 57
+#
+Current position
+Page table of contents
+External links
+Table of contents
+#
+# 58 59
+#
+Large
+Image
+#
+# 60
+#
+Menu entry
+#
+# 61 Text "Impressum" used in the HTML head range link tag.
+#
+Impressum
+#
+# 62 Error message, unfinished command!
+#
+Unfinished ``%%'' command!
+#
+# 63 64
+#
+Not a backslash escape sequence: ``
+''!
+#
+# 65
+#
+Image
+#
+# 66
+#
+Overwriting ``div'' option by ``table''!
+#
+# 67 68
+#
+No output directory configured!
+No output script configured
+#
+# 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
+#
+Overwriting previous setting for ``author''!
+Overwriting previous setting for ``title''!
+Overwriting previous setting for ``output directory''!
+Overwriting previous setting for ``output script''!
+Overwriting previous setting for ``template''!
+Overwriting previous setting for ``style''!
+Overwriting previous setting for ``short''!
+Overwriting previous setting for ``file''!
+Overwriting previous setting for ``suffix''!
+Overwriting previous setting for ``icon toc''!
+Overwriting previous setting for ``icon previous''!
+Overwriting previous setting for ``icon next''!
+Overwriting previous setting for ``icon index''!
+Overwriting previous setting for ``shortcut icon''!
+Overwriting previous setting for ``var''!
+#
+# 84 85
+#
+File not found: "
+"!
+#
+# 86
+#
+Overwriting previous setting for ``file''!
+#
+# 87
+#
+Start page
+#
+# 88
+#
+Too many text lines, max. 999 allowed!
+#
+# 89 90
+#
+Syntax error, ignoring unexpected %%hint%% key \"
+"!
+#
+# 91
+#
+Syntax error, missing text for %%hint%%!
+#
+# 92
+#
+Syntax error, missing title for %%hint%%!
+#
+# 93 94
+#
+Go to table of contents:
+On start page.
+#
+# 95
+#
+Overwriting previous setting for ``icon home''!
+#
+# 96
+#
+Syntax error, value required!
+#
+# 97 98 99
+#
+Overwriting previous setting for ``meta description''!
+Overwriting previous setting for ``meta keywords''!
+Overwriting previous setting for ``location''!
+$!end
+};
+
+
+
+/** Section names in project files.
+*/
+static dkChar const * const hb_section_names[] = {
+$!string-table macro=dkT
+options
+files
+contents
+$!end
+};
+
+
+
+/** Accepted program options.
+*/
+static dk3_option_t const hb_options[] = {
+ { dkT('h'), dkT("help"), 0 },
+ { dkT('v'), dkT("version"), 0 },
+ { dkT('L'), dkT("license"), 0 },
+ { dkT('o'), dkT("optional-sections"), 1 },
+ { dkT('i'), dkT("input-encoding"), 1 }
+};
+
+/** Number of elements in the hb_options array.
+*/
+static size_t const hb_sz_options = sizeof(hb_options)/sizeof(dk3_option_t);
+
+
+
+/** Initialize job structure.
+ @param job Job structure to initialize.
+ @param app Application structure.
+ @param msg Localized keywords.
+ @param kwnl Keywords not localized.
+*/
+static
+void
+hb_job_init(
+ hb_job_t *job,
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *kwnl
+)
+{
+ $? "+ hb_job_init"
+ job->app = app;
+ job->msg = msg;
+ job->kwnl = kwnl;
+ job->opt = NULL;
+ job->s_nodes = NULL;
+ job->i_nodes = NULL;
+ job->s_pnodes = NULL;
+ job->i_pnodes = NULL;
+ job->s_files = NULL;
+ job->i_files = NULL;
+ job->s_index = NULL;
+ job->i_index = NULL;
+ job->s_optsect = NULL;
+ job->i_optsect = NULL;
+ job->s_imgdim = NULL;
+ job->i_imgdim = NULL;
+ job->rootnode = NULL;
+ job->currentnode = NULL;
+ job->impressumnode = NULL;
+ job->firstnode = NULL;
+ job->lastnode = NULL;
+ job->infilename = NULL;
+ job->outputdir = NULL;
+ job->outputscript = NULL;
+ job->url = NULL;
+ job->indexfile = NULL;
+ job->impressumlink = NULL;
+ job->chmlang = NULL;
+ job->shipbuffer = NULL;
+ job->iltemplate = NULL;
+ job->ilfile = NULL;
+ job->special = NULL;
+ job->buffer32 = NULL;
+ job->of = NULL;
+ job->lineno = 0UL;
+ job->nextobj = 0UL;
+ job->npobjs = 0UL;
+ job->spused = 0;
+ job->shipused = 0;
+ job->options = HB_JOB_OPT_CREATE_TOC;
+ job->options |= HB_JOB_OPT_NUM_IN_POS;
+ job->options |= HB_JOB_OPT_NUM_IN_IDX;
+ job->options |= HB_JOB_OPT_NUM_IN_PAGE_HEADER;
+ job->options |= HB_JOB_OPT_CODE_LINE_NUMBERS;
+ job->actsect = 1;
+ job->iecmd = -1; /* No input encoding specified */
+ job->bs = 0;
+ job->cmd = 0;
+ job->exv = 1; $? ". INIT"
+ job->cs = HB_CS_ASCII;
+ job->secttype = HB_SECTION_UNKNOWN;
+ job->non_url = 0;
+ job->maxdepth = 0;
+ job->coli = 0;
+ job->cols = HB_COLIST_NONE;
+#if DK3_SIZEOF_INT > 2
+#if Dk3_SIZEOF_INT > 4
+ job->headlevels = 9223372036854775807;
+#else
+ job->headlevels = 2147483647;
+#endif
+#else
+ job->headlevels = 32767;
+#endif
+ $? "- hb_job_init"
+}
+
+
+
+/** Clean up job structure at end of program.
+ @param job Job structure to clean up.
+*/
+static
+void
+hb_job_end(hb_job_t *job)
+{
+ hb_img_dim_t *idptr; /* Current image dimension cache entry */
+ hb_index_entry_t *ie; /* Current index entry */
+ hb_node_t *cn; /* Current node */
+ dkChar *cfn; /* Current file name */
+ $? "+ hb_job_end"
+ /* Release options.
+ */
+ if(job->opt) {
+ dk3opt_close(job->opt); job->opt = NULL;
+ }
+
+ /* The s_nodes component contains a list of all nodes.
+ We traverse this container to release all nodes.
+ */
+ if(job->s_nodes) {
+ if(job->i_nodes) {
+ dk3sto_it_reset(job->i_nodes);
+ while(NULL != (cn = (hb_node_t *)dk3sto_it_next(job->i_nodes))) {
+ hb_node_delete(cn);
+ }
+ dk3sto_it_close(job->i_nodes); job->i_nodes = NULL;
+ }
+ dk3sto_close(job->s_nodes); job->s_nodes = NULL;
+ }
+
+ if(job->s_imgdim) {
+ if(job->i_imgdim) {
+ dk3sto_it_reset(job->i_imgdim);
+ while(NULL != (idptr = (hb_img_dim_t *)dk3sto_it_next(job->i_imgdim))) {
+ hbimgdim_delete(idptr);
+ }
+ dk3sto_it_close(job->i_imgdim);
+ }
+ dk3sto_close(job->s_imgdim);
+ } job->s_imgdim = NULL; job->i_imgdim = NULL;
+
+ if(job->s_optsect) {
+ if(job->i_optsect) {
+ dk3sto_it_reset(job->i_optsect);
+ while(NULL != (cfn = (dkChar *)dk3sto_it_next(job->i_optsect))) {
+ $? ". releasing optional section \"%!ds\"", TR_STR(cfn)
+ dk3_release(cfn);
+ }
+ dk3sto_it_close(job->i_optsect);
+ }
+ dk3sto_close(job->s_optsect);
+ }
+ job->s_optsect = NULL; job->i_optsect = NULL;
+
+ if(job->s_index) {
+ if(job->i_index) {
+ dk3sto_it_reset(job->i_index);
+ while(NULL != (ie = (hb_index_entry_t *)dk3sto_it_next(job->i_index))) {
+ hbindex_delete(ie);
+ }
+ dk3sto_it_close(job->i_index);
+ }
+ dk3sto_close(job->s_index);
+ }
+ job->s_index = NULL; job->i_index = NULL;
+
+ /* We must free the list of additional files.
+ */
+ if(job->s_files) {
+ if(job->i_files) {
+ dk3sto_it_reset(job->i_files);
+ while(NULL != (cfn = (dkChar *)dk3sto_it_next(job->i_files))) {
+ $? ". release file name \"%!ds\"", cfn
+ dk3_release(cfn);
+ }
+ dk3sto_it_close(job->i_files); job->i_files = NULL;
+ }
+ dk3sto_close(job->s_files); job->s_files = NULL;
+ }
+
+ /* The s_pnodes component contains a list of the leaf nodes
+ only (nodes to produce output for).
+ We already traversed s_nodes to release all the nodes, so
+ we can simply close s_pnodes and i_pnodes here.
+ */
+ if(job->s_pnodes) {
+ if(job->i_pnodes) {
+ dk3sto_it_close(job->i_pnodes);
+ }
+ dk3sto_close(job->s_pnodes); job->s_pnodes = NULL;
+ }
+
+ /* Release components allocated dynamically.
+ */
+ dk3_release(job->outputdir);
+ dk3_release(job->outputscript);
+ dk3_release(job->url);
+ dk3_release(job->impressumlink);
+ dk3_release(job->chmlang);
+ dk3_release(job->indexfile);
+ dk3_release(job->shipbuffer);
+ dk3_release(job->iltemplate);
+ dk3_release(job->ilfile);
+ dk3_release(job->special);
+ dk3_release(job->buffer32);
+
+ job->impressumnode = NULL;
+ $? "- hb_job_end"
+}
+
+
+
+/** Save names of optional sections to process.
+ @param job Job structure.
+ @param sections Section names.
+ @return 1 on success, 0 on errors.
+*/
+static
+int
+hb_save_optional_sections(hb_job_t *job, dkChar const *sections)
+{
+ dkChar bu[1024]; /* Private copy of sections */
+ dkChar *p1; /* Current section name */
+ dkChar *p2; /* Next section name */
+ dkChar *p3; /* Copy of current section for storage */
+ int back = 0; /* Result */
+ $? "+ hb_save_optional_sections \"%!ds\"", TR_STR(sections)
+ if((job) && (sections)) {
+ if(dk3str_len(sections) < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy(bu, sections);
+ back = 1; $? ". back = 1"
+ p1 = dk3str_start(bu, NULL);
+ while(p1) {
+ p2 = dk3str_chr(p1, dkT(','));
+ if(p2) {
+ *(p2++) = dkT('\0');
+ p2 = dk3str_start(p2, NULL);
+ }
+ dk3str_chomp(p1, NULL);
+ $? ". saving optional section \"%!ds\"", p1
+ p3 = dk3str_dup_app(p1, job->app);
+ if(p3) {
+ if(!dk3sto_add(job->s_optsect, p3)) {
+ dk3_release(p3);
+ back = 0; /* REPORTED */ $? ". back = 0"
+ }
+ } else {
+ back = 0; /* REPORTED */ $? ". back = 0"
+ }
+ p1 = p2;
+ }
+ } else {
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 135, 136, sections);
+ }
+ } $? "- hb_save_optional_sections %d", back
+ return back;
+}
+
+
+
+/** Process command line options.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hb_process_options(hb_job_t *job)
+{
+ dkChar const *optarg; /* Option argument */
+ int back = 0;
+ job->opt = dk3opt_open_from_app(
+ hb_options, hb_sz_options, dkT('s'), hb_kwnl[32], job->app
+ );
+ if(job->opt) {
+ if(0 == dk3opt_get_error_code(job->opt)) {
+ back = 1;
+ if(dk3opt_is_set(job->opt, dkT('h'))) {
+ job->cmd |= HB_CMD_HELP;
+ }
+ if(dk3opt_is_set(job->opt, dkT('v'))) {
+ job->cmd |= HB_CMD_VERSION;
+ }
+ if(dk3opt_is_set(job->opt, dkT('L'))) {
+ job->cmd |= HB_CMD_LICENSE;
+ }
+ if(0 == (job->cmd)) {
+ if(dk3opt_is_set(job->opt, dkT('i'))) {
+ optarg = dk3opt_get_short_arg(job->opt, dkT('i'));
+ if(optarg) {
+ job->iecmd = dk3enc_get_text_encoding_app(optarg, job->app);
+ if(0 > job->iecmd) { job->iecmd = -1; }
+ }
+ }
+ if(1 > dk3opt_get_num_args(job->opt)) { $? "! no project"
+ /* ERROR: No project file specified! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 13);
+ back = 0;
+ } else {
+ if(1 < dk3opt_get_num_args(job->opt)) { $? "! too many"
+ /* WARNING: Too many project files, using just one! */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 14);
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Print help text, version information or license terms.
+ @param job Job structure.
+*/
+static
+void
+hb_help_version_license(hb_job_t *job)
+{
+ dkChar const * const *ptr; /* Current line to print */
+ $? "+ hb_help_version_license"
+ /* Show version
+ */
+ dk3sf_initialize_stdout();
+ dk3sf_fputs(hb_version[0], stdout);
+ dk3sf_fputs(hb_version[1], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+
+ if(HB_CMD_LICENSE & (job->cmd)) {
+ /* Show license
+ */
+ ptr = hb_license;
+ while(*ptr) {
+ dk3sf_fputs(*(ptr++), stdout); dk3sf_fputc(dkT('\n'), stdout);
+ }
+ }
+ if(HB_CMD_HELP & (job->cmd)) {
+ /* Show help
+ */
+ dk3app_help(job->app, hb_kwnl[2], hb_help_text);
+ }
+ job->exv = 0; $? ". SUCCESS"
+ $? "- hb_help_version_license"
+}
+
+
+
+/** Compare two file names.
+ @param l Left pointer.
+ @param r Right pointer.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+static
+int
+hb_file_name_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ $? "+ hb_file_name_compare PTR=%d PTR=%d", TR_IPTR(l), TR_IPTR(r)
+ if(l) {
+ if(r) {
+ back = dk3str_fncmp((dkChar const *)l, (dkChar const *)r);
+ if(-1 > back) { back = -1; }
+ if( 1 < back) { back = 1; }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ } $? "- hb_file_name_compare %d", back
+ return back;
+}
+
+
+
+/** Compare two strings.
+ @param l Left string.
+ @param r Right string.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+static
+int
+hb_compare_strings(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ $? "+ hb_compare_strings PTR=%d PTR=%d", TR_IPTR(l), TR_IPTR(r)
+ if(l) {
+ if(r) {
+ back = dk3str_cmp((dkChar const *)l, (dkChar const *)r);
+ if(-1 > back) { back = -1; }
+ if( 1 < back) { back = 1; }
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ } $? "- hb_compare_strings %d", back
+ return back;
+}
+
+
+
+/** Allocate memory for job structure.
+ @param job Job structure to initialize.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hb_job_allocate(hb_job_t *job)
+{
+ int back = 0;
+ $? "+ hb_job_allocate"
+ job->s_nodes = dk3sto_open_app(job->app);
+ if(job->s_nodes) {
+ dk3sto_set_comp(job->s_nodes, hb_node_compare, 0);
+ job->i_nodes = dk3sto_it_open(job->s_nodes);
+ if(job->i_nodes) {
+ job->s_pnodes = dk3sto_open_app(job->app);
+ if(job->s_pnodes) {
+ dk3sto_set_comp(job->s_pnodes, hb_node_compare, 0);
+ job->i_pnodes = dk3sto_it_open(job->s_pnodes);
+ if(job->i_pnodes) {
+ job->rootnode = hb_node_new(job, NULL, 0UL, 0UL, -1);
+ job->nextobj += 1UL;
+ if(job->rootnode) {
+ (job->rootnode)->depth = 0;
+ if(dk3sto_add(job->s_nodes, job->rootnode)) {
+ job->currentnode = job->rootnode;
+ job->shipbuffer = dk3_new_app(dkChar,HB_LINE_LENGTH,job->app);
+ job->iltemplate = dk3_new_app(dkChar,HB_LINE_LENGTH,job->app);
+ job->ilfile = dk3_new_app(dkChar,HB_LINE_LENGTH,job->app);
+ job->special = dk3_new_app(dkChar,HB_LINE_LENGTH,job->app);
+ job->buffer32 = dk3_new_app(dk3_c32_t,HB_LINE_LENGTH,job->app);
+ job->bs = HB_LINE_LENGTH;
+ job->spused = 0;
+ if(job->iltemplate) {
+ if(job->ilfile) {
+ if(job->special) {
+ if(job->buffer32) {
+ if(job->shipbuffer) {
+ job->s_files = dk3sto_open_app(job->app);
+ if(job->s_files) {
+ dk3sto_set_comp(job->s_files,hb_file_name_compare,0);
+ job->i_files = dk3sto_it_open(job->s_files);
+ if(job->i_files) {
+ if(dk3sto_add(job->s_pnodes, job->rootnode)) {
+ back = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } else {
+ hb_node_delete(job->rootnode);
+ job->rootnode = NULL;
+ }
+ }
+ }
+ }
+ }
+ }
+ if(back) {
+ back = 0;
+ job->s_index = dk3sto_open_app(job->app);
+ if(job->s_index) {
+ dk3sto_set_comp(job->s_index, hbindex_compare, 0);
+ job->i_index = dk3sto_it_open(job->s_index);
+ if(job->i_index) {
+ job->s_optsect = dk3sto_open_app(job->app);
+ if(job->s_optsect) {
+ dk3sto_set_comp(job->s_optsect, hb_compare_strings, 0);
+ job->i_optsect = dk3sto_it_open(job->s_optsect);
+ if(job->i_optsect) {
+ job->s_imgdim = dk3sto_open_app(job->app);
+ if(job->s_imgdim) {
+ dk3sto_set_comp(job->s_imgdim, hbimgdim_compare, 0);
+ job->i_imgdim = dk3sto_it_open(job->s_imgdim);
+ if(job->i_imgdim) {
+ back = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ } $? "- hb_job_allocate %d", back
+ return back;
+}
+
+
+
+#if 0
+/** Add one file to file list.
+ @param job Job structure.
+ @param il Input line to process, contains file name.
+ @return 1 on success, -1 on error.
+*/
+static
+int
+hb_add_file_to_file_list(hb_job_t *job, dkChar *il)
+{
+#if VERSION_BEFORE_20131207
+ dkChar *p1; /* Start of line */
+ dkChar *p2; /* Allocated memory */
+ int back = 1;
+ p1 = dk3str_start(il, NULL);
+ if(p1) {
+ dk3str_chomp(p1, NULL);
+ if(!(dk3sto_it_find_like(job->i_files, (void const *)il, 0))) {
+ p2 = dk3str_dup_app(il,job->app);
+ if(p2) {
+ if(!(dk3sto_add(job->s_files, (void *)p2))) {
+ back = -1;
+ dk3_release(p2);
+ }
+ } else {
+ back = -1;
+ }
+ }
+ }
+ return back;
+#else
+ return(hbtool_add_file(job,il));
+#endif
+}
+#endif
+
+
+
+/** Find indent level.
+ @param il Input line to process.
+ @return Number of leading spaces.
+*/
+static
+int
+hb_find_indent(dkChar *il)
+{
+ dkChar *p1; /* Traverse text line */
+ int back = 0;
+ $? "+ hb_find_indent \"%!ds\"", TR_STR(il)
+ p1 = il;
+ while((dkT(' ') == *p1) || (dkT('\t') == *p1)) {
+ back++;
+ if(dkT('\t') == *p1) {
+ while(back % 8) { back++; }
+ }
+ p1++;
+ } $? "- hb_find_indent %d", back
+ return back;
+}
+
+
+
+/** Find parent candidate for new node.
+ @param current Current node to edit.
+ @param indent Indent of new node.
+ @return Pointer to node on success, NULL on error.
+*/
+static
+hb_node_t *
+hb_parent_candidate(hb_node_t *current, int indent)
+{
+ hb_node_t *back = NULL;
+ hb_node_t *ca; /* Candidate node */
+ int cc; /* Flag: Can continue */
+ $? "+ hb_parent_candidate"
+ ca = current;
+ cc = 1;
+ while(cc) {
+ if(ca) {
+ if((ca->indent) < indent) {
+ back = ca;
+ cc = 0;
+ } else {
+ ca = ca->parent;
+ }
+ } else {
+ cc = 0;
+ }
+ } $? "- hb_parent_candidate PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/** Process a line from the contents section.
+ @param job Job structure.
+ @param il Input line.
+ @return 1 on success, -1 on error.
+*/
+static
+int
+hb_add_contents(hb_job_t *job, dkChar *il)
+{
+ hb_node_t *pa; /* Parent node for new node */
+ hb_node_t *nn; /* New node */
+ dkChar *p1; /* Start of text line */
+ int indent; /* Indent level */
+ int back = 1;
+ $? "+ hb_add_contents \"%!ds\"", TR_STR(il)
+ p1 = dk3str_start(il, NULL);
+ if(p1) {
+ if(dkT('@') == *p1) {
+ p1++;
+ back = hbconf_process_line(job, p1, HB_SECTION_CONTENTS);
+ } else {
+ /* Create new node. */
+ indent = hb_find_indent(il);
+ pa = hb_parent_candidate(job->currentnode, indent);
+ if(pa) {
+ nn = hb_node_new(job, pa, job->lineno, job->nextobj, indent);
+ job->nextobj += 1UL;
+ if(nn) {
+ if(nn->depth > job->maxdepth) { job->maxdepth = nn->depth; }
+ if(dk3sto_add(job->s_nodes, (void *)nn)) {
+ if(dk3sto_add(pa->s_subnodes, (void *)nn)) {
+ job->currentnode = nn;
+ nn->title = dk3str_dup_app(p1,job->app);
+ if(!(nn->title)) {
+ back = -1; /* REPORTED */
+ }
+ } else {
+ back = -1; /* REPORTED */
+ }
+ } else {
+ back = -1; /* REPORTED */
+ hb_node_delete(nn);
+ }
+ } else {
+ back = -1; /* REPORTED */
+ }
+ } else {
+ back = -1;
+ /* ERROR: No parent candidate found! */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 15);
+ }
+ }
+ } $? "- hb_add_contents %d", back
+ return back;
+}
+
+
+
+/** Process one line from project file.
+ @param job Job structure.
+ @param il Input line to process.
+ @return 1 on success, 0 on minor errors, -1 on fatal errors.
+*/
+static
+int
+hb_process_line(hb_job_t *job, dkChar *il)
+{
+ dkChar *p1; /* Start of line */
+ dkChar *p2; /* Next pointer */
+ int back = 1; /* Result */
+ int newst = HB_SECTION_UNKNOWN; /* New section type */
+ $? "+ hb_process_line \"%!ds\"", TR_STR(il)
+ job->lineno += 1UL;
+ p1 = dk3str_start(il, NULL);
+ if(p1) {
+ dk3str_chomp(p1,NULL);
+ if(dkT('#') != *p1) {
+ if(dkT('[') == *p1) {
+ job->actsect = 1;
+ job->secttype = HB_SECTION_UNKNOWN;
+ p1++;
+ p1 = dk3str_start(p1, NULL);
+ if(p1) {
+ p2 = dk3str_chr(p1, dkT(']'));
+ if(p2) {
+ *p2 = dkT('\0');
+ dk3str_chomp(p1, NULL);
+ p2 = dk3str_chr(p1, dkT(':'));
+ if(p2) {
+ *(p2++) = dkT('\0');
+ p2 = dk3str_start(p2, NULL);
+ dk3str_chomp(p2, NULL);
+ dk3str_chomp(p1, NULL);
+ }
+ newst = dk3str_array_index(hb_section_names, p1, 0);
+ if(0 <= newst) {
+ job->secttype = 1 + newst;
+ } else {
+ /* ERROR: Syntax (unknown section name) */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 18);
+ }
+ if(p2) {
+ if(!dk3sto_it_find_like(job->i_optsect, p2, 0)) {
+ job->actsect = 0;
+#if DK3_ON_WINDOWS
+ if(0 == dk3str_cmp(p2, (job->kwnl)[18])) {
+ job->actsect = 1;
+ }
+#else
+ if(0 == dk3str_cmp(p2, (job->kwnl)[19])) {
+ job->actsect = 1;
+ }
+#endif
+ }
+ }
+ } else {
+ /* ERROR: Syntax (missing closing bracket) */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 17);
+ }
+ } else {
+ /* ERROR: Syntax (no text in bracket) */
+ back = -1;
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 16);
+ }
+ } else {
+ if(job->actsect) {
+ switch(job->secttype) {
+ case HB_SECTION_OPTIONS: {
+ back = hbconf_process_line(job, il, HB_SECTION_OPTIONS);
+ } break;
+ case HB_SECTION_FILES: {
+ back = hbtool_add_file(job, il);
+ } break;
+ case HB_SECTION_CONTENTS: {
+ back = hb_add_contents(job, il);
+ } break;
+ }
+ }
+ }
+ }
+ } $? "- hb_process_line %d", back
+ return back;
+}
+
+
+
+/** Line handler to process one line from project file.
+ @param obj Object to save data.
+ @param il Input line to process.
+ @return 1 on success, 0 on minor errors, -1 on fatal errors.
+*/
+static
+int
+hb_line_reader_handler(void *obj, dkChar *il)
+{
+ int back;
+ $? "+ hb_line_reader_handler"
+ back = hb_process_line((hb_job_t *)obj, il);
+ $? "- hb_line_reader_handler %d", back
+ return back;
+}
+
+
+
+/** Process command line variables, overwrite settings from
+ options section in project file.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hb_read_variables(hb_job_t *job)
+{
+ dkChar bu[1024]; /* Buffer for modification */
+ dk3_key_value_t *kvp; /* New key value pair */
+ dkChar const *optstr; /* Option string */
+ dkChar *p1; /* Start of option string (key) */
+ dkChar *p2; /* Start of value */
+ dkChar *p3; /* Copy of value */
+ int back = 1;
+ int nfo; /* Number of further arguments */
+ int i; /* Index of current argument */
+
+ if(0 < (nfo = dk3opt_get_num_fo(job->opt))) {
+ for(i = 0; i < nfo; i++) {
+ optstr = dk3opt_get_fo(job->opt, i);
+ if(optstr) {
+ if(dk3str_len(optstr) < DK3_SIZEOF(bu,dkChar)) {
+ dk3str_cpy(bu, optstr);
+ p1 = dk3str_start(bu, NULL);
+ if(p1) {
+ p2 = dk3str_chr(p1, dkT('='));
+ if(p2) {
+ *(p2++) = dkT('\0');
+ p2 = dk3str_start(p2, NULL);
+ }
+ if(p2) {
+ dk3str_chomp(p1, NULL);
+ dk3str_chomp(p2, NULL);
+ kvp = dk3sto_it_find_like(
+ (job->rootnode)->i_variables, p1, 1
+ );
+ if(kvp) {
+ p3 = dk3str_dup_app(p2, job->app);
+ if(p3) {
+ dk3_release(kvp->val);
+ kvp->val = p3;
+ } else {
+ back = 0;
+ }
+ } else {
+ kvp = dk3kv_new_app(p1, p2, job->app);
+ if(kvp) {
+ if(!dk3sto_add((job->rootnode)->s_variables, kvp)) {
+ dk3kv_delete(kvp);
+ back = 0;
+ }
+ } else {
+ back = 0;
+ }
+ }
+ } else {
+ kvp = dk3sto_it_find_like(
+ (job->rootnode)->i_variables, p1, 1
+ );
+ if(kvp) {
+ dk3sto_remove((job->rootnode)->s_variables, kvp);
+ dk3kv_delete(kvp);
+ }
+ }
+ } else {
+ /* Empty string is ok */
+ }
+ } else {
+ /* ERROR: String too long! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 135, 136, optstr);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Read the project file.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hb_read_project(hb_job_t *job)
+{
+ int back = 0;
+ int inenc; /* Input encoding */
+ $? "+ hb_read_project"
+ inenc = dk3app_get_input_file_encoding(job->app);
+ if(0 <= job->iecmd) { inenc = job->iecmd; }
+ back = dk3stream_process_filename_lines_app(
+ (void *)job, hb_line_reader_handler, job->infilename,
+ job->ilfile, job->bs,
+ dk3app_get_encoding(job->app),
+ inenc,
+ job->app
+ );
+ if(!hb_read_variables(job)) {
+ back = 0;
+ }
+ if((job->options) & HB_JOB_OPT_CHM) {
+ job->cs = HB_CS_ASCII;
+ }
+ if(1 != back) { back = 0; }
+ $? "- hb_read_project %d", back
+ return back;
+}
+
+
+
+/** Write all HTML files for the project.
+ @param job Job structure.
+*/
+static
+void
+hb_write_html_files(hb_job_t *job)
+{
+#if VERSION_BEFORE_20131206
+ hb_node_t *nptr;
+ $? "+ hb_write_html_files"
+ dk3sto_it_reset(job->i_pnodes);
+ while(NULL != (nptr = (hb_node_t *)dk3sto_it_next(job->i_pnodes))) {
+ $? ". node \"%!ds\"", TR_STR(nptr->title)
+ if(0UL != nptr->objno) { $? ". must write"
+ hbhtml_write_file(job, nptr);
+ }
+ } $? "- hb_write_html_files"
+#else
+ hb_node_t *c;
+ hb_node_t *p;
+ hb_node_t *n;
+ $? "+ hb_write_html_files"
+ p = c = n = NULL;
+ dk3sto_it_reset(job->i_pnodes);
+ c = dk3sto_it_next(job->i_pnodes);
+ while(c) {
+ n = dk3sto_it_next(job->i_pnodes);
+ if(0UL != c->objno) {
+ hbhtml_write_file(job, c, p, n);
+ }
+ p = c;
+ c = n;
+ }
+ $? "- hb_write_html_files"
+#endif
+}
+
+
+
+/** Write index html file.
+ @param job Job structure.
+*/
+static
+void
+hb_write_index(hb_job_t *job)
+{
+ hb_node_t *n; /* Current index item */
+ $? "+ hb_write_index"
+ dk3sto_it_reset(job->i_pnodes);
+ if(dk3sto_it_next(job->i_pnodes)) {
+ n = (hb_node_t *)dk3sto_it_next(job->i_pnodes);
+ if(n) {
+ hbhtml_write_file(job, job->rootnode, NULL, n);
+ } else {
+/* 2014/02/05 We now allow an empty contents section to
+ produce just one file index.html.
+*/
+#if VERSION_BEFORE_20140205
+ job->exv = 1; $? "! ERROR"
+#else
+ hbhtml_write_file(job, job->rootnode, NULL, n);
+#endif
+ }
+ } else {
+ job->exv = 1; $? "! ERROR"
+ } $? "- hb_write_index"
+}
+
+
+
+#if TRACE_DEBUG && (DK3_CHAR_SIZE == 1)
+/** Show document tree structure at a node recursively.
+ @param job Job structure.
+ @param nptr Current node to show.
+ @param l Indent level.
+*/
+static
+void
+hb_show_tree_node(hb_job_t *job, hb_node_t *nptr, int l)
+{
+ hb_node_t *hbptr;
+ int i;
+ if(dktrace_file()) {
+ fputs("> ", dktrace_file());
+ for(i = 0; i < l; i++) {
+ fputs(" ", dktrace_file());
+ }
+ fputs(nptr->title, dktrace_file());
+ if(nptr->shorttitle) {
+ fputs(" (", dktrace_file());
+ fputs(nptr->shorttitle, dktrace_file());
+ fputs(")", dktrace_file());
+ }
+ fprintf(dktrace_file(), " depth=%d", nptr->depth);
+ fputc('\n', dktrace_file());
+ dk3sto_it_reset(nptr->i_subnodes);
+ while(NULL != (hbptr = (hb_node_t *)dk3sto_it_next(nptr->i_subnodes))) {
+ hb_show_tree_node(job, hbptr, (l+1));
+ }
+ }
+}
+
+/** Show document tree structure.
+ @param job Job structure.
+*/
+static
+void
+hb_show_structure(hb_job_t *job)
+{
+ hb_show_tree_node(job, job->rootnode, 0);
+}
+#endif
+
+
+
+#if (DK3_ON_WINDOWS) || (DK3_CHAR_SIZE > 1)
+/** Write file name to output file, ANSI encoded.
+ Set exit status code on error.
+ @param job Job structure.
+ @param fn File name.
+*/
+static
+void
+hb_write_ansi_filename(hb_job_t *job, dkChar const *fn)
+{
+ $? "+ hb_write_ansi_filename \"%!ds\"", TR_STR(fn)
+ if(!dk3se_ansi_fputs(fn, dk3app_get_encoding(job->app), job->of, job->app)) {
+ job->exv = 1;
+ } $? "- hb_write_ansi_filename"
+}
+#endif
+
+
+#if !DK3_ON_WINDOWS
+/** Write a file name.
+ @param job Job structure.
+ @param fn File name to write.
+*/
+static
+void
+hb_write_filename(hb_job_t *job, dkChar const *fn)
+{
+#if DK3_CHAR_SIZE > 1
+ hb_write_ansi_filename(job, fn);
+#error "Not implemented!"
+#else
+ if(EOF == fputs(fn, job->of)) {
+ job->exv = 1;
+ /* ERROR: Write attempt failed! */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 120);
+ }
+#endif
+}
+#endif
+
+
+
+/** Check whether the output file for a node is a HTML file.
+ @param nptr Node to check.
+ @return 1 for HTML files, 0 otherwise.
+*/
+static
+int
+hb_htfile(hb_node_t *nptr)
+{
+ int back = 1;
+ $? "+ hb_htfile"
+ if(nptr->suffix) {
+ back = 0;
+ if(dk3str_fncmp(nptr->suffix, hb_kwnl[23]) == 0) { back = 1; }
+ if(dk3str_fncmp(nptr->suffix, hb_kwnl[24]) == 0) { back = 1; }
+ } $? "- hb_htfile %d", back
+ return back;
+}
+
+
+
+/** Write instruction to copy one file to script.
+ @param job Job structure.
+ @param fn File name.
+*/
+static
+void
+hb_write_script_copy_file(hb_job_t *job, dkChar const *fn)
+{
+#if DK3_ON_WINDOWS
+ fputs(hb_c8_kw[8], job->of);
+ hb_write_ansi_filename(job, fn);
+ fputs(hb_c8_kw[9], job->of);
+ hb_write_ansi_filename(job, fn);
+ fputs(hb_c8_kw[0], job->of);
+ fputs(hb_c8_kw[10], job->of);
+ hb_write_ansi_filename(job, fn);
+ fputs(hb_c8_kw[11], job->of);
+ hb_write_ansi_filename(job, fn);
+ fputs(hb_c8_kw[12], job->of);
+ hb_write_ansi_filename(job, job->outputdir);
+ fputs(hb_c8_kw[13], job->of);
+#else
+ fputs(hb_c8_kw[14], job->of); /* if */
+ hb_write_filename(job, fn);
+ fputs(hb_c8_kw[15], job->of); /* then */
+ fputs(hb_c8_kw[16], job->of); /* else */
+ if((job->options) & HB_JOB_OPT_LN) {
+ fputs(hb_c8_kw[19], job->of);
+ } else {
+ fputs(hb_c8_kw[20], job->of);
+ }
+ hb_write_filename(job, fn);
+ fputs(hb_c8_kw[21], job->of);
+ hb_write_filename(job, job->outputdir);
+ fputs(hb_c8_kw[5], job->of);
+ fputs(hb_c8_kw[17], job->of); /* fi */
+ fputs(hb_c8_kw[22], job->of);
+ hb_write_filename(job, fn);
+ fputs(hb_c8_kw[23], job->of);
+ fputs(hb_c8_kw[35], job->of);
+ fputs(hb_c8_kw[18], job->of);
+#endif
+}
+
+
+
+/** Write the output script.
+ Set exit status code on errors.
+ @param job Job structure.
+*/
+static
+void
+hb_write_script(hb_job_t *job)
+{
+ dkChar of[DK3_MAX_PATH]; /* Output file name */
+ hb_node_t *nptr; /* Current print node */
+ dkChar const *fn; /* Current resource file name */
+ $? "+ hb_write_script"
+ if(job->outputscript) {
+ if(job->outputdir) {
+ job->of = dk3sf_fopen_app(job->outputscript, hb_kwnl[22], job->app);
+ if(job->of) {
+ /* Start of file
+ */
+#if DK3_ON_WINDOWS
+ fputs(hb_c8_kw[31], job->of);
+#else
+ fputs(hb_c8_kw[32], job->of);
+ fputs(hb_c8_kw[33], job->of);
+#endif
+ /* Remove existing directory completely.
+ */
+#if DK3_ON_WINDOWS
+ fputs(hb_c8_kw[2], job->of);
+ hb_write_ansi_filename(job, job->outputdir);
+ fputs(hb_c8_kw[3], job->of);
+#else
+ fputs(hb_c8_kw[4], job->of);
+ hb_write_filename(job, job->outputdir);
+ fputs(hb_c8_kw[5], job->of);
+#endif
+ /* Create new directory.
+ */
+#if DK3_ON_WINDOWS
+ fputs(hb_c8_kw[6], job->of);
+ hb_write_ansi_filename(job, job->outputdir);
+ fputs(hb_c8_kw[5], job->of);
+#else
+ fputs(hb_c8_kw[7], job->of);
+ hb_write_filename(job, job->outputdir);
+ fputs(hb_c8_kw[5], job->of);
+#endif
+ /* Copy resource files.
+ */
+ dk3sto_it_reset(job->i_files);
+ while(NULL != (fn = (dkChar const *)dk3sto_it_next(job->i_files))) {
+ /* 2014-04-17
+ Writinig the file copy instruction is now in the
+ hb_write_script_copy_file() function.
+ */
+ hb_write_script_copy_file(job, fn);
+ }
+ /* For CHM projects copy index.hhp, index.hhc and index.hhk
+ */
+ if ((job->options) & HB_JOB_OPT_CHM) {
+ hb_write_script_copy_file(job, hb_kwnl[36]);
+ hb_write_script_copy_file(job, hb_kwnl[26]);
+ hb_write_script_copy_file(job, hb_kwnl[28]);
+ if ((job->options) & HB_JOB_OPT_CREATE_INDEX) {
+ if (hbchm_have_index_entries(job)) {
+ hb_write_script_copy_file(job, hb_kwnl[29]);
+ }
+ }
+ }
+ /* Copy HTML files, use tidy if available.
+ */
+ dk3sto_it_reset(job->i_pnodes);
+ while(NULL != (nptr = (hb_node_t *)dk3sto_it_next(job->i_pnodes))) {
+ if(hbhtml_create_output_filename(of,DK3_SIZEOF(of,dkChar),job,nptr))
+ {
+ fn = of;
+#if DK3_ON_WINDOWS
+ /* Remove existing file.
+ */
+ fputs(hb_c8_kw[10], job->of);
+ hb_write_ansi_filename(job, job->outputdir);
+ fputc('\\', job->of);
+ hb_write_ansi_filename(job, fn);
+ fputs(hb_c8_kw[38], job->of);
+ hb_write_ansi_filename(job, job->outputdir);
+ fputc('\\', job->of);
+ hb_write_ansi_filename(job, fn);
+ fputs(hb_c8_kw[39], job->of);
+ /* Use tidy or xcopy to bring new file in place.
+ */
+ fputs(hb_c8_kw[8], job->of);
+ hb_write_ansi_filename(job, fn);
+ fputs(hb_c8_kw[9], job->of);
+ hb_write_ansi_filename(job, fn);
+ fputs(hb_c8_kw[0], job->of);
+ if(((nptr->options) & HB_NODE_OPT_USE_TIDY) && (hb_htfile(nptr))) {
+ fputs(hb_c8_kw[36], job->of);
+ hb_write_ansi_filename(job, fn);
+ fputs(hb_c8_kw[0], job->of);
+ if(HB_CS_UTF_8 == job->cs) {
+ fputs(hb_c8_kw[24], job->of);
+ hb_write_ansi_filename(job, fn);
+ fputs(hb_c8_kw[26], job->of);
+ hb_write_ansi_filename(job, job->outputdir);
+ fputc('\\', job->of);
+ hb_write_ansi_filename(job, fn);
+ fputs(hb_c8_kw[3], job->of);
+ } else {
+ fputs(hb_c8_kw[25], job->of);
+ hb_write_ansi_filename(job, fn);
+ fputs(hb_c8_kw[26], job->of);
+ hb_write_ansi_filename(job, job->outputdir);
+ fputc('\\', job->of);
+ hb_write_ansi_filename(job, fn);
+ fputs(hb_c8_kw[3], job->of);
+ }
+ } else {
+ fputs(hb_c8_kw[10], job->of);
+ hb_write_ansi_filename(job, fn);
+ fputs(hb_c8_kw[11], job->of);
+ hb_write_ansi_filename(job, fn);
+ fputs(hb_c8_kw[12], job->of);
+ hb_write_ansi_filename(job, job->outputdir);
+ fputs(hb_c8_kw[13], job->of);
+ }
+#else
+ /* Remove existing file.
+ */
+ fputs(hb_c8_kw[14], job->of); /* if */
+ hb_write_filename(job, job->outputdir);
+ fputs(hb_c8_kw[30], job->of);
+ hb_write_filename(job, fn);
+ fputs(hb_c8_kw[15], job->of);
+ fputs(hb_c8_kw[16], job->of); /* then */
+ fputs(hb_c8_kw[4], job->of);
+ hb_write_filename(job, job->outputdir);
+ fputs(hb_c8_kw[30], job->of);
+ hb_write_filename(job, fn);
+ fputs(hb_c8_kw[5], job->of);
+ fputs(hb_c8_kw[18], job->of); /* fi */
+ /* Use tidy, cp or ln to bring new file in place.
+ */
+ fputs(hb_c8_kw[14], job->of);
+ hb_write_filename(job, fn);
+ fputs(hb_c8_kw[15], job->of);
+ fputs(hb_c8_kw[16], job->of);
+ if(((nptr->options) & HB_NODE_OPT_USE_TIDY) && (hb_htfile(nptr))) {
+ fputs(hb_c8_kw[37], job->of);
+ hb_write_filename(job, fn);
+ fputs(hb_c8_kw[0], job->of);
+ if(HB_CS_UTF_8 == job->cs) {
+ fputs(hb_c8_kw[27], job->of);
+ } else {
+ fputs(hb_c8_kw[28], job->of);
+ }
+ hb_write_filename(job, fn);
+ fputs(hb_c8_kw[29], job->of);
+ hb_write_filename(job, job->outputdir);
+ fputs(hb_c8_kw[30], job->of);
+ hb_write_filename(job, fn);
+ fputs(hb_c8_kw[5], job->of);
+ } else {
+ if((job->options) & HB_JOB_OPT_LN) {
+ fputs(hb_c8_kw[19], job->of);
+ } else {
+ fputs(hb_c8_kw[20], job->of);
+ }
+ hb_write_filename(job, fn);
+ fputs(hb_c8_kw[21], job->of);
+ hb_write_filename(job, job->outputdir);
+ fputs(hb_c8_kw[5], job->of);
+ }
+ fputs(hb_c8_kw[17], job->of);
+ fputs(hb_c8_kw[22], job->of);
+ hb_write_filename(job, fn);
+ fputs(hb_c8_kw[23], job->of);
+ fputs(hb_c8_kw[35], job->of);
+ fputs(hb_c8_kw[18], job->of);
+#endif
+ }
+ }
+ /* End of file.
+ */
+#if !DK3_ON_WINDOWS
+ /* find ... -type d -exec chmod ugo+rx {} \; */
+ fputs(hb_c8_kw[40], job->of);
+ hb_write_filename(job, job->outputdir);
+ fputs(hb_c8_kw[41], job->of);
+ /* find ... -type f -exec chmod ugo+r {} \; */
+ fputs(hb_c8_kw[40], job->of);
+ hb_write_filename(job, job->outputdir);
+ fputs(hb_c8_kw[42], job->of);
+ /* exit EXITCODE */
+ fputs(hb_c8_kw[34], job->of);
+#endif
+ /* Close file.
+ */
+ if(!dk3sf_fclose_fn_app(job->of, job->outputscript, job->app)) {
+ job->exv = 1;
+ }
+ } else {
+ job->exv = 1;
+ }
+ } else {
+ job->exv = 1;
+ /* ERROR: No output directory configured! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 67);
+ }
+ } else {
+ job->exv = 1;
+ /* ERROR: No output script configured! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 68);
+ } $? "- hb_write_script"
+}
+
+
+
+/** Write output files.
+ Set exit status code on errors.
+ @param job Job structure.
+*/
+static
+void
+hb_write_output(hb_job_t *job)
+{
+ $? "+ hb_write_output"
+#if DK3_CHAR_SIZE == 1
+ $!trace-code hb_show_structure(job);
+#endif
+ hb_write_html_files(job);
+ hb_write_index(job);
+ hb_write_script(job);
+ if((job->options) & HB_JOB_OPT_CHM) {
+ if(!hbchm_write_project(job)) { job->exv = 1; }
+ }
+#if DK3_CHAR_SIZE == 1
+ $!trace-code hb_show_structure(job);
+#endif
+ $? "- hb_write_output"
+}
+
+
+
+/** Check consistency of input data.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+hb_check_data(hb_job_t *job)
+{
+ hb_node_t *nptr; /* Current node */
+ int back = 1;
+ $? "+ hb_check_data"
+ /* All printable nodes must have a template.
+ */
+ job->npobjs = 0UL;
+ dk3sto_it_reset(job->i_pnodes);
+ while(NULL != (nptr = (hb_node_t *)dk3sto_it_next(job->i_pnodes))) {
+ if(!(job->firstnode)) { job->firstnode = nptr; }
+ job->lastnode = nptr;
+ nptr->pobjno = job->npobjs;
+ job->npobjs += 1UL;
+ if(!hbconf_node_template(job, nptr)) {
+ back = 0;
+ /* ERROR: No template for node! */
+ dk3app_set_source_line(job->app, nptr->lineno);
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 19);
+ }
+ }
+ if(back) {
+ /* ##### Further tests. */
+ } $? "- hb_check_data %d", back
+ return back;
+}
+
+
+
+/** Do normal processing for one specified project file.
+ @param job Job structure.
+*/
+static
+void
+hb_run_with_input_filename(hb_job_t *job)
+{
+ int res = 1;
+ $? "+ hb_run_with_input_filename"
+ dk3app_set_source_file(job->app, job->infilename);
+ dk3app_set_source_line(job->app, 0UL);
+ if(hb_job_allocate(job)) { $? ". allocation ok"
+ if(dk3opt_is_set(job->opt, dkT('o'))) {
+ res = hb_save_optional_sections(
+ job, dk3opt_get_short_arg(job->opt, dkT('o'))
+ );
+ }
+ if(res) {
+ if(hbconf_read_files(job)) {
+ if(hb_read_project(job)) {
+ if(hb_check_data(job)) {
+ hbtool_enumerate(job);
+ job->exv = 0; $? ". SUCCESS"
+ hb_write_output(job);
+ }
+ }
+ }
+ }
+ } else { $? "! allocation failed"
+ }
+ $? "- hb_run_with_input_filename"
+}
+
+
+
+/** Run normally.
+ @param job Job structure.
+*/
+static
+void
+hb_run(hb_job_t *job)
+{
+ dkChar const *infilename; /* Input file name */
+ dk3_dir_t *fne; /* File name expander */
+ dk3_um_t numfiles; /* Number of files in expander */
+ $? "+ hb_run"
+ infilename = dk3opt_get_arg(job->opt, 0);
+ if(infilename) {
+ if(dk3sf_must_expand(infilename)) {
+ fne = dk3dir_fne_open_app(infilename, job->app);
+ if(fne) {
+ numfiles = dk3dir_get_number_of_files(fne);
+ if(DK3_UM_0 < numfiles) {
+ if(DK3_UM_1 < numfiles) {
+ /* ERROR: Too many file names match */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 168, 169, infilename);
+ } else {
+ if(dk3dir_get_next_file(fne)) {
+ job->infilename = dk3dir_get_fullname(fne);
+ if(job->infilename) {
+ hb_run_with_input_filename(job);
+ } else {
+ /* ERROR: Failed to obtain file name */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ }
+ } else {
+ /* ERROR: Failed to obtain file name */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ }
+ }
+ } else {
+ /* ERROR: No matching file name! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 215, 216, infilename);
+ }
+ dk3dir_close(fne);
+ }
+ } else {
+ job->infilename = infilename;
+ hb_run_with_input_filename(job);
+ }
+ } else {
+ /* ERROR: Missing project file name! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 13);
+ }
+ $? "- hb_run"
+}
+
+
+
+/** Main function of the htmlbook program.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, any other value indicates an error.
+*/
+DK3_MAIN
+{
+ hb_job_t job; /* Job structure */
+ dk3_app_t *app = NULL; /* Application structure */
+ dkChar const * const *msg = NULL; /* Localized message texts */
+ dk3_time_t timer; /* Current time */
+ int exv = 1; /* Exit status code */
+
+ $!trace-init htmlbook.deb
+ $? "+ main"
+#if DK3_HAVE_TZSET
+ tzset();
+#endif
+ app = dk3app_open_command(
+ argc, (dkChar const * const *)argv, hb_kwnl[0]
+ );
+ if(app) {
+ msg = dk3app_messages(app, hb_kwnl[1], (dkChar const **)hb_kw);
+ hb_job_init(&job, app, msg, hb_kwnl);
+ dk3sf_time(&timer);
+ dk3sf_localtime_app(&(job.starttime), &timer, app);
+ if(hb_process_options(&job)) {
+ if(job.cmd) {
+ hb_help_version_license(&job);
+ } else {
+ hb_run(&job);
+ }
+ }
+ exv = job.exv;
+ hb_job_end(&job);
+ dk3app_close(app); app = NULL;
+ } else {
+ fputs("htmlbook: ERROR: Not enough memory (RAM/swap)!\n", stderr);
+ fflush(stderr);
+ }
+ $? "- main %d", exv
+ $!trace-end
+ fflush(stdout);
+ exit(exv); return exv;
+}
+
+
diff --git a/support/dktools/htmlbook.h b/support/dktools/htmlbook.h
new file mode 100644
index 0000000000..5a65abf455
--- /dev/null
+++ b/support/dktools/htmlbook.h
@@ -0,0 +1,407 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: htmlbook.ctr
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file htmlbook.h Header file for the htmlbook module.
+*/
+
+#ifndef HTMLBOOK_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define HTMLBOOK_H_INCLUDED 1
+
+
+#line 10 "htmlbook.ctr"
+
+#include "dk3conf.h"
+#include "dk3types.h"
+#include "dk3numco.h"
+
+
+
+/** Image dimension cache entry.
+*/
+typedef struct {
+ dkChar *fn; /**< Image name. */
+ unsigned long w; /**< Image width. */
+ unsigned long h; /**< Image height. */
+} hb_img_dim_t;
+
+
+
+/** External link.
+*/
+typedef struct {
+ dkChar *url; /**< Link URL. */
+ unsigned long lno; /**< Link number within current page. */
+} hb_link_t;
+
+
+
+/** One contents line.
+*/
+typedef struct {
+ dkChar *text; /**< Allocated line text. */
+ dkChar *aname; /**< The a name text (if any). */
+ dkChar *realtext; /**< Real start of text for header. */
+ unsigned long lineno; /**< Line number. */
+ unsigned long header; /**< Running number of header. */
+ unsigned headlevel; /**< Header level (1 to 6). */
+ int lt; /**< Line type (0=normal, 1=header). */
+} hb_line_t;
+
+
+
+/** One node in the document tree.
+*/
+struct hb__node_t {
+ struct hb__node_t *parent; /**< Parent node. */
+ struct hb__node_t *curchild; /**< Current child to edit. */
+ struct hb__node_t *jumpnode; /**< Link target node. */
+ dk3_sto_t *s_subnodes; /**< Subnodes collection. */
+ dk3_sto_it_t *i_subnodes; /**< Subnodes iterator. */
+ dk3_sto_t *s_variables; /**< Variables storage. */
+ dk3_sto_it_t *i_variables; /**< Variables iterator. */
+ dk3_sto_t *s_lines; /**< Contents lines storage. */
+ dk3_sto_it_t *i_lines; /**< Contents lines iterator. */
+ dk3_sto_t *s_lbyurl; /**< Storage for links by URL. */
+ dk3_sto_it_t *i_lbyurl; /**< Iterator for links by URL. */
+ dk3_sto_t *s_lbylno; /**< Storage for links by number. */
+ dk3_sto_it_t *i_lbylno; /**< Iterator for links by number. */
+ dk3_sto_t *s_jsfiles; /**< Storage for JS files. */
+ dk3_sto_it_t *i_jsfiles; /**< Iterator for JS files. */
+ dkChar *title; /**< Node title. */
+ dkChar *shorttitle; /**< Short title (optional). */
+ dkChar *fulltitle; /**< Full title (browser title bar). */
+ dkChar *filename; /**< Text file name (optional). */
+ dkChar *suffix; /**< Output file name suffix (opt). */
+ dkChar *template; /**< Template file name (optional). */
+ dkChar *stylefile; /**< Style file. */
+ dkChar *author; /**< Name of author. */
+ dkChar *location; /**< Location (city) of author. */
+ dkChar *icontoc; /**< File name TOC icon. */
+ dkChar *iconprev; /**< File name previous section icon. */
+ dkChar *iconnext; /**< File name next section icon. */
+ dkChar *iconindex; /**< File name index icon. */
+ dkChar *iconhome; /**< File name home icon. */
+ dkChar *favicon; /**< favicon. */
+ dkChar *metadesc; /**< Meta description tag. */
+ dkChar *metakeyw; /**< Meta keywords tag. */
+ dkChar const *outFileName; /**< Output file name. */
+ unsigned long lineno; /**< Line number in project file. */
+ unsigned long objno; /**< Object index. */
+ unsigned long pobjno; /**< Printable object number. */
+ unsigned long nextlink; /**< Next link number. */
+ unsigned long nextindex; /**< Next index entry number. */
+ unsigned long headno; /**< Head number. */
+ unsigned long nextsubheadno; /**< Next head number for sub node. */
+ unsigned long nextjs; /**< Number of next js file. */
+ long contnum; /**< Context number. */
+ unsigned options; /**< Options for node. */
+ int indent; /**< Line indent (number o spaces). */
+ int depth; /**< Depth. */
+ int tocstate; /**< State when creating TOC. */
+ int inenc; /**< Text file input encoding. */
+ int havenavimenu; /**< Flag: Already have navi menu. */
+};
+
+/** One node in the document tree.
+*/
+typedef struct hb__node_t hb_node_t;
+
+
+
+/** Entry in keyword index.
+*/
+typedef struct {
+ dkChar *tx; /**< Keyword index text. */
+ dkChar *fn; /**< File name. */
+ dkChar *an; /**< Anchor name (optional). */
+ unsigned long ul; /**< Anchor number (if no name available). */
+ hb_node_t *no; /**< Node for file name (needed for title). */
+} hb_index_entry_t;
+
+
+
+/** Job type for the htmlbook program.
+ The s_nodes storage contains a plain list of all nodes,
+ this storage is used to release all nodes at the end of the program.
+ The s_pnodes storage contains a plain list of all nodes to
+ write output for.
+ The tree structure is below the rootnode element.
+*/
+typedef struct {
+ dk3_tm_t starttime; /**< Start time. */
+ dk3_app_t *app; /**< Application structure. */
+ dkChar const * const *msg; /**< Localized messages. */
+ dkChar const * const *kwnl; /**< Keywords, not localized. */
+ dk3_option_set_t *opt; /**< Command line options. */
+ dk3_sto_t *s_nodes; /**< All nodes storage. */
+ dk3_sto_it_t *i_nodes; /**< All nodes storage iterator. */
+ dk3_sto_t *s_pnodes; /**< Leaf nodes storage. */
+ dk3_sto_it_t *i_pnodes; /**< Leaf nodes storage iterator. */
+ dk3_sto_t *s_files; /**< Additional files storage. */
+ dk3_sto_it_t *i_files; /**< Additional files iterator. */
+ dk3_sto_t *s_index; /**< Index entries storage. */
+ dk3_sto_it_t *i_index; /**< Index entries storage iterator. */
+ dk3_sto_t *s_optsect; /**< Optional sections storage. */
+ dk3_sto_it_t *i_optsect; /**< Optional sections iterator. */
+ dk3_sto_t *s_imgdim; /**< Image dimension cache storage. */
+ dk3_sto_it_t *i_imgdim; /**< Image dimension cache iterator. */
+ hb_node_t *rootnode; /**< Root node. */
+ hb_node_t *currentnode; /**< Current node to modify. */
+ hb_node_t *impressumnode; /**< Impressum node. */
+ hb_node_t *firstnode; /**< First pnode. */
+ hb_node_t *lastnode; /**< Last pnode. */
+ dkChar const *infilename; /**< Input file name (project). */
+ dkChar const *outputdir; /**< Output directory (allocated). */
+ dkChar const *outputscript; /**< Name of script to produce. */
+ dkChar const *url; /**< URL to publish the results. */
+ dkChar const *indexfile; /**< Typically index html. */
+ dkChar const *impressumlink; /**< Link to impressum. */
+ dkChar const *chmlang; /**< Language setting for CHM. */
+ dkChar *shipbuffer; /**< Shipout buffer. */
+ dkChar *iltemplate; /**< Input line from template. */
+ dkChar *ilfile; /**< Input line from file. */
+ dkChar *special; /**< Buffer for current special. */
+ dk3_c32_t *buffer32; /**< Buffer for 32-bit characters. */
+ FILE *of; /**< Output file. */
+ unsigned long lineno; /**< Line number. */
+ unsigned long nextobj; /**< Next object number. */
+ unsigned long npobjs; /**< Number of printable objects. */
+ size_t bs; /**< Buffer size. */
+ size_t spused; /**< Number elements used in special. */
+ size_t shipused; /**< Shipout buffer used. */
+ unsigned options; /**< Job options. */
+ int iecmd; /**< Input encoding from cmd args. */
+ int actsect; /**< Flag: Active section. */
+ int cmd; /**< Option processing result. */
+ int exv; /**< Exit status code. */
+ int cs; /**< Character set for HTML output. */
+ int secttype; /**< Section type. */
+ int non_url; /**< Flag: Non-URL characters found. */
+ int maxdepth; /**< Maximum depth of a node. */
+ int headlevels; /**< Maximum depth to print header. */
+ int coli; /**< Current code line number. */
+ int cols; /**< Code line state. */
+} hb_job_t;
+
+
+
+/** File processing help structure.
+*/
+typedef struct {
+ hb_job_t *job; /**< Job structure. */
+ hb_node_t *p; /**< Previous node. */
+ hb_node_t *n; /**< Next node. */
+ int in_template; /**< Flag: Processing template. */
+ int stm; /**< State machine. */
+} hb_file_processor_t;
+
+
+
+/** @defgroup hboptions Node options from project file. */
+/**@{*/
+
+/** Write page TOC.
+*/
+#define HB_NODE_OPT_PAGE_TOC 0x0001U
+
+/** Replace ampersand.
+*/
+#define HB_NODE_OPT_REPLACE_AMPERSAND 0x0002U
+
+/** Use tidy while copying.
+*/
+#define HB_NODE_OPT_USE_TIDY 0x0004U
+
+/** Write header chain.
+*/
+#define HB_NODE_OPT_HEADER_CHAIN 0x0008U
+
+/** Indicate the impressum node.
+*/
+#define HB_NODE_OPT_IMPRESSUM 0x0010U
+
+/** Stop inheritance of JS files at this node.
+*/
+#define HB_NODE_OPT_STOP_JS_INHERITANCE 0x0020U
+
+/**@}*/
+
+
+
+/** @defgroup hbjoboptions Job options. */
+/**@{*/
+
+/** Create index file.
+*/
+#define HB_JOB_OPT_CREATE_INDEX 0x0001U
+
+/** Create table of contents.
+*/
+#define HB_JOB_OPT_CREATE_TOC 0x0002U
+
+/** Currently processing code.
+*/
+#define HB_JOB_OPT_CODE 0x0004U
+
+/** Produce output for building a chm file.
+*/
+#define HB_JOB_OPT_CHM 0x0008U
+
+/** Use ln instead of cp for resource files.
+*/
+#define HB_JOB_OPT_LN 0x0010U
+
+/** Write section number in positions table.
+*/
+#define HB_JOB_OPT_NUM_IN_POS 0x0020U
+
+/** Write section number in keyword index.
+*/
+#define HB_JOB_OPT_NUM_IN_IDX 0x0040U
+
+/** Write section number in page header.
+*/
+#define HB_JOB_OPT_NUM_IN_PAGE_HEADER 0x0080U
+
+/** Enable full text search in chm output.
+*/
+#define HB_JOB_OPT_CHM_FULL_TEXT_SEARCH 0x0100U
+
+/** Print line numbers for code.
+*/
+#define HB_JOB_OPT_CODE_LINE_NUMBERS 0x0200U
+
+/**@}*/
+
+
+
+/** @defgroup hbcharsets Character sets used by htmlbook. */
+/**@{*/
+
+/** Character set us-ascii.
+*/
+#define HB_CS_ASCII 0
+
+/** Character set UTF-8.
+*/
+#define HB_CS_UTF_8 1
+
+/**@}*/
+
+
+
+/** @defgroup hbsections Section types. */
+/**@{*/
+
+/** Section type not yet known.
+*/
+#define HB_SECTION_UNKNOWN 0
+
+/** Options section.
+*/
+#define HB_SECTION_OPTIONS 1
+
+/** Files section.
+*/
+#define HB_SECTION_FILES 2
+
+/** Contents section.
+*/
+#define HB_SECTION_CONTENTS 3
+
+/**@}*/
+
+
+
+/** @defgroup hbtocstate Node state when creating TOC. */
+/**@{*/
+
+/** Work on this node is not yet in progress.
+*/
+#define HB_TOC_STATE_INIT 0
+
+/** Work on this node is in progress.
+*/
+#define HB_TOC_STATE_IN_PROGRESS 1
+
+/** Work on this node is finished.
+*/
+#define HB_TOC_STATE_FINISHED 2
+
+/**@}*/
+
+
+
+/** @defgroup hbcolist Code line states. */
+/**@{*/
+
+/** Directly after code special command.
+*/
+#define HB_COLIST_NONE 0
+
+/** In a new line, no contents yet thus no opened code tag.
+*/
+#define HB_COLIST_NOT_OPENED 1
+
+/** Code tag was opened and must be closed.
+*/
+#define HB_COLIST_OPENED 2
+
+/**@}*/
+
+
+
+/** Maximum line length.
+*/
+#define HB_LINE_LENGTH 16383
+
+
+#include "hbnode.h"
+#include "hbconf.h"
+#include "hbhtml.h"
+#include "hbtool.h"
+#include "hbcont.h"
+#include "hbindex.h"
+#include "hbimgdim.h"
+#include "hbchm.h"
+#include "dk3strkv.h"
+#include "dk3kv.h"
+#include "dk3se.h"
+
+
+
+
+#endif
diff --git a/support/dktools/htmlbook.rc b/support/dktools/htmlbook.rc
new file mode 100644
index 0000000000..25808fa621
--- /dev/null
+++ b/support/dktools/htmlbook.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Publish book-like HTML\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "Publish book-like HTML\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "htmlbook\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/initd-printqd.in b/support/dktools/initd-printqd.in
new file mode 100644
index 0000000000..be38047e14
--- /dev/null
+++ b/support/dktools/initd-printqd.in
@@ -0,0 +1,60 @@
+:
+
+
+# Standard directory variables from autoconf
+prefix=@prefix@
+datarootdir=@datarootdir@
+exec_prefix=@exec_prefix@
+bindir=@bindir@
+sbindir=@sbindir@
+libexecdir=@libexecdir@
+datadir=${datarootdir}
+sysconfdir=@sysconfdir@
+scd=$(sysconfdir)
+libdir=@libdir@
+sharedlibdir=$(libdir)/shared
+mandir=@mandir@
+includedir=@includedir@
+localstatedir=@localstatedir@
+
+RUNDIR=${localstatedir}/run/printqd
+LOGDIR=${localstatedir}/log/printqd
+DBDIR=${localstatedir}/printqd
+LPUSER=@LPUSER@
+LPGROUP=@LPGROUP@
+
+. ${sysconfdir}/rc.d/init.d/functions
+
+start() {
+ [ -d $RUNDIR ] || mkdir -p $RUNDIR
+ [ -d $LOGDIR ] || mkdir -p $LOGDIR
+ [ -d $DBDIR ] || mkdir -p $DBDIR
+ chown -R ${LPUSER}:${LPGROUP} $RUNDIR
+ chown -R ${LPUSER}:${LPGROUP} $LOGDIR
+ chown -R ${LPUSER}:${LPGROUP} $DBDIR
+ chmod -R 770 $RUNDIR
+ chmod -R 770 $LOGDIR
+ chmod -R 770 $DBDIR
+ ${sbindir}/printqd
+}
+
+stop() {
+ killproc printqd
+}
+
+case "$*" in
+"start")
+ start
+;;
+"stop")
+ stop
+;;
+"restart")
+ stop
+ sleep 1
+ start
+ sleep 1
+;;
+
+esac
+
diff --git a/support/dktools/install-sh b/support/dktools/install-sh
new file mode 100755
index 0000000000..0b0fdcbba6
--- /dev/null
+++ b/support/dktools/install-sh
@@ -0,0 +1,501 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2013-12-25.23; # UTC
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# 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
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# 'make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+
+tab=' '
+nl='
+'
+IFS=" $tab$nl"
+
+# Set DOITPROG to "echo" to test this script.
+
+doit=${DOITPROG-}
+doit_exec=${doit:-exec}
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+is_target_a_directory=possibly
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+ or: $0 [OPTION]... SRCFILES... DIRECTORY
+ or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+ or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+ --help display this help and exit.
+ --version display version info and exit.
+
+ -c (ignored)
+ -C install only if different (preserve the last data modification time)
+ -d create directories instead of installing files.
+ -g GROUP $chgrpprog installed files to GROUP.
+ -m MODE $chmodprog installed files to MODE.
+ -o USER $chownprog installed files to USER.
+ -s $stripprog installed files.
+ -t DIRECTORY install into DIRECTORY.
+ -T report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+ CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+ RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+ case $1 in
+ -c) ;;
+
+ -C) copy_on_change=true;;
+
+ -d) dir_arg=true;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift;;
+
+ --help) echo "$usage"; exit $?;;
+
+ -m) mode=$2
+ case $mode in
+ *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
+ echo "$0: invalid mode: $mode" >&2
+ exit 1;;
+ esac
+ shift;;
+
+ -o) chowncmd="$chownprog $2"
+ shift;;
+
+ -s) stripcmd=$stripprog;;
+
+ -t)
+ is_target_a_directory=always
+ dst_arg=$2
+ # Protect names problematic for 'test' and other utilities.
+ case $dst_arg in
+ -* | [=\(\)!]) dst_arg=./$dst_arg;;
+ esac
+ shift;;
+
+ -T) is_target_a_directory=never;;
+
+ --version) echo "$0 $scriptversion"; exit $?;;
+
+ --) shift
+ break;;
+
+ -*) echo "$0: invalid option: $1" >&2
+ exit 1;;
+
+ *) break;;
+ esac
+ shift
+done
+
+# We allow the use of options -d and -T together, by making -d
+# take the precedence; this is for compatibility with GNU install.
+
+if test -n "$dir_arg"; then
+ if test -n "$dst_arg"; then
+ echo "$0: target directory not allowed when installing a directory." >&2
+ exit 1
+ fi
+fi
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+ # When -d is used, all remaining arguments are directories to create.
+ # When -t is used, the destination is already specified.
+ # Otherwise, the last argument is the destination. Remove it from $@.
+ for arg
+ do
+ if test -n "$dst_arg"; then
+ # $@ is not empty: it contains at least $arg.
+ set fnord "$@" "$dst_arg"
+ shift # fnord
+ fi
+ shift # arg
+ dst_arg=$arg
+ # Protect names problematic for 'test' and other utilities.
+ case $dst_arg in
+ -* | [=\(\)!]) dst_arg=./$dst_arg;;
+ esac
+ done
+fi
+
+if test $# -eq 0; then
+ if test -z "$dir_arg"; then
+ echo "$0: no input file specified." >&2
+ exit 1
+ fi
+ # It's OK to call 'install-sh -d' without argument.
+ # This can happen when creating conditional directories.
+ exit 0
+fi
+
+if test -z "$dir_arg"; then
+ if test $# -gt 1 || test "$is_target_a_directory" = always; then
+ if test ! -d "$dst_arg"; then
+ echo "$0: $dst_arg: Is not a directory." >&2
+ exit 1
+ fi
+ fi
+fi
+
+if test -z "$dir_arg"; then
+ do_exit='(exit $ret); exit $ret'
+ trap "ret=129; $do_exit" 1
+ trap "ret=130; $do_exit" 2
+ trap "ret=141; $do_exit" 13
+ trap "ret=143; $do_exit" 15
+
+ # Set umask so as not to create temps with too-generous modes.
+ # However, 'strip' requires both read and write access to temps.
+ case $mode in
+ # Optimize common cases.
+ *644) cp_umask=133;;
+ *755) cp_umask=22;;
+
+ *[0-7])
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw='% 200'
+ fi
+ cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+ *)
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw=,u+rw
+ fi
+ cp_umask=$mode$u_plus_rw;;
+ esac
+fi
+
+for src
+do
+ # Protect names problematic for 'test' and other utilities.
+ case $src in
+ -* | [=\(\)!]) src=./$src;;
+ esac
+
+ if test -n "$dir_arg"; then
+ dst=$src
+ dstdir=$dst
+ test -d "$dstdir"
+ dstdir_status=$?
+ else
+
+ # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+ # might cause directories to be created, which would be especially bad
+ # if $src (and thus $dsttmp) contains '*'.
+ if test ! -f "$src" && test ! -d "$src"; then
+ echo "$0: $src does not exist." >&2
+ exit 1
+ fi
+
+ if test -z "$dst_arg"; then
+ echo "$0: no destination specified." >&2
+ exit 1
+ fi
+ dst=$dst_arg
+
+ # If destination is a directory, append the input filename; won't work
+ # if double slashes aren't ignored.
+ if test -d "$dst"; then
+ if test "$is_target_a_directory" = never; then
+ echo "$0: $dst_arg: Is a directory" >&2
+ exit 1
+ fi
+ dstdir=$dst
+ dst=$dstdir/`basename "$src"`
+ dstdir_status=0
+ else
+ dstdir=`dirname "$dst"`
+ test -d "$dstdir"
+ dstdir_status=$?
+ fi
+ fi
+
+ obsolete_mkdir_used=false
+
+ if test $dstdir_status != 0; then
+ case $posix_mkdir in
+ '')
+ # Create intermediate dirs using mode 755 as modified by the umask.
+ # This is like FreeBSD 'install' as of 1997-10-28.
+ umask=`umask`
+ case $stripcmd.$umask in
+ # Optimize common cases.
+ *[2367][2367]) mkdir_umask=$umask;;
+ .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+ *[0-7])
+ mkdir_umask=`expr $umask + 22 \
+ - $umask % 100 % 40 + $umask % 20 \
+ - $umask % 10 % 4 + $umask % 2
+ `;;
+ *) mkdir_umask=$umask,go-w;;
+ esac
+
+ # With -d, create the new directory with the user-specified mode.
+ # Otherwise, rely on $mkdir_umask.
+ if test -n "$dir_arg"; then
+ mkdir_mode=-m$mode
+ else
+ mkdir_mode=
+ fi
+
+ posix_mkdir=false
+ case $umask in
+ *[123567][0-7][0-7])
+ # POSIX mkdir -p sets u+wx bits regardless of umask, which
+ # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+ ;;
+ *)
+ tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+ if (umask $mkdir_umask &&
+ exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+ then
+ if test -z "$dir_arg" || {
+ # Check for POSIX incompatibilities with -m.
+ # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+ # other-writable bit of parent directory when it shouldn't.
+ # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+ ls_ld_tmpdir=`ls -ld "$tmpdir"`
+ case $ls_ld_tmpdir in
+ d????-?r-*) different_mode=700;;
+ d????-?--*) different_mode=755;;
+ *) false;;
+ esac &&
+ $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+ ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+ test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+ }
+ }
+ then posix_mkdir=:
+ fi
+ rmdir "$tmpdir/d" "$tmpdir"
+ else
+ # Remove any dirs left behind by ancient mkdir implementations.
+ rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+ fi
+ trap '' 0;;
+ esac;;
+ esac
+
+ if
+ $posix_mkdir && (
+ umask $mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+ )
+ then :
+ else
+
+ # The umask is ridiculous, or mkdir does not conform to POSIX,
+ # or it failed possibly due to a race condition. Create the
+ # directory the slow way, step by step, checking for races as we go.
+
+ case $dstdir in
+ /*) prefix='/';;
+ [-=\(\)!]*) prefix='./';;
+ *) prefix='';;
+ esac
+
+ oIFS=$IFS
+ IFS=/
+ set -f
+ set fnord $dstdir
+ shift
+ set +f
+ IFS=$oIFS
+
+ prefixes=
+
+ for d
+ do
+ test X"$d" = X && continue
+
+ prefix=$prefix$d
+ if test -d "$prefix"; then
+ prefixes=
+ else
+ if $posix_mkdir; then
+ (umask=$mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+ # Don't fail if two instances are running concurrently.
+ test -d "$prefix" || exit 1
+ else
+ case $prefix in
+ *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) qprefix=$prefix;;
+ esac
+ prefixes="$prefixes '$qprefix'"
+ fi
+ fi
+ prefix=$prefix/
+ done
+
+ if test -n "$prefixes"; then
+ # Don't fail if two instances are running concurrently.
+ (umask $mkdir_umask &&
+ eval "\$doit_exec \$mkdirprog $prefixes") ||
+ test -d "$dstdir" || exit 1
+ obsolete_mkdir_used=true
+ fi
+ fi
+ fi
+
+ if test -n "$dir_arg"; then
+ { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+ { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+ else
+
+ # Make a couple of temp file names in the proper directory.
+ dsttmp=$dstdir/_inst.$$_
+ rmtmp=$dstdir/_rm.$$_
+
+ # Trap to clean up those temp files at exit.
+ trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+ # Copy the file name to the temp name.
+ (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+ # and set any options; do chmod last to preserve setuid bits.
+ #
+ # If any of these fail, we abort the whole thing. If we want to
+ # ignore errors from any of these, just make sure not to ignore
+ # errors from the above "$doit $cpprog $src $dsttmp" command.
+ #
+ { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+ { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+ { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+ # If -C, don't bother to copy if it wouldn't change the file.
+ if $copy_on_change &&
+ old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
+ new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
+ set -f &&
+ set X $old && old=:$2:$4:$5:$6 &&
+ set X $new && new=:$2:$4:$5:$6 &&
+ set +f &&
+ test "$old" = "$new" &&
+ $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+ then
+ rm -f "$dsttmp"
+ else
+ # Rename the file to the real destination.
+ $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+ # The rename failed, perhaps because mv can't rename something else
+ # to itself, or perhaps because mv is so ancient that it does not
+ # support -f.
+ {
+ # Now remove or move aside any old file at destination location.
+ # We try this two ways since rm can't unlink itself on some
+ # systems and the destination file might be busy for other
+ # reasons. In this case, the final cleanup might fail but the new
+ # file should still install successfully.
+ {
+ test ! -f "$dst" ||
+ $doit $rmcmd -f "$dst" 2>/dev/null ||
+ { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+ { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+ } ||
+ { echo "$0: cannot unlink or rename $dst" >&2
+ (exit 1); exit 1
+ }
+ } &&
+
+ # Now rename the file to the real destination.
+ $doit $mvcmd "$dsttmp" "$dst"
+ }
+ fi || exit 1
+
+ trap '' 0
+ fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/support/dktools/itaclean.sh b/support/dktools/itaclean.sh
new file mode 100755
index 0000000000..d6a7069a75
--- /dev/null
+++ b/support/dktools/itaclean.sh
@@ -0,0 +1,62 @@
+#! /bin/sh
+
+# Copyright (c) 2015, Dirk Krause
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms,
+# with or without modification, are permitted provided
+# that the following conditions are met:
+#
+# * Redistributions of source code must retain the above
+# copyright notice, this list of conditions and the
+# following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials
+# provided with the distribution.
+#
+# * Neither the name of the copyright holder(s) nor the names of
+# contributors may be used to endorse or promote
+# products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.
+# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+
+
+EXITSTATUS=0
+
+remove_if_exists() {
+ if [ -f $* ]
+ then
+ rm $* || EXITSTATUS=1
+ fi
+}
+
+remove_if_exists hosts
+remove_if_exists hosts.ldif
+remove_if_exists ethers-by-ip
+remove_if_exists ethers-by-mac
+remove_if_exists ethers.ldif
+remove_if_exists netgroup.ldif
+remove_if_exists dhcpd.conf
+remove_if_exists netdocu.tex
+remove_if_exists licenses.tex
+remove_if_exists netdocu.pdf
+remove_if_exists licenses.pdf
+
+exit $EXITSTATUS
+
diff --git a/support/dktools/itacomp.c b/support/dktools/itacomp.c
new file mode 100644
index 0000000000..6a88cca630
--- /dev/null
+++ b/support/dktools/itacomp.c
@@ -0,0 +1,890 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: itacomp.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#line 10 "itacomp.ctr"
+
+#include "dk3all.h"
+#include "itadmin.h"
+
+
+
+
+
+#line 17 "itacomp.ctr"
+
+
+
+/** @file itacomp.c Comparison functions.
+This module provides comparison functions for the sorted
+containers.
+*/
+
+
+
+/** Correct comparison result.
+ @param v Direct result from string comparison.
+ @return -1, 0, or 1.
+*/
+static
+int
+itadmin_comp_correct(int v)
+{
+ int back;
+ back = v;
+ if(v < -1) back = -1;
+ if(v > 1) back = 1;
+ return back;
+}
+
+
+
+int
+itadmin_comp_user(void const *l, void const *r, int cr)
+{
+ itadmin_user const *pl;
+ itadmin_user const *pr;
+ char const *sn;
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (itadmin_user const *)l;
+ switch(cr) {
+ case 1: {
+ sn = (char const *)r;
+ if(pl->us) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->us, sn));
+ } else {
+ back = -1;
+ }
+ } break;
+ case 2: {
+ pr = (itadmin_user const *)r;
+ if(pl->na) {
+ if(pr->na) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->na, pr->na));
+ } else { back = 1; }
+ } else {
+ if(pr->na) { back = -1; }
+ }
+ if(back == 0) {
+ if(pl->sn) {
+ if(pr->sn) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->sn, pr->sn));
+ } else { back = 1; }
+ } else {
+ if(pr->sn) { back = -1; }
+ }
+ }
+ if(back == 0) {
+ if(pl->tt) {
+ if(pr->tt) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->tt, pr->tt));
+ } else { back = 1; }
+ } else {
+ if(pr->tt) { back = -1; }
+ }
+ }
+ if(back == 0) {
+ if(pl->us) {
+ if(pr->us) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->us, pr->us));
+ } else { back = 1; }
+ } else {
+ if(pr->us) { back = -1; }
+ }
+ }
+ } break;
+ default: {
+ pr = (itadmin_user *)r;
+ if(pl->us) {
+ if(pr->us) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->us, pr->us));
+ } else { back = 1; }
+ } else {
+ if(pr->us) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+int
+itadmin_comp_building(void const *l, void const *r, int cr)
+{
+ itadmin_building const *pl;
+ itadmin_building const *pr;
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (itadmin_building const *)l;
+ switch(cr) {
+ case 1: {
+ if(pl->s) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->s, (char const *)r));
+ } else { back = -1; }
+ } break;
+ default: {
+ pr = (itadmin_building const *)r;
+ if(pl->s) {
+ if(pr->s) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->s, pr->s));
+ } else { back = 1; }
+ } else {
+ if(pr->s) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+int
+itadmin_comp_speed(void const *l, void const *r, int cr)
+{
+ itadmin_speed const *pl;
+ itadmin_speed const *pr;
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (itadmin_speed const *)l;
+ switch(cr) {
+ case 1: {
+ if(pl->s) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->s, (char const *)r));
+ } else { back = -1; }
+ } break;
+ default: {
+ pr = (itadmin_speed const *)r;
+ if(pl->s) {
+ if(pr->s) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->s, pr->s));
+ } else { back = 1; }
+ } else {
+ if(pr->s) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+int
+itadmin_comp_vlan(void const *l, void const *r, int cr)
+{
+ itadmin_vlan const *pl;
+ itadmin_vlan const *pr;
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (itadmin_vlan const *)l;
+ switch(cr) {
+ case 1: {
+ if(pl->s) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->s, (char const *)r));
+ } else { back = -1; }
+ } break;
+ default: {
+ pr = (itadmin_vlan const *)r;
+ if(pl->s) {
+ if(pr->s) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->s, pr->s));
+ } else { back = 1; }
+ } else {
+ if(pr->s) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+int
+itadmin_comp_connect(void const *l, void const *r, int cr)
+{
+ itadmin_connect const *pl;
+ itadmin_connect const *pr;
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (itadmin_connect const *)l;
+ switch(cr) {
+ case 1: {
+ if(pl->s) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->s, (char const *)r));
+ } else { back = -1; }
+ } break;
+ default: {
+ pr = (itadmin_connect const *)r;
+ if(pl->s) {
+ if(pr->s) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->s, pr->s));
+ } else { back = 1; }
+ } else {
+ if(pr->s) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+int
+itadmin_comp_network(void const *l, void const *r, int cr)
+{
+ itadmin_network const *pl;
+ itadmin_network const *pr;
+ unsigned long const *ul;
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (itadmin_network const *)l;
+ switch(cr) {
+ case 1: {
+ ul = (unsigned long const *)r;
+ if(((pl->ip4) & (pl->ma4)) > ((*ul) & (pl->ma4))) {
+ back = 1;
+ } else {
+ if(((pl->ip4) & (pl->ma4)) < ((*ul) & (pl->ma4))) {
+ back = -1;
+ }
+ }
+ } break;
+ default: {
+ pr = (itadmin_network const *)r;
+ if(pl->ip4 > pr->ip4) {
+ back = 1;
+ } else {
+ if(pl->ip4 < pr->ip4) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+int
+itadmin_comp_netgroup(void const *l, void const *r, int cr)
+{
+ itadmin_netgroup const *pl;
+ itadmin_netgroup const *pr;
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (itadmin_netgroup const *)l;
+ switch(cr) {
+ case 1: {
+ if(pl->sn) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->sn, (char const *)r));
+ } else { back = -1; }
+ } break;
+ default: {
+ pr = (itadmin_netgroup const *)r;
+ if(pl->sn) {
+ if(pr->sn) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->sn, pr->sn));
+ } else { back = 1; }
+ } else {
+ if(pr->sn) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+int
+itadmin_comp_dhcp_class(void const *l, void const *r, int cr)
+{
+ itadmin_dhcp_class const *pl;
+ itadmin_dhcp_class const *pr;
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (itadmin_dhcp_class const *)l;
+ switch(cr) {
+ case 1: {
+ if(pl->sn) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->sn, (char const *)r));
+ } else { back = -1; }
+ } break;
+ default: {
+ pr = (itadmin_dhcp_class const *)r;
+ if(pl->sn) {
+ if(pr->sn) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->sn, pr->sn));
+ } else { back = 1; }
+ } else {
+ if(pr->sn) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+int
+itadmin_comp_dhcp_pool(void const *l, void const *r, int cr)
+{
+ itadmin_dhcp_pool const *pl;
+ itadmin_dhcp_pool const *pr;
+ unsigned long const *ul;
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (itadmin_dhcp_pool const *)l;
+ switch(cr) {
+ case 1: {
+ ul = (unsigned long const *)r;
+ if(pl->ip4s > *ul) {
+ back = 1;
+ } else {
+ if(pl->ip4e < *ul) {
+ back = -1;
+ }
+ }
+ } break;
+ default: {
+ pr = (itadmin_dhcp_pool const *)r;
+ if(pl->ip4s > pr->ip4s) {
+ back = 1;
+ } else {
+ if(pl->ip4s < pr->ip4s) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+int
+itadmin_comp_dhcp_group(void const *l, void const *r, int cr)
+{
+ itadmin_dhcp_group const *pl;
+ itadmin_dhcp_group const *pr;
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (itadmin_dhcp_group const *)l;
+ switch(cr) {
+ case 1: {
+ if(pl->sn) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->sn, (char const *)r));
+ } else { back = -1; }
+ } break;
+ default: {
+ pr = (itadmin_dhcp_group const *)r;
+ if(pl->sn) {
+ if(pr->sn) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->sn, pr->sn));
+ } else { back = 1; }
+ } else {
+ if(pr->sn) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+int
+itadmin_comp_host(void const *l, void const *r, int cr)
+{
+ itadmin_host const *pl;
+ itadmin_host const *pr;
+ unsigned long const *ul;
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (itadmin_host const *)l;
+ switch(cr) {
+ case 3: {
+ ul = (unsigned long const *)r;
+ if(pl->ipv4 > *ul) {
+ back = 1;
+ } else {
+ if(pl->ipv4 < *ul) {
+ back = -1;
+ }
+ }
+ } break;
+ case 2: {
+ pr = (itadmin_host const *)r;
+ if(pl->ipv4 > pr->ipv4) {
+ back = 1;
+ } else {
+ if(pl->ipv4 < pr->ipv4) {
+ back = -1;
+ }
+ }
+ } break;
+ case 1: {
+ if(pl->sn) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->sn, (char const *)r));
+ } else { back = -1; }
+ } break;
+ default: {
+ pr = (itadmin_host const *)r;
+ if(pl->sn) {
+ if(pr->sn) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->sn, pr->sn));
+ } else { back = 1; }
+ } else {
+ if(pr->sn) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+int
+itadmin_comp_swman(void const *l, void const *r, int cr)
+{
+ itadmin_swman const *pl;
+ itadmin_swman const *pr;
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (itadmin_swman const *)l;
+ switch(cr) {
+ case 2: {
+ pr = (itadmin_swman const *)r;
+ if(pl->ln) {
+ if(pr->ln) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->ln, pr->ln));
+ } else { back = 1; }
+ } else {
+ if(pr->ln) { back = -1; }
+ }
+ if(back == 0) {
+ if(pl->sn) {
+ if(pr->sn) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->sn, pr->sn));
+ } else { back = 1; }
+ } else {
+ if(pr->sn) { back = -1; }
+ }
+ }
+ } break;
+ case 1: {
+ if(pl->sn) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->sn, (char const *)r));
+ } else { back = -1; }
+ } break;
+ default: {
+ pr = (itadmin_swman const *)r;
+ if(pl->sn) {
+ if(pr->sn) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->sn, pr->sn));
+ } else { back = 1; }
+ } else {
+ if(pr->sn) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+int
+itadmin_comp_swprod(void const *l, void const *r, int cr)
+{
+ itadmin_swprod const *pl;
+ itadmin_swprod const *pr;
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (itadmin_swprod const *)l;
+ switch(cr) {
+ case 2: {
+ pr = (itadmin_swprod const *)r;
+ back = itadmin_comp_swman((void *)(pl->mn), (void *)(pr->mn), 2);
+ if(back == 0) {
+ if(pl->ln) {
+ if(pr->ln) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->ln, pr->ln));
+ } else { back = 1; }
+ } else {
+ if(pr->ln) { back = -1; }
+ }
+ }
+ if(back == 0) {
+ if(pl->sn) {
+ if(pr->sn) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->sn, pr->sn));
+ } else { back = 1; }
+ } else {
+ if(pr->sn) { back = -1; }
+ }
+ }
+ } break;
+ case 1: {
+ if(pl->sn) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->sn, (char const *)r));
+ } else { back = -1; }
+ } break;
+ default: {
+ pr = (itadmin_swprod const *)r;
+ if(pl->sn) {
+ if(pr->sn) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->sn, pr->sn));
+ } else { back = 1; }
+ } else {
+ if(pr->sn) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+int
+itadmin_comp_lictype(void const *l, void const *r, int cr)
+{
+ itadmin_lictype const *pl;
+ itadmin_lictype const *pr;
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (itadmin_lictype const *)l;
+ switch(cr) {
+ case 2: {
+ pr = (itadmin_lictype const *)r;
+ if(pl->ln) {
+ if(pr->ln) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->ln, pr->ln));
+ } else { back = 1; }
+ } else {
+ if(pr->ln) { back = -1; }
+ }
+ if(back == 0) {
+ if(pl->num > pr->num) {
+ back = 1;
+ } else {
+ if(pl->num < pr->num) {
+ back = -1;
+ }
+ }
+ }
+ } break;
+ case 1: {
+ if(pl->sn) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->sn, (char const *)r));
+ } else { back = -1; }
+ } break;
+ default: {
+ pr = (itadmin_lictype const *)r;
+ if(pl->sn) {
+ if(pr->sn) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->sn, pr->sn));
+ } else { back = 1; }
+ } else {
+ if(pr->sn) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+int
+itadmin_comp_license(void const *l, void const *r, int cr)
+{
+ itadmin_license const *pl;
+ itadmin_license const *pr;
+ unsigned long const *ulp;
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (itadmin_license const *)l;
+ pr = (itadmin_license const *)r;
+ ulp = (unsigned long const *)r;
+ switch(cr) {
+ case 2: {
+ back = itadmin_comp_swprod((void *)(pl->prod),(void *)(pr->prod),2);
+ if(back == 0) {
+ back = itadmin_comp_lictype((void const *)(pl->ltype), (void const *)(pr->ltype), 2);
+ }
+ if(back == 0) {
+ back = itadmin_comp_user((void const *)(pl->owner), (void const *)(pr->owner), 2);
+ }
+ if(back == 0) {
+ back = itadmin_comp_host((void const *)(pl->host), (void const *)(pr->host), 0);
+ }
+ if(back == 0) {
+ back = itadmin_comp_license(l, r, 0);
+ }
+ } break;
+ case 1: {
+ if(pl->pk > (*ulp)) {
+ back = 1;
+ } else {
+ if(pl->pk < (*ulp)) {
+ back = -1;
+ }
+ }
+ } break;
+ default: {
+ if(pl->pk > pr->pk) {
+ back = 1;
+ } else {
+ if(pl->pk < pr->pk) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+int
+itadmin_comp_dhcp_ginw(void const *l, void const *r, int cr)
+{
+ itadmin_dhcp_ginw const *pl;
+ itadmin_dhcp_ginw const *pr;
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (itadmin_dhcp_ginw const *)l;
+ switch(cr) {
+ case 1: {
+ if(pl->gr) {
+ if((pl->gr)->sn) {
+ back = dk3str_c8_cmp((pl->gr)->sn, (char const *)r);
+ back = itadmin_comp_correct(back);
+ } else back = -1;
+ } else back = -1;
+ } break;
+ default: {
+ pr = (itadmin_dhcp_ginw const *)r;
+ if(pl->gr) {
+ if(pr->gr) {
+ if((pl->gr)->sn) {
+ if((pr->gr)->sn) {
+ back = dk3str_c8_cmp((pl->gr)->sn, (pr->gr)->sn);
+ back = itadmin_comp_correct(back);
+ } else back = 1;
+ } else {
+ if((pr->gr)->sn) back = -1;
+ }
+ } else back = 1;
+ } else {
+ if(pr->gr) back = -1;
+ }
+ } break;
+ }
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ }
+ return back;
+}
+
+
+
+int
+itadmin_comp_date(itadmin_date const *l, itadmin_date const *r)
+{
+ int back = 0;
+ if(l) {
+ if(r) {
+ if(l->y > r->y) back = 1;
+ else {
+ if(l->y < r->y) back = -1;
+ }
+ if(back == 0) {
+ if(l->m > r->m) back = 1;
+ else {
+ if(l->m < r->m) back = -1;
+ }
+ }
+ if(back == 0) {
+ if(l->d > r->d) back = 1;
+ else {
+ if(l->d < r->d) back = -1;
+ }
+ }
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ }
+ return back;
+}
+
+
+
+int
+itadmin_comp_dhcp_option(void const *l, void const *r, int cr)
+{
+ itadmin_dhcp_option const *pl;
+ itadmin_dhcp_option const *pr;
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (itadmin_dhcp_option const *)l;
+ pr = (itadmin_dhcp_option const *)r;
+ if(pl->pk > pr->pk) {
+ back = 1;
+ } else {
+ if(pl->pk < pr->pk) {
+ back = -1;
+ }
+ }
+ if(back == 0) {
+ if(pl->k) {
+ if(pr->k) {
+ back = dk3str_c8_cmp(pl->k, pr->k);
+ back = itadmin_comp_correct(back);
+ } else back = 1;
+ } else {
+ if(pr->k) back = -1;
+ }
+ }
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ }
+ return back;
+}
+
+
+
+int
+itadmin_comp_string(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ if(l) {
+ if(r) {
+ switch(cr) {
+ case 1: {
+ back = itadmin_comp_correct(
+ dk3str_c8_casecmp((char const *)l, (char const *)r)
+ );
+ } break;
+ default: {
+ back = itadmin_comp_correct(
+ dk3str_c8_cmp((char const *)l, (char const *)r)
+ );
+ } break;
+ }
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ }
+ return back;
+}
+
diff --git a/support/dktools/itacomp.ctr b/support/dktools/itacomp.ctr
new file mode 100644
index 0000000000..1d04391c14
--- /dev/null
+++ b/support/dktools/itacomp.ctr
@@ -0,0 +1,860 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk3all.h"
+#include "itadmin.h"
+
+
+
+$!trace-include
+
+
+
+/** @file itacomp.c Comparison functions.
+This module provides comparison functions for the sorted
+containers.
+*/
+
+
+
+/** Correct comparison result.
+ @param v Direct result from string comparison.
+ @return -1, 0, or 1.
+*/
+static
+int
+itadmin_comp_correct(int v)
+{
+ int back;
+ back = v;
+ if(v < -1) back = -1;
+ if(v > 1) back = 1;
+ return back;
+}
+
+
+
+int
+itadmin_comp_user(void const *l, void const *r, int cr)
+{
+ itadmin_user const *pl;
+ itadmin_user const *pr;
+ char const *sn;
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (itadmin_user const *)l;
+ switch(cr) {
+ case 1: {
+ sn = (char const *)r;
+ if(pl->us) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->us, sn));
+ } else {
+ back = -1;
+ }
+ } break;
+ case 2: {
+ pr = (itadmin_user const *)r;
+ if(pl->na) {
+ if(pr->na) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->na, pr->na));
+ } else { back = 1; }
+ } else {
+ if(pr->na) { back = -1; }
+ }
+ if(back == 0) {
+ if(pl->sn) {
+ if(pr->sn) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->sn, pr->sn));
+ } else { back = 1; }
+ } else {
+ if(pr->sn) { back = -1; }
+ }
+ }
+ if(back == 0) {
+ if(pl->tt) {
+ if(pr->tt) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->tt, pr->tt));
+ } else { back = 1; }
+ } else {
+ if(pr->tt) { back = -1; }
+ }
+ }
+ if(back == 0) {
+ if(pl->us) {
+ if(pr->us) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->us, pr->us));
+ } else { back = 1; }
+ } else {
+ if(pr->us) { back = -1; }
+ }
+ }
+ } break;
+ default: {
+ pr = (itadmin_user *)r;
+ if(pl->us) {
+ if(pr->us) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->us, pr->us));
+ } else { back = 1; }
+ } else {
+ if(pr->us) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+int
+itadmin_comp_building(void const *l, void const *r, int cr)
+{
+ itadmin_building const *pl;
+ itadmin_building const *pr;
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (itadmin_building const *)l;
+ switch(cr) {
+ case 1: {
+ if(pl->s) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->s, (char const *)r));
+ } else { back = -1; }
+ } break;
+ default: {
+ pr = (itadmin_building const *)r;
+ if(pl->s) {
+ if(pr->s) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->s, pr->s));
+ } else { back = 1; }
+ } else {
+ if(pr->s) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+int
+itadmin_comp_speed(void const *l, void const *r, int cr)
+{
+ itadmin_speed const *pl;
+ itadmin_speed const *pr;
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (itadmin_speed const *)l;
+ switch(cr) {
+ case 1: {
+ if(pl->s) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->s, (char const *)r));
+ } else { back = -1; }
+ } break;
+ default: {
+ pr = (itadmin_speed const *)r;
+ if(pl->s) {
+ if(pr->s) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->s, pr->s));
+ } else { back = 1; }
+ } else {
+ if(pr->s) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+int
+itadmin_comp_vlan(void const *l, void const *r, int cr)
+{
+ itadmin_vlan const *pl;
+ itadmin_vlan const *pr;
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (itadmin_vlan const *)l;
+ switch(cr) {
+ case 1: {
+ if(pl->s) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->s, (char const *)r));
+ } else { back = -1; }
+ } break;
+ default: {
+ pr = (itadmin_vlan const *)r;
+ if(pl->s) {
+ if(pr->s) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->s, pr->s));
+ } else { back = 1; }
+ } else {
+ if(pr->s) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+int
+itadmin_comp_connect(void const *l, void const *r, int cr)
+{
+ itadmin_connect const *pl;
+ itadmin_connect const *pr;
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (itadmin_connect const *)l;
+ switch(cr) {
+ case 1: {
+ if(pl->s) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->s, (char const *)r));
+ } else { back = -1; }
+ } break;
+ default: {
+ pr = (itadmin_connect const *)r;
+ if(pl->s) {
+ if(pr->s) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->s, pr->s));
+ } else { back = 1; }
+ } else {
+ if(pr->s) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+int
+itadmin_comp_network(void const *l, void const *r, int cr)
+{
+ itadmin_network const *pl;
+ itadmin_network const *pr;
+ unsigned long const *ul;
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (itadmin_network const *)l;
+ switch(cr) {
+ case 1: {
+ ul = (unsigned long const *)r;
+ if(((pl->ip4) & (pl->ma4)) > ((*ul) & (pl->ma4))) {
+ back = 1;
+ } else {
+ if(((pl->ip4) & (pl->ma4)) < ((*ul) & (pl->ma4))) {
+ back = -1;
+ }
+ }
+ } break;
+ default: {
+ pr = (itadmin_network const *)r;
+ if(pl->ip4 > pr->ip4) {
+ back = 1;
+ } else {
+ if(pl->ip4 < pr->ip4) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+int
+itadmin_comp_netgroup(void const *l, void const *r, int cr)
+{
+ itadmin_netgroup const *pl;
+ itadmin_netgroup const *pr;
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (itadmin_netgroup const *)l;
+ switch(cr) {
+ case 1: {
+ if(pl->sn) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->sn, (char const *)r));
+ } else { back = -1; }
+ } break;
+ default: {
+ pr = (itadmin_netgroup const *)r;
+ if(pl->sn) {
+ if(pr->sn) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->sn, pr->sn));
+ } else { back = 1; }
+ } else {
+ if(pr->sn) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+int
+itadmin_comp_dhcp_class(void const *l, void const *r, int cr)
+{
+ itadmin_dhcp_class const *pl;
+ itadmin_dhcp_class const *pr;
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (itadmin_dhcp_class const *)l;
+ switch(cr) {
+ case 1: {
+ if(pl->sn) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->sn, (char const *)r));
+ } else { back = -1; }
+ } break;
+ default: {
+ pr = (itadmin_dhcp_class const *)r;
+ if(pl->sn) {
+ if(pr->sn) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->sn, pr->sn));
+ } else { back = 1; }
+ } else {
+ if(pr->sn) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+int
+itadmin_comp_dhcp_pool(void const *l, void const *r, int cr)
+{
+ itadmin_dhcp_pool const *pl;
+ itadmin_dhcp_pool const *pr;
+ unsigned long const *ul;
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (itadmin_dhcp_pool const *)l;
+ switch(cr) {
+ case 1: {
+ ul = (unsigned long const *)r;
+ if(pl->ip4s > *ul) {
+ back = 1;
+ } else {
+ if(pl->ip4e < *ul) {
+ back = -1;
+ }
+ }
+ } break;
+ default: {
+ pr = (itadmin_dhcp_pool const *)r;
+ if(pl->ip4s > pr->ip4s) {
+ back = 1;
+ } else {
+ if(pl->ip4s < pr->ip4s) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+int
+itadmin_comp_dhcp_group(void const *l, void const *r, int cr)
+{
+ itadmin_dhcp_group const *pl;
+ itadmin_dhcp_group const *pr;
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (itadmin_dhcp_group const *)l;
+ switch(cr) {
+ case 1: {
+ if(pl->sn) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->sn, (char const *)r));
+ } else { back = -1; }
+ } break;
+ default: {
+ pr = (itadmin_dhcp_group const *)r;
+ if(pl->sn) {
+ if(pr->sn) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->sn, pr->sn));
+ } else { back = 1; }
+ } else {
+ if(pr->sn) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+int
+itadmin_comp_host(void const *l, void const *r, int cr)
+{
+ itadmin_host const *pl;
+ itadmin_host const *pr;
+ unsigned long const *ul;
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (itadmin_host const *)l;
+ switch(cr) {
+ case 3: {
+ ul = (unsigned long const *)r;
+ if(pl->ipv4 > *ul) {
+ back = 1;
+ } else {
+ if(pl->ipv4 < *ul) {
+ back = -1;
+ }
+ }
+ } break;
+ case 2: {
+ pr = (itadmin_host const *)r;
+ if(pl->ipv4 > pr->ipv4) {
+ back = 1;
+ } else {
+ if(pl->ipv4 < pr->ipv4) {
+ back = -1;
+ }
+ }
+ } break;
+ case 1: {
+ if(pl->sn) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->sn, (char const *)r));
+ } else { back = -1; }
+ } break;
+ default: {
+ pr = (itadmin_host const *)r;
+ if(pl->sn) {
+ if(pr->sn) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->sn, pr->sn));
+ } else { back = 1; }
+ } else {
+ if(pr->sn) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+int
+itadmin_comp_swman(void const *l, void const *r, int cr)
+{
+ itadmin_swman const *pl;
+ itadmin_swman const *pr;
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (itadmin_swman const *)l;
+ switch(cr) {
+ case 2: {
+ pr = (itadmin_swman const *)r;
+ if(pl->ln) {
+ if(pr->ln) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->ln, pr->ln));
+ } else { back = 1; }
+ } else {
+ if(pr->ln) { back = -1; }
+ }
+ if(back == 0) {
+ if(pl->sn) {
+ if(pr->sn) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->sn, pr->sn));
+ } else { back = 1; }
+ } else {
+ if(pr->sn) { back = -1; }
+ }
+ }
+ } break;
+ case 1: {
+ if(pl->sn) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->sn, (char const *)r));
+ } else { back = -1; }
+ } break;
+ default: {
+ pr = (itadmin_swman const *)r;
+ if(pl->sn) {
+ if(pr->sn) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->sn, pr->sn));
+ } else { back = 1; }
+ } else {
+ if(pr->sn) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+int
+itadmin_comp_swprod(void const *l, void const *r, int cr)
+{
+ itadmin_swprod const *pl;
+ itadmin_swprod const *pr;
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (itadmin_swprod const *)l;
+ switch(cr) {
+ case 2: {
+ pr = (itadmin_swprod const *)r;
+ back = itadmin_comp_swman((void *)(pl->mn), (void *)(pr->mn), 2);
+ if(back == 0) {
+ if(pl->ln) {
+ if(pr->ln) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->ln, pr->ln));
+ } else { back = 1; }
+ } else {
+ if(pr->ln) { back = -1; }
+ }
+ }
+ if(back == 0) {
+ if(pl->sn) {
+ if(pr->sn) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->sn, pr->sn));
+ } else { back = 1; }
+ } else {
+ if(pr->sn) { back = -1; }
+ }
+ }
+ } break;
+ case 1: {
+ if(pl->sn) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->sn, (char const *)r));
+ } else { back = -1; }
+ } break;
+ default: {
+ pr = (itadmin_swprod const *)r;
+ if(pl->sn) {
+ if(pr->sn) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->sn, pr->sn));
+ } else { back = 1; }
+ } else {
+ if(pr->sn) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+int
+itadmin_comp_lictype(void const *l, void const *r, int cr)
+{
+ itadmin_lictype const *pl;
+ itadmin_lictype const *pr;
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (itadmin_lictype const *)l;
+ switch(cr) {
+ case 2: {
+ pr = (itadmin_lictype const *)r;
+ if(pl->ln) {
+ if(pr->ln) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->ln, pr->ln));
+ } else { back = 1; }
+ } else {
+ if(pr->ln) { back = -1; }
+ }
+ if(back == 0) {
+ if(pl->num > pr->num) {
+ back = 1;
+ } else {
+ if(pl->num < pr->num) {
+ back = -1;
+ }
+ }
+ }
+ } break;
+ case 1: {
+ if(pl->sn) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->sn, (char const *)r));
+ } else { back = -1; }
+ } break;
+ default: {
+ pr = (itadmin_lictype const *)r;
+ if(pl->sn) {
+ if(pr->sn) {
+ back = itadmin_comp_correct(dk3str_c8_cmp(pl->sn, pr->sn));
+ } else { back = 1; }
+ } else {
+ if(pr->sn) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+int
+itadmin_comp_license(void const *l, void const *r, int cr)
+{
+ itadmin_license const *pl;
+ itadmin_license const *pr;
+ unsigned long const *ulp;
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (itadmin_license const *)l;
+ pr = (itadmin_license const *)r;
+ ulp = (unsigned long const *)r;
+ switch(cr) {
+ case 2: {
+ back = itadmin_comp_swprod((void *)(pl->prod),(void *)(pr->prod),2);
+ if(back == 0) {
+ back = itadmin_comp_lictype((void const *)(pl->ltype), (void const *)(pr->ltype), 2);
+ }
+ if(back == 0) {
+ back = itadmin_comp_user((void const *)(pl->owner), (void const *)(pr->owner), 2);
+ }
+ if(back == 0) {
+ back = itadmin_comp_host((void const *)(pl->host), (void const *)(pr->host), 0);
+ }
+ if(back == 0) {
+ back = itadmin_comp_license(l, r, 0);
+ }
+ } break;
+ case 1: {
+ if(pl->pk > (*ulp)) {
+ back = 1;
+ } else {
+ if(pl->pk < (*ulp)) {
+ back = -1;
+ }
+ }
+ } break;
+ default: {
+ if(pl->pk > pr->pk) {
+ back = 1;
+ } else {
+ if(pl->pk < pr->pk) {
+ back = -1;
+ }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if(r) { back = -1; }
+ }
+ return back;
+}
+
+
+
+int
+itadmin_comp_dhcp_ginw(void const *l, void const *r, int cr)
+{
+ itadmin_dhcp_ginw const *pl;
+ itadmin_dhcp_ginw const *pr;
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (itadmin_dhcp_ginw const *)l;
+ switch(cr) {
+ case 1: {
+ if(pl->gr) {
+ if((pl->gr)->sn) {
+ back = dk3str_c8_cmp((pl->gr)->sn, (char const *)r);
+ back = itadmin_comp_correct(back);
+ } else back = -1;
+ } else back = -1;
+ } break;
+ default: {
+ pr = (itadmin_dhcp_ginw const *)r;
+ if(pl->gr) {
+ if(pr->gr) {
+ if((pl->gr)->sn) {
+ if((pr->gr)->sn) {
+ back = dk3str_c8_cmp((pl->gr)->sn, (pr->gr)->sn);
+ back = itadmin_comp_correct(back);
+ } else back = 1;
+ } else {
+ if((pr->gr)->sn) back = -1;
+ }
+ } else back = 1;
+ } else {
+ if(pr->gr) back = -1;
+ }
+ } break;
+ }
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ }
+ return back;
+}
+
+
+
+int
+itadmin_comp_date(itadmin_date const *l, itadmin_date const *r)
+{
+ int back = 0;
+ if(l) {
+ if(r) {
+ if(l->y > r->y) back = 1;
+ else {
+ if(l->y < r->y) back = -1;
+ }
+ if(back == 0) {
+ if(l->m > r->m) back = 1;
+ else {
+ if(l->m < r->m) back = -1;
+ }
+ }
+ if(back == 0) {
+ if(l->d > r->d) back = 1;
+ else {
+ if(l->d < r->d) back = -1;
+ }
+ }
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ }
+ return back;
+}
+
+
+
+int
+itadmin_comp_dhcp_option(void const *l, void const *r, int cr)
+{
+ itadmin_dhcp_option const *pl;
+ itadmin_dhcp_option const *pr;
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (itadmin_dhcp_option const *)l;
+ pr = (itadmin_dhcp_option const *)r;
+ if(pl->pk > pr->pk) {
+ back = 1;
+ } else {
+ if(pl->pk < pr->pk) {
+ back = -1;
+ }
+ }
+ if(back == 0) {
+ if(pl->k) {
+ if(pr->k) {
+ back = dk3str_c8_cmp(pl->k, pr->k);
+ back = itadmin_comp_correct(back);
+ } else back = 1;
+ } else {
+ if(pr->k) back = -1;
+ }
+ }
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ }
+ return back;
+}
+
+
+
+int
+itadmin_comp_string(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ if(l) {
+ if(r) {
+ switch(cr) {
+ case 1: {
+ back = itadmin_comp_correct(
+ dk3str_c8_casecmp((char const *)l, (char const *)r)
+ );
+ } break;
+ default: {
+ back = itadmin_comp_correct(
+ dk3str_c8_cmp((char const *)l, (char const *)r)
+ );
+ } break;
+ }
+ } else back = 1;
+ } else {
+ if(r) back = -1;
+ }
+ return back;
+}
+
diff --git a/support/dktools/itaconf.c b/support/dktools/itaconf.c
new file mode 100644
index 0000000000..b661fa8ab0
--- /dev/null
+++ b/support/dktools/itaconf.c
@@ -0,0 +1,826 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: itaconf.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file itaconf.c The itaconf module.
+*/
+
+
+#line 10 "itaconf.ctr"
+
+#include "dk3all.h"
+#include "itadmin.h"
+
+
+
+
+
+#line 17 "itaconf.ctr"
+
+
+
+/** Key names in configuration file.
+*/
+static dkChar const * const itadmin_config_keys[] = {
+/* 0 */
+dkT("database-host"),
+
+/* 1 */
+dkT("database-name"),
+
+/* 2 */
+dkT("database-credentials-file"),
+
+/* 3 */
+dkT("dhcpd.conf-vlan"),
+
+/* 4 */
+dkT("organization"),
+
+/* 5 */
+dkT("organizational-unit"),
+
+/* 6 */
+dkT("administrator-name"),
+
+/* 7 */
+dkT("create-dhcpd.conf"),
+
+/* 8 */
+dkT("database-type"),
+
+/* 9 */
+dkT("ldap-base"),
+
+/* 10 */
+dkT("use-koma-script"),
+
+/* 11 */
+dkT("msft-release-lease-on-shutdown"),
+
+NULL
+
+
+#line 73 "itaconf.ctr"
+};
+
+
+
+/** Items for "msft release lease on shutdown".
+*/
+static const char * const msft_release_keys[] = {
+"none", "pool", "all", NULL
+};
+
+
+/** Names of SQL database types.
+*/
+static dkChar const * const itadmin_config_database_types[] = {
+/* 0 */
+dkT("MySQL"),
+
+NULL
+
+
+#line 93 "itaconf.ctr"
+};
+
+
+
+/** Keywords to watch out for when processing a credential file.
+ Typically this is a .my.cnf file.
+*/
+static dkChar const * const itadmin_config_credential_keys[] = {
+/* 0 */
+dkT("client"),
+
+/* 1 */
+dkT("user"),
+
+/* 2 */
+dkT("password"),
+
+NULL
+
+
+#line 115 "itaconf.ctr"
+};
+
+
+
+/** Set one string entry in job structure.
+ @param job Job structure to modify.
+ @param resptr Pointer to result pointer.
+ @param srcptr Source string.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_config_set_string(
+ itadmin_job *job,
+ dkChar const **resptr,
+ dkChar const *srcptr
+)
+{
+ dkChar const *np; /* New string duplicate. */
+ int back = 0;
+
+
+#line 136 "itaconf.ctr"
+ np = dk3str_dup_app(srcptr,job->app);
+ if(np) {
+ dk3_release(*resptr);
+ *resptr = np;
+ back = 1;
+ } else {
+ /* ERROR: Memory allocation failed! */
+ }
+
+#line 144 "itaconf.ctr"
+ return back;
+}
+
+
+
+/** Configure a boolean value setting.
+ @param job Job structure.
+ @param bp Pointer to result variable.
+ @param defv Default value, used for empty or non-boolean strings.
+ @param txt Configuration text.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_config_set_bool(itadmin_job *job, int *bp, int defv, dkChar const *txt)
+{
+ dkChar lb[ITADMIN_CONFIG_LINE_SIZE]; /* Copy of value. */
+ dkChar *p1; /* Start of text in copy. */
+ int back = 1;
+
+
+#line 164 "itaconf.ctr"
+ if(txt) {
+ p1 = dk3str_start(txt, NULL);
+ if(p1) {
+ if(dk3str_len(p1) < DK3_SIZEOF(lb,dkChar)) {
+ dk3str_cpy_not_overlapped(lb, p1);
+ dk3str_normalize(lb,NULL,dkT(' '));
+ if(dk3str_is_bool(lb)) {
+ *bp = ((dk3str_is_on(lb)) ? 1 : 0);
+ } else {
+
+#line 173 "itaconf.ctr"
+ back = 0;
+ *bp = defv;
+ /* ERROR: Not a boolean! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 106, 107, lb);
+ }
+ } else {
+
+#line 179 "itaconf.ctr"
+ back = 0;
+ *bp = defv;
+ /* ERROR: Text too long! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 108, 109, p1);
+ }
+ } else {
+
+#line 185 "itaconf.ctr"
+ *bp = defv;
+ }
+ } else {
+
+#line 188 "itaconf.ctr"
+ *bp = defv;
+ }
+
+#line 190 "itaconf.ctr"
+ return back;
+}
+
+
+
+/** Set database type.
+ @param job Job structure.
+ @param txt Text for database type (at this time only "MySQL"
+ can be used).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_config_set_dbtype(itadmin_job *job, dkChar const *txt)
+{
+ int back = 0;
+ int i; /* Index of type in array of known types. */
+ if(txt) {
+ i = dk3str_array_index(itadmin_config_database_types, txt, 0);
+ if(i >= 0) {
+ job->dbt = i;
+ back = 1;
+ } else {
+ /* ERROR: No such database type! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 110, 111, txt);
+ }
+ } else {
+ /* ERROR: Empty text. */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 112);
+ }
+ return back;
+}
+
+
+
+
+/** Handler function for one configuration file line.
+ @param obj Reader object.
+ @param il Input line to process (constant text).
+ @return 1 for OK, 0 for recoverable error, -1 for abort.
+*/
+static
+int
+itadmin_config_const_line_handler(void *obj, dkChar const *il)
+{
+ dkChar line[ITADMIN_CONFIG_LINE_SIZE]; /* Private copy of line.*/
+ itadmin_job *job;
+ dkChar *p1; /* Start of line. */
+ dkChar *p2; /* Start of value in line. */
+ int back = 0;
+
+
+#line 241 "itaconf.ctr"
+ if((obj) && (il)) {
+ job = (itadmin_job *)obj;
+ if(dk3str_len(il) < DK3_SIZEOF(line,dkChar)) {
+ dk3str_cpy_not_overlapped(line, il);
+ dk3str_delnl(line);
+ p1 = dk3str_start(line, NULL);
+ if(p1) {
+ if(*p1 == dkT('#')) {
+ back = 1; /* Comment line. */
+ } else {
+ p2 = dk3str_chr(p1, dkT('='));
+ if(p2) {
+ *(p2++) = dkT('\0');
+ p2 = dk3str_start(p2, NULL);
+ if(p2) {
+ dk3str_normalize(p1, NULL, dkT('-'));
+ switch(dk3str_array_index(itadmin_config_keys, p1, 0)) {
+ case 0: { /* database host */
+ back = itadmin_config_set_string(job, &(job->dbhn), p2);
+ } break;
+ case 1: { /* database name */
+ back = itadmin_config_set_string(job, &(job->dbn), p2);
+ } break;
+ case 2: { /* credentials file */
+ back = itadmin_config_set_string(job, &(job->dbcf), p2);
+ } break;
+ case 3: { /* VLAN name */
+ back = itadmin_config_set_string(job, &(job->vlan), p2);
+ if(back) {
+ job->f_dh = 1;
+ }
+ } break;
+ case 4: { /* organization */
+ back = itadmin_config_set_string(job, &(job->org), p2);
+ } break;
+ case 5: { /* organizational unit */
+ back = itadmin_config_set_string(job, &(job->ou), p2);
+ } break;
+ case 6: { /* administrator name */
+ back = itadmin_config_set_string(job, &(job->admn), p2);
+ } break;
+ case 7: {
+ back = itadmin_config_set_bool(job, &(job->f_dh), 1, p2);
+ } break;
+ case 8: {
+ back = itadmin_config_set_dbtype(job, p2);
+ } break;
+ case 9: {
+ dk3str_normalize(p2, NULL, ' ');
+ back = itadmin_config_set_string(job, &(job->ldapb), p2);
+ } break;
+ case 10: {
+ if(dk3str_is_bool(p2)) {
+ back = 1;
+ job->ukoma = ((dk3str_is_on(p2)) ? 1 : 0);
+ } else {
+ /* ERROR: Boolean expected! */
+ dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,106,107,p2);
+ }
+ } break;
+ case 11: {
+ switch(dk3str_array_index(msft_release_keys, p2, 0)) {
+ case 0: {
+ job->rel = 0; back = 1;
+ } break;
+ case 1: {
+ job->rel = 1; back = 1;
+ } break;
+ case 2: {
+ job->rel = 2; back = 1;
+ } break;
+ default: {
+ /* ##### ERROR: Illegal keyword */
+ } break;
+ }
+ } break;
+ default: {
+ /* ERROR: Unknown option ... */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 113, 114, p1);
+ } break;
+ }
+ } else {
+ /* ERROR: No value! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 115);
+ }
+ } else {
+ /* ERROR: Missing '=' */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 115);
+ }
+ }
+ } else {
+ back = 1; /* Empty line. */
+ }
+ } else {
+ /* ERROR: Input line too long! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 116);
+ }
+ }
+
+#line 339 "itaconf.ctr"
+ return back;
+}
+
+
+
+/** Handler function for one configuration file line.
+ @param obj Reader object.
+ @param il Input line to process.
+ @return 1 for OK, 0 for recoverable error, -1 for abort.
+*/
+static
+int
+itadmin_cred_file_const_line_handler(void *obj, dkChar const *il)
+{
+ dkChar line[ITADMIN_CONFIG_LINE_SIZE]; /* Copy of line. */
+ dkChar *p1; /* Start of key. */
+ dkChar *p2; /* Start of value. */
+ itadmin_cred_reader *reader; /* Help structure to read creds. */
+ int back = 0;
+
+
+#line 359 "itaconf.ctr"
+ if((obj) && (il)) {
+
+#line 360 "itaconf.ctr"
+ reader = (itadmin_cred_reader *)obj;
+ if(dk3str_len(il) < DK3_SIZEOF(line,dkChar)) {
+
+#line 362 "itaconf.ctr"
+ dk3str_cpy_not_overlapped(line, il);
+ dk3str_delnl(line);
+ p1 = dk3str_start(line, NULL);
+ if(p1) {
+
+#line 366 "itaconf.ctr"
+ if(*p1 == dkT('#')) {
+
+#line 367 "itaconf.ctr"
+ back = 1; /* Ignore comment. */
+ } else {
+
+#line 369 "itaconf.ctr"
+ if(*p1 == dkT('[')) {
+
+#line 370 "itaconf.ctr"
+ reader->f_clnt = 0;
+ p1++;
+ p2 = dk3str_chr(p1, dkT(']'));
+ if(p2) {
+
+#line 374 "itaconf.ctr"
+ back = 1;
+ *p2 = dkT('\0');
+ if(dk3str_cmp(p1, itadmin_config_credential_keys[0]) == 0) {
+ reader->f_clnt = 1;
+ }
+ } else {
+
+#line 380 "itaconf.ctr"
+ /* ERROR: Syntax! */
+ dk3app_log_1(
+ (reader->job)->app, DK3_LL_ERROR, (reader->job)->msg, 117
+ );
+ }
+ } else {
+
+#line 386 "itaconf.ctr"
+ back = 1;
+ p2 = dk3str_chr(p1, dkT('='));
+ if(p2) {
+
+#line 389 "itaconf.ctr"
+ *(p2++) = dkT('\0');
+ p2 = dk3str_start(p2, NULL);
+ if(p2) {
+
+#line 392 "itaconf.ctr"
+ dk3str_normalize(p1,NULL,dkT(' '));
+ switch(dk3str_array_index(itadmin_config_credential_keys,p1,0))
+ {
+ case 1: { /* user */
+
+#line 396 "itaconf.ctr"
+ back = itadmin_config_set_string(
+ reader->job, &((reader->job)->dbus), p2
+ );
+ } break;
+ case 2: { /* password */
+
+#line 401 "itaconf.ctr"
+ back = itadmin_config_set_string(
+ reader->job, &((reader->job)->dbpw), p2
+ );
+ } break;
+ }
+ } else {
+
+#line 407 "itaconf.ctr"
+ /* Empty key. */
+ }
+ } else {
+
+#line 410 "itaconf.ctr"
+ /* Not a key=value line. */
+ }
+ }
+ }
+ } else {
+
+#line 415 "itaconf.ctr"
+ back = 1; /* Ignore empty line. */
+ }
+ } else {
+
+#line 418 "itaconf.ctr"
+ /* ERROR: Line too long! */
+ dk3app_log_1(
+ (reader->job)->app, DK3_LL_ERROR, (reader->job)->msg, 116
+ );
+ }
+ } else {
+
+#line 424 "itaconf.ctr"
+ }
+
+#line 425 "itaconf.ctr"
+ return back;
+}
+
+
+
+/** Handler function for one configuration file line.
+ @param obj Reader object.
+ @param il Input line to process.
+ @return 1 for OK, 0 for recoverable error, -1 for abort.
+*/
+static
+int
+itadmin_cred_file_line_handler(void *obj, dkChar *il)
+{
+ int back;
+ back = itadmin_cred_file_const_line_handler(obj, il);
+ return back;
+}
+
+
+
+/** Handler function for one configuration file line.
+ @param obj Reader object.
+ @param il Input line to process.
+ @return 1 for OK, 0 for recoverable error, -1 for abort.
+*/
+static
+int
+itadmin_config_line_handler(void *obj, dkChar *il)
+{
+ int back;
+ back = itadmin_config_const_line_handler(obj, il);
+ return back;
+}
+
+
+
+/** Process one configuration file.
+ @param job Job structure.
+ @param fn File name to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_config_process_one_file(itadmin_job *job, dkChar const *fn)
+{
+ dkChar line[ITADMIN_CONFIG_LINE_SIZE]; /* Copy of line. */
+ int back = 0;
+
+
+#line 474 "itaconf.ctr"
+ back = dk3stream_process_filename_lines_app(
+ (void *)job,
+ itadmin_config_line_handler,
+ fn,
+ line,
+ DK3_SIZEOF(line,dkChar),
+ dk3app_get_encoding(job->app),
+ dk3app_get_input_file_encoding(job->app),
+ job->app
+ );
+ if(back < 1) {
+ back = 0;
+ }
+
+#line 487 "itaconf.ctr"
+ return back;
+}
+
+
+
+/** Read credentials file to obtain database user name and password.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_config_read_credentials(itadmin_job *job)
+{
+ dkChar fnb[DK3_MAX_PATH]; /* File name buffer. */
+ dkChar line[ITADMIN_CONFIG_LINE_SIZE]; /* Input line buffer. */
+ itadmin_cred_reader reader; /* Helper structure to read creds. */
+ int back = 0;
+
+
+#line 505 "itaconf.ctr"
+ if(dk3str_len(job->dbcf) < DK3_SIZEOF(fnb,dkChar)) {
+ dk3str_cpy_not_overlapped(fnb, job->dbcf);
+ dk3str_correct_filename(fnb);
+ if(dk3sf_must_expand(fnb)) {
+ /* ERROR: File name must not contain wildcards! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 118, 119, fnb);
+ } else {
+ if(!dk3str_is_abs_path(fnb)) {
+ /* WARNING: File name should be specified as absolute path! */
+ dk3app_log_3(job->app, DK3_LL_WARNING, job->msg, 120, 121, fnb);
+ }
+ reader.job = job;
+ reader.f_clnt = 1;
+
+#line 518 "itaconf.ctr"
+ back = dk3stream_process_filename_sanitized_lines_app(
+ (void *)(&reader),
+ itadmin_cred_file_line_handler,
+ fnb,
+ line,
+ DK3_SIZEOF(line,dkChar),
+ dk3app_get_encoding(job->app),
+ dk3app_get_input_file_encoding(job->app),
+ job->app
+ );
+ }
+ } else {
+ /* ERROR: File name too long! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 65, 66, job->dbcf);
+ }
+ if(job->ec) {
+
+#line 534 "itaconf.ctr"
+ back = 0;
+ }
+
+#line 536 "itaconf.ctr"
+ return back;
+}
+
+
+
+int
+itadmin_config_read(itadmin_job *job)
+{
+ dkChar fnb[DK3_MAX_PATH]; /* Copy of file name. */
+ dk3_search_t *res; /* Search result, config. */
+ dk3_dir_t *fne; /* File name expander. */
+ dk3_stat_t const *es; /* Expandend file status. */
+ dkChar const *fn; /* File name. */
+ dkChar const *en; /* Expanded file name. */
+ dkChar const *fnorig; /* Original file name. */
+ int back = 0;
+ int have_file = 0; /* Flag: File found. */
+ int have_error = 0; /* Flag: Error occured. */
+ int argc; /* Number of file names. */
+ int i; /* Current file name index. */
+
+
+#line 557 "itaconf.ctr"
+ /*
+ Process default configuration files.
+ */
+ res = dk3app_find_config_file(job->app, (job->noloc)[4], 0);
+ if(res) {
+ dk3search_reset(res);
+ while((fn = dk3search_next(res)) != NULL) {
+ have_file = 1;
+ if(!itadmin_config_process_one_file(job, fn)) {
+ have_error = 1;
+ }
+ }
+ dk3search_close(res);
+ }
+ /*
+ Process configuration file(s) specified on command line.
+ */
+ argc = dk3opt_get_num_args(job->opt);
+ for(i = 0; i < argc; i++) {
+ fnorig = dk3opt_get_arg(job->opt, i);
+ if(fnorig) {
+ if(dk3str_len(fnorig) < DK3_SIZEOF(fnb,dkChar)) {
+ dk3str_cpy_not_overlapped(fnb, fnorig);
+ dk3str_correct_filename(fnb);
+ if(dk3sf_must_expand(fnb)) {
+ fne = dk3dir_fne_open_app(fnb, job->app);
+ if(fne) {
+ while(dk3dir_get_next_file(fne)) {
+ en = dk3dir_get_fullname(fne);
+ es = dk3dir_get_stat(fne);
+ if((en) && (es)) {
+ switch((es->ft) & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_REGULAR: {
+ have_file = 1;
+ if(!itadmin_config_process_one_file(job, fnb)) {
+ have_error = 1;
+ }
+ } break;
+ default: {
+ have_error = 1;
+ /* ERROR: Wrong file type! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 255, 256, en);
+ } break;
+ }
+ } else {
+ /* BUG: No complete information available! */
+ }
+ }
+ dk3dir_close(fne);
+ } else {
+ /* ERROR: Failed to expand file name! */
+ }
+ } else {
+ have_file = 1;
+ if(!itadmin_config_process_one_file(job, fnb)) {
+ have_error = 1;
+ }
+ }
+ } else {
+ /* ERROR: File name fnorig too long! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 65, 66, fnorig);
+ }
+ } else {
+ /* BUG: No pointer returned! */
+ }
+ }
+ /*
+ Final tests and error messages.
+ */
+ if(have_file) {
+
+#line 627 "itaconf.ctr"
+ if(!(have_error)) {
+
+#line 628 "itaconf.ctr"
+ back = 1;
+ if(!(job->dbhn)) {
+
+#line 630 "itaconf.ctr"
+ /* ERROR: Missing database host name! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 122);
+ back = 0;
+ }
+ if(!(job->dbn)) {
+
+#line 635 "itaconf.ctr"
+ /* ERROR: Missing database name! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 123);
+ back = 0;
+ }
+ if(!(job->vlan)) {
+
+#line 640 "itaconf.ctr"
+ /* Warning: Missing VLAN name! */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 124);
+ }
+ if(!(job->org)) {
+
+#line 644 "itaconf.ctr"
+ /* ERROR: Missing organization name! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 125);
+ back = 0;
+ }
+ if(!(job->ou)) {
+
+#line 649 "itaconf.ctr"
+ /* ERROR: Missing organizational unit name! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 126);
+ back = 0;
+ }
+ if(!(job->admn)) {
+
+#line 654 "itaconf.ctr"
+ /* ERROR: Missing administrator name! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 127);
+ back = 0;
+ }
+ if(!(job->dbcf)) {
+
+#line 659 "itaconf.ctr"
+ /* ERROR: Missing database credentials file name! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 128);
+ back = 0;
+ } else {
+
+#line 663 "itaconf.ctr"
+ if(back) {
+
+#line 664 "itaconf.ctr"
+ back = itadmin_config_read_credentials(job);
+ if(back) {
+ if(!(job->dbus)) {
+
+#line 667 "itaconf.ctr"
+ /* ERROR: Missing database user name! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 129);
+ back = 0;
+ }
+ if(!(job->dbpw)) {
+
+#line 672 "itaconf.ctr"
+ /* ERROR: Missing database user password! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 130);
+ back = 0;
+ }
+ }
+ }
+ }
+ if(back) {
+ if(!(job->ukoma)) {
+ if(dk3str_casecmp(dkT("de"), dk3app_get_language(job->app)) == 0) {
+ dk3app_log_1(job->app, DK3_LL_INFO, job->msg, 302);
+ }
+ }
+ }
+ if(!(back)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 132);
+ }
+ } else {
+
+#line 690 "itaconf.ctr"
+ }
+ } else {
+
+#line 692 "itaconf.ctr"
+ /* ERROR: No configuration file found for processing! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 131);
+ }
+
+#line 695 "itaconf.ctr"
+ return back;
+}
+
diff --git a/support/dktools/itaconf.ctr b/support/dktools/itaconf.ctr
new file mode 100644
index 0000000000..122d84bb23
--- /dev/null
+++ b/support/dktools/itaconf.ctr
@@ -0,0 +1,697 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk3all.h"
+#include "itadmin.h"
+
+
+
+$!trace-include
+
+
+
+/** Key names in configuration file.
+*/
+static dkChar const * const itadmin_config_keys[] = {
+$!string-table macro=dkT
+#
+# 0: Database host
+#
+database-host
+#
+# 1: Database name
+#
+database-name
+#
+# 2: my.cnf file containing credential for database connection
+#
+database-credentials-file
+#
+# 3: VLAN for which we have to write a dhcpd.conf file
+#
+dhcpd.conf-vlan
+#
+# 4: Organization name
+#
+organization
+#
+# 5: Organizational unit name
+#
+organizational-unit
+#
+# 6: Administrator name
+#
+administrator-name
+#
+# 7: Flag: Create dhcpd.conf file
+#
+create-dhcpd.conf
+#
+# 8: Database type
+#
+database-type
+#
+# 9: LDAP base
+#
+ldap-base
+#
+# 10: use koma-script
+#
+use-koma-script
+#
+# 11: release lease on shutdown
+#
+msft-release-lease-on-shutdown
+$!end
+};
+
+
+
+/** Items for "msft release lease on shutdown".
+*/
+static const char * const msft_release_keys[] = {
+"none", "pool", "all", NULL
+};
+
+
+/** Names of SQL database types.
+*/
+static dkChar const * const itadmin_config_database_types[] = {
+$!string-table macro=dkT
+#
+# 0: MySQL
+#
+MySQL
+$!end
+};
+
+
+
+/** Keywords to watch out for when processing a credential file.
+ Typically this is a .my.cnf file.
+*/
+static dkChar const * const itadmin_config_credential_keys[] = {
+$!string-table macro=dkT
+#
+# 0: Section title "client"
+#
+client
+#
+# 1: Key name "user"
+#
+user
+#
+# 2: Key name "password"
+#
+password
+$!end
+};
+
+
+
+/** Set one string entry in job structure.
+ @param job Job structure to modify.
+ @param resptr Pointer to result pointer.
+ @param srcptr Source string.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_config_set_string(
+ itadmin_job *job,
+ dkChar const **resptr,
+ dkChar const *srcptr
+)
+{
+ dkChar const *np; /* New string duplicate. */
+ int back = 0;
+ $? "+ itadmin_config_set_string \"%!ds\"", TR_STR(srcptr)
+ np = dk3str_dup_app(srcptr,job->app);
+ if(np) {
+ dk3_release(*resptr);
+ *resptr = np;
+ back = 1;
+ } else {
+ /* ERROR: Memory allocation failed! */
+ } $? "- itadmin_config_set_string %d", back
+ return back;
+}
+
+
+
+/** Configure a boolean value setting.
+ @param job Job structure.
+ @param bp Pointer to result variable.
+ @param defv Default value, used for empty or non-boolean strings.
+ @param txt Configuration text.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_config_set_bool(itadmin_job *job, int *bp, int defv, dkChar const *txt)
+{
+ dkChar lb[ITADMIN_CONFIG_LINE_SIZE]; /* Copy of value. */
+ dkChar *p1; /* Start of text in copy. */
+ int back = 1;
+ $? "+ itadmin_config_set_bool \"%!ds\"", TR_STR(txt)
+ if(txt) {
+ p1 = dk3str_start(txt, NULL);
+ if(p1) {
+ if(dk3str_len(p1) < DK3_SIZEOF(lb,dkChar)) {
+ dk3str_cpy_not_overlapped(lb, p1);
+ dk3str_normalize(lb,NULL,dkT(' '));
+ if(dk3str_is_bool(lb)) {
+ *bp = ((dk3str_is_on(lb)) ? 1 : 0);
+ } else { $? "! not a boolean"
+ back = 0;
+ *bp = defv;
+ /* ERROR: Not a boolean! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 106, 107, lb);
+ }
+ } else { $? "! text too long"
+ back = 0;
+ *bp = defv;
+ /* ERROR: Text too long! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 108, 109, p1);
+ }
+ } else { $? ". empty text"
+ *bp = defv;
+ }
+ } else { $? ". no text"
+ *bp = defv;
+ } $? "- itadmin_config_set_bool %d", back
+ return back;
+}
+
+
+
+/** Set database type.
+ @param job Job structure.
+ @param txt Text for database type (at this time only "MySQL"
+ can be used).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_config_set_dbtype(itadmin_job *job, dkChar const *txt)
+{
+ int back = 0;
+ int i; /* Index of type in array of known types. */
+ if(txt) {
+ i = dk3str_array_index(itadmin_config_database_types, txt, 0);
+ if(i >= 0) {
+ job->dbt = i;
+ back = 1;
+ } else {
+ /* ERROR: No such database type! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 110, 111, txt);
+ }
+ } else {
+ /* ERROR: Empty text. */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 112);
+ }
+ return back;
+}
+
+
+
+
+/** Handler function for one configuration file line.
+ @param obj Reader object.
+ @param il Input line to process (constant text).
+ @return 1 for OK, 0 for recoverable error, -1 for abort.
+*/
+static
+int
+itadmin_config_const_line_handler(void *obj, dkChar const *il)
+{
+ dkChar line[ITADMIN_CONFIG_LINE_SIZE]; /* Private copy of line.*/
+ itadmin_job *job;
+ dkChar *p1; /* Start of line. */
+ dkChar *p2; /* Start of value in line. */
+ int back = 0;
+ $? "+ itadmin_config_const_line_handler \"%!ds\"", TR_STR(il)
+ if((obj) && (il)) {
+ job = (itadmin_job *)obj;
+ if(dk3str_len(il) < DK3_SIZEOF(line,dkChar)) {
+ dk3str_cpy_not_overlapped(line, il);
+ dk3str_delnl(line);
+ p1 = dk3str_start(line, NULL);
+ if(p1) {
+ if(*p1 == dkT('#')) {
+ back = 1; /* Comment line. */
+ } else {
+ p2 = dk3str_chr(p1, dkT('='));
+ if(p2) {
+ *(p2++) = dkT('\0');
+ p2 = dk3str_start(p2, NULL);
+ if(p2) {
+ dk3str_normalize(p1, NULL, dkT('-'));
+ switch(dk3str_array_index(itadmin_config_keys, p1, 0)) {
+ case 0: { /* database host */
+ back = itadmin_config_set_string(job, &(job->dbhn), p2);
+ } break;
+ case 1: { /* database name */
+ back = itadmin_config_set_string(job, &(job->dbn), p2);
+ } break;
+ case 2: { /* credentials file */
+ back = itadmin_config_set_string(job, &(job->dbcf), p2);
+ } break;
+ case 3: { /* VLAN name */
+ back = itadmin_config_set_string(job, &(job->vlan), p2);
+ if(back) {
+ job->f_dh = 1;
+ }
+ } break;
+ case 4: { /* organization */
+ back = itadmin_config_set_string(job, &(job->org), p2);
+ } break;
+ case 5: { /* organizational unit */
+ back = itadmin_config_set_string(job, &(job->ou), p2);
+ } break;
+ case 6: { /* administrator name */
+ back = itadmin_config_set_string(job, &(job->admn), p2);
+ } break;
+ case 7: {
+ back = itadmin_config_set_bool(job, &(job->f_dh), 1, p2);
+ } break;
+ case 8: {
+ back = itadmin_config_set_dbtype(job, p2);
+ } break;
+ case 9: {
+ dk3str_normalize(p2, NULL, ' ');
+ back = itadmin_config_set_string(job, &(job->ldapb), p2);
+ } break;
+ case 10: {
+ if(dk3str_is_bool(p2)) {
+ back = 1;
+ job->ukoma = ((dk3str_is_on(p2)) ? 1 : 0);
+ } else {
+ /* ERROR: Boolean expected! */
+ dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,106,107,p2);
+ }
+ } break;
+ case 11: {
+ switch(dk3str_array_index(msft_release_keys, p2, 0)) {
+ case 0: {
+ job->rel = 0; back = 1;
+ } break;
+ case 1: {
+ job->rel = 1; back = 1;
+ } break;
+ case 2: {
+ job->rel = 2; back = 1;
+ } break;
+ default: {
+ /* ##### ERROR: Illegal keyword */
+ } break;
+ }
+ } break;
+ default: {
+ /* ERROR: Unknown option ... */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 113, 114, p1);
+ } break;
+ }
+ } else {
+ /* ERROR: No value! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 115);
+ }
+ } else {
+ /* ERROR: Missing '=' */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 115);
+ }
+ }
+ } else {
+ back = 1; /* Empty line. */
+ }
+ } else {
+ /* ERROR: Input line too long! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 116);
+ }
+ } $? "- itadmin_config_const_line_handler %d", back
+ return back;
+}
+
+
+
+/** Handler function for one configuration file line.
+ @param obj Reader object.
+ @param il Input line to process.
+ @return 1 for OK, 0 for recoverable error, -1 for abort.
+*/
+static
+int
+itadmin_cred_file_const_line_handler(void *obj, dkChar const *il)
+{
+ dkChar line[ITADMIN_CONFIG_LINE_SIZE]; /* Copy of line. */
+ dkChar *p1; /* Start of key. */
+ dkChar *p2; /* Start of value. */
+ itadmin_cred_reader *reader; /* Help structure to read creds. */
+ int back = 0;
+ $? "+ itadmin_cred_file_const_line_handler \"%!ds\"", il
+ if((obj) && (il)) { $? ". objects ok"
+ reader = (itadmin_cred_reader *)obj;
+ if(dk3str_len(il) < DK3_SIZEOF(line,dkChar)) { $? ". length ok"
+ dk3str_cpy_not_overlapped(line, il);
+ dk3str_delnl(line);
+ p1 = dk3str_start(line, NULL);
+ if(p1) { $? ". p1"
+ if(*p1 == dkT('#')) { $? ". comment"
+ back = 1; /* Ignore comment. */
+ } else { $? ". no comment"
+ if(*p1 == dkT('[')) { $? ". section"
+ reader->f_clnt = 0;
+ p1++;
+ p2 = dk3str_chr(p1, dkT(']'));
+ if(p2) { $? ". section end ok"
+ back = 1;
+ *p2 = dkT('\0');
+ if(dk3str_cmp(p1, itadmin_config_credential_keys[0]) == 0) {
+ reader->f_clnt = 1;
+ }
+ } else { $? "! no section end"
+ /* ERROR: Syntax! */
+ dk3app_log_1(
+ (reader->job)->app, DK3_LL_ERROR, (reader->job)->msg, 117
+ );
+ }
+ } else { $? ". not a section"
+ back = 1;
+ p2 = dk3str_chr(p1, dkT('='));
+ if(p2) { $? ". value found"
+ *(p2++) = dkT('\0');
+ p2 = dk3str_start(p2, NULL);
+ if(p2) { $? ". value found"
+ dk3str_normalize(p1,NULL,dkT(' '));
+ switch(dk3str_array_index(itadmin_config_credential_keys,p1,0))
+ {
+ case 1: { /* user */ $? ". user"
+ back = itadmin_config_set_string(
+ reader->job, &((reader->job)->dbus), p2
+ );
+ } break;
+ case 2: { /* password */ $? ". password"
+ back = itadmin_config_set_string(
+ reader->job, &((reader->job)->dbpw), p2
+ );
+ } break;
+ }
+ } else { $? "! no value"
+ /* Empty key. */
+ }
+ } else { $? "! no value"
+ /* Not a key=value line. */
+ }
+ }
+ }
+ } else { $? ". empty line"
+ back = 1; /* Ignore empty line. */
+ }
+ } else { $? "! length"
+ /* ERROR: Line too long! */
+ dk3app_log_1(
+ (reader->job)->app, DK3_LL_ERROR, (reader->job)->msg, 116
+ );
+ }
+ } else { $? "! args"
+ } $? "- itadmin_cred_file_const_line_handler %d", back
+ return back;
+}
+
+
+
+/** Handler function for one configuration file line.
+ @param obj Reader object.
+ @param il Input line to process.
+ @return 1 for OK, 0 for recoverable error, -1 for abort.
+*/
+static
+int
+itadmin_cred_file_line_handler(void *obj, dkChar *il)
+{
+ int back;
+ back = itadmin_cred_file_const_line_handler(obj, il);
+ return back;
+}
+
+
+
+/** Handler function for one configuration file line.
+ @param obj Reader object.
+ @param il Input line to process.
+ @return 1 for OK, 0 for recoverable error, -1 for abort.
+*/
+static
+int
+itadmin_config_line_handler(void *obj, dkChar *il)
+{
+ int back;
+ back = itadmin_config_const_line_handler(obj, il);
+ return back;
+}
+
+
+
+/** Process one configuration file.
+ @param job Job structure.
+ @param fn File name to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_config_process_one_file(itadmin_job *job, dkChar const *fn)
+{
+ dkChar line[ITADMIN_CONFIG_LINE_SIZE]; /* Copy of line. */
+ int back = 0;
+ $? "+ itadmin_config_process_one_file %!ds", TR_STR(fn)
+ back = dk3stream_process_filename_lines_app(
+ (void *)job,
+ itadmin_config_line_handler,
+ fn,
+ line,
+ DK3_SIZEOF(line,dkChar),
+ dk3app_get_encoding(job->app),
+ dk3app_get_input_file_encoding(job->app),
+ job->app
+ );
+ if(back < 1) {
+ back = 0;
+ } $? "- itadmin_config_process_one_file %d", back
+ return back;
+}
+
+
+
+/** Read credentials file to obtain database user name and password.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_config_read_credentials(itadmin_job *job)
+{
+ dkChar fnb[DK3_MAX_PATH]; /* File name buffer. */
+ dkChar line[ITADMIN_CONFIG_LINE_SIZE]; /* Input line buffer. */
+ itadmin_cred_reader reader; /* Helper structure to read creds. */
+ int back = 0;
+ $? "+ itadmin_config_read_credentials"
+ if(dk3str_len(job->dbcf) < DK3_SIZEOF(fnb,dkChar)) {
+ dk3str_cpy_not_overlapped(fnb, job->dbcf);
+ dk3str_correct_filename(fnb);
+ if(dk3sf_must_expand(fnb)) {
+ /* ERROR: File name must not contain wildcards! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 118, 119, fnb);
+ } else {
+ if(!dk3str_is_abs_path(fnb)) {
+ /* WARNING: File name should be specified as absolute path! */
+ dk3app_log_3(job->app, DK3_LL_WARNING, job->msg, 120, 121, fnb);
+ }
+ reader.job = job;
+ reader.f_clnt = 1; $? ". really read credentials"
+ back = dk3stream_process_filename_sanitized_lines_app(
+ (void *)(&reader),
+ itadmin_cred_file_line_handler,
+ fnb,
+ line,
+ DK3_SIZEOF(line,dkChar),
+ dk3app_get_encoding(job->app),
+ dk3app_get_input_file_encoding(job->app),
+ job->app
+ );
+ }
+ } else {
+ /* ERROR: File name too long! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 65, 66, job->dbcf);
+ }
+ if(job->ec) { $? "! any error during run"
+ back = 0;
+ } $? "- itadmin_config_read_credentials %d", back
+ return back;
+}
+
+
+
+int
+itadmin_config_read(itadmin_job *job)
+{
+ dkChar fnb[DK3_MAX_PATH]; /* Copy of file name. */
+ dk3_search_t *res; /* Search result, config. */
+ dk3_dir_t *fne; /* File name expander. */
+ dk3_stat_t const *es; /* Expandend file status. */
+ dkChar const *fn; /* File name. */
+ dkChar const *en; /* Expanded file name. */
+ dkChar const *fnorig; /* Original file name. */
+ int back = 0;
+ int have_file = 0; /* Flag: File found. */
+ int have_error = 0; /* Flag: Error occured. */
+ int argc; /* Number of file names. */
+ int i; /* Current file name index. */
+ $? "+ itadmin_config_read"
+ /*
+ Process default configuration files.
+ */
+ res = dk3app_find_config_file(job->app, (job->noloc)[4], 0);
+ if(res) {
+ dk3search_reset(res);
+ while((fn = dk3search_next(res)) != NULL) {
+ have_file = 1;
+ if(!itadmin_config_process_one_file(job, fn)) {
+ have_error = 1;
+ }
+ }
+ dk3search_close(res);
+ }
+ /*
+ Process configuration file(s) specified on command line.
+ */
+ argc = dk3opt_get_num_args(job->opt);
+ for(i = 0; i < argc; i++) {
+ fnorig = dk3opt_get_arg(job->opt, i);
+ if(fnorig) {
+ if(dk3str_len(fnorig) < DK3_SIZEOF(fnb,dkChar)) {
+ dk3str_cpy_not_overlapped(fnb, fnorig);
+ dk3str_correct_filename(fnb);
+ if(dk3sf_must_expand(fnb)) {
+ fne = dk3dir_fne_open_app(fnb, job->app);
+ if(fne) {
+ while(dk3dir_get_next_file(fne)) {
+ en = dk3dir_get_fullname(fne);
+ es = dk3dir_get_stat(fne);
+ if((en) && (es)) {
+ switch((es->ft) & (~(DK3_FT_SYMLINK))) {
+ case DK3_FT_REGULAR: {
+ have_file = 1;
+ if(!itadmin_config_process_one_file(job, fnb)) {
+ have_error = 1;
+ }
+ } break;
+ default: {
+ have_error = 1;
+ /* ERROR: Wrong file type! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 255, 256, en);
+ } break;
+ }
+ } else {
+ /* BUG: No complete information available! */
+ }
+ }
+ dk3dir_close(fne);
+ } else {
+ /* ERROR: Failed to expand file name! */
+ }
+ } else {
+ have_file = 1;
+ if(!itadmin_config_process_one_file(job, fnb)) {
+ have_error = 1;
+ }
+ }
+ } else {
+ /* ERROR: File name fnorig too long! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 65, 66, fnorig);
+ }
+ } else {
+ /* BUG: No pointer returned! */
+ }
+ }
+ /*
+ Final tests and error messages.
+ */
+ if(have_file) { $? ". files found"
+ if(!(have_error)) { $? ". no errors"
+ back = 1;
+ if(!(job->dbhn)) { $? "! db host"
+ /* ERROR: Missing database host name! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 122);
+ back = 0;
+ }
+ if(!(job->dbn)) { $? "! db name"
+ /* ERROR: Missing database name! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 123);
+ back = 0;
+ }
+ if(!(job->vlan)) { $? "! vlan"
+ /* Warning: Missing VLAN name! */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 124);
+ }
+ if(!(job->org)) { $? "! org"
+ /* ERROR: Missing organization name! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 125);
+ back = 0;
+ }
+ if(!(job->ou)) { $? "! ou"
+ /* ERROR: Missing organizational unit name! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 126);
+ back = 0;
+ }
+ if(!(job->admn)) { $? "! admn"
+ /* ERROR: Missing administrator name! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 127);
+ back = 0;
+ }
+ if(!(job->dbcf)) { $? "! dbcf"
+ /* ERROR: Missing database credentials file name! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 128);
+ back = 0;
+ } else { $? ". dbcf"
+ if(back) { $? ". back"
+ back = itadmin_config_read_credentials(job);
+ if(back) {
+ if(!(job->dbus)) { $? "! dbus"
+ /* ERROR: Missing database user name! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 129);
+ back = 0;
+ }
+ if(!(job->dbpw)) { $? "! dbpw"
+ /* ERROR: Missing database user password! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 130);
+ back = 0;
+ }
+ }
+ }
+ }
+ if(back) {
+ if(!(job->ukoma)) {
+ if(dk3str_casecmp(dkT("de"), dk3app_get_language(job->app)) == 0) {
+ dk3app_log_1(job->app, DK3_LL_INFO, job->msg, 302);
+ }
+ }
+ }
+ if(!(back)) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 132);
+ }
+ } else { $? "! errors found"
+ }
+ } else { $? "! no files"
+ /* ERROR: No configuration file found for processing! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 131);
+ } $? "- itadmin_config_read %d", back
+ return back;
+}
+
diff --git a/support/dktools/itadata.c b/support/dktools/itadata.c
new file mode 100644
index 0000000000..5b92503dfa
--- /dev/null
+++ b/support/dktools/itadata.c
@@ -0,0 +1,78 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: itadata.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file itadata.c The itadata module.
+*/
+
+
+#line 10 "itadata.ctr"
+
+#include "dk3all.h"
+#include "itadmin.h"
+
+
+
+
+
+#line 17 "itadata.ctr"
+
+
+
+int
+itadmin_data_read(itadmin_job *job)
+{
+ int back = 0;
+
+
+#line 25 "itadata.ctr"
+ switch(job->dbt) {
+ case DK3_SQLDB_TYPE_MYSQL: {
+ back = itadmin_data_mysql_read(job);
+ } break;
+ default: {
+ /* ERROR: Unsupported database type! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 133);
+ } break;
+ }
+ if(job->ec) { /* ERROR occured. */
+ back = 0;
+ }
+
+#line 37 "itadata.ctr"
+ return back;
+}
+
+
+
diff --git a/support/dktools/itadata.ctr b/support/dktools/itadata.ctr
new file mode 100644
index 0000000000..c377b1899a
--- /dev/null
+++ b/support/dktools/itadata.ctr
@@ -0,0 +1,41 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk3all.h"
+#include "itadmin.h"
+
+
+
+$!trace-include
+
+
+
+int
+itadmin_data_read(itadmin_job *job)
+{
+ int back = 0;
+ $? "+ itadmin_data_read"
+ switch(job->dbt) {
+ case DK3_SQLDB_TYPE_MYSQL: {
+ back = itadmin_data_mysql_read(job);
+ } break;
+ default: {
+ /* ERROR: Unsupported database type! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 133);
+ } break;
+ }
+ if(job->ec) { /* ERROR occured. */
+ back = 0;
+ } $? "- itadmin_data_read %d", back
+ return back;
+}
+
+
+
diff --git a/support/dktools/itadhcp.c b/support/dktools/itadhcp.c
new file mode 100644
index 0000000000..45e6ca8ba5
--- /dev/null
+++ b/support/dktools/itadhcp.c
@@ -0,0 +1,1161 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: itadhcp.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file itadhcp.c The itadhcp module.
+*/
+
+
+#line 10 "itadhcp.ctr"
+
+#include "dk3all.h"
+#include "itadmin.h"
+
+
+
+
+#line 16 "itadhcp.ctr"
+
+
+
+/** Keywords used by the module.
+*/
+static char const * const itadmin_dhcp_c8_kw[] = {
+/* 0 */
+"dhcpd.conf",
+
+/* 1 */
+" ",
+
+/* 2 */
+"option:",
+
+/* 3 */
+"option ",
+
+/* 4 */
+"not ",
+
+/* 5 */
+"w",
+
+/* 6 */
+"class \"",
+
+/* 7 */
+"\" { match hardware; }",
+
+/* 8 */
+"subclass \"",
+
+/* 9 */
+"\" 1:",
+
+/* 10 */
+";",
+
+/* 11 */
+"# ",
+
+/* 12 */
+"shared-network dhcpnet",
+
+/* 13 */
+"{",
+
+/* 14 */
+"}",
+
+/* 15 */
+"subnet ",
+
+/* 16 */
+" netmask ",
+
+/* 17 */
+"option routers\t\t",
+
+/* 18 */
+"option subnet-mask\t\t",
+
+/* 19 */
+"option broadcast-address\t",
+
+/* 20 */
+"pool",
+
+/* 21 */
+"range ",
+
+/* 22 */
+"allow unknown clients;",
+
+/* 23 */
+"deny unknown clients;",
+
+/* 24 */
+"allow members of \"",
+
+/* 25 */
+"deny members of \"",
+
+/* 26 */
+"\";",
+
+/* 27 */
+"group",
+
+/* 28 */
+"host ",
+
+/* 29 */
+"option host-name\t\"",
+
+/* 30 */
+"hardware ethernet\t",
+
+/* 31 */
+"fixed-address\t",
+
+/* 32 */
+"\n# ##### ITADMIN_POINT_1: After options, before classes\n\n",
+
+/* 33 */
+"\n# ##### ITADMIN_POINT_2: After classes, before VLAN\n\n",
+
+/* 34 */
+"option space MSFT;\n",
+
+/* 35 */
+"option MSFT.release-dhcp-lease-on-shutdown code 2 = unsigned integer 32;\n\n",
+
+/* 36 */
+"if substring (option vendor-class-identifier, 0, 4) = \"MSFT\" {\n",
+
+/* 37 */
+" option MSFT.release-dhcp-lease-on-shutdown 1;\n",
+
+/* 38 */
+" vendor-option-space MSFT;\n",
+
+/* 39 */
+"}\n",
+
+NULL
+
+
+#line 172 "itadhcp.ctr"
+};
+
+
+
+
+/** Option names requiring special treatment.
+*/
+static char const * const itadmin_dhcp_option_names[] = {
+/* 0 */
+"authorative",
+
+NULL
+
+
+#line 183 "itadhcp.ctr"
+};
+
+
+
+
+
+/** Indent line.
+ @param fipo Output file.
+ @param ind Indent level.
+*/
+static
+void
+itadmin_dhcp_indent(FILE *fipo, int ind)
+{
+ int i;
+ for(i = 0; i < ind; i++) {
+ fputs(itadmin_dhcp_c8_kw[1], fipo);
+ }
+}
+
+
+
+/** Write DHCP options.
+ @param job Job structure.
+ @param fipo Output file.
+ @param i_o Options storage iterator.
+ @param objtype Object type (ignored).
+ @param indent Indent level.
+
+*/
+static
+void
+itadmin_dhcp_write_options(
+ itadmin_job *job,
+ FILE *fipo,
+ dk3_sto_it_t *i_o,
+ int objtype,
+ int indent
+)
+{
+ itadmin_dhcp_option *opt;
+ char const *p1;
+ size_t sl;
+ int is_option;
+
+
+#line 228 "itadhcp.ctr"
+ dk3sto_it_reset(i_o);
+ while(NULL != (opt = (itadmin_dhcp_option *)dk3sto_it_next(i_o))) {
+
+#line 230 "itadhcp.ctr"
+ is_option = 0;
+ if(opt->k) {
+
+#line 232 "itadhcp.ctr"
+ p1 = dk3str_c8_start(opt->k, NULL);
+ if(p1) {
+
+#line 234 "itadhcp.ctr"
+ sl = strlen(itadmin_dhcp_c8_kw[2]);
+ if(dk3str_c8_len(p1) >= sl) {
+ if(dk3str_c8_ncmp(p1, itadmin_dhcp_c8_kw[2], sl) == 0) {
+ is_option = 1;
+ p1 = dk3str_c8_start(&(p1[7]), NULL);
+ }
+ }
+ } else {
+
+#line 242 "itadhcp.ctr"
+ }
+ if(p1) {
+
+#line 244 "itadhcp.ctr"
+ if(is_option) {
+
+#line 245 "itadhcp.ctr"
+ itadmin_dhcp_indent(fipo, indent);
+ fputs(itadmin_dhcp_c8_kw[3], fipo);
+ fputs(p1, fipo);
+ if(opt->v) {
+ fputc('\t', fipo);
+ fputs(opt->v, fipo);
+ }
+ fputc(';', fipo);
+ fputc('\n', fipo);
+ } else {
+
+#line 255 "itadhcp.ctr"
+ switch(dk3str_c8_array_index(itadmin_dhcp_option_names, p1, 0)) {
+ case 0: {
+
+#line 257 "itadhcp.ctr"
+ is_option = 1;
+ if(opt->v) {
+ if(dk3str_c8_is_bool(opt->v)) {
+ is_option = ((dk3str_c8_is_on(opt->v)) ? 1 : 0);
+ }
+ }
+ itadmin_dhcp_indent(fipo, indent);
+ if(!is_option) {
+ fputs(itadmin_dhcp_c8_kw[4], fipo);
+ }
+ fputs(p1, fipo);
+ fputc(';', fipo);
+ fputc('\n', fipo);
+ } break;
+ default: {
+
+#line 272 "itadhcp.ctr"
+ itadmin_dhcp_indent(fipo, indent);
+ fputs(p1, fipo);
+ if(opt->v) {
+ fputc('\t', fipo);
+ fputs(opt->v, fipo);
+ fputc(';', fipo);
+ fputc('\n', fipo);
+ }
+ } break;
+ }
+ }
+ } else {
+
+#line 284 "itadhcp.ctr"
+ }
+ } else {
+
+#line 286 "itadhcp.ctr"
+ }
+ }
+
+#line 288 "itadhcp.ctr"
+}
+
+
+
+/** Check DHCP pool for correct settings.
+ @param job Job structure.
+ @param dp Pool to check.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_dhcp_check_pool(
+ itadmin_job *job,
+ itadmin_dhcp_pool *dp
+)
+{
+ int back = 0;
+ char buffer[128];
+
+
+#line 307 "itadhcp.ctr"
+ if(dp->auc) {
+ if(!(dp->duc)) {
+ back = 1;
+ }
+ } else {
+ if(dp->duc) {
+ if(dp->acl) {
+ back = 1;
+ }
+ }
+ }
+ if(!(back)) {
+ /* ERROR: Inconsistent DHCP pool setup! */
+ sprintf(
+ buffer,
+ "%lu.%lu.%lu.%lu",
+ (((dp->ip4s) >> 24) & 0x000000FFUL),
+ (((dp->ip4s) >> 16) & 0x000000FFUL),
+ (((dp->ip4s) >> 8) & 0x000000FFUL),
+ ((dp->ip4s) & 0x000000FFUL)
+ );
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 134, 135, buffer);
+ }
+
+#line 330 "itadhcp.ctr"
+ return back;
+}
+
+
+
+/** Register DHCP group for all hosts in a class with a network.
+ @param job Job structure.
+ @param nw Network.
+ @param dc DHCP class.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_dhcp_register_class_groups(
+ itadmin_job *job,
+ itadmin_network *nw,
+ itadmin_dhcp_class *dc
+)
+{
+ itadmin_host *ho;
+ itadmin_dhcp_ginw *ginw;
+ int back = 1;
+
+
+#line 353 "itadhcp.ctr"
+ if(dc->i_ho) {
+ dk3sto_it_reset(dc->i_ho);
+ while(NULL != (ho = (itadmin_host *)dk3sto_it_next(dc->i_ho))) {
+ if(ho->dg) {
+ if(!(nw->s_dg)) {
+ nw->s_dg = dk3sto_open_app(job->app);
+ if(nw->s_dg) {
+ dk3sto_set_comp(nw->s_dg, itadmin_comp_dhcp_ginw, 0);
+ }
+ }
+ if(!(nw->i_dg)) {
+ if(nw->s_dg) {
+ nw->i_dg = dk3sto_it_open(nw->s_dg);
+ }
+ }
+ if((nw->s_dg) && (nw->i_dg)) {
+ ginw = (itadmin_dhcp_ginw *)dk3sto_it_find_like(
+ nw->i_dg, (void *)((ho->dg)->sn), 1
+ );
+ if(!(ginw)) {
+ ginw = itadmin_mem_dhcp_ginw_new(job, ho->dg);
+ if(ginw) {
+ if(!dk3sto_add(nw->s_dg, (void *)ginw)) {
+ /* ERROR: Failed to add! */
+ back = 0;
+ itadmin_mem_dhcp_ginw_del(ginw);
+ }
+ } else {
+ back = 0;
+ /* ERROR: Memory! */
+ }
+ }
+ } else {
+ back = 0;
+ }
+ }
+ }
+ }
+
+#line 391 "itadhcp.ctr"
+ return back;
+}
+
+
+
+/** Link DHCP classes to networks.
+ @param job Job structure.
+ @param i_nw Storage iterator for the networks.
+*/
+int
+itadmin_dhcp_link_classes(
+ itadmin_job *job,
+ dk3_sto_it_t *i_nw
+)
+{
+ char buffer[128];
+ itadmin_network *nw;
+ itadmin_dhcp_pool *dp;
+ itadmin_dhcp_class *dc;
+ int back = 1;
+
+
+#line 412 "itadhcp.ctr"
+ dk3sto_it_reset(i_nw);
+ while(NULL != (nw = (itadmin_network *)dk3sto_it_next(i_nw))) {
+
+#line 414 "itadhcp.ctr"
+ if(nw->i_p) {
+
+#line 415 "itadhcp.ctr"
+ dk3sto_it_reset(nw->i_p);
+ while(NULL != (dp = (itadmin_dhcp_pool *)dk3sto_it_next(nw->i_p))) {
+ if(!itadmin_dhcp_check_pool(job, dp)) { back = 0; }
+ if(!(dp->auc)) {
+
+#line 419 "itadhcp.ctr"
+ if(dp->duc) {
+
+#line 420 "itadhcp.ctr"
+ if(dp->acl) {
+
+#line 421 "itadhcp.ctr"
+ dc = dp->acl;
+
+#line 422 "itadhcp.ctr"
+ if(!(dc->dhcpn)) {
+
+#line 423 "itadhcp.ctr"
+ dc->dhcpn = nw;
+ if(!(nw->s_dc)) {
+
+#line 425 "itadhcp.ctr"
+ nw->s_dc = dk3sto_open_app(job->app);
+ if(nw->s_dc) {
+
+#line 427 "itadhcp.ctr"
+ dk3sto_set_comp(nw->s_dc, itadmin_comp_dhcp_class, 0);
+ } else {
+ back = 0;
+
+#line 430 "itadhcp.ctr"
+ }
+ }
+ if(!(nw->i_dc)) {
+
+#line 433 "itadhcp.ctr"
+ if(nw->s_dc) {
+
+#line 434 "itadhcp.ctr"
+ nw->i_dc = dk3sto_it_open(nw->s_dc);
+ } else {
+
+#line 436 "itadhcp.ctr"
+ back = 0;
+ }
+ }
+ if((nw->s_dc) && (nw->i_dc)) {
+
+#line 440 "itadhcp.ctr"
+ if(!(dk3sto_it_find_like(nw->i_dc, (void *)dc, 0))) {
+
+
+#line 442 "itadhcp.ctr"
+ if(!(dk3sto_add(nw->s_dc, (void *)dc))) {
+ back = 0;
+
+#line 444 "itadhcp.ctr"
+ }
+ }
+ } else {
+
+#line 447 "itadhcp.ctr"
+ back = 0;
+ /* ERROR: Memory */
+ }
+ } else {
+
+#line 451 "itadhcp.ctr"
+ if(((dc->dhcpn)->ip4) != (nw->ip4)) {
+ back = 0;
+
+#line 453 "itadhcp.ctr"
+ /* ERROR: Class assigned to pools in different nets! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 136, 137, dc->sn);
+ }
+ }
+ if(!itadmin_dhcp_register_class_groups(job, nw, dc)) {
+ back = 0;
+ }
+ } else {
+
+#line 461 "itadhcp.ctr"
+ /* ERROR: No allowed class specified! */
+ sprintf(
+ buffer,
+ "%lu.%lu.%lu.%lu",
+ (((dp->ip4s) >> 24) & 0x000000FFUL),
+ (((dp->ip4s) >> 16) & 0x000000FFUL),
+ (((dp->ip4s) >> 8) & 0x000000FFUL),
+ ((dp->ip4s) & 0x000000FFUL)
+ );
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 134, 138, buffer);
+ }
+ } else {
+
+#line 473 "itadhcp.ctr"
+ }
+ } else {
+
+#line 475 "itadhcp.ctr"
+ }
+ }
+ } else {
+
+#line 478 "itadhcp.ctr"
+ }
+ }
+
+#line 480 "itadhcp.ctr"
+ return back;
+}
+
+
+
+/** Write DHCP classes to output file.
+ @param job Job structure.
+ @param fipo output file.
+*/
+static
+void
+itadmin_dhcp_write_classes(itadmin_job *job, FILE *fipo)
+{
+ itadmin_dhcp_class *dc;
+ itadmin_host *ho;
+ int is_first;
+
+
+#line 497 "itadhcp.ctr"
+ dk3sto_it_reset(job->i_dc);
+ while(NULL != (dc = (itadmin_dhcp_class *)dk3sto_it_next(job->i_dc))) {
+
+
+#line 500 "itadhcp.ctr"
+ if((dc->sn) && (dc->dhcpn)) {
+
+#line 501 "itadhcp.ctr"
+ is_first = 1;
+ if(dc->i_ho) {
+
+#line 503 "itadhcp.ctr"
+ dk3sto_it_reset(dc->i_ho);
+ while(NULL != (ho = (itadmin_host *)dk3sto_it_next(dc->i_ho))) {
+ if((ho->sn) && (ho->maca) && (!(ho->ipv4))) {
+ if(is_first) {
+ fputc('\n', fipo);
+ fputs(itadmin_dhcp_c8_kw[6], fipo);
+ fputs(dc->sn, fipo);
+ fputs(itadmin_dhcp_c8_kw[7], fipo);
+ fputc('\n', fipo);
+ }
+ is_first = 0;
+ fputs(itadmin_dhcp_c8_kw[11], fipo);
+ fputs(ho->sn, fipo);
+ fputc('\n', fipo);
+ fputs(itadmin_dhcp_c8_kw[8], fipo);
+ fputs(dc->sn, fipo);
+ fputs(itadmin_dhcp_c8_kw[9], fipo);
+ fputs(ho->maca, fipo);
+ fputs(itadmin_dhcp_c8_kw[10], fipo);
+ fputc('\n', fipo);
+ }
+ }
+
+#line 525 "itadhcp.ctr"
+ } else {
+
+#line 526 "itadhcp.ctr"
+ }
+ }
+ }
+
+#line 529 "itadhcp.ctr"
+}
+
+
+
+/** Write one DHCP pool to output.
+ @param job Job structure.
+ @param fipo Output file.
+ @param dp Pool to write.
+ @param indent Line indent level.
+*/
+static
+void
+itadmin_dhcp_write_pool(
+ itadmin_job *job,
+ FILE *fipo,
+ itadmin_dhcp_pool *dp,
+ int indent
+)
+{
+ itadmin_dhcp_class *dc;
+
+
+#line 550 "itadhcp.ctr"
+ itadmin_dhcp_indent(fipo, indent);
+ fputs(itadmin_dhcp_c8_kw[20], fipo);
+ fputc('\n', fipo);
+ itadmin_dhcp_indent(fipo, indent);
+ fputs(itadmin_dhcp_c8_kw[13], fipo);
+ fputc('\n', fipo);
+ itadmin_dhcp_indent(fipo, (indent + 1));
+ fputs(itadmin_dhcp_c8_kw[21], fipo);
+ itadmin_tool_write_ip(fipo, dp->ip4s);
+ fputc('\t', fipo);
+ itadmin_tool_write_ip(fipo, dp->ip4e);
+ fputc(';', fipo);
+ fputc('\n', fipo);
+ if(dp->auc) {
+ itadmin_dhcp_indent(fipo, (indent + 1));
+ fputs(itadmin_dhcp_c8_kw[22], fipo);
+ fputc('\n', fipo);
+ /* Fuer alle Klassen verbieten */
+ if(job->i_dc) {
+ dk3sto_it_reset(job->i_dc);
+ while(NULL != (dc = (itadmin_dhcp_class *)dk3sto_it_next(job->i_dc))) {
+ itadmin_dhcp_indent(fipo, (indent + 1));
+ fputs(itadmin_dhcp_c8_kw[25], fipo);
+ fputs(dc->sn, fipo);
+ fputs(itadmin_dhcp_c8_kw[26], fipo);
+ fputc('\n', fipo);
+ }
+ }
+ } else {
+ itadmin_dhcp_indent(fipo, (indent + 1));
+ fputs(itadmin_dhcp_c8_kw[23], fipo);
+ fputc('\n', fipo);
+ if(dp->acl) {
+ itadmin_dhcp_indent(fipo, (indent + 1));
+ fputs(itadmin_dhcp_c8_kw[24], fipo);
+ fputs((dp->acl)->sn, fipo);
+ fputs(itadmin_dhcp_c8_kw[26], fipo);
+ fputc('\n', fipo);
+ }
+ }
+ /* POOL OPTIONS */
+ if(dp->i_do) {
+ itadmin_dhcp_write_options(job, fipo, dp->i_do, 4, (indent+1));
+ }
+ /* Release leases on shutdown for pool */
+ if (1 == job->rel) {
+ itadmin_dhcp_indent(fipo, (indent+1));
+ fputs(itadmin_dhcp_c8_kw[36], fipo);
+ itadmin_dhcp_indent(fipo, (indent+1));
+ fputs(itadmin_dhcp_c8_kw[37], fipo);
+ itadmin_dhcp_indent(fipo, (indent+1));
+ fputs(itadmin_dhcp_c8_kw[38], fipo);
+ itadmin_dhcp_indent(fipo, (indent+1));
+ fputs(itadmin_dhcp_c8_kw[39], fipo);
+ }
+ itadmin_dhcp_indent(fipo, indent);
+ fputs(itadmin_dhcp_c8_kw[14], fipo);
+ fputc('\n', fipo);
+
+#line 608 "itadhcp.ctr"
+}
+
+
+
+/** Write one host in group.
+ @param job Job structure.
+ @param fipo Output file.
+ @param ho Host to write.
+ @param ind Indent level at beginning of line.
+*/
+static
+void
+itadmin_dhcp_write_one_host(
+ itadmin_job *job,
+ FILE *fipo,
+ itadmin_host *ho,
+ int ind
+)
+{
+
+
+#line 628 "itadhcp.ctr"
+ if((ho->sn) && (ho->maca)) {
+ itadmin_dhcp_indent(fipo, ind);
+ fputs(itadmin_dhcp_c8_kw[28], fipo);
+ fputs(ho->sn, fipo);
+ fputc('\n', fipo);
+ itadmin_dhcp_indent(fipo, ind);
+ fputs(itadmin_dhcp_c8_kw[13], fipo);
+ fputc('\n', fipo);
+
+ itadmin_dhcp_indent(fipo, (ind + 1));
+ fputs(itadmin_dhcp_c8_kw[29], fipo);
+ fputs(ho->sn, fipo);
+ fputs(itadmin_dhcp_c8_kw[26], fipo);
+ fputc('\n', fipo);
+
+ itadmin_dhcp_indent(fipo, (ind + 1));
+ fputs(itadmin_dhcp_c8_kw[30], fipo);
+ fputs(ho->maca, fipo);
+ fputs(itadmin_dhcp_c8_kw[10], fipo);
+ fputc('\n', fipo);
+
+ if(ho->ipv4) {
+ itadmin_dhcp_indent(fipo, (ind + 1));
+ fputs(itadmin_dhcp_c8_kw[31], fipo);
+ itadmin_tool_write_ip(fipo, ho->ipv4);
+ fputs(itadmin_dhcp_c8_kw[10], fipo);
+ fputc('\n', fipo);
+ }
+
+ /* Added 2013-09-14: Must write host options too. */
+ if((ho->s_do) && (ho->i_do)) {
+ itadmin_dhcp_write_options(job, fipo, ho->i_do, 3, (ind+1));
+ }
+
+ itadmin_dhcp_indent(fipo, ind);
+ fputs(itadmin_dhcp_c8_kw[14], fipo);
+ fputc('\n', fipo);
+ }
+
+#line 666 "itadhcp.ctr"
+}
+
+
+
+/** Write hosts of one group for a network.
+
+*/
+static
+void
+itadmin_dhcp_write_group(
+ itadmin_job *job,
+ FILE *fipo,
+ itadmin_network *nw,
+ dk3_sto_it_t *i_ho,
+ itadmin_dhcp_group *gr,
+ int ind
+
+)
+{
+ itadmin_host *ho;
+ itadmin_dhcp_class *dc;
+ int is_first;
+ int is_in_group;
+
+
+#line 690 "itadhcp.ctr"
+ if(gr) {
+
+#line 691 "itadhcp.ctr"
+ } else {
+
+#line 692 "itadhcp.ctr"
+ }
+ is_first = 1;
+ if(i_ho) {
+ dk3sto_it_reset(i_ho);
+ while(NULL != (ho = (itadmin_host *)dk3sto_it_next(i_ho))) {
+ if((ho->sn) && (ho->maca)) {
+ if(is_first) {
+ itadmin_dhcp_indent(fipo, ind);
+ fputs(itadmin_dhcp_c8_kw[27], fipo);
+ fputc('\n', fipo);
+ itadmin_dhcp_indent(fipo, ind);
+ fputs(itadmin_dhcp_c8_kw[13], fipo);
+ fputc('\n', fipo);
+ if(gr) {
+ if(gr->i_do) {
+ itadmin_dhcp_write_options(job, fipo, gr->i_do, 3, (ind+1));
+ fputc('\n', fipo);
+ }
+ }
+ } is_first = 0;
+ itadmin_dhcp_write_one_host(job, fipo, ho, (ind + 1));
+ }
+ }
+ }
+ if(nw) {
+ if(nw->i_dc) {
+ dk3sto_it_reset(nw->i_dc);
+ while(NULL != (dc = (itadmin_dhcp_class *)dk3sto_it_next(nw->i_dc))) {
+ if(dc->i_ho) {
+ dk3sto_it_reset(dc->i_ho);
+ while(NULL != (ho = (itadmin_host *)dk3sto_it_next(dc->i_ho))) {
+ is_in_group = 0;
+ if(ho->dg) {
+ if(gr) {
+ if(itadmin_comp_dhcp_group((void *)(ho->dg),(void *)gr,0) == 0)
+ {
+ is_in_group = 1;
+ }
+ }
+ } else {
+ if(!(gr)) {
+ is_in_group = 1;
+ }
+ }
+ if(is_in_group) {
+ if(is_first) {
+ itadmin_dhcp_indent(fipo, ind);
+ fputs(itadmin_dhcp_c8_kw[27], fipo);
+ fputc('\n', fipo);
+ itadmin_dhcp_indent(fipo, ind);
+ fputs(itadmin_dhcp_c8_kw[13], fipo);
+ fputc('\n', fipo);
+ if(gr) {
+ if(gr->i_do) {
+ itadmin_dhcp_write_options(job,fipo,gr->i_do,3,(ind + 1));
+ fputc('\n', fipo);
+ }
+ }
+ } is_first = 0;
+ itadmin_dhcp_write_one_host(job, fipo, ho, (ind + 1));
+ }
+ }
+ }
+ }
+ }
+ }
+ if(!(is_first)) {
+ itadmin_dhcp_indent(fipo, ind);
+ fputs(itadmin_dhcp_c8_kw[14], fipo);
+ fputc('\n', fipo);
+ }
+
+
+#line 764 "itadhcp.ctr"
+}
+
+
+
+/** Write one network to output file.
+ @param job Job structure.
+ @param fipo Output file.
+ @param nw Network to write.
+ @param indent Indent at start of file.
+*/
+static
+void
+itadmin_dhcp_write_one_network(
+ itadmin_job *job,
+ FILE *fipo,
+ itadmin_network *nw,
+ int indent
+)
+{
+ itadmin_dhcp_pool *dp;
+ itadmin_dhcp_ginw *ginw;
+
+
+#line 786 "itadhcp.ctr"
+ itadmin_dhcp_indent(fipo, indent);
+ fputs(itadmin_dhcp_c8_kw[15], fipo);
+ itadmin_tool_write_ip(fipo, nw->ip4);
+ fputs(itadmin_dhcp_c8_kw[16], fipo);
+ itadmin_tool_write_ip(fipo, nw->ma4);
+ fputc('\n', fipo);
+ itadmin_dhcp_indent(fipo, indent);
+ fputs(itadmin_dhcp_c8_kw[13], fipo);
+ fputc('\n', fipo);
+ itadmin_dhcp_indent(fipo, (indent + 1));
+ fputs(itadmin_dhcp_c8_kw[17], fipo);
+ itadmin_tool_write_ip(fipo, nw->gw4);
+ fputc(';', fipo);
+ fputc('\n', fipo);
+ itadmin_dhcp_indent(fipo, (indent + 1));
+ fputs(itadmin_dhcp_c8_kw[18], fipo);
+ itadmin_tool_write_ip(fipo, nw->ma4);
+ fputc(';', fipo);
+ fputc('\n', fipo);
+ itadmin_dhcp_indent(fipo, (indent + 1));
+ fputs(itadmin_dhcp_c8_kw[19], fipo);
+ itadmin_tool_write_ip(fipo, nw->bc4);
+ fputc(';', fipo);
+ fputc('\n', fipo);
+ /* DHCP options */
+ if(nw->i_do) {
+ itadmin_dhcp_write_options(job, fipo, nw->i_do, 2, (indent+1));
+ fputc('\n', fipo);
+ }
+ /* Pools */
+ if(nw->i_p) {
+ dk3sto_it_reset(nw->i_p);
+ while(NULL != (dp = (itadmin_dhcp_pool *)dk3sto_it_next(nw->i_p))) {
+ itadmin_dhcp_write_pool(job, fipo, dp, (indent + 1));
+ }
+ }
+ /* Groups, direct for network and in DHCP classes */
+ if(nw->i_dg) {
+ dk3sto_it_reset(nw->i_dg);
+ while(NULL != (ginw = (itadmin_dhcp_ginw *)dk3sto_it_next(nw->i_dg))) {
+ itadmin_dhcp_write_group(job,fipo,nw,ginw->i_h,ginw->gr,(indent + 1));
+ }
+ }
+ /* Hosts without groups, direct for network and in DHCP classes */
+ itadmin_dhcp_write_group(job, fipo, nw, nw->i_hoi, NULL, (indent + 1));
+ itadmin_dhcp_indent(fipo, indent);
+ fputs(itadmin_dhcp_c8_kw[14], fipo);
+ fputc('\n', fipo);
+
+#line 834 "itadhcp.ctr"
+}
+
+
+
+/** Write DHCP networks.
+ @param job Job structure.
+ @param fipo Output file.
+ @param i_nw Iterator for networks storage.
+*/
+static
+void
+itadmin_dhcp_write_networks(
+ itadmin_job *job,
+ FILE *fipo,
+ dk3_sto_it_t *i_nw
+)
+{
+ itadmin_network *nw;
+
+
+#line 853 "itadhcp.ctr"
+ dk3sto_it_reset(i_nw);
+ while(NULL != (nw = (itadmin_network *)dk3sto_it_next(i_nw))) {
+ itadmin_dhcp_write_one_network(job, fipo, nw, 1);
+ }
+
+#line 857 "itadhcp.ctr"
+}
+
+
+
+/** Write data for one VLAN to output.
+ @param job Job structure.
+ @param fipo Output file.
+ @param i_nw Networks iterator.
+ @param i_do DHCP options storage iterator.
+*/
+static
+void
+itadmin_dhcp_write_vlan(
+ itadmin_job *job,
+ FILE *fipo,
+ dk3_sto_it_t *i_nw,
+ dk3_sto_it_t *i_do
+)
+{
+ itadmin_network *nw;
+ int num_networks;
+
+
+#line 879 "itadhcp.ctr"
+ num_networks = 0;
+ if(i_nw) {
+ dk3sto_it_reset(i_nw);
+ while(NULL != dk3sto_it_next(i_nw)) { num_networks++; }
+ if(num_networks > 0) {
+ dk3sto_it_reset(i_nw);
+ if((num_networks > 1) || (i_do)) {
+ fputs(itadmin_dhcp_c8_kw[12], fipo);
+ fputc('\n', fipo);
+ fputs(itadmin_dhcp_c8_kw[13], fipo);
+ fputc('\n', fipo);
+ if(i_do) {
+ itadmin_dhcp_write_options(job, fipo, i_do, 1, 1);
+ }
+ itadmin_dhcp_write_networks(job, fipo, i_nw);
+ fputs(itadmin_dhcp_c8_kw[14], fipo);
+ fputc('\n', fipo);
+ } else {
+ nw = (itadmin_network *)dk3sto_it_next(i_nw);
+ if(nw) {
+ itadmin_dhcp_write_one_network(job, fipo, nw, 0);
+ }
+ }
+ }
+ }
+
+#line 904 "itadhcp.ctr"
+}
+
+
+
+static
+void
+itadmin_dhcp_declare_msft_options(itadmin_job *job, FILE *fipo)
+{
+ if (0 < job->rel) {
+ fputs(itadmin_dhcp_c8_kw[34], fipo);
+ fputs(itadmin_dhcp_c8_kw[35], fipo);
+ }
+ if (2 == job->rel) {
+ fputs(itadmin_dhcp_c8_kw[36], fipo);
+ fputs(itadmin_dhcp_c8_kw[37], fipo);
+ fputs(itadmin_dhcp_c8_kw[38], fipo);
+ fputs(itadmin_dhcp_c8_kw[39], fipo);
+ fputc('\n', fipo);
+ }
+}
+
+
+
+/** Write output file for a VLAN or all networks.
+ @param job Job structure.
+ @param vlanname Name of VLAN (NULL if not specified).
+ @param i_nw Iterator for all networks.
+ @param i_do Iterator for VLAN DHCP options (may be NULL).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_dhcpd_output(
+ itadmin_job *job,
+ dkChar const *vlanname,
+ dk3_sto_it_t *i_nw,
+ dk3_sto_it_t *i_do
+)
+{
+ FILE *fipo;
+ int back = 0;
+
+
+#line 946 "itadhcp.ctr"
+ if(itadmin_dhcp_link_classes(job, i_nw)) {
+
+#line 947 "itadhcp.ctr"
+ fipo = dk3sf_c8_fopen_app(
+ itadmin_dhcp_c8_kw[0], itadmin_dhcp_c8_kw[5], job->app
+ );
+ if(fipo) {
+
+#line 951 "itadhcp.ctr"
+ itadmin_dhcp_write_options(job, fipo, job->i_do, 0, 0);
+ fputc('\n', fipo);
+ itadmin_dhcp_declare_msft_options(job, fipo);
+ fputs(itadmin_dhcp_c8_kw[32], fipo);
+ itadmin_dhcp_write_classes(job, fipo);
+ fputc('\n', fipo);
+ fputs(itadmin_dhcp_c8_kw[33], fipo);
+ itadmin_dhcp_write_vlan(job, fipo, i_nw, i_do);
+ back = 1;
+#if DK3_CHAR_SIZE == 1
+ if(!dk3sf_fclose_fn_app(fipo, itadmin_dhcp_c8_kw[0], job->app)) {
+ back = 0;
+ }
+#else
+ if(!dk3sf_fclose_fn_app(fipo, NULL, job->app)) {
+ back = 0;
+ }
+#endif
+ } else {
+
+#line 970 "itadhcp.ctr"
+ /* ERROR: Failed to open file. */
+ }
+ } else {
+
+#line 973 "itadhcp.ctr"
+ }
+
+#line 974 "itadhcp.ctr"
+ return back;
+}
+
+
+
+int
+itadmin_dhcpd_conf_output(itadmin_job *job)
+{
+ char vlname[ITADMIN_CONFIG_LINE_SIZE];
+ itadmin_vlan *dhcpvl;
+ int back = 0;
+ int res;
+
+
+#line 987 "itadhcp.ctr"
+ if(job->vlan) {
+ res = dk3str_str_to_c8u_app(
+ vlname, sizeof(vlname), job->vlan,
+ dk3app_get_encoding(job->app), job->app
+ );
+ if(res) {
+ dhcpvl =
+ (itadmin_vlan *)dk3sto_it_find_like(job->i_vl, (void *)vlname, 1);
+ if(dhcpvl) {
+ back = itadmin_dhcpd_output(job, dhcpvl->s, dhcpvl->i_nw, dhcpvl->i_do);
+ } else {
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 139, 140, job->vlan);
+ }
+ } else {
+ /* ERROR: Failed to convert VLAN name! */
+ }
+ } else {
+ back = itadmin_dhcpd_output(job, NULL, job->i_nw, NULL);
+ }
+
+#line 1006 "itadhcp.ctr"
+ return back;
+}
+
diff --git a/support/dktools/itadhcp.ctr b/support/dktools/itadhcp.ctr
new file mode 100644
index 0000000000..d9557012ba
--- /dev/null
+++ b/support/dktools/itadhcp.ctr
@@ -0,0 +1,1008 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk3all.h"
+#include "itadmin.h"
+
+
+$!trace-include
+
+
+
+/** Keywords used by the module.
+*/
+static char const * const itadmin_dhcp_c8_kw[] = {
+$!string-table
+#
+# 0: File name "dhcpd.conf"
+#
+dhcpd.conf
+#
+# 1: Indent level
+#
+
+#
+# 2: Line start option:
+#
+option:
+#
+# 3: option: must be replaced by option
+#
+option
+#
+# 4: Prefix for "not authorative"
+#
+not
+#
+# 5: File mode w
+#
+w
+#
+# 6: Start of dhcpd.conf class line
+#
+class "
+#
+# 7: End of dhcpd.conf class line
+#
+" { match hardware; }
+#
+# 8: Start of subclass line
+#
+subclass "
+#
+# 9: Center of subclass line
+#
+" 1:
+#
+# 10: End of subclass line
+#
+;
+#
+# 11: Comment for machine in DHCP class
+#
+\#
+#
+# 12: Section start for shared-network
+#
+shared-network dhcpnet
+#
+# 13: Opening bracket
+#
+{
+#
+# 14: Closing bracket
+#
+}
+#
+# 15: Start of subnet line
+#
+subnet
+#
+# 16: Central part of subnet line
+#
+ netmask
+#
+# 17: Network option router
+#
+option routers
+#
+# 18: Network option subnet-mask
+#
+option subnet-mask
+#
+# 19: Network option broadcast
+#
+option broadcast-address
+#
+# 20: Keyword pool
+#
+pool
+#
+# 21: Keyword range
+#
+range
+#
+# 22: Option "allow unknown clients"
+#
+allow unknown clients;
+#
+# 23: Option "deny unknown clients"
+#
+deny unknown clients;
+#
+# 24: Option "allow members of..."
+#
+allow members of "
+#
+# 25: Option deny members of ..."
+#
+deny members of "
+#
+# 26: End of allow/deny option
+#
+";
+#
+# 27: DHCP group
+#
+group
+#
+# 28: Keyword host.
+#
+host
+#
+# 29: DHCP option host-name
+#
+option host-name "
+#
+# 30: Keyword hardware ethernet
+#
+hardware ethernet
+#
+# 31: Keyword fixed-address
+#
+fixed-address
+#
+# 32: Point marker 1
+#
+\n# ##### ITADMIN_POINT_1: After options, before classes\n\n
+#
+# 33: Point marker 2
+#
+\n# ##### ITADMIN_POINT_2: After classes, before VLAN\n\n
+#
+# 34 35 Option declaration to release leases on shutdown.
+#
+option space MSFT;\n
+option MSFT.release-dhcp-lease-on-shutdown code 2 = unsigned integer 32;\n\n
+#
+# 36 37 38 39 Text to release leases on shutdown.
+#
+if substring (option vendor-class-identifier, 0, 4) = "MSFT" {\n
+ option MSFT.release-dhcp-lease-on-shutdown 1;\n
+ vendor-option-space MSFT;\n
+}\n
+$!end
+};
+
+
+
+
+/** Option names requiring special treatment.
+*/
+static char const * const itadmin_dhcp_option_names[] = {
+$!string-table
+authorative
+$!end
+};
+
+
+
+
+
+/** Indent line.
+ @param fipo Output file.
+ @param ind Indent level.
+*/
+static
+void
+itadmin_dhcp_indent(FILE *fipo, int ind)
+{
+ int i;
+ for(i = 0; i < ind; i++) {
+ fputs(itadmin_dhcp_c8_kw[1], fipo);
+ }
+}
+
+
+
+/** Write DHCP options.
+ @param job Job structure.
+ @param fipo Output file.
+ @param i_o Options storage iterator.
+ @param objtype Object type (ignored).
+ @param indent Indent level.
+
+*/
+static
+void
+itadmin_dhcp_write_options(
+ itadmin_job *job,
+ FILE *fipo,
+ dk3_sto_it_t *i_o,
+ int objtype,
+ int indent
+)
+{
+ itadmin_dhcp_option *opt;
+ char const *p1;
+ size_t sl;
+ int is_option;
+ $? "+ itadmin_dhcp_write_options"
+ dk3sto_it_reset(i_o);
+ while(NULL != (opt = (itadmin_dhcp_option *)dk3sto_it_next(i_o))) { $? ". opt"
+ is_option = 0;
+ if(opt->k) { $? ". k"
+ p1 = dk3str_c8_start(opt->k, NULL);
+ if(p1) { $? ". text in k"
+ sl = strlen(itadmin_dhcp_c8_kw[2]);
+ if(dk3str_c8_len(p1) >= sl) {
+ if(dk3str_c8_ncmp(p1, itadmin_dhcp_c8_kw[2], sl) == 0) {
+ is_option = 1;
+ p1 = dk3str_c8_start(&(p1[7]), NULL);
+ }
+ }
+ } else { $? "! no text in k"
+ }
+ if(p1) { $? ". text in k"
+ if(is_option) { $? ". option:"
+ itadmin_dhcp_indent(fipo, indent);
+ fputs(itadmin_dhcp_c8_kw[3], fipo);
+ fputs(p1, fipo);
+ if(opt->v) {
+ fputc('\t', fipo);
+ fputs(opt->v, fipo);
+ }
+ fputc(';', fipo);
+ fputc('\n', fipo);
+ } else { $? ". not option:"
+ switch(dk3str_c8_array_index(itadmin_dhcp_option_names, p1, 0)) {
+ case 0: { $? ". authorative"
+ is_option = 1;
+ if(opt->v) {
+ if(dk3str_c8_is_bool(opt->v)) {
+ is_option = ((dk3str_c8_is_on(opt->v)) ? 1 : 0);
+ }
+ }
+ itadmin_dhcp_indent(fipo, indent);
+ if(!is_option) {
+ fputs(itadmin_dhcp_c8_kw[4], fipo);
+ }
+ fputs(p1, fipo);
+ fputc(';', fipo);
+ fputc('\n', fipo);
+ } break;
+ default: { $? ". no special treatment"
+ itadmin_dhcp_indent(fipo, indent);
+ fputs(p1, fipo);
+ if(opt->v) {
+ fputc('\t', fipo);
+ fputs(opt->v, fipo);
+ fputc(';', fipo);
+ fputc('\n', fipo);
+ }
+ } break;
+ }
+ }
+ } else { $? "! no text in k"
+ }
+ } else { $? "! k"
+ }
+ } $? "- itadmin_dhcp_write_options"
+}
+
+
+
+/** Check DHCP pool for correct settings.
+ @param job Job structure.
+ @param dp Pool to check.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_dhcp_check_pool(
+ itadmin_job *job,
+ itadmin_dhcp_pool *dp
+)
+{
+ int back = 0;
+ char buffer[128];
+ $? "+ itadmin_dhcp_check_pool"
+ if(dp->auc) {
+ if(!(dp->duc)) {
+ back = 1;
+ }
+ } else {
+ if(dp->duc) {
+ if(dp->acl) {
+ back = 1;
+ }
+ }
+ }
+ if(!(back)) {
+ /* ERROR: Inconsistent DHCP pool setup! */
+ sprintf(
+ buffer,
+ "%lu.%lu.%lu.%lu",
+ (((dp->ip4s) >> 24) & 0x000000FFUL),
+ (((dp->ip4s) >> 16) & 0x000000FFUL),
+ (((dp->ip4s) >> 8) & 0x000000FFUL),
+ ((dp->ip4s) & 0x000000FFUL)
+ );
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 134, 135, buffer);
+ } $? "- itadmin_dhcp_check_pool %d", back
+ return back;
+}
+
+
+
+/** Register DHCP group for all hosts in a class with a network.
+ @param job Job structure.
+ @param nw Network.
+ @param dc DHCP class.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_dhcp_register_class_groups(
+ itadmin_job *job,
+ itadmin_network *nw,
+ itadmin_dhcp_class *dc
+)
+{
+ itadmin_host *ho;
+ itadmin_dhcp_ginw *ginw;
+ int back = 1;
+ $? "+ itadmin_dhcp_register_class_groups"
+ if(dc->i_ho) {
+ dk3sto_it_reset(dc->i_ho);
+ while(NULL != (ho = (itadmin_host *)dk3sto_it_next(dc->i_ho))) {
+ if(ho->dg) {
+ if(!(nw->s_dg)) {
+ nw->s_dg = dk3sto_open_app(job->app);
+ if(nw->s_dg) {
+ dk3sto_set_comp(nw->s_dg, itadmin_comp_dhcp_ginw, 0);
+ }
+ }
+ if(!(nw->i_dg)) {
+ if(nw->s_dg) {
+ nw->i_dg = dk3sto_it_open(nw->s_dg);
+ }
+ }
+ if((nw->s_dg) && (nw->i_dg)) {
+ ginw = (itadmin_dhcp_ginw *)dk3sto_it_find_like(
+ nw->i_dg, (void *)((ho->dg)->sn), 1
+ );
+ if(!(ginw)) {
+ ginw = itadmin_mem_dhcp_ginw_new(job, ho->dg);
+ if(ginw) {
+ if(!dk3sto_add(nw->s_dg, (void *)ginw)) {
+ /* ERROR: Failed to add! */
+ back = 0;
+ itadmin_mem_dhcp_ginw_del(ginw);
+ }
+ } else {
+ back = 0;
+ /* ERROR: Memory! */
+ }
+ }
+ } else {
+ back = 0;
+ }
+ }
+ }
+ } $? "- itadmin_dhcp_register_class_groups %d", back
+ return back;
+}
+
+
+
+/** Link DHCP classes to networks.
+ @param job Job structure.
+ @param i_nw Storage iterator for the networks.
+*/
+int
+itadmin_dhcp_link_classes(
+ itadmin_job *job,
+ dk3_sto_it_t *i_nw
+)
+{
+ char buffer[128];
+ itadmin_network *nw;
+ itadmin_dhcp_pool *dp;
+ itadmin_dhcp_class *dc;
+ int back = 1;
+ $? "+ itadmin_dhcp_link_classes"
+ dk3sto_it_reset(i_nw);
+ while(NULL != (nw = (itadmin_network *)dk3sto_it_next(i_nw))) { $? ".nw"
+ if(nw->i_p) { $? ". have pools"
+ dk3sto_it_reset(nw->i_p);
+ while(NULL != (dp = (itadmin_dhcp_pool *)dk3sto_it_next(nw->i_p))) {
+ if(!itadmin_dhcp_check_pool(job, dp)) { back = 0; }
+ if(!(dp->auc)) { $? ". unknown clients not allowed"
+ if(dp->duc) { $? ". unknown clients denied"
+ if(dp->acl) { $? ". pool allows one class only"
+ dc = dp->acl; $? ". class \"%!8s\"", TR_8STR(dc->sn)
+ if(!(dc->dhcpn)) { $? ". register new class to net"
+ dc->dhcpn = nw;
+ if(!(nw->s_dc)) { $? ". created storage"
+ nw->s_dc = dk3sto_open_app(job->app);
+ if(nw->s_dc) { $? ". storage ok"
+ dk3sto_set_comp(nw->s_dc, itadmin_comp_dhcp_class, 0);
+ } else {
+ back = 0; $? "! storage"
+ }
+ }
+ if(!(nw->i_dc)) { $? ". create iterator"
+ if(nw->s_dc) { $? ". iterator ok"
+ nw->i_dc = dk3sto_it_open(nw->s_dc);
+ } else { $? "! iterator"
+ back = 0;
+ }
+ }
+ if((nw->s_dc) && (nw->i_dc)) { $? ". storage and iterator"
+ if(!(dk3sto_it_find_like(nw->i_dc, (void *)dc, 0))) {
+ $? ". must add"
+ if(!(dk3sto_add(nw->s_dc, (void *)dc))) {
+ back = 0; $? "! failed to add"
+ }
+ }
+ } else { $? "! iterator or storage"
+ back = 0;
+ /* ERROR: Memory */
+ }
+ } else { $? ". class already registered in a net"
+ if(((dc->dhcpn)->ip4) != (nw->ip4)) {
+ back = 0; $? "! class registered in another net"
+ /* ERROR: Class assigned to pools in different nets! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 136, 137, dc->sn);
+ }
+ }
+ if(!itadmin_dhcp_register_class_groups(job, nw, dc)) {
+ back = 0;
+ }
+ } else { $? "! no class specified"
+ /* ERROR: No allowed class specified! */
+ sprintf(
+ buffer,
+ "%lu.%lu.%lu.%lu",
+ (((dp->ip4s) >> 24) & 0x000000FFUL),
+ (((dp->ip4s) >> 16) & 0x000000FFUL),
+ (((dp->ip4s) >> 8) & 0x000000FFUL),
+ ((dp->ip4s) & 0x000000FFUL)
+ );
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 134, 138, buffer);
+ }
+ } else { $? ". unknown clients not denied"
+ }
+ } else { $? ". unknown clients allowed"
+ }
+ }
+ } else { $? ". no pools in network"
+ }
+ } $? "- itadmin_dhcp_link_classes %d", back
+ return back;
+}
+
+
+
+/** Write DHCP classes to output file.
+ @param job Job structure.
+ @param fipo output file.
+*/
+static
+void
+itadmin_dhcp_write_classes(itadmin_job *job, FILE *fipo)
+{
+ itadmin_dhcp_class *dc;
+ itadmin_host *ho;
+ int is_first;
+ $? "+ itadmin_dhcp_write_classes"
+ dk3sto_it_reset(job->i_dc);
+ while(NULL != (dc = (itadmin_dhcp_class *)dk3sto_it_next(job->i_dc))) {
+ $? ". class \"%!8s\" PTR=%d", TR_8STR(dc->sn), TR_IPTR(dc->dhcpn)
+ if((dc->sn) && (dc->dhcpn)) { $? ". handle class"
+ is_first = 1;
+ if(dc->i_ho) { $? ". hosts iterator"
+ dk3sto_it_reset(dc->i_ho);
+ while(NULL != (ho = (itadmin_host *)dk3sto_it_next(dc->i_ho))) {
+ if((ho->sn) && (ho->maca) && (!(ho->ipv4))) {
+ if(is_first) {
+ fputc('\n', fipo);
+ fputs(itadmin_dhcp_c8_kw[6], fipo);
+ fputs(dc->sn, fipo);
+ fputs(itadmin_dhcp_c8_kw[7], fipo);
+ fputc('\n', fipo);
+ }
+ is_first = 0;
+ fputs(itadmin_dhcp_c8_kw[11], fipo);
+ fputs(ho->sn, fipo);
+ fputc('\n', fipo);
+ fputs(itadmin_dhcp_c8_kw[8], fipo);
+ fputs(dc->sn, fipo);
+ fputs(itadmin_dhcp_c8_kw[9], fipo);
+ fputs(ho->maca, fipo);
+ fputs(itadmin_dhcp_c8_kw[10], fipo);
+ fputc('\n', fipo);
+ }
+ } $? ". all hosts handled"
+ } else { $? "! hosts iterator"
+ }
+ }
+ } $? "- itadmin_dhcp_write_classes"
+}
+
+
+
+/** Write one DHCP pool to output.
+ @param job Job structure.
+ @param fipo Output file.
+ @param dp Pool to write.
+ @param indent Line indent level.
+*/
+static
+void
+itadmin_dhcp_write_pool(
+ itadmin_job *job,
+ FILE *fipo,
+ itadmin_dhcp_pool *dp,
+ int indent
+)
+{
+ itadmin_dhcp_class *dc;
+ $? "+ itadmin_dhcp_write_pool"
+ itadmin_dhcp_indent(fipo, indent);
+ fputs(itadmin_dhcp_c8_kw[20], fipo);
+ fputc('\n', fipo);
+ itadmin_dhcp_indent(fipo, indent);
+ fputs(itadmin_dhcp_c8_kw[13], fipo);
+ fputc('\n', fipo);
+ itadmin_dhcp_indent(fipo, (indent + 1));
+ fputs(itadmin_dhcp_c8_kw[21], fipo);
+ itadmin_tool_write_ip(fipo, dp->ip4s);
+ fputc('\t', fipo);
+ itadmin_tool_write_ip(fipo, dp->ip4e);
+ fputc(';', fipo);
+ fputc('\n', fipo);
+ if(dp->auc) {
+ itadmin_dhcp_indent(fipo, (indent + 1));
+ fputs(itadmin_dhcp_c8_kw[22], fipo);
+ fputc('\n', fipo);
+ /* Fuer alle Klassen verbieten */
+ if(job->i_dc) {
+ dk3sto_it_reset(job->i_dc);
+ while(NULL != (dc = (itadmin_dhcp_class *)dk3sto_it_next(job->i_dc))) {
+ itadmin_dhcp_indent(fipo, (indent + 1));
+ fputs(itadmin_dhcp_c8_kw[25], fipo);
+ fputs(dc->sn, fipo);
+ fputs(itadmin_dhcp_c8_kw[26], fipo);
+ fputc('\n', fipo);
+ }
+ }
+ } else {
+ itadmin_dhcp_indent(fipo, (indent + 1));
+ fputs(itadmin_dhcp_c8_kw[23], fipo);
+ fputc('\n', fipo);
+ if(dp->acl) {
+ itadmin_dhcp_indent(fipo, (indent + 1));
+ fputs(itadmin_dhcp_c8_kw[24], fipo);
+ fputs((dp->acl)->sn, fipo);
+ fputs(itadmin_dhcp_c8_kw[26], fipo);
+ fputc('\n', fipo);
+ }
+ }
+ /* POOL OPTIONS */
+ if(dp->i_do) {
+ itadmin_dhcp_write_options(job, fipo, dp->i_do, 4, (indent+1));
+ }
+ /* Release leases on shutdown for pool */
+ if (1 == job->rel) {
+ itadmin_dhcp_indent(fipo, (indent+1));
+ fputs(itadmin_dhcp_c8_kw[36], fipo);
+ itadmin_dhcp_indent(fipo, (indent+1));
+ fputs(itadmin_dhcp_c8_kw[37], fipo);
+ itadmin_dhcp_indent(fipo, (indent+1));
+ fputs(itadmin_dhcp_c8_kw[38], fipo);
+ itadmin_dhcp_indent(fipo, (indent+1));
+ fputs(itadmin_dhcp_c8_kw[39], fipo);
+ }
+ itadmin_dhcp_indent(fipo, indent);
+ fputs(itadmin_dhcp_c8_kw[14], fipo);
+ fputc('\n', fipo); $? "- itadmin_dhcp_write_pool"
+}
+
+
+
+/** Write one host in group.
+ @param job Job structure.
+ @param fipo Output file.
+ @param ho Host to write.
+ @param ind Indent level at beginning of line.
+*/
+static
+void
+itadmin_dhcp_write_one_host(
+ itadmin_job *job,
+ FILE *fipo,
+ itadmin_host *ho,
+ int ind
+)
+{
+ $? "+ itadmin_dhcp_write_one_host \"%!8s\"", TR_8STR(ho->sn)
+ if((ho->sn) && (ho->maca)) {
+ itadmin_dhcp_indent(fipo, ind);
+ fputs(itadmin_dhcp_c8_kw[28], fipo);
+ fputs(ho->sn, fipo);
+ fputc('\n', fipo);
+ itadmin_dhcp_indent(fipo, ind);
+ fputs(itadmin_dhcp_c8_kw[13], fipo);
+ fputc('\n', fipo);
+
+ itadmin_dhcp_indent(fipo, (ind + 1));
+ fputs(itadmin_dhcp_c8_kw[29], fipo);
+ fputs(ho->sn, fipo);
+ fputs(itadmin_dhcp_c8_kw[26], fipo);
+ fputc('\n', fipo);
+
+ itadmin_dhcp_indent(fipo, (ind + 1));
+ fputs(itadmin_dhcp_c8_kw[30], fipo);
+ fputs(ho->maca, fipo);
+ fputs(itadmin_dhcp_c8_kw[10], fipo);
+ fputc('\n', fipo);
+
+ if(ho->ipv4) {
+ itadmin_dhcp_indent(fipo, (ind + 1));
+ fputs(itadmin_dhcp_c8_kw[31], fipo);
+ itadmin_tool_write_ip(fipo, ho->ipv4);
+ fputs(itadmin_dhcp_c8_kw[10], fipo);
+ fputc('\n', fipo);
+ }
+
+ /* Added 2013-09-14: Must write host options too. */
+ if((ho->s_do) && (ho->i_do)) {
+ itadmin_dhcp_write_options(job, fipo, ho->i_do, 3, (ind+1));
+ }
+
+ itadmin_dhcp_indent(fipo, ind);
+ fputs(itadmin_dhcp_c8_kw[14], fipo);
+ fputc('\n', fipo);
+ } $? "- itadmin_dhcp_write_one_host"
+}
+
+
+
+/** Write hosts of one group for a network.
+
+*/
+static
+void
+itadmin_dhcp_write_group(
+ itadmin_job *job,
+ FILE *fipo,
+ itadmin_network *nw,
+ dk3_sto_it_t *i_ho,
+ itadmin_dhcp_group *gr,
+ int ind
+
+)
+{
+ itadmin_host *ho;
+ itadmin_dhcp_class *dc;
+ int is_first;
+ int is_in_group;
+ $? "+ itadmin_dhcp_write_group"
+ if(gr) { $? ". group \"%!8s\"", TR_8STR(gr->sn)
+ } else { $? ". no group"
+ }
+ is_first = 1;
+ if(i_ho) {
+ dk3sto_it_reset(i_ho);
+ while(NULL != (ho = (itadmin_host *)dk3sto_it_next(i_ho))) {
+ if((ho->sn) && (ho->maca)) {
+ if(is_first) {
+ itadmin_dhcp_indent(fipo, ind);
+ fputs(itadmin_dhcp_c8_kw[27], fipo);
+ fputc('\n', fipo);
+ itadmin_dhcp_indent(fipo, ind);
+ fputs(itadmin_dhcp_c8_kw[13], fipo);
+ fputc('\n', fipo);
+ if(gr) {
+ if(gr->i_do) {
+ itadmin_dhcp_write_options(job, fipo, gr->i_do, 3, (ind+1));
+ fputc('\n', fipo);
+ }
+ }
+ } is_first = 0;
+ itadmin_dhcp_write_one_host(job, fipo, ho, (ind + 1));
+ }
+ }
+ }
+ if(nw) {
+ if(nw->i_dc) {
+ dk3sto_it_reset(nw->i_dc);
+ while(NULL != (dc = (itadmin_dhcp_class *)dk3sto_it_next(nw->i_dc))) {
+ if(dc->i_ho) {
+ dk3sto_it_reset(dc->i_ho);
+ while(NULL != (ho = (itadmin_host *)dk3sto_it_next(dc->i_ho))) {
+ is_in_group = 0;
+ if(ho->dg) {
+ if(gr) {
+ if(itadmin_comp_dhcp_group((void *)(ho->dg),(void *)gr,0) == 0)
+ {
+ is_in_group = 1;
+ }
+ }
+ } else {
+ if(!(gr)) {
+ is_in_group = 1;
+ }
+ }
+ if(is_in_group) {
+ if(is_first) {
+ itadmin_dhcp_indent(fipo, ind);
+ fputs(itadmin_dhcp_c8_kw[27], fipo);
+ fputc('\n', fipo);
+ itadmin_dhcp_indent(fipo, ind);
+ fputs(itadmin_dhcp_c8_kw[13], fipo);
+ fputc('\n', fipo);
+ if(gr) {
+ if(gr->i_do) {
+ itadmin_dhcp_write_options(job,fipo,gr->i_do,3,(ind + 1));
+ fputc('\n', fipo);
+ }
+ }
+ } is_first = 0;
+ itadmin_dhcp_write_one_host(job, fipo, ho, (ind + 1));
+ }
+ }
+ }
+ }
+ }
+ }
+ if(!(is_first)) {
+ itadmin_dhcp_indent(fipo, ind);
+ fputs(itadmin_dhcp_c8_kw[14], fipo);
+ fputc('\n', fipo);
+ }
+ $? "- itadmin_dhcp_write_group"
+}
+
+
+
+/** Write one network to output file.
+ @param job Job structure.
+ @param fipo Output file.
+ @param nw Network to write.
+ @param indent Indent at start of file.
+*/
+static
+void
+itadmin_dhcp_write_one_network(
+ itadmin_job *job,
+ FILE *fipo,
+ itadmin_network *nw,
+ int indent
+)
+{
+ itadmin_dhcp_pool *dp;
+ itadmin_dhcp_ginw *ginw;
+ $? "+ itadmin_dhcp_write_one_network"
+ itadmin_dhcp_indent(fipo, indent);
+ fputs(itadmin_dhcp_c8_kw[15], fipo);
+ itadmin_tool_write_ip(fipo, nw->ip4);
+ fputs(itadmin_dhcp_c8_kw[16], fipo);
+ itadmin_tool_write_ip(fipo, nw->ma4);
+ fputc('\n', fipo);
+ itadmin_dhcp_indent(fipo, indent);
+ fputs(itadmin_dhcp_c8_kw[13], fipo);
+ fputc('\n', fipo);
+ itadmin_dhcp_indent(fipo, (indent + 1));
+ fputs(itadmin_dhcp_c8_kw[17], fipo);
+ itadmin_tool_write_ip(fipo, nw->gw4);
+ fputc(';', fipo);
+ fputc('\n', fipo);
+ itadmin_dhcp_indent(fipo, (indent + 1));
+ fputs(itadmin_dhcp_c8_kw[18], fipo);
+ itadmin_tool_write_ip(fipo, nw->ma4);
+ fputc(';', fipo);
+ fputc('\n', fipo);
+ itadmin_dhcp_indent(fipo, (indent + 1));
+ fputs(itadmin_dhcp_c8_kw[19], fipo);
+ itadmin_tool_write_ip(fipo, nw->bc4);
+ fputc(';', fipo);
+ fputc('\n', fipo);
+ /* DHCP options */
+ if(nw->i_do) {
+ itadmin_dhcp_write_options(job, fipo, nw->i_do, 2, (indent+1));
+ fputc('\n', fipo);
+ }
+ /* Pools */
+ if(nw->i_p) {
+ dk3sto_it_reset(nw->i_p);
+ while(NULL != (dp = (itadmin_dhcp_pool *)dk3sto_it_next(nw->i_p))) {
+ itadmin_dhcp_write_pool(job, fipo, dp, (indent + 1));
+ }
+ }
+ /* Groups, direct for network and in DHCP classes */
+ if(nw->i_dg) {
+ dk3sto_it_reset(nw->i_dg);
+ while(NULL != (ginw = (itadmin_dhcp_ginw *)dk3sto_it_next(nw->i_dg))) {
+ itadmin_dhcp_write_group(job,fipo,nw,ginw->i_h,ginw->gr,(indent + 1));
+ }
+ }
+ /* Hosts without groups, direct for network and in DHCP classes */
+ itadmin_dhcp_write_group(job, fipo, nw, nw->i_hoi, NULL, (indent + 1));
+ itadmin_dhcp_indent(fipo, indent);
+ fputs(itadmin_dhcp_c8_kw[14], fipo);
+ fputc('\n', fipo); $? "- itadmin_dhcp_write_one_network"
+}
+
+
+
+/** Write DHCP networks.
+ @param job Job structure.
+ @param fipo Output file.
+ @param i_nw Iterator for networks storage.
+*/
+static
+void
+itadmin_dhcp_write_networks(
+ itadmin_job *job,
+ FILE *fipo,
+ dk3_sto_it_t *i_nw
+)
+{
+ itadmin_network *nw;
+ $? "+ itadmin_dhcp_write_networks"
+ dk3sto_it_reset(i_nw);
+ while(NULL != (nw = (itadmin_network *)dk3sto_it_next(i_nw))) {
+ itadmin_dhcp_write_one_network(job, fipo, nw, 1);
+ } $? "- itadmin_dhcp_write_networks"
+}
+
+
+
+/** Write data for one VLAN to output.
+ @param job Job structure.
+ @param fipo Output file.
+ @param i_nw Networks iterator.
+ @param i_do DHCP options storage iterator.
+*/
+static
+void
+itadmin_dhcp_write_vlan(
+ itadmin_job *job,
+ FILE *fipo,
+ dk3_sto_it_t *i_nw,
+ dk3_sto_it_t *i_do
+)
+{
+ itadmin_network *nw;
+ int num_networks;
+ $? "+ itadmin_dhcp_write_vlan"
+ num_networks = 0;
+ if(i_nw) {
+ dk3sto_it_reset(i_nw);
+ while(NULL != dk3sto_it_next(i_nw)) { num_networks++; }
+ if(num_networks > 0) {
+ dk3sto_it_reset(i_nw);
+ if((num_networks > 1) || (i_do)) {
+ fputs(itadmin_dhcp_c8_kw[12], fipo);
+ fputc('\n', fipo);
+ fputs(itadmin_dhcp_c8_kw[13], fipo);
+ fputc('\n', fipo);
+ if(i_do) {
+ itadmin_dhcp_write_options(job, fipo, i_do, 1, 1);
+ }
+ itadmin_dhcp_write_networks(job, fipo, i_nw);
+ fputs(itadmin_dhcp_c8_kw[14], fipo);
+ fputc('\n', fipo);
+ } else {
+ nw = (itadmin_network *)dk3sto_it_next(i_nw);
+ if(nw) {
+ itadmin_dhcp_write_one_network(job, fipo, nw, 0);
+ }
+ }
+ }
+ } $? "- itadmin_dhcp_write_vlan"
+}
+
+
+
+static
+void
+itadmin_dhcp_declare_msft_options(itadmin_job *job, FILE *fipo)
+{
+ if (0 < job->rel) {
+ fputs(itadmin_dhcp_c8_kw[34], fipo);
+ fputs(itadmin_dhcp_c8_kw[35], fipo);
+ }
+ if (2 == job->rel) {
+ fputs(itadmin_dhcp_c8_kw[36], fipo);
+ fputs(itadmin_dhcp_c8_kw[37], fipo);
+ fputs(itadmin_dhcp_c8_kw[38], fipo);
+ fputs(itadmin_dhcp_c8_kw[39], fipo);
+ fputc('\n', fipo);
+ }
+}
+
+
+
+/** Write output file for a VLAN or all networks.
+ @param job Job structure.
+ @param vlanname Name of VLAN (NULL if not specified).
+ @param i_nw Iterator for all networks.
+ @param i_do Iterator for VLAN DHCP options (may be NULL).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_dhcpd_output(
+ itadmin_job *job,
+ dkChar const *vlanname,
+ dk3_sto_it_t *i_nw,
+ dk3_sto_it_t *i_do
+)
+{
+ FILE *fipo;
+ int back = 0;
+ $? "+ itadmin_dhcpd_output"
+ if(itadmin_dhcp_link_classes(job, i_nw)) { $? ". link classes ok"
+ fipo = dk3sf_c8_fopen_app(
+ itadmin_dhcp_c8_kw[0], itadmin_dhcp_c8_kw[5], job->app
+ );
+ if(fipo) { $? ". fopen"
+ itadmin_dhcp_write_options(job, fipo, job->i_do, 0, 0);
+ fputc('\n', fipo);
+ itadmin_dhcp_declare_msft_options(job, fipo);
+ fputs(itadmin_dhcp_c8_kw[32], fipo);
+ itadmin_dhcp_write_classes(job, fipo);
+ fputc('\n', fipo);
+ fputs(itadmin_dhcp_c8_kw[33], fipo);
+ itadmin_dhcp_write_vlan(job, fipo, i_nw, i_do);
+ back = 1;
+#if DK3_CHAR_SIZE == 1
+ if(!dk3sf_fclose_fn_app(fipo, itadmin_dhcp_c8_kw[0], job->app)) {
+ back = 0;
+ }
+#else
+ if(!dk3sf_fclose_fn_app(fipo, NULL, job->app)) {
+ back = 0;
+ }
+#endif
+ } else { $? "! fopen"
+ /* ERROR: Failed to open file. */
+ }
+ } else { $? "! error while linking classes"
+ } $? "- itadmin_dhcpd_output %d", back
+ return back;
+}
+
+
+
+int
+itadmin_dhcpd_conf_output(itadmin_job *job)
+{
+ char vlname[ITADMIN_CONFIG_LINE_SIZE];
+ itadmin_vlan *dhcpvl;
+ int back = 0;
+ int res;
+ $? "+ itadmin_dhcpd_conf_output"
+ if(job->vlan) {
+ res = dk3str_str_to_c8u_app(
+ vlname, sizeof(vlname), job->vlan,
+ dk3app_get_encoding(job->app), job->app
+ );
+ if(res) {
+ dhcpvl =
+ (itadmin_vlan *)dk3sto_it_find_like(job->i_vl, (void *)vlname, 1);
+ if(dhcpvl) {
+ back = itadmin_dhcpd_output(job, dhcpvl->s, dhcpvl->i_nw, dhcpvl->i_do);
+ } else {
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 139, 140, job->vlan);
+ }
+ } else {
+ /* ERROR: Failed to convert VLAN name! */
+ }
+ } else {
+ back = itadmin_dhcpd_output(job, NULL, job->i_nw, NULL);
+ } $? "- itadmin_dhcpd_conf_output %d", back
+ return back;
+}
+
diff --git a/support/dktools/itadmin.c b/support/dktools/itadmin.c
new file mode 100644
index 0000000000..8386c305fb
--- /dev/null
+++ b/support/dktools/itadmin.c
@@ -0,0 +1,2537 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: itadmin.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file itadmin.c The itadmin module.
+*/
+
+
+#line 1755 "itadmin.ctr"
+
+
+#include "dk3all.h"
+#include "itadmin.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4vers.h"
+
+
+
+
+#line 1766 "itadmin.ctr"
+
+
+
+/** Keywords used by the program, not localized.
+*/
+static dkChar const * const itadmin_kw_noloc[] = {
+/* 0 */
+dkT("dktools"),
+
+/* 1 */
+dkT("itadmin.str"),
+
+/* 2 */
+dkT("itadmin "),
+
+/* 3 */
+dkT("itadmin.txt"),
+
+/* 4 */
+dkT("itadmin.conf"),
+
+NULL
+
+
+#line 1794 "itadmin.ctr"
+};
+
+
+
+/** Localized message texts.
+*/
+static dkChar const * const itadmin_kw[] = {
+/* 0 */
+dkT("Network documentation"),
+
+/* 1 */
+dkT("Network documentation"),
+
+/* 2 */
+dkT(""),
+
+/* 3 */
+dkT("Hosts"),
+
+/* 4 */
+dkT("Other hosts"),
+
+/* 5 */
+dkT("Overview"),
+
+/* 6 */
+dkT("Purpose:"),
+
+/* 7 */
+dkT("Inventory ID:"),
+
+/* 8 */
+dkT("Serial no:"),
+
+/* 9 */
+dkT("not specified"),
+
+/* 10 */
+dkT("Main user:"),
+
+/* 11 */
+dkT("Place:"),
+
+/* 12 */
+dkT("Network"),
+
+/* 13 */
+dkT("IP address:"),
+
+/* 14 */
+dkT("DNS domain:"),
+
+/* 15 */
+dkT("MAC address:"),
+
+/* 16 */
+dkT("Ethernet socket:"),
+
+/* 17 */
+dkT("DHCP class:"),
+
+/* 18 */
+dkT("DHCP group:"),
+
+/* 19 */
+dkT("Netgroups"),
+
+/* 20 */
+dkT("IP address from DHCP pool, dynamically assigned to DHCP clients"),
+
+/* 21 */
+dkT("BYOD DHCP"),
+
+/* 22 */
+dkT("Bring your own device, use DHCP"),
+
+/* 23 */
+dkT("This is a ``bring your own device'' system, not owned by our organizational"),
+
+/* 24 */
+dkT("unit."),
+
+/* 25 */
+dkT("This host is not owned by our organizational unit, it is a computer outside."),
+
+/* 26 */
+dkT("It is listed in configuration files and documentation because there is a"),
+
+/* 27 */
+dkT("need for communication between our computers and this system."),
+
+/* 28 */
+dkT("IP address dynamically assigned to computers."),
+
+/* 29 */
+dkT("Parent groups"),
+
+/* 30 */
+dkT("Subgroups"),
+
+/* 31 */
+dkT("Additional network interface."),
+
+/* 32 */
+dkT("Member hosts"),
+
+/* 33 */
+dkT("DHCP pools"),
+
+/* 34 */
+dkT("Start address:"),
+
+/* 35 */
+dkT("End address:"),
+
+/* 36 */
+dkT("Allow unknown clients:"),
+
+/* 37 */
+dkT("Deny unknown clients:"),
+
+/* 38 */
+dkT("Allow class:"),
+
+/* 39 */
+dkT("yes"),
+
+/* 40 */
+dkT("no"),
+
+/* 41 */
+dkT("DHCP classes"),
+
+/* 42 */
+dkT("Ethernet connectors"),
+
+/* 43 */
+dkT("Connector"),
+
+/* 44 */
+dkT("Room"),
+
+/* 45 */
+dkT("VLAN"),
+
+/* 46 */
+dkT("Speed"),
+
+/* 47 */
+dkT("Hub port"),
+
+/* 48 */
+dkT("Available licenses"),
+
+/* 49 */
+dkT("The licenses listed here were purchased by the organizational unit"),
+
+/* 50 */
+dkT("but not (yet) assigned to a user or computer."),
+
+/* 51 */
+dkT("License report"),
+
+/* 52 */
+dkT("licenses"),
+
+/* 53 */
+dkT("Single computer license"),
+
+/* 54 */
+dkT("Purchase process ID:"),
+
+/* 55 */
+dkT("Delivery date:"),
+
+/* 56 */
+dkT("Delivery note ID:"),
+
+/* 57 */
+dkT("Invoice date:"),
+
+/* 58 */
+dkT("Invoice ID:"),
+
+/* 59 */
+dkT("Complete license list"),
+
+/* 60 */
+dkT("Host unknown"),
+
+/* 61 */
+dkT("Assignment to host not specified"),
+
+/* 62 */
+dkT("Other people's hosts"),
+
+/* 63 */
+dkT("Licenses used on other people's hosts"),
+
+/* 64 */
+dkT("The licenses listed in this section were assigned to the user."),
+
+/* 65 */
+dkT("There is no information available (yet) on which computers the licenses"),
+
+/* 66 */
+dkT("are used."),
+
+/* 67 */
+dkT("The licenses listed in this section were assigned to the user."),
+
+/* 68 */
+dkT("At this time they are used on computers other people are"),
+
+/* 69 */
+dkT("responsible for."),
+
+/* 70 */
+dkT("Note:"),
+
+/* 71 */
+dkT("These licenses are listed twice in the license report:"),
+
+/* 72 */
+dkT("Once in the section for the host and once again here."),
+
+/* 73 */
+dkT("This special situation is indicated in the host licenses section by"),
+
+/* 74 */
+dkT("the license owner name written in an"),
+
+/* 75 */
+dkT("italic font."),
+
+/* 76 */
+dkT("-"),
+
+/* 77 */
+dkT("Expanding netgroup dependencies."),
+
+/* 78 */
+dkT("Writing \"hosts\" file."),
+
+/* 79 */
+dkT("Writing \"hosts.ldif\" file."),
+
+/* 80 */
+dkT("Writing \"ethers\" files."),
+
+/* 81 */
+dkT("Writing \"ethers.ldif\" file."),
+
+/* 82 */
+dkT("Writing \"netgroup.ldif\" file."),
+
+/* 83 */
+dkT("Writing \"dhcpd.conf\" file."),
+
+/* 84 */
+dkT("Writing \"netdocu.tex\" file."),
+
+/* 85 */
+dkT("Writing \"licenses.tex\" file."),
+
+/* 86 */
+dkT("Finished writing output files."),
+
+/* 87 */
+dkT("Reading users table."),
+
+/* 88 */
+dkT("Reading buildings table."),
+
+/* 89 */
+dkT("Reading network speed types table."),
+
+/* 90 */
+dkT("Reading VLANs table."),
+
+/* 91 */
+dkT("Reading ethernet connectors table."),
+
+/* 92 */
+dkT("Reading netgroups table."),
+
+/* 93 */
+dkT("Reading netgroup dependencies table."),
+
+/* 94 */
+dkT("Reading networks table."),
+
+/* 95 */
+dkT("Reading DHCP classes table."),
+
+/* 96 */
+dkT("Reading DHCP groups table."),
+
+/* 97 */
+dkT("Reading DHCP pools table."),
+
+/* 98 */
+dkT("Reading hosts table."),
+
+/* 99 */
+dkT("Reading host name aliases table."),
+
+/* 100 */
+dkT("Reading DHCP options table."),
+
+/* 101 */
+dkT("Reading software manufacturers table."),
+
+/* 102 */
+dkT("Reading software products table."),
+
+/* 103 */
+dkT("Reading license types table."),
+
+/* 104 */
+dkT("Reading licenses table."),
+
+/* 105 */
+dkT("Finished reading input from database."),
+
+/* 106 */
+dkT("Not a boolean value: \""),
+
+/* 107 */
+dkT("\"!"),
+
+/* 108 */
+dkT("Configuration value text \""),
+
+/* 109 */
+dkT("\" too long!"),
+
+/* 110 */
+dkT("No such database type: \""),
+
+/* 111 */
+dkT("\"!"),
+
+/* 112 */
+dkT("A value text is required!"),
+
+/* 113 */
+dkT("Unknown configuration option \""),
+
+/* 114 */
+dkT("\"!"),
+
+/* 115 */
+dkT("Syntax error - \"=\" and value required!"),
+
+/* 116 */
+dkT("Input line too long!"),
+
+/* 117 */
+dkT("Missing end of section name!"),
+
+/* 118 */
+dkT("File name \""),
+
+/* 119 */
+dkT("\"\ncontains wildcards, this is not allowed!"),
+
+/* 120 */
+dkT("File name \""),
+
+/* 121 */
+dkT("\"\nis not an absolute path name!"),
+
+/* 122 */
+dkT("Missing database host name!"),
+
+/* 123 */
+dkT("Missing database name!"),
+
+/* 124 */
+dkT("Missing DHCP VLAN name!"),
+
+/* 125 */
+dkT("Missing organization name!"),
+
+/* 126 */
+dkT("Missing organizational unit name!"),
+
+/* 127 */
+dkT("Missing administrator name!"),
+
+/* 128 */
+dkT("Missing database credentials file name!"),
+
+/* 129 */
+dkT("Missing database user name!"),
+
+/* 130 */
+dkT("Missing database user password!"),
+
+/* 131 */
+dkT("No configuration file(s) \"itadmin.conf\" found!#"),
+
+/* 132 */
+dkT("Configuration problems,\nplease check the itadmin.conf configuration files!"),
+
+/* 133 */
+dkT("Unsupported database type!"),
+
+/* 134 */
+dkT("DHCP pool \""),
+
+/* 135 */
+dkT("\": Inconsistent setup!\nUnknown clients can be allowed or denied to use a pool, not both!"),
+
+/* 136 */
+dkT("DHCP class \""),
+
+/* 137 */
+dkT("\" assigned to pools in different networks!"),
+
+/* 138 */
+dkT("\": Missing allowed DHCP class name!"),
+
+/* 139 */
+dkT("No such VLAN: \""),
+
+/* 140 */
+dkT("\"!"),
+
+/* 141 */
+dkT("Failed to obtain results list for database query!"),
+
+/* 142 */
+dkT("Failed to query database!"),
+
+/* 143 */
+dkT("Table \"licenses\", record "),
+
+/* 144 */
+dkT(" Primary key is not numeric!"),
+
+/* 145 */
+dkT(" Missing primary key!"),
+
+/* 146 */
+dkT("License type \""),
+
+/* 147 */
+dkT("\": Not a number \""),
+
+/* 148 */
+dkT("\"!"),
+
+/* 149 */
+dkT("Table \"swmanufacturers\" record "),
+
+/* 150 */
+dkT(" Missing primary key!"),
+
+/* 151 */
+dkT("Table \"dhcpoptions\" record "),
+
+/* 152 */
+dkT(" Primary key is not numeric!"),
+
+/* 153 */
+dkT(" Missing primary key!"),
+
+/* 154 */
+dkT("Failed to set database encoding!"),
+
+/* 155 */
+dkT("Failed to connect to database \""),
+
+/* 156 */
+dkT("\" at host \""),
+
+/* 157 */
+dkT("\"!"),
+
+/* 158 */
+dkT("Illegal database name: \""),
+
+/* 159 */
+dkT("\"!"),
+
+/* 160 */
+dkT("Failed to convert database user passwort to UTF-8!"),
+
+/* 161 */
+dkT("Failed to convert database user name \""),
+
+/* 162 */
+dkT("\" to UTF-8!"),
+
+/* 163 */
+dkT("Failed to convert database host name \""),
+
+/* 164 */
+dkT("\" to UTF-8!"),
+
+/* 165 */
+dkT("Failed to initialize MySQL client object!"),
+
+/* 166 */
+dkT("Failed to initialize MySQL client library!"),
+
+/* 167 */
+dkT("MySQL database support not available!"),
+
+/* 168 */
+dkT("User name \""),
+
+/* 169 */
+dkT("\": Duplicated entry!"),
+
+/* 170 */
+dkT("Building \""),
+
+/* 171 */
+dkT("\": Duplicated entry!"),
+
+/* 172 */
+dkT("Ethernet speed setting \""),
+
+/* 173 */
+dkT("\": Duplicated entry!"),
+
+/* 174 */
+dkT("VLAN \""),
+
+/* 175 */
+dkT("\": Duplicated entry!"),
+
+/* 176 */
+dkT("Computer \""),
+
+/* 177 */
+dkT("\": Duplicated entry!"),
+
+/* 178 */
+dkT("Software manufacturer \""),
+
+/* 179 */
+dkT("\": Duplicated entry!"),
+
+/* 180 */
+dkT("Netgroup \""),
+
+/* 181 */
+dkT("\": Duplicated entry!"),
+
+/* 182 */
+dkT("Netgroup \""),
+
+/* 183 */
+dkT("\" not defined!"),
+
+/* 184 */
+dkT("Ethernet connector \""),
+
+/* 185 */
+dkT("\": Duplicated entry!"),
+
+/* 186 */
+dkT("Ethernet speed setting \""),
+
+/* 187 */
+dkT("\" not defined!"),
+
+/* 188 */
+dkT("VLAN \""),
+
+/* 189 */
+dkT("\" not defined!"),
+
+/* 190 */
+dkT("Building \""),
+
+/* 191 */
+dkT("\" not defined!"),
+
+/* 192 */
+dkT("Failed to convert net mask \""),
+
+/* 193 */
+dkT("\"!"),
+
+/* 194 */
+dkT("Using default net mask 255.255.255.0!"),
+
+/* 195 */
+dkT("Failed to convert default gateway \""),
+
+/* 196 */
+dkT("\"!"),
+
+/* 197 */
+dkT("Using default gateway "),
+
+/* 198 */
+dkT("."),
+
+/* 199 */
+dkT("Failed to convert broadcast address \""),
+
+/* 200 */
+dkT("\"!"),
+
+/* 201 */
+dkT("Network \""),
+
+/* 202 */
+dkT("\": Duplicated entry!"),
+
+/* 203 */
+dkT("Attempt to define IP network without specifying an IP address!"),
+
+/* 204 */
+dkT("DHCP class \""),
+
+/* 205 */
+dkT("\": Duplicated entry!"),
+
+/* 206 */
+dkT("DHCP group \""),
+
+/* 207 */
+dkT("\": Duplicated entry!"),
+
+/* 208 */
+dkT("Invalid network address \""),
+
+/* 209 */
+dkT("\"!"),
+
+/* 210 */
+dkT("DHCP class \""),
+
+/* 211 */
+dkT("\" not defined!"),
+
+/* 212 */
+dkT("Network \""),
+
+/* 213 */
+dkT("\" not defined!"),
+
+/* 214 */
+dkT("DHCP pool \""),
+
+/* 215 */
+dkT("\": Invalid end address!"),
+
+/* 216 */
+dkT("DHCP pool \""),
+
+/* 217 */
+dkT("\": Missing end address!"),
+
+/* 218 */
+dkT("DHCP pool \""),
+
+/* 219 */
+dkT("\": Invalid start address!"),
+
+/* 220 */
+dkT("DHCP pool definition attempted with empty start address!"),
+
+/* 221 */
+dkT("Computer \""),
+
+/* 222 */
+dkT("\": Illegal MAC address!"),
+
+/* 223 */
+dkT("Computer \""),
+
+/* 224 */
+dkT("\": MAC address too long!"),
+
+/* 225 */
+dkT("Computer \""),
+
+/* 226 */
+dkT("\": User \""),
+
+/* 227 */
+dkT("\" not defined!"),
+
+/* 228 */
+dkT("Computer \""),
+
+/* 229 */
+dkT("\": Netgroup \""),
+
+/* 230 */
+dkT("\" not defined!"),
+
+/* 231 */
+dkT("Computer \""),
+
+/* 232 */
+dkT("\": DHCP class \""),
+
+/* 233 */
+dkT("\" not defined!"),
+
+/* 234 */
+dkT("Computer \""),
+
+/* 235 */
+dkT("\": DHCP group \""),
+
+/* 236 */
+dkT("\" not defined!"),
+
+/* 237 */
+dkT("Computer \""),
+
+/* 238 */
+dkT("\": Ethernet connector \""),
+
+/* 239 */
+dkT("\" not defined!"),
+
+/* 240 */
+dkT("Computer \""),
+
+/* 241 */
+dkT("\": Building \""),
+
+/* 242 */
+dkT("\" not defined!"),
+
+/* 243 */
+dkT("Computer \""),
+
+/* 244 */
+dkT("\": Both DHCP class and IP address specified!"),
+
+/* 245 */
+dkT("Computer \""),
+
+/* 246 */
+dkT("\": DHCP class specified, but MAC address is missing!"),
+
+/* 247 */
+dkT("Computer \""),
+
+/* 248 */
+dkT("\": Netgroup specified, but IP address is missing!"),
+
+/* 249 */
+dkT("Computer \""),
+
+/* 250 */
+dkT("\": Netgroup specified, but DNS domain is missing!"),
+
+/* 251 */
+dkT("Computer \""),
+
+/* 252 */
+dkT("\": FQDN first flag set, but DNS domain is missing!"),
+
+/* 253 */
+dkT("Computer \""),
+
+/* 254 */
+dkT("\": Over expiration date, should be removed!"),
+
+/* 255 */
+dkT("Attempt to define a computer without a host name!"),
+
+/* 256 */
+dkT("Alias \""),
+
+/* 257 */
+dkT("\": Computer \""),
+
+/* 258 */
+dkT("\" not defined!"),
+
+/* 259 */
+dkT("DHCP option "),
+
+/* 260 */
+dkT(": VLAN \""),
+
+/* 261 */
+dkT("\" not defined!"),
+
+/* 262 */
+dkT("DHCP option "),
+
+/* 263 */
+dkT(": Network \""),
+
+/* 264 */
+dkT("\" not defined!"),
+
+/* 265 */
+dkT("DHCP option "),
+
+/* 266 */
+dkT(": DHCP group \""),
+
+/* 267 */
+dkT("\" not defined!"),
+
+/* 268 */
+dkT("DHCP option "),
+
+/* 269 */
+dkT(": DHCP pool \""),
+
+/* 270 */
+dkT("\" not defined!"),
+
+/* 271 */
+dkT("DHCP option "),
+
+/* 272 */
+dkT(": Computer \""),
+
+/* 273 */
+dkT("\" not defined!"),
+
+/* 274 */
+dkT("DHCP option "),
+
+/* 275 */
+dkT(": Unknown scope type name \""),
+
+/* 276 */
+dkT("\"!"),
+
+/* 277 */
+dkT("Software product \""),
+
+/* 278 */
+dkT("\": Duplicated entry!"),
+
+/* 279 */
+dkT("Software product \""),
+
+/* 280 */
+dkT("\": Software manufacturer \""),
+
+/* 281 */
+dkT("\" not defined!"),
+
+/* 282 */
+dkT("License type \""),
+
+/* 283 */
+dkT("\": Duplicated entry!"),
+
+/* 284 */
+dkT("License "),
+
+/* 285 */
+dkT(": Duplicated entry!"),
+
+/* 286 */
+dkT("License "),
+
+/* 287 */
+dkT(": User \""),
+
+/* 288 */
+dkT("\" not defined!"),
+
+/* 289 */
+dkT("License "),
+
+/* 290 */
+dkT(": Computer \""),
+
+/* 291 */
+dkT("\" not defined!"),
+
+/* 292 */
+dkT("License "),
+
+/* 293 */
+dkT(": License type \""),
+
+/* 294 */
+dkT("\" not defined!"),
+
+/* 295 */
+dkT("License "),
+
+/* 296 */
+dkT(" assigned to computer \""),
+
+/* 297 */
+dkT("\" but no user specified!"),
+
+/* 298 */
+dkT("License "),
+
+/* 299 */
+dkT(": No software product specified!"),
+
+/* 300 */
+dkT("Illegal date specification \""),
+
+/* 301 */
+dkT("\"!"),
+
+/* 302 */
+dkT("Users from Europe - especially from Germany - should consider using koma-script."),
+
+/* 303 */
+dkT("Illegal software manufacturer (short name): \""),
+
+/* 304 */
+dkT("\"!"),
+
+/* 305 */
+dkT("Illegal software (short name): \""),
+
+/* 306 */
+dkT("\"!"),
+
+/* 307 */
+dkT("Illegal license type (short name): \""),
+
+/* 308 */
+dkT("\"!"),
+
+/* 309 */
+dkT("Failed to reset sensitive memory range!"),
+
+NULL
+
+
+#line 2764 "itadmin.ctr"
+};
+
+
+
+/** License text written for --license option.
+*/
+static dkChar const * const itadmin_license_overview[] = {
+dkT(""),
+dkT("Overview"),
+dkT("========"),
+dkT("This software uses code from the following projects, either directly or"),
+dkT("by linking a library:"),
+dkT(""),
+dkT("dktools\t\tDK tools and libraries"),
+dkT("\t\tSee http://dktools.sourceforge.net for information."),
+dkT(""),
+dkT("MySQL\t\tMySQL client library."),
+dkT("\t\tSee http://www.mysql.com for information."),
+dkT(""),
+NULL
+
+
+#line 2785 "itadmin.ctr"
+};
+
+
+
+/** License for the dktools project.
+*/
+static dkChar const * const itadmin_license_dktools[] = {
+dkT(""),
+dkT("License conditions for DK tools and libraries"),
+dkT("============================================="),
+dkT("Copyright (c) 2012-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above copyright notice,"),
+dkT(" this list of conditions and the following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("* Neither the name of the copyright holder(s) nor the names of"),
+dkT(" contributors may be used to endorse or promote products derived from "),
+dkT(" this software without specific prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS"),
+dkT("\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT"),
+dkT("LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR"),
+dkT("A PARTICULAR PURPOSE ARE DISCLAIMED."),
+dkT(""),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS"),
+dkT("OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)"),
+dkT("HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,"),
+dkT("STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING"),
+dkT("IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE"),
+dkT("POSSIBILITY OF SUCH DAMAGE."),
+dkT(""),
+NULL
+
+
+#line 2826 "itadmin.ctr"
+};
+
+
+
+/** License for the MySQL client library (GPL + FLOSS exception).
+*/
+static dkChar const * const itadmin_license_mysql[] = {
+dkT("License conditions for the MySQL client library"),
+dkT("==============================================="),
+dkT(""),
+dkT("GNU General Public License"),
+dkT("--------------------------"),
+dkT(""),
+dkT("\t\t GNU GENERAL PUBLIC LICENSE"),
+dkT("\t\t Version 2, June 1991"),
+dkT(""),
+dkT(" Copyright (C) 1989, 1991 Free Software Foundation, Inc.,"),
+dkT(" 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA"),
+dkT(" Everyone is permitted to copy and distribute verbatim copies"),
+dkT(" of this license document, but changing it is not allowed."),
+dkT(""),
+dkT("\t\t\t Preamble"),
+dkT(""),
+dkT(" The licenses for most software are designed to take away your"),
+dkT("freedom to share and change it. By contrast, the GNU General Public"),
+dkT("License is intended to guarantee your freedom to share and change free"),
+dkT("software--to make sure the software is free for all its users. This"),
+dkT("General Public License applies to most of the Free Software"),
+dkT("Foundation's software and to any other program whose authors commit to"),
+dkT("using it. (Some other Free Software Foundation software is covered by"),
+dkT("the GNU Lesser General Public License instead.) You can apply it to"),
+dkT("your programs, too."),
+dkT(""),
+dkT(" When we speak of free software, we are referring to freedom, not"),
+dkT("price. Our General Public Licenses are designed to make sure that you"),
+dkT("have the freedom to distribute copies of free software (and charge for"),
+dkT("this service if you wish), that you receive source code or can get it"),
+dkT("if you want it, that you can change the software or use pieces of it"),
+dkT("in new free programs; and that you know you can do these things."),
+dkT(""),
+dkT(" To protect your rights, we need to make restrictions that forbid"),
+dkT("anyone to deny you these rights or to ask you to surrender the rights."),
+dkT("These restrictions translate to certain responsibilities for you if you"),
+dkT("distribute copies of the software, or if you modify it."),
+dkT(""),
+dkT(" For example, if you distribute copies of such a program, whether"),
+dkT("gratis or for a fee, you must give the recipients all the rights that"),
+dkT("you have. You must make sure that they, too, receive or can get the"),
+dkT("source code. And you must show them these terms so they know their"),
+dkT("rights."),
+dkT(""),
+dkT(" We protect your rights with two steps: (1) copyright the software, and"),
+dkT("(2) offer you this license which gives you legal permission to copy,"),
+dkT("distribute and/or modify the software."),
+dkT(""),
+dkT(" Also, for each author's protection and ours, we want to make certain"),
+dkT("that everyone understands that there is no warranty for this free"),
+dkT("software. If the software is modified by someone else and passed on, we"),
+dkT("want its recipients to know that what they have is not the original, so"),
+dkT("that any problems introduced by others will not reflect on the original"),
+dkT("authors' reputations."),
+dkT(""),
+dkT(" Finally, any free program is threatened constantly by software"),
+dkT("patents. We wish to avoid the danger that redistributors of a free"),
+dkT("program will individually obtain patent licenses, in effect making the"),
+dkT("program proprietary. To prevent this, we have made it clear that any"),
+dkT("patent must be licensed for everyone's free use or not licensed at all."),
+dkT(""),
+dkT(" The precise terms and conditions for copying, distribution and"),
+dkT("modification follow."),
+dkT(""),
+dkT("\t\t GNU GENERAL PUBLIC LICENSE"),
+dkT(" TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION"),
+dkT(""),
+dkT(" 0. This License applies to any program or other work which contains"),
+dkT("a notice placed by the copyright holder saying it may be distributed"),
+dkT("under the terms of this General Public License. The \"Program\", below,"),
+dkT("refers to any such program or work, and a \"work based on the Program\""),
+dkT("means either the Program or any derivative work under copyright law:"),
+dkT("that is to say, a work containing the Program or a portion of it,"),
+dkT("either verbatim or with modifications and/or translated into another"),
+dkT("language. (Hereinafter, translation is included without limitation in"),
+dkT("the term \"modification\".) Each licensee is addressed as \"you\"."),
+dkT(""),
+dkT("Activities other than copying, distribution and modification are not"),
+dkT("covered by this License; they are outside its scope. The act of"),
+dkT("running the Program is not restricted, and the output from the Program"),
+dkT("is covered only if its contents constitute a work based on the"),
+dkT("Program (independent of having been made by running the Program)."),
+dkT("Whether that is true depends on what the Program does."),
+dkT(""),
+dkT(" 1. You may copy and distribute verbatim copies of the Program's"),
+dkT("source code as you receive it, in any medium, provided that you"),
+dkT("conspicuously and appropriately publish on each copy an appropriate"),
+dkT("copyright notice and disclaimer of warranty; keep intact all the"),
+dkT("notices that refer to this License and to the absence of any warranty;"),
+dkT("and give any other recipients of the Program a copy of this License"),
+dkT("along with the Program."),
+dkT(""),
+dkT("You may charge a fee for the physical act of transferring a copy, and"),
+dkT("you may at your option offer warranty protection in exchange for a fee."),
+dkT(""),
+dkT(" 2. You may modify your copy or copies of the Program or any portion"),
+dkT("of it, thus forming a work based on the Program, and copy and"),
+dkT("distribute such modifications or work under the terms of Section 1"),
+dkT("above, provided that you also meet all of these conditions:"),
+dkT(""),
+dkT(" a) You must cause the modified files to carry prominent notices"),
+dkT(" stating that you changed the files and the date of any change."),
+dkT(""),
+dkT(" b) You must cause any work that you distribute or publish, that in"),
+dkT(" whole or in part contains or is derived from the Program or any"),
+dkT(" part thereof, to be licensed as a whole at no charge to all third"),
+dkT(" parties under the terms of this License."),
+dkT(""),
+dkT(" c) If the modified program normally reads commands interactively"),
+dkT(" when run, you must cause it, when started running for such"),
+dkT(" interactive use in the most ordinary way, to print or display an"),
+dkT(" announcement including an appropriate copyright notice and a"),
+dkT(" notice that there is no warranty (or else, saying that you provide"),
+dkT(" a warranty) and that users may redistribute the program under"),
+dkT(" these conditions, and telling the user how to view a copy of this"),
+dkT(" License. (Exception: if the Program itself is interactive but"),
+dkT(" does not normally print such an announcement, your work based on"),
+dkT(" the Program is not required to print an announcement.)"),
+dkT(""),
+dkT("These requirements apply to the modified work as a whole. If"),
+dkT("identifiable sections of that work are not derived from the Program,"),
+dkT("and can be reasonably considered independent and separate works in"),
+dkT("themselves, then this License, and its terms, do not apply to those"),
+dkT("sections when you distribute them as separate works. But when you"),
+dkT("distribute the same sections as part of a whole which is a work based"),
+dkT("on the Program, the distribution of the whole must be on the terms of"),
+dkT("this License, whose permissions for other licensees extend to the"),
+dkT("entire whole, and thus to each and every part regardless of who wrote it."),
+dkT(""),
+dkT("Thus, it is not the intent of this section to claim rights or contest"),
+dkT("your rights to work written entirely by you; rather, the intent is to"),
+dkT("exercise the right to control the distribution of derivative or"),
+dkT("collective works based on the Program."),
+dkT(""),
+dkT("In addition, mere aggregation of another work not based on the Program"),
+dkT("with the Program (or with a work based on the Program) on a volume of"),
+dkT("a storage or distribution medium does not bring the other work under"),
+dkT("the scope of this License."),
+dkT(""),
+dkT(" 3. You may copy and distribute the Program (or a work based on it,"),
+dkT("under Section 2) in object code or executable form under the terms of"),
+dkT("Sections 1 and 2 above provided that you also do one of the following:"),
+dkT(""),
+dkT(" a) Accompany it with the complete corresponding machine-readable"),
+dkT(" source code, which must be distributed under the terms of Sections"),
+dkT(" 1 and 2 above on a medium customarily used for software interchange;"),
+dkT(" or,"),
+dkT(""),
+dkT(" b) Accompany it with a written offer, valid for at least three"),
+dkT(" years, to give any third party, for a charge no more than your"),
+dkT(" cost of physically performing source distribution, a complete"),
+dkT(" machine-readable copy of the corresponding source code, to be"),
+dkT(" distributed under the terms of Sections 1 and 2 above on a medium"),
+dkT(" customarily used for software interchange; or,"),
+dkT(""),
+dkT(" c) Accompany it with the information you received as to the offer"),
+dkT(" to distribute corresponding source code. (This alternative is"),
+dkT(" allowed only for noncommercial distribution and only if you"),
+dkT(" received the program in object code or executable form with such"),
+dkT(" an offer, in accord with Subsection b above.)"),
+dkT(""),
+dkT("The source code for a work means the preferred form of the work for"),
+dkT("making modifications to it. For an executable work, complete source"),
+dkT("code means all the source code for all modules it contains, plus any"),
+dkT("associated interface definition files, plus the scripts used to"),
+dkT("control compilation and installation of the executable. However, as a"),
+dkT("special exception, the source code distributed need not include"),
+dkT("anything that is normally distributed (in either source or binary"),
+dkT("form) with the major components (compiler, kernel, and so on) of the"),
+dkT("operating system on which the executable runs, unless that component"),
+dkT("itself accompanies the executable."),
+dkT(""),
+dkT("If distribution of executable or object code is made by offering"),
+dkT("access to copy from a designated place, then offering equivalent"),
+dkT("access to copy the source code from the same place counts as"),
+dkT("distribution of the source code, even though third parties are not"),
+dkT("compelled to copy the source along with the object code."),
+dkT(""),
+dkT(" 4. You may not copy, modify, sublicense, or distribute the Program"),
+dkT("except as expressly provided under this License. Any attempt"),
+dkT("otherwise to copy, modify, sublicense or distribute the Program is"),
+dkT("void, and will automatically terminate your rights under this License."),
+dkT("However, parties who have received copies, or rights, from you under"),
+dkT("this License will not have their licenses terminated so long as such"),
+dkT("parties remain in full compliance."),
+dkT(""),
+dkT(" 5. You are not required to accept this License, since you have not"),
+dkT("signed it. However, nothing else grants you permission to modify or"),
+dkT("distribute the Program or its derivative works. These actions are"),
+dkT("prohibited by law if you do not accept this License. Therefore, by"),
+dkT("modifying or distributing the Program (or any work based on the"),
+dkT("Program), you indicate your acceptance of this License to do so, and"),
+dkT("all its terms and conditions for copying, distributing or modifying"),
+dkT("the Program or works based on it."),
+dkT(""),
+dkT(" 6. Each time you redistribute the Program (or any work based on the"),
+dkT("Program), the recipient automatically receives a license from the"),
+dkT("original licensor to copy, distribute or modify the Program subject to"),
+dkT("these terms and conditions. You may not impose any further"),
+dkT("restrictions on the recipients' exercise of the rights granted herein."),
+dkT("You are not responsible for enforcing compliance by third parties to"),
+dkT("this License."),
+dkT(""),
+dkT(" 7. If, as a consequence of a court judgment or allegation of patent"),
+dkT("infringement or for any other reason (not limited to patent issues),"),
+dkT("conditions are imposed on you (whether by court order, agreement or"),
+dkT("otherwise) that contradict the conditions of this License, they do not"),
+dkT("excuse you from the conditions of this License. If you cannot"),
+dkT("distribute so as to satisfy simultaneously your obligations under this"),
+dkT("License and any other pertinent obligations, then as a consequence you"),
+dkT("may not distribute the Program at all. For example, if a patent"),
+dkT("license would not permit royalty-free redistribution of the Program by"),
+dkT("all those who receive copies directly or indirectly through you, then"),
+dkT("the only way you could satisfy both it and this License would be to"),
+dkT("refrain entirely from distribution of the Program."),
+dkT(""),
+dkT("If any portion of this section is held invalid or unenforceable under"),
+dkT("any particular circumstance, the balance of the section is intended to"),
+dkT("apply and the section as a whole is intended to apply in other"),
+dkT("circumstances."),
+dkT(""),
+dkT("It is not the purpose of this section to induce you to infringe any"),
+dkT("patents or other property right claims or to contest validity of any"),
+dkT("such claims; this section has the sole purpose of protecting the"),
+dkT("integrity of the free software distribution system, which is"),
+dkT("implemented by public license practices. Many people have made"),
+dkT("generous contributions to the wide range of software distributed"),
+dkT("through that system in reliance on consistent application of that"),
+dkT("system; it is up to the author/donor to decide if he or she is willing"),
+dkT("to distribute software through any other system and a licensee cannot"),
+dkT("impose that choice."),
+dkT(""),
+dkT("This section is intended to make thoroughly clear what is believed to"),
+dkT("be a consequence of the rest of this License."),
+dkT(""),
+dkT(" 8. If the distribution and/or use of the Program is restricted in"),
+dkT("certain countries either by patents or by copyrighted interfaces, the"),
+dkT("original copyright holder who places the Program under this License"),
+dkT("may add an explicit geographical distribution limitation excluding"),
+dkT("those countries, so that distribution is permitted only in or among"),
+dkT("countries not thus excluded. In such case, this License incorporates"),
+dkT("the limitation as if written in the body of this License."),
+dkT(""),
+dkT(" 9. The Free Software Foundation may publish revised and/or new versions"),
+dkT("of the General Public License from time to time. Such new versions will"),
+dkT("be similar in spirit to the present version, but may differ in detail to"),
+dkT("address new problems or concerns."),
+dkT(""),
+dkT("Each version is given a distinguishing version number. If the Program"),
+dkT("specifies a version number of this License which applies to it and \"any"),
+dkT("later version\", you have the option of following the terms and conditions"),
+dkT("either of that version or of any later version published by the Free"),
+dkT("Software Foundation. If the Program does not specify a version number of"),
+dkT("this License, you may choose any version ever published by the Free Software"),
+dkT("Foundation."),
+dkT(""),
+dkT(" 10. If you wish to incorporate parts of the Program into other free"),
+dkT("programs whose distribution conditions are different, write to the author"),
+dkT("to ask for permission. For software which is copyrighted by the Free"),
+dkT("Software Foundation, write to the Free Software Foundation; we sometimes"),
+dkT("make exceptions for this. Our decision will be guided by the two goals"),
+dkT("of preserving the free status of all derivatives of our free software and"),
+dkT("of promoting the sharing and reuse of software generally."),
+dkT(""),
+dkT("\t\t\t NO WARRANTY"),
+dkT(""),
+dkT(" 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY"),
+dkT("FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN"),
+dkT("OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES"),
+dkT("PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED"),
+dkT("OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF"),
+dkT("MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS"),
+dkT("TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE"),
+dkT("PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,"),
+dkT("REPAIR OR CORRECTION."),
+dkT(""),
+dkT(" 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING"),
+dkT("WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR"),
+dkT("REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,"),
+dkT("INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING"),
+dkT("OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED"),
+dkT("TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY"),
+dkT("YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER"),
+dkT("PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE"),
+dkT("POSSIBILITY OF SUCH DAMAGES."),
+dkT(""),
+dkT("\t\t END OF TERMS AND CONDITIONS"),
+dkT(""),
+dkT("\t How to Apply These Terms to Your New Programs"),
+dkT(""),
+dkT(" If you develop a new program, and you want it to be of the greatest"),
+dkT("possible use to the public, the best way to achieve this is to make it"),
+dkT("free software which everyone can redistribute and change under these terms."),
+dkT(""),
+dkT(" To do so, attach the following notices to the program. It is safest"),
+dkT("to attach them to the start of each source file to most effectively"),
+dkT("convey the exclusion of warranty; and each file should have at least"),
+dkT("the \"copyright\" line and a pointer to where the full notice is found."),
+dkT(""),
+dkT(" <one line to give the program's name and a brief idea of what it does.>"),
+dkT(" Copyright (C) <year> <name of author>"),
+dkT(""),
+dkT(" This program is free software; you can redistribute it and/or modify"),
+dkT(" it under the terms of the GNU General Public License as published by"),
+dkT(" the Free Software Foundation; either version 2 of the License, or"),
+dkT(" (at your option) any later version."),
+dkT(""),
+dkT(" This program is distributed in the hope that it will be useful,"),
+dkT(" but WITHOUT ANY WARRANTY; without even the implied warranty of"),
+dkT(" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the"),
+dkT(" GNU General Public License for more details."),
+dkT(""),
+dkT(" You should have received a copy of the GNU General Public License along"),
+dkT(" with this program; if not, write to the Free Software Foundation, Inc.,"),
+dkT(" 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA."),
+dkT(""),
+dkT("Also add information on how to contact you by electronic and paper mail."),
+dkT(""),
+dkT("If the program is interactive, make it output a short notice like this"),
+dkT("when it starts in an interactive mode:"),
+dkT(""),
+dkT(" Gnomovision version 69, Copyright (C) year name of author"),
+dkT(" Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'."),
+dkT(" This is free software, and you are welcome to redistribute it"),
+dkT(" under certain conditions; type `show c' for details."),
+dkT(""),
+dkT("The hypothetical commands `show w' and `show c' should show the appropriate"),
+dkT("parts of the General Public License. Of course, the commands you use may"),
+dkT("be called something other than `show w' and `show c'; they could even be"),
+dkT("mouse-clicks or menu items--whatever suits your program."),
+dkT(""),
+dkT("You should also get your employer (if you work as a programmer) or your"),
+dkT("school, if any, to sign a \"copyright disclaimer\" for the program, if"),
+dkT("necessary. Here is a sample; alter the names:"),
+dkT(""),
+dkT(" Yoyodyne, Inc., hereby disclaims all copyright interest in the program"),
+dkT(" `Gnomovision' (which makes passes at compilers) written by James Hacker."),
+dkT(""),
+dkT(" <signature of Ty Coon>, 1 April 1989"),
+dkT(" Ty Coon, President of Vice"),
+dkT(""),
+dkT("This General Public License does not permit incorporating your program into"),
+dkT("proprietary programs. If your program is a subroutine library, you may"),
+dkT("consider it more useful to permit linking proprietary applications with the"),
+dkT("library. If this is what you want to do, use the GNU Lesser General"),
+dkT("Public License instead of this License."),
+dkT(""),
+dkT("MySQL FLOSS License Exception"),
+dkT("-----------------------------"),
+dkT(""),
+dkT("MySQL FLOSS License Exception"),
+dkT(""),
+dkT("The MySQL AB Exception for Free/Libre and Open Source Software-only"),
+dkT("Applications Using MySQL Client Libraries (the \"FLOSS Exception\")."),
+dkT(""),
+dkT("Version 0.6, 7 March 2007"),
+dkT(""),
+dkT("Exception Intent"),
+dkT(""),
+dkT("We want specified Free/Libre and Open Source Software (``FLOSS'')"),
+dkT("applications to be able to use specified GPL-licensed MySQL client"),
+dkT("libraries (the ``Program'') despite the fact that not all FLOSS"),
+dkT("licenses are compatible with version 2 of the GNU General Public"),
+dkT("License (the ``GPL'')."),
+dkT(""),
+dkT("Legal Terms and Conditions"),
+dkT(""),
+dkT("As a special exception to the terms and conditions of version 2.0"),
+dkT("of the GPL:"),
+dkT(""),
+dkT(" 1. You are free to distribute a Derivative Work that is formed"),
+dkT(" entirely from the Program and one or more works (each, a"),
+dkT(" \"FLOSS Work\") licensed under one or more of the licenses"),
+dkT(" listed below in section 1, as long as:"),
+dkT(" a. You obey the GPL in all respects for the Program and the"),
+dkT(" Derivative Work, except for identifiable sections of the"),
+dkT(" Derivative Work which are not derived from the Program,"),
+dkT(" and which can reasonably be considered independent and"),
+dkT(" separate works in themselves,"),
+dkT(" b. all identifiable sections of the Derivative Work which"),
+dkT(" are not derived from the Program, and which can"),
+dkT(" reasonably be considered independent and separate works"),
+dkT(" in themselves,"),
+dkT(" i. are distributed subject to one of the FLOSS licenses"),
+dkT(" listed below, and"),
+dkT(" ii. the object code or executable form of those sections"),
+dkT(" are accompanied by the complete corresponding"),
+dkT(" machine-readable source code for those sections on"),
+dkT(" the same medium and under the same FLOSS license as"),
+dkT(" the corresponding object code or executable forms of"),
+dkT(" those sections, and"),
+dkT(" c. any works which are aggregated with the Program or with a"),
+dkT(" Derivative Work on a volume of a storage or distribution"),
+dkT(" medium in accordance with the GPL, can reasonably be"),
+dkT(" considered independent and separate works in themselves"),
+dkT(" which are not derivatives of either the Program, a"),
+dkT(" Derivative Work or a FLOSS Work."),
+dkT(" If the above conditions are not met, then the Program may only"),
+dkT(" be copied, modified, distributed or used under the terms and"),
+dkT(" conditions of the GPL or another valid licensing option from"),
+dkT(" MySQL AB."),
+dkT(""),
+dkT(" 2. FLOSS License List"),
+dkT(""),
+dkT("License name Version(s)/Copyright Date"),
+dkT("Academic Free License 2.0"),
+dkT("Apache Software License 1.0/1.1/2.0"),
+dkT("Apple Public Source License 2.0"),
+dkT("Artistic license From Perl 5.8.0"),
+dkT("BSD license \"July 22 1999\""),
+dkT("Common Development and Distribution License (CDDL) 1.0"),
+dkT("Common Public License 1.0"),
+dkT("Eclipse Public License 1.0"),
+dkT("GNU Library or \"Lesser\" General Public License (LGPL) 2.0/2.1"),
+dkT("Jabber Open Source License 1.0"),
+dkT("MIT license (As listed in file MIT-License.txt) ---"),
+dkT("Mozilla Public License (MPL) 1.0/1.1"),
+dkT("Open Software License 2.0"),
+dkT("OpenSSL license (with original SSLeay license) \"2003\" (\"1998\")"),
+dkT("PHP License 3.0"),
+dkT("Python license (CNRI Python License) ---"),
+dkT("Python Software Foundation License 2.1.1"),
+dkT("Sleepycat License \"1999\""),
+dkT("University of Illinois/NCSA Open Source License ---"),
+dkT("W3C License \"2001\""),
+dkT("X11 License \"2001\""),
+dkT("Zlib/libpng License ---"),
+dkT("Zope Public License 2.0"),
+dkT(""),
+dkT(" Due to the many variants of some of the above licenses, we"),
+dkT(" require that any version follow the 2003 version of the Free"),
+dkT(" Software Foundation's Free Software Definition"),
+dkT(" (http://www.gnu.org/philosophy/free-sw.html) or version 1.9 of"),
+dkT(" the Open Source Definition by the Open Source Initiative"),
+dkT(" (http://www.opensource.org/docs/definition.php)."),
+dkT(""),
+dkT(" 3. Definitions"),
+dkT(""),
+dkT(" a. Terms used, but not defined, herein shall have the"),
+dkT(" meaning provided in the GPL."),
+dkT(" b. Derivative Work means a derivative work under copyright"),
+dkT(" law."),
+dkT(""),
+dkT(" 4. Applicability: This FLOSS Exception applies to all Programs"),
+dkT(" that contain a notice placed by MySQL AB saying that the"),
+dkT(" Program may be distributed under the terms of this FLOSS"),
+dkT(" Exception. If you create or distribute a work which is a"),
+dkT(" Derivative Work of both the Program and any other work"),
+dkT(" licensed under the GPL, then this FLOSS Exception is not"),
+dkT(" available for that work; thus, you must remove the FLOSS"),
+dkT(" Exception notice from that work and comply with the GPL in all"),
+dkT(" respects, including by retaining all GPL notices. You may"),
+dkT(" choose to redistribute a copy of the Program exclusively under"),
+dkT(" the terms of the GPL by removing the FLOSS Exception notice"),
+dkT(" from that copy of the Program, provided that the copy has"),
+dkT(" never been modified by you or any third party."),
+dkT(""),
+dkT("Appendix A. Qualified Libraries and Packages"),
+dkT(""),
+dkT("The following is a non-exhaustive list of libraries and packages"),
+dkT("which are covered by the FLOSS License Exception. Please note that"),
+dkT("this appendix is provided merely as an additional service to"),
+dkT("specific FLOSS projects wishing to simplify licensing information"),
+dkT("for their users. Compliance with one of the licenses noted under"),
+dkT("the \"FLOSS license list\" section remains a prerequisite."),
+dkT(""),
+dkT("Package Name Qualifying License and Version"),
+dkT("Apache Portable Runtime (APR) Apache Software License 2.0"),
+dkT(""),
+NULL
+
+
+#line 3304 "itadmin.ctr"
+};
+
+
+
+/** Help text shown for --help.
+*/
+static dkChar const * const itadmin_help_text[] = {
+dkT(""),
+dkT("NAME"),
+dkT(""),
+dkT(" itadmin - IT administration using databases"),
+dkT(""),
+dkT("SYNOPSIS"),
+dkT(""),
+dkT(" itadmin [<options>] [<config-file>]"),
+dkT(""),
+dkT("DESCRIPTION"),
+dkT(""),
+dkT("The program reads IT-related information from a database and creates"),
+dkT("configuration files, a network documentation, and a license report."),
+dkT("A configuration file can be specified as argument, the program searches"),
+dkT("for itadmin.conf files if no configuration file is specified."),
+dkT(""),
+dkT("OPTIONS"),
+dkT(""),
+dkT("-c"),
+dkT("--configuration"),
+dkT("\tCreate configuration files and network documentation."),
+dkT(""),
+dkT("-l"),
+dkT("--licenses"),
+dkT("\tCreate license report."),
+dkT("\tIf none of -c and -l is used the program creates all output"),
+dkT("\t(same as both -c and -l used)."),
+dkT(""),
+dkT("-h"),
+dkT("--help"),
+dkT("\tShow a help text."),
+dkT(""),
+dkT("-v"),
+dkT("--version"),
+dkT("\tShow version information."),
+dkT(""),
+dkT("-L"),
+dkT("--license-terms"),
+dkT("\tShow license terms."),
+dkT(""),
+dkT("EXIT STATUS"),
+dkT(""),
+dkT("0 on success, all other exit status codes indicate an error."),
+dkT(""),
+dkT("FILES"),
+dkT(""),
+dkT("itadmin.conf"),
+dkT("\tThe itadmin.conf file contains the configuration information"),
+dkT("\tused by the program. The file consists of key=value pairs, one"),
+dkT("\tper line. Keys can consist of multiple words."),
+dkT("\tLines started by '#' are comments."),
+dkT("\tThe following key=value pairs can be used:"),
+dkT(""),
+dkT("\tdatabase host\t\t\t=\t<string>"),
+dkT("\tdatabase name\t\t\t=\t<string>"),
+dkT("\tdatabase credentials file\t=\t<filename>"),
+dkT("\tdhcpd.conf vlan\t\t\t=\t<name>"),
+dkT("\torganization\t\t\t=\t<name>"),
+dkT("\torganizational unit\t\t=\t<name>"),
+dkT("\tadministrator name\t\t=\t<name>"),
+dkT(""),
+dkT("AUTHOR"),
+dkT(""),
+dkT("Dirk Krause"),
+dkT(""),
+dkT("HISTORY"),
+dkT(""),
+dkT("The itadmin program replaces the hostsadm script found in previous"),
+dkT("versions of dktools."),
+dkT(""),
+dkT("COPYRIGHT AND LICENSE"),
+dkT(""),
+dkT("Run"),
+dkT(" itadmin --license-terms"),
+dkT("to see the license conditions."),
+dkT(""),
+dkT("SEE ALSO"),
+dkT(""),
+dkT("http://dktools.sourceforge.net"),
+dkT(""),
+NULL
+
+
+#line 3393 "itadmin.ctr"
+};
+
+
+/** Options for the itadmin program.
+*/
+static dk3_option_t const itadmin_options[] = {
+ { dkT('h'), dkT("help"), 0 },
+ { dkT('v'), dkT("version"), 0 },
+ { dkT('L'), dkT("license-terms"), 0 },
+ { dkT('c'), dkT("configuration"), 0 },
+ { dkT('l'), dkT("licenses"), 0 },
+};
+
+/** Number of elements in itadmin_options.
+*/
+static size_t itadmin_sz_options =
+(sizeof(itadmin_options)/sizeof(dk3_option_t));
+
+
+
+int
+itadmin_job_do_network(itadmin_job *job)
+{
+ int back = 0;
+ if(job) {
+ if((job->cmd) & ITADMIN_CMD_CONFIG) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+int
+itadmin_job_do_dhcp(itadmin_job *job)
+{
+ int back = 0;
+ if(itadmin_job_do_network(job)) {
+ if(job->f_dh) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+int
+itadmin_job_do_licenses(itadmin_job *job)
+{
+ int back = 0;
+ if(job) {
+ if((job->cmd) & ITADMIN_CMD_LICENSES) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Clean up a storage, destroy contained objects.
+ @param s Storage to clean up.
+ @param i Iterator through storage.
+ @param f Function to use on each object.
+*/
+static
+void
+itadmin_clean_storage(
+ dk3_sto_t **s,
+ dk3_sto_it_t **i,
+ itadmin_obj_del *f
+)
+{
+ void *v;
+
+ if(*s) {
+ if(*i) {
+ dk3sto_it_reset(*i);
+ while((v = dk3sto_it_next(*i)) != NULL) {
+ (*f)(v);
+ }
+ dk3sto_it_close(*i);
+ }
+ dk3sto_close(*s);
+ }
+ *s = NULL;
+ *i = NULL;
+}
+
+
+
+/** Initialize job structure.
+ @param job Job structure to initialize.
+ @param app Application structure for diagnostics.
+ @param msg Localized message texts.
+ @param noloc Texts, not localized.
+*/
+static
+void
+itadmin_job_init(
+ itadmin_job *job,
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *noloc
+)
+{
+ job->app = app;
+ job->opt = NULL;
+ job->msg = msg;
+ job->noloc = noloc;
+ job->exval = 1;
+ job->cmd = 0;
+ job->ec = 0;
+ job->f_dh = 0;
+ job->dbt = DK3_SQLDB_TYPE_MYSQL;
+ job->dbhn = NULL;
+ job->uc2l = NULL;
+ job->dbn = NULL;
+ job->dbcf = NULL;
+ job->dbus = NULL;
+ job->dbpw = NULL;
+ job->vlan = NULL;
+ job->org = NULL;
+ job->ou = NULL;
+ job->admn = NULL;
+ job->ldapb = NULL;
+ job->ngdep = NULL;
+ job->nng = 0;
+ job->s_us = NULL; job->i_us = NULL;
+ job->s_usn = NULL; job->i_usn = NULL;
+ job->s_bu = NULL; job->i_bu = NULL;
+ job->s_sp = NULL; job->i_sp = NULL;
+ job->s_vl = NULL; job->i_vl = NULL;
+ job->s_pa = NULL; job->i_pa = NULL;
+ job->s_nw = NULL; job->i_nw = NULL;
+ job->s_ng = NULL; job->i_ng = NULL;
+ job->s_nd = NULL; job->i_nd = NULL;
+ job->s_dc = NULL; job->i_dc = NULL;
+ job->s_dp = NULL; job->i_dp = NULL;
+ job->s_dg = NULL; job->i_dg = NULL;
+ job->s_ho = NULL; job->i_ho = NULL;
+ job->s_hoi = NULL; job->i_hoi = NULL;
+ job->s_sm = NULL; job->i_sm = NULL;
+ job->s_sw = NULL; job->i_sw = NULL;
+ job->s_lt = NULL; job->i_lt = NULL;
+ job->s_lc = NULL; job->i_lc = NULL;
+ job->s_lf = NULL; job->i_lf = NULL;
+ job->s_do = NULL; job->i_do = NULL;
+ job->dbptr = NULL;
+ job->gdate = 0;
+ job->hlh = 0;
+ job->ukoma = 0;
+ job->rel = 0;
+ if(*(msg[76]) == dkT('.')) { job->gdate = 1; }
+}
+
+
+
+/** Prepare a storage/iterator pair.
+ @param job Job structure.
+ @param s Address of storage pointer.
+ @param i Address if iterator pointer.
+ @param f Object comparison function for storage.
+ @param cr Comparison criteria.
+ @param ok Pointer to OK flag, reset on errors.
+*/
+static
+void
+itadmin_job_prepare_storage(
+ itadmin_job *job,
+ dk3_sto_t **s,
+ dk3_sto_it_t **i,
+ dk3_fct_comp_t *f,
+ int cr,
+ int *ok
+)
+{
+ *s = NULL;
+ *i = NULL;
+ *s = dk3sto_open_app(job->app);
+ if(*s) {
+ *i = dk3sto_it_open(*s);
+ if(*i) {
+ if(f) {
+ dk3sto_set_comp(*s, f, cr);
+ }
+ } else {
+ *ok = 0;
+ }
+ } else {
+ *ok = 0;
+ }
+}
+
+
+
+/** Prepare all data structures for a job.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_job_up(itadmin_job *job)
+{
+ dk3_time_t ct;
+ dk3_tm_t tm;
+ int back = 1;
+ int f_utf8 = 0;
+ (job->today).y = 0;
+ (job->today).m = 0;
+ (job->today).d = 0;
+ if(dk3sf_time(&ct)) {
+ if(dk3sf_localtime_app(&tm, &ct, job->app)) {
+ (job->today).y = tm.Y;
+ (job->today).m = tm.M;
+ (job->today).d = tm.D;
+ }
+ }
+ itadmin_job_prepare_storage(
+ job, &(job->s_us), &(job->i_us), itadmin_comp_user, 0, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_usn), &(job->i_usn), itadmin_comp_user, 2, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_bu), &(job->i_bu), itadmin_comp_building, 0, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_sp), &(job->i_sp), itadmin_comp_speed, 0, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_vl), &(job->i_vl), itadmin_comp_vlan, 0, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_pa), &(job->i_pa), itadmin_comp_connect, 0, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_nw), &(job->i_nw), itadmin_comp_network, 0, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_ng), &(job->i_ng), itadmin_comp_netgroup, 0, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_nd), &(job->i_nd), NULL, 0, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_dc), &(job->i_dc), itadmin_comp_dhcp_class, 0, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_dp), &(job->i_dp), itadmin_comp_dhcp_pool, 0, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_dg), &(job->i_dg), itadmin_comp_dhcp_group, 0, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_ho), &(job->i_ho), itadmin_comp_host, 0, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_hoi), &(job->i_hoi), itadmin_comp_host, 2, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_sm), &(job->i_sm), itadmin_comp_swman, 0, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_sw), &(job->i_sw), itadmin_comp_swprod, 0, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_lt), &(job->i_lt), itadmin_comp_lictype, 0, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_lc), &(job->i_lc), itadmin_comp_license, 0, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_lf), &(job->i_lf), itadmin_comp_license, 2, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_do), &(job->i_do), itadmin_comp_dhcp_option, 0, &back
+ );
+ f_utf8 = 0;
+ if(DK3_ENCODING_UTF8 == dk3app_get_encoding(job->app)) { f_utf8 = 1; }
+ job->uc2l = dk3uc2lat_open_app(NULL, 0, f_utf8, job->app);
+ if(!(job->uc2l)) { back = 0; }
+ return back;
+}
+
+
+
+/** Clean up job structure.
+ @param job Job structure to clean up.
+*/
+static
+void
+itadmin_job_cleanup(itadmin_job *job)
+{
+#if 0
+ /* 2016-12-09
+ Function dk3mem_reset_secure() to sanitize memory was added.
+ */
+ size_t sz;
+ size_t i;
+ int ok = 1;
+#endif
+ if(job->opt) {
+ dk3opt_close(job->opt);
+ } job->opt = NULL;
+ if(job->uc2l) {
+ dk3uc2lat_close(job->uc2l);
+ } job->uc2l = NULL;
+
+
+#line 3704 "itadmin.ctr"
+
+
+#line 3705 "itadmin.ctr"
+
+
+#line 3706 "itadmin.ctr"
+
+
+#line 3707 "itadmin.ctr"
+
+
+#line 3708 "itadmin.ctr"
+ dk3_release(job->dbhn);
+
+
+#line 3710 "itadmin.ctr"
+
+
+#line 3711 "itadmin.ctr"
+
+
+#line 3712 "itadmin.ctr"
+
+
+#line 3713 "itadmin.ctr"
+
+
+#line 3714 "itadmin.ctr"
+ dk3_release(job->dbn);
+
+
+#line 3716 "itadmin.ctr"
+
+
+#line 3717 "itadmin.ctr"
+
+
+#line 3718 "itadmin.ctr"
+
+
+#line 3719 "itadmin.ctr"
+
+
+#line 3720 "itadmin.ctr"
+ dk3_release(job->dbcf);
+
+
+#line 3722 "itadmin.ctr"
+
+
+#line 3723 "itadmin.ctr"
+
+
+#line 3724 "itadmin.ctr"
+
+
+#line 3725 "itadmin.ctr"
+
+
+#line 3726 "itadmin.ctr"
+ if(job->dbus) {
+#if 0
+ /* 2016-12-09
+ Function dk3mem_reset_secure() to sanitize memory was added.
+ */
+ dk3mem_res((void *)(job->dbus), dk3str_c8_len(job->dbus));
+#endif
+ (void)dk3mem_reset_secure((void *)(job->dbus), dk3str_c8_len(job->dbus));
+ }
+ dk3_release(job->dbus);
+
+
+#line 3737 "itadmin.ctr"
+#if 0
+
+
+#line 3739 "itadmin.ctr"
+
+
+#line 3740 "itadmin.ctr"
+
+
+#line 3741 "itadmin.ctr"
+#endif
+
+
+#line 3743 "itadmin.ctr"
+ if(job->dbpw) {
+#if 0
+ /* 2016-12-09
+ Function dk3mem_reset_secure() to sanitize memory was added.
+ */
+ sz = dk3str_c8_len(job->dbpw);
+ dk3mem_res((void *)(job->dbpw), dk3str_c8_len(job->dbpw));
+ /* Static code analysis: Dead assignment ok = 0 */
+ /* The purpose of the following instruction is to avoid */
+ /* optimizing out the memory reset in the instruction before. */
+ for (i = 0; i < sz; i++) { if('\0' != (job->dbpw)[i]) { ok = 0; } }
+ if (1 != ok) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 309);
+ }
+#endif
+ (void)dk3mem_reset_secure((void *)(job->dbpw), dk3str_c8_len(job->dbpw));
+ }
+ dk3_release(job->dbpw);
+
+
+#line 3762 "itadmin.ctr"
+
+
+#line 3763 "itadmin.ctr"
+
+
+#line 3764 "itadmin.ctr"
+
+
+#line 3765 "itadmin.ctr"
+
+
+#line 3766 "itadmin.ctr"
+ dk3_release(job->vlan);
+
+
+#line 3768 "itadmin.ctr"
+
+
+#line 3769 "itadmin.ctr"
+
+
+#line 3770 "itadmin.ctr"
+
+
+#line 3771 "itadmin.ctr"
+
+
+#line 3772 "itadmin.ctr"
+ dk3_release(job->org);
+
+
+#line 3774 "itadmin.ctr"
+
+
+#line 3775 "itadmin.ctr"
+
+
+#line 3776 "itadmin.ctr"
+
+
+#line 3777 "itadmin.ctr"
+
+
+#line 3778 "itadmin.ctr"
+ dk3_release(job->ou);
+
+
+#line 3780 "itadmin.ctr"
+
+
+#line 3781 "itadmin.ctr"
+
+
+#line 3782 "itadmin.ctr"
+
+
+#line 3783 "itadmin.ctr"
+
+
+#line 3784 "itadmin.ctr"
+ dk3_release(job->admn);
+
+
+#line 3786 "itadmin.ctr"
+
+
+#line 3787 "itadmin.ctr"
+
+
+#line 3788 "itadmin.ctr"
+
+
+#line 3789 "itadmin.ctr"
+
+
+#line 3790 "itadmin.ctr"
+ dk3_release(job->ldapb);
+ itadmin_clean_storage(&(job->s_us), &(job->i_us), itadmin_mem_user_del);
+ itadmin_clean_storage(&(job->s_bu), &(job->i_bu), itadmin_mem_building_del);
+ itadmin_clean_storage(&(job->s_sp), &(job->i_sp), itadmin_mem_speed_del);
+ itadmin_clean_storage(&(job->s_vl), &(job->i_vl), itadmin_mem_vlan_del);
+ itadmin_clean_storage(&(job->s_pa), &(job->i_pa), itadmin_mem_connect_del);
+ itadmin_clean_storage(&(job->s_nw), &(job->i_nw), itadmin_mem_network_del);
+ itadmin_clean_storage(&(job->s_ng), &(job->i_ng), itadmin_mem_netgroup_del);
+ itadmin_clean_storage(&(job->s_nd), &(job->i_nd), itadmin_mem_ngdep_del);
+ itadmin_clean_storage(&(job->s_dc), &(job->i_dc), itadmin_mem_dhcp_class_del);
+ itadmin_clean_storage(&(job->s_dp), &(job->i_dp), itadmin_mem_dhcp_pool_del);
+ itadmin_clean_storage(&(job->s_dg), &(job->i_dg), itadmin_mem_dhcp_group_del);
+ if(job->s_hoi) {
+ if(job->i_hoi) {
+ dk3sto_it_close(job->i_hoi);
+ }
+ dk3sto_close(job->s_hoi);
+ }
+ job->s_hoi = NULL; job->i_hoi = NULL;
+ if(job->s_usn) {
+ if(job->i_usn) {
+ dk3sto_it_close(job->i_usn);
+ }
+ dk3sto_close(job->s_usn);
+ }
+ job->s_usn = NULL; job->i_usn = NULL;
+ itadmin_clean_storage(&(job->s_ho), &(job->i_ho), itadmin_mem_host_del);
+ itadmin_clean_storage(&(job->s_sm), &(job->i_sm), itadmin_mem_sw_man_del);
+ itadmin_clean_storage(&(job->s_sw), &(job->i_sw), itadmin_mem_software_del);
+ itadmin_clean_storage(&(job->s_lt), &(job->i_lt), itadmin_mem_lic_type_del);
+ if(job->s_lf) {
+ if(job->i_lf) {
+ dk3sto_it_close(job->i_lf);
+ }
+ dk3sto_close(job->s_lf);
+ }
+ job->s_lf = NULL; job->i_lf = NULL;
+ itadmin_clean_storage(&(job->s_lc), &(job->i_lc), itadmin_mem_license_del);
+ itadmin_clean_storage(&(job->s_do),&(job->i_do),itadmin_mem_dhcp_option_del);
+ if(job->ngdep) {
+ dk3bm_close(job->ngdep);
+ job->ngdep = NULL;
+ }
+}
+
+
+
+/** Process command line arguments.
+ @param job Job structure.
+ @return 1 on success (can continue), 0 on error.
+*/
+static
+int
+itadmin_process_arguments(itadmin_job *job)
+{
+ dkChar const * const *xargv = NULL;
+ int xargc = 0;
+ int back = 0;
+
+
+#line 3849 "itadmin.ctr"
+ xargc = dk3app_get_argc(job->app);
+ xargv = dk3app_get_argv(job->app);
+ xargv++; xargc--;
+ job->opt = dk3opt_open_app(
+ itadmin_options, itadmin_sz_options,
+ dkT('\0'), NULL,
+ xargc, xargv,
+ job->app
+ );
+ if(job->opt) {
+ if(0 == dk3opt_get_error_code(job->opt)) {
+ back = 1;
+ if(dk3opt_is_set(job->opt, dkT('c'))) {
+ job->cmd |= ITADMIN_CMD_CONFIG;
+ }
+ if(dk3opt_is_set(job->opt, dkT('l'))) {
+ job->cmd |= ITADMIN_CMD_LICENSES;
+ }
+ if(dk3opt_is_set(job->opt, dkT('h'))) {
+ job->cmd |= ITADMIN_CMD_HELP;
+ }
+ if(dk3opt_is_set(job->opt, dkT('v'))) {
+ job->cmd |= ITADMIN_CMD_VERSION;
+ }
+ if(dk3opt_is_set(job->opt, dkT('L'))) {
+ job->cmd |= ITADMIN_CMD_LICENSE_TERMS;
+ }
+ } else {
+
+#line 3877 "itadmin.ctr"
+ }
+ } else {
+
+#line 3879 "itadmin.ctr"
+ }
+
+
+#line 3881 "itadmin.ctr"
+ return back;
+}
+
+
+
+/** Show version number.
+ @param job Job structure.
+*/
+static
+void
+itadmin_show_version(itadmin_job *job)
+{
+ dk3sf_fputs(itadmin_kw_noloc[2], stdout);
+ dk3sf_fputs(DKT_VERSION_DK, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+#if !(DK3_HAVE_MYSQL_MYSQL_H || DK3_HAVE_MYSQL_H)
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 167);
+#endif
+}
+
+
+
+/** Show help text.
+ @param job Job structure.
+*/
+static
+void
+itadmin_show_help(itadmin_job *job)
+{
+ dk3app_help(job->app, itadmin_kw_noloc[3], itadmin_help_text);
+}
+
+
+
+/** Show one text section, used to show license terms.
+ @param job Job structure.
+ @param ltxt License text to show.
+*/
+static
+void
+itadmin_show_license_section(itadmin_job *job, dkChar const * const *ltxt)
+{
+ dkChar const * const *sptr;
+ sptr = ltxt;
+ while(*sptr) {
+ dk3sf_fputs(*(sptr++), stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+}
+
+
+
+/** Show license conditions.
+ @param job Job structure.
+*/
+static
+void
+itadmin_show_license(itadmin_job *job)
+{
+ itadmin_show_license_section(job, itadmin_license_overview);
+ itadmin_show_license_section(job, itadmin_license_dktools);
+ itadmin_show_license_section(job, itadmin_license_mysql);
+}
+
+
+
+/** Run the tasks.
+ @param job Job structure.
+*/
+static
+void
+itadmin_run(itadmin_job *job)
+{
+ int success = 0;
+ if(itadmin_config_read(job)) {
+ if(itadmin_data_read(job)) {
+ /* PROGRESS: Expanding netgroup dependencies. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 77);
+ if(itadmin_netgroup_expand(job)) {
+ success = 1;
+ if(itadmin_job_do_network(job)) {
+ /*
+ Hosts
+ */
+ /* PROGRESS: Writing hosts file. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 78);
+ if(!itadmin_hosts_output(job)) {
+
+#line 3968 "itadmin.ctr"
+ success = 0;
+ }
+ if(job->ldapb) {
+ /* PROGRESS: Writing hosts.ldif file. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 79);
+ if(!itadmin_hosts_ldif_output(job)) {
+
+#line 3974 "itadmin.ctr"
+ success = 0;
+ }
+ }
+ /*
+ Ethers
+ */
+ /* PROGRESS: Writing ethers file. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 80);
+ if(!itadmin_ethers_output(job)) {
+
+#line 3983 "itadmin.ctr"
+ success = 0;
+ }
+ if(job->ldapb) {
+ /* PROGRESS: Writing ethers.ldif file. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 81);
+ if(!itadmin_ethers_ldif_output(job)) {
+
+#line 3989 "itadmin.ctr"
+ success = 0;
+ }
+ }
+ /*
+ Netgroups
+ */
+ /* PROGRESS: Writing netgroup.ldif file. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 82);
+ if(!itadmin_netgroup_ldif_output(job)) {
+
+#line 3998 "itadmin.ctr"
+ success = 0;
+ }
+ /*
+ DHCP configuration
+ */
+ if(itadmin_job_do_dhcp(job)) {
+ /* PROGRESS: Writing dhcpd.conf file. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 83);
+ if(!itadmin_dhcpd_conf_output(job)) {
+
+#line 4007 "itadmin.ctr"
+ success = 0;
+ }
+ }
+ /*
+ Network documentation
+ */
+ /* PROGRESS: Writing netdocu.tex file. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 84);
+ if(!itadmin_netdocu(job)) {
+
+#line 4016 "itadmin.ctr"
+ success = 0;
+ }
+ }
+ if(itadmin_job_do_licenses(job)) {
+ /*
+ Write license report.
+ */
+ /* PROGRESS: Writing licenses.tex file. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 85);
+ if(!itadmin_license_report(job)) {
+
+#line 4026 "itadmin.ctr"
+ success = 0;
+ }
+ }
+ }
+ /* PROGRESS: Finished writing output. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 86);
+ }
+ }
+ if(success) {
+ job->exval = 0;
+ } else {
+
+#line 4037 "itadmin.ctr"
+ }
+}
+
+
+
+/** Run program or print help/license/version.
+ @param job Job structure.
+*/
+static
+void
+itadmin_run_or_help(itadmin_job *job)
+{
+
+
+#line 4050 "itadmin.ctr"
+ if((job->cmd) & (~(ITADMIN_CMD_CONFIG | ITADMIN_CMD_LICENSES))) {
+
+#line 4051 "itadmin.ctr"
+ job->exval = 0;
+ dk3sf_initialize_stdout();
+ if((job->cmd) & ITADMIN_CMD_VERSION) {
+
+#line 4054 "itadmin.ctr"
+ itadmin_show_version(job);
+ }
+ if((job->cmd) & ITADMIN_CMD_LICENSE_TERMS) {
+
+#line 4057 "itadmin.ctr"
+ itadmin_show_license(job);
+ }
+ if((job->cmd) & ITADMIN_CMD_HELP) {
+
+#line 4060 "itadmin.ctr"
+ itadmin_show_help(job);
+ }
+ } else {
+
+#line 4063 "itadmin.ctr"
+ if(!((job->cmd) & (ITADMIN_CMD_CONFIG | ITADMIN_CMD_LICENSES))) {
+ job->cmd = (ITADMIN_CMD_CONFIG | ITADMIN_CMD_LICENSES);
+ }
+ itadmin_run(job);
+ }
+
+#line 4068 "itadmin.ctr"
+}
+
+
+
+/** Entry point of the program.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, any other value indicates an error.
+*/
+DK3_MAIN
+{
+ itadmin_job job; /* Job structure. */
+ dk3_app_t *app; /* Application structure. */
+ dkChar const * const *msg; /* Localized message texts. */
+ int exval = 1; /* Exit status code. */
+
+
+#line 4084 "itadmin.ctr"
+
+
+#line 4085 "itadmin.ctr"
+#if DK3_HAVE_TZSET
+ tzset();
+#endif
+ job.exval = 1;
+ app = dk3app_open_command(
+ argc, (dkChar const * const *)argv, itadmin_kw_noloc[0]
+ );
+ if(app) {
+ msg = dk3app_messages(app,itadmin_kw_noloc[1],(dkChar const **)itadmin_kw);
+ if(msg) {
+ itadmin_job_init(&job, app, msg, itadmin_kw_noloc);
+ if(itadmin_job_up(&job)) {
+ if(itadmin_process_arguments(&job)) {
+ itadmin_run_or_help(&job);
+ }
+ }
+ itadmin_job_cleanup(&job);
+ } else {
+ /*
+ BUG: Should not happen as dk3app_messages() returns the default
+ string array if there is any error.
+ */
+ }
+ dk3app_close(app);
+ } else {
+ /* ERROR: Memory */
+ fprintf(
+ stderr,
+ "ERROR: Not enough memory\n"
+ );
+ fflush(stderr);
+ }
+ exval = job.exval;
+
+
+#line 4119 "itadmin.ctr"
+
+
+#line 4120 "itadmin.ctr"
+ fflush(stdout);
+ exit(exval); return exval;
+}
+
+
+
diff --git a/support/dktools/itadmin.ctr b/support/dktools/itadmin.ctr
new file mode 100644
index 0000000000..f60d2c5835
--- /dev/null
+++ b/support/dktools/itadmin.ctr
@@ -0,0 +1,4125 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+
+
+%% header
+
+#include "dk3all.h"
+
+
+
+/** Computer owner/user.
+*/
+typedef struct {
+ char const *us; /**< Short name, login name (primary key). */
+ char const *tt; /**< Title, academic degree. */
+ char const *sn; /**< Surname. */
+ char const *na; /**< Family name. */
+ char const *em; /**< E-mail address. */
+ char const *cc; /**< ID in cost controlling. */
+ char const *si; /**< Staff ID number. */
+ dk3_sto_t *s_ho; /**< Hosts for user. */
+ dk3_sto_it_t *i_ho; /**< Iterator for hosts storage. */
+ dk3_sto_t *s_li; /**< Licenses assigned to user. */
+ dk3_sto_it_t *i_li; /**< Iterator for licenses storage. */
+} itadmin_user;
+
+
+
+/** Building.
+*/
+typedef struct {
+ char const *s; /**< Short name (primary key). */
+ char const *l; /**< Full building name. */
+ char const *a1; /**< Address line 1. */
+ char const *a2; /**< Address line 2. */
+ char const *a3; /**< Address line 3. */
+ char const *a4; /**< Address line 4. */
+ char const *zc; /**< Zip code (german: Postleitzahl). */
+ char const *city; /**< City/Town name. */
+} itadmin_building;
+
+
+
+/** Speed for network connection.
+*/
+typedef struct {
+ char const *s; /**< Short speed name (primary key). */
+ char const *l; /**< Long speed name (description). */
+} itadmin_speed;
+
+
+
+/** VLAN.
+*/
+typedef struct {
+ char const *s; /**< Short VLAN name (primary key). */
+ char const *l; /**< Long VLAN name (description). */
+ dk3_sto_t *s_nw; /**< Storage for networks. */
+ dk3_sto_it_t *i_nw; /**< Iterator through networks storage. */
+ dk3_sto_t *s_do; /**< DHCP options for VLAN. */
+ dk3_sto_it_t *i_do; /**< Iterator through DHCP options. */
+} itadmin_vlan;
+
+
+
+/** Network connection socket.
+*/
+typedef struct {
+ char const *s; /**< Short name (label on socket, pk). */
+ char const *hp; /**< Hub port used for socket. */
+ char const *room; /**< Room name or number in building. */
+ itadmin_speed *sp; /**< Speed setting for socket. */
+ itadmin_vlan *vl; /**< VLAN for socket. */
+ itadmin_building *bu; /**< Building. */
+} itadmin_connect;
+
+
+
+/** Network.
+*/
+typedef struct {
+ itadmin_vlan *vl; /**< Parent VLAN. */
+ dk3_sto_t *s_p; /**< Storage for DHCP pools. */
+ dk3_sto_it_t *i_p; /**< Iterator through pools storage. */
+ dk3_sto_t *s_dg; /**< Storage for DHCP groups in network. */
+ dk3_sto_it_t *i_dg; /**< Iterator through groups in nw storage. */
+ dk3_sto_t *s_do; /**< DHCP options. */
+ dk3_sto_it_t *i_do; /**< Iterator for DHCP options. */
+ dk3_sto_t *s_hoi; /**< Storage for hosts. */
+ dk3_sto_it_t *i_hoi; /**< Iterator for hosts storage. */
+ dk3_sto_t *s_dc; /**< DHCP classes for this network. */
+ dk3_sto_it_t *i_dc; /**< Iterator through DHCP classes storage. */
+ unsigned long ip4; /**< IPv4 start address (primary key). */
+ unsigned long ma4; /**< IPv4 network mask. */
+ unsigned long gw4; /**< IPv4 gateway. */
+ unsigned long bc4; /**< IPv4 broadcast address. */
+} itadmin_network;
+
+
+
+/** Netgroup.
+*/
+typedef struct {
+ char const *sn; /**< Short name (primary key). */
+ char const *ln; /**< Long name (description). */
+ size_t no; /**< Netgroup number. */
+} itadmin_netgroup;
+
+
+
+/** Netgroup dependency.
+*/
+typedef struct {
+ itadmin_netgroup *pa; /**< Parent group. */
+ itadmin_netgroup *ch; /**< Child group. */
+} itadmin_ngdep;
+
+
+
+/** DHCP class.
+*/
+typedef struct {
+ char const *sn; /**< Short name (primary key). */
+ char const *ln; /**< Long name (description). */
+ dk3_sto_t *s_ho; /**< Hosts in this class. */
+ dk3_sto_it_t *i_ho; /**< Iterator through hosts storage. */
+ itadmin_network *dhcpn; /**< Network for DHCP hosts. */
+} itadmin_dhcp_class;
+
+
+
+/** DHCP address pool.
+*/
+typedef struct {
+ itadmin_network *nw; /**< Network. */
+ itadmin_dhcp_class *acl; /**< Allowed DHCP class. */
+ dk3_sto_t *s_do; /**< DHCP options for pool. */
+ dk3_sto_it_t *i_do; /**< Iterator for DHCP options. */
+ dk3_sto_t *s_hoi; /**< Hosts storage. */
+ dk3_sto_it_t *i_hoi; /**< Hosts storage iterator. */
+ unsigned long ip4s; /**< IPv4 start address. */
+ unsigned long ip4e; /**< IPv4 end address. */
+ char duc; /**< Flag: Deny unknown clients. */
+ char auc; /**< Flag: Allow unknown clients. */
+} itadmin_dhcp_pool;
+
+
+
+/** DHCP group.
+*/
+typedef struct {
+ char const *sn; /**< Short group name (primary key). */
+ char const *ln; /**< Long name (description). */
+ dk3_sto_t *s_do; /**< DHCP options storage. */
+ dk3_sto_it_t *i_do; /**< DHCP options iterator. */
+} itadmin_dhcp_group;
+
+
+
+/** DHCP group within a network.
+*/
+typedef struct {
+ itadmin_dhcp_group *gr; /**< Group. */
+ dk3_sto_t *s_h; /**< Storage for hosts in this group. */
+ dk3_sto_it_t *i_h; /**< Iterator for storage. */
+} itadmin_dhcp_ginw;
+
+
+
+/** Date (used for host expiration).
+*/
+typedef struct {
+ int y; /**< Year. */
+ int m; /**< Month. */
+ int d; /**< Day in month. */
+} itadmin_date;
+
+
+
+/** Host.
+*/
+typedef struct {
+ itadmin_date expi; /**< Expiration date. */
+ char const *sn; /**< Short host name (primary key). */
+ char const *co; /**< Comment, description. */
+ char const *maca; /**< MAC address. */
+ char const *room; /**< Room within the building. */
+ char const *inv; /**< Inventory ID. */
+ char const *serno; /**< Serial number. */
+ char const *hid; /**< Host ID. */
+ char const *dnsd; /**< DNS domain. */
+ itadmin_user *un; /**< System owner. */
+ itadmin_netgroup *ng; /**< Netgroup. */
+ itadmin_dhcp_class *dc; /**< DHCP class. */
+ itadmin_dhcp_group *dg; /**< DHCP group. */
+ itadmin_dhcp_pool *dp; /**< DHCP pool. */
+ itadmin_connect *nc; /**< Network connection socket. */
+ itadmin_building *bu; /**< Building. */
+ dk3_sto_t *s_al; /**< Storage for aliases. */
+ dk3_sto_it_t *i_al; /**< Iterator through aliases storage. */
+ dk3_sto_t *s_do; /**< DHCP options for host. */
+ dk3_sto_it_t *i_do; /**< DHCP options iterator. */
+ dk3_sto_t *s_li; /**< Licenses assigned to host. */
+ dk3_sto_it_t *i_li; /**< Iterator through licenses storage. */
+ unsigned long ipv4; /**< IPv4 address. */
+ char fnf; /**< Flag: Full name first in hosts. */
+ char fgu; /**< Flag: Guest computer. */
+ char snd; /**< Flag: Skip in network documentation. */
+ char saw; /**< Flag: Skip in arpwatch configuration. */
+} itadmin_host;
+
+
+
+/** Software manufacturer.
+*/
+typedef struct {
+ char const *sn; /**< Short name (primary key). */
+ char const *ln; /**< Full name. */
+} itadmin_swman;
+
+
+
+/** Software product.
+*/
+typedef struct {
+ char const *sn; /**< Short name (primary key). */
+ char const *ln; /**< Full name. */
+ itadmin_swman *mn; /**< Software manufacturer. */
+} itadmin_swprod;
+
+
+
+/** License type.
+*/
+typedef struct {
+ char const *sn; /**< Short name (primary key). */
+ char const *ln; /**< Full name. */
+ int num; /**< Number of client licenses. */
+} itadmin_lictype;
+
+
+
+/** Software license.
+*/
+typedef struct {
+ itadmin_date d_del; /**< Delivery date. */
+ itadmin_date d_inv; /**< Invoice date. */
+ char const *order; /**< Internal order ID. */
+ char const *notes; /**< Additional notes about the license. */
+ char const *i_del; /**< Delivery note ID. */
+ char const *i_inv; /**< Invoice ID. */
+ itadmin_swprod *prod; /**< Software product. */
+ itadmin_lictype *ltype; /**< License type. */
+ itadmin_user *owner; /**< License owner. */
+ itadmin_host *host; /**< Host where license is used. */
+ unsigned long pk; /**< Primary key from database. */
+} itadmin_license;
+
+
+
+/** DHCP option.
+*/
+typedef struct {
+ char const *k; /**< Key (option name). */
+ char const *v; /**< Option value. */
+ long pk; /**< Primary key from database. */
+} itadmin_dhcp_option;
+
+
+
+/** Job structure for the itadmin program.
+*/
+typedef struct {
+ itadmin_date today; /**< Current date. */
+ dk3_app_t *app; /**< Application structure. */
+ dk3_option_set_t *opt; /**< Option set. */
+ dk3_sto_t *s_us; /**< User storage. */
+ dk3_sto_it_t *i_us; /**< User storage iterator. */
+ dk3_sto_t *s_usn; /**< User sorted by name. */
+ dk3_sto_it_t *i_usn; /**< Storage iterator for users by name. */
+ dk3_sto_t *s_bu; /**< Building storage. */
+ dk3_sto_it_t *i_bu; /**< Building storage iterator. */
+ dk3_sto_t *s_sp; /**< Patch speed storage. */
+ dk3_sto_it_t *i_sp; /**< Patch speed storage iterator. */
+ dk3_sto_t *s_vl; /**< VLAN storage. */
+ dk3_sto_it_t *i_vl; /**< VLAN storage iterator. */
+ dk3_sto_t *s_pa; /**< Network patch storage. */
+ dk3_sto_it_t *i_pa; /**< Network patch storage iterator. */
+ dk3_sto_t *s_nw; /**< Network storage. */
+ dk3_sto_it_t *i_nw; /**< Network storage iterator. */
+ dk3_sto_t *s_ng; /**< Netgroup storage. */
+ dk3_sto_it_t *i_ng; /**< Netgroup storage iterator. */
+ dk3_sto_t *s_nd; /**< Netgroup dependency storage. */
+ dk3_sto_it_t *i_nd; /**< Netgroup dependency storage iterator. */
+ dk3_sto_t *s_dc; /**< DHCP class storage. */
+ dk3_sto_it_t *i_dc; /**< DHCP class storage iterator. */
+ dk3_sto_t *s_dp; /**< DHCP pool storage. */
+ dk3_sto_it_t *i_dp; /**< DHCP pool storage iterator. */
+ dk3_sto_t *s_dg; /**< DHCP group storage. */
+ dk3_sto_it_t *i_dg; /**< DHCP group storage iterator. */
+ dk3_sto_t *s_ho; /**< Host storage, sorted by name. */
+ dk3_sto_it_t *i_ho; /**< Host storage iterator for s_ho. */
+ dk3_sto_t *s_hoi; /**< Host storage, sorted by IP address. */
+ dk3_sto_it_t *i_hoi; /**< Host storage iterator for s_hoi. */
+ dk3_sto_t *s_sm; /**< Software manufacturer storage. */
+ dk3_sto_it_t *i_sm; /**< Software manufacturer storage iterator. */
+ dk3_sto_t *s_sw; /**< Software storage. */
+ dk3_sto_it_t *i_sw; /**< Software storage iterator. */
+ dk3_sto_t *s_lt; /**< License type storage. */
+ dk3_sto_it_t *i_lt; /**< License type storage iterator. */
+ dk3_sto_t *s_lc; /**< Licenses storage. */
+ dk3_sto_it_t *i_lc; /**< Licenses storage iterator. */
+ dk3_sto_t *s_lf; /**< Free licenses. */
+ dk3_sto_it_t *i_lf; /**< Free licenses iterator. */
+ dk3_sto_t *s_do; /**< DHCP options for entire server. */
+ dk3_sto_it_t *i_do; /**< Iterator for DHCP options. */
+ void *dbptr; /**< Database object pointer. */
+ dk3_bm_t *ngdep; /**< Direct/indirect netgroup dependencies. */
+ dk3_uc2lat_t *uc2l; /**< Unicode to LaTeX converter. */
+ dkChar const * const *msg; /**< Localized message texts. */
+ dkChar const * const *noloc; /**< Texts, not localized. */
+ dkChar const *dbhn; /**< Database host name. */
+ dkChar const *dbn; /**< Database name. */
+ dkChar const *dbcf; /**< Database credentials files. */
+ dkChar const *dbus; /**< Database user name. */
+ dkChar const *dbpw; /**< Database password. */
+ dkChar const *vlan; /**< VLAN name. */
+ dkChar const *org; /**< Organization name. */
+ dkChar const *ou; /**< Organizational unit name. */
+ dkChar const *admn; /**< Administrator name. */
+ dkChar const *ldapb; /**< LDAP base. */
+ size_t nng; /**< Number of netgroups. */
+ int exval; /**< Exit status code. */
+ int ec; /**< Error code, see @ref errorcodes. */
+ int cmd; /**< Command to execute. */
+ int f_dh; /**< Flag: Write dhcpd.conf file. */
+ int dbt; /**< Database type. */
+ int gdate; /**< Flag: German date notation. */
+ int hlh; /**< Flag: Have localhost entry. */
+ int ukoma; /**< Flag: Use koma-script. */
+ int rel; /**< Release lease on shutdown. */
+} itadmin_job;
+
+
+
+/** Reader structure for credentials file.
+*/
+typedef struct {
+ itadmin_job *job; /**< Job structure. */
+ int f_clnt; /**< Flag: In client section. */
+} itadmin_cred_reader;
+
+
+/** @defgroup itadmincommand Command IDs for itadmin. */
+/**@{*/
+/** itadmin command: Rebuild configuration and network documentation.
+*/
+#define ITADMIN_CMD_CONFIG 1
+
+/** itadmin command: Rebuild license report.
+*/
+#define ITADMIN_CMD_LICENSES 2
+
+/** itadmin command: show help text.
+*/
+#define ITADMIN_CMD_HELP 4
+
+/** itadmin command: show version information.
+*/
+#define ITADMIN_CMD_VERSION 8
+
+/** itadmin command: show license terms.
+*/
+#define ITADMIN_CMD_LICENSE_TERMS 16
+/**@}*/
+
+
+
+/** Maximum size for configuration file lines.
+*/
+#define ITADMIN_CONFIG_LINE_SIZE 256
+
+/** Function to remove one object.
+*/
+typedef void itadmin_obj_del(void *);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Read configuration file(s).
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_config_read(itadmin_job *job);
+
+/** Delete one user.
+ @param v Object to delete.
+*/
+void
+itadmin_mem_user_del(void *v);
+
+/** Delete one building.
+ @param v Object to delete.
+*/
+void
+itadmin_mem_building_del(void *v);
+
+/** Delete one speed setting.
+ @param v Object to delete.
+*/
+void
+itadmin_mem_speed_del(void *v);
+
+/** Delete one VLAN.
+ @param v Object to delete.
+*/
+void
+itadmin_mem_vlan_del(void *v);
+
+/** Delete one network connection patch.
+ @param v Object to delete.
+*/
+void
+itadmin_mem_connect_del(void *v);
+
+/** Delete one network.
+ @param v Object to delete.
+*/
+void
+itadmin_mem_network_del(void *v);
+
+/** Delete one netgroup.
+ @param v Object to delete.
+*/
+void
+itadmin_mem_netgroup_del(void *v);
+
+/** Delete one netgroup dependency.
+ @param v Object to delete.
+*/
+void
+itadmin_mem_ngdep_del(void *v);
+
+/** Delete one DHCP class.
+ @param v Object to delete.
+*/
+void
+itadmin_mem_dhcp_class_del(void *v);
+
+/** Delete one DHCP pool.
+ @param v Object to delete.
+*/
+void
+itadmin_mem_dhcp_pool_del(void *v);
+
+/** Delete one DHCP group.
+ @param v Object to delete.
+*/
+void
+itadmin_mem_dhcp_group_del(void *v);
+
+/** Delete one host.
+ @param v Object to delete.
+*/
+void
+itadmin_mem_host_del(void *v);
+
+/** Delete one software manufacturer.
+ @param v Object to delete.
+*/
+void
+itadmin_mem_sw_man_del(void *v);
+
+/** Delete one software product.
+ @param v Object to delete.
+*/
+void
+itadmin_mem_software_del(void *v);
+
+/** Delete one license type.
+ @param v Object to delete.
+*/
+void
+itadmin_mem_lic_type_del(void *v);
+
+/** Delete one license.
+ @param v Object to delete.
+*/
+void
+itadmin_mem_license_del(void *v);
+
+/** Create new user.
+ @param job Job structure.
+ @param un Name.
+ @param tt Academic degree or title (may be NULL).
+ @param sn Surname (may be NULL).
+ @param na Name.
+ @param em E-Mail (may be NULL).
+ @param cc Cost control ID (may be NULL).
+ @param si Staff ID number (may be NULL).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_user *
+itadmin_mem_user_new(
+ itadmin_job *job,
+ char const *un,
+ char const *tt,
+ char const *sn,
+ char const *na,
+ char const *em,
+ char const *cc,
+ char const *si
+);
+
+/** Create new building.
+ @param job Job structure.
+ @param s Name.
+ @param l Long name (may be NULL).
+ @param a1 Address line 1 (typically street and number,
+ may be NULL).
+ @param a2 Address line 2 (may be NULL).
+ @param a3 Address line 3 (may be NULL).
+ @param a4 Address line 4 (may be NULL).
+ @param zc Zip code (may be NULL).
+ @param city Town or city name (may be NULL).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_building *
+itadmin_mem_building_new(
+ itadmin_job *job,
+ char const *s,
+ char const *l,
+ char const *a1,
+ char const *a2,
+ char const *a3,
+ char const *a4,
+ char const *zc,
+ char const *city
+);
+
+/** Create new speed setting.
+ @param job Job structure.
+ @param s Name.
+ @param n Description (may be NULL).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_speed *
+itadmin_mem_speed_new(
+ itadmin_job *job,
+ char const *s,
+ char const *n
+);
+
+/** Create new VLAN.
+ @param job Job structure.
+ @param s Name.
+ @param l Long name (may be NULL).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_vlan *
+itadmin_mem_vlan_new(
+ itadmin_job *job,
+ char const *s,
+ char const *l
+);
+
+/** Create new network connector.
+ @param job Job structure.
+ @param s Name.
+ @param hp Building.
+ @param room Room.
+ @param sp Speed setting.
+ @param vl VLAN.
+ @param bu Building.
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_connect *
+itadmin_mem_connect_new(
+ itadmin_job *job,
+ char const *s,
+ char const *hp,
+ char const *room,
+ itadmin_speed *sp,
+ itadmin_vlan *vl,
+ itadmin_building *bu
+);
+
+/** Create new network.
+ @param job Job structure.
+ @param ip4 Network address.
+ @param ma4 Network mask.
+ @param gw4 Gateway.
+ @param bc4 Broadcast address.
+ @param vl VLAN.
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_network *
+itadmin_mem_network_new(
+ itadmin_job *job,
+ unsigned long ip4,
+ unsigned long ma4,
+ unsigned long gw4,
+ unsigned long bc4,
+ itadmin_vlan *vl
+);
+
+/** Create new netgroup.
+ @param job Job structure.
+ @param sn Short name.
+ @param ln Long name (may be NULL).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_netgroup *
+itadmin_mem_netgroup_new(
+ itadmin_job *job,
+ char const *sn,
+ char const *ln
+);
+
+/** Create new netgroup dependency.
+ @param job Job structure.
+ @param pa Parent group.
+ @param ch Child group.
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_ngdep *
+itadmin_mem_ngdep_new(
+ itadmin_job *job,
+ itadmin_netgroup *pa,
+ itadmin_netgroup *ch
+);
+
+/** Create new DHCP class.
+ @param job Job structure.
+ @param sn Short name.
+ @param ln Long name (may be NULL).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_dhcp_class *
+itadmin_mem_dhcp_class_new(
+ itadmin_job *job,
+ char const *sn,
+ char const *ln
+);
+
+/** Create new DHCP pool.
+ @param job Job structure.
+ @param nw Network.
+ @param cn Allowed class (if unknown clients are denied,
+ may be NULL).
+ @param ip4s IPv4 start address.
+ @param ip4e IPv4 end address.
+ @param duc Flag: Deny unknown clients (needs cn).
+ @param auc Flag: Allow unknown clients.
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_dhcp_pool *
+itadmin_mem_dhcp_pool_new(
+ itadmin_job *job,
+ itadmin_network *nw,
+ itadmin_dhcp_class *cn,
+ unsigned long ip4s,
+ unsigned long ip4e,
+ int duc,
+ int auc
+);
+
+/** Create new DHCP group.
+ @param job Job structure.
+ @param sn Short name.
+ @param ln Long name (may be NULL).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_dhcp_group *
+itadmin_mem_dhcp_group_new(
+ itadmin_job *job,
+ char const *sn,
+ char const *ln
+);
+
+/** Create new host
+ @param job Job structure.
+ @param sn Short name.
+ @param co Comment/description (may be NULL).
+ @param maca MAC address (may be NULL).
+ @param room Room (may be NULL).
+ @param inv Inventory number (may be NULL).
+ @param serno Serial number (may be NULL).
+ @param hid Host ID (may be NULL).
+ @param expi Expiration date (may be NULL).
+ @param dnsd DNS domain (may be NULL).
+ @param un System owner.
+ @param ng Netgroup (may be NULL).
+ @param dc DHCP class (may be NULL).
+ @param dg DHCP group (may be NULL).
+ @param nc Network connection socket (may be NULL).
+ @param bu Building (may be NULL).
+ @param ipv4 IPv4 address (may be NULL).
+ @param fnf Flag: FQDN first in hosts file.
+ @param fgu Flag: Guest computer (bring your own device).
+ @param snd Flag: Skip in network documentation.
+ @param saw Flag: Skip in arpwatch configuration.
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_host *
+itadmin_mem_host_new(
+ itadmin_job *job,
+ itadmin_date *expi,
+ char const *sn,
+ char const *co,
+ char const *maca,
+ char const *room,
+ char const *inv,
+ char const *serno,
+ char const *hid,
+ char const *dnsd,
+ itadmin_user *un,
+ itadmin_netgroup *ng,
+ itadmin_dhcp_class *dc,
+ itadmin_dhcp_group *dg,
+ itadmin_connect *nc,
+ itadmin_building *bu,
+ unsigned long ipv4,
+ int fnf,
+ int fgu,
+ int snd,
+ int saw
+);
+
+/** Create new software manufacturer.
+ @param job Job structure.
+ @param sn Short name.
+ @param ln Long name (description).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_swman *
+itadmin_mem_sw_man_new(
+ itadmin_job *job,
+ char const *sn,
+ char const *ln
+);
+
+/** Create new software product.
+ @param job Job structure.
+ @param sn Short name.
+ @param ln Long name.
+ @param mn Software manufacturer name (may be NULL).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_swprod *
+itadmin_mem_swprod_new(
+ itadmin_job *job,
+ char const *sn,
+ char const *ln,
+ itadmin_swman *mn
+);
+
+/** Create new license type.
+ @param job Job structure.
+ @param sn Short license type name.
+ @param ln Long name (description).
+ @param num Number of client licenses for floating license servers.
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_lictype *
+itadmin_mem_lictype_new(
+ itadmin_job *job,
+ char const *sn,
+ char const *ln,
+ int num
+);
+
+/** Create new license.
+ @param job Job structure.
+ @param pk Primary key from licenses table (unused).
+ @param order Order ID or tracking information (may be NULL).
+ @param notes Additional notes (may be NULL).
+ @param d_del Delivery date (may be NULL).
+ @param i_del Delivery note ID (may be NULL).
+ @param d_inv Invoice date (may be NULL).
+ @param i_inv Invoice ID (may be NULL).
+ @param prod Software product.
+ @param ltype License type.
+ @param owner License owner (may be NULL).
+ @param host Computer (may be NULL).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_license *
+itadmin_mem_license_new(
+ itadmin_job *job,
+ unsigned long pk,
+ char const *order,
+ char const *notes,
+ itadmin_date *d_del,
+ char const *i_del,
+ itadmin_date *d_inv,
+ char const *i_inv,
+ itadmin_swprod *prod,
+ itadmin_lictype *ltype,
+ itadmin_user *owner,
+ itadmin_host *host
+);
+
+/** Create new DHCP group in network.
+ @param job Job structure.
+ @param gr DHCP group structure.
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_dhcp_ginw *
+itadmin_mem_dhcp_ginw_new(itadmin_job *job, itadmin_dhcp_group *gr);
+
+/** Destroy DHCP group in network structure, release memory.
+ @param g Group structure to destroy.
+*/
+void
+itadmin_mem_dhcp_ginw_del(itadmin_dhcp_ginw *g);
+
+/** Initialize date structure.
+ @param dp Date pointer.
+*/
+void
+itadmin_mem_date_init(itadmin_date *dp);
+
+/** Copy date structure.
+ @param dp Destination pointer.
+ @param sp Source pointer.
+*/
+void
+itadmin_mem_date_copy(itadmin_date *dp, itadmin_date *sp);
+
+/** Create a DHCP option structure.
+ @param job Job structure.
+ @param k Key (option name).
+ @param v Option value.
+ @param pk Primary key number from table (unused).
+ @return Valid pointer to new object on success, NULL on error.
+*/
+itadmin_dhcp_option *
+itadmin_mem_dhcp_option_new(
+ itadmin_job *job,
+ char const *k,
+ char const *v,
+ long pk
+);
+
+/** Destroy DHCP option structure, release memory.
+ @param v Option to destroy.
+*/
+void
+itadmin_mem_dhcp_option_del(void *v);
+
+/** Read data from database.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_data_read(itadmin_job *job);
+
+/** Read data from MySQL database.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_data_mysql_read(itadmin_job *job);
+
+/** Register a user record.
+ @param job Job structure.
+ @param us_s User short name (login name).
+ @param us_t User title or academic degree.
+ @param us_sn Surname.
+ @param us_fn Family name.
+ @param us_em E-Mail.
+ @param us_ko Cost control ID.
+ @param us_se Organizational unit.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_register_user(
+ itadmin_job *job,
+ char const *us_s,
+ char const *us_t,
+ char const *us_sn,
+ char const *us_fn,
+ char const *us_em,
+ char const *us_ko,
+ char const *us_se
+);
+
+/** Register building.
+ @param job Job structure.
+ @param gb_s Short building name.
+ @param gb_l Long building name.
+ @param gb_a1 Address line 1.
+ @param gb_a2 Address line 2.
+ @param gb_a3 Address line 3.
+ @param gb_a4 Address line 4.
+ @param gb_plz Zip code.
+ @param gb_ort City name.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_register_building(
+ itadmin_job *job,
+ char const *gb_s,
+ char const *gb_l,
+ char const *gb_a1,
+ char const *gb_a2,
+ char const *gb_a3,
+ char const *gb_a4,
+ char const *gb_plz,
+ char const *gb_ort
+);
+
+/** Register a speed setting.
+ @param job Job structure.
+ @param sn Short name for setting.
+ @param ln Description.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_register_speed(
+ itadmin_job *job,
+ char const *sn,
+ char const *ln
+);
+
+/** Register a VLAN.
+ @param job Job structure.
+ @param vl_s Short name for VLAN.
+ @param vl_l Description.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_register_vlan(itadmin_job *job, char const *vl_s, char const *vl_l);
+
+/** Register patch (ethernet socket).
+ @param job Job structure.
+ @param dd_n Patch name.
+ @param sp_s Speed setting name.
+ @param vl_s VLAN short name.
+ @param dd_p Hub port name.
+ @param gb_s Building.
+ @param dd_r Room number/name of patch.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_register_patch(
+ itadmin_job *job,
+ char const *dd_n,
+ char const *sp_s,
+ char const *vl_s,
+ char const *dd_p,
+ char const *gb_s,
+ char const *dd_r
+);
+
+/** Register network.
+ @param job Job structure.
+ @param nw_ip IP address.
+ @param nw_ma Network mask.
+ @param nw_gw Gateway.
+ @param nw_bc Broadcast address.
+ @param vl_s VLAN for network.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_register_network(
+ itadmin_job *job,
+ char const *nw_ip,
+ char const *nw_ma,
+ char const *nw_gw,
+ char const *nw_bc,
+ char const *vl_s
+);
+
+/** Register DHCP pool.
+ @param job Job structure.
+ @param ips IP start address of pool.
+ @param ipe IP end address of pool.
+ @param nw Network address (may be NULL or empty).
+ @param alu Flag: Allow unknown clients.
+ @param dnu Flag: Deny unknown clients.
+ @param dcn Allowed class name if unknown clients denied.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_register_dhcp_pool(
+ itadmin_job *job,
+ char const *ips,
+ char const *ipe,
+ char const *nw,
+ int alu,
+ int dnu,
+ char const *dcn
+);
+
+/** Register DHCP class.
+ @param job Job structure.
+ @param dcs Short class name.
+ @param dcl Long class name (description).
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_register_dhcp_class(itadmin_job *job,char const *dcs,char const *dcl);
+
+/** Register DHCP group.
+ @param job Job structure.
+ @param sn Short name.
+ @param ln Long name (description).
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_register_dhcp_group(itadmin_job *job, char const *sn, char const *ln);
+
+/** Register netgroup.
+ @param job Job structure.
+ @param ng_s Short netgroup name.
+ @param ng_l Long name (description).
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_register_netgroup(itadmin_job *job,char const *ng_s,char const *ng_l);
+
+/** Register netgroup dependency.
+ @param job Job structure.
+ @param pgn Name of the parent group.
+ @param cgn Name of the child group.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_register_ngdep(itadmin_job *job, char const *pgn, char const *cgn);
+
+/** Register one host.
+ @param job Job structure.
+ @param co_s Short name for computer.
+ @param us_s Owner / user in charge.
+ @param co_ip IPv4 address.
+ @param co_mc MAC address.
+ @param ng_s Netgroup.
+ @param co_co Comment for PC.
+ @param dc_s DHCP class.
+ @param dg_s DHCP group.
+ @param dd_n Patch/connector number.
+ @param gb_s Building.
+ @param co_r Room number.
+ @param co_in Inventory ID.
+ @param co_sn Serial number.
+ @param co_dd DNS domain name.
+ @param co_ff Flag: Write FQDN first in /etc/hosts.
+ @param co_gu Flag: BYOD (bring your own device).
+ @param co_hi Host ID.
+ @param co_ex Expiration date.
+ @param co_nn Flag: Skip host in network documentation.
+ @param co_na Flag: Skip host for arpwatch.
+*/
+
+int
+itadmin_register_host(
+ itadmin_job *job,
+ char const *co_s,
+ char const *us_s,
+ char const *co_ip,
+ char const *co_mc,
+ char const *ng_s,
+ char const *co_co,
+ char const *dc_s,
+ char const *dg_s,
+ char const *dd_n,
+ char const *gb_s,
+ char const *co_r,
+ char const *co_in,
+ char const *co_sn,
+ char const *co_dd,
+ int co_ff,
+ int co_gu,
+ char const *co_hi,
+ itadmin_date *co_ex,
+ int co_nn,
+ int co_na
+);
+
+/** Register host name alias.
+ @param job Job structure.
+ @param al Alias name.
+ @param rn Real host name.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_register_alias(itadmin_job *job, char const *al, char const *rn);
+
+/** Register a DHCP option.
+ @param job Job structure.
+ @param sct Scope type name.
+ @param scn Scope name.
+ @param k Key (option name).
+ @param v Option value.
+ @param pk Primary key from database.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_register_dhcp_option(
+ itadmin_job *job,
+ char const *sct,
+ char const *scn,
+ char const *k,
+ char const *v,
+ long pk
+);
+
+/** Check name for empty string or minus.
+ We have to save the entry if the string pointer is not
+ NULL and the string is not empty and not a minus.
+ @param sn String to check.
+ @return 1 if string must be saved, 0 for ignore.
+*/
+int
+itadmin_register_check_user_name(char const *sn);
+
+/** Check whether we can attempt to convert a string to an IP address.
+ @param ip String to test.
+ @return 1 for string with text, 0 for empty string.
+*/
+int
+itadmin_register_check_ip(char const *ip);
+
+/** Register a software manufacturer.
+ @param job Job structure.
+ @param sm_s Short name.
+ @param sm_l Long name.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_register_swman( itadmin_job *job, char const *sm_s, char const *sm_l);
+
+/** Register a software product.
+ @param job Job structure.
+ @param sw_s Short software name.
+ @param sw_l Long software name.
+ @param sm_s Software manufacturer.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_register_swprod(
+ itadmin_job *job,
+ char const *sw_s,
+ char const *sw_l,
+ char const *sm_s
+);
+/** Register a license type.
+ @param job Job structure.
+ @param lt_s Short license type name.
+ @param lt_l Long name/description of license type.
+ @param nl Number of licenses (for floating licenses).
+*/
+int
+itadmin_register_lictype(
+ itadmin_job *job,
+ char const *lt_s,
+ char const *lt_l,
+ int nl
+);
+
+/** Register license.
+ @param job Job structure.
+ @param pk Primary key.
+ @param li_on Order number (purchase process ID).
+ @param sw_s Software short name.
+ @param us_s User to which the license is assigned.
+ @param co_s Computer on which the license is used.
+ @param lt_s License type.
+ @param li_no Optional note for the license.
+ @param sr_s Software reseller.
+ @param li_dd Delivery date.
+ @param li_nd Delivery note number.
+ @param li_di Invoide date.
+ @param li_ni Invoice number.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_register_license(
+ itadmin_job *job,
+ unsigned long pk,
+ char const *li_on,
+ char const *sw_s,
+ char const *us_s,
+ char const *co_s,
+ char const *lt_s,
+ char const *li_no,
+ char const *sr_s,
+ itadmin_date *li_dd,
+ char const *li_nd,
+ itadmin_date *li_di,
+ char const *li_ni
+);
+
+/** Compare structures for user.
+ @param l Left structure.
+ @param r Right structure, object, or name.
+ @param cr Comparison criteria
+ (0=user/user by us, 1=user/name by us, 2=user/user by na+sn+tt+us).
+ @return Comparison result.
+*/
+int
+itadmin_comp_user(void const *l, void const *r, int cr);
+
+/** Compare structures for buildings.
+ @param l Left structure.
+ @param r Right structure, object, or name.
+ @param cr Comparison criteria
+ (0=building/building by s, 1=building/name by s).
+ @return Comparison result.
+*/
+int
+itadmin_comp_building(void const *l, void const *r, int cr);
+
+/** Compare structures for network speed.
+ @param l Left structure.
+ @param r Right structure, object, or name.
+ @param cr Comparison criteria
+ (0=speed/speed by s, 1=speed/name).
+ @return Comparison result.
+*/
+int
+itadmin_comp_speed(void const *l, void const *r, int cr);
+
+/** Compare structures for VLAN.
+ @param l Left structure.
+ @param r Right structure, object, or name.
+ @param cr Comparison criteria
+ (0=vlan/vlan by s, 1=vlan/name by s).
+ @return Comparison result.
+*/
+int
+itadmin_comp_vlan(void const *l, void const *r, int cr);
+
+/** Compare structures for ethernet socket.
+ @param l Left structure.
+ @param r Right structure, object, or name.
+ @param cr Comparison criteria
+ (0=socket/socket by s, 1=socket/name).
+ @return Comparison result.
+*/
+int
+itadmin_comp_connect(void const *l, void const *r, int cr);
+
+/** Compare structures for network.
+ @param l Left structure.
+ @param r Right structure, object, or name.
+ @param cr Comparison criteria
+ (0=network/network by ip4, 1=network/ipaddress).
+ @return Comparison result.
+*/
+int
+itadmin_comp_network(void const *l, void const *r, int cr);
+
+/** Compare structures for netgroup.
+ @param l Left structure.
+ @param r Right structure, object, or name.
+ @param cr Comparison criteria
+ (0=netgroup/netgroup by sn, 1=netgroup/name by sn).
+ @return Comparison result.
+*/
+int
+itadmin_comp_netgroup(void const *l, void const *r, int cr);
+
+/** Compare structures for DHCP class.
+ @param l Left structure.
+ @param r Right structure, object, or name.
+ @param cr Comparison criteria
+ (0=class/class by sn, 1=class/name by sn).
+ @return Comparison result.
+*/
+int
+itadmin_comp_dhcp_class(void const *l, void const *r, int cr);
+
+/** Compare structures for DHCP pool.
+ @param l Left structure.
+ @param r Right structure, object, or name.
+ @param cr Comparison criteria
+ (0=pool/pool by ip4s, 1=pool/ipaddress).
+ @return Comparison result.
+*/
+int
+itadmin_comp_dhcp_pool(void const *l, void const *r, int cr);
+
+/** Compare structures for DHCP group.
+ @param l Left structure.
+ @param r Right structure, object, or name.
+ @param cr Comparison criteria
+ (0=group/group by sn, 1=group/name).
+ @return Comparison result.
+*/
+int
+itadmin_comp_dhcp_group(void const *l, void const *r, int cr);
+
+/** Compare structures for host
+ @param l Left structure.
+ @param r Right structure, object, or name.
+ @param cr Comparison criteria
+ (0=host/host by sn, 1=host/name, 2=host/host by ipv4, 3=host/ipaddr).
+ @return Comparison result.
+*/
+int
+itadmin_comp_host(void const *l, void const *r, int cr);
+
+/** Compare structures for software manufacturer.
+ @param l Left structure.
+ @param r Right structure, object, or name.
+ @param cr Comparison criteria
+ (0=swman/swman by sn, 1=swman/name).
+ @return Comparison result.
+*/
+int
+itadmin_comp_swman(void const *l, void const *r, int cr);
+
+/** Compare structures for software product.
+ @param l Left structure.
+ @param r Right structure, object, or name.
+ @param cr Comparison criteria
+ (0=product/product by sn, 1=product/name,
+ 2=product/product by mn->ln+ln).
+ @return Comparison result.
+*/
+int
+itadmin_comp_swprod(void const *l, void const *r, int cr);
+
+/** Compare structures for license type.
+ @param l Left structure.
+ @param r Right structure, object, or name.
+ @param cr Comparison criteria
+ (0=type/type by sn, 1=type/name).
+ @return Comparison result.
+*/
+int
+itadmin_comp_user(void const *l, void const *r, int cr);
+
+/** Compare structures for license type.
+ @param l Left structure.
+ @param r Right structure, object, or name.
+ @param cr Comparison criteria
+ (0=license/license by product).
+ @return Comparison result.
+*/
+int
+itadmin_comp_lictype(void const *l, void const *r, int cr);
+
+/** Compare structures for license.
+ @param l Left structure.
+ @param r Right structure, object, or name.
+ @param cr Comparison criteria
+ (0=license/license by pk, 1=license/pk, 2=license/license by product).
+ @return Comparison result.
+*/
+int
+itadmin_comp_license(void const *l, void const *r, int cr);
+
+/** Compare two licenses within a network.
+ @param l Left object.
+ @param r Right object or name.
+ @param cr Comparison criteria (0=group/group,
+ 1=group/name).
+ @return Comparison result.
+*/
+int
+itadmin_comp_dhcp_ginw(void const *l, void const *r, int cr);
+
+/** Compare two date structures.
+ @param l Left object.
+ @param r Right object.
+ @return 1 if @arg l is later than @arg r, 0 for equal days,
+ 1 if @arg l is earlier than @arg r.
+*/
+int
+itadmin_comp_date(itadmin_date const *l, itadmin_date const *r);
+
+/** Compare two DHCP options.
+ @param l Left object.
+ @param r Right object.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+int
+itadmin_comp_dhcp_option(void const *l, void const *r, int cr);
+
+/** Compare two strings.
+ @param l Left string.
+ @param r Right string.
+ @param cr Comparison criteria (1=case-insensitive, 0=normal).
+ @return Comparison result.
+*/
+int
+itadmin_comp_string(void const *l, void const *r, int cr);
+
+/** Check whether we have to write network configuration
+ and documentation.
+ @param job Job structure.
+ @return 1 for yes, 0 for no.
+*/
+int
+itadmin_job_do_network(itadmin_job *job);
+
+/** Check whether we have to write a dhcpd.conf file.
+ @param job Job structure.
+ @return 1 for yes, 0 for no.
+*/
+int
+itadmin_job_do_dhcp(itadmin_job *job);
+
+/** Check whether we have to write a license report.
+ @param job Job structure.
+ @return 1 for yes, 0 for no.
+*/
+int
+itadmin_job_do_licenses(itadmin_job *job);
+
+/** Convert string yyyy-mm-dd to date structure.
+ @param job Job structure.
+ @param dp Destination pointer.
+ @param str Source text.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_tool_convert_date(itadmin_job *job, itadmin_date *dp, char const *str);
+
+/** Write IPv4 address to file.
+ @param df Destination file.
+ @param ipv4 Address to write.
+*/
+void
+itadmin_tool_write_ip(FILE *df, unsigned long ipv4);
+
+/** Write IPv4 address to stream.
+ @param os Output stream.
+ @param ipv4 Address to write.
+*/
+void
+itadmin_tool_stream_ip(dk3_stream_t *os, unsigned long ipv4);
+
+/** Write user name short to LaTeX output.
+ @param job Job structure.
+ @param os Output stream.
+ @param user User to write.
+*/
+void
+itadmin_tool_write_user_latex_short(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ itadmin_user *user
+);
+
+/** Write user name long to LaTeX output.
+ @param job Job structure.
+ @param os Output stream.
+ @param user User to write.
+*/
+void
+itadmin_tool_write_user_latex_long(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ itadmin_user *user
+);
+
+/** Write the section header in the table.
+ @param job Job structure.
+ @param os Output stream.
+ @param kwi Keyword index.
+*/
+void
+itadmin_tool_table_section_header(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ size_t kwi
+);
+
+/** Start a table line.
+ @param job Job structure.
+ @param os Output stream.
+ @param kwi Keyword index in localized messages.
+*/
+void
+itadmin_tool_table_line_start(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ size_t kwi
+);
+
+/** Separate two items in a table.
+ @param job Job structure.
+ @param os Output stream.
+*/
+void
+itadmin_tool_table_line_sep_rows(
+ itadmin_job *job,
+ dk3_stream_t *os
+);
+
+/** Finish a table line.
+ @param job Job structure.
+ @param os Output stream.
+ @param pb Flag: Allow page break here.
+*/
+void
+itadmin_tool_table_line_finish(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ int pb
+);
+
+/** Create empty table field.
+ @param job Job structure.
+ @param os Output stream.
+ @param nu Flag: Write notification for missing value.
+*/
+void
+itadmin_tool_table_line_no_data(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ int nu
+);
+
+/** Write one detail table line.
+ @param job Job structure.
+ @param os Output stream.
+ @param kwi Keyword index for option name.
+ @param det Details to write.
+ @param nu Flag: Write a note about unknown values.
+ @param pb Flag: Allow page break after line.
+*/
+void
+itadmin_tool_table_line(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ size_t kwi,
+ char const *det,
+ int nu,
+ int pb
+);
+
+/** Write a table line consisting of two values.
+ @param job Job structure.
+ @param os Output stream.
+ @param key Key.
+ @param val Value.
+ @param fb Flag: Key in bold.
+ @param pb Flag: Allow page break.
+*/
+void
+itadmin_tool_table_values(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ char const *key,
+ char const *val,
+ int fb,
+ int pb
+);
+
+/** Check whether a host is owned by a user.
+ @param us User.
+ @param co Host.
+ @return 1 if the host is owned by the user, 0 otherwise.
+*/
+int
+itadmin_tool_check_same_user(itadmin_user *us, itadmin_host *co);
+
+/** Write a section of text to output stream.
+ @param job Job structure.
+ @param os Output stream.
+ @param sect Text section to write.
+*/
+void
+itadmin_tool_write_section(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ char const * const *sect
+);
+
+/** Write log message of one part.
+ @param job Job structure.
+ @param ll Log level.
+ @param i Index of message text in localized messages array.
+*/
+void
+itadmin_tool_log_1(
+ itadmin_job *job,
+ int ll,
+ size_t i
+);
+
+/** Write log message of three parts.
+ @param job Job structure.
+ @param ll Log level.
+ @param i1 Index of first message text in localized messages array.
+ @param i2 Index of third text part in localized messages array.
+ @param msg Variable message text, second text part.
+*/
+void
+itadmin_tool_log_utf8_3(
+ itadmin_job *job,
+ int ll,
+ size_t i1,
+ size_t i2,
+ char const *msg
+);
+
+/** Write log message of five parts.
+ @param job Job structure.
+ @param ll Log level.
+ @param i1 Index of first message text in localized messages array.
+ @param i2 Index of third text part in localized messages array.
+ @param i3 Index of fifth text part in localized messages array.
+ @param msg1 First variable message text, second text part.
+ @param msg2 Second variable messagetext, fourth text part.
+*/
+void
+itadmin_tool_log_utf8_5(
+ itadmin_job *job,
+ int ll,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ char const *msg1,
+ char const *msg2
+);
+
+/** Write log message of three parts.
+ @param job Job structure.
+ @param ll Log level.
+ @param i1 Index of first constant message part.
+ @param i2 Index of third message part.
+ @param pk Primary key as numeric value.
+*/
+void
+itadmin_tool_log_pk_3(
+ itadmin_job *job,
+ int ll,
+ size_t i1,
+ size_t i2,
+ unsigned long pk
+);
+
+/** Write log message of five parts.
+ @param job Job structure.
+ @param ll Log level.
+ @param i1 Index of first constant message part.
+ @param i2 Index of third message part.
+ @param i3 Index of fifth message part.
+ @param pk Primary key as numeric value.
+ @param msg Variable message part.
+*/
+void
+itadmin_tool_log_pk_5(
+ itadmin_job *job,
+ int ll,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ unsigned long pk,
+ char const *msg
+);
+
+/** Write IPv4 address to buffer.
+ @param bu Destination buffer, at least 16 bytes long.
+ @param ip IP address.
+*/
+void
+itadmin_tool_ip_to_buffer(char *bu, unsigned long ip);
+
+/** Write hosts file.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_hosts_output(itadmin_job *job);
+
+/** Write hosts.ldif file.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_hosts_ldif_output(itadmin_job *job);
+
+/** Write ethers-by-ip and ethers-by-mac files.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_ethers_output(itadmin_job *job);
+
+/** Write ethers.ldif file.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_ethers_ldif_output(itadmin_job *job);
+
+/** Expand netgroup dependencies.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_netgroup_expand(itadmin_job *job);
+
+/** Check whether a host is a member of a netgroup.
+ @param job Job structure.
+ @param netgroup Netgroup.
+ @param host Host.
+ @return 0 for no member, 1 for indirect member, 2 for direct member.
+*/
+int
+itadmin_netgroup_host_member(
+ itadmin_job *job,
+ itadmin_netgroup *netgroup,
+ itadmin_host *host
+);
+
+/** Write netgroup.ldif file.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_netgroup_ldif_output(itadmin_job *job);
+
+/** Write dhcpd.conf file.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_dhcpd_conf_output(itadmin_job *job);
+
+/** Write network documentation file.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_netdocu(itadmin_job *job);
+
+/** Write license report.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_license_report(itadmin_job *job);
+
+#ifdef __cplusplus
+}
+#endif
+
+%% module
+
+
+#include "dk3all.h"
+#include "itadmin.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4vers.h"
+
+
+$!trace-include
+
+
+
+/** Keywords used by the program, not localized.
+*/
+static dkChar const * const itadmin_kw_noloc[] = {
+$!string-table macro=dkT
+#
+# 0: Program group name.
+#
+dktools
+#
+# 1: String table name.
+#
+itadmin.str
+#
+# 2: Program name used in version
+#
+itadmin
+#
+# 3: Help text file name.
+#
+itadmin.txt
+#
+# 4: Configuration file name.
+#
+itadmin.conf
+$!end
+};
+
+
+
+/** Localized message texts.
+*/
+static dkChar const * const itadmin_kw[] = {
+$!string-table macro=dkT
+#
+# 0: Title for network documentation
+#
+Network documentation
+#
+# 1: Subject for network documentation
+#
+Network documentation
+#
+# 2: LaTeX packages for localization
+#
+
+#
+# 3: Hosts
+#
+Hosts
+#
+# 4: Other hosts
+#
+Other hosts
+#
+# 5: Overview
+#
+Overview
+#
+# 6: Purpose:
+#
+Purpose:
+#
+# 7: Inventory ID:
+#
+Inventory ID:
+#
+# 8: Serial no:
+#
+Serial no:
+#
+# 9: not specified (unknown)
+#
+not specified
+#
+# 10: Main user: (person responsible for host)
+#
+Main user:
+#
+# 11: Place (building and room)
+#
+Place:
+#
+# 12: Network
+#
+Network
+#
+# 13: IP address
+#
+IP address:
+#
+# 14: DNS domain
+#
+DNS domain:
+#
+# 15: MAC address
+#
+MAC address:
+#
+# 16: Ethernet socket (patch no)
+#
+Ethernet socket:
+#
+# 17: DHCP class
+#
+DHCP class:
+#
+# 18: DHCP group
+#
+DHCP group:
+#
+# 19: Netgroups
+#
+Netgroups
+#
+# 20: Notice, this is an address from a DHCP pool
+#
+IP address from DHCP pool, dynamically assigned to DHCP clients
+#
+# 21: Short section header BYOD + DHCP
+#
+BYOD DHCP
+#
+# 22: Section header BYOD + DHCP
+#
+Bring your own device, use DHCP
+#
+# 23:
+#
+This is a ``bring your own device'' system, not owned by our organizational
+#
+# 24:
+#
+unit.
+#
+# 25:
+#
+This host is not owned by our organizational unit, it is a computer outside.
+#
+# 26:
+#
+It is listed in configuration files and documentation because there is a
+#
+# 27:
+#
+need for communication between our computers and this system.
+#
+# 28:
+#
+IP address dynamically assigned to computers.
+#
+# 29: Parent groups
+#
+Parent groups
+#
+# 30: Subgroups
+#
+Subgroups
+#
+# 31: Additional network interface
+#
+Additional network interface.
+#
+# 32: Member hosts for netgroups
+#
+Member hosts
+#
+# 33: DHCP pools
+#
+DHCP pools
+#
+# 34: Start address
+#
+Start address:
+#
+# 35: End address
+#
+End address:
+#
+# 36: Allow unknown clients
+#
+Allow unknown clients:
+#
+# 37: Deny unknown clients
+#
+Deny unknown clients:
+#
+# 38: Allow members of group
+#
+Allow class:
+#
+# 39: yes
+#
+yes
+#
+# 40: no
+#
+no
+#
+# 41: DHCP classes
+#
+DHCP classes
+#
+# 42: Ethernet connectors
+#
+Ethernet connectors
+#
+# 43: Connector
+#
+Connector
+#
+# 44: Room
+#
+Room
+#
+# 45: VLAN
+#
+VLAN
+#
+# 46: Speed
+#
+Speed
+#
+# 47: Hub port
+#
+Hub port
+#
+# 48: Available licenses
+#
+Available licenses
+#
+# 49/50: Message to explain section contents
+#
+The licenses listed here were purchased by the organizational unit
+but not (yet) assigned to a user or computer.
+#
+# 51: LaTeX text for pdftitle
+#
+License report
+#
+# 52: LaTeX text for pdfsubject
+#
+licenses
+#
+# 53: Default license type: Single computer license
+#
+Single computer license
+#
+# 54: LaTeX text: Purchase process ID
+#
+Purchase process ID:
+#
+# 55: LaTeX text: Delivery date
+#
+Delivery date:
+#
+# 56: LaTeX text: Delivery note ID (Lieferschein-Nr)
+#
+Delivery note ID:
+#
+# 57: LaTeX text: Invoice date
+#
+Invoice date:
+#
+# 58: LaTeX text: Invoice ID (Rechnungs-Nr)
+#
+Invoice ID:
+#
+# 59: LaTeX text: Complete license list
+#
+Complete license list
+#
+# 60: LaTeX text: Host unknown
+#
+Host unknown
+#
+# 61: LaTeX text: Assignment to host not specified.
+#
+Assignment to host not specified
+#
+# 62: LaTeX text: Other people's hosts
+#
+Other people's hosts
+#
+# 63: LaTeX text: Licenses used on other people's hosts
+#
+Licenses used on other people's hosts
+#
+# 64: LaTeX text
+#
+The licenses listed in this section were assigned to the user.
+#
+# 65: LaTeX text
+#
+There is no information available (yet) on which computers the licenses
+#
+# 66: LaTeX text
+#
+are used.
+#
+# 67: LaTeX text
+#
+The licenses listed in this section were assigned to the user.
+#
+# 68: LaTeX text
+#
+At this time they are used on computers other people are
+#
+# 69: LaTeX text
+#
+responsible for.
+#
+# 70: LaTeX text
+#
+Note:
+#
+# 71: LaTeX text
+#
+These licenses are listed twice in the license report:
+#
+# 72: LaTeX text
+#
+Once in the section for the host and once again here.
+#
+# 73: LaTeX text
+#
+This special situation is indicated in the host licenses section by
+#
+# 74: LaTeX text
+#
+the license owner name written in an
+#
+# 75: LaTeX text
+#
+italic font.
+#
+# 76: String separator in date, - for english, . for german
+#
+-
+#
+# 77: Progress message: Expanding netgroup dependencies.
+#
+Expanding netgroup dependencies.
+#
+# 78: Progress message: Writing hosts file.
+#
+Writing "hosts" file.
+#
+# 79: Progress message: Writing hosts.ldif file.
+#
+Writing "hosts.ldif" file.
+#
+# 80: Progress message: Writing ethers files.
+#
+Writing "ethers" files.
+#
+# 81: Progress message: Writing ethers.ldif file.
+#
+Writing "ethers.ldif" file.
+#
+# 82: Progress message: Writing netgroup.ldif file.
+#
+Writing "netgroup.ldif" file.
+#
+# 83: Progress message: Writing dhcpd.conf file.
+#
+Writing "dhcpd.conf" file.
+#
+# 84: Progress message: Writing netdocu.tex file.
+#
+Writing "netdocu.tex" file.
+#
+# 85: Progress message: Writing licenses.tex file.
+#
+Writing "licenses.tex" file.
+#
+# 86: Progress message: Finished writing output files.
+#
+Finished writing output files.
+#
+# 87: Progress message: Reading users table.
+#
+Reading users table.
+#
+# 88: Progress message: Reading buildings table.
+#
+Reading buildings table.
+#
+# 89: Progress message: Reading network speed types table.
+#
+Reading network speed types table.
+#
+# 90: Progress message: Reading VLANs table.
+#
+Reading VLANs table.
+#
+# 91: Progress message: Reading ethernet connectors table.
+#
+Reading ethernet connectors table.
+#
+# 92: Progress message: Reading netgroups table.
+#
+Reading netgroups table.
+#
+# 93: Progress message: Reading netgroup dependencies table.
+#
+Reading netgroup dependencies table.
+#
+# 94: Progress message: Reading networks table.
+#
+Reading networks table.
+#
+# 95: Progress message: Reading DHCP classes table.
+#
+Reading DHCP classes table.
+#
+# 96: Progress message: Reading DHCP groups table.
+#
+Reading DHCP groups table.
+#
+# 97: Progress message: Reading DHCP pools table.
+#
+Reading DHCP pools table.
+#
+# 98: Progress message: Reading hosts table.
+#
+Reading hosts table.
+#
+# 99: Progress message: Reading host name aliases table.
+#
+Reading host name aliases table.
+#
+# 100: Progress message: Reading DHCP options table.
+#
+Reading DHCP options table.
+#
+# 101: Progress message: Reading software manufacturers table.
+#
+Reading software manufacturers table.
+#
+# 102: Progress message: Reading software products table.
+#
+Reading software products table.
+#
+# 103: Progress message: Reading license types table.
+#
+Reading license types table.
+#
+# 104: Progress message: Reading licenses table.
+#
+Reading licenses table.
+#
+# 105: Progress message: Finished reading input from database.
+#
+Finished reading input from database.
+#
+# 106/107: ERROR: Not a boolean value "..."!
+#
+Not a boolean value: "
+"!
+#
+# 108/109: ERROR: Configuration text "..." too long!
+#
+Configuration value text "
+" too long!
+#
+# 110/111: ERROR: No such database type: "..."!
+#
+No such database type: "
+"!
+#
+# 112: ERROR: A value text is required!
+#
+A value text is required!
+#
+# 113/114: ERROR: Unknown configuration option "..."!
+#
+Unknown configuration option "
+"!
+#
+# 115: ERROR: Syntax error - "=" and value required!
+#
+Syntax error - "=" and value required!
+#
+# 116: ERROR: Input line too long!
+#
+Input line too long!
+#
+# 117: ERROR: Missing end of section name!
+#
+Missing end of section name!
+#
+# 118/119: ERROR: File name contains wildcards, this is not allowed!
+#
+File name "
+"\ncontains wildcards, this is not allowed!
+#
+# 120/121: WARNING: File name "..." is not an absolute path name!
+#
+File name "
+"\nis not an absolute path name!
+#
+# 122: ERROR: Missing database host name!
+#
+Missing database host name!
+#
+# 123: ERROR: Missing database name!
+#
+Missing database name!
+#
+# 124: WARNING: Missing DHCP VLAN name!
+#
+Missing DHCP VLAN name!
+#
+# 125: ERROR: Missing organization name!
+#
+Missing organization name!
+#
+# 126: ERROR: Missing organizational unit name!
+#
+Missing organizational unit name!
+#
+# 127: ERROR: Missing administrator name!
+#
+Missing administrator name!
+#
+# 128: ERROR: Missing database credentials file name!
+#
+Missing database credentials file name!
+#
+# 129: ERROR: Missing database user name!
+#
+Missing database user name!
+#
+# 130: ERROR: Missing database user password!
+#
+Missing database user password!
+#
+# 131: ERROR: No configuration files found!
+#
+No configuration file(s) "itadmin.conf" found!#
+#
+# 132: ERROR: Configuration problems!
+#
+Configuration problems,\nplease check the itadmin.conf configuration files!
+#
+# 133: ERROR: Unsupported database type!
+#
+Unsupported database type!
+#
+# 134: ERROR start: DHCP pool "
+#
+DHCP pool "
+#
+# 135: ERROR:
+#
+": Inconsistent setup!\nUnknown clients can be allowed or denied to use a pool, not both!
+#
+# 136: ERROR start DHCP class "
+#
+DHCP class "
+#
+# 137: ERROR: DHCP class assigned to pools in different networks!
+#
+" assigned to pools in different networks!
+#
+# 138: ERROR: DHCP pool "...": Missing allowed DHCP class name!
+#
+": Missing allowed DHCP class name!
+#
+# 139/140: ERROR: No such VLAN!
+#
+No such VLAN: "
+"!
+#
+# 141: ERROR: Failed to obtain results list!
+#
+Failed to obtain results list for database query!
+#
+# 142: ERROR: Failed to query database!
+#
+Failed to query database!
+#
+# 143: ERROR: Primary key is not numeric!
+#
+Table "licenses", record
+#
+# 144: ERROR: Primary key is not numeric!
+#
+ Primary key is not numeric!
+#
+# 145: ERROR: Missing primary key!
+#
+ Missing primary key!
+#
+# 146, 147, 148: License type "...": Not a number "..."!
+#
+License type "
+": Not a number "
+"!
+#
+# 149/150: ERROR: Tabel swm record ... Missing primary key!
+#
+Table "swmanufacturers" record
+ Missing primary key!
+#
+# 151: ERROR start: Table "dhcpoptions" record ...
+#
+Table "dhcpoptions" record
+#
+# 152: ERROR: Primary key is not numeric!
+#
+ Primary key is not numeric!
+#
+# 153: ERROR: Missing primary key!
+#
+ Missing primary key!
+#
+# 154: ERROR: Failed to set database encoding!
+#
+Failed to set database encoding!
+#
+# 155/156/157: ERROR: Failed to connect to database!
+#
+Failed to connect to database "
+" at host "
+"!
+#
+# 158/159: ERROR: Illegal database name!
+#
+Illegal database name: "
+"!
+#
+# 160: ERROR: Failed to convert database user password!
+#
+Failed to convert database user passwort to UTF-8!
+#
+# 161/162: ERROR: Failed to convert database user name to UTF-8!
+#
+Failed to convert database user name "
+" to UTF-8!
+#
+# 163/164: ERROR: Failed to convert database host name to UTF-8!
+#
+Failed to convert database host name "
+" to UTF-8!
+#
+# 165: ERROR: Failed to initialize MySQL client object!
+#
+Failed to initialize MySQL client object!
+#
+# 166: ERROR: Failed to initialize MySQL client library!
+#
+Failed to initialize MySQL client library!
+#
+# 167: ERROR: MySQL database support not available!
+#
+MySQL database support not available!
+#
+# 168/169: ERROR: User name "...": Duplicated entry!
+#
+User name "
+": Duplicated entry!
+#
+# 170/171: ERROR: Building "...": Duplicated entry!
+#
+Building "
+": Duplicated entry!
+#
+# 172/173: ERROR: Ethernet speed setting "...": Duplicated entry!
+#
+Ethernet speed setting "
+": Duplicated entry!
+#
+# 174/175: VLAN "...": Duplicated entry!
+#
+VLAN "
+": Duplicated entry!
+#
+# 176/177: Computer "...": Duplicated entry!
+#
+Computer "
+": Duplicated entry!
+#
+# 178/179: Software manufacturer "...": Duplicated entry!
+#
+Software manufacturer "
+": Duplicated entry!
+#
+# 180/181: Netgroup "...": Duplicated entry!
+#
+Netgroup "
+": Duplicated entry!
+#
+# 182/183: Netgroup "..." not defined!
+#
+Netgroup "
+" not defined!
+#
+# 184/185: Ethernet connector "...": Duplicated entry!
+#
+Ethernet connector "
+": Duplicated entry!
+#
+# 186/187: Ethernet speed setting "..." not defined!
+#
+Ethernet speed setting "
+" not defined!
+#
+# 188/189: VLAN "..." not defined!
+#
+VLAN "
+" not defined!
+#
+# 190/191: Building "..." not defined!
+#
+Building "
+" not defined!
+#
+# 192/193: Failed to convert net mask "..."!
+#
+Failed to convert net mask "
+"!
+#
+# 194: Using default net mask 255.255.255.0!
+#
+Using default net mask 255.255.255.0!
+#
+# 195/196: Failed to convert default gateway "..."!
+#
+Failed to convert default gateway "
+"!
+#
+# 197/198: Using default gateway ...
+#
+Using default gateway
+.
+#
+# 199/200: Failed to convert broadcast address!
+#
+Failed to convert broadcast address "
+"!
+#
+# 201/202: Network "...": Duplicated entry!
+#
+Network "
+": Duplicated entry!
+#
+# 203: Attempt to define IP network without specifying an IP address!
+#
+Attempt to define IP network without specifying an IP address!
+#
+# 204/205: DHCP class "...": Duplicated entry!
+#
+DHCP class "
+": Duplicated entry!
+#
+# 206/207: DHCP group "...": Duplicated entry!
+#
+DHCP group "
+": Duplicated entry!
+#
+# 208/209: Invalied network address "..."!
+#
+Invalid network address "
+"!
+#
+# 210/211: DHCP class "..." not defined!
+#
+DHCP class "
+" not defined!
+#
+# 212/213: Network "..." not defined!
+#
+Network "
+" not defined!
+#
+# 214/215: DHCP pool "...": Invalid end address!
+#
+DHCP pool "
+": Invalid end address!
+#
+# 216/217: DHCP pool "...": Missing end address!
+#
+DHCP pool "
+": Missing end address!
+#
+# 218/219: DHCP pool "...": Invalid start address!
+#
+DHCP pool "
+": Invalid start address!
+#
+# 220: DHCP pool definition attempted with empty start address!
+#
+DHCP pool definition attempted with empty start address!
+#
+# 221/222: Computer "...": Illegal MAC address!
+#
+Computer "
+": Illegal MAC address!
+#
+# 223/224: Computer "...": MAC address too long!
+#
+Computer "
+": MAC address too long!
+#
+# 225/226/227: Computer "...": User "..." not defined!
+#
+Computer "
+": User "
+" not defined!
+#
+# 228/229/230: Computer "...": Netgroup "..." not defined!
+#
+Computer "
+": Netgroup "
+" not defined!
+#
+# 231/232/233: Computer "...": DHCP class "..." not defined!
+#
+Computer "
+": DHCP class "
+" not defined!
+#
+# 234/235/236: Computer "...": DHCP group "..." not defined!
+#
+Computer "
+": DHCP group "
+" not defined!
+#
+# 237/238/239: Computer "...": Ethernet connector "..." not defined!
+#
+Computer "
+": Ethernet connector "
+" not defined!
+#
+# 240/241/242: Computer "...": Building "..." not defined!
+#
+Computer "
+": Building "
+" not defined!
+#
+# 243/244: Computer "...": Both DHCP class and IP address defined!
+#
+Computer "
+": Both DHCP class and IP address specified!
+#
+# 245/246: Computer "...": DHCP class specified, but MAC address missing!
+#
+Computer "
+": DHCP class specified, but MAC address is missing!
+#
+# 247/248: Computer "...": Netgroup specified, but IP address missing!
+#
+Computer "
+": Netgroup specified, but IP address is missing!
+#
+# 249/250: Computer "...": Netgroup specified, but DNS domain missing!
+#
+Computer "
+": Netgroup specified, but DNS domain is missing!
+#
+# 251/252: Computer "...": FQDN first flag set, but DNS domain missing!
+#
+Computer "
+": FQDN first flag set, but DNS domain is missing!
+#
+# 253/254: Computer "...": Over expiration date, should be removed!
+#
+Computer "
+": Over expiration date, should be removed!
+#
+# 255: Attempt to define a computer without a host name!
+#
+Attempt to define a computer without a host name!
+#
+# 256/257/258: Alias "...": Computer "..." not defined!
+#
+Alias "
+": Computer "
+" not defined!
+#
+# 259/260/261: DHCP option ...: VLAN "..." not defined!
+#
+DHCP option
+: VLAN "
+" not defined!
+#
+# 262/263/264: DHCP option ...: Network "..." not defined!
+#
+DHCP option
+: Network "
+" not defined!
+#
+# 265/266/267: DHCP option ...: DHCP group "..." not defined!
+#
+DHCP option
+: DHCP group "
+" not defined!
+#
+# 268/269/270: DHCP option ...: DHCP pool "..." not defined!
+#
+DHCP option
+: DHCP pool "
+" not defined!
+#
+# 271/272/273: DHCP option ...: Computer "..." not defined!
+#
+DHCP option
+: Computer "
+" not defined!
+#
+# 274/275/276: DHCP option ...: Unknown scope type name "..."!
+#
+DHCP option
+: Unknown scope type name "
+"!
+#
+# 277/278: Software product "...": Duplicated entry!
+#
+Software product "
+": Duplicated entry!
+#
+# 279/280/281: Software product "...": Manufacturer "..." not defined!
+#
+Software product "
+": Software manufacturer "
+" not defined!
+#
+# 282/283: License type "...": Duplicated entry!
+#
+License type "
+": Duplicated entry!
+#
+# 284/285: License ...: Duplicated entry!
+#
+License
+: Duplicated entry!
+#
+# 286/287/288: License ...: User "..." not defined!
+#
+License
+: User "
+" not defined!
+#
+# 289/290/291: License ...: Computer "..." not defined!
+#
+License
+: Computer "
+" not defined!
+#
+# 292/293/294: License ...: License type "..." not defined!
+#
+License
+: License type "
+" not defined!
+#
+# 295/296/297: License ... assigned to computer "..." but no user specified!
+#
+License
+ assigned to computer "
+" but no user specified!
+#
+# 298/299: License ...: No software product specified!
+#
+License
+: No software product specified!
+#
+# 300/301: Illegal date specification "..."!
+#
+Illegal date specification "
+"!
+#
+# 302: Koma-script suggestion.
+#
+Users from Europe - especially from Germany - should consider using koma-script.
+#
+# 303/304: ERROR: Illegal software manufacturer!
+#
+Illegal software manufacturer (short name): "
+"!
+#
+# 305/306: ERROR: Illegal software!
+#
+Illegal software (short name): "
+"!
+#
+# 307/308: ERROR: Illegal license type!
+#
+Illegal license type (short name): "
+"!
+#
+# 309: ERROR: Failed to reset sensitive memory range!
+#
+Failed to reset sensitive memory range!
+$!end
+};
+
+
+
+/** License text written for --license option.
+*/
+static dkChar const * const itadmin_license_overview[] = {
+$!text macro=dkT
+
+Overview
+========
+This software uses code from the following projects, either directly or
+by linking a library:
+
+dktools DK tools and libraries
+ See http://dktools.sourceforge.net for information.
+
+MySQL MySQL client library.
+ See http://www.mysql.com for information.
+
+$!end
+};
+
+
+
+/** License for the dktools project.
+*/
+static dkChar const * const itadmin_license_dktools[] = {
+$!text macro=dkT
+
+License conditions for DK tools and libraries
+=============================================
+Copyright (c) 2012-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the copyright holder(s) nor the names of
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+$!end
+};
+
+
+
+/** License for the MySQL client library (GPL + FLOSS exception).
+*/
+static dkChar const * const itadmin_license_mysql[] = {
+$!text macro=dkT
+License conditions for the MySQL client library
+===============================================
+
+GNU General Public License
+--------------------------
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange;
+ or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program 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 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
+
+MySQL FLOSS License Exception
+-----------------------------
+
+MySQL FLOSS License Exception
+
+The MySQL AB Exception for Free/Libre and Open Source Software-only
+Applications Using MySQL Client Libraries (the "FLOSS Exception").
+
+Version 0.6, 7 March 2007
+
+Exception Intent
+
+We want specified Free/Libre and Open Source Software (``FLOSS'')
+applications to be able to use specified GPL-licensed MySQL client
+libraries (the ``Program'') despite the fact that not all FLOSS
+licenses are compatible with version 2 of the GNU General Public
+License (the ``GPL'').
+
+Legal Terms and Conditions
+
+As a special exception to the terms and conditions of version 2.0
+of the GPL:
+
+ 1. You are free to distribute a Derivative Work that is formed
+ entirely from the Program and one or more works (each, a
+ "FLOSS Work") licensed under one or more of the licenses
+ listed below in section 1, as long as:
+ a. You obey the GPL in all respects for the Program and the
+ Derivative Work, except for identifiable sections of the
+ Derivative Work which are not derived from the Program,
+ and which can reasonably be considered independent and
+ separate works in themselves,
+ b. all identifiable sections of the Derivative Work which
+ are not derived from the Program, and which can
+ reasonably be considered independent and separate works
+ in themselves,
+ i. are distributed subject to one of the FLOSS licenses
+ listed below, and
+ ii. the object code or executable form of those sections
+ are accompanied by the complete corresponding
+ machine-readable source code for those sections on
+ the same medium and under the same FLOSS license as
+ the corresponding object code or executable forms of
+ those sections, and
+ c. any works which are aggregated with the Program or with a
+ Derivative Work on a volume of a storage or distribution
+ medium in accordance with the GPL, can reasonably be
+ considered independent and separate works in themselves
+ which are not derivatives of either the Program, a
+ Derivative Work or a FLOSS Work.
+ If the above conditions are not met, then the Program may only
+ be copied, modified, distributed or used under the terms and
+ conditions of the GPL or another valid licensing option from
+ MySQL AB.
+
+ 2. FLOSS License List
+
+License name Version(s)/Copyright Date
+Academic Free License 2.0
+Apache Software License 1.0/1.1/2.0
+Apple Public Source License 2.0
+Artistic license From Perl 5.8.0
+BSD license "July 22 1999"
+Common Development and Distribution License (CDDL) 1.0
+Common Public License 1.0
+Eclipse Public License 1.0
+GNU Library or "Lesser" General Public License (LGPL) 2.0/2.1
+Jabber Open Source License 1.0
+MIT license (As listed in file MIT-License.txt) ---
+Mozilla Public License (MPL) 1.0/1.1
+Open Software License 2.0
+OpenSSL license (with original SSLeay license) "2003" ("1998")
+PHP License 3.0
+Python license (CNRI Python License) ---
+Python Software Foundation License 2.1.1
+Sleepycat License "1999"
+University of Illinois/NCSA Open Source License ---
+W3C License "2001"
+X11 License "2001"
+Zlib/libpng License ---
+Zope Public License 2.0
+
+ Due to the many variants of some of the above licenses, we
+ require that any version follow the 2003 version of the Free
+ Software Foundation's Free Software Definition
+ (http://www.gnu.org/philosophy/free-sw.html) or version 1.9 of
+ the Open Source Definition by the Open Source Initiative
+ (http://www.opensource.org/docs/definition.php).
+
+ 3. Definitions
+
+ a. Terms used, but not defined, herein shall have the
+ meaning provided in the GPL.
+ b. Derivative Work means a derivative work under copyright
+ law.
+
+ 4. Applicability: This FLOSS Exception applies to all Programs
+ that contain a notice placed by MySQL AB saying that the
+ Program may be distributed under the terms of this FLOSS
+ Exception. If you create or distribute a work which is a
+ Derivative Work of both the Program and any other work
+ licensed under the GPL, then this FLOSS Exception is not
+ available for that work; thus, you must remove the FLOSS
+ Exception notice from that work and comply with the GPL in all
+ respects, including by retaining all GPL notices. You may
+ choose to redistribute a copy of the Program exclusively under
+ the terms of the GPL by removing the FLOSS Exception notice
+ from that copy of the Program, provided that the copy has
+ never been modified by you or any third party.
+
+Appendix A. Qualified Libraries and Packages
+
+The following is a non-exhaustive list of libraries and packages
+which are covered by the FLOSS License Exception. Please note that
+this appendix is provided merely as an additional service to
+specific FLOSS projects wishing to simplify licensing information
+for their users. Compliance with one of the licenses noted under
+the "FLOSS license list" section remains a prerequisite.
+
+Package Name Qualifying License and Version
+Apache Portable Runtime (APR) Apache Software License 2.0
+
+$!end
+};
+
+
+
+/** Help text shown for --help.
+*/
+static dkChar const * const itadmin_help_text[] = {
+$!text macro=dkT
+
+NAME
+
+ itadmin - IT administration using databases
+
+SYNOPSIS
+
+ itadmin [<options>] [<config-file>]
+
+DESCRIPTION
+
+The program reads IT-related information from a database and creates
+configuration files, a network documentation, and a license report.
+A configuration file can be specified as argument, the program searches
+for itadmin.conf files if no configuration file is specified.
+
+OPTIONS
+
+-c
+--configuration
+ Create configuration files and network documentation.
+
+-l
+--licenses
+ Create license report.
+ If none of -c and -l is used the program creates all output
+ (same as both -c and -l used).
+
+-h
+--help
+ Show a help text.
+
+-v
+--version
+ Show version information.
+
+-L
+--license-terms
+ Show license terms.
+
+EXIT STATUS
+
+0 on success, all other exit status codes indicate an error.
+
+FILES
+
+itadmin.conf
+ The itadmin.conf file contains the configuration information
+ used by the program. The file consists of key=value pairs, one
+ per line. Keys can consist of multiple words.
+ Lines started by '#' are comments.
+ The following key=value pairs can be used:
+
+ database host = <string>
+ database name = <string>
+ database credentials file = <filename>
+ dhcpd.conf vlan = <name>
+ organization = <name>
+ organizational unit = <name>
+ administrator name = <name>
+
+AUTHOR
+
+Dirk Krause
+
+HISTORY
+
+The itadmin program replaces the hostsadm script found in previous
+versions of dktools.
+
+COPYRIGHT AND LICENSE
+
+Run
+ itadmin --license-terms
+to see the license conditions.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
+$!end
+};
+
+
+/** Options for the itadmin program.
+*/
+static dk3_option_t const itadmin_options[] = {
+ { dkT('h'), dkT("help"), 0 },
+ { dkT('v'), dkT("version"), 0 },
+ { dkT('L'), dkT("license-terms"), 0 },
+ { dkT('c'), dkT("configuration"), 0 },
+ { dkT('l'), dkT("licenses"), 0 },
+};
+
+/** Number of elements in itadmin_options.
+*/
+static size_t itadmin_sz_options =
+(sizeof(itadmin_options)/sizeof(dk3_option_t));
+
+
+
+int
+itadmin_job_do_network(itadmin_job *job)
+{
+ int back = 0;
+ if(job) {
+ if((job->cmd) & ITADMIN_CMD_CONFIG) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+int
+itadmin_job_do_dhcp(itadmin_job *job)
+{
+ int back = 0;
+ if(itadmin_job_do_network(job)) {
+ if(job->f_dh) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+int
+itadmin_job_do_licenses(itadmin_job *job)
+{
+ int back = 0;
+ if(job) {
+ if((job->cmd) & ITADMIN_CMD_LICENSES) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Clean up a storage, destroy contained objects.
+ @param s Storage to clean up.
+ @param i Iterator through storage.
+ @param f Function to use on each object.
+*/
+static
+void
+itadmin_clean_storage(
+ dk3_sto_t **s,
+ dk3_sto_it_t **i,
+ itadmin_obj_del *f
+)
+{
+ void *v;
+
+ if(*s) {
+ if(*i) {
+ dk3sto_it_reset(*i);
+ while((v = dk3sto_it_next(*i)) != NULL) {
+ (*f)(v);
+ }
+ dk3sto_it_close(*i);
+ }
+ dk3sto_close(*s);
+ }
+ *s = NULL;
+ *i = NULL;
+}
+
+
+
+/** Initialize job structure.
+ @param job Job structure to initialize.
+ @param app Application structure for diagnostics.
+ @param msg Localized message texts.
+ @param noloc Texts, not localized.
+*/
+static
+void
+itadmin_job_init(
+ itadmin_job *job,
+ dk3_app_t *app,
+ dkChar const * const *msg,
+ dkChar const * const *noloc
+)
+{
+ job->app = app;
+ job->opt = NULL;
+ job->msg = msg;
+ job->noloc = noloc;
+ job->exval = 1;
+ job->cmd = 0;
+ job->ec = 0;
+ job->f_dh = 0;
+ job->dbt = DK3_SQLDB_TYPE_MYSQL;
+ job->dbhn = NULL;
+ job->uc2l = NULL;
+ job->dbn = NULL;
+ job->dbcf = NULL;
+ job->dbus = NULL;
+ job->dbpw = NULL;
+ job->vlan = NULL;
+ job->org = NULL;
+ job->ou = NULL;
+ job->admn = NULL;
+ job->ldapb = NULL;
+ job->ngdep = NULL;
+ job->nng = 0;
+ job->s_us = NULL; job->i_us = NULL;
+ job->s_usn = NULL; job->i_usn = NULL;
+ job->s_bu = NULL; job->i_bu = NULL;
+ job->s_sp = NULL; job->i_sp = NULL;
+ job->s_vl = NULL; job->i_vl = NULL;
+ job->s_pa = NULL; job->i_pa = NULL;
+ job->s_nw = NULL; job->i_nw = NULL;
+ job->s_ng = NULL; job->i_ng = NULL;
+ job->s_nd = NULL; job->i_nd = NULL;
+ job->s_dc = NULL; job->i_dc = NULL;
+ job->s_dp = NULL; job->i_dp = NULL;
+ job->s_dg = NULL; job->i_dg = NULL;
+ job->s_ho = NULL; job->i_ho = NULL;
+ job->s_hoi = NULL; job->i_hoi = NULL;
+ job->s_sm = NULL; job->i_sm = NULL;
+ job->s_sw = NULL; job->i_sw = NULL;
+ job->s_lt = NULL; job->i_lt = NULL;
+ job->s_lc = NULL; job->i_lc = NULL;
+ job->s_lf = NULL; job->i_lf = NULL;
+ job->s_do = NULL; job->i_do = NULL;
+ job->dbptr = NULL;
+ job->gdate = 0;
+ job->hlh = 0;
+ job->ukoma = 0;
+ job->rel = 0;
+ if(*(msg[76]) == dkT('.')) { job->gdate = 1; }
+}
+
+
+
+/** Prepare a storage/iterator pair.
+ @param job Job structure.
+ @param s Address of storage pointer.
+ @param i Address if iterator pointer.
+ @param f Object comparison function for storage.
+ @param cr Comparison criteria.
+ @param ok Pointer to OK flag, reset on errors.
+*/
+static
+void
+itadmin_job_prepare_storage(
+ itadmin_job *job,
+ dk3_sto_t **s,
+ dk3_sto_it_t **i,
+ dk3_fct_comp_t *f,
+ int cr,
+ int *ok
+)
+{
+ *s = NULL;
+ *i = NULL;
+ *s = dk3sto_open_app(job->app);
+ if(*s) {
+ *i = dk3sto_it_open(*s);
+ if(*i) {
+ if(f) {
+ dk3sto_set_comp(*s, f, cr);
+ }
+ } else {
+ *ok = 0;
+ }
+ } else {
+ *ok = 0;
+ }
+}
+
+
+
+/** Prepare all data structures for a job.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_job_up(itadmin_job *job)
+{
+ dk3_time_t ct;
+ dk3_tm_t tm;
+ int back = 1;
+ int f_utf8 = 0;
+ (job->today).y = 0;
+ (job->today).m = 0;
+ (job->today).d = 0;
+ if(dk3sf_time(&ct)) {
+ if(dk3sf_localtime_app(&tm, &ct, job->app)) {
+ (job->today).y = tm.Y;
+ (job->today).m = tm.M;
+ (job->today).d = tm.D;
+ }
+ }
+ itadmin_job_prepare_storage(
+ job, &(job->s_us), &(job->i_us), itadmin_comp_user, 0, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_usn), &(job->i_usn), itadmin_comp_user, 2, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_bu), &(job->i_bu), itadmin_comp_building, 0, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_sp), &(job->i_sp), itadmin_comp_speed, 0, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_vl), &(job->i_vl), itadmin_comp_vlan, 0, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_pa), &(job->i_pa), itadmin_comp_connect, 0, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_nw), &(job->i_nw), itadmin_comp_network, 0, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_ng), &(job->i_ng), itadmin_comp_netgroup, 0, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_nd), &(job->i_nd), NULL, 0, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_dc), &(job->i_dc), itadmin_comp_dhcp_class, 0, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_dp), &(job->i_dp), itadmin_comp_dhcp_pool, 0, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_dg), &(job->i_dg), itadmin_comp_dhcp_group, 0, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_ho), &(job->i_ho), itadmin_comp_host, 0, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_hoi), &(job->i_hoi), itadmin_comp_host, 2, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_sm), &(job->i_sm), itadmin_comp_swman, 0, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_sw), &(job->i_sw), itadmin_comp_swprod, 0, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_lt), &(job->i_lt), itadmin_comp_lictype, 0, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_lc), &(job->i_lc), itadmin_comp_license, 0, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_lf), &(job->i_lf), itadmin_comp_license, 2, &back
+ );
+ itadmin_job_prepare_storage(
+ job, &(job->s_do), &(job->i_do), itadmin_comp_dhcp_option, 0, &back
+ );
+ f_utf8 = 0;
+ if(DK3_ENCODING_UTF8 == dk3app_get_encoding(job->app)) { f_utf8 = 1; }
+ job->uc2l = dk3uc2lat_open_app(NULL, 0, f_utf8, job->app);
+ if(!(job->uc2l)) { back = 0; }
+ return back;
+}
+
+
+
+/** Clean up job structure.
+ @param job Job structure to clean up.
+*/
+static
+void
+itadmin_job_cleanup(itadmin_job *job)
+{
+#if 0
+ /* 2016-12-09
+ Function dk3mem_reset_secure() to sanitize memory was added.
+ */
+ size_t sz;
+ size_t i;
+ int ok = 1;
+#endif
+ if(job->opt) {
+ dk3opt_close(job->opt);
+ } job->opt = NULL;
+ if(job->uc2l) {
+ dk3uc2lat_close(job->uc2l);
+ } job->uc2l = NULL;
+ $!trace-code if(job->dbhn) {
+ $!trace-code dk3sf_fputs(dkT("DB hostname: "), stdout);
+ $!trace-code dk3sf_fputs(job->dbhn, stdout);
+ $!trace-code dk3sf_fputc(dkT('\n'), stdout);
+ $!trace-code }
+ dk3_release(job->dbhn);
+ $!trace-code if(job->dbn) {
+ $!trace-code dk3sf_fputs(dkT("DB name: "), stdout);
+ $!trace-code dk3sf_fputs(job->dbn, stdout);
+ $!trace-code dk3sf_fputc(dkT('\n'), stdout);
+ $!trace-code }
+ dk3_release(job->dbn);
+ $!trace-code if(job->dbcf) {
+ $!trace-code dk3sf_fputs(dkT("DB credfile: "), stdout);
+ $!trace-code dk3sf_fputs(job->dbcf, stdout);
+ $!trace-code dk3sf_fputc(dkT('\n'), stdout);
+ $!trace-code }
+ dk3_release(job->dbcf);
+ $!trace-code if(job->dbus) {
+ $!trace-code dk3sf_fputs(dkT("DB username: "), stdout);
+ $!trace-code dk3sf_fputs(job->dbus, stdout);
+ $!trace-code dk3sf_fputc(dkT('\n'), stdout);
+ $!trace-code }
+ if(job->dbus) {
+#if 0
+ /* 2016-12-09
+ Function dk3mem_reset_secure() to sanitize memory was added.
+ */
+ dk3mem_res((void *)(job->dbus), dk3str_c8_len(job->dbus));
+#endif
+ (void)dk3mem_reset_secure((void *)(job->dbus), dk3str_c8_len(job->dbus));
+ }
+ dk3_release(job->dbus);
+ $!trace-code if(job->dbpw) {
+#if 0
+ $!trace-code dk3sf_fputs(dkT("DB password: "), stdout);
+ $!trace-code dk3sf_fputs(job->dbpw, stdout);
+ $!trace-code dk3sf_fputc(dkT('\n'), stdout);
+#endif
+ $!trace-code }
+ if(job->dbpw) {
+#if 0
+ /* 2016-12-09
+ Function dk3mem_reset_secure() to sanitize memory was added.
+ */
+ sz = dk3str_c8_len(job->dbpw);
+ dk3mem_res((void *)(job->dbpw), dk3str_c8_len(job->dbpw));
+ /* Static code analysis: Dead assignment ok = 0 */
+ /* The purpose of the following instruction is to avoid */
+ /* optimizing out the memory reset in the instruction before. */
+ for (i = 0; i < sz; i++) { if('\0' != (job->dbpw)[i]) { ok = 0; } }
+ if (1 != ok) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 309);
+ }
+#endif
+ (void)dk3mem_reset_secure((void *)(job->dbpw), dk3str_c8_len(job->dbpw));
+ }
+ dk3_release(job->dbpw);
+ $!trace-code if(job->vlan) {
+ $!trace-code dk3sf_fputs(dkT("VLAN name: "), stdout);
+ $!trace-code dk3sf_fputs(job->vlan, stdout);
+ $!trace-code dk3sf_fputc(dkT('\n'), stdout);
+ $!trace-code }
+ dk3_release(job->vlan);
+ $!trace-code if(job->org) {
+ $!trace-code dk3sf_fputs(dkT("Organization: "), stdout);
+ $!trace-code dk3sf_fputs(job->org, stdout);
+ $!trace-code dk3sf_fputc(dkT('\n'), stdout);
+ $!trace-code }
+ dk3_release(job->org);
+ $!trace-code if(job->ou) {
+ $!trace-code dk3sf_fputs(dkT("OU name: "), stdout);
+ $!trace-code dk3sf_fputs(job->ou, stdout);
+ $!trace-code dk3sf_fputc(dkT('\n'), stdout);
+ $!trace-code }
+ dk3_release(job->ou);
+ $!trace-code if(job->admn) {
+ $!trace-code dk3sf_fputs(dkT("admin name: "), stdout);
+ $!trace-code dk3sf_fputs(job->admn, stdout);
+ $!trace-code dk3sf_fputc(dkT('\n'), stdout);
+ $!trace-code }
+ dk3_release(job->admn);
+ $!trace-code if(job->ldapb) {
+ $!trace-code dk3sf_fputs(dkT("ldap base: "), stdout);
+ $!trace-code dk3sf_fputs(job->ldapb, stdout);
+ $!trace-code dk3sf_fputc(dkT('\n'), stdout);
+ $!trace-code }
+ dk3_release(job->ldapb);
+ itadmin_clean_storage(&(job->s_us), &(job->i_us), itadmin_mem_user_del);
+ itadmin_clean_storage(&(job->s_bu), &(job->i_bu), itadmin_mem_building_del);
+ itadmin_clean_storage(&(job->s_sp), &(job->i_sp), itadmin_mem_speed_del);
+ itadmin_clean_storage(&(job->s_vl), &(job->i_vl), itadmin_mem_vlan_del);
+ itadmin_clean_storage(&(job->s_pa), &(job->i_pa), itadmin_mem_connect_del);
+ itadmin_clean_storage(&(job->s_nw), &(job->i_nw), itadmin_mem_network_del);
+ itadmin_clean_storage(&(job->s_ng), &(job->i_ng), itadmin_mem_netgroup_del);
+ itadmin_clean_storage(&(job->s_nd), &(job->i_nd), itadmin_mem_ngdep_del);
+ itadmin_clean_storage(&(job->s_dc), &(job->i_dc), itadmin_mem_dhcp_class_del);
+ itadmin_clean_storage(&(job->s_dp), &(job->i_dp), itadmin_mem_dhcp_pool_del);
+ itadmin_clean_storage(&(job->s_dg), &(job->i_dg), itadmin_mem_dhcp_group_del);
+ if(job->s_hoi) {
+ if(job->i_hoi) {
+ dk3sto_it_close(job->i_hoi);
+ }
+ dk3sto_close(job->s_hoi);
+ }
+ job->s_hoi = NULL; job->i_hoi = NULL;
+ if(job->s_usn) {
+ if(job->i_usn) {
+ dk3sto_it_close(job->i_usn);
+ }
+ dk3sto_close(job->s_usn);
+ }
+ job->s_usn = NULL; job->i_usn = NULL;
+ itadmin_clean_storage(&(job->s_ho), &(job->i_ho), itadmin_mem_host_del);
+ itadmin_clean_storage(&(job->s_sm), &(job->i_sm), itadmin_mem_sw_man_del);
+ itadmin_clean_storage(&(job->s_sw), &(job->i_sw), itadmin_mem_software_del);
+ itadmin_clean_storage(&(job->s_lt), &(job->i_lt), itadmin_mem_lic_type_del);
+ if(job->s_lf) {
+ if(job->i_lf) {
+ dk3sto_it_close(job->i_lf);
+ }
+ dk3sto_close(job->s_lf);
+ }
+ job->s_lf = NULL; job->i_lf = NULL;
+ itadmin_clean_storage(&(job->s_lc), &(job->i_lc), itadmin_mem_license_del);
+ itadmin_clean_storage(&(job->s_do),&(job->i_do),itadmin_mem_dhcp_option_del);
+ if(job->ngdep) {
+ dk3bm_close(job->ngdep);
+ job->ngdep = NULL;
+ }
+}
+
+
+
+/** Process command line arguments.
+ @param job Job structure.
+ @return 1 on success (can continue), 0 on error.
+*/
+static
+int
+itadmin_process_arguments(itadmin_job *job)
+{
+ dkChar const * const *xargv = NULL;
+ int xargc = 0;
+ int back = 0;
+ $? "+ itadmin_process_arguments"
+ xargc = dk3app_get_argc(job->app);
+ xargv = dk3app_get_argv(job->app);
+ xargv++; xargc--;
+ job->opt = dk3opt_open_app(
+ itadmin_options, itadmin_sz_options,
+ dkT('\0'), NULL,
+ xargc, xargv,
+ job->app
+ );
+ if(job->opt) {
+ if(0 == dk3opt_get_error_code(job->opt)) {
+ back = 1;
+ if(dk3opt_is_set(job->opt, dkT('c'))) {
+ job->cmd |= ITADMIN_CMD_CONFIG;
+ }
+ if(dk3opt_is_set(job->opt, dkT('l'))) {
+ job->cmd |= ITADMIN_CMD_LICENSES;
+ }
+ if(dk3opt_is_set(job->opt, dkT('h'))) {
+ job->cmd |= ITADMIN_CMD_HELP;
+ }
+ if(dk3opt_is_set(job->opt, dkT('v'))) {
+ job->cmd |= ITADMIN_CMD_VERSION;
+ }
+ if(dk3opt_is_set(job->opt, dkT('L'))) {
+ job->cmd |= ITADMIN_CMD_LICENSE_TERMS;
+ }
+ } else { $? "! errors in opt proc"
+ }
+ } else { $? "! failed to read opts"
+ }
+ $? "- itadmin_process_arguments %d", back
+ return back;
+}
+
+
+
+/** Show version number.
+ @param job Job structure.
+*/
+static
+void
+itadmin_show_version(itadmin_job *job)
+{
+ dk3sf_fputs(itadmin_kw_noloc[2], stdout);
+ dk3sf_fputs(DKT_VERSION_DK, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+#if !(DK3_HAVE_MYSQL_MYSQL_H || DK3_HAVE_MYSQL_H)
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 167);
+#endif
+}
+
+
+
+/** Show help text.
+ @param job Job structure.
+*/
+static
+void
+itadmin_show_help(itadmin_job *job)
+{
+ dk3app_help(job->app, itadmin_kw_noloc[3], itadmin_help_text);
+}
+
+
+
+/** Show one text section, used to show license terms.
+ @param job Job structure.
+ @param ltxt License text to show.
+*/
+static
+void
+itadmin_show_license_section(itadmin_job *job, dkChar const * const *ltxt)
+{
+ dkChar const * const *sptr;
+ sptr = ltxt;
+ while(*sptr) {
+ dk3sf_fputs(*(sptr++), stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+}
+
+
+
+/** Show license conditions.
+ @param job Job structure.
+*/
+static
+void
+itadmin_show_license(itadmin_job *job)
+{
+ itadmin_show_license_section(job, itadmin_license_overview);
+ itadmin_show_license_section(job, itadmin_license_dktools);
+ itadmin_show_license_section(job, itadmin_license_mysql);
+}
+
+
+
+/** Run the tasks.
+ @param job Job structure.
+*/
+static
+void
+itadmin_run(itadmin_job *job)
+{
+ int success = 0;
+ if(itadmin_config_read(job)) {
+ if(itadmin_data_read(job)) {
+ /* PROGRESS: Expanding netgroup dependencies. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 77);
+ if(itadmin_netgroup_expand(job)) {
+ success = 1;
+ if(itadmin_job_do_network(job)) {
+ /*
+ Hosts
+ */
+ /* PROGRESS: Writing hosts file. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 78);
+ if(!itadmin_hosts_output(job)) { $? "! hosts output"
+ success = 0;
+ }
+ if(job->ldapb) {
+ /* PROGRESS: Writing hosts.ldif file. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 79);
+ if(!itadmin_hosts_ldif_output(job)) { $? "! hosts.ldif output"
+ success = 0;
+ }
+ }
+ /*
+ Ethers
+ */
+ /* PROGRESS: Writing ethers file. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 80);
+ if(!itadmin_ethers_output(job)) { $? "! ethers output"
+ success = 0;
+ }
+ if(job->ldapb) {
+ /* PROGRESS: Writing ethers.ldif file. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 81);
+ if(!itadmin_ethers_ldif_output(job)) { $? "! ethers ldif"
+ success = 0;
+ }
+ }
+ /*
+ Netgroups
+ */
+ /* PROGRESS: Writing netgroup.ldif file. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 82);
+ if(!itadmin_netgroup_ldif_output(job)) { $? "! netgroup.ldif"
+ success = 0;
+ }
+ /*
+ DHCP configuration
+ */
+ if(itadmin_job_do_dhcp(job)) {
+ /* PROGRESS: Writing dhcpd.conf file. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 83);
+ if(!itadmin_dhcpd_conf_output(job)) { $? "! dhcpd.conf"
+ success = 0;
+ }
+ }
+ /*
+ Network documentation
+ */
+ /* PROGRESS: Writing netdocu.tex file. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 84);
+ if(!itadmin_netdocu(job)) { $? "! netdocu output"
+ success = 0;
+ }
+ }
+ if(itadmin_job_do_licenses(job)) {
+ /*
+ Write license report.
+ */
+ /* PROGRESS: Writing licenses.tex file. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 85);
+ if(!itadmin_license_report(job)) { $? "! license report"
+ success = 0;
+ }
+ }
+ }
+ /* PROGRESS: Finished writing output. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 86);
+ }
+ }
+ if(success) {
+ job->exval = 0;
+ } else { $? "! no success"
+ }
+}
+
+
+
+/** Run program or print help/license/version.
+ @param job Job structure.
+*/
+static
+void
+itadmin_run_or_help(itadmin_job *job)
+{
+ $? "+ itadmin_run_or_help"
+ if((job->cmd) & (~(ITADMIN_CMD_CONFIG | ITADMIN_CMD_LICENSES))) { $? ". help"
+ job->exval = 0;
+ dk3sf_initialize_stdout();
+ if((job->cmd) & ITADMIN_CMD_VERSION) { $? ". version"
+ itadmin_show_version(job);
+ }
+ if((job->cmd) & ITADMIN_CMD_LICENSE_TERMS) { $? ". license"
+ itadmin_show_license(job);
+ }
+ if((job->cmd) & ITADMIN_CMD_HELP) { $? ". help"
+ itadmin_show_help(job);
+ }
+ } else { $? ". run"
+ if(!((job->cmd) & (ITADMIN_CMD_CONFIG | ITADMIN_CMD_LICENSES))) {
+ job->cmd = (ITADMIN_CMD_CONFIG | ITADMIN_CMD_LICENSES);
+ }
+ itadmin_run(job);
+ } $? "- itadmin_run_or_help"
+}
+
+
+
+/** Entry point of the program.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, any other value indicates an error.
+*/
+DK3_MAIN
+{
+ itadmin_job job; /* Job structure. */
+ dk3_app_t *app; /* Application structure. */
+ dkChar const * const *msg; /* Localized message texts. */
+ int exval = 1; /* Exit status code. */
+ $!trace-init itadmin.deb
+ $? "+ main"
+#if DK3_HAVE_TZSET
+ tzset();
+#endif
+ job.exval = 1;
+ app = dk3app_open_command(
+ argc, (dkChar const * const *)argv, itadmin_kw_noloc[0]
+ );
+ if(app) {
+ msg = dk3app_messages(app,itadmin_kw_noloc[1],(dkChar const **)itadmin_kw);
+ if(msg) {
+ itadmin_job_init(&job, app, msg, itadmin_kw_noloc);
+ if(itadmin_job_up(&job)) {
+ if(itadmin_process_arguments(&job)) {
+ itadmin_run_or_help(&job);
+ }
+ }
+ itadmin_job_cleanup(&job);
+ } else {
+ /*
+ BUG: Should not happen as dk3app_messages() returns the default
+ string array if there is any error.
+ */
+ }
+ dk3app_close(app);
+ } else {
+ /* ERROR: Memory */
+ fprintf(
+ stderr,
+ "ERROR: Not enough memory\n"
+ );
+ fflush(stderr);
+ }
+ exval = job.exval;
+ $? "- main %d", exval
+ $!trace-end
+ fflush(stdout);
+ exit(exval); return exval;
+}
+
+
+
diff --git a/support/dktools/itadmin.h b/support/dktools/itadmin.h
new file mode 100644
index 0000000000..6fb38ad42d
--- /dev/null
+++ b/support/dktools/itadmin.h
@@ -0,0 +1,1790 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: itadmin.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file itadmin.h Header file for the itadmin module.
+*/
+
+#ifndef ITADMIN_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define ITADMIN_H_INCLUDED 1
+
+
+#line 10 "itadmin.ctr"
+
+#include "dk3all.h"
+
+
+
+/** Computer owner/user.
+*/
+typedef struct {
+ char const *us; /**< Short name, login name (primary key). */
+ char const *tt; /**< Title, academic degree. */
+ char const *sn; /**< Surname. */
+ char const *na; /**< Family name. */
+ char const *em; /**< E-mail address. */
+ char const *cc; /**< ID in cost controlling. */
+ char const *si; /**< Staff ID number. */
+ dk3_sto_t *s_ho; /**< Hosts for user. */
+ dk3_sto_it_t *i_ho; /**< Iterator for hosts storage. */
+ dk3_sto_t *s_li; /**< Licenses assigned to user. */
+ dk3_sto_it_t *i_li; /**< Iterator for licenses storage. */
+} itadmin_user;
+
+
+
+/** Building.
+*/
+typedef struct {
+ char const *s; /**< Short name (primary key). */
+ char const *l; /**< Full building name. */
+ char const *a1; /**< Address line 1. */
+ char const *a2; /**< Address line 2. */
+ char const *a3; /**< Address line 3. */
+ char const *a4; /**< Address line 4. */
+ char const *zc; /**< Zip code (german: Postleitzahl). */
+ char const *city; /**< City/Town name. */
+} itadmin_building;
+
+
+
+/** Speed for network connection.
+*/
+typedef struct {
+ char const *s; /**< Short speed name (primary key). */
+ char const *l; /**< Long speed name (description). */
+} itadmin_speed;
+
+
+
+/** VLAN.
+*/
+typedef struct {
+ char const *s; /**< Short VLAN name (primary key). */
+ char const *l; /**< Long VLAN name (description). */
+ dk3_sto_t *s_nw; /**< Storage for networks. */
+ dk3_sto_it_t *i_nw; /**< Iterator through networks storage. */
+ dk3_sto_t *s_do; /**< DHCP options for VLAN. */
+ dk3_sto_it_t *i_do; /**< Iterator through DHCP options. */
+} itadmin_vlan;
+
+
+
+/** Network connection socket.
+*/
+typedef struct {
+ char const *s; /**< Short name (label on socket, pk). */
+ char const *hp; /**< Hub port used for socket. */
+ char const *room; /**< Room name or number in building. */
+ itadmin_speed *sp; /**< Speed setting for socket. */
+ itadmin_vlan *vl; /**< VLAN for socket. */
+ itadmin_building *bu; /**< Building. */
+} itadmin_connect;
+
+
+
+/** Network.
+*/
+typedef struct {
+ itadmin_vlan *vl; /**< Parent VLAN. */
+ dk3_sto_t *s_p; /**< Storage for DHCP pools. */
+ dk3_sto_it_t *i_p; /**< Iterator through pools storage. */
+ dk3_sto_t *s_dg; /**< Storage for DHCP groups in network. */
+ dk3_sto_it_t *i_dg; /**< Iterator through groups in nw storage. */
+ dk3_sto_t *s_do; /**< DHCP options. */
+ dk3_sto_it_t *i_do; /**< Iterator for DHCP options. */
+ dk3_sto_t *s_hoi; /**< Storage for hosts. */
+ dk3_sto_it_t *i_hoi; /**< Iterator for hosts storage. */
+ dk3_sto_t *s_dc; /**< DHCP classes for this network. */
+ dk3_sto_it_t *i_dc; /**< Iterator through DHCP classes storage. */
+ unsigned long ip4; /**< IPv4 start address (primary key). */
+ unsigned long ma4; /**< IPv4 network mask. */
+ unsigned long gw4; /**< IPv4 gateway. */
+ unsigned long bc4; /**< IPv4 broadcast address. */
+} itadmin_network;
+
+
+
+/** Netgroup.
+*/
+typedef struct {
+ char const *sn; /**< Short name (primary key). */
+ char const *ln; /**< Long name (description). */
+ size_t no; /**< Netgroup number. */
+} itadmin_netgroup;
+
+
+
+/** Netgroup dependency.
+*/
+typedef struct {
+ itadmin_netgroup *pa; /**< Parent group. */
+ itadmin_netgroup *ch; /**< Child group. */
+} itadmin_ngdep;
+
+
+
+/** DHCP class.
+*/
+typedef struct {
+ char const *sn; /**< Short name (primary key). */
+ char const *ln; /**< Long name (description). */
+ dk3_sto_t *s_ho; /**< Hosts in this class. */
+ dk3_sto_it_t *i_ho; /**< Iterator through hosts storage. */
+ itadmin_network *dhcpn; /**< Network for DHCP hosts. */
+} itadmin_dhcp_class;
+
+
+
+/** DHCP address pool.
+*/
+typedef struct {
+ itadmin_network *nw; /**< Network. */
+ itadmin_dhcp_class *acl; /**< Allowed DHCP class. */
+ dk3_sto_t *s_do; /**< DHCP options for pool. */
+ dk3_sto_it_t *i_do; /**< Iterator for DHCP options. */
+ dk3_sto_t *s_hoi; /**< Hosts storage. */
+ dk3_sto_it_t *i_hoi; /**< Hosts storage iterator. */
+ unsigned long ip4s; /**< IPv4 start address. */
+ unsigned long ip4e; /**< IPv4 end address. */
+ char duc; /**< Flag: Deny unknown clients. */
+ char auc; /**< Flag: Allow unknown clients. */
+} itadmin_dhcp_pool;
+
+
+
+/** DHCP group.
+*/
+typedef struct {
+ char const *sn; /**< Short group name (primary key). */
+ char const *ln; /**< Long name (description). */
+ dk3_sto_t *s_do; /**< DHCP options storage. */
+ dk3_sto_it_t *i_do; /**< DHCP options iterator. */
+} itadmin_dhcp_group;
+
+
+
+/** DHCP group within a network.
+*/
+typedef struct {
+ itadmin_dhcp_group *gr; /**< Group. */
+ dk3_sto_t *s_h; /**< Storage for hosts in this group. */
+ dk3_sto_it_t *i_h; /**< Iterator for storage. */
+} itadmin_dhcp_ginw;
+
+
+
+/** Date (used for host expiration).
+*/
+typedef struct {
+ int y; /**< Year. */
+ int m; /**< Month. */
+ int d; /**< Day in month. */
+} itadmin_date;
+
+
+
+/** Host.
+*/
+typedef struct {
+ itadmin_date expi; /**< Expiration date. */
+ char const *sn; /**< Short host name (primary key). */
+ char const *co; /**< Comment, description. */
+ char const *maca; /**< MAC address. */
+ char const *room; /**< Room within the building. */
+ char const *inv; /**< Inventory ID. */
+ char const *serno; /**< Serial number. */
+ char const *hid; /**< Host ID. */
+ char const *dnsd; /**< DNS domain. */
+ itadmin_user *un; /**< System owner. */
+ itadmin_netgroup *ng; /**< Netgroup. */
+ itadmin_dhcp_class *dc; /**< DHCP class. */
+ itadmin_dhcp_group *dg; /**< DHCP group. */
+ itadmin_dhcp_pool *dp; /**< DHCP pool. */
+ itadmin_connect *nc; /**< Network connection socket. */
+ itadmin_building *bu; /**< Building. */
+ dk3_sto_t *s_al; /**< Storage for aliases. */
+ dk3_sto_it_t *i_al; /**< Iterator through aliases storage. */
+ dk3_sto_t *s_do; /**< DHCP options for host. */
+ dk3_sto_it_t *i_do; /**< DHCP options iterator. */
+ dk3_sto_t *s_li; /**< Licenses assigned to host. */
+ dk3_sto_it_t *i_li; /**< Iterator through licenses storage. */
+ unsigned long ipv4; /**< IPv4 address. */
+ char fnf; /**< Flag: Full name first in hosts. */
+ char fgu; /**< Flag: Guest computer. */
+ char snd; /**< Flag: Skip in network documentation. */
+ char saw; /**< Flag: Skip in arpwatch configuration. */
+} itadmin_host;
+
+
+
+/** Software manufacturer.
+*/
+typedef struct {
+ char const *sn; /**< Short name (primary key). */
+ char const *ln; /**< Full name. */
+} itadmin_swman;
+
+
+
+/** Software product.
+*/
+typedef struct {
+ char const *sn; /**< Short name (primary key). */
+ char const *ln; /**< Full name. */
+ itadmin_swman *mn; /**< Software manufacturer. */
+} itadmin_swprod;
+
+
+
+/** License type.
+*/
+typedef struct {
+ char const *sn; /**< Short name (primary key). */
+ char const *ln; /**< Full name. */
+ int num; /**< Number of client licenses. */
+} itadmin_lictype;
+
+
+
+/** Software license.
+*/
+typedef struct {
+ itadmin_date d_del; /**< Delivery date. */
+ itadmin_date d_inv; /**< Invoice date. */
+ char const *order; /**< Internal order ID. */
+ char const *notes; /**< Additional notes about the license. */
+ char const *i_del; /**< Delivery note ID. */
+ char const *i_inv; /**< Invoice ID. */
+ itadmin_swprod *prod; /**< Software product. */
+ itadmin_lictype *ltype; /**< License type. */
+ itadmin_user *owner; /**< License owner. */
+ itadmin_host *host; /**< Host where license is used. */
+ unsigned long pk; /**< Primary key from database. */
+} itadmin_license;
+
+
+
+/** DHCP option.
+*/
+typedef struct {
+ char const *k; /**< Key (option name). */
+ char const *v; /**< Option value. */
+ long pk; /**< Primary key from database. */
+} itadmin_dhcp_option;
+
+
+
+/** Job structure for the itadmin program.
+*/
+typedef struct {
+ itadmin_date today; /**< Current date. */
+ dk3_app_t *app; /**< Application structure. */
+ dk3_option_set_t *opt; /**< Option set. */
+ dk3_sto_t *s_us; /**< User storage. */
+ dk3_sto_it_t *i_us; /**< User storage iterator. */
+ dk3_sto_t *s_usn; /**< User sorted by name. */
+ dk3_sto_it_t *i_usn; /**< Storage iterator for users by name. */
+ dk3_sto_t *s_bu; /**< Building storage. */
+ dk3_sto_it_t *i_bu; /**< Building storage iterator. */
+ dk3_sto_t *s_sp; /**< Patch speed storage. */
+ dk3_sto_it_t *i_sp; /**< Patch speed storage iterator. */
+ dk3_sto_t *s_vl; /**< VLAN storage. */
+ dk3_sto_it_t *i_vl; /**< VLAN storage iterator. */
+ dk3_sto_t *s_pa; /**< Network patch storage. */
+ dk3_sto_it_t *i_pa; /**< Network patch storage iterator. */
+ dk3_sto_t *s_nw; /**< Network storage. */
+ dk3_sto_it_t *i_nw; /**< Network storage iterator. */
+ dk3_sto_t *s_ng; /**< Netgroup storage. */
+ dk3_sto_it_t *i_ng; /**< Netgroup storage iterator. */
+ dk3_sto_t *s_nd; /**< Netgroup dependency storage. */
+ dk3_sto_it_t *i_nd; /**< Netgroup dependency storage iterator. */
+ dk3_sto_t *s_dc; /**< DHCP class storage. */
+ dk3_sto_it_t *i_dc; /**< DHCP class storage iterator. */
+ dk3_sto_t *s_dp; /**< DHCP pool storage. */
+ dk3_sto_it_t *i_dp; /**< DHCP pool storage iterator. */
+ dk3_sto_t *s_dg; /**< DHCP group storage. */
+ dk3_sto_it_t *i_dg; /**< DHCP group storage iterator. */
+ dk3_sto_t *s_ho; /**< Host storage, sorted by name. */
+ dk3_sto_it_t *i_ho; /**< Host storage iterator for s_ho. */
+ dk3_sto_t *s_hoi; /**< Host storage, sorted by IP address. */
+ dk3_sto_it_t *i_hoi; /**< Host storage iterator for s_hoi. */
+ dk3_sto_t *s_sm; /**< Software manufacturer storage. */
+ dk3_sto_it_t *i_sm; /**< Software manufacturer storage iterator. */
+ dk3_sto_t *s_sw; /**< Software storage. */
+ dk3_sto_it_t *i_sw; /**< Software storage iterator. */
+ dk3_sto_t *s_lt; /**< License type storage. */
+ dk3_sto_it_t *i_lt; /**< License type storage iterator. */
+ dk3_sto_t *s_lc; /**< Licenses storage. */
+ dk3_sto_it_t *i_lc; /**< Licenses storage iterator. */
+ dk3_sto_t *s_lf; /**< Free licenses. */
+ dk3_sto_it_t *i_lf; /**< Free licenses iterator. */
+ dk3_sto_t *s_do; /**< DHCP options for entire server. */
+ dk3_sto_it_t *i_do; /**< Iterator for DHCP options. */
+ void *dbptr; /**< Database object pointer. */
+ dk3_bm_t *ngdep; /**< Direct/indirect netgroup dependencies. */
+ dk3_uc2lat_t *uc2l; /**< Unicode to LaTeX converter. */
+ dkChar const * const *msg; /**< Localized message texts. */
+ dkChar const * const *noloc; /**< Texts, not localized. */
+ dkChar const *dbhn; /**< Database host name. */
+ dkChar const *dbn; /**< Database name. */
+ dkChar const *dbcf; /**< Database credentials files. */
+ dkChar const *dbus; /**< Database user name. */
+ dkChar const *dbpw; /**< Database password. */
+ dkChar const *vlan; /**< VLAN name. */
+ dkChar const *org; /**< Organization name. */
+ dkChar const *ou; /**< Organizational unit name. */
+ dkChar const *admn; /**< Administrator name. */
+ dkChar const *ldapb; /**< LDAP base. */
+ size_t nng; /**< Number of netgroups. */
+ int exval; /**< Exit status code. */
+ int ec; /**< Error code, see @ref errorcodes. */
+ int cmd; /**< Command to execute. */
+ int f_dh; /**< Flag: Write dhcpd.conf file. */
+ int dbt; /**< Database type. */
+ int gdate; /**< Flag: German date notation. */
+ int hlh; /**< Flag: Have localhost entry. */
+ int ukoma; /**< Flag: Use koma-script. */
+ int rel; /**< Release lease on shutdown. */
+} itadmin_job;
+
+
+
+/** Reader structure for credentials file.
+*/
+typedef struct {
+ itadmin_job *job; /**< Job structure. */
+ int f_clnt; /**< Flag: In client section. */
+} itadmin_cred_reader;
+
+
+/** @defgroup itadmincommand Command IDs for itadmin. */
+/**@{*/
+/** itadmin command: Rebuild configuration and network documentation.
+*/
+#define ITADMIN_CMD_CONFIG 1
+
+/** itadmin command: Rebuild license report.
+*/
+#define ITADMIN_CMD_LICENSES 2
+
+/** itadmin command: show help text.
+*/
+#define ITADMIN_CMD_HELP 4
+
+/** itadmin command: show version information.
+*/
+#define ITADMIN_CMD_VERSION 8
+
+/** itadmin command: show license terms.
+*/
+#define ITADMIN_CMD_LICENSE_TERMS 16
+/**@}*/
+
+
+
+/** Maximum size for configuration file lines.
+*/
+#define ITADMIN_CONFIG_LINE_SIZE 256
+
+/** Function to remove one object.
+*/
+typedef void itadmin_obj_del(void *);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Read configuration file(s).
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_config_read(itadmin_job *job);
+
+/** Delete one user.
+ @param v Object to delete.
+*/
+void
+itadmin_mem_user_del(void *v);
+
+/** Delete one building.
+ @param v Object to delete.
+*/
+void
+itadmin_mem_building_del(void *v);
+
+/** Delete one speed setting.
+ @param v Object to delete.
+*/
+void
+itadmin_mem_speed_del(void *v);
+
+/** Delete one VLAN.
+ @param v Object to delete.
+*/
+void
+itadmin_mem_vlan_del(void *v);
+
+/** Delete one network connection patch.
+ @param v Object to delete.
+*/
+void
+itadmin_mem_connect_del(void *v);
+
+/** Delete one network.
+ @param v Object to delete.
+*/
+void
+itadmin_mem_network_del(void *v);
+
+/** Delete one netgroup.
+ @param v Object to delete.
+*/
+void
+itadmin_mem_netgroup_del(void *v);
+
+/** Delete one netgroup dependency.
+ @param v Object to delete.
+*/
+void
+itadmin_mem_ngdep_del(void *v);
+
+/** Delete one DHCP class.
+ @param v Object to delete.
+*/
+void
+itadmin_mem_dhcp_class_del(void *v);
+
+/** Delete one DHCP pool.
+ @param v Object to delete.
+*/
+void
+itadmin_mem_dhcp_pool_del(void *v);
+
+/** Delete one DHCP group.
+ @param v Object to delete.
+*/
+void
+itadmin_mem_dhcp_group_del(void *v);
+
+/** Delete one host.
+ @param v Object to delete.
+*/
+void
+itadmin_mem_host_del(void *v);
+
+/** Delete one software manufacturer.
+ @param v Object to delete.
+*/
+void
+itadmin_mem_sw_man_del(void *v);
+
+/** Delete one software product.
+ @param v Object to delete.
+*/
+void
+itadmin_mem_software_del(void *v);
+
+/** Delete one license type.
+ @param v Object to delete.
+*/
+void
+itadmin_mem_lic_type_del(void *v);
+
+/** Delete one license.
+ @param v Object to delete.
+*/
+void
+itadmin_mem_license_del(void *v);
+
+/** Create new user.
+ @param job Job structure.
+ @param un Name.
+ @param tt Academic degree or title (may be NULL).
+ @param sn Surname (may be NULL).
+ @param na Name.
+ @param em E-Mail (may be NULL).
+ @param cc Cost control ID (may be NULL).
+ @param si Staff ID number (may be NULL).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_user *
+itadmin_mem_user_new(
+ itadmin_job *job,
+ char const *un,
+ char const *tt,
+ char const *sn,
+ char const *na,
+ char const *em,
+ char const *cc,
+ char const *si
+);
+
+/** Create new building.
+ @param job Job structure.
+ @param s Name.
+ @param l Long name (may be NULL).
+ @param a1 Address line 1 (typically street and number,
+ may be NULL).
+ @param a2 Address line 2 (may be NULL).
+ @param a3 Address line 3 (may be NULL).
+ @param a4 Address line 4 (may be NULL).
+ @param zc Zip code (may be NULL).
+ @param city Town or city name (may be NULL).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_building *
+itadmin_mem_building_new(
+ itadmin_job *job,
+ char const *s,
+ char const *l,
+ char const *a1,
+ char const *a2,
+ char const *a3,
+ char const *a4,
+ char const *zc,
+ char const *city
+);
+
+/** Create new speed setting.
+ @param job Job structure.
+ @param s Name.
+ @param n Description (may be NULL).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_speed *
+itadmin_mem_speed_new(
+ itadmin_job *job,
+ char const *s,
+ char const *n
+);
+
+/** Create new VLAN.
+ @param job Job structure.
+ @param s Name.
+ @param l Long name (may be NULL).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_vlan *
+itadmin_mem_vlan_new(
+ itadmin_job *job,
+ char const *s,
+ char const *l
+);
+
+/** Create new network connector.
+ @param job Job structure.
+ @param s Name.
+ @param hp Building.
+ @param room Room.
+ @param sp Speed setting.
+ @param vl VLAN.
+ @param bu Building.
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_connect *
+itadmin_mem_connect_new(
+ itadmin_job *job,
+ char const *s,
+ char const *hp,
+ char const *room,
+ itadmin_speed *sp,
+ itadmin_vlan *vl,
+ itadmin_building *bu
+);
+
+/** Create new network.
+ @param job Job structure.
+ @param ip4 Network address.
+ @param ma4 Network mask.
+ @param gw4 Gateway.
+ @param bc4 Broadcast address.
+ @param vl VLAN.
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_network *
+itadmin_mem_network_new(
+ itadmin_job *job,
+ unsigned long ip4,
+ unsigned long ma4,
+ unsigned long gw4,
+ unsigned long bc4,
+ itadmin_vlan *vl
+);
+
+/** Create new netgroup.
+ @param job Job structure.
+ @param sn Short name.
+ @param ln Long name (may be NULL).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_netgroup *
+itadmin_mem_netgroup_new(
+ itadmin_job *job,
+ char const *sn,
+ char const *ln
+);
+
+/** Create new netgroup dependency.
+ @param job Job structure.
+ @param pa Parent group.
+ @param ch Child group.
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_ngdep *
+itadmin_mem_ngdep_new(
+ itadmin_job *job,
+ itadmin_netgroup *pa,
+ itadmin_netgroup *ch
+);
+
+/** Create new DHCP class.
+ @param job Job structure.
+ @param sn Short name.
+ @param ln Long name (may be NULL).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_dhcp_class *
+itadmin_mem_dhcp_class_new(
+ itadmin_job *job,
+ char const *sn,
+ char const *ln
+);
+
+/** Create new DHCP pool.
+ @param job Job structure.
+ @param nw Network.
+ @param cn Allowed class (if unknown clients are denied,
+ may be NULL).
+ @param ip4s IPv4 start address.
+ @param ip4e IPv4 end address.
+ @param duc Flag: Deny unknown clients (needs cn).
+ @param auc Flag: Allow unknown clients.
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_dhcp_pool *
+itadmin_mem_dhcp_pool_new(
+ itadmin_job *job,
+ itadmin_network *nw,
+ itadmin_dhcp_class *cn,
+ unsigned long ip4s,
+ unsigned long ip4e,
+ int duc,
+ int auc
+);
+
+/** Create new DHCP group.
+ @param job Job structure.
+ @param sn Short name.
+ @param ln Long name (may be NULL).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_dhcp_group *
+itadmin_mem_dhcp_group_new(
+ itadmin_job *job,
+ char const *sn,
+ char const *ln
+);
+
+/** Create new host
+ @param job Job structure.
+ @param sn Short name.
+ @param co Comment/description (may be NULL).
+ @param maca MAC address (may be NULL).
+ @param room Room (may be NULL).
+ @param inv Inventory number (may be NULL).
+ @param serno Serial number (may be NULL).
+ @param hid Host ID (may be NULL).
+ @param expi Expiration date (may be NULL).
+ @param dnsd DNS domain (may be NULL).
+ @param un System owner.
+ @param ng Netgroup (may be NULL).
+ @param dc DHCP class (may be NULL).
+ @param dg DHCP group (may be NULL).
+ @param nc Network connection socket (may be NULL).
+ @param bu Building (may be NULL).
+ @param ipv4 IPv4 address (may be NULL).
+ @param fnf Flag: FQDN first in hosts file.
+ @param fgu Flag: Guest computer (bring your own device).
+ @param snd Flag: Skip in network documentation.
+ @param saw Flag: Skip in arpwatch configuration.
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_host *
+itadmin_mem_host_new(
+ itadmin_job *job,
+ itadmin_date *expi,
+ char const *sn,
+ char const *co,
+ char const *maca,
+ char const *room,
+ char const *inv,
+ char const *serno,
+ char const *hid,
+ char const *dnsd,
+ itadmin_user *un,
+ itadmin_netgroup *ng,
+ itadmin_dhcp_class *dc,
+ itadmin_dhcp_group *dg,
+ itadmin_connect *nc,
+ itadmin_building *bu,
+ unsigned long ipv4,
+ int fnf,
+ int fgu,
+ int snd,
+ int saw
+);
+
+/** Create new software manufacturer.
+ @param job Job structure.
+ @param sn Short name.
+ @param ln Long name (description).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_swman *
+itadmin_mem_sw_man_new(
+ itadmin_job *job,
+ char const *sn,
+ char const *ln
+);
+
+/** Create new software product.
+ @param job Job structure.
+ @param sn Short name.
+ @param ln Long name.
+ @param mn Software manufacturer name (may be NULL).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_swprod *
+itadmin_mem_swprod_new(
+ itadmin_job *job,
+ char const *sn,
+ char const *ln,
+ itadmin_swman *mn
+);
+
+/** Create new license type.
+ @param job Job structure.
+ @param sn Short license type name.
+ @param ln Long name (description).
+ @param num Number of client licenses for floating license servers.
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_lictype *
+itadmin_mem_lictype_new(
+ itadmin_job *job,
+ char const *sn,
+ char const *ln,
+ int num
+);
+
+/** Create new license.
+ @param job Job structure.
+ @param pk Primary key from licenses table (unused).
+ @param order Order ID or tracking information (may be NULL).
+ @param notes Additional notes (may be NULL).
+ @param d_del Delivery date (may be NULL).
+ @param i_del Delivery note ID (may be NULL).
+ @param d_inv Invoice date (may be NULL).
+ @param i_inv Invoice ID (may be NULL).
+ @param prod Software product.
+ @param ltype License type.
+ @param owner License owner (may be NULL).
+ @param host Computer (may be NULL).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_license *
+itadmin_mem_license_new(
+ itadmin_job *job,
+ unsigned long pk,
+ char const *order,
+ char const *notes,
+ itadmin_date *d_del,
+ char const *i_del,
+ itadmin_date *d_inv,
+ char const *i_inv,
+ itadmin_swprod *prod,
+ itadmin_lictype *ltype,
+ itadmin_user *owner,
+ itadmin_host *host
+);
+
+/** Create new DHCP group in network.
+ @param job Job structure.
+ @param gr DHCP group structure.
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_dhcp_ginw *
+itadmin_mem_dhcp_ginw_new(itadmin_job *job, itadmin_dhcp_group *gr);
+
+/** Destroy DHCP group in network structure, release memory.
+ @param g Group structure to destroy.
+*/
+void
+itadmin_mem_dhcp_ginw_del(itadmin_dhcp_ginw *g);
+
+/** Initialize date structure.
+ @param dp Date pointer.
+*/
+void
+itadmin_mem_date_init(itadmin_date *dp);
+
+/** Copy date structure.
+ @param dp Destination pointer.
+ @param sp Source pointer.
+*/
+void
+itadmin_mem_date_copy(itadmin_date *dp, itadmin_date *sp);
+
+/** Create a DHCP option structure.
+ @param job Job structure.
+ @param k Key (option name).
+ @param v Option value.
+ @param pk Primary key number from table (unused).
+ @return Valid pointer to new object on success, NULL on error.
+*/
+itadmin_dhcp_option *
+itadmin_mem_dhcp_option_new(
+ itadmin_job *job,
+ char const *k,
+ char const *v,
+ long pk
+);
+
+/** Destroy DHCP option structure, release memory.
+ @param v Option to destroy.
+*/
+void
+itadmin_mem_dhcp_option_del(void *v);
+
+/** Read data from database.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_data_read(itadmin_job *job);
+
+/** Read data from MySQL database.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_data_mysql_read(itadmin_job *job);
+
+/** Register a user record.
+ @param job Job structure.
+ @param us_s User short name (login name).
+ @param us_t User title or academic degree.
+ @param us_sn Surname.
+ @param us_fn Family name.
+ @param us_em E-Mail.
+ @param us_ko Cost control ID.
+ @param us_se Organizational unit.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_register_user(
+ itadmin_job *job,
+ char const *us_s,
+ char const *us_t,
+ char const *us_sn,
+ char const *us_fn,
+ char const *us_em,
+ char const *us_ko,
+ char const *us_se
+);
+
+/** Register building.
+ @param job Job structure.
+ @param gb_s Short building name.
+ @param gb_l Long building name.
+ @param gb_a1 Address line 1.
+ @param gb_a2 Address line 2.
+ @param gb_a3 Address line 3.
+ @param gb_a4 Address line 4.
+ @param gb_plz Zip code.
+ @param gb_ort City name.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_register_building(
+ itadmin_job *job,
+ char const *gb_s,
+ char const *gb_l,
+ char const *gb_a1,
+ char const *gb_a2,
+ char const *gb_a3,
+ char const *gb_a4,
+ char const *gb_plz,
+ char const *gb_ort
+);
+
+/** Register a speed setting.
+ @param job Job structure.
+ @param sn Short name for setting.
+ @param ln Description.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_register_speed(
+ itadmin_job *job,
+ char const *sn,
+ char const *ln
+);
+
+/** Register a VLAN.
+ @param job Job structure.
+ @param vl_s Short name for VLAN.
+ @param vl_l Description.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_register_vlan(itadmin_job *job, char const *vl_s, char const *vl_l);
+
+/** Register patch (ethernet socket).
+ @param job Job structure.
+ @param dd_n Patch name.
+ @param sp_s Speed setting name.
+ @param vl_s VLAN short name.
+ @param dd_p Hub port name.
+ @param gb_s Building.
+ @param dd_r Room number/name of patch.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_register_patch(
+ itadmin_job *job,
+ char const *dd_n,
+ char const *sp_s,
+ char const *vl_s,
+ char const *dd_p,
+ char const *gb_s,
+ char const *dd_r
+);
+
+/** Register network.
+ @param job Job structure.
+ @param nw_ip IP address.
+ @param nw_ma Network mask.
+ @param nw_gw Gateway.
+ @param nw_bc Broadcast address.
+ @param vl_s VLAN for network.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_register_network(
+ itadmin_job *job,
+ char const *nw_ip,
+ char const *nw_ma,
+ char const *nw_gw,
+ char const *nw_bc,
+ char const *vl_s
+);
+
+/** Register DHCP pool.
+ @param job Job structure.
+ @param ips IP start address of pool.
+ @param ipe IP end address of pool.
+ @param nw Network address (may be NULL or empty).
+ @param alu Flag: Allow unknown clients.
+ @param dnu Flag: Deny unknown clients.
+ @param dcn Allowed class name if unknown clients denied.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_register_dhcp_pool(
+ itadmin_job *job,
+ char const *ips,
+ char const *ipe,
+ char const *nw,
+ int alu,
+ int dnu,
+ char const *dcn
+);
+
+/** Register DHCP class.
+ @param job Job structure.
+ @param dcs Short class name.
+ @param dcl Long class name (description).
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_register_dhcp_class(itadmin_job *job,char const *dcs,char const *dcl);
+
+/** Register DHCP group.
+ @param job Job structure.
+ @param sn Short name.
+ @param ln Long name (description).
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_register_dhcp_group(itadmin_job *job, char const *sn, char const *ln);
+
+/** Register netgroup.
+ @param job Job structure.
+ @param ng_s Short netgroup name.
+ @param ng_l Long name (description).
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_register_netgroup(itadmin_job *job,char const *ng_s,char const *ng_l);
+
+/** Register netgroup dependency.
+ @param job Job structure.
+ @param pgn Name of the parent group.
+ @param cgn Name of the child group.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_register_ngdep(itadmin_job *job, char const *pgn, char const *cgn);
+
+/** Register one host.
+ @param job Job structure.
+ @param co_s Short name for computer.
+ @param us_s Owner / user in charge.
+ @param co_ip IPv4 address.
+ @param co_mc MAC address.
+ @param ng_s Netgroup.
+ @param co_co Comment for PC.
+ @param dc_s DHCP class.
+ @param dg_s DHCP group.
+ @param dd_n Patch/connector number.
+ @param gb_s Building.
+ @param co_r Room number.
+ @param co_in Inventory ID.
+ @param co_sn Serial number.
+ @param co_dd DNS domain name.
+ @param co_ff Flag: Write FQDN first in /etc/hosts.
+ @param co_gu Flag: BYOD (bring your own device).
+ @param co_hi Host ID.
+ @param co_ex Expiration date.
+ @param co_nn Flag: Skip host in network documentation.
+ @param co_na Flag: Skip host for arpwatch.
+*/
+
+int
+itadmin_register_host(
+ itadmin_job *job,
+ char const *co_s,
+ char const *us_s,
+ char const *co_ip,
+ char const *co_mc,
+ char const *ng_s,
+ char const *co_co,
+ char const *dc_s,
+ char const *dg_s,
+ char const *dd_n,
+ char const *gb_s,
+ char const *co_r,
+ char const *co_in,
+ char const *co_sn,
+ char const *co_dd,
+ int co_ff,
+ int co_gu,
+ char const *co_hi,
+ itadmin_date *co_ex,
+ int co_nn,
+ int co_na
+);
+
+/** Register host name alias.
+ @param job Job structure.
+ @param al Alias name.
+ @param rn Real host name.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_register_alias(itadmin_job *job, char const *al, char const *rn);
+
+/** Register a DHCP option.
+ @param job Job structure.
+ @param sct Scope type name.
+ @param scn Scope name.
+ @param k Key (option name).
+ @param v Option value.
+ @param pk Primary key from database.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_register_dhcp_option(
+ itadmin_job *job,
+ char const *sct,
+ char const *scn,
+ char const *k,
+ char const *v,
+ long pk
+);
+
+/** Check name for empty string or minus.
+ We have to save the entry if the string pointer is not
+ NULL and the string is not empty and not a minus.
+ @param sn String to check.
+ @return 1 if string must be saved, 0 for ignore.
+*/
+int
+itadmin_register_check_user_name(char const *sn);
+
+/** Check whether we can attempt to convert a string to an IP address.
+ @param ip String to test.
+ @return 1 for string with text, 0 for empty string.
+*/
+int
+itadmin_register_check_ip(char const *ip);
+
+/** Register a software manufacturer.
+ @param job Job structure.
+ @param sm_s Short name.
+ @param sm_l Long name.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_register_swman( itadmin_job *job, char const *sm_s, char const *sm_l);
+
+/** Register a software product.
+ @param job Job structure.
+ @param sw_s Short software name.
+ @param sw_l Long software name.
+ @param sm_s Software manufacturer.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_register_swprod(
+ itadmin_job *job,
+ char const *sw_s,
+ char const *sw_l,
+ char const *sm_s
+);
+/** Register a license type.
+ @param job Job structure.
+ @param lt_s Short license type name.
+ @param lt_l Long name/description of license type.
+ @param nl Number of licenses (for floating licenses).
+*/
+int
+itadmin_register_lictype(
+ itadmin_job *job,
+ char const *lt_s,
+ char const *lt_l,
+ int nl
+);
+
+/** Register license.
+ @param job Job structure.
+ @param pk Primary key.
+ @param li_on Order number (purchase process ID).
+ @param sw_s Software short name.
+ @param us_s User to which the license is assigned.
+ @param co_s Computer on which the license is used.
+ @param lt_s License type.
+ @param li_no Optional note for the license.
+ @param sr_s Software reseller.
+ @param li_dd Delivery date.
+ @param li_nd Delivery note number.
+ @param li_di Invoide date.
+ @param li_ni Invoice number.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_register_license(
+ itadmin_job *job,
+ unsigned long pk,
+ char const *li_on,
+ char const *sw_s,
+ char const *us_s,
+ char const *co_s,
+ char const *lt_s,
+ char const *li_no,
+ char const *sr_s,
+ itadmin_date *li_dd,
+ char const *li_nd,
+ itadmin_date *li_di,
+ char const *li_ni
+);
+
+/** Compare structures for user.
+ @param l Left structure.
+ @param r Right structure, object, or name.
+ @param cr Comparison criteria
+ (0=user/user by us, 1=user/name by us, 2=user/user by na+sn+tt+us).
+ @return Comparison result.
+*/
+int
+itadmin_comp_user(void const *l, void const *r, int cr);
+
+/** Compare structures for buildings.
+ @param l Left structure.
+ @param r Right structure, object, or name.
+ @param cr Comparison criteria
+ (0=building/building by s, 1=building/name by s).
+ @return Comparison result.
+*/
+int
+itadmin_comp_building(void const *l, void const *r, int cr);
+
+/** Compare structures for network speed.
+ @param l Left structure.
+ @param r Right structure, object, or name.
+ @param cr Comparison criteria
+ (0=speed/speed by s, 1=speed/name).
+ @return Comparison result.
+*/
+int
+itadmin_comp_speed(void const *l, void const *r, int cr);
+
+/** Compare structures for VLAN.
+ @param l Left structure.
+ @param r Right structure, object, or name.
+ @param cr Comparison criteria
+ (0=vlan/vlan by s, 1=vlan/name by s).
+ @return Comparison result.
+*/
+int
+itadmin_comp_vlan(void const *l, void const *r, int cr);
+
+/** Compare structures for ethernet socket.
+ @param l Left structure.
+ @param r Right structure, object, or name.
+ @param cr Comparison criteria
+ (0=socket/socket by s, 1=socket/name).
+ @return Comparison result.
+*/
+int
+itadmin_comp_connect(void const *l, void const *r, int cr);
+
+/** Compare structures for network.
+ @param l Left structure.
+ @param r Right structure, object, or name.
+ @param cr Comparison criteria
+ (0=network/network by ip4, 1=network/ipaddress).
+ @return Comparison result.
+*/
+int
+itadmin_comp_network(void const *l, void const *r, int cr);
+
+/** Compare structures for netgroup.
+ @param l Left structure.
+ @param r Right structure, object, or name.
+ @param cr Comparison criteria
+ (0=netgroup/netgroup by sn, 1=netgroup/name by sn).
+ @return Comparison result.
+*/
+int
+itadmin_comp_netgroup(void const *l, void const *r, int cr);
+
+/** Compare structures for DHCP class.
+ @param l Left structure.
+ @param r Right structure, object, or name.
+ @param cr Comparison criteria
+ (0=class/class by sn, 1=class/name by sn).
+ @return Comparison result.
+*/
+int
+itadmin_comp_dhcp_class(void const *l, void const *r, int cr);
+
+/** Compare structures for DHCP pool.
+ @param l Left structure.
+ @param r Right structure, object, or name.
+ @param cr Comparison criteria
+ (0=pool/pool by ip4s, 1=pool/ipaddress).
+ @return Comparison result.
+*/
+int
+itadmin_comp_dhcp_pool(void const *l, void const *r, int cr);
+
+/** Compare structures for DHCP group.
+ @param l Left structure.
+ @param r Right structure, object, or name.
+ @param cr Comparison criteria
+ (0=group/group by sn, 1=group/name).
+ @return Comparison result.
+*/
+int
+itadmin_comp_dhcp_group(void const *l, void const *r, int cr);
+
+/** Compare structures for host
+ @param l Left structure.
+ @param r Right structure, object, or name.
+ @param cr Comparison criteria
+ (0=host/host by sn, 1=host/name, 2=host/host by ipv4, 3=host/ipaddr).
+ @return Comparison result.
+*/
+int
+itadmin_comp_host(void const *l, void const *r, int cr);
+
+/** Compare structures for software manufacturer.
+ @param l Left structure.
+ @param r Right structure, object, or name.
+ @param cr Comparison criteria
+ (0=swman/swman by sn, 1=swman/name).
+ @return Comparison result.
+*/
+int
+itadmin_comp_swman(void const *l, void const *r, int cr);
+
+/** Compare structures for software product.
+ @param l Left structure.
+ @param r Right structure, object, or name.
+ @param cr Comparison criteria
+ (0=product/product by sn, 1=product/name,
+ 2=product/product by mn->ln+ln).
+ @return Comparison result.
+*/
+int
+itadmin_comp_swprod(void const *l, void const *r, int cr);
+
+/** Compare structures for license type.
+ @param l Left structure.
+ @param r Right structure, object, or name.
+ @param cr Comparison criteria
+ (0=type/type by sn, 1=type/name).
+ @return Comparison result.
+*/
+int
+itadmin_comp_user(void const *l, void const *r, int cr);
+
+/** Compare structures for license type.
+ @param l Left structure.
+ @param r Right structure, object, or name.
+ @param cr Comparison criteria
+ (0=license/license by product).
+ @return Comparison result.
+*/
+int
+itadmin_comp_lictype(void const *l, void const *r, int cr);
+
+/** Compare structures for license.
+ @param l Left structure.
+ @param r Right structure, object, or name.
+ @param cr Comparison criteria
+ (0=license/license by pk, 1=license/pk, 2=license/license by product).
+ @return Comparison result.
+*/
+int
+itadmin_comp_license(void const *l, void const *r, int cr);
+
+/** Compare two licenses within a network.
+ @param l Left object.
+ @param r Right object or name.
+ @param cr Comparison criteria (0=group/group,
+ 1=group/name).
+ @return Comparison result.
+*/
+int
+itadmin_comp_dhcp_ginw(void const *l, void const *r, int cr);
+
+/** Compare two date structures.
+ @param l Left object.
+ @param r Right object.
+ @return 1 if @arg l is later than @arg r, 0 for equal days,
+ 1 if @arg l is earlier than @arg r.
+*/
+int
+itadmin_comp_date(itadmin_date const *l, itadmin_date const *r);
+
+/** Compare two DHCP options.
+ @param l Left object.
+ @param r Right object.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+int
+itadmin_comp_dhcp_option(void const *l, void const *r, int cr);
+
+/** Compare two strings.
+ @param l Left string.
+ @param r Right string.
+ @param cr Comparison criteria (1=case-insensitive, 0=normal).
+ @return Comparison result.
+*/
+int
+itadmin_comp_string(void const *l, void const *r, int cr);
+
+/** Check whether we have to write network configuration
+ and documentation.
+ @param job Job structure.
+ @return 1 for yes, 0 for no.
+*/
+int
+itadmin_job_do_network(itadmin_job *job);
+
+/** Check whether we have to write a dhcpd.conf file.
+ @param job Job structure.
+ @return 1 for yes, 0 for no.
+*/
+int
+itadmin_job_do_dhcp(itadmin_job *job);
+
+/** Check whether we have to write a license report.
+ @param job Job structure.
+ @return 1 for yes, 0 for no.
+*/
+int
+itadmin_job_do_licenses(itadmin_job *job);
+
+/** Convert string yyyy-mm-dd to date structure.
+ @param job Job structure.
+ @param dp Destination pointer.
+ @param str Source text.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_tool_convert_date(itadmin_job *job, itadmin_date *dp, char const *str);
+
+/** Write IPv4 address to file.
+ @param df Destination file.
+ @param ipv4 Address to write.
+*/
+void
+itadmin_tool_write_ip(FILE *df, unsigned long ipv4);
+
+/** Write IPv4 address to stream.
+ @param os Output stream.
+ @param ipv4 Address to write.
+*/
+void
+itadmin_tool_stream_ip(dk3_stream_t *os, unsigned long ipv4);
+
+/** Write user name short to LaTeX output.
+ @param job Job structure.
+ @param os Output stream.
+ @param user User to write.
+*/
+void
+itadmin_tool_write_user_latex_short(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ itadmin_user *user
+);
+
+/** Write user name long to LaTeX output.
+ @param job Job structure.
+ @param os Output stream.
+ @param user User to write.
+*/
+void
+itadmin_tool_write_user_latex_long(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ itadmin_user *user
+);
+
+/** Write the section header in the table.
+ @param job Job structure.
+ @param os Output stream.
+ @param kwi Keyword index.
+*/
+void
+itadmin_tool_table_section_header(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ size_t kwi
+);
+
+/** Start a table line.
+ @param job Job structure.
+ @param os Output stream.
+ @param kwi Keyword index in localized messages.
+*/
+void
+itadmin_tool_table_line_start(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ size_t kwi
+);
+
+/** Separate two items in a table.
+ @param job Job structure.
+ @param os Output stream.
+*/
+void
+itadmin_tool_table_line_sep_rows(
+ itadmin_job *job,
+ dk3_stream_t *os
+);
+
+/** Finish a table line.
+ @param job Job structure.
+ @param os Output stream.
+ @param pb Flag: Allow page break here.
+*/
+void
+itadmin_tool_table_line_finish(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ int pb
+);
+
+/** Create empty table field.
+ @param job Job structure.
+ @param os Output stream.
+ @param nu Flag: Write notification for missing value.
+*/
+void
+itadmin_tool_table_line_no_data(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ int nu
+);
+
+/** Write one detail table line.
+ @param job Job structure.
+ @param os Output stream.
+ @param kwi Keyword index for option name.
+ @param det Details to write.
+ @param nu Flag: Write a note about unknown values.
+ @param pb Flag: Allow page break after line.
+*/
+void
+itadmin_tool_table_line(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ size_t kwi,
+ char const *det,
+ int nu,
+ int pb
+);
+
+/** Write a table line consisting of two values.
+ @param job Job structure.
+ @param os Output stream.
+ @param key Key.
+ @param val Value.
+ @param fb Flag: Key in bold.
+ @param pb Flag: Allow page break.
+*/
+void
+itadmin_tool_table_values(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ char const *key,
+ char const *val,
+ int fb,
+ int pb
+);
+
+/** Check whether a host is owned by a user.
+ @param us User.
+ @param co Host.
+ @return 1 if the host is owned by the user, 0 otherwise.
+*/
+int
+itadmin_tool_check_same_user(itadmin_user *us, itadmin_host *co);
+
+/** Write a section of text to output stream.
+ @param job Job structure.
+ @param os Output stream.
+ @param sect Text section to write.
+*/
+void
+itadmin_tool_write_section(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ char const * const *sect
+);
+
+/** Write log message of one part.
+ @param job Job structure.
+ @param ll Log level.
+ @param i Index of message text in localized messages array.
+*/
+void
+itadmin_tool_log_1(
+ itadmin_job *job,
+ int ll,
+ size_t i
+);
+
+/** Write log message of three parts.
+ @param job Job structure.
+ @param ll Log level.
+ @param i1 Index of first message text in localized messages array.
+ @param i2 Index of third text part in localized messages array.
+ @param msg Variable message text, second text part.
+*/
+void
+itadmin_tool_log_utf8_3(
+ itadmin_job *job,
+ int ll,
+ size_t i1,
+ size_t i2,
+ char const *msg
+);
+
+/** Write log message of five parts.
+ @param job Job structure.
+ @param ll Log level.
+ @param i1 Index of first message text in localized messages array.
+ @param i2 Index of third text part in localized messages array.
+ @param i3 Index of fifth text part in localized messages array.
+ @param msg1 First variable message text, second text part.
+ @param msg2 Second variable messagetext, fourth text part.
+*/
+void
+itadmin_tool_log_utf8_5(
+ itadmin_job *job,
+ int ll,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ char const *msg1,
+ char const *msg2
+);
+
+/** Write log message of three parts.
+ @param job Job structure.
+ @param ll Log level.
+ @param i1 Index of first constant message part.
+ @param i2 Index of third message part.
+ @param pk Primary key as numeric value.
+*/
+void
+itadmin_tool_log_pk_3(
+ itadmin_job *job,
+ int ll,
+ size_t i1,
+ size_t i2,
+ unsigned long pk
+);
+
+/** Write log message of five parts.
+ @param job Job structure.
+ @param ll Log level.
+ @param i1 Index of first constant message part.
+ @param i2 Index of third message part.
+ @param i3 Index of fifth message part.
+ @param pk Primary key as numeric value.
+ @param msg Variable message part.
+*/
+void
+itadmin_tool_log_pk_5(
+ itadmin_job *job,
+ int ll,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ unsigned long pk,
+ char const *msg
+);
+
+/** Write IPv4 address to buffer.
+ @param bu Destination buffer, at least 16 bytes long.
+ @param ip IP address.
+*/
+void
+itadmin_tool_ip_to_buffer(char *bu, unsigned long ip);
+
+/** Write hosts file.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_hosts_output(itadmin_job *job);
+
+/** Write hosts.ldif file.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_hosts_ldif_output(itadmin_job *job);
+
+/** Write ethers-by-ip and ethers-by-mac files.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_ethers_output(itadmin_job *job);
+
+/** Write ethers.ldif file.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_ethers_ldif_output(itadmin_job *job);
+
+/** Expand netgroup dependencies.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_netgroup_expand(itadmin_job *job);
+
+/** Check whether a host is a member of a netgroup.
+ @param job Job structure.
+ @param netgroup Netgroup.
+ @param host Host.
+ @return 0 for no member, 1 for indirect member, 2 for direct member.
+*/
+int
+itadmin_netgroup_host_member(
+ itadmin_job *job,
+ itadmin_netgroup *netgroup,
+ itadmin_host *host
+);
+
+/** Write netgroup.ldif file.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_netgroup_ldif_output(itadmin_job *job);
+
+/** Write dhcpd.conf file.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_dhcpd_conf_output(itadmin_job *job);
+
+/** Write network documentation file.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_netdocu(itadmin_job *job);
+
+/** Write license report.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+int
+itadmin_license_report(itadmin_job *job);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/support/dktools/itadmin.rc b/support/dktools/itadmin.rc
new file mode 100644
index 0000000000..5071926b1f
--- /dev/null
+++ b/support/dktools/itadmin.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "IT management using a MySQL DB\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "IT management using a MySQL DB\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "itadmin\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/itaether.c b/support/dktools/itaether.c
new file mode 100644
index 0000000000..3671cca3e2
--- /dev/null
+++ b/support/dktools/itaether.c
@@ -0,0 +1,229 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: itaether.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file itaether.c The itaether module.
+*/
+
+
+#line 11 "itaether.ctr"
+
+
+#include "dk3all.h"
+#include "itadmin.h"
+
+
+
+
+
+#line 19 "itaether.ctr"
+
+
+
+/** Keywords used by the module.
+*/
+static char const * const itadmin_ethers_c8_kw[] = {
+/* 0 */
+"\n",
+
+/* 1 */
+"w",
+
+/* 2 */
+"ethers-by-ip",
+
+/* 3 */
+"ethers-by-mac",
+
+/* 4 */
+"ethers.ldif",
+
+/* 5 */
+"dn: cn=",
+
+/* 6 */
+",ou=ethers,",
+
+/* 7 */
+"objectClass: ieee802Device",
+
+/* 8 */
+"objectClass: device",
+
+/* 9 */
+"objectClass: top",
+
+/* 10 */
+"cn: ",
+
+/* 11 */
+"macAddress: ",
+
+NULL
+
+
+#line 75 "itaether.ctr"
+};
+
+
+
+
+int
+itadmin_ethers_output(itadmin_job *job)
+{
+ itadmin_host *host;
+ FILE *f1;
+ FILE *f2;
+ int back = 0;
+
+
+#line 88 "itaether.ctr"
+ f1 = dk3sf_c8_fopen_app(
+ itadmin_ethers_c8_kw[2],
+ itadmin_ethers_c8_kw[1],
+ job->app
+ );
+ if(f1) {
+ f2 = dk3sf_c8_fopen_app(
+ itadmin_ethers_c8_kw[3],
+ itadmin_ethers_c8_kw[1],
+ job->app
+ );
+ if(f2) {
+ back = 1;
+ dk3sto_it_reset(job->i_hoi);
+ while(NULL != (host = (itadmin_host *)dk3sto_it_next(job->i_hoi))) {
+ if((host->ipv4) && (host->sn) && (host->maca)) {
+ itadmin_tool_write_ip(f1, host->ipv4);
+ fputc('\t', f1);
+ fputs(host->maca, f1);
+ fputc('\n', f1);
+ fputs(host->maca, f2);
+ fputc('\t', f2);
+ itadmin_tool_write_ip(f2, host->ipv4);
+ fputc('\n', f2);
+ }
+ }
+#if DK3_CHAR_SIZE == 1
+ if(!dk3sf_fclose_fn_app(f2, itadmin_ethers_c8_kw[3], job->app)) {
+ back = 0;
+ }
+#else
+ if(!dk3sf_fclose_fn_app(f2, NULL, job->app)) {
+ back = 0;
+ }
+#endif
+ } else {
+ }
+#if DK3_CHAR_SIZE == 1
+ if(!dk3sf_fclose_fn_app(f1, itadmin_ethers_c8_kw[2], job->app)) {
+ back = 0;
+ }
+#else
+ if(!dk3sf_fclose_fn_app(f1, NULL, job->app)) {
+ back = 0;
+ }
+#endif
+ } else {
+ }
+
+
+#line 137 "itaether.ctr"
+ return back;
+}
+
+
+
+int
+itadmin_ethers_ldif_output(itadmin_job *job)
+{
+ char bu[ITADMIN_CONFIG_LINE_SIZE];
+ itadmin_host *host;
+ FILE *fipo;
+ int ie;
+ int back = 0;
+
+
+#line 151 "itaether.ctr"
+ ie = dk3app_get_encoding(job->app);
+ if(dk3str_to_c8u_app(bu,sizeof(bu),job->ldapb,ie,job->app)) {
+ fipo = dk3sf_c8_fopen_app(
+ itadmin_ethers_c8_kw[4],
+ itadmin_ethers_c8_kw[1],
+ job->app
+ );
+ if(fipo) {
+ back = 1;
+ dk3sto_it_reset(job->i_hoi);
+ while(NULL != (host = (itadmin_host *)dk3sto_it_next(job->i_hoi))) {
+ if((host->ipv4) && (host->sn) && (host->maca)) {
+ fputs(itadmin_ethers_c8_kw[5], fipo);
+ itadmin_tool_write_ip(fipo, host->ipv4);
+ fputs(itadmin_ethers_c8_kw[6], fipo);
+ fputs(bu, fipo);
+ fputc('\n', fipo);
+ fputs(itadmin_ethers_c8_kw[7], fipo);
+ fputc('\n', fipo);
+ fputs(itadmin_ethers_c8_kw[8], fipo);
+ fputc('\n', fipo);
+ fputs(itadmin_ethers_c8_kw[9], fipo);
+ fputc('\n', fipo);
+ fputs(itadmin_ethers_c8_kw[10], fipo);
+ itadmin_tool_write_ip(fipo, host->ipv4);
+ fputc('\n', fipo);
+ fputs(itadmin_ethers_c8_kw[11], fipo);
+ fputs(host->maca, fipo);
+ fputc('\n', fipo); fputc('\n', fipo);
+ }
+ }
+#if DK3_CHAR_SIZE == 1
+ if(!dk3sf_fclose_fn_app(fipo, itadmin_ethers_c8_kw[4], job->app)) {
+ back = 0;
+ }
+#else
+ if(!dk3sf_fclose_fn_app(fipo, NULL, job->app)) {
+ back = 0;
+ }
+#endif
+ } else {
+ }
+ } else {
+ }
+
+
+#line 196 "itaether.ctr"
+ return back;
+}
+
+
diff --git a/support/dktools/itaether.ctr b/support/dktools/itaether.ctr
new file mode 100644
index 0000000000..786b383fe5
--- /dev/null
+++ b/support/dktools/itaether.ctr
@@ -0,0 +1,199 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+
+
+
+%% module
+
+
+#include "dk3all.h"
+#include "itadmin.h"
+
+
+
+$!trace-include
+
+
+
+/** Keywords used by the module.
+*/
+static char const * const itadmin_ethers_c8_kw[] = {
+$!string-table
+#
+# 0: Newline
+#
+\n
+#
+# 1: File open mode w
+#
+w
+#
+# 2: File name "ethers-byip"
+#
+ethers-by-ip
+#
+# 3: File name "ethers-by-mac"
+#
+ethers-by-mac
+#
+# 4: File name "ethers.ldif"
+#
+ethers.ldif
+#
+# 5: Start of DN line
+#
+dn: cn=
+#
+# 6: Middle of DN line
+#
+,ou=ethers,
+#
+# 7: objectClass: ieee802Device
+#
+objectClass: ieee802Device
+#
+# 8: objectClass: device
+#
+objectClass: device
+#
+# 9: objectClass: top
+#
+objectClass: top
+#
+# 10: cn: (start of line)
+#
+cn:
+#
+# 11: macAddress: (start of line)
+#
+macAddress:
+$!end
+};
+
+
+
+
+int
+itadmin_ethers_output(itadmin_job *job)
+{
+ itadmin_host *host;
+ FILE *f1;
+ FILE *f2;
+ int back = 0;
+ $? "+ itadmin_ethers_out"
+ f1 = dk3sf_c8_fopen_app(
+ itadmin_ethers_c8_kw[2],
+ itadmin_ethers_c8_kw[1],
+ job->app
+ );
+ if(f1) {
+ f2 = dk3sf_c8_fopen_app(
+ itadmin_ethers_c8_kw[3],
+ itadmin_ethers_c8_kw[1],
+ job->app
+ );
+ if(f2) {
+ back = 1;
+ dk3sto_it_reset(job->i_hoi);
+ while(NULL != (host = (itadmin_host *)dk3sto_it_next(job->i_hoi))) {
+ if((host->ipv4) && (host->sn) && (host->maca)) {
+ itadmin_tool_write_ip(f1, host->ipv4);
+ fputc('\t', f1);
+ fputs(host->maca, f1);
+ fputc('\n', f1);
+ fputs(host->maca, f2);
+ fputc('\t', f2);
+ itadmin_tool_write_ip(f2, host->ipv4);
+ fputc('\n', f2);
+ }
+ }
+#if DK3_CHAR_SIZE == 1
+ if(!dk3sf_fclose_fn_app(f2, itadmin_ethers_c8_kw[3], job->app)) {
+ back = 0;
+ }
+#else
+ if(!dk3sf_fclose_fn_app(f2, NULL, job->app)) {
+ back = 0;
+ }
+#endif
+ } else {
+ }
+#if DK3_CHAR_SIZE == 1
+ if(!dk3sf_fclose_fn_app(f1, itadmin_ethers_c8_kw[2], job->app)) {
+ back = 0;
+ }
+#else
+ if(!dk3sf_fclose_fn_app(f1, NULL, job->app)) {
+ back = 0;
+ }
+#endif
+ } else {
+ }
+ $? "- itadmin_ethers_out %d", back
+ return back;
+}
+
+
+
+int
+itadmin_ethers_ldif_output(itadmin_job *job)
+{
+ char bu[ITADMIN_CONFIG_LINE_SIZE];
+ itadmin_host *host;
+ FILE *fipo;
+ int ie;
+ int back = 0;
+ $? "+ itadmin_ethers_ldif_output"
+ ie = dk3app_get_encoding(job->app);
+ if(dk3str_to_c8u_app(bu,sizeof(bu),job->ldapb,ie,job->app)) {
+ fipo = dk3sf_c8_fopen_app(
+ itadmin_ethers_c8_kw[4],
+ itadmin_ethers_c8_kw[1],
+ job->app
+ );
+ if(fipo) {
+ back = 1;
+ dk3sto_it_reset(job->i_hoi);
+ while(NULL != (host = (itadmin_host *)dk3sto_it_next(job->i_hoi))) {
+ if((host->ipv4) && (host->sn) && (host->maca)) {
+ fputs(itadmin_ethers_c8_kw[5], fipo);
+ itadmin_tool_write_ip(fipo, host->ipv4);
+ fputs(itadmin_ethers_c8_kw[6], fipo);
+ fputs(bu, fipo);
+ fputc('\n', fipo);
+ fputs(itadmin_ethers_c8_kw[7], fipo);
+ fputc('\n', fipo);
+ fputs(itadmin_ethers_c8_kw[8], fipo);
+ fputc('\n', fipo);
+ fputs(itadmin_ethers_c8_kw[9], fipo);
+ fputc('\n', fipo);
+ fputs(itadmin_ethers_c8_kw[10], fipo);
+ itadmin_tool_write_ip(fipo, host->ipv4);
+ fputc('\n', fipo);
+ fputs(itadmin_ethers_c8_kw[11], fipo);
+ fputs(host->maca, fipo);
+ fputc('\n', fipo); fputc('\n', fipo);
+ }
+ }
+#if DK3_CHAR_SIZE == 1
+ if(!dk3sf_fclose_fn_app(fipo, itadmin_ethers_c8_kw[4], job->app)) {
+ back = 0;
+ }
+#else
+ if(!dk3sf_fclose_fn_app(fipo, NULL, job->app)) {
+ back = 0;
+ }
+#endif
+ } else {
+ }
+ } else {
+ }
+ $? "- itadmin_ethers_ldif_output %d", back
+ return back;
+}
+
+
diff --git a/support/dktools/itahosts.c b/support/dktools/itahosts.c
new file mode 100644
index 0000000000..92d0ad4f65
--- /dev/null
+++ b/support/dktools/itahosts.c
@@ -0,0 +1,321 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: itahosts.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file itahosts.c The itahosts module.
+*/
+
+
+#line 10 "itahosts.ctr"
+
+#include "dk3all.h"
+#include "itadmin.h"
+
+
+
+
+
+#line 17 "itahosts.ctr"
+
+
+
+/** Keywords used by the module.
+*/
+char const * const itadmin_hosts_c8_kw[] = {
+/* 0 */
+"hosts",
+
+/* 1 */
+"w",
+
+/* 2 */
+"hosts.ldif",
+
+/* 3 */
+"dn: cn=",
+
+/* 4 */
+"+ipHostNumber=",
+
+/* 5 */
+",ou=Hosts,",
+
+/* 6 */
+"objectClass: ipHost",
+
+/* 7 */
+"objectClass: device",
+
+/* 8 */
+"objectClass: top",
+
+/* 9 */
+"cn: ",
+
+/* 10 */
+"ipHostNumber: ",
+
+/* 11 */
+"127.0.0.1\tlocalhost\tloopback",
+
+/* 12 */
+"dn: cn=localhost+ipHostNumber=127.0.0.1",
+
+/* 13 */
+"cn: localhost",
+
+/* 14 */
+"cn: loopback",
+
+/* 15 */
+"ipHostNumber: 127.0.0.1",
+
+NULL
+
+
+#line 89 "itahosts.ctr"
+};
+
+
+int
+itadmin_hosts_output(itadmin_job *job)
+{
+ FILE *fipo; /* Output file. */
+ itadmin_network *cnw; /* Current network. */
+ itadmin_network *pnw; /* Previous network. */
+ itadmin_host *host; /* Current host to process. */
+ char const *al; /* Current alias to process. */
+ int dnw; /* Flag: Different network. */
+ int any = 0; /* Flag: Any host found. */
+ int back = 0;
+
+
+#line 104 "itahosts.ctr"
+ fipo = dk3sf_c8_fopen_app(
+ itadmin_hosts_c8_kw[0], itadmin_hosts_c8_kw[1], job->app
+ );
+ if(fipo) {
+ if(!(job->hlh)) {
+ fputs(itadmin_hosts_c8_kw[11], fipo);
+ fputc('\n', fipo);
+ fputc('\n', fipo);
+ }
+ dk3sto_it_reset(job->i_hoi);
+ pnw = cnw = NULL;
+ while(NULL != (host = (itadmin_host *)dk3sto_it_next(job->i_hoi))) {
+ if((host->ipv4) && (host->sn)) {
+ dnw = 0;
+ cnw = (itadmin_network *)dk3sto_it_find_like(
+ job->i_nw, (void *)(&(host->ipv4)), 1
+ );
+ if(pnw) {
+ if(cnw) {
+ if(cnw->ip4 != pnw->ip4) {
+ dnw = 1;
+ }
+ } else {
+ dnw = 1;
+ }
+ } else {
+ if(cnw) {
+ dnw = 1;
+ }
+ }
+ pnw = cnw;
+ if(dnw) { fputc('\n', fipo); }
+ itadmin_tool_write_ip(fipo, host->ipv4);
+ fputc('\t', fipo);
+ fputs(host->sn, fipo);
+ if((host->fnf) && (host->dnsd)) {
+ fputc('.', fipo);
+ fputs(host->dnsd, fipo);
+ fputc(' ', fipo);
+ fputs(host->sn, fipo);
+ }
+ if(host->i_al) {
+ dk3sto_it_reset(host->i_al);
+ while(NULL != (al = (char const *)dk3sto_it_next(host->i_al))) {
+ fputc(' ', fipo);
+ fputs(al, fipo);
+ }
+ }
+ fputc('\n', fipo);
+ any = 1;
+ }
+ }
+ if(any) {
+ back = 1;
+ }
+#if DK3_CHAR_SIZE == 1
+ if(!dk3sf_fclose_fn_app(fipo, itadmin_hosts_c8_kw[0], job->app)) {
+ back = 0;
+ }
+#else
+ if(!dk3sf_fclose_fn_app(fipo, NULL, job->app)) {
+ back = 0;
+ }
+#endif
+ } else {
+
+#line 169 "itahosts.ctr"
+ }
+
+#line 170 "itahosts.ctr"
+ return back;
+}
+
+
+
+int
+itadmin_hosts_ldif_output(itadmin_job *job)
+{
+ char bu[ITADMIN_CONFIG_LINE_SIZE];
+ itadmin_host *host;
+ FILE *fipo;
+ char const *al;
+ int ie;
+ int any = 0;
+ int back = 0;
+
+
+#line 186 "itahosts.ctr"
+ ie = dk3app_get_encoding(job->app);
+ if(dk3str_to_c8u_app(bu,sizeof(bu),job->ldapb,ie,job->app)) {
+ fipo = dk3sf_c8_fopen_app(
+ itadmin_hosts_c8_kw[2], itadmin_hosts_c8_kw[1], job->app
+ );
+ if(fipo) {
+ if(!(job->hlh)) {
+ fputs(itadmin_hosts_c8_kw[12], fipo);
+ fputs(itadmin_hosts_c8_kw[5], fipo);
+ fputs(bu, fipo);
+ fputc('\n', fipo);
+ /* objectClass: ipHost */
+ fputs(itadmin_hosts_c8_kw[6], fipo);
+ fputc('\n', fipo);
+ /* objectClass: device */
+ fputs(itadmin_hosts_c8_kw[7], fipo);
+ fputc('\n', fipo);
+ /* objectClass: top */
+ fputs(itadmin_hosts_c8_kw[8], fipo);
+ fputc('\n', fipo);
+ /* cn: localhost */
+ fputs(itadmin_hosts_c8_kw[13], fipo);
+ fputc('\n', fipo);
+ /* cn: loopback */
+ fputs(itadmin_hosts_c8_kw[14], fipo);
+ fputc('\n', fipo);
+ /* ipHostNumber: 127.0.0.1 */
+ fputs(itadmin_hosts_c8_kw[15], fipo);
+ fputc('\n', fipo);
+ fputc('\n', fipo);
+ }
+ dk3sto_it_reset(job->i_hoi);
+ while(NULL != (host = (itadmin_host *)dk3sto_it_next(job->i_hoi))) {
+ if((host->ipv4) && (host->sn)) {
+ any = 1;
+ /* DN */
+ fputs(itadmin_hosts_c8_kw[3], fipo);
+ fputs(host->sn, fipo);
+ if((host->fnf) && (host->dnsd)) {
+ fputc('.', fipo);
+ fputs(host->dnsd, fipo);
+ }
+ fputs(itadmin_hosts_c8_kw[4], fipo);
+ itadmin_tool_write_ip(fipo, host->ipv4);
+ fputs(itadmin_hosts_c8_kw[5], fipo);
+ fputs(bu, fipo);
+ fputc('\n', fipo);
+ /* objectClass: ipHost */
+ fputs(itadmin_hosts_c8_kw[6], fipo);
+ fputc('\n', fipo);
+ /* objectClass: device */
+ fputs(itadmin_hosts_c8_kw[7], fipo);
+ fputc('\n', fipo);
+ /* objectClass: top */
+ fputs(itadmin_hosts_c8_kw[8], fipo);
+ fputc('\n', fipo);
+ /* cn: */
+ if((host->dnsd) && (host->fnf)) {
+ fputs(itadmin_hosts_c8_kw[9], fipo);
+ fputs(host->sn, fipo);
+ fputc('.', fipo);
+ fputs(host->dnsd, fipo);
+ fputc('\n', fipo);
+ }
+ fputs(itadmin_hosts_c8_kw[9], fipo);
+ fputs(host->sn, fipo);
+ fputc('\n', fipo);
+ if(host->i_al) {
+ dk3sto_it_reset(host->i_al);
+ while(NULL != (al = (char const *)dk3sto_it_next(host->i_al))) {
+ fputs(itadmin_hosts_c8_kw[9], fipo);
+ fputs(al, fipo);
+ fputc('\n', fipo);
+ }
+ }
+ /* ipHostNumber: */
+ fputs(itadmin_hosts_c8_kw[10], fipo);
+ itadmin_tool_write_ip(fipo, host->ipv4);
+ fputc('\n', fipo);
+ fputc('\n', fipo);
+ }
+ }
+ if(any) {
+ back = 1;
+ }
+#if DK3_CHAR_SIZE == 1
+ if(!dk3sf_fclose_fn_app(fipo, itadmin_hosts_c8_kw[2], job->app)) {
+ back = 0;
+ }
+#else
+ if(!dk3sf_fclose_fn_app(fipo, NULL, job->app)) {
+ back = 0;
+ }
+#endif
+ } else {
+
+#line 281 "itahosts.ctr"
+ }
+ } else {
+
+#line 283 "itahosts.ctr"
+ }
+
+
+#line 285 "itahosts.ctr"
+ return back;
+}
+
+
diff --git a/support/dktools/itahosts.ctr b/support/dktools/itahosts.ctr
new file mode 100644
index 0000000000..f25a2e53de
--- /dev/null
+++ b/support/dktools/itahosts.ctr
@@ -0,0 +1,288 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk3all.h"
+#include "itadmin.h"
+
+
+
+$!trace-include
+
+
+
+/** Keywords used by the module.
+*/
+char const * const itadmin_hosts_c8_kw[] = {
+$!string-table
+#
+# 0: File name "hosts"
+#
+hosts
+#
+# 1: File open mode "w"
+#
+w
+#
+# 2: File name "hosts.ldif"
+#
+hosts.ldif
+#
+# 3: Line start for DN
+#
+dn: cn=
+#
+# 4: ipHostNumber in DN line
+#
++ipHostNumber=
+#
+# 5: Final string in DN line before base
+#
+,ou=Hosts,
+#
+# 6: objectClass: ipHost
+#
+objectClass: ipHost
+#
+# 7: objectClass: device
+#
+objectClass: device
+#
+# 8: objectClass: top
+#
+objectClass: top
+#
+# 9: cn
+#
+cn:
+#
+# 10: ipHostNumber
+#
+ipHostNumber:
+#
+# 11: First hosts line.
+#
+127.0.0.1 localhost loopback
+#
+# 12: First hosts.ldif line.
+#
+dn: cn=localhost+ipHostNumber=127.0.0.1
+#
+# 13:
+#
+cn: localhost
+#
+# 14:
+#
+cn: loopback
+#
+# 15:
+#
+ipHostNumber: 127.0.0.1
+$!end
+};
+
+
+int
+itadmin_hosts_output(itadmin_job *job)
+{
+ FILE *fipo; /* Output file. */
+ itadmin_network *cnw; /* Current network. */
+ itadmin_network *pnw; /* Previous network. */
+ itadmin_host *host; /* Current host to process. */
+ char const *al; /* Current alias to process. */
+ int dnw; /* Flag: Different network. */
+ int any = 0; /* Flag: Any host found. */
+ int back = 0;
+ $? "+ itadmin_output_hosts"
+ fipo = dk3sf_c8_fopen_app(
+ itadmin_hosts_c8_kw[0], itadmin_hosts_c8_kw[1], job->app
+ );
+ if(fipo) {
+ if(!(job->hlh)) {
+ fputs(itadmin_hosts_c8_kw[11], fipo);
+ fputc('\n', fipo);
+ fputc('\n', fipo);
+ }
+ dk3sto_it_reset(job->i_hoi);
+ pnw = cnw = NULL;
+ while(NULL != (host = (itadmin_host *)dk3sto_it_next(job->i_hoi))) {
+ if((host->ipv4) && (host->sn)) {
+ dnw = 0;
+ cnw = (itadmin_network *)dk3sto_it_find_like(
+ job->i_nw, (void *)(&(host->ipv4)), 1
+ );
+ if(pnw) {
+ if(cnw) {
+ if(cnw->ip4 != pnw->ip4) {
+ dnw = 1;
+ }
+ } else {
+ dnw = 1;
+ }
+ } else {
+ if(cnw) {
+ dnw = 1;
+ }
+ }
+ pnw = cnw;
+ if(dnw) { fputc('\n', fipo); }
+ itadmin_tool_write_ip(fipo, host->ipv4);
+ fputc('\t', fipo);
+ fputs(host->sn, fipo);
+ if((host->fnf) && (host->dnsd)) {
+ fputc('.', fipo);
+ fputs(host->dnsd, fipo);
+ fputc(' ', fipo);
+ fputs(host->sn, fipo);
+ }
+ if(host->i_al) {
+ dk3sto_it_reset(host->i_al);
+ while(NULL != (al = (char const *)dk3sto_it_next(host->i_al))) {
+ fputc(' ', fipo);
+ fputs(al, fipo);
+ }
+ }
+ fputc('\n', fipo);
+ any = 1;
+ }
+ }
+ if(any) {
+ back = 1;
+ }
+#if DK3_CHAR_SIZE == 1
+ if(!dk3sf_fclose_fn_app(fipo, itadmin_hosts_c8_kw[0], job->app)) {
+ back = 0;
+ }
+#else
+ if(!dk3sf_fclose_fn_app(fipo, NULL, job->app)) {
+ back = 0;
+ }
+#endif
+ } else { $? "! fopen"
+ } $? "- itadmin_output_hosts %d", back
+ return back;
+}
+
+
+
+int
+itadmin_hosts_ldif_output(itadmin_job *job)
+{
+ char bu[ITADMIN_CONFIG_LINE_SIZE];
+ itadmin_host *host;
+ FILE *fipo;
+ char const *al;
+ int ie;
+ int any = 0;
+ int back = 0;
+ $? "+ itadmin_hosts_ldif_output"
+ ie = dk3app_get_encoding(job->app);
+ if(dk3str_to_c8u_app(bu,sizeof(bu),job->ldapb,ie,job->app)) {
+ fipo = dk3sf_c8_fopen_app(
+ itadmin_hosts_c8_kw[2], itadmin_hosts_c8_kw[1], job->app
+ );
+ if(fipo) {
+ if(!(job->hlh)) {
+ fputs(itadmin_hosts_c8_kw[12], fipo);
+ fputs(itadmin_hosts_c8_kw[5], fipo);
+ fputs(bu, fipo);
+ fputc('\n', fipo);
+ /* objectClass: ipHost */
+ fputs(itadmin_hosts_c8_kw[6], fipo);
+ fputc('\n', fipo);
+ /* objectClass: device */
+ fputs(itadmin_hosts_c8_kw[7], fipo);
+ fputc('\n', fipo);
+ /* objectClass: top */
+ fputs(itadmin_hosts_c8_kw[8], fipo);
+ fputc('\n', fipo);
+ /* cn: localhost */
+ fputs(itadmin_hosts_c8_kw[13], fipo);
+ fputc('\n', fipo);
+ /* cn: loopback */
+ fputs(itadmin_hosts_c8_kw[14], fipo);
+ fputc('\n', fipo);
+ /* ipHostNumber: 127.0.0.1 */
+ fputs(itadmin_hosts_c8_kw[15], fipo);
+ fputc('\n', fipo);
+ fputc('\n', fipo);
+ }
+ dk3sto_it_reset(job->i_hoi);
+ while(NULL != (host = (itadmin_host *)dk3sto_it_next(job->i_hoi))) {
+ if((host->ipv4) && (host->sn)) {
+ any = 1;
+ /* DN */
+ fputs(itadmin_hosts_c8_kw[3], fipo);
+ fputs(host->sn, fipo);
+ if((host->fnf) && (host->dnsd)) {
+ fputc('.', fipo);
+ fputs(host->dnsd, fipo);
+ }
+ fputs(itadmin_hosts_c8_kw[4], fipo);
+ itadmin_tool_write_ip(fipo, host->ipv4);
+ fputs(itadmin_hosts_c8_kw[5], fipo);
+ fputs(bu, fipo);
+ fputc('\n', fipo);
+ /* objectClass: ipHost */
+ fputs(itadmin_hosts_c8_kw[6], fipo);
+ fputc('\n', fipo);
+ /* objectClass: device */
+ fputs(itadmin_hosts_c8_kw[7], fipo);
+ fputc('\n', fipo);
+ /* objectClass: top */
+ fputs(itadmin_hosts_c8_kw[8], fipo);
+ fputc('\n', fipo);
+ /* cn: */
+ if((host->dnsd) && (host->fnf)) {
+ fputs(itadmin_hosts_c8_kw[9], fipo);
+ fputs(host->sn, fipo);
+ fputc('.', fipo);
+ fputs(host->dnsd, fipo);
+ fputc('\n', fipo);
+ }
+ fputs(itadmin_hosts_c8_kw[9], fipo);
+ fputs(host->sn, fipo);
+ fputc('\n', fipo);
+ if(host->i_al) {
+ dk3sto_it_reset(host->i_al);
+ while(NULL != (al = (char const *)dk3sto_it_next(host->i_al))) {
+ fputs(itadmin_hosts_c8_kw[9], fipo);
+ fputs(al, fipo);
+ fputc('\n', fipo);
+ }
+ }
+ /* ipHostNumber: */
+ fputs(itadmin_hosts_c8_kw[10], fipo);
+ itadmin_tool_write_ip(fipo, host->ipv4);
+ fputc('\n', fipo);
+ fputc('\n', fipo);
+ }
+ }
+ if(any) {
+ back = 1;
+ }
+#if DK3_CHAR_SIZE == 1
+ if(!dk3sf_fclose_fn_app(fipo, itadmin_hosts_c8_kw[2], job->app)) {
+ back = 0;
+ }
+#else
+ if(!dk3sf_fclose_fn_app(fipo, NULL, job->app)) {
+ back = 0;
+ }
+#endif
+ } else { $? "! fopen"
+ }
+ } else { $? "! conversion to UTF-8 failed"
+ }
+ $? "- itadmin_hosts_ldif_output %d", back
+ return back;
+}
+
+
diff --git a/support/dktools/italic.c b/support/dktools/italic.c
new file mode 100644
index 0000000000..5db6997f4a
--- /dev/null
+++ b/support/dktools/italic.c
@@ -0,0 +1,1297 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: italic.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file italic.c The italic module.
+*/
+
+
+#line 9 "italic.ctr"
+
+#include "dk3all.h"
+#include "itadmin.h"
+
+
+
+
+
+#line 16 "italic.ctr"
+
+
+
+/** Keywords used by the module.
+*/
+static char const * const itadmin_license_c8_kw[] = {
+/* 0 */
+"\n",
+
+/* 1 */
+" ",
+
+/* 2 */
+"licenses.tex",
+
+/* 3 */
+"w",
+
+/* 4 */
+"\\chapter{",
+
+/* 5 */
+"}",
+
+/* 6 */
+"\\clearpage",
+
+/* 7 */
+"\\\\\n\\end{longtable}",
+
+/* 8 */
+"\\section{",
+
+/* 9 */
+"\\subsection{",
+
+/* 10 */
+"\\subsubsection{",
+
+/* 11 */
+"pdftitle={",
+
+/* 12 */
+"pdfsubject={",
+
+/* 13 */
+"pdfauthor={",
+
+/* 14 */
+"pdfcreator={itadmin - http://dktools.sourceforge.net/}",
+
+/* 15 */
+"\\author{",
+
+/* 16 */
+"\\title{",
+
+/* 17 */
+",",
+
+/* 18 */
+"\\begin{longtable}{lll}",
+
+/* 19 */
+"\\endfirsthead",
+
+/* 20 */
+"\\endhead",
+
+/* 21 */
+"\\endfoot",
+
+/* 22 */
+"\\endlastfoot",
+
+/* 23 */
+"\\\\[0.5em]",
+
+/* 24 */
+"&",
+
+/* 25 */
+"\\multicolumn{2}{l}{",
+
+/* 26 */
+"\\\\*",
+
+/* 27 */
+"\\textit{",
+
+/* 28 */
+"\\chapter[",
+
+/* 29 */
+"]{",
+
+/* 30 */
+"\\section[",
+
+/* 31 */
+"\\emph{",
+
+/* 32 */
+"\\/} ",
+
+NULL
+
+
+#line 156 "italic.ctr"
+};
+
+
+
+/** Start of LaTeX source.
+*/
+static char const * const itadmin_license_file_start1a[] = {
+"\\documentclass[titlepage,origlongtable]{scrbook}",
+"\\KOMAoptions{paper=a4}",
+"\\KOMAoptions{fontsize=12pt}",
+NULL
+
+
+#line 168 "italic.ctr"
+};
+
+
+
+/** Start of LaTeX source.
+*/
+static char const * const itadmin_license_file_start1b[] = {
+"\\documentclass[12pt]{book}",
+NULL
+
+
+#line 178 "italic.ctr"
+};
+
+
+/** LaTeX packages after ngerman.
+*/
+static char const * const itadmin_license_file_start4[] = {
+"\\usepackage{ifpdf}",
+"\\usepackage[utf8]{inputenc}",
+"\\usepackage{mathptmx}",
+"\\usepackage[scaled=.92]{helvet}",
+"\\usepackage{courier}",
+"\\usepackage[T1]{fontenc}",
+"\\usepackage{textcomp}",
+"\\usepackage{latexsym}",
+"\\usepackage{varioref}",
+"\\usepackage{color}",
+"\\usepackage{makeidx}",
+"\\usepackage{longtable}",
+"\\makeindex",
+"\\ifpdf",
+"\\usepackage[activate=normal]{pdfcprot}",
+"\\pdfcompresslevel=9",
+"\\usepackage[",
+"pdftex,",
+"colorlinks=true,",
+"pdfpagemode=UseNone,",
+"pdfstartview={XYZ 0 835 1.25},",
+"bookmarksnumbered,",
+NULL
+
+
+#line 208 "italic.ctr"
+};
+
+
+
+/** LaTeX package after hyperref options for title, subject, author.
+*/
+static char const * const itadmin_license_file_start2[] = {
+"]{hyperref}",
+"\\else",
+"\\usepackage[dvips,colorlinks=true,linkcolor=black]{hyperref}",
+"\\fi",
+"\\parindent0cm",
+NULL
+
+
+#line 222 "italic.ctr"
+};
+
+
+
+/** Renewcommand used only for koma-script.
+*/
+static char const * const itadmin_license_file_start3a[] = {
+"\\renewcommand*{\\sectfont}{\\bfseries}",
+NULL
+
+
+#line 232 "italic.ctr"
+};
+
+
+
+/** Final commands after title and author.
+*/
+static char const * const itadmin_license_file_start3[] = {
+"\\setcounter{secnumdepth}{1}",
+"\\begin{document}",
+NULL
+
+
+#line 243 "italic.ctr"
+};
+
+
+
+/** LaTeX file end.
+*/
+static char const * const itadmin_license_file_end[] = {
+"\\end{document}",
+NULL
+
+
+#line 253 "italic.ctr"
+};
+
+
+
+/** Write data for one license.
+ @param job Job structure.
+ @param os Output stream.
+ @param lic License to write.
+*/
+static
+void
+itadmin_license_write_license_type(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ itadmin_license *lic
+)
+{
+ char const *ltn;
+ int ie;
+ ltn = NULL;
+ if(lic->ltype) {
+ ltn = (lic->ltype)->sn;
+ if((lic->ltype)->ln) {
+ ltn = (lic->ltype)->ln;
+ }
+ }
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[25]);
+ if(ltn) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, ltn);
+ } else {
+ ie = dk3app_get_encoding(job->app);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[53], ie);
+ }
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+}
+
+
+
+/** Check whether we must write the license owner because the host owner
+ differs from the license owner.
+ @param user License owner.
+ @param host Host on which the license is used.
+ @return 1 if host and license owner differ, 0 if they match.
+*/
+static
+int
+itadmin_license_must_write_license_owner(itadmin_user *user, itadmin_host *host)
+{
+ int back = 0;
+ if(user) {
+ if(user->us) {
+ if(host) {
+ if(host->un) {
+ if((host->un)->us) {
+ if(dk3str_c8_cmp(user->us, (host->un)->us)) {
+ back = 1;
+ }
+ }
+ } else {
+ }
+ } else {
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Check whether we must write the host owner because the host owner
+ differs from the license owner.
+ @param user License owner.
+ @param host Host on which the license is used.
+ @return 1 if host and license owner differ, 0 if they match.
+*/
+static
+int
+itadmin_license_must_write_host_owner(itadmin_user *user, itadmin_host *host)
+{
+ int back = 0;
+ if(host) {
+ if(host->un) {
+ if(user) {
+ if((host->un)->us) {
+ if(user->us) {
+ if(dk3str_c8_cmp((host->un)->us, user->us)) {
+ back = 1;
+ }
+ } else {
+ back = 1;
+ }
+ }
+ } else {
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Write data for one license.
+ @param job Job structure.
+ @param os Output stream.
+ @param lic License to write.
+ @param pman Software manufacturuer name.
+ @param pprod Software product name.
+ @param mn Flag: Write software manufacturer name.
+ @param pn Flag: Write software product name.
+ @param un Flag: Write user name who owns the license.
+ @param hn Flag: Write host name where license is used.
+ @param ond On difference between license owner and host owner:
+ 0=do nothing, 1=write host owner, 2=write license owner
+*/
+static
+void
+itadmin_license_write_license(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ itadmin_license *lic,
+ char const *pman,
+ char const *pprod,
+ int mn,
+ int pn,
+ int un,
+ int hn,
+ int ond
+)
+{
+ char bu[128];
+ int ie;
+ ie = dk3app_get_encoding(job->app);
+ sprintf(bu, "%lu", lic->pk);
+ dk3stream_c8_fputs(os, bu);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ if((mn) && (pman)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[25]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, pman);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ if((pn) && (pprod)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[26]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[25]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, pprod);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ }
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[26]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ itadmin_license_write_license_type(job, os, lic);
+ } else {
+ if((pn) && (pprod)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[25]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, pprod);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[26]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ itadmin_license_write_license_type(job, os, lic);
+ } else {
+ itadmin_license_write_license_type(job, os, lic);
+ }
+ }
+ if(lic->notes) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[26]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[25]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, lic->notes);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ }
+ if(un) {
+ if(lic->owner) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[26]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[25]);
+ itadmin_tool_write_user_latex_long(job, os, lic->owner);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ }
+ }
+ if(hn) {
+ if(lic->host) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[26]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ if((lic->host)->sn) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, (lic->host)->sn);
+ }
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ if((lic->host)->co) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, (lic->host)->co);
+ }
+ switch(ond) {
+ case 1: { /* On difference write host owner. */
+ if(itadmin_license_must_write_host_owner(lic->owner, lic->host)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[26]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[25]);
+ if(mn) { dk3stream_c8_fputs(os, itadmin_license_c8_kw[27]); }
+ itadmin_tool_write_user_latex_long(job, os, (lic->host)->un);
+ if(mn) { dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]); }
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ }
+ } break;
+ case 2: { /* On difference write license owner. */
+ if(itadmin_license_must_write_license_owner(lic->owner, lic->host)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[26]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[25]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[27]);
+ itadmin_tool_write_user_latex_long(job, os, lic->owner);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ }
+ } break;
+ }
+ }
+ } else {
+ if((lic->host) && (lic->owner)) {
+ switch(ond) {
+ case 1: {
+ if(itadmin_license_must_write_host_owner(lic->owner, lic->host)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[26]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[25]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[27]);
+ itadmin_tool_write_user_latex_long(job, os, (lic->host)->un);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ }
+ } break;
+ case 2: {
+ if(itadmin_license_must_write_license_owner(lic->owner, lic->host)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[26]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[25]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[27]);
+ itadmin_tool_write_user_latex_long(job, os, lic->owner);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ }
+ } break;
+ }
+ }
+ }
+ if(lic->order) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[26]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[54], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, lic->order);
+ }
+ if(((lic->d_del).d) && ((lic->d_del).m) && ((lic->d_del).y)) {
+ if(job->gdate) {
+ sprintf(
+ bu, "%02d.%02d.%04d", (lic->d_del).d, (lic->d_del).m, (lic->d_del).y
+ );
+ } else {
+ sprintf(
+ bu, "%04d-%02d-%02d", (lic->d_del).y, (lic->d_del).m, (lic->d_del).d
+ );
+ }
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[26]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[55], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ dk3stream_c8_fputs(os, bu);
+ }
+ if(lic->i_del) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[26]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[56], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, lic->i_del);
+ }
+ if(((lic->d_inv).d) && ((lic->d_inv).m) && ((lic->d_inv).y)) {
+ if(job->gdate) {
+ sprintf(
+ bu, "%02d.%02d.%04d", (lic->d_inv).d, (lic->d_inv).m, (lic->d_inv).y
+ );
+ } else {
+ sprintf(
+ bu, "%04d-%02d-%02d", (lic->d_inv).y, (lic->d_inv).m, (lic->d_inv).d
+ );
+ }
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[26]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[57], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ dk3stream_c8_fputs(os, bu);
+ }
+ if(lic->i_inv) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[26]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[58], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, lic->i_inv);
+ }
+}
+
+
+
+/** Get software manufacturer name.
+ @param li License
+ @return Software manufacturer name on success, NULL on error.
+*/
+static
+char const *
+itadmin_license_get_manufacturer(itadmin_license *li)
+{
+ char const *back = NULL;
+ if(li->prod) {
+ if((li->prod)->mn) {
+ back = ((li->prod)->mn)->sn;
+ if(((li->prod)->mn)->ln) {
+ back = ((li->prod)->mn)->ln;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Get software product name.
+ @param li License.
+ @return Product name on success, NULL on error.
+*/
+static
+char const *
+itadmin_license_get_product(itadmin_license *li)
+{
+ char const *back = NULL;
+ if(li->prod) {
+ back = (li->prod)->sn;
+ if((li->prod)->ln) {
+ back = (li->prod)->ln;
+ }
+ }
+ return back;
+}
+
+
+
+/** Check whether manufacturer and/or product have changed.
+ @param pman
+ @param prev_man
+ @param pprod
+ @param prev_prod
+ @return 0=no change, 1=product change, 2=manufacturer change.
+*/
+static
+int
+itadmin_license_change_level(
+ char const *pman,
+ char const *prev_man,
+ char const *pprod,
+ char const *prev_prod
+)
+{
+ int back = 0;
+
+
+#line 627 "italic.ctr"
+ if(pprod) {
+ if(prev_prod) {
+ if(dk3str_c8_cmp(pprod, prev_prod)) {
+ back = 1;
+ }
+ } else { back = 1; }
+ } else {
+ if(prev_prod) { back = 1; }
+ }
+ if(pman) {
+ if(prev_man) {
+ if(dk3str_c8_cmp(pman, prev_man)) {
+ back = 2;
+ }
+ } else { back = 2; }
+ } else {
+ if(prev_man) { back = 2; }
+ }
+
+#line 645 "italic.ctr"
+ return back;
+}
+
+
+
+/** Start a longtable for the licenses.
+ @param job Job structure.
+ @param os Output stream.
+*/
+static
+void
+itadmin_license_start_longtable_for_licenses(
+ itadmin_job *job,
+ dk3_stream_t *os
+)
+{
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[18]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[19]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[20]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[21]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[22]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+}
+
+
+
+/** End a longtable for the licenses.
+ @param job Job structure.
+ @param os Output stream.
+*/
+static
+void
+itadmin_license_end_longtable_for_licenses(
+ itadmin_job *job,
+ dk3_stream_t *os
+)
+{
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[7]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+}
+
+
+
+/** Write available licenses.
+ @param job Job structure.
+ @param os Output stream.
+*/
+static
+void
+itadmin_license_write_available(itadmin_job *job, dk3_stream_t *os)
+{
+ itadmin_license *li; /* Current license to print. */
+ char const *prev_man; /* Previous software manufacturer. */
+ char const *prev_prod; /* Previous software product. */
+ char const *pman; /* Current software manufacturer. */
+ char const *pprod; /* Current software product. */
+ int have_chap; /* Flag: Chapter was started. */
+ int have_tab; /* Flag: Table was started. */
+ int ie; /* Input encoding. */
+
+
+#line 709 "italic.ctr"
+ ie = dk3app_get_encoding(job->app);
+ have_chap = have_tab = 0;
+ prev_man = NULL; prev_prod = NULL;
+ dk3sto_it_reset(job->i_lf);
+ while(NULL != (li = (itadmin_license *)dk3sto_it_next(job->i_lf))) {
+ if(!(have_chap)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[4]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[48], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[49], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[50], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ } have_chap = 1;
+ pman = itadmin_license_get_manufacturer(li);
+
+#line 725 "italic.ctr"
+ pprod = itadmin_license_get_product(li);
+
+#line 726 "italic.ctr"
+ switch(itadmin_license_change_level(pman, prev_man, pprod, prev_prod)) {
+ case 2: { /* Manufacturer changed. */
+ if(have_tab) {
+ itadmin_license_end_longtable_for_licenses(job, os);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[6]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ }
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[8]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, pman);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[9]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, pprod);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ have_tab = 0;
+ } break;
+ case 1: { /* Product changed. */
+ if(have_tab) {
+ itadmin_license_end_longtable_for_licenses(job, os);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[6]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ }
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[9]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, pprod);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ have_tab = 0;
+ } break;
+ default: { /* No change. */
+ if(have_tab) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[23]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ }
+ } break;
+ }
+ if(!(have_tab)) {
+ itadmin_license_start_longtable_for_licenses(job, os);
+ have_tab = 1;
+ }
+ itadmin_license_write_license(job, os, li, pman, pprod, 0, 0, 0, 0, 0);
+ prev_man = pman; prev_prod = pprod;
+ }
+ if(have_chap) {
+ if(have_tab) {
+ /* end{longtable} */
+ itadmin_license_end_longtable_for_licenses(job, os);
+ }
+ /* clearpage */
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[6]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ }
+
+#line 778 "italic.ctr"
+}
+
+
+
+/** Write license report per user/host.
+ @param job Job structure.
+ @param os Output stream.
+*/
+static
+void
+itadmin_license_write_user(itadmin_job *job, dk3_stream_t *os)
+{
+ itadmin_user *us;
+ itadmin_host *ho;
+ itadmin_license *li;
+ char const *pman;
+ char const *pprod;
+ char const *prev_man;
+ char const *prev_prod;
+ int have_chap;
+ int have_sec;
+#if VERSION_BEFORE_20150821
+ int have_subsec;
+#endif
+ int have_tab;
+ int ie;
+
+
+#line 805 "italic.ctr"
+ ie = dk3app_get_encoding(job->app);
+ dk3sto_it_reset(job->i_us);
+ while(NULL != (us = (itadmin_user *)dk3sto_it_next(job->i_us))) {
+ have_chap = 0;
+#if VERSION_BEFORE_20150821
+ have_sec = 0;
+#endif
+#if VERSION_BEFORE_20150821
+ have_subsec = 0;
+#endif
+#if VERSION_BEFORE_20150821
+ have_tab = 0;
+#endif
+ /*
+ Licenses on hosts
+ */
+ if(us->i_ho) {
+ dk3sto_it_reset(us->i_ho);
+ while(NULL != (ho = (itadmin_host *)dk3sto_it_next(us->i_ho))) {
+ have_sec = 0;
+#if VERSION_BEFORE_20150821
+ have_subsec = 0;
+#endif
+ if(ho->i_li) {
+ prev_man = NULL;
+ prev_prod = NULL;
+ have_tab = 0;
+ dk3sto_it_reset(ho->i_li);
+ while(NULL != (li = (itadmin_license *)dk3sto_it_next(ho->i_li))) {
+ pman = itadmin_license_get_manufacturer(li);
+ pprod = itadmin_license_get_product(li);
+ switch(itadmin_license_change_level(pman,prev_man,pprod,prev_prod))
+ {
+ case 2: { /* Manufacturer changed. */
+ if(have_tab) {
+ itadmin_license_end_longtable_for_licenses(job, os);
+ } have_tab = 0;
+ if(!(have_chap)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[28]);
+ itadmin_tool_write_user_latex_short(job, os, us);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[29]);
+ itadmin_tool_write_user_latex_long(job, os, us);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ } have_chap = 1;
+ if(!(have_sec)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[8]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, ho->sn);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ } have_sec = 1;
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[9]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, pman);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ } break;
+ default: { /* Manufacturer unchanged. */
+ if(have_tab) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[23]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ }
+ } break;
+ }
+ if(!(have_tab)) {
+ itadmin_license_start_longtable_for_licenses(job, os);
+ have_tab = 1;
+ }
+ itadmin_license_write_license(job, os, li, pman, pprod, 0, 1, 0, 0, 2);
+ prev_man = pman; prev_prod = pprod;
+ }
+ if(have_tab) {
+ itadmin_license_end_longtable_for_licenses(job, os);
+ }
+ if(have_sec) {
+ /* clearpage */
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[6]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ }
+ }
+ }
+ }
+ if(us->i_li) {
+ /*
+ Licenses not assigned to hosts
+ */
+ have_sec = 0; have_tab = 0;
+ dk3sto_it_reset(us->i_li);
+ prev_man = NULL; prev_prod = NULL;
+ while(NULL != (li = (itadmin_license *)dk3sto_it_next(us->i_li))) {
+ if(!(li->host)) {
+ pman = itadmin_license_get_manufacturer(li);
+ pprod = itadmin_license_get_product(li);
+ switch(itadmin_license_change_level(pman,prev_man,pprod,prev_prod))
+ {
+ case 2: { /* Manufacturer changed */
+ if(have_tab) {
+ itadmin_license_end_longtable_for_licenses(job, os);
+ } have_tab = 0;
+ if(!(have_chap)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[28]);
+ itadmin_tool_write_user_latex_short(job, os, us);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[29]);
+ itadmin_tool_write_user_latex_long(job, os, us);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ } have_chap = 1;
+ if(!(have_sec)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[30]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[60], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[29]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[61], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[64], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[65], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[66], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ } have_sec = 1;
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[9]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, pman);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[10]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, pprod);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ } break;
+ case 1: { /* Product changed */
+ if(have_tab) {
+ itadmin_license_end_longtable_for_licenses(job, os);
+ } have_tab = 0;
+ if(!(have_chap)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[28]);
+ itadmin_tool_write_user_latex_short(job, os, us);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[29]);
+ itadmin_tool_write_user_latex_long(job, os, us);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ } have_chap = 1;
+ if(!(have_sec)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[30]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[60], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[29]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[61], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[64], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[65], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[66], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ } have_sec = 1;
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[10]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, pprod);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ } break;
+ default: {
+ if(have_tab) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[23]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ }
+ } break;
+ }
+ if(!(have_tab)) {
+ itadmin_license_start_longtable_for_licenses(job, os);
+ have_tab = 1;
+ }
+ itadmin_license_write_license(job, os, li, pman, pprod, 0, 0, 0, 0, 0);
+ prev_man = pman; prev_prod = pprod;
+ }
+ }
+ if(have_tab) {
+ itadmin_license_end_longtable_for_licenses(job, os);
+ }
+ if(have_sec) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[6]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ }
+ /*
+ Licenses used on other users computers
+ */
+ have_sec = 0; have_tab = 0;
+ dk3sto_it_reset(us->i_li);
+ prev_man = NULL; prev_prod = NULL;
+ while(NULL != (li = (itadmin_license *)dk3sto_it_next(us->i_li))) {
+ if(li->host) {
+ pman = itadmin_license_get_manufacturer(li);
+ pprod = itadmin_license_get_product(li);
+ switch(itadmin_license_change_level(pman,prev_man,pprod,prev_prod))
+ {
+ case 2: { /* Manufacturer changed */
+ if(have_tab) {
+ itadmin_license_end_longtable_for_licenses(job, os);
+ } have_tab = 0;
+ if(!(have_chap)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[28]);
+ itadmin_tool_write_user_latex_short(job, os, us);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[29]);
+ itadmin_tool_write_user_latex_long(job, os, us);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ } have_chap = 1;
+ if(!(have_sec)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[30]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[62], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[29]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[63], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[67], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[68], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[69], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[26]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[31]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[70], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[32]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[71], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[72], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[73], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[74], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[75], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ } have_sec = 1;
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[9]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, pman);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[10]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, pprod);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ } break;
+ case 1: { /* Product changed */
+ if(have_tab) {
+ itadmin_license_end_longtable_for_licenses(job, os);
+ } have_tab = 0;
+ if(!(have_chap)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[28]);
+ itadmin_tool_write_user_latex_short(job, os, us);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[29]);
+ itadmin_tool_write_user_latex_long(job, os, us);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ } have_chap = 1;
+ if(!(have_sec)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[30]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[62], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[29]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[63], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[67], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[68], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[69], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[26]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[31]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[70], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[32]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[71], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[72], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[73], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[74], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[75], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ } have_sec = 1;
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[10]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, pprod);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ } break;
+ default: {
+ if(have_tab) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[23]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ }
+ } break;
+ }
+ if(!(have_tab)) {
+ itadmin_license_start_longtable_for_licenses(job, os);
+ have_tab = 1;
+ }
+ itadmin_license_write_license(job, os, li, pman, pprod, 0, 0, 0, 1, 1);
+ prev_man = pman; prev_prod = pprod;
+ }
+ }
+ if(have_tab) {
+ itadmin_license_end_longtable_for_licenses(job, os);
+ }
+ if(have_sec) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[6]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ }
+ }
+ }
+
+#line 1117 "italic.ctr"
+}
+
+
+
+/** Write complete list of licenses.
+ @param job Job structure.
+ @param os Output stream.
+*/
+static
+void
+itadmin_license_write_complete_list(itadmin_job *job, dk3_stream_t *os)
+{
+ itadmin_license *li;
+ char const *pman;
+ char const *pprod;
+ int have_tab = 0;
+ int ie;
+ ie = dk3app_get_encoding(job->app);
+ dk3sto_it_reset(job->i_lc);
+ while(NULL != (li = (itadmin_license *)dk3sto_it_next(job->i_lc))) {
+ if(!(have_tab)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[4]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[59], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ itadmin_license_start_longtable_for_licenses(job, os);
+ } else {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[23]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ }
+ have_tab = 1;
+ pman = itadmin_license_get_manufacturer(li);
+ pprod = itadmin_license_get_product(li);
+ itadmin_license_write_license(job, os, li, pman, pprod, 1, 1, 1, 1, 1);
+ }
+ if(have_tab) {
+ itadmin_license_end_longtable_for_licenses(job, os);
+ }
+}
+
+
+
+/** Write license report to file.
+ @param job Job structure.
+ @param os Output stream.
+*/
+static
+void
+itadmin_license_write_file(itadmin_job *job, dk3_stream_t *os)
+{
+ int ie;
+ ie = dk3app_get_encoding(job->app);
+ if(job->ukoma) {
+ itadmin_tool_write_section(job, os, itadmin_license_file_start1a);
+ } else {
+ itadmin_tool_write_section(job, os, itadmin_license_file_start1b);
+ }
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_strputs(os, (job->msg)[2], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ itadmin_tool_write_section(job, os, itadmin_license_file_start4);
+ /* pdftitle */
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[11]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[51], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[17]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ /* pdfsubject */
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[12]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[52], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[17]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ /* pdfauthor */
+ if(job->admn) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[13]);
+ dk3uc2lat_stputs(job->uc2l, os, job->admn, ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[17]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ }
+ /* pdfcreator */
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[14]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ itadmin_tool_write_section(job, os, itadmin_license_file_start2);
+ /* author */
+ if(job->admn) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[15]);
+ dk3uc2lat_stputs(job->uc2l, os, job->admn, ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ }
+ /* title */
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[16]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[51], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ if(job->ukoma) {
+ itadmin_tool_write_section(job, os, itadmin_license_file_start3a);
+ }
+ itadmin_tool_write_section(job, os, itadmin_license_file_start3);
+ itadmin_license_write_available(job, os);
+ itadmin_license_write_user(job, os);
+ itadmin_license_write_complete_list(job, os);
+ dk3uc2lat_final_report(job->uc2l, os);
+ itadmin_tool_write_section(job, os, itadmin_license_file_end);
+}
+
+
+
+int
+itadmin_license_report(itadmin_job *job)
+{
+ FILE *fipo;
+ dk3_stream_t *os;
+ int back = 0;
+
+
+#line 1234 "italic.ctr"
+ fipo = dk3sf_c8_fopen_app(
+ itadmin_license_c8_kw[2],
+ itadmin_license_c8_kw[3],
+ job->app
+ );
+ if(fipo) {
+ os = dk3stream_open_file_app(fipo, DK3_STREAM_FLAG_WRITE, job->app);
+ if(os) {
+ back = 1;
+ itadmin_license_write_file(job, os);
+ dk3stream_close(os);
+ }
+#if DK3_CHAR_SIZE == 1
+ if(!dk3sf_fclose_fn_app(fipo, itadmin_license_c8_kw[2], job->app)) {
+ back = 0;
+ }
+#else
+ if(!dk3sf_fclose_fn_app(fipo, NULL, job->app)) {
+ back = 0;
+ }
+#endif
+ }
+
+
+#line 1257 "italic.ctr"
+ return back;
+}
+
+
diff --git a/support/dktools/italic.ctr b/support/dktools/italic.ctr
new file mode 100644
index 0000000000..97041e63bf
--- /dev/null
+++ b/support/dktools/italic.ctr
@@ -0,0 +1,1260 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+
+%% module
+
+#include "dk3all.h"
+#include "itadmin.h"
+
+
+
+$!trace-include
+
+
+
+/** Keywords used by the module.
+*/
+static char const * const itadmin_license_c8_kw[] = {
+$!string-table
+#
+# 0: Newline
+#
+\n
+#
+# 1: Space
+#
+
+#
+# 2: File name for license report
+#
+licenses.tex
+#
+# 3: File open mode: write
+#
+w
+#
+# 4: Opening a chapter
+#
+\\chapter{
+#
+# 5: Ending a LaTeX command
+#
+}
+#
+# 6: Clearpage command
+#
+\\clearpage
+#
+# 7: End long table
+#
+\\\\\n\\end{longtable}
+#
+# 8: Section
+#
+\\section{
+#
+# 9: Subsection
+#
+\\subsection{
+#
+# 10: Subsubsection
+#
+\\subsubsection{
+#
+# 11:
+#
+pdftitle={
+#
+# 12:
+#
+pdfsubject={
+#
+# 13:
+#
+pdfauthor={
+#
+# 14:
+#
+pdfcreator={itadmin - http://dktools.sourceforge.net/}
+#
+# 15:
+#
+\\author{
+#
+# 16:
+#
+\\title{
+#
+# 17: Comma
+#
+,
+#
+# 18: Begin long table
+#
+\\begin{longtable}{lll}
+#
+# 19
+#
+\\endfirsthead
+#
+# 20
+#
+\\endhead
+#
+# 21
+#
+\\endfoot
+#
+# 22
+#
+\\endlastfoot
+#
+# 23
+#
+\\\\[0.5em]
+#
+# 24
+#
+&
+#
+# 25
+#
+\\multicolumn{2}{l}{
+#
+# 26
+#
+\\\\*
+#
+# 27
+#
+\\textit{
+#
+# 28
+#
+\\chapter[
+#
+# 29
+#
+]{
+#
+# 30
+#
+\\section[
+#
+# 31
+#
+\\emph{
+#
+# 32
+#
+\\/}
+$!end
+};
+
+
+
+/** Start of LaTeX source.
+*/
+static char const * const itadmin_license_file_start1a[] = {
+$!text
+\documentclass[titlepage,origlongtable]{scrbook}
+\KOMAoptions{paper=a4}
+\KOMAoptions{fontsize=12pt}
+$!end
+};
+
+
+
+/** Start of LaTeX source.
+*/
+static char const * const itadmin_license_file_start1b[] = {
+$!text
+\documentclass[12pt]{book}
+$!end
+};
+
+
+/** LaTeX packages after ngerman.
+*/
+static char const * const itadmin_license_file_start4[] = {
+$!text
+\usepackage{ifpdf}
+\usepackage[utf8]{inputenc}
+\usepackage{mathptmx}
+\usepackage[scaled=.92]{helvet}
+\usepackage{courier}
+\usepackage[T1]{fontenc}
+\usepackage{textcomp}
+\usepackage{latexsym}
+\usepackage{varioref}
+\usepackage{color}
+\usepackage{makeidx}
+\usepackage{longtable}
+\makeindex
+\ifpdf
+\usepackage[activate=normal]{pdfcprot}
+\pdfcompresslevel=9
+\usepackage[
+pdftex,
+colorlinks=true,
+pdfpagemode=UseNone,
+pdfstartview={XYZ 0 835 1.25},
+bookmarksnumbered,
+$!end
+};
+
+
+
+/** LaTeX package after hyperref options for title, subject, author.
+*/
+static char const * const itadmin_license_file_start2[] = {
+$!text
+]{hyperref}
+\else
+\usepackage[dvips,colorlinks=true,linkcolor=black]{hyperref}
+\fi
+\parindent0cm
+$!end
+};
+
+
+
+/** Renewcommand used only for koma-script.
+*/
+static char const * const itadmin_license_file_start3a[] = {
+$!text
+\renewcommand*{\sectfont}{\bfseries}
+$!end
+};
+
+
+
+/** Final commands after title and author.
+*/
+static char const * const itadmin_license_file_start3[] = {
+$!text
+\setcounter{secnumdepth}{1}
+\begin{document}
+$!end
+};
+
+
+
+/** LaTeX file end.
+*/
+static char const * const itadmin_license_file_end[] = {
+$!text
+\end{document}
+$!end
+};
+
+
+
+/** Write data for one license.
+ @param job Job structure.
+ @param os Output stream.
+ @param lic License to write.
+*/
+static
+void
+itadmin_license_write_license_type(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ itadmin_license *lic
+)
+{
+ char const *ltn;
+ int ie;
+ ltn = NULL;
+ if(lic->ltype) {
+ ltn = (lic->ltype)->sn;
+ if((lic->ltype)->ln) {
+ ltn = (lic->ltype)->ln;
+ }
+ }
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[25]);
+ if(ltn) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, ltn);
+ } else {
+ ie = dk3app_get_encoding(job->app);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[53], ie);
+ }
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+}
+
+
+
+/** Check whether we must write the license owner because the host owner
+ differs from the license owner.
+ @param user License owner.
+ @param host Host on which the license is used.
+ @return 1 if host and license owner differ, 0 if they match.
+*/
+static
+int
+itadmin_license_must_write_license_owner(itadmin_user *user, itadmin_host *host)
+{
+ int back = 0;
+ if(user) {
+ if(user->us) {
+ if(host) {
+ if(host->un) {
+ if((host->un)->us) {
+ if(dk3str_c8_cmp(user->us, (host->un)->us)) {
+ back = 1;
+ }
+ }
+ } else {
+ }
+ } else {
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Check whether we must write the host owner because the host owner
+ differs from the license owner.
+ @param user License owner.
+ @param host Host on which the license is used.
+ @return 1 if host and license owner differ, 0 if they match.
+*/
+static
+int
+itadmin_license_must_write_host_owner(itadmin_user *user, itadmin_host *host)
+{
+ int back = 0;
+ if(host) {
+ if(host->un) {
+ if(user) {
+ if((host->un)->us) {
+ if(user->us) {
+ if(dk3str_c8_cmp((host->un)->us, user->us)) {
+ back = 1;
+ }
+ } else {
+ back = 1;
+ }
+ }
+ } else {
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Write data for one license.
+ @param job Job structure.
+ @param os Output stream.
+ @param lic License to write.
+ @param pman Software manufacturuer name.
+ @param pprod Software product name.
+ @param mn Flag: Write software manufacturer name.
+ @param pn Flag: Write software product name.
+ @param un Flag: Write user name who owns the license.
+ @param hn Flag: Write host name where license is used.
+ @param ond On difference between license owner and host owner:
+ 0=do nothing, 1=write host owner, 2=write license owner
+*/
+static
+void
+itadmin_license_write_license(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ itadmin_license *lic,
+ char const *pman,
+ char const *pprod,
+ int mn,
+ int pn,
+ int un,
+ int hn,
+ int ond
+)
+{
+ char bu[128];
+ int ie;
+ ie = dk3app_get_encoding(job->app);
+ sprintf(bu, "%lu", lic->pk);
+ dk3stream_c8_fputs(os, bu);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ if((mn) && (pman)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[25]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, pman);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ if((pn) && (pprod)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[26]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[25]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, pprod);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ }
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[26]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ itadmin_license_write_license_type(job, os, lic);
+ } else {
+ if((pn) && (pprod)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[25]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, pprod);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[26]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ itadmin_license_write_license_type(job, os, lic);
+ } else {
+ itadmin_license_write_license_type(job, os, lic);
+ }
+ }
+ if(lic->notes) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[26]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[25]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, lic->notes);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ }
+ if(un) {
+ if(lic->owner) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[26]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[25]);
+ itadmin_tool_write_user_latex_long(job, os, lic->owner);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ }
+ }
+ if(hn) {
+ if(lic->host) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[26]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ if((lic->host)->sn) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, (lic->host)->sn);
+ }
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ if((lic->host)->co) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, (lic->host)->co);
+ }
+ switch(ond) {
+ case 1: { /* On difference write host owner. */
+ if(itadmin_license_must_write_host_owner(lic->owner, lic->host)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[26]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[25]);
+ if(mn) { dk3stream_c8_fputs(os, itadmin_license_c8_kw[27]); }
+ itadmin_tool_write_user_latex_long(job, os, (lic->host)->un);
+ if(mn) { dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]); }
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ }
+ } break;
+ case 2: { /* On difference write license owner. */
+ if(itadmin_license_must_write_license_owner(lic->owner, lic->host)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[26]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[25]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[27]);
+ itadmin_tool_write_user_latex_long(job, os, lic->owner);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ }
+ } break;
+ }
+ }
+ } else {
+ if((lic->host) && (lic->owner)) {
+ switch(ond) {
+ case 1: {
+ if(itadmin_license_must_write_host_owner(lic->owner, lic->host)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[26]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[25]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[27]);
+ itadmin_tool_write_user_latex_long(job, os, (lic->host)->un);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ }
+ } break;
+ case 2: {
+ if(itadmin_license_must_write_license_owner(lic->owner, lic->host)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[26]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[25]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[27]);
+ itadmin_tool_write_user_latex_long(job, os, lic->owner);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ }
+ } break;
+ }
+ }
+ }
+ if(lic->order) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[26]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[54], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, lic->order);
+ }
+ if(((lic->d_del).d) && ((lic->d_del).m) && ((lic->d_del).y)) {
+ if(job->gdate) {
+ sprintf(
+ bu, "%02d.%02d.%04d", (lic->d_del).d, (lic->d_del).m, (lic->d_del).y
+ );
+ } else {
+ sprintf(
+ bu, "%04d-%02d-%02d", (lic->d_del).y, (lic->d_del).m, (lic->d_del).d
+ );
+ }
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[26]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[55], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ dk3stream_c8_fputs(os, bu);
+ }
+ if(lic->i_del) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[26]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[56], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, lic->i_del);
+ }
+ if(((lic->d_inv).d) && ((lic->d_inv).m) && ((lic->d_inv).y)) {
+ if(job->gdate) {
+ sprintf(
+ bu, "%02d.%02d.%04d", (lic->d_inv).d, (lic->d_inv).m, (lic->d_inv).y
+ );
+ } else {
+ sprintf(
+ bu, "%04d-%02d-%02d", (lic->d_inv).y, (lic->d_inv).m, (lic->d_inv).d
+ );
+ }
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[26]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[57], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ dk3stream_c8_fputs(os, bu);
+ }
+ if(lic->i_inv) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[26]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[58], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[24]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, lic->i_inv);
+ }
+}
+
+
+
+/** Get software manufacturer name.
+ @param li License
+ @return Software manufacturer name on success, NULL on error.
+*/
+static
+char const *
+itadmin_license_get_manufacturer(itadmin_license *li)
+{
+ char const *back = NULL;
+ if(li->prod) {
+ if((li->prod)->mn) {
+ back = ((li->prod)->mn)->sn;
+ if(((li->prod)->mn)->ln) {
+ back = ((li->prod)->mn)->ln;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Get software product name.
+ @param li License.
+ @return Product name on success, NULL on error.
+*/
+static
+char const *
+itadmin_license_get_product(itadmin_license *li)
+{
+ char const *back = NULL;
+ if(li->prod) {
+ back = (li->prod)->sn;
+ if((li->prod)->ln) {
+ back = (li->prod)->ln;
+ }
+ }
+ return back;
+}
+
+
+
+/** Check whether manufacturer and/or product have changed.
+ @param pman
+ @param prev_man
+ @param pprod
+ @param prev_prod
+ @return 0=no change, 1=product change, 2=manufacturer change.
+*/
+static
+int
+itadmin_license_change_level(
+ char const *pman,
+ char const *prev_man,
+ char const *pprod,
+ char const *prev_prod
+)
+{
+ int back = 0;
+ $? "+ itadmin_license_change_level \"%!8s\"=\"%!8s\" \"%!8s\"=\"%!8s\"", TR_8STR(pman), TR_8STR(prev_man), TR_8STR(pprod), TR_8STR(prev_prod)
+ if(pprod) {
+ if(prev_prod) {
+ if(dk3str_c8_cmp(pprod, prev_prod)) {
+ back = 1;
+ }
+ } else { back = 1; }
+ } else {
+ if(prev_prod) { back = 1; }
+ }
+ if(pman) {
+ if(prev_man) {
+ if(dk3str_c8_cmp(pman, prev_man)) {
+ back = 2;
+ }
+ } else { back = 2; }
+ } else {
+ if(prev_man) { back = 2; }
+ } $? "- itadmin_license_change_level %d", back
+ return back;
+}
+
+
+
+/** Start a longtable for the licenses.
+ @param job Job structure.
+ @param os Output stream.
+*/
+static
+void
+itadmin_license_start_longtable_for_licenses(
+ itadmin_job *job,
+ dk3_stream_t *os
+)
+{
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[18]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[19]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[20]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[21]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[22]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+}
+
+
+
+/** End a longtable for the licenses.
+ @param job Job structure.
+ @param os Output stream.
+*/
+static
+void
+itadmin_license_end_longtable_for_licenses(
+ itadmin_job *job,
+ dk3_stream_t *os
+)
+{
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[7]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+}
+
+
+
+/** Write available licenses.
+ @param job Job structure.
+ @param os Output stream.
+*/
+static
+void
+itadmin_license_write_available(itadmin_job *job, dk3_stream_t *os)
+{
+ itadmin_license *li; /* Current license to print. */
+ char const *prev_man; /* Previous software manufacturer. */
+ char const *prev_prod; /* Previous software product. */
+ char const *pman; /* Current software manufacturer. */
+ char const *pprod; /* Current software product. */
+ int have_chap; /* Flag: Chapter was started. */
+ int have_tab; /* Flag: Table was started. */
+ int ie; /* Input encoding. */
+ $? "+ itadmin_license_write_available"
+ ie = dk3app_get_encoding(job->app);
+ have_chap = have_tab = 0;
+ prev_man = NULL; prev_prod = NULL;
+ dk3sto_it_reset(job->i_lf);
+ while(NULL != (li = (itadmin_license *)dk3sto_it_next(job->i_lf))) {
+ if(!(have_chap)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[4]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[48], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[49], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[50], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ } have_chap = 1;
+ pman = itadmin_license_get_manufacturer(li); $? ". pman = \"%!8s\"", TR_8STR(pman)
+ pprod = itadmin_license_get_product(li); $? ". pprod = \"%!8s\"", TR_8STR(pprod)
+ switch(itadmin_license_change_level(pman, prev_man, pprod, prev_prod)) {
+ case 2: { /* Manufacturer changed. */
+ if(have_tab) {
+ itadmin_license_end_longtable_for_licenses(job, os);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[6]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ }
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[8]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, pman);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[9]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, pprod);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ have_tab = 0;
+ } break;
+ case 1: { /* Product changed. */
+ if(have_tab) {
+ itadmin_license_end_longtable_for_licenses(job, os);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[6]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ }
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[9]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, pprod);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ have_tab = 0;
+ } break;
+ default: { /* No change. */
+ if(have_tab) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[23]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ }
+ } break;
+ }
+ if(!(have_tab)) {
+ itadmin_license_start_longtable_for_licenses(job, os);
+ have_tab = 1;
+ }
+ itadmin_license_write_license(job, os, li, pman, pprod, 0, 0, 0, 0, 0);
+ prev_man = pman; prev_prod = pprod;
+ }
+ if(have_chap) {
+ if(have_tab) {
+ /* end{longtable} */
+ itadmin_license_end_longtable_for_licenses(job, os);
+ }
+ /* clearpage */
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[6]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ } $? "- itadmin_license_write_available"
+}
+
+
+
+/** Write license report per user/host.
+ @param job Job structure.
+ @param os Output stream.
+*/
+static
+void
+itadmin_license_write_user(itadmin_job *job, dk3_stream_t *os)
+{
+ itadmin_user *us;
+ itadmin_host *ho;
+ itadmin_license *li;
+ char const *pman;
+ char const *pprod;
+ char const *prev_man;
+ char const *prev_prod;
+ int have_chap;
+ int have_sec;
+#if VERSION_BEFORE_20150821
+ int have_subsec;
+#endif
+ int have_tab;
+ int ie;
+ $? "+ itadmin_license_write_user"
+ ie = dk3app_get_encoding(job->app);
+ dk3sto_it_reset(job->i_us);
+ while(NULL != (us = (itadmin_user *)dk3sto_it_next(job->i_us))) {
+ have_chap = 0;
+#if VERSION_BEFORE_20150821
+ have_sec = 0;
+#endif
+#if VERSION_BEFORE_20150821
+ have_subsec = 0;
+#endif
+#if VERSION_BEFORE_20150821
+ have_tab = 0;
+#endif
+ /*
+ Licenses on hosts
+ */
+ if(us->i_ho) {
+ dk3sto_it_reset(us->i_ho);
+ while(NULL != (ho = (itadmin_host *)dk3sto_it_next(us->i_ho))) {
+ have_sec = 0;
+#if VERSION_BEFORE_20150821
+ have_subsec = 0;
+#endif
+ if(ho->i_li) {
+ prev_man = NULL;
+ prev_prod = NULL;
+ have_tab = 0;
+ dk3sto_it_reset(ho->i_li);
+ while(NULL != (li = (itadmin_license *)dk3sto_it_next(ho->i_li))) {
+ pman = itadmin_license_get_manufacturer(li);
+ pprod = itadmin_license_get_product(li);
+ switch(itadmin_license_change_level(pman,prev_man,pprod,prev_prod))
+ {
+ case 2: { /* Manufacturer changed. */
+ if(have_tab) {
+ itadmin_license_end_longtable_for_licenses(job, os);
+ } have_tab = 0;
+ if(!(have_chap)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[28]);
+ itadmin_tool_write_user_latex_short(job, os, us);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[29]);
+ itadmin_tool_write_user_latex_long(job, os, us);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ } have_chap = 1;
+ if(!(have_sec)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[8]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, ho->sn);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ } have_sec = 1;
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[9]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, pman);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ } break;
+ default: { /* Manufacturer unchanged. */
+ if(have_tab) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[23]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ }
+ } break;
+ }
+ if(!(have_tab)) {
+ itadmin_license_start_longtable_for_licenses(job, os);
+ have_tab = 1;
+ }
+ itadmin_license_write_license(job, os, li, pman, pprod, 0, 1, 0, 0, 2);
+ prev_man = pman; prev_prod = pprod;
+ }
+ if(have_tab) {
+ itadmin_license_end_longtable_for_licenses(job, os);
+ }
+ if(have_sec) {
+ /* clearpage */
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[6]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ }
+ }
+ }
+ }
+ if(us->i_li) {
+ /*
+ Licenses not assigned to hosts
+ */
+ have_sec = 0; have_tab = 0;
+ dk3sto_it_reset(us->i_li);
+ prev_man = NULL; prev_prod = NULL;
+ while(NULL != (li = (itadmin_license *)dk3sto_it_next(us->i_li))) {
+ if(!(li->host)) {
+ pman = itadmin_license_get_manufacturer(li);
+ pprod = itadmin_license_get_product(li);
+ switch(itadmin_license_change_level(pman,prev_man,pprod,prev_prod))
+ {
+ case 2: { /* Manufacturer changed */
+ if(have_tab) {
+ itadmin_license_end_longtable_for_licenses(job, os);
+ } have_tab = 0;
+ if(!(have_chap)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[28]);
+ itadmin_tool_write_user_latex_short(job, os, us);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[29]);
+ itadmin_tool_write_user_latex_long(job, os, us);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ } have_chap = 1;
+ if(!(have_sec)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[30]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[60], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[29]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[61], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[64], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[65], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[66], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ } have_sec = 1;
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[9]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, pman);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[10]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, pprod);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ } break;
+ case 1: { /* Product changed */
+ if(have_tab) {
+ itadmin_license_end_longtable_for_licenses(job, os);
+ } have_tab = 0;
+ if(!(have_chap)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[28]);
+ itadmin_tool_write_user_latex_short(job, os, us);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[29]);
+ itadmin_tool_write_user_latex_long(job, os, us);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ } have_chap = 1;
+ if(!(have_sec)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[30]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[60], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[29]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[61], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[64], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[65], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[66], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ } have_sec = 1;
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[10]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, pprod);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ } break;
+ default: {
+ if(have_tab) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[23]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ }
+ } break;
+ }
+ if(!(have_tab)) {
+ itadmin_license_start_longtable_for_licenses(job, os);
+ have_tab = 1;
+ }
+ itadmin_license_write_license(job, os, li, pman, pprod, 0, 0, 0, 0, 0);
+ prev_man = pman; prev_prod = pprod;
+ }
+ }
+ if(have_tab) {
+ itadmin_license_end_longtable_for_licenses(job, os);
+ }
+ if(have_sec) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[6]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ }
+ /*
+ Licenses used on other users computers
+ */
+ have_sec = 0; have_tab = 0;
+ dk3sto_it_reset(us->i_li);
+ prev_man = NULL; prev_prod = NULL;
+ while(NULL != (li = (itadmin_license *)dk3sto_it_next(us->i_li))) {
+ if(li->host) {
+ pman = itadmin_license_get_manufacturer(li);
+ pprod = itadmin_license_get_product(li);
+ switch(itadmin_license_change_level(pman,prev_man,pprod,prev_prod))
+ {
+ case 2: { /* Manufacturer changed */
+ if(have_tab) {
+ itadmin_license_end_longtable_for_licenses(job, os);
+ } have_tab = 0;
+ if(!(have_chap)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[28]);
+ itadmin_tool_write_user_latex_short(job, os, us);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[29]);
+ itadmin_tool_write_user_latex_long(job, os, us);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ } have_chap = 1;
+ if(!(have_sec)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[30]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[62], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[29]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[63], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[67], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[68], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[69], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[26]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[31]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[70], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[32]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[71], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[72], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[73], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[74], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[75], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ } have_sec = 1;
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[9]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, pman);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[10]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, pprod);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ } break;
+ case 1: { /* Product changed */
+ if(have_tab) {
+ itadmin_license_end_longtable_for_licenses(job, os);
+ } have_tab = 0;
+ if(!(have_chap)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[28]);
+ itadmin_tool_write_user_latex_short(job, os, us);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[29]);
+ itadmin_tool_write_user_latex_long(job, os, us);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ } have_chap = 1;
+ if(!(have_sec)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[30]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[62], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[29]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[63], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[67], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[68], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[69], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[26]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[31]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[70], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[32]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[71], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[72], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[73], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[74], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[75], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ } have_sec = 1;
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[10]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, pprod);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ } break;
+ default: {
+ if(have_tab) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[23]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ }
+ } break;
+ }
+ if(!(have_tab)) {
+ itadmin_license_start_longtable_for_licenses(job, os);
+ have_tab = 1;
+ }
+ itadmin_license_write_license(job, os, li, pman, pprod, 0, 0, 0, 1, 1);
+ prev_man = pman; prev_prod = pprod;
+ }
+ }
+ if(have_tab) {
+ itadmin_license_end_longtable_for_licenses(job, os);
+ }
+ if(have_sec) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[6]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ }
+ }
+ } $? "- itadmin_license_write_user"
+}
+
+
+
+/** Write complete list of licenses.
+ @param job Job structure.
+ @param os Output stream.
+*/
+static
+void
+itadmin_license_write_complete_list(itadmin_job *job, dk3_stream_t *os)
+{
+ itadmin_license *li;
+ char const *pman;
+ char const *pprod;
+ int have_tab = 0;
+ int ie;
+ ie = dk3app_get_encoding(job->app);
+ dk3sto_it_reset(job->i_lc);
+ while(NULL != (li = (itadmin_license *)dk3sto_it_next(job->i_lc))) {
+ if(!(have_tab)) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[4]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[59], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ itadmin_license_start_longtable_for_licenses(job, os);
+ } else {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[23]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ }
+ have_tab = 1;
+ pman = itadmin_license_get_manufacturer(li);
+ pprod = itadmin_license_get_product(li);
+ itadmin_license_write_license(job, os, li, pman, pprod, 1, 1, 1, 1, 1);
+ }
+ if(have_tab) {
+ itadmin_license_end_longtable_for_licenses(job, os);
+ }
+}
+
+
+
+/** Write license report to file.
+ @param job Job structure.
+ @param os Output stream.
+*/
+static
+void
+itadmin_license_write_file(itadmin_job *job, dk3_stream_t *os)
+{
+ int ie;
+ ie = dk3app_get_encoding(job->app);
+ if(job->ukoma) {
+ itadmin_tool_write_section(job, os, itadmin_license_file_start1a);
+ } else {
+ itadmin_tool_write_section(job, os, itadmin_license_file_start1b);
+ }
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ dk3stream_strputs(os, (job->msg)[2], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ itadmin_tool_write_section(job, os, itadmin_license_file_start4);
+ /* pdftitle */
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[11]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[51], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[17]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ /* pdfsubject */
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[12]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[52], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[17]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ /* pdfauthor */
+ if(job->admn) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[13]);
+ dk3uc2lat_stputs(job->uc2l, os, job->admn, ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[17]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ }
+ /* pdfcreator */
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[14]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ itadmin_tool_write_section(job, os, itadmin_license_file_start2);
+ /* author */
+ if(job->admn) {
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[15]);
+ dk3uc2lat_stputs(job->uc2l, os, job->admn, ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ }
+ /* title */
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[16]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[51], ie);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_license_c8_kw[0]);
+ if(job->ukoma) {
+ itadmin_tool_write_section(job, os, itadmin_license_file_start3a);
+ }
+ itadmin_tool_write_section(job, os, itadmin_license_file_start3);
+ itadmin_license_write_available(job, os);
+ itadmin_license_write_user(job, os);
+ itadmin_license_write_complete_list(job, os);
+ dk3uc2lat_final_report(job->uc2l, os);
+ itadmin_tool_write_section(job, os, itadmin_license_file_end);
+}
+
+
+
+int
+itadmin_license_report(itadmin_job *job)
+{
+ FILE *fipo;
+ dk3_stream_t *os;
+ int back = 0;
+ $? "+ itadmin_license_report"
+ fipo = dk3sf_c8_fopen_app(
+ itadmin_license_c8_kw[2],
+ itadmin_license_c8_kw[3],
+ job->app
+ );
+ if(fipo) {
+ os = dk3stream_open_file_app(fipo, DK3_STREAM_FLAG_WRITE, job->app);
+ if(os) {
+ back = 1;
+ itadmin_license_write_file(job, os);
+ dk3stream_close(os);
+ }
+#if DK3_CHAR_SIZE == 1
+ if(!dk3sf_fclose_fn_app(fipo, itadmin_license_c8_kw[2], job->app)) {
+ back = 0;
+ }
+#else
+ if(!dk3sf_fclose_fn_app(fipo, NULL, job->app)) {
+ back = 0;
+ }
+#endif
+ }
+ $? "- itadmin_license_report %d", back
+ return back;
+}
+
+
diff --git a/support/dktools/itamem.c b/support/dktools/itamem.c
new file mode 100644
index 0000000000..13afbfeff8
--- /dev/null
+++ b/support/dktools/itamem.c
@@ -0,0 +1,1721 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: itamem.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file itamem.c The itamem module.
+*/
+
+
+#line 10 "itamem.ctr"
+
+#include "dk3all.h"
+#include "itadmin.h"
+
+
+
+
+
+#line 17 "itamem.ctr"
+
+
+
+
+
+#line 21 "itamem.ctr"
+
+
+#line 22 "itamem.ctr"
+
+
+#line 23 "itamem.ctr"
+
+
+#line 24 "itamem.ctr"
+
+
+
+void
+itadmin_mem_date_init(itadmin_date *dp)
+{
+ dp->y = 0;
+ dp->m = 0;
+ dp->d = 0;
+}
+
+
+
+void
+itadmin_mem_date_copy(itadmin_date *dp, itadmin_date *sp)
+{
+ dp->y = sp->y;
+ dp->m = sp->m;
+ dp->d = sp->d;
+}
+
+
+
+void
+itadmin_mem_user_del(void *v)
+{
+ itadmin_user *u;
+
+
+#line 52 "itamem.ctr"
+ if(v) {
+ u = (itadmin_user *)v;
+
+#line 54 "itamem.ctr"
+ dk3_release(u->us);
+ dk3_release(u->tt);
+ dk3_release(u->sn);
+ dk3_release(u->na);
+ dk3_release(u->em);
+ dk3_release(u->cc);
+ dk3_release(u->si);
+ if(u->s_ho) {
+ if(u->i_ho) {
+ dk3sto_it_close(u->i_ho);
+ }
+ dk3sto_close(u->s_ho);
+ }
+ u->s_ho = NULL; u->i_ho = NULL;
+ if(u->s_li) {
+ if(u->i_li) {
+ dk3sto_it_close(u->i_li);
+ }
+ dk3sto_close(u->s_li);
+ }
+ u->s_li = NULL; u->i_li = NULL;
+ dk3_delete(v);
+ }
+
+#line 77 "itamem.ctr"
+}
+
+
+
+void
+itadmin_mem_building_del(void *v)
+{
+ itadmin_building *b;
+
+
+#line 86 "itamem.ctr"
+ if(v) {
+ b = (itadmin_building *)v;
+
+#line 88 "itamem.ctr"
+ dk3_release(b->s);
+ dk3_release(b->l);
+ dk3_release(b->a1);
+ dk3_release(b->a2);
+ dk3_release(b->a3);
+ dk3_release(b->a4);
+ dk3_release(b->zc);
+ dk3_release(b->city);
+ dk3_delete(v);
+ }
+
+#line 98 "itamem.ctr"
+}
+
+
+
+void
+itadmin_mem_speed_del(void *v)
+{
+ itadmin_speed *s;
+
+
+#line 107 "itamem.ctr"
+ if(v) {
+ s = (itadmin_speed *)v;
+
+#line 109 "itamem.ctr"
+ dk3_release(s->s);
+ dk3_release(s->l);
+ dk3_delete(v);
+ }
+
+#line 113 "itamem.ctr"
+}
+
+
+
+void
+itadmin_mem_vlan_del(void *v)
+{
+ itadmin_vlan *l;
+ itadmin_dhcp_option *d;
+
+
+#line 123 "itamem.ctr"
+ if(v) {
+ l = (itadmin_vlan *)v;
+
+#line 125 "itamem.ctr"
+ dk3_release(l->s);
+ dk3_release(l->l);
+ if(l->s_nw) {
+ if(l->i_nw) {
+ dk3sto_it_close(l->i_nw);
+ }
+ dk3sto_close(l->s_nw);
+ }
+ l->s_nw = NULL; l->i_nw = NULL;
+ if(l->s_do) {
+ if(l->i_do) {
+ dk3sto_it_reset(l->i_do);
+ while(NULL != (d = (itadmin_dhcp_option *)dk3sto_it_next(l->i_do))) {
+ itadmin_mem_dhcp_option_del((void *)d);
+ }
+ dk3sto_it_close(l->i_do);
+ }
+ dk3sto_close(l->s_do);
+ }
+ l->s_do = NULL; l->i_do = NULL;
+ dk3_delete(v);
+ }
+
+#line 147 "itamem.ctr"
+}
+
+
+
+void
+itadmin_mem_connect_del(void *v)
+{
+ itadmin_connect *c;
+
+
+#line 156 "itamem.ctr"
+ if(v) {
+ c = (itadmin_connect *)v;
+
+#line 158 "itamem.ctr"
+ dk3_release(c->s);
+ dk3_release(c->hp);
+ dk3_release(c->room);
+ c->sp = NULL; c->vl = NULL; c->bu = NULL;
+ dk3_delete(v);
+ }
+
+#line 164 "itamem.ctr"
+}
+
+
+
+void
+itadmin_mem_dhcp_ginw_del(itadmin_dhcp_ginw *g)
+{
+ if(g) {
+ g->gr = NULL;
+ if(g->s_h) {
+ if(g->i_h) {
+ dk3sto_it_close(g->i_h);
+ }
+ dk3sto_close(g->s_h);
+ }
+ g->s_h = NULL; g->i_h = NULL;
+ dk3_delete(g);
+ }
+}
+
+
+
+void
+itadmin_mem_network_del(void *v)
+{
+ itadmin_network *n;
+ itadmin_dhcp_ginw *ginw;
+ void *vp;
+
+
+#line 193 "itamem.ctr"
+ if(v) {
+ n = (itadmin_network *)v;
+
+#line 195 "itamem.ctr"
+ n->ip4 = 0UL;
+
+#line 196 "itamem.ctr"
+ n->ma4 = 0UL;
+
+#line 197 "itamem.ctr"
+ n->gw4 = 0UL;
+
+#line 198 "itamem.ctr"
+ n->bc4 = 0UL;
+ n->vl = NULL;
+ if(n->s_dg) {
+ if(n->i_dg) {
+ dk3sto_it_reset(n->i_dg);
+ while(NULL != (ginw = (itadmin_dhcp_ginw *)dk3sto_it_next(n->i_dg))) {
+ itadmin_mem_dhcp_ginw_del(ginw);
+ }
+ dk3sto_it_close(n->i_dg);
+ }
+ dk3sto_close(n->s_dg);
+ }
+ n->s_dg = NULL; n->i_dg = NULL;
+ if(n->s_p) {
+ if(n->i_p) {
+ dk3sto_it_close(n->i_p);
+ }
+ dk3sto_close(n->s_p);
+ }
+ n->s_p = NULL; n->i_p = NULL;
+ if(n->s_do) {
+ if(n->i_do) {
+ dk3sto_it_reset(n->i_do);
+ while(NULL != (vp = dk3sto_it_next(n->i_do))) {
+ itadmin_mem_dhcp_option_del(vp);
+ }
+ dk3sto_it_close(n->i_do);
+ }
+ dk3sto_close(n->s_do);
+ }
+ n->s_do = NULL; n->i_do = NULL;
+ if(n->s_hoi) {
+ if(n->i_hoi) {
+ dk3sto_it_close(n->i_hoi);
+ }
+ dk3sto_close(n->s_hoi);
+ }
+ n->s_hoi = NULL; n->i_hoi = NULL;
+ if(n->s_dc) {
+ if(n->i_dc) {
+ dk3sto_it_close(n->i_dc);
+ }
+ dk3sto_close(n->s_dc);
+ }
+ n->s_dc = NULL; n->i_dc = NULL;
+ dk3_delete(v);
+ }
+
+#line 245 "itamem.ctr"
+}
+
+
+
+void
+itadmin_mem_netgroup_del(void *v)
+{
+ itadmin_netgroup *g;
+
+
+#line 254 "itamem.ctr"
+ if(v) {
+ g = (itadmin_netgroup *)v;
+
+#line 256 "itamem.ctr"
+ dk3_release(g->sn);
+ dk3_release(g->ln);
+ dk3_delete(v);
+ }
+
+#line 260 "itamem.ctr"
+}
+
+
+
+void
+itadmin_mem_ngdep_del(void *v)
+{
+ itadmin_ngdep *d;
+ if(v) {
+
+#line 269 "itamem.ctr"
+ d = (itadmin_ngdep *)v;
+ d->pa = NULL;
+ d->ch = NULL;
+ dk3_delete(v);
+ }
+}
+
+
+
+void
+itadmin_mem_dhcp_class_del(void *v)
+{
+ itadmin_dhcp_class *c;
+
+
+#line 283 "itamem.ctr"
+ if(v) {
+ c = (itadmin_dhcp_class *)v;
+
+#line 285 "itamem.ctr"
+ dk3_release(c->sn);
+ dk3_release(c->ln);
+ if(c->s_ho) {
+ if(c->i_ho) {
+ dk3sto_it_close(c->i_ho);
+ }
+ dk3sto_close(c->s_ho);
+ }
+ c->s_ho = NULL; c->i_ho = NULL;
+ c->dhcpn = NULL;
+ dk3_delete(v);
+ }
+
+#line 297 "itamem.ctr"
+}
+
+
+
+void
+itadmin_mem_dhcp_pool_del(void *v)
+{
+ itadmin_dhcp_pool *p;
+ itadmin_dhcp_option *pdo;
+
+
+#line 307 "itamem.ctr"
+ if(v) {
+ p = (itadmin_dhcp_pool *)v;
+ p->nw = NULL;
+ p->acl = NULL;
+
+#line 311 "itamem.ctr"
+ p->ip4s = 0UL;
+
+#line 312 "itamem.ctr"
+ p->ip4e = 0UL;
+ if(p->s_do) {
+ if(p->i_do) {
+ dk3sto_it_reset(p->i_do);
+ while(NULL != (pdo = (itadmin_dhcp_option *)dk3sto_it_next(p->i_do))) {
+ itadmin_mem_dhcp_option_del((void *)pdo);
+ }
+ dk3sto_it_close(p->i_do);
+ }
+ dk3sto_close(p->s_do);
+ }
+ p->s_do = NULL; p->i_do = NULL;
+ if(p->s_hoi) {
+ if(p->i_hoi) {
+ dk3sto_it_close(p->i_hoi);
+ }
+ dk3sto_close(p->s_hoi);
+ }
+ p->s_hoi = NULL; p->i_hoi = NULL;
+ p->duc = 0x00; p->auc = 0x00;
+ dk3_delete(v);
+ }
+
+#line 334 "itamem.ctr"
+}
+
+
+
+void
+itadmin_mem_dhcp_group_del(void *v)
+{
+ itadmin_dhcp_group *g;
+ void *vp;
+
+
+#line 344 "itamem.ctr"
+ if(v) {
+ g = (itadmin_dhcp_group *)v;
+
+#line 346 "itamem.ctr"
+ dk3_release(g->sn);
+ dk3_release(g->ln);
+ if(g->s_do) {
+ if(g->i_do) {
+ dk3sto_it_reset(g->i_do);
+ while(NULL != (vp = dk3sto_it_next(g->i_do))) {
+ itadmin_mem_dhcp_option_del(vp);
+ }
+ dk3sto_it_close(g->i_do);
+ }
+ dk3sto_close(g->s_do);
+ }
+ g->s_do = NULL; g->i_do = NULL;
+ dk3_delete(v);
+ }
+
+#line 361 "itamem.ctr"
+}
+
+
+
+void
+itadmin_mem_host_del(void *v)
+{
+ itadmin_host *h;
+ char const *c;
+ void *vp;
+
+
+#line 372 "itamem.ctr"
+ if(v) {
+ h = (itadmin_host *)v;
+
+#line 374 "itamem.ctr"
+ dk3_release(h->sn);
+ dk3_release(h->co);
+ dk3_release(h->maca);
+ dk3_release(h->room);
+ dk3_release(h->inv);
+ dk3_release(h->serno);
+ dk3_release(h->hid);
+ dk3_release(h->dnsd);
+ h->un = NULL;
+ h->ng = NULL;
+ h->dc = NULL;
+ h->dg = NULL;
+ h->nc = NULL;
+ h->bu = NULL;
+ itadmin_mem_date_init(&(h->expi));
+ if(h->s_al) {
+ if(h->i_al) {
+ dk3sto_it_reset(h->i_al);
+ while((c = (char const *)dk3sto_it_next(h->i_al)) != NULL) {
+ dk3_delete(c);
+ }
+ dk3sto_it_close(h->i_al);
+ }
+ dk3sto_close(h->s_al);
+ }
+ h->s_al = NULL; h->i_al = NULL;
+ if(h->s_do) {
+ if(h->i_do) {
+ dk3sto_it_reset(h->i_do);
+ while(NULL != (vp = dk3sto_it_next(h->i_do))) {
+ itadmin_mem_dhcp_option_del(vp);
+ }
+ dk3sto_it_close(h->i_do);
+ }
+ dk3sto_close(h->s_do);
+ }
+ h->s_do = NULL; h->i_do = NULL;
+ if(h->s_li) {
+ if(h->i_li) {
+ dk3sto_it_close(h->i_li);
+ }
+ dk3sto_close(h->s_li);
+ }
+ h->s_li = NULL; h->i_li = NULL;
+ h->ipv4 = 0UL;
+ h->fnf = h->fgu = h->snd = h->saw = 0x00;
+ dk3_delete(v);
+ }
+
+#line 422 "itamem.ctr"
+}
+
+
+
+void
+itadmin_mem_sw_man_del(void *v)
+{
+ itadmin_swman *m;
+
+
+#line 431 "itamem.ctr"
+ if(v) {
+ m = (itadmin_swman *)v;
+
+#line 433 "itamem.ctr"
+ dk3_release(m->sn);
+ dk3_release(m->ln);
+ dk3_delete(v);
+ }
+
+#line 437 "itamem.ctr"
+}
+
+
+
+void
+itadmin_mem_software_del(void *v)
+{
+ itadmin_swprod *p;
+
+
+#line 446 "itamem.ctr"
+ if(v) {
+ p = (itadmin_swprod *)v;
+
+#line 448 "itamem.ctr"
+ dk3_release(p->sn);
+ dk3_release(p->ln);
+ p->mn = NULL;
+ dk3_delete(v);
+ }
+
+#line 453 "itamem.ctr"
+}
+
+
+
+void
+itadmin_mem_lic_type_del(void *v)
+{
+ itadmin_lictype *t;
+
+
+#line 462 "itamem.ctr"
+ if(v) {
+ t = (itadmin_lictype *)v;
+
+#line 464 "itamem.ctr"
+ dk3_release(t->sn);
+ dk3_release(t->ln);
+ t->num = 0;
+ dk3_delete(v);
+ }
+
+#line 469 "itamem.ctr"
+}
+
+
+
+void
+itadmin_mem_license_del(void *v)
+{
+ itadmin_license *l;
+
+
+#line 478 "itamem.ctr"
+ if(v) {
+ l = (itadmin_license *)v;
+
+#line 480 "itamem.ctr"
+ dk3_release(l->order);
+ dk3_release(l->notes);
+ dk3_release(l->i_del);
+ dk3_release(l->i_inv);
+ itadmin_mem_date_init(&(l->d_del));
+ itadmin_mem_date_init(&(l->d_inv));
+ l->prod = NULL;
+ l->ltype = NULL;
+ l->owner = NULL;
+ l->host = NULL;
+ l->pk = 0UL;
+ dk3_delete(v);
+ }
+
+#line 493 "itamem.ctr"
+}
+
+
+
+/** Set a string pointer.
+ @param job Job structure.
+ @param dptr Address of destination pointer.
+ @param sstr Source pointer.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_mem_set_string(
+ itadmin_job *job,
+ char const **dptr,
+ char const *sstr
+)
+{
+ char bu[ITADMIN_CONFIG_LINE_SIZE];
+ char *p1;
+ char const *np;
+ int back = 0;
+ if(sstr) {
+ dk3_release(*dptr);
+ if(dk3str_c8_len(sstr) < sizeof(bu)) {
+ dk3str_c8_cpy_not_overlapped(bu, sstr);
+ p1 = dk3str_c8_start(bu, NULL);
+ if(p1) {
+ dk3str_c8_normalize(p1,NULL,' ');
+ np = dk3str_c8_dup_app(p1, job->app);
+ if(np) {
+ *dptr = np;
+ back = 1;
+ } else {
+ /* ERROR: Memory */
+ job->ec = DK3_ERROR_MEMORY;
+ }
+ } else {
+ back = 1; /* Empty text */
+ }
+ } else {
+ np = dk3str_c8_dup_app(sstr, job->app);
+ if(np) {
+ *dptr = np;
+ back = 1;
+ } else {
+ /* ERROR: Memory */
+ job->ec = DK3_ERROR_MEMORY;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Create new user.
+ @param job Job structure.
+ @param un Name.
+ @param tt Academic degree or title (may be NULL).
+ @param sn Surname (may be NULL).
+ @param na Name.
+ @param em E-Mail (may be NULL).
+ @param cc Cost control ID (may be NULL).
+ @param si Staff ID number (may be NULL).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_user *
+itadmin_mem_user_new(
+ itadmin_job *job,
+ char const *un,
+ char const *tt,
+ char const *sn,
+ char const *na,
+ char const *em,
+ char const *cc,
+ char const *si
+)
+{
+ itadmin_user *back = NULL;
+ int ok = 1;
+ if(un) {
+ back = dk3_new_app(itadmin_user,1,job->app);
+ if(back) {
+ back->us = NULL;
+ back->tt = NULL;
+ back->sn = NULL;
+ back->na = NULL;
+ back->em = NULL;
+ back->cc = NULL;
+ back->si = NULL;
+ back->s_ho = NULL;
+ back->i_ho = NULL;
+ back->s_li = NULL;
+ back->i_li = NULL;
+ if(un) { if(!itadmin_mem_set_string(job, &(back->us), un)) { ok = 0; } }
+ if(tt) { if(!itadmin_mem_set_string(job, &(back->tt), tt)) { ok = 0; } }
+ if(sn) { if(!itadmin_mem_set_string(job, &(back->sn), sn)) { ok = 0; } }
+ if(na) { if(!itadmin_mem_set_string(job, &(back->na), na)) { ok = 0; } }
+ if(em) { if(!itadmin_mem_set_string(job, &(back->em), em)) { ok = 0; } }
+ if(cc) { if(!itadmin_mem_set_string(job, &(back->cc), cc)) { ok = 0; } }
+ if(si) { if(!itadmin_mem_set_string(job, &(back->si), si)) { ok = 0; } }
+ if(!(ok)) {
+ itadmin_mem_user_del((void *)back);
+ back = NULL;
+ }
+ } else {
+ job->ec = DK3_ERROR_MEMORY;
+ }
+ }
+ return back;
+}
+
+
+
+/** Create new building.
+ @param job Job structure.
+ @param s Name.
+ @param l Long name (may be NULL).
+ @param a1 Address line 1 (typically street and number,
+ may be NULL).
+ @param a2 Address line 2 (may be NULL).
+ @param a3 Address line 3 (may be NULL).
+ @param a4 Address line 4 (may be NULL).
+ @param zc Zip code (may be NULL).
+ @param city Town or city name (may be NULL).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_building *
+itadmin_mem_building_new(
+ itadmin_job *job,
+ char const *s,
+ char const *l,
+ char const *a1,
+ char const *a2,
+ char const *a3,
+ char const *a4,
+ char const *zc,
+ char const *city
+)
+{
+ itadmin_building *back = NULL;
+ int ok = 1;
+
+
+#line 637 "itamem.ctr"
+ if(s) {
+ back = dk3_new_app(itadmin_building,1,job->app);
+ if(back) {
+
+#line 640 "itamem.ctr"
+ back->s = NULL;
+ back->l = NULL;
+ back->a1 = NULL;
+ back->a2 = NULL;
+ back->a3 = NULL;
+ back->a4 = NULL;
+ back->zc = NULL;
+ back->city = NULL;
+ if(s) { if(!itadmin_mem_set_string(job, &(back->s), s)) { ok = 0; } }
+ if(l) { if(!itadmin_mem_set_string(job, &(back->l), l)) { ok = 0; } }
+ if(a1) { if(!itadmin_mem_set_string(job, &(back->a1), a1)) { ok = 0; } }
+ if(a2) { if(!itadmin_mem_set_string(job, &(back->a2), a2)) { ok = 0; } }
+ if(a3) { if(!itadmin_mem_set_string(job, &(back->a3), a3)) { ok = 0; } }
+ if(a4) { if(!itadmin_mem_set_string(job, &(back->a4), a4)) { ok = 0; } }
+ if(zc) { if(!itadmin_mem_set_string(job, &(back->zc), zc)) { ok = 0; } }
+ if(city) { if(!itadmin_mem_set_string(job, &(back->city), city)) { ok = 0; } }
+ if(!(ok)) {
+
+#line 657 "itamem.ctr"
+ itadmin_mem_building_del((void *)back);
+ back = NULL;
+ }
+ }
+ }
+
+#line 662 "itamem.ctr"
+ return back;
+}
+
+
+
+/** Create new speed setting.
+ @param job Job structure.
+ @param s Name.
+ @param n Description (may be NULL).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_speed *
+itadmin_mem_speed_new(
+ itadmin_job *job,
+ char const *s,
+ char const *n
+)
+{
+ itadmin_speed *back = NULL;
+ int ok = 1;
+ if(s) {
+ back = dk3_new_app(itadmin_speed,1,job->app);
+ if(back) {
+ back->s = NULL;
+ back->l = NULL;
+ if(s) { if(!itadmin_mem_set_string(job, &(back->s), s)) { ok = 0; } }
+ if(n) { if(!itadmin_mem_set_string(job, &(back->l), n)) { ok = 0; } }
+ if(!(ok)) {
+ itadmin_mem_speed_del((void *)back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Create new VLAN.
+ @param job Job structure.
+ @param s Name.
+ @param l Long name (may be NULL).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_vlan *
+itadmin_mem_vlan_new(
+ itadmin_job *job,
+ char const *s,
+ char const *l
+)
+{
+ itadmin_vlan *back = NULL;
+ int ok = 1;
+ if(s) {
+ back = dk3_new_app(itadmin_vlan,1,job->app);
+ if(back) {
+ back->s = NULL;
+ back->l = NULL;
+ back->s_nw = NULL;
+ back->i_nw = NULL;
+ back->s_do = NULL;
+ back->i_do = NULL;
+ if(s) { if(!itadmin_mem_set_string(job, &(back->s), s)) { ok = 0; } }
+ if(l) { if(!itadmin_mem_set_string(job, &(back->l), l)) { ok = 0; } }
+ if(itadmin_job_do_dhcp(job)) {
+ back->s_nw = dk3sto_open_app(job->app);
+ if(back->s_nw) {
+ dk3sto_set_comp(back->s_nw, itadmin_comp_network, 0);
+ back->i_nw = dk3sto_it_open(back->s_nw);
+ if(back->i_nw) {
+ } else {
+ ok = 0;
+ /* ERROR: Memory */
+ }
+ } else {
+ ok = 0;
+ /* ERROR: Memory */
+ }
+ }
+ if(!(ok)) {
+ itadmin_mem_vlan_del((void *)back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Create new network connector.
+ @param job Job structure.
+ @param s Name.
+ @param hp Hub port name/number.
+ @param room Room.
+ @param sp Speed setting.
+ @param vl VLAN.
+ @param bu Building.
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_connect *
+itadmin_mem_connect_new(
+ itadmin_job *job,
+ char const *s,
+ char const *hp,
+ char const *room,
+ itadmin_speed *sp,
+ itadmin_vlan *vl,
+ itadmin_building *bu
+)
+{
+ itadmin_connect *back = NULL;
+ int ok = 1;
+ if(s) {
+ back = dk3_new_app(itadmin_connect,1,job->app);
+ if(back) {
+ back->s = NULL;
+ back->hp = NULL;
+ back->room = NULL;
+ back->sp = sp;
+ back->vl = vl;
+ back->bu = bu;
+ if(!itadmin_mem_set_string(job, &(back->s), s)) { ok = 0; }
+ if(hp) { if(!itadmin_mem_set_string(job, &(back->hp), hp)) { ok = 0; } }
+ if(room) {
+ if(!itadmin_mem_set_string(job, &(back->room), room)) { ok = 0; }
+ }
+ if(!(ok)) {
+ itadmin_mem_connect_del((void *)back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+itadmin_dhcp_ginw *
+itadmin_mem_dhcp_ginw_new(itadmin_job *job, itadmin_dhcp_group *gr)
+{
+ itadmin_dhcp_ginw *back = NULL;
+ if((job) && (gr)) {
+ back = dk3_new_app(itadmin_dhcp_ginw,1,job->app);
+ if(back) {
+ back->gr = gr;
+ back->s_h = NULL;
+ back->i_h = NULL;
+ back->s_h = dk3sto_open_app(job->app);
+ if(back->s_h) {
+ dk3sto_set_comp(back->s_h, itadmin_comp_host, 2);
+ back->i_h = dk3sto_it_open(back->s_h);
+ }
+ if(!((back->s_h) && (back->i_h))) {
+ itadmin_mem_dhcp_ginw_del(back);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Create new network.
+ @param job Job structure.
+ @param ip4 Network address.
+ @param ma4 Network mask.
+ @param gw4 Gateway.
+ @param bc4 Broadcast address.
+ @param vl VLAN.
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_network *
+itadmin_mem_network_new(
+ itadmin_job *job,
+ unsigned long ip4,
+ unsigned long ma4,
+ unsigned long gw4,
+ unsigned long bc4,
+ itadmin_vlan *vl
+)
+{
+ itadmin_network *back = NULL;
+#if 0
+ unsigned long ulip4;
+ unsigned long ulma4;
+ unsigned long ulgw4;
+ unsigned long ulbc4;
+ int ok = 1;
+ if((ip4) && (ma4) && (gw4)) {
+ back = dk3_new_app(itadmin_network,1,job->app);
+ if(back) {
+ back->ip4 = back->ma4 = back->gw4 = back->bc4 = 0UL;
+ back->vl = vl;
+ back->s_p = NULL;
+ back->i_p = NULL;
+ back->s_dg = NULL;
+ back->i_dg = NULL;
+ back->s_hoi = NULL;
+ back->i_hoi = NULL;
+ back->s_dc = NULL;
+ back->i_dc = NULL;
+ if(!dk3enc_c8_ipaddr_to_ul_app(ip4, &ulip4, job->app)) { ok = 0; }
+ if(!dk3enc_c8_ipaddr_to_ul_app(ma4, &ulma4, job->app)) { ok = 0; }
+ if(!dk3enc_c8_ipaddr_to_ul_app(gw4, &ulgw4, job->app)) { ok = 0; }
+ if(bc4) {
+ if(!dk3enc_c8_ipaddr_to_ul_app(bc4, &ulbc4, job->app)) { ok = 0; }
+ } else {
+ ulbc4 = ((~(ulip4 & ulma4)) | ulip4);
+ }
+ back->ip4 = ulip4;
+ back->ma4 = ulma4;
+ back->gw4 = ulgw4;
+ back->bc4 = ulbc4;
+ if(job->f_dh) {
+ back->s_p = dk3sto_open_app(job->app);
+ if(back->s_p) {
+ dk3sto_set_comp(back->s_p, itadmin_comp_dhcp_pool, 0);
+ back->i_p = dk3sto_it_open(back->s_p);
+ if(back->i_p) {
+ back->s_dg = dk3sto_open_app(job->app);
+ if(back->s_dg) {
+ dk3sto_set_comp(back->s_dg, itadmin_comp_dhcp_ginw, 0);
+ back->i_dg = dk3sto_it_open(back->s_dg);
+ if(back->i_dg) {
+ /* Success. */
+ } else {
+ ok = 0;
+ }
+ } else {
+ ok = 0;
+ }
+ } else {
+ ok = 0;
+ }
+ } else { ok = 0; }
+ }
+ if(!(ok)) {
+ itadmin_mem_network_del((void *)back);
+ back = NULL;
+ }
+ }
+ }
+#else
+ if((ip4) && (ma4)) {
+ int ok;
+ back = dk3_new_app(itadmin_network,1,job->app);
+ if(back) {
+ ok = 1;
+ back->ip4 = ip4;
+ back->ma4 = ma4;
+ back->gw4 = gw4;
+ back->bc4 = bc4;
+ back->vl = vl;
+ back->s_p = NULL;
+ back->i_p = NULL;
+ back->s_do = NULL;
+ back->i_do = NULL;
+ if(itadmin_job_do_dhcp(job)) {
+ ok = 0;
+ back->s_p = dk3sto_open_app(job->app);
+ if(back->s_p) {
+ dk3sto_set_comp(back->s_p, itadmin_comp_dhcp_pool, 0);
+ back->i_p = dk3sto_it_open(back->s_p);
+ if(back->i_p) {
+ ok = 1;
+ }
+ }
+ }
+ if(!(ok)) {
+ itadmin_mem_network_del((void *)back);
+ back = NULL;
+ }
+ }
+ }
+#endif
+ return back;
+}
+
+
+
+/** Create new netgroup
+ @param job Job structure.
+ @param sn Short name.
+ @param ln Long name (may be NULL).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_netgroup *
+itadmin_mem_netgroup_new(
+ itadmin_job *job,
+ char const *sn,
+ char const *ln
+)
+{
+ itadmin_netgroup *back = NULL;
+ int ok = 1;
+ if(sn) {
+ back = dk3_new_app(itadmin_netgroup,1,job->app);
+ if(back) {
+ back->no = 0;
+ back->ln = NULL;
+ if(sn) { if(!itadmin_mem_set_string(job, &(back->sn), sn)) { ok = 0; } }
+ if(ln) { if(!itadmin_mem_set_string(job, &(back->ln), ln)) { ok = 0; } }
+ if(!(ok)) {
+ itadmin_mem_netgroup_del((void *)back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Create new netgroup dependency.
+ @param job Job structure.
+ @param pa Parent group.
+ @param ch Child group.
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_ngdep *
+itadmin_mem_ngdep_new(
+ itadmin_job *job,
+ itadmin_netgroup *pa,
+ itadmin_netgroup *ch
+)
+{
+ itadmin_ngdep *back = NULL;
+ if((pa) && (ch)) {
+ back = dk3_new_app(itadmin_ngdep,1,job->app);
+ if(back) {
+ back->pa = pa;
+ back->ch = ch;
+ }
+ }
+ return back;
+}
+
+
+
+/** Create new DHCP class.
+ @param job Job structure.
+ @param sn Short name.
+ @param ln Long name (may be NULL).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_dhcp_class *
+itadmin_mem_dhcp_class_new(
+ itadmin_job *job,
+ char const *sn,
+ char const *ln
+)
+{
+ itadmin_dhcp_class *back = NULL;
+ int ok = 1;
+ if(sn) {
+ back = dk3_new_app(itadmin_dhcp_class,1,job->app);
+ if(back) {
+ back->s_ho = NULL;
+ back->i_ho = NULL;
+ back->dhcpn = NULL;
+ if(!itadmin_mem_set_string(job, &(back->sn), sn)) { ok = 0; }
+ if(ln) { if(!itadmin_mem_set_string(job, &(back->ln), ln)) { ok = 0; } }
+ if(!(ok)) {
+ itadmin_mem_dhcp_class_del((void *)back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Create new DHCP pool.
+ @param job Job structure.
+ @param nw Network.
+ @param cn Allowed class (if unknown clients are denied,
+ may be NULL).
+ @param ip4s IPv4 start address.
+ @param ip4e IPv4 end address.
+ @param duc Flag: Deny unknown clients (needs cn).
+ @param auc Flag: Allow unknown clients.
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_dhcp_pool *
+itadmin_mem_dhcp_pool_new(
+ itadmin_job *job,
+ itadmin_network *nw,
+ itadmin_dhcp_class *cn,
+ unsigned long ip4s,
+ unsigned long ip4e,
+ int duc,
+ int auc
+)
+{
+ char buffer[128];
+ itadmin_dhcp_pool *back = NULL;
+ int ok = 1;
+
+
+#line 1062 "itamem.ctr"
+ if((nw) && (ip4s) && (ip4e)) {
+ back = dk3_new_app(itadmin_dhcp_pool,1,job->app);
+ if(back) {
+ back->nw = nw;
+ back->acl = cn;
+ back->s_do = NULL;
+ back->i_do = NULL;
+ back->s_hoi = NULL;
+ back->i_hoi = NULL;
+ back->ip4s = ip4s;
+ back->ip4e = ip4e;
+ back->duc = ((duc) ? 0x01 : 0x00);
+ back->auc = ((auc) ? 0x01 : 0x00);
+ if((duc) && (auc)) {
+ ok = 0;
+ /* ERROR: can not allow and deny at same time! */
+ sprintf(
+ buffer,
+ "%lu.%lu.%lu.%lu",
+ ((ip4s >> 24) & 0x000000FFUL),
+ ((ip4s >> 16) & 0x000000FFUL),
+ ((ip4s >> 8) & 0x000000FFUL),
+ (ip4s & 0x000000FFUL)
+ );
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 134, 135, buffer);
+ }
+ if(!(ok)) {
+ itadmin_mem_dhcp_pool_del((void *)back);
+ back = NULL;
+ }
+ }
+ }
+
+#line 1094 "itamem.ctr"
+ return back;
+}
+
+
+
+/** Create new DHCP group.
+ @param job Job structure.
+ @param sn Short name.
+ @param ln Long name (may be NULL).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_dhcp_group *
+itadmin_mem_dhcp_group_new(
+ itadmin_job *job,
+ char const *sn,
+ char const *ln
+)
+{
+ itadmin_dhcp_group *back = NULL;
+ int ok = 1;
+ if(sn) {
+ back = dk3_new_app(itadmin_dhcp_group,1,job->app);
+ if(back) {
+ back->sn = NULL;
+ back->ln = NULL;
+ back->s_do = NULL;
+ back->i_do = NULL;
+ if(!itadmin_mem_set_string(job, &(back->sn), sn)) { ok = 0; }
+ if(ln) { if(!itadmin_mem_set_string(job, &(back->ln), ln)) { ok = 0; } }
+ if(!(ok)) {
+ itadmin_mem_dhcp_group_del((void *)back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Create new host
+ @param job Job structure.
+ @param sn Short name.
+ @param co Comment/description (may be NULL).
+ @param maca MAC address (may be NULL).
+ @param room Room (may be NULL).
+ @param inv Inventory number (may be NULL).
+ @param serno Serial number (may be NULL).
+ @param hid Host ID (may be NULL).
+ @param expi Expiration date (may be NULL).
+ @param dnsd DNS domain (may be NULL).
+ @param un System owner.
+ @param ng Netgroup (may be NULL).
+ @param dc DHCP class (may be NULL).
+ @param dg DHCP group (may be NULL).
+ @param nc Network connection socket (may be NULL).
+ @param bu Building (may be NULL).
+ @param ipv4 IPv4 address (may be NULL).
+ @param fnf Flag: FQDN first in hosts file.
+ @param fgu Flag: Guest computer (bring your own device).
+ @param snd Flag: Skip in network documentation.
+ @param saw Flag: Skip in arpwatch configuration.
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_host *
+itadmin_mem_host_new(
+ itadmin_job *job,
+ itadmin_date *expi,
+ char const *sn,
+ char const *co,
+ char const *maca,
+ char const *room,
+ char const *inv,
+ char const *serno,
+ char const *hid,
+ char const *dnsd,
+ itadmin_user *un,
+ itadmin_netgroup *ng,
+ itadmin_dhcp_class *dc,
+ itadmin_dhcp_group *dg,
+ itadmin_connect *nc,
+ itadmin_building *bu,
+ unsigned long ipv4,
+ int fnf,
+ int fgu,
+ int snd,
+ int saw
+)
+{
+ itadmin_host *back = NULL;
+ int ok = 1;
+
+
+#line 1186 "itamem.ctr"
+
+
+#line 1187 "itamem.ctr"
+
+
+#line 1188 "itamem.ctr"
+
+
+#line 1189 "itamem.ctr"
+
+
+#line 1190 "itamem.ctr"
+
+
+#line 1191 "itamem.ctr"
+
+
+#line 1192 "itamem.ctr"
+
+
+#line 1193 "itamem.ctr"
+
+
+#line 1194 "itamem.ctr"
+
+
+#line 1195 "itamem.ctr"
+
+
+#line 1196 "itamem.ctr"
+
+
+#line 1197 "itamem.ctr"
+
+
+#line 1198 "itamem.ctr"
+
+
+#line 1199 "itamem.ctr"
+ if(sn) {
+
+#line 1200 "itamem.ctr"
+ back = dk3_new_app(itadmin_host,1,job->app);
+ if(back) {
+
+#line 1202 "itamem.ctr"
+ back->sn = back->co = back->maca = back->room = back->inv = back->serno
+ = back->hid = back->dnsd = NULL;
+ itadmin_mem_date_init(&(back->expi));
+ back->un = un;
+ back->ng = ng;
+ back->dc = dc;
+ back->dg = dg;
+ back->nc = nc;
+ back->bu = bu;
+ back->s_al = NULL;
+ back->i_al = NULL;
+ back->s_do = NULL;
+ back->i_do = NULL;
+ back->s_li = NULL;
+ back->i_li = NULL;
+ back->ipv4 = ipv4;
+ back->fnf = ((fnf) ? 0x01 : 0x00);
+ back->fgu = (char)fgu;
+ back->snd = ((snd) ? 0x01 : 0x00);
+ back->saw = ((saw) ? 0x01 : 0x00);
+ back->dp = NULL;
+ if(!itadmin_mem_set_string(job, &(back->sn), sn)) {
+ ok = 0;
+
+#line 1225 "itamem.ctr"
+ }
+ if(co) {
+ if(!itadmin_mem_set_string(job, &(back->co), co)) {
+ ok = 0;
+
+#line 1229 "itamem.ctr"
+ }
+ }
+ if(maca) {
+ if(!itadmin_mem_set_string(job, &(back->maca), maca)) {
+ ok = 0;
+
+#line 1234 "itamem.ctr"
+ }
+ }
+ if(room) {
+ if(!itadmin_mem_set_string(job, &(back->room), room)) {
+ ok = 0;
+
+#line 1239 "itamem.ctr"
+ }
+ }
+ if(inv) {
+ if(!itadmin_mem_set_string(job, &(back->inv), inv)) {
+ ok = 0;
+
+#line 1244 "itamem.ctr"
+ }
+ }
+ if(serno) {
+ if(!itadmin_mem_set_string(job, &(back->serno), serno)) {
+ ok = 0;
+
+#line 1249 "itamem.ctr"
+ }
+ }
+ if(hid) {
+ if(!itadmin_mem_set_string(job, &(back->hid), hid)) {
+ ok = 0;
+
+#line 1254 "itamem.ctr"
+ }
+ }
+ if(expi) {
+ itadmin_mem_date_copy(&(back->expi), expi);
+ }
+ if(dnsd) {
+ if(!itadmin_mem_set_string(job, &(back->dnsd), dnsd)) {
+ ok = 0;
+
+#line 1262 "itamem.ctr"
+ }
+ }
+ back->s_al = dk3sto_open_app(job->app);
+ if(back->s_al) {
+ /* SET COMPARISON FUNCTION */
+ dk3sto_set_comp(back->s_al, itadmin_comp_string, 0);
+ back->i_al = dk3sto_it_open(back->s_al);
+ if(!(back->i_al)) { ok = 0; }
+ } else { ok = 0; }
+ if(!(ok)) {
+
+#line 1272 "itamem.ctr"
+ itadmin_mem_host_del((void *)back);
+ back = NULL;
+ }
+ } else {
+
+#line 1276 "itamem.ctr"
+ }
+ } else {
+
+#line 1278 "itamem.ctr"
+ }
+
+#line 1279 "itamem.ctr"
+ return back;
+}
+
+
+
+/** Create new software manufacturer.
+ @param job Job structure.
+ @param sn Short name.
+ @param ln Long name (description).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_swman *
+itadmin_mem_swman_new(
+ itadmin_job *job,
+ char const *sn,
+ char const *ln
+)
+{
+ itadmin_swman *back = NULL;
+ int ok = 1;
+ if(sn) {
+ back = dk3_new_app(itadmin_swman,1,job->app);
+ if(back) {
+ back->sn = NULL;
+ back->ln = NULL;
+ if(!itadmin_mem_set_string(job, &(back->sn), sn)) { ok = 0; }
+ if(ln) { if(!itadmin_mem_set_string(job, &(back->ln), ln)) { ok = 0; } }
+ if(!(ok)) {
+ itadmin_mem_sw_man_del((void *)back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Create new software product.
+ @param job Job structure.
+ @param sn Short name.
+ @param ln Long name.
+ @param mn Software manufacturer (may be NULL).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_swprod *
+itadmin_mem_swprod_new(
+ itadmin_job *job,
+ char const *sn,
+ char const *ln,
+ itadmin_swman *mn
+)
+{
+ itadmin_swprod *back = NULL;
+ int ok = 1;
+ if(sn) {
+ back = dk3_new_app(itadmin_swprod,1,job->app);
+ if(back) {
+ back->sn = NULL;
+ back->ln = NULL;
+ back->mn = mn;
+ if(!itadmin_mem_set_string(job, &(back->sn), sn)) { ok = 0; }
+ if(ln) { if(!itadmin_mem_set_string(job, &(back->ln), ln)) { ok = 0; } }
+ if(!(ok)) {
+ itadmin_mem_software_del((void *)back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Create new license type.
+ @param job Job structure.
+ @param sn Short license type name.
+ @param ln Long name (description).
+ @param num Number of client licenses for floating license servers.
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_lictype *
+itadmin_mem_lictype_new(
+ itadmin_job *job,
+ char const *sn,
+ char const *ln,
+ int num
+)
+{
+ itadmin_lictype *back = NULL;
+ int ok = 1;
+ if(sn) {
+ back = dk3_new_app(itadmin_lictype,1,job->app);
+ if(back) {
+ back->sn = NULL; back->ln = NULL; back->num = num;
+ if(!itadmin_mem_set_string(job, &(back->sn), sn)) { ok = 0; }
+ if(ln) { if(!itadmin_mem_set_string(job, &(back->ln), ln)) { ok = 0; } }
+ if(!(ok)) {
+ itadmin_mem_lic_type_del((void *)back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+itadmin_license *
+itadmin_mem_license_new(
+ itadmin_job *job,
+ unsigned long pk,
+ char const *order,
+ char const *notes,
+ itadmin_date *d_del,
+ char const *i_del,
+ itadmin_date *d_inv,
+ char const *i_inv,
+ itadmin_swprod *prod,
+ itadmin_lictype *ltype,
+ itadmin_user *owner,
+ itadmin_host *host
+)
+{
+ itadmin_license *back = NULL;
+ int ok = 1;
+ if(prod) {
+ back = dk3_new_app(itadmin_license,1,job->app);
+ if(back) {
+ back->order = NULL;
+ back->notes = NULL;
+ itadmin_mem_date_init(&(back->d_del));
+ back->i_del = NULL;
+ itadmin_mem_date_init(&(back->d_inv));
+ back->i_inv = NULL;
+ back->pk = pk;
+ back->prod = prod;
+ back->ltype = ltype;
+ back->owner = owner;
+ back->host = host;
+ if(order) {
+ if(!itadmin_mem_set_string(job, &(back->order), order)) { ok = 0; }
+ }
+ if(notes) {
+ if(!itadmin_mem_set_string(job, &(back->notes), notes)) { ok = 0; }
+ }
+ if(i_del) {
+ if(!itadmin_mem_set_string(job, &(back->i_del), i_del)) { ok = 0; }
+ }
+ if(i_inv) {
+ if(!itadmin_mem_set_string(job, &(back->i_inv), i_inv)) { ok = 0; }
+ }
+ if(!(ok)) {
+ itadmin_mem_license_del((void *)back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void
+itadmin_mem_dhcp_option_del(void *v)
+{
+ itadmin_dhcp_option *o;
+
+
+#line 1447 "itamem.ctr"
+ if(v) {
+ o = (itadmin_dhcp_option *)v;
+
+#line 1449 "itamem.ctr"
+ dk3_release(o->k);
+ dk3_release(o->v);
+ dk3_release(o);
+ }
+
+#line 1453 "itamem.ctr"
+}
+
+
+
+itadmin_dhcp_option *
+itadmin_mem_dhcp_option_new(
+ itadmin_job *job,
+ char const *k,
+ char const *v,
+ long pk
+)
+{
+ itadmin_dhcp_option *back = NULL;
+ int ok = 1;
+ if((job) && (k)) {
+ back = dk3_new_app(itadmin_dhcp_option,1,job->app);
+ if(back) {
+ back->k = NULL;
+ back->v = NULL;
+ back->pk = pk;
+ if(!itadmin_mem_set_string(job, &(back->k), k)) { ok = 0; }
+ if(v) { if(!itadmin_mem_set_string(job, &(back->v), v)) { ok = 0; } }
+ if(!(ok)) {
+ itadmin_mem_dhcp_option_del((void *)back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+itadmin_swman *
+itadmin_mem_sw_man_new(itadmin_job *job, char const *sn, char const *ln)
+{
+ itadmin_swman *back = NULL;
+ int ok = 1;
+ if((job) && (sn)) {
+ back = dk3_new_app(itadmin_swman,1,job->app);
+ if(back) {
+ back->sn = NULL;
+ back->ln = NULL;
+ if(sn) { if(!itadmin_mem_set_string(job, &(back->sn), sn)) { ok = 0; } }
+ if(ln) { if(!itadmin_mem_set_string(job, &(back->ln), ln)) { ok = 0; } }
+ if(!(ok)) {
+ itadmin_mem_sw_man_del(back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/itamem.ctr b/support/dktools/itamem.ctr
new file mode 100644
index 0000000000..5febe9f654
--- /dev/null
+++ b/support/dktools/itamem.ctr
@@ -0,0 +1,1506 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk3all.h"
+#include "itadmin.h"
+
+
+
+$!trace-include
+
+
+
+$!trace-code #define IP1(x) (((x) >> 24) & 0x000000FFUL)
+$!trace-code #define IP2(x) (((x) >> 16) & 0x000000FFUL)
+$!trace-code #define IP3(x) (((x) >> 8) & 0x000000FFUL)
+$!trace-code #define IP4(x) ( (x) & 0x000000FFUL)
+
+
+
+void
+itadmin_mem_date_init(itadmin_date *dp)
+{
+ dp->y = 0;
+ dp->m = 0;
+ dp->d = 0;
+}
+
+
+
+void
+itadmin_mem_date_copy(itadmin_date *dp, itadmin_date *sp)
+{
+ dp->y = sp->y;
+ dp->m = sp->m;
+ dp->d = sp->d;
+}
+
+
+
+void
+itadmin_mem_user_del(void *v)
+{
+ itadmin_user *u;
+ $? "+ itadmin_mem_user_del"
+ if(v) {
+ u = (itadmin_user *)v; $? ". user=\"%!8s\"", TR_8STR(u->us)
+ dk3_release(u->us);
+ dk3_release(u->tt);
+ dk3_release(u->sn);
+ dk3_release(u->na);
+ dk3_release(u->em);
+ dk3_release(u->cc);
+ dk3_release(u->si);
+ if(u->s_ho) {
+ if(u->i_ho) {
+ dk3sto_it_close(u->i_ho);
+ }
+ dk3sto_close(u->s_ho);
+ }
+ u->s_ho = NULL; u->i_ho = NULL;
+ if(u->s_li) {
+ if(u->i_li) {
+ dk3sto_it_close(u->i_li);
+ }
+ dk3sto_close(u->s_li);
+ }
+ u->s_li = NULL; u->i_li = NULL;
+ dk3_delete(v);
+ } $? "- itadmin_mem_user_del"
+}
+
+
+
+void
+itadmin_mem_building_del(void *v)
+{
+ itadmin_building *b;
+ $? "+ itadmin_mem_building_del"
+ if(v) {
+ b = (itadmin_building *)v; $? ". building=\"%!8s\"", TR_8STR(b->s)
+ dk3_release(b->s);
+ dk3_release(b->l);
+ dk3_release(b->a1);
+ dk3_release(b->a2);
+ dk3_release(b->a3);
+ dk3_release(b->a4);
+ dk3_release(b->zc);
+ dk3_release(b->city);
+ dk3_delete(v);
+ } $? "- itadmin_mem_building_del"
+}
+
+
+
+void
+itadmin_mem_speed_del(void *v)
+{
+ itadmin_speed *s;
+ $? "+ itadmin_mem_speed_del"
+ if(v) {
+ s = (itadmin_speed *)v; $? ". speed=\"%!8s\"", TR_8STR(s->s)
+ dk3_release(s->s);
+ dk3_release(s->l);
+ dk3_delete(v);
+ } $? "- itadmin_mem_speed_del"
+}
+
+
+
+void
+itadmin_mem_vlan_del(void *v)
+{
+ itadmin_vlan *l;
+ itadmin_dhcp_option *d;
+ $? "+ itadmin_mem_vlan_del"
+ if(v) {
+ l = (itadmin_vlan *)v; $? ". VLAN name=\"%!8s\"", TR_8STR(l->s)
+ dk3_release(l->s);
+ dk3_release(l->l);
+ if(l->s_nw) {
+ if(l->i_nw) {
+ dk3sto_it_close(l->i_nw);
+ }
+ dk3sto_close(l->s_nw);
+ }
+ l->s_nw = NULL; l->i_nw = NULL;
+ if(l->s_do) {
+ if(l->i_do) {
+ dk3sto_it_reset(l->i_do);
+ while(NULL != (d = (itadmin_dhcp_option *)dk3sto_it_next(l->i_do))) {
+ itadmin_mem_dhcp_option_del((void *)d);
+ }
+ dk3sto_it_close(l->i_do);
+ }
+ dk3sto_close(l->s_do);
+ }
+ l->s_do = NULL; l->i_do = NULL;
+ dk3_delete(v);
+ } $? "- itadmin_mem_vlan_del"
+}
+
+
+
+void
+itadmin_mem_connect_del(void *v)
+{
+ itadmin_connect *c;
+ $? "+ itadmin_mem_connect_del"
+ if(v) {
+ c = (itadmin_connect *)v; $? ". name = \"%!8s\"", TR_8STR(c->s)
+ dk3_release(c->s);
+ dk3_release(c->hp);
+ dk3_release(c->room);
+ c->sp = NULL; c->vl = NULL; c->bu = NULL;
+ dk3_delete(v);
+ } $? "- itadmin_mem_connect_del"
+}
+
+
+
+void
+itadmin_mem_dhcp_ginw_del(itadmin_dhcp_ginw *g)
+{
+ if(g) {
+ g->gr = NULL;
+ if(g->s_h) {
+ if(g->i_h) {
+ dk3sto_it_close(g->i_h);
+ }
+ dk3sto_close(g->s_h);
+ }
+ g->s_h = NULL; g->i_h = NULL;
+ dk3_delete(g);
+ }
+}
+
+
+
+void
+itadmin_mem_network_del(void *v)
+{
+ itadmin_network *n;
+ itadmin_dhcp_ginw *ginw;
+ void *vp;
+ $? "+ itadmin_mem_network_del"
+ if(v) {
+ n = (itadmin_network *)v; $? ". ip=%lu.%lu.%lu.%lu", IP1(n->ip4), IP2(n->ip4), IP3(n->ip4), IP4(n->ip4)
+ n->ip4 = 0UL; $? ". ma=%lu.%lu.%lu.%lu", IP1(n->ma4), IP2(n->ma4), IP3(n->ma4), IP4(n->ma4)
+ n->ma4 = 0UL; $? ". gw=%lu.%lu.%lu.%lu", IP1(n->gw4), IP2(n->gw4), IP3(n->gw4), IP4(n->gw4)
+ n->gw4 = 0UL; $? ". bc=%lu.%lu.%lu.%lu", IP1(n->bc4), IP2(n->bc4), IP3(n->bc4), IP4(n->bc4)
+ n->bc4 = 0UL;
+ n->vl = NULL;
+ if(n->s_dg) {
+ if(n->i_dg) {
+ dk3sto_it_reset(n->i_dg);
+ while(NULL != (ginw = (itadmin_dhcp_ginw *)dk3sto_it_next(n->i_dg))) {
+ itadmin_mem_dhcp_ginw_del(ginw);
+ }
+ dk3sto_it_close(n->i_dg);
+ }
+ dk3sto_close(n->s_dg);
+ }
+ n->s_dg = NULL; n->i_dg = NULL;
+ if(n->s_p) {
+ if(n->i_p) {
+ dk3sto_it_close(n->i_p);
+ }
+ dk3sto_close(n->s_p);
+ }
+ n->s_p = NULL; n->i_p = NULL;
+ if(n->s_do) {
+ if(n->i_do) {
+ dk3sto_it_reset(n->i_do);
+ while(NULL != (vp = dk3sto_it_next(n->i_do))) {
+ itadmin_mem_dhcp_option_del(vp);
+ }
+ dk3sto_it_close(n->i_do);
+ }
+ dk3sto_close(n->s_do);
+ }
+ n->s_do = NULL; n->i_do = NULL;
+ if(n->s_hoi) {
+ if(n->i_hoi) {
+ dk3sto_it_close(n->i_hoi);
+ }
+ dk3sto_close(n->s_hoi);
+ }
+ n->s_hoi = NULL; n->i_hoi = NULL;
+ if(n->s_dc) {
+ if(n->i_dc) {
+ dk3sto_it_close(n->i_dc);
+ }
+ dk3sto_close(n->s_dc);
+ }
+ n->s_dc = NULL; n->i_dc = NULL;
+ dk3_delete(v);
+ } $? "- itadmin_mem_network_del"
+}
+
+
+
+void
+itadmin_mem_netgroup_del(void *v)
+{
+ itadmin_netgroup *g;
+ $? "+ itadmin_mem_netgroup_del"
+ if(v) {
+ g = (itadmin_netgroup *)v; $? ". name = \"%!8s\"", TR_8STR(g->sn)
+ dk3_release(g->sn);
+ dk3_release(g->ln);
+ dk3_delete(v);
+ } $? "- itadmin_mem_netgroup_del"
+}
+
+
+
+void
+itadmin_mem_ngdep_del(void *v)
+{
+ itadmin_ngdep *d;
+ if(v) { $? "= itadmin_mem_ngdep_del"
+ d = (itadmin_ngdep *)v;
+ d->pa = NULL;
+ d->ch = NULL;
+ dk3_delete(v);
+ }
+}
+
+
+
+void
+itadmin_mem_dhcp_class_del(void *v)
+{
+ itadmin_dhcp_class *c;
+ $? "+ itadmin_mem_dhcp_class_del"
+ if(v) {
+ c = (itadmin_dhcp_class *)v; $? ". name = \"%!8s\"", TR_8STR(c->sn)
+ dk3_release(c->sn);
+ dk3_release(c->ln);
+ if(c->s_ho) {
+ if(c->i_ho) {
+ dk3sto_it_close(c->i_ho);
+ }
+ dk3sto_close(c->s_ho);
+ }
+ c->s_ho = NULL; c->i_ho = NULL;
+ c->dhcpn = NULL;
+ dk3_delete(v);
+ } $? "- itadmin_mem_dhcp_class_del"
+}
+
+
+
+void
+itadmin_mem_dhcp_pool_del(void *v)
+{
+ itadmin_dhcp_pool *p;
+ itadmin_dhcp_option *pdo;
+ $? "+ itadmin_mem_dhcp_pool_del"
+ if(v) {
+ p = (itadmin_dhcp_pool *)v;
+ p->nw = NULL;
+ p->acl = NULL; $? ". s = %lu.%lu.%lu.%lu", IP1(p->ip4s), IP2(p->ip4s), IP3(p->ip4s), IP4(p->ip4s)
+ p->ip4s = 0UL; $? ". e = %lu.%lu.%lu.%lu", IP1(p->ip4e), IP2(p->ip4e), IP3(p->ip4e), IP4(p->ip4e)
+ p->ip4e = 0UL;
+ if(p->s_do) {
+ if(p->i_do) {
+ dk3sto_it_reset(p->i_do);
+ while(NULL != (pdo = (itadmin_dhcp_option *)dk3sto_it_next(p->i_do))) {
+ itadmin_mem_dhcp_option_del((void *)pdo);
+ }
+ dk3sto_it_close(p->i_do);
+ }
+ dk3sto_close(p->s_do);
+ }
+ p->s_do = NULL; p->i_do = NULL;
+ if(p->s_hoi) {
+ if(p->i_hoi) {
+ dk3sto_it_close(p->i_hoi);
+ }
+ dk3sto_close(p->s_hoi);
+ }
+ p->s_hoi = NULL; p->i_hoi = NULL;
+ p->duc = 0x00; p->auc = 0x00;
+ dk3_delete(v);
+ } $? "- itadmin_mem_dhcp_pool_del"
+}
+
+
+
+void
+itadmin_mem_dhcp_group_del(void *v)
+{
+ itadmin_dhcp_group *g;
+ void *vp;
+ $? "+ itadmin_mem_dhcp_group_del"
+ if(v) {
+ g = (itadmin_dhcp_group *)v; $? ". name = \"%!8s\"", TR_8STR(g->sn)
+ dk3_release(g->sn);
+ dk3_release(g->ln);
+ if(g->s_do) {
+ if(g->i_do) {
+ dk3sto_it_reset(g->i_do);
+ while(NULL != (vp = dk3sto_it_next(g->i_do))) {
+ itadmin_mem_dhcp_option_del(vp);
+ }
+ dk3sto_it_close(g->i_do);
+ }
+ dk3sto_close(g->s_do);
+ }
+ g->s_do = NULL; g->i_do = NULL;
+ dk3_delete(v);
+ } $? "- itadmin_mem_dhcp_group_del"
+}
+
+
+
+void
+itadmin_mem_host_del(void *v)
+{
+ itadmin_host *h;
+ char const *c;
+ void *vp;
+ $? "+ itadmin_mem_host_del"
+ if(v) {
+ h = (itadmin_host *)v; $? ". host = \"%!8s\"", TR_8STR(h->sn)
+ dk3_release(h->sn);
+ dk3_release(h->co);
+ dk3_release(h->maca);
+ dk3_release(h->room);
+ dk3_release(h->inv);
+ dk3_release(h->serno);
+ dk3_release(h->hid);
+ dk3_release(h->dnsd);
+ h->un = NULL;
+ h->ng = NULL;
+ h->dc = NULL;
+ h->dg = NULL;
+ h->nc = NULL;
+ h->bu = NULL;
+ itadmin_mem_date_init(&(h->expi));
+ if(h->s_al) {
+ if(h->i_al) {
+ dk3sto_it_reset(h->i_al);
+ while((c = (char const *)dk3sto_it_next(h->i_al)) != NULL) {
+ dk3_delete(c);
+ }
+ dk3sto_it_close(h->i_al);
+ }
+ dk3sto_close(h->s_al);
+ }
+ h->s_al = NULL; h->i_al = NULL;
+ if(h->s_do) {
+ if(h->i_do) {
+ dk3sto_it_reset(h->i_do);
+ while(NULL != (vp = dk3sto_it_next(h->i_do))) {
+ itadmin_mem_dhcp_option_del(vp);
+ }
+ dk3sto_it_close(h->i_do);
+ }
+ dk3sto_close(h->s_do);
+ }
+ h->s_do = NULL; h->i_do = NULL;
+ if(h->s_li) {
+ if(h->i_li) {
+ dk3sto_it_close(h->i_li);
+ }
+ dk3sto_close(h->s_li);
+ }
+ h->s_li = NULL; h->i_li = NULL;
+ h->ipv4 = 0UL;
+ h->fnf = h->fgu = h->snd = h->saw = 0x00;
+ dk3_delete(v);
+ } $? "- itadmin_mem_host_del"
+}
+
+
+
+void
+itadmin_mem_sw_man_del(void *v)
+{
+ itadmin_swman *m;
+ $? "+ itadmin_mem_sw_man_del"
+ if(v) {
+ m = (itadmin_swman *)v; $? ". \"%!8s\"", TR_8STR(m->sn)
+ dk3_release(m->sn);
+ dk3_release(m->ln);
+ dk3_delete(v);
+ } $? "- itadmin_mem_sw_man_del"
+}
+
+
+
+void
+itadmin_mem_software_del(void *v)
+{
+ itadmin_swprod *p;
+ $? "+ itadmin_mem_software_del"
+ if(v) {
+ p = (itadmin_swprod *)v; $? ". \"%!8s\"", TR_8STR(p->sn)
+ dk3_release(p->sn);
+ dk3_release(p->ln);
+ p->mn = NULL;
+ dk3_delete(v);
+ } $? "- itadmin_mem_software_del"
+}
+
+
+
+void
+itadmin_mem_lic_type_del(void *v)
+{
+ itadmin_lictype *t;
+ $? "+ itadmin_mem_lic_type_del"
+ if(v) {
+ t = (itadmin_lictype *)v; $? ". \"%!8s\"", TR_8STR(t->sn)
+ dk3_release(t->sn);
+ dk3_release(t->ln);
+ t->num = 0;
+ dk3_delete(v);
+ } $? "- itadmin_mem_lic_type_del"
+}
+
+
+
+void
+itadmin_mem_license_del(void *v)
+{
+ itadmin_license *l;
+ $? "+ itadmin_mem_license_del"
+ if(v) {
+ l = (itadmin_license *)v; $? ". %lu", l->pk
+ dk3_release(l->order);
+ dk3_release(l->notes);
+ dk3_release(l->i_del);
+ dk3_release(l->i_inv);
+ itadmin_mem_date_init(&(l->d_del));
+ itadmin_mem_date_init(&(l->d_inv));
+ l->prod = NULL;
+ l->ltype = NULL;
+ l->owner = NULL;
+ l->host = NULL;
+ l->pk = 0UL;
+ dk3_delete(v);
+ } $? "- itadmin_mem_license_del"
+}
+
+
+
+/** Set a string pointer.
+ @param job Job structure.
+ @param dptr Address of destination pointer.
+ @param sstr Source pointer.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_mem_set_string(
+ itadmin_job *job,
+ char const **dptr,
+ char const *sstr
+)
+{
+ char bu[ITADMIN_CONFIG_LINE_SIZE];
+ char *p1;
+ char const *np;
+ int back = 0;
+ if(sstr) {
+ dk3_release(*dptr);
+ if(dk3str_c8_len(sstr) < sizeof(bu)) {
+ dk3str_c8_cpy_not_overlapped(bu, sstr);
+ p1 = dk3str_c8_start(bu, NULL);
+ if(p1) {
+ dk3str_c8_normalize(p1,NULL,' ');
+ np = dk3str_c8_dup_app(p1, job->app);
+ if(np) {
+ *dptr = np;
+ back = 1;
+ } else {
+ /* ERROR: Memory */
+ job->ec = DK3_ERROR_MEMORY;
+ }
+ } else {
+ back = 1; /* Empty text */
+ }
+ } else {
+ np = dk3str_c8_dup_app(sstr, job->app);
+ if(np) {
+ *dptr = np;
+ back = 1;
+ } else {
+ /* ERROR: Memory */
+ job->ec = DK3_ERROR_MEMORY;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Create new user.
+ @param job Job structure.
+ @param un Name.
+ @param tt Academic degree or title (may be NULL).
+ @param sn Surname (may be NULL).
+ @param na Name.
+ @param em E-Mail (may be NULL).
+ @param cc Cost control ID (may be NULL).
+ @param si Staff ID number (may be NULL).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_user *
+itadmin_mem_user_new(
+ itadmin_job *job,
+ char const *un,
+ char const *tt,
+ char const *sn,
+ char const *na,
+ char const *em,
+ char const *cc,
+ char const *si
+)
+{
+ itadmin_user *back = NULL;
+ int ok = 1;
+ if(un) {
+ back = dk3_new_app(itadmin_user,1,job->app);
+ if(back) {
+ back->us = NULL;
+ back->tt = NULL;
+ back->sn = NULL;
+ back->na = NULL;
+ back->em = NULL;
+ back->cc = NULL;
+ back->si = NULL;
+ back->s_ho = NULL;
+ back->i_ho = NULL;
+ back->s_li = NULL;
+ back->i_li = NULL;
+ if(un) { if(!itadmin_mem_set_string(job, &(back->us), un)) { ok = 0; } }
+ if(tt) { if(!itadmin_mem_set_string(job, &(back->tt), tt)) { ok = 0; } }
+ if(sn) { if(!itadmin_mem_set_string(job, &(back->sn), sn)) { ok = 0; } }
+ if(na) { if(!itadmin_mem_set_string(job, &(back->na), na)) { ok = 0; } }
+ if(em) { if(!itadmin_mem_set_string(job, &(back->em), em)) { ok = 0; } }
+ if(cc) { if(!itadmin_mem_set_string(job, &(back->cc), cc)) { ok = 0; } }
+ if(si) { if(!itadmin_mem_set_string(job, &(back->si), si)) { ok = 0; } }
+ if(!(ok)) {
+ itadmin_mem_user_del((void *)back);
+ back = NULL;
+ }
+ } else {
+ job->ec = DK3_ERROR_MEMORY;
+ }
+ }
+ return back;
+}
+
+
+
+/** Create new building.
+ @param job Job structure.
+ @param s Name.
+ @param l Long name (may be NULL).
+ @param a1 Address line 1 (typically street and number,
+ may be NULL).
+ @param a2 Address line 2 (may be NULL).
+ @param a3 Address line 3 (may be NULL).
+ @param a4 Address line 4 (may be NULL).
+ @param zc Zip code (may be NULL).
+ @param city Town or city name (may be NULL).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_building *
+itadmin_mem_building_new(
+ itadmin_job *job,
+ char const *s,
+ char const *l,
+ char const *a1,
+ char const *a2,
+ char const *a3,
+ char const *a4,
+ char const *zc,
+ char const *city
+)
+{
+ itadmin_building *back = NULL;
+ int ok = 1;
+ $? "+ itadmin_mem_building_new \"%!8s\"", TR_8STR(s)
+ if(s) {
+ back = dk3_new_app(itadmin_building,1,job->app);
+ if(back) { $? ". back"
+ back->s = NULL;
+ back->l = NULL;
+ back->a1 = NULL;
+ back->a2 = NULL;
+ back->a3 = NULL;
+ back->a4 = NULL;
+ back->zc = NULL;
+ back->city = NULL;
+ if(s) { if(!itadmin_mem_set_string(job, &(back->s), s)) { ok = 0; } }
+ if(l) { if(!itadmin_mem_set_string(job, &(back->l), l)) { ok = 0; } }
+ if(a1) { if(!itadmin_mem_set_string(job, &(back->a1), a1)) { ok = 0; } }
+ if(a2) { if(!itadmin_mem_set_string(job, &(back->a2), a2)) { ok = 0; } }
+ if(a3) { if(!itadmin_mem_set_string(job, &(back->a3), a3)) { ok = 0; } }
+ if(a4) { if(!itadmin_mem_set_string(job, &(back->a4), a4)) { ok = 0; } }
+ if(zc) { if(!itadmin_mem_set_string(job, &(back->zc), zc)) { ok = 0; } }
+ if(city) { if(!itadmin_mem_set_string(job, &(back->city), city)) { ok = 0; } }
+ if(!(ok)) { $? "! ok"
+ itadmin_mem_building_del((void *)back);
+ back = NULL;
+ }
+ }
+ } $? "- itadmin_mem_building_new PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/** Create new speed setting.
+ @param job Job structure.
+ @param s Name.
+ @param n Description (may be NULL).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_speed *
+itadmin_mem_speed_new(
+ itadmin_job *job,
+ char const *s,
+ char const *n
+)
+{
+ itadmin_speed *back = NULL;
+ int ok = 1;
+ if(s) {
+ back = dk3_new_app(itadmin_speed,1,job->app);
+ if(back) {
+ back->s = NULL;
+ back->l = NULL;
+ if(s) { if(!itadmin_mem_set_string(job, &(back->s), s)) { ok = 0; } }
+ if(n) { if(!itadmin_mem_set_string(job, &(back->l), n)) { ok = 0; } }
+ if(!(ok)) {
+ itadmin_mem_speed_del((void *)back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Create new VLAN.
+ @param job Job structure.
+ @param s Name.
+ @param l Long name (may be NULL).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_vlan *
+itadmin_mem_vlan_new(
+ itadmin_job *job,
+ char const *s,
+ char const *l
+)
+{
+ itadmin_vlan *back = NULL;
+ int ok = 1;
+ if(s) {
+ back = dk3_new_app(itadmin_vlan,1,job->app);
+ if(back) {
+ back->s = NULL;
+ back->l = NULL;
+ back->s_nw = NULL;
+ back->i_nw = NULL;
+ back->s_do = NULL;
+ back->i_do = NULL;
+ if(s) { if(!itadmin_mem_set_string(job, &(back->s), s)) { ok = 0; } }
+ if(l) { if(!itadmin_mem_set_string(job, &(back->l), l)) { ok = 0; } }
+ if(itadmin_job_do_dhcp(job)) {
+ back->s_nw = dk3sto_open_app(job->app);
+ if(back->s_nw) {
+ dk3sto_set_comp(back->s_nw, itadmin_comp_network, 0);
+ back->i_nw = dk3sto_it_open(back->s_nw);
+ if(back->i_nw) {
+ } else {
+ ok = 0;
+ /* ERROR: Memory */
+ }
+ } else {
+ ok = 0;
+ /* ERROR: Memory */
+ }
+ }
+ if(!(ok)) {
+ itadmin_mem_vlan_del((void *)back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Create new network connector.
+ @param job Job structure.
+ @param s Name.
+ @param hp Hub port name/number.
+ @param room Room.
+ @param sp Speed setting.
+ @param vl VLAN.
+ @param bu Building.
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_connect *
+itadmin_mem_connect_new(
+ itadmin_job *job,
+ char const *s,
+ char const *hp,
+ char const *room,
+ itadmin_speed *sp,
+ itadmin_vlan *vl,
+ itadmin_building *bu
+)
+{
+ itadmin_connect *back = NULL;
+ int ok = 1;
+ if(s) {
+ back = dk3_new_app(itadmin_connect,1,job->app);
+ if(back) {
+ back->s = NULL;
+ back->hp = NULL;
+ back->room = NULL;
+ back->sp = sp;
+ back->vl = vl;
+ back->bu = bu;
+ if(!itadmin_mem_set_string(job, &(back->s), s)) { ok = 0; }
+ if(hp) { if(!itadmin_mem_set_string(job, &(back->hp), hp)) { ok = 0; } }
+ if(room) {
+ if(!itadmin_mem_set_string(job, &(back->room), room)) { ok = 0; }
+ }
+ if(!(ok)) {
+ itadmin_mem_connect_del((void *)back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+itadmin_dhcp_ginw *
+itadmin_mem_dhcp_ginw_new(itadmin_job *job, itadmin_dhcp_group *gr)
+{
+ itadmin_dhcp_ginw *back = NULL;
+ if((job) && (gr)) {
+ back = dk3_new_app(itadmin_dhcp_ginw,1,job->app);
+ if(back) {
+ back->gr = gr;
+ back->s_h = NULL;
+ back->i_h = NULL;
+ back->s_h = dk3sto_open_app(job->app);
+ if(back->s_h) {
+ dk3sto_set_comp(back->s_h, itadmin_comp_host, 2);
+ back->i_h = dk3sto_it_open(back->s_h);
+ }
+ if(!((back->s_h) && (back->i_h))) {
+ itadmin_mem_dhcp_ginw_del(back);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Create new network.
+ @param job Job structure.
+ @param ip4 Network address.
+ @param ma4 Network mask.
+ @param gw4 Gateway.
+ @param bc4 Broadcast address.
+ @param vl VLAN.
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_network *
+itadmin_mem_network_new(
+ itadmin_job *job,
+ unsigned long ip4,
+ unsigned long ma4,
+ unsigned long gw4,
+ unsigned long bc4,
+ itadmin_vlan *vl
+)
+{
+ itadmin_network *back = NULL;
+#if 0
+ unsigned long ulip4;
+ unsigned long ulma4;
+ unsigned long ulgw4;
+ unsigned long ulbc4;
+ int ok = 1;
+ if((ip4) && (ma4) && (gw4)) {
+ back = dk3_new_app(itadmin_network,1,job->app);
+ if(back) {
+ back->ip4 = back->ma4 = back->gw4 = back->bc4 = 0UL;
+ back->vl = vl;
+ back->s_p = NULL;
+ back->i_p = NULL;
+ back->s_dg = NULL;
+ back->i_dg = NULL;
+ back->s_hoi = NULL;
+ back->i_hoi = NULL;
+ back->s_dc = NULL;
+ back->i_dc = NULL;
+ if(!dk3enc_c8_ipaddr_to_ul_app(ip4, &ulip4, job->app)) { ok = 0; }
+ if(!dk3enc_c8_ipaddr_to_ul_app(ma4, &ulma4, job->app)) { ok = 0; }
+ if(!dk3enc_c8_ipaddr_to_ul_app(gw4, &ulgw4, job->app)) { ok = 0; }
+ if(bc4) {
+ if(!dk3enc_c8_ipaddr_to_ul_app(bc4, &ulbc4, job->app)) { ok = 0; }
+ } else {
+ ulbc4 = ((~(ulip4 & ulma4)) | ulip4);
+ }
+ back->ip4 = ulip4;
+ back->ma4 = ulma4;
+ back->gw4 = ulgw4;
+ back->bc4 = ulbc4;
+ if(job->f_dh) {
+ back->s_p = dk3sto_open_app(job->app);
+ if(back->s_p) {
+ dk3sto_set_comp(back->s_p, itadmin_comp_dhcp_pool, 0);
+ back->i_p = dk3sto_it_open(back->s_p);
+ if(back->i_p) {
+ back->s_dg = dk3sto_open_app(job->app);
+ if(back->s_dg) {
+ dk3sto_set_comp(back->s_dg, itadmin_comp_dhcp_ginw, 0);
+ back->i_dg = dk3sto_it_open(back->s_dg);
+ if(back->i_dg) {
+ /* Success. */
+ } else {
+ ok = 0;
+ }
+ } else {
+ ok = 0;
+ }
+ } else {
+ ok = 0;
+ }
+ } else { ok = 0; }
+ }
+ if(!(ok)) {
+ itadmin_mem_network_del((void *)back);
+ back = NULL;
+ }
+ }
+ }
+#else
+ if((ip4) && (ma4)) {
+ int ok;
+ back = dk3_new_app(itadmin_network,1,job->app);
+ if(back) {
+ ok = 1;
+ back->ip4 = ip4;
+ back->ma4 = ma4;
+ back->gw4 = gw4;
+ back->bc4 = bc4;
+ back->vl = vl;
+ back->s_p = NULL;
+ back->i_p = NULL;
+ back->s_do = NULL;
+ back->i_do = NULL;
+ if(itadmin_job_do_dhcp(job)) {
+ ok = 0;
+ back->s_p = dk3sto_open_app(job->app);
+ if(back->s_p) {
+ dk3sto_set_comp(back->s_p, itadmin_comp_dhcp_pool, 0);
+ back->i_p = dk3sto_it_open(back->s_p);
+ if(back->i_p) {
+ ok = 1;
+ }
+ }
+ }
+ if(!(ok)) {
+ itadmin_mem_network_del((void *)back);
+ back = NULL;
+ }
+ }
+ }
+#endif
+ return back;
+}
+
+
+
+/** Create new netgroup
+ @param job Job structure.
+ @param sn Short name.
+ @param ln Long name (may be NULL).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_netgroup *
+itadmin_mem_netgroup_new(
+ itadmin_job *job,
+ char const *sn,
+ char const *ln
+)
+{
+ itadmin_netgroup *back = NULL;
+ int ok = 1;
+ if(sn) {
+ back = dk3_new_app(itadmin_netgroup,1,job->app);
+ if(back) {
+ back->no = 0;
+ back->ln = NULL;
+ if(sn) { if(!itadmin_mem_set_string(job, &(back->sn), sn)) { ok = 0; } }
+ if(ln) { if(!itadmin_mem_set_string(job, &(back->ln), ln)) { ok = 0; } }
+ if(!(ok)) {
+ itadmin_mem_netgroup_del((void *)back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Create new netgroup dependency.
+ @param job Job structure.
+ @param pa Parent group.
+ @param ch Child group.
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_ngdep *
+itadmin_mem_ngdep_new(
+ itadmin_job *job,
+ itadmin_netgroup *pa,
+ itadmin_netgroup *ch
+)
+{
+ itadmin_ngdep *back = NULL;
+ if((pa) && (ch)) {
+ back = dk3_new_app(itadmin_ngdep,1,job->app);
+ if(back) {
+ back->pa = pa;
+ back->ch = ch;
+ }
+ }
+ return back;
+}
+
+
+
+/** Create new DHCP class.
+ @param job Job structure.
+ @param sn Short name.
+ @param ln Long name (may be NULL).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_dhcp_class *
+itadmin_mem_dhcp_class_new(
+ itadmin_job *job,
+ char const *sn,
+ char const *ln
+)
+{
+ itadmin_dhcp_class *back = NULL;
+ int ok = 1;
+ if(sn) {
+ back = dk3_new_app(itadmin_dhcp_class,1,job->app);
+ if(back) {
+ back->s_ho = NULL;
+ back->i_ho = NULL;
+ back->dhcpn = NULL;
+ if(!itadmin_mem_set_string(job, &(back->sn), sn)) { ok = 0; }
+ if(ln) { if(!itadmin_mem_set_string(job, &(back->ln), ln)) { ok = 0; } }
+ if(!(ok)) {
+ itadmin_mem_dhcp_class_del((void *)back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Create new DHCP pool.
+ @param job Job structure.
+ @param nw Network.
+ @param cn Allowed class (if unknown clients are denied,
+ may be NULL).
+ @param ip4s IPv4 start address.
+ @param ip4e IPv4 end address.
+ @param duc Flag: Deny unknown clients (needs cn).
+ @param auc Flag: Allow unknown clients.
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_dhcp_pool *
+itadmin_mem_dhcp_pool_new(
+ itadmin_job *job,
+ itadmin_network *nw,
+ itadmin_dhcp_class *cn,
+ unsigned long ip4s,
+ unsigned long ip4e,
+ int duc,
+ int auc
+)
+{
+ char buffer[128];
+ itadmin_dhcp_pool *back = NULL;
+ int ok = 1;
+ $? "+ itadmin_mem_dhcp_pool_new"
+ if((nw) && (ip4s) && (ip4e)) {
+ back = dk3_new_app(itadmin_dhcp_pool,1,job->app);
+ if(back) {
+ back->nw = nw;
+ back->acl = cn;
+ back->s_do = NULL;
+ back->i_do = NULL;
+ back->s_hoi = NULL;
+ back->i_hoi = NULL;
+ back->ip4s = ip4s;
+ back->ip4e = ip4e;
+ back->duc = ((duc) ? 0x01 : 0x00);
+ back->auc = ((auc) ? 0x01 : 0x00);
+ if((duc) && (auc)) {
+ ok = 0;
+ /* ERROR: can not allow and deny at same time! */
+ sprintf(
+ buffer,
+ "%lu.%lu.%lu.%lu",
+ ((ip4s >> 24) & 0x000000FFUL),
+ ((ip4s >> 16) & 0x000000FFUL),
+ ((ip4s >> 8) & 0x000000FFUL),
+ (ip4s & 0x000000FFUL)
+ );
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 134, 135, buffer);
+ }
+ if(!(ok)) {
+ itadmin_mem_dhcp_pool_del((void *)back);
+ back = NULL;
+ }
+ }
+ } $? "- itadmin_mem_dhcp_pool_new PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/** Create new DHCP group.
+ @param job Job structure.
+ @param sn Short name.
+ @param ln Long name (may be NULL).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_dhcp_group *
+itadmin_mem_dhcp_group_new(
+ itadmin_job *job,
+ char const *sn,
+ char const *ln
+)
+{
+ itadmin_dhcp_group *back = NULL;
+ int ok = 1;
+ if(sn) {
+ back = dk3_new_app(itadmin_dhcp_group,1,job->app);
+ if(back) {
+ back->sn = NULL;
+ back->ln = NULL;
+ back->s_do = NULL;
+ back->i_do = NULL;
+ if(!itadmin_mem_set_string(job, &(back->sn), sn)) { ok = 0; }
+ if(ln) { if(!itadmin_mem_set_string(job, &(back->ln), ln)) { ok = 0; } }
+ if(!(ok)) {
+ itadmin_mem_dhcp_group_del((void *)back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Create new host
+ @param job Job structure.
+ @param sn Short name.
+ @param co Comment/description (may be NULL).
+ @param maca MAC address (may be NULL).
+ @param room Room (may be NULL).
+ @param inv Inventory number (may be NULL).
+ @param serno Serial number (may be NULL).
+ @param hid Host ID (may be NULL).
+ @param expi Expiration date (may be NULL).
+ @param dnsd DNS domain (may be NULL).
+ @param un System owner.
+ @param ng Netgroup (may be NULL).
+ @param dc DHCP class (may be NULL).
+ @param dg DHCP group (may be NULL).
+ @param nc Network connection socket (may be NULL).
+ @param bu Building (may be NULL).
+ @param ipv4 IPv4 address (may be NULL).
+ @param fnf Flag: FQDN first in hosts file.
+ @param fgu Flag: Guest computer (bring your own device).
+ @param snd Flag: Skip in network documentation.
+ @param saw Flag: Skip in arpwatch configuration.
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_host *
+itadmin_mem_host_new(
+ itadmin_job *job,
+ itadmin_date *expi,
+ char const *sn,
+ char const *co,
+ char const *maca,
+ char const *room,
+ char const *inv,
+ char const *serno,
+ char const *hid,
+ char const *dnsd,
+ itadmin_user *un,
+ itadmin_netgroup *ng,
+ itadmin_dhcp_class *dc,
+ itadmin_dhcp_group *dg,
+ itadmin_connect *nc,
+ itadmin_building *bu,
+ unsigned long ipv4,
+ int fnf,
+ int fgu,
+ int snd,
+ int saw
+)
+{
+ itadmin_host *back = NULL;
+ int ok = 1;
+ $? "+ itadmin_mem_host_new"
+ $? ". sn = \"%!8s\"", TR_8STR(sn)
+ $? ". co = \"%!8s\"", TR_8STR(co)
+ $? ". maca = \"%!8s\"", TR_8STR(maca)
+ $? ". room = \"%!8s\"", TR_8STR(room)
+ $? ". inv = \"%!8s\"", TR_8STR(inv)
+ $? ". serno = \"%!8s\"", TR_8STR(serno)
+ $? ". hid = \"%!8s\"", TR_8STR(hid)
+ $? ". dnsd = \"%!8s\"", TR_8STR(dnsd)
+ $? ". ipv4 = %lu", ipv4
+ $? ". fnf = %d", fnf
+ $? ". fgu = %d", fgu
+ $? ". snd = %d", snd
+ $? ". saw = %d", saw
+ if(sn) { $? ". sn"
+ back = dk3_new_app(itadmin_host,1,job->app);
+ if(back) { $? ". back"
+ back->sn = back->co = back->maca = back->room = back->inv = back->serno
+ = back->hid = back->dnsd = NULL;
+ itadmin_mem_date_init(&(back->expi));
+ back->un = un;
+ back->ng = ng;
+ back->dc = dc;
+ back->dg = dg;
+ back->nc = nc;
+ back->bu = bu;
+ back->s_al = NULL;
+ back->i_al = NULL;
+ back->s_do = NULL;
+ back->i_do = NULL;
+ back->s_li = NULL;
+ back->i_li = NULL;
+ back->ipv4 = ipv4;
+ back->fnf = ((fnf) ? 0x01 : 0x00);
+ back->fgu = (char)fgu;
+ back->snd = ((snd) ? 0x01 : 0x00);
+ back->saw = ((saw) ? 0x01 : 0x00);
+ back->dp = NULL;
+ if(!itadmin_mem_set_string(job, &(back->sn), sn)) {
+ ok = 0; $? "! sn"
+ }
+ if(co) {
+ if(!itadmin_mem_set_string(job, &(back->co), co)) {
+ ok = 0; $? "! co"
+ }
+ }
+ if(maca) {
+ if(!itadmin_mem_set_string(job, &(back->maca), maca)) {
+ ok = 0; $? "! maca"
+ }
+ }
+ if(room) {
+ if(!itadmin_mem_set_string(job, &(back->room), room)) {
+ ok = 0; $? "! room"
+ }
+ }
+ if(inv) {
+ if(!itadmin_mem_set_string(job, &(back->inv), inv)) {
+ ok = 0; $? "! inv"
+ }
+ }
+ if(serno) {
+ if(!itadmin_mem_set_string(job, &(back->serno), serno)) {
+ ok = 0; $? "! serno"
+ }
+ }
+ if(hid) {
+ if(!itadmin_mem_set_string(job, &(back->hid), hid)) {
+ ok = 0; $? "! hostid"
+ }
+ }
+ if(expi) {
+ itadmin_mem_date_copy(&(back->expi), expi);
+ }
+ if(dnsd) {
+ if(!itadmin_mem_set_string(job, &(back->dnsd), dnsd)) {
+ ok = 0; $? "! dnsd"
+ }
+ }
+ back->s_al = dk3sto_open_app(job->app);
+ if(back->s_al) {
+ /* SET COMPARISON FUNCTION */
+ dk3sto_set_comp(back->s_al, itadmin_comp_string, 0);
+ back->i_al = dk3sto_it_open(back->s_al);
+ if(!(back->i_al)) { ok = 0; }
+ } else { ok = 0; }
+ if(!(ok)) { $? "! ok"
+ itadmin_mem_host_del((void *)back);
+ back = NULL;
+ }
+ } else { $? "! memory"
+ }
+ } else { $? "! sn"
+ } $? "- itadmin_mem_host_new PTR=%d", TR_IPTR(back)
+ return back;
+}
+
+
+
+/** Create new software manufacturer.
+ @param job Job structure.
+ @param sn Short name.
+ @param ln Long name (description).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_swman *
+itadmin_mem_swman_new(
+ itadmin_job *job,
+ char const *sn,
+ char const *ln
+)
+{
+ itadmin_swman *back = NULL;
+ int ok = 1;
+ if(sn) {
+ back = dk3_new_app(itadmin_swman,1,job->app);
+ if(back) {
+ back->sn = NULL;
+ back->ln = NULL;
+ if(!itadmin_mem_set_string(job, &(back->sn), sn)) { ok = 0; }
+ if(ln) { if(!itadmin_mem_set_string(job, &(back->ln), ln)) { ok = 0; } }
+ if(!(ok)) {
+ itadmin_mem_sw_man_del((void *)back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Create new software product.
+ @param job Job structure.
+ @param sn Short name.
+ @param ln Long name.
+ @param mn Software manufacturer (may be NULL).
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_swprod *
+itadmin_mem_swprod_new(
+ itadmin_job *job,
+ char const *sn,
+ char const *ln,
+ itadmin_swman *mn
+)
+{
+ itadmin_swprod *back = NULL;
+ int ok = 1;
+ if(sn) {
+ back = dk3_new_app(itadmin_swprod,1,job->app);
+ if(back) {
+ back->sn = NULL;
+ back->ln = NULL;
+ back->mn = mn;
+ if(!itadmin_mem_set_string(job, &(back->sn), sn)) { ok = 0; }
+ if(ln) { if(!itadmin_mem_set_string(job, &(back->ln), ln)) { ok = 0; } }
+ if(!(ok)) {
+ itadmin_mem_software_del((void *)back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Create new license type.
+ @param job Job structure.
+ @param sn Short license type name.
+ @param ln Long name (description).
+ @param num Number of client licenses for floating license servers.
+ @return Pointer to new object on success, NULL on error.
+*/
+itadmin_lictype *
+itadmin_mem_lictype_new(
+ itadmin_job *job,
+ char const *sn,
+ char const *ln,
+ int num
+)
+{
+ itadmin_lictype *back = NULL;
+ int ok = 1;
+ if(sn) {
+ back = dk3_new_app(itadmin_lictype,1,job->app);
+ if(back) {
+ back->sn = NULL; back->ln = NULL; back->num = num;
+ if(!itadmin_mem_set_string(job, &(back->sn), sn)) { ok = 0; }
+ if(ln) { if(!itadmin_mem_set_string(job, &(back->ln), ln)) { ok = 0; } }
+ if(!(ok)) {
+ itadmin_mem_lic_type_del((void *)back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+itadmin_license *
+itadmin_mem_license_new(
+ itadmin_job *job,
+ unsigned long pk,
+ char const *order,
+ char const *notes,
+ itadmin_date *d_del,
+ char const *i_del,
+ itadmin_date *d_inv,
+ char const *i_inv,
+ itadmin_swprod *prod,
+ itadmin_lictype *ltype,
+ itadmin_user *owner,
+ itadmin_host *host
+)
+{
+ itadmin_license *back = NULL;
+ int ok = 1;
+ if(prod) {
+ back = dk3_new_app(itadmin_license,1,job->app);
+ if(back) {
+ back->order = NULL;
+ back->notes = NULL;
+ itadmin_mem_date_init(&(back->d_del));
+ back->i_del = NULL;
+ itadmin_mem_date_init(&(back->d_inv));
+ back->i_inv = NULL;
+ back->pk = pk;
+ back->prod = prod;
+ back->ltype = ltype;
+ back->owner = owner;
+ back->host = host;
+ if(order) {
+ if(!itadmin_mem_set_string(job, &(back->order), order)) { ok = 0; }
+ }
+ if(notes) {
+ if(!itadmin_mem_set_string(job, &(back->notes), notes)) { ok = 0; }
+ }
+ if(i_del) {
+ if(!itadmin_mem_set_string(job, &(back->i_del), i_del)) { ok = 0; }
+ }
+ if(i_inv) {
+ if(!itadmin_mem_set_string(job, &(back->i_inv), i_inv)) { ok = 0; }
+ }
+ if(!(ok)) {
+ itadmin_mem_license_del((void *)back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void
+itadmin_mem_dhcp_option_del(void *v)
+{
+ itadmin_dhcp_option *o;
+ $? "+ itadmin_dhcp_option_del"
+ if(v) {
+ o = (itadmin_dhcp_option *)v; $? ". \"%!8s\"=\"%!8s\"",TR_8STR(o->k),TR_8STR(o->v)
+ dk3_release(o->k);
+ dk3_release(o->v);
+ dk3_release(o);
+ } $? "- itadmin_dhcp_option_del"
+}
+
+
+
+itadmin_dhcp_option *
+itadmin_mem_dhcp_option_new(
+ itadmin_job *job,
+ char const *k,
+ char const *v,
+ long pk
+)
+{
+ itadmin_dhcp_option *back = NULL;
+ int ok = 1;
+ if((job) && (k)) {
+ back = dk3_new_app(itadmin_dhcp_option,1,job->app);
+ if(back) {
+ back->k = NULL;
+ back->v = NULL;
+ back->pk = pk;
+ if(!itadmin_mem_set_string(job, &(back->k), k)) { ok = 0; }
+ if(v) { if(!itadmin_mem_set_string(job, &(back->v), v)) { ok = 0; } }
+ if(!(ok)) {
+ itadmin_mem_dhcp_option_del((void *)back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+itadmin_swman *
+itadmin_mem_sw_man_new(itadmin_job *job, char const *sn, char const *ln)
+{
+ itadmin_swman *back = NULL;
+ int ok = 1;
+ if((job) && (sn)) {
+ back = dk3_new_app(itadmin_swman,1,job->app);
+ if(back) {
+ back->sn = NULL;
+ back->ln = NULL;
+ if(sn) { if(!itadmin_mem_set_string(job, &(back->sn), sn)) { ok = 0; } }
+ if(ln) { if(!itadmin_mem_set_string(job, &(back->ln), ln)) { ok = 0; } }
+ if(!(ok)) {
+ itadmin_mem_sw_man_del(back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
diff --git a/support/dktools/itamysql.c b/support/dktools/itamysql.c
new file mode 100644
index 0000000000..130e87829e
--- /dev/null
+++ b/support/dktools/itamysql.c
@@ -0,0 +1,2353 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: itamysql.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file itamysql.c The itamysql module.
+*/
+
+
+#line 10 "itamysql.ctr"
+
+#include "dk3all.h"
+#include "itadmin.h"
+
+#if DK3_HAVE_MYSQL_MYSQL_H
+#include <mysql/mysql.h>
+#else
+#if DK3_HAVE_MYSQL_H
+#include <mysql.h>
+#endif
+#endif
+
+
+
+
+
+#line 25 "itamysql.ctr"
+
+
+
+#if DK3_HAVE_MYSQL_MYSQL_H || DK3_HAVE_MYSQL_H
+
+
+/** Keywords used by this module.
+*/
+static char const *itadmin_mysql_c8_kw[] = {
+/* 0 */
+"select * from users",
+
+/* 1 */
+"select * from buildings",
+
+/* 2 */
+"select * from vlans",
+
+/* 3 */
+"select * from patches",
+
+/* 4 */
+"select * from ddspeed",
+
+/* 5 */
+"select * from networks",
+
+/* 6 */
+"select * from netgroups",
+
+/* 7 */
+"select * from ngdeps",
+
+/* 8 */
+"select * from dhcpclasses",
+
+/* 9 */
+"select * from dhcpgroups",
+
+/* 10 */
+"select * from dhcppools",
+
+/* 11 */
+"select * from computers",
+
+/* 12 */
+"select * from aliases",
+
+/* 13 */
+"select * from dhcpoptions",
+
+/* 14 */
+"select * from swmanufacturers",
+
+/* 15 */
+"select * from swproducts",
+
+/* 16 */
+"select * from licensetypes",
+
+/* 17 */
+"select * from licenses",
+
+NULL
+
+
+#line 108 "itamysql.ctr"
+};
+
+
+
+/** Configuration section name "itadmin".
+*/
+static char itadmin_mysql_arg_0[] = {
+ 'i', 't', 'a', 'd', 'm', 'i', 'n', '\0'
+};
+
+
+/** Configuration section name "client".
+*/
+static char itadmin_mysql_gr_client[] = {
+ 'c', 'l', 'i', 'e', 'n', 't', '\0'
+};
+
+
+/** Argv array to initialize the library.
+*/
+static char *itadmin_mysql_argv[] = {
+ itadmin_mysql_arg_0,
+ NULL
+};
+
+
+/** Groups (configuration file section) names.
+*/
+static char *itadmin_mysql_groups[] = {
+ itadmin_mysql_gr_client,
+ itadmin_mysql_arg_0,
+ NULL
+};
+
+
+/** Elements from users table.
+*/
+static char const * const itadmin_mysql_cn_users[] = {
+/* 0 */
+"us_s",
+
+/* 1 */
+"us_t",
+
+/* 2 */
+"us_sn",
+
+/* 3 */
+"us_fn",
+
+/* 4 */
+"us_em",
+
+/* 5 */
+"us_ko",
+
+/* 6 */
+"us_se",
+
+NULL
+
+
+#line 155 "itamysql.ctr"
+};
+
+/** Number of elements in itadmin_mysql_cn_users.
+*/
+static size_t const itadmin_mysql_sz_cn_users =
+sizeof(itadmin_mysql_cn_users)/sizeof(DK3_PCCHAR) - 1;
+
+
+/** Elements from buildings table.
+*/
+static char const * const itadmin_mysql_cn_buildings[] = {
+/* 0 */
+"gb_s",
+
+/* 1 */
+"gb_l",
+
+/* 2 */
+"gb_a1",
+
+/* 3 */
+"gb_a2",
+
+/* 4 */
+"gb_a3",
+
+/* 5 */
+"gb_a4",
+
+/* 6 */
+"gb_plz",
+
+/* 7 */
+"gb_ort",
+
+NULL
+
+
+#line 176 "itamysql.ctr"
+};
+
+/** Number of elements in itadmin_mysql_cn_buildings.
+*/
+static size_t const itadmin_mysql_sz_cn_buildings =
+sizeof(itadmin_mysql_cn_buildings)/sizeof(DK3_PCCHAR) - 1;
+
+
+/** Elements from speed table.
+*/
+static char const * const itadmin_mysql_cn_speed[] = {
+/* 0 */
+"sp_s",
+
+/* 1 */
+"sp_l",
+
+NULL
+
+
+#line 191 "itamysql.ctr"
+};
+
+/** Number of elements in itadmin_mysql_cn_speed.
+*/
+static size_t const itadmin_mysql_sz_cn_speed =
+sizeof(itadmin_mysql_cn_speed)/sizeof(DK3_PCCHAR) - 1;
+
+
+/** Elements from vlan table.
+*/
+static char const * const itadmin_mysql_cn_vlan[] = {
+/* 0 */
+"vl_s",
+
+/* 1 */
+"vl_l",
+
+NULL
+
+
+#line 206 "itamysql.ctr"
+};
+
+/** Number of elements in itadmin_mysql_cn_vlan.
+*/
+static size_t const itadmin_mysql_sz_cn_vlan =
+sizeof(itadmin_mysql_cn_vlan)/sizeof(DK3_PCCHAR) - 1;
+
+
+/** Elements from patch table.
+*/
+static char const * const itadmin_mysql_cn_patch[] = {
+/* 0 */
+"dd_n",
+
+/* 1 */
+"sp_s",
+
+/* 2 */
+"vl_s",
+
+/* 3 */
+"dd_p",
+
+/* 4 */
+"gb_s",
+
+/* 5 */
+"dd_r",
+
+NULL
+
+
+#line 225 "itamysql.ctr"
+};
+
+/** Number of elements in itadmin_mysql_cn_patch.
+*/
+static size_t const itadmin_mysql_sz_cn_patch =
+sizeof(itadmin_mysql_cn_patch)/sizeof(DK3_PCCHAR) - 1;
+
+
+/** Elements from netgroup table.
+*/
+static char const * const itadmin_mysql_cn_netgroup[] = {
+/* 0 */
+"ng_s",
+
+/* 1 */
+"ng_l",
+
+NULL
+
+
+#line 240 "itamysql.ctr"
+};
+
+/** Number of elements in itadmin_mysql_cn_netgroup.
+*/
+static size_t const itadmin_mysql_sz_cn_netgroup =
+sizeof(itadmin_mysql_cn_netgroup)/sizeof(DK3_PCCHAR) - 1;
+
+
+/** Elements from dhcp_option table.
+*/
+static char const * const itadmin_mysql_cn_dhcp_option[] = {
+/* 0 */
+"do_pk",
+
+/* 1 */
+"do_sc",
+
+/* 2 */
+"do_sn",
+
+/* 3 */
+"do_n",
+
+/* 4 */
+"do_v",
+
+NULL
+
+
+#line 258 "itamysql.ctr"
+};
+
+/** Number of elements in itadmin_mysql_cn_dhcp_option.
+*/
+static size_t const itadmin_mysql_sz_cn_dhcp_option =
+sizeof(itadmin_mysql_cn_dhcp_option)/sizeof(DK3_PCCHAR) - 1;
+
+
+/** Elements from swman table.
+*/
+static char const * const itadmin_mysql_cn_swman[] = {
+/* 0 */
+"sm_s",
+
+/* 1 */
+"sm_l",
+
+NULL
+
+
+#line 273 "itamysql.ctr"
+};
+
+/** Number of elements in itadmin_mysql_cn_swman.
+*/
+static size_t const itadmin_mysql_sz_cn_swman =
+sizeof(itadmin_mysql_cn_swman)/sizeof(DK3_PCCHAR) - 1;
+
+
+/** Elements from swprod table.
+*/
+static char const * const itadmin_mysql_cn_swprod[] = {
+/* 0 */
+"sw_s",
+
+/* 1 */
+"sw_l",
+
+/* 2 */
+"sm_s",
+
+NULL
+
+
+#line 289 "itamysql.ctr"
+};
+
+/** Number of elements in itadmin_mysql_cn_swprod.
+*/
+static size_t const itadmin_mysql_sz_cn_swprod =
+sizeof(itadmin_mysql_cn_swprod)/sizeof(DK3_PCCHAR) - 1;
+
+
+/** Elements from lictype table.
+*/
+static char const * const itadmin_mysql_cn_lictype[] = {
+/* 0 */
+"lt_s",
+
+/* 1 */
+"lt_l",
+
+/* 2 */
+"lt_i",
+
+NULL
+
+
+#line 305 "itamysql.ctr"
+};
+
+/** Number of elements in itadmin_mysql_cn_lictype.
+*/
+static size_t const itadmin_mysql_sz_cn_lictype =
+sizeof(itadmin_mysql_cn_lictype)/sizeof(DK3_PCCHAR) - 1;
+
+
+/** Elements from license table.
+*/
+static char const * const itadmin_mysql_cn_license[] = {
+/* 0 */
+"li_pk",
+
+/* 1 */
+"li_on",
+
+/* 2 */
+"sw_s",
+
+/* 3 */
+"us_s",
+
+/* 4 */
+"co_s",
+
+/* 5 */
+"lt_s",
+
+/* 6 */
+"li_no",
+
+/* 7 */
+"sr_s",
+
+/* 8 */
+"li_dd",
+
+/* 9 */
+"li_nd",
+
+/* 10 */
+"li_di",
+
+/* 11 */
+"li_ni",
+
+NULL
+
+
+#line 343 "itamysql.ctr"
+};
+
+/** Number of elements in itadmin_mysql_cn_license.
+*/
+static size_t const itadmin_mysql_sz_cn_license =
+sizeof(itadmin_mysql_cn_license)/sizeof(DK3_PCCHAR) - 1;
+
+
+/** Elements from ngdep table.
+*/
+static char const * const itadmin_mysql_cn_ngdep[] = {
+/* 0 */
+"nd_p",
+
+/* 1 */
+"nd_c",
+
+NULL
+
+
+#line 358 "itamysql.ctr"
+};
+
+/** Number of elements in itadmin_mysql_cn_ngdep.
+*/
+static size_t const itadmin_mysql_sz_cn_ngdep =
+sizeof(itadmin_mysql_cn_ngdep)/sizeof(DK3_PCCHAR) - 1;
+
+
+/** Elements from hosts table.
+*/
+static char const * const itadmin_mysql_cn_hosts[] = {
+/* 0 */
+"co_s",
+
+/* 1 */
+"us_s",
+
+/* 2 */
+"co_ip",
+
+/* 3 */
+"co_mc",
+
+/* 4 */
+"ng_s",
+
+/* 5 */
+"co_co",
+
+/* 6 */
+"dc_s",
+
+/* 7 */
+"dg_s",
+
+/* 8 */
+"dd_n",
+
+/* 9 */
+"gb_s",
+
+/* 10 */
+"co_r",
+
+/* 11 */
+"co_in",
+
+/* 12 */
+"co_sn",
+
+/* 13 */
+"co_dd",
+
+/* 14 */
+"co_ff",
+
+/* 15 */
+"co_gu",
+
+/* 16 */
+"co_hi",
+
+/* 17 */
+"co_ex",
+
+/* 18 */
+"co_nn",
+
+/* 19 */
+"co_na",
+
+NULL
+
+
+#line 391 "itamysql.ctr"
+};
+
+/** Number of elements in itadmin_mysql_cn_hosts.
+*/
+static size_t const itadmin_mysql_sz_cn_hosts =
+sizeof(itadmin_mysql_cn_hosts)/sizeof(DK3_PCCHAR) - 1;
+
+
+/** Elements from network table.
+*/
+static char const * const itadmin_mysql_cn_network[] = {
+/* 0 */
+"nw_ip",
+
+/* 1 */
+"nw_ma",
+
+/* 2 */
+"nw_gw",
+
+/* 3 */
+"nw_bc",
+
+/* 4 */
+"vl_s",
+
+NULL
+
+
+#line 409 "itamysql.ctr"
+};
+
+/** Number of elements in itadmin_mysql_cn_network.
+*/
+static size_t const itadmin_mysql_sz_cn_network =
+sizeof(itadmin_mysql_cn_network)/sizeof(DK3_PCCHAR) - 1;
+
+
+/** Elements from dhcp_class table.
+*/
+static char const * const itadmin_mysql_cn_dhcp_class[] = {
+/* 0 */
+"dc_s",
+
+/* 1 */
+"dc_d",
+
+NULL
+
+
+#line 424 "itamysql.ctr"
+};
+
+/** Number of elements in itadmin_mysql_cn_dhcp_class.
+*/
+static size_t const itadmin_mysql_sz_cn_dhcp_class =
+sizeof(itadmin_mysql_cn_dhcp_class)/sizeof(DK3_PCCHAR) - 1;
+
+
+/** Elements from dhcp_group table.
+*/
+static char const * const itadmin_mysql_cn_dhcp_group[] = {
+/* 0 */
+"dg_s",
+
+/* 1 */
+"dg_l",
+
+NULL
+
+
+#line 439 "itamysql.ctr"
+};
+
+/** Number of elements in itadmin_mysql_cn_dhcp_group.
+*/
+static size_t const itadmin_mysql_sz_cn_dhcp_group =
+sizeof(itadmin_mysql_cn_dhcp_group)/sizeof(DK3_PCCHAR) - 1;
+
+
+/** Elements from dhcp_pool table.
+*/
+static char const * const itadmin_mysql_cn_dhcp_pool[] = {
+/* 0 */
+"dp_st",
+
+/* 1 */
+"dp_en",
+
+/* 2 */
+"nw_ip",
+
+/* 3 */
+"dp_al",
+
+/* 4 */
+"dp_dn",
+
+/* 5 */
+"dc_s",
+
+NULL
+
+
+#line 458 "itamysql.ctr"
+};
+
+/** Number of elements in itadmin_mysql_cn_dhcp_pool.
+*/
+static size_t const itadmin_mysql_sz_cn_dhcp_pool =
+sizeof(itadmin_mysql_cn_dhcp_pool)/sizeof(DK3_PCCHAR) - 1;
+
+
+/** Elements from alias table.
+*/
+static char const * const itadmin_mysql_cn_alias[] = {
+/* 0 */
+"al_s",
+
+/* 1 */
+"co_s",
+
+NULL
+
+
+#line 473 "itamysql.ctr"
+};
+
+/** Number of elements in itadmin_mysql_cn_alias.
+*/
+static size_t const itadmin_mysql_sz_cn_alias =
+sizeof(itadmin_mysql_cn_alias)/sizeof(DK3_PCCHAR) - 1;
+
+
+#if VERSION_BEFORE_20120208
+/** Obtain int value from string.
+ @param job Job structure.
+ @param ptr String to convert.
+ @param lgt Length of string.
+ @param def Default value to use if conversion fails.
+ @return The value or the default value.
+*/
+static
+int
+itadmin_mysql_read_int(itadmin_job *job, char const *ptr, size_t lgt, int def)
+{
+ int back;
+ int i;
+
+
+#line 496 "itamysql.ctr"
+ back = def;
+ if(ptr) {
+ if(lgt) {
+ if(sscanf(ptr, "%d", &i) == 1) {
+ back = i;
+
+#line 501 "itamysql.ctr"
+ }
+ }
+ }
+
+#line 504 "itamysql.ctr"
+ return back;
+}
+#else
+/** Obtain int value from string.
+ @param job Job structure.
+ @param ptr String to convert.
+ @param lgts Lengths of strings.
+ @param cnind Column name indices.
+ @param ind Current index to use.
+ @param def Default value to use if conversion fails.
+ @return The value or the default value.
+*/
+static
+int
+itadmin_mysql_read_int(
+ itadmin_job *job,
+ char const *ptr,
+ unsigned long *lgts,
+ size_t *cnind,
+ size_t ind,
+ int def
+)
+{
+ int back;
+ int i;
+
+
+#line 530 "itamysql.ctr"
+ back = def;
+ if(ptr) {
+ if(cnind[ind] != 0xFFFFU) {
+ if(lgts[cnind[ind]]) {
+ if(sscanf(ptr, "%d", &i) == 1) {
+ back = i;
+ }
+ }
+ }
+ }
+
+#line 540 "itamysql.ctr"
+ return back;
+}
+#endif
+
+
+/** Find column name indices.
+ For column names not found the program sets the index
+ to 0xFFFFU.
+ @param job Job structure.
+ @param cnind Destination array for indices.
+ @param sz_cnind Size of @a cnind.
+ @param nf Number of fields in query result.
+ @param mr Query result.
+ @param colnames Column names.
+*/
+static
+void
+itadmin_data_mysql_find_indices(
+ itadmin_job *job,
+ size_t *cnind,
+ size_t sz_cnind,
+ size_t nf,
+ MYSQL_RES *mr,
+ char const * const *colnames
+)
+{
+ MYSQL_FIELD *field;
+ size_t i;
+ int ai;
+ for(i = 0; i < sz_cnind; i++) { cnind[i] = 0xFFFFU; }
+ for(i = 0; i < nf; i++) {
+ field = mysql_fetch_field_direct(mr, i);
+ if(field) {
+ if(field->name) {
+ ai = dk3str_c8_array_index(colnames, field->name, 0);
+ if(ai >= 0) {
+ if(((size_t)ai) < sz_cnind) {
+ cnind[(size_t)ai] = i;
+ }
+ }
+ }
+ }
+ }
+}
+
+
+
+/** Set value pointers.
+ @param job Job structure.
+ @param val Value pointers array.
+ @param cnind Index array.
+ @param sz_cnind Size of @a val and @a cnind.
+ @param nf Number of fields in @a mrow.
+ @param mrow One result row.
+ @param lgts Array of string lengths for row.
+*/
+static
+void
+itadmin_data_mysql_set_pointers(
+ itadmin_job *job,
+ char const * *val,
+ size_t *cnind,
+ size_t sz_cnind,
+ size_t nf,
+ MYSQL_ROW mrow,
+ unsigned long *lgts
+)
+{
+ size_t i;
+ size_t j;
+ for(i = 0; i < sz_cnind; i++) {
+ val[i] = NULL;
+ if(cnind[i] != 0xFFFFU) {
+ j = cnind[i];
+ if(j < nf) {
+ if(lgts[j]) {
+ if(mrow[j]) {
+ val[i] = mrow[j];
+ }
+ }
+ }
+ }
+ }
+}
+
+
+
+/** Read aliases table.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_alias(itadmin_job *job)
+{
+ MYSQL_RES *mr; /* Results set. */
+ MYSQL_ROW mrow; /* One result row. */
+ char const *val[sizeof(itadmin_mysql_cn_alias)/sizeof(DK3_PCCHAR) - 1];
+ size_t cnind[sizeof(itadmin_mysql_cn_alias)/sizeof(DK3_PCCHAR) - 1];
+ unsigned long *lgts; /* Field lengths. */
+ unsigned int nf; /* Number of fields in result. */
+ int res; /* Query result. */
+ int back = 0;
+
+
+#line 644 "itamysql.ctr"
+ res = mysql_query((MYSQL *)(job->dbptr), itadmin_mysql_c8_kw[12]);
+ if(0 == res) {
+ mr = mysql_use_result((MYSQL *)(job->dbptr));
+ if(mr) {
+ nf = mysql_num_fields(mr);
+ itadmin_data_mysql_find_indices(
+ job, cnind, itadmin_mysql_sz_cn_alias, nf, mr,
+ itadmin_mysql_cn_alias
+ );
+ back = 1;
+ do {
+ mrow = mysql_fetch_row(mr);
+ if(mrow) {
+ lgts = mysql_fetch_lengths(mr);
+ if(lgts) {
+ itadmin_data_mysql_set_pointers(
+ job, val, cnind, itadmin_mysql_sz_cn_alias,
+ nf, mrow, lgts
+ );
+ res = itadmin_register_alias(
+ job,
+ val[0], val[1]
+ );
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ }
+ } while(mrow);
+ mysql_free_result(mr);
+ } else {
+ /* ERROR: Failed to obtain results list */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 141);
+ }
+ } else {
+ /* ERROR: Query failed! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 142);
+ }
+
+
+#line 683 "itamysql.ctr"
+ return back;
+}
+
+
+
+/** Read DHCP pool table.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_dhcp_pool(itadmin_job *job)
+{
+ MYSQL_RES *mr; /* Results set. */
+ MYSQL_ROW mrow; /* One result row. */
+ char const *val[sizeof(itadmin_mysql_cn_dhcp_pool)/sizeof(DK3_PCCHAR) - 1];
+ size_t cnind[sizeof(itadmin_mysql_cn_dhcp_pool)/sizeof(DK3_PCCHAR) - 1];
+ unsigned long *lgts; /* Field lengths. */
+ unsigned int nf; /* Number of fields in result. */
+ int res; /* Query result. */
+ int back = 0;
+
+
+#line 705 "itamysql.ctr"
+ res = mysql_query((MYSQL *)(job->dbptr), itadmin_mysql_c8_kw[10]);
+ if(0 == res) {
+ mr = mysql_use_result((MYSQL *)(job->dbptr));
+ if(mr) {
+ nf = mysql_num_fields(mr);
+ itadmin_data_mysql_find_indices(
+ job, cnind, itadmin_mysql_sz_cn_dhcp_pool, nf, mr,
+ itadmin_mysql_cn_dhcp_pool
+ );
+ back = 1;
+ do {
+ mrow = mysql_fetch_row(mr);
+ if(mrow) {
+ lgts = mysql_fetch_lengths(mr);
+ if(lgts) {
+ itadmin_data_mysql_set_pointers(
+ job, val, cnind, itadmin_mysql_sz_cn_dhcp_pool,
+ nf, mrow, lgts
+ );
+ res = itadmin_register_dhcp_pool(
+ job,
+ val[0], val[1], val[2],
+#if VERSION_BEFORE_20120208
+ itadmin_mysql_read_int(job, val[3], lgts[cnind[3]], 0),
+ itadmin_mysql_read_int(job, val[4], lgts[cnind[4]], 0),
+#else
+ itadmin_mysql_read_int(job, val[3], lgts, cnind, 3, 0),
+ itadmin_mysql_read_int(job, val[4], lgts, cnind, 4, 0),
+#endif
+ val[5]
+ );
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ }
+ } while(mrow);
+
+ mysql_free_result(mr);
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 141);
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 142);
+ }
+
+
+#line 751 "itamysql.ctr"
+ return back;
+}
+
+
+/** Read DHCP group table.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_dhcp_group(itadmin_job *job)
+{
+ MYSQL_RES *mr; /* Results set. */
+ MYSQL_ROW mrow; /* One result row. */
+ char const *val[sizeof(itadmin_mysql_cn_dhcp_group)/sizeof(DK3_PCCHAR) - 1];
+ size_t cnind[sizeof(itadmin_mysql_cn_dhcp_group)/sizeof(DK3_PCCHAR) - 1];
+ unsigned long *lgts; /* Field lengths. */
+ unsigned int nf; /* Number of fields in result. */
+ int res; /* Query result. */
+ int back = 0;
+
+
+#line 772 "itamysql.ctr"
+ res = mysql_query((MYSQL *)(job->dbptr), itadmin_mysql_c8_kw[9]);
+ if(0 == res) {
+ mr = mysql_use_result((MYSQL *)(job->dbptr));
+ if(mr) {
+ nf = mysql_num_fields(mr);
+ itadmin_data_mysql_find_indices(
+ job, cnind, itadmin_mysql_sz_cn_dhcp_group, nf, mr,
+ itadmin_mysql_cn_dhcp_group
+ );
+ back = 1;
+ do {
+ mrow = mysql_fetch_row(mr);
+ if(mrow) {
+ lgts = mysql_fetch_lengths(mr);
+ if(lgts) {
+ itadmin_data_mysql_set_pointers(
+ job, val, cnind, itadmin_mysql_sz_cn_dhcp_group,
+ nf, mrow, lgts
+ );
+ res = itadmin_register_dhcp_group(job, val[0], val[1]);
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ }
+ } while(mrow);
+ mysql_free_result(mr);
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 141);
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 142);
+ }
+
+
+#line 806 "itamysql.ctr"
+ return back;
+}
+
+
+
+/** Read DHCP class table.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_dhcp_class(itadmin_job *job)
+{
+ MYSQL_RES *mr; /* Results set. */
+ MYSQL_ROW mrow; /* One result row. */
+ char const *val[sizeof(itadmin_mysql_cn_dhcp_class)/sizeof(DK3_PCCHAR) - 1];
+ size_t cnind[sizeof(itadmin_mysql_cn_dhcp_class)/sizeof(DK3_PCCHAR) - 1];
+ unsigned long *lgts; /* Field lengths. */
+ unsigned int nf; /* Number of fields in result. */
+ int res; /* Query result. */
+ int back = 0;
+
+
+#line 828 "itamysql.ctr"
+ res = mysql_query((MYSQL *)(job->dbptr), itadmin_mysql_c8_kw[8]);
+ if(0 == res) {
+ mr = mysql_use_result((MYSQL *)(job->dbptr));
+ if(mr) {
+ nf = mysql_num_fields(mr);
+ itadmin_data_mysql_find_indices(
+ job, cnind, itadmin_mysql_sz_cn_dhcp_class, nf, mr,
+ itadmin_mysql_cn_dhcp_class
+ );
+ back = 1;
+ do {
+ mrow = mysql_fetch_row(mr);
+ if(mrow) {
+ lgts = mysql_fetch_lengths(mr);
+ if(lgts) {
+ itadmin_data_mysql_set_pointers(
+ job, val, cnind, itadmin_mysql_sz_cn_dhcp_class,
+ nf, mrow, lgts
+ );
+ res = itadmin_register_dhcp_class(job, val[0], val[1]);
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ }
+ } while(mrow);
+ mysql_free_result(mr);
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 141);
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 142);
+ }
+
+
+#line 862 "itamysql.ctr"
+ return back;
+}
+
+
+
+/** Read networks table.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_network(itadmin_job *job)
+{
+ MYSQL_RES *mr; /* Results set. */
+ MYSQL_ROW mrow; /* One result row. */
+ char const *val[sizeof(itadmin_mysql_cn_network)/sizeof(DK3_PCCHAR) - 1];
+ size_t cnind[sizeof(itadmin_mysql_cn_network)/sizeof(DK3_PCCHAR) - 1];
+ unsigned long *lgts; /* Field lengths. */
+ unsigned int nf; /* Number of fields in result. */
+ int res; /* Query result. */
+ int back = 0;
+
+
+#line 884 "itamysql.ctr"
+ res = mysql_query((MYSQL *)(job->dbptr), itadmin_mysql_c8_kw[5]);
+ if(0 == res) {
+ mr = mysql_use_result((MYSQL *)(job->dbptr));
+ if(mr) {
+ nf = mysql_num_fields(mr);
+ itadmin_data_mysql_find_indices(
+ job, cnind, itadmin_mysql_sz_cn_network, nf, mr,
+ itadmin_mysql_cn_network
+ );
+ back = 1;
+ do {
+ mrow = mysql_fetch_row(mr);
+ if(mrow) {
+ lgts = mysql_fetch_lengths(mr);
+ if(lgts) {
+ itadmin_data_mysql_set_pointers(
+ job, val, cnind, itadmin_mysql_sz_cn_network,
+ nf, mrow, lgts
+ );
+ res = itadmin_register_network(
+ job, val[0], val[1], val[2], val[3], val[4]
+ );
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ }
+ } while(mrow);
+ mysql_free_result(mr);
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 141);
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 142);
+ }
+
+
+#line 920 "itamysql.ctr"
+ return back;
+}
+
+
+
+/** Read hosts table.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_hosts(itadmin_job *job)
+{
+ itadmin_date expi; /* Expiration date for host entry. */
+ MYSQL_RES *mr; /* Results set. */
+ MYSQL_ROW mrow; /* One result row. */
+ char const *val[sizeof(itadmin_mysql_cn_hosts)/sizeof(DK3_PCCHAR) - 1];
+ size_t cnind[sizeof(itadmin_mysql_cn_hosts)/sizeof(DK3_PCCHAR) - 1];
+ unsigned long *lgts; /* Field lengths. */
+ unsigned int nf; /* Number of fields in result. */
+ int res; /* Query result. */
+ int hexpi; /* Flag: Have expiration date. */
+ int flag_first; /* Flag: Write FQDN to /etc/hosts first. */
+ int flag_guest; /* Flag: Guest computer. */
+ int flag_no_net_docu; /* Flag: Skip host in docu. */
+ int flag_no_arpwatch; /* Flag: Skip host for arpwatch. */
+ int back = 0;
+
+
+#line 948 "itamysql.ctr"
+ res = mysql_query((MYSQL *)(job->dbptr), itadmin_mysql_c8_kw[11]);
+ if(0 == res) {
+ mr = mysql_use_result((MYSQL *)(job->dbptr));
+ if(mr) {
+ nf = mysql_num_fields(mr);
+ itadmin_data_mysql_find_indices(
+ job, cnind, itadmin_mysql_sz_cn_hosts, nf, mr,
+ itadmin_mysql_cn_hosts
+ );
+ back = 1;
+ do {
+ mrow = mysql_fetch_row(mr);
+ if(mrow) {
+
+#line 961 "itamysql.ctr"
+ lgts = mysql_fetch_lengths(mr);
+ if(lgts) {
+
+#line 963 "itamysql.ctr"
+ itadmin_data_mysql_set_pointers(
+ job, val, cnind, itadmin_mysql_sz_cn_hosts,
+ nf, mrow, lgts
+ );
+ flag_first =
+ itadmin_mysql_read_int(job, val[14], lgts, cnind, 14, 0);
+ flag_guest =
+ itadmin_mysql_read_int(job, val[15], lgts, cnind, 15, 0);
+ flag_no_net_docu =
+ itadmin_mysql_read_int(job, val[18], lgts, cnind, 18, 0);
+ flag_no_arpwatch =
+ itadmin_mysql_read_int(job, val[19], lgts, cnind, 19, 0);
+ itadmin_mem_date_init(&expi);
+ hexpi = 0;
+ if(val[17]) {
+
+#line 978 "itamysql.ctr"
+ if(cnind[17] != 0xFFFFU) {
+
+#line 979 "itamysql.ctr"
+ if(lgts[cnind[17]]) {
+
+#line 980 "itamysql.ctr"
+ if(itadmin_tool_convert_date(job, &expi, val[17])) {
+ hexpi = 1;
+
+#line 982 "itamysql.ctr"
+ } else {
+
+#line 983 "itamysql.ctr"
+ }
+ } else {
+
+#line 985 "itamysql.ctr"
+ }
+ } else {
+
+#line 987 "itamysql.ctr"
+ }
+ } else {
+
+#line 989 "itamysql.ctr"
+ }
+
+#line 990 "itamysql.ctr"
+ res = itadmin_register_host(
+ job, val[0], val[1], val[2], val[3], val[4], val[5], val[6],
+ val[7], val[8], val[9], val[10], val[11], val[12], val[13],
+ flag_first, flag_guest, val[16], ((hexpi) ? &expi : NULL),
+ flag_no_net_docu, flag_no_arpwatch
+ );
+
+#line 996 "itamysql.ctr"
+ if(!(res)) { back = 0; }
+ } else {
+
+#line 998 "itamysql.ctr"
+ back = 0;
+ }
+
+#line 1000 "itamysql.ctr"
+ }
+ } while(mrow);
+ mysql_free_result(mr);
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 141);
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 142);
+ }
+
+
+#line 1010 "itamysql.ctr"
+ return back;
+}
+
+
+
+/** Read ngdep table.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_ngdep(itadmin_job *job)
+{
+ MYSQL_RES *mr; /* Results set. */
+ MYSQL_ROW mrow; /* One result row. */
+ char const *val[sizeof(itadmin_mysql_cn_ngdep)/sizeof(DK3_PCCHAR) - 1];
+ size_t cnind[sizeof(itadmin_mysql_cn_ngdep)/sizeof(DK3_PCCHAR) - 1];
+ unsigned long *lgts; /* Field lengths. */
+ unsigned int nf; /* Number of fields in result. */
+ int res; /* Query result. */
+ int back = 0;
+
+
+#line 1032 "itamysql.ctr"
+ res = mysql_query((MYSQL *)(job->dbptr), itadmin_mysql_c8_kw[7]);
+ if(0 == res) {
+ mr = mysql_use_result((MYSQL *)(job->dbptr));
+ if(mr) {
+ nf = mysql_num_fields(mr);
+ itadmin_data_mysql_find_indices(
+ job, cnind, itadmin_mysql_sz_cn_ngdep, nf, mr,
+ itadmin_mysql_cn_ngdep
+ );
+ back = 1;
+ do {
+ mrow = mysql_fetch_row(mr);
+ if(mrow) {
+ lgts = mysql_fetch_lengths(mr);
+ if(lgts) {
+ itadmin_data_mysql_set_pointers(
+ job, val, cnind, itadmin_mysql_sz_cn_ngdep,
+ nf, mrow, lgts
+ );
+ res = itadmin_register_ngdep(job, val[0], val[1]);
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ }
+ } while(mrow);
+ mysql_free_result(mr);
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 141);
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 142);
+ }
+
+
+#line 1066 "itamysql.ctr"
+ return back;
+}
+
+
+
+/** Read license types table.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_license(itadmin_job *job)
+{
+ char lnbuffer[128]; /* Line number buffer. */
+ MYSQL_RES *mr; /* Results set. */
+ MYSQL_ROW mrow; /* One result row. */
+ itadmin_date dd; /* Delivery date. */
+ itadmin_date di; /* Invoice date. */
+ char const *val[sizeof(itadmin_mysql_cn_license)/sizeof(DK3_PCCHAR) - 1];
+ size_t cnind[sizeof(itadmin_mysql_cn_license)/sizeof(DK3_PCCHAR) - 1];
+ unsigned long *lgts; /* Field lengths. */
+ unsigned long pk; /* Primary key. */
+ unsigned long lineno; /* Record number. */
+ unsigned int nf; /* Number of fields in result. */
+ int res; /* Query result. */
+ int hdd; /* Flag: Have delivery date. */
+ int hdi; /* Flag: Have invoice date. */
+ int back = 0;
+
+
+#line 1095 "itamysql.ctr"
+ res = mysql_query((MYSQL *)(job->dbptr), itadmin_mysql_c8_kw[17]);
+ if(0 == res) {
+ mr = mysql_use_result((MYSQL *)(job->dbptr));
+ if(mr) {
+ nf = mysql_num_fields(mr);
+ itadmin_data_mysql_find_indices(
+ job, cnind, itadmin_mysql_sz_cn_license, nf, mr,
+ itadmin_mysql_cn_license
+ );
+ back = 1;
+ lineno = 0UL;
+ do {
+ mrow = mysql_fetch_row(mr);
+ if(mrow) {
+ lgts = mysql_fetch_lengths(mr);
+ if(lgts) {
+ itadmin_data_mysql_set_pointers(
+ job, val, cnind, itadmin_mysql_sz_cn_license,
+ nf, mrow, lgts
+ );
+ /*
+ res = itadmin_register_license(
+ job, val[0], val[1], licno
+ );
+ if(!(res)) { back = 0; }
+ */
+ if(val[0]) {
+ if(sscanf(val[0], "%lu", &pk) == 1) {
+ hdd = hdi = 0;
+ if(val[8]) {
+ if(cnind[8] != 0xFFFFU) {
+ if(lgts[cnind[8]]) {
+ if(itadmin_tool_convert_date(job, &dd, val[8])) {
+ hdd = 1;
+ }
+ }
+ }
+ }
+ if(val[10]) {
+ if(cnind[10] != 0xFFFFU) {
+ if(lgts[cnind[10]]) {
+ if(itadmin_tool_convert_date(job, &di, val[10])) {
+ hdi = 1;
+ }
+ }
+ }
+ }
+ res = itadmin_register_license(
+ job,
+ pk,
+ val[1], /* li_on */
+ val[2], /* sw_s */
+ val[3], /* us_s */
+ val[4], /* co_s */
+ val[5], /* lt_s */
+ val[6], /* li_no */
+ val[7], /* sr_s */
+ ((hdd) ? &dd : NULL),
+ val[9], /* li_nd */
+ ((hdi) ? &di : NULL),
+ val[11] /* li_ni */
+ );
+ if(!(res)) { back = 0; }
+ } else {
+ /* ERROR: Primary key not numeric! */
+ sprintf(lnbuffer, "%lu", lineno);
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 143, 144, lnbuffer);
+ }
+ } else {
+ /* ERROR: No primary key */
+ sprintf(lnbuffer, "%lu", lineno);
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 143, 145, lnbuffer);
+ }
+ } else {
+ back = 0;
+ }
+ }
+ lineno++;
+ } while(mrow);
+ mysql_free_result(mr);
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 141);
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 142);
+ }
+
+
+#line 1182 "itamysql.ctr"
+ return back;
+}
+
+
+
+/** Read license types table.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_lictype(itadmin_job *job)
+{
+ MYSQL_RES *mr; /* Results set. */
+ MYSQL_ROW mrow; /* One result row. */
+ char const *val[sizeof(itadmin_mysql_cn_lictype)/sizeof(DK3_PCCHAR) - 1];
+ size_t cnind[sizeof(itadmin_mysql_cn_lictype)/sizeof(DK3_PCCHAR) - 1];
+ unsigned long *lgts; /* Field lengths. */
+ unsigned int nf; /* Number of fields in result. */
+ int res; /* Query result. */
+ int licno; /* Number of licenses. */
+ int back = 0;
+
+
+#line 1205 "itamysql.ctr"
+ res = mysql_query((MYSQL *)(job->dbptr), itadmin_mysql_c8_kw[16]);
+ if(0 == res) {
+ mr = mysql_use_result((MYSQL *)(job->dbptr));
+ if(mr) {
+ nf = mysql_num_fields(mr);
+ itadmin_data_mysql_find_indices(
+ job, cnind, itadmin_mysql_sz_cn_lictype, nf, mr,
+ itadmin_mysql_cn_lictype
+ );
+ back = 1;
+ do {
+ mrow = mysql_fetch_row(mr);
+ if(mrow) {
+ lgts = mysql_fetch_lengths(mr);
+ if(lgts) {
+ itadmin_data_mysql_set_pointers(
+ job, val, cnind, itadmin_mysql_sz_cn_lictype,
+ nf, mrow, lgts
+ );
+ licno = 1;
+ if(val[2]) {
+ char const *s;
+ int i;
+ s = dk3str_c8_start(val[2], NULL);
+ if(s) {
+ if(sscanf(s, "%d", &i) == 1) {
+ licno = i;
+ } else {
+ /* ERROR: Not a number! */
+ itadmin_tool_log_utf8_5(
+ job, DK3_LL_ERROR, 146, 147, 148, val[0], s
+ );
+ }
+ }
+ }
+ res = itadmin_register_lictype(
+ job, val[0], val[1], licno
+ );
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ }
+ } while(mrow);
+ mysql_free_result(mr);
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 141);
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 142);
+ }
+
+
+#line 1257 "itamysql.ctr"
+ return back;
+}
+
+
+
+/** Read software products table.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_swprod(itadmin_job *job)
+{
+ MYSQL_RES *mr; /* Results set. */
+ MYSQL_ROW mrow; /* One result row. */
+ char const *val[sizeof(itadmin_mysql_cn_swprod)/sizeof(DK3_PCCHAR) - 1];
+ size_t cnind[sizeof(itadmin_mysql_cn_swprod)/sizeof(DK3_PCCHAR) - 1];
+ unsigned long *lgts; /* Field lengths. */
+ unsigned int nf; /* Number of fields in result. */
+ int res; /* Query result. */
+ int back = 0;
+
+
+#line 1279 "itamysql.ctr"
+ res = mysql_query((MYSQL *)(job->dbptr), itadmin_mysql_c8_kw[15]);
+ if(0 == res) {
+ mr = mysql_use_result((MYSQL *)(job->dbptr));
+ if(mr) {
+ nf = mysql_num_fields(mr);
+ itadmin_data_mysql_find_indices(
+ job, cnind, itadmin_mysql_sz_cn_swprod, nf, mr,
+ itadmin_mysql_cn_swprod
+ );
+ back = 1;
+ do {
+ mrow = mysql_fetch_row(mr);
+ if(mrow) {
+ lgts = mysql_fetch_lengths(mr);
+ if(lgts) {
+ itadmin_data_mysql_set_pointers(
+ job, val, cnind, itadmin_mysql_sz_cn_swprod,
+ nf, mrow, lgts
+ );
+ res = itadmin_register_swprod(
+ job, val[0], val[1], val[2]
+ );
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ }
+ } while(mrow);
+ mysql_free_result(mr);
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 141);
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 142);
+ }
+
+
+#line 1315 "itamysql.ctr"
+ return back;
+}
+
+
+
+/** Read swman table.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_swman(itadmin_job *job)
+{
+ char lnbuffer[128]; /* Buffer for record number. */
+ unsigned long lineno; /* Record number. */
+ MYSQL_RES *mr; /* Results set. */
+ MYSQL_ROW mrow; /* One result row. */
+ char const *val[sizeof(itadmin_mysql_cn_swman)/sizeof(DK3_PCCHAR) - 1];
+ size_t cnind[sizeof(itadmin_mysql_cn_swman)/sizeof(DK3_PCCHAR) - 1];
+ unsigned long *lgts; /* Field lengths. */
+#if 0
+ long pk;
+#endif
+ unsigned int nf; /* Number of fields in result. */
+ int res; /* Query result. */
+ int back = 0;
+
+
+#line 1342 "itamysql.ctr"
+ res = mysql_query((MYSQL *)(job->dbptr), itadmin_mysql_c8_kw[14]);
+ if(0 == res) {
+ mr = mysql_use_result((MYSQL *)(job->dbptr));
+ if(mr) {
+ nf = mysql_num_fields(mr);
+ itadmin_data_mysql_find_indices(
+ job, cnind, itadmin_mysql_sz_cn_swman, nf, mr,
+ itadmin_mysql_cn_swman
+ );
+ back = 1;
+ lineno = 0UL;
+ do {
+ mrow = mysql_fetch_row(mr);
+ if(mrow) {
+ lgts = mysql_fetch_lengths(mr);
+ if(lgts) {
+ itadmin_data_mysql_set_pointers(
+ job, val, cnind, itadmin_mysql_sz_cn_swman,
+ nf, mrow, lgts
+ );
+ res = 0;
+ if(val[0]) {
+ res = itadmin_register_swman(
+ job, val[0], val[1]
+ );
+ } else {
+ /* ERROR: No pk pointer! */
+ sprintf(lnbuffer, "%lu", lineno);
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 149, 150, lnbuffer);
+ }
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ }
+ lineno++;
+ } while(mrow);
+ mysql_free_result(mr);
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 141);
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 142);
+ }
+
+
+#line 1387 "itamysql.ctr"
+ return back;
+}
+
+
+
+/** Read dhcp_option table.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_dhcp_option(itadmin_job *job)
+{
+ char lnbuffer[128]; /* Record number buffer. */
+ unsigned long lineno; /* Record number. */
+ MYSQL_RES *mr; /* Results set. */
+ MYSQL_ROW mrow; /* One result row. */
+ char const *val[sizeof(itadmin_mysql_cn_dhcp_option)/sizeof(DK3_PCCHAR) - 1];
+ size_t cnind[sizeof(itadmin_mysql_cn_dhcp_option)/sizeof(DK3_PCCHAR) - 1];
+ unsigned long *lgts; /* Field lengths. */
+ long pk;
+ unsigned int nf; /* Number of fields in result. */
+ int res; /* Query result. */
+ int back = 0;
+
+
+#line 1412 "itamysql.ctr"
+ res = mysql_query((MYSQL *)(job->dbptr), itadmin_mysql_c8_kw[13]);
+ if(0 == res) {
+ mr = mysql_use_result((MYSQL *)(job->dbptr));
+ if(mr) {
+ nf = mysql_num_fields(mr);
+ itadmin_data_mysql_find_indices(
+ job, cnind, itadmin_mysql_sz_cn_dhcp_option, nf, mr,
+ itadmin_mysql_cn_dhcp_option
+ );
+ back = 1;
+ lineno = 0UL;
+ do {
+ mrow = mysql_fetch_row(mr);
+ if(mrow) {
+ lgts = mysql_fetch_lengths(mr);
+ if(lgts) {
+ itadmin_data_mysql_set_pointers(
+ job, val, cnind, itadmin_mysql_sz_cn_dhcp_option,
+ nf, mrow, lgts
+ );
+ res = 0;
+ if(val[0]) {
+ if(sscanf(val[0], "%ld", &pk) == 1) {
+ res = itadmin_register_dhcp_option(
+ job, val[1], val[2], val[3], val[4], pk
+ );
+ } else {
+ /* ERROR: pk not a number! */
+ sprintf(lnbuffer, "%lu", lineno);
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 151, 152, lnbuffer);
+ }
+ } else {
+ /* ERROR: No pk pointer! */
+ sprintf(lnbuffer, "%lu", lineno);
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 151, 153, lnbuffer);
+ }
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ }
+ lineno++;
+ } while(mrow);
+ mysql_free_result(mr);
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 141);
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 142);
+ }
+
+
+#line 1463 "itamysql.ctr"
+ return back;
+}
+
+
+
+/** Read netgroup table.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_netgroup(itadmin_job *job)
+{
+ MYSQL_RES *mr; /* Results set. */
+ MYSQL_ROW mrow; /* One result row. */
+ char const *val[sizeof(itadmin_mysql_cn_netgroup)/sizeof(DK3_PCCHAR) - 1];
+ size_t cnind[sizeof(itadmin_mysql_cn_netgroup)/sizeof(DK3_PCCHAR) - 1];
+ unsigned long *lgts; /* Field lengths. */
+ unsigned int nf; /* Number of fields in result. */
+ int res; /* Query result. */
+ int back = 0;
+
+
+#line 1485 "itamysql.ctr"
+ res = mysql_query((MYSQL *)(job->dbptr), itadmin_mysql_c8_kw[6]);
+ if(0 == res) {
+ mr = mysql_use_result((MYSQL *)(job->dbptr));
+ if(mr) {
+ nf = mysql_num_fields(mr);
+ itadmin_data_mysql_find_indices(
+ job, cnind, itadmin_mysql_sz_cn_netgroup, nf, mr,
+ itadmin_mysql_cn_netgroup
+ );
+ back = 1;
+ do {
+ mrow = mysql_fetch_row(mr);
+ if(mrow) {
+ lgts = mysql_fetch_lengths(mr);
+ if(lgts) {
+ itadmin_data_mysql_set_pointers(
+ job, val, cnind, itadmin_mysql_sz_cn_netgroup,
+ nf, mrow, lgts
+ );
+ res = itadmin_register_netgroup(job, val[0], val[1]);
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ }
+ } while(mrow);
+ mysql_free_result(mr);
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 141);
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 142);
+ }
+
+
+#line 1519 "itamysql.ctr"
+ return back;
+}
+
+
+
+/** Read patches table.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_patch(itadmin_job *job)
+{
+ MYSQL_RES *mr; /* Results set. */
+ MYSQL_ROW mrow; /* One result row. */
+ char const *val[sizeof(itadmin_mysql_cn_patch)/sizeof(DK3_PCCHAR) - 1];
+ size_t cnind[sizeof(itadmin_mysql_cn_patch)/sizeof(DK3_PCCHAR) - 1];
+ unsigned long *lgts; /* Field lengths. */
+ unsigned int nf; /* Number of fields in result. */
+ int res; /* Query result. */
+ int back = 0;
+
+
+#line 1541 "itamysql.ctr"
+ res = mysql_query((MYSQL *)(job->dbptr), itadmin_mysql_c8_kw[3]);
+ if(0 == res) {
+ mr = mysql_use_result((MYSQL *)(job->dbptr));
+ if(mr) {
+ nf = mysql_num_fields(mr);
+ itadmin_data_mysql_find_indices(
+ job, cnind, itadmin_mysql_sz_cn_patch, nf, mr,
+ itadmin_mysql_cn_patch
+ );
+ back = 1;
+ do {
+ mrow = mysql_fetch_row(mr);
+ if(mrow) {
+ lgts = mysql_fetch_lengths(mr);
+ if(lgts) {
+ itadmin_data_mysql_set_pointers(
+ job, val, cnind, itadmin_mysql_sz_cn_patch,
+ nf, mrow, lgts
+ );
+ res = itadmin_register_patch(
+ job, val[0], val[1], val[2], val[3], val[4], val[5]
+ );
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ }
+ } while(mrow);
+ mysql_free_result(mr);
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 141);
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 142);
+ }
+
+
+#line 1577 "itamysql.ctr"
+ return back;
+}
+
+
+
+/** Read VLAN table.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_vlan(itadmin_job *job)
+{
+ MYSQL_RES *mr; /* Results set. */
+ MYSQL_ROW mrow; /* One result row. */
+ char const *val[sizeof(itadmin_mysql_cn_vlan)/sizeof(DK3_PCCHAR) - 1];
+ size_t cnind[sizeof(itadmin_mysql_cn_vlan)/sizeof(DK3_PCCHAR) - 1];
+ unsigned long *lgts; /* Field lengths. */
+ unsigned int nf; /* Number of fields in result. */
+ int res; /* Query result. */
+ int back = 0;
+
+
+#line 1599 "itamysql.ctr"
+ res = mysql_query((MYSQL *)(job->dbptr), itadmin_mysql_c8_kw[2]);
+ if(0 == res) {
+ mr = mysql_use_result((MYSQL *)(job->dbptr));
+ if(mr) {
+ nf = mysql_num_fields(mr);
+ itadmin_data_mysql_find_indices(
+ job, cnind, itadmin_mysql_sz_cn_vlan, nf, mr,
+ itadmin_mysql_cn_vlan
+ );
+ back = 1;
+ do {
+ mrow = mysql_fetch_row(mr);
+ if(mrow) {
+ lgts = mysql_fetch_lengths(mr);
+ if(lgts) {
+ itadmin_data_mysql_set_pointers(
+ job, val, cnind, itadmin_mysql_sz_cn_vlan,
+ nf, mrow, lgts
+ );
+ res = itadmin_register_vlan(job, val[0], val[1]);
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ }
+ } while(mrow);
+ mysql_free_result(mr);
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 141);
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 142);
+ }
+
+
+#line 1633 "itamysql.ctr"
+ return back;
+}
+
+
+
+/** Read speed table.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_speed(itadmin_job *job)
+{
+ MYSQL_RES *mr; /* Results set. */
+ MYSQL_ROW mrow; /* One result row. */
+ char const *val[sizeof(itadmin_mysql_cn_speed)/sizeof(DK3_PCCHAR) - 1];
+ size_t cnind[sizeof(itadmin_mysql_cn_speed)/sizeof(DK3_PCCHAR) - 1];
+ unsigned long *lgts; /* Field lengths. */
+ unsigned int nf; /* Number of fields in result. */
+ int res; /* Query result. */
+ int back = 0;
+
+
+#line 1655 "itamysql.ctr"
+ res = mysql_query((MYSQL *)(job->dbptr), itadmin_mysql_c8_kw[4]);
+ if(0 == res) {
+ mr = mysql_use_result((MYSQL *)(job->dbptr));
+ if(mr) {
+ nf = mysql_num_fields(mr);
+ itadmin_data_mysql_find_indices(
+ job, cnind, itadmin_mysql_sz_cn_speed, nf, mr,
+ itadmin_mysql_cn_speed
+ );
+ back = 1;
+ do {
+ mrow = mysql_fetch_row(mr);
+ if(mrow) {
+ lgts = mysql_fetch_lengths(mr);
+ if(lgts) {
+ itadmin_data_mysql_set_pointers(
+ job, val, cnind, itadmin_mysql_sz_cn_speed,
+ nf, mrow, lgts
+ );
+ res = itadmin_register_speed(job, val[0], val[1]);
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ }
+ } while(mrow);
+ mysql_free_result(mr);
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 141);
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 142);
+ }
+
+
+#line 1689 "itamysql.ctr"
+ return back;
+}
+
+
+
+/** Read buildings table.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_buildings(itadmin_job *job)
+{
+ MYSQL_RES *mr; /* Results set. */
+ MYSQL_ROW mrow; /* One result row. */
+ char const *val[sizeof(itadmin_mysql_cn_buildings)/sizeof(DK3_PCCHAR) - 1];
+ size_t cnind[sizeof(itadmin_mysql_cn_buildings)/sizeof(DK3_PCCHAR) - 1];
+ unsigned long *lgts; /* Field lengths. */
+ unsigned int nf; /* Number of fields in result. */
+ int res; /* Query result. */
+ int back = 0;
+
+
+#line 1711 "itamysql.ctr"
+ res = mysql_query((MYSQL *)(job->dbptr), itadmin_mysql_c8_kw[1]);
+ if(0 == res) {
+ mr = mysql_use_result((MYSQL *)(job->dbptr));
+ if(mr) {
+ nf = mysql_num_fields(mr);
+ itadmin_data_mysql_find_indices(
+ job, cnind, itadmin_mysql_sz_cn_buildings, nf, mr,
+ itadmin_mysql_cn_buildings
+ );
+ back = 1;
+ do {
+ mrow = mysql_fetch_row(mr);
+ if(mrow) {
+ lgts = mysql_fetch_lengths(mr);
+ if(lgts) {
+ itadmin_data_mysql_set_pointers(
+ job, val, cnind, itadmin_mysql_sz_cn_buildings,
+ nf, mrow, lgts
+ );
+
+#line 1730 "itamysql.ctr"
+ res = itadmin_register_building(
+ job,
+ val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7]
+ );
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0;
+
+#line 1737 "itamysql.ctr"
+ }
+ }
+ } while(mrow);
+ mysql_free_result(mr);
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 141);
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 142);
+ }
+
+
+#line 1748 "itamysql.ctr"
+ return back;
+}
+
+
+
+/** Read users table.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_users(itadmin_job *job)
+{
+ MYSQL_RES *mr; /* Results set. */
+ MYSQL_ROW mrow; /* One result row. */
+ char const *val[sizeof(itadmin_mysql_cn_users)/sizeof(DK3_PCCHAR) - 1];
+ size_t cnind[sizeof(itadmin_mysql_cn_users)/sizeof(DK3_PCCHAR) - 1];
+ unsigned long *lgts; /* Field lengths array. */
+ unsigned int nf; /* Number of fields in result. */
+ int res; /* Query result. */
+ int back = 0;
+
+
+#line 1770 "itamysql.ctr"
+ res = mysql_query((MYSQL *)(job->dbptr), itadmin_mysql_c8_kw[0]);
+
+#line 1771 "itamysql.ctr"
+ if(0 == res) {
+
+#line 1772 "itamysql.ctr"
+ mr = mysql_use_result((MYSQL *)(job->dbptr));
+ if(mr) {
+
+#line 1774 "itamysql.ctr"
+ nf = mysql_num_fields(mr);
+
+#line 1775 "itamysql.ctr"
+ itadmin_data_mysql_find_indices(
+ job, cnind, itadmin_mysql_sz_cn_users, nf, mr, itadmin_mysql_cn_users
+ );
+ back = 1;
+ do {
+
+#line 1780 "itamysql.ctr"
+ mrow = mysql_fetch_row(mr);
+ if(mrow) {
+
+#line 1782 "itamysql.ctr"
+ lgts = mysql_fetch_lengths(mr);
+ if(lgts) {
+
+#line 1784 "itamysql.ctr"
+ itadmin_data_mysql_set_pointers(
+ job, val, cnind, itadmin_mysql_sz_cn_users,
+ nf, mrow, lgts
+ );
+ res = itadmin_register_user(
+ job, val[0], val[1], val[2], val[3], val[4], val[5], val[6]
+ );
+ if(!(res)) {
+ back = 0;
+ }
+ } else {
+
+#line 1795 "itamysql.ctr"
+ back = 0;
+ }
+ }
+
+#line 1798 "itamysql.ctr"
+ } while(mrow);
+
+#line 1799 "itamysql.ctr"
+ mysql_free_result(mr);
+ } else {
+
+#line 1801 "itamysql.ctr"
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 141);
+ }
+ } else {
+
+#line 1804 "itamysql.ctr"
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 142);
+ }
+
+#line 1806 "itamysql.ctr"
+ return back;
+}
+
+
+
+
+/** Retrieve data from a MySQL database.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_retrieve(itadmin_job *job)
+{
+ int back = 1;
+
+
+#line 1822 "itamysql.ctr"
+ /* PROGRESS: Reading users table. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 87);
+ if(!itadmin_data_mysql_users(job)) { back = 0; }
+ /* PROGRESS: Reading buildings table. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 88);
+ if(!itadmin_data_mysql_buildings(job)) { back = 0; }
+ if(itadmin_job_do_network(job)) {
+ /* PROGRESS: Reading connection speed type table. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 89);
+ if(!itadmin_data_mysql_speed(job)) { back = 0; }
+ /* PROGRESS: Reading VLANS table. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 90);
+ if(!itadmin_data_mysql_vlan(job)) { back = 0; }
+ /* PROGRESS: Reading ethernet connections table. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 91);
+ if(!itadmin_data_mysql_patch(job)) { back = 0; }
+ /* PROGRESS: Reading netgroups table. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 92);
+ if(!itadmin_data_mysql_netgroup(job)) { back = 0; }
+ /* PROGRESS: Reading netgroup dependencies. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 93);
+ if(!itadmin_data_mysql_ngdep(job)) { back = 0; }
+ }
+ if((itadmin_job_do_dhcp(job)) || (itadmin_job_do_licenses(job))) {
+ /* PROGRESS: Reading networks. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 94);
+ if(!itadmin_data_mysql_network(job)) { back = 0; }
+ }
+ if(itadmin_job_do_network(job)) {
+ if(itadmin_job_do_dhcp(job)) {
+ /* PROGRESS: Reading DHCP classes. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 95);
+ if(!itadmin_data_mysql_dhcp_class(job)) { back = 0; }
+ /* PROGRESS: Reading DHCP groups. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 96);
+ if(!itadmin_data_mysql_dhcp_group(job)) { back = 0; }
+ }
+ }
+ if((itadmin_job_do_dhcp(job)) || (itadmin_job_do_licenses(job))) {
+ /* PROGRESS: Reading DHCP pools. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 97);
+ if(!itadmin_data_mysql_dhcp_pool(job)) { back = 0; }
+ }
+ /* PROGRESS: Reading hosts. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 98);
+ if(!itadmin_data_mysql_hosts(job)) { back = 0; }
+ /* PROGRESS: Reading host name aliases. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 99);
+ if(!itadmin_data_mysql_alias(job)) { back = 0; }
+ if(itadmin_job_do_dhcp(job)) {
+ /* PROGRESS: Reading DHCP options. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 100);
+ if(!itadmin_data_mysql_dhcp_option(job)) { back = 0; }
+ }
+ if(itadmin_job_do_licenses(job)) {
+ /* PROGRESS: Reading software manufacturers. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 101);
+ if(!itadmin_data_mysql_swman(job)) { back = 0; }
+ /* PROGRESS: Reading software products. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 102);
+ if(!itadmin_data_mysql_swprod(job)) { back = 0; }
+ /* PROGRESS: Reading license types. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 103);
+ if(!itadmin_data_mysql_lictype(job)) { back = 0; }
+ /* PROGRESS: Reading licenses. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 104);
+ if(!itadmin_data_mysql_license(job)) { back = 0; }
+ }
+ /* PROGRESS: Finished reading input. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 105);
+
+
+#line 1893 "itamysql.ctr"
+ return back;
+}
+
+
+#endif
+
+int
+itadmin_data_mysql_read(itadmin_job *job)
+{
+#if DK3_HAVE_MYSQL_MYSQL_H || DK3_HAVE_MYSQL_H
+ char dbh[ITADMIN_CONFIG_LINE_SIZE]; /* Host name. */
+ char dbu[ITADMIN_CONFIG_LINE_SIZE]; /* User name. */
+ char dbp[ITADMIN_CONFIG_LINE_SIZE]; /* Password. */
+ char dbn[ITADMIN_CONFIG_LINE_SIZE]; /* DB name. */
+ MYSQL *re1;
+ MYSQL *res; /* Same connection. */
+ int ie; /* INput encoding. */
+ int back = 0;
+
+
+#line 1912 "itamysql.ctr"
+ ie = dk3app_get_encoding(job->app);
+ if(0 == mysql_library_init(-1, itadmin_mysql_argv, itadmin_mysql_groups)) {
+ re1 = mysql_init(NULL);
+ if(re1) {
+ if(dk3str_to_c8u_app(dbh,sizeof(dbh),job->dbhn,ie,job->app)) {
+ if(dk3str_to_c8u_app(dbu,sizeof(dbu),job->dbus,ie,job->app)) {
+ if(dk3str_to_c8u_app(dbp,sizeof(dbp),job->dbpw,ie,job->app)) {
+ if(dk3str_to_c8u_app(dbn,sizeof(dbn),job->dbn,ie,job->app)) {
+
+
+#line 1921 "itamysql.ctr"
+ res = mysql_real_connect(re1, dbh, dbu, dbp, dbn, 0, NULL, 0);
+ if(res) {
+
+#line 1923 "itamysql.ctr"
+ job->dbptr = (void *)res;
+ if(mysql_set_character_set(res, "utf8")) {
+
+#line 1925 "itamysql.ctr"
+ /* WARNING: Failed to set encoding! */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 154);
+ }
+ back = itadmin_data_mysql_retrieve(job);
+ } else {
+
+#line 1930 "itamysql.ctr"
+ /* ERROR: Failed to connect to database! */
+ itadmin_tool_log_utf8_5(job,DK3_LL_ERROR,155,156,157,dbn,dbh);
+ }
+ } else {
+
+#line 1934 "itamysql.ctr"
+ /* ERROR: Failed to convert database name! */
+ dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,158,159,job->dbn);
+ }
+ } else {
+
+#line 1938 "itamysql.ctr"
+ /* ERROR: Failed to convert database user password! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 160);
+ }
+ } else {
+
+#line 1942 "itamysql.ctr"
+ /* ERROR: Failed to convert database user name! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 161, 162, job->dbus);
+ }
+ } else {
+
+#line 1946 "itamysql.ctr"
+ /* ERROR: Failed to convert database host name! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 163, 164, job->dbhn);
+ }
+ mysql_close(re1);
+ } else {
+ /* ERROR: Failed to initialize MySQL client object! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 165);
+ }
+ mysql_library_end();
+ } else {
+ /* ERROR: Failed to initialize MySQL library! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 166);
+ }
+
+
+#line 1960 "itamysql.ctr"
+#else
+ int back = 0;
+ /* ERROR: No MySQL support available! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 167);
+#endif
+ return back;
+}
+
+
+
diff --git a/support/dktools/itamysql.ctr b/support/dktools/itamysql.ctr
new file mode 100644
index 0000000000..1085e90258
--- /dev/null
+++ b/support/dktools/itamysql.ctr
@@ -0,0 +1,1969 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk3all.h"
+#include "itadmin.h"
+
+#if DK3_HAVE_MYSQL_MYSQL_H
+#include <mysql/mysql.h>
+#else
+#if DK3_HAVE_MYSQL_H
+#include <mysql.h>
+#endif
+#endif
+
+
+
+$!trace-include
+
+
+
+#if DK3_HAVE_MYSQL_MYSQL_H || DK3_HAVE_MYSQL_H
+
+
+/** Keywords used by this module.
+*/
+static char const *itadmin_mysql_c8_kw[] = {
+$!string-table
+#
+# 0: SQL instruction "select * from users"
+#
+select * from users
+#
+# 1: SQL instruction "select * from buildings"
+#
+select * from buildings
+#
+# 2: SQL instruction "select * from vlans"
+#
+select * from vlans
+#
+# 3: SQL instruction "select * from patches"
+#
+select * from patches
+#
+# 4: SQL instruction "select * from ddspeed"
+#
+select * from ddspeed
+#
+# 5: SQL instruction "select * from networks"
+#
+select * from networks
+#
+# 6: SQL instruction "select * from netgroups"
+#
+select * from netgroups
+#
+# 7: SQL instruction "select * from ngdeps"
+#
+select * from ngdeps
+#
+# 8: SQL instruction "select * from dhcpclasses"
+#
+select * from dhcpclasses
+#
+# 9: SQL instruction "select * from dhcpgroups"
+#
+select * from dhcpgroups
+#
+# 10: SQL instruction "select * from dhcppools"
+#
+select * from dhcppools
+#
+# 11: SQL instruction "select * from computers"
+#
+select * from computers
+#
+# 12: SQL instruction "select * from aliases"
+#
+select * from aliases
+#
+# 13: SQL instruction "select * from dhcpoptions"
+#
+select * from dhcpoptions
+#
+# 14: SQL instruction "select * from swmanufacturers"
+#
+select * from swmanufacturers
+#
+# 15: SQL instruction "select * from swproducts"
+#
+select * from swproducts
+#
+# 16: SQL instruction "select * from licensetypes"
+#
+select * from licensetypes
+#
+# 17: SQL instruction "select * from licenses"
+#
+select * from licenses
+$!end
+};
+
+
+
+/** Configuration section name "itadmin".
+*/
+static char itadmin_mysql_arg_0[] = {
+ 'i', 't', 'a', 'd', 'm', 'i', 'n', '\0'
+};
+
+
+/** Configuration section name "client".
+*/
+static char itadmin_mysql_gr_client[] = {
+ 'c', 'l', 'i', 'e', 'n', 't', '\0'
+};
+
+
+/** Argv array to initialize the library.
+*/
+static char *itadmin_mysql_argv[] = {
+ itadmin_mysql_arg_0,
+ NULL
+};
+
+
+/** Groups (configuration file section) names.
+*/
+static char *itadmin_mysql_groups[] = {
+ itadmin_mysql_gr_client,
+ itadmin_mysql_arg_0,
+ NULL
+};
+
+
+/** Elements from users table.
+*/
+static char const * const itadmin_mysql_cn_users[] = {
+$!string-table
+us_s
+us_t
+us_sn
+us_fn
+us_em
+us_ko
+us_se
+$!end
+};
+
+/** Number of elements in itadmin_mysql_cn_users.
+*/
+static size_t const itadmin_mysql_sz_cn_users =
+sizeof(itadmin_mysql_cn_users)/sizeof(DK3_PCCHAR) - 1;
+
+
+/** Elements from buildings table.
+*/
+static char const * const itadmin_mysql_cn_buildings[] = {
+$!string-table
+gb_s
+gb_l
+gb_a1
+gb_a2
+gb_a3
+gb_a4
+gb_plz
+gb_ort
+$!end
+};
+
+/** Number of elements in itadmin_mysql_cn_buildings.
+*/
+static size_t const itadmin_mysql_sz_cn_buildings =
+sizeof(itadmin_mysql_cn_buildings)/sizeof(DK3_PCCHAR) - 1;
+
+
+/** Elements from speed table.
+*/
+static char const * const itadmin_mysql_cn_speed[] = {
+$!string-table
+sp_s
+sp_l
+$!end
+};
+
+/** Number of elements in itadmin_mysql_cn_speed.
+*/
+static size_t const itadmin_mysql_sz_cn_speed =
+sizeof(itadmin_mysql_cn_speed)/sizeof(DK3_PCCHAR) - 1;
+
+
+/** Elements from vlan table.
+*/
+static char const * const itadmin_mysql_cn_vlan[] = {
+$!string-table
+vl_s
+vl_l
+$!end
+};
+
+/** Number of elements in itadmin_mysql_cn_vlan.
+*/
+static size_t const itadmin_mysql_sz_cn_vlan =
+sizeof(itadmin_mysql_cn_vlan)/sizeof(DK3_PCCHAR) - 1;
+
+
+/** Elements from patch table.
+*/
+static char const * const itadmin_mysql_cn_patch[] = {
+$!string-table
+dd_n
+sp_s
+vl_s
+dd_p
+gb_s
+dd_r
+$!end
+};
+
+/** Number of elements in itadmin_mysql_cn_patch.
+*/
+static size_t const itadmin_mysql_sz_cn_patch =
+sizeof(itadmin_mysql_cn_patch)/sizeof(DK3_PCCHAR) - 1;
+
+
+/** Elements from netgroup table.
+*/
+static char const * const itadmin_mysql_cn_netgroup[] = {
+$!string-table
+ng_s
+ng_l
+$!end
+};
+
+/** Number of elements in itadmin_mysql_cn_netgroup.
+*/
+static size_t const itadmin_mysql_sz_cn_netgroup =
+sizeof(itadmin_mysql_cn_netgroup)/sizeof(DK3_PCCHAR) - 1;
+
+
+/** Elements from dhcp_option table.
+*/
+static char const * const itadmin_mysql_cn_dhcp_option[] = {
+$!string-table
+do_pk
+do_sc
+do_sn
+do_n
+do_v
+$!end
+};
+
+/** Number of elements in itadmin_mysql_cn_dhcp_option.
+*/
+static size_t const itadmin_mysql_sz_cn_dhcp_option =
+sizeof(itadmin_mysql_cn_dhcp_option)/sizeof(DK3_PCCHAR) - 1;
+
+
+/** Elements from swman table.
+*/
+static char const * const itadmin_mysql_cn_swman[] = {
+$!string-table
+sm_s
+sm_l
+$!end
+};
+
+/** Number of elements in itadmin_mysql_cn_swman.
+*/
+static size_t const itadmin_mysql_sz_cn_swman =
+sizeof(itadmin_mysql_cn_swman)/sizeof(DK3_PCCHAR) - 1;
+
+
+/** Elements from swprod table.
+*/
+static char const * const itadmin_mysql_cn_swprod[] = {
+$!string-table
+sw_s
+sw_l
+sm_s
+$!end
+};
+
+/** Number of elements in itadmin_mysql_cn_swprod.
+*/
+static size_t const itadmin_mysql_sz_cn_swprod =
+sizeof(itadmin_mysql_cn_swprod)/sizeof(DK3_PCCHAR) - 1;
+
+
+/** Elements from lictype table.
+*/
+static char const * const itadmin_mysql_cn_lictype[] = {
+$!string-table
+lt_s
+lt_l
+lt_i
+$!end
+};
+
+/** Number of elements in itadmin_mysql_cn_lictype.
+*/
+static size_t const itadmin_mysql_sz_cn_lictype =
+sizeof(itadmin_mysql_cn_lictype)/sizeof(DK3_PCCHAR) - 1;
+
+
+/** Elements from license table.
+*/
+static char const * const itadmin_mysql_cn_license[] = {
+$!string-table
+# 0
+li_pk
+# 1
+li_on
+# 2
+sw_s
+# 3
+us_s
+# 4
+co_s
+# 5
+lt_s
+# 6
+li_no
+# 7
+sr_s
+# 8
+li_dd
+# 9
+li_nd
+# 10
+li_di
+# 11
+li_ni
+# 12
+$!end
+};
+
+/** Number of elements in itadmin_mysql_cn_license.
+*/
+static size_t const itadmin_mysql_sz_cn_license =
+sizeof(itadmin_mysql_cn_license)/sizeof(DK3_PCCHAR) - 1;
+
+
+/** Elements from ngdep table.
+*/
+static char const * const itadmin_mysql_cn_ngdep[] = {
+$!string-table
+nd_p
+nd_c
+$!end
+};
+
+/** Number of elements in itadmin_mysql_cn_ngdep.
+*/
+static size_t const itadmin_mysql_sz_cn_ngdep =
+sizeof(itadmin_mysql_cn_ngdep)/sizeof(DK3_PCCHAR) - 1;
+
+
+/** Elements from hosts table.
+*/
+static char const * const itadmin_mysql_cn_hosts[] = {
+$!string-table
+co_s
+us_s
+co_ip
+co_mc
+ng_s
+co_co
+dc_s
+dg_s
+dd_n
+gb_s
+co_r
+co_in
+co_sn
+co_dd
+co_ff
+co_gu
+co_hi
+co_ex
+co_nn
+co_na
+$!end
+};
+
+/** Number of elements in itadmin_mysql_cn_hosts.
+*/
+static size_t const itadmin_mysql_sz_cn_hosts =
+sizeof(itadmin_mysql_cn_hosts)/sizeof(DK3_PCCHAR) - 1;
+
+
+/** Elements from network table.
+*/
+static char const * const itadmin_mysql_cn_network[] = {
+$!string-table
+nw_ip
+nw_ma
+nw_gw
+nw_bc
+vl_s
+$!end
+};
+
+/** Number of elements in itadmin_mysql_cn_network.
+*/
+static size_t const itadmin_mysql_sz_cn_network =
+sizeof(itadmin_mysql_cn_network)/sizeof(DK3_PCCHAR) - 1;
+
+
+/** Elements from dhcp_class table.
+*/
+static char const * const itadmin_mysql_cn_dhcp_class[] = {
+$!string-table
+dc_s
+dc_d
+$!end
+};
+
+/** Number of elements in itadmin_mysql_cn_dhcp_class.
+*/
+static size_t const itadmin_mysql_sz_cn_dhcp_class =
+sizeof(itadmin_mysql_cn_dhcp_class)/sizeof(DK3_PCCHAR) - 1;
+
+
+/** Elements from dhcp_group table.
+*/
+static char const * const itadmin_mysql_cn_dhcp_group[] = {
+$!string-table
+dg_s
+dg_l
+$!end
+};
+
+/** Number of elements in itadmin_mysql_cn_dhcp_group.
+*/
+static size_t const itadmin_mysql_sz_cn_dhcp_group =
+sizeof(itadmin_mysql_cn_dhcp_group)/sizeof(DK3_PCCHAR) - 1;
+
+
+/** Elements from dhcp_pool table.
+*/
+static char const * const itadmin_mysql_cn_dhcp_pool[] = {
+$!string-table
+dp_st
+dp_en
+nw_ip
+dp_al
+dp_dn
+dc_s
+$!end
+};
+
+/** Number of elements in itadmin_mysql_cn_dhcp_pool.
+*/
+static size_t const itadmin_mysql_sz_cn_dhcp_pool =
+sizeof(itadmin_mysql_cn_dhcp_pool)/sizeof(DK3_PCCHAR) - 1;
+
+
+/** Elements from alias table.
+*/
+static char const * const itadmin_mysql_cn_alias[] = {
+$!string-table
+al_s
+co_s
+$!end
+};
+
+/** Number of elements in itadmin_mysql_cn_alias.
+*/
+static size_t const itadmin_mysql_sz_cn_alias =
+sizeof(itadmin_mysql_cn_alias)/sizeof(DK3_PCCHAR) - 1;
+
+
+#if VERSION_BEFORE_20120208
+/** Obtain int value from string.
+ @param job Job structure.
+ @param ptr String to convert.
+ @param lgt Length of string.
+ @param def Default value to use if conversion fails.
+ @return The value or the default value.
+*/
+static
+int
+itadmin_mysql_read_int(itadmin_job *job, char const *ptr, size_t lgt, int def)
+{
+ int back;
+ int i;
+ $? "+ itadmin_mysql_read_int \"%!8s\"", TR_8STR(ptr)
+ back = def;
+ if(ptr) {
+ if(lgt) {
+ if(sscanf(ptr, "%d", &i) == 1) {
+ back = i; $? ". success"
+ }
+ }
+ } $? "- itadmin_mysql_read_int %d", back
+ return back;
+}
+#else
+/** Obtain int value from string.
+ @param job Job structure.
+ @param ptr String to convert.
+ @param lgts Lengths of strings.
+ @param cnind Column name indices.
+ @param ind Current index to use.
+ @param def Default value to use if conversion fails.
+ @return The value or the default value.
+*/
+static
+int
+itadmin_mysql_read_int(
+ itadmin_job *job,
+ char const *ptr,
+ unsigned long *lgts,
+ size_t *cnind,
+ size_t ind,
+ int def
+)
+{
+ int back;
+ int i;
+ $? "+ itadmin_mysql_read_int \"%!8s\"", TR_8STR(ptr)
+ back = def;
+ if(ptr) {
+ if(cnind[ind] != 0xFFFFU) {
+ if(lgts[cnind[ind]]) {
+ if(sscanf(ptr, "%d", &i) == 1) {
+ back = i;
+ }
+ }
+ }
+ } $? "- itadmin_mysql_read_int %d", back
+ return back;
+}
+#endif
+
+
+/** Find column name indices.
+ For column names not found the program sets the index
+ to 0xFFFFU.
+ @param job Job structure.
+ @param cnind Destination array for indices.
+ @param sz_cnind Size of @a cnind.
+ @param nf Number of fields in query result.
+ @param mr Query result.
+ @param colnames Column names.
+*/
+static
+void
+itadmin_data_mysql_find_indices(
+ itadmin_job *job,
+ size_t *cnind,
+ size_t sz_cnind,
+ size_t nf,
+ MYSQL_RES *mr,
+ char const * const *colnames
+)
+{
+ MYSQL_FIELD *field;
+ size_t i;
+ int ai;
+ for(i = 0; i < sz_cnind; i++) { cnind[i] = 0xFFFFU; }
+ for(i = 0; i < nf; i++) {
+ field = mysql_fetch_field_direct(mr, i);
+ if(field) {
+ if(field->name) {
+ ai = dk3str_c8_array_index(colnames, field->name, 0);
+ if(ai >= 0) {
+ if(((size_t)ai) < sz_cnind) {
+ cnind[(size_t)ai] = i;
+ }
+ }
+ }
+ }
+ }
+}
+
+
+
+/** Set value pointers.
+ @param job Job structure.
+ @param val Value pointers array.
+ @param cnind Index array.
+ @param sz_cnind Size of @a val and @a cnind.
+ @param nf Number of fields in @a mrow.
+ @param mrow One result row.
+ @param lgts Array of string lengths for row.
+*/
+static
+void
+itadmin_data_mysql_set_pointers(
+ itadmin_job *job,
+ char const * *val,
+ size_t *cnind,
+ size_t sz_cnind,
+ size_t nf,
+ MYSQL_ROW mrow,
+ unsigned long *lgts
+)
+{
+ size_t i;
+ size_t j;
+ for(i = 0; i < sz_cnind; i++) {
+ val[i] = NULL;
+ if(cnind[i] != 0xFFFFU) {
+ j = cnind[i];
+ if(j < nf) {
+ if(lgts[j]) {
+ if(mrow[j]) {
+ val[i] = mrow[j];
+ }
+ }
+ }
+ }
+ }
+}
+
+
+
+/** Read aliases table.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_alias(itadmin_job *job)
+{
+ MYSQL_RES *mr; /* Results set. */
+ MYSQL_ROW mrow; /* One result row. */
+ char const *val[sizeof(itadmin_mysql_cn_alias)/sizeof(DK3_PCCHAR) - 1];
+ size_t cnind[sizeof(itadmin_mysql_cn_alias)/sizeof(DK3_PCCHAR) - 1];
+ unsigned long *lgts; /* Field lengths. */
+ unsigned int nf; /* Number of fields in result. */
+ int res; /* Query result. */
+ int back = 0;
+ $? "+ itadmin_data_mysql_alias"
+ res = mysql_query((MYSQL *)(job->dbptr), itadmin_mysql_c8_kw[12]);
+ if(0 == res) {
+ mr = mysql_use_result((MYSQL *)(job->dbptr));
+ if(mr) {
+ nf = mysql_num_fields(mr);
+ itadmin_data_mysql_find_indices(
+ job, cnind, itadmin_mysql_sz_cn_alias, nf, mr,
+ itadmin_mysql_cn_alias
+ );
+ back = 1;
+ do {
+ mrow = mysql_fetch_row(mr);
+ if(mrow) {
+ lgts = mysql_fetch_lengths(mr);
+ if(lgts) {
+ itadmin_data_mysql_set_pointers(
+ job, val, cnind, itadmin_mysql_sz_cn_alias,
+ nf, mrow, lgts
+ );
+ res = itadmin_register_alias(
+ job,
+ val[0], val[1]
+ );
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ }
+ } while(mrow);
+ mysql_free_result(mr);
+ } else {
+ /* ERROR: Failed to obtain results list */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 141);
+ }
+ } else {
+ /* ERROR: Query failed! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 142);
+ }
+ $? "- itadmin_data_mysql_alias %d", back
+ return back;
+}
+
+
+
+/** Read DHCP pool table.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_dhcp_pool(itadmin_job *job)
+{
+ MYSQL_RES *mr; /* Results set. */
+ MYSQL_ROW mrow; /* One result row. */
+ char const *val[sizeof(itadmin_mysql_cn_dhcp_pool)/sizeof(DK3_PCCHAR) - 1];
+ size_t cnind[sizeof(itadmin_mysql_cn_dhcp_pool)/sizeof(DK3_PCCHAR) - 1];
+ unsigned long *lgts; /* Field lengths. */
+ unsigned int nf; /* Number of fields in result. */
+ int res; /* Query result. */
+ int back = 0;
+ $? "+ itadmin_data_mysql_dhcp_pool"
+ res = mysql_query((MYSQL *)(job->dbptr), itadmin_mysql_c8_kw[10]);
+ if(0 == res) {
+ mr = mysql_use_result((MYSQL *)(job->dbptr));
+ if(mr) {
+ nf = mysql_num_fields(mr);
+ itadmin_data_mysql_find_indices(
+ job, cnind, itadmin_mysql_sz_cn_dhcp_pool, nf, mr,
+ itadmin_mysql_cn_dhcp_pool
+ );
+ back = 1;
+ do {
+ mrow = mysql_fetch_row(mr);
+ if(mrow) {
+ lgts = mysql_fetch_lengths(mr);
+ if(lgts) {
+ itadmin_data_mysql_set_pointers(
+ job, val, cnind, itadmin_mysql_sz_cn_dhcp_pool,
+ nf, mrow, lgts
+ );
+ res = itadmin_register_dhcp_pool(
+ job,
+ val[0], val[1], val[2],
+#if VERSION_BEFORE_20120208
+ itadmin_mysql_read_int(job, val[3], lgts[cnind[3]], 0),
+ itadmin_mysql_read_int(job, val[4], lgts[cnind[4]], 0),
+#else
+ itadmin_mysql_read_int(job, val[3], lgts, cnind, 3, 0),
+ itadmin_mysql_read_int(job, val[4], lgts, cnind, 4, 0),
+#endif
+ val[5]
+ );
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ }
+ } while(mrow);
+
+ mysql_free_result(mr);
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 141);
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 142);
+ }
+ $? "- itadmin_data_mysql_dhcp_pool %d", back
+ return back;
+}
+
+
+/** Read DHCP group table.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_dhcp_group(itadmin_job *job)
+{
+ MYSQL_RES *mr; /* Results set. */
+ MYSQL_ROW mrow; /* One result row. */
+ char const *val[sizeof(itadmin_mysql_cn_dhcp_group)/sizeof(DK3_PCCHAR) - 1];
+ size_t cnind[sizeof(itadmin_mysql_cn_dhcp_group)/sizeof(DK3_PCCHAR) - 1];
+ unsigned long *lgts; /* Field lengths. */
+ unsigned int nf; /* Number of fields in result. */
+ int res; /* Query result. */
+ int back = 0;
+ $? "+ itadmin_data_mysql_dhcp_group"
+ res = mysql_query((MYSQL *)(job->dbptr), itadmin_mysql_c8_kw[9]);
+ if(0 == res) {
+ mr = mysql_use_result((MYSQL *)(job->dbptr));
+ if(mr) {
+ nf = mysql_num_fields(mr);
+ itadmin_data_mysql_find_indices(
+ job, cnind, itadmin_mysql_sz_cn_dhcp_group, nf, mr,
+ itadmin_mysql_cn_dhcp_group
+ );
+ back = 1;
+ do {
+ mrow = mysql_fetch_row(mr);
+ if(mrow) {
+ lgts = mysql_fetch_lengths(mr);
+ if(lgts) {
+ itadmin_data_mysql_set_pointers(
+ job, val, cnind, itadmin_mysql_sz_cn_dhcp_group,
+ nf, mrow, lgts
+ );
+ res = itadmin_register_dhcp_group(job, val[0], val[1]);
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ }
+ } while(mrow);
+ mysql_free_result(mr);
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 141);
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 142);
+ }
+ $? "- itadmin_data_mysql_dhcp_group %d", back
+ return back;
+}
+
+
+
+/** Read DHCP class table.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_dhcp_class(itadmin_job *job)
+{
+ MYSQL_RES *mr; /* Results set. */
+ MYSQL_ROW mrow; /* One result row. */
+ char const *val[sizeof(itadmin_mysql_cn_dhcp_class)/sizeof(DK3_PCCHAR) - 1];
+ size_t cnind[sizeof(itadmin_mysql_cn_dhcp_class)/sizeof(DK3_PCCHAR) - 1];
+ unsigned long *lgts; /* Field lengths. */
+ unsigned int nf; /* Number of fields in result. */
+ int res; /* Query result. */
+ int back = 0;
+ $? "+ itadmin_data_mysql_dhcp_class"
+ res = mysql_query((MYSQL *)(job->dbptr), itadmin_mysql_c8_kw[8]);
+ if(0 == res) {
+ mr = mysql_use_result((MYSQL *)(job->dbptr));
+ if(mr) {
+ nf = mysql_num_fields(mr);
+ itadmin_data_mysql_find_indices(
+ job, cnind, itadmin_mysql_sz_cn_dhcp_class, nf, mr,
+ itadmin_mysql_cn_dhcp_class
+ );
+ back = 1;
+ do {
+ mrow = mysql_fetch_row(mr);
+ if(mrow) {
+ lgts = mysql_fetch_lengths(mr);
+ if(lgts) {
+ itadmin_data_mysql_set_pointers(
+ job, val, cnind, itadmin_mysql_sz_cn_dhcp_class,
+ nf, mrow, lgts
+ );
+ res = itadmin_register_dhcp_class(job, val[0], val[1]);
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ }
+ } while(mrow);
+ mysql_free_result(mr);
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 141);
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 142);
+ }
+ $? "- itadmin_data_mysql_dhcp_class %d", back
+ return back;
+}
+
+
+
+/** Read networks table.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_network(itadmin_job *job)
+{
+ MYSQL_RES *mr; /* Results set. */
+ MYSQL_ROW mrow; /* One result row. */
+ char const *val[sizeof(itadmin_mysql_cn_network)/sizeof(DK3_PCCHAR) - 1];
+ size_t cnind[sizeof(itadmin_mysql_cn_network)/sizeof(DK3_PCCHAR) - 1];
+ unsigned long *lgts; /* Field lengths. */
+ unsigned int nf; /* Number of fields in result. */
+ int res; /* Query result. */
+ int back = 0;
+ $? "+ itadmin_data_mysql_network"
+ res = mysql_query((MYSQL *)(job->dbptr), itadmin_mysql_c8_kw[5]);
+ if(0 == res) {
+ mr = mysql_use_result((MYSQL *)(job->dbptr));
+ if(mr) {
+ nf = mysql_num_fields(mr);
+ itadmin_data_mysql_find_indices(
+ job, cnind, itadmin_mysql_sz_cn_network, nf, mr,
+ itadmin_mysql_cn_network
+ );
+ back = 1;
+ do {
+ mrow = mysql_fetch_row(mr);
+ if(mrow) {
+ lgts = mysql_fetch_lengths(mr);
+ if(lgts) {
+ itadmin_data_mysql_set_pointers(
+ job, val, cnind, itadmin_mysql_sz_cn_network,
+ nf, mrow, lgts
+ );
+ res = itadmin_register_network(
+ job, val[0], val[1], val[2], val[3], val[4]
+ );
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ }
+ } while(mrow);
+ mysql_free_result(mr);
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 141);
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 142);
+ }
+ $? "- itadmin_data_mysql_network %d", back
+ return back;
+}
+
+
+
+/** Read hosts table.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_hosts(itadmin_job *job)
+{
+ itadmin_date expi; /* Expiration date for host entry. */
+ MYSQL_RES *mr; /* Results set. */
+ MYSQL_ROW mrow; /* One result row. */
+ char const *val[sizeof(itadmin_mysql_cn_hosts)/sizeof(DK3_PCCHAR) - 1];
+ size_t cnind[sizeof(itadmin_mysql_cn_hosts)/sizeof(DK3_PCCHAR) - 1];
+ unsigned long *lgts; /* Field lengths. */
+ unsigned int nf; /* Number of fields in result. */
+ int res; /* Query result. */
+ int hexpi; /* Flag: Have expiration date. */
+ int flag_first; /* Flag: Write FQDN to /etc/hosts first. */
+ int flag_guest; /* Flag: Guest computer. */
+ int flag_no_net_docu; /* Flag: Skip host in docu. */
+ int flag_no_arpwatch; /* Flag: Skip host for arpwatch. */
+ int back = 0;
+ $? "+ itadmin_data_mysql_hosts"
+ res = mysql_query((MYSQL *)(job->dbptr), itadmin_mysql_c8_kw[11]);
+ if(0 == res) {
+ mr = mysql_use_result((MYSQL *)(job->dbptr));
+ if(mr) {
+ nf = mysql_num_fields(mr);
+ itadmin_data_mysql_find_indices(
+ job, cnind, itadmin_mysql_sz_cn_hosts, nf, mr,
+ itadmin_mysql_cn_hosts
+ );
+ back = 1;
+ do {
+ mrow = mysql_fetch_row(mr);
+ if(mrow) { $? ". host to handle"
+ lgts = mysql_fetch_lengths(mr);
+ if(lgts) { $? ". lgts"
+ itadmin_data_mysql_set_pointers(
+ job, val, cnind, itadmin_mysql_sz_cn_hosts,
+ nf, mrow, lgts
+ );
+ flag_first =
+ itadmin_mysql_read_int(job, val[14], lgts, cnind, 14, 0);
+ flag_guest =
+ itadmin_mysql_read_int(job, val[15], lgts, cnind, 15, 0);
+ flag_no_net_docu =
+ itadmin_mysql_read_int(job, val[18], lgts, cnind, 18, 0);
+ flag_no_arpwatch =
+ itadmin_mysql_read_int(job, val[19], lgts, cnind, 19, 0);
+ itadmin_mem_date_init(&expi);
+ hexpi = 0;
+ if(val[17]) { $? ". date string set"
+ if(cnind[17] != 0xFFFFU) { $? ". index found"
+ if(lgts[cnind[17]]) { $? ". length ok"
+ if(itadmin_tool_convert_date(job, &expi, val[17])) {
+ hexpi = 1; $? ". date conversion ok"
+ } else { $? "! date conversion failed"
+ }
+ } else { $? "! length"
+ }
+ } else { $? "! no index found"
+ }
+ } else { $? ". no date string"
+ } $? ". going to register hosts"
+ res = itadmin_register_host(
+ job, val[0], val[1], val[2], val[3], val[4], val[5], val[6],
+ val[7], val[8], val[9], val[10], val[11], val[12], val[13],
+ flag_first, flag_guest, val[16], ((hexpi) ? &expi : NULL),
+ flag_no_net_docu, flag_no_arpwatch
+ ); $? ". host registration done"
+ if(!(res)) { back = 0; }
+ } else { $? "! lgts"
+ back = 0;
+ } $? ". host finished"
+ }
+ } while(mrow);
+ mysql_free_result(mr);
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 141);
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 142);
+ }
+ $? "- itadmin_data_mysql_hosts %d", back
+ return back;
+}
+
+
+
+/** Read ngdep table.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_ngdep(itadmin_job *job)
+{
+ MYSQL_RES *mr; /* Results set. */
+ MYSQL_ROW mrow; /* One result row. */
+ char const *val[sizeof(itadmin_mysql_cn_ngdep)/sizeof(DK3_PCCHAR) - 1];
+ size_t cnind[sizeof(itadmin_mysql_cn_ngdep)/sizeof(DK3_PCCHAR) - 1];
+ unsigned long *lgts; /* Field lengths. */
+ unsigned int nf; /* Number of fields in result. */
+ int res; /* Query result. */
+ int back = 0;
+ $? "+ itadmin_data_mysql_ngdep"
+ res = mysql_query((MYSQL *)(job->dbptr), itadmin_mysql_c8_kw[7]);
+ if(0 == res) {
+ mr = mysql_use_result((MYSQL *)(job->dbptr));
+ if(mr) {
+ nf = mysql_num_fields(mr);
+ itadmin_data_mysql_find_indices(
+ job, cnind, itadmin_mysql_sz_cn_ngdep, nf, mr,
+ itadmin_mysql_cn_ngdep
+ );
+ back = 1;
+ do {
+ mrow = mysql_fetch_row(mr);
+ if(mrow) {
+ lgts = mysql_fetch_lengths(mr);
+ if(lgts) {
+ itadmin_data_mysql_set_pointers(
+ job, val, cnind, itadmin_mysql_sz_cn_ngdep,
+ nf, mrow, lgts
+ );
+ res = itadmin_register_ngdep(job, val[0], val[1]);
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ }
+ } while(mrow);
+ mysql_free_result(mr);
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 141);
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 142);
+ }
+ $? "- itadmin_data_mysql_ngdep %d", back
+ return back;
+}
+
+
+
+/** Read license types table.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_license(itadmin_job *job)
+{
+ char lnbuffer[128]; /* Line number buffer. */
+ MYSQL_RES *mr; /* Results set. */
+ MYSQL_ROW mrow; /* One result row. */
+ itadmin_date dd; /* Delivery date. */
+ itadmin_date di; /* Invoice date. */
+ char const *val[sizeof(itadmin_mysql_cn_license)/sizeof(DK3_PCCHAR) - 1];
+ size_t cnind[sizeof(itadmin_mysql_cn_license)/sizeof(DK3_PCCHAR) - 1];
+ unsigned long *lgts; /* Field lengths. */
+ unsigned long pk; /* Primary key. */
+ unsigned long lineno; /* Record number. */
+ unsigned int nf; /* Number of fields in result. */
+ int res; /* Query result. */
+ int hdd; /* Flag: Have delivery date. */
+ int hdi; /* Flag: Have invoice date. */
+ int back = 0;
+ $? "+ itadmin_data_mysql_license"
+ res = mysql_query((MYSQL *)(job->dbptr), itadmin_mysql_c8_kw[17]);
+ if(0 == res) {
+ mr = mysql_use_result((MYSQL *)(job->dbptr));
+ if(mr) {
+ nf = mysql_num_fields(mr);
+ itadmin_data_mysql_find_indices(
+ job, cnind, itadmin_mysql_sz_cn_license, nf, mr,
+ itadmin_mysql_cn_license
+ );
+ back = 1;
+ lineno = 0UL;
+ do {
+ mrow = mysql_fetch_row(mr);
+ if(mrow) {
+ lgts = mysql_fetch_lengths(mr);
+ if(lgts) {
+ itadmin_data_mysql_set_pointers(
+ job, val, cnind, itadmin_mysql_sz_cn_license,
+ nf, mrow, lgts
+ );
+ /*
+ res = itadmin_register_license(
+ job, val[0], val[1], licno
+ );
+ if(!(res)) { back = 0; }
+ */
+ if(val[0]) {
+ if(sscanf(val[0], "%lu", &pk) == 1) {
+ hdd = hdi = 0;
+ if(val[8]) {
+ if(cnind[8] != 0xFFFFU) {
+ if(lgts[cnind[8]]) {
+ if(itadmin_tool_convert_date(job, &dd, val[8])) {
+ hdd = 1;
+ }
+ }
+ }
+ }
+ if(val[10]) {
+ if(cnind[10] != 0xFFFFU) {
+ if(lgts[cnind[10]]) {
+ if(itadmin_tool_convert_date(job, &di, val[10])) {
+ hdi = 1;
+ }
+ }
+ }
+ }
+ res = itadmin_register_license(
+ job,
+ pk,
+ val[1], /* li_on */
+ val[2], /* sw_s */
+ val[3], /* us_s */
+ val[4], /* co_s */
+ val[5], /* lt_s */
+ val[6], /* li_no */
+ val[7], /* sr_s */
+ ((hdd) ? &dd : NULL),
+ val[9], /* li_nd */
+ ((hdi) ? &di : NULL),
+ val[11] /* li_ni */
+ );
+ if(!(res)) { back = 0; }
+ } else {
+ /* ERROR: Primary key not numeric! */
+ sprintf(lnbuffer, "%lu", lineno);
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 143, 144, lnbuffer);
+ }
+ } else {
+ /* ERROR: No primary key */
+ sprintf(lnbuffer, "%lu", lineno);
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 143, 145, lnbuffer);
+ }
+ } else {
+ back = 0;
+ }
+ }
+ lineno++;
+ } while(mrow);
+ mysql_free_result(mr);
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 141);
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 142);
+ }
+ $? "- itadmin_data_mysql_license %d", back
+ return back;
+}
+
+
+
+/** Read license types table.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_lictype(itadmin_job *job)
+{
+ MYSQL_RES *mr; /* Results set. */
+ MYSQL_ROW mrow; /* One result row. */
+ char const *val[sizeof(itadmin_mysql_cn_lictype)/sizeof(DK3_PCCHAR) - 1];
+ size_t cnind[sizeof(itadmin_mysql_cn_lictype)/sizeof(DK3_PCCHAR) - 1];
+ unsigned long *lgts; /* Field lengths. */
+ unsigned int nf; /* Number of fields in result. */
+ int res; /* Query result. */
+ int licno; /* Number of licenses. */
+ int back = 0;
+ $? "+ itadmin_data_mysql_lictype"
+ res = mysql_query((MYSQL *)(job->dbptr), itadmin_mysql_c8_kw[16]);
+ if(0 == res) {
+ mr = mysql_use_result((MYSQL *)(job->dbptr));
+ if(mr) {
+ nf = mysql_num_fields(mr);
+ itadmin_data_mysql_find_indices(
+ job, cnind, itadmin_mysql_sz_cn_lictype, nf, mr,
+ itadmin_mysql_cn_lictype
+ );
+ back = 1;
+ do {
+ mrow = mysql_fetch_row(mr);
+ if(mrow) {
+ lgts = mysql_fetch_lengths(mr);
+ if(lgts) {
+ itadmin_data_mysql_set_pointers(
+ job, val, cnind, itadmin_mysql_sz_cn_lictype,
+ nf, mrow, lgts
+ );
+ licno = 1;
+ if(val[2]) {
+ char const *s;
+ int i;
+ s = dk3str_c8_start(val[2], NULL);
+ if(s) {
+ if(sscanf(s, "%d", &i) == 1) {
+ licno = i;
+ } else {
+ /* ERROR: Not a number! */
+ itadmin_tool_log_utf8_5(
+ job, DK3_LL_ERROR, 146, 147, 148, val[0], s
+ );
+ }
+ }
+ }
+ res = itadmin_register_lictype(
+ job, val[0], val[1], licno
+ );
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ }
+ } while(mrow);
+ mysql_free_result(mr);
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 141);
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 142);
+ }
+ $? "- itadmin_data_mysql_lictype %d", back
+ return back;
+}
+
+
+
+/** Read software products table.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_swprod(itadmin_job *job)
+{
+ MYSQL_RES *mr; /* Results set. */
+ MYSQL_ROW mrow; /* One result row. */
+ char const *val[sizeof(itadmin_mysql_cn_swprod)/sizeof(DK3_PCCHAR) - 1];
+ size_t cnind[sizeof(itadmin_mysql_cn_swprod)/sizeof(DK3_PCCHAR) - 1];
+ unsigned long *lgts; /* Field lengths. */
+ unsigned int nf; /* Number of fields in result. */
+ int res; /* Query result. */
+ int back = 0;
+ $? "+ itadmin_data_mysql_swprod"
+ res = mysql_query((MYSQL *)(job->dbptr), itadmin_mysql_c8_kw[15]);
+ if(0 == res) {
+ mr = mysql_use_result((MYSQL *)(job->dbptr));
+ if(mr) {
+ nf = mysql_num_fields(mr);
+ itadmin_data_mysql_find_indices(
+ job, cnind, itadmin_mysql_sz_cn_swprod, nf, mr,
+ itadmin_mysql_cn_swprod
+ );
+ back = 1;
+ do {
+ mrow = mysql_fetch_row(mr);
+ if(mrow) {
+ lgts = mysql_fetch_lengths(mr);
+ if(lgts) {
+ itadmin_data_mysql_set_pointers(
+ job, val, cnind, itadmin_mysql_sz_cn_swprod,
+ nf, mrow, lgts
+ );
+ res = itadmin_register_swprod(
+ job, val[0], val[1], val[2]
+ );
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ }
+ } while(mrow);
+ mysql_free_result(mr);
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 141);
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 142);
+ }
+ $? "- itadmin_data_mysql_swprod %d", back
+ return back;
+}
+
+
+
+/** Read swman table.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_swman(itadmin_job *job)
+{
+ char lnbuffer[128]; /* Buffer for record number. */
+ unsigned long lineno; /* Record number. */
+ MYSQL_RES *mr; /* Results set. */
+ MYSQL_ROW mrow; /* One result row. */
+ char const *val[sizeof(itadmin_mysql_cn_swman)/sizeof(DK3_PCCHAR) - 1];
+ size_t cnind[sizeof(itadmin_mysql_cn_swman)/sizeof(DK3_PCCHAR) - 1];
+ unsigned long *lgts; /* Field lengths. */
+#if 0
+ long pk;
+#endif
+ unsigned int nf; /* Number of fields in result. */
+ int res; /* Query result. */
+ int back = 0;
+ $? "+ itadmin_data_mysql_swman"
+ res = mysql_query((MYSQL *)(job->dbptr), itadmin_mysql_c8_kw[14]);
+ if(0 == res) {
+ mr = mysql_use_result((MYSQL *)(job->dbptr));
+ if(mr) {
+ nf = mysql_num_fields(mr);
+ itadmin_data_mysql_find_indices(
+ job, cnind, itadmin_mysql_sz_cn_swman, nf, mr,
+ itadmin_mysql_cn_swman
+ );
+ back = 1;
+ lineno = 0UL;
+ do {
+ mrow = mysql_fetch_row(mr);
+ if(mrow) {
+ lgts = mysql_fetch_lengths(mr);
+ if(lgts) {
+ itadmin_data_mysql_set_pointers(
+ job, val, cnind, itadmin_mysql_sz_cn_swman,
+ nf, mrow, lgts
+ );
+ res = 0;
+ if(val[0]) {
+ res = itadmin_register_swman(
+ job, val[0], val[1]
+ );
+ } else {
+ /* ERROR: No pk pointer! */
+ sprintf(lnbuffer, "%lu", lineno);
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 149, 150, lnbuffer);
+ }
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ }
+ lineno++;
+ } while(mrow);
+ mysql_free_result(mr);
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 141);
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 142);
+ }
+ $? "- itadmin_data_mysql_swman %d", back
+ return back;
+}
+
+
+
+/** Read dhcp_option table.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_dhcp_option(itadmin_job *job)
+{
+ char lnbuffer[128]; /* Record number buffer. */
+ unsigned long lineno; /* Record number. */
+ MYSQL_RES *mr; /* Results set. */
+ MYSQL_ROW mrow; /* One result row. */
+ char const *val[sizeof(itadmin_mysql_cn_dhcp_option)/sizeof(DK3_PCCHAR) - 1];
+ size_t cnind[sizeof(itadmin_mysql_cn_dhcp_option)/sizeof(DK3_PCCHAR) - 1];
+ unsigned long *lgts; /* Field lengths. */
+ long pk;
+ unsigned int nf; /* Number of fields in result. */
+ int res; /* Query result. */
+ int back = 0;
+ $? "+ itadmin_data_mysql_dhcp_option"
+ res = mysql_query((MYSQL *)(job->dbptr), itadmin_mysql_c8_kw[13]);
+ if(0 == res) {
+ mr = mysql_use_result((MYSQL *)(job->dbptr));
+ if(mr) {
+ nf = mysql_num_fields(mr);
+ itadmin_data_mysql_find_indices(
+ job, cnind, itadmin_mysql_sz_cn_dhcp_option, nf, mr,
+ itadmin_mysql_cn_dhcp_option
+ );
+ back = 1;
+ lineno = 0UL;
+ do {
+ mrow = mysql_fetch_row(mr);
+ if(mrow) {
+ lgts = mysql_fetch_lengths(mr);
+ if(lgts) {
+ itadmin_data_mysql_set_pointers(
+ job, val, cnind, itadmin_mysql_sz_cn_dhcp_option,
+ nf, mrow, lgts
+ );
+ res = 0;
+ if(val[0]) {
+ if(sscanf(val[0], "%ld", &pk) == 1) {
+ res = itadmin_register_dhcp_option(
+ job, val[1], val[2], val[3], val[4], pk
+ );
+ } else {
+ /* ERROR: pk not a number! */
+ sprintf(lnbuffer, "%lu", lineno);
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 151, 152, lnbuffer);
+ }
+ } else {
+ /* ERROR: No pk pointer! */
+ sprintf(lnbuffer, "%lu", lineno);
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 151, 153, lnbuffer);
+ }
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ }
+ lineno++;
+ } while(mrow);
+ mysql_free_result(mr);
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 141);
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 142);
+ }
+ $? "- itadmin_data_mysql_dhcp_option %d", back
+ return back;
+}
+
+
+
+/** Read netgroup table.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_netgroup(itadmin_job *job)
+{
+ MYSQL_RES *mr; /* Results set. */
+ MYSQL_ROW mrow; /* One result row. */
+ char const *val[sizeof(itadmin_mysql_cn_netgroup)/sizeof(DK3_PCCHAR) - 1];
+ size_t cnind[sizeof(itadmin_mysql_cn_netgroup)/sizeof(DK3_PCCHAR) - 1];
+ unsigned long *lgts; /* Field lengths. */
+ unsigned int nf; /* Number of fields in result. */
+ int res; /* Query result. */
+ int back = 0;
+ $? "+ itadmin_data_mysql_netgroup"
+ res = mysql_query((MYSQL *)(job->dbptr), itadmin_mysql_c8_kw[6]);
+ if(0 == res) {
+ mr = mysql_use_result((MYSQL *)(job->dbptr));
+ if(mr) {
+ nf = mysql_num_fields(mr);
+ itadmin_data_mysql_find_indices(
+ job, cnind, itadmin_mysql_sz_cn_netgroup, nf, mr,
+ itadmin_mysql_cn_netgroup
+ );
+ back = 1;
+ do {
+ mrow = mysql_fetch_row(mr);
+ if(mrow) {
+ lgts = mysql_fetch_lengths(mr);
+ if(lgts) {
+ itadmin_data_mysql_set_pointers(
+ job, val, cnind, itadmin_mysql_sz_cn_netgroup,
+ nf, mrow, lgts
+ );
+ res = itadmin_register_netgroup(job, val[0], val[1]);
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ }
+ } while(mrow);
+ mysql_free_result(mr);
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 141);
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 142);
+ }
+ $? "- itadmin_data_mysql_netgroup %d", back
+ return back;
+}
+
+
+
+/** Read patches table.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_patch(itadmin_job *job)
+{
+ MYSQL_RES *mr; /* Results set. */
+ MYSQL_ROW mrow; /* One result row. */
+ char const *val[sizeof(itadmin_mysql_cn_patch)/sizeof(DK3_PCCHAR) - 1];
+ size_t cnind[sizeof(itadmin_mysql_cn_patch)/sizeof(DK3_PCCHAR) - 1];
+ unsigned long *lgts; /* Field lengths. */
+ unsigned int nf; /* Number of fields in result. */
+ int res; /* Query result. */
+ int back = 0;
+ $? "+ itadmin_data_mysql_patch"
+ res = mysql_query((MYSQL *)(job->dbptr), itadmin_mysql_c8_kw[3]);
+ if(0 == res) {
+ mr = mysql_use_result((MYSQL *)(job->dbptr));
+ if(mr) {
+ nf = mysql_num_fields(mr);
+ itadmin_data_mysql_find_indices(
+ job, cnind, itadmin_mysql_sz_cn_patch, nf, mr,
+ itadmin_mysql_cn_patch
+ );
+ back = 1;
+ do {
+ mrow = mysql_fetch_row(mr);
+ if(mrow) {
+ lgts = mysql_fetch_lengths(mr);
+ if(lgts) {
+ itadmin_data_mysql_set_pointers(
+ job, val, cnind, itadmin_mysql_sz_cn_patch,
+ nf, mrow, lgts
+ );
+ res = itadmin_register_patch(
+ job, val[0], val[1], val[2], val[3], val[4], val[5]
+ );
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ }
+ } while(mrow);
+ mysql_free_result(mr);
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 141);
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 142);
+ }
+ $? "- itadmin_data_mysql_patch %d", back
+ return back;
+}
+
+
+
+/** Read VLAN table.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_vlan(itadmin_job *job)
+{
+ MYSQL_RES *mr; /* Results set. */
+ MYSQL_ROW mrow; /* One result row. */
+ char const *val[sizeof(itadmin_mysql_cn_vlan)/sizeof(DK3_PCCHAR) - 1];
+ size_t cnind[sizeof(itadmin_mysql_cn_vlan)/sizeof(DK3_PCCHAR) - 1];
+ unsigned long *lgts; /* Field lengths. */
+ unsigned int nf; /* Number of fields in result. */
+ int res; /* Query result. */
+ int back = 0;
+ $? "+ itadmin_data_mysql_vlan"
+ res = mysql_query((MYSQL *)(job->dbptr), itadmin_mysql_c8_kw[2]);
+ if(0 == res) {
+ mr = mysql_use_result((MYSQL *)(job->dbptr));
+ if(mr) {
+ nf = mysql_num_fields(mr);
+ itadmin_data_mysql_find_indices(
+ job, cnind, itadmin_mysql_sz_cn_vlan, nf, mr,
+ itadmin_mysql_cn_vlan
+ );
+ back = 1;
+ do {
+ mrow = mysql_fetch_row(mr);
+ if(mrow) {
+ lgts = mysql_fetch_lengths(mr);
+ if(lgts) {
+ itadmin_data_mysql_set_pointers(
+ job, val, cnind, itadmin_mysql_sz_cn_vlan,
+ nf, mrow, lgts
+ );
+ res = itadmin_register_vlan(job, val[0], val[1]);
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ }
+ } while(mrow);
+ mysql_free_result(mr);
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 141);
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 142);
+ }
+ $? "- itadmin_data_mysql_vlan %d", back
+ return back;
+}
+
+
+
+/** Read speed table.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_speed(itadmin_job *job)
+{
+ MYSQL_RES *mr; /* Results set. */
+ MYSQL_ROW mrow; /* One result row. */
+ char const *val[sizeof(itadmin_mysql_cn_speed)/sizeof(DK3_PCCHAR) - 1];
+ size_t cnind[sizeof(itadmin_mysql_cn_speed)/sizeof(DK3_PCCHAR) - 1];
+ unsigned long *lgts; /* Field lengths. */
+ unsigned int nf; /* Number of fields in result. */
+ int res; /* Query result. */
+ int back = 0;
+ $? "+ itadmin_data_mysql_speed"
+ res = mysql_query((MYSQL *)(job->dbptr), itadmin_mysql_c8_kw[4]);
+ if(0 == res) {
+ mr = mysql_use_result((MYSQL *)(job->dbptr));
+ if(mr) {
+ nf = mysql_num_fields(mr);
+ itadmin_data_mysql_find_indices(
+ job, cnind, itadmin_mysql_sz_cn_speed, nf, mr,
+ itadmin_mysql_cn_speed
+ );
+ back = 1;
+ do {
+ mrow = mysql_fetch_row(mr);
+ if(mrow) {
+ lgts = mysql_fetch_lengths(mr);
+ if(lgts) {
+ itadmin_data_mysql_set_pointers(
+ job, val, cnind, itadmin_mysql_sz_cn_speed,
+ nf, mrow, lgts
+ );
+ res = itadmin_register_speed(job, val[0], val[1]);
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0;
+ }
+ }
+ } while(mrow);
+ mysql_free_result(mr);
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 141);
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 142);
+ }
+ $? "- itadmin_data_mysql_speed %d", back
+ return back;
+}
+
+
+
+/** Read buildings table.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_buildings(itadmin_job *job)
+{
+ MYSQL_RES *mr; /* Results set. */
+ MYSQL_ROW mrow; /* One result row. */
+ char const *val[sizeof(itadmin_mysql_cn_buildings)/sizeof(DK3_PCCHAR) - 1];
+ size_t cnind[sizeof(itadmin_mysql_cn_buildings)/sizeof(DK3_PCCHAR) - 1];
+ unsigned long *lgts; /* Field lengths. */
+ unsigned int nf; /* Number of fields in result. */
+ int res; /* Query result. */
+ int back = 0;
+ $? "+ itadmin_data_mysql_buildings"
+ res = mysql_query((MYSQL *)(job->dbptr), itadmin_mysql_c8_kw[1]);
+ if(0 == res) {
+ mr = mysql_use_result((MYSQL *)(job->dbptr));
+ if(mr) {
+ nf = mysql_num_fields(mr);
+ itadmin_data_mysql_find_indices(
+ job, cnind, itadmin_mysql_sz_cn_buildings, nf, mr,
+ itadmin_mysql_cn_buildings
+ );
+ back = 1;
+ do {
+ mrow = mysql_fetch_row(mr);
+ if(mrow) {
+ lgts = mysql_fetch_lengths(mr);
+ if(lgts) {
+ itadmin_data_mysql_set_pointers(
+ job, val, cnind, itadmin_mysql_sz_cn_buildings,
+ nf, mrow, lgts
+ ); $? ". building \"%!8s\"", TR_8STR(val[0])
+ res = itadmin_register_building(
+ job,
+ val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7]
+ );
+ if(!(res)) { back = 0; }
+ } else {
+ back = 0; $? "! lengths"
+ }
+ }
+ } while(mrow);
+ mysql_free_result(mr);
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 141);
+ }
+ } else {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 142);
+ }
+ $? "- itadmin_data_mysql_buildings %d", back
+ return back;
+}
+
+
+
+/** Read users table.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_users(itadmin_job *job)
+{
+ MYSQL_RES *mr; /* Results set. */
+ MYSQL_ROW mrow; /* One result row. */
+ char const *val[sizeof(itadmin_mysql_cn_users)/sizeof(DK3_PCCHAR) - 1];
+ size_t cnind[sizeof(itadmin_mysql_cn_users)/sizeof(DK3_PCCHAR) - 1];
+ unsigned long *lgts; /* Field lengths array. */
+ unsigned int nf; /* Number of fields in result. */
+ int res; /* Query result. */
+ int back = 0;
+ $? "+ itadmin_data_mysql_users PTR=%d", TR_IPTR(job->dbptr)
+ res = mysql_query((MYSQL *)(job->dbptr), itadmin_mysql_c8_kw[0]); $? ". res = %d", res
+ if(0 == res) { $? ". query ok"
+ mr = mysql_use_result((MYSQL *)(job->dbptr));
+ if(mr) { $? ". have result"
+ nf = mysql_num_fields(mr); $? ". nf = %lu", (unsigned long)nf
+ itadmin_data_mysql_find_indices(
+ job, cnind, itadmin_mysql_sz_cn_users, nf, mr, itadmin_mysql_cn_users
+ );
+ back = 1;
+ do { $? ". start of loop"
+ mrow = mysql_fetch_row(mr);
+ if(mrow) { $? ". found result row"
+ lgts = mysql_fetch_lengths(mr);
+ if(lgts) { $? ". lengths ok"
+ itadmin_data_mysql_set_pointers(
+ job, val, cnind, itadmin_mysql_sz_cn_users,
+ nf, mrow, lgts
+ );
+ res = itadmin_register_user(
+ job, val[0], val[1], val[2], val[3], val[4], val[5], val[6]
+ );
+ if(!(res)) {
+ back = 0;
+ }
+ } else { $? "! lengths"
+ back = 0;
+ }
+ } $? ". end of loop"
+ } while(mrow); $? ". after loop"
+ mysql_free_result(mr);
+ } else { $? "! no result"
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 141);
+ }
+ } else { $? "! query failed %d", res
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 142);
+ } $? "- itadmin_data_mysql_users %d", back
+ return back;
+}
+
+
+
+
+/** Retrieve data from a MySQL database.
+ @param job Job structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_data_mysql_retrieve(itadmin_job *job)
+{
+ int back = 1;
+ $? "+ itadmin_data_mysql_retrieve"
+ /* PROGRESS: Reading users table. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 87);
+ if(!itadmin_data_mysql_users(job)) { back = 0; }
+ /* PROGRESS: Reading buildings table. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 88);
+ if(!itadmin_data_mysql_buildings(job)) { back = 0; }
+ if(itadmin_job_do_network(job)) {
+ /* PROGRESS: Reading connection speed type table. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 89);
+ if(!itadmin_data_mysql_speed(job)) { back = 0; }
+ /* PROGRESS: Reading VLANS table. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 90);
+ if(!itadmin_data_mysql_vlan(job)) { back = 0; }
+ /* PROGRESS: Reading ethernet connections table. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 91);
+ if(!itadmin_data_mysql_patch(job)) { back = 0; }
+ /* PROGRESS: Reading netgroups table. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 92);
+ if(!itadmin_data_mysql_netgroup(job)) { back = 0; }
+ /* PROGRESS: Reading netgroup dependencies. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 93);
+ if(!itadmin_data_mysql_ngdep(job)) { back = 0; }
+ }
+ if((itadmin_job_do_dhcp(job)) || (itadmin_job_do_licenses(job))) {
+ /* PROGRESS: Reading networks. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 94);
+ if(!itadmin_data_mysql_network(job)) { back = 0; }
+ }
+ if(itadmin_job_do_network(job)) {
+ if(itadmin_job_do_dhcp(job)) {
+ /* PROGRESS: Reading DHCP classes. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 95);
+ if(!itadmin_data_mysql_dhcp_class(job)) { back = 0; }
+ /* PROGRESS: Reading DHCP groups. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 96);
+ if(!itadmin_data_mysql_dhcp_group(job)) { back = 0; }
+ }
+ }
+ if((itadmin_job_do_dhcp(job)) || (itadmin_job_do_licenses(job))) {
+ /* PROGRESS: Reading DHCP pools. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 97);
+ if(!itadmin_data_mysql_dhcp_pool(job)) { back = 0; }
+ }
+ /* PROGRESS: Reading hosts. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 98);
+ if(!itadmin_data_mysql_hosts(job)) { back = 0; }
+ /* PROGRESS: Reading host name aliases. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 99);
+ if(!itadmin_data_mysql_alias(job)) { back = 0; }
+ if(itadmin_job_do_dhcp(job)) {
+ /* PROGRESS: Reading DHCP options. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 100);
+ if(!itadmin_data_mysql_dhcp_option(job)) { back = 0; }
+ }
+ if(itadmin_job_do_licenses(job)) {
+ /* PROGRESS: Reading software manufacturers. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 101);
+ if(!itadmin_data_mysql_swman(job)) { back = 0; }
+ /* PROGRESS: Reading software products. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 102);
+ if(!itadmin_data_mysql_swprod(job)) { back = 0; }
+ /* PROGRESS: Reading license types. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 103);
+ if(!itadmin_data_mysql_lictype(job)) { back = 0; }
+ /* PROGRESS: Reading licenses. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 104);
+ if(!itadmin_data_mysql_license(job)) { back = 0; }
+ }
+ /* PROGRESS: Finished reading input. */
+ itadmin_tool_log_1(job, DK3_LL_PROGRESS, 105);
+ $? "- itadmin_data_mysql_retrieve %d", back
+ return back;
+}
+
+
+#endif
+
+int
+itadmin_data_mysql_read(itadmin_job *job)
+{
+#if DK3_HAVE_MYSQL_MYSQL_H || DK3_HAVE_MYSQL_H
+ char dbh[ITADMIN_CONFIG_LINE_SIZE]; /* Host name. */
+ char dbu[ITADMIN_CONFIG_LINE_SIZE]; /* User name. */
+ char dbp[ITADMIN_CONFIG_LINE_SIZE]; /* Password. */
+ char dbn[ITADMIN_CONFIG_LINE_SIZE]; /* DB name. */
+ MYSQL *re1;
+ MYSQL *res; /* Same connection. */
+ int ie; /* INput encoding. */
+ int back = 0;
+ $? "+ itadmin_data_mysql_read"
+ ie = dk3app_get_encoding(job->app);
+ if(0 == mysql_library_init(-1, itadmin_mysql_argv, itadmin_mysql_groups)) {
+ re1 = mysql_init(NULL);
+ if(re1) {
+ if(dk3str_to_c8u_app(dbh,sizeof(dbh),job->dbhn,ie,job->app)) {
+ if(dk3str_to_c8u_app(dbu,sizeof(dbu),job->dbus,ie,job->app)) {
+ if(dk3str_to_c8u_app(dbp,sizeof(dbp),job->dbpw,ie,job->app)) {
+ if(dk3str_to_c8u_app(dbn,sizeof(dbn),job->dbn,ie,job->app)) {
+ $? ". h=\"%!8s\" u=\"%!8s\" p=\"%!8s\" n=\"%!8s\"", dbh, dbu, dbp, dbn
+ res = mysql_real_connect(re1, dbh, dbu, dbp, dbn, 0, NULL, 0);
+ if(res) { $? ". connected"
+ job->dbptr = (void *)res;
+ if(mysql_set_character_set(res, "utf8")) { $? "! utf8"
+ /* WARNING: Failed to set encoding! */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 154);
+ }
+ back = itadmin_data_mysql_retrieve(job);
+ } else { $? "! failed to connect"
+ /* ERROR: Failed to connect to database! */
+ itadmin_tool_log_utf8_5(job,DK3_LL_ERROR,155,156,157,dbn,dbh);
+ }
+ } else { $? "! database name"
+ /* ERROR: Failed to convert database name! */
+ dk3app_log_3(job->app,DK3_LL_ERROR,job->msg,158,159,job->dbn);
+ }
+ } else { $? "! user password"
+ /* ERROR: Failed to convert database user password! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 160);
+ }
+ } else { $? "! user name"
+ /* ERROR: Failed to convert database user name! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 161, 162, job->dbus);
+ }
+ } else { $? "! db host name"
+ /* ERROR: Failed to convert database host name! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 163, 164, job->dbhn);
+ }
+ mysql_close(re1);
+ } else {
+ /* ERROR: Failed to initialize MySQL client object! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 165);
+ }
+ mysql_library_end();
+ } else {
+ /* ERROR: Failed to initialize MySQL library! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 166);
+ }
+ $? "- itadmin_data_mysql_read %d", back
+#else
+ int back = 0;
+ /* ERROR: No MySQL support available! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 167);
+#endif
+ return back;
+}
+
+
+
diff --git a/support/dktools/itanetd.c b/support/dktools/itanetd.c
new file mode 100644
index 0000000000..8da28fe049
--- /dev/null
+++ b/support/dktools/itanetd.c
@@ -0,0 +1,1322 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: itanetd.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file itanetd.c The itanetd module.
+*/
+
+
+#line 10 "itanetd.ctr"
+
+#include "dk3all.h"
+#include "itadmin.h"
+
+
+
+
+
+#line 17 "itanetd.ctr"
+
+
+
+/** Keywords used by the module.
+*/
+static char const * const itadmin_netdocu_c8_kw[] = {
+/* 0 */
+"\n",
+
+/* 1 */
+" ",
+
+/* 2 */
+"w",
+
+/* 3 */
+"netdocu.tex",
+
+/* 4 */
+"pdftitle={",
+
+/* 5 */
+"},",
+
+/* 6 */
+"pdfsubject={",
+
+/* 7 */
+"pdfauthor={",
+
+/* 8 */
+"pdfcreator={itadmin - http://dktools.sourceforge.net/}",
+
+/* 9 */
+"\\author{",
+
+/* 10 */
+"\\title{",
+
+/* 11 */
+"}",
+
+/* 12 */
+"\\section{",
+
+/* 13 */
+"\\subsection[",
+
+/* 14 */
+"]{",
+
+/* 15 */
+"\\subsection{",
+
+/* 16 */
+"\\subsubsection{",
+
+/* 17 */
+"\\clearpage",
+
+/* 18 */
+"\\begin{tabular}{rl}",
+
+/* 19 */
+"\\end{tabular}",
+
+/* 20 */
+"\\\\*[1em]",
+
+/* 21 */
+"\\begin{itemize}",
+
+/* 22 */
+"\\end{itemize}",
+
+/* 23 */
+"\\item{",
+
+/* 24 */
+"&",
+
+/* 25 */
+"\\\\",
+
+/* 26 */
+"\\textbf{",
+
+/* 27 */
+"\\begin{longtable}{ll}",
+
+/* 28 */
+"\\endfirsthead",
+
+/* 29 */
+"\\endhead",
+
+/* 30 */
+"\\endfoot",
+
+/* 31 */
+"\\endlastfoot",
+
+/* 32 */
+"\\end{longtable}",
+
+/* 33 */
+"~\\\\[0.5em]",
+
+/* 34 */
+"\\begin{longtable}{|c|c|c|c|c|}",
+
+/* 35 */
+"\\hline",
+
+/* 36 */
+"\\multicolumn{1}{|c}{\\textbf{",
+
+/* 37 */
+"\\multicolumn{1}{|c|}{\\textbf{",
+
+/* 38 */
+"}}",
+
+NULL
+
+
+#line 181 "itanetd.ctr"
+};
+
+
+
+/** Start of LaTeX source.
+*/
+static char const * const itadmin_netdocu_file_start1a[] = {
+"\\documentclass[titlepage,origlongtable]{scrartcl}",
+"\\KOMAoptions{paper=a4}",
+"\\KOMAoptions{fontsize=12pt}",
+NULL
+
+
+#line 193 "itanetd.ctr"
+};
+
+
+
+/** Start of LaTeX source.
+*/
+static char const * const itadmin_netdocu_file_start1b[] = {
+"\\documentclass[12pt]{article}",
+NULL
+
+
+#line 203 "itanetd.ctr"
+};
+
+
+/** LaTeX packages after ngerman.
+*/
+static char const * const itadmin_netdocu_file_start4[] = {
+"\\usepackage{ifpdf}",
+"\\usepackage[utf8]{inputenc}",
+"\\usepackage{mathptmx}",
+"\\usepackage[scaled=.92]{helvet}",
+"\\usepackage{courier}",
+"\\usepackage[T1]{fontenc}",
+"\\usepackage{textcomp}",
+"\\usepackage{latexsym}",
+"\\usepackage{varioref}",
+"\\usepackage{color}",
+"\\usepackage{makeidx}",
+"\\usepackage{longtable}",
+"\\makeindex",
+"\\ifpdf",
+"\\usepackage[activate=normal]{pdfcprot}",
+"\\pdfcompresslevel=9",
+"\\usepackage[",
+"pdftex,",
+"colorlinks=true,",
+"pdfpagemode=UseNone,",
+"pdfstartview={XYZ 0 835 1.25},",
+"bookmarksnumbered,",
+NULL
+
+
+#line 233 "itanetd.ctr"
+};
+
+
+
+/** LaTeX package after hyperref options for title, subject, author.
+*/
+static char const * const itadmin_netdocu_file_start2[] = {
+"]{hyperref}",
+"\\else",
+"\\usepackage[dvips,colorlinks=true,linkcolor=black]{hyperref}",
+"\\fi",
+"\\parindent0cm",
+NULL
+
+
+#line 247 "itanetd.ctr"
+};
+
+
+
+/** Renewcommand, only used for koma-script.
+*/
+static char const * const itadmin_netdocu_file_start3a[] = {
+"\\renewcommand*{\\sectfont}{\\bfseries}",
+NULL
+
+
+#line 257 "itanetd.ctr"
+};
+
+
+
+/** Final commands after title and author.
+*/
+static char const * const itadmin_netdocu_file_start3[] = {
+"\\setcounter{secnumdepth}{1}",
+"\\begin{document}",
+NULL
+
+
+#line 268 "itanetd.ctr"
+};
+
+
+
+/** LaTeX file end.
+*/
+static char const * const itadmin_netdocu_file_end[] = {
+"\\end{document}",
+NULL
+
+
+#line 278 "itanetd.ctr"
+};
+
+
+
+/** Write section header for hosts section
+*/
+static
+void
+itadmin_netdocu_write_sh_hosts(itadmin_job *job, dk3_stream_t *os)
+{
+ int ie;
+ ie = dk3app_get_encoding(job->app);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[12]);
+ dk3stream_strputs(os, (job->msg)[3], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+}
+
+
+
+/** Write section header for one user.
+*/
+static
+void
+itadmin_netdocu_write_sh_user(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ itadmin_user *user
+)
+{
+#if VERSION_BEFORE_20150821
+ int ie;
+ ie = dk3app_get_encoding(job->app);
+#endif
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[13]);
+ itadmin_tool_write_user_latex_short(job, os, user);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[14]);
+ itadmin_tool_write_user_latex_long(job, os, user);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+}
+
+
+
+/** Write section header "Other hosts"
+ @param job Job structure.
+ @param os Output stream.
+*/
+static
+void
+itadmin_netdocu_write_sh_others(itadmin_job *job, dk3_stream_t *os)
+{
+ int ie;
+ ie = dk3app_get_encoding(job->app);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[15]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[4], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+}
+
+
+
+/** Write section header "BYOD"
+ @param job Job structure.
+ @param os Output stream.
+*/
+static
+void
+itadmin_netdocu_write_sh_byod(itadmin_job *job, dk3_stream_t *os)
+{
+ int ie;
+ ie = dk3app_get_encoding(job->app);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[13]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[21], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[14]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[22], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+}
+
+
+
+/** Write data for one host.
+ @param job Job structure.
+ @param os Output stream.
+ @param host Host to write.
+*/
+static
+void
+itadmin_netdocu_write_one_host(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ itadmin_host *host
+)
+{
+ itadmin_netgroup *ng;
+ char const *p1;
+ int ie;
+
+
+#line 377 "itanetd.ctr"
+ ie = dk3app_get_encoding(job->app);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[16]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, host->sn);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ if(host->dp) {
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[20], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[20]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ } else {
+ if(host->fgu) {
+ switch(host->fgu) {
+ case 2: {
+
+#line 390 "itanetd.ctr"
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[25], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[26], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[27], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[20]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ } break;
+ case 3: {
+
+#line 399 "itanetd.ctr"
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[28], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[20]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ } break;
+ case 4: {
+
+#line 404 "itanetd.ctr"
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[31], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[20]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ } break;
+ default: {
+
+#line 409 "itanetd.ctr"
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[23], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[24], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[20]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ } break;
+ }
+ }
+ }
+ /* begin{tabular}.... */
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[18]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+
+ itadmin_tool_table_section_header(job, os, 5);
+
+
+#line 424 "itanetd.ctr"
+ if(host->un) {
+ itadmin_tool_table_line_start(job, os, 10);
+ itadmin_tool_table_line_sep_rows(job, os);
+ itadmin_tool_write_user_latex_long(job, os, host->un);
+ itadmin_tool_table_line_finish(job, os, 0);
+ } else {
+ if(!(host->fgu)) {
+ itadmin_tool_table_line(job, os, 10, NULL, 1, 0);
+ }
+ }
+
+
+#line 435 "itanetd.ctr"
+ itadmin_tool_table_line(job, os, 6, host->co, 1, 0);
+ /* Ort (Gebaeude und Raum) */
+
+#line 437 "itanetd.ctr"
+ itadmin_tool_table_line_start(job, os, 11);
+ itadmin_tool_table_line_sep_rows(job, os);
+ if(host->bu) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, (host->bu)->s);
+ if(host->room) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[1]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, host->room);
+ }
+ } else {
+ if(host->room) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, host->room);
+ } else {
+ itadmin_tool_table_line_no_data(job, os, 1);
+ }
+ }
+
+#line 452 "itanetd.ctr"
+ itadmin_tool_table_line_finish(job, os, 0);
+ itadmin_tool_table_line(job, os, 7, host->inv, 1, 0);
+ itadmin_tool_table_line(job, os, 8, host->serno, 1, 1);
+
+ itadmin_tool_table_section_header(job, os, 12);
+ if(host->ipv4) {
+ itadmin_tool_table_line_start(job, os, 13);
+ itadmin_tool_table_line_sep_rows(job, os);
+ itadmin_tool_stream_ip(os, host->ipv4);
+ itadmin_tool_table_line_finish(job, os, 0);
+ if(host->dnsd) {
+ itadmin_tool_table_line(job, os, 14, host->dnsd, 0, 0);
+ }
+ } else {
+ if(!(host->dc)) {
+ itadmin_tool_table_line(job, os, 13, NULL, 1, 0);
+ }
+ }
+ /* MAC-Adresse */
+ itadmin_tool_table_line(job, os, 15, host->maca, 1, 0);
+ /* Datendose */
+ p1 = NULL;
+ if(host->nc) { p1 = (host->nc)->s; }
+ itadmin_tool_table_line(job, os, 16, p1, 1, 0);
+ /* DHCP-Klasse */
+ if(!((host->ipv4) || (host->dp))) {
+ p1 = NULL;
+ if(host->dc) { p1 = (host->dc)->sn; }
+ itadmin_tool_table_line(job, os, 17, p1, 1, 0);
+ }
+ /* DHCP-Gruppe */
+ p1 = NULL;
+ if(host->dg) { p1 = (host->dg)->sn; }
+ itadmin_tool_table_line(job, os, 18, p1, 0, 1);
+ /* Netgroups */
+ if(host->ng) {
+ itadmin_tool_table_section_header(job, os, 19);
+ itadmin_tool_table_values(job, os, (host->ng)->sn, (host->ng)->ln, 1, 0);
+ dk3sto_it_reset(job->i_ng);
+ while(NULL != (ng = (itadmin_netgroup *)dk3sto_it_next(job->i_ng))) {
+ if(1 == itadmin_netgroup_host_member(job, ng, host)) {
+ itadmin_tool_table_values(job,os, ng->sn, ng->ln, 0, 0);
+ }
+ }
+ }
+ /* end{tabular} */
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[19]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[17]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+
+
+#line 503 "itanetd.ctr"
+}
+
+
+
+
+/** Write data for one host.
+ @param job Job structure.
+ @param os Output stream.
+ @param host Host to write.
+*/
+static
+void
+itadmin_netdocu_write_byod_host(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ itadmin_host *host
+)
+{
+ char const *p1;
+#if VERSION_BEFORE_20150821
+ int ie;
+#endif
+
+
+#line 526 "itanetd.ctr"
+#if VERSION_BEFORE_20150821
+ ie = dk3app_get_encoding(job->app);
+#endif
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[16]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, host->sn);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ /* begin{tabular}.... */
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[18]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ if(host->un) {
+ itadmin_tool_table_line_start(job, os, 10);
+ itadmin_tool_table_line_sep_rows(job, os);
+ itadmin_tool_write_user_latex_long(job, os, host->un);
+ itadmin_tool_table_line_finish(job, os, 0);
+ } else {
+ }
+ itadmin_tool_table_line(job, os, 6, host->co, 1, 0);
+ if(host->ipv4) {
+ itadmin_tool_table_line_start(job, os, 13);
+ itadmin_tool_table_line_sep_rows(job, os);
+ itadmin_tool_stream_ip(os, host->ipv4);
+ itadmin_tool_table_line_finish(job, os, 0);
+ } else {
+ if(!(host->dc)) {
+ itadmin_tool_table_line(job, os, 13, NULL, 1, 0);
+ }
+ }
+ /* MAC-Adresse */
+ itadmin_tool_table_line(job, os, 15, host->maca, 1, 0);
+ /* DHCP-Klasse */
+ if(!((host->ipv4) || (host->dp))) {
+ p1 = NULL;
+ if(host->dc) { p1 = (host->dc)->sn; }
+ itadmin_tool_table_line(job, os, 17, p1, 1, 0);
+ }
+ /* DHCP-Gruppe */
+ if(host->dg) {
+ p1 = NULL;
+ if(host->dg) { p1 = (host->dg)->sn; }
+ itadmin_tool_table_line(job, os, 18, p1, 0, 1);
+ }
+ /* end{tabular} */
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[19]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+
+
+#line 572 "itanetd.ctr"
+}
+
+
+
+/** Check whether the host is a BRING YOUR OWN DEVICE computer.
+ @param host The host to check.
+ @return 1 for yes, 0 for no.
+*/
+static
+int
+itadmin_netdocu_is_byod(itadmin_host *host)
+{
+ int back = 0;
+ if(!(host->ipv4)) {
+ if(host->dc) {
+ if(host->fgu == 1) {
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Write hosts section of network documentation.
+ @param job Job structure.
+ @param os Output stream.
+*/
+static
+void
+itadmin_netdocu_write_hosts(itadmin_job *job, dk3_stream_t *os)
+{
+ itadmin_user *user;
+ itadmin_host *host;
+ int hshw = 0; /* Flag: Host section header written. */
+ int ushw;
+ dk3sto_it_reset(job->i_us);
+ while(NULL != (user = (itadmin_user *)dk3sto_it_next(job->i_usn))) {
+ ushw = 0;
+ if(user->i_ho) {
+ dk3sto_it_reset(user->i_ho);
+ while(NULL != (host = (itadmin_host *)dk3sto_it_next(user->i_ho))) {
+ if(!(host->snd)) {
+ if(!(hshw)) {
+ itadmin_netdocu_write_sh_hosts(job, os);
+ hshw = 1;
+ }
+ if(!(ushw)) {
+ itadmin_netdocu_write_sh_user(job, os, user);
+ ushw = 1;
+ }
+ itadmin_netdocu_write_one_host(job, os, host);
+ }
+ }
+ }
+ }
+ ushw = 0;
+ dk3sto_it_reset(job->i_ho);
+ while(NULL != (host = (itadmin_host *)dk3sto_it_next(job->i_ho))) {
+ if(!(host->un)) {
+ if(!(host->snd)) {
+ if(!itadmin_netdocu_is_byod(host)) {
+ if(!(hshw)) {
+ itadmin_netdocu_write_sh_hosts(job, os);
+ hshw = 1;
+ }
+ if(!(ushw)) {
+ itadmin_netdocu_write_sh_others(job, os);
+ ushw = 1;
+ }
+ itadmin_netdocu_write_one_host(job, os, host);
+ }
+ }
+ }
+ }
+ ushw = 0;
+ dk3sto_it_reset(job->i_ho);
+ while(NULL != (host = (itadmin_host *)dk3sto_it_next(job->i_ho))) {
+ if(!(host->un)) {
+ if(!(host->snd)) {
+ if(itadmin_netdocu_is_byod(host)) {
+ if(!(hshw)) {
+ itadmin_netdocu_write_sh_hosts(job, os);
+ hshw = 1;
+ }
+ if(!(ushw)) {
+ itadmin_netdocu_write_sh_byod(job, os);
+ ushw = 1;
+ }
+ itadmin_netdocu_write_byod_host(job, os, host);
+ }
+ }
+ }
+ }
+ if(ushw) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[17]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ }
+}
+
+
+
+/** Write start of longtable for Netgroup member hosts.
+ @param job job structure.
+ @param os Output stream.
+*/
+static
+void
+itadmin_netdocu_write_netgroup_member_longtable(
+ itadmin_job *job,
+ dk3_stream_t *os
+)
+{
+ int ie;
+ ie = dk3app_get_encoding(job->app);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[16]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[32], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[27]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[28]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[29]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[30]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[31]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+}
+
+
+
+/** Write one member host to longtable.
+ @param job Job structure.
+ @param os Output stream.
+ @param ng Netgroup.
+ @param ho Host.
+ @param f_d Flag: Direct member (write bold).
+*/
+static
+void
+itadmin_netdocu_write_netgroup_member_host(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ itadmin_netgroup *ng,
+ itadmin_host *ho,
+ int f_d
+)
+{
+ if(f_d) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[26]);
+ }
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, ho->sn);
+ if(f_d) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ }
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ if(ho->co) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, ho->co);
+ }
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[25]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+}
+
+/** Write netgroups section.
+ @param job Job structure.
+ @param os Output stream.
+*/
+static
+int
+itadmin_netdocu_write_netgroups(itadmin_job *job, dk3_stream_t *os)
+{
+ itadmin_netgroup *ng;
+ itadmin_netgroup *ng2;
+ itadmin_host *ho;
+ dk3_sto_it_t *i_ng2;
+ int ng_found = 0;
+ int sh_found = 0;
+ int ie;
+ int back = 1;
+
+ ie = dk3app_get_encoding(job->app);
+ dk3sto_it_reset(job->i_ng);
+ while(NULL != (ng = (itadmin_netgroup *)dk3sto_it_next(job->i_ng))) {
+#if VERSION_BEFORE_20150821
+ sh_found = 0;
+#endif
+ if(!(ng_found)) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[12]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[19], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ ng_found = 1;
+ }
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[15]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, ng->sn);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ if(ng->ln) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, ng->ln);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ }
+ i_ng2 = dk3sto_it_open(job->s_ng);
+ if(i_ng2) {
+ dk3sto_it_reset(i_ng2);
+ sh_found = 0;
+ while(NULL != (ng2 = (itadmin_netgroup *)dk3sto_it_next(i_ng2))) {
+ if(ng->no != ng2->no) {
+ if(dk3bm_get(job->ngdep, ng->no, ng2->no)) {
+ if(!(sh_found)) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[16]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[29], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[18]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ } sh_found = 1;
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, ng2->sn);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ if(ng2->ln) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, ng2->ln);
+ }
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[25]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ }
+ }
+ }
+ if(sh_found) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[19]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ }
+ dk3sto_it_reset(i_ng2);
+ sh_found = 0;
+ while(NULL != (ng2 = (itadmin_netgroup *)dk3sto_it_next(i_ng2))) {
+ if(ng->no != ng2->no) {
+ if(dk3bm_get(job->ngdep, ng2->no, ng->no)) {
+ if(!(sh_found)) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[16]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[30], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[18]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ } sh_found = 1;
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, ng2->sn);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ if(ng2->ln) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, ng2->ln);
+ }
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[25]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ }
+ }
+ }
+ if(sh_found) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[19]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ }
+ dk3sto_it_close(i_ng2);
+ }
+ /* Member hosts */
+ dk3sto_it_reset(job->i_ho);
+ sh_found = 0;
+ while(NULL != (ho = (itadmin_host *)dk3sto_it_next(job->i_ho))) {
+ if(2 == itadmin_netgroup_host_member(job, ng, ho)) {
+ if(!(sh_found)) {
+ itadmin_netdocu_write_netgroup_member_longtable(job, os);
+ } sh_found = 1;
+ itadmin_netdocu_write_netgroup_member_host(job, os, ng, ho, 1);
+ }
+ }
+ dk3sto_it_reset(job->i_ho);
+ while(NULL != (ho = (itadmin_host *)dk3sto_it_next(job->i_ho))) {
+ if(1 == itadmin_netgroup_host_member(job, ng, ho)) {
+ if(!(sh_found)) {
+ itadmin_netdocu_write_netgroup_member_longtable(job, os);
+ } sh_found = 1;
+ itadmin_netdocu_write_netgroup_member_host(job, os, ng, ho, 0);
+ }
+ }
+ if(sh_found) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[32]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ }
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[17]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ }
+ return back;
+}
+
+
+
+
+/** Write DHCP pools list.
+ @param job Job structure.
+ @param os Output stream.
+*/
+static
+void
+itadmin_netdocu_write_dhcp_pools(itadmin_job *job, dk3_stream_t *os)
+{
+ itadmin_dhcp_pool *po;
+ int is_first = 1;
+ int ie;
+ ie = dk3app_get_encoding(job->app);
+ dk3sto_it_reset(job->i_dp);
+ while(NULL != (po = (itadmin_dhcp_pool *)dk3sto_it_next(job->i_dp))) {
+ if(is_first) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[12]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[33], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ } else {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[33]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ } is_first = 0;
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[15]);
+ itadmin_tool_stream_ip(os, po->ip4s);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[18]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[34], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ itadmin_tool_stream_ip(os, po->ip4s);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[25]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[35], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ itadmin_tool_stream_ip(os, po->ip4e);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[25]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[36], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[(po->auc) ? 39 : 40], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[25]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[37], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[(po->duc) ? 39 : 40], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[25]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ if(po->acl) {
+ if((po->acl)->sn) {
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[38], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, (po->acl)->sn);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[25]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ }
+ }
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[19]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ }
+ if(0 == is_first) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[17]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ }
+}
+
+
+
+/** Write DHCP classes list.
+ @param job Job structure.
+ @param os Output stream.
+*/
+static
+void
+itadmin_netdocu_write_dhcp_classes(itadmin_job *job, dk3_stream_t *os)
+{
+ itadmin_dhcp_class *dc;
+ itadmin_host *ho;
+ int is_first = 1;
+ int first_host;
+ int ie;
+ ie = dk3app_get_encoding(job->app);
+ dk3sto_it_reset(job->i_dc);
+ while(NULL != (dc = (itadmin_dhcp_class *)dk3sto_it_next(job->i_dc))) {
+ if(is_first) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[12]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[41], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ } else {
+ }
+ is_first = 0;
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[15]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, dc->sn);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ if(dc->ln) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, dc->ln);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ }
+ if(dc->i_ho) {
+ dk3sto_it_reset(dc->i_ho);
+ first_host = 1;
+ while(NULL != (ho = (itadmin_host *)dk3sto_it_next(dc->i_ho))) {
+ if(first_host) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[27]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[28]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[29]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[30]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[31]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ } first_host = 0;
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, ho->sn);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ if(ho->co) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, ho->co);
+ }
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[25]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ }
+ if(!(first_host)) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[32]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ }
+ }
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[17]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ }
+}
+
+
+
+/** Write patches list.
+ @param job Job structure.
+ @param os Output stream.
+*/
+static
+void
+itadmin_netdocu_write_patches(itadmin_job *job, dk3_stream_t *os)
+{
+ itadmin_connect *co;
+ int is_first = 1;
+ int ie;
+
+
+#line 1016 "itanetd.ctr"
+ ie = dk3app_get_encoding(job->app);
+ dk3sto_it_reset(job->i_pa);
+ while(NULL != (co = (itadmin_connect *)dk3sto_it_next(job->i_pa))) {
+ if(is_first) {
+
+#line 1020 "itanetd.ctr"
+ /* Section patches */
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[12]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[42], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ /* begin longtable */
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[34]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[35]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[36]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[43], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[38]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[36]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[44], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[38]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[36]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[45], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[38]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[36]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[46], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[38]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[37]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[47], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[38]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[25]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[35]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ /* end first header */
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[28]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[35]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[36]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[43], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[38]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[36]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[44], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[38]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[36]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[45], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[38]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[36]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[46], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[38]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[37]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[47], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[38]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[25]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[35]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ /* end header */
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[29]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ /* end footer */
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[30]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ /* end last footer */
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[35]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[31]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ } is_first = 0;
+
+#line 1093 "itanetd.ctr"
+
+ /* Horitontal line */
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[35]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ /* Dose */
+
+#line 1098 "itanetd.ctr"
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, co->s);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ /* Gebaeude + Raum */
+
+#line 1101 "itanetd.ctr"
+ if(co->bu) {
+ if((co->bu)->s) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, (co->bu)->s);
+ if(co->room) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[1]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, co->room);
+ }
+ } else {
+ if(co->room) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, co->room);
+ }
+ }
+ } else {
+ if(co->room) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, co->room);
+ }
+ }
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ /* VLAN */
+
+#line 1120 "itanetd.ctr"
+ if(co->vl) {
+ if((co->vl)->s) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, (co->vl)->s);
+ }
+ }
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ /* Speed */
+
+#line 1127 "itanetd.ctr"
+ if(co->sp) {
+ if((co->sp)->s) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, (co->sp)->s);
+ }
+ }
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ /* Hub port */
+
+#line 1134 "itanetd.ctr"
+ if(co->hp) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, co->hp);
+ }
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[25]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ }
+
+#line 1140 "itanetd.ctr"
+ if(!(is_first)) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[32]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ }
+
+#line 1144 "itanetd.ctr"
+}
+
+
+
+/** Write contents of network documentation.
+ @param job Job structure.
+ @param os Output stream.
+*/
+static
+void
+itadmin_netdocu_write_contents(itadmin_job *job, dk3_stream_t *os)
+{
+ itadmin_netdocu_write_hosts(job, os);
+ itadmin_netdocu_write_netgroups(job, os);
+ itadmin_netdocu_write_dhcp_pools(job, os);
+ itadmin_netdocu_write_dhcp_classes(job, os);
+ itadmin_netdocu_write_patches(job, os);
+}
+
+
+
+/** Write entire output file.
+ @param job Job structure.
+ @param os Output stream.
+ */
+static
+void
+itadmin_netdocu_write_file(itadmin_job *job, dk3_stream_t *os)
+{
+ int ie;
+ ie = dk3app_get_encoding(job->app);
+ if(job->ukoma) {
+ itadmin_tool_write_section(job, os, itadmin_netdocu_file_start1a);
+ } else {
+ itadmin_tool_write_section(job, os, itadmin_netdocu_file_start1b);
+ }
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_strputs(os, (job->msg)[2], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ itadmin_tool_write_section(job, os, itadmin_netdocu_file_start4);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[4]);
+ dk3stream_strputs(os, (job->msg)[0], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[6]);
+ dk3stream_strputs(os, (job->msg)[1], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ if(job->admn) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[7]);
+ dk3stream_strputs(os, job->admn, ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ }
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[8]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ itadmin_tool_write_section(job, os, itadmin_netdocu_file_start2);
+
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[10]);
+ dk3stream_strputs(os, (job->msg)[0], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ if(job->admn) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[9]);
+ dk3stream_strputs(os, job->admn, ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ }
+ if(job->ukoma) {
+ itadmin_tool_write_section(job, os, itadmin_netdocu_file_start3a);
+ }
+ itadmin_tool_write_section(job, os, itadmin_netdocu_file_start3);
+ itadmin_netdocu_write_contents(job, os);
+ dk3uc2lat_final_report(job->uc2l, os);
+ itadmin_tool_write_section(job, os, itadmin_netdocu_file_end);
+}
+
+
+
+int
+itadmin_netdocu(itadmin_job *job)
+{
+ FILE *fipo;
+ dk3_stream_t *os;
+ int back = 0;
+
+
+#line 1230 "itanetd.ctr"
+ fipo = dk3sf_c8_fopen_app(
+ itadmin_netdocu_c8_kw[3], itadmin_netdocu_c8_kw[2], job->app
+ );
+ if(fipo) {
+
+#line 1234 "itanetd.ctr"
+ os = dk3stream_open_file_app(fipo, DK3_STREAM_FLAG_WRITE, job->app);
+ if(os) {
+
+#line 1236 "itanetd.ctr"
+ itadmin_netdocu_write_file(job, os);
+ dk3stream_close(os);
+ back = 1;
+ } else {
+
+#line 1240 "itanetd.ctr"
+ }
+#if DK3_CHAR_SIZE == 1
+ if(!dk3sf_fclose_fn_app(fipo, itadmin_netdocu_c8_kw[3], job->app)) {
+ back = 0;
+ }
+#else
+ if(!dk3sf_fclose_fn_app(fipo, NULL, job->app)) {
+ back = 0;
+ }
+#endif
+ } else {
+
+#line 1251 "itanetd.ctr"
+ }
+
+
+#line 1253 "itanetd.ctr"
+ return back;
+}
+
+
diff --git a/support/dktools/itanetd.ctr b/support/dktools/itanetd.ctr
new file mode 100644
index 0000000000..ac4dd40165
--- /dev/null
+++ b/support/dktools/itanetd.ctr
@@ -0,0 +1,1256 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk3all.h"
+#include "itadmin.h"
+
+
+
+$!trace-include
+
+
+
+/** Keywords used by the module.
+*/
+static char const * const itadmin_netdocu_c8_kw[] = {
+$!string-table
+#
+# 0: Newline
+#
+\n
+#
+# 1: Space
+#
+
+#
+# 2: File open mode for writing
+#
+w
+#
+# 3: Output file name
+#
+netdocu.tex
+#
+# 4: Start of pdftitle
+#
+pdftitle={
+#
+# 5: End of LaTeX command
+#
+},
+#
+# 6: Start of pdfsubject
+#
+pdfsubject={
+#
+# 7: Start of pdfauthor
+#
+pdfauthor={
+#
+# 8: pdfcreator
+#
+pdfcreator={itadmin - http://dktools.sourceforge.net/}
+#
+# 9: Author
+#
+\\author{
+#
+# 10: Title
+#
+\\title{
+#
+# 11: End of LaTeX command
+#
+}
+#
+# 12: Section
+#
+\\section{
+#
+# 13: Start of subsection
+#
+\\subsection[
+#
+# 14: Center part of subsection
+#
+]{
+#
+# 15: Subsection
+#
+\\subsection{
+#
+# 16: Subsubsection
+#
+\\subsubsection{
+#
+# 17: Clearpage
+#
+\\clearpage
+#
+# 18: Begin of table
+#
+\\begin{tabular}{rl}
+#
+# 19: End of table
+#
+\\end{tabular}
+#
+# 20: End of line, no page break
+#
+\\\\*[1em]
+#
+# 21: begin itemize
+#
+\\begin{itemize}
+#
+# 22: end itemize
+#
+\\end{itemize}
+#
+# 23: start item
+#
+\\item{
+#
+# 24: Tabular field separator.
+#
+&
+#
+# 25: Line break in table.
+#
+\\\\
+#
+# 26: Bold font for direct member hosts
+#
+\\textbf{
+#
+# 27:
+#
+\\begin{longtable}{ll}
+#
+# 28:
+#
+\\endfirsthead
+#
+# 29:
+#
+\\endhead
+#
+# 30:
+#
+\\endfoot
+#
+# 31:
+#
+\\endlastfoot
+#
+# 32:
+#
+\\end{longtable}
+#
+# 33: Empty line and newline
+#
+~\\\\[0.5em]
+#
+# 34: Longtable for patches
+#
+\\begin{longtable}{|c|c|c|c|c|}
+#
+# 35: Horizontal line
+#
+\\hline
+#
+# 36: Normal multicolumn for patches
+#
+\\multicolumn{1}{|c}{\\textbf{
+#
+# 37: Last multicolumn
+#
+\\multicolumn{1}{|c|}{\\textbf{
+#
+# 38: End of multicolumn
+#
+}}
+$!end
+};
+
+
+
+/** Start of LaTeX source.
+*/
+static char const * const itadmin_netdocu_file_start1a[] = {
+$!text
+\documentclass[titlepage,origlongtable]{scrartcl}
+\KOMAoptions{paper=a4}
+\KOMAoptions{fontsize=12pt}
+$!end
+};
+
+
+
+/** Start of LaTeX source.
+*/
+static char const * const itadmin_netdocu_file_start1b[] = {
+$!text
+\documentclass[12pt]{article}
+$!end
+};
+
+
+/** LaTeX packages after ngerman.
+*/
+static char const * const itadmin_netdocu_file_start4[] = {
+$!text
+\usepackage{ifpdf}
+\usepackage[utf8]{inputenc}
+\usepackage{mathptmx}
+\usepackage[scaled=.92]{helvet}
+\usepackage{courier}
+\usepackage[T1]{fontenc}
+\usepackage{textcomp}
+\usepackage{latexsym}
+\usepackage{varioref}
+\usepackage{color}
+\usepackage{makeidx}
+\usepackage{longtable}
+\makeindex
+\ifpdf
+\usepackage[activate=normal]{pdfcprot}
+\pdfcompresslevel=9
+\usepackage[
+pdftex,
+colorlinks=true,
+pdfpagemode=UseNone,
+pdfstartview={XYZ 0 835 1.25},
+bookmarksnumbered,
+$!end
+};
+
+
+
+/** LaTeX package after hyperref options for title, subject, author.
+*/
+static char const * const itadmin_netdocu_file_start2[] = {
+$!text
+]{hyperref}
+\else
+\usepackage[dvips,colorlinks=true,linkcolor=black]{hyperref}
+\fi
+\parindent0cm
+$!end
+};
+
+
+
+/** Renewcommand, only used for koma-script.
+*/
+static char const * const itadmin_netdocu_file_start3a[] = {
+$!text
+\renewcommand*{\sectfont}{\bfseries}
+$!end
+};
+
+
+
+/** Final commands after title and author.
+*/
+static char const * const itadmin_netdocu_file_start3[] = {
+$!text
+\setcounter{secnumdepth}{1}
+\begin{document}
+$!end
+};
+
+
+
+/** LaTeX file end.
+*/
+static char const * const itadmin_netdocu_file_end[] = {
+$!text
+\end{document}
+$!end
+};
+
+
+
+/** Write section header for hosts section
+*/
+static
+void
+itadmin_netdocu_write_sh_hosts(itadmin_job *job, dk3_stream_t *os)
+{
+ int ie;
+ ie = dk3app_get_encoding(job->app);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[12]);
+ dk3stream_strputs(os, (job->msg)[3], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+}
+
+
+
+/** Write section header for one user.
+*/
+static
+void
+itadmin_netdocu_write_sh_user(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ itadmin_user *user
+)
+{
+#if VERSION_BEFORE_20150821
+ int ie;
+ ie = dk3app_get_encoding(job->app);
+#endif
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[13]);
+ itadmin_tool_write_user_latex_short(job, os, user);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[14]);
+ itadmin_tool_write_user_latex_long(job, os, user);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+}
+
+
+
+/** Write section header "Other hosts"
+ @param job Job structure.
+ @param os Output stream.
+*/
+static
+void
+itadmin_netdocu_write_sh_others(itadmin_job *job, dk3_stream_t *os)
+{
+ int ie;
+ ie = dk3app_get_encoding(job->app);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[15]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[4], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+}
+
+
+
+/** Write section header "BYOD"
+ @param job Job structure.
+ @param os Output stream.
+*/
+static
+void
+itadmin_netdocu_write_sh_byod(itadmin_job *job, dk3_stream_t *os)
+{
+ int ie;
+ ie = dk3app_get_encoding(job->app);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[13]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[21], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[14]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[22], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+}
+
+
+
+/** Write data for one host.
+ @param job Job structure.
+ @param os Output stream.
+ @param host Host to write.
+*/
+static
+void
+itadmin_netdocu_write_one_host(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ itadmin_host *host
+)
+{
+ itadmin_netgroup *ng;
+ char const *p1;
+ int ie;
+ $? "+ itadmin_netdocu_write_one_host \"%!8s\"", TR_8STR(host->sn)
+ ie = dk3app_get_encoding(job->app);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[16]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, host->sn);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ if(host->dp) {
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[20], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[20]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ } else {
+ if(host->fgu) {
+ switch(host->fgu) {
+ case 2: { $? ". host outside organization unit"
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[25], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[26], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[27], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[20]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ } break;
+ case 3: { $? ". dynamic IP address"
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[28], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[20]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ } break;
+ case 4: { $? ". additional network interface"
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[31], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[20]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ } break;
+ default: { $? ". bring your own device"
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[23], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[24], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[20]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ } break;
+ }
+ }
+ }
+ /* begin{tabular}.... */
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[18]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+
+ itadmin_tool_table_section_header(job, os, 5);
+ $? ". before user"
+ if(host->un) {
+ itadmin_tool_table_line_start(job, os, 10);
+ itadmin_tool_table_line_sep_rows(job, os);
+ itadmin_tool_write_user_latex_long(job, os, host->un);
+ itadmin_tool_table_line_finish(job, os, 0);
+ } else {
+ if(!(host->fgu)) {
+ itadmin_tool_table_line(job, os, 10, NULL, 1, 0);
+ }
+ }
+ $? ". after user"
+ itadmin_tool_table_line(job, os, 6, host->co, 1, 0);
+ /* Ort (Gebaeude und Raum) */ $? ". before building"
+ itadmin_tool_table_line_start(job, os, 11);
+ itadmin_tool_table_line_sep_rows(job, os);
+ if(host->bu) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, (host->bu)->s);
+ if(host->room) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[1]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, host->room);
+ }
+ } else {
+ if(host->room) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, host->room);
+ } else {
+ itadmin_tool_table_line_no_data(job, os, 1);
+ }
+ } $? ". after building"
+ itadmin_tool_table_line_finish(job, os, 0);
+ itadmin_tool_table_line(job, os, 7, host->inv, 1, 0);
+ itadmin_tool_table_line(job, os, 8, host->serno, 1, 1);
+
+ itadmin_tool_table_section_header(job, os, 12);
+ if(host->ipv4) {
+ itadmin_tool_table_line_start(job, os, 13);
+ itadmin_tool_table_line_sep_rows(job, os);
+ itadmin_tool_stream_ip(os, host->ipv4);
+ itadmin_tool_table_line_finish(job, os, 0);
+ if(host->dnsd) {
+ itadmin_tool_table_line(job, os, 14, host->dnsd, 0, 0);
+ }
+ } else {
+ if(!(host->dc)) {
+ itadmin_tool_table_line(job, os, 13, NULL, 1, 0);
+ }
+ }
+ /* MAC-Adresse */
+ itadmin_tool_table_line(job, os, 15, host->maca, 1, 0);
+ /* Datendose */
+ p1 = NULL;
+ if(host->nc) { p1 = (host->nc)->s; }
+ itadmin_tool_table_line(job, os, 16, p1, 1, 0);
+ /* DHCP-Klasse */
+ if(!((host->ipv4) || (host->dp))) {
+ p1 = NULL;
+ if(host->dc) { p1 = (host->dc)->sn; }
+ itadmin_tool_table_line(job, os, 17, p1, 1, 0);
+ }
+ /* DHCP-Gruppe */
+ p1 = NULL;
+ if(host->dg) { p1 = (host->dg)->sn; }
+ itadmin_tool_table_line(job, os, 18, p1, 0, 1);
+ /* Netgroups */
+ if(host->ng) {
+ itadmin_tool_table_section_header(job, os, 19);
+ itadmin_tool_table_values(job, os, (host->ng)->sn, (host->ng)->ln, 1, 0);
+ dk3sto_it_reset(job->i_ng);
+ while(NULL != (ng = (itadmin_netgroup *)dk3sto_it_next(job->i_ng))) {
+ if(1 == itadmin_netgroup_host_member(job, ng, host)) {
+ itadmin_tool_table_values(job,os, ng->sn, ng->ln, 0, 0);
+ }
+ }
+ }
+ /* end{tabular} */
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[19]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[17]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ $? "- itadmin_netdocu_write_one_host"
+}
+
+
+
+
+/** Write data for one host.
+ @param job Job structure.
+ @param os Output stream.
+ @param host Host to write.
+*/
+static
+void
+itadmin_netdocu_write_byod_host(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ itadmin_host *host
+)
+{
+ char const *p1;
+#if VERSION_BEFORE_20150821
+ int ie;
+#endif
+ $? "+ itadmin_netdocu_write_one_host \"%!8s\"", TR_8STR(host->sn)
+#if VERSION_BEFORE_20150821
+ ie = dk3app_get_encoding(job->app);
+#endif
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[16]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, host->sn);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ /* begin{tabular}.... */
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[18]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ if(host->un) {
+ itadmin_tool_table_line_start(job, os, 10);
+ itadmin_tool_table_line_sep_rows(job, os);
+ itadmin_tool_write_user_latex_long(job, os, host->un);
+ itadmin_tool_table_line_finish(job, os, 0);
+ } else {
+ }
+ itadmin_tool_table_line(job, os, 6, host->co, 1, 0);
+ if(host->ipv4) {
+ itadmin_tool_table_line_start(job, os, 13);
+ itadmin_tool_table_line_sep_rows(job, os);
+ itadmin_tool_stream_ip(os, host->ipv4);
+ itadmin_tool_table_line_finish(job, os, 0);
+ } else {
+ if(!(host->dc)) {
+ itadmin_tool_table_line(job, os, 13, NULL, 1, 0);
+ }
+ }
+ /* MAC-Adresse */
+ itadmin_tool_table_line(job, os, 15, host->maca, 1, 0);
+ /* DHCP-Klasse */
+ if(!((host->ipv4) || (host->dp))) {
+ p1 = NULL;
+ if(host->dc) { p1 = (host->dc)->sn; }
+ itadmin_tool_table_line(job, os, 17, p1, 1, 0);
+ }
+ /* DHCP-Gruppe */
+ if(host->dg) {
+ p1 = NULL;
+ if(host->dg) { p1 = (host->dg)->sn; }
+ itadmin_tool_table_line(job, os, 18, p1, 0, 1);
+ }
+ /* end{tabular} */
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[19]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ $? "- itadmin_netdocu_write_one_host"
+}
+
+
+
+/** Check whether the host is a BRING YOUR OWN DEVICE computer.
+ @param host The host to check.
+ @return 1 for yes, 0 for no.
+*/
+static
+int
+itadmin_netdocu_is_byod(itadmin_host *host)
+{
+ int back = 0;
+ if(!(host->ipv4)) {
+ if(host->dc) {
+ if(host->fgu == 1) {
+ back = 1;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+/** Write hosts section of network documentation.
+ @param job Job structure.
+ @param os Output stream.
+*/
+static
+void
+itadmin_netdocu_write_hosts(itadmin_job *job, dk3_stream_t *os)
+{
+ itadmin_user *user;
+ itadmin_host *host;
+ int hshw = 0; /* Flag: Host section header written. */
+ int ushw;
+ dk3sto_it_reset(job->i_us);
+ while(NULL != (user = (itadmin_user *)dk3sto_it_next(job->i_usn))) {
+ ushw = 0;
+ if(user->i_ho) {
+ dk3sto_it_reset(user->i_ho);
+ while(NULL != (host = (itadmin_host *)dk3sto_it_next(user->i_ho))) {
+ if(!(host->snd)) {
+ if(!(hshw)) {
+ itadmin_netdocu_write_sh_hosts(job, os);
+ hshw = 1;
+ }
+ if(!(ushw)) {
+ itadmin_netdocu_write_sh_user(job, os, user);
+ ushw = 1;
+ }
+ itadmin_netdocu_write_one_host(job, os, host);
+ }
+ }
+ }
+ }
+ ushw = 0;
+ dk3sto_it_reset(job->i_ho);
+ while(NULL != (host = (itadmin_host *)dk3sto_it_next(job->i_ho))) {
+ if(!(host->un)) {
+ if(!(host->snd)) {
+ if(!itadmin_netdocu_is_byod(host)) {
+ if(!(hshw)) {
+ itadmin_netdocu_write_sh_hosts(job, os);
+ hshw = 1;
+ }
+ if(!(ushw)) {
+ itadmin_netdocu_write_sh_others(job, os);
+ ushw = 1;
+ }
+ itadmin_netdocu_write_one_host(job, os, host);
+ }
+ }
+ }
+ }
+ ushw = 0;
+ dk3sto_it_reset(job->i_ho);
+ while(NULL != (host = (itadmin_host *)dk3sto_it_next(job->i_ho))) {
+ if(!(host->un)) {
+ if(!(host->snd)) {
+ if(itadmin_netdocu_is_byod(host)) {
+ if(!(hshw)) {
+ itadmin_netdocu_write_sh_hosts(job, os);
+ hshw = 1;
+ }
+ if(!(ushw)) {
+ itadmin_netdocu_write_sh_byod(job, os);
+ ushw = 1;
+ }
+ itadmin_netdocu_write_byod_host(job, os, host);
+ }
+ }
+ }
+ }
+ if(ushw) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[17]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ }
+}
+
+
+
+/** Write start of longtable for Netgroup member hosts.
+ @param job job structure.
+ @param os Output stream.
+*/
+static
+void
+itadmin_netdocu_write_netgroup_member_longtable(
+ itadmin_job *job,
+ dk3_stream_t *os
+)
+{
+ int ie;
+ ie = dk3app_get_encoding(job->app);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[16]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[32], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[27]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[28]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[29]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[30]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[31]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+}
+
+
+
+/** Write one member host to longtable.
+ @param job Job structure.
+ @param os Output stream.
+ @param ng Netgroup.
+ @param ho Host.
+ @param f_d Flag: Direct member (write bold).
+*/
+static
+void
+itadmin_netdocu_write_netgroup_member_host(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ itadmin_netgroup *ng,
+ itadmin_host *ho,
+ int f_d
+)
+{
+ if(f_d) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[26]);
+ }
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, ho->sn);
+ if(f_d) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ }
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ if(ho->co) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, ho->co);
+ }
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[25]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+}
+
+/** Write netgroups section.
+ @param job Job structure.
+ @param os Output stream.
+*/
+static
+int
+itadmin_netdocu_write_netgroups(itadmin_job *job, dk3_stream_t *os)
+{
+ itadmin_netgroup *ng;
+ itadmin_netgroup *ng2;
+ itadmin_host *ho;
+ dk3_sto_it_t *i_ng2;
+ int ng_found = 0;
+ int sh_found = 0;
+ int ie;
+ int back = 1;
+
+ ie = dk3app_get_encoding(job->app);
+ dk3sto_it_reset(job->i_ng);
+ while(NULL != (ng = (itadmin_netgroup *)dk3sto_it_next(job->i_ng))) {
+#if VERSION_BEFORE_20150821
+ sh_found = 0;
+#endif
+ if(!(ng_found)) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[12]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[19], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ ng_found = 1;
+ }
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[15]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, ng->sn);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ if(ng->ln) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, ng->ln);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ }
+ i_ng2 = dk3sto_it_open(job->s_ng);
+ if(i_ng2) {
+ dk3sto_it_reset(i_ng2);
+ sh_found = 0;
+ while(NULL != (ng2 = (itadmin_netgroup *)dk3sto_it_next(i_ng2))) {
+ if(ng->no != ng2->no) {
+ if(dk3bm_get(job->ngdep, ng->no, ng2->no)) {
+ if(!(sh_found)) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[16]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[29], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[18]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ } sh_found = 1;
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, ng2->sn);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ if(ng2->ln) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, ng2->ln);
+ }
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[25]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ }
+ }
+ }
+ if(sh_found) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[19]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ }
+ dk3sto_it_reset(i_ng2);
+ sh_found = 0;
+ while(NULL != (ng2 = (itadmin_netgroup *)dk3sto_it_next(i_ng2))) {
+ if(ng->no != ng2->no) {
+ if(dk3bm_get(job->ngdep, ng2->no, ng->no)) {
+ if(!(sh_found)) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[16]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[30], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[18]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ } sh_found = 1;
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, ng2->sn);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ if(ng2->ln) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, ng2->ln);
+ }
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[25]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ }
+ }
+ }
+ if(sh_found) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[19]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ }
+ dk3sto_it_close(i_ng2);
+ }
+ /* Member hosts */
+ dk3sto_it_reset(job->i_ho);
+ sh_found = 0;
+ while(NULL != (ho = (itadmin_host *)dk3sto_it_next(job->i_ho))) {
+ if(2 == itadmin_netgroup_host_member(job, ng, ho)) {
+ if(!(sh_found)) {
+ itadmin_netdocu_write_netgroup_member_longtable(job, os);
+ } sh_found = 1;
+ itadmin_netdocu_write_netgroup_member_host(job, os, ng, ho, 1);
+ }
+ }
+ dk3sto_it_reset(job->i_ho);
+ while(NULL != (ho = (itadmin_host *)dk3sto_it_next(job->i_ho))) {
+ if(1 == itadmin_netgroup_host_member(job, ng, ho)) {
+ if(!(sh_found)) {
+ itadmin_netdocu_write_netgroup_member_longtable(job, os);
+ } sh_found = 1;
+ itadmin_netdocu_write_netgroup_member_host(job, os, ng, ho, 0);
+ }
+ }
+ if(sh_found) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[32]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ }
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[17]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ }
+ return back;
+}
+
+
+
+
+/** Write DHCP pools list.
+ @param job Job structure.
+ @param os Output stream.
+*/
+static
+void
+itadmin_netdocu_write_dhcp_pools(itadmin_job *job, dk3_stream_t *os)
+{
+ itadmin_dhcp_pool *po;
+ int is_first = 1;
+ int ie;
+ ie = dk3app_get_encoding(job->app);
+ dk3sto_it_reset(job->i_dp);
+ while(NULL != (po = (itadmin_dhcp_pool *)dk3sto_it_next(job->i_dp))) {
+ if(is_first) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[12]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[33], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ } else {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[33]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ } is_first = 0;
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[15]);
+ itadmin_tool_stream_ip(os, po->ip4s);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[18]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[34], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ itadmin_tool_stream_ip(os, po->ip4s);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[25]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[35], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ itadmin_tool_stream_ip(os, po->ip4e);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[25]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[36], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[(po->auc) ? 39 : 40], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[25]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[37], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[(po->duc) ? 39 : 40], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[25]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ if(po->acl) {
+ if((po->acl)->sn) {
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[38], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, (po->acl)->sn);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[25]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ }
+ }
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[19]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ }
+ if(0 == is_first) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[17]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ }
+}
+
+
+
+/** Write DHCP classes list.
+ @param job Job structure.
+ @param os Output stream.
+*/
+static
+void
+itadmin_netdocu_write_dhcp_classes(itadmin_job *job, dk3_stream_t *os)
+{
+ itadmin_dhcp_class *dc;
+ itadmin_host *ho;
+ int is_first = 1;
+ int first_host;
+ int ie;
+ ie = dk3app_get_encoding(job->app);
+ dk3sto_it_reset(job->i_dc);
+ while(NULL != (dc = (itadmin_dhcp_class *)dk3sto_it_next(job->i_dc))) {
+ if(is_first) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[12]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[41], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ } else {
+ }
+ is_first = 0;
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[15]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, dc->sn);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ if(dc->ln) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, dc->ln);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ }
+ if(dc->i_ho) {
+ dk3sto_it_reset(dc->i_ho);
+ first_host = 1;
+ while(NULL != (ho = (itadmin_host *)dk3sto_it_next(dc->i_ho))) {
+ if(first_host) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[27]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[28]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[29]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[30]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[31]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ } first_host = 0;
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, ho->sn);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ if(ho->co) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, ho->co);
+ }
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[25]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ }
+ if(!(first_host)) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[32]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ }
+ }
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[17]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ }
+}
+
+
+
+/** Write patches list.
+ @param job Job structure.
+ @param os Output stream.
+*/
+static
+void
+itadmin_netdocu_write_patches(itadmin_job *job, dk3_stream_t *os)
+{
+ itadmin_connect *co;
+ int is_first = 1;
+ int ie;
+ $? "+ itadmin_netdocu_write_patches"
+ ie = dk3app_get_encoding(job->app);
+ dk3sto_it_reset(job->i_pa);
+ while(NULL != (co = (itadmin_connect *)dk3sto_it_next(job->i_pa))) {
+ if(is_first) { $? ". section and table header"
+ /* Section patches */
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[12]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[42], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ /* begin longtable */
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[34]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[35]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[36]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[43], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[38]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[36]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[44], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[38]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[36]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[45], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[38]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[36]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[46], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[38]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[37]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[47], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[38]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[25]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[35]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ /* end first header */
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[28]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[35]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[36]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[43], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[38]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[36]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[44], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[38]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[36]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[45], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[38]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[36]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[46], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[38]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[37]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[47], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[38]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[25]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[35]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ /* end header */
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[29]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ /* end footer */
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[30]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ /* end last footer */
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[35]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[31]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ } is_first = 0; $? ". headers ok"
+
+ /* Horitontal line */
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[35]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ /* Dose */ $? ". "
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, co->s);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ /* Gebaeude + Raum */ $? ". "
+ if(co->bu) {
+ if((co->bu)->s) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, (co->bu)->s);
+ if(co->room) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[1]);
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, co->room);
+ }
+ } else {
+ if(co->room) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, co->room);
+ }
+ }
+ } else {
+ if(co->room) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, co->room);
+ }
+ }
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ /* VLAN */ $? ". "
+ if(co->vl) {
+ if((co->vl)->s) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, (co->vl)->s);
+ }
+ }
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ /* Speed */ $? ". "
+ if(co->sp) {
+ if((co->sp)->s) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, (co->sp)->s);
+ }
+ }
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[24]);
+ /* Hub port */ $? ". "
+ if(co->hp) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, co->hp);
+ }
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[25]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ } $? ". "
+ if(!(is_first)) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[32]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ } $? "- itadmin_netdocu_write_patches"
+}
+
+
+
+/** Write contents of network documentation.
+ @param job Job structure.
+ @param os Output stream.
+*/
+static
+void
+itadmin_netdocu_write_contents(itadmin_job *job, dk3_stream_t *os)
+{
+ itadmin_netdocu_write_hosts(job, os);
+ itadmin_netdocu_write_netgroups(job, os);
+ itadmin_netdocu_write_dhcp_pools(job, os);
+ itadmin_netdocu_write_dhcp_classes(job, os);
+ itadmin_netdocu_write_patches(job, os);
+}
+
+
+
+/** Write entire output file.
+ @param job Job structure.
+ @param os Output stream.
+ */
+static
+void
+itadmin_netdocu_write_file(itadmin_job *job, dk3_stream_t *os)
+{
+ int ie;
+ ie = dk3app_get_encoding(job->app);
+ if(job->ukoma) {
+ itadmin_tool_write_section(job, os, itadmin_netdocu_file_start1a);
+ } else {
+ itadmin_tool_write_section(job, os, itadmin_netdocu_file_start1b);
+ }
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_strputs(os, (job->msg)[2], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ itadmin_tool_write_section(job, os, itadmin_netdocu_file_start4);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[4]);
+ dk3stream_strputs(os, (job->msg)[0], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[6]);
+ dk3stream_strputs(os, (job->msg)[1], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ if(job->admn) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[7]);
+ dk3stream_strputs(os, job->admn, ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[5]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ }
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[8]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ itadmin_tool_write_section(job, os, itadmin_netdocu_file_start2);
+
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[10]);
+ dk3stream_strputs(os, (job->msg)[0], ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ if(job->admn) {
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[9]);
+ dk3stream_strputs(os, job->admn, ie);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[11]);
+ dk3stream_c8_fputs(os, itadmin_netdocu_c8_kw[0]);
+ }
+ if(job->ukoma) {
+ itadmin_tool_write_section(job, os, itadmin_netdocu_file_start3a);
+ }
+ itadmin_tool_write_section(job, os, itadmin_netdocu_file_start3);
+ itadmin_netdocu_write_contents(job, os);
+ dk3uc2lat_final_report(job->uc2l, os);
+ itadmin_tool_write_section(job, os, itadmin_netdocu_file_end);
+}
+
+
+
+int
+itadmin_netdocu(itadmin_job *job)
+{
+ FILE *fipo;
+ dk3_stream_t *os;
+ int back = 0;
+ $? "+ itadmin_netdocu"
+ fipo = dk3sf_c8_fopen_app(
+ itadmin_netdocu_c8_kw[3], itadmin_netdocu_c8_kw[2], job->app
+ );
+ if(fipo) { $? ". fopen"
+ os = dk3stream_open_file_app(fipo, DK3_STREAM_FLAG_WRITE, job->app);
+ if(os) { $? ". os"
+ itadmin_netdocu_write_file(job, os);
+ dk3stream_close(os);
+ back = 1;
+ } else { $? "! os"
+ }
+#if DK3_CHAR_SIZE == 1
+ if(!dk3sf_fclose_fn_app(fipo, itadmin_netdocu_c8_kw[3], job->app)) {
+ back = 0;
+ }
+#else
+ if(!dk3sf_fclose_fn_app(fipo, NULL, job->app)) {
+ back = 0;
+ }
+#endif
+ } else { $? "! fopen"
+ }
+ $? "- itadmin_netdocu %d", back
+ return back;
+}
+
+
diff --git a/support/dktools/itange.c b/support/dktools/itange.c
new file mode 100644
index 0000000000..0d79c75901
--- /dev/null
+++ b/support/dktools/itange.c
@@ -0,0 +1,325 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: itange.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file itange.c The itange module.
+*/
+
+
+#line 10 "itange.ctr"
+
+#include "dk3all.h"
+#include "itadmin.h"
+
+
+
+
+
+#line 17 "itange.ctr"
+
+
+
+/** Keywords used by the module.
+*/
+static char const * const itadmin_netgroup_c8_kw[] = {
+/* 0 */
+"netgroup.ldif",
+
+/* 1 */
+"w",
+
+/* 2 */
+"dn: cn=",
+
+/* 3 */
+",ou=netgroup,",
+
+/* 4 */
+"objectClass: top",
+
+/* 5 */
+"objectClass: nisNetgroup",
+
+/* 6 */
+"cn: ",
+
+/* 7 */
+"nisNetgroupTriple: (",
+
+/* 8 */
+",,",
+
+/* 9 */
+")",
+
+NULL
+
+
+#line 65 "itange.ctr"
+};
+
+int
+itadmin_netgroup_expand(itadmin_job *job)
+{
+ itadmin_netgroup *ng; /* Current netgroup. */
+ itadmin_ngdep *nd; /* Netgroup dependency. */
+ size_t nng; /* Next netgroup number. */
+ int back = 0;
+
+
+#line 75 "itange.ctr"
+ /*
+ Assign number to each netgroup.
+ */
+ nng = 0;
+ dk3sto_it_reset(job->i_ng);
+ while(NULL != (ng = (itadmin_netgroup *)dk3sto_it_next(job->i_ng))) {
+ ng->no = nng++;
+ }
+ job->nng = nng;
+ /*
+ Create dependency matrix.
+ */
+ if(nng > 0) {
+ job->ngdep = dk3bm_open(nng, nng, job->app);
+ if(job->ngdep) {
+
+#line 90 "itange.ctr"
+ /*
+ Enter dependencies into matrix.
+ */
+ dk3sto_it_reset(job->i_nd);
+ while(NULL != (nd = (itadmin_ngdep *)dk3sto_it_next(job->i_nd))) {
+ if((nd->ch) && (nd->pa)) {
+ dk3bm_set(job->ngdep, (nd->ch)->no, (nd->pa)->no, 1);
+ }
+ }
+ /*
+ Expand matrix to find indirect parent/child relations.
+ */
+ dk3bm_expand(job->ngdep);
+ back = 1;
+ } else {
+
+#line 105 "itange.ctr"
+ }
+ } else {
+
+#line 107 "itange.ctr"
+ back = 1;
+ }
+
+
+#line 110 "itange.ctr"
+ return back;
+}
+
+
+
+int
+itadmin_netgroup_host_member(
+ itadmin_job *job,
+ itadmin_netgroup *netgroup,
+ itadmin_host *host
+)
+{
+ int back = 0;
+
+
+#line 124 "itange.ctr"
+ if((netgroup) && (host)) {
+
+#line 125 "itange.ctr"
+ if(host->ng) {
+
+#line 126 "itange.ctr"
+ if((host->ng)->no == netgroup->no) {
+
+#line 127 "itange.ctr"
+ back = 2;
+ } else {
+
+#line 129 "itange.ctr"
+ if(job->ngdep) {
+
+#line 130 "itange.ctr"
+ if(dk3bm_get(job->ngdep, (host->ng)->no, netgroup->no)) {
+ back = 1;
+ }
+ } else {
+
+#line 134 "itange.ctr"
+ }
+ }
+ } else {
+
+#line 137 "itange.ctr"
+ }
+ } else {
+
+#line 139 "itange.ctr"
+ }
+
+#line 140 "itange.ctr"
+ return back;
+}
+
+
+
+int
+itadmin_netgroup_ldif_output(itadmin_job *job)
+{
+ char bu[ITADMIN_CONFIG_LINE_SIZE];
+ itadmin_netgroup *ng; /* Current netgroup to process. */
+ itadmin_host *host; /* Current host to process. */
+ FILE *fipo; /* Output file. */
+ char const *al; /* Current alias name. */
+ int ie; /* Input encoding. */
+ int nghf = 0; /* Flag: Already host found here. */
+ int back = 0;
+
+
+#line 157 "itange.ctr"
+ ie = dk3app_get_encoding(job->app);
+ if(dk3str_to_c8u_app(bu,sizeof(bu),job->ldapb,ie,job->app)) {
+
+#line 159 "itange.ctr"
+ fipo = dk3sf_c8_fopen_app(
+ itadmin_netgroup_c8_kw[0],
+ itadmin_netgroup_c8_kw[1],
+ job->app
+ );
+ if(fipo) {
+
+#line 165 "itange.ctr"
+ dk3sto_it_reset(job->i_ng);
+ while(NULL != (ng = (itadmin_netgroup *)dk3sto_it_next(job->i_ng))) {
+ nghf = 0;
+
+#line 168 "itange.ctr"
+ dk3sto_it_reset(job->i_hoi);
+ while(NULL != (host = (itadmin_host *)dk3sto_it_next(job->i_hoi))) {
+ if((host->sn) && (host->ipv4) && (host->dnsd)) {
+
+#line 171 "itange.ctr"
+ if(itadmin_netgroup_host_member(job, ng, host)) {
+
+#line 172 "itange.ctr"
+ if(!(nghf)) {
+ fputs(itadmin_netgroup_c8_kw[2], fipo);
+ fputs(ng->sn, fipo);
+ fputs(itadmin_netgroup_c8_kw[3], fipo);
+ fputs(bu, fipo);
+ fputc('\n', fipo);
+ fputs(itadmin_netgroup_c8_kw[4], fipo);
+ fputc('\n', fipo);
+ fputs(itadmin_netgroup_c8_kw[5], fipo);
+ fputc('\n', fipo);
+ fputs(itadmin_netgroup_c8_kw[6], fipo);
+ fputs(ng->sn, fipo);
+ fputc('\n', fipo);
+ }
+ nghf = 1;
+
+#line 187 "itange.ctr"
+ /* Short host name */
+ fputs(itadmin_netgroup_c8_kw[7], fipo);
+ fputs(host->sn, fipo);
+ fputs(itadmin_netgroup_c8_kw[8], fipo);
+ fputs(host->dnsd, fipo);
+ fputs(itadmin_netgroup_c8_kw[9], fipo);
+ fputc('\n', fipo);
+ /* Full host name */
+ fputs(itadmin_netgroup_c8_kw[7], fipo);
+ fputs(host->sn, fipo);
+ fputc('.', fipo);
+ fputs(host->dnsd, fipo);
+ fputs(itadmin_netgroup_c8_kw[8], fipo);
+ fputs(host->dnsd, fipo);
+ fputs(itadmin_netgroup_c8_kw[9], fipo);
+ fputc('\n', fipo);
+ /* Aliases */
+ if(host->i_al) {
+ dk3sto_it_reset(host->i_al);
+ while(NULL != (al = (char const *)dk3sto_it_next(host->i_al))) {
+ fputs(itadmin_netgroup_c8_kw[7], fipo);
+ fputs(al, fipo);
+ fputs(itadmin_netgroup_c8_kw[8], fipo);
+ fputs(host->dnsd, fipo);
+ fputs(itadmin_netgroup_c8_kw[9], fipo);
+ fputc('\n', fipo);
+ }
+ }
+ /* IP */
+ fputs(itadmin_netgroup_c8_kw[7], fipo);
+ itadmin_tool_write_ip(fipo, host->ipv4);
+ fputs(itadmin_netgroup_c8_kw[8], fipo);
+ fputs(host->dnsd, fipo);
+ fputs(itadmin_netgroup_c8_kw[9], fipo);
+ fputc('\n', fipo);
+ } else {
+
+#line 223 "itange.ctr"
+ }
+ }
+ }
+ if(nghf) {
+ fputc('\n', fipo);
+ }
+ }
+ back = 1;
+#if DK3_CHAR_SIZE == 1
+ if(!dk3sf_fclose_fn_app(fipo, itadmin_netgroup_c8_kw[0], job->app)) {
+ back = 0;
+ }
+#else
+ if(!dk3sf_fclose_fn_app(fipo, NULL, job->app)) {
+ back = 0;
+ }
+#endif
+ } else {
+
+#line 241 "itange.ctr"
+ }
+ } else {
+
+#line 243 "itange.ctr"
+ }
+
+
+#line 245 "itange.ctr"
+ return back;
+}
+
+
diff --git a/support/dktools/itange.ctr b/support/dktools/itange.ctr
new file mode 100644
index 0000000000..30ae02b546
--- /dev/null
+++ b/support/dktools/itange.ctr
@@ -0,0 +1,248 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk3all.h"
+#include "itadmin.h"
+
+
+
+$!trace-include
+
+
+
+/** Keywords used by the module.
+*/
+static char const * const itadmin_netgroup_c8_kw[] = {
+$!string-table
+#
+# 0: File name "netgroup.ldif"
+#
+netgroup.ldif
+#
+# 1: File open mode "w"
+#
+w
+#
+# 2: Start of DN line
+#
+dn: cn=
+#
+# 3: Middle of DN line
+#
+,ou=netgroup,
+#
+# 4: objectClass: top
+#
+objectClass: top
+#
+# 5: objectClass: nisNetgroup
+#
+objectClass: nisNetgroup
+#
+# 6: cn: (start of line)
+#
+cn:
+#
+# 7: nisNetgroupTriple: (start of line)
+#
+nisNetgroupTriple: (
+#
+# 8: Center of nisNetgroupTriple line
+#
+,,
+#
+# 9: End of nisNetgroupTriple line
+#
+)
+$!end
+};
+
+int
+itadmin_netgroup_expand(itadmin_job *job)
+{
+ itadmin_netgroup *ng; /* Current netgroup. */
+ itadmin_ngdep *nd; /* Netgroup dependency. */
+ size_t nng; /* Next netgroup number. */
+ int back = 0;
+ $? "+ itadmin_netgroup_expand"
+ /*
+ Assign number to each netgroup.
+ */
+ nng = 0;
+ dk3sto_it_reset(job->i_ng);
+ while(NULL != (ng = (itadmin_netgroup *)dk3sto_it_next(job->i_ng))) {
+ ng->no = nng++;
+ }
+ job->nng = nng;
+ /*
+ Create dependency matrix.
+ */
+ if(nng > 0) {
+ job->ngdep = dk3bm_open(nng, nng, job->app);
+ if(job->ngdep) { $? ". allocation"
+ /*
+ Enter dependencies into matrix.
+ */
+ dk3sto_it_reset(job->i_nd);
+ while(NULL != (nd = (itadmin_ngdep *)dk3sto_it_next(job->i_nd))) {
+ if((nd->ch) && (nd->pa)) {
+ dk3bm_set(job->ngdep, (nd->ch)->no, (nd->pa)->no, 1);
+ }
+ }
+ /*
+ Expand matrix to find indirect parent/child relations.
+ */
+ dk3bm_expand(job->ngdep);
+ back = 1;
+ } else { $? "! allocation"
+ }
+ } else { $? ". no netgroups"
+ back = 1;
+ }
+ $? "- itadmin_netgroup_expand %d", back
+ return back;
+}
+
+
+
+int
+itadmin_netgroup_host_member(
+ itadmin_job *job,
+ itadmin_netgroup *netgroup,
+ itadmin_host *host
+)
+{
+ int back = 0;
+ $? "+ itadmin_netgroup_host_member"
+ if((netgroup) && (host)) { $? ". args ok"
+ if(host->ng) { $? ". host->ng"
+ if((host->ng)->no == netgroup->no) { $? ". direct"
+ back = 2;
+ } else { $? ". not direct"
+ if(job->ngdep) { $? ". job->ngdep"
+ if(dk3bm_get(job->ngdep, (host->ng)->no, netgroup->no)) {
+ back = 1;
+ }
+ } else { $? "! job->ngdep"
+ }
+ }
+ } else { $? ". no primary ng"
+ }
+ } else { $? "! args"
+ } $? "- itadmin_netgroup_host_member %d", back
+ return back;
+}
+
+
+
+int
+itadmin_netgroup_ldif_output(itadmin_job *job)
+{
+ char bu[ITADMIN_CONFIG_LINE_SIZE];
+ itadmin_netgroup *ng; /* Current netgroup to process. */
+ itadmin_host *host; /* Current host to process. */
+ FILE *fipo; /* Output file. */
+ char const *al; /* Current alias name. */
+ int ie; /* Input encoding. */
+ int nghf = 0; /* Flag: Already host found here. */
+ int back = 0;
+ $? "+ itadmin_netgroup_ldif_output"
+ ie = dk3app_get_encoding(job->app);
+ if(dk3str_to_c8u_app(bu,sizeof(bu),job->ldapb,ie,job->app)) { $? ". bu"
+ fipo = dk3sf_c8_fopen_app(
+ itadmin_netgroup_c8_kw[0],
+ itadmin_netgroup_c8_kw[1],
+ job->app
+ );
+ if(fipo) { $? ". fipo"
+ dk3sto_it_reset(job->i_ng);
+ while(NULL != (ng = (itadmin_netgroup *)dk3sto_it_next(job->i_ng))) {
+ nghf = 0; $? ". ng"
+ dk3sto_it_reset(job->i_hoi);
+ while(NULL != (host = (itadmin_host *)dk3sto_it_next(job->i_hoi))) {
+ if((host->sn) && (host->ipv4) && (host->dnsd)) { $? ". host"
+ if(itadmin_netgroup_host_member(job, ng, host)) { $? ". member"
+ if(!(nghf)) {
+ fputs(itadmin_netgroup_c8_kw[2], fipo);
+ fputs(ng->sn, fipo);
+ fputs(itadmin_netgroup_c8_kw[3], fipo);
+ fputs(bu, fipo);
+ fputc('\n', fipo);
+ fputs(itadmin_netgroup_c8_kw[4], fipo);
+ fputc('\n', fipo);
+ fputs(itadmin_netgroup_c8_kw[5], fipo);
+ fputc('\n', fipo);
+ fputs(itadmin_netgroup_c8_kw[6], fipo);
+ fputs(ng->sn, fipo);
+ fputc('\n', fipo);
+ }
+ nghf = 1; $? ". header ok"
+ /* Short host name */
+ fputs(itadmin_netgroup_c8_kw[7], fipo);
+ fputs(host->sn, fipo);
+ fputs(itadmin_netgroup_c8_kw[8], fipo);
+ fputs(host->dnsd, fipo);
+ fputs(itadmin_netgroup_c8_kw[9], fipo);
+ fputc('\n', fipo);
+ /* Full host name */
+ fputs(itadmin_netgroup_c8_kw[7], fipo);
+ fputs(host->sn, fipo);
+ fputc('.', fipo);
+ fputs(host->dnsd, fipo);
+ fputs(itadmin_netgroup_c8_kw[8], fipo);
+ fputs(host->dnsd, fipo);
+ fputs(itadmin_netgroup_c8_kw[9], fipo);
+ fputc('\n', fipo);
+ /* Aliases */
+ if(host->i_al) {
+ dk3sto_it_reset(host->i_al);
+ while(NULL != (al = (char const *)dk3sto_it_next(host->i_al))) {
+ fputs(itadmin_netgroup_c8_kw[7], fipo);
+ fputs(al, fipo);
+ fputs(itadmin_netgroup_c8_kw[8], fipo);
+ fputs(host->dnsd, fipo);
+ fputs(itadmin_netgroup_c8_kw[9], fipo);
+ fputc('\n', fipo);
+ }
+ }
+ /* IP */
+ fputs(itadmin_netgroup_c8_kw[7], fipo);
+ itadmin_tool_write_ip(fipo, host->ipv4);
+ fputs(itadmin_netgroup_c8_kw[8], fipo);
+ fputs(host->dnsd, fipo);
+ fputs(itadmin_netgroup_c8_kw[9], fipo);
+ fputc('\n', fipo);
+ } else { $? ". no member"
+ }
+ }
+ }
+ if(nghf) {
+ fputc('\n', fipo);
+ }
+ }
+ back = 1;
+#if DK3_CHAR_SIZE == 1
+ if(!dk3sf_fclose_fn_app(fipo, itadmin_netgroup_c8_kw[0], job->app)) {
+ back = 0;
+ }
+#else
+ if(!dk3sf_fclose_fn_app(fipo, NULL, job->app)) {
+ back = 0;
+ }
+#endif
+ } else { $? "! fipo"
+ }
+ } else { $? "! bu"
+ }
+ $? "- itadmin_netgroup_ldif_output %d", back
+ return back;
+}
+
+
diff --git a/support/dktools/itareg.c b/support/dktools/itareg.c
new file mode 100644
index 0000000000..76c534b978
--- /dev/null
+++ b/support/dktools/itareg.c
@@ -0,0 +1,2235 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: itareg.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file itareg.c The itareg module.
+*/
+
+
+#line 11 "itareg.ctr"
+
+
+#include "dk3all.h"
+#include "itadmin.h"
+
+
+
+
+
+#line 19 "itareg.ctr"
+
+
+
+/** Keywords used by the module.
+*/
+static char const * const itadmin_register_c8_kw[] = {
+/* 0 */
+"",
+
+/* 1 */
+"-",
+
+/* 2 */
+"%02x:%02x:%02x:%02x:%02x:%02x",
+
+NULL
+
+
+#line 39 "itareg.ctr"
+};
+
+
+
+/** Scope type names.
+*/
+char const * const itadmin_register_scope_type_names[] = {
+/* 0 */
+"server",
+
+/* 1 */
+"vlan",
+
+/* 2 */
+"network",
+
+/* 3 */
+"group",
+
+/* 4 */
+"pool",
+
+/* 5 */
+"host",
+
+NULL
+
+
+#line 60 "itareg.ctr"
+};
+
+
+
+int
+itadmin_register_check_user_name(char const *sn)
+{
+ int back = 0;
+
+
+#line 69 "itareg.ctr"
+ if(sn) {
+ if(dk3str_c8_cmp(sn, itadmin_register_c8_kw[0])) {
+ if(dk3str_c8_cmp(sn, itadmin_register_c8_kw[1])) {
+ back = 1;
+ }
+ }
+ }
+
+#line 76 "itareg.ctr"
+ return back;
+}
+
+
+
+int
+itadmin_register_check_ip(char const *ip)
+{
+ int back = 0;
+
+
+#line 86 "itareg.ctr"
+ if(ip) {
+ if(dk3str_c8_len(ip) > 0) {
+ back = 1;
+ }
+ }
+
+#line 91 "itareg.ctr"
+ return back;
+}
+
+
+
+/** Correct a MAC address (Windows notation to normal notation).
+ @param job Job structure.
+ @param mac Text buffer to modify.
+ @return 1 for valid MAC address found, 0 for invalid source text.
+*/
+int
+itadmin_register_correct_mac(itadmin_job *job, char *mac)
+{
+ char *p1;
+ char *p2;
+ int back = 0;
+ int i1;
+ int i2;
+ int i3;
+ int i4;
+ int i5;
+ int i6;
+
+
+#line 114 "itareg.ctr"
+ p1 = mac;
+ while(*p1) {
+ if(*p1 == '-') { *p1 = ':'; }
+ p1++;
+ }
+ p1 = dk3str_c8_chr(mac, ':');
+ if(p1) {
+ *(p1++) = '\0';
+ if(sscanf(mac, "%x", &i1) == 1) {
+ p2 = dk3str_c8_chr(p1, ':');
+ if(p2) {
+ *(p2++) = '\0';
+ if(sscanf(p1, "%x", &i2) == 1) {
+ p1 = dk3str_c8_chr(p2, ':');
+ if(p1) {
+ *(p1++) = '\0';
+ if(sscanf(p2, "%x", &i3) == 1) {
+ p2 = dk3str_c8_chr(p1, ':');
+ if(p2) {
+ *(p2++) = '\0';
+ if(sscanf(p1, "%x", &i4) == 1) {
+ p1 = dk3str_c8_chr(p2, ':');
+ if(p1) {
+ *(p1++) = '\0';
+ if(sscanf(p2, "%x", &i5) == 1) {
+ if(sscanf(p1, "%x", &i6) == 1) {
+ if((i1 >= 0) && (i1 < 256)) {
+ if((i2 >= 0) && (i2 < 256)) {
+ if((i3 >= 0) && (i3 < 256)) {
+ if((i4 >= 0) && (i4 < 256)) {
+ if((i5 >= 0) && (i5 < 256)) {
+ if((i6 >= 0) && (i6 < 256)) {
+ sprintf(
+ mac,
+ itadmin_register_c8_kw[2],
+ i1, i2, i3, i4, i5, i6
+ );
+ back = 1;
+ p1 = mac;
+ while(*p1) {
+ switch(*p1) {
+ case 'a': {
+ *p1 = 'A';
+ } break;
+ case 'b': {
+ *p1 = 'B';
+ } break;
+ case 'c': {
+ *p1 = 'C';
+ } break;
+ case 'd': {
+ *p1 = 'D';
+ } break;
+ case 'e': {
+ *p1 = 'E';
+ } break;
+ case 'f': {
+ *p1 = 'F';
+ } break;
+ }
+ p1++;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+#line 193 "itareg.ctr"
+ return back;
+}
+
+
+
+int
+itadmin_register_user(
+ itadmin_job *job,
+ char const *us_s,
+ char const *us_t,
+ char const *us_sn,
+ char const *us_fn,
+ char const *us_em,
+ char const *us_ko,
+ char const *us_se
+)
+{
+ itadmin_user *nu;
+ int back = 0;
+
+
+#line 213 "itareg.ctr"
+
+
+#line 214 "itareg.ctr"
+
+
+#line 215 "itareg.ctr"
+
+
+#line 216 "itareg.ctr"
+
+
+#line 217 "itareg.ctr"
+
+
+#line 218 "itareg.ctr"
+
+
+#line 219 "itareg.ctr"
+
+
+#line 220 "itareg.ctr"
+ nu = itadmin_mem_user_new(job, us_s, us_t, us_sn, us_fn, us_em, us_ko, us_se);
+ if(itadmin_register_check_user_name(us_s)) {
+ if(dk3sto_it_find_like(job->i_us, (void *)us_s, 1)) {
+ /* ERROR: Duplicated entry! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 168, 169, us_s);
+ } else {
+ if(nu) {
+ if(dk3sto_add(job->s_us, (void *)nu)) {
+ if(dk3sto_add(job->s_usn, (void *)nu)) {
+ back = 1;
+ }
+ } else {
+ itadmin_mem_user_del((void *)nu);
+ }
+ }
+ }
+ } else {
+ back = 1;
+ }
+
+
+#line 240 "itareg.ctr"
+ return back;
+}
+
+
+
+int
+itadmin_register_building(
+ itadmin_job *job,
+ char const *gb_s,
+ char const *gb_l,
+ char const *gb_a1,
+ char const *gb_a2,
+ char const *gb_a3,
+ char const *gb_a4,
+ char const *gb_plz,
+ char const *gb_ort
+)
+{
+ itadmin_building *nb;
+ int back = 0;
+
+
+#line 261 "itareg.ctr"
+ if(itadmin_register_check_user_name(gb_s)) {
+
+#line 262 "itareg.ctr"
+ if(dk3sto_it_find_like(job->i_bu, (void *)gb_s, 1)) {
+
+#line 263 "itareg.ctr"
+ /* ERROR: Duplicated entry! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 170, 171, gb_s);
+ } else {
+
+#line 266 "itareg.ctr"
+ nb = itadmin_mem_building_new(
+ job,
+ gb_s, gb_l, gb_a1, gb_a2, gb_a3, gb_a4, gb_plz, gb_ort
+ );
+ if(nb) {
+
+#line 271 "itareg.ctr"
+ if(dk3sto_add(job->s_bu, (void *)nb)) {
+
+#line 272 "itareg.ctr"
+ back = 1;
+ } else {
+
+#line 274 "itareg.ctr"
+ itadmin_mem_building_del((void *)nb);
+ }
+ } else {
+
+#line 277 "itareg.ctr"
+ }
+ }
+ } else {
+
+#line 280 "itareg.ctr"
+ back = 1;
+ }
+
+#line 282 "itareg.ctr"
+ return back;
+}
+
+
+
+int
+itadmin_register_speed(itadmin_job *job, char const *sn, char const *ln)
+{
+ itadmin_speed *sp;
+ int back = 0;
+
+
+#line 293 "itareg.ctr"
+ if(itadmin_register_check_user_name(sn)) {
+ if(dk3sto_it_find_like(job->i_sp, (void *)sn, 1)) {
+ /* ERROR: Duplicated entry! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 172, 173, sn);
+ } else {
+ sp = itadmin_mem_speed_new(job, sn, ln);
+ if(sp) {
+ if(dk3sto_add(job->s_sp, (void *)sp)) {
+ back = 1;
+ } else {
+ itadmin_mem_speed_del((void *)sp);
+ }
+ }
+ }
+ } else {
+ back = 1;
+ }
+
+#line 310 "itareg.ctr"
+ return back;
+}
+
+
+
+int
+itadmin_register_vlan(itadmin_job *job, char const *vl_s, char const *vl_l)
+{
+ itadmin_vlan *vl;
+ int back = 0;
+
+
+#line 321 "itareg.ctr"
+ if(itadmin_register_check_user_name(vl_s)) {
+ if(dk3sto_it_find_like(job->i_vl, (void *)vl_s, 1)) {
+ /* ERROR: Duplicated entry! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 174, 175, vl_s);
+ } else {
+ vl = itadmin_mem_vlan_new(job, vl_s, vl_l);
+ if(vl) {
+ if(dk3sto_add(job->s_vl, (void *)vl)) {
+ back = 1;
+ } else {
+ itadmin_mem_vlan_del((void *)vl);
+ }
+ }
+ }
+ } else {
+ back = 1;
+ }
+
+#line 338 "itareg.ctr"
+ return back;
+}
+
+
+
+int
+itadmin_register_netgroup(itadmin_job *job, char const *ng_s, char const *ng_l)
+{
+ itadmin_netgroup *ng;
+ int back = 0;
+ if(itadmin_register_check_user_name(ng_s)) {
+ if(dk3sto_it_find_like(job->i_ng, (void *)ng_s, 1)) {
+ /* ERROR: Duplicate entry! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 180, 181, ng_s);
+ } else {
+ ng = itadmin_mem_netgroup_new(job, ng_s, ng_l);
+ if(ng) {
+ if(dk3sto_add(job->s_ng, (void *)ng)) {
+ back = 1;
+ } else {
+ itadmin_mem_netgroup_del((void *)ng);
+ }
+ }
+ }
+ } else {
+ back = 1;
+ }
+ return back;
+}
+
+
+
+int
+itadmin_register_ngdep(itadmin_job *job, char const *pgn, char const *cgn)
+{
+ itadmin_ngdep *nd;
+ itadmin_netgroup *pg;
+ itadmin_netgroup *cg;
+ int back = 0;
+
+
+#line 378 "itareg.ctr"
+ if((pgn) && (cgn)) {
+ if(itadmin_register_check_user_name(pgn)) {
+ if(itadmin_register_check_user_name(cgn)) {
+ pg = NULL; cg = NULL;
+ pg = (itadmin_netgroup *)dk3sto_it_find_like(job->i_ng, (void *)pgn, 1);
+ cg = (itadmin_netgroup *)dk3sto_it_find_like(job->i_ng, (void *)cgn, 1);
+ if(!(pg)) {
+ /* WARNING: Netgroup does not yet exist! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 182, 183, pgn);
+ itadmin_register_netgroup(job, pgn, NULL);
+ pg = (itadmin_netgroup *)dk3sto_it_find_like(job->i_ng,(void *)pgn,1);
+ }
+ if(!(cg)) {
+ /* WARNING: Netgroup does not yet exist! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 182, 183, cgn);
+ itadmin_register_netgroup(job, cgn, NULL);
+ cg = (itadmin_netgroup *)dk3sto_it_find_like(job->i_ng,(void *)cgn,1);
+ }
+ if((pg) && (cg)) {
+ nd = itadmin_mem_ngdep_new(job, pg, cg);
+ if(nd) {
+ if(dk3sto_add(job->s_nd, (void *)nd)) {
+ back = 1;
+ } else {
+ itadmin_mem_ngdep_del(nd);
+ }
+ }
+ }
+ }
+ }
+ }
+
+#line 409 "itareg.ctr"
+ return back;
+}
+
+
+
+int
+itadmin_register_patch(
+ itadmin_job *job,
+ char const *dd_n,
+ char const *sp_s,
+ char const *vl_s,
+ char const *dd_p,
+ char const *gb_s,
+ char const *dd_r
+)
+{
+ itadmin_connect *pa;
+ itadmin_building *bu;
+ itadmin_vlan *vl;
+ itadmin_speed *sp;
+ int back = 0;
+
+
+#line 431 "itareg.ctr"
+ if(itadmin_register_check_user_name(dd_n)) {
+ if(dk3sto_it_find_like(job->i_pa, (void *)dd_n, 1)) {
+ /* ERROR: Duplicate entry! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 184, 185, dd_n);
+ } else {
+ bu = NULL;
+ vl = NULL;
+ sp = NULL;
+ if(itadmin_register_check_user_name(sp_s)) {
+ sp = (itadmin_speed *)dk3sto_it_find_like(
+ job->i_sp, (void *)sp_s, 1
+ );
+ if(!(sp)) {
+ /* WARNING: Inconsistency, no such speed! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 186, 187, sp_s);
+ }
+ }
+ if(itadmin_register_check_user_name(vl_s)) {
+ vl = (itadmin_vlan *)dk3sto_it_find_like(
+ job->i_vl, (void *)vl_s, 1
+ );
+ if(!(vl)) {
+ /* WARNING: Inconsistency, no such VLAN! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 188, 189, vl_s);
+ }
+ }
+ if(itadmin_register_check_user_name(gb_s)) {
+ bu = (itadmin_building *)dk3sto_it_find_like(
+ job->i_bu, (void *)gb_s, 1
+ );
+ if(!(bu)) {
+ /* WARNING: Inconsistency, no such building! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 190, 191, gb_s);
+ }
+ }
+ pa = itadmin_mem_connect_new(job, dd_n, dd_p, dd_r, sp, vl, bu);
+ if(pa) {
+ if(dk3sto_add(job->s_pa, (void *)pa)) {
+ back = 1;
+ } else {
+ itadmin_mem_connect_del((void *)pa);
+ }
+ }
+ }
+ } else {
+ back = 1;
+ }
+
+#line 478 "itareg.ctr"
+ return back;
+}
+
+
+
+int
+itadmin_register_network(
+ itadmin_job *job,
+ char const *nw_ip,
+ char const *nw_ma,
+ char const *nw_gw,
+ char const *nw_bc,
+ char const *vl_s
+)
+{
+ char buffer[128];
+ itadmin_vlan *vl;
+ itadmin_network *nw;
+ unsigned long ip;
+ unsigned long ma;
+ unsigned long gw;
+ unsigned long bc;
+ int back = 0;
+
+
+#line 502 "itareg.ctr"
+ if(itadmin_register_check_ip(nw_ip)) {
+ if(dk3enc_c8_ipaddr_to_ul_app(nw_ip, &ip, job->app)) {
+ back = 1;
+ if(itadmin_register_check_ip(nw_ma)) {
+ if(!dk3enc_c8_ipaddr_to_ul_app(nw_ma, &ma, job->app)) {
+ back = 0;
+ /* ERROR: Failed to convert net mask! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 192, 193, nw_ma);
+ }
+ } else {
+ /* WARNING: Using default mask 255.255.255.0! */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 194);
+ ma = 0xFFFFFF00UL;
+ }
+ if(back) {
+ if(itadmin_register_check_ip(nw_gw)) {
+ if(!dk3enc_c8_ipaddr_to_ul_app(nw_gw, &gw, job->app)) {
+ back = 0;
+ /* ERROR: Failed to convert gateway! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 195, 196, nw_gw);
+ }
+ } else {
+ /* WARNING: Using default gateway ip+1! */
+ gw = ip + 1UL;
+ itadmin_tool_ip_to_buffer(buffer, gw);
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 197, 198, buffer);
+ }
+ if(back) {
+ if(itadmin_register_check_ip(nw_bc)) {
+ if(!dk3enc_c8_ipaddr_to_ul_app(nw_bc, &bc, job->app)) {
+ back = 0;
+ /* ERROR: Failed to convert broadcast address! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 199, 200, nw_bc);
+ }
+ } else {
+ bc = (ip | (~(ip & ma)));
+ }
+ if(back) {
+ vl = NULL;
+ if(itadmin_register_check_user_name(vl_s)) {
+ vl = (itadmin_vlan *)dk3sto_it_find_like(
+ job->i_vl, (void *)vl_s, 1
+ );
+ if(!(vl)) {
+ back = 0;
+ /* ERROR: No such VLAN! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 188, 189, vl_s);
+ }
+ }
+ if(back) {
+ if(dk3sto_it_find_like(job->i_nw, (void *)(&ip), 1)) {
+ back = 0;
+ /* ERROR: Duplicate entry! */
+ itadmin_tool_ip_to_buffer(buffer, ip);
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 201, 202, buffer);
+ } else {
+ nw = itadmin_mem_network_new(job, ip, ma, gw, bc, vl);
+ if(nw) {
+ if(dk3sto_add(job->s_nw, (void *)nw)) {
+ if(itadmin_job_do_dhcp(job)) {
+ if(vl) {
+ if(vl->s_nw) {
+ if(!dk3sto_add(vl->s_nw, (void *)nw)) {
+ back = 0;
+ /* ERROR: Failed to create backward reference! */
+ }
+ } else {
+ back = 0;
+ /* ERROR: Storage not available! */
+ }
+ }
+ }
+ } else {
+ back = 0;
+ itadmin_mem_network_del((void *)nw);
+ }
+ } else {
+ back = 0;
+ }
+ }
+ }
+ }
+ }
+ }
+ } else {
+ /* ERROR: Failed to convert IP address! */
+ }
+ } else {
+ /* ERROR: Need IP address! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 203);
+ }
+
+
+#line 594 "itareg.ctr"
+ return back;
+}
+
+
+
+int
+itadmin_register_dhcp_class(itadmin_job *job, char const *dcs, char const *dcl)
+{
+ itadmin_dhcp_class *dc;
+ int back = 0;
+
+
+#line 605 "itareg.ctr"
+ if(itadmin_register_check_user_name(dcs)) {
+ if(dk3sto_it_find_like(job->i_dc, (void *)dcs, 1)) {
+ /* ERROR: Duplicate entry! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 204, 205, dcs);
+ } else {
+ dc = itadmin_mem_dhcp_class_new(job, dcs, dcl);
+ if(dc) {
+ if(dk3sto_add(job->s_dc, (void *)dc)) {
+ back = 1;
+ } else {
+ itadmin_mem_dhcp_class_del(dc);
+ }
+ }
+ }
+ } else {
+ back = 1;
+ }
+
+#line 622 "itareg.ctr"
+ return back;
+}
+
+
+
+int
+itadmin_register_dhcp_group(itadmin_job *job, char const *sn, char const *ln)
+{
+ itadmin_dhcp_group *dg;
+ int back = 0;
+
+
+#line 633 "itareg.ctr"
+ if(itadmin_register_check_user_name(sn)) {
+ if(dk3sto_it_find_like(job->i_dg, (void *)sn, 1)) {
+ /* ERROR: Duplicate entry! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 206, 207, sn);
+ } else {
+ dg = itadmin_mem_dhcp_group_new(job, sn, ln);
+ if(dg) {
+ if(dk3sto_add(job->s_dg, (void *)dg)) {
+ back = 1;
+ } else {
+ itadmin_mem_dhcp_group_del(dg);
+ }
+ }
+ }
+ } else {
+ back = 1;
+ }
+
+#line 650 "itareg.ctr"
+ return back;
+}
+
+
+
+
+
+#line 656 "itareg.ctr"
+
+
+#line 657 "itareg.ctr"
+
+
+#line 658 "itareg.ctr"
+
+
+#line 659 "itareg.ctr"
+
+
+#line 660 "itareg.ctr"
+
+
+#line 661 "itareg.ctr"
+
+
+#line 662 "itareg.ctr"
+
+
+#line 663 "itareg.ctr"
+
+
+#line 664 "itareg.ctr"
+
+
+#line 665 "itareg.ctr"
+
+
+#line 666 "itareg.ctr"
+
+
+#line 667 "itareg.ctr"
+
+
+#line 668 "itareg.ctr"
+
+
+#line 669 "itareg.ctr"
+
+
+#line 670 "itareg.ctr"
+
+
+#line 671 "itareg.ctr"
+
+
+#line 672 "itareg.ctr"
+
+
+#line 673 "itareg.ctr"
+
+
+#line 674 "itareg.ctr"
+
+
+
+int
+itadmin_register_dhcp_pool(
+ itadmin_job *job,
+ char const *ips,
+ char const *ipe,
+ char const *nw,
+ int alu,
+ int dnu,
+ char const *dcn
+)
+{
+ char bu1[128];
+ itadmin_dhcp_pool *dp; /* New pool. */
+ itadmin_network *ian; /* Network. */
+ itadmin_dhcp_class *iac; /* DHCP class. */
+ unsigned long ip4s; /* Start address of pool. */
+ unsigned long ip4e; /* End address of pool. */
+ unsigned long ip4n; /* Network address. */
+ int back = 0;
+ int ok = 1;
+
+
+#line 698 "itareg.ctr"
+ if(itadmin_register_check_ip(ips)) {
+ if(dk3enc_c8_ipaddr_to_ul_app(ips, &ip4s, job->app)) {
+ if(ip4s) {
+
+
+#line 702 "itareg.ctr"
+ if(itadmin_register_check_ip(ipe)) {
+ if(dk3enc_c8_ipaddr_to_ul_app(ipe, &ip4e, job->app)) {
+ if(ip4e) {
+
+
+#line 706 "itareg.ctr"
+ if(itadmin_register_check_ip(nw)) {
+ if(dk3enc_c8_ipaddr_to_ul_app(nw, &ip4n, job->app)) {
+ if((ip4n)) {
+
+
+#line 710 "itareg.ctr"
+ } else {
+ ok = 0;
+
+#line 712 "itareg.ctr"
+ /* ERROR: Invalid network address! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 208, 209, nw);
+ }
+ } else {
+ ok = 0;
+
+#line 717 "itareg.ctr"
+ /* ERROR: Failed to convert network address! */
+ }
+ } else {
+ ip4n = ip4s;
+
+#line 721 "itareg.ctr"
+ }
+ if(ok) {
+
+#line 723 "itareg.ctr"
+ ian = NULL;
+ iac = NULL;
+ if(dcn) {
+ iac = (itadmin_dhcp_class *)dk3sto_it_find_like(
+ job->i_dc, (void *)dcn, 1
+ );
+ if(!(iac)) {
+ ok = 0;
+
+#line 731 "itareg.ctr"
+ /* ERROR: DHCP class not found! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 210, 211, dcn);
+ }
+ }
+ if(ok) {
+ ian = (itadmin_network *)dk3sto_it_find_like(
+ job->i_nw, &ip4n, 1
+ );
+ if(ian) {
+
+
+#line 741 "itareg.ctr"
+ dp = itadmin_mem_dhcp_pool_new(
+ job, ian, iac, ip4s, ip4e, dnu, alu
+ );
+ if(dp) {
+ if(dk3sto_add(job->s_dp, (void *)dp)) {
+ if(ian->s_p) {
+ if(dk3sto_add(ian->s_p, (void *)dp)) {
+ back = 1;
+ } else {
+
+#line 750 "itareg.ctr"
+ /* ERROR: Memory */
+ }
+ } else {
+
+#line 753 "itareg.ctr"
+ /* BUG: We should arrive here only if s_p is set! */
+ }
+ } else {
+
+#line 756 "itareg.ctr"
+ itadmin_mem_dhcp_pool_del(dp);
+ }
+ } else {
+
+#line 759 "itareg.ctr"
+ }
+ } else {
+
+#line 761 "itareg.ctr"
+ /* ERROR: Network not found! */
+ itadmin_tool_ip_to_buffer(bu1, ip4n);
+ itadmin_tool_log_utf8_3(job,DK3_LL_ERROR,212,213,bu1);
+ }
+ } else {
+
+#line 766 "itareg.ctr"
+ }
+ }
+ } else {
+
+#line 769 "itareg.ctr"
+ /* ERROR: Invalid end address! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 214, 215, ips);
+ }
+ } else {
+
+#line 773 "itareg.ctr"
+ /* ERROR: Failed to convert end IP address! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 214, 215, ips);
+
+ }
+ } else {
+
+#line 778 "itareg.ctr"
+ /* ERROR: Need end address! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 216, 217, ips);
+ }
+ } else {
+
+#line 782 "itareg.ctr"
+ /* ERROR: Invalid start address ! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 218, 219, ips);
+ }
+ } else {
+
+#line 786 "itareg.ctr"
+ /* ERROR: Failed to convert start IP address! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 218, 219, ips);
+ }
+ } else {
+
+#line 790 "itareg.ctr"
+ /* ERROR: Need start address! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 220);
+ }
+
+
+#line 794 "itareg.ctr"
+ return back;
+}
+
+
+
+/** Register a host into a DHCP pool.
+ @param job Job structure.
+ @param pool DHCP pool.
+ @param host Host in DHCP pool.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_register_host_in_pool(
+ itadmin_job *job,
+ itadmin_dhcp_pool *pool,
+ itadmin_host *host
+)
+{
+ int back = 0;
+
+
+#line 815 "itareg.ctr"
+ if(!(pool->s_hoi)) {
+ pool->s_hoi = dk3sto_open_app(job->app);
+ if(pool->s_hoi) {
+ dk3sto_set_comp(pool->s_hoi, itadmin_comp_host, 2);
+ }
+ }
+ if(!(pool->i_hoi)) {
+ if(pool->s_hoi) {
+ pool->i_hoi = dk3sto_it_open(pool->s_hoi);
+ }
+ }
+ if((pool->s_hoi) && (pool->i_hoi)) {
+ if(dk3sto_add(pool->s_hoi, (void *)host)) {
+ back = 1;
+ }
+ }
+
+#line 831 "itareg.ctr"
+ return back;
+}
+
+
+
+/** Register host in a network.
+ @param job Job structure.
+ @param net Network for host.
+ @param host Host to register.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_register_host_in_network(
+ itadmin_job *job,
+ itadmin_network *net,
+ itadmin_host *host
+)
+{
+ int back = 0;
+
+
+#line 852 "itareg.ctr"
+ if(!(net->s_hoi)) {
+ net->s_hoi = dk3sto_open_app(job->app);
+ if(net->s_hoi) {
+ dk3sto_set_comp(net->s_hoi, itadmin_comp_host, 2);
+ }
+ }
+ if(!(net->i_hoi)) {
+ if(net->s_hoi) {
+ net->i_hoi = dk3sto_it_open(net->s_hoi);
+ }
+ }
+ if((net->s_hoi) && (net->i_hoi)) {
+ if(dk3sto_add(net->s_hoi, (void *)host)) {
+ back = 1;
+ }
+ }
+
+#line 868 "itareg.ctr"
+ return back;
+}
+
+
+
+/** Register host in a DHCP group.
+ @param job Job structure.
+ @param dgroup DHCP group for host.
+ @param net Network for host.
+ @param host Host to register.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_register_host_in_dhcp_group(
+ itadmin_job *job,
+ itadmin_dhcp_group *dgroup,
+ itadmin_network *net,
+ itadmin_host *host
+)
+{
+ itadmin_dhcp_ginw *ginw;
+ int back = 0;
+
+
+#line 892 "itareg.ctr"
+ if(!(net->s_dg)) {
+ net->s_dg = dk3sto_open_app(job->app);
+ if(net->s_dg) {
+ dk3sto_set_comp(net->s_dg, itadmin_comp_dhcp_ginw, 0);
+ }
+ }
+ if(!(net->i_dg)) {
+ if(net->s_dg) {
+ net->i_dg = dk3sto_it_open(net->s_dg);
+ }
+ }
+ if((net->s_dg) && (net->i_dg)) {
+
+#line 904 "itareg.ctr"
+ ginw = (itadmin_dhcp_ginw *)dk3sto_it_find_like(
+ net->i_dg, (void *)(dgroup->sn), 1
+ );
+ if(!(ginw)) {
+
+#line 908 "itareg.ctr"
+ ginw = itadmin_mem_dhcp_ginw_new(job, dgroup);
+ if(ginw) {
+ if(!dk3sto_add(net->s_dg, (void *)ginw)) {
+ itadmin_mem_dhcp_ginw_del(ginw);
+ ginw = NULL;
+ }
+ }
+ }
+ if(ginw) {
+
+#line 917 "itareg.ctr"
+ if(!(ginw->s_h)) {
+ ginw->s_h = dk3sto_open_app(job->app);
+ if(ginw->s_h) {
+ dk3sto_set_comp(ginw->s_h, itadmin_comp_host, 2);
+ }
+ }
+ if(!(ginw->i_h)) {
+ if(ginw->s_h) {
+ ginw->i_h = dk3sto_it_open(ginw->s_h);
+ }
+ }
+ if((ginw->s_h) && (ginw->i_h)) {
+
+#line 929 "itareg.ctr"
+ if(dk3sto_add(ginw->s_h, (void *)host)) {
+ back = 1;
+ }
+ } else {
+
+#line 933 "itareg.ctr"
+ }
+ } else {
+
+#line 935 "itareg.ctr"
+ }
+ } else {
+
+#line 937 "itareg.ctr"
+ }
+
+#line 938 "itareg.ctr"
+ return back;
+}
+
+
+
+/** Register host in a DHCP class.
+ @param job Job structure.
+ @param dhcpcl DHCP class for host.
+ @param host Host to register in class.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_register_host_in_dhcp_class(
+ itadmin_job *job,
+ itadmin_dhcp_class *dhcpcl,
+ itadmin_host *host
+)
+{
+ int back = 0;
+
+
+#line 959 "itareg.ctr"
+ if(!(dhcpcl->s_ho)) {
+ dhcpcl->s_ho = dk3sto_open_app(job->app);
+ if(dhcpcl->s_ho) {
+ dk3sto_set_comp(dhcpcl->s_ho, itadmin_comp_host, 0);
+ }
+ }
+ if(!(dhcpcl->i_ho)) {
+ if(dhcpcl->s_ho) {
+ dhcpcl->i_ho = dk3sto_it_open(dhcpcl->s_ho);
+ }
+ }
+ if((dhcpcl->s_ho) && (dhcpcl->i_ho)) {
+ if(dk3sto_add(dhcpcl->s_ho, (void *)host)) {
+ back = 1;
+ }
+ }
+
+#line 975 "itareg.ctr"
+ return back;
+}
+
+
+
+/** Register host for a user.
+ @param job Job structure.
+ @param user User responsible for host.
+ @param host Host to register.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_register_host_for_user(
+ itadmin_job *job,
+ itadmin_user *user,
+ itadmin_host *host
+)
+{
+ int back = 0;
+
+
+#line 996 "itareg.ctr"
+ if(!(user->s_ho)) {
+ user->s_ho = dk3sto_open_app(job->app);
+ if(user->s_ho) {
+ dk3sto_set_comp(user->s_ho, itadmin_comp_host, 0);
+ }
+ }
+ if(!(user->i_ho)) {
+ if(user->s_ho) {
+ user->i_ho = dk3sto_it_open(user->s_ho);
+ }
+ }
+ if((user->s_ho) && (user->i_ho)) {
+ if(dk3sto_add(user->s_ho, (void *)host)) {
+ back = 1;
+ }
+ }
+
+#line 1012 "itareg.ctr"
+ return back;
+}
+
+
+int
+itadmin_register_host(
+ itadmin_job *job,
+ char const *co_s,
+ char const *us_s,
+ char const *co_ip,
+ char const *co_mc,
+ char const *ng_s,
+ char const *co_co,
+ char const *dc_s,
+ char const *dg_s,
+ char const *dd_n,
+ char const *gb_s,
+ char const *co_r,
+ char const *co_in,
+ char const *co_sn,
+ char const *co_dd,
+ int co_ff,
+ int co_gu,
+ char const *co_hi,
+ itadmin_date *co_ex,
+ int co_nn,
+ int co_na
+)
+{
+ char maca[32];
+ itadmin_user *user;
+ itadmin_netgroup *ng;
+ itadmin_dhcp_class *dc;
+ itadmin_dhcp_group *dg;
+ itadmin_connect *nc;
+ itadmin_building *bu;
+ itadmin_host *ho;
+ itadmin_network *nw;
+ unsigned long ipv4;
+ int back = 0;
+
+
+#line 1053 "itareg.ctr"
+
+
+#line 1054 "itareg.ctr"
+
+
+#line 1055 "itareg.ctr"
+
+
+#line 1056 "itareg.ctr"
+
+
+#line 1057 "itareg.ctr"
+
+
+#line 1058 "itareg.ctr"
+
+
+#line 1059 "itareg.ctr"
+
+
+#line 1060 "itareg.ctr"
+
+
+#line 1061 "itareg.ctr"
+
+
+#line 1062 "itareg.ctr"
+
+
+#line 1063 "itareg.ctr"
+
+
+#line 1064 "itareg.ctr"
+
+
+#line 1065 "itareg.ctr"
+ if(itadmin_register_check_user_name(co_s)) {
+
+#line 1066 "itareg.ctr"
+ if(dk3sto_it_find_like(job->i_ho, (void *)co_s, 1)) {
+
+#line 1067 "itareg.ctr"
+ /* ERROR: Duplicated entry! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 176, 177, co_s);
+ } else {
+
+#line 1070 "itareg.ctr"
+ user = NULL;
+ ng = NULL;
+ dc = NULL;
+ dg = NULL;
+ nc = NULL;
+ bu = NULL;
+ ipv4 = 0UL;
+ back = 1;
+ if(co_mc) {
+
+#line 1079 "itareg.ctr"
+ if(dk3str_c8_len(co_mc) < sizeof(maca)) {
+
+#line 1080 "itareg.ctr"
+ dk3str_c8_cpy_not_overlapped(maca, co_mc);
+ if(!itadmin_register_correct_mac(job, maca)) {
+ back = 0;
+
+#line 1083 "itareg.ctr"
+ /* ERROR: Illegal MAC address! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 221, 222, co_mc);
+ } else {
+
+#line 1086 "itareg.ctr"
+ }
+ } else {
+
+#line 1088 "itareg.ctr"
+ back = 0;
+ /* ERROR: MAC address too long! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 223, 224, co_mc);
+ }
+ }
+ if(itadmin_register_check_user_name(us_s)) {
+
+#line 1094 "itareg.ctr"
+ user = (itadmin_user *)dk3sto_it_find_like(job->i_us, (void *)us_s, 1);
+ if(!(user)) {
+
+#line 1096 "itareg.ctr"
+ /* ERROR: No such user! */
+ back = 0;
+ itadmin_tool_log_utf8_5(job, DK3_LL_ERROR, 225, 226, 227, co_s, us_s);
+ }
+ }
+ if(itadmin_register_check_user_name(ng_s)) {
+ ng = (itadmin_netgroup *)dk3sto_it_find_like(job->i_ng,(void *)ng_s,1);
+ if(!(ng)) {
+
+#line 1104 "itareg.ctr"
+ /* ERROR: No such netgroup! */
+ back = 0;
+ itadmin_tool_log_utf8_5(job, DK3_LL_ERROR, 228, 229, 230, co_s, ng_s);
+ }
+ }
+ if(itadmin_job_do_dhcp(job)) {
+
+#line 1110 "itareg.ctr"
+ if(itadmin_register_check_user_name(dc_s)) {
+ dc = (itadmin_dhcp_class *)dk3sto_it_find_like(
+ job->i_dc, (void *)dc_s, 1
+ );
+ if(!(dc)) {
+
+#line 1115 "itareg.ctr"
+ /* ERROR: No such DHCP class! */
+ back = 0;
+ itadmin_tool_log_utf8_5(job,DK3_LL_ERROR,231,232,233,co_s,dc_s);
+ }
+ }
+ if(itadmin_register_check_user_name(dg_s)) {
+ dg = (itadmin_dhcp_group *)dk3sto_it_find_like(
+ job->i_dg, (void *)dg_s, 1
+ );
+ if(!(dg)) {
+
+#line 1125 "itareg.ctr"
+ /* ERROR: No such DHCP group! */
+ back = 0;
+ itadmin_tool_log_utf8_5(job,DK3_LL_ERROR,234,235,236,co_s,dg_s);
+ }
+ }
+ }
+ if(itadmin_register_check_user_name(dd_n)) {
+ nc = (itadmin_connect *)dk3sto_it_find_like(job->i_pa, (void *)dd_n, 1);
+ if(!(nc)) {
+
+#line 1134 "itareg.ctr"
+ /* ERROR: No such patch! */
+ back = 0;
+ itadmin_tool_log_utf8_5(job, DK3_LL_ERROR, 237, 238, 239, co_s, dd_n);
+ }
+ }
+ if(itadmin_register_check_user_name(gb_s)) {
+ bu = (itadmin_building *)dk3sto_it_find_like(job->i_bu,(void *)gb_s,1);
+ if(!(bu)) {
+
+#line 1142 "itareg.ctr"
+ /* ERROR: No such building! */
+ back = 0;
+ itadmin_tool_log_utf8_5(job, DK3_LL_ERROR, 240, 241, 242, co_s, gb_s);
+ }
+ }
+ if(itadmin_register_check_ip(co_ip)) {
+ if(!dk3enc_c8_ipaddr_to_ul_app(co_ip, &ipv4, job->app)) {
+ /* ERROR: Failed to convert IP address string to address! */
+ back = 0;
+
+#line 1151 "itareg.ctr"
+ }
+ }
+ if(back) {
+
+#line 1154 "itareg.ctr"
+ back = 0;
+ if((ipv4) && (dc)) {
+ /* WARNING: Both IPv4 address and DHCP class! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_WARNING, 243, 244, co_s);
+ }
+ if((dc) && (!(co_mc))) {
+ /* WARNING: DHCP class but no MAC address! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_WARNING, 245, 246, co_s);
+ }
+ if((!(ipv4)) && (ng)) {
+ /* WARNING: Netgroup but no IP address! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_WARNING, 247, 248, co_s);
+ }
+ if((ng) && (!co_dd)) {
+ /* WARNING: Netgroup but no DNS domain! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_WARNING, 249, 250, co_s);
+ }
+ if((co_ff) && (!(co_dd))) {
+ /* WARNING: FQDN first flag but no DNS domain! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_WARNING, 251, 252, co_s);
+ }
+
+#line 1175 "itareg.ctr"
+ if(co_ex) {
+ if(((job->today).y) || ((job->today).m) || ((job->today).d)) {
+ if((co_ex->y) || (co_ex->m) || (co_ex->d)) {
+ if(itadmin_comp_date(&(job->today), co_ex) > 0) {
+ /* WARNING: Host expired. */
+ itadmin_tool_log_utf8_3(job, DK3_LL_WARNING, 253, 254, co_s);
+ }
+ }
+ }
+ }
+
+
+#line 1186 "itareg.ctr"
+ ho = itadmin_mem_host_new(
+ job, co_ex, co_s, co_co,
+ ((co_mc) ? maca : NULL),
+ co_r, co_in, co_sn, co_hi, co_dd,
+ user, ng, dc, dg, nc, bu, ipv4, co_ff, co_gu, co_nn, co_na
+ );
+ if(ho) {
+
+#line 1193 "itareg.ctr"
+ if(dk3sto_add(job->s_ho, (void *)ho)) {
+
+#line 1194 "itareg.ctr"
+ if(dk3sto_add(job->s_hoi, (void *)ho)) {
+ back = 1;
+
+#line 1196 "itareg.ctr"
+ if(ipv4 == 0x7F000001UL) {
+ job->hlh = 1;
+ }
+ if(itadmin_job_do_dhcp(job)) {
+
+#line 1200 "itareg.ctr"
+ nw = NULL;
+ if(ipv4) {
+ nw = (itadmin_network *)dk3sto_it_find_like(
+ job->i_nw, (void *)(&ipv4), 1
+ );
+ }
+ if(nw) {
+
+#line 1207 "itareg.ctr"
+ ho->dp = (itadmin_dhcp_pool *)dk3sto_it_find_like(
+ job->i_dp, (void *)(&ipv4), 1
+ );
+ if(!(ho->dp)) {
+
+#line 1211 "itareg.ctr"
+ if(dg) {
+
+#line 1212 "itareg.ctr"
+ if(!itadmin_register_host_in_dhcp_group(job,dg,nw,ho)) {
+ back = 0;
+ }
+ } else {
+
+#line 1216 "itareg.ctr"
+ if(!itadmin_register_host_in_network(job, nw, ho)) {
+ back = 0;
+ }
+ }
+ } else {
+
+#line 1221 "itareg.ctr"
+ if(!itadmin_register_host_in_pool(job, ho->dp, ho)) {
+ back = 0;
+ }
+ }
+ } else {
+
+#line 1226 "itareg.ctr"
+ /* Host not in a network. */
+ if(dc) {
+
+#line 1228 "itareg.ctr"
+ if(!itadmin_register_host_in_dhcp_class(job,dc,ho)) {
+ back = 0;
+ }
+ } else {
+
+#line 1232 "itareg.ctr"
+ }
+ }
+ } else {
+
+#line 1235 "itareg.ctr"
+ }
+ if(user) {
+ if(!itadmin_register_host_for_user(job, user, ho)) {
+ back = 0;
+ }
+ }
+ } else {
+
+#line 1242 "itareg.ctr"
+ }
+ } else {
+
+#line 1244 "itareg.ctr"
+ itadmin_mem_host_del(ho);
+ }
+ } else {
+
+#line 1247 "itareg.ctr"
+ /* ERROR: Memory! */
+ }
+ }
+ }
+ } else {
+
+#line 1252 "itareg.ctr"
+ /* ERROR: Computer name! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 255);
+ }
+
+
+#line 1256 "itareg.ctr"
+ return back;
+}
+
+
+
+int
+itadmin_register_alias(itadmin_job *job, char const *al, char const *rn)
+{
+ itadmin_host *host;
+ char const *nn;
+ int back = 0;
+
+
+#line 1268 "itareg.ctr"
+ if((job) && (al) && (rn)) {
+ host = (itadmin_host *)dk3sto_it_find_like(job->i_ho, (void *)rn, 1);
+ if(host) {
+ if(!(host->s_al)) {
+ host->s_al = dk3sto_open_app(job->app);
+ if(host->s_al) {
+ dk3sto_set_comp(host->s_al, itadmin_comp_string, 0);
+ }
+ }
+ if(!(host->i_al)) {
+ if(host->s_al) {
+ host->i_al = dk3sto_it_open(host->s_al);
+ }
+ }
+ if((host->s_al) && (host->i_al)) {
+ nn = dk3str_c8_dup_app(al, job->app);
+ if(nn) {
+ if(dk3sto_add(host->s_al, (void *)nn)) {
+ back = 1;
+ } else {
+ dk3_delete(nn);
+ }
+ } else {
+ /* ERROR: Memory! */
+ }
+ } else {
+ /* ERROR: Memory! */
+ }
+ } else {
+ /* ERROR: No such host rn! */
+ itadmin_tool_log_utf8_5(job, DK3_LL_ERROR, 256, 257, 258, al, rn);
+ }
+ }
+
+#line 1301 "itareg.ctr"
+ return back;
+}
+
+
+
+int
+itadmin_register_dhcp_option(
+ itadmin_job *job,
+ char const *sct,
+ char const *scn,
+ char const *k,
+ char const *v,
+ long pk
+)
+{
+ char buffer[128];
+ itadmin_dhcp_option *no;
+ itadmin_vlan *vl;
+ itadmin_network *nw;
+ itadmin_dhcp_group *dg;
+ itadmin_dhcp_pool *dp;
+ itadmin_host *ho;
+ unsigned long ipv4 = 0UL;
+ int scope;
+ int back = 0;
+
+
+#line 1327 "itareg.ctr"
+
+
+#line 1328 "itareg.ctr"
+
+
+#line 1329 "itareg.ctr"
+
+
+#line 1330 "itareg.ctr"
+
+
+#line 1331 "itareg.ctr"
+ if((job) && (sct) && (k)) {
+ scope = dk3str_c8_array_index(itadmin_register_scope_type_names, sct, 0);
+ switch(scope) {
+ case 0: {
+
+#line 1335 "itareg.ctr"
+ if((job->s_do) && (job->i_do)) {
+ no = itadmin_mem_dhcp_option_new(job, k, v, pk);
+ if(no) {
+ if(dk3sto_add(job->s_do, (void *)no)) {
+ back = 1;
+ } else {
+ itadmin_mem_dhcp_option_del((void *)no);
+ }
+ } else {
+ }
+ } else {
+ /* BUG: Should be set during itamin_job_up()! */
+ }
+ } break;
+ case 1: {
+
+#line 1350 "itareg.ctr"
+ vl = NULL;
+ if(scn) {
+ vl = (itadmin_vlan *)dk3sto_it_find_like(
+ job->i_vl, (void *)scn, 1
+ );
+ }
+ if(vl) {
+ if(!(vl->s_do)) {
+ vl->s_do = dk3sto_open_app(job->app);
+ if(vl->s_do) {
+ dk3sto_set_comp(vl->s_do, itadmin_comp_dhcp_option, 0);
+ }
+ }
+ if(!(vl->i_do)) {
+ if(vl->s_do) {
+ vl->i_do = dk3sto_it_open(vl->s_do);
+ }
+ }
+ if((vl->s_do) && (vl->i_do)) {
+ no = itadmin_mem_dhcp_option_new(job, k, v, pk);
+ if(no) {
+ if(dk3sto_add(vl->s_do, (void *)no)) {
+ back = 1;
+ } else {
+ itadmin_mem_dhcp_option_del((void *)no);
+ }
+ } else {
+ }
+ }
+ } else {
+ /* ERROR: No such VLAN! */
+ itadmin_tool_log_pk_5(job, DK3_LL_ERROR, 259, 260, 261, pk, scn);
+ }
+ } break;
+ case 2: {
+
+#line 1385 "itareg.ctr"
+ nw = NULL;
+ if(scn) {
+ if(dk3enc_c8_ipaddr_to_ul_app(scn, &ipv4, job->app)) {
+ nw = (itadmin_network *)dk3sto_it_find_like(
+ job->i_nw, (void *)(&ipv4), 1
+ );
+ }
+ }
+ if(nw) {
+ if(!(nw->s_do)) {
+ nw->s_do = dk3sto_open_app(job->app);
+ if(nw->s_do) {
+ dk3sto_set_comp(nw->s_do, itadmin_comp_dhcp_option, 0);
+ }
+ }
+ if(!(nw->i_do)) {
+ if(nw->s_do) {
+ nw->i_do = dk3sto_it_open(nw->s_do);
+ }
+ }
+ if((nw->s_do) && (nw->i_do)) {
+ no = itadmin_mem_dhcp_option_new(job, k, v, pk);
+ if(no) {
+ if(dk3sto_add(nw->s_do, (void *)no)) {
+ back = 1;
+ } else {
+ itadmin_mem_dhcp_option_del((void *)no);
+ }
+ } else {
+ }
+ }
+ } else {
+ /* ERROR: No such network! */
+ itadmin_tool_ip_to_buffer(buffer, ipv4);
+ itadmin_tool_log_pk_5(job,DK3_LL_ERROR,262,263,264,pk,buffer);
+ }
+ } break;
+ case 3: {
+
+#line 1423 "itareg.ctr"
+ dg = NULL;
+ if(scn) {
+ dg = (itadmin_dhcp_group *)dk3sto_it_find_like(
+ job->i_dg, (void *)scn, 1
+ );
+ }
+ if(dg) {
+ if(!(dg->s_do)) {
+ dg->s_do = dk3sto_open_app(job->app);
+ if(dg->s_do) {
+ dk3sto_set_comp(dg->s_do, itadmin_comp_dhcp_option, 0);
+ }
+ }
+ if(!(dg->i_do)) {
+ if(dg->s_do) {
+ dg->i_do = dk3sto_it_open(dg->s_do);
+ }
+ }
+ if((dg->s_do) && (dg->i_do)) {
+ no = itadmin_mem_dhcp_option_new(job, k, v, pk);
+ if(no) {
+ if(dk3sto_add(dg->s_do, (void *)no)) {
+ back = 1;
+ } else {
+ itadmin_mem_dhcp_option_del((void *)no);
+ }
+ } else {
+ }
+ }
+ } else {
+ /* ERROR: No such DHCP group! */
+ itadmin_tool_log_pk_5(job, DK3_LL_ERROR, 265, 266, 267, pk, scn);
+ }
+ } break;
+ case 4: {
+
+#line 1458 "itareg.ctr"
+ dp = NULL;
+ if(scn) {
+ if(dk3enc_c8_ipaddr_to_ul_app(scn, &ipv4, job->app)) {
+ dp = (itadmin_dhcp_pool *)dk3sto_it_find_like(
+ job->i_dp, (void *)(&ipv4), 1
+ );
+ }
+ }
+ if(dp) {
+ if(!(dp->s_do)) {
+ dp->s_do = dk3sto_open_app(job->app);
+ if(dp->s_do) {
+ dk3sto_set_comp(dp->s_do, itadmin_comp_dhcp_option, 0);
+ }
+ }
+ if(!(dp->i_do)) {
+ if(dp->s_do) {
+ dp->i_do = dk3sto_it_open(dp->s_do);
+ }
+ }
+ if((dp->s_do) && (dp->i_do)) {
+ no = itadmin_mem_dhcp_option_new(job, k, v, pk);
+ if(no) {
+ if(dk3sto_add(dp->s_do, (void *)no)) {
+ back = 1;
+ } else {
+ itadmin_mem_dhcp_option_del((void *)no);
+ }
+ } else {
+ }
+ }
+ } else {
+ /* ERROR: No such DHCP pool! */
+ itadmin_tool_ip_to_buffer(buffer, ipv4);
+ itadmin_tool_log_pk_5(job,DK3_LL_ERROR,268,269,270,pk,buffer);
+ }
+ } break;
+ case 5: {
+
+#line 1496 "itareg.ctr"
+ ho = NULL;
+ if(scn) {
+ ho = (itadmin_host *)dk3sto_it_find_like(
+ job->i_ho, (void *)scn, 1
+ );
+ }
+ if(ho) {
+ if(!(ho->s_do)) {
+ ho->s_do = dk3sto_open_app(job->app);
+ if(ho->s_do) {
+ dk3sto_set_comp(ho->s_do, itadmin_comp_dhcp_option, 0);
+ }
+ }
+ if(!(ho->i_do)) {
+ if(ho->s_do) {
+ ho->i_do = dk3sto_it_open(ho->s_do);
+ }
+ }
+ if((ho->s_do) && (ho->i_do)) {
+ no = itadmin_mem_dhcp_option_new(job, k, v, pk);
+ if(no) {
+ if(dk3sto_add(ho->s_do, (void *)no)) {
+ back = 1;
+ } else {
+ itadmin_mem_dhcp_option_del((void *)no);
+ }
+ } else {
+ }
+ }
+ } else {
+ /* ERROR: No such host! */
+ itadmin_tool_log_pk_5(job, DK3_LL_ERROR, 271, 272, 273, pk, scn);
+ }
+ } break;
+ default: {
+ /* ERROR: Unknown scope type name! */
+ itadmin_tool_log_pk_5(job, DK3_LL_ERROR, 274, 275, 276, pk, sct);
+ } break;
+ }
+ } else {
+ /* ERROR: Incomplete arguments! */
+ }
+
+#line 1538 "itareg.ctr"
+ return back;
+}
+
+
+
+int
+itadmin_register_swman( itadmin_job *job, char const *sm_s, char const *sm_l)
+{
+ itadmin_swman *sm;
+ int back = 0;
+
+
+#line 1549 "itareg.ctr"
+ if(itadmin_register_check_user_name(sm_s)) {
+
+#line 1550 "itareg.ctr"
+ if(dk3sto_it_find_like(job->i_sm, (void *)sm_s, 1)) {
+
+#line 1551 "itareg.ctr"
+ /* ERROR: Duplicated entry! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 178, 179, sm_s);
+ } else {
+ sm = itadmin_mem_sw_man_new(job, sm_s, sm_l);
+ if(sm) {
+ if(dk3sto_add(job->s_sm, (void *)sm)) {
+ back = 1;
+ } else {
+ itadmin_mem_sw_man_del((void *)sm);
+ }
+ }
+ }
+ } else {
+ /* ERROR: Manufacturer name! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 303, 304, sm_s);
+ }
+
+#line 1567 "itareg.ctr"
+ return back;
+}
+
+
+
+int
+itadmin_register_swprod(
+ itadmin_job *job,
+ char const *sw_s,
+ char const *sw_l,
+ char const *sm_s
+)
+{
+ itadmin_swprod *sp;
+ itadmin_swman *sm;
+ int back = 0;
+ if(itadmin_register_check_user_name(sw_s)) {
+ if(dk3sto_it_find_like(job->i_sw, (void *)sw_s, 1)) {
+ /* ERROR: Duplicate entry! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 277, 278, sw_s);
+ } else {
+ sm = NULL;
+ if(sm_s) {
+ sm = (itadmin_swman *)dk3sto_it_find_like(job->i_sm, (void *)sm_s, 1);
+ if(!(sm)) {
+ /* WARNING: Failed to find software manufacturer! */
+ itadmin_tool_log_utf8_5(job, DK3_LL_ERROR, 279, 280, 281, sw_s, sm_s);
+ }
+ }
+ sp = itadmin_mem_swprod_new(job, sw_s, sw_l, sm);
+ if(sp) {
+ if(dk3sto_add(job->s_sw, (void *)sp)) {
+ back = 1;
+ } else {
+ itadmin_mem_software_del((void *)sp);
+ }
+ }
+ }
+ } else {
+ /* ERROR: Illegal software product name! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 305, 306, sw_s);
+ }
+ return back;
+}
+
+
+
+int
+itadmin_register_lictype(
+ itadmin_job *job,
+ char const *lt_s,
+ char const *lt_l,
+ int nl
+)
+{
+ itadmin_lictype *lt;
+ int back = 0;
+ if(itadmin_register_check_user_name(lt_s)) {
+ if(dk3sto_it_find_like(job->i_lt, (void *)lt_s, 1)) {
+ /* ERROR: Duplicate entry! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 282, 283, lt_s);
+ } else {
+ lt = itadmin_mem_lictype_new(job, lt_s, lt_l, nl);
+ if(lt) {
+ if(dk3sto_add(job->s_lt, (void *)lt)) {
+ back = 1;
+ } else {
+ itadmin_mem_lic_type_del((void *)lt);
+ }
+ }
+ }
+ } else {
+ /* ERROR: Illegal license type name */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 307, 308, lt_s);
+ }
+ return back;
+}
+
+
+
+/** Register a license assigned to a user.
+ @param job Job structure.
+ @param us User.
+ @param li New license to register.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_register_license_to_user(
+ itadmin_job *job,
+ itadmin_user *us,
+ itadmin_license *li
+)
+{
+ int back = 0;
+ if(!(us->s_li)) {
+ us->s_li = dk3sto_open_app(job->app);
+ if(us->s_li) {
+ dk3sto_set_comp(us->s_li, itadmin_comp_license, 2);
+ }
+ }
+ if(!(us->i_li)) {
+ if(us->s_li) {
+ us->i_li = dk3sto_it_open(us->s_li);
+ }
+ }
+ if((us->s_li) && (us->i_li)) {
+ if(dk3sto_add(us->s_li, (void *)li)) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Register a license used on a computer.
+ @param job Job structure.
+ @param co Computer on which the license is used.
+ @param li License to register.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_register_license_to_host(
+ itadmin_job *job,
+ itadmin_host *co,
+ itadmin_license *li
+)
+{
+ int back = 0;
+ if(!(co->s_li)) {
+ co->s_li = dk3sto_open_app(job->app);
+ if(co->s_li) {
+ dk3sto_set_comp(co->s_li, itadmin_comp_license, 2);
+ }
+ }
+ if(!(co->i_li)) {
+ if(co->s_li) {
+ co->i_li = dk3sto_it_open(co->s_li);
+ }
+ }
+ if((co->s_li) && (co->i_li)) {
+ if(dk3sto_add(co->s_li, (void *)li)) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Register an unused license (a license not assigned to
+ any user or computer).
+ @param job Job structure.
+ @param li License to register.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_register_unused_license(
+ itadmin_job *job,
+ itadmin_license *li
+)
+{
+ int back = 0;
+ if(dk3sto_add(job->s_lf, (void *)li)) {
+ back = 1;
+ }
+ return back;
+}
+
+
+
+int
+itadmin_register_license(
+ itadmin_job *job,
+ unsigned long pk,
+ char const *li_on,
+ char const *sw_s,
+ char const *us_s,
+ char const *co_s,
+ char const *lt_s,
+ char const *li_no,
+ char const *sr_s,
+ itadmin_date *li_dd,
+ char const *li_nd,
+ itadmin_date *li_di,
+ char const *li_ni
+)
+{
+ itadmin_swprod *sp;
+ itadmin_lictype *lt;
+ itadmin_user *us;
+ itadmin_host *co;
+ itadmin_license *li;
+ int back = 0;
+ if(itadmin_register_check_user_name(sw_s)) {
+ if(dk3sto_it_find_like(job->i_lc, (void *)(&pk), 1)) {
+ /* ERROR: Duplicate entry */
+ itadmin_tool_log_pk_3(job, DK3_LL_ERROR, 284, 285, pk);
+ } else {
+ sp = NULL; lt = NULL; us = NULL; co = NULL;
+ sp = (itadmin_swprod *)dk3sto_it_find_like(job->i_sw, (void *)sw_s, 1);
+ if(sp) {
+ back = 1;
+ if(us_s) {
+ if(itadmin_register_check_user_name(us_s)) {
+ us =
+ (itadmin_user *)dk3sto_it_find_like(job->i_us, (void *)us_s, 1);
+ if(!(us)) {
+ back = 0;
+ /* ERROR: User not found! */
+ itadmin_tool_log_pk_5(job,DK3_LL_ERROR,286,287,288,pk,us_s);
+ }
+ }
+ }
+ if(co_s) {
+ if(itadmin_register_check_user_name(co_s)) {
+ co =
+ (itadmin_host *)dk3sto_it_find_like(job->i_ho, (void *)co_s, 1);
+ if(!(co)) {
+ back = 0;
+ /* ERROR: Computer not found! */
+ itadmin_tool_log_pk_5(job,DK3_LL_ERROR,289,290,291,pk,co_s);
+ }
+ }
+ }
+ if(lt_s) {
+ if(itadmin_register_check_user_name(lt_s)) {
+ lt =
+ (itadmin_lictype *)dk3sto_it_find_like(job->i_lt,(void *)lt_s,1);
+ if(!(lt)) {
+ back = 0;
+ /* ERROR: License type not found! */
+ itadmin_tool_log_pk_5(job,DK3_LL_ERROR,292,293,294,pk,lt_s);
+ }
+ }
+ }
+ if(back) {
+ back = 0;
+ li = itadmin_mem_license_new(
+ job, pk, li_on, li_no, li_dd, li_nd, li_di, li_ni, sp, lt, us, co
+ );
+ if(li) {
+ if(dk3sto_add(job->s_lc, (void *)li)) {
+ back = 1;
+ if(us) {
+ if(co) {
+ if(itadmin_tool_check_same_user(us, co)) {
+ if(!itadmin_register_license_to_host(job, co, li)) {
+ back = 0;
+ }
+ } else {
+ if(!itadmin_register_license_to_host(job, co, li)) {
+ back = 0;
+ }
+ if(!itadmin_register_license_to_user(job, us, li)) {
+ back = 0;
+ }
+ }
+ } else {
+ if(!itadmin_register_license_to_user(job, us, li)) {
+ back = 0;
+ }
+ }
+ } else {
+ if(co) {
+ if(!itadmin_register_license_to_host(job, co, li)) {
+ back = 0;
+ }
+ /* Warning: License assigned to computer, not user */
+ itadmin_tool_log_pk_5(
+ job, DK3_LL_WARNING, 295, 296, 297, pk, co_s
+ );
+ } else {
+ if(!itadmin_register_unused_license(job, li)) {
+ back = 0;
+ }
+ }
+ }
+ } else {
+ itadmin_mem_license_del((void *)li);
+ }
+ }
+ }
+ }
+ }
+ } else {
+ /* ERROR: No software specified! */
+ itadmin_tool_log_pk_3(job, DK3_LL_ERROR, 298, 299, pk);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/itareg.ctr b/support/dktools/itareg.ctr
new file mode 100644
index 0000000000..6dd72164e7
--- /dev/null
+++ b/support/dktools/itareg.ctr
@@ -0,0 +1,1862 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+
+
+
+%% module
+
+
+#include "dk3all.h"
+#include "itadmin.h"
+
+
+
+$!trace-include
+
+
+
+/** Keywords used by the module.
+*/
+static char const * const itadmin_register_c8_kw[] = {
+$!string-table
+#
+# 0: Empty string.
+#
+
+#
+# 1: Minus.
+#
+-
+#
+# 2: Format string for MAC address
+#
+%02x:%02x:%02x:%02x:%02x:%02x
+$!end
+};
+
+
+
+/** Scope type names.
+*/
+char const * const itadmin_register_scope_type_names[] = {
+$!string-table
+# 0
+server
+# 1
+vlan
+# 2
+network
+# 3
+group
+# 4
+pool
+# 5
+host
+$!end
+};
+
+
+
+int
+itadmin_register_check_user_name(char const *sn)
+{
+ int back = 0;
+ $? "+ itadmin_register_check_user_name \"%!8s\"", TR_8STR(sn)
+ if(sn) {
+ if(dk3str_c8_cmp(sn, itadmin_register_c8_kw[0])) {
+ if(dk3str_c8_cmp(sn, itadmin_register_c8_kw[1])) {
+ back = 1;
+ }
+ }
+ } $? "- itadmin_register_check_user_name %d", back
+ return back;
+}
+
+
+
+int
+itadmin_register_check_ip(char const *ip)
+{
+ int back = 0;
+ $? "+ itadmin_register_check_ip \"%!8s\"", TR_8STR(ip)
+ if(ip) {
+ if(dk3str_c8_len(ip) > 0) {
+ back = 1;
+ }
+ } $? "- itadmin_register_check_ip %d", back
+ return back;
+}
+
+
+
+/** Correct a MAC address (Windows notation to normal notation).
+ @param job Job structure.
+ @param mac Text buffer to modify.
+ @return 1 for valid MAC address found, 0 for invalid source text.
+*/
+int
+itadmin_register_correct_mac(itadmin_job *job, char *mac)
+{
+ char *p1;
+ char *p2;
+ int back = 0;
+ int i1;
+ int i2;
+ int i3;
+ int i4;
+ int i5;
+ int i6;
+ $? "+ itadmin_register_correct_mac \"%!8s\"", mac
+ p1 = mac;
+ while(*p1) {
+ if(*p1 == '-') { *p1 = ':'; }
+ p1++;
+ }
+ p1 = dk3str_c8_chr(mac, ':');
+ if(p1) {
+ *(p1++) = '\0';
+ if(sscanf(mac, "%x", &i1) == 1) {
+ p2 = dk3str_c8_chr(p1, ':');
+ if(p2) {
+ *(p2++) = '\0';
+ if(sscanf(p1, "%x", &i2) == 1) {
+ p1 = dk3str_c8_chr(p2, ':');
+ if(p1) {
+ *(p1++) = '\0';
+ if(sscanf(p2, "%x", &i3) == 1) {
+ p2 = dk3str_c8_chr(p1, ':');
+ if(p2) {
+ *(p2++) = '\0';
+ if(sscanf(p1, "%x", &i4) == 1) {
+ p1 = dk3str_c8_chr(p2, ':');
+ if(p1) {
+ *(p1++) = '\0';
+ if(sscanf(p2, "%x", &i5) == 1) {
+ if(sscanf(p1, "%x", &i6) == 1) {
+ if((i1 >= 0) && (i1 < 256)) {
+ if((i2 >= 0) && (i2 < 256)) {
+ if((i3 >= 0) && (i3 < 256)) {
+ if((i4 >= 0) && (i4 < 256)) {
+ if((i5 >= 0) && (i5 < 256)) {
+ if((i6 >= 0) && (i6 < 256)) {
+ sprintf(
+ mac,
+ itadmin_register_c8_kw[2],
+ i1, i2, i3, i4, i5, i6
+ );
+ back = 1;
+ p1 = mac;
+ while(*p1) {
+ switch(*p1) {
+ case 'a': {
+ *p1 = 'A';
+ } break;
+ case 'b': {
+ *p1 = 'B';
+ } break;
+ case 'c': {
+ *p1 = 'C';
+ } break;
+ case 'd': {
+ *p1 = 'D';
+ } break;
+ case 'e': {
+ *p1 = 'E';
+ } break;
+ case 'f': {
+ *p1 = 'F';
+ } break;
+ }
+ p1++;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } $? "- itadmin_register_correct_mac %d \"%!8s\"", back, mac
+ return back;
+}
+
+
+
+int
+itadmin_register_user(
+ itadmin_job *job,
+ char const *us_s,
+ char const *us_t,
+ char const *us_sn,
+ char const *us_fn,
+ char const *us_em,
+ char const *us_ko,
+ char const *us_se
+)
+{
+ itadmin_user *nu;
+ int back = 0;
+ $? "+ itadmin_register_user"
+ $? "+ us_s = \"%!8s\"", TR_8STR(us_s)
+ $? "+ us_t = \"%!8s\"", TR_8STR(us_t)
+ $? "+ us_sn = \"%!8s\"", TR_8STR(us_sn)
+ $? "+ us_fn = \"%!8s\"", TR_8STR(us_fn)
+ $? "+ us_em = \"%!8s\"", TR_8STR(us_em)
+ $? "+ us_ko = \"%!8s\"", TR_8STR(us_ko)
+ $? "+ us_se = \"%!8s\"", TR_8STR(us_se)
+ nu = itadmin_mem_user_new(job, us_s, us_t, us_sn, us_fn, us_em, us_ko, us_se);
+ if(itadmin_register_check_user_name(us_s)) {
+ if(dk3sto_it_find_like(job->i_us, (void *)us_s, 1)) {
+ /* ERROR: Duplicated entry! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 168, 169, us_s);
+ } else {
+ if(nu) {
+ if(dk3sto_add(job->s_us, (void *)nu)) {
+ if(dk3sto_add(job->s_usn, (void *)nu)) {
+ back = 1;
+ }
+ } else {
+ itadmin_mem_user_del((void *)nu);
+ }
+ }
+ }
+ } else {
+ back = 1;
+ }
+ $? "- itadmin_register_user %d", back
+ return back;
+}
+
+
+
+int
+itadmin_register_building(
+ itadmin_job *job,
+ char const *gb_s,
+ char const *gb_l,
+ char const *gb_a1,
+ char const *gb_a2,
+ char const *gb_a3,
+ char const *gb_a4,
+ char const *gb_plz,
+ char const *gb_ort
+)
+{
+ itadmin_building *nb;
+ int back = 0;
+ $? "+ itadmin_register_building \"%!8s\"", TR_8STR(gb_s)
+ if(itadmin_register_check_user_name(gb_s)) { $? ". name"
+ if(dk3sto_it_find_like(job->i_bu, (void *)gb_s, 1)) { $? "! dupli"
+ /* ERROR: Duplicated entry! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 170, 171, gb_s);
+ } else { $? ". add"
+ nb = itadmin_mem_building_new(
+ job,
+ gb_s, gb_l, gb_a1, gb_a2, gb_a3, gb_a4, gb_plz, gb_ort
+ );
+ if(nb) { $? ". nb"
+ if(dk3sto_add(job->s_bu, (void *)nb)) { $? ". ok"
+ back = 1;
+ } else { $? "! dk3stoadd"
+ itadmin_mem_building_del((void *)nb);
+ }
+ } else { $? "! nb"
+ }
+ }
+ } else { $? ". no save"
+ back = 1;
+ } $? "- itadmin_register_building %d", back
+ return back;
+}
+
+
+
+int
+itadmin_register_speed(itadmin_job *job, char const *sn, char const *ln)
+{
+ itadmin_speed *sp;
+ int back = 0;
+ $? "+ itadmin_register_speed \"%!8s\"", TR_8STR(sn)
+ if(itadmin_register_check_user_name(sn)) {
+ if(dk3sto_it_find_like(job->i_sp, (void *)sn, 1)) {
+ /* ERROR: Duplicated entry! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 172, 173, sn);
+ } else {
+ sp = itadmin_mem_speed_new(job, sn, ln);
+ if(sp) {
+ if(dk3sto_add(job->s_sp, (void *)sp)) {
+ back = 1;
+ } else {
+ itadmin_mem_speed_del((void *)sp);
+ }
+ }
+ }
+ } else {
+ back = 1;
+ } $? "- itadmin_register_speed %d", back
+ return back;
+}
+
+
+
+int
+itadmin_register_vlan(itadmin_job *job, char const *vl_s, char const *vl_l)
+{
+ itadmin_vlan *vl;
+ int back = 0;
+ $? "+ itadmin_register_vlan \"%!8s\"", TR_8STR(vl_s)
+ if(itadmin_register_check_user_name(vl_s)) {
+ if(dk3sto_it_find_like(job->i_vl, (void *)vl_s, 1)) {
+ /* ERROR: Duplicated entry! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 174, 175, vl_s);
+ } else {
+ vl = itadmin_mem_vlan_new(job, vl_s, vl_l);
+ if(vl) {
+ if(dk3sto_add(job->s_vl, (void *)vl)) {
+ back = 1;
+ } else {
+ itadmin_mem_vlan_del((void *)vl);
+ }
+ }
+ }
+ } else {
+ back = 1;
+ } $? "- itadmin_register_vlan %d", back
+ return back;
+}
+
+
+
+int
+itadmin_register_netgroup(itadmin_job *job, char const *ng_s, char const *ng_l)
+{
+ itadmin_netgroup *ng;
+ int back = 0;
+ if(itadmin_register_check_user_name(ng_s)) {
+ if(dk3sto_it_find_like(job->i_ng, (void *)ng_s, 1)) {
+ /* ERROR: Duplicate entry! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 180, 181, ng_s);
+ } else {
+ ng = itadmin_mem_netgroup_new(job, ng_s, ng_l);
+ if(ng) {
+ if(dk3sto_add(job->s_ng, (void *)ng)) {
+ back = 1;
+ } else {
+ itadmin_mem_netgroup_del((void *)ng);
+ }
+ }
+ }
+ } else {
+ back = 1;
+ }
+ return back;
+}
+
+
+
+int
+itadmin_register_ngdep(itadmin_job *job, char const *pgn, char const *cgn)
+{
+ itadmin_ngdep *nd;
+ itadmin_netgroup *pg;
+ itadmin_netgroup *cg;
+ int back = 0;
+ $? "+ itadmin_register_ngdep \"%!8s\" => \"%!8s\"", TR_8STR(pgn), TR_8STR(cgn)
+ if((pgn) && (cgn)) {
+ if(itadmin_register_check_user_name(pgn)) {
+ if(itadmin_register_check_user_name(cgn)) {
+ pg = NULL; cg = NULL;
+ pg = (itadmin_netgroup *)dk3sto_it_find_like(job->i_ng, (void *)pgn, 1);
+ cg = (itadmin_netgroup *)dk3sto_it_find_like(job->i_ng, (void *)cgn, 1);
+ if(!(pg)) {
+ /* WARNING: Netgroup does not yet exist! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 182, 183, pgn);
+ itadmin_register_netgroup(job, pgn, NULL);
+ pg = (itadmin_netgroup *)dk3sto_it_find_like(job->i_ng,(void *)pgn,1);
+ }
+ if(!(cg)) {
+ /* WARNING: Netgroup does not yet exist! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 182, 183, cgn);
+ itadmin_register_netgroup(job, cgn, NULL);
+ cg = (itadmin_netgroup *)dk3sto_it_find_like(job->i_ng,(void *)cgn,1);
+ }
+ if((pg) && (cg)) {
+ nd = itadmin_mem_ngdep_new(job, pg, cg);
+ if(nd) {
+ if(dk3sto_add(job->s_nd, (void *)nd)) {
+ back = 1;
+ } else {
+ itadmin_mem_ngdep_del(nd);
+ }
+ }
+ }
+ }
+ }
+ } $? "- itadmin_register_ngdep %d", back
+ return back;
+}
+
+
+
+int
+itadmin_register_patch(
+ itadmin_job *job,
+ char const *dd_n,
+ char const *sp_s,
+ char const *vl_s,
+ char const *dd_p,
+ char const *gb_s,
+ char const *dd_r
+)
+{
+ itadmin_connect *pa;
+ itadmin_building *bu;
+ itadmin_vlan *vl;
+ itadmin_speed *sp;
+ int back = 0;
+ $? "+ itadmin_register_patch \"%!8s\"", TR_8STR(dd_n)
+ if(itadmin_register_check_user_name(dd_n)) {
+ if(dk3sto_it_find_like(job->i_pa, (void *)dd_n, 1)) {
+ /* ERROR: Duplicate entry! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 184, 185, dd_n);
+ } else {
+ bu = NULL;
+ vl = NULL;
+ sp = NULL;
+ if(itadmin_register_check_user_name(sp_s)) {
+ sp = (itadmin_speed *)dk3sto_it_find_like(
+ job->i_sp, (void *)sp_s, 1
+ );
+ if(!(sp)) {
+ /* WARNING: Inconsistency, no such speed! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 186, 187, sp_s);
+ }
+ }
+ if(itadmin_register_check_user_name(vl_s)) {
+ vl = (itadmin_vlan *)dk3sto_it_find_like(
+ job->i_vl, (void *)vl_s, 1
+ );
+ if(!(vl)) {
+ /* WARNING: Inconsistency, no such VLAN! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 188, 189, vl_s);
+ }
+ }
+ if(itadmin_register_check_user_name(gb_s)) {
+ bu = (itadmin_building *)dk3sto_it_find_like(
+ job->i_bu, (void *)gb_s, 1
+ );
+ if(!(bu)) {
+ /* WARNING: Inconsistency, no such building! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 190, 191, gb_s);
+ }
+ }
+ pa = itadmin_mem_connect_new(job, dd_n, dd_p, dd_r, sp, vl, bu);
+ if(pa) {
+ if(dk3sto_add(job->s_pa, (void *)pa)) {
+ back = 1;
+ } else {
+ itadmin_mem_connect_del((void *)pa);
+ }
+ }
+ }
+ } else {
+ back = 1;
+ } $? "- itadmin_register_patch %d", back
+ return back;
+}
+
+
+
+int
+itadmin_register_network(
+ itadmin_job *job,
+ char const *nw_ip,
+ char const *nw_ma,
+ char const *nw_gw,
+ char const *nw_bc,
+ char const *vl_s
+)
+{
+ char buffer[128];
+ itadmin_vlan *vl;
+ itadmin_network *nw;
+ unsigned long ip;
+ unsigned long ma;
+ unsigned long gw;
+ unsigned long bc;
+ int back = 0;
+ $? "+ itadmin_register_network \"%!8s\"", TR_8STR(nw_ip)
+ if(itadmin_register_check_ip(nw_ip)) {
+ if(dk3enc_c8_ipaddr_to_ul_app(nw_ip, &ip, job->app)) {
+ back = 1;
+ if(itadmin_register_check_ip(nw_ma)) {
+ if(!dk3enc_c8_ipaddr_to_ul_app(nw_ma, &ma, job->app)) {
+ back = 0;
+ /* ERROR: Failed to convert net mask! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 192, 193, nw_ma);
+ }
+ } else {
+ /* WARNING: Using default mask 255.255.255.0! */
+ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 194);
+ ma = 0xFFFFFF00UL;
+ }
+ if(back) {
+ if(itadmin_register_check_ip(nw_gw)) {
+ if(!dk3enc_c8_ipaddr_to_ul_app(nw_gw, &gw, job->app)) {
+ back = 0;
+ /* ERROR: Failed to convert gateway! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 195, 196, nw_gw);
+ }
+ } else {
+ /* WARNING: Using default gateway ip+1! */
+ gw = ip + 1UL;
+ itadmin_tool_ip_to_buffer(buffer, gw);
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 197, 198, buffer);
+ }
+ if(back) {
+ if(itadmin_register_check_ip(nw_bc)) {
+ if(!dk3enc_c8_ipaddr_to_ul_app(nw_bc, &bc, job->app)) {
+ back = 0;
+ /* ERROR: Failed to convert broadcast address! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 199, 200, nw_bc);
+ }
+ } else {
+ bc = (ip | (~(ip & ma)));
+ }
+ if(back) {
+ vl = NULL;
+ if(itadmin_register_check_user_name(vl_s)) {
+ vl = (itadmin_vlan *)dk3sto_it_find_like(
+ job->i_vl, (void *)vl_s, 1
+ );
+ if(!(vl)) {
+ back = 0;
+ /* ERROR: No such VLAN! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 188, 189, vl_s);
+ }
+ }
+ if(back) {
+ if(dk3sto_it_find_like(job->i_nw, (void *)(&ip), 1)) {
+ back = 0;
+ /* ERROR: Duplicate entry! */
+ itadmin_tool_ip_to_buffer(buffer, ip);
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 201, 202, buffer);
+ } else {
+ nw = itadmin_mem_network_new(job, ip, ma, gw, bc, vl);
+ if(nw) {
+ if(dk3sto_add(job->s_nw, (void *)nw)) {
+ if(itadmin_job_do_dhcp(job)) {
+ if(vl) {
+ if(vl->s_nw) {
+ if(!dk3sto_add(vl->s_nw, (void *)nw)) {
+ back = 0;
+ /* ERROR: Failed to create backward reference! */
+ }
+ } else {
+ back = 0;
+ /* ERROR: Storage not available! */
+ }
+ }
+ }
+ } else {
+ back = 0;
+ itadmin_mem_network_del((void *)nw);
+ }
+ } else {
+ back = 0;
+ }
+ }
+ }
+ }
+ }
+ }
+ } else {
+ /* ERROR: Failed to convert IP address! */
+ }
+ } else {
+ /* ERROR: Need IP address! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 203);
+ }
+ $? "- itadmin_register_network %d", back
+ return back;
+}
+
+
+
+int
+itadmin_register_dhcp_class(itadmin_job *job, char const *dcs, char const *dcl)
+{
+ itadmin_dhcp_class *dc;
+ int back = 0;
+ $? "+ itadmin_register_dhcp_class \"%!8s\" \"%!8s\"",TR_8STR(dcs),TR_8STR(dcl)
+ if(itadmin_register_check_user_name(dcs)) {
+ if(dk3sto_it_find_like(job->i_dc, (void *)dcs, 1)) {
+ /* ERROR: Duplicate entry! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 204, 205, dcs);
+ } else {
+ dc = itadmin_mem_dhcp_class_new(job, dcs, dcl);
+ if(dc) {
+ if(dk3sto_add(job->s_dc, (void *)dc)) {
+ back = 1;
+ } else {
+ itadmin_mem_dhcp_class_del(dc);
+ }
+ }
+ }
+ } else {
+ back = 1;
+ } $? "- itadmin_register_dhcp_class %d", back
+ return back;
+}
+
+
+
+int
+itadmin_register_dhcp_group(itadmin_job *job, char const *sn, char const *ln)
+{
+ itadmin_dhcp_group *dg;
+ int back = 0;
+ $? "+ itadmin_register_dhcp_group \"%!8s\" \"%!8s\"", TR_8STR(sn), TR_8STR(ln)
+ if(itadmin_register_check_user_name(sn)) {
+ if(dk3sto_it_find_like(job->i_dg, (void *)sn, 1)) {
+ /* ERROR: Duplicate entry! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 206, 207, sn);
+ } else {
+ dg = itadmin_mem_dhcp_group_new(job, sn, ln);
+ if(dg) {
+ if(dk3sto_add(job->s_dg, (void *)dg)) {
+ back = 1;
+ } else {
+ itadmin_mem_dhcp_group_del(dg);
+ }
+ }
+ }
+ } else {
+ back = 1;
+ } $? "- itadmin_register_dhcp_group %d", back
+ return back;
+}
+
+
+
+$!trace-code static
+$!trace-code void
+$!trace-code itadmin_register_report_ip4(char const *s, unsigned long ip)
+$!trace-code {
+$!trace-code FILE *fipo;
+$!trace-code fipo = dktrace_file();
+$!trace-code if(!(fipo)) { fipo = stdout; }
+$!trace-code if(fipo) {
+$!trace-code fprintf(
+$!trace-code fipo,
+$!trace-code "%s %lu.%lu.%lu.%lu\n",
+$!trace-code ((s) ? s : "(NULL)"),
+$!trace-code ((ip >> 24) & 0x000000FFUL),
+$!trace-code ((ip >> 16) & 0x000000FFUL),
+$!trace-code ((ip >> 8) & 0x000000FFUL),
+$!trace-code ( ip & 0x000000FFUL)
+$!trace-code );
+$!trace-code }
+$!trace-code }
+
+
+
+int
+itadmin_register_dhcp_pool(
+ itadmin_job *job,
+ char const *ips,
+ char const *ipe,
+ char const *nw,
+ int alu,
+ int dnu,
+ char const *dcn
+)
+{
+ char bu1[128];
+ itadmin_dhcp_pool *dp; /* New pool. */
+ itadmin_network *ian; /* Network. */
+ itadmin_dhcp_class *iac; /* DHCP class. */
+ unsigned long ip4s; /* Start address of pool. */
+ unsigned long ip4e; /* End address of pool. */
+ unsigned long ip4n; /* Network address. */
+ int back = 0;
+ int ok = 1;
+ $? "+ itadmin_register_dhcp_pool"
+ if(itadmin_register_check_ip(ips)) {
+ if(dk3enc_c8_ipaddr_to_ul_app(ips, &ip4s, job->app)) {
+ if(ip4s) {
+$!trace-code itadmin_register_report_ip4("Start address:", ip4s);
+ if(itadmin_register_check_ip(ipe)) {
+ if(dk3enc_c8_ipaddr_to_ul_app(ipe, &ip4e, job->app)) {
+ if(ip4e) {
+$!trace-code itadmin_register_report_ip4("End address: ", ip4s);
+ if(itadmin_register_check_ip(nw)) {
+ if(dk3enc_c8_ipaddr_to_ul_app(nw, &ip4n, job->app)) {
+ if((ip4n)) {
+$!trace-code itadmin_register_report_ip4("Net address: ", ip4s);
+ } else {
+ ok = 0; $? "! invalid network address"
+ /* ERROR: Invalid network address! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 208, 209, nw);
+ }
+ } else {
+ ok = 0; $? "! failed to convert network address"
+ /* ERROR: Failed to convert network address! */
+ }
+ } else {
+ ip4n = ip4s; $? ". network = start"
+ }
+ if(ok) { $? ". no errors so far"
+ ian = NULL;
+ iac = NULL;
+ if(dcn) {
+ iac = (itadmin_dhcp_class *)dk3sto_it_find_like(
+ job->i_dc, (void *)dcn, 1
+ );
+ if(!(iac)) {
+ ok = 0; $? "! DHCP class not found"
+ /* ERROR: DHCP class not found! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 210, 211, dcn);
+ }
+ }
+ if(ok) {
+ ian = (itadmin_network *)dk3sto_it_find_like(
+ job->i_nw, &ip4n, 1
+ );
+ if(ian) {
+$!trace-code itadmin_register_report_ip4("Net address: ", ian->ip4);
+ dp = itadmin_mem_dhcp_pool_new(
+ job, ian, iac, ip4s, ip4e, dnu, alu
+ );
+ if(dp) {
+ if(dk3sto_add(job->s_dp, (void *)dp)) {
+ if(ian->s_p) {
+ if(dk3sto_add(ian->s_p, (void *)dp)) {
+ back = 1;
+ } else { $? "! memory"
+ /* ERROR: Memory */
+ }
+ } else { $? "! bug"
+ /* BUG: We should arrive here only if s_p is set! */
+ }
+ } else { $? "! failed to add to storage"
+ itadmin_mem_dhcp_pool_del(dp);
+ }
+ } else { $? "! allocation failed"
+ }
+ } else { $? "! network not found"
+ /* ERROR: Network not found! */
+ itadmin_tool_ip_to_buffer(bu1, ip4n);
+ itadmin_tool_log_utf8_3(job,DK3_LL_ERROR,212,213,bu1);
+ }
+ } else { $? "! aborted due to previous errors"
+ }
+ }
+ } else { $? "! invalid end address"
+ /* ERROR: Invalid end address! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 214, 215, ips);
+ }
+ } else { $? "! failed to convert end address"
+ /* ERROR: Failed to convert end IP address! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 214, 215, ips);
+
+ }
+ } else { $? "! end address empty or NULL"
+ /* ERROR: Need end address! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 216, 217, ips);
+ }
+ } else { $? "! invalid start address"
+ /* ERROR: Invalid start address ! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 218, 219, ips);
+ }
+ } else { $? "! failed to convert start address"
+ /* ERROR: Failed to convert start IP address! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 218, 219, ips);
+ }
+ } else { $? "! start address empty or NULL"
+ /* ERROR: Need start address! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 220);
+ }
+ $? "- itadmin_register_dhcp_pool %d", back
+ return back;
+}
+
+
+
+/** Register a host into a DHCP pool.
+ @param job Job structure.
+ @param pool DHCP pool.
+ @param host Host in DHCP pool.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_register_host_in_pool(
+ itadmin_job *job,
+ itadmin_dhcp_pool *pool,
+ itadmin_host *host
+)
+{
+ int back = 0;
+ $? "+ itadmin_register_host_in_pool"
+ if(!(pool->s_hoi)) {
+ pool->s_hoi = dk3sto_open_app(job->app);
+ if(pool->s_hoi) {
+ dk3sto_set_comp(pool->s_hoi, itadmin_comp_host, 2);
+ }
+ }
+ if(!(pool->i_hoi)) {
+ if(pool->s_hoi) {
+ pool->i_hoi = dk3sto_it_open(pool->s_hoi);
+ }
+ }
+ if((pool->s_hoi) && (pool->i_hoi)) {
+ if(dk3sto_add(pool->s_hoi, (void *)host)) {
+ back = 1;
+ }
+ } $? "- itadmin_register_host_in_pool %d", back
+ return back;
+}
+
+
+
+/** Register host in a network.
+ @param job Job structure.
+ @param net Network for host.
+ @param host Host to register.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_register_host_in_network(
+ itadmin_job *job,
+ itadmin_network *net,
+ itadmin_host *host
+)
+{
+ int back = 0;
+ $? "+ itadmin_register_host_in_network"
+ if(!(net->s_hoi)) {
+ net->s_hoi = dk3sto_open_app(job->app);
+ if(net->s_hoi) {
+ dk3sto_set_comp(net->s_hoi, itadmin_comp_host, 2);
+ }
+ }
+ if(!(net->i_hoi)) {
+ if(net->s_hoi) {
+ net->i_hoi = dk3sto_it_open(net->s_hoi);
+ }
+ }
+ if((net->s_hoi) && (net->i_hoi)) {
+ if(dk3sto_add(net->s_hoi, (void *)host)) {
+ back = 1;
+ }
+ } $? "- itadmin_register_host_in_network %d", back
+ return back;
+}
+
+
+
+/** Register host in a DHCP group.
+ @param job Job structure.
+ @param dgroup DHCP group for host.
+ @param net Network for host.
+ @param host Host to register.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_register_host_in_dhcp_group(
+ itadmin_job *job,
+ itadmin_dhcp_group *dgroup,
+ itadmin_network *net,
+ itadmin_host *host
+)
+{
+ itadmin_dhcp_ginw *ginw;
+ int back = 0;
+ $? "+ itadmin_register_host_in_dhcp_group"
+ if(!(net->s_dg)) {
+ net->s_dg = dk3sto_open_app(job->app);
+ if(net->s_dg) {
+ dk3sto_set_comp(net->s_dg, itadmin_comp_dhcp_ginw, 0);
+ }
+ }
+ if(!(net->i_dg)) {
+ if(net->s_dg) {
+ net->i_dg = dk3sto_it_open(net->s_dg);
+ }
+ }
+ if((net->s_dg) && (net->i_dg)) { $? ". storage and iterator"
+ ginw = (itadmin_dhcp_ginw *)dk3sto_it_find_like(
+ net->i_dg, (void *)(dgroup->sn), 1
+ );
+ if(!(ginw)) { $? ". not found"
+ ginw = itadmin_mem_dhcp_ginw_new(job, dgroup);
+ if(ginw) {
+ if(!dk3sto_add(net->s_dg, (void *)ginw)) {
+ itadmin_mem_dhcp_ginw_del(ginw);
+ ginw = NULL;
+ }
+ }
+ }
+ if(ginw) { $? ". ginw"
+ if(!(ginw->s_h)) {
+ ginw->s_h = dk3sto_open_app(job->app);
+ if(ginw->s_h) {
+ dk3sto_set_comp(ginw->s_h, itadmin_comp_host, 2);
+ }
+ }
+ if(!(ginw->i_h)) {
+ if(ginw->s_h) {
+ ginw->i_h = dk3sto_it_open(ginw->s_h);
+ }
+ }
+ if((ginw->s_h) && (ginw->i_h)) { $? ". storage and iterator"
+ if(dk3sto_add(ginw->s_h, (void *)host)) {
+ back = 1;
+ }
+ } else { $? "! storage and iterator"
+ }
+ } else { $? "! ginw"
+ }
+ } else { $? "! storage and iterator"
+ } $? "- itadmin_register_host_in_dhcp_group %d", back
+ return back;
+}
+
+
+
+/** Register host in a DHCP class.
+ @param job Job structure.
+ @param dhcpcl DHCP class for host.
+ @param host Host to register in class.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_register_host_in_dhcp_class(
+ itadmin_job *job,
+ itadmin_dhcp_class *dhcpcl,
+ itadmin_host *host
+)
+{
+ int back = 0;
+ $? "+ itadmin_register_host_in_dhcp_class"
+ if(!(dhcpcl->s_ho)) {
+ dhcpcl->s_ho = dk3sto_open_app(job->app);
+ if(dhcpcl->s_ho) {
+ dk3sto_set_comp(dhcpcl->s_ho, itadmin_comp_host, 0);
+ }
+ }
+ if(!(dhcpcl->i_ho)) {
+ if(dhcpcl->s_ho) {
+ dhcpcl->i_ho = dk3sto_it_open(dhcpcl->s_ho);
+ }
+ }
+ if((dhcpcl->s_ho) && (dhcpcl->i_ho)) {
+ if(dk3sto_add(dhcpcl->s_ho, (void *)host)) {
+ back = 1;
+ }
+ } $? "- itadmin_register_host_in_dhcp_class %d", back
+ return back;
+}
+
+
+
+/** Register host for a user.
+ @param job Job structure.
+ @param user User responsible for host.
+ @param host Host to register.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_register_host_for_user(
+ itadmin_job *job,
+ itadmin_user *user,
+ itadmin_host *host
+)
+{
+ int back = 0;
+ $? "+ itadmin_register_host_for_user"
+ if(!(user->s_ho)) {
+ user->s_ho = dk3sto_open_app(job->app);
+ if(user->s_ho) {
+ dk3sto_set_comp(user->s_ho, itadmin_comp_host, 0);
+ }
+ }
+ if(!(user->i_ho)) {
+ if(user->s_ho) {
+ user->i_ho = dk3sto_it_open(user->s_ho);
+ }
+ }
+ if((user->s_ho) && (user->i_ho)) {
+ if(dk3sto_add(user->s_ho, (void *)host)) {
+ back = 1;
+ }
+ } $? "- itadmin_register_host_for_user %d", back
+ return back;
+}
+
+
+int
+itadmin_register_host(
+ itadmin_job *job,
+ char const *co_s,
+ char const *us_s,
+ char const *co_ip,
+ char const *co_mc,
+ char const *ng_s,
+ char const *co_co,
+ char const *dc_s,
+ char const *dg_s,
+ char const *dd_n,
+ char const *gb_s,
+ char const *co_r,
+ char const *co_in,
+ char const *co_sn,
+ char const *co_dd,
+ int co_ff,
+ int co_gu,
+ char const *co_hi,
+ itadmin_date *co_ex,
+ int co_nn,
+ int co_na
+)
+{
+ char maca[32];
+ itadmin_user *user;
+ itadmin_netgroup *ng;
+ itadmin_dhcp_class *dc;
+ itadmin_dhcp_group *dg;
+ itadmin_connect *nc;
+ itadmin_building *bu;
+ itadmin_host *ho;
+ itadmin_network *nw;
+ unsigned long ipv4;
+ int back = 0;
+ $? "+ itadmin_register_host \"%!8s\"", TR_8STR(co_s)
+ $? ". us_s = \"%!8s\"", TR_8STR(us_s)
+ $? ". co_mc = \"%!8s\"", TR_8STR(co_mc)
+ $? ". ng_s = \"%!8s\"", TR_8STR(ng_s)
+ $? ". co_co = \"%!8s\"", TR_8STR(co_co)
+ $? ". dc_s = \"%!8s\"", TR_8STR(dc_s)
+ $? ". dg_s = \"%!8s\"", TR_8STR(dg_s)
+ $? ". gb_s = \"%!8s\"", TR_8STR(gb_s)
+ $? ". co_r = \"%!8s\"", TR_8STR(co_r)
+ $? ". co_in = \"%!8s\"", TR_8STR(co_in)
+ $? ". co_sn = \"%!8s\"", TR_8STR(co_sn)
+ $? ". co_dd = \"%!8s\"", TR_8STR(co_dd)
+ $? ". co_ip = \"%!8s\"", TR_8STR(co_ip)
+ if(itadmin_register_check_user_name(co_s)) { $? ". computer name"
+ if(dk3sto_it_find_like(job->i_ho, (void *)co_s, 1)) { $? "! duplicated"
+ /* ERROR: Duplicated entry! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 176, 177, co_s);
+ } else { $? ". can add"
+ user = NULL;
+ ng = NULL;
+ dc = NULL;
+ dg = NULL;
+ nc = NULL;
+ bu = NULL;
+ ipv4 = 0UL;
+ back = 1;
+ if(co_mc) { $? ". inspect mac"
+ if(dk3str_c8_len(co_mc) < sizeof(maca)) { $? ". length ok"
+ dk3str_c8_cpy_not_overlapped(maca, co_mc);
+ if(!itadmin_register_correct_mac(job, maca)) {
+ back = 0; $? "! correction"
+ /* ERROR: Illegal MAC address! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 221, 222, co_mc);
+ } else { $? ". correction"
+ }
+ } else { $? "! length"
+ back = 0;
+ /* ERROR: MAC address too long! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 223, 224, co_mc);
+ }
+ }
+ if(itadmin_register_check_user_name(us_s)) { $? ". user \"%!8s\"", TR_8STR(us_s)
+ user = (itadmin_user *)dk3sto_it_find_like(job->i_us, (void *)us_s, 1);
+ if(!(user)) { $? "! user"
+ /* ERROR: No such user! */
+ back = 0;
+ itadmin_tool_log_utf8_5(job, DK3_LL_ERROR, 225, 226, 227, co_s, us_s);
+ }
+ }
+ if(itadmin_register_check_user_name(ng_s)) {
+ ng = (itadmin_netgroup *)dk3sto_it_find_like(job->i_ng,(void *)ng_s,1);
+ if(!(ng)) { $? "! ng"
+ /* ERROR: No such netgroup! */
+ back = 0;
+ itadmin_tool_log_utf8_5(job, DK3_LL_ERROR, 228, 229, 230, co_s, ng_s);
+ }
+ }
+ if(itadmin_job_do_dhcp(job)) { $? ". do dhcp"
+ if(itadmin_register_check_user_name(dc_s)) {
+ dc = (itadmin_dhcp_class *)dk3sto_it_find_like(
+ job->i_dc, (void *)dc_s, 1
+ );
+ if(!(dc)) { $? "! dc"
+ /* ERROR: No such DHCP class! */
+ back = 0;
+ itadmin_tool_log_utf8_5(job,DK3_LL_ERROR,231,232,233,co_s,dc_s);
+ }
+ }
+ if(itadmin_register_check_user_name(dg_s)) {
+ dg = (itadmin_dhcp_group *)dk3sto_it_find_like(
+ job->i_dg, (void *)dg_s, 1
+ );
+ if(!(dg)) { $? "! dg"
+ /* ERROR: No such DHCP group! */
+ back = 0;
+ itadmin_tool_log_utf8_5(job,DK3_LL_ERROR,234,235,236,co_s,dg_s);
+ }
+ }
+ }
+ if(itadmin_register_check_user_name(dd_n)) {
+ nc = (itadmin_connect *)dk3sto_it_find_like(job->i_pa, (void *)dd_n, 1);
+ if(!(nc)) { $? "! nc"
+ /* ERROR: No such patch! */
+ back = 0;
+ itadmin_tool_log_utf8_5(job, DK3_LL_ERROR, 237, 238, 239, co_s, dd_n);
+ }
+ }
+ if(itadmin_register_check_user_name(gb_s)) {
+ bu = (itadmin_building *)dk3sto_it_find_like(job->i_bu,(void *)gb_s,1);
+ if(!(bu)) { $? "! bu"
+ /* ERROR: No such building! */
+ back = 0;
+ itadmin_tool_log_utf8_5(job, DK3_LL_ERROR, 240, 241, 242, co_s, gb_s);
+ }
+ }
+ if(itadmin_register_check_ip(co_ip)) {
+ if(!dk3enc_c8_ipaddr_to_ul_app(co_ip, &ipv4, job->app)) {
+ /* ERROR: Failed to convert IP address string to address! */
+ back = 0; $? "! ip"
+ }
+ }
+ if(back) { $? ". back"
+ back = 0;
+ if((ipv4) && (dc)) {
+ /* WARNING: Both IPv4 address and DHCP class! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_WARNING, 243, 244, co_s);
+ }
+ if((dc) && (!(co_mc))) {
+ /* WARNING: DHCP class but no MAC address! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_WARNING, 245, 246, co_s);
+ }
+ if((!(ipv4)) && (ng)) {
+ /* WARNING: Netgroup but no IP address! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_WARNING, 247, 248, co_s);
+ }
+ if((ng) && (!co_dd)) {
+ /* WARNING: Netgroup but no DNS domain! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_WARNING, 249, 250, co_s);
+ }
+ if((co_ff) && (!(co_dd))) {
+ /* WARNING: FQDN first flag but no DNS domain! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_WARNING, 251, 252, co_s);
+ } $? ". before comp date"
+ if(co_ex) {
+ if(((job->today).y) || ((job->today).m) || ((job->today).d)) {
+ if((co_ex->y) || (co_ex->m) || (co_ex->d)) {
+ if(itadmin_comp_date(&(job->today), co_ex) > 0) {
+ /* WARNING: Host expired. */
+ itadmin_tool_log_utf8_3(job, DK3_LL_WARNING, 253, 254, co_s);
+ }
+ }
+ }
+ }
+ $? ". after comp date"
+ ho = itadmin_mem_host_new(
+ job, co_ex, co_s, co_co,
+ ((co_mc) ? maca : NULL),
+ co_r, co_in, co_sn, co_hi, co_dd,
+ user, ng, dc, dg, nc, bu, ipv4, co_ff, co_gu, co_nn, co_na
+ );
+ if(ho) { $? ". ho"
+ if(dk3sto_add(job->s_ho, (void *)ho)) { $? ". add"
+ if(dk3sto_add(job->s_hoi, (void *)ho)) {
+ back = 1; $? ". add"
+ if(ipv4 == 0x7F000001UL) {
+ job->hlh = 1;
+ }
+ if(itadmin_job_do_dhcp(job)) { $? ". DHCP"
+ nw = NULL;
+ if(ipv4) {
+ nw = (itadmin_network *)dk3sto_it_find_like(
+ job->i_nw, (void *)(&ipv4), 1
+ );
+ }
+ if(nw) { $? ". network found"
+ ho->dp = (itadmin_dhcp_pool *)dk3sto_it_find_like(
+ job->i_dp, (void *)(&ipv4), 1
+ );
+ if(!(ho->dp)) { $? ". not in DHCP pool"
+ if(dg) { $? ". host in DHCP group"
+ if(!itadmin_register_host_in_dhcp_group(job,dg,nw,ho)) {
+ back = 0;
+ }
+ } else { $? ". not in DHCP group"
+ if(!itadmin_register_host_in_network(job, nw, ho)) {
+ back = 0;
+ }
+ }
+ } else { $? ". host in DHCP pool"
+ if(!itadmin_register_host_in_pool(job, ho->dp, ho)) {
+ back = 0;
+ }
+ }
+ } else { $? ". no network for IP"
+ /* Host not in a network. */
+ if(dc) { $? ". register DHCP class"
+ if(!itadmin_register_host_in_dhcp_class(job,dc,ho)) {
+ back = 0;
+ }
+ } else { $? ". no DHCP class"
+ }
+ }
+ } else { $? ". no DHCP"
+ }
+ if(user) {
+ if(!itadmin_register_host_for_user(job, user, ho)) {
+ back = 0;
+ }
+ }
+ } else { $? "! add"
+ }
+ } else { $? "! add"
+ itadmin_mem_host_del(ho);
+ }
+ } else { $? "! ho"
+ /* ERROR: Memory! */
+ }
+ }
+ }
+ } else { $? "! computer name"
+ /* ERROR: Computer name! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 255);
+ }
+ $? "- itadmin_register_host %d", back
+ return back;
+}
+
+
+
+int
+itadmin_register_alias(itadmin_job *job, char const *al, char const *rn)
+{
+ itadmin_host *host;
+ char const *nn;
+ int back = 0;
+ $? "+ itadmin_register_alias \"%!8s\"=\"%!8s\"", TR_8STR(al), TR_8STR(rn)
+ if((job) && (al) && (rn)) {
+ host = (itadmin_host *)dk3sto_it_find_like(job->i_ho, (void *)rn, 1);
+ if(host) {
+ if(!(host->s_al)) {
+ host->s_al = dk3sto_open_app(job->app);
+ if(host->s_al) {
+ dk3sto_set_comp(host->s_al, itadmin_comp_string, 0);
+ }
+ }
+ if(!(host->i_al)) {
+ if(host->s_al) {
+ host->i_al = dk3sto_it_open(host->s_al);
+ }
+ }
+ if((host->s_al) && (host->i_al)) {
+ nn = dk3str_c8_dup_app(al, job->app);
+ if(nn) {
+ if(dk3sto_add(host->s_al, (void *)nn)) {
+ back = 1;
+ } else {
+ dk3_delete(nn);
+ }
+ } else {
+ /* ERROR: Memory! */
+ }
+ } else {
+ /* ERROR: Memory! */
+ }
+ } else {
+ /* ERROR: No such host rn! */
+ itadmin_tool_log_utf8_5(job, DK3_LL_ERROR, 256, 257, 258, al, rn);
+ }
+ } $? "- itadmin_register_alias %d", back
+ return back;
+}
+
+
+
+int
+itadmin_register_dhcp_option(
+ itadmin_job *job,
+ char const *sct,
+ char const *scn,
+ char const *k,
+ char const *v,
+ long pk
+)
+{
+ char buffer[128];
+ itadmin_dhcp_option *no;
+ itadmin_vlan *vl;
+ itadmin_network *nw;
+ itadmin_dhcp_group *dg;
+ itadmin_dhcp_pool *dp;
+ itadmin_host *ho;
+ unsigned long ipv4 = 0UL;
+ int scope;
+ int back = 0;
+ $? "+ itadmin_register_dhcp_option"
+ $? ". scope type: %!8s", TR_8STR(sct)
+ $? ". scope name: %!8s", TR_8STR(scn)
+ $? ". name %!8s", TR_8STR(k)
+ $? ". value %!8s", TR_8STR(v)
+ if((job) && (sct) && (k)) {
+ scope = dk3str_c8_array_index(itadmin_register_scope_type_names, sct, 0);
+ switch(scope) {
+ case 0: { $? ". server"
+ if((job->s_do) && (job->i_do)) {
+ no = itadmin_mem_dhcp_option_new(job, k, v, pk);
+ if(no) {
+ if(dk3sto_add(job->s_do, (void *)no)) {
+ back = 1;
+ } else {
+ itadmin_mem_dhcp_option_del((void *)no);
+ }
+ } else {
+ }
+ } else {
+ /* BUG: Should be set during itamin_job_up()! */
+ }
+ } break;
+ case 1: { $? ". vlan"
+ vl = NULL;
+ if(scn) {
+ vl = (itadmin_vlan *)dk3sto_it_find_like(
+ job->i_vl, (void *)scn, 1
+ );
+ }
+ if(vl) {
+ if(!(vl->s_do)) {
+ vl->s_do = dk3sto_open_app(job->app);
+ if(vl->s_do) {
+ dk3sto_set_comp(vl->s_do, itadmin_comp_dhcp_option, 0);
+ }
+ }
+ if(!(vl->i_do)) {
+ if(vl->s_do) {
+ vl->i_do = dk3sto_it_open(vl->s_do);
+ }
+ }
+ if((vl->s_do) && (vl->i_do)) {
+ no = itadmin_mem_dhcp_option_new(job, k, v, pk);
+ if(no) {
+ if(dk3sto_add(vl->s_do, (void *)no)) {
+ back = 1;
+ } else {
+ itadmin_mem_dhcp_option_del((void *)no);
+ }
+ } else {
+ }
+ }
+ } else {
+ /* ERROR: No such VLAN! */
+ itadmin_tool_log_pk_5(job, DK3_LL_ERROR, 259, 260, 261, pk, scn);
+ }
+ } break;
+ case 2: { $? ". network"
+ nw = NULL;
+ if(scn) {
+ if(dk3enc_c8_ipaddr_to_ul_app(scn, &ipv4, job->app)) {
+ nw = (itadmin_network *)dk3sto_it_find_like(
+ job->i_nw, (void *)(&ipv4), 1
+ );
+ }
+ }
+ if(nw) {
+ if(!(nw->s_do)) {
+ nw->s_do = dk3sto_open_app(job->app);
+ if(nw->s_do) {
+ dk3sto_set_comp(nw->s_do, itadmin_comp_dhcp_option, 0);
+ }
+ }
+ if(!(nw->i_do)) {
+ if(nw->s_do) {
+ nw->i_do = dk3sto_it_open(nw->s_do);
+ }
+ }
+ if((nw->s_do) && (nw->i_do)) {
+ no = itadmin_mem_dhcp_option_new(job, k, v, pk);
+ if(no) {
+ if(dk3sto_add(nw->s_do, (void *)no)) {
+ back = 1;
+ } else {
+ itadmin_mem_dhcp_option_del((void *)no);
+ }
+ } else {
+ }
+ }
+ } else {
+ /* ERROR: No such network! */
+ itadmin_tool_ip_to_buffer(buffer, ipv4);
+ itadmin_tool_log_pk_5(job,DK3_LL_ERROR,262,263,264,pk,buffer);
+ }
+ } break;
+ case 3: { $? ". group"
+ dg = NULL;
+ if(scn) {
+ dg = (itadmin_dhcp_group *)dk3sto_it_find_like(
+ job->i_dg, (void *)scn, 1
+ );
+ }
+ if(dg) {
+ if(!(dg->s_do)) {
+ dg->s_do = dk3sto_open_app(job->app);
+ if(dg->s_do) {
+ dk3sto_set_comp(dg->s_do, itadmin_comp_dhcp_option, 0);
+ }
+ }
+ if(!(dg->i_do)) {
+ if(dg->s_do) {
+ dg->i_do = dk3sto_it_open(dg->s_do);
+ }
+ }
+ if((dg->s_do) && (dg->i_do)) {
+ no = itadmin_mem_dhcp_option_new(job, k, v, pk);
+ if(no) {
+ if(dk3sto_add(dg->s_do, (void *)no)) {
+ back = 1;
+ } else {
+ itadmin_mem_dhcp_option_del((void *)no);
+ }
+ } else {
+ }
+ }
+ } else {
+ /* ERROR: No such DHCP group! */
+ itadmin_tool_log_pk_5(job, DK3_LL_ERROR, 265, 266, 267, pk, scn);
+ }
+ } break;
+ case 4: { $? ". pool"
+ dp = NULL;
+ if(scn) {
+ if(dk3enc_c8_ipaddr_to_ul_app(scn, &ipv4, job->app)) {
+ dp = (itadmin_dhcp_pool *)dk3sto_it_find_like(
+ job->i_dp, (void *)(&ipv4), 1
+ );
+ }
+ }
+ if(dp) {
+ if(!(dp->s_do)) {
+ dp->s_do = dk3sto_open_app(job->app);
+ if(dp->s_do) {
+ dk3sto_set_comp(dp->s_do, itadmin_comp_dhcp_option, 0);
+ }
+ }
+ if(!(dp->i_do)) {
+ if(dp->s_do) {
+ dp->i_do = dk3sto_it_open(dp->s_do);
+ }
+ }
+ if((dp->s_do) && (dp->i_do)) {
+ no = itadmin_mem_dhcp_option_new(job, k, v, pk);
+ if(no) {
+ if(dk3sto_add(dp->s_do, (void *)no)) {
+ back = 1;
+ } else {
+ itadmin_mem_dhcp_option_del((void *)no);
+ }
+ } else {
+ }
+ }
+ } else {
+ /* ERROR: No such DHCP pool! */
+ itadmin_tool_ip_to_buffer(buffer, ipv4);
+ itadmin_tool_log_pk_5(job,DK3_LL_ERROR,268,269,270,pk,buffer);
+ }
+ } break;
+ case 5: { $? ". host"
+ ho = NULL;
+ if(scn) {
+ ho = (itadmin_host *)dk3sto_it_find_like(
+ job->i_ho, (void *)scn, 1
+ );
+ }
+ if(ho) {
+ if(!(ho->s_do)) {
+ ho->s_do = dk3sto_open_app(job->app);
+ if(ho->s_do) {
+ dk3sto_set_comp(ho->s_do, itadmin_comp_dhcp_option, 0);
+ }
+ }
+ if(!(ho->i_do)) {
+ if(ho->s_do) {
+ ho->i_do = dk3sto_it_open(ho->s_do);
+ }
+ }
+ if((ho->s_do) && (ho->i_do)) {
+ no = itadmin_mem_dhcp_option_new(job, k, v, pk);
+ if(no) {
+ if(dk3sto_add(ho->s_do, (void *)no)) {
+ back = 1;
+ } else {
+ itadmin_mem_dhcp_option_del((void *)no);
+ }
+ } else {
+ }
+ }
+ } else {
+ /* ERROR: No such host! */
+ itadmin_tool_log_pk_5(job, DK3_LL_ERROR, 271, 272, 273, pk, scn);
+ }
+ } break;
+ default: {
+ /* ERROR: Unknown scope type name! */
+ itadmin_tool_log_pk_5(job, DK3_LL_ERROR, 274, 275, 276, pk, sct);
+ } break;
+ }
+ } else {
+ /* ERROR: Incomplete arguments! */
+ } $? "- itadmin_register_dhcp_option %d", back
+ return back;
+}
+
+
+
+int
+itadmin_register_swman( itadmin_job *job, char const *sm_s, char const *sm_l)
+{
+ itadmin_swman *sm;
+ int back = 0;
+ $? "+ itadmin_register_swman \"%!8s\" \"%!8s\"", TR_8STR(sm_s), TR_8STR(sm_l)
+ if(itadmin_register_check_user_name(sm_s)) { $? ". short name"
+ if(dk3sto_it_find_like(job->i_sm, (void *)sm_s, 1)) { $? "! duplicated"
+ /* ERROR: Duplicated entry! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 178, 179, sm_s);
+ } else {
+ sm = itadmin_mem_sw_man_new(job, sm_s, sm_l);
+ if(sm) {
+ if(dk3sto_add(job->s_sm, (void *)sm)) {
+ back = 1;
+ } else {
+ itadmin_mem_sw_man_del((void *)sm);
+ }
+ }
+ }
+ } else {
+ /* ERROR: Manufacturer name! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 303, 304, sm_s);
+ } $? "- itadmin_register_swman %d", back
+ return back;
+}
+
+
+
+int
+itadmin_register_swprod(
+ itadmin_job *job,
+ char const *sw_s,
+ char const *sw_l,
+ char const *sm_s
+)
+{
+ itadmin_swprod *sp;
+ itadmin_swman *sm;
+ int back = 0;
+ if(itadmin_register_check_user_name(sw_s)) {
+ if(dk3sto_it_find_like(job->i_sw, (void *)sw_s, 1)) {
+ /* ERROR: Duplicate entry! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 277, 278, sw_s);
+ } else {
+ sm = NULL;
+ if(sm_s) {
+ sm = (itadmin_swman *)dk3sto_it_find_like(job->i_sm, (void *)sm_s, 1);
+ if(!(sm)) {
+ /* WARNING: Failed to find software manufacturer! */
+ itadmin_tool_log_utf8_5(job, DK3_LL_ERROR, 279, 280, 281, sw_s, sm_s);
+ }
+ }
+ sp = itadmin_mem_swprod_new(job, sw_s, sw_l, sm);
+ if(sp) {
+ if(dk3sto_add(job->s_sw, (void *)sp)) {
+ back = 1;
+ } else {
+ itadmin_mem_software_del((void *)sp);
+ }
+ }
+ }
+ } else {
+ /* ERROR: Illegal software product name! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 305, 306, sw_s);
+ }
+ return back;
+}
+
+
+
+int
+itadmin_register_lictype(
+ itadmin_job *job,
+ char const *lt_s,
+ char const *lt_l,
+ int nl
+)
+{
+ itadmin_lictype *lt;
+ int back = 0;
+ if(itadmin_register_check_user_name(lt_s)) {
+ if(dk3sto_it_find_like(job->i_lt, (void *)lt_s, 1)) {
+ /* ERROR: Duplicate entry! */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 282, 283, lt_s);
+ } else {
+ lt = itadmin_mem_lictype_new(job, lt_s, lt_l, nl);
+ if(lt) {
+ if(dk3sto_add(job->s_lt, (void *)lt)) {
+ back = 1;
+ } else {
+ itadmin_mem_lic_type_del((void *)lt);
+ }
+ }
+ }
+ } else {
+ /* ERROR: Illegal license type name */
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 307, 308, lt_s);
+ }
+ return back;
+}
+
+
+
+/** Register a license assigned to a user.
+ @param job Job structure.
+ @param us User.
+ @param li New license to register.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_register_license_to_user(
+ itadmin_job *job,
+ itadmin_user *us,
+ itadmin_license *li
+)
+{
+ int back = 0;
+ if(!(us->s_li)) {
+ us->s_li = dk3sto_open_app(job->app);
+ if(us->s_li) {
+ dk3sto_set_comp(us->s_li, itadmin_comp_license, 2);
+ }
+ }
+ if(!(us->i_li)) {
+ if(us->s_li) {
+ us->i_li = dk3sto_it_open(us->s_li);
+ }
+ }
+ if((us->s_li) && (us->i_li)) {
+ if(dk3sto_add(us->s_li, (void *)li)) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Register a license used on a computer.
+ @param job Job structure.
+ @param co Computer on which the license is used.
+ @param li License to register.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_register_license_to_host(
+ itadmin_job *job,
+ itadmin_host *co,
+ itadmin_license *li
+)
+{
+ int back = 0;
+ if(!(co->s_li)) {
+ co->s_li = dk3sto_open_app(job->app);
+ if(co->s_li) {
+ dk3sto_set_comp(co->s_li, itadmin_comp_license, 2);
+ }
+ }
+ if(!(co->i_li)) {
+ if(co->s_li) {
+ co->i_li = dk3sto_it_open(co->s_li);
+ }
+ }
+ if((co->s_li) && (co->i_li)) {
+ if(dk3sto_add(co->s_li, (void *)li)) {
+ back = 1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Register an unused license (a license not assigned to
+ any user or computer).
+ @param job Job structure.
+ @param li License to register.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+itadmin_register_unused_license(
+ itadmin_job *job,
+ itadmin_license *li
+)
+{
+ int back = 0;
+ if(dk3sto_add(job->s_lf, (void *)li)) {
+ back = 1;
+ }
+ return back;
+}
+
+
+
+int
+itadmin_register_license(
+ itadmin_job *job,
+ unsigned long pk,
+ char const *li_on,
+ char const *sw_s,
+ char const *us_s,
+ char const *co_s,
+ char const *lt_s,
+ char const *li_no,
+ char const *sr_s,
+ itadmin_date *li_dd,
+ char const *li_nd,
+ itadmin_date *li_di,
+ char const *li_ni
+)
+{
+ itadmin_swprod *sp;
+ itadmin_lictype *lt;
+ itadmin_user *us;
+ itadmin_host *co;
+ itadmin_license *li;
+ int back = 0;
+ if(itadmin_register_check_user_name(sw_s)) {
+ if(dk3sto_it_find_like(job->i_lc, (void *)(&pk), 1)) {
+ /* ERROR: Duplicate entry */
+ itadmin_tool_log_pk_3(job, DK3_LL_ERROR, 284, 285, pk);
+ } else {
+ sp = NULL; lt = NULL; us = NULL; co = NULL;
+ sp = (itadmin_swprod *)dk3sto_it_find_like(job->i_sw, (void *)sw_s, 1);
+ if(sp) {
+ back = 1;
+ if(us_s) {
+ if(itadmin_register_check_user_name(us_s)) {
+ us =
+ (itadmin_user *)dk3sto_it_find_like(job->i_us, (void *)us_s, 1);
+ if(!(us)) {
+ back = 0;
+ /* ERROR: User not found! */
+ itadmin_tool_log_pk_5(job,DK3_LL_ERROR,286,287,288,pk,us_s);
+ }
+ }
+ }
+ if(co_s) {
+ if(itadmin_register_check_user_name(co_s)) {
+ co =
+ (itadmin_host *)dk3sto_it_find_like(job->i_ho, (void *)co_s, 1);
+ if(!(co)) {
+ back = 0;
+ /* ERROR: Computer not found! */
+ itadmin_tool_log_pk_5(job,DK3_LL_ERROR,289,290,291,pk,co_s);
+ }
+ }
+ }
+ if(lt_s) {
+ if(itadmin_register_check_user_name(lt_s)) {
+ lt =
+ (itadmin_lictype *)dk3sto_it_find_like(job->i_lt,(void *)lt_s,1);
+ if(!(lt)) {
+ back = 0;
+ /* ERROR: License type not found! */
+ itadmin_tool_log_pk_5(job,DK3_LL_ERROR,292,293,294,pk,lt_s);
+ }
+ }
+ }
+ if(back) {
+ back = 0;
+ li = itadmin_mem_license_new(
+ job, pk, li_on, li_no, li_dd, li_nd, li_di, li_ni, sp, lt, us, co
+ );
+ if(li) {
+ if(dk3sto_add(job->s_lc, (void *)li)) {
+ back = 1;
+ if(us) {
+ if(co) {
+ if(itadmin_tool_check_same_user(us, co)) {
+ if(!itadmin_register_license_to_host(job, co, li)) {
+ back = 0;
+ }
+ } else {
+ if(!itadmin_register_license_to_host(job, co, li)) {
+ back = 0;
+ }
+ if(!itadmin_register_license_to_user(job, us, li)) {
+ back = 0;
+ }
+ }
+ } else {
+ if(!itadmin_register_license_to_user(job, us, li)) {
+ back = 0;
+ }
+ }
+ } else {
+ if(co) {
+ if(!itadmin_register_license_to_host(job, co, li)) {
+ back = 0;
+ }
+ /* Warning: License assigned to computer, not user */
+ itadmin_tool_log_pk_5(
+ job, DK3_LL_WARNING, 295, 296, 297, pk, co_s
+ );
+ } else {
+ if(!itadmin_register_unused_license(job, li)) {
+ back = 0;
+ }
+ }
+ }
+ } else {
+ itadmin_mem_license_del((void *)li);
+ }
+ }
+ }
+ }
+ }
+ } else {
+ /* ERROR: No software specified! */
+ itadmin_tool_log_pk_3(job, DK3_LL_ERROR, 298, 299, pk);
+ }
+ return back;
+}
+
+
diff --git a/support/dktools/itatool.c b/support/dktools/itatool.c
new file mode 100644
index 0000000000..3a9ec21f65
--- /dev/null
+++ b/support/dktools/itatool.c
@@ -0,0 +1,537 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: itatool.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file itatool.c The itatool module.
+*/
+
+
+#line 10 "itatool.ctr"
+
+#include "dk3all.h"
+#include "itadmin.h"
+
+
+
+
+
+#line 17 "itatool.ctr"
+
+
+
+/** Keywords used by this module, not localized.
+*/
+static char const * const itadmin_tool_c8_kw[] = {
+/* 0 */
+"\n",
+
+/* 1 */
+" ",
+
+/* 2 */
+"\\multicolumn{2}{c}{\\textbf{",
+
+/* 3 */
+"}",
+
+/* 4 */
+"\\\\*",
+
+/* 5 */
+"\\\\[1em]",
+
+/* 6 */
+"&",
+
+/* 7 */
+"\\textit{",
+
+/* 8 */
+"\\textbf{",
+
+NULL
+
+
+#line 61 "itatool.ctr"
+};
+
+
+
+int
+itadmin_tool_convert_date(itadmin_job *job, itadmin_date *dp, char const *str)
+{
+ char bu[64]; /* Private copy of string. */
+ char *p1; /* Start of month. */
+ char *p2; /* Start of day. */
+ int i; /* Temporary conversion result. */
+ int back = 0;
+ int se = 0;
+ if((dp) && (str)) {
+ if(dk3str_c8_len(str) < sizeof(bu)) {
+ dk3str_c8_cpy_not_overlapped(bu, str);
+ dk3str_c8_normalize(bu, NULL, ' ');
+ p1 = dk3str_c8_chr(bu, '-');
+ if(p1) {
+ *(p1++) = '\0';
+ p2 = dk3str_c8_chr(p1, '-');
+ if(p2) {
+ *(p2++) = '\0';
+ if(sscanf(bu, "%d", &i) == 1) {
+ dp->y = i;
+ if(sscanf(p1, "%d", &i) == 1) {
+ dp->m = i;
+ if(sscanf(p2, "%d", &i) == 1) {
+ dp->d = i;
+ back = 1;
+ } else {
+ /* Syntax error */
+ se = 1;
+ }
+ } else {
+ /* Syntax error */
+ se = 1;
+ }
+ } else {
+ /* Syntax error */
+ se = 1;
+ }
+ } else {
+ /* Syntax error */
+ se = 1;
+ }
+ } else {
+ p1 =dk3str_c8_chr(bu, '.');
+ if(p1) {
+ *(p1++) = '\0';
+ p2 = dk3str_c8_chr(p1, '.');
+ if(p2) {
+ *(p2++) = '\0';
+ if(sscanf(bu, "%d", &i) == 1) {
+ dp->d = i;
+ if(sscanf(p1, "%d", &i) == 1) {
+ dp->m = i;
+ if(sscanf(p2, "%d", &i) == 1) {
+ dp->y = i;
+ back = 1;
+ if(i < 100) {
+ dp->y = 1900 + i;
+ }
+ } else {
+ se = 1;
+ }
+ } else {
+ se = 1;
+ }
+ } else {
+ se = 1;
+ }
+ } else {
+ se = 1;
+ }
+ } else {
+ se = 1;
+ }
+ }
+ } else {
+ /* ERROR: String too long! */
+ se = 1;
+ }
+ if(!(back)) {
+ dp->y = 0; dp->m = 0; dp->d = 0;
+ if(se) {
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 300, 301, str);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void
+itadmin_tool_write_ip(FILE *df, unsigned long ipv4)
+{
+ if(df) {
+ fprintf(
+ df,
+ "%lu.%lu.%lu.%lu",
+ ((ipv4 >> 24) & 255UL),
+ ((ipv4 >> 16) & 255UL),
+ ((ipv4 >> 8) & 255UL),
+ ( ipv4 & 255UL)
+ );
+ }
+}
+
+
+
+void
+itadmin_tool_stream_ip(dk3_stream_t *os, unsigned long ipv4)
+{
+ char buffer[128];
+ if(os) {
+ sprintf(
+ buffer,
+ "%lu.%lu.%lu.%lu",
+ ((ipv4 >> 24) & 255UL),
+ ((ipv4 >> 16) & 255UL),
+ ((ipv4 >> 8) & 255UL),
+ ( ipv4 & 255UL)
+ );
+ dk3stream_c8_fputs(os, buffer);
+ }
+}
+
+
+
+void
+itadmin_tool_write_user_latex_short(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ itadmin_user *user
+)
+{
+ if(user->na) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, user->na);
+ } else {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, user->us);
+ }
+}
+
+
+void
+itadmin_tool_write_user_latex_long(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ itadmin_user *user
+)
+{
+ int found = 0;
+ if(user->na) {
+ if(user->tt) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, user->tt);
+ found = 1;
+ }
+ if(user->sn) {
+ if(found) {
+ dk3stream_c8_fputs(os, itadmin_tool_c8_kw[1]);
+ }
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, user->sn);
+ found = 1;
+ }
+ if(found) {
+ dk3stream_c8_fputs(os, itadmin_tool_c8_kw[1]);
+ }
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, user->na);
+ } else {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, user->us);
+ }
+}
+
+
+
+void
+itadmin_tool_table_section_header(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ size_t kwi
+)
+{
+ int ie;
+ ie = dk3app_get_encoding(job->app);
+ dk3stream_c8_fputs(os, itadmin_tool_c8_kw[2]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[kwi], ie);
+ dk3stream_c8_fputs(os, itadmin_tool_c8_kw[3]);
+ dk3stream_c8_fputs(os, itadmin_tool_c8_kw[3]);
+ dk3stream_c8_fputs(os, itadmin_tool_c8_kw[4]);
+ dk3stream_c8_fputs(os, itadmin_tool_c8_kw[0]);
+}
+
+
+
+void
+itadmin_tool_table_line_start(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ size_t kwi
+)
+{
+ int ie;
+ ie = dk3app_get_encoding(job->app);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[kwi], ie);
+}
+
+
+
+void
+itadmin_tool_table_line_sep_rows(
+ itadmin_job *job,
+ dk3_stream_t *os
+)
+{
+ dk3stream_c8_fputs(os, itadmin_tool_c8_kw[6]);
+}
+
+
+
+void
+itadmin_tool_table_line_finish(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ int pb
+)
+{
+ dk3stream_c8_fputs(os, itadmin_tool_c8_kw[(pb) ? 5 : 4]);
+ dk3stream_c8_fputs(os, itadmin_tool_c8_kw[0]);
+}
+
+
+
+void
+itadmin_tool_table_line_no_data(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ int nu
+)
+{
+ int ie;
+ ie = dk3app_get_encoding(job->app);
+ if(nu) {
+ dk3stream_c8_fputs(os, itadmin_tool_c8_kw[7]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[9], ie);
+ dk3stream_c8_fputs(os, itadmin_tool_c8_kw[3]);
+ }
+}
+
+
+
+void
+itadmin_tool_table_line(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ size_t kwi,
+ char const *det,
+ int nu,
+ int pb
+)
+{
+ itadmin_tool_table_line_start(job, os, kwi);
+ itadmin_tool_table_line_sep_rows(job, os);
+ if(det) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, det);
+ } else {
+ itadmin_tool_table_line_no_data(job, os, nu);
+ }
+ itadmin_tool_table_line_finish(job, os, pb);
+}
+
+
+
+void
+itadmin_tool_table_values(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ char const *key,
+ char const *val,
+ int fb,
+ int pb
+)
+{
+ if(key) {
+ if(fb) {
+ dk3stream_c8_fputs(os, itadmin_tool_c8_kw[8]);
+ }
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, key);
+ if(fb) {
+ dk3stream_c8_fputs(os, itadmin_tool_c8_kw[3]);
+ }
+ }
+ dk3stream_c8_fputs(os, itadmin_tool_c8_kw[6]);
+ if(val) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, val);
+ }
+ dk3stream_c8_fputs(os, itadmin_tool_c8_kw[(pb) ? 5 : 4]);
+}
+
+
+
+int
+itadmin_tool_check_same_user(itadmin_user *us, itadmin_host *co)
+{
+ int back = 0;
+ if((us) && (co)) {
+ if(co->un) {
+ if((us->us) && ((co->un)->us)) {
+ if(dk3str_c8_cmp(us->us, (co->un)->us) == 0) {
+ back = 1;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void
+itadmin_tool_write_section(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ char const * const *sect
+)
+{
+ char const * const *ptr;
+ ptr = sect;
+ while(*ptr) {
+ dk3stream_c8_fputs(os, *(ptr++));
+ dk3stream_c8_fputs(os, itadmin_tool_c8_kw[0]);
+ }
+}
+
+
+
+void
+itadmin_tool_log_1(
+ itadmin_job *job,
+ int ll,
+ size_t i
+)
+{
+ if(job) {
+ dk3app_log_1(job->app, ll, job->msg, i);
+ }
+}
+
+
+
+void
+itadmin_tool_log_utf8_3(
+ itadmin_job *job,
+ int ll,
+ size_t i1,
+ size_t i2,
+ char const *msg
+)
+{
+ dkChar bu[256];
+ int res;
+ if((job) && (msg)) {
+ res = dk3str_c8u_to_str_app(
+ bu, DK3_SIZEOF(bu,dkChar), dk3app_get_encoding(job->app), msg, job->app
+ );
+ if(res) {
+ dk3app_log_3(job->app, ll, job->msg, i1, i2, bu);
+ }
+ }
+}
+
+
+
+void
+itadmin_tool_log_utf8_5(
+ itadmin_job *job,
+ int ll,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ char const *msg1,
+ char const *msg2
+)
+{
+ dkChar bu1[256];
+ dkChar bu2[256];
+ int res;
+
+ res = dk3str_c8u_to_str_app(
+ bu1, DK3_SIZEOF(bu1,dkChar), dk3app_get_encoding(job->app), msg1, job->app
+ );
+ if(res) {
+ res = dk3str_c8u_to_str_app(
+ bu2,DK3_SIZEOF(bu2,dkChar),dk3app_get_encoding(job->app),msg2,job->app
+ );
+ if(res) {
+ dk3app_log_5(job->app, ll, job->msg, i1, i2, i3, bu1, bu2);
+ }
+ }
+}
+
+
+
+void
+itadmin_tool_log_pk_3(
+ itadmin_job *job,
+ int ll,
+ size_t i1,
+ size_t i2,
+ unsigned long pk
+)
+{
+ char buffer[128];
+ sprintf(buffer, "%lu", pk);
+ itadmin_tool_log_utf8_3(job, ll, i1, i2, buffer);
+}
+
+
+
+void
+itadmin_tool_log_pk_5(
+ itadmin_job *job,
+ int ll,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ unsigned long pk,
+ char const *msg
+)
+{
+ char buffer[128];
+ sprintf(buffer, "%lu", pk);
+ itadmin_tool_log_utf8_5(job, ll, i1, i2, i3, buffer, msg);
+}
+
+
+
+void
+itadmin_tool_ip_to_buffer(char *bu, unsigned long ip)
+{
+ sprintf(
+ bu,
+ "%lu.%lu.%lu.%lu",
+ ((ip >> 24) & 0x000000FFUL),
+ ((ip >> 16) & 0x000000FFUL),
+ ((ip >> 8) & 0x000000FFUL),
+ ( ip & 0x000000FFUL)
+ );
+}
+
diff --git a/support/dktools/itatool.ctr b/support/dktools/itatool.ctr
new file mode 100644
index 0000000000..4f74db09a8
--- /dev/null
+++ b/support/dktools/itatool.ctr
@@ -0,0 +1,511 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk3all.h"
+#include "itadmin.h"
+
+
+
+$!trace-include
+
+
+
+/** Keywords used by this module, not localized.
+*/
+static char const * const itadmin_tool_c8_kw[] = {
+$!string-table
+#
+# 0: Newline
+#
+\n
+#
+# 1: Space
+#
+
+#
+# 2: Table header
+#
+\\multicolumn{2}{c}{\\textbf{
+#
+# 3: Closing bracket
+#
+}
+#
+# 4: Newline but no page break
+#
+\\\\*
+#
+# 5: Newline, page break allowed here
+#
+\\\\[1em]
+#
+# 6: Table column separator
+#
+&
+#
+# 7: Start of text span in italic
+#
+\\textit{
+#
+# 8: Start of text span in bold
+#
+\\textbf{
+$!end
+};
+
+
+
+int
+itadmin_tool_convert_date(itadmin_job *job, itadmin_date *dp, char const *str)
+{
+ char bu[64]; /* Private copy of string. */
+ char *p1; /* Start of month. */
+ char *p2; /* Start of day. */
+ int i; /* Temporary conversion result. */
+ int back = 0;
+ int se = 0;
+ if((dp) && (str)) {
+ if(dk3str_c8_len(str) < sizeof(bu)) {
+ dk3str_c8_cpy_not_overlapped(bu, str);
+ dk3str_c8_normalize(bu, NULL, ' ');
+ p1 = dk3str_c8_chr(bu, '-');
+ if(p1) {
+ *(p1++) = '\0';
+ p2 = dk3str_c8_chr(p1, '-');
+ if(p2) {
+ *(p2++) = '\0';
+ if(sscanf(bu, "%d", &i) == 1) {
+ dp->y = i;
+ if(sscanf(p1, "%d", &i) == 1) {
+ dp->m = i;
+ if(sscanf(p2, "%d", &i) == 1) {
+ dp->d = i;
+ back = 1;
+ } else {
+ /* Syntax error */
+ se = 1;
+ }
+ } else {
+ /* Syntax error */
+ se = 1;
+ }
+ } else {
+ /* Syntax error */
+ se = 1;
+ }
+ } else {
+ /* Syntax error */
+ se = 1;
+ }
+ } else {
+ p1 =dk3str_c8_chr(bu, '.');
+ if(p1) {
+ *(p1++) = '\0';
+ p2 = dk3str_c8_chr(p1, '.');
+ if(p2) {
+ *(p2++) = '\0';
+ if(sscanf(bu, "%d", &i) == 1) {
+ dp->d = i;
+ if(sscanf(p1, "%d", &i) == 1) {
+ dp->m = i;
+ if(sscanf(p2, "%d", &i) == 1) {
+ dp->y = i;
+ back = 1;
+ if(i < 100) {
+ dp->y = 1900 + i;
+ }
+ } else {
+ se = 1;
+ }
+ } else {
+ se = 1;
+ }
+ } else {
+ se = 1;
+ }
+ } else {
+ se = 1;
+ }
+ } else {
+ se = 1;
+ }
+ }
+ } else {
+ /* ERROR: String too long! */
+ se = 1;
+ }
+ if(!(back)) {
+ dp->y = 0; dp->m = 0; dp->d = 0;
+ if(se) {
+ itadmin_tool_log_utf8_3(job, DK3_LL_ERROR, 300, 301, str);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void
+itadmin_tool_write_ip(FILE *df, unsigned long ipv4)
+{
+ if(df) {
+ fprintf(
+ df,
+ "%lu.%lu.%lu.%lu",
+ ((ipv4 >> 24) & 255UL),
+ ((ipv4 >> 16) & 255UL),
+ ((ipv4 >> 8) & 255UL),
+ ( ipv4 & 255UL)
+ );
+ }
+}
+
+
+
+void
+itadmin_tool_stream_ip(dk3_stream_t *os, unsigned long ipv4)
+{
+ char buffer[128];
+ if(os) {
+ sprintf(
+ buffer,
+ "%lu.%lu.%lu.%lu",
+ ((ipv4 >> 24) & 255UL),
+ ((ipv4 >> 16) & 255UL),
+ ((ipv4 >> 8) & 255UL),
+ ( ipv4 & 255UL)
+ );
+ dk3stream_c8_fputs(os, buffer);
+ }
+}
+
+
+
+void
+itadmin_tool_write_user_latex_short(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ itadmin_user *user
+)
+{
+ if(user->na) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, user->na);
+ } else {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, user->us);
+ }
+}
+
+
+void
+itadmin_tool_write_user_latex_long(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ itadmin_user *user
+)
+{
+ int found = 0;
+ if(user->na) {
+ if(user->tt) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, user->tt);
+ found = 1;
+ }
+ if(user->sn) {
+ if(found) {
+ dk3stream_c8_fputs(os, itadmin_tool_c8_kw[1]);
+ }
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, user->sn);
+ found = 1;
+ }
+ if(found) {
+ dk3stream_c8_fputs(os, itadmin_tool_c8_kw[1]);
+ }
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, user->na);
+ } else {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, user->us);
+ }
+}
+
+
+
+void
+itadmin_tool_table_section_header(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ size_t kwi
+)
+{
+ int ie;
+ ie = dk3app_get_encoding(job->app);
+ dk3stream_c8_fputs(os, itadmin_tool_c8_kw[2]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[kwi], ie);
+ dk3stream_c8_fputs(os, itadmin_tool_c8_kw[3]);
+ dk3stream_c8_fputs(os, itadmin_tool_c8_kw[3]);
+ dk3stream_c8_fputs(os, itadmin_tool_c8_kw[4]);
+ dk3stream_c8_fputs(os, itadmin_tool_c8_kw[0]);
+}
+
+
+
+void
+itadmin_tool_table_line_start(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ size_t kwi
+)
+{
+ int ie;
+ ie = dk3app_get_encoding(job->app);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[kwi], ie);
+}
+
+
+
+void
+itadmin_tool_table_line_sep_rows(
+ itadmin_job *job,
+ dk3_stream_t *os
+)
+{
+ dk3stream_c8_fputs(os, itadmin_tool_c8_kw[6]);
+}
+
+
+
+void
+itadmin_tool_table_line_finish(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ int pb
+)
+{
+ dk3stream_c8_fputs(os, itadmin_tool_c8_kw[(pb) ? 5 : 4]);
+ dk3stream_c8_fputs(os, itadmin_tool_c8_kw[0]);
+}
+
+
+
+void
+itadmin_tool_table_line_no_data(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ int nu
+)
+{
+ int ie;
+ ie = dk3app_get_encoding(job->app);
+ if(nu) {
+ dk3stream_c8_fputs(os, itadmin_tool_c8_kw[7]);
+ dk3uc2lat_stputs(job->uc2l, os, (job->msg)[9], ie);
+ dk3stream_c8_fputs(os, itadmin_tool_c8_kw[3]);
+ }
+}
+
+
+
+void
+itadmin_tool_table_line(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ size_t kwi,
+ char const *det,
+ int nu,
+ int pb
+)
+{
+ itadmin_tool_table_line_start(job, os, kwi);
+ itadmin_tool_table_line_sep_rows(job, os);
+ if(det) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, det);
+ } else {
+ itadmin_tool_table_line_no_data(job, os, nu);
+ }
+ itadmin_tool_table_line_finish(job, os, pb);
+}
+
+
+
+void
+itadmin_tool_table_values(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ char const *key,
+ char const *val,
+ int fb,
+ int pb
+)
+{
+ if(key) {
+ if(fb) {
+ dk3stream_c8_fputs(os, itadmin_tool_c8_kw[8]);
+ }
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, key);
+ if(fb) {
+ dk3stream_c8_fputs(os, itadmin_tool_c8_kw[3]);
+ }
+ }
+ dk3stream_c8_fputs(os, itadmin_tool_c8_kw[6]);
+ if(val) {
+ dk3uc2lat_c8_utf8_stputs(job->uc2l, os, val);
+ }
+ dk3stream_c8_fputs(os, itadmin_tool_c8_kw[(pb) ? 5 : 4]);
+}
+
+
+
+int
+itadmin_tool_check_same_user(itadmin_user *us, itadmin_host *co)
+{
+ int back = 0;
+ if((us) && (co)) {
+ if(co->un) {
+ if((us->us) && ((co->un)->us)) {
+ if(dk3str_c8_cmp(us->us, (co->un)->us) == 0) {
+ back = 1;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void
+itadmin_tool_write_section(
+ itadmin_job *job,
+ dk3_stream_t *os,
+ char const * const *sect
+)
+{
+ char const * const *ptr;
+ ptr = sect;
+ while(*ptr) {
+ dk3stream_c8_fputs(os, *(ptr++));
+ dk3stream_c8_fputs(os, itadmin_tool_c8_kw[0]);
+ }
+}
+
+
+
+void
+itadmin_tool_log_1(
+ itadmin_job *job,
+ int ll,
+ size_t i
+)
+{
+ if(job) {
+ dk3app_log_1(job->app, ll, job->msg, i);
+ }
+}
+
+
+
+void
+itadmin_tool_log_utf8_3(
+ itadmin_job *job,
+ int ll,
+ size_t i1,
+ size_t i2,
+ char const *msg
+)
+{
+ dkChar bu[256];
+ int res;
+ if((job) && (msg)) {
+ res = dk3str_c8u_to_str_app(
+ bu, DK3_SIZEOF(bu,dkChar), dk3app_get_encoding(job->app), msg, job->app
+ );
+ if(res) {
+ dk3app_log_3(job->app, ll, job->msg, i1, i2, bu);
+ }
+ }
+}
+
+
+
+void
+itadmin_tool_log_utf8_5(
+ itadmin_job *job,
+ int ll,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ char const *msg1,
+ char const *msg2
+)
+{
+ dkChar bu1[256];
+ dkChar bu2[256];
+ int res;
+
+ res = dk3str_c8u_to_str_app(
+ bu1, DK3_SIZEOF(bu1,dkChar), dk3app_get_encoding(job->app), msg1, job->app
+ );
+ if(res) {
+ res = dk3str_c8u_to_str_app(
+ bu2,DK3_SIZEOF(bu2,dkChar),dk3app_get_encoding(job->app),msg2,job->app
+ );
+ if(res) {
+ dk3app_log_5(job->app, ll, job->msg, i1, i2, i3, bu1, bu2);
+ }
+ }
+}
+
+
+
+void
+itadmin_tool_log_pk_3(
+ itadmin_job *job,
+ int ll,
+ size_t i1,
+ size_t i2,
+ unsigned long pk
+)
+{
+ char buffer[128];
+ sprintf(buffer, "%lu", pk);
+ itadmin_tool_log_utf8_3(job, ll, i1, i2, buffer);
+}
+
+
+
+void
+itadmin_tool_log_pk_5(
+ itadmin_job *job,
+ int ll,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ unsigned long pk,
+ char const *msg
+)
+{
+ char buffer[128];
+ sprintf(buffer, "%lu", pk);
+ itadmin_tool_log_utf8_5(job, ll, i1, i2, i3, buffer, msg);
+}
+
+
+
+void
+itadmin_tool_ip_to_buffer(char *bu, unsigned long ip)
+{
+ sprintf(
+ bu,
+ "%lu.%lu.%lu.%lu",
+ ((ip >> 24) & 0x000000FFUL),
+ ((ip >> 16) & 0x000000FFUL),
+ ((ip >> 8) & 0x000000FFUL),
+ ( ip & 0x000000FFUL)
+ );
+}
+
diff --git a/support/dktools/libdk4app.dox b/support/dktools/libdk4app.dox
new file mode 100644
index 0000000000..3458397b82
--- /dev/null
+++ b/support/dktools/libdk4app.dox
@@ -0,0 +1,36 @@
+/** @page libdk4app libdk4app
+
+@section secdk4app Application support
+
+Application support includes:
+- File search for both configuration and resource files <br>
+ The users language and region are considered when building the
+ list of directories to search for a file.
+- Localized messages <br>
+ String table files for the users language and region can be found
+ using the file search.
+- Preferences <br>
+ An administrator or user can configure defaults for configuration items.
+- Logging <br>
+ Log goes to standard output and optionally to a log file. <br>
+ The log file is removed automatically when the appication exits
+ unless there were errors.
+
+@section secdk4apphead Headers and modules
+
+Header | Purpose
+: ---: | :------
+dk4app.h | Application data type and basic functions.
+dk4mema.h | Dynamic memory allocation, diagnostics.
+dk4aopt.h | Access to command line options.
+dk4fs.h | File search.
+dk4appmkdh.h | Create directory hierarchy for file, diagnostics.
+dk4dira.h | Open directory for traversal, diagnostics.
+dk4fileia.h | Information about a file, diagnostics.
+dk4fopda.h | Open file, apply security checks, diagnostics.
+dk4fdrda.h | Read from file descriptor, diagnostics.
+dk4fdrde.h | Issue diagnostics for errors while reading from file descriptor.
+dk4fdwre.h | Issue diagnostics for errors while writing to file descriptor.
+dk4strda.h | String duplication, diagnostics.
+
+*/
diff --git a/support/dktools/libdk4base.dox b/support/dktools/libdk4base.dox
new file mode 100644
index 0000000000..9c66dc5eef
--- /dev/null
+++ b/support/dktools/libdk4base.dox
@@ -0,0 +1,21 @@
+/** @page libdk4base libdk4base
+
+@section secdk4basemod Headers and modules
+
+Header | Purpose
+:----: | :------
+dk4conf.h | Header: Configuration for DK libraries.
+dk4types.h | Header: Data types for DK libraries.
+dk4const.h | Header: Constant value definitions.
+dk4numco.h | Header: Fallback definitions for numeric constants.
+dk4mpl.h | Header: Maximum path length for files and directories.
+dk4error.h | Error reporting.
+dk4mem.h | Dynamic memory allocations.
+dk4memrs.h | Secure memory reset.
+dk4memcpl.h | Copy in overlapping memory ranges.
+dk4str8.h | String functions for char strings.
+dk4strw.h | String functions for wchar_t strings.
+dk4strd.h | String functions for dkChar strings.
+dk4numl.h | Get string length required to show a number.
+
+*/
diff --git a/support/dktools/libdk4c.dox b/support/dktools/libdk4c.dox
new file mode 100644
index 0000000000..aa1d9321f7
--- /dev/null
+++ b/support/dktools/libdk4c.dox
@@ -0,0 +1,262 @@
+/** @page libdk4c libdk4c
+
+@section secdk4headers Pure Headers
+
+Header | Purpose
+:----: | :------
+dk4vers.h | Version number as text.
+
+@section secdk4sortsto Sorted storage
+
+Header | Purpose
+:----: | :------
+dk4sto.h | Sorted and unsorted storage using AVL trees or double-linked lists.
+
+@section secdk4cinfret Information retrieval
+
+Header | Purpose
+:----: | :------
+dk4inst.h | Directory names configured during build process.
+dk4user.h | User login name and home directory.
+dk4isadm.h | Check whether current user is administrator or non-privileged user.
+dk4loc.h | Language, region and encoding.
+dk4hname8.h | Host name as char string.
+dk4hnamew.h | Host name as wchar_t string.
+dk4hnamed.h | Host name as dkChar string.
+dk4getpid.h | Process ID.
+dk4exep8.h | Path name of executed file as char string.
+dk4exepw.h | Path name of executed file as wchar_t string.
+dk4exepd.h | Path name of executed file as dkChar string.
+
+@section secdk4datetime Date and time
+
+Header | Purpose
+:----: | :------
+dk4time.h | Timestamp operations.
+dk4timec.h | Constants to choose a time format.
+dk4ctime.h | Timestamp operations with clock times.
+dk4ftime.h | File timestamp operations, conversion to text.
+dk4time08.h | Convert timestamps to char text.
+dk4timewc.h | Convert timestamps to wchar_t text.
+dk4timedk.h | Convert timestamps to dkChar text.
+
+@section secdk4output Output to file
+
+Header | Purpose
+:----: | :------
+dk4fput.h | Put characters and strings to file.
+dk4svbuf.h | Assign a specific memory range as file buffer, so the buffer can be sanitized after reading or writing security relevant things.
+
+@section secdk4file File and directory
+
+Header | Purpose
+:----: | :------
+dk4getcwd8.h | Get current working directory as char string.
+dk4getcwdw.h | Get current working directory as wchar_t string.
+dk4getcwdd.h | Get current working directory as dkChar string.
+dk4path8.h | Path names in char texts.
+dk4pathw.h | Path names in wchar_t texts.
+dk4pathd.h | Path names in dkChar texts.
+dk4fopc8.h | Open file specified as char path name, additional security checks.
+dk4fopwc.h | Open file specified as wchar_t path name, additional security checks.
+dk4fopd.h | Open file specified as dkChar path name, additional security checks.
+dk4fd.h | File descriptors: Open and close files, read and write data.
+dk4ft.h | File type constants.
+dk4stat.h | Constants for file information.
+dk4statt.h | Type definitions used by the stat functions.
+dk4stat8.h | File information for a path specified as char text.
+dk4statw.h | File information for a path specified as wchar_t text.
+dk4statd.h | File information for a path specified as dkChar text.
+dk4ufit.h | Definitions for the 3 headers below.
+dk4ufi08.h | Create unique file identifier for char path name.
+dk4ufiwc.h | Create unique file identifier for wchar_t path name.
+dk4ufi.h | Create unique file identifier for dkChar path name.
+dk4fs.h | File search for configuration and resource files.
+dk4symlink.h | Find symbolic link destination.
+dk4fileit.h | Data types and constant values for file information.
+dk4file8.h | Check presence of file specified as char text.
+dk4filew.h | Check presence of file specified as wchar_t text.
+dk4filed.h | Check presence of file specified as dkChar text.
+dk4filei.h | Information about files using system-specific functions.
+dk4fileiu.h | Retrieve unique file identifier from file information.
+dk4filei8.h | Retrieve file information for a file specified as char string.
+dk4fileiw.h | Retrieve file information for a file specified as wchar_t string.
+dk4fileid.h | Retrieve file information for a file specified as dkChar string.
+dk4fileig8.h | Convert file related timestamp to char string.
+dk4mkdh8.h | Create directory hierarchy to store a file specified as char.
+dk4mkdhw.h | Create directory hierarchy to store a file specified as wchar_t.
+dk4mkdh.h | Create directory hierarchy to store a file specified as dkChar.
+dk4dir08.h | Open directory specified as char string.
+dk4dirwc.h | Open directory specified as wchar_t string.
+dk4dir.h | Open directory specified as dkChar string.
+dk4fne08.h | Windows: Expand file name specified as char string.
+dk4fnewc.h | Windows: Expand file name specified as wchar_t string.
+dk4fne.h | Windows: Expand file name specified as dkChar string.
+dk4delfile08.h | Delete file specified as char string.
+dk4delfilewc.h | Delete file specified as wchar_t string.
+dk4delfile.h | Delete file specified as dkChar string.
+dk4deldir08.h | Delete empty directory specified as char string.
+dk4deldirwc.h | Delete empty directory specified as wchar_t string.
+dk4deldir.h | Delete empty directory specified as dkChar string.
+dk4istty.h | Check whether FILE or file descriptor is connected to a terminal.
+
+@section secdk4rec Character and string recoding
+
+Header | Purpose
+:----: | :------
+dk4enc.h | Find encoding type by name.
+dk4bom.h | Search for byte order mark at start of data stream.
+dk4ansi.h | Convert ANSI character text to 32 bit characters and vice versa.
+dk4utf8.h | Convert UTF-8 encoded text to 32 bit characters and vice versa.
+dk4utf16.h | Convert UTF-16 characters or bytes to 32 bit character and vice versa.
+dk4c32.h | Convert bytes to 32 bit character.
+dk4rec.h | String recoding between different character sizes and encodings, includes the dk4rec**.h files below.
+dk4rec01.h | String recoding ASCII to ANSI.
+dk4rec02.h | String recoding ANSI to ASCII.
+dk4rec03.h | String recoding ASCII to UTF-8.
+dk4rec04.h | String recoding UTF-8 to ASCII.
+dk4rec05.h | String recoding ANSI to UTF-8.
+dk4rec06.h | String recoding UTF-8 to ANSI.
+dk4rec07.h | String recoding ASCII to UTF-16.
+dk4rec08.h | String recoding UTF-16 to ASCII.
+dk4rec09.h | String recoding ANSI to UTF-16.
+dk4rec10.h | String recoding UTF-16 to ANSI.
+dk4rec11.h | String recoding UTF-8 to UTF-16.
+dk4rec12.h | String recoding UTF-16 to UTF-8.
+dk4rec13.h | String recoding ASCII to 32 bit.
+dk4rec14.h | String recoding 32 bit to ASCII.
+dk4rec15.h | String recoding ANSI to 32 bit.
+dk4rec16.h | String recoding 32 bit to ANSI.
+dk4rec17.h | String recoding UTF-8 to 32 bit.
+dk4rec18.h | String recoding 32 bit to UTF-8.
+dk4rec19.h | String recoding UTF-16 32 bit.
+dk4rec20.h | String recoding 32 bit to UTF-16.
+dk4rec21.h | String recoding ASCII to dkChar.
+dk4rec22.h | String recoding char to dkChar.
+dk4rec23.h | String recoding char to wchar_t.
+dk4rec24.h | String recoding wchar_t to char.
+dk4rec25.h | String recoding dkChar to any.
+
+
+@section secdk4textpro Text processing
+
+Header | Purpose
+:----: | :------
+dk4edstm.h | Operation results for state machines operations in BOM detection.
+dk4tsp.h | Type definitions for headers below.
+dk4tsp08.h | Convert bytes to char or char lines, process text.
+dk4tsp16.h | Convert bytes to 16-bit characters or lines, process text.
+dk4tsp32.h | Convert bytes to 32-bit characters or lines, process text.
+dk4tspdk.h | Convert bytes to dkChar characters or lines, process text.
+
+@section secdk4numbenc Number encoding
+
+Header | Purpose
+:----: | :------
+dk4numl.h | Find maximum string length for integer bit width.
+dk4dblc8.h | Convert double value to char string.
+dk4dblwc.h | Convert double value to wchar_t string.
+dk4dbldk.h | Convert double value to dkChar string.
+
+@section secdk4encdec Text data encoding and decoding
+
+Header | Purpose
+:----: | :------
+dk4dec.h | Operation result when adding byte(s) to a decoder.
+dk4binenc.h | Encode binary data to text using ASCII-Hex or ASCII-85.
+dk4ahd.h | ASCII-Hex decoder
+dk4a85e.h | ASCII-85 encoder.
+dk4a85d.h | ASCII-85 decoder.
+dk4rle.h | Run-length encoder.
+dk4rld.h | Run-length decoder.
+
+@section secdk4stt String tables
+
+Header | Purpose
+:----: | :------
+dk4stt.h | String tables.
+
+@section secdk4cmdlo Command line options
+
+Header | Purpose
+:----: | :------
+dk4opt.h | Command line options.
+
+@section secdk4pref Preferences
+
+Header | Purpose
+:----: | :------
+dk4pref.h | Preferences.
+
+@section secdk4stream Generic I/O using dk4_stream_t API
+
+Header | Purpose
+:----: | :------
+dk4strm.h | Generic stream API.
+dk4strmr.h | Open stream to read a file (either plain or compressed).
+dk4strmw.h | Open stream to write a file (either plain or compressed).
+dk4mbstrm.h | Open stream to write to a memory buffer.
+dk4strmf.h | Implementation for plain files.
+dk4strmb.h | Implementation for bzip2 compressed files.
+dk4strmg.h | Implementation for gzip compressed files.
+dk4strmo08.h | Write char strings to stream, recode if necessary.
+dk4strmo16.h | Write 16-bit char strings to stream, recode if necessary.
+dk4strmo32.h | Write 32-bit char strings to stream, recode if necessary.
+dk4strmodk.h | Write dkChar strings to stream, recode if necessary.
+dk4strms.h | Serialize (write) data to stream.
+dk4strmu.h | Unserialize (read) data from stream.
+dk4c8dbl.h | Write double value to dk4_stream_t or FILE without scientific notation.
+dk4strmco.h | Build a compressing and encoding stream on top of an existring stream.
+
+@section secdk4membs Memory buffers
+
+Header | Purpose
+:----: | :------
+dk4membuf.h | Write data to memory buffers for later use.
+dk4membf.h | Save buffer contents to file.
+dk4membs.h | Save buffer contents to stream.
+
+@section secdk4bits Bit handling
+
+Header | Purpose
+:----: | :------
+dk4bf.h | Bit field and bit arrays.
+dk4bitsh.h | Bit shifter (generates bytes from a sequence of bits).
+
+@section secdk4math Mathematics
+
+Header | Purpose
+:----: | :------
+dk4fpe.h | Access the FPU status.
+
+@section secdk4mdch Message digests and checksums
+
+Header | Purpose
+:----: | :------
+dk4mdch.h | Choose a message or checksum type by name.
+
+@section secdk4winreg Windows registry access
+
+Header | Purpose
+:----: | :------
+dk4wregk.h | Registry key names.
+dk4wregt.h | Registry data types.
+dk4wregc.h | Constants and data types used in the headers below.
+dk4wreg8.h | Access to Windows registry using char strings.
+dk4wregw.h | Access to Windows registry using wchar_t strings.
+dk4wregd.h | Access to Windows registry using dkChar strings.
+
+@section secdk4dmt Daemon tool functions
+
+Header | Purpose
+:----: | :------
+dk4dmt.h | Daemon tool functions.
+
+@section secdk4trace Tracing and debugging
+
+Header | Purpose
+:----: | :------
+dk3trace.h | Functions for code generated by dkct.
+
+*/
+
diff --git a/support/dktools/libdk4dbi.dox b/support/dktools/libdk4dbi.dox
new file mode 100644
index 0000000000..57d6797287
--- /dev/null
+++ b/support/dktools/libdk4dbi.dox
@@ -0,0 +1,46 @@
+/** @page libdk4dbi libdk4dbi
+
+@section secoverview Overview
+
+This library provides a generic interface to Berkeley DB, NDBM and
+in-memory databases. An application can use this API without having
+to care about the real database library used behind the scenes.
+
+Additionally the library has functions to store key/value text pairs
+(char, wchar_t and dkChar texts) in the database.
+
+- Berkeley DB <br>
+ This is the preferred database backend.
+
+- NDBM <br>
+ Some commercial Unix distributions are shipped with NDBM functions
+ in their C runtime library.
+ The gdbm package also provides a function set for the NDBM API,
+ this requires you to replace
+ ~~~~~~~~~~~~~~~{.c}
+ #include <ndbm.h>
+ ~~~~~~~~~~~~~~~
+ by
+ ~~~~~~~~~~~~~~~{.c}
+ #include <gdbm/ndbm.h>
+ ~~~~~~~~~~~~~~~
+ Note: Although you can use the NDBM functions from the GDBM package
+ with DK libraries on your computer, the resulting binary is not
+ redistributable as the DK libraries are BSD-style licensed and the
+ GPL license used by the GDBM package requires all software using
+ the GDBM libraries to be GPL-licensed too.
+
+- in-memory database <br>
+ This is the fallback database included in DK libraries
+ used if neither Berkeley DB nor usable NDBM are found.
+
+@section secmodules Modules
+
+Header | Purpose
+:----: | :------
+dk4dbi.h | Open, close and configure database; save, retrieve and delete binary data key/value pairs.
+dk4dbit8.h | Add-on: save, retrieve and delete char key/value text pairs.
+dk4dbitw.h | Add-on: save, retrieve and delete wchar_t key/value text pairs.
+dk4dbit.h | Add-on: save, retrieve and delete dkChar key/value text pairs.
+
+*/
diff --git a/support/dktools/libdk4dbia.dox b/support/dktools/libdk4dbia.dox
new file mode 100644
index 0000000000..685e0681cb
--- /dev/null
+++ b/support/dktools/libdk4dbia.dox
@@ -0,0 +1,11 @@
+/** @page libdk4dbia libdk4dbia
+
+@section secdk4dbiaoverview Generic API for databases
+
+The dk4dbia.h header file and the module in libdk4dbia provide the
+dk4dbi_open_app() and dk4dbi_open_sizes_app() functions to open a
+simple database. Both functions issue diagnostic messages on errors.
+The dk4dbi_open_app() looks up maximum key and value sizes in the
+preferences.
+
+*/
diff --git a/support/dktools/libdk4lat.dox b/support/dktools/libdk4lat.dox
new file mode 100644
index 0000000000..4a204f1735
--- /dev/null
+++ b/support/dktools/libdk4lat.dox
@@ -0,0 +1,15 @@
+/** @page libdk4lat libdk4lat
+
+@section seclibdk4lat Conversion to LaTeX
+
+The dk4uc2l.h header and the module in the libdk4lat library provide the
+dk4_uc2l_t data type and related functions to find LaTeX sequences
+representing 32 bit characters.
+
+Lookup tables in the ${datarootdir}/dktools/charmap directory are used
+to find the LaTeX sequences.
+
+After finishing output one can write additional recommendations
+(i.e. which packages to include) as comments.
+
+*/
diff --git a/support/dktools/libdk4ma.dox b/support/dktools/libdk4ma.dox
new file mode 100644
index 0000000000..3aa7bdc989
--- /dev/null
+++ b/support/dktools/libdk4ma.dox
@@ -0,0 +1,42 @@
+/** @page libdk4ma libdk4ma
+
+@section mathop Mathematical operations
+
+Mathematical operations on integer numbers with overflow test and
+protection against division by 0 for different sizes
+(addition - add, substraction - sub, multiplication - mul,
+division - div, absolute value - abs):
+
+Data type | Header | Example function
+:-------: | :----: | :---------------
+char | dk4maac.h | dk4ma_char_add()
+unsigned char | dk4maauc.h | dk4ma_uchar_add()
+short | dk4maas.h | dk4ma_short_add()
+unsigned short | dk4maaus.h | dk4ma_ushort_add()
+int | dk4maai.h | dk4ma_int_add()
+unsigned int | dk4maaui.h | dk4ma_uint_add()
+long | dk4maal.h | dk4ma_long_add()
+unsigned long | dk4maaul.h | dk4ma_ulong_add()
+size_t | dk4maasz.h | dk4ma_size_t_add()
+long long | dk4maall.h | dk4ma_ll_add()
+unsigned long long | dk4maalu.h | dk4ma_ull_add()
+intmax_t | dk4maami.h | dk4ma_intmax_t_add()
+uintmax_t | dk4maamu.h | dk4ma_uintmax_t_add()
+dk4_im_t | dk4maadi.h | dk4ma_im_add()
+dk4_um_t | dk4maadu.h | dk4ma_um_add()
+
+@section mathcomp Comparisons
+
+Comparison between signed and unsigned integers for different sizes:
+
+Data type | Header | Function
+:-------: | :----: | :-------
+signed char / unsigned char | dk4macc.h | dk4ma_char_compare()
+short / unsigned short | dk4macs.h | dk4ma_short_compare()
+int / unsigned | dk4maci.h | dk4ma_int_compare()
+long / unsigned long | dk4macl.h | dk4ma_long_compare()
+long long / unsigned long long | dk4macll.h | dk4ma_long_long_compare()
+intmax_t / uintmax_t | dk4macm.h | dk4ma_intmax_t_compare()
+dk4_im_t / dk4_um_t | dk4macd.h | dk4ma_im_compare()
+
+*/
diff --git a/support/dktools/libdk4maio8d.dox b/support/dktools/libdk4maio8d.dox
new file mode 100644
index 0000000000..788310e179
--- /dev/null
+++ b/support/dktools/libdk4maio8d.dox
@@ -0,0 +1,39 @@
+/** @page libdk4maio8d libdk4maio8d
+
+@section secinput8d Convert text to number
+
+Retrieve integer or double number from char text in decimal notation.
+
+Data type | Header | Function
+:-------: | :----: | :-------
+char | dk4mai8dic.h | dk4ma_input_c8_dec_char()
+unsigned char | dk4mai8duc.h | dk4ma_input_c8_dec_uchar()
+short | dk4mai8dis.h | dk4ma_input_c8_dec_short()
+unsigned short | dk4mai8dus.h | dk4ma_input_c8_dec_ushort()
+int | dk4mai8dii.h | dk4ma_input_c8_dec_int()
+unsigned | dk4mai8dui.h | dk4ma_input_c8_dec_uint()
+long | dk4mai8dil.h | dk4ma_input_c8_dec_long()
+unsigned long | dk4mai8dul.h | dk4ma_input_c8_dec_ulong()
+size_t | dk4mai8dsz.h | dk4ma_input_c8_dec_size_t()
+long long | dk4mai8dli.h | dk4ma_input_c8_dec_ll()
+unsigned long long | dk4mai8dlu.h | dk4ma_input_c8_dec_ull()
+intmax_t | dk4mai8dmi.h | dk4ma_input_c8_dec_intmax_t()
+uintmax_t | dk4mai8dmu.h | dk4ma_input_c8_dec_uintmax_t()
+dk4_im_t | dk4mai8ddi.h | dk4ma_input_c8_dec_dk4_im_t()
+dk4_um_t | dk4mai8ddu.h | dk4ma_input_c8_dec_dk4_um_t()
+double | dk4mai8dbl.h | dk4ma_input_c8_double()
+
+@section secioutput8d Convert number to text
+
+Convert integer number to char text in decimal notation.
+
+Data type | Header | Function
+:-------: | :----: | :-------
+dk4_im_t | dk4mao8d.h | dk4ma_write_c8_decimal_unsigned()
+dk4_um_t | dk4mao8d.h | dk4ma_write_c8_decimal_signed()
+double | dk4mao8dbl.h | dk4ma_write_c8_double()
+
+You can cast all other signed integer values to dk4_im_t and all other
+unsigned integer values to dk4_um_t without loss.
+
+*/
diff --git a/support/dktools/libdk4maio8h.dox b/support/dktools/libdk4maio8h.dox
new file mode 100644
index 0000000000..8294d763a0
--- /dev/null
+++ b/support/dktools/libdk4maio8h.dox
@@ -0,0 +1,36 @@
+/** @page libdk4maio8h libdk4maio8h
+
+@section secinput8h Convert text to number
+
+Retrieve integer number from char text in hexadecimal notation.
+
+Data type | Header | Function
+:-------: | :----: | :-------
+char | dk4mai8hic.h | dk4ma_input_c8_hex_char()
+unsigned char | dk4mai8huc.h | dk4ma_input_c8_hex_uchar()
+short | dk4mai8his.h | dk4ma_input_c8_hex_short()
+unsigned short | dk4mai8hus.h | dk4ma_input_c8_hex_ushort()
+int | dk4mai8hii.h | dk4ma_input_c8_hex_int()
+unsigned | dk4mai8hui.h | dk4ma_input_c8_hex_uint()
+long | dk4mai8hil.h | dk4ma_input_c8_hex_long()
+unsigned long | dk4mai8hul.h | dk4ma_input_c8_hex_ulong()
+long long | dk4mai8hli.h | dk4ma_input_c8_hex_ll()
+unsigned long long | dk4mai8hlu.h | dk4ma_input_c8_hex_ull()
+intmax_t | dk4mai8hmi.h | dk4ma_input_c8_hex_intmax_t()
+uintmax_t | dk4mai8hmu.h | dk4ma_input_c8_hex_uintmax_t()
+dk4_im_t | dk4mai8hdi.h | dk4ma_input_c8_hex_dk4_im_t()
+dk4_um_t | dk4mai8hdu.h | dk4ma_input_c8_hex_dk4_um_t()
+
+@section secioutput8h Convert number to text
+
+Convert integer number to char text in hexadecimal notation.
+
+Data type | Header | Function
+:-------: | :----: | :-------
+dk4_im_t | dk4mao8h.h | dk4ma_write_c8_hex_unsigned()
+dk4_um_t | dk4mao8h.h | dk4ma_write_c8_hex_signed()
+
+You can cast all other signed integer values to dk4_im_t and all other
+unsigned integer values to dk4_um_t without loss.
+
+*/
diff --git a/support/dktools/libdk4maiodd.dox b/support/dktools/libdk4maiodd.dox
new file mode 100644
index 0000000000..06f846bbb8
--- /dev/null
+++ b/support/dktools/libdk4maiodd.dox
@@ -0,0 +1,39 @@
+/** @page libdk4maiodd libdk4maiodd
+
+@section secinputdd Convert text to number
+
+Retrieve integer or double number from dkChar text in decimal notation.
+
+Data type | Header | Function
+:-------: | :----: | :-------
+char | dk4maiddic.h | dk4ma_input_dk_dec_char()
+unsigned char | dk4maidduc.h | dk4ma_input_dk_dec_uchar()
+short | dk4maiddis.h | dk4ma_input_dk_dec_short()
+unsigned short | dk4maiddus.h | dk4ma_input_dk_dec_ushort()
+int | dk4maiddii.h | dk4ma_input_dk_dec_int()
+unsigned | dk4maiddui.h | dk4ma_input_dk_dec_uint()
+long | dk4maiddil.h | dk4ma_input_dk_dec_long()
+unsigned long | dk4maiddul.h | dk4ma_input_dk_dec_ulong()
+size_t | dk4maiddsz.h | dk4ma_input_dk_dec_size_t()
+long long | dk4maiddli.h | dk4ma_input_dk_dec_ll()
+unsigned long long | dk4maiddlu.h | dk4ma_input_dk_dec_ull()
+intmax_t | dk4maiddmi.h | dk4ma_input_dk_dec_intmax_t()
+uintmax_t | dk4maiddmu.h | dk4ma_input_dk_dec_uintmax_t()
+dk4_im_t | dk4maidddi.h | dk4ma_input_dk_dec_dk4_im_t()
+dk4_um_t | dk4maidddu.h | dk4ma_input_dk_dec_dk4_um_t()
+double | dk4maiddbl.h | dk4ma_input_dk_double()
+
+@section secioutputdd Convert number to text
+
+Convert integer number to dkChar text in decimal notation.
+
+Data type | Header | Function
+:-------: | :----: | :-------
+dk4_im_t | dk4maodd.h | dk4ma_write_decimal_unsigned()
+dk4_um_t | dk4maodd.h | dk4ma_write_decimal_signed()
+double | dk4maoddbl.h | dk4ma_write_double()
+
+You can cast all other signed integer values to dk4_im_t and all other
+unsigned integer values to dk4_um_t without loss.
+
+*/
diff --git a/support/dktools/libdk4maiodh.dox b/support/dktools/libdk4maiodh.dox
new file mode 100644
index 0000000000..d5ff542639
--- /dev/null
+++ b/support/dktools/libdk4maiodh.dox
@@ -0,0 +1,36 @@
+/** @page libdk4maiodh libdk4maiodh
+
+@section secinputdh Convert text to number
+
+Retrieve integer number from dkChar text in hexadecimal notation.
+
+Data type | Header | Function
+:-------: | :----: | :-------
+char | dk4maidhic.h | dk4ma_input_dk_hex_char()
+unsigned char | dk4maidhuc.h | dk4ma_input_dk_hex_uchar()
+short | dk4maidhis.h | dk4ma_input_dk_hex_short()
+unsigned short | dk4maidhus.h | dk4ma_input_dk_hex_ushort()
+int | dk4maidhii.h | dk4ma_input_dk_hex_int()
+unsigned | dk4maidhui.h | dk4ma_input_dk_hex_uint()
+long | dk4maidhil.h | dk4ma_input_dk_hex_long()
+unsigned long | dk4maidhul.h | dk4ma_input_dk_hex_ulong()
+long long | dk4maidhli.h | dk4ma_input_dk_hex_ll()
+unsigned long long | dk4maidhlu.h | dk4ma_input_dk_hex_ull()
+intmax_t | dk4maidhmi.h | dk4ma_input_dk_hex_intmax_t()
+uintmax_t | dk4maidhmu.h | dk4ma_input_dk_hex_uintmax_t()
+dk4_im_t | dk4maidhdi.h | dk4ma_input_dk_hex_dk4_im_t()
+dk4_um_t | dk4maidhdu.h | dk4ma_input_dk_hex_dk4_um_t()
+
+@section secioutputdh Convert number to text
+
+Convert integer number to dkChar text in hexadecimal notation.
+
+Data type | Header | Function
+:-------: | :----: | :-------
+dk4_im_t | dk4maodh.h | dk4ma_write_hex_unsigned()
+dk4_um_t | dk4maodh.h | dk4ma_write_hex_signed()
+
+You can cast all other signed integer values to dk4_im_t and all other
+unsigned integer values to dk4_um_t without loss.
+
+*/
diff --git a/support/dktools/libdk4maiowd.dox b/support/dktools/libdk4maiowd.dox
new file mode 100644
index 0000000000..11cb40ef14
--- /dev/null
+++ b/support/dktools/libdk4maiowd.dox
@@ -0,0 +1,39 @@
+/** @page libdk4maiowd libdk4maiowd
+
+@section secinputwd Convert text to number
+
+Retrieve integer or double number from wchar_t text in decimal notation.
+
+Data type | Header | Function
+:-------: | :----: | :-------
+char | dk4maiwdic.h | dk4ma_input_wc_dec_char()
+unsigned char | dk4maiwduc.h | dk4ma_input_wc_dec_uchar()
+short | dk4maiwdis.h | dk4ma_input_wc_dec_short()
+unsigned short | dk4maiwdus.h | dk4ma_input_wc_dec_ushort()
+int | dk4maiwdii.h | dk4ma_input_wc_dec_int()
+unsigned | dk4maiwdui.h | dk4ma_input_wc_dec_uint()
+long | dk4maiwdil.h | dk4ma_input_wc_dec_long()
+unsigned long | dk4maiwdul.h | dk4ma_input_wc_dec_ulong()
+size_t | dk4maiwdsz.h | dk4ma_input_wc_dec_size_t()
+long long | dk4maiwdli.h | dk4ma_input_wc_dec_ll()
+unsigned long long | dk4maiwdlu.h | dk4ma_input_wc_dec_ull()
+intmax_t | dk4maiwdmi.h | dk4ma_input_wc_dec_intmax_t()
+uintmax_t | dk4maiwdmu.h | dk4ma_input_wc_dec_uintmax_t()
+dk4_im_t | dk4maiwddi.h | dk4ma_input_wc_dec_dk4_im_t()
+dk4_um_t | dk4maiwddu.h | dk4ma_input_wc_dec_dk4_um_t()
+double | dk4maiwdbl.h | dk4ma_input_wc_double()
+
+@section secioutputwd Convert number to text
+
+Convert integer number to wchar_t text in decimal notation.
+
+Data type | Header | Function
+:-------: | :----: | :-------
+dk4_im_t | dk4maowd.h | dk4ma_write_wc_decimal_unsigned()
+dk4_um_t | dk4maowd.h | dk4ma_write_wc_decimal_signed()
+double | dk4maowdbl.h | dk4ma_write_wc_double()
+
+You can cast all other signed integer values to dk4_im_t and all other
+unsigned integer values to dk4_um_t without loss.
+
+*/
diff --git a/support/dktools/libdk4maiowh.dox b/support/dktools/libdk4maiowh.dox
new file mode 100644
index 0000000000..28d11b196e
--- /dev/null
+++ b/support/dktools/libdk4maiowh.dox
@@ -0,0 +1,36 @@
+/** @page libdk4maiowh libdk4maiowh
+
+@section secinputwh Convert text to number
+
+Retrieve integer number from wchar_t text in hexadecimal notation.
+
+Data type | Header | Function
+:-------: | :----: | :-------
+char | dk4maiwhic.h | dk4ma_input_wc_hex_char()
+unsigned char | dk4maiwhuc.h | dk4ma_input_wc_hex_uchar()
+short | dk4maiwhis.h | dk4ma_input_wc_hex_short()
+unsigned short | dk4maiwhus.h | dk4ma_input_wc_hex_ushort()
+int | dk4maiwhii.h | dk4ma_input_wc_hex_int()
+unsigned | dk4maiwhui.h | dk4ma_input_wc_hex_uint()
+long | dk4maiwhil.h | dk4ma_input_wc_hex_long()
+unsigned long | dk4maiwhul.h | dk4ma_input_wc_hex_ulong()
+long long | dk4maiwhli.h | dk4ma_input_wc_hex_ll()
+unsigned long long | dk4maiwhlu.h | dk4ma_input_wc_hex_ull()
+intmax_t | dk4maiwhmi.h | dk4ma_input_wc_hex_intmax_t()
+uintmax_t | dk4maiwhmu.h | dk4ma_input_wc_hex_uintmax_t()
+dk4_im_t | dk4maiwhdi.h | dk4ma_input_wc_hex_dk4_im_t()
+dk4_um_t | dk4maiwhdu.h | dk4ma_input_wc_hex_dk4_um_t()
+
+@section secioutputwh Convert number to text
+
+Convert integer number to wchar_t text in hexadecimal notation.
+
+Data type | Header | Function
+:-------: | :----: | :-------
+dk4_im_t | dk4maowh.h | dk4ma_write_wc_hex_unsigned()
+dk4_um_t | dk4maowh.h | dk4ma_write_wc_hex_signed()
+
+You can cast all other signed integer values to dk4_im_t and all other
+unsigned integer values to dk4_um_t without loss.
+
+*/
diff --git a/support/dktools/libdk4mdrnd.dox b/support/dktools/libdk4mdrnd.dox
new file mode 100644
index 0000000000..c0e0bf2593
--- /dev/null
+++ b/support/dktools/libdk4mdrnd.dox
@@ -0,0 +1,15 @@
+/** @page libdk4mdrnd libdk4mdrnd
+
+@section secmd Message digests
+
+The dk4md.h header and the module in the libdk4mdrnd library
+provide an easy API to the message digest routines in the OpenSSL
+library.
+
+This product includes software developed by the OpenSSL Project for use in
+the OpenSSL Toolkit (http://www.openssl.org/).
+This product includes cryptographic software written by
+Eric Young (eay@cryptsoft.com).
+This product includes software written by Tim Hudson (tjh@cryptsoft.com).
+
+*/
diff --git a/support/dktools/libdk4pppt.dox b/support/dktools/libdk4pppt.dox
new file mode 100644
index 0000000000..401997d489
--- /dev/null
+++ b/support/dktools/libdk4pppt.dox
@@ -0,0 +1,7 @@
+/** @page libdk4pppt libdk4pppt
+
+Header/module | Purpose
+:-----------: | :-----:
+dk4paper.h | Paper configuration (retrieve size for a given paper name).
+
+*/
diff --git a/support/dktools/libdk4sock.dox b/support/dktools/libdk4sock.dox
new file mode 100644
index 0000000000..8455ca2d49
--- /dev/null
+++ b/support/dktools/libdk4sock.dox
@@ -0,0 +1,9 @@
+/** @page libdk4sock libdk4sock
+
+@section secdk4sock Socket support library
+
+The dk4sock.h header and the modules in the libdk4sock library
+deal with sockets, both for networking and local UNIX domain sockets
+(on systems supporting local sockets).
+
+*/
diff --git a/support/dktools/libdk4socka.dox b/support/dktools/libdk4socka.dox
new file mode 100644
index 0000000000..7fc33af710
--- /dev/null
+++ b/support/dktools/libdk4socka.dox
@@ -0,0 +1,10 @@
+/** @page libdk4socka libdk4socka
+
+@section secdk4sockaover Socket functions with included diagnostics
+
+The dk4socka.h header and the modules in the libdk4socka library contain
+equivalents to some functions from the libdk4sock library.
+The functions from libdk4socka automatically issue diagnostic messages
+on errors.
+
+*/
diff --git a/support/dktools/libdk4wx.dox b/support/dktools/libdk4wx.dox
new file mode 100644
index 0000000000..f5c24b10e4
--- /dev/null
+++ b/support/dktools/libdk4wx.dox
@@ -0,0 +1,23 @@
+/** @page libdk4wx libdk4wx
+
+@section seclibdk4wxover Classes to build wxWidgets based applications
+
+Header | Class / Type | Purpose
+:----: | :----------: | :------
+dk4verswx.h | - | Version number as wxChar string.
+dk4wxtypes.h | DK4_PCWXCHAR | Pointer to wxChar string.
+dk4wxcs.h | DK4_SIZEOF_WXCHAR | Size of a wxChar in bytes.
+dk4strx.h | - | String functions for wxChar strings.
+dk4recwx.h | - | Conversion between dkChar and wxChar, wxChar to char.
+dk4tspwx.h | dk4_tspwx_t | Text processing for wxChar.
+dk4wxpref.h | dk4_wx_pref_t | Preference in wxChar, used by Dk4WxApplicationHelper.
+dk4wxstt.h | dk4_wx_string_table_t | String tables in wxChar, used by Dk4WxApplicationHelper.
+Dk4WxApplicationHelper.h | Dk4WxApplicationHelper | General tool functions.
+Dk4WxHelpController.h | Dk4WxHelpController | Load help file, either *.htb (non-Windows platforms) or *.chm (Windows platforms).
+Dk4WxFrame.h | Dk4WxFrame | Base class for top level windows.
+Dk4WxControl.h | Dk4WxControl | Base class for control elements.
+Dk4WxProgressDialog.h | Dk4WxProgressDialog | Progress dialog.
+Dk4WxAutostartController.h | Dk4WxAutostartController | Controller to autostart some functionality on first idle event.
+Dk4WxProgressControllerBase.h | Dk4WxProgressControllerWorkerBase | Base class for progress controllers interface to worker thread.
+Dk4WxProgressControllerBase.h | Dk4WxProgressControllerOwnerBase | Progress controllers interface to event processing (main) thread.
+*/
diff --git a/support/dktools/livesys-data/apt-pinning.txt b/support/dktools/livesys-data/apt-pinning.txt
new file mode 100644
index 0000000000..83792c4572
--- /dev/null
+++ b/support/dktools/livesys-data/apt-pinning.txt
@@ -0,0 +1,20 @@
+Package: libreoffice-*
+Pin: version *
+Pin-Priority: -1
+
+Package: mythes-*
+Pin: version *
+Pin-Priority: -1
+
+Package: hyphen-*
+Pin: version *
+Pin-Priority: -1
+
+Package: hunspell-*
+Pin: version *
+Pin-Priority: -1
+
+Package: aspell-*
+Pin: version *
+Pin-Priority: -1
+
diff --git a/support/dktools/livesys-data/apt_pinning.txt b/support/dktools/livesys-data/apt_pinning.txt
new file mode 100644
index 0000000000..139597f9cb
--- /dev/null
+++ b/support/dktools/livesys-data/apt_pinning.txt
@@ -0,0 +1,2 @@
+
+
diff --git a/support/dktools/livesys-data/hook_autologin.txt b/support/dktools/livesys-data/hook_autologin.txt
new file mode 100755
index 0000000000..986086d133
--- /dev/null
+++ b/support/dktools/livesys-data/hook_autologin.txt
@@ -0,0 +1,18 @@
+#! /bin/sh
+echo HOOK chroot hook_autologin.txt
+# mkdir -pv /etc/systemd/system/getty@tty1.service.d
+# cp /usr/share/dktoolian/autologin.conf /etc/systemd/system/getty@tty1.service.d
+# chmod 644 /etc/systemd/system/getty@tty1.service.d/autologin.conf
+# if [ -f /etc/inittab -a -f /usr/share/dktoolian/inittab.sed ]
+# then
+# sed -i -f /usr/share/dktoolian/inittab.sed /etc/inittab
+# fi
+
+# SVCS="console-getty container-getty@ getty@ serial-getty@"
+SVCS="getty@"
+for s in ${SVCS}
+do
+ sed -i -f /usr/share/dktoolian/getty.sed "/lib/systemd/system/${s}.service"
+done
+rm -fr /usr/share/dktoolian/getty.sed
+
diff --git a/support/dktools/livesys-data/hook_bootbeep.txt b/support/dktools/livesys-data/hook_bootbeep.txt
new file mode 100644
index 0000000000..a8a550e4c4
--- /dev/null
+++ b/support/dktools/livesys-data/hook_bootbeep.txt
@@ -0,0 +1,5 @@
+if [ -f "${DIR}/livesys/binary/isolinux/menu.cfg" -a -f "${DIR}/livesys/config/includes.chroot/usr/share/dktoolian/nobeep.sed" ]
+then
+ sed -i -f "${DIR}/livesys/config/includes.chroot/usr/share/dktoolian/nobeep.sed" "${DIR}/livesys/binary/isolinux/menu.cfg"
+fi
+
diff --git a/support/dktools/livesys-data/hook_etcfiles.txt b/support/dktools/livesys-data/hook_etcfiles.txt
new file mode 100755
index 0000000000..b02ed3ae19
--- /dev/null
+++ b/support/dktools/livesys-data/hook_etcfiles.txt
@@ -0,0 +1,18 @@
+#! /bin/sh
+#
+# Copy files from /usr/share/dktoolian/etc to /etc
+#
+echo HOOK chroot hook_etcfiles.txt
+if [ -d /usr/share/dktoolian/etc ]
+then
+ cd /usr/share/dktoolian/etc
+ for i in `find . -type d`
+ do
+ [ -d "/etc/$i" ] || ( mkdir "/etc/$i" ; chmod 755 "/etc/$i" )
+ done
+ for i in `find . -type f`
+ do
+ cp "$i" "/etc/$i"
+ done
+fi
+
diff --git a/support/dktools/livesys-data/msg_nonfree.txt b/support/dktools/livesys-data/msg_nonfree.txt
new file mode 100644
index 0000000000..58dafafe5e
--- /dev/null
+++ b/support/dktools/livesys-data/msg_nonfree.txt
@@ -0,0 +1,6 @@
+NOTE: The live system contains non-free firmware files.
+So the live system is probably not distributable.
+
+The two sentences above are an opinion piece and do not contain legal advice.
+You should consult a lawyer to obtain legal advice about the legal status
+of distributing this live system.
diff --git a/support/dktools/livesys-data/pkg_base.txt b/support/dktools/livesys-data/pkg_base.txt
new file mode 100644
index 0000000000..ecb3025f1d
--- /dev/null
+++ b/support/dktools/livesys-data/pkg_base.txt
@@ -0,0 +1,88 @@
+live-boot # Boot configuration for live systems
+live-config # Configuration for live systems
+live-tools # Extra components for live system
+user-setup # Set up initial user and password
+sudo # Grant root privileges to normal users
+firmware-linux-free # Binary firmware for various drivers
+kbd # utilities for console/keyboard layout
+console-keymaps # Keyboard mapping files
+console-data # Keyboard mapping files
+hwinfo # Information about used hardware
+lshw # List hardware
+pciutils # Utilities to check PCI devices, i.e. lspci
+usbutils # Utilities to check USB devices, i.e. lsusb
+hdparm # Hard disk management
+smartmontools # Hard disk management
+udisks # Unmount USB devices
+genisoimage # Create ISO image
+wodim # Burn ISO image to CD/DVD
+util-linux # Several system administration commands
+util-linux-locales # Localized texts for administration commands
+gdisk # Disk partitioning program (GPT)
+parted # Disk partitions management
+gddrescue # attempt data recovery
+squashfs-tools # Tools for squashfs file systems
+e2fsprogs # Tools for ext2, ext3, ext4 file systems
+dosfstools # Access DOS/Windows FAT file systems
+mtools # Floppy disks utilities
+ntfs-3g # NTFS file system
+ntfs-config # Configure NTFS devices
+nfs-client # NFS client
+smbclient # Samba client programs
+binutils # Assembler and related tools for object files
+coreutils # Text processing on command line
+diffutils # Diff and patch files
+patchutils # Diff and patch files
+patch # Apply a patch to a file
+lsof # List all open files
+file # Guess file types
+tcsh # Shell
+bash # Shell
+bash-completion # File name completion
+perl # Scripting language
+m4 # Text macro processor
+bc # Calculator
+cpio # Archivation
+arj # Archivation
+tar # Archivation
+zip # Compression
+unzip # Decompression
+bzip2 # Compression/decompression
+xz-utils # Compression/decompression
+ncompress # Archivation
+lzma # Archivation
+lzop # Archivation
+sed # Text stream manipulation
+dos2unix # Convert dos to unix
+recode # Text recoding
+openssh-client # ssh client
+openssl # Encryption tool
+md5deep # Calculate checksums
+gnupg # Encryption
+isc-dhcp-client # DHCP client
+iproute # Check IP routes
+iputils-ping # Ping program
+net-tools # Network utilities
+wireless-tools # Wireless networking utilities
+snmp # Network management
+rsync # Remote file/directory synchronization
+rdist # Distribute equal files to multiple computers
+cadaver # DAV client
+lynx # Text mode web browser
+ncftp # Comfortable FTP client
+wget # Retrieve files from HTTP/FTP servers
+wput # Upload files to FTP server
+netcat # The netcat program for IPv4
+netcat6 # The netcat program for IPv6
+udpcast # Broadcast/multicast data transmission
+clonezilla # Backup and recovery of disk drives
+partclone # Partition cloning, used blocks only
+partimage # Partition imaging, used blocks only
+cifs-utils # Mount SMB file systems
+dialog # Required by clonezilla
+sshfs # Mount remote directory via SSH protocol
+vim # Editor vi
+nano # Editor nano
+joe # Joes own editor
+man # Online-help
+makedev # The MAKEDEV program
diff --git a/support/dktools/livesys-data/pkg_firmware.txt b/support/dktools/livesys-data/pkg_firmware.txt
new file mode 100644
index 0000000000..2accee0c75
--- /dev/null
+++ b/support/dktools/livesys-data/pkg_firmware.txt
@@ -0,0 +1,23 @@
+atmel-firmware # Atmel at76c50x wireless networking chips
+bluez-firmware # Broadcom BCM203x chipset bluetooth dongles
+dahdi-firmware-nonfree # DAHDI (Zaptel) telephony devices
+firmware-adi # Analog Devices Inc. DSL modem chips
+firmware-atheros # Atheros wireless cards
+firmware-b43-installer # Broadcom 43xx wireless network cards
+firmware-b43legacy-installer # Broadcom 43xx wireless network cards
+firmware-bnx2 # Broadcom NetXtremeII
+firmware-bnx2x # Broadcom NetXtreme II 10Gb
+firmware-brcm80211 # Broadcom 802.11 wireless cards
+firmware-intelwimax # Intel WiMAX Connection devices
+firmware-ipw2x00 # Intel Pro Wireless 2100, 2200 and 2915
+firmware-iwlwifi # Intel Wireless cards
+firmware-libertas # Marvell Libertas 8xxx wireless cards
+firmware-linux # Binary firmware for various drivers
+firmware-linux-nonfree # Binary firmware for various drivers
+firmware-myricom # Myri-10G Ethernet adapters
+firmware-netxen # QLogic Intelligent Ethernet (3000 and 3100)
+firmware-ralink # Ralink wireless cards
+firmware-realtek # Realtek wired and wireless network adapters
+firmware-ti-connectivity # TI Connectivity wireless network adapters
+firmware-zd1211 # the zd1211rw wireless driver
+prism2-usb-firmware-installer # prism2_usb kernel driver
diff --git a/support/dktools/livesys-data/pkg_lang_base.txt b/support/dktools/livesys-data/pkg_lang_base.txt
new file mode 100644
index 0000000000..49e5a44027
--- /dev/null
+++ b/support/dktools/livesys-data/pkg_lang_base.txt
@@ -0,0 +1,62 @@
+task-amharic
+task-arabic
+task-asturian
+task-basque
+task-belarusian
+task-bengali
+task-bosnian
+task-brazilian-portuguese
+task-bulgarian
+task-catalan
+task-chinese-s
+task-chinese-t
+task-croatian
+task-cyrillic
+task-czech
+task-danish
+task-dutch
+task-english
+task-esperanto
+task-estonian
+task-finnish
+task-french
+task-galician
+task-german
+task-greek
+task-gujarati
+task-hebrew
+task-hindi
+task-hungarian
+task-icelandic
+task-irish
+task-italian
+task-japanese
+task-kazakh
+task-khmer
+task-korean
+task-kurdish
+task-latvian
+task-lithuanian
+task-macedonian
+task-malayalam
+task-marathi
+task-northern-sami
+task-norwegian
+task-persian
+task-polish
+task-portuguese
+task-punjabi
+task-romanian
+task-russian
+task-serbian
+task-slovak
+task-slovenian
+task-spanish
+task-swedish
+task-tagalog
+task-tamil
+task-telugu
+task-thai
+task-turkish
+task-ukrainian
+task-welsh
diff --git a/support/dktools/livesys-data/pkg_lang_desktop.txt b/support/dktools/livesys-data/pkg_lang_desktop.txt
new file mode 100644
index 0000000000..5efecae5cc
--- /dev/null
+++ b/support/dktools/livesys-data/pkg_lang_desktop.txt
@@ -0,0 +1,72 @@
+task-albanian-desktop
+task-amharic-desktop
+task-arabic-desktop
+task-asturian-desktop
+task-basque-desktop
+task-belarusian-desktop
+task-bengali-desktop
+task-bosnian-desktop
+task-brazilian-portuguese-desktop
+task-british-desktop
+task-bulgarian-desktop
+task-catalan-desktop
+task-chinese-s-desktop
+task-chinese-t-desktop
+task-croatian-desktop
+task-cyrillic-desktop
+task-czech-desktop
+task-danish-desktop
+task-dutch-desktop
+task-dzongkha-desktop
+task-esperanto-desktop
+task-estonian-desktop
+task-finnish-desktop
+task-french-desktop
+task-galician-desktop
+task-georgian-desktop
+task-german-desktop
+task-greek-desktop
+task-gujarati-desktop
+task-hebrew-desktop
+task-hindi-desktop
+task-hungarian-desktop
+task-icelandic-desktop
+task-indonesian-desktop
+task-irish-desktop
+task-italian-desktop
+task-japanese-desktop
+task-kannada-desktop
+task-kazakh-desktop
+task-khmer-desktop
+task-korean-desktop
+task-kurdish-desktop
+task-latvian-desktop
+task-lithuanian-desktop
+task-macedonian-desktop
+task-malayalam-desktop
+task-marathi-desktop
+task-nepali-desktop
+task-northern-sami-desktop
+task-norwegian-desktop
+task-persian-desktop
+task-polish-desktop
+task-portuguese-desktop
+task-punjabi-desktop
+task-romanian-desktop
+task-russian-desktop
+task-serbian-desktop
+task-sinhala-desktop
+task-slovak-desktop
+task-slovenian-desktop
+task-south-african-english-desktop
+task-spanish-desktop
+task-swedish-desktop
+task-tamil-desktop
+task-telugu-desktop
+task-thai-desktop
+task-turkish-desktop
+task-ukrainian-desktop
+task-uyghur-desktop
+task-vietnamese-desktop
+task-welsh-desktop
+task-xhosa-desktop
diff --git a/support/dktools/livesys-data/pkg_local.txt b/support/dktools/livesys-data/pkg_local.txt
new file mode 100644
index 0000000000..3d50f78c61
--- /dev/null
+++ b/support/dktools/livesys-data/pkg_local.txt
@@ -0,0 +1,23 @@
+build-essential # Package containing tools to build Debian packages
+autoconf # Create configure scripts automatically
+automake # Create Makefile.in automatically from Makefile.am
+autotools-dev # Files config.guess and config.sub
+dh-make # Create Debian package files for pure source archives
+debhelper # Tool programs for Debian package creation
+devscripts # Scripts for Debian package maintenance
+fakeroot # Wrapper to simulate access to root directory
+lintian # Debian package checker
+patch # Patch a file
+patchutils # Additional tools to work with patches
+pbuilder # Package builder
+make # Compiler control program
+gcc # GNU C compiler
+g++ # GNU C++ compiler
+zlib1g-dev # Development support for zlib
+libbz2-dev # Development support for libbz2
+libssl-dev # Development support for OpenSSL
+libdb-dev # Development support for Berkeley DB
+live-build # Components to build a live system
+debootstrap # Debian bootstrapper (create initial system)
+makedev # Create device files
+reprepro # Create apt repositories
diff --git a/support/dktools/livesys-data/pkg_xfce.txt b/support/dktools/livesys-data/pkg_xfce.txt
new file mode 100644
index 0000000000..629b4f2d3c
--- /dev/null
+++ b/support/dktools/livesys-data/pkg_xfce.txt
@@ -0,0 +1,40 @@
+tasksel # Install packages for specified tasks
+xorg # X11 windows system on a desktop
+xserver-xorg-video-all # All video output drivers
+xserver-xorg-input-all # All input device drivers
+desktop-base # Common files for desktop environments
+xdg-utils # Desktop integration programs
+avahi-daemon # Multicast service discovery
+libnss-mdns # NSS module for Multicast DNS name resolution
+anacron # Periodic maintenance jobs
+eject # Eject CD/DVD from drive
+iw # Command line program to configure WiFi
+alsa-utils # Programs to use ALSA sound system
+alsa-base # Removes kmod files
+xfwm4 # XFCE window manager
+xfconf # XFCE configuration helper program
+xfce4-settings # XFCE configuration program
+xfce4-panel # The panel in the XFCE window manager
+xfdesktop4 # XFCE desktop configuration program
+thunar # File manager
+gtk2-engines-xfce # Themes engine to use GNOME themes on XFCE
+gtk3-engines-xfce # Themes engine to use GNOME themes on XFCE
+xfce4-session # Session manager for XFCE
+xfce4-appfinder # Search for installed programs
+xfce4-mixer # Mixer program (sound?)
+libxfce4ui-utils # Help files, additional configuration programs
+thunar-volman # Volume manager for remove media in thunar
+tango-icon-theme # Icon theme
+xfce4-notifyd # Desktop notifications daemon
+xfce4-power-manager # Power manager
+lightdm # Display manager (login program)
+xfce4-goodies # Extension programs for XFCE desktop
+xfce4-terminal # Terminal emulation program
+mousepad # Graphical text editor for XFCE
+dbus-x11 # Interprocess message bus
+evince # PDF/PS viewer
+network-manager-gnome # Network manager
+synaptic # Package installation program
+iceweasel # Web browser
+system-config-printer # Printer configuration for CUPS
+gnome-orca # Screen reader
diff --git a/support/dktools/livesys-data/root-cli/usr/share/dktoolian/getty.sed b/support/dktools/livesys-data/root-cli/usr/share/dktoolian/getty.sed
new file mode 100644
index 0000000000..d1a8c9d3fd
--- /dev/null
+++ b/support/dktools/livesys-data/root-cli/usr/share/dktoolian/getty.sed
@@ -0,0 +1 @@
+/^ExecStart=/s/\-\-noclear/--autologin root --noclear/
diff --git a/support/dktools/livesys-data/root/usr/local/bin/dktoolian-etc b/support/dktools/livesys-data/root/usr/local/bin/dktoolian-etc
new file mode 100755
index 0000000000..04ee8bcbef
--- /dev/null
+++ b/support/dktools/livesys-data/root/usr/local/bin/dktoolian-etc
@@ -0,0 +1,19 @@
+#! /bin/sh
+
+[ -d /usr/share/dktoolian/etc ] || exit 0
+
+umask 022
+cd /usr/share/dktoolian/etc
+for i in `find . -type d`
+do
+ if [ ! -d /etc/$i ]
+ then
+ mkdir -p /etc/$i
+ chmod 755 /etc/$i
+ fi
+done
+for i in `find . -type f`
+do
+ cp $i /etc/$i
+done
+
diff --git a/support/dktools/livesys-data/root/usr/local/bin/dktoolian-ntp b/support/dktools/livesys-data/root/usr/local/bin/dktoolian-ntp
new file mode 100755
index 0000000000..60d395941f
--- /dev/null
+++ b/support/dktools/livesys-data/root/usr/local/bin/dktoolian-ntp
@@ -0,0 +1,2 @@
+#! /bin/sh
+cp /usr/share/dktoolian/ntp.conf.template /etc/ntp.conf
diff --git a/support/dktools/livesys-data/root/usr/share/dktoolian/etc-files.sed b/support/dktools/livesys-data/root/usr/share/dktoolian/etc-files.sed
new file mode 100644
index 0000000000..e518dce937
--- /dev/null
+++ b/support/dktools/livesys-data/root/usr/share/dktoolian/etc-files.sed
@@ -0,0 +1,2 @@
+/^[ \t]*exit[ \t][ \t]*0[ \t]*$/c/usr/local/bin/dktoolian-etc\nexit 0
+
diff --git a/support/dktools/livesys-data/root/usr/share/dktoolian/ntp.conf.template b/support/dktools/livesys-data/root/usr/share/dktoolian/ntp.conf.template
new file mode 100644
index 0000000000..ed6a32931f
--- /dev/null
+++ b/support/dktools/livesys-data/root/usr/share/dktoolian/ntp.conf.template
@@ -0,0 +1,14 @@
+driftfile /var/lib/ntp/ntp.drift
+statistics loopstats peerstats clockstats
+filegen loopstats file loopstats type day enable
+filegen peerstats file peerstats type day enable
+filegen clockstats file clockstats type day enable
+# MYSERVER
+server 0.debian.pool.ntp.org iburst
+server 1.debian.pool.ntp.org iburst
+server 2.debian.pool.ntp.org iburst
+server 3.debian.pool.ntp.org iburst
+restrict -4 default kod notrap nomodify nopeer noquery
+restrict -6 default kod notrap nomodify nopeer noquery
+restrict 127.0.0.1
+restrict ::1
diff --git a/support/dktools/livesys-data/sed_isolinux.txt b/support/dktools/livesys-data/sed_isolinux.txt
new file mode 100644
index 0000000000..d8edfcf46a
--- /dev/null
+++ b/support/dktools/livesys-data/sed_isolinux.txt
@@ -0,0 +1,2 @@
+/^[Tt][Ii][Mm][ee][Oo][Uu][Tt][ \t][ \t]*0/ctimeout 50
+
diff --git a/support/dktools/livesys-data/sed_menu.txt b/support/dktools/livesys-data/sed_menu.txt
new file mode 100644
index 0000000000..7f4f8a6814
--- /dev/null
+++ b/support/dktools/livesys-data/sed_menu.txt
@@ -0,0 +1,2 @@
+/[Ii][Nn][Cc][Ll][Uu][Dd][Ee][ \t][ \t]*[Ii][Nn][Ss][Tt][Aa][Ll][Ll]\.[Cc][Ff][Gg]/d
+
diff --git a/support/dktools/livesys-data/sed_nobeep.txt b/support/dktools/livesys-data/sed_nobeep.txt
new file mode 100644
index 0000000000..1e5b3d3cd8
--- /dev/null
+++ b/support/dktools/livesys-data/sed_nobeep.txt
@@ -0,0 +1 @@
+/^[ \t]*[Mm][Ee][Nn][Uu][ \t][ \t]*[Tt][Ii][Tt][Ll][Ee][ \t]/s/\o007//
diff --git a/support/dktools/lprngcl.c b/support/dktools/lprngcl.c
new file mode 100644
index 0000000000..a6fe3f57f0
--- /dev/null
+++ b/support/dktools/lprngcl.c
@@ -0,0 +1,1398 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: lprngcl.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#line 10 "lprngcl.ctr"
+
+/** @file lprngcl.c Lprng Cleanup.
+*/
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_MATH_H
+#ifndef MATH_H_INCLUDED
+#include <math.h>
+#define MATH_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4vers.h"
+#include "dk4str8.h"
+#include "dk4strd.h"
+#include "dk4app.h"
+#include "dk4aopt.h"
+#include "dk4enc.h"
+#include "dk4fput.h"
+#include "dk4mem.h"
+#include "dk4mema.h"
+#include "dk4fput.h"
+#include "dk4tspdk.h"
+#include "dk4sock.h"
+#include "dk4socka.h"
+#include "dk4user.h"
+#include "dk4rec.h"
+
+
+
+
+
+#line 86 "lprngcl.ctr"
+
+
+/** Buffer for request and response data.
+*/
+static char buf[4096];
+
+
+/** Current queue complete name.
+*/
+static dkChar curqueue[1024];
+
+
+/** Current user name.
+*/
+static dkChar username[1024];
+
+
+/** Queue name in 8 bit characters.
+*/
+static char queue8[1024];
+
+
+/** User name in 8 bit characters.
+*/
+static char user8[1024];
+
+
+/** Default help text, used if help text file is not found.
+*/
+static const dkChar * const lprngcl_help_text[] = {
+dkT(""),
+dkT("Clean up LPRng queues"),
+dkT(""),
+dkT("lprngcl [-t seconds] [-a] <queue>..."),
+dkT("lprngcl [--help] [--version] [--license] [--manual]"),
+dkT(""),
+dkT("Specify queues in name@host notation."),
+dkT(""),
+dkT("-t seconds\t--timeout=seconds\tTimeout for network operations."),
+dkT("-a\t\t--ascii\t\t\tServer uses ASCII, not UTF-8."),
+dkT(""),
+dkT("\t\t--help\t\t\tShow this short help text."),
+dkT("\t\t--version\t\tShow version information."),
+dkT("\t\t--license\t\tShow license information."),
+dkT("\t\t--manual\t\t*** SHOW FULL MANUAL ***"),
+dkT(""),
+NULL
+
+
+#line 134 "lprngcl.ctr"
+};
+
+
+
+/** License conditions.
+*/
+static const dkChar * const lprngcl_license_text[] = {
+dkT("This software uses code from the following projects, either directly or as"),
+dkT("a library:"),
+dkT(""),
+dkT("dktools\t\tDirk Krause's tools and libraries."),
+dkT("\t\tSee http://dktools.sourceforge.net/ for more information."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT("zlib\t\tData compression library."),
+dkT("\t\tSee http://www.zlib.net/ for more information."),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT("bzip2\t\tData compression program and library."),
+dkT("\t\tSee http://www.bzip.org/ for more information."),
+#endif
+dkT(""),
+dkT("All the licenses below apply to the program."),
+dkT("Licenses for used libraries are shown as found on my Scientific Linux 6.x"),
+dkT("computer in the /usr/share/doc directory on 2015-04-01. Check the project"),
+dkT("homepages of the used libraries for additional information and/or updated"),
+dkT("license terms."),
+dkT(""),
+dkT(""),
+dkT("DK tools and libraries license"),
+dkT("=============================="),
+dkT("Copyright (c) 2015-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above copyright notice,"),
+dkT(" this list of conditions and the following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("* Neither the name of the Dirk Krause nor the names of contributors may be"),
+dkT(" used to endorse or promote products derived from this software without"),
+dkT(" specific prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\""),
+dkT("AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED."),
+dkT(""),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,"),
+dkT("INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,"),
+dkT("BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,"),
+dkT("DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY"),
+dkT("OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,"),
+dkT("EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT(""),
+dkT("Zlib license"),
+dkT("============"),
+dkT("(C) 1995-2004 Jean-loup Gailly and Mark Adler"),
+dkT(""),
+dkT("This software is provided 'as-is', without any express or implied"),
+dkT("warranty. In no event will the authors be held liable for any damages"),
+dkT("arising from the use of this software."),
+dkT(""),
+dkT("Permission is granted to anyone to use this software for any purpose,"),
+dkT("including commercial applications, and to alter it and redistribute it"),
+dkT("freely, subject to the following restrictions:"),
+dkT(""),
+dkT("1. The origin of this software must not be misrepresented; you must not"),
+dkT(" claim that you wrote the original software. If you use this software"),
+dkT(" in a product, an acknowledgment in the product documentation would be"),
+dkT(" appreciated but is not required."),
+dkT("2. Altered source versions must be plainly marked as such, and must not be"),
+dkT(" misrepresented as being the original software."),
+dkT("3. This notice may not be removed or altered from any source distribution."),
+dkT(""),
+dkT("Jean-loup Gailly Mark Adler"),
+dkT("jloup@gzip.org madler@alumni.caltech.edu"),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT(""),
+dkT("Bzip2 and libbzip2 library license"),
+dkT("=================================="),
+dkT("This program, \"bzip2\", the associated library \"libbzip2\", and all"),
+dkT("documentation, are copyright (C) 1996-2007 Julian R Seward. All"),
+dkT("rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions"),
+dkT("are met:"),
+dkT(""),
+dkT("1. Redistributions of source code must retain the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer."),
+dkT(""),
+dkT("2. The origin of this software must not be misrepresented; you must "),
+dkT(" not claim that you wrote the original software. If you use this "),
+dkT(" software in a product, an acknowledgment in the product "),
+dkT(" documentation would be appreciated but is not required."),
+dkT(""),
+dkT("3. Altered source versions must be plainly marked as such, and must"),
+dkT(" not be misrepresented as being the original software."),
+dkT(""),
+dkT("4. The name of the author may not be used to endorse or promote "),
+dkT(" products derived from this software without specific prior written "),
+dkT(" permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS"),
+dkT("OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED"),
+dkT("WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE"),
+dkT("GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS"),
+dkT("INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,"),
+dkT("WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS"),
+dkT("SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+dkT(""),
+dkT("Julian Seward, jseward@bzip.org"),
+dkT("bzip2/libbzip2 version 1.0.5 of 10 December 2007"),
+#endif
+dkT(""),
+NULL
+
+
+#line 265 "lprngcl.ctr"
+};
+
+
+
+/** Options used by the program.
+*/
+static const dk4_option_specification_t lprngcl_options[] = {
+
+ /* Timeout for connection attempts and other network operations.
+ */
+ { dkT('t'), dkT("timeout"), DK4_OPT_ARG_DOUBLE },
+
+ /* Remote host uses ASCII encoding, not UTF-8.
+ */
+ { dkT('a'), dkT("ascii"), DK4_OPT_ARG_NONE },
+
+ /* Verbose output.
+ */
+ { dkT('v'), dkT("verbose"), DK4_OPT_ARG_NONE }
+
+};
+
+
+
+/** Constant texts used by the program, not localized.
+*/
+static const dkChar * const lprngcl_kwnl[] = {
+/* 0 */
+dkT("dktools"),
+
+/* 1 */
+dkT("lprngcl.txt"),
+
+/* 2 */
+dkT("lprngcl.str"),
+
+NULL
+
+
+#line 300 "lprngcl.ctr"
+};
+
+
+
+/** Defaults for keywords, replaced by localized version if found.
+*/
+static const dkChar * const lprngcl_kw_def[] = {
+/* 0 */
+dkT("Failed to set up signal handlers!"),
+
+/* 1 */
+dkT("Failed to restore signal handlers!"),
+
+/* 2 */
+dkT("Failed to set up text stream processor!"),
+
+/* 3 */
+dkT("Failed to construct request!\nQueue or user name too long!"),
+
+/* 4 */
+dkT("Failed to convert queue name to 8 bit text!"),
+
+/* 5 */
+dkT("No host name specified in queue!"),
+
+/* 6 */
+dkT("Queue name too long!"),
+
+/* 7 */
+dkT("Failed to obtain command line argument (bug)!"),
+
+/* 8 */
+dkT("Failed to convert user name to 8 bit text!"),
+
+/* 9 */
+dkT("Failed to find current user name!"),
+
+/* 10 */
+dkT("Queue name(s) required!"),
+
+/* 11 */
+dkT("Failed to write to standard output!"),
+
+/* 12 */
+dkT("Request:\n\""),
+
+/* 13 */
+dkT("\"."),
+
+NULL
+
+
+#line 362 "lprngcl.ctr"
+};
+
+
+
+static const char * const lprngcl_c8_kw[] = {
+/* 0 */
+" ",
+
+/* 1 */
+"\n",
+
+/* 2 */
+"all",
+
+NULL
+
+
+#line 381 "lprngcl.ctr"
+};
+
+
+/** Application object.
+*/
+static dk4_app_t *app = NULL;
+
+
+/** Message texts, changed to localized texts if possible.
+*/
+static const dkChar * const *msg = lprngcl_kw_def;
+
+
+/** Size of lprngcl_options array.
+*/
+static const size_t lprngcl_sz_options =
+sizeof(lprngcl_options)/sizeof(dk4_option_specification_t);
+
+
+/** Size of lprngcl_kw_def array.
+*/
+static size_t sz_msg = (sizeof(lprngcl_kw_def)/sizeof(DK4_PDKCHAR) - 1);
+
+
+/** Size of buffer for current queue.
+*/
+static const size_t szcurqueue = DK4_SIZEOF(curqueue,dkChar);
+
+
+/** Size of buffer.
+*/
+static size_t szbuf = sizeof(buf);
+
+
+/** Timeout (seconds) for network operations.
+*/
+static long to_secs = 0L;
+
+
+/** Timeout (microseconds) for network operations.
+*/
+static long to_usecs = 0L;
+
+
+/** Exit status code.
+*/
+static int exval = EXIT_FAILURE;
+
+
+/** Flag: Errors while writing to stdout.
+*/
+static int wrerror = 0;
+
+
+/** Flag: Remote host uses UTF-8 encoding.
+*/
+static int isUtf8 = 1;
+
+
+/** Flag: Produce verbose output.
+*/
+static int isVerbose = 0;
+
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+/** Check whether we can continue or if a signal was received.
+ @param check_pipe Flag: Check for occured SIGPIPE signal too.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(int check_pipe)
+{
+ int back = 1;
+#ifdef SIGPIPE
+ if (0 != check_pipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_int )) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+/** Use timeout value specified as double.
+ @param to Timeout for network operations.
+*/
+static
+void
+use_timeout(double to)
+{
+
+
+#line 553 "lprngcl.ctr"
+ if (0.0 > to) { to = -1.0 * to; }
+ to_secs = (long)floor(to);
+ to = to - floor(to);
+ to = to * 1000000.0;
+ to_usecs = (long)floor(to);
+
+
+#line 559 "lprngcl.ctr"
+}
+
+
+
+/** Process command line options.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+process_options(void)
+{
+ double to = 0.0;
+ int back = 1;
+
+
+#line 573 "lprngcl.ctr"
+ if (0 != dk4app_opt_is_set_short(app, dkT('t'), NULL)) {
+ if (0 != dk4app_opt_get_double_short(&to, app, dkT('t'), NULL)) {
+
+
+#line 576 "lprngcl.ctr"
+ use_timeout(to);
+ }
+ } else {
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('a'), NULL)) {
+
+
+#line 582 "lprngcl.ctr"
+ isUtf8 = 0;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('v'), NULL)) {
+
+
+#line 586 "lprngcl.ctr"
+ isVerbose = 1;
+ }
+
+
+#line 589 "lprngcl.ctr"
+ return back;
+}
+
+
+
+/** Character handler for text stream processing.
+*/
+static
+int
+lprngcl_char_handler(
+ void *obj,
+ dkChar c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_TSP_RES_OK;
+ if (0 == dk4fputc(c, stdout, NULL)) {
+ exval = EXIT_FAILURE;
+ wrerror = 1;
+ }
+ return back;
+}
+
+
+
+/** Process one request to delete print jobs.
+ @param hptr Host name pointer.
+ @param fullqueue Full queue name.
+*/
+static
+void
+process_one_delete_request(const dkChar *hptr, const dkChar *fullqueue)
+{
+ dk4_tspdk_t tspdk;
+ size_t rql;
+ size_t wrb;
+ int cc;
+ int tspok;
+ int res;
+ dk4_socket_t sock;
+
+
+#line 631 "lprngcl.ctr"
+ rql = dk4str8_len(buf);
+ sock = dk4socket_tcp_client_for_host_port_app(
+ hptr, 515, 0, to_secs, to_usecs, app
+ );
+ if (INVALID_SOCKET != sock) {
+
+#line 636 "lprngcl.ctr"
+ wrb = rql;
+ if (0 != isVerbose) {
+
+#line 638 "lprngcl.ctr"
+ if (0 == dk4fputs(fullqueue, stdout, NULL)) {
+ wrerror = 1;
+
+#line 640 "lprngcl.ctr"
+ exval = EXIT_FAILURE;
+ }
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) {
+ wrerror = 1;
+
+#line 644 "lprngcl.ctr"
+ exval = EXIT_FAILURE;
+ }
+ }
+
+#line 647 "lprngcl.ctr"
+ res = dk4socket_send_attempt_app(
+ sock, buf, &wrb, 0, to_secs, to_usecs, app, 1
+ );
+
+#line 650 "lprngcl.ctr"
+ switch (res) {
+ case DK4_SOCKET_RESULT_SUCCESS :
+ case DK4_SOCKET_RESULT_IN_PROGRESS :
+ {
+
+#line 654 "lprngcl.ctr"
+ if ((0 != isVerbose) && (DK4_SOCKET_RESULT_SUCCESS == res)) {
+
+
+#line 656 "lprngcl.ctr"
+ res = dk4socket_shutdown_app(sock, DK4_SOCKET_SHUT_WRITE, app);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+
+#line 658 "lprngcl.ctr"
+ tspok = dk4tspdk_setup_char(
+ &tspdk, NULL, lprngcl_char_handler,
+ dk4app_get_stdout_encoding(app),
+ (
+ (0 != isUtf8)
+ ? (DK4_FILE_ENCODING_UTF8)
+ : (DK4_FILE_ENCODING_ASCII)
+ ),
+ NULL
+ );
+ if (0 == tspok) {
+
+#line 669 "lprngcl.ctr"
+ /* ERROR: Failed to set up text stream processor */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 2);
+ exval = EXIT_FAILURE;
+ }
+ cc = 1;
+ do {
+ if (0 != sig_can_continue(0)) {
+
+#line 676 "lprngcl.ctr"
+ wrb = sizeof(buf);
+ res = dk4socket_recv_app(
+ sock, buf, &wrb, 0, to_secs, to_usecs, app
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+
+#line 681 "lprngcl.ctr"
+ if (0 == wrb) {
+
+#line 682 "lprngcl.ctr"
+ cc = 0;
+ } else {
+
+#line 684 "lprngcl.ctr"
+ if (0 != tspok) {
+
+#line 685 "lprngcl.ctr"
+ res = dk4tspdk_add_bytes(&tspdk,(unsigned char *)buf,wrb);
+ if (DK4_TSP_RES_OK != res) {
+
+#line 687 "lprngcl.ctr"
+ exval = EXIT_FAILURE;
+ tspok = 0;
+ }
+ }
+ }
+ } else {
+
+#line 693 "lprngcl.ctr"
+ cc = 0;
+ }
+ } else {
+
+#line 696 "lprngcl.ctr"
+ cc = -1;
+ }
+ } while(1 == cc);
+ if ((0 == cc) && (0 != tspok)) {
+
+#line 700 "lprngcl.ctr"
+ res = dk4tspdk_finish(&tspdk);
+ if (DK4_TSP_RES_OK != res) {
+
+#line 702 "lprngcl.ctr"
+ exval = EXIT_FAILURE;
+ }
+ }
+ } else {
+
+#line 706 "lprngcl.ctr"
+ exval = EXIT_FAILURE;
+ }
+ } else {
+
+#line 709 "lprngcl.ctr"
+ res = dk4socket_shutdown_app(sock, DK4_SOCKET_SHUT_WRITE, app);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+
+#line 711 "lprngcl.ctr"
+ cc = 1;
+ do {
+ if (0 != sig_can_continue(0)) {
+
+#line 714 "lprngcl.ctr"
+ wrb = sizeof(buf);
+ res = dk4socket_recv_app(
+ sock, buf, &wrb, 0, to_secs, to_usecs, app
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+
+#line 719 "lprngcl.ctr"
+ if (0 == wrb) {
+
+#line 720 "lprngcl.ctr"
+ cc = 0;
+ }
+ } else {
+
+#line 723 "lprngcl.ctr"
+ cc = 0;
+ }
+ } else {
+
+#line 726 "lprngcl.ctr"
+ cc = -1;
+ }
+ } while(1 == cc);
+ } else {
+
+#line 730 "lprngcl.ctr"
+ exval = EXIT_FAILURE;
+ }
+ }
+ } break;
+#if TRACE_DEBUG
+ default : {
+
+#line 736 "lprngcl.ctr"
+ } break;
+#endif
+ }
+ res = dk4socket_close_app(sock, app);
+ if (DK4_SOCKET_RESULT_SUCCESS != res) {
+
+#line 741 "lprngcl.ctr"
+ exval = EXIT_FAILURE;
+ }
+ } else {
+
+#line 744 "lprngcl.ctr"
+ exval = EXIT_FAILURE;
+ }
+
+
+#line 747 "lprngcl.ctr"
+}
+
+
+
+/** Send requests to delete the users print jobs.
+ @param xargc Number of queue names.
+*/
+static
+void
+send_delete_requests(int xargc)
+{
+ const dkChar *xargv = NULL; /* Current cmd line argument */
+ dkChar *hptr = NULL; /* Start of host name */
+ int res = 0; /* Text conversion result */
+ int i = 0; /* Current cmd line arg index */
+
+
+#line 763 "lprngcl.ctr"
+ if (0 != dk4user_get_logname(username, DK4_SIZEOF(username,dkChar),0, NULL)) {
+
+
+#line 765 "lprngcl.ctr"
+ if (0 != isUtf8) {
+
+#line 766 "lprngcl.ctr"
+ res = dk4recode_dk_to_any(
+ user8, sizeof(user8), DK4_ENCODING_UTF8, username,
+ dk4app_get_encoding(app), NULL
+ );
+ } else {
+
+#line 771 "lprngcl.ctr"
+ res = dk4recode_dk_to_any(
+ user8, sizeof(user8), DK4_ENCODING_ASCII, username,
+ dk4app_get_encoding(app), NULL
+ );
+ }
+ if (0 != res) {
+
+#line 777 "lprngcl.ctr"
+ exval = EXIT_SUCCESS;
+ for (i = 0; ((i < xargc) && (sig_can_continue(0))); i++) {
+
+
+#line 780 "lprngcl.ctr"
+ xargv = dk4app_get_argv(app, i);
+ if (NULL != xargv) {
+
+#line 782 "lprngcl.ctr"
+ if (0 != dk4str_cpy_s(curqueue, szcurqueue, xargv, NULL)) {
+
+
+#line 784 "lprngcl.ctr"
+ hptr = dk4str_chr(curqueue, dkT('@'));
+ if (NULL != hptr) {
+ *(hptr++) = dkT('\0');
+ hptr = dk4str_start(hptr, NULL);
+ if (NULL != hptr) {
+
+#line 789 "lprngcl.ctr"
+ if (0 != isUtf8) {
+
+#line 790 "lprngcl.ctr"
+ res = dk4recode_dk_to_any(
+ queue8, sizeof(queue8), DK4_ENCODING_UTF8, curqueue,
+ dk4app_get_encoding(app), NULL
+ );
+ } else {
+
+#line 795 "lprngcl.ctr"
+ res = dk4recode_dk_to_any(
+ queue8, sizeof(queue8), DK4_ENCODING_ASCII, curqueue,
+ dk4app_get_encoding(app), NULL
+ );
+ }
+ if (0 != res) {
+
+#line 801 "lprngcl.ctr"
+ res = 1;
+ if (0 == dk4str8_cpy_s(buf, szbuf, lprngcl_c8_kw[0], NULL)) {
+ res = 0;
+
+#line 804 "lprngcl.ctr"
+ buf[0] = '\0';
+ }
+ if (0 == dk4str8_cat_s(buf, szbuf, queue8, NULL)) {
+ res = 0;
+
+#line 808 "lprngcl.ctr"
+ }
+ if (0 == dk4str8_cat_s(buf, szbuf, lprngcl_c8_kw[0], NULL)) {
+ res = 0;
+
+#line 811 "lprngcl.ctr"
+ }
+ if (0 == dk4str8_cat_s(buf, szbuf, user8, NULL)) {
+ res = 0;
+
+#line 814 "lprngcl.ctr"
+ }
+ if (0 == dk4str8_cat_s(buf, szbuf, lprngcl_c8_kw[0], NULL)) {
+ res = 0;
+
+#line 817 "lprngcl.ctr"
+ }
+ if (0 == dk4str8_cat_s(buf, szbuf, user8, NULL)) {
+ res = 0;
+
+#line 820 "lprngcl.ctr"
+ }
+ if (0 != res) {
+
+#line 822 "lprngcl.ctr"
+ /* LOG Print removal request */
+#if DK4_CHAR_SIZE == 1
+ dk4app_log_3(app, msg, sz_msg, DK4_LL_INFO, 12, 13, buf);
+#endif
+ }
+ if (0 == dk4str8_cat_s(buf, szbuf, lprngcl_c8_kw[1], NULL)) {
+ res = 0;
+
+#line 829 "lprngcl.ctr"
+ }
+ buf[0] = 0x05;
+ if (0 != res) {
+
+#line 832 "lprngcl.ctr"
+ process_one_delete_request(hptr, xargv);
+ } else {
+
+#line 834 "lprngcl.ctr"
+ /* ERROR: Failed to construct request */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 3);
+ }
+ } else {
+
+#line 838 "lprngcl.ctr"
+ exval = EXIT_FAILURE;
+ /* ERROR: Failed to convert queue name to 8 bit text */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 4);
+ }
+ } else {
+
+#line 843 "lprngcl.ctr"
+ exval = EXIT_FAILURE;
+ /* ERROR: No host name in queue */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 5);
+ }
+ } else {
+
+#line 848 "lprngcl.ctr"
+ exval = EXIT_FAILURE;
+ /* ERROR: No host name in queue */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 5);
+ }
+ } else {
+
+#line 853 "lprngcl.ctr"
+ exval = EXIT_FAILURE;
+ /* ERROR: Queue name too long */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 6);
+ }
+ } else {
+
+#line 858 "lprngcl.ctr"
+ exval = EXIT_FAILURE;
+ /* ERROR: Failed to obtain command line argument */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 7);
+ }
+ }
+ } else {
+
+#line 864 "lprngcl.ctr"
+ /* ERROR: Failed to recode user name to 8 bit characters */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 8);
+ }
+ } else {
+
+#line 868 "lprngcl.ctr"
+ /* ERROR: Failed to find current user name */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 9);
+ }
+
+
+#line 872 "lprngcl.ctr"
+}
+
+
+
+/** The real work.
+*/
+static
+void
+run_the_functions(void)
+{
+ int xargc = 0;
+
+
+#line 884 "lprngcl.ctr"
+ if (0 != process_options()) {
+
+#line 885 "lprngcl.ctr"
+ xargc = dk4app_get_argc(app);
+ if (0 < xargc) {
+
+#line 887 "lprngcl.ctr"
+ if (0 != dk4socket_up_app(app)) {
+
+#line 888 "lprngcl.ctr"
+ send_delete_requests(xargc);
+ dk4socket_down_app(app);
+ } else {
+
+#line 891 "lprngcl.ctr"
+ exval = EXIT_FAILURE;
+ }
+ } else {
+
+#line 894 "lprngcl.ctr"
+ /* ERROR: No queues specified */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 10);
+ }
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 900 "lprngcl.ctr"
+ }
+#endif
+
+
+#line 903 "lprngcl.ctr"
+}
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+run_with_signals(void)
+{
+#ifdef SIGPIPE
+ struct sigaction opipe;
+#endif
+ struct sigaction oint;
+ struct sigaction oterm;
+#ifdef SIGPIPE
+ struct sigaction npipe;
+#endif
+ struct sigaction nint;
+ struct sigaction nterm;
+ int success = 0;
+
+
+#line 926 "lprngcl.ctr"
+#ifdef SIGPIPE
+ /* Set up signal handling for SIGPIPE.
+ */
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+
+#line 933 "lprngcl.ctr"
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+
+#line 938 "lprngcl.ctr"
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+
+#line 943 "lprngcl.ctr"
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+#endif
+
+ /* Set up signal handling for SIGINT.
+ */
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+
+#line 955 "lprngcl.ctr"
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+
+#line 960 "lprngcl.ctr"
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+
+#line 965 "lprngcl.ctr"
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+
+#line 976 "lprngcl.ctr"
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+
+#line 981 "lprngcl.ctr"
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+
+#line 986 "lprngcl.ctr"
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+
+ success = 1;
+
+#line 992 "lprngcl.ctr"
+ run_the_functions();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+
+#line 997 "lprngcl.ctr"
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+
+#line 1006 "lprngcl.ctr"
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+#ifdef SIGPIPE
+ /* Restore signal handling for SIGPIPE.
+ */
+ restore_old_pipe:
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+
+#line 1016 "lprngcl.ctr"
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+#endif
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) {
+
+#line 1026 "lprngcl.ctr"
+ exval = EXIT_FAILURE;
+ }
+
+
+#line 1029 "lprngcl.ctr"
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+run_with_signals(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+
+#line 1044 "lprngcl.ctr"
+#ifdef SIGPIPE
+ oldpipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ run_the_functions();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+#ifdef SIGPIPE
+ sigset(SIGPIPE, oldpipe);
+#endif
+
+
+#line 1056 "lprngcl.ctr"
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+run_with_signals(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+
+
+#line 1071 "lprngcl.ctr"
+#ifdef SIGPIPE
+ oldpipe = signal(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ run_the_functions();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+#ifdef SIGPIPE
+ signal(SIGPIPE, oldpipe);
+#endif
+
+
+#line 1083 "lprngcl.ctr"
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+run_with_signals(void)
+{
+
+
+#line 1092 "lprngcl.ctr"
+ run_the_functions();
+
+
+#line 1094 "lprngcl.ctr"
+}
+#endif
+#endif
+#endif
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+
+
+#line 1113 "lprngcl.ctr"
+
+
+#line 1114 "lprngcl.ctr"
+ dk4fput_initialize_stdout();
+ dk4fput_initialize_stderr();
+ app = dk4app_open_cmd(
+ argc, argv, lprngcl_options, lprngcl_sz_options,
+ lprngcl_kwnl[0], DKT_VERSION_DK,
+ lprngcl_kwnl[1], lprngcl_help_text, lprngcl_license_text
+ );
+ if (NULL != app) {
+
+#line 1122 "lprngcl.ctr"
+ sz_msg = dk4app_string_table_size(lprngcl_kw_def);
+ msg = dk4app_string_table(app, lprngcl_kwnl[2], lprngcl_kw_def);
+ if (0 != dk4app_can_run_normally(app)) {
+
+#line 1125 "lprngcl.ctr"
+ run_with_signals();
+ } else {
+
+#line 1127 "lprngcl.ctr"
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ if (0 != wrerror) {
+
+#line 1132 "lprngcl.ctr"
+ /* ERROR: Failed to write to standard output */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 11);
+ }
+ dk4app_close(app);
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 1139 "lprngcl.ctr"
+ }
+#endif
+ fflush(stdout);
+ fflush(stderr);
+ dk4fput_cleanup_stderr();
+ dk4fput_cleanup_stdout();
+
+
+#line 1146 "lprngcl.ctr"
+
+
+#line 1147 "lprngcl.ctr"
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/lprngcl.ctr b/support/dktools/lprngcl.ctr
new file mode 100644
index 0000000000..5d73928ccc
--- /dev/null
+++ b/support/dktools/lprngcl.ctr
@@ -0,0 +1,1149 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+
+
+%% module
+
+/** @file lprngcl.c Lprng Cleanup.
+*/
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_MATH_H
+#ifndef MATH_H_INCLUDED
+#include <math.h>
+#define MATH_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4vers.h"
+#include "dk4str8.h"
+#include "dk4strd.h"
+#include "dk4app.h"
+#include "dk4aopt.h"
+#include "dk4enc.h"
+#include "dk4fput.h"
+#include "dk4mem.h"
+#include "dk4mema.h"
+#include "dk4fput.h"
+#include "dk4tspdk.h"
+#include "dk4sock.h"
+#include "dk4socka.h"
+#include "dk4user.h"
+#include "dk4rec.h"
+
+
+
+$!trace-include
+
+
+/** Buffer for request and response data.
+*/
+static char buf[4096];
+
+
+/** Current queue complete name.
+*/
+static dkChar curqueue[1024];
+
+
+/** Current user name.
+*/
+static dkChar username[1024];
+
+
+/** Queue name in 8 bit characters.
+*/
+static char queue8[1024];
+
+
+/** User name in 8 bit characters.
+*/
+static char user8[1024];
+
+
+/** Default help text, used if help text file is not found.
+*/
+static const dkChar * const lprngcl_help_text[] = {
+$!text macro=dkT,preprocessor
+
+Clean up LPRng queues
+
+lprngcl [-t seconds] [-a] <queue>...
+lprngcl [--help] [--version] [--license] [--manual]
+
+Specify queues in name@host notation.
+
+-t seconds --timeout=seconds Timeout for network operations.
+-a --ascii Server uses ASCII, not UTF-8.
+
+ --help Show this short help text.
+ --version Show version information.
+ --license Show license information.
+ --manual *** SHOW FULL MANUAL ***
+
+$!end
+};
+
+
+
+/** License conditions.
+*/
+static const dkChar * const lprngcl_license_text[] = {
+$!text macro=dkT,preprocessor
+This software uses code from the following projects, either directly or as
+a library:
+
+dktools Dirk Krause's tools and libraries.
+ See http://dktools.sourceforge.net/ for more information.
+#if DK4_HAVE_ZLIB_H
+
+zlib Data compression library.
+ See http://www.zlib.net/ for more information.
+#endif
+#if DK4_HAVE_BZLIB_H
+
+bzip2 Data compression program and library.
+ See http://www.bzip.org/ for more information.
+#endif
+
+All the licenses below apply to the program.
+Licenses for used libraries are shown as found on my Scientific Linux 6.x
+computer in the /usr/share/doc directory on 2015-04-01. Check the project
+homepages of the used libraries for additional information and/or updated
+license terms.
+
+
+DK tools and libraries license
+==============================
+Copyright (c) 2015-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#if DK4_HAVE_ZLIB_H
+
+
+Zlib license
+============
+(C) 1995-2004 Jean-loup Gailly and Mark Adler
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+
+Jean-loup Gailly Mark Adler
+jloup@gzip.org madler@alumni.caltech.edu
+#endif
+#if DK4_HAVE_BZLIB_H
+
+
+Bzip2 and libbzip2 library license
+==================================
+This program, "bzip2", the associated library "libbzip2", and all
+documentation, are copyright (C) 1996-2007 Julian R Seward. All
+rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+3. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Julian Seward, jseward@bzip.org
+bzip2/libbzip2 version 1.0.5 of 10 December 2007
+#endif
+
+$!end
+};
+
+
+
+/** Options used by the program.
+*/
+static const dk4_option_specification_t lprngcl_options[] = {
+
+ /* Timeout for connection attempts and other network operations.
+ */
+ { dkT('t'), dkT("timeout"), DK4_OPT_ARG_DOUBLE },
+
+ /* Remote host uses ASCII encoding, not UTF-8.
+ */
+ { dkT('a'), dkT("ascii"), DK4_OPT_ARG_NONE },
+
+ /* Verbose output.
+ */
+ { dkT('v'), dkT("verbose"), DK4_OPT_ARG_NONE }
+
+};
+
+
+
+/** Constant texts used by the program, not localized.
+*/
+static const dkChar * const lprngcl_kwnl[] = {
+$!string-table macro=dkT
+#
+# 0 1 2 Group, help text file, string table file
+#
+dktools
+lprngcl.txt
+lprngcl.str
+$!end
+};
+
+
+
+/** Defaults for keywords, replaced by localized version if found.
+*/
+static const dkChar * const lprngcl_kw_def[] = {
+$!string-table macro=dkT
+#
+# 0 ERROR: Failed to set up signal handlers!
+#
+Failed to set up signal handlers!
+#
+# 1 ERROR: Failed to restore signal handlers!
+#
+Failed to restore signal handlers!
+#
+# 2 ERROR: Failed to set up text stream processor!
+#
+Failed to set up text stream processor!
+#
+# 3 ERROR: Failed to construct request!
+#
+Failed to construct request!\nQueue or user name too long!
+#
+# 4 ERROR: Failed to convert queue name to 8 bit text!
+#
+Failed to convert queue name to 8 bit text!
+#
+# 5 ERROR: No host name specified in queue!
+#
+No host name specified in queue!
+#
+# 6 ERROR: Queue name too long!
+#
+Queue name too long!
+#
+# 7 ERROR: Failed to obtain command line argument (bug)!
+#
+Failed to obtain command line argument (bug)!
+#
+# 8 ERROR: Failed to convert user name to 8 bit text!
+#
+Failed to convert user name to 8 bit text!
+#
+# 9 ERROR: Failed to find current user name!
+#
+Failed to find current user name!
+#
+# 10 ERROR: Queue name(s) required!
+#
+Queue name(s) required!
+#
+# 11 ERROR: Failed to write to standard output!
+#
+Failed to write to standard output!
+#
+# 12 13
+#
+Request:\n"
+".
+$!end
+};
+
+
+
+static const char * const lprngcl_c8_kw[] = {
+$!string-table
+#
+# 0 Space
+#
+
+#
+# 1 Newline
+#
+\n
+#
+# 2 all print jobs
+#
+all
+$!end
+};
+
+
+/** Application object.
+*/
+static dk4_app_t *app = NULL;
+
+
+/** Message texts, changed to localized texts if possible.
+*/
+static const dkChar * const *msg = lprngcl_kw_def;
+
+
+/** Size of lprngcl_options array.
+*/
+static const size_t lprngcl_sz_options =
+sizeof(lprngcl_options)/sizeof(dk4_option_specification_t);
+
+
+/** Size of lprngcl_kw_def array.
+*/
+static size_t sz_msg = (sizeof(lprngcl_kw_def)/sizeof(DK4_PDKCHAR) - 1);
+
+
+/** Size of buffer for current queue.
+*/
+static const size_t szcurqueue = DK4_SIZEOF(curqueue,dkChar);
+
+
+/** Size of buffer.
+*/
+static size_t szbuf = sizeof(buf);
+
+
+/** Timeout (seconds) for network operations.
+*/
+static long to_secs = 0L;
+
+
+/** Timeout (microseconds) for network operations.
+*/
+static long to_usecs = 0L;
+
+
+/** Exit status code.
+*/
+static int exval = EXIT_FAILURE;
+
+
+/** Flag: Errors while writing to stdout.
+*/
+static int wrerror = 0;
+
+
+/** Flag: Remote host uses UTF-8 encoding.
+*/
+static int isUtf8 = 1;
+
+
+/** Flag: Produce verbose output.
+*/
+static int isVerbose = 0;
+
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+/** Check whether we can continue or if a signal was received.
+ @param check_pipe Flag: Check for occured SIGPIPE signal too.
+ @return 1 if the program can continue, 0 if a signal was received.
+*/
+static
+int
+sig_can_continue(int check_pipe)
+{
+ int back = 1;
+#ifdef SIGPIPE
+ if (0 != check_pipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ if (0 != sig_read_atomic(&sig_had_int )) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ return back;
+}
+
+
+
+/** Use timeout value specified as double.
+ @param to Timeout for network operations.
+*/
+static
+void
+use_timeout(double to)
+{
+ $? "+ use_timeout %lg", to
+ if (0.0 > to) { to = -1.0 * to; }
+ to_secs = (long)floor(to);
+ to = to - floor(to);
+ to = to * 1000000.0;
+ to_usecs = (long)floor(to);
+ $? "- use_timeout secs=%ld usecs=%ld", to_secs, to_usecs
+}
+
+
+
+/** Process command line options.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+process_options(void)
+{
+ double to = 0.0;
+ int back = 1;
+ $? "+ process_options"
+ if (0 != dk4app_opt_is_set_short(app, dkT('t'), NULL)) {
+ if (0 != dk4app_opt_get_double_short(&to, app, dkT('t'), NULL)) {
+ $? ". timeout"
+ use_timeout(to);
+ }
+ } else {
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('a'), NULL)) {
+ $? ". ASCII"
+ isUtf8 = 0;
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('v'), NULL)) {
+ $? ". verbose"
+ isVerbose = 1;
+ }
+ $? "- process_options %d", back
+ return back;
+}
+
+
+
+/** Character handler for text stream processing.
+*/
+static
+int
+lprngcl_char_handler(
+ void *obj,
+ dkChar c,
+ dk4_text_stream_position_t *pos,
+ dk4_er_t *erp
+)
+{
+ int back = DK4_TSP_RES_OK;
+ if (0 == dk4fputc(c, stdout, NULL)) {
+ exval = EXIT_FAILURE;
+ wrerror = 1;
+ }
+ return back;
+}
+
+
+
+/** Process one request to delete print jobs.
+ @param hptr Host name pointer.
+ @param fullqueue Full queue name.
+*/
+static
+void
+process_one_delete_request(const dkChar *hptr, const dkChar *fullqueue)
+{
+ dk4_tspdk_t tspdk;
+ size_t rql;
+ size_t wrb;
+ int cc;
+ int tspok;
+ int res;
+ dk4_socket_t sock;
+ $? "+ process_one_delete_request"
+ rql = dk4str8_len(buf);
+ sock = dk4socket_tcp_client_for_host_port_app(
+ hptr, 515, 0, to_secs, to_usecs, app
+ );
+ if (INVALID_SOCKET != sock) { $? ". socket"
+ wrb = rql;
+ if (0 != isVerbose) { $? ". verbose"
+ if (0 == dk4fputs(fullqueue, stdout, NULL)) {
+ wrerror = 1; $? "! fputs"
+ exval = EXIT_FAILURE;
+ }
+ if (0 == dk4fputc(dkT('\n'), stdout, NULL)) {
+ wrerror = 1; $? "! fputc"
+ exval = EXIT_FAILURE;
+ }
+ } $? ". attempt send"
+ res = dk4socket_send_attempt_app(
+ sock, buf, &wrb, 0, to_secs, to_usecs, app, 1
+ ); $? ". attempt send done"
+ switch (res) {
+ case DK4_SOCKET_RESULT_SUCCESS :
+ case DK4_SOCKET_RESULT_IN_PROGRESS :
+ { $? ". send ok"
+ if ((0 != isVerbose) && (DK4_SOCKET_RESULT_SUCCESS == res)) {
+ $? ". verbose"
+ res = dk4socket_shutdown_app(sock, DK4_SOCKET_SHUT_WRITE, app);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) { $? ". shutdown"
+ tspok = dk4tspdk_setup_char(
+ &tspdk, NULL, lprngcl_char_handler,
+ dk4app_get_stdout_encoding(app),
+ (
+ (0 != isUtf8)
+ ? (DK4_FILE_ENCODING_UTF8)
+ : (DK4_FILE_ENCODING_ASCII)
+ ),
+ NULL
+ );
+ if (0 == tspok) { $? "! text processing"
+ /* ERROR: Failed to set up text stream processor */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 2);
+ exval = EXIT_FAILURE;
+ }
+ cc = 1;
+ do {
+ if (0 != sig_can_continue(0)) { $? ". loop pass"
+ wrb = sizeof(buf);
+ res = dk4socket_recv_app(
+ sock, buf, &wrb, 0, to_secs, to_usecs, app
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) { $? ". recv"
+ if (0 == wrb) { $? ". 0 bytes"
+ cc = 0;
+ } else { $? ". data found"
+ if (0 != tspok) { $? ". text processing"
+ res = dk4tspdk_add_bytes(&tspdk,(unsigned char *)buf,wrb);
+ if (DK4_TSP_RES_OK != res) { $? "! text processing"
+ exval = EXIT_FAILURE;
+ tspok = 0;
+ }
+ }
+ }
+ } else { $? "! recv"
+ cc = 0;
+ }
+ } else { $? ". signal"
+ cc = -1;
+ }
+ } while(1 == cc);
+ if ((0 == cc) && (0 != tspok)) { $? ". regular loop end"
+ res = dk4tspdk_finish(&tspdk);
+ if (DK4_TSP_RES_OK != res) { $? "! text processing"
+ exval = EXIT_FAILURE;
+ }
+ }
+ } else { $? "! shutdown"
+ exval = EXIT_FAILURE;
+ }
+ } else { $? ". not verbose"
+ res = dk4socket_shutdown_app(sock, DK4_SOCKET_SHUT_WRITE, app);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) { $? ". shutdown"
+ cc = 1;
+ do {
+ if (0 != sig_can_continue(0)) { $? ". loop pass"
+ wrb = sizeof(buf);
+ res = dk4socket_recv_app(
+ sock, buf, &wrb, 0, to_secs, to_usecs, app
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) { $? ". recv"
+ if (0 == wrb) { $? ". 0 bytes"
+ cc = 0;
+ }
+ } else { $? "! recv"
+ cc = 0;
+ }
+ } else { $? "! signal"
+ cc = -1;
+ }
+ } while(1 == cc);
+ } else { $? "! shutdown"
+ exval = EXIT_FAILURE;
+ }
+ }
+ } break;
+#if TRACE_DEBUG
+ default : { $? "! send failed"
+ } break;
+#endif
+ }
+ res = dk4socket_close_app(sock, app);
+ if (DK4_SOCKET_RESULT_SUCCESS != res) { $? "! close"
+ exval = EXIT_FAILURE;
+ }
+ } else { $? "! socket"
+ exval = EXIT_FAILURE;
+ }
+ $? "- process_one_delete_request"
+}
+
+
+
+/** Send requests to delete the users print jobs.
+ @param xargc Number of queue names.
+*/
+static
+void
+send_delete_requests(int xargc)
+{
+ const dkChar *xargv = NULL; /* Current cmd line argument */
+ dkChar *hptr = NULL; /* Start of host name */
+ int res = 0; /* Text conversion result */
+ int i = 0; /* Current cmd line arg index */
+ $? "+ send_delete_requests %d", xargc
+ if (0 != dk4user_get_logname(username, DK4_SIZEOF(username,dkChar),0, NULL)) {
+ $? ". logname = \"%!ds\"", username
+ if (0 != isUtf8) { $? ". UTF-8"
+ res = dk4recode_dk_to_any(
+ user8, sizeof(user8), DK4_ENCODING_UTF8, username,
+ dk4app_get_encoding(app), NULL
+ );
+ } else { $? ". ASCII"
+ res = dk4recode_dk_to_any(
+ user8, sizeof(user8), DK4_ENCODING_ASCII, username,
+ dk4app_get_encoding(app), NULL
+ );
+ }
+ if (0 != res) { $? ". conversion to 8 bit text"
+ exval = EXIT_SUCCESS;
+ for (i = 0; ((i < xargc) && (sig_can_continue(0))); i++) {
+ $? ". pass %d", i
+ xargv = dk4app_get_argv(app, i);
+ if (NULL != xargv) { $? ". argv = \"%!ds\"", xargv
+ if (0 != dk4str_cpy_s(curqueue, szcurqueue, xargv, NULL)) {
+ $? ". copied"
+ hptr = dk4str_chr(curqueue, dkT('@'));
+ if (NULL != hptr) {
+ *(hptr++) = dkT('\0');
+ hptr = dk4str_start(hptr, NULL);
+ if (NULL != hptr) { $? ". host = \"%!ds\"", hptr
+ if (0 != isUtf8) { $? ". UTF-8"
+ res = dk4recode_dk_to_any(
+ queue8, sizeof(queue8), DK4_ENCODING_UTF8, curqueue,
+ dk4app_get_encoding(app), NULL
+ );
+ } else { $? ". ASCII"
+ res = dk4recode_dk_to_any(
+ queue8, sizeof(queue8), DK4_ENCODING_ASCII, curqueue,
+ dk4app_get_encoding(app), NULL
+ );
+ }
+ if (0 != res) { $? ". conversion to 8 bit text"
+ res = 1;
+ if (0 == dk4str8_cpy_s(buf, szbuf, lprngcl_c8_kw[0], NULL)) {
+ res = 0; $? "! request construction"
+ buf[0] = '\0';
+ }
+ if (0 == dk4str8_cat_s(buf, szbuf, queue8, NULL)) {
+ res = 0; $? "! request construction"
+ }
+ if (0 == dk4str8_cat_s(buf, szbuf, lprngcl_c8_kw[0], NULL)) {
+ res = 0; $? "! request construction"
+ }
+ if (0 == dk4str8_cat_s(buf, szbuf, user8, NULL)) {
+ res = 0; $? "! request construction"
+ }
+ if (0 == dk4str8_cat_s(buf, szbuf, lprngcl_c8_kw[0], NULL)) {
+ res = 0; $? "! request construction"
+ }
+ if (0 == dk4str8_cat_s(buf, szbuf, user8, NULL)) {
+ res = 0; $? "! request construction"
+ }
+ if (0 != res) { $? ". request=\"%!8s\"", buf
+ /* LOG Print removal request */
+#if DK4_CHAR_SIZE == 1
+ dk4app_log_3(app, msg, sz_msg, DK4_LL_INFO, 12, 13, buf);
+#endif
+ }
+ if (0 == dk4str8_cat_s(buf, szbuf, lprngcl_c8_kw[1], NULL)) {
+ res = 0; $? "! request construction"
+ }
+ buf[0] = 0x05;
+ if (0 != res) { $? ". process rq"
+ process_one_delete_request(hptr, xargv);
+ } else { $? "! failed to construct rq"
+ /* ERROR: Failed to construct request */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 3);
+ }
+ } else { $? "! conversion to 8 bit text"
+ exval = EXIT_FAILURE;
+ /* ERROR: Failed to convert queue name to 8 bit text */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 4);
+ }
+ } else { $? "! no host name in queue"
+ exval = EXIT_FAILURE;
+ /* ERROR: No host name in queue */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 5);
+ }
+ } else { $? "! no host name in queue"
+ exval = EXIT_FAILURE;
+ /* ERROR: No host name in queue */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 5);
+ }
+ } else { $? "! buffer too small"
+ exval = EXIT_FAILURE;
+ /* ERROR: Queue name too long */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 6);
+ }
+ } else { $? "! bug, no argv"
+ exval = EXIT_FAILURE;
+ /* ERROR: Failed to obtain command line argument */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 7);
+ }
+ }
+ } else { $? "! conversion to 8 bit text"
+ /* ERROR: Failed to recode user name to 8 bit characters */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 8);
+ }
+ } else { $? "! user name"
+ /* ERROR: Failed to find current user name */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 9);
+ }
+ $? "- send_delete_requests"
+}
+
+
+
+/** The real work.
+*/
+static
+void
+run_the_functions(void)
+{
+ int xargc = 0;
+ $? "+ run_the_functions"
+ if (0 != process_options()) { $? ". option processing ok"
+ xargc = dk4app_get_argc(app);
+ if (0 < xargc) { $? ". cmd line arguments"
+ if (0 != dk4socket_up_app(app)) { $? ". socket subsys up"
+ send_delete_requests(xargc);
+ dk4socket_down_app(app);
+ } else { $? "! socket subsys"
+ exval = EXIT_FAILURE;
+ }
+ } else { $? "! no cmd line arguments"
+ /* ERROR: No queues specified */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 10);
+ }
+ }
+#if TRACE_DEBUG
+ else { $? "! option processing failed"
+ }
+#endif
+ $? "- run_the_functions"
+}
+
+
+
+#if DK4_HAVE_SIGACTION
+/** Set signal handlers and run.
+*/
+static
+void
+run_with_signals(void)
+{
+#ifdef SIGPIPE
+ struct sigaction opipe;
+#endif
+ struct sigaction oint;
+ struct sigaction oterm;
+#ifdef SIGPIPE
+ struct sigaction npipe;
+#endif
+ struct sigaction nint;
+ struct sigaction nterm;
+ int success = 0;
+ $? "+ run_with_signals DK4_HAVE_SIGACTION"
+#ifdef SIGPIPE
+ /* Set up signal handling for SIGPIPE.
+ */
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) { $? "! pipe sigemtpyset"
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) { $? "! pipe sigaddset"
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) { $? "! pipe sigaction"
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+ goto finished;
+ }
+#endif
+
+ /* Set up signal handling for SIGINT.
+ */
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) { $? "! int sigemptyset"
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) { $? "! int sigaddset"
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) { $? "! int sigaction"
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_pipe;
+ }
+
+ /* Set up signal handling for SIGTERM
+ */
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) { $? "! term sigemptyset"
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) { $? "! term sigaddset"
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) { $? "! term sigaction"
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+ goto restore_old_int;
+ }
+
+ success = 1; $? ". signals ok"
+ run_the_functions();
+
+ /* Restore signal handling for SIGTERM.
+ */
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) { $? "! term sigaction"
+ /* ERROR: Failed to restore old SIGTERM settings */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+ /* Restore signal handling for SIGINT.
+ */
+ restore_old_int:
+ if (0 != sigaction(SIGINT, &oint, NULL)) { $? "! int sigaction"
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+
+#ifdef SIGPIPE
+ /* Restore signal handling for SIGPIPE.
+ */
+ restore_old_pipe:
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) { $? "! pipe sigaction"
+ /* ERROR: Failed to restore old SIGPIPE settings */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 1);
+ success = 0;
+ }
+#endif
+
+ /* Set exit status code if error occured.
+ */
+ finished:
+ if (0 == success) { $? "! errors occured"
+ exval = EXIT_FAILURE;
+ }
+ $? "- run_with_signals DK4_HAVE_SIGACTION"
+}
+#else
+#if DK4_HAVE_SIGSET
+/** Set signal handlers and run.
+*/
+static
+void
+run_with_signals(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+ $? "+ run_with_signals DK4_HAVE_SIGSET"
+#ifdef SIGPIPE
+ oldpipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = sigset(SIGINT, sig_handler_int);
+ oldterm = sigset(SIGTERM, sig_handler_term);
+ run_the_functions();
+ sigset(SIGTERM, oldterm);
+ sigset(SIGINT, oldint);
+#ifdef SIGPIPE
+ sigset(SIGPIPE, oldpipe);
+#endif
+ $? "- run_with_signals DK4_HAVE_SIGSET"
+}
+#else
+#if DK4_HAVE_SIGNAL
+/** Set signal handlers and run.
+*/
+static
+void
+run_with_signals(void)
+{
+#ifdef SIGPIPE
+ dk4_sig_handler_t *oldpipe = NULL;
+#endif
+ dk4_sig_handler_t *oldint = NULL;
+ dk4_sig_handler_t *oldterm = NULL;
+ $? "+ run_with_signals DK4_HAVE_SIGNAL"
+#ifdef SIGPIPE
+ oldpipe = signal(SIGPIPE, sig_handler_pipe);
+#endif
+ oldint = signal(SIGINT, sig_handler_int);
+ oldterm = signal(SIGTERM, sig_handler_term);
+ run_the_functions();
+ signal(SIGTERM, oldterm);
+ signal(SIGINT, oldint);
+#ifdef SIGPIPE
+ signal(SIGPIPE, oldpipe);
+#endif
+ $? "- run_with_signals DK4_HAVE_SIGNAL"
+}
+#else
+/** Set signal handlers and run.
+*/
+static
+void
+run_with_signals(void)
+{
+ $? "+ run_with_signals NO SIGNALS"
+ run_the_functions();
+ $? "- run_with_signals NO SIGNALS"
+}
+#endif
+#endif
+#endif
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ $!trace-init lprngcl.deb
+ $? "+ main"
+ dk4fput_initialize_stdout();
+ dk4fput_initialize_stderr();
+ app = dk4app_open_cmd(
+ argc, argv, lprngcl_options, lprngcl_sz_options,
+ lprngcl_kwnl[0], DKT_VERSION_DK,
+ lprngcl_kwnl[1], lprngcl_help_text, lprngcl_license_text
+ );
+ if (NULL != app) { $? ". app"
+ sz_msg = dk4app_string_table_size(lprngcl_kw_def);
+ msg = dk4app_string_table(app, lprngcl_kwnl[2], lprngcl_kw_def);
+ if (0 != dk4app_can_run_normally(app)) { $? ". run normally"
+ run_with_signals();
+ } else { $? ". help, version, license"
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ if (0 != wrerror) { $? "! stdout write error"
+ /* ERROR: Failed to write to standard output */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 11);
+ }
+ dk4app_close(app);
+ }
+#if TRACE_DEBUG
+ else { $? "! app"
+ }
+#endif
+ fflush(stdout);
+ fflush(stderr);
+ dk4fput_cleanup_stderr();
+ dk4fput_cleanup_stdout();
+ $? "- main %d", exval
+ $!trace-end
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/lprngcl.rc b/support/dktools/lprngcl.rc
new file mode 100644
index 0000000000..dfaf4e8272
--- /dev/null
+++ b/support/dktools/lprngcl.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "LPRng print queue cleaner\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "LPRng print queue cleaner\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "lprngcl\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/makefile.vc b/support/dktools/makefile.vc
new file mode 100644
index 0000000000..91d6a1fdbc
--- /dev/null
+++ b/support/dktools/makefile.vc
@@ -0,0 +1,1342 @@
+
+!include "conf.vc"
+!include "translate.vc"
+
+!IF "$(CONF_GUI)" == "yes"
+
+LIBDK4WXOBJ= \
+ Dk4WxControl.obj \
+ Dk4WxProgressDialog.obj \
+ Dk4WxFrame.obj \
+ Dk4WxHelpController.obj \
+ Dk4WxAutostartController.obj \
+ Dk4WxApplicationHelper.obj \
+ dk4wxpref.obj \
+ dk4wxstt.obj \
+ dk4recwx.obj \
+ dk4tspwx.obj \
+ dk4strx.obj \
+ dk4maoxdbl.obj \
+ dk4maixdbl.obj \
+ dk4maixdic.obj \
+ dk4maixdis.obj \
+ dk4maixdii.obj \
+ dk4maixdmi.obj \
+ dk4maixdli.obj \
+ dk4maixdil.obj \
+ dk4maixddi.obj \
+ dk4maixduc.obj \
+ dk4maixdus.obj \
+ dk4maixdui.obj \
+ dk4maixdmu.obj \
+ dk4maixdlu.obj \
+ dk4maixdul.obj \
+ dk4maixdsz.obj \
+ dk4maixddu.obj \
+ dk4maoxd.obj
+
+!ELSE
+
+LIBDK4WXOBJ=
+
+!ENDIF
+
+LIBDK4SOCKAOBJ= \
+ dk4socka09.obj \
+ dk4socka08.obj \
+ dk4socka07.obj \
+ dk4socka06.obj \
+ dk4socka05.obj \
+ dk4socka04.obj \
+ dk4socka03.obj \
+ dk4socka02.obj \
+ dk4socka01.obj
+
+LIBDK4SOCKOBJ= \
+ dk4sock37.obj \
+ dk4sock36.obj \
+ dk4sock35.obj \
+ dk4sock34.obj \
+ dk4sock33.obj \
+ dk4sock32.obj \
+ dk4sock31.obj \
+ dk4sock30.obj \
+ dk4sock29.obj \
+ dk4sock28.obj \
+ dk4sock27.obj \
+ dk4sock26.obj \
+ dk4sock25.obj \
+ dk4sock24.obj \
+ dk4sock23.obj \
+ dk4sock22.obj \
+ dk4sock21.obj \
+ dk4sock20.obj \
+ dk4sock19.obj \
+ dk4sock18.obj \
+ dk4sock17.obj \
+ dk4sock16.obj \
+ dk4sock15.obj \
+ dk4sock14.obj \
+ dk4sock13.obj \
+ dk4sock12.obj \
+ dk4sock11.obj \
+ dk4sock10.obj \
+ dk4sock09.obj \
+ dk4sock08.obj \
+ dk4sock07.obj \
+ dk4sock06.obj \
+ dk4sock05.obj \
+ dk4sock04.obj \
+ dk4sock03.obj \
+ dk4sock02.obj \
+ dk4sock01.obj
+
+LIBDK4LATOBJ= \
+ dk4uc2l.obj
+
+LIBDK4APPOBJ= \
+ dk4papea.obj \
+ dk4fdrda.obj \
+ dk4fdrde.obj \
+ dk4fdwre.obj \
+ dk4mema.obj \
+ dk4fopda.obj \
+ dk4appargs.obj \
+ dk4appop.obj \
+ dk4appmkdh.obj \
+ dk4appstt.obj \
+ dk4appenc.obj \
+ dk4aopt01.obj \
+ dk4aopt02.obj \
+ dk4aopt03.obj \
+ dk4aopt04.obj \
+ dk4aopt05.obj \
+ dk4aopt06.obj \
+ dk4aopt07.obj \
+ dk4aopt08.obj \
+ dk4aopt09.obj \
+ dk4aopt10.obj \
+ dk4aopt11.obj \
+ dk4aopt12.obj \
+ dk4aopt13.obj \
+ dk4aopt14.obj \
+ dk4aopt15.obj \
+ dk4aopt16.obj \
+ dk4appfs03.obj \
+ dk4appfs04.obj \
+ dk4appfs01.obj \
+ dk4appfs02.obj \
+ dk4appfne.obj \
+ dk4dira.obj \
+ dk4fileia.obj \
+ dk4appdeltree.obj \
+ dk4appdeldir.obj \
+ dk4appdelfile.obj \
+ dk4applog.obj \
+ dk4apref.obj \
+ dk4aprgs.obj \
+ dk4apphlv.obj \
+ dk4strda.obj
+
+LIBDK4MDRNDOBJ= \
+ dk4md.obj
+
+LIBDK4DBIAOBJ= \
+ dk4dbia.obj
+
+LIBDK4DBIOBJ= \
+ dk4dbit8.obj \
+ dk4dbitw.obj \
+ dk4dbit.obj \
+ dk4dbi.obj
+
+LIBDK4COBJ= \
+ dk4font.obj \
+ dk4paper.obj \
+ dk4mdch.obj \
+ dk4binenc.obj \
+ dk4stt.obj \
+ dk4opt.obj \
+ dk4opt01.obj \
+ dk4opt02.obj \
+ dk4opt03.obj \
+ dk4opt04.obj \
+ dk4opt05.obj \
+ dk4opt06.obj \
+ dk4opt07.obj \
+ dk4pref.obj \
+ dk4fs.obj \
+ dk4tspdk.obj \
+ dk4tsp32.obj \
+ dk4tsp16.obj \
+ dk4tsp08.obj \
+ dk4strmco.obj \
+ dk4lzwe.obj \
+ dk4mbstrm.obj \
+ dk4membs.obj \
+ dk4membf.obj \
+ dk4membuf.obj \
+ dk4strmu.obj \
+ dk4strms.obj \
+ dk4strmw.obj \
+ dk4strmr.obj \
+ dk4strmf.obj \
+ dk4strmh.obj \
+ dk4strmg.obj \
+ dk4strmb.obj \
+ dk4strmodk.obj \
+ dk4strmo08.obj \
+ dk4strmo16.obj \
+ dk4strmo32.obj \
+ dk4c8dbl.obj \
+ dk4strm.obj \
+ dk4fput.obj \
+ dk4svbuf.obj \
+ dk4fopd.obj \
+ dk4fopwc.obj \
+ dk4fopc8.obj \
+ dk4sto.obj \
+ dk4exepd.obj \
+ dk4exepw.obj \
+ dk4exep8.obj \
+ dk4pathd.obj \
+ dk4pathw.obj \
+ dk4path8.obj \
+ dk4symlink.obj \
+ dk4fileiu.obj \
+ dk4fileigd.obj \
+ dk4fileigw.obj \
+ dk4fileig8.obj \
+ dk4filei.obj \
+ dk4fileid.obj \
+ dk4fileiw.obj \
+ dk4filei8.obj \
+ dk4filed.obj \
+ dk4filew.obj \
+ dk4file8.obj \
+ dk4mm.obj \
+ dk4stat.obj \
+ dk4statd.obj \
+ dk4statw.obj \
+ dk4stat8.obj \
+ dk4enc.obj \
+ dk4dbldk.obj \
+ dk4dblwc.obj \
+ dk4dblc8.obj \
+ dk4bom.obj \
+ dk4rec25.obj \
+ dk4rec24.obj \
+ dk4rec23.obj \
+ dk4rec22.obj \
+ dk4rec21.obj \
+ dk4rec20.obj \
+ dk4rec19.obj \
+ dk4rec18.obj \
+ dk4rec17.obj \
+ dk4rec16.obj \
+ dk4rec15.obj \
+ dk4rec14.obj \
+ dk4rec13.obj \
+ dk4rec12.obj \
+ dk4rec11.obj \
+ dk4rec10.obj \
+ dk4rec09.obj \
+ dk4rec08.obj \
+ dk4rec07.obj \
+ dk4rec06.obj \
+ dk4rec05.obj \
+ dk4rec04.obj \
+ dk4rec03.obj \
+ dk4rec02.obj \
+ dk4rec01.obj \
+ dk4ansi.obj \
+ dk4utf8.obj \
+ dk4utf16.obj \
+ dk4c32.obj \
+ dk4istty.obj \
+ dk4fd.obj \
+ dk4hnamed.obj \
+ dk4hnamew.obj \
+ dk4hname8.obj \
+ dk4user.obj \
+ dk4mkdh.obj \
+ dk4mkdh8.obj \
+ dk4mkdhw.obj \
+ dk4deldir.obj \
+ dk4deldirwc.obj \
+ dk4deldir08.obj \
+ dk4ufi.obj \
+ dk4ufiwc.obj \
+ dk4ufi08.obj \
+ dk4fne.obj \
+ dk4fnewc.obj \
+ dk4fne08.obj \
+ dk4getcwdd.obj \
+ dk4getcwdw.obj \
+ dk4getcwd8.obj \
+ dk4dir.obj \
+ dk4dirwc.obj \
+ dk4dir08.obj \
+ dk4delfile.obj \
+ dk4delfilewc.obj \
+ dk4delfile08.obj \
+ dk4ftimewc.obj \
+ dk4ftimedk.obj \
+ dk4ftime.obj \
+ dk4ctime.obj \
+ dk4time.obj \
+ dk4timedk.obj \
+ dk4timewc.obj \
+ dk4time08.obj \
+ dk4loc.obj \
+ dk4wregd.obj \
+ dk4wregw.obj \
+ dk4wreg8.obj \
+ dk4wregc.obj \
+ dk4a85e.obj \
+ dk4a85d.obj \
+ dk4ahd.obj \
+ dk4rle.obj \
+ dk4rld.obj \
+ dk4bf.obj \
+ dk4bitsh.obj \
+ dk4getpid.obj \
+ dk4inst.obj \
+ dk4isadm.obj \
+ dk4fpe.obj \
+ dk3trace.obj
+
+LIBDK4MAIODDOBJ= \
+ dk4maoddbl.obj \
+ dk4maiddbl.obj \
+ dk4maiddic.obj \
+ dk4maiddis.obj \
+ dk4maiddii.obj \
+ dk4maiddmi.obj \
+ dk4maiddli.obj \
+ dk4maiddil.obj \
+ dk4maidddi.obj \
+ dk4maidduc.obj \
+ dk4maiddus.obj \
+ dk4maiddui.obj \
+ dk4maiddmu.obj \
+ dk4maiddlu.obj \
+ dk4maiddul.obj \
+ dk4maiddsz.obj \
+ dk4maidddu.obj \
+ dk4maodd.obj
+
+LIBDK4MAIODHOBJ= \
+ dk4maidhic.obj \
+ dk4maidhis.obj \
+ dk4maidhii.obj \
+ dk4maidhmi.obj \
+ dk4maidhli.obj \
+ dk4maidhil.obj \
+ dk4maidhdi.obj \
+ dk4maidhuc.obj \
+ dk4maidhus.obj \
+ dk4maidhui.obj \
+ dk4maidhmu.obj \
+ dk4maidhlu.obj \
+ dk4maidhul.obj \
+ dk4maidhdu.obj \
+ dk4maodh.obj \
+ dk4maodo.obj
+
+LIBDK4MAIOWDOBJ= \
+ dk4maowdbl.obj \
+ dk4maiwdbl.obj \
+ dk4maiwdic.obj \
+ dk4maiwdis.obj \
+ dk4maiwdii.obj \
+ dk4maiwdmi.obj \
+ dk4maiwdli.obj \
+ dk4maiwdil.obj \
+ dk4maiwduc.obj \
+ dk4maiwdus.obj \
+ dk4maiwdui.obj \
+ dk4maiwdmu.obj \
+ dk4maiwdlu.obj \
+ dk4maiwdul.obj \
+ dk4maiwdsz.obj \
+ dk4maiwddi.obj \
+ dk4maiwddu.obj \
+ dk4maowd.obj
+
+LIBDK4MAIOWHOBJ= \
+ dk4maiwhic.obj \
+ dk4maiwhis.obj \
+ dk4maiwhii.obj \
+ dk4maiwhmi.obj \
+ dk4maiwhli.obj \
+ dk4maiwhil.obj \
+ dk4maiwhuc.obj \
+ dk4maiwhus.obj \
+ dk4maiwhui.obj \
+ dk4maiwhmu.obj \
+ dk4maiwhlu.obj \
+ dk4maiwhul.obj \
+ dk4maiwhdi.obj \
+ dk4maiwhdu.obj \
+ dk4maowh.obj
+
+LIBDK4MAIO8DOBJ= \
+ dk4mao8dbl.obj \
+ dk4mai8dbl.obj \
+ dk4mai8dic.obj \
+ dk4mai8dis.obj \
+ dk4mai8dii.obj \
+ dk4mai8dmi.obj \
+ dk4mai8dli.obj \
+ dk4mai8dil.obj \
+ dk4mai8ddi.obj \
+ dk4mai8duc.obj \
+ dk4mai8dus.obj \
+ dk4mai8dui.obj \
+ dk4mai8dmu.obj \
+ dk4mai8dlu.obj \
+ dk4mai8dul.obj \
+ dk4mai8dsz.obj \
+ dk4mai8ddu.obj \
+ dk4mao8d.obj
+
+LIBDK4MAIO8HOBJ= \
+ dk4mai8hic.obj \
+ dk4mai8his.obj \
+ dk4mai8hii.obj \
+ dk4mai8hmi.obj \
+ dk4mai8hli.obj \
+ dk4mai8hil.obj \
+ dk4mai8hdi.obj \
+ dk4mai8huc.obj \
+ dk4mai8hus.obj \
+ dk4mai8hui.obj \
+ dk4mai8hmu.obj \
+ dk4mai8hlu.obj \
+ dk4mai8hul.obj \
+ dk4mai8hdu.obj \
+ dk4mao8h.obj
+
+LIBDK4MAOBJ= \
+ dk4macd.obj \
+ dk4macm.obj \
+ dk4macll.obj \
+ dk4macl.obj \
+ dk4maci.obj \
+ dk4macs.obj \
+ dk4macc.obj \
+ dk4maasz.obj \
+ dk4maadi.obj \
+ dk4maadu.obj \
+ dk4maami.obj \
+ dk4maamu.obj \
+ dk4maall.obj \
+ dk4maalu.obj \
+ dk4maal.obj \
+ dk4maaul.obj \
+ dk4maai.obj \
+ dk4maaui.obj \
+ dk4maas.obj \
+ dk4maaus.obj \
+ dk4maac.obj \
+ dk4maauc.obj
+
+LIBDK4BASEOBJ= \
+ dk4numl.obj \
+ dk4strd.obj \
+ dk4strw.obj \
+ dk4str8.obj \
+ dk4memcpl.obj \
+ dk4memrs.obj \
+ dk4mem.obj \
+ dk4error.obj
+
+OBJLIBDK4= \
+ $(LIBDK4LATOBJ) \
+ $(LIBDK4SOCKAOBJ) \
+ $(LIBDK4DBIAOBJ) \
+ $(LIBDK4APPOBJ) \
+ $(LIBDK4MDRNDOBJ) \
+ $(LIBDK4SOCKOBJ) \
+ $(LIBDK4DBIOBJ) \
+ $(LIBDK4COBJ) \
+ $(LIBDK4MAIODDOBJ) \
+ $(LIBDK4MAIOWDOBJ) \
+ $(LIBDK4MAIO8DOBJ) \
+ $(LIBDK4MAIODHOBJ) \
+ $(LIBDK4MAIOWHOBJ) \
+ $(LIBDK4MAIO8HOBJ) \
+ $(LIBDK4MAOBJ) \
+ $(LIBDK4BASEOBJ)
+
+all: libraries programs
+
+install: all
+ -MKDIR "$(CONF_OUTPUTDIR)"
+ -MKDIR "$(PREFIX)"
+ -MKDIR "$(BINDIR)"
+ -MKDIR "$(ETCDIR)"
+ -MKDIR "$(ETCDIR)\dk3app"
+ -MKDIR "$(SHAREDIR)"
+ -MKDIR "$(MANDIR)"
+ -MKDIR "$(MAN1DIR)"
+ -MKDIR "$(MAN5DIR)"
+ -MKDIR "$(DATADIR)"
+ -MKDIR "$(DK4APPDIR)"
+ -MKDIR "$(INCLUDEDIR)"
+ -MKDIR "$(LIBDIR)"
+ -MKDIR "$(CONTRIBDIR)"
+ xcopy *.exe "$(BINDIR)\" /Y
+ xcopy dk3trace.h "$(INCLUDEDIR)\" /Y
+ xcopy dk4*.h "$(INCLUDEDIR)\" /Y
+ xcopy dk4*.lib "$(LIBDIR)\" /Y
+ xcopy dktools\* "$(DATADIR)\" /S /Y
+ xcopy dk4app\* "$(DK4APPDIR)\" /S /Y
+ xcopy win32\*.iss "$(CONF_OUTPUTDIR)\" /Y
+ xcopy dkctinst.ico "$(CONF_OUTPUTDIR)\" /Y
+ xcopy dkctunin.ico "$(CONF_OUTPUTDIR)\" /Y
+ xcopy etc-dk3app\* "$(ETCDIR)\dk3app\" /S /Y
+ xcopy help-chm\* "$(DATADIR)\" /S /Y
+ xcopy contrib\* "$(CONTRIBDIR)\" /S /Y
+ xcopy man\man1\* "$(MAN1DIR)\" /S /Y
+ xcopy man\man5\* "$(MAN5DIR)\" /S /Y
+
+SMALLLIBRARIES= \
+ dk4lat.lib \
+ dk4socka.lib \
+ dk4app.lib \
+ dk4sock.lib \
+ dk4c.lib \
+ dk4maiodd.lib \
+ dk4maiodh.lib \
+ dk4maiowd.lib \
+ dk4maiowh.lib \
+ dk4maio8d.lib \
+ dk4maio8h.lib \
+ dk4ma.lib \
+ dk4base.lib \
+ dk3trace.lib
+
+LIBRARIES= dk4.lib $(SMALLLIBRARIES)
+
+# Start of dktools-3 libraries section
+#
+#
+
+!IF "X$(CONF_GUI)" == "Xyes"
+
+LIBDK3WXOBJ= \
+ DkWxColorView.obj \
+ DkWxFrame.obj \
+ DkWxDialog.obj \
+ DkWxProgressDialog.obj \
+ DkWxBufferedControl.obj \
+ DkWxProcessingController.obj \
+ DkWxProcessingIdleController.obj \
+ DkWxCommunicator.obj \
+ DkWxHelpController.obj \
+ DkWxAppHelper.obj \
+ dk3wxs.obj
+
+DK3GUIPROGRAMS= \
+ wxdkfcs.exe \
+ wxdkct.exe \
+ wxbmpp.exe \
+ wxdkclock.exe \
+ winprint.exe \
+ wxdkhtb.exe \
+ wximgsz.exe \
+ wxpqdic.exe \
+ ChangeScreenSize.exe
+
+!ELSE
+
+LIBDK3WXOBJ=
+
+DK3GUIPROGRAMS=
+
+!ENDIF
+
+DK3PROGRAMS= $(DK3GUIPROGRAMS) \
+ dkwt.exe \
+ dkwtadm.exe \
+ wprclean.exe \
+ lprngcl.exe \
+ bmpp.exe \
+ fig2lat.exe \
+ htmlbook.exe \
+ dkct.exe \
+ plpdftex.exe \
+ addctrld.exe \
+ dkwxwiz.exe \
+ dk3info.exe \
+ dkwxpath.exe
+
+LIBDK3OBJ= $(LIBDK3WXOBJ) \
+ dk3figbb.obj \
+ dk3figpr.obj \
+ dk3figah.obj \
+ dk3figrd.obj \
+ dk3figto.obj \
+ dk3fig.obj \
+ dk3font.obj \
+ dk3ct.obj \
+ dk3dbi.obj \
+ dk3bm.obj \
+ dk3bmeo.obj \
+ dk3bmep.obj \
+ dk3bmeps.obj \
+ dk3bmj.obj \
+ dk3pdf.obj \
+ dk3paper.obj \
+ dk3bifa.obj \
+ dk3bif.obj \
+ dk3pixre.obj \
+ dk3appr.obj \
+ dk3of.obj \
+ dk3chks.obj \
+ dk3strmb.obj \
+ dk3strmg.obj \
+ dk3opt.obj \
+ dk3bf.obj \
+ dk3uc2l.obj \
+ dk3wreg.obj \
+ dk3se.obj \
+ dk3ufi.obj \
+ dk3strkv.obj \
+ dk3app.obj \
+ dk3strm.obj \
+ dk3sto.obj \
+ dk3dir.obj \
+ dk3enc.obj \
+ dk3str.obj \
+ dk3cores.obj \
+ dk3sf.obj \
+ dk3echo.obj \
+ dk3signl.obj \
+ dk3mas.obj \
+ dk3maus.obj \
+ dk3mai.obj \
+ dk3maui.obj \
+ dk3mal.obj \
+ dk3maul.obj \
+ dk3mad.obj \
+ dk3madsc.obj \
+ dk3madic.obj \
+ dk3madlc.obj \
+ dk3maidd.obj dk3maihd.obj dk3maodd.obj dk3maohd.obj \
+ dk3maid8.obj dk3maih8.obj dk3maod8.obj dk3maoh8.obj dk3masts.obj \
+ dk3madfo.obj \
+ dk3madso.obj \
+ dk3madsi.obj \
+ dk3inst.obj \
+ dk3srch.obj \
+ dk3bits.obj \
+ dk3mem.obj \
+ dk3bb.obj \
+ dk3bezcu.obj \
+ dk3xsp.obj \
+ dk3kv.obj \
+ dk3trace.obj
+
+dk3.lib: $(LIBDK3OBJ)
+ -if exist dk3.lib del dk3.lib
+ $(LIB) /nologo /out:dk3.lib $(LIBDK3OBJ)
+
+DK3WTOBJ= \
+ dkwt.obj \
+ dkwt-ac.obj \
+ dkwt-ev.obj \
+ dkwt-cp.obj \
+ dkwt-gr.obj \
+ dkwt-pr.obj \
+ dkwt-env.obj \
+ dkwt-to.obj \
+ dkwt.res
+
+dkwt.exe: $(DK3WTOBJ) dk3.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(EXE) /out:$@ $(DK3WTOBJ) ws2_32.lib winspool.lib dk3.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+dkwtadm.exe: $(DK3WTOBJ) dk3.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(EXE) /out:$@ $(DK3WTOBJ) ws2_32.lib winspool.lib dk3.lib
+ -IF EXIST dkwtadm.exe.manifest DEL dkwtadm.exe.manifest
+ copy dkwtadm.exe.manifest.in dkwtadm.exe.manifest
+ $(VC_MANIFEST_EMBED_EXE)
+
+WPRCLEANOBJ= wprclean.obj dk3print.obj dk3prcfg.obj dk3prreq.obj wprclean.res
+
+wprclean.exe: $(WPRCLEANOBJ) dk3.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(EXE) /out:$@ $(WPRCLEANOBJ) winspool.lib dk3.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+BMPPOBJ= bmeps3.obj bmpp.res
+
+bmpp.exe: $(BMPPOBJ) dk3.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(EXE) /out:$@ $(BMPPOBJ) dk3.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+FIG2LATOBJ= \
+ fig2lat.obj \
+ f2lopt.obj \
+ f2lud.obj \
+ f2ludpat.obj \
+ f2lpgf.obj \
+ f2lpdf.obj \
+ f2leps.obj \
+ f2lsvg.obj \
+ f2lsvgst.obj \
+ f2ll2l.obj \
+ f2lto.obj \
+ f2lpara.obj \
+ fig2lat.res
+
+fig2lat.exe: $(FIG2LATOBJ) dk3.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(EXE) /out:$@ $(FIG2LATOBJ) dk3.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+HTMLBOOKOBJ= \
+ htmlbook.obj \
+ hbnode.obj \
+ hbconf.obj \
+ hbhtml.obj \
+ hbtool.obj \
+ hbindex.obj \
+ hbcont.obj \
+ hbimgdim.obj \
+ hbchm.obj \
+ htmlbook.res
+
+htmlbook.exe: $(HTMLBOOKOBJ) dk3.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(EXE) /out:$@ $(HTMLBOOKOBJ) dk3.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+DKCTOBJ= dkct.obj \
+ dkct-tr.obj \
+ dkct-au.obj \
+ dkct-gui.obj \
+ dkct-to.obj \
+ dkct-str.obj \
+ dkct.res
+
+dkct.exe: $(DKCTOBJ) dk3.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(EXE) /out:$@ $(DKCTOBJ) dk3.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+PLPDFTEXOBJ= plpdftex.obj plptcol.obj plpdftex.res
+
+plpdftex.exe: $(PLPDFTEXOBJ) dk3.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(EXE) /out:$@ $(PLPDFTEXOBJ) dk3.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+# DKDBTOBJ= dkdbt.obj dkdbt.res
+
+# dkdbt.exe: $(DKDBTOBJ) dk3.lib
+# @echo Link $@
+# -IF EXIST $@ DEL $@
+# $(EXE) /out:$@ $(DKDBTOBJ) dk3.lib
+# $(VC_MANIFEST_EMBED_EXE)
+
+ADDCTRLDOBJ= addctrld.obj addctrld.res
+
+addctrld.exe: $(ADDCTRLDOBJ) dk3.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(EXE) /out:$@ $(ADDCTRLDOBJ) dk3.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+DKWXWIZOBJ= dkwxwiz.obj dkwxwiz.res
+
+dkwxwiz.exe: $(DKWXWIZOBJ) dk3.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(EXE) /out:$@ $(DKWXWIZOBJ) dk3.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+DK3INFOOBJ= dk3info.obj dk3info.res
+
+dk3info.exe: $(DK3INFOOBJ) dk3.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(EXE) /out:$@ $(DK3INFOOBJ) dk3.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+WXDKCTOBJ= \
+ DkWxTraceApp.obj \
+ DkWxTraceFrame.obj \
+ DkWxTraceThread.obj \
+ DkWxTraceOptionsDialog.obj \
+ dkct-str-gui.obj \
+ dkct-tr-gui.obj \
+ dkct-au-gui.obj \
+ dkct-gui-gui.obj \
+ dkct-to-gui.obj \
+ wxdkct.res
+
+wxdkct.exe: $(WXDKCTOBJ) dk3.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(GUIEXE) /out:$@ $(WXDKCTOBJ) dk3.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+WXBMPPOBJ= \
+ DkWxBmepsApp.obj \
+ DkWxBmepsFrame.obj \
+ DkWxBmepsOptionsDialog.obj \
+ DkWxBmepsThread.obj \
+ DkWxProgressDialog.obj \
+ DkWxFrame.obj \
+ DkWxAppHelper.obj \
+ DkWxHelpController.obj \
+ DkWxCommunicator.obj \
+ DkWxColorView.obj \
+ dk3wxs.obj \
+ dk3bm-gui.obj \
+ dk3bmj-gui.obj \
+ dk3bmeo.obj \
+ dk3bmeps.obj \
+ dk3pdf-gui.obj \
+ dk3paper.obj \
+ dk3bifa-gui.obj \
+ dk3bif-gui.obj \
+ dk3pixre.obj \
+ dk3opt.obj \
+ dk3app.obj \
+ dk3wreg.obj \
+ dk3of.obj \
+ dk3strm.obj \
+ dk3sto.obj \
+ dk3dir.obj \
+ dk3enc.obj \
+ dk3str.obj \
+ dk3sf.obj \
+ dk3maui.obj \
+ dk3mal.obj \
+ dk3maul.obj \
+ dk3mad.obj \
+ dk3madlc.obj \
+ dk3maidd.obj dk3maodd.obj dk3maid8.obj dk3maod8.obj \
+ dk3madfo.obj \
+ dk3madso.obj \
+ dk3madsi.obj \
+ dk3inst.obj \
+ dk3srch.obj \
+ dk3bits.obj \
+ dk3mem.obj \
+ dk3trace.obj \
+ wxbmpp.res
+
+wxbmpp.exe: $(WXBMPPOBJ)
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(GUIEXE) /out:$@ $(WXBMPPOBJ)
+ $(VC_MANIFEST_EMBED_EXE)
+
+WXDKCLOCKOBJ= \
+ DkClockApp.obj \
+ DkClockFrame.obj \
+ DkClockOptionsDialog.obj \
+ DkClockView.obj \
+ DkClockData.obj \
+ DkClockTaskbarIcon.obj \
+ wxdkclock.res
+
+wxdkclock.exe: $(WXDKCLOCKOBJ) dk3.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(GUIEXE) /out:$@ $(WXDKCLOCKOBJ) dk3.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+WINPRINTOBJ= \
+ WinprintApp.obj \
+ WinprintFrame.obj \
+ WinprintThread.obj \
+ WinprintChooserDialog.obj \
+ dk3print.obj \
+ dk3prcfg.obj \
+ dk3prreq.obj \
+ winprint.res
+
+winprint.exe: $(WINPRINTOBJ) dk3.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(GUIEXE) /out:$@ $(WINPRINTOBJ) dk3.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+WXDKHTBOBJ= \
+ DkWxHtbApp.obj \
+ DkWxHtbFrame.obj \
+ wxdkhtb.res
+
+wxdkhtb.exe: $(WXDKHTBOBJ) dk3.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(GUIEXE) /out:$@ $(WXDKHTBOBJ) dk3.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+WXIMGSZOBJ= \
+ DkWxImgszApp.obj \
+ DkWxImgszFrame.obj \
+ DkWxImgszOptionsDialog.obj \
+ wximgsz.res
+
+wximgsz.exe: $(WXIMGSZOBJ) dk3.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(GUIEXE) /out:$@ $(WXIMGSZOBJ) dk3.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+WXPQDICOBJ= \
+ WxpqdicApp.obj \
+ WxpqdicFrame.obj \
+ wxpqdic.res
+
+wxpqdic.exe: $(WXPQDICOBJ) dk4.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(GUIEXE) /out:$@ $(WXPQDICOBJ) ws2_32.lib dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+DKWXPATHOBJ= DkWxPathApp.obj DkWxPathFrame.obj dkwxpath.res
+
+dkwxpath.exe: $(DKWXPATHOBJ) dk3.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(GUIEXE) /out:$@ $(DKWXPATHOBJ) dk3.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+WXDKFCSOBJ= \
+ Dk4FcsApp.obj \
+ Dk4FcsFrame.obj \
+ wxdkfcs.res
+
+wxdkfcs.exe: $(WXDKFCSOBJ)
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(GUIEXE) /out:$@ $(WXDKFCSOBJ) dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+WXDKSCRSZOBJ= \
+ ScreenSizeApp.obj \
+ ScreenSizeFrame.obj \
+ wxdkscrsz.res
+
+ChangeScreenSize.exe: $(WXDKSCRSZOBJ)
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(GUIEXE) /out:$@ $(WXDKSCRSZOBJ) dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+dkct-str-gui.cpp: dkct-str.c
+ -IF EXIST $@ DEL $@
+ copy dk3usewx.c +dkct-str.c $@
+
+dkct-tr-gui.cpp: dkct-tr.c
+ -IF EXIST $@ DEL $@
+ copy dk3usewx.c +dkct-tr.c $@
+
+dkct-au-gui.cpp: dkct-au.c
+ -IF EXIST $@ DEL $@
+ copy dk3usewx.c +dkct-au.c $@
+
+dkct-gui-gui.cpp: dkct-gui.c
+ -IF EXIST $@ DEL $@
+ copy dk3usewx.c +dkct-gui.c $@
+
+dkct-to-gui.cpp: dkct-to.c
+ -IF EXIST $@ DEL $@
+ copy dk3usewx.c +dkct-to.c $@
+
+dk3bm-gui.cpp: dk3bm.c
+ -IF EXIST $@ DEL $@
+ copy dk3usewx.c +dk3bm.c $@
+
+dk3bmj-gui.cpp: dk3bmj.c
+ -IF EXIST $@ DEL $@
+ copy dk3usewx.c +dk3bmj.c $@
+
+dk3pdf-gui.cpp: dk3pdf.c
+ -IF EXIST $@ DEL $@
+ copy dk3usewx.c +dk3pdf.c $@
+
+dk3bifa-gui.cpp: dk3bifa.c
+ -IF EXIST $@ DEL $@
+ copy dk3usewx.c +dk3bifa.c $@
+
+dk3bif-gui.cpp: dk3bif.c
+ -IF EXIST $@ DEL $@
+ copy dk3usewx.c +dk3bif.c $@
+
+
+#
+#
+# End of dktools-3 libraries section
+
+
+
+libraries: $(LIBRARIES) dk3.lib
+
+dk4.lib: $(LIBDK4WXOBJ) $(OBJLIBDK4)
+ -if exist dk4.lib del dk4.lib
+ $(LIB) /nologo /out:dk4.lib $(LIBDK4WXOBJ) $(OBJLIBDK4)
+
+dk4wx.lib: $(LIBDK4WXOBJ)
+ -if exist $@ del $@
+ $(LIB) /nologo /out:$@ $(LIBDK4WXOBJ)
+
+dk4lat.lib: $(LIBDK4LATOBJ)
+ -if exist $@ del $@
+ $(LIB) /nologo /out:$@ $(LIBDK4LATOBJ)
+
+dk4socka.lib: $(LIBDK4SOCKAOBJ)
+ -if exist $@ del $@
+ $(LIB) /nologo /out:$@ $(LIBDK4SOCKAOBJ)
+
+dk4dbia.lib: $(LIBDK4DBIAOBJ)
+ -if exist $@ del $@
+ $(LIB) /nologo /out:$@ $(LIBDK4DBIAOBJ)
+
+dk4app.lib: $(LIBDK4APPOBJ)
+ -if exist $@ del $@
+ $(LIB) /nologo /out:$@ $(LIBDK4APPOBJ)
+
+dk4sock.lib: $(LIBDK4SOCKOBJ)
+ -if exist $@ del $@
+ $(LIB) /nologo /out:$@ $(LIBDK4SOCKOBJ)
+
+dk4dbi.lib: $(LIBDK4DBIOBJ)
+ -if exist $@ del $@
+ $(LIB) /nologo /out:$@ $(LIBDK4DBIOBJ)
+
+dk4c.lib: $(LIBDK4COBJ)
+ -if exist $@ del $@
+ $(LIB) /nologo /out:$@ $(LIBDK4COBJ)
+
+dk4maiodd.lib: $(LIBDK4MAIODDOBJ)
+ -if exist $@ del $@
+ $(LIB) /nologo /out:$@ $(LIBDK4MAIODDOBJ)
+
+dk4maiodh.lib: $(LIBDK4MAIODHOBJ)
+ -if exist $@ del $@
+ $(LIB) /nologo /out:$@ $(LIBDK4MAIODHOBJ)
+
+dk4maiowd.lib: $(LIBDK4MAIOWDOBJ)
+ -if exist $@ del $@
+ $(LIB) /nologo /out:$@ $(LIBDK4MAIOWDOBJ)
+
+dk4maiowh.lib: $(LIBDK4MAIOWHOBJ)
+ -if exist $@ del $@
+ $(LIB) /nologo /out:$@ $(LIBDK4MAIOWHOBJ)
+
+dk4maio8d.lib: $(LIBDK4MAIO8DOBJ)
+ -if exist $@ del $@
+ $(LIB) /nologo /out:$@ $(LIBDK4MAIO8DOBJ)
+
+dk4maio8h.lib: $(LIBDK4MAIO8HOBJ)
+ -if exist $@ del $@
+ $(LIB) /nologo /out:$@ $(LIBDK4MAIO8HOBJ)
+
+dk4ma.lib: $(LIBDK4MAOBJ)
+ -if exist $@ del $@
+ $(LIB) /nologo /out:$@ $(LIBDK4MAOBJ)
+
+dk4base.lib: $(LIBDK4BASEOBJ)
+ -if exist $@ del $@
+ $(LIB) /nologo /out:$@ $(LIBDK4BASEOBJ)
+
+dk3trace.lib: dk3trace.obj
+ -if exist $@ del $@
+ $(LIB) /nologo /out:$@ dk3trace.obj
+
+PROGRAMS= \
+ dk-cat.exe \
+ dk-blks.exe \
+ dk-sqlsplit.exe \
+ dk-eradisk.exe \
+ dk-ls.exe \
+ dk-sort.exe \
+ dk-fic.exe \
+ dk-pwgen.exe \
+ dk-rand.exe \
+ dk-t2h.exe \
+ dk-t2l.exe \
+ dk-hex.exe \
+ dk-bmm.exe \
+ dk-recv.exe \
+ dk-send.exe \
+ dk-t2db.exe \
+ dk-db2t.exe \
+ dk-dbco.exe \
+ dk4info.exe
+
+programs: $(PROGRAMS) $(DK3PROGRAMS)
+
+dk-cat.exe: dk-cat.obj dk-cat.res dk4.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(EXE) /out:$@ dk-cat.obj dk-cat.res dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+dk-blks.exe: dk-blks.obj dk-blks.res dk4.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(EXE) /out:$@ dk-blks.obj dk-blks.res dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+dk-sqlsplit.exe: dk-sqlsplit.obj dk-sqlsplit.res dk4.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(EXE) /out:$@ dk-sqlsplit.obj dk-sqlsplit.res dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+dk-eradisk.exe: dk-eradisk.obj dk-eradisk.res dk4.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(EXE) /out:$@ dk-eradisk.obj dk-eradisk.res dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+DKLSOBJ= dk-ls.obj dk-ls-to.obj dk-ls.res
+
+dk-ls.exe: $(DKLSOBJ) dk4.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(EXE) /out:$@ $(DKLSOBJ) dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+DKSORTOBJ= dk-sort.obj dk-sort.res
+
+dk-sort.exe: $(DKSORTOBJ) dk4.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(EXE) /out:$@ $(DKSORTOBJ) dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+DKFICOBJ= dk-fic.obj dk-fic.res
+
+dk-fic.exe: $(DKFICOBJ) dk4.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(EXE) /out:$@ $(DKFICOBJ) dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+DKPWGENOBJ= dk-pwgen.obj dk-pwgen.res
+
+dk-pwgen.exe: $(DKPWGENOBJ) dk4.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(EXE) /out:$@ $(DKPWGENOBJ) dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+dk-rand.exe: dk-rand.obj dk-rand.res
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(EXE) /out:$@ dk-rand.obj dk-rand.res dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+dk-t2h.exe: dk-t2h.obj dk-t2h.res dk4.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(EXE) /out:$@ dk-t2h.obj dk-t2h.res dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+dk-t2l.exe: dk-t2l.obj dk-t2l.res dk4.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(EXE) /out:$@ dk-t2l.obj dk-t2l.res dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+dk-hex.exe: dk-hex.obj dk-hex.res dk4.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(EXE) /out:$@ dk-hex.obj dk-hex.res dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+dk-bmm.exe: dk-bmm.obj dk-bmm.res dk4.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(EXE) /out:$@ dk-bmm.obj dk-bmm.res dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+dk-recv.exe: dk-recv.obj dk-recv.res dk4.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(EXE) $(WINSOCKLIB) /out:$@ dk-recv.obj dk-recv.res ws2_32.lib dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+dk-send.exe: dk-send.obj dk-send.res dk4.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(EXE) $(WINSOCKLIB) /out:$@ dk-send.obj dk-send.res ws2_32.lib dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+lprngcl.exe: lprngcl.obj lprngcl.res dk4.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(EXE) $(WINSOCKLIB) /out:$@ lprngcl.obj lprngcl.res ws2_32.lib dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+WPRCLEAN2OBJ= wprclean2.obj wprclean.res
+
+wprclean2.exe: $(WPRCLEAN2OBJ) dk4.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(EXE) /out:$@ $(WPRCLEAN2OBJ) winspool.lib dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+dk-t2db.exe: dk-t2db.obj dk-t2db.res dk4.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(EXE) /out:$@ dk-t2db.obj dk-t2db.res dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+dk-db2t.exe: dk-db2t.obj dk-db2t.res dk4.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(EXE) /out:$@ dk-db2t.obj dk-db2t.res dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+dk-dbco.exe: dk-dbco.obj dk-dbco.res dk4.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(EXE) /out:$@ dk-dbco.obj dk-dbco.res dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+dk4info.exe: dk4info.obj dk4info.res dk4.lib
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(EXE) $(WINSOCKLIB) /out:$@ dk4info.obj dk4info.res dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+wxcs.exe: wxcs.obj
+ @echo Link $@
+ -IF EXIST $@ DEL $@
+ $(EXE) /out:$@ wxcs.obj
+ $(VC_MANIFEST_EMBED_EXE)
+
+clean:
+ -DEL *.lib /Q
+ -DEL *.obj /Q
+ -DEL *.res /Q
+ -DEL *.exe /Q
+
+#
+# The test programs below are not built during a normal installation.
+#
+
+test-dk4loc.exe: test-dk4loc.obj dk4.lib
+ $(EXE) /out:$@ test-dk4loc.obj dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+test-dk4strm.exe: test-dk4strm.obj dk4.lib
+ $(EXE) /out:$@ test-dk4strm.obj dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+test-dk4numl.exe: test-dk4numl.obj dk4.lib
+ $(EXE) /out:$@ test-dk4numl.obj dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+test-dk4tsp08.exe: test-dk4tsp08.obj dk4.lib
+ $(EXE) /out:$@ test-dk4tsp08.obj dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+test-bool.exe: test-bool.obj dk4.lib
+ $(EXE) /out:$@ test-bool.obj dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+test-dk4enc.exe: test-dk4enc.obj dk4.lib
+ $(EXE) /out:$@ test-dk4enc.obj dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+test-dk4user.exe: test-dk4user.obj dk4.lib
+ $(EXE) /out:$@ test-dk4user.obj dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+test-dk4mai8dbl.exe: test-dk4mai8dbl.obj dk4.lib
+ $(EXE) /out:$@ test-dk4mai8dbl.obj dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+test-fne.exe: test-fne.obj dk4.lib
+ $(EXE) /out:$@ test-fne.obj dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+test-mkdir.exe: test-mkdir.obj dk4.lib
+ $(EXE) /out:$@ test-mkdir.obj dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+test-deldir.exe: test-deldir.obj dk4.lib
+ $(EXE) /out:$@ test-deldir.obj dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+test-dk4dir08.exe: test-dk4dir08.obj dk4.lib
+ $(EXE) /out:$@ test-dk4dir08.obj dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+test-dk4dir.exe: test-dk4dir.obj dk4.lib
+ $(EXE) /out:$@ test-dk4dir.obj dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+test-deltree.exe: test-deltree.obj dk4.lib
+ $(EXE) /out:$@ test-deltree.obj dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+test-filei.exe: test-filei.obj dk4.lib
+ $(EXE) /out:$@ test-filei.obj dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+test-dk4time08.exe: test-dk4time08.obj dk4.lib
+ $(EXE) /out:$@ test-dk4time08.obj dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+test-a85e.exe: test-a85e.obj dk4.lib
+ $(EXE) /out:$@ test-a85e.obj dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+test-a85d.exe: test-a85d.obj dk4.lib
+ $(EXE) /out:$@ test-a85d.obj dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+test-rle.exe: test-rle.obj dk4.lib
+ $(EXE) /out:$@ test-rle.obj dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+test-rld.exe: test-rld.obj dk4.lib
+ $(EXE) /out:$@ test-rld.obj dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+test-sock.exe: test-sock.obj dk4.lib
+ $(EXE) $(WINSOCKLIB) /out:$@ test-sock.obj dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+test-peer.exe: test-peer.obj dk4.lib
+ $(EXE) $(WINSOCKLIB) /out:$@ test-peer.obj dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+test-membuf.exe: test-membuf.obj dk4.lib
+ $(EXE) $(WINSOCKLIB) /out:$@ test-membuf.obj dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+test-home.exe: test-home.obj dk4.lib
+ $(EXE) /out:$@ test-home.obj dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
+test-deldirwc.exe: test-deldirwc.obj dk4.lib
+ $(EXE) /out:$@ test-deldirwc.obj dk4.lib
+ $(VC_MANIFEST_EMBED_EXE)
+
diff --git a/support/dktools/man/man1/addctrld.1 b/support/dktools/man/man1/addctrld.1
new file mode 100644
index 0000000000..2c50f3fa99
--- /dev/null
+++ b/support/dktools/man/man1/addctrld.1
@@ -0,0 +1,96 @@
+'\" t
+.\" Title: addctrld
+.\" Author: [see the "AUTHORS" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 03/28/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "ADDCTRLD" "1" "03/28/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+addctrld \- Add Ctrl\-D to data stream
+.SH "SYNOPSIS"
+.sp
+.nf
+addctrld
+.fi
+.SH "DESCRIPTION"
+.sp
+The program adds a final Ctrl\-D to a data stream if not yet present\&.
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other status codes indicate an error\&.
+.SH "NOTES"
+.sp
+This program uses DK libraries version 4\&.
+.SH "AUTHORS"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/bmpp.1 b/support/dktools/man/man1/bmpp.1
new file mode 100644
index 0000000000..9501a97af2
--- /dev/null
+++ b/support/dktools/man/man1/bmpp.1
@@ -0,0 +1,361 @@
+'\" t
+.\" Title: bmpp
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 03/28/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "BMPP" "1" "03/28/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+bmpp \- Bitmap to PS/PDF converter
+.SH "SYNOPSIS"
+.sp
+\fBbmpp\fR [\fB\-l\fR\fIdriver\fR[\&.\fImode\fR][,\fIkey\fR[=\fIvalue\fR]\&...]] [\fIoptions\fR] \fIfile(s)\fR
+.SH "DESCRIPTION"
+.sp
+The program converts bitmap images from PNG, JPEG, or TIFF to PS/EPS and PDF\&.
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+\fBDrivers:\fR
+.PP
+\fBps\fR
+.RS 4
+PostScript, can be used to print\&.
+.RE
+.PP
+\fBeps\fR
+.RS 4
+Encapsulated PostScript, image for inclusion into a document\&.
+.RE
+.PP
+\fBpdf\fR
+.RS 4
+Portable document format (PDF)\&.
+.RE
+.PP
+\fBbb\fR
+.RS 4
+Bounding box information only, no image contents\&.
+.RE
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+\fBOutput modes:\fR
+.PP
+\fBobject\fR
+.RS 4
+Object which can be embedded into a text or drawing by a text processing or drawing software\&.
+.RE
+.PP
+\fBimage\fR
+.RS 4
+Image for stand\-alone viewing\&.
+.RE
+.PP
+\fBdocument\fR
+.RS 4
+Fit the output to a given paper size for printing\&.
+.RE
+.RE
+.SH "OPTIONS"
+.PP
+\fB\-h\fR, \fB\-\-help\fR
+.RS 4
+Show help text\&.
+.RE
+.PP
+\fB\-v\fR, \fB\-\-version\fR
+.RS 4
+Shows version number\&.
+.RE
+.PP
+\fB\-L\fR, \fB\-\-license\-terms\fR
+.RS 4
+Show license terms\&.
+.RE
+.PP
+\fB\-t\fR \fItype\fR
+.RS 4
+Input image type, "png", "jpeg", or "tiff", must be specified when processing standard input or if the input file name suffix does not indicate the type\&.
+.RE
+.PP
+\fB\-m\fR
+.RS 4
+Make mode: Avoid unnecessary conversions if output file is up to date\&. Only active when processing a directory\&.
+.RE
+.PP
+\fB\-s\fR
+.RS 4
+Write to standard output, not to file\&.
+.RE
+.PP
+\fB\-o\fR \fIkey\fR[=\fIvalue\fR]
+.RS 4
+Detailed conversion options\&.
+.RE
+.SH "NAME=VALUE PAIRS"
+.sp
+The key=value pairs set detailed conversion options\&. For boolean settings the value can be omitted, the presence of the name sets the option to active\&. The following keys (and values) can be used:
+.PP
+\fBlevel\fR=\fIpslevel\fR
+.RS 4
+PS level, "2" or "3"\&. Default: 3\&.
+.RE
+.PP
+\fBcolor\fR[=\fIboolean\fR]
+.RS 4
+Color output for PS output\&. For PDF output color is always enabled\&. This setting is ignored when passing DCT data from JPEG files to output directly\&. Default: On\&.
+.RE
+.PP
+\fBdsc\fR[=\fIboolean\fR]
+.RS 4
+DSC comments when producing PS/EPS output\&. Default: Off, except for ps\&.document\&.
+.RE
+.PP
+\fBdraft\fR[=\fIboolean\fR]
+.RS 4
+Draft mode (small placeholder image only)\&. Default: Off\&.
+.RE
+.PP
+\fBpredictor\fR=\fIpredictor\fR
+.RS 4
+Predictor for flate compressions, "tiff", "sub", "up", "average", or "paeth"\&. Default: none\&.
+.RE
+.PP
+\fBduplex\fR[=\fIboolean\fR]
+.RS 4
+Duplex mode when producing documents\&. Default: Off\&.
+.RE
+.PP
+\fBtumble\fR[=\fIboolean\fR]
+.RS 4
+Tumble in addition to duplex mode\&. Default: Off\&.
+.RE
+.PP
+\fBdct\fR[=\fIboolean\fR]
+.RS 4
+Direct pass\-through of DCT encoded data found in JPEG files\&. Default: On\&.
+.RE
+.PP
+\fBbg\fR=\fIint\fR:\fIint\fR:\fIint\fR[:\fIboolean\fR]
+.RS 4
+Default background RGB color to be used if the input file does not contain a background color chunk\&. The optional boolean value at the end can be used to enforce this background over the background chunk\&. RGB values are in the range 0\&...255\&. Default: White, off\&.
+.RE
+.PP
+\fBinterpolation\fR[=\fIboolean\fR]
+.RS 4
+Image interpolation\&. Default: On\&.
+.RE
+.PP
+\fBjpeg\-interpolation\fR[=\fIboolean\fR]
+.RS 4
+Image interpolation if DCT data is passed through directly\&. Default: Off\&.
+.RE
+.PP
+\fBresolution\fR=\fIresolution\fR
+.RS 4
+Resolution, either "1:1" (use a 1 point x 1 point square for each source pixel), "chunk" (use resolution data from image) or an integer value for dpi\&. Default: 1:1 for objects, chunk for images, fit to paper size for documents\&.
+.RE
+.PP
+\fBpaper\fR=\fIpaper\fR
+.RS 4
+Paper size for documents\&. The paper size must be configured in a dk3paper\&.conf file\&. Only one from "resolution" or "paper" can be used\&.
+.RE
+.PP
+\fBmake\fR[=\fIboolean\fR]
+.RS 4
+Make mode when processing directories\&. Default: Off\&.
+.RE
+.PP
+\fBbpc\fR[=\fIboolean\fR]
+.RS 4
+Reduce the number of bits per component\&. Default: On\&.
+.RE
+.SH "EXIT STATUS"
+.sp
+0 on success, all other exit status codes indicate an error\&.
+.SH "PREFERENCES"
+.PP
+/print/ps/level
+.RS 4
+Default PS level, 2 or 3\&.
+.RE
+.SH "EXAMPLES"
+.PP
+bmpp \-lps\&.document,level=2,paper=A4,duplex,bpc myfax\&.tif
+.RS 4
+converts a fax TIFF file "myfax\&.tif" to "myfax\&.ps" for a PS 2 printer\&.
+.RE
+.PP
+bmpp \-l pdf\&.document,paper=A4,duplex fax\&.tif
+.RS 4
+creates a PDF file fax\&.pdf\&.
+.RE
+.PP
+bmpp \-l ps\&.object screenshot\&.png
+.RS 4
+creates a PS object file screenshot\&.ps for use with latex/dvips\&.
+.RE
+.PP
+bmpp \-l pdf\&.object screenshot\&.png
+.RS 4
+creates a PDF object file screenshot\&.pdf for use with pdflatex\&.
+.RE
+.PP
+bmpp \-l ps\&.image file\&.png
+.RS 4
+creates a PS image file\&.ps\&.
+.RE
+.PP
+bmpp \-l pdf\&.image file\&.png
+.RS 4
+creates a PDF image file\&.pdf\&.
+.RE
+.SH "FILES"
+.PP
+\fBdk3paper\&.conf\fR
+.RS 4
+If paper=\&... the named paper size must be configured in a dk3paper\&.conf file\&.
+.RE
+.SH "RESTRICTIONS"
+.sp
+The program uses the TIFFReadRGBAImage() function from the libtiff library to read TIFF images\&. The input file must meet the following conditions:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The file must be compliant to the "TIFF baseline v6\&.0 standard"\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The number of bits of component must be 8 or less\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The frames must not be too large, the system must be able to allocate the 4 * w * h bytes needed for image date in one piece\&.
+.RE
+.sp
+TIFF refers to a group of different compression and encoding mechanisms\&. A TIFF file is a sequence of data chunks, each data chunk contains a tag (chunk type identifier)\&. A lot of tags is defined in standards, i\&.e\&. the "TIFF baseline v6\&.0 standard"\&. Some software vendors add vendor\-specific or non\-standard tags when writing TIFF files\&. So when processing TIFF files in bmpp, you should not be surprised to see warnings or error messages about unknown TIFF tags\&. Neither bmpp nor the tifflib library are to blame for this, it is the responsibility of the people adding the non\-standard tags\&. Sometimes bmpp can read the image despite of the warnings/errors\&.
+.sp
+If you create bitmaps you want to process with bmpp, you should create PNG images instead of TIFF images if you have the choice\&.
+.SH "NOTES"
+.sp
+This program uses DK libraries version 3\&.
+.SH "AUTHOR"
+.sp
+Dirk Krause
+.SH "HISTORY"
+.sp
+The bmpp program replaces the bmeps program found in previous versions of dktools\&.
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2011\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net/bmpp\&.html
+.RS 4
+The DK tools and libraries homepage contains more information about bmpp and other programs\&.
+.RE
+.PP
+http://gxhints\&.sourceforge\&.net
+.RS 4
+The Graphics Conversion Hints page recommends programs and shows procedures for conversions between recent vector graphics formats\&.
+.RE
+.PP
+http://netpbm\&.sourceforge\&.net (especially pnmtops)
+.RS 4
+NetPBM is a toolkit for graphics images, including conversion of images between a variety of different formats\&.
+.RE
diff --git a/support/dktools/man/man1/dk-blks.1 b/support/dktools/man/man1/dk-blks.1
new file mode 100644
index 0000000000..8a5fdd81f8
--- /dev/null
+++ b/support/dktools/man/man1/dk-blks.1
@@ -0,0 +1,102 @@
+'\" t
+.\" Title: dk-blks
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2016
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "DK\-BLKS" "1" "09/03/2016" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dk-blks \- Adjust block size\&.
+.SH "SYNOPSIS"
+.sp
+\fBdk\-blks\fR [\fIoption\fR]
+.SH "DESCRIPTION"
+.sp
+The program reads a data stream from standard input and writes it to standard output using a specified block size\&.
+.sp
+It is inteded to prepare a data stream for the \*(Aqdd\*(Aq program, source data may come from network transmission or a decryption or decompression program\&.
+.SH "OPTIONS"
+.PP
+\fB\-b\fR \fIsize\fR, \fB\-\-block\-size=\fR\fIsize\fR
+.RS 4
+Block size (default: 4096)\&. You can append \*(Aqk\*(Aq, \*(Aqm\*(Aq, \*(Aqg\*(Aq or \*(Aqt\*(Aq for multiples of 1024 and powers of 1024, i\&.e\&. \*(Aq\-b 4k\*(Aq or \*(Aq\-b 1m\*(Aq\&.
+.RE
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other values indicate errors\&.
+.SH "NOTES"
+.sp
+This program uses DK libraries version 4\&.
+.SH "AUTHOR"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2015\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/dk-bmm.1 b/support/dktools/man/man1/dk-bmm.1
new file mode 100644
index 0000000000..f62bd1bbc8
--- /dev/null
+++ b/support/dktools/man/man1/dk-bmm.1
@@ -0,0 +1,160 @@
+'\" t
+.\" Title: dk-bmm
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 03/28/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "DK\-BMM" "1" "03/28/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dk-bmm \- Backup media management
+.SH "SYNOPSIS"
+.sp
+\fBdk\-bmm\fR [\fIoption(s)\fR] [\fIfile\fR]
+.SH "DESCRIPTION"
+.sp
+The dk\-bmm program performs one of the following four operations:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Retrieve name of current backup media set (option \-s)\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Confirm that backup to current media set was finished successfully (options \-s and \-c)\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Retrieve number of current backup media (default operation, neither \-s nor \-c required)\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Confirm that backup to current media was finished successfully (option \-c)\&.
+.RE
+.SH "OPTIONS"
+.PP
+\fB\-s\fR, \fB\-\-set\fR
+.RS 4
+Process backup media sets\&.
+.RE
+.PP
+\fB\-c\fR, \fB\-\-confirm\fR
+.RS 4
+Confirm that previous backup was finished successfully\&.
+.RE
+.PP
+\fB\-r\fR, \fB\-\-report\fR
+.RS 4
+Write report for one media set\&.
+.RE
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other values indicate errors\&.
+.SH "RESTRICTIONS"
+.sp
+On Windows the file name length is restricted to _MAX_PATH (260) characters if the file name contains a wildcard (* or ? character)\&.
+.SH "NOTES"
+.sp
+This program uses DK libraries version 4\&.
+.SH "AUTHOR"
+.sp
+Dirk Krause
+.SH "HISTORY"
+.sp
+This program was named \*(Aqtape\*(Aq in version 2\&.x\&.x, in version 3\&.x\&.x the functionality was availalbe in \*(Aqdkt tape\*(Aq\&.
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2015\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/dk-cat.1 b/support/dktools/man/man1/dk-cat.1
new file mode 100644
index 0000000000..0f8ecbf4d5
--- /dev/null
+++ b/support/dktools/man/man1/dk-cat.1
@@ -0,0 +1,203 @@
+'\" t
+.\" Title: dk-cat
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 02/08/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "DK\-CAT" "1" "02/08/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dk-cat \- Show text files\&.
+.SH "SYNOPSIS"
+.sp
+\fBdk\-cat\fR [\fIoptions\fR] [\fIfile(s)\fR]
+.SH "DESCRIPTION"
+.sp
+The dk\-cat program shows text files\&. If a BOM (byte order marker) at the start of file indicates an encoding, the file is recoded to the system encoding or the encoding required by command line options\&.
+.SH "OPTIONS"
+.PP
+\fB\-c\fR \fIboolean\fR, \fB\-\-crnl=\fR\fI_boolean\fR
+.RS 4
+Enable/disable use of the CR/NL sequence\&. Without this option the systems default is used\&.
+.RE
+.PP
+\fB\-n\fR, \fB\-\-line\-numbers\fR
+.RS 4
+Line numbers before each line\&.
+.RE
+.PP
+\fB\-\-line\-number\-width=\fR\fIinteger\fR
+.RS 4
+Minimum number of digits to use for line numbers, default is 5\&.
+.RE
+.PP
+\fB\-w\fR, \fB\-\-normalize\fR
+.RS 4
+Normalize text lines (remove leading and trailing white spaces, replace whitespace sequences by one space)\&.
+.RE
+.PP
+\fB\-i\fR \fIstring\fR
+.RS 4
+Expected input encoding\&. The encoding specified here is overwritten if a BOM is found at the start of an input file\&.
+.TS
+tab(:);
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt.
+T{
+plain
+T}:T{
+ASCII text
+T}
+T{
+ascii
+T}:T{
+synonym for plain
+T}
+T{
+ansi
+T}:T{
+ANSI
+T}
+T{
+utf\-8
+T}:T{
+UTF\-8
+T}
+T{
+utf\-16
+T}:T{
+UTF\-16, systems default endianness
+T}
+T{
+utf\-16le
+T}:T{
+UTF\-16, least significant byte first
+T}
+T{
+utf\-16be
+T}:T{
+UTF\-16, most significant byte first
+T}
+T{
+c32
+T}:T{
+32 bit, systems default endianness
+T}
+T{
+c32le
+T}:T{
+32 bit, least significant byte first
+T}
+T{
+c32be
+T}:T{
+32 bit, most significant byte first
+T}
+.TE
+.sp 1
+.RE
+.PP
+\fB\-o\fR \fIstring\fR
+.RS 4
+Output encoding, see above for encodings\&. Use
+\fIencoding\fR[\fB,bom\fR] \- i\&.e\&. utf\-16be,bom \- to require writing a byte order marker at start of output\&. The default is no BOM when writing to a terminal, use BOM when writing to file\&.
+.RE
+.PP
+\fB\-p\fR, \fB\-\-pass\-through\fR
+.RS 4
+Pass\-through of UTF\-8 encoded data when UTF\-8 output is wanted and UTF\-8 input is found\&. Without this option input is decoded to 32 bit characters and encoded to UTF\-8 (check for correct UTF\-8 encoding)\&.
+.RE
+.PP
+\fB\-\-verbose\fR
+.RS 4
+Show error message upon interrupt by SIGPIPE\&.
+.RE
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other values indicate errors\&.
+.SH "RESTRICTIONS"
+.sp
+On Windows the file name length is restricted to _MAX_PATH (260) characters if the file name contains a wildcard (* or ? character)\&.
+.SH "NOTES"
+.sp
+This program uses DK libraries version 4\&.
+.SH "AUTHOR"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2015\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/dk-db2t.1 b/support/dktools/man/man1/dk-db2t.1
new file mode 100644
index 0000000000..ee00af83a6
--- /dev/null
+++ b/support/dktools/man/man1/dk-db2t.1
@@ -0,0 +1,223 @@
+'\" t
+.\" Title: dk-db2t
+.\" Author: [see the "AUTHORS" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 02/08/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "DK\-DB2T" "1" "02/08/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dk-db2t \- Show simple database as text
+.SH "SYNOPSIS"
+.sp
+\fBdk\-db2t\fR [\fIoptions\fR] \fIdatabase\fR\&...
+.SH "DESCRIPTION"
+.sp
+The program shows a simple text database as text on standard output\&.
+.sp
+A simple database is a Berkeley DB, NDBM or in\-memory database\&. The records are key/value pairs, both key and value are a byte array\&. Keys are unique\&.
+.sp
+In a simple text database all keys and values are text strings\&. The finalizing 0 character is saved in the database together with the texts\&.
+.sp
+Use type::filename to specify databases (Type and file name are separated by two colons)\&. The following type names can be used:
+.TS
+tab(:);
+lt lt
+lt lt
+lt lt.
+T{
+.sp
+bdb
+T}:T{
+.sp
+Berkeley DB
+T}
+T{
+.sp
+ndbm
+T}:T{
+.sp
+NDBM database
+T}
+T{
+.sp
+mem
+T}:T{
+.sp
+in\-memory database
+T}
+.TE
+.sp 1
+.SH "OPTIONS"
+.PP
+\fB\-k\fR \fIsize\fR, \fB\-\-key\-buffer\-size=\fR\fIsize\fR
+.RS 4
+Size for key buffer (must be large enough to store the largest string including the finalizing 0 character)\&.
+.RE
+.PP
+\fB\-v\fR \fIsize\fR, \fB\-\-value\-buffer\-size=\fR\fIsize\fR
+.RS 4
+Size for value buffer (must be large enough to store the largest value string including the finalizing 0 character)\&.
+.RE
+.PP
+\fB\-R\fR, \fB\-\-reset\fR
+.RS 4
+Ignore preferences values for key and value buffer size\&.
+.RE
+.PP
+\fB\-\-help\fR
+.RS 4
+Show short help text\&.
+.RE
+.PP
+\fB\-\-version\fR
+.RS 4
+Show version and supported database backends\&.
+.RE
+.PP
+\fB\-\-license\fR
+.RS 4
+Show license terms\&.
+.RE
+.PP
+\fB\-\-manual\fR
+.RS 4
+Show this long help text\&.
+.RE
+.PP
+\fB\-\-verbose\fR
+.RS 4
+Show error message upon interrupt by SIGPIPE\&.
+.RE
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other status codes indicate an error\&.
+.SH "PREFERENCES"
+.PP
+\fBtext\-db\&.key\&.max\-size\fR
+.RS 4
+Size of key buffer if option \-k was not used\&.
+.RE
+.PP
+\fBtext\-db\&.value\&.max\-size\fR
+.RS 4
+Size of value buffer if option \-v was not used\&.
+.RE
+.SH "RESTRICTIONS"
+.sp
+There is no wildcard expansion for file names on Windows, * and ? can not be used in file names\&.
+.SH "NOTES"
+.sp
+This program uses DK libraries version 4\&.
+.SH "EXAMPLES"
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Show in\-memory database file1\&.dat
+.sp
+dk\-db2t mem::file1\&.dat
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Show Berkeley DB database file2\&.dat
+.sp
+dk\-db2t bdb::file2\&.dat
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Show NDBM database file3 (consisting of files file3\&.dir and file3\&.pag)
+.sp
+dk\-db2t ndbm::file3
+.RE
+.SH "AUTHORS"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/dk-dbco.1 b/support/dktools/man/man1/dk-dbco.1
new file mode 100644
index 0000000000..907d445f0c
--- /dev/null
+++ b/support/dktools/man/man1/dk-dbco.1
@@ -0,0 +1,185 @@
+'\" t
+.\" Title: dk-dbco
+.\" Author: [see the "AUTHORS" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2016
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "DK\-DBCO" "1" "09/03/2016" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dk-dbco \- Copy and convert simple databases
+.SH "SYNOPSIS"
+.sp
+\fBdk\-dbco\fR [\fIoptions\fR] \fIsource\fR \fIdestination\fR
+.SH "DESCRIPTION"
+.sp
+The program copies the records from a simple database into another simple database\&. The records are converted to the new database type if necessary\&.
+.sp
+A \fIsimple\fR \fIdatabase\fR is a Berkeley DB, NDBM or in\-memory database\&. The records are key/value pairs, both key and value are a byte array\&. Keys are unique\&.
+.sp
+Use type::filename to specify databases (Type and file name are separated by two colons)\&. The following type names can be used:
+.TS
+tab(:);
+lt lt
+lt lt
+lt lt.
+T{
+.sp
+bdb
+T}:T{
+.sp
+Berkeley DB
+T}
+T{
+.sp
+ndbm
+T}:T{
+.sp
+NDBM database
+T}
+T{
+.sp
+mem
+T}:T{
+.sp
+in\-memory database
+T}
+.TE
+.sp 1
+.SH "OPTIONS"
+.PP
+\fB\-a\fR, \fB\-\-add\fR
+.RS 4
+adds data to an existing database (modifies or adds records)\&. Without this option the program deletes an existing database and creates a new one\&.
+.RE
+.PP
+\fB\-k\fR \fIsize\fR, \fB\-\-key\-buffer\-size=\fR\fIsize\fR
+.RS 4
+Key buffer size (number of bytes), default: 4096\&.
+.RE
+.PP
+\fB\-v\fR \fIsize\fR, \fB\-\-value\-buffer\-size=\fR\fIsize\fR
+.RS 4
+Value buffer size (number of bytes), default: 4096\&.
+.RE
+.PP
+\fB\-R\fR, \fB\-\-reset\fR
+.RS 4
+Ignore preference values for key and value buffer size\&.
+.RE
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other status codes indicate an error\&.
+.SH "NOTES"
+.sp
+This program uses DK libraries version 4\&.
+.SH "PREFERENCES"
+.PP
+\fBdb\&.key\&.max\-size\fR
+.RS 4
+Key buffer size if the \-k option was not used\&.
+.RE
+.PP
+\fBdb\&.value\&.max\-size\fR
+.RS 4
+Value buffer size if the \-v option was not used\&.
+.RE
+.SH "EXAMPLES"
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Convert Berkeley DB database db1\&.db to in\-memory database db2\&.dat, truncate db2\&.dat if it already exists:
+.sp
+dk\-dbco bdb::db1\&.db mem::db2\&.dat
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Convert NDBM database db3 (consisting of files db3\&.dir and db3\&.pag) to in\-memory database db4\&.dat, keep existing records in db4\&.dat:
+.sp
+dk\-dbco \-a ndbm::db3 mem::db4\&.dat
+.RE
+.SH "AUTHORS"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/dk-eradisk.1 b/support/dktools/man/man1/dk-eradisk.1
new file mode 100644
index 0000000000..a4443a1fdc
--- /dev/null
+++ b/support/dktools/man/man1/dk-eradisk.1
@@ -0,0 +1,110 @@
+'\" t
+.\" Title: dk-eradisk
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 03/28/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "DK\-ERADISK" "1" "03/28/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dk-eradisk \- Generate patterns to erase disk before retiring it
+.SH "SYNOPSIS"
+.sp
+\fBdk\-eradisk\fR [\fIoptions\fR]
+.SH "DESCRIPTION"
+.sp
+The program generates a data stream to erase a disk\&. Before retiring a disk or handing a disk over to another user one should remove all contents\&. The output from dk\-eradisk can be used as input for the "dd" program to savely clean a disk\&.
+.SH "OPTIONS"
+.PP
+\fB\-p\fR \fInumber\fR, \fB\-\-pass=\fR\fInumber\fR
+.RS 4
+Pass number\&. Pass 0 (should be used as final pass) can be used to write 0 bytes, so operating systems recognize the disk as new from manufacturer\&. The pass number chooses the bit pattern, one from 0x00, 0xFF, 0x0F, 0xF0, 0x33, 0xCC, 0x55, or 0xAA\&. When doing multiple passes, start with the highest pass number, use pass number 0 for the final pass\&.
+.RE
+.PP
+\fB\-b\fR \fIsize\fR, \fB*\-\-blocksize=\fR\fIsize\fR
+.RS 4
+Block size (default: 4096)\&. The default is suitable for traditional hard disks\&. For flash memory (i\&.e\&. SSD) you should increase the value to 1m\&.
+.RE
+.PP
+\fB\-c\fR \fIsize\fR, \fB\-\-count=\fR\fIsize\fR
+.RS 4
+Number of blocks to write\&. The default 0 creates an endless sequence of blocks until the program is finished by signal\&.
+.RE
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other values indicate errors\&.
+.SH "NOTES"
+.sp
+This program uses DK libraries version 4\&.
+.SH "AUTHOR"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2015\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/dk-fic.1 b/support/dktools/man/man1/dk-fic.1
new file mode 100644
index 0000000000..53a395435c
--- /dev/null
+++ b/support/dktools/man/man1/dk-fic.1
@@ -0,0 +1,144 @@
+'\" t
+.\" Title: dk-fic
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 03/28/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "DK\-FIC" "1" "03/28/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dk-fic \- File integrity checker
+.SH "SYNOPSIS"
+.sp
+\fBdk\-fic\fR [\fIoptions\fR] [\fIfile(s)\fR]
+.SH "DESCRIPTION"
+.sp
+The program can either build file checksum list or check (verify) checksum lists\&. A checksum list contains message digests (MD5, SHA\-1, RIPEMD\-160 and SHA\-512), file size and file name\&. If support for the SHA\-512 message digest algorithm was not found during build process, the SHA\-512 message digest is skipped\&. Message digests are converted to text using ASCII\-85 encoding, not ASCII\-Hex\&. When building a file checksum list, the files specified as command line arguments contain lists of file names to produce checksums for\&. If no file is specified as argument, the list of file names is read from standard input\&. When verifying checksum lists, the files specified as command line arguments contain checksum lists previously produced\&. If no file is specified as argument, the checksum list is read from standard input\&.
+.SH "OPTIONS"
+.PP
+\fB\-c\fR, \fB\-\-check\fR
+.RS 4
+Check (verify) a checksum list\&. Without this option the program produces a checksum list\&.
+.RE
+.PP
+\fB\-v\fR, \fB\-\-verbose\fR
+.RS 4
+Messages for succeeded tests too when checking\&. By default a message is only produced for failed tests\&.
+.RE
+.PP
+\fB\-q\fR, \fB\-\-quiet\fR
+.RS 4
+No output for failed tests when checking a checksum list\&. Options \-v and \-q are mutually exclusive\&.
+.RE
+.PP
+\fB\-l\fR \fIsize\fR, \fB\-\-line\-size=\fR\fIsize\fR
+.RS 4
+Input line buffer size\&.
+.RE
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other values indicate errors\&.
+.SH "PREFERENCES"
+.PP
+\fBline\&.size\fR
+.RS 4
+Line buffer size if the \-l option was not used\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Produce a checksum list on Windows
+.RS 4
+dk\-ls \-r \-tf \-pn <directory> | dk\-fic > checklist\&.txt
+.RE
+.PP
+Produce a checksum list on non\-Windows systems
+.RS 4
+find <directory> \-type f | dk\-fic > checklist\&.txt
+.RE
+.PP
+Verify a checksum list
+.RS 4
+dk\-fic \-c < checklist\&.txt
+.RE
+.sp
+When creating a checksum list, make sure the checksum list file is not included in the checksum list itself\&.
+.SH "RESTRICTIONS"
+.sp
+On Windows the file name length is restricted to _MAX_PATH (260) characters if the file name contains a wildcard (* or ? character)\&.
+.SH "NOTES"
+.sp
+This program uses DK libraries version 4\&.
+.SH "AUTHOR"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2015\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.sp
+This product includes cryptographic software written by Eric Young (eay@cryptsoft\&.com)\&. This product includes software written by Tim Hudson (tjh@cryptsoft\&.com)\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/dk-hex.1 b/support/dktools/man/man1/dk-hex.1
new file mode 100644
index 0000000000..ea7d202173
--- /dev/null
+++ b/support/dktools/man/man1/dk-hex.1
@@ -0,0 +1,118 @@
+'\" t
+.\" Title: dk-hex
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2016
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "DK\-HEX" "1" "09/03/2016" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dk-hex \- Show file contents in hexadecimal notation
+.SH "SYNOPSIS"
+.sp
+\fBdk\-hex\fR [\fIoptions\fR] [\fIfile(s)\fR]
+.SH "DESCRIPTION"
+.sp
+The dk\-hex program shows file contents in hexadecimal or octal notation\&. Input is read from the specified files or from standard input if no files are specified\&.
+.SH "OPTIONS"
+.PP
+\fB\-o\fR, \fB\-\-octal\fR
+.RS 4
+Octal notation instead of hexadecimal notation\&.
+.RE
+.PP
+\fB\-a\fR, \fB\-\-addresses\fR
+.RS 4
+Addresses shown too\&.
+.RE
+.PP
+\fB\-t\fR, \fB\-\-text\fR
+.RS 4
+Show printable text characters too\&.
+.RE
+.PP
+\fB\-\-verbose\fR
+.RS 4
+Show error message upon interrupt by SIGPIPE\&.
+.RE
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other values indicate errors\&.
+.SH "RESTRICTION"
+.sp
+On Windows the file name length is restricted to _MAX_PATH (260) characters if the file name contains a wildcard (* or ? character)\&.
+.SH "NOTES"
+.sp
+This program uses DK libraries version 4\&.
+.SH "AUTHOR"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2015\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/dk-ls.1 b/support/dktools/man/man1/dk-ls.1
new file mode 100644
index 0000000000..21b5668346
--- /dev/null
+++ b/support/dktools/man/man1/dk-ls.1
@@ -0,0 +1,762 @@
+'\" t
+.\" Title: dk-ls
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2016
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "DK\-LS" "1" "09/03/2016" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dk-ls \- List files
+.SH "SYNOPSIS"
+.sp
+\fBdk\-ls\fR [\fIoptions\fR] [\fIfile(s)\fR]
+.SH "DESCRIPTION"
+.sp
+The dk\-ls program shows information about files\&.
+.SH "OPTIONS"
+.PP
+\fB\-r\fR, \fB\-\-recursive\fR
+.RS 4
+Recursive listing\&.
+.RE
+.PP
+\fB\-f\fR, \fB\-\-stay\-on\-filesystem\fR
+.RS 4
+Stay in the current file system for recursive listings\&.
+.RE
+.PP
+\fB\-p\fR \fIstring\fR, \fB\-\-print\-order=\fR\fIstring\fR
+.RS 4
+Print order\&. The string consists of key characters for information to print:
+.TS
+tab(:);
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt.
+T{
+n
+T}:T{
+Name
+T}
+T{
+N
+T}:T{
+Name, do not show symlink targets
+T}
+T{
+s
+T}:T{
+Size
+T}
+T{
+t
+T}:T{
+Type
+T}
+T{
+p
+T}:T{
+Permissions (attributes on Windows systems)
+T}
+T{
+c
+T}:T{
+Creation timestamp
+T}
+T{
+m
+T}:T{
+Modification timestamp
+T}
+T{
+a
+T}:T{
+Last access timestamp
+T}
+T{
+l
+T}:T{
+Number of (hard) links
+T}
+T{
+u
+T}:T{
+File owner UID
+T}
+T{
+g
+T}:T{
+File owner GID
+T}
+T{
+d
+T}:T{
+Device number
+T}
+T{
+i
+T}:T{
+Inode number
+T}
+T{
+r
+T}:T{
+Relative device number for special files
+T}
+T{
+w
+T}:T{
+Windows reparse tag value (on Windows systems only)
+.sp
+
+The default is \*(Aqmtpn\*(Aq on non\-Windows systems, \*(Aqmtn\*(Aq on Windows systems unless the \*(Aqprint\&.order\*(Aq preference is defined\&.
+T}
+.TE
+.sp 1
+.RE
+.PP
+\fB\-t\fR \fIstring\fR, \fB\-\-types=\fR\fIstring\fR
+.RS 4
+Types to show information for:
+.TS
+tab(:);
+lt lt
+lt lt.
+T{
+d
+T}:T{
+Directories
+T}
+T{
+f
+T}:T{
+Files
+T}
+.TE
+.sp 1
+.RE
+.PP
+\fB\-s\fR, \fB\-\-summary\fR
+.RS 4
+Show summary at end (total number of reported directories, files and size in bytes)\&.
+.RE
+.PP
+\fB\-m\fR \fIstring\fR, \fB\-\-message\-digest=\fR\fIstring\fR
+.RS 4
+Message digest and encoding, separated by a dot\&. Default is "sha\-1\&.hex" unless changed by the "message\&.digest" preference\&.
+.PP
+Message digests
+.RS 4
+.TS
+tab(:);
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt.
+T{
+md5
+T}:T{
+MD\-5
+T}
+T{
+ripemd\-160
+T}:T{
+RIPE\-MD 160
+T}
+T{
+sha\-1
+T}:T{
+SHA\-1
+T}
+T{
+sha\-224
+T}:T{
+SHA\-224
+T}
+T{
+sha\-256
+T}:T{
+SHA\-256
+T}
+T{
+sha\-384
+T}:T{
+SHA\-384
+T}
+T{
+sha\-512
+T}:T{
+SHA\-512
+T}
+.TE
+.sp 1
+.RE
+.PP
+Encodings
+.RS 4
+.TS
+tab(:);
+lt lt
+lt lt.
+T{
+hex
+T}:T{
+ASCII\-Hex encoding
+T}
+T{
+a85
+T}:T{
+ASCII\-85 encoding
+T}
+.TE
+.sp 1
+.RE
+.RE
+.PP
+\fB\-R\fR, \fB\-\-reset\fR
+.RS 4
+Ignore all preference values (\*(Aqprint\&.order\*(Aq and \*(Aqmessage\&.digest\*(Aq)\&.
+.RE
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other values indicate errors\&.
+.SH "DIAGNOSTICS"
+.sp
+A sequence of question marks is printed if the program fails to obtain device number, volume serial number, inode number, or file index number\&.
+.sp
+A single question mark is printed if the program fails to obtain number of links, file owner UID, or file owner GID\&.
+.sp
+A sequence of \*(Aqx\*(Aq characters is printed if a message digest is requested for anything else than a regular file or if the program failed to read the file\&.
+.SH "TYPE OUTPUT ON NON-WINDOWS SYSTEMS"
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+One link indicator character:
+.TS
+tab(:);
+lt lt
+lt lt
+lt lt
+lt lt.
+T{
+l
+T}:T{
+Symbolic link within the same file system
+T}
+T{
+L
+T}:T{
+Wide symbolic link (target on another file system)
+T}
+T{
+!
+T}:T{
+Dangling link (target does not exist)
+T}
+T{
+\-
+T}:T{
+Not a symbolic link
+T}
+.TE
+.sp 1
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+One file type character:
+.TS
+tab(:);
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt.
+T{
+d
+T}:T{
+Directory
+T}
+T{
+\-
+T}:T{
+Regular file
+T}
+T{
+p
+T}:T{
+Pipe (FIFO)
+T}
+T{
+c
+T}:T{
+Character special device
+T}
+T{
+b
+T}:T{
+Block special device
+T}
+T{
+s
+T}:T{
+Network socket
+T}
+T{
+C
+T}:T{
+Multiplexed character device
+T}
+T{
+B
+T}:T{
+Multiplexed block device
+T}
+T{
+D
+T}:T{
+Name service door
+T}
+T{
+e
+T}:T{
+Event port
+T}
+T{
+o
+T}:T{
+Xenix special file
+T}
+T{
+n
+T}:T{
+Xenix semaphore
+T}
+T{
+M
+T}:T{
+Xenix shared data
+T}
+T{
+v
+T}:T{
+VXFS compressed file
+T}
+T{
+n
+T}:T{
+Network special file
+T}
+T{
+w
+T}:T{
+Whiteout
+T}
+T{
+a
+T}:T{
+ACL shadow entry
+T}
+.TE
+.sp 1
+.RE
+.SH "PERMISSIONS OUTPUT ON NON-WINDOWS SYSTEMS"
+.sp
+The output consists of 3 groups: Permissions for file owner user, file owner group and other persons\&. Each group consists of 3 characters indicating read (\*(Aqr\*(Aq), write (\*(Aqw\*(Aq), and execute (\*(Aqx\*(Aq) permission\&.
+.sp
+If the set user ID bit is set, the execution permission character for the user is changed from \*(Aqx\*(Aq to \*(Aqs\*(Aq or from \*(Aq\-\*(Aq to \*(AqS\*(Aq\&. If the set group ID bit is set, the execution permission character for the group is changed from \*(Aqx\*(Aq to \*(Aqs\*(Aq or from \*(Aq\-\*(Aq to \*(AqS\*(Aq\&. If the restricted deletion flag or sticky bit is set, the execution permission character for others is changed from \*(Aqx\*(Aq to \*(Aqt\*(Aq or from \*(Aq\-\*(Aq to \*(AqT\*(Aq\&.
+.SH "TYPE OUTPUT ON WINDOWS SYSTEMS"
+.sp
+The output consists of 2 characters:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+One reparse point character:
+.TS
+tab(:);
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt.
+T{
+m
+T}:T{
+Mount point
+T}
+T{
+l
+T}:T{
+Symbolic link
+T}
+T{
+w
+T}:T{
+Mounted WIM image
+T}
+T{
+s
+T}:T{
+SIS reparse point
+T}
+T{
+n
+T}:T{
+NFS reparse point
+T}
+T{
+c
+T}:T{
+CSV reparse point
+T}
+T{
+d
+T}:T{
+DFS reparse point
+T}
+T{
+f
+T}:T{
+DFSR reparse point
+T}
+T{
+u
+T}:T{
+Deduplication reparse point
+T}
+T{
+h
+T}:T{
+HSM reparse point
+T}
+T{
+2
+T}:T{
+HSM2 reparse point
+T}
+T{
+r
+T}:T{
+Any other reparse point
+T}
+T{
+\-
+T}:T{
+Not a reparse point
+T}
+.TE
+.sp 1
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+One file type character:
+.TS
+tab(:);
+lt lt
+lt lt
+lt lt.
+T{
+d
+T}:T{
+Directory
+T}
+T{
+b
+T}:T{
+Block special device
+T}
+T{
+\-
+T}:T{
+Regular file
+T}
+.TE
+.sp 1
+.RE
+.SH "ATTRIBUTES OUTPUT ON WINDOWS SYSTEMS"
+.sp
+The output consists of 10 characters indicating the attributes, \*(Aq\-\*(Aq is used for unset attributes:
+.TS
+tab(:);
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt.
+T{
+.sp
+R
+T}:T{
+.sp
+Read only (File can not be modified)
+T}
+T{
+.sp
+S
+T}:T{
+.sp
+System (system file or directory)
+T}
+T{
+.sp
+H
+T}:T{
+.sp
+Hidden (not shown in directory listings or in Windows explorer)
+T}
+T{
+.sp
+I
+T}:T{
+.sp
+Not indexed (excluded from indexing)
+T}
+T{
+.sp
+C
+T}:T{
+.sp
+Compressed
+T}
+T{
+.sp
+E
+T}:T{
+.sp
+Encrypted
+T}
+T{
+.sp
+O
+T}:T{
+.sp
+Offline
+T}
+T{
+.sp
+P
+T}:T{
+.sp
+Sparse
+T}
+T{
+.sp
+T
+T}:T{
+.sp
+Temporary
+T}
+T{
+.sp
+V
+T}:T{
+.sp
+Virtual
+T}
+.TE
+.sp 1
+.SH "PREFERENCES"
+.PP
+\fBprint\&.order\fR
+.RS 4
+String, default output column order if the \-p option is not used\&.
+.RE
+.PP
+\fBmessage\&.digest\fR
+.RS 4
+String, default message digest type and encoding if the \-m option is not used\&.
+.RE
+.SH "RESTRICTIONS"
+.sp
+On Windows the file name length is restricted to _MAX_PATH (260) characters if the file name contains a wildcard (* or ? character)\&.
+.sp
+On Windows systems user management and file permission concepts differ significantly from the concepts on Linux and Unix systems\&. The characters \*(Aqu\*(Aq and \*(Aqg\*(Aq in the print order specification have no effect\&.
+.sp
+On Windows there are different functions available to obtain information about files\&. Sometimes a function delivering less information succeeds for files where the default function delivering more information fails (i\&.e\&. when non\-privileged processes ask for information about c:\epagefile\&.sys)\&. In such situations we can not print volume serial number, file index or number of links\&. Question marks are shown instead\&.
+.sp
+On non\-Windows systems there is no reparse point tag, so a \*(Aqw\*(Aq in the print order specification has no effect\&.
+.SH "NOTES"
+.sp
+This program uses DK libraries version 4\&.
+.SH "QUOTED FILE NAMES ON WINDOWS"
+.sp
+On Windows systems the backslash is used for two purposes:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+as separator between path name components and
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+as escape character, i\&.e\&. in double quoted strings\&.
+.RE
+.sp
+Quotes are used around text containing spaces to pass the entire text as one argument to a command\&. Unfortunately quoting also activates processing of backslashes as start of escape sequences\&.
+.sp
+Use either C:\e or "C:\e\e" to refer to the C:\e directory, but not "C:\e"\&.
+.SH "AUTHOR"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2015\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.TS
+tab(:);
+lt lt
+lt lt.
+T{
+.sp
+SF project page
+T}:T{
+.sp
+http://sourceforge\&.net/projects/dktools
+T}
+T{
+.sp
+DK tools home page
+T}:T{
+.sp
+http://dktools\&.sourceforge\&.net/dk\-ls\&.html
+T}
+.TE
+.sp 1
diff --git a/support/dktools/man/man1/dk-pwd.1 b/support/dktools/man/man1/dk-pwd.1
new file mode 100644
index 0000000000..0223d39fbb
--- /dev/null
+++ b/support/dktools/man/man1/dk-pwd.1
@@ -0,0 +1,105 @@
+'\" t
+.\" Title: dk-pwd
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 03/28/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "DK\-PWD" "1" "03/28/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dk-pwd \- Print working directory
+.SH "SYNOPSIS"
+.sp
+\fBdkpwd\fR [\fIoption(s)\fR]
+.SH "DESCRIPTION"
+.sp
+The program shows the current working directory name on standard output\&.
+.SH "OPTIONS"
+.PP
+\fB\-l\fR
+.RS 4
+Last part of name only\&.
+.RE
+.PP
+\fB\-b\fR
+.RS 4
+Backslashes (on Windows) replaced by slashes\&.
+.RE
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other values indicate errors\&.
+.SH "NOTES"
+.sp
+This program uses DK libraries version 4\&.
+.SH "AUTHOR"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2015\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/dk-pwgen.1 b/support/dktools/man/man1/dk-pwgen.1
new file mode 100644
index 0000000000..d135e0022e
--- /dev/null
+++ b/support/dktools/man/man1/dk-pwgen.1
@@ -0,0 +1,231 @@
+'\" t
+.\" Title: dk-pwgen
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 02/08/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "DK\-PWGEN" "1" "02/08/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dk-pwgen \- Password, pin, hexadecimal key generator
+.SH "SYNOPSIS"
+.sp
+\fBdk\-pwgen\fR [\fIoptions\fR]
+.SH "DESCRIPTION"
+.sp
+The dk\-pwgen program generates passwords, pins or hexadecimal keys (i\&.e\&. used for WiFi)\&. The output type is one of the following:
+.PP
+\fBNormal user password\fR
+.RS 4
+This is the default output type\&. Specify a range (or just a value) for password length, number of uppercase characters in the password, number of digits in the password and number of special characters in the password\&. The minimum password length must be at least the summary of uppercase, digits and special character maximum\&.
+.RE
+.PP
+\fBHard password\fR
+.RS 4
+Use \-h to switch to hard passwords and specify the length (either value or range)\&. Characters are choosen in the range 0x33 to 0x7A (\*(Aq!\*(Aq to \*(Aqz\*(Aq)\&.
+.RE
+.PP
+\fBBinary random data\fR
+.RS 4
+Use \-b to switch to binary data output and specify the length (either value or range)\&. This option is not available on Windows systems, use the dk\-rand program instead\&.
+.RE
+.PP
+\fBPin number\fR
+.RS 4
+Use \-p to switch to pin numbers and specify the length (either value or range)\&.
+.RE
+.PP
+\fBHexadecimal key\fR
+.RS 4
+Use \-x or \-X to switch to hexadecimal keys and specify the length (either value or range)\&.
+.RE
+.SH "OPTIONS"
+.PP
+\fB\-h\fR, \fB\-\-hard\fR
+.RS 4
+Hard password instead of normal user passwords\&.
+.RE
+.PP
+\fB\-b\fR, \fB\-\-binary\fR
+.RS 4
+Binary output instead of text output\&. This option is not available on Windows, use the dk\-rand program instead\&.
+.RE
+.PP
+\fB\-x\fR, \fB\-\-hex\fR
+.RS 4
+Hexadecimal key using \*(Aqa\*(Aq \&... \*(Aqf\*(Aq for 10 \&... 15\&.
+.RE
+.PP
+\fB\-X\fR, \fB\-\-Hex\fR
+.RS 4
+Hexadecimal key using \*(AqA\*(Aq \&... \*(AqF\*(Aq for 10 \&... 15\&.
+.RE
+.PP
+\fB\-p\fR, \fB\-\-pin\fR
+.RS 4
+PIN number\&.
+.RE
+.PP
+\fB\-l\fR \fIrange\fR, \fB\-\-length=\fR\fIrange\fR
+.RS 4
+Output length\&. Ranges are specified as
+\fImin\fR\-\fImax\fR, i\&.e\&. "6\-8"\&.
+.RE
+.PP
+\fB\-u\fR \fIrange\fR, \fB\-\-upper\-case=\fR\fIrange\fR
+.RS 4
+Number of upper case characters for normal user passwords\&.
+.RE
+.PP
+\fB\-d\fR \fIrange\fR, \fB\-\-digits=\fR\fIrange\fR
+.RS 4
+Number of digits for normal user passwords\&.
+.RE
+.PP
+\fB\-s\fR \fIrange\fR, \fB\-\-special=\fR\fIrange\fR
+.RS 4
+Number of special characters for normal user passwords\&.
+.RE
+.PP
+\fB\-n\fR, \fB\-\-no\-newline\fR
+.RS 4
+Suppress newline at end of output\&.
+.RE
+.PP
+\fB\-\-verbose\fR
+.RS 4
+Show error message upon interrupt by SIGPIPE\&.
+.RE
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other values indicate errors\&.
+.SH "NOTES"
+.sp
+This program uses DK libraries version 4\&.
+.SH "EXAMPLES"
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Create normal user password, 8 to 10 characters long, containing 1 to 3 upper case characters, 1 to 2 digits and 1 to 2 special characters:
+.sp
+dk\-pwgen \-l 8\-10 \-u 1\-3 \-d 1\-2 \-s 1\-2
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Create a harder password, 8 to 10 characters long:
+.sp
+dk\-pwgen \-h \-l 8\-10
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Create a numeric PIN, 6 characters long:
+.sp
+dk\-pwgen \-p \-l 6
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Create a hexadecimal key for WiFi, 64 characters long:
+.sp
+dk\-pwgen \-x \-l 64
+.RE
+.SH "AUTHOR"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2015\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.sp
+This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www\&.openssl\&.org/)\&. This product includes cryptographic software written by Eric Young (eay@cryptsoft\&.com)\&. This product includes software written by Tim Hudson (tjh@cryptsoft\&.com)\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/dk-rand.1 b/support/dktools/man/man1/dk-rand.1
new file mode 100644
index 0000000000..968cdddb23
--- /dev/null
+++ b/support/dktools/man/man1/dk-rand.1
@@ -0,0 +1,132 @@
+'\" t
+.\" Title: dk-rand
+.\" Author: [see the "AUTHORS" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2016
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "DK\-RAND" "1" "09/03/2016" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dk-rand \- Generate binary random data
+.SH "SYNOPSIS"
+.sp
+\fBdk\-rand\fR [\fB\-b\fR \fIsize\fR]
+.SH "DESCRIPTION"
+.sp
+The program generates binary random data\&.
+.SH "OPTIONS"
+.PP
+\fB\-b\fR \fIsize\fR
+.RS 4
+Number of bytes to generate\&.
+.RE
+.PP
+\fB\-\-help\fR
+.RS 4
+Show short help text\&.
+.RE
+.PP
+\fB\-\-version\fR
+.RS 4
+Show version information\&.
+.RE
+.PP
+\fB\-\-license\fR
+.RS 4
+Show license conditions\&.
+.RE
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other status codes indicate an error\&.
+.SH "NOTES"
+.sp
+This program uses DK libraries version 4\&.
+.SH "ENVIRONMENT"
+.PP
+\fBEGDSOCKET\fR
+.RS 4
+Path to EGD socket to obtain seed data from the entropy gathering daemon (EGD)\&.
+.RE
+.SH "FILES"
+.PP
+\fB/dev/random\fR
+.RS 4
+Preferred entropy source on non\-Windows systems\&.
+.RE
+.PP
+\fB/dev/urandom\fR
+.RS 4
+Alternative entropy source on non\-Windows systems\&.
+.RE
+.SH "AUTHORS"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/dk-recv.1 b/support/dktools/man/man1/dk-recv.1
new file mode 100644
index 0000000000..0a0323c68f
--- /dev/null
+++ b/support/dktools/man/man1/dk-recv.1
@@ -0,0 +1,150 @@
+'\" t
+.\" Title: dk-recv
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 03/28/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "DK\-RECV" "1" "03/28/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dk-recv \- Receive data from a dk\-send process
+.SH "SYNOPSIS"
+.sp
+\fBdk\-recv\fR [\fIoption(s)\fR] \fIhost\fR \fIport\fR [\fIfile\fR]
+.SH "DESCRIPTION"
+.sp
+The program establishes a TCP connection to the given host and port and receives data\&. Output is written to the given file or standard output\&.
+.SH "OPTIONS"
+.PP
+\fB\-t\fR, \fB\-\-transmission\fR
+.RS 4
+Tell dk\-send process to start transmission\&.
+.RE
+.PP
+\fB\-l\fR \fIport\fR, \fB\-\-local\-port=\fR\fIport\fR
+.RS 4
+Local port number to use (service name allowed)\&.
+.RE
+.PP
+\fB\-c\fR \fItimeout\fR, \fB\-\-connect\-timeout=\fR\fItimeout\fR
+.RS 4
+Timeout for connection (integer or floating point number)\&.
+.RE
+.PP
+\fB\-\-help\fR
+.RS 4
+Show short help screen\&.
+.RE
+.PP
+\fB\-\-manual\fR
+.RS 4
+Show manual text (this text)\&.
+.RE
+.PP
+\fB\-\-version\fR
+.RS 4
+Show version information\&.
+.RE
+.PP
+\fB\-\-license\fR
+.RS 4
+Show license\&.
+.RE
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other values indicate errors\&.
+.SH "EXAMPLES"
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Receive data and store on hard disk (or partition):
+.sp
+dk\-recv 192\&.0\&.2\&.103 9876 | dk\-blks \-b 4k | dd of=/dev/sda bs=4096
+.RE
+.SH "RESTRICTIONS"
+.sp
+On Windows the file name length is restricted to _MAX_PATH (260) characters if the file name contains a wildcard (* or ? character)\&.
+.SH "NOTES"
+.sp
+This program uses DK libraries version 4\&.
+.SH "AUTHOR"
+.sp
+Dirk Krause
+.SH "HISTORY"
+.sp
+The functionality of this program was available in \(lqdknet \-r\(rq in version 3\&.x\&.x\&.
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2015\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/dk-send.1 b/support/dktools/man/man1/dk-send.1
new file mode 100644
index 0000000000..4740b5bc29
--- /dev/null
+++ b/support/dktools/man/man1/dk-send.1
@@ -0,0 +1,175 @@
+'\" t
+.\" Title: dk-send
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 03/22/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "DK\-SEND" "1" "03/22/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dk-send \- Send data to one or multiple recipients (dk\-recv processes)
+.SH "SYNOPSIS"
+.sp
+\fBdk\-send\fR [\fIoption(s)\fR] \fIport\fR [\fIfile\fR]
+.SH "DESCRIPTION"
+.sp
+The program accepts incoming connection requests and establishes connections\&. The file contents (or data from standard input) is sent to all recipients\&.
+.SH "OPTIONS"
+.PP
+\fB\-n\fR \fInumber\fR, \fB\-\-number\-of\-clients=\fR\fInumber\fR
+.RS 4
+Number of expected clients or "unlimited"\&. When specifying "unlimited" here, the last client must use the \-t option\&.
+.RE
+.PP
+\fB\-a\fR \fIclients\fR, \fB\-\-allow=\fR\fIclients\fR
+.RS 4
+Comma\-separated list of allowed client addresses\&. Each client address consists of an IP address (IPv4 or IPv6), optionally followed by a netmask (IP address or bit number)\&. IP address and mask are separated by a slash\&.
+.RE
+.PP
+\fB\-l\fR, \fB\-\-local\-only\fR
+.RS 4
+Listen on local interfaces only\&.
+.RE
+.PP
+\fB\-b\fR \fInumber\fR, \fB\-\-backlog=\fR\fInumber\fR
+.RS 4
+Number of connection requests to queue if necessary\&.
+.RE
+.PP
+\fB\-c\fR \fItimeout\fR, \fB\-\-connect\-timeout=\fR\fItimeout\fR
+.RS 4
+Timeout in seconds for read attempt after establishing a connection\&.
+.RE
+.PP
+\fB\-p\fR, \fBis\-pipe\fR
+.RS 4
+Indicate that dk\-send is the end of a pipe\&. Without this option dk\-send stops reading input if all recipients disconnected\&. If the \-p option is used the dk\-send program continues reading input even if all recipients have disconnected, to avoid sending a SIGPIPE signal to the pipe feeder\&.
+.RE
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other values indicate errors\&.
+.SH "EXAMPLES"
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Send an entire hard disk or partition
+.sp
+dd if=/dev/sda bs=4096 | dk\-send 9876
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+\&... to 3 recipients
+.sp
+dd if=/dev/sda bs=4096 | dk\-send \-n 3 9876
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+\&... which must be in 192\&.0\&.2\&.0/255\&.255\&.255\&.0
+.sp
+dd if=/dev/sda bs=4096 | dk\-send \-n 3 \-a 192\&.0\&.2\&.0/255\&.255\&.255\&.0 9876
+.sp
+or
+.sp
+dd if=/dev/sda bs=4096 | dk\-send \-n 3 \-a 192\&.0\&.2\&.0/24 9876
+.RE
+.SH "RESTRICTIONS"
+.sp
+On Windows the file name length is restricted to _MAX_PATH (260) characters if the file name contains a wildcard (* or ? character)\&.
+.SH "NOTES"
+.sp
+This program uses DK libraries version 4\&.
+.SH "AUTHOR"
+.sp
+Dirk Krause
+.SH "HISTORY"
+.sp
+The functionality of this program was available in "dknet \-s" in version 3\&.x\&.x\&.
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2015\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/dk-sort.1 b/support/dktools/man/man1/dk-sort.1
new file mode 100644
index 0000000000..3a501c8c5a
--- /dev/null
+++ b/support/dktools/man/man1/dk-sort.1
@@ -0,0 +1,232 @@
+'\" t
+.\" Title: dk-sort
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 02/08/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "DK\-SORT" "1" "02/08/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dk-sort \- Sort text line by line
+.SH "SYNOPSIS"
+.sp
+\fBdk\-sort\fR [\fIoptions\fR] [\fIfile(s)\fR]
+.SH "DESCRIPTION"
+.sp
+The program sorts input text from the specified files (or from standard input if no file is specified) line by line\&.
+.SH "OPTIONS"
+.PP
+\fB\-i\fR \fIstring\fR, \fB\-\-input\-encoding=\fR\fIstring\fR
+.RS 4
+Expected input encoding\&. A byte order marker (BOM) at the beginning of the file overwrites the encoding specified here\&.
+.TS
+tab(:);
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt.
+T{
+ascii
+T}:T{
+ASCII or ISO\-8859\-1
+T}
+T{
+ansi
+T}:T{
+ANSI
+T}
+T{
+utf\-8
+T}:T{
+UTF\-8
+T}
+T{
+utf\-16
+T}:T{
+UTF\-16 in the systems default endianness
+T}
+T{
+utf\-16\-lsb
+T}:T{
+UTF\-16, least significant byte first
+T}
+T{
+utf\-16\-msb
+T}:T{
+UTF\-16, most significant byte first
+T}
+T{
+c32
+T}:T{
+32 bit character in the systems default endianness
+T}
+T{
+c32\-lsb
+T}:T{
+32 bit character, least significant byte first
+T}
+T{
+c32\-msb
+T}:T{
+32 bit character, most significant byte first
+T}
+.TE
+.sp 1
+.RE
+.PP
+\fB\-c\fR, \fB\-\-case\-insensitive\fR
+.RS 4
+Case\-insensitive comparisons\&.
+.RE
+.PP
+\fB\-b\fR, \fB\-\-ignore\-leading\-blanks\fR
+.RS 4
+Ignore leading whitespace sequences at start of line\&.
+.RE
+.PP
+\fB\-w\fR, \fB\-\-normalize\fR
+.RS 4
+Normalize lines (delete leading and trailing whitespace sequences and replace other whitespace sequences by one space)\&.
+.RE
+.PP
+\fB\-e\fR, \fB\-\-suppress\-empty\-lines\fR
+.RS 4
+Suppress empty lines\&.
+.RE
+.PP
+\fB\-n\fR, \fB\-\-number\fR
+.RS 4
+Compare lines by leading integer number\&.
+.RE
+.PP
+\fB\-u\fR, \fB\-\-unsigned\fR
+.RS 4
+Compare lines by leading unsigned integer number\&.
+.RE
+.PP
+\fB\-x\fR, \fB\-\-hex\fR
+.RS 4
+Compare lines by leading unsigned integer number in hexadecimal notation\&.
+.RE
+.PP
+\fB\-f\fR, \fB\-\-float\fR
+.RS 4
+Compare lines by leading floating point number (C data type double is used)\&.
+.RE
+.PP
+\fB\-v\fR, \fB\-\-value\-lines\-first\fR
+.RS 4
+Write lines containing a value (\-n, \-u, \-x, \-f) before lines containing no value\&. Default is to write the lines without value first\&.
+.RE
+.PP
+\fB\-m\fR, \fB\-\-merge\-equal\-lines\fR
+.RS 4
+Write only one line from a sequence of equal lines to output\&.
+.RE
+.PP
+\fB\-r\fR, \fB\-\-reverse\fR
+.RS 4
+Reversed sort order\&.
+.RE
+.PP
+\fB\-l\fR \fIsize\fR, \fB\-\-line\-size=\fR\fIsize\fR
+.RS 4
+Line buffer size (default and minimum is 1024)\&.
+.RE
+.PP
+\fB\-R\fR, \fB\-\-reset\fR
+.RS 4
+Ignore preference settings for line buffer size\&.
+.RE
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other values indicate errors\&.
+.SH "PREFERENCES"
+.PP
+\fBline\&.size\fR
+.RS 4
+Line buffer size if the \-l option is not used\&.
+.RE
+.SH "RESTRICTIONS"
+.sp
+On Windows the file name length is restricted to _MAX_PATH (260) characters if the file name contains a wildcard (* or ? character)\&.
+.SH "NOTES"
+.sp
+This program uses DK libraries version 4\&.
+.SH "AUTHOR"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2015\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/dk-sqlsplit.1 b/support/dktools/man/man1/dk-sqlsplit.1
new file mode 100644
index 0000000000..8800ecd604
--- /dev/null
+++ b/support/dktools/man/man1/dk-sqlsplit.1
@@ -0,0 +1,99 @@
+'\" t
+.\" Title: dk-sqlsplit
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 03/28/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "DK\-SQLSPLIT" "1" "03/28/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dk-sqlsplit \- Split overlong SQL lines
+.SH "SYNOPSIS"
+.sp
+\fBdk\-sqlsplit\fR [\fIfile(s)\fR]
+.SH "DESCRIPTION"
+.sp
+The program splits overlong SQL lines (i\&.e\&. produced by mysqldump) at record borders\&. Record borders are sequences of closing bracket, comma, and opening bracket outside single quoted, double quoted, or back\-tick quoted strings or comments\&.
+.sp
+The program reads input from standard input or from the specified files and writes output to standard output\&.
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other values indicate errors\&.
+.SH "RESTRICTIONS"
+.sp
+On Windows the file name length is restricted to _MAX_PATH (260) characters if the file name contains a wildcard (* or ? character)\&.
+.SH "NOTES"
+.sp
+This program uses DK libraries version 4\&.
+.SH "AUTHOR"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2015\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/dk-t2db.1 b/support/dktools/man/man1/dk-t2db.1
new file mode 100644
index 0000000000..624ac379ce
--- /dev/null
+++ b/support/dktools/man/man1/dk-t2db.1
@@ -0,0 +1,232 @@
+'\" t
+.\" Title: dk-t2db
+.\" Author: [see the "AUTHORS" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 03/28/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "DK\-T2DB" "1" "03/28/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dk-t2db \- Text to database converter
+.SH "SYNOPSIS"
+.sp
+\fBdk\-t2db\fR [\fIoptions\fR] [\fIfile\fR\&...] \fIdatabase\fR
+.SH "DESCRIPTION"
+.sp
+The program converts text from the specified files or standard input into a simple text database\&.
+.sp
+A \fIsimple\fR \fIdatabase\fR is a Berkeley DB, NDBM or in\-memory database\&. The records are key/value pairs, both key and value are a byte array\&. Keys are unique\&.
+.sp
+In a \fIsimple\fR \fItext\fR \fIdatabase\fR all keys and values are text strings\&. The finalizing 0 character is saved in the database together with the texts\&.
+.sp
+Use type::filename to specify databases (Type and file name are separated by two colons)\&. The following type names can be used:
+.TS
+tab(:);
+lt lt
+lt lt
+lt lt.
+T{
+.sp
+bdb
+T}:T{
+.sp
+Berkeley DB
+T}
+T{
+.sp
+ndbm
+T}:T{
+.sp
+NDBM database
+T}
+T{
+.sp
+mem
+T}:T{
+.sp
+in\-memory database
+T}
+.TE
+.sp 1
+.SH "OPTIONS"
+.PP
+\fB\-a\fR, \fB\-\-add\fR
+.RS 4
+adds data to an existing database (modifies or adds records)\&. Without this option the program deletes an exisiting database and creates a new one\&.
+.RE
+.PP
+\fB\-R\fR, \fB\-\-reset\fR
+.RS 4
+ignores preference values for line, key and value buffer size\&.
+.RE
+.PP
+\fB\-l\fR \fIsize\fR, \fB\-\-line\-size=\fR\fIsize\fR
+.RS 4
+Line buffer size (number of characters), default: 1024\&.
+.RE
+.PP
+\fB\-k\fR \fIsize\fR, \fB\-\-key\-buffer\-size=\fR\fIsize\fR
+.RS 4
+Key buffer size (number of characters), default: 512\&.
+.RE
+.PP
+\fB\-v\fR \fIsize\fR, \fB\-\-value\-buffer\-size=\fR\fIsize\fR
+.RS 4
+Value buffer size (number of characters), default: 512\&.
+.RE
+.PP
+\fB\-i\fR \fIstring\fR, \fB\-\-input\-encoding=\fR\fIstring\fR
+.RS 4
+Expected input encoding\&. The encoding is overwritten if a byte order marker (BOM) is found at the start of input\&.
+.RE
+.PP
+\fB\-c\fR \fIstring\fR, \fB\-\-comment=\fR\fIstring\fR
+.RS 4
+Optional comment character\&. All lines having the comment character as first non\-whitespace character are comments\&.
+.RE
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other status codes indicate an error\&.
+.SH "PREFERENCES"
+.PP
+\fBline\&.size\fR
+.RS 4
+Input line buffer size
+.RE
+.PP
+\fBtext\-db\&.key\&.max\-size\fR
+.RS 4
+Key buffer size
+.RE
+.PP
+\fBtext\-db\&.value\&.max\-size\fR
+.RS 4
+Value buffer size
+.RE
+.SH "FILES"
+.sp
+Input files are text files\&. Each text line specifies one record\&. The first word in a line (first sequence of non\-whitespace characters) is the key text\&. All further text started by the second word until the line end is used as value\&.
+.sp
+The key can not contain spaces, the value can contain spaces\&.
+.sp
+A line containing just a key but no value results in deletion of the specified record\&.
+.SH "EXAMPLES"
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Process standard input, create in\-memory database file db\&.dat:
+.sp
+dk\-t2db \-c "#" mem::db\&.dat
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Process text input file db\&.in, create Berkeley DB file bdb\&.dat:
+.sp
+dk\-t2db \-c "#" db\&.in bdb::bdb\&.dat
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Process text input file db\&.in, modify existing NDBM database ndbm\&.dat:
+.sp
+dk\-t2db \-a \-c "#" db\&.in ndbm::ndbm\&.dat
+.RE
+.SH "RESTRICTIONS"
+.sp
+On Windows the file name length is restricted to _MAX_PATH (260) characters if the file name contains a wildcard (* or ? character)\&.
+.sp
+Wildcards can not be used to specify the database file name\&.
+.SH "NOTES"
+.sp
+This program uses DK libraries version 4\&.
+.SH "AUTHORS"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/dk-t2h.1 b/support/dktools/man/man1/dk-t2h.1
new file mode 100644
index 0000000000..3ebb68711a
--- /dev/null
+++ b/support/dktools/man/man1/dk-t2h.1
@@ -0,0 +1,186 @@
+'\" t
+.\" Title: dk-t2h
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 03/28/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "DK\-T2H" "1" "03/28/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dk-t2h \- Text to HTML converter
+.SH "SYNOPSIS"
+.sp
+\fBdk\-t2h\fR [\fIoptions\fR] [\fIfile(s)\fR]
+.SH "DESCRIPTION"
+.sp
+The program converts text from the specified files or standard input to HTML\&. Alternatively you can use the \-e option to convert text specified on the command line\&.
+.SH "OPTIONS"
+.PP
+\fB\-i\fR \fIstring\fR, \fB\-\-input\-encoding=\fR\fIstring\fR
+.RS 4
+Expected input encoding, overwritten if a byte order marker (BOM) is found at start of input\&.
+.TS
+tab(:);
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt.
+T{
+ascii
+T}:T{
+ASCII or ISO\-8859\-1
+T}
+T{
+ansi
+T}:T{
+ANSI
+T}
+T{
+utf\-8
+T}:T{
+UTF\-8
+T}
+T{
+utf\-16
+T}:T{
+UTF\-16 in the systems default endianness
+T}
+T{
+utf\-16\-le
+T}:T{
+UTF\-16, least significant byte first
+T}
+T{
+utf\-16\-be
+T}:T{
+UTF\-16, most significant byte first
+T}
+T{
+c32
+T}:T{
+32 bit character in the systems default endianness
+T}
+T{
+c32\-le
+T}:T{
+32 bit character, least significant byte first
+T}
+T{
+c32\-be
+T}:T{
+32 bit character, most significant byte first
+T}
+.TE
+.sp 1
+.RE
+.PP
+\fB\-l\fR, \fB\-\-code\-lines\fR
+.RS 4
+Wrap all lines into <code title="001">\&...</code>\&.
+.RE
+.PP
+\fB\-e\fR, \fB\-\-echo\fR
+.RS 4
+Convert the command line arguments, do not treat them as file names\&.
+.RE
+.PP
+\fB\-f\fR, \fB\-\-full\fR
+.RS 4
+Produce a full HTML file, not just a fragment\&. Options \-e and \-f are mutually exclusive\&.
+.RE
+.PP
+\fB\-t\fR \fIstring\fR, \fB\-\-title=\fR\fIstring\fR
+.RS 4
+Title for full HTML file, ignored if the \-f option is not present\&.
+.RE
+.PP
+\fB\-\-verbose\fR
+.RS 4
+Show error message upon interrupt by SIGPIPE\&.
+.RE
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other values indicate errors\&.
+.SH "RESTRICTIONS"
+.sp
+On Windows the file name length is restricted to _MAX_PATH (260) characters if the file name contains a wildcard (* or ? character)\&.
+.SH "NOTES"
+.sp
+This program uses DK libraries version 4\&.
+.SH "AUTHOR"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2015\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/dk-t2l.1 b/support/dktools/man/man1/dk-t2l.1
new file mode 100644
index 0000000000..e692252e23
--- /dev/null
+++ b/support/dktools/man/man1/dk-t2l.1
@@ -0,0 +1,236 @@
+'\" t
+.\" Title: dk-t2l
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 03/28/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "DK\-T2L" "1" "03/28/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dk-t2l \- Text to LaTeX converter
+.SH "SYNOPSIS"
+.sp
+\fBdk\-t2l\fR [\fIoptions\fR] [\fIfile(s)\fR]
+.SH "DESCRIPTION"
+.sp
+The program converts text from the specified files or standard input to LaTeX\&. Alternatively you can use the \-e option to convert text specified on the command line\&.
+.SH "OPTIONS"
+.PP
+\fB\-i\fR \fIstring\fR, \fB\-\-input\-encoding=\fR\fIstring\fR
+.RS 4
+Expected input encoding, overwritten if a byte order marker (BOM) is found at start of input\&.
+.TS
+tab(:);
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt.
+T{
+ascii
+T}:T{
+ASCII or ISO\-8859\-1
+T}
+T{
+ansi
+T}:T{
+ANSI
+T}
+T{
+utf\-8
+T}:T{
+UTF\-8
+T}
+T{
+utf\-16
+T}:T{
+UTF\-16 in the systems default endianness
+T}
+T{
+utf\-16\-le
+T}:T{
+UTF\-16, least significant byte first
+T}
+T{
+utf\-16\-be
+T}:T{
+UTF\-16, most significant byte first
+T}
+T{
+c32
+T}:T{
+32 bit character in the systems default endianness
+T}
+T{
+c32\-le
+T}:T{
+32 bit character, least significant byte first
+T}
+T{
+c32\-be
+T}:T{
+32 bit character, most significant byte first
+T}
+.TE
+.sp 1
+.RE
+.PP
+\fB\-e\fR, \fB\-\-echo\fR
+.RS 4
+Convert the command line arguments, do not treat them as file names\&.
+.RE
+.PP
+\fB\-n\fR, \fB\-\-numeric\fR
+.RS 4
+Command line arguments are characters given as decimal numbers\&.
+.RE
+.PP
+\fB\-h\fR, \fB\-\-hex\fR
+.RS 4
+Command line arguments are characters given as hexadecimal numbers\&.
+.RE
+.PP
+\fB\-r\fR, \fB\-\-recommendations\fR
+.RS 4
+Write usable font encodings and recommended LaTeX packages list\&.
+.RE
+.PP
+\fB\-l\fR, \fB\-\-line\-feed\fR
+.RS 4
+Write \e\e sequence before newline (default is to simply write the newline)\&.
+.RE
+.PP
+\fB\-t\fR, \fB\-\-tabulator\fR
+.RS 4
+Write \eHT{} for tabulators (default is to write a space)\&.
+.RE
+.PP
+\fB\-\-verbose\fR
+.RS 4
+Show error message upon interrupt by SIGPIPE\&.
+.RE
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other values indicate errors\&.
+.SH "FILES"
+.sp
+The program uses translation tables in *\&.t2l files to convert from UNICODE to LaTeX\&. Typically the files are stored in the ${datadir}/dktools/charmap directory\&. The files consist of empty lines, comment lines, and data lines\&. A comment line is started by a raute character \*(Aq#\*(Aq as first text character\&. A data line consists of several texts, separated by whitespaces or whitespace sequences\&. It contains the following components:
+.PP
+\fBHexadecimal character value (required)\fR
+.RS 4
+The UNICODE standard uses 24 (newer versions) or 32 bits (older versions) for characters\&. The character value in a data line must be in the range 0\&...FFFFFFFF\&.
+.RE
+.PP
+\fBb=\fR\fIstring\fR (optional)
+.RS 4
+A LaTeX sequence that can be used in both math mode and non\-math mode for the character\&.
+.sp
+At least one from b=\&..., t=\&... m=\&... is required\&.
+.RE
+.PP
+\fBt=\fR\fIstring\fR (optional)
+.RS 4
+A LaTeX sequence that can be used in text mode (non\-math mode) for the character\&.
+.RE
+.PP
+\fBm=\fR\fIstring\fR (optional)
+.RS 4
+A LaTeX sequence that can be used in math mode for the characters\&.
+.RE
+.PP
+\fBe=\fR\fIstring\fR (optional)
+.RS 4
+Information about font encodings\&. You can either specify the font encodings usable in a comma\-separated list ("ot1", "t1", "t4", "t5"), i\&.e\&. "t1,ot1" or use an exclamation mark to specify a list of denied encoding, i\&.e\&. "!t4,t5"\&.
+.RE
+.PP
+\fBp=\fR\fIstring\fR (optional)
+.RS 4
+Information about LaTeX packages required\&.
+.RE
+.SH "RESTRICTIONS"
+.sp
+On Windows the file name length is restricted to _MAX_PATH (260) characters if the file name contains a wildcard (* or ? character)\&.
+.sp
+The program uses translation tables in *\&.t2l files to convert from UNICODE to LaTeX\&. UNICODE contains 1,114,112 characters (wikipedia article, 2015\-05\-12), so I can not provide complete tables for all characters\&. As I am a native German speaker, the tables include support for some Central European languages\&.
+.SH "NOTES"
+.sp
+This program uses DK libraries version 4\&.
+.SH "CONTRIBUTIONS"
+.sp
+You can provide further translation tables from UNICODE to LaTeX, please use the SourceForge project page http://sourceforge\&.net/projects/dktools to contact me (forums, patches)\&. I can only accept your work if you use a 3 clauses BSD license\&. I think translation tables should be made by native speakers of a language (or at least people experienced in the language) with at least some LaTeX experience\&.
+.SH "AUTHOR"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2015\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/dk-uid.1 b/support/dktools/man/man1/dk-uid.1
new file mode 100644
index 0000000000..6e16b4a66d
--- /dev/null
+++ b/support/dktools/man/man1/dk-uid.1
@@ -0,0 +1,117 @@
+'\" t
+.\" Title: dk-uid
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 02/08/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "DK\-UID" "1" "02/08/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dk-uid \- Find free user ID
+.SH "SYNOPSIS"
+.sp
+\fBdk\-uid\fR \fImin\fR \fImax\fR
+.SH "DESCRIPTION"
+.sp
+The program searches for the first free UID in a given range and writes the number to standard output\&.
+.SH "ARGUMENTS"
+.TS
+tab(:);
+lt lt
+lt lt.
+T{
+.sp
+\fImin\fR
+T}:T{
+.sp
+Minimum UID number\&.
+T}
+T{
+.sp
+\fImax\fR
+T}:T{
+.sp
+Maximum UID number\&.
+T}
+.TE
+.sp 1
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other values indicate errors\&.
+.SH "NOTES"
+.sp
+This program uses DK libraries version 4\&.
+.sp
+It is not available on the Windows platform\&.
+.SH "AUTHOR"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2015\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/dk3info.1 b/support/dktools/man/man1/dk3info.1
new file mode 100644
index 0000000000..8a76b0d38e
--- /dev/null
+++ b/support/dktools/man/man1/dk3info.1
@@ -0,0 +1,97 @@
+'\" t
+.\" Title: dk3info
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 05/25/2016
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "DK3INFO" "1" "05/25/2016" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dk3info \- Information about directories and features
+.SH "SYNOPSIS"
+.sp
+\fBdk3info\fR [\fB\-l\fR]
+.SH "DESCRIPTION"
+.sp
+The program shows the directories currently used and the directories configured during build process\&. Option \-l additionally prints the compiler constants created by the configure script\&.
+.SH "OPTIONS"
+.PP
+\fB\-l\fR
+.RS 4
+Show compiler constants\&.
+.RE
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other values indicate errors\&.
+.SH "AUTHOR"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2015\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/dk4info.1 b/support/dktools/man/man1/dk4info.1
new file mode 100644
index 0000000000..77cd6e669e
--- /dev/null
+++ b/support/dktools/man/man1/dk4info.1
@@ -0,0 +1,97 @@
+'\" t
+.\" Title: dk4info
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 01/03/2016
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "DK4INFO" "1" "01/03/2016" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dk4info \- Information about directories and features
+.SH "SYNOPSIS"
+.sp
+\fBdk4info\fR [\fB\-l\fR]
+.SH "DESCRIPTION"
+.sp
+The program shows the directories currently used and the directories configured during build process\&. Option \-l additionally prints the compiler constants created by the configure script\&.
+.SH "OPTIONS"
+.PP
+\fB\-l\fR
+.RS 4
+Show compiler constants\&.
+.RE
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other values indicate errors\&.
+.SH "AUTHOR"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2015\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/dkct.1 b/support/dktools/man/man1/dkct.1
new file mode 100644
index 0000000000..21bfd73931
--- /dev/null
+++ b/support/dktools/man/man1/dkct.1
@@ -0,0 +1,201 @@
+'\" t
+.\" Title: dkct
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 03/28/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "DKCT" "1" "03/28/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dkct \- Dirk Krause\*(Aqs C tool
+.SH "SYNOPSIS"
+.sp
+\fBdkt\fR [\fIoptions\fR] [\fIfiles\fR]
+.sp
+DESCRIPTION
+.sp
+The program provides:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+A preprocessor for debug/trace instructions,
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+a code generator for state machines,
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+a code generator for GUIs using the wxWidgets library\&.
+.RE
+.sp
+The program converts *\&.ctr, *\&.cpt, *\&.mtr and *\&.jtr files to *\&.c, *\&.cpp, *\&.m and *\&.java\&. The source files can contain debug instructions in a special notation\&. When producing release versions the debug instructions are ignored\&. When producing debug versions the debug instructions are converted to output instructions\&.
+.SH "OPTIONS"
+.PP
+\fB\-R\fR, \fB\-\-reset\fR
+.RS 4
+Ignore all settings from configuration files\&.
+.RE
+.PP
+\fB\-d\fR, \fB\-\-debug\fR
+.RS 4
+Create debug output\&.
+.RE
+.PP
+\fB\-s\fR, \fB\-\-debug\-stdout\fR
+.RS 4
+Debug output goes to standard output\&.
+.RE
+.PP
+\fB\-t\fR, \fB\-\-timestamp\fR
+.RS 4
+Debug output contains a timestamp\&.
+.RE
+.PP
+\fB\-k\fR, \fB\-\-trace\-keyword\fR
+.RS 4
+Debug output contains "trace" string\&.
+.RE
+.PP
+\fB\-w\fR, \fB\-\-windows\-wide\-char\fR
+.RS 4
+Prepare debug output for wchar_t\&.
+.RE
+.PP
+\fB\-p\fR, \fB\-\-portable\-output\fR
+.RS 4
+Create portable debug output code (implies \-w)\&.
+.RE
+.PP
+\fB\-l\fR, \fB\-\-line\-numbers\fR
+.RS 4
+Write preprozessor directives "#line \&..." to output\&.
+.RE
+.PP
+\fB\-m\fR, \fB\-\-make\fR
+.RS 4
+Make mode: rebuild destination files only if necessary\&.
+.RE
+.PP
+\fB\-b\fR \fIwidth\fR, \fB\-\-box\-width=\fR\fIwidth\fR
+.RS 4
+Set box with for comment boxes\&.
+.RE
+.PP
+\fB\-h\fR, \fB\-\-help\fR
+.RS 4
+Show help text\&.
+.RE
+.PP
+\fB\-v\fR, \fB\-\-version\fR
+.RS 4
+Show version number\&.
+.RE
+.PP
+\fB\-L\fR, \fB\-\-license\-terms\fR
+.RS 4
+Show license conditions\&.
+.RE
+.SH "EXIT STATUS"
+.sp
+The program returns 0 on success, any other value indicates an error\&.
+.SH "NOTES"
+.sp
+This program uses DK libraries version 3\&.
+.SH "AUTHOR"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2011\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+\fBdkct(5)\fR
+.RS 4
+Input file syntax for dkct (*\&.ctr, *\&.cpt, *\&.mtr files)\&.
+.RE
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/dkdbt.1 b/support/dktools/man/man1/dkdbt.1
new file mode 100644
index 0000000000..5dd3013353
--- /dev/null
+++ b/support/dktools/man/man1/dkdbt.1
@@ -0,0 +1,326 @@
+'\" t
+.\" Title: dkdbt
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 03/28/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "DKDBT" "1" "03/28/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dkdbt \- Dirk Krause\*(Aqs database tool
+.SH "SYNOPSIS"
+.sp
+\fBdkdbt\fR \fBcopy\fR [\fB\-a\fR] \fIsource\-db\-name\fR \fIdestination\-db\-name\fR
+.sp
+\fBdkdbt\fR \fBmake\fR [\fB\-c\fR \fIchar\fR] [\fB\-a\fR] [\fB\-i\fR \fIencoding\fR] \fIdestination\-db\-name\fR [\fIfile(s)\fR]
+.sp
+\fBdkdbt\fR \fBtext\fR [\fB\-o\fR \fIencoding\fR] \fIsource\-db\-name\fR [\fIfile\fR]
+.sp
+\fBdkdbt\fR \fBsplit\-sql\-lines\fR [\fIinputfile\fR [\fIoutputfile\fR]]
+.sp
+\fBdkdbt\fR \fBhelp\fR
+.sp
+\fBdkdbt\fR \fBversion\fR
+.sp
+\fBdkdbt\fR \fBlicense\fR
+.sp
+\fBdkdbt\fR \fBfeatures\fR
+.SH "DESCRIPTION"
+.sp
+The dkdbt program handles simple databases containing text entries\&.
+.PP
+\fBcopy\fR
+.RS 4
+Copy records from the source database
+\fIsource\-db\-name\fR
+to the destination database
+\fIdestination\-db\-name\fR\&. The destination database is truncated by default before filling it\&. Use the \*(Aq\-a\*(Aq option to append to an existing database\&.
+.RE
+.PP
+\fBmake\fR
+.RS 4
+Make database, copy records from text file(s) to a destination database
+\fIdestination\-db\-name\fR\&. The destination database is truncated by default before filling it\&. Use the \*(Aq\-a\*(Aq option to append to an existing database\&. Use the \*(Aq\-c\*(Aq option to specify the character introducing comment lines\&. i\&.e\&. \*(Aq#\*(Aq\&.
+.RE
+.PP
+\fBtext\fR
+.RS 4
+Show a database as text\&. Output is written to standard output unless an output file name is specified\&. The systems default encoding is used for text output unless the \*(Aq\-o\*(Aq option is used\&.
+.RE
+.PP
+\fBsplit\-sql\-lines\fR
+.RS 4
+Split overlong output lines in mysqldump output\&. The mysqldump program writes all records from a table into one text line\&.
+.sp
+Text lines are separated at \*(Aq),(\*(Aq patterns\&. The splitting algorithm is very simple, you should use dkdbt sqlsplit only on text databases not containing \*(Aq),(\*(Aq in key or value text\&.
+.RE
+.PP
+\fBhelp\fR
+.RS 4
+Print a short help screen\&.
+.RE
+.PP
+\fBversion\fR
+.RS 4
+Print version number and short information about supported database types\&.
+.RE
+.PP
+\fBlicense\fR
+.RS 4
+Print license terms for dkdbt and the used libraries\&.
+.RE
+.PP
+\fBfeatures\fR
+.RS 4
+Show information about supported database types\&.
+.RE
+.SH "OPTIONS"
+.PP
+\fB\-a\fR
+.RS 4
+Append to an existing database instead of creating a new one\&.
+.RE
+.PP
+\fB\-c\fR \fIcharacter\fR
+.RS 4
+Character to mark a line as comment line (must be the first character in line without leading spaces)\&.
+.RE
+.PP
+\fB\-i\fR \fIencoding\fR
+.RS 4
+Expected input encoding\&. Overwritten if a byte order marker (BOM) is found at start of input\&.
+.TS
+tab(:);
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt.
+T{
+PLAIN
+T}:T{
+ASCII or ISO\-LATIN\-1
+T}
+T{
+UTF\-8
+T}:T{
+UTF\-8
+T}
+T{
+UTF\-16
+T}:T{
+UTF\-16, systems default endianness
+T}
+T{
+UTF\-16\&.MSB
+T}:T{
+UTF\-16, most significant byte first
+T}
+T{
+UTF\-16\&.LSB
+T}:T{
+UTF\-16, least significant byte first
+T}
+T{
+C32
+T}:T{
+32 bit character, systems default endianness
+T}
+T{
+C32\&.MSB
+T}:T{
+32 bit character, most significant byte first
+T}
+T{
+C32\&.LSB
+T}:T{
+32 bit character, least significant byte first
+T}
+.TE
+.sp 1
+.RE
+.PP
+\fB\-o\fR \fIencoding\fR
+.RS 4
+Output encoding for text output\&. See the \-i option\&.
+.RE
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other status codes indicate an error\&.
+.SH "FILES"
+.sp
+\fBDatabase names\fR
+.sp
+The following database types can be used:
+.PP
+\fBmem\fR
+.RS 4
+In\-memory database implemented in the dk3dbi module from the DK tools project\&. No external library required\&.
+.RE
+.PP
+\fBbdb\fR
+.RS 4
+The Berkeley DB\&. Only available if the Berkeley DB libraries and header files were available when building dkdbt\&.
+.RE
+.PP
+\fBndbm\fR
+.RS 4
+NDBM API\&. Only available if the appropriate libraries and header files were available and acceptable when building dkdbt\&.
+.sp
+Acceptable means: Not the NDBM implementation from the GDBM package, as GDBM is GPL\-licensed and DK tools is BSD licensed\&.
+.RE
+.sp
+To specify a database name, separate database type and file name by two colons\&. Example: mem::/var/run/my\-library
+.sp
+\fBFile structure for mem:: databases\fR
+.sp
+All records in the databases dkdbt can handle consist of a text key and a text value\&. Four items are stored in the file for each record:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The key length as size_t in the systems size and endianness\&. The length includes the finalizing 0 character\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The value length as size_t in the systems size and endianness\&. The length includes the finalizing 0 character\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The key text including the finalizing 0 character\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The value text including the finalizing 0 character\&.
+.RE
+.sp
+\fBText input files for databases\fR
+.sp
+The files consist of one record per line\&. Each record consists of a key and a value\&. The key is the first word in the line consisting of non\-whitespace characters\&. The value starts at the first word after the key and contains all remaining text in the line\&. Key and value are separated by a whitespace or a sequence of whitespaces\&.
+.sp
+Input may contain comment lines, if the \-c option was provided\&. The comment indicator character must be the first character in the line\&.
+.sp
+Example input for: dkdbt make \-c \*(Aq#\*(Aq
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+# This is a comment\&.
+Poland Kruklanki, Malbork
+Sweden Drottningholm, Gripsholm, Vadstena
+Scotland Dundee, Kingussie, Campbeltown, Portree, Stirling
+Hungary Sopron, Budapest
+England Bristol, Exeter, Salisbury
+Ireland Kilkenny, Tralee, Adare
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The first line in the example is a comment\&. The record with the \*(AqPoland\*(Aq key contains the value \*(AqKruklanki, Malbork\*(Aq\&.
+.sp
+\fBInput files for dkdbt split\-sql\-lines\fR
+.sp
+The line splitting algorithm is very simple, lines are splitted after the comman in \*(Aq),(\fI\&. So you can use it only on mysqldump output of databases not containing the text \e\fR),(\*(Aq in any of the values\&.
+.SH "AUTHOR"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2011\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/dktools.1 b/support/dktools/man/man1/dktools.1
new file mode 100644
index 0000000000..1d9e866eae
--- /dev/null
+++ b/support/dktools/man/man1/dktools.1
@@ -0,0 +1,406 @@
+'\" t
+.\" Title: dktools
+.\" Author: [see the "AUTHORS" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 03/28/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "DKTOOLS" "1" "03/28/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dktools \- Dirk Krause\*(Aqs tools and libraries
+.SH "DESCRIPTION"
+.sp
+The package contains programs for different purposes:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Graphics conversion
+.TS
+tab(:);
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt.
+T{
+bmpp
+T}:T{
+Convert PNG/JPEG/TIFF to PDF/PS/EPS
+T}
+T{
+wxbmpp
+T}:T{
+GUI version of bmpp
+T}
+T{
+fig2lat
+T}:T{
+Convert *\&.fig to PGF/PDF+TeX/EPS+TeX/SVG
+T}
+T{
+wximgsz
+T}:T{
+Suggest size pairs to scale bitmap image
+T}
+T{
+plpdftex
+T}:T{
+PDF+TeX output driver for octpgfpl
+T}
+.TE
+.sp 1
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Web publishing
+.TS
+tab(:);
+lt lt.
+T{
+htmlbook
+T}:T{
+Publish HTML like a book
+T}
+.TE
+.sp 1
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Software development
+.TS
+tab(:);
+lt lt
+lt lt
+lt lt
+lt lt.
+T{
+dkct
+T}:T{
+Debugging/tracing preprocessor for C/C++/Objective\-C
+T}
+T{
+wxdkct
+T}:T{
+GUI version of dkct
+T}
+T{
+dkwxwiz
+T}:T{
+Wizard to create DK tools + wxWidgets projects
+T}
+T{
+wxdkhtb
+T}:T{
+Viewer for *\&.htb help files
+T}
+.TE
+.sp 1
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+IT Administration
+.TS
+tab(:);
+lt lt.
+T{
+itadmin
+T}:T{
+Use a MySQL database to manage your IT
+T}
+.TE
+.sp 1
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+File and directory tools
+.TS
+tab(:);
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt.
+T{
+dk\-ls
+T}:T{
+List files, configurable output column order
+T}
+T{
+dk\-fic
+T}:T{
+File integrity checker
+T}
+T{
+dk\-bmm
+T}:T{
+Backup media management
+T}
+T{
+dk\-blks
+T}:T{
+Prepare data stream for dd
+T}
+T{
+dk\-eradisk
+T}:T{
+Generate data stream to erase a disk
+T}
+T{
+dk\-hex
+T}:T{
+Show data in hexadecimal/octal notation
+T}
+T{
+dk\-pwd
+T}:T{
+Print current working directory
+T}
+.TE
+.sp 1
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Text tools
+.TS
+tab(:);
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt.
+T{
+dk\-cat
+T}:T{
+Show file contents
+T}
+T{
+dk\-sort
+T}:T{
+Sort text line by line
+T}
+T{
+dk\-t2h
+T}:T{
+Convert text to HTML
+T}
+T{
+dk\-t2l
+T}:T{
+Convert text to LaTeX
+T}
+T{
+dk\-sqlsplit
+T}:T{
+Split overlong SQL lines
+T}
+T{
+dkdbt
+T}:T{
+Convert text to database or vice versa
+T}
+.TE
+.sp 1
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+User and password tools
+.TS
+tab(:);
+lt lt
+lt lt.
+T{
+dk\-uid
+T}:T{
+Find free user ID in given range
+T}
+T{
+dk\-pwgen
+T}:T{
+Suggest password, PIN or WiFi key
+T}
+.TE
+.sp 1
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Network tools
+.TS
+tab(:);
+lt lt
+lt lt.
+T{
+dk\-send
+T}:T{
+Send data to one or multiple recipients
+T}
+T{
+dk\-recv
+T}:T{
+Receive data from a dk\-send process
+T}
+.TE
+.sp 1
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Printer administration
+.TS
+tab(:);
+lt lt
+lt lt
+lt lt.
+T{
+printqd
+T}:T{
+Print quota enforcement daemon
+T}
+T{
+wxpqdic
+T}:T{
+Info client to check print quota
+T}
+T{
+addctrld
+T}:T{
+Add final Ctrl\-D if not yet present
+T}
+.TE
+.sp 1
+.RE
+.SH "AUTHORS"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2015\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/dkwxwiz.1 b/support/dktools/man/man1/dkwxwiz.1
new file mode 100644
index 0000000000..66eea5ba73
--- /dev/null
+++ b/support/dktools/man/man1/dkwxwiz.1
@@ -0,0 +1,214 @@
+'\" t
+.\" Title: dkwxwiz
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2016
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "DKWXWIZ" "1" "09/03/2016" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dkwxwiz \- Wizard to create a wxWidgets + dkct based project\&.
+.SH "SYNOPSIS"
+.sp
+\fBdkwxwiz\fR [\fIoptions\fR] \fIprogram\fR \fIapplication\fR \fIwindow\fR
+.SH "DESCRIPTION"
+.sp
+The program creates source code skeletons for a new GUI application based on wxWidgets assuming you use the dktools libraries and the dkct program during development\&. As arguments you have to specify:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The name of the final program (i\&.e\&. "myprog")\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The name of the application class derived from wxApp (i\&.e, "MyProgApp")\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The name of the main window class (i\&.e\&. "MyProgFrame")\&.
+.RE
+.sp
+Use valid C/C++ identifiers for all three names\&.
+.sp
+OPTIONS
+.PP
+\fB\-h\fR, \fB\-\-help\fR
+.RS 4
+Show a help text\&.
+.RE
+.PP
+\fB\-v\fR, \fB\-\-version\fR
+.RS 4
+Show the program version\&.
+.RE
+.PP
+\fB\-L\fR, \fB\-\-license\-terms\fR
+.RS 4
+Show the license conditions\&.
+.RE
+.PP
+\fB\-f\fR, \fB\-\-force\fR
+.RS 4
+Overwrite existing files\&.
+.RE
+.PP
+\fB\-c\fR \fIcopyright\-owner\-name\fR
+.RS 4
+Name of the copyright owner\&.
+.RE
+.PP
+\fB\-l\fR \fIlicense type\fR
+.RS 4
+License type (i\&.e\&. "bsd")\&.
+.RE
+.SH "EXIT STATUS"
+.sp
+The program returns exit status 0 on success, any other value indicates an error\&.
+.SH "NOTES"
+.sp
+This program uses DK libraries version 3\&.
+.SH "EXAMPLES"
+.sp
+Run
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+dkwxwiz testprog TestApp TestFrame
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+in an empty directory to create a new project\&.
+.SH "FILES"
+.sp
+The following files from the dktools resource directory are used:
+.PP
+\fBdkwxwizh\&.txt\fR
+.RS 4
+Template for project header file *\&.h\&.
+.RE
+.PP
+\fBdkwxwiza\&.txt\fR
+.RS 4
+Template for application class source *\&.cpt
+.RE
+.PP
+\fBdkwxwizf\&.txt\fR
+.RS 4
+Template for top\-level window class source *\&.wxc\&.
+.RE
+.PP
+\fBdkwxwizc\&.txt\fR
+.RS 4
+Template for configure\&.ac file for autoconf\&.
+.RE
+.PP
+\fBdkwxwizm\&.txt\fR
+.RS 4
+Template for the Makefile\&.in file\&.
+.RE
+.PP
+\fBdkwxwizx\&.txt\fR
+.RS 4
+Template for the *\&.xpm icon file\&.
+.RE
+.sp
+You can create copies of these files in dkt\-3\-site and modify them i\&.e\&. to set a default copyright owner and a default license type\&.
+.SH "SEE ALSO"
+.sp
+http://dktools\&.sourceforge\&.net
+.SH "AUTHOR"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2013\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net/
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/fig2lat.1 b/support/dktools/man/man1/fig2lat.1
new file mode 100644
index 0000000000..89639111c0
--- /dev/null
+++ b/support/dktools/man/man1/fig2lat.1
@@ -0,0 +1,540 @@
+'\" t
+.\" Title: fig2lat
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 02/08/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "FIG2LAT" "1" "02/08/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+fig2lat \- Fig to LaTeX conversion
+.SH "SYNOPSIS"
+.sp
+\fBfig2lat\fR [\fB\-l\fR \fIdriver\fR] [\fIoptions\fR] [\fB\-o\fR \fIkey\fR\fB=\fR\fIvalue\fR]\&... \fIfile\fR
+.SH "DESCRIPTION"
+.sp
+Fig2lat converts *\&.fig drawings created using XFig, jFig or WinFIG to other graphics formats, mainly for use with the LaTeX typesetting system\&.
+.SH "OPTIONS"
+.PP
+\fB\-l\fR \fIdriver\fR
+.RS 4
+Output driver, one from the following:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+\fBDrivers to use a Fig file with latex or pdflatex\fR
+.PP
+\fBpdf\&.tex\fR
+.RS 4
+Produce a *\&.tex / *\&.pdf file pair\&. Include the *\&.tex file in your LaTeX source, the *\&.tex file includes the *\&.pdf file\&.
+.RE
+.PP
+\fBeps\&.tex\fR
+.RS 4
+Produce a *\&.tex / *\&.eps file pair\&. Include the *\&.tex file in your LaTeX source, the *\&.tex file includes the *\&.eps file\&.
+.RE
+.PP
+\fBpgf\fR
+.RS 4
+Produce a *\&.pgf file for inclusion in a *\&.tex source\&.
+.RE
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+\fBDrivers to produce a standalone image\fR
+.PP
+\fBtex\&.pdf\fR
+.RS 4
+Produce a full *\&.tex file for use with pdflatex\&. A file file\-i\&.pdf is produced additionally, this file is included by the *\&.tex file\&.
+.RE
+.PP
+\fBtex\fR
+.RS 4
+Produce a full *\&.tex file for use with pdflatex\&. The image is embedded as a PGF image\&.
+.RE
+.PP
+\fBeps\fR
+.RS 4
+Produce a standalone EPS file\&.
+.RE
+.PP
+\fBsvg\fR
+.RS 4
+Produce a standalone SVG file\&.
+.RE
+.RE
+.RE
+.PP
+\fB\-m\fR
+.RS 4
+Make mode when running on a directory: Convert files only if no destination files up to date are found\&.
+.RE
+.PP
+\fB\-o\fR \fIkey\fR=\fIvalue\fR
+.RS 4
+Key/value options, may be used multiple times\&. The following keys can be used:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+\fBGeneral options\fR
+.PP
+\fBlw\fR=\fIwidth\fR
+.RS 4
+Base line width\&. The default for Fig files is 1/80 inch\&. Width can be one of the following:
+.TS
+tab(:);
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt.
+T{
+\fInumber\fR\fBbp\fR
+T}:T{
+PS points
+T}
+T{
+\fInumber\fR\fBpt\fR
+T}:T{
+Width in pt
+T}
+T{
+\fInumber\fR\fBin\fR
+T}:T{
+Width in inch
+T}
+T{
+\fInumber\fR\fBcm\fR
+T}:T{
+Width in cm
+T}
+T{
+\fInumber\fR\fBmm\fR
+T}:T{
+Width in mm
+T}
+T{
+\fBlighten\fR
+T}:T{
+Use 1/160 inch
+T}
+T{
+\fBauto\fR
+T}:T{
+0\&.4pt * textsize / 10
+T}
+.TE
+.sp 1
+.RE
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+\fBText handling options\fR
+.PP
+\fBtf\fR=\fIstring\fR
+.RS 4
+Text font selection for normal (non\-special) text\&. Either \*(Aqsimilar\*(Aq or \*(Aqfig\*(Aq\&.
+.RE
+.PP
+\fBts\fR=\fIsize\fR
+.RS 4
+Font size factor for normal (non\-special) text\&. Either the keyword \*(Aqnone\*(Aq or a scale factor (typically in the range 0\&.95 \&... 1\&.0)\&.
+.RE
+.PP
+\fBbbts\fR[=\fIboolean\fR]
+.RS 4
+Use text size in bounding box calculaion\&.
+.RE
+.PP
+\fBsmash\fR[=\fIboolean\fR]
+.RS 4
+Use \esmash instruction in LaTeX output\&.
+.RE
+.PP
+\fBmbox\fR[=\fIboolean\fR]
+.RS 4
+Use \embox instruction in LaTeX output\&.
+.RE
+.PP
+\fBreset@font\fR[=\fIboolean\fR]
+.RS 4
+Use reset@font instruction in LaTeX output\&.
+.RE
+.PP
+\fBste\fR[=\fIencoding\fR]
+.RS 4
+Encoding used when writing special text to output file\&. Either \*(Aqplain\*(Aq or \*(Aqutf\-8\*(Aq\&.
+.RE
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+\fBX\-Spline and Bezier\-Spline options\fR
+.PP
+\fBxsss\fR[=\fInumber\fR]
+.RS 4
+Number of Bezier\-Spline subsegments per X\-spline segment\&. Default: 8, minimum: 2\&.
+.RE
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+\fBArrowhead options\fR
+.PP
+\fBahas\fR=\fInumber\fR
+.RS 4
+Number of X\-spline segments for a 90 degree angle on arcs\&. Default: 4\&.
+.RE
+.PP
+\fBahss\fR=\fIinteger\fR
+.RS 4
+Number of arrowhead X\-spline segments for each original X\-spline segment for arrowheads on splines\&. Default: 4\&.
+.RE
+.PP
+\fBahms\fR=\fIinteger\fR
+.RS 4
+Minimum number of X\-spline segments for each arrowhead edge\&. Default: 4
+.RE
+.PP
+\fBahip\fR=\fIfloat\fR
+.RS 4
+Arrowhead iteration precision\&. Default: 0\&.04\&.
+.RE
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+\fBOutput options\fR
+.PP
+\fBcodi\fR=[\fInumber\fR]
+.RS 4
+Number of digits used for colors\&. Default: 3\&.
+.RE
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+\fBCompatibilty options (compatibility to fig2dev)\fR
+.PP
+\fBcosp\fR[=\fIboolean\fR]
+.RS 4
+Compatible splines\&.
+.RE
+.PP
+\fBcoah\fR[=\fIboolean\fR]
+.RS 4
+Compatible arrowheads\&.
+.RE
+.PP
+\fBxsah\fR[=\fIboolean\fR]
+.RS 4
+X\-spline arrowheads (not together with coah)\&.
+.RE
+.PP
+\fBcols\fR[=\fIboolean\fR]
+.RS 4
+Compatible line styles\&.
+.RE
+.PP
+\fBcofop\fR[=\fIboolean\fR]
+.RS 4
+Compatible fill for open paths\&.
+.RE
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+\fBSource type (mutually exclusive)\fR
+.PP
+\fBxfig\fR
+.RS 4
+File produced by XFig
+.RE
+.PP
+\fBjfig\fR
+.RS 4
+File produced by jFig\&.
+.RE
+.PP
+\fBwinfig\fR
+.RS 4
+File produced by WinFIG\&.
+.RE
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+\fBDriver specific options (tex, tex\&.pdf)\fR
+.PP
+\fBdcts\fR[=\fInumber\fR]
+.RS 4
+Font size in pt used in the document class\&.
+.RE
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+\fBDriver specific options (eps, eps\&.tex)\fR
+.PP
+\fBshowpage\fR[=\fIboolean\fR]
+.RS 4
+Use showpage operator\&.
+.RE
+.PP
+\fBlevel\fR=\fIinteger\fR
+.RS 4
+PS level, 2 or 3\&.
+.RE
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+\fBDriver specific options (svg)\fR
+.PP
+\fBcss\fR[=\fIboolean\fR]
+.RS 4
+Use CSS styling\&.
+.RE
+.PP
+\fBgroup\fR[=\fIboolean\fR]
+.RS 4
+Group arrowhead objects with the object they are attached to\&.
+.RE
+.PP
+\fBfragment\fR[=\fIboolean\fR]
+.RS 4
+Write an SVG fragment instead of a complete file\&.
+.RE
+.PP
+\fBfontbase\fR[=\fIstring\fR]
+.RS 4
+Specify source for GhostScript fonts converted to TTF, "none", "local", or "web"\&.
+.RE
+.PP
+\fBreplacementfonts\fR=[\fIboolean\fR]
+.RS 4
+Enable/disable use of replacement font families\&.
+.RE
+.PP
+\fBmiterlimit\fR[=\fIboolean\fR]
+.RS 4
+Enable/disable use of "stroke\-miterlimit" style setting\&.
+.RE
+.RE
+.RE
+.SH "EXIT STATUS"
+.sp
+0 on success, all other exit status codes indicate an error\&.
+.SH "FILES"
+.sp
+Fig2lat uses the following files from the current working directory:
+.PP
+\fBf2lfonts\&.tex\fR
+.RS 4
+is used in the preamble of tex and tex\&.pdf output, the file contents replaces the font selection packages\&.
+.RE
+.PP
+\fBf2lother\&.tex\fR
+.RS 4
+is used in the preamble of tex and tex\&.pdf output, the file contents replaces the packages for "other setup"\&.
+.RE
+.SH "NOTES"
+.sp
+This program uses DK libraries version 3\&.
+.sp
+There are differences between the output from fig2lat and the output from fig2dev\&. This is intended, otherwise we would not need an additional program\&.
+.PP
+\fBInterpolated X\-splines:\fR
+.RS 4
+Fig2lat uses the correct formula q=\-0\&.5*s as described in /BS1995/\&.
+.RE
+.PP
+\fBArrowheads:\fR
+.RS 4
+All arrowhead types introduced in xfig 3\&.2\&.5 are supported\&. On splines and arcs we have curved arrowheads\&. The same line width as for the original line is used for the arrowhead too, the arrowhead linewidth specified in the Fig file is ignored\&.
+.RE
+.PP
+\fBText:\fR
+.RS 4
+When using LaTeX/pdfLaTeX related drivers (tex, tex\&.pdf, pdf\&.tex, eps\&.tex, pgf) all text is handled by LaTeX/pdfLaTeX\&. The tf setting controls whether to use PS fonts or similar feature LaTeX fonts for normal text\&. For special text no font selection instructions are written at all, so document default fonts are used\&.
+.RE
+.PP
+\fBFill patterns:\fR
+.RS 4
+Fill patterns are vector graphics in fig2lat\&.
+.RE
+.PP
+\fBSplines:\fR
+.RS 4
+X\-splines are converted to a sequence of Bezier splines instead of polylines\&.
+.RE
+.SH "KNOWN ISSUES"
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The curved arrowheads on arcs and splines are implemented as sequences of short \- sometimes very short \- Bezier curves\&. At least for my arrowtest\&.fig test file I saw malformed arrowheads in some renderers although the same graphics were shown fine in other renderers\&. You can avoid the problem by using the coah option (compatible arrowheads)\&. For Batik 1\&.7 Squiggle you can also attempt the miterlimit=no option\&.
+.RE
+.SH "AUTHOR"
+.sp
+Dirk Krause
+.SH "HISTORY"
+.sp
+This program replaces the fig2vect program seen in previous versions of dktools\&.
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2012\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+\fB/BS1995/\fR
+.RS 4
+Carole Blanc, Christophe Schlick:
+\fBX\-Splines: A Spline Model Designed for the End\-User\fR
+Proceedings of the SIGGRAPH 1995
+.RE
+.PP
+\fBfig2lat\fR
+.RS 4
+http://dktools\&.sourceforge\&.net
+.RE
diff --git a/support/dktools/man/man1/htmlbook.1 b/support/dktools/man/man1/htmlbook.1
new file mode 100644
index 0000000000..ecd34162a7
--- /dev/null
+++ b/support/dktools/man/man1/htmlbook.1
@@ -0,0 +1,202 @@
+'\" t
+.\" Title: htmlbook
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2016
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "HTMLBOOK" "1" "09/03/2016" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+htmlbook \- Create HTML book structure
+.SH "SYNOPSIS"
+.sp
+htmlbook [\fIoption(s)\fR] \fIfile\fR
+.SH "DESCRIPTION"
+.sp
+The program creates a HTML book structure in a specified output directory\&. Configuration is read from a project file specified on the command line\&.
+.SH "OPTIONS"
+.PP
+\fB\-i\fR \fIencoding\fR, \fB\-\-input\-encoding=\fR\fIencoding\fR
+.RS 4
+Expected input encoding, overwritten by a byte order marker (BOM) at start of input text\&.
+.TS
+tab(:);
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt.
+T{
+ascii
+T}:T{
+ASCII or ISO\-8859\-1
+T}
+T{
+utf\-8
+T}:T{
+UTF\-8
+T}
+T{
+utf\-16
+T}:T{
+UTF\-16 in the systems default endianness
+T}
+T{
+utf\-16\-lsb
+T}:T{
+UTF\-16, least significant byte first
+T}
+T{
+utf\-16\-msb
+T}:T{
+UTF\-16, most significant byte first
+T}
+T{
+c32
+T}:T{
+32 bit character in the systems default endianness
+T}
+T{
+c32\-lsb
+T}:T{
+32 bit character, least significant byte first
+T}
+T{
+c32\-msb
+T}:T{
+32 bit character, most significant byte first
+T}
+.TE
+.sp 1
+.RE
+.PP
+\fB\-o\fR \fIname\fR[,\fIname\fR\&...]
+.RS 4
+Activate optional project file sections\&.
+.RE
+.PP
+\fB\-s\fR \fIname\fR\fB=\fR\fIvalue\fR \&..., \fB\-\-set=\fR\fIname\fR\fB=\fR\fIvalue\fR \&...
+.RS 4
+Set variables (overwrite variables from options section)\&.
+.RE
+.PP
+\fB\-h\fR, \fB\-\-help\fR
+.RS 4
+Print help text\&.
+.RE
+.PP
+\fB\-v\fR, \fB\-\-version\fR
+.RS 4
+Print version information\&.
+.RE
+.PP
+\fB\-L\fR, \fB\-\-license\fR
+.RS 4
+Print license terms\&.
+.RE
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, any other value indicates an error\&.
+.SH "NOTES"
+.sp
+This program uses DK libraries version 3\&.
+.sp
+All text files, style files and images must be local files in the current working directory\&.
+.SH "AUTHOR"
+.sp
+Dirk krause
+.SH "HISTORY"
+.sp
+2013\-11\-30 work on program was started\&.
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2013\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+\fBhtmlbook\-project(5)\fR
+.RS 4
+Syntax of the project file\&.
+.RE
+.PP
+\fBhtmlbook\-template(5)\fR
+.RS 4
+Syntax of template files\&.
+.RE
+.PP
+\fBhtmlbook\-text(5)\fR
+.RS 4
+Syntax of text files\&.
+.RE
+.PP
+tidy(1)
+.RS 4
+Validate, correct and pretty\-print HTML files\&.
+.RE
+.PP
+http://dktools\&.sourceforge\&.net/
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/itaclean.1 b/support/dktools/man/man1/itaclean.1
new file mode 100644
index 0000000000..62265793a6
--- /dev/null
+++ b/support/dktools/man/man1/itaclean.1
@@ -0,0 +1,212 @@
+'\" t
+.\" Title: itaclean
+.\" Author: [see the "AUTHORS" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 05/25/2016
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "ITACLEAN" "1" "05/25/2016" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+itaclean \- Clean up before running itadmin
+.SH "SYNOPSIS"
+.sp
+itaclean
+.SH "DESCRIPTION"
+.sp
+The itaclean script removes the following files from the current working directory:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+hosts
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+hosts\&.ldif
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+ethers\-by\-ip
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+ethers\-by\-mac
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+ethers\&.ldif
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+netgroup\&.ldif
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+dhcpd\&.conf
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+netdocu\&.tex
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+licenses\&.tex
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+netdocu\&.pdf
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+licenses\&.pdf
+.RE
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other status codes indicate an error\&.
+.SH "AUTHORS"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2015\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+\fBitadmin(1)\fR
+.RS 4
+Use a database to manage your IT\&.
+.RE
diff --git a/support/dktools/man/man1/itadmin.1 b/support/dktools/man/man1/itadmin.1
new file mode 100644
index 0000000000..5cb2aed17d
--- /dev/null
+++ b/support/dktools/man/man1/itadmin.1
@@ -0,0 +1,191 @@
+'\" t
+.\" Title: itadmin
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 03/28/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "ITADMIN" "1" "03/28/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+itadmin \- IT administration using databases
+.SH "SYNOPSIS"
+.sp
+\fBitadmin\fR [\fIoptions\fR] [\fIconfig\-file\fR]
+.SH "DESCRIPTION"
+.sp
+The program reads IT\-related information from a database and creates configuration files, a network documentation, and a license report\&. A configuration file can be specified as argument, the program searches for itadmin\&.conf files if no configuration file is specified\&.
+.SH "OPTIONS"
+.PP
+\fB\-c\fR, \fB\-\-configuration\fR
+.RS 4
+Create configuration files and network documentation\&.
+.RE
+.PP
+\fB\-l\fR, \fB\-\-licenses\fR
+.RS 4
+Create license report\&. If none of \-c and \-l is used the program creates all output (same as both \-c and \-l used)\&.
+.RE
+.PP
+\fB\-h\fR, \fB\-\-help\fR
+.RS 4
+Show help text\&.
+.RE
+.PP
+\fB\-v\fR, \fB\-\-version\fR
+.RS 4
+Show version information\&.
+.RE
+.PP
+\fB\-L\fR, \fB\-\-license\-terms\fR
+.RS 4
+Show license terms\&.
+.RE
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other status codes indicate an error\&.
+.SH "NOTES"
+.sp
+This program uses DK libraries version 3\&.
+.sp
+It is not available on the Windows platform\&.
+.SH "FILES"
+.PP
+\fBitadmin\&.conf\fR
+.RS 4
+The itadmin\&.conf file contains the configuration information used by the program\&. The file consists of key=value pairs, one per line\&. Keys can consist of multiple words\&. Lines started by \*(Aq#\*(Aq are comments\&. The following key=value pairs can be used:
+.PP
+\fBdatabase host = \fR\fIstring>\fR
+.RS 4
+Name or IP address of the database host to connect to\&.
+.RE
+.PP
+\fBdatabase name = \fR\fIstring\fR
+.RS 4
+Database name\&.
+.RE
+.PP
+\fBdatabase type = \fR\fIname\fR
+.RS 4
+Database type, only \(lqmysql\(rq supported\&.
+.RE
+.PP
+\fBdatabase credentials file = \fR\fIfilename\fR
+.RS 4
+File containing credential (typically a "\&.my\&.cnf" file)\&.
+.RE
+.PP
+\fBcreate dhcpd\&.conf = \fR\fIboolean\fR
+.RS 4
+Flag: Create a dhcpd\&.conf file for ISC dhcpd\&.
+.RE
+.PP
+\fBdhcpd\&.conf vlan = \fR\fIname\fR
+.RS 4
+Name of VLAN to produce dhcpd\&.conf file for\&.
+.RE
+.PP
+\fBmsft release lease on shutdown = \fR\fIstring\fR
+.RS 4
+Decide whether to release leases on Windows PC shutdown, one from \(lqall\(rq, \(lqpool\(rq or \(lqnone\(rq\&.
+.RE
+.PP
+\fBldap base = \fR\fIname\fR
+.RS 4
+The name of your LDAP base object, i\&.e\&. \(lqdc=my\-corporation,dc=com\(rq\&. If this entry is missing, no files \(lqhosts\&.ldif\(rq, \(lqethers\&.ldif\(rq or \(lqnetgroup\&.ldif\(rq are produced\&.
+.RE
+.PP
+\fBadministrator name = \fR\fIname\fR
+.RS 4
+Administrator name, used in document title\&.
+.RE
+.PP
+\fBorganization = \fR\fIname\fR
+.RS 4
+Organization name, used in document title\&.
+.RE
+.PP
+\fBorganizational unit = \fR\fIname\fR
+.RS 4
+Organizational unit name, used in document title\&.
+.RE
+.PP
+\fBuse koma\-script = \fR\fIboolean\fR
+.RS 4
+If this flag is set, the \(lqsrcbook\(rq and \(lqsrcartcl\(rq document classes are used in licenses\&.tex and netdocu\&.tex instead of \(lqbook\(rq and \(lqarticle\(rq\&. If A4 is your preferred paper size for printouts, I recommend to set this flag\&.
+.RE
+.RE
+.SH "AUTHOR"
+.sp
+Dirk Krause
+.SH "HISTORY"
+.sp
+The itadmin program replaces the hostsadm script found in previous versions of dktools\&.
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2012\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/lprngcl.1 b/support/dktools/man/man1/lprngcl.1
new file mode 100644
index 0000000000..65ad26d534
--- /dev/null
+++ b/support/dktools/man/man1/lprngcl.1
@@ -0,0 +1,134 @@
+'\" t
+.\" Title: lprngcl
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 02/08/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "LPRNGCL" "1" "02/08/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+lprngcl \- Clean LPRng print queues
+.SH "SYNOPSIS"
+.sp
+\fBlprngcl\fR [\fB\-a\fR] [\fB\-t\fR \fIseconds\fR] [\fB\-v\fR] \fIqueue\fR\&...
+.sp
+\fBlprngcl\fR [\fB\-\-help\fR] [\fB\-\-version\fR] [\fB\-\-license\fR] [\fB\-\-manual\fR]
+.SH "DESCRIPTION"
+.sp
+The lprngcl program deletes all print jobs created by the current user from the named LPD/LPRng print queues\&. It is intended for use in computer labs or PC classrooms in schools and universities\&. Users logging off will leave the room and thus have no longer interest in the print jobs still in the queues\&.
+.SH "OPTIONS"
+.PP
+\fB\-a\fR, \fB\-\-ascii\fR
+.RS 4
+The LPRng host uses ASCII encoding\&. Default: UTF\-8\&.
+.RE
+.PP
+\fB\-t\fR \fInumber\fR, \fB\-\-timeout=\fR\fInumber\fR
+.RS 4
+Timeout for network operations, number of seconds\&.
+.RE
+.PP
+\fB\-v\fR, \fB\-\-verbose\fR
+.RS 4
+Produce verbose output, show the servers response\&.
+.RE
+.PP
+\fB\-\-help\fR
+.RS 4
+Show short help text\&.
+.RE
+.PP
+\fB\-\-version\fR
+.RS 4
+Show version information\&.
+.RE
+.PP
+\fB\-\-license\fR
+.RS 4
+Show the license terms\&.
+.RE
+.PP
+\fB\-\-manual\fR
+.RS 4
+Show longer help text (similar to this man page)\&.
+.RE
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other status codes indicate an error\&.
+.SH "NOTES"
+.sp
+In version 4\&.3\&.0 and above lprngcl does no longer use a dk3print\&.conf file\&. So there is no default LPRng host and no default queue\&. The queues to clean must be specified on the command line in \fIqueue\fR\fB@\fR\fIhost\fR notation\&.
+.sp
+This program uses DK libraries version 4\&.
+.SH "AUTHOR"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2013\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/pjsnmp.1 b/support/dktools/man/man1/pjsnmp.1
new file mode 100644
index 0000000000..770d3c5a2c
--- /dev/null
+++ b/support/dktools/man/man1/pjsnmp.1
@@ -0,0 +1,1211 @@
+'\" t
+.\" Title: pjsnmp
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 02/08/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "PJSNMP" "1" "02/08/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pjsnmp \- Print job transfer over TCP socket with SNMP support
+.SH "SYNOPSIS"
+.sp
+\fBpjsnmp\fR [\fIoption(s)\fR]
+.SH "DESCRIPTION"
+.sp
+Pjsnmp is a filter for the LPRng print system\&. It is used to transfer print job data from the LPRng server to a networked printer\&. This filter does not modify data, it just reads print job data from standard input and transfers that data using a TCP connection\&.
+.sp
+The program uses SNMP to check the printer status before sending the print job, while sending data and after sending the print job\&. Data exchange includes device status (hrDeviceStatus), printer status (hrPrinterStatus), error and warning conditions (hrPrinterDetectedErrorState), page counter value (prtMarkerLifeCount) and the first status text line (prtConsoleDisplayBufferText)\&.
+.sp
+A summary state is derived from the information found:
+.PP
+\fBunreachable\fR
+.RS 4
+SNMP data exchange failed\&.
+
+Probably the printer is turned off or not correctly connected to the network\&.
+.RE
+.PP
+\fBstandby\fR
+.RS 4
+The printer is in power\-save mode as there were no print requests for a longer time\&.
+.RE
+.PP
+\fBidle\fR
+.RS 4
+The printer has nothing to do\&.
+.RE
+.PP
+\fBwarmup\fR
+.RS 4
+The printer is warming up, either after power\-on or when recovering from standby state or errors\&.
+.RE
+.PP
+\fBbusy\fR
+.RS 4
+The printer is printing\&.
+.RE
+.PP
+\fBerror\fR
+.RS 4
+There is any error condition preventing the printer from printing (i\&.e\&. out of paper, out of toner, paper jam\&...)\&. It is not known whether or not the printer has data to print\&.
+.RE
+.PP
+\fBunknown\fR
+.RS 4
+There was an SNMP response but data can not be mapped to one of the states above\&.
+.RE
+.sp
+Before starting print data transfer pjsnmp waits for the printer to reach \fIidle\fR or \fIstandby\fR state so it is secure to use the page counter value\&. After the data transfer pjsnmp waits for the printer to finish the print job until it is in \fIidle\fR or \fIstandby\fR state again\&.
+.sp
+Optionally pjsnmp can be used in conjunction with printqd for print accounting or print quota\&.
+.sp
+The following OIDs are inspected by pjsnmp:
+.PP
+\fBhrDeviceStatus\fR
+.RS 4
+The device status, one from:
+.PP
+\fIunknown\fR
+.RS 4
+The current state of the device is unknown\&.
+.RE
+.PP
+\fIrunning\fR
+.RS 4
+The device is working, no unusual or error condition\&.
+.RE
+.PP
+\fIwarning\fR
+.RS 4
+Unusual or error condition, the device is still operational\&.
+.RE
+.PP
+\fItesting\fR
+.RS 4
+The device is not available (i\&.e\&. in self test)\&.
+.RE
+.PP
+\fIdown\fR
+.RS 4
+Due to errors the device is not available for any use\&.
+.RE
+.RE
+.PP
+\fBhrPrinterStatus\fR
+.RS 4
+The printer status, one from
+.PP
+\fIother\fR
+.RS 4
+States not mentioned below\&.
+.RE
+.PP
+\fIunknown\fR
+.RS 4
+State is unknown, hrDeviceStatus should be
+\fIunknown\fR
+too\&.
+.RE
+.PP
+\fIidle\fR
+.RS 4
+Waiting for a print job (nothing to do)\&.
+.RE
+.PP
+\fIprinting\fR
+.RS 4
+The printer is printing\&.
+.RE
+.PP
+\fIwarmup\fR
+.RS 4
+Warmup after power on or when returning from standby or error\&.
+.RE
+.RE
+.PP
+\fBhrPrinterDetectedErrorState\fR
+.RS 4
+A set of bits indicating error and warning conditions\&. Bit 0 is the MSB in the first response byte, bit 7 is the LSB in the first response byte\&. Bit 8 is the MSB of the second response byte\&...
+.PP
+\fIlow\-paper\fR (bit 0, warning)
+.RS 4
+Paper is low, printer will be out of paper soon\&.
+.RE
+.PP
+\fIno\-paper\fR (bit 1, error)
+.RS 4
+Out of paper\&.
+.RE
+.PP
+\fIlow\-toner\fR (bit 2, warning)
+.RS 4
+Toner is low, printer will be out of toner soon\&.
+.RE
+.PP
+\fIno\-toner\fR (bit 3, error)
+.RS 4
+Out of toner\&.
+.RE
+.PP
+\fIdoor\-open\fR (bit 4, error)
+.RS 4
+Any of the doors (i\&.e\&. to change toner or marker supply) is open\&.
+.RE
+.PP
+\fIpaper\-jam\fR (bit 5, error)
+.RS 4
+Paper jam\&.
+.RE
+.PP
+\fIoffline\fR (bit 6, error)
+.RS 4
+Printer is not working due to error\&.
+.RE
+.PP
+\fIservice\-requested\fR (bit 7, warning)
+.RS 4
+You should either do preventive maintenance (i\&.e\&. cleaning) or press a button on the printer (i\&.e\&. to confirm paper type and size you just inserted)\&.
+.RE
+.PP
+\fIinput\-tray\-missing\fR (bit 8, error)
+.RS 4
+An input tray was removed (i\&.e\&. for filling)\&.
+.RE
+.PP
+\fIoutput\-tray\-missing\fR (bit 9, error)
+.RS 4
+An output tray was removed\&.
+.RE
+.PP
+\fImarker\-supply\-missing\fR (bit 10, error)
+.RS 4
+No marker supply available\&.
+.RE
+.PP
+\fIoutput\-near\-full\fR (bit 11, warning)
+.RS 4
+Output tray is nearly full, will become full soon\&.
+.RE
+.PP
+\fIoutput\-full\fR (bit 12, error)
+.RS 4
+Output tray is full\&.
+.RE
+.PP
+\fIinput\-tray\-empty\fR (bit 13, warning)
+.RS 4
+At least one input tray is empty\&.
+.RE
+.PP
+\fIoverdue\-preventive\-maintenance\fR (bit 14, warning)
+.RS 4
+Some preventive maintenance is necessary\&.
+.RE
+.RE
+.PP
+\fBprtMarkerLifeCount\fR
+.RS 4
+The number of print impressions, typically the number of printed pages (either in printers life time or since power\-on)\&. For duplex printing front and back page are counted as 2\&.
+.RE
+.PP
+\fBprtConsoleDisplayBufferText\fR
+.RS 4
+The status text shown in the first line of the printers console\&.
+.RE
+.SH "GETTING THE SUMMARY STATE FROM SNMP INFORMATION"
+.sp
+\fBStage 1: Device and printer status\fR
+.sp
+In the first processing stage a summary state is choosen for the combination of device status and printer status\&.
+.TS
+allbox tab(:);
+ltB ltB ltB.
+T{
+Device status
+T}:T{
+Printer status
+T}:T{
+Summary state
+T}
+.T&
+lt lt lt
+lt lt lt
+lt lt lt
+lt lt lt
+lt lt lt
+lt lt lt
+lt lt lt
+lt lt lt
+lt lt lt
+lt lt lt
+lt lt lt
+lt lt lt
+lt lt lt
+lt lt lt
+lt lt lt
+lt lt lt
+lt lt lt
+lt lt lt
+lt lt lt
+lt lt lt
+lt lt lt
+lt lt lt
+lt lt lt
+lt lt lt
+lt lt lt.
+T{
+.sp
+unknown
+T}:T{
+.sp
+other
+T}:T{
+.sp
+unknown
+T}
+T{
+.sp
+unknown
+T}:T{
+.sp
+unknown
+T}:T{
+.sp
+unknown
+T}
+T{
+.sp
+unknown
+T}:T{
+.sp
+idle
+T}:T{
+.sp
+unknown
+T}
+T{
+.sp
+unknown
+T}:T{
+.sp
+printing
+T}:T{
+.sp
+unknown
+T}
+T{
+.sp
+unknown
+T}:T{
+.sp
+warmup
+T}:T{
+.sp
+warmup
+T}
+T{
+.sp
+running
+T}:T{
+.sp
+other
+T}:T{
+.sp
+standby
+T}
+T{
+.sp
+running
+T}:T{
+.sp
+unknown
+T}:T{
+.sp
+unknown
+T}
+T{
+.sp
+running
+T}:T{
+.sp
+idle
+T}:T{
+.sp
+idle
+T}
+T{
+.sp
+running
+T}:T{
+.sp
+printing
+T}:T{
+.sp
+busy
+T}
+T{
+.sp
+running
+T}:T{
+.sp
+warmup
+T}:T{
+.sp
+warmup
+T}
+T{
+.sp
+warning
+T}:T{
+.sp
+other
+T}:T{
+.sp
+standby
+T}
+T{
+.sp
+warning
+T}:T{
+.sp
+unknown
+T}:T{
+.sp
+unknown
+T}
+T{
+.sp
+warning
+T}:T{
+.sp
+idle
+T}:T{
+.sp
+idle
+T}
+T{
+.sp
+warning
+T}:T{
+.sp
+printing
+T}:T{
+.sp
+busy
+T}
+T{
+.sp
+warning
+T}:T{
+.sp
+warmup
+T}:T{
+.sp
+warmup
+T}
+T{
+.sp
+testing
+T}:T{
+.sp
+other
+T}:T{
+.sp
+unknown
+T}
+T{
+.sp
+testing
+T}:T{
+.sp
+unknown
+T}:T{
+.sp
+unknown
+T}
+T{
+.sp
+testing
+T}:T{
+.sp
+idle
+T}:T{
+.sp
+unknown
+T}
+T{
+.sp
+testing
+T}:T{
+.sp
+printing
+T}:T{
+.sp
+unknown
+T}
+T{
+.sp
+testing
+T}:T{
+.sp
+warmup
+T}:T{
+.sp
+warmup
+T}
+T{
+.sp
+down
+T}:T{
+.sp
+other
+T}:T{
+.sp
+error
+T}
+T{
+.sp
+down
+T}:T{
+.sp
+unknown
+T}:T{
+.sp
+error
+T}
+T{
+.sp
+down
+T}:T{
+.sp
+idle
+T}:T{
+.sp
+error
+T}
+T{
+.sp
+down
+T}:T{
+.sp
+printing
+T}:T{
+.sp
+error
+T}
+T{
+.sp
+down
+T}:T{
+.sp
+warmup
+T}:T{
+.sp
+warmup
+T}
+.TE
+.sp 1
+.sp
+An SNMP model can be used to change the mapping from device/printer status to summary states\&.
+.sp
+\fBStage 2: Checking printer detected error state\fR
+.sp
+If the printer detected error state contains any condition marked with \(lqError\(rq in the hrPrinterDetectedErrorState table, the summary state is changed to \fIerror\fR\&.
+.sp
+If the :pjsnmp\-pdes\-always flag is disabled in the printcap entry, this check is only applied if stage 1 resulted in \fIunknown\fR\&.
+.sp
+An SNMP model can be used to change the conditions interpreted as errors\&.
+.sp
+\fBStage 3: Status text from the display\fR
+.sp
+An SNMP model can be used to map status texts from the printers first display line to summary states \fIbusy\fR, \fIidle\fR and \fIstandby\fR\&.
+.sp
+In the model you can configure to inspect the display line text always or for summary state \fIunknown\fR only\&.
+.sp
+\fBStage 4: Mapping unknown to busy\fR
+.sp
+If the summary state is \fIunknown\fR and :pjsnmp\-unknown\-busy is set in the printcap entry, the state is shown as \fIbusy\fR\&.
+.SH "OPTIONS"
+.sp
+All options for pjsnmp are set by the LPRng print system\&.
+.SH "EXIT STATUS"
+.sp
+0 on success, 3 to remove the print job due to errors or 6 to hold the print job\&.
+.SH "ENVIRONMENT"
+.sp
+LPRng places a copy of the printcap entry for the printer in the PRINTCAP_ENTRY environment variable\&.
+.SH "FILES - THE PRINTCAP FILE"
+.sp
+The ${sysconfdir}/lpd/printcap file configures the LPRng print queues\&.
+.sp
+Each queue description is started by the queue name without a leading colon\&. A list of configuration entries follows, each one is separated from previous contents by a colon\&. This list of configuration entries can span multiple lines, if the first non\-whitespace character on a line is a colon the line is the continuation line\&.
+.sp
+Each entry can be either a boolean value or a \fIkey\fR=\fIvalue\fR pair\&.
+.sp
+A boolean value does not contain an equal sign \(lq=\(rq\&. A boolean entry without \(lq@\(rq is turned on (true), a name followed by \(lq@\(rq turns a setting off (false)\&.
+.sp
+The following entries are relevant for pjsnmp:
+.PP
+\fB:server\fR
+.RS 4
+Pjsnmp is used in the configuration on the server only, not by the client programs\&.
+.RE
+.PP
+\fB:lp=|\fR\fI/path\&.../pjsnmp\fR
+.RS 4
+IO device names started by \(lq|\(rq indicate a program to run as a filter\&. The program obtains the print data to transmit from it\*(Aqs standard input\&. We use the pjsnmp program here, the entries below are used to configure it\&.
+.RE
+.PP
+\fB:pjsnmp\-host=\fR\fIhost\fR
+.RS 4
+The host name or IPv4 address of the printer\&. Default: none\&. LPRng uses the colon as separator between configuration entries, IPv6 uses colons to separate words\&. So we can not specify IPv6 addresses here\&.
+.RE
+.PP
+\fB:pjsnmp\-port=\fR\fInumber\fR
+.RS 4
+The port number of the printer (default: 9100)\&.
+.RE
+.PP
+\fB:pjsnmp\-local\-port=\fR\fInumber\fR
+.RS 4
+Local port number to use\&. Default: 0 (use arbitrary port)\&.
+\fINote:\fR
+When running multiple print queues on a server you should use different local port numbers for each queue\&. I recommend to leave this setting at the default and let the system choose an arbitrary local port\&.
+.RE
+.PP
+\fB:pjsnmp\-read\-response\fR
+.RS 4
+Flag: Do receive operations on network socket\&. Default: off\&.
+.RE
+.PP
+\fB:pjsnmp\-ordrel\fR
+.RS 4
+Flag: Do an orderly release of the TCP connection after transferring the print data\&. Default: off\&.
+.RE
+.PP
+\fB:pjsnmp\-version=\fR\fIstring\fR
+.RS 4
+The SNMP version to use, \(lq1\(rq, \(lq2c\(rq, or \(lq3\(rq\&. Default: 1\&.
+.RE
+.PP
+\fB:pjsnmp\-community=\fR\fIname\fR
+.RS 4
+The SNMP community name\&. Default: \(lqpublic\(rq\&.
+.RE
+.PP
+\fB:pjsnmp\-during\-transfer\fR
+.RS 4
+Flag: Do SNMP data transfer before each attempt to send data\&. Default: on\&. If the option is disabled, pjsnmp does SNMP queries only on failed attempts to send data\&.
+.RE
+.PP
+\fB:pjsnmp\-pdes\-always\fR
+.RS 4
+Flag: Use printer detected error state conditions for all device/printer status combinations\&. Default: on\&. If the flag is disabled, these conditions are used only if the summary state is
+\fIunknown\fR\&.
+.RE
+.PP
+\fB:pjsnmp\-model\-name=\fR\fIname\fR
+.RS 4
+SNMP model to use for printer\&. Use of SNMP models is optional, only necessary for printers not using the reasonable SNMP implementation below\&. Default: none\&.
+.RE
+.PP
+\fB:pjsnmp\-model\-file=\fR\fIpath\fR
+.RS 4
+File name containing the SNMP model descriptions\&. Default ${datarootdir}/dktools/pjsnmp\&.conf \&.
+.RE
+.PP
+\fB:pjsnmp\-unknown\-busy\fR
+.RS 4
+Flag: Indicate summary state
+\fIunknown\fR
+as
+\fIbusy\fR\&. Default: off\&.
+.RE
+.PP
+\fB:pjsnmp\-force\-printable\-status\-text\fR
+.RS 4
+Flag: Show status text from printer in status file even if it contains non\-ASCII characters (these characters are replaced by a question mark in output)\&. Default: on\&.
+.RE
+.PP
+\fB:pjsnmp\-ignore\-failed\-session\fR
+.RS 4
+Flag: Ignore failure to establish SNMP session\&. Default: off\&. If this flag is turned on pjsnmp attempts to transfer print data even if the program failed to establish an SNMP session and thus can not do state monitoring or accounting\&.
+.RE
+.PP
+\fB:pjsnmp\-require\-printing=\fR\fInumber\fR
+.RS 4
+Timeout at job end for suspicious transitions to summary state
+\fIidle\fR
+or
+\fIstandby\fR\&. Default: 600\&.
+.sp
+On suspicious transitions we give the printer some time to start or resume printing\&. Suspicious transitions include:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Transition from
+\fIerror\fR
+to
+\fIidle\fR
+or
+\fIstandby\fR\&. After recovering from an error condition some printers go from
+\fIerror\fR
+to
+\fIbusy\fR
+via
+\fIidle\fR
+or
+\fIstandby\fR\&. Such intermediate
+\fIidle\fR
+or
+\fIstandby\fR
+states do not indicate the end of a print job\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Transitions to
+\fIidle\fR
+or
+\fIstandby\fR
+if the page counter value did not change since start of job or last time seeing
+\fIerror\fR\&. For very short print jobs the printer starts printing some seconds after the data transfer was finished\&.
+.RE
+.RE
+.PP
+\fB:pjsnmp\-accounting\-enable\fR
+.RS 4
+Flag: Pass pagecounters to an accounting/quota system\&. Default: off\&.
+.RE
+.PP
+\fB:pjsnmp\-accounting\-check\fR
+.RS 4
+Flag: Check a users permission to print to a queue before transferring data\&. Default: off\&. Requires :accounting_enable\&. To receive responses from the quota/accounting system we must use one of three methods to connect to the accounting system:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Local UNIX domain socket (recommended method)\&. Specify the path name of the accounting systems local UNIX domain socket in :pjsnmp\-accounting\-file\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Network connection\&. Specify host name and port number in :pjsnmp\-accounting\-host and :pjsnmp\-accounting\-port\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Pipe program\&. A program to handle accounting data is specified in :pjsnmp\-accounting\-file using \(lq|\(rq\&. The programs exit status indicates how to handle the print job: 0 to transfer data to the printer, 3 to remove the job (printing is denied), 6 to hold the job in the queue (printing is denied)\&.
+.RE
+.RE
+.PP
+\fB:pjsnmp\-accounting\-file=\fR\fIpath\fR
+.RS 4
+Path name for socket or accounting file\&. Default: none\&. A path started by \(lq|\(rq indicates a program to use in a pipe\&. The pipe is uni\-directional by definition\&. Pjsnmp writes accounting data into the pipe, the specified program reads this data from it\*(Aqs standard input\&.
+.sp
+For permission checks the programs exit status code indicates how to handle the print job (0=print, 3=remove job when printing is denied, 6=hold job when printing is denied)\&.
+.RE
+.PP
+\fB:pjsnmp\-accounting\-host=\fR\fIhost\fR
+.RS 4
+Host name for network connection\&. Note: Neither encryption nor authentication is used when transferring accounting data over network\&. The recommended method is to run the accounting software on the print server and use a local UNIX domain socket for communication\&.
+.RE
+.PP
+\fB:pjsnmp\-accounting\-port=\fR\fInumber\fR
+.RS 4
+Port number for network connection\&.
+.RE
+.PP
+\fB:pjsnmp\-non\-ascii\-job\-title\fR
+.RS 4
+Flag: Allow non\-ASCII characters in job title for accounting\&. Default: Off\&.
+.RE
+.PP
+\fB:pjsnmp\-allow\-printing\-if\-accounting\-connection\-failed\fR
+.RS 4
+Flag: Allow printing if no connection to accounting system is possible\&. Default: off\&.
+.RE
+.PP
+\fB:pjsnmp\-unreachable\-timeout\-start=\fR\fInumber\fR
+.RS 4
+Timeout (number of seconds) to abort the print job if the printer is unreachable at start of job\&. Default: 3600\&.
+.RE
+.PP
+\fB:pjsnmp\-unreachable\-timeout\-end=\fR\fInumber\fR
+.RS 4
+Timeout (number of seconds) to abort processing if the printer is unreachable after transferring print job data\&. Default: 120\&.
+.RE
+.PP
+\fB:pjsnmp\-unreachable\-timeout\-printing=\fR\fInumber\fR
+.RS 4
+Timeout (number of seconds) to abort data transfer if the printer is unreachable during data transfer\&. Default: 120\&.
+.RE
+.PP
+\fB:pjsnmp\-unwriteable\-timeout\-printing=\fR\fInumber\fR
+.RS 4
+Timeout (number of seconds) to abort data transfer if the network socket is not writeable during data transfer\&. Default: 900\&.
+.RE
+.PP
+\fB:pjsnmp\-verbose\fR
+.RS 4
+Flag: Verbose output (show command line arguments)\&.
+.RE
+.SH "FILES - SNMP MODEL FILE"
+.sp
+The ${datarootdir}/dktools/print\-snmp\&.conf file (or any other file you specify in the :pjsnmp\-model\-file entry in the printcap file) configures SNMP models\&.
+.sp
+Lines started by a raute character \(lq#\(rq are comments\&.
+.sp
+The file contains a list of SNMP models\&.
+.sp
+Each model description consists of a name line and a list of data lines\&.
+.sp
+The name line contains the model name in square brackets\&.
+.sp
+Data lines consist of key and value, separated by equal sign \(lq=\(rq\&. Both key and value can consist of multiple text words\&.
+.sp
+The following data lines are allowed:
+.PP
+\fBmap =\fR \fIdevice\fR\fB/\fR\fIprinter\fR \fIsummary\fR
+.RS 4
+Set mapping from a device status / printer status combination to a summary state\&.
+.RE
+.PP
+\fBerror condition =\fR \fIcondition\fR
+.RS 4
+Change the condition set from hrPrinterDetectedErrorState treated as errors\&. The first \(lqerror condition =\(rq line resets the condition set, so you can build a new one from scratch\&.
+.sp
+See the description of hrPrinterDetectedErrorState above for condition names\&. The default set contains the conditions marked as error in the description\&.
+.RE
+.PP
+\fBadd error condition =\fR \fIcondition\fR
+.RS 4
+Modify the condition set from hrPrinterDetectedErrorState treated as errors starting with the default set\&.
+.RE
+.PP
+\fBstatus text oid =\fR \fIoid\fR
+.RS 4
+OID delivering the status text shown in the printers first display line\&. The OID must be specified in
+\fInumeric\fR
+notation, 1\&.3\&.6\&.1\&.2\&.1\&.43\&.16\&.5\&.1\&.2\&.1\&.1 is the default\&.
+.RE
+.PP
+\fBtext standby =\fR \fItext\fR
+.RS 4
+Specifies a text signaling standby state\&.
+.sp
+Texts can be specified in double quotes or as hexadecimal byte sequence, i\&.e\&.:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+text standby = "Power Save"
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+is equivalent to
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+text standby = 50 6F 77 65 72 20 53 61 76 65
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The status text retrieved from the printer must match the specified text exactly\&.
+.RE
+.PP
+\fBstart standby =\fR \fItext\fR
+.RS 4
+Specifies a start of texts indicating summary state
+\fIstandby\fR\&.
+.sp
+Example
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+start standby = "Power Save"
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+detects
+\fIstandby\fR
+state if the printer returns status text \(lqPower Save Mode On\(rq\&.
+.RE
+.PP
+\fBtext idle =\fR \fItext\fR
+.RS 4
+Specifies texts indicating summary state
+\fIidle\fR\&.
+.RE
+.PP
+\fBstart idle =\fR \fItext\fR
+.RS 4
+Specifies a start of texts indicating summary state
+\fIidle\fR\&.
+.RE
+.PP
+\fBtext busy =\fR \fItext\fR
+.RS 4
+Specifies texts indicating summary state
+\fIbusy\fR\&.
+.RE
+.PP
+\fBstart busy =\fR \fItext\fR
+.RS 4
+Specifies a start of texts indicating summary state
+\fIbusy\fR\&.
+.RE
+.PP
+\fBtext unknown =\fR \fItext\fR
+.RS 4
+Specifies texts indicating summary state
+\fIunknown\fR\&.
+.RE
+.PP
+\fBstart unknown =\fR \fItext\fR
+.RS 4
+Specifies a start of texts indicating summary state
+\fIunknown\fR\&.
+.RE
+.PP
+\fBtext error =\fR \fItext\fR
+.RS 4
+Specifies texts indicating summary state
+\fIerror\fR\&.
+.RE
+.PP
+\fBstart error =\fR \fItext\fR
+.RS 4
+Specifies a start of texts indicating summary state
+\fIerror\fR\&.
+.RE
+.PP
+\fBtext warmup =\fR \fItext\fR
+.RS 4
+Specifies texts indicating summary state
+\fIwarmup\fR\&.
+.RE
+.PP
+\fBstart warmup =\fR \fItext\fR
+.RS 4
+Specifies a start of texts indicating summary state
+\fIwarmup\fR\&.
+.RE
+.PP
+\fBalways use status text =\fR \fIboolean\fR
+.RS 4
+Flag: Use status text for all summary states, default: off\&. If the flag is disabled, status texts are used only if the summary state found so far is
+\fIunknown\fR\&.
+.RE
+.SH "NOTES"
+.sp
+Different printer manufacturers use different interpretations of hrDeviceStatus, hrPrinterStatus and hrPrinterDetectedErrorState\&.
+.sp
+This program uses DK libraries version 4\&.
+.sp
+It is not available on the Windows platform\&.
+.sp
+Written as a simple program (not an application) it is not relocatable, all diagnostic messages and output texts are in English\&.
+.SH "NOTES - REASONABLE SNMP IMPLEMENTATION"
+.sp
+The first printers I used with pjsnmp followed the table found in [Edl2003] and a similar table found in RFC 3805\&.
+.TS
+allbox tab(:);
+ltB ltB ltB.
+T{
+Printer status
+T}:T{
+hrDeviceStatus
+T}:T{
+hrPrinterStatus
+T}
+.T&
+lt lt lt
+lt lt lt
+lt lt lt
+lt lt lt
+lt lt lt
+lt lt lt
+lt lt lt
+lt lt lt.
+T{
+.sp
+Normal, waiting for job
+T}:T{
+.sp
+running
+T}:T{
+.sp
+idle
+T}
+T{
+.sp
+Busy (printing)
+T}:T{
+.sp
+running
+T}:T{
+.sp
+printing
+T}
+T{
+.sp
+Non\-critical alert
+T}:T{
+.sp
+warning
+T}:T{
+.sp
+idle or printing
+T}
+T{
+.sp
+Unavailable (can\(cqt print)
+T}:T{
+.sp
+down
+T}:T{
+.sp
+other
+T}
+T{
+.sp
+Moving offline
+T}:T{
+.sp
+warning
+T}:T{
+.sp
+idle or printing
+T}
+T{
+.sp
+Offline (no printing possible)
+T}:T{
+.sp
+down
+T}:T{
+.sp
+other
+T}
+T{
+.sp
+Moving online (recovering from error or standby)
+T}:T{
+.sp
+down
+T}:T{
+.sp
+warmup
+T}
+T{
+.sp
+Standby
+T}:T{
+.sp
+running
+T}:T{
+.sp
+other
+T}
+.TE
+.sp 1
+.sp
+Some important points from the table:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The printer is either waiting for the next job or in standby if the device status is
+\fIrunning\fR
+or
+\fIwarning\fR
+and the printer status is
+\fIidle\fR
+or
+\fIother\fR\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The device status is
+\fIdown\fR
+for serious errors preventing the printer from printing\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The device status
+\fIwarning\fR
+indicates only conditions not preventing the printer from printing\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+If the printer has print data but any conditions prevents printing, one of the \(lqError\(rq condition bits in hrPrinterDetectedErrorState is set\&.
+.RE
+.SH "NOTES - THE SPECIAL SNMP IMPLEMENTATION"
+.sp
+Unfortunately some printer manufacturers use the \fIwarning\fR/\fIother\fR combination both for \(lqprinter is idle but there is a warning condition\(rq and for \(lqprinting interrupted due to error like out of paper, out of toner\&...\(rq\&.
+.sp
+Very special implementations show only warning conditions in hrPrinterDetectedErrorState in these situations\&.
+.SH "NOTES - CONCLUSION"
+.sp
+In the default configuration pjsnmp handles printers with a reasonable SNMP implementation\&. SNMP models are required to handle the special SNMP implementations\&.
+.SH "AUTHOR"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.TS
+tab(:);
+lt lt
+lt lt.
+T{
+.sp
+SF project page
+T}:T{
+.sp
+http://sourceforge\&.net/projects/dktools
+T}
+T{
+.sp
+DK tools home page
+T}:T{
+.sp
+http://dktools\&.sourceforge\&.net/dk\-ls\&.html
+T}
+.TE
+.sp 1
+.SH "LITERATURE"
+.PP
+Edl2003
+.RS 4
+H\&. Edlund: Design and Implementation of Accounting and Status Notification for the LPRng Print Spooler\&. Bachelor\(cqs Thesis, Linköping University, LITH\-IDA\-EX\-ING\(em03/019\(emSE
+.RE
diff --git a/support/dktools/man/man1/plpdftex.1 b/support/dktools/man/man1/plpdftex.1
new file mode 100644
index 0000000000..3e01448abe
--- /dev/null
+++ b/support/dktools/man/man1/plpdftex.1
@@ -0,0 +1,123 @@
+'\" t
+.\" Title: plpdftex
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 02/08/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "PLPDFTEX" "1" "02/08/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+plpdftex \- Output driver for octpgfpl
+.SH "SYNOPSIS"
+.sp
+\fBplpdftex\fR [\fIoption\fR]
+.SH "DESCRIPTION"
+.sp
+The program creates a PDF/TeX file pair based on graphics instructions found in input\&.
+.sp
+It is not a general purpose program, it is only an output driver for the octpgfpl package for GNU Octave\&.
+.SH "OPTIONS"
+.PP
+\fB\-l\fR
+.RS 4
+Show license terms\&.
+.RE
+.PP
+\fB\-\-help\fR
+.RS 4
+Show help text\&.
+.RE
+.PP
+\fB\-\-check\-presence\fR
+.RS 4
+Write \*(Aq1\*(Aq to standard output and return exit code 0\&. The pgfplot() function from the octpgfpl package for GNU Octave uses this option to check the presence of the plpdftex program\&.
+.RE
+.SH "EXIT STATUS"
+.sp
+The program sets exit status code 0 on success, any other value indicates an error\&.
+.SH "RESTRICTIONS"
+.PP
+\fBNo full graphics instruction set\fR
+.RS 4
+The program is not a full text to PDF/TeX converter, only the graphics instructions needed by the pgfplot() function are supported\&.
+.RE
+.PP
+\fBShould not be run as root on input provided by users\fR
+.RS 4
+As the names of the output files to write are configured via input, you should not run the program as root and not on input from untrusted sources\&.
+.RE
+.SH "NOTES"
+.sp
+This program uses DK libraries version 4\&.
+.SH "AUTHOR"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2014\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net/
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/printqd.1 b/support/dktools/man/man1/printqd.1
new file mode 100644
index 0000000000..c6691f69af
--- /dev/null
+++ b/support/dktools/man/man1/printqd.1
@@ -0,0 +1,260 @@
+'\" t
+.\" Title: printqd
+.\" Author: [see the "AUTHORS" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 03/28/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "PRINTQD" "1" "03/28/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+printqd \- Print quota daemon for LPRng
+.SH "SYNOPSIS"
+.sp
+\fBprintqd\fR [\fIoptions\fR]
+.SH "CONFIGURATION"
+.sp
+Before you can run printqd you must find the user and group used to run the LPRng software\&. Check the /etc/lpd/lpd\&.conf file for lines
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+default user=
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+default group=
+.RE
+.sp
+In our example we assume the default settings, user \(lqdaemon\(rq and group \(lqdaemon\(rq\&.
+.sp
+Make sure the directories
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+${localstatedir}/printqd
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+${localstatedir}/run/printqd
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+${localstatedir}/log/printqd
+.RE
+.sp
+exist and are owned by user \(lqdaemon\(rq and group \(lqdaemon\(rq\&. Permissions to these directories must be set to 770 (rwxrwx\-\-\-) or 775 (rwxrwxr\-x)\&.
+.sp
+The place of the local state directory ${localstatedir} depends on your installation, typically it is the /var or /usr/local/var directory\&. You can use the dk4info program to find it, use the directory from the \(lqConfigured at built time:\(rq section\&.
+.sp
+Some systems clean the /var/run directory completely on boot or reboot\&. On such systems the /var/run/printqd directory must be created and set up before printqd is started\&.
+.SH "DESCRIPTION"
+.sp
+Printqd is a daemon to allow or deny print jobs on LPRng print systems\&. It can be used to simply allow/deny printing for users based on user name or group membership\&. If LPRng can retrieve page counter values from printers printqd can be used to enforce page limits or to calculate the amount of pages printed by a user within a given time period\&.
+.sp
+Printqd was developed specifically for LPRng, it can not be used with other print systems\&.
+.sp
+The program was developed with schools and universities in mind to stop stupid printing\&. These institutions can allow every student a page limit of \fIn\fR pages per semester/trimester on all PC classroom printers in summary without having to configure each user individually\&. On a semester start all used pages numbers records are removed using one administrative command, so all users are reset to \(lq0 pages printed\(rq\&. Inidividual accounts can be created (i\&.e\&. for those doing bachelor/master thesis in\-house or for students assisting in projects or for pre\-paid printing additional pages)\&. These individual accounts are not affected by the global reset command\&.
+.sp
+LPRng checks once whether a print job is allowed to be printed before starting processing\&. So printqd compares the number of pages used within the general limit against the limit value and allows printing if the limit is not yet reached\&. If the limit is reached printqd checks whether there is a positive number of pages in the personal print account\&. This checking is only done once before a print job is sent to a printer, the entire print job is printed if the check succeeds\&. So the LPRng/printqd combination probably allows one last print job of every user to exceed the limit, but no further print jobs are allowed for that user\&.
+.SH "OPTIONS"
+.PP
+\fB\-c\fR \fIconfigfile\fR
+.RS 4
+Specify the configuration file name\&.
+.RE
+.PP
+\fB\-d\fR
+.RS 4
+Run in debug mode: Do not fork to run as background process, write log messages to standard error channel\&.
+.RE
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other status codes indicate an error\&.
+.SH "DIAGNOSTICS"
+.sp
+Printqd writes messages to a log file, important messages (start and end of daemon, start and end of processing) are also written to system log\&.
+.SH "COMMUNICATION"
+.sp
+Client programs can use three methods to contact printqd:
+.PP
+Local UNIX domain socket
+.RS 4
+The preferred method for all data transfer\&. An administrator can set permissions in the file system to restrict access to the socket\&.
+.RE
+.PP
+TCP connection (optional)
+.RS 4
+Printqd listens on a specified TCP port for incoming connection requests\&. Should be used and allowed for remote LPRng servers serving print queues only, and for the \(lqinfo\(rq protocol level\&.
+.RE
+.PP
+UDP datagrams (optional)
+.RS 4
+UDP datagrams are allowed to contain requests\&. Printqd sends the response to the address the request came from\&. Should be used for the \(lqinfo\(rq protocol level only\&.
+.RE
+.sp
+When enabling TCP and/or UDP you can configure which hosts are allowed to use the \(lqinfo\(rq, \(lqdata\(rq or \(lqadmin\(rq protocol levels\&.
+.SH "FILES"
+.sp
+The format of the ${sysconfdir}/printqd/printqd\&.conf configuration file is documented in the printqd\&.conf(5) man page\&.
+.sp
+The format of the database is documented in the printqd\&.db(5) man page\&.
+.sp
+The communication protocol for printqd is documented in the printqd\&.protocol(5) man page\&.
+.SH "VERSIONS"
+.sp
+In version 4\&.3\&.0 printqd was rewritten\&. When upgrading from 4\&.2\&.2 and below, the configuration file needs modification\&.
+.SH "REQUIREMENTS"
+.sp
+Printqd and friends can be used with the LPRng print system only as they are specifically designed for that print system\&.
+.sp
+For print quota: Printers must allow to read the page counter value and some other information (device state, printer state, printer detected error state) using the SNMP protocol\&. Most printers with integrated ethernet connectors will do\&. External ethernet print servers attached to the printers parallel or USB port do not have access to the printers page counter\&.
+.sp
+The ifhp filter (part of LPRng) can retrieve this information by communicating to the printer, see the ifhp\&.conf file for suitable printers\&.
+.sp
+Printers must accept print data only from the LPRng print server\&. If any host can send print data to the printer, everyone can easily bypass the LPRng system and the quota system\&. Most printers today have a web interface or at least some telnet/ssh interface to configure the printer\&. Typically you can restrict the hosts allowed to send print data here\&.
+.SH "NOTES"
+.sp
+This program uses DK libraries version 4\&.
+.sp
+It is not available on the Windows platform\&.
+.sp
+Written as a simple program (not an application) it is not relocatable, all diagnostic messages and output texts are in English\&.
+.SH "AUTHORS"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+printqd\&.conf(5)
+.RS 4
+Print quota daemon configuration file syntax\&.
+.RE
+.PP
+printqd\&.db(5)
+.RS 4
+Database structure for printqd\&.
+.RE
+.PP
+printqd\&.protocol(5)
+.RS 4
+Communication protocol for printqd\&.
+.RE
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
+.PP
+http://www\&.lprng\&.com
+.RS 4
+The LPRng print system\&.
+.RE
+.PP
+printqdc(1)
+.RS 4
+Client to communicate to printqd\&.
+.RE
+.PP
+wxpqdic(1)
+.RS 4
+Client to retrieve print quota status for a user\&.
+.RE
+.PP
+pjsnmp(1)
+.RS 4
+Data transer filter for use with LPRng, can communicate directly to printqd\&.
+.RE
diff --git a/support/dktools/man/man1/printqda.1 b/support/dktools/man/man1/printqda.1
new file mode 100644
index 0000000000..24439de712
--- /dev/null
+++ b/support/dktools/man/man1/printqda.1
@@ -0,0 +1,263 @@
+'\" t
+.\" Title: printqda
+.\" Author: [see the "AUTHORS" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 01/03/2016
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "PRINTQDA" "1" "01/03/2016" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+printqda \- Print quota daemon administration
+.SH "SYNOPSIS"
+.sp
+\fBprintqda\fR
+.SH "CONFIGURATION"
+.sp
+A configuration file printqd\&.conf is used for setup, see \fBprintqd\&.conf(5)\fR\&. Typically the file is located in the ${sysconfdir}/printqd directory\&.
+.SH "DESCRIPTION"
+.sp
+The printqda program reads standard input line by line\&. Each input line is processed by the following steps:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The line is checked whether it is a valid request in the printqd protocol\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+A connection to the printqd is established\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The request line is written to printqd\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+If there is a response from printqd, it is printed to standard output\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The connection to printqd is closed\&.
+.RE
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other status codes indicate an error\&.
+.SH "PROTOCOL"
+.sp
+The protocol has three levels: "info", "data" and "admin"\&.
+.sp
+The "info" protocol level contains just the "info" request (see below)\&. The wxpqdic client connects to a prinqdi daemon\&. This daemon checks the request and forwards it to the printqd daemon\&. The response from printqd is forwarded to the remote wxpqdic client\&.
+.sp
+The "data" protocol level contains the requests from the "info" protocol level and the "acct\-check", "acct\-start" and "acct\-end" requests (see below)\&. LPRng and/or pjsnmp use these requests to check whether to accept or reject a job and to save page counter values\&. LPRng should not connect directly to the UNIX domain socket, it should run printqdc in a pipe\&. The printqdc program translates LPRng requests into the printqd protocol before connecting to printqd\&.
+.sp
+The "admin" protocol level contains the requests from the "data" protocol level and the "control" requests (see below)\&. The printqda client can be used to communicate to printqd\&.
+.sp
+The printqda program can use all three protocol levels\&.
+.sp
+The following requests are processed by printqd:
+.PP
+\fBinfo\fR \fIprinter\fR \fIuser\fR
+.RS 4
+Information whether a user can print on a printer\&. The response line consists of four numbers:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Page limit (0 for printing denied, \-1 for unlimited printing)\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Pages used from print limit\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Available pages in personal print account\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Summary\&. 1: Printing allowed\&. 0: Printing denied\&.
+.RE
+.RE
+.PP
+\fBacct\-check\fR \fIprinter\fR \fIuser\fR
+.RS 4
+Check whether the user is allowed to print on the printer\&. The response line contains one of the keywords:
+.TS
+tab(:);
+lt lt
+lt lt
+lt lt.
+T{
+\fBACCEPT\fR
+T}:T{
+Process the print job\&.
+T}
+T{
+\fBREMOVE\fR
+T}:T{
+Printing denied, delete job\&.
+T}
+T{
+\fBHOLD\fR
+T}:T{
+Printing denied, hold job in queue\&.
+T}
+.TE
+.sp 1
+.RE
+.PP
+\fBacct\-start\fR \fIprinter\fR \fIuser\fR \fIpagecount\fR \fIjobname\fR \fIjobtitle\fR
+.RS 4
+Start of a print job, save page counter value\&. No response\&.
+.RE
+.PP
+\fBacct\-end\fR \fIprinter\fR \fIuser\fR \fIpagecount\fR \fIjobname\fR \fIjobtitle\fR
+.RS 4
+End of a print job, calculate and save number of pages for job\&. No response\&.
+.RE
+.PP
+\fBcontrol\fR \fBreset\fR \fBclass=\fR\fIclassname\fR \fBuser=\fR\fIusername\fR
+.RS 4
+Delete database entry about number of printed pages for a user in a printer class (resets number of printed pages to 0)\&. An asterisk may be used in the class and/or user name\&. No response\&.
+.RE
+.PP
+\fBcontrol\fR \fBadd\fR \fBclass=\fR\fIclassname\fR \fBuser=\fR\fIusername\fR \fBpages=\fR\fInumber\fR
+.RS 4
+Increase a users personal print account by a number of pages\&. No response\&.
+.RE
+.PP
+\fBcontrol\fR \fBdatabase\-cleanup\fR
+.RS 4
+Clean up the database\&. Remove entries for non\-existing users or printers\&. No response\&.
+.RE
+.SH "AUTHORS"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2012\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/printqdc.1 b/support/dktools/man/man1/printqdc.1
new file mode 100644
index 0000000000..f5e5f22569
--- /dev/null
+++ b/support/dktools/man/man1/printqdc.1
@@ -0,0 +1,270 @@
+'\" t
+.\" Title: printqdc
+.\" Author: [see the "AUTHORS" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 03/28/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "PRINTQDC" "1" "03/28/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+printqdc \- Print quota daemon administration
+.SH "SYNOPSIS"
+.sp
+\fBprintqdc\fR
+.SH "CONFIGURATION"
+.sp
+A configuration file printqd\&.conf is used for setup, see \fBprintqd\&.conf(5)\fR\&. Typically the file is located in the ${sysconfdir}/printqd directory\&.
+.SH "DESCRIPTION"
+.sp
+The printqdc program reads standard input line by line\&. Each input line is processed by the following steps:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The line is checked whether it is a valid request in the printqd protocol, levels "info" or "data"\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+A connection to the printqd is established\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The request line is written to printqd\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+If there is a response from printqd, it is printed to standard output\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The connection to printqd is closed\&.
+.RE
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other status codes indicate an error\&.
+.SH "NOTES"
+.sp
+This program uses DK libraries version 4\&.
+.sp
+It is not available on the Windows platform\&.
+.sp
+Written as a simple program (not an application) it is not relocatable, all diagnostic messages and output texts are in English\&.
+.SH "PROTOCOL"
+.sp
+The protocol has three levels: "info", "data" and "admin"\&.
+.sp
+The "info" protocol level contains just the "info" request (see below)\&. The wxpqdic client connects to a prinqdi daemon\&. This daemon checks the request and forwards it to the printqd daemon\&. The response from printqd is forwarded to the remote wxpqdic client\&.
+.sp
+The "data" protocol level contains the requests from the "info" protocol level and the "acct\-check", "acct\-start" and "acct\-end" requests (see below)\&. LPRng and/or pjsnmp use these requests to check whether to accept or reject a job and to save page counter values\&. LPRng should not connect directly to the UNIX domain socket, it should run printqdc in a pipe\&. The printqdc program translates LPRng requests into the printqd protocol before connecting to printqd\&.
+.sp
+The "admin" protocol level contains the requests from the "data" protocol level and the "control" requests (see below)\&.
+.sp
+The printqdc program can use the "info" and "data" levels of the protocol\&.
+.sp
+The following requests are processed by printqd:
+.PP
+\fBinfo\fR \fIprinter\fR \fIuser\fR
+.RS 4
+Information whether a user can print on a printer\&. The response line consists of four numbers:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Page limit (0 for printing denied, \-1 for unlimited printing)\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Pages used from print limit\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Available pages in personal print account\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Summary\&. 1: Printing allowed\&. 0: Printing denied\&.
+.RE
+.RE
+.PP
+\fBacct\-check\fR \fIprinter\fR \fIuser\fR
+.RS 4
+Check whether the user is allowed to print on the printer\&. The response line contains one of the keywords:
+.TS
+tab(:);
+lt lt
+lt lt
+lt lt.
+T{
+\fBACCEPT\fR
+T}:T{
+Process the print job\&.
+T}
+T{
+\fBREMOVE\fR
+T}:T{
+Printing denied, delete job\&.
+T}
+T{
+\fBHOLD\fR
+T}:T{
+Printing denied, hold job in queue\&.
+T}
+.TE
+.sp 1
+.RE
+.PP
+\fBacct\-start\fR \fIprinter\fR \fIuser\fR \fIpagecount\fR \fIjobname\fR \fIjobtitle\fR
+.RS 4
+Start of a print job, save page counter value\&. No response\&.
+.RE
+.PP
+\fBacct\-end\fR \fIprinter\fR \fIuser\fR \fIpagecount\fR \fIjobname\fR \fIjobtitle\fR
+.RS 4
+End of a print job, calculate and save number of pages for job\&. No response\&.
+.RE
+.PP
+\fBcontrol\fR \fBreset\fR \fBclass=\fR\fIclassname\fR \fBuser=\fR\fIusername\fR
+.RS 4
+Delete database entry about number of printed pages for a user in a printer class (resets number of printed pages to 0)\&. An asterisk may be used in the class and/or user name\&. No response\&.
+.RE
+.PP
+\fBcontrol\fR \fBadd\fR \fBclass=\fR\fIclassname\fR \fBuser=\fR\fIusername\fR \fBpages=\fR\fInumber\fR
+.RS 4
+Increase a users personal print account by a number of pages\&. No response\&.
+.RE
+.PP
+\fBcontrol\fR \fBdatabase\-cleanup\fR
+.RS 4
+Clean up the database\&. Remove entries for non\-existing users or printers\&. No response\&.
+.RE
+.SH "AUTHORS"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2012\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/printqdi.1 b/support/dktools/man/man1/printqdi.1
new file mode 100644
index 0000000000..5533e77426
--- /dev/null
+++ b/support/dktools/man/man1/printqdi.1
@@ -0,0 +1,162 @@
+'\" t
+.\" Title: printqdi
+.\" Author: [see the "AUTHORS" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 02/08/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "PRINTQDI" "1" "02/08/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+printqdi \- Print quota information daemon
+.SH "SYNOPSIS"
+.sp
+printqdi
+.SH "CONFIGURATION"
+.sp
+A configuration file printqd\&.conf is used for setup, see \fBprintqd\&.conf(5)\fR\&. Typically the file is located in the ${sysconfdir}/printqd directory\&.
+.SH "DESCRIPTION"
+.sp
+The printqdi daemon listens on a TCP port for incoming connections\&.
+.sp
+On each connection one request is read, checked and forwarded to the printqd daemon over the UNIX domain socket\&. The response from printqd is written to the connection\&.
+.sp
+Programs like wxpqdic can be used on desktop clients to show users whether or not they are allowed to print\&.
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other status codes indicate an error\&.
+.SH "PROTOCOL"
+.sp
+The protocol has three levels: "info", "data" and "admin"\&. Printqdi only handles the "info" level\&.
+.sp
+The "info" protocol level contains just the "info" request (see below)\&. The wxpqdic client connects to a prinqdi daemon\&. This daemon checks the request and forwards it to the printqd daemon\&. The response from printqd is forwarded to the remote wxpqdic client\&.
+.PP
+\fBinfo\fR \fIprinter\fR \fIuser\fR
+.RS 4
+Information whether a user can print on a printer\&. The response line consists of four numbers:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Page limit (0 for printing denied, \-1 for unlimited printing)\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Pages used from print limit\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Available pages in personal print account\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Summary\&. 1: Printing allowed\&. 0: Printing denied\&.
+.RE
+.RE
+.SH "AUTHORS"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2012\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+\fBprintqd\&.conf(5)\fR
+.RS 4
+Configuration file syntax\&.
+.RE
+.PP
+\fBprintqd(1)\fR
+.RS 4
+Print quota enforcement daemon for LPRng\&.
+.RE
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/prmonsnmp.1 b/support/dktools/man/man1/prmonsnmp.1
new file mode 100644
index 0000000000..cb3b40a3f5
--- /dev/null
+++ b/support/dktools/man/man1/prmonsnmp.1
@@ -0,0 +1,202 @@
+'\" t
+.\" Title: prmonsnmp
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 03/28/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "PRMONSNMP" "1" "03/28/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+prmonsnmp \- Printer monitoring using the SNMP protocol
+.SH "SYNOPSIS"
+.sp
+\fBprmonsnmp\fR \fIoptions\fR \fIhost\fR
+.SH "DESCRIPTION"
+.sp
+The program periodically retrieves data for the
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+hrDeviceStatus
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+hrPrinterStatus
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+hrPrinterDetectedErrorState
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+prtMarkerLifeCount
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+prtConsoleDisplayBufferText
+.RE
+.sp
+OIDs using the SNMP protocol from the specified printer and reports any changes\&. The hrPrinterDetectedErrorState value is shown both as bits array and as text\&.
+.sp
+Prmonsnmp can be used for two purposes:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Finding information desired to build an SNMP model for the pjsnmp program\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Monitoring a printer\&.
+.RE
+.SH "OPTIONS"
+.PP
+\fB\-v\fR \fIversion\fR
+.RS 4
+SNMP version, one from \(lq1\(rq, \(lq2c\(rq, \(lq2\(rq (same as 2c) and \(lq3\(rq\&. Default: 1\&.
+.RE
+.PP
+\fB\-c\fR \fIname\fR
+.RS 4
+SNMP community name, default: \(lqpublic\(rq\&.
+.RE
+.PP
+\fB\-t\fR \fInumber\fR
+.RS 4
+Timeout in seconds\&. Default: endless (until interrupted by INT or TERM signal)\&.
+.RE
+.PP
+\fB\-n\fR
+.RS 4
+Do not sleep for a grace period of 250ms between SNMP queries\&.
+.RE
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other status codes indicate an error\&.
+.SH "NOTES"
+.sp
+Non\-ASCII characters in the prtConsoleDisplayBufferText value are replaced by question marks \(lq?\(rq when writing the text\&.
+.sp
+This program uses DK libraries version 4\&.
+.sp
+It is not available on the Windows platform\&.
+.sp
+Written as a simple program (not an application) it is not relocatable, all diagnostic messages and output texts are in English\&.
+.SH "AUTHOR"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/rshdown.1 b/support/dktools/man/man1/rshdown.1
new file mode 100644
index 0000000000..161b8d68f4
--- /dev/null
+++ b/support/dktools/man/man1/rshdown.1
@@ -0,0 +1,402 @@
+'\" t
+.\" Title: rshdown
+.\" Author: [see the "AUTHORS" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 03/28/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "RSHDOWN" "1" "03/28/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+rshdown \- Remote shutdown
+.SH "SYNOPSIS"
+.sp
+\fBrshdown\fR [\fB\-c\fR \fIconfigfile\fR]
+.sp
+\fBrshdown\fR \fB\-s\fR [\fB\-n\fR \fInumber\fR] [\fB\-l\fR \fIport\fR] [\fB\-b\fR] \fIhost\fR \fIport\fR \fIfile\fR
+.SH "DESCRIPTION"
+.sp
+If a server is shut down by the uninterruptable power supply (UPS) it might be a good idea to shut down all the clients requiring server resources before shutting down the server itself as the clients may hang if the server is not available\&. Especially NFS clients should be shut down before shutting down the NFS server\&.
+.sp
+The rshdown binary is:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+A daemon waiting for a shutdown data packet and
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+a client to send a shutdown data packet to one or multiple rshdown daemons\&.
+.RE
+.sp
+The shutdown sender (the client) and the shutdown recipients (daemons) have a pre\-shared secret (a file containing up to 1460 bytes of random data distributed between the involved computers on a secure channel)\&.
+.sp
+To initiate a remote shutdown the sender reads the data from the local copy of the file and sends an UDP packet containing the data to the recipients\&.
+.sp
+The recipients wait for incoming UDP data packets on a specified port\&. Incoming packets on this port are checked for several conditions:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Sender address
+
+If the configuration file contains a
+\fBsender\fR
+line, shutdown packets are only accepted from that host or network\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Sender port
+
+If the configuration file contains a
+\fBsender port\fR
+line, shutdown packets are only accepted when coming from this port\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Packet contents
+
+The packet contents is compared against the recipients local copy of the pre\-shared secret file\&. A shutdown is only initiated, if the comparison succeeds\&.
+.RE
+.SH "OPTIONS"
+.PP
+\fB\-c\fR \fIconfigfile\fR
+.RS 4
+Configuration file for the daemon\&.
+.RE
+.PP
+\fB\-s\fR
+.RS 4
+Send data\&. This option runs the sender functionality\&. If \-s is omitted, the program will run as recipient (daemon) and wait for incoming data packets\&.
+.RE
+.PP
+\fB\-l\fR \fIport\fR
+.RS 4
+Local port number for the sender to use\&.
+.RE
+.PP
+\fB\-b\fR
+.RS 4
+Initialize the socket to send broadcast packets\&. Specify a broadcast address for the
+\fIhost\fR\&.
+.RE
+.PP
+\fB\-n\fR \fInumber\fR
+.RS 4
+Number of packets to send, default: 1\&.
+.RE
+.PP
+\fIhost\fR
+.RS 4
+Recipients address as host name, IPv4 or IPv6 address\&. When specifying broadcast addresses like 255\&.255\&.255\&.255 or 192\&.0\&.2\&.255 you have to use the \-b option to enable broadcast sending\&.
+.RE
+.PP
+\fIport\fR
+.RS 4
+Port number the recipient ist listening on\&.
+.RE
+.PP
+\fIfile\fR
+.RS 4
+Path name of file containing the pre\-shared secret\&.
+.RE
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other status codes indicate an error\&.
+.SH "ENVIRONMENT"
+.sp
+Rshdown uses the system() function to run the command specified in the configuration file\&. This function passes the given command to the /bin/sh shell\&.
+.SH "FILES"
+.sp
+The default path ${sysconfdir}/rshdown/rshdown\&.conf for the server (daemon) configuration file can be overwritten by the \-c option\&.
+.sp
+Lines started by # are comment lines\&.
+.sp
+The following lines are allowed in the configuration file:
+.PP
+\fBsender =\fR \fIaddress\fR
+.RS 4
+IP address(es) we accept packets from\&. Optional, no default\&.
+.RE
+.PP
+\fBsender port =\fR \fIport\fR
+.RS 4
+Port number on sender\&. Optional, default 0 accepts any sender port\&.
+.RE
+.PP
+\fBreceiver port =\fR \fIport\fR
+.RS 4
+Local port number to read UDP packets\&. Required, no default\&.
+.RE
+.PP
+\fBfile =\fR \fIpath\fR
+.RS 4
+Full path name of file containing the pre\-shared secret\&.
+.RE
+.PP
+\fBsignal =\fR \fIsignal\fR
+.RS 4
+Signal number (preferred) or name\&. The signal specified here is sent to process 1 (init) to initiate a shutdown if an acceptable shutdown packet was received unless a command to execute is specified (see below)\&. Optional, default: SIGPWR\&.
+.RE
+.PP
+\fBcommand =\fR \fIcommand\fR
+.RS 4
+Command to execute if an acceptable shutdown packet was received, overwrites any specified signal number\&. Optional, no default\&.
+.RE
+.PP
+\fBsyslog facility =\fR \fIname\fR
+.RS 4
+Name of syslog facility\&. Optional, default auth\&.
+.RE
+.PP
+\fBdebug =\fR \fIboolean\fR
+.RS 4
+Flag: Write additional debug messages to syslog for discarded packets\&.
+.RE
+.SH "RESTRICTIONS"
+.sp
+\fBThe contents of the secret file is sent unencrypted\&.\fR
+.sp
+After an emergency shutdown you should replace it by a new file on all involved machines!
+.sp
+An emergency shutdown due to power failure and UPS battery running low should be as fast as possible for both the server and the clients\&. So I decided to do notification using UDP packets including sending the notification packet to a broadcast address for several reasons:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Using TCP connections would require timeout mechanisms resulting in a longer time needed for sending on the server connected to the UPS\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Opening multiple TCP connections at same time would result in multiple processes on the server and a higher resource usage\&. This is not a good idea because the server might need these resources to cleanly shut down all server processes as fast as possible\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Using a challenge/response mechanism would require a TCP connection to each recipient and the cryptographic operations would result in additional CPU load\&.
+.RE
+.SH "NOTES"
+.sp
+This program uses DK libraries version 4\&.
+.sp
+It is not available on the Windows platform\&.
+.SH "EXAMPLES"
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+\fBGenerate pre\-shared secret file:\fR
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+touch /etc/rshdown/secret
+chmod 600 /etc/rshdown/secret
+dk\-pwgen \-b \-l 1450\-1460 > /etc/rshdown/secret
+chmod 600 /etc/rshdown/secret
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+\fBUse scp to copy secret file (on destination machine):\fR
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+mkdir \-p /etc/rshdown
+chmod 755 /etc/rshdown
+touch /etc/rshdown/secret
+chmod 600 /etc/rshdown/secret
+scp __user__@__host__:/etc/rshdown/secret /etc/rshdown/secret
+chmod 600 /etc/rshdown/secret
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+\fBGenerate /etc/rshdown/rshdown\&.conf file on recipient hosts:\fR
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+# Allowed sender address
+sender = 192\&.0\&.2\&.100
+
+# Allowed sender port (any if not specified here)
+sender port = 1234
+
+# Local UDP port we are using
+receiver port = 1234
+
+# File containing data to compare against packet contents
+file = /etc/rshdown/secret
+
+# Signal number to send to init process
+# Only used if no command specified below
+signal = sigpwr
+
+# Command to execute on arrival of shutdown packet
+# The command should return immediately (so you can run a task
+# in background)
+# NOTE: The shutdown command differs between operating systems\&.
+# I\&.e\&. on Solaris you would use "shutdown \-i0 \-g0 \-y" instead\&.
+command = /sbin/shutdown \-h now > /dev/null 2>&1 &
+
+# Syslog facility used by daemon
+syslog facility = auth
+
+# Flag: Debug messages in syslog for discarded packets
+debug = off
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.SH "AUTHORS"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/wxbmpp.1 b/support/dktools/man/man1/wxbmpp.1
new file mode 100644
index 0000000000..e0564f1a70
--- /dev/null
+++ b/support/dktools/man/man1/wxbmpp.1
@@ -0,0 +1,132 @@
+'\" t
+.\" Title: wxbmpp
+.\" Author: [see the "AUTHORS" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 03/28/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "WXBMPP" "1" "03/28/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+wxbmpp \- GUI program to convert PNG/JPEG/TIFF to PDF/PS
+.SH "SYNOPSIS"
+.sp
+\fBwxbmpp\fR
+.SH "DESCRIPTION"
+.sp
+The program provides a GUI to convert PNG/JPEG/TIFF files to PDF or PS\&. In the program you can:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Choose a directory containing the images to convert\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Set conversion options\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Run the conversion\&.
+.RE
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other status codes indicate an error\&.
+.SH "NOTES"
+.sp
+This program uses DK libraries version 3\&.
+.SH "AUTHORS"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2011\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+\fBbmpp(1)\fR
+.RS 4
+Command line tool to convert PNG/JPEG/TIFF to PDF/PS\&.
+.RE
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/wxdkclock.1 b/support/dktools/man/man1/wxdkclock.1
new file mode 100644
index 0000000000..271811cb88
--- /dev/null
+++ b/support/dktools/man/man1/wxdkclock.1
@@ -0,0 +1,94 @@
+'\" t
+.\" Title: wxdkclock
+.\" Author: [see the "AUTHORS" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 02/08/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "WXDKCLOCK" "1" "02/08/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+wxdkclock \- Desktop clock with one alert
+.SH "SYNOPSIS"
+.sp
+\fBwxdkclock\fR
+.SH "DESCRIPTION"
+.sp
+The program shows a clock on the desktop\&. You can configure one alert\&. If alert time is reached the wxdkclock window comes to front and maximizes\&.
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other status codes indicate an error\&.
+.SH "NOTES"
+.sp
+This program uses DK libraries version 3\&. all diagnostic messages and output texts are in English\&.
+.SH "AUTHORS"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2015\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/wxdkct.1 b/support/dktools/man/man1/wxdkct.1
new file mode 100644
index 0000000000..6d30e1e54e
--- /dev/null
+++ b/support/dktools/man/man1/wxdkct.1
@@ -0,0 +1,169 @@
+'\" t
+.\" Title: wxdkct
+.\" Author: [see the "AUTHORS" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 03/28/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "WXDKCT" "1" "03/28/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+wxdkct \- wxWidgets GUI version of dkct
+.SH "SYNOPSIS"
+.sp
+wxdkct
+.SH "DESCRIPTION"
+.sp
+The program provides:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+A preprocessor for debug/trace instructions,
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+a code generator for state machines,
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+a code generator for GUIs using the wxWidgets library\&.
+.RE
+.sp
+The program converts *\&.ctr, *\&.cpt, *\&.mtr and *\&.jtr files to *\&.c, *\&.cpp, *\&.m and *\&.java\&. The source files can contain debug instructions in a special notation\&. When producing release versions the debug instructions are ignored\&. When producing debug versions the debug instructions are converted to output instructions\&.
+.sp
+In the GUI you can:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Choose a directory containing the source files,
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+set conversion options and
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+start conversions\&.
+.RE
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other status codes indicate an error\&.
+.SH "NOTES"
+.sp
+This program uses DK libraries version 3\&.
+.SH "AUTHORS"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2011\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+\fBdkct(1)\fR
+.RS 4
+Command line version of wxdkct\&.
+.RE
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/wxdkfcs.1 b/support/dktools/man/man1/wxdkfcs.1
new file mode 100644
index 0000000000..baaafb203d
--- /dev/null
+++ b/support/dktools/man/man1/wxdkfcs.1
@@ -0,0 +1,91 @@
+'\" t
+.\" Title: wxdkfcs
+.\" Author: [see the "AUTHORS" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 01/03/2016
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "WXDKFCS" "1" "01/03/2016" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+wxdkfcs \- GUI tools to view file checksums
+.SH "SYNOPSIS"
+.sp
+\fBwxdkfcs\fR [\fIfile\fR]
+.SH "DESCRIPTION"
+.sp
+The program calculates checksums for a file using different message digest algorithms\&. The results are shown in hexadecimal notation\&.
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other status codes indicate an error\&.
+.SH "AUTHORS"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2015\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/wxdkhtb.1 b/support/dktools/man/man1/wxdkhtb.1
new file mode 100644
index 0000000000..c2050c147b
--- /dev/null
+++ b/support/dktools/man/man1/wxdkhtb.1
@@ -0,0 +1,94 @@
+'\" t
+.\" Title: wxdkhtb
+.\" Author: [see the "AUTHORS" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 02/08/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "WXDKHTB" "1" "02/08/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+wxdkhtb \- Viewer for HTB files
+.SH "SYNOPSIS"
+.sp
+\fBwxdkhtb\fR [\fIfile\fR]
+.SH "DESCRIPTION"
+.sp
+The viewer shows the specified *\&.htb file\&.
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other status codes indicate an error\&.
+.SH "NOTES"
+.sp
+This program uses DK libraries version 3\&.
+.SH "AUTHORS"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2014\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/wximgsz.1 b/support/dktools/man/man1/wximgsz.1
new file mode 100644
index 0000000000..2008247bb3
--- /dev/null
+++ b/support/dktools/man/man1/wximgsz.1
@@ -0,0 +1,154 @@
+'\" t
+.\" Title: wximgsz
+.\" Author: [see the "AUTHORS" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2016
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "WXIMGSZ" "1" "09/03/2016" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+wximgsz \- Suggest size pairs to scale an image
+.SH "SYNOPSIS"
+.sp
+\fBwximgsz\fR
+.SH "DESCRIPTION"
+.sp
+The program suggests and evaluates size pairs (width and height) to rescale a bitmap image\&.
+.sp
+In the "Original image" section of the main window enter the width and height of an existing image (number of pixels)\&.
+.sp
+In the "Intended change" section you can choose an action:
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 1.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 1." 4.2
+.\}
+Decrease the image
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 2.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 2." 4.2
+.\}
+Scale image to a width fitting into a given range
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 3.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 3." 4.2
+.\}
+Scale image to a height fitting into a given range
+.RE
+.sp
+For (2) and (3) you have to specify the range\&.
+.sp
+After pushing the "Calculate new images sizes" button the results \- if any \- are shown in the table in the "Results" section\&.
+.sp
+Each line contains a suggested width and height pair\&.
+.sp
+Evaluation is shown by red, yellow or green background or optionally by an indicator string (empty string, one plus sign or two plus signs)\&.
+.PP
+Red / empty string
+.RS 4
+Basic quality: Both new width and height values are integers\&.
+.RE
+.PP
+Yellow / "+"
+.RS 4
+Better quality: New width and height and the scale factor are integer numbers\&.
+.RE
+.PP
+Green / "++"
+.RS 4
+Best quality: New width and height values are integers, the scale factor is a power of 2\&.
+.RE
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other status codes indicate an error\&.
+.SH "NOTES"
+.sp
+This program uses DK libraries version 3\&.
+.SH "AUTHORS"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2012\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man1/wxpqdic.1 b/support/dktools/man/man1/wxpqdic.1
new file mode 100644
index 0000000000..b2e8d0cd76
--- /dev/null
+++ b/support/dktools/man/man1/wxpqdic.1
@@ -0,0 +1,154 @@
+'\" t
+.\" Title: wxpqdic
+.\" Author: [see the "AUTHORS" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2016
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "WXPQDIC" "1" "09/03/2016" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+wxpqdic \- Client to query printqd for print quota information
+.SH "SYNOPSIS"
+.sp
+\fBwxpqdic\fR \fB\-h\fR \fIhost\fR \fB\-p\fR \fIport\fR \fB\-l\fR \fIport\fR \fB\-q\fR \fIname\fR \fB\-u\fR \fIuser\fR \fB\-i\fR \fInumber\fR \-a
+.SH "DESCRIPTION"
+.sp
+The program retrieves print quota information from a printqd daemon and shows them in a GUI\&.
+.sp
+On success the program shows the following information:
+.PP
+\fBLimit\fR
+.RS 4
+The limit for the user on the specified queue\&.
+.RE
+.PP
+\fBUsed\fR
+.RS 4
+Number of pages printed within the limit\&. Increased towards the limit while printing\&.
+.RE
+.PP
+\fBPersonal print account\fR
+.RS 4
+Number of pages available in the additional personal print account, if any\&. Decreased towards 0 while printing\&.
+.RE
+.PP
+\fBPrinting allowed\fR
+.RS 4
+Summary: Is the user allowed to print\&.
+.RE
+.sp
+If information retrieval fails, the program shows an error message in red color in the status line on the bottom\&.
+.SH "OPTIONS"
+.PP
+\fB\-h\fR \fIhost\fR
+.RS 4
+IP address or name of host running the printqd daemon\&. Required, no default\&.
+.RE
+.PP
+\fB\-p\fR \fIport\fR
+.RS 4
+UDP port number the printqd wait for requests on the remote host\&. Optional, default: 9100\&.
+.RE
+.PP
+\fB\-l\fR \fIport\fR
+.RS 4
+Local port number to use\&. Optional, default: 9100\&.
+.RE
+.PP
+\fB\-q\fR \fIname\fR
+.RS 4
+Queue name the user wants to print to\&. Required, no default\&.
+.RE
+.PP
+\fB\-u\fR \fIname\fR
+.RS 4
+User name to query information for\&. Optional, default: user running the program\&.
+.RE
+.PP
+\fB\-i\fR \fInumber\fR
+.RS 4
+Refresh interval in seconds\&. Optional, default: 30, minimum: 5\&.
+.RE
+.PP
+\fB\-a\fR
+.RS 4
+Printqd host uses ASCII encoding, not UTF\-8\&. Optional\&.
+.RE
+.SH "EXIT STATUS"
+.sp
+The program returns exit status code 0 on success, all other status codes indicate an error\&.
+.SH "NOTES"
+.sp
+This program uses DK libraries version 4\&.
+.SH "AUTHORS"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2011\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man5/dkct-wxgui.5 b/support/dktools/man/man5/dkct-wxgui.5
new file mode 100644
index 0000000000..0012410cd3
--- /dev/null
+++ b/support/dktools/man/man5/dkct-wxgui.5
@@ -0,0 +1,1510 @@
+'\" t
+.\" Title: dkct-wxgui
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 03/28/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "DKCT\-WXGUI" "5" "03/28/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dkct-wxgui \- Dirk Krause\*(Aqs C tool, *\&.wxc file syntax
+.SH "DESCRIPTION"
+.sp
+The \fB%% wx\-gui\fR section in a *\&.wxc file describes the layout of a main window or dialog box in an ini\-file style\&. Parts of the class definition and the constructor code are generated automatically from this section\&.
+.SH "SYNTAX"
+.sp
+A *\&.wxc file contains the following sections:
+.PP
+\fB%% options\fR
+.RS 4
+General setup for the module\&.
+.RE
+.PP
+\fB%% wx\-gui\fR
+.RS 4
+GUI description\&.
+.RE
+.PP
+\fB%% header start\fR
+.RS 4
+Header file code to be placed before the class definition\&.
+.RE
+.PP
+\fB%% class start\fR
+.RS 4
+Header file code to be placed in the class definition before the automatically created variables\&.
+.RE
+.PP
+\fB%% class end\fR
+.RS 4
+Header file code to be placed in the class definition after the automatically created variables\&.
+.RE
+.PP
+\fB%% header end\fR
+.RS 4
+Header file code to be placed after the class definition\&.
+.RE
+.PP
+\fB%% module start\fR
+.RS 4
+Source file code to be placed before the class constructor\&.
+.RE
+.PP
+\fB%% constructor start\fR
+.RS 4
+Start of class constructori, placed before automatically generated code for GUI setup\&.
+.RE
+.PP
+\fB%% constructor end\fR
+.RS 4
+End of class constructor, placed after automatically generated code for GUI setup\&.
+.RE
+.PP
+\fB%% module end\fR
+.RS 4
+Source file code to be placed after the class constructor\&.
+.RE
+.sp
+The options section is used for general setup as described in dkct(5)\&.
+.sp
+Code from header start, class start, class end and header end sections is copied into the *\&.h output file, code from module start, constructor start, constructor end and module end sections is copied to the *\&.cpp output file\&. These sections may contain special instructions as described for the %%module section of *\&.ctr, *\&.cpt and *\&.mtr files in dkct(5)\&.
+.SH "THE WX-GUI SECTION"
+.SS "General syntax"
+.sp
+The section is a list of paragraphs\&. Each paragraph describes either the top window or one of the GUI components\&.
+.sp
+Each paragraph \- except the first one \- is introduced by a
+.sp
+[\fItype\fR \fIname\fR]
+.sp
+line which will result in a
+.sp
+type *name;
+.sp
+member variable of the class to create\&.
+.sp
+The first paragraph without a header line describes the top level window\&.
+.sp
+The remaining lines in a paragraph are \fIkey\fR=\fIvalue\fR lines to set the attributes of the component\&.
+.SS "Key=value lines to set attributes"
+.PP
+\fBbitmap =\fR \fIwxBitmap\fR
+.RS 4
+Bitmap to show (for wxStaticBitmap and wxBitmapButton)\&.
+.RE
+.PP
+\fBbitmap button style =\fR [\fBauto\-draw\fR] [\fBtop\fR] [\fBleft\fR] [\fBright\fR] [\fBbottom\fR]
+.RS 4
+Optional style information for a wxBitmapButton, a space separated keyword list:
+.PP
+\fBauto\-draw\fR
+.RS 4
+Add 3D border, use main bitmap only\&.
+.RE
+.PP
+\fBleft\fR | \fBright\fR
+.RS 4
+Modify horizontal alignment (default: centered)\&.
+.RE
+.PP
+\fBtop\fR | \fBbottom\fR
+.RS 4
+Modify vertical alignment (default: centered)\&.
+.RE
+.RE
+.PP
+\fBbitmap disabled =\fR \fIwxBitmap:bitmap\fR
+.RS 4
+Bitmap to show on a disabled wxBitmapButton, optional\&.
+.RE
+.PP
+\fBbitmap focus =\fR \fIwxBitmap:bitmap\fR
+.RS 4
+Bitmap to show when a wxBitmapButton has focus, optional\&.
+.RE
+.PP
+\fBbitmap hover =\fR \fIwxBitmap:bitmap\fR
+.RS 4
+Bitmap to show when the mouse is over an enabled wxBitmapButton, optional\&.
+.RE
+.PP
+\fBbitmap selected =\fR \fIwxBitmap:bitmap\fR
+.RS 4
+Bitmap to show when wxBitmapButton is selected, optional\&.
+.RE
+.PP
+\fBborder =\fR \fIint:border\fR [\fBall\fR | [\fBtop\fR] [\fBleft\fR] [\fBright\fR] [\fBbottom\fR]]
+.RS 4
+Additional border around objects (number of pixels)\&. The border can be applied to all sides of the object (default) or to specified sides\&.
+.RE
+.PP
+\fBbutton style =\fR [\fBfit\fR] [\fBno\-border\fR] [\fBtop\fR] [\fBleft\fR] [\fBright\fR] [\fBbottom\fR]
+.RS 4
+Style for wxButton objects:
+.PP
+\fBfit\fR
+.RS 4
+Use just the space needed, not the default size\&.
+.RE
+.PP
+\fBno\-border\fR
+.RS 4
+Do not draw the usual button border\&.
+.RE
+.PP
+\fBtop\fR \fBbottom\fR \fBleft\fR \fBright\fR
+.RS 4
+Modify label alignment within the button\&. Default: Centered\&.
+.RE
+.RE
+.PP
+\fBcell data =\fR \fIint:row\fR \fIint:column\fR \fIwxString:text\fR
+.RS 4
+Data for one grid cell\&. Allowed multiple times\&.
+.RE
+.PP
+\fBchoices =\fR \fIint:size\fR \fIconst\-wxString[]:texts\fR
+.RS 4
+Choice texts for wxChoice, wxComboBox, wxListBox and wxCheckListBox\&.
+.RE
+.PP
+\fBchoices =\fR \fIwxArrayString:texts\fR
+.RS 4
+Choice texts for wxChoice, wxComboBox, wxListBox and wxCheckListBox\&. Alternative form\&.
+.RE
+.PP
+\fBcolumn head =\fR \fIwxString:text\fR
+.RS 4
+Column head for a wxGrid\&. May be used multiple times for all column heads\&.
+.RE
+.PP
+\fBcolumns =\fR \fIint:columns\fR
+.RS 4
+Number of columns in a wxRadioBox or wxGrid\&. For a wxRadioBox either the maximum number of rows or columns must be specified\&. For a wxGrid either a table object or both the numbers of rows and columns must be specified\&.
+.RE
+.PP
+\fBcomplete constructor specified =\fR \fIboolean:complete\fR
+.RS 4
+Flag: The constructor attribute contains all constructor arguments\&. If set to false, the parent window and the window ID (default: wxID_ANY) are inserted before the other arguments\&.
+.RE
+.PP
+\fBconstructor =\fR \fI*:argument\fR [, \&...]
+.RS 4
+List of arguments passed to the constructor\&. NOTE: The parent wxWindow and the window ID are inserted at start of the list unless the "complete constructor specified" attribute (see above) is set\&.
+.RE
+.PP
+\fBcontents =\fR \fIobject:obj\fR \fIint:row\fR \fIint:column\fR \fIint:height\fR \fIint:width\fR [[\fBtop\fR] | [\fBcentered\-y\fR] | [\fBbottom\fR]] [[\fBleft\fR] | [\fBcentered\-x\fR] | [\fBright\fR]]
+.RS 4
+Contents to add to a wxGridBagSizer\&. The alignment keywords control the alignment of the object within the available space\&. Use "text style" to set up the alignment of a text label within the object\&.
+.RE
+.PP
+\fBcontents =\fR \fIobject:obj\fR [[\fBtop\fR] | [\fBcentered\-y\fR] | [\fBbottom\fR]] [[\fBleft\fR] | [\fBcentered\-x\fR] | [\fBright\fR]]
+.RS 4
+Contents to add to a other sizers (not a wxGridBagSizer)\&. The alignment keywords control the alignment of the object within the available space\&. Use "text style" to set up the alignment of a text label within the object\&.
+.RE
+.PP
+\fBdirection =\fR \fBhorizontal\fR | \fBvertical\fR
+.RS 4
+Direction of wxBoxSizer, wxGauge or wxSlider
+.RE
+.PP
+\fBexpand =\fR \fIboolean:expand\fR
+.RS 4
+Flag: Object should grow when container grows\&.
+.RE
+.PP
+\fBgauge style =\fR \fBsmooth\fR
+.RS 4
+Flag: Gauge increases pixel by pixel\&.
+.RE
+.PP
+\fBgrid =\fR \fIint:y\-gap\fR \fIint:x\-gap\fR
+.RS 4
+Grid settings for a wxGridBagSizer\&.
+.RE
+.PP
+\fBgrid =\fR \fIint:rows\fR \fIint:columns\fR \fIint:y\-gap\fR \fIint:x\-gap\fR
+.RS 4
+Grid settings for a wxGridBagSizer (more detailed setup)\&.
+.RE
+.PP
+\fBgrid style =\fR [\fBautosize\-data\fR] [[\fBautosize\-labels\fR] | [\fBautosize\-labels\-rows\fR] | [\fBautosize\-labels\-columns\fR]]
+.RS 4
+Style settings for a wxGrid:
+.PP
+\fBautosize\-data\fR
+.RS 4
+Automatically size data cells\&.
+.RE
+.PP
+\fBautosize\-labels\fR
+.RS 4
+Automatically size row and column labels\&.
+.RE
+.PP
+\fBautosize\-labels\-rows\fR
+.RS 4
+Automatically size row labels\&.
+.RE
+.PP
+\fBautosize\-labels\-columns\fR
+.RS 4
+Automatically size column labels\&.
+.RE
+.RE
+.PP
+\fBgrow =\fR \fIboolean:grow\fR
+.RS 4
+Flag: Object should grow when container grows (alias for "expand")\&.
+.RE
+.PP
+\fBgrowable column =\fR \fIint:index\fR
+.RS 4
+Insert a growable column before the column specified by the 0\-based
+\fIindex\fR
+number in a wxGridBagSizer\&. Allowed multiple times, you should start with the largest index\&.
+.RE
+.PP
+\fBgrowable row =\fR \fIint:index\fR
+.RS 4
+Insert a growable row before the row specified by the 0\-based
+\fIindex\fR
+number in a wxGridBagSizer\&. Allowed multiple times, you should start with the largest index\&.
+.RE
+.PP
+\fBicon = \fR \fIwxIcon:icon\fR
+.RS 4
+Icon for top level windows\&.
+.RE
+.PP
+\fBid = \fR \fIint:id\fR
+.RS 4
+Window ID for object\&.
+.RE
+.PP
+\fBkeys = \fR \fIboolean:keyboard\fR
+.RS 4
+Flag: Keyboard can be used (for wxSpinControl and wxSpinButton)\&.
+.RE
+.PP
+\fBmenu bar =\fR \fIwxMenuBar:menubar\fR
+.RS 4
+Menu bar object for top level window, optional\&.
+.RE
+.PP
+\fBmenu item style =\fR \fBnormal\fR | \fBcheck\fR | \fBradio\fR | \fBseparator\fR
+.RS 4
+Optional style for wxMenuItem\&.
+.RE
+.PP
+\fBminimum pane size =\fR \fIint:size\fR
+.RS 4
+Minitmum size for pane in wxSplitter window, optional\&.
+.RE
+.PP
+\fBminimum size =\fR \fIint:width\fR \fIint:height\fR
+.RS 4
+Minimum object size\&.
+.RE
+.PP
+\fBnotebook style =\fR [\fBfixed\-width\fR] [\fBmultiline\fR] [\fBno\-theme\fR] [\fBflat\fR] [\fBtop\fR | \fBbottom\fR] [\fBleft\fR | \fBright\fR]
+.RS 4
+Style for wxNoteBook, optional:
+.PP
+\fBfixed\-width\fR
+.RS 4
+All buttons have the same width (Windows only)\&.
+.RE
+.PP
+\fBmultiline\fR
+.RS 4
+Multiple button lines allowed (Windows only)\&.
+.RE
+.PP
+\fBno\-theme\fR
+.RS 4
+Solid background instead of gradient (Windows only)\&.
+.RE
+.PP
+\fBflat\fR
+.RS 4
+Tabs in flat style (Windows CE only)\&.
+.RE
+.PP
+\fBtop\fR | \fBbottom\fR
+.RS 4
+Vertical position\&.
+.RE
+.PP
+\fBleft\fR | \fBright\fR
+.RS 4
+Horizontal position\&.
+.RE
+.RE
+.PP
+\fBproportion =\fR \fIint:factor\fR
+.RS 4
+Proportion for growing the element when the container grows\&.
+.RE
+.PP
+\fBrange =\fR \fIint:min\fR \fIint:max\fR
+.RS 4
+Range for wxSpinButton, wxSpinControl, wxSlider\&.
+.RE
+.PP
+\fBrange =\fR \fIint:max\fR
+.RS 4
+Range for gauge, minimum is 0\&.
+.RE
+.PP
+\fBrow head =\fR \fIwxString:text\fR
+.RS 4
+Row head specification for a wxGrid row\&. Allowed multiple times to cover all rows of the grid\&.
+.RE
+.PP
+\fBrows =\fR \fIint:rows\fR
+.RS 4
+Maximum number of rows in a wxRadioBox or wxGrid\&. For a wxRadioBox either the maximum number of rows or columns must be specified\&. For a wxGrid either a table object or both the numbers of rows and columns must be specified\&.
+.RE
+.PP
+\fBsash =\fR \fIint:size\fR
+.RS 4
+Size of wxSplitterWindow children\&. Positive values are the size of the first (upper or left) child\&. Negative values specify the size of the second (lower or right) child\&. The default 0 assigns equal size to both children\&.
+.RE
+.PP
+\fBselection =\fR \fBsingle\fR | \fBmultiple\fR | \fBextended\fR
+.RS 4
+Selection style for wxListBox and wxCheckListBox:
+.PP
+\fBsingle\fR
+.RS 4
+Select one item\&.
+.RE
+.PP
+\fBmultiple\fR
+.RS 4
+Select multiple items\&.
+.RE
+.PP
+\fBextended\fR
+.RS 4
+Select multiple items, use shift key and mouse or special keys\&.
+.RE
+.RE
+.PP
+\fBsize =\fR \fIint:width\fR \fIint:height\fR
+.RS 4
+Default size for an object\&.
+.RE
+.PP
+\fBslider style =\fR [\fBticks\fR] [\fBlabels\fR] [\fBrange\fR] [\fBinverse\fR] [\fBtop\fR | \fBbottom\fR] [\fBleft\fR | \fBright\fR]
+.RS 4
+Style for wxSlider object:
+.PP
+\fBticks\fR
+.RS 4
+Display tick marks\&.
+.RE
+.PP
+\fBlabels\fR
+.RS 4
+Show minimum, maximum and current value\&.
+.RE
+.PP
+\fBrange\fR
+.RS 4
+Allow selection of a range (Windows only)\&.
+.RE
+.PP
+\fBinverse\fR
+.RS 4
+Inverse minimum and maximum endpoint, incompatible with "range"\&.
+.RE
+.PP
+\fBtop\fR | \fBbottom\fR
+.RS 4
+Vertical alignment\&.
+.RE
+.PP
+\fBleft\fR | \fBright\fR
+.RS 4
+Horizontal alignment\&.
+.RE
+.RE
+.PP
+\fBsplitter window style =\fR [\fB3d\fR | \fB3d\-sash\fR | \fB3d\-border\fR] [\fBborder\fR | \fBno\-border\fR] [\fBno\-xp\-theme\fR] [\fBpermit\-unsplit\fR] [\fBlive\-update\fR]
+.RS 4
+Style for wxSplitterWindow:
+.PP
+\fB3d\fR
+.RS 4
+3D effect for border and sash\&.
+.RE
+.PP
+\fB3d\-sash\fR
+.RS 4
+3D effect for sash\&.
+.RE
+.PP
+\fB3d\-border\fR
+.RS 4
+3D effect for border\&.
+.RE
+.PP
+\fBborder\fR
+.RS 4
+Standard border\&.
+.RE
+.PP
+\fBno\-border\fR
+.RS 4
+No border\&.
+.RE
+.PP
+\fBno\-xp\-theme\fR
+.RS 4
+Do not use a Windows XP theme\&.
+.RE
+.PP
+\fBpermit\-unsplit\fR
+.RS 4
+Permit to unsplit the window\&.
+.RE
+.PP
+\fBlive\-update\fR
+.RS 4
+Update window and children immediately when dragging sash\&.
+.RE
+.RE
+.PP
+\fBstart\-group =\fR \fIboolean:flag\fR
+.RS 4
+Flag: the wxRadioButton is the start of a new radio button group\&. Default: no\&.
+.RE
+.PP
+\fBstates =\fR \fIint:number\fR [\fBchecked\fR | \fBunchecked\fR | \fBundetermined\fR]
+.RS 4
+Number of states (2 or 3) and optionally initial state for a wxCheckBox:
+.PP
+\fBchecked\fR
+.RS 4
+Option activated (turned on)\&.
+.RE
+.PP
+\fBunchecked\fR
+.RS 4
+Option deactivated (turned off)\&.
+.RE
+.PP
+\fBundetermined\fR
+.RS 4
+Option disabled (only for 3\-state checkboxes)\&.
+.RE
+.RE
+.PP
+\fBstatus bar =\fR \fIint:nparts\fR [\fIwxString:text\fR]
+.RS 4
+Number of parts in the status bar of a top level window and optionally the initial status text for the first part\&.
+.RE
+.PP
+\fBstatus text =\fR \fIwxString:text\fR
+.RS 4
+Optional status text for a top level window\&.
+.RE
+.PP
+\fBtable =\fR \fItable:object\fR [\fIboolean:isOwner\fR]
+.RS 4
+Table object for a wxGrid and optionally the flag whether the wxGrid is the owner of the table object\&.
+.RE
+.PP
+\fBtext =\fR \fIwxString:text\fR
+.RS 4
+Text for various elements, title text for top level windows\&.
+.RE
+.PP
+\fBtext style =\fR [\fBreadonly\fR] [\fBenter\fR] [\fBtab\fR] [\fBmultiline\fR] [\fBpassword\fR] [\fBrich\fR | \fBrich2\fR] [\fBurl\fR] [\fBselection\fR] [\fBleft\fR | \fBcentered\fR | \fBright\fR] [\fBno\-wrap\fR | \fBchar\-wrap\fR | \fBword\-wrap\fR | \fBbest\-wrap\fR] [\fBcapitalize\fR] [\fBno\-autoresize\fR]
+.RS 4
+Style for wxTextCtrl, wxStaticText or wxGrid object:
+.PP
+\fBreadonly\fR
+.RS 4
+Text can not be edited\&.
+.RE
+.PP
+\fBenter\fR
+.RS 4
+ENTER key adds line breaks (normally used for navigation), wxTextCtrl only\&.
+.RE
+.PP
+\fBtab\fR
+.RS 4
+Allow entering tabulator keys (normally used for navigation), wxTex tCtrl only\&.
+.RE
+.PP
+\fBmultiline\fR
+.RS 4
+Multi\-line wxTextCtrl\&.
+.RE
+.PP
+\fBpassword\fR
+.RS 4
+Input is hidden\&.
+.RE
+.PP
+\fBrich\fR
+.RS 4
+Use rich text control for wxTextCtrl on Windows\&.
+.RE
+.PP
+\fBrich2\fR
+.RS 4
+User newer version of rich text control for wxTextCtrl on Windows\&.
+.RE
+.PP
+\fBurl\fR
+.RS 4
+Highlight URLs in wxTextCtrl when applicable\&.
+.RE
+.PP
+\fBselection\fR
+.RS 4
+Show selection even if text control does not have focus\&.
+.RE
+.PP
+\fBleft\fR | \fBcentered\fR | \fBright\fR
+.RS 4
+Horizontal alignment\&.
+.RE
+.PP
+\fBno\-wrap\fR
+.RS 4
+Do not wrap long lines, show scrollbar instead\&.
+.RE
+.PP
+\fBchar\-wrap\fR
+.RS 4
+Wrap long lines on any position in wxTextCtrl\&.
+.RE
+.PP
+\fBword\-wrap\fR
+.RS 4
+Wrap long lines at word boundaries in wxTextCtrl\&.
+.RE
+.PP
+\fBbest\-wrap\fR
+.RS 4
+Find best position for wrapping in wxTextCtrl\&.
+.RE
+.PP
+\fBcapitalize\fR
+.RS 4
+Capitalize first letter, only wxTextCtrl on PocketPC and Smartphone\&.
+.RE
+.PP
+\fBno\-autoresize\fR
+.RS 4
+Do not automatically resize wxStaticText object\&.
+.RE
+.RE
+.PP
+\fBtip =\fR \fIwxString:text\fR
+.RS 4
+Tool tip text\&.
+.RE
+.PP
+\fBtool bar =\fR \fIwxToolBar:object\fR
+.RS 4
+Toolbar object for a top level window\&.
+.RE
+.PP
+\fBtoolbar button style =\fR \fBnormal\fR | \fBcheck\fR | \fBradio\fR | \fBseparator\fR
+.RS 4
+Optional style for toolbar button:
+.PP
+\fBnormal\fR
+.RS 4
+Normal button\&.
+.RE
+.PP
+\fBcheck\fR
+.RS 4
+Checkbox\&.
+.RE
+.PP
+\fBradio\fR
+.RS 4
+Radio button\&.
+.RE
+.PP
+\fBseparator\fR
+.RS 4
+Separator\&.
+.RE
+.RE
+.PP
+\fBtoolbar style =\fR [\fBflat\fR] [\fBdockable\fR] [\fBtext\fR] [\fBno\-icons\fR] [\fBno\-divider\fR] [\fBhorizontal\-layout\fR] [\fBno\-tooltips\fR] [\fBright\fR | \fBbottom\fR]
+.RS 4
+Optional style for wxToolBar:
+.PP
+\fBflat\fR
+.RS 4
+Flat look for toolbar (Windows and GTK)\&.
+.RE
+.PP
+\fBdockable\fR
+.RS 4
+Toolbar is floatable and dockable (GTK only)\&.
+.RE
+.PP
+\fBtext\fR
+.RS 4
+Show button text (only icons shown by default)\&.
+.RE
+.PP
+\fBno\-icons\fR
+.RS 4
+Do not show icons\&.
+.RE
+.PP
+\fBno\-divider\fR
+.RS 4
+No divider (border) around toolbar\&.
+.RE
+.PP
+\fBhorizontal\-layout\fR
+.RS 4
+Texts beside image (in conjunction with
+\fBtext\fR)\&.
+.RE
+.PP
+\fBno\-tooltips\fR
+.RS 4
+Do not show tooltips\&.
+.RE
+.PP
+\fBright\fR | \fBbottom\fR
+.RS 4
+Choose border for toolbar placement\&.
+.RE
+.RE
+.PP
+\fBtooltip flag =\fR \fIboolean:tooltips\fR
+.RS 4
+Flag: Show tooltips\&.
+.RE
+.PP
+\fBtype =\fR \fBdialog\fR | \fBframe\fR
+.RS 4
+Top level window type\&.
+.RE
+.PP
+\fBvalidator =\fR \fIvalidator:object\fR
+.RS 4
+Validator object for control\&.
+.RE
+.PP
+\fBvalue =\fR \fIint:value\fR
+.RS 4
+Initial value for wxSpinButton, wxSpinControl, wxSlider and wxGauge\&.
+.RE
+.PP
+\fBwrap =\fR \fIboolean:wrap\fR
+.RS 4
+Flag: Allow wxSpinButton and wxSpinControl to wrap\&.
+.RE
+.SS "Required, recommended and optional attributes"
+.PP
+\fBwxFrame\fR
+.RS 4
+.PP
+Required
+.RS 4
+type=frame, contents
+.RE
+.PP
+Recommended
+.RS 4
+icon, menu bar, text, tool bar, status bar, status text
+.RE
+.PP
+Optional
+.RS 4
+id, tooltip flag, size
+.RE
+.RE
+.PP
+\fBwxDialog\fR
+.RS 4
+.PP
+Required
+.RS 4
+type=dialog, contents
+.RE
+.PP
+Recommended
+.RS 4
+text
+.RE
+.PP
+Optional
+.RS 4
+id, icon, status bar, size, tooltip flag
+.RE
+.RE
+.PP
+\fBwxMDIParentFrame\fR
+.RS 4
+.PP
+Required
+.RS 4
+type=frame, contents
+.RE
+.PP
+Recommended
+.RS 4
+menu bar, tool bar, status bar, text
+.RE
+.PP
+Optional
+.RS 4
+icon, id, size, tooltip flag
+.RE
+.RE
+.PP
+\fBwxMDIChildFrame\fR
+.RS 4
+.PP
+Required
+.RS 4
+type=frame, contents
+.RE
+.PP
+Recommended
+.RS 4
+text
+.RE
+.PP
+Optional
+.RS 4
+id, size, tooltip flag
+.RE
+.RE
+.PP
+\fBwxPopupWindow\fR
+.RS 4
+.PP
+Required
+.RS 4
+contents
+.RE
+.PP
+Recommended
+.RS 4
+text
+.RE
+.PP
+Optional
+.RS 4
+id, size, tooltip flag
+.RE
+.RE
+.PP
+\fBwxBoxSizer\fR
+.RS 4
+.PP
+Required
+.RS 4
+direction, contents
+.RE
+.PP
+Optional
+.RS 4
+grow, proportion, border
+.RE
+.RE
+.PP
+\fBwxFlexGridSizer\fR
+.RS 4
+.PP
+Required
+.RS 4
+grid, contents
+.RE
+.PP
+Optional
+.RS 4
+grow, proportion, border
+.RE
+.RE
+.PP
+\fBwxGridBagSizer\fR
+.RS 4
+.PP
+Required
+.RS 4
+contents
+.RE
+.PP
+Optional
+.RS 4
+grow, proportion, grid, border, growable column, growable row
+.RE
+.RE
+.PP
+\fBwxGridSizer\fR
+.RS 4
+.PP
+Required
+.RS 4
+grid, contents
+.RE
+.PP
+Optional
+.RS 4
+grow, proportion, border
+.RE
+.RE
+.PP
+\fBwxStaticBoxSizer\fR
+.RS 4
+.PP
+Required
+.RS 4
+direction, contents
+.RE
+.PP
+Optional
+.RS 4
+grow, proportion, border
+.RE
+.RE
+.PP
+\fBwxStdDialogButtonSizer\fR
+.RS 4
+.PP
+Required
+.RS 4
+contents
+.RE
+.PP
+Optional
+.RS 4
+grow, proportion, border
+.RE
+.RE
+.PP
+\fBwxPanel\fR
+.RS 4
+.PP
+Required
+.RS 4
+contents
+.RE
+.PP
+Optional
+.RS 4
+grow, proportion, border, id, size
+.RE
+.RE
+.PP
+\fBwxNotebook\fR
+.RS 4
+.PP
+Required
+.RS 4
+contents
+.RE
+.PP
+Optional
+.RS 4
+notebook style, grow, proportion, border, id, size
+.RE
+.RE
+.PP
+\fBwxScrolledWindow\fR
+.RS 4
+.PP
+Required
+.RS 4
+contents
+.RE
+.PP
+Recommended
+.RS 4
+direction, size
+.RE
+.PP
+Optional
+.RS 4
+grow, proportion, border, id
+.RE
+.RE
+.PP
+\fBwxSplitterWindow\fR
+.RS 4
+.PP
+Required
+.RS 4
+contents
+.RE
+.PP
+Optional
+.RS 4
+splitter window style, grow, proportion, sash, border, minimum pane size, id, size
+.RE
+.RE
+.PP
+\fBwxButton\fR
+.RS 4
+.PP
+Required
+.RS 4
+text, id
+.RE
+.PP
+Recommended
+.RS 4
+tip
+.RE
+.PP
+Optional
+.RS 4
+button style, validator, grow, proportion, border, size, tooltip flag
+.RE
+.RE
+.PP
+\fBwxBitmapButton\fR
+.RS 4
+.PP
+Required
+.RS 4
+text, id, bitmap
+.RE
+.PP
+Recommended
+.RS 4
+tip
+.RE
+.PP
+Optional
+.RS 4
+bitmap selected, bitmap disabled, bitmap focus, bitmap hover, bitmap button style, validator, grow, proportion, border, size, tooltip flag
+.RE
+.RE
+.PP
+\fBwxChoice\fR
+.RS 4
+.PP
+Required
+.RS 4
+choices
+.RE
+.PP
+Recommended
+.RS 4
+tip
+.RE
+.PP
+Optional
+.RS 4
+id, validator, grow, proportion, border, size, tooltip flag
+.RE
+.RE
+.PP
+\fBwxComboBox\fR
+.RS 4
+.PP
+Required
+.RS 4
+choices
+.RE
+.PP
+Recommended
+.RS 4
+tip
+.RE
+.PP
+Optional
+.RS 4
+id, validator, grow, proportion, border, size, tooltip flag
+.RE
+.RE
+.PP
+\fBwxCheckBox\fR
+.RS 4
+.PP
+Required
+.RS 4
+text
+.RE
+.PP
+Recommended
+.RS 4
+tip
+.RE
+.PP
+Optional
+.RS 4
+states, id, validator, grow, proportion, border, size, tooltip flag
+.RE
+.RE
+.PP
+\fBwxListBox\fR
+.RS 4
+.PP
+Required
+.RS 4
+choices
+.RE
+.PP
+Recommended
+.RS 4
+tip, size
+.RE
+.PP
+Optional
+.RS 4
+id, range, validator, grow, proportion, border, tooltip flag
+.RE
+.RE
+.PP
+\fBwxCheckListBox\fR
+.RS 4
+.PP
+Required
+.RS 4
+choices
+.RE
+.PP
+Recommended
+.RS 4
+tip, size
+.RE
+.PP
+Optional
+.RS 4
+id, range, validator, grow, proportion, border, tooltip flag
+.RE
+.RE
+.PP
+\fBwxRadioBox\fR
+.RS 4
+.PP
+Required
+.RS 4
+columns or rows
+.RE
+.PP
+Recommended
+.RS 4
+tip
+.RE
+.PP
+Optional
+.RS 4
+validator, grow, proportion, border, id, size
+.RE
+.RE
+.PP
+\fBwxRadioButton\fR
+.RS 4
+.PP
+Required
+.RS 4
+text, id
+.RE
+.PP
+Recommended
+.RS 4
+start group, tip
+.RE
+.PP
+Optional
+.RS 4
+validator, grow, proportion, border, size, tooltip flag
+.RE
+.RE
+.PP
+\fBwxScrollBar\fR
+.RS 4
+.PP
+Optional
+.RS 4
+id, validator, grow, proportion, border, size, tip
+.RE
+.RE
+.PP
+\fBwxSpinButton\fR
+.RS 4
+.PP
+Required
+.RS 4
+text, range, value,
+.RE
+.PP
+Recommended
+.RS 4
+direction, keys, tip
+.RE
+.PP
+Optional
+.RS 4
+wrap, id, validator, grow, proportion, border, size
+.RE
+.RE
+.PP
+\fBwxSpinCtrl\fR
+.RS 4
+.PP
+Required
+.RS 4
+text, range, value
+.RE
+.PP
+Recommended
+.RS 4
+direction, keys, tip
+.RE
+.PP
+Optional
+.RS 4
+wrap, id, validator, grow, proportion, border, size, tooltip flag
+.RE
+.RE
+.PP
+\fBwxSlider\fR
+.RS 4
+.PP
+Required
+.RS 4
+text, range, value
+.RE
+.PP
+Recommended
+.RS 4
+tip
+.RE
+.PP
+Optional
+.RS 4
+id, slider style, validator, grow, proportion, border, size, tooltip flag
+.RE
+.RE
+.PP
+\fBwxTextCtrl\fR
+.RS 4
+.PP
+Recommended
+.RS 4
+text, text style, tip, size
+.RE
+.PP
+Optional
+.RS 4
+id, validator, grow, proportion, border, tooltip flag
+.RE
+.RE
+.sp
+\fBwxGrid\fR Required::: table or rows and columns Optional::: row head, column head, cell data, grid style, text style
+.PP
+\fBwxToggleButton\fR
+.RS 4
+.PP
+Required
+.RS 4
+text
+.RE
+.PP
+Recommended
+.RS 4
+tip
+.RE
+.PP
+Optional
+.RS 4
+id, validator, grow, proportion, border, size, tooltip flag
+.RE
+.RE
+.PP
+\fBwxGauge\fR
+.RS 4
+.PP
+Required
+.RS 4
+range, value, direction, text
+.RE
+.PP
+Recommended
+.RS 4
+tip, id, gauge style
+.RE
+.PP
+Optional
+.RS 4
+validator, grow, proportion, border, size
+.RE
+.RE
+.PP
+\fBwxStaticText\fR
+.RS 4
+.PP
+Required
+.RS 4
+text
+.RE
+.PP
+Recommended
+.RS 4
+text style
+.RE
+.PP
+Optional
+.RS 4
+grow, proportion, border, id, size, tip
+.RE
+.RE
+.PP
+\fBwxStaticBitmap\fR
+.RS 4
+.PP
+Required
+.RS 4
+bitmap
+.RE
+.PP
+Optional
+.RS 4
+bitmap button style, grow, proportion, border, id, size, tip
+.RE
+.RE
+.PP
+\fBwxStaticLine\fR
+.RS 4
+.PP
+Required
+.RS 4
+direction
+.RE
+.PP
+Optional
+.RS 4
+grow, proportion, border, id, size, tip
+.RE
+.RE
+.PP
+\fBwxStaticBox\fR
+.RS 4
+.PP
+Optional
+.RS 4
+grow, proportion, border, id, size, tip
+.RE
+.RE
+.PP
+\fBwxMenuBar\fR
+.RS 4
+.PP
+Required
+.RS 4
+contents
+.RE
+.PP
+Optional
+.RS 4
+border, id, tip
+.RE
+.RE
+.PP
+\fBwxMenu\fR
+.RS 4
+.PP
+Required
+.RS 4
+text, contents
+.RE
+.PP
+Recommended
+.RS 4
+tip
+.RE
+.PP
+Optional
+.RS 4
+border, id
+.RE
+.RE
+.PP
+\fBwxMenuItem\fR
+.RS 4
+.PP
+Required
+.RS 4
+text, id
+.RE
+.PP
+Recommended
+.RS 4
+tip
+.RE
+.PP
+Optional
+.RS 4
+bitmap, menu item style, border
+.RE
+.RE
+.PP
+\fBwxToolBar\fR
+.RS 4
+.PP
+Required
+.RS 4
+contents
+.RE
+.PP
+Optional
+.RS 4
+tool bar style, border, id, tip
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+wxStatusBar**::
+.RE
+.RE
+.PP
+Optional
+.RS 4
+contents, border, id, tip
+.RE
+.RE
+.PP
+\fBwxToolBarToolBase\fR
+.RS 4
+.PP
+Required
+.RS 4
+id, bitmap
+.RE
+.PP
+Recommended
+.RS 4
+tip
+.RE
+.PP
+Optional
+.RS 4
+bitmap disabled, bitmap button style, toolbar button style, border
+.RE
+.RE
+.PP
+\fBany other class not listed above\fR
+.RS 4
+.PP
+Optional
+.RS 4
+id, text, size, minumum size, tip
+.RE
+.RE
+.SS "Pseudo objects"
+.PP
+\fB$space(\fR\fIwidth\fR\fB)\fR
+.RS 4
+Fixed width placeholder for space between elements, can be added to sizers\&. Does not grow if sizer grows\&.
+.RE
+.PP
+\fB$stretch(\fR\fIwidth\fR\fB)\fR
+.RS 4
+Variable width placeholder for space between elements, can be added to sizers\&. Grows when sizer grows\&.
+.RE
+.PP
+\fB$separator\fR
+.RS 4
+Separator between menu items\&.
+.RE
+.SH "AUTHOR"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2011\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+\fBdkct(1)\fR
+.RS 4
+The dkct program (Dirk Krause\(cqs C tool)\&.
+.RE
+.PP
+\fBdkct(5)\fR
+.RS 4
+Input file syntax for dkct (*\&.ctr, *\&.cpt and *\&.mtr files)\&.
+.RE
+.PP
+http://dktools\&.sourceforge\&.net/
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man5/dkct.5 b/support/dktools/man/man5/dkct.5
new file mode 100644
index 0000000000..2b9b363b39
--- /dev/null
+++ b/support/dktools/man/man5/dkct.5
@@ -0,0 +1,635 @@
+'\" t
+.\" Title: dkct
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 02/08/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "DKCT" "5" "02/08/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dkct \- Dirk Krause\*(Aqs C tool
+.SH "DESCRIPTION"
+.sp
+This file describes the syntax of *\&.ctr, *\&.cpt and *\&.mtr input files for dkct\&.
+.sp
+The syntax of *\&.wxc files is described in dkct\-wxgui(5)\&.
+.SH "SYNTAX"
+.sp
+The files contain multiple sections\&. Each section is opened by one of the following section headers:
+.PP
+\fB%% options\fR
+.RS 4
+General module setup, optional\&.
+.RE
+.PP
+\fB%% header\fR
+.RS 4
+Contents for the modules *\&.h file, optional\&.
+.RE
+.PP
+\fB%% module\fR
+.RS 4
+Contents for the modules *\&.c, *\&.cpp or *\&.m (Objective\-C) file, mandatory\&.
+.RE
+.PP
+\fB%% state machine\fR
+.RS 4
+Additional contents for header and source files to build state machines\&. Optional, allowed multiple times for multiple state machines\&.
+.RE
+.SS "Options section"
+.sp
+The options section contains the general setup, lines are \fIkey\fR=\fIvalue\fR pairs\&. Keys can consist of multiple words\&. The following lines can be used:
+.PP
+\fBcopyright owner =\fR \fIname\fR
+.RS 4
+The full name of the copyright owner\&.
+.RE
+.PP
+\fBcopyright year =\fR \fIyear(s)\fR
+.RS 4
+The years for the copyright\&.
+.RE
+.PP
+\fBlicense =\fR \fIname\fR
+.RS 4
+License type, i\&.e\&. "bsd", "gpl" or "lgpl"\&.
+.RE
+.SS "Header section"
+.sp
+The contents of the header section is transferred into the *\&.h file\&. A protection against multiple inclusions is added:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+#ifndef SHORTFILENAME_H_INCLUDED
+#define SHORTFILENAME_H_INCLUDED 1
+/* \&.\&.\&. header section contents \&.\&.\&. */
+#endif
+.fi
+.if n \{\
+.RE
+.\}
+.SS "Module section"
+.sp
+The module section contains the code for the *\&.c, *\&.cpp or *\&.m file\&. In addition to C/C++/Objective\-C code you can use the following special instructions for tracing and simplifications:
+.PP
+\fB$!trace\-include\fR
+.RS 4
+Is converted into a
+.RE
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+#include <dk3trace\&.h>
+#ifndef TRACE_DEBUG
+#define TRACE_DEBUG 1
+#endif
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+section when producing debug code, ignored otherwise\&. You should place this instruction on the file level after the last #include instruction\&.
+.PP
+\fB$!trace\-init\fR \fIfilename\fR
+.RS 4
+is converted into code opening the trace file and setting up tracing when producing debug code, ignored otherwise\&. You should place this instruction at the start of your main() function\&.
+.RE
+.PP
+\fB$!trace\-end\fR
+.RS 4
+is converted into code closing the trace file and finishing tracing when producing debug code, ignored otherwise\&. You should place this instruction at the end of your main() function or immediately before calls to exit()\&.
+.RE
+.PP
+\fB$? "\fR\fIformat\fR\fB"\fR [\fB,\fR \fIexpression\fR \&...]
+.RS 4
+is converted into code writing trace messages when producing debug code, ignored otherwise\&. This instruction results in a printf()/fprintf() call, so the format string follows the same rules as printf()/fprintf() format strings\&. Special placeholders "%!dc", "%!ds", "%!wc" and "%!ws" can be used for dkChar characters, dkChar strings, wxChar characters and wxChar strings\&. I recommend to use the following characters as first character in the format string:
+.TS
+tab(:);
+lt lt
+lt lt
+lt lt
+lt lt.
+T{
++
+T}:T{
+Entering a function
+T}
+T{
+\-
+T}:T{
+Returning from a function
+T}
+T{
+\&.
+T}:T{
+Normal conditions
+T}
+T{
+!
+T}:T{
+Error conditions
+T}
+.TE
+.sp 1
+.RE
+.PP
+\fB$\fR*
+.RS 4
+is used to build a box comment (one marker at the start, one at the end)\&.
+.RE
+.PP
+\fB$!trace\-command\fR \fIcode\fR
+.RS 4
+places the code in the output only when producing debug code\&. You can abbreviate this to "\fB$!!\fR\fIcode\fR"\&. NOTE: To protect larger code sections \- i\&.e\&. entire functions \- use the TRACE_DEBUG preprocessor constant\&. It is defined to 1 when producing debug code, undefined otherwise\&.
+.RE
+.PP
+\fB$!pipe\fR \fIcommand\fR
+.RS 4
+The specified command is executed by dkct, output from the command is written into the source code\&. You can abbreviate this to "\fB$!|\fR\fIcommand\fR"\&.
+.RE
+.PP
+\fB$!string\-table\fR \fIarguments\fR
+.RS 4
+produces a string array and optionally a string table file\&. The string table is finished by a
+\fB$!end\fR
+line\&. A raute character \*(Aq\*(Aq at start of line marks a comment line\&. To create a text line starting with a raute, write a backslash before the \*(Aq\*(Aq\&. The following arguments can be used, separated by comma:
+.PP
+\fBfile=\fR\fIfilename\fR
+.RS 4
+Output string table file name, optional\&.
+.RE
+.PP
+\fBprefix=\fR\fIprefix\fR
+.RS 4
+Prefix to write before each string, i\&.e\&. \*(AqL\*(Aq to have wide character string L"my text"\&. Optional\&.
+.RE
+.PP
+\fBmacro=\fR\fIname\fR
+.RS 4
+Macro to use for each string, i\&.e\&. "dkT" to have dkChar strings like dkT("my text")\&. Optional\&. Prefix and macro are mutually exclusive\&.
+.RE
+.RE
+.PP
+\fB$!text\fR \fIarguments\fR
+.RS 4
+produces a string array and optionally an output text file\&. For text lines started by a raute character you can choose whether to convert them to strings or to use them as preprocessor instructions\&. The following arguments can be used, separated by comma:
+.PP
+\fBfile=\fR\fIfilename\fR
+.RS 4
+Output text file name, optional\&.
+.RE
+.PP
+\fBprefix=\fR\fIprefix\fR
+.RS 4
+Prefix to write before each string, i\&.e\&. \*(AqL\*(Aq to have wide character string L"my text"\&. Optional\&.
+.RE
+.PP
+\fBmacro=\fR\fIname\fR
+.RS 4
+Macro to use for each string, i\&.e\&. "dkT" to have dkChar strings like dkT("my text")\&. Optional\&. Prefix and macro are mutually exclusive\&.
+.RE
+.RE
+.PP
+\fBpreprocessor\fR
+.RS 4
+Lines started by raute are preprocessor instructions\&. The default (without this argument) is to convert them to strings too\&.
+.RE
+.SS "State machine section"
+.sp
+A state machine consists of
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+a set of states,
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+a set of inputs,
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+a set of outputs and
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+a set of rules choosing the next state and an output value for current state and input\&.
+.RE
+.sp
+States, inputs and outputs are represented by int values\&.
+.sp
+The current state is kept in an int variable\&.
+.sp
+States, inputs, outputs and rules are defined in "[states]", "[inputs]", "[outputs]" and "[rules]" subsections\&. An additional "[options]" subsection is used for setup\&. Each non\-comment line in a "[states]", "[inputs]" or "[outputs]" subsection contains one name (valid identifier in the C programming language) and optionally a numeric value assigned to the name\&. If the value is omitted, dkct automatically assigns values\&.
+.sp
+The first state defined in the "[states]" subsection is the default state established by the \fIxxx\fR_reset() function\&.
+.sp
+Each rule consists of four items: current state, input, resulting next state and output\&.
+.sp
+The wildcard "\fB" can be used for current state and/or input to define wildcard rules or a general rule ("\fR" used for both current state and input)\&.
+.sp
+To resolve conflicts from wildcards the rules have different priorities:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+\fBExact\fR
+rules (no wildcards) have highest priority\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+\fBWildcard\fR
+rules (one wildcard, either current state or input) have medium priority\&. If a state/input combination matches multiple wildcard rules (but no exact rule), the
+\fBfirst\fR
+rule found is used\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The
+\fBgeneral rule\fR
+(wildcard used for both current state and input) has lowest priority\&. If no explicit general rule is written, an implicit rule is constructed using the first state defined in the states subsection and the first output defined in the outputs section\&.
+.RE
+.sp
+The options subsection consists of \fIkey\fR=\fIvalue\fR pairs, keys can consist of multiple words\&. The following lines can be used:
+.PP
+\fBname =\fR \fIidentifier\fR
+.RS 4
+Start text in generated function names, a setting "xyz" here results in function names "xyz_reset()" to reset the state machine and "xyz_step()" to process one input\&.
+.RE
+.PP
+\fBwrite header =\fR \fIboolean\fR
+.RS 4
+Enable/disable writing of a header file "xyz\&.h"\&.
+.RE
+.SH "EXAMPLE"
+.sp
+The examle program reads input line by line and inspects each line whether or not it is a valid identifier in the C programming language\&. Each input character is classified whether it is a character, digit, underscore or anything else\&. This information is passed to a state machine\&. Finally an end marker is passed to the state machine\&. If this step returns output code O_OK, the string was a valid C identifier\&.
+.PP
+\fBThe test-ident.ctr file, use -ldk4base when linking\fR.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011\-2015
+license = bsd
+
+
+
+%% header
+
+$*
+Function prototypes\&.
+This command will result in a comment box in the header file\&.
+$*
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Test whether a string is an identifier\&.
+ @param test String to check\&.
+ @return 1 on success (string is identifier), 0 on error\&.
+*/
+int test_identifier(char const *text);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+/* This program uses functions from the dk4str8\&.o module\&.
+ So you should use \-ldk4base when linking\&.
+*/
+
+#include <dk4conf\&.h>
+#include <dk4types\&.h>
+#include <stdio\&.h>
+#include <stdlib\&.h>
+#if DK3_HAVE_UNISTD_H
+#include <unistd\&.h>
+#endif
+#include <dk4str8\&.h>
+
+$!trace\-include
+
+/** Help text, never used, just for demonstration\&.
+*/
+static char const * const help_text1[] = {
+$!text preprocessor
+This help text is never shown, it is here just to demonstrate the
+use of the build\-in $!text function\&.
+#ifdef _WIN32
+We are on a Windows system\&.
+#else
+We are not on a Windows system\&.
+#endif
+$!end
+};
+
+/** Help text, never used, just for demonstration\&.
+*/
+static char const * const help_text2[] = {
+$!text
+This help text is never shown, it is here just to demonstrate the
+use of the build\-in $!text function\&.
+#Lines with raute are converted to text when the preprocessor
+option was not used\&.
+$!end
+};
+
+/** Help text, never used, just for demonstration\&.
+*/
+static dkChar const * const help_text3[] = {
+$!text macro=dkT
+This help text is never shown, it is here just to demonstrate the
+use of the macro functionality in the build\-in $!text function\&.
+$!end
+};
+
+/** Help text, never used, just for demonstration\&.
+*/
+static wchar_t const * const help_text4[] = {
+$!text prefix=L
+This help text is never shown, it is here just to demonstrate the
+use of the prefix functionality in the build\-in $!text function\&.
+$!end
+};
+
+/** Find start of text (first non\-whitespace)\&.
+ @param t String to test\&.
+ @return Pointer to start of text or NULL\&.
+*/
+static
+char *
+str_start(char *t)
+{
+ char *back = NULL;
+ char *ptr;
+ ptr = t;
+ while((*ptr) && (back == NULL)) {
+ if(*ptr != \*(Aq \*(Aq) {
+ if(*ptr != \*(Aq\et\*(Aq) {
+ back = ptr;
+ }
+ }
+ ptr++;
+ }
+ return back;
+}
+
+/** Remove trailing newline\&.
+ @param t String to modify\&.
+*/
+static
+void
+str_delnl(char *t)
+{
+ char *ptr;
+ ptr = t;
+ while(*ptr) {
+ if(*ptr == \*(Aq\er\*(Aq) *ptr = \*(Aq\e0\*(Aq;
+ if(*ptr == \*(Aq\en\*(Aq) *ptr = \*(Aq\e0\*(Aq;
+ ptr++;
+ }
+}
+
+int test_identifier(char const *text)
+{
+ int back = 0;
+ char const *ptr;
+ int state;
+ int i;
+ $? "+ test_identifier \e"%s\e"", TR_STR(text)
+ idtest_reset(&state);
+ ptr = text;
+ while(*ptr) { $? "\&. processing character %c", *ptr
+ if((*ptr >= \*(AqA\*(Aq) && (*ptr <= \*(AqZ\*(Aq)) {
+ i = I_CHAR;
+ } else {
+ if((*ptr >= \*(Aqa\*(Aq) && (*ptr <= \*(Aqz\*(Aq)) {
+ i = I_CHAR;
+ } else {
+ if((*ptr >= \*(Aq0\*(Aq) && (*ptr <= \*(Aq9\*(Aq)) {
+ i = I_DIGIT;
+ } else {
+ if(*ptr == \*(Aq_\*(Aq) {
+ i = I_UNDER;
+ } else {
+ i = I_ANY;
+ }
+ }
+ }
+ }
+ (void)idtest_step(&state, i);
+ ptr++;
+ }
+ if(idtest_step(&state, I_END) == O_OK) {
+ back = 1;
+ } $? "\- test_identifier %d", back
+ return back;
+}
+
+/** Main function\&.
+ @param argc Number of command line arguments\&.
+ @param argv Command line arguments array\&.
+*/
+int main(int argc, char *argv[])
+{
+ char buffer[1024];
+ char *p1;
+ int cc;
+
+ /* Debug output goes to test\-ident\&.deb in the current directory */
+ $!trace\-init test\-ident\&.deb
+ /* We are entering the main function */
+ $? "+ main"
+ do { $? "\&. start of loop"
+ cc = 0;
+ if(fgets(buffer, sizeof(buffer), stdin)) {
+ p1 = dk4str8_start(buffer, NULL);
+ if(p1) { $? "\&. text found \e"%s\e"", p1
+ cc = 1;
+ dk4str_delnl(p1);
+ printf("%s %d\en", p1, test_identifier(p1));
+ }
+ }
+ } while(cc);
+ /* We are about to leave the main function */
+ $? "\- main"
+ /* Close debug output file */
+ $!trace\-end
+ exit(0); return 0;
+}
+
+
+
+%% state machine
+
+[options]
+name = idtest
+write header = no
+
+[states]
+S_START # No character found yet\&.
+S_OK # Everything ok so far\&.
+S_ERROR # An error occured\&.
+
+[inputs]
+I_CHAR # Character\&.
+I_UNDER # Underscore\&.
+I_DIGIT # Digit\&.
+I_ANY # Any other input character\&.
+I_END # End of input\&.
+
+[outputs]
+O_ERROR # Error occured\&.
+O_OK # Everything ok so far\&.
+
+[rules]
+* * S_ERROR O_ERROR
+* I_END S_START O_ERROR
+S_START I_CHAR S_OK O_OK
+S_START I_UNDER S_OK O_OK
+S_OK I_CHAR S_OK O_OK
+S_OK I_UNDER S_OK O_OK
+S_OK I_DIGIT S_OK O_OK
+S_OK I_END S_START O_OK
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+.SH "AUTHOR"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2011\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+\fBdkct(1)\fR
+.RS 4
+The dkct program (Dirk Krause\(cqs C tool)\&.
+.RE
+.PP
+http://dktools\&.sourceforge\&.net/
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man5/htmlbook-project.5 b/support/dktools/man/man5/htmlbook-project.5
new file mode 100644
index 0000000000..0e1a379fbc
--- /dev/null
+++ b/support/dktools/man/man5/htmlbook-project.5
@@ -0,0 +1,319 @@
+'\" t
+.\" Title: htmlbook-project
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 01/03/2016
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "HTMLBOOK\-PROJECT" "5" "01/03/2016" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+htmlbook-project \- Project file for htmlbook\&.
+.SH "DESCRIPTION"
+.sp
+This text describes the htmlbook project file syntax\&.
+.SH "SYNTAX"
+.sp
+The project file consists of three sections:
+.PP
+\fB[options]\fR
+.RS 4
+General project setup\&.
+.RE
+.PP
+\fB[files]\fR
+.RS 4
+Additional files to copy into the destination directory\&.
+.RE
+.PP
+\fB[contents]\fR
+.RS 4
+Book structure and list of text files to use\&.
+.RE
+.sp
+Further sections \fB[options:\fR\fIname\fR\fB]\fR, \fB[files:\fR\fIname\fR\fB]\fR and \fB[contents:\fR\fIname\fR\fB]\fR are optional\&. These options are process if the name is activated by the \fB\-o\fR command line option\&.
+.sp
+Optional sections named "windows" are activated automatically on Windows systems, optional sections named "non\-windows" are activated automatically on non\-Windows systems\&.
+.SS "Options section"
+.sp
+The section contains "\fIkey\fR=\fIvalue\fR" lines\&. Keys may consist of multiple words\&.
+.PP
+\fBoutput script\fR
+.RS 4
+Script to re\-create the output directory and copy files into it\&. The script is produced by the htmlbook program\&.
+.RE
+.PP
+\fBoutput directory\fR
+.RS 4
+Name of output directory\&. This directory is removed completely and created again each time the output script (see above) is run\&.
+.RE
+.PP
+\fBtitle\fR
+.RS 4
+Document or collection title\&.
+.RE
+.PP
+\fBurl\fR
+.RS 4
+URL to access the document collection via web\&.
+.RE
+.PP
+\fBindex file\fR
+.RS 4
+Name of file containing text for start page\&.
+.RE
+.PP
+\fBhtml charset\fR
+.RS 4
+Character set for output HTML files ("us\-ascii", "ascii", or "utf\-8")\&.
+.RE
+.PP
+\fBtemplate\fR
+.RS 4
+Name of default template file ("web\&.hbt")\&.
+.RE
+.PP
+\fBstyle\fR
+.RS 4
+Name of default style file ("style\&.css")\&.
+.RE
+.PP
+\fBpage toc\fR
+.RS 4
+Flag: Create an intra\-page table of contents\&.
+.RE
+.PP
+\fBcreate toc\fR
+.RS 4
+Flag: Create table of contents\&.
+.RE
+.PP
+\fBcreate index\fR
+.RS 4
+Flag: Create keyword index\&.
+.RE
+.PP
+\fBsection numbers in index\fR
+.RS 4
+Flag: Write section numbers in index\&.
+.RE
+.PP
+\fBreplace ampersand\fR
+.RS 4
+Flag: Replace ampersand in texts (no)\&.
+.RE
+.PP
+\fBtidy\fR
+.RS 4
+Flag: Use tidy for inspection and correction of HTML output files\&.
+.RE
+.PP
+\fBln\fR
+.RS 4
+Flag: Use ln command in output script instead of cp to save disk space\&.
+.RE
+.PP
+\fBauthor\fR
+.RS 4
+Author name\&.
+.RE
+.PP
+\fBlocation\fR
+.RS 4
+Location of author\&.
+.RE
+.PP
+\fBwrite position\fR
+.RS 4
+Flag: Write position within the collection at start of page\&.
+.RE
+.PP
+\fBsection numbers in position\fR
+.RS 4
+Flag: Write section number in position\&.
+.RE
+.PP
+\fBshortcut icon\fR
+.RS 4
+URL to shortcut icon\&.
+.RE
+.PP
+\fBicon toc\fR
+.RS 4
+File name for "table of contents" icons in navigation bar\&.
+.RE
+.PP
+\fBicon previous\fR
+.RS 4
+File name for "go to previous page" icons in navigation bar\&.
+.RE
+.PP
+\fBicon next\fR
+.RS 4
+File name for "go to next page" icons in navigation bar\&.
+.RE
+.PP
+\fBicon index\fR
+.RS 4
+File name for "go to keyword index" icons in navigation bar\&.
+.RE
+.PP
+\fBimpressum link\fR
+.RS 4
+URL to impressum\&.
+.RE
+.PP
+\fBimpressum page\fR
+.RS 4
+Name of text file for impressum (you can use either impressum link or impressum page)\&.
+.RE
+.PP
+\fBchm\fR
+.RS 4
+Flag: Create HTML to produce a CHM file later\&.
+.RE
+.PP
+\fBchm language\fR
+.RS 4
+Language setting for CHM project ("0x409 English (USA)")\&.
+.RE
+.PP
+\fBjs file\fR
+.RS 4
+File name of JavaScript file\&.
+.RE
+.PP
+\fBinherit js\fR
+.RS 4
+Flag: Inherit JavaScript files from parents\&.
+.RE
+.PP
+\fBvar\fR
+.RS 4
+Set variable (the first text word on the right side is the variable name, the remainder of the line is the variable value)\&.
+.RE
+.SS "Files section"
+.sp
+The "[files]" section lists the name of additional files to copy, one per line\&.
+.SS "Contents section"
+.sp
+The "[contents]" section contains the tree structure for navigation\&.
+.sp
+Each subsection for a node is started by a title line\&. The indent level corresponds to the tree structure\&.
+.sp
+Title lines with same indent level are neighbours (sub\-nodes of the same parent node)\&. A nodes parent node is the next node above the node with smaller indent\&.
+.sp
+After the node title there are lines started by a @ to configure the node:
+.PP
+\fBfile = \fR\fIfile\fR
+.RS 4
+Text input file for the nodes contents\&.
+.RE
+.PP
+\fBinput encoding = \fR\fIencoding\fR
+.RS 4
+Default encoding to use if no BOM is found\&.
+.RE
+.PP
+\fBsuffix = \fR\fIstring\fR
+.RS 4
+File name suffix for output file\&.
+.RE
+.PP
+\fBshort = \fR\fIshort title\fR
+.RS 4
+Short title for use in the navigation menu\&.
+.RE
+.sp
+Additionally you can use the "html charset", "template", "style", "page toc", "write position", "replace ampersand", "tidy", "ln", "author", "location", "js file", "inherit js", "var", "icon toc", "icon previous", "icon next", "icon index", and "shortcut icon" settings as shown for the options section\&.
+.sp
+Leafs (nodes without further subnodes) must have a text file configured, for other nodes it\(cqs optional\&.
+.SH "EXAMPLE"
+.sp
+A working example index\&.prj file is in the src directory of the dktools\-doc\-x\&.y\&.z\&.tar\&.gz archive\&.
+.SH "AUTHOR"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2013\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+\fBhtmlbook(1)\fR
+.RS 4
+Program description\&.
+.RE
+.PP
+\fBhtmlbook\-template(5)\fR
+.RS 4
+Syntax of template files\&.
+.RE
+.PP
+\fBhtmlbook\-text(5)\fR
+.RS 4
+Syntax of text files\&.
+.RE
+.PP
+http://dktools\&.sourceforge\&.net/
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man5/htmlbook-template.5 b/support/dktools/man/man5/htmlbook-template.5
new file mode 100644
index 0000000000..4bdb9da97f
--- /dev/null
+++ b/support/dktools/man/man5/htmlbook-template.5
@@ -0,0 +1,505 @@
+'\" t
+.\" Title: htmlbook-template
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 02/06/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "HTMLBOOK\-TEMPLATE" "5" "02/06/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+htmlbook-template \- Template file for htmlbook\&.
+.SH "DESCRIPTION"
+.sp
+This text describes the htmlbook template file syntax\&.
+.SH "SYNTAX"
+.sp
+The template file specifies the text between <BODY> and </BODY>\&. Special commands \fB%%\fR\fIcommand\fR\fB%%\fR can be used to insert the text, the navigation menu, navigation blocks with clickable icons\&. The following special commands are available:
+.PP
+\fB%%contents%%\fR
+.RS 4
+inserts the text file contents\&.
+.RE
+.PP
+\fB%%title%%\fR
+.RS 4
+inserts the node title (page title)\&.
+.RE
+.PP
+\fB%%img \fR\fIoptions\fR\fB%%\fR
+.RS 4
+inserts an image\&. The following options are available:
+.PP
+\fBdiv\fR[\fB=\fR\fIbool\fR]
+.RS 4
+Create <div> around <img>
+.RE
+.PP
+\fBcentered\fR[\fB=\fR\fIbool\fR]
+.RS 4
+Show image centered, not left\-aligned\&.
+.RE
+.PP
+\fBsrc=\fR\fIfile\fR
+.RS 4
+File name for image\&.
+.RE
+.PP
+\fBalt="\fR\fItext\fR\fB"\fR
+.RS 4
+Alternative text for image\&.
+.RE
+.PP
+\fBtitle\fR[\fB="\fR\fItext\fR\fB"\fR]
+.RS 4
+Title text (alt= is used as default)\&.
+.RE
+.PP
+\fBcaption\fR[\fB="\fR\fItext\fR\fB"\fR]
+.RS 4
+Image caption\&.
+.RE
+.PP
+\fBlongdesc=\fR\fIURL\fR
+.RS 4
+File containing long description of image\&.
+.RE
+.PP
+\fBborder=\fR\fIwidth\fR
+.RS 4
+Border width\&.
+.RE
+.PP
+\fBheight=\fR\fIheight\fR
+.RS 4
+Image height\&.
+.RE
+.PP
+\fBwidth=\fR\fIwidth\fR
+.RS 4
+Image width\&.
+.RE
+.PP
+\fBsvg=\fR\fIfile\fR
+.RS 4
+SVG version of image\&.
+.RE
+.PP
+\fBsvgwh\fR[\fB=\fR\fIbool\fR]
+.RS 4
+Apply PNG/JPEG dimensions to SVG object\&.
+.RE
+.PP
+\fBobject\fR[\fB=\fR\fIbool\fR]
+.RS 4
+Create object for SVG\&.
+.RE
+.PP
+\fBpdf=\fR\fIfile\fR
+.RS 4
+PDF version of image\&.
+.RE
+.PP
+\fBlarger=\fR\fIfile\fR
+.RS 4
+Larger version of image\&.
+.RE
+.PP
+\fBismap\fR[\fB=\fR\fIbool\fR]
+.RS 4
+Set ismap attribute\&.
+.RE
+.PP
+\fBusemap=\fR\fIfile\fR
+.RS 4
+Image map file\&.
+.RE
+.PP
+\fBname=\fR\fIname\fR
+.RS 4
+Item name\&.
+.RE
+.PP
+\fBid=\fR\fIname\fR
+.RS 4
+ID for CSS styling\&.
+.RE
+.PP
+\fBclass=\fR\fIname\fR
+.RS 4
+Class name for CSS styling\&.
+.RE
+.PP
+\fBalign=\fR\fIname\fR
+.RS 4
+Alignment\&.
+.RE
+.PP
+\fBvspace=\fR\fIdistance\fR
+.RS 4
+Vertical space\&.
+.RE
+.PP
+\fBhspace=\fR\fIdistance\fR
+.RS 4
+Horizontal space\&.
+.RE
+.PP
+\fBdownloads\fR[\fB=\fR\fIBool\fR]
+.RS 4
+Provide links to download vector graphics
+.RE
+.PP
+\fBcache\fR
+.RS 4
+Cache image dimensions for images used multiple times\&. Image dimensions for images used in a template are cached automatically\&.
+.RE
+.RE
+.PP
+\fB%%menu \fR\fIoptions\fR\fB%%\fR
+.RS 4
+inserts the navigation menu\&. The following options are available:
+.PP
+\fBstyle=\fR\fIstyle\fR
+.RS 4
+One from "reverse" (full menu in reverse order), "full" (full menu), "top" (show only first hierarchy level) or "current" (show only current hierarchy level)\&.
+.RE
+.PP
+\fBsub\fR[\fB=\fR\fIbool\fR]
+.RS 4
+Flag: Show subnodes of current node\&.
+.RE
+.RE
+.PP
+\fB%%navigation \fR\fIoptions\fR\fB%%\fR
+.RS 4
+inserts a navigation block\&. The following options are available:
+.PP
+\fBhome=\fR\fIfile\fR
+.RS 4
+Icon for table of contents ("home\&.png")\&.
+.RE
+.PP
+\fBprevious=\fR\fIfile\fR
+.RS 4
+Icon for previous section ("prev\&.png")\&.
+.RE
+.PP
+\fBnext=\fR\fIfile\fR
+.RS 4
+Icon for next section ("next\&.png")\&.
+.RE
+.PP
+\fBtoc=\fR\fIfile\fR
+.RS 4
+Icon for table of contents ("toc\&.png")\&.
+.RE
+.PP
+\fBindex=\fR\fIfile\fR
+.RS 4
+Icon for keyword index ("index\&.png")\&.
+.RE
+.RE
+.PP
+\fB%%author%%\fR
+.RS 4
+inserts the author name\&.
+.RE
+.PP
+\fB%%location%%\fR
+.RS 4
+inserts the authors location\&.
+.RE
+.PP
+\fB%%date \fR\fIoptions\fR\fB%%\fR
+.RS 4
+inserts the current node\&. The following options are available:
+.PP
+\fBstyle=\fR\fIname\fR
+.RS 4
+Date style, currently only "german" is allowed to switch from the default "yyyy\-mm\-dd" to "dd\&.mm\&.yyyy"\&.
+.RE
+.RE
+.PP
+\fB%%var \fR\fIname\fR \fIoptions\fR\fB%%\fR
+.RS 4
+inserts a variable value\&. The following options are available:
+.PP
+\fBurl\fR[\fB=\fR\fIbool\fR]
+.RS 4
+Flag: Encode as URL, not as text\&.
+.RE
+.RE
+.PP
+\fB%%code \fR\fIoptions\fR\fB%%\fR
+.RS 4
+controls output encoding\&. By default the \*(Aq<\*(Aq, \*(Aq>\*(Aq are not replaced by "<", and ">" as we expect to get correct HTML from the text files\&. Replacement of \*(Aq&\*(Aq by "&" is controlled by the "replace ampersand" setting in the options section\&. In code mode our text comes from a source code file, so we have to encode these characters for HTML output\&. The following options are available:
+.PP
+\fBenable\fR[\fB=\fR\fIbool\fR]
+.RS 4
+turns code mode on\&.
+.RE
+.PP
+\fBon\fR[\fB=\fR\fIbool\fR]
+.RS 4
+turns code mode on\&.
+.RE
+.PP
+\fBdisable\fR[\fB=\fR\fIbool\fR]
+.RS 4
+turns code mode off\&.
+.RE
+.PP
+\fBoff\fR[\fB=\fR\fIbool\fR]
+.RS 4
+turns code mode off\&.
+.RE
+.PP
+\fBtoggle\fR
+.RS 4
+toggles code mode\&.
+.RE
+.RE
+.PP
+\fB%%a \fR\fIoptions\fR\fB%%\fR
+.RS 4
+inserts a named anchor or a hyperlink\&. The following options are available:
+.PP
+\fBname=\fR\fIname\fR
+.RS 4
+Anchor name\&.
+.RE
+.PP
+\fBhref=\fR\fIURL\fR
+.RS 4
+Link destination\&.
+.RE
+.PP
+\fBtitle="\fR\fItext\fR\fB"\fR
+.RS 4
+Text to show when mouse is over link\&.
+.RE
+.PP
+\fBtext="\fR\fItext\fR\fB"\fR
+.RS 4
+Text for hyperlink\&.
+.RE
+.PP
+\fBtarget=\fR\fIdestination\fR
+.RS 4
+Destination windows or frame, i\&.e\&. "_blank"\&.
+.RE
+.PP
+\fBtype=\fR\fItext\fR
+.RS 4
+MIME type\&.
+.RE
+.PP
+\fBexternal\fR[\fB=\fR\fIbool\fR]
+.RS 4
+Override result of internal/external test\&.
+.RE
+.PP
+\fBid=\fR\fItext\fR
+.RS 4
+ID for CSS styling\&.
+.RE
+.PP
+\fBclass=\fR\fItext\fR
+.RS 4
+Class name for CSS styling\&.
+.RE
+.PP
+\fBstyle=\fR\fItext\fR
+.RS 4
+Direct style information\&.
+.RE
+.PP
+\fBhreflang=\fR\fItext\fR
+.RS 4
+Language for href text\&.
+.RE
+.PP
+\fBcharset=\fR\fItext\fR
+.RS 4
+Character set\&.
+.RE
+.PP
+\fBonblur=\fR\fItext\fR
+.RS 4
+Script to execute when link looses focus\&.
+.RE
+.PP
+\fBonfocus=\fR\fItext\fR
+.RS 4
+Script to execute when link gets focus\&.
+.RE
+.PP
+\fBaccesskey=\fR\fItext\fR
+.RS 4
+Hotkey for link\&.
+.RE
+.PP
+\fBtabindex=\fR\fInumber\fR
+.RS 4
+Tabulator index\&.
+.RE
+.PP
+\fBshape=\fR\fItext\fR
+.RS 4
+Link shape form\&.
+.RE
+.PP
+\fBcoords=\fR\fItext\fR
+.RS 4
+Coordinates\&.
+.RE
+.PP
+\fBrel=\fR\fItext\fR
+.RS 4
+Information for link to next element\&.
+.RE
+.PP
+\fBrev=\fR\fItext\fR
+.RS 4
+Information for link to previous element\&.
+.RE
+.RE
+.PP
+\fB%%menuentry \fR\fIoptions\fR\fB%%\fR
+.RS 4
+inserts code to visualize a menu entry\&. The following options are available:
+.PP
+\fBitem="\fR\fItext\fR\fB"\fR
+.RS 4
+Text of the menu entry, can be used multiple times for hierarchical menus\&.
+.RE
+.RE
+.PP
+\fB%%sourcefile \fR\fIoptions\fR\fB%%\fR
+.RS 4
+shows a file contents in a
+<PRE></PRE>
+environment and provides a download hyperlink\&. The following options are available:
+.PP
+\fBfile=\fR\fIfile\fR
+.RS 4
+File name\&.
+.RE
+.PP
+\fBtype=\fR\fItext\fR
+.RS 4
+MIME type\&.
+.RE
+.PP
+\fBtitle="\fR\fItext\fR\fB"\fR
+.RS 4
+Text shown when mouse is over hyperlink\&.
+.RE
+.RE
+.PP
+\fB%%hint \fR\fIoptions\fR\fB%%\fR
+.RS 4
+creates a
+<span class="hint" title="\&...">\&...</span>
+text piece\&. The following options are available:
+.PP
+\fBtext=\fR\fItext\fR
+.RS 4
+Text in the span\&.
+.RE
+.PP
+\fBtitle=\fR\fItext\fR
+.RS 4
+Tool tip text to show when mouse is over text span\&.
+.RE
+.RE
+.SH "EXAMPLE"
+.sp
+Working example files web\&.hbt and chm\&.hbt are in the src directory of the dktools\-doc\-x\&.y\&.z\&.tar\&.gz archive\&.
+.SH "AUTHOR"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2013\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+\fBhtmlbook(1)\fR
+.RS 4
+Program description\&.
+.RE
+.PP
+\fBhtmlbook\-project(5)\fR
+.RS 4
+Syntax of the project file\&.
+.RE
+.PP
+\fBhtmlbook\-text(5)\fR
+.RS 4
+Syntax of text files\&.
+.RE
+.PP
+http://dktools\&.sourceforge\&.net/
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man5/htmlbook-text.5 b/support/dktools/man/man5/htmlbook-text.5
new file mode 100644
index 0000000000..64767dd17e
--- /dev/null
+++ b/support/dktools/man/man5/htmlbook-text.5
@@ -0,0 +1,538 @@
+'\" t
+.\" Title: htmlbook-text
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 10/26/2016
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "HTMLBOOK\-TEXT" "5" "10/26/2016" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+htmlbook-text \- Text file for htmlbook\&.
+.SH "DESCRIPTION"
+.sp
+This text describes the htmlbook template file syntax\&.
+.SH "SYNTAX"
+.sp
+Text files contain optional page setup lines and the page contents\&.
+.sp
+Page setup lines start with a dot and a command name like
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\&.meta\-description Content for the meta description tag
+\&.meta\-keywords Content for the meta keywords tag
+\&.author Authors name
+\&.title Longer title shown in browsers window deco
+\&.short Short title shown in the navigation menu
+\&.location AUthors location
+\&.page\-toc boolean
+\&.replace\-ampersand boolean
+\&.write\-position boolean
+\&.shortcut\-icon Icon name for shortcut icon (favicon)
+\&.js\-file JavaScript file name
+\&.inherit\-js boolean
+\&.context\-number Context number when building CHM help file
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+You can use headings like
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\&.1 @name@ Heading text
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+for a structural document\&. Depths 1, 2, 3, 4, or 5 are converted to <h2>\&...<h6> headers\&. A <h1> header is used for the page title\&. The @name@ specification is optional, it results in a named anchor <a name="name"></a> before the heading\&. If the name specification is omitted, an anchor name is generated automatically\&. Special commands can be used in the text:
+.PP
+\fB%%index \fR\fIoptions\fR\fB%%\fR
+.RS 4
+Add an entry to the keyword index\&. The following options can be used:
+.PP
+\fBtext="\fR\fItext\fR\fB"\fR
+.RS 4
+Keyword\&.
+.RE
+.PP
+\fBname="\fR\fItext\fR\fB"\fR
+.RS 4
+Name of a named anchor\&.
+.RE
+.PP
+\fBreference\fR[\fB=\fR\fIbool\fR]
+.RS 4
+Flag: Use existing named anchor, do not create an anchor\&.
+.RE
+.RE
+.PP
+\fB%%title%%\fR
+.RS 4
+Insert the node title (page title)\&.
+.RE
+.sp
+Most of the special commands known from the template files (except %%contents%%) can be used in text files too:
+.PP
+\fB%%img \fR\fIoptions\fR\fB%%\fR
+.RS 4
+Insert an image\&. The following options are available:
+.PP
+\fBdiv\fR[\fB=\fR\fIbool\fR]
+.RS 4
+Create <div> around <img>
+.RE
+.PP
+\fBcentered\fR[\fB=\fR\fIbool\fR]
+.RS 4
+Show image centered, not left\-aligned\&.
+.RE
+.PP
+\fBsrc=\fR\fIfile\fR
+.RS 4
+File name for image\&.
+.RE
+.PP
+\fBalt="\fR\fItext\fR\fB"\fR
+.RS 4
+Alternative text for image\&.
+.RE
+.PP
+\fBtitle\fR[\fB="\fR\fItext\fR\fB"\fR]
+.RS 4
+Title text (alt= is used as default)\&.
+.RE
+.PP
+\fBcaption\fR[\fB="\fR\fItext\fR\fB"\fR]
+.RS 4
+Image caption\&.
+.RE
+.PP
+\fBlongdesc=\fR\fIURL\fR
+.RS 4
+File containing long description of image\&.
+.RE
+.PP
+\fBborder=\fR\fIwidth\fR
+.RS 4
+Border width\&.
+.RE
+.PP
+\fBheight=\fR\fIheight\fR
+.RS 4
+Image height\&.
+.RE
+.PP
+\fBwidth=\fR\fIwidth\fR
+.RS 4
+Image width\&.
+.RE
+.PP
+\fBsvg=\fR\fIfile\fR
+.RS 4
+SVG version of image\&.
+.RE
+.PP
+\fBsvgwh\fR[\fB=\fR\fIbool\fR]
+.RS 4
+Apply PNG/JPEG dimensions to SVG object\&.
+.RE
+.PP
+\fBobject\fR[\fB=\fR\fIbool\fR]
+.RS 4
+Create object for SVG\&.
+.RE
+.PP
+\fBpdf=\fR\fIfile\fR
+.RS 4
+PDF version of image\&.
+.RE
+.PP
+\fBlarger=\fR\fIfile\fR
+.RS 4
+Larger version of image\&.
+.RE
+.PP
+\fBismap\fR[\fB=\fR\fIbool\fR]
+.RS 4
+Set ismap attribute\&.
+.RE
+.PP
+\fBusemap=\fR\fIfile\fR
+.RS 4
+Image map file\&.
+.RE
+.PP
+\fBname=\fR\fIname\fR
+.RS 4
+Item name\&.
+.RE
+.PP
+\fBid=\fR\fIname\fR
+.RS 4
+ID for CSS styling\&.
+.RE
+.PP
+\fBclass=\fR\fIname\fR
+.RS 4
+Class name for CSS styling\&.
+.RE
+.PP
+\fBalign=\fR\fIname\fR
+.RS 4
+Alignment\&.
+.RE
+.PP
+\fBvspace=\fR\fIdistance\fR
+.RS 4
+Vertical space\&.
+.RE
+.PP
+\fBhspace=\fR\fIdistance\fR
+.RS 4
+Horizontal space\&.
+.RE
+.PP
+\fBdownloads\fR[\fB=\fR\fIBool\fR]
+.RS 4
+Provide links to download vector graphics
+.RE
+.PP
+\fBcache\fR
+.RS 4
+Cache image dimensions for images used multiple times\&. Image dimensions for images used in a template are cached automatically\&.
+.RE
+.RE
+.PP
+\fB%%menu \fR\fIoptions\fR\fB%%\fR
+.RS 4
+Insert the navigation menu\&. The following options are available:
+.PP
+\fBstyle=\fR\fIstyle\fR
+.RS 4
+One from "reverse" (full menu in reverse order), "full" (full menu), "top" (show only first hierarchy level) or "current" (show only current hierarchy level)\&.
+.RE
+.PP
+\fBsub\fR[\fB=\fR\fIbool\fR]
+.RS 4
+Flag: Show subnodes of current node\&.
+.RE
+.RE
+.PP
+\fB%%navigation \fR\fIoptions\fR\fB%%\fR
+.RS 4
+Insert a navigation block\&. The following options are available:
+.PP
+\fBitop=\fR\fIfile\fR
+.RS 4
+Icon for table of contents ("toc\&.png")\&.
+.RE
+.PP
+\fBiprev=\fR\fIfile\fR
+.RS 4
+Icon for previous section ("prev\&.png")\&.
+.RE
+.PP
+\fBinext=\fR\fIfile\fR
+.RS 4
+Icon for next section ("next\&.png")\&.
+.RE
+.PP
+\fBikind=\fR\fIfile\fR
+.RS 4
+Icon for keyword index ("index\&.png")\&.
+.RE
+.RE
+.PP
+\fB%%author%%\fR
+.RS 4
+inserts the author name\&.
+.RE
+.PP
+\fB%%location%%\fR
+.RS 4
+Insert the authors location\&.
+.RE
+.PP
+\fB%%date \fR\fIoptions\fR\fB%%\fR
+.RS 4
+Insert the current node\&. The following options are available:
+.PP
+\fBstyle=\fR\fIname\fR
+.RS 4
+Date style, currently only "german" is allowed to switch from the default "yyyy\-mm\-dd" to "dd\&.mm\&.yyyy"\&.
+.RE
+.RE
+.PP
+\fB%%var \fR\fIname\fR \fIoptions\fR\fB%%\fR
+.RS 4
+Insert a variable value\&. The following options are available:
+.PP
+\fBurl\fR[\fB=\fR\fIbool\fR]
+.RS 4
+Flag: Encode as URL, not as text\&.
+.RE
+.RE
+.PP
+\fB%%code \fR\fIoptions\fR\fB%%\fR
+.RS 4
+Output encoding for code\&. By default the \*(Aq<\*(Aq, \*(Aq>\*(Aq are not replaced by "<", and ">" as we expect to get correct HTML from the text files\&. Replacement of \*(Aq&\*(Aq by "&" is controlled by the "replace ampersand" setting in the options section\&. In code mode our text comes from a source code file, so we have to encode these characters for HTML output\&. The following options are available:
+.PP
+\fBenable\fR[\fB=\fR\fIbool\fR]
+.RS 4
+Turn code mode on\&.
+.RE
+.PP
+\fBon\fR[\fB=\fR\fIbool\fR]
+.RS 4
+Turn code mode on\&.
+.RE
+.PP
+\fBdisable\fR[\fB=\fR\fIbool\fR]
+.RS 4
+Turn code mode off\&.
+.RE
+.PP
+\fBoff\fR[\fB=\fR\fIbool\fR]
+.RS 4
+Turn code mode off\&.
+.RE
+.PP
+\fBtoggle\fR
+.RS 4
+Toggle code mode\&.
+.RE
+.RE
+.PP
+\fB%%a \fR\fIoptions\fR\fB%%\fR
+.RS 4
+Insert a named anchor or a hyperlink\&. The following options are available:
+.PP
+\fBname=\fR\fIname\fR
+.RS 4
+Anchor name\&.
+.RE
+.PP
+\fBhref=\fR\fIURL\fR
+.RS 4
+Link destination\&.
+.RE
+.PP
+\fBtitle="\fR\fItext\fR\fB"\fR
+.RS 4
+Text to show when mouse is over link\&.
+.RE
+.PP
+\fBtext="\fR\fItext\fR\fB"\fR
+.RS 4
+Text for hyperlink\&.
+.RE
+.PP
+\fBtarget=\fR\fIdestination\fR
+.RS 4
+Destination windows or frame, i\&.e\&. "_blank"\&.
+.RE
+.PP
+\fBtype=\fR\fItext\fR
+.RS 4
+MIME type\&.
+.RE
+.PP
+\fBexternal\fR[\fB=\fR\fIbool\fR]
+.RS 4
+Override result of internal/external test\&.
+.RE
+.PP
+\fBid=\fR\fItext\fR
+.RS 4
+ID for CSS styling\&.
+.RE
+.PP
+\fBclass=\fR\fItext\fR
+.RS 4
+Class name for CSS styling\&.
+.RE
+.PP
+\fBstyle=\fR\fItext\fR
+.RS 4
+Direct style information\&.
+.RE
+.PP
+\fBhreflang=\fR\fItext\fR
+.RS 4
+Language for href text\&.
+.RE
+.PP
+\fBcharset=\fR\fItext\fR
+.RS 4
+Character set\&.
+.RE
+.PP
+\fBonblur=\fR\fItext\fR
+.RS 4
+Script to execute when link looses focus\&.
+.RE
+.PP
+\fBonfocus=\fR\fItext\fR
+.RS 4
+Script to execute when link gets focus\&.
+.RE
+.PP
+\fBaccesskey=\fR\fItext\fR
+.RS 4
+Hotkey for link\&.
+.RE
+.PP
+\fBtabindex=\fR\fInumber\fR
+.RS 4
+Tabulator index\&.
+.RE
+.PP
+\fBshape=\fR\fItext\fR
+.RS 4
+Link shape form\&.
+.RE
+.PP
+\fBcoords=\fR\fItext\fR
+.RS 4
+Coordinates\&.
+.RE
+.PP
+\fBrel=\fR\fItext\fR
+.RS 4
+Information for link to next element\&.
+.RE
+.PP
+\fBrev=\fR\fItext\fR
+.RS 4
+Information for link to previous element\&.
+.RE
+.RE
+.PP
+\fB%%menuentry \fR\fIoptions\fR\fB%%\fR
+.RS 4
+Insert code to visualize a menu entry\&. The following options are available:
+.PP
+\fBitem="\fR\fItext\fR\fB"\fR
+.RS 4
+Text of the menu entry, can be used multiple times for hierarchical menus\&.
+.RE
+.RE
+.PP
+\fB%%sourcefile \fR\fIoptions\fR\fB%%\fR
+.RS 4
+Insert a file contents in a
+<PRE></PRE>
+environment and provide a download hyperlink\&. The following options are available:
+.PP
+\fBfile=\fR\fIfile\fR
+.RS 4
+File name\&.
+.RE
+.PP
+\fBtype=\fR\fItext\fR
+.RS 4
+MIME type\&.
+.RE
+.PP
+\fBtitle="\fR\fItext\fR\fB"\fR
+.RS 4
+Text shown when mouse is over hyperlink\&.
+.RE
+.RE
+.SH "EXAMPLE"
+.sp
+Working example files web\&.hbt and chm\&.hbt are in the src directory of the dktools\-doc\-x\&.y\&.z\&.tar\&.gz archive\&.
+.SH "AUTHOR"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2013\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+\fBhtmlbook(1)\fR
+.RS 4
+Program description\&.
+.RE
+.PP
+\fBhtmlbook\-project(5)\fR
+.RS 4
+Syntax of the project file\&.
+.RE
+.PP
+\fBhtmlbook\-template(5)\fR
+.RS 4
+Syntax of template files\&.
+.RE
+.PP
+http://dktools\&.sourceforge\&.net/
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man5/printqd.conf.5 b/support/dktools/man/man5/printqd.conf.5
new file mode 100644
index 0000000000..fef95353c9
--- /dev/null
+++ b/support/dktools/man/man5/printqd.conf.5
@@ -0,0 +1,259 @@
+'\" t
+.\" Title: printqd.conf
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 03/28/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "PRINTQD\&.CONF" "5" "03/28/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+printqd.conf \- Configuration file for printqd
+.SH "DESCRIPTION"
+.sp
+This text describes the printqd\&.conf file syntax\&.
+.sp
+Printers are grouped into printer classes\&. A limit for a printer class means that a user can print a number of pages in summary on the printers of that class\&.
+.SH "SYNTAX"
+.sp
+The printqd\&.conf file consists of one options section, one or multiple class sections and one or multiple printer sections\&.
+.SS "OPTIONS SECTION"
+.sp
+The \fB[options]\fR section can contain the following lines:
+.PP
+\fBrun as user =\fR \fIname\fR
+.RS 4
+User name of the account to run the daemon\&. Optional, no default (remain running as root)\&. For security reasons the daemon should give up root privileges before servicing any request\&. It depends on the name service you use whether or not you can use this feature\&. Printqd uses the
+\fIgetpwnam()\fR
+and
+\fIgetgrnam()\fR
+functions to access user and group data\&. When running printqd as non\-root user the user must have access to other users\*(Aq data using these functions\&.
+.RE
+.PP
+\fBrun as group =\fR \fIname\fR
+.RS 4
+In addtion to change the user account from root to something else we can also change the group\&. Optional, no default (remain running under root GID)\&.
+.RE
+.PP
+\fBdatabase =\fR \fItype\fR\fB::\fR\fIfilename\fR
+.RS 4
+Database type and file name\&. Optional, default: ${localstatedir}/var/printqd/printqd\&.* with best available database type and appropriate file name suffix\&. The
+\fItype\fR
+argument is the database type: \(lqbdb\(rq, \(lqndbm\(rq, or \(lqmem\(rq for Berkeley DB, NDBM or in\-memory databases\&. The
+\fIfilename\fR
+argument is the file name for the database\&. For NDBM databases \(lq\&.dir\(rq and \(lq\&.pag\(rq are appended automatically\&.
+.RE
+.PP
+\fBlocal socket =\fR \fIfilename\fR
+.RS 4
+File name of the administrative socket\&. Optional, ${localstatedir}/run/printqd/printqd\&.sock is used by default\&. The printqd daemon accepts info, data, and control requests from clients connecting over this socket\&. This must be a UNIX domain socket, the file name must have less than 108 characters\&. If you use the \(lqrun as user\(rq feature, the specified user account must have permission to remove and create this file (write access to the ${localstatedir}/run/printqd directory is required)\&.
+.RE
+.PP
+\fBlocal socket owner =\fR \fIname\fR
+.RS 4
+Owner user name of local socket\&. Optional, default: \(lqrun as user\(rq account, or root\&. Recommended: If \(lqrun as user\(rq is specified, use the same account here\&. Otherwise use the account running the LPRng print system\&.
+.RE
+.PP
+\fBlocal socket group =\fR \fIname\fR
+.RS 4
+Owner group name of local socket\&. Optional, default: \(lqrun as group\(rq, or root\&. Recommended: If \(lqrun as group\(rq is specified, use the same group here\&. Otherwise use the group running the LPRng print system\&.
+.RE
+.PP
+\fBlocal socket backlog =\fR \fIinteger\fR
+.RS 4
+Backlog for the socket configured above (maximum number of pending connection requests)\&. Optional, default: 5\&. Recommended: at least 1 + number of print queues\&.
+.RE
+.PP
+\fBmax local connections =\fR \fIinteger\fR
+.RS 4
+Maximum number of connections allowed via local socket at same time\&. Optional, default: 0 (no limit)\&. Recommended: unlimited (0) or at least 1 + number of print queues\&.
+.RE
+.PP
+\fBudp port =\fR \fIportnumber\fR
+.RS 4
+Port number for UDP packets\&. Optional, default: UDP not used\&. Make sure to configure a port number not yet used by other services on your system\&. If you use the \(lqrun as user\(rq feature, make sure not to use a privileged port below 1024\&.
+.RE
+.PP
+\fBtcp port =\fR \fIportnumber\fR
+.RS 4
+Port number for TCP connections\&. Optional, default: TCP not used\&. Make sure to configure a port number not yet used by other services on your system\&. If you use the \(lqrun as user\(rq feature, make sure not to use a privileged port below 1024\&.
+.RE
+.PP
+\fBtcp port backlog =\fR \fIinteger\fR
+.RS 4
+Backlog for the TCP socket (maximum number of pending connection requests)\&. Optional, default: 5\&. Recommended: Number of LPRng print queues on remote print servers + number of all PCs able to submit print jobs to the servers\&. If clients fail to connect you should attempt to increase the number\&.
+.RE
+.PP
+\fBmax tcp connections =\fR \fIinteger\fR
+.RS 4
+Maximum number of TCP connections allowed at same time\&. Optional, default: no limit\&. Recommended: No limit or summary of print queues number and client hosts number\&.
+.RE
+.PP
+\fBinfo allow =\fR \fInetwork\fR[\fB/\fR\fImask\fR]
+.RS 4
+Client addresses or networks allowed to connect to use \(lqinfo\(rq requests\&. Optional, default: no hosts allowed\&. Recommended: All hosts which can send print jobs to the print server\&. Multiple \(lqinfo\ \&allow\(rq entries can be used\&. You can use one line containing an asterisk as network to accept info requests from everywhere (only recommended if your network is behind a firwall or a router with ACLs restricting inbound traffic)\&.
+.RE
+.PP
+\fBdata allow =\fR \fInetwork\fR[\fB/\fR\fImask\fR]
+.RS 4
+Client addresses or networks allowed to connect to use \(lqinfo\(rq and \(lqdata\(rq requests\&. Optional, default: no hosts allowed\&. Recommended: Only print servers running print queues\&. Multiple \(lqdata\ \&allow\(rq entries can be used\&. You could use one line containing an asterisk as network to accept data requests from everywhere, but this is not recommended\&.
+.RE
+.PP
+\fBadmin allow =\fR \fInetwork\fR[\fB/\fR\fImask\fR]
+.RS 4
+Client addresses or networks allowed to connect to use \(lqinfo\(rq, \(lqdata\(rq and \(lqadmin\(rq requests\&. Optional, default: no hosts allowed\&. Recommended: Only administrator PCs\&. Multiple \(lqadmin\ \&allow\(rq entries can be used\&. You could use one line containing an asterisk as network to accept admin requests from everywhere, but this is not recommended\&.
+.RE
+.PP
+\fBlog file =\fR \fIfilename\fR
+.RS 4
+Name for log file\&. Optional, ${localstatedir}/log/printqd/printqd\&.log is the default\&.
+.RE
+.PP
+\fBlog features =\fR \fIfeatures\fR
+.RS 4
+Features to write log messages for, comma\-separated list:
+.PP
+db
+.RS 4
+Database modifications\&.
+.RE
+.PP
+info
+.RS 4
+Info requests and responses (normally not logged)\&.
+.RE
+.PP
+all
+.RS 4
+Same as \(lqdb,info\(rq\&.
+.RE
+.PP
+none
+.RS 4
+Produce minimum log only (default)\&.
+.RE
+.RE
+.SS "CLASS SECTIONS"
+.sp
+Limits are configured for printer classes\&. A printer class contains one or multiple printers\&. If a limit of \fIn\fR pages is configured for a user in a class, the user can print these \fIn\fR pages in summary on all printers in the class, not \fIn\fR pages on each printer\&.
+.sp
+The \fB[class\fR \fIname\fR\fB]\fR sections can contain the following lines:
+.PP
+\fBdefault limit =\fR \fIlimit\fR
+.RS 4
+Default limit, either \(lqunlimited\(rq, a page number, or 0 to deny printing\&. Recommended, default: 0\&.
+.RE
+.PP
+\fBuser limit =\fR \fIname\fR \fIlimit\fR
+.RS 4
+Limit for the named user\&. Optional\&. Multiple user limit entries can be used for different users\&.
+.RE
+.PP
+\fBgroup limit =\fR \fIname\fR \fIlimit\fR
+.RS 4
+Limit for the named group\&. Optional\&. Multiple group limit entries can be used for different groups\&.
+.RE
+.PP
+\fBdeny action =\fR \fIstring\fR
+.RS 4
+Action if printing is denied: either \(lqremove\(rq to remove the print job from the queue, or \(lqhold\(rq to keep the job for later processing\&. Optional, default: remove\&.
+.RE
+.SS "PRINTER SECTIONS"
+.sp
+A \fB[printer\fR \fIname\fR\fB]\fR section configures a specific printer\&. It can contain the following settings:
+.PP
+\fBclass =\fR \fIname\fR
+.RS 4
+Class name for the printer, it must be one of the classes defined above\&. Required, no default\&.
+.RE
+.PP
+\fBalias =\fR \fIname\fR
+.RS 4
+Alias name assigned to the printer\&. Optional\&. Recommendation: You should list the same alias names as used in the printcap file\&.
+.RE
+.SH "AUTHOR"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2012\-2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+printqd(1)
+.RS 4
+Print quota daemon\&.
+.RE
+.PP
+printqd\&.db(5)
+.RS 4
+Print quota daemon database\&.
+.RE
+.PP
+printqd\&.protocol(5)
+.RS 4
+Communication protocol for printqd\&.
+.RE
+.PP
+http://dktools\&.sourceforge\&.net/
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man5/printqd.db.5 b/support/dktools/man/man5/printqd.db.5
new file mode 100644
index 0000000000..1cb6671667
--- /dev/null
+++ b/support/dktools/man/man5/printqd.db.5
@@ -0,0 +1,124 @@
+'\" t
+.\" Title: printqd.db
+.\" Author: [see the "AUTHORS" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 03/28/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "PRINTQD\&.DB" "5" "03/28/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+printqd.db \- Database entries in the printqd database\&.
+.SH "SYNTAX"
+.sp
+Printqd keeps data in a text database\&. This can be a Berkeley DB, an NDBM database or an in\-memory database\&.
+.sp
+All entries consists of a key and a value, both key and value are saved as text\&.
+.sp
+Keys can be of different types:
+.PP
+\fBp:\fR\fIclass\fR\fB:\fR\fIuser\fR
+.RS 4
+Number of pages the user printed in the printer class from a limit (general limit, group limit, or user limit)\&. Pages are counted upwards when printing until the user reaches or exceeds the page limit\&.
+.RE
+.PP
+\fBa:\fR\fIclass\fR\fB:\fR\fIuser\fR
+.RS 4
+Number of pages in the personal user account (number of pages still available)\&. The number is counted downwards when printing\&.
+.RE
+.PP
+\fBj:\fR\fIprinter\fR
+.RS 4
+Information about a print job currently executed by a printer: page counter before job start, user name and print job name\&. The items are separated by a colon\&.
+.RE
+.PP
+\fBo:test\fR
+.RS 4
+Dummy entry, created when the printqd program is started to make sure there is a database file which can be modified using chmod and chown before the user account is switched to non\-root\&.
+.RE
+.SH "AUTHORS"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+printqd(1)
+.RS 4
+Print quota daemon\&.
+.RE
+.PP
+printqd\&.conf(5)
+.RS 4
+Printqd configuration file syntax\&.
+.RE
+.PP
+printqd\&.protocol(5)
+.RS 4
+Communication protocol for printqd\&.
+.RE
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/man/man5/printqd.protocol.5 b/support/dktools/man/man5/printqd.protocol.5
new file mode 100644
index 0000000000..6a3abac3e5
--- /dev/null
+++ b/support/dktools/man/man5/printqd.protocol.5
@@ -0,0 +1,204 @@
+'\" t
+.\" Title: printqd.protocol
+.\" Author: [see the "AUTHORS" section]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\" Date: 03/28/2017
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "PRINTQD\&.PROTOCOL" "5" "03/28/2017" "\ \&" "\ \&"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+printqd.protocol \- Protocol for communcation to printqd
+.SH "PROTOCOL"
+.sp
+The printqd protocol consists of three levels:
+.PP
+info
+.RS 4
+Users can check their print quota status, the requests do not result in any modification of the database\&.
+.RE
+.PP
+data
+.RS 4
+LPRng asks for a users permission to print on a given queue and reports printers internal page counter values to printqd before and after print jobs\&. This results in modifications of the database (increasing the number of pages used and/or decreasing personal print accounts)\&. The \(lqinfo\(rq protocol level is included\&.
+.RE
+.PP
+admin
+.RS 4
+An administrator can reset the number of pages printed by users, increase personal print accounts or initiate a database cleanup\&. The \(lqinfo\(rq and \(lqdata\(rq protocol levels are included\&.
+.RE
+.SS "INFO PROTOCOL LEVEL"
+.sp
+In the \(lqinfo\(rq protocol level theres is just one request:
+.PP
+\fBinfo\fR \fIprinter\fR \fIuser\fR
+.RS 4
+Retrieve a users print quota status for a print queue\&. The response consists of 4 numbers separated by space:
+.PP
+limit
+.RS 4
+The limit for the user in the print queues class\&. The value \-1 means unlimited printing\&.
+.RE
+.PP
+used
+.RS 4
+The number of pages already printed in the print queues class\&.
+.RE
+.PP
+account
+.RS 4
+Number of additional pages in personal print account for class\&.
+.RE
+.PP
+summary
+.RS 4
+1 if the user can print, 0 if printing is denied\&.
+.RE
+.RE
+.SS "DATA PROTOCOL LEVEL"
+.sp
+In the \(lqdata\(rq protocol level there are the following requests:
+.PP
+\fBacct\-check\fR \fIprinter\fR \fIuser\fR
+.RS 4
+Check whether a user is allowed to print on the current printer\&. The response is one from: \(lqACCEPT\(rq, \(lqREMOVE\(rq, or \(lqHOLD\(rq\&.
+.RE
+.PP
+\fBjobstart \*(Aq\-n\fR\fIuser\fR\fB\*(Aq \*(Aq\-P\fR\fIprinter\fR\fB\*(Aq\fR \&...
+.RS 4
+Check whether a user is allowed to print on the current printer\&. The response is one from: \(lqACCEPT\(rq, \(lqREMOVE\(rq, or \(lqHOLD\(rq\&.
+.RE
+.PP
+\fBjobend \*(Aq\-n\fR\fIuser\fR\fB\*(Aq \*(Aq\-P\fR\fIprinter\fR\fB\*(Aq\fR \&...
+.RS 4
+Ignored (implemented for compatibility reasons)\&.
+.RE
+.PP
+\fBacct\-charge\fR \fIprinter\fR \fIuser\fR \fIpages\fR [\fIjobname\fR [\fIjobtitle\fR]]
+.RS 4
+A print job was completed, the job used the specified number of pages\&. Using this request is preferred over acct\-start/acct\-end or filestart/fileend pairs as it is more robust, does not require the server to save the job name and does not require having a job name available\&.
+.RE
+.PP
+\fBacct\-start\fR \fIprinter\fR \fIuser\fR \fIpagecount\fR \fIjobname\fR [\fIjobtitle\fR]
+.RS 4
+Ready to transmit a print job to the printer, the printers internal page counter has the specified value before starting the job\&.
+.RE
+.PP
+\fBacct\-end\fR \fIprinter\fR \fIuser\fR \fIpagecount\fR \fIjobname\fR [\fIjobtitle\fR]
+.RS 4
+Finished processing a print job, the printers internal page counter has the specified value after finishing the job\&.
+.RE
+.PP
+\fBfilestart \*(Aq\-n\fR\fIuser\fR\fB\*(Aq \*(Aq\-P\fR\fIprinter\fR\fB\*(Aq \*(Aq\-p\fR\fIpagecount\fR\fB\*(Aq \*(Aq\-A\fR\fIjobname\fR\fB\*(Aq\fR
+.RS 4
+Ready to transmit a print job to the printer, the printers internal page counter has the specified value before starting the job\&.
+.RE
+.PP
+\fBfileend \*(Aq\-n\fR\fIuser\fR\fB\*(Aq \*(Aq\-P\fR\fIprinter\fR\fB\*(Aq \*(Aq\-p\fR\fIpagecount\fR\fB\*(Aq \*(Aq\-A\fR\fIjobname\fR\fB\*(Aq\fR
+.RS 4
+Finished processing a print job, the printers internal page counter has the specified value after finishing the job\&.
+.RE
+.SS "ADMIN PROTOCOL LEVEL"
+.sp
+In the \(lqadmin\(rq protocol level there are the following requests:
+.PP
+\fBcontrol\fR \fBreset\fR \fBclass=\fR\fIname\fR \fBuser=\fR\fIname\fR
+.RS 4
+Reset number of pages printed within the limit for the specified user(s) in the specified class(es)\&. An asterisk \(lq*\(rq as user or class name or an omitted user or class specification addresses all users/all classes\&.
+.RE
+.PP
+\fBcontrol\fR \fBadd\fR \fBclass=\fR\fIname\fR \fBuser=\fR\fIname\fR \fBpages=\fR\fInumber\fR
+.RS 4
+Add the specified number of pages to a users additional personal print account\&.
+.RE
+.PP
+\fBcontrol\fR \fBdatabase\-cleanup\fR
+.RS 4
+Clean up database, remove entries referring to non\-existing users, classes or printers\&.
+.RE
+.SH "AUTHORS"
+.sp
+Dirk Krause
+.SH "COPYRIGHT AND LICENSE"
+.sp
+Copyright (c) 2016, Dirk Krause
+.sp
+All rights reserved\&.
+.sp
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Neither the name of the copyright holder(s) nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission\&.
+.RE
+.sp
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \(lqAS IS\(rq AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED\&. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\&.
+.SH "SEE ALSO"
+.PP
+printqd(1)
+.RS 4
+Print quota daemon\&.
+.RE
+.PP
+printqd\&.conf(5)
+.RS 4
+Print quota daemon configuration file syntax\&.
+.RE
+.PP
+printqd\&.db(5)
+.RS 4
+Print quota daemon database structure\&.
+.RE
+.PP
+http://dktools\&.sourceforge\&.net
+.RS 4
+Project homepage\&.
+.RE
diff --git a/support/dktools/mod-dkconfig.sed b/support/dktools/mod-dkconfig.sed
new file mode 100644
index 0000000000..f8181214fe
--- /dev/null
+++ b/support/dktools/mod-dkconfig.sed
@@ -0,0 +1,2 @@
+/wxWidgets_header_start/,/wxWidgets_header_end/d
+/wxWidgets_body_start/,/wxWidgets_body_end/d
diff --git a/support/dktools/modsnmp.sed b/support/dktools/modsnmp.sed
new file mode 100644
index 0000000000..2faa65f851
--- /dev/null
+++ b/support/dktools/modsnmp.sed
@@ -0,0 +1,3 @@
+s/\-lsocket//g
+s/\-lnsl//g
+s/\-lm//g
diff --git a/support/dktools/pjsnmp.c b/support/dktools/pjsnmp.c
new file mode 100644
index 0000000000..4dab12c63f
--- /dev/null
+++ b/support/dktools/pjsnmp.c
@@ -0,0 +1,6379 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: pjsnmp.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file pjsnmp.c The pjsnmp module.
+*/
+
+
+#line 10 "pjsnmp.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_LIBNETSNMP && ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET))
+
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/utilities.h>
+#include <net-snmp/library/snmp_logging.h>
+
+#include "dk4types.h"
+#include "dk4inst.h"
+#include "dk4maasz.h"
+#include "dk4maadu.h"
+#include "dk4mem.h"
+#include "dk4sto.h"
+#include "dk4str8.h"
+#include "dk4fopc8.h"
+#include "dk4stat.h"
+#include "dk4stat8.h"
+#include "dk4mai8dus.h"
+#include "dk4mai8huc.h"
+#include "dk4mai8dii.h"
+#include "dk4mai8ddu.h"
+#include "dk4mao8d.h"
+#include "dk4mao8h.h"
+#include "dk4time.h"
+#include "dk4time08.h"
+#include "dk4sock.h"
+#include "dk4isadm.h"
+#include "dk4lprng.h"
+
+
+
+
+
+#line 48 "pjsnmp.ctr"
+
+#endif
+/* if DK4_HAVE_LIBNETSNMP && ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET)) */
+
+
+
+/** One status text entry from SNMP model.
+*/
+typedef struct {
+ unsigned char *text; /**< Text pointer, not 0-terminated. */
+ size_t size; /**< Text size. */
+ int state; /**< Summary state if text was found. */
+ int start; /**< Flag: Text here is start text only. */
+} status_text_t;
+
+
+#if DK4_HAVE_LIBNETSNMP && ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET))
+
+
+/** SNMP device status.
+*/
+enum {
+ SNMP_DEVST_UNKNOWN = 1 , /**< Status is unknown. */
+
+ SNMP_DEVST_RUNNING = 2 , /**< Running. */
+
+ SNMP_DEVST_WARNING = 3 , /**< Warning condition active. */
+
+ SNMP_DEVST_TESTING = 4 , /**< In self test. */
+
+ SNMP_DEVST_DOWN = 5 /**< Down due to error condition. */
+};
+
+
+/** SNMP printer status.
+*/
+enum {
+ SNMP_PRST_OTHER = 1 , /**< Any state not mentioned below. */
+
+ SNMP_PRST_UNKNOWN = 2 , /**< Unknown. */
+
+ SNMP_PRST_IDLE = 3 , /**< Ready, waiting for next job. */
+
+ SNMP_PRST_PRINTING = 4 , /**< Printing a job. */
+
+ SNMP_PRST_WARMUP = 5 /**< Warming up. */
+};
+
+
+/** State summary.
+ For accounting we would only need to distinguish between
+ standby/idle (secure to retrieve page counter) and anything
+ else.
+ But we want to print human readable state summaries to status
+ file which are shown by lpq -L.
+*/
+enum {
+ PJSNMP_ST_UNKNOWN = 0 , /**< Failed to retrieve printer state. */
+
+ PJSNMP_ST_UNREACHABLE = 1 , /**< Printer is unreachable. */
+
+ PJSNMP_ST_ERROR = 2 , /**< Error state on printer. */
+
+ PJSNMP_ST_BUSY = 3 , /**< Printer is printing. */
+
+ PJSNMP_ST_IDLE = 4 , /**< Printer idle, can retrieve page counter. */
+
+ PJSNMP_ST_WARMUP = 5 , /**< Warming up. */
+
+ PJSNMP_ST_STANDBY = 6 , /**< Standby. */
+};
+
+
+/** @defgroup pdes Printer detected error states.
+ The first byte in the octet string is the most significant byte
+ in the unsigned long value.
+*/
+/**@{*/
+/** Warning: Paper low.
+*/
+#define PDES_WARNING_PAPER_LOW 0x80000000UL
+
+/** Error: Out of paper.
+*/
+#define PDES_ERROR_NO_PAPER 0x40000000UL
+
+/** Warning: Toner low.
+*/
+#define PDES_WARNING_TONER_LOW 0x20000000UL
+
+/** Error: Out of toner.
+*/
+#define PDES_ERROR_NO_TONER 0x10000000UL
+
+/** Error: Door open.
+*/
+#define PDES_ERROR_DOOR_OPEN 0x08000000UL
+
+/** Error: Paper jam.
+*/
+#define PDES_ERROR_PAPER_JAM 0x04000000UL
+
+/** Error: Printer offline.
+*/
+#define PDES_ERROR_OFFLINE 0x02000000UL
+
+/** Warning: Service requested.
+*/
+#define PDES_WARNING_SERVICE 0x01000000UL
+
+/** Input tray removed.
+*/
+#define PDES_ERROR_INPUT_TRAY_MISSING 0x00800000UL
+
+/** Output tray removed.
+*/
+#define PDES_ERROR_OUTPUT_TRAY_MISSING 0x00400000UL
+
+/** Marker supply missing.
+*/
+#define PDES_ERROR_MARKER_SUPPLY_MISSING 0x00200000UL
+
+/** Output tray nearly full.
+*/
+#define PDES_WARNING_OUTPUT_NEAR_FULL 0x00100000UL
+
+/** Output tray full.
+*/
+#define PDES_ERROR_OUTPUT_FULL 0x00080000UL
+
+/** At least one input tray empty.
+*/
+#define PDES_WARNING_INPUT_TRAY_EMPTY 0x00040000UL
+
+/** Overdue preventive maintenance.
+*/
+#define PDES_WARNING_OVERDUE_PREVENT_MAINT 0x00020000UL
+
+
+/** Bitmask to check if there is any error condition.
+*/
+#define PDES_ANY_ERROR \
+( PDES_ERROR_NO_PAPER \
+| PDES_ERROR_NO_TONER \
+| PDES_ERROR_DOOR_OPEN \
+| PDES_ERROR_PAPER_JAM \
+| PDES_ERROR_OFFLINE \
+| PDES_ERROR_INPUT_TRAY_MISSING \
+| PDES_ERROR_OUTPUT_TRAY_MISSING \
+| PDES_ERROR_MARKER_SUPPLY_MISSING \
+| PDES_ERROR_OUTPUT_FULL)
+
+
+/** Bitmask to check if there is any warning condition.
+*/
+#define PDES_ANY_WARNING \
+( PDES_WARNING_PAPER_LOW \
+| PDES_WARNING_TONER_LOW \
+| PDES_WARNING_SERVICE \
+| PDES_WARNING_OUTPUT_NEAR_FULL \
+| PDES_WARNING_OVERDUE_PREVENT_MAINT \
+| PDES_WARNING_INPUT_TRAY_EMPTY)
+
+
+/** Bitmask to check whether any error or warning condition is set.
+*/
+#define PDES_ANY_CONDITION ((PDES_ANY_WARNING) | (PDES_ANY_ERROR))
+
+/**@}*/
+
+
+/** Buffer for sending.
+ Should be large to minimize number of I/O operations.
+*/
+#if DK4_SIZEOF_SIZE_T > 2
+static char pjsnmp_buf[1048576];
+#else
+static char pjsnmp_buf[16384];
+#endif
+
+
+/** Current status text, also used in accounting.
+*/
+static char stat_text[2048];
+
+
+/** Buffer for responses from printer.
+*/
+static char dummy_text[2048];
+
+
+/** Previous status text.
+*/
+static char ostat_text[sizeof(stat_text)];
+
+
+/** Buffer for automatically constructed job name.
+*/
+static char job_name_buf[32+(8*sizeof(dk4_um_t))];
+
+
+/** Status text oid.
+*/
+static oid oid_st[MAX_OID_LEN];
+
+
+/** OID for device status.
+*/
+static const oid oid_ds[] = {
+ (oid)1, (oid)3, (oid)6, (oid)1, (oid)2, (oid)1,
+ (oid)25, (oid)3, (oid)2, (oid)1, (oid)5, (oid)1
+};
+
+
+/** OID for printer status.
+*/
+static const oid oid_ps[] = {
+ (oid)1, (oid)3, (oid)6, (oid)1, (oid)2, (oid)1,
+ (oid)25, (oid)3, (oid)5, (oid)1, (oid)1, (oid)1
+};
+
+
+/** OID for pagecount value.
+*/
+static const oid oid_pc[] = {
+ (oid)1, (oid)3, (oid)6, (oid)1, (oid)2, (oid)1,
+ (oid)43, (oid)10, (oid)2, (oid)1, (oid)4, (oid)1, (oid)1
+};
+
+
+/** OID for printer detected error state.
+*/
+static const oid oid_pe[] = {
+ (oid)1, (oid)3, (oid)6, (oid)1, (oid)2, (oid)1,
+ (oid)25, (oid)3, (oid)5, (oid)1, (oid)2, (oid)1
+};
+
+
+/** Default OID for status text.
+*/
+static const oid oid_dst[] = {
+ (oid)1, (oid)3, (oid)6, (oid)1, (oid)2, (oid)1,
+ (oid)43, (oid)16, (oid)5, (oid)1, (oid)2, (oid)1, (oid)1
+};
+
+
+/** Constant texts, not localized.
+*/
+static const char * const pjsnmp_kw[] = {
+/* 0 */
+"\n",
+
+/* 1 */
+" ",
+
+/* 2 */
+"PRINTCAP_ENTRY",
+
+/* 3 */
+"*",
+
+/* 4 */
+"pjsnmp",
+
+/* 5 */
+"public",
+
+/* 6 */
+"acct-check",
+
+/* 7 */
+"Device and printer status: ",
+
+/* 8 */
+"/",
+
+/* 9 */
+"Printer detected error state: ",
+
+/* 10 */
+"Current printer state: ",
+
+/* 11 */
+"not found",
+
+/* 12 */
+"unknown",
+
+/* 13 */
+"running",
+
+/* 14 */
+"warning",
+
+/* 15 */
+"testing",
+
+/* 16 */
+"down",
+
+/* 17 */
+"not found",
+
+/* 18 */
+"other",
+
+/* 19 */
+"unknown",
+
+/* 20 */
+"idle",
+
+/* 21 */
+"printing",
+
+/* 22 */
+"warmup",
+
+/* 23 */
+"UNKNOWN",
+
+/* 24 */
+"UNREACHABLE",
+
+/* 25 */
+"ERROR",
+
+/* 26 */
+"BUSY",
+
+/* 27 */
+"IDLE",
+
+/* 28 */
+"WARMUP",
+
+/* 29 */
+"STANDBY",
+
+/* 30 */
+"\"",
+
+/* 31 */
+"\"\n",
+
+/* 32 */
+"ERROR: ",
+
+/* 33 */
+"Warning: ",
+
+/* 34 */
+"Paper low (printer will run out of paper soon).\n",
+
+/* 35 */
+"Out of paper!\n",
+
+/* 36 */
+"Toner low (printer will run out of toner soon).\n",
+
+/* 37 */
+"Out of toner!\n",
+
+/* 38 */
+"Door open!\n",
+
+/* 39 */
+"Paper jam!\n",
+
+/* 40 */
+"Offline!\n",
+
+/* 41 */
+"Service requested.\n",
+
+/* 42 */
+"Input tray missing!\n",
+
+/* 43 */
+"Output tray missing!\n",
+
+/* 44 */
+"Marker supply missing!\n",
+
+/* 45 */
+"Output tray nearly full (will be full soon).\n",
+
+/* 46 */
+"Output tray full!\n",
+
+/* 47 */
+"At least one input tray is empty.\n",
+
+/* 48 */
+"Overdue preventive maintenance.\n",
+
+/* 49 */
+"ERROR ON PRINTER, MANUAL INTERVENTION REQUIRED!\n",
+
+/* 50 */
+"PRINTER PROBABLY REQUIRES MANUAL INTERVENTION!\n",
+
+/* 51 */
+"acct-start",
+
+/* 52 */
+"acct-end",
+
+/* 53 */
+"acct-charge",
+
+/* 54 */
+"print-job",
+
+/* 55 */
+"Print job finished.\n",
+
+/* 56 */
+"Job size: ",
+
+/* 57 */
+"Data transfer: ",
+
+/* 58 */
+"Processing: ",
+
+/* 59 */
+"Pages: ",
+
+/* 60 */
+" bytes\n",
+
+/* 61 */
+" seconds\n",
+
+/* 62 */
+"# ",
+
+/* 63 */
+"Configuration problem (command line arguments)!\n",
+
+/* 64 */
+"Configuration problem (printcap file)!\n",
+
+/* 65 */
+"Configuration problem (SNMP model file)!\n",
+
+/* 66 */
+"ERROR: Missing option name!\n",
+
+/* 67 */
+"ERROR: Missing option argument!\n",
+
+/* 68 */
+"ERROR: Non-option command line argument found!\n",
+
+/* 69 */
+"ERROR: No user name specified!\n",
+
+/* 70 */
+"ERROR: No print queue name specified!\n",
+
+/* 71 */
+"ERROR: No print job name specified!\n",
+
+/* 72 */
+"Warning: Redefinition of \"",
+
+/* 73 */
+"\" to \"",
+
+/* 74 */
+"\"!\n",
+
+/* 75 */
+"ERROR: Empty text for option \"",
+
+/* 76 */
+"\"!\n",
+
+/* 77 */
+"ERROR: Missing text for \"",
+
+/* 78 */
+"\"!\n",
+
+/* 79 */
+"ERROR: Option \"",
+
+/* 80 */
+"\" requires unsigned short number!\nIllegal text: \"",
+
+/* 81 */
+"\"!",
+
+/* 82 */
+"ERROR: Illegal SNMP version: \"",
+
+/* 83 */
+"\"!\nAllowed: \"1\", \"2c\", \"3\"!\n",
+
+/* 84 */
+"ERROR: Option \"",
+
+/* 85 */
+"\" requires an integer value!\nIllegal text: \"",
+
+/* 86 */
+"\"!\n",
+
+/* 87 */
+"ERROR: Missing \"]\"!\n",
+
+/* 88 */
+"ERROR: Missing model name!\n",
+
+/* 89 */
+"ERROR: Illegal summary state: \"",
+
+/* 90 */
+"\"!\n",
+
+/* 91 */
+"ERROR: Illegal printer status name: \"",
+
+/* 92 */
+"\"!\n",
+
+/* 93 */
+"ERROR: Illegal device status name: \"",
+
+/* 94 */
+"\"!",
+
+/* 95 */
+"ERROR: Missing printer status name!\n",
+
+/* 96 */
+"ERROR: Missing summary state name!\n",
+
+/* 97 */
+"ERROR: Illegal condition name: \"",
+
+/* 98 */
+"\"!\n",
+
+/* 99 */
+"ERROR: OID too long!\n",
+
+/* 100 */
+"ERROR: Numeric overflow for sub id: \"",
+
+/* 101 */
+"\"!\n",
+
+/* 102 */
+"ERROR: Not a number: \"",
+
+/* 103 */
+"\"!\n",
+
+/* 104 */
+"ERROR: Empty OID text!\n",
+
+/* 105 */
+"ERROR: Memory allocation failed!\n",
+
+/* 106 */
+"ERROR: Empty string!\n",
+
+/* 107 */
+"ERROR: Incorrect string specification!\n",
+
+/* 108 */
+"ERROR: Not a hexadecimal byte: \"",
+
+/* 109 */
+"\"!\n",
+
+/* 110 */
+"ERROR: Value required!\n",
+
+/* 111 */
+"ERROR: Not a boolean: \"",
+
+/* 112 */
+"\"!\n",
+
+/* 113 */
+"ERROR: Illegal key: \"",
+
+/* 114 */
+"\"!\n",
+
+/* 115 */
+"ERROR: Model not found: \"",
+
+/* 116 */
+"\"!\n",
+
+/* 117 */
+"ERROR: Failed to open model file!\n\"",
+
+/* 118 */
+"\"!\n",
+
+/* 119 */
+"ERROR: Missing host name for printer!\n",
+
+/* 120 */
+"ERROR: PRINTCAP_ENTRY not found in environment!\n",
+
+/* 121 */
+"ERROR: Failed to create SNMP session!\n",
+
+/* 122 */
+"ERROR: Failed to send data to accounting system!\n",
+
+/* 123 */
+"ERROR: Partial success when sending data to accounting system!\n",
+
+/* 124 */
+"ERROR: Failed to shut down accounting socket!\n",
+
+/* 125 */
+"ERROR: Failed to connect to accounting system!\n",
+
+/* 126 */
+"ERROR: Failed to start accounting program!\n",
+
+/* 127 */
+"ERROR: Missing command name for accounting program!\n",
+
+/* 128 */
+"ERROR: Failed to open accounting file!\n",
+
+/* 129 */
+"ERROR: Can not receive response from pipe!\n",
+
+/* 130 */
+"ERROR: Can not receive response from file!\n",
+
+/* 131 */
+"Checking permission: user=\"",
+
+/* 132 */
+"\" printer=\"",
+
+/* 133 */
+"\".\n",
+
+/* 134 */
+"Printing allowed.\n",
+
+/* 135 */
+"ERROR: PRINTING DENIED BY ACCOUNTING/QUOTA SYSTEM!\n",
+
+/* 136 */
+"ERROR: Printer unreachable too long!\n",
+
+/* 137 */
+"ERROR: Network connection not writeable (timeout)!\n",
+
+/* 138 */
+"ERROR: Failed to send data!\n",
+
+/* 139 */
+"ERROR: Failed to read print data from standard input!\n",
+
+/* 140 */
+"ERROR: Failed to connect to printer!\n",
+
+/* 141 */
+"ERROR: Failed to set up signal handlers!\n",
+
+/* 142 */
+"ERROR: Failed to restore signal handlers!\n",
+
+/* 143 */
+":",
+
+/* 144 */
+"",
+
+/* 145 */
+"Retrieving page counter at start.\n",
+
+/* 146 */
+"Retrieving page counter at end.\n",
+
+/* 147 */
+"Page counter at start: ",
+
+/* 148 */
+"Page counter at end: ",
+
+/* 149 */
+"Failed to retrieve page counter value!\n",
+
+/* 150 */
+"---\n",
+
+/* 151 */
+"Starting print data transfer.\n",
+
+/* 152 */
+"Finished print data transfer.\n",
+
+/* 153 */
+"Print data transfer aborted.\n",
+
+/* 154 */
+"Transmitting accounting data via network socket.\n",
+
+/* 155 */
+"Writing accounting data pipe.\n",
+
+/* 156 */
+"Transmitting accounting data via local socket.\n",
+
+/* 157 */
+"Writing accounting data to file.\n",
+
+/* 158 */
+"Transmitting accounting data to fd 3.\n",
+
+/* 159 */
+"Accounting data transmitted successfully.\n",
+
+/* 160 */
+"ERROR: Failed to transmit accounting data!\n",
+
+/* 161 */
+"\" requires an unsigned integer value!\nIllegal text: \"",
+
+/* 162 */
+"Warning: Unusual change to idle/standby state.\nWaiting ",
+
+/* 163 */
+" seconds ",
+
+/* 164 */
+"for printer to resume printing.\n",
+
+/* 165 */
+"ERROR: No accounting destination configured!\n",
+
+/* 166 */
+"Response from accounting system: \"",
+
+/* 167 */
+"\".\n",
+
+/* 168 */
+"Printer in error state too long!\n",
+
+/* 169 */
+"Command line arguments:\n",
+
+/* 170 */
+"ERROR: Failed to initialize socket subsystem!\n",
+
+/* 171 */
+"pjsnmp@localhost+",
+
+NULL
+
+
+#line 744 "pjsnmp.ctr"
+};
+
+
+
+/** Responses from accounting system.
+*/
+static const char * const accounting_responses[] = {
+/* 0 */
+"ACCEPT",
+
+/* 1 */
+"HOLD",
+
+/* 2 */
+"REMOVE",
+
+NULL
+
+
+#line 756 "pjsnmp.ctr"
+};
+
+
+
+/** Names for configuration items in the printcap entry.
+*/
+static const char * const printcap_entry_names[] = {
+/* 0 */
+"pjsnmp-host",
+
+/* 1 */
+"pjsnmp-port",
+
+/* 2 */
+"pjsnmp-ordrel",
+
+/* 3 */
+"pjsnmp-accounting-enable",
+
+/* 4 */
+"pjsnmp-accounting-check",
+
+/* 5 */
+"pjsnmp-accounting-file",
+
+/* 6 */
+"pjsnmp-accounting-host",
+
+/* 7 */
+"pjsnmp-accounting-port",
+
+/* 8 */
+"pjsnmp-require-printing",
+
+/* 9 */
+"pjsnmp-version",
+
+/* 10 */
+"pjsnmp-community",
+
+/* 11 */
+"pjsnmp-during-transfer",
+
+/* 12 */
+"pjsnmp-model-file",
+
+/* 13 */
+"pjsnmp-model-name",
+
+/* 14 */
+"pjsnmp-ignore-failed-session",
+
+/* 15 */
+"pjsnmp-allow-printing-if-accounting-connection-failed",
+
+/* 16 */
+"pjsnmp-pdes-always",
+
+/* 17 */
+"pjsnmp-unknown-busy",
+
+/* 18 */
+"pjsnmp-unreachable-timeout-start",
+
+/* 19 */
+"pjsnmp-unreachable-timeout-end",
+
+/* 20 */
+"pjsnmp-unreachable-timeout-printing",
+
+/* 21 */
+"pjsnmp-local-port",
+
+/* 22 */
+"pjsnmp-unwriteable-timeout-printing",
+
+/* 23 */
+"pjsnmp-read-response",
+
+/* 24 */
+"pjsnmp-force-printable-status-text",
+
+/* 25 */
+"pjsnmp-error-timeout-start",
+
+/* 26 */
+"pjsnmp-error-timeout-end",
+
+/* 27 */
+"pjsnmp-error-timeout-printing",
+
+/* 28 */
+"pjsnmp-verbose",
+
+/* 29 */
+"pjsnmp-non-ascii-job-title",
+
+/* 30 */
+"pjsnmp-accounting-start-end",
+
+NULL
+
+
+#line 891 "pjsnmp.ctr"
+};
+
+
+/** SNMP version names, 2 and 2c are the same.
+*/
+static const char * const snmp_version_names[] = {
+/* 0 */
+"1",
+
+/* 1 */
+"2",
+
+/* 2 */
+"2c",
+
+/* 3 */
+"3",
+
+NULL
+
+
+#line 903 "pjsnmp.ctr"
+};
+
+
+/** Keywords used in the SNMP models file.
+*/
+static const char * const model_keys[] = {
+/* 0 */
+"map",
+
+/* 1 */
+"error condition",
+
+/* 2 */
+"add error condition",
+
+/* 3 */
+"status text oid",
+
+/* 4 */
+"text standby",
+
+/* 5 */
+"start standby",
+
+/* 6 */
+"text idle",
+
+/* 7 */
+"start idle",
+
+/* 8 */
+"always use status text",
+
+/* 9 */
+"text busy",
+
+/* 10 */
+"start busy",
+
+/* 11 */
+"text unknown",
+
+/* 12 */
+"start unknown",
+
+/* 13 */
+"text error",
+
+/* 14 */
+"start error",
+
+/* 15 */
+"text warmup",
+
+/* 16 */
+"start warmup",
+
+NULL
+
+
+#line 939 "pjsnmp.ctr"
+};
+
+
+/** Summary state keywords used in the models file, can be abbreviated.
+*/
+static const char * const summary_state_names[] = {
+/* 0 */
+"u$nknown",
+
+/* 1 */
+"e$rror",
+
+/* 2 */
+"b$usy",
+
+/* 3 */
+"i$dle",
+
+/* 4 */
+"w$armup",
+
+/* 5 */
+"s$tandby",
+
+NULL
+
+
+#line 953 "pjsnmp.ctr"
+};
+
+
+/** Device status names, can be abbreviated.
+*/
+static const char * const device_status_names[] = {
+/* 0 */
+"u$nknown",
+
+/* 1 */
+"r$unning",
+
+/* 2 */
+"w$arning",
+
+/* 3 */
+"t$esting",
+
+/* 4 */
+"d$own",
+
+NULL
+
+
+#line 966 "pjsnmp.ctr"
+};
+
+
+/** Printer status names, can be abbreviated.
+*/
+static const char * const printer_status_names[] = {
+/* 0 */
+"o$ther",
+
+/* 1 */
+"u$nknown",
+
+/* 2 */
+"i$dle",
+
+/* 3 */
+"p$rinting",
+
+/* 4 */
+"w$armup",
+
+NULL
+
+
+#line 979 "pjsnmp.ctr"
+};
+
+
+/** Names for the condition bits in the SNMP models file.
+*/
+static const char * const condition_names[] = {
+/* 0 */
+"low-paper",
+
+/* 1 */
+"no-paper",
+
+/* 2 */
+"low-toner",
+
+/* 3 */
+"no-toner",
+
+/* 4 */
+"door-open",
+
+/* 5 */
+"paper-jam",
+
+/* 6 */
+"offline",
+
+/* 7 */
+"service-requested",
+
+/* 8 */
+"input-tray-missing",
+
+/* 9 */
+"output-tray-missing",
+
+/* 10 */
+"marker-supply-missing",
+
+/* 11 */
+"output-near-full",
+
+/* 12 */
+"output-full",
+
+/* 13 */
+"input-tray-empty",
+
+/* 14 */
+"overdue-preventive-maintenance",
+
+NULL
+
+
+#line 1002 "pjsnmp.ctr"
+};
+
+
+/** Default configuration file for SNMP models.
+*/
+static const char def_model_file[] = {
+DK4_INST_DIR_SHARE "/dktools/print-snmp.conf"
+};
+
+
+/** Option values for uppercase options.
+*/
+static char *upper[] = {
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+};
+
+
+/** Option values for lowercase options.
+*/
+static char *lower[] = {
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+};
+
+
+/** Mapping from device/printer status combinations to short summaries.
+*/
+static int summary_states[] = {
+ /* unknown-other */ PJSNMP_ST_UNKNOWN ,
+ /* unknown-unknown */ PJSNMP_ST_UNKNOWN ,
+ /* unknown-idle */ PJSNMP_ST_UNKNOWN ,
+ /* unknown-printing */ PJSNMP_ST_UNKNOWN ,
+ /* unknown-warmup */ PJSNMP_ST_WARMUP ,
+
+ /* running-other */ PJSNMP_ST_STANDBY ,
+ /* running-unknown */ PJSNMP_ST_UNKNOWN ,
+ /* running-idle */ PJSNMP_ST_IDLE ,
+ /* running-printing */ PJSNMP_ST_BUSY ,
+ /* running-warmup */ PJSNMP_ST_WARMUP ,
+
+ /* warning-other */ PJSNMP_ST_STANDBY ,
+ /* warning-unknown */ PJSNMP_ST_UNKNOWN ,
+ /* warning-idle */ PJSNMP_ST_IDLE ,
+ /* warning-printing */ PJSNMP_ST_BUSY ,
+ /* warning-warmup */ PJSNMP_ST_WARMUP ,
+
+ /* testing-other */ PJSNMP_ST_UNKNOWN ,
+ /* testing-unknown */ PJSNMP_ST_UNKNOWN ,
+ /* testing-idle */ PJSNMP_ST_UNKNOWN ,
+ /* testing-printing */ PJSNMP_ST_UNKNOWN ,
+ /* testing-warmup */ PJSNMP_ST_WARMUP ,
+
+ /* down-other */ PJSNMP_ST_ERROR ,
+ /* down-unknown */ PJSNMP_ST_ERROR ,
+ /* down-idle */ PJSNMP_ST_ERROR ,
+ /* down-printing */ PJSNMP_ST_ERROR ,
+ /* down-warmup */ PJSNMP_ST_WARMUP
+};
+
+
+
+/** Error report for number of bytes transferred.
+*/
+static dk4_er_t er_bytes;
+
+
+/** Copy of the printcap entry from PRINTCAP_ENTRY environment variable
+ (allocated, freed during cleanup before exit).
+*/
+static char *printcap_entry = NULL;
+
+
+/** Printer host name (from printcap entry).
+*/
+static char *host_name = NULL;
+
+
+/** User name to be charged for the job (from -n or -L option).
+*/
+static char *user_name = NULL;
+
+
+/** Print queue name (from -P or -Q option).
+*/
+static char *queue_name = NULL;
+
+
+/** Job title (from -J -f or -N option).
+*/
+static char *job_title = NULL;
+
+
+/** Job name from -A -j -t or -D option
+ (only needed for old accounting system).
+*/
+static char *job_name = NULL;
+
+
+/** File, socket, pipe or host name for accounting
+ (from pjsnmp-accounting-file in printcap entry).
+*/
+static char *acct_name = NULL;
+
+
+/** Host to connect to for accounting
+ (from pjsnmp-accounting-host in printcap entry).
+*/
+static char *acct_host = NULL;
+
+
+/** SNMP community name
+ (from pjsnmp-community in printcap entry).
+*/
+static char *snmp_comm = NULL;
+
+
+/** File name containing SNMP models
+ (from pjsnmp-model-file in printcap entry).
+*/
+static char *model_file = NULL;
+
+
+/** SNMP model name (from pjsnmp-model-name in printcap entry).
+*/
+static char *model_name = NULL;
+
+
+/** Status file for log messages (name obtained from -s cmd arg).
+*/
+static FILE *stt_file = NULL;
+
+
+/** Output file to use for log messages.
+ This is either stt_file or stderr, but never NULL.
+*/
+static FILE *out_file = NULL;
+
+
+/** SNMP session.
+*/
+static struct snmp_session *snmp_sess = NULL;
+
+
+/** Storage for status text nodes.
+*/
+static dk4_sto_t *s_stn = NULL;
+
+
+/** Iterator through storage above.
+*/
+static dk4_sto_it_t *i_stn = NULL;
+
+
+/** Number of bytes transferred.
+*/
+static dk4_um_t bytes_trans = (dk4_um_t)0UL;
+
+
+/** Timeout if printer not seen printing
+ (from pjsnmp-require-printing in printcap entry).
+ If the first page contains a complicated graphics it
+ might take a longer time to start printing.
+*/
+static dk4_um_t print_timeout = (dk4_um_t)600UL;
+
+
+/** Timeout if printer is unreachable at start of print job
+ (from pjsnmp-unreachable-timeout-start in printcap entry).
+*/
+static dk4_um_t unto_start = (dk4_um_t)900UL;
+
+
+/** Timeout if printer is unreachable during data transfer
+ (from pjsnmp-unreachable-timeout-printing in printcap entry).
+*/
+static dk4_um_t unto_print = (dk4_um_t)120UL;
+
+/** Timeout if printer socket is unwriteable during data transfer
+ (from pjsnmp-unwriteable-timeout-printing in printcap entry).
+*/
+static dk4_um_t unwt_print = (dk4_um_t)900UL;
+
+/** Timeout if printer is unreachable at end of print job
+ (from pjsnmp-unreachable-timeout-end in printcap entry).
+*/
+static dk4_um_t unto_end = (dk4_um_t)120UL;
+
+/** Timeout for error condition before printing to skip job.
+*/
+static dk4_um_t erto_start = (dk4_um_t)900UL;
+
+/** Timeout if printer is in error state during printing.
+*/
+static dk4_um_t erto_print = (dk4_um_t)86400UL;
+
+/** Timeout if printer is in error state after job.
+*/
+static dk4_um_t erto_end = (dk4_um_t)3600UL;
+
+/** Start time printer gone unreachable.
+*/
+static dk4_time_t start_unreach = (dk4_time_t)0UL;
+
+/** Start time printer gone error.
+*/
+static dk4_time_t start_error = (dk4_time_t)0UL;
+
+
+/** Size of device status OID (number of elements).
+*/
+static const size_t sz_oid_ds = sizeof(oid_ds)/sizeof(oid);
+
+
+/** Size of device status OID (number of bytes).
+*/
+static const size_t by_oid_ds = sizeof(oid_ds);
+
+
+/** Size of printer status OID (number of elements).
+*/
+static const size_t sz_oid_ps = sizeof(oid_ps)/sizeof(oid);
+
+
+/** Size of printer status OID (number of bytes).
+*/
+static const size_t by_oid_ps = sizeof(oid_ps);
+
+
+/** Size of page counter OID (number of elements).
+*/
+static const size_t sz_oid_pc = sizeof(oid_pc)/sizeof(oid);
+
+
+/** Size of page counter OID (number of bytes).
+*/
+static const size_t by_oid_pc = sizeof(oid_pc);
+
+
+/** Size of printer error OID (number of elements).
+*/
+static const size_t sz_oid_pe = sizeof(oid_pe)/sizeof(oid);
+
+
+/** Size of printer error OID (number of bytes).
+*/
+static const size_t by_oid_pe = sizeof(oid_pe);
+
+
+/** Size of printer error OID (number of elements).
+*/
+static const size_t sz_oid_dst = sizeof(oid_dst)/sizeof(oid);
+
+
+/** Size of printer error OID (number of bytes).
+*/
+static const size_t by_oid_dst = sizeof(oid_dst);
+
+
+/** Number of items in status text OID.
+*/
+static size_t sz_oid_st = sizeof(oid_dst)/sizeof(oid);
+
+
+/** Number of bytes in status text OID.
+*/
+static size_t by_oid_st = sizeof(oid_dst);
+
+
+/** Number of bytes currently stored in stat_text.
+*/
+static size_t sz_stat_text = 0;
+
+
+/** Number of bytes stored in ostat_text.
+*/
+static size_t sz_ostat_text = 0;
+
+
+/** Start of program.
+*/
+static dk4_time_t t1 = (dk4_time_t)0UL;
+
+
+/** Start of data transfer.
+*/
+static dk4_time_t t2 = (dk4_time_t)0UL;
+
+
+/** End of data transfer.
+*/
+static dk4_time_t t3 = (dk4_time_t)0UL;
+
+
+/** End of program.
+*/
+static dk4_time_t t4 = (dk4_time_t)0UL;
+
+
+/** SNMP version number (from pjsnmp-version in printcap entry).
+*/
+static long snmp_version = SNMP_VERSION_1;
+
+
+/** Bit mask to retrieve real error conditions from
+ hrPrinterDetectedErrorStates
+ (modified by error condition and add error condition in model).
+*/
+static unsigned long pdes_error = PDES_ANY_ERROR ;
+
+
+/** Previous printer detected error state conditions.
+*/
+static unsigned long opdes_cond = 0UL;
+
+
+/** Current printer detected error state conditions.
+*/
+static unsigned long pdes_cond = 0UL;
+
+
+/** Page counter at start of job.
+*/
+static unsigned long pc_start = 0UL;
+
+
+/** Unusable page counter value (start value or at last error).
+*/
+static unsigned long pc_error = 0UL;
+
+
+/** Page counter at end of job.
+*/
+static unsigned long pc_end = 0UL;
+
+
+/** Current page counter.
+*/
+static unsigned long pcnt = 0UL;
+
+
+#endif
+/* if DK4_HAVE_LIBNETSNMP && ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET)) */
+
+
+
+/** Exit status code, must be one from the enum.
+*/
+static int exval = LPRNG_EXIT_REMOVE;
+
+
+#if DK4_HAVE_LIBNETSNMP && ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET))
+
+
+/** Flag: Verbose
+*/
+static int verbose = 0;
+
+
+/** Flag: Allow non-ASCII characters in job title for accounting.
+*/
+static int allow_non_ascii = 0;
+
+
+/** Always use status text (default: only if summary is "unknown").
+*/
+static int stat_always = 0;
+
+
+/** Flag: Always use printer detected error state
+ (from pjsnmp-pdes-always in printcap entry), default: on.
+*/
+static int pdes_always = 1;
+
+
+/** Flag: Reset of pdes_error was done.
+*/
+static int pdes_reset = 0;
+
+
+/** Flag: Report unknown states as busy
+ (from pjsnmp-unknown-busy in printcap entry), default: off.
+*/
+static int unkn_busy = 0;
+
+
+/** Flag: Do orderly release (from pjsnmp-ordrel in printcap entry).
+*/
+static int host_ordr = 0;
+
+
+/** Flag: Accounting enabled
+ (from pjsnmp-accounting-enable in printcap entry).
+*/
+static int acct_enab = 0;
+
+
+/** Flag: Quota check enabled
+ (from pjsnmp-accounting-check in printcap entry).
+*/
+static int acct_achk = 0;
+
+
+/** Flag: Use separated start/end lines for accounting.
+ Default is to use just one charge line at end.
+*/
+static int acct_start_end = 0;
+
+
+/** Flag: Read printer responses
+ (from pjsnmp-read-response in printcap entry).
+*/
+static int read_responses = 0;
+
+
+/** Flag: Force printable status text
+ (from pjsnmp-force-printable-status-text in printcap entry).
+*/
+static int force_printable_status_text = 1;
+
+/** Flag: SNMP check during transfer
+ (from pjsnmp-during-transfer in printcap entry).
+*/
+static int check_trans = 1;
+
+
+/** Flag: EOF found on standard input.
+*/
+static int have_eof = 0;
+
+
+/** Ignore failed SNMP session
+ (from pjsnmp-ignore-failed-session in printcap entry).
+*/
+static int snmp_igfs = 0;
+
+
+/** Allow printing if accounting connection failed.
+ (from pjsnmp-allow-printing-if-accounting-connection-failed).
+*/
+static int acct_apcf = 0;
+
+
+/** Flag: Have page counter at start.
+*/
+static int have_pcs = 0;
+
+
+/** Flag: Have page counter at end.
+*/
+static int have_pce = 0;
+
+
+/** Previous device status.
+*/
+static int odevst = 0;
+
+
+/** Current device status.
+*/
+static int devst = 0;
+
+
+/** Previous printer status.
+*/
+static int oprist = 0;
+
+
+/** Current printer status.
+*/
+static int prist = 0;
+
+
+/** Previous summary status.
+*/
+static int ostsum = PJSNMP_ST_UNKNOWN;
+
+
+/** Current summary status.
+*/
+static int stsum = PJSNMP_ST_UNKNOWN;
+
+
+/** Flag: The printer was seen in printing state.
+ This flag is cleared if the printer was seen in error state,
+ as some printers go from error to printing via idle.
+*/
+static int seen_printing = 0;
+
+
+/** Last header used for log messages.
+*/
+static int last_header = 0;
+
+
+/** Decision from permission check
+ 0=unknown
+ 1=accept
+ 2=hold
+ 3=remove
+*/
+static int decision = 0;
+
+
+/** Port number to send data to in host representation
+ (from pjsnmp-port in printcap entry).
+*/
+static unsigned short host_port = 9100;
+
+
+/** Local port number.
+ (from pjsnmp-local-port in printcap entry).
+*/
+static unsigned short local_port = 0;
+
+
+/** Accounting port number in host representation
+ (from pjsnmp-accounting-port in printcap entry).
+*/
+static unsigned short acct_port = 9100;
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+/** Pass volatile pointer through to caller.
+ The CERT C coding standard recommends to set signal indicator
+ variables through pointers to avoid
+ compilers from optimizing too hard (they might attempt
+ to keep the value in a register although properly marked
+ as volatile).
+ @param ptr Address of volatile indicator variable.
+ @return Same pointer as ptr.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+
+/** Check whether we can continue or must abort due to signal.
+ @param dopipe Flag: Check for SIGPIPE too.
+ @return 1 if we can continue, 0 otherwise.
+*/
+static
+int
+can_continue(int dopipe)
+{
+ int back = 1;
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_int)) { back = 0; }
+#ifdef SIGPIPE
+ if (0 != dopipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ return back;
+}
+
+
+/** Log a timestamp.
+ @return 1 if time changed since previous log, 0 otherwise.
+*/
+static
+int
+log_timestamp(void)
+{
+ char buf[64];
+ static dk4_time_t previous_log = (dk4_time_t)0UL;
+ dk4_time_t current;
+ int back = 0;
+
+
+#line 1647 "pjsnmp.ctr"
+ dk4time_get(&current);
+ if (current != previous_log) {
+
+#line 1649 "pjsnmp.ctr"
+ if (dk4time_as_text_c8(buf, sizeof(buf), &current, NULL)) {
+ back = 1;
+
+#line 1651 "pjsnmp.ctr"
+ fputs(pjsnmp_kw[62], out_file);
+ fputs(buf, out_file);
+ fputs(pjsnmp_kw[0], out_file);
+ previous_log = current;
+ }
+ }
+
+#line 1657 "pjsnmp.ctr"
+ return back;
+}
+
+
+
+/** Log a 1 component message with header line.
+ @param h Header line chooser (1, 2 or 3).
+ @param i Index of message text in pjsnmp_kw.
+*/
+static
+void
+log_1_with_header(int h, size_t i)
+{
+ (void)log_timestamp();
+ if (last_header != h) {
+ fputs(pjsnmp_kw[62 + h], out_file);
+ last_header = h;
+ }
+ fputs(pjsnmp_kw[i], out_file);
+ fflush(out_file);
+}
+
+
+
+/** Log a 3 components message with header line.
+ @param h Header line chooser (1, 2 or 3).
+ @param i1 Index of first text component in pjsnmp_kw.
+ @param i2 Index of third text component in pjsnmp_kw.
+ @param s Second text component (variable text).
+*/
+static
+void
+log_3_with_header(int n, size_t i1, size_t i2, const char *s)
+{
+ (void)log_timestamp();
+ if (last_header != n) {
+ fputs(pjsnmp_kw[62 + n], out_file);
+ last_header = n;
+ }
+ fputs(pjsnmp_kw[i1], out_file);
+ if (NULL != s) { fputs(s, out_file); }
+ fputs(pjsnmp_kw[i2], out_file);
+ fflush(out_file);
+}
+
+
+
+/** Log a 5 components message with header line.
+ @param h Header line chooser (1, 2 or 3).
+ @param i1 Index of first text component in pjsnmp_kw.
+ @param i2 Index of third text component in pjsnmp_kw.
+ @param i3 Index of fifth text component in pjsnmp_kw.
+ @param s1 Second text component (variable text).
+ @param s2 Fourth text component (variable text).
+*/
+static
+void
+log_5_with_header(
+ int n,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ const char *s1,
+ const char *s2
+)
+{
+ (void)log_timestamp();
+ if (last_header != n) {
+ fputs(pjsnmp_kw[62 + n], out_file);
+ last_header = n;
+ }
+ fputs(pjsnmp_kw[i1], out_file);
+ if (NULL != s1) { fputs(s1, out_file); }
+ fputs(pjsnmp_kw[i2], out_file);
+ if (NULL != s2) { fputs(s2, out_file); }
+ fputs(pjsnmp_kw[i3], out_file);
+ fflush(out_file);
+}
+
+
+
+/** Log a 1 component message without header line.
+ @param i Index of text component in pjsnmp_kw.
+*/
+static
+void
+log_1_no_header(size_t i)
+{
+
+
+#line 1746 "pjsnmp.ctr"
+ log_timestamp();
+ fputs(pjsnmp_kw[i], out_file);
+ fflush(out_file);
+
+
+#line 1750 "pjsnmp.ctr"
+}
+
+
+
+/** Log a 3 components message without header line.
+ @param i1 Index of first text component in pjsnmp_kw.
+ @param i2 Index of third text component in pjsnmp_kw.
+ @param s Second text component (variable text).
+*/
+static
+void
+log_3_no_header(size_t i1, size_t i2, const char *s)
+{
+
+
+#line 1764 "pjsnmp.ctr"
+ log_timestamp();
+ fputs(pjsnmp_kw[i1], out_file);
+ if (NULL != s) { fputs(s, out_file); }
+ fputs(pjsnmp_kw[i2], out_file);
+ fflush(out_file);
+
+
+#line 1770 "pjsnmp.ctr"
+}
+
+
+
+/** Log a 5 components message without header line.
+ @param i1 Index of first text component in pjsnmp_kw.
+ @param i2 Index of third text component in pjsnmp_kw.
+ @param i3 Index of fifth text component in pjsnmp_kw.
+ @param s1 Second text component (variable text).
+ @param s2 Fourth text component (variable text).
+*/
+static
+void
+log_5_no_header(
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ const char *s1,
+ const char *s2
+)
+{
+ log_timestamp();
+ fputs(pjsnmp_kw[i1], out_file);
+ if (NULL != s1) { fputs(s1, out_file); }
+ fputs(pjsnmp_kw[i2], out_file);
+ if (NULL != s2) { fputs(s2, out_file); }
+ fputs(pjsnmp_kw[i3], out_file);
+ fflush(out_file);
+}
+
+
+
+/** Log a 1 component message related to model file.
+ @param lineno Line number in model file to complain about.
+ @param i Index of first text component in pjsnmp_kw.
+*/
+static
+void
+log_model_1(dk4_um_t lineno, size_t i)
+{
+ char buf[8*sizeof(dk4_um_t)];
+ const char *fn;
+ const char *ptr;
+ int res;
+
+ (void)log_timestamp();
+ if (3 != last_header) {
+ last_header = 3;
+ fputs(pjsnmp_kw[65], out_file);
+ }
+ if ((dk4_um_t)0UL < lineno) {
+ res = dk4ma_write_c8_decimal_unsigned(buf, sizeof(buf), lineno, 0, NULL);
+ if (0 != res) {
+ fn = ((NULL != model_file) ? model_file : def_model_file);
+ ptr = dk4str8_rchr(fn, '/');
+ if (NULL != ptr) {
+ ptr++;
+ } else {
+ ptr = fn;
+ }
+ fputs(ptr, out_file);
+ fputs(pjsnmp_kw[143], out_file);
+ fputs(buf, out_file);
+ fputs(pjsnmp_kw[143], out_file);
+ fputs(pjsnmp_kw[1], out_file);
+ }
+ }
+ fputs(pjsnmp_kw[i], out_file);
+ fflush(out_file);
+}
+
+
+
+/** Log a 3 components message related to model file.
+ @param lineno Line number in model file to complain about.
+ @param i1 Index of first text component in pjsnmp_kw.
+ @param i2 Index of third text component in pjsnmp_kw.
+ @param s Second text component (variable text).
+*/
+static
+void
+log_model_3(
+ dk4_um_t lineno,
+ size_t i1,
+ size_t i2,
+ const char *s
+)
+{
+ char buf[8*sizeof(dk4_um_t)];
+ const char *fn;
+ const char *ptr;
+ int res;
+
+ (void)log_timestamp();
+ if (3 != last_header) {
+ last_header = 3;
+ fputs(pjsnmp_kw[65], out_file);
+ }
+ if ((dk4_um_t)0UL < lineno) {
+ res = dk4ma_write_c8_decimal_unsigned(buf, sizeof(buf), lineno, 0, NULL);
+ if (0 != res) {
+ fn = ((NULL != model_file) ? model_file : def_model_file);
+ ptr = dk4str8_rchr(fn, '/');
+ if (NULL != ptr) {
+ ptr++;
+ } else {
+ ptr = fn;
+ }
+ fputs(ptr, out_file);
+ fputs(pjsnmp_kw[143], out_file);
+ fputs(buf, out_file);
+ fputs(pjsnmp_kw[143], out_file);
+ fputs(pjsnmp_kw[1], out_file);
+ }
+ }
+ fputs(pjsnmp_kw[i1], out_file);
+ if (NULL != s) { fputs(s, out_file); }
+ fputs(pjsnmp_kw[i2], out_file);
+ fflush(out_file);
+}
+
+
+
+/** Create new status text node.
+ @param t Text, not 0-terminated.
+ @param tsz Text size.
+ @param st Summary state if text is found.
+ @param fl Flag: This is the start text only.
+ @return Valid pointer on success, NULL on error.
+*/
+static
+status_text_t *
+stt_new(
+ const unsigned char *t,
+ size_t tsz,
+ int st,
+ int fl
+)
+{
+ status_text_t *back = NULL;
+
+
+#line 1911 "pjsnmp.ctr"
+ if ((NULL != t) && (0 < tsz)) {
+ back = dk4mem_new(status_text_t,1,NULL);
+ if (NULL != back) {
+ DK4_MEMRES(back, sizeof(status_text_t));
+ back->start = fl;
+ back->state = st;
+ back->size = tsz;
+ back->text = dk4mem_new(unsigned char,tsz,NULL);
+ if (NULL != back->text) {
+ DK4_MEMCPY(back->text, t, tsz);
+ } else {
+
+#line 1922 "pjsnmp.ctr"
+ dk4mem_free(back);
+ back = NULL;
+ }
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 1928 "pjsnmp.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 1933 "pjsnmp.ctr"
+ }
+#endif
+
+
+#line 1936 "pjsnmp.ctr"
+ return back;
+}
+
+
+
+/** Destroy status text node, release memory.
+ @param ptr Node to destroy.
+*/
+static
+void
+stt_delete(status_text_t *ptr)
+{
+
+
+#line 1949 "pjsnmp.ctr"
+ if (NULL != ptr) {
+
+#line 1950 "pjsnmp.ctr"
+ dk4mem_release(ptr->text);
+ dk4mem_free(ptr);
+ }
+
+
+#line 1954 "pjsnmp.ctr"
+}
+
+
+
+/** Compare two status text nodes.
+ While building the storage the start flag is ignored.
+ When searching a text for a status text received via SNMP
+ we have to consider the flag.
+ @param l Left object.
+ @param r Right object.
+ @param cr Comparison criteria (0=build storage, 1=search).
+ @return Comparison result.
+*/
+static
+int
+stt_compare(const void *l, const void *r, int cr)
+{
+ const status_text_t *pl; /* Left operand */
+ const status_text_t *pr; /* Right operand */
+ size_t min; /* Minimum of both text sizes */
+ int back = 0;
+
+
+#line 1976 "pjsnmp.ctr"
+ if (NULL != l) {
+ if (NULL != r) {
+ pl = (const status_text_t *)l;
+ pr = (const status_text_t *)r;
+ min = pl->size;
+ if (min > pr->size) { min = pr->size; }
+ if (0 < min) {
+ back = dk4mem_cmp(pl->text, pr->text, min, NULL);
+ }
+ if (0 == back) {
+ if ((0 == cr) || (0 == pl->start)) {
+ if (pl->size > pr->size) {
+ back = 1;
+ } else {
+ if (pl->size < pr->size) {
+ back = -1;
+ }
+ }
+ }
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != r) {
+ back = -1;
+ }
+ }
+
+
+#line 2005 "pjsnmp.ctr"
+ return back;
+}
+
+
+
+/** Set one command line option.
+ @param Option character.
+ @param Option argument.
+*/
+static
+void
+set_option(char c, char *val)
+{
+ size_t sz = 0; /* Index of option in arguments array */
+
+
+#line 2020 "pjsnmp.ctr"
+ if (NULL != val) {
+ if (('a' <= c) && ('z' >= c)) {
+ sz = (size_t)(c - 'a');
+ if (DK4_SIZEOF(lower,DK4_PCHAR) > sz) {
+ lower[sz] = val;
+
+#line 2025 "pjsnmp.ctr"
+ }
+ } else {
+ if (('A' <= c) && ('Z' >= c)) {
+ sz = (size_t)(c - 'A');
+ if (DK4_SIZEOF(upper,DK4_PCHAR) > sz) {
+ upper[sz] = val;
+
+#line 2031 "pjsnmp.ctr"
+ }
+ }
+ }
+ }
+
+#line 2035 "pjsnmp.ctr"
+}
+
+
+
+/** Retrieve argument for one option.
+ @param c Option character (option name).
+ @return The value provided as option argument, NULL otherwise.
+*/
+static
+char *
+get_option(char c)
+{
+ char *back = NULL;
+ size_t sz = 0; /* Index of option in arguments array */
+
+
+#line 2050 "pjsnmp.ctr"
+ if (('a' <= c) && ('z' >= c)) {
+ sz = (size_t)(c - 'a');
+ if (DK4_SIZEOF(lower,DK4_PCHAR) > sz) {
+ back = lower[sz];
+ }
+ } else {
+ if (('A' <= c) && ('Z' >= c)) {
+ sz = (size_t)(c - 'A');
+ if (DK4_SIZEOF(upper,DK4_PCHAR) > sz) {
+ back = upper[sz];
+ }
+ }
+ }
+
+#line 2063 "pjsnmp.ctr"
+ return back;
+}
+
+
+
+/** Process command line arguments.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+process_command_line_arguments(int argc, char *argv[])
+{
+ char *curarg; /* Current argument to process */
+ char *s_name; /* Status file name */
+ size_t szjnb; /* Size of job name buffer */
+ int back = 1;
+ int i; /* Index of current argument */
+ int res; /* Result for number to text conversion */
+ char c; /* Option name */
+
+
+#line 2085 "pjsnmp.ctr"
+ for (i = 1; i < argc; i++) {
+ curarg = argv[i];
+
+#line 2087 "pjsnmp.ctr"
+ if ('-' == *curarg) {
+
+#line 2088 "pjsnmp.ctr"
+ curarg++;
+ if ('\0' != *curarg) {
+
+#line 2090 "pjsnmp.ctr"
+ c = *(curarg++);
+ if ('\0' != *curarg) {
+
+#line 2092 "pjsnmp.ctr"
+ set_option(c, curarg);
+ } else {
+
+#line 2094 "pjsnmp.ctr"
+#if VERSION_BEFORE_20160208
+ /* -c may appear without an argument.
+ */
+ back = 0;
+ /* ERROR: Missing option argument */
+ log_1_with_header(1, 67);
+#else
+ set_option(c, (char *)(pjsnmp_kw[144]));
+#endif
+ }
+ } else {
+
+#line 2105 "pjsnmp.ctr"
+ back = 0;
+ /* ERROR: Only minus */
+ log_1_with_header(1, 66);
+ }
+ } else {
+
+#line 2110 "pjsnmp.ctr"
+#if 0
+ /* 2016-02-15 Seeing non-option arguments is not an error,
+ the accounting file name is passed once
+ as argument to -a and once as file name.
+ */
+ back = 0;
+ /* ERROR: Non-option argument found */
+ log_1_with_header(1, 68);
+#endif
+ }
+ }
+ if (0 != back) {
+
+#line 2122 "pjsnmp.ctr"
+ s_name = get_option('s');
+ if (NULL != s_name) {
+
+#line 2124 "pjsnmp.ctr"
+ stt_file = fopen(s_name, "w");
+ if (NULL != stt_file) {
+
+#line 2126 "pjsnmp.ctr"
+ out_file = stt_file;
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 2130 "pjsnmp.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 2135 "pjsnmp.ctr"
+ }
+#endif
+ user_name = get_option('n');
+ if (NULL == user_name) user_name = get_option('L');
+ if (NULL != user_name) {
+ user_name = dk4str8_start(user_name, NULL);
+ }
+ if (NULL != user_name) {
+ (void)dk4str8_next(user_name, NULL);
+ if (0 == strlen(user_name)) { user_name = NULL; }
+ }
+ if (NULL == user_name) {
+
+#line 2147 "pjsnmp.ctr"
+ /* ERROR: No user name */
+ log_1_with_header(1, 69);
+ back = 0;
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 2153 "pjsnmp.ctr"
+ }
+#endif
+ if (0 != back) {
+
+#line 2156 "pjsnmp.ctr"
+ queue_name = get_option('P');
+ if (NULL == queue_name) queue_name = get_option('Q');
+ if (NULL != queue_name) {
+ queue_name = dk4str8_start(queue_name, NULL);
+ }
+ if (NULL != queue_name) {
+ (void)dk4str8_next(queue_name, NULL);
+ if (0 == strlen(queue_name)) { queue_name = NULL; }
+ }
+ if (NULL == queue_name) {
+
+#line 2166 "pjsnmp.ctr"
+ /* ERROR: No queue name */
+ log_1_with_header(1, 70);
+ back = 0;
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 2172 "pjsnmp.ctr"
+ }
+#endif
+ }
+ if (0 != back) {
+ job_name = get_option('A');
+
+#line 2177 "pjsnmp.ctr"
+ if (NULL == job_name) job_name = get_option('j');
+ if (NULL == job_name) job_name = get_option('t');
+ if (NULL == job_name) job_name = get_option('D');
+ if (NULL != job_name) {
+ job_name = dk4str8_start(job_name, NULL);
+ }
+ if (NULL != job_name) {
+ (void)dk4str8_next(job_name, NULL);
+ if (0 == strlen(job_name)) { job_name = NULL; }
+ }
+ if (NULL == job_name) {
+ szjnb = sizeof(job_name_buf);
+ if (0 != dk4str8_cpy_s(job_name_buf, szjnb, pjsnmp_kw[171], NULL)) {
+ res = dk4ma_write_c8_decimal_unsigned(
+ &(job_name_buf[strlen(job_name_buf)]),
+ (szjnb - strlen(job_name_buf)), (dk4_um_t)getpid(), 0, NULL
+ );
+ if (0 != res) {
+ job_name = job_name_buf;
+ }
+ }
+ }
+ if (NULL == job_name) {
+
+#line 2200 "pjsnmp.ctr"
+ /* ERROR: No job name */
+ log_1_with_header(1, 71);
+ back = 0;
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 2206 "pjsnmp.ctr"
+ }
+#endif
+ }
+ if (0 != back) {
+
+#line 2210 "pjsnmp.ctr"
+ job_title = get_option('J');
+ if (NULL == job_title) job_title = get_option('f');
+ if (NULL == job_title) job_title = get_option('N');
+ if (NULL != job_title) {
+ job_title = dk4str8_start(job_title, NULL);
+ }
+ if (NULL != job_title) {
+ dk4str8_normalize(job_title, NULL);
+ }
+#if 0
+ /* 20160206
+ Allow job_title to be NULL, pjsnmp_kw[54] is used instead.
+ */
+ if (NULL == job_title) {
+
+#line 2224 "pjsnmp.ctr"
+ back = 0;
+ }
+#endif
+#if TRACE_DEBUG
+ else {
+
+#line 2229 "pjsnmp.ctr"
+ }
+#endif
+ }
+ }
+
+
+#line 2234 "pjsnmp.ctr"
+ return back;
+}
+
+
+
+/** Set string pointer.
+ @param dptr Address of pointer to set.
+ @param src Value.
+ @param name Configuration entry name.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+set_string(char **dptr, char *src, const char *name)
+{
+ int back = 0;
+
+
+#line 2251 "pjsnmp.ctr"
+ if (NULL != src) {
+ src = dk4str8_start(src, NULL);
+ if (NULL != src) {
+
+#line 2254 "pjsnmp.ctr"
+ if (NULL != *dptr) {
+
+#line 2255 "pjsnmp.ctr"
+ /* WARNING: Redefinition */
+ log_5_with_header(2, 72, 73, 74, name, src);
+ }
+ *dptr = src;
+ back = 1;
+ } else {
+
+#line 2261 "pjsnmp.ctr"
+ /* ERROR: Empty text */
+ log_3_with_header(2, 75, 76, name);
+ }
+ } else {
+
+#line 2265 "pjsnmp.ctr"
+ /* ERROR: Text string required */
+ log_3_with_header(2, 77, 78, name);
+ }
+
+#line 2268 "pjsnmp.ctr"
+ return back;
+}
+
+
+
+/** Set unsigned short variable.
+ @param dptr Address of variable to set.
+ @param src Text containing the value.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+set_unsigned_short(unsigned short *dptr, char *src, const char *name)
+{
+ const char *ep = NULL; /* First unprocessabe char */
+ int back = 0;
+ int res; /* Operation result */
+ unsigned short us;
+
+
+#line 2287 "pjsnmp.ctr"
+ if (NULL != src) {
+ src = dk4str8_start(src, NULL);
+ if (NULL != src) {
+ res = dk4ma_input_c8_dec_ushort(&us, src, &ep, 1, NULL);
+ if (0 != res) {
+ *dptr = us;
+ back = 1;
+
+#line 2294 "pjsnmp.ctr"
+ } else {
+
+#line 2295 "pjsnmp.ctr"
+ /* ERROR: Not a number! */
+ log_5_with_header(2, 79, 80, 81, name, src);
+ }
+ } else {
+
+#line 2299 "pjsnmp.ctr"
+ /* ERROR: Empty text */
+ log_3_with_header(2, 75, 76, name);
+ }
+ } else {
+
+#line 2303 "pjsnmp.ctr"
+ /* ERROR: Numeric value required */
+ log_3_with_header(2, 77, 78, name);
+ }
+
+#line 2306 "pjsnmp.ctr"
+ return back;
+}
+
+
+
+/** Set SNMP version.
+ @param dptr Address of variable to set.
+ @param src Text containing the SNMP version.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+set_snmp_version(long *dptr, char *src)
+{
+ int back = 0;
+
+
+#line 2322 "pjsnmp.ctr"
+ if (NULL != src) {
+ src = dk4str8_start(src, NULL);
+ if (NULL != src) {
+ switch (dk4str8_array_index(snmp_version_names, src, 0)) {
+ case 0: {
+
+#line 2327 "pjsnmp.ctr"
+ *dptr = SNMP_VERSION_1;
+ back = 1;
+ } break;
+ case 1: case 2: {
+
+#line 2331 "pjsnmp.ctr"
+ *dptr = SNMP_VERSION_2c;
+ back = 1;
+ } break;
+ case 3: {
+
+#line 2335 "pjsnmp.ctr"
+ *dptr = SNMP_VERSION_3;
+ back = 1;
+ } break;
+ default: {
+
+#line 2339 "pjsnmp.ctr"
+ /* ERROR: Illegal SNMP version */
+ log_3_with_header(2, 82, 83, src);
+ } break;
+ }
+ } else {
+
+#line 2344 "pjsnmp.ctr"
+ /* ERROR: Empty text */
+ log_3_with_header(2, 75, 76, printcap_entry_names[9]);
+ }
+ } else {
+
+#line 2348 "pjsnmp.ctr"
+ /* ERROR: Value required */
+ log_3_with_header(2, 77, 78, printcap_entry_names[9]);
+ }
+
+
+#line 2352 "pjsnmp.ctr"
+ return back;
+}
+
+
+
+/** Set maximum unsigned integer variable from text.
+ @param dptr Address of destination variable.
+ @param src Text containing the value.
+ @param name Setting name for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+set_umax(dk4_um_t *dptr, char *src, const char *name)
+{
+ const char *ep = NULL; /* First unprocessable character */
+ dk4_um_t i = 0UL; /* Result value */
+ int back = 0;
+ int res; /* Operation result */
+
+
+#line 2372 "pjsnmp.ctr"
+ if (NULL != src) {
+ res = dk4ma_input_c8_dec_dk4_um_t(&i, src, &ep, 1, NULL);
+ if (0 != res) {
+ *dptr = i;
+
+#line 2376 "pjsnmp.ctr"
+ back = 1;
+ } else {
+
+#line 2378 "pjsnmp.ctr"
+ /* ERROR: Not a numeric value */
+ log_5_with_header(2, 84, 161, 86, name, src);
+ }
+ } else {
+
+#line 2382 "pjsnmp.ctr"
+ /* ERROR: Value required */
+ log_3_with_header(2, 77, 78, name);
+ }
+
+#line 2385 "pjsnmp.ctr"
+ return back;
+}
+
+
+
+#if 0
+
+/** Set integer variable from text.
+ @param dptr Address of destination variable.
+ @param src Text containing the value.
+ @param name Setting name for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+set_integer(int *dptr, char *src, const char *name)
+{
+ const char *ep = NULL; /* First unprocessable character */
+ int i = 0; /* Result value */
+ int back = 0;
+ int res; /* Operation result */
+
+
+#line 2407 "pjsnmp.ctr"
+ if (NULL != src) {
+ res = dk4ma_input_c8_dec_int(&i, src, &ep, 1, NULL);
+ if (0 != res) {
+ *dptr = i;
+
+#line 2411 "pjsnmp.ctr"
+ back = 1;
+ } else {
+
+#line 2413 "pjsnmp.ctr"
+ /* ERROR: Not a numeric value */
+ log_5_with_header(2, 84, 85, 86, name, src);
+ }
+ } else {
+
+#line 2417 "pjsnmp.ctr"
+ /* ERROR: Value required */
+ log_3_with_header(2, 77, 78, name);
+ }
+
+#line 2420 "pjsnmp.ctr"
+ return back;
+}
+
+#endif
+
+
+
+/** Process one configuration item from a printcap entry.
+ @param ci Item to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+process_one_config_item(char *ci)
+{
+ char *value = NULL; /* Value for config item */
+ int btrue = 1; /* Condition */
+ int back = 1;
+
+
+#line 2439 "pjsnmp.ctr"
+ value = dk4str8_chr(ci, '=');
+ if (NULL != value) {
+ *(value++) = '\0';
+ value = dk4str8_start(value, NULL);
+
+#line 2443 "pjsnmp.ctr"
+ } else {
+ value = dk4str8_chr(ci, '@');
+ if (NULL != value) {
+
+#line 2446 "pjsnmp.ctr"
+ *value = '\0';
+ btrue = 0;
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 2451 "pjsnmp.ctr"
+ }
+#endif
+ }
+ switch (dk4str8_array_index(printcap_entry_names, ci, 0)) {
+ case 0: {
+
+#line 2456 "pjsnmp.ctr"
+ if (0 == set_string(&host_name, value, printcap_entry_names[0])) {
+ back = 0;
+ }
+ } break;
+ case 1: {
+
+#line 2461 "pjsnmp.ctr"
+ if (0 == set_unsigned_short(&host_port, value, printcap_entry_names[1])) {
+ back = 0;
+ }
+ } break;
+ case 2: {
+
+#line 2466 "pjsnmp.ctr"
+ host_ordr = btrue;
+ } break;
+ case 3: {
+
+#line 2469 "pjsnmp.ctr"
+ acct_enab = btrue;
+ } break;
+ case 4: {
+
+#line 2472 "pjsnmp.ctr"
+ acct_achk = btrue;
+ } break;
+ case 5: {
+
+#line 2475 "pjsnmp.ctr"
+ if (0 == set_string(&acct_name, value, printcap_entry_names[5])) {
+ back = 0;
+ }
+ } break;
+ case 6: {
+
+#line 2480 "pjsnmp.ctr"
+ if (0 == set_string(&acct_host, value, printcap_entry_names[6])) {
+ back = 0;
+ }
+ } break;
+ case 7: {
+
+#line 2485 "pjsnmp.ctr"
+ if (0 == set_unsigned_short(&acct_port, value, printcap_entry_names[7])) {
+ back = 0;
+ }
+ } break;
+ case 8: {
+
+#line 2490 "pjsnmp.ctr"
+ if (NULL != value) {
+ if (0 == set_umax(&print_timeout, value, printcap_entry_names[8])) {
+ back = 0;
+ }
+ } else {
+ if (0 == btrue) { print_timeout = (dk4_um_t)0UL; }
+ else { back = 0; }
+ }
+ } break;
+ case 9: {
+
+#line 2500 "pjsnmp.ctr"
+ if (0 == set_snmp_version(&snmp_version, value)) {
+ back = 0;
+ }
+ } break;
+ case 10: {
+
+#line 2505 "pjsnmp.ctr"
+ if (0 == set_string(&snmp_comm, value, printcap_entry_names[10])) {
+ back = 0;
+ }
+ } break;
+ case 11: {
+
+#line 2510 "pjsnmp.ctr"
+ check_trans = btrue;
+ } break;
+ case 12: {
+
+#line 2513 "pjsnmp.ctr"
+ if (0 == set_string(&model_file, value, printcap_entry_names[12])) {
+ back = 0;
+ }
+ } break;
+ case 13: {
+
+#line 2518 "pjsnmp.ctr"
+ if (0 == set_string(&model_name, value, printcap_entry_names[13])) {
+ back = 0;
+ }
+ } break;
+ case 14: {
+
+#line 2523 "pjsnmp.ctr"
+ snmp_igfs = btrue;
+ } break;
+ case 15: {
+
+#line 2526 "pjsnmp.ctr"
+ acct_apcf = btrue;
+ } break;
+ case 16: {
+
+#line 2529 "pjsnmp.ctr"
+ pdes_always = btrue;
+ } break;
+ case 17: {
+
+#line 2532 "pjsnmp.ctr"
+ unkn_busy = btrue;
+ } break;
+ case 18: {
+
+#line 2535 "pjsnmp.ctr"
+ if (NULL != value) {
+ if (0 == set_umax(&unto_start, value, printcap_entry_names[18])) {
+ back = 0;
+ }
+ } else {
+ if (0 == btrue) { unto_start = (dk4_um_t)0UL; }
+ else { back = 0; }
+ }
+ } break;
+ case 19: {
+
+#line 2545 "pjsnmp.ctr"
+ if (NULL != value) {
+ if (0 == set_umax(&unto_end, value, printcap_entry_names[19])) {
+ back = 0;
+ }
+ } else {
+ if (0 == btrue) { unto_end = (dk4_um_t)0UL; }
+ else { back = 0; }
+ }
+ } break;
+ case 20: {
+
+#line 2555 "pjsnmp.ctr"
+ if (NULL != value) {
+ if (0 == set_umax(&unto_print, value, printcap_entry_names[20])) {
+ back = 0;
+ }
+ } else {
+ if (0 == btrue) { unto_print = (dk4_um_t)0UL; }
+ else { back = 0; }
+ }
+ } break;
+ case 21: {
+
+#line 2565 "pjsnmp.ctr"
+ if (0 == set_unsigned_short(&local_port, value, printcap_entry_names[21]))
+ {
+ back = 0;
+
+#line 2568 "pjsnmp.ctr"
+ }
+ } break;
+ case 22: {
+
+#line 2571 "pjsnmp.ctr"
+ if (NULL != value) {
+ if (0 == set_umax(&unwt_print, value, printcap_entry_names[22])) {
+ back = 0;
+ }
+ } else {
+ if (0 == btrue) { unwt_print = (dk4_um_t)0UL; }
+ else {
+
+#line 2578 "pjsnmp.ctr"
+ back = 0;
+ }
+ }
+ } break;
+ case 23: {
+
+#line 2583 "pjsnmp.ctr"
+ read_responses = btrue;
+ } break;
+ case 24: {
+
+#line 2586 "pjsnmp.ctr"
+ force_printable_status_text = btrue;
+ } break;
+ case 25: {
+ if (NULL != value) {
+ if (0 == set_umax(&erto_start, value, printcap_entry_names[22])) {
+ back = 0;
+ }
+ } else {
+ if (0 == btrue) { erto_start = (dk4_um_t)0UL; }
+ else {
+
+#line 2596 "pjsnmp.ctr"
+ back = 0;
+ }
+ }
+ } break;
+ case 26: {
+ if (NULL != value) {
+ if (0 == set_umax(&erto_end, value, printcap_entry_names[22])) {
+ back = 0;
+ }
+ } else {
+ if (0 == btrue) { erto_end = (dk4_um_t)0UL; }
+ else {
+
+#line 2608 "pjsnmp.ctr"
+ back = 0;
+ }
+ }
+ } break;
+ case 27: {
+ if (NULL != value) {
+ if (0 == set_umax(&erto_print, value, printcap_entry_names[22])) {
+ back = 0;
+ }
+ } else {
+ if (0 == btrue) { erto_print = (dk4_um_t)0UL; }
+ else {
+
+#line 2620 "pjsnmp.ctr"
+ back = 0;
+ }
+ }
+ } break;
+ case 28: {
+ verbose = btrue;
+ } break;
+ case 29: {
+ allow_non_ascii = btrue;
+ } break;
+ case 30: {
+ acct_start_end = btrue;
+ } break;
+ }
+
+#line 2634 "pjsnmp.ctr"
+ return back;
+}
+
+
+
+/** Check whether the line opens the model we are searching for.
+ @param str Text to check.
+ @param bptr Address of success indicator.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+check_in_model(char *str, int *bptr, dk4_um_t lineno)
+{
+ char *ptr; /* Closing square bracket */
+ int back = 0;
+
+
+#line 2651 "pjsnmp.ctr"
+ str = dk4str8_start(str, NULL);
+ if (NULL != str) {
+ ptr = dk4str8_chr(str, ']');
+ if (NULL != ptr) {
+ *ptr = '\0';
+ dk4str8_normalize(str, NULL);
+
+#line 2657 "pjsnmp.ctr"
+ if (0 == strcmp(str, model_name)) {
+ back = 1;
+
+#line 2659 "pjsnmp.ctr"
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 2662 "pjsnmp.ctr"
+ }
+#endif
+ } else {
+
+#line 2665 "pjsnmp.ctr"
+ /* ERROR: Syntax */
+ log_model_1(lineno, 87);
+ }
+ } else {
+
+#line 2669 "pjsnmp.ctr"
+ /* ERROR: Syntax */
+ log_model_1(lineno, 88);
+ }
+
+#line 2672 "pjsnmp.ctr"
+ return back;
+}
+
+
+
+/** Overwrite one mapping from device/printer status to summary state.
+ @param devst Device status.
+ @param prst Printer status.
+ @param sujmst Summary state resulting from device and printer status.
+*/
+static
+void
+set_state_mapping(int devst, int prst, int sumst)
+{
+
+
+#line 2687 "pjsnmp.ctr"
+ if ((0 < devst) && (6 > devst)) {
+ if ((0 < prst) && (6 > prst)) {
+
+#line 2689 "pjsnmp.ctr"
+ summary_states[5 * devst + prst - 6] = sumst;
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 2693 "pjsnmp.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 2698 "pjsnmp.ctr"
+ }
+#endif
+
+
+#line 2701 "pjsnmp.ctr"
+}
+
+
+
+/** Map device and printer status to summary state.
+ @param devst Device status.
+ @param prst Printer status.
+ @return Summary state.
+*/
+static
+int
+get_state_mapping(int devst, int prst)
+{
+ int back = PJSNMP_ST_UNKNOWN;
+
+
+#line 2716 "pjsnmp.ctr"
+ if ((0 < devst) && (6 > devst)) {
+ if ((0 < prst) && (6 > prst)) {
+
+#line 2718 "pjsnmp.ctr"
+ back = summary_states[5 * devst + prst - 6];
+
+
+#line 2720 "pjsnmp.ctr"
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 2723 "pjsnmp.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 2728 "pjsnmp.ctr"
+ }
+#endif
+
+
+#line 2731 "pjsnmp.ctr"
+ return back;
+}
+
+
+
+/** Add a state mapping.
+ @param str Mapping text.
+ @param lineno Line number (for diagnostics).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+model_conf_map(char *str, dk4_um_t lineno)
+{
+ char *psummary; /* Summary state name */
+ char *ppr; /* Printer status */
+ int stsum; /* Summary state */
+ int stdev; /* Device status */
+ int stpri; /* Printer status */
+ int back = 0;
+
+
+#line 2752 "pjsnmp.ctr"
+ psummary = dk4str8_next(str, NULL);
+ if (NULL != psummary) {
+
+#line 2754 "pjsnmp.ctr"
+ ppr = dk4str8_chr(str, '/');
+ if (NULL != ppr) {
+
+#line 2756 "pjsnmp.ctr"
+ *(ppr++) = '\0';
+ ppr = dk4str8_start(ppr, NULL);
+ if (NULL != ppr) {
+
+#line 2759 "pjsnmp.ctr"
+ back = 1;
+ switch (dk4str8_abbr_index(summary_state_names, '$', psummary, 0)) {
+ case 0: {
+
+#line 2762 "pjsnmp.ctr"
+ stsum = PJSNMP_ST_UNKNOWN;
+ } break;
+ case 1: {
+
+#line 2765 "pjsnmp.ctr"
+ stsum = PJSNMP_ST_ERROR;
+ } break;
+ case 2: {
+
+#line 2768 "pjsnmp.ctr"
+ stsum = PJSNMP_ST_BUSY;
+ } break;
+ case 3: {
+
+#line 2771 "pjsnmp.ctr"
+ stsum = PJSNMP_ST_IDLE;
+ } break;
+ case 4: {
+
+#line 2774 "pjsnmp.ctr"
+ stsum = PJSNMP_ST_WARMUP;
+ } break;
+ case 5: {
+
+#line 2777 "pjsnmp.ctr"
+ stsum = PJSNMP_ST_STANDBY;
+ } break;
+ default: {
+
+#line 2780 "pjsnmp.ctr"
+ back = 0;
+ /* ERROR: Illegal summary state */
+ log_model_3(lineno, 89, 90, psummary);
+ } break;
+ }
+ if (0 != back) {
+
+#line 2786 "pjsnmp.ctr"
+ if (0 == strcmp(str, pjsnmp_kw[3])) {
+ if (0 == strcmp(ppr, pjsnmp_kw[3])) {
+
+#line 2788 "pjsnmp.ctr"
+ for (stdev = 1; stdev < 6; stdev++) {
+ for (stpri = 1; stpri < 6; stpri++) {
+ set_state_mapping(stdev, stpri, stsum);
+ }
+ }
+ } else {
+
+#line 2794 "pjsnmp.ctr"
+ stpri = dk4str8_abbr_index(printer_status_names, '$', ppr, 0);
+ if (-1 < stpri) {
+ stpri++;
+
+#line 2797 "pjsnmp.ctr"
+ for (stdev = 1; stdev < 6; stdev++) {
+ set_state_mapping(stdev, stpri, stsum);
+ }
+ } else {
+
+#line 2801 "pjsnmp.ctr"
+ back = 0;
+ /* ERROR: Syntax, illegal printer status name */
+ log_model_3(lineno, 91, 92, ppr);
+ }
+ }
+ } else {
+ stdev = dk4str8_abbr_index(device_status_names, '$', str, 0);
+ if (-1 < stdev) {
+ stdev++;
+
+#line 2810 "pjsnmp.ctr"
+ if (0 == strcmp(ppr, pjsnmp_kw[3])) {
+
+#line 2811 "pjsnmp.ctr"
+ for (stpri = 1; stpri < 6; stpri++) {
+ set_state_mapping(stdev, stpri, stsum);
+ }
+ } else {
+
+#line 2815 "pjsnmp.ctr"
+ stpri = dk4str8_abbr_index(printer_status_names, '$', ppr, 0);
+ if (-1 < stpri) {
+ stpri++;
+
+#line 2818 "pjsnmp.ctr"
+ set_state_mapping(stdev, stpri, stsum);
+ } else {
+
+#line 2820 "pjsnmp.ctr"
+ back = 0;
+ /* ERROR: Syntax, illegal printer status name */
+ log_model_3(lineno, 91, 92, ppr);
+ }
+ }
+ } else {
+
+#line 2826 "pjsnmp.ctr"
+ back = 0;
+ /* ERROR: Syntax, illegal device status name */
+ log_model_3(lineno, 93, 94, ppr);
+ }
+ }
+ } else {
+
+#line 2832 "pjsnmp.ctr"
+ }
+ } else {
+
+#line 2834 "pjsnmp.ctr"
+ /* ERROR: Syntax, printer status missing */
+ log_model_1(lineno, 95);
+ }
+ } else {
+
+#line 2838 "pjsnmp.ctr"
+ /* ERROR: Syntax, printer status missing */
+ log_model_1(lineno, 95);
+ }
+ } else {
+
+#line 2842 "pjsnmp.ctr"
+ /* ERROR: Syntax, summary state missing */
+ log_model_1(lineno, 96);
+ }
+
+#line 2845 "pjsnmp.ctr"
+ return back;
+}
+
+
+
+/** Add a condition to the error conditions list.
+ @param str Text for condition.
+ @param addcond Flag: Add to existing list, do not reset.
+ @param lineno Line number (for diagnostics).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+model_conf_error_condition(char *str, int addcond, dk4_um_t lineno)
+{
+ unsigned long cond; /* Used to build condition bit */
+ int i; /* Index of keyword in condition_names */
+ int back = 0;
+
+
+#line 2864 "pjsnmp.ctr"
+ if ((0 == addcond) && (0 == pdes_reset)) {
+ pdes_error = 0UL;
+
+#line 2866 "pjsnmp.ctr"
+ }
+ pdes_reset = 1;
+ dk4str8_normalize(str, NULL);
+ i = dk4str8_array_index(condition_names, str, 0);
+
+#line 2870 "pjsnmp.ctr"
+ if (-1 < i) {
+ back = 1;
+ cond = 0x80000000UL;
+ while (0 < i--) { cond = cond / 2UL; }
+ pdes_error |= cond;
+
+#line 2875 "pjsnmp.ctr"
+ } else {
+
+#line 2876 "pjsnmp.ctr"
+ /* ERROR: Syntax, illegal condition name */
+ log_model_3(lineno, 97, 98, str);
+ }
+
+#line 2879 "pjsnmp.ctr"
+ return back;
+}
+
+
+
+/** Set status text OID.
+ @param str Text containing the OID.
+ @param lineno Line number (for diagnostics).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+model_conf_status_oid(char *str, dk4_um_t lineno)
+{
+ const char *ep; /* First unprocessable character */
+ char *np; /* Next part */
+ dk4_um_t num; /* Numeric value for sub-id */
+ size_t used = 0; /* Number of used sub-ids */
+ int back = 1;
+ int res; /* Operation result */
+
+
+#line 2900 "pjsnmp.ctr"
+ dk4str8_normalize(str, NULL);
+ if ('.' == *str) {
+
+#line 2902 "pjsnmp.ctr"
+ str++;
+ }
+ while ((NULL != str) && (1 == back)) {
+ np = dk4str8_chr(str, '.');
+ if (NULL != np) {
+ *(np++) = '\0';
+ }
+
+#line 2909 "pjsnmp.ctr"
+ ep = NULL;
+ res = dk4ma_input_c8_dec_dk4_um_t(&num, str, &ep, 1, NULL);
+ if (0 != res) {
+
+#line 2912 "pjsnmp.ctr"
+ if ((dk4_um_t)(MAX_SUBID) >= num) {
+
+#line 2913 "pjsnmp.ctr"
+ if (used < DK4_SIZEOF(oid_st,oid)) {
+
+#line 2914 "pjsnmp.ctr"
+ oid_st[used++] = (oid)num;
+ } else {
+
+#line 2916 "pjsnmp.ctr"
+ /* ERROR: Syntax, OID too long */
+ log_model_1(lineno, 99);
+ }
+ } else {
+
+#line 2920 "pjsnmp.ctr"
+ back = 0;
+ /* ERROR: Syntax, overflow */
+ log_model_3(lineno, 100, 101, str);
+ }
+ } else {
+
+#line 2925 "pjsnmp.ctr"
+ back = 0;
+ /* ERROR: Syntax, not a number */
+ log_model_3(lineno, 102, 103, str);
+ }
+ str = np;
+ }
+ if (0 == used) {
+
+#line 2932 "pjsnmp.ctr"
+ back = 0;
+ /* ERROR: Syntax, empty OID */
+ log_model_1(lineno, 104);
+ }
+ if (0 != back) {
+ sz_oid_st = used;
+ } else {
+ sz_oid_st = 0;
+ }
+ by_oid_st = sz_oid_st * sizeof(oid);
+
+
+#line 2943 "pjsnmp.ctr"
+ return back;
+}
+
+
+
+/** Remove final double quote from string.
+ @param str String to modify.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+remove_final_double_quote(char *str)
+{
+ char *ptr; /* Position of final double quote */
+ int back = 0;
+
+
+#line 2959 "pjsnmp.ctr"
+ ptr = dk4str8_rchr(str, '"');
+ if (NULL != ptr) {
+
+#line 2961 "pjsnmp.ctr"
+ *(ptr++) = '\0';
+ back = 1;
+ while ('\0' != *ptr) {
+ if (' ' != *ptr) {
+ if ('\t' != *ptr) {
+ if ('\r' != *ptr) {
+ if ('\n' != *ptr) {
+ back = 0;
+
+#line 2969 "pjsnmp.ctr"
+ }
+ }
+ }
+ }
+ ptr++;
+ }
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 2978 "pjsnmp.ctr"
+ }
+#endif
+
+
+#line 2981 "pjsnmp.ctr"
+ return back;
+}
+
+
+
+/** Add a text indicating a state to the storage.
+ @param str Indicator text.
+ @param state State number indicated by the text.
+ @param start Flag: This text is just the start of the real text.
+ @param lineno Line number (for diagnostics).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+model_conf_state_text(char *str, int state, int start, dk4_um_t lineno)
+{
+ status_text_t *stptr; /* New configuration node to add */
+ const char *ep; /* First unprocessable char when reading number */
+ char *cptr; /* Current word to process */
+ char *nptr; /* Next word (remaining text) to process */
+ size_t sl; /* String length */
+ int res; /* Operation result */
+ int back = 0;
+ unsigned char uc; /* Current byte found */
+
+
+#line 3006 "pjsnmp.ctr"
+ if (NULL == s_stn) {
+ s_stn = dk4sto_open(NULL);
+ if (NULL != s_stn) {
+ dk4sto_set_comp(s_stn, stt_compare, 0);
+ }
+ }
+ if ((NULL != s_stn) && (NULL == i_stn)) {
+ i_stn = dk4sto_it_open(s_stn, NULL);
+ }
+ if ((NULL != s_stn) && (NULL != i_stn)) {
+
+#line 3016 "pjsnmp.ctr"
+ if (NULL != str) {
+
+#line 3017 "pjsnmp.ctr"
+ if ('"' == *str) {
+
+#line 3018 "pjsnmp.ctr"
+ str++;
+ if (0 != remove_final_double_quote(str)) {
+ sl = strlen(str);
+ if (0 < sl) {
+
+#line 3022 "pjsnmp.ctr"
+ stptr = stt_new((unsigned char *)str, sl, state, start);
+ if (NULL != stptr) {
+
+#line 3024 "pjsnmp.ctr"
+ if (0 != dk4sto_add(s_stn, stptr, NULL)) {
+ back = 1;
+
+#line 3026 "pjsnmp.ctr"
+ } else {
+
+#line 3027 "pjsnmp.ctr"
+ /* ERROR: Allocation failed */
+ log_model_1(lineno, 105);
+ stt_delete(stptr);
+ }
+ } else {
+
+#line 3032 "pjsnmp.ctr"
+ /* ERROR: Allocation failed */
+ log_model_1(lineno, 105);
+ }
+ } else {
+
+#line 3036 "pjsnmp.ctr"
+ /* ERROR: Syntax, string empty */
+ log_model_1(lineno, 106);
+ }
+ } else {
+
+#line 3040 "pjsnmp.ctr"
+ /* ERROR: Syntax, closing double quote missing or text after */
+ log_model_1(lineno, 107);
+ }
+ } else {
+
+#line 3044 "pjsnmp.ctr"
+ sl = 0;
+ cptr = str;
+ back = 1;
+ while ((NULL != cptr) && (0 != back)) {
+ nptr = dk4str8_next(cptr, NULL);
+ ep = NULL;
+
+#line 3050 "pjsnmp.ctr"
+ res = dk4ma_input_c8_hex_uchar(&uc, cptr, &ep, 1, NULL);
+ if (0 != res) {
+ str[sl++] = (char)uc;
+
+#line 3053 "pjsnmp.ctr"
+ } else {
+ back = 0;
+
+#line 3055 "pjsnmp.ctr"
+ /* ERROR: Syntax, not a hexadecimal byte */
+ log_model_3(lineno, 108, 109, cptr);
+ }
+ cptr = nptr;
+ }
+ if (0 != back) {
+ if (0 < sl) {
+
+#line 3062 "pjsnmp.ctr"
+ stptr = stt_new((unsigned char *)str, sl, state, start);
+ if (NULL != stptr) {
+
+#line 3064 "pjsnmp.ctr"
+ if (0 == dk4sto_add(s_stn, stptr, NULL)) {
+ back = 0;
+
+#line 3066 "pjsnmp.ctr"
+ stt_delete(stptr);
+ /* ERROR: Allocation failed */
+ log_model_1(lineno, 105);
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 3072 "pjsnmp.ctr"
+ }
+#endif
+ } else {
+
+#line 3075 "pjsnmp.ctr"
+ back = 0;
+ /* ERROR: Memory allocation failed */
+ log_model_1(lineno, 105);
+ }
+ } else {
+
+#line 3080 "pjsnmp.ctr"
+ /* ERROR: Syntax, empty string */
+ log_model_1(lineno, 106);
+ }
+ }
+ }
+ } else {
+
+#line 3086 "pjsnmp.ctr"
+ /* ERROR: Value required */
+ log_model_1(lineno, 110);
+ }
+ } else {
+
+#line 3090 "pjsnmp.ctr"
+ /* ERROR: Memory allocation failed */
+ log_model_1(lineno, 105);
+ }
+
+#line 3093 "pjsnmp.ctr"
+ return back;
+}
+
+
+
+/** Process one configuration line from model file.
+ @param str Line to process.
+ @param lineno Line number in the file (for diagnostics).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+process_model_line(char *str, dk4_um_t lineno)
+{
+ char *valptr; /* Value in line */
+ int back = 0;
+
+
+#line 3110 "pjsnmp.ctr"
+ valptr = dk4str8_chr(str, '=');
+ if (NULL != valptr) {
+
+#line 3112 "pjsnmp.ctr"
+ *(valptr++) = '\0';
+ dk4str8_normalize(str, NULL);
+ valptr = dk4str8_start(valptr, NULL);
+ if (NULL != valptr) {
+
+#line 3116 "pjsnmp.ctr"
+ switch (dk4str8_array_index(model_keys, str, 0)) {
+ case 0: {
+ back = model_conf_map(valptr, lineno);
+ } break;
+ case 1: {
+ back = model_conf_error_condition(valptr, 0, lineno);
+ } break;
+ case 2: {
+ back = model_conf_error_condition(valptr, 1, lineno);
+ } break;
+ case 3: {
+ back = model_conf_status_oid(valptr, lineno);
+ } break;
+ case 4: {
+ back = model_conf_state_text(valptr, PJSNMP_ST_STANDBY, 0, lineno);
+ } break;
+ case 5: {
+ back = model_conf_state_text(valptr, PJSNMP_ST_STANDBY, 1, lineno);
+ } break;
+ case 6: {
+ back = model_conf_state_text(valptr, PJSNMP_ST_IDLE, 0, lineno);
+ } break;
+ case 7: {
+ back = model_conf_state_text(valptr, PJSNMP_ST_IDLE, 1, lineno);
+ } break;
+ case 8: {
+ back = 1;
+ if (NULL != valptr) {
+ valptr = dk4str8_start(valptr, NULL);
+ if (NULL != valptr) {
+ dk4str8_normalize(valptr, NULL);
+ if (dk4str8_is_bool(valptr)) {
+ stat_always = dk4str8_is_on(valptr);
+ } else {
+ back = 0;
+ /* ERROR: Not a boolean */
+ log_model_3(lineno, 111, 112, valptr);
+ }
+ } else {
+ stat_always = 1;
+ }
+ } else {
+ stat_always = 1;
+ }
+ } break;
+ case 9: {
+ back = model_conf_state_text(valptr, PJSNMP_ST_BUSY, 0, lineno);
+ } break;
+ case 10: {
+ back = model_conf_state_text(valptr, PJSNMP_ST_BUSY, 1, lineno);
+ } break;
+ case 11: {
+ back = model_conf_state_text(valptr, PJSNMP_ST_UNKNOWN, 0, lineno);
+ } break;
+ case 12: {
+ back = model_conf_state_text(valptr, PJSNMP_ST_UNKNOWN, 1, lineno);
+ } break;
+ case 13: {
+ back = model_conf_state_text(valptr, PJSNMP_ST_ERROR, 0, lineno);
+ } break;
+ case 14: {
+ back = model_conf_state_text(valptr, PJSNMP_ST_ERROR, 1, lineno);
+ } break;
+ case 15: {
+ back = model_conf_state_text(valptr, PJSNMP_ST_WARMUP, 0, lineno);
+ } break;
+ case 16: {
+ back = model_conf_state_text(valptr, PJSNMP_ST_WARMUP, 1, lineno);
+ } break;
+ default: {
+
+#line 3186 "pjsnmp.ctr"
+ /* ERROR: Syntax, unknown key */
+ log_model_3(lineno, 113, 114, str);
+ } break;
+ }
+ } else {
+
+#line 3191 "pjsnmp.ctr"
+ /* ERROR: Syntax, missing value */
+ log_model_1(lineno, 110);
+ }
+ } else {
+
+#line 3195 "pjsnmp.ctr"
+ /* ERROR: Syntax, missing value */
+ log_model_1(lineno, 110);
+ }
+
+#line 3198 "pjsnmp.ctr"
+ return back;
+}
+
+
+
+/** Configure for specified SNMP model.
+*/
+static
+int
+process_model_setup(void)
+{
+ FILE *infile; /* Input file to read */
+ char *p1; /* Start of text in line */
+ dk4_um_t lineno = (dk4_um_t)0UL;
+ int in_model = 0; /* Flag: In model to read */
+ int found = 0; /* Flag: Model was found */
+ int back = 0;
+
+
+#line 3216 "pjsnmp.ctr"
+ infile = fopen(((NULL != model_file) ? model_file : def_model_file), "r");
+ if (NULL != infile) {
+
+#line 3218 "pjsnmp.ctr"
+ back = 1;
+ while (NULL != fgets(pjsnmp_buf, sizeof(pjsnmp_buf), infile)) {
+ lineno++;
+#if TRACE_DEBUG
+ dk4str8_delnl(pjsnmp_buf);
+
+#line 3223 "pjsnmp.ctr"
+#endif
+ p1 = dk4str8_start(pjsnmp_buf, NULL);
+ if (NULL != p1) {
+ if ('[' == *p1) {
+ in_model = check_in_model(++p1, &back, lineno);
+ if (0 != in_model) {
+ found = 1;
+ }
+ } else {
+ if (0 != in_model) {
+ if ('#' != *p1) {
+#if !TRACE_DEBUG
+ dk4str8_delnl(pjsnmp_buf);
+#endif
+ if (0 == process_model_line(p1, lineno)) {
+ back = 0;
+ }
+ }
+ }
+ }
+ }
+ }
+ fclose(infile);
+ if (0 == found) {
+
+#line 3247 "pjsnmp.ctr"
+ back = 0;
+ /* ERROR: Model not found */
+ log_model_3((dk4_um_t)0UL, 115, 116, model_name);
+ }
+ } else {
+
+#line 3252 "pjsnmp.ctr"
+ /* ERROR: Failed to open model file */
+ log_model_3(
+ (dk4_um_t)0UL, 115, 116,
+ ((NULL != model_file) ? model_file : def_model_file)
+ );
+ }
+
+#line 3258 "pjsnmp.ctr"
+ return back;
+}
+
+
+
+/** Process PRINTCAP_ENTRY and optionally
+ model file.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+process_setup(void)
+{
+ char *ptr; /* Environment variable value */
+ char *cl; /* Current line */
+ char *nl; /* Next line */
+ char *ci; /* Current item */
+ char *ni; /* Next item */
+ int found = 0; /* Already item found */
+ int back = 0;
+
+
+#line 3281 "pjsnmp.ctr"
+
+ ptr = getenv(pjsnmp_kw[2]);
+ if (NULL != ptr) {
+
+#line 3284 "pjsnmp.ctr"
+ printcap_entry = dk4str8_dup(ptr, NULL);
+ if (NULL != printcap_entry) {
+
+#line 3286 "pjsnmp.ctr"
+ back = 1;
+
+#line 3287 "pjsnmp.ctr"
+ cl = printcap_entry;
+ while (NULL != cl) {
+ nl = dk4str8_chr(cl, '\n');
+ if (NULL != nl) {
+ *(nl++) = '\0';
+ nl = dk4str8_start(nl, NULL);
+ }
+
+#line 3294 "pjsnmp.ctr"
+ ptr = cl;
+ while ('\0' != *ptr) {
+ if ('\r' == *ptr) { *ptr = '\0'; } else { ptr++; }
+ }
+ ci = dk4str8_start(cl, NULL);
+ if (NULL != ci) {
+ if ('#' != *ci) {
+ while (NULL != ci) {
+ ni = dk4str8_chr(ci, ':');
+ if (NULL != ni) {
+ *(ni++) = '\0'; ni = dk4str8_start(ni, NULL);
+ }
+
+#line 3306 "pjsnmp.ctr"
+ ci = dk4str8_start(ci, NULL);
+ if (NULL != ci) {
+ if (0 != found) {
+ if (0 == process_one_config_item(ci)) {
+ back = 0;
+
+#line 3311 "pjsnmp.ctr"
+ }
+ }
+ found = 1;
+ }
+ ci = ni;
+ }
+ }
+ }
+ cl = nl;
+ }
+ if (NULL == host_name) {
+ back = 0;
+
+#line 3323 "pjsnmp.ctr"
+ /* ERROR: Host name of printer required */
+ log_1_with_header(2, 119);
+ }
+ if (0 != back) {
+ if (NULL != model_name) {
+ back = process_model_setup();
+
+#line 3329 "pjsnmp.ctr"
+ }
+ }
+ if (0 != back) {
+ if (0 != acct_achk) {
+
+#line 3333 "pjsnmp.ctr"
+ acct_enab = 1;
+ }
+ if (0 != acct_enab) {
+ if (NULL == acct_name) {
+ if ((NULL == acct_host) || (0 == acct_port)) {
+ log_1_with_header(2, 165);
+ back = 0;
+ }
+ }
+ }
+ }
+ } else {
+
+#line 3345 "pjsnmp.ctr"
+ /* ERROR: Memory allocation failed */
+ log_1_with_header(2, 105);
+ }
+ } else {
+
+#line 3349 "pjsnmp.ctr"
+ /* ERROR: Missing printcap entry environment variable */
+ log_1_with_header(2, 120);
+ }
+
+
+#line 3353 "pjsnmp.ctr"
+ return back;
+}
+
+
+
+/** Eat up remaining input from standard input.
+*/
+static
+void
+eatup_input(void)
+{
+ size_t rdb; /* Number of read bytes */
+ int cc = 1;
+
+
+#line 3367 "pjsnmp.ctr"
+ do {
+ if (0 != can_continue(0)) {
+ if (0 == have_eof) {
+
+#line 3370 "pjsnmp.ctr"
+ rdb = fread(pjsnmp_buf, 1, sizeof(pjsnmp_buf), stdin);
+ if (0 == rdb) {
+
+#line 3372 "pjsnmp.ctr"
+ cc = 0;
+ have_eof = 1;
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 3377 "pjsnmp.ctr"
+ }
+#endif
+ } else {
+
+#line 3380 "pjsnmp.ctr"
+ cc = 0;
+ }
+ } else {
+
+#line 3383 "pjsnmp.ctr"
+ cc = -1;
+ }
+ } while (1 == cc);
+
+
+#line 3387 "pjsnmp.ctr"
+}
+
+
+
+/** Release memory for the text nodes in s_stn.
+*/
+static
+void
+relase_status_text_nodes(void)
+{
+ status_text_t *ptr; /* Current node to release */
+
+
+#line 3399 "pjsnmp.ctr"
+ if (NULL != s_stn) {
+ if (NULL != i_stn) {
+ dk4sto_it_reset(i_stn);
+ do {
+ ptr = (status_text_t *)dk4sto_it_next(i_stn);
+ if (NULL != ptr) {
+
+#line 3405 "pjsnmp.ctr"
+ stt_delete(ptr);
+ }
+ } while(NULL != ptr);
+ dk4sto_it_close(i_stn); i_stn = NULL;
+ }
+ dk4sto_close(s_stn); s_stn = NULL;
+ }
+
+
+#line 3413 "pjsnmp.ctr"
+}
+
+
+
+/** Attempt to open an SNMP session.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+attempt_snmp_session(void)
+{
+ struct snmp_session template; /* Template for the session */
+ int back = 0;
+
+
+#line 3427 "pjsnmp.ctr"
+ init_snmp(pjsnmp_kw[4]);
+ DK4_MEMRES(&template, sizeof(template));
+ snmp_sess_init(&template);
+ template.version = snmp_version;
+ template.peername = host_name;
+ template.community = (unsigned char *)snmp_comm;
+ if (NULL == snmp_comm) {
+ template.community = (unsigned char *)(pjsnmp_kw[5]);
+ }
+ template.community_len = strlen((char *)(template.community));
+ snmp_sess = snmp_open(&template);
+ if (NULL != snmp_sess) {
+
+#line 3439 "pjsnmp.ctr"
+ back = 1;
+ } else {
+
+#line 3441 "pjsnmp.ctr"
+ /* ERROR: Failed to open SNMP session */
+ log_1_no_header(121);
+ if (0 != snmp_igfs) {
+
+#line 3444 "pjsnmp.ctr"
+ back = 1;
+ }
+ }
+
+#line 3447 "pjsnmp.ctr"
+ return back;
+}
+
+
+
+/** Accounting data exchange via socket (either network socket
+ or local UNIX domain socket) and close socket.
+ @param sock Socket to use for data exchange.
+ @param expect_response Flag: Response from accounting system expected.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+accounting_ex_socket(dk4_socket_t sock, int expect_response)
+{
+ size_t sl; /* String length */
+ size_t by; /* Bytes written or read */
+ int res; /* Operation result */
+ int cutted; /* String was cutted */
+ int cc; /* Flag: Can continue */
+ int back = 0;
+
+
+#line 3469 "pjsnmp.ctr"
+ cutted = 0;
+ if (0 != can_continue(0)) {
+
+#line 3471 "pjsnmp.ctr"
+ sl = strlen(pjsnmp_buf);
+ by = sl;
+ res = dk4socket_send(sock, pjsnmp_buf, &by, 0, 0L, 0L, NULL);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+
+#line 3475 "pjsnmp.ctr"
+ if (by == sl) {
+
+#line 3476 "pjsnmp.ctr"
+ back = 1;
+
+#line 3477 "pjsnmp.ctr"
+ } else {
+
+#line 3478 "pjsnmp.ctr"
+ /* ERROR: Partial send */
+ log_1_no_header(123);
+ }
+ } else {
+
+#line 3482 "pjsnmp.ctr"
+ /* ERROR: Failed to send data */
+ log_1_no_header(122);
+ }
+ sl = 0;
+ pjsnmp_buf[0] = '\0';
+ res = dk4socket_shutdown(sock, DK4_SOCKET_SHUT_WRITE, NULL);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+
+#line 3489 "pjsnmp.ctr"
+ cc = 1;
+ do {
+ if (0 != can_continue(0)) {
+
+#line 3492 "pjsnmp.ctr"
+ by = sizeof(stat_text) - 1;
+ res = dk4socket_recv(sock, stat_text, &by, 0, 0L, 0L, NULL);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+
+#line 3495 "pjsnmp.ctr"
+ if (0 < by) {
+
+#line 3496 "pjsnmp.ctr"
+ stat_text[by] = '\0';
+ res = dk4str8_cat_s(pjsnmp_buf,sizeof(pjsnmp_buf),stat_text,NULL);
+ if (0 == res) {
+ cutted = 1;
+
+#line 3500 "pjsnmp.ctr"
+ back = 0;
+ }
+ } else {
+
+#line 3503 "pjsnmp.ctr"
+ cc = 0;
+ }
+ } else {
+
+#line 3506 "pjsnmp.ctr"
+ cc = -1;
+ }
+ } else {
+
+#line 3509 "pjsnmp.ctr"
+ cc = -1;
+ back = 0;
+ }
+ } while(1 == cc);
+ } else {
+
+#line 3514 "pjsnmp.ctr"
+ back = 0;
+ /* ERROR: Socket shutdown failed */
+ log_1_no_header(124);
+ }
+ if (0 != expect_response) {
+
+#line 3519 "pjsnmp.ctr"
+ if (0 == strlen(pjsnmp_buf)) {
+
+#line 3520 "pjsnmp.ctr"
+ back = 0;
+ }
+ if (0 != cutted) {
+
+#line 3523 "pjsnmp.ctr"
+ back = 0;
+ }
+ }
+ } else {
+
+#line 3527 "pjsnmp.ctr"
+ pjsnmp_buf[0] = '\0';
+ }
+ dk4socket_close(sock, NULL);
+
+
+#line 3531 "pjsnmp.ctr"
+ return back;
+}
+
+
+
+/** Accounting data exchange via local UNIX domain socket.
+ @param expect_response Flag: Response from accounting system expected.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+accounting_ex_local_socket(int expect_response)
+{
+ dk4_socket_t sock; /* Socket to use for accounting */
+ int back = 0;
+
+
+#line 3547 "pjsnmp.ctr"
+ sock = dk4socket_c8_unix_client(acct_name, NULL);
+ if (INVALID_SOCKET != sock) {
+ back = accounting_ex_socket(sock, expect_response);
+ /* Socket not closed here, closed in accounting_ex_socket() */
+ } else {
+ /* ERROR: Failed to open UNIX domain socket */
+ log_1_no_header(125);
+ pjsnmp_buf[0] = '\0';
+ }
+
+
+#line 3557 "pjsnmp.ctr"
+ return back;
+}
+
+
+
+/** Accounting data exchange via network socket.
+ @param expect_response Flag: Response from accounting system expected.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+accounting_ex_network(int expect_response)
+{
+ dk4_socket_t sock; /* Socket to use for accounting */
+ int back = 0;
+
+
+#line 3573 "pjsnmp.ctr"
+ sock = dk4socket_c8_tcp_client_host_port(acct_host,acct_port,0,0L,0L,NULL);
+ if (INVALID_SOCKET != sock) {
+ back = accounting_ex_socket(sock, expect_response);
+ /* Socket not closed here, closed in accounting_ex_socket() */
+ } else {
+ /* ERROR: Failed to open network connection */
+ log_1_no_header(125);
+ pjsnmp_buf[0] = '\0';
+ }
+
+
+#line 3583 "pjsnmp.ctr"
+ return back;
+}
+
+
+
+/** Accounting data exchange to file.
+ @param fipo Accounting file.
+ @param expect_response Flag: Response from accounting system expected.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+accounting_ex_file(FILE *fipo, int expect_response)
+{
+ int back = 0;
+
+
+#line 3599 "pjsnmp.ctr"
+ if (EOF != fputs(pjsnmp_buf, fipo)) {
+
+#line 3600 "pjsnmp.ctr"
+ if (EOF != fflush(fipo)) {
+
+#line 3601 "pjsnmp.ctr"
+ back = 1;
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 3605 "pjsnmp.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 3610 "pjsnmp.ctr"
+ }
+#endif
+ pjsnmp_buf[0] = '\0';
+ if (0 != expect_response) {
+
+#line 3614 "pjsnmp.ctr"
+ back = 0;
+ }
+
+#line 3616 "pjsnmp.ctr"
+ return back;
+}
+
+
+
+/** Accounting data exchange via pipe.
+ @param expect_response Flag: Response from accounting system expected.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+accounting_ex_pipe(int expect_response)
+{
+ FILE *fipo = NULL; /* Connection to pipe */
+ char *prgn = NULL; /* Program name */
+ int back = 0;
+ int pcres = 0; /* Result from pclose */
+
+
+#line 3634 "pjsnmp.ctr"
+ prgn = dk4str8_start(&(acct_name[1]), NULL);
+ if (NULL != prgn) {
+
+#line 3636 "pjsnmp.ctr"
+ fipo = popen(prgn, "w");
+ if (NULL != fipo) {
+
+#line 3638 "pjsnmp.ctr"
+ back = accounting_ex_file(fipo, 0);
+ pcres = pclose(fipo);
+ pjsnmp_buf[0] = '\0';
+ if (0 != expect_response) {
+ switch (pcres) {
+ case LPRNG_EXIT_REMOVE : {
+ decision = 3;
+ } break;
+ case LPRNG_EXIT_HOLD : {
+ decision = 2;
+ }
+ default : {
+ decision = 1;
+ } break;
+ }
+ log_3_no_header(166, 167, accounting_responses[decision - 1]);
+ }
+ } else {
+
+#line 3656 "pjsnmp.ctr"
+ /* ERROR: Failed to start program for pipe */
+ log_1_no_header(126);
+ pjsnmp_buf[0] = '\0';
+ }
+ } else {
+
+#line 3661 "pjsnmp.ctr"
+ /* ERROR: Not command name found */
+ log_1_with_header(2, 127);
+ pjsnmp_buf[0] = '\0';
+ }
+
+#line 3665 "pjsnmp.ctr"
+ return back;
+}
+
+
+
+/** Accounting data exchange via file specified by name.
+ @param expect_response Flag: Response from accounting system expected.
+ @param crf Flag: Create new file.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+accounting_ex_filename(int expect_response, int crf)
+{
+ dk4_er_t er; /* Error report */
+ FILE *fipo = NULL; /* File to write to */
+ int back = 1;
+ int tests = DK4_FOPEN_SC_USER; /* Security tests for fopen */
+
+
+#line 3684 "pjsnmp.ctr"
+ if (0 != dk4isadmin()) {
+
+#line 3685 "pjsnmp.ctr"
+ tests = DK4_FOPEN_SC_PRIVILEGED;
+ }
+ dk4error_init(&er);
+ fipo = dk4fopen_c8(acct_name, ((0 != crf) ? "w" : "a"), tests, &er);
+ if (NULL != fipo) {
+
+#line 3690 "pjsnmp.ctr"
+ back = accounting_ex_file(fipo, expect_response);
+ if(EOF == fclose(fipo)) {
+
+#line 3692 "pjsnmp.ctr"
+ back = 0;
+ }
+ } else {
+
+#line 3695 "pjsnmp.ctr"
+ /* ERROR: Failed to open accounting file name */
+ log_1_no_header(128);
+ pjsnmp_buf[0] = '\0';
+ }
+
+#line 3699 "pjsnmp.ctr"
+ return back;
+}
+
+
+
+#if 0
+/* 2016-02-10:
+ Although chapter 15.5 of the LPRng reference manual states that the
+ :af file is opened (file, pipe or network socket) and passed as
+ file descriptor 3 to all filters, this did not work in my tests.
+ Text written to fd 3 did not arrive at the accounting system.
+*/
+
+/** Accounting data exchange via file descriptor 3.
+ @param expect_response Flag: Response from accounting system expected.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+accounting_ex_fd3(int expect_response)
+{
+ size_t sl; /* String length */
+ ssize_t bwr; /* Number of bytes written or read */
+ int back = 0;
+
+
+#line 3724 "pjsnmp.ctr"
+ sl = strlen(pjsnmp_buf);
+ bwr = write(3, pjsnmp_buf, sl);
+ pjsnmp_buf[0] = '\0';
+ if (0 < bwr) {
+
+#line 3728 "pjsnmp.ctr"
+ if (sl == (size_t)bwr) {
+
+#line 3729 "pjsnmp.ctr"
+ back = 1;
+ } else {
+
+#line 3731 "pjsnmp.ctr"
+ /* ERROR: Incomplete write operation */
+ log_1_no_header(122);
+ }
+ if (0 != expect_response) {
+
+#line 3735 "pjsnmp.ctr"
+ bwr = read(3, pjsnmp_buf, sizeof(pjsnmp_buf));
+ if (0 < bwr) {
+
+#line 3737 "pjsnmp.ctr"
+ pjsnmp_buf[bwr] = '\0';
+ } else {
+
+#line 3739 "pjsnmp.ctr"
+ pjsnmp_buf[0] = '\0';
+ back = 0;
+ }
+ }
+ } else {
+
+#line 3744 "pjsnmp.ctr"
+ /* ERROR: Write failed */
+ log_1_no_header(122);
+ }
+
+#line 3747 "pjsnmp.ctr"
+ return back;
+}
+
+#endif
+
+
+
+
+
+/** Data exchange with accounting system.
+ The contents of pjsnmp_buf is sent to the accounting system,
+ the response - if any - is stored in pjsnmp_buf.
+ @param expect_response Flag: Accounting system should send response.
+ @return 1 on successfull exchange, 0 on connection error.
+*/
+static
+int
+accounting_exchange(int expect_response)
+{
+ dk4_stat_t stb; /* File status buffer */
+ int issock = 0; /* Flag: File is socket */
+ int back = 0; /* Function result */
+ int crf = 0; /* Flag: Create log file */
+
+
+#line 3771 "pjsnmp.ctr"
+ if ((NULL != acct_host) && (0 < acct_port)) {
+
+#line 3772 "pjsnmp.ctr"
+ log_1_no_header(154);
+ back = accounting_ex_network(expect_response);
+ log_1_no_header((0 != back) ? 159 : 160);
+ } else {
+
+#line 3776 "pjsnmp.ctr"
+ if (NULL != acct_name) {
+
+#line 3777 "pjsnmp.ctr"
+ if ('|' == *acct_name) {
+
+#line 3778 "pjsnmp.ctr"
+#if 0
+ if (0 != expect_response) {
+ /* ERROR: Can not receive response from pipe */
+ log_1_with_header(2, 129);
+ }
+#endif
+ log_1_no_header(155);
+ back = accounting_ex_pipe(expect_response);
+ log_1_no_header((0 != back) ? 159 : 160);
+ } else {
+
+#line 3788 "pjsnmp.ctr"
+ if (0 != dk4stat_c8(&stb, acct_name, NULL)) {
+ if (0 != dk4stat_is_unix_domain_socket(&stb, NULL)) {
+ issock = 1;
+
+#line 3791 "pjsnmp.ctr"
+ }
+ } else {
+ crf = 1;
+
+#line 3794 "pjsnmp.ctr"
+ }
+ if (0 != issock) {
+ log_1_no_header(156);
+ back = accounting_ex_local_socket(expect_response);
+ log_1_no_header((0 != back) ? 159 : 160);
+ } else {
+ if (0 != expect_response) {
+ /* ERROR: Can not receive response from file */
+ log_1_with_header(2, 130);
+ }
+ log_1_no_header(157);
+ back = accounting_ex_filename(expect_response, crf);
+ log_1_no_header((0 != back) ? 159 : 160);
+ }
+ }
+ } else {
+
+#line 3810 "pjsnmp.ctr"
+#if 0
+ log_1_no_header(158);
+ back = accounting_ex_fd3(expect_response);
+ log_1_no_header((0 != back) ? 159 : 160);
+#else
+ log_1_with_header(2, 165);
+#endif
+ }
+ }
+
+#line 3819 "pjsnmp.ctr"
+ return back;
+}
+
+
+
+/** Check users permission to print on queue.
+ @return 1 if user is allowed to print, 0 otherwise.
+*/
+static
+int
+check_permission(void)
+{
+ int back = 1;
+ int res = 0; /* Result from check */
+ const size_t bsz = sizeof(pjsnmp_buf); /* Buffer size */
+
+
+#line 3835 "pjsnmp.ctr"
+ if ((0 != acct_enab) && (0 != acct_achk)) {
+
+#line 3836 "pjsnmp.ctr"
+ /* LOG: Checking print permission */
+ log_5_no_header(131, 132, 133, user_name, queue_name);
+ if(0 != dk4str8_cpy_s(pjsnmp_buf, bsz, pjsnmp_kw[6], NULL)) {
+ if(0 != dk4str8_cat_s(pjsnmp_buf, bsz, pjsnmp_kw[1], NULL)) {
+ if(0 != dk4str8_cat_s(pjsnmp_buf, bsz, queue_name, NULL)) {
+ if(0 != dk4str8_cat_s(pjsnmp_buf, bsz, pjsnmp_kw[1], NULL)) {
+ if(0 != dk4str8_cat_s(pjsnmp_buf, bsz, user_name, NULL)) {
+ if(0 != dk4str8_cat_s(pjsnmp_buf, bsz, pjsnmp_kw[0], NULL)) {
+ back = 0;
+
+#line 3845 "pjsnmp.ctr"
+ if (0 != accounting_exchange(1)) {
+
+#line 3846 "pjsnmp.ctr"
+ dk4str8_normalize(pjsnmp_buf, NULL);
+
+#line 3847 "pjsnmp.ctr"
+ if (0 < strlen(pjsnmp_buf)) {
+
+#line 3848 "pjsnmp.ctr"
+ if (0 != decision) {
+ res = decision - 1;
+ } else {
+ res = dk4str8_array_index(accounting_responses, pjsnmp_buf, 0);
+ if (-1 < res) { decision = res + 1; }
+ }
+ switch (res) {
+ case 0: {
+ back = 1;
+
+#line 3857 "pjsnmp.ctr"
+ } break;
+ case 1: {
+
+#line 3859 "pjsnmp.ctr"
+ exval = LPRNG_EXIT_HOLD;
+ } break;
+ }
+ log_3_no_header(166, 167, pjsnmp_buf);
+ } else {
+
+#line 3864 "pjsnmp.ctr"
+#if 0
+ /* 2016-02-15 An empty response indicates permission
+ to print.
+ */
+ if (0 != acct_apcf) { back = 1; }
+#endif
+ back = 1;
+ }
+ } else {
+
+#line 3873 "pjsnmp.ctr"
+ if (0 != acct_apcf) { back = 1; }
+ else { decision = 3; }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ /* LOG: Test result */
+ log_1_no_header((0 != back) ? 134 : 135);
+ }
+
+#line 3885 "pjsnmp.ctr"
+ return back;
+}
+
+
+
+/** Retrieve integer value from variable list.
+ @param iptr Address of variable to set.
+ @param var SNMP variable containing the value.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+get_int(int *iptr, struct variable_list *var)
+{
+ char bu[64]; /* Buffer for numeric values as text */
+ const char *endptr = NULL; /* First unprocessable character */
+ long l; /* long value */
+ int i; /* int value */
+ int back = 0;
+
+
+#line 3905 "pjsnmp.ctr"
+ switch (var->type) {
+ case ASN_OCTET_STR : {
+
+#line 3907 "pjsnmp.ctr"
+ if ((var->val_len > 0) && (var->val_len < sizeof(bu))) {
+ dk4mem_cpy(bu, (void *)((var->val).string), var->val_len, NULL);
+ bu[var->val_len] = '\0';
+ if (0 != dk4ma_input_c8_dec_int(&i, bu, &endptr, 1, NULL)) {
+ *iptr = i;
+ back = 1;
+ }
+ }
+ } break;
+ case ASN_TIMETICKS :
+ case ASN_GAUGE :
+ case ASN_COUNTER :
+ case ASN_INTEGER : {
+
+#line 3920 "pjsnmp.ctr"
+ l = *((var->val).integer);
+ *iptr = (int)l;
+ back = 1;
+ } break;
+ }
+
+
+#line 3926 "pjsnmp.ctr"
+ return back;
+}
+
+
+
+/** Retrieve unsigned long value from variable list.
+ @param ulptr Address of variable to set.
+ @param var SNMP variable containing the value.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+get_ul(unsigned long *ulptr, struct variable_list *var)
+{
+ unsigned long ul = 0UL; /* Result variable */
+ long l; /* long value */
+ int back = 0;
+
+
+#line 3944 "pjsnmp.ctr"
+ switch (var->type) {
+ case ASN_OCTET_STR : {
+
+#line 3946 "pjsnmp.ctr"
+ if (0 < var->val_len) {
+ ul |=
+ ((((unsigned long)(((var->val).string)[0])) << 24) & 0xFF000000UL);
+ back = 1;
+ }
+ if (1 < var->val_len) {
+ ul |=
+ ((((unsigned long)(((var->val).string)[1])) << 16) & 0x00FF0000UL);
+ }
+ if (2 < var->val_len) {
+ ul |=
+ ((((unsigned long)(((var->val).string)[2])) << 8) & 0x0000FF00UL);
+ }
+ if (3 < var->val_len) {
+ ul |=
+ ((((unsigned long)(((var->val).string)[3])) ) & 0x000000FFUL);
+ }
+ if (0 != back) {
+ *ulptr = ul;
+ }
+ } break;
+ case ASN_TIMETICKS :
+ case ASN_GAUGE :
+ case ASN_COUNTER :
+ case ASN_INTEGER : {
+
+#line 3971 "pjsnmp.ctr"
+ l = *((var->val).integer);
+ if (0L <= l) {
+ *ulptr = (unsigned long)l;
+ back = 1;
+ }
+ } break;
+ }
+
+
+#line 3979 "pjsnmp.ctr"
+ return back;
+}
+
+
+
+/** Check whether a buffer contains non-ASCII characters.
+ @param ptr Buffer address.
+ @param i Buffer size.
+ @return 1 if non-ASCII found, 0 otherwise.
+*/
+static
+int
+contains_non_ascii(const char *ptr, size_t i)
+{
+ int back = 0;
+
+
+#line 3995 "pjsnmp.ctr"
+ while ((0 == back) && (0 < i)) {
+ if (0x7F < (unsigned char)(*(ptr++))) {
+ back = 1;
+ }
+ i--;
+ }
+
+#line 4001 "pjsnmp.ctr"
+ return back;
+}
+
+
+
+/** Replace all non-ascii characters by question marks.
+*/
+static
+void
+no_non_ascii(char *str)
+{
+ unsigned char uc;
+ while ('\0' != *str) {
+ uc = (unsigned char)(*str);
+ if ((0x20 > uc) || (0x7E < uc)) {
+ *str = '?';
+ }
+ str++;
+ }
+}
+
+
+
+
+/** Check two OIDs for equality.
+ @param pl Left OID.
+ @param szl Left OID size.
+ @param pr Right OID.
+ @param szr Right OID size.
+ @return 1 for equal OIDs, 0 otherwise.
+*/
+static
+int
+oids_equal(const oid *pl, size_t szl, const oid *pr, size_t szr)
+{
+#if VERSION_BEFORE_20160206
+ size_t i; /* Index of current sub-id to compare */
+#endif
+ int back = 0;
+ if ((szl == szr) && (0 < szl)) {
+#if VERSION_BEFORE_20160206
+ back = 1;
+ for (i = 0; ((i < szl) && (1 == back)); i++) {
+ if (pl[i] != pr[i]) {
+ back = 0;
+ }
+ }
+#else
+ /* No check for overflow necessary, max 4 * 128. */
+ if (0 == dk4mem_cmp(pl, pr, (szl * sizeof(oid)), NULL)) {
+ back = 1;
+ }
+#endif
+ }
+ return back;
+}
+
+
+/** Find OID index.
+ @param oid Pointer to OID to check.
+ @param sz OID size.
+ @return 0 for hrDeviceStatus, 1 for hrPrinterStatus,
+ 2 for page counter, 3 for hrPrinterDetectedErrorState,
+ 4 for status text,
+ -1 otherwise.
+*/
+static
+int
+oid_index(oid *p, size_t sz)
+{
+ int back = -1;
+
+
+#line 4073 "pjsnmp.ctr"
+ if (0 != oids_equal(p, sz, oid_ds, sz_oid_ds)) {
+ back = 0;
+ } else {
+ if (0 != oids_equal(p, sz, oid_ps, sz_oid_ps)) {
+ back = 1;
+ } else {
+ if (0 != oids_equal(p, sz, oid_pc, sz_oid_pc)) {
+ back = 2;
+ } else {
+ if (0 != oids_equal(p, sz, oid_pe, sz_oid_pe)) {
+ back = 3;
+ } else {
+ if (0 < sz_oid_st) {
+
+#line 4086 "pjsnmp.ctr"
+ if (0 != oids_equal(p, sz, oid_st, sz_oid_st)) {
+ back = 4;
+ }
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 4092 "pjsnmp.ctr"
+ }
+#endif
+ }
+ }
+ }
+ }
+
+#line 4098 "pjsnmp.ctr"
+ return back;
+}
+
+
+
+/** Show one active condition from hrPrinterDetectedErrorState.
+ @param cond Condition bit (checked against the found conditions).
+ @param cind Index of corresponding text in pjsnmp_kw.
+*/
+static
+void
+show_pdes(unsigned long cond, size_t cind)
+{
+ if (0UL != (pdes_cond & cond)) {
+ fputs(pjsnmp_kw[((0UL != (pdes_error & cond)) ? 32 : 33)], out_file);
+ fputs(pjsnmp_kw[cind], out_file);
+ }
+}
+
+
+
+static
+void
+show_text_containing_non_ascii(const unsigned char *ptr, size_t num)
+{
+ while(0 < num--) {
+ if (0x7F < *ptr) {
+ fputc('?', out_file);
+ } else {
+ fputc(*ptr, out_file);
+ }
+ ptr++;
+ }
+}
+
+
+
+/** Report status if changed.
+ @param found Bitmask for found information.
+*/
+static
+void
+report_status_if_changed(int found)
+{
+ unsigned long tcond = 0x80000000UL; /* Bit for one condition */
+ int must_report = 0; /* Flag: Must report change */
+ int i;
+
+
+#line 4146 "pjsnmp.ctr"
+ /* Check whether or not to report.
+ */
+ if (stsum != ostsum) {
+
+#line 4149 "pjsnmp.ctr"
+ must_report = 1;
+ } else {
+ if (devst != odevst) {
+
+#line 4152 "pjsnmp.ctr"
+ must_report = 1;
+ } else {
+ if (prist != oprist) {
+
+#line 4155 "pjsnmp.ctr"
+ must_report = 1;
+ } else {
+ if (pdes_cond != opdes_cond) {
+
+#line 4158 "pjsnmp.ctr"
+ must_report = 1;
+ } else {
+ if (0 < sz_stat_text) {
+ if (0 != force_printable_status_text) {
+ if (sz_ostat_text != sz_stat_text) {
+ must_report = 1;
+ } else {
+ if (0 != dk4mem_cmp(stat_text,ostat_text,sz_stat_text,NULL)) {
+ must_report = 1;
+ }
+ }
+ } else {
+ if (0 == contains_non_ascii(stat_text, sz_stat_text)) {
+ if (sz_stat_text != sz_ostat_text) {
+ must_report = 1;
+
+#line 4173 "pjsnmp.ctr"
+ } else {
+ if (0 != dk4mem_cmp(stat_text,ostat_text,sz_stat_text,NULL)) {
+ must_report = 1;
+
+#line 4176 "pjsnmp.ctr"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* Report if necessary.
+ */
+ if (0 != must_report) {
+
+#line 4189 "pjsnmp.ctr"
+ fputs(pjsnmp_kw[150], out_file);
+ (void)log_timestamp();
+ if ((-1 < devst) && (6 > devst)) {
+ if ((-1 < prist) && (6 > prist)) {
+ fputs(pjsnmp_kw[7], out_file);
+ fputs(pjsnmp_kw[11 + devst], out_file);
+ fputs(pjsnmp_kw[8], out_file);
+ fputs(pjsnmp_kw[17 + prist], out_file);
+ fputs(pjsnmp_kw[0], out_file);
+ }
+ }
+ fputs(pjsnmp_kw[9], out_file);
+ for (i = 0; i < 16; i++) {
+ if ((0 < i) && (0 == (i % 4))) { fputc('-', out_file); }
+ fputc(((0UL != (pdes_cond & tcond)) ? '1' : '0'), out_file);
+ tcond = tcond / 2UL;
+ }
+ fputs(pjsnmp_kw[0], out_file);
+ show_pdes(PDES_ERROR_DOOR_OPEN, 38);
+ show_pdes(PDES_ERROR_OFFLINE, 40);
+ show_pdes(PDES_ERROR_MARKER_SUPPLY_MISSING, 44);
+ show_pdes(PDES_ERROR_NO_TONER, 37);
+ show_pdes(PDES_WARNING_TONER_LOW, 36);
+ show_pdes(PDES_ERROR_INPUT_TRAY_MISSING, 42);
+ show_pdes(PDES_WARNING_INPUT_TRAY_EMPTY, 47);
+ show_pdes(PDES_ERROR_NO_PAPER, 35);
+ show_pdes(PDES_WARNING_PAPER_LOW, 34);
+ show_pdes(PDES_ERROR_OUTPUT_TRAY_MISSING, 43);
+ show_pdes(PDES_ERROR_PAPER_JAM, 39);
+ show_pdes(PDES_ERROR_OUTPUT_FULL, 46);
+ show_pdes(PDES_WARNING_OUTPUT_NEAR_FULL, 45);
+ show_pdes(PDES_WARNING_SERVICE, 41);
+ show_pdes(PDES_WARNING_OVERDUE_PREVENT_MAINT, 48);
+ if (0 < sz_stat_text) {
+ if (0 != force_printable_status_text) {
+ fputs(pjsnmp_kw[30], out_file);
+ show_text_containing_non_ascii((unsigned char *)stat_text,sz_stat_text);
+ fputs(pjsnmp_kw[31], out_file);
+ } else {
+ if (0 == contains_non_ascii(stat_text, sz_stat_text)) {
+ fputs(pjsnmp_kw[30], out_file);
+ fwrite(stat_text, 1, sz_stat_text, out_file);
+ fputs(pjsnmp_kw[31], out_file);
+ }
+ }
+ }
+ if ((-1 < stsum) && (7 > stsum)) {
+ fputs(pjsnmp_kw[10], out_file);
+ fputs(pjsnmp_kw[23 + stsum], out_file);
+ fputs(pjsnmp_kw[0], out_file);
+ }
+ if (PJSNMP_ST_ERROR == stsum) {
+ fputs(pjsnmp_kw[49], out_file);
+ } else {
+ if (0UL != (pdes_cond & PDES_WARNING_SERVICE)) {
+ if (0UL == (pdes_error & PDES_WARNING_SERVICE)) {
+ fputs(pjsnmp_kw[50], out_file);
+ }
+ }
+ }
+ fflush(out_file);
+ }
+
+
+#line 4252 "pjsnmp.ctr"
+}
+
+
+
+/** One SNMP data exchange.
+ @param passno 0 before start, 1 during transfer, 2 at end.
+ @return 1 on success, 0 on error (stop printing).
+*/
+static
+int
+one_snmp_request(int passno)
+{
+ status_text_t tx; /* Used in comparison */
+ status_text_t *ptx = NULL; /* Text node found */
+ struct snmp_pdu *rq = NULL; /* Request */
+ struct snmp_pdu *rs = NULL; /* Response */
+ struct variable_list *vars = NULL; /* Response variables */
+ int status = 0; /* SNMP result */
+ int found = 0; /* Information from response */
+ int back = 0;
+
+
+#line 4273 "pjsnmp.ctr"
+ if (0 != can_continue(0)) {
+
+#line 4274 "pjsnmp.ctr"
+ if (NULL != snmp_sess) {
+
+#line 4275 "pjsnmp.ctr"
+ pdes_cond = 0UL;
+ pcnt = 0UL;
+ devst = 0;
+ prist = 0;
+ stsum = PJSNMP_ST_UNREACHABLE;
+ stat_text[0] = '\0';
+ sz_stat_text = 0;
+ rq = snmp_pdu_create(SNMP_MSG_GET);
+ if (NULL != rq) {
+
+#line 4284 "pjsnmp.ctr"
+ back = 1;
+ snmp_add_null_var(rq, oid_ds, sz_oid_ds);
+ snmp_add_null_var(rq, oid_ps, sz_oid_ps);
+ snmp_add_null_var(rq, oid_pc, sz_oid_pc);
+ snmp_add_null_var(rq, oid_pe, sz_oid_pe);
+ if (0 < sz_oid_st) {
+
+#line 4290 "pjsnmp.ctr"
+ snmp_add_null_var(rq, oid_st, sz_oid_st);
+ }
+ status = snmp_synch_response(snmp_sess, rq, &rs);
+ if (STAT_SUCCESS == status) {
+
+#line 4294 "pjsnmp.ctr"
+ if (NULL != rs) {
+
+#line 4295 "pjsnmp.ctr"
+ if (SNMP_ERR_NOERROR == rs->errstat) {
+
+#line 4296 "pjsnmp.ctr"
+
+ /* Obtain response elements.
+ */
+ stsum = PJSNMP_ST_UNKNOWN;
+ vars = rs->variables;
+ while (NULL != vars) {
+ switch (oid_index(vars->name, vars->name_length)) {
+ case 0: {
+
+#line 4304 "pjsnmp.ctr"
+ if (0 != get_int(&devst, vars)) {
+
+#line 4305 "pjsnmp.ctr"
+ found |= 1;
+ }
+ } break;
+ case 1: {
+
+#line 4309 "pjsnmp.ctr"
+ if (0 != get_int(&prist, vars)) {
+
+#line 4310 "pjsnmp.ctr"
+ found |= 2;
+ }
+ } break;
+ case 2: {
+
+#line 4314 "pjsnmp.ctr"
+ if (0 != get_ul(&pcnt, vars)) {
+
+#line 4315 "pjsnmp.ctr"
+ found |= 4;
+
+#line 4316 "pjsnmp.ctr"
+ switch (passno) {
+ case 0: {
+ pc_start = pcnt;
+ have_pcs = 1;
+ } break;
+ case 1: {
+ /* When aborting due to timeout in
+ error or unreachable state we use the
+ last page counter seen.
+ */
+ pc_end = pcnt;
+ have_pce = 1;
+ } break;
+ case 2: {
+ pc_end = pcnt;
+ have_pce = 1;
+ } break;
+ }
+ }
+ } break;
+ case 3: {
+
+#line 4337 "pjsnmp.ctr"
+ if (0 != get_ul(&pdes_cond, vars)) { found |= 8; }
+ } break;
+ case 4: {
+
+#line 4340 "pjsnmp.ctr"
+ if (0 < vars->val_len) {
+ if (sizeof(stat_text) > vars->val_len) {
+
+#line 4342 "pjsnmp.ctr"
+ dk4mem_cpy(
+ stat_text, (vars->val).string,
+ vars->val_len, NULL
+ );
+ sz_stat_text = vars->val_len;
+ } else {
+
+#line 4348 "pjsnmp.ctr"
+ dk4mem_cpy(
+ stat_text, (vars->val).string,
+ sizeof(stat_text), NULL
+ );
+ sz_stat_text = sizeof(stat_text);
+ }
+ found |= 16;
+ }
+ } break;
+ }
+ vars = vars->next_variable;
+ }
+
+ /* Build summary (1): device and printer status.
+ */
+ if (3 == (3 & found)) {
+ stsum = get_state_mapping(devst, prist);
+
+
+#line 4366 "pjsnmp.ctr"
+ }
+
+ /* Build summary (2): printer detected error state
+ */
+ if (8 == (8 & found)) {
+ if ((0 != pdes_always) || (PJSNMP_ST_UNKNOWN == stsum)) {
+ if (0L != (pdes_error & pdes_cond)) {
+ stsum = PJSNMP_ST_ERROR;
+
+#line 4374 "pjsnmp.ctr"
+ }
+ }
+ }
+
+ /* Build summary (3): status text line
+ */
+ if (16 == (16 & found)) {
+ if ((0 != stat_always) || (PJSNMP_ST_UNKNOWN == stsum)) {
+ if ((NULL != s_stn) && (NULL != i_stn)) {
+ DK4_MEMRES(&tx, sizeof(tx));
+ tx.text = (unsigned char *)stat_text;
+ tx.size = sz_stat_text;
+ tx.state = 0;
+ tx.start = 0;
+ ptx = (status_text_t *)dk4sto_it_find_like(i_stn, &tx, 1);
+ if (NULL != ptx) {
+ stsum = ptx->state;
+
+
+#line 4392 "pjsnmp.ctr"
+ }
+ }
+ }
+ }
+
+ /* Build summary (4): Map unknown to busy if configured
+ */
+ if ((0 != unkn_busy) && (PJSNMP_ST_UNKNOWN == stsum)) {
+ stsum = PJSNMP_ST_BUSY;
+
+#line 4401 "pjsnmp.ctr"
+ }
+
+ /* For error state mark this page counter as print
+ job not yet finished.
+ */
+ switch (stsum) {
+ case PJSNMP_ST_ERROR: {
+ seen_printing = 0;
+
+#line 4409 "pjsnmp.ctr"
+ if ((0 < passno) && (0UL < pcnt)) {
+ pc_error = pcnt;
+
+#line 4411 "pjsnmp.ctr"
+ }
+ start_unreach = (dk4_time_t)0UL;
+ if ((dk4_time_t)0UL == start_error) {
+ dk4time_get(&start_error);
+ }
+ } break;
+ case PJSNMP_ST_BUSY: {
+ seen_printing = 1;
+
+#line 4419 "pjsnmp.ctr"
+ start_unreach = (dk4_time_t)0UL;
+ start_error = (dk4_time_t)0UL;
+ } break;
+ case PJSNMP_ST_UNREACHABLE : {
+ if ((dk4_time_t)0UL == start_unreach) {
+ dk4time_get(&start_unreach);
+ }
+ start_error = (dk4_time_t)0UL;
+ } break;
+ default : {
+ start_unreach = (dk4_time_t)0UL;
+ start_error = (dk4_time_t)0UL;
+ } break;
+ }
+
+ /* On change, print new state.
+ */
+ report_status_if_changed(found);
+
+ /* Save data for next comparison.
+ */
+ odevst = devst;
+ oprist = prist;
+ ostsum = stsum;
+ opdes_cond = pdes_cond;
+ if (0 < sz_stat_text) {
+ DK4_MEMCPY(ostat_text, stat_text, sz_stat_text);
+ }
+ sz_ostat_text = sz_stat_text;
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 4451 "pjsnmp.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 4456 "pjsnmp.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 4461 "pjsnmp.ctr"
+ }
+#endif
+ if (NULL != rs) {
+ snmp_free_pdu(rs);
+ }
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 4469 "pjsnmp.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 4474 "pjsnmp.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 4479 "pjsnmp.ctr"
+ }
+#endif
+
+
+#line 4482 "pjsnmp.ctr"
+ return back;
+}
+
+
+
+/** Create accounting text line and do data exchange
+ with accounting system.
+ @param kwind Index of start keyword in pjsnmp_kw array.
+ @param pc Page counter value to transmit.
+*/
+static
+void
+accounting_index_and_value(size_t kwind, unsigned long pc)
+{
+ char buf[64]; /* Buffer for number as text */
+ const char *jt; /* Job title */
+ size_t szbuf = sizeof(pjsnmp_buf); /* Buffer size */
+ size_t sl;
+ int res; /* Conversion result */
+
+
+#line 4502 "pjsnmp.ctr"
+ res = dk4ma_write_c8_decimal_unsigned(
+ buf, sizeof(buf), (dk4_um_t)pc, 0, NULL
+ );
+ if (0 != res) {
+ if (0 != dk4str8_cpy_s(pjsnmp_buf, szbuf, pjsnmp_kw[kwind], NULL)) {
+ if (0 != dk4str8_cat_s(pjsnmp_buf, szbuf, pjsnmp_kw[1], NULL)) {
+ if (0 != dk4str8_cat_s(pjsnmp_buf, szbuf, queue_name, NULL)) {
+ if (0 != dk4str8_cat_s(pjsnmp_buf, szbuf, pjsnmp_kw[1], NULL)) {
+ if (0 != dk4str8_cat_s(pjsnmp_buf, szbuf, user_name, NULL)) {
+ if (0 != dk4str8_cat_s(pjsnmp_buf, szbuf, pjsnmp_kw[1], NULL)) {
+ if (0 != dk4str8_cat_s(pjsnmp_buf, szbuf, buf, NULL)) {
+ if (0 != dk4str8_cat_s(pjsnmp_buf, szbuf, pjsnmp_kw[1], NULL)) {
+ if (0 != dk4str8_cat_s(pjsnmp_buf, szbuf, job_name, NULL)) {
+ if (0 != dk4str8_cat_s(pjsnmp_buf, szbuf, pjsnmp_kw[1], NULL)) {
+ jt = job_title;
+ if (NULL == jt) { jt = pjsnmp_kw[54]; }
+ sl = strlen(pjsnmp_buf);
+ if (0 != dk4str8_cat_s(pjsnmp_buf, szbuf, jt, NULL)) {
+ if (0 == allow_non_ascii) { no_non_ascii(&(pjsnmp_buf[sl])); }
+ if (0 != dk4str8_cat_s(pjsnmp_buf, szbuf, pjsnmp_kw[0], NULL)) {
+
+
+#line 4523 "pjsnmp.ctr"
+ (void)accounting_exchange(0);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+#line 4537 "pjsnmp.ctr"
+}
+
+
+/** Report used pages to accounting system.
+*/
+static
+void
+report_used_pages(void)
+{
+
+
+#line 4547 "pjsnmp.ctr"
+ if (0 != acct_start_end) {
+ accounting_index_and_value(51, pc_start);
+ accounting_index_and_value(52, pc_end);
+ } else {
+ accounting_index_and_value(53, (pc_end - pc_start));
+ }
+
+
+#line 4554 "pjsnmp.ctr"
+}
+
+
+
+/** Do accounting before and after print job.
+ @param passno 0=before print job, 1=after print job.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+do_accounting(int passno)
+{
+ static
+ char buf[8*sizeof(dk4_um_t)]; /* Number as text */
+ struct timeval to; /* Timeout for select */
+ dk4_time_t start_idle = (dk4_time_t)0UL; /* Start idle/standby */
+ dk4_time_t current_time = (dk4_time_t)0UL; /* Current time */
+ dk4_time_t timeout_time = (dk4_time_t)0UL; /* Timeout reached */
+ int res = 0; /* Conversion result */
+ int back = 0;
+ int cc = 1; /* Flag: Can continue */
+ int uncoi = 0; /* Flag: Unconditional idle reported */
+ int cto = 0; /* Flag: Must check timeout */
+
+
+#line 4578 "pjsnmp.ctr"
+ if (NULL != snmp_sess) {
+
+#line 4579 "pjsnmp.ctr"
+ /* In the loop retrieve printer status via SNMP,
+ finish if printer is idle or in standby state.
+ */
+ log_1_no_header(145+passno);
+ do {
+ if (0 != can_continue(0)) {
+
+#line 4585 "pjsnmp.ctr"
+ if (0 != one_snmp_request((0 == passno) ? 0 : 2)) {
+
+
+#line 4587 "pjsnmp.ctr"
+
+ /* In idle or standby we can retrieve the page counter
+ if the page counter was changed or the printer was seen
+ printing.
+ */
+ switch (stsum) {
+ case PJSNMP_ST_IDLE : case PJSNMP_ST_STANDBY : {
+ back = 1; cc = 0;
+
+#line 4595 "pjsnmp.ctr"
+ cto = 0;
+ if (1 == passno) {
+ if ((0 == seen_printing) && (0 < print_timeout)) {
+ cto = 1;
+
+#line 4599 "pjsnmp.ctr"
+ } else {
+ if ((0UL != pc_error) && (1 == have_pce)) {
+ if ((pc_end == pc_error)&&((dk4_um_t)0UL < print_timeout)) {
+ cto = 1;
+
+#line 4603 "pjsnmp.ctr"
+ }
+ }
+ }
+ if (0 != cto) {
+ dk4time_get(&current_time);
+ if ((dk4_time_t)0UL < start_idle) {
+ if ((start_idle+(dk4_time_t)print_timeout) > current_time) {
+ back = 0; cc = 1;
+
+#line 4611 "pjsnmp.ctr"
+ }
+ } else {
+ start_idle = current_time;
+ back = 0; cc = 1;
+ if (0 == uncoi) {
+ uncoi = 1;
+ res = dk4ma_write_c8_decimal_unsigned(
+ buf, sizeof(buf), print_timeout, 0, NULL
+ );
+ log_timestamp();
+ fputs(pjsnmp_kw[162], out_file);
+ if (0 != res) {
+ fputs(buf, out_file);
+ fputs(pjsnmp_kw[163], out_file);
+ }
+ fputs(pjsnmp_kw[164], out_file);
+ fflush(out_file);
+ }
+ }
+ }
+ }
+ } break;
+ case PJSNMP_ST_UNREACHABLE : {
+ start_idle = (dk4_time_t)0UL; /* not idle */
+ uncoi = 0;
+ /* If printer is unreachable we abort after timeout.
+ */
+ if (((0 == passno) && ((dk4_um_t)0UL != unto_start))
+ || ((1 == passno) && ((dk4_um_t)0UL != unto_end))
+ )
+ {
+ if ((dk4_time_t)0UL < start_unreach) {
+ dk4time_get(&current_time);
+ timeout_time =
+ start_unreach
+ + (dk4_time_t)((0 == passno) ? unto_start : unto_end);
+ if (current_time > timeout_time) {
+
+#line 4648 "pjsnmp.ctr"
+ cc = 0;
+ /* ERROR: Timeout while printer unreachable */
+ log_1_no_header(136);
+ }
+ } else {
+ dk4time_get(&start_unreach);
+ }
+ }
+ } break;
+ case PJSNMP_ST_ERROR : {
+ start_idle = (dk4_time_t)0UL; /* not idle */
+ uncoi = 0;
+ if (
+ ((0 == passno) && ((dk4_um_t)0UL < erto_start))
+ || ((1 == passno) && ((dk4_um_t)0UL < erto_end))
+ )
+ {
+ if ((dk4_um_t)0UL < start_error) {
+ dk4time_get(&current_time);
+ timeout_time =
+ start_error
+ + (dk4_time_t)((0 == passno) ? erto_start : erto_end);
+ if (current_time > timeout_time) {
+ cc = 0;
+ /* ERROR: Timeout while printer in error state */
+ log_1_no_header(168);
+ if (0 == passno) {
+ back = 0; /* Do not print */
+ }
+ }
+ } else {
+ dk4time_get(&start_error);
+ }
+ }
+ } break;
+ default: {
+ start_idle = (dk4_time_t)0UL; /* not idle */
+ uncoi = 0;
+ } break;
+ }
+
+ /* Decrease cpu and network load from polling
+ */
+ if (1 == cc) {
+ if (0 != can_continue(0)) {
+ if (PJSNMP_ST_UNREACHABLE == stsum) {
+ sleep(1);
+ } else {
+ to.tv_sec = 0L;
+ to.tv_usec = 250000L;
+ (void)select(0, NULL, NULL, NULL, &to);
+ }
+ } else {
+ cc = -1;
+ }
+ }
+
+ } else {
+
+#line 4706 "pjsnmp.ctr"
+ cc = -1;
+ }
+ } else {
+
+#line 4709 "pjsnmp.ctr"
+ cc = -1;
+ }
+ } while(1 == cc);
+ fputs(pjsnmp_kw[150], out_file);
+ if (((0 == passno)&&(0 != have_pcs))||((1 == passno)&&(0 != have_pce))) {
+
+
+#line 4715 "pjsnmp.ctr"
+ res = dk4ma_write_c8_decimal_unsigned(buf, sizeof(buf), pcnt, 0, NULL);
+ if (0 != res) {
+
+
+#line 4718 "pjsnmp.ctr"
+ log_3_no_header((147+passno), 0, buf);
+
+
+#line 4720 "pjsnmp.ctr"
+ }
+
+
+#line 4722 "pjsnmp.ctr"
+ } else {
+
+
+#line 4724 "pjsnmp.ctr"
+ log_1_no_header(149);
+
+
+#line 4726 "pjsnmp.ctr"
+ }
+
+ /* Save page counter at start to page counter unusable for
+ print job finished.
+ */
+ if (0 == passno) {
+ if (0 != have_pcs) {
+ pc_error = pc_start;
+ }
+ }
+ /* After successful page counting at job end, report to
+ accounting system.
+ */
+ if (1 == passno) {
+
+#line 4740 "pjsnmp.ctr"
+ if ((0 != have_pcs) && (0 != have_pce)) {
+
+#line 4741 "pjsnmp.ctr"
+ if (pc_end > pc_start) {
+
+#line 4742 "pjsnmp.ctr"
+ /* Report number of used pages to accounting system */
+ report_used_pages();
+ }
+ }
+ }
+ } else {
+
+#line 4748 "pjsnmp.ctr"
+ if (0 != snmp_igfs) {
+
+#line 4749 "pjsnmp.ctr"
+ back = 1;
+ }
+ }
+
+#line 4752 "pjsnmp.ctr"
+ return back;
+}
+
+
+
+/** Transfer data to printer.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+data_transfer(void)
+{
+ fd_set wfds; /* Writable files set */
+ fd_set rfds; /* Readable files set */
+ struct timeval to; /* Timeout for select */
+ char *wrptr; /* Pointer to data to write */
+ dk4_time_t unwriteable; /* Socket started to be unwriteable */
+ dk4_time_t current; /* Current time */
+ dk4_time_t tots; /* Timestamp when timeout is reached */
+ size_t rdb; /* Number of bytes read from stdin */
+ size_t remaining; /* Remaining bytes to write to socket */
+ size_t wrb; /* Bytes currently written to socket */
+ dk4_socket_t sock; /* Network socket to printer */
+ int back = 0;
+ int cc = 1; /* Flag: Can continue */
+ int ccwr; /* Flag: Can continue writing */
+ int res; /* Number conversion result */
+ int writable; /* Flag: Socket is writeable */
+
+
+#line 4781 "pjsnmp.ctr"
+ unwriteable = (dk4_time_t)0UL;
+ if ((NULL != host_name) && (0 < host_port)) {
+ sock = dk4socket_c8_tcp_client_host_port(
+ host_name, host_port, local_port, 0L, 0L, NULL
+ );
+ if (INVALID_SOCKET != sock) {
+ exval = LPRNG_EXIT_SUCCESS;
+ dk4time_get(&t2);
+ back = 1;
+ log_1_no_header(151);
+ do {
+ if (0 != can_continue(0)) {
+ rdb = fread(pjsnmp_buf, 1, sizeof(pjsnmp_buf), stdin);
+ if (0 < rdb) {
+ wrptr = pjsnmp_buf;
+ remaining = rdb;
+ ccwr = 1;
+ do {
+ if (0 != can_continue(0)) {
+ writable = 0;
+ FD_ZERO(&wfds);
+ FD_SET(sock,&wfds);
+ if (0 != read_responses) {
+ FD_ZERO(&rfds);
+ FD_SET(sock,&rfds);
+ }
+ to.tv_sec = 0L;
+ to.tv_usec = 250000L;
+ if (0 != read_responses) {
+ res = select((sock + 1), &rfds, &wfds, NULL, &to);
+ } else {
+ res = select((sock + 1), NULL, &wfds, NULL, &to);
+ }
+ if (0 < res) {
+ if (FD_ISSET(sock,&wfds)) {
+ writable = 1;
+ unwriteable = (dk4_time_t)0UL;
+ } else {
+ if (0 != unwt_print) {
+ dk4time_get(&current);
+ if ((dk4_time_t)0UL != unwriteable) {
+ tots = unwriteable + (dk4_time_t)unwt_print;
+ if (current > tots) {
+ cc = ccwr = -1;
+ /* ERROR: Timeout, socket unwriteable */
+ log_1_no_header(137);
+ }
+ } else {
+ unwriteable = current;
+ }
+ }
+ }
+ if (0 != read_responses) {
+ if (FD_ISSET(sock,&rfds)) {
+ wrb = sizeof(dummy_text);
+ res = dk4socket_recv(sock,dummy_text,&wrb,0,0L,0L,NULL);
+ }
+ }
+ }
+ if (0 != can_continue(0)) {
+ if ((0 == writable) || (0 != check_trans)) {
+ if (0 != one_snmp_request(1)) {
+ switch (stsum) {
+ case PJSNMP_ST_UNREACHABLE : {
+ if ((dk4_um_t)0UL < unto_print) {
+ if ((dk4_time_t)0UL < start_unreach) {
+ tots = start_unreach + (dk4_time_t)unto_print;
+ dk4time_get(&current);
+ if (current > tots) {
+ cc = ccwr = -1;
+ /* ERROR: Timeout, printer start_unreach */
+ log_1_no_header(136);
+ }
+ } else {
+ dk4time_get(&start_unreach);
+ }
+ }
+ } break;
+ case PJSNMP_ST_ERROR : {
+ if ((dk4_um_t)0UL < erto_print) {
+ if ((dk4_time_t)0UL < start_error) {
+ tots = start_error + (dk4_time_t)erto_print;
+ dk4time_get(&current);
+ if (current > tots) {
+ cc = ccwr = -1;
+ /* ERROR: Timeout, printer start_unreach */
+ log_1_no_header(168);
+ }
+ } else {
+ dk4time_get(&start_error);
+ }
+ }
+ } break;
+ }
+ }
+ }
+ if (0 != can_continue(0)) {
+ wrb = remaining;
+ res = dk4socket_send(sock, wrptr, &wrb, 0, 0L, 0L, NULL);
+ switch (res) {
+ case DK4_SOCKET_RESULT_SUCCESS:
+ case DK4_SOCKET_RESULT_IN_PROGRESS :
+ {
+ if (0 < wrb) {
+ bytes_trans = dk4ma_um_add(bytes_trans,wrb,&er_bytes);
+ if (wrb < remaining) {
+ remaining = remaining - wrb;
+ wrptr = &(wrptr[wrb]);
+ } else {
+ remaining = 0;
+ ccwr = 0;
+ }
+ }
+ } break;
+ default: {
+ /* ERROR: Failed to send data */
+ log_1_no_header(138);
+ ccwr = -1; cc = -1; back = 0;
+ } break;
+ }
+ } else {
+ ccwr = -1; cc = -1; back = 0;
+ }
+ } else {
+ ccwr = -1; cc = -1; back = 0;
+ }
+ } else {
+ ccwr = -1; cc = -1; back = 0;
+ }
+ } while (1 == ccwr);
+ } else {
+ have_eof = 1;
+ cc = 0;
+ if (0 != ferror(stdin)) {
+ /* ERROR: Failed to read from standard input */
+ log_1_no_header(139);
+ }
+ }
+ } else {
+ cc = -1;
+ back = 0;
+ }
+ } while (1 == cc);
+ log_1_no_header((0 == cc) ? 152 : 153);
+ if (0 == cc) {
+ if (0 != host_ordr) {
+ res = dk4socket_shutdown(sock, DK4_SOCKET_SHUT_WRITE, NULL);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ cc = 1;
+ do {
+ if (0 != can_continue(0)) {
+ wrb = sizeof(pjsnmp_buf);
+ res = dk4socket_recv(sock, pjsnmp_buf, &wrb, 0, 0L, 0L, NULL);
+ switch (res) {
+ case DK4_SOCKET_RESULT_SUCCESS: {
+ if (0 == wrb) {
+ cc = 0;
+ }
+ } break;
+ default: {
+ cc = -1;
+ } break;
+ }
+ } else {
+ cc = -1;
+ back = 0;
+ }
+ } while (1 == cc);
+ }
+ }
+ }
+ dk4socket_close(sock, NULL);
+ dk4time_get(&t3);
+ } else {
+
+#line 4955 "pjsnmp.ctr"
+ /* ERROR: Failed to connect */
+ log_1_no_header(140);
+ }
+ } else {
+
+#line 4959 "pjsnmp.ctr"
+ }
+
+
+#line 4961 "pjsnmp.ctr"
+ return back;
+}
+
+
+
+/** Write one line of final statistics.
+ @param b Text containing a number.
+ @param max Maximum number width.
+ @param i1 Index in pjsnmp_kw of text before number.
+ @param i2 Index in pjsnmp_kw of text after number.
+*/
+static
+void
+final_stat_line(const char *b, size_t max, size_t i1, size_t i2)
+{
+ size_t sl; /* String length of number */
+
+ sl = strlen(b);
+ fputs(pjsnmp_kw[i1], out_file);
+ while (sl++ < max) { fputc(' ', out_file); }
+ fputs(b, out_file);
+ fputs(pjsnmp_kw[i2], out_file);
+}
+
+
+
+/** Issue final statistics.
+*/
+static
+void
+final_statistics(void)
+{
+ char b1[64]; /* Number of bytes */
+ char b2[64]; /* Transfer time */
+ char b3[64]; /* Processing time */
+ char b4[64]; /* Number of pages */
+ size_t max; /* Maximum of all sizes */
+ size_t sl; /* Current size */
+ int res; /* Conversion result */
+ int found = 0; /* Information found */
+
+ /* Initialize buffers.
+ */
+ b1[0] = '\0'; b2[0] = '\0'; b3[0] = '\0'; b4[0] = '\0';
+
+ /* Convert numbers to strings.
+ */
+ if (DK4_E_NONE == er_bytes.ec) {
+ res = dk4ma_write_c8_decimal_unsigned(
+ b1, sizeof(b1), (dk4_um_t)bytes_trans, 0, NULL
+ );
+ if (0 == res) { b1[0] = '\0'; }
+ else { found |= 1; }
+ }
+ if (((dk4_time_t)0UL != t2) && ((dk4_time_t)0UL != t3)) {
+ res = dk4ma_write_c8_decimal_unsigned(
+ b2, sizeof(b2), (dk4_um_t)(t3 - t2), 0, NULL
+ );
+ if (0 == res) { b2[0] = '\0'; }
+ else { found |= 2; }
+ }
+ res = dk4ma_write_c8_decimal_unsigned(
+ b3, sizeof(b3), (dk4_um_t)(t4 - t1), 0, NULL
+ );
+ if (0 == res) { b3[0] = '\0'; }
+ else { found |= 4; }
+ if ((0 != have_pcs) && (0 != have_pce)) {
+ res = dk4ma_write_c8_decimal_unsigned(
+ b4, sizeof(b4), (dk4_um_t)(pc_end - pc_start), 0, NULL
+ );
+ if (0 == res) { b4[0] = '\0'; }
+ else { found |= 8; }
+ }
+
+ /* Find maximum string length.
+ */
+ max = 0;
+ if (0 != (1 & found)) {
+ max = sl = strlen(b1);
+ }
+ if (0 != (2 & found)) {
+ sl = strlen(b2);
+ if (sl > max) max = sl;
+ }
+ if (0 != (4 & found)) {
+ sl = strlen(b3);
+ if (sl > max) max = sl;
+ }
+ if (0 != (8 & found)) {
+ sl = strlen(b4);
+ if (sl > max) max = sl;
+ }
+
+ /* Write texts.
+ */
+ fputs(pjsnmp_kw[55], out_file);
+ (void)log_timestamp();
+ if (0 != (1 & found)) {
+ final_stat_line(b1, max, 56, 60);
+ }
+ if (0 != (2 & found)) {
+ final_stat_line(b2, max, 57, 61);
+ }
+ if (0 != (4 & found)) {
+ final_stat_line(b3, max, 58, 61);
+ }
+ if (0 != (8 & found)) {
+ final_stat_line(b4, max, 59, 0);
+ }
+ if (0 != found) {
+ fflush(out_file);
+ }
+}
+
+
+
+/** Initialization at startup.
+*/
+static
+void
+initialize_at_startup(void)
+{
+ stat_text[0] = '\0'; sz_stat_text = 0;
+ ostat_text[0] = '\0'; sz_ostat_text = 0;
+ dk4error_init(&er_bytes);
+}
+
+
+
+static
+void
+report_at_job_start(int argc, char *argv[])
+{
+ int found = 0;
+ char *ptr;
+ if (0 != verbose) {
+ int i;
+ fputs(pjsnmp_kw[169], out_file);
+ for (i = 1; i < argc; i++) {
+ fputs(argv[i], out_file);
+ fputc('\n', out_file);
+ }
+ fflush(out_file);
+ } else {
+ if (NULL != user_name) {
+ fputs(user_name, out_file);
+ found = 1;
+ }
+ if (NULL != queue_name) {
+ if (0 != found) { fputc(' ', out_file); }
+ fputs(queue_name, out_file);
+ found = 1;
+ }
+ if (NULL != job_name) {
+ if (0 != found) { fputc(' ', out_file); }
+ fputs(job_name, out_file);
+ found = 1;
+ }
+ if (0 != found) { fputc('\n', out_file); }
+ if (NULL != job_title) {
+ ptr = job_title;
+ while ('\0' != *ptr) {
+ if (0x80 > ((unsigned char)(*ptr))) {
+ fputc(*ptr, out_file);
+ } else {
+ fputc('?', out_file);
+ }
+ ptr++;
+ }
+ fputc('\n', out_file);
+ found = 1;
+ }
+ if (0 != found) {
+ fflush(out_file);
+ }
+ }
+}
+
+
+
+
+#endif
+/* if DK4_HAVE_LIBNETSNMP && ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET)) */
+
+
+
+/** Main program.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return Exit status code, one from LPRNG_EXIT_xxx.
+*/
+int
+main(int argc, char *argv[])
+{
+#if DK4_HAVE_LIBNETSNMP && ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET))
+
+ /* +++++ All libraries available */
+
+#if DK4_HAVE_SIGACTION
+#ifdef SIGPIPE
+ struct sigaction opipe; /* Old disposition for SIGPIPE */
+ struct sigaction npipe; /* New disposition for SIGPIPE */
+#endif
+ struct sigaction oint; /* Old disposition for SIGINT */
+ struct sigaction nint; /* New disposition for SIGINT */
+ struct sigaction oterm; /* Old disposition for SIGTERM */
+ struct sigaction nterm; /* New disposition for SIGTERM */
+#else
+#ifdef SIGPIPE
+ dk4_sig_handler_t *opipe = NULL; /* Old disposition for SIGPIPE */
+#endif
+ dk4_sig_handler_t *oterm = NULL; /* Old disposition for SIGTERM */
+ dk4_sig_handler_t *oint = NULL; /* Old disposition for SIGINT */
+#endif
+
+#if DK4_HAVE_SIGACTION
+#ifdef SIGPIPE
+ int set_pipe = 0; /* Flag: Disposition SIGPIPE changed */
+#endif
+ int set_int = 0; /* Flag: Disposition SIGINT changed */
+ int set_term = 0; /* Flag: Disposition SIGTERM changed */
+ int sig_i_f = 0; /* Flag: Handler installation failed */
+ int sig_r_f = 0; /* Flag: Handler restoration failed */
+#endif
+ int sockinit = 0; /* Flag: Socket subsys initialized */
+
+
+
+#line 5188 "pjsnmp.ctr"
+
+
+#line 5189 "pjsnmp.ctr"
+
+ /* Initialize output file.
+ */
+ out_file = stderr;
+ dk4time_get(&t1);
+
+ /* Copy default OID for status text.
+ */
+ DK4_MEMCPY(oid_st, oid_dst, by_oid_dst);
+ sz_oid_st = sz_oid_dst;
+ by_oid_st = sz_oid_st * sizeof(oid);
+
+ /* Process command line arguments, open log file.
+ */
+ if (0 == process_command_line_arguments(argc, argv)) { goto finished; }
+
+ /* Set up signal handlers.
+ */
+#if DK4_HAVE_SIGACTION
+#ifdef SIGPIPE
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) { sig_i_f = 1; goto finished; }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) { sig_i_f = 1; goto finished; }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) { sig_i_f = 1; goto finished; }
+ set_pipe = 1;
+#endif
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) { sig_i_f = 1; goto finished; }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) { sig_i_f = 1; goto finished; }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) { sig_i_f = 1; goto finished; }
+ set_term = 1;
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) { sig_i_f = 1; goto finished; }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) { sig_i_f = 1; goto finished; }
+ if (0 != sigaction(SIGINT, &nint, &oint)) { sig_i_f = 1; goto finished; }
+ set_int = 1;
+#else
+#ifdef SIGPIPE
+ opipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oint = sigset(SIGINT, sig_handler_int);
+ oterm = sigset(SIGTERM, sig_handler_term);
+#endif
+
+ /* Process remaining setup (PRINTCAP_ENTRY, model file).
+ */
+ if (0 == process_setup()) { goto finished; }
+
+ /* Header files for job in log output.
+ */
+ report_at_job_start(argc, argv);
+
+ /* Initialize socket subsystem.
+ */
+ if (DK4_SOCKET_RESULT_SUCCESS != dk4socket_up(NULL)) {
+ log_1_no_header(170);
+ goto finished;
+ }
+ sockinit = 1;
+
+ /* Check users permission to print.
+ */
+ if (0 == check_permission()) { goto finished; }
+
+ /* Establish SNMP session.
+ */
+ if (0 == attempt_snmp_session()) { goto finished; }
+
+ /* Initialization.
+ */
+ initialize_at_startup();
+
+ /* Accounting before job.
+ */
+ if (0 == do_accounting(0)) { goto finished; }
+
+ /* Data transfer.
+ */
+ if (0 == data_transfer()) { goto finished; }
+
+ /* Accounting after job.
+ */
+ if (0 == do_accounting(1)) { goto finished; }
+
+ /* Cleanup
+ -------
+ */
+ finished:
+
+ /* Clean up SNMP session.
+ */
+ if (NULL != snmp_sess) { snmp_close(snmp_sess); }
+
+ /* Eat up data from standard input.
+ */
+ eatup_input();
+
+ /* release socket subsystem.
+ */
+ if (0 != sockinit) { (void)dk4socket_down(NULL); }
+
+ /* Release status text nodes, if any.
+ */
+ relase_status_text_nodes();
+
+ /* Release dynamically allocated printcap entry copy.
+ */
+ dk4mem_release(printcap_entry);
+
+ /* Restore signal handlers
+ */
+#if DK4_HAVE_SIGACTION
+ if (0 != sig_i_f) {
+ /* ERROR: Failed to set up signal handlers */
+ log_1_no_header(141);
+ }
+ if (0 != set_int) {
+ if (0 != sigaction(SIGINT, &oint, NULL)) { sig_r_f = 1; }
+ }
+ if (0 != set_term) {
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) { sig_r_f = 1; }
+ }
+#ifdef SIGPIPE
+ if (0 != set_pipe) {
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) { sig_r_f = 1; }
+ }
+#endif
+ if (0 != sig_r_f) {
+ /* ERROR: Failed to restore signal handlers */
+ log_1_no_header(142);
+ }
+#else
+ if (NULL != oterm) { sigset(SIGTERM, oterm); }
+ if (NULL != oint ) { sigset(SIGINT, oint ); }
+#ifdef SIGPIPE
+ if (NULL != opipe) { sigset(SIGPIPE, opipe); }
+#endif
+#endif
+
+ /* Final log message, close log file
+ */
+ dk4time_get(&t4);
+ if (2 > decision) { final_statistics(); }
+ if (NULL != stt_file) { fclose(stt_file); }
+ out_file = stderr;
+
+
+
+#line 5342 "pjsnmp.ctr"
+
+
+#line 5343 "pjsnmp.ctr"
+
+ /* ----- All libraries available */
+
+#else
+/* if DK4_HAVE_LIBNETSNMP && ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET)) */
+ /* +++++ Missing libraries */
+#if !DK4_HAVE_LIBNETSNMP
+ fputs("ERROR: Missing Net-SNMP support!\n", stderr);
+#endif
+#if !((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET))
+ fputs("ERROR: Missing sigaction()/sigset() support!\n", stderr);
+#endif
+ fflush(stderr);
+ /* ----- Missing libraries */
+#endif
+/* if DK4_HAVE_LIBNETSNMP && ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET)) */
+ exit(exval); return exval;
+}
+
+
+/*
+
+2016-02-26 Added dk4socket_up() and dk4socket_down().
+
+*/
diff --git a/support/dktools/pjsnmp.ctr b/support/dktools/pjsnmp.ctr
new file mode 100644
index 0000000000..fdfadbae7e
--- /dev/null
+++ b/support/dktools/pjsnmp.ctr
@@ -0,0 +1,5367 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_LIBNETSNMP && ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET))
+
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/utilities.h>
+#include <net-snmp/library/snmp_logging.h>
+
+#include "dk4types.h"
+#include "dk4inst.h"
+#include "dk4maasz.h"
+#include "dk4maadu.h"
+#include "dk4mem.h"
+#include "dk4sto.h"
+#include "dk4str8.h"
+#include "dk4fopc8.h"
+#include "dk4stat.h"
+#include "dk4stat8.h"
+#include "dk4mai8dus.h"
+#include "dk4mai8huc.h"
+#include "dk4mai8dii.h"
+#include "dk4mai8ddu.h"
+#include "dk4mao8d.h"
+#include "dk4mao8h.h"
+#include "dk4time.h"
+#include "dk4time08.h"
+#include "dk4sock.h"
+#include "dk4isadm.h"
+#include "dk4lprng.h"
+
+
+
+$!trace-include
+
+#endif
+/* if DK4_HAVE_LIBNETSNMP && ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET)) */
+
+
+
+/** One status text entry from SNMP model.
+*/
+typedef struct {
+ unsigned char *text; /**< Text pointer, not 0-terminated. */
+ size_t size; /**< Text size. */
+ int state; /**< Summary state if text was found. */
+ int start; /**< Flag: Text here is start text only. */
+} status_text_t;
+
+
+#if DK4_HAVE_LIBNETSNMP && ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET))
+
+
+/** SNMP device status.
+*/
+enum {
+ SNMP_DEVST_UNKNOWN = 1 , /**< Status is unknown. */
+
+ SNMP_DEVST_RUNNING = 2 , /**< Running. */
+
+ SNMP_DEVST_WARNING = 3 , /**< Warning condition active. */
+
+ SNMP_DEVST_TESTING = 4 , /**< In self test. */
+
+ SNMP_DEVST_DOWN = 5 /**< Down due to error condition. */
+};
+
+
+/** SNMP printer status.
+*/
+enum {
+ SNMP_PRST_OTHER = 1 , /**< Any state not mentioned below. */
+
+ SNMP_PRST_UNKNOWN = 2 , /**< Unknown. */
+
+ SNMP_PRST_IDLE = 3 , /**< Ready, waiting for next job. */
+
+ SNMP_PRST_PRINTING = 4 , /**< Printing a job. */
+
+ SNMP_PRST_WARMUP = 5 /**< Warming up. */
+};
+
+
+/** State summary.
+ For accounting we would only need to distinguish between
+ standby/idle (secure to retrieve page counter) and anything
+ else.
+ But we want to print human readable state summaries to status
+ file which are shown by lpq -L.
+*/
+enum {
+ PJSNMP_ST_UNKNOWN = 0 , /**< Failed to retrieve printer state. */
+
+ PJSNMP_ST_UNREACHABLE = 1 , /**< Printer is unreachable. */
+
+ PJSNMP_ST_ERROR = 2 , /**< Error state on printer. */
+
+ PJSNMP_ST_BUSY = 3 , /**< Printer is printing. */
+
+ PJSNMP_ST_IDLE = 4 , /**< Printer idle, can retrieve page counter. */
+
+ PJSNMP_ST_WARMUP = 5 , /**< Warming up. */
+
+ PJSNMP_ST_STANDBY = 6 , /**< Standby. */
+};
+
+
+/** @defgroup pdes Printer detected error states.
+ The first byte in the octet string is the most significant byte
+ in the unsigned long value.
+*/
+/**@{*/
+/** Warning: Paper low.
+*/
+#define PDES_WARNING_PAPER_LOW 0x80000000UL
+
+/** Error: Out of paper.
+*/
+#define PDES_ERROR_NO_PAPER 0x40000000UL
+
+/** Warning: Toner low.
+*/
+#define PDES_WARNING_TONER_LOW 0x20000000UL
+
+/** Error: Out of toner.
+*/
+#define PDES_ERROR_NO_TONER 0x10000000UL
+
+/** Error: Door open.
+*/
+#define PDES_ERROR_DOOR_OPEN 0x08000000UL
+
+/** Error: Paper jam.
+*/
+#define PDES_ERROR_PAPER_JAM 0x04000000UL
+
+/** Error: Printer offline.
+*/
+#define PDES_ERROR_OFFLINE 0x02000000UL
+
+/** Warning: Service requested.
+*/
+#define PDES_WARNING_SERVICE 0x01000000UL
+
+/** Input tray removed.
+*/
+#define PDES_ERROR_INPUT_TRAY_MISSING 0x00800000UL
+
+/** Output tray removed.
+*/
+#define PDES_ERROR_OUTPUT_TRAY_MISSING 0x00400000UL
+
+/** Marker supply missing.
+*/
+#define PDES_ERROR_MARKER_SUPPLY_MISSING 0x00200000UL
+
+/** Output tray nearly full.
+*/
+#define PDES_WARNING_OUTPUT_NEAR_FULL 0x00100000UL
+
+/** Output tray full.
+*/
+#define PDES_ERROR_OUTPUT_FULL 0x00080000UL
+
+/** At least one input tray empty.
+*/
+#define PDES_WARNING_INPUT_TRAY_EMPTY 0x00040000UL
+
+/** Overdue preventive maintenance.
+*/
+#define PDES_WARNING_OVERDUE_PREVENT_MAINT 0x00020000UL
+
+
+/** Bitmask to check if there is any error condition.
+*/
+#define PDES_ANY_ERROR \
+( PDES_ERROR_NO_PAPER \
+| PDES_ERROR_NO_TONER \
+| PDES_ERROR_DOOR_OPEN \
+| PDES_ERROR_PAPER_JAM \
+| PDES_ERROR_OFFLINE \
+| PDES_ERROR_INPUT_TRAY_MISSING \
+| PDES_ERROR_OUTPUT_TRAY_MISSING \
+| PDES_ERROR_MARKER_SUPPLY_MISSING \
+| PDES_ERROR_OUTPUT_FULL)
+
+
+/** Bitmask to check if there is any warning condition.
+*/
+#define PDES_ANY_WARNING \
+( PDES_WARNING_PAPER_LOW \
+| PDES_WARNING_TONER_LOW \
+| PDES_WARNING_SERVICE \
+| PDES_WARNING_OUTPUT_NEAR_FULL \
+| PDES_WARNING_OVERDUE_PREVENT_MAINT \
+| PDES_WARNING_INPUT_TRAY_EMPTY)
+
+
+/** Bitmask to check whether any error or warning condition is set.
+*/
+#define PDES_ANY_CONDITION ((PDES_ANY_WARNING) | (PDES_ANY_ERROR))
+
+/**@}*/
+
+
+/** Buffer for sending.
+ Should be large to minimize number of I/O operations.
+*/
+#if DK4_SIZEOF_SIZE_T > 2
+static char pjsnmp_buf[1048576];
+#else
+static char pjsnmp_buf[16384];
+#endif
+
+
+/** Current status text, also used in accounting.
+*/
+static char stat_text[2048];
+
+
+/** Buffer for responses from printer.
+*/
+static char dummy_text[2048];
+
+
+/** Previous status text.
+*/
+static char ostat_text[sizeof(stat_text)];
+
+
+/** Buffer for automatically constructed job name.
+*/
+static char job_name_buf[32+(8*sizeof(dk4_um_t))];
+
+
+/** Status text oid.
+*/
+static oid oid_st[MAX_OID_LEN];
+
+
+/** OID for device status.
+*/
+static const oid oid_ds[] = {
+ (oid)1, (oid)3, (oid)6, (oid)1, (oid)2, (oid)1,
+ (oid)25, (oid)3, (oid)2, (oid)1, (oid)5, (oid)1
+};
+
+
+/** OID for printer status.
+*/
+static const oid oid_ps[] = {
+ (oid)1, (oid)3, (oid)6, (oid)1, (oid)2, (oid)1,
+ (oid)25, (oid)3, (oid)5, (oid)1, (oid)1, (oid)1
+};
+
+
+/** OID for pagecount value.
+*/
+static const oid oid_pc[] = {
+ (oid)1, (oid)3, (oid)6, (oid)1, (oid)2, (oid)1,
+ (oid)43, (oid)10, (oid)2, (oid)1, (oid)4, (oid)1, (oid)1
+};
+
+
+/** OID for printer detected error state.
+*/
+static const oid oid_pe[] = {
+ (oid)1, (oid)3, (oid)6, (oid)1, (oid)2, (oid)1,
+ (oid)25, (oid)3, (oid)5, (oid)1, (oid)2, (oid)1
+};
+
+
+/** Default OID for status text.
+*/
+static const oid oid_dst[] = {
+ (oid)1, (oid)3, (oid)6, (oid)1, (oid)2, (oid)1,
+ (oid)43, (oid)16, (oid)5, (oid)1, (oid)2, (oid)1, (oid)1
+};
+
+
+/** Constant texts, not localized.
+*/
+static const char * const pjsnmp_kw[] = {
+$!string-table
+#
+# 0 Newline
+#
+\n
+#
+# 1 Space
+#
+
+#
+# 2 Environment variable name
+#
+PRINTCAP_ENTRY
+#
+# 3 Asterisk for all device/printer status names
+#
+*
+#
+# 4 Program name
+#
+pjsnmp
+#
+# 5 Default SNMP community
+#
+public
+#
+# 6 Keyword for permission checking.
+#
+acct-check
+#
+# 7 ... 10 Keywords
+#
+Device and printer status:
+/
+Printer detected error state:
+Current printer state:
+#
+# 11 ... 16 Device status
+#
+not found
+unknown
+running
+warning
+testing
+down
+#
+# 17 ... 22 Printer status
+#
+not found
+other
+unknown
+idle
+printing
+warmup
+#
+# 23 ... 29 Printer summary states
+#
+UNKNOWN
+UNREACHABLE
+ERROR
+BUSY
+IDLE
+WARMUP
+STANDBY
+#
+# 30 31
+#
+"
+"\n
+#
+# 32 33 Abbreviations for errors and warnings
+#
+ERROR:
+Warning:
+#
+# 34 48 Printer detected error states.
+#
+Paper low (printer will run out of paper soon).\n
+Out of paper!\n
+Toner low (printer will run out of toner soon).\n
+Out of toner!\n
+Door open!\n
+Paper jam!\n
+Offline!\n
+Service requested.\n
+Input tray missing!\n
+Output tray missing!\n
+Marker supply missing!\n
+Output tray nearly full (will be full soon).\n
+Output tray full!\n
+At least one input tray is empty.\n
+Overdue preventive maintenance.\n
+#
+# 49 50
+#
+ERROR ON PRINTER, MANUAL INTERVENTION REQUIRED!\n
+PRINTER PROBABLY REQUIRES MANUAL INTERVENTION!\n
+#
+# 51 52 53 Accounting keywords
+#
+acct-start
+acct-end
+acct-charge
+#
+# 54
+#
+print-job
+#
+# 55
+#
+Print job finished.\n
+#
+# 56 ... 59
+#
+Job size:
+Data transfer:
+Processing:
+Pages:
+#
+# 60 ... 61 units
+#
+ bytes\n
+ seconds\n
+#
+# 62 Start of line before timestamps
+#
+\#
+#
+# 63 ... 65 (log_1_with_header 1...3)
+#
+Configuration problem (command line arguments)!\n
+Configuration problem (printcap file)!\n
+Configuration problem (SNMP model file)!\n
+#
+# 66
+#
+ERROR: Missing option name!\n
+#
+# 67
+#
+ERROR: Missing option argument!\n
+#
+# 68
+#
+ERROR: Non-option command line argument found!\n
+#
+# 69
+#
+ERROR: No user name specified!\n
+#
+# 70
+#
+ERROR: No print queue name specified!\n
+#
+# 71
+#
+ERROR: No print job name specified!\n
+#
+# 72 73 74
+#
+Warning: Redefinition of "
+" to "
+"!\n
+#
+# 75 76
+#
+ERROR: Empty text for option "
+"!\n
+#
+# 77 78
+#
+ERROR: Missing text for "
+"!\n
+#
+# 79 80 81
+#
+ERROR: Option "
+" requires unsigned short number!\nIllegal text: "
+"!
+#
+# 82 83
+#
+ERROR: Illegal SNMP version: "
+"!\nAllowed: "1", "2c", "3"!\n
+#
+# 84 85 86
+#
+ERROR: Option "
+" requires an integer value!\nIllegal text: "
+"!\n
+#
+# 87
+#
+ERROR: Missing "]"!\n
+#
+# 88
+#
+ERROR: Missing model name!\n
+#
+# 89 90
+#
+ERROR: Illegal summary state: "
+"!\n
+#
+# 91 92
+#
+ERROR: Illegal printer status name: "
+"!\n
+#
+# 93 94
+#
+ERROR: Illegal device status name: "
+"!
+#
+# 95
+#
+ERROR: Missing printer status name!\n
+#
+# 96
+#
+ERROR: Missing summary state name!\n
+#
+# 97 98
+#
+ERROR: Illegal condition name: "
+"!\n
+#
+# 99
+#
+ERROR: OID too long!\n
+#
+# 100 101
+#
+ERROR: Numeric overflow for sub id: "
+"!\n
+#
+# 102 103
+#
+ERROR: Not a number: "
+"!\n
+#
+# 104
+#
+ERROR: Empty OID text!\n
+#
+# 105
+#
+ERROR: Memory allocation failed!\n
+#
+# 106
+#
+ERROR: Empty string!\n
+#
+# 107
+#
+ERROR: Incorrect string specification!\n
+#
+# 108 109
+#
+ERROR: Not a hexadecimal byte: "
+"!\n
+#
+# 110
+#
+ERROR: Value required!\n
+#
+# 111 112
+#
+ERROR: Not a boolean: "
+"!\n
+#
+# 113 114
+#
+ERROR: Illegal key: "
+"!\n
+#
+# 115 116
+#
+ERROR: Model not found: "
+"!\n
+#
+# 117 118
+#
+ERROR: Failed to open model file!\n"
+"!\n
+#
+# 119
+#
+ERROR: Missing host name for printer!\n
+#
+# 120
+#
+ERROR: PRINTCAP_ENTRY not found in environment!\n
+#
+# 121
+#
+ERROR: Failed to create SNMP session!\n
+#
+# 122
+#
+ERROR: Failed to send data to accounting system!\n
+#
+# 123
+#
+ERROR: Partial success when sending data to accounting system!\n
+#
+# 124
+#
+ERROR: Failed to shut down accounting socket!\n
+#
+# 125
+#
+ERROR: Failed to connect to accounting system!\n
+#
+# 126
+#
+ERROR: Failed to start accounting program!\n
+#
+# 127
+#
+ERROR: Missing command name for accounting program!\n
+#
+# 128
+#
+ERROR: Failed to open accounting file!\n
+#
+# 129 130
+#
+ERROR: Can not receive response from pipe!\n
+ERROR: Can not receive response from file!\n
+#
+# 131 ... 133
+#
+Checking permission: user="
+" printer="
+".\n
+#
+# 134 135
+#
+Printing allowed.\n
+ERROR: PRINTING DENIED BY ACCOUNTING/QUOTA SYSTEM!\n
+#
+# 136
+#
+ERROR: Printer unreachable too long!\n
+#
+# 137
+#
+ERROR: Network connection not writeable (timeout)!\n
+#
+# 138
+#
+ERROR: Failed to send data!\n
+#
+# 139
+#
+ERROR: Failed to read print data from standard input!\n
+#
+# 140
+#
+ERROR: Failed to connect to printer!\n
+#
+# 141 142
+#
+ERROR: Failed to set up signal handlers!\n
+ERROR: Failed to restore signal handlers!\n
+#
+# 143
+#
+:
+#
+# 144 Empty string
+#
+
+#
+# 145 146
+#
+Retrieving page counter at start.\n
+Retrieving page counter at end.\n
+#
+# 147 148
+#
+Page counter at start:
+Page counter at end:
+#
+# 149
+#
+Failed to retrieve page counter value!\n
+#
+# 150
+#
+---\n
+#
+# 151 ... 153
+#
+Starting print data transfer.\n
+Finished print data transfer.\n
+Print data transfer aborted.\n
+#
+# 154 ... 158
+#
+Transmitting accounting data via network socket.\n
+Writing accounting data pipe.\n
+Transmitting accounting data via local socket.\n
+Writing accounting data to file.\n
+Transmitting accounting data to fd 3.\n
+#
+# 159 160
+#
+Accounting data transmitted successfully.\n
+ERROR: Failed to transmit accounting data!\n
+#
+# 161
+#
+" requires an unsigned integer value!\nIllegal text: "
+#
+# 162 ... 164
+#
+Warning: Unusual change to idle/standby state.\nWaiting
+ seconds
+for printer to resume printing.\n
+#
+# 165
+#
+ERROR: No accounting destination configured!\n
+#
+# 166 167
+#
+Response from accounting system: "
+".\n
+#
+# 168
+#
+Printer in error state too long!\n
+#
+# 169
+#
+Command line arguments:\n
+#
+# 170
+#
+ERROR: Failed to initialize socket subsystem!\n
+#
+# 171
+#
+pjsnmp@localhost+
+$!end
+};
+
+
+
+/** Responses from accounting system.
+*/
+static const char * const accounting_responses[] = {
+$!string-table
+ACCEPT
+HOLD
+REMOVE
+$!end
+};
+
+
+
+/** Names for configuration items in the printcap entry.
+*/
+static const char * const printcap_entry_names[] = {
+$!string-table
+#
+# 0 Host name, default: none.
+#
+pjsnmp-host
+#
+# 1 Port number, default: 9100.
+#
+pjsnmp-port
+#
+# 2 Orderly release, default: off.
+#
+pjsnmp-ordrel
+#
+# 3 Accounting enabled, default: off
+#
+pjsnmp-accounting-enable
+#
+# 4 Check quota, default: off.
+#
+pjsnmp-accounting-check
+#
+# 5 Accounting file, default: none.
+#
+pjsnmp-accounting-file
+#
+# 6 Accounting host, default: none.
+#
+pjsnmp-accounting-host
+#
+# 7 Accounting port, default: 9100.
+#
+pjsnmp-accounting-port
+#
+# 8 Timeout if no printing occures, default: 300.
+#
+pjsnmp-require-printing
+#
+# 9 SNMP version, default: 1.
+#
+pjsnmp-version
+#
+# 10 SNMP community, default: public.
+#
+pjsnmp-community
+#
+# 11 Flag: SNMP checks also on successfully send, default: on
+#
+pjsnmp-during-transfer
+#
+# 12 File for descriptions, default: /usr/share/dktools/print-snmp.conf.
+#
+pjsnmp-model-file
+#
+# 13 SNMP model for the printer, default: none.
+#
+pjsnmp-model-name
+#
+# 14 Flag: Ignore failed SNMP session, default: off
+#
+pjsnmp-ignore-failed-session
+#
+# 15 Flag: Allow printing if accounting connection failed, default: off.
+#
+pjsnmp-allow-printing-if-accounting-connection-failed
+#
+# 16 Flag: Always use printer detected error state, default: on
+#
+pjsnmp-pdes-always
+#
+# 17 Flag: Show unknown states as busy, default: off.
+#
+pjsnmp-unknown-busy
+#
+# 18 Timeout if printer is unreachable at start, default: 3600 seconds.
+#
+pjsnmp-unreachable-timeout-start
+#
+# 19 Timeout if printer is unreachable at end, default: 3600 seconds.
+#
+pjsnmp-unreachable-timeout-end
+#
+# 20 Timeout if printer is unreachable during data transfer,
+# default: 3600 seconds.
+#
+pjsnmp-unreachable-timeout-printing
+#
+# 21 Local port number, default: none.
+#
+pjsnmp-local-port
+#
+# 22 Timeout if print socket is unwriteable during data transfer,
+# default: 3600 seconds.
+#
+pjsnmp-unwriteable-timeout-printing
+#
+# 23 Flag: Obtain responses from printer, default: off.
+#
+pjsnmp-read-response
+#
+# 24 Flag: Force printable status text.
+#
+pjsnmp-force-printable-status-text
+#
+# 25 Timeout for error state at start of job
+#
+pjsnmp-error-timeout-start
+#
+# 26 Timeout for error state at end of job
+#
+pjsnmp-error-timeout-end
+#
+# 27 Timeout for error state during printing
+#
+pjsnmp-error-timeout-printing
+#
+# 28 Flag: Verbose
+#
+pjsnmp-verbose
+#
+# 29 Flag: Allow Non-ASCII characters in job title for accounting.
+#
+pjsnmp-non-ascii-job-title
+#
+# 30 Flag: Use two accounting lines for start and end
+#
+pjsnmp-accounting-start-end
+$!end
+};
+
+
+/** SNMP version names, 2 and 2c are the same.
+*/
+static const char * const snmp_version_names[] = {
+$!string-table
+1
+2
+2c
+3
+$!end
+};
+
+
+/** Keywords used in the SNMP models file.
+*/
+static const char * const model_keys[] = {
+$!string-table
+# 0
+map
+# 1 2
+error condition
+add error condition
+# 3
+status text oid
+# 4 5 6 7
+text standby
+start standby
+text idle
+start idle
+# 8
+always use status text
+#
+# 9 10
+#
+text busy
+start busy
+#
+# 11 ... 16
+#
+text unknown
+start unknown
+text error
+start error
+text warmup
+start warmup
+$!end
+};
+
+
+/** Summary state keywords used in the models file, can be abbreviated.
+*/
+static const char * const summary_state_names[] = {
+$!string-table
+u$nknown
+e$rror
+b$usy
+i$dle
+w$armup
+s$tandby
+$!end
+};
+
+
+/** Device status names, can be abbreviated.
+*/
+static const char * const device_status_names[] = {
+$!string-table
+u$nknown
+r$unning
+w$arning
+t$esting
+d$own
+$!end
+};
+
+
+/** Printer status names, can be abbreviated.
+*/
+static const char * const printer_status_names[] = {
+$!string-table
+o$ther
+u$nknown
+i$dle
+p$rinting
+w$armup
+$!end
+};
+
+
+/** Names for the condition bits in the SNMP models file.
+*/
+static const char * const condition_names[] = {
+$!string-table
+low-paper
+no-paper
+low-toner
+no-toner
+door-open
+paper-jam
+offline
+service-requested
+input-tray-missing
+output-tray-missing
+marker-supply-missing
+output-near-full
+output-full
+input-tray-empty
+overdue-preventive-maintenance
+$!end
+};
+
+
+/** Default configuration file for SNMP models.
+*/
+static const char def_model_file[] = {
+DK4_INST_DIR_SHARE "/dktools/print-snmp.conf"
+};
+
+
+/** Option values for uppercase options.
+*/
+static char *upper[] = {
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+};
+
+
+/** Option values for lowercase options.
+*/
+static char *lower[] = {
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+};
+
+
+/** Mapping from device/printer status combinations to short summaries.
+*/
+static int summary_states[] = {
+ /* unknown-other */ PJSNMP_ST_UNKNOWN ,
+ /* unknown-unknown */ PJSNMP_ST_UNKNOWN ,
+ /* unknown-idle */ PJSNMP_ST_UNKNOWN ,
+ /* unknown-printing */ PJSNMP_ST_UNKNOWN ,
+ /* unknown-warmup */ PJSNMP_ST_WARMUP ,
+
+ /* running-other */ PJSNMP_ST_STANDBY ,
+ /* running-unknown */ PJSNMP_ST_UNKNOWN ,
+ /* running-idle */ PJSNMP_ST_IDLE ,
+ /* running-printing */ PJSNMP_ST_BUSY ,
+ /* running-warmup */ PJSNMP_ST_WARMUP ,
+
+ /* warning-other */ PJSNMP_ST_STANDBY ,
+ /* warning-unknown */ PJSNMP_ST_UNKNOWN ,
+ /* warning-idle */ PJSNMP_ST_IDLE ,
+ /* warning-printing */ PJSNMP_ST_BUSY ,
+ /* warning-warmup */ PJSNMP_ST_WARMUP ,
+
+ /* testing-other */ PJSNMP_ST_UNKNOWN ,
+ /* testing-unknown */ PJSNMP_ST_UNKNOWN ,
+ /* testing-idle */ PJSNMP_ST_UNKNOWN ,
+ /* testing-printing */ PJSNMP_ST_UNKNOWN ,
+ /* testing-warmup */ PJSNMP_ST_WARMUP ,
+
+ /* down-other */ PJSNMP_ST_ERROR ,
+ /* down-unknown */ PJSNMP_ST_ERROR ,
+ /* down-idle */ PJSNMP_ST_ERROR ,
+ /* down-printing */ PJSNMP_ST_ERROR ,
+ /* down-warmup */ PJSNMP_ST_WARMUP
+};
+
+
+
+/** Error report for number of bytes transferred.
+*/
+static dk4_er_t er_bytes;
+
+
+/** Copy of the printcap entry from PRINTCAP_ENTRY environment variable
+ (allocated, freed during cleanup before exit).
+*/
+static char *printcap_entry = NULL;
+
+
+/** Printer host name (from printcap entry).
+*/
+static char *host_name = NULL;
+
+
+/** User name to be charged for the job (from -n or -L option).
+*/
+static char *user_name = NULL;
+
+
+/** Print queue name (from -P or -Q option).
+*/
+static char *queue_name = NULL;
+
+
+/** Job title (from -J -f or -N option).
+*/
+static char *job_title = NULL;
+
+
+/** Job name from -A -j -t or -D option
+ (only needed for old accounting system).
+*/
+static char *job_name = NULL;
+
+
+/** File, socket, pipe or host name for accounting
+ (from pjsnmp-accounting-file in printcap entry).
+*/
+static char *acct_name = NULL;
+
+
+/** Host to connect to for accounting
+ (from pjsnmp-accounting-host in printcap entry).
+*/
+static char *acct_host = NULL;
+
+
+/** SNMP community name
+ (from pjsnmp-community in printcap entry).
+*/
+static char *snmp_comm = NULL;
+
+
+/** File name containing SNMP models
+ (from pjsnmp-model-file in printcap entry).
+*/
+static char *model_file = NULL;
+
+
+/** SNMP model name (from pjsnmp-model-name in printcap entry).
+*/
+static char *model_name = NULL;
+
+
+/** Status file for log messages (name obtained from -s cmd arg).
+*/
+static FILE *stt_file = NULL;
+
+
+/** Output file to use for log messages.
+ This is either stt_file or stderr, but never NULL.
+*/
+static FILE *out_file = NULL;
+
+
+/** SNMP session.
+*/
+static struct snmp_session *snmp_sess = NULL;
+
+
+/** Storage for status text nodes.
+*/
+static dk4_sto_t *s_stn = NULL;
+
+
+/** Iterator through storage above.
+*/
+static dk4_sto_it_t *i_stn = NULL;
+
+
+/** Number of bytes transferred.
+*/
+static dk4_um_t bytes_trans = (dk4_um_t)0UL;
+
+
+/** Timeout if printer not seen printing
+ (from pjsnmp-require-printing in printcap entry).
+ If the first page contains a complicated graphics it
+ might take a longer time to start printing.
+*/
+static dk4_um_t print_timeout = (dk4_um_t)600UL;
+
+
+/** Timeout if printer is unreachable at start of print job
+ (from pjsnmp-unreachable-timeout-start in printcap entry).
+*/
+static dk4_um_t unto_start = (dk4_um_t)900UL;
+
+
+/** Timeout if printer is unreachable during data transfer
+ (from pjsnmp-unreachable-timeout-printing in printcap entry).
+*/
+static dk4_um_t unto_print = (dk4_um_t)120UL;
+
+/** Timeout if printer socket is unwriteable during data transfer
+ (from pjsnmp-unwriteable-timeout-printing in printcap entry).
+*/
+static dk4_um_t unwt_print = (dk4_um_t)900UL;
+
+/** Timeout if printer is unreachable at end of print job
+ (from pjsnmp-unreachable-timeout-end in printcap entry).
+*/
+static dk4_um_t unto_end = (dk4_um_t)120UL;
+
+/** Timeout for error condition before printing to skip job.
+*/
+static dk4_um_t erto_start = (dk4_um_t)900UL;
+
+/** Timeout if printer is in error state during printing.
+*/
+static dk4_um_t erto_print = (dk4_um_t)86400UL;
+
+/** Timeout if printer is in error state after job.
+*/
+static dk4_um_t erto_end = (dk4_um_t)3600UL;
+
+/** Start time printer gone unreachable.
+*/
+static dk4_time_t start_unreach = (dk4_time_t)0UL;
+
+/** Start time printer gone error.
+*/
+static dk4_time_t start_error = (dk4_time_t)0UL;
+
+
+/** Size of device status OID (number of elements).
+*/
+static const size_t sz_oid_ds = sizeof(oid_ds)/sizeof(oid);
+
+
+/** Size of device status OID (number of bytes).
+*/
+static const size_t by_oid_ds = sizeof(oid_ds);
+
+
+/** Size of printer status OID (number of elements).
+*/
+static const size_t sz_oid_ps = sizeof(oid_ps)/sizeof(oid);
+
+
+/** Size of printer status OID (number of bytes).
+*/
+static const size_t by_oid_ps = sizeof(oid_ps);
+
+
+/** Size of page counter OID (number of elements).
+*/
+static const size_t sz_oid_pc = sizeof(oid_pc)/sizeof(oid);
+
+
+/** Size of page counter OID (number of bytes).
+*/
+static const size_t by_oid_pc = sizeof(oid_pc);
+
+
+/** Size of printer error OID (number of elements).
+*/
+static const size_t sz_oid_pe = sizeof(oid_pe)/sizeof(oid);
+
+
+/** Size of printer error OID (number of bytes).
+*/
+static const size_t by_oid_pe = sizeof(oid_pe);
+
+
+/** Size of printer error OID (number of elements).
+*/
+static const size_t sz_oid_dst = sizeof(oid_dst)/sizeof(oid);
+
+
+/** Size of printer error OID (number of bytes).
+*/
+static const size_t by_oid_dst = sizeof(oid_dst);
+
+
+/** Number of items in status text OID.
+*/
+static size_t sz_oid_st = sizeof(oid_dst)/sizeof(oid);
+
+
+/** Number of bytes in status text OID.
+*/
+static size_t by_oid_st = sizeof(oid_dst);
+
+
+/** Number of bytes currently stored in stat_text.
+*/
+static size_t sz_stat_text = 0;
+
+
+/** Number of bytes stored in ostat_text.
+*/
+static size_t sz_ostat_text = 0;
+
+
+/** Start of program.
+*/
+static dk4_time_t t1 = (dk4_time_t)0UL;
+
+
+/** Start of data transfer.
+*/
+static dk4_time_t t2 = (dk4_time_t)0UL;
+
+
+/** End of data transfer.
+*/
+static dk4_time_t t3 = (dk4_time_t)0UL;
+
+
+/** End of program.
+*/
+static dk4_time_t t4 = (dk4_time_t)0UL;
+
+
+/** SNMP version number (from pjsnmp-version in printcap entry).
+*/
+static long snmp_version = SNMP_VERSION_1;
+
+
+/** Bit mask to retrieve real error conditions from
+ hrPrinterDetectedErrorStates
+ (modified by error condition and add error condition in model).
+*/
+static unsigned long pdes_error = PDES_ANY_ERROR ;
+
+
+/** Previous printer detected error state conditions.
+*/
+static unsigned long opdes_cond = 0UL;
+
+
+/** Current printer detected error state conditions.
+*/
+static unsigned long pdes_cond = 0UL;
+
+
+/** Page counter at start of job.
+*/
+static unsigned long pc_start = 0UL;
+
+
+/** Unusable page counter value (start value or at last error).
+*/
+static unsigned long pc_error = 0UL;
+
+
+/** Page counter at end of job.
+*/
+static unsigned long pc_end = 0UL;
+
+
+/** Current page counter.
+*/
+static unsigned long pcnt = 0UL;
+
+
+#endif
+/* if DK4_HAVE_LIBNETSNMP && ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET)) */
+
+
+
+/** Exit status code, must be one from the enum.
+*/
+static int exval = LPRNG_EXIT_REMOVE;
+
+
+#if DK4_HAVE_LIBNETSNMP && ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET))
+
+
+/** Flag: Verbose
+*/
+static int verbose = 0;
+
+
+/** Flag: Allow non-ASCII characters in job title for accounting.
+*/
+static int allow_non_ascii = 0;
+
+
+/** Always use status text (default: only if summary is "unknown").
+*/
+static int stat_always = 0;
+
+
+/** Flag: Always use printer detected error state
+ (from pjsnmp-pdes-always in printcap entry), default: on.
+*/
+static int pdes_always = 1;
+
+
+/** Flag: Reset of pdes_error was done.
+*/
+static int pdes_reset = 0;
+
+
+/** Flag: Report unknown states as busy
+ (from pjsnmp-unknown-busy in printcap entry), default: off.
+*/
+static int unkn_busy = 0;
+
+
+/** Flag: Do orderly release (from pjsnmp-ordrel in printcap entry).
+*/
+static int host_ordr = 0;
+
+
+/** Flag: Accounting enabled
+ (from pjsnmp-accounting-enable in printcap entry).
+*/
+static int acct_enab = 0;
+
+
+/** Flag: Quota check enabled
+ (from pjsnmp-accounting-check in printcap entry).
+*/
+static int acct_achk = 0;
+
+
+/** Flag: Use separated start/end lines for accounting.
+ Default is to use just one charge line at end.
+*/
+static int acct_start_end = 0;
+
+
+/** Flag: Read printer responses
+ (from pjsnmp-read-response in printcap entry).
+*/
+static int read_responses = 0;
+
+
+/** Flag: Force printable status text
+ (from pjsnmp-force-printable-status-text in printcap entry).
+*/
+static int force_printable_status_text = 1;
+
+/** Flag: SNMP check during transfer
+ (from pjsnmp-during-transfer in printcap entry).
+*/
+static int check_trans = 1;
+
+
+/** Flag: EOF found on standard input.
+*/
+static int have_eof = 0;
+
+
+/** Ignore failed SNMP session
+ (from pjsnmp-ignore-failed-session in printcap entry).
+*/
+static int snmp_igfs = 0;
+
+
+/** Allow printing if accounting connection failed.
+ (from pjsnmp-allow-printing-if-accounting-connection-failed).
+*/
+static int acct_apcf = 0;
+
+
+/** Flag: Have page counter at start.
+*/
+static int have_pcs = 0;
+
+
+/** Flag: Have page counter at end.
+*/
+static int have_pce = 0;
+
+
+/** Previous device status.
+*/
+static int odevst = 0;
+
+
+/** Current device status.
+*/
+static int devst = 0;
+
+
+/** Previous printer status.
+*/
+static int oprist = 0;
+
+
+/** Current printer status.
+*/
+static int prist = 0;
+
+
+/** Previous summary status.
+*/
+static int ostsum = PJSNMP_ST_UNKNOWN;
+
+
+/** Current summary status.
+*/
+static int stsum = PJSNMP_ST_UNKNOWN;
+
+
+/** Flag: The printer was seen in printing state.
+ This flag is cleared if the printer was seen in error state,
+ as some printers go from error to printing via idle.
+*/
+static int seen_printing = 0;
+
+
+/** Last header used for log messages.
+*/
+static int last_header = 0;
+
+
+/** Decision from permission check
+ 0=unknown
+ 1=accept
+ 2=hold
+ 3=remove
+*/
+static int decision = 0;
+
+
+/** Port number to send data to in host representation
+ (from pjsnmp-port in printcap entry).
+*/
+static unsigned short host_port = 9100;
+
+
+/** Local port number.
+ (from pjsnmp-local-port in printcap entry).
+*/
+static unsigned short local_port = 0;
+
+
+/** Accounting port number in host representation
+ (from pjsnmp-accounting-port in printcap entry).
+*/
+static unsigned short acct_port = 9100;
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+/** Pass volatile pointer through to caller.
+ The CERT C coding standard recommends to set signal indicator
+ variables through pointers to avoid
+ compilers from optimizing too hard (they might attempt
+ to keep the value in a register although properly marked
+ as volatile).
+ @param ptr Address of volatile indicator variable.
+ @return Same pointer as ptr.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+
+/** Check whether we can continue or must abort due to signal.
+ @param dopipe Flag: Check for SIGPIPE too.
+ @return 1 if we can continue, 0 otherwise.
+*/
+static
+int
+can_continue(int dopipe)
+{
+ int back = 1;
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_int)) { back = 0; }
+#ifdef SIGPIPE
+ if (0 != dopipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ return back;
+}
+
+
+/** Log a timestamp.
+ @return 1 if time changed since previous log, 0 otherwise.
+*/
+static
+int
+log_timestamp(void)
+{
+ char buf[64];
+ static dk4_time_t previous_log = (dk4_time_t)0UL;
+ dk4_time_t current;
+ int back = 0;
+ $? "+ log_timestamp"
+ dk4time_get(&current);
+ if (current != previous_log) { $? ". time changed"
+ if (dk4time_as_text_c8(buf, sizeof(buf), &current, NULL)) {
+ back = 1; $? ". time converted to text"
+ fputs(pjsnmp_kw[62], out_file);
+ fputs(buf, out_file);
+ fputs(pjsnmp_kw[0], out_file);
+ previous_log = current;
+ }
+ } $? "- log_timestamp %d", back
+ return back;
+}
+
+
+
+/** Log a 1 component message with header line.
+ @param h Header line chooser (1, 2 or 3).
+ @param i Index of message text in pjsnmp_kw.
+*/
+static
+void
+log_1_with_header(int h, size_t i)
+{
+ (void)log_timestamp();
+ if (last_header != h) {
+ fputs(pjsnmp_kw[62 + h], out_file);
+ last_header = h;
+ }
+ fputs(pjsnmp_kw[i], out_file);
+ fflush(out_file);
+}
+
+
+
+/** Log a 3 components message with header line.
+ @param h Header line chooser (1, 2 or 3).
+ @param i1 Index of first text component in pjsnmp_kw.
+ @param i2 Index of third text component in pjsnmp_kw.
+ @param s Second text component (variable text).
+*/
+static
+void
+log_3_with_header(int n, size_t i1, size_t i2, const char *s)
+{
+ (void)log_timestamp();
+ if (last_header != n) {
+ fputs(pjsnmp_kw[62 + n], out_file);
+ last_header = n;
+ }
+ fputs(pjsnmp_kw[i1], out_file);
+ if (NULL != s) { fputs(s, out_file); }
+ fputs(pjsnmp_kw[i2], out_file);
+ fflush(out_file);
+}
+
+
+
+/** Log a 5 components message with header line.
+ @param h Header line chooser (1, 2 or 3).
+ @param i1 Index of first text component in pjsnmp_kw.
+ @param i2 Index of third text component in pjsnmp_kw.
+ @param i3 Index of fifth text component in pjsnmp_kw.
+ @param s1 Second text component (variable text).
+ @param s2 Fourth text component (variable text).
+*/
+static
+void
+log_5_with_header(
+ int n,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ const char *s1,
+ const char *s2
+)
+{
+ (void)log_timestamp();
+ if (last_header != n) {
+ fputs(pjsnmp_kw[62 + n], out_file);
+ last_header = n;
+ }
+ fputs(pjsnmp_kw[i1], out_file);
+ if (NULL != s1) { fputs(s1, out_file); }
+ fputs(pjsnmp_kw[i2], out_file);
+ if (NULL != s2) { fputs(s2, out_file); }
+ fputs(pjsnmp_kw[i3], out_file);
+ fflush(out_file);
+}
+
+
+
+/** Log a 1 component message without header line.
+ @param i Index of text component in pjsnmp_kw.
+*/
+static
+void
+log_1_no_header(size_t i)
+{
+ $? "+ log_1_no_header %u", (unsigned)i
+ log_timestamp();
+ fputs(pjsnmp_kw[i], out_file);
+ fflush(out_file);
+ $? "- log_1_no_header"
+}
+
+
+
+/** Log a 3 components message without header line.
+ @param i1 Index of first text component in pjsnmp_kw.
+ @param i2 Index of third text component in pjsnmp_kw.
+ @param s Second text component (variable text).
+*/
+static
+void
+log_3_no_header(size_t i1, size_t i2, const char *s)
+{
+ $? "+ log_3_no_header %u %u \"%s\"", (unsigned)i1, (unsigned)i2, TR_8STR(s)
+ log_timestamp();
+ fputs(pjsnmp_kw[i1], out_file);
+ if (NULL != s) { fputs(s, out_file); }
+ fputs(pjsnmp_kw[i2], out_file);
+ fflush(out_file);
+ $? "- log_3_no_header"
+}
+
+
+
+/** Log a 5 components message without header line.
+ @param i1 Index of first text component in pjsnmp_kw.
+ @param i2 Index of third text component in pjsnmp_kw.
+ @param i3 Index of fifth text component in pjsnmp_kw.
+ @param s1 Second text component (variable text).
+ @param s2 Fourth text component (variable text).
+*/
+static
+void
+log_5_no_header(
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ const char *s1,
+ const char *s2
+)
+{
+ log_timestamp();
+ fputs(pjsnmp_kw[i1], out_file);
+ if (NULL != s1) { fputs(s1, out_file); }
+ fputs(pjsnmp_kw[i2], out_file);
+ if (NULL != s2) { fputs(s2, out_file); }
+ fputs(pjsnmp_kw[i3], out_file);
+ fflush(out_file);
+}
+
+
+
+/** Log a 1 component message related to model file.
+ @param lineno Line number in model file to complain about.
+ @param i Index of first text component in pjsnmp_kw.
+*/
+static
+void
+log_model_1(dk4_um_t lineno, size_t i)
+{
+ char buf[8*sizeof(dk4_um_t)];
+ const char *fn;
+ const char *ptr;
+ int res;
+
+ (void)log_timestamp();
+ if (3 != last_header) {
+ last_header = 3;
+ fputs(pjsnmp_kw[65], out_file);
+ }
+ if ((dk4_um_t)0UL < lineno) {
+ res = dk4ma_write_c8_decimal_unsigned(buf, sizeof(buf), lineno, 0, NULL);
+ if (0 != res) {
+ fn = ((NULL != model_file) ? model_file : def_model_file);
+ ptr = dk4str8_rchr(fn, '/');
+ if (NULL != ptr) {
+ ptr++;
+ } else {
+ ptr = fn;
+ }
+ fputs(ptr, out_file);
+ fputs(pjsnmp_kw[143], out_file);
+ fputs(buf, out_file);
+ fputs(pjsnmp_kw[143], out_file);
+ fputs(pjsnmp_kw[1], out_file);
+ }
+ }
+ fputs(pjsnmp_kw[i], out_file);
+ fflush(out_file);
+}
+
+
+
+/** Log a 3 components message related to model file.
+ @param lineno Line number in model file to complain about.
+ @param i1 Index of first text component in pjsnmp_kw.
+ @param i2 Index of third text component in pjsnmp_kw.
+ @param s Second text component (variable text).
+*/
+static
+void
+log_model_3(
+ dk4_um_t lineno,
+ size_t i1,
+ size_t i2,
+ const char *s
+)
+{
+ char buf[8*sizeof(dk4_um_t)];
+ const char *fn;
+ const char *ptr;
+ int res;
+
+ (void)log_timestamp();
+ if (3 != last_header) {
+ last_header = 3;
+ fputs(pjsnmp_kw[65], out_file);
+ }
+ if ((dk4_um_t)0UL < lineno) {
+ res = dk4ma_write_c8_decimal_unsigned(buf, sizeof(buf), lineno, 0, NULL);
+ if (0 != res) {
+ fn = ((NULL != model_file) ? model_file : def_model_file);
+ ptr = dk4str8_rchr(fn, '/');
+ if (NULL != ptr) {
+ ptr++;
+ } else {
+ ptr = fn;
+ }
+ fputs(ptr, out_file);
+ fputs(pjsnmp_kw[143], out_file);
+ fputs(buf, out_file);
+ fputs(pjsnmp_kw[143], out_file);
+ fputs(pjsnmp_kw[1], out_file);
+ }
+ }
+ fputs(pjsnmp_kw[i1], out_file);
+ if (NULL != s) { fputs(s, out_file); }
+ fputs(pjsnmp_kw[i2], out_file);
+ fflush(out_file);
+}
+
+
+
+/** Create new status text node.
+ @param t Text, not 0-terminated.
+ @param tsz Text size.
+ @param st Summary state if text is found.
+ @param fl Flag: This is the start text only.
+ @return Valid pointer on success, NULL on error.
+*/
+static
+status_text_t *
+stt_new(
+ const unsigned char *t,
+ size_t tsz,
+ int st,
+ int fl
+)
+{
+ status_text_t *back = NULL;
+ $? "+ stt_new %s %u state=%d start=%d", TR_8PTR(t), (unsigned)tsz, st, fl
+ if ((NULL != t) && (0 < tsz)) {
+ back = dk4mem_new(status_text_t,1,NULL);
+ if (NULL != back) {
+ DK4_MEMRES(back, sizeof(status_text_t));
+ back->start = fl;
+ back->state = st;
+ back->size = tsz;
+ back->text = dk4mem_new(unsigned char,tsz,NULL);
+ if (NULL != back->text) {
+ DK4_MEMCPY(back->text, t, tsz);
+ } else { $? "! second allocation"
+ dk4mem_free(back);
+ back = NULL;
+ }
+ }
+#if TRACE_DEBUG
+ else { $? "! first allocation"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! args"
+ }
+#endif
+ $? "- stt_new %s", TR_8PTR(back)
+ return back;
+}
+
+
+
+/** Destroy status text node, release memory.
+ @param ptr Node to destroy.
+*/
+static
+void
+stt_delete(status_text_t *ptr)
+{
+ $? "+ stt_delete %s", TR_8PTR(ptr)
+ if (NULL != ptr) { $? ". lgt=%u", (unsigned)(ptr->size)
+ dk4mem_release(ptr->text);
+ dk4mem_free(ptr);
+ }
+ $? "- stt_delete"
+}
+
+
+
+/** Compare two status text nodes.
+ While building the storage the start flag is ignored.
+ When searching a text for a status text received via SNMP
+ we have to consider the flag.
+ @param l Left object.
+ @param r Right object.
+ @param cr Comparison criteria (0=build storage, 1=search).
+ @return Comparison result.
+*/
+static
+int
+stt_compare(const void *l, const void *r, int cr)
+{
+ const status_text_t *pl; /* Left operand */
+ const status_text_t *pr; /* Right operand */
+ size_t min; /* Minimum of both text sizes */
+ int back = 0;
+ $? "+ stt_compare cr=%d", cr
+ if (NULL != l) {
+ if (NULL != r) {
+ pl = (const status_text_t *)l;
+ pr = (const status_text_t *)r;
+ min = pl->size;
+ if (min > pr->size) { min = pr->size; }
+ if (0 < min) {
+ back = dk4mem_cmp(pl->text, pr->text, min, NULL);
+ }
+ if (0 == back) {
+ if ((0 == cr) || (0 == pl->start)) {
+ if (pl->size > pr->size) {
+ back = 1;
+ } else {
+ if (pl->size < pr->size) {
+ back = -1;
+ }
+ }
+ }
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != r) {
+ back = -1;
+ }
+ }
+ $? "- stt_compare %d", back
+ return back;
+}
+
+
+
+/** Set one command line option.
+ @param Option character.
+ @param Option argument.
+*/
+static
+void
+set_option(char c, char *val)
+{
+ size_t sz = 0; /* Index of option in arguments array */
+ $? "+ set_option %c %s", c, TR_8STR(val)
+ if (NULL != val) {
+ if (('a' <= c) && ('z' >= c)) {
+ sz = (size_t)(c - 'a');
+ if (DK4_SIZEOF(lower,DK4_PCHAR) > sz) {
+ lower[sz] = val; $? ". ok"
+ }
+ } else {
+ if (('A' <= c) && ('Z' >= c)) {
+ sz = (size_t)(c - 'A');
+ if (DK4_SIZEOF(upper,DK4_PCHAR) > sz) {
+ upper[sz] = val; $? ". ok"
+ }
+ }
+ }
+ } $? "- set_option"
+}
+
+
+
+/** Retrieve argument for one option.
+ @param c Option character (option name).
+ @return The value provided as option argument, NULL otherwise.
+*/
+static
+char *
+get_option(char c)
+{
+ char *back = NULL;
+ size_t sz = 0; /* Index of option in arguments array */
+ $? "- get_option %c", c
+ if (('a' <= c) && ('z' >= c)) {
+ sz = (size_t)(c - 'a');
+ if (DK4_SIZEOF(lower,DK4_PCHAR) > sz) {
+ back = lower[sz];
+ }
+ } else {
+ if (('A' <= c) && ('Z' >= c)) {
+ sz = (size_t)(c - 'A');
+ if (DK4_SIZEOF(upper,DK4_PCHAR) > sz) {
+ back = upper[sz];
+ }
+ }
+ } $? "- get_option \"%s\"", TR_8STR(back)
+ return back;
+}
+
+
+
+/** Process command line arguments.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+process_command_line_arguments(int argc, char *argv[])
+{
+ char *curarg; /* Current argument to process */
+ char *s_name; /* Status file name */
+ size_t szjnb; /* Size of job name buffer */
+ int back = 1;
+ int i; /* Index of current argument */
+ int res; /* Result for number to text conversion */
+ char c; /* Option name */
+ $? "+ process_command_line_arguments"
+ for (i = 1; i < argc; i++) {
+ curarg = argv[i]; $? ". argv[%d]=\"%s\"", i, curarg
+ if ('-' == *curarg) { $? ". option"
+ curarg++;
+ if ('\0' != *curarg) { $? ". option name"
+ c = *(curarg++);
+ if ('\0' != *curarg) { $? ". option argument"
+ set_option(c, curarg);
+ } else { $? "! missing option argument"
+#if VERSION_BEFORE_20160208
+ /* -c may appear without an argument.
+ */
+ back = 0;
+ /* ERROR: Missing option argument */
+ log_1_with_header(1, 67);
+#else
+ set_option(c, (char *)(pjsnmp_kw[144]));
+#endif
+ }
+ } else { $? "! missing option name"
+ back = 0;
+ /* ERROR: Only minus */
+ log_1_with_header(1, 66);
+ }
+ } else { $? "! not an option \"%s\"", curarg
+#if 0
+ /* 2016-02-15 Seeing non-option arguments is not an error,
+ the accounting file name is passed once
+ as argument to -a and once as file name.
+ */
+ back = 0;
+ /* ERROR: Non-option argument found */
+ log_1_with_header(1, 68);
+#endif
+ }
+ }
+ if (0 != back) { $? ". options processed"
+ s_name = get_option('s');
+ if (NULL != s_name) { $? ". status file name ok"
+ stt_file = fopen(s_name, "w");
+ if (NULL != stt_file) { $? ". status file opened"
+ out_file = stt_file;
+ }
+#if TRACE_DEBUG
+ else { $? "! failed to open status file"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! no status file name"
+ }
+#endif
+ user_name = get_option('n');
+ if (NULL == user_name) user_name = get_option('L');
+ if (NULL != user_name) {
+ user_name = dk4str8_start(user_name, NULL);
+ }
+ if (NULL != user_name) {
+ (void)dk4str8_next(user_name, NULL);
+ if (0 == strlen(user_name)) { user_name = NULL; }
+ }
+ if (NULL == user_name) { $? "! missing user name"
+ /* ERROR: No user name */
+ log_1_with_header(1, 69);
+ back = 0;
+ }
+#if TRACE_DEBUG
+ else { $? ". user \"%s\"", user_name
+ }
+#endif
+ if (0 != back) { $? ". user name ok"
+ queue_name = get_option('P');
+ if (NULL == queue_name) queue_name = get_option('Q');
+ if (NULL != queue_name) {
+ queue_name = dk4str8_start(queue_name, NULL);
+ }
+ if (NULL != queue_name) {
+ (void)dk4str8_next(queue_name, NULL);
+ if (0 == strlen(queue_name)) { queue_name = NULL; }
+ }
+ if (NULL == queue_name) { $? "! missing queue name"
+ /* ERROR: No queue name */
+ log_1_with_header(1, 70);
+ back = 0;
+ }
+#if TRACE_DEBUG
+ else { $? ". queue \"%s\"", queue_name
+ }
+#endif
+ }
+ if (0 != back) {
+ job_name = get_option('A'); $? ". check job name"
+ if (NULL == job_name) job_name = get_option('j');
+ if (NULL == job_name) job_name = get_option('t');
+ if (NULL == job_name) job_name = get_option('D');
+ if (NULL != job_name) {
+ job_name = dk4str8_start(job_name, NULL);
+ }
+ if (NULL != job_name) {
+ (void)dk4str8_next(job_name, NULL);
+ if (0 == strlen(job_name)) { job_name = NULL; }
+ }
+ if (NULL == job_name) {
+ szjnb = sizeof(job_name_buf);
+ if (0 != dk4str8_cpy_s(job_name_buf, szjnb, pjsnmp_kw[171], NULL)) {
+ res = dk4ma_write_c8_decimal_unsigned(
+ &(job_name_buf[strlen(job_name_buf)]),
+ (szjnb - strlen(job_name_buf)), (dk4_um_t)getpid(), 0, NULL
+ );
+ if (0 != res) {
+ job_name = job_name_buf;
+ }
+ }
+ }
+ if (NULL == job_name) { $? "! missing job name"
+ /* ERROR: No job name */
+ log_1_with_header(1, 71);
+ back = 0;
+ }
+#if TRACE_DEBUG
+ else { $? ". job \"%s\"", job_name
+ }
+#endif
+ }
+ if (0 != back) { $? ". checking job title"
+ job_title = get_option('J');
+ if (NULL == job_title) job_title = get_option('f');
+ if (NULL == job_title) job_title = get_option('N');
+ if (NULL != job_title) {
+ job_title = dk4str8_start(job_title, NULL);
+ }
+ if (NULL != job_title) {
+ dk4str8_normalize(job_title, NULL);
+ }
+#if 0
+ /* 20160206
+ Allow job_title to be NULL, pjsnmp_kw[54] is used instead.
+ */
+ if (NULL == job_title) { $? "! missing job title"
+ back = 0;
+ }
+#endif
+#if TRACE_DEBUG
+ else { $? ". title \"%s\"", job_title
+ }
+#endif
+ }
+ }
+ $? "- process_command_line_arguments %d", back
+ return back;
+}
+
+
+
+/** Set string pointer.
+ @param dptr Address of pointer to set.
+ @param src Value.
+ @param name Configuration entry name.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+set_string(char **dptr, char *src, const char *name)
+{
+ int back = 0;
+ $? "+ set_string"
+ if (NULL != src) {
+ src = dk4str8_start(src, NULL);
+ if (NULL != src) { $? ". src ok"
+ if (NULL != *dptr) { $? ". redefined"
+ /* WARNING: Redefinition */
+ log_5_with_header(2, 72, 73, 74, name, src);
+ }
+ *dptr = src;
+ back = 1;
+ } else { $? "! empty"
+ /* ERROR: Empty text */
+ log_3_with_header(2, 75, 76, name);
+ }
+ } else { $? "! NULL pointer"
+ /* ERROR: Text string required */
+ log_3_with_header(2, 77, 78, name);
+ } $? "- set_string %d", back
+ return back;
+}
+
+
+
+/** Set unsigned short variable.
+ @param dptr Address of variable to set.
+ @param src Text containing the value.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+set_unsigned_short(unsigned short *dptr, char *src, const char *name)
+{
+ const char *ep = NULL; /* First unprocessabe char */
+ int back = 0;
+ int res; /* Operation result */
+ unsigned short us;
+ $? "+ set_unsigned_short %s", TR_8PTR(src)
+ if (NULL != src) {
+ src = dk4str8_start(src, NULL);
+ if (NULL != src) {
+ res = dk4ma_input_c8_dec_ushort(&us, src, &ep, 1, NULL);
+ if (0 != res) {
+ *dptr = us;
+ back = 1; $? ". setting to %u", (unsigned)us
+ } else { $? "! not a number"
+ /* ERROR: Not a number! */
+ log_5_with_header(2, 79, 80, 81, name, src);
+ }
+ } else { $? "! empty text"
+ /* ERROR: Empty text */
+ log_3_with_header(2, 75, 76, name);
+ }
+ } else { $? "! NULL"
+ /* ERROR: Numeric value required */
+ log_3_with_header(2, 77, 78, name);
+ } $? "- set_unsigned_short %d", back
+ return back;
+}
+
+
+
+/** Set SNMP version.
+ @param dptr Address of variable to set.
+ @param src Text containing the SNMP version.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+set_snmp_version(long *dptr, char *src)
+{
+ int back = 0;
+ $? "+ set_snmp_version %s", TR_8PTR(src)
+ if (NULL != src) {
+ src = dk4str8_start(src, NULL);
+ if (NULL != src) {
+ switch (dk4str8_array_index(snmp_version_names, src, 0)) {
+ case 0: { $? ". 1"
+ *dptr = SNMP_VERSION_1;
+ back = 1;
+ } break;
+ case 1: case 2: { $? ". 2c"
+ *dptr = SNMP_VERSION_2c;
+ back = 1;
+ } break;
+ case 3: { $? ". 3"
+ *dptr = SNMP_VERSION_3;
+ back = 1;
+ } break;
+ default: { $? "! illegal text"
+ /* ERROR: Illegal SNMP version */
+ log_3_with_header(2, 82, 83, src);
+ } break;
+ }
+ } else { $? "! empty"
+ /* ERROR: Empty text */
+ log_3_with_header(2, 75, 76, printcap_entry_names[9]);
+ }
+ } else { $? "! NULL"
+ /* ERROR: Value required */
+ log_3_with_header(2, 77, 78, printcap_entry_names[9]);
+ }
+ $? "- set_snmp_version %d", back
+ return back;
+}
+
+
+
+/** Set maximum unsigned integer variable from text.
+ @param dptr Address of destination variable.
+ @param src Text containing the value.
+ @param name Setting name for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+set_umax(dk4_um_t *dptr, char *src, const char *name)
+{
+ const char *ep = NULL; /* First unprocessable character */
+ dk4_um_t i = 0UL; /* Result value */
+ int back = 0;
+ int res; /* Operation result */
+ $? "+ set_umax %s", TR_8PTR(src)
+ if (NULL != src) {
+ res = dk4ma_input_c8_dec_dk4_um_t(&i, src, &ep, 1, NULL);
+ if (0 != res) {
+ *dptr = i; $? ". value"
+ back = 1;
+ } else { $? "! not a number"
+ /* ERROR: Not a numeric value */
+ log_5_with_header(2, 84, 161, 86, name, src);
+ }
+ } else { $? "! NULL"
+ /* ERROR: Value required */
+ log_3_with_header(2, 77, 78, name);
+ } $? "- set_umax %d", back
+ return back;
+}
+
+
+
+#if 0
+
+/** Set integer variable from text.
+ @param dptr Address of destination variable.
+ @param src Text containing the value.
+ @param name Setting name for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+set_integer(int *dptr, char *src, const char *name)
+{
+ const char *ep = NULL; /* First unprocessable character */
+ int i = 0; /* Result value */
+ int back = 0;
+ int res; /* Operation result */
+ $? "+ set_integer %s", TR_8PTR(src)
+ if (NULL != src) {
+ res = dk4ma_input_c8_dec_int(&i, src, &ep, 1, NULL);
+ if (0 != res) {
+ *dptr = i; $? ". value %d", i
+ back = 1;
+ } else { $? "! not a number"
+ /* ERROR: Not a numeric value */
+ log_5_with_header(2, 84, 85, 86, name, src);
+ }
+ } else { $? "! NULL"
+ /* ERROR: Value required */
+ log_3_with_header(2, 77, 78, name);
+ } $? "- set_integer %d", back
+ return back;
+}
+
+#endif
+
+
+
+/** Process one configuration item from a printcap entry.
+ @param ci Item to process.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+process_one_config_item(char *ci)
+{
+ char *value = NULL; /* Value for config item */
+ int btrue = 1; /* Condition */
+ int back = 1;
+ $? "+ process_one_config_item \"%s\"", TR_8STR(ci)
+ value = dk4str8_chr(ci, '=');
+ if (NULL != value) {
+ *(value++) = '\0';
+ value = dk4str8_start(value, NULL); $? "\"%s\"=\"%s\"", ci, TR_8STR(value)
+ } else {
+ value = dk4str8_chr(ci, '@');
+ if (NULL != value) { $? ". negative condition"
+ *value = '\0';
+ btrue = 0;
+ }
+#if TRACE_DEBUG
+ else { $? ". positive condition"
+ }
+#endif
+ }
+ switch (dk4str8_array_index(printcap_entry_names, ci, 0)) {
+ case 0: { $? ". host"
+ if (0 == set_string(&host_name, value, printcap_entry_names[0])) {
+ back = 0;
+ }
+ } break;
+ case 1: { $? ". port"
+ if (0 == set_unsigned_short(&host_port, value, printcap_entry_names[1])) {
+ back = 0;
+ }
+ } break;
+ case 2: { $? ". orderly release"
+ host_ordr = btrue;
+ } break;
+ case 3: { $? ". enable accounting"
+ acct_enab = btrue;
+ } break;
+ case 4: { $? ". enable quota check"
+ acct_achk = btrue;
+ } break;
+ case 5: { $? ". accounting file"
+ if (0 == set_string(&acct_name, value, printcap_entry_names[5])) {
+ back = 0;
+ }
+ } break;
+ case 6: { $? ". accounting host"
+ if (0 == set_string(&acct_host, value, printcap_entry_names[6])) {
+ back = 0;
+ }
+ } break;
+ case 7: { $? ". accounting port"
+ if (0 == set_unsigned_short(&acct_port, value, printcap_entry_names[7])) {
+ back = 0;
+ }
+ } break;
+ case 8: { $? ". timeout if not printing"
+ if (NULL != value) {
+ if (0 == set_umax(&print_timeout, value, printcap_entry_names[8])) {
+ back = 0;
+ }
+ } else {
+ if (0 == btrue) { print_timeout = (dk4_um_t)0UL; }
+ else { back = 0; }
+ }
+ } break;
+ case 9: { $? ". SNMP version"
+ if (0 == set_snmp_version(&snmp_version, value)) {
+ back = 0;
+ }
+ } break;
+ case 10: { $? ". SNMP community"
+ if (0 == set_string(&snmp_comm, value, printcap_entry_names[10])) {
+ back = 0;
+ }
+ } break;
+ case 11: { $? ". SNMP during transfer"
+ check_trans = btrue;
+ } break;
+ case 12: { $? ". model file"
+ if (0 == set_string(&model_file, value, printcap_entry_names[12])) {
+ back = 0;
+ }
+ } break;
+ case 13: { $? ". model name"
+ if (0 == set_string(&model_name, value, printcap_entry_names[13])) {
+ back = 0;
+ }
+ } break;
+ case 14: { $? ". ignore failed session"
+ snmp_igfs = btrue;
+ } break;
+ case 15: { $? ". allow printing when accounting down"
+ acct_apcf = btrue;
+ } break;
+ case 16: { $? ". always use printer detected error state"
+ pdes_always = btrue;
+ } break;
+ case 17: { $? ". report unknown as busy"
+ unkn_busy = btrue;
+ } break;
+ case 18: { $? ". timeout for unreachable at start"
+ if (NULL != value) {
+ if (0 == set_umax(&unto_start, value, printcap_entry_names[18])) {
+ back = 0;
+ }
+ } else {
+ if (0 == btrue) { unto_start = (dk4_um_t)0UL; }
+ else { back = 0; }
+ }
+ } break;
+ case 19: { $? ". timeout for unreachable at end"
+ if (NULL != value) {
+ if (0 == set_umax(&unto_end, value, printcap_entry_names[19])) {
+ back = 0;
+ }
+ } else {
+ if (0 == btrue) { unto_end = (dk4_um_t)0UL; }
+ else { back = 0; }
+ }
+ } break;
+ case 20: { $? ". timeout for unreachable during transfer"
+ if (NULL != value) {
+ if (0 == set_umax(&unto_print, value, printcap_entry_names[20])) {
+ back = 0;
+ }
+ } else {
+ if (0 == btrue) { unto_print = (dk4_um_t)0UL; }
+ else { back = 0; }
+ }
+ } break;
+ case 21: { $? ". local port number"
+ if (0 == set_unsigned_short(&local_port, value, printcap_entry_names[21]))
+ {
+ back = 0; $? ". back = 0"
+ }
+ } break;
+ case 22: { $? ". timeout for unwriteable during transfer"
+ if (NULL != value) {
+ if (0 == set_umax(&unwt_print, value, printcap_entry_names[22])) {
+ back = 0;
+ }
+ } else {
+ if (0 == btrue) { unwt_print = (dk4_um_t)0UL; }
+ else { $? ". back = 0"
+ back = 0;
+ }
+ }
+ } break;
+ case 23: { $? ". read printer responses"
+ read_responses = btrue;
+ } break;
+ case 24: { $? ". force printable status text"
+ force_printable_status_text = btrue;
+ } break;
+ case 25: {
+ if (NULL != value) {
+ if (0 == set_umax(&erto_start, value, printcap_entry_names[22])) {
+ back = 0;
+ }
+ } else {
+ if (0 == btrue) { erto_start = (dk4_um_t)0UL; }
+ else { $? ". back = 0"
+ back = 0;
+ }
+ }
+ } break;
+ case 26: {
+ if (NULL != value) {
+ if (0 == set_umax(&erto_end, value, printcap_entry_names[22])) {
+ back = 0;
+ }
+ } else {
+ if (0 == btrue) { erto_end = (dk4_um_t)0UL; }
+ else { $? ". back = 0"
+ back = 0;
+ }
+ }
+ } break;
+ case 27: {
+ if (NULL != value) {
+ if (0 == set_umax(&erto_print, value, printcap_entry_names[22])) {
+ back = 0;
+ }
+ } else {
+ if (0 == btrue) { erto_print = (dk4_um_t)0UL; }
+ else { $? ". back = 0"
+ back = 0;
+ }
+ }
+ } break;
+ case 28: {
+ verbose = btrue;
+ } break;
+ case 29: {
+ allow_non_ascii = btrue;
+ } break;
+ case 30: {
+ acct_start_end = btrue;
+ } break;
+ } $? "- process_one_config_item %d", back
+ return back;
+}
+
+
+
+/** Check whether the line opens the model we are searching for.
+ @param str Text to check.
+ @param bptr Address of success indicator.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+check_in_model(char *str, int *bptr, dk4_um_t lineno)
+{
+ char *ptr; /* Closing square bracket */
+ int back = 0;
+ $? "+ check_in_model"
+ str = dk4str8_start(str, NULL);
+ if (NULL != str) {
+ ptr = dk4str8_chr(str, ']');
+ if (NULL != ptr) {
+ *ptr = '\0';
+ dk4str8_normalize(str, NULL); $? ". model \"%s\"", str
+ if (0 == strcmp(str, model_name)) {
+ back = 1; $? ". model found"
+ }
+#if TRACE_DEBUG
+ else { $? ". not the requested model"
+ }
+#endif
+ } else { $? "! no closing bracket"
+ /* ERROR: Syntax */
+ log_model_1(lineno, 87);
+ }
+ } else { $? "! no text"
+ /* ERROR: Syntax */
+ log_model_1(lineno, 88);
+ } $? "- check_in_model %d", back
+ return back;
+}
+
+
+
+/** Overwrite one mapping from device/printer status to summary state.
+ @param devst Device status.
+ @param prst Printer status.
+ @param sujmst Summary state resulting from device and printer status.
+*/
+static
+void
+set_state_mapping(int devst, int prst, int sumst)
+{
+ $? "+ set_state_mapping %d/%d %d", devst, prst, sumst
+ if ((0 < devst) && (6 > devst)) {
+ if ((0 < prst) && (6 > prst)) { $? ". ok"
+ summary_states[5 * devst + prst - 6] = sumst;
+ }
+#if TRACE_DEBUG
+ else { $? "! prst %d", prst
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! devst %d", devst
+ }
+#endif
+ $? "- set_state_mapping"
+}
+
+
+
+/** Map device and printer status to summary state.
+ @param devst Device status.
+ @param prst Printer status.
+ @return Summary state.
+*/
+static
+int
+get_state_mapping(int devst, int prst)
+{
+ int back = PJSNMP_ST_UNKNOWN;
+ $? "+ get_state_mapping %d/%d", devst, prst
+ if ((0 < devst) && (6 > devst)) {
+ if ((0 < prst) && (6 > prst)) { $? ". ok"
+ back = summary_states[5 * devst + prst - 6];
+ $? ". %s/%s => %s", pjsnmp_kw[11 + devst], pjsnmp_kw[17 + prist], pjsnmp_kw[23 + back]
+ }
+#if TRACE_DEBUG
+ else { $? "! prst %d", prst
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! devst %d", devst
+ }
+#endif
+ $? "- get_state_mapping %d", back
+ return back;
+}
+
+
+
+/** Add a state mapping.
+ @param str Mapping text.
+ @param lineno Line number (for diagnostics).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+model_conf_map(char *str, dk4_um_t lineno)
+{
+ char *psummary; /* Summary state name */
+ char *ppr; /* Printer status */
+ int stsum; /* Summary state */
+ int stdev; /* Device status */
+ int stpri; /* Printer status */
+ int back = 0;
+ $? "+ model_conf_map %s", TR_8STR(str)
+ psummary = dk4str8_next(str, NULL);
+ if (NULL != psummary) { $? ". summary"
+ ppr = dk4str8_chr(str, '/');
+ if (NULL != ppr) { $? ". ppr"
+ *(ppr++) = '\0';
+ ppr = dk4str8_start(ppr, NULL);
+ if (NULL != ppr) { $? ". ppr"
+ back = 1;
+ switch (dk4str8_abbr_index(summary_state_names, '$', psummary, 0)) {
+ case 0: { $? ". unknown"
+ stsum = PJSNMP_ST_UNKNOWN;
+ } break;
+ case 1: { $? ". error"
+ stsum = PJSNMP_ST_ERROR;
+ } break;
+ case 2: { $? ". busy"
+ stsum = PJSNMP_ST_BUSY;
+ } break;
+ case 3: { $? ". idle"
+ stsum = PJSNMP_ST_IDLE;
+ } break;
+ case 4: { $? ". warmup"
+ stsum = PJSNMP_ST_WARMUP;
+ } break;
+ case 5: { $? ". standby"
+ stsum = PJSNMP_ST_STANDBY;
+ } break;
+ default: { $? "! illegal summary"
+ back = 0;
+ /* ERROR: Illegal summary state */
+ log_model_3(lineno, 89, 90, psummary);
+ } break;
+ }
+ if (0 != back) { $? ". summary ok"
+ if (0 == strcmp(str, pjsnmp_kw[3])) {
+ if (0 == strcmp(ppr, pjsnmp_kw[3])) { $? ". */*"
+ for (stdev = 1; stdev < 6; stdev++) {
+ for (stpri = 1; stpri < 6; stpri++) {
+ set_state_mapping(stdev, stpri, stsum);
+ }
+ }
+ } else { $? ". */x"
+ stpri = dk4str8_abbr_index(printer_status_names, '$', ppr, 0);
+ if (-1 < stpri) {
+ stpri++; $? ". stpri %d", stpri
+ for (stdev = 1; stdev < 6; stdev++) {
+ set_state_mapping(stdev, stpri, stsum);
+ }
+ } else { $? "! illegal printer status"
+ back = 0;
+ /* ERROR: Syntax, illegal printer status name */
+ log_model_3(lineno, 91, 92, ppr);
+ }
+ }
+ } else {
+ stdev = dk4str8_abbr_index(device_status_names, '$', str, 0);
+ if (-1 < stdev) {
+ stdev++; $? ". stdev %d", stdev
+ if (0 == strcmp(ppr, pjsnmp_kw[3])) { $? ". x/*"
+ for (stpri = 1; stpri < 6; stpri++) {
+ set_state_mapping(stdev, stpri, stsum);
+ }
+ } else { $? ". x/x"
+ stpri = dk4str8_abbr_index(printer_status_names, '$', ppr, 0);
+ if (-1 < stpri) {
+ stpri++; $? ". stpri %d", stpri
+ set_state_mapping(stdev, stpri, stsum);
+ } else { $? "! illegal printer status"
+ back = 0;
+ /* ERROR: Syntax, illegal printer status name */
+ log_model_3(lineno, 91, 92, ppr);
+ }
+ }
+ } else { $? "! illegal device status"
+ back = 0;
+ /* ERROR: Syntax, illegal device status name */
+ log_model_3(lineno, 93, 94, ppr);
+ }
+ }
+ } else { $? "! summary state not found"
+ }
+ } else { $? "! printer status missing"
+ /* ERROR: Syntax, printer status missing */
+ log_model_1(lineno, 95);
+ }
+ } else { $? "! printer status missing"
+ /* ERROR: Syntax, printer status missing */
+ log_model_1(lineno, 95);
+ }
+ } else { $? "! summary missing"
+ /* ERROR: Syntax, summary state missing */
+ log_model_1(lineno, 96);
+ } $? "- model_conf_map %d", back
+ return back;
+}
+
+
+
+/** Add a condition to the error conditions list.
+ @param str Text for condition.
+ @param addcond Flag: Add to existing list, do not reset.
+ @param lineno Line number (for diagnostics).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+model_conf_error_condition(char *str, int addcond, dk4_um_t lineno)
+{
+ unsigned long cond; /* Used to build condition bit */
+ int i; /* Index of keyword in condition_names */
+ int back = 0;
+ $? "+ model_conf_error_condition %s", TR_8STR(str)
+ if ((0 == addcond) && (0 == pdes_reset)) {
+ pdes_error = 0UL; $? ". reset pdes error"
+ }
+ pdes_reset = 1;
+ dk4str8_normalize(str, NULL);
+ i = dk4str8_array_index(condition_names, str, 0); $? ". i %d", i
+ if (-1 < i) {
+ back = 1;
+ cond = 0x80000000UL;
+ while (0 < i--) { cond = cond / 2UL; }
+ pdes_error |= cond; $? ". cond %lx", cond
+ } else { $? "! illegal condition"
+ /* ERROR: Syntax, illegal condition name */
+ log_model_3(lineno, 97, 98, str);
+ } $? "- model_conf_error_condition %d", back
+ return back;
+}
+
+
+
+/** Set status text OID.
+ @param str Text containing the OID.
+ @param lineno Line number (for diagnostics).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+model_conf_status_oid(char *str, dk4_um_t lineno)
+{
+ const char *ep; /* First unprocessable character */
+ char *np; /* Next part */
+ dk4_um_t num; /* Numeric value for sub-id */
+ size_t used = 0; /* Number of used sub-ids */
+ int back = 1;
+ int res; /* Operation result */
+ $? "+ model_conf_status_oid"
+ dk4str8_normalize(str, NULL);
+ if ('.' == *str) { $? ". skip leading dot"
+ str++;
+ }
+ while ((NULL != str) && (1 == back)) {
+ np = dk4str8_chr(str, '.');
+ if (NULL != np) {
+ *(np++) = '\0';
+ } $? ". current=\"%s\" next=\"%s\"", str, TR_8STR(np)
+ ep = NULL;
+ res = dk4ma_input_c8_dec_dk4_um_t(&num, str, &ep, 1, NULL);
+ if (0 != res) { $? ". number %lu", (unsigned long)num
+ if ((dk4_um_t)(MAX_SUBID) >= num) { $? ". in range"
+ if (used < DK4_SIZEOF(oid_st,oid)) { $? ". length ok"
+ oid_st[used++] = (oid)num;
+ } else { $? "! too long"
+ /* ERROR: Syntax, OID too long */
+ log_model_1(lineno, 99);
+ }
+ } else { $? "! numeric overflow"
+ back = 0;
+ /* ERROR: Syntax, overflow */
+ log_model_3(lineno, 100, 101, str);
+ }
+ } else { $? "! not a number"
+ back = 0;
+ /* ERROR: Syntax, not a number */
+ log_model_3(lineno, 102, 103, str);
+ }
+ str = np;
+ }
+ if (0 == used) { $? "! empty text"
+ back = 0;
+ /* ERROR: Syntax, empty OID */
+ log_model_1(lineno, 104);
+ }
+ if (0 != back) {
+ sz_oid_st = used;
+ } else {
+ sz_oid_st = 0;
+ }
+ by_oid_st = sz_oid_st * sizeof(oid);
+ $? "- model_conf_status_oid %d", back
+ return back;
+}
+
+
+
+/** Remove final double quote from string.
+ @param str String to modify.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+remove_final_double_quote(char *str)
+{
+ char *ptr; /* Position of final double quote */
+ int back = 0;
+ $? "+ remove_final_double_quote \"%s\"", TR_8STR(str)
+ ptr = dk4str8_rchr(str, '"');
+ if (NULL != ptr) { $? ". closing double quote found"
+ *(ptr++) = '\0';
+ back = 1;
+ while ('\0' != *ptr) {
+ if (' ' != *ptr) {
+ if ('\t' != *ptr) {
+ if ('\r' != *ptr) {
+ if ('\n' != *ptr) {
+ back = 0; $? "! non-whitespace after string"
+ }
+ }
+ }
+ }
+ ptr++;
+ }
+ }
+#if TRACE_DEBUG
+ else { $? "! no closing double quote"
+ }
+#endif
+ $? "- remove_final_double_quote %d \"%s\"", back, TR_8STR(str)
+ return back;
+}
+
+
+
+/** Add a text indicating a state to the storage.
+ @param str Indicator text.
+ @param state State number indicated by the text.
+ @param start Flag: This text is just the start of the real text.
+ @param lineno Line number (for diagnostics).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+model_conf_state_text(char *str, int state, int start, dk4_um_t lineno)
+{
+ status_text_t *stptr; /* New configuration node to add */
+ const char *ep; /* First unprocessable char when reading number */
+ char *cptr; /* Current word to process */
+ char *nptr; /* Next word (remaining text) to process */
+ size_t sl; /* String length */
+ int res; /* Operation result */
+ int back = 0;
+ unsigned char uc; /* Current byte found */
+ $? "+ model_conf_state_text %s", TR_8STR(str)
+ if (NULL == s_stn) {
+ s_stn = dk4sto_open(NULL);
+ if (NULL != s_stn) {
+ dk4sto_set_comp(s_stn, stt_compare, 0);
+ }
+ }
+ if ((NULL != s_stn) && (NULL == i_stn)) {
+ i_stn = dk4sto_it_open(s_stn, NULL);
+ }
+ if ((NULL != s_stn) && (NULL != i_stn)) { $? ". allocations ok"
+ if (NULL != str) { $? ". have text"
+ if ('"' == *str) { $? ". double quoted string"
+ str++;
+ if (0 != remove_final_double_quote(str)) {
+ sl = strlen(str);
+ if (0 < sl) { $? ". string not empty"
+ stptr = stt_new((unsigned char *)str, sl, state, start);
+ if (NULL != stptr) { $? ". allocation ok"
+ if (0 != dk4sto_add(s_stn, stptr, NULL)) {
+ back = 1; $? ". added to storage"
+ } else { $? "! allocation"
+ /* ERROR: Allocation failed */
+ log_model_1(lineno, 105);
+ stt_delete(stptr);
+ }
+ } else { $? "! allocation"
+ /* ERROR: Allocation failed */
+ log_model_1(lineno, 105);
+ }
+ } else { $? "! empty"
+ /* ERROR: Syntax, string empty */
+ log_model_1(lineno, 106);
+ }
+ } else { $? "! closing double quote"
+ /* ERROR: Syntax, closing double quote missing or text after */
+ log_model_1(lineno, 107);
+ }
+ } else { $? ". hex sequence"
+ sl = 0;
+ cptr = str;
+ back = 1;
+ while ((NULL != cptr) && (0 != back)) {
+ nptr = dk4str8_next(cptr, NULL);
+ ep = NULL; $? ". current=\"%s\" next=\"%s\"", cptr, TR_8STR(nptr)
+ res = dk4ma_input_c8_hex_uchar(&uc, cptr, &ep, 1, NULL);
+ if (0 != res) {
+ str[sl++] = (char)uc; $? ". hex byte ok"
+ } else {
+ back = 0; $? "! not a hex byte"
+ /* ERROR: Syntax, not a hexadecimal byte */
+ log_model_3(lineno, 108, 109, cptr);
+ }
+ cptr = nptr;
+ }
+ if (0 != back) {
+ if (0 < sl) { $? ". string ok"
+ stptr = stt_new((unsigned char *)str, sl, state, start);
+ if (NULL != stptr) { $? ". allocation ok"
+ if (0 == dk4sto_add(s_stn, stptr, NULL)) {
+ back = 0; $? "! allocation"
+ stt_delete(stptr);
+ /* ERROR: Allocation failed */
+ log_model_1(lineno, 105);
+ }
+#if TRACE_DEBUG
+ else { $? ". added to storage"
+ }
+#endif
+ } else { $? "! allocation"
+ back = 0;
+ /* ERROR: Memory allocation failed */
+ log_model_1(lineno, 105);
+ }
+ } else { $? "! empty string"
+ /* ERROR: Syntax, empty string */
+ log_model_1(lineno, 106);
+ }
+ }
+ }
+ } else { $? "! NULL"
+ /* ERROR: Value required */
+ log_model_1(lineno, 110);
+ }
+ } else { $? "! memory allocation"
+ /* ERROR: Memory allocation failed */
+ log_model_1(lineno, 105);
+ } $? "- model_conf_state_text %d", back
+ return back;
+}
+
+
+
+/** Process one configuration line from model file.
+ @param str Line to process.
+ @param lineno Line number in the file (for diagnostics).
+ @return 1 on success, 0 on error.
+*/
+static
+int
+process_model_line(char *str, dk4_um_t lineno)
+{
+ char *valptr; /* Value in line */
+ int back = 0;
+ $? "+ process_model_line \"%s\"", TR_8STR(str)
+ valptr = dk4str8_chr(str, '=');
+ if (NULL != valptr) { $? ". value ok"
+ *(valptr++) = '\0';
+ dk4str8_normalize(str, NULL);
+ valptr = dk4str8_start(valptr, NULL);
+ if (NULL != valptr) { $? ". value contains text"
+ switch (dk4str8_array_index(model_keys, str, 0)) {
+ case 0: {
+ back = model_conf_map(valptr, lineno);
+ } break;
+ case 1: {
+ back = model_conf_error_condition(valptr, 0, lineno);
+ } break;
+ case 2: {
+ back = model_conf_error_condition(valptr, 1, lineno);
+ } break;
+ case 3: {
+ back = model_conf_status_oid(valptr, lineno);
+ } break;
+ case 4: {
+ back = model_conf_state_text(valptr, PJSNMP_ST_STANDBY, 0, lineno);
+ } break;
+ case 5: {
+ back = model_conf_state_text(valptr, PJSNMP_ST_STANDBY, 1, lineno);
+ } break;
+ case 6: {
+ back = model_conf_state_text(valptr, PJSNMP_ST_IDLE, 0, lineno);
+ } break;
+ case 7: {
+ back = model_conf_state_text(valptr, PJSNMP_ST_IDLE, 1, lineno);
+ } break;
+ case 8: {
+ back = 1;
+ if (NULL != valptr) {
+ valptr = dk4str8_start(valptr, NULL);
+ if (NULL != valptr) {
+ dk4str8_normalize(valptr, NULL);
+ if (dk4str8_is_bool(valptr)) {
+ stat_always = dk4str8_is_on(valptr);
+ } else {
+ back = 0;
+ /* ERROR: Not a boolean */
+ log_model_3(lineno, 111, 112, valptr);
+ }
+ } else {
+ stat_always = 1;
+ }
+ } else {
+ stat_always = 1;
+ }
+ } break;
+ case 9: {
+ back = model_conf_state_text(valptr, PJSNMP_ST_BUSY, 0, lineno);
+ } break;
+ case 10: {
+ back = model_conf_state_text(valptr, PJSNMP_ST_BUSY, 1, lineno);
+ } break;
+ case 11: {
+ back = model_conf_state_text(valptr, PJSNMP_ST_UNKNOWN, 0, lineno);
+ } break;
+ case 12: {
+ back = model_conf_state_text(valptr, PJSNMP_ST_UNKNOWN, 1, lineno);
+ } break;
+ case 13: {
+ back = model_conf_state_text(valptr, PJSNMP_ST_ERROR, 0, lineno);
+ } break;
+ case 14: {
+ back = model_conf_state_text(valptr, PJSNMP_ST_ERROR, 1, lineno);
+ } break;
+ case 15: {
+ back = model_conf_state_text(valptr, PJSNMP_ST_WARMUP, 0, lineno);
+ } break;
+ case 16: {
+ back = model_conf_state_text(valptr, PJSNMP_ST_WARMUP, 1, lineno);
+ } break;
+ default: { $? "! illegal key"
+ /* ERROR: Syntax, unknown key */
+ log_model_3(lineno, 113, 114, str);
+ } break;
+ }
+ } else { $? "! missing value"
+ /* ERROR: Syntax, missing value */
+ log_model_1(lineno, 110);
+ }
+ } else { $? "! missing value"
+ /* ERROR: Syntax, missing value */
+ log_model_1(lineno, 110);
+ } $? "- process_model_line %d", back
+ return back;
+}
+
+
+
+/** Configure for specified SNMP model.
+*/
+static
+int
+process_model_setup(void)
+{
+ FILE *infile; /* Input file to read */
+ char *p1; /* Start of text in line */
+ dk4_um_t lineno = (dk4_um_t)0UL;
+ int in_model = 0; /* Flag: In model to read */
+ int found = 0; /* Flag: Model was found */
+ int back = 0;
+ $? "+ process_model_setup"
+ infile = fopen(((NULL != model_file) ? model_file : def_model_file), "r");
+ if (NULL != infile) { $? ". file opened"
+ back = 1;
+ while (NULL != fgets(pjsnmp_buf, sizeof(pjsnmp_buf), infile)) {
+ lineno++;
+#if TRACE_DEBUG
+ dk4str8_delnl(pjsnmp_buf); $? ". buffer \"%s\"", pjsnmp_buf
+#endif
+ p1 = dk4str8_start(pjsnmp_buf, NULL);
+ if (NULL != p1) {
+ if ('[' == *p1) {
+ in_model = check_in_model(++p1, &back, lineno);
+ if (0 != in_model) {
+ found = 1;
+ }
+ } else {
+ if (0 != in_model) {
+ if ('#' != *p1) {
+#if !TRACE_DEBUG
+ dk4str8_delnl(pjsnmp_buf);
+#endif
+ if (0 == process_model_line(p1, lineno)) {
+ back = 0;
+ }
+ }
+ }
+ }
+ }
+ }
+ fclose(infile);
+ if (0 == found) { $? "! model not found"
+ back = 0;
+ /* ERROR: Model not found */
+ log_model_3((dk4_um_t)0UL, 115, 116, model_name);
+ }
+ } else { $? "! failed to open model file"
+ /* ERROR: Failed to open model file */
+ log_model_3(
+ (dk4_um_t)0UL, 115, 116,
+ ((NULL != model_file) ? model_file : def_model_file)
+ );
+ } $? "- process_model_setup %d", back
+ return back;
+}
+
+
+
+/** Process PRINTCAP_ENTRY and optionally
+ model file.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+process_setup(void)
+{
+ char *ptr; /* Environment variable value */
+ char *cl; /* Current line */
+ char *nl; /* Next line */
+ char *ci; /* Current item */
+ char *ni; /* Next item */
+ int found = 0; /* Already item found */
+ int back = 0;
+ $? "+ process_setup"
+
+ ptr = getenv(pjsnmp_kw[2]);
+ if (NULL != ptr) { $? ". have printcap entry"
+ printcap_entry = dk4str8_dup(ptr, NULL);
+ if (NULL != printcap_entry) { $? ". have private copy"
+ back = 1; $? ". back = 1"
+ cl = printcap_entry;
+ while (NULL != cl) {
+ nl = dk4str8_chr(cl, '\n');
+ if (NULL != nl) {
+ *(nl++) = '\0';
+ nl = dk4str8_start(nl, NULL);
+ } $? ". line current=\"%s\" next=\"%s\"", cl, TR_8STR(nl)
+ ptr = cl;
+ while ('\0' != *ptr) {
+ if ('\r' == *ptr) { *ptr = '\0'; } else { ptr++; }
+ }
+ ci = dk4str8_start(cl, NULL);
+ if (NULL != ci) {
+ if ('#' != *ci) {
+ while (NULL != ci) {
+ ni = dk4str8_chr(ci, ':');
+ if (NULL != ni) {
+ *(ni++) = '\0'; ni = dk4str8_start(ni, NULL);
+ } $? ". item current=\"%s\" next=\"%s\"", ci, TR_8STR(ni)
+ ci = dk4str8_start(ci, NULL);
+ if (NULL != ci) {
+ if (0 != found) {
+ if (0 == process_one_config_item(ci)) {
+ back = 0; $? ". back = 0"
+ }
+ }
+ found = 1;
+ }
+ ci = ni;
+ }
+ }
+ }
+ cl = nl;
+ }
+ if (NULL == host_name) {
+ back = 0; $? "! missing host name, back = 0"
+ /* ERROR: Host name of printer required */
+ log_1_with_header(2, 119);
+ }
+ if (0 != back) {
+ if (NULL != model_name) {
+ back = process_model_setup(); $? ". back = %d", back
+ }
+ }
+ if (0 != back) {
+ if (0 != acct_achk) { $? ". checking requires enab"
+ acct_enab = 1;
+ }
+ if (0 != acct_enab) {
+ if (NULL == acct_name) {
+ if ((NULL == acct_host) || (0 == acct_port)) {
+ log_1_with_header(2, 165);
+ back = 0;
+ }
+ }
+ }
+ }
+ } else { $? "! allocation"
+ /* ERROR: Memory allocation failed */
+ log_1_with_header(2, 105);
+ }
+ } else { $? "! missing PRINTCAP_ENTRY"
+ /* ERROR: Missing printcap entry environment variable */
+ log_1_with_header(2, 120);
+ }
+ $? "- process_setup %d", back
+ return back;
+}
+
+
+
+/** Eat up remaining input from standard input.
+*/
+static
+void
+eatup_input(void)
+{
+ size_t rdb; /* Number of read bytes */
+ int cc = 1;
+ $? "+ eatup_input"
+ do {
+ if (0 != can_continue(0)) {
+ if (0 == have_eof) { $? ". must read"
+ rdb = fread(pjsnmp_buf, 1, sizeof(pjsnmp_buf), stdin);
+ if (0 == rdb) { $? ". final 0-bytes read"
+ cc = 0;
+ have_eof = 1;
+ }
+#if TRACE_DEBUG
+ else { $? ". data found"
+ }
+#endif
+ } else { $? ". eof found"
+ cc = 0;
+ }
+ } else { $? "! signal"
+ cc = -1;
+ }
+ } while (1 == cc);
+ $? "- eatup_input"
+}
+
+
+
+/** Release memory for the text nodes in s_stn.
+*/
+static
+void
+relase_status_text_nodes(void)
+{
+ status_text_t *ptr; /* Current node to release */
+ $? "+ relase_status_text_nodes"
+ if (NULL != s_stn) {
+ if (NULL != i_stn) {
+ dk4sto_it_reset(i_stn);
+ do {
+ ptr = (status_text_t *)dk4sto_it_next(i_stn);
+ if (NULL != ptr) { $? ". release one node"
+ stt_delete(ptr);
+ }
+ } while(NULL != ptr);
+ dk4sto_it_close(i_stn); i_stn = NULL;
+ }
+ dk4sto_close(s_stn); s_stn = NULL;
+ }
+ $? "- relase_status_text_nodes"
+}
+
+
+
+/** Attempt to open an SNMP session.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+attempt_snmp_session(void)
+{
+ struct snmp_session template; /* Template for the session */
+ int back = 0;
+ $? "+ attempt_snmp_session"
+ init_snmp(pjsnmp_kw[4]);
+ DK4_MEMRES(&template, sizeof(template));
+ snmp_sess_init(&template);
+ template.version = snmp_version;
+ template.peername = host_name;
+ template.community = (unsigned char *)snmp_comm;
+ if (NULL == snmp_comm) {
+ template.community = (unsigned char *)(pjsnmp_kw[5]);
+ }
+ template.community_len = strlen((char *)(template.community));
+ snmp_sess = snmp_open(&template);
+ if (NULL != snmp_sess) { $? ". session"
+ back = 1;
+ } else { $? "! no session"
+ /* ERROR: Failed to open SNMP session */
+ log_1_no_header(121);
+ if (0 != snmp_igfs) { $? ". ignore failed session"
+ back = 1;
+ }
+ } $? "- attempt_snmp_session %d", back
+ return back;
+}
+
+
+
+/** Accounting data exchange via socket (either network socket
+ or local UNIX domain socket) and close socket.
+ @param sock Socket to use for data exchange.
+ @param expect_response Flag: Response from accounting system expected.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+accounting_ex_socket(dk4_socket_t sock, int expect_response)
+{
+ size_t sl; /* String length */
+ size_t by; /* Bytes written or read */
+ int res; /* Operation result */
+ int cutted; /* String was cutted */
+ int cc; /* Flag: Can continue */
+ int back = 0;
+ $? "+ accounting_ex_socket %d %d", (int)sock, expect_response
+ cutted = 0;
+ if (0 != can_continue(0)) { $? ". can run"
+ sl = strlen(pjsnmp_buf);
+ by = sl;
+ res = dk4socket_send(sock, pjsnmp_buf, &by, 0, 0L, 0L, NULL);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) { $? ". send ok"
+ if (by == sl) { $? ". number of bytes ok"
+ back = 1; $? ". back=1"
+ } else { $? "! partial"
+ /* ERROR: Partial send */
+ log_1_no_header(123);
+ }
+ } else { $? "! send"
+ /* ERROR: Failed to send data */
+ log_1_no_header(122);
+ }
+ sl = 0;
+ pjsnmp_buf[0] = '\0';
+ res = dk4socket_shutdown(sock, DK4_SOCKET_SHUT_WRITE, NULL);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) { $? ". shutdown ok"
+ cc = 1;
+ do {
+ if (0 != can_continue(0)) { $? ". can run"
+ by = sizeof(stat_text) - 1;
+ res = dk4socket_recv(sock, stat_text, &by, 0, 0L, 0L, NULL);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) { $? ". recv"
+ if (0 < by) { $? ". bytes"
+ stat_text[by] = '\0';
+ res = dk4str8_cat_s(pjsnmp_buf,sizeof(pjsnmp_buf),stat_text,NULL);
+ if (0 == res) {
+ cutted = 1; $? "! too long"
+ back = 0;
+ }
+ } else { $? ". 0 bytes"
+ cc = 0;
+ }
+ } else { $? "! recv"
+ cc = -1;
+ }
+ } else { $? "! signal"
+ cc = -1;
+ back = 0;
+ }
+ } while(1 == cc);
+ } else { $? "! socket shutdown"
+ back = 0;
+ /* ERROR: Socket shutdown failed */
+ log_1_no_header(124);
+ }
+ if (0 != expect_response) { $? ". response expected"
+ if (0 == strlen(pjsnmp_buf)) { $? "! no response"
+ back = 0;
+ }
+ if (0 != cutted) { $? "! too much response data"
+ back = 0;
+ }
+ }
+ } else { $? "! signal"
+ pjsnmp_buf[0] = '\0';
+ }
+ dk4socket_close(sock, NULL);
+ $? "- accounting_ex_socket %d", back
+ return back;
+}
+
+
+
+/** Accounting data exchange via local UNIX domain socket.
+ @param expect_response Flag: Response from accounting system expected.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+accounting_ex_local_socket(int expect_response)
+{
+ dk4_socket_t sock; /* Socket to use for accounting */
+ int back = 0;
+ $? "+ accounting_ex_local_socket response=%d", expect_response
+ sock = dk4socket_c8_unix_client(acct_name, NULL);
+ if (INVALID_SOCKET != sock) {
+ back = accounting_ex_socket(sock, expect_response);
+ /* Socket not closed here, closed in accounting_ex_socket() */
+ } else {
+ /* ERROR: Failed to open UNIX domain socket */
+ log_1_no_header(125);
+ pjsnmp_buf[0] = '\0';
+ }
+ $? "- accounting_ex_local_socket %d", back
+ return back;
+}
+
+
+
+/** Accounting data exchange via network socket.
+ @param expect_response Flag: Response from accounting system expected.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+accounting_ex_network(int expect_response)
+{
+ dk4_socket_t sock; /* Socket to use for accounting */
+ int back = 0;
+ $? "+ accounting_ex_network response=%d", expect_response
+ sock = dk4socket_c8_tcp_client_host_port(acct_host,acct_port,0,0L,0L,NULL);
+ if (INVALID_SOCKET != sock) {
+ back = accounting_ex_socket(sock, expect_response);
+ /* Socket not closed here, closed in accounting_ex_socket() */
+ } else {
+ /* ERROR: Failed to open network connection */
+ log_1_no_header(125);
+ pjsnmp_buf[0] = '\0';
+ }
+ $? "- accounting_ex_network %d", back
+ return back;
+}
+
+
+
+/** Accounting data exchange to file.
+ @param fipo Accounting file.
+ @param expect_response Flag: Response from accounting system expected.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+accounting_ex_file(FILE *fipo, int expect_response)
+{
+ int back = 0;
+ $? "+ accounting_ex_file response=%d", expect_response
+ if (EOF != fputs(pjsnmp_buf, fipo)) { $? ". fputs"
+ if (EOF != fflush(fipo)) { $? ". fflush"
+ back = 1;
+ }
+#if TRACE_DEBUG
+ else { $? "! fflush"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! fputs"
+ }
+#endif
+ pjsnmp_buf[0] = '\0';
+ if (0 != expect_response) { $? "! response wanted"
+ back = 0;
+ } $? "- accounting_ex_file %d", back
+ return back;
+}
+
+
+
+/** Accounting data exchange via pipe.
+ @param expect_response Flag: Response from accounting system expected.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+accounting_ex_pipe(int expect_response)
+{
+ FILE *fipo = NULL; /* Connection to pipe */
+ char *prgn = NULL; /* Program name */
+ int back = 0;
+ int pcres = 0; /* Result from pclose */
+ $? "+ accounting_ex_pipe response=%d", expect_response
+ prgn = dk4str8_start(&(acct_name[1]), NULL);
+ if (NULL != prgn) { $? ". command name ok"
+ fipo = popen(prgn, "w");
+ if (NULL != fipo) { $? ". pipe opened"
+ back = accounting_ex_file(fipo, 0);
+ pcres = pclose(fipo);
+ pjsnmp_buf[0] = '\0';
+ if (0 != expect_response) {
+ switch (pcres) {
+ case LPRNG_EXIT_REMOVE : {
+ decision = 3;
+ } break;
+ case LPRNG_EXIT_HOLD : {
+ decision = 2;
+ }
+ default : {
+ decision = 1;
+ } break;
+ }
+ log_3_no_header(166, 167, accounting_responses[decision - 1]);
+ }
+ } else { $? "! popen"
+ /* ERROR: Failed to start program for pipe */
+ log_1_no_header(126);
+ pjsnmp_buf[0] = '\0';
+ }
+ } else { $? "! command name not found"
+ /* ERROR: Not command name found */
+ log_1_with_header(2, 127);
+ pjsnmp_buf[0] = '\0';
+ } $? "- accounting_ex_pipe %d", back
+ return back;
+}
+
+
+
+/** Accounting data exchange via file specified by name.
+ @param expect_response Flag: Response from accounting system expected.
+ @param crf Flag: Create new file.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+accounting_ex_filename(int expect_response, int crf)
+{
+ dk4_er_t er; /* Error report */
+ FILE *fipo = NULL; /* File to write to */
+ int back = 1;
+ int tests = DK4_FOPEN_SC_USER; /* Security tests for fopen */
+ $? "+ accounting_ex_filename response=%d, create=%d", expect_response, crf
+ if (0 != dk4isadmin()) { $? ". administrative privileges"
+ tests = DK4_FOPEN_SC_PRIVILEGED;
+ }
+ dk4error_init(&er);
+ fipo = dk4fopen_c8(acct_name, ((0 != crf) ? "w" : "a"), tests, &er);
+ if (NULL != fipo) { $? ". fopen"
+ back = accounting_ex_file(fipo, expect_response);
+ if(EOF == fclose(fipo)) { $? "! fclose"
+ back = 0;
+ }
+ } else { $? "! fopen"
+ /* ERROR: Failed to open accounting file name */
+ log_1_no_header(128);
+ pjsnmp_buf[0] = '\0';
+ } $? "- accounting_ex_filename %d", back
+ return back;
+}
+
+
+
+#if 0
+/* 2016-02-10:
+ Although chapter 15.5 of the LPRng reference manual states that the
+ :af file is opened (file, pipe or network socket) and passed as
+ file descriptor 3 to all filters, this did not work in my tests.
+ Text written to fd 3 did not arrive at the accounting system.
+*/
+
+/** Accounting data exchange via file descriptor 3.
+ @param expect_response Flag: Response from accounting system expected.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+accounting_ex_fd3(int expect_response)
+{
+ size_t sl; /* String length */
+ ssize_t bwr; /* Number of bytes written or read */
+ int back = 0;
+ $? "+ accounting_ex_fd3 response=%d", expect_response
+ sl = strlen(pjsnmp_buf);
+ bwr = write(3, pjsnmp_buf, sl);
+ pjsnmp_buf[0] = '\0';
+ if (0 < bwr) { $? ". write"
+ if (sl == (size_t)bwr) { $? ". full"
+ back = 1;
+ } else { $? "! partial"
+ /* ERROR: Incomplete write operation */
+ log_1_no_header(122);
+ }
+ if (0 != expect_response) { $? ". expect response"
+ bwr = read(3, pjsnmp_buf, sizeof(pjsnmp_buf));
+ if (0 < bwr) { $? ". bytes read"
+ pjsnmp_buf[bwr] = '\0';
+ } else { $? "! no response"
+ pjsnmp_buf[0] = '\0';
+ back = 0;
+ }
+ }
+ } else { $? "! write"
+ /* ERROR: Write failed */
+ log_1_no_header(122);
+ } $? "- accounting_ex_fd3 %d", back
+ return back;
+}
+
+#endif
+
+
+
+
+
+/** Data exchange with accounting system.
+ The contents of pjsnmp_buf is sent to the accounting system,
+ the response - if any - is stored in pjsnmp_buf.
+ @param expect_response Flag: Accounting system should send response.
+ @return 1 on successfull exchange, 0 on connection error.
+*/
+static
+int
+accounting_exchange(int expect_response)
+{
+ dk4_stat_t stb; /* File status buffer */
+ int issock = 0; /* Flag: File is socket */
+ int back = 0; /* Function result */
+ int crf = 0; /* Flag: Create log file */
+ $? "+ accounting_exchange response=%d", expect_response
+ if ((NULL != acct_host) && (0 < acct_port)) { $? ". host+port"
+ log_1_no_header(154);
+ back = accounting_ex_network(expect_response);
+ log_1_no_header((0 != back) ? 159 : 160);
+ } else { $? ". no host+port"
+ if (NULL != acct_name) { $? ". acct_name"
+ if ('|' == *acct_name) { $? ". pipe"
+#if 0
+ if (0 != expect_response) {
+ /* ERROR: Can not receive response from pipe */
+ log_1_with_header(2, 129);
+ }
+#endif
+ log_1_no_header(155);
+ back = accounting_ex_pipe(expect_response);
+ log_1_no_header((0 != back) ? 159 : 160);
+ } else { $? ". not a pipe"
+ if (0 != dk4stat_c8(&stb, acct_name, NULL)) {
+ if (0 != dk4stat_is_unix_domain_socket(&stb, NULL)) {
+ issock = 1; $? ". existing socket"
+ }
+ } else {
+ crf = 1; $? ". create new file"
+ }
+ if (0 != issock) {
+ log_1_no_header(156);
+ back = accounting_ex_local_socket(expect_response);
+ log_1_no_header((0 != back) ? 159 : 160);
+ } else {
+ if (0 != expect_response) {
+ /* ERROR: Can not receive response from file */
+ log_1_with_header(2, 130);
+ }
+ log_1_no_header(157);
+ back = accounting_ex_filename(expect_response, crf);
+ log_1_no_header((0 != back) ? 159 : 160);
+ }
+ }
+ } else { $? ". fd3"
+#if 0
+ log_1_no_header(158);
+ back = accounting_ex_fd3(expect_response);
+ log_1_no_header((0 != back) ? 159 : 160);
+#else
+ log_1_with_header(2, 165);
+#endif
+ }
+ } $? "- accounting_exchange %d", back
+ return back;
+}
+
+
+
+/** Check users permission to print on queue.
+ @return 1 if user is allowed to print, 0 otherwise.
+*/
+static
+int
+check_permission(void)
+{
+ int back = 1;
+ int res = 0; /* Result from check */
+ const size_t bsz = sizeof(pjsnmp_buf); /* Buffer size */
+ $? "+ check_permission"
+ if ((0 != acct_enab) && (0 != acct_achk)) { $? ". check required"
+ /* LOG: Checking print permission */
+ log_5_no_header(131, 132, 133, user_name, queue_name);
+ if(0 != dk4str8_cpy_s(pjsnmp_buf, bsz, pjsnmp_kw[6], NULL)) {
+ if(0 != dk4str8_cat_s(pjsnmp_buf, bsz, pjsnmp_kw[1], NULL)) {
+ if(0 != dk4str8_cat_s(pjsnmp_buf, bsz, queue_name, NULL)) {
+ if(0 != dk4str8_cat_s(pjsnmp_buf, bsz, pjsnmp_kw[1], NULL)) {
+ if(0 != dk4str8_cat_s(pjsnmp_buf, bsz, user_name, NULL)) {
+ if(0 != dk4str8_cat_s(pjsnmp_buf, bsz, pjsnmp_kw[0], NULL)) {
+ back = 0; $? ". request ok"
+ if (0 != accounting_exchange(1)) { $? ". request/response"
+ dk4str8_normalize(pjsnmp_buf, NULL); $? ". \"%s\"", pjsnmp_buf
+ if (0 < strlen(pjsnmp_buf)) { $? ". data in response"
+ if (0 != decision) {
+ res = decision - 1;
+ } else {
+ res = dk4str8_array_index(accounting_responses, pjsnmp_buf, 0);
+ if (-1 < res) { decision = res + 1; }
+ }
+ switch (res) {
+ case 0: {
+ back = 1; $? ". ACCEPT"
+ } break;
+ case 1: { $? ". HOLD"
+ exval = LPRNG_EXIT_HOLD;
+ } break;
+ }
+ log_3_no_header(166, 167, pjsnmp_buf);
+ } else { $? "! empty response"
+#if 0
+ /* 2016-02-15 An empty response indicates permission
+ to print.
+ */
+ if (0 != acct_apcf) { back = 1; }
+#endif
+ back = 1;
+ }
+ } else { $? "! no response"
+ if (0 != acct_apcf) { back = 1; }
+ else { decision = 3; }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ /* LOG: Test result */
+ log_1_no_header((0 != back) ? 134 : 135);
+ } $? "- check_permission %d", back
+ return back;
+}
+
+
+
+/** Retrieve integer value from variable list.
+ @param iptr Address of variable to set.
+ @param var SNMP variable containing the value.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+get_int(int *iptr, struct variable_list *var)
+{
+ char bu[64]; /* Buffer for numeric values as text */
+ const char *endptr = NULL; /* First unprocessable character */
+ long l; /* long value */
+ int i; /* int value */
+ int back = 0;
+ $? "+ get_int"
+ switch (var->type) {
+ case ASN_OCTET_STR : { $? ". from string"
+ if ((var->val_len > 0) && (var->val_len < sizeof(bu))) {
+ dk4mem_cpy(bu, (void *)((var->val).string), var->val_len, NULL);
+ bu[var->val_len] = '\0';
+ if (0 != dk4ma_input_c8_dec_int(&i, bu, &endptr, 1, NULL)) {
+ *iptr = i;
+ back = 1;
+ }
+ }
+ } break;
+ case ASN_TIMETICKS :
+ case ASN_GAUGE :
+ case ASN_COUNTER :
+ case ASN_INTEGER : { $? ". from integer"
+ l = *((var->val).integer);
+ *iptr = (int)l;
+ back = 1;
+ } break;
+ }
+ $? "- get_int %d", back
+ return back;
+}
+
+
+
+/** Retrieve unsigned long value from variable list.
+ @param ulptr Address of variable to set.
+ @param var SNMP variable containing the value.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+get_ul(unsigned long *ulptr, struct variable_list *var)
+{
+ unsigned long ul = 0UL; /* Result variable */
+ long l; /* long value */
+ int back = 0;
+ $? "+ get_ul"
+ switch (var->type) {
+ case ASN_OCTET_STR : { $? ". from byte array"
+ if (0 < var->val_len) {
+ ul |=
+ ((((unsigned long)(((var->val).string)[0])) << 24) & 0xFF000000UL);
+ back = 1;
+ }
+ if (1 < var->val_len) {
+ ul |=
+ ((((unsigned long)(((var->val).string)[1])) << 16) & 0x00FF0000UL);
+ }
+ if (2 < var->val_len) {
+ ul |=
+ ((((unsigned long)(((var->val).string)[2])) << 8) & 0x0000FF00UL);
+ }
+ if (3 < var->val_len) {
+ ul |=
+ ((((unsigned long)(((var->val).string)[3])) ) & 0x000000FFUL);
+ }
+ if (0 != back) {
+ *ulptr = ul;
+ }
+ } break;
+ case ASN_TIMETICKS :
+ case ASN_GAUGE :
+ case ASN_COUNTER :
+ case ASN_INTEGER : { $? ". from integer"
+ l = *((var->val).integer);
+ if (0L <= l) {
+ *ulptr = (unsigned long)l;
+ back = 1;
+ }
+ } break;
+ }
+ $? "- get_ul %d", back
+ return back;
+}
+
+
+
+/** Check whether a buffer contains non-ASCII characters.
+ @param ptr Buffer address.
+ @param i Buffer size.
+ @return 1 if non-ASCII found, 0 otherwise.
+*/
+static
+int
+contains_non_ascii(const char *ptr, size_t i)
+{
+ int back = 0;
+ $? "+ contains_non_ascii"
+ while ((0 == back) && (0 < i)) {
+ if (0x7F < (unsigned char)(*(ptr++))) {
+ back = 1;
+ }
+ i--;
+ } $? "- contains_non_ascii %d", back
+ return back;
+}
+
+
+
+/** Replace all non-ascii characters by question marks.
+*/
+static
+void
+no_non_ascii(char *str)
+{
+ unsigned char uc;
+ while ('\0' != *str) {
+ uc = (unsigned char)(*str);
+ if ((0x20 > uc) || (0x7E < uc)) {
+ *str = '?';
+ }
+ str++;
+ }
+}
+
+
+
+
+/** Check two OIDs for equality.
+ @param pl Left OID.
+ @param szl Left OID size.
+ @param pr Right OID.
+ @param szr Right OID size.
+ @return 1 for equal OIDs, 0 otherwise.
+*/
+static
+int
+oids_equal(const oid *pl, size_t szl, const oid *pr, size_t szr)
+{
+#if VERSION_BEFORE_20160206
+ size_t i; /* Index of current sub-id to compare */
+#endif
+ int back = 0;
+ if ((szl == szr) && (0 < szl)) {
+#if VERSION_BEFORE_20160206
+ back = 1;
+ for (i = 0; ((i < szl) && (1 == back)); i++) {
+ if (pl[i] != pr[i]) {
+ back = 0;
+ }
+ }
+#else
+ /* No check for overflow necessary, max 4 * 128. */
+ if (0 == dk4mem_cmp(pl, pr, (szl * sizeof(oid)), NULL)) {
+ back = 1;
+ }
+#endif
+ }
+ return back;
+}
+
+
+/** Find OID index.
+ @param oid Pointer to OID to check.
+ @param sz OID size.
+ @return 0 for hrDeviceStatus, 1 for hrPrinterStatus,
+ 2 for page counter, 3 for hrPrinterDetectedErrorState,
+ 4 for status text,
+ -1 otherwise.
+*/
+static
+int
+oid_index(oid *p, size_t sz)
+{
+ int back = -1;
+ $? "+ oid_index"
+ if (0 != oids_equal(p, sz, oid_ds, sz_oid_ds)) {
+ back = 0;
+ } else {
+ if (0 != oids_equal(p, sz, oid_ps, sz_oid_ps)) {
+ back = 1;
+ } else {
+ if (0 != oids_equal(p, sz, oid_pc, sz_oid_pc)) {
+ back = 2;
+ } else {
+ if (0 != oids_equal(p, sz, oid_pe, sz_oid_pe)) {
+ back = 3;
+ } else {
+ if (0 < sz_oid_st) { $? ". have status text oid"
+ if (0 != oids_equal(p, sz, oid_st, sz_oid_st)) {
+ back = 4;
+ }
+ }
+#if TRACE_DEBUG
+ else { $? "! no status text oid"
+ }
+#endif
+ }
+ }
+ }
+ } $? "- oid_index %d", back
+ return back;
+}
+
+
+
+/** Show one active condition from hrPrinterDetectedErrorState.
+ @param cond Condition bit (checked against the found conditions).
+ @param cind Index of corresponding text in pjsnmp_kw.
+*/
+static
+void
+show_pdes(unsigned long cond, size_t cind)
+{
+ if (0UL != (pdes_cond & cond)) {
+ fputs(pjsnmp_kw[((0UL != (pdes_error & cond)) ? 32 : 33)], out_file);
+ fputs(pjsnmp_kw[cind], out_file);
+ }
+}
+
+
+
+static
+void
+show_text_containing_non_ascii(const unsigned char *ptr, size_t num)
+{
+ while(0 < num--) {
+ if (0x7F < *ptr) {
+ fputc('?', out_file);
+ } else {
+ fputc(*ptr, out_file);
+ }
+ ptr++;
+ }
+}
+
+
+
+/** Report status if changed.
+ @param found Bitmask for found information.
+*/
+static
+void
+report_status_if_changed(int found)
+{
+ unsigned long tcond = 0x80000000UL; /* Bit for one condition */
+ int must_report = 0; /* Flag: Must report change */
+ int i;
+ $? "+ report_status_if_changed found=%d", found
+ /* Check whether or not to report.
+ */
+ if (stsum != ostsum) { $? ". summary changed"
+ must_report = 1;
+ } else {
+ if (devst != odevst) { $? ". device status changed"
+ must_report = 1;
+ } else {
+ if (prist != oprist) { $? ". printer status changed"
+ must_report = 1;
+ } else {
+ if (pdes_cond != opdes_cond) { $? ". error conditions changed"
+ must_report = 1;
+ } else {
+ if (0 < sz_stat_text) {
+ if (0 != force_printable_status_text) {
+ if (sz_ostat_text != sz_stat_text) {
+ must_report = 1;
+ } else {
+ if (0 != dk4mem_cmp(stat_text,ostat_text,sz_stat_text,NULL)) {
+ must_report = 1;
+ }
+ }
+ } else {
+ if (0 == contains_non_ascii(stat_text, sz_stat_text)) {
+ if (sz_stat_text != sz_ostat_text) {
+ must_report = 1; $? ". status text size changed"
+ } else {
+ if (0 != dk4mem_cmp(stat_text,ostat_text,sz_stat_text,NULL)) {
+ must_report = 1; $? ". status text changed"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* Report if necessary.
+ */
+ if (0 != must_report) { $? ". must report"
+ fputs(pjsnmp_kw[150], out_file);
+ (void)log_timestamp();
+ if ((-1 < devst) && (6 > devst)) {
+ if ((-1 < prist) && (6 > prist)) {
+ fputs(pjsnmp_kw[7], out_file);
+ fputs(pjsnmp_kw[11 + devst], out_file);
+ fputs(pjsnmp_kw[8], out_file);
+ fputs(pjsnmp_kw[17 + prist], out_file);
+ fputs(pjsnmp_kw[0], out_file);
+ }
+ }
+ fputs(pjsnmp_kw[9], out_file);
+ for (i = 0; i < 16; i++) {
+ if ((0 < i) && (0 == (i % 4))) { fputc('-', out_file); }
+ fputc(((0UL != (pdes_cond & tcond)) ? '1' : '0'), out_file);
+ tcond = tcond / 2UL;
+ }
+ fputs(pjsnmp_kw[0], out_file);
+ show_pdes(PDES_ERROR_DOOR_OPEN, 38);
+ show_pdes(PDES_ERROR_OFFLINE, 40);
+ show_pdes(PDES_ERROR_MARKER_SUPPLY_MISSING, 44);
+ show_pdes(PDES_ERROR_NO_TONER, 37);
+ show_pdes(PDES_WARNING_TONER_LOW, 36);
+ show_pdes(PDES_ERROR_INPUT_TRAY_MISSING, 42);
+ show_pdes(PDES_WARNING_INPUT_TRAY_EMPTY, 47);
+ show_pdes(PDES_ERROR_NO_PAPER, 35);
+ show_pdes(PDES_WARNING_PAPER_LOW, 34);
+ show_pdes(PDES_ERROR_OUTPUT_TRAY_MISSING, 43);
+ show_pdes(PDES_ERROR_PAPER_JAM, 39);
+ show_pdes(PDES_ERROR_OUTPUT_FULL, 46);
+ show_pdes(PDES_WARNING_OUTPUT_NEAR_FULL, 45);
+ show_pdes(PDES_WARNING_SERVICE, 41);
+ show_pdes(PDES_WARNING_OVERDUE_PREVENT_MAINT, 48);
+ if (0 < sz_stat_text) {
+ if (0 != force_printable_status_text) {
+ fputs(pjsnmp_kw[30], out_file);
+ show_text_containing_non_ascii((unsigned char *)stat_text,sz_stat_text);
+ fputs(pjsnmp_kw[31], out_file);
+ } else {
+ if (0 == contains_non_ascii(stat_text, sz_stat_text)) {
+ fputs(pjsnmp_kw[30], out_file);
+ fwrite(stat_text, 1, sz_stat_text, out_file);
+ fputs(pjsnmp_kw[31], out_file);
+ }
+ }
+ }
+ if ((-1 < stsum) && (7 > stsum)) {
+ fputs(pjsnmp_kw[10], out_file);
+ fputs(pjsnmp_kw[23 + stsum], out_file);
+ fputs(pjsnmp_kw[0], out_file);
+ }
+ if (PJSNMP_ST_ERROR == stsum) {
+ fputs(pjsnmp_kw[49], out_file);
+ } else {
+ if (0UL != (pdes_cond & PDES_WARNING_SERVICE)) {
+ if (0UL == (pdes_error & PDES_WARNING_SERVICE)) {
+ fputs(pjsnmp_kw[50], out_file);
+ }
+ }
+ }
+ fflush(out_file);
+ }
+ $? "- report_status_if_changed"
+}
+
+
+
+/** One SNMP data exchange.
+ @param passno 0 before start, 1 during transfer, 2 at end.
+ @return 1 on success, 0 on error (stop printing).
+*/
+static
+int
+one_snmp_request(int passno)
+{
+ status_text_t tx; /* Used in comparison */
+ status_text_t *ptx = NULL; /* Text node found */
+ struct snmp_pdu *rq = NULL; /* Request */
+ struct snmp_pdu *rs = NULL; /* Response */
+ struct variable_list *vars = NULL; /* Response variables */
+ int status = 0; /* SNMP result */
+ int found = 0; /* Information from response */
+ int back = 0;
+ $? "+ one_snmp_request pass=%d", passno
+ if (0 != can_continue(0)) { $? ". no signal"
+ if (NULL != snmp_sess) { $? ". session"
+ pdes_cond = 0UL;
+ pcnt = 0UL;
+ devst = 0;
+ prist = 0;
+ stsum = PJSNMP_ST_UNREACHABLE;
+ stat_text[0] = '\0';
+ sz_stat_text = 0;
+ rq = snmp_pdu_create(SNMP_MSG_GET);
+ if (NULL != rq) { $? ". rq"
+ back = 1;
+ snmp_add_null_var(rq, oid_ds, sz_oid_ds);
+ snmp_add_null_var(rq, oid_ps, sz_oid_ps);
+ snmp_add_null_var(rq, oid_pc, sz_oid_pc);
+ snmp_add_null_var(rq, oid_pe, sz_oid_pe);
+ if (0 < sz_oid_st) { $? ". have status text oid"
+ snmp_add_null_var(rq, oid_st, sz_oid_st);
+ }
+ status = snmp_synch_response(snmp_sess, rq, &rs);
+ if (STAT_SUCCESS == status) { $? ". status"
+ if (NULL != rs) { $? ". rs"
+ if (SNMP_ERR_NOERROR == rs->errstat) { $? ". errstat"
+
+ /* Obtain response elements.
+ */
+ stsum = PJSNMP_ST_UNKNOWN;
+ vars = rs->variables;
+ while (NULL != vars) {
+ switch (oid_index(vars->name, vars->name_length)) {
+ case 0: { $? ". device status"
+ if (0 != get_int(&devst, vars)) { $? ". value ok"
+ found |= 1;
+ }
+ } break;
+ case 1: { $? ". printer status"
+ if (0 != get_int(&prist, vars)) { $? ". value ok"
+ found |= 2;
+ }
+ } break;
+ case 2: { $? ". page count"
+ if (0 != get_ul(&pcnt, vars)) { $? ". value ok"
+ found |= 4; $? ". pcnt=%lu", pcnt
+ switch (passno) {
+ case 0: {
+ pc_start = pcnt;
+ have_pcs = 1;
+ } break;
+ case 1: {
+ /* When aborting due to timeout in
+ error or unreachable state we use the
+ last page counter seen.
+ */
+ pc_end = pcnt;
+ have_pce = 1;
+ } break;
+ case 2: {
+ pc_end = pcnt;
+ have_pce = 1;
+ } break;
+ }
+ }
+ } break;
+ case 3: { $? ". printer detected error state"
+ if (0 != get_ul(&pdes_cond, vars)) { found |= 8; }
+ } break;
+ case 4: { $? ". status text"
+ if (0 < vars->val_len) {
+ if (sizeof(stat_text) > vars->val_len) { $? ". length ok"
+ dk4mem_cpy(
+ stat_text, (vars->val).string,
+ vars->val_len, NULL
+ );
+ sz_stat_text = vars->val_len;
+ } else { $? "! too long, cutted"
+ dk4mem_cpy(
+ stat_text, (vars->val).string,
+ sizeof(stat_text), NULL
+ );
+ sz_stat_text = sizeof(stat_text);
+ }
+ found |= 16;
+ }
+ } break;
+ }
+ vars = vars->next_variable;
+ }
+
+ /* Build summary (1): device and printer status.
+ */
+ if (3 == (3 & found)) {
+ stsum = get_state_mapping(devst, prist);
+ $? ". stsum=%s (1)", pjsnmp_kw[23+stsum]
+ }
+
+ /* Build summary (2): printer detected error state
+ */
+ if (8 == (8 & found)) {
+ if ((0 != pdes_always) || (PJSNMP_ST_UNKNOWN == stsum)) {
+ if (0L != (pdes_error & pdes_cond)) {
+ stsum = PJSNMP_ST_ERROR; $? ". stsum=ERROR (2)"
+ }
+ }
+ }
+
+ /* Build summary (3): status text line
+ */
+ if (16 == (16 & found)) {
+ if ((0 != stat_always) || (PJSNMP_ST_UNKNOWN == stsum)) {
+ if ((NULL != s_stn) && (NULL != i_stn)) {
+ DK4_MEMRES(&tx, sizeof(tx));
+ tx.text = (unsigned char *)stat_text;
+ tx.size = sz_stat_text;
+ tx.state = 0;
+ tx.start = 0;
+ ptx = (status_text_t *)dk4sto_it_find_like(i_stn, &tx, 1);
+ if (NULL != ptx) {
+ stsum = ptx->state;
+ $? ". stsum=%s (3)", pjsnmp_kw[23 + stsum]
+ }
+ }
+ }
+ }
+
+ /* Build summary (4): Map unknown to busy if configured
+ */
+ if ((0 != unkn_busy) && (PJSNMP_ST_UNKNOWN == stsum)) {
+ stsum = PJSNMP_ST_BUSY; $? ". stsum=BUSY (4)"
+ }
+
+ /* For error state mark this page counter as print
+ job not yet finished.
+ */
+ switch (stsum) {
+ case PJSNMP_ST_ERROR: {
+ seen_printing = 0; $? ". seen_printing=0"
+ if ((0 < passno) && (0UL < pcnt)) {
+ pc_error = pcnt; $? ". pc_error=%lu", pc_error
+ }
+ start_unreach = (dk4_time_t)0UL;
+ if ((dk4_time_t)0UL == start_error) {
+ dk4time_get(&start_error);
+ }
+ } break;
+ case PJSNMP_ST_BUSY: {
+ seen_printing = 1; $? ". seen_printing=1"
+ start_unreach = (dk4_time_t)0UL;
+ start_error = (dk4_time_t)0UL;
+ } break;
+ case PJSNMP_ST_UNREACHABLE : {
+ if ((dk4_time_t)0UL == start_unreach) {
+ dk4time_get(&start_unreach);
+ }
+ start_error = (dk4_time_t)0UL;
+ } break;
+ default : {
+ start_unreach = (dk4_time_t)0UL;
+ start_error = (dk4_time_t)0UL;
+ } break;
+ }
+
+ /* On change, print new state.
+ */
+ report_status_if_changed(found);
+
+ /* Save data for next comparison.
+ */
+ odevst = devst;
+ oprist = prist;
+ ostsum = stsum;
+ opdes_cond = pdes_cond;
+ if (0 < sz_stat_text) {
+ DK4_MEMCPY(ostat_text, stat_text, sz_stat_text);
+ }
+ sz_ostat_text = sz_stat_text;
+ }
+#if TRACE_DEBUG
+ else { $? "! errstat"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! rs"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! status"
+ }
+#endif
+ if (NULL != rs) {
+ snmp_free_pdu(rs);
+ }
+ }
+#if TRACE_DEBUG
+ else { $? "! rq"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! no session"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! signal"
+ }
+#endif
+ $? "- one_snmp_request %d", back
+ return back;
+}
+
+
+
+/** Create accounting text line and do data exchange
+ with accounting system.
+ @param kwind Index of start keyword in pjsnmp_kw array.
+ @param pc Page counter value to transmit.
+*/
+static
+void
+accounting_index_and_value(size_t kwind, unsigned long pc)
+{
+ char buf[64]; /* Buffer for number as text */
+ const char *jt; /* Job title */
+ size_t szbuf = sizeof(pjsnmp_buf); /* Buffer size */
+ size_t sl;
+ int res; /* Conversion result */
+ $? "+ accounting_index_and_value %u %lu", (unsigned)kwind, pc
+ res = dk4ma_write_c8_decimal_unsigned(
+ buf, sizeof(buf), (dk4_um_t)pc, 0, NULL
+ );
+ if (0 != res) {
+ if (0 != dk4str8_cpy_s(pjsnmp_buf, szbuf, pjsnmp_kw[kwind], NULL)) {
+ if (0 != dk4str8_cat_s(pjsnmp_buf, szbuf, pjsnmp_kw[1], NULL)) {
+ if (0 != dk4str8_cat_s(pjsnmp_buf, szbuf, queue_name, NULL)) {
+ if (0 != dk4str8_cat_s(pjsnmp_buf, szbuf, pjsnmp_kw[1], NULL)) {
+ if (0 != dk4str8_cat_s(pjsnmp_buf, szbuf, user_name, NULL)) {
+ if (0 != dk4str8_cat_s(pjsnmp_buf, szbuf, pjsnmp_kw[1], NULL)) {
+ if (0 != dk4str8_cat_s(pjsnmp_buf, szbuf, buf, NULL)) {
+ if (0 != dk4str8_cat_s(pjsnmp_buf, szbuf, pjsnmp_kw[1], NULL)) {
+ if (0 != dk4str8_cat_s(pjsnmp_buf, szbuf, job_name, NULL)) {
+ if (0 != dk4str8_cat_s(pjsnmp_buf, szbuf, pjsnmp_kw[1], NULL)) {
+ jt = job_title;
+ if (NULL == jt) { jt = pjsnmp_kw[54]; }
+ sl = strlen(pjsnmp_buf);
+ if (0 != dk4str8_cat_s(pjsnmp_buf, szbuf, jt, NULL)) {
+ if (0 == allow_non_ascii) { no_non_ascii(&(pjsnmp_buf[sl])); }
+ if (0 != dk4str8_cat_s(pjsnmp_buf, szbuf, pjsnmp_kw[0], NULL)) {
+ $? ". request string created"
+ (void)accounting_exchange(0);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } $? "- accounting_index_and_value"
+}
+
+
+/** Report used pages to accounting system.
+*/
+static
+void
+report_used_pages(void)
+{
+ $? "+ report_used_pages"
+ if (0 != acct_start_end) {
+ accounting_index_and_value(51, pc_start);
+ accounting_index_and_value(52, pc_end);
+ } else {
+ accounting_index_and_value(53, (pc_end - pc_start));
+ }
+ $? "- report_used_pages"
+}
+
+
+
+/** Do accounting before and after print job.
+ @param passno 0=before print job, 1=after print job.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+do_accounting(int passno)
+{
+ static
+ char buf[8*sizeof(dk4_um_t)]; /* Number as text */
+ struct timeval to; /* Timeout for select */
+ dk4_time_t start_idle = (dk4_time_t)0UL; /* Start idle/standby */
+ dk4_time_t current_time = (dk4_time_t)0UL; /* Current time */
+ dk4_time_t timeout_time = (dk4_time_t)0UL; /* Timeout reached */
+ int res = 0; /* Conversion result */
+ int back = 0;
+ int cc = 1; /* Flag: Can continue */
+ int uncoi = 0; /* Flag: Unconditional idle reported */
+ int cto = 0; /* Flag: Must check timeout */
+ $? "+ do_accounting %d", passno
+ if (NULL != snmp_sess) { $? ". session"
+ /* In the loop retrieve printer status via SNMP,
+ finish if printer is idle or in standby state.
+ */
+ log_1_no_header(145+passno);
+ do {
+ if (0 != can_continue(0)) { $? ". no signal"
+ if (0 != one_snmp_request((0 == passno) ? 0 : 2)) {
+ $? ". SNMP exchange"
+
+ /* In idle or standby we can retrieve the page counter
+ if the page counter was changed or the printer was seen
+ printing.
+ */
+ switch (stsum) {
+ case PJSNMP_ST_IDLE : case PJSNMP_ST_STANDBY : {
+ back = 1; cc = 0; $? ". idle or standby"
+ cto = 0;
+ if (1 == passno) {
+ if ((0 == seen_printing) && (0 < print_timeout)) {
+ cto = 1; $? ". cto=1 (not seen printing)"
+ } else {
+ if ((0UL != pc_error) && (1 == have_pce)) {
+ if ((pc_end == pc_error)&&((dk4_um_t)0UL < print_timeout)) {
+ cto = 1; $? ". cto=1 (pagecounter)"
+ }
+ }
+ }
+ if (0 != cto) {
+ dk4time_get(&current_time);
+ if ((dk4_time_t)0UL < start_idle) {
+ if ((start_idle+(dk4_time_t)print_timeout) > current_time) {
+ back = 0; cc = 1; $? ". wait to start printing"
+ }
+ } else {
+ start_idle = current_time;
+ back = 0; cc = 1;
+ if (0 == uncoi) {
+ uncoi = 1;
+ res = dk4ma_write_c8_decimal_unsigned(
+ buf, sizeof(buf), print_timeout, 0, NULL
+ );
+ log_timestamp();
+ fputs(pjsnmp_kw[162], out_file);
+ if (0 != res) {
+ fputs(buf, out_file);
+ fputs(pjsnmp_kw[163], out_file);
+ }
+ fputs(pjsnmp_kw[164], out_file);
+ fflush(out_file);
+ }
+ }
+ }
+ }
+ } break;
+ case PJSNMP_ST_UNREACHABLE : {
+ start_idle = (dk4_time_t)0UL; /* not idle */
+ uncoi = 0;
+ /* If printer is unreachable we abort after timeout.
+ */
+ if (((0 == passno) && ((dk4_um_t)0UL != unto_start))
+ || ((1 == passno) && ((dk4_um_t)0UL != unto_end))
+ )
+ {
+ if ((dk4_time_t)0UL < start_unreach) {
+ dk4time_get(&current_time);
+ timeout_time =
+ start_unreach
+ + (dk4_time_t)((0 == passno) ? unto_start : unto_end);
+ if (current_time > timeout_time) { $? ". timeout unreach"
+ cc = 0;
+ /* ERROR: Timeout while printer unreachable */
+ log_1_no_header(136);
+ }
+ } else {
+ dk4time_get(&start_unreach);
+ }
+ }
+ } break;
+ case PJSNMP_ST_ERROR : {
+ start_idle = (dk4_time_t)0UL; /* not idle */
+ uncoi = 0;
+ if (
+ ((0 == passno) && ((dk4_um_t)0UL < erto_start))
+ || ((1 == passno) && ((dk4_um_t)0UL < erto_end))
+ )
+ {
+ if ((dk4_um_t)0UL < start_error) {
+ dk4time_get(&current_time);
+ timeout_time =
+ start_error
+ + (dk4_time_t)((0 == passno) ? erto_start : erto_end);
+ if (current_time > timeout_time) {
+ cc = 0;
+ /* ERROR: Timeout while printer in error state */
+ log_1_no_header(168);
+ if (0 == passno) {
+ back = 0; /* Do not print */
+ }
+ }
+ } else {
+ dk4time_get(&start_error);
+ }
+ }
+ } break;
+ default: {
+ start_idle = (dk4_time_t)0UL; /* not idle */
+ uncoi = 0;
+ } break;
+ }
+
+ /* Decrease cpu and network load from polling
+ */
+ if (1 == cc) {
+ if (0 != can_continue(0)) {
+ if (PJSNMP_ST_UNREACHABLE == stsum) {
+ sleep(1);
+ } else {
+ to.tv_sec = 0L;
+ to.tv_usec = 250000L;
+ (void)select(0, NULL, NULL, NULL, &to);
+ }
+ } else {
+ cc = -1;
+ }
+ }
+
+ } else { $? "! SNMP exchange failed"
+ cc = -1;
+ }
+ } else { $? "! signal"
+ cc = -1;
+ }
+ } while(1 == cc);
+ fputs(pjsnmp_kw[150], out_file);
+ if (((0 == passno)&&(0 != have_pcs))||((1 == passno)&&(0 != have_pce))) {
+ $? ". attempt to report page counter"
+ res = dk4ma_write_c8_decimal_unsigned(buf, sizeof(buf), pcnt, 0, NULL);
+ if (0 != res) {
+ $? ". before log3"
+ log_3_no_header((147+passno), 0, buf);
+ $? ". after log3"
+ }
+ $? ". page counter reported"
+ } else {
+ $? ". before log1"
+ log_1_no_header(149);
+ $? ". after log1"
+ }
+
+ /* Save page counter at start to page counter unusable for
+ print job finished.
+ */
+ if (0 == passno) {
+ if (0 != have_pcs) {
+ pc_error = pc_start;
+ }
+ }
+ /* After successful page counting at job end, report to
+ accounting system.
+ */
+ if (1 == passno) { $? ". end of print job"
+ if ((0 != have_pcs) && (0 != have_pce)) { $? ". have page counters"
+ if (pc_end > pc_start) { $? ". page counter changed"
+ /* Report number of used pages to accounting system */
+ report_used_pages();
+ }
+ }
+ }
+ } else { $? "! session"
+ if (0 != snmp_igfs) { $? ". ignore missing session"
+ back = 1;
+ }
+ } $? "- do_accounting %d", back
+ return back;
+}
+
+
+
+/** Transfer data to printer.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+data_transfer(void)
+{
+ fd_set wfds; /* Writable files set */
+ fd_set rfds; /* Readable files set */
+ struct timeval to; /* Timeout for select */
+ char *wrptr; /* Pointer to data to write */
+ dk4_time_t unwriteable; /* Socket started to be unwriteable */
+ dk4_time_t current; /* Current time */
+ dk4_time_t tots; /* Timestamp when timeout is reached */
+ size_t rdb; /* Number of bytes read from stdin */
+ size_t remaining; /* Remaining bytes to write to socket */
+ size_t wrb; /* Bytes currently written to socket */
+ dk4_socket_t sock; /* Network socket to printer */
+ int back = 0;
+ int cc = 1; /* Flag: Can continue */
+ int ccwr; /* Flag: Can continue writing */
+ int res; /* Number conversion result */
+ int writable; /* Flag: Socket is writeable */
+ $? "+ data_transfer"
+ unwriteable = (dk4_time_t)0UL;
+ if ((NULL != host_name) && (0 < host_port)) {
+ sock = dk4socket_c8_tcp_client_host_port(
+ host_name, host_port, local_port, 0L, 0L, NULL
+ );
+ if (INVALID_SOCKET != sock) {
+ exval = LPRNG_EXIT_SUCCESS;
+ dk4time_get(&t2);
+ back = 1;
+ log_1_no_header(151);
+ do {
+ if (0 != can_continue(0)) {
+ rdb = fread(pjsnmp_buf, 1, sizeof(pjsnmp_buf), stdin);
+ if (0 < rdb) {
+ wrptr = pjsnmp_buf;
+ remaining = rdb;
+ ccwr = 1;
+ do {
+ if (0 != can_continue(0)) {
+ writable = 0;
+ FD_ZERO(&wfds);
+ FD_SET(sock,&wfds);
+ if (0 != read_responses) {
+ FD_ZERO(&rfds);
+ FD_SET(sock,&rfds);
+ }
+ to.tv_sec = 0L;
+ to.tv_usec = 250000L;
+ if (0 != read_responses) {
+ res = select((sock + 1), &rfds, &wfds, NULL, &to);
+ } else {
+ res = select((sock + 1), NULL, &wfds, NULL, &to);
+ }
+ if (0 < res) {
+ if (FD_ISSET(sock,&wfds)) {
+ writable = 1;
+ unwriteable = (dk4_time_t)0UL;
+ } else {
+ if (0 != unwt_print) {
+ dk4time_get(&current);
+ if ((dk4_time_t)0UL != unwriteable) {
+ tots = unwriteable + (dk4_time_t)unwt_print;
+ if (current > tots) {
+ cc = ccwr = -1;
+ /* ERROR: Timeout, socket unwriteable */
+ log_1_no_header(137);
+ }
+ } else {
+ unwriteable = current;
+ }
+ }
+ }
+ if (0 != read_responses) {
+ if (FD_ISSET(sock,&rfds)) {
+ wrb = sizeof(dummy_text);
+ res = dk4socket_recv(sock,dummy_text,&wrb,0,0L,0L,NULL);
+ }
+ }
+ }
+ if (0 != can_continue(0)) {
+ if ((0 == writable) || (0 != check_trans)) {
+ if (0 != one_snmp_request(1)) {
+ switch (stsum) {
+ case PJSNMP_ST_UNREACHABLE : {
+ if ((dk4_um_t)0UL < unto_print) {
+ if ((dk4_time_t)0UL < start_unreach) {
+ tots = start_unreach + (dk4_time_t)unto_print;
+ dk4time_get(&current);
+ if (current > tots) {
+ cc = ccwr = -1;
+ /* ERROR: Timeout, printer start_unreach */
+ log_1_no_header(136);
+ }
+ } else {
+ dk4time_get(&start_unreach);
+ }
+ }
+ } break;
+ case PJSNMP_ST_ERROR : {
+ if ((dk4_um_t)0UL < erto_print) {
+ if ((dk4_time_t)0UL < start_error) {
+ tots = start_error + (dk4_time_t)erto_print;
+ dk4time_get(&current);
+ if (current > tots) {
+ cc = ccwr = -1;
+ /* ERROR: Timeout, printer start_unreach */
+ log_1_no_header(168);
+ }
+ } else {
+ dk4time_get(&start_error);
+ }
+ }
+ } break;
+ }
+ }
+ }
+ if (0 != can_continue(0)) {
+ wrb = remaining;
+ res = dk4socket_send(sock, wrptr, &wrb, 0, 0L, 0L, NULL);
+ switch (res) {
+ case DK4_SOCKET_RESULT_SUCCESS:
+ case DK4_SOCKET_RESULT_IN_PROGRESS :
+ {
+ if (0 < wrb) {
+ bytes_trans = dk4ma_um_add(bytes_trans,wrb,&er_bytes);
+ if (wrb < remaining) {
+ remaining = remaining - wrb;
+ wrptr = &(wrptr[wrb]);
+ } else {
+ remaining = 0;
+ ccwr = 0;
+ }
+ }
+ } break;
+ default: {
+ /* ERROR: Failed to send data */
+ log_1_no_header(138);
+ ccwr = -1; cc = -1; back = 0;
+ } break;
+ }
+ } else {
+ ccwr = -1; cc = -1; back = 0;
+ }
+ } else {
+ ccwr = -1; cc = -1; back = 0;
+ }
+ } else {
+ ccwr = -1; cc = -1; back = 0;
+ }
+ } while (1 == ccwr);
+ } else {
+ have_eof = 1;
+ cc = 0;
+ if (0 != ferror(stdin)) {
+ /* ERROR: Failed to read from standard input */
+ log_1_no_header(139);
+ }
+ }
+ } else {
+ cc = -1;
+ back = 0;
+ }
+ } while (1 == cc);
+ log_1_no_header((0 == cc) ? 152 : 153);
+ if (0 == cc) {
+ if (0 != host_ordr) {
+ res = dk4socket_shutdown(sock, DK4_SOCKET_SHUT_WRITE, NULL);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ cc = 1;
+ do {
+ if (0 != can_continue(0)) {
+ wrb = sizeof(pjsnmp_buf);
+ res = dk4socket_recv(sock, pjsnmp_buf, &wrb, 0, 0L, 0L, NULL);
+ switch (res) {
+ case DK4_SOCKET_RESULT_SUCCESS: {
+ if (0 == wrb) {
+ cc = 0;
+ }
+ } break;
+ default: {
+ cc = -1;
+ } break;
+ }
+ } else {
+ cc = -1;
+ back = 0;
+ }
+ } while (1 == cc);
+ }
+ }
+ }
+ dk4socket_close(sock, NULL);
+ dk4time_get(&t3);
+ } else { $? "! connection failed"
+ /* ERROR: Failed to connect */
+ log_1_no_header(140);
+ }
+ } else { $? "! host name or port number invalid"
+ }
+ $? "- data_transfer %d", back
+ return back;
+}
+
+
+
+/** Write one line of final statistics.
+ @param b Text containing a number.
+ @param max Maximum number width.
+ @param i1 Index in pjsnmp_kw of text before number.
+ @param i2 Index in pjsnmp_kw of text after number.
+*/
+static
+void
+final_stat_line(const char *b, size_t max, size_t i1, size_t i2)
+{
+ size_t sl; /* String length of number */
+
+ sl = strlen(b);
+ fputs(pjsnmp_kw[i1], out_file);
+ while (sl++ < max) { fputc(' ', out_file); }
+ fputs(b, out_file);
+ fputs(pjsnmp_kw[i2], out_file);
+}
+
+
+
+/** Issue final statistics.
+*/
+static
+void
+final_statistics(void)
+{
+ char b1[64]; /* Number of bytes */
+ char b2[64]; /* Transfer time */
+ char b3[64]; /* Processing time */
+ char b4[64]; /* Number of pages */
+ size_t max; /* Maximum of all sizes */
+ size_t sl; /* Current size */
+ int res; /* Conversion result */
+ int found = 0; /* Information found */
+
+ /* Initialize buffers.
+ */
+ b1[0] = '\0'; b2[0] = '\0'; b3[0] = '\0'; b4[0] = '\0';
+
+ /* Convert numbers to strings.
+ */
+ if (DK4_E_NONE == er_bytes.ec) {
+ res = dk4ma_write_c8_decimal_unsigned(
+ b1, sizeof(b1), (dk4_um_t)bytes_trans, 0, NULL
+ );
+ if (0 == res) { b1[0] = '\0'; }
+ else { found |= 1; }
+ }
+ if (((dk4_time_t)0UL != t2) && ((dk4_time_t)0UL != t3)) {
+ res = dk4ma_write_c8_decimal_unsigned(
+ b2, sizeof(b2), (dk4_um_t)(t3 - t2), 0, NULL
+ );
+ if (0 == res) { b2[0] = '\0'; }
+ else { found |= 2; }
+ }
+ res = dk4ma_write_c8_decimal_unsigned(
+ b3, sizeof(b3), (dk4_um_t)(t4 - t1), 0, NULL
+ );
+ if (0 == res) { b3[0] = '\0'; }
+ else { found |= 4; }
+ if ((0 != have_pcs) && (0 != have_pce)) {
+ res = dk4ma_write_c8_decimal_unsigned(
+ b4, sizeof(b4), (dk4_um_t)(pc_end - pc_start), 0, NULL
+ );
+ if (0 == res) { b4[0] = '\0'; }
+ else { found |= 8; }
+ }
+
+ /* Find maximum string length.
+ */
+ max = 0;
+ if (0 != (1 & found)) {
+ max = sl = strlen(b1);
+ }
+ if (0 != (2 & found)) {
+ sl = strlen(b2);
+ if (sl > max) max = sl;
+ }
+ if (0 != (4 & found)) {
+ sl = strlen(b3);
+ if (sl > max) max = sl;
+ }
+ if (0 != (8 & found)) {
+ sl = strlen(b4);
+ if (sl > max) max = sl;
+ }
+
+ /* Write texts.
+ */
+ fputs(pjsnmp_kw[55], out_file);
+ (void)log_timestamp();
+ if (0 != (1 & found)) {
+ final_stat_line(b1, max, 56, 60);
+ }
+ if (0 != (2 & found)) {
+ final_stat_line(b2, max, 57, 61);
+ }
+ if (0 != (4 & found)) {
+ final_stat_line(b3, max, 58, 61);
+ }
+ if (0 != (8 & found)) {
+ final_stat_line(b4, max, 59, 0);
+ }
+ if (0 != found) {
+ fflush(out_file);
+ }
+}
+
+
+
+/** Initialization at startup.
+*/
+static
+void
+initialize_at_startup(void)
+{
+ stat_text[0] = '\0'; sz_stat_text = 0;
+ ostat_text[0] = '\0'; sz_ostat_text = 0;
+ dk4error_init(&er_bytes);
+}
+
+
+
+static
+void
+report_at_job_start(int argc, char *argv[])
+{
+ int found = 0;
+ char *ptr;
+ if (0 != verbose) {
+ int i;
+ fputs(pjsnmp_kw[169], out_file);
+ for (i = 1; i < argc; i++) {
+ fputs(argv[i], out_file);
+ fputc('\n', out_file);
+ }
+ fflush(out_file);
+ } else {
+ if (NULL != user_name) {
+ fputs(user_name, out_file);
+ found = 1;
+ }
+ if (NULL != queue_name) {
+ if (0 != found) { fputc(' ', out_file); }
+ fputs(queue_name, out_file);
+ found = 1;
+ }
+ if (NULL != job_name) {
+ if (0 != found) { fputc(' ', out_file); }
+ fputs(job_name, out_file);
+ found = 1;
+ }
+ if (0 != found) { fputc('\n', out_file); }
+ if (NULL != job_title) {
+ ptr = job_title;
+ while ('\0' != *ptr) {
+ if (0x80 > ((unsigned char)(*ptr))) {
+ fputc(*ptr, out_file);
+ } else {
+ fputc('?', out_file);
+ }
+ ptr++;
+ }
+ fputc('\n', out_file);
+ found = 1;
+ }
+ if (0 != found) {
+ fflush(out_file);
+ }
+ }
+}
+
+
+
+
+#endif
+/* if DK4_HAVE_LIBNETSNMP && ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET)) */
+
+
+
+/** Main program.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return Exit status code, one from LPRNG_EXIT_xxx.
+*/
+int
+main(int argc, char *argv[])
+{
+#if DK4_HAVE_LIBNETSNMP && ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET))
+
+ /* +++++ All libraries available */
+
+#if DK4_HAVE_SIGACTION
+#ifdef SIGPIPE
+ struct sigaction opipe; /* Old disposition for SIGPIPE */
+ struct sigaction npipe; /* New disposition for SIGPIPE */
+#endif
+ struct sigaction oint; /* Old disposition for SIGINT */
+ struct sigaction nint; /* New disposition for SIGINT */
+ struct sigaction oterm; /* Old disposition for SIGTERM */
+ struct sigaction nterm; /* New disposition for SIGTERM */
+#else
+#ifdef SIGPIPE
+ dk4_sig_handler_t *opipe = NULL; /* Old disposition for SIGPIPE */
+#endif
+ dk4_sig_handler_t *oterm = NULL; /* Old disposition for SIGTERM */
+ dk4_sig_handler_t *oint = NULL; /* Old disposition for SIGINT */
+#endif
+
+#if DK4_HAVE_SIGACTION
+#ifdef SIGPIPE
+ int set_pipe = 0; /* Flag: Disposition SIGPIPE changed */
+#endif
+ int set_int = 0; /* Flag: Disposition SIGINT changed */
+ int set_term = 0; /* Flag: Disposition SIGTERM changed */
+ int sig_i_f = 0; /* Flag: Handler installation failed */
+ int sig_r_f = 0; /* Flag: Handler restoration failed */
+#endif
+ int sockinit = 0; /* Flag: Socket subsys initialized */
+
+ $!trace-init /tmp/pjsnmp.deb
+ $? "+ main"
+
+ /* Initialize output file.
+ */
+ out_file = stderr;
+ dk4time_get(&t1);
+
+ /* Copy default OID for status text.
+ */
+ DK4_MEMCPY(oid_st, oid_dst, by_oid_dst);
+ sz_oid_st = sz_oid_dst;
+ by_oid_st = sz_oid_st * sizeof(oid);
+
+ /* Process command line arguments, open log file.
+ */
+ if (0 == process_command_line_arguments(argc, argv)) { goto finished; }
+
+ /* Set up signal handlers.
+ */
+#if DK4_HAVE_SIGACTION
+#ifdef SIGPIPE
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) { sig_i_f = 1; goto finished; }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) { sig_i_f = 1; goto finished; }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) { sig_i_f = 1; goto finished; }
+ set_pipe = 1;
+#endif
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) { sig_i_f = 1; goto finished; }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) { sig_i_f = 1; goto finished; }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) { sig_i_f = 1; goto finished; }
+ set_term = 1;
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) { sig_i_f = 1; goto finished; }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) { sig_i_f = 1; goto finished; }
+ if (0 != sigaction(SIGINT, &nint, &oint)) { sig_i_f = 1; goto finished; }
+ set_int = 1;
+#else
+#ifdef SIGPIPE
+ opipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oint = sigset(SIGINT, sig_handler_int);
+ oterm = sigset(SIGTERM, sig_handler_term);
+#endif
+
+ /* Process remaining setup (PRINTCAP_ENTRY, model file).
+ */
+ if (0 == process_setup()) { goto finished; }
+
+ /* Header files for job in log output.
+ */
+ report_at_job_start(argc, argv);
+
+ /* Initialize socket subsystem.
+ */
+ if (DK4_SOCKET_RESULT_SUCCESS != dk4socket_up(NULL)) {
+ log_1_no_header(170);
+ goto finished;
+ }
+ sockinit = 1;
+
+ /* Check users permission to print.
+ */
+ if (0 == check_permission()) { goto finished; }
+
+ /* Establish SNMP session.
+ */
+ if (0 == attempt_snmp_session()) { goto finished; }
+
+ /* Initialization.
+ */
+ initialize_at_startup();
+
+ /* Accounting before job.
+ */
+ if (0 == do_accounting(0)) { goto finished; }
+
+ /* Data transfer.
+ */
+ if (0 == data_transfer()) { goto finished; }
+
+ /* Accounting after job.
+ */
+ if (0 == do_accounting(1)) { goto finished; }
+
+ /* Cleanup
+ -------
+ */
+ finished:
+
+ /* Clean up SNMP session.
+ */
+ if (NULL != snmp_sess) { snmp_close(snmp_sess); }
+
+ /* Eat up data from standard input.
+ */
+ eatup_input();
+
+ /* release socket subsystem.
+ */
+ if (0 != sockinit) { (void)dk4socket_down(NULL); }
+
+ /* Release status text nodes, if any.
+ */
+ relase_status_text_nodes();
+
+ /* Release dynamically allocated printcap entry copy.
+ */
+ dk4mem_release(printcap_entry);
+
+ /* Restore signal handlers
+ */
+#if DK4_HAVE_SIGACTION
+ if (0 != sig_i_f) {
+ /* ERROR: Failed to set up signal handlers */
+ log_1_no_header(141);
+ }
+ if (0 != set_int) {
+ if (0 != sigaction(SIGINT, &oint, NULL)) { sig_r_f = 1; }
+ }
+ if (0 != set_term) {
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) { sig_r_f = 1; }
+ }
+#ifdef SIGPIPE
+ if (0 != set_pipe) {
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) { sig_r_f = 1; }
+ }
+#endif
+ if (0 != sig_r_f) {
+ /* ERROR: Failed to restore signal handlers */
+ log_1_no_header(142);
+ }
+#else
+ if (NULL != oterm) { sigset(SIGTERM, oterm); }
+ if (NULL != oint ) { sigset(SIGINT, oint ); }
+#ifdef SIGPIPE
+ if (NULL != opipe) { sigset(SIGPIPE, opipe); }
+#endif
+#endif
+
+ /* Final log message, close log file
+ */
+ dk4time_get(&t4);
+ if (2 > decision) { final_statistics(); }
+ if (NULL != stt_file) { fclose(stt_file); }
+ out_file = stderr;
+
+ $? "- main %d", exval
+ $!trace-end
+
+ /* ----- All libraries available */
+
+#else
+/* if DK4_HAVE_LIBNETSNMP && ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET)) */
+ /* +++++ Missing libraries */
+#if !DK4_HAVE_LIBNETSNMP
+ fputs("ERROR: Missing Net-SNMP support!\n", stderr);
+#endif
+#if !((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET))
+ fputs("ERROR: Missing sigaction()/sigset() support!\n", stderr);
+#endif
+ fflush(stderr);
+ /* ----- Missing libraries */
+#endif
+/* if DK4_HAVE_LIBNETSNMP && ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET)) */
+ exit(exval); return exval;
+}
+
+
+/*
+
+2016-02-26 Added dk4socket_up() and dk4socket_down().
+
+*/
diff --git a/support/dktools/pjsnmp.h b/support/dktools/pjsnmp.h
new file mode 100644
index 0000000000..79300545ee
--- /dev/null
+++ b/support/dktools/pjsnmp.h
@@ -0,0 +1,246 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: pjsnmp.ctr
+*/
+
+/*
+Copyright (C) 2012-2016, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file pjsnmp.h Header file for the pjsnmp module.
+*/
+
+#ifndef PJSNMP_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define PJSNMP_H_INCLUDED 1
+
+
+#line 10 "pjsnmp.ctr"
+
+#include "dk3conf.h"
+#include "dk3types.h"
+
+#if DK3_CHAR_SIZE == 1
+#if (DK3_HAVE_SIGACTION) || (DK3_HAVE_SIGSET)
+#if DK3_HAVE_LIBNETSNMP
+
+#include "dk3all.h"
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/utilities.h>
+
+
+/** @defgroup pjsnmpexitcodes Exit codes for pjsnmp.
+*/
+/**@{*/
+/** Exit code: Success.
+*/
+#define PJSNMP_EXIT_SUCCESS 0
+
+/** Exit code: Transient error condition, retry later.
+*/
+#define PJSNMP_EXIT_FAIL 1
+
+/** Exit code: Unrecoverable error, remove job from queue.
+*/
+#define PJSNMP_EXIT_REMOVE 3
+
+/** Exit code: Hold job for later processing.
+*/
+#define PJSNMP_EXIT_HOLD 6
+
+/** Exit code: Filter disturbed by signal.
+*/
+#define PJSNMP_EXIT_SIGNAL 9
+/**@}*/
+
+
+
+/** @defgroup pjsnmpdevicestatus Device status from SNMP.
+*/
+/**@{*/
+/** Device status: Unknown.
+*/
+#define PJSNMP_DEVICE_UNKNOWN 1
+
+/** Device status: Device is running.
+*/
+#define PJSNMP_DEVICE_RUNNING 2
+
+/** Device status: Warning like paper or toner low.
+*/
+#define PJSNMP_DEVICE_WARNING 3
+
+/** Device status: In self-test.
+*/
+#define PJSNMP_DEVICE_TESTING 4
+
+/** Device status: Down due to error condition, i.e. paper jam.
+*/
+#define PJSNMP_DEVICE_DOWN 5
+/**@}*/
+
+
+
+/** @defgroup pjsnmpprinterstatus Printer status from SNMP.
+*/
+/**@{*/
+/** Printer status: Any state not mentioned below.
+*/
+#define PJSNMP_PRINTER_OTHER 1
+
+/** Printer status: Unknown.
+*/
+#define PJSNMP_PRINTER_UNKNOWN 2
+
+/** Printer status: Ready, waiting for next job.
+*/
+#define PJSNMP_PRINTER_IDLE 3
+
+/** Printer status: Printing a job.
+*/
+#define PJSNMP_PRINTER_PRINTING 4
+
+/** Printer status: Warming up.
+*/
+#define PJSNMP_PRINTER_WARMUP 5
+/**@}*/
+
+
+
+/** @defgroup pjsnmpprintersummary Printer state summary.
+*/
+/**@{*/
+/** State summary: Printer unreachable, probably turned off.
+*/
+#define PJSNMP_STATE_UNREACHABLE 1
+
+/** State summary: Failed to create SNMP request!
+*/
+#define PJSNMP_STATE_REQUEST_FAILED 2
+
+/** State summary: Error in SNMP response!
+*/
+#define PJSNMP_STATE_ERROR_IN_RESPONSE 3
+
+/** State summary: Printer ready, can use pagecounter.
+*/
+#define PJSNMP_STATE_READY 4
+
+/** State summary: Waiting for printer to start printing.
+*/
+#define PJSNMP_STATE_WAIT_START 5
+
+/** State summary: Printer warming up.
+*/
+#define PJSNMP_STATE_WARMUP 6
+
+/** State summary: Printing.
+*/
+#define PJSNMP_STATE_PRINTING 7
+
+/** State summary: Printing interrupted due to error.
+*/
+#define PJSNMP_STATE_ERROR 8
+
+/** State summary: Printer unreachable, probably turned off.
+*/
+#define PJSNMP_STATE_OTHER 9
+/**@}*/
+
+
+/** Ensure value to be in range.
+*/
+#define PJSNMP_IN_RANGE(a,b,c) (((c) >= (a)) ? (c) : (((c) <= (b)) ? (c) : (a)))
+
+
+
+/** Printer state.
+*/
+typedef struct {
+ unsigned long pc; /**< Pagecounter value. */
+ unsigned long ec; /**< Error conditions. */
+ int ds; /**< Device state, see @ref pjsnmpdevicestatus. */
+ int ps; /**< Printer state, see @ref pjsnmpprinterstatus. */
+ int st; /**< State summary, see @ref pjsnmpprintersummary. */
+} pjsnmp_printer_state_t;
+
+
+
+/** Job structure.
+*/
+typedef struct {
+ struct snmp_session st; /**< Session template. */
+ pjsnmp_printer_state_t os; /**< Old SNMP state. */
+ pjsnmp_printer_state_t cs; /**< Current SNMP state. */
+ struct snmp_session *ss; /**< SNMP session. */
+ char const *un; /**< User name. */
+ char const *qn; /**< Printer name. */
+ char const *jn; /**< Job name. */
+ char const *jt; /**< Job title. */
+ char const *sf; /**< Status file. */
+ dk3_app_t *app; /**< Application structure. */
+ dkChar const * const *lm; /**< Localized message texts. */
+ char *hn; /**< Host name to transfer data to. */
+ char *af; /**< Accounting file/socket name. */
+ char *sc; /**< SNMP community. */
+ char *tf; /**< Temporary file. */
+ char *sl; /**< SNMP log file. */
+ int *addst; /**< Additional state combinations. */
+ size_t szadd; /**< Number of elements in addst. */
+ size_t usadd; /**< Used elements in addst. */
+ time_t ti; /**< Start time of stage 2. */
+ time_t tl; /**< Time of last log. */
+ unsigned long pc; /**< Page count at start of job. */
+ int ex; /**< Exit status code. */
+ int ac; /**< Flag: achk accounting check. */
+ int as; /**< Accounting style: 0=printqd, 1=lprng. */
+ int sv; /**< SNMP version. */
+ int od; /**< Flag: Orderly release printer socket. */
+ int fe; /**< Flag: ERROR or signal, job cancelled. */
+ int ct; /**< Flag: SNMP check during data transfer. */
+ int is; /**< Flag: Ignore SNMP failure. */
+ int wp; /**< Flag: Printer was seen printing. */
+ int hl; /**< Flag: Already have log messages. */
+ int pdes; /**< Flag: Use hrPrinterDetectedErrorState. */
+ int poid; /**< Flag: running/warning+other = standby. */
+ int repr; /**< Flag: Report response. */
+ int rqpr; /**< Flag: Require printing state. */
+ unsigned short pn; /**< Port name to transfer data to. */
+} pjsnmp_job_t;
+
+
+#endif
+#endif
+#endif
+
+
+
+
+#endif
diff --git a/support/dktools/pkginfo b/support/dktools/pkginfo
new file mode 100644
index 0000000000..715b79086b
--- /dev/null
+++ b/support/dktools/pkginfo
@@ -0,0 +1,9 @@
+PKG="DKRAdktools"
+NAME="dktools"
+ARCH="sparc"
+VERSION="4.8.3"
+CATEGORY="application"
+VENDOR="Dirk Krause"
+EMAIL="dirk.krause@no.e-mail.address.provided.com"
+PSTAMP="Dirk Krause"
+CLASSES="none"
diff --git a/support/dktools/pkginfo.in b/support/dktools/pkginfo.in
new file mode 100644
index 0000000000..a5ee3f95aa
--- /dev/null
+++ b/support/dktools/pkginfo.in
@@ -0,0 +1,9 @@
+PKG="DKRAdktools"
+NAME="dktools"
+ARCH="sparc"
+VERSION="@VERSNO@"
+CATEGORY="application"
+VENDOR="Dirk Krause"
+EMAIL="dirk.krause@no.e-mail.address.provided.com"
+PSTAMP="Dirk Krause"
+CLASSES="none"
diff --git a/support/dktools/plpdftex.c b/support/dktools/plpdftex.c
new file mode 100644
index 0000000000..8bfd05f837
--- /dev/null
+++ b/support/dktools/plpdftex.c
@@ -0,0 +1,3175 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: plpdftex.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file plpdftex.c The plpdftex module.
+*/
+
+
+#line 95 "plpdftex.ctr"
+
+#include "dk3all.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4vers.h"
+#include "dkt.h"
+#include "dk3pdf.h"
+#include "plpdftex.h"
+
+#include <stdio.h>
+
+
+
+
+
+#line 110 "plpdftex.ctr"
+
+
+
+/** Option to check for the presence of the program.
+*/
+static dkChar const plpdftex_check_presence[] = { dkT("--check-presence") };
+
+/** Protocol version to issue as response to a presence check.
+*/
+#if VERSION_BEFORE_20140924
+static dkChar const plpdftex_protocol[] = { dkT("1\n") };
+#else
+static char const plpdftex_protocol[] = { "1\n" };
+#endif
+
+/** Application group name.
+*/
+static dkChar const plpdftex_group_name[] = { dkT("dktools") };
+
+/** DK tools version number.
+*/
+static dkChar const plpdftex_version[] = { DKT_VERSION_DK };
+
+
+
+/** Default help text shown if help file is not found.
+*/
+static dkChar const * const plpdftex_text_help[] = {
+dkT(""),
+dkT("NAME"),
+dkT(""),
+dkT(" plpdftex - Plot into a combination of *.pdf/*.tex files."),
+dkT(""),
+dkT("SYNOPSIS"),
+dkT(""),
+dkT(" plpdftex"),
+dkT(" plpdftex --check-presence"),
+dkT(" plpdftex --help"),
+dkT(" plpdftex --license-terms"),
+dkT(""),
+dkT("DESCRIPTION"),
+dkT(""),
+dkT("The program processes an incoming data stream containing both graphics"),
+dkT("instructions and text labels. Graphics instructions are written to a"),
+dkT("PDF file, text labels are written to a *.tex file."),
+dkT("The *.tex file includes the PDF file containing the graphics and"),
+dkT("typesets the text labels on top of it."),
+dkT(""),
+dkT("This program is not intended to be used directly, it is an output"),
+dkT("driver for the octpgfpl package for GNU Octave."),
+dkT(""),
+dkT(""),
+dkT("OPTIONS"),
+dkT(""),
+dkT("-h\t\t\tShow this help text."),
+dkT("--help"),
+dkT(""),
+dkT("-v\t\t\tShow version information."),
+dkT("--version"),
+dkT(""),
+dkT("-l\t\t\tShow the license conditions."),
+dkT("--license-terms"),
+dkT(""),
+dkT("--check-presence\tPrint the protocol version, may be used to"),
+dkT("\t\t\tcheck for the presence of the program."),
+dkT(""),
+dkT("EXIT STATUS"),
+dkT(""),
+dkT("0 on success, all other exit status codes indicate an error."),
+dkT(""),
+dkT("INPUT FILE"),
+dkT(""),
+dkT("Input is read from standard input."),
+dkT(""),
+dkT("The first line specifies a file name combination. It must end on"),
+dkT("either ``.pdftex'' to produce a *.pdf/*.tex combination for inclusion"),
+dkT("in a LaTeX document or on ``.pdftexs'' to produce a *.pdf/*.tex"),
+dkT("combination for standalone processing."),
+dkT(""),
+dkT("The second line contains two unsigned integer numbers, separated"),
+dkT("by spaces: Image width and height in PS/PDF points (known as bp in"),
+dkT("LaTeX)."),
+dkT(""),
+dkT("The remaining lines describe the image, there are ``t'' lines"),
+dkT("and ``p'' lines, i.e."),
+dkT(""),
+dkT("t\tfs\t\t12"),
+dkT("t\tfont-setup\t\\usepackage[T1]{fontenc}"),
+dkT("t\tpackage\t\t\\usepackage[intlimit]{amsmath}"),
+dkT("t\tpreamble\t\\DeclareMathOperator{\\intd}{\\text{d}}"),
+dkT("t\ttext\t\t10 20 base left\tblack This is a test."),
+dkT("t\ttext-box\t10 20 base left red This is another test."),
+dkT("p\tgsave"),
+dkT("p\tgrestore"),
+dkT("p\tlw\t\t3"),
+dkT("p\tbuttcap"),
+dkT("p\tmiterjoin"),
+dkT("p\tnodash"),
+dkT("p\tstroke-color\tblue!50!black"),
+dkT("p\tfill-color\tred!80!white"),
+dkT("p\trectangle\t5 5 200 80"),
+dkT("p\tcircle\t\t20 30 5"),
+dkT("p\tmoveto\t\t30 80"),
+dkT("p\tlineto\t\t50 90"),
+dkT("p\tcurveto\t\t50 100 100 100 100 90"),
+dkT("p\tclosepath"),
+dkT("p\tstroke"),
+dkT("p\tfill"),
+dkT("p\tclip"),
+dkT(""),
+dkT("The ``t fs'' ``t font-setup'', ``t package'' and ``t preamble''"),
+dkT("lines are only used when producing a *.pdf/*.tex file combination for"),
+dkT("standalone processing, otherwise they are ignored."),
+dkT(""),
+dkT("``t fs'' specifies the font size for the documentclass line."),
+dkT("This line must be used before ``t font-setup'', ``t package'', ``t preamble'',"),
+dkT("``t text'' or ``p'' lines. The line is optional, by default the documentclass"),
+dkT("is written without the font size specification."),
+dkT(""),
+dkT("``t font-setup'' specifies usepackage and other instructions for font"),
+dkT("setup. These lines are optional, a default font setup section is used"),
+dkT("if no ``t font-setup'' lines are used. Any ``t font-setup'' lines"),
+dkT("must be used before ``t package'', ``t preamble'', ``t text'' or ``p''"),
+dkT("lines."),
+dkT(""),
+dkT("``t preamble'' lines contain further setup instructions for the preamble,"),
+dkT("they are optional."),
+dkT(""),
+dkT("``t text'' lines contain text labels to show. The line contains"),
+dkT("x position, y position, vertical alignment (bottom, base, centered,"),
+dkT("or top), horizontal alignment (left, centered, or right), color"),
+dkT("and the text to show."),
+dkT(""),
+dkT("All color definitions must be LaTeX color strings like"),
+dkT("``blue!50!white''..."),
+dkT(""),
+dkT("``t text-box'' lines contain text labels to show. The line contains"),
+dkT("x position, y position, vertical alignment (bottom, base, centered,"),
+dkT("or top), horizontal alignment (left, centered, or right), color"),
+dkT("and the text to show."),
+dkT(""),
+dkT("``p'' lines contain graphics instructions transferred to the PDF file."),
+dkT(""),
+dkT("``p gsave'' saves the current graphics state."),
+dkT(""),
+dkT("``p grestore'' restores the graphics state."),
+dkT(""),
+dkT("``p lw'' sets the line width for stroking."),
+dkT(""),
+dkT("``p buttcap'' sets line cap style to butted."),
+dkT(""),
+dkT("``p miterjoin'' sets the line join style to miter."),
+dkT(""),
+dkT("``p nodash'' sets up contiguous line style."),
+dkT(""),
+dkT("``p stroke-color'' sets the stroke color."),
+dkT(""),
+dkT("``p fill-color'' sets the fill color."),
+dkT(""),
+dkT("``p rectangle'' creates a rectangular path, specify start x position,"),
+dkT("start y position, end x position and end y position."),
+dkT(""),
+dkT("``p circle'' creates a circular path, specify center x position,"),
+dkT("center y position and radius."),
+dkT(""),
+dkT("``p moveto'' starts a new path and moves the current position"),
+dkT("to the specified x and y position."),
+dkT(""),
+dkT("``p lineto'' adds a line segment from the current position to the specified"),
+dkT("x and y position to the path."),
+dkT(""),
+dkT("``p curveto'' adds a Bezier segment starting at the current position"),
+dkT("to the path. Specify x and y position of the first control point,"),
+dkT("x and y position of the second control point and x and y position"),
+dkT("of the final point."),
+dkT(""),
+dkT("``p closepath'' closes the current path."),
+dkT(""),
+dkT("``p stroke'' strokes the current path."),
+dkT(""),
+dkT("``p fill'' fills the current path."),
+dkT(""),
+dkT("``p clip'' uses the current path as clip path."),
+dkT(""),
+dkT(""),
+dkT("OUTPUT FILES"),
+dkT(""),
+dkT("The output file names are determined from the first input line."),
+dkT(""),
+dkT("NOTES"),
+dkT(""),
+dkT("The plpdftex program does not support all features of PDF/TeX file pairs,"),
+dkT("it is only intended as an output driver for the pgfplot() instruction"),
+dkT("in the octpgfpl package for GNU Octave."),
+dkT(""),
+dkT("RESTRICTIONS"),
+dkT(""),
+dkT("Color definitions for plpdftex must only contain color names ``white'',"),
+dkT("``black'', ``red'', ``green'', ``blue'', ``cyan'', ``magenta'', ``yellow'',"),
+dkT("``gray'', ``lightgray'', ``darkgray'', ``brown'', ``lime'', ``olive'',"),
+dkT("``orange'', ``pink'', ``purple'', ``teal'', ``violet'' and combinations"),
+dkT("like ``red!50!black''."),
+dkT(""),
+dkT("AUTHOR"),
+dkT(""),
+dkT("Dirk Krause"),
+dkT(""),
+dkT("COPYRIGHT AND LICENSE"),
+dkT(""),
+dkT("Run"),
+dkT(" plpdftex -l"),
+dkT("to see the license conditions."),
+dkT(""),
+dkT("SEE ALSO"),
+dkT(""),
+dkT("http://dktools.sourceforge.net"),
+dkT("http://octpgfpl.sourceforge.net"),
+dkT(""),
+NULL
+
+
+#line 330 "plpdftex.ctr"
+};
+
+
+
+/** License conditions.
+*/
+static dkChar const * const plpdftex_license_text[] = {
+dkT(""),
+dkT("Copyright (c) 2014-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above copyright notice,"),
+dkT(" this list of conditions and the following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("* Neither the name of the copyright holder(s) nor the names of"),
+dkT(" contributors may be used to endorse or promote products derived from "),
+dkT(" this software without specific prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS"),
+dkT("\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT"),
+dkT("LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR"),
+dkT("A PARTICULAR PURPOSE ARE DISCLAIMED."),
+dkT(""),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS"),
+dkT("OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)"),
+dkT("HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,"),
+dkT("STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING"),
+dkT("IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE"),
+dkT("POSSIBILITY OF SUCH DAMAGE."),
+dkT(""),
+NULL
+
+
+#line 369 "plpdftex.ctr"
+};
+
+
+static dkChar const * const plpdftex_kw[] = {
+/* 0 */
+dkT("plpdftex"),
+
+/* 1 */
+dkT("Too many command line arguments, just one input file name allowed!"),
+
+/* 2 */
+dkT("Failed to retrieve first command line argument (probably a bug)!"),
+
+/* 3 */
+dkT("Output file names missing in first line!"),
+
+/* 4 */
+dkT("File name too long in first line!"),
+
+/* 5 */
+dkT("Wrong file name suffix, must be *.pdftex or *.pdftexs!"),
+
+/* 6 */
+dkT("Missing second line, containing width and height!"),
+
+/* 7 */
+dkT("Failed to retrieve width and height!"),
+
+/* 8 */
+dkT("Numeric overflow, width and/or height too large!"),
+
+/* 9 */
+dkT("Failed to write PDF data to file!"),
+
+/* 10 */
+dkT("Failed to open PDF page!"),
+
+/* 11 */
+dkT("Failed to close PDF page!"),
+
+/* 12 */
+dkT("Syntax error, document already closed!"),
+
+/* 13 */
+dkT("Syntax error, line not started by ``t'', ``p'', or ``#''!"),
+
+/* 14 */
+dkT("Syntax error, missing command!"),
+
+/* 15 */
+dkT("PDF clip operation failed!"),
+
+/* 16 */
+dkT("PDF fill operation failed!"),
+
+/* 17 */
+dkT("PDF stroke operation failed!"),
+
+/* 18 */
+dkT("PDF closepath operation failed!"),
+
+/* 19 */
+dkT("PDF curveto operation failed!"),
+
+/* 20 */
+dkT("Syntax error, numeric value expected!"),
+
+/* 21 */
+dkT("Syntax error, too few arguments for command!"),
+
+/* 22 */
+dkT("PDF moveto operation failed!"),
+
+/* 23 */
+dkT("Syntax error, radius is negative!"),
+
+/* 24 */
+dkT("PDF lineto operation failed!"),
+
+/* 25 */
+dkT("PDF set nonstroking color operation failed!"),
+
+/* 26 */
+dkT("No such color!"),
+
+/* 27 */
+dkT("PDF set stroking color operation failed!"),
+
+/* 28 */
+dkT("PDF set dash operation failed!"),
+
+/* 29 */
+dkT("PDF set linejoin operation failed!"),
+
+/* 30 */
+dkT("PDF set linecap operation failed!"),
+
+/* 31 */
+dkT("Syntax error, linewidth negative!"),
+
+/* 32 */
+dkT("PDF set linewidth operation failed!"),
+
+/* 33 */
+dkT("PDF grestore operation failed!"),
+
+/* 34 */
+dkT("PDF gsave operation failed!"),
+
+/* 35 */
+dkT("Write operation failed to TeX output file!"),
+
+/* 36 */
+dkT("Syntax error, invalid horizontal alignment specification!"),
+
+/* 37 */
+dkT("Syntax error, invalid horizontal alignment specification!"),
+
+/* 38 */
+dkT("Syntax error, order must be fs, font-setup, package, preamble, text!"),
+
+NULL
+
+
+#line 531 "plpdftex.ctr"
+};
+
+
+
+/** 8 bit strings
+*/
+static char const * const plpdftex_c8_kw[] = {
+/* 0 */
+"-i.pdf",
+
+/* 1 */
+".tex",
+
+/* 2 */
+"\\documentclass{article}",
+
+/* 3 */
+"% font setup (begin)",
+
+/* 4 */
+"% font setup (end)",
+
+/* 5 */
+"% other packages (begin)",
+
+/* 6 */
+"% other packages (end)",
+
+/* 7 */
+"\\setlength{\\paperwidth}{%ldbp}\n",
+
+/* 8 */
+"\\setlength{\\paperheight}{%ldbp}\n",
+
+/* 9 */
+"% user-specific setup instructions (begin)",
+
+/* 10 */
+"% user-specific setup instructions (end)",
+
+/* 11 */
+"\\begin{document}%",
+
+/* 12 */
+"\\begin{picture}(0,0)%",
+
+/* 13 */
+"\\includegraphics{",
+
+/* 14 */
+"}%",
+
+/* 15 */
+"\\end{picture}%",
+
+/* 16 */
+"\\setlength{\\unitlength}{1bp}%",
+
+/* 17 */
+"\\begin{picture}(%ld,%ld)%\n",
+
+/* 18 */
+"\\end{document}",
+
+/* 19 */
+"\\put(%g,%g){\\makebox(0,0)",
+
+/* 20 */
+"[",
+
+/* 21 */
+"]",
+
+/* 22 */
+"{\\smash{{\\color{%s}%s}}}}\n",
+
+/* 23 */
+"{\\colorbox{white}{\\color{%s}\\ovalbox{%s}}}}\n",
+
+/* 24 */
+"{{\\color{%s}%s}}}\n",
+
+NULL
+
+
+#line 601 "plpdftex.ctr"
+};
+
+
+
+/** Default font setup.
+*/
+static char const * const plpdftex_default_font_setup[] = {
+/* 0 */
+"% begin font setup",
+
+/* 1 */
+"\\usepackage[T1]{fontenc}",
+
+/* 2 */
+"\\usepackage{textcomp}",
+
+/* 3 */
+"\\usepackage{mathptmx}",
+
+/* 4 */
+"\\usepackage[scaled=.92]{helvet}",
+
+/* 5 */
+"\\usepackage{courier}",
+
+/* 6 */
+"% end font setup",
+
+NULL
+
+
+#line 617 "plpdftex.ctr"
+};
+
+
+
+/** Default additional packages.
+*/
+static char const * const plpdftex_default_packages[] = {
+/* 0 */
+"% other packages (begin)",
+
+/* 1 */
+"\\usepackage{textcomp}",
+
+/* 2 */
+"\\usepackage[intlimits]{amsmath}",
+
+/* 3 */
+"% other packages (end)",
+
+NULL
+
+
+#line 630 "plpdftex.ctr"
+};
+
+
+
+static char const * const plpdftex_required_packages[] = {
+/* 0 */
+"% required packages (begin)",
+
+/* 1 */
+"\\usepackage{fancybox}",
+
+/* 2 */
+"\\usepackage{graphicx}",
+
+/* 3 */
+"\\usepackage{xcolor}",
+
+/* 4 */
+"% required packages (end)",
+
+/* 5 */
+"% required instructions (begin)",
+
+NULL
+
+
+#line 643 "plpdftex.ctr"
+};
+
+
+
+
+static char const * const plpdftex_required_instructions[] = {
+/* 0 */
+"\\pagestyle{empty}",
+
+/* 1 */
+"\\setlength{\\voffset}{-1in}",
+
+/* 2 */
+"\\setlength{\\topmargin}{0bp}",
+
+/* 3 */
+"\\setlength{\\headheight}{0bp}",
+
+/* 4 */
+"\\setlength{\\headsep}{0bp}",
+
+/* 5 */
+"\\setlength{\\topskip}{0bp}",
+
+/* 6 */
+"\\setlength{\\hoffset}{-1in}",
+
+/* 7 */
+"\\setlength{\\oddsidemargin}{0bp}",
+
+/* 8 */
+"\\setlength{\\evensidemargin}{0bp}",
+
+/* 9 */
+"\\setlength{\\marginparwidth}{0bp}",
+
+/* 10 */
+"\\setlength{\\marginparsep}{0bp}",
+
+/* 11 */
+"\\setlength{\\textwidth}{\\paperwidth}",
+
+/* 12 */
+"\\setlength{\\textheight}{\\paperheight}",
+
+/* 13 */
+"\\setlength{\\parskip}{0bp}",
+
+/* 14 */
+"\\setlength{\\parindent}{0bp}",
+
+/* 15 */
+"\\setlength{\\pdfpagewidth}{\\paperwidth}",
+
+/* 16 */
+"\\setlength{\\pdfpageheight}{\\paperheight}",
+
+/* 17 */
+"% required instructions (end)",
+
+NULL
+
+
+#line 669 "plpdftex.ctr"
+};
+
+
+
+/** Output file suffixes.
+*/
+static char const * const pldftex_output_file_suffixes[] = {
+/* 0 */
+"pdftex",
+
+/* 1 */
+"pdftexs",
+
+NULL
+
+
+#line 680 "plpdftex.ctr"
+};
+
+
+
+/** Instruction names in TeX lines.
+*/
+static char const * const plpdftex_tex_instructions[] = {
+/* 0 */
+"fs",
+
+/* 1 */
+"font-setup",
+
+/* 2 */
+"package",
+
+/* 3 */
+"preamble",
+
+/* 4 */
+"text",
+
+/* 5 */
+"text-box",
+
+NULL
+
+
+#line 713 "plpdftex.ctr"
+};
+
+
+
+/** Instruction names in PDF instructions.
+*/
+static char const * const plpdftex_pdf_instructions[] = {
+/* 0 */
+"gsave",
+
+/* 1 */
+"grestore",
+
+/* 2 */
+"lw",
+
+/* 3 */
+"buttcap",
+
+/* 4 */
+"miterjoin",
+
+/* 5 */
+"nodash",
+
+/* 6 */
+"stroke-color",
+
+/* 7 */
+"fill-color",
+
+/* 8 */
+"rectangle",
+
+/* 9 */
+"circle",
+
+/* 10 */
+"moveto",
+
+/* 11 */
+"lineto",
+
+/* 12 */
+"curveto",
+
+/* 13 */
+"closepath",
+
+/* 14 */
+"stroke",
+
+/* 15 */
+"fill",
+
+/* 16 */
+"clip",
+
+NULL
+
+
+#line 790 "plpdftex.ctr"
+};
+
+
+
+/** Vertical alignments.
+*/
+char const * const plpdftex_vertical_alignments[] = {
+"top", "centered", "base", "bottom", NULL
+};
+
+
+
+/** Horizontal alignments.
+*/
+char const * const plpdftex_horizontal_alignments[] = {
+"left", "centered", "right", NULL
+};
+
+
+
+/** Options expected by the program.
+*/
+static dk3_option_t const plpdftex_options[] = {
+ { dkT('h'), dkT("help"), 0 },
+ { dkT('v'), dkT("version"), 0 },
+ { dkT('l'), dkT("license-terms"), 0 }
+};
+
+
+
+/** Number of options in plpdftex_options array.
+*/
+static size_t const sz_plpdftex_options =
+sizeof(plpdftex_options)/sizeof(dk3_option_t);
+
+
+
+/** Initialize job structure.
+ @param jptr Job to initialize.
+*/
+static
+void
+plpdftex_job_init(plpdftex_job_t *jptr)
+{
+
+
+#line 835 "plpdftex.ctr"
+ jptr->app = NULL;
+ jptr->msg = NULL;
+ jptr->kwnl = NULL;
+ jptr->exc = 1;
+
+#line 839 "plpdftex.ctr"
+ jptr->argc = 0;
+ jptr->argv = NULL;
+ jptr->infn = NULL;
+ jptr->opt = NULL;
+ jptr->infi = NULL;
+ jptr->fnb1 = NULL;
+ jptr->fnpdf = NULL;
+ jptr->fntex = NULL;
+ jptr->opdf = NULL;
+ jptr->fopdf = NULL;
+ jptr->fotex = NULL;
+ jptr->szfn = 0;
+ jptr->ilbuf = NULL;
+ jptr->szilb = 0;
+ jptr->stagr = 0;
+ jptr->state = PLPT_STATE_NO_OUTPUT_YET;
+ jptr->sco = NULL;
+ jptr->sico = NULL;
+ jptr->imgw = 0UL;
+ jptr->imgh = 0UL;
+
+
+#line 860 "plpdftex.ctr"
+}
+
+
+
+/** Clean up job structure before exiting the program.
+ @param jptr Job structure to clean up.
+*/
+static
+void
+plpdftex_job_cleanup(plpdftex_job_t *jptr)
+{
+ plpt_named_color_t *colptr;
+
+
+#line 873 "plpdftex.ctr"
+ if (jptr->sico) {
+ dk3sto_it_reset(jptr->sico);
+ do {
+ colptr = (plpt_named_color_t *)dk3sto_it_next(jptr->sico);
+ if (colptr) {
+ plptcolor_delete(colptr);
+ }
+ } while (colptr);
+ dk3sto_it_close(jptr->sico);
+ } jptr->sico = NULL;
+ if (jptr->sco) {
+ dk3sto_close(jptr->sco);
+ } jptr->sco = NULL;
+ jptr->msg = NULL;
+ jptr->kwnl = NULL;
+ if (jptr->opt) {
+ dk3opt_close(jptr->opt);
+ }
+ jptr->opt = NULL;
+ if (jptr->app) {
+ dk3app_close(jptr->app);
+ }
+ jptr->app = NULL;
+
+
+#line 897 "plpdftex.ctr"
+}
+
+
+
+/** Process font size line.
+ @param job Job structure.
+ @param txt Text line to process.
+*/
+static
+void
+plpdftex_process_tex_fontsize(plpdftex_job_t *job, char *txt)
+{
+ double fs = 10.0;
+ int ok = 0;
+
+
+#line 912 "plpdftex.ctr"
+ if (NULL == txt) {
+ /* ERROR: No text */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+ if (0 == dk3ma_d_from_c8_string(&fs, txt, NULL)) {
+ /* ERROR: Not a number */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ goto finished;
+ }
+ if (0 == job->stagr) {
+ ok = 1;
+ goto finished;
+ }
+ switch (job->state) {
+ case PLPT_STATE_NO_OUTPUT_YET: {
+ ok = 1;
+ job->state = PLPT_STATE_DOCUMENT_CLASS;
+ fprintf(job->fotex, "\\documentclass[%gpt]{article}\n", fs);
+ } break;
+ default: {
+ /* ERROR: Too late */
+ ok = 1;
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 38);
+ goto finished;
+ } break;
+ }
+ finished:
+ if (0 == ok) {
+ job->exc = 1;
+
+#line 942 "plpdftex.ctr"
+ }
+
+#line 943 "plpdftex.ctr"
+}
+
+
+
+static
+void
+plpdftex_write_textline(plpdftex_job_t *job, char const *txt)
+{
+
+
+#line 952 "plpdftex.ctr"
+ if (EOF == fputs(txt, job->fotex)) {
+ /* Write error */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ job->exc = 1;
+
+#line 956 "plpdftex.ctr"
+ }
+ if (EOF == fputc('\n', job->fotex)) {
+ job->exc = 1;
+
+#line 959 "plpdftex.ctr"
+ }
+
+#line 960 "plpdftex.ctr"
+}
+
+
+
+/** Process font setup line.
+ @param job Job structure.
+ @param txt Text line to process.
+*/
+static
+void
+plpdftex_process_tex_font_setup(plpdftex_job_t *job, char *txt)
+{
+ int ok = 0;
+
+
+#line 974 "plpdftex.ctr"
+ if (0 == job->stagr) {
+ ok = 1;
+ goto finished;
+ }
+ if (NULL == txt) {
+ /* ERROR: Not text */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+ switch (job->state) {
+ case PLPT_STATE_NO_OUTPUT_YET: {
+ ok = 1;
+ /* documentclass{article} */
+ plpdftex_write_textline(job, plpdftex_c8_kw[2]);
+ /* font setup (begin) */
+ plpdftex_write_textline(job, plpdftex_c8_kw[3]);
+ plpdftex_write_textline(job, txt);
+ job->state = PLPT_STATE_USER_FONT_SETUP;
+ } break;
+ case PLPT_STATE_DOCUMENT_CLASS: {
+ ok = 1;
+ /* font setup (begin) */
+ plpdftex_write_textline(job, plpdftex_c8_kw[3]);
+ plpdftex_write_textline(job, txt);
+ job->state = PLPT_STATE_USER_FONT_SETUP;
+ } break;
+ case PLPT_STATE_USER_FONT_SETUP: {
+ ok = 1;
+ plpdftex_write_textline(job, txt);
+ } break;
+ default: {
+ /* ERROR: Too late */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 38);
+ }
+ }
+
+ finished:
+ if (0 == ok) {
+ job->exc = 1;
+
+#line 1013 "plpdftex.ctr"
+ }
+
+#line 1014 "plpdftex.ctr"
+}
+
+
+
+static
+void
+plpdftex_write_default_font_setup(plpdftex_job_t *job)
+{
+ char const * const *ptr;
+
+
+#line 1024 "plpdftex.ctr"
+ ptr = plpdftex_default_font_setup;
+ while (NULL != *ptr) {
+ plpdftex_write_textline(job, *(ptr++));
+ }
+
+#line 1028 "plpdftex.ctr"
+}
+
+
+
+static
+void
+plpdftex_write_default_packages(plpdftex_job_t *job)
+{
+ char const * const *ptr;
+
+
+#line 1038 "plpdftex.ctr"
+ ptr = plpdftex_default_packages;
+ while (NULL != *ptr) {
+ plpdftex_write_textline(job, *(ptr++));
+ }
+
+#line 1042 "plpdftex.ctr"
+}
+
+
+
+static
+void
+plpdftex_write_required_packages(plpdftex_job_t *job)
+{
+ char const * const *ptr;
+
+
+#line 1052 "plpdftex.ctr"
+ ptr = plpdftex_required_packages;
+ while (NULL != *ptr) {
+ plpdftex_write_textline(job, *(ptr++));
+ }
+
+ fprintf(job->fotex, plpdftex_c8_kw[7], job->imgw);
+ fprintf(job->fotex, plpdftex_c8_kw[8], job->imgh);
+
+ ptr = plpdftex_required_instructions;
+ while (NULL != *ptr) {
+ plpdftex_write_textline(job, *(ptr++));
+ }
+
+
+#line 1065 "plpdftex.ctr"
+}
+
+
+
+/** Process package selection line.
+ @param job Job structure.
+ @param txt Text line to process.
+*/
+static
+void
+plpdftex_process_tex_package(plpdftex_job_t *job, char *txt)
+{
+ int ok = 0;
+
+
+#line 1079 "plpdftex.ctr"
+ if (0 == job->stagr) {
+ ok = 1;
+ goto finished;
+ }
+ if (NULL == txt) {
+ /* ERROR: Missing text */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+ switch (job->state) {
+ case PLPT_STATE_NO_OUTPUT_YET: {
+ ok = 1;
+ /* documentclass{article} */
+ plpdftex_write_textline(job, plpdftex_c8_kw[2]);
+ plpdftex_write_default_font_setup(job);
+ plpdftex_write_textline(job, plpdftex_c8_kw[5]);
+ plpdftex_write_textline(job, txt);
+ job->state = PLPT_STATE_USER_PACKAGES;
+ } break;
+ case PLPT_STATE_DOCUMENT_CLASS: {
+ ok = 1;
+ plpdftex_write_default_font_setup(job);
+ plpdftex_write_textline(job, plpdftex_c8_kw[5]);
+ plpdftex_write_textline(job, txt);
+ job->state = PLPT_STATE_USER_PACKAGES;
+ } break;
+ case PLPT_STATE_USER_FONT_SETUP: {
+ ok = 1;
+ plpdftex_write_textline(job, plpdftex_c8_kw[4]);
+ plpdftex_write_textline(job, plpdftex_c8_kw[5]);
+ plpdftex_write_textline(job, txt);
+ job->state = PLPT_STATE_USER_PACKAGES;
+ } break;
+ case PLPT_STATE_USER_PACKAGES: {
+ ok = 1;
+ plpdftex_write_textline(job, txt);
+ } break;
+ }
+ finished:
+ if (0 == ok) {
+ job->exc = 1;
+
+#line 1120 "plpdftex.ctr"
+ }
+
+#line 1121 "plpdftex.ctr"
+}
+
+
+
+/** Process preamble line.
+ @param job Job structure.
+ @param txt Text line to process.
+*/
+static
+void
+plpdftex_process_tex_preamble(plpdftex_job_t *job, char *txt)
+{
+ int ok = 0;
+
+
+#line 1135 "plpdftex.ctr"
+ if (0 == job->stagr) {
+ ok = 1;
+ goto finished;
+ }
+ if (NULL == txt) {
+ /* ERROR: No text */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+ switch (job->state) {
+ case PLPT_STATE_NO_OUTPUT_YET: {
+ ok = 1;
+ /* documentclass{article} */
+ plpdftex_write_textline(job, plpdftex_c8_kw[2]);
+ plpdftex_write_default_font_setup(job);
+ plpdftex_write_default_packages(job);
+ plpdftex_write_required_packages(job);
+ plpdftex_write_textline(job, plpdftex_c8_kw[9]);
+ plpdftex_write_textline(job, txt);
+ job->state = PLPT_STATE_USER_SETUP;
+ } break;
+ case PLPT_STATE_DOCUMENT_CLASS: {
+ ok = 1;
+ plpdftex_write_default_font_setup(job);
+ plpdftex_write_default_packages(job);
+ plpdftex_write_required_packages(job);
+ plpdftex_write_textline(job, plpdftex_c8_kw[9]);
+ plpdftex_write_textline(job, txt);
+ job->state = PLPT_STATE_USER_SETUP;
+ } break;
+ case PLPT_STATE_USER_FONT_SETUP: {
+ ok = 1;
+ plpdftex_write_textline(job, plpdftex_c8_kw[4]);
+ plpdftex_write_default_packages(job);
+ plpdftex_write_required_packages(job);
+ plpdftex_write_textline(job, plpdftex_c8_kw[9]);
+ plpdftex_write_textline(job, txt);
+ job->state = PLPT_STATE_USER_SETUP;
+ } break;
+ case PLPT_STATE_USER_PACKAGES: {
+ ok = 1;
+ plpdftex_write_textline(job, plpdftex_c8_kw[6]);
+ plpdftex_write_required_packages(job);
+ plpdftex_write_textline(job, plpdftex_c8_kw[9]);
+ plpdftex_write_textline(job, txt);
+ job->state = PLPT_STATE_USER_SETUP;
+ } break;
+ case PLPT_STATE_USER_SETUP: {
+ ok = 1;
+ plpdftex_write_textline(job, txt);
+ } break;
+ }
+
+ finished:
+ if (0 == ok) {
+ job->exc = 1;
+
+#line 1191 "plpdftex.ctr"
+ }
+
+#line 1192 "plpdftex.ctr"
+}
+
+
+
+/** Write start of TeX file.
+ @param job Job structure.
+*/
+static
+void
+plpdftex_open_picture_set(plpdftex_job_t *job)
+{
+
+
+#line 1204 "plpdftex.ctr"
+ if (0 != job->stagr) {
+ plpdftex_write_textline(job, plpdftex_c8_kw[11]);
+ }
+ plpdftex_write_textline(job, plpdftex_c8_kw[12]);
+ if (EOF == fputs(plpdftex_c8_kw[13], job->fotex)) {
+ /* ERROR: Write failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ job->exc = 1;
+
+#line 1212 "plpdftex.ctr"
+ }
+ if (EOF == fputs(job->fnpdf, job->fotex)) {
+ /* ERROR: Write failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ job->exc = 1;
+
+#line 1217 "plpdftex.ctr"
+ }
+ plpdftex_write_textline(job, plpdftex_c8_kw[14]);
+ plpdftex_write_textline(job, plpdftex_c8_kw[15]);
+ plpdftex_write_textline(job, plpdftex_c8_kw[16]);
+ if (0 >= fprintf(job->fotex, plpdftex_c8_kw[17], job->imgw, job->imgh)) {
+ /* ERROR: Write failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ job->exc = 1;
+
+#line 1225 "plpdftex.ctr"
+ }
+
+#line 1226 "plpdftex.ctr"
+}
+
+
+
+static
+void
+plpdftex_close_picture_set(plpdftex_job_t *job)
+{
+
+
+#line 1235 "plpdftex.ctr"
+ plpdftex_write_textline(job, plpdftex_c8_kw[15]);
+ if (0 != job->stagr) {
+ plpdftex_write_textline(job, plpdftex_c8_kw[18]);
+ }
+
+#line 1239 "plpdftex.ctr"
+}
+
+
+
+
+/** Process text label line.
+ @param job Job structure.
+ @param txt Text line to process.
+ @param withbox Flag: With box (1) or without box (0).
+*/
+static
+void
+plpdftex_process_tex_text(plpdftex_job_t *job, char *txt, int withbox)
+{
+ char *p1 = NULL; /* Y position */
+ char *p2 = NULL; /* Vertical alignment */
+ char *p3 = NULL; /* Horizontal alignment */
+ char *p4 = NULL; /* Color */
+ char *p5 = NULL; /* Label text */
+ double x = 0.0; /* X position */
+ double y = 0.0; /* Y position */
+ int av = 0; /* Vertical alignment */
+ int ah = 0; /* Horizontal alignment */
+ int ok = 0;
+ char c;
+
+
+#line 1265 "plpdftex.ctr"
+ /* Split strings.
+ */
+ if (NULL == txt) {
+ /* ERROR: No text */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+ p1 = dk3str_c8_next(txt, NULL);
+ if (NULL == p1) {
+ /* ERROR: No y position */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+ p2 = dk3str_c8_next(p1, NULL);
+ if (NULL == p2) {
+ /* ERROR: No vertical alignment */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+ p3 = dk3str_c8_next(p2, NULL);
+ if (NULL == p3) {
+ /* ERROR: No horizontal alignment */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+ p4 = dk3str_c8_next(p3, NULL);
+ if (NULL == p4) {
+ /* ERROR: No color */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+ p5 = dk3str_c8_next(p4, NULL);
+ if (NULL == p5) {
+ /* ERROR: No text */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+
+ /* Retrieve values from strings.
+ */
+ if (0 == dk3ma_d_from_c8_string(&x, txt, NULL)) {
+ /* ERROR: x value not numeric */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ goto finished;
+ }
+ if (0 == dk3ma_d_from_c8_string(&y, p1, NULL)) {
+ /* ERROR: y value not numeric */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ goto finished;
+ }
+ av = dk3str_c8_array_index(plpdftex_vertical_alignments, p2, 0);
+ if (0 > av) {
+ /* ERROR: Not a valid vertical alignment */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 37);
+ goto finished;
+ }
+ ah = dk3str_c8_array_index(plpdftex_horizontal_alignments, p3, 0);
+ if (0 > ah) {
+ /* ERROR: Not a valid horizontal alignment */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 36);
+ goto finished;
+ }
+
+ /* Write file header parts not yet written.
+ */
+ if (0 != job->stagr) {
+ switch (job->state) {
+ case PLPT_STATE_NO_OUTPUT_YET: {
+ ok = 1;
+ /* documentclass{article} */
+ plpdftex_write_textline(job, plpdftex_c8_kw[2]);
+ plpdftex_write_default_font_setup(job);
+ plpdftex_write_default_packages(job);
+ plpdftex_write_required_packages(job);
+ plpdftex_write_textline(job, plpdftex_c8_kw[9]);
+ plpdftex_write_textline(job, plpdftex_c8_kw[10]);
+ plpdftex_open_picture_set(job);
+ job->state = PLPT_STATE_IN_DOCUMENT;
+ } break;
+ case PLPT_STATE_DOCUMENT_CLASS: {
+ ok = 1;
+ plpdftex_write_default_font_setup(job);
+ plpdftex_write_default_packages(job);
+ plpdftex_write_required_packages(job);
+ plpdftex_write_textline(job, plpdftex_c8_kw[9]);
+ plpdftex_write_textline(job, plpdftex_c8_kw[10]);
+ plpdftex_open_picture_set(job);
+ job->state = PLPT_STATE_IN_DOCUMENT;
+ } break;
+ case PLPT_STATE_USER_FONT_SETUP: {
+ ok = 1;
+ plpdftex_write_textline(job, plpdftex_c8_kw[4]);
+ plpdftex_write_default_packages(job);
+ plpdftex_write_required_packages(job);
+ plpdftex_write_textline(job, plpdftex_c8_kw[9]);
+ plpdftex_write_textline(job, plpdftex_c8_kw[10]);
+ plpdftex_open_picture_set(job);
+ job->state = PLPT_STATE_IN_DOCUMENT;
+ } break;
+ case PLPT_STATE_USER_PACKAGES: {
+ ok = 1;
+ plpdftex_write_textline(job, plpdftex_c8_kw[6]);
+ plpdftex_write_required_packages(job);
+ plpdftex_write_textline(job, plpdftex_c8_kw[9]);
+ plpdftex_write_textline(job, plpdftex_c8_kw[10]);
+ plpdftex_open_picture_set(job);
+ job->state = PLPT_STATE_IN_DOCUMENT;
+ } break;
+ case PLPT_STATE_USER_SETUP: {
+ ok = 1;
+ plpdftex_write_textline(job, plpdftex_c8_kw[10]);
+ plpdftex_open_picture_set(job);
+ job->state = PLPT_STATE_IN_DOCUMENT;
+ } break;
+ case PLPT_STATE_IN_DOCUMENT: {
+ ok = 1;
+ } break;
+ default: {
+ /* ERROR: Too late */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 12);
+ goto finished;
+ } break;
+ }
+ } else {
+ switch (job->state) {
+ case PLPT_STATE_NO_OUTPUT_YET:
+ case PLPT_STATE_DOCUMENT_CLASS:
+ case PLPT_STATE_USER_FONT_SETUP:
+ case PLPT_STATE_USER_PACKAGES:
+ case PLPT_STATE_USER_SETUP:
+ {
+ ok = 1;
+ plpdftex_open_picture_set(job);
+ job->state = PLPT_STATE_IN_DOCUMENT;
+ } break;
+ case PLPT_STATE_IN_DOCUMENT: {
+ ok = 1;
+ } break;
+ default: {
+ /* ERROR: Too late */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 12);
+ goto finished;
+ } break;
+ }
+ }
+
+ /* Write text label.
+ */
+ if (1 == ok) {
+ if (1 == withbox) {
+
+#line 1415 "plpdftex.ctr"
+ /* put(%g,%g)makebox(0,0) */
+
+#line 1416 "plpdftex.ctr"
+ if (0 >= fprintf(job->fotex, plpdftex_c8_kw[19], x, y)) {
+ /* ERROR: fprintf failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ ok = 0; goto finished;
+ }
+ /* Alignment */
+ if ((ah != 1) || (av != 1)) {
+
+#line 1423 "plpdftex.ctr"
+ if (EOF == fputs(plpdftex_c8_kw[20], job->fotex)) {
+ /* ERROR: Write failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ ok = 0; goto finished;
+ }
+ c = '\0';
+ switch (ah) {
+ case 0: { c = 'l'; } break;
+ case 2: { c = 'r'; } break;
+ }
+ if ('\0' != c) {
+ if (EOF == fputc(c, job->fotex)) {
+ /* ERROR: Write failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ ok = 0; goto finished;
+ }
+ }
+ c = '\0';
+ switch (av) {
+ case 0: { c = 't'; } break;
+ case 2: case 3: { c = 'b'; } break;
+ }
+ if ('\0' != c) {
+ if (EOF == fputc(c, job->fotex)) {
+ /* ERROR: Write failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ ok = 0; goto finished;
+ }
+ }
+ if (EOF == fputs(plpdftex_c8_kw[21], job->fotex)) {
+ /* ERROR: Write failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ ok = 0; goto finished;
+ }
+ }
+ if (0 >= fprintf(job->fotex, plpdftex_c8_kw[23], p4, p5)) {
+ /* ERROR: Write failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ ok = 0; goto finished;
+ }
+ } else {
+
+#line 1464 "plpdftex.ctr"
+ /* put(%g,%g)makebox(0,0) */
+
+#line 1465 "plpdftex.ctr"
+ if (0 >= fprintf(job->fotex, plpdftex_c8_kw[19], x, y)) {
+ /* ERROR: fprintf failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ ok = 0; goto finished;
+ }
+ /* Alignment */
+ if ((ah != 1) || (av != 1)) {
+
+#line 1472 "plpdftex.ctr"
+ if (EOF == fputs(plpdftex_c8_kw[20], job->fotex)) {
+ /* ERROR: Write failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ ok = 0; goto finished;
+ }
+ c = '\0';
+ switch (ah) {
+ case 0: { c = 'l'; } break;
+ case 2: { c = 'r'; } break;
+ }
+ if ('\0' != c) {
+ if (EOF == fputc(c, job->fotex)) {
+ /* ERROR: Write failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ ok = 0; goto finished;
+ }
+ }
+ c = '\0';
+ switch (av) {
+ case 0: { c = 't'; } break;
+ case 2: case 3: { c = 'b'; } break;
+ }
+ if ('\0' != c) {
+ if (EOF == fputc(c, job->fotex)) {
+ /* ERROR: Write failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ ok = 0; goto finished;
+ }
+ }
+ if (EOF == fputs(plpdftex_c8_kw[21], job->fotex)) {
+ /* ERROR: Write failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ ok = 0; goto finished;
+ }
+ }
+ if (2 == av) {
+ /* Use smash only for baseline vertical alignment */
+ if (0 >= fprintf(job->fotex, plpdftex_c8_kw[22], p4, p5)) {
+ /* ERROR: Write failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ ok = 0; goto finished;
+ }
+ } else {
+ /* No smash for top, center, bottom vertical alignment */
+ if (0 >= fprintf(job->fotex, plpdftex_c8_kw[24], p4, p5)) {
+ /* ERROR: Write failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ ok = 0; goto finished;
+ }
+ }
+ }
+ }
+ /* Return.
+ */
+ finished:
+ if (0 == ok) {
+ job->exc = 1;
+
+#line 1529 "plpdftex.ctr"
+ }
+
+#line 1530 "plpdftex.ctr"
+}
+
+
+
+/** Process a TeX line.
+ @param job Job structure.
+ @param txt Text to process.
+*/
+static
+void
+plpdftex_process_tex_line(plpdftex_job_t *job, char *txt)
+{
+ char *firstarg;
+
+
+#line 1544 "plpdftex.ctr"
+ firstarg = dk3str_c8_next(txt, NULL);
+ switch(dk3str_c8_array_index(plpdftex_tex_instructions, txt, 0)) {
+ case 0: {
+ plpdftex_process_tex_fontsize(job, firstarg);
+ } break;
+ case 1: {
+ plpdftex_process_tex_font_setup(job, firstarg);
+ } break;
+ case 2: {
+ plpdftex_process_tex_package(job, firstarg);
+ } break;
+ case 3: {
+ plpdftex_process_tex_preamble(job, firstarg);
+ } break;
+ case 4: {
+ plpdftex_process_tex_text(job, firstarg, 0);
+ } break;
+ case 5: {
+ plpdftex_process_tex_text(job, firstarg, 1);
+ } break;
+ }
+
+#line 1565 "plpdftex.ctr"
+}
+
+
+
+/** Process PDF gsave line.
+ @param job Job structure.
+ @param txt Text to process, may be NULL.
+*/
+static
+void
+pldpdftex_process_pdf_gsave(plpdftex_job_t *job, char *txt)
+{
+ int ok = 0;
+
+
+#line 1579 "plpdftex.ctr"
+ if (0 != dk3pdf_gsave(job->opdf)) {
+ ok = 1;
+ } else {
+ /* ERROR: gsave failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 34);
+ }
+ if(0 == ok) {
+ job->exc = 1;
+
+#line 1587 "plpdftex.ctr"
+ }
+
+#line 1588 "plpdftex.ctr"
+}
+
+
+
+/** Process PDF grestore line.
+ @param job Job structure.
+ @param txt Text to process, may be NULL.
+*/
+static
+void
+pldpdftex_process_pdf_grestore(plpdftex_job_t *job, char *txt)
+{
+ int ok = 0;
+
+
+#line 1602 "plpdftex.ctr"
+ if (0 != dk3pdf_grestore(job->opdf)) {
+ ok = 1;
+ } else {
+ /* ERROR grestore failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 33);
+ }
+ if(0 == ok) {
+ job->exc = 1;
+
+#line 1610 "plpdftex.ctr"
+ }
+
+#line 1611 "plpdftex.ctr"
+}
+
+
+
+/** Process PDF linewidth line.
+ @param job Job structure.
+ @param txt Text to process, may be NULL.
+*/
+static
+void
+pldpdftex_process_pdf_lw(plpdftex_job_t *job, char *txt)
+{
+ double lw = 1.0;
+ int ok = 0;
+ int mec = 0;
+
+
+#line 1627 "plpdftex.ctr"
+ if (NULL != txt) {
+ if (0 != dk3ma_d_from_c8_string(&lw, txt, &mec)) {
+ if (0.0 <= lw) {
+ if (0 != dk3pdf_set_linewidth(job->opdf, lw)) {
+ ok = 1;
+ } else {
+ /* ERROR: Failed to set line width */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 32);
+ }
+ } else {
+ /* Syntax error, negative number */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 31);
+ }
+ } else {
+ /* Syntax error, not numeric */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ }
+ } else {
+ /* Syntax error, missing line width */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ }
+ if(0 == ok) {
+ job->exc = 1;
+
+#line 1650 "plpdftex.ctr"
+ }
+
+#line 1651 "plpdftex.ctr"
+}
+
+
+
+/** Process PDF buttcap line.
+ @param job Job structure.
+ @param txt Text to process, may be NULL.
+*/
+static
+void
+pldpdftex_process_pdf_buttcap(plpdftex_job_t *job, char *txt)
+{
+ int ok = 0;
+
+
+#line 1665 "plpdftex.ctr"
+ if (0 != dk3pdf_set_linecap(job->opdf, DK3_LINECAP_BUTT)) {
+ ok = 1;
+ } else {
+ /* ERROR: Failed to set line cap */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 30);
+ }
+ if(0 == ok) {
+ job->exc = 1;
+
+#line 1673 "plpdftex.ctr"
+ }
+
+#line 1674 "plpdftex.ctr"
+}
+
+
+/** Process PDF miterjoin line.
+ @param job Job structure.
+ @param txt Text to process, may be NULL.
+*/
+static
+void
+pldpdftex_process_pdf_miterjoin(plpdftex_job_t *job, char *txt)
+{
+ int ok = 0;
+
+
+#line 1687 "plpdftex.ctr"
+ if (0 != dk3pdf_set_linejoin(job->opdf, DK3_LINEJOIN_MITER)) {
+ ok = 1;
+ } else {
+ /* Failed to set linejoin */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 29);
+ }
+ if(0 == ok) {
+ job->exc = 1;
+
+#line 1695 "plpdftex.ctr"
+ }
+
+#line 1696 "plpdftex.ctr"
+}
+
+
+
+/** Process PDF nodash line.
+ @param job Job structure.
+ @param txt Text to process, may be NULL.
+*/
+static
+void
+pldpdftex_process_pdf_nodash(plpdftex_job_t *job, char *txt)
+{
+ double d = 0.0;
+ int ok = 0;
+
+
+#line 1711 "plpdftex.ctr"
+ if (0 != dk3pdf_set_line_dash(job->opdf, &d, 0, 0.0)) {
+ ok = 1;
+ } else {
+ /* Failed to set dash */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 28);
+ }
+ if(0 == ok) {
+ job->exc = 1;
+
+#line 1719 "plpdftex.ctr"
+ }
+
+#line 1720 "plpdftex.ctr"
+}
+
+
+
+/** Process PDF stroke color line.
+ @param job Job structure.
+ @param txt Text to process, may be NULL.
+*/
+static
+void
+pldpdftex_process_pdf_stroke_color(plpdftex_job_t *job, char *txt)
+{
+ double r = 0.0;
+ double g = 0.0;
+ double b = 0.0;
+ int ok = 0;
+
+
+#line 1737 "plpdftex.ctr"
+ if (NULL != txt) {
+ if (0 != plptcol_get_color(job, txt, &r, &g, &b)) {
+ if (0 != dk3pdf_stroking_rgb(job->opdf, r, g, b)) {
+ ok = 1;
+ } else {
+ /* Failed to set stroke color */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 27);
+ }
+ } else {
+ /* Color not found! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 26);
+ }
+ } else {
+ /* Syntax error, missing text */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ }
+ if(0 == ok) {
+ job->exc = 1;
+
+#line 1755 "plpdftex.ctr"
+ }
+
+#line 1756 "plpdftex.ctr"
+}
+
+
+
+/** Process PDF fill color line.
+ @param job Job structure.
+ @param txt Text to process, may be NULL.
+*/
+static
+void
+pldpdftex_process_pdf_fill_color(plpdftex_job_t *job, char *txt)
+{
+ double r = 0.0;
+ double g = 0.0;
+ double b = 0.0;
+ int ok = 0;
+
+
+#line 1773 "plpdftex.ctr"
+ if (NULL != txt) {
+ if (0 != plptcol_get_color(job, txt, &r, &g, &b)) {
+ if (0 != dk3pdf_nonstroking_rgb(job->opdf, r, g, b)) {
+ ok = 1;
+ } else {
+ /* Failed to set stroke color */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 25);
+ }
+ } else {
+ /* Color not found! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ }
+ } else {
+ /* Syntax error, missing text */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ }
+ if(0 == ok) {
+ job->exc = 1;
+
+#line 1791 "plpdftex.ctr"
+ }
+
+#line 1792 "plpdftex.ctr"
+}
+
+
+
+/** Process PDF rectangle line.
+ @param job Job structure.
+ @param txt Text to process, may be NULL.
+*/
+static
+void
+pldpdftex_process_pdf_rectangle(plpdftex_job_t *job, char *txt)
+{
+ char *p1 = NULL;
+ char *p2 = NULL;
+ char *p3 = NULL;
+ double x1 = 0.0;
+ double x2 = 0.0;
+ double y1 = 0.0;
+ double y2 = 0.0;
+ int ok = 0;
+
+
+#line 1813 "plpdftex.ctr"
+ /* Set txt, p1, p2, p3 to x1, y1, x2, y2.
+ */
+ if (NULL == txt) {
+ /* Syntax error, missing text */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto cleanup;
+ }
+ p1 = dk3str_c8_next(txt, NULL);
+ if (NULL == p1) {
+ /* Syntax error, missing y1 */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto cleanup;
+ }
+ p2 = dk3str_c8_next(p1, NULL);
+ if (NULL == p2) {
+ /* Syntax error, missing x2 */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto cleanup;
+ }
+ p3 = dk3str_c8_next(p2, NULL);
+ if (NULL == p3) {
+ /* Syntax error, missing y2 */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto cleanup;
+ }
+
+ /* Read values from strings.
+ */
+ if (0 == dk3ma_d_from_c8_string(&x1, txt, NULL)) {
+ /* Syntax error, x1 not a number */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ goto cleanup;
+ }
+ if (0 == dk3ma_d_from_c8_string(&y1, p1, NULL)) {
+ /* Syntax error, y1 not a number */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ goto cleanup;
+ }
+ if (0 == dk3ma_d_from_c8_string(&x2, p2, NULL)) {
+ /* Syntax error, x2 not a number */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ goto cleanup;
+ }
+ if (0 == dk3ma_d_from_c8_string(&y2, p3, NULL)) {
+ /* Syntax error, y2 not a number */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ goto cleanup;
+ }
+
+ /* PDF drawing operations.
+ */
+ if (0 == dk3pdf_newpath_moveto(job->opdf, x1, y1)) {
+ /* ERROR: moveto failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 22);
+ goto cleanup;
+ }
+ if (0 == dk3pdf_lineto(job->opdf, x2, y1)) {
+ /* ERROR: lineto failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 24);
+ goto cleanup;
+ }
+ if (0 == dk3pdf_lineto(job->opdf, x2, y2)) {
+ /* ERROR: lineto failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 24);
+ goto cleanup;
+ }
+ if (0 == dk3pdf_lineto(job->opdf, x1, y2)) {
+ /* ERROR: lineto failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 24);
+ goto cleanup;
+ }
+ if (0 == dk3pdf_lineto(job->opdf, x1, y1)) {
+ /* ERROR: lineto failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 24);
+ goto cleanup;
+ }
+ if (0 == dk3pdf_closepath(job->opdf)) {
+ /* ERROR: closepath failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 18);
+ goto cleanup;
+ }
+
+ /* Success.
+ */
+ ok = 1;
+
+ cleanup:
+ if(0 == ok) {
+ job->exc = 1;
+
+#line 1902 "plpdftex.ctr"
+ }
+
+#line 1903 "plpdftex.ctr"
+}
+
+
+
+/** Segments per quarter circle.
+*/
+static size_t const plpt_segments = 2;
+
+
+
+/** Calculate kappa value to draw a circle.
+ @param segments Number of segments for one _quarter_
+ of the circle.
+ @return Kappa value (factor to apply to first derivative
+ when calculating control points).
+*/
+static
+double
+plpdftex_kappa(size_t segments)
+{
+ double back = 0.0;
+ double alpha;
+
+
+#line 1926 "plpdftex.ctr"
+ alpha = M_PI / (2.0 * (double)segments);
+
+ /* kappa = (2*sqrt(8*(1-cos(a)))-4*sin(a)) / (3*a*(1-cos(a))) */
+
+ back = (2.0 * sqrt(8.0 * (1.0 - cos(alpha))) - 4.0 * sin(alpha))
+ / (3.0 * alpha * (1.0 - cos(alpha)));
+
+
+#line 1933 "plpdftex.ctr"
+ return back;
+}
+
+
+
+/** Process PDF circle line.
+ @param job Job structure.
+ @param txt Text to process, may be NULL.
+*/
+static
+void
+pldpdftex_process_pdf_circle(plpdftex_job_t *job, char *txt)
+{
+ char *p1; /* Text containing y */
+ char *p2; /* Text containing radius */
+ double x; /* Center x */
+ double y; /* Center y */
+ double r; /* Radius */
+ double x0; /* Current point x */
+ double y0; /* Current point y */
+ double x1; /* First control point x */
+ double y1; /* First control point y */
+ double x2; /* Second control point x */
+ double y2; /* Second control point y */
+ double x3; /* Final point x */
+ double y3; /* Final point y */
+ double alpha; /* Arc angle. */
+ double a1; /* Start angle. */
+ double a2; /* End angle. */
+ double kappa; /* Kappa value. */
+ size_t i; /* Current sub-segment */
+ int ok = 0; /* Flag: Success */
+
+
+#line 1966 "plpdftex.ctr"
+ /* Find strings
+ */
+ if (NULL == txt) {
+ /* Syntax error, no data */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+ p1 = dk3str_c8_next(txt, NULL);
+ if (NULL == p1) {
+ /* Syntax error, missing y */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+ p2 = dk3str_c8_next(p1, NULL);
+ if (NULL == p2) {
+ /* Syntax error, missing r */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+
+ /* Retrieve values from strings.
+ */
+ if (0 == dk3ma_d_from_c8_string(&x, txt, NULL)) {
+ /* Syntax error, not a number */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ goto finished;
+ }
+ if (0 == dk3ma_d_from_c8_string(&y, txt, NULL)) {
+ /* Syntax error, not a number */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ goto finished;
+ }
+ if (0 == dk3ma_d_from_c8_string(&r, txt, NULL)) {
+ /* Syntax error, not a number */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ goto finished;
+ }
+ if (0.0 > r) {
+ /* ERROR: Negative radius */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 23);
+ goto finished;
+ }
+ if (0 == dk3pdf_newpath_moveto(job->opdf, x+r, y)) {
+ goto finished;
+ }
+ kappa = plpdftex_kappa(plpt_segments);
+ alpha = 2.0 * M_PI / ((double)(4 * plpt_segments));
+ ok = 1;
+ for (i = 0; i < (4 * plpt_segments); i++) {
+ a1 = (double)i * alpha;
+ a2 = a1 + alpha;
+ if (0 == i) a1 = 0.0;
+ if ((4 * plpt_segments - 1) == i) a2 = 2.0 * M_PI;
+ x0 = r * cos(a1); y0 = r * sin(a1);
+ if (0 == i) { x0 = r; y0 = 0.0; }
+ x3 = r * cos(a2); y3 = r * sin(a2);
+ if ((4 * plpt_segments - 1) == i) { x3 = r; y3 = 0.0; }
+ x1 = -1.0 * r * alpha * sin(a1);
+ y1 = r * alpha * cos(a1);
+ x2 = -1.0 * r * alpha * sin(a2);
+ y2 = r * alpha * cos(a2);
+ x1 = x1 * kappa;
+ y1 = y1 * kappa;
+ x2 = -1.0 * kappa * x2;
+ y2 = -1.0 * kappa * y2;
+ x1 += x0;
+ y1 += y0;
+ x2 += x3;
+ y2 += y3;
+#if VERSION_BEFORE_20150821
+ x0 += x;
+#endif
+ x1 += x; x2 += x; x3 += x;
+#if VERSION_BEFORE_20150821
+ y0 += y;
+#endif
+ y1 += y; y2 += y; y3 += y;
+ if (0 == dk3pdf_curveto(job->opdf, x1, y1, x2, y2, x3, y3)) {
+ ok = 0;
+ goto finished;
+ }
+ }
+ if (0 == dk3pdf_closepath(job->opdf)) {
+ ok = 0;
+ }
+
+ /* Return
+ */
+ finished:
+ if(0 == ok) {
+ job->exc = 1;
+
+#line 2057 "plpdftex.ctr"
+ }
+
+#line 2058 "plpdftex.ctr"
+}
+
+
+
+/** Process PDF moveto line.
+ @param job Job structure.
+ @param txt Text to process, may be NULL.
+*/
+static
+void
+pldpdftex_process_pdf_moveto(plpdftex_job_t *job, char *txt)
+{
+ char *p1;
+ double x;
+ double y;
+ int ok = 0;
+
+
+#line 2075 "plpdftex.ctr"
+ if (NULL != txt) {
+ p1 = dk3str_c8_next(txt, NULL);
+ if (NULL != p1) {
+ if (0 != dk3ma_d_from_c8_string(&x, txt, NULL)) {
+ if (0 != dk3ma_d_from_c8_string(&y, p1, NULL)) {
+ if (0 != dk3pdf_newpath_moveto(job->opdf, x, y)) {
+ ok = 1;
+ } else {
+ /* ERROR, moveto failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 22);
+ }
+ } else {
+ /* ERROR, y not numeric */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ }
+ } else {
+ /* ERROR, x not numeric */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ }
+ } else {
+ /* Syntax error, missing y value */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ }
+ } else {
+ /* Syntax error, no coordinates */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ }
+ if(0 == ok) {
+ job->exc = 1;
+
+#line 2104 "plpdftex.ctr"
+ }
+
+#line 2105 "plpdftex.ctr"
+}
+
+
+
+/** Process PDF lineto line.
+ @param job Job structure.
+ @param txt Text to process, may be NULL.
+*/
+static
+void
+pldpdftex_process_pdf_lineto(plpdftex_job_t *job, char *txt)
+{
+ char *p1;
+ double x;
+ double y;
+ int ok = 0;
+
+
+#line 2122 "plpdftex.ctr"
+ if (NULL != txt) {
+ p1 = dk3str_c8_next(txt, NULL);
+ if (NULL != p1) {
+ if (0 != dk3ma_d_from_c8_string(&x, txt, NULL)) {
+ if (0 != dk3ma_d_from_c8_string(&y, p1, NULL)) {
+ if (0 != dk3pdf_lineto(job->opdf, x, y)) {
+ ok = 1;
+ } else {
+ /* ERROR, moveto failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 22);
+ }
+ } else {
+ /* ERROR, y not numeric */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ }
+ } else {
+ /* ERROR, x not numeric */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ }
+ } else {
+ /* Syntax error, missing y value */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ }
+ } else {
+ /* Syntax error, no coordinates */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ }
+ if(0 == ok) {
+ job->exc = 1;
+
+#line 2151 "plpdftex.ctr"
+ }
+
+#line 2152 "plpdftex.ctr"
+}
+
+
+
+/** Process PDF curveto line.
+ @param job Job structure.
+ @param txt Text to process, may be NULL.
+*/
+static
+void
+pldpdftex_process_pdf_curveto(plpdftex_job_t *job, char *txt)
+{
+ char *p1; /* y1 */
+ char *p2; /* x2 */
+ char *p3; /* y2 */
+ char *p4; /* x3 */
+ char *p5; /* y3 */
+ double x1;
+ double y1;
+ double x2;
+ double y2;
+ double x3;
+ double y3;
+ int ok = 0;
+
+
+#line 2177 "plpdftex.ctr"
+ /* Split string.
+ */
+ if (NULL == txt) {
+ /* ERROR: No text */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+ p1 = dk3str_c8_next(txt, NULL);
+ if (NULL == p1) {
+ /* ERROR: No y1 */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+ p2 = dk3str_c8_next(p1, NULL);
+ if (NULL == p2) {
+ /* ERROR: No x2 */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+ p3 = dk3str_c8_next(p2, NULL);
+ if (NULL == p3) {
+ /* ERROR: No y2 */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+ p4 = dk3str_c8_next(p3, NULL);
+ if (NULL == p4) {
+ /* ERROR: No x3 */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+ p5 = dk3str_c8_next(p4, NULL);
+ if (NULL == p5) {
+ /* ERROR: No y3 */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+
+ /* Retrieve values.
+ */
+ if (0 == dk3ma_d_from_c8_string(&x1, txt, NULL)) {
+ /* ERROR: x1 not numeric */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ goto finished;
+ }
+ if (0 == dk3ma_d_from_c8_string(&y1, p1, NULL)) {
+ /* ERROR: y1 not numeric */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ goto finished;
+ }
+ if (0 == dk3ma_d_from_c8_string(&x2, p2, NULL)) {
+ /* ERROR: x2 not numeric */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ goto finished;
+ }
+ if (0 == dk3ma_d_from_c8_string(&y2, p3, NULL)) {
+ /* ERROR: y2 not numeric */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ goto finished;
+ }
+ if (0 == dk3ma_d_from_c8_string(&x3, p4, NULL)) {
+ /* ERROR: x3 not numeric */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ goto finished;
+ }
+ if (0 == dk3ma_d_from_c8_string(&y3, p5, NULL)) {
+ /* ERROR: y3 not numeric */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ goto finished;
+ }
+
+ /* Write curve segment.
+ */
+ if (0 != dk3pdf_curveto(job->opdf, x1, y1, x2, y2, x3, y3)) {
+ ok = 1;
+ } else {
+ /* ERROR: curveto failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 19);
+ }
+
+ /* Return.
+ */
+ finished:
+ if(0 == ok) {
+ job->exc = 1;
+
+#line 2262 "plpdftex.ctr"
+ }
+
+#line 2263 "plpdftex.ctr"
+}
+
+
+
+/** Process PDF closepath line.
+ @param job Job structure.
+ @param txt Text to process, may be NULL.
+*/
+static
+void
+pldpdftex_process_pdf_closepath(plpdftex_job_t *job, char *txt)
+{
+ int ok = 0;
+
+
+#line 2277 "plpdftex.ctr"
+ if (0 != dk3pdf_closepath(job->opdf)) {
+ ok = 1;
+ } else {
+ /* ERROR: closepath failed */
+ }
+ if(0 == ok) {
+ job->exc = 1;
+
+#line 2284 "plpdftex.ctr"
+ }
+
+#line 2285 "plpdftex.ctr"
+}
+
+
+
+/** Process PDF stroke line.
+ @param job Job structure.
+ @param txt Text to process, may be NULL.
+*/
+static
+void
+pldpdftex_process_pdf_stroke(plpdftex_job_t *job, char *txt)
+{
+ int ok = 0;
+
+
+#line 2299 "plpdftex.ctr"
+ if (0 != dk3pdf_stroke(job->opdf)) {
+ ok = 1;
+ } else {
+ /* ERROR: stroke failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 17);
+ }
+ if(0 == ok) {
+ job->exc = 1;
+
+#line 2307 "plpdftex.ctr"
+ }
+
+#line 2308 "plpdftex.ctr"
+}
+
+
+
+/** Process PDF fill line.
+ @param job Job structure.
+ @param txt Text to process, may be NULL.
+*/
+static
+void
+pldpdftex_process_pdf_fill(plpdftex_job_t *job, char *txt)
+{
+ int ok = 0;
+
+
+#line 2322 "plpdftex.ctr"
+ if (0 != dk3pdf_fill_eo(job->opdf)) {
+ ok = 1;
+ } else {
+ /* ERROR: Fill failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 16);
+ }
+ if(0 == ok) {
+ job->exc = 1;
+
+#line 2330 "plpdftex.ctr"
+ }
+
+#line 2331 "plpdftex.ctr"
+}
+
+
+
+/** Process PDF clip line.
+ @param job Job structure.
+ @param txt Text to process, may be NULL.
+*/
+static
+void
+pldpdftex_process_pdf_clip(plpdftex_job_t *job, char *txt)
+{
+ int ok = 0;
+
+
+#line 2345 "plpdftex.ctr"
+ if (0 != dk3pdf_clip_eo(job->opdf)) {
+ ok = 1;
+ } else {
+ /* ERROR: clip failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 15);
+ }
+ if(0 == ok) {
+ job->exc = 1;
+
+#line 2353 "plpdftex.ctr"
+ }
+
+#line 2354 "plpdftex.ctr"
+}
+
+
+
+/** Process a PDF line.
+ @param job Job structure.
+ @param txt Text to process.
+*/
+static
+void
+plpdftex_process_pdf_line(plpdftex_job_t *job, char *txt)
+{
+ char *firstarg;
+
+
+#line 2368 "plpdftex.ctr"
+ firstarg = dk3str_c8_next(txt, NULL);
+ switch(dk3str_c8_array_index(plpdftex_pdf_instructions, txt, 0)) {
+ case 0: {
+ pldpdftex_process_pdf_gsave(job, firstarg);
+ } break;
+ case 1: {
+ pldpdftex_process_pdf_grestore(job, firstarg);
+ } break;
+ case 2: {
+ pldpdftex_process_pdf_lw(job, firstarg);
+ } break;
+ case 3: {
+ pldpdftex_process_pdf_buttcap(job, firstarg);
+ } break;
+ case 4: {
+ pldpdftex_process_pdf_miterjoin(job, firstarg);
+ } break;
+ case 5: {
+ pldpdftex_process_pdf_nodash(job, firstarg);
+ } break;
+ case 6: {
+ pldpdftex_process_pdf_stroke_color(job, firstarg);
+ } break;
+ case 7: {
+ pldpdftex_process_pdf_fill_color(job, firstarg);
+ } break;
+ case 8: {
+ pldpdftex_process_pdf_rectangle(job, firstarg);
+ } break;
+ case 9: {
+ pldpdftex_process_pdf_circle(job, firstarg);
+ } break;
+ case 10: {
+ pldpdftex_process_pdf_moveto(job, firstarg);
+ } break;
+ case 11: {
+ pldpdftex_process_pdf_lineto(job, firstarg);
+ } break;
+ case 12: {
+ pldpdftex_process_pdf_curveto(job, firstarg);
+ } break;
+ case 13: {
+ pldpdftex_process_pdf_closepath(job, firstarg);
+ } break;
+ case 14: {
+ pldpdftex_process_pdf_stroke(job, firstarg);
+ } break;
+ case 15: {
+ pldpdftex_process_pdf_fill(job, firstarg);
+ } break;
+ case 16: {
+ pldpdftex_process_pdf_clip(job, firstarg);
+ } break;
+ }
+
+#line 2422 "plpdftex.ctr"
+}
+
+
+
+/** Process one input line stored into ilbuf by plpdftex_run_for_input().
+ @param job Job structure.
+*/
+static
+void
+plpdftex_process_line(plpdftex_job_t *job)
+{
+ char *p1;
+
+
+#line 2435 "plpdftex.ctr"
+ p1 = dk3str_c8_start(job->ilbuf, NULL);
+ if (NULL != p1) {
+ dk3str_c8_chomp(p1, NULL);
+
+#line 2438 "plpdftex.ctr"
+ switch(*p1) {
+ case 't': {
+ p1 = dk3str_c8_start(++p1, NULL);
+ if (NULL != p1) {
+ plpdftex_process_tex_line(job, p1);
+ } else {
+ /* Syntax error */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 14);
+ job->exc = 1;
+
+#line 2447 "plpdftex.ctr"
+ }
+ } break;
+ case 'p': {
+ p1 = dk3str_c8_start(++p1, NULL);
+ if (NULL != p1) {
+ plpdftex_process_pdf_line(job, p1);
+ } else {
+ /* Syntax error */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 14);
+ job->exc = 1;
+
+#line 2457 "plpdftex.ctr"
+ }
+ } break;
+ case '#': {
+
+#line 2460 "plpdftex.ctr"
+ } break;
+ default: {
+ /* Syntax error */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 13);
+ job->exc = 1;
+
+#line 2465 "plpdftex.ctr"
+ } break;
+ }
+ }
+
+#line 2468 "plpdftex.ctr"
+}
+
+
+
+/** Process the normal input lines.
+ @param job Job structure.
+*/
+static
+void
+plpdftex_run_for_input(plpdftex_job_t *job)
+{
+ int ok = 0;
+
+
+#line 2481 "plpdftex.ctr"
+ while (NULL != fgets(job->ilbuf, (int)(job->szilb), job->infi)) {
+ plpdftex_process_line(job);
+ }
+ if (0 != job->stagr) {
+ switch (job->state) {
+ case PLPT_STATE_NO_OUTPUT_YET: {
+ ok = 1;
+ /* documentclass{article} */
+ plpdftex_write_textline(job, plpdftex_c8_kw[2]);
+ plpdftex_write_default_font_setup(job);
+ plpdftex_write_default_packages(job);
+ plpdftex_write_required_packages(job);
+ plpdftex_write_textline(job, plpdftex_c8_kw[9]);
+ plpdftex_write_textline(job, plpdftex_c8_kw[10]);
+ plpdftex_open_picture_set(job);
+ plpdftex_close_picture_set(job);
+ job->state = PLPT_STATE_AFTER_DOCUMENT;
+ } break;
+ case PLPT_STATE_DOCUMENT_CLASS: {
+ ok = 1;
+ plpdftex_write_default_font_setup(job);
+ plpdftex_write_default_packages(job);
+ plpdftex_write_required_packages(job);
+ plpdftex_write_textline(job, plpdftex_c8_kw[9]);
+ plpdftex_write_textline(job, plpdftex_c8_kw[10]);
+ plpdftex_open_picture_set(job);
+ plpdftex_close_picture_set(job);
+ job->state = PLPT_STATE_AFTER_DOCUMENT;
+ } break;
+ case PLPT_STATE_USER_FONT_SETUP: {
+ ok = 1;
+ plpdftex_write_textline(job, plpdftex_c8_kw[4]);
+ plpdftex_write_default_packages(job);
+ plpdftex_write_required_packages(job);
+ plpdftex_write_textline(job, plpdftex_c8_kw[9]);
+ plpdftex_write_textline(job, plpdftex_c8_kw[10]);
+ plpdftex_open_picture_set(job);
+ plpdftex_close_picture_set(job);
+ job->state = PLPT_STATE_AFTER_DOCUMENT;
+ } break;
+ case PLPT_STATE_USER_PACKAGES: {
+ ok = 1;
+ plpdftex_write_textline(job, plpdftex_c8_kw[6]);
+ plpdftex_write_required_packages(job);
+ plpdftex_write_textline(job, plpdftex_c8_kw[9]);
+ plpdftex_write_textline(job, plpdftex_c8_kw[10]);
+ plpdftex_open_picture_set(job);
+ plpdftex_close_picture_set(job);
+ job->state = PLPT_STATE_AFTER_DOCUMENT;
+ } break;
+ case PLPT_STATE_USER_SETUP: {
+ ok = 1;
+ plpdftex_write_textline(job, plpdftex_c8_kw[10]);
+ plpdftex_open_picture_set(job);
+ plpdftex_close_picture_set(job);
+ job->state = PLPT_STATE_AFTER_DOCUMENT;
+ } break;
+ case PLPT_STATE_IN_DOCUMENT: {
+ ok = 1;
+ plpdftex_close_picture_set(job);
+ job->state = PLPT_STATE_AFTER_DOCUMENT;
+ } break;
+ case PLPT_STATE_AFTER_DOCUMENT: {
+ ok = 1;
+ } break;
+ default: {
+ /* ERROR: Too late */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 12);
+ goto finished;
+ } break;
+ }
+ } else {
+ switch (job->state) {
+ case PLPT_STATE_NO_OUTPUT_YET:
+ case PLPT_STATE_DOCUMENT_CLASS:
+ case PLPT_STATE_USER_FONT_SETUP:
+ case PLPT_STATE_USER_PACKAGES:
+ case PLPT_STATE_USER_SETUP: {
+ plpdftex_open_picture_set(job);
+ plpdftex_close_picture_set(job);
+ job->state = PLPT_STATE_AFTER_DOCUMENT;
+ } break;
+ case PLPT_STATE_IN_DOCUMENT: {
+ ok = 1;
+ plpdftex_close_picture_set(job);
+ job->state = PLPT_STATE_AFTER_DOCUMENT;
+ } break;
+ case PLPT_STATE_AFTER_DOCUMENT: {
+ ok = 1;
+ } break;
+ default: {
+ /* ERROR: Too late */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 12);
+ goto finished;
+ } break;
+ }
+ }
+
+ finished:
+ if (0 == ok) {
+ job->exc = 1;
+
+#line 2582 "plpdftex.ctr"
+ }
+
+#line 2583 "plpdftex.ctr"
+}
+
+
+
+/** Open PDF and TeX output file, create output structures
+ and process all input.
+ @param job Job structure.
+*/
+static
+void
+plpdftex_run_with_output_filenames(plpdftex_job_t *job)
+{
+ unsigned long w;
+ unsigned long h;
+
+
+#line 2598 "plpdftex.ctr"
+ if (fgets(job->ilbuf, (int)(job->szilb), job->infi)) {
+ if (sscanf(job->ilbuf, "%lu %lu", &w, &h) == 2) {
+ job->imgw = w; job->imgh = h;
+ if (((unsigned long)DK3_L_MAX >= w) && ((unsigned long)DK3_L_MAX >= h)) {
+ job->fotex = dk3sf_c8_fopen_app(job->fntex, "w", job->app);
+ if (NULL != job->fotex) {
+ job->fopdf = dk3sf_c8_fopen_app(job->fnpdf, "wb", job->app);
+ if (NULL != job->fopdf) {
+ job->opdf = dk3pdf_open_app(job->app);
+ if (NULL != job->opdf) {
+ dk3pdf_set_next_mediabox(job->opdf, 0L, (long)w, 0L, (long)h);
+ if (0 != dk3pdf_open_page_with_clip(job->opdf, 1)) {
+ job->exc = 0;
+
+#line 2611 "plpdftex.ctr"
+ plpdftex_run_for_input(job);
+ if (0 == dk3pdf_close_page(job->opdf)) {
+ job->exc = 1;
+
+#line 2614 "plpdftex.ctr"
+ /* ERROR: Failed to close PDF page */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 11);
+ }
+ } else {
+ /* ERROR: Failed to open a PDF page */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 10);
+ }
+ if (0 == dk3pdf_write_file(job->opdf, job->fopdf)) {
+ job->exc = 1;
+
+#line 2623 "plpdftex.ctr"
+ /* ERROR: Failed to write PDF to file! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 9);
+ }
+ dk3pdf_close(job->opdf); job->opdf = NULL;
+ } else {
+ /* Failed to open PDF output structure */
+ }
+ if (0 == dk3sf_fclose_app(job->fopdf, job->app)) {
+ job->exc = 1;
+
+#line 2632 "plpdftex.ctr"
+ }
+ job->fopdf = NULL;
+ } else {
+ /* Failed to open PDF output file */
+ }
+ if (0 == dk3sf_fclose_app(job->fotex, job->app)) {
+ job->exc = 1;
+
+#line 2639 "plpdftex.ctr"
+ }
+ job->fotex = NULL;
+ } else {
+ /* Failed to open TeX output file */
+ }
+ } else {
+ /* Overflow, w or h too large! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 8);
+ }
+ } else {
+ /* ERROR: No w h */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 7);
+ }
+ } else {
+ /* ERROR: Missing w h line */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 6);
+ }
+
+#line 2656 "plpdftex.ctr"
+}
+
+
+
+/** Process input from file or stdin.
+ @param job Job structure.
+*/
+static
+void
+plpdftex_process_input(plpdftex_job_t *job)
+{
+ char *p1;
+
+
+#line 2669 "plpdftex.ctr"
+ if (fgets(job->ilbuf, (int)(job->szilb), job->infi)) {
+ p1 = dk3str_c8_start(job->ilbuf, NULL);
+ if (p1) {
+ dk3str_c8_chomp(job->ilbuf, NULL);
+ if (dk3str_c8_len(job->ilbuf) < job->szfn) {
+ dk3str_c8_cpy(job->fnb1, job->ilbuf);
+ dk3str_c8_cpy(job->fnpdf, job->ilbuf);
+ p1 = dk3str_c8_get_suffix(job->fnpdf);
+ if (p1) { *p1 = '\0'; }
+ dk3str_c8_cpy(job->fntex, job->fnpdf);
+ if (
+ (dk3str_c8_len(job->fnpdf)+dk3str_c8_len(plpdftex_c8_kw[0]))
+ < job->szfn
+ )
+ {
+ dk3str_c8_cat(job->fnpdf, plpdftex_c8_kw[0]);
+ dk3str_c8_cat(job->fntex, plpdftex_c8_kw[1]);
+ p1 = dk3str_c8_get_suffix(job->fnb1);
+ if (p1) {
+ p1++;
+ switch (dk3str_c8_array_index(pldftex_output_file_suffixes,p1,0)) {
+ case 0: {
+ /* pdf + tex for inclusion */
+ plpdftex_run_with_output_filenames(job);
+ } break;
+ case 1: {
+ /* standalone pdf + tex */
+ job->stagr = 1;
+ plpdftex_run_with_output_filenames(job);
+ } break;
+ default: {
+ /* ERROR: Invalid file name */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 5);
+ } break;
+ }
+ }
+ } else {
+ /* ERROR: File name too long! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 4);
+ }
+ } else {
+ /* ERROR: File name too long in first input line */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 4);
+ }
+ } else {
+ /* ERROR: Syntax error, first line must not be empty */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 3);
+ }
+ }
+
+#line 2718 "plpdftex.ctr"
+}
+
+
+
+/** Process input.
+ @param job Job structure.
+*/
+static
+void
+plpdftex_run_processing(plpdftex_job_t *job)
+{
+ dk3_dir_t *fne;
+ dkChar const *fnpattern;
+ dkChar const *fn;
+ dk3_um_t nfiles;
+ int numargs;
+
+
+#line 2735 "plpdftex.ctr"
+ numargs = dk3opt_get_num_args(job->opt);
+ switch (numargs) {
+ case 0: {
+ job->infi = stdin;
+ plpdftex_process_input(job);
+ } break;
+ case 1: {
+ fnpattern = dk3opt_get_arg(job->opt, 0);
+ if (fnpattern) {
+ if (dk3sf_must_expand(fnpattern)) {
+ fne = dk3dir_fne_open_app(fnpattern, job->app);
+ if (fne) {
+ nfiles = dk3dir_get_number_of_files(fne);
+ if (nfiles) {
+ if (DK3_UM_1 == nfiles) {
+ if (dk3dir_get_next_file(fne)) {
+ fn = dk3dir_get_fullname(fne);
+ if (fn) {
+ job->infi = dk3sf_fopen_app(fn, dkT("r"), job->app);
+ if (job->infi) {
+ plpdftex_process_input(job);
+ fclose(job->infi); job->infi = NULL;
+ }
+ } else {
+ /* ERROR: Must not happen */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 166);
+ }
+ } else {
+ /* ERROR: Must not happen */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 166);
+ }
+ } else {
+ /* ERROR: Too many file names match pattern! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 168, 169, fnpattern);
+ }
+ } else {
+ /* ERROR: No files match pattern */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 215, 216, fnpattern);
+ }
+ dk3dir_close(fne);
+ }
+ } else {
+ job->infi = dk3sf_fopen_app(fnpattern, dkT("r"), job->app);
+ if (job->infi) {
+ plpdftex_process_input(job);
+ fclose(job->infi); job->infi = NULL;
+ }
+ }
+ } else {
+ /* ERROR: Something wrong with options */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 2);
+ }
+ } break;
+ default: {
+ /* ERROR: One argument is maximum */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 1);
+ } break;
+ }
+
+#line 2793 "plpdftex.ctr"
+}
+
+
+
+/** Run.
+ @param job Job structure.
+*/
+static
+void
+plpdftex_run(plpdftex_job_t *job)
+{
+ int cmd; /* Command to execute */
+
+
+#line 2806 "plpdftex.ctr"
+ job->opt = dk3opt_open_from_app(
+ plpdftex_options, sz_plpdftex_options, dkT('\0'), NULL, job->app
+ );
+ if (job->opt) {
+ if (0 == dk3opt_get_error_code(job->opt)) {
+ cmd = 0;
+ if(dk3opt_is_set(job->opt, dkT('h'))) {
+ cmd |= DK3_APP_CMD_HELP;
+ }
+ if(dk3opt_is_set(job->opt, dkT('v'))) {
+ cmd |= DK3_APP_CMD_VERSION;
+ }
+ if(dk3opt_is_set(job->opt, dkT('l'))) {
+ cmd |= DK3_APP_CMD_LICENSE;
+ }
+ if (cmd) {
+ dk3sf_initialize_stdout();
+ /* Show version */
+ if (cmd & DK3_APP_CMD_VERSION) {
+ dk3sf_fputs(plpdftex_version, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ if (cmd & DK3_APP_CMD_LICENSE) {
+ /* Show license */
+ dk3sf_fputt(plpdftex_license_text, stdout);
+ }
+ if (cmd & DK3_APP_CMD_HELP) {
+ /* Show help */
+ dk3app_help(job->app, dkT("plpdftex.txt"), plpdftex_text_help);
+ }
+ job->exc = 0;
+
+#line 2837 "plpdftex.ctr"
+ } else {
+ /* Run normally */
+ plpdftex_run_processing(job);
+ }
+ }
+ }
+
+#line 2843 "plpdftex.ctr"
+}
+
+
+
+/** File name as read from input.
+*/
+static char plpdftex_input_filename[DK3_MAX_PATH];
+
+
+
+/** PDF output file name.
+*/
+static char plpdftex_pdf_filename[DK3_MAX_PATH];
+
+
+
+/** TeX output file name.
+*/
+static char plpdftex_tex_filename[DK3_MAX_PATH];
+
+
+
+/** Input line buffer (one line from input file).
+*/
+static char plpdftex_input_buffer[1024];
+
+
+
+/** Main function, entry point of the program.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, any other value indicates an error.
+*/
+DK3_MAIN
+{
+ plpdftex_job_t job; /* Job structure. */
+ int check_presence = 0; /* Flag: Just presence check. */
+ int exit_code = 1; /* Exit code returned to OS. */
+
+
+
+#line 2883 "plpdftex.ctr"
+
+
+#line 2884 "plpdftex.ctr"
+ if (2 == argc) {
+ if (dk3str_cmp(argv[1], plpdftex_check_presence) == 0) {
+ check_presence = 1;
+ }
+ }
+ if (check_presence) {
+ fputs(plpdftex_protocol, stdout);
+ exit_code = 0;
+ } else {
+ plpdftex_job_init(&job);
+ job.fnb1 = plpdftex_input_filename;
+ job.fnpdf = plpdftex_pdf_filename;
+ job.fntex = plpdftex_tex_filename;
+ job.szfn = DK3_MAX_PATH;
+ job.ilbuf = plpdftex_input_buffer;
+ job.szilb = sizeof(plpdftex_input_buffer);
+ job.app = dk3app_open_command(
+ argc, (dkChar const * const *)argv, plpdftex_group_name
+ );
+ if (job.app) {
+ job.msg = dk3app_messages(
+ job.app, dkT("plpdftex.str"), (dkChar const **)plpdftex_kw
+ );
+ job.sco = dk3sto_open_app(job.app);
+ if (job.sco) {
+ job.sico = dk3sto_it_open(job.sco);
+ if (job.sico) {
+ plpdftex_run(&job);
+ }
+ }
+ }
+ exit_code = job.exc;
+ plpdftex_job_cleanup(&job);
+ }
+
+
+#line 2919 "plpdftex.ctr"
+
+
+#line 2920 "plpdftex.ctr"
+ fflush(stdout);
+ exit(exit_code); return exit_code;
+}
+
diff --git a/support/dktools/plpdftex.ctr b/support/dktools/plpdftex.ctr
new file mode 100644
index 0000000000..d3a8fbd31f
--- /dev/null
+++ b/support/dktools/plpdftex.ctr
@@ -0,0 +1,2923 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2014-xxxx
+license = bsd
+
+%% header
+
+#include "dk3all.h"
+
+
+
+/** Current state of the program.
+*/
+enum {
+
+ /** No output produced yet.
+ */
+ PLPT_STATE_NO_OUTPUT_YET = 0,
+
+ /** Document class line written.
+ */
+ PLPT_STATE_DOCUMENT_CLASS,
+
+ /** Lines of user-specified font setup written.
+ */
+ PLPT_STATE_USER_FONT_SETUP,
+
+ /** Lines of user-specified usepackage instructions written.
+ */
+ PLPT_STATE_USER_PACKAGES,
+
+ /** User-specified setup lines were written.
+ */
+ PLPT_STATE_USER_SETUP,
+
+ /** The begin document line was written, contents may be added.
+ */
+ PLPT_STATE_IN_DOCUMENT,
+
+ /** Finished, the end document line was written.
+ */
+ PLPT_STATE_AFTER_DOCUMENT
+
+};
+
+
+
+/** Job structure for the plpdftex program.
+*/
+typedef struct {
+ dk3_app_t *app; /**< Application structure. */
+ dkChar const * const *msg; /**< Localized messages texts. */
+ dkChar const * const *kwnl; /**< Keywords not localized. */
+ dkChar const * const *argv; /**< Command line arguments array. */
+ dkChar const *infn; /**< Input file name. */
+ dk3_sto_t *sco; /**< Storage for colors. */
+ dk3_sto_it_t *sico; /**< Storage iterator for colors. */
+ char *fnb1; /**< File name as read from input. */
+ char *fnpdf; /**< File name, PDF output file. */
+ char *fntex; /**< File name, TeX output file. */
+ char *ilbuf; /**< Input line buffer. */
+ dk3_option_set_t *opt; /**< Options. */
+ dk3_pdf_t *opdf; /**< PDF output structure. */
+ FILE *infi; /**< Input file. */
+ FILE *fopdf; /**< PDF output file. */
+ FILE *fotex; /**< TeX output file. */
+ long imgw; /**< Image width. */
+ long imgh; /**< Image height. */
+ size_t szfn; /**< File name buffer size. */
+ size_t szilb; /**< Size of input line buffer. */
+ int state; /**< Current program state. */
+ int exc; /**< Exit code. */
+ int argc; /**< Number of command line arguments. */
+ int stagr; /**< Flag: Produce standalone graphics. */
+} plpdftex_job_t;
+
+
+
+/** Named color.
+*/
+typedef struct {
+ char const *name; /**< Color name. */
+ double r; /**< Red. */
+ double g; /**< Green. */
+ double b; /**< Blue. */
+} plpt_named_color_t;
+
+
+#include "plptcol.h"
+
+
+
+%% module
+
+#include "dk3all.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4vers.h"
+#include "dkt.h"
+#include "dk3pdf.h"
+#include "plpdftex.h"
+
+#include <stdio.h>
+
+
+
+$!trace-include
+
+
+
+/** Option to check for the presence of the program.
+*/
+static dkChar const plpdftex_check_presence[] = { dkT("--check-presence") };
+
+/** Protocol version to issue as response to a presence check.
+*/
+#if VERSION_BEFORE_20140924
+static dkChar const plpdftex_protocol[] = { dkT("1\n") };
+#else
+static char const plpdftex_protocol[] = { "1\n" };
+#endif
+
+/** Application group name.
+*/
+static dkChar const plpdftex_group_name[] = { dkT("dktools") };
+
+/** DK tools version number.
+*/
+static dkChar const plpdftex_version[] = { DKT_VERSION_DK };
+
+
+
+/** Default help text shown if help file is not found.
+*/
+static dkChar const * const plpdftex_text_help[] = {
+$!text macro=dkT
+
+NAME
+
+ plpdftex - Plot into a combination of *.pdf/*.tex files.
+
+SYNOPSIS
+
+ plpdftex
+ plpdftex --check-presence
+ plpdftex --help
+ plpdftex --license-terms
+
+DESCRIPTION
+
+The program processes an incoming data stream containing both graphics
+instructions and text labels. Graphics instructions are written to a
+PDF file, text labels are written to a *.tex file.
+The *.tex file includes the PDF file containing the graphics and
+typesets the text labels on top of it.
+
+This program is not intended to be used directly, it is an output
+driver for the octpgfpl package for GNU Octave.
+
+
+OPTIONS
+
+-h Show this help text.
+--help
+
+-v Show version information.
+--version
+
+-l Show the license conditions.
+--license-terms
+
+--check-presence Print the protocol version, may be used to
+ check for the presence of the program.
+
+EXIT STATUS
+
+0 on success, all other exit status codes indicate an error.
+
+INPUT FILE
+
+Input is read from standard input.
+
+The first line specifies a file name combination. It must end on
+either ``.pdftex'' to produce a *.pdf/*.tex combination for inclusion
+in a LaTeX document or on ``.pdftexs'' to produce a *.pdf/*.tex
+combination for standalone processing.
+
+The second line contains two unsigned integer numbers, separated
+by spaces: Image width and height in PS/PDF points (known as bp in
+LaTeX).
+
+The remaining lines describe the image, there are ``t'' lines
+and ``p'' lines, i.e.
+
+t fs 12
+t font-setup \usepackage[T1]{fontenc}
+t package \usepackage[intlimit]{amsmath}
+t preamble \DeclareMathOperator{\intd}{\text{d}}
+t text 10 20 base left black This is a test.
+t text-box 10 20 base left red This is another test.
+p gsave
+p grestore
+p lw 3
+p buttcap
+p miterjoin
+p nodash
+p stroke-color blue!50!black
+p fill-color red!80!white
+p rectangle 5 5 200 80
+p circle 20 30 5
+p moveto 30 80
+p lineto 50 90
+p curveto 50 100 100 100 100 90
+p closepath
+p stroke
+p fill
+p clip
+
+The ``t fs'' ``t font-setup'', ``t package'' and ``t preamble''
+lines are only used when producing a *.pdf/*.tex file combination for
+standalone processing, otherwise they are ignored.
+
+``t fs'' specifies the font size for the documentclass line.
+This line must be used before ``t font-setup'', ``t package'', ``t preamble'',
+``t text'' or ``p'' lines. The line is optional, by default the documentclass
+is written without the font size specification.
+
+``t font-setup'' specifies usepackage and other instructions for font
+setup. These lines are optional, a default font setup section is used
+if no ``t font-setup'' lines are used. Any ``t font-setup'' lines
+must be used before ``t package'', ``t preamble'', ``t text'' or ``p''
+lines.
+
+``t preamble'' lines contain further setup instructions for the preamble,
+they are optional.
+
+``t text'' lines contain text labels to show. The line contains
+x position, y position, vertical alignment (bottom, base, centered,
+or top), horizontal alignment (left, centered, or right), color
+and the text to show.
+
+All color definitions must be LaTeX color strings like
+``blue!50!white''...
+
+``t text-box'' lines contain text labels to show. The line contains
+x position, y position, vertical alignment (bottom, base, centered,
+or top), horizontal alignment (left, centered, or right), color
+and the text to show.
+
+``p'' lines contain graphics instructions transferred to the PDF file.
+
+``p gsave'' saves the current graphics state.
+
+``p grestore'' restores the graphics state.
+
+``p lw'' sets the line width for stroking.
+
+``p buttcap'' sets line cap style to butted.
+
+``p miterjoin'' sets the line join style to miter.
+
+``p nodash'' sets up contiguous line style.
+
+``p stroke-color'' sets the stroke color.
+
+``p fill-color'' sets the fill color.
+
+``p rectangle'' creates a rectangular path, specify start x position,
+start y position, end x position and end y position.
+
+``p circle'' creates a circular path, specify center x position,
+center y position and radius.
+
+``p moveto'' starts a new path and moves the current position
+to the specified x and y position.
+
+``p lineto'' adds a line segment from the current position to the specified
+x and y position to the path.
+
+``p curveto'' adds a Bezier segment starting at the current position
+to the path. Specify x and y position of the first control point,
+x and y position of the second control point and x and y position
+of the final point.
+
+``p closepath'' closes the current path.
+
+``p stroke'' strokes the current path.
+
+``p fill'' fills the current path.
+
+``p clip'' uses the current path as clip path.
+
+
+OUTPUT FILES
+
+The output file names are determined from the first input line.
+
+NOTES
+
+The plpdftex program does not support all features of PDF/TeX file pairs,
+it is only intended as an output driver for the pgfplot() instruction
+in the octpgfpl package for GNU Octave.
+
+RESTRICTIONS
+
+Color definitions for plpdftex must only contain color names ``white'',
+``black'', ``red'', ``green'', ``blue'', ``cyan'', ``magenta'', ``yellow'',
+``gray'', ``lightgray'', ``darkgray'', ``brown'', ``lime'', ``olive'',
+``orange'', ``pink'', ``purple'', ``teal'', ``violet'' and combinations
+like ``red!50!black''.
+
+AUTHOR
+
+Dirk Krause
+
+COPYRIGHT AND LICENSE
+
+Run
+ plpdftex -l
+to see the license conditions.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+http://octpgfpl.sourceforge.net
+
+$!end
+};
+
+
+
+/** License conditions.
+*/
+static dkChar const * const plpdftex_license_text[] = {
+$!text macro=dkT
+
+Copyright (c) 2014-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the copyright holder(s) nor the names of
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+$!end
+};
+
+
+static dkChar const * const plpdftex_kw[] = {
+$!string-table macro=dkT
+#
+# 0 Program name
+#
+plpdftex
+#
+# 1
+#
+Too many command line arguments, just one input file name allowed!
+#
+# 2
+#
+Failed to retrieve first command line argument (probably a bug)!
+#
+# 3
+#
+Output file names missing in first line!
+#
+# 4
+#
+File name too long in first line!
+#
+# 5
+#
+Wrong file name suffix, must be *.pdftex or *.pdftexs!
+#
+# 6
+#
+Missing second line, containing width and height!
+#
+# 7
+#
+Failed to retrieve width and height!
+#
+# 8
+#
+Numeric overflow, width and/or height too large!
+#
+# 9
+#
+Failed to write PDF data to file!
+#
+# 10
+#
+Failed to open PDF page!
+#
+# 11
+#
+Failed to close PDF page!
+#
+# 12
+#
+Syntax error, document already closed!
+#
+# 13
+#
+Syntax error, line not started by ``t'', ``p'', or ``#''!
+#
+# 14
+#
+Syntax error, missing command!
+#
+# 15
+#
+PDF clip operation failed!
+#
+# 16
+#
+PDF fill operation failed!
+#
+# 17
+#
+PDF stroke operation failed!
+#
+# 18
+#
+PDF closepath operation failed!
+#
+# 19
+#
+PDF curveto operation failed!
+#
+# 20
+#
+Syntax error, numeric value expected!
+#
+# 21
+#
+Syntax error, too few arguments for command!
+#
+# 22
+#
+PDF moveto operation failed!
+#
+# 23
+#
+Syntax error, radius is negative!
+#
+# 24
+#
+PDF lineto operation failed!
+#
+# 25
+#
+PDF set nonstroking color operation failed!
+#
+# 26
+#
+No such color!
+#
+# 27
+#
+PDF set stroking color operation failed!
+#
+# 28
+#
+PDF set dash operation failed!
+#
+# 29
+#
+PDF set linejoin operation failed!
+#
+# 30
+#
+PDF set linecap operation failed!
+#
+# 31
+#
+Syntax error, linewidth negative!
+#
+# 32
+#
+PDF set linewidth operation failed!
+#
+# 33
+#
+PDF grestore operation failed!
+#
+# 34
+#
+PDF gsave operation failed!
+#
+# 35
+#
+Write operation failed to TeX output file!
+#
+# 36
+#
+Syntax error, invalid horizontal alignment specification!
+#
+# 37
+#
+Syntax error, invalid horizontal alignment specification!
+#
+# 38
+#
+Syntax error, order must be fs, font-setup, package, preamble, text!
+$!end
+};
+
+
+
+/** 8 bit strings
+*/
+static char const * const plpdftex_c8_kw[] = {
+$!string-table
+#
+# 0 1 Output file name suffixes
+#
+-i.pdf
+.tex
+#
+# 2
+#
+\\documentclass{article}
+#
+# 3 4
+#
+% font setup (begin)
+% font setup (end)
+#
+# 5 6
+#
+% other packages (begin)
+% other packages (end)
+#
+# 7 8
+#
+\\setlength{\\paperwidth}{%ldbp}\n
+\\setlength{\\paperheight}{%ldbp}\n
+#
+# 9 10
+#
+% user-specific setup instructions (begin)
+% user-specific setup instructions (end)
+#
+# 11
+#
+\\begin{document}%
+#
+# 12 13 14 15 16
+#
+\\begin{picture}(0,0)%
+\\includegraphics{
+}%
+\\end{picture}%
+\\setlength{\\unitlength}{1bp}%
+#
+# 17 18
+#
+\\begin{picture}(%ld,%ld)%\n
+\\end{document}
+#
+# 19 20 21 22
+#
+\\put(%g,%g){\\makebox(0,0)
+[
+]
+{\\smash{{\\color{%s}%s}}}}\n
+#
+# 23
+#
+{\\colorbox{white}{\\color{%s}\\ovalbox{%s}}}}\n
+#
+# 24
+#
+{{\\color{%s}%s}}}\n
+$!end
+};
+
+
+
+/** Default font setup.
+*/
+static char const * const plpdftex_default_font_setup[] = {
+$!string-table
+% begin font setup
+\\usepackage[T1]{fontenc}
+\\usepackage{textcomp}
+\\usepackage{mathptmx}
+\\usepackage[scaled=.92]{helvet}
+\\usepackage{courier}
+% end font setup
+$!end
+};
+
+
+
+/** Default additional packages.
+*/
+static char const * const plpdftex_default_packages[] = {
+$!string-table
+% other packages (begin)
+\\usepackage{textcomp}
+\\usepackage[intlimits]{amsmath}
+% other packages (end)
+$!end
+};
+
+
+
+static char const * const plpdftex_required_packages[] = {
+$!string-table
+% required packages (begin)
+\\usepackage{fancybox}
+\\usepackage{graphicx}
+\\usepackage{xcolor}
+% required packages (end)
+% required instructions (begin)
+$!end
+};
+
+
+
+
+static char const * const plpdftex_required_instructions[] = {
+$!string-table
+\\pagestyle{empty}
+\\setlength{\\voffset}{-1in}
+\\setlength{\\topmargin}{0bp}
+\\setlength{\\headheight}{0bp}
+\\setlength{\\headsep}{0bp}
+\\setlength{\\topskip}{0bp}
+\\setlength{\\hoffset}{-1in}
+\\setlength{\\oddsidemargin}{0bp}
+\\setlength{\\evensidemargin}{0bp}
+\\setlength{\\marginparwidth}{0bp}
+\\setlength{\\marginparsep}{0bp}
+\\setlength{\\textwidth}{\\paperwidth}
+\\setlength{\\textheight}{\\paperheight}
+\\setlength{\\parskip}{0bp}
+\\setlength{\\parindent}{0bp}
+\\setlength{\\pdfpagewidth}{\\paperwidth}
+\\setlength{\\pdfpageheight}{\\paperheight}
+% required instructions (end)
+$!end
+};
+
+
+
+/** Output file suffixes.
+*/
+static char const * const pldftex_output_file_suffixes[] = {
+$!string-table
+pdftex
+pdftexs
+$!end
+};
+
+
+
+/** Instruction names in TeX lines.
+*/
+static char const * const plpdftex_tex_instructions[] = {
+$!string-table
+#
+# 0
+#
+fs
+#
+# 1
+#
+font-setup
+#
+# 2
+#
+package
+#
+# 3
+#
+preamble
+#
+# 4
+#
+text
+#
+# 5
+#
+text-box
+$!end
+};
+
+
+
+/** Instruction names in PDF instructions.
+*/
+static char const * const plpdftex_pdf_instructions[] = {
+$!string-table
+#
+# 0
+#
+gsave
+#
+# 1
+#
+grestore
+#
+# 2
+#
+lw
+#
+# 3
+#
+buttcap
+#
+# 4
+#
+miterjoin
+#
+# 5
+#
+nodash
+#
+# 6
+#
+stroke-color
+#
+# 7
+#
+fill-color
+#
+# 8
+#
+rectangle
+#
+# 9
+#
+circle
+#
+# 10
+#
+moveto
+#
+# 11
+#
+lineto
+#
+# 12
+#
+curveto
+#
+# 13
+#
+closepath
+#
+# 14
+#
+stroke
+#
+# 15
+#
+fill
+#
+# 16
+#
+clip
+$!end
+};
+
+
+
+/** Vertical alignments.
+*/
+char const * const plpdftex_vertical_alignments[] = {
+"top", "centered", "base", "bottom", NULL
+};
+
+
+
+/** Horizontal alignments.
+*/
+char const * const plpdftex_horizontal_alignments[] = {
+"left", "centered", "right", NULL
+};
+
+
+
+/** Options expected by the program.
+*/
+static dk3_option_t const plpdftex_options[] = {
+ { dkT('h'), dkT("help"), 0 },
+ { dkT('v'), dkT("version"), 0 },
+ { dkT('l'), dkT("license-terms"), 0 }
+};
+
+
+
+/** Number of options in plpdftex_options array.
+*/
+static size_t const sz_plpdftex_options =
+sizeof(plpdftex_options)/sizeof(dk3_option_t);
+
+
+
+/** Initialize job structure.
+ @param jptr Job to initialize.
+*/
+static
+void
+plpdftex_job_init(plpdftex_job_t *jptr)
+{
+ $? "+ plpdftex_job_init"
+ jptr->app = NULL;
+ jptr->msg = NULL;
+ jptr->kwnl = NULL;
+ jptr->exc = 1; $? ". exc 1"
+ jptr->argc = 0;
+ jptr->argv = NULL;
+ jptr->infn = NULL;
+ jptr->opt = NULL;
+ jptr->infi = NULL;
+ jptr->fnb1 = NULL;
+ jptr->fnpdf = NULL;
+ jptr->fntex = NULL;
+ jptr->opdf = NULL;
+ jptr->fopdf = NULL;
+ jptr->fotex = NULL;
+ jptr->szfn = 0;
+ jptr->ilbuf = NULL;
+ jptr->szilb = 0;
+ jptr->stagr = 0;
+ jptr->state = PLPT_STATE_NO_OUTPUT_YET;
+ jptr->sco = NULL;
+ jptr->sico = NULL;
+ jptr->imgw = 0UL;
+ jptr->imgh = 0UL;
+ $? "- plpdftex_job_init"
+}
+
+
+
+/** Clean up job structure before exiting the program.
+ @param jptr Job structure to clean up.
+*/
+static
+void
+plpdftex_job_cleanup(plpdftex_job_t *jptr)
+{
+ plpt_named_color_t *colptr;
+ $? "+ plpdftex_job_cleanup"
+ if (jptr->sico) {
+ dk3sto_it_reset(jptr->sico);
+ do {
+ colptr = (plpt_named_color_t *)dk3sto_it_next(jptr->sico);
+ if (colptr) {
+ plptcolor_delete(colptr);
+ }
+ } while (colptr);
+ dk3sto_it_close(jptr->sico);
+ } jptr->sico = NULL;
+ if (jptr->sco) {
+ dk3sto_close(jptr->sco);
+ } jptr->sco = NULL;
+ jptr->msg = NULL;
+ jptr->kwnl = NULL;
+ if (jptr->opt) {
+ dk3opt_close(jptr->opt);
+ }
+ jptr->opt = NULL;
+ if (jptr->app) {
+ dk3app_close(jptr->app);
+ }
+ jptr->app = NULL;
+ $? "- plpdftex_job_cleanup"
+}
+
+
+
+/** Process font size line.
+ @param job Job structure.
+ @param txt Text line to process.
+*/
+static
+void
+plpdftex_process_tex_fontsize(plpdftex_job_t *job, char *txt)
+{
+ double fs = 10.0;
+ int ok = 0;
+ $? "+ plpdftex_process_tex_fontsize"
+ if (NULL == txt) {
+ /* ERROR: No text */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+ if (0 == dk3ma_d_from_c8_string(&fs, txt, NULL)) {
+ /* ERROR: Not a number */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ goto finished;
+ }
+ if (0 == job->stagr) {
+ ok = 1;
+ goto finished;
+ }
+ switch (job->state) {
+ case PLPT_STATE_NO_OUTPUT_YET: {
+ ok = 1;
+ job->state = PLPT_STATE_DOCUMENT_CLASS;
+ fprintf(job->fotex, "\\documentclass[%gpt]{article}\n", fs);
+ } break;
+ default: {
+ /* ERROR: Too late */
+ ok = 1;
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 38);
+ goto finished;
+ } break;
+ }
+ finished:
+ if (0 == ok) {
+ job->exc = 1; $? ". exc 1"
+ } $? "- plpdftex_process_tex_fontsize"
+}
+
+
+
+static
+void
+plpdftex_write_textline(plpdftex_job_t *job, char const *txt)
+{
+ $? "+ plpdftex_write_textline"
+ if (EOF == fputs(txt, job->fotex)) {
+ /* Write error */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ job->exc = 1; $? ". exc 1"
+ }
+ if (EOF == fputc('\n', job->fotex)) {
+ job->exc = 1; $? ". exc 1"
+ } $? "- plpdftex_write_textline"
+}
+
+
+
+/** Process font setup line.
+ @param job Job structure.
+ @param txt Text line to process.
+*/
+static
+void
+plpdftex_process_tex_font_setup(plpdftex_job_t *job, char *txt)
+{
+ int ok = 0;
+ $? "+ plpdftex_process_tex_font_setup"
+ if (0 == job->stagr) {
+ ok = 1;
+ goto finished;
+ }
+ if (NULL == txt) {
+ /* ERROR: Not text */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+ switch (job->state) {
+ case PLPT_STATE_NO_OUTPUT_YET: {
+ ok = 1;
+ /* documentclass{article} */
+ plpdftex_write_textline(job, plpdftex_c8_kw[2]);
+ /* font setup (begin) */
+ plpdftex_write_textline(job, plpdftex_c8_kw[3]);
+ plpdftex_write_textline(job, txt);
+ job->state = PLPT_STATE_USER_FONT_SETUP;
+ } break;
+ case PLPT_STATE_DOCUMENT_CLASS: {
+ ok = 1;
+ /* font setup (begin) */
+ plpdftex_write_textline(job, plpdftex_c8_kw[3]);
+ plpdftex_write_textline(job, txt);
+ job->state = PLPT_STATE_USER_FONT_SETUP;
+ } break;
+ case PLPT_STATE_USER_FONT_SETUP: {
+ ok = 1;
+ plpdftex_write_textline(job, txt);
+ } break;
+ default: {
+ /* ERROR: Too late */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 38);
+ }
+ }
+
+ finished:
+ if (0 == ok) {
+ job->exc = 1; $? ". exc 1"
+ } $? "- plpdftex_process_tex_font_setup"
+}
+
+
+
+static
+void
+plpdftex_write_default_font_setup(plpdftex_job_t *job)
+{
+ char const * const *ptr;
+ $? "+ plpdftex_write_default_font_setup"
+ ptr = plpdftex_default_font_setup;
+ while (NULL != *ptr) {
+ plpdftex_write_textline(job, *(ptr++));
+ } $? "- plpdftex_write_default_font_setup"
+}
+
+
+
+static
+void
+plpdftex_write_default_packages(plpdftex_job_t *job)
+{
+ char const * const *ptr;
+ $? "+ plpdftex_write_default_packages"
+ ptr = plpdftex_default_packages;
+ while (NULL != *ptr) {
+ plpdftex_write_textline(job, *(ptr++));
+ } $? "- plpdftex_write_default_packages"
+}
+
+
+
+static
+void
+plpdftex_write_required_packages(plpdftex_job_t *job)
+{
+ char const * const *ptr;
+ $? "+ plpdftex_write_required_packages"
+ ptr = plpdftex_required_packages;
+ while (NULL != *ptr) {
+ plpdftex_write_textline(job, *(ptr++));
+ }
+
+ fprintf(job->fotex, plpdftex_c8_kw[7], job->imgw);
+ fprintf(job->fotex, plpdftex_c8_kw[8], job->imgh);
+
+ ptr = plpdftex_required_instructions;
+ while (NULL != *ptr) {
+ plpdftex_write_textline(job, *(ptr++));
+ }
+ $? "- plpdftex_write_required_packages"
+}
+
+
+
+/** Process package selection line.
+ @param job Job structure.
+ @param txt Text line to process.
+*/
+static
+void
+plpdftex_process_tex_package(plpdftex_job_t *job, char *txt)
+{
+ int ok = 0;
+ $? "+ plpdftex_process_tex_package"
+ if (0 == job->stagr) {
+ ok = 1;
+ goto finished;
+ }
+ if (NULL == txt) {
+ /* ERROR: Missing text */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+ switch (job->state) {
+ case PLPT_STATE_NO_OUTPUT_YET: {
+ ok = 1;
+ /* documentclass{article} */
+ plpdftex_write_textline(job, plpdftex_c8_kw[2]);
+ plpdftex_write_default_font_setup(job);
+ plpdftex_write_textline(job, plpdftex_c8_kw[5]);
+ plpdftex_write_textline(job, txt);
+ job->state = PLPT_STATE_USER_PACKAGES;
+ } break;
+ case PLPT_STATE_DOCUMENT_CLASS: {
+ ok = 1;
+ plpdftex_write_default_font_setup(job);
+ plpdftex_write_textline(job, plpdftex_c8_kw[5]);
+ plpdftex_write_textline(job, txt);
+ job->state = PLPT_STATE_USER_PACKAGES;
+ } break;
+ case PLPT_STATE_USER_FONT_SETUP: {
+ ok = 1;
+ plpdftex_write_textline(job, plpdftex_c8_kw[4]);
+ plpdftex_write_textline(job, plpdftex_c8_kw[5]);
+ plpdftex_write_textline(job, txt);
+ job->state = PLPT_STATE_USER_PACKAGES;
+ } break;
+ case PLPT_STATE_USER_PACKAGES: {
+ ok = 1;
+ plpdftex_write_textline(job, txt);
+ } break;
+ }
+ finished:
+ if (0 == ok) {
+ job->exc = 1; $? ". exc 1"
+ } $? "- plpdftex_process_tex_package"
+}
+
+
+
+/** Process preamble line.
+ @param job Job structure.
+ @param txt Text line to process.
+*/
+static
+void
+plpdftex_process_tex_preamble(plpdftex_job_t *job, char *txt)
+{
+ int ok = 0;
+ $? "+ plpdftex_process_tex_preamble"
+ if (0 == job->stagr) {
+ ok = 1;
+ goto finished;
+ }
+ if (NULL == txt) {
+ /* ERROR: No text */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+ switch (job->state) {
+ case PLPT_STATE_NO_OUTPUT_YET: {
+ ok = 1;
+ /* documentclass{article} */
+ plpdftex_write_textline(job, plpdftex_c8_kw[2]);
+ plpdftex_write_default_font_setup(job);
+ plpdftex_write_default_packages(job);
+ plpdftex_write_required_packages(job);
+ plpdftex_write_textline(job, plpdftex_c8_kw[9]);
+ plpdftex_write_textline(job, txt);
+ job->state = PLPT_STATE_USER_SETUP;
+ } break;
+ case PLPT_STATE_DOCUMENT_CLASS: {
+ ok = 1;
+ plpdftex_write_default_font_setup(job);
+ plpdftex_write_default_packages(job);
+ plpdftex_write_required_packages(job);
+ plpdftex_write_textline(job, plpdftex_c8_kw[9]);
+ plpdftex_write_textline(job, txt);
+ job->state = PLPT_STATE_USER_SETUP;
+ } break;
+ case PLPT_STATE_USER_FONT_SETUP: {
+ ok = 1;
+ plpdftex_write_textline(job, plpdftex_c8_kw[4]);
+ plpdftex_write_default_packages(job);
+ plpdftex_write_required_packages(job);
+ plpdftex_write_textline(job, plpdftex_c8_kw[9]);
+ plpdftex_write_textline(job, txt);
+ job->state = PLPT_STATE_USER_SETUP;
+ } break;
+ case PLPT_STATE_USER_PACKAGES: {
+ ok = 1;
+ plpdftex_write_textline(job, plpdftex_c8_kw[6]);
+ plpdftex_write_required_packages(job);
+ plpdftex_write_textline(job, plpdftex_c8_kw[9]);
+ plpdftex_write_textline(job, txt);
+ job->state = PLPT_STATE_USER_SETUP;
+ } break;
+ case PLPT_STATE_USER_SETUP: {
+ ok = 1;
+ plpdftex_write_textline(job, txt);
+ } break;
+ }
+
+ finished:
+ if (0 == ok) {
+ job->exc = 1; $? ". exc 1"
+ } $? "- plpdftex_process_tex_preamble"
+}
+
+
+
+/** Write start of TeX file.
+ @param job Job structure.
+*/
+static
+void
+plpdftex_open_picture_set(plpdftex_job_t *job)
+{
+ $? "+ plpdftex_open_picture_set"
+ if (0 != job->stagr) {
+ plpdftex_write_textline(job, plpdftex_c8_kw[11]);
+ }
+ plpdftex_write_textline(job, plpdftex_c8_kw[12]);
+ if (EOF == fputs(plpdftex_c8_kw[13], job->fotex)) {
+ /* ERROR: Write failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ job->exc = 1; $? ". exc 1"
+ }
+ if (EOF == fputs(job->fnpdf, job->fotex)) {
+ /* ERROR: Write failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ job->exc = 1; $? ". exc 1"
+ }
+ plpdftex_write_textline(job, plpdftex_c8_kw[14]);
+ plpdftex_write_textline(job, plpdftex_c8_kw[15]);
+ plpdftex_write_textline(job, plpdftex_c8_kw[16]);
+ if (0 >= fprintf(job->fotex, plpdftex_c8_kw[17], job->imgw, job->imgh)) {
+ /* ERROR: Write failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ job->exc = 1; $? ". exc 1"
+ } $? "- plpdftex_open_picture_set"
+}
+
+
+
+static
+void
+plpdftex_close_picture_set(plpdftex_job_t *job)
+{
+ $? "+ plpdftex_close_picture_set"
+ plpdftex_write_textline(job, plpdftex_c8_kw[15]);
+ if (0 != job->stagr) {
+ plpdftex_write_textline(job, plpdftex_c8_kw[18]);
+ } $? "- plpdftex_close_picture_set"
+}
+
+
+
+
+/** Process text label line.
+ @param job Job structure.
+ @param txt Text line to process.
+ @param withbox Flag: With box (1) or without box (0).
+*/
+static
+void
+plpdftex_process_tex_text(plpdftex_job_t *job, char *txt, int withbox)
+{
+ char *p1 = NULL; /* Y position */
+ char *p2 = NULL; /* Vertical alignment */
+ char *p3 = NULL; /* Horizontal alignment */
+ char *p4 = NULL; /* Color */
+ char *p5 = NULL; /* Label text */
+ double x = 0.0; /* X position */
+ double y = 0.0; /* Y position */
+ int av = 0; /* Vertical alignment */
+ int ah = 0; /* Horizontal alignment */
+ int ok = 0;
+ char c;
+ $? "+ plpdftex_process_tex_text"
+ /* Split strings.
+ */
+ if (NULL == txt) {
+ /* ERROR: No text */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+ p1 = dk3str_c8_next(txt, NULL);
+ if (NULL == p1) {
+ /* ERROR: No y position */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+ p2 = dk3str_c8_next(p1, NULL);
+ if (NULL == p2) {
+ /* ERROR: No vertical alignment */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+ p3 = dk3str_c8_next(p2, NULL);
+ if (NULL == p3) {
+ /* ERROR: No horizontal alignment */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+ p4 = dk3str_c8_next(p3, NULL);
+ if (NULL == p4) {
+ /* ERROR: No color */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+ p5 = dk3str_c8_next(p4, NULL);
+ if (NULL == p5) {
+ /* ERROR: No text */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+
+ /* Retrieve values from strings.
+ */
+ if (0 == dk3ma_d_from_c8_string(&x, txt, NULL)) {
+ /* ERROR: x value not numeric */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ goto finished;
+ }
+ if (0 == dk3ma_d_from_c8_string(&y, p1, NULL)) {
+ /* ERROR: y value not numeric */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ goto finished;
+ }
+ av = dk3str_c8_array_index(plpdftex_vertical_alignments, p2, 0);
+ if (0 > av) {
+ /* ERROR: Not a valid vertical alignment */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 37);
+ goto finished;
+ }
+ ah = dk3str_c8_array_index(plpdftex_horizontal_alignments, p3, 0);
+ if (0 > ah) {
+ /* ERROR: Not a valid horizontal alignment */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 36);
+ goto finished;
+ }
+
+ /* Write file header parts not yet written.
+ */
+ if (0 != job->stagr) {
+ switch (job->state) {
+ case PLPT_STATE_NO_OUTPUT_YET: {
+ ok = 1;
+ /* documentclass{article} */
+ plpdftex_write_textline(job, plpdftex_c8_kw[2]);
+ plpdftex_write_default_font_setup(job);
+ plpdftex_write_default_packages(job);
+ plpdftex_write_required_packages(job);
+ plpdftex_write_textline(job, plpdftex_c8_kw[9]);
+ plpdftex_write_textline(job, plpdftex_c8_kw[10]);
+ plpdftex_open_picture_set(job);
+ job->state = PLPT_STATE_IN_DOCUMENT;
+ } break;
+ case PLPT_STATE_DOCUMENT_CLASS: {
+ ok = 1;
+ plpdftex_write_default_font_setup(job);
+ plpdftex_write_default_packages(job);
+ plpdftex_write_required_packages(job);
+ plpdftex_write_textline(job, plpdftex_c8_kw[9]);
+ plpdftex_write_textline(job, plpdftex_c8_kw[10]);
+ plpdftex_open_picture_set(job);
+ job->state = PLPT_STATE_IN_DOCUMENT;
+ } break;
+ case PLPT_STATE_USER_FONT_SETUP: {
+ ok = 1;
+ plpdftex_write_textline(job, plpdftex_c8_kw[4]);
+ plpdftex_write_default_packages(job);
+ plpdftex_write_required_packages(job);
+ plpdftex_write_textline(job, plpdftex_c8_kw[9]);
+ plpdftex_write_textline(job, plpdftex_c8_kw[10]);
+ plpdftex_open_picture_set(job);
+ job->state = PLPT_STATE_IN_DOCUMENT;
+ } break;
+ case PLPT_STATE_USER_PACKAGES: {
+ ok = 1;
+ plpdftex_write_textline(job, plpdftex_c8_kw[6]);
+ plpdftex_write_required_packages(job);
+ plpdftex_write_textline(job, plpdftex_c8_kw[9]);
+ plpdftex_write_textline(job, plpdftex_c8_kw[10]);
+ plpdftex_open_picture_set(job);
+ job->state = PLPT_STATE_IN_DOCUMENT;
+ } break;
+ case PLPT_STATE_USER_SETUP: {
+ ok = 1;
+ plpdftex_write_textline(job, plpdftex_c8_kw[10]);
+ plpdftex_open_picture_set(job);
+ job->state = PLPT_STATE_IN_DOCUMENT;
+ } break;
+ case PLPT_STATE_IN_DOCUMENT: {
+ ok = 1;
+ } break;
+ default: {
+ /* ERROR: Too late */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 12);
+ goto finished;
+ } break;
+ }
+ } else {
+ switch (job->state) {
+ case PLPT_STATE_NO_OUTPUT_YET:
+ case PLPT_STATE_DOCUMENT_CLASS:
+ case PLPT_STATE_USER_FONT_SETUP:
+ case PLPT_STATE_USER_PACKAGES:
+ case PLPT_STATE_USER_SETUP:
+ {
+ ok = 1;
+ plpdftex_open_picture_set(job);
+ job->state = PLPT_STATE_IN_DOCUMENT;
+ } break;
+ case PLPT_STATE_IN_DOCUMENT: {
+ ok = 1;
+ } break;
+ default: {
+ /* ERROR: Too late */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 12);
+ goto finished;
+ } break;
+ }
+ }
+
+ /* Write text label.
+ */
+ if (1 == ok) {
+ if (1 == withbox) { $? ". text box"
+ /* put(%g,%g)makebox(0,0) */ $? ". 19"
+ if (0 >= fprintf(job->fotex, plpdftex_c8_kw[19], x, y)) {
+ /* ERROR: fprintf failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ ok = 0; goto finished;
+ }
+ /* Alignment */
+ if ((ah != 1) || (av != 1)) { $? ". alignment"
+ if (EOF == fputs(plpdftex_c8_kw[20], job->fotex)) {
+ /* ERROR: Write failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ ok = 0; goto finished;
+ }
+ c = '\0';
+ switch (ah) {
+ case 0: { c = 'l'; } break;
+ case 2: { c = 'r'; } break;
+ }
+ if ('\0' != c) {
+ if (EOF == fputc(c, job->fotex)) {
+ /* ERROR: Write failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ ok = 0; goto finished;
+ }
+ }
+ c = '\0';
+ switch (av) {
+ case 0: { c = 't'; } break;
+ case 2: case 3: { c = 'b'; } break;
+ }
+ if ('\0' != c) {
+ if (EOF == fputc(c, job->fotex)) {
+ /* ERROR: Write failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ ok = 0; goto finished;
+ }
+ }
+ if (EOF == fputs(plpdftex_c8_kw[21], job->fotex)) {
+ /* ERROR: Write failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ ok = 0; goto finished;
+ }
+ }
+ if (0 >= fprintf(job->fotex, plpdftex_c8_kw[23], p4, p5)) {
+ /* ERROR: Write failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ ok = 0; goto finished;
+ }
+ } else { $? ". text"
+ /* put(%g,%g)makebox(0,0) */ $? ". 19"
+ if (0 >= fprintf(job->fotex, plpdftex_c8_kw[19], x, y)) {
+ /* ERROR: fprintf failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ ok = 0; goto finished;
+ }
+ /* Alignment */
+ if ((ah != 1) || (av != 1)) { $? ". alignment"
+ if (EOF == fputs(plpdftex_c8_kw[20], job->fotex)) {
+ /* ERROR: Write failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ ok = 0; goto finished;
+ }
+ c = '\0';
+ switch (ah) {
+ case 0: { c = 'l'; } break;
+ case 2: { c = 'r'; } break;
+ }
+ if ('\0' != c) {
+ if (EOF == fputc(c, job->fotex)) {
+ /* ERROR: Write failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ ok = 0; goto finished;
+ }
+ }
+ c = '\0';
+ switch (av) {
+ case 0: { c = 't'; } break;
+ case 2: case 3: { c = 'b'; } break;
+ }
+ if ('\0' != c) {
+ if (EOF == fputc(c, job->fotex)) {
+ /* ERROR: Write failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ ok = 0; goto finished;
+ }
+ }
+ if (EOF == fputs(plpdftex_c8_kw[21], job->fotex)) {
+ /* ERROR: Write failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ ok = 0; goto finished;
+ }
+ }
+ if (2 == av) {
+ /* Use smash only for baseline vertical alignment */
+ if (0 >= fprintf(job->fotex, plpdftex_c8_kw[22], p4, p5)) {
+ /* ERROR: Write failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ ok = 0; goto finished;
+ }
+ } else {
+ /* No smash for top, center, bottom vertical alignment */
+ if (0 >= fprintf(job->fotex, plpdftex_c8_kw[24], p4, p5)) {
+ /* ERROR: Write failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 35);
+ ok = 0; goto finished;
+ }
+ }
+ }
+ }
+ /* Return.
+ */
+ finished:
+ if (0 == ok) {
+ job->exc = 1; $? ". exc 1"
+ } $? "- plpdftex_process_tex_text"
+}
+
+
+
+/** Process a TeX line.
+ @param job Job structure.
+ @param txt Text to process.
+*/
+static
+void
+plpdftex_process_tex_line(plpdftex_job_t *job, char *txt)
+{
+ char *firstarg;
+ $? "+ plpdftex_process_tex_line"
+ firstarg = dk3str_c8_next(txt, NULL);
+ switch(dk3str_c8_array_index(plpdftex_tex_instructions, txt, 0)) {
+ case 0: {
+ plpdftex_process_tex_fontsize(job, firstarg);
+ } break;
+ case 1: {
+ plpdftex_process_tex_font_setup(job, firstarg);
+ } break;
+ case 2: {
+ plpdftex_process_tex_package(job, firstarg);
+ } break;
+ case 3: {
+ plpdftex_process_tex_preamble(job, firstarg);
+ } break;
+ case 4: {
+ plpdftex_process_tex_text(job, firstarg, 0);
+ } break;
+ case 5: {
+ plpdftex_process_tex_text(job, firstarg, 1);
+ } break;
+ } $? "- plpdftex_process_tex_line"
+}
+
+
+
+/** Process PDF gsave line.
+ @param job Job structure.
+ @param txt Text to process, may be NULL.
+*/
+static
+void
+pldpdftex_process_pdf_gsave(plpdftex_job_t *job, char *txt)
+{
+ int ok = 0;
+ $? "+ pldpdftex_process_pdf_gsave"
+ if (0 != dk3pdf_gsave(job->opdf)) {
+ ok = 1;
+ } else {
+ /* ERROR: gsave failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 34);
+ }
+ if(0 == ok) {
+ job->exc = 1; $? ". exc 1"
+ } $? "- pldpdftex_process_pdf_gsave"
+}
+
+
+
+/** Process PDF grestore line.
+ @param job Job structure.
+ @param txt Text to process, may be NULL.
+*/
+static
+void
+pldpdftex_process_pdf_grestore(plpdftex_job_t *job, char *txt)
+{
+ int ok = 0;
+ $? "+ pldpdftex_process_pdf_grestore"
+ if (0 != dk3pdf_grestore(job->opdf)) {
+ ok = 1;
+ } else {
+ /* ERROR grestore failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 33);
+ }
+ if(0 == ok) {
+ job->exc = 1; $? ". exc 1"
+ } $? "- pldpdftex_process_pdf_grestore"
+}
+
+
+
+/** Process PDF linewidth line.
+ @param job Job structure.
+ @param txt Text to process, may be NULL.
+*/
+static
+void
+pldpdftex_process_pdf_lw(plpdftex_job_t *job, char *txt)
+{
+ double lw = 1.0;
+ int ok = 0;
+ int mec = 0;
+ $? "+ pldpdftex_process_pdf_lw"
+ if (NULL != txt) {
+ if (0 != dk3ma_d_from_c8_string(&lw, txt, &mec)) {
+ if (0.0 <= lw) {
+ if (0 != dk3pdf_set_linewidth(job->opdf, lw)) {
+ ok = 1;
+ } else {
+ /* ERROR: Failed to set line width */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 32);
+ }
+ } else {
+ /* Syntax error, negative number */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 31);
+ }
+ } else {
+ /* Syntax error, not numeric */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ }
+ } else {
+ /* Syntax error, missing line width */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ }
+ if(0 == ok) {
+ job->exc = 1; $? ". exc 1"
+ } $? "- pldpdftex_process_pdf_lw"
+}
+
+
+
+/** Process PDF buttcap line.
+ @param job Job structure.
+ @param txt Text to process, may be NULL.
+*/
+static
+void
+pldpdftex_process_pdf_buttcap(plpdftex_job_t *job, char *txt)
+{
+ int ok = 0;
+ $? "+ pldpdftex_process_pdf_buttcap"
+ if (0 != dk3pdf_set_linecap(job->opdf, DK3_LINECAP_BUTT)) {
+ ok = 1;
+ } else {
+ /* ERROR: Failed to set line cap */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 30);
+ }
+ if(0 == ok) {
+ job->exc = 1; $? ". exc 1"
+ } $? "- pldpdftex_process_pdf_buttcap"
+}
+
+
+/** Process PDF miterjoin line.
+ @param job Job structure.
+ @param txt Text to process, may be NULL.
+*/
+static
+void
+pldpdftex_process_pdf_miterjoin(plpdftex_job_t *job, char *txt)
+{
+ int ok = 0;
+ $? "+ pldpdftex_process_pdf_miterjoin"
+ if (0 != dk3pdf_set_linejoin(job->opdf, DK3_LINEJOIN_MITER)) {
+ ok = 1;
+ } else {
+ /* Failed to set linejoin */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 29);
+ }
+ if(0 == ok) {
+ job->exc = 1; $? ". exc 1"
+ } $? "- pldpdftex_process_pdf_miterjoin"
+}
+
+
+
+/** Process PDF nodash line.
+ @param job Job structure.
+ @param txt Text to process, may be NULL.
+*/
+static
+void
+pldpdftex_process_pdf_nodash(plpdftex_job_t *job, char *txt)
+{
+ double d = 0.0;
+ int ok = 0;
+ $? "+ pldpdftex_process_pdf_nodash"
+ if (0 != dk3pdf_set_line_dash(job->opdf, &d, 0, 0.0)) {
+ ok = 1;
+ } else {
+ /* Failed to set dash */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 28);
+ }
+ if(0 == ok) {
+ job->exc = 1; $? ". exc 1"
+ } $? "- pldpdftex_process_pdf_nodash"
+}
+
+
+
+/** Process PDF stroke color line.
+ @param job Job structure.
+ @param txt Text to process, may be NULL.
+*/
+static
+void
+pldpdftex_process_pdf_stroke_color(plpdftex_job_t *job, char *txt)
+{
+ double r = 0.0;
+ double g = 0.0;
+ double b = 0.0;
+ int ok = 0;
+ $? "+ pldpdftex_process_pdf_stroke_color"
+ if (NULL != txt) {
+ if (0 != plptcol_get_color(job, txt, &r, &g, &b)) {
+ if (0 != dk3pdf_stroking_rgb(job->opdf, r, g, b)) {
+ ok = 1;
+ } else {
+ /* Failed to set stroke color */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 27);
+ }
+ } else {
+ /* Color not found! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 26);
+ }
+ } else {
+ /* Syntax error, missing text */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ }
+ if(0 == ok) {
+ job->exc = 1; $? ". exc 1"
+ } $? "- pldpdftex_process_pdf_stroke_color"
+}
+
+
+
+/** Process PDF fill color line.
+ @param job Job structure.
+ @param txt Text to process, may be NULL.
+*/
+static
+void
+pldpdftex_process_pdf_fill_color(plpdftex_job_t *job, char *txt)
+{
+ double r = 0.0;
+ double g = 0.0;
+ double b = 0.0;
+ int ok = 0;
+ $? "+ pldpdftex_process_pdf_fill_color"
+ if (NULL != txt) {
+ if (0 != plptcol_get_color(job, txt, &r, &g, &b)) {
+ if (0 != dk3pdf_nonstroking_rgb(job->opdf, r, g, b)) {
+ ok = 1;
+ } else {
+ /* Failed to set stroke color */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 25);
+ }
+ } else {
+ /* Color not found! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ }
+ } else {
+ /* Syntax error, missing text */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ }
+ if(0 == ok) {
+ job->exc = 1; $? ". exc 1"
+ } $? "- pldpdftex_process_pdf_fill_color"
+}
+
+
+
+/** Process PDF rectangle line.
+ @param job Job structure.
+ @param txt Text to process, may be NULL.
+*/
+static
+void
+pldpdftex_process_pdf_rectangle(plpdftex_job_t *job, char *txt)
+{
+ char *p1 = NULL;
+ char *p2 = NULL;
+ char *p3 = NULL;
+ double x1 = 0.0;
+ double x2 = 0.0;
+ double y1 = 0.0;
+ double y2 = 0.0;
+ int ok = 0;
+ $? "+ pldpdftex_process_pdf_rectangle"
+ /* Set txt, p1, p2, p3 to x1, y1, x2, y2.
+ */
+ if (NULL == txt) {
+ /* Syntax error, missing text */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto cleanup;
+ }
+ p1 = dk3str_c8_next(txt, NULL);
+ if (NULL == p1) {
+ /* Syntax error, missing y1 */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto cleanup;
+ }
+ p2 = dk3str_c8_next(p1, NULL);
+ if (NULL == p2) {
+ /* Syntax error, missing x2 */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto cleanup;
+ }
+ p3 = dk3str_c8_next(p2, NULL);
+ if (NULL == p3) {
+ /* Syntax error, missing y2 */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto cleanup;
+ }
+
+ /* Read values from strings.
+ */
+ if (0 == dk3ma_d_from_c8_string(&x1, txt, NULL)) {
+ /* Syntax error, x1 not a number */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ goto cleanup;
+ }
+ if (0 == dk3ma_d_from_c8_string(&y1, p1, NULL)) {
+ /* Syntax error, y1 not a number */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ goto cleanup;
+ }
+ if (0 == dk3ma_d_from_c8_string(&x2, p2, NULL)) {
+ /* Syntax error, x2 not a number */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ goto cleanup;
+ }
+ if (0 == dk3ma_d_from_c8_string(&y2, p3, NULL)) {
+ /* Syntax error, y2 not a number */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ goto cleanup;
+ }
+
+ /* PDF drawing operations.
+ */
+ if (0 == dk3pdf_newpath_moveto(job->opdf, x1, y1)) {
+ /* ERROR: moveto failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 22);
+ goto cleanup;
+ }
+ if (0 == dk3pdf_lineto(job->opdf, x2, y1)) {
+ /* ERROR: lineto failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 24);
+ goto cleanup;
+ }
+ if (0 == dk3pdf_lineto(job->opdf, x2, y2)) {
+ /* ERROR: lineto failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 24);
+ goto cleanup;
+ }
+ if (0 == dk3pdf_lineto(job->opdf, x1, y2)) {
+ /* ERROR: lineto failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 24);
+ goto cleanup;
+ }
+ if (0 == dk3pdf_lineto(job->opdf, x1, y1)) {
+ /* ERROR: lineto failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 24);
+ goto cleanup;
+ }
+ if (0 == dk3pdf_closepath(job->opdf)) {
+ /* ERROR: closepath failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 18);
+ goto cleanup;
+ }
+
+ /* Success.
+ */
+ ok = 1;
+
+ cleanup:
+ if(0 == ok) {
+ job->exc = 1; $? ". exc 1"
+ } $? "- pldpdftex_process_pdf_rectangle"
+}
+
+
+
+/** Segments per quarter circle.
+*/
+static size_t const plpt_segments = 2;
+
+
+
+/** Calculate kappa value to draw a circle.
+ @param segments Number of segments for one _quarter_
+ of the circle.
+ @return Kappa value (factor to apply to first derivative
+ when calculating control points).
+*/
+static
+double
+plpdftex_kappa(size_t segments)
+{
+ double back = 0.0;
+ double alpha;
+ $? "+ plpdftex_kappa %u", (unsigned)segments
+ alpha = M_PI / (2.0 * (double)segments);
+
+ /* kappa = (2*sqrt(8*(1-cos(a)))-4*sin(a)) / (3*a*(1-cos(a))) */
+
+ back = (2.0 * sqrt(8.0 * (1.0 - cos(alpha))) - 4.0 * sin(alpha))
+ / (3.0 * alpha * (1.0 - cos(alpha)));
+ $? "- plpdftex_kappa %lg", back
+ return back;
+}
+
+
+
+/** Process PDF circle line.
+ @param job Job structure.
+ @param txt Text to process, may be NULL.
+*/
+static
+void
+pldpdftex_process_pdf_circle(plpdftex_job_t *job, char *txt)
+{
+ char *p1; /* Text containing y */
+ char *p2; /* Text containing radius */
+ double x; /* Center x */
+ double y; /* Center y */
+ double r; /* Radius */
+ double x0; /* Current point x */
+ double y0; /* Current point y */
+ double x1; /* First control point x */
+ double y1; /* First control point y */
+ double x2; /* Second control point x */
+ double y2; /* Second control point y */
+ double x3; /* Final point x */
+ double y3; /* Final point y */
+ double alpha; /* Arc angle. */
+ double a1; /* Start angle. */
+ double a2; /* End angle. */
+ double kappa; /* Kappa value. */
+ size_t i; /* Current sub-segment */
+ int ok = 0; /* Flag: Success */
+ $? "+ pldpdftex_process_pdf_circle"
+ /* Find strings
+ */
+ if (NULL == txt) {
+ /* Syntax error, no data */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+ p1 = dk3str_c8_next(txt, NULL);
+ if (NULL == p1) {
+ /* Syntax error, missing y */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+ p2 = dk3str_c8_next(p1, NULL);
+ if (NULL == p2) {
+ /* Syntax error, missing r */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+
+ /* Retrieve values from strings.
+ */
+ if (0 == dk3ma_d_from_c8_string(&x, txt, NULL)) {
+ /* Syntax error, not a number */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ goto finished;
+ }
+ if (0 == dk3ma_d_from_c8_string(&y, txt, NULL)) {
+ /* Syntax error, not a number */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ goto finished;
+ }
+ if (0 == dk3ma_d_from_c8_string(&r, txt, NULL)) {
+ /* Syntax error, not a number */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ goto finished;
+ }
+ if (0.0 > r) {
+ /* ERROR: Negative radius */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 23);
+ goto finished;
+ }
+ if (0 == dk3pdf_newpath_moveto(job->opdf, x+r, y)) {
+ goto finished;
+ }
+ kappa = plpdftex_kappa(plpt_segments);
+ alpha = 2.0 * M_PI / ((double)(4 * plpt_segments));
+ ok = 1;
+ for (i = 0; i < (4 * plpt_segments); i++) {
+ a1 = (double)i * alpha;
+ a2 = a1 + alpha;
+ if (0 == i) a1 = 0.0;
+ if ((4 * plpt_segments - 1) == i) a2 = 2.0 * M_PI;
+ x0 = r * cos(a1); y0 = r * sin(a1);
+ if (0 == i) { x0 = r; y0 = 0.0; }
+ x3 = r * cos(a2); y3 = r * sin(a2);
+ if ((4 * plpt_segments - 1) == i) { x3 = r; y3 = 0.0; }
+ x1 = -1.0 * r * alpha * sin(a1);
+ y1 = r * alpha * cos(a1);
+ x2 = -1.0 * r * alpha * sin(a2);
+ y2 = r * alpha * cos(a2);
+ x1 = x1 * kappa;
+ y1 = y1 * kappa;
+ x2 = -1.0 * kappa * x2;
+ y2 = -1.0 * kappa * y2;
+ x1 += x0;
+ y1 += y0;
+ x2 += x3;
+ y2 += y3;
+#if VERSION_BEFORE_20150821
+ x0 += x;
+#endif
+ x1 += x; x2 += x; x3 += x;
+#if VERSION_BEFORE_20150821
+ y0 += y;
+#endif
+ y1 += y; y2 += y; y3 += y;
+ if (0 == dk3pdf_curveto(job->opdf, x1, y1, x2, y2, x3, y3)) {
+ ok = 0;
+ goto finished;
+ }
+ }
+ if (0 == dk3pdf_closepath(job->opdf)) {
+ ok = 0;
+ }
+
+ /* Return
+ */
+ finished:
+ if(0 == ok) {
+ job->exc = 1; $? ". exc 1"
+ } $? "- pldpdftex_process_pdf_circle"
+}
+
+
+
+/** Process PDF moveto line.
+ @param job Job structure.
+ @param txt Text to process, may be NULL.
+*/
+static
+void
+pldpdftex_process_pdf_moveto(plpdftex_job_t *job, char *txt)
+{
+ char *p1;
+ double x;
+ double y;
+ int ok = 0;
+ $? "+ pldpdftex_process_pdf_moveto"
+ if (NULL != txt) {
+ p1 = dk3str_c8_next(txt, NULL);
+ if (NULL != p1) {
+ if (0 != dk3ma_d_from_c8_string(&x, txt, NULL)) {
+ if (0 != dk3ma_d_from_c8_string(&y, p1, NULL)) {
+ if (0 != dk3pdf_newpath_moveto(job->opdf, x, y)) {
+ ok = 1;
+ } else {
+ /* ERROR, moveto failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 22);
+ }
+ } else {
+ /* ERROR, y not numeric */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ }
+ } else {
+ /* ERROR, x not numeric */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ }
+ } else {
+ /* Syntax error, missing y value */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ }
+ } else {
+ /* Syntax error, no coordinates */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ }
+ if(0 == ok) {
+ job->exc = 1; $? ". exc 1"
+ } $? "- pldpdftex_process_pdf_moveto"
+}
+
+
+
+/** Process PDF lineto line.
+ @param job Job structure.
+ @param txt Text to process, may be NULL.
+*/
+static
+void
+pldpdftex_process_pdf_lineto(plpdftex_job_t *job, char *txt)
+{
+ char *p1;
+ double x;
+ double y;
+ int ok = 0;
+ $? "+ pldpdftex_process_pdf_lineto"
+ if (NULL != txt) {
+ p1 = dk3str_c8_next(txt, NULL);
+ if (NULL != p1) {
+ if (0 != dk3ma_d_from_c8_string(&x, txt, NULL)) {
+ if (0 != dk3ma_d_from_c8_string(&y, p1, NULL)) {
+ if (0 != dk3pdf_lineto(job->opdf, x, y)) {
+ ok = 1;
+ } else {
+ /* ERROR, moveto failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 22);
+ }
+ } else {
+ /* ERROR, y not numeric */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ }
+ } else {
+ /* ERROR, x not numeric */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ }
+ } else {
+ /* Syntax error, missing y value */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ }
+ } else {
+ /* Syntax error, no coordinates */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ }
+ if(0 == ok) {
+ job->exc = 1; $? ". exc 1"
+ } $? "- pldpdftex_process_pdf_lineto"
+}
+
+
+
+/** Process PDF curveto line.
+ @param job Job structure.
+ @param txt Text to process, may be NULL.
+*/
+static
+void
+pldpdftex_process_pdf_curveto(plpdftex_job_t *job, char *txt)
+{
+ char *p1; /* y1 */
+ char *p2; /* x2 */
+ char *p3; /* y2 */
+ char *p4; /* x3 */
+ char *p5; /* y3 */
+ double x1;
+ double y1;
+ double x2;
+ double y2;
+ double x3;
+ double y3;
+ int ok = 0;
+ $? "+ pldpdftex_process_pdf_curveto"
+ /* Split string.
+ */
+ if (NULL == txt) {
+ /* ERROR: No text */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+ p1 = dk3str_c8_next(txt, NULL);
+ if (NULL == p1) {
+ /* ERROR: No y1 */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+ p2 = dk3str_c8_next(p1, NULL);
+ if (NULL == p2) {
+ /* ERROR: No x2 */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+ p3 = dk3str_c8_next(p2, NULL);
+ if (NULL == p3) {
+ /* ERROR: No y2 */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+ p4 = dk3str_c8_next(p3, NULL);
+ if (NULL == p4) {
+ /* ERROR: No x3 */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+ p5 = dk3str_c8_next(p4, NULL);
+ if (NULL == p5) {
+ /* ERROR: No y3 */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 21);
+ goto finished;
+ }
+
+ /* Retrieve values.
+ */
+ if (0 == dk3ma_d_from_c8_string(&x1, txt, NULL)) {
+ /* ERROR: x1 not numeric */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ goto finished;
+ }
+ if (0 == dk3ma_d_from_c8_string(&y1, p1, NULL)) {
+ /* ERROR: y1 not numeric */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ goto finished;
+ }
+ if (0 == dk3ma_d_from_c8_string(&x2, p2, NULL)) {
+ /* ERROR: x2 not numeric */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ goto finished;
+ }
+ if (0 == dk3ma_d_from_c8_string(&y2, p3, NULL)) {
+ /* ERROR: y2 not numeric */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ goto finished;
+ }
+ if (0 == dk3ma_d_from_c8_string(&x3, p4, NULL)) {
+ /* ERROR: x3 not numeric */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ goto finished;
+ }
+ if (0 == dk3ma_d_from_c8_string(&y3, p5, NULL)) {
+ /* ERROR: y3 not numeric */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 20);
+ goto finished;
+ }
+
+ /* Write curve segment.
+ */
+ if (0 != dk3pdf_curveto(job->opdf, x1, y1, x2, y2, x3, y3)) {
+ ok = 1;
+ } else {
+ /* ERROR: curveto failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 19);
+ }
+
+ /* Return.
+ */
+ finished:
+ if(0 == ok) {
+ job->exc = 1; $? ". exc 1"
+ } $? "- pldpdftex_process_pdf_curveto"
+}
+
+
+
+/** Process PDF closepath line.
+ @param job Job structure.
+ @param txt Text to process, may be NULL.
+*/
+static
+void
+pldpdftex_process_pdf_closepath(plpdftex_job_t *job, char *txt)
+{
+ int ok = 0;
+ $? "+ pldpdftex_process_pdf_closepath"
+ if (0 != dk3pdf_closepath(job->opdf)) {
+ ok = 1;
+ } else {
+ /* ERROR: closepath failed */
+ }
+ if(0 == ok) {
+ job->exc = 1; $? ". exc 1"
+ } $? "- pldpdftex_process_pdf_closepath"
+}
+
+
+
+/** Process PDF stroke line.
+ @param job Job structure.
+ @param txt Text to process, may be NULL.
+*/
+static
+void
+pldpdftex_process_pdf_stroke(plpdftex_job_t *job, char *txt)
+{
+ int ok = 0;
+ $? "+ pldpdftex_process_pdf_stroke"
+ if (0 != dk3pdf_stroke(job->opdf)) {
+ ok = 1;
+ } else {
+ /* ERROR: stroke failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 17);
+ }
+ if(0 == ok) {
+ job->exc = 1; $? ". exc 1"
+ } $? "- pldpdftex_process_pdf_stroke"
+}
+
+
+
+/** Process PDF fill line.
+ @param job Job structure.
+ @param txt Text to process, may be NULL.
+*/
+static
+void
+pldpdftex_process_pdf_fill(plpdftex_job_t *job, char *txt)
+{
+ int ok = 0;
+ $? "+ pldpdftex_process_pdf_fill"
+ if (0 != dk3pdf_fill_eo(job->opdf)) {
+ ok = 1;
+ } else {
+ /* ERROR: Fill failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 16);
+ }
+ if(0 == ok) {
+ job->exc = 1; $? ". exc 1"
+ } $? "- pldpdftex_process_pdf_fill"
+}
+
+
+
+/** Process PDF clip line.
+ @param job Job structure.
+ @param txt Text to process, may be NULL.
+*/
+static
+void
+pldpdftex_process_pdf_clip(plpdftex_job_t *job, char *txt)
+{
+ int ok = 0;
+ $? "+ pldpdftex_process_pdf_clip"
+ if (0 != dk3pdf_clip_eo(job->opdf)) {
+ ok = 1;
+ } else {
+ /* ERROR: clip failed */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 15);
+ }
+ if(0 == ok) {
+ job->exc = 1; $? ". exc 1"
+ } $? "- pldpdftex_process_pdf_clip"
+}
+
+
+
+/** Process a PDF line.
+ @param job Job structure.
+ @param txt Text to process.
+*/
+static
+void
+plpdftex_process_pdf_line(plpdftex_job_t *job, char *txt)
+{
+ char *firstarg;
+ $? "+ plpdftex_process_pdf_line"
+ firstarg = dk3str_c8_next(txt, NULL);
+ switch(dk3str_c8_array_index(plpdftex_pdf_instructions, txt, 0)) {
+ case 0: {
+ pldpdftex_process_pdf_gsave(job, firstarg);
+ } break;
+ case 1: {
+ pldpdftex_process_pdf_grestore(job, firstarg);
+ } break;
+ case 2: {
+ pldpdftex_process_pdf_lw(job, firstarg);
+ } break;
+ case 3: {
+ pldpdftex_process_pdf_buttcap(job, firstarg);
+ } break;
+ case 4: {
+ pldpdftex_process_pdf_miterjoin(job, firstarg);
+ } break;
+ case 5: {
+ pldpdftex_process_pdf_nodash(job, firstarg);
+ } break;
+ case 6: {
+ pldpdftex_process_pdf_stroke_color(job, firstarg);
+ } break;
+ case 7: {
+ pldpdftex_process_pdf_fill_color(job, firstarg);
+ } break;
+ case 8: {
+ pldpdftex_process_pdf_rectangle(job, firstarg);
+ } break;
+ case 9: {
+ pldpdftex_process_pdf_circle(job, firstarg);
+ } break;
+ case 10: {
+ pldpdftex_process_pdf_moveto(job, firstarg);
+ } break;
+ case 11: {
+ pldpdftex_process_pdf_lineto(job, firstarg);
+ } break;
+ case 12: {
+ pldpdftex_process_pdf_curveto(job, firstarg);
+ } break;
+ case 13: {
+ pldpdftex_process_pdf_closepath(job, firstarg);
+ } break;
+ case 14: {
+ pldpdftex_process_pdf_stroke(job, firstarg);
+ } break;
+ case 15: {
+ pldpdftex_process_pdf_fill(job, firstarg);
+ } break;
+ case 16: {
+ pldpdftex_process_pdf_clip(job, firstarg);
+ } break;
+ } $? "- plpdftex_process_pdf_line"
+}
+
+
+
+/** Process one input line stored into ilbuf by plpdftex_run_for_input().
+ @param job Job structure.
+*/
+static
+void
+plpdftex_process_line(plpdftex_job_t *job)
+{
+ char *p1;
+ $? "+ plpdftex_process_line"
+ p1 = dk3str_c8_start(job->ilbuf, NULL);
+ if (NULL != p1) {
+ dk3str_c8_chomp(p1, NULL); $? ". input line \"%!8s\"", p1
+ switch(*p1) {
+ case 't': {
+ p1 = dk3str_c8_start(++p1, NULL);
+ if (NULL != p1) {
+ plpdftex_process_tex_line(job, p1);
+ } else {
+ /* Syntax error */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 14);
+ job->exc = 1; $? ". exc 1"
+ }
+ } break;
+ case 'p': {
+ p1 = dk3str_c8_start(++p1, NULL);
+ if (NULL != p1) {
+ plpdftex_process_pdf_line(job, p1);
+ } else {
+ /* Syntax error */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 14);
+ job->exc = 1; $? ". exc 1"
+ }
+ } break;
+ case '#': { $? ". comment, ignore"
+ } break;
+ default: {
+ /* Syntax error */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 13);
+ job->exc = 1; $? ". exc 1"
+ } break;
+ }
+ } $? "- plpdftex_process_line"
+}
+
+
+
+/** Process the normal input lines.
+ @param job Job structure.
+*/
+static
+void
+plpdftex_run_for_input(plpdftex_job_t *job)
+{
+ int ok = 0;
+ $? "+ plpdftex_run_for_input"
+ while (NULL != fgets(job->ilbuf, (int)(job->szilb), job->infi)) {
+ plpdftex_process_line(job);
+ }
+ if (0 != job->stagr) {
+ switch (job->state) {
+ case PLPT_STATE_NO_OUTPUT_YET: {
+ ok = 1;
+ /* documentclass{article} */
+ plpdftex_write_textline(job, plpdftex_c8_kw[2]);
+ plpdftex_write_default_font_setup(job);
+ plpdftex_write_default_packages(job);
+ plpdftex_write_required_packages(job);
+ plpdftex_write_textline(job, plpdftex_c8_kw[9]);
+ plpdftex_write_textline(job, plpdftex_c8_kw[10]);
+ plpdftex_open_picture_set(job);
+ plpdftex_close_picture_set(job);
+ job->state = PLPT_STATE_AFTER_DOCUMENT;
+ } break;
+ case PLPT_STATE_DOCUMENT_CLASS: {
+ ok = 1;
+ plpdftex_write_default_font_setup(job);
+ plpdftex_write_default_packages(job);
+ plpdftex_write_required_packages(job);
+ plpdftex_write_textline(job, plpdftex_c8_kw[9]);
+ plpdftex_write_textline(job, plpdftex_c8_kw[10]);
+ plpdftex_open_picture_set(job);
+ plpdftex_close_picture_set(job);
+ job->state = PLPT_STATE_AFTER_DOCUMENT;
+ } break;
+ case PLPT_STATE_USER_FONT_SETUP: {
+ ok = 1;
+ plpdftex_write_textline(job, plpdftex_c8_kw[4]);
+ plpdftex_write_default_packages(job);
+ plpdftex_write_required_packages(job);
+ plpdftex_write_textline(job, plpdftex_c8_kw[9]);
+ plpdftex_write_textline(job, plpdftex_c8_kw[10]);
+ plpdftex_open_picture_set(job);
+ plpdftex_close_picture_set(job);
+ job->state = PLPT_STATE_AFTER_DOCUMENT;
+ } break;
+ case PLPT_STATE_USER_PACKAGES: {
+ ok = 1;
+ plpdftex_write_textline(job, plpdftex_c8_kw[6]);
+ plpdftex_write_required_packages(job);
+ plpdftex_write_textline(job, plpdftex_c8_kw[9]);
+ plpdftex_write_textline(job, plpdftex_c8_kw[10]);
+ plpdftex_open_picture_set(job);
+ plpdftex_close_picture_set(job);
+ job->state = PLPT_STATE_AFTER_DOCUMENT;
+ } break;
+ case PLPT_STATE_USER_SETUP: {
+ ok = 1;
+ plpdftex_write_textline(job, plpdftex_c8_kw[10]);
+ plpdftex_open_picture_set(job);
+ plpdftex_close_picture_set(job);
+ job->state = PLPT_STATE_AFTER_DOCUMENT;
+ } break;
+ case PLPT_STATE_IN_DOCUMENT: {
+ ok = 1;
+ plpdftex_close_picture_set(job);
+ job->state = PLPT_STATE_AFTER_DOCUMENT;
+ } break;
+ case PLPT_STATE_AFTER_DOCUMENT: {
+ ok = 1;
+ } break;
+ default: {
+ /* ERROR: Too late */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 12);
+ goto finished;
+ } break;
+ }
+ } else {
+ switch (job->state) {
+ case PLPT_STATE_NO_OUTPUT_YET:
+ case PLPT_STATE_DOCUMENT_CLASS:
+ case PLPT_STATE_USER_FONT_SETUP:
+ case PLPT_STATE_USER_PACKAGES:
+ case PLPT_STATE_USER_SETUP: {
+ plpdftex_open_picture_set(job);
+ plpdftex_close_picture_set(job);
+ job->state = PLPT_STATE_AFTER_DOCUMENT;
+ } break;
+ case PLPT_STATE_IN_DOCUMENT: {
+ ok = 1;
+ plpdftex_close_picture_set(job);
+ job->state = PLPT_STATE_AFTER_DOCUMENT;
+ } break;
+ case PLPT_STATE_AFTER_DOCUMENT: {
+ ok = 1;
+ } break;
+ default: {
+ /* ERROR: Too late */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 12);
+ goto finished;
+ } break;
+ }
+ }
+
+ finished:
+ if (0 == ok) {
+ job->exc = 1; $? ". exc 1"
+ } $? "- plpdftex_run_for_input"
+}
+
+
+
+/** Open PDF and TeX output file, create output structures
+ and process all input.
+ @param job Job structure.
+*/
+static
+void
+plpdftex_run_with_output_filenames(plpdftex_job_t *job)
+{
+ unsigned long w;
+ unsigned long h;
+ $? "+ plpdftex_run_with_output_filenames"
+ if (fgets(job->ilbuf, (int)(job->szilb), job->infi)) {
+ if (sscanf(job->ilbuf, "%lu %lu", &w, &h) == 2) {
+ job->imgw = w; job->imgh = h;
+ if (((unsigned long)DK3_L_MAX >= w) && ((unsigned long)DK3_L_MAX >= h)) {
+ job->fotex = dk3sf_c8_fopen_app(job->fntex, "w", job->app);
+ if (NULL != job->fotex) {
+ job->fopdf = dk3sf_c8_fopen_app(job->fnpdf, "wb", job->app);
+ if (NULL != job->fopdf) {
+ job->opdf = dk3pdf_open_app(job->app);
+ if (NULL != job->opdf) {
+ dk3pdf_set_next_mediabox(job->opdf, 0L, (long)w, 0L, (long)h);
+ if (0 != dk3pdf_open_page_with_clip(job->opdf, 1)) {
+ job->exc = 0; $? ". exc 0"
+ plpdftex_run_for_input(job);
+ if (0 == dk3pdf_close_page(job->opdf)) {
+ job->exc = 1; $? ". exc 1"
+ /* ERROR: Failed to close PDF page */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 11);
+ }
+ } else {
+ /* ERROR: Failed to open a PDF page */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 10);
+ }
+ if (0 == dk3pdf_write_file(job->opdf, job->fopdf)) {
+ job->exc = 1; $? ". exc 1"
+ /* ERROR: Failed to write PDF to file! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 9);
+ }
+ dk3pdf_close(job->opdf); job->opdf = NULL;
+ } else {
+ /* Failed to open PDF output structure */
+ }
+ if (0 == dk3sf_fclose_app(job->fopdf, job->app)) {
+ job->exc = 1; $? ". exc 1"
+ }
+ job->fopdf = NULL;
+ } else {
+ /* Failed to open PDF output file */
+ }
+ if (0 == dk3sf_fclose_app(job->fotex, job->app)) {
+ job->exc = 1; $? ". exc 1"
+ }
+ job->fotex = NULL;
+ } else {
+ /* Failed to open TeX output file */
+ }
+ } else {
+ /* Overflow, w or h too large! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 8);
+ }
+ } else {
+ /* ERROR: No w h */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 7);
+ }
+ } else {
+ /* ERROR: Missing w h line */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 6);
+ } $? "- plpdftex_run_with_output_filenames"
+}
+
+
+
+/** Process input from file or stdin.
+ @param job Job structure.
+*/
+static
+void
+plpdftex_process_input(plpdftex_job_t *job)
+{
+ char *p1;
+ $? "+ plpdftex_process_input"
+ if (fgets(job->ilbuf, (int)(job->szilb), job->infi)) {
+ p1 = dk3str_c8_start(job->ilbuf, NULL);
+ if (p1) {
+ dk3str_c8_chomp(job->ilbuf, NULL);
+ if (dk3str_c8_len(job->ilbuf) < job->szfn) {
+ dk3str_c8_cpy(job->fnb1, job->ilbuf);
+ dk3str_c8_cpy(job->fnpdf, job->ilbuf);
+ p1 = dk3str_c8_get_suffix(job->fnpdf);
+ if (p1) { *p1 = '\0'; }
+ dk3str_c8_cpy(job->fntex, job->fnpdf);
+ if (
+ (dk3str_c8_len(job->fnpdf)+dk3str_c8_len(plpdftex_c8_kw[0]))
+ < job->szfn
+ )
+ {
+ dk3str_c8_cat(job->fnpdf, plpdftex_c8_kw[0]);
+ dk3str_c8_cat(job->fntex, plpdftex_c8_kw[1]);
+ p1 = dk3str_c8_get_suffix(job->fnb1);
+ if (p1) {
+ p1++;
+ switch (dk3str_c8_array_index(pldftex_output_file_suffixes,p1,0)) {
+ case 0: {
+ /* pdf + tex for inclusion */
+ plpdftex_run_with_output_filenames(job);
+ } break;
+ case 1: {
+ /* standalone pdf + tex */
+ job->stagr = 1;
+ plpdftex_run_with_output_filenames(job);
+ } break;
+ default: {
+ /* ERROR: Invalid file name */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 5);
+ } break;
+ }
+ }
+ } else {
+ /* ERROR: File name too long! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 4);
+ }
+ } else {
+ /* ERROR: File name too long in first input line */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 4);
+ }
+ } else {
+ /* ERROR: Syntax error, first line must not be empty */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 3);
+ }
+ } $? "- plpdftex_process_input"
+}
+
+
+
+/** Process input.
+ @param job Job structure.
+*/
+static
+void
+plpdftex_run_processing(plpdftex_job_t *job)
+{
+ dk3_dir_t *fne;
+ dkChar const *fnpattern;
+ dkChar const *fn;
+ dk3_um_t nfiles;
+ int numargs;
+ $? "+ plpdftex_run_processing"
+ numargs = dk3opt_get_num_args(job->opt);
+ switch (numargs) {
+ case 0: {
+ job->infi = stdin;
+ plpdftex_process_input(job);
+ } break;
+ case 1: {
+ fnpattern = dk3opt_get_arg(job->opt, 0);
+ if (fnpattern) {
+ if (dk3sf_must_expand(fnpattern)) {
+ fne = dk3dir_fne_open_app(fnpattern, job->app);
+ if (fne) {
+ nfiles = dk3dir_get_number_of_files(fne);
+ if (nfiles) {
+ if (DK3_UM_1 == nfiles) {
+ if (dk3dir_get_next_file(fne)) {
+ fn = dk3dir_get_fullname(fne);
+ if (fn) {
+ job->infi = dk3sf_fopen_app(fn, dkT("r"), job->app);
+ if (job->infi) {
+ plpdftex_process_input(job);
+ fclose(job->infi); job->infi = NULL;
+ }
+ } else {
+ /* ERROR: Must not happen */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 166);
+ }
+ } else {
+ /* ERROR: Must not happen */
+ dk3app_log_i1(job->app, DK3_LL_ERROR, 166);
+ }
+ } else {
+ /* ERROR: Too many file names match pattern! */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 168, 169, fnpattern);
+ }
+ } else {
+ /* ERROR: No files match pattern */
+ dk3app_log_i3(job->app, DK3_LL_ERROR, 215, 216, fnpattern);
+ }
+ dk3dir_close(fne);
+ }
+ } else {
+ job->infi = dk3sf_fopen_app(fnpattern, dkT("r"), job->app);
+ if (job->infi) {
+ plpdftex_process_input(job);
+ fclose(job->infi); job->infi = NULL;
+ }
+ }
+ } else {
+ /* ERROR: Something wrong with options */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 2);
+ }
+ } break;
+ default: {
+ /* ERROR: One argument is maximum */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 1);
+ } break;
+ } $? "- plpdftex_run_processing"
+}
+
+
+
+/** Run.
+ @param job Job structure.
+*/
+static
+void
+plpdftex_run(plpdftex_job_t *job)
+{
+ int cmd; /* Command to execute */
+ $? "+ plpdftex_run"
+ job->opt = dk3opt_open_from_app(
+ plpdftex_options, sz_plpdftex_options, dkT('\0'), NULL, job->app
+ );
+ if (job->opt) {
+ if (0 == dk3opt_get_error_code(job->opt)) {
+ cmd = 0;
+ if(dk3opt_is_set(job->opt, dkT('h'))) {
+ cmd |= DK3_APP_CMD_HELP;
+ }
+ if(dk3opt_is_set(job->opt, dkT('v'))) {
+ cmd |= DK3_APP_CMD_VERSION;
+ }
+ if(dk3opt_is_set(job->opt, dkT('l'))) {
+ cmd |= DK3_APP_CMD_LICENSE;
+ }
+ if (cmd) {
+ dk3sf_initialize_stdout();
+ /* Show version */
+ if (cmd & DK3_APP_CMD_VERSION) {
+ dk3sf_fputs(plpdftex_version, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ if (cmd & DK3_APP_CMD_LICENSE) {
+ /* Show license */
+ dk3sf_fputt(plpdftex_license_text, stdout);
+ }
+ if (cmd & DK3_APP_CMD_HELP) {
+ /* Show help */
+ dk3app_help(job->app, dkT("plpdftex.txt"), plpdftex_text_help);
+ }
+ job->exc = 0; $? ". exc 0"
+ } else {
+ /* Run normally */
+ plpdftex_run_processing(job);
+ }
+ }
+ } $? "- plpdftex_run"
+}
+
+
+
+/** File name as read from input.
+*/
+static char plpdftex_input_filename[DK3_MAX_PATH];
+
+
+
+/** PDF output file name.
+*/
+static char plpdftex_pdf_filename[DK3_MAX_PATH];
+
+
+
+/** TeX output file name.
+*/
+static char plpdftex_tex_filename[DK3_MAX_PATH];
+
+
+
+/** Input line buffer (one line from input file).
+*/
+static char plpdftex_input_buffer[1024];
+
+
+
+/** Main function, entry point of the program.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, any other value indicates an error.
+*/
+DK3_MAIN
+{
+ plpdftex_job_t job; /* Job structure. */
+ int check_presence = 0; /* Flag: Just presence check. */
+ int exit_code = 1; /* Exit code returned to OS. */
+
+ $!trace-init /tmp/plpdftex.deb
+ $? "- main"
+ if (2 == argc) {
+ if (dk3str_cmp(argv[1], plpdftex_check_presence) == 0) {
+ check_presence = 1;
+ }
+ }
+ if (check_presence) {
+ fputs(plpdftex_protocol, stdout);
+ exit_code = 0;
+ } else {
+ plpdftex_job_init(&job);
+ job.fnb1 = plpdftex_input_filename;
+ job.fnpdf = plpdftex_pdf_filename;
+ job.fntex = plpdftex_tex_filename;
+ job.szfn = DK3_MAX_PATH;
+ job.ilbuf = plpdftex_input_buffer;
+ job.szilb = sizeof(plpdftex_input_buffer);
+ job.app = dk3app_open_command(
+ argc, (dkChar const * const *)argv, plpdftex_group_name
+ );
+ if (job.app) {
+ job.msg = dk3app_messages(
+ job.app, dkT("plpdftex.str"), (dkChar const **)plpdftex_kw
+ );
+ job.sco = dk3sto_open_app(job.app);
+ if (job.sco) {
+ job.sico = dk3sto_it_open(job.sco);
+ if (job.sico) {
+ plpdftex_run(&job);
+ }
+ }
+ }
+ exit_code = job.exc;
+ plpdftex_job_cleanup(&job);
+ }
+ $? "- main %d", exit_code
+ $!trace-end
+ fflush(stdout);
+ exit(exit_code); return exit_code;
+}
+
diff --git a/support/dktools/plpdftex.h b/support/dktools/plpdftex.h
new file mode 100644
index 0000000000..f40864297d
--- /dev/null
+++ b/support/dktools/plpdftex.h
@@ -0,0 +1,132 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: plpdftex.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file plpdftex.h Header file for the plpdftex module.
+*/
+
+#ifndef PLPDFTEX_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define PLPDFTEX_H_INCLUDED 1
+
+
+#line 8 "plpdftex.ctr"
+
+#include "dk3all.h"
+
+
+
+/** Current state of the program.
+*/
+enum {
+
+ /** No output produced yet.
+ */
+ PLPT_STATE_NO_OUTPUT_YET = 0,
+
+ /** Document class line written.
+ */
+ PLPT_STATE_DOCUMENT_CLASS,
+
+ /** Lines of user-specified font setup written.
+ */
+ PLPT_STATE_USER_FONT_SETUP,
+
+ /** Lines of user-specified usepackage instructions written.
+ */
+ PLPT_STATE_USER_PACKAGES,
+
+ /** User-specified setup lines were written.
+ */
+ PLPT_STATE_USER_SETUP,
+
+ /** The begin document line was written, contents may be added.
+ */
+ PLPT_STATE_IN_DOCUMENT,
+
+ /** Finished, the end document line was written.
+ */
+ PLPT_STATE_AFTER_DOCUMENT
+
+};
+
+
+
+/** Job structure for the plpdftex program.
+*/
+typedef struct {
+ dk3_app_t *app; /**< Application structure. */
+ dkChar const * const *msg; /**< Localized messages texts. */
+ dkChar const * const *kwnl; /**< Keywords not localized. */
+ dkChar const * const *argv; /**< Command line arguments array. */
+ dkChar const *infn; /**< Input file name. */
+ dk3_sto_t *sco; /**< Storage for colors. */
+ dk3_sto_it_t *sico; /**< Storage iterator for colors. */
+ char *fnb1; /**< File name as read from input. */
+ char *fnpdf; /**< File name, PDF output file. */
+ char *fntex; /**< File name, TeX output file. */
+ char *ilbuf; /**< Input line buffer. */
+ dk3_option_set_t *opt; /**< Options. */
+ dk3_pdf_t *opdf; /**< PDF output structure. */
+ FILE *infi; /**< Input file. */
+ FILE *fopdf; /**< PDF output file. */
+ FILE *fotex; /**< TeX output file. */
+ long imgw; /**< Image width. */
+ long imgh; /**< Image height. */
+ size_t szfn; /**< File name buffer size. */
+ size_t szilb; /**< Size of input line buffer. */
+ int state; /**< Current program state. */
+ int exc; /**< Exit code. */
+ int argc; /**< Number of command line arguments. */
+ int stagr; /**< Flag: Produce standalone graphics. */
+} plpdftex_job_t;
+
+
+
+/** Named color.
+*/
+typedef struct {
+ char const *name; /**< Color name. */
+ double r; /**< Red. */
+ double g; /**< Green. */
+ double b; /**< Blue. */
+} plpt_named_color_t;
+
+
+#include "plptcol.h"
+
+
+
+
+#endif
diff --git a/support/dktools/plpdftex.rc b/support/dktools/plpdftex.rc
new file mode 100644
index 0000000000..7566733326
--- /dev/null
+++ b/support/dktools/plpdftex.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Output driver for octpgfpl\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "Output driver for octpgfpl\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "plpdftex\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/plptcol.c b/support/dktools/plptcol.c
new file mode 100644
index 0000000000..8de2e7f3b4
--- /dev/null
+++ b/support/dktools/plptcol.c
@@ -0,0 +1,304 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: plptcol.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file plptcol.c The plptcol module.
+*/
+
+
+#line 62 "plptcol.ctr"
+
+#include "plpdftex.h"
+
+
+
+
+
+#line 68 "plptcol.ctr"
+
+
+
+void
+plptcolor_delete(plpt_named_color_t *ptr)
+{
+ if (ptr) {
+ dk3_release(ptr->name);
+ dk3_delete(ptr);
+ }
+}
+
+
+
+plpt_named_color_t *
+plptcolor_new(char const *name, double r, double g, double b, dk3_app_t *app)
+{
+ plpt_named_color_t *back = NULL;
+ if (name) {
+ back = dk3_new_app(plpt_named_color_t,1,app);
+ if (back) {
+ back->r = r;
+ back->g = g;
+ back->b = b;
+ back->name = dk3str_c8_dup_app(name, app);
+ if (!(back->name)) {
+ dk3_delete(back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+plptcolor_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ plpt_named_color_t *pl;
+ plpt_named_color_t *pr;
+
+ if (l) {
+ if (r) {
+ pl = (plpt_named_color_t *)l;
+ pr = (plpt_named_color_t *)r;
+ switch(cr) {
+ case 1: {
+ if (pl->name) {
+ back = dk3str_c8_cmp(pl->name, (char *)pr);
+ if(-1 > back) back = -1;
+ if( 1 < back) back = 1;
+ } else back = -1;
+ } break;
+ default: {
+ if (pl->name) {
+ if (pr->name) {
+ back = dk3str_c8_cmp(pl->name, pr->name);
+ if(-1 > back) back = -1;
+ if( 1 < back) back = 1;
+ } else back = 1;
+ } else {
+ if (pr->name) back = -1;
+ }
+ } break;
+ }
+ } else back = 1;
+ } else {
+ if (r) back = -1;
+ }
+ return back;
+}
+
+
+
+/** Predefined colors.
+*/
+static plpt_named_color_t const plptc_predefined_colors[] = {
+ { "white", 1.0, 1.0, 1.0 },
+ { "black", 0.0, 0.0, 0.0 },
+ { "red", 1.0, 0.0, 0.0 },
+ { "green", 0.0, 1.0, 0.0 },
+ { "blue", 0.0, 0.0, 1.0 },
+ { "cyan", 0.0, 1.0, 1.0 },
+ { "magenta", 1.0, 0.0, 1.0 },
+ { "yellow", 1.0, 1.0, 0.0 },
+ { "gray", 0.5, 0.5, 0.5 },
+ { "lightgray", 0.75, 0.75, 0.75 },
+ { "darkgray", 0.25, 0.25, 0.25 },
+ { "brown", 0.75, 0.5 , 0.25 },
+ { "lime", 0.75, 1.0 , 0.0 },
+ { "olive", 0.5 , 0.5 , 0.0 },
+ { "orange", 1.0 , 0.5 , 0.0 },
+ { "pink", 1.0 , 0.75, 0.75 },
+ { "purple", 0.75, 0.0 , 0.25 },
+ { "teal", 0.00, 0.5 , 0.5 },
+ { "violet", 0.5 , 0.0 , 0.5 }
+};
+
+/** Number of predefined colors.
+*/
+static size_t const sz_plptc_predefined_colors =
+sizeof(plptc_predefined_colors)/sizeof(plpt_named_color_t);
+
+
+
+/** Find a named color.
+ @param job Job structure.
+ @param txt Color name.
+ @return Pointer to plpt_named_color_t on success, NULL on error.
+*/
+static
+plpt_named_color_t const *
+plptcol_find_color(plpdftex_job_t *job, char const *txt)
+{
+ plpt_named_color_t const *back = NULL;
+ size_t i;
+
+ for (i = 0; i < sz_plptc_predefined_colors; i++) {
+ if (0 == strcmp(txt, plptc_predefined_colors[i].name)) {
+ back = &(plptc_predefined_colors[i]);
+ }
+ }
+ if (NULL == back) {
+ back = (plpt_named_color_t *)dk3sto_it_find_like(
+ job->sico, txt, 1
+ );
+ }
+ return back;
+}
+
+
+
+int
+plptcol_get_color(
+ plpdftex_job_t *job,
+ char *txt,
+ double *r,
+ double *g,
+ double *b
+)
+{
+ plpt_named_color_t const *cptr = NULL;
+ char *stt = NULL; /* Start of text */
+ char *per = NULL; /* Percentage value as text */
+ char *bgc = NULL; /* Background color */
+ char *npt = NULL; /* Next pointer */
+ double rres = 0.0; /* Result value for red */
+ double gres = 0.0; /* Result value for green */
+ double bres = 0.0; /* Result value for blue */
+ double bgr = 0.0; /* Background red */
+ double bgg = 0.0; /* Background green */
+ double bgb = 0.0; /* Background blue */
+ double f = 1.0; /* Factor */
+ int back = 0; /* Function result */
+
+
+#line 225 "plptcol.ctr"
+ /* Check arguments.
+ */
+ if ((NULL == r) || (NULL == g) || (NULL == b)) {
+
+#line 228 "plptcol.ctr"
+ goto finished;
+ }
+ if ((NULL == job) || (NULL == txt)) {
+
+#line 231 "plptcol.ctr"
+ goto cleanup;
+ }
+
+ /* Scan first color component.
+ */
+ stt = txt;
+ dk3str_c8_chomp(stt, NULL);
+ per = strchr(stt, '!');
+ if (NULL != per) { *(per++) = '\0'; }
+ cptr = plptcol_find_color(job, txt);
+ if (NULL == cptr) {
+
+#line 242 "plptcol.ctr"
+ /* ##### ERROR: Color not found! */
+ goto cleanup;
+ }
+ rres = cptr->r;
+
+#line 246 "plptcol.ctr"
+ gres = cptr->g;
+
+#line 247 "plptcol.ctr"
+ bres = cptr->b;
+
+#line 248 "plptcol.ctr"
+
+ /* Mix against further components.
+ */
+ while (NULL != per) {
+ npt = NULL;
+ bgc = strchr(per, '!');
+ if (NULL != bgc) {
+ *(bgc++) = '\0';
+ npt = strchr(bgc, '!');
+ if (NULL != npt) {
+ *(npt++) = '\0';
+ }
+ }
+ if (0 == dk3ma_d_from_c8_string(&f, per, NULL)) {
+ /* ##### ERROR: Not a number */
+
+#line 263 "plptcol.ctr"
+ goto cleanup;
+ }
+ if ((0.0 > f) || (100.0 < f)) {
+
+#line 266 "plptcol.ctr"
+ /* ##### ERROR: Out of range */
+ goto cleanup;
+ }
+ f = f / 100.0;
+ bgr = bgg = bgb = 1.0;
+ if (bgc) {
+ cptr = plptcol_find_color(job, txt);
+ if (NULL == cptr) {
+ /* ##### ERROR: Color not found */
+ goto cleanup;
+ }
+ bgr = cptr->r; bgg = cptr->g; bgb = cptr->b;
+ }
+ rres = f * rres + (1.0 - f) * bgr;
+
+#line 280 "plptcol.ctr"
+ gres = f * gres + (1.0 - f) * bgg;
+
+#line 281 "plptcol.ctr"
+ bres = f * bres + (1.0 - f) * bgb;
+
+#line 282 "plptcol.ctr"
+ per = npt;
+ }
+ back = 1;
+
+#line 285 "plptcol.ctr"
+
+ /* Transfer results and return.
+ */
+ cleanup:
+ *r = rres; *g = gres; *b = bres;
+ finished:
+
+
+#line 292 "plptcol.ctr"
+ return back;
+}
+
+
diff --git a/support/dktools/plptcol.ctr b/support/dktools/plptcol.ctr
new file mode 100644
index 0000000000..c923979636
--- /dev/null
+++ b/support/dktools/plptcol.ctr
@@ -0,0 +1,295 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2014-xxxx
+license = bsd
+
+
+%% header
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Dynamically allocate new color structure.
+ @param name Color name.
+ @param r Red.
+ @param g Green.
+ @param b Blue.
+ @return Pointer to new structure on success, NULL on error.
+*/
+plpt_named_color_t *
+plptcolor_new(char const *name, double r, double g, double b, dk3_app_t *app);
+
+/** Compare two named colors.
+ @param l Left color.
+ @param r Right color.
+ @param cr Comparison criteria (0=name).
+ @return Comparison result.
+*/
+int
+plptcolor_compare(void const *l, void const *r, int cr);
+
+/** Destroy color structure, release memory.
+ @param ptr Color structure to destroy.
+*/
+void
+plptcolor_delete(plpt_named_color_t *ptr);
+
+/** Find color information.
+ @param job Job structure.
+ @param txt LaTeX color specification, i.e. "brown!80!blue",
+ modified during analysis.
+ @param r Pointer to red result variable.
+ @param g Pointer to green result variable.
+ @param b Pointer to blue result variable.
+*/
+int
+plptcol_get_color(
+ plpdftex_job_t *job,
+ char *txt,
+ double *r,
+ double *g,
+ double *b
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+#include "plpdftex.h"
+
+
+
+$!trace-include
+
+
+
+void
+plptcolor_delete(plpt_named_color_t *ptr)
+{
+ if (ptr) {
+ dk3_release(ptr->name);
+ dk3_delete(ptr);
+ }
+}
+
+
+
+plpt_named_color_t *
+plptcolor_new(char const *name, double r, double g, double b, dk3_app_t *app)
+{
+ plpt_named_color_t *back = NULL;
+ if (name) {
+ back = dk3_new_app(plpt_named_color_t,1,app);
+ if (back) {
+ back->r = r;
+ back->g = g;
+ back->b = b;
+ back->name = dk3str_c8_dup_app(name, app);
+ if (!(back->name)) {
+ dk3_delete(back);
+ back = NULL;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+plptcolor_compare(void const *l, void const *r, int cr)
+{
+ int back = 0;
+ plpt_named_color_t *pl;
+ plpt_named_color_t *pr;
+
+ if (l) {
+ if (r) {
+ pl = (plpt_named_color_t *)l;
+ pr = (plpt_named_color_t *)r;
+ switch(cr) {
+ case 1: {
+ if (pl->name) {
+ back = dk3str_c8_cmp(pl->name, (char *)pr);
+ if(-1 > back) back = -1;
+ if( 1 < back) back = 1;
+ } else back = -1;
+ } break;
+ default: {
+ if (pl->name) {
+ if (pr->name) {
+ back = dk3str_c8_cmp(pl->name, pr->name);
+ if(-1 > back) back = -1;
+ if( 1 < back) back = 1;
+ } else back = 1;
+ } else {
+ if (pr->name) back = -1;
+ }
+ } break;
+ }
+ } else back = 1;
+ } else {
+ if (r) back = -1;
+ }
+ return back;
+}
+
+
+
+/** Predefined colors.
+*/
+static plpt_named_color_t const plptc_predefined_colors[] = {
+ { "white", 1.0, 1.0, 1.0 },
+ { "black", 0.0, 0.0, 0.0 },
+ { "red", 1.0, 0.0, 0.0 },
+ { "green", 0.0, 1.0, 0.0 },
+ { "blue", 0.0, 0.0, 1.0 },
+ { "cyan", 0.0, 1.0, 1.0 },
+ { "magenta", 1.0, 0.0, 1.0 },
+ { "yellow", 1.0, 1.0, 0.0 },
+ { "gray", 0.5, 0.5, 0.5 },
+ { "lightgray", 0.75, 0.75, 0.75 },
+ { "darkgray", 0.25, 0.25, 0.25 },
+ { "brown", 0.75, 0.5 , 0.25 },
+ { "lime", 0.75, 1.0 , 0.0 },
+ { "olive", 0.5 , 0.5 , 0.0 },
+ { "orange", 1.0 , 0.5 , 0.0 },
+ { "pink", 1.0 , 0.75, 0.75 },
+ { "purple", 0.75, 0.0 , 0.25 },
+ { "teal", 0.00, 0.5 , 0.5 },
+ { "violet", 0.5 , 0.0 , 0.5 }
+};
+
+/** Number of predefined colors.
+*/
+static size_t const sz_plptc_predefined_colors =
+sizeof(plptc_predefined_colors)/sizeof(plpt_named_color_t);
+
+
+
+/** Find a named color.
+ @param job Job structure.
+ @param txt Color name.
+ @return Pointer to plpt_named_color_t on success, NULL on error.
+*/
+static
+plpt_named_color_t const *
+plptcol_find_color(plpdftex_job_t *job, char const *txt)
+{
+ plpt_named_color_t const *back = NULL;
+ size_t i;
+
+ for (i = 0; i < sz_plptc_predefined_colors; i++) {
+ if (0 == strcmp(txt, plptc_predefined_colors[i].name)) {
+ back = &(plptc_predefined_colors[i]);
+ }
+ }
+ if (NULL == back) {
+ back = (plpt_named_color_t *)dk3sto_it_find_like(
+ job->sico, txt, 1
+ );
+ }
+ return back;
+}
+
+
+
+int
+plptcol_get_color(
+ plpdftex_job_t *job,
+ char *txt,
+ double *r,
+ double *g,
+ double *b
+)
+{
+ plpt_named_color_t const *cptr = NULL;
+ char *stt = NULL; /* Start of text */
+ char *per = NULL; /* Percentage value as text */
+ char *bgc = NULL; /* Background color */
+ char *npt = NULL; /* Next pointer */
+ double rres = 0.0; /* Result value for red */
+ double gres = 0.0; /* Result value for green */
+ double bres = 0.0; /* Result value for blue */
+ double bgr = 0.0; /* Background red */
+ double bgg = 0.0; /* Background green */
+ double bgb = 0.0; /* Background blue */
+ double f = 1.0; /* Factor */
+ int back = 0; /* Function result */
+ $? "+ plptcol_get_color \"%!8s\"", TR_8STR(txt)
+ /* Check arguments.
+ */
+ if ((NULL == r) || (NULL == g) || (NULL == b)) { $? "! r, g, b"
+ goto finished;
+ }
+ if ((NULL == job) || (NULL == txt)) { $? "! job, txt"
+ goto cleanup;
+ }
+
+ /* Scan first color component.
+ */
+ stt = txt;
+ dk3str_c8_chomp(stt, NULL);
+ per = strchr(stt, '!');
+ if (NULL != per) { *(per++) = '\0'; }
+ cptr = plptcol_find_color(job, txt);
+ if (NULL == cptr) { $? "! color not found"
+ /* ##### ERROR: Color not found! */
+ goto cleanup;
+ }
+ rres = cptr->r; $? ". r = %lg", rres
+ gres = cptr->g; $? ". g = %lg", gres
+ bres = cptr->b; $? ". b = %lg", bres
+
+ /* Mix against further components.
+ */
+ while (NULL != per) {
+ npt = NULL;
+ bgc = strchr(per, '!');
+ if (NULL != bgc) {
+ *(bgc++) = '\0';
+ npt = strchr(bgc, '!');
+ if (NULL != npt) {
+ *(npt++) = '\0';
+ }
+ }
+ if (0 == dk3ma_d_from_c8_string(&f, per, NULL)) {
+ /* ##### ERROR: Not a number */ $? "! not a number"
+ goto cleanup;
+ }
+ if ((0.0 > f) || (100.0 < f)) { $? "! out of range"
+ /* ##### ERROR: Out of range */
+ goto cleanup;
+ }
+ f = f / 100.0;
+ bgr = bgg = bgb = 1.0;
+ if (bgc) {
+ cptr = plptcol_find_color(job, txt);
+ if (NULL == cptr) {
+ /* ##### ERROR: Color not found */
+ goto cleanup;
+ }
+ bgr = cptr->r; bgg = cptr->g; bgb = cptr->b;
+ }
+ rres = f * rres + (1.0 - f) * bgr; $? ". r = %lg", rres
+ gres = f * gres + (1.0 - f) * bgg; $? ". g = %lg", gres
+ bres = f * bres + (1.0 - f) * bgb; $? ". b = %lg", bres
+ per = npt;
+ }
+ back = 1; $? ". success"
+
+ /* Transfer results and return.
+ */
+ cleanup:
+ *r = rres; *g = gres; *b = bres;
+ finished:
+ $? "- plptcol_get_color %d rgb=(%lg %lg %lg)", back, rres, gres, bres
+ return back;
+}
+
+
diff --git a/support/dktools/plptcol.h b/support/dktools/plptcol.h
new file mode 100644
index 0000000000..871ed37f76
--- /dev/null
+++ b/support/dktools/plptcol.h
@@ -0,0 +1,98 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: plptcol.ctr
+*/
+
+/*
+Copyright (C) 2014-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file plptcol.h Header file for the plptcol module.
+*/
+
+#ifndef PLPTCOL_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define PLPTCOL_H_INCLUDED 1
+
+
+#line 9 "plptcol.ctr"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Dynamically allocate new color structure.
+ @param name Color name.
+ @param r Red.
+ @param g Green.
+ @param b Blue.
+ @return Pointer to new structure on success, NULL on error.
+*/
+plpt_named_color_t *
+plptcolor_new(char const *name, double r, double g, double b, dk3_app_t *app);
+
+/** Compare two named colors.
+ @param l Left color.
+ @param r Right color.
+ @param cr Comparison criteria (0=name).
+ @return Comparison result.
+*/
+int
+plptcolor_compare(void const *l, void const *r, int cr);
+
+/** Destroy color structure, release memory.
+ @param ptr Color structure to destroy.
+*/
+void
+plptcolor_delete(plpt_named_color_t *ptr);
+
+/** Find color information.
+ @param job Job structure.
+ @param txt LaTeX color specification, i.e. "brown!80!blue",
+ modified during analysis.
+ @param r Pointer to red result variable.
+ @param g Pointer to green result variable.
+ @param b Pointer to blue result variable.
+*/
+int
+plptcol_get_color(
+ plpdftex_job_t *job,
+ char *txt,
+ double *r,
+ double *g,
+ double *b
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
diff --git a/support/dktools/printqd.c b/support/dktools/printqd.c
new file mode 100644
index 0000000000..a2d9562898
--- /dev/null
+++ b/support/dktools/printqd.c
@@ -0,0 +1,8356 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: printqd.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#line 210 "printqd.ctr"
+
+/** @file printqd.c The printqd daemon.
+
+A print accounting and quota daemon for use with the LPRng print system.
+*/
+
+
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+
+
+/* CORRECT NEXT LINE AFTER REPLACING PRINTQD */
+#include "printqd.h"
+
+
+
+#if (DK4_CHAR_SIZE == 1) \
+&& ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET)) \
+&& DK4_HAVE_GETPWNAM && DK4_HAVE_GETGRNAM \
+&& ((DK4_HAVE_SETSID) || (DK4_HAVE_SETPGRP)) \
+&& ((DK4_HAVE_PWD_H) && (DK4_HAVE_GRP_H)) \
+&& DK4_HAVE_UID_T && DK4_HAVE_GID_T && DK4_HAVE_MODE_T && (!DK4_ON_WINDOWS)
+
+
+
+#include <stdio.h>
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_STAT_H
+#ifndef SYS_STAT_H_INCLUDED
+#include <sys/stat.h>
+#define SYS_STAT_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PWD_H
+#ifndef PWD_H_INCLUDED
+#include <pwd.h>
+#define PWD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_GRP_H
+#ifndef GRP_H_INCLUDED
+#include <grp.h>
+#define GRP_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYSLOG_H
+#ifndef SYSLOG_H_INCLUDED
+#include <syslog.h>
+#define SYSLOG_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4opt.h"
+#include "dk4dmt.h"
+#include "dk4inst.h"
+#include "dk4dmt.h"
+#include "dk4sto.h"
+#include "dk4sock.h"
+#include "dk4mem.h"
+#include "dk4str8.h"
+#include "dk4mai8dii.h"
+#include "dk4mai8dsz.h"
+#include "dk4mai8dus.h"
+#include "dk4mai8ddu.h"
+#include "dk4mao8d.h"
+#include "dk4fopc8.h"
+#include "dk4dbi.h"
+#include "dk4dbit8.h"
+#include "dk4time.h"
+#include "dk4time08.h"
+#include "dk4mkdh8.h"
+#include "dk4delfile08.h"
+
+
+
+
+
+#line 319 "printqd.ctr"
+
+
+
+#ifndef LOG_LPR
+/** Default log feature for printing.
+*/
+#define LOG_LPR (6 << 3)
+#endif
+
+
+
+#ifndef LOG_EMERG
+/** Log message level to ignore, printqd does not make system unusable.
+*/
+#define LOG_EMERG (0)
+#endif
+
+#ifndef LOG_ERR
+/** Log message level error.
+*/
+#define LOG_ERR (3)
+#endif
+
+#ifndef LOG_INFO
+/** Log message level info.
+*/
+#define LOG_INFO (6)
+#endif
+
+/** Input buffer, used
+ * for configuration file reading and
+ * for reading requests.
+*/
+static char inbuf[1024];
+
+
+/** Buffer to construct key for database entries.
+*/
+static char kb[sizeof(inbuf)];
+
+
+/** Buffer to construct/convert values for database entries.
+*/
+static char vb[sizeof(inbuf)];
+
+
+/** Options used by the program.
+*/
+static dk4_option_t options[] = {
+
+ /* Debug mode.
+ */
+ { { dkT('d'), dkT("debug"), DK4_OPT_ARG_NONE }, { NULL }, 0 },
+
+ /* Configuration file.
+ */
+ { { dkT('c'), dkT("config"), DK4_OPT_ARG_STRING }, { NULL }, 0 }
+};
+
+
+
+/** Default configuration file name.
+*/
+static const char def_conf_file_name[] = {
+ DK4_INST_DIR_ETC "/printqd/printqd.conf"
+};
+
+
+
+/** Default socket file name.
+*/
+static const char def_sock_file_name[] = {
+ DK4_INST_DIR_VAR "/run/printqd/printqd.sock"
+};
+
+
+
+/** Default database file name.
+*/
+static const char def_db_file_name[] = {
+#if DK4_HAVE_DB_H
+ "bdb::" DK4_INST_DIR_VAR "/lib/printqd/printqd.db"
+#else
+#if DK4_HAVE_NDBM_H
+ "ndbm::" DK4_INST_DIR_VAR "/lib/printqd/printqd"
+#else
+ "mem::" DK4_INST_DIR_VAR "/lib/printqd/printqd.db"
+#endif
+#endif
+};
+
+
+
+/** Default log file name.
+*/
+static const char def_log_file_name[] = {
+ DK4_INST_DIR_VAR "/log/printqd/printqd.log"
+};
+
+
+
+
+/** PID file name.
+*/
+static const char pid_file_name[] = {
+ DK4_INST_DIR_VAR "/run/printqd/printqd.pid"
+};
+
+
+
+/** Constant texts used by the module.
+*/
+static const char * const printqd_kw[] = {
+/* 0 */
+"printqd",
+
+/* 1 */
+"r",
+
+/* 2 */
+"*",
+
+/* 3 */
+"unlimited",
+
+/* 4 */
+"denied",
+
+/* 5 */
+"\n",
+
+/* 6 */
+"# ",
+
+/* 7 */
+": ",
+
+/* 8 */
+":",
+
+/* 9 */
+"ERROR: ",
+
+/* 10 */
+"a",
+
+/* 11 */
+"",
+
+/* 12 */
+"Not an integer number:\n\"",
+
+/* 13 */
+"\", reading stoppend at \"",
+
+/* 14 */
+"\"!",
+
+/* 15 */
+"Positive number required!",
+
+/* 16 */
+"Not a size specification:\n\"",
+
+/* 17 */
+"\", reading stopped at \"",
+
+/* 18 */
+"\"!",
+
+/* 19 */
+"Not a 16 bit unsigned number:\n\"",
+
+/* 20 */
+"\", reading stopped at \"",
+
+/* 21 */
+"\"!",
+
+/* 22 */
+"Port number must not be 0!",
+
+/* 23 */
+"Too much text, unexpected:\n\"",
+
+/* 24 */
+"\"!",
+
+/* 25 */
+"Not a peer definition:\n\"",
+
+/* 26 */
+"\"!",
+
+/* 27 */
+"Not enough memory (allocation failed)!",
+
+/* 28 */
+"Not an unsigned number:\n\"",
+
+/* 29 */
+"\", reading stopped at \"",
+
+/* 30 */
+"\"!",
+
+/* 31 */
+"Missing limit text!",
+
+/* 32 */
+"Limit redefinition for: \"",
+
+/* 33 */
+"\"!",
+
+/* 34 */
+"Redefinition of default limit!",
+
+/* 35 */
+"Redefinition of deny action!",
+
+/* 36 */
+"Printer already exists: \"",
+
+/* 37 */
+"\"!",
+
+/* 38 */
+"Printer alias already exists: \"",
+
+/* 39 */
+"\"!",
+
+/* 40 */
+"Class not found: \"",
+
+/* 41 */
+"\"!",
+
+/* 42 */
+"Redefinition of printers class!",
+
+/* 43 */
+"Class already exists: \"",
+
+/* 44 */
+"\"!",
+
+/* 45 */
+"Missing class name!",
+
+/* 46 */
+"Printer or alias already exists: \"",
+
+/* 47 */
+"\"!",
+
+/* 48 */
+"Missing printer name!",
+
+/* 49 */
+"Illegal section type name: \"",
+
+/* 50 */
+"\"!",
+
+/* 51 */
+"Missing section type!",
+
+/* 52 */
+"Redefinition of user ID to run as!",
+
+/* 53 */
+"User not found: \"",
+
+/* 54 */
+"\"!",
+
+/* 55 */
+"Only allowed in options section!",
+
+/* 56 */
+"Redefinition of group ID to run as!",
+
+/* 57 */
+"Group not found: \"",
+
+/* 58 */
+"\"!",
+
+/* 59 */
+"Redefinition of database name!",
+
+/* 60 */
+"Redefinition of socket name!",
+
+/* 61 */
+"Only allowed in class section!",
+
+/* 62 */
+"Only allowed in printer section!",
+
+/* 63 */
+"Redefinition of log file name!",
+
+/* 64 */
+"Value missing!",
+
+/* 65 */
+"Failed to open file for reading!",
+
+/* 66 */
+"User to run as was changed!",
+
+/* 67 */
+"Group to run as was changed!",
+
+/* 68 */
+"Failed to install signal handlers!",
+
+/* 69 */
+"Failed to restore signal handlers!",
+
+/* 70 */
+": ERROR: Failed to create new process!\n",
+
+/* 71 */
+"Failed to create new process!",
+
+/* 72 */
+"Service start prevented by errors!",
+
+/* 73 */
+"Daemon starting.",
+
+/* 74 */
+"Daemon exited.",
+
+/* 75 */
+"Entering service mode.",
+
+/* 76 */
+"Exiting service mode.",
+
+/* 77 */
+"Exiting service mode for reconfiguration.",
+
+/* 78 */
+"Exited service mode.",
+
+/* 79 */
+"o:test",
+
+/* 80 */
+"ACCEPT",
+
+/* 81 */
+"REMOVE",
+
+/* 82 */
+"HOLD",
+
+/* 83 */
+"0 0 0 0",
+
+/* 84 */
+"-1",
+
+/* 85 */
+" ",
+
+/* 86 */
+"<- ",
+
+/* 87 */
+"-> ",
+
+/* 88 */
+"p:",
+
+/* 89 */
+"a:",
+
+/* 90 */
+"j:",
+
+/* 91 */
+"No class configured for printer: \"",
+
+/* 92 */
+"\"!",
+
+/* 93 */
+"Warning: No default limit configured for class: \"",
+
+/* 94 */
+"\"!",
+
+/* 95 */
+"Failed to create directory hierarchy for log file:\n\"",
+
+/* 96 */
+"\"!",
+
+/* 97 */
+"Failed to create directory hierarchy for database:\n\"",
+
+/* 98 */
+"\"!",
+
+/* 99 */
+"Failed to create directory hierarchy for socket:\n\"",
+
+/* 100 */
+"\"!",
+
+/* 101 */
+"Failed to listen on local socket:\n\"",
+
+/* 102 */
+"\"!",
+
+/* 103 */
+"Failed to create TCP listener socket set!",
+
+/* 104 */
+"Failed to create UDP socket set!",
+
+/* 105 */
+"Failed to open database:\n\"",
+
+/* 106 */
+"\"!",
+
+/* 107 */
+"Failed to write initial entry to database!",
+
+/* 108 */
+"Failed to synchronize database to disk!",
+
+/* 109 */
+"Failed to change log file ownership!",
+
+/* 110 */
+"Failed to change log file permissions!",
+
+/* 111 */
+"Failed to change database ownership and/or permissions!",
+
+/* 112 */
+"Failed to change local socket ownership!",
+
+/* 113 */
+"Failed to change local socket permissions!",
+
+/* 114 */
+"Failed to switch group!",
+
+/* 115 */
+"Failed to switch user!",
+
+/* 116 */
+"Response text too long (bug)!",
+
+/* 117 */
+"Failed to write database entry!",
+
+/* 118 */
+"Failed to delete database entry!",
+
+/* 119 */
+"The select() function failed!",
+
+/* 120 */
+"Insufficient memory!",
+
+/* 121 */
+"Failed to synchronize database to disk!",
+
+/* 122 */
+"DB SET \"",
+
+/* 123 */
+"\"=\"",
+
+/* 124 */
+"\" ok.",
+
+/* 125 */
+"\" FAILED (invalid arguments)!",
+
+/* 126 */
+"\" FAILED (syntax)!",
+
+/* 127 */
+"\" FAILED (numeric overflow in size calculation)!",
+
+/* 128 */
+"\" FAILED (unsupported db backend)!",
+
+/* 129 */
+"\" FAILED (no such entry)!",
+
+/* 130 */
+"\" FAILED (insufficient memory)!",
+
+/* 131 */
+"\" FAILED (can not write)!",
+
+/* 132 */
+"\" FAILED (reason unknown)!",
+
+/* 133 */
+"DB GET \"",
+
+/* 134 */
+"\" FAILED (buffer too small)!",
+
+/* 135 */
+"DB DEL \"",
+
+/* 136 */
+"DB SYN ok.",
+
+/* 137 */
+"DB SYN FAILED (invalid arguments)!",
+
+/* 138 */
+"DB SYN FAILED (unsupported db backend)!",
+
+/* 139 */
+"DB SYN FAILED (syntax)!",
+
+/* 140 */
+"DB SYN FAILED (security checks for file failed)!",
+
+/* 141 */
+"DB SYN FAILED (can not open file for writing)!",
+
+/* 142 */
+"DB SYN FAILED (can not write)!",
+
+/* 143 */
+"DB SYN FAILED (can not close file)!",
+
+/* 144 */
+"DB SYN FAILED (unknown reason)!",
+
+/* 145 */
+"(l=",
+
+/* 146 */
+",u=",
+
+/* 147 */
+",a=",
+
+/* 148 */
+") + u=",
+
+/* 149 */
+" => (l=",
+
+/* 150 */
+")",
+
+/* 151 */
+"unlimited",
+
+/* 152 */
+"p",
+
+/* 153 */
+") + a=",
+
+/* 154 */
+"Illegal log feature name: \"",
+
+/* 155 */
+"\"!",
+
+/* 156 */
+"Failed to update account data for user \"",
+
+/* 157 */
+"\" in class \"",
+
+/* 158 */
+"\"!",
+
+/* 159 */
+"Missing class name in reset request!",
+
+/* 160 */
+"Missing user name in reset request!",
+
+/* 161 */
+"Failed to update account data for user \"",
+
+/* 162 */
+"\" in class \"",
+
+/* 163 */
+"\"!",
+
+/* 164 */
+"No such class: \"",
+
+/* 165 */
+"\"!",
+
+/* 166 */
+"Not a number: \"",
+
+/* 167 */
+"\"!",
+
+/* 168 */
+"Illegal sub-command: \"",
+
+/* 169 */
+"\"!",
+
+/* 170 */
+"Logging to file \"",
+
+/* 171 */
+"\" failed!",
+
+/* 172 */
+"Database modification failed!",
+
+/* 173 */
+"Database synchronization to disk failed!",
+
+/* 174 */
+"Failed to change ownership on database file:\n\"",
+
+/* 175 */
+"\"!",
+
+/* 176 */
+"Failed to change permissions on database file:\n\"",
+
+/* 177 */
+"\"!",
+
+/* 178 */
+"\" (name too long)!",
+
+/* 179 */
+"\" (file exists, but no socket)!",
+
+/* 180 */
+"\" (failed to remove old socket)!",
+
+/* 181 */
+"\" (failed to create socket: ",
+
+/* 182 */
+")!",
+
+/* 183 */
+"\" (failed to bind local ",
+
+/* 184 */
+"\" (failed to listen ",
+
+/* 185 */
+"\" (failed to change ownership)!",
+
+/* 186 */
+"\" (failed to change permissions)!",
+
+/* 187 */
+"Daemon exited due to errors, see log file!",
+
+/* 188 */
+"Failed to create TCP socket set (math overflow)!",
+
+/* 189 */
+"Failed to create TCP socket set (memory)!",
+
+/* 190 */
+"Failed to create TCP socket set (socket(): ",
+
+/* 191 */
+")!",
+
+/* 192 */
+"Failed to create TCP socket set (bind(): ",
+
+/* 193 */
+"Failed to create TCP socket set (listen(): ",
+
+/* 194 */
+"Failed to create TCP socket set (getaddrinfo(): ",
+
+/* 195 */
+"Failed to create UDP socket set (math overflow)!",
+
+/* 196 */
+"Failed to create UDP socket set (memory)!",
+
+/* 197 */
+"Failed to create UDP socket set (socket(): ",
+
+/* 198 */
+")!",
+
+/* 199 */
+"Failed to create UDP socket set (bind(): ",
+
+/* 200 */
+"Failed to create UDP socket set (listen(): ",
+
+/* 201 */
+"Failed to create UDP socket set (getaddrinfo(): ",
+
+/* 202 */
+"\" (backend type not supported)!",
+
+/* 203 */
+"\" (overflow in size calculation)!",
+
+/* 204 */
+"\" (insufficient memory)!",
+
+/* 205 */
+"\"\n(not a regular file / not a database / key or value size too large)!",
+
+/* 206 */
+"\" (denied by security check)!",
+
+/* 207 */
+"\" (failed to open for reading)!",
+
+/* 208 */
+"\" (failed to write to file)!",
+
+/* 209 */
+"\" (failed to synchronize to disk)!",
+
+/* 210 */
+"Failed to write initial entry to database (key or value too long)!",
+
+/* 211 */
+"Failed to write initial entry to database (unsupported backend type)!",
+
+/* 212 */
+"Failed to write initial entry to database (insufficient memory)!",
+
+/* 213 */
+"Failed to write initial entry to database (can not open file for writing)!",
+
+/* 214 */
+"Failed to write initial entry to database (can not write to file)!",
+
+/* 215 */
+"Failed to write initial entry to database (can not synchronize to disk)!",
+
+/* 216 */
+"Failed to write initial entry to database (denied by security check)!",
+
+/* 217 */
+"Failed to change PID file ownership!",
+
+/* 218 */
+"Failed to change PID file permissions!",
+
+NULL
+
+
+#line 1013 "printqd.ctr"
+};
+
+
+
+/** Choices for deny action.
+*/
+static const char * const deny_action_names[] = {
+/* 0 */
+"remove",
+
+/* 1 */
+"hold",
+
+NULL
+
+
+#line 1024 "printqd.ctr"
+};
+
+
+
+/** Section names in configuration files.
+*/
+static const char * const config_section_names[] = {
+/* 0 */
+"options",
+
+/* 1 */
+"class",
+
+/* 2 */
+"printer",
+
+NULL
+
+
+#line 1036 "printqd.ctr"
+};
+
+
+
+/** Option names in configuration file.
+*/
+static const char * const config_option_names[] = {
+/* 0 */
+"run as user",
+
+/* 1 */
+"run as group",
+
+/* 2 */
+"database",
+
+/* 3 */
+"local socket",
+
+/* 4 */
+"local socket backlog",
+
+/* 5 */
+"max local connections",
+
+/* 6 */
+"udp port",
+
+/* 7 */
+"tcp port",
+
+/* 8 */
+"tcp port backlog",
+
+/* 9 */
+"max tcp connections",
+
+/* 10 */
+"info allow",
+
+/* 11 */
+"data allow",
+
+/* 12 */
+"admin allow",
+
+/* 13 */
+"user limit",
+
+/* 14 */
+"group limit",
+
+/* 15 */
+"default limit",
+
+/* 16 */
+"deny action",
+
+/* 17 */
+"alias",
+
+/* 18 */
+"class",
+
+/* 19 */
+"log file",
+
+/* 20 */
+"log features",
+
+/* 21 */
+"local socket owner",
+
+/* 22 */
+"local socket group",
+
+NULL
+
+
+#line 1101 "printqd.ctr"
+};
+
+
+
+/** Command names in the printqd protocol.
+*/
+static const char * const pqd_command_names[] = {
+/* 0 */
+"jobstart",
+
+/* 1 */
+"jobend",
+
+/* 2 */
+"start",
+
+/* 3 */
+"end",
+
+/* 4 */
+"filestart",
+
+/* 5 */
+"fileend",
+
+/* 6 */
+"info",
+
+/* 7 */
+"acct-check",
+
+/* 8 */
+"acct-start",
+
+/* 9 */
+"acct-end",
+
+/* 10 */
+"acct-charge",
+
+/* 11 */
+"control",
+
+NULL
+
+
+#line 1122 "printqd.ctr"
+};
+
+
+
+/** Sub-commands of control.
+*/
+static const char * const control_sub_cmds[] = {
+/* 0 */
+"r$eset",
+
+/* 1 */
+"a$dd",
+
+/* 2 */
+"d$atabase-cleanup",
+
+NULL
+
+
+#line 1134 "printqd.ctr"
+};
+
+
+
+/** Argument names for control requests.
+*/
+static const char * const control_arg_names[] = {
+/* 0 */
+"c$lass",
+
+/* 1 */
+"u$ser",
+
+/* 2 */
+"p$ages",
+
+NULL
+
+
+#line 1146 "printqd.ctr"
+};
+
+
+
+/** Log feature names.
+*/
+static const char * const log_feature_names[] = {
+/* 0 */
+"db",
+
+/* 1 */
+"info",
+
+/* 2 */
+"all",
+
+/* 3 */
+"*",
+
+/* 4 */
+"none",
+
+/* 5 */
+"-",
+
+NULL
+
+
+#line 1161 "printqd.ctr"
+};
+
+
+
+static const char * const db_type_names[] = {
+/* 0 */
+"p",
+
+/* 1 */
+"a",
+
+/* 2 */
+"j",
+
+NULL
+
+
+#line 1171 "printqd.ctr"
+};
+
+
+/** Daemon configuration.
+*/
+static pqd_conf_t conf;
+
+
+
+/** Connections over local socket, stores pqd_l_conn_t.
+ Not NULL in service (service is not run if allocation fails).
+*/
+static dk4_sto_t *s_c_unix = NULL;
+
+
+
+/** Iterator through s_c_unix container.
+ Not NULL in service (service is not run if allocation failes).
+*/
+static dk4_sto_it_t *i_c_unix = NULL;
+
+
+
+/** Container for TCP connections, stores pqd_n_conn_t.
+ Not NULL in service (service is not run if allocation fails).
+*/
+static dk4_sto_t *s_c_tcp = NULL;
+
+
+
+/** Iterator through s_c_tcp container.
+ Not NULL in service (service is not run if allocation fails).
+*/
+static dk4_sto_it_t *i_c_tcp = NULL;
+
+
+
+/** To accept TCP connections.
+ May be NULL in service, if no TCP port number is conigured.
+*/
+static dk4_socket_set_t *ss_tcp = NULL;
+
+
+
+/** For info requests.
+ May be NULL in service, if no UDP port number is configured.
+*/
+static dk4_socket_set_t *ss_udp = NULL;
+
+
+
+/** Database.
+ Not NULL in service (service is not run if allocation fails).
+*/
+static dk4_dbi_t *db = NULL;
+
+
+
+/** Number of options in the options array.
+*/
+static const size_t szoptions = sizeof(options)/sizeof(dk4_option_t);
+
+
+
+/** Current connections on local socket.
+*/
+static size_t con_loc = 0;
+
+
+
+/** Current connections on TCP socket.
+*/
+static size_t con_tcp = 0;
+
+
+
+/** Timestamp of previous log message.
+*/
+static dk4_time_t prev_log_time = (dk4_time_t)0UL;
+
+
+
+/** Listen for incoming UNIX connection requests.
+ Always set in service, service exits when failed to
+ bind local address.
+*/
+static dk4_socket_t so_unix = INVALID_SOCKET;
+
+
+
+/** Program exit code, either EXIT_FAILURE or EXIT_SUCCESS.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+/** Flag: can continue outer (and inner) loop, 1=yes, 0=no, -1=abort.
+*/
+static int ccouter = 1;
+
+
+
+/** Flag: can continue inner loop, 1=yes, 0=no, -1=abort.
+*/
+static int ccinner = 1;
+
+
+
+/** Flag: User and group switching was already done.
+*/
+static int user_switched = 0;
+
+
+
+/** Syslog feature to use.
+*/
+static int syslogf = LOG_LPR;
+
+
+/** Flag: Modified since last synchronization.
+*/
+static int db_modified = 0;
+
+
+/** Flag: Debug mode, process runs in foreground and logs to stderr.
+*/
+static int debug = 0;
+
+
+/** Flag: Previous attempt to log to file failed.
+*/
+static int prev_filelog_failed = 0;
+
+
+/** Flag: Previous database modification failed.
+*/
+static int prev_dbmod_failed = 0;
+
+
+/** Flag: Previous database synchronization to disk failed.
+*/
+static int prev_dbsync_failed = 0;
+
+
+/** UID in previous pass.
+*/
+static uid_t prev_uid = (uid_t)0;
+
+
+
+/** GID in previous pass.
+*/
+static gid_t prev_gid = (gid_t)0;
+
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+#ifdef SIGHUP
+/** Indicator: SIGHUP signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_hup = 0;
+#endif
+
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+/** Pass pointer through.
+ Use of this function is recommended by CERT C coding standard
+ to avoid optimizing out.
+ @param ptr Pointer to pass through.
+ @return The ptr argument.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+
+
+#ifdef SIGHUP
+/** Handler for SIGHUP signal.
+ @param signo Signal number (always SIGHUP, ignored).
+*/
+static
+void
+sig_handler_hup(int signo)
+{
+ *sig_pass_pointer(&sig_had_hup) = 1;
+}
+#endif
+
+
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+
+
+/** Check whether we can continue or must abort due to signal.
+ @param dopipe Flag: Check for SIGPIPE too.
+ @return 1 if we can continue, 0 otherwise.
+*/
+static
+int
+can_continue(int dohup, int dopipe)
+{
+ int back = 1;
+
+
+#line 1451 "printqd.ctr"
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_int)) { back = 0; }
+#ifdef SIGHUP
+ if (0 != dohup) {
+ if (0 != sig_read_atomic(&sig_had_hup)) { back = 0; }
+ if (1 > ccinner) { back = 0; }
+ }
+#endif
+#ifdef SIGPIPE
+ if (0 != dopipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ if (1 > ccouter) { back = 0; }
+
+
+#line 1466 "printqd.ctr"
+ return back;
+}
+
+
+
+/** Log a multi part message to file, either stderr or log file.
+ @param fipo Output file.
+ @param timebuf Text buffer containing timestamp.
+ @param sourcefile Source file name.
+ @param linebuf Text buffer containing source file line number.
+ @param error Flag: Insert keyword "ERROR:"
+ @param shtime Flag: Show timestamp from buffer.
+ @param shline Flag: Show line number from buffer.
+ @param msgs Array containing the message parts.
+ @param szmsgs Number of elements in msgs array.
+
+*/
+static
+void
+log_file_multipart_message(
+ FILE *fipo,
+ const char *timebuf,
+ const char *sourcefile,
+ const char *linebuf,
+ int error,
+ int shtime,
+ int shline,
+ const char * const *msgs,
+ size_t szmsgs
+)
+{
+ size_t i;
+
+
+#line 1499 "printqd.ctr"
+ if (0 != shtime) {
+ fputs(printqd_kw[6], fipo);
+ fputs(timebuf, fipo);
+ fputs(printqd_kw[5], fipo);
+ }
+ if (NULL != sourcefile) {
+ fputs(sourcefile, fipo);
+ if (0 != shline) {
+ fputs(printqd_kw[8], fipo);
+ fputs(linebuf, fipo);
+ }
+ fputs(printqd_kw[7], fipo);
+ }
+ if (0 != error) {
+ fputs(printqd_kw[9], fipo);
+ }
+ for (i = 0; i < szmsgs; i++) {
+ if (NULL != msgs[i]) {
+ fputs(msgs[i], fipo);
+ }
+ }
+ fputs(printqd_kw[5], fipo);
+ fflush(fipo);
+
+
+#line 1523 "printqd.ctr"
+}
+
+
+
+/** Write a log message consisting of multiple parts.
+ @param sourcefile Configuration file name.
+ @param sourceline Configuration file line number.
+ @param sll Syslog level.
+ @param msgs Array containing the message parts.
+ @param szmsgs Number of elements in msgs array.
+*/
+static
+void
+log_multipart_message(
+ const char *sourcefile,
+ unsigned long sourceline,
+ int sll,
+ int error,
+ char const * const *msgs,
+ size_t szmsgs
+)
+{
+ char timebuf[64];
+ char linebuf[64];
+ FILE *fipo;
+ const char *lfn;
+ dk4_time_t current;
+ int stests = DK4_FOPEN_SC_PRIVILEGED;
+ int shtime = 0;
+ int shline = 0;
+
+
+#line 1554 "printqd.ctr"
+ /* Check whether to prepend a timestamp line.
+ */
+ dk4time_get(&current);
+ if (current != prev_log_time) {
+ prev_log_time = current;
+ if (0 != dk4time_as_text_c8(timebuf, sizeof(timebuf), &current, NULL)) {
+ shtime = 1;
+ }
+ }
+
+ /* Check whether to prepend source file name and line number.
+ */
+ if ((NULL != sourcefile) && ((dk4_um_t)0UL != sourceline)) {
+ shline = dk4ma_write_c8_decimal_unsigned(
+ linebuf, sizeof(linebuf), (dk4_um_t)sourceline, 0, NULL
+ );
+ }
+
+ /* Output to log file.
+ */
+ lfn = conf.lname;
+ if (NULL == lfn) { lfn = def_log_file_name; }
+ fipo = dk4fopen_c8(lfn, printqd_kw[10], stests, NULL);
+ if (NULL != fipo) {
+ prev_filelog_failed = 0;
+ log_file_multipart_message(
+ fipo, timebuf, sourcefile, linebuf, error, shtime, shline, msgs, szmsgs
+ );
+ fclose(fipo);
+ } else {
+#if DK4_HAVE_SYSLOG
+ if (0 == prev_filelog_failed) {
+ openlog(printqd_kw[0], LOG_PID, syslogf);
+ syslog(LOG_ERR, "%s%s%s", printqd_kw[170], lfn, printqd_kw[171]);
+ closelog();
+ }
+#endif
+ prev_filelog_failed = 1;
+ }
+
+ /* Output to stderr when debugging.
+ */
+ if (0 != debug) {
+ log_file_multipart_message(
+ stderr, timebuf, sourcefile, linebuf, error, shtime, shline, msgs, szmsgs
+ );
+ }
+
+ /* Output to syslog.
+ */
+ if (LOG_EMERG != sll) {
+#if DK4_HAVE_SYSLOG
+ openlog(printqd_kw[0], LOG_PID, syslogf);
+ if (1 < szmsgs) {
+ if (2 < szmsgs) {
+ if (3 < szmsgs) {
+ if (4 < szmsgs) {
+ if (5 < szmsgs) {
+ if (6 < szmsgs) {
+ if (7 < szmsgs) {
+ if (8 < szmsgs) {
+ syslog(
+ sll, "%s%s%s%s%s%s%s%s%s",
+ ((NULL != msgs[0]) ? (msgs[0]) : (printqd_kw[11])),
+ ((NULL != msgs[1]) ? (msgs[1]) : (printqd_kw[11])),
+ ((NULL != msgs[2]) ? (msgs[2]) : (printqd_kw[11])),
+ ((NULL != msgs[3]) ? (msgs[3]) : (printqd_kw[11])),
+ ((NULL != msgs[4]) ? (msgs[4]) : (printqd_kw[11])),
+ ((NULL != msgs[5]) ? (msgs[5]) : (printqd_kw[11])),
+ ((NULL != msgs[6]) ? (msgs[6]) : (printqd_kw[11])),
+ ((NULL != msgs[7]) ? (msgs[7]) : (printqd_kw[11])),
+ ((NULL != msgs[8]) ? (msgs[8]) : (printqd_kw[11]))
+ );
+ } else {
+ syslog(
+ sll, "%s%s%s%s%s%s%s%s",
+ ((NULL != msgs[0]) ? (msgs[0]) : (printqd_kw[11])),
+ ((NULL != msgs[1]) ? (msgs[1]) : (printqd_kw[11])),
+ ((NULL != msgs[2]) ? (msgs[2]) : (printqd_kw[11])),
+ ((NULL != msgs[3]) ? (msgs[3]) : (printqd_kw[11])),
+ ((NULL != msgs[4]) ? (msgs[4]) : (printqd_kw[11])),
+ ((NULL != msgs[5]) ? (msgs[5]) : (printqd_kw[11])),
+ ((NULL != msgs[6]) ? (msgs[6]) : (printqd_kw[11])),
+ ((NULL != msgs[7]) ? (msgs[7]) : (printqd_kw[11]))
+ );
+ }
+ } else {
+ syslog(
+ sll, "%s%s%s%s%s%s%s",
+ ((NULL != msgs[0]) ? (msgs[0]) : (printqd_kw[11])),
+ ((NULL != msgs[1]) ? (msgs[1]) : (printqd_kw[11])),
+ ((NULL != msgs[2]) ? (msgs[2]) : (printqd_kw[11])),
+ ((NULL != msgs[3]) ? (msgs[3]) : (printqd_kw[11])),
+ ((NULL != msgs[4]) ? (msgs[4]) : (printqd_kw[11])),
+ ((NULL != msgs[5]) ? (msgs[5]) : (printqd_kw[11])),
+ ((NULL != msgs[6]) ? (msgs[6]) : (printqd_kw[11]))
+ );
+ }
+ } else {
+ syslog(
+ sll, "%s%s%s%s%s%s",
+ ((NULL != msgs[0]) ? (msgs[0]) : (printqd_kw[11])),
+ ((NULL != msgs[1]) ? (msgs[1]) : (printqd_kw[11])),
+ ((NULL != msgs[2]) ? (msgs[2]) : (printqd_kw[11])),
+ ((NULL != msgs[3]) ? (msgs[3]) : (printqd_kw[11])),
+ ((NULL != msgs[4]) ? (msgs[4]) : (printqd_kw[11])),
+ ((NULL != msgs[5]) ? (msgs[5]) : (printqd_kw[11]))
+ );
+ }
+ } else {
+ syslog(
+ sll, "%s%s%s%s%s",
+ ((NULL != msgs[0]) ? (msgs[0]) : (printqd_kw[11])),
+ ((NULL != msgs[1]) ? (msgs[1]) : (printqd_kw[11])),
+ ((NULL != msgs[2]) ? (msgs[2]) : (printqd_kw[11])),
+ ((NULL != msgs[3]) ? (msgs[3]) : (printqd_kw[11])),
+ ((NULL != msgs[4]) ? (msgs[4]) : (printqd_kw[11]))
+ );
+ }
+ } else {
+ syslog(
+ sll, "%s%s%s%s",
+ ((NULL != msgs[0]) ? (msgs[0]) : (printqd_kw[11])),
+ ((NULL != msgs[1]) ? (msgs[1]) : (printqd_kw[11])),
+ ((NULL != msgs[2]) ? (msgs[2]) : (printqd_kw[11])),
+ ((NULL != msgs[3]) ? (msgs[3]) : (printqd_kw[11]))
+ );
+ }
+ } else {
+ syslog(
+ sll, "%s%s%s",
+ ((NULL != msgs[0]) ? (msgs[0]) : (printqd_kw[11])),
+ ((NULL != msgs[1]) ? (msgs[1]) : (printqd_kw[11])),
+ ((NULL != msgs[2]) ? (msgs[2]) : (printqd_kw[11]))
+ );
+ }
+ } else {
+ syslog(
+ sll, "%s%s",
+ ((NULL != msgs[0]) ? (msgs[0]) : (printqd_kw[11])),
+ ((NULL != msgs[1]) ? (msgs[1]) : (printqd_kw[11]))
+ );
+ }
+ } else {
+ syslog(
+ sll, "%s",
+ ((NULL != msgs[0]) ? (msgs[0]) : (printqd_kw[11]))
+ );
+ }
+ closelog();
+#endif
+ }
+
+
+#line 1707 "printqd.ctr"
+}
+
+
+
+static
+void
+log_1(
+ const char *sourcefile,
+ unsigned long sourceline,
+ int sll,
+ int error,
+ size_t i1
+)
+{
+ const char *msgs[2];
+
+
+#line 1723 "printqd.ctr"
+ msgs[0] = printqd_kw[i1];
+ msgs[1] = NULL;
+ log_multipart_message(sourcefile, sourceline, sll, error, msgs, 1);
+
+
+#line 1727 "printqd.ctr"
+}
+
+
+
+static
+void
+log_3(
+ const char *sourcefile,
+ unsigned long sourceline,
+ int sll,
+ int error,
+ size_t i1,
+ size_t i2,
+ const char *s1
+)
+{
+ const char *msgs[4];
+
+
+#line 1745 "printqd.ctr"
+ msgs[0] = printqd_kw[i1];
+ msgs[1] = s1;
+ msgs[2] = printqd_kw[i2];
+ msgs[3] = NULL;
+ log_multipart_message(sourcefile, sourceline, sll, error, msgs, 3);
+
+
+#line 1751 "printqd.ctr"
+}
+
+
+
+static
+void
+log_5(
+ const char *sourcefile,
+ unsigned long sourceline,
+ int sll,
+ int error,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ const char *s1,
+ const char *s2
+)
+{
+ const char *msgs[6];
+
+
+#line 1771 "printqd.ctr"
+ msgs[0] = printqd_kw[i1];
+ msgs[1] = s1;
+ msgs[2] = printqd_kw[i2];
+ msgs[3] = s2;
+ msgs[4] = printqd_kw[i3];
+ msgs[5] = NULL;
+ log_multipart_message(sourcefile, sourceline, sll, error, msgs, 5);
+
+
+#line 1779 "printqd.ctr"
+}
+
+
+
+/** Set database entry (create or modify).
+ @param db Database to modify.
+ @param k Key.
+ @param v Value.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dbi_set(
+ dk4_dbi_t *db,
+ const char *k,
+ const char *v,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er;
+ int back = 0;
+
+ dk4error_init(&er);
+ back = dk4dbi_c8_set(db, k, v, &er);
+ dk4error_copy(erp, &er);
+ db_modified = 1;
+ if (0 != back) {
+ prev_dbmod_failed = 0;
+ if (0 != conf.ldb) {
+ log_5(NULL, 0UL, LOG_EMERG, 0, 122, 123, 124, k, v);
+ }
+ } else {
+#if DK4_HAVE_SYSLOG
+ if (0 == prev_dbmod_failed) {
+ openlog(printqd_kw[0], LOG_PID, syslogf);
+ syslog(LOG_ERR, "%s", printqd_kw[172]);
+ closelog();
+ }
+#endif
+ prev_dbmod_failed = 1;
+ switch (er.ec) {
+ case DK4_E_INVALID_ARGUMENTS : {
+ log_5(NULL, 0UL, LOG_EMERG, 1, 122, 123, 125, k, v);
+ } break;
+ case DK4_E_SYNTAX : {
+ log_5(NULL, 0UL, LOG_EMERG, 1, 122, 123, 126, k, v);
+ } break;
+ case DK4_E_MATH_OVERFLOW : {
+ log_5(NULL, 0UL, LOG_EMERG, 1, 122, 123, 127, k, v);
+ } break;
+ case DK4_E_NOT_SUPPORTED : {
+ log_5(NULL, 0UL, LOG_EMERG, 1, 122, 123, 128, k, v);
+ } break;
+ case DK4_E_NOT_FOUND : {
+ log_5(NULL, 0UL, LOG_EMERG, 1, 122, 123, 129, k, v);
+ } break;
+ case DK4_E_MEMORY_ALLOCATION_FAILED : {
+ log_5(NULL, 0UL, LOG_EMERG, 1, 122, 123, 130, k, v);
+ } break;
+ case DK4_E_WRITE_FAILED : {
+ log_5(NULL, 0UL, LOG_EMERG, 1, 122, 123, 131, k, v);
+ } break;
+ default : {
+ log_5(NULL, 0UL, LOG_EMERG, 1, 122, 123, 132, k, v);
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+/** Retrieve database entry.
+ @param db Database to retrieve data from.
+ @param k Key text.
+ @param vbuf Buffer for text value.
+ @param vsz Size of buffer.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dbi_get(
+ dk4_dbi_t *db,
+ const char *k,
+ char *vbuf,
+ size_t vsz,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er;
+ int back = 0;
+
+ dk4error_init(&er);
+ back = dk4dbi_c8_get(db, k, vbuf, vsz, &er);
+ dk4error_copy(erp, &er);
+ if (0 != back) {
+ if (0 != conf.ldb) {
+ log_5(NULL, 0UL, LOG_EMERG, 0, 133, 123, 124, k, vbuf);
+ }
+ } else {
+ switch (er.ec) {
+ case DK4_E_INVALID_ARGUMENTS : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 133, 125, k);
+ } break;
+ case DK4_E_MATH_OVERFLOW : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 133, 127, k);
+ } break;
+ case DK4_E_NOT_SUPPORTED : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 133, 128, k);
+ } break;
+ case DK4_E_NOT_FOUND : {
+ if (0 != conf.ldb) {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 133, 129, k);
+ }
+ } break;
+ case DK4_E_BUFFER_TOO_SMALL : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 133, 134, k);
+ } break;
+ default : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 133, 132, k);
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+/** Delete DB entry if it exists.
+ @param db Database to modify.
+ @param k Key.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dbi_del(
+ dk4_dbi_t *db,
+ const char *k,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er;
+ int back = 0;
+
+ dk4error_init(&er);
+ back = dk4dbi_c8_del(db, k, &er);
+ dk4error_copy(erp, &er);
+ db_modified = 1;
+ if (0 != back) {
+ prev_dbmod_failed = 0;
+ if (0 != conf.ldb) {
+ log_3(NULL, 0UL, LOG_EMERG, 0, 135, 124, k);
+ }
+ } else {
+ if (DK4_E_NOT_FOUND != er.ec) {
+#if DK4_HAVE_SYSLOG
+ if (0 == prev_dbmod_failed) {
+ openlog(printqd_kw[0], LOG_PID, syslogf);
+ syslog(LOG_ERR, "%s", printqd_kw[172]);
+ closelog();
+ }
+#endif
+ prev_dbmod_failed = 1;
+ }
+ switch (er.ec) {
+ case DK4_E_INVALID_ARGUMENTS : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 135, 125, k);
+ } break;
+ case DK4_E_SYNTAX : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 135, 126, k);
+ } break;
+ case DK4_E_MATH_OVERFLOW : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 135, 127, k);
+ } break;
+ case DK4_E_NOT_SUPPORTED : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 135, 128, k);
+ } break;
+ case DK4_E_WRITE_FAILED : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 135, 131, k);
+ } break;
+ case DK4_E_NOT_FOUND : {
+ if (0 != conf.ldb) {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 135, 129, k);
+ }
+ } break;
+ default : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 135, 132, k);
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+/** Synchronize database modifications to disk, if any.
+ @param db Database.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dbi_sync(dk4_dbi_t *db, dk4_er_t *erp)
+{
+ dk4_er_t er;
+ int back = 0;
+ if (0 != db_modified) {
+ dk4error_init(&er);
+ back = dk4dbi_sync(db, &er);
+ dk4error_copy(erp, &er);
+ if (0 != back) {
+ db_modified = 0;
+ prev_dbsync_failed = 0;
+ if (0 != conf.ldb) {
+ log_1(NULL, 0UL, LOG_EMERG, 0, 136);
+ }
+ } else {
+#if DK4_HAVE_SYSLOG
+ if (0 == prev_dbsync_failed) {
+ openlog(printqd_kw[0], LOG_PID, syslogf);
+ syslog(LOG_ERR, "%s", printqd_kw[173]);
+ closelog();
+ }
+#endif
+ prev_dbsync_failed = 1;
+ switch (er.ec) {
+ case DK4_E_INVALID_ARGUMENTS : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 137);
+ } break;
+ case DK4_E_NOT_SUPPORTED : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 138);
+ } break;
+ case DK4_E_SYNTAX : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 139);
+ } break;
+ case DK4_E_SEC_CHECK : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 140);
+ } break;
+ case DK4_E_OPEN_WRITE_FAILED : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 141);
+ } break;
+ case DK4_E_WRITE_FAILED : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 142);
+ } break;
+ case DK4_E_CLOSE_FAILED : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 143);
+ } break;
+ default : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 144);
+ } break;
+ }
+ }
+ } else {
+ back = 1;
+ }
+ return back;
+}
+
+
+
+/** Compare two pqd_l_conn_t structures.
+ @param l Left object.
+ @param r Right object.
+ @param cr Comparison criteria, ignored.
+ @return Comparison result.
+*/
+static
+int
+compare_pqd_l_conn_t(const void *l, const void *r, int cr)
+{
+ const pqd_l_conn_t *pl;
+ const pqd_l_conn_t *pr;
+ int back = 0;
+
+
+#line 2056 "printqd.ctr"
+ if (NULL != l) {
+ if (NULL != r) {
+ pl = (const pqd_l_conn_t *)l;
+ pr = (const pqd_l_conn_t *)r;
+ if (pl->sock > pr->sock) {
+ back = 1;
+ } else {
+ if (pl->sock < pr->sock) {
+ back = -1;
+ }
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != r) { back = -1; }
+ }
+
+
+#line 2074 "printqd.ctr"
+ return back;
+}
+
+
+
+/** Compare two pqd_n_conn_t structures.
+ @param l Left object.
+ @param r Right object.
+ @param cr Comparison criteria, ignored.
+ @return Comparison result.
+*/
+static
+int
+compare_pqd_n_conn_t(const void *l, const void *r, int cr)
+{
+ const pqd_n_conn_t *pl;
+ const pqd_n_conn_t *pr;
+ int back = 0;
+
+
+#line 2093 "printqd.ctr"
+ if (NULL != l) {
+ if (NULL != r) {
+ pl = (const pqd_n_conn_t *)l;
+ pr = (const pqd_n_conn_t *)r;
+ if (pl->sock > pr->sock) {
+ back = 1;
+ } else {
+ if (pl->sock < pr->sock) {
+ back = -1;
+ }
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != r) { back = -1; }
+ }
+
+
+#line 2111 "printqd.ctr"
+ return back;
+}
+
+
+
+/** Delete a limit structure (release memory).
+ @param ptr Limit to delete.
+*/
+static
+void
+limit_delete(pqd_limit_t *ptr)
+{
+
+
+#line 2124 "printqd.ctr"
+ if (NULL != ptr) {
+
+#line 2125 "printqd.ctr"
+ dk4mem_release(ptr->name);
+ ptr->limit = (dk4_um_t)0UL;
+ dk4mem_free(ptr);
+ }
+
+
+#line 2130 "printqd.ctr"
+}
+
+
+
+/** Create limit structure (allocate memory).
+ @param name User or group name.
+ @param max Maximum page number.
+ @return Valid pointer on success, NULL on error.
+*/
+static
+pqd_limit_t *
+limit_new(const char *name, dk4_um_t max)
+{
+ pqd_limit_t *back = NULL;
+
+
+#line 2145 "printqd.ctr"
+ if (NULL != name) {
+
+#line 2146 "printqd.ctr"
+ back = dk4mem_new(pqd_limit_t,1,NULL);
+ if (NULL != back) {
+
+#line 2148 "printqd.ctr"
+ back->limit = max;
+ back->name = dk4str8_dup(name, NULL);
+ if (NULL == back->name) {
+
+#line 2151 "printqd.ctr"
+ limit_delete(back);
+ back = NULL;
+ }
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 2157 "printqd.ctr"
+ }
+#endif
+ }
+
+#line 2160 "printqd.ctr"
+ return back;
+}
+
+
+
+/** Compare limit structures.
+ @param l Left object.
+ @param r Right object.
+ @param cr Comparison criteria (0=limit/limit, 1=limit/name).
+ @return Comparison result.
+*/
+static
+int
+limit_compare(const void *l, const void *r, int cr)
+{
+ const pqd_limit_t *pl;
+ const pqd_limit_t *pr;
+
+
+#line 2178 "printqd.ctr"
+ int back = 0;
+ if (NULL != l) {
+ if (NULL != r) {
+ pl = (const pqd_limit_t *)l;
+ switch (cr) {
+ case 1: {
+ if (NULL != pl->name) {
+ back = strcmp(pl->name, (const char *)r);
+ if (-1 > back) { back = -1; }
+ if ( 1 < back) { back = 1; }
+ } else { back = -1; }
+ } break;
+ default: {
+ pr = (const pqd_limit_t *)r;
+ if (NULL != pl->name) {
+ if (NULL != pr->name) {
+ back = strcmp(pl->name, pr->name);
+ if (-1 > back) { back = -1; }
+ if ( 1 < back) { back = 1; }
+ } else { back = 1; }
+ } else {
+ if (NULL != pr->name) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if (NULL != r) { back = -1; }
+ }
+
+#line 2207 "printqd.ctr"
+ return back;
+}
+
+
+
+/** Delete all limits in a storage.
+ @param it Storage iterator.
+*/
+static
+void
+limit_all_delete(dk4_sto_it_t *it)
+{
+ pqd_limit_t *ptr;
+
+
+
+#line 2222 "printqd.ctr"
+ dk4sto_it_reset(it);
+ do {
+ ptr = (pqd_limit_t *)dk4sto_it_next(it);
+ if (NULL != ptr) {
+ limit_delete(ptr);
+ }
+ } while (NULL != ptr);
+ dk4sto_it_close(it);
+
+
+#line 2231 "printqd.ctr"
+}
+
+
+
+/** Delete a class structure (release memory).
+ @param ptr Class to delete.
+*/
+static
+void
+class_delete(pqd_class_t *ptr)
+{
+
+
+#line 2243 "printqd.ctr"
+ if (NULL != ptr) {
+
+#line 2244 "printqd.ctr"
+ dk4mem_release(ptr->name);
+ if (NULL != ptr->i_u) {
+ limit_all_delete(ptr->i_u);
+ } ptr->i_u = NULL;
+ if (NULL != ptr->s_u) {
+ dk4sto_close(ptr->s_u);
+ } ptr->s_u = NULL;
+ if (NULL != ptr->i_g) {
+ limit_all_delete(ptr->i_g);
+ } ptr->i_g = NULL;
+ if (NULL != ptr->s_g) {
+ dk4sto_close(ptr->s_g);
+ } ptr->s_g = NULL;
+ ptr->dl = (dk4_um_t)0UL;
+ ptr->da = 0;
+ dk4mem_free(ptr);
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 2263 "printqd.ctr"
+ }
+#endif
+
+
+#line 2266 "printqd.ctr"
+}
+
+
+
+/** Delete all classes from a containter.
+ @param it Container iterator.
+*/
+static
+void
+class_all_delete(dk4_sto_it_t *it)
+{
+ pqd_class_t *ptr;
+
+
+#line 2279 "printqd.ctr"
+ dk4sto_it_reset(it);
+ do {
+ ptr = (pqd_class_t *)dk4sto_it_next(it);
+ if (NULL != ptr) {
+ class_delete(ptr);
+ }
+ } while (NULL != ptr);
+ dk4sto_it_close(it);
+
+
+#line 2288 "printqd.ctr"
+}
+
+
+
+/** Create a class structure (allocate memory).
+ @param n Class name.
+ @return Valid pointer on success, NULL on error.
+*/
+static
+pqd_class_t *
+class_new(const char *n)
+{
+ pqd_class_t *back = NULL;
+ int ok = 0;
+
+
+#line 2303 "printqd.ctr"
+ if (NULL != n) {
+
+#line 2304 "printqd.ctr"
+ back = dk4mem_new(pqd_class_t,1,NULL);
+ if (NULL != back) {
+ back->s_u = NULL;
+ back->i_u = NULL;
+ back->s_g = NULL;
+ back->i_g = NULL;
+ back->dl = (dk4_um_t)0UL;
+ back->da = 0;
+ back->hdl = 0;
+ back->name = dk4str8_dup(n, NULL);
+ if (NULL != back->name) {
+ back->s_u = dk4sto_open(NULL);
+ if (NULL != back->s_u) {
+ dk4sto_set_comp(back->s_u, limit_compare, 0);
+ back->i_u = dk4sto_it_open(back->s_u, NULL);
+ if (NULL != back->i_u) {
+ back->s_g = dk4sto_open(NULL);
+ if (NULL != back->s_g) {
+ dk4sto_set_comp(back->s_g, limit_compare, 0);
+ back->i_g = dk4sto_it_open(back->s_g, NULL);
+ if (NULL != back->i_g) {
+ ok = 1;
+
+#line 2326 "printqd.ctr"
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 2329 "printqd.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 2334 "printqd.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 2339 "printqd.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 2344 "printqd.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 2349 "printqd.ctr"
+ }
+#endif
+ if (0 == ok) {
+
+#line 2352 "printqd.ctr"
+ class_delete(back);
+ back = NULL;
+ }
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 2358 "printqd.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 2363 "printqd.ctr"
+ }
+#endif
+
+
+#line 2366 "printqd.ctr"
+ return back;
+}
+
+
+
+/** Compare classes.
+ @param l Left object.
+ @param r Right object.
+ @param cr Comparison criteria (0=class/class, 1=class/name).
+ @return Comparison result.
+*/
+static
+int
+class_compare(const void *l, const void *r, int cr)
+{
+ const pqd_class_t *pl;
+ const pqd_class_t *pr;
+ int back = 0;
+
+
+#line 2385 "printqd.ctr"
+ if (NULL != l) {
+ if (NULL != r) {
+ pl = (const pqd_class_t *)l;
+ switch (cr) {
+ case 1: {
+ if (NULL != pl->name) {
+ back = strcmp(pl->name, (const char *)r);
+ if (-1 > back) { back = -1; }
+ if ( 1 < back) { back = 1; }
+ } else { back = -1; }
+ } break;
+ default: {
+ pr = (const pqd_class_t *)r;
+ if (NULL != pl->name) {
+ if (NULL != pr->name) {
+ back = strcmp(pl->name, pr->name);
+ if (-1 > back) { back = -1; }
+ if ( 1 < back) { back = 1; }
+ } else { back = 1; }
+ } else {
+ if (NULL != pr->name) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if (NULL != r) { back = -1; }
+ }
+
+#line 2413 "printqd.ctr"
+ return back;
+}
+
+
+
+/** Delete a printer structure (release memory).
+ @param ptr Printer structure to delete.
+*/
+static
+void
+printer_delete(pqd_printer_t *ptr)
+{
+
+
+#line 2426 "printqd.ctr"
+ if (NULL != ptr) {
+
+#line 2427 "printqd.ctr"
+ dk4mem_release(ptr->name);
+ ptr->cl = NULL;
+ dk4mem_free(ptr);
+ }
+
+
+#line 2432 "printqd.ctr"
+}
+
+
+
+/** Create printer structure (allocate memory).
+ @param n Printer name.
+ @return Valid pointer on success, NULL on error.
+*/
+static
+pqd_printer_t *
+printer_new(const char *n)
+{
+ pqd_printer_t *back = NULL;
+
+
+#line 2446 "printqd.ctr"
+ if (NULL != n) {
+ back = dk4mem_new(pqd_printer_t,1,NULL);
+ if (NULL != back) {
+ back->cl = NULL;
+ back->name = dk4str8_dup(n,NULL);
+ if (NULL == back->name) {
+
+#line 2452 "printqd.ctr"
+ printer_delete(back);
+ back = NULL;
+ }
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 2458 "printqd.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 2463 "printqd.ctr"
+ }
+#endif
+
+
+#line 2466 "printqd.ctr"
+ return back;
+}
+
+
+
+/** Compare two printers.
+ @param l Left object.
+ @param r Right object.
+ @param cr Comparison criteria (0=printer/printer, 1=printer/name).
+ @return Comparison result.
+*/
+static
+int
+printer_compare(const void *l, const void *r, int cr)
+{
+ const pqd_printer_t *pl;
+ const pqd_printer_t *pr;
+ int back = 0;
+
+
+#line 2485 "printqd.ctr"
+ if (NULL != l) {
+ if (NULL != r) {
+ pl = (const pqd_printer_t *)l;
+ switch (cr) {
+ case 1: {
+ if (NULL != pl->name) {
+ back = strcmp(pl->name, (const char *)r);
+ if (-1 > back) { back = -1; }
+ if ( 1 < back) { back = 1; }
+ } else { back = -1; }
+ } break;
+ default: {
+ pr = (const pqd_printer_t *)r;
+ if (NULL != pl->name) {
+ if (NULL != pr->name) {
+ back = strcmp(pl->name, pr->name);
+ if (-1 > back) { back = -1; }
+ if ( 1 < back) { back = 1; }
+ } else { back = 1; }
+ } else {
+ if (NULL != pr->name) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if (NULL != r) { back = -1; }
+ }
+
+#line 2513 "printqd.ctr"
+ return back;
+}
+
+
+
+/** Delete all printers from a container.
+ @param it Container iterator.
+*/
+static
+void
+printer_all_delete(dk4_sto_it_t *it)
+{
+ pqd_printer_t *ptr;
+
+
+#line 2527 "printqd.ctr"
+ dk4sto_it_reset(it);
+ do {
+ ptr = (pqd_printer_t *)dk4sto_it_next(it);
+ if (NULL != ptr) {
+ printer_delete(ptr);
+ }
+ } while (NULL != ptr);
+ dk4sto_it_close(it);
+
+
+#line 2536 "printqd.ctr"
+}
+
+
+
+/** Delete printer alias structure (release memory).
+ @param ptr Structure to delete.
+*/
+static
+void
+printer_alias_delete(pqd_printer_alias_t *ptr)
+{
+
+
+#line 2548 "printqd.ctr"
+ if (NULL != ptr) {
+
+#line 2549 "printqd.ctr"
+ dk4mem_release(ptr->name);
+ ptr->pr = NULL;
+ dk4mem_free(ptr);
+ }
+
+
+#line 2554 "printqd.ctr"
+}
+
+
+
+/** Create printer alias structure (allocate memory).
+ @param n Alias name.
+ @param pr Printer for alias.
+ @return Valid pointer on success, NULL on error.
+*/
+static
+pqd_printer_alias_t *
+printer_alias_new(const char *n, pqd_printer_t *pr)
+{
+ pqd_printer_alias_t *back = NULL;
+
+
+#line 2569 "printqd.ctr"
+ if ((NULL != n) && (NULL != pr)) {
+ back = dk4mem_new(pqd_printer_alias_t,1,NULL);
+ if (NULL != back) {
+ back->pr = pr;
+ back->name = dk4str8_dup(n,NULL);
+ if (NULL == back->name) {
+ printer_alias_delete(back);
+ back = NULL;
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 2580 "printqd.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 2585 "printqd.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 2590 "printqd.ctr"
+ }
+#endif
+
+
+#line 2593 "printqd.ctr"
+ return back;
+}
+
+
+
+/** Compare printer alias structures.
+ @param l Left object.
+ @param r Right object.
+ @param cr Comparison criteria (0=alias/alias, 1=alias/name).
+ @return Comparison result.
+*/
+static
+int
+printer_alias_compare(const void *l, const void *r, int cr)
+{
+ const pqd_printer_alias_t *pl;
+ const pqd_printer_alias_t *pr;
+ int back = 0;
+
+
+#line 2612 "printqd.ctr"
+ if (NULL != l) {
+ if (NULL != r) {
+ pl = (const pqd_printer_alias_t *)l;
+ switch (cr) {
+ case 1: {
+ if (NULL != pl->name) {
+ back = strcmp(pl->name, (const char *)r);
+ if (-1 > back) { back = -1; }
+ if ( 1 < back) { back = 1; }
+ } else { back = -1; }
+ } break;
+ default: {
+ pr = (const pqd_printer_alias_t *)r;
+ if (NULL != pl->name) {
+ if (NULL != pr->name) {
+ back = strcmp(pl->name, pr->name);
+ if (-1 > back) { back = -1; }
+ if ( 1 < back) { back = 1; }
+ } else { back = 1; }
+ } else {
+ if (NULL != pr->name) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if (NULL != r) { back = -1; }
+ }
+
+#line 2640 "printqd.ctr"
+ return back;
+}
+
+
+
+/** Delete all printer alias structures in a container.
+ @param it Container iterator.
+*/
+static
+void
+printer_alias_all_delete(dk4_sto_it_t *it)
+{
+ pqd_printer_alias_t *ptr;
+
+
+#line 2654 "printqd.ctr"
+ dk4sto_it_reset(it);
+ do {
+ ptr = (pqd_printer_alias_t *)dk4sto_it_next(it);
+ if (NULL != ptr) {
+ printer_alias_delete(ptr);
+ }
+ } while (NULL != ptr);
+ dk4sto_it_close(it);
+
+
+#line 2663 "printqd.ctr"
+}
+
+
+
+/** Initialize configuration before reading configuration file.
+*/
+static
+void
+config_init(void)
+{
+
+
+#line 2674 "printqd.ctr"
+ DK4_MEMRES(&conf, sizeof(conf));
+ conf.sname = NULL;
+ conf.dname = NULL;
+ conf.lname = NULL;
+ conf.s_c = NULL;
+ conf.i_c = NULL;
+ conf.s_p = NULL;
+ conf.i_p = NULL;
+ conf.s_a = NULL;
+ conf.i_a = NULL;
+ conf.s_ai = NULL;
+ conf.i_ai = NULL;
+ conf.s_ad = NULL;
+ conf.i_ad = NULL;
+ conf.s_aa = NULL;
+ conf.i_aa = NULL;
+ conf.m_loc = 0; /* Maximum 0 means unlimited number of connections. */
+ conf.m_tcp = 0; /* Maximum 0 means unlimited number of connections. */
+ conf.uid = 0;
+ conf.gid = 0;
+ conf.suid = 0;
+ conf.sgid = 0;
+ conf.slbl = 5;
+ conf.snbl = 5;
+ conf.iglo = 0;
+ conf.dglo = 0;
+ conf.aglo = 0;
+ conf.ptcp = 0;
+ conf.pudp = 0;
+ conf.linf = 0;
+ conf.ldb = 0;
+
+
+#line 2706 "printqd.ctr"
+}
+
+
+
+/** Allocate internal structures for configuration.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+config_allocate(void)
+{
+ int back = 0;
+
+
+#line 2719 "printqd.ctr"
+ conf.s_c = dk4sto_open(NULL);
+ conf.s_p = dk4sto_open(NULL);
+ conf.s_a = dk4sto_open(NULL);
+ conf.s_ai = dk4sto_open(NULL);
+ conf.s_ad = dk4sto_open(NULL);
+ conf.s_aa = dk4sto_open(NULL);
+ if ((NULL != conf.s_ai) && (NULL != conf.s_ad) && (NULL != conf.s_aa)) {
+ if ((NULL != conf.s_c) && (NULL != conf.s_p) && (NULL != conf.s_a)) {
+ dk4sto_set_comp(conf.s_c, class_compare, 0);
+ dk4sto_set_comp(conf.s_p, printer_compare, 0);
+ dk4sto_set_comp(conf.s_a, printer_alias_compare, 0);
+ dk4sto_set_comp(conf.s_ai, dk4socket_allowed_peer_compare, 0);
+ dk4sto_set_comp(conf.s_ad, dk4socket_allowed_peer_compare, 0);
+ dk4sto_set_comp(conf.s_aa, dk4socket_allowed_peer_compare, 0);
+ conf.i_c = dk4sto_it_open(conf.s_c, NULL);
+ conf.i_p = dk4sto_it_open(conf.s_p, NULL);
+ conf.i_a = dk4sto_it_open(conf.s_a, NULL);
+ conf.i_ai = dk4sto_it_open(conf.s_ai, NULL);
+ conf.i_ad = dk4sto_it_open(conf.s_ad, NULL);
+ conf.i_aa = dk4sto_it_open(conf.s_aa, NULL);
+ if ((NULL != conf.i_ai) && (NULL != conf.i_ad) && (NULL != conf.i_aa)) {
+ if ((NULL != conf.i_c) && (NULL != conf.i_p) && (NULL != conf.i_a)) {
+ back = 1;
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 2745 "printqd.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 2750 "printqd.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 2755 "printqd.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 2760 "printqd.ctr"
+ }
+#endif
+
+
+#line 2763 "printqd.ctr"
+ return back;
+}
+
+
+
+/** Set backlog variable.
+ @param iptr Address of backlog number variable.
+ @param pv Text containing the number.
+ @param fn File name for diagnostics.
+ @param lineno Line number.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+set_backlog(int *iptr, char *pv, const char *fn, unsigned long lineno)
+{
+ const char *ep = NULL;
+ int i = 0;
+ int back = 0;
+ int res = 0;
+
+
+#line 2784 "printqd.ctr"
+ res = dk4ma_input_c8_dec_int(&i, pv, &ep, 1, NULL);
+ if (0 != res) {
+ if (0 < i) {
+ *iptr = i;
+ back = 1;
+ } else {
+
+#line 2790 "printqd.ctr"
+ /* ERROR: Must be positive */
+ log_1(fn, lineno, LOG_EMERG, 1, 15);
+ }
+ } else {
+
+#line 2794 "printqd.ctr"
+ /* ERROR: Not an integer number */
+ log_5(fn, lineno, LOG_EMERG, 1, 12, 13, 14, pv, ep);
+ }
+
+#line 2797 "printqd.ctr"
+ return back;
+}
+
+
+
+/** Set maximum number of connections.
+ @param pmaxconn Address of result variable.
+ @param pv Text containing the number.
+ @param fn File name for diagnostics.
+ @param lineno Line number.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+set_max_connections(
+ size_t *pmaxconn,
+ char *pv,
+ const char *fn,
+ unsigned long lineno
+)
+{
+ const char *ep = NULL;
+ size_t sz = 0;
+ int back = 0;
+ int res = 0;
+
+
+#line 2823 "printqd.ctr"
+ res = dk4ma_input_c8_dec_size_t(&sz, pv, &ep, 1, NULL);
+ if (0 != res) {
+ *pmaxconn = sz;
+ back = 1;
+ } else {
+
+#line 2828 "printqd.ctr"
+ /* ERROR: Not a size specification */
+ log_5(fn, lineno, LOG_EMERG, 1, 16, 17, 18, pv, ep);
+ }
+
+
+#line 2832 "printqd.ctr"
+ return back;
+}
+
+
+
+/** Set port number from text.
+ @param ppn Address of port number variable.
+ @param pv Text containing the number.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+set_port_number(
+ unsigned short *ppn,
+ char *pv,
+ const char *fn,
+ unsigned long lineno
+)
+{
+ const char *ep = NULL;
+ unsigned short pn = 0;
+ int back = 0;
+ int res = 0;
+
+
+#line 2856 "printqd.ctr"
+ res = dk4ma_input_c8_dec_ushort(&pn, pv, &ep, 1, NULL);
+ if (0 != res) {
+ if (0 < pn) {
+ *ppn = pn;
+ back = 1;
+ } else {
+
+#line 2862 "printqd.ctr"
+ /* ERROR: Port number must not be 0 */
+ log_1(fn, lineno, LOG_EMERG, 1, 22);
+ }
+ } else {
+
+#line 2866 "printqd.ctr"
+ /* ERROR: Not a 16 bit unsigned number */
+ log_5(fn, lineno, LOG_EMERG, 1, 19, 20, 21, pv, ep);
+ }
+
+
+#line 2870 "printqd.ctr"
+ return back;
+}
+
+
+
+/** Add address to list of allowed hosts.
+ @param s Containter of allowed peers.
+ @param i Iterator through container.
+ @param iptr Address of global flag variable.
+ @param str Text containing the address.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+allow_hosts(
+ dk4_sto_t *s,
+ dk4_sto_it_t *i,
+ int *iptr,
+ char *str,
+ const char *filename,
+ unsigned long lineno
+)
+{
+ dk4_allowed_peer_t ap;
+ dk4_allowed_peer_t *pap;
+ char *px = NULL;
+ int res = 0;
+ int back = 0;
+
+
+#line 2899 "printqd.ctr"
+ px = dk4str8_next(str, NULL);
+ if (NULL == px) {
+ if (0 == strcmp(str, printqd_kw[2])) {
+ *iptr = 1;
+ back = 1;
+ } else {
+ DK4_MEMRES(&ap, sizeof(ap));
+ res = dk4socket_c8_get_allowed_peer(&ap, str, NULL);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ pap = dk4mem_new(dk4_allowed_peer_t,1,NULL);
+ if (NULL != pap) {
+ DK4_MEMCPY(pap, &ap, sizeof(ap));
+ if (0 != dk4sto_add(s, pap, NULL)) {
+ back = 1;
+ } else {
+
+#line 2914 "printqd.ctr"
+ dk4mem_free(pap);
+ /* ERROR: Memory */
+ log_1(filename, lineno, LOG_EMERG, 1, 27);
+ }
+ } else {
+
+#line 2919 "printqd.ctr"
+ /* ERROR: Memory */
+ log_1(filename, lineno, LOG_EMERG, 1, 27);
+ }
+ } else {
+
+#line 2923 "printqd.ctr"
+ /* ERROR: Syntax, not a peer definition */
+ log_3(filename, lineno, LOG_EMERG, 1, 25, 26, str);
+ }
+ }
+ } else {
+
+#line 2928 "printqd.ctr"
+ /* ERROR: Unexpected text */
+ log_3(filename, lineno, LOG_EMERG, 1, 23, 24, px);
+ }
+
+
+#line 2932 "printqd.ctr"
+ return back;
+}
+
+
+
+/** Obtain limit value from text.
+ @param plim Address of limit variable to set.
+ @param src Text containing the limit.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+get_limit_value(dk4_um_t *plim, char *src, const char *fn, unsigned long lineno)
+{
+ const char *ep = NULL;
+ dk4_um_t value = (dk4_um_t)0UL;
+ int back = 0;
+ int res = 0;
+
+
+#line 2951 "printqd.ctr"
+ if (0 == strcmp(src, printqd_kw[3])) {
+ *plim = DK4_UM_MAX;
+ back = 1;
+ } else {
+ if (0 == strcmp(src, printqd_kw[4])) {
+ *plim = value;
+ back = 1;
+ } else {
+ res = dk4ma_input_c8_dec_dk4_um_t(&value, src, &ep, 1, NULL);
+ if (0 != res) {
+ *plim = value;
+ back = 1;
+ } else {
+
+#line 2964 "printqd.ctr"
+ /* ERROR: Syntax, not an unsigned number */
+ log_5(fn, lineno, LOG_EMERG, 1, 28, 29, 30, src, ep);
+ }
+ }
+ }
+
+
+#line 2970 "printqd.ctr"
+ return back;
+}
+
+
+
+/** Add a user or group limit to a class.
+ @param pcl Class to modify.
+ @param s Container for limits.
+ @param i Container iterator.
+ @param str Text containing name and limit.
+ @param fn File name.
+ @param lineno Line number.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+add_limit(
+ pqd_class_t *pcl,
+ dk4_sto_t *s,
+ dk4_sto_it_t *i,
+ char *str,
+ const char *fn,
+ dk4_um_t lineno
+)
+{
+ pqd_limit_t *plim;
+ char *pnum;
+ char *px;
+ dk4_um_t limval = (dk4_um_t)0UL;
+ int back = 0;
+
+
+#line 3001 "printqd.ctr"
+ pnum = dk4str8_next(str, NULL);
+ if (NULL != pnum) {
+ px = dk4str8_next(pnum, NULL);
+ if (NULL == px) {
+ if (0 != get_limit_value(&limval, pnum, fn, lineno)) {
+ plim = (pqd_limit_t *)dk4sto_it_find_like(i, str, 1);
+ if (NULL == plim) {
+ plim = limit_new(str, limval);
+ if (NULL != plim) {
+ if (0 != dk4sto_add(s, plim, NULL)) {
+ back = 1;
+ } else {
+
+#line 3013 "printqd.ctr"
+ /* ERROR: Memory */
+ log_1(fn, lineno, LOG_EMERG, 1, 27);
+ limit_delete(plim);
+ }
+ } else {
+
+#line 3018 "printqd.ctr"
+ /* ERROR: Memory */
+ log_1(fn, lineno, LOG_EMERG, 1, 27);
+ }
+ } else {
+
+#line 3022 "printqd.ctr"
+ /* ERROR: Limit redefinition */
+ log_3(fn, lineno, LOG_EMERG, 1, 32, 33, str);
+ }
+ }
+ } else {
+
+#line 3027 "printqd.ctr"
+ /* ERROR: Syntax, no further text expected */
+ log_3(fn, lineno, LOG_EMERG, 1, 23, 24, px);
+ }
+ } else {
+
+#line 3031 "printqd.ctr"
+ /* ERROR: Missing limit. */
+ log_1(fn, lineno, LOG_EMERG, 1, 31);
+ }
+
+
+#line 3035 "printqd.ctr"
+ return back;
+}
+
+
+
+/** Set default limit for class.
+ @param pcl Class to modify.
+ @param pv String containing the limit.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+set_default_limit(
+ pqd_class_t *pcl,
+ char *pv,
+ const char *fn,
+ unsigned long lineno
+)
+{
+ char *px;
+ dk4_um_t value = (dk4_um_t)0UL;
+ int back = 0;
+
+
+#line 3058 "printqd.ctr"
+ px = dk4str8_next(pv, NULL);
+ if (NULL == px) {
+ if (0 != get_limit_value(&value, pv, fn, lineno)) {
+ if ((0 == (1 & (pcl->hdl))) || (value == pcl->dl) ) {
+ pcl->hdl |= 1;
+ pcl->dl = value;
+ back = 1;
+ } else {
+
+#line 3066 "printqd.ctr"
+ /* ERROR: Syntax, default limit redefined */
+ log_1(fn, lineno, LOG_EMERG, 1, 34);
+ }
+ }
+ } else {
+
+#line 3071 "printqd.ctr"
+ /* ERROR: No further text expected */
+ log_3(fn, lineno, LOG_EMERG, 1, 23, 24, px);
+ }
+
+
+#line 3075 "printqd.ctr"
+ return back;
+}
+
+
+
+/** Set deny action for printer class.
+ @param pcl Class to modify.
+ @param pv String containing the action.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+set_deny_action(
+ pqd_class_t *pcl,
+ char *pv,
+ const char *fn,
+ unsigned long lineno
+)
+{
+ char *px = NULL;
+ int back = 0;
+ int res = 0;
+
+
+#line 3098 "printqd.ctr"
+ px = dk4str8_next(pv, NULL);
+ if (NULL == px) {
+ switch ( (res = dk4str8_array_index(deny_action_names, pv, 0)) ) {
+ case 0: case 1: {
+ if (0 == (2 & pcl->hdl)) {
+ pcl->da = res;
+ pcl->hdl |= 2;
+ back = 1;
+ } else {
+
+#line 3107 "printqd.ctr"
+ /* ERROR: Redefinition of deny action */
+ log_1(fn, lineno, LOG_EMERG, 1, 35);
+ }
+ } break;
+ default: {
+ } break;
+ }
+ } else {
+
+#line 3115 "printqd.ctr"
+ /* ERROR: Syntax, no further text expected */
+ log_3(fn, lineno, LOG_EMERG, 1, 23, 24, px);
+ }
+
+
+#line 3119 "printqd.ctr"
+ return back;
+}
+
+
+
+/** Add an alias for the current printer to list.
+ @param ppr Printer to add alias for.
+ @param pv Alias name.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+add_alias(pqd_printer_t *ppr, char *pv, const char *fn, unsigned long lineno)
+{
+ pqd_printer_alias_t *ppa;
+ pqd_printer_t *pp;
+ char *px;
+ int back = 0;
+
+
+#line 3138 "printqd.ctr"
+ px = dk4str8_next(pv, NULL);
+ if (NULL == px) {
+ ppa = (pqd_printer_alias_t *)dk4sto_it_find_like(conf.i_a, pv, 1);
+ if (NULL == ppa) {
+ pp = (pqd_printer_t *)dk4sto_it_find_like(conf.i_p, pv, 1);
+ if (NULL == pp) {
+ ppa = printer_alias_new(pv, ppr);
+ if (NULL != ppa) {
+ if (0 != dk4sto_add(conf.s_a, ppa, NULL)) {
+ back = 1;
+ } else {
+
+#line 3149 "printqd.ctr"
+ /* ERROR: Memory */
+ log_1(fn, lineno, LOG_EMERG, 1, 27);
+ printer_alias_delete(ppa);
+ }
+ } else {
+
+#line 3154 "printqd.ctr"
+ /* ERROR: Memory */
+ log_1(fn, lineno, LOG_EMERG, 1, 27);
+ }
+ } else {
+
+#line 3158 "printqd.ctr"
+ /* ERROR: Printer exists */
+ log_3(fn, lineno, LOG_EMERG, 1, 36, 37, pv);
+ }
+ } else {
+
+#line 3162 "printqd.ctr"
+ /* ERROR: Alias already exists */
+ log_3(fn, lineno, LOG_EMERG, 1, 38, 39, pv);
+ }
+ } else {
+
+#line 3166 "printqd.ctr"
+ /* ERROR: Syntax, unexpected text */
+ log_3(fn, lineno, LOG_EMERG, 1, 23, 24, px);
+ }
+
+
+#line 3170 "printqd.ctr"
+ return back;
+}
+
+
+
+/** Assign a class to a printer.
+ @param ppr Printer to modify.
+ @param pv Class name.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+assign_class(pqd_printer_t *ppr, char *pv, const char *fn, unsigned long lineno)
+{
+ pqd_class_t *pcl;
+ char *px;
+ int back = 0;
+
+
+#line 3188 "printqd.ctr"
+ px = dk4str8_next(pv, NULL);
+ if (NULL == px) {
+ if (NULL == ppr->cl) {
+ pcl = (pqd_class_t *)dk4sto_it_find_like(conf.i_c, pv, 1);
+ if (NULL != pcl) {
+ ppr->cl = pcl;
+ back = 1;
+ } else {
+
+#line 3196 "printqd.ctr"
+ /* ERROR: Syntax, class not found */
+ log_3(fn, lineno, LOG_EMERG, 1, 40, 41, pv);
+ }
+ } else {
+
+#line 3200 "printqd.ctr"
+ /* ERROR: Syntax, redefinition of printer class */
+ log_1(fn, lineno, LOG_EMERG, 1, 42);
+ }
+ } else {
+
+#line 3204 "printqd.ctr"
+ /* ERROR: Syntax, unexpected text */
+ log_3(fn, lineno, LOG_EMERG, 1, 23, 24, px);
+ }
+
+
+#line 3208 "printqd.ctr"
+ return back;
+}
+
+
+
+/** Check configuration for errors.
+ @return 1 if configuration is usable, 0 on errors.
+*/
+static
+int
+config_check(const char *filename, unsigned long lineno)
+{
+ pqd_printer_t *pr = NULL;
+ pqd_class_t *cl = NULL;
+ int back = 1;
+
+
+
+#line 3225 "printqd.ctr"
+ /* Each printer must have a class assigned.
+ */
+ dk4sto_it_reset(conf.i_p);
+ do {
+ pr = (pqd_printer_t *)dk4sto_it_next(conf.i_p);
+ if (NULL != pr) {
+ if (NULL == pr->cl) {
+ back = 0;
+
+#line 3233 "printqd.ctr"
+ /* ERROR: No class for printer */
+ log_3(filename, lineno, LOG_EMERG, 1, 91, 92, pr->name);
+ }
+ }
+ } while(NULL != pr);
+
+ /* Each class should have a default limit
+ */
+ dk4sto_it_reset(conf.i_c);
+ do {
+ cl = (pqd_class_t *)dk4sto_it_next(conf.i_c);
+ if (NULL != cl) {
+ if (0 == cl->hdl) {
+
+
+#line 3247 "printqd.ctr"
+ /* WARNING: Default limit missing for class */
+ log_3(filename, lineno, LOG_EMERG, 0, 93, 94, cl->name);
+ }
+ }
+ } while (NULL != cl);
+
+
+
+#line 3254 "printqd.ctr"
+ return back;
+}
+
+
+
+/** Set additional features to log.
+ @param pv Text containing the feature names.
+ @param fn File name for diagnostics.
+ @param lineno Line numbers for diagnostics.
+ @return 1 on success, 0 on errors.
+*/
+static
+int
+set_log_features(char *pv, const char *fn, unsigned long lineno)
+{
+
+ char *pc;
+ char *pn;
+ int back = 0;
+
+ if (NULL != pv) {
+ back = 1;
+ pc = dk4str8_start(pv, NULL);
+ while (NULL != pc) {
+ pn = strchr(pc, ',');
+ if (NULL != pn) {
+ *(pn++) = '\0';
+ pn = dk4str8_start(pn, NULL);
+ }
+ dk4str8_normalize(pc, NULL);
+ switch ( dk4str8_array_index(log_feature_names, pc, 0) ) {
+ case 0 : {
+ conf.ldb = 1;
+ } break;
+ case 1 : {
+ conf.linf = 1;
+ } break;
+ case 2 : case 3 : {
+ conf.ldb = 1;
+ conf.linf = 1;
+ } break;
+ case 4 : case 5 : {
+ conf.ldb = 0;
+ conf.linf = 0;
+ } break;
+ default : {
+ /* ERROR: Unknown log feature name */
+ log_3(NULL, 0UL, LOG_EMERG, 0, 154, 155, pc);
+ back = 0;
+ } break;
+ }
+ pc = pn;
+ }
+ } else {
+ /* ERROR: Value required */
+ conf.ldb = 0; conf.linf = 0;
+ }
+ return back;
+}
+
+
+
+/** Read configuration file.
+ @return 1 on success (can continue), 0 on error (must exit).
+*/
+static
+int
+config_read(void)
+{
+ const char *fn = NULL; /* Input file name */
+ FILE *fipo = NULL; /* Input file */
+ pqd_class_t *pcl = NULL; /* Current class to modify */
+ pqd_printer_t *ppr = NULL; /* Current printer to modify */
+ pqd_printer_alias_t *ppa = NULL; /* Printer alias */
+ char *pk = NULL; /* Key text */
+ char *pv = NULL; /* Value text */
+ char *px = NULL; /* Text after value */
+ unsigned long lineno = 0UL; /* Current line number */
+ int back = 0; /* Result */
+ int sectt = 0; /* Section type: 0=opt, 1=class, 2=pr */
+ int myres = 0; /* Internal operation result */
+
+
+#line 3336 "printqd.ctr"
+ if (0 != config_allocate()) {
+ if (0 != options[1].found) { fn = options[1].val.t; }
+ if (NULL == fn) { fn = def_conf_file_name; }
+ fipo = dk4fopen_c8(fn, printqd_kw[1], DK4_FOPEN_SC_IS_REGULAR, NULL);
+ if (NULL != fipo) {
+ back = 1;
+ sectt = 0;
+ while ((1 == back) && (NULL != fgets(inbuf, sizeof(inbuf), fipo))) {
+ lineno++;
+ dk4str8_delnl(inbuf);
+
+#line 3346 "printqd.ctr"
+ pk = dk4str8_start(inbuf, NULL);
+ if (NULL != pk) {
+ if ('#' != *pk) {
+ if ('[' == *pk) {
+
+#line 3350 "printqd.ctr"
+ /*
+ Opening a new section.
+ */
+ pk = dk4str8_start(++pk, NULL);
+ if (NULL != pk) {
+
+#line 3355 "printqd.ctr"
+ sectt = -1;
+ pcl = NULL;
+ ppr = NULL;
+ pv = dk4str8_chr(pk, ']');
+ if (NULL != pv) { *pv = '\0'; }
+
+#line 3360 "printqd.ctr"
+ pv = dk4str8_next(pk, NULL);
+ switch ( dk4str8_array_index(config_section_names, pk, 0) ) {
+ /* Opening options section.
+ */
+ case 0 : {
+
+#line 3365 "printqd.ctr"
+ sectt = 0;
+ } break;
+ /* Opening class section.
+ */
+ case 1 : {
+
+#line 3370 "printqd.ctr"
+ sectt = 1;
+ if (NULL != pv) {
+ if (NULL == (px = dk4str8_next(pv, NULL))) {
+ pcl = (pqd_class_t *)dk4sto_it_find_like(
+ conf.i_c, pv, 1
+ );
+ if (NULL == pcl) {
+ pcl = class_new(pv);
+ if (NULL != pcl) {
+ if (0 == dk4sto_add(conf.s_c, pcl, NULL)) {
+ /* ERROR: Memory */
+ log_1(fn, lineno, LOG_EMERG, 1, 27);
+ class_delete(pcl);
+ pcl = NULL;
+
+#line 3384 "printqd.ctr"
+ back = 0;
+ }
+ } else {
+
+#line 3387 "printqd.ctr"
+ /* ERROR: MEMORY */
+ log_1(fn, lineno, LOG_EMERG, 1, 27);
+ back = 0;
+ }
+ } else {
+
+#line 3392 "printqd.ctr"
+ /* ERROR: Syntax, class already exists */
+ log_3(fn, lineno, LOG_EMERG, 1, 43, 44, pv);
+ back = 0;
+ }
+ } else {
+
+#line 3397 "printqd.ctr"
+ /* ERROR: Syntax, only one component allowed */
+ log_3(fn, lineno, LOG_EMERG, 1, 23, 24, px);
+ back = 0;
+ }
+ } else {
+
+#line 3402 "printqd.ctr"
+ /* ERROR: Syntax, missing class name */
+ log_1(fn, lineno, LOG_EMERG, 1, 45);
+ back = 0;
+ }
+ } break;
+ /* Opening printer section.
+ */
+ case 2 : {
+
+#line 3410 "printqd.ctr"
+ sectt = 2;
+ if (NULL != pv) {
+ if (NULL == (px = dk4str8_next(pv, NULL))) {
+ ppr = (pqd_printer_t *)dk4sto_it_find_like(
+ conf.i_p,pv,1
+ );
+ ppa = (pqd_printer_alias_t *)dk4sto_it_find_like(
+ conf.i_a,pv,1
+ );
+ if ((NULL == ppr) && (NULL == ppa)) {
+ ppr = printer_new(pv);
+ if (NULL != ppr) {
+ if (0 == dk4sto_add(conf.s_p, ppr, NULL)) {
+ /* ERROR: Memory */
+ log_1(fn, lineno, LOG_EMERG, 1, 27);
+ printer_delete(ppr);
+ ppr = NULL;
+ back = 0;
+
+#line 3428 "printqd.ctr"
+ }
+ } else {
+
+#line 3430 "printqd.ctr"
+ /* ERROR: Memory */
+ log_1(fn, lineno, LOG_EMERG, 1, 27);
+ back = 0;
+ }
+ } else {
+
+#line 3435 "printqd.ctr"
+ /* ERROR: Syntax, pr/al already exists */
+ log_3(fn, lineno, LOG_EMERG, 1, 46, 47, pv);
+ back = 0;
+ }
+ } else {
+
+#line 3440 "printqd.ctr"
+ /* ERROR: Syntax, just one component allowed */
+ log_3(fn, lineno, LOG_EMERG, 1, 23, 24, px);
+ back = 0;
+ }
+ } else {
+
+#line 3445 "printqd.ctr"
+ /* ERROR: Syntax, name required */
+ log_1(fn, lineno, LOG_EMERG, 1, 48);
+ back = 0;
+ }
+ } break;
+ default : {
+
+#line 3451 "printqd.ctr"
+ /* ERROR: Syntax, illegal section name */
+ log_3(fn, lineno, LOG_EMERG, 1, 49, 50, pk);
+ back = 0;
+ } break;
+ }
+ } else {
+
+#line 3457 "printqd.ctr"
+ /* ERROR: Syntax, empty section */
+ log_1(fn, lineno, LOG_EMERG, 1, 51);
+ back = 0;
+ }
+ } else {
+
+#line 3462 "printqd.ctr"
+ /*
+ Data line for existing section.
+ */
+ pv = dk4str8_chr(pk, '=');
+ if (NULL != pv) {
+ *(pv++) = '\0';
+ pv = dk4str8_start(pv, NULL);
+ if (NULL != pv) {
+ dk4str8_normalize(pk, NULL);
+
+#line 3471 "printqd.ctr"
+ switch ( dk4str8_array_index(config_option_names, pk, 0) ) {
+ case 0 : {
+
+
+#line 3474 "printqd.ctr"
+ if (0 == sectt) {
+ struct passwd *pw;
+ if (NULL == (px = dk4str8_next(pv, NULL))) {
+ pw = getpwnam(pv);
+ if (NULL != pw) {
+ if ((0 == conf.uid) || (conf.uid == pw->pw_uid)) {
+ conf.uid = pw->pw_uid;
+ } else {
+ /* ERROR: Redefinition */
+ log_1(fn, lineno, LOG_EMERG, 1, 52);
+ back = 0;
+
+#line 3485 "printqd.ctr"
+ }
+ } else {
+
+#line 3487 "printqd.ctr"
+ /* ERROR: User not found */
+ log_3(fn, lineno, LOG_EMERG, 1, 53, 54, pv);
+ back = 0;
+ }
+ } else {
+
+#line 3492 "printqd.ctr"
+ /* ERROR: Syntax, just one component allowed */
+ log_3(fn, lineno, LOG_EMERG, 1, 23, 24, px);
+ back = 0;
+ }
+ } else {
+
+#line 3497 "printqd.ctr"
+ /* ERROR: Only allwowed in options section */
+ log_1(fn, lineno, LOG_EMERG, 1, 55);
+ back = 0;
+ }
+ } break;
+ case 1 : {
+
+#line 3503 "printqd.ctr"
+ if (0 == sectt) {
+ struct group *pgr;
+ if (NULL == (px = dk4str8_next(pv, NULL))) {
+ pgr = getgrnam(pv);
+ if (NULL != pgr) {
+ if ((0 == conf.gid) || (conf.gid == pgr->gr_gid)) {
+ conf.gid = pgr->gr_gid;
+ } else {
+ /* ERROR: Syntax, group redefinition */
+ log_1(fn, lineno, LOG_EMERG, 1, 56);
+ back = 0;
+
+#line 3514 "printqd.ctr"
+ }
+ } else {
+
+#line 3516 "printqd.ctr"
+ /* ERROR: Syntax, group not found */
+ log_3(fn, lineno, LOG_EMERG, 1, 57, 58, pv);
+ back = 0;
+ }
+ } else {
+
+#line 3521 "printqd.ctr"
+ /* ERROR: Syntax, just one component allowed */
+ log_3(fn, lineno, LOG_EMERG, 1, 23, 24, px);
+ back = 0;
+ }
+ } else {
+
+#line 3526 "printqd.ctr"
+ /* ERROR: Syntax, only allowed in options */
+ log_1(fn, lineno, LOG_EMERG, 1, 55);
+ back = 0;
+ }
+ } break;
+ case 2 : {
+
+#line 3532 "printqd.ctr"
+ if (0 == sectt) {
+ if (NULL == conf.dname) {
+ conf.dname = dk4str8_dup(pv, NULL);
+ if (NULL == conf.dname) {
+ /* ERROR: Memory */
+ log_1(fn, lineno, LOG_EMERG, 1, 27);
+ back = 0;
+
+#line 3539 "printqd.ctr"
+ }
+ } else {
+ /* ERROR: Redefinition */
+ log_1(fn, lineno, LOG_EMERG, 1, 59);
+ back = 0;
+
+#line 3544 "printqd.ctr"
+ }
+ } else {
+
+#line 3546 "printqd.ctr"
+ /* ERROR: Syntax, only allowed in options */
+ log_1(fn, lineno, LOG_EMERG, 1, 55);
+ back = 0;
+ }
+ } break;
+ case 3 : {
+
+#line 3552 "printqd.ctr"
+ if (0 == sectt) {
+ if (NULL == conf.sname) {
+ conf.sname = dk4str8_dup(pv, NULL);
+ if (NULL == conf.sname) {
+ /* ERROR: Memory */
+ log_1(fn, lineno, LOG_EMERG, 1, 27);
+ back = 0;
+
+#line 3559 "printqd.ctr"
+ }
+ } else {
+
+#line 3561 "printqd.ctr"
+ /* ERROR: Redefinition */
+ log_1(fn, lineno, LOG_EMERG, 1, 60);
+ back = 0;
+ }
+ } else {
+
+#line 3566 "printqd.ctr"
+ /* ERROR: Syntax, only allowed in options */
+ log_1(fn, lineno, LOG_EMERG, 1, 55);
+ back = 0;
+ }
+ } break;
+ case 4 : {
+
+#line 3572 "printqd.ctr"
+ if (0 == sectt) {
+ if (0 == set_backlog(&(conf.slbl), pv, fn, lineno)) {
+ back = 0;
+
+#line 3575 "printqd.ctr"
+ }
+ } else {
+
+#line 3577 "printqd.ctr"
+ /* ERROR: Syntax, only allowed in options */
+ log_1(fn, lineno, LOG_EMERG, 1, 55);
+ back = 0;
+ }
+ } break;
+ case 5 : {
+
+#line 3583 "printqd.ctr"
+ if (0 == sectt) {
+ if(0 == set_max_connections(&(conf.m_loc),pv,fn,lineno))
+ {
+ back = 0;
+
+#line 3587 "printqd.ctr"
+ }
+ } else {
+
+#line 3589 "printqd.ctr"
+ /* ERROR: Syntax, only allowed in options */
+ log_1(fn, lineno, LOG_EMERG, 1, 55);
+ back = 0;
+ }
+ } break;
+ case 6 : {
+
+#line 3595 "printqd.ctr"
+ if (0 == sectt) {
+ if (0 == set_port_number(&(conf.pudp),pv,fn,lineno)) {
+ back = 0;
+
+#line 3598 "printqd.ctr"
+ }
+ } else {
+
+#line 3600 "printqd.ctr"
+ /* ERROR: Syntax, only allowed in options */
+ log_1(fn, lineno, LOG_EMERG, 1, 55);
+ back = 0;
+ }
+ } break;
+ case 7 : {
+
+#line 3606 "printqd.ctr"
+ if (0 == sectt) {
+ if (0 == set_port_number(&(conf.ptcp),pv,fn,lineno)) {
+ back = 0;
+
+#line 3609 "printqd.ctr"
+ }
+ } else {
+
+#line 3611 "printqd.ctr"
+ /* ERROR: Syntax, only allowed in options */
+ log_1(fn, lineno, LOG_EMERG, 1, 55);
+ back = 0;
+ }
+ } break;
+ case 8 : {
+
+#line 3617 "printqd.ctr"
+ if (0 == sectt) {
+ if (0 == set_backlog(&(conf.snbl), pv, fn, lineno)) {
+ back = 0;
+
+#line 3620 "printqd.ctr"
+ }
+ } else {
+
+#line 3622 "printqd.ctr"
+ /* ERROR: Syntax, only allowed in options */
+ log_1(fn, lineno, LOG_EMERG, 1, 55);
+ back = 0;
+ }
+ } break;
+ case 9 : {
+
+#line 3628 "printqd.ctr"
+ if (0 == sectt) {
+ if(0 == set_max_connections(&(conf.m_tcp),pv,fn,lineno))
+ {
+ back = 0;
+
+#line 3632 "printqd.ctr"
+ }
+ } else {
+
+#line 3634 "printqd.ctr"
+ /* ERROR: Syntax, only allowed in options */
+ log_1(fn, lineno, LOG_EMERG, 1, 55);
+ back = 0;
+ }
+ } break;
+ case 10 : {
+
+#line 3640 "printqd.ctr"
+ if (0 == sectt) {
+ myres = allow_hosts(
+ conf.s_ai, conf.i_ai, &(conf.iglo), pv,
+ fn, lineno
+ );
+ if (0 == myres) {
+
+#line 3646 "printqd.ctr"
+ back = 0;
+ }
+ } else {
+
+#line 3649 "printqd.ctr"
+ /* ERROR: Syntax, only allowed in options */
+ log_1(fn, lineno, LOG_EMERG, 1, 55);
+ back = 0;
+ }
+ } break;
+ case 11 : {
+
+#line 3655 "printqd.ctr"
+ if (0 == sectt) {
+ myres = allow_hosts(
+ conf.s_ad, conf.i_ad, &(conf.dglo), pv,
+ fn, lineno
+ );
+ if (0 == myres) {
+
+#line 3661 "printqd.ctr"
+ back = 0;
+ }
+ } else {
+
+#line 3664 "printqd.ctr"
+ /* ERROR: Syntax, only allowed in options */
+ log_1(fn, lineno, LOG_EMERG, 1, 55);
+ back = 0;
+ }
+ } break;
+ case 12 : {
+
+#line 3670 "printqd.ctr"
+ if (0 == sectt) {
+ myres = allow_hosts(
+ conf.s_aa, conf.i_aa, &(conf.aglo), pv,
+ fn, lineno
+ );
+ if (0 == myres) {
+
+#line 3676 "printqd.ctr"
+ back = 0;
+ }
+ } else {
+
+#line 3679 "printqd.ctr"
+ /* ERROR: Syntax, only allowed in options */
+ log_1(fn, lineno, LOG_EMERG, 1, 55);
+ back = 0;
+ }
+ } break;
+ case 13 : {
+
+#line 3685 "printqd.ctr"
+ if ((1 == sectt) && (NULL != pcl)) {
+ myres = add_limit(
+ pcl, pcl->s_u, pcl->i_u, pv, fn, lineno
+ );
+ if (0 == myres) {
+
+#line 3690 "printqd.ctr"
+ back = 0;
+ }
+ } else {
+
+#line 3693 "printqd.ctr"
+ /* ERROR: Syntax, only allowed in class */
+ log_1(fn, lineno, LOG_EMERG, 1, 61);
+ back = 0;
+ }
+ } break;
+ case 14 : {
+
+#line 3699 "printqd.ctr"
+ if ((1 == sectt) && (NULL != pcl)) {
+ myres = add_limit(
+ pcl, pcl->s_g, pcl->i_g, pv, fn, lineno
+ );
+ if (0 == myres) {
+
+#line 3704 "printqd.ctr"
+ back = 0;
+ }
+ } else {
+
+#line 3707 "printqd.ctr"
+ /* ERROR: Syntax, only allowed in class */
+ log_1(fn, lineno, LOG_EMERG, 1, 61);
+ back = 0;
+ }
+ } break;
+ case 15 : {
+
+#line 3713 "printqd.ctr"
+ if ((1 == sectt) && (NULL != pcl)) {
+ myres = set_default_limit(pcl, pv, fn, lineno);
+ if (0 == myres) {
+
+#line 3716 "printqd.ctr"
+ back = 0;
+ }
+ } else {
+
+#line 3719 "printqd.ctr"
+ /* ERROR: Syntax, only allowed in class */
+ log_1(fn, lineno, LOG_EMERG, 1, 61);
+ back = 0;
+ }
+ } break;
+ case 16 : {
+
+#line 3725 "printqd.ctr"
+ if ((1 == sectt) && (NULL != pcl)) {
+ myres = set_deny_action(pcl, pv, fn, lineno);
+ if (0 == myres) {
+
+#line 3728 "printqd.ctr"
+ back = 0;
+ }
+ } else {
+
+#line 3731 "printqd.ctr"
+ /* ERROR: Syntax, only allowed in class */
+ log_1(fn, lineno, LOG_EMERG, 1, 61);
+ back = 0;
+ }
+ } break;
+ case 17 : {
+
+#line 3737 "printqd.ctr"
+ if ((2 == sectt) && (NULL != ppr)) {
+ myres = add_alias(ppr, pv, fn, lineno);
+ if (0 == myres) {
+
+#line 3740 "printqd.ctr"
+ back = 0;
+ }
+ } else {
+
+#line 3743 "printqd.ctr"
+ /* ERROR: Syntax, only allowed in printer */
+ log_1(fn, lineno, LOG_EMERG, 1, 62);
+ back = 0;
+ }
+ } break;
+ case 18 : {
+
+#line 3749 "printqd.ctr"
+ if ((2 == sectt) && (NULL != ppr)) {
+ myres = assign_class(ppr, pv, fn, lineno);
+ if (0 == myres) {
+
+#line 3752 "printqd.ctr"
+ back = 0;
+ }
+ } else {
+
+#line 3755 "printqd.ctr"
+ /* ERROR: Syntax, only allowed in printer */
+ log_1(fn, lineno, LOG_EMERG, 1, 62);
+ back = 0;
+ }
+ } break;
+ case 19 : {
+
+#line 3761 "printqd.ctr"
+ if (0 == sectt) {
+ if (NULL == conf.lname) {
+ conf.lname = dk4str8_dup(pv, NULL);
+ if (NULL == conf.lname) {
+ /* ERROR: Memory */
+ log_1(fn, lineno, LOG_EMERG, 1, 27);
+ back = 0;
+
+#line 3768 "printqd.ctr"
+ }
+ } else {
+
+#line 3770 "printqd.ctr"
+ /* ERROR: Redefinition */
+ log_1(fn, lineno, LOG_EMERG, 1, 63);
+ back = 0;
+ }
+ } else {
+
+#line 3775 "printqd.ctr"
+ /* ERROR: Only in options */
+ log_1(fn, lineno, LOG_EMERG, 1, 55);
+ back = 0;
+ }
+ } break;
+ case 20 : {
+
+#line 3781 "printqd.ctr"
+ back = set_log_features(pv, fn, lineno);
+ } break;
+ case 21 : {
+
+#line 3784 "printqd.ctr"
+ if (0 == sectt) {
+ struct passwd *pw;
+ if (NULL == (px = dk4str8_next(pv, NULL))) {
+ pw = getpwnam(pv);
+ if (NULL != pw) {
+ if ((0 == conf.suid) || (conf.suid == pw->pw_uid)) {
+ conf.suid = pw->pw_uid;
+ } else {
+ /* ERROR: Redefinition */
+ log_1(fn, lineno, LOG_EMERG, 1, 52);
+ back = 0;
+
+#line 3795 "printqd.ctr"
+ }
+ } else {
+
+#line 3797 "printqd.ctr"
+ /* ERROR: User not found */
+ log_3(fn, lineno, LOG_EMERG, 1, 53, 54, pv);
+ back = 0;
+ }
+ } else {
+
+#line 3802 "printqd.ctr"
+ /* ERROR: Syntax, just one component allowed */
+ log_3(fn, lineno, LOG_EMERG, 1, 23, 24, px);
+ back = 0;
+ }
+ } else {
+
+#line 3807 "printqd.ctr"
+ /* ERROR: Only allwowed in options section */
+ log_1(fn, lineno, LOG_EMERG, 1, 55);
+ back = 0;
+ }
+ } break;
+ case 22 : {
+
+#line 3813 "printqd.ctr"
+ if (0 == sectt) {
+ struct group *pgr;
+ if (NULL == (px = dk4str8_next(pv, NULL))) {
+ pgr = getgrnam(pv);
+ if (NULL != pgr) {
+ if((0 == conf.sgid) || (conf.sgid == pgr->gr_gid)) {
+ conf.sgid = pgr->gr_gid;
+ } else {
+ /* ERROR: Syntax, group redefinition */
+ log_1(fn, lineno, LOG_EMERG, 1, 56);
+ back = 0;
+
+#line 3824 "printqd.ctr"
+ }
+ } else {
+
+#line 3826 "printqd.ctr"
+ /* ERROR: Syntax, group not found */
+ log_3(fn, lineno, LOG_EMERG, 1, 57, 58, pv);
+ back = 0;
+ }
+ } else {
+
+#line 3831 "printqd.ctr"
+ /* ERROR: Syntax, just one component allowed */
+ log_3(fn, lineno, LOG_EMERG, 1, 23, 24, px);
+ back = 0;
+ }
+ } else {
+
+#line 3836 "printqd.ctr"
+ /* ERROR: Syntax, only allowed in options */
+ log_1(fn, lineno, LOG_EMERG, 1, 55);
+ back = 0;
+ }
+ } break;
+ }
+ } else {
+
+#line 3843 "printqd.ctr"
+ /* ERROR: Syntax, missing value */
+ log_1(fn, lineno, LOG_EMERG, 1, 64);
+ back = 0;
+ }
+ } else {
+
+#line 3848 "printqd.ctr"
+ /* ERROR: Syntax, missing value */
+ log_1(fn, lineno, LOG_EMERG, 1, 64);
+ back = 0;
+ }
+ }
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 3856 "printqd.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 3861 "printqd.ctr"
+ }
+#endif
+ }
+ fclose(fipo);
+ if (1 == back) {
+ back = config_check(fn, lineno);
+ }
+ } else {
+
+#line 3869 "printqd.ctr"
+ /* ERROR: Failed to open file */
+ log_1(fn, 0UL, LOG_EMERG, 1, 65);
+ }
+ } else {
+ /* ERROR: Memory */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 27);
+ }
+
+
+#line 3877 "printqd.ctr"
+ return back;
+}
+
+
+
+static
+void
+release_allowed_peers(dk4_sto_it_t *it)
+{
+ dk4_allowed_peer_t *peer;
+
+
+#line 3888 "printqd.ctr"
+ dk4sto_it_reset(it);
+ do {
+ peer = (dk4_allowed_peer_t *)dk4sto_it_next(it);
+ if (NULL != peer) {
+ dk4mem_free(peer);
+ }
+ } while (NULL != peer);
+ dk4sto_it_close(it);
+
+
+#line 3897 "printqd.ctr"
+}
+
+
+
+/** Release resources used to save configuration data.
+*/
+static
+void
+config_release(void)
+{
+
+
+#line 3908 "printqd.ctr"
+ prev_uid = conf.uid;
+ prev_gid = conf.gid;
+
+ if (NULL != conf.i_aa) { /* Allowed peers for administration */
+ release_allowed_peers(conf.i_aa);
+ } conf.i_aa = NULL;
+ if (NULL != conf.s_aa) {
+ dk4sto_close(conf.s_aa);
+ } conf.s_aa = NULL;
+ if (NULL != conf.i_ad) { /* Allowed peers for data */
+ release_allowed_peers(conf.i_ad);
+ } conf.i_ad = NULL;
+ if (NULL != conf.s_ad) {
+ dk4sto_close(conf.s_ad);
+ } conf.s_ad = NULL;
+ if (NULL != conf.i_ai) { /* Allowed peers for information */
+ release_allowed_peers(conf.i_ai);
+ } conf.i_ai = NULL;
+ if (NULL != conf.s_ai) {
+ dk4sto_close(conf.s_ai);
+ } conf.s_ai = NULL;
+ if (NULL != conf.i_a) { /* Aliases */
+ printer_alias_all_delete(conf.i_a);
+ } conf.i_a = NULL;
+ if (NULL != conf.s_a) {
+ dk4sto_close(conf.s_a);
+ } conf.s_a = NULL;
+ if (NULL != conf.i_p) { /* Printers */
+ printer_all_delete(conf.i_p);
+ } conf.i_p = NULL;
+ if (NULL != conf.s_p) {
+ dk4sto_close(conf.s_p);
+ } conf.s_p = NULL;
+ if (NULL != conf.i_c) { /* Classes */
+ class_all_delete(conf.i_c);
+ } conf.i_c = NULL;
+ if (NULL != conf.s_c) {
+ dk4sto_close(conf.s_c);
+ } conf.s_c = NULL;
+ dk4mem_release(conf.dname);
+ dk4mem_release(conf.sname);
+ dk4mem_release(conf.lname);
+ conf.m_loc = 0;
+ conf.m_tcp = 0;
+ conf.uid = 0;
+ conf.gid = 0;
+ conf.slbl = 0;
+ conf.snbl = 0;
+ conf.ptcp = 9100;
+ conf.pudp = 9100;
+
+
+#line 3959 "printqd.ctr"
+}
+
+
+
+/** Allocate resources before starting outer loop.
+ @return 1 on success (can enter loop), 0 on error (exit).
+*/
+static
+int
+outer_allocate_resources(void)
+{
+ int back = 0;
+
+
+#line 3972 "printqd.ctr"
+
+ /* Initialize variables to NULL.
+ */
+ s_c_unix = NULL;
+ i_c_unix = NULL;
+ s_c_tcp = NULL;
+ i_c_tcp = NULL;
+
+ /* Allocate resources.
+ */
+ s_c_unix = dk4sto_open(NULL);
+ if (NULL == s_c_unix) {
+
+#line 3984 "printqd.ctr"
+ /* ERROR: Memory */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 27);
+ goto finished;
+ }
+ dk4sto_set_comp(s_c_unix, compare_pqd_l_conn_t, 0);
+ i_c_unix = dk4sto_it_open(s_c_unix, NULL);
+ if (NULL == i_c_unix) {
+
+#line 3991 "printqd.ctr"
+ /* ERROR: Memory */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 27);
+ goto finished;
+ }
+ s_c_tcp = dk4sto_open(NULL);
+ if (NULL == s_c_tcp) {
+
+#line 3997 "printqd.ctr"
+ /* ERROR: Memory */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 27);
+ goto finished;
+ }
+ dk4sto_set_comp(s_c_tcp, compare_pqd_n_conn_t, 0);
+ i_c_tcp = dk4sto_it_open(s_c_tcp, NULL);
+ if (NULL == i_c_tcp) {
+
+#line 4004 "printqd.ctr"
+ /* ERROR: Memory */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 27);
+ goto finished;
+ }
+
+ /* Indicate success.
+ */
+ back = 1;
+
+ finished:
+
+
+#line 4015 "printqd.ctr"
+ return back;
+}
+
+
+
+/** Release resources after finishing outer loop.
+*/
+static
+void
+outer_release_resources(void)
+{
+ pqd_n_conn_t *pnc;
+ pqd_l_conn_t *plc;
+
+
+#line 4029 "printqd.ctr"
+
+ if (NULL != i_c_tcp) {
+ dk4sto_it_reset(i_c_tcp);
+ do {
+ pnc = (pqd_n_conn_t *)dk4sto_it_next(i_c_tcp);
+ if (NULL != pnc) {
+ /* Release pnc */
+ if (INVALID_SOCKET != pnc->sock) {
+ (void)dk4socket_close(pnc->sock, NULL);
+ }
+ dk4mem_free(pnc);
+ }
+ } while(NULL != pnc);
+ dk4sto_it_close(i_c_tcp);
+ }
+ i_c_tcp = NULL;
+ if (NULL != s_c_tcp) {
+ dk4sto_close(s_c_tcp);
+ }
+ s_c_tcp = NULL;
+ if (NULL != i_c_unix) {
+ dk4sto_it_reset(i_c_unix);
+ do {
+ plc = (pqd_l_conn_t *)dk4sto_it_next(i_c_unix);
+ if (NULL != plc) {
+ /* Release plc */
+ if (INVALID_SOCKET != plc->sock) {
+ (void)dk4socket_close(plc->sock, NULL);
+ }
+ dk4mem_free(plc);
+ }
+ } while (NULL != plc);
+ dk4sto_it_close(i_c_unix);
+ }
+ i_c_unix = NULL;
+ if (NULL != s_c_unix) {
+ dk4sto_close(s_c_unix);
+ }
+ s_c_unix = NULL;
+
+
+#line 4069 "printqd.ctr"
+}
+
+
+
+static
+void
+pqd_dbi_open_error(const char *fn, dk4_er_t *erp)
+{
+ switch (erp->ec) {
+ case DK4_E_NOT_SUPPORTED : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 105, 202, fn);
+ } break;
+ case DK4_E_MATH_OVERFLOW : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 105, 203, fn);
+ } break;
+ case DK4_E_MEMORY_ALLOCATION_FAILED : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 105, 204, fn);
+ } break;
+ case DK4_E_SYNTAX : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 105, 205, fn);
+ } break;
+ case DK4_E_SEC_CHECK : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 105, 206, fn);
+ } break;
+ case DK4_E_OPEN_READ_FAILED : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 105, 207, fn);
+ } break;
+ case DK4_E_OPEN_WRITE_FAILED : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 105, 208, fn);
+ } break;
+ case DK4_E_CLOSE_FAILED : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 105, 209, fn);
+ } break;
+ default : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 105, 106, fn);
+ } break;
+ }
+}
+
+
+/** Allocate resources before starting inner loop.
+ * Create log directory and log file.
+ * Open database.
+ * Log message for starting service.
+ @return 1 on success (can enter loop), 0 on error (exit).
+*/
+static
+int
+inner_allocate_resources(void)
+{
+ char necbuf[16*sizeof(dk4_um_t)];
+ dk4_er_t er;
+ const char *fn;
+ uid_t sockuid;
+ gid_t sockgid;
+ int res;
+ int back = 0;
+
+
+#line 4127 "printqd.ctr"
+
+ /* Log file directory hierarchy.
+ */
+ fn = conf.lname;
+ if (NULL == fn) { fn = def_log_file_name; }
+ if (0 != user_switched) {
+ res = dk4mkdir_hierarchy_c8(fn, 0, NULL);
+ } else {
+ res = dk4mkdir_hierarchy_ugm_c8(fn, 0, conf.uid, conf.gid, 0750, NULL);
+ }
+ if (0 == res) {
+
+#line 4138 "printqd.ctr"
+ /* ERROR: Failed to create directory hierachy for log file */
+ log_3(NULL, 0UL, LOG_EMERG, 1, 95, 96, fn);
+ goto finished;
+ }
+
+ /* Database directory hierarchy
+ */
+ fn = conf.dname;
+ if (NULL == fn) { fn = def_db_file_name; }
+ fn = dk4dbi_filename_part(fn);
+ if (0 != user_switched) {
+ res = dk4mkdir_hierarchy_c8(fn, 0, NULL);
+ } else {
+ res = dk4mkdir_hierarchy_ugm_c8(fn, 0, conf.uid, conf.gid, 0750, NULL);
+ }
+ if (0 == res) {
+
+#line 4154 "printqd.ctr"
+ /* ERROR: Failed to create directory hierarchy for db file */
+ log_3(NULL, 0UL, LOG_EMERG, 1, 97, 98, fn);
+ goto finished;
+ }
+
+ /* Socket directory hierarchy
+ */
+ fn = conf.sname;
+ if (NULL == fn) { fn = def_sock_file_name; }
+ sockuid = conf.suid;
+ if (0 == sockuid) { sockuid = conf.uid; }
+ sockgid = conf.sgid;
+ if (0 == sockgid) { sockgid = conf.gid; }
+ if ((0 != user_switched) && (0 != conf.uid)) {
+ res = dk4mkdir_hierarchy_c8(fn, 0, NULL);
+ } else {
+ /*
+ In contrast to the db and log directories the non-privileged
+ user needs write access to the directory as the socket is deleted
+ and newly created.
+ */
+ res = dk4mkdir_hierarchy_ugm_c8(fn, 0, sockuid, sockgid, 0770, NULL);
+ }
+ if (0 == res) {
+
+#line 4178 "printqd.ctr"
+ /* ERROR: Failed to create directory hierarchy for socket */
+ log_3(NULL, 0UL, LOG_EMERG, 1, 99, 100, fn);
+ goto finished;
+ }
+
+ /* UNIX listener socket.
+ */
+ fn = conf.sname;
+ if (NULL == fn) { fn = def_sock_file_name; }
+
+
+#line 4188 "printqd.ctr"
+ dk4error_init(&er);
+ if (
+ ((0 != sockuid) || (0 != sockgid))
+ && ((0 == user_switched) || (0 == conf.uid))
+ )
+ {
+ so_unix = dk4socket_c8_unix_listener_owner_group_mode(
+ fn, ((0 < conf.slbl) ? (conf.slbl) : 5), sockuid, sockgid, 0660, &er
+ );
+ } else {
+ so_unix = dk4socket_c8_unix_listener(
+ fn, ((0 < conf.slbl) ? (conf.slbl) : 5), &er
+ );
+ }
+ if (INVALID_SOCKET == so_unix) {
+
+#line 4203 "printqd.ctr"
+ /* ERROR: Failed to create listener socket */
+ res = dk4ma_write_c8_decimal_signed(
+ necbuf, sizeof(necbuf), (dk4_im_t)(er.dt.iDetails1), 0, NULL
+ );
+ if (0 != res) {
+ switch (er.ec) {
+ case DK4_E_SYNTAX : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 101, 178, fn);
+ } break;
+ case DK4_E_NON_SOCKET : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 101, 179, fn);
+ } break;
+ case DK4_E_UNLINK_FAILED : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 101, 180, fn);
+ } break;
+ case DK4_E_SOCKET_SOCKET : {
+ log_5(NULL, 0UL, LOG_EMERG, 1, 101, 181, 182, fn, necbuf);
+ } break;
+ case DK4_E_SOCKET_BIND : {
+ log_5(NULL, 0UL, LOG_EMERG, 1, 101, 183, 182, fn, necbuf);
+ } break;
+ case DK4_E_SOCKET_LISTEN : {
+ log_5(NULL, 0UL, LOG_EMERG, 1, 101, 184, 182, fn, necbuf);
+ } break;
+ case DK4_E_CHOWN_FAILED : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 101, 185, fn);
+ } break;
+ case DK4_E_CHMOD_FAILED : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 101, 186, fn);
+ } break;
+ default : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 101, 102, fn);
+ } break;
+ }
+ } else {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 101, 102, fn);
+ }
+ goto finished;
+ }
+
+#line 4242 "printqd.ctr"
+
+ /* TCP listener socket set.
+ */
+ if (0 < conf.ptcp) {
+ dk4error_init(&er);
+ ss_tcp = dk4socket_c8_set_server(
+ conf.ptcp, ((0 < conf.snbl) ? (conf.snbl) : 5), 0, &er
+ );
+ if (NULL == ss_tcp) {
+
+#line 4251 "printqd.ctr"
+ /* ERROR: Failed to create TCP listener socket */
+ res = dk4ma_write_c8_decimal_signed(
+ necbuf, sizeof(necbuf), (dk4_im_t)(er.dt.iDetails1), 0, NULL
+ );
+ if (0 != res) {
+ switch (er.ec) {
+ case DK4_E_MATH_OVERFLOW : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 188);
+ } break;
+ case DK4_E_MEMORY_ALLOCATION_FAILED : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 189);
+ } break;
+ case DK4_E_SOCKET_SOCKET : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 190, 191, necbuf);
+ } break;
+ case DK4_E_SOCKET_BIND : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 192, 191, necbuf);
+ } break;
+ case DK4_E_SOCKET_LISTEN : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 193, 191, necbuf);
+ } break;
+ case DK4_E_SOCKET_GETADDRLOC : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 194, 191, necbuf);
+ } break;
+ default : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 103);
+ } break;
+ }
+ } else {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 103);
+ }
+ goto finished;
+ }
+ }
+
+ /* UDP socket set.
+ */
+ if (0 < conf.pudp) {
+ dk4error_init(&er);
+ ss_udp = dk4socket_c8_set_udp(conf.pudp, 0, 0, &er);
+ if (NULL == ss_udp) {
+
+#line 4292 "printqd.ctr"
+ /* ERROR: Failed to create UDP socket set */
+ res = dk4ma_write_c8_decimal_signed(
+ necbuf, sizeof(necbuf), (dk4_im_t)(er.dt.iDetails1), 0, NULL
+ );
+ if (0 != res) {
+ switch (er.ec) {
+ case DK4_E_MATH_OVERFLOW : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 195);
+ } break;
+ case DK4_E_MEMORY_ALLOCATION_FAILED : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 196);
+ } break;
+ case DK4_E_SOCKET_SOCKET : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 197, 198, necbuf);
+ } break;
+ case DK4_E_SOCKET_BIND : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 199, 198, necbuf);
+ } break;
+ case DK4_E_SOCKET_LISTEN : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 200, 198, necbuf);
+ } break;
+ case DK4_E_SOCKET_GETADDRLOC : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 201, 198, necbuf);
+ } break;
+ }
+ } else {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 104);
+ }
+ goto finished;
+ }
+ }
+
+ fn = conf.dname;
+ if (NULL == fn) { fn = def_db_file_name; }
+
+
+#line 4327 "printqd.ctr"
+ dk4error_init(&er);
+ db = dk4dbi_open(fn, 1, 0, 1024, 1024, &er);
+ if (NULL != db) {
+
+#line 4330 "printqd.ctr"
+ db_modified = 0;
+ res = 1;
+ dk4error_init(&er);
+ if (0 == dbi_set(db, printqd_kw[79],printqd_kw[79],&er)) { res = 0; }
+ if (0 == dk4dbi_close(db, &er)) { res = 0; }
+ db = NULL;
+ db_modified = 0;
+ if (0 != res) {
+
+
+#line 4339 "printqd.ctr"
+ dk4error_init(&er);
+ db = dk4dbi_open(fn, 1, 0, 1024, 1024, &er);
+ if (NULL != db) {
+
+#line 4342 "printqd.ctr"
+ db_modified = 0;
+ } else {
+
+#line 4344 "printqd.ctr"
+ /* ERROR: Failed to open database */
+ pqd_dbi_open_error(fn, &er);
+ goto finished;
+ }
+ } else {
+
+#line 4349 "printqd.ctr"
+ /* ERROR: Failed to write initial entry to database */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 107);
+ switch (er.ec) {
+ case DK4_E_SYNTAX : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 210);
+ } break;
+ case DK4_E_NOT_SUPPORTED : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 211);
+ } break;
+ case DK4_E_MEMORY_ALLOCATION_FAILED : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 212);
+ } break;
+ case DK4_E_OPEN_WRITE_FAILED : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 213);
+ } break;
+ case DK4_E_WRITE_FAILED : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 214);
+ } break;
+ case DK4_E_CLOSE_FAILED : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 215);
+ } break;
+ case DK4_E_SEC_CHECK : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 216);
+ } break;
+ default : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 107);
+ } break;
+ }
+ goto finished;
+ }
+ } else {
+
+#line 4380 "printqd.ctr"
+ /* ERROR: Failed to open database */
+ pqd_dbi_open_error(fn, &er);
+ goto finished;
+ }
+
+ /* Finally indicate success.
+ */
+ back = 1;
+
+ finished:
+
+
+#line 4391 "printqd.ctr"
+ return back;
+}
+
+
+
+/** Release resources after finishing inner loop.
+ * Log message for finishing service.
+ * Synchronize and close database.
+ * Close log file.
+*/
+static
+int
+inner_release_resources(void)
+{
+ const char *fn;
+ int back = 1;
+
+
+#line 4408 "printqd.ctr"
+
+ /* Database
+ */
+ if (NULL != db) {
+ if (0 == dk4dbi_close(db, NULL)) {
+
+#line 4413 "printqd.ctr"
+ /* ERROR: Failed to synchronize database to disk */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 108);
+ back = 0;
+ }
+ db = NULL;
+ db_modified = 0;
+ }
+
+ /* UDP socket set.
+ */
+ if (NULL != ss_udp) {
+
+#line 4424 "printqd.ctr"
+ dk4socket_set_close(ss_udp, NULL);
+ }
+ ss_udp = NULL;
+
+ /* TCP listener socket set.
+ */
+ if (NULL != ss_tcp) {
+
+#line 4431 "printqd.ctr"
+ dk4socket_set_close(ss_tcp, NULL);
+ }
+ ss_tcp = NULL;
+
+ /* Unix listener socket.
+ */
+ if (INVALID_SOCKET != so_unix) { dk4socket_close(so_unix, NULL); }
+ so_unix = INVALID_SOCKET;
+ fn = conf.sname;
+ if (NULL == fn) { fn = def_sock_file_name; }
+ (void)dk4delete_file_c8(fn, NULL);
+
+
+
+#line 4444 "printqd.ctr"
+ return back;
+}
+
+
+
+/** Switch to non-privileged user and group if configured to do so.
+ @return 1 on success (can continue), 0 on error (exit).
+*/
+static
+int
+change_group_and_user(void)
+{
+ const char *fn = NULL;
+ uid_t myuid;
+ gid_t mygid;
+ int dbt = DK4_DB_BE_UNKNOWN;
+ int back = 1;
+
+
+#line 4462 "printqd.ctr"
+ if (0 != user_switched) {
+
+#line 4463 "printqd.ctr"
+ if (conf.uid != prev_uid) {
+ back = 0;
+
+#line 4465 "printqd.ctr"
+ /* ERROR: User to run as was changed */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 66);
+ } else {
+ if (conf.gid != prev_gid) {
+
+#line 4469 "printqd.ctr"
+ back = 0;
+ /* ERROR: Group to run as was changed */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 67);
+ }
+ }
+ } else {
+
+#line 4475 "printqd.ctr"
+ user_switched = 1;
+ myuid = geteuid();
+ mygid = getegid();
+ if ((myuid != conf.uid) || (mygid != conf.gid)) {
+
+#line 4479 "printqd.ctr"
+ /*
+ PID file ownership and permissions
+ */
+ if (0 != chown(pid_file_name, conf.uid, conf.gid)) {
+ back = 0;
+ /* ERROR: Failed to change PID file ownership */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 217);
+ }
+ if (0 != chmod(pid_file_name, 0660)) {
+ back = 0;
+ /* ERROR: Failed to change PID file permissions */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 218);
+ }
+ /*
+ Log file ownership and permissions
+ */
+ fn = conf.lname;
+ if (NULL == fn) { fn = def_log_file_name; }
+ if (0 != chown(fn, conf.uid, conf.gid)) {
+ back = 0;
+
+#line 4499 "printqd.ctr"
+ /* ERROR: Failed to change log file ownership */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 109);
+ }
+ if (0 != chmod(fn, 0660)) {
+ back = 0;
+
+#line 4504 "printqd.ctr"
+ /* ERROR: Failed to change log file permissions */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 110);
+ }
+ /*
+ Database ownership and permissions
+ */
+ if (0 == dk4dbi_change_owner_and_mode(db,conf.uid,conf.gid,0660,NULL)) {
+ back = 0;
+
+#line 4512 "printqd.ctr"
+ /* ERROR: failed to change db ownership and permissions */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 111);
+ }
+ switch ( (dbt = dk4dbi_get_type(db)) ) {
+ case DK4_DB_BE_BDB : case DK4_DB_BE_NDBM : {
+
+
+#line 4518 "printqd.ctr"
+ if (0 == dk4dbi_close(db, NULL)) {
+
+#line 4519 "printqd.ctr"
+ /* ERROR: Failed to synchronize database to disk */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 121);
+ }
+ db = NULL;
+ db_modified = 0;
+ if (DK4_DB_BE_BDB == dbt) {
+ fn = ((NULL != conf.dname) ? (conf.dname) : (def_db_file_name));
+ fn = dk4dbi_filename_part(fn);
+ if (0 != chown(fn, conf.uid, conf.gid)) {
+ back = 0;
+ log_3(NULL, 0UL, LOG_EMERG, 1, 174, 175, fn);
+ }
+ if (0 != chmod(fn, 0660)) {
+ back = 0;
+ log_3(NULL, 0UL, LOG_EMERG, 1, 176, 177, fn);
+ }
+ }
+ } break;
+ }
+ /*
+ Local UNIX socket ownership and permission
+ */
+ if (INVALID_SOCKET != so_unix) {
+
+#line 4542 "printqd.ctr"
+
+
+#line 4543 "printqd.ctr"
+ if (0 != fchown(so_unix, conf.uid, conf.gid)) {
+ back = 0;
+
+#line 4545 "printqd.ctr"
+ /* ERROR: Failed to change socket ownership */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 112);
+ }
+
+
+#line 4549 "printqd.ctr"
+ if (0 != fchmod(so_unix, 0660)) {
+ back = 0;
+
+#line 4551 "printqd.ctr"
+ /* ERROR: Failed to change socket permissions */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 113);
+ }
+ } else {
+
+#line 4555 "printqd.ctr"
+ }
+ /*
+ Switch group
+ */
+ if (0 != setgid(conf.gid)) {
+ back = 0;
+
+#line 4561 "printqd.ctr"
+ /* ERROR: Failed to switch group */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 114);
+ }
+ /*
+ Switch user
+ */
+ if (0 != setuid(conf.uid)) {
+ back = 0;
+
+#line 4569 "printqd.ctr"
+ /* ERROR: Failed to switch user */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 115);
+ }
+ /*
+ Re-open database if closed.
+ */
+ if (NULL == db) {
+
+#line 4576 "printqd.ctr"
+ fn = conf.dname;
+ if (NULL == fn) { fn = def_db_file_name; }
+ db = dk4dbi_open(fn, 1, 0, 1024, 1024, NULL);
+ if (NULL != db) {
+ db_modified = 0;
+ } else {
+
+#line 4582 "printqd.ctr"
+ back = 0;
+ /* ERROR: Failed to open database */
+ log_3(NULL, 0UL, LOG_EMERG, 1, 105, 106, fn);
+ }
+ }
+ } else {
+
+#line 4588 "printqd.ctr"
+ }
+ }
+
+
+#line 4591 "printqd.ctr"
+ return back;
+}
+
+
+
+static
+int
+protocol_level_for_address(struct sockaddr *so)
+{
+ int back = PQD_PROTO_NONE;
+
+
+#line 4602 "printqd.ctr"
+ if (0 != conf.aglo) {
+ back = PQD_PROTO_ADMIN;
+ } else {
+ if (NULL != dk4sto_it_find_like(conf.i_aa, so, 1)) {
+ back = PQD_PROTO_ADMIN;
+ } else {
+ if (0 != conf.dglo) {
+ back = PQD_PROTO_DATA;
+ } else {
+ if (NULL != dk4sto_it_find_like(conf.i_ad, so, 1)) {
+ back = PQD_PROTO_DATA;
+ } else {
+ if (0 != conf.iglo) {
+ back = PQD_PROTO_INFO;
+ } else {
+ if (NULL != dk4sto_it_find_like(conf.i_ai, so, 1)) {
+ back = PQD_PROTO_INFO;
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+#line 4626 "printqd.ctr"
+ return back;
+}
+
+
+
+/** Check whether the action is allowed in the protocol level.
+ @param act Action to check.
+ @param protlev Protocol level.
+ @return 1 if action is allowed, 0 otherwise.
+*/
+static
+int
+protocol_level_check(int act, int protlev)
+{
+ int back = 0;
+
+
+#line 4642 "printqd.ctr"
+ switch (act) {
+ case PQD_CMD_INFO : {
+ if (PQD_PROTO_INFO <= protlev) { back = 1; }
+ } break;
+ case PQD_CMD_CONTROL : {
+ if (PQD_PROTO_ADMIN <= protlev) { back = 1; }
+ } break;
+ default : {
+ if (PQD_PROTO_DATA <= protlev) { back = 1; }
+ } break;
+ }
+
+
+#line 4654 "printqd.ctr"
+ return back;
+}
+
+
+
+static
+void
+job_init(pqd_rq_t *ptr)
+{
+
+
+#line 4664 "printqd.ctr"
+ DK4_MEMRES(ptr, sizeof(pqd_rq_t));
+ ptr->connptr = NULL;
+ ptr->sto = NULL;
+ ptr->soa = NULL;
+ ptr->pnconn = NULL;
+ ptr->cmdptr = NULL;
+ ptr->argptr = NULL;
+ ptr->szsoa = 0;
+ ptr->sock = 0;
+ ptr->action = 0;
+ ptr->protlev = PQD_PROTO_NONE;
+ ptr->logthis = 1;
+
+
+#line 4677 "printqd.ctr"
+}
+
+
+
+static
+void
+account_init(pqd_account_t *ptr)
+{
+
+
+#line 4686 "printqd.ctr"
+ DK4_MEMRES(ptr, sizeof(pqd_account_t));
+ ptr->limit = (dk4_um_t)0UL;
+ ptr->used = (dk4_um_t)0UL;
+ ptr->account = (dk4_um_t)0UL;
+ ptr->da = 0;
+
+
+#line 4692 "printqd.ctr"
+}
+
+
+
+/** Close a stream connection record.
+ @param sock Socket to close.
+ @param sto Container for the records.
+ @param ptr Record to delete, containing the socket.
+ @param pnconn Address of connection number variable to decrease.
+*/
+static
+void
+close_stream_conn(
+ dk4_socket_t sock,
+ dk4_sto_t *sto,
+ void *ptr,
+ size_t *pnconn
+)
+{
+
+
+#line 4712 "printqd.ctr"
+ if ((NULL != sto) && (NULL != ptr)) {
+ dk4sto_remove(sto, ptr, NULL);
+ }
+ if (INVALID_SOCKET != sock) {
+ (void)dk4socket_close(sock, NULL);
+ }
+ if (NULL != ptr) {
+ dk4mem_free(ptr);
+ }
+ if (NULL != pnconn) {
+ if (0 < *pnconn) {
+ *pnconn -= 1;
+ }
+ }
+
+
+#line 4727 "printqd.ctr"
+}
+
+
+
+/** Send a text response.
+ @param job Job structure.
+ @param str Text to send (still without newline).
+*/
+static
+void
+send_text(pqd_rq_t *job, const char *str)
+{
+ const char * msgs[3]; /* Log message text parts */
+ size_t sz; /* Number of bytes to send */
+ size_t wr; /* Number of bytes successfully sent */
+ int res; /* Operation result */
+
+
+#line 4744 "printqd.ctr"
+ if (0 != dk4str8_cpy_s(inbuf, sizeof(inbuf), str, NULL)) {
+ if (0 != job->logthis) {
+ msgs[0] = printqd_kw[86];
+ msgs[1] = str;
+ msgs[2] = NULL;
+ log_multipart_message(NULL, 0UL, LOG_EMERG, 0, msgs, 2);
+ }
+ if (0 != dk4str8_cat_s(inbuf, sizeof(inbuf), printqd_kw[5], NULL)) {
+ sz = dk4str8_len(inbuf);
+ wr = sz;
+ if ((NULL != job->soa) && (0 < job->szsoa)) {
+
+#line 4755 "printqd.ctr"
+ (void)dk4socket_sendto(
+ job->sock, inbuf, &wr, 0, job->soa, job->szsoa, 0L, 0L, NULL
+ );
+ } else {
+
+#line 4759 "printqd.ctr"
+ res = dk4socket_send(job->sock, inbuf, &wr, 0, 0L, 0L, NULL);
+ switch (res) {
+ case DK4_SOCKET_RESULT_SUCCESS :
+ case DK4_SOCKET_RESULT_IN_PROGRESS : {
+ if (wr != sz) {
+
+#line 4764 "printqd.ctr"
+ res = DK4_SOCKET_RESULT_FAILED;
+ }
+ } break;
+ }
+ if (DK4_SOCKET_RESULT_FAILED == res) {
+
+#line 4769 "printqd.ctr"
+ close_stream_conn(job->sock, job->sto, job->connptr, job->pnconn);
+ }
+ }
+ } else {
+
+#line 4773 "printqd.ctr"
+ /* ERROR: Response text too long (BUG)! */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 116);
+ }
+ } else {
+
+#line 4777 "printqd.ctr"
+ /* ERROR: Response text too long (BUG)! */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 116);
+ }
+
+
+#line 4781 "printqd.ctr"
+}
+
+
+
+/** Send response for info or acct-check request.
+ @param job Job structure.
+ @param account Account structure containing limits and used pages.
+ @param summary Summary: Allowed to print.
+ @param how How to respond: 0=info, 1=acct-check/jobstart.
+*/
+static
+void
+send_response(
+ pqd_rq_t *job,
+ pqd_account_t *account,
+ int summary,
+ int how
+)
+{
+ char res[16+32*sizeof(dk4_um_t)];
+ char b1[16+8*sizeof(dk4_um_t)];
+ int ok = 0;
+
+
+#line 4804 "printqd.ctr"
+ switch (how) {
+ case 0: {
+ /* Limit Used Account Summary */
+ if (DK4_UM_MAX == account->limit) {
+ ok = dk4str8_cpy_s(res, sizeof(res), printqd_kw[84], NULL);
+ } else {
+ ok = dk4ma_write_c8_decimal_unsigned(
+ b1, sizeof(b1), account->limit, 0, NULL
+ );
+ if (0 != ok) {
+ ok = dk4str8_cpy_s(res, sizeof(res), b1, NULL);
+ }
+ }
+ if (0 != ok) {
+ ok = dk4ma_write_c8_decimal_unsigned(
+ b1, sizeof(b1), account->used, 0, NULL
+ );
+ if (0 != ok) {
+ ok = dk4str8_cat_s(res, sizeof(res), printqd_kw[85], NULL);
+ if (0 != ok) {
+ ok = dk4str8_cat_s(res, sizeof(res), b1, NULL);
+ if (0 != ok) {
+ ok = dk4ma_write_c8_decimal_unsigned(
+ b1, sizeof(b1), account->account, 0, NULL
+ );
+ if (0 != ok) {
+ ok = dk4str8_cat_s(res, sizeof(res), printqd_kw[85], NULL);
+ if (0 != ok) {
+ ok = dk4str8_cat_s(res, sizeof(res), b1, NULL);
+ if (0 != ok) {
+ ok = dk4ma_write_c8_decimal_signed(
+ b1, sizeof(b1), (dk4_im_t)summary, 0, NULL
+ );
+ if (0 != ok) {
+ ok = dk4str8_cat_s(res,sizeof(res),printqd_kw[85],NULL);
+ if (0 != ok) {
+ ok = dk4str8_cat_s(res, sizeof(res), b1, NULL);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if (0 != ok) {
+ send_text(job, res);
+ } else {
+ send_text(job, printqd_kw[83]);
+ }
+ } break;
+ default: {
+ if (0 != summary) {
+ send_text(job, printqd_kw[80]);
+ } else {
+ switch (account->da) {
+ case 0: {
+ send_text(job, printqd_kw[81]);
+ } break;
+ default: {
+ send_text(job, printqd_kw[82]);
+ } break;
+ }
+ }
+ } break;
+ }
+
+
+#line 4872 "printqd.ctr"
+}
+
+
+
+/** Get printer entry for name (printer or alias name).
+ @param name Printer or alias name.
+ @return Printer entry.
+*/
+static
+pqd_printer_t *
+get_printer_for_name(const char *name)
+{
+ pqd_printer_t *back = NULL;
+ pqd_printer_alias_t *al = NULL;
+
+
+#line 4887 "printqd.ctr"
+ back = (pqd_printer_t *)dk4sto_it_find_like(conf.i_p, name, 1);
+ if (NULL == back) {
+ al = (pqd_printer_alias_t *)dk4sto_it_find_like(conf.i_a, name, 1);
+ if (NULL != al) {
+ back = al->pr;
+ }
+ }
+
+
+#line 4895 "printqd.ctr"
+ return back;
+}
+
+
+
+/** Save one dk4_um_t value to database.
+ @param kwi Keyword index for key start.
+ @param un User name.
+ @param cn Class name.
+ @param val Value to store.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+save_one_number(
+ size_t kwi,
+ const char *un,
+ const char *cn,
+ dk4_um_t val
+)
+{
+ int back = 0;
+ int strok = 0;
+
+
+#line 4919 "printqd.ctr"
+ if (0 != dk4str8_cpy_s(kb, sizeof(kb), printqd_kw[kwi], NULL)) {
+ if (0 != dk4str8_cat_s(kb, sizeof(kb), cn, NULL)) {
+ if (0 != dk4str8_cat_s(kb, sizeof(kb), printqd_kw[8], NULL)) {
+ if (0 != dk4str8_cat_s(kb, sizeof(kb), un, NULL)) {
+ if ((dk4_um_t)0UL != val) {
+ if(0 != dk4ma_write_c8_decimal_unsigned(vb,sizeof(vb),val,0,NULL)) {
+ strok = 1;
+
+
+#line 4927 "printqd.ctr"
+ if (0 != dbi_set(db, kb, vb, NULL)) {
+
+#line 4928 "printqd.ctr"
+ back = 1;
+ }
+ else {
+
+#line 4931 "printqd.ctr"
+ /* ERROR: Failed to set DB entry */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 117);
+ }
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 4937 "printqd.ctr"
+ }
+#endif
+ } else {
+ strok = 1;
+
+
+#line 4942 "printqd.ctr"
+ if (0 != dbi_del(db, kb, NULL)) {
+
+#line 4943 "printqd.ctr"
+ back = 1;
+ } else {
+
+#line 4945 "printqd.ctr"
+ /* ERROR: Failed to delete DB entry */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 118);
+ }
+ }
+ }
+ }
+ }
+ }
+ if (0 == strok) {
+ /* ##### ERROR: Strings too long */
+ }
+
+
+#line 4957 "printqd.ctr"
+ return back;
+}
+
+
+
+/** Save changes in account to database.
+ @param oldacc Previous account information, may be NULL.
+ @param newacc Updated account information, not NULL.
+ @param un User name.
+ @param cl Class structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+save_account_for_user_and_class(
+ pqd_account_t *oldacc,
+ pqd_account_t *newacc,
+ const char *un,
+ pqd_class_t *cl
+)
+{
+ int mustsave; /* Flag: Must save item */
+ int back = 1;
+
+
+#line 4981 "printqd.ctr"
+ mustsave = 1;
+ if (NULL != oldacc) {
+ if (oldacc->used == newacc->used) {
+ mustsave = 0;
+ }
+ }
+ if (0 != mustsave) {
+
+#line 4988 "printqd.ctr"
+ if (0 == save_one_number(88, un, cl->name, newacc->used)) {
+ back = 0;
+ }
+ }
+ mustsave = 1;
+ if (NULL != oldacc) {
+ if (oldacc->account == newacc->account) {
+ mustsave = 0;
+ }
+ }
+ if (0 != mustsave) {
+
+#line 4999 "printqd.ctr"
+ if (0 == save_one_number(89, un, cl->name, newacc->account)) {
+ back = 0;
+ }
+ }
+
+
+#line 5004 "printqd.ctr"
+ return back;
+}
+
+
+
+/** Retrieve account data for a user in a specified printer class.
+ @param account Data structure to fill.
+ @param un User name.
+ @param cl Printer class.
+ @param mi Flag: Must initialize account before filling it.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+retrieve_account_for_user_and_class(
+ pqd_account_t *account,
+ const char *un,
+ pqd_class_t *cl,
+ int mi
+)
+{
+ char **grmem = NULL;
+ const char *ep = NULL; /* End of data */
+ pqd_limit_t *lim = NULL; /* Limit set */
+ struct passwd *pw = NULL; /* Password struct */
+ struct group *gr = NULL; /* Group struct */
+ dk4_um_t um = (dk4_um_t)0UL; /* Value found in text */
+ gid_t pg = 0; /* Primary group */
+ int ingr = 0; /* Flag: User in group */
+ int back = 0;
+
+
+#line 5035 "printqd.ctr"
+ /*
+ Check arguments
+ */
+ if (NULL == account) {
+ goto finished;
+ }
+ if (0 != mi) {
+ account_init(account);
+ }
+ if ((NULL == un) || (NULL == cl)) {
+ goto finished;
+ }
+ if (NULL == cl->name) {
+ goto finished;
+ }
+ /*
+ Use default action from class
+ */
+ account->da = cl->da;
+ /*
+ Find number of pages already printed
+ */
+ if (0 != dk4str8_cpy_s(kb, sizeof(kb), printqd_kw[88], NULL)) {
+ if (0 != dk4str8_cat_s(kb, sizeof(kb), cl->name, NULL)) {
+ if (0 != dk4str8_cat_s(kb, sizeof(kb), printqd_kw[8], NULL)) {
+ if (0 != dk4str8_cat_s(kb, sizeof(kb), un, NULL)) {
+
+
+#line 5062 "printqd.ctr"
+ if (0 != dbi_get(db, kb, vb, sizeof(vb), NULL)) {
+ if (0 != dk4ma_input_c8_dec_dk4_um_t(&um, vb, &ep, 1, NULL)) {
+ account->used = um;
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 5068 "printqd.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 5073 "printqd.ctr"
+ }
+#endif
+ }
+ }
+ }
+ }
+ /*
+ Find number of pages in personal print account
+ */
+ if (0 != dk4str8_cpy_s(kb, sizeof(kb), printqd_kw[89], NULL)) {
+ if (0 != dk4str8_cat_s(kb, sizeof(kb), cl->name, NULL)) {
+ if (0 != dk4str8_cat_s(kb, sizeof(kb), printqd_kw[8], NULL)) {
+ if (0 != dk4str8_cat_s(kb, sizeof(kb), un, NULL)) {
+
+
+#line 5087 "printqd.ctr"
+ if (0 != dbi_get(db, kb, vb, sizeof(vb), NULL)) {
+ um = (dk4_um_t)0UL; ep = NULL;
+ if (0 != dk4ma_input_c8_dec_dk4_um_t(&um, vb, &ep, 1, NULL)) {
+ account->account = um;
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 5094 "printqd.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 5099 "printqd.ctr"
+ }
+#endif
+ }
+ }
+ }
+ }
+ /*
+ Find user limit
+ */
+
+
+#line 5109 "printqd.ctr"
+ lim = (pqd_limit_t *)dk4sto_it_find_like(cl->i_u, un, 1);
+ if (NULL != lim) {
+
+#line 5111 "printqd.ctr"
+ account->limit = lim->limit;
+ back = 1;
+ goto finished;
+ }
+ /*
+ Find group limit
+ */
+
+
+#line 5119 "printqd.ctr"
+ pw = getpwnam(un);
+ if (NULL != pw) {
+
+#line 5121 "printqd.ctr"
+ pg = pw->pw_gid;
+ dk4sto_it_reset(cl->i_g);
+ do {
+
+
+#line 5125 "printqd.ctr"
+ lim = dk4sto_it_next(cl->i_g);
+ if (NULL != lim) {
+
+#line 5127 "printqd.ctr"
+ if (lim->limit > account->limit) {
+
+#line 5128 "printqd.ctr"
+
+
+#line 5129 "printqd.ctr"
+ gr = getgrnam(lim->name);
+ if (NULL != gr) {
+
+#line 5131 "printqd.ctr"
+ if (pg == gr->gr_gid) {
+
+#line 5132 "printqd.ctr"
+ account->limit = lim->limit;
+ back = 1;
+ } else {
+
+#line 5135 "printqd.ctr"
+ if (NULL != gr->gr_mem) {
+ grmem = gr->gr_mem;
+ ingr = 0;
+ while ((0 == ingr) && (NULL != *grmem)) {
+
+
+#line 5140 "printqd.ctr"
+ if (0 == strcmp(un, *grmem)) {
+ ingr = 1;
+ }
+ grmem++;
+ }
+ if (0 != ingr) {
+
+#line 5146 "printqd.ctr"
+ account->limit = lim->limit;
+ back = 1;
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 5151 "printqd.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 5156 "printqd.ctr"
+ }
+#endif
+ }
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 5162 "printqd.ctr"
+ }
+#endif
+ }
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 5168 "printqd.ctr"
+ }
+#endif
+
+
+#line 5171 "printqd.ctr"
+ } while(NULL != lim);
+ if (0 != back) {
+ goto finished;
+ }
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 5178 "printqd.ctr"
+ }
+#endif
+ /*
+ Apply default limit
+ */
+
+
+#line 5184 "printqd.ctr"
+ account->limit = cl->dl;
+ back = 1;
+
+ finished:
+
+
+#line 5189 "printqd.ctr"
+ return back;
+}
+
+
+
+/** Retrieve user account data for a given user name and a given printer
+ name.
+ @param account Account structure to fill.
+ @param printer_name Print queue name or alias.
+ @param user_name User name.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+retrieve_account_data(
+ pqd_account_t *account,
+ const char *printer_name,
+ const char *user_name
+)
+{
+ pqd_printer_t *pr = NULL; /* Printer */
+ pqd_class_t *cl = NULL; /* Class */
+ int back = 0;
+
+
+#line 5213 "printqd.ctr"
+ /*
+ Initialize account data
+ */
+ account_init(account);
+ /*
+ Find printer
+ */
+ pr = get_printer_for_name(printer_name);
+ if (NULL == pr) {
+
+#line 5222 "printqd.ctr"
+ goto finished;
+ }
+ /*
+ Find class for printer
+ */
+ cl = pr->cl;
+ if (NULL == cl) {
+
+#line 5229 "printqd.ctr"
+ goto finished;
+ }
+ if (NULL == cl->name) {
+
+#line 5232 "printqd.ctr"
+ goto finished;
+ }
+ /*
+ Search for data
+ */
+ back = retrieve_account_for_user_and_class(account, user_name, cl, 0);
+ /*
+ Return result
+ */
+ finished:
+
+
+#line 5243 "printqd.ctr"
+ return back;
+}
+
+
+
+/** Add a number of pages for a print job to existing account data.
+ @param account Account data for user.
+ @param pages Number of pages used by print job.
+*/
+static
+void
+account_add_pages_from_job(pqd_account_t *account, dk4_um_t pages)
+{
+ dk4_um_t available;
+
+ /* The limit is used first.
+ */
+ if (account->limit > account->used) {
+ available = account->limit - account->used;
+ if (available >= pages) {
+ account->used += pages;
+ pages = (dk4_um_t)0UL;
+ } else {
+ account->used = account->limit;
+ pages -= available;
+ }
+ }
+ /* The personal print account is used only if the limit is reached.
+ */
+ if ((dk4_um_t)0UL < pages) {
+ if (account->account >= pages) {
+ account->account -= pages;
+ } else {
+ pages -= account->account;
+ account->account = (dk4_um_t)0UL;
+ }
+ }
+ /* Finally keep track of pages printed over limit.
+ */
+ if ((dk4_um_t)0UL < pages) {
+ if ((DK4_UM_MAX - pages) >= account->used) {
+ account->used += pages;
+ } else {
+ account->used = DK4_UM_MAX;
+ }
+ }
+}
+
+
+
+/** Find summary (allowed to print) for account details.
+ @param limit Limit (maximum number of pages) for user.
+ @param used Number of used pages within the limit.
+ @param account Number of pages in additional personal print account.
+ @return 1 if printing is allowed, 0 otherwise.
+*/
+static
+int
+account_summary(dk4_um_t limit, dk4_um_t used, dk4_um_t account)
+{
+ int back = 0;
+
+
+#line 5305 "printqd.ctr"
+ if (DK4_UM_MAX == limit) {
+
+#line 5306 "printqd.ctr"
+ back = 1;
+ } else {
+ if (used < limit) {
+
+#line 5309 "printqd.ctr"
+ back = 1;
+ } else {
+ if ((dk4_um_t)0UL < account) {
+
+#line 5312 "printqd.ctr"
+ back = 1;
+ }
+ }
+ }
+
+
+#line 5317 "printqd.ctr"
+ return back;
+}
+
+
+/** Process info or acct-check request, only retrieve data
+ without modifying anything.
+ @param job Data for one request to process.
+ @param how Response type: 0=info, 1=acct-check.
+*/
+static
+void
+rq_retrieve_data(pqd_rq_t *job, int how)
+{
+ pqd_account_t account;
+ char *printer_name = NULL;
+ char *user_name = NULL;
+ int summary = 0;
+
+
+#line 5335 "printqd.ctr"
+ printer_name = job->argptr;
+ if (NULL != printer_name) {
+ user_name = dk4str8_next(printer_name, NULL);
+ if (NULL != user_name) {
+ (void)dk4str8_next(user_name, NULL);
+ }
+ }
+ if ((NULL != printer_name) && (NULL != user_name)) {
+ if (0 != retrieve_account_data(&account, printer_name, user_name)) {
+#if VERSION_BEFORE_20160329
+ if ((account.used < account.limit) || ((dk4_um_t)0UL < account.account)) {
+ summary = 1;
+ }
+#else
+ summary = account_summary(account.limit, account.used, account.account);
+#endif
+ }
+ send_response(job, &account, summary, how);
+ } else {
+ /* Close connection on malformed request.
+ */
+ if ((NULL == job->soa) && (0 == job->szsoa)) {
+ close_stream_conn(job->sock, job->sto, job->connptr, job->pnconn);
+ }
+ }
+
+
+#line 5361 "printqd.ctr"
+}
+
+
+
+/** Process info request.
+ @param job Data for one request to process.
+*/
+static
+void
+rq_info(pqd_rq_t *job)
+{
+
+
+#line 5373 "printqd.ctr"
+ rq_retrieve_data(job, 0);
+
+
+#line 5375 "printqd.ctr"
+}
+
+
+
+/** Find final quote for current word.
+ @param str String to find quote in.
+ @param quote Quote character.
+ @return Pointer to found quote on success, NULL on error.
+*/
+static
+char *
+lprng_final_quote(char *str, char quote)
+{
+ char *back = NULL;
+
+
+#line 5390 "printqd.ctr"
+ while (('\0' != *str) && (NULL == back)) {
+ if (quote == *str) {
+ *str = '\0';
+ back = str;
+ back++;
+ back = dk4str8_start(back, NULL);
+ } else {
+ if ('\\' == *str) {
+ if ('\0' != str[1]) {
+ dk4str8_cpy_to_left(str, &(str[1]));
+ str++;
+ } else {
+ *str = '\0';
+ }
+ } else {
+ str++;
+ }
+ }
+ }
+
+
+#line 5410 "printqd.ctr"
+ return back;
+}
+
+
+
+/** Find start of next text word in LPRng accounting line.
+ @param str Current word (remaining text) in accounting line.
+ @return Pointer to next word if found, NULL on error.
+*/
+static
+char *
+lprng_next_word(char *str)
+{
+ char *back = NULL;
+
+
+#line 5425 "printqd.ctr"
+ switch (*str) {
+ case '\'' : {
+ back = lprng_final_quote(&(str[1]), '\'');
+ } break;
+ case '"' : {
+ back = lprng_final_quote(&(str[1]), '"');
+ } break;
+ default : {
+ back = dk4str8_next(str, NULL);
+ } break;
+ }
+
+#line 5436 "printqd.ctr"
+ return back;
+}
+
+
+
+/** Fill data structure from LPRng accounting line.
+ @param liptr Structure to fill.
+ @param textline The text line to use.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+lprng_info_from_line(lprng_info_t *liptr, char *textline)
+{
+ char *next;
+ int back = 1;
+
+
+#line 5453 "printqd.ctr"
+ DK4_MEMRES(liptr, sizeof(lprng_info_t));
+ liptr->username = NULL; liptr->queuename = NULL;
+ liptr->jobtitle = NULL; liptr->pagecount = NULL;
+ while (NULL != textline) {
+ next = lprng_next_word(textline);
+ if (('\'' == *textline) || ('"' == *textline)) {
+ textline++;
+ }
+ if ('-' == *textline) {
+ textline++;
+ switch (*textline) {
+ case 'n': {
+ liptr->username = ++textline;
+ } break;
+ case 'P': {
+ liptr->queuename = ++textline;
+ } break;
+ case 'J': {
+ liptr->jobtitle = ++textline;
+ } break;
+ case 'p': {
+ liptr->pagecount = ++textline;
+ } break;
+ }
+ } else {
+
+#line 5478 "printqd.ctr"
+#if 0
+ /* 2016-02-15 Simply ignore non-option text.
+ */
+ back = 0;
+ /* ERROR: No minus sign */
+#endif
+ }
+ textline = next;
+ }
+
+
+#line 5488 "printqd.ctr"
+ return back;
+}
+
+
+
+/** Process jobstart request.
+ @param job Data for one request to process.
+*/
+static
+void
+rq_jobstart(pqd_rq_t *job)
+{
+ lprng_info_t lpi;
+ pqd_account_t account;
+ char *un = NULL;
+ char *qn = NULL;
+ int summ = 0;
+
+
+#line 5506 "printqd.ctr"
+ if (0 != lprng_info_from_line(&lpi, job->argptr)) {
+ un = lpi.username; qn = lpi.queuename;
+ }
+ if ((NULL != un) && (NULL != qn)) {
+ if (0 != retrieve_account_data(&account, qn, un)) {
+ summ = account_summary(account.limit, account.used, account.account);
+ }
+ send_response(job, &account, summ, 1);
+ } else {
+ /* Close connection on malformed request.
+ */
+ if ((NULL == job->soa) && (0 == job->szsoa)) {
+ close_stream_conn(job->sock, job->sto, job->connptr, job->pnconn);
+ }
+ }
+
+
+#line 5522 "printqd.ctr"
+}
+
+
+
+/** Report change result to log file.
+ @param un User name.
+ @param cl Class.
+ @param olda Old account values.
+ @param newa New account values.
+ @param pages Number of pages to add.
+ @param doadd Flag: Show added pages instead of used pages.
+*/
+static
+void
+log_old_and_new_account(
+ const char *un,
+ const pqd_class_t *cl,
+ const pqd_account_t *olda,
+ const pqd_account_t *newa,
+ dk4_um_t pages,
+ int doadd
+)
+{
+ char nb[8*sizeof(dk4_um_t)];
+ const char *msgs[2];
+ int res = 1;
+ if (0 == dk4str8_cpy_s(kb, sizeof(kb), un, NULL)) { res = 0; }
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), printqd_kw[85], NULL)) { res = 0; }
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), cl->name, NULL)) { res = 0; }
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), printqd_kw[7], NULL)) { res = 0; }
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), printqd_kw[145], NULL)) { res = 0; }
+ if (DK4_UM_MAX == olda->limit) {
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), printqd_kw[151], NULL)) { res = 0; }
+ } else {
+ if(0 != dk4ma_write_c8_decimal_unsigned(nb,sizeof(nb),olda->limit,0,NULL)) {
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), nb, NULL)) { res = 0; }
+ } else {
+ res = 0;
+ }
+ }
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), printqd_kw[146], NULL)) { res = 0; }
+ if(0 != dk4ma_write_c8_decimal_unsigned(nb,sizeof(nb),olda->used,0,NULL)) {
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), nb, NULL)) { res = 0; }
+ } else {
+ res = 0;
+ }
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), printqd_kw[147], NULL)) { res = 0; }
+ if(0 != dk4ma_write_c8_decimal_unsigned(nb,sizeof(nb),olda->account,0,NULL)) {
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), nb, NULL)) { res = 0; }
+ } else {
+ res = 0;
+ }
+ switch (doadd) {
+ case 1: {
+ if (0 == dk4str8_cat_s(kb,sizeof(kb),printqd_kw[153],NULL)) { res = 0; }
+ } break;
+ default: {
+ if (0 == dk4str8_cat_s(kb,sizeof(kb),printqd_kw[148],NULL)) { res = 0; }
+ } break;
+ }
+ if(0 != dk4ma_write_c8_decimal_unsigned(nb,sizeof(nb),pages,0,NULL)) {
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), nb, NULL)) { res = 0; }
+ } else {
+ res = 0;
+ }
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), printqd_kw[149], NULL)) { res = 0; }
+ if (DK4_UM_MAX == newa->limit) {
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), printqd_kw[151], NULL)) { res = 0; }
+ } else {
+ if(0 != dk4ma_write_c8_decimal_unsigned(nb,sizeof(nb),newa->limit,0,NULL)) {
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), nb, NULL)) { res = 0; }
+ } else {
+ res = 0;
+ }
+ }
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), printqd_kw[146], NULL)) { res = 0; }
+ if(0 != dk4ma_write_c8_decimal_unsigned(nb,sizeof(nb),newa->used,0,NULL)) {
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), nb, NULL)) { res = 0; }
+ } else {
+ res = 0;
+ }
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), printqd_kw[147], NULL)) { res = 0; }
+ if(0 != dk4ma_write_c8_decimal_unsigned(nb,sizeof(nb),newa->account,0,NULL)) {
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), nb, NULL)) { res = 0; }
+ } else {
+ res = 0;
+ }
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), printqd_kw[150], NULL)) { res = 0; }
+ if (0 != res) {
+ msgs[0] = kb;
+ msgs[1] = NULL;
+ log_multipart_message(NULL, 0UL, LOG_EMERG, 0, msgs, 1);
+ }
+}
+
+
+
+/** Charge user for a print job.
+ @param job Job structure.
+ @param un User name.
+ @param cl Printer class of printer the job was printed on.
+ @param pcval Number of pages in print job.
+*/
+static
+void
+do_charge(
+ pqd_rq_t *job,
+ const char *un,
+ pqd_class_t *cl,
+ dk4_um_t pcval
+)
+{
+ pqd_account_t oldacc;
+ pqd_account_t newacc;
+
+
+#line 5637 "printqd.ctr"
+ if (0 != retrieve_account_for_user_and_class(&oldacc, un, cl, 1)) {
+ DK4_MEMCPY(&newacc, &oldacc, sizeof(pqd_account_t));
+ account_add_pages_from_job(&newacc, pcval);
+ log_old_and_new_account(un, cl, &oldacc, &newacc, pcval, 0);
+ if (0 == save_account_for_user_and_class(&oldacc, &newacc, un, cl)) {
+
+
+#line 5643 "printqd.ctr"
+ /* ERROR: Failed to update account data */
+ log_5(NULL, 0UL, LOG_EMERG, 1, 156, 157, 158, un, cl->name);
+ }
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 5649 "printqd.ctr"
+ }
+#endif
+
+
+#line 5652 "printqd.ctr"
+}
+
+
+
+/** On start of file printing save user name, job name and pagecount
+ value to database for later use.
+ @param job Job structure.
+ @param un User name.
+ @param pn Printer name.
+ @param jn Job name.
+ @param pc Printer page count at start of job.
+*/
+static
+void
+do_filestart(
+ pqd_rq_t *job,
+ const char *un,
+ const char *pn,
+ const char *jn,
+ const char *pc
+)
+{
+ const char *ep = NULL;
+ pqd_printer_t *pr = NULL;
+ pqd_class_t *cl = NULL;
+ dk4_um_t pcstt = (dk4_um_t)0UL;
+ int res = 0;
+
+
+#line 5680 "printqd.ctr"
+ pr = get_printer_for_name(pn);
+ if (NULL != pr) {
+ cl = pr->cl;
+ }
+ if (NULL != cl) {
+ res = dk4ma_input_c8_dec_dk4_um_t(&pcstt, pc, &ep, 1, NULL);
+ }
+ if ((NULL != pr) && (NULL != cl) && (0 != res)) {
+
+
+#line 5689 "printqd.ctr"
+ if (0 == dk4str8_cpy_s(kb, sizeof(kb), printqd_kw[90], NULL)) { res = 0; }
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), pr->name, NULL)) { res = 0; }
+ if (0 == dk4str8_cpy_s(vb, sizeof(vb), pc, NULL)) { res = 0; }
+ if (0 == dk4str8_cat_s(vb, sizeof(vb), printqd_kw[8], NULL)) { res = 0; }
+ if (0 == dk4str8_cat_s(vb, sizeof(vb), un, NULL)) { res = 0; }
+ if (0 == dk4str8_cat_s(vb, sizeof(vb), printqd_kw[8], NULL)) { res = 0; }
+ if (0 == dk4str8_cat_s(vb, sizeof(vb), jn, NULL)) { res = 0; }
+ if (0 != res) {
+
+#line 5697 "printqd.ctr"
+ if (0 == dbi_set(db, kb, vb, NULL)) {
+
+#line 5698 "printqd.ctr"
+ /* ERROR: Failed to set database entry */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 117);
+ }
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 5704 "printqd.ctr"
+ }
+#endif
+ } else {
+
+#line 5707 "printqd.ctr"
+ /* Close connection on malformed request
+ */
+ if ((NULL == job->soa) && (0 == job->szsoa)) {
+ close_stream_conn(job->sock, job->sto, job->connptr, job->pnconn);
+ }
+ }
+
+
+#line 5714 "printqd.ctr"
+}
+
+
+
+/** On end of file calculate page number used by the job and
+ save modified account to database.
+ @param job Job structure.
+ @param un User name.
+ @param pn Printer name.
+ @param jn Job name.
+ @param pc Printer page count at start of job.
+*/
+static
+void
+do_fileend(
+ pqd_rq_t *job,
+ const char *un,
+ const char *pn,
+ const char *jn,
+ const char *pc
+)
+{
+ const char *ep = NULL; /* End of processed text */
+ pqd_printer_t *pr = NULL; /* Printer */
+ pqd_class_t *cl = NULL; /* Printer class */
+ char *oun = NULL; /* Old user name */
+ char *opc = NULL; /* Old page counter value */
+ char *ojn = NULL; /* Old job name */
+ dk4_um_t pcstt = (dk4_um_t)0UL; /* Page counter at job start */
+ dk4_um_t pcend = (dk4_um_t)0UL; /* Page counter at job end */
+ int res = 0;
+
+
+
+#line 5747 "printqd.ctr"
+ pr = get_printer_for_name(pn);
+ if (NULL != pr) {
+ cl = pr->cl;
+ }
+ if (NULL != cl) {
+ res = dk4ma_input_c8_dec_dk4_um_t(&pcend, pc, &ep, 1, NULL);
+ }
+ if ((NULL != pr) && (NULL != cl) && (0 != res)) {
+ if (0 == dk4str8_cpy_s(kb, sizeof(kb), printqd_kw[90], NULL)) { res = 0; }
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), pr->name, NULL)) { res = 0; }
+ if (0 != res) {
+
+#line 5758 "printqd.ctr"
+ if (0 != dbi_get(db, kb, vb, sizeof(vb), NULL)) {
+
+
+#line 5760 "printqd.ctr"
+ if (0 == dbi_del(db, kb, NULL)) {
+ /* ERROR: Failed to delete db entry */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 118);
+ }
+
+
+#line 5765 "printqd.ctr"
+ opc = dk4str8_start(vb, NULL);
+ if (NULL != opc) {
+ oun = dk4str8_chr(opc, ':');
+ if (NULL != oun) {
+ *(oun++) = '\0';
+ oun = dk4str8_start(oun, NULL);
+ }
+ }
+ if (NULL != oun) {
+ ojn = dk4str8_chr(oun, ':');
+ if (NULL != ojn) {
+ *(ojn++) = '\0';
+ ojn = dk4str8_start(ojn, NULL);
+ }
+ }
+ if ((NULL != opc) && (NULL != oun) && (NULL != ojn)) {
+
+
+#line 5782 "printqd.ctr"
+
+
+#line 5783 "printqd.ctr"
+
+
+#line 5784 "printqd.ctr"
+ if (0 == strcmp(ojn, jn)) {
+ if (0 == strcmp(oun, un)) {
+ ep = NULL;
+ res = dk4ma_input_c8_dec_dk4_um_t(&pcstt, opc, &ep, 1, NULL);
+ if (0 != res) {
+ if (pcend > pcstt) {
+
+#line 5790 "printqd.ctr"
+ do_charge(job, un, cl, (pcend - pcstt));
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 5794 "printqd.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 5799 "printqd.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 5804 "printqd.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 5809 "printqd.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 5814 "printqd.ctr"
+ }
+#endif
+ }
+ else {
+
+#line 5818 "printqd.ctr"
+
+
+#line 5819 "printqd.ctr"
+ if (0 == dbi_del(db, kb, NULL)) {
+ /* ERROR: Failed to delete db entry */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 118);
+ }
+ }
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 5827 "printqd.ctr"
+ }
+#endif
+ } else {
+
+#line 5830 "printqd.ctr"
+ /* Close connection on malformed request
+ */
+ if ((NULL == job->soa) && (0 == job->szsoa)) {
+ close_stream_conn(job->sock, job->sto, job->connptr, job->pnconn);
+ }
+ }
+
+
+#line 5837 "printqd.ctr"
+}
+
+
+
+/** Process filestart request.
+ @param job Data for one request to process.
+*/
+static
+void
+rq_filestart(pqd_rq_t *job)
+{
+ lprng_info_t lpi;
+ char *un = NULL;
+ char *pn = NULL;
+ char *jn = NULL;
+ char *pc = NULL;
+
+
+#line 5854 "printqd.ctr"
+ if (0 != lprng_info_from_line(&lpi, job->argptr)) {
+ un = lpi.username; pn = lpi.queuename;
+ jn = lpi.jobtitle; pc = lpi.pagecount;
+ }
+ if ((NULL != un) && (NULL != pn) && (NULL != jn) && (NULL != pc)) {
+ do_filestart(job, un, pn, jn, pc);
+ } else {
+ /* Close connection on malformed request
+ */
+ if ((NULL == job->soa) && (0 == job->szsoa)) {
+ close_stream_conn(job->sock, job->sto, job->connptr, job->pnconn);
+ }
+ }
+
+
+#line 5868 "printqd.ctr"
+}
+
+
+
+/** Process fileend request.
+ @param job Data for one request to process.
+*/
+static
+void
+rq_fileend(pqd_rq_t *job)
+{
+ lprng_info_t lpi;
+ char *un = NULL;
+ char *pn = NULL;
+ char *jn = NULL;
+ char *pc = NULL;
+
+
+#line 5885 "printqd.ctr"
+ if (0 != lprng_info_from_line(&lpi, job->argptr)) {
+ un = lpi.username; pn = lpi.queuename;
+ jn = lpi.jobtitle; pc = lpi.pagecount;
+ }
+ if ((NULL != un) && (NULL != pn) && (NULL != jn) && (NULL != pc)) {
+ do_fileend(job, un, pn, jn, pc);
+ } else {
+ /* Close connection on malformed request
+ */
+ if ((NULL == job->soa) && (0 == job->szsoa)) {
+ close_stream_conn(job->sock, job->sto, job->connptr, job->pnconn);
+ }
+ }
+
+
+#line 5899 "printqd.ctr"
+}
+
+
+
+/** Process acct-check request.
+ @param job Data for one request to process.
+*/
+static
+void
+rq_acct_check(pqd_rq_t *job)
+{
+
+
+#line 5911 "printqd.ctr"
+ rq_retrieve_data(job, 1);
+
+
+#line 5913 "printqd.ctr"
+}
+
+
+
+/** Process acct-start request.
+ @param job Data for one request to process.
+*/
+static
+void
+rq_acct_start(pqd_rq_t *job)
+{
+ char *un = NULL;
+ char *pn = NULL;
+ char *jn = NULL;
+ char *pc = NULL;
+
+
+#line 5929 "printqd.ctr"
+ pn = job->argptr;
+ if (NULL != pn) {
+ un = dk4str8_next(pn, NULL);
+ }
+ if (NULL != un) {
+ pc = dk4str8_next(un, NULL);
+ }
+ if (NULL != pc) {
+ jn = dk4str8_next(pc, NULL);
+ }
+ if (NULL != jn) {
+ (void)dk4str8_next(jn, NULL);
+ }
+ if ((NULL != un) && (NULL != pn) && (NULL != jn) && (NULL != pc)) {
+ do_filestart(job, un, pn, jn, pc);
+ } else {
+ /* Close connection on malformed request
+ */
+ if ((NULL == job->soa) && (0 == job->szsoa)) {
+ close_stream_conn(job->sock, job->sto, job->connptr, job->pnconn);
+ }
+ }
+
+
+#line 5952 "printqd.ctr"
+}
+
+
+
+/** Process acct-end request.
+ @param job Data for one request to process.
+*/
+static
+void
+rq_acct_end(pqd_rq_t *job)
+{
+ char *un = NULL;
+ char *pn = NULL;
+ char *jn = NULL;
+ char *pc = NULL;
+
+
+#line 5968 "printqd.ctr"
+ pn = job->argptr;
+ if (NULL != pn) {
+ un = dk4str8_next(pn, NULL);
+ }
+ if (NULL != un) {
+ pc = dk4str8_next(un, NULL);
+ }
+ if (NULL != pc) {
+ jn = dk4str8_next(pc, NULL);
+ }
+ if (NULL != jn) {
+ (void)dk4str8_next(jn, NULL);
+ }
+ if ((NULL != un) && (NULL != pn) && (NULL != jn) && (NULL != pc)) {
+ do_fileend(job, un, pn, jn, pc);
+ } else {
+ /* Close connection on malformed request
+ */
+ if ((NULL == job->soa) && (0 == job->szsoa)) {
+ close_stream_conn(job->sock, job->sto, job->connptr, job->pnconn);
+ }
+ }
+
+
+#line 5991 "printqd.ctr"
+}
+
+
+
+/** Process acct-charge request.
+ @param job Data for one request to process.
+*/
+static
+void
+rq_acct_charge(pqd_rq_t *job)
+{
+ const char *ep = NULL;
+ pqd_printer_t *pr = NULL;
+ pqd_class_t *cl = NULL;
+ char *un = NULL;
+ char *pn = NULL;
+ char *pc = NULL;
+ dk4_um_t pcval = (dk4_um_t)0UL;
+
+
+#line 6010 "printqd.ctr"
+ pn = job->argptr;
+ if (NULL != pn) {
+ un = dk4str8_next(pn, NULL);
+ }
+ if (NULL != un) {
+ pc = dk4str8_next(un, NULL);
+ }
+ if (NULL != pc) {
+ (void)dk4str8_next(pc, NULL);
+ }
+ if (NULL != pn) {
+ pr = get_printer_for_name(pn);
+ }
+ if (NULL != pr) {
+ cl = pr->cl;
+ }
+ if (
+ (NULL != un) && (NULL != pn) && (NULL != pc) && (NULL != pr) && (NULL != cl)
+ )
+ {
+ if (0 != dk4ma_input_c8_dec_dk4_um_t(&pcval, pc, &ep, 1, NULL)) {
+ do_charge(job, un, cl, pcval);
+ } else {
+ /* Close connection on malformed request
+ */
+ if ((NULL == job->soa) && (0 == job->szsoa)) {
+ close_stream_conn(job->sock, job->sto, job->connptr, job->pnconn);
+ }
+ }
+ } else {
+ /* Close connection on malformed request
+ */
+ if ((NULL == job->soa) && (0 == job->szsoa)) {
+ close_stream_conn(job->sock, job->sto, job->connptr, job->pnconn);
+ }
+ }
+
+
+#line 6047 "printqd.ctr"
+}
+
+
+
+/** Object for DB traversal in control requests.
+*/
+typedef struct {
+ dk4_sto_t *s; /**< Key name storage. */
+ dk4_sto_it_t *i; /**< Key name storage iterator. */
+ char *cn; /**< Class name. */
+ char *un; /**< User name. */
+} pqd_control_t;
+
+
+
+/** Comparison function for storage.
+ @param l Left object.
+ @param r Right object.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+static
+int
+db_entry_compare(const void *l, const void *r, int cr)
+{
+ int back = 0;
+ if (NULL != l) {
+ if (NULL != r) {
+ back = strcmp((const char *)l, (const char *)r);
+ if (-1 > back) back = -1;
+ if ( 1 < back) back = 1;
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != r) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Traverse simple database containing text.
+ @param obj Object to modify during traversal.
+ @param k Key text.
+ @param v Value text.
+ @return 1 on success, 0 on error (continue traversal),
+ -1 on error (abort).
+*/
+static
+int
+rq_c_reset_traverse(void *obj, const char *k, const char *v)
+{
+ pqd_control_t *ctoptr = NULL; /* Traversal object pointer */
+ char *p1 = NULL; /* DB entry type */
+ char *p2 = NULL; /* Class name */
+ char *p3 = NULL; /* User name */
+ int clm = 0; /* Flag: Class name matches */
+ int unm = 0; /* Flag: User name matches */
+ int back = 1;
+
+
+#line 6110 "printqd.ctr"
+ ctoptr = (pqd_control_t *)obj;
+ if (0 != dk4str8_cpy_s(kb, sizeof(kb), k, NULL)) {
+ p1 = dk4str8_start(kb, NULL);
+ if (NULL != p1) {
+ p2 = strchr(p1, ':');
+ if (NULL != p2) {
+ *(p2++) = '\0';
+ p2 = dk4str8_start(p2, NULL);
+ }
+ if (NULL != p2) {
+ if (0 == strcmp(p1, printqd_kw[152])) {
+ p3 = strchr(p2, ':');
+ if (NULL != p3) {
+ *(p3++) = '\0';
+ p3 = dk4str8_start(p3, NULL);
+ }
+ if (NULL != p3) {
+ if (NULL != ctoptr->cn) {
+ if (0 == strcmp(ctoptr->cn, p2)) {
+ clm = 1;
+ }
+ } else {
+ clm = 1;
+ }
+ if (0 != clm) {
+ if (NULL != ctoptr->un) {
+ if (0 == strcmp(ctoptr->un, p3)) {
+ unm = 1;
+ }
+ } else {
+ unm = 1;
+ }
+ if (0 != unm) {
+ p1 = dk4str8_dup(k, NULL);
+ if (NULL != p1) {
+ if (0 == dk4sto_add(ctoptr->s, p1, NULL)) {
+ dk4mem_free(p1);
+
+#line 6147 "printqd.ctr"
+ }
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 6151 "printqd.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 6156 "printqd.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 6161 "printqd.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 6166 "printqd.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 6171 "printqd.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 6176 "printqd.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 6181 "printqd.ctr"
+ }
+#endif
+ }
+ if (0 == can_continue(0, 0)) { back = -1; }
+
+
+#line 6186 "printqd.ctr"
+ return back;
+}
+
+
+
+/** Traverse simple database containing text.
+ @param obj Object to modify during traversal.
+ @param k Key text.
+ @param v Value text.
+ @return 1 on success, 0 on error (continue traversal),
+ -1 on error (abort).
+*/
+static
+int
+rc_c_dbcl_traverse(void *obj, const char *k, const char *v)
+{
+ pqd_control_t *pctobj;
+ pqd_class_t *cl;
+ char *p1; /* First argument */
+ char *p2; /* Second argument */
+ int cdel = 0; /* Flag: Can delete item */
+ int back = 1;
+
+ if (0 != dk4str8_cpy_s(kb, sizeof(kb), k, NULL)) {
+ if (0 != dk4str8_cpy_s(vb, sizeof(vb), k, NULL)) {
+ p1 = strchr(kb, ':');
+ if (NULL != p1) {
+ *(p1++) = '\0';
+ p1 = dk4str8_start(p1, NULL);
+ dk4str8_normalize(kb, NULL);
+ if (NULL != p1) {
+ pctobj = (pqd_control_t *)obj;
+ switch ( dk4str8_array_index(db_type_names, kb, 0) ) {
+ case 0 : /* p:class:user */
+ case 1 : /* a:class:user */
+ {
+ p2 = strchr(p1, ':');
+ if (NULL != p2) {
+ *(p2++) = '\0';
+ p2 = dk4str8_start(p2, NULL);
+ if (NULL != p2) {
+ dk4str8_normalize(p1, NULL);
+ dk4str8_normalize(p2, NULL);
+ cl = dk4sto_it_find_like(conf.i_c, p1, 1);
+ if (NULL != cl) {
+ if (NULL == dk4sto_it_find_like(cl->i_u, p2, 1)) {
+ if (NULL == getpwnam(p2)) {
+ cdel = 1;
+ }
+ }
+ } else {
+ cdel = 1;
+ }
+ if (0 != cdel) {
+ p1 = dk4str8_dup(vb, NULL);
+ if (NULL != p1) {
+ if (0 == dk4sto_add(pctobj->s, p1, NULL)) {
+ dk4mem_free(p1);
+ back = 0;
+ }
+ } else {
+ back = 0;
+ }
+ }
+ }
+ }
+ } break;
+ case 2 : { /* j:printer */
+ dk4str8_normalize(p1, NULL);
+ if (NULL == get_printer_for_name(p1)) {
+ p1 = dk4str8_dup(vb, NULL);
+ if (NULL != p1) {
+ if (0 == dk4sto_add(pctobj->s, p1, NULL)) {
+ dk4mem_free(p1);
+ back = 0;
+ }
+ } else {
+ back = 0;
+ }
+ }
+ } break;
+ }
+ }
+ }
+ }
+ }
+ if (0 == can_continue(0, 0)) { back = -1; }
+ return back;
+}
+
+
+
+/** Process control reset request.
+ @param job Arguments for request.
+*/
+static
+void
+rq_c_reset(pqd_rq_t *job)
+{
+ pqd_control_t ctobj;
+ char *pc;
+ char *pn;
+ char *pv;
+
+
+#line 6290 "printqd.ctr"
+ /* Initialize variable
+ */
+ ctobj.s = NULL;
+ ctobj.i = NULL;
+ ctobj.cn = NULL;
+ ctobj.un = NULL;
+ /* Process command arguments
+ */
+ pc = job->argptr;
+ while (NULL != pc) {
+ pn = dk4str8_next(pc, NULL);
+
+
+#line 6302 "printqd.ctr"
+ pv = dk4str8_chr(pc, '=');
+ if (NULL != pv) {
+ *(pv++) = '\0';
+ pv = dk4str8_start(pv, NULL);
+ }
+
+
+#line 6308 "printqd.ctr"
+ if (NULL != pv) {
+ switch ( dk4str8_abbr_index(control_arg_names, '$', pc, 0) ) {
+ case 0 : {
+ ctobj.cn = pv;
+ } break;
+ case 1 : {
+ ctobj.un = pv;
+ } break;
+ default : {
+
+
+#line 6318 "printqd.ctr"
+ } break;
+ }
+ }
+ pc = pn;
+ }
+
+
+#line 6324 "printqd.ctr"
+ if (NULL != ctobj.cn) {
+ if (0 == dk4str8_cmp(printqd_kw[2], ctobj.cn)) { ctobj.cn = NULL; }
+ }
+ if (NULL != ctobj.un) {
+ if (0 == dk4str8_cmp(printqd_kw[2], ctobj.un)) { ctobj.un = NULL; }
+ }
+ ctobj.s = dk4sto_open(NULL);
+ if (NULL != ctobj.s) {
+
+#line 6332 "printqd.ctr"
+ dk4sto_set_comp(ctobj.s, db_entry_compare, 0);
+ ctobj.i = dk4sto_it_open(ctobj.s, NULL);
+ if (NULL != ctobj.i) {
+
+#line 6335 "printqd.ctr"
+ (void)dk4dbi_c8_traverse(db, (void *)(&ctobj), rq_c_reset_traverse);
+
+
+#line 6337 "printqd.ctr"
+ dk4sto_it_reset(ctobj.i);
+ do {
+ pc = (char *)dk4sto_it_next(ctobj.i);
+ if (NULL != pc) {
+
+#line 6341 "printqd.ctr"
+ if (0 != can_continue(0, 0)) {
+ (void)dbi_del(db, pc, NULL);
+ }
+ dk4mem_free(pc);
+ }
+ } while (NULL != pc);
+ dk4sto_it_close(ctobj.i);
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 6351 "printqd.ctr"
+ }
+#endif
+ dk4sto_close(ctobj.s);
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 6357 "printqd.ctr"
+ }
+#endif
+
+
+#line 6360 "printqd.ctr"
+}
+
+
+
+/** Process control add request.
+ @param job Arguments for request.
+*/
+static
+void
+rq_c_add(pqd_rq_t *job)
+{
+ pqd_account_t oldacc;
+ pqd_account_t newacc;
+ pqd_class_t *cl = NULL;
+ const char *ep = NULL;
+ char *clname = NULL;
+ char *uname = NULL;
+ char *ptext = NULL;
+ char *pc;
+ char *pn;
+ char *pv;
+ dk4_um_t pages = (dk4_um_t)0UL;
+
+ /* Process command arguments
+ */
+ pc = job->argptr;
+ while (NULL != pc) {
+ pn = dk4str8_next(pc, NULL);
+ pv = dk4str8_chr(pc, '=');
+ if (NULL != pv) {
+ *(pv++) = '\0';
+ pv = dk4str8_start(pv, NULL);
+ }
+ if (NULL != pv) {
+ switch ( dk4str8_abbr_index(control_arg_names, '$', pc, 0) ) {
+ case 0 : {
+ clname = pv;
+ } break;
+ case 1 : {
+ uname = pv;
+ } break;
+ case 2 : {
+ ptext = pv;
+ } break;
+ }
+ }
+ pc = pn;
+ }
+ if ((NULL != clname) && (NULL != uname) && (NULL != ptext)) {
+ if (0 != dk4ma_input_c8_dec_dk4_um_t(&pages, ptext, &ep, 1, NULL)) {
+ cl = dk4sto_it_find_like(conf.i_c, clname, 1);
+ if (NULL != cl) {
+ if (0 != retrieve_account_for_user_and_class(&oldacc, uname, cl, 1)) {
+ DK4_MEMCPY(&newacc, &oldacc, sizeof(pqd_account_t));
+ if ((DK4_UM_MAX - pages) >= newacc.account) {
+ newacc.account += pages;
+ } else {
+ newacc.account = DK4_UM_MAX;
+ }
+ log_old_and_new_account(uname, cl, &oldacc, &newacc, pages, 1);
+ if (0 == save_account_for_user_and_class(&oldacc,&newacc,uname,cl)) {
+ /* ERROR: Failed to save new account */
+ log_5(NULL, 0UL, LOG_EMERG, 1, 156, 157, 158, uname, cl->name);
+ }
+ } else {
+ /* ERROR: Failed to retrieve account data */
+ log_5(NULL, 0UL, LOG_EMERG, 1, 161, 162, 163, uname, cl->name);
+ }
+ } else {
+ /* ERROR: No such class */
+ log_3(NULL, 0UL, LOG_EMERG, 1, 164, 165, clname);
+ }
+ } else {
+ /* ERROR: ptext not numeric */
+ log_3(NULL, 0UL, LOG_EMERG, 1, 166, 167, ptext);
+ }
+ }
+}
+
+
+
+/** Process control database-cleanup request.
+ @param job Arguments for request.
+*/
+static
+void
+rq_c_dbcl(pqd_rq_t *job)
+{
+ pqd_control_t ctobj;
+ char *ptr;
+
+ DK4_MEMRES(&ctobj, sizeof(pqd_control_t));
+ ctobj.s = NULL;
+ ctobj.i = NULL;
+ ctobj.cn = NULL;
+ ctobj.un = NULL;
+
+ ctobj.s = dk4sto_open(NULL);
+ if (NULL != ctobj.s) {
+ dk4sto_set_comp(ctobj.s, db_entry_compare, 0);
+ ctobj.i = dk4sto_it_open(ctobj.s, NULL);
+ if (NULL != ctobj.i) {
+ (void)dk4dbi_c8_traverse(db, (void *)(&ctobj), rc_c_dbcl_traverse);
+ dk4sto_it_reset(ctobj.i);
+ do {
+ ptr = (char *)dk4sto_it_next(ctobj.i);
+ if (NULL != ptr) {
+ if (0 != can_continue(0, 0)) {
+ dbi_del(db, ptr, NULL);
+ }
+ dk4mem_free(ptr);
+ }
+ } while(NULL != ptr);
+ dk4sto_it_close(ctobj.i);
+ }
+ dk4sto_close(ctobj.s);
+ }
+}
+
+
+
+/** Process control request.
+ @param job Data for one request to process.
+*/
+static
+void
+rq_control(pqd_rq_t *job)
+{
+ char *subcmd;
+ int sc;
+
+
+#line 6491 "printqd.ctr"
+ subcmd = job->argptr;
+ job->argptr = dk4str8_next(subcmd, NULL);
+
+
+#line 6494 "printqd.ctr"
+ switch ( (sc = dk4str8_abbr_index(control_sub_cmds, '$', subcmd, 0)) ) {
+ case 0 : {
+
+#line 6496 "printqd.ctr"
+ rq_c_reset(job);
+ } break;
+ case 1 : {
+
+#line 6499 "printqd.ctr"
+ rq_c_add(job);
+ } break;
+ case 2 : {
+
+#line 6502 "printqd.ctr"
+ rq_c_dbcl(job);
+ } break;
+ default : {
+ /* ERROR: Illegal sub-command */
+ log_3(NULL, 0UL, LOG_EMERG, 1, 168, 169, subcmd);
+ } break;
+ }
+
+
+#line 6510 "printqd.ctr"
+}
+
+
+
+/** Process contents of the inbuf buffer, send response if necessary.
+ @param job Data for one request to process.
+*/
+static
+void
+process_data(pqd_rq_t *job)
+{
+ const char * msgs[3];
+
+
+#line 6523 "printqd.ctr"
+ job->cmdptr = dk4str8_start(inbuf, NULL);
+ if (NULL != job->cmdptr) {
+ dk4str8_delnl(job->cmdptr);
+ /* LOG request */
+ if (0 == conf.linf) {
+ if ('i' == (job->cmdptr)[0]) {
+ if ('n' == (job->cmdptr)[1]) {
+ if ('f' == (job->cmdptr)[2]) {
+ if ('o' == (job->cmdptr)[3]) {
+ job->logthis = 0;
+ }
+ }
+ }
+ }
+ }
+ if (0 != job->logthis) {
+ msgs[0] = printqd_kw[87];
+ msgs[1] = job->cmdptr;
+ msgs[2] = NULL;
+ log_multipart_message(NULL, 0UL, LOG_EMERG, 0, msgs, 2);
+ }
+ /* Process request */
+ job->argptr = dk4str8_next(job->cmdptr, NULL);
+ job->action = dk4str8_array_index(pqd_command_names, job->cmdptr, 0);
+ if (0 != protocol_level_check(job->action, job->protlev)) {
+ switch (job->action) {
+ case PQD_CMD_INFO : {
+ rq_info(job);
+ } break;
+ case PQD_CMD_JOBSTART : {
+ rq_jobstart(job);
+ } break;
+ case PQD_CMD_FILESTART : {
+ rq_filestart(job);
+ } break;
+ case PQD_CMD_FILEEND : {
+ rq_fileend(job);
+ } break;
+ case PQD_CMD_ACCT_CHECK : {
+ rq_acct_check(job);
+ } break;
+ case PQD_CMD_ACCT_START : {
+ rq_acct_start(job);
+ } break;
+ case PQD_CMD_ACCT_END : {
+ rq_acct_end(job);
+ } break;
+ case PQD_CMD_ACCT_CHARGE : {
+ rq_acct_charge(job);
+ } break;
+ case PQD_CMD_CONTROL : {
+ rq_control(job);
+ } break;
+ }
+ } else {
+ /* Close connection if request is denied.
+ */
+ if ((NULL == job->soa) && (0 == job->szsoa)) {
+ close_stream_conn(job->sock, job->sto, job->connptr, job->pnconn);
+ }
+ }
+ }
+
+
+#line 6586 "printqd.ctr"
+}
+
+
+
+/** Run one pass within inner loop.
+*/
+static
+void
+one_pass(void)
+{
+ fd_set rfds; /* Read file desc set */
+ dk4_sockaddr_storage_t soa_sto; /* Remote address */
+ pqd_rq_t job; /* Job structure */
+ struct sockaddr *soa; /* Remote address */
+#if VERSION_BEFORE_20160329
+ struct sockaddr_in *soa4; /* Remote IPv4 address */
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ struct sockaddr_in6 *soa6; /* Remote IPv6 address */
+#endif
+#endif
+ pqd_l_conn_t *pconnloc; /* UNIX connection record */
+ pqd_n_conn_t *pconntcp; /* TCP connection record */
+ size_t sz_soa_sto; /* Address size */
+ size_t rdbytes; /* Number of bytes read */
+ size_t i; /* Traverse socket set */
+ dk4_socket_t sock; /* Current new socket */
+ int maxfd = 0; /* Maximum fd number */
+ int l_conn = 0; /* Flag: Local connection */
+ int l_proc = 0; /* Flag: Local processing */
+ int res = 0; /* Operation result */
+ int addrok; /* Flag: Address size ok */
+ int protlev; /* Procotol level for conn */
+
+
+
+#line 6620 "printqd.ctr"
+ /* Create file descriptor set for select.
+ */
+ FD_ZERO(&rfds);
+ /* Check for incoming UNIX conn rq only if maximum not yet reached.
+ */
+ if ((0 == conf.m_loc) || (con_loc < conf.m_loc)) {
+ FD_SET(so_unix,&rfds);
+ if (maxfd < so_unix) { maxfd = so_unix; }
+ }
+
+ /* Check for incoming TCP conn rq only if maximum not yet reached.
+ */
+ if ((NULL != ss_tcp) && ((0 == conf.m_tcp) || (con_tcp < conf.m_tcp))) {
+ for (i = 0; i < ss_tcp->szUsed; i++) {
+ FD_SET((ss_tcp->pSockets)[i],&rfds);
+ if (maxfd < (ss_tcp->pSockets)[i]) { maxfd = (ss_tcp->pSockets)[i]; }
+ }
+ }
+
+ /* Check for data on existing UNIX connections.
+ */
+ dk4sto_it_reset(i_c_unix);
+ do {
+ pconnloc = (pqd_l_conn_t *)dk4sto_it_next(i_c_unix);
+ if (NULL != pconnloc) {
+ FD_SET(pconnloc->sock,&rfds);
+ if (maxfd < pconnloc->sock) { maxfd = pconnloc->sock; }
+ }
+ } while (NULL != pconnloc);
+
+ /* Check for data on existing TCP connections.
+ */
+ dk4sto_it_reset(i_c_tcp);
+ do {
+ pconntcp = (pqd_n_conn_t *)dk4sto_it_next(i_c_tcp);
+ if (NULL != pconntcp) {
+ FD_SET(pconntcp->sock,&rfds);
+ if (maxfd < pconntcp->sock) { maxfd = pconntcp->sock; }
+ }
+ } while (NULL != pconntcp);
+
+ /* Check for data on UDP sockets.
+ */
+ if (NULL != ss_udp) {
+ for (i = 0; i < ss_udp->szUsed; i++) {
+ FD_SET((ss_udp->pSockets)[i],&rfds);
+ if (maxfd < (ss_udp->pSockets)[i]) { maxfd = (ss_udp->pSockets)[i]; }
+ }
+ }
+
+ /* Check for signal meanwhile.
+ */
+ if (0 == can_continue(1, 0)) {
+
+#line 6673 "printqd.ctr"
+ goto finished;
+ }
+
+ /* Run select().
+ */
+ errno = 0;
+ res = select((1+maxfd), &rfds, NULL, NULL, NULL);
+ if (-1 == res) {
+ switch (errno) {
+ case EINTR: {
+
+#line 6683 "printqd.ctr"
+ goto finished;
+ } break;
+ default: {
+
+#line 6686 "printqd.ctr"
+ /* ERROR: Serious error from select() function */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 119);
+ ccouter = -1;
+ ccinner = -1;
+ goto finished;
+ } break;
+ }
+ }
+ if (0 == res) {
+
+#line 6695 "printqd.ctr"
+ goto finished;
+ }
+
+ /* Check for new connection attempts on local socket.
+ */
+ if ((0 == conf.m_loc) || (con_loc < conf.m_loc)) {
+ if (0 != (FD_ISSET(so_unix,&rfds))) {
+
+#line 6702 "printqd.ctr"
+ sock = dk4socket_accept(so_unix, NULL, NULL, NULL);
+ if (INVALID_SOCKET != sock) {
+ pconnloc = dk4mem_new(pqd_l_conn_t,1,NULL);
+ if (NULL != pconnloc) {
+ pconnloc->sock = sock;
+ if (dk4sto_add(s_c_unix, pconnloc, NULL)) {
+ con_loc++;
+ l_conn = 1;
+ } else {
+ dk4mem_free(pconnloc);
+ (void)dk4socket_close(sock, NULL);
+ }
+ } else {
+ (void)dk4socket_close(sock, NULL);
+ /* ERROR: Memory */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 120);
+ ccouter = -1;
+ ccinner = -1;
+ }
+ }
+ }
+ }
+
+ /* Process data from local socket connections.
+ */
+ dk4sto_it_reset(i_c_unix);
+ do {
+ if (0 != can_continue(1, 0)) {
+ pconnloc = (pqd_l_conn_t *)dk4sto_it_next(i_c_unix);
+ if (NULL != pconnloc) {
+ if (0 != (FD_ISSET(pconnloc->sock,&rfds))) {
+ l_proc = 1;
+
+#line 6734 "printqd.ctr"
+ rdbytes = sizeof(inbuf);
+ res = dk4socket_recv(
+ pconnloc->sock, inbuf, &rdbytes, 0, 0L, 0L, NULL
+ );
+ if (0 != can_continue(0, 0)) {
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ if (0 < rdbytes) {
+ if (sizeof(inbuf) > rdbytes) {
+ inbuf[rdbytes] = '\0';
+ job_init(&job);
+ job.sock = pconnloc->sock;
+ job.protlev = PQD_PROTO_ADMIN;
+ job.connptr = pconnloc;
+ job.sto = s_c_unix;
+ job.pnconn = &con_loc;
+ process_data(&job);
+ }
+ } else {
+ close_stream_conn(pconnloc->sock, s_c_unix, pconnloc, &con_loc);
+ }
+ } else {
+ close_stream_conn(pconnloc->sock, s_c_unix, pconnloc, &con_loc);
+ }
+ } else {
+ pconnloc = NULL;
+ }
+ }
+ }
+ } else {
+ pconnloc = NULL;
+ }
+ } while (NULL != pconnloc);
+
+ /* Skip TCP and UDP data if activity on higher priorized local sockets.
+ */
+ if ((0 != l_conn) || (0 != l_proc) || (0 == can_continue(1, 0))) {
+
+
+#line 6771 "printqd.ctr"
+ goto finished;
+ }
+
+ /* Check for new connection attempts on TCP.
+ */
+ if ((NULL != ss_tcp) && ((0 == conf.m_tcp) || (con_tcp < conf.m_tcp))) {
+ for (i = 0; ((i < ss_tcp->szUsed) && (0 != can_continue(1, 0))); i++) {
+ if (0 != (FD_ISSET((ss_tcp->pSockets)[i],&rfds))) {
+
+
+#line 6780 "printqd.ctr"
+ DK4_MEMRES(&soa_sto, sizeof(soa_sto));
+ sz_soa_sto = sizeof(soa_sto);
+ sock = dk4socket_accept(
+ (ss_tcp->pSockets)[i],
+ (struct sockaddr *)(&soa_sto), &sz_soa_sto, NULL
+ );
+ if (INVALID_SOCKET != sock) {
+#if VERSION_BEFORE_20160329
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ soa6 = (struct sockaddr_in6 *)(&soa_sto);
+#endif
+ soa4 = (struct sockaddr_in *)(&soa_sto);
+#endif
+ soa = (struct sockaddr *)(&soa_sto);
+ addrok = 0;
+ if (AF_INET == soa->sa_family) {
+ if (sizeof(struct sockaddr_in) == sz_soa_sto) {
+ addrok = 1;
+ }
+ }
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ if (AF_INET6 == soa->sa_family) {
+ if (sizeof(struct sockaddr_in6) == sz_soa_sto) {
+ addrok = 1;
+ }
+ }
+#endif
+ if (0 != addrok) {
+ protlev = protocol_level_for_address(soa);
+ if (PQD_PROTO_NONE < protlev) {
+
+#line 6810 "printqd.ctr"
+ pconntcp = dk4mem_new(pqd_n_conn_t,1,NULL);
+ if (NULL != pconntcp) {
+ pconntcp->sock = sock;
+ if (0 != dk4sto_add(s_c_tcp, pconntcp, NULL)) {
+#if VERSION_BEFORE_20160811
+ DK4_MEMCPY(&(pconntcp->raddr),&soa_sto,sizeof(&soa_sto));
+#else
+ DK4_MEMCPY(&(pconntcp->raddr),&soa_sto,sizeof(soa_sto));
+#endif
+ pconntcp->pqdpl = protlev;
+ } else {
+ dk4mem_free(pconntcp);
+ (void)dk4socket_close(sock, NULL);
+ /* ERROR: Memory */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 120);
+ ccouter = -1;
+ ccinner = -1;
+ }
+ } else {
+ (void)dk4socket_close(sock, NULL);
+ /* ERROR: Memory */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 120);
+ ccouter = -1;
+ ccinner = -1;
+ }
+ } else {
+
+#line 6836 "printqd.ctr"
+ (void)dk4socket_close(sock, NULL);
+ }
+ } else {
+
+#line 6839 "printqd.ctr"
+ (void)dk4socket_close(sock, NULL);
+ }
+ }
+ }
+ }
+ }
+ if (0 == can_continue(1, 0)) {
+
+
+#line 6847 "printqd.ctr"
+ goto finished;
+ }
+
+ /* Process data from TCP connections.
+ */
+ dk4sto_it_reset(i_c_tcp);
+ do {
+ if (0 != can_continue(1, 0)) {
+ pconntcp = (pqd_n_conn_t *)dk4sto_it_next(i_c_tcp);
+ if (NULL != pconntcp) {
+ if (0 != (FD_ISSET(pconntcp->sock,&rfds))) {
+
+
+#line 6859 "printqd.ctr"
+ rdbytes = sizeof(inbuf);
+ res = dk4socket_recv(
+ pconntcp->sock, inbuf, &rdbytes, 0, 0L, 0L, NULL
+ );
+ if (0 != can_continue(0, 0)) {
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ if (0 < rdbytes) {
+ if (sizeof(inbuf) > rdbytes) {
+ inbuf[rdbytes] = '\0';
+ job_init(&job);
+ job.sock = pconntcp->sock;
+ job.protlev = pconntcp->pqdpl;
+ job.connptr = pconntcp;
+ job.sto = s_c_tcp;
+ job.pnconn = &con_tcp;
+ process_data(&job);
+ }
+ } else {
+ close_stream_conn(pconntcp->sock, s_c_tcp, pconntcp, &con_tcp);
+ }
+ } else {
+ close_stream_conn(pconntcp->sock, s_c_tcp, pconntcp, &con_tcp);
+ }
+ } else {
+ }
+ }
+ }
+ } else {
+ pconntcp = NULL;
+ }
+ } while (NULL != pconntcp);
+ if (0 == can_continue(1, 0)) {
+
+
+#line 6892 "printqd.ctr"
+ goto finished;
+ }
+
+ /* Process UDP data.
+ */
+ if (NULL != ss_udp) {
+ for (i = 0; ((i < ss_udp->szUsed) && (0 != can_continue(1, 0))); i++) {
+ if (0 != (FD_ISSET((ss_udp->pSockets)[i],&rfds))) {
+
+
+#line 6901 "printqd.ctr"
+ rdbytes = sizeof(inbuf);
+ sz_soa_sto = sizeof(soa_sto);
+ res = dk4socket_recvfrom(
+ (ss_udp->pSockets)[i], inbuf, &rdbytes, 0,
+ (struct sockaddr *)(&soa_sto), &sz_soa_sto, 0L, 0L, NULL
+ );
+ if ((DK4_SOCKET_RESULT_SUCCESS == res) && (0 < rdbytes)) {
+ if ((0 != can_continue(1, 0)) && (sizeof(inbuf) > rdbytes)) {
+ inbuf[rdbytes] = '\0';
+#if VERSION_BEFORE_20160329
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ soa6 = (struct sockaddr_in6 *)(&soa_sto);
+#endif
+ soa4 = (struct sockaddr_in *)(&soa_sto);
+#endif
+ soa = (struct sockaddr *)(&soa_sto);
+ addrok = 0;
+ if (AF_INET == soa->sa_family) {
+ if (sizeof(struct sockaddr_in) == sz_soa_sto) {
+ addrok = 1;
+ }
+ }
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ if (AF_INET6 == soa->sa_family) {
+ if (sizeof(struct sockaddr_in6) == sz_soa_sto) {
+ addrok = 1;
+ }
+ }
+#endif
+ if (0 != addrok) {
+ protlev = protocol_level_for_address(soa);
+ if (PQD_PROTO_NONE < protlev) {
+ job_init(&job);
+ job.sock = (ss_udp->pSockets)[i];
+ job.protlev = PQD_PROTO_INFO;
+ job.soa = (struct sockaddr *)(&soa_sto);
+ job.szsoa = sz_soa_sto;
+ process_data(&job);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ finished:
+
+
+#line 6949 "printqd.ctr"
+ if (0 == dbi_sync(db, NULL)) {
+ /* ERROR: Failed to synchronize database */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 121);
+ }
+ if (0 == can_continue(1, 0)) {
+ ccinner = 0;
+ if (0 == can_continue(0, 0)) {
+ ccouter = 0;
+ }
+ }
+
+
+#line 6960 "printqd.ctr"
+}
+
+
+
+
+/** Run two nested loops: The outer loop is only finished
+ by SIGTERM or SIGINT to exit the program, the inner loop
+ is also finished by SIGHUP to re-read the configuration.
+*/
+static
+void
+service_loops(void)
+{
+
+
+#line 6974 "printqd.ctr"
+
+
+#line 6975 "printqd.ctr"
+ /* LOG: Daemon running */
+ log_1(NULL, 0UL, LOG_INFO, 0, 73);
+ if (outer_allocate_resources()) {
+ /* Outer loop is left on SIGTERM or SIGINT.
+ */
+ while(1 == ccouter) {
+ if (1 == can_continue(0, 0)) {
+ config_init();
+ if (0 != config_read()) {
+ if (inner_allocate_resources()) {
+ if (0 != change_group_and_user()) {
+ /* Inner loop is left on SIGHUP, SIGTERM or SIGINT.
+ */
+ ccinner = 1;
+ *sig_pass_pointer(&sig_had_hup) = 0;
+ prev_filelog_failed = 0;
+ /* LOG: Entering service mode */
+ log_1(NULL, 0UL, LOG_INFO, 0, 75);
+ while(1 == ccinner) {
+ if (1 == can_continue(1, 0)) {
+
+#line 6995 "printqd.ctr"
+ one_pass();
+ } else {
+
+#line 6997 "printqd.ctr"
+ ccinner = 0;
+ if (0 == can_continue(0, 0)) {
+ ccouter = 0;
+ /* LOG: Exiting service mode */
+ log_1(NULL, 0UL, LOG_INFO, 0, 76);
+ } else {
+ /* LOG: Exiting service mode for reconfiguration */
+ log_1(NULL, 0UL, LOG_INFO, 0, 77);
+ }
+ }
+ }
+ /* LOG: Exited service mode */
+ log_1(NULL, 0UL, LOG_INFO, 0, 78);
+ } else {
+
+#line 7011 "printqd.ctr"
+ ccouter = -1;
+ }
+ } else {
+
+#line 7014 "printqd.ctr"
+ ccouter = -1;
+ }
+ if (0 == inner_release_resources()) {
+
+#line 7017 "printqd.ctr"
+ ccouter = -1;
+ }
+ } else {
+
+#line 7020 "printqd.ctr"
+ ccouter = -1;
+ }
+ config_release();
+ } else {
+
+#line 7024 "printqd.ctr"
+ ccouter = 0;
+ }
+ }
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 7030 "printqd.ctr"
+ }
+#endif
+ outer_release_resources();
+ /* LOG: Daemon exiting */
+ log_1(
+ NULL, 0UL,
+ ((0 == ccouter) ? (LOG_INFO) : (LOG_ERR)),
+ ((0 == ccouter) ? (0) : (1)),
+ ((0 == ccouter) ? (74) : (187))
+ );
+
+
+#line 7041 "printqd.ctr"
+
+
+#line 7042 "printqd.ctr"
+}
+
+
+
+/** Run service in debug mode or normal mode.
+*/
+static
+void
+set_signal_handlers_and_run_service(void)
+{
+ int loop_was_running = 0;
+#ifdef DK4_HAVE_SIGACTION
+#ifdef SIGHUP
+ struct sigaction ohup;
+ struct sigaction nhup;
+#endif
+#ifdef SIGPIPE
+ struct sigaction opipe;
+ struct sigaction npipe;
+#endif
+ struct sigaction oint;
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+#else
+#ifdef SIGPIPE
+ dk4_sig_handler_t *opipe = NULL;
+#endif
+#ifdef SIGHUP
+ dk4_sig_handler_t *ohup = NULL;
+#endif
+ dk4_sig_handler_t *oterm = NULL;
+ dk4_sig_handler_t *oint = NULL;
+#endif
+#ifdef DK4_HAVE_SIGACTION
+#ifdef SIGHUP
+ int shup = 0;
+#endif
+#ifdef SIGPIPE
+ int spipe = 0;
+#endif
+ int sint = 0;
+ int sterm = 0;
+ int s_f_i = 0;
+ int s_f_r = 0;
+#endif
+
+ /* Set signal handlers
+ */
+#if DK4_HAVE_SIGACTION
+#ifdef SIGPIPE
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ spipe = 1;
+#endif
+#ifdef SIGHUP
+ DK4_MEMRES(&nhup, sizeof(nhup));
+ nhup.sa_handler = sig_handler_hup;
+ nhup.sa_flags = 0;
+ if (0 != sigemptyset(&nhup.sa_mask)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaddset(&nhup.sa_mask, SIGHUP)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaction(SIGHUP, &nhup, &ohup)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ shup = 1;
+#endif
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ sterm = 1;
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ sint = 1;
+#else
+#ifdef SIGPIPE
+ opipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+#ifdef SIGHUP
+ ohup = sigset(SIGHUP, sig_handler_hup);
+#endif
+ oint = sigset(SIGINT, sig_handler_int);
+ oterm = sigset(SIGTERM, sig_handler_term);
+#endif
+
+
+ service_loops();
+ loop_was_running = 1;
+
+ finished:
+
+ /*
+ */
+ if (0 == loop_was_running) {
+ log_1(NULL, 0UL, LOG_ERR, 1, 72);
+ }
+
+ /* Restore signal handlers
+ */
+#if DK4_HAVE_SIGACTION
+ if (0 != s_f_i) {
+ /* ERROR: Failed to install signal handlers */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 68);
+ exval = EXIT_FAILURE;
+ }
+ if (0 != sint) {
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ s_f_r = 1;
+ }
+ }
+ if (0 != sterm) {
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ s_f_r = 1;
+ }
+ }
+#ifdef SIGHUP
+ if (0 != shup) {
+ if (0 != sigaction(SIGHUP, &ohup, NULL)) {
+ s_f_r = 1;
+ }
+ }
+#endif
+#ifdef SIGPIPE
+ if (0 != spipe) {
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ s_f_r = 1;
+ }
+ }
+#endif
+ if (0 != s_f_r) {
+ /* ERROR: Failed to restore signal handlers */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 69);
+ exval = EXIT_FAILURE;
+ }
+#else
+ if (NULL != oterm) { sigset(SIGTERM, oterm); }
+ if (NULL != oint ) { sigset(SIGINT, oint ); }
+#ifdef SIGHUP
+ if (NULL != ohup) { sigset(SIGHUP, ohup); }
+#endif
+#ifdef SIGPIPE
+ if (NULL != opipe) { sigset(SIGPIPE, opipe); }
+#endif
+#endif
+
+}
+
+
+
+/** Program entry point.
+ @param argc
+ @param argv
+ @return 0 on success, any other value indicates an error.
+*/
+int
+main(int argc, char *argv[])
+{
+ pid_t cpid; /* Child process PID */
+ int res; /* Operation result */
+
+ /* Process command line arguments.
+ */
+ res = dk4opt_process_argv(
+ options, szoptions, argc, argv, NULL, NULL, 1, 1, NULL
+ );
+ if (0 == res) {
+ exval = 2; /* Invalid or excess arguments */
+ goto finished;
+ }
+
+ /* Must be started as root.
+ */
+ if (0 != geteuid()) {
+ fputs("printqd: ERROR: Must be run as root!\n", stderr);
+ fflush(stderr);
+ goto finished;
+ }
+
+ /* Check used command line arguments.
+ */
+ if (0 != options[0].found) { debug = 1; }
+
+ /* Run in debug mode.
+ */
+ if (0 != debug) {
+ set_signal_handlers_and_run_service();
+ goto finished;
+ }
+
+ /* PREPARE TO RUN AS DAEMON
+ */
+ if (0 == dk4dmt_parent_before_fork(printqd_kw[0],pid_file_name,1,syslogf)) {
+ goto finished;
+ }
+
+ /* Create first background process
+ */
+ cpid = fork();
+ if ((pid_t)0 < cpid) {
+ /* In the parent process */
+ goto finished;
+ } else {
+ if ((pid_t)0 == cpid) {
+ /* In the child process, continue below */
+ } else {
+ /* Failed to create process */
+ /* ERROR: fork() failed */
+ fputs(printqd_kw[0], stderr);
+ fputs(printqd_kw[70], stderr);
+ fflush(stderr);
+ goto finished;
+ }
+ }
+
+ /* Intermediate process and daemon process should indicate success.
+ */
+ exval = EXIT_SUCCESS;
+
+ /* Decouple from terminals.
+ */
+ if (0 == dk4dmt_intermediate_before_fork(printqd_kw[0], syslogf)) {
+ goto finished;
+ }
+
+ /* Create daemon background process from within first background process
+ */
+ cpid = fork();
+ if ((pid_t)0 < cpid) {
+ /* In the intermediate process */
+ goto finished;
+ } else {
+ if ((pid_t)0 == cpid) {
+ /* In the daemon process, continue below */
+ } else {
+ /* Failed to create process */
+ /* ERROR: fork() failed */
+ log_1(NULL, 0UL, LOG_ERR, 1, 71);
+ goto finished;
+ }
+ }
+
+ /* In the daemon process
+ */
+ if (0 != dk4dmt_daemon_after_fork(printqd_kw[0], pid_file_name, syslogf)) {
+ set_signal_handlers_and_run_service();
+ }
+ dk4dmt_daemon_end(printqd_kw[0], pid_file_name, syslogf);
+
+ /* Exit the program.
+ */
+ finished:
+ exit(exval); return exval;
+}
+
+#else
+
+/** Program entry point.
+ @param argc
+ @param argv
+ @return 0 on success, any other value indicates an error.
+*/
+int
+main(int argc, char *argv[])
+{
+ fputs("printqd: ERROR: Build requirements violation!\n", stderr);
+#if DK4_CHAR_SIZE > 1
+ fputs("Default character size is larger than 1!\n", stderr);
+#endif
+#if !((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET))
+ fputs("Neither sigaction() nor sigset() are available!\n", stderr);
+#endif
+#if !(DK4_HAVE_PWD_H)
+ fputs("Include file \"pwd.h\" not found!\n", stderr);
+#endif
+#if !(DK4_HAVE_UID_T)
+ fputs("Data type uid_t not available!\n", stderr);
+#endif
+#if !(DK4_HAVE_GRP_H)
+ fputs("Include file \"grp.h\" not found!\n", stderr);
+#endif
+#if !(DK4_HAVE_GID_T)
+ fputs("Data type gid_t not available!\n", stderr);
+#endif
+#if !(DK4_HAVE_MODE_T)
+ fputs("Data type mode_t not available!\n", stderr);
+#endif
+#if !(DK4_HAVE_GETPWNAM)
+ fputs("Function getpwnam() is not available!\n", stderr);
+#endif
+#if !(DK4_HAVE_GETGRNAM)
+ fputs("Function getgrnam() is not available!\n", stderr);
+#endif
+#if !((DK4_HAVE_SETSID) || (DK4_HAVE_SETPGRP))
+ fputs("Neither setsid() nor setpgrp() are available!\n", stderr);
+#endif
+#if DK4_ON_WINDOWS
+ fputs("On Windows platform!\n", stderr);
+#endif
+ fflush(stderr);
+ exit(EXIT_FAILURE); return EXIT_FAILURE;
+}
+
+
+#endif
diff --git a/support/dktools/printqd.conf.sample b/support/dktools/printqd.conf.sample
new file mode 100644
index 0000000000..136ba3f345
--- /dev/null
+++ b/support/dktools/printqd.conf.sample
@@ -0,0 +1,206 @@
+# The options section contains general options.
+# =============================================
+
+[options]
+
+# After startup the printqd process gives up privileges and runs
+# under an unprivileged user account.
+# Use the same UID ase the LPRng lpd daemon does.
+# For some name services you can not use this option as only the
+# root user has access to user and group information.
+# --------------------------------------------------------------
+# run as user = lp
+
+# After startup the printqd process gives up privileges and runs
+# under an unprivileged group.
+# The group must have the following permissions:
+# - Write access to the directory containing the local UNIX
+# domain socket,
+# - Read/write access to the local UNIX domain socket, if it
+# already exists,
+# - Write access to the log file (write access to the directory
+# containing the log file if the file does not yet exist) and
+# - Write access to the database file(s) (write access to the
+# directory containing the database files if they do not
+# yet exist).
+# Use the same GID as the LPRng lpd daemon does.
+# --------------------------------------------------------------
+# run as group = lp
+
+# Database type and file name separated by `::', optional.
+# By default the database is placed in the ${localstatedir}/printqd
+# directory as file(s) printqd.* , the best available database type
+# is choosen with a corresponding file name suffix.
+# -----------------------------------------------------------------
+# database = mem::/var/printqd/printqd.db
+
+# Local UNIX domain socket, optional.
+# Default is ${localstatedir}/run/printqd/printqd.sock .
+# ------------------------------------------------------
+# local socket = /var/run/printqd/printqd.sock
+
+# Owner of the local socket.
+# Only needed if ``run as user'' is not specified.
+# Use the account of the LPRng print system.
+# ------------------------------------------------
+# local socket owner = lp
+
+# Owner group of local socket.
+# Only needed if ``run as group'' is not specified.
+# Use the group of the LPRng print system.
+# -------------------------------------------------
+# local socket group = lp
+
+# Number of connection attempts to queue for local UNIX domain socket.
+# The default is 5. You should use at least 1 + number of print queues.
+# ---------------------------------------------------------------------
+# local socket backlog = 5
+
+# Maximum number of connections established over local UNIX domain socket.
+# Should be at least 1 + number of print queues.
+# ------------------------------------------------------------------------
+# max local connections = 7
+
+# UDP port to receive info requests and send responses (optional).
+# ----------------------------------------------------------------
+# udp port = 9100
+
+# TCP port to listen for connections (optional).
+# ----------------------------------------------
+# tcp port = 9100
+
+# Number of connection attempts to queue for TCP port. Default: 5.
+# ----------------------------------------------------------------
+# tcp port backlog = 5
+
+# Maximum number of connections established over TCP port.
+# --------------------------------------------------------
+# max tcp connections = 50
+
+# The hosts below are allowed to send info requests.
+# May be used multiple times.
+# If no ``info allow'' line is present, access is denied
+# from all hosts.
+# The asterisk line would enable info requests from everywhere,
+# this is only recommended if your network is behind a firewall
+# or router with ACLs restricting inbound traffic.
+# -------------------------------------------------------------
+info allow = 192.0.2.0/24
+# info allow = *
+
+# The host below is allowed to send data level requests.
+# May be used multiple times.
+# If no ``data allow'' line is present, access is denied
+# from all hosts.
+# ------------------------------------------------------
+# data allow = 127.0.0.1/32
+
+# The hosts below are allowed to send admin level requests.
+# In the example here we deny admin level requests over network.
+# If no ``admin allow'' line is present, access is denied
+# from all hosts.
+# --------------------------------------------------------------
+# admin allow = 127.0.0.1/32
+
+# Log file name, optional.
+# Default is ${localstatedir}/log/printqd/printqdlog .
+# ----------------------------------------------------
+# log file = /var/log/printqd/printqd.log
+
+# By default only minimum log is written.
+# You can configure additional features in a comma separated list:
+# - db Write log entries for database changes.
+# - info Write log entries for info requests and responses.
+# Use the shortcut ``*'' or ``all'' for maximum logging,
+# ``-'' or ``none'' for minimum.
+# ----------------------------------------------------------------
+# log features = -
+
+
+# A class is a group of printers. In the example below we assume
+# two computer class rooms with printers lp and lp2.
+# The limit configured for the class is the summary of pages on
+# all printers in a class.
+# ==============================================================
+
+[class cl-mfd]
+
+# Limits for specific users. Instead of the text ``unlimited''
+# we could specify page numbers or the text ``denied''.
+# The right side consists of user name and limit.
+# ------------------------------------------------------------
+user limit = Administrator unlimited
+user limit = Administ unlimited
+user limit = admin unlimited
+user limit = root unlimited
+
+# Group limits are used for those users without a user-specific
+# limit.
+# The right side consists of group name and limit.
+# -------------------------------------------------------------
+group limit = fac_m unlimited
+
+# The default limit is used for all users without user- or
+# group-specific limit.
+# The right side just contains the limit.
+# --------------------------------------------------------
+default limit = 0
+
+# The deny action decides wether a denied print job is
+# removed (``remove'') or kept in the queue (``hold'').
+# -----------------------------------------------------
+deny action = remove
+
+
+# There are two further printer classes.
+# ======================================
+
+[class cl-color]
+user limit = Administrator unlimited
+user limit = Administ unlimited
+user limit = admin unlimited
+user limit = root unlimited
+group limit = fac_m unlimited
+default limit = 0
+deny action = remove
+
+[class cl-lab]
+user limit = Administrator unlimited
+user limit = Administ unlimited
+user limit = admin unlimited
+user limit = root unlimited
+group limit = fac_m unlimited
+default limit = 200
+deny action = remove
+
+
+# Each printer must be a member of one of the classes configured above.
+# =====================================================================
+
+[printer lp1]
+
+# The printer lp1 has an alias lp configured in the printcap file.
+# ----------------------------------------------------------------
+alias = lp
+
+# The printer is a member of the cl-lab class.
+# --------------------------------------------
+class = cl-lab
+
+
+
+# The printer in the other computer classroom is also in the cl-lab class.
+# ========================================================================
+
+[printer lp2]
+class = cl-lab
+
+# And the remaining printers
+# ==========================
+
+[printer lpcolor]
+class = cl-color
+
+[printer mfd]
+class = cl-mfd
+
diff --git a/support/dktools/printqd.ctr b/support/dktools/printqd.ctr
new file mode 100644
index 0000000000..6a58484b23
--- /dev/null
+++ b/support/dktools/printqd.ctr
@@ -0,0 +1,7389 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+
+
+%% header
+
+/* CORRECT NEXT LINE AFTER REPLACING PRINTQD */
+
+/** @file printqd.h Definitions for printqd.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4STO_H_INCLUDED
+#include "dk4sto.h"
+#endif
+
+#ifndef DK4SOCK_H_INCLUDED
+#include "dk4sock.h"
+#endif
+
+
+
+/** Limit for one user or group.
+*/
+typedef struct {
+ char *name; /**< User or group name */
+ dk4_um_t limit; /**< Page limit. */
+} pqd_limit_t;
+
+
+
+
+/** Printer class (may contain multiple printers).
+*/
+typedef struct {
+ char *name; /**< Class name. */
+ dk4_sto_t *s_u; /**< User limits storage. */
+ dk4_sto_it_t *i_u; /**< User limits storage iterator. */
+ dk4_sto_t *s_g; /**< Group limits storage. */
+ dk4_sto_it_t *i_g; /**< Group limits storage iterator. */
+ dk4_um_t dl; /**< Default limit. */
+ int da; /**< Deny action: 1=hold, 0=remove. */
+ int hdl; /**< Flag: Have default limit. */
+} pqd_class_t;
+
+
+
+/** Printer.
+*/
+typedef struct {
+ char *name; /**< Printer name. */
+ pqd_class_t *cl; /**< Printer class. */
+} pqd_printer_t;
+/*
+ In service the class is not NULL.
+ If no class is configured for a printer, the program complains
+ and exits.
+*/
+
+
+
+/** Printer alias.
+*/
+typedef struct {
+ char *name; /**< Alias name. */
+ pqd_printer_t *pr; /**< The real printer. */
+} pqd_printer_alias_t;
+
+
+
+/** Printqd configuration.
+*/
+typedef struct {
+ char *sname; /**< UNIX domain socket file name. */
+ char *dname; /**< Database name (including type). */
+ char *lname; /**< Log file name. */
+ dk4_sto_t *s_c; /**< Storage for classes. */
+ dk4_sto_it_t *i_c; /**< Iterator for class storage. */
+ dk4_sto_t *s_p; /**< Storage for printers. */
+ dk4_sto_it_t *i_p; /**< Iterator for printers storage. */
+ dk4_sto_t *s_a; /**< Storage for aliases. */
+ dk4_sto_it_t *i_a; /**< Iterator for aliases storage. */
+ dk4_sto_t *s_ai; /**< Storage for peers allowed info rq. */
+ dk4_sto_it_t *i_ai; /**< Iterator for info peers storage. */
+ dk4_sto_t *s_ad; /**< Storage for peers allowed data rq. */
+ dk4_sto_it_t *i_ad; /**< Iterator for data peers storage. */
+ dk4_sto_t *s_aa; /**< Storage for peers allowed admin rq. */
+ dk4_sto_it_t *i_aa; /**< Iterator for admin peers storage. */
+ size_t m_loc; /**< Maximum number of local connections. */
+ size_t m_tcp; /**< Maximum number of TCP connections. */
+ uid_t uid; /**< Run as specified user. */
+ uid_t suid; /**< Local socket owner UID. */
+ gid_t gid; /**< Run as specified group. */
+ gid_t sgid; /**< Local socket owner GID. */
+ int slbl; /**< Backlog for local socket. */
+ int snbl; /**< Backlog for network socket. */
+ int iglo; /**< Flag: Globally allow info requests. */
+ int dglo; /**< Flag: Globally allow data requests. */
+ int aglo; /**< Flag: Globally allow admin requests. */
+ int linf; /**< Flag: Log info requests. */
+ int ldb; /**< Flag: Log database modifications. */
+ unsigned short ptcp; /**< TCP port (info, data, admin), host repr. */
+ unsigned short pudp; /**< UDP port (info only), host represent. */
+} pqd_conf_t;
+
+
+
+/** Connection record for local socket.
+*/
+typedef struct {
+ dk4_socket_t sock; /**< Socket. */
+} pqd_l_conn_t;
+
+
+
+/** Connection record for network socket.
+*/
+typedef struct {
+ dk4_sockaddr_storage_t raddr; /**< Remote address. */
+ dk4_socket_t sock; /**< Socket. */
+ int pqdpl; /**< Printqd protocol level. */
+} pqd_n_conn_t;
+
+
+
+/** One request to process.
+*/
+typedef struct {
+ void *connptr; /**< Connection record for socket. */
+ dk4_sto_t *sto; /**< Container for conn records. */
+ struct sockaddr *soa; /**< Remote address, only UDP. */
+ size_t *pnconn; /**< Addr of variable, NULL for UDP. */
+ char *cmdptr; /**< Start of command. */
+ char *argptr; /**< Command arguments. */
+ size_t szsoa; /**< Size of rem address, only UDP. */
+ dk4_socket_t sock; /**< Socket to use for response. */
+ int protlev; /**< Protocol level. */
+ int action; /**< Action to take. */
+ int logthis; /**< Flag: Log request and response. */
+} pqd_rq_t;
+
+
+
+/** Data for one user in a class.
+*/
+typedef struct {
+ dk4_um_t limit; /**< Limit (maximum page number). */
+ dk4_um_t used; /**< Number of pages used within limit. */
+ dk4_um_t account; /**< Remaining pages personal print account. */
+ int da; /**< Deny action: 0=remove, 1=hold. */
+} pqd_account_t;
+
+
+
+/** Information from one LPRng accounting line.
+*/
+typedef struct {
+ char *username; /**< User name. */
+ char *queuename; /**< Print queue name. */
+ char *jobtitle; /**< Print job title. */
+ char *pagecount; /**< Pagecount reported in line. */
+} lprng_info_t;
+
+
+
+
+/** Printqd protocol levels.
+*/
+enum {
+ PQD_PROTO_NONE = 0 , /**< No requests allowed. */
+ PQD_PROTO_INFO = 1 , /**< Info requests only. */
+ PQD_PROTO_DATA = 2 , /**< Info and data requests. */
+ PQD_PROTO_ADMIN = 3 /**< Info, data and admin requests. */
+};
+
+
+
+/** Commands in the printqd protocol.
+*/
+enum {
+ PQD_CMD_NONE = -1 , /**< Illegal command. */
+ PQD_CMD_JOBSTART = 0 , /**< Start of print job, response required. */
+ PQD_CMD_JOBEND = 1 , /**< End of print job. */
+ PQD_CMD_START = 2 , /**< Start of printing (ignored). */
+ PQD_CMD_END = 3 , /**< End of printing (ignored). */
+ PQD_CMD_FILESTART = 4 , /**< Start of file printing (pc). */
+ PQD_CMD_FILEEND = 5 , /**< End of file printing (pc). */
+ PQD_CMD_INFO = 6 , /**< Information, response required. */
+ PQD_CMD_ACCT_CHECK = 7 , /**< Check permission, response required. */
+ PQD_CMD_ACCT_START = 8 , /**< Start of file printing (pc). */
+ PQD_CMD_ACCT_END = 9 , /**< End of file printing (pc). */
+ PQD_CMD_ACCT_CHARGE = 10 , /**< Summary for file printing (pc). */
+ PQD_CMD_CONTROL = 11 /**< Control request. */
+};
+
+
+
+%% module
+
+/** @file printqd.c The printqd daemon.
+
+A print accounting and quota daemon for use with the LPRng print system.
+*/
+
+
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+
+
+/* CORRECT NEXT LINE AFTER REPLACING PRINTQD */
+#include "printqd.h"
+
+
+
+#if (DK4_CHAR_SIZE == 1) \
+&& ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET)) \
+&& DK4_HAVE_GETPWNAM && DK4_HAVE_GETGRNAM \
+&& ((DK4_HAVE_SETSID) || (DK4_HAVE_SETPGRP)) \
+&& ((DK4_HAVE_PWD_H) && (DK4_HAVE_GRP_H)) \
+&& DK4_HAVE_UID_T && DK4_HAVE_GID_T && DK4_HAVE_MODE_T && (!DK4_ON_WINDOWS)
+
+
+
+#include <stdio.h>
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_STAT_H
+#ifndef SYS_STAT_H_INCLUDED
+#include <sys/stat.h>
+#define SYS_STAT_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PWD_H
+#ifndef PWD_H_INCLUDED
+#include <pwd.h>
+#define PWD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_GRP_H
+#ifndef GRP_H_INCLUDED
+#include <grp.h>
+#define GRP_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYSLOG_H
+#ifndef SYSLOG_H_INCLUDED
+#include <syslog.h>
+#define SYSLOG_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4opt.h"
+#include "dk4dmt.h"
+#include "dk4inst.h"
+#include "dk4dmt.h"
+#include "dk4sto.h"
+#include "dk4sock.h"
+#include "dk4mem.h"
+#include "dk4str8.h"
+#include "dk4mai8dii.h"
+#include "dk4mai8dsz.h"
+#include "dk4mai8dus.h"
+#include "dk4mai8ddu.h"
+#include "dk4mao8d.h"
+#include "dk4fopc8.h"
+#include "dk4dbi.h"
+#include "dk4dbit8.h"
+#include "dk4time.h"
+#include "dk4time08.h"
+#include "dk4mkdh8.h"
+#include "dk4delfile08.h"
+
+
+
+$!trace-include
+
+
+
+#ifndef LOG_LPR
+/** Default log feature for printing.
+*/
+#define LOG_LPR (6 << 3)
+#endif
+
+
+
+#ifndef LOG_EMERG
+/** Log message level to ignore, printqd does not make system unusable.
+*/
+#define LOG_EMERG (0)
+#endif
+
+#ifndef LOG_ERR
+/** Log message level error.
+*/
+#define LOG_ERR (3)
+#endif
+
+#ifndef LOG_INFO
+/** Log message level info.
+*/
+#define LOG_INFO (6)
+#endif
+
+/** Input buffer, used
+ * for configuration file reading and
+ * for reading requests.
+*/
+static char inbuf[1024];
+
+
+/** Buffer to construct key for database entries.
+*/
+static char kb[sizeof(inbuf)];
+
+
+/** Buffer to construct/convert values for database entries.
+*/
+static char vb[sizeof(inbuf)];
+
+
+/** Options used by the program.
+*/
+static dk4_option_t options[] = {
+
+ /* Debug mode.
+ */
+ { { dkT('d'), dkT("debug"), DK4_OPT_ARG_NONE }, { NULL }, 0 },
+
+ /* Configuration file.
+ */
+ { { dkT('c'), dkT("config"), DK4_OPT_ARG_STRING }, { NULL }, 0 }
+};
+
+
+
+/** Default configuration file name.
+*/
+static const char def_conf_file_name[] = {
+ DK4_INST_DIR_ETC "/printqd/printqd.conf"
+};
+
+
+
+/** Default socket file name.
+*/
+static const char def_sock_file_name[] = {
+ DK4_INST_DIR_VAR "/run/printqd/printqd.sock"
+};
+
+
+
+/** Default database file name.
+*/
+static const char def_db_file_name[] = {
+#if DK4_HAVE_DB_H
+ "bdb::" DK4_INST_DIR_VAR "/lib/printqd/printqd.db"
+#else
+#if DK4_HAVE_NDBM_H
+ "ndbm::" DK4_INST_DIR_VAR "/lib/printqd/printqd"
+#else
+ "mem::" DK4_INST_DIR_VAR "/lib/printqd/printqd.db"
+#endif
+#endif
+};
+
+
+
+/** Default log file name.
+*/
+static const char def_log_file_name[] = {
+ DK4_INST_DIR_VAR "/log/printqd/printqd.log"
+};
+
+
+
+
+/** PID file name.
+*/
+static const char pid_file_name[] = {
+ DK4_INST_DIR_VAR "/run/printqd/printqd.pid"
+};
+
+
+
+/** Constant texts used by the module.
+*/
+static const char * const printqd_kw[] = {
+$!string-table
+#
+# 0 Program name
+#
+printqd
+#
+# 1 File open mode
+#
+r
+#
+# 2 Asterisk
+#
+*
+#
+# 3 unlimited
+#
+unlimited
+#
+# 4 denied
+#
+denied
+#
+# 5 Newline
+#
+\n
+#
+# 6 Start of comment
+#
+\#
+#
+# 7 8
+#
+:
+:
+#
+# 9
+#
+ERROR:
+#
+# 10 File open mode
+#
+a
+#
+# 11 Empty string
+#
+
+#
+# 12 13 14
+#
+Not an integer number:\n"
+", reading stoppend at "
+"!
+#
+# 15
+#
+Positive number required!
+#
+# 16 17 18
+#
+Not a size specification:\n"
+", reading stopped at "
+"!
+#
+# 19 20 21
+#
+Not a 16 bit unsigned number:\n"
+", reading stopped at "
+"!
+#
+# 22
+#
+Port number must not be 0!
+#
+# 23 24
+#
+Too much text, unexpected:\n"
+"!
+#
+# 25 26
+#
+Not a peer definition:\n"
+"!
+#
+# 27
+#
+Not enough memory (allocation failed)!
+#
+# 28 29 30
+#
+Not an unsigned number:\n"
+", reading stopped at "
+"!
+#
+# 31
+#
+Missing limit text!
+#
+# 32 33
+#
+Limit redefinition for: "
+"!
+#
+# 34
+#
+Redefinition of default limit!
+#
+# 35
+#
+Redefinition of deny action!
+#
+# 36 37
+#
+Printer already exists: "
+"!
+#
+# 38 39
+#
+Printer alias already exists: "
+"!
+#
+# 40 41
+#
+Class not found: "
+"!
+#
+# 42
+#
+Redefinition of printers class!
+#
+# 43 44
+#
+Class already exists: "
+"!
+#
+# 45
+#
+Missing class name!
+#
+# 46 47
+#
+Printer or alias already exists: "
+"!
+#
+# 48
+#
+Missing printer name!
+#
+# 49 50
+#
+Illegal section type name: "
+"!
+#
+# 51
+#
+Missing section type!
+#
+# 52
+#
+Redefinition of user ID to run as!
+#
+# 53 54
+#
+User not found: "
+"!
+#
+# 55
+#
+Only allowed in options section!
+#
+# 56
+#
+Redefinition of group ID to run as!
+#
+# 57 58
+#
+Group not found: "
+"!
+#
+# 59
+#
+Redefinition of database name!
+#
+# 60
+#
+Redefinition of socket name!
+#
+# 61
+#
+Only allowed in class section!
+#
+# 62
+#
+Only allowed in printer section!
+#
+# 63
+#
+Redefinition of log file name!
+#
+# 64
+#
+Value missing!
+#
+# 65
+#
+Failed to open file for reading!
+#
+# 66
+#
+User to run as was changed!
+#
+# 67
+#
+Group to run as was changed!
+#
+# 68
+#
+Failed to install signal handlers!
+#
+# 69
+#
+Failed to restore signal handlers!
+#
+# 70
+#
+: ERROR: Failed to create new process!\n
+#
+# 71
+#
+Failed to create new process!
+#
+# 72
+#
+Service start prevented by errors!
+#
+# 73 74
+#
+Daemon starting.
+Daemon exited.
+#
+# 75 76 77 78
+#
+Entering service mode.
+Exiting service mode.
+Exiting service mode for reconfiguration.
+Exited service mode.
+#
+# 79
+#
+o:test
+#
+# 80 81 82 83 84 Response keywords
+#
+ACCEPT
+REMOVE
+HOLD
+0 0 0 0
+-1
+#
+# 85 Space
+#
+
+#
+# 86 87 Markers for request and response
+#
+<-
+->
+#
+# 88 89 90 Start of db keys
+#
+p:
+a:
+j:
+#
+# 91 92 Error: No class for printer
+#
+No class configured for printer: "
+"!
+#
+# 93 94
+#
+Warning: No default limit configured for class: "
+"!
+#
+# 95 96
+#
+Failed to create directory hierarchy for log file:\n"
+"!
+#
+# 97 98
+#
+Failed to create directory hierarchy for database:\n"
+"!
+#
+# 99 100
+#
+Failed to create directory hierarchy for socket:\n"
+"!
+#
+# 101 102
+#
+Failed to listen on local socket:\n"
+"!
+#
+# 103
+#
+Failed to create TCP listener socket set!
+#
+# 104
+#
+Failed to create UDP socket set!
+#
+# 105 106
+#
+Failed to open database:\n"
+"!
+#
+# 107
+#
+Failed to write initial entry to database!
+#
+# 108
+#
+Failed to synchronize database to disk!
+#
+# 109
+#
+Failed to change log file ownership!
+#
+# 110
+#
+Failed to change log file permissions!
+#
+# 111
+#
+Failed to change database ownership and/or permissions!
+#
+# 112
+#
+Failed to change local socket ownership!
+#
+# 113
+#
+Failed to change local socket permissions!
+#
+# 114
+#
+Failed to switch group!
+#
+# 115
+#
+Failed to switch user!
+#
+# 116
+#
+Response text too long (bug)!
+#
+# 117
+#
+Failed to write database entry!
+#
+# 118
+#
+Failed to delete database entry!
+#
+# 119
+#
+The select() function failed!
+#
+# 120
+#
+Insufficient memory!
+#
+# 121
+#
+Failed to synchronize database to disk!
+#
+# 122 123 124
+#
+DB SET "
+"="
+" ok.
+#
+# 125 ... 132
+#
+" FAILED (invalid arguments)!
+" FAILED (syntax)!
+" FAILED (numeric overflow in size calculation)!
+" FAILED (unsupported db backend)!
+" FAILED (no such entry)!
+" FAILED (insufficient memory)!
+" FAILED (can not write)!
+" FAILED (reason unknown)!
+#
+# 133
+#
+DB GET "
+#
+# 134
+#
+" FAILED (buffer too small)!
+#
+# 135
+#
+DB DEL "
+#
+# 136 ... 144
+#
+DB SYN ok.
+DB SYN FAILED (invalid arguments)!
+DB SYN FAILED (unsupported db backend)!
+DB SYN FAILED (syntax)!
+DB SYN FAILED (security checks for file failed)!
+DB SYN FAILED (can not open file for writing)!
+DB SYN FAILED (can not write)!
+DB SYN FAILED (can not close file)!
+DB SYN FAILED (unknown reason)!
+#
+# 145 ... 151
+#
+(l=
+,u=
+,a=
+) + u=
+ => (l=
+)
+unlimited
+#
+# 152
+#
+p
+#
+# 153
+#
+) + a=
+#
+# 154 155
+#
+Illegal log feature name: "
+"!
+#
+# 156 157 158
+#
+Failed to update account data for user "
+" in class "
+"!
+#
+# 159 160
+#
+Missing class name in reset request!
+Missing user name in reset request!
+#
+# 161 162 163
+#
+Failed to update account data for user "
+" in class "
+"!
+#
+# 164 165
+#
+No such class: "
+"!
+#
+# 166 167
+#
+Not a number: "
+"!
+#
+# 168 169
+#
+Illegal sub-command: "
+"!
+#
+# 170 171
+#
+Logging to file "
+" failed!
+#
+# 172
+#
+Database modification failed!
+#
+# 173
+#
+Database synchronization to disk failed!
+#
+# 174 175
+#
+Failed to change ownership on database file:\n"
+"!
+#
+# 176 177
+#
+Failed to change permissions on database file:\n"
+"!
+#
+# 178
+#
+" (name too long)!
+#
+# 179
+#
+" (file exists, but no socket)!
+#
+# 180
+#
+" (failed to remove old socket)!
+#
+# 181 182
+#
+" (failed to create socket:
+)!
+#
+# 183
+#
+" (failed to bind local
+#
+# 184
+#
+" (failed to listen
+#
+# 185 186
+#
+" (failed to change ownership)!
+" (failed to change permissions)!
+#
+# 187
+#
+Daemon exited due to errors, see log file!
+#
+# 188 189
+#
+Failed to create TCP socket set (math overflow)!
+Failed to create TCP socket set (memory)!
+#
+# 190 191 192 193 194
+#
+Failed to create TCP socket set (socket():
+)!
+Failed to create TCP socket set (bind():
+Failed to create TCP socket set (listen():
+Failed to create TCP socket set (getaddrinfo():
+#
+# 195 196
+#
+Failed to create UDP socket set (math overflow)!
+Failed to create UDP socket set (memory)!
+#
+# 197 ... 201
+#
+Failed to create UDP socket set (socket():
+)!
+Failed to create UDP socket set (bind():
+Failed to create UDP socket set (listen():
+Failed to create UDP socket set (getaddrinfo():
+#
+# 202 ... 209
+#
+" (backend type not supported)!
+" (overflow in size calculation)!
+" (insufficient memory)!
+"\n(not a regular file / not a database / key or value size too large)!
+" (denied by security check)!
+" (failed to open for reading)!
+" (failed to write to file)!
+" (failed to synchronize to disk)!
+#
+# 210 ... 216
+#
+Failed to write initial entry to database (key or value too long)!
+Failed to write initial entry to database (unsupported backend type)!
+Failed to write initial entry to database (insufficient memory)!
+Failed to write initial entry to database (can not open file for writing)!
+Failed to write initial entry to database (can not write to file)!
+Failed to write initial entry to database (can not synchronize to disk)!
+Failed to write initial entry to database (denied by security check)!
+#
+# 217 218
+#
+Failed to change PID file ownership!
+Failed to change PID file permissions!
+$!end
+};
+
+
+
+/** Choices for deny action.
+*/
+static const char * const deny_action_names[] = {
+$!string-table
+remove
+hold
+$!end
+};
+
+
+
+/** Section names in configuration files.
+*/
+static const char * const config_section_names[] = {
+$!string-table
+options
+class
+printer
+$!end
+};
+
+
+
+/** Option names in configuration file.
+*/
+static const char * const config_option_names[] = {
+$!string-table
+#
+# 0 1
+#
+run as user
+run as group
+#
+# 2
+#
+database
+#
+# 3 4 5
+#
+local socket
+local socket backlog
+max local connections
+#
+# 6
+#
+udp port
+#
+# 7 8 9
+#
+tcp port
+tcp port backlog
+max tcp connections
+#
+# 10 11 12
+#
+info allow
+data allow
+admin allow
+#
+# 13 14 15
+#
+user limit
+group limit
+default limit
+#
+# 16
+#
+deny action
+#
+# 17 18
+#
+alias
+class
+#
+# 19 20
+#
+log file
+log features
+#
+# 21 22
+#
+local socket owner
+local socket group
+$!end
+};
+
+
+
+/** Command names in the printqd protocol.
+*/
+static const char * const pqd_command_names[] = {
+$!string-table
+jobstart
+jobend
+start
+end
+filestart
+fileend
+info
+acct-check
+acct-start
+acct-end
+acct-charge
+control
+$!end
+};
+
+
+
+/** Sub-commands of control.
+*/
+static const char * const control_sub_cmds[] = {
+$!string-table
+r$eset
+a$dd
+d$atabase-cleanup
+$!end
+};
+
+
+
+/** Argument names for control requests.
+*/
+static const char * const control_arg_names[] = {
+$!string-table
+c$lass
+u$ser
+p$ages
+$!end
+};
+
+
+
+/** Log feature names.
+*/
+static const char * const log_feature_names[] = {
+$!string-table
+db
+info
+all
+*
+none
+-
+$!end
+};
+
+
+
+static const char * const db_type_names[] = {
+$!string-table
+p
+a
+j
+$!end
+};
+
+
+/** Daemon configuration.
+*/
+static pqd_conf_t conf;
+
+
+
+/** Connections over local socket, stores pqd_l_conn_t.
+ Not NULL in service (service is not run if allocation fails).
+*/
+static dk4_sto_t *s_c_unix = NULL;
+
+
+
+/** Iterator through s_c_unix container.
+ Not NULL in service (service is not run if allocation failes).
+*/
+static dk4_sto_it_t *i_c_unix = NULL;
+
+
+
+/** Container for TCP connections, stores pqd_n_conn_t.
+ Not NULL in service (service is not run if allocation fails).
+*/
+static dk4_sto_t *s_c_tcp = NULL;
+
+
+
+/** Iterator through s_c_tcp container.
+ Not NULL in service (service is not run if allocation fails).
+*/
+static dk4_sto_it_t *i_c_tcp = NULL;
+
+
+
+/** To accept TCP connections.
+ May be NULL in service, if no TCP port number is conigured.
+*/
+static dk4_socket_set_t *ss_tcp = NULL;
+
+
+
+/** For info requests.
+ May be NULL in service, if no UDP port number is configured.
+*/
+static dk4_socket_set_t *ss_udp = NULL;
+
+
+
+/** Database.
+ Not NULL in service (service is not run if allocation fails).
+*/
+static dk4_dbi_t *db = NULL;
+
+
+
+/** Number of options in the options array.
+*/
+static const size_t szoptions = sizeof(options)/sizeof(dk4_option_t);
+
+
+
+/** Current connections on local socket.
+*/
+static size_t con_loc = 0;
+
+
+
+/** Current connections on TCP socket.
+*/
+static size_t con_tcp = 0;
+
+
+
+/** Timestamp of previous log message.
+*/
+static dk4_time_t prev_log_time = (dk4_time_t)0UL;
+
+
+
+/** Listen for incoming UNIX connection requests.
+ Always set in service, service exits when failed to
+ bind local address.
+*/
+static dk4_socket_t so_unix = INVALID_SOCKET;
+
+
+
+/** Program exit code, either EXIT_FAILURE or EXIT_SUCCESS.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+/** Flag: can continue outer (and inner) loop, 1=yes, 0=no, -1=abort.
+*/
+static int ccouter = 1;
+
+
+
+/** Flag: can continue inner loop, 1=yes, 0=no, -1=abort.
+*/
+static int ccinner = 1;
+
+
+
+/** Flag: User and group switching was already done.
+*/
+static int user_switched = 0;
+
+
+
+/** Syslog feature to use.
+*/
+static int syslogf = LOG_LPR;
+
+
+/** Flag: Modified since last synchronization.
+*/
+static int db_modified = 0;
+
+
+/** Flag: Debug mode, process runs in foreground and logs to stderr.
+*/
+static int debug = 0;
+
+
+/** Flag: Previous attempt to log to file failed.
+*/
+static int prev_filelog_failed = 0;
+
+
+/** Flag: Previous database modification failed.
+*/
+static int prev_dbmod_failed = 0;
+
+
+/** Flag: Previous database synchronization to disk failed.
+*/
+static int prev_dbsync_failed = 0;
+
+
+/** UID in previous pass.
+*/
+static uid_t prev_uid = (uid_t)0;
+
+
+
+/** GID in previous pass.
+*/
+static gid_t prev_gid = (gid_t)0;
+
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+#ifdef SIGHUP
+/** Indicator: SIGHUP signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_hup = 0;
+#endif
+
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+/** Pass pointer through.
+ Use of this function is recommended by CERT C coding standard
+ to avoid optimizing out.
+ @param ptr Pointer to pass through.
+ @return The ptr argument.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+
+
+#ifdef SIGHUP
+/** Handler for SIGHUP signal.
+ @param signo Signal number (always SIGHUP, ignored).
+*/
+static
+void
+sig_handler_hup(int signo)
+{
+ *sig_pass_pointer(&sig_had_hup) = 1;
+}
+#endif
+
+
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+
+
+/** Check whether we can continue or must abort due to signal.
+ @param dopipe Flag: Check for SIGPIPE too.
+ @return 1 if we can continue, 0 otherwise.
+*/
+static
+int
+can_continue(int dohup, int dopipe)
+{
+ int back = 1;
+ $? "+ can_continue dohup=%d dopipe=%d", dohup, dopipe
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_int)) { back = 0; }
+#ifdef SIGHUP
+ if (0 != dohup) {
+ if (0 != sig_read_atomic(&sig_had_hup)) { back = 0; }
+ if (1 > ccinner) { back = 0; }
+ }
+#endif
+#ifdef SIGPIPE
+ if (0 != dopipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ if (1 > ccouter) { back = 0; }
+ $? "- can_continue %d", back
+ return back;
+}
+
+
+
+/** Log a multi part message to file, either stderr or log file.
+ @param fipo Output file.
+ @param timebuf Text buffer containing timestamp.
+ @param sourcefile Source file name.
+ @param linebuf Text buffer containing source file line number.
+ @param error Flag: Insert keyword "ERROR:"
+ @param shtime Flag: Show timestamp from buffer.
+ @param shline Flag: Show line number from buffer.
+ @param msgs Array containing the message parts.
+ @param szmsgs Number of elements in msgs array.
+
+*/
+static
+void
+log_file_multipart_message(
+ FILE *fipo,
+ const char *timebuf,
+ const char *sourcefile,
+ const char *linebuf,
+ int error,
+ int shtime,
+ int shline,
+ const char * const *msgs,
+ size_t szmsgs
+)
+{
+ size_t i;
+ $? "+ log_file_multipart_message %u", (unsigned)szmsgs
+ if (0 != shtime) {
+ fputs(printqd_kw[6], fipo);
+ fputs(timebuf, fipo);
+ fputs(printqd_kw[5], fipo);
+ }
+ if (NULL != sourcefile) {
+ fputs(sourcefile, fipo);
+ if (0 != shline) {
+ fputs(printqd_kw[8], fipo);
+ fputs(linebuf, fipo);
+ }
+ fputs(printqd_kw[7], fipo);
+ }
+ if (0 != error) {
+ fputs(printqd_kw[9], fipo);
+ }
+ for (i = 0; i < szmsgs; i++) {
+ if (NULL != msgs[i]) {
+ fputs(msgs[i], fipo);
+ }
+ }
+ fputs(printqd_kw[5], fipo);
+ fflush(fipo);
+ $? "- log_file_multipart_message"
+}
+
+
+
+/** Write a log message consisting of multiple parts.
+ @param sourcefile Configuration file name.
+ @param sourceline Configuration file line number.
+ @param sll Syslog level.
+ @param msgs Array containing the message parts.
+ @param szmsgs Number of elements in msgs array.
+*/
+static
+void
+log_multipart_message(
+ const char *sourcefile,
+ unsigned long sourceline,
+ int sll,
+ int error,
+ char const * const *msgs,
+ size_t szmsgs
+)
+{
+ char timebuf[64];
+ char linebuf[64];
+ FILE *fipo;
+ const char *lfn;
+ dk4_time_t current;
+ int stests = DK4_FOPEN_SC_PRIVILEGED;
+ int shtime = 0;
+ int shline = 0;
+ $? "+ log_multipart_message %u", (unsigned)szmsgs
+ /* Check whether to prepend a timestamp line.
+ */
+ dk4time_get(&current);
+ if (current != prev_log_time) {
+ prev_log_time = current;
+ if (0 != dk4time_as_text_c8(timebuf, sizeof(timebuf), &current, NULL)) {
+ shtime = 1;
+ }
+ }
+
+ /* Check whether to prepend source file name and line number.
+ */
+ if ((NULL != sourcefile) && ((dk4_um_t)0UL != sourceline)) {
+ shline = dk4ma_write_c8_decimal_unsigned(
+ linebuf, sizeof(linebuf), (dk4_um_t)sourceline, 0, NULL
+ );
+ }
+
+ /* Output to log file.
+ */
+ lfn = conf.lname;
+ if (NULL == lfn) { lfn = def_log_file_name; }
+ fipo = dk4fopen_c8(lfn, printqd_kw[10], stests, NULL);
+ if (NULL != fipo) {
+ prev_filelog_failed = 0;
+ log_file_multipart_message(
+ fipo, timebuf, sourcefile, linebuf, error, shtime, shline, msgs, szmsgs
+ );
+ fclose(fipo);
+ } else {
+#if DK4_HAVE_SYSLOG
+ if (0 == prev_filelog_failed) {
+ openlog(printqd_kw[0], LOG_PID, syslogf);
+ syslog(LOG_ERR, "%s%s%s", printqd_kw[170], lfn, printqd_kw[171]);
+ closelog();
+ }
+#endif
+ prev_filelog_failed = 1;
+ }
+
+ /* Output to stderr when debugging.
+ */
+ if (0 != debug) {
+ log_file_multipart_message(
+ stderr, timebuf, sourcefile, linebuf, error, shtime, shline, msgs, szmsgs
+ );
+ }
+
+ /* Output to syslog.
+ */
+ if (LOG_EMERG != sll) {
+#if DK4_HAVE_SYSLOG
+ openlog(printqd_kw[0], LOG_PID, syslogf);
+ if (1 < szmsgs) {
+ if (2 < szmsgs) {
+ if (3 < szmsgs) {
+ if (4 < szmsgs) {
+ if (5 < szmsgs) {
+ if (6 < szmsgs) {
+ if (7 < szmsgs) {
+ if (8 < szmsgs) {
+ syslog(
+ sll, "%s%s%s%s%s%s%s%s%s",
+ ((NULL != msgs[0]) ? (msgs[0]) : (printqd_kw[11])),
+ ((NULL != msgs[1]) ? (msgs[1]) : (printqd_kw[11])),
+ ((NULL != msgs[2]) ? (msgs[2]) : (printqd_kw[11])),
+ ((NULL != msgs[3]) ? (msgs[3]) : (printqd_kw[11])),
+ ((NULL != msgs[4]) ? (msgs[4]) : (printqd_kw[11])),
+ ((NULL != msgs[5]) ? (msgs[5]) : (printqd_kw[11])),
+ ((NULL != msgs[6]) ? (msgs[6]) : (printqd_kw[11])),
+ ((NULL != msgs[7]) ? (msgs[7]) : (printqd_kw[11])),
+ ((NULL != msgs[8]) ? (msgs[8]) : (printqd_kw[11]))
+ );
+ } else {
+ syslog(
+ sll, "%s%s%s%s%s%s%s%s",
+ ((NULL != msgs[0]) ? (msgs[0]) : (printqd_kw[11])),
+ ((NULL != msgs[1]) ? (msgs[1]) : (printqd_kw[11])),
+ ((NULL != msgs[2]) ? (msgs[2]) : (printqd_kw[11])),
+ ((NULL != msgs[3]) ? (msgs[3]) : (printqd_kw[11])),
+ ((NULL != msgs[4]) ? (msgs[4]) : (printqd_kw[11])),
+ ((NULL != msgs[5]) ? (msgs[5]) : (printqd_kw[11])),
+ ((NULL != msgs[6]) ? (msgs[6]) : (printqd_kw[11])),
+ ((NULL != msgs[7]) ? (msgs[7]) : (printqd_kw[11]))
+ );
+ }
+ } else {
+ syslog(
+ sll, "%s%s%s%s%s%s%s",
+ ((NULL != msgs[0]) ? (msgs[0]) : (printqd_kw[11])),
+ ((NULL != msgs[1]) ? (msgs[1]) : (printqd_kw[11])),
+ ((NULL != msgs[2]) ? (msgs[2]) : (printqd_kw[11])),
+ ((NULL != msgs[3]) ? (msgs[3]) : (printqd_kw[11])),
+ ((NULL != msgs[4]) ? (msgs[4]) : (printqd_kw[11])),
+ ((NULL != msgs[5]) ? (msgs[5]) : (printqd_kw[11])),
+ ((NULL != msgs[6]) ? (msgs[6]) : (printqd_kw[11]))
+ );
+ }
+ } else {
+ syslog(
+ sll, "%s%s%s%s%s%s",
+ ((NULL != msgs[0]) ? (msgs[0]) : (printqd_kw[11])),
+ ((NULL != msgs[1]) ? (msgs[1]) : (printqd_kw[11])),
+ ((NULL != msgs[2]) ? (msgs[2]) : (printqd_kw[11])),
+ ((NULL != msgs[3]) ? (msgs[3]) : (printqd_kw[11])),
+ ((NULL != msgs[4]) ? (msgs[4]) : (printqd_kw[11])),
+ ((NULL != msgs[5]) ? (msgs[5]) : (printqd_kw[11]))
+ );
+ }
+ } else {
+ syslog(
+ sll, "%s%s%s%s%s",
+ ((NULL != msgs[0]) ? (msgs[0]) : (printqd_kw[11])),
+ ((NULL != msgs[1]) ? (msgs[1]) : (printqd_kw[11])),
+ ((NULL != msgs[2]) ? (msgs[2]) : (printqd_kw[11])),
+ ((NULL != msgs[3]) ? (msgs[3]) : (printqd_kw[11])),
+ ((NULL != msgs[4]) ? (msgs[4]) : (printqd_kw[11]))
+ );
+ }
+ } else {
+ syslog(
+ sll, "%s%s%s%s",
+ ((NULL != msgs[0]) ? (msgs[0]) : (printqd_kw[11])),
+ ((NULL != msgs[1]) ? (msgs[1]) : (printqd_kw[11])),
+ ((NULL != msgs[2]) ? (msgs[2]) : (printqd_kw[11])),
+ ((NULL != msgs[3]) ? (msgs[3]) : (printqd_kw[11]))
+ );
+ }
+ } else {
+ syslog(
+ sll, "%s%s%s",
+ ((NULL != msgs[0]) ? (msgs[0]) : (printqd_kw[11])),
+ ((NULL != msgs[1]) ? (msgs[1]) : (printqd_kw[11])),
+ ((NULL != msgs[2]) ? (msgs[2]) : (printqd_kw[11]))
+ );
+ }
+ } else {
+ syslog(
+ sll, "%s%s",
+ ((NULL != msgs[0]) ? (msgs[0]) : (printqd_kw[11])),
+ ((NULL != msgs[1]) ? (msgs[1]) : (printqd_kw[11]))
+ );
+ }
+ } else {
+ syslog(
+ sll, "%s",
+ ((NULL != msgs[0]) ? (msgs[0]) : (printqd_kw[11]))
+ );
+ }
+ closelog();
+#endif
+ }
+ $? "- log_multipart_message"
+}
+
+
+
+static
+void
+log_1(
+ const char *sourcefile,
+ unsigned long sourceline,
+ int sll,
+ int error,
+ size_t i1
+)
+{
+ const char *msgs[2];
+ $? "+ log_1"
+ msgs[0] = printqd_kw[i1];
+ msgs[1] = NULL;
+ log_multipart_message(sourcefile, sourceline, sll, error, msgs, 1);
+ $? "- log_1"
+}
+
+
+
+static
+void
+log_3(
+ const char *sourcefile,
+ unsigned long sourceline,
+ int sll,
+ int error,
+ size_t i1,
+ size_t i2,
+ const char *s1
+)
+{
+ const char *msgs[4];
+ $? "+ log_3"
+ msgs[0] = printqd_kw[i1];
+ msgs[1] = s1;
+ msgs[2] = printqd_kw[i2];
+ msgs[3] = NULL;
+ log_multipart_message(sourcefile, sourceline, sll, error, msgs, 3);
+ $? "- log_3"
+}
+
+
+
+static
+void
+log_5(
+ const char *sourcefile,
+ unsigned long sourceline,
+ int sll,
+ int error,
+ size_t i1,
+ size_t i2,
+ size_t i3,
+ const char *s1,
+ const char *s2
+)
+{
+ const char *msgs[6];
+ $? "+ log_5"
+ msgs[0] = printqd_kw[i1];
+ msgs[1] = s1;
+ msgs[2] = printqd_kw[i2];
+ msgs[3] = s2;
+ msgs[4] = printqd_kw[i3];
+ msgs[5] = NULL;
+ log_multipart_message(sourcefile, sourceline, sll, error, msgs, 5);
+ $? "- log_5"
+}
+
+
+
+/** Set database entry (create or modify).
+ @param db Database to modify.
+ @param k Key.
+ @param v Value.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dbi_set(
+ dk4_dbi_t *db,
+ const char *k,
+ const char *v,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er;
+ int back = 0;
+
+ dk4error_init(&er);
+ back = dk4dbi_c8_set(db, k, v, &er);
+ dk4error_copy(erp, &er);
+ db_modified = 1;
+ if (0 != back) {
+ prev_dbmod_failed = 0;
+ if (0 != conf.ldb) {
+ log_5(NULL, 0UL, LOG_EMERG, 0, 122, 123, 124, k, v);
+ }
+ } else {
+#if DK4_HAVE_SYSLOG
+ if (0 == prev_dbmod_failed) {
+ openlog(printqd_kw[0], LOG_PID, syslogf);
+ syslog(LOG_ERR, "%s", printqd_kw[172]);
+ closelog();
+ }
+#endif
+ prev_dbmod_failed = 1;
+ switch (er.ec) {
+ case DK4_E_INVALID_ARGUMENTS : {
+ log_5(NULL, 0UL, LOG_EMERG, 1, 122, 123, 125, k, v);
+ } break;
+ case DK4_E_SYNTAX : {
+ log_5(NULL, 0UL, LOG_EMERG, 1, 122, 123, 126, k, v);
+ } break;
+ case DK4_E_MATH_OVERFLOW : {
+ log_5(NULL, 0UL, LOG_EMERG, 1, 122, 123, 127, k, v);
+ } break;
+ case DK4_E_NOT_SUPPORTED : {
+ log_5(NULL, 0UL, LOG_EMERG, 1, 122, 123, 128, k, v);
+ } break;
+ case DK4_E_NOT_FOUND : {
+ log_5(NULL, 0UL, LOG_EMERG, 1, 122, 123, 129, k, v);
+ } break;
+ case DK4_E_MEMORY_ALLOCATION_FAILED : {
+ log_5(NULL, 0UL, LOG_EMERG, 1, 122, 123, 130, k, v);
+ } break;
+ case DK4_E_WRITE_FAILED : {
+ log_5(NULL, 0UL, LOG_EMERG, 1, 122, 123, 131, k, v);
+ } break;
+ default : {
+ log_5(NULL, 0UL, LOG_EMERG, 1, 122, 123, 132, k, v);
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+/** Retrieve database entry.
+ @param db Database to retrieve data from.
+ @param k Key text.
+ @param vbuf Buffer for text value.
+ @param vsz Size of buffer.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dbi_get(
+ dk4_dbi_t *db,
+ const char *k,
+ char *vbuf,
+ size_t vsz,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er;
+ int back = 0;
+
+ dk4error_init(&er);
+ back = dk4dbi_c8_get(db, k, vbuf, vsz, &er);
+ dk4error_copy(erp, &er);
+ if (0 != back) {
+ if (0 != conf.ldb) {
+ log_5(NULL, 0UL, LOG_EMERG, 0, 133, 123, 124, k, vbuf);
+ }
+ } else {
+ switch (er.ec) {
+ case DK4_E_INVALID_ARGUMENTS : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 133, 125, k);
+ } break;
+ case DK4_E_MATH_OVERFLOW : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 133, 127, k);
+ } break;
+ case DK4_E_NOT_SUPPORTED : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 133, 128, k);
+ } break;
+ case DK4_E_NOT_FOUND : {
+ if (0 != conf.ldb) {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 133, 129, k);
+ }
+ } break;
+ case DK4_E_BUFFER_TOO_SMALL : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 133, 134, k);
+ } break;
+ default : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 133, 132, k);
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+/** Delete DB entry if it exists.
+ @param db Database to modify.
+ @param k Key.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dbi_del(
+ dk4_dbi_t *db,
+ const char *k,
+ dk4_er_t *erp
+)
+{
+ dk4_er_t er;
+ int back = 0;
+
+ dk4error_init(&er);
+ back = dk4dbi_c8_del(db, k, &er);
+ dk4error_copy(erp, &er);
+ db_modified = 1;
+ if (0 != back) {
+ prev_dbmod_failed = 0;
+ if (0 != conf.ldb) {
+ log_3(NULL, 0UL, LOG_EMERG, 0, 135, 124, k);
+ }
+ } else {
+ if (DK4_E_NOT_FOUND != er.ec) {
+#if DK4_HAVE_SYSLOG
+ if (0 == prev_dbmod_failed) {
+ openlog(printqd_kw[0], LOG_PID, syslogf);
+ syslog(LOG_ERR, "%s", printqd_kw[172]);
+ closelog();
+ }
+#endif
+ prev_dbmod_failed = 1;
+ }
+ switch (er.ec) {
+ case DK4_E_INVALID_ARGUMENTS : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 135, 125, k);
+ } break;
+ case DK4_E_SYNTAX : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 135, 126, k);
+ } break;
+ case DK4_E_MATH_OVERFLOW : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 135, 127, k);
+ } break;
+ case DK4_E_NOT_SUPPORTED : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 135, 128, k);
+ } break;
+ case DK4_E_WRITE_FAILED : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 135, 131, k);
+ } break;
+ case DK4_E_NOT_FOUND : {
+ if (0 != conf.ldb) {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 135, 129, k);
+ }
+ } break;
+ default : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 135, 132, k);
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+/** Synchronize database modifications to disk, if any.
+ @param db Database.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dbi_sync(dk4_dbi_t *db, dk4_er_t *erp)
+{
+ dk4_er_t er;
+ int back = 0;
+ if (0 != db_modified) {
+ dk4error_init(&er);
+ back = dk4dbi_sync(db, &er);
+ dk4error_copy(erp, &er);
+ if (0 != back) {
+ db_modified = 0;
+ prev_dbsync_failed = 0;
+ if (0 != conf.ldb) {
+ log_1(NULL, 0UL, LOG_EMERG, 0, 136);
+ }
+ } else {
+#if DK4_HAVE_SYSLOG
+ if (0 == prev_dbsync_failed) {
+ openlog(printqd_kw[0], LOG_PID, syslogf);
+ syslog(LOG_ERR, "%s", printqd_kw[173]);
+ closelog();
+ }
+#endif
+ prev_dbsync_failed = 1;
+ switch (er.ec) {
+ case DK4_E_INVALID_ARGUMENTS : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 137);
+ } break;
+ case DK4_E_NOT_SUPPORTED : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 138);
+ } break;
+ case DK4_E_SYNTAX : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 139);
+ } break;
+ case DK4_E_SEC_CHECK : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 140);
+ } break;
+ case DK4_E_OPEN_WRITE_FAILED : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 141);
+ } break;
+ case DK4_E_WRITE_FAILED : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 142);
+ } break;
+ case DK4_E_CLOSE_FAILED : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 143);
+ } break;
+ default : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 144);
+ } break;
+ }
+ }
+ } else {
+ back = 1;
+ }
+ return back;
+}
+
+
+
+/** Compare two pqd_l_conn_t structures.
+ @param l Left object.
+ @param r Right object.
+ @param cr Comparison criteria, ignored.
+ @return Comparison result.
+*/
+static
+int
+compare_pqd_l_conn_t(const void *l, const void *r, int cr)
+{
+ const pqd_l_conn_t *pl;
+ const pqd_l_conn_t *pr;
+ int back = 0;
+ $? "+ compare_pqd_l_conn_t"
+ if (NULL != l) {
+ if (NULL != r) {
+ pl = (const pqd_l_conn_t *)l;
+ pr = (const pqd_l_conn_t *)r;
+ if (pl->sock > pr->sock) {
+ back = 1;
+ } else {
+ if (pl->sock < pr->sock) {
+ back = -1;
+ }
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != r) { back = -1; }
+ }
+ $? "- compare_pqd_l_conn_t %d", back
+ return back;
+}
+
+
+
+/** Compare two pqd_n_conn_t structures.
+ @param l Left object.
+ @param r Right object.
+ @param cr Comparison criteria, ignored.
+ @return Comparison result.
+*/
+static
+int
+compare_pqd_n_conn_t(const void *l, const void *r, int cr)
+{
+ const pqd_n_conn_t *pl;
+ const pqd_n_conn_t *pr;
+ int back = 0;
+ $? "+ compare_pqd_n_conn_t"
+ if (NULL != l) {
+ if (NULL != r) {
+ pl = (const pqd_n_conn_t *)l;
+ pr = (const pqd_n_conn_t *)r;
+ if (pl->sock > pr->sock) {
+ back = 1;
+ } else {
+ if (pl->sock < pr->sock) {
+ back = -1;
+ }
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != r) { back = -1; }
+ }
+ $? "- compare_pqd_n_conn_t %d", back
+ return back;
+}
+
+
+
+/** Delete a limit structure (release memory).
+ @param ptr Limit to delete.
+*/
+static
+void
+limit_delete(pqd_limit_t *ptr)
+{
+ $? "+ limit_delete %s", TR_8PTR(ptr)
+ if (NULL != ptr) { $? ". name = \"%s\"", TR_8STR(ptr->name)
+ dk4mem_release(ptr->name);
+ ptr->limit = (dk4_um_t)0UL;
+ dk4mem_free(ptr);
+ }
+ $? "- limit_delete"
+}
+
+
+
+/** Create limit structure (allocate memory).
+ @param name User or group name.
+ @param max Maximum page number.
+ @return Valid pointer on success, NULL on error.
+*/
+static
+pqd_limit_t *
+limit_new(const char *name, dk4_um_t max)
+{
+ pqd_limit_t *back = NULL;
+ $? "+ limit_new \"%s\" %lu", TR_8STR(name), (unsigned long)max
+ if (NULL != name) { $? ". name ok"
+ back = dk4mem_new(pqd_limit_t,1,NULL);
+ if (NULL != back) { $? ". allocation ok"
+ back->limit = max;
+ back->name = dk4str8_dup(name, NULL);
+ if (NULL == back->name) { $? "! allocation (2)"
+ limit_delete(back);
+ back = NULL;
+ }
+ }
+#if TRACE_DEBUG
+ else { $? "! allocation (1)"
+ }
+#endif
+ } $? "- limit_new %s", TR_8PTR(back)
+ return back;
+}
+
+
+
+/** Compare limit structures.
+ @param l Left object.
+ @param r Right object.
+ @param cr Comparison criteria (0=limit/limit, 1=limit/name).
+ @return Comparison result.
+*/
+static
+int
+limit_compare(const void *l, const void *r, int cr)
+{
+ const pqd_limit_t *pl;
+ const pqd_limit_t *pr;
+ $? "+ limit_compare"
+ int back = 0;
+ if (NULL != l) {
+ if (NULL != r) {
+ pl = (const pqd_limit_t *)l;
+ switch (cr) {
+ case 1: {
+ if (NULL != pl->name) {
+ back = strcmp(pl->name, (const char *)r);
+ if (-1 > back) { back = -1; }
+ if ( 1 < back) { back = 1; }
+ } else { back = -1; }
+ } break;
+ default: {
+ pr = (const pqd_limit_t *)r;
+ if (NULL != pl->name) {
+ if (NULL != pr->name) {
+ back = strcmp(pl->name, pr->name);
+ if (-1 > back) { back = -1; }
+ if ( 1 < back) { back = 1; }
+ } else { back = 1; }
+ } else {
+ if (NULL != pr->name) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if (NULL != r) { back = -1; }
+ } $? "- limit_compare %d", back
+ return back;
+}
+
+
+
+/** Delete all limits in a storage.
+ @param it Storage iterator.
+*/
+static
+void
+limit_all_delete(dk4_sto_it_t *it)
+{
+ pqd_limit_t *ptr;
+
+ $? "+ limit_all_delete %s", TR_8PTR(it)
+ dk4sto_it_reset(it);
+ do {
+ ptr = (pqd_limit_t *)dk4sto_it_next(it);
+ if (NULL != ptr) {
+ limit_delete(ptr);
+ }
+ } while (NULL != ptr);
+ dk4sto_it_close(it);
+ $? "- limit_all_delete"
+}
+
+
+
+/** Delete a class structure (release memory).
+ @param ptr Class to delete.
+*/
+static
+void
+class_delete(pqd_class_t *ptr)
+{
+ $? "+ class_delete %s", TR_8PTR(ptr)
+ if (NULL != ptr) { $? ". ptr ok"
+ dk4mem_release(ptr->name);
+ if (NULL != ptr->i_u) {
+ limit_all_delete(ptr->i_u);
+ } ptr->i_u = NULL;
+ if (NULL != ptr->s_u) {
+ dk4sto_close(ptr->s_u);
+ } ptr->s_u = NULL;
+ if (NULL != ptr->i_g) {
+ limit_all_delete(ptr->i_g);
+ } ptr->i_g = NULL;
+ if (NULL != ptr->s_g) {
+ dk4sto_close(ptr->s_g);
+ } ptr->s_g = NULL;
+ ptr->dl = (dk4_um_t)0UL;
+ ptr->da = 0;
+ dk4mem_free(ptr);
+ }
+#if TRACE_DEBUG
+ else { $? "! ptr"
+ }
+#endif
+ $? "- class_delete"
+}
+
+
+
+/** Delete all classes from a containter.
+ @param it Container iterator.
+*/
+static
+void
+class_all_delete(dk4_sto_it_t *it)
+{
+ pqd_class_t *ptr;
+ $? "+ class_all_delete %s", TR_8PTR(it)
+ dk4sto_it_reset(it);
+ do {
+ ptr = (pqd_class_t *)dk4sto_it_next(it);
+ if (NULL != ptr) {
+ class_delete(ptr);
+ }
+ } while (NULL != ptr);
+ dk4sto_it_close(it);
+ $? "- class_all_delete"
+}
+
+
+
+/** Create a class structure (allocate memory).
+ @param n Class name.
+ @return Valid pointer on success, NULL on error.
+*/
+static
+pqd_class_t *
+class_new(const char *n)
+{
+ pqd_class_t *back = NULL;
+ int ok = 0;
+ $? "+ class_new \"%s\"", TR_8STR(n)
+ if (NULL != n) { $? ". n ok"
+ back = dk4mem_new(pqd_class_t,1,NULL);
+ if (NULL != back) {
+ back->s_u = NULL;
+ back->i_u = NULL;
+ back->s_g = NULL;
+ back->i_g = NULL;
+ back->dl = (dk4_um_t)0UL;
+ back->da = 0;
+ back->hdl = 0;
+ back->name = dk4str8_dup(n, NULL);
+ if (NULL != back->name) {
+ back->s_u = dk4sto_open(NULL);
+ if (NULL != back->s_u) {
+ dk4sto_set_comp(back->s_u, limit_compare, 0);
+ back->i_u = dk4sto_it_open(back->s_u, NULL);
+ if (NULL != back->i_u) {
+ back->s_g = dk4sto_open(NULL);
+ if (NULL != back->s_g) {
+ dk4sto_set_comp(back->s_g, limit_compare, 0);
+ back->i_g = dk4sto_it_open(back->s_g, NULL);
+ if (NULL != back->i_g) {
+ ok = 1; $? ". allocations ok"
+ }
+#if TRACE_DEBUG
+ else { $? "! allocation (6)"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! allocation (5)"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! allocation (4)"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! allocation (3)"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! allocation (2)"
+ }
+#endif
+ if (0 == ok) { $? "! allocations"
+ class_delete(back);
+ back = NULL;
+ }
+ }
+#if TRACE_DEBUG
+ else { $? "! allocation (1)"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! n"
+ }
+#endif
+ $? "- class_new %s", TR_8PTR(back)
+ return back;
+}
+
+
+
+/** Compare classes.
+ @param l Left object.
+ @param r Right object.
+ @param cr Comparison criteria (0=class/class, 1=class/name).
+ @return Comparison result.
+*/
+static
+int
+class_compare(const void *l, const void *r, int cr)
+{
+ const pqd_class_t *pl;
+ const pqd_class_t *pr;
+ int back = 0;
+ $? "+ class_compare"
+ if (NULL != l) {
+ if (NULL != r) {
+ pl = (const pqd_class_t *)l;
+ switch (cr) {
+ case 1: {
+ if (NULL != pl->name) {
+ back = strcmp(pl->name, (const char *)r);
+ if (-1 > back) { back = -1; }
+ if ( 1 < back) { back = 1; }
+ } else { back = -1; }
+ } break;
+ default: {
+ pr = (const pqd_class_t *)r;
+ if (NULL != pl->name) {
+ if (NULL != pr->name) {
+ back = strcmp(pl->name, pr->name);
+ if (-1 > back) { back = -1; }
+ if ( 1 < back) { back = 1; }
+ } else { back = 1; }
+ } else {
+ if (NULL != pr->name) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if (NULL != r) { back = -1; }
+ } $? "- class_compare %d", back
+ return back;
+}
+
+
+
+/** Delete a printer structure (release memory).
+ @param ptr Printer structure to delete.
+*/
+static
+void
+printer_delete(pqd_printer_t *ptr)
+{
+ $? "+ printer_delete %s", TR_8PTR(ptr)
+ if (NULL != ptr) { $? ". name = \"%s\"", TR_8STR(ptr->name)
+ dk4mem_release(ptr->name);
+ ptr->cl = NULL;
+ dk4mem_free(ptr);
+ }
+ $? "- printer_delete"
+}
+
+
+
+/** Create printer structure (allocate memory).
+ @param n Printer name.
+ @return Valid pointer on success, NULL on error.
+*/
+static
+pqd_printer_t *
+printer_new(const char *n)
+{
+ pqd_printer_t *back = NULL;
+ $? "+ printer_new \"%s\"", TR_8STR(n)
+ if (NULL != n) {
+ back = dk4mem_new(pqd_printer_t,1,NULL);
+ if (NULL != back) {
+ back->cl = NULL;
+ back->name = dk4str8_dup(n,NULL);
+ if (NULL == back->name) { $? "! allocation (2)"
+ printer_delete(back);
+ back = NULL;
+ }
+ }
+#if TRACE_DEBUG
+ else { $? "! allocation (1)"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! n"
+ }
+#endif
+ $? "- printer_new %s", TR_8PTR(back)
+ return back;
+}
+
+
+
+/** Compare two printers.
+ @param l Left object.
+ @param r Right object.
+ @param cr Comparison criteria (0=printer/printer, 1=printer/name).
+ @return Comparison result.
+*/
+static
+int
+printer_compare(const void *l, const void *r, int cr)
+{
+ const pqd_printer_t *pl;
+ const pqd_printer_t *pr;
+ int back = 0;
+ $? "+ printer_compare"
+ if (NULL != l) {
+ if (NULL != r) {
+ pl = (const pqd_printer_t *)l;
+ switch (cr) {
+ case 1: {
+ if (NULL != pl->name) {
+ back = strcmp(pl->name, (const char *)r);
+ if (-1 > back) { back = -1; }
+ if ( 1 < back) { back = 1; }
+ } else { back = -1; }
+ } break;
+ default: {
+ pr = (const pqd_printer_t *)r;
+ if (NULL != pl->name) {
+ if (NULL != pr->name) {
+ back = strcmp(pl->name, pr->name);
+ if (-1 > back) { back = -1; }
+ if ( 1 < back) { back = 1; }
+ } else { back = 1; }
+ } else {
+ if (NULL != pr->name) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if (NULL != r) { back = -1; }
+ } $? "- printer_compare %d", back
+ return back;
+}
+
+
+
+/** Delete all printers from a container.
+ @param it Container iterator.
+*/
+static
+void
+printer_all_delete(dk4_sto_it_t *it)
+{
+ pqd_printer_t *ptr;
+ $? "+ printer_all_delete %s", TR_8PTR(it)
+ dk4sto_it_reset(it);
+ do {
+ ptr = (pqd_printer_t *)dk4sto_it_next(it);
+ if (NULL != ptr) {
+ printer_delete(ptr);
+ }
+ } while (NULL != ptr);
+ dk4sto_it_close(it);
+ $? "- printer_all_delete"
+}
+
+
+
+/** Delete printer alias structure (release memory).
+ @param ptr Structure to delete.
+*/
+static
+void
+printer_alias_delete(pqd_printer_alias_t *ptr)
+{
+ $? "+ printer_alias_delete %s", TR_8PTR(ptr)
+ if (NULL != ptr) { $? ". name = \"%s\"", TR_8STR(ptr->name)
+ dk4mem_release(ptr->name);
+ ptr->pr = NULL;
+ dk4mem_free(ptr);
+ }
+ $? "- printer_alias_delete"
+}
+
+
+
+/** Create printer alias structure (allocate memory).
+ @param n Alias name.
+ @param pr Printer for alias.
+ @return Valid pointer on success, NULL on error.
+*/
+static
+pqd_printer_alias_t *
+printer_alias_new(const char *n, pqd_printer_t *pr)
+{
+ pqd_printer_alias_t *back = NULL;
+ $? "+ printer_alias_new \"%s\" %s", TR_8STR(n), TR_8PTR(pr)
+ if ((NULL != n) && (NULL != pr)) {
+ back = dk4mem_new(pqd_printer_alias_t,1,NULL);
+ if (NULL != back) {
+ back->pr = pr;
+ back->name = dk4str8_dup(n,NULL);
+ if (NULL == back->name) {
+ printer_alias_delete(back);
+ back = NULL;
+ }
+#if TRACE_DEBUG
+ else { $? "! allocation (2)"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! allocation (1)"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! n or pr"
+ }
+#endif
+ $? "- printer_alias_new %s", TR_8PTR(back)
+ return back;
+}
+
+
+
+/** Compare printer alias structures.
+ @param l Left object.
+ @param r Right object.
+ @param cr Comparison criteria (0=alias/alias, 1=alias/name).
+ @return Comparison result.
+*/
+static
+int
+printer_alias_compare(const void *l, const void *r, int cr)
+{
+ const pqd_printer_alias_t *pl;
+ const pqd_printer_alias_t *pr;
+ int back = 0;
+ $? "+ printer_alias_compare"
+ if (NULL != l) {
+ if (NULL != r) {
+ pl = (const pqd_printer_alias_t *)l;
+ switch (cr) {
+ case 1: {
+ if (NULL != pl->name) {
+ back = strcmp(pl->name, (const char *)r);
+ if (-1 > back) { back = -1; }
+ if ( 1 < back) { back = 1; }
+ } else { back = -1; }
+ } break;
+ default: {
+ pr = (const pqd_printer_alias_t *)r;
+ if (NULL != pl->name) {
+ if (NULL != pr->name) {
+ back = strcmp(pl->name, pr->name);
+ if (-1 > back) { back = -1; }
+ if ( 1 < back) { back = 1; }
+ } else { back = 1; }
+ } else {
+ if (NULL != pr->name) { back = -1; }
+ }
+ } break;
+ }
+ } else { back = 1; }
+ } else {
+ if (NULL != r) { back = -1; }
+ } $? "- printer_alias_compare %d", back
+ return back;
+}
+
+
+
+/** Delete all printer alias structures in a container.
+ @param it Container iterator.
+*/
+static
+void
+printer_alias_all_delete(dk4_sto_it_t *it)
+{
+ pqd_printer_alias_t *ptr;
+ $? "+ printer_alias_all_delete %s", TR_8PTR(it)
+ dk4sto_it_reset(it);
+ do {
+ ptr = (pqd_printer_alias_t *)dk4sto_it_next(it);
+ if (NULL != ptr) {
+ printer_alias_delete(ptr);
+ }
+ } while (NULL != ptr);
+ dk4sto_it_close(it);
+ $? "- printer_alias_all_delete"
+}
+
+
+
+/** Initialize configuration before reading configuration file.
+*/
+static
+void
+config_init(void)
+{
+ $? "+ config_init"
+ DK4_MEMRES(&conf, sizeof(conf));
+ conf.sname = NULL;
+ conf.dname = NULL;
+ conf.lname = NULL;
+ conf.s_c = NULL;
+ conf.i_c = NULL;
+ conf.s_p = NULL;
+ conf.i_p = NULL;
+ conf.s_a = NULL;
+ conf.i_a = NULL;
+ conf.s_ai = NULL;
+ conf.i_ai = NULL;
+ conf.s_ad = NULL;
+ conf.i_ad = NULL;
+ conf.s_aa = NULL;
+ conf.i_aa = NULL;
+ conf.m_loc = 0; /* Maximum 0 means unlimited number of connections. */
+ conf.m_tcp = 0; /* Maximum 0 means unlimited number of connections. */
+ conf.uid = 0;
+ conf.gid = 0;
+ conf.suid = 0;
+ conf.sgid = 0;
+ conf.slbl = 5;
+ conf.snbl = 5;
+ conf.iglo = 0;
+ conf.dglo = 0;
+ conf.aglo = 0;
+ conf.ptcp = 0;
+ conf.pudp = 0;
+ conf.linf = 0;
+ conf.ldb = 0;
+ $? "- config_init"
+}
+
+
+
+/** Allocate internal structures for configuration.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+config_allocate(void)
+{
+ int back = 0;
+ $? "+ config_allocate"
+ conf.s_c = dk4sto_open(NULL);
+ conf.s_p = dk4sto_open(NULL);
+ conf.s_a = dk4sto_open(NULL);
+ conf.s_ai = dk4sto_open(NULL);
+ conf.s_ad = dk4sto_open(NULL);
+ conf.s_aa = dk4sto_open(NULL);
+ if ((NULL != conf.s_ai) && (NULL != conf.s_ad) && (NULL != conf.s_aa)) {
+ if ((NULL != conf.s_c) && (NULL != conf.s_p) && (NULL != conf.s_a)) {
+ dk4sto_set_comp(conf.s_c, class_compare, 0);
+ dk4sto_set_comp(conf.s_p, printer_compare, 0);
+ dk4sto_set_comp(conf.s_a, printer_alias_compare, 0);
+ dk4sto_set_comp(conf.s_ai, dk4socket_allowed_peer_compare, 0);
+ dk4sto_set_comp(conf.s_ad, dk4socket_allowed_peer_compare, 0);
+ dk4sto_set_comp(conf.s_aa, dk4socket_allowed_peer_compare, 0);
+ conf.i_c = dk4sto_it_open(conf.s_c, NULL);
+ conf.i_p = dk4sto_it_open(conf.s_p, NULL);
+ conf.i_a = dk4sto_it_open(conf.s_a, NULL);
+ conf.i_ai = dk4sto_it_open(conf.s_ai, NULL);
+ conf.i_ad = dk4sto_it_open(conf.s_ad, NULL);
+ conf.i_aa = dk4sto_it_open(conf.s_aa, NULL);
+ if ((NULL != conf.i_ai) && (NULL != conf.i_ad) && (NULL != conf.i_aa)) {
+ if ((NULL != conf.i_c) && (NULL != conf.i_p) && (NULL != conf.i_a)) {
+ back = 1;
+ }
+#if TRACE_DEBUG
+ else { $? "! allocation (4)"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! allocation (3)"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! allocation (2)"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! allocation (1)"
+ }
+#endif
+ $? "- config_allocate %d", back
+ return back;
+}
+
+
+
+/** Set backlog variable.
+ @param iptr Address of backlog number variable.
+ @param pv Text containing the number.
+ @param fn File name for diagnostics.
+ @param lineno Line number.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+set_backlog(int *iptr, char *pv, const char *fn, unsigned long lineno)
+{
+ const char *ep = NULL;
+ int i = 0;
+ int back = 0;
+ int res = 0;
+ $? "+ set_backlog %s \"%s\"", TR_8PTR(iptr), TR_8STR(pv)
+ res = dk4ma_input_c8_dec_int(&i, pv, &ep, 1, NULL);
+ if (0 != res) {
+ if (0 < i) {
+ *iptr = i;
+ back = 1;
+ } else { $? "! not positive"
+ /* ERROR: Must be positive */
+ log_1(fn, lineno, LOG_EMERG, 1, 15);
+ }
+ } else { $? "! not integer"
+ /* ERROR: Not an integer number */
+ log_5(fn, lineno, LOG_EMERG, 1, 12, 13, 14, pv, ep);
+ } $? "- set_backlog %d", back
+ return back;
+}
+
+
+
+/** Set maximum number of connections.
+ @param pmaxconn Address of result variable.
+ @param pv Text containing the number.
+ @param fn File name for diagnostics.
+ @param lineno Line number.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+set_max_connections(
+ size_t *pmaxconn,
+ char *pv,
+ const char *fn,
+ unsigned long lineno
+)
+{
+ const char *ep = NULL;
+ size_t sz = 0;
+ int back = 0;
+ int res = 0;
+ $? "+ set_max_connections %s \"%s\"", TR_8PTR(pmaxconn), TR_8STR(pv)
+ res = dk4ma_input_c8_dec_size_t(&sz, pv, &ep, 1, NULL);
+ if (0 != res) {
+ *pmaxconn = sz;
+ back = 1;
+ } else { $? "! not a size"
+ /* ERROR: Not a size specification */
+ log_5(fn, lineno, LOG_EMERG, 1, 16, 17, 18, pv, ep);
+ }
+ $? "- set_max_connections %d", back
+ return back;
+}
+
+
+
+/** Set port number from text.
+ @param ppn Address of port number variable.
+ @param pv Text containing the number.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+set_port_number(
+ unsigned short *ppn,
+ char *pv,
+ const char *fn,
+ unsigned long lineno
+)
+{
+ const char *ep = NULL;
+ unsigned short pn = 0;
+ int back = 0;
+ int res = 0;
+ $? "+ set_port_number %s \"%s\"", TR_8PTR(ppn), TR_8STR(pv)
+ res = dk4ma_input_c8_dec_ushort(&pn, pv, &ep, 1, NULL);
+ if (0 != res) {
+ if (0 < pn) {
+ *ppn = pn;
+ back = 1;
+ } else { $? "! 0 not allowed"
+ /* ERROR: Port number must not be 0 */
+ log_1(fn, lineno, LOG_EMERG, 1, 22);
+ }
+ } else { $? "! not unsigned short"
+ /* ERROR: Not a 16 bit unsigned number */
+ log_5(fn, lineno, LOG_EMERG, 1, 19, 20, 21, pv, ep);
+ }
+ $? "- set_port_number %d", back
+ return back;
+}
+
+
+
+/** Add address to list of allowed hosts.
+ @param s Containter of allowed peers.
+ @param i Iterator through container.
+ @param iptr Address of global flag variable.
+ @param str Text containing the address.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+allow_hosts(
+ dk4_sto_t *s,
+ dk4_sto_it_t *i,
+ int *iptr,
+ char *str,
+ const char *filename,
+ unsigned long lineno
+)
+{
+ dk4_allowed_peer_t ap;
+ dk4_allowed_peer_t *pap;
+ char *px = NULL;
+ int res = 0;
+ int back = 0;
+ $? "+ allow_hosts %s %s %s \"%s\"", TR_8PTR(s), TR_8PTR(i), TR_8PTR(iptr), TR_8STR(str)
+ px = dk4str8_next(str, NULL);
+ if (NULL == px) {
+ if (0 == strcmp(str, printqd_kw[2])) {
+ *iptr = 1;
+ back = 1;
+ } else {
+ DK4_MEMRES(&ap, sizeof(ap));
+ res = dk4socket_c8_get_allowed_peer(&ap, str, NULL);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ pap = dk4mem_new(dk4_allowed_peer_t,1,NULL);
+ if (NULL != pap) {
+ DK4_MEMCPY(pap, &ap, sizeof(ap));
+ if (0 != dk4sto_add(s, pap, NULL)) {
+ back = 1;
+ } else { $? "! storage add"
+ dk4mem_free(pap);
+ /* ERROR: Memory */
+ log_1(filename, lineno, LOG_EMERG, 1, 27);
+ }
+ } else { $? "! allocation"
+ /* ERROR: Memory */
+ log_1(filename, lineno, LOG_EMERG, 1, 27);
+ }
+ } else { $? "! not a peer definition"
+ /* ERROR: Syntax, not a peer definition */
+ log_3(filename, lineno, LOG_EMERG, 1, 25, 26, str);
+ }
+ }
+ } else { $? "! unexpected text"
+ /* ERROR: Unexpected text */
+ log_3(filename, lineno, LOG_EMERG, 1, 23, 24, px);
+ }
+ $? "- allow_hosts %d", back
+ return back;
+}
+
+
+
+/** Obtain limit value from text.
+ @param plim Address of limit variable to set.
+ @param src Text containing the limit.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+get_limit_value(dk4_um_t *plim, char *src, const char *fn, unsigned long lineno)
+{
+ const char *ep = NULL;
+ dk4_um_t value = (dk4_um_t)0UL;
+ int back = 0;
+ int res = 0;
+ $? "+ get_limit_value %s \"%s\"", TR_8PTR(plim), TR_8STR(src)
+ if (0 == strcmp(src, printqd_kw[3])) {
+ *plim = DK4_UM_MAX;
+ back = 1;
+ } else {
+ if (0 == strcmp(src, printqd_kw[4])) {
+ *plim = value;
+ back = 1;
+ } else {
+ res = dk4ma_input_c8_dec_dk4_um_t(&value, src, &ep, 1, NULL);
+ if (0 != res) {
+ *plim = value;
+ back = 1;
+ } else { $? "! not an unsigned number"
+ /* ERROR: Syntax, not an unsigned number */
+ log_5(fn, lineno, LOG_EMERG, 1, 28, 29, 30, src, ep);
+ }
+ }
+ }
+ $? "- get_limit_value %d", back
+ return back;
+}
+
+
+
+/** Add a user or group limit to a class.
+ @param pcl Class to modify.
+ @param s Container for limits.
+ @param i Container iterator.
+ @param str Text containing name and limit.
+ @param fn File name.
+ @param lineno Line number.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+add_limit(
+ pqd_class_t *pcl,
+ dk4_sto_t *s,
+ dk4_sto_it_t *i,
+ char *str,
+ const char *fn,
+ dk4_um_t lineno
+)
+{
+ pqd_limit_t *plim;
+ char *pnum;
+ char *px;
+ dk4_um_t limval = (dk4_um_t)0UL;
+ int back = 0;
+ $? "+ add_limit %s %s %s \"%s\"", TR_8PTR(pcl), TR_8PTR(s), TR_8PTR(i), TR_8STR(str)
+ pnum = dk4str8_next(str, NULL);
+ if (NULL != pnum) {
+ px = dk4str8_next(pnum, NULL);
+ if (NULL == px) {
+ if (0 != get_limit_value(&limval, pnum, fn, lineno)) {
+ plim = (pqd_limit_t *)dk4sto_it_find_like(i, str, 1);
+ if (NULL == plim) {
+ plim = limit_new(str, limval);
+ if (NULL != plim) {
+ if (0 != dk4sto_add(s, plim, NULL)) {
+ back = 1;
+ } else { $? "! allocation (2)"
+ /* ERROR: Memory */
+ log_1(fn, lineno, LOG_EMERG, 1, 27);
+ limit_delete(plim);
+ }
+ } else { $? "! allocation (1)"
+ /* ERROR: Memory */
+ log_1(fn, lineno, LOG_EMERG, 1, 27);
+ }
+ } else { $? "! redefinition"
+ /* ERROR: Limit redefinition */
+ log_3(fn, lineno, LOG_EMERG, 1, 32, 33, str);
+ }
+ }
+ } else { $? "! unexpected text"
+ /* ERROR: Syntax, no further text expected */
+ log_3(fn, lineno, LOG_EMERG, 1, 23, 24, px);
+ }
+ } else { $? "! no limit text"
+ /* ERROR: Missing limit. */
+ log_1(fn, lineno, LOG_EMERG, 1, 31);
+ }
+ $? "- add_limit %d", back
+ return back;
+}
+
+
+
+/** Set default limit for class.
+ @param pcl Class to modify.
+ @param pv String containing the limit.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+set_default_limit(
+ pqd_class_t *pcl,
+ char *pv,
+ const char *fn,
+ unsigned long lineno
+)
+{
+ char *px;
+ dk4_um_t value = (dk4_um_t)0UL;
+ int back = 0;
+ $? "+ set_default_limit %s \"%s\"", TR_8PTR(pcl), TR_8STR(pv)
+ px = dk4str8_next(pv, NULL);
+ if (NULL == px) {
+ if (0 != get_limit_value(&value, pv, fn, lineno)) {
+ if ((0 == (1 & (pcl->hdl))) || (value == pcl->dl) ) {
+ pcl->hdl |= 1;
+ pcl->dl = value;
+ back = 1;
+ } else { $? "! redefinition"
+ /* ERROR: Syntax, default limit redefined */
+ log_1(fn, lineno, LOG_EMERG, 1, 34);
+ }
+ }
+ } else { $? "! unexpected text"
+ /* ERROR: No further text expected */
+ log_3(fn, lineno, LOG_EMERG, 1, 23, 24, px);
+ }
+ $? "- set_default_limit %d", back
+ return back;
+}
+
+
+
+/** Set deny action for printer class.
+ @param pcl Class to modify.
+ @param pv String containing the action.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+set_deny_action(
+ pqd_class_t *pcl,
+ char *pv,
+ const char *fn,
+ unsigned long lineno
+)
+{
+ char *px = NULL;
+ int back = 0;
+ int res = 0;
+ $? "+ set_deny_action %s \"%s\"", TR_8PTR(pcl), TR_8STR(pv)
+ px = dk4str8_next(pv, NULL);
+ if (NULL == px) {
+ switch ( (res = dk4str8_array_index(deny_action_names, pv, 0)) ) {
+ case 0: case 1: {
+ if (0 == (2 & pcl->hdl)) {
+ pcl->da = res;
+ pcl->hdl |= 2;
+ back = 1;
+ } else { $? "! redefinition"
+ /* ERROR: Redefinition of deny action */
+ log_1(fn, lineno, LOG_EMERG, 1, 35);
+ }
+ } break;
+ default: {
+ } break;
+ }
+ } else { $? "! unexpected text"
+ /* ERROR: Syntax, no further text expected */
+ log_3(fn, lineno, LOG_EMERG, 1, 23, 24, px);
+ }
+ $? "- set_deny_action %d", back
+ return back;
+}
+
+
+
+/** Add an alias for the current printer to list.
+ @param ppr Printer to add alias for.
+ @param pv Alias name.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+add_alias(pqd_printer_t *ppr, char *pv, const char *fn, unsigned long lineno)
+{
+ pqd_printer_alias_t *ppa;
+ pqd_printer_t *pp;
+ char *px;
+ int back = 0;
+ $? "+ add_alias %s \"%s\"", TR_8PTR(ppr), TR_8STR(pv)
+ px = dk4str8_next(pv, NULL);
+ if (NULL == px) {
+ ppa = (pqd_printer_alias_t *)dk4sto_it_find_like(conf.i_a, pv, 1);
+ if (NULL == ppa) {
+ pp = (pqd_printer_t *)dk4sto_it_find_like(conf.i_p, pv, 1);
+ if (NULL == pp) {
+ ppa = printer_alias_new(pv, ppr);
+ if (NULL != ppa) {
+ if (0 != dk4sto_add(conf.s_a, ppa, NULL)) {
+ back = 1;
+ } else { $? "! allocation (2)"
+ /* ERROR: Memory */
+ log_1(fn, lineno, LOG_EMERG, 1, 27);
+ printer_alias_delete(ppa);
+ }
+ } else { $? "! allocation (1)"
+ /* ERROR: Memory */
+ log_1(fn, lineno, LOG_EMERG, 1, 27);
+ }
+ } else { $? "! printer exists"
+ /* ERROR: Printer exists */
+ log_3(fn, lineno, LOG_EMERG, 1, 36, 37, pv);
+ }
+ } else { $? "! alias exists"
+ /* ERROR: Alias already exists */
+ log_3(fn, lineno, LOG_EMERG, 1, 38, 39, pv);
+ }
+ } else { $? "! unexpected text"
+ /* ERROR: Syntax, unexpected text */
+ log_3(fn, lineno, LOG_EMERG, 1, 23, 24, px);
+ }
+ $? "- add_alias %d", back
+ return back;
+}
+
+
+
+/** Assign a class to a printer.
+ @param ppr Printer to modify.
+ @param pv Class name.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+assign_class(pqd_printer_t *ppr, char *pv, const char *fn, unsigned long lineno)
+{
+ pqd_class_t *pcl;
+ char *px;
+ int back = 0;
+ $? "+ assign_class %s \"%s\"", TR_8PTR(ppr), TR_8STR(pv)
+ px = dk4str8_next(pv, NULL);
+ if (NULL == px) {
+ if (NULL == ppr->cl) {
+ pcl = (pqd_class_t *)dk4sto_it_find_like(conf.i_c, pv, 1);
+ if (NULL != pcl) {
+ ppr->cl = pcl;
+ back = 1;
+ } else { $? "! not found"
+ /* ERROR: Syntax, class not found */
+ log_3(fn, lineno, LOG_EMERG, 1, 40, 41, pv);
+ }
+ } else { $? "! redefinition"
+ /* ERROR: Syntax, redefinition of printer class */
+ log_1(fn, lineno, LOG_EMERG, 1, 42);
+ }
+ } else { $? "! unexpected text"
+ /* ERROR: Syntax, unexpected text */
+ log_3(fn, lineno, LOG_EMERG, 1, 23, 24, px);
+ }
+ $? "- assign_class %d", back
+ return back;
+}
+
+
+
+/** Check configuration for errors.
+ @return 1 if configuration is usable, 0 on errors.
+*/
+static
+int
+config_check(const char *filename, unsigned long lineno)
+{
+ pqd_printer_t *pr = NULL;
+ pqd_class_t *cl = NULL;
+ int back = 1;
+
+ $? "+ config_check"
+ /* Each printer must have a class assigned.
+ */
+ dk4sto_it_reset(conf.i_p);
+ do {
+ pr = (pqd_printer_t *)dk4sto_it_next(conf.i_p);
+ if (NULL != pr) {
+ if (NULL == pr->cl) {
+ back = 0; $? "! no class for printer \"%s\"", TR_8STR(pr->name)
+ /* ERROR: No class for printer */
+ log_3(filename, lineno, LOG_EMERG, 1, 91, 92, pr->name);
+ }
+ }
+ } while(NULL != pr);
+
+ /* Each class should have a default limit
+ */
+ dk4sto_it_reset(conf.i_c);
+ do {
+ cl = (pqd_class_t *)dk4sto_it_next(conf.i_c);
+ if (NULL != cl) {
+ if (0 == cl->hdl) {
+ $? "! WARNING no default limit for class \"%s\"", TR_8STR(cl->name)
+ /* WARNING: Default limit missing for class */
+ log_3(filename, lineno, LOG_EMERG, 0, 93, 94, cl->name);
+ }
+ }
+ } while (NULL != cl);
+
+ $? "- config_check %d", back
+ return back;
+}
+
+
+
+/** Set additional features to log.
+ @param pv Text containing the feature names.
+ @param fn File name for diagnostics.
+ @param lineno Line numbers for diagnostics.
+ @return 1 on success, 0 on errors.
+*/
+static
+int
+set_log_features(char *pv, const char *fn, unsigned long lineno)
+{
+
+ char *pc;
+ char *pn;
+ int back = 0;
+
+ if (NULL != pv) {
+ back = 1;
+ pc = dk4str8_start(pv, NULL);
+ while (NULL != pc) {
+ pn = strchr(pc, ',');
+ if (NULL != pn) {
+ *(pn++) = '\0';
+ pn = dk4str8_start(pn, NULL);
+ }
+ dk4str8_normalize(pc, NULL);
+ switch ( dk4str8_array_index(log_feature_names, pc, 0) ) {
+ case 0 : {
+ conf.ldb = 1;
+ } break;
+ case 1 : {
+ conf.linf = 1;
+ } break;
+ case 2 : case 3 : {
+ conf.ldb = 1;
+ conf.linf = 1;
+ } break;
+ case 4 : case 5 : {
+ conf.ldb = 0;
+ conf.linf = 0;
+ } break;
+ default : {
+ /* ERROR: Unknown log feature name */
+ log_3(NULL, 0UL, LOG_EMERG, 0, 154, 155, pc);
+ back = 0;
+ } break;
+ }
+ pc = pn;
+ }
+ } else {
+ /* ERROR: Value required */
+ conf.ldb = 0; conf.linf = 0;
+ }
+ return back;
+}
+
+
+
+/** Read configuration file.
+ @return 1 on success (can continue), 0 on error (must exit).
+*/
+static
+int
+config_read(void)
+{
+ const char *fn = NULL; /* Input file name */
+ FILE *fipo = NULL; /* Input file */
+ pqd_class_t *pcl = NULL; /* Current class to modify */
+ pqd_printer_t *ppr = NULL; /* Current printer to modify */
+ pqd_printer_alias_t *ppa = NULL; /* Printer alias */
+ char *pk = NULL; /* Key text */
+ char *pv = NULL; /* Value text */
+ char *px = NULL; /* Text after value */
+ unsigned long lineno = 0UL; /* Current line number */
+ int back = 0; /* Result */
+ int sectt = 0; /* Section type: 0=opt, 1=class, 2=pr */
+ int myres = 0; /* Internal operation result */
+ $? "+ config_read"
+ if (0 != config_allocate()) {
+ if (0 != options[1].found) { fn = options[1].val.t; }
+ if (NULL == fn) { fn = def_conf_file_name; }
+ fipo = dk4fopen_c8(fn, printqd_kw[1], DK4_FOPEN_SC_IS_REGULAR, NULL);
+ if (NULL != fipo) {
+ back = 1;
+ sectt = 0;
+ while ((1 == back) && (NULL != fgets(inbuf, sizeof(inbuf), fipo))) {
+ lineno++;
+ dk4str8_delnl(inbuf); $? ". line = \"%s\"", inbuf
+ pk = dk4str8_start(inbuf, NULL);
+ if (NULL != pk) {
+ if ('#' != *pk) {
+ if ('[' == *pk) { $? ". section line"
+ /*
+ Opening a new section.
+ */
+ pk = dk4str8_start(++pk, NULL);
+ if (NULL != pk) { $? ". section \"%s\"", pk
+ sectt = -1;
+ pcl = NULL;
+ ppr = NULL;
+ pv = dk4str8_chr(pk, ']');
+ if (NULL != pv) { *pv = '\0'; } $? ". section = \"%s\"", pk
+ pv = dk4str8_next(pk, NULL);
+ switch ( dk4str8_array_index(config_section_names, pk, 0) ) {
+ /* Opening options section.
+ */
+ case 0 : { $? ". options section"
+ sectt = 0;
+ } break;
+ /* Opening class section.
+ */
+ case 1 : { $? ". class section"
+ sectt = 1;
+ if (NULL != pv) {
+ if (NULL == (px = dk4str8_next(pv, NULL))) {
+ pcl = (pqd_class_t *)dk4sto_it_find_like(
+ conf.i_c, pv, 1
+ );
+ if (NULL == pcl) {
+ pcl = class_new(pv);
+ if (NULL != pcl) {
+ if (0 == dk4sto_add(conf.s_c, pcl, NULL)) {
+ /* ERROR: Memory */
+ log_1(fn, lineno, LOG_EMERG, 1, 27);
+ class_delete(pcl);
+ pcl = NULL; $? "! memory"
+ back = 0;
+ }
+ } else { $? "! memory"
+ /* ERROR: MEMORY */
+ log_1(fn, lineno, LOG_EMERG, 1, 27);
+ back = 0;
+ }
+ } else { $? "! already exists"
+ /* ERROR: Syntax, class already exists */
+ log_3(fn, lineno, LOG_EMERG, 1, 43, 44, pv);
+ back = 0;
+ }
+ } else { $? "! unexpected text"
+ /* ERROR: Syntax, only one component allowed */
+ log_3(fn, lineno, LOG_EMERG, 1, 23, 24, px);
+ back = 0;
+ }
+ } else { $? "! missing class name"
+ /* ERROR: Syntax, missing class name */
+ log_1(fn, lineno, LOG_EMERG, 1, 45);
+ back = 0;
+ }
+ } break;
+ /* Opening printer section.
+ */
+ case 2 : { $? ". printer section"
+ sectt = 2;
+ if (NULL != pv) {
+ if (NULL == (px = dk4str8_next(pv, NULL))) {
+ ppr = (pqd_printer_t *)dk4sto_it_find_like(
+ conf.i_p,pv,1
+ );
+ ppa = (pqd_printer_alias_t *)dk4sto_it_find_like(
+ conf.i_a,pv,1
+ );
+ if ((NULL == ppr) && (NULL == ppa)) {
+ ppr = printer_new(pv);
+ if (NULL != ppr) {
+ if (0 == dk4sto_add(conf.s_p, ppr, NULL)) {
+ /* ERROR: Memory */
+ log_1(fn, lineno, LOG_EMERG, 1, 27);
+ printer_delete(ppr);
+ ppr = NULL;
+ back = 0; $? "! memory"
+ }
+ } else { $? "! memory"
+ /* ERROR: Memory */
+ log_1(fn, lineno, LOG_EMERG, 1, 27);
+ back = 0;
+ }
+ } else { $? "! already exists"
+ /* ERROR: Syntax, pr/al already exists */
+ log_3(fn, lineno, LOG_EMERG, 1, 46, 47, pv);
+ back = 0;
+ }
+ } else { $? "! unexpected text"
+ /* ERROR: Syntax, just one component allowed */
+ log_3(fn, lineno, LOG_EMERG, 1, 23, 24, px);
+ back = 0;
+ }
+ } else { $? "! missing printer name"
+ /* ERROR: Syntax, name required */
+ log_1(fn, lineno, LOG_EMERG, 1, 48);
+ back = 0;
+ }
+ } break;
+ default : { $? "! illegal section name"
+ /* ERROR: Syntax, illegal section name */
+ log_3(fn, lineno, LOG_EMERG, 1, 49, 50, pk);
+ back = 0;
+ } break;
+ }
+ } else { $? "! empty section"
+ /* ERROR: Syntax, empty section */
+ log_1(fn, lineno, LOG_EMERG, 1, 51);
+ back = 0;
+ }
+ } else { $? ". data line"
+ /*
+ Data line for existing section.
+ */
+ pv = dk4str8_chr(pk, '=');
+ if (NULL != pv) {
+ *(pv++) = '\0';
+ pv = dk4str8_start(pv, NULL);
+ if (NULL != pv) {
+ dk4str8_normalize(pk, NULL); $? ". pk=\"%s\" pv=\"%s\"",pk,pv
+ switch ( dk4str8_array_index(config_option_names, pk, 0) ) {
+ case 0 : {
+ $? ". run as user"
+ if (0 == sectt) {
+ struct passwd *pw;
+ if (NULL == (px = dk4str8_next(pv, NULL))) {
+ pw = getpwnam(pv);
+ if (NULL != pw) {
+ if ((0 == conf.uid) || (conf.uid == pw->pw_uid)) {
+ conf.uid = pw->pw_uid;
+ } else {
+ /* ERROR: Redefinition */
+ log_1(fn, lineno, LOG_EMERG, 1, 52);
+ back = 0; $? "! redefinition"
+ }
+ } else { $? "! user not found"
+ /* ERROR: User not found */
+ log_3(fn, lineno, LOG_EMERG, 1, 53, 54, pv);
+ back = 0;
+ }
+ } else { $? "! unexpected text"
+ /* ERROR: Syntax, just one component allowed */
+ log_3(fn, lineno, LOG_EMERG, 1, 23, 24, px);
+ back = 0;
+ }
+ } else { $? "! only in options"
+ /* ERROR: Only allwowed in options section */
+ log_1(fn, lineno, LOG_EMERG, 1, 55);
+ back = 0;
+ }
+ } break;
+ case 1 : { $? ". run as group"
+ if (0 == sectt) {
+ struct group *pgr;
+ if (NULL == (px = dk4str8_next(pv, NULL))) {
+ pgr = getgrnam(pv);
+ if (NULL != pgr) {
+ if ((0 == conf.gid) || (conf.gid == pgr->gr_gid)) {
+ conf.gid = pgr->gr_gid;
+ } else {
+ /* ERROR: Syntax, group redefinition */
+ log_1(fn, lineno, LOG_EMERG, 1, 56);
+ back = 0; $? "! redefinition"
+ }
+ } else { $? "! not found"
+ /* ERROR: Syntax, group not found */
+ log_3(fn, lineno, LOG_EMERG, 1, 57, 58, pv);
+ back = 0;
+ }
+ } else { $? "! unexpected text"
+ /* ERROR: Syntax, just one component allowed */
+ log_3(fn, lineno, LOG_EMERG, 1, 23, 24, px);
+ back = 0;
+ }
+ } else { $? "! only in options"
+ /* ERROR: Syntax, only allowed in options */
+ log_1(fn, lineno, LOG_EMERG, 1, 55);
+ back = 0;
+ }
+ } break;
+ case 2 : { $? ". database"
+ if (0 == sectt) {
+ if (NULL == conf.dname) {
+ conf.dname = dk4str8_dup(pv, NULL);
+ if (NULL == conf.dname) {
+ /* ERROR: Memory */
+ log_1(fn, lineno, LOG_EMERG, 1, 27);
+ back = 0; $? "! memory"
+ }
+ } else {
+ /* ERROR: Redefinition */
+ log_1(fn, lineno, LOG_EMERG, 1, 59);
+ back = 0; $? "! redefinition"
+ }
+ } else { $? "! only in options"
+ /* ERROR: Syntax, only allowed in options */
+ log_1(fn, lineno, LOG_EMERG, 1, 55);
+ back = 0;
+ }
+ } break;
+ case 3 : { $? ". local socket"
+ if (0 == sectt) {
+ if (NULL == conf.sname) {
+ conf.sname = dk4str8_dup(pv, NULL);
+ if (NULL == conf.sname) {
+ /* ERROR: Memory */
+ log_1(fn, lineno, LOG_EMERG, 1, 27);
+ back = 0; $? "! memory"
+ }
+ } else { $? "! redefinition"
+ /* ERROR: Redefinition */
+ log_1(fn, lineno, LOG_EMERG, 1, 60);
+ back = 0;
+ }
+ } else { $? "! only in options"
+ /* ERROR: Syntax, only allowed in options */
+ log_1(fn, lineno, LOG_EMERG, 1, 55);
+ back = 0;
+ }
+ } break;
+ case 4 : { $? ". local socket backlog"
+ if (0 == sectt) {
+ if (0 == set_backlog(&(conf.slbl), pv, fn, lineno)) {
+ back = 0; $? "! failed"
+ }
+ } else { $? "! only in options"
+ /* ERROR: Syntax, only allowed in options */
+ log_1(fn, lineno, LOG_EMERG, 1, 55);
+ back = 0;
+ }
+ } break;
+ case 5 : { $? ". max local connections"
+ if (0 == sectt) {
+ if(0 == set_max_connections(&(conf.m_loc),pv,fn,lineno))
+ {
+ back = 0; $? "! failed"
+ }
+ } else { $? "! only in options"
+ /* ERROR: Syntax, only allowed in options */
+ log_1(fn, lineno, LOG_EMERG, 1, 55);
+ back = 0;
+ }
+ } break;
+ case 6 : { $? ". udp port"
+ if (0 == sectt) {
+ if (0 == set_port_number(&(conf.pudp),pv,fn,lineno)) {
+ back = 0; $? "! failed"
+ }
+ } else { $? "! only in options"
+ /* ERROR: Syntax, only allowed in options */
+ log_1(fn, lineno, LOG_EMERG, 1, 55);
+ back = 0;
+ }
+ } break;
+ case 7 : { $? ". tcp port"
+ if (0 == sectt) {
+ if (0 == set_port_number(&(conf.ptcp),pv,fn,lineno)) {
+ back = 0; $? "! failed"
+ }
+ } else { $? "! only in options"
+ /* ERROR: Syntax, only allowed in options */
+ log_1(fn, lineno, LOG_EMERG, 1, 55);
+ back = 0;
+ }
+ } break;
+ case 8 : { $? ". tcp port backlog"
+ if (0 == sectt) {
+ if (0 == set_backlog(&(conf.snbl), pv, fn, lineno)) {
+ back = 0; $? "! failed"
+ }
+ } else { $? "! only in options"
+ /* ERROR: Syntax, only allowed in options */
+ log_1(fn, lineno, LOG_EMERG, 1, 55);
+ back = 0;
+ }
+ } break;
+ case 9 : { $? ". max tcp connections"
+ if (0 == sectt) {
+ if(0 == set_max_connections(&(conf.m_tcp),pv,fn,lineno))
+ {
+ back = 0; $? "! failed"
+ }
+ } else { $? "! only in options"
+ /* ERROR: Syntax, only allowed in options */
+ log_1(fn, lineno, LOG_EMERG, 1, 55);
+ back = 0;
+ }
+ } break;
+ case 10 : { $? ". info allow"
+ if (0 == sectt) {
+ myres = allow_hosts(
+ conf.s_ai, conf.i_ai, &(conf.iglo), pv,
+ fn, lineno
+ );
+ if (0 == myres) { $? "! failed"
+ back = 0;
+ }
+ } else { $? "! only in options"
+ /* ERROR: Syntax, only allowed in options */
+ log_1(fn, lineno, LOG_EMERG, 1, 55);
+ back = 0;
+ }
+ } break;
+ case 11 : { $? ". data allow"
+ if (0 == sectt) {
+ myres = allow_hosts(
+ conf.s_ad, conf.i_ad, &(conf.dglo), pv,
+ fn, lineno
+ );
+ if (0 == myres) { $? "! failed"
+ back = 0;
+ }
+ } else { $? "! only in options"
+ /* ERROR: Syntax, only allowed in options */
+ log_1(fn, lineno, LOG_EMERG, 1, 55);
+ back = 0;
+ }
+ } break;
+ case 12 : { $? ". admin allow"
+ if (0 == sectt) {
+ myres = allow_hosts(
+ conf.s_aa, conf.i_aa, &(conf.aglo), pv,
+ fn, lineno
+ );
+ if (0 == myres) { $? "! failed"
+ back = 0;
+ }
+ } else { $? "! only in options"
+ /* ERROR: Syntax, only allowed in options */
+ log_1(fn, lineno, LOG_EMERG, 1, 55);
+ back = 0;
+ }
+ } break;
+ case 13 : { $? ". user limit"
+ if ((1 == sectt) && (NULL != pcl)) {
+ myres = add_limit(
+ pcl, pcl->s_u, pcl->i_u, pv, fn, lineno
+ );
+ if (0 == myres) { $? "! failed"
+ back = 0;
+ }
+ } else { $? "! only in class"
+ /* ERROR: Syntax, only allowed in class */
+ log_1(fn, lineno, LOG_EMERG, 1, 61);
+ back = 0;
+ }
+ } break;
+ case 14 : { $? ". group limit"
+ if ((1 == sectt) && (NULL != pcl)) {
+ myres = add_limit(
+ pcl, pcl->s_g, pcl->i_g, pv, fn, lineno
+ );
+ if (0 == myres) { $? "! failed"
+ back = 0;
+ }
+ } else { $? "! only in class"
+ /* ERROR: Syntax, only allowed in class */
+ log_1(fn, lineno, LOG_EMERG, 1, 61);
+ back = 0;
+ }
+ } break;
+ case 15 : { $? ". default limit"
+ if ((1 == sectt) && (NULL != pcl)) {
+ myres = set_default_limit(pcl, pv, fn, lineno);
+ if (0 == myres) { $? "! failed"
+ back = 0;
+ }
+ } else { $? "! only in class"
+ /* ERROR: Syntax, only allowed in class */
+ log_1(fn, lineno, LOG_EMERG, 1, 61);
+ back = 0;
+ }
+ } break;
+ case 16 : { $? ". deny action"
+ if ((1 == sectt) && (NULL != pcl)) {
+ myres = set_deny_action(pcl, pv, fn, lineno);
+ if (0 == myres) { $? "! failed"
+ back = 0;
+ }
+ } else { $? "! only in class"
+ /* ERROR: Syntax, only allowed in class */
+ log_1(fn, lineno, LOG_EMERG, 1, 61);
+ back = 0;
+ }
+ } break;
+ case 17 : { $? ". alias"
+ if ((2 == sectt) && (NULL != ppr)) {
+ myres = add_alias(ppr, pv, fn, lineno);
+ if (0 == myres) { $? "! failed"
+ back = 0;
+ }
+ } else { $? "! only in printer"
+ /* ERROR: Syntax, only allowed in printer */
+ log_1(fn, lineno, LOG_EMERG, 1, 62);
+ back = 0;
+ }
+ } break;
+ case 18 : { $? ". class"
+ if ((2 == sectt) && (NULL != ppr)) {
+ myres = assign_class(ppr, pv, fn, lineno);
+ if (0 == myres) { $? "! failed"
+ back = 0;
+ }
+ } else { $? "! only in printer"
+ /* ERROR: Syntax, only allowed in printer */
+ log_1(fn, lineno, LOG_EMERG, 1, 62);
+ back = 0;
+ }
+ } break;
+ case 19 : { $? ". log file"
+ if (0 == sectt) {
+ if (NULL == conf.lname) {
+ conf.lname = dk4str8_dup(pv, NULL);
+ if (NULL == conf.lname) {
+ /* ERROR: Memory */
+ log_1(fn, lineno, LOG_EMERG, 1, 27);
+ back = 0; $? "! memory"
+ }
+ } else { $? "! redefinition"
+ /* ERROR: Redefinition */
+ log_1(fn, lineno, LOG_EMERG, 1, 63);
+ back = 0;
+ }
+ } else { $? "! only in options"
+ /* ERROR: Only in options */
+ log_1(fn, lineno, LOG_EMERG, 1, 55);
+ back = 0;
+ }
+ } break;
+ case 20 : { $? ". log features"
+ back = set_log_features(pv, fn, lineno);
+ } break;
+ case 21 : { $? ". local socket owner"
+ if (0 == sectt) {
+ struct passwd *pw;
+ if (NULL == (px = dk4str8_next(pv, NULL))) {
+ pw = getpwnam(pv);
+ if (NULL != pw) {
+ if ((0 == conf.suid) || (conf.suid == pw->pw_uid)) {
+ conf.suid = pw->pw_uid;
+ } else {
+ /* ERROR: Redefinition */
+ log_1(fn, lineno, LOG_EMERG, 1, 52);
+ back = 0; $? "! redefinition"
+ }
+ } else { $? "! user not found"
+ /* ERROR: User not found */
+ log_3(fn, lineno, LOG_EMERG, 1, 53, 54, pv);
+ back = 0;
+ }
+ } else { $? "! unexpected text"
+ /* ERROR: Syntax, just one component allowed */
+ log_3(fn, lineno, LOG_EMERG, 1, 23, 24, px);
+ back = 0;
+ }
+ } else { $? "! only in options"
+ /* ERROR: Only allwowed in options section */
+ log_1(fn, lineno, LOG_EMERG, 1, 55);
+ back = 0;
+ }
+ } break;
+ case 22 : { $? ". local socket group"
+ if (0 == sectt) {
+ struct group *pgr;
+ if (NULL == (px = dk4str8_next(pv, NULL))) {
+ pgr = getgrnam(pv);
+ if (NULL != pgr) {
+ if((0 == conf.sgid) || (conf.sgid == pgr->gr_gid)) {
+ conf.sgid = pgr->gr_gid;
+ } else {
+ /* ERROR: Syntax, group redefinition */
+ log_1(fn, lineno, LOG_EMERG, 1, 56);
+ back = 0; $? "! redefinition"
+ }
+ } else { $? "! not found"
+ /* ERROR: Syntax, group not found */
+ log_3(fn, lineno, LOG_EMERG, 1, 57, 58, pv);
+ back = 0;
+ }
+ } else { $? "! unexpected text"
+ /* ERROR: Syntax, just one component allowed */
+ log_3(fn, lineno, LOG_EMERG, 1, 23, 24, px);
+ back = 0;
+ }
+ } else { $? "! only in options"
+ /* ERROR: Syntax, only allowed in options */
+ log_1(fn, lineno, LOG_EMERG, 1, 55);
+ back = 0;
+ }
+ } break;
+ }
+ } else { $? "! value text missing"
+ /* ERROR: Syntax, missing value */
+ log_1(fn, lineno, LOG_EMERG, 1, 64);
+ back = 0;
+ }
+ } else { $? "! value text missing"
+ /* ERROR: Syntax, missing value */
+ log_1(fn, lineno, LOG_EMERG, 1, 64);
+ back = 0;
+ }
+ }
+ }
+#if TRACE_DEBUG
+ else { $? ". comment line"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? ". empty line"
+ }
+#endif
+ }
+ fclose(fipo);
+ if (1 == back) {
+ back = config_check(fn, lineno);
+ }
+ } else { $? "! failed to open file"
+ /* ERROR: Failed to open file */
+ log_1(fn, 0UL, LOG_EMERG, 1, 65);
+ }
+ } else {
+ /* ERROR: Memory */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 27);
+ }
+ $? "- config_read %d", back
+ return back;
+}
+
+
+
+static
+void
+release_allowed_peers(dk4_sto_it_t *it)
+{
+ dk4_allowed_peer_t *peer;
+ $? "+ release_allowed_peers %s", TR_8PTR(it)
+ dk4sto_it_reset(it);
+ do {
+ peer = (dk4_allowed_peer_t *)dk4sto_it_next(it);
+ if (NULL != peer) {
+ dk4mem_free(peer);
+ }
+ } while (NULL != peer);
+ dk4sto_it_close(it);
+ $? "- release_allowed_peers"
+}
+
+
+
+/** Release resources used to save configuration data.
+*/
+static
+void
+config_release(void)
+{
+ $? "+ config_release"
+ prev_uid = conf.uid;
+ prev_gid = conf.gid;
+
+ if (NULL != conf.i_aa) { /* Allowed peers for administration */
+ release_allowed_peers(conf.i_aa);
+ } conf.i_aa = NULL;
+ if (NULL != conf.s_aa) {
+ dk4sto_close(conf.s_aa);
+ } conf.s_aa = NULL;
+ if (NULL != conf.i_ad) { /* Allowed peers for data */
+ release_allowed_peers(conf.i_ad);
+ } conf.i_ad = NULL;
+ if (NULL != conf.s_ad) {
+ dk4sto_close(conf.s_ad);
+ } conf.s_ad = NULL;
+ if (NULL != conf.i_ai) { /* Allowed peers for information */
+ release_allowed_peers(conf.i_ai);
+ } conf.i_ai = NULL;
+ if (NULL != conf.s_ai) {
+ dk4sto_close(conf.s_ai);
+ } conf.s_ai = NULL;
+ if (NULL != conf.i_a) { /* Aliases */
+ printer_alias_all_delete(conf.i_a);
+ } conf.i_a = NULL;
+ if (NULL != conf.s_a) {
+ dk4sto_close(conf.s_a);
+ } conf.s_a = NULL;
+ if (NULL != conf.i_p) { /* Printers */
+ printer_all_delete(conf.i_p);
+ } conf.i_p = NULL;
+ if (NULL != conf.s_p) {
+ dk4sto_close(conf.s_p);
+ } conf.s_p = NULL;
+ if (NULL != conf.i_c) { /* Classes */
+ class_all_delete(conf.i_c);
+ } conf.i_c = NULL;
+ if (NULL != conf.s_c) {
+ dk4sto_close(conf.s_c);
+ } conf.s_c = NULL;
+ dk4mem_release(conf.dname);
+ dk4mem_release(conf.sname);
+ dk4mem_release(conf.lname);
+ conf.m_loc = 0;
+ conf.m_tcp = 0;
+ conf.uid = 0;
+ conf.gid = 0;
+ conf.slbl = 0;
+ conf.snbl = 0;
+ conf.ptcp = 9100;
+ conf.pudp = 9100;
+ $? "- config_release"
+}
+
+
+
+/** Allocate resources before starting outer loop.
+ @return 1 on success (can enter loop), 0 on error (exit).
+*/
+static
+int
+outer_allocate_resources(void)
+{
+ int back = 0;
+ $? "+ outer_allocate_resources"
+
+ /* Initialize variables to NULL.
+ */
+ s_c_unix = NULL;
+ i_c_unix = NULL;
+ s_c_tcp = NULL;
+ i_c_tcp = NULL;
+
+ /* Allocate resources.
+ */
+ s_c_unix = dk4sto_open(NULL);
+ if (NULL == s_c_unix) { $? "! allocation (1)"
+ /* ERROR: Memory */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 27);
+ goto finished;
+ }
+ dk4sto_set_comp(s_c_unix, compare_pqd_l_conn_t, 0);
+ i_c_unix = dk4sto_it_open(s_c_unix, NULL);
+ if (NULL == i_c_unix) { $? "! allocation (2)"
+ /* ERROR: Memory */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 27);
+ goto finished;
+ }
+ s_c_tcp = dk4sto_open(NULL);
+ if (NULL == s_c_tcp) { $? "! allocation (3)"
+ /* ERROR: Memory */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 27);
+ goto finished;
+ }
+ dk4sto_set_comp(s_c_tcp, compare_pqd_n_conn_t, 0);
+ i_c_tcp = dk4sto_it_open(s_c_tcp, NULL);
+ if (NULL == i_c_tcp) { $? "! allocation (4)"
+ /* ERROR: Memory */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 27);
+ goto finished;
+ }
+
+ /* Indicate success.
+ */
+ back = 1;
+
+ finished:
+ $? "- outer_allocate_resources %d", back
+ return back;
+}
+
+
+
+/** Release resources after finishing outer loop.
+*/
+static
+void
+outer_release_resources(void)
+{
+ pqd_n_conn_t *pnc;
+ pqd_l_conn_t *plc;
+ $? "+ outer_release_resources"
+
+ if (NULL != i_c_tcp) {
+ dk4sto_it_reset(i_c_tcp);
+ do {
+ pnc = (pqd_n_conn_t *)dk4sto_it_next(i_c_tcp);
+ if (NULL != pnc) {
+ /* Release pnc */
+ if (INVALID_SOCKET != pnc->sock) {
+ (void)dk4socket_close(pnc->sock, NULL);
+ }
+ dk4mem_free(pnc);
+ }
+ } while(NULL != pnc);
+ dk4sto_it_close(i_c_tcp);
+ }
+ i_c_tcp = NULL;
+ if (NULL != s_c_tcp) {
+ dk4sto_close(s_c_tcp);
+ }
+ s_c_tcp = NULL;
+ if (NULL != i_c_unix) {
+ dk4sto_it_reset(i_c_unix);
+ do {
+ plc = (pqd_l_conn_t *)dk4sto_it_next(i_c_unix);
+ if (NULL != plc) {
+ /* Release plc */
+ if (INVALID_SOCKET != plc->sock) {
+ (void)dk4socket_close(plc->sock, NULL);
+ }
+ dk4mem_free(plc);
+ }
+ } while (NULL != plc);
+ dk4sto_it_close(i_c_unix);
+ }
+ i_c_unix = NULL;
+ if (NULL != s_c_unix) {
+ dk4sto_close(s_c_unix);
+ }
+ s_c_unix = NULL;
+ $? "- outer_release_resources"
+}
+
+
+
+static
+void
+pqd_dbi_open_error(const char *fn, dk4_er_t *erp)
+{
+ switch (erp->ec) {
+ case DK4_E_NOT_SUPPORTED : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 105, 202, fn);
+ } break;
+ case DK4_E_MATH_OVERFLOW : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 105, 203, fn);
+ } break;
+ case DK4_E_MEMORY_ALLOCATION_FAILED : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 105, 204, fn);
+ } break;
+ case DK4_E_SYNTAX : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 105, 205, fn);
+ } break;
+ case DK4_E_SEC_CHECK : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 105, 206, fn);
+ } break;
+ case DK4_E_OPEN_READ_FAILED : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 105, 207, fn);
+ } break;
+ case DK4_E_OPEN_WRITE_FAILED : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 105, 208, fn);
+ } break;
+ case DK4_E_CLOSE_FAILED : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 105, 209, fn);
+ } break;
+ default : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 105, 106, fn);
+ } break;
+ }
+}
+
+
+/** Allocate resources before starting inner loop.
+ * Create log directory and log file.
+ * Open database.
+ * Log message for starting service.
+ @return 1 on success (can enter loop), 0 on error (exit).
+*/
+static
+int
+inner_allocate_resources(void)
+{
+ char necbuf[16*sizeof(dk4_um_t)];
+ dk4_er_t er;
+ const char *fn;
+ uid_t sockuid;
+ gid_t sockgid;
+ int res;
+ int back = 0;
+ $? "+ inner_allocate_resources"
+
+ /* Log file directory hierarchy.
+ */
+ fn = conf.lname;
+ if (NULL == fn) { fn = def_log_file_name; }
+ if (0 != user_switched) {
+ res = dk4mkdir_hierarchy_c8(fn, 0, NULL);
+ } else {
+ res = dk4mkdir_hierarchy_ugm_c8(fn, 0, conf.uid, conf.gid, 0750, NULL);
+ }
+ if (0 == res) { $? "! log dir hierarchy"
+ /* ERROR: Failed to create directory hierachy for log file */
+ log_3(NULL, 0UL, LOG_EMERG, 1, 95, 96, fn);
+ goto finished;
+ }
+
+ /* Database directory hierarchy
+ */
+ fn = conf.dname;
+ if (NULL == fn) { fn = def_db_file_name; }
+ fn = dk4dbi_filename_part(fn);
+ if (0 != user_switched) {
+ res = dk4mkdir_hierarchy_c8(fn, 0, NULL);
+ } else {
+ res = dk4mkdir_hierarchy_ugm_c8(fn, 0, conf.uid, conf.gid, 0750, NULL);
+ }
+ if (0 == res) { $? "! db dir hierarchy"
+ /* ERROR: Failed to create directory hierarchy for db file */
+ log_3(NULL, 0UL, LOG_EMERG, 1, 97, 98, fn);
+ goto finished;
+ }
+
+ /* Socket directory hierarchy
+ */
+ fn = conf.sname;
+ if (NULL == fn) { fn = def_sock_file_name; }
+ sockuid = conf.suid;
+ if (0 == sockuid) { sockuid = conf.uid; }
+ sockgid = conf.sgid;
+ if (0 == sockgid) { sockgid = conf.gid; }
+ if ((0 != user_switched) && (0 != conf.uid)) {
+ res = dk4mkdir_hierarchy_c8(fn, 0, NULL);
+ } else {
+ /*
+ In contrast to the db and log directories the non-privileged
+ user needs write access to the directory as the socket is deleted
+ and newly created.
+ */
+ res = dk4mkdir_hierarchy_ugm_c8(fn, 0, sockuid, sockgid, 0770, NULL);
+ }
+ if (0 == res) { $? "! socket dir hierarchy"
+ /* ERROR: Failed to create directory hierarchy for socket */
+ log_3(NULL, 0UL, LOG_EMERG, 1, 99, 100, fn);
+ goto finished;
+ }
+
+ /* UNIX listener socket.
+ */
+ fn = conf.sname;
+ if (NULL == fn) { fn = def_sock_file_name; }
+ $? ". create local socket \"%s\"", fn
+ dk4error_init(&er);
+ if (
+ ((0 != sockuid) || (0 != sockgid))
+ && ((0 == user_switched) || (0 == conf.uid))
+ )
+ {
+ so_unix = dk4socket_c8_unix_listener_owner_group_mode(
+ fn, ((0 < conf.slbl) ? (conf.slbl) : 5), sockuid, sockgid, 0660, &er
+ );
+ } else {
+ so_unix = dk4socket_c8_unix_listener(
+ fn, ((0 < conf.slbl) ? (conf.slbl) : 5), &er
+ );
+ }
+ if (INVALID_SOCKET == so_unix) { $? "! local socket"
+ /* ERROR: Failed to create listener socket */
+ res = dk4ma_write_c8_decimal_signed(
+ necbuf, sizeof(necbuf), (dk4_im_t)(er.dt.iDetails1), 0, NULL
+ );
+ if (0 != res) {
+ switch (er.ec) {
+ case DK4_E_SYNTAX : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 101, 178, fn);
+ } break;
+ case DK4_E_NON_SOCKET : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 101, 179, fn);
+ } break;
+ case DK4_E_UNLINK_FAILED : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 101, 180, fn);
+ } break;
+ case DK4_E_SOCKET_SOCKET : {
+ log_5(NULL, 0UL, LOG_EMERG, 1, 101, 181, 182, fn, necbuf);
+ } break;
+ case DK4_E_SOCKET_BIND : {
+ log_5(NULL, 0UL, LOG_EMERG, 1, 101, 183, 182, fn, necbuf);
+ } break;
+ case DK4_E_SOCKET_LISTEN : {
+ log_5(NULL, 0UL, LOG_EMERG, 1, 101, 184, 182, fn, necbuf);
+ } break;
+ case DK4_E_CHOWN_FAILED : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 101, 185, fn);
+ } break;
+ case DK4_E_CHMOD_FAILED : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 101, 186, fn);
+ } break;
+ default : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 101, 102, fn);
+ } break;
+ }
+ } else {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 101, 102, fn);
+ }
+ goto finished;
+ } $? ". local socket"
+
+ /* TCP listener socket set.
+ */
+ if (0 < conf.ptcp) {
+ dk4error_init(&er);
+ ss_tcp = dk4socket_c8_set_server(
+ conf.ptcp, ((0 < conf.snbl) ? (conf.snbl) : 5), 0, &er
+ );
+ if (NULL == ss_tcp) { $? "! tcp socket set"
+ /* ERROR: Failed to create TCP listener socket */
+ res = dk4ma_write_c8_decimal_signed(
+ necbuf, sizeof(necbuf), (dk4_im_t)(er.dt.iDetails1), 0, NULL
+ );
+ if (0 != res) {
+ switch (er.ec) {
+ case DK4_E_MATH_OVERFLOW : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 188);
+ } break;
+ case DK4_E_MEMORY_ALLOCATION_FAILED : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 189);
+ } break;
+ case DK4_E_SOCKET_SOCKET : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 190, 191, necbuf);
+ } break;
+ case DK4_E_SOCKET_BIND : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 192, 191, necbuf);
+ } break;
+ case DK4_E_SOCKET_LISTEN : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 193, 191, necbuf);
+ } break;
+ case DK4_E_SOCKET_GETADDRLOC : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 194, 191, necbuf);
+ } break;
+ default : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 103);
+ } break;
+ }
+ } else {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 103);
+ }
+ goto finished;
+ }
+ }
+
+ /* UDP socket set.
+ */
+ if (0 < conf.pudp) {
+ dk4error_init(&er);
+ ss_udp = dk4socket_c8_set_udp(conf.pudp, 0, 0, &er);
+ if (NULL == ss_udp) { $? "! udp socket set"
+ /* ERROR: Failed to create UDP socket set */
+ res = dk4ma_write_c8_decimal_signed(
+ necbuf, sizeof(necbuf), (dk4_im_t)(er.dt.iDetails1), 0, NULL
+ );
+ if (0 != res) {
+ switch (er.ec) {
+ case DK4_E_MATH_OVERFLOW : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 195);
+ } break;
+ case DK4_E_MEMORY_ALLOCATION_FAILED : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 196);
+ } break;
+ case DK4_E_SOCKET_SOCKET : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 197, 198, necbuf);
+ } break;
+ case DK4_E_SOCKET_BIND : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 199, 198, necbuf);
+ } break;
+ case DK4_E_SOCKET_LISTEN : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 200, 198, necbuf);
+ } break;
+ case DK4_E_SOCKET_GETADDRLOC : {
+ log_3(NULL, 0UL, LOG_EMERG, 1, 201, 198, necbuf);
+ } break;
+ }
+ } else {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 104);
+ }
+ goto finished;
+ }
+ }
+
+ fn = conf.dname;
+ if (NULL == fn) { fn = def_db_file_name; }
+ $? ". db open attempt 1 \"%s\"", fn
+ dk4error_init(&er);
+ db = dk4dbi_open(fn, 1, 0, 1024, 1024, &er);
+ if (NULL != db) { $? ". open db (1) ok"
+ db_modified = 0;
+ res = 1;
+ dk4error_init(&er);
+ if (0 == dbi_set(db, printqd_kw[79],printqd_kw[79],&er)) { res = 0; }
+ if (0 == dk4dbi_close(db, &er)) { res = 0; }
+ db = NULL;
+ db_modified = 0;
+ if (0 != res) {
+ $? ". db open attempt 2 \"%s\"", fn
+ dk4error_init(&er);
+ db = dk4dbi_open(fn, 1, 0, 1024, 1024, &er);
+ if (NULL != db) { $? ". open db (2) ok"
+ db_modified = 0;
+ } else { $? "! open db (2)"
+ /* ERROR: Failed to open database */
+ pqd_dbi_open_error(fn, &er);
+ goto finished;
+ }
+ } else { $? "! initial db entry"
+ /* ERROR: Failed to write initial entry to database */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 107);
+ switch (er.ec) {
+ case DK4_E_SYNTAX : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 210);
+ } break;
+ case DK4_E_NOT_SUPPORTED : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 211);
+ } break;
+ case DK4_E_MEMORY_ALLOCATION_FAILED : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 212);
+ } break;
+ case DK4_E_OPEN_WRITE_FAILED : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 213);
+ } break;
+ case DK4_E_WRITE_FAILED : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 214);
+ } break;
+ case DK4_E_CLOSE_FAILED : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 215);
+ } break;
+ case DK4_E_SEC_CHECK : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 216);
+ } break;
+ default : {
+ log_1(NULL, 0UL, LOG_EMERG, 1, 107);
+ } break;
+ }
+ goto finished;
+ }
+ } else { $? "! open db (1)"
+ /* ERROR: Failed to open database */
+ pqd_dbi_open_error(fn, &er);
+ goto finished;
+ }
+
+ /* Finally indicate success.
+ */
+ back = 1;
+
+ finished:
+ $? "- inner_allocate_resources %d", back
+ return back;
+}
+
+
+
+/** Release resources after finishing inner loop.
+ * Log message for finishing service.
+ * Synchronize and close database.
+ * Close log file.
+*/
+static
+int
+inner_release_resources(void)
+{
+ const char *fn;
+ int back = 1;
+ $? "+ inner_release_resources"
+
+ /* Database
+ */
+ if (NULL != db) {
+ if (0 == dk4dbi_close(db, NULL)) { $? "! sync db"
+ /* ERROR: Failed to synchronize database to disk */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 108);
+ back = 0;
+ }
+ db = NULL;
+ db_modified = 0;
+ }
+
+ /* UDP socket set.
+ */
+ if (NULL != ss_udp) { $? "! udp socket set close"
+ dk4socket_set_close(ss_udp, NULL);
+ }
+ ss_udp = NULL;
+
+ /* TCP listener socket set.
+ */
+ if (NULL != ss_tcp) { $? "! tcp socket set close"
+ dk4socket_set_close(ss_tcp, NULL);
+ }
+ ss_tcp = NULL;
+
+ /* Unix listener socket.
+ */
+ if (INVALID_SOCKET != so_unix) { dk4socket_close(so_unix, NULL); }
+ so_unix = INVALID_SOCKET;
+ fn = conf.sname;
+ if (NULL == fn) { fn = def_sock_file_name; }
+ (void)dk4delete_file_c8(fn, NULL);
+
+ $? "- inner_release_resources"
+ return back;
+}
+
+
+
+/** Switch to non-privileged user and group if configured to do so.
+ @return 1 on success (can continue), 0 on error (exit).
+*/
+static
+int
+change_group_and_user(void)
+{
+ const char *fn = NULL;
+ uid_t myuid;
+ gid_t mygid;
+ int dbt = DK4_DB_BE_UNKNOWN;
+ int back = 1;
+ $? "+ change_group_and_user"
+ if (0 != user_switched) { $? ". already switched"
+ if (conf.uid != prev_uid) {
+ back = 0; $? "! re-switch user"
+ /* ERROR: User to run as was changed */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 66);
+ } else {
+ if (conf.gid != prev_gid) { $? "! re-switch group"
+ back = 0;
+ /* ERROR: Group to run as was changed */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 67);
+ }
+ }
+ } else { $? ". not yet switched"
+ user_switched = 1;
+ myuid = geteuid();
+ mygid = getegid();
+ if ((myuid != conf.uid) || (mygid != conf.gid)) { $? ". must switch"
+ /*
+ PID file ownership and permissions
+ */
+ if (0 != chown(pid_file_name, conf.uid, conf.gid)) {
+ back = 0;
+ /* ERROR: Failed to change PID file ownership */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 217);
+ }
+ if (0 != chmod(pid_file_name, 0660)) {
+ back = 0;
+ /* ERROR: Failed to change PID file permissions */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 218);
+ }
+ /*
+ Log file ownership and permissions
+ */
+ fn = conf.lname;
+ if (NULL == fn) { fn = def_log_file_name; }
+ if (0 != chown(fn, conf.uid, conf.gid)) {
+ back = 0; $? "! log file ownership"
+ /* ERROR: Failed to change log file ownership */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 109);
+ }
+ if (0 != chmod(fn, 0660)) {
+ back = 0; $? "! log file permission"
+ /* ERROR: Failed to change log file permissions */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 110);
+ }
+ /*
+ Database ownership and permissions
+ */
+ if (0 == dk4dbi_change_owner_and_mode(db,conf.uid,conf.gid,0660,NULL)) {
+ back = 0; $? "! db ownership and permissions"
+ /* ERROR: failed to change db ownership and permissions */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 111);
+ }
+ switch ( (dbt = dk4dbi_get_type(db)) ) {
+ case DK4_DB_BE_BDB : case DK4_DB_BE_NDBM : {
+ $? ". close database, must re-open after switching user"
+ if (0 == dk4dbi_close(db, NULL)) { $? "! close failed"
+ /* ERROR: Failed to synchronize database to disk */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 121);
+ }
+ db = NULL;
+ db_modified = 0;
+ if (DK4_DB_BE_BDB == dbt) {
+ fn = ((NULL != conf.dname) ? (conf.dname) : (def_db_file_name));
+ fn = dk4dbi_filename_part(fn);
+ if (0 != chown(fn, conf.uid, conf.gid)) {
+ back = 0;
+ log_3(NULL, 0UL, LOG_EMERG, 1, 174, 175, fn);
+ }
+ if (0 != chmod(fn, 0660)) {
+ back = 0;
+ log_3(NULL, 0UL, LOG_EMERG, 1, 176, 177, fn);
+ }
+ }
+ } break;
+ }
+ /*
+ Local UNIX socket ownership and permission
+ */
+ if (INVALID_SOCKET != so_unix) { $? ". socket open"
+ $? ". fchown socket"
+ if (0 != fchown(so_unix, conf.uid, conf.gid)) {
+ back = 0; $? "! socket ownership"
+ /* ERROR: Failed to change socket ownership */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 112);
+ }
+ $? ". fchmod socket"
+ if (0 != fchmod(so_unix, 0660)) {
+ back = 0; $? "! socket permissions"
+ /* ERROR: Failed to change socket permissions */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 113);
+ }
+ } else { $? "! socket not yet open"
+ }
+ /*
+ Switch group
+ */
+ if (0 != setgid(conf.gid)) {
+ back = 0; $? "! switch group"
+ /* ERROR: Failed to switch group */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 114);
+ }
+ /*
+ Switch user
+ */
+ if (0 != setuid(conf.uid)) {
+ back = 0; $? "! switch user"
+ /* ERROR: Failed to switch user */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 115);
+ }
+ /*
+ Re-open database if closed.
+ */
+ if (NULL == db) { $? ". must reopen database"
+ fn = conf.dname;
+ if (NULL == fn) { fn = def_db_file_name; }
+ db = dk4dbi_open(fn, 1, 0, 1024, 1024, NULL);
+ if (NULL != db) {
+ db_modified = 0;
+ } else { $? "! failed to re-open database"
+ back = 0;
+ /* ERROR: Failed to open database */
+ log_3(NULL, 0UL, LOG_EMERG, 1, 105, 106, fn);
+ }
+ }
+ } else { $? ". user/group already ok"
+ }
+ }
+ $? "- change_group_and_user %d", back
+ return back;
+}
+
+
+
+static
+int
+protocol_level_for_address(struct sockaddr *so)
+{
+ int back = PQD_PROTO_NONE;
+ $? "+ protocol_level_for_address"
+ if (0 != conf.aglo) {
+ back = PQD_PROTO_ADMIN;
+ } else {
+ if (NULL != dk4sto_it_find_like(conf.i_aa, so, 1)) {
+ back = PQD_PROTO_ADMIN;
+ } else {
+ if (0 != conf.dglo) {
+ back = PQD_PROTO_DATA;
+ } else {
+ if (NULL != dk4sto_it_find_like(conf.i_ad, so, 1)) {
+ back = PQD_PROTO_DATA;
+ } else {
+ if (0 != conf.iglo) {
+ back = PQD_PROTO_INFO;
+ } else {
+ if (NULL != dk4sto_it_find_like(conf.i_ai, so, 1)) {
+ back = PQD_PROTO_INFO;
+ }
+ }
+ }
+ }
+ }
+ }
+ $? "- protocol_level_for_address %d", back
+ return back;
+}
+
+
+
+/** Check whether the action is allowed in the protocol level.
+ @param act Action to check.
+ @param protlev Protocol level.
+ @return 1 if action is allowed, 0 otherwise.
+*/
+static
+int
+protocol_level_check(int act, int protlev)
+{
+ int back = 0;
+ $? "+ protocol_level_check act=%d protlev=%d", act, protlev
+ switch (act) {
+ case PQD_CMD_INFO : {
+ if (PQD_PROTO_INFO <= protlev) { back = 1; }
+ } break;
+ case PQD_CMD_CONTROL : {
+ if (PQD_PROTO_ADMIN <= protlev) { back = 1; }
+ } break;
+ default : {
+ if (PQD_PROTO_DATA <= protlev) { back = 1; }
+ } break;
+ }
+ $? "- protocol_level_check %d", back
+ return back;
+}
+
+
+
+static
+void
+job_init(pqd_rq_t *ptr)
+{
+ $? "+ job_init %s", TR_8PTR(ptr)
+ DK4_MEMRES(ptr, sizeof(pqd_rq_t));
+ ptr->connptr = NULL;
+ ptr->sto = NULL;
+ ptr->soa = NULL;
+ ptr->pnconn = NULL;
+ ptr->cmdptr = NULL;
+ ptr->argptr = NULL;
+ ptr->szsoa = 0;
+ ptr->sock = 0;
+ ptr->action = 0;
+ ptr->protlev = PQD_PROTO_NONE;
+ ptr->logthis = 1;
+ $? "- job_init"
+}
+
+
+
+static
+void
+account_init(pqd_account_t *ptr)
+{
+ $? "+ account_init %s", TR_8PTR(ptr)
+ DK4_MEMRES(ptr, sizeof(pqd_account_t));
+ ptr->limit = (dk4_um_t)0UL;
+ ptr->used = (dk4_um_t)0UL;
+ ptr->account = (dk4_um_t)0UL;
+ ptr->da = 0;
+ $? "- account_init"
+}
+
+
+
+/** Close a stream connection record.
+ @param sock Socket to close.
+ @param sto Container for the records.
+ @param ptr Record to delete, containing the socket.
+ @param pnconn Address of connection number variable to decrease.
+*/
+static
+void
+close_stream_conn(
+ dk4_socket_t sock,
+ dk4_sto_t *sto,
+ void *ptr,
+ size_t *pnconn
+)
+{
+ $? "+ close_stream_conn %d", (int)sock
+ if ((NULL != sto) && (NULL != ptr)) {
+ dk4sto_remove(sto, ptr, NULL);
+ }
+ if (INVALID_SOCKET != sock) {
+ (void)dk4socket_close(sock, NULL);
+ }
+ if (NULL != ptr) {
+ dk4mem_free(ptr);
+ }
+ if (NULL != pnconn) {
+ if (0 < *pnconn) {
+ *pnconn -= 1;
+ }
+ }
+ $? "- close_stream_conn"
+}
+
+
+
+/** Send a text response.
+ @param job Job structure.
+ @param str Text to send (still without newline).
+*/
+static
+void
+send_text(pqd_rq_t *job, const char *str)
+{
+ const char * msgs[3]; /* Log message text parts */
+ size_t sz; /* Number of bytes to send */
+ size_t wr; /* Number of bytes successfully sent */
+ int res; /* Operation result */
+ $? "+ send_text \"%s\"", TR_8STR(str)
+ if (0 != dk4str8_cpy_s(inbuf, sizeof(inbuf), str, NULL)) {
+ if (0 != job->logthis) {
+ msgs[0] = printqd_kw[86];
+ msgs[1] = str;
+ msgs[2] = NULL;
+ log_multipart_message(NULL, 0UL, LOG_EMERG, 0, msgs, 2);
+ }
+ if (0 != dk4str8_cat_s(inbuf, sizeof(inbuf), printqd_kw[5], NULL)) {
+ sz = dk4str8_len(inbuf);
+ wr = sz;
+ if ((NULL != job->soa) && (0 < job->szsoa)) { $? ". UDP"
+ (void)dk4socket_sendto(
+ job->sock, inbuf, &wr, 0, job->soa, job->szsoa, 0L, 0L, NULL
+ );
+ } else { $? ". TCP or local"
+ res = dk4socket_send(job->sock, inbuf, &wr, 0, 0L, 0L, NULL);
+ switch (res) {
+ case DK4_SOCKET_RESULT_SUCCESS :
+ case DK4_SOCKET_RESULT_IN_PROGRESS : {
+ if (wr != sz) { $? "! partial send"
+ res = DK4_SOCKET_RESULT_FAILED;
+ }
+ } break;
+ }
+ if (DK4_SOCKET_RESULT_FAILED == res) { $? "! partial or no send"
+ close_stream_conn(job->sock, job->sto, job->connptr, job->pnconn);
+ }
+ }
+ } else { $? "! text too long (2)"
+ /* ERROR: Response text too long (BUG)! */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 116);
+ }
+ } else { $? "! text too long (1)"
+ /* ERROR: Response text too long (BUG)! */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 116);
+ }
+ $? "- send_text"
+}
+
+
+
+/** Send response for info or acct-check request.
+ @param job Job structure.
+ @param account Account structure containing limits and used pages.
+ @param summary Summary: Allowed to print.
+ @param how How to respond: 0=info, 1=acct-check/jobstart.
+*/
+static
+void
+send_response(
+ pqd_rq_t *job,
+ pqd_account_t *account,
+ int summary,
+ int how
+)
+{
+ char res[16+32*sizeof(dk4_um_t)];
+ char b1[16+8*sizeof(dk4_um_t)];
+ int ok = 0;
+ $? "+ send_response"
+ switch (how) {
+ case 0: {
+ /* Limit Used Account Summary */
+ if (DK4_UM_MAX == account->limit) {
+ ok = dk4str8_cpy_s(res, sizeof(res), printqd_kw[84], NULL);
+ } else {
+ ok = dk4ma_write_c8_decimal_unsigned(
+ b1, sizeof(b1), account->limit, 0, NULL
+ );
+ if (0 != ok) {
+ ok = dk4str8_cpy_s(res, sizeof(res), b1, NULL);
+ }
+ }
+ if (0 != ok) {
+ ok = dk4ma_write_c8_decimal_unsigned(
+ b1, sizeof(b1), account->used, 0, NULL
+ );
+ if (0 != ok) {
+ ok = dk4str8_cat_s(res, sizeof(res), printqd_kw[85], NULL);
+ if (0 != ok) {
+ ok = dk4str8_cat_s(res, sizeof(res), b1, NULL);
+ if (0 != ok) {
+ ok = dk4ma_write_c8_decimal_unsigned(
+ b1, sizeof(b1), account->account, 0, NULL
+ );
+ if (0 != ok) {
+ ok = dk4str8_cat_s(res, sizeof(res), printqd_kw[85], NULL);
+ if (0 != ok) {
+ ok = dk4str8_cat_s(res, sizeof(res), b1, NULL);
+ if (0 != ok) {
+ ok = dk4ma_write_c8_decimal_signed(
+ b1, sizeof(b1), (dk4_im_t)summary, 0, NULL
+ );
+ if (0 != ok) {
+ ok = dk4str8_cat_s(res,sizeof(res),printqd_kw[85],NULL);
+ if (0 != ok) {
+ ok = dk4str8_cat_s(res, sizeof(res), b1, NULL);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if (0 != ok) {
+ send_text(job, res);
+ } else {
+ send_text(job, printqd_kw[83]);
+ }
+ } break;
+ default: {
+ if (0 != summary) {
+ send_text(job, printqd_kw[80]);
+ } else {
+ switch (account->da) {
+ case 0: {
+ send_text(job, printqd_kw[81]);
+ } break;
+ default: {
+ send_text(job, printqd_kw[82]);
+ } break;
+ }
+ }
+ } break;
+ }
+ $? "- send_response"
+}
+
+
+
+/** Get printer entry for name (printer or alias name).
+ @param name Printer or alias name.
+ @return Printer entry.
+*/
+static
+pqd_printer_t *
+get_printer_for_name(const char *name)
+{
+ pqd_printer_t *back = NULL;
+ pqd_printer_alias_t *al = NULL;
+ $? "+ get_printer_for_name \"%s\"", TR_8STR(name)
+ back = (pqd_printer_t *)dk4sto_it_find_like(conf.i_p, name, 1);
+ if (NULL == back) {
+ al = (pqd_printer_alias_t *)dk4sto_it_find_like(conf.i_a, name, 1);
+ if (NULL != al) {
+ back = al->pr;
+ }
+ }
+ $? "- get_printer_for_name %s", TR_8PTR(back)
+ return back;
+}
+
+
+
+/** Save one dk4_um_t value to database.
+ @param kwi Keyword index for key start.
+ @param un User name.
+ @param cn Class name.
+ @param val Value to store.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+save_one_number(
+ size_t kwi,
+ const char *un,
+ const char *cn,
+ dk4_um_t val
+)
+{
+ int back = 0;
+ int strok = 0;
+ $? "+ save_one_number \"%s\" \"%s\" %lu", TR_8STR(un), TR_8STR(cn), (unsigned long)val
+ if (0 != dk4str8_cpy_s(kb, sizeof(kb), printqd_kw[kwi], NULL)) {
+ if (0 != dk4str8_cat_s(kb, sizeof(kb), cn, NULL)) {
+ if (0 != dk4str8_cat_s(kb, sizeof(kb), printqd_kw[8], NULL)) {
+ if (0 != dk4str8_cat_s(kb, sizeof(kb), un, NULL)) {
+ if ((dk4_um_t)0UL != val) {
+ if(0 != dk4ma_write_c8_decimal_unsigned(vb,sizeof(vb),val,0,NULL)) {
+ strok = 1;
+ $? ". db set \"%s\"=\"%s\"", kb, vb
+ if (0 != dbi_set(db, kb, vb, NULL)) { $? ". saved"
+ back = 1;
+ }
+ else { $? "! db set"
+ /* ERROR: Failed to set DB entry */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 117);
+ }
+ }
+#if TRACE_DEBUG
+ else { $? "! to text"
+ }
+#endif
+ } else {
+ strok = 1;
+ $? ". db del \"%s\"", kb
+ if (0 != dbi_del(db, kb, NULL)) { $? ". deleted"
+ back = 1;
+ } else { $? "! db del"
+ /* ERROR: Failed to delete DB entry */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 118);
+ }
+ }
+ }
+ }
+ }
+ }
+ if (0 == strok) {
+ /* ##### ERROR: Strings too long */
+ }
+ $? "- save_one_number %d", back
+ return back;
+}
+
+
+
+/** Save changes in account to database.
+ @param oldacc Previous account information, may be NULL.
+ @param newacc Updated account information, not NULL.
+ @param un User name.
+ @param cl Class structure.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+save_account_for_user_and_class(
+ pqd_account_t *oldacc,
+ pqd_account_t *newacc,
+ const char *un,
+ pqd_class_t *cl
+)
+{
+ int mustsave; /* Flag: Must save item */
+ int back = 1;
+ $? "+ save_account_for_user_and_class"
+ mustsave = 1;
+ if (NULL != oldacc) {
+ if (oldacc->used == newacc->used) {
+ mustsave = 0;
+ }
+ }
+ if (0 != mustsave) { $? ". must save pages"
+ if (0 == save_one_number(88, un, cl->name, newacc->used)) {
+ back = 0;
+ }
+ }
+ mustsave = 1;
+ if (NULL != oldacc) {
+ if (oldacc->account == newacc->account) {
+ mustsave = 0;
+ }
+ }
+ if (0 != mustsave) { $? ". must save account"
+ if (0 == save_one_number(89, un, cl->name, newacc->account)) {
+ back = 0;
+ }
+ }
+ $? "- save_account_for_user_and_class %d", back
+ return back;
+}
+
+
+
+/** Retrieve account data for a user in a specified printer class.
+ @param account Data structure to fill.
+ @param un User name.
+ @param cl Printer class.
+ @param mi Flag: Must initialize account before filling it.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+retrieve_account_for_user_and_class(
+ pqd_account_t *account,
+ const char *un,
+ pqd_class_t *cl,
+ int mi
+)
+{
+ char **grmem = NULL;
+ const char *ep = NULL; /* End of data */
+ pqd_limit_t *lim = NULL; /* Limit set */
+ struct passwd *pw = NULL; /* Password struct */
+ struct group *gr = NULL; /* Group struct */
+ dk4_um_t um = (dk4_um_t)0UL; /* Value found in text */
+ gid_t pg = 0; /* Primary group */
+ int ingr = 0; /* Flag: User in group */
+ int back = 0;
+ $? "+ retrieve_account_for_user_and_class \"%s\" %s", TR_8STR(un), TR_PTR(cl)
+ /*
+ Check arguments
+ */
+ if (NULL == account) {
+ goto finished;
+ }
+ if (0 != mi) {
+ account_init(account);
+ }
+ if ((NULL == un) || (NULL == cl)) {
+ goto finished;
+ }
+ if (NULL == cl->name) {
+ goto finished;
+ }
+ /*
+ Use default action from class
+ */
+ account->da = cl->da;
+ /*
+ Find number of pages already printed
+ */
+ if (0 != dk4str8_cpy_s(kb, sizeof(kb), printqd_kw[88], NULL)) {
+ if (0 != dk4str8_cat_s(kb, sizeof(kb), cl->name, NULL)) {
+ if (0 != dk4str8_cat_s(kb, sizeof(kb), printqd_kw[8], NULL)) {
+ if (0 != dk4str8_cat_s(kb, sizeof(kb), un, NULL)) {
+ $? ". db get \"%s\"", kb
+ if (0 != dbi_get(db, kb, vb, sizeof(vb), NULL)) {
+ if (0 != dk4ma_input_c8_dec_dk4_um_t(&um, vb, &ep, 1, NULL)) {
+ account->used = um;
+ }
+#if TRACE_DEBUG
+ else { $? "! not a number"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! db get"
+ }
+#endif
+ }
+ }
+ }
+ }
+ /*
+ Find number of pages in personal print account
+ */
+ if (0 != dk4str8_cpy_s(kb, sizeof(kb), printqd_kw[89], NULL)) {
+ if (0 != dk4str8_cat_s(kb, sizeof(kb), cl->name, NULL)) {
+ if (0 != dk4str8_cat_s(kb, sizeof(kb), printqd_kw[8], NULL)) {
+ if (0 != dk4str8_cat_s(kb, sizeof(kb), un, NULL)) {
+ $? ". db get \"%s\"", kb
+ if (0 != dbi_get(db, kb, vb, sizeof(vb), NULL)) {
+ um = (dk4_um_t)0UL; ep = NULL;
+ if (0 != dk4ma_input_c8_dec_dk4_um_t(&um, vb, &ep, 1, NULL)) {
+ account->account = um;
+ }
+#if TRACE_DEBUG
+ else { $? "! not a number"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! db get"
+ }
+#endif
+ }
+ }
+ }
+ }
+ /*
+ Find user limit
+ */
+ $? ". check user limit"
+ lim = (pqd_limit_t *)dk4sto_it_find_like(cl->i_u, un, 1);
+ if (NULL != lim) { $? ". user limit found"
+ account->limit = lim->limit;
+ back = 1;
+ goto finished;
+ }
+ /*
+ Find group limit
+ */
+ $? ". check group limits"
+ pw = getpwnam(un);
+ if (NULL != pw) { $? ". pw found"
+ pg = pw->pw_gid;
+ dk4sto_it_reset(cl->i_g);
+ do {
+ $? ". loop start"
+ lim = dk4sto_it_next(cl->i_g);
+ if (NULL != lim) { $? ". yet another group limit"
+ if (lim->limit > account->limit) { $? ". group limit is higher"
+ $? ". group=\"%s\" limit=%lu", TR_8STR(lim->name), (unsigned long)(lim->limit)
+ gr = getgrnam(lim->name);
+ if (NULL != gr) { $? ". gr found"
+ if (pg == gr->gr_gid) { $? ". is users primary group"
+ account->limit = lim->limit;
+ back = 1;
+ } else { $? ". not primary group"
+ if (NULL != gr->gr_mem) {
+ grmem = gr->gr_mem;
+ ingr = 0;
+ while ((0 == ingr) && (NULL != *grmem)) {
+ $? ". compare \"%s\" \"%s\"", TR_8STR(un), TR_8STR(*grmem)
+ if (0 == strcmp(un, *grmem)) {
+ ingr = 1;
+ }
+ grmem++;
+ }
+ if (0 != ingr) { $? ". user is in group"
+ account->limit = lim->limit;
+ back = 1;
+ }
+#if TRACE_DEBUG
+ else { $? ". user is not in group"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? ". no members in group"
+ }
+#endif
+ }
+ }
+#if TRACE_DEBUG
+ else { $? "! group not found"
+ }
+#endif
+ }
+ }
+#if TRACE_DEBUG
+ else { $? "! no more group limits"
+ }
+#endif
+ $? ". loop end"
+ } while(NULL != lim);
+ if (0 != back) {
+ goto finished;
+ }
+ }
+#if TRACE_DEBUG
+ else { $? "! getpwnam"
+ }
+#endif
+ /*
+ Apply default limit
+ */
+ $? ". apply default limit"
+ account->limit = cl->dl;
+ back = 1;
+
+ finished:
+ $? "- retrieve_account_for_user_and_class %d", back
+ return back;
+}
+
+
+
+/** Retrieve user account data for a given user name and a given printer
+ name.
+ @param account Account structure to fill.
+ @param printer_name Print queue name or alias.
+ @param user_name User name.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+retrieve_account_data(
+ pqd_account_t *account,
+ const char *printer_name,
+ const char *user_name
+)
+{
+ pqd_printer_t *pr = NULL; /* Printer */
+ pqd_class_t *cl = NULL; /* Class */
+ int back = 0;
+ $? "+ retrieve_account_data p=\"%s\" u=\"%s\"", TR_8STR(printer_name), TR_8STR(user_name)
+ /*
+ Initialize account data
+ */
+ account_init(account);
+ /*
+ Find printer
+ */
+ pr = get_printer_for_name(printer_name);
+ if (NULL == pr) { $? "! no such printer"
+ goto finished;
+ }
+ /*
+ Find class for printer
+ */
+ cl = pr->cl;
+ if (NULL == cl) { $? "! no such class"
+ goto finished;
+ }
+ if (NULL == cl->name) { $? "! no class name"
+ goto finished;
+ }
+ /*
+ Search for data
+ */
+ back = retrieve_account_for_user_and_class(account, user_name, cl, 0);
+ /*
+ Return result
+ */
+ finished:
+ $? "- retrieve_account_data %d", back
+ return back;
+}
+
+
+
+/** Add a number of pages for a print job to existing account data.
+ @param account Account data for user.
+ @param pages Number of pages used by print job.
+*/
+static
+void
+account_add_pages_from_job(pqd_account_t *account, dk4_um_t pages)
+{
+ dk4_um_t available;
+
+ /* The limit is used first.
+ */
+ if (account->limit > account->used) {
+ available = account->limit - account->used;
+ if (available >= pages) {
+ account->used += pages;
+ pages = (dk4_um_t)0UL;
+ } else {
+ account->used = account->limit;
+ pages -= available;
+ }
+ }
+ /* The personal print account is used only if the limit is reached.
+ */
+ if ((dk4_um_t)0UL < pages) {
+ if (account->account >= pages) {
+ account->account -= pages;
+ } else {
+ pages -= account->account;
+ account->account = (dk4_um_t)0UL;
+ }
+ }
+ /* Finally keep track of pages printed over limit.
+ */
+ if ((dk4_um_t)0UL < pages) {
+ if ((DK4_UM_MAX - pages) >= account->used) {
+ account->used += pages;
+ } else {
+ account->used = DK4_UM_MAX;
+ }
+ }
+}
+
+
+
+/** Find summary (allowed to print) for account details.
+ @param limit Limit (maximum number of pages) for user.
+ @param used Number of used pages within the limit.
+ @param account Number of pages in additional personal print account.
+ @return 1 if printing is allowed, 0 otherwise.
+*/
+static
+int
+account_summary(dk4_um_t limit, dk4_um_t used, dk4_um_t account)
+{
+ int back = 0;
+ $? "+ account_summary l=%lu u=%lu a=%lu", (unsigned long)limit, (unsigned long)used, (unsigned long)account
+ if (DK4_UM_MAX == limit) { $? ". unlimited"
+ back = 1;
+ } else {
+ if (used < limit) { $? ". limit not yet reached"
+ back = 1;
+ } else {
+ if ((dk4_um_t)0UL < account) { $? ". positive account value"
+ back = 1;
+ }
+ }
+ }
+ $? "- account_summary %d", back
+ return back;
+}
+
+
+/** Process info or acct-check request, only retrieve data
+ without modifying anything.
+ @param job Data for one request to process.
+ @param how Response type: 0=info, 1=acct-check.
+*/
+static
+void
+rq_retrieve_data(pqd_rq_t *job, int how)
+{
+ pqd_account_t account;
+ char *printer_name = NULL;
+ char *user_name = NULL;
+ int summary = 0;
+ $? "+ rq_retrieve_data %d", how
+ printer_name = job->argptr;
+ if (NULL != printer_name) {
+ user_name = dk4str8_next(printer_name, NULL);
+ if (NULL != user_name) {
+ (void)dk4str8_next(user_name, NULL);
+ }
+ }
+ if ((NULL != printer_name) && (NULL != user_name)) {
+ if (0 != retrieve_account_data(&account, printer_name, user_name)) {
+#if VERSION_BEFORE_20160329
+ if ((account.used < account.limit) || ((dk4_um_t)0UL < account.account)) {
+ summary = 1;
+ }
+#else
+ summary = account_summary(account.limit, account.used, account.account);
+#endif
+ }
+ send_response(job, &account, summary, how);
+ } else {
+ /* Close connection on malformed request.
+ */
+ if ((NULL == job->soa) && (0 == job->szsoa)) {
+ close_stream_conn(job->sock, job->sto, job->connptr, job->pnconn);
+ }
+ }
+ $? "- rq_retrieve_data"
+}
+
+
+
+/** Process info request.
+ @param job Data for one request to process.
+*/
+static
+void
+rq_info(pqd_rq_t *job)
+{
+ $? "+ rq_info"
+ rq_retrieve_data(job, 0);
+ $? "- rq_info"
+}
+
+
+
+/** Find final quote for current word.
+ @param str String to find quote in.
+ @param quote Quote character.
+ @return Pointer to found quote on success, NULL on error.
+*/
+static
+char *
+lprng_final_quote(char *str, char quote)
+{
+ char *back = NULL;
+ $? "+ lprng_final_quote %c %s", quote, TR_8STR(str)
+ while (('\0' != *str) && (NULL == back)) {
+ if (quote == *str) {
+ *str = '\0';
+ back = str;
+ back++;
+ back = dk4str8_start(back, NULL);
+ } else {
+ if ('\\' == *str) {
+ if ('\0' != str[1]) {
+ dk4str8_cpy_to_left(str, &(str[1]));
+ str++;
+ } else {
+ *str = '\0';
+ }
+ } else {
+ str++;
+ }
+ }
+ }
+ $? "- lprng_final_quote \"%s\"", TR_8STR(back)
+ return back;
+}
+
+
+
+/** Find start of next text word in LPRng accounting line.
+ @param str Current word (remaining text) in accounting line.
+ @return Pointer to next word if found, NULL on error.
+*/
+static
+char *
+lprng_next_word(char *str)
+{
+ char *back = NULL;
+ $? "+ lprng_next_word \"%s\"", TR_8STR(str)
+ switch (*str) {
+ case '\'' : {
+ back = lprng_final_quote(&(str[1]), '\'');
+ } break;
+ case '"' : {
+ back = lprng_final_quote(&(str[1]), '"');
+ } break;
+ default : {
+ back = dk4str8_next(str, NULL);
+ } break;
+ } $? "- lprng_next_word \"%s\"", TR_8STR(back)
+ return back;
+}
+
+
+
+/** Fill data structure from LPRng accounting line.
+ @param liptr Structure to fill.
+ @param textline The text line to use.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+lprng_info_from_line(lprng_info_t *liptr, char *textline)
+{
+ char *next;
+ int back = 1;
+ $? "+ lprng_info_from_line \"%s\"", TR_8STR(textline)
+ DK4_MEMRES(liptr, sizeof(lprng_info_t));
+ liptr->username = NULL; liptr->queuename = NULL;
+ liptr->jobtitle = NULL; liptr->pagecount = NULL;
+ while (NULL != textline) {
+ next = lprng_next_word(textline);
+ if (('\'' == *textline) || ('"' == *textline)) {
+ textline++;
+ }
+ if ('-' == *textline) {
+ textline++;
+ switch (*textline) {
+ case 'n': {
+ liptr->username = ++textline;
+ } break;
+ case 'P': {
+ liptr->queuename = ++textline;
+ } break;
+ case 'J': {
+ liptr->jobtitle = ++textline;
+ } break;
+ case 'p': {
+ liptr->pagecount = ++textline;
+ } break;
+ }
+ } else { $? "! not a minus"
+#if 0
+ /* 2016-02-15 Simply ignore non-option text.
+ */
+ back = 0;
+ /* ERROR: No minus sign */
+#endif
+ }
+ textline = next;
+ }
+ $? "- lprng_info_from_line %d", back
+ return back;
+}
+
+
+
+/** Process jobstart request.
+ @param job Data for one request to process.
+*/
+static
+void
+rq_jobstart(pqd_rq_t *job)
+{
+ lprng_info_t lpi;
+ pqd_account_t account;
+ char *un = NULL;
+ char *qn = NULL;
+ int summ = 0;
+ $? "+ rq_jobstart"
+ if (0 != lprng_info_from_line(&lpi, job->argptr)) {
+ un = lpi.username; qn = lpi.queuename;
+ }
+ if ((NULL != un) && (NULL != qn)) {
+ if (0 != retrieve_account_data(&account, qn, un)) {
+ summ = account_summary(account.limit, account.used, account.account);
+ }
+ send_response(job, &account, summ, 1);
+ } else {
+ /* Close connection on malformed request.
+ */
+ if ((NULL == job->soa) && (0 == job->szsoa)) {
+ close_stream_conn(job->sock, job->sto, job->connptr, job->pnconn);
+ }
+ }
+ $? "- rq_jobstart"
+}
+
+
+
+/** Report change result to log file.
+ @param un User name.
+ @param cl Class.
+ @param olda Old account values.
+ @param newa New account values.
+ @param pages Number of pages to add.
+ @param doadd Flag: Show added pages instead of used pages.
+*/
+static
+void
+log_old_and_new_account(
+ const char *un,
+ const pqd_class_t *cl,
+ const pqd_account_t *olda,
+ const pqd_account_t *newa,
+ dk4_um_t pages,
+ int doadd
+)
+{
+ char nb[8*sizeof(dk4_um_t)];
+ const char *msgs[2];
+ int res = 1;
+ if (0 == dk4str8_cpy_s(kb, sizeof(kb), un, NULL)) { res = 0; }
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), printqd_kw[85], NULL)) { res = 0; }
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), cl->name, NULL)) { res = 0; }
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), printqd_kw[7], NULL)) { res = 0; }
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), printqd_kw[145], NULL)) { res = 0; }
+ if (DK4_UM_MAX == olda->limit) {
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), printqd_kw[151], NULL)) { res = 0; }
+ } else {
+ if(0 != dk4ma_write_c8_decimal_unsigned(nb,sizeof(nb),olda->limit,0,NULL)) {
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), nb, NULL)) { res = 0; }
+ } else {
+ res = 0;
+ }
+ }
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), printqd_kw[146], NULL)) { res = 0; }
+ if(0 != dk4ma_write_c8_decimal_unsigned(nb,sizeof(nb),olda->used,0,NULL)) {
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), nb, NULL)) { res = 0; }
+ } else {
+ res = 0;
+ }
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), printqd_kw[147], NULL)) { res = 0; }
+ if(0 != dk4ma_write_c8_decimal_unsigned(nb,sizeof(nb),olda->account,0,NULL)) {
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), nb, NULL)) { res = 0; }
+ } else {
+ res = 0;
+ }
+ switch (doadd) {
+ case 1: {
+ if (0 == dk4str8_cat_s(kb,sizeof(kb),printqd_kw[153],NULL)) { res = 0; }
+ } break;
+ default: {
+ if (0 == dk4str8_cat_s(kb,sizeof(kb),printqd_kw[148],NULL)) { res = 0; }
+ } break;
+ }
+ if(0 != dk4ma_write_c8_decimal_unsigned(nb,sizeof(nb),pages,0,NULL)) {
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), nb, NULL)) { res = 0; }
+ } else {
+ res = 0;
+ }
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), printqd_kw[149], NULL)) { res = 0; }
+ if (DK4_UM_MAX == newa->limit) {
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), printqd_kw[151], NULL)) { res = 0; }
+ } else {
+ if(0 != dk4ma_write_c8_decimal_unsigned(nb,sizeof(nb),newa->limit,0,NULL)) {
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), nb, NULL)) { res = 0; }
+ } else {
+ res = 0;
+ }
+ }
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), printqd_kw[146], NULL)) { res = 0; }
+ if(0 != dk4ma_write_c8_decimal_unsigned(nb,sizeof(nb),newa->used,0,NULL)) {
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), nb, NULL)) { res = 0; }
+ } else {
+ res = 0;
+ }
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), printqd_kw[147], NULL)) { res = 0; }
+ if(0 != dk4ma_write_c8_decimal_unsigned(nb,sizeof(nb),newa->account,0,NULL)) {
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), nb, NULL)) { res = 0; }
+ } else {
+ res = 0;
+ }
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), printqd_kw[150], NULL)) { res = 0; }
+ if (0 != res) {
+ msgs[0] = kb;
+ msgs[1] = NULL;
+ log_multipart_message(NULL, 0UL, LOG_EMERG, 0, msgs, 1);
+ }
+}
+
+
+
+/** Charge user for a print job.
+ @param job Job structure.
+ @param un User name.
+ @param cl Printer class of printer the job was printed on.
+ @param pcval Number of pages in print job.
+*/
+static
+void
+do_charge(
+ pqd_rq_t *job,
+ const char *un,
+ pqd_class_t *cl,
+ dk4_um_t pcval
+)
+{
+ pqd_account_t oldacc;
+ pqd_account_t newacc;
+ $? "+ do_charge %s \"%s\" \"%s\" %lu", TR_8PTR(job), un, TR_8STR(cl->name), (unsigned long)pcval
+ if (0 != retrieve_account_for_user_and_class(&oldacc, un, cl, 1)) {
+ DK4_MEMCPY(&newacc, &oldacc, sizeof(pqd_account_t));
+ account_add_pages_from_job(&newacc, pcval);
+ log_old_and_new_account(un, cl, &oldacc, &newacc, pcval, 0);
+ if (0 == save_account_for_user_and_class(&oldacc, &newacc, un, cl)) {
+ $? "! failed to save updated account data"
+ /* ERROR: Failed to update account data */
+ log_5(NULL, 0UL, LOG_EMERG, 1, 156, 157, 158, un, cl->name);
+ }
+ }
+#if TRACE_DEBUG
+ else { $? "! failed to retrieve existing account data"
+ }
+#endif
+ $? "- do_charge"
+}
+
+
+
+/** On start of file printing save user name, job name and pagecount
+ value to database for later use.
+ @param job Job structure.
+ @param un User name.
+ @param pn Printer name.
+ @param jn Job name.
+ @param pc Printer page count at start of job.
+*/
+static
+void
+do_filestart(
+ pqd_rq_t *job,
+ const char *un,
+ const char *pn,
+ const char *jn,
+ const char *pc
+)
+{
+ const char *ep = NULL;
+ pqd_printer_t *pr = NULL;
+ pqd_class_t *cl = NULL;
+ dk4_um_t pcstt = (dk4_um_t)0UL;
+ int res = 0;
+ $? "+ do_filestart %s \"%s\" \"%s\" \"%s\" \"%s\"", TR_8PTR(job),un,pn,jn,pc
+ pr = get_printer_for_name(pn);
+ if (NULL != pr) {
+ cl = pr->cl;
+ }
+ if (NULL != cl) {
+ res = dk4ma_input_c8_dec_dk4_um_t(&pcstt, pc, &ep, 1, NULL);
+ }
+ if ((NULL != pr) && (NULL != cl) && (0 != res)) {
+ $? ". pr=\"%s\" cl=\"%s\"", pr->name, TR_8STR(cl->name)
+ if (0 == dk4str8_cpy_s(kb, sizeof(kb), printqd_kw[90], NULL)) { res = 0; }
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), pr->name, NULL)) { res = 0; }
+ if (0 == dk4str8_cpy_s(vb, sizeof(vb), pc, NULL)) { res = 0; }
+ if (0 == dk4str8_cat_s(vb, sizeof(vb), printqd_kw[8], NULL)) { res = 0; }
+ if (0 == dk4str8_cat_s(vb, sizeof(vb), un, NULL)) { res = 0; }
+ if (0 == dk4str8_cat_s(vb, sizeof(vb), printqd_kw[8], NULL)) { res = 0; }
+ if (0 == dk4str8_cat_s(vb, sizeof(vb), jn, NULL)) { res = 0; }
+ if (0 != res) { $? ". db set \"%s\"=\"%s\"", kb, vb
+ if (0 == dbi_set(db, kb, vb, NULL)) { $? "! db set"
+ /* ERROR: Failed to set database entry */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 117);
+ }
+ }
+#if TRACE_DEBUG
+ else { $? "! key or value name too long"
+ }
+#endif
+ } else { $? "! malformed request"
+ /* Close connection on malformed request
+ */
+ if ((NULL == job->soa) && (0 == job->szsoa)) {
+ close_stream_conn(job->sock, job->sto, job->connptr, job->pnconn);
+ }
+ }
+ $? "- do_filestart"
+}
+
+
+
+/** On end of file calculate page number used by the job and
+ save modified account to database.
+ @param job Job structure.
+ @param un User name.
+ @param pn Printer name.
+ @param jn Job name.
+ @param pc Printer page count at start of job.
+*/
+static
+void
+do_fileend(
+ pqd_rq_t *job,
+ const char *un,
+ const char *pn,
+ const char *jn,
+ const char *pc
+)
+{
+ const char *ep = NULL; /* End of processed text */
+ pqd_printer_t *pr = NULL; /* Printer */
+ pqd_class_t *cl = NULL; /* Printer class */
+ char *oun = NULL; /* Old user name */
+ char *opc = NULL; /* Old page counter value */
+ char *ojn = NULL; /* Old job name */
+ dk4_um_t pcstt = (dk4_um_t)0UL; /* Page counter at job start */
+ dk4_um_t pcend = (dk4_um_t)0UL; /* Page counter at job end */
+ int res = 0;
+
+ $? "+ do_fileend %s \"%s\" \"%s\" \"%s\" \"%s\"", TR_8PTR(job), un, pn, jn, pc
+ pr = get_printer_for_name(pn);
+ if (NULL != pr) {
+ cl = pr->cl;
+ }
+ if (NULL != cl) {
+ res = dk4ma_input_c8_dec_dk4_um_t(&pcend, pc, &ep, 1, NULL);
+ }
+ if ((NULL != pr) && (NULL != cl) && (0 != res)) {
+ if (0 == dk4str8_cpy_s(kb, sizeof(kb), printqd_kw[90], NULL)) { res = 0; }
+ if (0 == dk4str8_cat_s(kb, sizeof(kb), pr->name, NULL)) { res = 0; }
+ if (0 != res) { $? ". db get \"%s\"", kb
+ if (0 != dbi_get(db, kb, vb, sizeof(vb), NULL)) {
+ $? ". db del \"%s\"", kb
+ if (0 == dbi_del(db, kb, NULL)) {
+ /* ERROR: Failed to delete db entry */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 118);
+ }
+ $? ". db res \"%s\"", vb
+ opc = dk4str8_start(vb, NULL);
+ if (NULL != opc) {
+ oun = dk4str8_chr(opc, ':');
+ if (NULL != oun) {
+ *(oun++) = '\0';
+ oun = dk4str8_start(oun, NULL);
+ }
+ }
+ if (NULL != oun) {
+ ojn = dk4str8_chr(oun, ':');
+ if (NULL != ojn) {
+ *(ojn++) = '\0';
+ ojn = dk4str8_start(ojn, NULL);
+ }
+ }
+ if ((NULL != opc) && (NULL != oun) && (NULL != ojn)) {
+ $? ". user \"%s\", old \"%s\"", un, oun
+ $? ". job \"%s\", old \"%s\"", jn, ojn
+ $? ". page count \"%s\", old \"%s\"", pc, opc
+ if (0 == strcmp(ojn, jn)) {
+ if (0 == strcmp(oun, un)) {
+ ep = NULL;
+ res = dk4ma_input_c8_dec_dk4_um_t(&pcstt, opc, &ep, 1, NULL);
+ if (0 != res) {
+ if (pcend > pcstt) { $? ". charge user"
+ do_charge(job, un, cl, (pcend - pcstt));
+ }
+#if TRACE_DEBUG
+ else { $? "! pagecount unchanged"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! old pagecount not numeric"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! user name mismatch"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! job name mismatch"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! incomplete entry"
+ }
+#endif
+ }
+ else { $? "! not found"
+ $? ". db del \"%s\"", kb
+ if (0 == dbi_del(db, kb, NULL)) {
+ /* ERROR: Failed to delete db entry */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 118);
+ }
+ }
+ }
+#if TRACE_DEBUG
+ else { $? "! printer name too long"
+ }
+#endif
+ } else { $? "! malformed request"
+ /* Close connection on malformed request
+ */
+ if ((NULL == job->soa) && (0 == job->szsoa)) {
+ close_stream_conn(job->sock, job->sto, job->connptr, job->pnconn);
+ }
+ }
+ $? "- do_fileend"
+}
+
+
+
+/** Process filestart request.
+ @param job Data for one request to process.
+*/
+static
+void
+rq_filestart(pqd_rq_t *job)
+{
+ lprng_info_t lpi;
+ char *un = NULL;
+ char *pn = NULL;
+ char *jn = NULL;
+ char *pc = NULL;
+ $? "+ rq_filestart"
+ if (0 != lprng_info_from_line(&lpi, job->argptr)) {
+ un = lpi.username; pn = lpi.queuename;
+ jn = lpi.jobtitle; pc = lpi.pagecount;
+ }
+ if ((NULL != un) && (NULL != pn) && (NULL != jn) && (NULL != pc)) {
+ do_filestart(job, un, pn, jn, pc);
+ } else {
+ /* Close connection on malformed request
+ */
+ if ((NULL == job->soa) && (0 == job->szsoa)) {
+ close_stream_conn(job->sock, job->sto, job->connptr, job->pnconn);
+ }
+ }
+ $? "- rq_filestart"
+}
+
+
+
+/** Process fileend request.
+ @param job Data for one request to process.
+*/
+static
+void
+rq_fileend(pqd_rq_t *job)
+{
+ lprng_info_t lpi;
+ char *un = NULL;
+ char *pn = NULL;
+ char *jn = NULL;
+ char *pc = NULL;
+ $? "+ rq_fileend"
+ if (0 != lprng_info_from_line(&lpi, job->argptr)) {
+ un = lpi.username; pn = lpi.queuename;
+ jn = lpi.jobtitle; pc = lpi.pagecount;
+ }
+ if ((NULL != un) && (NULL != pn) && (NULL != jn) && (NULL != pc)) {
+ do_fileend(job, un, pn, jn, pc);
+ } else {
+ /* Close connection on malformed request
+ */
+ if ((NULL == job->soa) && (0 == job->szsoa)) {
+ close_stream_conn(job->sock, job->sto, job->connptr, job->pnconn);
+ }
+ }
+ $? "- rq_fileend"
+}
+
+
+
+/** Process acct-check request.
+ @param job Data for one request to process.
+*/
+static
+void
+rq_acct_check(pqd_rq_t *job)
+{
+ $? "+ rq_acct_check"
+ rq_retrieve_data(job, 1);
+ $? "- rq_acct_check"
+}
+
+
+
+/** Process acct-start request.
+ @param job Data for one request to process.
+*/
+static
+void
+rq_acct_start(pqd_rq_t *job)
+{
+ char *un = NULL;
+ char *pn = NULL;
+ char *jn = NULL;
+ char *pc = NULL;
+ $? "+ rq_acct_start"
+ pn = job->argptr;
+ if (NULL != pn) {
+ un = dk4str8_next(pn, NULL);
+ }
+ if (NULL != un) {
+ pc = dk4str8_next(un, NULL);
+ }
+ if (NULL != pc) {
+ jn = dk4str8_next(pc, NULL);
+ }
+ if (NULL != jn) {
+ (void)dk4str8_next(jn, NULL);
+ }
+ if ((NULL != un) && (NULL != pn) && (NULL != jn) && (NULL != pc)) {
+ do_filestart(job, un, pn, jn, pc);
+ } else {
+ /* Close connection on malformed request
+ */
+ if ((NULL == job->soa) && (0 == job->szsoa)) {
+ close_stream_conn(job->sock, job->sto, job->connptr, job->pnconn);
+ }
+ }
+ $? "- rq_acct_start"
+}
+
+
+
+/** Process acct-end request.
+ @param job Data for one request to process.
+*/
+static
+void
+rq_acct_end(pqd_rq_t *job)
+{
+ char *un = NULL;
+ char *pn = NULL;
+ char *jn = NULL;
+ char *pc = NULL;
+ $? "+ rq_acct_end"
+ pn = job->argptr;
+ if (NULL != pn) {
+ un = dk4str8_next(pn, NULL);
+ }
+ if (NULL != un) {
+ pc = dk4str8_next(un, NULL);
+ }
+ if (NULL != pc) {
+ jn = dk4str8_next(pc, NULL);
+ }
+ if (NULL != jn) {
+ (void)dk4str8_next(jn, NULL);
+ }
+ if ((NULL != un) && (NULL != pn) && (NULL != jn) && (NULL != pc)) {
+ do_fileend(job, un, pn, jn, pc);
+ } else {
+ /* Close connection on malformed request
+ */
+ if ((NULL == job->soa) && (0 == job->szsoa)) {
+ close_stream_conn(job->sock, job->sto, job->connptr, job->pnconn);
+ }
+ }
+ $? "- rq_acct_end"
+}
+
+
+
+/** Process acct-charge request.
+ @param job Data for one request to process.
+*/
+static
+void
+rq_acct_charge(pqd_rq_t *job)
+{
+ const char *ep = NULL;
+ pqd_printer_t *pr = NULL;
+ pqd_class_t *cl = NULL;
+ char *un = NULL;
+ char *pn = NULL;
+ char *pc = NULL;
+ dk4_um_t pcval = (dk4_um_t)0UL;
+ $? "+ rq_acct_charge"
+ pn = job->argptr;
+ if (NULL != pn) {
+ un = dk4str8_next(pn, NULL);
+ }
+ if (NULL != un) {
+ pc = dk4str8_next(un, NULL);
+ }
+ if (NULL != pc) {
+ (void)dk4str8_next(pc, NULL);
+ }
+ if (NULL != pn) {
+ pr = get_printer_for_name(pn);
+ }
+ if (NULL != pr) {
+ cl = pr->cl;
+ }
+ if (
+ (NULL != un) && (NULL != pn) && (NULL != pc) && (NULL != pr) && (NULL != cl)
+ )
+ {
+ if (0 != dk4ma_input_c8_dec_dk4_um_t(&pcval, pc, &ep, 1, NULL)) {
+ do_charge(job, un, cl, pcval);
+ } else {
+ /* Close connection on malformed request
+ */
+ if ((NULL == job->soa) && (0 == job->szsoa)) {
+ close_stream_conn(job->sock, job->sto, job->connptr, job->pnconn);
+ }
+ }
+ } else {
+ /* Close connection on malformed request
+ */
+ if ((NULL == job->soa) && (0 == job->szsoa)) {
+ close_stream_conn(job->sock, job->sto, job->connptr, job->pnconn);
+ }
+ }
+ $? "- rq_acct_charge"
+}
+
+
+
+/** Object for DB traversal in control requests.
+*/
+typedef struct {
+ dk4_sto_t *s; /**< Key name storage. */
+ dk4_sto_it_t *i; /**< Key name storage iterator. */
+ char *cn; /**< Class name. */
+ char *un; /**< User name. */
+} pqd_control_t;
+
+
+
+/** Comparison function for storage.
+ @param l Left object.
+ @param r Right object.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+static
+int
+db_entry_compare(const void *l, const void *r, int cr)
+{
+ int back = 0;
+ if (NULL != l) {
+ if (NULL != r) {
+ back = strcmp((const char *)l, (const char *)r);
+ if (-1 > back) back = -1;
+ if ( 1 < back) back = 1;
+ } else {
+ back = 1;
+ }
+ } else {
+ if (NULL != r) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+/** Traverse simple database containing text.
+ @param obj Object to modify during traversal.
+ @param k Key text.
+ @param v Value text.
+ @return 1 on success, 0 on error (continue traversal),
+ -1 on error (abort).
+*/
+static
+int
+rq_c_reset_traverse(void *obj, const char *k, const char *v)
+{
+ pqd_control_t *ctoptr = NULL; /* Traversal object pointer */
+ char *p1 = NULL; /* DB entry type */
+ char *p2 = NULL; /* Class name */
+ char *p3 = NULL; /* User name */
+ int clm = 0; /* Flag: Class name matches */
+ int unm = 0; /* Flag: User name matches */
+ int back = 1;
+ $? "+ rq_c_reset_traverse \"%s\"=\"%s\"", TR_8STR(k), TR_8STR(v)
+ ctoptr = (pqd_control_t *)obj;
+ if (0 != dk4str8_cpy_s(kb, sizeof(kb), k, NULL)) {
+ p1 = dk4str8_start(kb, NULL);
+ if (NULL != p1) {
+ p2 = strchr(p1, ':');
+ if (NULL != p2) {
+ *(p2++) = '\0';
+ p2 = dk4str8_start(p2, NULL);
+ }
+ if (NULL != p2) {
+ if (0 == strcmp(p1, printqd_kw[152])) {
+ p3 = strchr(p2, ':');
+ if (NULL != p3) {
+ *(p3++) = '\0';
+ p3 = dk4str8_start(p3, NULL);
+ }
+ if (NULL != p3) {
+ if (NULL != ctoptr->cn) {
+ if (0 == strcmp(ctoptr->cn, p2)) {
+ clm = 1;
+ }
+ } else {
+ clm = 1;
+ }
+ if (0 != clm) {
+ if (NULL != ctoptr->un) {
+ if (0 == strcmp(ctoptr->un, p3)) {
+ unm = 1;
+ }
+ } else {
+ unm = 1;
+ }
+ if (0 != unm) {
+ p1 = dk4str8_dup(k, NULL);
+ if (NULL != p1) {
+ if (0 == dk4sto_add(ctoptr->s, p1, NULL)) {
+ dk4mem_free(p1); $? "! sto add"
+ }
+ }
+#if TRACE_DEBUG
+ else { $? "! insufficient memory"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! user name mismatch"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! class name mismatch"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! no third component"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! not a p entry"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! no second component"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! empty"
+ }
+#endif
+ }
+ if (0 == can_continue(0, 0)) { back = -1; }
+ $? "- rq_c_reset_traverse %d", back
+ return back;
+}
+
+
+
+/** Traverse simple database containing text.
+ @param obj Object to modify during traversal.
+ @param k Key text.
+ @param v Value text.
+ @return 1 on success, 0 on error (continue traversal),
+ -1 on error (abort).
+*/
+static
+int
+rc_c_dbcl_traverse(void *obj, const char *k, const char *v)
+{
+ pqd_control_t *pctobj;
+ pqd_class_t *cl;
+ char *p1; /* First argument */
+ char *p2; /* Second argument */
+ int cdel = 0; /* Flag: Can delete item */
+ int back = 1;
+
+ if (0 != dk4str8_cpy_s(kb, sizeof(kb), k, NULL)) {
+ if (0 != dk4str8_cpy_s(vb, sizeof(vb), k, NULL)) {
+ p1 = strchr(kb, ':');
+ if (NULL != p1) {
+ *(p1++) = '\0';
+ p1 = dk4str8_start(p1, NULL);
+ dk4str8_normalize(kb, NULL);
+ if (NULL != p1) {
+ pctobj = (pqd_control_t *)obj;
+ switch ( dk4str8_array_index(db_type_names, kb, 0) ) {
+ case 0 : /* p:class:user */
+ case 1 : /* a:class:user */
+ {
+ p2 = strchr(p1, ':');
+ if (NULL != p2) {
+ *(p2++) = '\0';
+ p2 = dk4str8_start(p2, NULL);
+ if (NULL != p2) {
+ dk4str8_normalize(p1, NULL);
+ dk4str8_normalize(p2, NULL);
+ cl = dk4sto_it_find_like(conf.i_c, p1, 1);
+ if (NULL != cl) {
+ if (NULL == dk4sto_it_find_like(cl->i_u, p2, 1)) {
+ if (NULL == getpwnam(p2)) {
+ cdel = 1;
+ }
+ }
+ } else {
+ cdel = 1;
+ }
+ if (0 != cdel) {
+ p1 = dk4str8_dup(vb, NULL);
+ if (NULL != p1) {
+ if (0 == dk4sto_add(pctobj->s, p1, NULL)) {
+ dk4mem_free(p1);
+ back = 0;
+ }
+ } else {
+ back = 0;
+ }
+ }
+ }
+ }
+ } break;
+ case 2 : { /* j:printer */
+ dk4str8_normalize(p1, NULL);
+ if (NULL == get_printer_for_name(p1)) {
+ p1 = dk4str8_dup(vb, NULL);
+ if (NULL != p1) {
+ if (0 == dk4sto_add(pctobj->s, p1, NULL)) {
+ dk4mem_free(p1);
+ back = 0;
+ }
+ } else {
+ back = 0;
+ }
+ }
+ } break;
+ }
+ }
+ }
+ }
+ }
+ if (0 == can_continue(0, 0)) { back = -1; }
+ return back;
+}
+
+
+
+/** Process control reset request.
+ @param job Arguments for request.
+*/
+static
+void
+rq_c_reset(pqd_rq_t *job)
+{
+ pqd_control_t ctobj;
+ char *pc;
+ char *pn;
+ char *pv;
+ $? "+ rq_c_reset"
+ /* Initialize variable
+ */
+ ctobj.s = NULL;
+ ctobj.i = NULL;
+ ctobj.cn = NULL;
+ ctobj.un = NULL;
+ /* Process command arguments
+ */
+ pc = job->argptr;
+ while (NULL != pc) {
+ pn = dk4str8_next(pc, NULL);
+ $? ". pc=\"%s\" pn=\"%s\"", pc, TR_8STR(pn)
+ pv = dk4str8_chr(pc, '=');
+ if (NULL != pv) {
+ *(pv++) = '\0';
+ pv = dk4str8_start(pv, NULL);
+ }
+ $? ". pc=\"%s\" pv=\"%s\"", pc, TR_8STR(pv)
+ if (NULL != pv) {
+ switch ( dk4str8_abbr_index(control_arg_names, '$', pc, 0) ) {
+ case 0 : {
+ ctobj.cn = pv;
+ } break;
+ case 1 : {
+ ctobj.un = pv;
+ } break;
+ default : {
+ $? ". unknown \"%s\"=\"%s\"", pc, pv
+ } break;
+ }
+ }
+ pc = pn;
+ }
+ $? ". class=%s user=%s", TR_8STR(ctobj.cn), TR_8STR(ctobj.un)
+ if (NULL != ctobj.cn) {
+ if (0 == dk4str8_cmp(printqd_kw[2], ctobj.cn)) { ctobj.cn = NULL; }
+ }
+ if (NULL != ctobj.un) {
+ if (0 == dk4str8_cmp(printqd_kw[2], ctobj.un)) { ctobj.un = NULL; }
+ }
+ ctobj.s = dk4sto_open(NULL);
+ if (NULL != ctobj.s) { $? ". storage"
+ dk4sto_set_comp(ctobj.s, db_entry_compare, 0);
+ ctobj.i = dk4sto_it_open(ctobj.s, NULL);
+ if (NULL != ctobj.i) { $? ". iterator"
+ (void)dk4dbi_c8_traverse(db, (void *)(&ctobj), rq_c_reset_traverse);
+ $? ". traversal finished"
+ dk4sto_it_reset(ctobj.i);
+ do {
+ pc = (char *)dk4sto_it_next(ctobj.i);
+ if (NULL != pc) { $? ". delete \"%s\"", pc
+ if (0 != can_continue(0, 0)) {
+ (void)dbi_del(db, pc, NULL);
+ }
+ dk4mem_free(pc);
+ }
+ } while (NULL != pc);
+ dk4sto_it_close(ctobj.i);
+ }
+#if TRACE_DEBUG
+ else { $? "! iterator"
+ }
+#endif
+ dk4sto_close(ctobj.s);
+ }
+#if TRACE_DEBUG
+ else { $? "! storage"
+ }
+#endif
+ $? "- rq_c_reset"
+}
+
+
+
+/** Process control add request.
+ @param job Arguments for request.
+*/
+static
+void
+rq_c_add(pqd_rq_t *job)
+{
+ pqd_account_t oldacc;
+ pqd_account_t newacc;
+ pqd_class_t *cl = NULL;
+ const char *ep = NULL;
+ char *clname = NULL;
+ char *uname = NULL;
+ char *ptext = NULL;
+ char *pc;
+ char *pn;
+ char *pv;
+ dk4_um_t pages = (dk4_um_t)0UL;
+
+ /* Process command arguments
+ */
+ pc = job->argptr;
+ while (NULL != pc) {
+ pn = dk4str8_next(pc, NULL);
+ pv = dk4str8_chr(pc, '=');
+ if (NULL != pv) {
+ *(pv++) = '\0';
+ pv = dk4str8_start(pv, NULL);
+ }
+ if (NULL != pv) {
+ switch ( dk4str8_abbr_index(control_arg_names, '$', pc, 0) ) {
+ case 0 : {
+ clname = pv;
+ } break;
+ case 1 : {
+ uname = pv;
+ } break;
+ case 2 : {
+ ptext = pv;
+ } break;
+ }
+ }
+ pc = pn;
+ }
+ if ((NULL != clname) && (NULL != uname) && (NULL != ptext)) {
+ if (0 != dk4ma_input_c8_dec_dk4_um_t(&pages, ptext, &ep, 1, NULL)) {
+ cl = dk4sto_it_find_like(conf.i_c, clname, 1);
+ if (NULL != cl) {
+ if (0 != retrieve_account_for_user_and_class(&oldacc, uname, cl, 1)) {
+ DK4_MEMCPY(&newacc, &oldacc, sizeof(pqd_account_t));
+ if ((DK4_UM_MAX - pages) >= newacc.account) {
+ newacc.account += pages;
+ } else {
+ newacc.account = DK4_UM_MAX;
+ }
+ log_old_and_new_account(uname, cl, &oldacc, &newacc, pages, 1);
+ if (0 == save_account_for_user_and_class(&oldacc,&newacc,uname,cl)) {
+ /* ERROR: Failed to save new account */
+ log_5(NULL, 0UL, LOG_EMERG, 1, 156, 157, 158, uname, cl->name);
+ }
+ } else {
+ /* ERROR: Failed to retrieve account data */
+ log_5(NULL, 0UL, LOG_EMERG, 1, 161, 162, 163, uname, cl->name);
+ }
+ } else {
+ /* ERROR: No such class */
+ log_3(NULL, 0UL, LOG_EMERG, 1, 164, 165, clname);
+ }
+ } else {
+ /* ERROR: ptext not numeric */
+ log_3(NULL, 0UL, LOG_EMERG, 1, 166, 167, ptext);
+ }
+ }
+}
+
+
+
+/** Process control database-cleanup request.
+ @param job Arguments for request.
+*/
+static
+void
+rq_c_dbcl(pqd_rq_t *job)
+{
+ pqd_control_t ctobj;
+ char *ptr;
+
+ DK4_MEMRES(&ctobj, sizeof(pqd_control_t));
+ ctobj.s = NULL;
+ ctobj.i = NULL;
+ ctobj.cn = NULL;
+ ctobj.un = NULL;
+
+ ctobj.s = dk4sto_open(NULL);
+ if (NULL != ctobj.s) {
+ dk4sto_set_comp(ctobj.s, db_entry_compare, 0);
+ ctobj.i = dk4sto_it_open(ctobj.s, NULL);
+ if (NULL != ctobj.i) {
+ (void)dk4dbi_c8_traverse(db, (void *)(&ctobj), rc_c_dbcl_traverse);
+ dk4sto_it_reset(ctobj.i);
+ do {
+ ptr = (char *)dk4sto_it_next(ctobj.i);
+ if (NULL != ptr) {
+ if (0 != can_continue(0, 0)) {
+ dbi_del(db, ptr, NULL);
+ }
+ dk4mem_free(ptr);
+ }
+ } while(NULL != ptr);
+ dk4sto_it_close(ctobj.i);
+ }
+ dk4sto_close(ctobj.s);
+ }
+}
+
+
+
+/** Process control request.
+ @param job Data for one request to process.
+*/
+static
+void
+rq_control(pqd_rq_t *job)
+{
+ char *subcmd;
+ int sc;
+ $? "+ rq_control"
+ subcmd = job->argptr;
+ job->argptr = dk4str8_next(subcmd, NULL);
+ $? ". argptr = \"%s\"", TR_8STR(job->argptr)
+ switch ( (sc = dk4str8_abbr_index(control_sub_cmds, '$', subcmd, 0)) ) {
+ case 0 : { $? ". reset"
+ rq_c_reset(job);
+ } break;
+ case 1 : { $? ". add"
+ rq_c_add(job);
+ } break;
+ case 2 : { $? ". database-cleanup"
+ rq_c_dbcl(job);
+ } break;
+ default : {
+ /* ERROR: Illegal sub-command */
+ log_3(NULL, 0UL, LOG_EMERG, 1, 168, 169, subcmd);
+ } break;
+ }
+ $? "- rq_control"
+}
+
+
+
+/** Process contents of the inbuf buffer, send response if necessary.
+ @param job Data for one request to process.
+*/
+static
+void
+process_data(pqd_rq_t *job)
+{
+ const char * msgs[3];
+ $? "+ process_data sock=%d level=%d addr=%s", job->sock, job->protlev, TR_8PTR(job->soa)
+ job->cmdptr = dk4str8_start(inbuf, NULL);
+ if (NULL != job->cmdptr) {
+ dk4str8_delnl(job->cmdptr);
+ /* LOG request */
+ if (0 == conf.linf) {
+ if ('i' == (job->cmdptr)[0]) {
+ if ('n' == (job->cmdptr)[1]) {
+ if ('f' == (job->cmdptr)[2]) {
+ if ('o' == (job->cmdptr)[3]) {
+ job->logthis = 0;
+ }
+ }
+ }
+ }
+ }
+ if (0 != job->logthis) {
+ msgs[0] = printqd_kw[87];
+ msgs[1] = job->cmdptr;
+ msgs[2] = NULL;
+ log_multipart_message(NULL, 0UL, LOG_EMERG, 0, msgs, 2);
+ }
+ /* Process request */
+ job->argptr = dk4str8_next(job->cmdptr, NULL);
+ job->action = dk4str8_array_index(pqd_command_names, job->cmdptr, 0);
+ if (0 != protocol_level_check(job->action, job->protlev)) {
+ switch (job->action) {
+ case PQD_CMD_INFO : {
+ rq_info(job);
+ } break;
+ case PQD_CMD_JOBSTART : {
+ rq_jobstart(job);
+ } break;
+ case PQD_CMD_FILESTART : {
+ rq_filestart(job);
+ } break;
+ case PQD_CMD_FILEEND : {
+ rq_fileend(job);
+ } break;
+ case PQD_CMD_ACCT_CHECK : {
+ rq_acct_check(job);
+ } break;
+ case PQD_CMD_ACCT_START : {
+ rq_acct_start(job);
+ } break;
+ case PQD_CMD_ACCT_END : {
+ rq_acct_end(job);
+ } break;
+ case PQD_CMD_ACCT_CHARGE : {
+ rq_acct_charge(job);
+ } break;
+ case PQD_CMD_CONTROL : {
+ rq_control(job);
+ } break;
+ }
+ } else {
+ /* Close connection if request is denied.
+ */
+ if ((NULL == job->soa) && (0 == job->szsoa)) {
+ close_stream_conn(job->sock, job->sto, job->connptr, job->pnconn);
+ }
+ }
+ }
+ $? "- process_data"
+}
+
+
+
+/** Run one pass within inner loop.
+*/
+static
+void
+one_pass(void)
+{
+ fd_set rfds; /* Read file desc set */
+ dk4_sockaddr_storage_t soa_sto; /* Remote address */
+ pqd_rq_t job; /* Job structure */
+ struct sockaddr *soa; /* Remote address */
+#if VERSION_BEFORE_20160329
+ struct sockaddr_in *soa4; /* Remote IPv4 address */
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ struct sockaddr_in6 *soa6; /* Remote IPv6 address */
+#endif
+#endif
+ pqd_l_conn_t *pconnloc; /* UNIX connection record */
+ pqd_n_conn_t *pconntcp; /* TCP connection record */
+ size_t sz_soa_sto; /* Address size */
+ size_t rdbytes; /* Number of bytes read */
+ size_t i; /* Traverse socket set */
+ dk4_socket_t sock; /* Current new socket */
+ int maxfd = 0; /* Maximum fd number */
+ int l_conn = 0; /* Flag: Local connection */
+ int l_proc = 0; /* Flag: Local processing */
+ int res = 0; /* Operation result */
+ int addrok; /* Flag: Address size ok */
+ int protlev; /* Procotol level for conn */
+
+ $? "+ one_pass"
+ /* Create file descriptor set for select.
+ */
+ FD_ZERO(&rfds);
+ /* Check for incoming UNIX conn rq only if maximum not yet reached.
+ */
+ if ((0 == conf.m_loc) || (con_loc < conf.m_loc)) {
+ FD_SET(so_unix,&rfds);
+ if (maxfd < so_unix) { maxfd = so_unix; }
+ }
+
+ /* Check for incoming TCP conn rq only if maximum not yet reached.
+ */
+ if ((NULL != ss_tcp) && ((0 == conf.m_tcp) || (con_tcp < conf.m_tcp))) {
+ for (i = 0; i < ss_tcp->szUsed; i++) {
+ FD_SET((ss_tcp->pSockets)[i],&rfds);
+ if (maxfd < (ss_tcp->pSockets)[i]) { maxfd = (ss_tcp->pSockets)[i]; }
+ }
+ }
+
+ /* Check for data on existing UNIX connections.
+ */
+ dk4sto_it_reset(i_c_unix);
+ do {
+ pconnloc = (pqd_l_conn_t *)dk4sto_it_next(i_c_unix);
+ if (NULL != pconnloc) {
+ FD_SET(pconnloc->sock,&rfds);
+ if (maxfd < pconnloc->sock) { maxfd = pconnloc->sock; }
+ }
+ } while (NULL != pconnloc);
+
+ /* Check for data on existing TCP connections.
+ */
+ dk4sto_it_reset(i_c_tcp);
+ do {
+ pconntcp = (pqd_n_conn_t *)dk4sto_it_next(i_c_tcp);
+ if (NULL != pconntcp) {
+ FD_SET(pconntcp->sock,&rfds);
+ if (maxfd < pconntcp->sock) { maxfd = pconntcp->sock; }
+ }
+ } while (NULL != pconntcp);
+
+ /* Check for data on UDP sockets.
+ */
+ if (NULL != ss_udp) {
+ for (i = 0; i < ss_udp->szUsed; i++) {
+ FD_SET((ss_udp->pSockets)[i],&rfds);
+ if (maxfd < (ss_udp->pSockets)[i]) { maxfd = (ss_udp->pSockets)[i]; }
+ }
+ }
+
+ /* Check for signal meanwhile.
+ */
+ if (0 == can_continue(1, 0)) { $? ". one_pass: interrupted"
+ goto finished;
+ }
+
+ /* Run select().
+ */
+ errno = 0;
+ res = select((1+maxfd), &rfds, NULL, NULL, NULL);
+ if (-1 == res) {
+ switch (errno) {
+ case EINTR: { $? ". one_pass: select interrupted"
+ goto finished;
+ } break;
+ default: { $? ". one_pass: error from select"
+ /* ERROR: Serious error from select() function */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 119);
+ ccouter = -1;
+ ccinner = -1;
+ goto finished;
+ } break;
+ }
+ }
+ if (0 == res) { $? ". one_pass: no descriptors ready"
+ goto finished;
+ }
+
+ /* Check for new connection attempts on local socket.
+ */
+ if ((0 == conf.m_loc) || (con_loc < conf.m_loc)) {
+ if (0 != (FD_ISSET(so_unix,&rfds))) { $? ". one_pass: local conn"
+ sock = dk4socket_accept(so_unix, NULL, NULL, NULL);
+ if (INVALID_SOCKET != sock) {
+ pconnloc = dk4mem_new(pqd_l_conn_t,1,NULL);
+ if (NULL != pconnloc) {
+ pconnloc->sock = sock;
+ if (dk4sto_add(s_c_unix, pconnloc, NULL)) {
+ con_loc++;
+ l_conn = 1;
+ } else {
+ dk4mem_free(pconnloc);
+ (void)dk4socket_close(sock, NULL);
+ }
+ } else {
+ (void)dk4socket_close(sock, NULL);
+ /* ERROR: Memory */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 120);
+ ccouter = -1;
+ ccinner = -1;
+ }
+ }
+ }
+ }
+
+ /* Process data from local socket connections.
+ */
+ dk4sto_it_reset(i_c_unix);
+ do {
+ if (0 != can_continue(1, 0)) {
+ pconnloc = (pqd_l_conn_t *)dk4sto_it_next(i_c_unix);
+ if (NULL != pconnloc) {
+ if (0 != (FD_ISSET(pconnloc->sock,&rfds))) {
+ l_proc = 1; $? ". one_pass: local data"
+ rdbytes = sizeof(inbuf);
+ res = dk4socket_recv(
+ pconnloc->sock, inbuf, &rdbytes, 0, 0L, 0L, NULL
+ );
+ if (0 != can_continue(0, 0)) {
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ if (0 < rdbytes) {
+ if (sizeof(inbuf) > rdbytes) {
+ inbuf[rdbytes] = '\0';
+ job_init(&job);
+ job.sock = pconnloc->sock;
+ job.protlev = PQD_PROTO_ADMIN;
+ job.connptr = pconnloc;
+ job.sto = s_c_unix;
+ job.pnconn = &con_loc;
+ process_data(&job);
+ }
+ } else {
+ close_stream_conn(pconnloc->sock, s_c_unix, pconnloc, &con_loc);
+ }
+ } else {
+ close_stream_conn(pconnloc->sock, s_c_unix, pconnloc, &con_loc);
+ }
+ } else {
+ pconnloc = NULL;
+ }
+ }
+ }
+ } else {
+ pconnloc = NULL;
+ }
+ } while (NULL != pconnloc);
+
+ /* Skip TCP and UDP data if activity on higher priorized local sockets.
+ */
+ if ((0 != l_conn) || (0 != l_proc) || (0 == can_continue(1, 0))) {
+ $? ". one_pass: skip non-local processing"
+ goto finished;
+ }
+
+ /* Check for new connection attempts on TCP.
+ */
+ if ((NULL != ss_tcp) && ((0 == conf.m_tcp) || (con_tcp < conf.m_tcp))) {
+ for (i = 0; ((i < ss_tcp->szUsed) && (0 != can_continue(1, 0))); i++) {
+ if (0 != (FD_ISSET((ss_tcp->pSockets)[i],&rfds))) {
+ $? ". one_pass: tcp conn"
+ DK4_MEMRES(&soa_sto, sizeof(soa_sto));
+ sz_soa_sto = sizeof(soa_sto);
+ sock = dk4socket_accept(
+ (ss_tcp->pSockets)[i],
+ (struct sockaddr *)(&soa_sto), &sz_soa_sto, NULL
+ );
+ if (INVALID_SOCKET != sock) {
+#if VERSION_BEFORE_20160329
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ soa6 = (struct sockaddr_in6 *)(&soa_sto);
+#endif
+ soa4 = (struct sockaddr_in *)(&soa_sto);
+#endif
+ soa = (struct sockaddr *)(&soa_sto);
+ addrok = 0;
+ if (AF_INET == soa->sa_family) {
+ if (sizeof(struct sockaddr_in) == sz_soa_sto) {
+ addrok = 1;
+ }
+ }
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ if (AF_INET6 == soa->sa_family) {
+ if (sizeof(struct sockaddr_in6) == sz_soa_sto) {
+ addrok = 1;
+ }
+ }
+#endif
+ if (0 != addrok) {
+ protlev = protocol_level_for_address(soa);
+ if (PQD_PROTO_NONE < protlev) { $? ". allowed %d", protlev
+ pconntcp = dk4mem_new(pqd_n_conn_t,1,NULL);
+ if (NULL != pconntcp) {
+ pconntcp->sock = sock;
+ if (0 != dk4sto_add(s_c_tcp, pconntcp, NULL)) {
+#if VERSION_BEFORE_20160811
+ DK4_MEMCPY(&(pconntcp->raddr),&soa_sto,sizeof(&soa_sto));
+#else
+ DK4_MEMCPY(&(pconntcp->raddr),&soa_sto,sizeof(soa_sto));
+#endif
+ pconntcp->pqdpl = protlev;
+ } else {
+ dk4mem_free(pconntcp);
+ (void)dk4socket_close(sock, NULL);
+ /* ERROR: Memory */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 120);
+ ccouter = -1;
+ ccinner = -1;
+ }
+ } else {
+ (void)dk4socket_close(sock, NULL);
+ /* ERROR: Memory */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 120);
+ ccouter = -1;
+ ccinner = -1;
+ }
+ } else { $? "! denied client"
+ (void)dk4socket_close(sock, NULL);
+ }
+ } else { $? "! size/family mismatch"
+ (void)dk4socket_close(sock, NULL);
+ }
+ }
+ }
+ }
+ }
+ if (0 == can_continue(1, 0)) {
+ $? ". one_pass: interrupted"
+ goto finished;
+ }
+
+ /* Process data from TCP connections.
+ */
+ dk4sto_it_reset(i_c_tcp);
+ do {
+ if (0 != can_continue(1, 0)) {
+ pconntcp = (pqd_n_conn_t *)dk4sto_it_next(i_c_tcp);
+ if (NULL != pconntcp) {
+ if (0 != (FD_ISSET(pconntcp->sock,&rfds))) {
+ $? ". one_pass: tcp data"
+ rdbytes = sizeof(inbuf);
+ res = dk4socket_recv(
+ pconntcp->sock, inbuf, &rdbytes, 0, 0L, 0L, NULL
+ );
+ if (0 != can_continue(0, 0)) {
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ if (0 < rdbytes) {
+ if (sizeof(inbuf) > rdbytes) {
+ inbuf[rdbytes] = '\0';
+ job_init(&job);
+ job.sock = pconntcp->sock;
+ job.protlev = pconntcp->pqdpl;
+ job.connptr = pconntcp;
+ job.sto = s_c_tcp;
+ job.pnconn = &con_tcp;
+ process_data(&job);
+ }
+ } else {
+ close_stream_conn(pconntcp->sock, s_c_tcp, pconntcp, &con_tcp);
+ }
+ } else {
+ close_stream_conn(pconntcp->sock, s_c_tcp, pconntcp, &con_tcp);
+ }
+ } else {
+ }
+ }
+ }
+ } else {
+ pconntcp = NULL;
+ }
+ } while (NULL != pconntcp);
+ if (0 == can_continue(1, 0)) {
+ $? ". one_pass: interrupted"
+ goto finished;
+ }
+
+ /* Process UDP data.
+ */
+ if (NULL != ss_udp) {
+ for (i = 0; ((i < ss_udp->szUsed) && (0 != can_continue(1, 0))); i++) {
+ if (0 != (FD_ISSET((ss_udp->pSockets)[i],&rfds))) {
+ $? ". one_pass: udp data"
+ rdbytes = sizeof(inbuf);
+ sz_soa_sto = sizeof(soa_sto);
+ res = dk4socket_recvfrom(
+ (ss_udp->pSockets)[i], inbuf, &rdbytes, 0,
+ (struct sockaddr *)(&soa_sto), &sz_soa_sto, 0L, 0L, NULL
+ );
+ if ((DK4_SOCKET_RESULT_SUCCESS == res) && (0 < rdbytes)) {
+ if ((0 != can_continue(1, 0)) && (sizeof(inbuf) > rdbytes)) {
+ inbuf[rdbytes] = '\0';
+#if VERSION_BEFORE_20160329
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ soa6 = (struct sockaddr_in6 *)(&soa_sto);
+#endif
+ soa4 = (struct sockaddr_in *)(&soa_sto);
+#endif
+ soa = (struct sockaddr *)(&soa_sto);
+ addrok = 0;
+ if (AF_INET == soa->sa_family) {
+ if (sizeof(struct sockaddr_in) == sz_soa_sto) {
+ addrok = 1;
+ }
+ }
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ if (AF_INET6 == soa->sa_family) {
+ if (sizeof(struct sockaddr_in6) == sz_soa_sto) {
+ addrok = 1;
+ }
+ }
+#endif
+ if (0 != addrok) {
+ protlev = protocol_level_for_address(soa);
+ if (PQD_PROTO_NONE < protlev) {
+ job_init(&job);
+ job.sock = (ss_udp->pSockets)[i];
+ job.protlev = PQD_PROTO_INFO;
+ job.soa = (struct sockaddr *)(&soa_sto);
+ job.szsoa = sz_soa_sto;
+ process_data(&job);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ finished:
+ $? ". end of pass, synchronize db"
+ if (0 == dbi_sync(db, NULL)) {
+ /* ERROR: Failed to synchronize database */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 121);
+ }
+ if (0 == can_continue(1, 0)) {
+ ccinner = 0;
+ if (0 == can_continue(0, 0)) {
+ ccouter = 0;
+ }
+ }
+ $? "- one_pass"
+}
+
+
+
+
+/** Run two nested loops: The outer loop is only finished
+ by SIGTERM or SIGINT to exit the program, the inner loop
+ is also finished by SIGHUP to re-read the configuration.
+*/
+static
+void
+service_loops(void)
+{
+ $!trace-init /tmp/printqd.deb
+ $? "+ service_loops"
+ /* LOG: Daemon running */
+ log_1(NULL, 0UL, LOG_INFO, 0, 73);
+ if (outer_allocate_resources()) {
+ /* Outer loop is left on SIGTERM or SIGINT.
+ */
+ while(1 == ccouter) {
+ if (1 == can_continue(0, 0)) {
+ config_init();
+ if (0 != config_read()) {
+ if (inner_allocate_resources()) {
+ if (0 != change_group_and_user()) {
+ /* Inner loop is left on SIGHUP, SIGTERM or SIGINT.
+ */
+ ccinner = 1;
+ *sig_pass_pointer(&sig_had_hup) = 0;
+ prev_filelog_failed = 0;
+ /* LOG: Entering service mode */
+ log_1(NULL, 0UL, LOG_INFO, 0, 75);
+ while(1 == ccinner) {
+ if (1 == can_continue(1, 0)) { $? ". yet another pass"
+ one_pass();
+ } else { $? "! signal"
+ ccinner = 0;
+ if (0 == can_continue(0, 0)) {
+ ccouter = 0;
+ /* LOG: Exiting service mode */
+ log_1(NULL, 0UL, LOG_INFO, 0, 76);
+ } else {
+ /* LOG: Exiting service mode for reconfiguration */
+ log_1(NULL, 0UL, LOG_INFO, 0, 77);
+ }
+ }
+ }
+ /* LOG: Exited service mode */
+ log_1(NULL, 0UL, LOG_INFO, 0, 78);
+ } else { $? "! failed to change user"
+ ccouter = -1;
+ }
+ } else { $? "! inner resource allocation"
+ ccouter = -1;
+ }
+ if (0 == inner_release_resources()) { $? "! inner resource release"
+ ccouter = -1;
+ }
+ } else { $? "! configuration read"
+ ccouter = -1;
+ }
+ config_release();
+ } else { $? "! signal"
+ ccouter = 0;
+ }
+ }
+ }
+#if TRACE_DEBUG
+ else { $? "! outer resource allocation"
+ }
+#endif
+ outer_release_resources();
+ /* LOG: Daemon exiting */
+ log_1(
+ NULL, 0UL,
+ ((0 == ccouter) ? (LOG_INFO) : (LOG_ERR)),
+ ((0 == ccouter) ? (0) : (1)),
+ ((0 == ccouter) ? (74) : (187))
+ );
+ $? "- service_loops"
+ $!trace-end
+}
+
+
+
+/** Run service in debug mode or normal mode.
+*/
+static
+void
+set_signal_handlers_and_run_service(void)
+{
+ int loop_was_running = 0;
+#ifdef DK4_HAVE_SIGACTION
+#ifdef SIGHUP
+ struct sigaction ohup;
+ struct sigaction nhup;
+#endif
+#ifdef SIGPIPE
+ struct sigaction opipe;
+ struct sigaction npipe;
+#endif
+ struct sigaction oint;
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+#else
+#ifdef SIGPIPE
+ dk4_sig_handler_t *opipe = NULL;
+#endif
+#ifdef SIGHUP
+ dk4_sig_handler_t *ohup = NULL;
+#endif
+ dk4_sig_handler_t *oterm = NULL;
+ dk4_sig_handler_t *oint = NULL;
+#endif
+#ifdef DK4_HAVE_SIGACTION
+#ifdef SIGHUP
+ int shup = 0;
+#endif
+#ifdef SIGPIPE
+ int spipe = 0;
+#endif
+ int sint = 0;
+ int sterm = 0;
+ int s_f_i = 0;
+ int s_f_r = 0;
+#endif
+
+ /* Set signal handlers
+ */
+#if DK4_HAVE_SIGACTION
+#ifdef SIGPIPE
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ spipe = 1;
+#endif
+#ifdef SIGHUP
+ DK4_MEMRES(&nhup, sizeof(nhup));
+ nhup.sa_handler = sig_handler_hup;
+ nhup.sa_flags = 0;
+ if (0 != sigemptyset(&nhup.sa_mask)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaddset(&nhup.sa_mask, SIGHUP)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaction(SIGHUP, &nhup, &ohup)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ shup = 1;
+#endif
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ sterm = 1;
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ sint = 1;
+#else
+#ifdef SIGPIPE
+ opipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+#ifdef SIGHUP
+ ohup = sigset(SIGHUP, sig_handler_hup);
+#endif
+ oint = sigset(SIGINT, sig_handler_int);
+ oterm = sigset(SIGTERM, sig_handler_term);
+#endif
+
+
+ service_loops();
+ loop_was_running = 1;
+
+ finished:
+
+ /*
+ */
+ if (0 == loop_was_running) {
+ log_1(NULL, 0UL, LOG_ERR, 1, 72);
+ }
+
+ /* Restore signal handlers
+ */
+#if DK4_HAVE_SIGACTION
+ if (0 != s_f_i) {
+ /* ERROR: Failed to install signal handlers */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 68);
+ exval = EXIT_FAILURE;
+ }
+ if (0 != sint) {
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ s_f_r = 1;
+ }
+ }
+ if (0 != sterm) {
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ s_f_r = 1;
+ }
+ }
+#ifdef SIGHUP
+ if (0 != shup) {
+ if (0 != sigaction(SIGHUP, &ohup, NULL)) {
+ s_f_r = 1;
+ }
+ }
+#endif
+#ifdef SIGPIPE
+ if (0 != spipe) {
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ s_f_r = 1;
+ }
+ }
+#endif
+ if (0 != s_f_r) {
+ /* ERROR: Failed to restore signal handlers */
+ log_1(NULL, 0UL, LOG_EMERG, 1, 69);
+ exval = EXIT_FAILURE;
+ }
+#else
+ if (NULL != oterm) { sigset(SIGTERM, oterm); }
+ if (NULL != oint ) { sigset(SIGINT, oint ); }
+#ifdef SIGHUP
+ if (NULL != ohup) { sigset(SIGHUP, ohup); }
+#endif
+#ifdef SIGPIPE
+ if (NULL != opipe) { sigset(SIGPIPE, opipe); }
+#endif
+#endif
+
+}
+
+
+
+/** Program entry point.
+ @param argc
+ @param argv
+ @return 0 on success, any other value indicates an error.
+*/
+int
+main(int argc, char *argv[])
+{
+ pid_t cpid; /* Child process PID */
+ int res; /* Operation result */
+
+ /* Process command line arguments.
+ */
+ res = dk4opt_process_argv(
+ options, szoptions, argc, argv, NULL, NULL, 1, 1, NULL
+ );
+ if (0 == res) {
+ exval = 2; /* Invalid or excess arguments */
+ goto finished;
+ }
+
+ /* Must be started as root.
+ */
+ if (0 != geteuid()) {
+ fputs("printqd: ERROR: Must be run as root!\n", stderr);
+ fflush(stderr);
+ goto finished;
+ }
+
+ /* Check used command line arguments.
+ */
+ if (0 != options[0].found) { debug = 1; }
+
+ /* Run in debug mode.
+ */
+ if (0 != debug) {
+ set_signal_handlers_and_run_service();
+ goto finished;
+ }
+
+ /* PREPARE TO RUN AS DAEMON
+ */
+ if (0 == dk4dmt_parent_before_fork(printqd_kw[0],pid_file_name,1,syslogf)) {
+ goto finished;
+ }
+
+ /* Create first background process
+ */
+ cpid = fork();
+ if ((pid_t)0 < cpid) {
+ /* In the parent process */
+ goto finished;
+ } else {
+ if ((pid_t)0 == cpid) {
+ /* In the child process, continue below */
+ } else {
+ /* Failed to create process */
+ /* ERROR: fork() failed */
+ fputs(printqd_kw[0], stderr);
+ fputs(printqd_kw[70], stderr);
+ fflush(stderr);
+ goto finished;
+ }
+ }
+
+ /* Intermediate process and daemon process should indicate success.
+ */
+ exval = EXIT_SUCCESS;
+
+ /* Decouple from terminals.
+ */
+ if (0 == dk4dmt_intermediate_before_fork(printqd_kw[0], syslogf)) {
+ goto finished;
+ }
+
+ /* Create daemon background process from within first background process
+ */
+ cpid = fork();
+ if ((pid_t)0 < cpid) {
+ /* In the intermediate process */
+ goto finished;
+ } else {
+ if ((pid_t)0 == cpid) {
+ /* In the daemon process, continue below */
+ } else {
+ /* Failed to create process */
+ /* ERROR: fork() failed */
+ log_1(NULL, 0UL, LOG_ERR, 1, 71);
+ goto finished;
+ }
+ }
+
+ /* In the daemon process
+ */
+ if (0 != dk4dmt_daemon_after_fork(printqd_kw[0], pid_file_name, syslogf)) {
+ set_signal_handlers_and_run_service();
+ }
+ dk4dmt_daemon_end(printqd_kw[0], pid_file_name, syslogf);
+
+ /* Exit the program.
+ */
+ finished:
+ exit(exval); return exval;
+}
+
+#else
+
+/** Program entry point.
+ @param argc
+ @param argv
+ @return 0 on success, any other value indicates an error.
+*/
+int
+main(int argc, char *argv[])
+{
+ fputs("printqd: ERROR: Build requirements violation!\n", stderr);
+#if DK4_CHAR_SIZE > 1
+ fputs("Default character size is larger than 1!\n", stderr);
+#endif
+#if !((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET))
+ fputs("Neither sigaction() nor sigset() are available!\n", stderr);
+#endif
+#if !(DK4_HAVE_PWD_H)
+ fputs("Include file \"pwd.h\" not found!\n", stderr);
+#endif
+#if !(DK4_HAVE_UID_T)
+ fputs("Data type uid_t not available!\n", stderr);
+#endif
+#if !(DK4_HAVE_GRP_H)
+ fputs("Include file \"grp.h\" not found!\n", stderr);
+#endif
+#if !(DK4_HAVE_GID_T)
+ fputs("Data type gid_t not available!\n", stderr);
+#endif
+#if !(DK4_HAVE_MODE_T)
+ fputs("Data type mode_t not available!\n", stderr);
+#endif
+#if !(DK4_HAVE_GETPWNAM)
+ fputs("Function getpwnam() is not available!\n", stderr);
+#endif
+#if !(DK4_HAVE_GETGRNAM)
+ fputs("Function getgrnam() is not available!\n", stderr);
+#endif
+#if !((DK4_HAVE_SETSID) || (DK4_HAVE_SETPGRP))
+ fputs("Neither setsid() nor setpgrp() are available!\n", stderr);
+#endif
+#if DK4_ON_WINDOWS
+ fputs("On Windows platform!\n", stderr);
+#endif
+ fflush(stderr);
+ exit(EXIT_FAILURE); return EXIT_FAILURE;
+}
+
+
+#endif
diff --git a/support/dktools/printqd.h b/support/dktools/printqd.h
new file mode 100644
index 0000000000..85014ecf48
--- /dev/null
+++ b/support/dktools/printqd.h
@@ -0,0 +1,242 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: printqd.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef PRINTQD_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define PRINTQD_H_INCLUDED 1
+
+
+#line 10 "printqd.ctr"
+
+/* CORRECT NEXT LINE AFTER REPLACING PRINTQD */
+
+/** @file printqd.h Definitions for printqd.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4STO_H_INCLUDED
+#include "dk4sto.h"
+#endif
+
+#ifndef DK4SOCK_H_INCLUDED
+#include "dk4sock.h"
+#endif
+
+
+
+/** Limit for one user or group.
+*/
+typedef struct {
+ char *name; /**< User or group name */
+ dk4_um_t limit; /**< Page limit. */
+} pqd_limit_t;
+
+
+
+
+/** Printer class (may contain multiple printers).
+*/
+typedef struct {
+ char *name; /**< Class name. */
+ dk4_sto_t *s_u; /**< User limits storage. */
+ dk4_sto_it_t *i_u; /**< User limits storage iterator. */
+ dk4_sto_t *s_g; /**< Group limits storage. */
+ dk4_sto_it_t *i_g; /**< Group limits storage iterator. */
+ dk4_um_t dl; /**< Default limit. */
+ int da; /**< Deny action: 1=hold, 0=remove. */
+ int hdl; /**< Flag: Have default limit. */
+} pqd_class_t;
+
+
+
+/** Printer.
+*/
+typedef struct {
+ char *name; /**< Printer name. */
+ pqd_class_t *cl; /**< Printer class. */
+} pqd_printer_t;
+/*
+ In service the class is not NULL.
+ If no class is configured for a printer, the program complains
+ and exits.
+*/
+
+
+
+/** Printer alias.
+*/
+typedef struct {
+ char *name; /**< Alias name. */
+ pqd_printer_t *pr; /**< The real printer. */
+} pqd_printer_alias_t;
+
+
+
+/** Printqd configuration.
+*/
+typedef struct {
+ char *sname; /**< UNIX domain socket file name. */
+ char *dname; /**< Database name (including type). */
+ char *lname; /**< Log file name. */
+ dk4_sto_t *s_c; /**< Storage for classes. */
+ dk4_sto_it_t *i_c; /**< Iterator for class storage. */
+ dk4_sto_t *s_p; /**< Storage for printers. */
+ dk4_sto_it_t *i_p; /**< Iterator for printers storage. */
+ dk4_sto_t *s_a; /**< Storage for aliases. */
+ dk4_sto_it_t *i_a; /**< Iterator for aliases storage. */
+ dk4_sto_t *s_ai; /**< Storage for peers allowed info rq. */
+ dk4_sto_it_t *i_ai; /**< Iterator for info peers storage. */
+ dk4_sto_t *s_ad; /**< Storage for peers allowed data rq. */
+ dk4_sto_it_t *i_ad; /**< Iterator for data peers storage. */
+ dk4_sto_t *s_aa; /**< Storage for peers allowed admin rq. */
+ dk4_sto_it_t *i_aa; /**< Iterator for admin peers storage. */
+ size_t m_loc; /**< Maximum number of local connections. */
+ size_t m_tcp; /**< Maximum number of TCP connections. */
+ uid_t uid; /**< Run as specified user. */
+ uid_t suid; /**< Local socket owner UID. */
+ gid_t gid; /**< Run as specified group. */
+ gid_t sgid; /**< Local socket owner GID. */
+ int slbl; /**< Backlog for local socket. */
+ int snbl; /**< Backlog for network socket. */
+ int iglo; /**< Flag: Globally allow info requests. */
+ int dglo; /**< Flag: Globally allow data requests. */
+ int aglo; /**< Flag: Globally allow admin requests. */
+ int linf; /**< Flag: Log info requests. */
+ int ldb; /**< Flag: Log database modifications. */
+ unsigned short ptcp; /**< TCP port (info, data, admin), host repr. */
+ unsigned short pudp; /**< UDP port (info only), host represent. */
+} pqd_conf_t;
+
+
+
+/** Connection record for local socket.
+*/
+typedef struct {
+ dk4_socket_t sock; /**< Socket. */
+} pqd_l_conn_t;
+
+
+
+/** Connection record for network socket.
+*/
+typedef struct {
+ dk4_sockaddr_storage_t raddr; /**< Remote address. */
+ dk4_socket_t sock; /**< Socket. */
+ int pqdpl; /**< Printqd protocol level. */
+} pqd_n_conn_t;
+
+
+
+/** One request to process.
+*/
+typedef struct {
+ void *connptr; /**< Connection record for socket. */
+ dk4_sto_t *sto; /**< Container for conn records. */
+ struct sockaddr *soa; /**< Remote address, only UDP. */
+ size_t *pnconn; /**< Addr of variable, NULL for UDP. */
+ char *cmdptr; /**< Start of command. */
+ char *argptr; /**< Command arguments. */
+ size_t szsoa; /**< Size of rem address, only UDP. */
+ dk4_socket_t sock; /**< Socket to use for response. */
+ int protlev; /**< Protocol level. */
+ int action; /**< Action to take. */
+ int logthis; /**< Flag: Log request and response. */
+} pqd_rq_t;
+
+
+
+/** Data for one user in a class.
+*/
+typedef struct {
+ dk4_um_t limit; /**< Limit (maximum page number). */
+ dk4_um_t used; /**< Number of pages used within limit. */
+ dk4_um_t account; /**< Remaining pages personal print account. */
+ int da; /**< Deny action: 0=remove, 1=hold. */
+} pqd_account_t;
+
+
+
+/** Information from one LPRng accounting line.
+*/
+typedef struct {
+ char *username; /**< User name. */
+ char *queuename; /**< Print queue name. */
+ char *jobtitle; /**< Print job title. */
+ char *pagecount; /**< Pagecount reported in line. */
+} lprng_info_t;
+
+
+
+
+/** Printqd protocol levels.
+*/
+enum {
+ PQD_PROTO_NONE = 0 , /**< No requests allowed. */
+ PQD_PROTO_INFO = 1 , /**< Info requests only. */
+ PQD_PROTO_DATA = 2 , /**< Info and data requests. */
+ PQD_PROTO_ADMIN = 3 /**< Info, data and admin requests. */
+};
+
+
+
+/** Commands in the printqd protocol.
+*/
+enum {
+ PQD_CMD_NONE = -1 , /**< Illegal command. */
+ PQD_CMD_JOBSTART = 0 , /**< Start of print job, response required. */
+ PQD_CMD_JOBEND = 1 , /**< End of print job. */
+ PQD_CMD_START = 2 , /**< Start of printing (ignored). */
+ PQD_CMD_END = 3 , /**< End of printing (ignored). */
+ PQD_CMD_FILESTART = 4 , /**< Start of file printing (pc). */
+ PQD_CMD_FILEEND = 5 , /**< End of file printing (pc). */
+ PQD_CMD_INFO = 6 , /**< Information, response required. */
+ PQD_CMD_ACCT_CHECK = 7 , /**< Check permission, response required. */
+ PQD_CMD_ACCT_START = 8 , /**< Start of file printing (pc). */
+ PQD_CMD_ACCT_END = 9 , /**< End of file printing (pc). */
+ PQD_CMD_ACCT_CHARGE = 10 , /**< Summary for file printing (pc). */
+ PQD_CMD_CONTROL = 11 /**< Control request. */
+};
+
+
+
+
+#endif
diff --git a/support/dktools/printqda.c b/support/dktools/printqda.c
new file mode 100644
index 0000000000..64faa3c00c
--- /dev/null
+++ b/support/dktools/printqda.c
@@ -0,0 +1,1200 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: printqda.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file printqda.c The printqda module.
+*/
+
+
+#line 29 "printqda.ctr"
+
+#include "printqd.h"
+#include "printqda.h"
+
+
+
+
+
+#line 36 "printqda.ctr"
+
+
+/** If this is defined to 1, each original request / daemon
+ request pair is reported to stdout.
+*/
+#define PRINTQDA_DEBUG 0
+
+#if DK3_CHAR_SIZE == 1
+#if DK3_HAVE_STRUCT_SOCKADDR_UN
+
+
+/** Configuration file name relative to sysconf directory.
+*/
+static char const pqda_conffile[] = { PQD_CONFFILE };
+
+
+/** Constant non-localized keywords used by the module.
+*/
+static char const * const pqda_c8_kw[] = {
+/* 0 */
+"printqda",
+
+/* 1 */
+"dktools",
+
+/* 2 */
+" ",
+
+/* 3 */
+"acct-check",
+
+/* 4 */
+"acct-start",
+
+/* 5 */
+"acct-end",
+
+/* 6 */
+"printqdc",
+
+NULL
+
+
+#line 85 "printqda.ctr"
+};
+
+
+
+/** Localized message texts used by the program.
+*/
+static char const * const pqda_loc[] = {
+/* 0 */
+"printqda.str",
+
+/* 1 */
+"Option was already set: \"",
+
+/* 2 */
+"\"!",
+
+/* 3 */
+"Option not started by a character: \"",
+
+/* 4 */
+"\"!",
+
+/* 5 */
+"Empty option: \"",
+
+/* 6 */
+"\"!",
+
+/* 7 */
+"Syntax error in request!",
+
+/* 8 */
+"Syntax error, string not finalized!",
+
+/* 9 */
+"Request contents too long!",
+
+/* 10 */
+"Incomplete request! Missing one from:\nuser name, printer name, page count, job name, or job title!",
+
+/* 11 */
+"Too few arguments in request!",
+
+/* 12 */
+"Incomplete request, missing either user or printer name!",
+
+/* 13 */
+"Illegal control sub-request: \"",
+
+/* 14 */
+"\"!",
+
+/* 15 */
+"Connection failed, skipping all remaining input!",
+
+/* 16 */
+"Name of system configuration directory too long:\n\"",
+
+/* 17 */
+"\"!",
+
+/* 18 */
+"Failed to find system configuration directory!",
+
+/* 19 */
+"Only printqda can process control requests, not printqdc!",
+
+NULL
+
+
+#line 159 "printqda.ctr"
+};
+
+
+
+/** Request types (first word in request line).
+*/
+static char const * const pqda_request_types[] = {
+/* 0 */
+"info",
+
+/* 1 */
+"acct-check",
+
+/* 2 */
+"acct-start",
+
+/* 3 */
+"acct-end",
+
+/* 4 */
+"jobstart",
+
+/* 5 */
+"filestart",
+
+/* 6 */
+"fileend",
+
+/* 7 */
+"jobend",
+
+/* 8 */
+"control",
+
+NULL
+
+
+#line 177 "printqda.ctr"
+};
+
+
+
+/** Possible responses to LPRng jobstart requests.
+*/
+static char const * const pqda_decisions[] = {
+/* 0 */
+"ACCEPT",
+
+/* 1 */
+"REMOVE",
+
+/* 2 */
+"HOLD",
+
+NULL
+
+
+#line 189 "printqda.ctr"
+};
+
+
+
+/** Subrequests of control request.
+*/
+static char const * const pqda_control_sub_requests[] = {
+/* 0 */
+"r$eset",
+
+/* 1 */
+"a$dd",
+
+/* 2 */
+"d$atabase-cleanup",
+
+NULL
+
+
+#line 201 "printqda.ctr"
+};
+
+
+
+
+/** Initialize job structure.
+ @param job Job structure to initialize.
+*/
+static
+void
+pqda_job_init(pqda_job_t *job)
+{
+
+
+#line 214 "printqda.ctr"
+ dk3mem_res((void *)job, sizeof(pqda_job_t));
+ job->app = NULL;
+ job->lmsg = NULL;
+ job->cmsg = NULL;
+ job->exval = 3;
+
+#line 219 "printqda.ctr"
+ job->fadm = 0;
+
+#line 220 "printqda.ctr"
+ job->fcerr = 0;
+ job->up = NULL;
+ job->lo = NULL;
+
+
+#line 224 "printqda.ctr"
+}
+
+
+
+/** Clean up job structure before exiting program.
+ @param job Job structure to clean up.
+*/
+static
+void
+pqda_job_cleanup(pqda_job_t *job)
+{
+
+
+#line 236 "printqda.ctr"
+ if(job->app) {
+ dk3app_close(job->app); job->app = NULL;
+ }
+
+#line 239 "printqda.ctr"
+}
+
+
+
+/** Check whether the program is run as administration program printqda
+ or as multiplexor printqdc.
+ The result is stored in fadm.
+ @param job Job structure.
+ @param exename Name of the executable file running.
+*/
+static
+void
+pqda_check_admin(pqda_job_t *job, char const *exename)
+{
+ char bu[DK3_MAX_PATH]; /* Buffer for modification. */
+ char *p1; /* Start of program name. */
+ char *p2; /* File name suffix. */
+
+
+#line 257 "printqda.ctr"
+ if(exename) {
+ if(strlen(exename) < sizeof(bu)) {
+ strcpy(bu, exename);
+ p1 = dk3str_rchr(bu, '/');
+ if(p1) {
+ p1++;
+ } else {
+ p1 = bu;
+ }
+ p2 = dk3str_rchr(p1, '.');
+ if(p2) { *p2 = '\0'; }
+
+#line 268 "printqda.ctr"
+ if(0 == strcmp(p1, pqda_c8_kw[0])) {
+ job->fadm = 1;
+
+#line 270 "printqda.ctr"
+ }
+ }
+ }
+
+#line 273 "printqda.ctr"
+}
+
+
+
+/** Store an LPRng option.
+ @param job Job structure.
+ @param kc Key character.
+ @param v Value to store.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+pqda_lprng_set_option(pqda_job_t *job, char kc, char *v)
+{
+ int back = 0;
+
+
+#line 289 "printqda.ctr"
+ if(('a' <= kc) && ('z' >= kc)) {
+ if((job->lo)[kc - 'a']) {
+ if(job->fadm) {
+ /* WARNING: Option set twice! */
+ dk3app_log_3(job->app, DK3_LL_WARNING, job->lmsg, 1, 2, v);
+ }
+ }
+ (job->lo)[kc - 'a'] = v;
+ back = 1;
+ } else {
+ if(('A' <= kc) && ('Z' >= kc)) {
+ if((job->up)[kc - 'A']) {
+ if(job->fadm) {
+ /* WARNING: Option set twice! */
+ dk3app_log_3(job->app, DK3_LL_WARNING, job->lmsg, 1, 2, v);
+ }
+ }
+ (job->up)[kc - 'A'] = v;
+ back = 1;
+ }
+ }
+
+#line 310 "printqda.ctr"
+ return back;
+}
+
+
+
+/** Retrieve one LPRng option.
+ @param job Job structure.
+ @param kc Key character.
+ @return Pointer to option value if defined, NULL otherwise.
+*/
+static
+char *
+pqda_lprng_get_option(pqda_job_t *job, char kc)
+{
+ char *back = NULL;
+
+
+#line 326 "printqda.ctr"
+ if(('a' <= kc) && ('z' >= kc)) {
+ back = (job->lo)[kc - 'a'];
+ } else {
+ if(('A' <= kc) && ('Z' >= kc)) {
+ back = (job->up)[kc - 'A'];
+ }
+ }
+
+#line 333 "printqda.ctr"
+ return back;
+}
+
+
+
+
+/** Retrieve LPRng specific options.
+ @param job Job structure.
+ @param p2 String containing the options.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+pqda_lprng_options(pqda_job_t *job, char *p2)
+{
+ char *ptr; /* Current character to process. */
+ char *ps; /* Start of current string. */
+ int back = 1;
+ int i; /* Traverse all up and lo pointers. */
+ int st; /* Current reader state. */
+
+
+#line 354 "printqda.ctr"
+ for(i = 0; i < 26; i++) { (job->up)[i] = NULL; (job->lo)[i] = NULL; }
+ st = 0;
+ ptr = p2;
+ ps = NULL;
+ while(*ptr) {
+
+#line 359 "printqda.ctr"
+ switch(st) {
+ case 0: { /* in space before a string. */
+ if('\'' == *ptr) {
+ st = 1;
+ ps = ptr;
+ }
+ } break;
+ case 1: { /* in string. */
+ switch(*ptr) {
+ case '\'': {
+
+#line 369 "printqda.ctr"
+ *ptr = '\0';
+ st = 0;
+ if(ps) {
+
+#line 372 "printqda.ctr"
+ ps++;
+ if('-' == ps[0]) {
+ if('\0' != ps[1]) {
+ if(!pqda_lprng_set_option(job, ps[1], &(ps[2]))) {
+ back = 0;
+
+#line 377 "printqda.ctr"
+ if(job->fadm) {
+ /* ERROR: Not a character */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->lmsg, 3, 4, ps);
+ }
+ }
+ } else {
+
+#line 383 "printqda.ctr"
+ back = 0;
+ if(job->fadm) {
+ /* ERROR in string, empty option */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->lmsg, 5, 6, ps);
+ }
+ }
+ }
+ } else {
+
+#line 391 "printqda.ctr"
+ back = 0;
+ if(job->fadm) {
+ /* ERROR in input! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->lmsg, 7);
+ }
+ }
+ } break;
+ case '\\': {
+
+#line 399 "printqda.ctr"
+ st = 2;
+ } break;
+ }
+ } break;
+ case 2: { /* in string, backslash found. */
+ st = 1;
+ } break;
+ }
+ ptr++;
+ }
+ if(0 != st) {
+
+#line 410 "printqda.ctr"
+ back = 0;
+ if(job->fadm) {
+ /* ERROR: Incorrect input! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->lmsg, 8);
+ }
+ }
+
+#line 416 "printqda.ctr"
+ return back;
+}
+
+
+
+/** Convert a filestart/fileend request.
+ @param job Job structure.
+ @param rq First request word.
+ @param ib3 Input buffer 3 to use for response.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+pqda_file_startend(pqda_job_t *job, char const *rq, char *ib3)
+{
+ char *pn; /* Printer name. */
+ char *un; /* User name. */
+ char *pc; /* Pagecount value as text. */
+ char *jn; /* Print job name. */
+ char *jt; /* Print job title. */
+ size_t sz; /* Size of converted request. */
+ int back = 0;
+
+
+#line 439 "printqda.ctr"
+ un = NULL; pn = NULL; pc = NULL; jn = NULL; jt = NULL;
+ un = pqda_lprng_get_option(job, 'n');
+ pn = pqda_lprng_get_option(job, 'P');
+ pc = pqda_lprng_get_option(job, 'p');
+ jt = pqda_lprng_get_option(job, 'J');
+ jn = pqda_lprng_get_option(job, 'A');
+ if(!(jn)) { jn = pqda_lprng_get_option(job, 'D'); }
+ if(!(jn)) { jn = pn; }
+ if(!(jt)) { jt = jn; }
+ if((un) && (pn) && (pc) && (jt) && (jn)) {
+ sz = 5 * strlen(pqda_c8_kw[2]);
+ sz += strlen(rq);
+ sz += strlen(un);
+ sz += strlen(pn);
+ sz += strlen(pc);
+ sz += strlen(jt);
+ sz += strlen(jn);
+ if(PQD_INPUT_BUFFER_SIZE > sz) {
+ strcpy(ib3, rq);
+ strcat(ib3, pqda_c8_kw[2]);
+ strcat(ib3, pn);
+ strcat(ib3, pqda_c8_kw[2]);
+ strcat(ib3, un);
+ strcat(ib3, pqda_c8_kw[2]);
+ strcat(ib3, pc);
+ strcat(ib3, pqda_c8_kw[2]);
+ strcat(ib3, jn);
+ strcat(ib3, pqda_c8_kw[2]);
+ strcat(ib3, jt);
+ back = 1;
+ } else {
+ if(job->fadm) {
+ /* ERROR: Request contents too long! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->lmsg, 9);
+ }
+ }
+ } else {
+ if(job->fadm) {
+ /* ERROR: Incomplete jobstart/jobend request! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->lmsg, 10);
+ }
+ }
+
+#line 481 "printqda.ctr"
+ return back;
+}
+
+
+
+/** Prepare input for printqd.
+ @param job Job structure.
+ @param ib1 Original request, unmodified.
+ @param ib3 Input buffer for printqd, our destination.
+ @param p2 Arguments to original request, writable copy.
+ @param act Request type.
+*/
+static
+int
+pqda_daemon_input(
+ pqda_job_t *job,
+ char *ib1,
+ char *ib3,
+ char *p2,
+ int act
+)
+{
+ char *parts[16]; /* Splitted request string. */
+ char *un; /* User name. */
+ char *pn; /* Printer name. */
+ size_t na; /* Number of elements in nparts. */
+ size_t sz; /* String length of result string. */
+ int res; /* Operation result. */
+ int back = 0;
+
+
+#line 511 "printqda.ctr"
+ if((act < 8) || (job->fadm)) { /* control requests only printqda. */
+ un = NULL;
+ pn = NULL;
+ switch(act) {
+ case 0: { /* info */
+ na = dk3str_c8_explode(parts, 15, p2, NULL);
+ if(2 <= na) {
+ back = 1;
+ } else {
+ if(job->fadm) {
+ /* ERROR: Too few arguments in request! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->lmsg, 11);
+ }
+ }
+ } break;
+ case 1: { /* acct-check */
+ na = dk3str_c8_explode(parts, 15, p2, NULL);
+ if(2 <= na) {
+ back = 1;
+ } else {
+ if(job->fadm) {
+ /* ERROR: Too few arguments in request! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->lmsg, 11);
+ }
+ }
+ } break;
+ case 2: { /* acct-start */
+ na = dk3str_c8_explode(parts, 15, p2, NULL);
+ if(5 <= na) {
+ back = 1;
+ } else {
+ if(job->fadm) {
+ /* ERROR: Too few arguments in request! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->lmsg, 11);
+ }
+ }
+ } break;
+ case 3: { /* acct-end */
+ na = dk3str_c8_explode(parts, 15, p2, NULL);
+ if(5 <= na) {
+ back = 1;
+ } else {
+ if(job->fadm) {
+ /* ERROR: Too few arguments in request */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->lmsg, 11);
+ }
+ }
+ } break;
+ case 4: { /* jobstart */
+ if(pqda_lprng_options(job, p2)) {
+ un = pqda_lprng_get_option(job, 'n');
+ pn = pqda_lprng_get_option(job, 'P');
+ if((un) && (pn)) {
+ sz = strlen(pqda_c8_kw[3]);
+ sz += 2 * strlen(pqda_c8_kw[2]);
+ sz += strlen(un);
+ sz += strlen(pn);
+ if(sz < PQD_INPUT_BUFFER_SIZE) {
+ strcpy(ib3, pqda_c8_kw[3]);
+ strcat(ib3, pqda_c8_kw[2]);
+ strcat(ib3, pn);
+ strcat(ib3, pqda_c8_kw[2]);
+ strcat(ib3, un);
+ back = 1;
+ } else {
+ if(job->fadm) {
+ /* ERROR: Request data too long! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->lmsg, 9);
+ }
+ }
+ } else {
+ if(job->fadm) {
+ /* ERROR: Incomplete information in request! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->lmsg, 12);
+ }
+ }
+ }
+ } break;
+ case 5: { /* filestart */
+ if(pqda_lprng_options(job, p2)) {
+ back = pqda_file_startend(job, pqda_c8_kw[4], ib3);
+ }
+ } break;
+ case 6: { /* fileend */
+ if(pqda_lprng_options(job, p2)) {
+ back = pqda_file_startend(job, pqda_c8_kw[5], ib3);
+ }
+ } break;
+ case 7: { /* jobend */
+ /* Nothing to do, we ignore this request. */
+ } break;
+ case 8: { /* control */
+ na = dk3str_c8_explode(parts, 15, p2, NULL);
+ if(na > 0) {
+ res = dk3str_array_abbr(pqda_control_sub_requests, parts[0], '$', 0);
+ if(-1 < res) {
+ back = 1;
+ } else {
+ if(job->fadm) {
+ /* ERROR: Too few arguments in request! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->lmsg, 13, 14, parts[0]);
+ }
+ }
+ } else {
+ if(job->fadm) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->lmsg, 11);
+ }
+ }
+ } break;
+ }
+ } else {
+ if((8 == act) && (!(job->fadm))) {
+ job->exval = 1;
+
+#line 624 "printqda.ctr"
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->lmsg, 19);
+#if DK3_HAVE_SYSLOG
+ openlog(pqda_c8_kw[6], LOG_PID, LOG_LPR);
+ syslog(LOG_ERR, "Attempt to send control request to printqdc!");
+ closelog();
+#endif
+ }
+ }
+#if PRINTQDA_DEBUG
+ if(back) {
+ printf("%s\n%s\n", ib1, ib3);
+ } else {
+ if(7 != act) {
+ printf("!!! FAILED %s\n", ib1);
+ }
+ }
+#endif
+
+
+#line 642 "printqda.ctr"
+ return back;
+}
+
+
+
+/** Convert daemon response to this programs response.
+ @param job Job structure.
+ @param ib3 Destination buffer.
+ @param ib2 Daemon response.
+ @param act Request type.
+ @return 1 if we must write output to standard output,
+ 0 otherwise.
+*/
+static
+int
+pqda_daemon_output(pqda_job_t *job, char *ib3, char *ib2, int act)
+{
+ int back = 0;
+
+
+#line 661 "printqda.ctr"
+ ib3[0] = '\0';
+ switch(act) {
+ case 0: {
+
+#line 664 "printqda.ctr"
+ back = 1;
+ } break;
+ case 1: {
+
+#line 667 "printqda.ctr"
+ back = 1;
+ } break;
+ case 4: {
+
+#line 670 "printqda.ctr"
+ back = 1;
+ } break;
+ }
+ if(back) {
+ strcpy(ib3, ib2);
+ dk3str_c8_delnl(ib3);
+ if(!(strlen(ib3) > 0)) {
+ back = 0;
+ }
+ }
+
+
+#line 681 "printqda.ctr"
+ return back;
+}
+
+
+
+/** Process all input lines found on standard input.
+ @param job Job structure
+*/
+static
+void
+pqda_process_input(pqda_job_t *job)
+{
+ char ib1[PQD_INPUT_BUFFER_SIZE]; /* Original input. */
+ char ib2[PQD_INPUT_BUFFER_SIZE]; /* Copy for test. */
+ char ib3[PQD_INPUT_BUFFER_SIZE]; /* Daemon input. */
+ char *p1; /* Request keyword. */
+ char *p2; /* Request arguments. */
+ dk3_socket_t sock; /* Socket to daemon. */
+ size_t sz; /* Request size. */
+ int act; /* Action to take. */
+ int bw; /* Bytes written. */
+ int first; /* Flag: First resp. */
+ int res; /* Shutdown result. */
+
+
+#line 705 "printqda.ctr"
+ while(fgets(ib1, sizeof(ib1), stdin)) {
+ if(!(job->fcerr)) {
+ dk3str_c8_delnl(ib1);
+ strcpy(ib2, ib1);
+ p1 = dk3str_c8_start(ib2, NULL);
+ if(p1) {
+ if(*p1 != '#') {
+ p2 = dk3str_c8_next(p1, NULL);
+ act = dk3str_c8_array_index(pqda_request_types, p1, 0);
+ strcpy(ib3, ib1);
+ if(pqda_daemon_input(job, ib1, ib3, p2, act)) {
+ sz = strlen(ib3);
+ sock = dk3socket_un_stream_client(
+ (job->cfg).usn, 0L, 0L, NULL, job->app
+ );
+ if(INVALID_SOCKET != sock) {
+ bw = dk3socket_send(sock, ib3, sz, 0L, 0L, NULL, job->app);
+ if(bw >= 0) {
+ res = dk3socket_shutdown(
+ sock, DK3_TCPIP_SHUTDOWN_WRITE, NULL, job->app
+ );
+ if(res) {
+ first = 1;
+ ib2[0] = '\0';
+ do {
+ bw = dk3socket_recv(
+ sock, ib3, (sizeof(ib3) - 1), 0L, 0L, NULL, job->app
+ );
+ if(bw > 0) {
+ if(first) {
+ first = 0;
+ ib3[((size_t)bw < sizeof(ib3)) ? bw : (sizeof(ib3) - 1)]
+ = '\0';
+ strcpy(ib2, ib3);
+ }
+ }
+ } while(bw > 0);
+ if(!(first)) {
+ if(pqda_daemon_output(job, ib3, ib2, act)) {
+ fputs(ib3, stdout);
+ fputc('\n', stdout);
+ fflush(stdout);
+ if(!(job->fadm)) {
+
+#line 748 "printqda.ctr"
+ switch(dk3str_c8_array_index(pqda_decisions, ib3, 0)) {
+ case 1: {
+ job->exval = 3;
+
+#line 751 "printqda.ctr"
+ } break;
+ case 2: {
+ job->exval = 6;
+
+#line 754 "printqda.ctr"
+ } break;
+ }
+ } else {
+
+#line 757 "printqda.ctr"
+ }
+ }
+ }
+ }
+ }
+ dk3socket_close(sock, NULL, NULL);
+#if VERSION_BEFORE_20150821
+ sock = INVALID_SOCKET;
+#endif
+ } else {
+ job->fcerr = 1;
+ job->exval = 1;
+
+#line 769 "printqda.ctr"
+ /* FATAL: Connection failed, skipping all remaining input */
+ if(job->fadm) {
+ dk3app_log_1(job->app, DK3_LL_FATAL, job->lmsg, 15);
+ } else {
+#if DK3_HAVE_SYSLOG
+ openlog(pqda_c8_kw[6], LOG_PID, LOG_LPR);
+ syslog(LOG_ERR, "Failed to connect to printqd! Skipping all input!");
+ closelog();
+#endif
+ }
+ }
+ } else {
+
+#line 781 "printqda.ctr"
+ }
+ }
+ }
+ }
+ }
+
+
+#line 787 "printqda.ctr"
+}
+
+
+
+/** Process configuration file and run.
+ @param job Job structure.
+ @param cfgfilename Name of configuration file.
+*/
+static
+void
+pqda_run_with_config_filename(pqda_job_t *job, char const *cfgfilename)
+{
+ int res;
+
+
+#line 801 "printqda.ctr"
+ res = pqdconf_read(
+ &(job->cfg),
+ cfgfilename,
+ ((job->fadm) ? PQD_PROGRAM_TYPE_ADMIN : PQD_PROGRAM_TYPE_MULTIPLEXOR),
+ job->app, job->cmsg
+ );
+ if(res) {
+
+#line 808 "printqda.ctr"
+ res = pqdconf_check(
+ &(job->cfg),
+ ((job->fadm) ? PQD_PROGRAM_TYPE_ADMIN : PQD_PROGRAM_TYPE_MULTIPLEXOR),
+ job->app, job->cmsg
+ );
+ if(res) {
+
+#line 814 "printqda.ctr"
+
+
+#line 815 "printqda.ctr"
+ job->exval = 0;
+
+#line 816 "printqda.ctr"
+ pqda_process_input(job);
+ } else {
+
+#line 818 "printqda.ctr"
+ /* ERROR: Check failed! */
+ }
+ } else {
+
+#line 821 "printqda.ctr"
+ /* ERROR: Failed to read configuration! */
+ }
+ pqdconf_cleanup(&(job->cfg));
+
+
+#line 825 "printqda.ctr"
+}
+
+
+
+/** Find configuration file name and run with it.
+ @param job Job structure.
+*/
+static
+void
+pqda_search_for_config_filename(pqda_job_t *job)
+{
+ char bu[DK3_MAX_PATH]; /* Buffer to construct file name. */
+ char const *scd; /* System configuration directory. */
+
+
+#line 839 "printqda.ctr"
+ scd = dk3inst_get_directory(1);
+ if(scd) {
+ if(strlen(scd) < sizeof(bu)) {
+ strcpy(bu, scd);
+ if((strlen(bu) + strlen(pqda_conffile)) < sizeof(bu)) {
+ strcat(bu, pqda_conffile);
+ pqda_run_with_config_filename(job, bu);
+ } else {
+ /* ERROR: sysconfdir name too long! */
+ if(job->fadm) {
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->lmsg, 16, 17, scd);
+ } else {
+#if DK3_HAVE_SYSLOG
+ openlog(pqda_c8_kw[6], LOG_PID, LOG_LPR);
+ syslog(LOG_ERR, "File name of sysconfdir too long!");
+ closelog();
+#endif
+ }
+ }
+ } else {
+ /* ERROR: sysconfdir too long! */
+ if(job->fadm) {
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->lmsg, 16, 17, scd);
+ } else {
+#if DK3_HAVE_SYSLOG
+ openlog(pqda_c8_kw[6], LOG_PID, LOG_LPR);
+ syslog(LOG_ERR, "File name of sysconfdir too long!");
+ closelog();
+#endif
+ }
+ }
+ } else {
+ /* ERROR: Failed to obtain sysconfdir! */
+ if(job->fadm) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->lmsg, 18);
+ } else {
+#if DK3_HAVE_SYSLOG
+ openlog(pqda_c8_kw[6], LOG_PID, LOG_LPR);
+ syslog(LOG_ERR, "Failed to find sysconfdir!");
+ closelog();
+#endif
+ }
+ }
+
+#line 882 "printqda.ctr"
+}
+
+
+
+/** Run after allocating an application structure.
+ @param job Job structure.
+*/
+static
+void
+pqda_run_with_app(pqda_job_t *job)
+{
+ char const * const *xargv; /* Command line arguments array. */
+ int xargc; /* Number of command line arguments. */
+
+
+#line 896 "printqda.ctr"
+ job->lmsg = dk3app_messages(job->app, pqda_loc[0], pqda_loc);
+ job->cmsg = pqdconf_get_messages(job->app);
+ xargc = dk3app_get_argc(job->app);
+ xargv = dk3app_get_argv(job->app);
+ if((xargc > 1) && (job->fadm)) {
+ pqda_run_with_config_filename(job, xargv[1]);
+ } else {
+ pqda_search_for_config_filename(job);
+ }
+
+
+#line 906 "printqda.ctr"
+}
+
+
+
+/** For printqdc we use a silent application now instead of a
+ daemon application. Multiple instance of printqdc may run
+ at the same time, so we should not let them write all to
+ the same log file.
+*/
+#if VERSION_BEFORE_20120526
+/** When running as daemon (no output to stderr) we need the
+ current directory.
+ @param job Job structure.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+*/
+static
+void
+pqda_run_for_daemon(pqda_job_t *job, int argc, char *argv[])
+{
+ char bu[DK3_MAX_PATH]; /* Buffer for current working dir. */
+
+
+#line 928 "printqda.ctr"
+ if(dk3sf_c8_getcwd_app(bu, sizeof(bu), NULL)) {
+ job->app = dk3app_open_daemon(
+ bu, argc, (dkChar const * const *)argv, pqda_c8_kw[1]
+ );
+ if(job->app) {
+ pqda_run_with_app(job);
+ }
+ } else {
+ /* ERROR: Failed to find current directory! */
+ }
+
+#line 938 "printqda.ctr"
+}
+#endif
+
+
+
+/** Entry point of the program.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, any other value indicates an error.
+*/
+int
+main(int argc, char *argv[])
+{
+ pqda_job_t job; /* Job structure. */
+ char *up[26]; /* Upper case option arguments. */
+ char *lo[26]; /* Lower case option arguments. */
+ int exval; /* Exit status code. */
+
+
+#line 956 "printqda.ctr"
+
+
+#line 957 "printqda.ctr"
+ pqda_job_init(&job);
+ pqda_check_admin(&job, argv[0]);
+ job.up = up;
+ job.lo = lo;
+
+#if VERSION_BEFORE_20120526
+ if(job.fadm) {
+ job.app = dk3app_open_command(
+ argc, (dkChar const * const *)argv, pqda_c8_kw[1]
+ );
+ if(job.app) {
+ pqda_run_with_app(&job);
+ } else {
+ fputs("printqda: ERROR: Not enough memory (RAM/swap)!\n", stderr);
+ fflush(stderr);
+ }
+ } else {
+ pqda_run_for_daemon(&job, argc, argv);
+ }
+#endif
+ if(job.fadm) {
+ job.app = dk3app_open_command(
+ argc, (dkChar const * const *)argv, pqda_c8_kw[1]
+ );
+ } else {
+ job.app = dk3app_open_silent(
+ argc, (dkChar const * const *)argv, pqda_c8_kw[1]
+ );
+ }
+ if(job.app) {
+ pqda_run_with_app(&job);
+ } else {
+ if(job.fadm) {
+ fputs("printqda: ERROR: Not enough memory (RAM/swap)!\n", stderr);
+ fflush(stderr);
+ }
+ }
+ exval = job.exval;
+#if 0
+ /* NO, EXIT CODE MUST INDICATE ACTION TOO! */
+ if(!(job.fadm)) { exval = 0; }
+#endif
+ pqda_job_cleanup(&job);
+
+
+#line 1001 "printqda.ctr"
+
+
+#line 1002 "printqda.ctr"
+ fflush(stdout);
+ exit(exval); return exval;
+}
+
+
+
+#else
+/** Program entry point.
+ @param argc
+ @param argv
+ @return 0 on success, any other value indicates an error.
+*/
+int main(int argc, char *argv[])
+{
+ fprintf(stderr, "printqd: ERROR: No UNIX domain sockets available!\n");
+ fflush(stderr);
+ exit(1);
+}
+#endif
+#else
+/** Program entry point.
+ @param argc
+ @param argv
+ @return 0 on success, any other value indicates an error.
+*/
+int main(int argc, char *argv[])
+{
+ fprintf(
+ stderr,
+ "printqd: ERROR: This program does not support wide characters (%d)!\n",
+ DK3_CHAR_SIZE
+ );
+ fflush(stderr);
+ exit(1);
+}
+#endif
+
diff --git a/support/dktools/printqda.ctr b/support/dktools/printqda.ctr
new file mode 100644
index 0000000000..0e33a91351
--- /dev/null
+++ b/support/dktools/printqda.ctr
@@ -0,0 +1,1038 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2012-xxxx
+license = bsd
+
+
+
+%% header
+
+
+/** Printqda job structure.
+*/
+typedef struct {
+ pqd_conf_t cfg; /**< Configuration. */
+ dk3_app_t *app; /**< Application structure. */
+ char const * const *lmsg; /**< Localized message texts. */
+ char const * const *cmsg; /**< Localized messages for config. */
+ char **up; /**< Uppercase option arguments. */
+ char **lo; /**< Lowercase option arguments. */
+ int exval; /**< Exit status code. */
+ int fadm; /**< Flag: Running as printqda. */
+ int fcerr; /**< Flag: Connection error occured. */
+} pqda_job_t;
+
+
+
+%% module
+
+#include "printqd.h"
+#include "printqda.h"
+
+
+
+$!trace-include
+
+
+/** If this is defined to 1, each original request / daemon
+ request pair is reported to stdout.
+*/
+#define PRINTQDA_DEBUG 0
+
+#if DK3_CHAR_SIZE == 1
+#if DK3_HAVE_STRUCT_SOCKADDR_UN
+
+
+/** Configuration file name relative to sysconf directory.
+*/
+static char const pqda_conffile[] = { PQD_CONFFILE };
+
+
+/** Constant non-localized keywords used by the module.
+*/
+static char const * const pqda_c8_kw[] = {
+$!string-table
+#
+# 0 Program name when running as administrator.
+#
+printqda
+#
+# 1 Program group name.
+#
+dktools
+#
+# 2 Space to separate arguments in line
+#
+
+#
+# 3 Request keyword
+#
+acct-check
+#
+# 4 Request keyword
+#
+acct-start
+#
+# 5 Request keyword
+#
+acct-end
+#
+# 6 Program running as multiplexor
+#
+printqdc
+$!end
+};
+
+
+
+/** Localized message texts used by the program.
+*/
+static char const * const pqda_loc[] = {
+$!string-table
+#
+# 0 Name of localized message texts file.
+#
+printqda.str
+#
+# 1 2 Option was already set!
+#
+Option was already set: "
+"!
+#
+# 3 4 Option not started by a character!
+#
+Option not started by a character: "
+"!
+#
+# 5 6 Empty option!
+#
+Empty option: "
+"!
+#
+# 7 Syntax error in request!
+#
+Syntax error in request!
+#
+# 8 Syntax error, string not finalized!
+#
+Syntax error, string not finalized!
+#
+# 9 Request contents too long!
+#
+Request contents too long!
+#
+# 10 Incomplete request!
+#
+Incomplete request! Missing one from:\nuser name, printer name, page count, job name, or job title!
+#
+# 11 Too few arguments in request!
+#
+Too few arguments in request!
+#
+# 12 Incomplete request!
+#
+Incomplete request, missing either user or printer name!
+#
+# 13 14 Illegal control sub-request!
+#
+Illegal control sub-request: "
+"!
+#
+# 15
+#
+Connection failed, skipping all remaining input!
+#
+# 16 17
+#
+Name of system configuration directory too long:\n"
+"!
+#
+# 18
+#
+Failed to find system configuration directory!
+#
+# 19
+#
+Only printqda can process control requests, not printqdc!
+$!end
+};
+
+
+
+/** Request types (first word in request line).
+*/
+static char const * const pqda_request_types[] = {
+$!string-table
+info
+acct-check
+acct-start
+acct-end
+jobstart
+filestart
+fileend
+jobend
+control
+$!end
+};
+
+
+
+/** Possible responses to LPRng jobstart requests.
+*/
+static char const * const pqda_decisions[] = {
+$!string-table
+ACCEPT
+REMOVE
+HOLD
+$!end
+};
+
+
+
+/** Subrequests of control request.
+*/
+static char const * const pqda_control_sub_requests[] = {
+$!string-table
+r$eset
+a$dd
+d$atabase-cleanup
+$!end
+};
+
+
+
+
+/** Initialize job structure.
+ @param job Job structure to initialize.
+*/
+static
+void
+pqda_job_init(pqda_job_t *job)
+{
+ $? "+ pqda_job_init"
+ dk3mem_res((void *)job, sizeof(pqda_job_t));
+ job->app = NULL;
+ job->lmsg = NULL;
+ job->cmsg = NULL;
+ job->exval = 3; $? ". exval = 3"
+ job->fadm = 0; $? ". fadm = 0"
+ job->fcerr = 0;
+ job->up = NULL;
+ job->lo = NULL;
+ $? "- pqda_job_init"
+}
+
+
+
+/** Clean up job structure before exiting program.
+ @param job Job structure to clean up.
+*/
+static
+void
+pqda_job_cleanup(pqda_job_t *job)
+{
+ $? "+ pqda_job_cleanup"
+ if(job->app) {
+ dk3app_close(job->app); job->app = NULL;
+ } $? "- pqda_job_cleanup"
+}
+
+
+
+/** Check whether the program is run as administration program printqda
+ or as multiplexor printqdc.
+ The result is stored in fadm.
+ @param job Job structure.
+ @param exename Name of the executable file running.
+*/
+static
+void
+pqda_check_admin(pqda_job_t *job, char const *exename)
+{
+ char bu[DK3_MAX_PATH]; /* Buffer for modification. */
+ char *p1; /* Start of program name. */
+ char *p2; /* File name suffix. */
+ $? "+ pqda_check_admin"
+ if(exename) {
+ if(strlen(exename) < sizeof(bu)) {
+ strcpy(bu, exename);
+ p1 = dk3str_rchr(bu, '/');
+ if(p1) {
+ p1++;
+ } else {
+ p1 = bu;
+ }
+ p2 = dk3str_rchr(p1, '.');
+ if(p2) { *p2 = '\0'; } $? ". \"%!8s\"==\"%!8s\"", p1, pqda_c8_kw[0]
+ if(0 == strcmp(p1, pqda_c8_kw[0])) {
+ job->fadm = 1; $? ". fadm = 1"
+ }
+ }
+ } $? "- pqda_check_admin %d", job->fadm
+}
+
+
+
+/** Store an LPRng option.
+ @param job Job structure.
+ @param kc Key character.
+ @param v Value to store.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+pqda_lprng_set_option(pqda_job_t *job, char kc, char *v)
+{
+ int back = 0;
+ $? "+ pqda_lprng_set_option %!8c \"%!8s\"", kc, TR_8STR(v)
+ if(('a' <= kc) && ('z' >= kc)) {
+ if((job->lo)[kc - 'a']) {
+ if(job->fadm) {
+ /* WARNING: Option set twice! */
+ dk3app_log_3(job->app, DK3_LL_WARNING, job->lmsg, 1, 2, v);
+ }
+ }
+ (job->lo)[kc - 'a'] = v;
+ back = 1;
+ } else {
+ if(('A' <= kc) && ('Z' >= kc)) {
+ if((job->up)[kc - 'A']) {
+ if(job->fadm) {
+ /* WARNING: Option set twice! */
+ dk3app_log_3(job->app, DK3_LL_WARNING, job->lmsg, 1, 2, v);
+ }
+ }
+ (job->up)[kc - 'A'] = v;
+ back = 1;
+ }
+ } $? "- pqda_lprng_set_option %d", back
+ return back;
+}
+
+
+
+/** Retrieve one LPRng option.
+ @param job Job structure.
+ @param kc Key character.
+ @return Pointer to option value if defined, NULL otherwise.
+*/
+static
+char *
+pqda_lprng_get_option(pqda_job_t *job, char kc)
+{
+ char *back = NULL;
+ $? "+ pqda_lprng_get_option %!8c", kc
+ if(('a' <= kc) && ('z' >= kc)) {
+ back = (job->lo)[kc - 'a'];
+ } else {
+ if(('A' <= kc) && ('Z' >= kc)) {
+ back = (job->up)[kc - 'A'];
+ }
+ } $? "- pqda_lprng_get_option \"%!8s\"", TR_8STR(back)
+ return back;
+}
+
+
+
+
+/** Retrieve LPRng specific options.
+ @param job Job structure.
+ @param p2 String containing the options.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+pqda_lprng_options(pqda_job_t *job, char *p2)
+{
+ char *ptr; /* Current character to process. */
+ char *ps; /* Start of current string. */
+ int back = 1;
+ int i; /* Traverse all up and lo pointers. */
+ int st; /* Current reader state. */
+ $? "+ pqda_lprng_options \"%!8s\"", p2
+ for(i = 0; i < 26; i++) { (job->up)[i] = NULL; (job->lo)[i] = NULL; }
+ st = 0;
+ ptr = p2;
+ ps = NULL;
+ while(*ptr) { $? ". st = %d c = %!8c", st, *ptr
+ switch(st) {
+ case 0: { /* in space before a string. */
+ if('\'' == *ptr) {
+ st = 1;
+ ps = ptr;
+ }
+ } break;
+ case 1: { /* in string. */
+ switch(*ptr) {
+ case '\'': { $? ". string end"
+ *ptr = '\0';
+ st = 0;
+ if(ps) { $? ". ps"
+ ps++;
+ if('-' == ps[0]) {
+ if('\0' != ps[1]) {
+ if(!pqda_lprng_set_option(job, ps[1], &(ps[2]))) {
+ back = 0; $? "! failed to save"
+ if(job->fadm) {
+ /* ERROR: Not a character */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->lmsg, 3, 4, ps);
+ }
+ }
+ } else { $? "! error in string"
+ back = 0;
+ if(job->fadm) {
+ /* ERROR in string, empty option */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->lmsg, 5, 6, ps);
+ }
+ }
+ }
+ } else { $? "! ps"
+ back = 0;
+ if(job->fadm) {
+ /* ERROR in input! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->lmsg, 7);
+ }
+ }
+ } break;
+ case '\\': { $? ". backslash"
+ st = 2;
+ } break;
+ }
+ } break;
+ case 2: { /* in string, backslash found. */
+ st = 1;
+ } break;
+ }
+ ptr++;
+ }
+ if(0 != st) { $? "! wrong state"
+ back = 0;
+ if(job->fadm) {
+ /* ERROR: Incorrect input! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->lmsg, 8);
+ }
+ } $? "- pqda_lprng_options %d", back
+ return back;
+}
+
+
+
+/** Convert a filestart/fileend request.
+ @param job Job structure.
+ @param rq First request word.
+ @param ib3 Input buffer 3 to use for response.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+pqda_file_startend(pqda_job_t *job, char const *rq, char *ib3)
+{
+ char *pn; /* Printer name. */
+ char *un; /* User name. */
+ char *pc; /* Pagecount value as text. */
+ char *jn; /* Print job name. */
+ char *jt; /* Print job title. */
+ size_t sz; /* Size of converted request. */
+ int back = 0;
+ $? "+ pqda_file_startend"
+ un = NULL; pn = NULL; pc = NULL; jn = NULL; jt = NULL;
+ un = pqda_lprng_get_option(job, 'n');
+ pn = pqda_lprng_get_option(job, 'P');
+ pc = pqda_lprng_get_option(job, 'p');
+ jt = pqda_lprng_get_option(job, 'J');
+ jn = pqda_lprng_get_option(job, 'A');
+ if(!(jn)) { jn = pqda_lprng_get_option(job, 'D'); }
+ if(!(jn)) { jn = pn; }
+ if(!(jt)) { jt = jn; }
+ if((un) && (pn) && (pc) && (jt) && (jn)) {
+ sz = 5 * strlen(pqda_c8_kw[2]);
+ sz += strlen(rq);
+ sz += strlen(un);
+ sz += strlen(pn);
+ sz += strlen(pc);
+ sz += strlen(jt);
+ sz += strlen(jn);
+ if(PQD_INPUT_BUFFER_SIZE > sz) {
+ strcpy(ib3, rq);
+ strcat(ib3, pqda_c8_kw[2]);
+ strcat(ib3, pn);
+ strcat(ib3, pqda_c8_kw[2]);
+ strcat(ib3, un);
+ strcat(ib3, pqda_c8_kw[2]);
+ strcat(ib3, pc);
+ strcat(ib3, pqda_c8_kw[2]);
+ strcat(ib3, jn);
+ strcat(ib3, pqda_c8_kw[2]);
+ strcat(ib3, jt);
+ back = 1;
+ } else {
+ if(job->fadm) {
+ /* ERROR: Request contents too long! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->lmsg, 9);
+ }
+ }
+ } else {
+ if(job->fadm) {
+ /* ERROR: Incomplete jobstart/jobend request! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->lmsg, 10);
+ }
+ } $? "- pqda_file_startend %d", back
+ return back;
+}
+
+
+
+/** Prepare input for printqd.
+ @param job Job structure.
+ @param ib1 Original request, unmodified.
+ @param ib3 Input buffer for printqd, our destination.
+ @param p2 Arguments to original request, writable copy.
+ @param act Request type.
+*/
+static
+int
+pqda_daemon_input(
+ pqda_job_t *job,
+ char *ib1,
+ char *ib3,
+ char *p2,
+ int act
+)
+{
+ char *parts[16]; /* Splitted request string. */
+ char *un; /* User name. */
+ char *pn; /* Printer name. */
+ size_t na; /* Number of elements in nparts. */
+ size_t sz; /* String length of result string. */
+ int res; /* Operation result. */
+ int back = 0;
+ $? "+ pqda_daemon_input \"%!8s\"", p2
+ if((act < 8) || (job->fadm)) { /* control requests only printqda. */
+ un = NULL;
+ pn = NULL;
+ switch(act) {
+ case 0: { /* info */
+ na = dk3str_c8_explode(parts, 15, p2, NULL);
+ if(2 <= na) {
+ back = 1;
+ } else {
+ if(job->fadm) {
+ /* ERROR: Too few arguments in request! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->lmsg, 11);
+ }
+ }
+ } break;
+ case 1: { /* acct-check */
+ na = dk3str_c8_explode(parts, 15, p2, NULL);
+ if(2 <= na) {
+ back = 1;
+ } else {
+ if(job->fadm) {
+ /* ERROR: Too few arguments in request! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->lmsg, 11);
+ }
+ }
+ } break;
+ case 2: { /* acct-start */
+ na = dk3str_c8_explode(parts, 15, p2, NULL);
+ if(5 <= na) {
+ back = 1;
+ } else {
+ if(job->fadm) {
+ /* ERROR: Too few arguments in request! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->lmsg, 11);
+ }
+ }
+ } break;
+ case 3: { /* acct-end */
+ na = dk3str_c8_explode(parts, 15, p2, NULL);
+ if(5 <= na) {
+ back = 1;
+ } else {
+ if(job->fadm) {
+ /* ERROR: Too few arguments in request */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->lmsg, 11);
+ }
+ }
+ } break;
+ case 4: { /* jobstart */
+ if(pqda_lprng_options(job, p2)) {
+ un = pqda_lprng_get_option(job, 'n');
+ pn = pqda_lprng_get_option(job, 'P');
+ if((un) && (pn)) {
+ sz = strlen(pqda_c8_kw[3]);
+ sz += 2 * strlen(pqda_c8_kw[2]);
+ sz += strlen(un);
+ sz += strlen(pn);
+ if(sz < PQD_INPUT_BUFFER_SIZE) {
+ strcpy(ib3, pqda_c8_kw[3]);
+ strcat(ib3, pqda_c8_kw[2]);
+ strcat(ib3, pn);
+ strcat(ib3, pqda_c8_kw[2]);
+ strcat(ib3, un);
+ back = 1;
+ } else {
+ if(job->fadm) {
+ /* ERROR: Request data too long! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->lmsg, 9);
+ }
+ }
+ } else {
+ if(job->fadm) {
+ /* ERROR: Incomplete information in request! */
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->lmsg, 12);
+ }
+ }
+ }
+ } break;
+ case 5: { /* filestart */
+ if(pqda_lprng_options(job, p2)) {
+ back = pqda_file_startend(job, pqda_c8_kw[4], ib3);
+ }
+ } break;
+ case 6: { /* fileend */
+ if(pqda_lprng_options(job, p2)) {
+ back = pqda_file_startend(job, pqda_c8_kw[5], ib3);
+ }
+ } break;
+ case 7: { /* jobend */
+ /* Nothing to do, we ignore this request. */
+ } break;
+ case 8: { /* control */
+ na = dk3str_c8_explode(parts, 15, p2, NULL);
+ if(na > 0) {
+ res = dk3str_array_abbr(pqda_control_sub_requests, parts[0], '$', 0);
+ if(-1 < res) {
+ back = 1;
+ } else {
+ if(job->fadm) {
+ /* ERROR: Too few arguments in request! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->lmsg, 13, 14, parts[0]);
+ }
+ }
+ } else {
+ if(job->fadm) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->lmsg, 11);
+ }
+ }
+ } break;
+ }
+ } else {
+ if((8 == act) && (!(job->fadm))) {
+ job->exval = 1; $? ". exval = 1"
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->lmsg, 19);
+#if DK3_HAVE_SYSLOG
+ openlog(pqda_c8_kw[6], LOG_PID, LOG_LPR);
+ syslog(LOG_ERR, "Attempt to send control request to printqdc!");
+ closelog();
+#endif
+ }
+ }
+#if PRINTQDA_DEBUG
+ if(back) {
+ printf("%s\n%s\n", ib1, ib3);
+ } else {
+ if(7 != act) {
+ printf("!!! FAILED %s\n", ib1);
+ }
+ }
+#endif
+ $? "- pqda_daemon_input %d ib3 = \"%!8s\"", back, ib3
+ return back;
+}
+
+
+
+/** Convert daemon response to this programs response.
+ @param job Job structure.
+ @param ib3 Destination buffer.
+ @param ib2 Daemon response.
+ @param act Request type.
+ @return 1 if we must write output to standard output,
+ 0 otherwise.
+*/
+static
+int
+pqda_daemon_output(pqda_job_t *job, char *ib3, char *ib2, int act)
+{
+ int back = 0;
+ $? "+ pqda_daemon_output"
+ ib3[0] = '\0';
+ switch(act) {
+ case 0: { $? ". info"
+ back = 1;
+ } break;
+ case 1: { $? ". acct-check"
+ back = 1;
+ } break;
+ case 4: { $? ". jobstart"
+ back = 1;
+ } break;
+ }
+ if(back) {
+ strcpy(ib3, ib2);
+ dk3str_c8_delnl(ib3);
+ if(!(strlen(ib3) > 0)) {
+ back = 0;
+ }
+ }
+ $? "- pqda_daemon_output %d", back
+ return back;
+}
+
+
+
+/** Process all input lines found on standard input.
+ @param job Job structure
+*/
+static
+void
+pqda_process_input(pqda_job_t *job)
+{
+ char ib1[PQD_INPUT_BUFFER_SIZE]; /* Original input. */
+ char ib2[PQD_INPUT_BUFFER_SIZE]; /* Copy for test. */
+ char ib3[PQD_INPUT_BUFFER_SIZE]; /* Daemon input. */
+ char *p1; /* Request keyword. */
+ char *p2; /* Request arguments. */
+ dk3_socket_t sock; /* Socket to daemon. */
+ size_t sz; /* Request size. */
+ int act; /* Action to take. */
+ int bw; /* Bytes written. */
+ int first; /* Flag: First resp. */
+ int res; /* Shutdown result. */
+ $? "+ pqda_process_input"
+ while(fgets(ib1, sizeof(ib1), stdin)) {
+ if(!(job->fcerr)) {
+ dk3str_c8_delnl(ib1);
+ strcpy(ib2, ib1);
+ p1 = dk3str_c8_start(ib2, NULL);
+ if(p1) {
+ if(*p1 != '#') {
+ p2 = dk3str_c8_next(p1, NULL);
+ act = dk3str_c8_array_index(pqda_request_types, p1, 0);
+ strcpy(ib3, ib1);
+ if(pqda_daemon_input(job, ib1, ib3, p2, act)) {
+ sz = strlen(ib3);
+ sock = dk3socket_un_stream_client(
+ (job->cfg).usn, 0L, 0L, NULL, job->app
+ );
+ if(INVALID_SOCKET != sock) {
+ bw = dk3socket_send(sock, ib3, sz, 0L, 0L, NULL, job->app);
+ if(bw >= 0) {
+ res = dk3socket_shutdown(
+ sock, DK3_TCPIP_SHUTDOWN_WRITE, NULL, job->app
+ );
+ if(res) {
+ first = 1;
+ ib2[0] = '\0';
+ do {
+ bw = dk3socket_recv(
+ sock, ib3, (sizeof(ib3) - 1), 0L, 0L, NULL, job->app
+ );
+ if(bw > 0) {
+ if(first) {
+ first = 0;
+ ib3[((size_t)bw < sizeof(ib3)) ? bw : (sizeof(ib3) - 1)]
+ = '\0';
+ strcpy(ib2, ib3);
+ }
+ }
+ } while(bw > 0);
+ if(!(first)) {
+ if(pqda_daemon_output(job, ib3, ib2, act)) {
+ fputs(ib3, stdout);
+ fputc('\n', stdout);
+ fflush(stdout);
+ if(!(job->fadm)) { $? ". check \"%!8s\"", ib3
+ switch(dk3str_c8_array_index(pqda_decisions, ib3, 0)) {
+ case 1: {
+ job->exval = 3; $? ". exval = 3"
+ } break;
+ case 2: {
+ job->exval = 6; $? ". exval = 3"
+ } break;
+ }
+ } else { $? ". feel as printqda"
+ }
+ }
+ }
+ }
+ }
+ dk3socket_close(sock, NULL, NULL);
+#if VERSION_BEFORE_20150821
+ sock = INVALID_SOCKET;
+#endif
+ } else {
+ job->fcerr = 1;
+ job->exval = 1; $? ". exval = 1"
+ /* FATAL: Connection failed, skipping all remaining input */
+ if(job->fadm) {
+ dk3app_log_1(job->app, DK3_LL_FATAL, job->lmsg, 15);
+ } else {
+#if DK3_HAVE_SYSLOG
+ openlog(pqda_c8_kw[6], LOG_PID, LOG_LPR);
+ syslog(LOG_ERR, "Failed to connect to printqd! Skipping all input!");
+ closelog();
+#endif
+ }
+ }
+ } else { $? "! pqda_daemon_input \"%!8s\"", ib1
+ }
+ }
+ }
+ }
+ }
+ $? "- pqda_process_input"
+}
+
+
+
+/** Process configuration file and run.
+ @param job Job structure.
+ @param cfgfilename Name of configuration file.
+*/
+static
+void
+pqda_run_with_config_filename(pqda_job_t *job, char const *cfgfilename)
+{
+ int res;
+ $? "+ pqda_run_with_config_filename \"%!8s\"", TR_8STR(cfgfilename)
+ res = pqdconf_read(
+ &(job->cfg),
+ cfgfilename,
+ ((job->fadm) ? PQD_PROGRAM_TYPE_ADMIN : PQD_PROGRAM_TYPE_MULTIPLEXOR),
+ job->app, job->cmsg
+ );
+ if(res) { $? ". config read ok"
+ res = pqdconf_check(
+ &(job->cfg),
+ ((job->fadm) ? PQD_PROGRAM_TYPE_ADMIN : PQD_PROGRAM_TYPE_MULTIPLEXOR),
+ job->app, job->cmsg
+ );
+ if(res) { $? ". config check ok"
+ $? ". configuration was read successfully"
+ job->exval = 0; $? ". exval = 0"
+ pqda_process_input(job);
+ } else { $? "! config check"
+ /* ERROR: Check failed! */
+ }
+ } else { $? "! config read"
+ /* ERROR: Failed to read configuration! */
+ }
+ pqdconf_cleanup(&(job->cfg));
+ $? "- pqda_run_with_config_filename"
+}
+
+
+
+/** Find configuration file name and run with it.
+ @param job Job structure.
+*/
+static
+void
+pqda_search_for_config_filename(pqda_job_t *job)
+{
+ char bu[DK3_MAX_PATH]; /* Buffer to construct file name. */
+ char const *scd; /* System configuration directory. */
+ $? "+ pqda_search_for_config_filename"
+ scd = dk3inst_get_directory(1);
+ if(scd) {
+ if(strlen(scd) < sizeof(bu)) {
+ strcpy(bu, scd);
+ if((strlen(bu) + strlen(pqda_conffile)) < sizeof(bu)) {
+ strcat(bu, pqda_conffile);
+ pqda_run_with_config_filename(job, bu);
+ } else {
+ /* ERROR: sysconfdir name too long! */
+ if(job->fadm) {
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->lmsg, 16, 17, scd);
+ } else {
+#if DK3_HAVE_SYSLOG
+ openlog(pqda_c8_kw[6], LOG_PID, LOG_LPR);
+ syslog(LOG_ERR, "File name of sysconfdir too long!");
+ closelog();
+#endif
+ }
+ }
+ } else {
+ /* ERROR: sysconfdir too long! */
+ if(job->fadm) {
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->lmsg, 16, 17, scd);
+ } else {
+#if DK3_HAVE_SYSLOG
+ openlog(pqda_c8_kw[6], LOG_PID, LOG_LPR);
+ syslog(LOG_ERR, "File name of sysconfdir too long!");
+ closelog();
+#endif
+ }
+ }
+ } else {
+ /* ERROR: Failed to obtain sysconfdir! */
+ if(job->fadm) {
+ dk3app_log_1(job->app, DK3_LL_ERROR, job->lmsg, 18);
+ } else {
+#if DK3_HAVE_SYSLOG
+ openlog(pqda_c8_kw[6], LOG_PID, LOG_LPR);
+ syslog(LOG_ERR, "Failed to find sysconfdir!");
+ closelog();
+#endif
+ }
+ } $? "- pqda_search_for_config_filename"
+}
+
+
+
+/** Run after allocating an application structure.
+ @param job Job structure.
+*/
+static
+void
+pqda_run_with_app(pqda_job_t *job)
+{
+ char const * const *xargv; /* Command line arguments array. */
+ int xargc; /* Number of command line arguments. */
+ $? "+ pqda_run_with_app"
+ job->lmsg = dk3app_messages(job->app, pqda_loc[0], pqda_loc);
+ job->cmsg = pqdconf_get_messages(job->app);
+ xargc = dk3app_get_argc(job->app);
+ xargv = dk3app_get_argv(job->app);
+ if((xargc > 1) && (job->fadm)) {
+ pqda_run_with_config_filename(job, xargv[1]);
+ } else {
+ pqda_search_for_config_filename(job);
+ }
+ $? "- pqda_run_with_app"
+}
+
+
+
+/** For printqdc we use a silent application now instead of a
+ daemon application. Multiple instance of printqdc may run
+ at the same time, so we should not let them write all to
+ the same log file.
+*/
+#if VERSION_BEFORE_20120526
+/** When running as daemon (no output to stderr) we need the
+ current directory.
+ @param job Job structure.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+*/
+static
+void
+pqda_run_for_daemon(pqda_job_t *job, int argc, char *argv[])
+{
+ char bu[DK3_MAX_PATH]; /* Buffer for current working dir. */
+ $? "+ pqda_run_for_daemon"
+ if(dk3sf_c8_getcwd_app(bu, sizeof(bu), NULL)) {
+ job->app = dk3app_open_daemon(
+ bu, argc, (dkChar const * const *)argv, pqda_c8_kw[1]
+ );
+ if(job->app) {
+ pqda_run_with_app(job);
+ }
+ } else {
+ /* ERROR: Failed to find current directory! */
+ } $? "- pqda_run_for_daemon"
+}
+#endif
+
+
+
+/** Entry point of the program.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, any other value indicates an error.
+*/
+int
+main(int argc, char *argv[])
+{
+ pqda_job_t job; /* Job structure. */
+ char *up[26]; /* Upper case option arguments. */
+ char *lo[26]; /* Lower case option arguments. */
+ int exval; /* Exit status code. */
+ $!trace-init /tmp/printqda.deb
+ $? "+ main"
+ pqda_job_init(&job);
+ pqda_check_admin(&job, argv[0]);
+ job.up = up;
+ job.lo = lo;
+
+#if VERSION_BEFORE_20120526
+ if(job.fadm) {
+ job.app = dk3app_open_command(
+ argc, (dkChar const * const *)argv, pqda_c8_kw[1]
+ );
+ if(job.app) {
+ pqda_run_with_app(&job);
+ } else {
+ fputs("printqda: ERROR: Not enough memory (RAM/swap)!\n", stderr);
+ fflush(stderr);
+ }
+ } else {
+ pqda_run_for_daemon(&job, argc, argv);
+ }
+#endif
+ if(job.fadm) {
+ job.app = dk3app_open_command(
+ argc, (dkChar const * const *)argv, pqda_c8_kw[1]
+ );
+ } else {
+ job.app = dk3app_open_silent(
+ argc, (dkChar const * const *)argv, pqda_c8_kw[1]
+ );
+ }
+ if(job.app) {
+ pqda_run_with_app(&job);
+ } else {
+ if(job.fadm) {
+ fputs("printqda: ERROR: Not enough memory (RAM/swap)!\n", stderr);
+ fflush(stderr);
+ }
+ }
+ exval = job.exval;
+#if 0
+ /* NO, EXIT CODE MUST INDICATE ACTION TOO! */
+ if(!(job.fadm)) { exval = 0; }
+#endif
+ pqda_job_cleanup(&job);
+ $? "- main %d", exval
+ $!trace-end
+ fflush(stdout);
+ exit(exval); return exval;
+}
+
+
+
+#else
+/** Program entry point.
+ @param argc
+ @param argv
+ @return 0 on success, any other value indicates an error.
+*/
+int main(int argc, char *argv[])
+{
+ fprintf(stderr, "printqd: ERROR: No UNIX domain sockets available!\n");
+ fflush(stderr);
+ exit(1);
+}
+#endif
+#else
+/** Program entry point.
+ @param argc
+ @param argv
+ @return 0 on success, any other value indicates an error.
+*/
+int main(int argc, char *argv[])
+{
+ fprintf(
+ stderr,
+ "printqd: ERROR: This program does not support wide characters (%d)!\n",
+ DK3_CHAR_SIZE
+ );
+ fflush(stderr);
+ exit(1);
+}
+#endif
+
diff --git a/support/dktools/printqda.h b/support/dktools/printqda.h
new file mode 100644
index 0000000000..f6d91cf74d
--- /dev/null
+++ b/support/dktools/printqda.h
@@ -0,0 +1,64 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: printqda.ctr
+*/
+
+/*
+Copyright (C) 2012-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file printqda.h Header file for the printqda module.
+*/
+
+#ifndef PRINTQDA_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define PRINTQDA_H_INCLUDED 1
+
+
+#line 10 "printqda.ctr"
+
+
+/** Printqda job structure.
+*/
+typedef struct {
+ pqd_conf_t cfg; /**< Configuration. */
+ dk3_app_t *app; /**< Application structure. */
+ char const * const *lmsg; /**< Localized message texts. */
+ char const * const *cmsg; /**< Localized messages for config. */
+ char **up; /**< Uppercase option arguments. */
+ char **lo; /**< Lowercase option arguments. */
+ int exval; /**< Exit status code. */
+ int fadm; /**< Flag: Running as printqda. */
+ int fcerr; /**< Flag: Connection error occured. */
+} pqda_job_t;
+
+
+
+
+#endif
diff --git a/support/dktools/printqdc.c b/support/dktools/printqdc.c
new file mode 100644
index 0000000000..3be104d3a3
--- /dev/null
+++ b/support/dktools/printqdc.c
@@ -0,0 +1,1563 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: printqdc.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file printqdc.c The printqdc module.
+*/
+
+
+#line 10 "printqdc.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+
+
+/** Requirements to build this program:
+ * Use 8 bit characters, so we can use the directories from dk4inst.c.
+ * Signal handling mechanism.
+*/
+#if (DK4_CHAR_SIZE == 1) && ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET))
+
+
+
+#if DK4_HAVE_MATH_H
+#ifndef MATH_H_INCLUDED
+#include <math.h>
+#define MATH_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4inst.h"
+#include "dk4mpl.h"
+#include "dk4mem.h"
+#include "dk4mai8ddu.h"
+#include "dk4mai8dus.h"
+#include "dk4str8.h"
+#include "dk4lprng.h"
+#include "dk4opt.h"
+#include "dk4sock.h"
+#include "dk4vers.h"
+
+
+
+
+
+#line 103 "printqdc.ctr"
+
+
+
+/** Information from one LPRng accounting line.
+*/
+typedef struct {
+ char *username;
+ char *queuename;
+ char *jobtitle;
+ char *pagecount;
+} lprng_info_t;
+
+
+
+
+/** Command line options for program.
+*/
+static dk4_option_t options[] = {
+ { { dkT('i'), dkT("interactive"), DK4_OPT_ARG_NONE }, { NULL }, 0},
+ { { dkT('s'), dkT("socket"), DK4_OPT_ARG_STRING }, { NULL }, 0},
+ { { dkT('h'), dkT("host"), DK4_OPT_ARG_STRING }, { NULL }, 0},
+ { { dkT('p'), dkT("port"), DK4_OPT_ARG_UNSIGNED }, { NULL }, 0},
+ { { dkT('\0'),dkT("help"), DK4_OPT_ARG_NONE}, { NULL }, 0},
+ { { dkT('\0'),dkT("version"), DK4_OPT_ARG_NONE}, { NULL }, 0},
+ { { dkT('\0'),dkT("license"), DK4_OPT_ARG_NONE}, { NULL }, 0}
+};
+
+
+
+/** Help text.
+*/
+static const char * const help_text[] = {
+"",
+"Print quota daemon client",
+"",
+"printqdc [-i] [-s path] | [-h host -p port]",
+"",
+"-i\t\t\tInteractive mode instead of default pipe mode.",
+"--interactive",
+"",
+"-s path\t\t\tPath name for local UNIX domain socket.",
+"--socket=path",
+"",
+"-h host\t\t\tHost name of remote host.",
+"--host=host",
+"",
+"-p port\t\t\tPort number at remote host.",
+"--port=port",
+"",
+"--help\t\t\tShow this help text.",
+"--version\t\tShow version number.",
+"--license\t\tShow license information.",
+"",
+NULL
+
+
+#line 158 "printqdc.ctr"
+};
+
+
+
+/** License conditions text.
+*/
+static const char * const license_text[] = {
+"",
+"This software uses code from the following projects, either directly or as",
+"a library:",
+"",
+"dktools\t\tDirk Krause's tools and libraries.",
+"\t\tSee http://dktools.sourceforge.net/ for more information.",
+"",
+"DK tools and libraries license",
+"==============================",
+"Copyright (c) 2015-2016, Dirk Krause",
+"All rights reserved.",
+"",
+"Redistribution and use in source and binary forms, with or without",
+"modification, are permitted provided that the following conditions are met:",
+"",
+"* Redistributions of source code must retain the above copyright notice,",
+" this list of conditions and the following disclaimer.",
+"* Redistributions in binary form must reproduce the above copyright",
+" notice, this list of conditions and the following disclaimer in the",
+" documentation and/or other materials provided with the distribution.",
+"* Neither the name of the Dirk Krause nor the names of contributors may be",
+" used to endorse or promote products derived from this software without",
+" specific prior written permission.",
+"",
+"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"",
+"AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE",
+"IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE",
+"ARE DISCLAIMED.",
+"",
+"IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,",
+"INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,",
+"BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,",
+"DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY",
+"OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING",
+"NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,",
+"EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.",
+"",
+NULL
+
+
+#line 204 "printqdc.ctr"
+};
+
+
+
+/** Version information.
+*/
+static const char version_text[] = { DKT_VERSION_C8 };
+
+
+
+/** Constant text keywords used by the module.
+*/
+static const char * const pqdc_kw[] = {
+/* 0 */
+"\n",
+
+/* 1 */
+" ",
+
+/* 2 */
+"x@x+1",
+
+/* 3 */
+"Print job",
+
+/* 4 */
+"-> ",
+
+/* 5 */
+"<- \"",
+
+/* 6 */
+"\"\n",
+
+/* 7 */
+"printqdc: ",
+
+/* 8 */
+"ERROR: Port number too large!\n",
+
+/* 9 */
+"ERROR: Port number required!\n",
+
+/* 10 */
+"ERROR: Host name required!\n",
+
+/* 11 */
+"ERROR: Failed to shut down socket!\n",
+
+/* 12 */
+"ERROR: Failed to send data!\n",
+
+/* 13 */
+"ERROR: Failed to open connection to accounting system!\n",
+
+/* 14 */
+"ERROR: Failed to construct request (would be too long)!\n",
+
+/* 15 */
+"ERROR: Incomplete information to construct request!\n",
+
+/* 16 */
+"ERROR: Pagecounter not numeric!\n",
+
+/* 17 */
+"ERROR: Too few arguments for request!\n",
+
+/* 18 */
+"ERROR: Unknown command keyword!\n",
+
+/* 19 */
+"ERROR: Missing arguments!\n",
+
+/* 20 */
+"ERROR: Interrupted by signal!\n",
+
+/* 21 */
+"ERROR: Failed to install signal handlers!\n",
+
+/* 22 */
+"ERROR: Failed to restore signal handlers!\n",
+
+/* 23 */
+"ERROR: Failed to initialize socket subsystem!\n",
+
+NULL
+
+
+#line 276 "printqdc.ctr"
+};
+
+
+
+/** Default socket name.
+*/
+static const char def_sock_name[] = {
+ DK4_INST_DIR_VAR "/run/printqd/printqd.sock"
+};
+
+
+
+/** Protocol keywords at start of accounting line.
+*/
+static const char * const command_names[] = {
+/* 0 */
+"jobstart",
+
+/* 1 */
+"jobend",
+
+/* 2 */
+"start",
+
+/* 3 */
+"end",
+
+/* 4 */
+"filestart",
+
+/* 5 */
+"fileend",
+
+/* 6 */
+"info",
+
+/* 7 */
+"acct-check",
+
+/* 8 */
+"acct-start",
+
+/* 9 */
+"acct-end",
+
+/* 10 */
+"acct-charge",
+
+/* 11 */
+"control",
+
+NULL
+
+
+#line 311 "printqdc.ctr"
+};
+
+
+/** Responses from printqd
+*/
+static const char * const responses[] = {
+/* 0 */
+"ACCEPT",
+
+/* 1 */
+"HOLD",
+
+/* 2 */
+"REMOVE",
+
+NULL
+
+
+#line 322 "printqdc.ctr"
+};
+
+/** Data exchange buffer.
+*/
+static char inbuf[4096];
+
+
+/** Copy for inspection.
+*/
+static char cpbuf[sizeof(inbuf)];
+
+
+/** Host name for network connection.
+*/
+static char *host_name = NULL;
+
+
+/** Socket file name for local connection.
+*/
+static char *sock_name = NULL;
+
+
+/** Number of options.
+*/
+static size_t szoptions = sizeof(options)/sizeof(dk4_option_t);
+
+
+/** Normal exit value (when run as pipe).
+*/
+static int exval = LPRNG_EXIT_SUCCESS;
+
+
+
+/** Help (1), version (2), license (4).
+*/
+static int hvl = 0;
+
+
+
+/** Exit value for interactive mode.
+*/
+static int iexval = EXIT_FAILURE;
+
+
+/** Flag: Interactive mode (-i option).
+*/
+static int intera = 0;
+
+
+/** Flag: EOF was found.
+*/
+static int eof_found = 0;
+
+
+/** Flag: Response already found and processed.
+*/
+static int found_response = 0;
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+/** Port number for network connection.
+*/
+static unsigned short portno = 0U;
+
+
+/** Pass pointer through.
+ Use of this function is recommended by CERT C coding standard
+ to avoid optimizing out.
+ @param ptr Pointer to pass through.
+ @return The ptr argument.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+
+/** Check whether we can continue or must abort due to signal.
+ @param dopipe Flag: Check for SIGPIPE too.
+ @return 1 if we can continue, 0 otherwise.
+*/
+static
+int
+can_continue(void)
+{
+ int back = 1;
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_int)) { back = 0; }
+ return back;
+}
+
+
+
+/** Log one-component message to stderr.
+ @param kwind Index of text in printqdc_kw array.
+*/
+static
+void
+log_1(size_t kwind)
+{
+ if (0 != intera) {
+ fputs(pqdc_kw[7], stderr);
+ fputs(pqdc_kw[kwind], stderr);
+ fflush(stderr);
+ }
+}
+
+
+/** Eat up input to avoid broken pipe in feeder.
+*/
+static
+void
+eatup_input(void)
+{
+ size_t rdb;
+ int cc = 1;
+ do {
+ if (0 != can_continue()) {
+ rdb = fread(inbuf, 1, sizeof(inbuf), stdin);
+ if (0 == rdb) {
+ cc = 0;
+ }
+ } else {
+ cc = -1;
+ }
+ } while(1 == cc);
+}
+
+
+
+/** Process command line arguments.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+cmd_line_args(int argc, char *argv[])
+{
+ dkChar *filenames[32];
+ size_t szfilenames = DK4_SIZEOF(filenames,DK4_PDKCHAR);
+ int back;
+ back = dk4opt_process_argv(
+ options, szoptions, argc, argv, filenames, &szfilenames,
+ 1, 0, NULL
+ );
+ if (1 == back) {
+ if (0 != options[4].found) {
+ hvl |= 1;
+ }
+ if (0 != options[5].found) {
+ hvl |= 2;
+ }
+ if (0 != options[6].found) {
+ hvl |= 4;
+ }
+ if (0 != options[0].found) {
+ intera = 1;
+ }
+ if (0 != options[1].found) {
+ sock_name = options[1].val.t;
+ }
+ if (0 != options[2].found) {
+ host_name = options[2].val.t;
+ }
+ if (0 != options[3].found) {
+ if ((dk4_um_t)0x0000FFFFUL >= options[3].val.u) {
+ portno = (unsigned short)(options[3].val.u);
+ } else {
+ back = 0;
+ /* ERROR: Port number to large! */
+ log_1(8);
+ }
+ }
+ if ((NULL != host_name) && (0 == portno)) {
+ back = 0;
+ /* ERROR: Port number required */
+ log_1(9);
+ }
+ if ((NULL == host_name) && (0 != portno)) {
+ back = 0;
+ /* ERROR: Host name required */
+ log_1(10);
+ }
+ } else {
+ if (0 != options[0].found) {
+ (void)dk4opt_process_argv(
+ options, szoptions, argc, argv, filenames, &szfilenames,
+ 1, 1, NULL
+ );
+ }
+ }
+ return back;
+}
+
+
+
+/** Data exchange with accounting system.
+ @param pres Flag: Process response, 0=no, 1=acct-check, 2=info.
+*/
+static
+void
+process_data(int pres)
+{
+ const char *ep; /* End pointer for text to number conversions */
+ char *ptr; /* Traverse data line */
+ dk4_um_t um; /* Number obtained from text */
+ size_t sl; /* Input buffer string length */
+ size_t wrb; /* Bytes we still have to write */
+ dk4_socket_t sock; /* Connection to accounting/quota daemon */
+ int res; /* Operation result */
+ int cc; /* Flag: Can continue */
+
+
+#line 611 "printqdc.ctr"
+ wrb = sl = strlen(inbuf);
+ /* LOG/SHOW: Request */
+ if (0 != intera) {
+
+#line 614 "printqdc.ctr"
+ fputs(pqdc_kw[4], stdout);
+ if (0 < sl) {
+ fputs(inbuf, stdout);
+ if (0 < sl) {
+ if ('\n' != inbuf[sl - 1]) {
+ fputc('\n', stdout);
+ }
+ } else {
+ fputc('\n', stdout);
+ }
+ }
+ fflush(stdout);
+ }
+ if ((0 < sl) && (0 != can_continue())) {
+
+#line 628 "printqdc.ctr"
+ if ((NULL != host_name) && (0 < portno)) {
+
+#line 629 "printqdc.ctr"
+ sock = dk4socket_c8_tcp_client_host_port(
+ host_name, portno, 0, 0L, 0L, NULL
+ );
+ } else {
+
+#line 633 "printqdc.ctr"
+ sock = dk4socket_c8_unix_client(
+ ((NULL != sock_name) ? sock_name : def_sock_name), NULL
+ );
+ }
+ if (INVALID_SOCKET != sock) {
+
+#line 638 "printqdc.ctr"
+ if (0 != can_continue()) {
+
+#line 639 "printqdc.ctr"
+ res = dk4socket_send(sock, inbuf, &wrb, 0, 0L, 0L, NULL);
+ if ((DK4_SOCKET_RESULT_SUCCESS == res) && (wrb == sl)) {
+
+#line 641 "printqdc.ctr"
+ if (0 != can_continue()) {
+
+#line 642 "printqdc.ctr"
+ res = dk4socket_shutdown(sock, DK4_SOCKET_SHUT_WRITE, NULL);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+
+#line 644 "printqdc.ctr"
+ cc = 1;
+ do {
+ if (0 != can_continue()) {
+
+#line 647 "printqdc.ctr"
+ wrb = sizeof(inbuf);
+ res = dk4socket_recv(sock, inbuf, &wrb, 0, 0L, 0L, NULL);
+ if ((DK4_SOCKET_RESULT_SUCCESS==res)&&(0 != can_continue())) {
+ if (0 < wrb) {
+
+#line 651 "printqdc.ctr"
+ if (0 != pres) {
+
+#line 652 "printqdc.ctr"
+ if (sizeof(inbuf) > wrb) {
+ inbuf[wrb] = '\0';
+ } else {
+ iexval = EXIT_FAILURE;
+ inbuf[sizeof(inbuf)-1] = '\0';
+ }
+ dk4str8_normalize(inbuf, NULL);
+ /* LOG/SHOW: Response */
+ if (0 != intera) {
+ fputs(pqdc_kw[5], stdout);
+ fputs(inbuf, stdout);
+ fputs(pqdc_kw[6], stdout);
+ fflush(stdout);
+ }
+ switch (pres) {
+ case 1: {
+ if (0 == found_response) {
+ switch (dk4str8_array_index(responses,inbuf,0)) {
+ case 1: {
+ exval = LPRNG_EXIT_HOLD;
+ } break;
+ case 2: {
+ exval = LPRNG_EXIT_REMOVE;
+ } break;
+ }
+ }
+ found_response = 1;
+ } break;
+ case 2: {
+ if (0 == found_response) {
+ um = (dk4_um_t)0UL;
+ ep = NULL;
+ ptr = dk4str8_start(inbuf, NULL);
+ if (NULL != ptr) {
+ ptr = dk4str8_next(ptr, NULL);
+ if (NULL != ptr) {
+ ptr = dk4str8_next(ptr, NULL);
+ if (NULL != ptr) {
+ ptr = dk4str8_next(ptr, NULL);
+ if (NULL != ptr) {
+ res = dk4ma_input_c8_dec_dk4_um_t(
+ &um, ptr, &ep, 1, NULL
+ );
+ if (0 == res) {
+ um = (dk4_um_t)0UL;
+ }
+ }
+ }
+ }
+ }
+ if ((dk4_um_t)0UL == um) {
+ exval = LPRNG_EXIT_REMOVE;
+ }
+ }
+ found_response = 1;
+ } break;
+ }
+ } else {
+
+#line 710 "printqdc.ctr"
+ }
+ } else {
+
+#line 712 "printqdc.ctr"
+ cc = 0;
+ }
+ } else {
+
+#line 715 "printqdc.ctr"
+ iexval = EXIT_FAILURE;
+ cc = -1;
+ }
+ } else {
+
+#line 719 "printqdc.ctr"
+ cc = -1;
+ }
+ } while (1 == cc);
+ } else {
+
+#line 723 "printqdc.ctr"
+ iexval = EXIT_FAILURE;
+ /* ERROR: Failed to shut down socket */
+ log_1(11);
+ }
+ } else {
+
+#line 728 "printqdc.ctr"
+ }
+ } else {
+
+#line 730 "printqdc.ctr"
+ iexval = EXIT_FAILURE;
+ /* ERROR: Sending data failed */
+ log_1(12);
+ }
+ } else {
+
+#line 735 "printqdc.ctr"
+ }
+ dk4socket_close(sock, NULL);
+ } else {
+
+#line 738 "printqdc.ctr"
+ iexval = EXIT_FAILURE;
+ /* ERROR: Failed to open socket */
+ log_1(13);
+ }
+ } else {
+
+#line 743 "printqdc.ctr"
+ }
+
+
+#line 745 "printqdc.ctr"
+}
+
+
+
+/** Find final quote for current word.
+ @param str String to find quote in.
+ @param quote Quote character.
+ @return Pointer to found quote on success, NULL on error.
+*/
+static
+char *
+lprng_final_quote(char *str, char quote)
+{
+ char *back = NULL;
+
+
+#line 760 "printqdc.ctr"
+ while (('\0' != *str) && (NULL == back)) {
+ if (quote == *str) {
+ *str = '\0';
+ back = str;
+ back++;
+ back = dk4str8_start(back, NULL);
+ } else {
+ if ('\\' == *str) {
+ if ('\0' != str[1]) {
+ dk4str8_cpy_to_left(str, &(str[1]));
+ str++;
+ } else {
+ *str = '\0';
+ }
+ } else {
+ str++;
+ }
+ }
+ }
+
+
+#line 780 "printqdc.ctr"
+ return back;
+}
+
+
+/** Find start of next text word in LPRng accounting line.
+ @param str Current word (remaining text) in accounting line.
+ @return Pointer to next word if found, NULL on error.
+*/
+static
+char *
+lprng_next_word(char *str)
+{
+ char *back = NULL;
+
+
+#line 794 "printqdc.ctr"
+ switch (*str) {
+ case '\'' : {
+ back = lprng_final_quote(&(str[1]), '\'');
+ } break;
+ case '"' : {
+ back = lprng_final_quote(&(str[1]), '"');
+ } break;
+ default : {
+ back = dk4str8_next(str, NULL);
+ } break;
+ }
+
+#line 805 "printqdc.ctr"
+ return back;
+}
+
+
+
+/** Fill data structure from LPRng accounting line.
+ @param liptr Structure to fill.
+ @param textline The text line to use.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+lprng_info_from_line(lprng_info_t *liptr, char *textline)
+{
+ char *next;
+ int back = 1;
+
+
+#line 822 "printqdc.ctr"
+ DK4_MEMRES(liptr, sizeof(lprng_info_t));
+ liptr->username = NULL; liptr->queuename = NULL;
+ liptr->jobtitle = NULL; liptr->pagecount = NULL;
+ while (NULL != textline) {
+ next = lprng_next_word(textline);
+ if (('\'' == *textline) || ('"' == *textline)) {
+ textline++;
+ }
+ if ('-' == *textline) {
+ textline++;
+ switch (*textline) {
+ case 'n': {
+ liptr->username = ++textline;
+ } break;
+ case 'P': {
+ liptr->queuename = ++textline;
+ } break;
+ case 'J': {
+ liptr->jobtitle = ++textline;
+ } break;
+ case 'p': {
+ liptr->pagecount = ++textline;
+ } break;
+ }
+ } else {
+
+#line 847 "printqdc.ctr"
+#if 0
+ /* 2016-02-15 Simply ignore non-option text.
+ */
+ back = 0;
+ /* ERROR: No minus sign */
+#endif
+ }
+ textline = next;
+ }
+
+
+#line 857 "printqdc.ctr"
+ return back;
+}
+
+
+
+/** Process one line received from LPRng.
+ @param cmd Index in command names array.
+ @param args Further arguments in line.
+*/
+static
+void
+lprng_line(int cmd, char *args)
+{
+ lprng_info_t li; /* All relevant components of line */
+ const char *ep = NULL; /* End pointer for numeric conversion */
+ const char *jt; /* Job title */
+ dk4_um_t um; /* Text to number conversion result */
+ int res; /* Operation result */
+ int ok = 0; /* Flag: Can process line */
+
+
+#line 877 "printqdc.ctr"
+ if (0 != lprng_info_from_line(&li, args)) {
+ switch (cmd) {
+ case 0: {
+ if ((NULL != li.username) && (NULL != li.queuename)) {
+ if (0 != dk4str8_cpy_s(inbuf,sizeof(inbuf),command_names[7], NULL)) {
+ if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),pqdc_kw[1], NULL)) {
+ if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),li.queuename, NULL)) {
+ if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),pqdc_kw[1], NULL)) {
+ if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),li.username, NULL)) {
+ if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),pqdc_kw[0], NULL)) {
+ ok = 1;
+
+#line 888 "printqdc.ctr"
+ }
+ }
+ }
+ }
+ }
+ }
+ if (0 != ok) {
+ process_data(1);
+ } else {
+
+#line 897 "printqdc.ctr"
+ iexval = EXIT_FAILURE;
+ /* ERROR: Failed to construct request */
+ log_1(14);
+ }
+ } else {
+
+#line 902 "printqdc.ctr"
+ iexval = EXIT_FAILURE;
+ /* ERROR: Incomplete information */
+ log_1(15);
+ }
+ } break;
+ default: {
+ if ((NULL != li.username) && (NULL != li.queuename)) {
+ if (NULL != li.pagecount) {
+ res = dk4ma_input_c8_dec_dk4_um_t(&um, li.pagecount, &ep, 1, NULL);
+ if (0 != res) {
+ cmd += 4;
+ if(0 !=dk4str8_cpy_s(inbuf,sizeof(inbuf),command_names[cmd],NULL))
+ {
+ if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),pqdc_kw[1], NULL)) {
+ if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),li.queuename, NULL)) {
+ if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),pqdc_kw[1], NULL)) {
+ if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),li.username, NULL)) {
+ if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),pqdc_kw[1], NULL)) {
+ if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),li.pagecount, NULL)) {
+ if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),pqdc_kw[1], NULL)) {
+ if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),pqdc_kw[2], NULL)) {
+ if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),pqdc_kw[1], NULL)) {
+ jt = li.jobtitle;
+ if (NULL == jt) { jt = pqdc_kw[3]; }
+ if (0 != dk4str8_cat_s(inbuf, sizeof(inbuf), jt, NULL)) {
+ if (0 != dk4str8_cat_s(inbuf, sizeof(inbuf), pqdc_kw[0], NULL)) {
+ ok = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if (0 != ok) {
+
+#line 942 "printqdc.ctr"
+ process_data(0);
+ } else {
+
+#line 944 "printqdc.ctr"
+ iexval = EXIT_FAILURE;
+ /* ERROR: Failed to construct request */
+ log_1(14);
+ }
+ } else {
+
+#line 949 "printqdc.ctr"
+ iexval = EXIT_FAILURE;
+ /* ERROR: Pagecounter not numeric */
+ log_1(16);
+ }
+ } else {
+
+#line 954 "printqdc.ctr"
+ iexval = EXIT_FAILURE;
+ /* ERROR: Incomplete information */
+ log_1(15);
+ }
+ } else {
+
+#line 959 "printqdc.ctr"
+ iexval = EXIT_FAILURE;
+ /* ERROR: Incomplete information */
+ log_1(15);
+ }
+ } break;
+ }
+ } else {
+ iexval = EXIT_FAILURE;
+ }
+
+
+#line 969 "printqdc.ctr"
+}
+
+
+
+/** Process one line containing printqd style data.
+ @param args Arguments text.
+ @param minargs Minimum required number of arguments.
+ @param num3 Flag: Argument 3 must be unsigned number.
+ @param pres Flag: Process response.
+*/
+static
+void
+printqd_line(char *args, size_t minargs, int num3, int pres)
+{
+ const char *ep = NULL; /* End of usable data */
+ char *next; /* Start of arguments */
+ dk4_um_t um = (dk4_um_t)0UL; /* Numeric conversion result */
+ size_t i; /* Current argument index */
+ int res; /* Operation result */
+ int errnum = 0; /* Flag: Numeric error */
+
+
+#line 990 "printqdc.ctr"
+ dk4str8_normalize(args, NULL);
+ i = 0;
+
+#line 992 "printqdc.ctr"
+ while(args) {
+ i++;
+ next = dk4str8_next(args, NULL);
+ if ((3 == i) && (0 != num3)) {
+
+#line 996 "printqdc.ctr"
+ res = dk4ma_input_c8_dec_dk4_um_t(&um, args, &ep, 1, NULL);
+ if (0 == res) { errnum = 1; }
+ }
+ args = next;
+ }
+
+#line 1001 "printqdc.ctr"
+ if ((i >= minargs) && (0 == errnum)) {
+ process_data(pres);
+ } else {
+ if (i < minargs) {
+ /* ERROR: Too few arguments */
+ log_1(17);
+ }
+ if (0 != errnum) {
+ /* ERROR: Page counter not numeric */
+ log_1(16);
+ }
+ iexval = EXIT_FAILURE;
+ }
+
+
+#line 1015 "printqdc.ctr"
+}
+
+
+
+/** Process input from stdin.
+*/
+static
+void
+process_input(void)
+{
+ char *args; /* Start of arguments after command */
+ int cc; /* Flag: Can continue */
+ int res; /* Operation result for numeric conversions */
+
+
+#line 1029 "printqdc.ctr"
+ cc = 1;
+ do {
+ if (0 != can_continue()) {
+
+#line 1032 "printqdc.ctr"
+ if (fgets(inbuf, sizeof(inbuf), stdin)) {
+
+#line 1033 "printqdc.ctr"
+ dk4str8_cpy_s(cpbuf, sizeof(cpbuf), inbuf, NULL);
+ dk4str8_delnl(cpbuf);
+ if (NULL != dk4str8_start(cpbuf, NULL)) {
+ if (0 != intera) {
+
+#line 1037 "printqdc.ctr"
+ fputs(cpbuf, stdout);
+ fputc('\n', stdout);
+ fflush(stdout);
+ }
+ args = dk4str8_next(cpbuf, NULL);
+ if (NULL != args) {
+
+#line 1043 "printqdc.ctr"
+ res = dk4str8_array_index(command_names, cpbuf, 0);
+ if (0 != can_continue()) {
+ switch (res) {
+ case 0: {
+ lprng_line(res, args);
+ } break;
+ case 1: {
+ } break;
+ case 2: {
+ } break;
+ case 3: {
+ } break;
+ case 4: {
+ lprng_line(res, args);
+ } break;
+ case 5: {
+ lprng_line(res, args);
+ } break;
+ case 6: {
+ printqd_line(args, 2, 0, 2);
+ } break;
+ case 7: {
+ printqd_line(args, 2, 0, 1);
+ } break;
+ case 8: {
+ printqd_line(args, 4, 1, 0);
+ } break;
+ case 9: {
+ printqd_line(args, 4, 1, 0);
+ } break;
+ case 10: {
+ printqd_line(args, 3, 1, 0);
+ } break;
+ case 11: {
+ printqd_line(args, 1, 0, 0);
+ } break;
+ default: {
+ iexval = EXIT_FAILURE;
+ /* ERROR: Unknown keyword */
+ log_1(18);
+ } break;
+ }
+ } else {
+ cc = -1;
+ }
+ } else {
+
+#line 1089 "printqdc.ctr"
+ /* ERROR: No arguments */
+ log_1(19);
+ iexval = EXIT_FAILURE;
+ }
+ } else {
+
+#line 1094 "printqdc.ctr"
+ }
+ } else {
+
+#line 1096 "printqdc.ctr"
+ eof_found = 1;
+ cc = 0;
+ }
+ } else {
+
+#line 1100 "printqdc.ctr"
+ cc = -1;
+ }
+ } while (1 == cc);
+
+
+#line 1104 "printqdc.ctr"
+}
+
+
+
+/** Show a text paragraph on standard output.
+ @param txt Text to show.
+*/
+static
+void
+show_text(const char * const *txt)
+{
+ if (NULL != txt) {
+ while (NULL != *txt) {
+ fputs(*(txt++), stdout);
+ fputc('\n', stdout);
+ }
+ fflush(stdout);
+ }
+}
+
+
+
+/** Handle --help, --version, --license options.
+*/
+static
+void
+run_hvl(void)
+{
+ if (0 != (1 & hvl)) {
+ show_text(help_text);
+ }
+ if (0 != (2 & hvl)) {
+ fputs(version_text, stdout);
+ fputc('\n', stdout);
+ fflush(stdout);
+ }
+ if (0 != (4 & hvl)) {
+ show_text(license_text);
+ }
+}
+
+
+
+/** Main program.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return Exit status code.
+*/
+int
+main(int argc, char *argv[])
+{
+#ifdef DK4_HAVE_SIGACTION
+#ifdef SIGPIPE
+ struct sigaction opipe;
+ struct sigaction npipe;
+#endif
+ struct sigaction oint;
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+#else
+#ifdef SIGPIPE
+ dk4_sig_handler_t *opipe = NULL;
+#endif
+ dk4_sig_handler_t *oterm = NULL;
+ dk4_sig_handler_t *oint = NULL;
+#endif
+#ifdef DK4_HAVE_SIGACTION
+#ifdef SIGPIPE
+ int spipe = 0;
+#endif
+ int sint = 0;
+ int sterm = 0;
+ int s_f_i = 0;
+ int s_f_r = 0;
+#endif
+ int socki = 0;
+
+ /* Set signal handlers
+ */
+#if DK4_HAVE_SIGACTION
+#ifdef SIGPIPE
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ spipe = 1;
+#endif
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ sterm = 1;
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ sint = 1;
+#else
+#ifdef SIGPIPE
+ opipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oint = sigset(SIGINT, sig_handler_int);
+ oterm = sigset(SIGTERM, sig_handler_term);
+#endif
+
+ /* Start tracing
+ */
+
+
+#line 1246 "printqdc.ctr"
+
+
+#line 1247 "printqdc.ctr"
+
+ /* Process command line arguments
+ */
+ if (0 == cmd_line_args(argc, argv)) { goto finished; }
+
+ /* Help, version, license.
+ */
+ if (0 != hvl) {
+ run_hvl();
+ goto finished;
+ }
+
+ /* Bring socket subsystem up.
+ */
+ if (DK4_SOCKET_RESULT_SUCCESS != dk4socket_up(NULL)) {
+ /* ERROR: Failed to initialize socket subsystem */
+ log_1(23);
+ goto finished;
+ }
+ socki = 1;
+
+ iexval = EXIT_SUCCESS;
+
+
+#line 1270 "printqdc.ctr"
+ process_input();
+
+ finished:
+
+ /* Eat up remaining input, if any.
+ */
+ if ((0 == hvl) && (0 == eof_found)) { eatup_input(); }
+
+ /* Log notification about abort by signal.
+ */
+ if (0 == can_continue()) {
+ /* LOG: Interrupted by signal */
+ log_1(20);
+ iexval = EXIT_FAILURE;
+ }
+
+ /* Release socket subsystem.
+ */
+ if (0 != socki) { (void)dk4socket_down(NULL); }
+
+ /* Restore signal handlers
+ */
+#if DK4_HAVE_SIGACTION
+ if (0 != s_f_i) {
+ /* ERROR: Failed to install signal handlers */
+ log_1(21);
+ iexval = EXIT_FAILURE;
+ }
+ if (0 != sint) {
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ s_f_r = 1;
+ }
+ }
+ if (0 != sterm) {
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ s_f_r = 1;
+ }
+ }
+#ifdef SIGPIPE
+ if (0 != spipe) {
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ s_f_r = 1;
+ }
+ }
+#endif
+ if (0 != s_f_r) {
+ /* ERROR: Failed to restore signal handlers */
+ log_1(22);
+ iexval = EXIT_FAILURE;
+ }
+#else
+ if (NULL != oterm) { sigset(SIGTERM, oterm); }
+ if (NULL != oint ) { sigset(SIGINT, oint ); }
+#ifdef SIGPIPE
+ if (NULL != opipe) { sigset(SIGPIPE, opipe); }
+#endif
+#endif
+
+ /* Set exit status code depending on interactive mode
+ */
+ if (0 != intera) { exval = iexval; }
+
+ /* Finish tracing
+ */
+
+
+#line 1335 "printqdc.ctr"
+
+
+#line 1336 "printqdc.ctr"
+
+ /* Exit
+ */
+ exit(exval); return exval;
+}
+
+#else
+/* if (DK4_CHAR_SIZE == 1) && ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET)) */
+
+/** Main program.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return Exit status code.
+*/
+int main(int argc, char *argv[])
+{
+ fputs("printqdc: ERROR: Program can not be used on this system!\n", stderr);
+ fflush(stderr);
+ exit(EXIT_FAILURE); return EXIT_FAILURE;
+}
+
+#endif
+/* if (DK4_CHAR_SIZE == 1) && ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET)) */
+
diff --git a/support/dktools/printqdc.ctr b/support/dktools/printqdc.ctr
new file mode 100644
index 0000000000..35be526772
--- /dev/null
+++ b/support/dktools/printqdc.ctr
@@ -0,0 +1,1359 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+#include <stdio.h>
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+
+
+/** Requirements to build this program:
+ * Use 8 bit characters, so we can use the directories from dk4inst.c.
+ * Signal handling mechanism.
+*/
+#if (DK4_CHAR_SIZE == 1) && ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET))
+
+
+
+#if DK4_HAVE_MATH_H
+#ifndef MATH_H_INCLUDED
+#include <math.h>
+#define MATH_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_ERRNO_H
+#ifndef ERRNO_H_INCLUDED
+#include <errno.h>
+#define ERRNO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4inst.h"
+#include "dk4mpl.h"
+#include "dk4mem.h"
+#include "dk4mai8ddu.h"
+#include "dk4mai8dus.h"
+#include "dk4str8.h"
+#include "dk4lprng.h"
+#include "dk4opt.h"
+#include "dk4sock.h"
+#include "dk4vers.h"
+
+
+
+$!trace-include
+
+
+
+/** Information from one LPRng accounting line.
+*/
+typedef struct {
+ char *username;
+ char *queuename;
+ char *jobtitle;
+ char *pagecount;
+} lprng_info_t;
+
+
+
+
+/** Command line options for program.
+*/
+static dk4_option_t options[] = {
+ { { dkT('i'), dkT("interactive"), DK4_OPT_ARG_NONE }, { NULL }, 0},
+ { { dkT('s'), dkT("socket"), DK4_OPT_ARG_STRING }, { NULL }, 0},
+ { { dkT('h'), dkT("host"), DK4_OPT_ARG_STRING }, { NULL }, 0},
+ { { dkT('p'), dkT("port"), DK4_OPT_ARG_UNSIGNED }, { NULL }, 0},
+ { { dkT('\0'),dkT("help"), DK4_OPT_ARG_NONE}, { NULL }, 0},
+ { { dkT('\0'),dkT("version"), DK4_OPT_ARG_NONE}, { NULL }, 0},
+ { { dkT('\0'),dkT("license"), DK4_OPT_ARG_NONE}, { NULL }, 0}
+};
+
+
+
+/** Help text.
+*/
+static const char * const help_text[] = {
+$!text
+
+Print quota daemon client
+
+printqdc [-i] [-s path] | [-h host -p port]
+
+-i Interactive mode instead of default pipe mode.
+--interactive
+
+-s path Path name for local UNIX domain socket.
+--socket=path
+
+-h host Host name of remote host.
+--host=host
+
+-p port Port number at remote host.
+--port=port
+
+--help Show this help text.
+--version Show version number.
+--license Show license information.
+
+$!end
+};
+
+
+
+/** License conditions text.
+*/
+static const char * const license_text[] = {
+$!text preprocessor
+
+This software uses code from the following projects, either directly or as
+a library:
+
+dktools Dirk Krause's tools and libraries.
+ See http://dktools.sourceforge.net/ for more information.
+
+DK tools and libraries license
+==============================
+Copyright (c) 2015-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+$!end
+};
+
+
+
+/** Version information.
+*/
+static const char version_text[] = { DKT_VERSION_C8 };
+
+
+
+/** Constant text keywords used by the module.
+*/
+static const char * const pqdc_kw[] = {
+$!string-table
+#
+# 0 Newline
+#
+\n
+#
+# 1 Space
+#
+
+#
+# 2 Default job name
+#
+x@x+1
+#
+# 3 Default job title
+#
+Print job
+#
+# 4
+#
+->
+#
+# 5 6
+#
+<- "
+"\n
+#
+# 7 ... 10
+#
+printqdc:
+ERROR: Port number too large!\n
+ERROR: Port number required!\n
+ERROR: Host name required!\n
+#
+# 11 ... 15
+#
+ERROR: Failed to shut down socket!\n
+ERROR: Failed to send data!\n
+ERROR: Failed to open connection to accounting system!\n
+ERROR: Failed to construct request (would be too long)!\n
+ERROR: Incomplete information to construct request!\n
+#
+# 16 ... 20
+#
+ERROR: Pagecounter not numeric!\n
+ERROR: Too few arguments for request!\n
+ERROR: Unknown command keyword!\n
+ERROR: Missing arguments!\n
+ERROR: Interrupted by signal!\n
+#
+# 21 ... 22
+#
+ERROR: Failed to install signal handlers!\n
+ERROR: Failed to restore signal handlers!\n
+#
+# 23
+#
+ERROR: Failed to initialize socket subsystem!\n
+$!end
+};
+
+
+
+/** Default socket name.
+*/
+static const char def_sock_name[] = {
+ DK4_INST_DIR_VAR "/run/printqd/printqd.sock"
+};
+
+
+
+/** Protocol keywords at start of accounting line.
+*/
+static const char * const command_names[] = {
+$!string-table
+#
+# 0 ... 5 LPRng
+#
+jobstart
+jobend
+start
+end
+filestart
+fileend
+#
+# 6 ... 11 printqd
+#
+info
+acct-check
+acct-start
+acct-end
+acct-charge
+control
+$!end
+};
+
+
+/** Responses from printqd
+*/
+static const char * const responses[] = {
+$!string-table
+ACCEPT
+HOLD
+REMOVE
+$!end
+};
+
+/** Data exchange buffer.
+*/
+static char inbuf[4096];
+
+
+/** Copy for inspection.
+*/
+static char cpbuf[sizeof(inbuf)];
+
+
+/** Host name for network connection.
+*/
+static char *host_name = NULL;
+
+
+/** Socket file name for local connection.
+*/
+static char *sock_name = NULL;
+
+
+/** Number of options.
+*/
+static size_t szoptions = sizeof(options)/sizeof(dk4_option_t);
+
+
+/** Normal exit value (when run as pipe).
+*/
+static int exval = LPRNG_EXIT_SUCCESS;
+
+
+
+/** Help (1), version (2), license (4).
+*/
+static int hvl = 0;
+
+
+
+/** Exit value for interactive mode.
+*/
+static int iexval = EXIT_FAILURE;
+
+
+/** Flag: Interactive mode (-i option).
+*/
+static int intera = 0;
+
+
+/** Flag: EOF was found.
+*/
+static int eof_found = 0;
+
+
+/** Flag: Response already found and processed.
+*/
+static int found_response = 0;
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+/** Port number for network connection.
+*/
+static unsigned short portno = 0U;
+
+
+/** Pass pointer through.
+ Use of this function is recommended by CERT C coding standard
+ to avoid optimizing out.
+ @param ptr Pointer to pass through.
+ @return The ptr argument.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+
+/** Check whether we can continue or must abort due to signal.
+ @param dopipe Flag: Check for SIGPIPE too.
+ @return 1 if we can continue, 0 otherwise.
+*/
+static
+int
+can_continue(void)
+{
+ int back = 1;
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_int)) { back = 0; }
+ return back;
+}
+
+
+
+/** Log one-component message to stderr.
+ @param kwind Index of text in printqdc_kw array.
+*/
+static
+void
+log_1(size_t kwind)
+{
+ if (0 != intera) {
+ fputs(pqdc_kw[7], stderr);
+ fputs(pqdc_kw[kwind], stderr);
+ fflush(stderr);
+ }
+}
+
+
+/** Eat up input to avoid broken pipe in feeder.
+*/
+static
+void
+eatup_input(void)
+{
+ size_t rdb;
+ int cc = 1;
+ do {
+ if (0 != can_continue()) {
+ rdb = fread(inbuf, 1, sizeof(inbuf), stdin);
+ if (0 == rdb) {
+ cc = 0;
+ }
+ } else {
+ cc = -1;
+ }
+ } while(1 == cc);
+}
+
+
+
+/** Process command line arguments.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+cmd_line_args(int argc, char *argv[])
+{
+ dkChar *filenames[32];
+ size_t szfilenames = DK4_SIZEOF(filenames,DK4_PDKCHAR);
+ int back;
+ back = dk4opt_process_argv(
+ options, szoptions, argc, argv, filenames, &szfilenames,
+ 1, 0, NULL
+ );
+ if (1 == back) {
+ if (0 != options[4].found) {
+ hvl |= 1;
+ }
+ if (0 != options[5].found) {
+ hvl |= 2;
+ }
+ if (0 != options[6].found) {
+ hvl |= 4;
+ }
+ if (0 != options[0].found) {
+ intera = 1;
+ }
+ if (0 != options[1].found) {
+ sock_name = options[1].val.t;
+ }
+ if (0 != options[2].found) {
+ host_name = options[2].val.t;
+ }
+ if (0 != options[3].found) {
+ if ((dk4_um_t)0x0000FFFFUL >= options[3].val.u) {
+ portno = (unsigned short)(options[3].val.u);
+ } else {
+ back = 0;
+ /* ERROR: Port number to large! */
+ log_1(8);
+ }
+ }
+ if ((NULL != host_name) && (0 == portno)) {
+ back = 0;
+ /* ERROR: Port number required */
+ log_1(9);
+ }
+ if ((NULL == host_name) && (0 != portno)) {
+ back = 0;
+ /* ERROR: Host name required */
+ log_1(10);
+ }
+ } else {
+ if (0 != options[0].found) {
+ (void)dk4opt_process_argv(
+ options, szoptions, argc, argv, filenames, &szfilenames,
+ 1, 1, NULL
+ );
+ }
+ }
+ return back;
+}
+
+
+
+/** Data exchange with accounting system.
+ @param pres Flag: Process response, 0=no, 1=acct-check, 2=info.
+*/
+static
+void
+process_data(int pres)
+{
+ const char *ep; /* End pointer for text to number conversions */
+ char *ptr; /* Traverse data line */
+ dk4_um_t um; /* Number obtained from text */
+ size_t sl; /* Input buffer string length */
+ size_t wrb; /* Bytes we still have to write */
+ dk4_socket_t sock; /* Connection to accounting/quota daemon */
+ int res; /* Operation result */
+ int cc; /* Flag: Can continue */
+ $? "+ process_data %d", pres
+ wrb = sl = strlen(inbuf);
+ /* LOG/SHOW: Request */
+ if (0 != intera) { $? ". log at start"
+ fputs(pqdc_kw[4], stdout);
+ if (0 < sl) {
+ fputs(inbuf, stdout);
+ if (0 < sl) {
+ if ('\n' != inbuf[sl - 1]) {
+ fputc('\n', stdout);
+ }
+ } else {
+ fputc('\n', stdout);
+ }
+ }
+ fflush(stdout);
+ }
+ if ((0 < sl) && (0 != can_continue())) { $? ". rq size ok"
+ if ((NULL != host_name) && (0 < portno)) { $? ". network"
+ sock = dk4socket_c8_tcp_client_host_port(
+ host_name, portno, 0, 0L, 0L, NULL
+ );
+ } else { $? ". local"
+ sock = dk4socket_c8_unix_client(
+ ((NULL != sock_name) ? sock_name : def_sock_name), NULL
+ );
+ }
+ if (INVALID_SOCKET != sock) { $? ". sock"
+ if (0 != can_continue()) { $? ". can continue"
+ res = dk4socket_send(sock, inbuf, &wrb, 0, 0L, 0L, NULL);
+ if ((DK4_SOCKET_RESULT_SUCCESS == res) && (wrb == sl)) { $? ". send"
+ if (0 != can_continue()) { $? ". can continue"
+ res = dk4socket_shutdown(sock, DK4_SOCKET_SHUT_WRITE, NULL);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) { $? ". shutdown"
+ cc = 1;
+ do {
+ if (0 != can_continue()) { $? ". can continue"
+ wrb = sizeof(inbuf);
+ res = dk4socket_recv(sock, inbuf, &wrb, 0, 0L, 0L, NULL);
+ if ((DK4_SOCKET_RESULT_SUCCESS==res)&&(0 != can_continue())) {
+ if (0 < wrb) { $? ". data"
+ if (0 != pres) { $? ". process response"
+ if (sizeof(inbuf) > wrb) {
+ inbuf[wrb] = '\0';
+ } else {
+ iexval = EXIT_FAILURE;
+ inbuf[sizeof(inbuf)-1] = '\0';
+ }
+ dk4str8_normalize(inbuf, NULL);
+ /* LOG/SHOW: Response */
+ if (0 != intera) {
+ fputs(pqdc_kw[5], stdout);
+ fputs(inbuf, stdout);
+ fputs(pqdc_kw[6], stdout);
+ fflush(stdout);
+ }
+ switch (pres) {
+ case 1: {
+ if (0 == found_response) {
+ switch (dk4str8_array_index(responses,inbuf,0)) {
+ case 1: {
+ exval = LPRNG_EXIT_HOLD;
+ } break;
+ case 2: {
+ exval = LPRNG_EXIT_REMOVE;
+ } break;
+ }
+ }
+ found_response = 1;
+ } break;
+ case 2: {
+ if (0 == found_response) {
+ um = (dk4_um_t)0UL;
+ ep = NULL;
+ ptr = dk4str8_start(inbuf, NULL);
+ if (NULL != ptr) {
+ ptr = dk4str8_next(ptr, NULL);
+ if (NULL != ptr) {
+ ptr = dk4str8_next(ptr, NULL);
+ if (NULL != ptr) {
+ ptr = dk4str8_next(ptr, NULL);
+ if (NULL != ptr) {
+ res = dk4ma_input_c8_dec_dk4_um_t(
+ &um, ptr, &ep, 1, NULL
+ );
+ if (0 == res) {
+ um = (dk4_um_t)0UL;
+ }
+ }
+ }
+ }
+ }
+ if ((dk4_um_t)0UL == um) {
+ exval = LPRNG_EXIT_REMOVE;
+ }
+ }
+ found_response = 1;
+ } break;
+ }
+ } else { $? ". ignore response"
+ }
+ } else { $? ". 0 bytes response"
+ cc = 0;
+ }
+ } else { $? "! recv"
+ iexval = EXIT_FAILURE;
+ cc = -1;
+ }
+ } else { $? "! signal"
+ cc = -1;
+ }
+ } while (1 == cc);
+ } else { $? "! shutdown"
+ iexval = EXIT_FAILURE;
+ /* ERROR: Failed to shut down socket */
+ log_1(11);
+ }
+ } else { $? "! signal"
+ }
+ } else { $? "! send"
+ iexval = EXIT_FAILURE;
+ /* ERROR: Sending data failed */
+ log_1(12);
+ }
+ } else { $? "! signal"
+ }
+ dk4socket_close(sock, NULL);
+ } else { $? "! sock"
+ iexval = EXIT_FAILURE;
+ /* ERROR: Failed to open socket */
+ log_1(13);
+ }
+ } else { $? "! rq size 0"
+ }
+ $? "- process_data"
+}
+
+
+
+/** Find final quote for current word.
+ @param str String to find quote in.
+ @param quote Quote character.
+ @return Pointer to found quote on success, NULL on error.
+*/
+static
+char *
+lprng_final_quote(char *str, char quote)
+{
+ char *back = NULL;
+ $? "+ lprng_final_quote %c %s", quote, TR_8STR(str)
+ while (('\0' != *str) && (NULL == back)) {
+ if (quote == *str) {
+ *str = '\0';
+ back = str;
+ back++;
+ back = dk4str8_start(back, NULL);
+ } else {
+ if ('\\' == *str) {
+ if ('\0' != str[1]) {
+ dk4str8_cpy_to_left(str, &(str[1]));
+ str++;
+ } else {
+ *str = '\0';
+ }
+ } else {
+ str++;
+ }
+ }
+ }
+ $? "- lprng_final_quote \"%s\"", TR_8STR(back)
+ return back;
+}
+
+
+/** Find start of next text word in LPRng accounting line.
+ @param str Current word (remaining text) in accounting line.
+ @return Pointer to next word if found, NULL on error.
+*/
+static
+char *
+lprng_next_word(char *str)
+{
+ char *back = NULL;
+ $? "+ lprng_next_word \"%s\"", TR_8STR(str)
+ switch (*str) {
+ case '\'' : {
+ back = lprng_final_quote(&(str[1]), '\'');
+ } break;
+ case '"' : {
+ back = lprng_final_quote(&(str[1]), '"');
+ } break;
+ default : {
+ back = dk4str8_next(str, NULL);
+ } break;
+ } $? "- lprng_next_word \"%s\"", TR_8STR(back)
+ return back;
+}
+
+
+
+/** Fill data structure from LPRng accounting line.
+ @param liptr Structure to fill.
+ @param textline The text line to use.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+lprng_info_from_line(lprng_info_t *liptr, char *textline)
+{
+ char *next;
+ int back = 1;
+ $? "+ lprng_info_from_line \"%s\"", TR_8STR(textline)
+ DK4_MEMRES(liptr, sizeof(lprng_info_t));
+ liptr->username = NULL; liptr->queuename = NULL;
+ liptr->jobtitle = NULL; liptr->pagecount = NULL;
+ while (NULL != textline) {
+ next = lprng_next_word(textline);
+ if (('\'' == *textline) || ('"' == *textline)) {
+ textline++;
+ }
+ if ('-' == *textline) {
+ textline++;
+ switch (*textline) {
+ case 'n': {
+ liptr->username = ++textline;
+ } break;
+ case 'P': {
+ liptr->queuename = ++textline;
+ } break;
+ case 'J': {
+ liptr->jobtitle = ++textline;
+ } break;
+ case 'p': {
+ liptr->pagecount = ++textline;
+ } break;
+ }
+ } else { $? "! not a minus"
+#if 0
+ /* 2016-02-15 Simply ignore non-option text.
+ */
+ back = 0;
+ /* ERROR: No minus sign */
+#endif
+ }
+ textline = next;
+ }
+ $? "- lprng_info_from_line %d", back
+ return back;
+}
+
+
+
+/** Process one line received from LPRng.
+ @param cmd Index in command names array.
+ @param args Further arguments in line.
+*/
+static
+void
+lprng_line(int cmd, char *args)
+{
+ lprng_info_t li; /* All relevant components of line */
+ const char *ep = NULL; /* End pointer for numeric conversion */
+ const char *jt; /* Job title */
+ dk4_um_t um; /* Text to number conversion result */
+ int res; /* Operation result */
+ int ok = 0; /* Flag: Can process line */
+ $? "+ lprng_line %d \"%s\"", cmd, TR_8STR(args)
+ if (0 != lprng_info_from_line(&li, args)) {
+ switch (cmd) {
+ case 0: {
+ if ((NULL != li.username) && (NULL != li.queuename)) {
+ if (0 != dk4str8_cpy_s(inbuf,sizeof(inbuf),command_names[7], NULL)) {
+ if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),pqdc_kw[1], NULL)) {
+ if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),li.queuename, NULL)) {
+ if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),pqdc_kw[1], NULL)) {
+ if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),li.username, NULL)) {
+ if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),pqdc_kw[0], NULL)) {
+ ok = 1; $? ". new request constructed"
+ }
+ }
+ }
+ }
+ }
+ }
+ if (0 != ok) {
+ process_data(1);
+ } else { $? "! failed to construct"
+ iexval = EXIT_FAILURE;
+ /* ERROR: Failed to construct request */
+ log_1(14);
+ }
+ } else { $? "! incomplete"
+ iexval = EXIT_FAILURE;
+ /* ERROR: Incomplete information */
+ log_1(15);
+ }
+ } break;
+ default: {
+ if ((NULL != li.username) && (NULL != li.queuename)) {
+ if (NULL != li.pagecount) {
+ res = dk4ma_input_c8_dec_dk4_um_t(&um, li.pagecount, &ep, 1, NULL);
+ if (0 != res) {
+ cmd += 4;
+ if(0 !=dk4str8_cpy_s(inbuf,sizeof(inbuf),command_names[cmd],NULL))
+ {
+ if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),pqdc_kw[1], NULL)) {
+ if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),li.queuename, NULL)) {
+ if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),pqdc_kw[1], NULL)) {
+ if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),li.username, NULL)) {
+ if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),pqdc_kw[1], NULL)) {
+ if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),li.pagecount, NULL)) {
+ if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),pqdc_kw[1], NULL)) {
+ if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),pqdc_kw[2], NULL)) {
+ if (0 != dk4str8_cat_s(inbuf,sizeof(inbuf),pqdc_kw[1], NULL)) {
+ jt = li.jobtitle;
+ if (NULL == jt) { jt = pqdc_kw[3]; }
+ if (0 != dk4str8_cat_s(inbuf, sizeof(inbuf), jt, NULL)) {
+ if (0 != dk4str8_cat_s(inbuf, sizeof(inbuf), pqdc_kw[0], NULL)) {
+ ok = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if (0 != ok) { $? ". rq constructed"
+ process_data(0);
+ } else { $? "! failed to construct rq"
+ iexval = EXIT_FAILURE;
+ /* ERROR: Failed to construct request */
+ log_1(14);
+ }
+ } else { $? "! pc not numeric"
+ iexval = EXIT_FAILURE;
+ /* ERROR: Pagecounter not numeric */
+ log_1(16);
+ }
+ } else { $? "! incomplete rq"
+ iexval = EXIT_FAILURE;
+ /* ERROR: Incomplete information */
+ log_1(15);
+ }
+ } else { $? "! incomplete rq"
+ iexval = EXIT_FAILURE;
+ /* ERROR: Incomplete information */
+ log_1(15);
+ }
+ } break;
+ }
+ } else {
+ iexval = EXIT_FAILURE;
+ }
+ $? "- lprng_line"
+}
+
+
+
+/** Process one line containing printqd style data.
+ @param args Arguments text.
+ @param minargs Minimum required number of arguments.
+ @param num3 Flag: Argument 3 must be unsigned number.
+ @param pres Flag: Process response.
+*/
+static
+void
+printqd_line(char *args, size_t minargs, int num3, int pres)
+{
+ const char *ep = NULL; /* End of usable data */
+ char *next; /* Start of arguments */
+ dk4_um_t um = (dk4_um_t)0UL; /* Numeric conversion result */
+ size_t i; /* Current argument index */
+ int res; /* Operation result */
+ int errnum = 0; /* Flag: Numeric error */
+ $? "+ printqd_line"
+ dk4str8_normalize(args, NULL);
+ i = 0; $? ". line = \"%s\"", args
+ while(args) {
+ i++;
+ next = dk4str8_next(args, NULL);
+ if ((3 == i) && (0 != num3)) { $? ". check \"%s\"", args
+ res = dk4ma_input_c8_dec_dk4_um_t(&um, args, &ep, 1, NULL);
+ if (0 == res) { errnum = 1; }
+ }
+ args = next;
+ } $? ". i=%u errnum=%d", (unsigned)i, errnum
+ if ((i >= minargs) && (0 == errnum)) {
+ process_data(pres);
+ } else {
+ if (i < minargs) {
+ /* ERROR: Too few arguments */
+ log_1(17);
+ }
+ if (0 != errnum) {
+ /* ERROR: Page counter not numeric */
+ log_1(16);
+ }
+ iexval = EXIT_FAILURE;
+ }
+ $? "- printqd_line"
+}
+
+
+
+/** Process input from stdin.
+*/
+static
+void
+process_input(void)
+{
+ char *args; /* Start of arguments after command */
+ int cc; /* Flag: Can continue */
+ int res; /* Operation result for numeric conversions */
+ $? "+ process_input"
+ cc = 1;
+ do {
+ if (0 != can_continue()) { $? ". can continue"
+ if (fgets(inbuf, sizeof(inbuf), stdin)) { $? ". data"
+ dk4str8_cpy_s(cpbuf, sizeof(cpbuf), inbuf, NULL);
+ dk4str8_delnl(cpbuf);
+ if (NULL != dk4str8_start(cpbuf, NULL)) {
+ if (0 != intera) { $? ". interactive"
+ fputs(cpbuf, stdout);
+ fputc('\n', stdout);
+ fflush(stdout);
+ }
+ args = dk4str8_next(cpbuf, NULL);
+ if (NULL != args) { $? ". arguments"
+ res = dk4str8_array_index(command_names, cpbuf, 0);
+ if (0 != can_continue()) {
+ switch (res) {
+ case 0: {
+ lprng_line(res, args);
+ } break;
+ case 1: {
+ } break;
+ case 2: {
+ } break;
+ case 3: {
+ } break;
+ case 4: {
+ lprng_line(res, args);
+ } break;
+ case 5: {
+ lprng_line(res, args);
+ } break;
+ case 6: {
+ printqd_line(args, 2, 0, 2);
+ } break;
+ case 7: {
+ printqd_line(args, 2, 0, 1);
+ } break;
+ case 8: {
+ printqd_line(args, 4, 1, 0);
+ } break;
+ case 9: {
+ printqd_line(args, 4, 1, 0);
+ } break;
+ case 10: {
+ printqd_line(args, 3, 1, 0);
+ } break;
+ case 11: {
+ printqd_line(args, 1, 0, 0);
+ } break;
+ default: {
+ iexval = EXIT_FAILURE;
+ /* ERROR: Unknown keyword */
+ log_1(18);
+ } break;
+ }
+ } else {
+ cc = -1;
+ }
+ } else { $? "! no arguments"
+ /* ERROR: No arguments */
+ log_1(19);
+ iexval = EXIT_FAILURE;
+ }
+ } else { $? ". skip empty line"
+ }
+ } else { $? ". end of data"
+ eof_found = 1;
+ cc = 0;
+ }
+ } else { $? "! aborted"
+ cc = -1;
+ }
+ } while (1 == cc);
+ $? "- process_input"
+}
+
+
+
+/** Show a text paragraph on standard output.
+ @param txt Text to show.
+*/
+static
+void
+show_text(const char * const *txt)
+{
+ if (NULL != txt) {
+ while (NULL != *txt) {
+ fputs(*(txt++), stdout);
+ fputc('\n', stdout);
+ }
+ fflush(stdout);
+ }
+}
+
+
+
+/** Handle --help, --version, --license options.
+*/
+static
+void
+run_hvl(void)
+{
+ if (0 != (1 & hvl)) {
+ show_text(help_text);
+ }
+ if (0 != (2 & hvl)) {
+ fputs(version_text, stdout);
+ fputc('\n', stdout);
+ fflush(stdout);
+ }
+ if (0 != (4 & hvl)) {
+ show_text(license_text);
+ }
+}
+
+
+
+/** Main program.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return Exit status code.
+*/
+int
+main(int argc, char *argv[])
+{
+#ifdef DK4_HAVE_SIGACTION
+#ifdef SIGPIPE
+ struct sigaction opipe;
+ struct sigaction npipe;
+#endif
+ struct sigaction oint;
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+#else
+#ifdef SIGPIPE
+ dk4_sig_handler_t *opipe = NULL;
+#endif
+ dk4_sig_handler_t *oterm = NULL;
+ dk4_sig_handler_t *oint = NULL;
+#endif
+#ifdef DK4_HAVE_SIGACTION
+#ifdef SIGPIPE
+ int spipe = 0;
+#endif
+ int sint = 0;
+ int sterm = 0;
+ int s_f_i = 0;
+ int s_f_r = 0;
+#endif
+ int socki = 0;
+
+ /* Set signal handlers
+ */
+#if DK4_HAVE_SIGACTION
+#ifdef SIGPIPE
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ spipe = 1;
+#endif
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ sterm = 1;
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ sint = 1;
+#else
+#ifdef SIGPIPE
+ opipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oint = sigset(SIGINT, sig_handler_int);
+ oterm = sigset(SIGTERM, sig_handler_term);
+#endif
+
+ /* Start tracing
+ */
+ $!trace-init printqdc.deb
+ $? "+ main"
+
+ /* Process command line arguments
+ */
+ if (0 == cmd_line_args(argc, argv)) { goto finished; }
+
+ /* Help, version, license.
+ */
+ if (0 != hvl) {
+ run_hvl();
+ goto finished;
+ }
+
+ /* Bring socket subsystem up.
+ */
+ if (DK4_SOCKET_RESULT_SUCCESS != dk4socket_up(NULL)) {
+ /* ERROR: Failed to initialize socket subsystem */
+ log_1(23);
+ goto finished;
+ }
+ socki = 1;
+
+ iexval = EXIT_SUCCESS;
+ $? ". comman line arguments processed, going to process input"
+ process_input();
+
+ finished:
+
+ /* Eat up remaining input, if any.
+ */
+ if ((0 == hvl) && (0 == eof_found)) { eatup_input(); }
+
+ /* Log notification about abort by signal.
+ */
+ if (0 == can_continue()) {
+ /* LOG: Interrupted by signal */
+ log_1(20);
+ iexval = EXIT_FAILURE;
+ }
+
+ /* Release socket subsystem.
+ */
+ if (0 != socki) { (void)dk4socket_down(NULL); }
+
+ /* Restore signal handlers
+ */
+#if DK4_HAVE_SIGACTION
+ if (0 != s_f_i) {
+ /* ERROR: Failed to install signal handlers */
+ log_1(21);
+ iexval = EXIT_FAILURE;
+ }
+ if (0 != sint) {
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ s_f_r = 1;
+ }
+ }
+ if (0 != sterm) {
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ s_f_r = 1;
+ }
+ }
+#ifdef SIGPIPE
+ if (0 != spipe) {
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ s_f_r = 1;
+ }
+ }
+#endif
+ if (0 != s_f_r) {
+ /* ERROR: Failed to restore signal handlers */
+ log_1(22);
+ iexval = EXIT_FAILURE;
+ }
+#else
+ if (NULL != oterm) { sigset(SIGTERM, oterm); }
+ if (NULL != oint ) { sigset(SIGINT, oint ); }
+#ifdef SIGPIPE
+ if (NULL != opipe) { sigset(SIGPIPE, opipe); }
+#endif
+#endif
+
+ /* Set exit status code depending on interactive mode
+ */
+ if (0 != intera) { exval = iexval; }
+
+ /* Finish tracing
+ */
+ $? "- main %d", exval
+ $!trace-end
+
+ /* Exit
+ */
+ exit(exval); return exval;
+}
+
+#else
+/* if (DK4_CHAR_SIZE == 1) && ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET)) */
+
+/** Main program.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return Exit status code.
+*/
+int main(int argc, char *argv[])
+{
+ fputs("printqdc: ERROR: Program can not be used on this system!\n", stderr);
+ fflush(stderr);
+ exit(EXIT_FAILURE); return EXIT_FAILURE;
+}
+
+#endif
+/* if (DK4_CHAR_SIZE == 1) && ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET)) */
+
diff --git a/support/dktools/printqds.h b/support/dktools/printqds.h
new file mode 100644
index 0000000000..f2de51c751
--- /dev/null
+++ b/support/dktools/printqds.h
@@ -0,0 +1,19 @@
+
+#ifndef PRINTQDS_H_INCLUDED
+/** Protection against multiple inclusion. */
+#define PRINTQDS_H_INCLUDED 1
+
+/** Maximum request length.
+*/
+#define PQD_INPUT_BUFFER_SIZE 512
+
+/** Maximum response length.
+*/
+#define PQD_OUTPUT_BUFFER_SIZE 128
+
+/** Size of configuration file line.
+*/
+#define PQD_CONFIG_BUFFER_SIZE (DK3_MAX_PATH + PQD_INPUT_BUFFER_SIZE)
+
+#endif
+
diff --git a/support/dktools/prmonsnmp.c b/support/dktools/prmonsnmp.c
new file mode 100644
index 0000000000..5842a9ca1a
--- /dev/null
+++ b/support/dktools/prmonsnmp.c
@@ -0,0 +1,2090 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: prmonsnmp.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file prmonsnmp.c The prmonsnmp module.
+*/
+
+
+#line 10 "prmonsnmp.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+
+
+/** Constant text fragments used by the program, not localized.
+*/
+static const char * const prmonsnmp_kw[] = {
+/* 0 */
+"\n",
+
+/* 1 */
+" ",
+
+/* 2 */
+"prmonsnmp",
+
+/* 3 */
+"public",
+
+/* 4 */
+"unreachable",
+
+/* 5 */
+"unknown",
+
+/* 6 */
+"running",
+
+/* 7 */
+"warning",
+
+/* 8 */
+"testing",
+
+/* 9 */
+"down",
+
+/* 10 */
+"unreachable",
+
+/* 11 */
+"other",
+
+/* 12 */
+"unknown",
+
+/* 13 */
+"idle",
+
+/* 14 */
+"printing",
+
+/* 15 */
+"warmup",
+
+/* 16 */
+"XXXX-XXXX-XXXX-XXXX",
+
+/* 17 */
+" / ",
+
+/* 18 */
+" ",
+
+/* 19 */
+"W: Low paper.\n",
+
+/* 20 */
+"E: No paper!\n",
+
+/* 21 */
+"W: Low toner.\n",
+
+/* 22 */
+"E: No toner!\n",
+
+/* 23 */
+"E: Door open!\n",
+
+/* 24 */
+"E: Jammed!\n",
+
+/* 25 */
+"E: Offline!\n",
+
+/* 26 */
+"W: Service requested.\n",
+
+/* 27 */
+"E: Input tray missing!\n",
+
+/* 28 */
+"E: Output tray missing!\n",
+
+/* 29 */
+"E: Marker supply missing!\n",
+
+/* 30 */
+"W: Output near full.\n",
+
+/* 31 */
+"E: Output full!\n",
+
+/* 32 */
+"W: Input tray empty.\n",
+
+/* 33 */
+"W: Overdue preventive maintenance.\n",
+
+/* 34 */
+"# ",
+
+/* 35 */
+"UNREACHABLE!\n",
+
+/* 36 */
+": ERROR: Failed to create SNMP request PDU!\n",
+
+/* 37 */
+": Warning: SNMP version configured multiple times!\n",
+
+/* 38 */
+": ERROR: Illegal SNMP version: \"",
+
+/* 39 */
+"\"!\n",
+
+/* 40 */
+": Warning: SNMP community configured multiple times!\n",
+
+/* 41 */
+": Warning: Host name configured multiple times!\n",
+
+/* 42 */
+": ERROR: Missing host name!\n",
+
+/* 43 */
+": ERROR: Failed to open SNMP session!\n",
+
+/* 44 */
+": ERROR: Failed to restore signal handlers!\n",
+
+/* 45 */
+": ERROR: Failed to set up signal handlers!\n",
+
+NULL
+
+
+#line 152 "prmonsnmp.ctr"
+};
+
+
+
+#if DK4_HAVE_LIBNETSNMP && ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET))
+
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/utilities.h>
+#include <net-snmp/library/snmp_logging.h>
+
+#include "dk4mem.h"
+#include "dk4str8.h"
+#include "dk4mai8dus.h"
+#include "dk4time.h"
+#include "dk4time08.h"
+#include "dk4sock.h"
+#include "dk4maasz.h"
+#include "dk4mai8dii.h"
+#include "dk4mai8ddu.h"
+#include "dk4mao8d.h"
+#include "dk4mao8h.h"
+#include "dk4enc.h"
+#include "dk4loc.h"
+#include "dk4vers.h"
+
+
+
+
+
+#line 181 "prmonsnmp.ctr"
+
+
+
+/** Status text from SNMP response.
+*/
+static char statext[1024];
+
+
+
+/** Previous status text.
+*/
+static char ostatext[sizeof(statext)];
+
+
+
+/** Long option names.
+*/
+static const char * const long_options[] = {
+/* 0 */
+"help",
+
+/* 1 */
+"version",
+
+/* 2 */
+"license",
+
+NULL
+
+
+#line 204 "prmonsnmp.ctr"
+};
+
+
+
+/** OID for device status.
+*/
+static const oid prmonsnmp_oid_ds[] = {
+ (oid)1, (oid)3, (oid)6, (oid)1, (oid)2, (oid)1,
+ (oid)25, (oid)3, (oid)2, (oid)1, (oid)5, (oid)1
+};
+
+/** Size of device status OID (number of elements).
+*/
+static size_t const pjsnmp_sz_oid_ds = sizeof(prmonsnmp_oid_ds)/sizeof(oid);
+
+/** Size of device status OID (number of bytes).
+*/
+static size_t const pjsnmp_bytes_oid_ds = sizeof(prmonsnmp_oid_ds);
+
+
+/** OID for printer status.
+*/
+static const oid prmonsnmp_oid_ps[] = {
+ (oid)1, (oid)3, (oid)6, (oid)1, (oid)2, (oid)1,
+ (oid)25, (oid)3, (oid)5, (oid)1, (oid)1, (oid)1
+};
+
+/** Size of printer status OID (number of elements).
+*/
+static size_t const pjsnmp_sz_oid_ps = sizeof(prmonsnmp_oid_ps)/sizeof(oid);
+
+/** Size of printer status OID (number of bytes).
+*/
+static size_t const pjsnmp_bytes_oid_ps = sizeof(prmonsnmp_oid_ps);
+
+
+/** OID for pagecount value.
+*/
+static const oid prmonsnmp_oid_pc[] = {
+ (oid)1, (oid)3, (oid)6, (oid)1, (oid)2, (oid)1,
+ (oid)43, (oid)10, (oid)2, (oid)1, (oid)4, (oid)1, (oid)1
+};
+
+/** Size of page counter OID (number of elements).
+*/
+static size_t const pjsnmp_sz_oid_pc = sizeof(prmonsnmp_oid_pc)/sizeof(oid);
+
+/** Size of page counter OID (number of bytes).
+*/
+static size_t const pjsnmp_bytes_oid_pc = sizeof(prmonsnmp_oid_pc);
+
+
+/** Printer error OID.
+*/
+static const oid prmonsnmp_oid_pe[] = {
+ (oid)1, (oid)3, (oid)6, (oid)1, (oid)2, (oid)1,
+ (oid)25, (oid)3, (oid)5, (oid)1, (oid)2, (oid)1
+};
+
+/** Size of printer error OID (number of elements).
+*/
+static size_t const pjsnmp_sz_oid_pe = sizeof(prmonsnmp_oid_pe)/sizeof(oid);
+
+/** Size of printer error OID (number of bytes).
+*/
+static size_t const pjsnmp_bytes_oid_pe = sizeof(prmonsnmp_oid_pe);
+
+/** Status text OID.
+*/
+static const oid prmonsnmp_oid_st[] = {
+ (oid)1, (oid)3, (oid)6, (oid)1, (oid)2, (oid)1,
+ (oid)43, (oid)16, (oid)5, (oid)1, (oid)2, (oid)1, (oid)1
+};
+
+/** Size of printer error OID (number of elements).
+*/
+static size_t const pjsnmp_sz_oid_st = sizeof(prmonsnmp_oid_st)/sizeof(oid);
+
+/** Size of printer error OID (number of bytes).
+*/
+static size_t const pjsnmp_bytes_oid_st = sizeof(prmonsnmp_oid_st);
+
+
+
+/** Help text.
+*/
+static const char * const help_text[] = {
+"",
+"Monitor printers",
+"",
+"prmonsnmp [-v version] [-c community] [-t seconds] [-n] host",
+"",
+"Options:",
+"-v version\t\tSNMP version: 1, 2c, 2 (same as 2c), 3, default: 1.",
+"-c community\t\tSNMP community name, default: public.",
+"-t seconds\t\tDuration for monitoring, default: 0 (endless).",
+"-n\t\t\tNo 250 ms grace period between requests.",
+"",
+"--help\t\t\tShow this help text.",
+"--version\t\tShow version number.",
+"--license\t\tShow license information.",
+"",
+NULL
+
+
+#line 308 "prmonsnmp.ctr"
+};
+
+
+
+/** License conditions text.
+*/
+static const char * const license_text[] = {
+"",
+"This software uses code from the following projects, either directly or as",
+"a library:",
+"",
+"dktools\t\tDirk Krause's tools and libraries.",
+"\t\tSee http://dktools.sourceforge.net/ for more information.",
+#if DK4_HAVE_LIBNETSNMP
+"Net-SNMP\tSNMP access library.",
+"\t\tSee http://net-snmp.sourceforge.net/ for more information.",
+#endif
+#if DK4_HAVE_ZLIB_H
+"",
+"zlib\t\tData compression library.",
+"\t\tSee http://www.zlib.net/ for more information.",
+#endif
+#if DK4_HAVE_OPENSSL_MD5_H && DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_OPENSSL_RIPEMD_H
+"",
+"OpenSSL\t\tCryptographic toolkit, used to build file checksums here.",
+"\t\tSee http://www.openssl.org/ for more information.",
+"",
+"This product includes software developed by the OpenSSL Project for use in",
+"the OpenSSL Toolkit (http://www.openssl.org/).",
+"This product includes cryptographic software written by",
+"Eric Young (eay@cryptsoft.com).",
+"This product includes software written by Tim Hudson (tjh@cryptsoft.com).",
+#endif
+"",
+"All the licenses below apply to the program.",
+"Licenses for used libraries are shown as found on my Scientific Linux 6.x",
+"computer in the /usr/share/doc directory on 2015-04-01. Check the project",
+"homepages of the used libraries for additional information and/or updated",
+"license terms.",
+"",
+"",
+"DK tools and libraries license",
+"==============================",
+"Copyright (c) 2015-2016, Dirk Krause",
+"All rights reserved.",
+"",
+"Redistribution and use in source and binary forms, with or without",
+"modification, are permitted provided that the following conditions are met:",
+"",
+"* Redistributions of source code must retain the above copyright notice,",
+" this list of conditions and the following disclaimer.",
+"* Redistributions in binary form must reproduce the above copyright",
+" notice, this list of conditions and the following disclaimer in the",
+" documentation and/or other materials provided with the distribution.",
+"* Neither the name of the Dirk Krause nor the names of contributors may be",
+" used to endorse or promote products derived from this software without",
+" specific prior written permission.",
+"",
+"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"",
+"AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE",
+"IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE",
+"ARE DISCLAIMED.",
+"",
+"IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,",
+"INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,",
+"BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,",
+"DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY",
+"OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING",
+"NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,",
+"EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.",
+#if DK4_HAVE_LIBNETSNMP
+"",
+"",
+"Net-SNMP license",
+"================",
+"Various copyrights apply to this package, listed in various separate parts",
+"below. Please make sure that you read all the parts. Up until 2001,",
+"the project was based at UC Davis, and the first part covers all code",
+"written during this time. From 2001 onwards, the project has been",
+"based at SourceForge, and Networks Associates Technology, Inc hold the",
+"copyright on behalf of the wider Net-SNMP community, covering all",
+"derivative work done since then. An additional copyright section has",
+"been added as Part 3 below also under a BSD license for the work",
+"contributed by Cambridge Broadband Ltd. to the project since 2001.",
+"An additional copyright section has been added as Part 4 below also",
+"under a BSD license for the work contributed by Sun Microsystems, Inc.",
+"to the project since 2003.",
+"",
+"Code has been contributed to this project by many people over",
+"the years it has been in development, and a full list of contributors",
+"can be found in the README file under the THANKS section.",
+"",
+"",
+"---- Part 1: CMU/UCD copyright notice: (BSD like) -----",
+"",
+"",
+" Copyright 1989, 1991, 1992 by Carnegie Mellon University",
+"",
+"\t\t Derivative Work - 1996, 1998-2000",
+"Copyright 1996, 1998-2000 The Regents of the University of California",
+"",
+"\t\t\t All Rights Reserved",
+"",
+"Permission to use, copy, modify and distribute this software and its",
+"documentation for any purpose and without fee is hereby granted,",
+"provided that the above copyright notice appears in all copies and",
+"that both that copyright notice and this permission notice appear in",
+"supporting documentation, and that the name of CMU and The Regents of",
+"the University of California not be used in advertising or publicity",
+"pertaining to distribution of the software without specific written",
+"permission.",
+"",
+"CMU AND THE REGENTS OF THE UNIVERSITY OF CALIFORNIA DISCLAIM ALL",
+"WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED",
+"WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL CMU OR",
+"THE REGENTS OF THE UNIVERSITY OF CALIFORNIA BE LIABLE FOR ANY SPECIAL,",
+"INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING",
+"FROM THE LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF",
+"CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN",
+"CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.",
+"",
+"",
+"---- Part 2: Networks Associates Technology, Inc copyright notice (BSD) -----",
+"",
+"Copyright (c) 2001-2003, Networks Associates Technology, Inc",
+"All rights reserved.",
+" ",
+"Redistribution and use in source and binary forms, with or without",
+"modification, are permitted provided that the following conditions are met:",
+" ",
+"* Redistributions of source code must retain the above copyright notice,",
+" this list of conditions and the following disclaimer.",
+" ",
+"* Redistributions in binary form must reproduce the above copyright",
+" notice, this list of conditions and the following disclaimer in the",
+" documentation and/or other materials provided with the distribution.",
+" ",
+"* Neither the name of the Networks Associates Technology, Inc nor the",
+" names of its contributors may be used to endorse or promote",
+" products derived from this software without specific prior written",
+" permission.",
+" ",
+"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS",
+"IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,",
+"THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR",
+"PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR",
+"CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,",
+"EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,",
+"PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;",
+"OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,",
+"WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR",
+"OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF",
+"ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.",
+"",
+"---- Part 3: Cambridge Broadband Ltd. copyright notice (BSD) -----",
+"",
+"Portions of this code are copyright (c) 2001-2003, Cambridge Broadband Ltd.",
+"All rights reserved.",
+" ",
+"Redistribution and use in source and binary forms, with or without",
+"modification, are permitted provided that the following conditions are met:",
+" ",
+"* Redistributions of source code must retain the above copyright notice,",
+" this list of conditions and the following disclaimer.",
+" ",
+"* Redistributions in binary form must reproduce the above copyright",
+" notice, this list of conditions and the following disclaimer in the",
+" documentation and/or other materials provided with the distribution.",
+" ",
+"* The name of Cambridge Broadband Ltd. may not be used to endorse or",
+" promote products derived from this software without specific prior",
+" written permission.",
+" ",
+"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY",
+"EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE",
+"IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR",
+"PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE",
+"LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR",
+"CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF",
+"SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR",
+"BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,",
+"WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE",
+"OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN",
+"IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.",
+"",
+"",
+"---- Part 4: Sun Microsystems, Inc. copyright notice (BSD) -----",
+"",
+"Copyright © 2003 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, ",
+"California 95054, U.S.A. All rights reserved.",
+"",
+"Use is subject to license terms below.",
+"",
+"This distribution may include materials developed by third parties.",
+"",
+"Sun, Sun Microsystems, the Sun logo and Solaris are trademarks or registered ",
+"trademarks of Sun Microsystems, Inc. in the U.S. and other countries.",
+"",
+"Redistribution and use in source and binary forms, with or without",
+"modification, are permitted provided that the following conditions are met:",
+"",
+"* Redistributions of source code must retain the above copyright notice,",
+" this list of conditions and the following disclaimer.",
+"",
+"* Redistributions in binary form must reproduce the above copyright",
+" notice, this list of conditions and the following disclaimer in the",
+" documentation and/or other materials provided with the distribution.",
+"",
+"* Neither the name of the Sun Microsystems, Inc. nor the",
+" names of its contributors may be used to endorse or promote",
+" products derived from this software without specific prior written",
+" permission.",
+"",
+"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS",
+"IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,",
+"THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR",
+"PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR",
+"CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,",
+"EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,",
+"PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;",
+"OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,",
+"WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR",
+"OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF",
+"ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.",
+"",
+"---- Part 5: Sparta, Inc copyright notice (BSD) -----",
+"",
+"Copyright (c) 2003-2006, Sparta, Inc",
+"All rights reserved.",
+" ",
+"Redistribution and use in source and binary forms, with or without",
+"modification, are permitted provided that the following conditions are met:",
+" ",
+"* Redistributions of source code must retain the above copyright notice,",
+" this list of conditions and the following disclaimer.",
+" ",
+"* Redistributions in binary form must reproduce the above copyright",
+" notice, this list of conditions and the following disclaimer in the",
+" documentation and/or other materials provided with the distribution.",
+" ",
+"* Neither the name of Sparta, Inc nor the names of its contributors may",
+" be used to endorse or promote products derived from this software",
+" without specific prior written permission.",
+" ",
+"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS",
+"IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,",
+"THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR",
+"PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR",
+"CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,",
+"EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,",
+"PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;",
+"OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,",
+"WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR",
+"OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF",
+"ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.",
+"",
+"---- Part 6: Cisco/BUPTNIC copyright notice (BSD) -----",
+"",
+"Copyright (c) 2004, Cisco, Inc and Information Network",
+"Center of Beijing University of Posts and Telecommunications.",
+"All rights reserved.",
+" ",
+"Redistribution and use in source and binary forms, with or without",
+"modification, are permitted provided that the following conditions are met:",
+" ",
+"* Redistributions of source code must retain the above copyright notice,",
+" this list of conditions and the following disclaimer.",
+" ",
+"* Redistributions in binary form must reproduce the above copyright",
+" notice, this list of conditions and the following disclaimer in the",
+" documentation and/or other materials provided with the distribution.",
+" ",
+"* Neither the name of Cisco, Inc, Beijing University of Posts and",
+" Telecommunications, nor the names of their contributors may",
+" be used to endorse or promote products derived from this software",
+" without specific prior written permission.",
+" ",
+"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS",
+"IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,",
+"THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR",
+"PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR",
+"CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,",
+"EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,",
+"PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;",
+"OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,",
+"WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR",
+"OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF",
+"ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.",
+"",
+"---- Part 7: Fabasoft R&D Software GmbH & Co KG copyright notice (BSD) -----",
+"",
+"Copyright (c) Fabasoft R&D Software GmbH & Co KG, 2003",
+"oss@fabasoft.com",
+"Author: Bernhard Penz <bernhard.penz@fabasoft.com>",
+"",
+"Redistribution and use in source and binary forms, with or without",
+"modification, are permitted provided that the following conditions are met:",
+"",
+"* Redistributions of source code must retain the above copyright notice,",
+" this list of conditions and the following disclaimer.",
+"",
+"* Redistributions in binary form must reproduce the above copyright",
+" notice, this list of conditions and the following disclaimer in the",
+" documentation and/or other materials provided with the distribution.",
+"",
+"* The name of Fabasoft R&D Software GmbH & Co KG or any of its subsidiaries, ",
+" brand or product names may not be used to endorse or promote products ",
+" derived from this software without specific prior written permission.",
+"",
+"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY",
+"EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE",
+"IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR",
+"PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE",
+"LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR",
+"CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF",
+"SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR",
+"BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,",
+"WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE",
+"OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN",
+"IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.",
+#endif
+#if DK4_HAVE_ZLIB_H
+"",
+"",
+"Zlib license",
+"============",
+"(C) 1995-2004 Jean-loup Gailly and Mark Adler",
+"",
+"This software is provided 'as-is', without any express or implied",
+"warranty. In no event will the authors be held liable for any damages",
+"arising from the use of this software.",
+"",
+"Permission is granted to anyone to use this software for any purpose,",
+"including commercial applications, and to alter it and redistribute it",
+"freely, subject to the following restrictions:",
+"",
+"1. The origin of this software must not be misrepresented; you must not",
+" claim that you wrote the original software. If you use this software",
+" in a product, an acknowledgment in the product documentation would be",
+" appreciated but is not required.",
+"2. Altered source versions must be plainly marked as such, and must not be",
+" misrepresented as being the original software.",
+"3. This notice may not be removed or altered from any source distribution.",
+"",
+"Jean-loup Gailly Mark Adler",
+"jloup@gzip.org madler@alumni.caltech.edu",
+#endif
+#if DK4_HAVE_BZLIB_H
+"",
+"",
+"Bzip2 and libbzip2 library license",
+"==================================",
+"This program, \"bzip2\", the associated library \"libbzip2\", and all",
+"documentation, are copyright (C) 1996-2007 Julian R Seward. All",
+"rights reserved.",
+"",
+"Redistribution and use in source and binary forms, with or without",
+"modification, are permitted provided that the following conditions",
+"are met:",
+"",
+"1. Redistributions of source code must retain the above copyright",
+" notice, this list of conditions and the following disclaimer.",
+"",
+"2. The origin of this software must not be misrepresented; you must ",
+" not claim that you wrote the original software. If you use this ",
+" software in a product, an acknowledgment in the product ",
+" documentation would be appreciated but is not required.",
+"",
+"3. Altered source versions must be plainly marked as such, and must",
+" not be misrepresented as being the original software.",
+"",
+"4. The name of the author may not be used to endorse or promote ",
+" products derived from this software without specific prior written ",
+" permission.",
+"",
+"THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS",
+"OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED",
+"WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE",
+"ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY",
+"DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL",
+"DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE",
+"GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS",
+"INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,",
+"WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING",
+"NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS",
+"SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.",
+"",
+"Julian Seward, jseward@bzip.org",
+"bzip2/libbzip2 version 1.0.5 of 10 December 2007",
+#endif
+#if DK4_HAVE_OPENSSL_MD5_H && DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_OPENSSL_RIPEMD_H
+"",
+"",
+"OpenSSL license",
+"===============",
+"",
+"LICENSE ISSUES",
+"--------------",
+"",
+"The OpenSSL toolkit stays under a dual license, i.e. both the conditions of",
+"the OpenSSL License and the original SSLeay license apply to the toolkit.",
+"See below for the actual license texts. Actually both licenses are BSD-style",
+"Open Source licenses. In case of any license issues related to OpenSSL",
+"please contact openssl-core@openssl.org.",
+"",
+"OpenSSL License",
+"---------------",
+"",
+"Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved.",
+"",
+"Redistribution and use in source and binary forms, with or without",
+"modification, are permitted provided that the following conditions",
+"are met:",
+"",
+"1. Redistributions of source code must retain the above copyright",
+" notice, this list of conditions and the following disclaimer. ",
+"",
+"2. Redistributions in binary form must reproduce the above copyright",
+" notice, this list of conditions and the following disclaimer in",
+" the documentation and/or other materials provided with the",
+" distribution.",
+"",
+"3. All advertising materials mentioning features or use of this",
+" software must display the following acknowledgment:",
+" \"This product includes software developed by the OpenSSL Project",
+" for use in the OpenSSL Toolkit. (http://www.openssl.org/)\"",
+"",
+"4. The names \"OpenSSL Toolkit\" and \"OpenSSL Project\" must not be used to",
+" endorse or promote products derived from this software without",
+" prior written permission. For written permission, please contact",
+" openssl-core@openssl.org.",
+"",
+"5. Products derived from this software may not be called \"OpenSSL\"",
+" nor may \"OpenSSL\" appear in their names without prior written",
+" permission of the OpenSSL Project.",
+"",
+"6. Redistributions of any form whatsoever must retain the following",
+" acknowledgment:",
+" \"This product includes software developed by the OpenSSL Project",
+" for use in the OpenSSL Toolkit (http://www.openssl.org/)\"",
+"",
+"THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY",
+"EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE",
+"IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR",
+"PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR",
+"ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,",
+"SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT",
+"NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;",
+"LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)",
+"HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,",
+"STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)",
+"ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED",
+"OF THE POSSIBILITY OF SUCH DAMAGE.",
+"",
+"This product includes cryptographic software written by Eric Young",
+"(eay@cryptsoft.com). This product includes software written by Tim",
+"Hudson (tjh@cryptsoft.com).",
+"",
+"",
+"Original SSLeay License",
+"-----------------------",
+"",
+"Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)",
+"All rights reserved.",
+"",
+"This package is an SSL implementation written",
+"by Eric Young (eay@cryptsoft.com).",
+"The implementation was written so as to conform with Netscapes SSL.",
+"",
+"This library is free for commercial and non-commercial use as long as",
+"the following conditions are aheared to. The following conditions",
+"apply to all code found in this distribution, be it the RC4, RSA,",
+"lhash, DES, etc., code; not just the SSL code. The SSL documentation",
+"included with this distribution is covered by the same copyright terms",
+"except that the holder is Tim Hudson (tjh@cryptsoft.com).",
+"",
+"Copyright remains Eric Young's, and as such any Copyright notices in",
+"the code are not to be removed.",
+"If this package is used in a product, Eric Young should be given attribution",
+"as the author of the parts of the library used.",
+"This can be in the form of a textual message at program startup or",
+"in documentation (online or textual) provided with the package.",
+"",
+"Redistribution and use in source and binary forms, with or without",
+"modification, are permitted provided that the following conditions",
+"are met:",
+"1. Redistributions of source code must retain the copyright",
+" notice, this list of conditions and the following disclaimer.",
+"2. Redistributions in binary form must reproduce the above copyright",
+" notice, this list of conditions and the following disclaimer in the",
+" documentation and/or other materials provided with the distribution.",
+"3. All advertising materials mentioning features or use of this software",
+" must display the following acknowledgement:",
+" \"This product includes cryptographic software written by",
+" Eric Young (eay@cryptsoft.com)\"",
+" The word 'cryptographic' can be left out if the rouines from the library",
+" being used are not cryptographic related :-).",
+"4. If you include any Windows specific code (or a derivative thereof) from ",
+" the apps directory (application code) you must include an acknowledgement:",
+" \"This product includes software written by Tim Hudson (tjh@cryptsoft.com)\"",
+"",
+"THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND",
+"ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE",
+"IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE",
+"ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE",
+"FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL",
+"DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS",
+"OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)",
+"HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT",
+"LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY",
+"OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF",
+"SUCH DAMAGE.",
+"",
+"The licence and distribution terms for any publically available version or",
+"derivative of this code cannot be changed. i.e. this code cannot simply be",
+"copied and put under another distribution licence",
+"[including the GNU Public Licence.]",
+"",
+#endif
+"",
+NULL
+
+
+#line 830 "prmonsnmp.ctr"
+};
+
+
+
+/** Version information.
+*/
+static const char version_text[] = { DKT_VERSION_C8 };
+
+
+
+/** Accepted SNMP version names.
+*/
+static const char * const snmp_version_names[] = {
+/* 0 */
+"1",
+
+/* 1 */
+"2",
+
+/* 2 */
+"2c",
+
+/* 3 */
+"3",
+
+NULL
+
+
+#line 849 "prmonsnmp.ctr"
+};
+
+
+/** Host name (or IP address) of printer.
+*/
+static char *host_name = NULL;
+
+/** SNMP community name.
+*/
+static char *snmp_comm = NULL;
+
+
+/** SNMP session.
+*/
+static struct snmp_session *snmp_sess = NULL;
+
+
+/** Timeout in seconds.
+*/
+static dk4_um_t timeout = (dk4_um_t)0UL;
+
+
+/** Previous log timestamp.
+*/
+static dk4_time_t previous_log = (dk4_time_t)0UL;
+
+
+/** SNMP version.
+*/
+static long snmp_vers = SNMP_VERSION_1;
+
+/** Flag: Had a previous log.
+*/
+static int have_time = 0;
+
+
+/** Flag: Behave gracefully, max 4 SNMP requests per second.
+*/
+static int grace = 1;
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+static int encoding = DK4_ENCODING_ASCII;
+#endif
+
+/** Exit status code.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+#if DK4_HAVE_LIBNETSNMP && ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET))
+
+
+
+/** Help (1), version (2), license (4).
+*/
+static int hvl = 0;
+
+
+
+/** Pass volatile pointer.
+ @param ptr Pointer to pass through.
+ @return The original pointer.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+
+/** Check whether we can continue or must abort due to signal.
+ @param dopipe Flag: Check for SIGPIPE too.
+ @return 1 if we can continue, 0 otherwise.
+*/
+static
+int
+can_continue(int dopipe)
+{
+ int back = 1;
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_int)) { back = 0; }
+#ifdef SIGPIPE
+ if (0 != dopipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ return back;
+}
+
+
+
+/** Check two OIDs for equality.
+ @param pl Left OID.
+ @param szl Left OID size.
+ @param pr Right OID.
+ @param szr Right OID size.
+ @return 1 for equal OIDs, 0 otherwise.
+*/
+static
+int
+oids_equal(const oid *pl, size_t szl, const oid *pr, size_t szr)
+{
+#if VERSION_BEFORE_20160206
+ size_t i;
+#endif
+ int back = 0;
+
+ if (szl == szr) {
+#if VERSION_BEFORE_20160206
+ back = 1;
+ for (i = 0; ((i < szl) && (1 == back)); i++) {
+ if (pl[i] != pr[i]) {
+ back = 0;
+ }
+ }
+#else
+ if (0 == dk4mem_cmp(pl, pr, (szl * sizeof(oid)), NULL)) {
+ back = 1;
+ }
+#endif
+ }
+ return back;
+}
+
+
+/** Find OID index.
+ @param oid Pointer to OID to check.
+ @param sz OID size.
+ @return 0 for hrDeviceStatus, 1 for hrPrinterStatus,
+ 2 for page counter, 3 for hrPrinterDetectedErrorState,
+ 4 for prtMarkerLifeCount, -1 otherwise.
+*/
+static
+int
+oid_index(oid *p, size_t sz)
+{
+ int back = -1;
+ if (0 != oids_equal(p, sz, prmonsnmp_oid_ds, pjsnmp_sz_oid_ds)) {
+ back = 0;
+ } else {
+ if (0 != oids_equal(p, sz, prmonsnmp_oid_ps, pjsnmp_sz_oid_ps)) {
+ back = 1;
+ } else {
+ if (0 != oids_equal(p, sz, prmonsnmp_oid_pe, pjsnmp_sz_oid_pe)) {
+ back = 2;
+ } else {
+ if (0 != oids_equal(p, sz, prmonsnmp_oid_st, pjsnmp_sz_oid_st)) {
+ back = 3;
+ } else {
+ if (0 != oids_equal(p, sz, prmonsnmp_oid_pc, pjsnmp_sz_oid_pc)) {
+ back = 4;
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+/** Retrieve integer value from variable list.
+ @param iptr Address of variable to set.
+ @param var SNMP variable containing the value.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+get_int(int *iptr, struct variable_list *var)
+{
+ char bu[64]; /* Buffer for text data copy */
+ const char *endptr = NULL; /* End of used data in numeric conversion */
+ long l; /* Long value from SNMP response */
+ int i; /* Text to number conversion result */
+ int back = 0;
+
+
+#line 1099 "prmonsnmp.ctr"
+ switch (var->type) {
+ case ASN_OCTET_STR : {
+
+#line 1101 "prmonsnmp.ctr"
+ if ((var->val_len > 0) && (var->val_len < sizeof(bu))) {
+ dk4mem_cpy(bu, (void *)((var->val).string), var->val_len, NULL);
+ bu[var->val_len] = '\0';
+ if (0 != dk4ma_input_c8_dec_int(&i, bu, &endptr, 1, NULL)) {
+ *iptr = i;
+ back = 1;
+ }
+ }
+ } break;
+ case ASN_TIMETICKS :
+ case ASN_GAUGE :
+ case ASN_COUNTER :
+ case ASN_INTEGER : {
+
+#line 1114 "prmonsnmp.ctr"
+ l = *((var->val).integer);
+ *iptr = (int)l;
+ back = 1;
+ } break;
+ }
+
+
+#line 1120 "prmonsnmp.ctr"
+ return back;
+}
+
+
+/** Retrieve unsigned long value from variable list.
+ @param ulptr Address of variable to set.
+ @param var SNMP variable containing the value.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+get_ul(unsigned long *ulptr, struct variable_list *var)
+{
+ unsigned long ul = 0UL; /* Conversion result */
+ long l; /* Long result from SNMP response */
+ int back = 0;
+
+
+#line 1137 "prmonsnmp.ctr"
+ switch (var->type) {
+ case ASN_OCTET_STR : {
+
+#line 1139 "prmonsnmp.ctr"
+ if (0 < var->val_len) {
+ ul |=
+ ((((unsigned long)(((var->val).string)[0])) << 24) & 0xFF000000UL);
+ back = 1;
+ }
+ if (1 < var->val_len) {
+ ul |=
+ ((((unsigned long)(((var->val).string)[1])) << 16) & 0x00FF0000UL);
+ }
+ if (2 < var->val_len) {
+ ul |=
+ ((((unsigned long)(((var->val).string)[2])) << 8) & 0x0000FF00UL);
+ }
+ if (3 < var->val_len) {
+ ul |=
+ ((((unsigned long)(((var->val).string)[3])) ) & 0x000000FFUL);
+ }
+ if (0 != back) {
+ *ulptr = ul;
+ }
+ } break;
+ case ASN_TIMETICKS :
+ case ASN_GAUGE :
+ case ASN_COUNTER :
+ case ASN_INTEGER : {
+
+#line 1164 "prmonsnmp.ctr"
+ l = *((var->val).integer);
+ if (0L <= l) {
+ *ulptr = (unsigned long)l;
+ back = 1;
+ }
+ } break;
+ }
+
+
+#line 1172 "prmonsnmp.ctr"
+ return back;
+}
+
+
+
+/** Check whether a text buffer contains non-ASCII bytes.
+ @param ptr Buffer start address.
+ @param i Buffer size.
+ @return 1 if non-ASCII found, 0 for ASCII only.
+*/
+static
+int
+contains_non_ascii(const unsigned char *ptr, size_t i)
+{
+ int back = 0;
+ while ((0 == back) && (0 < i)) {
+ if (0x7F < *(ptr++)) {
+ back = 1;
+ }
+ i--;
+ }
+ return back;
+}
+
+
+
+/** Log current timestamp.
+*/
+static
+void
+log_timestamp(void)
+{
+ char buf[64]; /* Text representation of timestamp */
+ dk4_time_t current; /* Current time */
+ int res; /* Conversion operation result */
+
+ dk4time_get(&current);
+ if ((0 == have_time) || (current != previous_log)) {
+ res = dk4time_as_text_c8(buf, sizeof(buf), &current, NULL);
+ if (0 != res) {
+ if (0 != have_time) {
+ fputc('\n', stdout);
+ }
+ fputs(prmonsnmp_kw[34], stdout);
+ fputs(buf, stdout);
+ fputc('\n', stdout);
+ }
+ } else {
+ if (0 != have_time) {
+ fputc('\n', stdout);
+ }
+ }
+ have_time = 1;
+ previous_log = current;
+}
+
+
+
+/** Show text, convert non-ASCII to question marks.
+ @param str String to show.
+ @param sz Text length.
+*/
+static
+void
+show_as_ascii(const unsigned char *str, size_t sz)
+{
+ while (0 < sz--) {
+ if (0x7F < *str) {
+ fputc('?', stdout);
+ } else {
+ fputc(*str, stdout);
+ }
+ str++;
+ }
+}
+
+
+
+/** The main loop sending SNMP requests and printing
+ responses to standard output.
+*/
+static
+void
+run_main_loop(void)
+{
+ char nb[64]; /* Buffer for hex representation */
+ struct timeval to; /* Timeout for select */
+ struct snmp_pdu *rq; /* Request */
+ struct snmp_pdu *rs; /* Response */
+ struct variable_list *vars; /* Current variable to process */
+ unsigned char *uptr; /* Traverse text */
+ dk4_time_t start_time; /* Start time */
+ dk4_time_t timeout_time; /* First timeout seen */
+ dk4_time_t current_time; /* Current time */
+ unsigned long cond = 0UL; /* Printer detected error */
+ unsigned long ocond = 0UL; /* Previous printer det err */
+ unsigned long tcond = 0UL; /* Current conditions */
+ unsigned long opcnt = 0UL; /* Previous page count */
+ unsigned long ul; /* unsigned long from current var */
+ unsigned long pcnt; /* Page count */
+ size_t lst; /* Status text length */
+ size_t olst; /* Previous status text length */
+ int i; /* Traverse bits in pr det err st */
+ int found; /* Summary: Which information found */
+ int must_show; /* Must show changed values */
+ int must_flush; /* Must flush standard output */
+ int status; /* SNMP response status */
+ int res; /* Operation result */
+ int cc = 1; /* Flag: Can continue */
+ int devst = 0; /* Device status */
+ int prist = 0; /* Printer status */
+ int unreach = 0; /* Flag: Unreachable */
+ int odevst = 0; /* Previous device status */
+ int oprist = 0; /* Previous printer status */
+ int ounreach = 0; /* Previous unreach flag */
+
+ dk4time_get(&start_time);
+ timeout_time = (dk4_time_t)0UL;
+ if ((dk4_um_t)0UL < timeout) {
+ timeout_time = start_time + (dk4_time_t)timeout;
+ }
+ cc = 1;
+ statext[0] = '\0';
+ ostatext[0] = '\0';
+ olst = 0;
+ do {
+ pcnt = 0UL;
+ unreach = 1;
+ devst = 0;
+ prist = 0;
+ found = 0;
+ cond = 0UL;
+ statext[0] = '\0';
+ rs = NULL;
+ lst = 0;
+ must_show = 0;
+
+#line 1308 "prmonsnmp.ctr"
+ must_flush = 0;
+ if (0 != can_continue(0)) {
+ rq = snmp_pdu_create(SNMP_MSG_GET);
+ if (NULL != rq) {
+ snmp_add_null_var(rq, prmonsnmp_oid_ds, pjsnmp_sz_oid_ds);
+ snmp_add_null_var(rq, prmonsnmp_oid_ps, pjsnmp_sz_oid_ps);
+ snmp_add_null_var(rq, prmonsnmp_oid_pe, pjsnmp_sz_oid_pe);
+ snmp_add_null_var(rq, prmonsnmp_oid_st, pjsnmp_sz_oid_st);
+ snmp_add_null_var(rq, prmonsnmp_oid_pc, pjsnmp_sz_oid_pc);
+ status = snmp_synch_response(snmp_sess, rq, &rs);
+ if (STAT_SUCCESS == status) {
+ if (NULL != rs) {
+ if (SNMP_ERR_NOERROR == rs->errstat) {
+ unreach = 0;
+ vars = rs->variables;
+ while (NULL != vars) {
+ switch (oid_index(vars->name, vars->name_length)) {
+ case 0: {
+ i = 0;
+ if (0 != get_int(&i, vars)) {
+ devst = i;
+ found |= 1;
+ }
+ } break;
+ case 1: {
+ i = 0;
+ if (0 != get_int(&i, vars)) {
+ prist = i;
+ found |= 2;
+ }
+ } break;
+ case 2: {
+ ul = 0UL;
+ if (0 != get_ul(&ul, vars)) {
+ cond = ul;
+ found |= 4;
+ }
+ } break;
+ case 3: {
+ if ((0 < vars->val_len)&&(sizeof(statext) > vars->val_len))
+ {
+ dk4mem_cpy(statext,(vars->val).string,vars->val_len,NULL);
+ statext[vars->val_len] = '\0';
+ lst = vars->val_len;
+ found |= 8;
+ }
+ } break;
+ case 4: {
+ ul = 0UL;
+ if (0 != get_ul(&ul, vars)) {
+ pcnt = ul;
+ found |= 16;
+ }
+ } break;
+ }
+ vars = vars->next_variable;
+ }
+ if (0 != (1 & found)) {
+ if (devst != odevst) {
+
+#line 1367 "prmonsnmp.ctr"
+ must_show = 1;
+ }
+ }
+ if (0 != (2 & found)) {
+ if (prist != oprist) {
+
+#line 1372 "prmonsnmp.ctr"
+ must_show = 1;
+ }
+ }
+ if (0 != (4 & found)) {
+ if (cond != ocond) {
+
+#line 1377 "prmonsnmp.ctr"
+ must_show = 1;
+ }
+ }
+ if (0 != (8 & found)) {
+ if (lst != olst) {
+
+#line 1382 "prmonsnmp.ctr"
+ must_show = 1;
+ }
+ if (0 != dk4mem_cmp(statext, ostatext, lst, NULL)) {
+
+
+#line 1386 "prmonsnmp.ctr"
+ must_show = 1;
+ }
+ }
+ if (0 != (16 & found)) {
+ if (pcnt != opcnt) {
+ must_show = 1;
+ }
+ }
+ if (0 != must_show) {
+ log_timestamp();
+ must_flush = 1;
+ if ((0 != (1 & found)) && (0 <= devst) && (5 >= devst)) {
+ fputs(prmonsnmp_kw[4 + devst], stdout);
+ }
+ if ((0 != (2 & found)) && (0 <= prist) && (5 >= prist)) {
+ fputs(prmonsnmp_kw[17], stdout);
+ fputs(prmonsnmp_kw[10 + prist], stdout);
+ }
+ if (0 != (4 & found)) {
+ fputs(prmonsnmp_kw[18], stdout);
+ tcond = 0x80000000UL;
+ for (i = 0; i < 16; i++) {
+ if ((0 < i) && (0 == (i % 4))) {
+ fputc('-', stdout);
+ }
+ fputc(((0UL != (tcond & cond)) ? '1' : '0'), stdout);
+ tcond = tcond / 2UL;
+ }
+ }
+ if (0 != (16 & found)) {
+ res = dk4ma_write_c8_decimal_unsigned(
+ nb, sizeof(nb), (dk4_um_t)pcnt, 0, NULL
+ );
+ if (0 != res) {
+ fputs(prmonsnmp_kw[18], stdout);
+ fputs(nb, stdout);
+ }
+ }
+ fputc('\n', stdout);
+ if (0 != (4 & found)) {
+ tcond = 0x80000000UL;
+ for (i = 0; i < 15; i++) {
+ if (0UL != (cond & tcond)) {
+ fputs(prmonsnmp_kw[19 + i], stdout);
+ }
+ tcond = tcond / 2UL;
+ }
+ }
+ if (0 != (8 & found)) {
+ if (0 < lst) {
+ uptr = (unsigned char *)statext;
+ for (i = 0; i < lst; i++) {
+ if (0 < i) {
+ if (0 == (i % 24)) {
+ fputc('\n', stdout);
+ } else {
+ fputc(' ', stdout);
+ }
+ }
+ res = dk4ma_write_c8_hex_unsigned(
+ nb, sizeof(nb), (dk4_um_t)(*(uptr++)), 2, NULL
+ );
+ if (0 != res) {
+ fputs(nb, stdout);
+ }
+ }
+ fputc('\n', stdout);
+ fputc('"', stdout);
+ if (0 == contains_non_ascii((unsigned char *)statext,lst)) {
+ fwrite(statext, 1, lst, stdout);
+ } else {
+ show_as_ascii((unsigned char *)statext, lst);
+ }
+ fputc('"', stdout);
+ fputc('\n', stdout);
+ }
+ }
+ }
+ }
+ }
+ }
+ if (NULL != rs) {
+ snmp_free_pdu(rs);
+ }
+ if (unreach != ounreach) {
+ log_timestamp();
+ fputs(prmonsnmp_kw[35], stdout);
+ must_flush = 1;
+ }
+ ounreach = unreach;
+ odevst = devst;
+ oprist = prist;
+ ocond = cond;
+ olst = lst;
+ opcnt = pcnt;
+ strcpy(ostatext, statext);
+ } else {
+ cc = -1;
+ exval = EXIT_FAILURE;
+ /* ERROR: Failed to create request PDU */
+ fputs(prmonsnmp_kw[2], stderr);
+ fputs(prmonsnmp_kw[36], stderr);
+ fflush(stderr);
+ }
+ if (0 != must_flush) {
+ fflush(stdout);
+ }
+ } else {
+ cc = -1;
+ }
+ if (1 == cc) {
+ if ((dk4_time_t)0UL < timeout_time) {
+ dk4time_get(&current_time);
+ if (current_time > timeout_time) {
+ cc = 0;
+ }
+ }
+ }
+ if (1 == cc) {
+ if (0 != grace) {
+ to.tv_sec = 0L;
+ to.tv_usec = 250000L;
+ select(0, NULL, NULL, NULL, &to);
+ }
+ }
+ } while (1 == cc);
+}
+
+
+
+/** Set SNMP version.
+ @param name SNMP version name as text.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+set_snmp_version(const char *name)
+{
+ int back = 0;
+ switch (dk4str8_array_index(snmp_version_names, name, 0)) {
+ case 0: {
+ back = 1;
+ snmp_vers = SNMP_VERSION_1;
+ } break;
+ case 1: case 2: {
+ back = 1;
+ snmp_vers = SNMP_VERSION_2c;
+ } break;
+ case 3: {
+ back = 1;
+ snmp_vers = SNMP_VERSION_3;
+ } break;
+ }
+ return back;
+}
+
+
+
+/** Process command line arguments.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+process_command_line_arguments(int argc, char *argv[])
+{
+ char **lfdarg; /* Traverse cmd line arguments */
+ char *curarg; /* Current cmd line argument */
+ const char *ep; /* End of used data in conversion */
+ dk4_um_t um; /* Conversion result */
+ int i; /* Cmd line args still remaining */
+ int have_vers = 0; /* Flag: Have SNMP version */
+ int back = 1; /* Function result */
+ int res; /* Conversion result */
+
+ lfdarg = argv; i = argc;
+ lfdarg++; i--;
+ while (0 < i) {
+ curarg = *lfdarg;
+ if ('-' == *curarg) {
+ curarg++;
+ switch (*curarg) {
+ case '-' : {
+ curarg++;
+ switch ( dk4str8_array_index(long_options, curarg, 0) ) {
+ case 0: {
+ hvl |= 1;
+ } break;
+ case 1: {
+ hvl |= 2;
+ } break;
+ case 2: {
+ hvl |= 4;
+ } break;
+ }
+ } break;
+ case 'n' : {
+ grace = 0;
+ } break;
+ case 'v' : {
+ if (0 != have_vers) {
+ /* WARNING: Version redefined */
+ fputs(prmonsnmp_kw[2], stderr);
+ fputs(prmonsnmp_kw[37], stderr);
+ fflush(stderr);
+ }
+ have_vers = 1;
+ curarg++; curarg = dk4str8_start(curarg, NULL);
+ if (NULL == curarg) {
+ lfdarg++; i--;
+ if (0 < i) { curarg = *lfdarg; }
+ }
+ if (NULL != curarg) {
+ if (0 == set_snmp_version(curarg)) {
+ /* WARNING: Illegal SNMP version */
+ fputs(prmonsnmp_kw[2], stderr);
+ fputs(prmonsnmp_kw[38], stderr);
+ fputs(curarg, stderr);
+ fputs(prmonsnmp_kw[39], stderr);
+ fflush(stderr);
+ back = 0;
+ }
+ } else {
+ back = 0;
+ }
+ } break;
+ case 'c' : {
+ curarg++; curarg = dk4str8_start(curarg, NULL);
+ if (NULL == curarg) {
+ lfdarg++; i--;
+ if (0 < i) { curarg = *lfdarg; }
+ }
+ if (NULL != curarg) {
+ if (NULL != snmp_comm) {
+ /* WARNING: Community redefined */
+ fputs(prmonsnmp_kw[2], stderr);
+ fputs(prmonsnmp_kw[40], stderr);
+ fflush(stderr);
+ }
+ snmp_comm = curarg;
+ } else {
+ back = 0;
+ }
+ } break;
+ case 't' : {
+ curarg++; curarg = dk4str8_start(curarg, NULL);
+ if (NULL == curarg) {
+ lfdarg++; i--;
+ if (0 < i) { curarg = *lfdarg; }
+ }
+ if (NULL != curarg) {
+ ep = NULL;
+ res = dk4ma_input_c8_dec_dk4_um_t(&um, curarg, &ep, 1, NULL);
+ if (0 != res) {
+ timeout = um;
+ } else {
+ back = 0;
+ }
+ } else {
+ back = 0;
+ }
+ } break;
+ }
+ } else {
+ if (NULL != host_name) {
+ /* WARNING: Host name redefined */
+ fputs(prmonsnmp_kw[2], stderr);
+ fputs(prmonsnmp_kw[41], stderr);
+ fflush(stderr);
+ }
+ host_name = curarg;
+ }
+ if (0 < i) { lfdarg++; i--; }
+ }
+ if ((0 == hvl) && (NULL == host_name)) {
+ /* ERROR: Missing host name */
+ fputs(prmonsnmp_kw[2], stderr);
+ fputs(prmonsnmp_kw[42], stderr);
+ fflush(stderr);
+ back = 0;
+ }
+ return back;
+}
+
+
+/** Show a text paragraph on standard output.
+ @param txt Text to show.
+*/
+static
+void
+show_text(const char * const *txt)
+{
+ if (NULL != txt) {
+ while (NULL != *txt) {
+ fputs(*(txt++), stdout);
+ fputc('\n', stdout);
+ }
+ fflush(stdout);
+ }
+}
+
+
+
+/** Handle --help, --version, --license options.
+*/
+static
+void
+run_hvl(void)
+{
+
+
+#line 1697 "prmonsnmp.ctr"
+ if (0 != (1 & hvl)) {
+ show_text(help_text);
+ }
+ if (0 != (2 & hvl)) {
+ fputs(version_text, stdout);
+ fputc('\n', stdout);
+ fflush(stdout);
+ }
+ if (0 != (4 & hvl)) {
+ show_text(license_text);
+ }
+ exval = EXIT_SUCCESS;
+
+
+#line 1710 "prmonsnmp.ctr"
+}
+
+
+
+#endif
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+int main(int argc, char *argv[])
+{
+#if DK4_HAVE_LIBNETSNMP && ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET))
+
+ /* +++++ Required libraries available */
+ dkChar blang[32];
+ dkChar breg[32];
+ struct snmp_session template;
+#if DK4_HAVE_SIGACTION
+#ifdef SIGPIPE
+ struct sigaction opipe;
+ struct sigaction npipe;
+#endif
+ struct sigaction oint;
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+#else
+#ifdef SIGPIPE
+ dk4_sig_handler_t *opipe = NULL;
+#endif
+ dk4_sig_handler_t *oterm = NULL;
+ dk4_sig_handler_t *oint = NULL;
+#endif
+ const size_t szblang = DK4_SIZEOF(blang,dkChar);
+ const size_t szbreg = DK4_SIZEOF(breg,dkChar);
+#if DK4_HAVE_SIGACTION
+ int pipe_set = 0;
+ int term_set = 0;
+ int int_set = 0;
+ int sig_i_f = 0;
+ int sig_r_f = 0;
+#endif
+
+
+#line 1755 "prmonsnmp.ctr"
+
+
+#line 1756 "prmonsnmp.ctr"
+
+ /* Set signal handlers.
+ --------------------
+ */
+#if DK4_HAVE_SIGACTION
+#ifdef SIGPIPE
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ sig_i_f = 1;
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ sig_i_f = 1;
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ sig_i_f = 1;
+ goto finished;
+ }
+ pipe_set = 1;
+#endif
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ sig_i_f = 1;
+ goto finished;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ sig_i_f = 1;
+ goto finished;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ sig_i_f = 1;
+ goto finished;
+ }
+ term_set = 1;
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ sig_i_f = 1;
+ goto finished;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ sig_i_f = 1;
+ goto finished;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ sig_i_f = 1;
+ goto finished;
+ }
+ int_set = 1;
+#else
+#ifdef SIGPIPE
+ opipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oint = sigset(SIGINT, sig_handler_int);
+ oterm = sigset(SIGTERM, sig_handler_term);
+#endif
+
+ /*
+ Retrieve encoding.
+ ------------------
+ */
+ if (0 == dk4loc_get_settings(blang, szblang, breg, szbreg, &encoding, NULL)) {
+ encoding = DK4_ENCODING_ASCII;
+ }
+ /* Process command line arguments.
+ -------------------------------
+ */
+ if (0 == process_command_line_arguments(argc, argv)) {
+ goto finished;
+ }
+
+ if (0 != hvl) {
+ run_hvl();
+ goto finished;
+ }
+
+ /* Set up SNMP and create session.
+ -------------------------------
+ */
+#if DK4_HAVE_SNMP_DISABLE_SYSLOG
+
+
+#line 1852 "prmonsnmp.ctr"
+ snmp_disable_syslog();
+#endif
+#if DK4_HAVE_SNMP_DISABLE_FILELOG
+
+
+#line 1856 "prmonsnmp.ctr"
+ snmp_disable_filelog();
+#endif
+#if DK4_HAVE_SNMP_DISABLE_STDERRLOG
+
+
+#line 1860 "prmonsnmp.ctr"
+ snmp_disable_stderrlog();
+#endif
+ init_snmp(prmonsnmp_kw[2]);
+ DK4_MEMRES(&template, sizeof(template));
+ snmp_sess_init(&template);
+ template.version = snmp_vers;
+ template.peername = host_name;
+ template.community = (unsigned char *)snmp_comm;
+ if (NULL == snmp_comm) {
+ template.community = (unsigned char *)(prmonsnmp_kw[3]);
+ }
+ template.community_len = strlen((char *)(template.community));
+ snmp_sess = snmp_open(&template);
+ if (NULL == snmp_sess) {
+ /* ERROR: Failed to open session */
+ fputs(prmonsnmp_kw[2], stderr);
+ fputs(prmonsnmp_kw[43], stderr);
+ fflush(stderr);
+ goto finished;
+ }
+
+ /* Run main loop.
+ --------------
+ */
+ exval = EXIT_SUCCESS;
+ run_main_loop();
+
+ /*
+ Cleanup.
+ --------
+ */
+ finished:
+ /*
+ Close SNMP session, if any.
+ */
+ /*
+ Restore signal handlers
+ */
+#if DK4_HAVE_SIGACTION
+ if (0 != sig_i_f) {
+ fputs(prmonsnmp_kw[2], stderr);
+ fputs(prmonsnmp_kw[45], stderr);
+ fflush(stderr);
+ }
+ if (0 != int_set) {
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR */
+ sig_r_f = 1;
+ }
+ }
+ if (0 != term_set) {
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR */
+ sig_r_f = 1;
+ }
+ }
+#ifdef SIGPIPE
+ if (0 != pipe_set) {
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ /* ERROR */
+ sig_r_f = 1;
+ }
+ }
+#endif
+ if (0 != sig_r_f) {
+ fputs(prmonsnmp_kw[2], stderr);
+ fputs(prmonsnmp_kw[44], stderr);
+ fflush(stderr);
+ }
+#else
+ if (NULL != oterm) { sigset(SIGTERM, oterm); }
+ if (NULL != oint ) { sigset(SIGINT, oint ); }
+#ifdef SIGPIPE
+ if (NULL != opipe) { sigset(SIGPIPE, opipe); }
+#endif
+#endif
+
+
+
+#line 1938 "prmonsnmp.ctr"
+
+
+#line 1939 "prmonsnmp.ctr"
+ /* ----- Required libraries available */
+
+#else
+/* if DK4_HAVE_LIBNETSNMP && ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET)) */
+ fputs(prmonsnmp_kw[2], stderr);
+ fputs(": ERROR: Required features missing!\n", stderr);
+#if !DK4_HAVE_LIBNETSNMP
+ fputs("Support for Net-SNMP required!\n", stderr);
+ fputs("http://sourceforge.net/projects/net-snmp\n", stderr);
+#endif
+#if !((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET))
+ fputs("Support for sigaction() or sigset() required but not found!\n",stderr);
+#endif
+ fflush(stderr);
+#endif
+/* if DK4_HAVE_LIBNETSNMP && ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET)) */
+ exit(exval); return exval;
+}
+
+
diff --git a/support/dktools/prmonsnmp.ctr b/support/dktools/prmonsnmp.ctr
new file mode 100644
index 0000000000..3d92551b06
--- /dev/null
+++ b/support/dktools/prmonsnmp.ctr
@@ -0,0 +1,1958 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+
+
+/** Constant text fragments used by the program, not localized.
+*/
+static const char * const prmonsnmp_kw[] = {
+$!string-table
+#
+# 0 Newline
+#
+\n
+#
+# 1 Space
+#
+
+#
+# 2 Program name
+#
+prmonsnmp
+#
+# 3 Default SNMP community name
+#
+public
+#
+# 4 ... 9 Device status
+#
+unreachable
+unknown
+running
+warning
+testing
+down
+#
+# 10 ... 15 Printer status
+#
+unreachable
+other
+unknown
+idle
+printing
+warmup
+#
+# 16 Default condition set
+#
+XXXX-XXXX-XXXX-XXXX
+#
+# 17 Separator
+#
+ /
+#
+# 18 3 spaces
+#
+
+#
+# 19 ... 33 Error conditions
+#
+W: Low paper.\n
+E: No paper!\n
+W: Low toner.\n
+E: No toner!\n
+E: Door open!\n
+E: Jammed!\n
+E: Offline!\n
+W: Service requested.\n
+E: Input tray missing!\n
+E: Output tray missing!\n
+E: Marker supply missing!\n
+W: Output near full.\n
+E: Output full!\n
+W: Input tray empty.\n
+W: Overdue preventive maintenance.\n
+#
+# 34 Comment marker before timestamp
+#
+\#
+#
+# 35 Error: Unreachable
+#
+UNREACHABLE!\n
+#
+# 36 ERROR: Failed to create request PDU
+#
+: ERROR: Failed to create SNMP request PDU!\n
+#
+# 37 Warning: SNMP version configured multiple times
+#
+: Warning: SNMP version configured multiple times!\n
+#
+# 38 39 ERROR: Illegal SNMP version
+#
+: ERROR: Illegal SNMP version: "
+"!\n
+#
+# 40
+#
+: Warning: SNMP community configured multiple times!\n
+#
+# 41
+#
+: Warning: Host name configured multiple times!\n
+#
+# 42
+#
+: ERROR: Missing host name!\n
+#
+# 43
+#
+: ERROR: Failed to open SNMP session!\n
+#
+# 44
+#
+: ERROR: Failed to restore signal handlers!\n
+#
+# 45
+#
+: ERROR: Failed to set up signal handlers!\n
+$!end
+};
+
+
+
+#if DK4_HAVE_LIBNETSNMP && ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET))
+
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/utilities.h>
+#include <net-snmp/library/snmp_logging.h>
+
+#include "dk4mem.h"
+#include "dk4str8.h"
+#include "dk4mai8dus.h"
+#include "dk4time.h"
+#include "dk4time08.h"
+#include "dk4sock.h"
+#include "dk4maasz.h"
+#include "dk4mai8dii.h"
+#include "dk4mai8ddu.h"
+#include "dk4mao8d.h"
+#include "dk4mao8h.h"
+#include "dk4enc.h"
+#include "dk4loc.h"
+#include "dk4vers.h"
+
+
+
+$!trace-include
+
+
+
+/** Status text from SNMP response.
+*/
+static char statext[1024];
+
+
+
+/** Previous status text.
+*/
+static char ostatext[sizeof(statext)];
+
+
+
+/** Long option names.
+*/
+static const char * const long_options[] = {
+$!string-table
+help
+version
+license
+$!end
+};
+
+
+
+/** OID for device status.
+*/
+static const oid prmonsnmp_oid_ds[] = {
+ (oid)1, (oid)3, (oid)6, (oid)1, (oid)2, (oid)1,
+ (oid)25, (oid)3, (oid)2, (oid)1, (oid)5, (oid)1
+};
+
+/** Size of device status OID (number of elements).
+*/
+static size_t const pjsnmp_sz_oid_ds = sizeof(prmonsnmp_oid_ds)/sizeof(oid);
+
+/** Size of device status OID (number of bytes).
+*/
+static size_t const pjsnmp_bytes_oid_ds = sizeof(prmonsnmp_oid_ds);
+
+
+/** OID for printer status.
+*/
+static const oid prmonsnmp_oid_ps[] = {
+ (oid)1, (oid)3, (oid)6, (oid)1, (oid)2, (oid)1,
+ (oid)25, (oid)3, (oid)5, (oid)1, (oid)1, (oid)1
+};
+
+/** Size of printer status OID (number of elements).
+*/
+static size_t const pjsnmp_sz_oid_ps = sizeof(prmonsnmp_oid_ps)/sizeof(oid);
+
+/** Size of printer status OID (number of bytes).
+*/
+static size_t const pjsnmp_bytes_oid_ps = sizeof(prmonsnmp_oid_ps);
+
+
+/** OID for pagecount value.
+*/
+static const oid prmonsnmp_oid_pc[] = {
+ (oid)1, (oid)3, (oid)6, (oid)1, (oid)2, (oid)1,
+ (oid)43, (oid)10, (oid)2, (oid)1, (oid)4, (oid)1, (oid)1
+};
+
+/** Size of page counter OID (number of elements).
+*/
+static size_t const pjsnmp_sz_oid_pc = sizeof(prmonsnmp_oid_pc)/sizeof(oid);
+
+/** Size of page counter OID (number of bytes).
+*/
+static size_t const pjsnmp_bytes_oid_pc = sizeof(prmonsnmp_oid_pc);
+
+
+/** Printer error OID.
+*/
+static const oid prmonsnmp_oid_pe[] = {
+ (oid)1, (oid)3, (oid)6, (oid)1, (oid)2, (oid)1,
+ (oid)25, (oid)3, (oid)5, (oid)1, (oid)2, (oid)1
+};
+
+/** Size of printer error OID (number of elements).
+*/
+static size_t const pjsnmp_sz_oid_pe = sizeof(prmonsnmp_oid_pe)/sizeof(oid);
+
+/** Size of printer error OID (number of bytes).
+*/
+static size_t const pjsnmp_bytes_oid_pe = sizeof(prmonsnmp_oid_pe);
+
+/** Status text OID.
+*/
+static const oid prmonsnmp_oid_st[] = {
+ (oid)1, (oid)3, (oid)6, (oid)1, (oid)2, (oid)1,
+ (oid)43, (oid)16, (oid)5, (oid)1, (oid)2, (oid)1, (oid)1
+};
+
+/** Size of printer error OID (number of elements).
+*/
+static size_t const pjsnmp_sz_oid_st = sizeof(prmonsnmp_oid_st)/sizeof(oid);
+
+/** Size of printer error OID (number of bytes).
+*/
+static size_t const pjsnmp_bytes_oid_st = sizeof(prmonsnmp_oid_st);
+
+
+
+/** Help text.
+*/
+static const char * const help_text[] = {
+$!text
+
+Monitor printers
+
+prmonsnmp [-v version] [-c community] [-t seconds] [-n] host
+
+Options:
+-v version SNMP version: 1, 2c, 2 (same as 2c), 3, default: 1.
+-c community SNMP community name, default: public.
+-t seconds Duration for monitoring, default: 0 (endless).
+-n No 250 ms grace period between requests.
+
+--help Show this help text.
+--version Show version number.
+--license Show license information.
+
+$!end
+};
+
+
+
+/** License conditions text.
+*/
+static const char * const license_text[] = {
+$!text preprocessor
+
+This software uses code from the following projects, either directly or as
+a library:
+
+dktools Dirk Krause's tools and libraries.
+ See http://dktools.sourceforge.net/ for more information.
+#if DK4_HAVE_LIBNETSNMP
+Net-SNMP SNMP access library.
+ See http://net-snmp.sourceforge.net/ for more information.
+#endif
+#if DK4_HAVE_ZLIB_H
+
+zlib Data compression library.
+ See http://www.zlib.net/ for more information.
+#endif
+#if DK4_HAVE_OPENSSL_MD5_H && DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_OPENSSL_RIPEMD_H
+
+OpenSSL Cryptographic toolkit, used to build file checksums here.
+ See http://www.openssl.org/ for more information.
+
+This product includes software developed by the OpenSSL Project for use in
+the OpenSSL Toolkit (http://www.openssl.org/).
+This product includes cryptographic software written by
+Eric Young (eay@cryptsoft.com).
+This product includes software written by Tim Hudson (tjh@cryptsoft.com).
+#endif
+
+All the licenses below apply to the program.
+Licenses for used libraries are shown as found on my Scientific Linux 6.x
+computer in the /usr/share/doc directory on 2015-04-01. Check the project
+homepages of the used libraries for additional information and/or updated
+license terms.
+
+
+DK tools and libraries license
+==============================
+Copyright (c) 2015-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#if DK4_HAVE_LIBNETSNMP
+
+
+Net-SNMP license
+================
+Various copyrights apply to this package, listed in various separate parts
+below. Please make sure that you read all the parts. Up until 2001,
+the project was based at UC Davis, and the first part covers all code
+written during this time. From 2001 onwards, the project has been
+based at SourceForge, and Networks Associates Technology, Inc hold the
+copyright on behalf of the wider Net-SNMP community, covering all
+derivative work done since then. An additional copyright section has
+been added as Part 3 below also under a BSD license for the work
+contributed by Cambridge Broadband Ltd. to the project since 2001.
+An additional copyright section has been added as Part 4 below also
+under a BSD license for the work contributed by Sun Microsystems, Inc.
+to the project since 2003.
+
+Code has been contributed to this project by many people over
+the years it has been in development, and a full list of contributors
+can be found in the README file under the THANKS section.
+
+
+---- Part 1: CMU/UCD copyright notice: (BSD like) -----
+
+
+ Copyright 1989, 1991, 1992 by Carnegie Mellon University
+
+ Derivative Work - 1996, 1998-2000
+Copyright 1996, 1998-2000 The Regents of the University of California
+
+ All Rights Reserved
+
+Permission to use, copy, modify and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appears in all copies and
+that both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of CMU and The Regents of
+the University of California not be used in advertising or publicity
+pertaining to distribution of the software without specific written
+permission.
+
+CMU AND THE REGENTS OF THE UNIVERSITY OF CALIFORNIA DISCLAIM ALL
+WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL CMU OR
+THE REGENTS OF THE UNIVERSITY OF CALIFORNIA BE LIABLE FOR ANY SPECIAL,
+INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+FROM THE LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+
+---- Part 2: Networks Associates Technology, Inc copyright notice (BSD) -----
+
+Copyright (c) 2001-2003, Networks Associates Technology, Inc
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+* Neither the name of the Networks Associates Technology, Inc nor the
+ names of its contributors may be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
+IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+---- Part 3: Cambridge Broadband Ltd. copyright notice (BSD) -----
+
+Portions of this code are copyright (c) 2001-2003, Cambridge Broadband Ltd.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+* The name of Cambridge Broadband Ltd. may not be used to endorse or
+ promote products derived from this software without specific prior
+ written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+---- Part 4: Sun Microsystems, Inc. copyright notice (BSD) -----
+
+Copyright © 2003 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+California 95054, U.S.A. All rights reserved.
+
+Use is subject to license terms below.
+
+This distribution may include materials developed by third parties.
+
+Sun, Sun Microsystems, the Sun logo and Solaris are trademarks or registered
+trademarks of Sun Microsystems, Inc. in the U.S. and other countries.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+* Neither the name of the Sun Microsystems, Inc. nor the
+ names of its contributors may be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
+IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+---- Part 5: Sparta, Inc copyright notice (BSD) -----
+
+Copyright (c) 2003-2006, Sparta, Inc
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+* Neither the name of Sparta, Inc nor the names of its contributors may
+ be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
+IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+---- Part 6: Cisco/BUPTNIC copyright notice (BSD) -----
+
+Copyright (c) 2004, Cisco, Inc and Information Network
+Center of Beijing University of Posts and Telecommunications.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+* Neither the name of Cisco, Inc, Beijing University of Posts and
+ Telecommunications, nor the names of their contributors may
+ be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
+IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+---- Part 7: Fabasoft R&D Software GmbH & Co KG copyright notice (BSD) -----
+
+Copyright (c) Fabasoft R&D Software GmbH & Co KG, 2003
+oss@fabasoft.com
+Author: Bernhard Penz <bernhard.penz@fabasoft.com>
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+* The name of Fabasoft R&D Software GmbH & Co KG or any of its subsidiaries,
+ brand or product names may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#endif
+#if DK4_HAVE_ZLIB_H
+
+
+Zlib license
+============
+(C) 1995-2004 Jean-loup Gailly and Mark Adler
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+
+Jean-loup Gailly Mark Adler
+jloup@gzip.org madler@alumni.caltech.edu
+#endif
+#if DK4_HAVE_BZLIB_H
+
+
+Bzip2 and libbzip2 library license
+==================================
+This program, "bzip2", the associated library "libbzip2", and all
+documentation, are copyright (C) 1996-2007 Julian R Seward. All
+rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+3. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Julian Seward, jseward@bzip.org
+bzip2/libbzip2 version 1.0.5 of 10 December 2007
+#endif
+#if DK4_HAVE_OPENSSL_MD5_H && DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_OPENSSL_RIPEMD_H
+
+
+OpenSSL license
+===============
+
+LICENSE ISSUES
+--------------
+
+The OpenSSL toolkit stays under a dual license, i.e. both the conditions of
+the OpenSSL License and the original SSLeay license apply to the toolkit.
+See below for the actual license texts. Actually both licenses are BSD-style
+Open Source licenses. In case of any license issues related to OpenSSL
+please contact openssl-core@openssl.org.
+
+OpenSSL License
+---------------
+
+Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+3. All advertising materials mentioning features or use of this
+ software must display the following acknowledgment:
+ "This product includes software developed by the OpenSSL Project
+ for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+
+4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ endorse or promote products derived from this software without
+ prior written permission. For written permission, please contact
+ openssl-core@openssl.org.
+
+5. Products derived from this software may not be called "OpenSSL"
+ nor may "OpenSSL" appear in their names without prior written
+ permission of the OpenSSL Project.
+
+6. Redistributions of any form whatsoever must retain the following
+ acknowledgment:
+ "This product includes software developed by the OpenSSL Project
+ for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+
+THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+OF THE POSSIBILITY OF SUCH DAMAGE.
+
+This product includes cryptographic software written by Eric Young
+(eay@cryptsoft.com). This product includes software written by Tim
+Hudson (tjh@cryptsoft.com).
+
+
+Original SSLeay License
+-----------------------
+
+Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+All rights reserved.
+
+This package is an SSL implementation written
+by Eric Young (eay@cryptsoft.com).
+The implementation was written so as to conform with Netscapes SSL.
+
+This library is free for commercial and non-commercial use as long as
+the following conditions are aheared to. The following conditions
+apply to all code found in this distribution, be it the RC4, RSA,
+lhash, DES, etc., code; not just the SSL code. The SSL documentation
+included with this distribution is covered by the same copyright terms
+except that the holder is Tim Hudson (tjh@cryptsoft.com).
+
+Copyright remains Eric Young's, and as such any Copyright notices in
+the code are not to be removed.
+If this package is used in a product, Eric Young should be given attribution
+as the author of the parts of the library used.
+This can be in the form of a textual message at program startup or
+in documentation (online or textual) provided with the package.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. All advertising materials mentioning features or use of this software
+ must display the following acknowledgement:
+ "This product includes cryptographic software written by
+ Eric Young (eay@cryptsoft.com)"
+ The word 'cryptographic' can be left out if the rouines from the library
+ being used are not cryptographic related :-).
+4. If you include any Windows specific code (or a derivative thereof) from
+ the apps directory (application code) you must include an acknowledgement:
+ "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+
+THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+The licence and distribution terms for any publically available version or
+derivative of this code cannot be changed. i.e. this code cannot simply be
+copied and put under another distribution licence
+[including the GNU Public Licence.]
+
+#endif
+
+$!end
+};
+
+
+
+/** Version information.
+*/
+static const char version_text[] = { DKT_VERSION_C8 };
+
+
+
+/** Accepted SNMP version names.
+*/
+static const char * const snmp_version_names[] = {
+$!string-table
+1
+2
+2c
+3
+$!end
+};
+
+
+/** Host name (or IP address) of printer.
+*/
+static char *host_name = NULL;
+
+/** SNMP community name.
+*/
+static char *snmp_comm = NULL;
+
+
+/** SNMP session.
+*/
+static struct snmp_session *snmp_sess = NULL;
+
+
+/** Timeout in seconds.
+*/
+static dk4_um_t timeout = (dk4_um_t)0UL;
+
+
+/** Previous log timestamp.
+*/
+static dk4_time_t previous_log = (dk4_time_t)0UL;
+
+
+/** SNMP version.
+*/
+static long snmp_vers = SNMP_VERSION_1;
+
+/** Flag: Had a previous log.
+*/
+static int have_time = 0;
+
+
+/** Flag: Behave gracefully, max 4 SNMP requests per second.
+*/
+static int grace = 1;
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+static int encoding = DK4_ENCODING_ASCII;
+#endif
+
+/** Exit status code.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+#if DK4_HAVE_LIBNETSNMP && ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET))
+
+
+
+/** Help (1), version (2), license (4).
+*/
+static int hvl = 0;
+
+
+
+/** Pass volatile pointer.
+ @param ptr Pointer to pass through.
+ @return The original pointer.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+
+/** Check whether we can continue or must abort due to signal.
+ @param dopipe Flag: Check for SIGPIPE too.
+ @return 1 if we can continue, 0 otherwise.
+*/
+static
+int
+can_continue(int dopipe)
+{
+ int back = 1;
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_int)) { back = 0; }
+#ifdef SIGPIPE
+ if (0 != dopipe) {
+ if (0 != sig_read_atomic(&sig_had_pipe)) { back = 0; }
+ }
+#endif
+ return back;
+}
+
+
+
+/** Check two OIDs for equality.
+ @param pl Left OID.
+ @param szl Left OID size.
+ @param pr Right OID.
+ @param szr Right OID size.
+ @return 1 for equal OIDs, 0 otherwise.
+*/
+static
+int
+oids_equal(const oid *pl, size_t szl, const oid *pr, size_t szr)
+{
+#if VERSION_BEFORE_20160206
+ size_t i;
+#endif
+ int back = 0;
+
+ if (szl == szr) {
+#if VERSION_BEFORE_20160206
+ back = 1;
+ for (i = 0; ((i < szl) && (1 == back)); i++) {
+ if (pl[i] != pr[i]) {
+ back = 0;
+ }
+ }
+#else
+ if (0 == dk4mem_cmp(pl, pr, (szl * sizeof(oid)), NULL)) {
+ back = 1;
+ }
+#endif
+ }
+ return back;
+}
+
+
+/** Find OID index.
+ @param oid Pointer to OID to check.
+ @param sz OID size.
+ @return 0 for hrDeviceStatus, 1 for hrPrinterStatus,
+ 2 for page counter, 3 for hrPrinterDetectedErrorState,
+ 4 for prtMarkerLifeCount, -1 otherwise.
+*/
+static
+int
+oid_index(oid *p, size_t sz)
+{
+ int back = -1;
+ if (0 != oids_equal(p, sz, prmonsnmp_oid_ds, pjsnmp_sz_oid_ds)) {
+ back = 0;
+ } else {
+ if (0 != oids_equal(p, sz, prmonsnmp_oid_ps, pjsnmp_sz_oid_ps)) {
+ back = 1;
+ } else {
+ if (0 != oids_equal(p, sz, prmonsnmp_oid_pe, pjsnmp_sz_oid_pe)) {
+ back = 2;
+ } else {
+ if (0 != oids_equal(p, sz, prmonsnmp_oid_st, pjsnmp_sz_oid_st)) {
+ back = 3;
+ } else {
+ if (0 != oids_equal(p, sz, prmonsnmp_oid_pc, pjsnmp_sz_oid_pc)) {
+ back = 4;
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+/** Retrieve integer value from variable list.
+ @param iptr Address of variable to set.
+ @param var SNMP variable containing the value.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+get_int(int *iptr, struct variable_list *var)
+{
+ char bu[64]; /* Buffer for text data copy */
+ const char *endptr = NULL; /* End of used data in numeric conversion */
+ long l; /* Long value from SNMP response */
+ int i; /* Text to number conversion result */
+ int back = 0;
+ $? "+ get_int"
+ switch (var->type) {
+ case ASN_OCTET_STR : { $? ". from string"
+ if ((var->val_len > 0) && (var->val_len < sizeof(bu))) {
+ dk4mem_cpy(bu, (void *)((var->val).string), var->val_len, NULL);
+ bu[var->val_len] = '\0';
+ if (0 != dk4ma_input_c8_dec_int(&i, bu, &endptr, 1, NULL)) {
+ *iptr = i;
+ back = 1;
+ }
+ }
+ } break;
+ case ASN_TIMETICKS :
+ case ASN_GAUGE :
+ case ASN_COUNTER :
+ case ASN_INTEGER : { $? ". from integer"
+ l = *((var->val).integer);
+ *iptr = (int)l;
+ back = 1;
+ } break;
+ }
+ $? "- get_int %d", back
+ return back;
+}
+
+
+/** Retrieve unsigned long value from variable list.
+ @param ulptr Address of variable to set.
+ @param var SNMP variable containing the value.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+get_ul(unsigned long *ulptr, struct variable_list *var)
+{
+ unsigned long ul = 0UL; /* Conversion result */
+ long l; /* Long result from SNMP response */
+ int back = 0;
+ $? "+ get_ul"
+ switch (var->type) {
+ case ASN_OCTET_STR : { $? ". from byte array"
+ if (0 < var->val_len) {
+ ul |=
+ ((((unsigned long)(((var->val).string)[0])) << 24) & 0xFF000000UL);
+ back = 1;
+ }
+ if (1 < var->val_len) {
+ ul |=
+ ((((unsigned long)(((var->val).string)[1])) << 16) & 0x00FF0000UL);
+ }
+ if (2 < var->val_len) {
+ ul |=
+ ((((unsigned long)(((var->val).string)[2])) << 8) & 0x0000FF00UL);
+ }
+ if (3 < var->val_len) {
+ ul |=
+ ((((unsigned long)(((var->val).string)[3])) ) & 0x000000FFUL);
+ }
+ if (0 != back) {
+ *ulptr = ul;
+ }
+ } break;
+ case ASN_TIMETICKS :
+ case ASN_GAUGE :
+ case ASN_COUNTER :
+ case ASN_INTEGER : { $? ". from integer"
+ l = *((var->val).integer);
+ if (0L <= l) {
+ *ulptr = (unsigned long)l;
+ back = 1;
+ }
+ } break;
+ }
+ $? "- get_ul %d", back
+ return back;
+}
+
+
+
+/** Check whether a text buffer contains non-ASCII bytes.
+ @param ptr Buffer start address.
+ @param i Buffer size.
+ @return 1 if non-ASCII found, 0 for ASCII only.
+*/
+static
+int
+contains_non_ascii(const unsigned char *ptr, size_t i)
+{
+ int back = 0;
+ while ((0 == back) && (0 < i)) {
+ if (0x7F < *(ptr++)) {
+ back = 1;
+ }
+ i--;
+ }
+ return back;
+}
+
+
+
+/** Log current timestamp.
+*/
+static
+void
+log_timestamp(void)
+{
+ char buf[64]; /* Text representation of timestamp */
+ dk4_time_t current; /* Current time */
+ int res; /* Conversion operation result */
+
+ dk4time_get(&current);
+ if ((0 == have_time) || (current != previous_log)) {
+ res = dk4time_as_text_c8(buf, sizeof(buf), &current, NULL);
+ if (0 != res) {
+ if (0 != have_time) {
+ fputc('\n', stdout);
+ }
+ fputs(prmonsnmp_kw[34], stdout);
+ fputs(buf, stdout);
+ fputc('\n', stdout);
+ }
+ } else {
+ if (0 != have_time) {
+ fputc('\n', stdout);
+ }
+ }
+ have_time = 1;
+ previous_log = current;
+}
+
+
+
+/** Show text, convert non-ASCII to question marks.
+ @param str String to show.
+ @param sz Text length.
+*/
+static
+void
+show_as_ascii(const unsigned char *str, size_t sz)
+{
+ while (0 < sz--) {
+ if (0x7F < *str) {
+ fputc('?', stdout);
+ } else {
+ fputc(*str, stdout);
+ }
+ str++;
+ }
+}
+
+
+
+/** The main loop sending SNMP requests and printing
+ responses to standard output.
+*/
+static
+void
+run_main_loop(void)
+{
+ char nb[64]; /* Buffer for hex representation */
+ struct timeval to; /* Timeout for select */
+ struct snmp_pdu *rq; /* Request */
+ struct snmp_pdu *rs; /* Response */
+ struct variable_list *vars; /* Current variable to process */
+ unsigned char *uptr; /* Traverse text */
+ dk4_time_t start_time; /* Start time */
+ dk4_time_t timeout_time; /* First timeout seen */
+ dk4_time_t current_time; /* Current time */
+ unsigned long cond = 0UL; /* Printer detected error */
+ unsigned long ocond = 0UL; /* Previous printer det err */
+ unsigned long tcond = 0UL; /* Current conditions */
+ unsigned long opcnt = 0UL; /* Previous page count */
+ unsigned long ul; /* unsigned long from current var */
+ unsigned long pcnt; /* Page count */
+ size_t lst; /* Status text length */
+ size_t olst; /* Previous status text length */
+ int i; /* Traverse bits in pr det err st */
+ int found; /* Summary: Which information found */
+ int must_show; /* Must show changed values */
+ int must_flush; /* Must flush standard output */
+ int status; /* SNMP response status */
+ int res; /* Operation result */
+ int cc = 1; /* Flag: Can continue */
+ int devst = 0; /* Device status */
+ int prist = 0; /* Printer status */
+ int unreach = 0; /* Flag: Unreachable */
+ int odevst = 0; /* Previous device status */
+ int oprist = 0; /* Previous printer status */
+ int ounreach = 0; /* Previous unreach flag */
+
+ dk4time_get(&start_time);
+ timeout_time = (dk4_time_t)0UL;
+ if ((dk4_um_t)0UL < timeout) {
+ timeout_time = start_time + (dk4_time_t)timeout;
+ }
+ cc = 1;
+ statext[0] = '\0';
+ ostatext[0] = '\0';
+ olst = 0;
+ do {
+ pcnt = 0UL;
+ unreach = 1;
+ devst = 0;
+ prist = 0;
+ found = 0;
+ cond = 0UL;
+ statext[0] = '\0';
+ rs = NULL;
+ lst = 0;
+ must_show = 0; $? ". must_show = 0"
+ must_flush = 0;
+ if (0 != can_continue(0)) {
+ rq = snmp_pdu_create(SNMP_MSG_GET);
+ if (NULL != rq) {
+ snmp_add_null_var(rq, prmonsnmp_oid_ds, pjsnmp_sz_oid_ds);
+ snmp_add_null_var(rq, prmonsnmp_oid_ps, pjsnmp_sz_oid_ps);
+ snmp_add_null_var(rq, prmonsnmp_oid_pe, pjsnmp_sz_oid_pe);
+ snmp_add_null_var(rq, prmonsnmp_oid_st, pjsnmp_sz_oid_st);
+ snmp_add_null_var(rq, prmonsnmp_oid_pc, pjsnmp_sz_oid_pc);
+ status = snmp_synch_response(snmp_sess, rq, &rs);
+ if (STAT_SUCCESS == status) {
+ if (NULL != rs) {
+ if (SNMP_ERR_NOERROR == rs->errstat) {
+ unreach = 0;
+ vars = rs->variables;
+ while (NULL != vars) {
+ switch (oid_index(vars->name, vars->name_length)) {
+ case 0: {
+ i = 0;
+ if (0 != get_int(&i, vars)) {
+ devst = i;
+ found |= 1;
+ }
+ } break;
+ case 1: {
+ i = 0;
+ if (0 != get_int(&i, vars)) {
+ prist = i;
+ found |= 2;
+ }
+ } break;
+ case 2: {
+ ul = 0UL;
+ if (0 != get_ul(&ul, vars)) {
+ cond = ul;
+ found |= 4;
+ }
+ } break;
+ case 3: {
+ if ((0 < vars->val_len)&&(sizeof(statext) > vars->val_len))
+ {
+ dk4mem_cpy(statext,(vars->val).string,vars->val_len,NULL);
+ statext[vars->val_len] = '\0';
+ lst = vars->val_len;
+ found |= 8;
+ }
+ } break;
+ case 4: {
+ ul = 0UL;
+ if (0 != get_ul(&ul, vars)) {
+ pcnt = ul;
+ found |= 16;
+ }
+ } break;
+ }
+ vars = vars->next_variable;
+ }
+ if (0 != (1 & found)) {
+ if (devst != odevst) { $? ". must_show = 1"
+ must_show = 1;
+ }
+ }
+ if (0 != (2 & found)) {
+ if (prist != oprist) { $? ". must_show = 1"
+ must_show = 1;
+ }
+ }
+ if (0 != (4 & found)) {
+ if (cond != ocond) { $? ". must_show = 1"
+ must_show = 1;
+ }
+ }
+ if (0 != (8 & found)) {
+ if (lst != olst) { $? ". must_show = 1"
+ must_show = 1;
+ }
+ if (0 != dk4mem_cmp(statext, ostatext, lst, NULL)) {
+ $? ". must_show = 1"
+ must_show = 1;
+ }
+ }
+ if (0 != (16 & found)) {
+ if (pcnt != opcnt) {
+ must_show = 1;
+ }
+ }
+ if (0 != must_show) {
+ log_timestamp();
+ must_flush = 1;
+ if ((0 != (1 & found)) && (0 <= devst) && (5 >= devst)) {
+ fputs(prmonsnmp_kw[4 + devst], stdout);
+ }
+ if ((0 != (2 & found)) && (0 <= prist) && (5 >= prist)) {
+ fputs(prmonsnmp_kw[17], stdout);
+ fputs(prmonsnmp_kw[10 + prist], stdout);
+ }
+ if (0 != (4 & found)) {
+ fputs(prmonsnmp_kw[18], stdout);
+ tcond = 0x80000000UL;
+ for (i = 0; i < 16; i++) {
+ if ((0 < i) && (0 == (i % 4))) {
+ fputc('-', stdout);
+ }
+ fputc(((0UL != (tcond & cond)) ? '1' : '0'), stdout);
+ tcond = tcond / 2UL;
+ }
+ }
+ if (0 != (16 & found)) {
+ res = dk4ma_write_c8_decimal_unsigned(
+ nb, sizeof(nb), (dk4_um_t)pcnt, 0, NULL
+ );
+ if (0 != res) {
+ fputs(prmonsnmp_kw[18], stdout);
+ fputs(nb, stdout);
+ }
+ }
+ fputc('\n', stdout);
+ if (0 != (4 & found)) {
+ tcond = 0x80000000UL;
+ for (i = 0; i < 15; i++) {
+ if (0UL != (cond & tcond)) {
+ fputs(prmonsnmp_kw[19 + i], stdout);
+ }
+ tcond = tcond / 2UL;
+ }
+ }
+ if (0 != (8 & found)) {
+ if (0 < lst) {
+ uptr = (unsigned char *)statext;
+ for (i = 0; i < lst; i++) {
+ if (0 < i) {
+ if (0 == (i % 24)) {
+ fputc('\n', stdout);
+ } else {
+ fputc(' ', stdout);
+ }
+ }
+ res = dk4ma_write_c8_hex_unsigned(
+ nb, sizeof(nb), (dk4_um_t)(*(uptr++)), 2, NULL
+ );
+ if (0 != res) {
+ fputs(nb, stdout);
+ }
+ }
+ fputc('\n', stdout);
+ fputc('"', stdout);
+ if (0 == contains_non_ascii((unsigned char *)statext,lst)) {
+ fwrite(statext, 1, lst, stdout);
+ } else {
+ show_as_ascii((unsigned char *)statext, lst);
+ }
+ fputc('"', stdout);
+ fputc('\n', stdout);
+ }
+ }
+ }
+ }
+ }
+ }
+ if (NULL != rs) {
+ snmp_free_pdu(rs);
+ }
+ if (unreach != ounreach) {
+ log_timestamp();
+ fputs(prmonsnmp_kw[35], stdout);
+ must_flush = 1;
+ }
+ ounreach = unreach;
+ odevst = devst;
+ oprist = prist;
+ ocond = cond;
+ olst = lst;
+ opcnt = pcnt;
+ strcpy(ostatext, statext);
+ } else {
+ cc = -1;
+ exval = EXIT_FAILURE;
+ /* ERROR: Failed to create request PDU */
+ fputs(prmonsnmp_kw[2], stderr);
+ fputs(prmonsnmp_kw[36], stderr);
+ fflush(stderr);
+ }
+ if (0 != must_flush) {
+ fflush(stdout);
+ }
+ } else {
+ cc = -1;
+ }
+ if (1 == cc) {
+ if ((dk4_time_t)0UL < timeout_time) {
+ dk4time_get(&current_time);
+ if (current_time > timeout_time) {
+ cc = 0;
+ }
+ }
+ }
+ if (1 == cc) {
+ if (0 != grace) {
+ to.tv_sec = 0L;
+ to.tv_usec = 250000L;
+ select(0, NULL, NULL, NULL, &to);
+ }
+ }
+ } while (1 == cc);
+}
+
+
+
+/** Set SNMP version.
+ @param name SNMP version name as text.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+set_snmp_version(const char *name)
+{
+ int back = 0;
+ switch (dk4str8_array_index(snmp_version_names, name, 0)) {
+ case 0: {
+ back = 1;
+ snmp_vers = SNMP_VERSION_1;
+ } break;
+ case 1: case 2: {
+ back = 1;
+ snmp_vers = SNMP_VERSION_2c;
+ } break;
+ case 3: {
+ back = 1;
+ snmp_vers = SNMP_VERSION_3;
+ } break;
+ }
+ return back;
+}
+
+
+
+/** Process command line arguments.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+process_command_line_arguments(int argc, char *argv[])
+{
+ char **lfdarg; /* Traverse cmd line arguments */
+ char *curarg; /* Current cmd line argument */
+ const char *ep; /* End of used data in conversion */
+ dk4_um_t um; /* Conversion result */
+ int i; /* Cmd line args still remaining */
+ int have_vers = 0; /* Flag: Have SNMP version */
+ int back = 1; /* Function result */
+ int res; /* Conversion result */
+
+ lfdarg = argv; i = argc;
+ lfdarg++; i--;
+ while (0 < i) {
+ curarg = *lfdarg;
+ if ('-' == *curarg) {
+ curarg++;
+ switch (*curarg) {
+ case '-' : {
+ curarg++;
+ switch ( dk4str8_array_index(long_options, curarg, 0) ) {
+ case 0: {
+ hvl |= 1;
+ } break;
+ case 1: {
+ hvl |= 2;
+ } break;
+ case 2: {
+ hvl |= 4;
+ } break;
+ }
+ } break;
+ case 'n' : {
+ grace = 0;
+ } break;
+ case 'v' : {
+ if (0 != have_vers) {
+ /* WARNING: Version redefined */
+ fputs(prmonsnmp_kw[2], stderr);
+ fputs(prmonsnmp_kw[37], stderr);
+ fflush(stderr);
+ }
+ have_vers = 1;
+ curarg++; curarg = dk4str8_start(curarg, NULL);
+ if (NULL == curarg) {
+ lfdarg++; i--;
+ if (0 < i) { curarg = *lfdarg; }
+ }
+ if (NULL != curarg) {
+ if (0 == set_snmp_version(curarg)) {
+ /* WARNING: Illegal SNMP version */
+ fputs(prmonsnmp_kw[2], stderr);
+ fputs(prmonsnmp_kw[38], stderr);
+ fputs(curarg, stderr);
+ fputs(prmonsnmp_kw[39], stderr);
+ fflush(stderr);
+ back = 0;
+ }
+ } else {
+ back = 0;
+ }
+ } break;
+ case 'c' : {
+ curarg++; curarg = dk4str8_start(curarg, NULL);
+ if (NULL == curarg) {
+ lfdarg++; i--;
+ if (0 < i) { curarg = *lfdarg; }
+ }
+ if (NULL != curarg) {
+ if (NULL != snmp_comm) {
+ /* WARNING: Community redefined */
+ fputs(prmonsnmp_kw[2], stderr);
+ fputs(prmonsnmp_kw[40], stderr);
+ fflush(stderr);
+ }
+ snmp_comm = curarg;
+ } else {
+ back = 0;
+ }
+ } break;
+ case 't' : {
+ curarg++; curarg = dk4str8_start(curarg, NULL);
+ if (NULL == curarg) {
+ lfdarg++; i--;
+ if (0 < i) { curarg = *lfdarg; }
+ }
+ if (NULL != curarg) {
+ ep = NULL;
+ res = dk4ma_input_c8_dec_dk4_um_t(&um, curarg, &ep, 1, NULL);
+ if (0 != res) {
+ timeout = um;
+ } else {
+ back = 0;
+ }
+ } else {
+ back = 0;
+ }
+ } break;
+ }
+ } else {
+ if (NULL != host_name) {
+ /* WARNING: Host name redefined */
+ fputs(prmonsnmp_kw[2], stderr);
+ fputs(prmonsnmp_kw[41], stderr);
+ fflush(stderr);
+ }
+ host_name = curarg;
+ }
+ if (0 < i) { lfdarg++; i--; }
+ }
+ if ((0 == hvl) && (NULL == host_name)) {
+ /* ERROR: Missing host name */
+ fputs(prmonsnmp_kw[2], stderr);
+ fputs(prmonsnmp_kw[42], stderr);
+ fflush(stderr);
+ back = 0;
+ }
+ return back;
+}
+
+
+/** Show a text paragraph on standard output.
+ @param txt Text to show.
+*/
+static
+void
+show_text(const char * const *txt)
+{
+ if (NULL != txt) {
+ while (NULL != *txt) {
+ fputs(*(txt++), stdout);
+ fputc('\n', stdout);
+ }
+ fflush(stdout);
+ }
+}
+
+
+
+/** Handle --help, --version, --license options.
+*/
+static
+void
+run_hvl(void)
+{
+ $? "+ run_hvl"
+ if (0 != (1 & hvl)) {
+ show_text(help_text);
+ }
+ if (0 != (2 & hvl)) {
+ fputs(version_text, stdout);
+ fputc('\n', stdout);
+ fflush(stdout);
+ }
+ if (0 != (4 & hvl)) {
+ show_text(license_text);
+ }
+ exval = EXIT_SUCCESS;
+ $? "- run_hvl"
+}
+
+
+
+#endif
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+int main(int argc, char *argv[])
+{
+#if DK4_HAVE_LIBNETSNMP && ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET))
+
+ /* +++++ Required libraries available */
+ dkChar blang[32];
+ dkChar breg[32];
+ struct snmp_session template;
+#if DK4_HAVE_SIGACTION
+#ifdef SIGPIPE
+ struct sigaction opipe;
+ struct sigaction npipe;
+#endif
+ struct sigaction oint;
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+#else
+#ifdef SIGPIPE
+ dk4_sig_handler_t *opipe = NULL;
+#endif
+ dk4_sig_handler_t *oterm = NULL;
+ dk4_sig_handler_t *oint = NULL;
+#endif
+ const size_t szblang = DK4_SIZEOF(blang,dkChar);
+ const size_t szbreg = DK4_SIZEOF(breg,dkChar);
+#if DK4_HAVE_SIGACTION
+ int pipe_set = 0;
+ int term_set = 0;
+ int int_set = 0;
+ int sig_i_f = 0;
+ int sig_r_f = 0;
+#endif
+ $!trace-init prmonsnmp.deb
+ $? "+ main"
+
+ /* Set signal handlers.
+ --------------------
+ */
+#if DK4_HAVE_SIGACTION
+#ifdef SIGPIPE
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ sig_i_f = 1;
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ /* ERROR: Failed to set up masked signal set for SIGPIPE */
+ sig_i_f = 1;
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ /* ERROR: Failed to set up signal handler for SIGPIPE */
+ sig_i_f = 1;
+ goto finished;
+ }
+ pipe_set = 1;
+#endif
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ sig_i_f = 1;
+ goto finished;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ /* ERROR: Failed to set up masked signal set for SIGTERM */
+ sig_i_f = 1;
+ goto finished;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ /* ERROR: Failed to set up signal handler for SIGTERM */
+ sig_i_f = 1;
+ goto finished;
+ }
+ term_set = 1;
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ sig_i_f = 1;
+ goto finished;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ /* ERROR: Failed to set up masked signal set for SIGINT */
+ sig_i_f = 1;
+ goto finished;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ /* ERROR: Failed to set up signal handler for SIGINT */
+ sig_i_f = 1;
+ goto finished;
+ }
+ int_set = 1;
+#else
+#ifdef SIGPIPE
+ opipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oint = sigset(SIGINT, sig_handler_int);
+ oterm = sigset(SIGTERM, sig_handler_term);
+#endif
+
+ /*
+ Retrieve encoding.
+ ------------------
+ */
+ if (0 == dk4loc_get_settings(blang, szblang, breg, szbreg, &encoding, NULL)) {
+ encoding = DK4_ENCODING_ASCII;
+ }
+ /* Process command line arguments.
+ -------------------------------
+ */
+ if (0 == process_command_line_arguments(argc, argv)) {
+ goto finished;
+ }
+
+ if (0 != hvl) {
+ run_hvl();
+ goto finished;
+ }
+
+ /* Set up SNMP and create session.
+ -------------------------------
+ */
+#if DK4_HAVE_SNMP_DISABLE_SYSLOG
+ $? ". disable syslog"
+ snmp_disable_syslog();
+#endif
+#if DK4_HAVE_SNMP_DISABLE_FILELOG
+ $? ". disable filelog"
+ snmp_disable_filelog();
+#endif
+#if DK4_HAVE_SNMP_DISABLE_STDERRLOG
+ $? ". disable stderrlog"
+ snmp_disable_stderrlog();
+#endif
+ init_snmp(prmonsnmp_kw[2]);
+ DK4_MEMRES(&template, sizeof(template));
+ snmp_sess_init(&template);
+ template.version = snmp_vers;
+ template.peername = host_name;
+ template.community = (unsigned char *)snmp_comm;
+ if (NULL == snmp_comm) {
+ template.community = (unsigned char *)(prmonsnmp_kw[3]);
+ }
+ template.community_len = strlen((char *)(template.community));
+ snmp_sess = snmp_open(&template);
+ if (NULL == snmp_sess) {
+ /* ERROR: Failed to open session */
+ fputs(prmonsnmp_kw[2], stderr);
+ fputs(prmonsnmp_kw[43], stderr);
+ fflush(stderr);
+ goto finished;
+ }
+
+ /* Run main loop.
+ --------------
+ */
+ exval = EXIT_SUCCESS;
+ run_main_loop();
+
+ /*
+ Cleanup.
+ --------
+ */
+ finished:
+ /*
+ Close SNMP session, if any.
+ */
+ /*
+ Restore signal handlers
+ */
+#if DK4_HAVE_SIGACTION
+ if (0 != sig_i_f) {
+ fputs(prmonsnmp_kw[2], stderr);
+ fputs(prmonsnmp_kw[45], stderr);
+ fflush(stderr);
+ }
+ if (0 != int_set) {
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ /* ERROR */
+ sig_r_f = 1;
+ }
+ }
+ if (0 != term_set) {
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ /* ERROR */
+ sig_r_f = 1;
+ }
+ }
+#ifdef SIGPIPE
+ if (0 != pipe_set) {
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ /* ERROR */
+ sig_r_f = 1;
+ }
+ }
+#endif
+ if (0 != sig_r_f) {
+ fputs(prmonsnmp_kw[2], stderr);
+ fputs(prmonsnmp_kw[44], stderr);
+ fflush(stderr);
+ }
+#else
+ if (NULL != oterm) { sigset(SIGTERM, oterm); }
+ if (NULL != oint ) { sigset(SIGINT, oint ); }
+#ifdef SIGPIPE
+ if (NULL != opipe) { sigset(SIGPIPE, opipe); }
+#endif
+#endif
+
+ $? "- main %d", exval
+ $!trace-end
+ /* ----- Required libraries available */
+
+#else
+/* if DK4_HAVE_LIBNETSNMP && ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET)) */
+ fputs(prmonsnmp_kw[2], stderr);
+ fputs(": ERROR: Required features missing!\n", stderr);
+#if !DK4_HAVE_LIBNETSNMP
+ fputs("Support for Net-SNMP required!\n", stderr);
+ fputs("http://sourceforge.net/projects/net-snmp\n", stderr);
+#endif
+#if !((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET))
+ fputs("Support for sigaction() or sigset() required but not found!\n",stderr);
+#endif
+ fflush(stderr);
+#endif
+/* if DK4_HAVE_LIBNETSNMP && ((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET)) */
+ exit(exval); return exval;
+}
+
+
diff --git a/support/dktools/resources/GNUmakefile b/support/dktools/resources/GNUmakefile
new file mode 100644
index 0000000000..0295552cde
--- /dev/null
+++ b/support/dktools/resources/GNUmakefile
@@ -0,0 +1,60 @@
+
+XPMS= \
+ ../choose-dir.xpm \
+ ../dkclock.xpm \
+ ../dkicon.xpm \
+ ../exit-program.xpm \
+ ../run2.xpm \
+ ../run-conversion.xpm \
+ ../set-options.xpm \
+ ../wxdkscrsz.xpm
+
+ICONS= \
+ ../dkclock.ico \
+ ../dkctinst.ico \
+ ../dkctunin.ico \
+ ../dkicon.ico \
+ ../wxdkscrsz.ico
+
+SPLASH= \
+ ../splash-dktoolian.png
+
+../%.xpm: %.fig
+ gxhconvert -o=xpm -a $*.fig
+ mv $*.xpm ..
+
+../%.ico: %.fig
+ gxhconvert -o=ico -a $*.fig
+ mv $*.ico ..
+
+build: # Create *.xpm and *.ico files
+build: $(XPMS) $(ICONS) $(SPLASH)
+ touch test.dat
+ [ ! -f ../favicon.ico ] || rm -f ../favicon.ico
+ ln ../dkicon.ico ../favicon.ico
+ rm -f test.dat *.ico *.xpm
+
+../splash-dktoolian.png: splash-dktoolian.fig
+ fig2lat -ltex.pdf splash-dktoolian.fig
+ pdflatex -interaction=batchmode splash-dktoolian || pdflatex -interaction=nonstopmode -halt-on-error -file-line-error splash-dktoolian
+ pdftoppm -r 160 splash-dktoolian.pdf | pnmtopng > splash-dktoolian.png
+ ls -l splash-dktoolian.png
+ pngnq -n 64 splash-dktoolian.png
+ mv splash-dktoolian-nq8.png splash-dktoolian.png
+ ls -l splash-dktoolian.png
+ optipng -q -zc1-9 -zm1-9 -zs0-3 -f0-5 splash-dktoolian.png
+ ls -l splash-dktoolian.png
+ mv splash-dktoolian.png ..
+ [ ! -f splash-dktoolian.aux ] || rm -fr splash-dktoolian.aux
+ [ ! -f splash-dktoolian.log ] || rm -fr splash-dktoolian.log
+ [ ! -f splash-dktoolian.pdf ] || rm -fr splash-dktoolian.pdf
+ [ ! -f splash-dktoolian-i.pdf ] || rm -fr splash-dktoolian-i.pdf
+ [ ! -f splash-dktoolian.tex ] || rm -fr splash-dktoolian.tex
+
+clean: # Clean up (remove *.xpm and *.ico files)
+clean:
+ -rm -f *.xpm *.ico *.aux *.png *.pgm *.pnm *.ppm *.pdf *.svg *.log *.tex
+
+help: # Show targets in GNUmakefile
+ @echo 'Here is a list of the targets in this GNUmakefile:'
+ -@egrep '^[^:;= ]*::?[ ]*' GNUmakefile|grep '#'|grep -v '^#'
diff --git a/support/dktools/resources/choose-dir.fig b/support/dktools/resources/choose-dir.fig
new file mode 100644
index 0000000000..e8b2326ed3
--- /dev/null
+++ b/support/dktools/resources/choose-dir.fig
@@ -0,0 +1,20 @@
+#FIG 3.2
+Portrait
+Center
+Inches
+A4
+100.0
+Single
+-2
+1200 2
+2 2 0 0 7 7 999 1 -1 1.00 0 0 0 0 0 5
+ 0 0 1200 0 1200 1125 0 1125 0 0
+2 3 0 3 0 31 101 1 20 1.00 0 0 12 0 0 5
+ 975 150 975 300 525 300 675 150
+ 975 150
+2 3 0 3 0 31 101 1 20 0 0 0 12 0 0 7
+ 975 150 825 300 150 300 150 975
+ 1050 975 1050 150 975 150
+2 3 0 3 0 31 100 1 20 0 0 0 12 0 0 5
+ 675 150 525 300 225 300 375 150
+ 675 150
diff --git a/support/dktools/resources/dkclock.fig b/support/dktools/resources/dkclock.fig
new file mode 100644
index 0000000000..b31b98ea3e
--- /dev/null
+++ b/support/dktools/resources/dkclock.fig
@@ -0,0 +1,27 @@
+#FIG 3.2 Produced by xfig version 3.2.5a
+Portrait
+Center
+Inches
+A4
+100.00
+Single
+-2
+1200 2
+1 1 0 1 0 0 97 1 20 6.400 1 0.0000 210 375 75 75 135 300 285 450
+1 1 0 1 0 0 97 1 20 6.400 1 0.0000 150 600 75 75 75 525 225 675
+1 1 0 1 0 0 97 1 20 6.400 1 0.0000 210 825 75 75 135 750 285 900
+1 1 0 1 0 0 97 1 20 6.400 1 0.0000 375 989 75 75 300 914 450 1064
+1 1 0 1 0 0 97 1 20 6.400 1 0.0000 600 1050 75 75 525 975 675 1125
+1 1 0 1 0 0 97 1 20 6.400 1 0.0000 825 989 75 75 750 914 900 1064
+1 1 0 1 0 0 97 1 20 6.400 1 0.0000 989 825 75 75 914 750 1064 900
+1 1 0 1 0 0 97 1 20 6.400 1 0.0000 1050 600 75 75 975 525 1125 675
+1 1 0 1 0 0 97 1 20 6.400 1 0.0000 989 375 75 75 914 300 1064 450
+1 1 0 1 0 0 97 1 20 6.400 1 0.0000 825 210 75 75 750 135 900 285
+1 1 0 1 0 0 97 1 20 6.400 1 0.0000 600 150 75 75 525 75 675 225
+1 1 0 1 0 0 97 1 20 6.400 1 0.0000 375 210 75 75 300 135 450 285
+2 2 0 0 31 31 999 1 20 1.000 0 0 0 0 0 5
+ 0 0 1200 0 1200 1200 0 1200 0 0
+2 1 0 8 0 0 100 1 -1 0.000 0 1 12 0 0 2
+ 600 300 600 600
+2 1 0 8 0 0 100 1 -1 0.000 0 1 12 0 0 2
+ 750 600 600 600
diff --git a/support/dktools/resources/dkctinst.fig b/support/dktools/resources/dkctinst.fig
new file mode 100644
index 0000000000..9f0d368117
--- /dev/null
+++ b/support/dktools/resources/dkctinst.fig
@@ -0,0 +1,13 @@
+#FIG 3.2
+Portrait
+Center
+Inches
+A4
+100.0
+Single
+-2
+1200 2
+2 2 0 0 14 14 101 1 20 1.00 0 0 0 0 0 5
+ 0 0 1200 0 1200 1200 0 1200 0 0
+4 2 0 100 1 30 42.0 0.0 4 833.0 616.0 562 525 D\001
+4 0 0 100 1 30 42.0 0.0 4 833.0 616.0 637 1087 K\001
diff --git a/support/dktools/resources/dkctunin.fig b/support/dktools/resources/dkctunin.fig
new file mode 100644
index 0000000000..77a98659fb
--- /dev/null
+++ b/support/dktools/resources/dkctunin.fig
@@ -0,0 +1,13 @@
+#FIG 3.2
+Portrait
+Center
+Inches
+A4
+100.0
+Single
+-2
+1200 2
+2 2 0 0 4 4 101 1 20 1.00 0 0 0 0 0 5
+ 0 0 1200 0 1200 1200 0 1200 0 0
+4 2 0 100 1 30 42.0 0.0 4 833.0 616.0 562 525 D\001
+4 0 0 100 1 30 42.0 0.0 4 833.0 616.0 637 1087 K\001
diff --git a/support/dktools/resources/dkicon.fig b/support/dktools/resources/dkicon.fig
new file mode 100644
index 0000000000..5e6a6ed94a
--- /dev/null
+++ b/support/dktools/resources/dkicon.fig
@@ -0,0 +1,13 @@
+#FIG 3.2
+Portrait
+Center
+Inches
+A4
+100.0
+Single
+-2
+1200 2
+2 2 0 0 31 31 101 1 20 0 0 0 0 0 0 5
+ 0 0 1200 0 1200 1200 0 1200 0 0
+4 2 0 100 1 30 42.0 0.0 4 833.0 617.0 637 600 D\001
+4 0 0 100 1 30 42.0 0.0 4 833.0 616.0 637 1087 K\001
diff --git a/support/dktools/resources/exit-program.fig b/support/dktools/resources/exit-program.fig
new file mode 100644
index 0000000000..d74c8bab7f
--- /dev/null
+++ b/support/dktools/resources/exit-program.fig
@@ -0,0 +1,18 @@
+#FIG 3.2
+Portrait
+Center
+Inches
+A4
+100.0
+Single
+-2
+1200 2
+2 2 0 0 7 7 999 1 -1 6.40 0 0 0 0 0 5
+ 0 0 1200 0 1200 1125 0 1125 0 0
+2 2 0 0 7 7 103 1 20 6.40 0 0 0 0 0 5
+ 300 150 900 150 900 975 300 975 300 150
+2 3 0 0 20 20 100 1 20 6.40 0 0 12 0 0 5
+ 300 150 675 150 675 750 300 975
+ 300 150
+2 2 0 3 0 0 100 1 -1 6.40 0 0 0 0 0 5
+ 300 150 900 150 900 975 300 975 300 150
diff --git a/support/dktools/resources/favicon.fig b/support/dktools/resources/favicon.fig
new file mode 100644
index 0000000000..5e6a6ed94a
--- /dev/null
+++ b/support/dktools/resources/favicon.fig
@@ -0,0 +1,13 @@
+#FIG 3.2
+Portrait
+Center
+Inches
+A4
+100.0
+Single
+-2
+1200 2
+2 2 0 0 31 31 101 1 20 0 0 0 0 0 0 5
+ 0 0 1200 0 1200 1200 0 1200 0 0
+4 2 0 100 1 30 42.0 0.0 4 833.0 617.0 637 600 D\001
+4 0 0 100 1 30 42.0 0.0 4 833.0 616.0 637 1087 K\001
diff --git a/support/dktools/resources/run-conversion.fig b/support/dktools/resources/run-conversion.fig
new file mode 100644
index 0000000000..8561402a37
--- /dev/null
+++ b/support/dktools/resources/run-conversion.fig
@@ -0,0 +1,13 @@
+#FIG 3.2
+Portrait
+Center
+Inches
+A4
+100.0
+Single
+-2
+1200 2
+2 2 0 0 7 7 999 1 -1 0 0 0 0 0 0 5
+ 0 0 1200 0 1200 1125 0 1125 0 0
+2 3 0 1 12 12 100 1 20 1.00 0 0 12 0 0 4
+ 150 150 1050 600 150 975 150 150
diff --git a/support/dktools/resources/run2.fig b/support/dktools/resources/run2.fig
new file mode 100644
index 0000000000..962549007a
--- /dev/null
+++ b/support/dktools/resources/run2.fig
@@ -0,0 +1,13 @@
+#FIG 3.2
+Portrait
+Center
+Inches
+A4
+100.0
+Single
+-2
+1200 2
+2 2 0 0 7 7 999 1 -1 0 0 0 0 0 0 5
+ 0 0 1200 0 1200 1200 0 1200 0 0
+2 3 0 1 12 12 100 1 20 0 0 0 12 0 0 4
+ 75 75 1125 600 75 1125 75 75
diff --git a/support/dktools/resources/set-options.fig b/support/dktools/resources/set-options.fig
new file mode 100644
index 0000000000..3be4a5be9a
--- /dev/null
+++ b/support/dktools/resources/set-options.fig
@@ -0,0 +1,15 @@
+#FIG 3.2
+Portrait
+Center
+Inches
+A4
+100.0
+Single
+-2
+1200 2
+2 2 0 0 7 7 999 1 -1 1.00 0 0 0 0 0 5
+ 0 0 1200 0 1200 1125 0 1125 0 0
+2 2 0 3 0 0 100 1 5 0 0 0 0 0 0 5
+ 300 300 900 300 900 900 300 900 300 300
+2 1 0 5 12 0 99 1 -1 0 0 0 12 0 0 3
+ 225 525 600 975 1050 150
diff --git a/support/dktools/resources/splash-dktoolian.fig b/support/dktools/resources/splash-dktoolian.fig
new file mode 100644
index 0000000000..a778832a8b
--- /dev/null
+++ b/support/dktools/resources/splash-dktoolian.fig
@@ -0,0 +1,20 @@
+#FIG 3.2
+Portrait
+Center
+Inches
+A4
+100.0
+Single
+-2
+1200 2
+2 2 0 0 0 0 104 1 8 0 0 0 0 0 0 5
+ 0 0 4800 0 4800 3600 0 3600 0 0
+2 2 0 0 0 0 103 1 12 0 0 0 0 0 0 5
+ 75 75 4725 75 4725 3525 75 3525 75 75
+2 2 0 0 0 0 102 1 16 0 0 0 0 0 0 5
+ 150 150 4650 150 4650 3450 150 3450 150 150
+2 2 0 0 0 0 101 1 20 0 0 0 0 0 0 5
+ 225 225 4575 225 4575 3375 225 3375 225 225
+4 1 31 100 1 28 12.0 0.0 4 250.0 4533.0 2400 750 Debian GNU/Linux based rescue live system\001
+4 1 31 100 1 28 12.0 0.0 4 250.0 1900.0 2400 975 including DK tools\001
+4 1 31 100 1 30 18.0 0.0 4 366.0 1716.0 2400 525 DKtoolian\001
diff --git a/support/dktools/resources/toolbase.fig b/support/dktools/resources/toolbase.fig
new file mode 100644
index 0000000000..27dd122d66
--- /dev/null
+++ b/support/dktools/resources/toolbase.fig
@@ -0,0 +1,14 @@
+#FIG 3.2
+Portrait
+Center
+Inches
+A4
+100.0
+Single
+-2
+1200 2
+2 2 0 0 4 4 999 1 20 1.00 0 0 0 0 0 5
+ 0 37 600 37 600 600 0 600 0 37
+5 1 0 5 0 0 100 1 -1 0 0 1 0 0 300.0 330.0 225 150 300 525 375 150
+2 1 0 5 0 0 100 1 -1 0 0 0 12 0 0 2
+ 300 75 300 290
diff --git a/support/dktools/resources/wxdkscrsz.fig b/support/dktools/resources/wxdkscrsz.fig
new file mode 100644
index 0000000000..951aaec89e
--- /dev/null
+++ b/support/dktools/resources/wxdkscrsz.fig
@@ -0,0 +1,25 @@
+#FIG 3.2
+Portrait
+Center
+Inches
+A4
+100.0
+Single
+-2
+1200 2
+0 32 #c0c0c0
+2 2 0 0 31 31 999 1 20 0 0 0 0 0 0 5
+ 1200 1200 2400 1200 2400 2400 1200 2400 1200 1200
+2 2 0 3 7 0 100 1 -1 0 0 0 0 0 0 5
+ 1275 1537 2325 1537 2325 2100 1275 2100 1275 1537
+2 2 0 3 7 0 100 1 -1 0 0 0 0 0 0 5
+ 1275 1687 2025 1687 2025 2100 1275 2100 1275 1687
+4 1 0 100 1 30 18.0 0.0 4 336.0 496.0 1650 2006 DK\001
+2 2 1 3 32 0 99 1 -1 6.40 0 0 0 0 0 5
+ 1275 1687 2025 1687 2025 2100 1275 2100 1275 1687
+2 2 1 3 32 0 99 1 -1 6.40 0 0 0 0 0 5
+ 1275 1537 2325 1537 2325 2100 1275 2100 1275 1537
+2 1 0 2 0 0 95 1 -1 1.00 0 0 12 1 1 2
+ 1 1 1.0 24.00 48.00
+ 1 1 1.0 24.00 48.00
+ 2025 1687 2325 1537
diff --git a/support/dktools/rshdown.c b/support/dktools/rshdown.c
new file mode 100644
index 0000000000..9b9ef33dd5
--- /dev/null
+++ b/support/dktools/rshdown.c
@@ -0,0 +1,2789 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: rshdown.ctr
+*/
+
+/*
+Copyright (C) 2016-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file rshdown.c The rshdown module.
+*/
+
+
+#line 9 "rshdown.ctr"
+
+/*
+ rshdown -s [-n _number_] [-l _port_] [-b] _address_ _port_ _file_
+ rshdown [-c _configfile_]
+
+ Either send shutdown packages (-s option used)
+ or run as daemon in background (no -s option)
+ and wait for shutdown packages.
+
+ Sending:
+
+ -n _number_ Number of packages to send
+
+ -l _port_ Local port number to use
+ Default: Same as remote port
+
+ -b Flag: Destination address is a broadcast address
+
+ _address_ Destination address (hostname or IP address)
+
+ _port_ Port number on destination host
+
+ _file_ File containing data to send
+
+ Daemon:
+
+ -c _configfile_ Configuration file.
+
+*/
+
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+
+#include <stdio.h>
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if (DK4_CHAR_SIZE == 1) \
+ && (DK4_HAVE_SIGACTION || DK4_HAVE_SIGSET) \
+ && (DK4_HAVE_SETSID || DK4_HAVE_SETPGRP)
+
+#if DK4_HAVE_MATH_H
+#ifndef MATH_H_INCLUDED
+#include <math.h>
+#define MATH_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYSLOG_H
+#ifndef SYSLOG_H_INCLUDED
+#include <syslog.h>
+#define SYSLOG_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4mem.h"
+#include "dk4memrs.h"
+#include "dk4opt.h"
+#include "dk4mai8dus.h"
+#include "dk4mai8dii.h"
+#include "dk4fopt.h"
+#include "dk4fopc8.h"
+#include "dk4isadm.h"
+#include "dk4sock.h"
+#include "dk4inst.h"
+#include "dk4str8.h"
+#include "dk4mpl.h"
+#include "dk4dmt.h"
+#include "dk4vers.h"
+
+
+
+
+
+#line 131 "rshdown.ctr"
+
+
+
+#ifndef RSHDOWN_BUFFER_SIZE
+/** Buffer size, should not exceed UDP packet size.
+*/
+#define RSHDOWN_BUFFER_SIZE 1460
+#endif
+
+
+
+/** Path name of data file.
+*/
+static char file_name[DK4_MAX_PATH];
+
+
+
+/** Send and receive buffer.
+*/
+static char b1[RSHDOWN_BUFFER_SIZE];
+
+
+/** Buffer for local secret from file in daemon.
+*/
+static char b2[sizeof(b1)];
+
+
+/** Command to execute on packet arrival.
+*/
+static char cmd[1024];
+
+
+/** Allowed sender peer as text.
+*/
+static char asender[1024];
+
+
+/** Options used by the program.
+*/
+static dk4_option_t options[] = {
+
+ /* 0 Configuration file.
+ */
+ { { dkT('c'), dkT("config"), DK4_OPT_ARG_STRING }, { NULL }, 0 },
+
+ /* 1 Send data.
+ */
+ { { dkT('s'), dkT("send"), DK4_OPT_ARG_NONE }, { NULL }, 0 },
+
+ /* 2 Destination address is a broadcast address.
+ */
+ { { dkT('b'), dkT("broadcast"), DK4_OPT_ARG_NONE }, { NULL }, 0 },
+
+ /* 3 Number of packets to send.
+ */
+ { { dkT('n'), dkT("number"), DK4_OPT_ARG_UNSIGNED}, { NULL }, 0 },
+
+ /* 4 Local port number.
+ */
+ { { dkT('l'), dkT("local"), DK4_OPT_ARG_UNSIGNED}, { NULL }, 0},
+
+ /* 5 Help.
+ */
+ { { dkT('\0'),dkT("help"), DK4_OPT_ARG_NONE}, { NULL }, 0},
+
+ /* 6 Version.
+ */
+ { { dkT('\0'),dkT("version"), DK4_OPT_ARG_NONE}, { NULL }, 0},
+
+ /* 7 License
+ */
+ { { dkT('\0'),dkT("license"), DK4_OPT_ARG_NONE}, { NULL }, 0}
+};
+
+
+
+/** Help text.
+*/
+static const char * const help_text[] = {
+"",
+"Remote shutdown sender and recipient",
+"",
+"rshdown [-c config]",
+"rshdown -s [-n number] [-l port] [-b] host port file",
+"",
+"-c config\t\tConfiguration file for recipient (daemon).",
+"",
+"-s\t\t\tSend shutdown data packet.",
+"-n number\t\tSend packet multiple times.",
+"-l port\t\t\tLocal port to use for sending.",
+"-b\t\t\tPrepare socket for broadcast sending.",
+"host\t\t\tRemote host (recipient), host name or IP address.",
+"\t\t\tOption -b is required if you specify a broadcast",
+"\t\t\taddress like 255.255.255.255 or 192.0.2.255 here.",
+"port\t\t\tRemote port.",
+"file\t\t\tFile containing pre-shared secret (shutdown data).",
+"",
+"--help\t\t\tShow this help text.",
+"--version\t\tShow version number.",
+"--license\t\tShow license information.",
+"",
+NULL
+
+
+#line 234 "rshdown.ctr"
+};
+
+
+
+/** License conditions text.
+*/
+static const char * const license_text[] = {
+"",
+"This software uses code from the following projects, either directly or as",
+"a library:",
+"",
+"dktools\t\tDirk Krause's tools and libraries.",
+"\t\tSee http://dktools.sourceforge.net/ for more information.",
+"",
+"DK tools and libraries license",
+"==============================",
+"Copyright (c) 2015-2016, Dirk Krause",
+"All rights reserved.",
+"",
+"Redistribution and use in source and binary forms, with or without",
+"modification, are permitted provided that the following conditions are met:",
+"",
+"* Redistributions of source code must retain the above copyright notice,",
+" this list of conditions and the following disclaimer.",
+"* Redistributions in binary form must reproduce the above copyright",
+" notice, this list of conditions and the following disclaimer in the",
+" documentation and/or other materials provided with the distribution.",
+"* Neither the name of the Dirk Krause nor the names of contributors may be",
+" used to endorse or promote products derived from this software without",
+" specific prior written permission.",
+"",
+"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"",
+"AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE",
+"IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE",
+"ARE DISCLAIMED.",
+"",
+"IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,",
+"INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,",
+"BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,",
+"DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY",
+"OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING",
+"NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,",
+"EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.",
+"",
+NULL
+
+
+#line 280 "rshdown.ctr"
+};
+
+
+
+/** Version information.
+*/
+static const char version_text[] = { DKT_VERSION_C8 };
+
+
+
+/** Default configuration file name.
+*/
+static const char def_conf_name[] = {
+ DK4_INST_DIR_ETC "/rshdown/rshdown.conf"
+};
+
+
+
+/** PID file name.
+*/
+static const char pid_file_name[] = {
+ DK4_INST_DIR_VAR "/run/rshdown.pid"
+};
+
+
+
+/** Key names expected in configuration file.
+*/
+static const char * const key_names[] = {
+/* 0 */
+"sender",
+
+/* 1 */
+"sender port",
+
+/* 2 */
+"receiver port",
+
+/* 3 */
+"signal",
+
+/* 4 */
+"command",
+
+/* 5 */
+"file",
+
+/* 6 */
+"debug",
+
+/* 7 */
+"syslog facility",
+
+NULL
+
+
+#line 343 "rshdown.ctr"
+};
+
+
+
+/** Signal names.
+*/
+static const char * const signal_names[] = {
+/* 0 */
+"sighup",
+
+/* 1 */
+"hup",
+
+/* 2 */
+"sigint",
+
+/* 3 */
+"int",
+
+/* 4 */
+"sigquit",
+
+/* 5 */
+"quit",
+
+/* 6 */
+"sigill",
+
+/* 7 */
+"ill",
+
+/* 8 */
+"sigtrap",
+
+/* 9 */
+"trap",
+
+/* 10 */
+"sigabrt",
+
+/* 11 */
+"abrt",
+
+/* 12 */
+"sigiot",
+
+/* 13 */
+"iot",
+
+/* 14 */
+"sigbus",
+
+/* 15 */
+"bus",
+
+/* 16 */
+"sigfpe",
+
+/* 17 */
+"fpe",
+
+/* 18 */
+"sigkill",
+
+/* 19 */
+"kill",
+
+/* 20 */
+"sigusr1",
+
+/* 21 */
+"usr1",
+
+/* 22 */
+"sigsegv",
+
+/* 23 */
+"segv",
+
+/* 24 */
+"sigusr2",
+
+/* 25 */
+"usr2",
+
+/* 26 */
+"sigpipe",
+
+/* 27 */
+"pipe",
+
+/* 28 */
+"sigalrm",
+
+/* 29 */
+"alrm",
+
+/* 30 */
+"sigterm",
+
+/* 31 */
+"term",
+
+/* 32 */
+"sigstkflt",
+
+/* 33 */
+"stkflt",
+
+/* 34 */
+"sigcld",
+
+/* 35 */
+"cld",
+
+/* 36 */
+"sigchld",
+
+/* 37 */
+"chld",
+
+/* 38 */
+"sigcont",
+
+/* 39 */
+"cont",
+
+/* 40 */
+"sigstop",
+
+/* 41 */
+"stop",
+
+/* 42 */
+"sigtstp",
+
+/* 43 */
+"tstp",
+
+/* 44 */
+"sigttin",
+
+/* 45 */
+"ttin",
+
+/* 46 */
+"sigttou",
+
+/* 47 */
+"ttou",
+
+/* 48 */
+"sigurg",
+
+/* 49 */
+"urg",
+
+/* 50 */
+"sigxcpu",
+
+/* 51 */
+"xcpu",
+
+/* 52 */
+"sigxfsz",
+
+/* 53 */
+"xfsz",
+
+/* 54 */
+"sigvtalrm",
+
+/* 55 */
+"vtalrm",
+
+/* 56 */
+"sigprof",
+
+/* 57 */
+"prof",
+
+/* 58 */
+"sigwinch",
+
+/* 59 */
+"winch",
+
+/* 60 */
+"sigpoll",
+
+/* 61 */
+"poll",
+
+/* 62 */
+"sigio",
+
+/* 63 */
+"io",
+
+/* 64 */
+"sigpwr",
+
+/* 65 */
+"pwr",
+
+/* 66 */
+"sigsys",
+
+/* 67 */
+"sys",
+
+NULL
+
+
+#line 453 "rshdown.ctr"
+};
+
+
+
+/** Syslog facility names.
+*/
+static const char * const syslog_facility_names[] = {
+/* 0 */
+"auth",
+
+/* 1 */
+"authpriv",
+
+/* 2 */
+"cron",
+
+/* 3 */
+"daemon",
+
+/* 4 */
+"ftp",
+
+/* 5 */
+"kern",
+
+/* 6 */
+"lpr",
+
+/* 7 */
+"mail",
+
+/* 8 */
+"news",
+
+/* 9 */
+"security",
+
+/* 10 */
+"syslog",
+
+/* 11 */
+"user",
+
+/* 12 */
+"uucp",
+
+/* 13 */
+"local0",
+
+/* 14 */
+"local1",
+
+/* 15 */
+"local2",
+
+/* 16 */
+"local3",
+
+/* 17 */
+"local4",
+
+/* 18 */
+"local5",
+
+/* 19 */
+"local6",
+
+/* 20 */
+"local7",
+
+NULL
+
+
+#line 483 "rshdown.ctr"
+};
+
+
+/** Texts used by the program, not localized.
+*/
+static const char * const rshdown_kw[] = {
+/* 0 */
+"rshdown",
+
+/* 1 */
+": ",
+
+/* 2 */
+"ERROR: Failed to set broadcast mode on socket!\n",
+
+/* 3 */
+"ERROR: Failed to bind local address!\n",
+
+/* 4 */
+"ERROR: Failed to bind local address: \"",
+
+/* 5 */
+"\"!\n",
+
+/* 6 */
+"ERROR: Failed to create socket!\n",
+
+/* 7 */
+"ERROR: Failed to find address for: \"",
+
+/* 8 */
+"\"!\n",
+
+/* 9 */
+"ERROR: Failed to bring socket subsystem up!\n",
+
+/* 10 */
+"ERROR: 3 arguments required: host, port and file!\n",
+
+/* 11 */
+"ERROR: Not a 16 bit unsigned integer: \"",
+
+/* 12 */
+"\"!\n",
+
+/* 13 */
+"ERROR: Port number 0 is not allowed!\n",
+
+/* 14 */
+"ERROR: Failed to open data file:\n\"",
+
+/* 15 */
+"\"!\n",
+
+/* 16 */
+"ERROR: Failed to read data from file:\n\"",
+
+/* 17 */
+"\"!\n",
+
+/* 18 */
+"ERROR: Failed to install signal handlers!\n",
+
+/* 19 */
+"ERROR: Failed to restore signal handlers!\n",
+
+/* 20 */
+"ERROR: Failed to create child process!\n",
+
+/* 21 */
+"Failed to detach from terminal!",
+
+/* 22 */
+"Failed to create child process!",
+
+/* 23 */
+"Failed to install signal handlers!",
+
+/* 24 */
+"Failed to restore signal handlers!",
+
+/* 25 */
+"Failed to bring socket subsystem up!",
+
+/* 26 */
+"Failed to create UDP socket set!",
+
+/* 27 */
+"ERROR: Local port number too large!\n",
+
+/* 28 */
+"ERROR: Local port number must not be 0!\n",
+
+/* 29 */
+"Failed to set allowed peer: \"",
+
+/* 30 */
+"\"!",
+
+/* 31 */
+"ERROR: Illegal signal name: \"",
+
+/* 32 */
+"\"!\n",
+
+/* 33 */
+"ERROR: Sender name too long:\n",
+
+/* 34 */
+"\"!\n",
+
+/* 35 */
+"ERROR: Sender name defined multiple times!\n",
+
+/* 36 */
+"ERROR: Signal number must be positive!\n",
+
+/* 37 */
+"ERROR: Command too long:\n\"",
+
+/* 38 */
+"\"!\n",
+
+/* 39 */
+"ERROR: Command defined multiple times!\n",
+
+/* 40 */
+"ERROR: File name too long:\n\"",
+
+/* 41 */
+"\"!\n",
+
+/* 42 */
+"ERROR: File name defined multiple times!\n",
+
+/* 43 */
+"ERROR: Unknown key in configuration file!\n",
+
+/* 44 */
+"ERROR: Missing value on configuration line!\n",
+
+/* 45 */
+"ERROR: No local port specified!\n",
+
+/* 46 */
+"ERROR: Signal number or command required!\n",
+
+/* 47 */
+"ERROR: No data file specified!\n",
+
+/* 48 */
+"ERROR: Illegal syslog facility: \"",
+
+/* 49 */
+"\"!\n",
+
+/* 50 */
+"Service started.",
+
+/* 51 */
+"Initiate shutdown.",
+
+/* 52 */
+"Service finished.",
+
+/* 53 */
+"Packet from \"",
+
+/* 54 */
+"\" discarded, wrong sender address!",
+
+/* 55 */
+"Packet from \"",
+
+/* 56 */
+"\" discarded, wrong sender port!",
+
+/* 57 */
+"Packet from \"",
+
+/* 58 */
+"\" discarded, size mismatch!",
+
+/* 59 */
+"Packet from \"",
+
+/* 60 */
+"\" discarded, data mismatch!",
+
+/* 61 */
+"Failed to execute command: \"",
+
+/* 62 */
+"\"!",
+
+NULL
+
+
+#line 689 "rshdown.ctr"
+};
+
+
+
+/** Number of options in the options array.
+*/
+static const size_t szoptions = sizeof(options)/sizeof(dk4_option_t);
+
+
+
+/** Number of bytes in buffer b1.
+*/
+static size_t szb1 = 0;
+
+
+
+/** Number of bytes in buffer b2.
+*/
+static size_t szb2 = 0;
+
+
+
+/** Exit status code.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+/** Options: Help (1), version (2), license (4).
+*/
+static int hvl = 0;
+
+
+
+/** Flag: Additional debug messages.
+*/
+static int debug = 0;
+
+
+
+#ifdef LOG_DAEMON
+/** Syslog facility.
+*/
+static int syslogf = LOG_AUTH;
+#else
+/** Syslog facility.
+*/
+static int syslogf = (3<<3);
+#endif
+
+
+
+/** Signal to send on arrival of shutdown data packet.
+*/
+static int signo =
+#ifdef SIGPWR
+SIGPWR
+#else
+#ifdef SIGTERM
+SIGTERM
+#else
+15
+#endif
+#endif
+;
+
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+/** Remote port.
+*/
+static unsigned short rp = 0U;
+
+
+
+/** Local port.
+*/
+static unsigned short lp = 0U;
+
+
+/** Pass pointer through.
+ Use of this function is recommended by CERT C coding standard
+ to avoid optimizing out.
+ @param ptr Pointer to pass through.
+ @return The ptr argument.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+
+/** Check whether we can continue or must abort due to signal.
+ @param dopipe Flag: Check for SIGPIPE too.
+ @return 1 if we can continue, 0 otherwise.
+*/
+static
+int
+can_continue(void)
+{
+ int back = 1;
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_int)) { back = 0; }
+ return back;
+}
+
+
+
+/** Write log message to stderr, 1 component.
+ @param i Text index in rshdown_kw array.
+*/
+static
+void
+log_1(size_t i)
+{
+ fputs(rshdown_kw[0], stderr);
+ fputs(rshdown_kw[1], stderr);
+ fputs(rshdown_kw[i], stderr);
+ fflush(stderr);
+}
+
+
+
+/** Write syslog message, 1 component.
+ @param i Index of text in rshdown_kw array.
+*/
+static
+void
+syslog_1(size_t i)
+{
+#if DK4_HAVE_SYSLOG
+ openlog(rshdown_kw[0], LOG_PID, syslogf);
+ syslog(LOG_ERR, "%s", rshdown_kw[i]);
+ closelog();
+#endif
+}
+
+
+
+/** Write syslog message, 3 components.
+ @param i1 Index of first component in rshdown_kw array.
+ @param i2 Index of third component in rshdown_kw array.
+ @param str Second component.
+*/
+static
+void
+syslog_3(size_t i1, size_t i2, const char *str)
+{
+#if DK4_HAVE_SYSLOG
+ openlog(rshdown_kw[0], LOG_PID, syslogf);
+ if (NULL != str) {
+ syslog(LOG_ERR, "%s%s%s", rshdown_kw[i1], str, rshdown_kw[i2]);
+ } else {
+ syslog(LOG_ERR, "%s%s", rshdown_kw[i1], rshdown_kw[i2]);
+ }
+ closelog();
+#endif
+}
+
+
+
+/** Write an additional debug message to syslog.
+ @param i1 Index of first component in rshdown_kw array.
+ @param i2 Index of third component in rshdown_kw array.
+ @param sa Socket address, second component.
+*/
+static
+void
+syslog_debug(size_t i1, size_t i2, dk4_sockaddr_storage_t *sa)
+{
+#if DK4_HAVE_SYSLOG
+ char buf[128]; /* Buffer for text respresentation of address */
+ int res; /* Operation result from conversion */
+
+ if (0 != debug) {
+ res = dk4socket_c8_sockaddr_to_text(buf, sizeof(buf), sa, NULL);
+ openlog(rshdown_kw[0], LOG_PID, syslogf);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ syslog(LOG_DEBUG, "%s%s%s", rshdown_kw[i1], buf, rshdown_kw[i2]);
+ } else {
+ syslog(LOG_DEBUG, "%s%s", rshdown_kw[i1], rshdown_kw[i2]);
+ }
+ closelog();
+ }
+#endif
+}
+
+
+
+/** Write log message to stderr, 3 components.
+ @param i1 Index of first component in rshdown_kw array.
+ @param i2 Index of third component in rshdown_kw array.
+ @param str Second component.
+*/
+static
+void
+log_3(size_t i1, size_t i2, const char *str)
+{
+ fputs(rshdown_kw[0], stderr);
+ fputs(rshdown_kw[1], stderr);
+ fputs(rshdown_kw[i1], stderr);
+ if (NULL != str) { fputs(str, stderr); }
+ fputs(rshdown_kw[i2], stderr);
+ fflush(stderr);
+}
+
+
+
+/** Send buffer over network.
+ @param hn Remote host name or IP address as text.
+ @param rp Remote port in host representation.
+ @param lp Local port in host representation.
+ @param sz Number of bytes in b1.
+*/
+static
+void
+send_network(const char *hn, size_t sz)
+{
+ char adbuf[128]; /* Address as text */
+ dk4_sockaddr_storage_t array[2]; /* Address pair */
+ dk4_um_t num = (dk4_um_t)0UL;
+ size_t szr = 0; /* Rem addr size */
+ size_t szl = 0; /* Loc addr size */
+ size_t lgt = 0; /* Length sent */
+ dk4_socket_t sock = INVALID_SOCKET;
+ int res = 0; /* Operation result */
+ int ip4 = 0; /* IPv4 preferred */
+ int af = AF_UNSPEC;
+ int pf = PF_UNSPEC;
+
+
+#line 995 "rshdown.ctr"
+ if (DK4_SOCKET_RESULT_SUCCESS == dk4socket_up(NULL)) {
+ if (options[2].found) { ip4 = 1; }
+
+#line 997 "rshdown.ctr"
+ res = dk4socket_c8_udp_addresses_numeric(array, hn, rp, lp, ip4, NULL);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+
+#line 999 "rshdown.ctr"
+ szr = dk4socket_address_size(array);
+ szl = dk4socket_address_size(&(array[1]));
+ af = dk4socket_address_family(&(array[1]));
+ pf = dk4socket_pf_for_af(af);
+ if ((0 < szr) && (0 < szl) && (AF_UNSPEC != af) && (PF_UNSPEC != pf)) {
+ sock = dk4socket_open(pf, SOCK_DGRAM, 0, NULL);
+ if (INVALID_SOCKET != sock) {
+
+#line 1006 "rshdown.ctr"
+ exval = EXIT_SUCCESS;
+ (void)dk4socket_option_set_reuse(sock, 1, NULL);
+ if (options[2].found) {
+
+#line 1009 "rshdown.ctr"
+ res = dk4socket_option_set_broadcast(sock,1,NULL);
+ if (DK4_SOCKET_RESULT_SUCCESS != res) {
+ /* ERROR: Failed to set broadcast mode */
+ log_1(2);
+ exval = EXIT_FAILURE;
+
+#line 1014 "rshdown.ctr"
+ }
+ }
+ res = dk4socket_bind(
+ sock, (struct sockaddr *)(&(array[1])), szl, NULL
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+
+#line 1020 "rshdown.ctr"
+ if (0 != options[3].found) { num = options[3].val.u; }
+ if ((dk4_um_t)0UL == num) { num = (dk4_um_t)1UL; }
+ while ((0 != can_continue()) && ((dk4_um_t)0UL < num--)) {
+ lgt = sz;
+
+#line 1024 "rshdown.ctr"
+ res = dk4socket_sendto(
+ sock, b1, &lgt, 0,
+ (struct sockaddr *)(&(array[0])), szr,
+ 0L, 0L, NULL
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+
+#line 1030 "rshdown.ctr"
+ if (lgt != sz) { exval = EXIT_FAILURE; }
+ } else {
+
+#line 1032 "rshdown.ctr"
+ exval = EXIT_FAILURE;
+ }
+ }
+ } else {
+
+#line 1036 "rshdown.ctr"
+ /* ERROR: Failed to bind local address */
+ res = dk4socket_c8_addr_port_to_text(
+ adbuf, sizeof(adbuf),
+ af, (struct sockaddr *)(&(array[1])), szl, NULL
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ log_3(4, 5, adbuf);
+ } else {
+ log_1(3);
+ }
+ }
+ (void)dk4socket_close(sock, NULL);
+ } else {
+
+#line 1049 "rshdown.ctr"
+ /* ERROR: Failed to open socket */
+ log_1(6);
+ }
+ } else {
+
+#line 1053 "rshdown.ctr"
+ if (0 == szr) {
+
+#line 1054 "rshdown.ctr"
+ log_3(7, 8, hn);
+ }
+ if (0 == szl) {
+
+#line 1057 "rshdown.ctr"
+ log_3(7, 8, hn);
+ }
+ if (AF_UNSPEC == af) {
+
+#line 1060 "rshdown.ctr"
+ log_3(7, 8, hn);
+ }
+ if (PF_UNSPEC == pf) {
+
+#line 1063 "rshdown.ctr"
+ log_3(7, 8, hn);
+ }
+ }
+ } else {
+
+#line 1067 "rshdown.ctr"
+ /* ERROR: Failed to obtain addresses */
+ log_3(7, 8, hn);
+ }
+ (void)dk4socket_down(NULL);
+ } else {
+
+#line 1072 "rshdown.ctr"
+ /* ERROR: Failed to bring socket subsystem up */
+ log_1(9);
+ }
+
+
+#line 1076 "rshdown.ctr"
+}
+
+
+
+/** Send shutdown data packet.
+ @param filenames Command line arguments array,
+ 0=remote host, 1=remote port, 2=filename.
+ @param szfilenames Number of elements in filenames array.
+*/
+static
+void
+sender_with_signals(const char * const *filenames, size_t szfilenames)
+{
+ FILE *fipo = NULL; /* Data file */
+ const char *ep = NULL; /* End of usefull data pointer */
+ size_t lgt = 0; /* Number of bytes in buffer */
+ int res = 0; /* Conversion or operation result */
+
+
+#line 1094 "rshdown.ctr"
+ if (3 == szfilenames) {
+
+#line 1095 "rshdown.ctr"
+ res = dk4ma_input_c8_dec_ushort(&rp, filenames[1], &ep, 1, NULL);
+ if (0 != res) {
+
+#line 1097 "rshdown.ctr"
+ if (0 != rp) {
+
+#line 1098 "rshdown.ctr"
+ lp = rp;
+ if (0 != options[4].found) {
+
+#line 1100 "rshdown.ctr"
+ if ((dk4_um_t)0UL < options[4].val.u) {
+
+#line 1101 "rshdown.ctr"
+ if ((dk4_um_t)(USHRT_MAX) >= options[4].val.u) {
+ lp = (unsigned short)(options[4].val.u);
+
+#line 1103 "rshdown.ctr"
+ } else {
+
+#line 1104 "rshdown.ctr"
+ lp = 0;
+ /* ERROR: Local port number exceeds 16 bit unsigned range */
+ log_1(27);
+ }
+ } else {
+
+#line 1109 "rshdown.ctr"
+ lp = 0;
+ /* ERROR: Local port number 0 is not allowed */
+ log_1(28);
+ }
+ }
+ if (0 != lp) {
+
+#line 1115 "rshdown.ctr"
+ fipo = dk4fopen_c8(filenames[2], "rb", DK4_FOPEN_SC_IS_REGULAR, NULL);
+ if (NULL != fipo) {
+
+#line 1117 "rshdown.ctr"
+ lgt = fread(b1, 1, sizeof(b1), fipo);
+ fclose(fipo);
+ if (0 < lgt) {
+
+#line 1120 "rshdown.ctr"
+ /* Send bytes over network */
+ send_network(filenames[0], lgt);
+ /* Overwrite memory containing data packet */
+ if (0 == dk4mem_reset_secure(b1, sizeof(b1), NULL)) {
+ exval = EXIT_FAILURE;
+
+#line 1125 "rshdown.ctr"
+ }
+ } else {
+
+#line 1127 "rshdown.ctr"
+ /* ERROR: No data read from file */
+ log_3(16, 17, filenames[2]);
+ }
+ } else {
+
+#line 1131 "rshdown.ctr"
+ /* ERROR: Failed to open data file */
+ log_3(14, 15, filenames[2]);
+ }
+ } else {
+
+#line 1135 "rshdown.ctr"
+ }
+ } else {
+
+#line 1137 "rshdown.ctr"
+ /* ERROR: Remote port number 0 is not allowed */
+ log_1(13);
+ }
+ } else {
+
+#line 1141 "rshdown.ctr"
+ /* ERROR: Not a 16 bit unsigned number */
+ log_3(11, 12, filenames[1]);
+ }
+ } else {
+
+#line 1145 "rshdown.ctr"
+ /* ERROR: Three arguments required - host, port and file */
+ log_1(10);
+ }
+
+
+#line 1149 "rshdown.ctr"
+}
+
+
+
+/** Send shutdown data packet.
+ @param filenames Command line arguments array,
+ 0=remote host, 1=remote port, 2=filename.
+ @param szfilenames Number of elements in filenames array.
+*/
+static
+void
+sender(const char * const *filenames, size_t szfilenames)
+{
+
+
+#line 1163 "rshdown.ctr"
+
+
+#line 1164 "rshdown.ctr"
+#ifdef DK4_HAVE_SIGACTION
+#ifdef SIGPIPE
+ struct sigaction opipe;
+ struct sigaction npipe;
+#endif
+ struct sigaction oint;
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+#else
+#ifdef SIGPIPE
+ dk4_sig_handler_t *opipe = NULL;
+#endif
+ dk4_sig_handler_t *oterm = NULL;
+ dk4_sig_handler_t *oint = NULL;
+#endif
+#ifdef DK4_HAVE_SIGACTION
+#ifdef SIGPIPE
+ int spipe = 0;
+#endif
+ int sint = 0;
+ int sterm = 0;
+ int s_f_i = 0;
+ int s_f_r = 0;
+#endif
+
+ /* Set signal handlers
+ */
+#if DK4_HAVE_SIGACTION
+#ifdef SIGPIPE
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ spipe = 1;
+#endif
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ sterm = 1;
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ sint = 1;
+#else
+#ifdef SIGPIPE
+ opipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oint = sigset(SIGINT, sig_handler_int);
+ oterm = sigset(SIGTERM, sig_handler_term);
+#endif
+
+ /* Send the bytes.
+ */
+ sender_with_signals(filenames, szfilenames);
+
+ finished:
+
+ /* Restore signal handlers
+ */
+#if DK4_HAVE_SIGACTION
+ if (0 != s_f_i) {
+ /* ERROR: Failed to install signal handlers */
+ log_1(18);
+ exval = EXIT_FAILURE;
+ }
+ if (0 != sint) {
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ s_f_r = 1;
+ }
+ }
+ if (0 != sterm) {
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ s_f_r = 1;
+ }
+ }
+#ifdef SIGPIPE
+ if (0 != spipe) {
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ s_f_r = 1;
+ }
+ }
+#endif
+ if (0 != s_f_r) {
+ /* ERROR: Failed to restore signal handlers */
+ log_1(19);
+ exval = EXIT_FAILURE;
+ }
+#else
+ if (NULL != oterm) { sigset(SIGTERM, oterm); }
+ if (NULL != oint ) { sigset(SIGINT, oint ); }
+#ifdef SIGPIPE
+ if (NULL != opipe) { sigset(SIGPIPE, opipe); }
+#endif
+#endif
+
+
+#line 1295 "rshdown.ctr"
+
+
+#line 1296 "rshdown.ctr"
+}
+
+
+
+/** Run service
+*/
+static
+void
+run_daemon_loop(void)
+{
+ dk4_allowed_peer_t peer; /* Allowed remote address */
+ dk4_sockaddr_storage_t sa; /* Generic socket address */
+ fd_set rfds; /* Readable file descriptors */
+ dk4_socket_set_t *sset = NULL; /* Set of sockets to read data from */
+ struct sockaddr *soa = NULL; /* Minimum socket address */
+ struct sockaddr_in *so4 = NULL; /* IPv4 socket address */
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ struct sockaddr_in6 *so6 = NULL; /* IPv6 socket address */
+#endif
+ size_t szsa = 0; /* Size of sa */
+ size_t i = 0; /* Traverse socket set */
+ dk4_socket_t smax = 0; /* Maximum socket fd number */
+ int cc = 1; /* Flag: Can continue */
+ int pused = 0; /* Flag: Peer used */
+ int res = 0; /* Operation result */
+ int ok = 0; /* Flag: Data packet matches file */
+ unsigned short frp = 0; /* Found remote port */
+
+
+#line 1324 "rshdown.ctr"
+ soa = (struct sockaddr *)(&sa);
+ so4 = (struct sockaddr_in *)(&sa);
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ so6 = (struct sockaddr_in6 *)(&sa);
+#endif
+ if (DK4_SOCKET_RESULT_SUCCESS == dk4socket_up(NULL)) {
+
+
+#line 1331 "rshdown.ctr"
+ if (0 < strlen(asender)) {
+
+#line 1332 "rshdown.ctr"
+ res = dk4socket_c8_get_allowed_peer(&peer, asender, NULL);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+
+#line 1334 "rshdown.ctr"
+ pused = 1;
+ } else {
+
+#line 1336 "rshdown.ctr"
+ cc = 0;
+ /* SYSLOG ERROR: Invalid peer name */
+ syslog_3(29, 30, asender);
+ }
+ }
+ if (1 == cc) {
+
+#line 1342 "rshdown.ctr"
+ sset = dk4socket_set_udp_directly(lp, 0, 0, NULL);
+ if (NULL != sset) {
+
+#line 1344 "rshdown.ctr"
+ /* SYSLOG: Started */
+#if DK4_HAVE_SYSLOG
+ openlog(rshdown_kw[0], LOG_PID, syslogf);
+ syslog(LOG_INFO, "%s", rshdown_kw[50]);
+ closelog();
+#endif
+ do {
+ if (0 != can_continue()) {
+ FD_ZERO(&rfds);
+ smax = -1;
+ for (i = 0; i < sset->szUsed; i++) {
+
+
+#line 1356 "rshdown.ctr"
+ FD_SET((sset->pSockets)[i],&rfds);
+ if (smax < (sset->pSockets)[i]) { smax = (sset->pSockets)[i]; }
+ }
+ res = select((1+smax), &rfds, NULL, NULL, NULL);
+ if (0 != can_continue()) {
+ if (0 < res) {
+
+#line 1362 "rshdown.ctr"
+ for (i = 0; ((1 == cc) && (i < sset->szUsed)); i++) {
+
+
+#line 1364 "rshdown.ctr"
+ if (FD_ISSET((sset->pSockets)[i],&rfds)) {
+
+
+#line 1366 "rshdown.ctr"
+ DK4_MEMRES(&sa, sizeof(sa));
+ szb2 = sizeof(b2);
+ szsa = sizeof(sa);
+ res = dk4socket_recvfrom(
+ (sset->pSockets)[i], b2, &szb2, 0,
+ (struct sockaddr *)(&sa), &szsa, 0L, 0L, NULL
+ );
+ if (0 != can_continue()) {
+
+#line 1374 "rshdown.ctr"
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+
+#line 1375 "rshdown.ctr"
+ if (0 < szb2) {
+
+#line 1376 "rshdown.ctr"
+ ok = 1;
+ if (0 != pused) {
+
+#line 1378 "rshdown.ctr"
+ res = dk4socket_allowed_peer_compare(&peer, &sa, 1);
+ if (0 != res) {
+
+#line 1380 "rshdown.ctr"
+ ok = 0;
+ /* SYSLOG DEBUG: Address mismatch */
+ syslog_debug(53, 54, &sa);
+ }
+ }
+ if (0U != rp) {
+
+#line 1386 "rshdown.ctr"
+ frp = 0;
+ switch (soa->sa_family) {
+ case AF_INET : {
+ frp = dk4socket_ntohs(so4->sin_port);
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ frp = dk4socket_ntohs(so6->sin6_port);
+ } break;
+#endif
+ }
+ if (frp != rp) {
+
+#line 1398 "rshdown.ctr"
+ ok = 0;
+ /* SYSLOG DEBUG: Port mismatch */
+ syslog_debug(55, 56, &sa);
+ }
+ }
+ if (0 != ok) {
+
+#line 1404 "rshdown.ctr"
+ ok = 0;
+ if (szb1 == szb2) {
+
+#line 1406 "rshdown.ctr"
+ if (0 == DK4_MEMCMP(b1,b2,szb1)) {
+ ok = 1;
+
+#line 1408 "rshdown.ctr"
+ } else {
+
+#line 1409 "rshdown.ctr"
+ /* SYSLOG DEBUG: Data mismatch */
+ syslog_debug(59, 60, &sa);
+ }
+ } else {
+
+#line 1413 "rshdown.ctr"
+ /* SYSLOG DEBUG: Size mismatch */
+ syslog_debug(57, 58, &sa);
+ }
+ }
+ if (0 != ok) {
+
+#line 1418 "rshdown.ctr"
+ /* Shutdown */
+ /* SYSLOG: Initiating shutdown */
+#if DK4_HAVE_SYSLOG
+ openlog(rshdown_kw[0], LOG_PID, syslogf);
+ syslog(LOG_INFO, "%s", rshdown_kw[51]);
+ closelog();
+#endif
+ if (0 < strlen(cmd)) {
+
+#line 1426 "rshdown.ctr"
+ if (0 != system(cmd)) {
+#if DK4_HAVE_SYSLOG
+
+ openlog(rshdown_kw[0], LOG_PID, syslogf);
+ syslog(
+ LOG_ERR, "%s%s%s",
+ rshdown_kw[61], cmd, rshdown_kw[62]
+ );
+ closelog();
+#endif
+ }
+ } else {
+
+#line 1438 "rshdown.ctr"
+ if (0 < signo) {
+ kill((pid_t)1, signo);
+ } else {
+#ifdef SIGPWR
+ kill((pid_t)1, SIGPWR);
+#else
+#ifdef SIGTERM
+ kill((pid_t)1, SIGTERM);
+#else
+ kill((pid_t)1, 15);
+#endif
+#endif
+ }
+ }
+ cc = 0;
+ }
+ } else {
+
+#line 1455 "rshdown.ctr"
+ }
+ } else {
+
+#line 1457 "rshdown.ctr"
+ }
+ } else {
+
+#line 1459 "rshdown.ctr"
+ cc = -1;
+ }
+ } else {
+
+#line 1462 "rshdown.ctr"
+ }
+ }
+ } else {
+
+#line 1465 "rshdown.ctr"
+ }
+ } else {
+
+#line 1467 "rshdown.ctr"
+ cc = -1;
+ }
+ } else {
+
+#line 1470 "rshdown.ctr"
+ cc = -1;
+ }
+ } while (1 == cc);
+
+#line 1473 "rshdown.ctr"
+ dk4socket_set_close(sset, NULL);
+ /* SYSLOG: Finished */
+#if DK4_HAVE_SYSLOG
+ openlog(rshdown_kw[0], LOG_PID, syslogf);
+ syslog(LOG_INFO, "%s", rshdown_kw[52]);
+ closelog();
+#endif
+ } else {
+
+#line 1481 "rshdown.ctr"
+ /* SYSLOG ERROR: Failed to create socket set */
+ syslog_1(26);
+ }
+ } else {
+
+#line 1485 "rshdown.ctr"
+ }
+ (void)dk4socket_down(NULL);
+ } else {
+
+#line 1488 "rshdown.ctr"
+ /* SYSLOG ERROR: Failed to bring socket subsystem up */
+ syslog_1(25);
+ }
+
+
+#line 1492 "rshdown.ctr"
+}
+
+
+
+/** Set signal handlers and run service.
+*/
+static
+void
+run_daemon_with_signals(void)
+{
+#ifdef DK4_HAVE_SIGACTION
+#ifdef SIGPIPE
+ struct sigaction opipe;
+ struct sigaction npipe;
+#endif
+ struct sigaction oint;
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+#else
+#ifdef SIGPIPE
+ dk4_sig_handler_t *opipe = NULL;
+#endif
+ dk4_sig_handler_t *oterm = NULL;
+ dk4_sig_handler_t *oint = NULL;
+#endif
+#ifdef DK4_HAVE_SIGACTION
+#ifdef SIGPIPE
+ int spipe = 0;
+#endif
+ int sint = 0;
+ int sterm = 0;
+ int s_f_i = 0;
+ int s_f_r = 0;
+#endif
+
+
+#line 1528 "rshdown.ctr"
+ /* Set signal handlers
+ */
+#if DK4_HAVE_SIGACTION
+#ifdef SIGPIPE
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ spipe = 1;
+#endif
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ sterm = 1;
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ sint = 1;
+#else
+#ifdef SIGPIPE
+ opipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oint = sigset(SIGINT, sig_handler_int);
+ oterm = sigset(SIGTERM, sig_handler_term);
+#endif
+
+ run_daemon_loop();
+
+ finished:
+
+ /* Restore signal handlers
+ */
+#if DK4_HAVE_SIGACTION
+ if (0 != s_f_i) {
+ /* ERROR: Failed to install signal handlers */
+ syslog_1(23);
+ exval = EXIT_FAILURE;
+ }
+ if (0 != sint) {
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ s_f_r = 1;
+ }
+ }
+ if (0 != sterm) {
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ s_f_r = 1;
+ }
+ }
+#ifdef SIGPIPE
+ if (0 != spipe) {
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ s_f_r = 1;
+ }
+ }
+#endif
+ if (0 != s_f_r) {
+ /* ERROR: Failed to restore signal handlers */
+ syslog_1(24);
+ exval = EXIT_FAILURE;
+ }
+#else
+ if (NULL != oterm) { sigset(SIGTERM, oterm); }
+ if (NULL != oint ) { sigset(SIGINT, oint ); }
+#ifdef SIGPIPE
+ if (NULL != opipe) { sigset(SIGPIPE, opipe); }
+#endif
+#endif
+
+
+#line 1631 "rshdown.ctr"
+}
+
+
+
+/** Retrieve port number from a configuration file line.
+ @param dest Address of destination variable.
+ @param pv String containing the port number.
+ @param fn File name for diagnostics.
+ @param lineno Line number for diagnostics.
+ @param a0 Flag: Remote port, 0 allowed for arbitrary ports.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+set_port_number(
+ unsigned short *dest, const char *pv, const char *fn, dk4_um_t lineno, int a0
+)
+{
+ const char *ep = NULL;
+ int back = 0;
+ unsigned short us = 0U;
+
+ if (0 != dk4ma_input_c8_dec_ushort(&us, pv, &ep, 1, NULL)) {
+ if (0U != us) {
+ *dest = us;
+ back = 1;
+ } else {
+ if (0 != a0) {
+ *dest = us;
+ back = 1;
+ } else {
+ /* ERROR: Port number 0 not allowed! */
+ log_1(28);
+ }
+ }
+ } else {
+ /* ERROR: Not a 16 bit unsigned number! */
+ log_3(11, 12, pv);
+ }
+ return back;
+}
+
+
+
+/** Set the signal number.
+ @param pv Text containing the number.
+ @param fn File name for diagnostics.
+ @param lineno Line number for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+set_signal_number(const char *pv, const char *fn, dk4_um_t lineno)
+{
+ int back = 1;
+
+
+#line 1687 "rshdown.ctr"
+ switch ( dk4str8_array_index(signal_names, pv, 0) ) {
+ case 0 : case 1 : {
+#ifdef SIGHUP
+ signo = SIGHUP;
+#else
+ signo = 1;
+#endif
+ } break;
+ case 2 : case 3 : {
+#ifdef SIGINT
+ signo = SIGINT;
+#else
+ signo = 2;
+#endif
+ } break;
+ case 4 : case 5 : {
+#ifdef SIGQUIT
+ signo = SIGQUIT;
+#else
+ signo = 3;
+#endif
+ } break;
+ case 6 : case 7 : {
+#ifdef SIGILL
+ signo = SIGILL;
+#else
+ signo = 4;
+#endif
+ } break;
+ case 8 : case 9 : {
+#ifdef SIGTRAP
+ signo = SIGTRAP;
+#else
+ signo = 5;
+#endif
+ } break;
+ case 10 : case 11 : case 12 : case 13 : {
+#ifdef SIGABRT
+ signo = SIGABRT;
+#else
+#ifdef SIGIOT
+ signo = SIGIOT;
+#else
+ signo = 6;
+#endif
+#endif
+ } break;
+ case 14 : case 15 : {
+#ifdef SIGBUS
+ signo = SIGBUS;
+#else
+ signo = 7;
+#endif
+ } break;
+ case 16 : case 17 : {
+#ifdef SIGFPE
+ signo = SIGFPE;
+#else
+ signo = 8;
+#endif
+ } break;
+ case 18 : case 19 : {
+#ifdef SIGKILL
+ signo = SIGKILL;
+#else
+ signo = 9;
+#endif
+ } break;
+ case 20 : case 21 : {
+#ifdef SIGUSR1
+ signo = SIGUSR1;
+#else
+ signo = 10;
+#endif
+ } break;
+ case 22 : case 23 : {
+#ifdef SIGSEGV
+ signo = SIGSEGV;
+#else
+ signo = 11;
+#endif
+ } break;
+ case 24 : case 25 : {
+#ifdef SIGUSR2
+ signo = SIGUSR2;
+#else
+ signo = 12;
+#endif
+ } break;
+ case 26 : case 27 : {
+#ifdef SIGPIPE
+ signo = SIGPIPE;
+#else
+ signo = 13;
+#endif
+ } break;
+ case 28 : case 29 : {
+#ifdef SIGALRM
+ signo = SIGALRM;
+#else
+ signo = 14;
+#endif
+ } break;
+ case 30 : case 31 : {
+#ifdef SIGTERM
+ signo = SIGTERM;
+#else
+ signo = 15;
+#endif
+ } break;
+ case 32 : case 33 : {
+#ifdef SIGSTKFLT
+ signo = SIGSTKFLT;
+#else
+ signo = 16;
+#endif
+ } break;
+ case 34 : case 35 : case 36 : case 37 : {
+#ifdef SIGCLD
+ signo = SIGCLD;
+#else
+#ifdef SIGCHLD
+ signo = SIGCHLD;
+#else
+ signo = 17;
+#endif
+#endif
+ } break;
+ case 38 : case 39 : {
+#ifdef SIGCONT
+ signo = SIGCONT;
+#else
+ signo = 18;
+#endif
+ } break;
+ case 40 : case 41 : {
+#ifdef SIGSTOP
+ signo = SIGSTOP;
+#else
+ signo = 19;
+#endif
+ } break;
+ case 42 : case 43 : {
+#ifdef SIGTSTP
+ signo = SIGTSTP;
+#else
+ signo = 20;
+#endif
+ } break;
+ case 44 : case 45 : {
+#ifdef SIGTTIN
+ signo = SIGTTIN;
+#else
+ signo = 21;
+#endif
+ } break;
+ case 46 : case 47 : {
+#ifdef SIGTTOU
+ signo = SIGTTOU;
+#else
+ signo = 22;
+#endif
+ } break;
+ case 48 : case 49 : {
+#ifdef SIGURG
+ signo = SIGURG;
+#else
+ signo = 23;
+#endif
+ } break;
+ case 50 : case 51 : {
+#ifdef SIGXCPU
+ signo = SIGXCPU;
+#else
+ signo = 24;
+#endif
+ } break;
+ case 52 : case 53 : {
+#ifdef SIGXFSZ
+ signo = SIGXFSZ;
+#else
+ signo = 25;
+#endif
+ } break;
+ case 54 : case 55 : {
+#ifdef SIGVTALRM
+ signo = SIGVTALRM;
+#else
+ signo = 26;
+#endif
+ } break;
+ case 56 : case 57 : {
+#ifdef SIGPROF
+ signo = SIGPROF;
+#else
+ signo = 27;
+#endif
+ } break;
+ case 58 : case 59 : {
+#ifdef SIGWINCH
+ signo = SIGWINCH;
+#else
+ signo = 28;
+#endif
+ } break;
+ case 60 : case 61 : case 62 : case 63 : {
+#ifdef SIGPOLL
+ signo = SIGPOLL;
+#else
+#ifdef SIGIO
+ signo = SIGIO
+#else
+ signo = 29;
+#endif
+#endif
+ } break;
+ case 64 : case 65 : {
+#ifdef SIGPWR
+ signo = SIGPWR;
+#else
+ signo = 30;
+#endif
+ } break;
+ case 66 : case 67 : {
+#ifdef SIGSYS
+ signo = SIGSYS;
+#else
+ signo = 31;
+#endif
+ } break;
+ default : {
+
+#line 1918 "rshdown.ctr"
+ back = 0;
+ /* ERROR: Illegal signal name */
+ log_3(31, 32, pv);
+ } break;
+ }
+
+#line 1923 "rshdown.ctr"
+ return back;
+}
+
+
+
+/** Set syslog facility.
+ @param pv Text representation of syslog facility.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+set_syslog_facility(const char *pv)
+{
+ int back = 1;
+ if (NULL != pv) {
+ switch ( dk4str8_array_index(syslog_facility_names, pv, 0) ) {
+#ifdef LOG_AUTH
+ case 0: { syslogf = LOG_AUTH; } break;
+#endif
+#ifdef LOG_AUTHPRIV
+ case 1: { syslogf = LOG_AUTHPRIV; } break;
+#endif
+#ifdef LOG_CRON
+ case 2: { syslogf = LOG_CRON; } break;
+#endif
+#ifdef LOG_DAEMON
+ case 3: { syslogf = LOG_DAEMON; } break;
+#endif
+#ifdef LOG_FTP
+ case 4: { syslogf = LOG_FTP; } break;
+#endif
+#ifdef LOG_KERN
+ case 5: { syslogf = LOG_KERN; } break;
+#endif
+#ifdef LOG_LPR
+ case 6: { syslogf = LOG_LPR; } break;
+#endif
+#ifdef LOG_MAIL
+ case 7: { syslogf = LOG_MAIL; } break;
+#endif
+#ifdef LOG_NEWS
+ case 8: { syslogf = LOG_NEWS; } break;
+#endif
+#ifdef LOG_AUTH
+ case 9: { syslogf = LOG_AUTH; } break;
+#endif
+#ifdef LOG_SYSLOG
+ case 10: { syslogf = LOG_SYSLOG; } break;
+#endif
+#ifdef LOG_USER
+ case 11: { syslogf = LOG_USER; } break;
+#endif
+#ifdef LOG_UUCP
+ case 12: { syslogf = LOG_UUCP; } break;
+#endif
+#ifdef LOG_LOCAL0
+ case 13: { syslogf = LOG_LOCAL0; } break;
+#endif
+#ifdef LOG_LOCAL1
+ case 14: { syslogf = LOG_LOCAL1; } break;
+#endif
+#ifdef LOG_LOCAL2
+ case 15: { syslogf = LOG_LOCAL2; } break;
+#endif
+#ifdef LOG_LOCAL3
+ case 16: { syslogf = LOG_LOCAL3; } break;
+#endif
+#ifdef LOG_LOCAL4
+ case 17: { syslogf = LOG_LOCAL4; } break;
+#endif
+#ifdef LOG_LOCAL5
+ case 18: { syslogf = LOG_LOCAL5; } break;
+#endif
+#ifdef LOG_LOCAL6
+ case 19: { syslogf = LOG_LOCAL6; } break;
+#endif
+#ifdef LOG_LOCAL7
+ case 20: { syslogf = LOG_LOCAL7; } break;
+#endif
+ default: {
+ back = 0;
+ log_3(48, 49, pv);
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+/** Read configuration file.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+read_config_file(void)
+{
+ FILE *fipo = NULL; /* Input file to process */
+ const char *fn = NULL; /* Input file name */
+ const char *ep = NULL; /* End pointer after number */
+ char *pk = NULL; /* Pointer to key string */
+ char *pv = NULL; /* Pointer to value string */
+ dk4_um_t lineno = (dk4_um_t)0UL; /* Current line number */
+ int back = 0;
+
+
+#line 2028 "rshdown.ctr"
+ if (0 != options[0].found) { fn = options[0].val.t; }
+ if (NULL == fn) { fn = def_conf_name; }
+ fipo = dk4fopen_c8(fn, "r", DK4_FOPEN_SC_IS_REGULAR, NULL);
+ if (NULL != fipo) {
+ back = 1;
+ while( fgets(b1, sizeof(b1), fipo) ) {
+ lineno++;
+ pk = dk4str8_start(b1, NULL);
+ if (NULL != pk) {
+ if ('#' != *pk) {
+ pv = dk4str8_chr(pk, '=');
+ if (NULL != pv) {
+ *(pv++) = '\0';
+ pv = dk4str8_start(pv, NULL);
+ if (NULL != pv) {
+ dk4str8_normalize(pk, NULL);
+ dk4str8_delnl(pv);
+ switch ( dk4str8_array_index(key_names, pk, 0) ) {
+ case 0: { /* sender address */
+ if (0 == strlen(asender)) {
+ dk4str8_normalize(pv, NULL);
+ if (0 == dk4str8_cpy_s(asender,sizeof(asender),pv,NULL)) {
+ back = 0;
+
+#line 2051 "rshdown.ctr"
+ /* ERROR: Sender name too long */
+ log_3(33, 34, pv);
+ }
+ } else {
+
+#line 2055 "rshdown.ctr"
+ back = 0;
+ /* ERROR: Redefinition of sender */
+ log_1(35);
+ }
+ } break;
+ case 1: { /* sender port */
+ if (0 == set_port_number(&rp, pv, fn, lineno, 1)) {
+ back = 0;
+
+#line 2063 "rshdown.ctr"
+ }
+ } break;
+ case 2: { /* local port */
+ if (0 == set_port_number(&lp, pv, fn, lineno, 0)) {
+ back = 0;
+
+#line 2068 "rshdown.ctr"
+ }
+ } break;
+ case 3: { /* signal */
+ ep = NULL;
+ if (0 != dk4ma_input_c8_dec_int(&signo, pv, &ep, 1, NULL)) {
+ if (1 > signo) {
+ back = 0;
+
+#line 2075 "rshdown.ctr"
+ /* ERROR: Signal number must be positive */
+ log_1(36);
+ }
+ } else {
+ dk4str8_normalize(pv, NULL);
+ if (0 == set_signal_number(pv, fn, lineno)) {
+ back = 0;
+
+#line 2082 "rshdown.ctr"
+ }
+ }
+ } break;
+ case 4: { /* command */
+ if (0 == strlen(cmd)) {
+ if (0 == dk4str8_cpy_s(cmd, sizeof(cmd), pv, NULL)) {
+ back = 0;
+ /* ERROR: Command too long! */
+ log_3(37, 38, pv);
+ }
+ } else {
+
+#line 2093 "rshdown.ctr"
+ back = 0;
+ /* ERROR: Redefinition of command */
+ log_1(39);
+ }
+ } break;
+ case 5: { /* file */
+ if (0 == strlen(file_name)) {
+ if (0 == dk4str8_cpy_s(file_name,sizeof(file_name),pv,NULL))
+ {
+ back = 0;
+ /* ERROR: File name too long! */
+ log_3(40, 41, pv);
+ }
+ } else {
+
+#line 2107 "rshdown.ctr"
+ back = 0;
+ /* ERROR: Redefinition of file name */
+ log_1(42);
+ }
+ } break;
+ case 6: {
+ debug = ((dk4str8_is_on(pv)) ? 1 : 0);
+ } break;
+ case 7: {
+ dk4str8_normalize(pv, NULL);
+ if (0 == set_syslog_facility(pv)) {
+ back = 0;
+ }
+ } break;
+ default : {
+
+#line 2122 "rshdown.ctr"
+ log_1(43);
+ } break;
+ }
+ } else {
+
+#line 2126 "rshdown.ctr"
+ back = 0;
+ /* ERROR: Missing value */
+ log_1(44);
+ }
+ } else {
+
+#line 2131 "rshdown.ctr"
+ back = 0;
+ /* ERROR: Missing value */
+ log_1(44);
+ }
+ }
+ }
+ }
+ fclose(fipo);
+ if ((0 != back) && (0U == lp)) {
+ back = 0;
+
+#line 2141 "rshdown.ctr"
+ /* ERROR: Local port not specified */
+ log_1(45);
+ }
+ if (0 != back) {
+ if ((0 == signo) && (0 == strlen(cmd))) {
+ back = 0;
+
+#line 2147 "rshdown.ctr"
+ /* ERROR: Signal or command required */
+ log_1(46);
+ }
+ }
+ if (0 != back) {
+ if (0 != strlen(file_name)) {
+ fipo = dk4fopen_c8(file_name, "rb", DK4_FOPEN_SC_IS_REGULAR, NULL);
+ if (NULL != fipo) {
+ szb1 = fread(b1, 1, sizeof(b1), fipo);
+ fclose(fipo);
+ if (0 == szb1) {
+ back = 0;
+
+#line 2159 "rshdown.ctr"
+ /* ERROR: Failed to read data from file */
+ log_3(16, 17, file_name);
+ }
+ } else {
+
+#line 2163 "rshdown.ctr"
+ back = 0;
+ /* ERROR: Failed to open data file */
+ log_3(14, 15, file_name);
+ }
+ } else {
+
+#line 2168 "rshdown.ctr"
+ back = 0;
+ /* ERROR: No data file specified */
+ log_1(47);
+ }
+ }
+ } else {
+
+#line 2174 "rshdown.ctr"
+ }
+
+#line 2175 "rshdown.ctr"
+ return back;
+}
+
+
+
+/** Daemon waiting for shutdown data packet.
+*/
+static
+void
+run_as_daemon(void)
+{
+ pid_t cpid;
+
+
+#line 2188 "rshdown.ctr"
+ /* Preparations before we start.
+ */
+ DK4_MEMRES(cmd, sizeof(cmd));
+ DK4_MEMRES(asender, sizeof(asender));
+ DK4_MEMRES(file_name, sizeof(file_name));
+ if (read_config_file()) {
+
+#line 2194 "rshdown.ctr"
+ if (0 != dk4dmt_parent_before_fork(rshdown_kw[0],pid_file_name,1,syslogf)) {
+ cpid = fork();
+ if ((pid_t)0 == cpid) { /* in the child */
+ if (0 != dk4dmt_intermediate_before_fork(rshdown_kw[0], syslogf)) {
+ cpid = fork();
+ if ((pid_t)0 == cpid) { /* in the child */
+
+
+#line 2201 "rshdown.ctr"
+
+
+#line 2202 "rshdown.ctr"
+ exval = EXIT_SUCCESS;
+ if (dk4dmt_daemon_after_fork(rshdown_kw[0],pid_file_name,syslogf)) {
+ run_daemon_with_signals();
+ }
+ dk4dmt_daemon_end(rshdown_kw[0], pid_file_name, syslogf);
+ if (0 == dk4mem_reset_secure(b1, sizeof(b1), NULL)) {
+ exval = EXIT_FAILURE;
+ }
+ if (0 == dk4mem_reset_secure(b2, sizeof(b2), NULL)) {
+ exval = EXIT_FAILURE;
+ }
+
+
+#line 2214 "rshdown.ctr"
+
+
+#line 2215 "rshdown.ctr"
+ } else {
+ if ((pid_t)(-1) != cpid) { /* intermediate process */
+ exval = EXIT_SUCCESS;
+ if (0 == dk4mem_reset_secure(b1, sizeof(b1), NULL)) {
+ exval = EXIT_FAILURE;
+ }
+ if (0 == dk4mem_reset_secure(b2, sizeof(b2), NULL)) {
+ exval = EXIT_FAILURE;
+ }
+ } else { /* error */
+ if (0 == dk4mem_reset_secure(b1, sizeof(b1), NULL)) {
+ exval = EXIT_FAILURE;
+ }
+ if (0 == dk4mem_reset_secure(b2, sizeof(b2), NULL)) {
+ exval = EXIT_FAILURE;
+ }
+ /* SYSLOG ERROR: Failed to create child process */
+ syslog_1(22);
+ }
+ }
+ } else {
+ if (0 == dk4mem_reset_secure(b1, sizeof(b1), NULL)) {
+ exval = EXIT_FAILURE;
+ }
+ if (0 == dk4mem_reset_secure(b2, sizeof(b2), NULL)) {
+ exval = EXIT_FAILURE;
+ }
+ /* SYSLOG ERROR: Failed to detach */
+ syslog_1(21);
+ }
+ } else {
+ if ((pid_t)(-1) != cpid) { /* parent */
+ exval = EXIT_SUCCESS;
+ } else { /* error */
+ /* ERROR: Failed to create child process */
+ log_1(20);
+ }
+ }
+ }
+ }
+ if (0 == dk4mem_reset_secure(b1, sizeof(b1), NULL)) {
+ exval = EXIT_FAILURE;
+ }
+ if (0 == dk4mem_reset_secure(b2, sizeof(b2), NULL)) {
+ exval = EXIT_FAILURE;
+ }
+
+
+#line 2262 "rshdown.ctr"
+}
+
+
+
+/** Show a text paragraph on standard output.
+ @param txt Text to show.
+*/
+static
+void
+show_text(const char * const *txt)
+{
+ if (NULL != txt) {
+ while (NULL != *txt) {
+ fputs(*(txt++), stdout);
+ fputc('\n', stdout);
+ }
+ fflush(stdout);
+ }
+}
+
+
+
+/** Handle --help, --version, --license options.
+*/
+static
+void
+run_hvl(void)
+{
+ if (0 != (1 & hvl)) {
+ show_text(help_text);
+ }
+ if (0 != (2 & hvl)) {
+ fputs(version_text, stdout);
+ fputc('\n', stdout);
+ fflush(stdout);
+ }
+ if (0 != (4 & hvl)) {
+ show_text(license_text);
+ }
+}
+
+
+
+/** Program entry point.
+ @param argc
+ @param argv
+ @return 0 on success, any other value indicates an error.
+*/
+int
+main(int argc, char *argv[])
+{
+ char *filenames[32];
+ size_t szfilenames = 32; /* Array size */
+ int res = 0; /* Operation result */
+
+
+
+#line 2318 "rshdown.ctr"
+
+ /* Process command line arguments.
+ */
+ res = dk4opt_process_argv(
+ options, szoptions, argc, argv, filenames, &szfilenames, 1, 1, NULL
+ );
+ if (0 == res) {
+
+#line 2325 "rshdown.ctr"
+ goto finished;
+ }
+
+ /* Check help, version, license.
+ */
+ if (0 != options[5].found) { hvl |= 1; }
+ if (0 != options[6].found) { hvl |= 2; }
+ if (0 != options[7].found) { hvl |= 4; }
+ if (0 != hvl) {
+ run_hvl();
+ goto finished;
+ }
+
+ /* Either send data or run as daemon to receive data.
+ */
+ if (0 != options[1].found) {
+
+#line 2341 "rshdown.ctr"
+ sender((const char * const *)filenames, szfilenames);
+ } else {
+
+#line 2343 "rshdown.ctr"
+ run_as_daemon();
+ }
+
+ finished:
+
+
+#line 2348 "rshdown.ctr"
+ exit(exval); return exval;
+}
+
+
+#else
+
+
+/** Program entry point.
+ @param argc
+ @param argv
+ @return 0 on success, any other value indicates an error.
+*/
+int
+main(int argc, char *argv[])
+{
+ fputs("rshdown: ERROR: Build requirements violation!\n", stderr);
+#if DK4_CHAR_SIZE > 1
+ fputs("Default character size is larger than 1!\n", stderr);
+#endif
+#if !((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET))
+ fputs("Neither sigaction() nor sigset() are available!\n", stderr);
+#endif
+#if !((DK4_HAVE_SETSID) || (DK4_HAVE_SETPGRP))
+ fputs("Neither setsid() nor setpgrp() are available!\n", stderr);
+#endif
+ fflush(stderr);
+ exit(EXIT_FAILURE); return EXIT_FAILURE;
+}
+
+#endif
+
+
diff --git a/support/dktools/rshdown.conf.sample b/support/dktools/rshdown.conf.sample
new file mode 100644
index 0000000000..ba2e4195dc
--- /dev/null
+++ b/support/dktools/rshdown.conf.sample
@@ -0,0 +1,40 @@
+# Allowed sender address:
+# - One machine specified by IPv6 address: ::1
+# - One machine specified by IPv4 address: 192.0.2.100
+# - One network specified by IPv4 address/mask: 192.0.2.0/24
+# - Alternatively mask in dotted notation: 192.0.2.0/255.255.255.0
+sender = 192.0.2.100
+
+# Allowed sender port (any if not specified here).
+sender port = 1234
+
+# Local UDP port we are using.
+receiver port = 1234
+
+# File containing data to compare against packet contents.
+file = /etc/rshdown/secret
+
+# Signal number or case-insensitive name to send to init process.
+# Only used if no command specified below.
+# Signal names: hup int quit ill trap abrt iot bus fpe kill usr1
+# segv usr2 pipe alrm term stkflt cld cont stop ttin
+# ttou urg xcpu xfsz vtalrm prof winch poll io pwr sys
+# Alternatively: sighup sigint sigquit ...
+# Signal names are system dependant, not every signal is supported on every
+# system.
+signal = sigpwr
+
+# Command to execute on arrival of shutdown packet
+# The command is passed to /bin/sh by the system() function.
+# The shutdown command syntax is OS dependant, i.e. on Solaris
+# we would use "shutdown -i0 -g0 -y" instead.
+command = shutdown -h now > /dev/null 2>&1 &
+
+# Syslog facility to use, one from:
+# auth authpriv cron daemon ftp kern lpr mail news security syslog user
+# uucp local0 local1 local2 local3 local4 local5 local6 local7
+syslog facility = auth
+
+# Flag: Syslog messages for discarded packets.
+debug = off
+
diff --git a/support/dktools/rshdown.ctr b/support/dktools/rshdown.ctr
new file mode 100644
index 0000000000..7e7edc2b51
--- /dev/null
+++ b/support/dktools/rshdown.ctr
@@ -0,0 +1,2379 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2016-xxxx
+license = bsd
+
+
+%% module
+
+/*
+ rshdown -s [-n _number_] [-l _port_] [-b] _address_ _port_ _file_
+ rshdown [-c _configfile_]
+
+ Either send shutdown packages (-s option used)
+ or run as daemon in background (no -s option)
+ and wait for shutdown packages.
+
+ Sending:
+
+ -n _number_ Number of packages to send
+
+ -l _port_ Local port number to use
+ Default: Same as remote port
+
+ -b Flag: Destination address is a broadcast address
+
+ _address_ Destination address (hostname or IP address)
+
+ _port_ Port number on destination host
+
+ _file_ File containing data to send
+
+ Daemon:
+
+ -c _configfile_ Configuration file.
+
+*/
+
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+
+#include <stdio.h>
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if (DK4_CHAR_SIZE == 1) \
+ && (DK4_HAVE_SIGACTION || DK4_HAVE_SIGSET) \
+ && (DK4_HAVE_SETSID || DK4_HAVE_SETPGRP)
+
+#if DK4_HAVE_MATH_H
+#ifndef MATH_H_INCLUDED
+#include <math.h>
+#define MATH_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_STRING_H
+#ifndef STRING_H_INCLUDED
+#include <string.h>
+#define STRING_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYSLOG_H
+#ifndef SYSLOG_H_INCLUDED
+#include <syslog.h>
+#define SYSLOG_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4mem.h"
+#include "dk4memrs.h"
+#include "dk4opt.h"
+#include "dk4mai8dus.h"
+#include "dk4mai8dii.h"
+#include "dk4fopt.h"
+#include "dk4fopc8.h"
+#include "dk4isadm.h"
+#include "dk4sock.h"
+#include "dk4inst.h"
+#include "dk4str8.h"
+#include "dk4mpl.h"
+#include "dk4dmt.h"
+#include "dk4vers.h"
+
+
+
+$!trace-include
+
+
+
+#ifndef RSHDOWN_BUFFER_SIZE
+/** Buffer size, should not exceed UDP packet size.
+*/
+#define RSHDOWN_BUFFER_SIZE 1460
+#endif
+
+
+
+/** Path name of data file.
+*/
+static char file_name[DK4_MAX_PATH];
+
+
+
+/** Send and receive buffer.
+*/
+static char b1[RSHDOWN_BUFFER_SIZE];
+
+
+/** Buffer for local secret from file in daemon.
+*/
+static char b2[sizeof(b1)];
+
+
+/** Command to execute on packet arrival.
+*/
+static char cmd[1024];
+
+
+/** Allowed sender peer as text.
+*/
+static char asender[1024];
+
+
+/** Options used by the program.
+*/
+static dk4_option_t options[] = {
+
+ /* 0 Configuration file.
+ */
+ { { dkT('c'), dkT("config"), DK4_OPT_ARG_STRING }, { NULL }, 0 },
+
+ /* 1 Send data.
+ */
+ { { dkT('s'), dkT("send"), DK4_OPT_ARG_NONE }, { NULL }, 0 },
+
+ /* 2 Destination address is a broadcast address.
+ */
+ { { dkT('b'), dkT("broadcast"), DK4_OPT_ARG_NONE }, { NULL }, 0 },
+
+ /* 3 Number of packets to send.
+ */
+ { { dkT('n'), dkT("number"), DK4_OPT_ARG_UNSIGNED}, { NULL }, 0 },
+
+ /* 4 Local port number.
+ */
+ { { dkT('l'), dkT("local"), DK4_OPT_ARG_UNSIGNED}, { NULL }, 0},
+
+ /* 5 Help.
+ */
+ { { dkT('\0'),dkT("help"), DK4_OPT_ARG_NONE}, { NULL }, 0},
+
+ /* 6 Version.
+ */
+ { { dkT('\0'),dkT("version"), DK4_OPT_ARG_NONE}, { NULL }, 0},
+
+ /* 7 License
+ */
+ { { dkT('\0'),dkT("license"), DK4_OPT_ARG_NONE}, { NULL }, 0}
+};
+
+
+
+/** Help text.
+*/
+static const char * const help_text[] = {
+$!text
+
+Remote shutdown sender and recipient
+
+rshdown [-c config]
+rshdown -s [-n number] [-l port] [-b] host port file
+
+-c config Configuration file for recipient (daemon).
+
+-s Send shutdown data packet.
+-n number Send packet multiple times.
+-l port Local port to use for sending.
+-b Prepare socket for broadcast sending.
+host Remote host (recipient), host name or IP address.
+ Option -b is required if you specify a broadcast
+ address like 255.255.255.255 or 192.0.2.255 here.
+port Remote port.
+file File containing pre-shared secret (shutdown data).
+
+--help Show this help text.
+--version Show version number.
+--license Show license information.
+
+$!end
+};
+
+
+
+/** License conditions text.
+*/
+static const char * const license_text[] = {
+$!text preprocessor
+
+This software uses code from the following projects, either directly or as
+a library:
+
+dktools Dirk Krause's tools and libraries.
+ See http://dktools.sourceforge.net/ for more information.
+
+DK tools and libraries license
+==============================
+Copyright (c) 2015-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+$!end
+};
+
+
+
+/** Version information.
+*/
+static const char version_text[] = { DKT_VERSION_C8 };
+
+
+
+/** Default configuration file name.
+*/
+static const char def_conf_name[] = {
+ DK4_INST_DIR_ETC "/rshdown/rshdown.conf"
+};
+
+
+
+/** PID file name.
+*/
+static const char pid_file_name[] = {
+ DK4_INST_DIR_VAR "/run/rshdown.pid"
+};
+
+
+
+/** Key names expected in configuration file.
+*/
+static const char * const key_names[] = {
+$!string-table
+#
+# 0
+#
+sender
+#
+# 1
+#
+sender port
+#
+# 2
+#
+receiver port
+#
+# 3
+#
+signal
+#
+# 4
+#
+command
+#
+# 5
+#
+file
+#
+# 6
+#
+debug
+#
+# 7
+#
+syslog facility
+$!end
+};
+
+
+
+/** Signal names.
+*/
+static const char * const signal_names[] = {
+$!string-table
+# 0 1
+sighup
+hup
+# 2 3
+sigint
+int
+# 4 5
+sigquit
+quit
+# 6 7
+sigill
+ill
+# 8 9
+sigtrap
+trap
+# 10 11
+sigabrt
+abrt
+# 12 13
+sigiot
+iot
+# 14 15
+sigbus
+bus
+# 16 17
+sigfpe
+fpe
+# 18 19
+sigkill
+kill
+# 20 21
+sigusr1
+usr1
+# 22 23
+sigsegv
+segv
+# 24 25
+sigusr2
+usr2
+# 26 27
+sigpipe
+pipe
+# 28 29
+sigalrm
+alrm
+# 30 31
+sigterm
+term
+# 32 33
+sigstkflt
+stkflt
+# 34 35 36 37
+sigcld
+cld
+sigchld
+chld
+# 38 39
+sigcont
+cont
+# 40 41
+sigstop
+stop
+# 42 43
+sigtstp
+tstp
+# 44 45
+sigttin
+ttin
+# 46 47
+sigttou
+ttou
+# 48 49
+sigurg
+urg
+# 50 51
+sigxcpu
+xcpu
+# 52 53
+sigxfsz
+xfsz
+# 54 55
+sigvtalrm
+vtalrm
+# 56 57
+sigprof
+prof
+# 58 59
+sigwinch
+winch
+# 60 61
+sigpoll
+poll
+# 62 63
+sigio
+io
+# 64 65
+sigpwr
+pwr
+# 66 67
+sigsys
+sys
+$!end
+};
+
+
+
+/** Syslog facility names.
+*/
+static const char * const syslog_facility_names[] = {
+$!string-table
+auth
+authpriv
+cron
+daemon
+ftp
+kern
+lpr
+mail
+news
+security
+syslog
+user
+uucp
+local0
+local1
+local2
+local3
+local4
+local5
+local6
+local7
+$!end
+};
+
+
+/** Texts used by the program, not localized.
+*/
+static const char * const rshdown_kw[] = {
+$!string-table
+#
+# 0 Program name
+#
+rshdown
+#
+# 1
+#
+:
+#
+# 2
+#
+ERROR: Failed to set broadcast mode on socket!\n
+#
+# 3
+#
+ERROR: Failed to bind local address!\n
+#
+# 4 5
+#
+ERROR: Failed to bind local address: "
+"!\n
+#
+# 6
+#
+ERROR: Failed to create socket!\n
+#
+# 7 8
+#
+ERROR: Failed to find address for: "
+"!\n
+#
+# 9
+#
+ERROR: Failed to bring socket subsystem up!\n
+#
+# 10
+#
+ERROR: 3 arguments required: host, port and file!\n
+#
+# 11 12
+#
+ERROR: Not a 16 bit unsigned integer: "
+"!\n
+#
+# 13
+#
+ERROR: Port number 0 is not allowed!\n
+#
+# 14 15
+#
+ERROR: Failed to open data file:\n"
+"!\n
+#
+# 16 17
+#
+ERROR: Failed to read data from file:\n"
+"!\n
+#
+# 18
+#
+ERROR: Failed to install signal handlers!\n
+#
+# 19
+#
+ERROR: Failed to restore signal handlers!\n
+#
+# 20
+#
+ERROR: Failed to create child process!\n
+#
+# 21
+#
+Failed to detach from terminal!
+#
+# 22
+#
+Failed to create child process!
+#
+# 23 24
+#
+Failed to install signal handlers!
+Failed to restore signal handlers!
+#
+# 25
+#
+Failed to bring socket subsystem up!
+#
+# 26
+#
+Failed to create UDP socket set!
+#
+# 27 28
+#
+ERROR: Local port number too large!\n
+ERROR: Local port number must not be 0!\n
+#
+# 29 30
+#
+Failed to set allowed peer: "
+"!
+#
+# 31 32
+#
+ERROR: Illegal signal name: "
+"!\n
+#
+# 33 34
+#
+ERROR: Sender name too long:\n
+"!\n
+#
+# 35
+#
+ERROR: Sender name defined multiple times!\n
+#
+# 36
+#
+ERROR: Signal number must be positive!\n
+#
+# 37 38
+#
+ERROR: Command too long:\n"
+"!\n
+#
+# 39
+#
+ERROR: Command defined multiple times!\n
+#
+# 40 41
+#
+ERROR: File name too long:\n"
+"!\n
+#
+# 42
+#
+ERROR: File name defined multiple times!\n
+#
+# 43
+#
+ERROR: Unknown key in configuration file!\n
+#
+# 44
+#
+ERROR: Missing value on configuration line!\n
+#
+# 45
+#
+ERROR: No local port specified!\n
+#
+# 46
+#
+ERROR: Signal number or command required!\n
+#
+# 47
+#
+ERROR: No data file specified!\n
+#
+# 48 49
+#
+ERROR: Illegal syslog facility: "
+"!\n
+#
+# 50
+#
+Service started.
+#
+# 51
+#
+Initiate shutdown.
+#
+# 52
+#
+Service finished.
+#
+# 53 54
+#
+Packet from "
+" discarded, wrong sender address!
+#
+# 55 56
+#
+Packet from "
+" discarded, wrong sender port!
+#
+# 57 58
+#
+Packet from "
+" discarded, size mismatch!
+#
+# 59 60
+#
+Packet from "
+" discarded, data mismatch!
+#
+# 61 62
+#
+Failed to execute command: "
+"!
+$!end
+};
+
+
+
+/** Number of options in the options array.
+*/
+static const size_t szoptions = sizeof(options)/sizeof(dk4_option_t);
+
+
+
+/** Number of bytes in buffer b1.
+*/
+static size_t szb1 = 0;
+
+
+
+/** Number of bytes in buffer b2.
+*/
+static size_t szb2 = 0;
+
+
+
+/** Exit status code.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+/** Options: Help (1), version (2), license (4).
+*/
+static int hvl = 0;
+
+
+
+/** Flag: Additional debug messages.
+*/
+static int debug = 0;
+
+
+
+#ifdef LOG_DAEMON
+/** Syslog facility.
+*/
+static int syslogf = LOG_AUTH;
+#else
+/** Syslog facility.
+*/
+static int syslogf = (3<<3);
+#endif
+
+
+
+/** Signal to send on arrival of shutdown data packet.
+*/
+static int signo =
+#ifdef SIGPWR
+SIGPWR
+#else
+#ifdef SIGTERM
+SIGTERM
+#else
+15
+#endif
+#endif
+;
+
+
+
+#ifdef SIGPIPE
+/** Indicator: SIGPIPE signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_pipe = 0;
+#endif
+
+
+/** Indicator: SIGINT signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_int = 0;
+
+
+/** Indicator: SIGTERM signal received.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t sig_had_term = 0;
+
+
+
+/** Remote port.
+*/
+static unsigned short rp = 0U;
+
+
+
+/** Local port.
+*/
+static unsigned short lp = 0U;
+
+
+/** Pass pointer through.
+ Use of this function is recommended by CERT C coding standard
+ to avoid optimizing out.
+ @param ptr Pointer to pass through.
+ @return The ptr argument.
+*/
+static
+DK4_VOLATILE
+dk4_sig_atomic_t *
+sig_pass_pointer(DK4_VOLATILE dk4_sig_atomic_t *ptr)
+{
+ return ptr;
+}
+
+
+#ifdef SIGPIPE
+/** Handler for SIGPIPE signal.
+ @param signo Signal number (always SIGPIPE, ignored).
+*/
+static
+void
+sig_handler_pipe(int signo)
+{
+ *sig_pass_pointer(&sig_had_pipe) = 1;
+}
+#endif
+
+
+/** Handler for SIGINT signal.
+ @param signo Signal number (always SIGINT, ignored).
+*/
+static
+void
+sig_handler_int(int signo)
+{
+ *sig_pass_pointer(&sig_had_int) = 1;
+}
+
+
+/** Handler for SIGTERM signal.
+ @param signo Signal number (always SIGTERM, ignored).
+*/
+static
+void
+sig_handler_term(int signo)
+{
+ *sig_pass_pointer(&sig_had_term) = 1;
+}
+
+
+/** Read value from volatile atomic type.
+ This function is necessary as some compilers mis-optimize
+ direct access to volatile variables (at least if you believe
+ one of the coding standards).
+ @param ap Pointer to volatile atomic variable.
+ @return Contents of the variable.
+*/
+static
+dk4_sig_atomic_t
+sig_read_atomic(DK4_VOLATILE dk4_sig_atomic_t *ap)
+{
+ return (*ap);
+}
+
+
+/** Check whether we can continue or must abort due to signal.
+ @param dopipe Flag: Check for SIGPIPE too.
+ @return 1 if we can continue, 0 otherwise.
+*/
+static
+int
+can_continue(void)
+{
+ int back = 1;
+ if (0 != sig_read_atomic(&sig_had_term)) { back = 0; }
+ if (0 != sig_read_atomic(&sig_had_int)) { back = 0; }
+ return back;
+}
+
+
+
+/** Write log message to stderr, 1 component.
+ @param i Text index in rshdown_kw array.
+*/
+static
+void
+log_1(size_t i)
+{
+ fputs(rshdown_kw[0], stderr);
+ fputs(rshdown_kw[1], stderr);
+ fputs(rshdown_kw[i], stderr);
+ fflush(stderr);
+}
+
+
+
+/** Write syslog message, 1 component.
+ @param i Index of text in rshdown_kw array.
+*/
+static
+void
+syslog_1(size_t i)
+{
+#if DK4_HAVE_SYSLOG
+ openlog(rshdown_kw[0], LOG_PID, syslogf);
+ syslog(LOG_ERR, "%s", rshdown_kw[i]);
+ closelog();
+#endif
+}
+
+
+
+/** Write syslog message, 3 components.
+ @param i1 Index of first component in rshdown_kw array.
+ @param i2 Index of third component in rshdown_kw array.
+ @param str Second component.
+*/
+static
+void
+syslog_3(size_t i1, size_t i2, const char *str)
+{
+#if DK4_HAVE_SYSLOG
+ openlog(rshdown_kw[0], LOG_PID, syslogf);
+ if (NULL != str) {
+ syslog(LOG_ERR, "%s%s%s", rshdown_kw[i1], str, rshdown_kw[i2]);
+ } else {
+ syslog(LOG_ERR, "%s%s", rshdown_kw[i1], rshdown_kw[i2]);
+ }
+ closelog();
+#endif
+}
+
+
+
+/** Write an additional debug message to syslog.
+ @param i1 Index of first component in rshdown_kw array.
+ @param i2 Index of third component in rshdown_kw array.
+ @param sa Socket address, second component.
+*/
+static
+void
+syslog_debug(size_t i1, size_t i2, dk4_sockaddr_storage_t *sa)
+{
+#if DK4_HAVE_SYSLOG
+ char buf[128]; /* Buffer for text respresentation of address */
+ int res; /* Operation result from conversion */
+
+ if (0 != debug) {
+ res = dk4socket_c8_sockaddr_to_text(buf, sizeof(buf), sa, NULL);
+ openlog(rshdown_kw[0], LOG_PID, syslogf);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ syslog(LOG_DEBUG, "%s%s%s", rshdown_kw[i1], buf, rshdown_kw[i2]);
+ } else {
+ syslog(LOG_DEBUG, "%s%s", rshdown_kw[i1], rshdown_kw[i2]);
+ }
+ closelog();
+ }
+#endif
+}
+
+
+
+/** Write log message to stderr, 3 components.
+ @param i1 Index of first component in rshdown_kw array.
+ @param i2 Index of third component in rshdown_kw array.
+ @param str Second component.
+*/
+static
+void
+log_3(size_t i1, size_t i2, const char *str)
+{
+ fputs(rshdown_kw[0], stderr);
+ fputs(rshdown_kw[1], stderr);
+ fputs(rshdown_kw[i1], stderr);
+ if (NULL != str) { fputs(str, stderr); }
+ fputs(rshdown_kw[i2], stderr);
+ fflush(stderr);
+}
+
+
+
+/** Send buffer over network.
+ @param hn Remote host name or IP address as text.
+ @param rp Remote port in host representation.
+ @param lp Local port in host representation.
+ @param sz Number of bytes in b1.
+*/
+static
+void
+send_network(const char *hn, size_t sz)
+{
+ char adbuf[128]; /* Address as text */
+ dk4_sockaddr_storage_t array[2]; /* Address pair */
+ dk4_um_t num = (dk4_um_t)0UL;
+ size_t szr = 0; /* Rem addr size */
+ size_t szl = 0; /* Loc addr size */
+ size_t lgt = 0; /* Length sent */
+ dk4_socket_t sock = INVALID_SOCKET;
+ int res = 0; /* Operation result */
+ int ip4 = 0; /* IPv4 preferred */
+ int af = AF_UNSPEC;
+ int pf = PF_UNSPEC;
+ $? "+ send_network"
+ if (DK4_SOCKET_RESULT_SUCCESS == dk4socket_up(NULL)) {
+ if (options[2].found) { ip4 = 1; } $? ". socket subsystem up"
+ res = dk4socket_c8_udp_addresses_numeric(array, hn, rp, lp, ip4, NULL);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) { $? ". addresses ok"
+ szr = dk4socket_address_size(array);
+ szl = dk4socket_address_size(&(array[1]));
+ af = dk4socket_address_family(&(array[1]));
+ pf = dk4socket_pf_for_af(af);
+ if ((0 < szr) && (0 < szl) && (AF_UNSPEC != af) && (PF_UNSPEC != pf)) {
+ sock = dk4socket_open(pf, SOCK_DGRAM, 0, NULL);
+ if (INVALID_SOCKET != sock) { $? ". socket ok"
+ exval = EXIT_SUCCESS;
+ (void)dk4socket_option_set_reuse(sock, 1, NULL);
+ if (options[2].found) { $? ". prepare for broadcast"
+ res = dk4socket_option_set_broadcast(sock,1,NULL);
+ if (DK4_SOCKET_RESULT_SUCCESS != res) {
+ /* ERROR: Failed to set broadcast mode */
+ log_1(2);
+ exval = EXIT_FAILURE; $? "! broadcast preparation"
+ }
+ }
+ res = dk4socket_bind(
+ sock, (struct sockaddr *)(&(array[1])), szl, NULL
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) { $? ". address bound"
+ if (0 != options[3].found) { num = options[3].val.u; }
+ if ((dk4_um_t)0UL == num) { num = (dk4_um_t)1UL; }
+ while ((0 != can_continue()) && ((dk4_um_t)0UL < num--)) {
+ lgt = sz; $? ". send attempt"
+ res = dk4socket_sendto(
+ sock, b1, &lgt, 0,
+ (struct sockaddr *)(&(array[0])), szr,
+ 0L, 0L, NULL
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) { $? ". sendto ok"
+ if (lgt != sz) { exval = EXIT_FAILURE; }
+ } else { $? "! sendto failed"
+ exval = EXIT_FAILURE;
+ }
+ }
+ } else { $? "! failed to bind local addr"
+ /* ERROR: Failed to bind local address */
+ res = dk4socket_c8_addr_port_to_text(
+ adbuf, sizeof(adbuf),
+ af, (struct sockaddr *)(&(array[1])), szl, NULL
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ log_3(4, 5, adbuf);
+ } else {
+ log_1(3);
+ }
+ }
+ (void)dk4socket_close(sock, NULL);
+ } else { $? "! failed to open socket"
+ /* ERROR: Failed to open socket */
+ log_1(6);
+ }
+ } else { $? "! something wrong"
+ if (0 == szr) { $? "! remote address size"
+ log_3(7, 8, hn);
+ }
+ if (0 == szl) { $? "! local address size"
+ log_3(7, 8, hn);
+ }
+ if (AF_UNSPEC == af) { $? "! address family"
+ log_3(7, 8, hn);
+ }
+ if (PF_UNSPEC == pf) { $? "! protocol family"
+ log_3(7, 8, hn);
+ }
+ }
+ } else { $? "! addresses not found"
+ /* ERROR: Failed to obtain addresses */
+ log_3(7, 8, hn);
+ }
+ (void)dk4socket_down(NULL);
+ } else { $? "! socket subsystem"
+ /* ERROR: Failed to bring socket subsystem up */
+ log_1(9);
+ }
+ $? "- send_network"
+}
+
+
+
+/** Send shutdown data packet.
+ @param filenames Command line arguments array,
+ 0=remote host, 1=remote port, 2=filename.
+ @param szfilenames Number of elements in filenames array.
+*/
+static
+void
+sender_with_signals(const char * const *filenames, size_t szfilenames)
+{
+ FILE *fipo = NULL; /* Data file */
+ const char *ep = NULL; /* End of usefull data pointer */
+ size_t lgt = 0; /* Number of bytes in buffer */
+ int res = 0; /* Conversion or operation result */
+ $? "+ sender_with_signals"
+ if (3 == szfilenames) { $? ". szfilenames"
+ res = dk4ma_input_c8_dec_ushort(&rp, filenames[1], &ep, 1, NULL);
+ if (0 != res) { $? ". port number"
+ if (0 != rp) { $? ". port number not 0"
+ lp = rp;
+ if (0 != options[4].found) { $? ". local port given"
+ if ((dk4_um_t)0UL < options[4].val.u) { $? ". lp ok"
+ if ((dk4_um_t)(USHRT_MAX) >= options[4].val.u) {
+ lp = (unsigned short)(options[4].val.u); $? ". lp ok"
+ } else { $? "! overflow"
+ lp = 0;
+ /* ERROR: Local port number exceeds 16 bit unsigned range */
+ log_1(27);
+ }
+ } else { $? "! lp 0"
+ lp = 0;
+ /* ERROR: Local port number 0 is not allowed */
+ log_1(28);
+ }
+ }
+ if (0 != lp) { $? ". can run"
+ fipo = dk4fopen_c8(filenames[2], "rb", DK4_FOPEN_SC_IS_REGULAR, NULL);
+ if (NULL != fipo) { $? ". data file opened"
+ lgt = fread(b1, 1, sizeof(b1), fipo);
+ fclose(fipo);
+ if (0 < lgt) { $? ". data from file"
+ /* Send bytes over network */
+ send_network(filenames[0], lgt);
+ /* Overwrite memory containing data packet */
+ if (0 == dk4mem_reset_secure(b1, sizeof(b1), NULL)) {
+ exval = EXIT_FAILURE; $? "! reset mem failed"
+ }
+ } else { $? "! no data from file"
+ /* ERROR: No data read from file */
+ log_3(16, 17, filenames[2]);
+ }
+ } else { $? "! data file"
+ /* ERROR: Failed to open data file */
+ log_3(14, 15, filenames[2]);
+ }
+ } else { $? "! config"
+ }
+ } else { $? "! port number 0"
+ /* ERROR: Remote port number 0 is not allowed */
+ log_1(13);
+ }
+ } else { $? "! port number"
+ /* ERROR: Not a 16 bit unsigned number */
+ log_3(11, 12, filenames[1]);
+ }
+ } else { $? "! szfilenames"
+ /* ERROR: Three arguments required - host, port and file */
+ log_1(10);
+ }
+ $? "- sender_with_signals"
+}
+
+
+
+/** Send shutdown data packet.
+ @param filenames Command line arguments array,
+ 0=remote host, 1=remote port, 2=filename.
+ @param szfilenames Number of elements in filenames array.
+*/
+static
+void
+sender(const char * const *filenames, size_t szfilenames)
+{
+ $!trace-init rshdown.deb
+ $? "+ sender"
+#ifdef DK4_HAVE_SIGACTION
+#ifdef SIGPIPE
+ struct sigaction opipe;
+ struct sigaction npipe;
+#endif
+ struct sigaction oint;
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+#else
+#ifdef SIGPIPE
+ dk4_sig_handler_t *opipe = NULL;
+#endif
+ dk4_sig_handler_t *oterm = NULL;
+ dk4_sig_handler_t *oint = NULL;
+#endif
+#ifdef DK4_HAVE_SIGACTION
+#ifdef SIGPIPE
+ int spipe = 0;
+#endif
+ int sint = 0;
+ int sterm = 0;
+ int s_f_i = 0;
+ int s_f_r = 0;
+#endif
+
+ /* Set signal handlers
+ */
+#if DK4_HAVE_SIGACTION
+#ifdef SIGPIPE
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ spipe = 1;
+#endif
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ sterm = 1;
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ sint = 1;
+#else
+#ifdef SIGPIPE
+ opipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oint = sigset(SIGINT, sig_handler_int);
+ oterm = sigset(SIGTERM, sig_handler_term);
+#endif
+
+ /* Send the bytes.
+ */
+ sender_with_signals(filenames, szfilenames);
+
+ finished:
+
+ /* Restore signal handlers
+ */
+#if DK4_HAVE_SIGACTION
+ if (0 != s_f_i) {
+ /* ERROR: Failed to install signal handlers */
+ log_1(18);
+ exval = EXIT_FAILURE;
+ }
+ if (0 != sint) {
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ s_f_r = 1;
+ }
+ }
+ if (0 != sterm) {
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ s_f_r = 1;
+ }
+ }
+#ifdef SIGPIPE
+ if (0 != spipe) {
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ s_f_r = 1;
+ }
+ }
+#endif
+ if (0 != s_f_r) {
+ /* ERROR: Failed to restore signal handlers */
+ log_1(19);
+ exval = EXIT_FAILURE;
+ }
+#else
+ if (NULL != oterm) { sigset(SIGTERM, oterm); }
+ if (NULL != oint ) { sigset(SIGINT, oint ); }
+#ifdef SIGPIPE
+ if (NULL != opipe) { sigset(SIGPIPE, opipe); }
+#endif
+#endif
+ $? "- sender"
+ $!trace-end
+}
+
+
+
+/** Run service
+*/
+static
+void
+run_daemon_loop(void)
+{
+ dk4_allowed_peer_t peer; /* Allowed remote address */
+ dk4_sockaddr_storage_t sa; /* Generic socket address */
+ fd_set rfds; /* Readable file descriptors */
+ dk4_socket_set_t *sset = NULL; /* Set of sockets to read data from */
+ struct sockaddr *soa = NULL; /* Minimum socket address */
+ struct sockaddr_in *so4 = NULL; /* IPv4 socket address */
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ struct sockaddr_in6 *so6 = NULL; /* IPv6 socket address */
+#endif
+ size_t szsa = 0; /* Size of sa */
+ size_t i = 0; /* Traverse socket set */
+ dk4_socket_t smax = 0; /* Maximum socket fd number */
+ int cc = 1; /* Flag: Can continue */
+ int pused = 0; /* Flag: Peer used */
+ int res = 0; /* Operation result */
+ int ok = 0; /* Flag: Data packet matches file */
+ unsigned short frp = 0; /* Found remote port */
+ $? "+ run_daemon_loop"
+ soa = (struct sockaddr *)(&sa);
+ so4 = (struct sockaddr_in *)(&sa);
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ so6 = (struct sockaddr_in6 *)(&sa);
+#endif
+ if (DK4_SOCKET_RESULT_SUCCESS == dk4socket_up(NULL)) {
+ $? ". socket subsystem"
+ if (0 < strlen(asender)) { $? ". sender specified"
+ res = dk4socket_c8_get_allowed_peer(&peer, asender, NULL);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) { $? ". peer found"
+ pused = 1;
+ } else { $? "! peer not found"
+ cc = 0;
+ /* SYSLOG ERROR: Invalid peer name */
+ syslog_3(29, 30, asender);
+ }
+ }
+ if (1 == cc) { $? ". no errors yet"
+ sset = dk4socket_set_udp_directly(lp, 0, 0, NULL);
+ if (NULL != sset) { $? ". socket set ok"
+ /* SYSLOG: Started */
+#if DK4_HAVE_SYSLOG
+ openlog(rshdown_kw[0], LOG_PID, syslogf);
+ syslog(LOG_INFO, "%s", rshdown_kw[50]);
+ closelog();
+#endif
+ do {
+ if (0 != can_continue()) {
+ FD_ZERO(&rfds);
+ smax = -1;
+ for (i = 0; i < sset->szUsed; i++) {
+ $? ". socket %d", (sset->pSockets)[i]
+ FD_SET((sset->pSockets)[i],&rfds);
+ if (smax < (sset->pSockets)[i]) { smax = (sset->pSockets)[i]; }
+ }
+ res = select((1+smax), &rfds, NULL, NULL, NULL);
+ if (0 != can_continue()) {
+ if (0 < res) { $? ". data available"
+ for (i = 0; ((1 == cc) && (i < sset->szUsed)); i++) {
+ $? ". checking %d", (sset->pSockets)[i]
+ if (FD_ISSET((sset->pSockets)[i],&rfds)) {
+ $? ". ready to read"
+ DK4_MEMRES(&sa, sizeof(sa));
+ szb2 = sizeof(b2);
+ szsa = sizeof(sa);
+ res = dk4socket_recvfrom(
+ (sset->pSockets)[i], b2, &szb2, 0,
+ (struct sockaddr *)(&sa), &szsa, 0L, 0L, NULL
+ );
+ if (0 != can_continue()) { $? ". can continue"
+ if (DK4_SOCKET_RESULT_SUCCESS == res) { $? ". read"
+ if (0 < szb2) { $? ". %u bytes received", (unsigned)szb2
+ ok = 1;
+ if (0 != pused) { $? ". check peer"
+ res = dk4socket_allowed_peer_compare(&peer, &sa, 1);
+ if (0 != res) { $? "! address mismatch"
+ ok = 0;
+ /* SYSLOG DEBUG: Address mismatch */
+ syslog_debug(53, 54, &sa);
+ }
+ }
+ if (0U != rp) { $? ". check port"
+ frp = 0;
+ switch (soa->sa_family) {
+ case AF_INET : {
+ frp = dk4socket_ntohs(so4->sin_port);
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6
+ case AF_INET6 : {
+ frp = dk4socket_ntohs(so6->sin6_port);
+ } break;
+#endif
+ }
+ if (frp != rp) { $? "! port mismatch"
+ ok = 0;
+ /* SYSLOG DEBUG: Port mismatch */
+ syslog_debug(55, 56, &sa);
+ }
+ }
+ if (0 != ok) { $? ". peer/port ok"
+ ok = 0;
+ if (szb1 == szb2) { $? ". size match"
+ if (0 == DK4_MEMCMP(b1,b2,szb1)) {
+ ok = 1; $? ". data matches"
+ } else { $? "! data mismatch"
+ /* SYSLOG DEBUG: Data mismatch */
+ syslog_debug(59, 60, &sa);
+ }
+ } else { $? "! size mismatch"
+ /* SYSLOG DEBUG: Size mismatch */
+ syslog_debug(57, 58, &sa);
+ }
+ }
+ if (0 != ok) { $? ". going to shut down"
+ /* Shutdown */
+ /* SYSLOG: Initiating shutdown */
+#if DK4_HAVE_SYSLOG
+ openlog(rshdown_kw[0], LOG_PID, syslogf);
+ syslog(LOG_INFO, "%s", rshdown_kw[51]);
+ closelog();
+#endif
+ if (0 < strlen(cmd)) { $? ". command"
+ if (0 != system(cmd)) {
+#if DK4_HAVE_SYSLOG
+
+ openlog(rshdown_kw[0], LOG_PID, syslogf);
+ syslog(
+ LOG_ERR, "%s%s%s",
+ rshdown_kw[61], cmd, rshdown_kw[62]
+ );
+ closelog();
+#endif
+ }
+ } else { $? ". signal"
+ if (0 < signo) {
+ kill((pid_t)1, signo);
+ } else {
+#ifdef SIGPWR
+ kill((pid_t)1, SIGPWR);
+#else
+#ifdef SIGTERM
+ kill((pid_t)1, SIGTERM);
+#else
+ kill((pid_t)1, 15);
+#endif
+#endif
+ }
+ }
+ cc = 0;
+ }
+ } else { $? "! size is 0"
+ }
+ } else { $? "! recvfrom"
+ }
+ } else { $? "! signal"
+ cc = -1;
+ }
+ } else { $? ". not ready to read"
+ }
+ }
+ } else { $? ". no fd ready"
+ }
+ } else { $? "! signal"
+ cc = -1;
+ }
+ } else { $? "! signal"
+ cc = -1;
+ }
+ } while (1 == cc); $? ". loop finished"
+ dk4socket_set_close(sset, NULL);
+ /* SYSLOG: Finished */
+#if DK4_HAVE_SYSLOG
+ openlog(rshdown_kw[0], LOG_PID, syslogf);
+ syslog(LOG_INFO, "%s", rshdown_kw[52]);
+ closelog();
+#endif
+ } else { $? "! socket set"
+ /* SYSLOG ERROR: Failed to create socket set */
+ syslog_1(26);
+ }
+ } else { $? "! previous errors"
+ }
+ (void)dk4socket_down(NULL);
+ } else { $? "! socket subsystem"
+ /* SYSLOG ERROR: Failed to bring socket subsystem up */
+ syslog_1(25);
+ }
+ $? "- run_daemon_loop"
+}
+
+
+
+/** Set signal handlers and run service.
+*/
+static
+void
+run_daemon_with_signals(void)
+{
+#ifdef DK4_HAVE_SIGACTION
+#ifdef SIGPIPE
+ struct sigaction opipe;
+ struct sigaction npipe;
+#endif
+ struct sigaction oint;
+ struct sigaction nint;
+ struct sigaction oterm;
+ struct sigaction nterm;
+#else
+#ifdef SIGPIPE
+ dk4_sig_handler_t *opipe = NULL;
+#endif
+ dk4_sig_handler_t *oterm = NULL;
+ dk4_sig_handler_t *oint = NULL;
+#endif
+#ifdef DK4_HAVE_SIGACTION
+#ifdef SIGPIPE
+ int spipe = 0;
+#endif
+ int sint = 0;
+ int sterm = 0;
+ int s_f_i = 0;
+ int s_f_r = 0;
+#endif
+ $? "+ run_daemon_with_signals"
+ /* Set signal handlers
+ */
+#if DK4_HAVE_SIGACTION
+#ifdef SIGPIPE
+ DK4_MEMRES(&npipe, sizeof(npipe));
+ npipe.sa_handler = sig_handler_pipe;
+ npipe.sa_flags = 0;
+ if (0 != sigemptyset(&npipe.sa_mask)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaddset(&npipe.sa_mask, SIGPIPE)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaction(SIGPIPE, &npipe, &opipe)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ spipe = 1;
+#endif
+ DK4_MEMRES(&nterm, sizeof(nterm));
+ nterm.sa_handler = sig_handler_term;
+ nterm.sa_flags = 0;
+ if (0 != sigemptyset(&nterm.sa_mask)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaddset(&nterm.sa_mask, SIGTERM)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaction(SIGTERM, &nterm, &oterm)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ sterm = 1;
+ DK4_MEMRES(&nint, sizeof(nint));
+ nint.sa_handler = sig_handler_int;
+ nint.sa_flags = 0;
+ if (0 != sigemptyset(&nint.sa_mask)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaddset(&nint.sa_mask, SIGINT)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ if (0 != sigaction(SIGINT, &nint, &oint)) {
+ s_f_i = 1;
+ goto finished;
+ }
+ sint = 1;
+#else
+#ifdef SIGPIPE
+ opipe = sigset(SIGPIPE, sig_handler_pipe);
+#endif
+ oint = sigset(SIGINT, sig_handler_int);
+ oterm = sigset(SIGTERM, sig_handler_term);
+#endif
+
+ run_daemon_loop();
+
+ finished:
+
+ /* Restore signal handlers
+ */
+#if DK4_HAVE_SIGACTION
+ if (0 != s_f_i) {
+ /* ERROR: Failed to install signal handlers */
+ syslog_1(23);
+ exval = EXIT_FAILURE;
+ }
+ if (0 != sint) {
+ if (0 != sigaction(SIGINT, &oint, NULL)) {
+ s_f_r = 1;
+ }
+ }
+ if (0 != sterm) {
+ if (0 != sigaction(SIGTERM, &oterm, NULL)) {
+ s_f_r = 1;
+ }
+ }
+#ifdef SIGPIPE
+ if (0 != spipe) {
+ if (0 != sigaction(SIGPIPE, &opipe, NULL)) {
+ s_f_r = 1;
+ }
+ }
+#endif
+ if (0 != s_f_r) {
+ /* ERROR: Failed to restore signal handlers */
+ syslog_1(24);
+ exval = EXIT_FAILURE;
+ }
+#else
+ if (NULL != oterm) { sigset(SIGTERM, oterm); }
+ if (NULL != oint ) { sigset(SIGINT, oint ); }
+#ifdef SIGPIPE
+ if (NULL != opipe) { sigset(SIGPIPE, opipe); }
+#endif
+#endif
+ $? "- run_daemon_with_signals"
+}
+
+
+
+/** Retrieve port number from a configuration file line.
+ @param dest Address of destination variable.
+ @param pv String containing the port number.
+ @param fn File name for diagnostics.
+ @param lineno Line number for diagnostics.
+ @param a0 Flag: Remote port, 0 allowed for arbitrary ports.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+set_port_number(
+ unsigned short *dest, const char *pv, const char *fn, dk4_um_t lineno, int a0
+)
+{
+ const char *ep = NULL;
+ int back = 0;
+ unsigned short us = 0U;
+
+ if (0 != dk4ma_input_c8_dec_ushort(&us, pv, &ep, 1, NULL)) {
+ if (0U != us) {
+ *dest = us;
+ back = 1;
+ } else {
+ if (0 != a0) {
+ *dest = us;
+ back = 1;
+ } else {
+ /* ERROR: Port number 0 not allowed! */
+ log_1(28);
+ }
+ }
+ } else {
+ /* ERROR: Not a 16 bit unsigned number! */
+ log_3(11, 12, pv);
+ }
+ return back;
+}
+
+
+
+/** Set the signal number.
+ @param pv Text containing the number.
+ @param fn File name for diagnostics.
+ @param lineno Line number for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+set_signal_number(const char *pv, const char *fn, dk4_um_t lineno)
+{
+ int back = 1;
+ $? "+ set_signal_number \"%s\"", TR_8STR(pv)
+ switch ( dk4str8_array_index(signal_names, pv, 0) ) {
+ case 0 : case 1 : {
+#ifdef SIGHUP
+ signo = SIGHUP;
+#else
+ signo = 1;
+#endif
+ } break;
+ case 2 : case 3 : {
+#ifdef SIGINT
+ signo = SIGINT;
+#else
+ signo = 2;
+#endif
+ } break;
+ case 4 : case 5 : {
+#ifdef SIGQUIT
+ signo = SIGQUIT;
+#else
+ signo = 3;
+#endif
+ } break;
+ case 6 : case 7 : {
+#ifdef SIGILL
+ signo = SIGILL;
+#else
+ signo = 4;
+#endif
+ } break;
+ case 8 : case 9 : {
+#ifdef SIGTRAP
+ signo = SIGTRAP;
+#else
+ signo = 5;
+#endif
+ } break;
+ case 10 : case 11 : case 12 : case 13 : {
+#ifdef SIGABRT
+ signo = SIGABRT;
+#else
+#ifdef SIGIOT
+ signo = SIGIOT;
+#else
+ signo = 6;
+#endif
+#endif
+ } break;
+ case 14 : case 15 : {
+#ifdef SIGBUS
+ signo = SIGBUS;
+#else
+ signo = 7;
+#endif
+ } break;
+ case 16 : case 17 : {
+#ifdef SIGFPE
+ signo = SIGFPE;
+#else
+ signo = 8;
+#endif
+ } break;
+ case 18 : case 19 : {
+#ifdef SIGKILL
+ signo = SIGKILL;
+#else
+ signo = 9;
+#endif
+ } break;
+ case 20 : case 21 : {
+#ifdef SIGUSR1
+ signo = SIGUSR1;
+#else
+ signo = 10;
+#endif
+ } break;
+ case 22 : case 23 : {
+#ifdef SIGSEGV
+ signo = SIGSEGV;
+#else
+ signo = 11;
+#endif
+ } break;
+ case 24 : case 25 : {
+#ifdef SIGUSR2
+ signo = SIGUSR2;
+#else
+ signo = 12;
+#endif
+ } break;
+ case 26 : case 27 : {
+#ifdef SIGPIPE
+ signo = SIGPIPE;
+#else
+ signo = 13;
+#endif
+ } break;
+ case 28 : case 29 : {
+#ifdef SIGALRM
+ signo = SIGALRM;
+#else
+ signo = 14;
+#endif
+ } break;
+ case 30 : case 31 : {
+#ifdef SIGTERM
+ signo = SIGTERM;
+#else
+ signo = 15;
+#endif
+ } break;
+ case 32 : case 33 : {
+#ifdef SIGSTKFLT
+ signo = SIGSTKFLT;
+#else
+ signo = 16;
+#endif
+ } break;
+ case 34 : case 35 : case 36 : case 37 : {
+#ifdef SIGCLD
+ signo = SIGCLD;
+#else
+#ifdef SIGCHLD
+ signo = SIGCHLD;
+#else
+ signo = 17;
+#endif
+#endif
+ } break;
+ case 38 : case 39 : {
+#ifdef SIGCONT
+ signo = SIGCONT;
+#else
+ signo = 18;
+#endif
+ } break;
+ case 40 : case 41 : {
+#ifdef SIGSTOP
+ signo = SIGSTOP;
+#else
+ signo = 19;
+#endif
+ } break;
+ case 42 : case 43 : {
+#ifdef SIGTSTP
+ signo = SIGTSTP;
+#else
+ signo = 20;
+#endif
+ } break;
+ case 44 : case 45 : {
+#ifdef SIGTTIN
+ signo = SIGTTIN;
+#else
+ signo = 21;
+#endif
+ } break;
+ case 46 : case 47 : {
+#ifdef SIGTTOU
+ signo = SIGTTOU;
+#else
+ signo = 22;
+#endif
+ } break;
+ case 48 : case 49 : {
+#ifdef SIGURG
+ signo = SIGURG;
+#else
+ signo = 23;
+#endif
+ } break;
+ case 50 : case 51 : {
+#ifdef SIGXCPU
+ signo = SIGXCPU;
+#else
+ signo = 24;
+#endif
+ } break;
+ case 52 : case 53 : {
+#ifdef SIGXFSZ
+ signo = SIGXFSZ;
+#else
+ signo = 25;
+#endif
+ } break;
+ case 54 : case 55 : {
+#ifdef SIGVTALRM
+ signo = SIGVTALRM;
+#else
+ signo = 26;
+#endif
+ } break;
+ case 56 : case 57 : {
+#ifdef SIGPROF
+ signo = SIGPROF;
+#else
+ signo = 27;
+#endif
+ } break;
+ case 58 : case 59 : {
+#ifdef SIGWINCH
+ signo = SIGWINCH;
+#else
+ signo = 28;
+#endif
+ } break;
+ case 60 : case 61 : case 62 : case 63 : {
+#ifdef SIGPOLL
+ signo = SIGPOLL;
+#else
+#ifdef SIGIO
+ signo = SIGIO
+#else
+ signo = 29;
+#endif
+#endif
+ } break;
+ case 64 : case 65 : {
+#ifdef SIGPWR
+ signo = SIGPWR;
+#else
+ signo = 30;
+#endif
+ } break;
+ case 66 : case 67 : {
+#ifdef SIGSYS
+ signo = SIGSYS;
+#else
+ signo = 31;
+#endif
+ } break;
+ default : { $? "! illegal signal name"
+ back = 0;
+ /* ERROR: Illegal signal name */
+ log_3(31, 32, pv);
+ } break;
+ } $? "- set_signal_number %d", back
+ return back;
+}
+
+
+
+/** Set syslog facility.
+ @param pv Text representation of syslog facility.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+set_syslog_facility(const char *pv)
+{
+ int back = 1;
+ if (NULL != pv) {
+ switch ( dk4str8_array_index(syslog_facility_names, pv, 0) ) {
+#ifdef LOG_AUTH
+ case 0: { syslogf = LOG_AUTH; } break;
+#endif
+#ifdef LOG_AUTHPRIV
+ case 1: { syslogf = LOG_AUTHPRIV; } break;
+#endif
+#ifdef LOG_CRON
+ case 2: { syslogf = LOG_CRON; } break;
+#endif
+#ifdef LOG_DAEMON
+ case 3: { syslogf = LOG_DAEMON; } break;
+#endif
+#ifdef LOG_FTP
+ case 4: { syslogf = LOG_FTP; } break;
+#endif
+#ifdef LOG_KERN
+ case 5: { syslogf = LOG_KERN; } break;
+#endif
+#ifdef LOG_LPR
+ case 6: { syslogf = LOG_LPR; } break;
+#endif
+#ifdef LOG_MAIL
+ case 7: { syslogf = LOG_MAIL; } break;
+#endif
+#ifdef LOG_NEWS
+ case 8: { syslogf = LOG_NEWS; } break;
+#endif
+#ifdef LOG_AUTH
+ case 9: { syslogf = LOG_AUTH; } break;
+#endif
+#ifdef LOG_SYSLOG
+ case 10: { syslogf = LOG_SYSLOG; } break;
+#endif
+#ifdef LOG_USER
+ case 11: { syslogf = LOG_USER; } break;
+#endif
+#ifdef LOG_UUCP
+ case 12: { syslogf = LOG_UUCP; } break;
+#endif
+#ifdef LOG_LOCAL0
+ case 13: { syslogf = LOG_LOCAL0; } break;
+#endif
+#ifdef LOG_LOCAL1
+ case 14: { syslogf = LOG_LOCAL1; } break;
+#endif
+#ifdef LOG_LOCAL2
+ case 15: { syslogf = LOG_LOCAL2; } break;
+#endif
+#ifdef LOG_LOCAL3
+ case 16: { syslogf = LOG_LOCAL3; } break;
+#endif
+#ifdef LOG_LOCAL4
+ case 17: { syslogf = LOG_LOCAL4; } break;
+#endif
+#ifdef LOG_LOCAL5
+ case 18: { syslogf = LOG_LOCAL5; } break;
+#endif
+#ifdef LOG_LOCAL6
+ case 19: { syslogf = LOG_LOCAL6; } break;
+#endif
+#ifdef LOG_LOCAL7
+ case 20: { syslogf = LOG_LOCAL7; } break;
+#endif
+ default: {
+ back = 0;
+ log_3(48, 49, pv);
+ } break;
+ }
+ }
+ return back;
+}
+
+
+
+/** Read configuration file.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+read_config_file(void)
+{
+ FILE *fipo = NULL; /* Input file to process */
+ const char *fn = NULL; /* Input file name */
+ const char *ep = NULL; /* End pointer after number */
+ char *pk = NULL; /* Pointer to key string */
+ char *pv = NULL; /* Pointer to value string */
+ dk4_um_t lineno = (dk4_um_t)0UL; /* Current line number */
+ int back = 0;
+ $? "+ read_config_file"
+ if (0 != options[0].found) { fn = options[0].val.t; }
+ if (NULL == fn) { fn = def_conf_name; }
+ fipo = dk4fopen_c8(fn, "r", DK4_FOPEN_SC_IS_REGULAR, NULL);
+ if (NULL != fipo) {
+ back = 1;
+ while( fgets(b1, sizeof(b1), fipo) ) {
+ lineno++;
+ pk = dk4str8_start(b1, NULL);
+ if (NULL != pk) {
+ if ('#' != *pk) {
+ pv = dk4str8_chr(pk, '=');
+ if (NULL != pv) {
+ *(pv++) = '\0';
+ pv = dk4str8_start(pv, NULL);
+ if (NULL != pv) {
+ dk4str8_normalize(pk, NULL);
+ dk4str8_delnl(pv);
+ switch ( dk4str8_array_index(key_names, pk, 0) ) {
+ case 0: { /* sender address */
+ if (0 == strlen(asender)) {
+ dk4str8_normalize(pv, NULL);
+ if (0 == dk4str8_cpy_s(asender,sizeof(asender),pv,NULL)) {
+ back = 0; $? "! sender too long"
+ /* ERROR: Sender name too long */
+ log_3(33, 34, pv);
+ }
+ } else { $? "! redefinition of sender"
+ back = 0;
+ /* ERROR: Redefinition of sender */
+ log_1(35);
+ }
+ } break;
+ case 1: { /* sender port */
+ if (0 == set_port_number(&rp, pv, fn, lineno, 1)) {
+ back = 0; $? "! remote port not numeric"
+ }
+ } break;
+ case 2: { /* local port */
+ if (0 == set_port_number(&lp, pv, fn, lineno, 0)) {
+ back = 0; $? "! local port not numeric"
+ }
+ } break;
+ case 3: { /* signal */
+ ep = NULL;
+ if (0 != dk4ma_input_c8_dec_int(&signo, pv, &ep, 1, NULL)) {
+ if (1 > signo) {
+ back = 0; $? "! illegal value for signo"
+ /* ERROR: Signal number must be positive */
+ log_1(36);
+ }
+ } else {
+ dk4str8_normalize(pv, NULL);
+ if (0 == set_signal_number(pv, fn, lineno)) {
+ back = 0; $? "! failed to set signo"
+ }
+ }
+ } break;
+ case 4: { /* command */
+ if (0 == strlen(cmd)) {
+ if (0 == dk4str8_cpy_s(cmd, sizeof(cmd), pv, NULL)) {
+ back = 0;
+ /* ERROR: Command too long! */
+ log_3(37, 38, pv);
+ }
+ } else { $? "! command redefined"
+ back = 0;
+ /* ERROR: Redefinition of command */
+ log_1(39);
+ }
+ } break;
+ case 5: { /* file */
+ if (0 == strlen(file_name)) {
+ if (0 == dk4str8_cpy_s(file_name,sizeof(file_name),pv,NULL))
+ {
+ back = 0;
+ /* ERROR: File name too long! */
+ log_3(40, 41, pv);
+ }
+ } else { $? "! file name redefined"
+ back = 0;
+ /* ERROR: Redefinition of file name */
+ log_1(42);
+ }
+ } break;
+ case 6: {
+ debug = ((dk4str8_is_on(pv)) ? 1 : 0);
+ } break;
+ case 7: {
+ dk4str8_normalize(pv, NULL);
+ if (0 == set_syslog_facility(pv)) {
+ back = 0;
+ }
+ } break;
+ default : { $? "! unknown key"
+ log_1(43);
+ } break;
+ }
+ } else { $? "! missing value"
+ back = 0;
+ /* ERROR: Missing value */
+ log_1(44);
+ }
+ } else { $? "! missing value"
+ back = 0;
+ /* ERROR: Missing value */
+ log_1(44);
+ }
+ }
+ }
+ }
+ fclose(fipo);
+ if ((0 != back) && (0U == lp)) {
+ back = 0; $? "! missing local port"
+ /* ERROR: Local port not specified */
+ log_1(45);
+ }
+ if (0 != back) {
+ if ((0 == signo) && (0 == strlen(cmd))) {
+ back = 0; $? "! command or signo"
+ /* ERROR: Signal or command required */
+ log_1(46);
+ }
+ }
+ if (0 != back) {
+ if (0 != strlen(file_name)) {
+ fipo = dk4fopen_c8(file_name, "rb", DK4_FOPEN_SC_IS_REGULAR, NULL);
+ if (NULL != fipo) {
+ szb1 = fread(b1, 1, sizeof(b1), fipo);
+ fclose(fipo);
+ if (0 == szb1) {
+ back = 0; $? "! data file contents"
+ /* ERROR: Failed to read data from file */
+ log_3(16, 17, file_name);
+ }
+ } else { $? "! open data file"
+ back = 0;
+ /* ERROR: Failed to open data file */
+ log_3(14, 15, file_name);
+ }
+ } else { $? "! data file name"
+ back = 0;
+ /* ERROR: No data file specified */
+ log_1(47);
+ }
+ }
+ } else { $? "! failed to open conf file"
+ } $? "- read_config_file %d", back
+ return back;
+}
+
+
+
+/** Daemon waiting for shutdown data packet.
+*/
+static
+void
+run_as_daemon(void)
+{
+ pid_t cpid;
+ $? "+ run_as_daemon"
+ /* Preparations before we start.
+ */
+ DK4_MEMRES(cmd, sizeof(cmd));
+ DK4_MEMRES(asender, sizeof(asender));
+ DK4_MEMRES(file_name, sizeof(file_name));
+ if (read_config_file()) { $? ". conf ok"
+ if (0 != dk4dmt_parent_before_fork(rshdown_kw[0],pid_file_name,1,syslogf)) {
+ cpid = fork();
+ if ((pid_t)0 == cpid) { /* in the child */
+ if (0 != dk4dmt_intermediate_before_fork(rshdown_kw[0], syslogf)) {
+ cpid = fork();
+ if ((pid_t)0 == cpid) { /* in the child */
+ $!trace-init /tmp/rshdown.deb
+ $? "+ daemon process"
+ exval = EXIT_SUCCESS;
+ if (dk4dmt_daemon_after_fork(rshdown_kw[0],pid_file_name,syslogf)) {
+ run_daemon_with_signals();
+ }
+ dk4dmt_daemon_end(rshdown_kw[0], pid_file_name, syslogf);
+ if (0 == dk4mem_reset_secure(b1, sizeof(b1), NULL)) {
+ exval = EXIT_FAILURE;
+ }
+ if (0 == dk4mem_reset_secure(b2, sizeof(b2), NULL)) {
+ exval = EXIT_FAILURE;
+ }
+ $? "- daemon process %d", exval
+ $!trace-end
+ } else {
+ if ((pid_t)(-1) != cpid) { /* intermediate process */
+ exval = EXIT_SUCCESS;
+ if (0 == dk4mem_reset_secure(b1, sizeof(b1), NULL)) {
+ exval = EXIT_FAILURE;
+ }
+ if (0 == dk4mem_reset_secure(b2, sizeof(b2), NULL)) {
+ exval = EXIT_FAILURE;
+ }
+ } else { /* error */
+ if (0 == dk4mem_reset_secure(b1, sizeof(b1), NULL)) {
+ exval = EXIT_FAILURE;
+ }
+ if (0 == dk4mem_reset_secure(b2, sizeof(b2), NULL)) {
+ exval = EXIT_FAILURE;
+ }
+ /* SYSLOG ERROR: Failed to create child process */
+ syslog_1(22);
+ }
+ }
+ } else {
+ if (0 == dk4mem_reset_secure(b1, sizeof(b1), NULL)) {
+ exval = EXIT_FAILURE;
+ }
+ if (0 == dk4mem_reset_secure(b2, sizeof(b2), NULL)) {
+ exval = EXIT_FAILURE;
+ }
+ /* SYSLOG ERROR: Failed to detach */
+ syslog_1(21);
+ }
+ } else {
+ if ((pid_t)(-1) != cpid) { /* parent */
+ exval = EXIT_SUCCESS;
+ } else { /* error */
+ /* ERROR: Failed to create child process */
+ log_1(20);
+ }
+ }
+ }
+ }
+ if (0 == dk4mem_reset_secure(b1, sizeof(b1), NULL)) {
+ exval = EXIT_FAILURE;
+ }
+ if (0 == dk4mem_reset_secure(b2, sizeof(b2), NULL)) {
+ exval = EXIT_FAILURE;
+ }
+ $? "- run_as_daemon"
+}
+
+
+
+/** Show a text paragraph on standard output.
+ @param txt Text to show.
+*/
+static
+void
+show_text(const char * const *txt)
+{
+ if (NULL != txt) {
+ while (NULL != *txt) {
+ fputs(*(txt++), stdout);
+ fputc('\n', stdout);
+ }
+ fflush(stdout);
+ }
+}
+
+
+
+/** Handle --help, --version, --license options.
+*/
+static
+void
+run_hvl(void)
+{
+ if (0 != (1 & hvl)) {
+ show_text(help_text);
+ }
+ if (0 != (2 & hvl)) {
+ fputs(version_text, stdout);
+ fputc('\n', stdout);
+ fflush(stdout);
+ }
+ if (0 != (4 & hvl)) {
+ show_text(license_text);
+ }
+}
+
+
+
+/** Program entry point.
+ @param argc
+ @param argv
+ @return 0 on success, any other value indicates an error.
+*/
+int
+main(int argc, char *argv[])
+{
+ char *filenames[32];
+ size_t szfilenames = 32; /* Array size */
+ int res = 0; /* Operation result */
+
+ $? "+ main"
+
+ /* Process command line arguments.
+ */
+ res = dk4opt_process_argv(
+ options, szoptions, argc, argv, filenames, &szfilenames, 1, 1, NULL
+ );
+ if (0 == res) { $? "! option processing"
+ goto finished;
+ }
+
+ /* Check help, version, license.
+ */
+ if (0 != options[5].found) { hvl |= 1; }
+ if (0 != options[6].found) { hvl |= 2; }
+ if (0 != options[7].found) { hvl |= 4; }
+ if (0 != hvl) {
+ run_hvl();
+ goto finished;
+ }
+
+ /* Either send data or run as daemon to receive data.
+ */
+ if (0 != options[1].found) { $? ". run sender"
+ sender((const char * const *)filenames, szfilenames);
+ } else { $? ". run daemon"
+ run_as_daemon();
+ }
+
+ finished:
+ $? "- main %d", exval
+ exit(exval); return exval;
+}
+
+
+#else
+
+
+/** Program entry point.
+ @param argc
+ @param argv
+ @return 0 on success, any other value indicates an error.
+*/
+int
+main(int argc, char *argv[])
+{
+ fputs("rshdown: ERROR: Build requirements violation!\n", stderr);
+#if DK4_CHAR_SIZE > 1
+ fputs("Default character size is larger than 1!\n", stderr);
+#endif
+#if !((DK4_HAVE_SIGACTION) || (DK4_HAVE_SIGSET))
+ fputs("Neither sigaction() nor sigset() are available!\n", stderr);
+#endif
+#if !((DK4_HAVE_SETSID) || (DK4_HAVE_SETPGRP))
+ fputs("Neither setsid() nor setpgrp() are available!\n", stderr);
+#endif
+ fflush(stderr);
+ exit(EXIT_FAILURE); return EXIT_FAILURE;
+}
+
+#endif
+
+
diff --git a/support/dktools/run-conversion.xpm b/support/dktools/run-conversion.xpm
new file mode 100644
index 0000000000..c927c98161
--- /dev/null
+++ b/support/dktools/run-conversion.xpm
@@ -0,0 +1,39 @@
+/* XPM */
+static const char *xpm_run_conversion[] = {
+/* width height ncolors chars_per_pixel */
+"16 15 17 1",
+/* colors */
+" c #3AA73A",
+". c #34A534",
+"X c #FDFEFD",
+"o c #F8FCF8",
+"O c #0B930B",
+"+ c #008F00",
+"@ c #ADDAAD",
+"# c #99D299",
+"$ c #8CCC8C",
+"% c #5DB65D",
+"& c #31A431",
+"* c #239E23",
+"= c #FFFFFF",
+"- c #FEFFFE",
+"; c #E7F3E7",
+": c #D0E9D0",
+"> c None",
+/* pixels */
+">>>>>>>>>>>>>>>>",
+">>>>>>>>>>>>>>>>",
+">>&>>>>>>>>>>>>>",
+">>++ >>>>>>>>>>>",
+">>++++.>>>>>>>>>",
+">>++++++.>>>>>>>",
+">>++++++++.>>>>>",
+">>++++++++++&>>>",
+">>+++++++++O%>>>",
+">>+++++++*%>>>>>",
+">>+++++ >>>>>>>>",
+">>++O%>>>>>>>>>>",
+">>*>>>>>>>>>>>>>",
+">>>>>>>>>>>>>>>>",
+">>>>>>>>>>>>>>>>"
+};
diff --git a/support/dktools/run2.xpm b/support/dktools/run2.xpm
new file mode 100644
index 0000000000..e02561230d
--- /dev/null
+++ b/support/dktools/run2.xpm
@@ -0,0 +1,31 @@
+/* XPM */
+static const char *xpm_run2[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 8 1",
+/* colors */
+" c #FCFEFC",
+". c #008F00",
+"X c #98D298",
+"o c #31A431",
+"O c #2DA22D",
+"+ c #FFFFFF",
+"@ c #E7F3E7",
+"# c None",
+/* pixels */
+"################",
+"#O##############",
+"#..o############",
+"#....o##########",
+"#......o########",
+"#........o######",
+"#..........o####",
+"#............o##",
+"#............o##",
+"#..........o####",
+"#........o######",
+"#......o########",
+"#....o##########",
+"#..o############",
+"#O##############",
+"################"
+};
diff --git a/support/dktools/scripts/build-help.sh b/support/dktools/scripts/build-help.sh
new file mode 100755
index 0000000000..00a677fa90
--- /dev/null
+++ b/support/dktools/scripts/build-help.sh
@@ -0,0 +1,106 @@
+#! /bin/sh
+
+# Copyright (c) 2002-2016, Dirk Krause
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms,
+# with or without modification, are permitted provided
+# that the following conditions are met:
+#
+# * Redistributions of source code must retain the above
+# copyright notice, this list of conditions and the
+# following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# opyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials
+# provided with the distribution.
+# * Neither the name of the Dirk Krause nor the names of
+# contributors may be used to endorse or promote
+# products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED.
+# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+# DAMAGE.
+
+echo `date '+%Y-%m-%d %H:%M:%S'` Start scripts/build-help.sh
+
+if [ ! -d help-html ]
+then
+ mkdir -p help-html
+ chmod 755 help-html
+fi
+
+cd help-src
+
+for i in `find . -type d`
+do
+ if [ ! -d "../help-html/$i" ]
+ then
+ mkdir -p "../help-html/$i"
+ chmod 755 "../help-html/$i"
+ fi
+done
+
+for i in *
+do
+ cd "$i"
+ for j in en de
+ do
+ cd $j
+ echo Making icons in help-src/$i/$j
+ make icons
+ echo Retrieve favicon.ico in help-src/$i/$j
+ [ -f favicon.ico ] || ln ../../../dkicon.ico favicon.ico
+ echo Making chm in help-src/$i/$j
+ make chminstall
+ cd ..
+ done
+ cd ..
+done
+cd ..
+
+cd help-html
+for i in *
+do
+ cd "$i"
+ for j in en de
+ do
+ cd $j
+ echo BUILDING CHM AND HTB IN help-html/$i/$j
+ zip -r -9 ../$i.zip * -x $i.chm
+ chmod 644 ../$i.zip
+ if [ ! -d ../../../help-htb/$j ]
+ then
+ mkdir -p ../../../help-htb/$j
+ chmod 755 ../../../help-htb/$j
+ fi
+ mv ../$i.zip ../../../help-htb/$j/$i.htb
+ chmcmd --verbosity 5 --html-scan project.hhp
+ chmod 644 index.chm
+ if [ ! -d ../../../help-chm/$j ]
+ then
+ mkdir -p ../../../help-chm/$j
+ chmod 755 ../../../help-chm/$j
+ fi
+ mv index.chm ../../../help-chm/$j/$i.chm
+ cd ..
+ done
+ cd ..
+done
+cd ..
+
+echo `date '+%Y-%m-%d %H:%M:%S'` Finished scripts/build-help.sh
+
diff --git a/support/dktools/scripts/build-help.sh.in b/support/dktools/scripts/build-help.sh.in
new file mode 100644
index 0000000000..143b58ee68
--- /dev/null
+++ b/support/dktools/scripts/build-help.sh.in
@@ -0,0 +1,106 @@
+#! /bin/sh
+
+# Copyright (c) 2002-2016, Dirk Krause
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms,
+# with or without modification, are permitted provided
+# that the following conditions are met:
+#
+# * Redistributions of source code must retain the above
+# copyright notice, this list of conditions and the
+# following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# opyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials
+# provided with the distribution.
+# * Neither the name of the Dirk Krause nor the names of
+# contributors may be used to endorse or promote
+# products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED.
+# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+# DAMAGE.
+
+echo `date '+%Y-%m-%d %H:%M:%S'` Start scripts/build-help.sh
+
+if [ ! -d help-html ]
+then
+ mkdir -p help-html
+ chmod 755 help-html
+fi
+
+cd help-src
+
+for i in `find . -type d`
+do
+ if [ ! -d "../help-html/$i" ]
+ then
+ mkdir -p "../help-html/$i"
+ chmod 755 "../help-html/$i"
+ fi
+done
+
+for i in *
+do
+ cd "$i"
+ for j in en de
+ do
+ cd $j
+ echo Making icons in help-src/$i/$j
+ @MAKE@ icons
+ echo Retrieve favicon.ico in help-src/$i/$j
+ [ -f favicon.ico ] || ln ../../../dkicon.ico favicon.ico
+ echo Making chm in help-src/$i/$j
+ @MAKE@ chminstall
+ cd ..
+ done
+ cd ..
+done
+cd ..
+
+cd help-html
+for i in *
+do
+ cd "$i"
+ for j in en de
+ do
+ cd $j
+ echo BUILDING CHM AND HTB IN help-html/$i/$j
+ zip -r -9 ../$i.zip * -x $i.chm
+ chmod 644 ../$i.zip
+ if [ ! -d ../../../help-htb/$j ]
+ then
+ mkdir -p ../../../help-htb/$j
+ chmod 755 ../../../help-htb/$j
+ fi
+ mv ../$i.zip ../../../help-htb/$j/$i.htb
+ chmcmd --verbosity 5 --html-scan project.hhp
+ chmod 644 index.chm
+ if [ ! -d ../../../help-chm/$j ]
+ then
+ mkdir -p ../../../help-chm/$j
+ chmod 755 ../../../help-chm/$j
+ fi
+ mv index.chm ../../../help-chm/$j/$i.chm
+ cd ..
+ done
+ cd ..
+done
+cd ..
+
+echo `date '+%Y-%m-%d %H:%M:%S'` Finished scripts/build-help.sh
+
diff --git a/support/dktools/scripts/check_config_have.pl b/support/dktools/scripts/check_config_have.pl
new file mode 100755
index 0000000000..53560b44a1
--- /dev/null
+++ b/support/dktools/scripts/check_config_have.pl
@@ -0,0 +1,98 @@
+#! /usr/bin/perl
+
+# Copyright (c) 2002-2016, Dirk Krause
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms,
+# with or without modification, are permitted provided
+# that the following conditions are met:
+#
+# * Redistributions of source code must retain the above
+# copyright notice, this list of conditions and the
+# following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# opyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials
+# provided with the distribution.
+# * Neither the name of the Dirk Krause nor the names of
+# contributors may be used to endorse or promote
+# products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED.
+# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+# DAMAGE.
+
+
+my %used;
+my %found;
+
+sub
+read_one_source_file($)
+{
+ my $fn = shift;
+ my $fh = undef;
+ my $line;
+ my $n1;
+ my $n2;
+ if (open($fh, "<$fn")) {
+ while(<$fh>) {
+ $line = $_; chomp $line;
+ $cc = 1;
+ while($cc) {
+ $cc = 0;
+ if ($line =~ /.*(DK4_HAVE_[a-zA-Z_01-9]+)(.*)/o) {
+ $n1 = $1;
+ $n2 = $2;
+ $used{"$n1"} = 1;
+ $line = $n2;
+ }
+ }
+ }
+ close($fh);
+ }
+}
+
+my $fn;
+
+foreach $fn (<dk4*.ctr>) {
+ read_one_source_file($fn);
+}
+foreach $fn (<Dk4*.cpt>) {
+ read_one_source_file($fn);
+}
+foreach $fn (<Dk4*.wxc>) {
+ read_one_source_file($fn);
+}
+
+my $fh = undef;
+my $line;
+my $n;
+if (open($fh, "<dk4conf.h")) {
+ while(<$fh>) {
+ $line = $_; chomp $line;
+ if ($line =~ /(DK4_HAVE_[a-zA-Z_01-9]+)/o) {
+ $n = $1;
+ $found{"$n"} = 1;
+ }
+ }
+ close($fh);
+ foreach $n (sort keys %used) {
+ if (!exists($found{"$n"})) {
+ print "Missing $n\n";
+ }
+ }
+}
+
diff --git a/support/dktools/scripts/clean-for-fig.sh b/support/dktools/scripts/clean-for-fig.sh
new file mode 100755
index 0000000000..0d634cd65e
--- /dev/null
+++ b/support/dktools/scripts/clean-for-fig.sh
@@ -0,0 +1,57 @@
+#! /bin/sh
+
+# Copyright (c) 2002-2016, Dirk Krause
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms,
+# with or without modification, are permitted provided
+# that the following conditions are met:
+#
+# * Redistributions of source code must retain the above
+# copyright notice, this list of conditions and the
+# following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# opyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials
+# provided with the distribution.
+# * Neither the name of the Dirk Krause nor the names of
+# contributors may be used to endorse or promote
+# products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED.
+# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+# DAMAGE.
+
+
+echo `date '+%Y-%m-%d %H:%M:%S'` Start scripts/clean-for-fig.sh
+
+DIRECTORIES="doc/src resources"
+
+for l in $DIRECTORIES
+do
+ for i in `find $l -name '*.fig'`
+ do
+ j=`echo $i | sed -e 's/\.fig$//g'`
+ for k in png pdf tex svg log
+ do
+ [ ! -f $j.$k ] || rm -f $j.$k
+ done
+ [ ! -f $j-i.pdf ] || rm -f $j-i.pdf
+ done
+done
+
+echo `date '+%Y-%m-%d %H:%M:%S'` Finished scripts/clean-for-fig.sh
+
diff --git a/support/dktools/scripts/clean-for-tex.sh b/support/dktools/scripts/clean-for-tex.sh
new file mode 100755
index 0000000000..be559804da
--- /dev/null
+++ b/support/dktools/scripts/clean-for-tex.sh
@@ -0,0 +1,50 @@
+#! /bin/sh
+
+# Copyright (c) 2002-2016, Dirk Krause
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms,
+# with or without modification, are permitted provided
+# that the following conditions are met:
+#
+# * Redistributions of source code must retain the above
+# copyright notice, this list of conditions and the
+# following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# opyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials
+# provided with the distribution.
+# * Neither the name of the Dirk Krause nor the names of
+# contributors may be used to endorse or promote
+# products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED.
+# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+# DAMAGE.
+
+echo `date '+%Y-%m-%d %H:%M:%S'` Start scripts/clean-for-tex.sh
+
+for i in `find doc/src -name 'math-*.tex'`
+do
+ j=`echo $i | sed -e 's/\.tex$//g'`
+ for k in png pdf svg aux log
+ do
+ [ ! -f $j.$k ] || rm -f $j.$k
+ done
+done
+
+echo `date '+%Y-%m-%d %H:%M:%S'` Finished scripts/clean-for-tex.sh
+
diff --git a/support/dktools/scripts/clean-help-doc.sh b/support/dktools/scripts/clean-help-doc.sh
new file mode 100755
index 0000000000..bd25b7c875
--- /dev/null
+++ b/support/dktools/scripts/clean-help-doc.sh
@@ -0,0 +1,53 @@
+#! /bin/sh
+
+# Copyright (c) 2002-2016, Dirk Krause
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms,
+# with or without modification, are permitted provided
+# that the following conditions are met:
+#
+# * Redistributions of source code must retain the above
+# copyright notice, this list of conditions and the
+# following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# opyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials
+# provided with the distribution.
+# * Neither the name of the Dirk Krause nor the names of
+# contributors may be used to endorse or promote
+# products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED.
+# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+# DAMAGE.
+
+echo `date '+%Y-%m-%d %H:%M:%S'` Start scripts/clean-help-doc.sh
+
+for i in doc/src help-src
+do
+ for j in index toc prev previous next
+ do
+ for k in pdf svg
+ do
+ find $i -name "$j.$k" -exec rm {} \;
+ done
+ done
+done
+
+
+echo `date '+%Y-%m-%d %H:%M:%S'` Finished scripts/clean-help-doc.sh
+
diff --git a/support/dktools/scripts/clean-resources.sh b/support/dktools/scripts/clean-resources.sh
new file mode 100755
index 0000000000..66d5c60d66
--- /dev/null
+++ b/support/dktools/scripts/clean-resources.sh
@@ -0,0 +1,44 @@
+#! /bin/sh
+
+# Copyright (c) 2002-2016, Dirk Krause
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms,
+# with or without modification, are permitted provided
+# that the following conditions are met:
+#
+# * Redistributions of source code must retain the above
+# copyright notice, this list of conditions and the
+# following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# opyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials
+# provided with the distribution.
+# * Neither the name of the Dirk Krause nor the names of
+# contributors may be used to endorse or promote
+# products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED.
+# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+# DAMAGE.
+
+echo `date '+%Y-%m-%d %H:%M:%S'` Start scripts/clean-resources.sh
+
+cd resources
+make clean
+
+echo `date '+%Y-%m-%d %H:%M:%S'` Finished scripts/clean-resources.sh
+
diff --git a/support/dktools/scripts/clean.sh b/support/dktools/scripts/clean.sh
new file mode 100755
index 0000000000..cf01bddc91
--- /dev/null
+++ b/support/dktools/scripts/clean.sh
@@ -0,0 +1,88 @@
+#! /bin/sh
+
+# Copyright (c) 2002-2016, Dirk Krause
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms,
+# with or without modification, are permitted provided
+# that the following conditions are met:
+#
+# * Redistributions of source code must retain the above
+# copyright notice, this list of conditions and the
+# following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# opyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials
+# provided with the distribution.
+# * Neither the name of the Dirk Krause nor the names of
+# contributors may be used to endorse or promote
+# products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED.
+# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+# DAMAGE.
+
+#
+# DO NOT RUN THIS SCRIPT MANUALLY!
+# This script is run from the Makefile in the parent directory on
+# make clean
+# after removing other files.
+#
+
+echo `date '+%Y-%m-%d %H:%M:%S'` Start scripts/clean.sh
+
+DIR=`dirname $0`
+echo $DIR
+
+
+for i in *.ctr
+do
+ j=`echo $i | sed -e 's/\.ctr//g'`
+ [ ! -f $j.c ] || rm -f $j.c
+ egrep '%%.*header' $i > /dev/null
+ EC=$?
+ if [ "X$EC" = "X0" ]
+ then
+ rm $j.h
+ fi
+done
+
+for i in *.cpt
+do
+ j=`echo $i | sed -e 's/\.cpt//g'`
+ [ ! -f $j.cpp ] || rm -f $j.cpp
+ egrep '%%.*header' $i > /dev/null
+ EC=$?
+ if [ "X$EC" = "X0" ]
+ then
+ rm $j.h
+ fi
+done
+
+for i in *.wxc
+do
+ j=`echo $i | sed -e 's/\.wxc//g'`
+ [ ! -f $j.cpp ] || rm -f $j.cpp
+ egrep '%%.*header' $i > /dev/null
+ EC=$?
+ if [ "X$EC" = "X0" ]
+ then
+ rm $j.h
+ fi
+done
+
+echo `date '+%Y-%m-%d %H:%M:%S'` Finished scripts/clean.sh
+
diff --git a/support/dktools/scripts/create-debian-changelog.pl b/support/dktools/scripts/create-debian-changelog.pl
new file mode 100755
index 0000000000..55b5a7adcd
--- /dev/null
+++ b/support/dktools/scripts/create-debian-changelog.pl
@@ -0,0 +1,137 @@
+#! /usr/bin/perl
+
+# Copyright (c) 2002-2016, Dirk Krause
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms,
+# with or without modification, are permitted provided
+# that the following conditions are met:
+#
+# * Redistributions of source code must retain the above
+# copyright notice, this list of conditions and the
+# following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# opyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials
+# provided with the distribution.
+# * Neither the name of the Dirk Krause nor the names of
+# contributors may be used to endorse or promote
+# products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED.
+# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+# DAMAGE.
+
+my @lines;
+my $numlines = 0;
+my $isfirst = 1;
+my $inchangelog = 0;
+my $ifh = undef;
+my $ofh = undef;
+my $newwday = "";
+my $newmon = "";
+my $newmday = "";
+my $newyear = "";
+my $newname = "";
+my $newmail = "";
+my $newmajor = "";
+my $newminor = "";
+my $newmicro = "";
+my $wday = "";
+my $mon = "";
+my $mday = "";
+my $year = "";
+my $name = "";
+my $mail = "";
+my $major = "";
+my $minor = "";
+my $micro = "";
+
+my $line;
+
+
+sub shipout()
+{
+ my $i;
+ if (0 < $numlines) {
+ if (0 != $isfirst) {
+ $isfirst = 0;
+ print "# DO NOT EDIT THIS FILE!\n";
+ print "# It is generated automatically from the dktools-el6.spec.in\n";
+ print "# file.";
+ }
+ print "\ndktools ($major.$minor.$micro-1) unstable; urgency=low\n\n";
+ for ($i = 0; $i < $numlines; $i++) {
+ $line = $lines[$i];
+ print "$line\n";
+ }
+ print "\n -- $name <$mail> $wday, $mday $mon $year 20:00:00 +0200\n\n";
+ }
+}
+
+
+if (open($ifh, "<dktools-el6.spec.in")) {
+ while(<$ifh>) {
+ $line = $_; chomp $line;
+ if ($line =~ /^\s*\%/o) {
+ if ($line =~ /^\s*\%changelog/o) {
+ $inchangelog = 1;
+ } else {
+ $inchangelog = 0;
+ }
+ } else {
+ if (0 != $inchangelog) {
+ if ($line =~ /^\s*$/o) {
+ shipout();
+ $numlines = 0;
+ } else {
+ if ($line =~ /^\*\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+([^<>]+)\s+<([^<>]+)>\s+(\d+)\.(\d+)\.(\d+)/o) {
+ $newwday = $1;
+ $newmon = $2;
+ $newmday = $3;
+ $newyear = $4;
+ $newname = $5;
+ $newmail = $6;
+ $newmajor = $7;
+ $newminor = $8;
+ $newmicro = $9;
+ shipout();
+ $numlines = 0;
+ $wday = $newwday;
+ $mon = $newmon;
+ $mday = $newmday;
+ $year = $newyear;
+ $name = $newname;
+ $mail = $newmail;
+ $major = $newmajor;
+ $minor = $newminor;
+ $micro = $newmicro;
+ } else {
+ if ($line =~ /^\s*\-\s*(.*)/o) {
+ $line = "* $1";
+ }
+ $line = " $line";
+ $lines[$numlines++] = $line;
+ }
+ }
+ }
+ }
+ }
+ shipout();
+ close($ifh);
+}
+
+
diff --git a/support/dktools/scripts/create-desktop-files.sh.in b/support/dktools/scripts/create-desktop-files.sh.in
new file mode 100644
index 0000000000..1b7bbe4ed9
--- /dev/null
+++ b/support/dktools/scripts/create-desktop-files.sh.in
@@ -0,0 +1,133 @@
+#! /bin/sh
+
+# Copyright (c) 2002-2016, Dirk Krause
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms,
+# with or without modification, are permitted provided
+# that the following conditions are met:
+#
+# * Redistributions of source code must retain the above
+# copyright notice, this list of conditions and the
+# following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# opyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials
+# provided with the distribution.
+# * Neither the name of the Dirk Krause nor the names of
+# contributors may be used to endorse or promote
+# products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED.
+# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+# DAMAGE.
+
+echo `date '+%Y-%m-%d %H:%M:%S'` Start scripts/create-desktop-files.sh
+
+# Standard directory variables from autoconf
+prefix=@prefix@
+datarootdir=@datarootdir@
+exec_prefix=@exec_prefix@
+bindir=@bindir@
+sbindir=@sbindir@
+libexecdir=@libexecdir@
+datadir=${datarootdir}
+sysconfdir=@sysconfdir@
+scd=${sysconfdir}
+libdir=@libdir@
+sharedlibdir=${libdir}/shared
+mandir=@mandir@
+includedir=@includedir@
+localstatedir=@localstatedir@
+srcdir=@srcdir@
+top_srcdir=@top_srcdir@
+VPATH=@srcdir@
+
+cat > wxbmpp.desktop <<EOF
+
+[Desktop Entry]
+Encoding=UTF-8
+Categories=Application;Graphics;
+Name=wxbmpp
+Comment=Converter from PNG/JPEG/TIFF to PDF/EPS
+Comment[de]=Konvertierung von PNG/JPEG/TIFF zu PDF/EPS
+Exec=@bindir@/wxbmpp %f
+Terminal=0
+Type=Application
+Icon=@datarootdir@/dktools/dkicon.ico
+
+EOF
+
+cat > wxdkclock.desktop <<EOF
+
+[Desktop Entry]
+Encoding=UTF-8
+Categories=Application;Clock;
+Name=DK clock
+Name[de]=Uhr
+Comment=Simple clock with one alert
+Comment[de]=Einfache Uhr mit einem Alarm
+Exec=@bindir@/wxdkclock
+Terminal=0
+Type=Application
+Icon=@datarootdir@/dktools/dkclock.ico
+EOF
+
+cat > wxdkct.desktop <<EOF
+
+[Desktop Entry]
+Encoding=UTF-8
+Categories=Application;Development;
+Name=wxdkct
+Comment=C, C++, Objective-C and Java Tool
+Comment[de]=Tool für C, C++, Objective-C und Java
+Exec=@bindir@/wxdkct
+Terminal=0
+Type=Application
+Icon=@datarootdir@/dktools/dkicon.ico
+EOF
+
+cat > wximgsz.desktop <<EOF
+
+[Desktop Entry]
+Encoding=UTF-8
+Categories=Application;Graphics;
+Name=wximgsz
+Comment=Suggest size pairs to rescale bitmap images
+Comment[de]=Größenvorschläge für Skalierung von Bitmap-Bildern
+Exec=@bindir@/wximgsz
+Terminal=0
+Type=Application
+Icon=@datarootdir@/dktools/dkicon.ico
+EOF
+
+cat > wxdkfcs.desktop <<EOF
+
+[Desktop Entry]
+Encoding=UTF-8
+Categories=System;Utility;FileTools;
+Name=wxdkfcs
+Comment=Create file checksums
+Comment[de]=Prüfsummen für Dateien
+Exec=@bindir@/wxdkfcs
+Terminal=0
+Type=Application
+Icon=@datarootdir@/dktools/dkicon.ico
+EOF
+
+
+echo `date '+%Y-%m-%d %H:%M:%S'` Finished scripts/create-desktop-files.sh
+
diff --git a/support/dktools/scripts/create-distribution.sh b/support/dktools/scripts/create-distribution.sh
new file mode 100755
index 0000000000..f47b8e9735
--- /dev/null
+++ b/support/dktools/scripts/create-distribution.sh
@@ -0,0 +1,229 @@
+#! /bin/sh
+
+# Copyright (c) 2002-2016, Dirk Krause
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms,
+# with or without modification, are permitted provided
+# that the following conditions are met:
+#
+# * Redistributions of source code must retain the above
+# copyright notice, this list of conditions and the
+# following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# opyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials
+# provided with the distribution.
+# * Neither the name of the Dirk Krause nor the names of
+# contributors may be used to endorse or promote
+# products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED.
+# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+# DAMAGE.
+
+echo `date '+%Y-%m-%d %H:%M:%S'` Start scripts/create-distribution.sh
+
+umask 0
+
+D1=`date`
+echo $D1
+
+VERSION=`cat version.txt`
+
+SRCDIR=/home/krause/work/dklib-4
+
+DOWNLOADS=/home/krause/Downloads
+
+# Ensure the Downloads directory is available
+[ -d $DOWNLOADS ] || mkdir -p $DOWNLOADS
+
+# Remove artifacts
+A="dktools-${VERSION} dktools-doc-${VERSION} dktools-devdoc-${VERSION}"
+A="$A dktools-full-${VERSION} dktools-sf-doc-${VERSION}"
+for i in $A
+do
+ echo Removing old files for $i
+ if [ -d ${DOWNLOADS}/$i ]
+ then
+ echo "rm -fr ${DOWNLOADS}/$i"
+ rm -fr ${DOWNLOADS}/$i
+ fi
+ if [ -f ${DOWNLOADS}/${i}.tar ]
+ then
+ echo "rm -f ${DOWNLOADS}/${i}.tar"
+ rm -f ${DOWNLOADS}/${i}.tar
+ fi
+ if [ -f ${DOWNLOADS}/${i}.tar.gz ]
+ then
+ echo "rm -f ${DOWNLOADS}/${i}.tar.gz"
+ rm -f ${DOWNLOADS}/${i}.tar.gz
+ fi
+ if [ -f /home/krause/SW-DEV/archives/${i}.tar.gz ]
+ then
+ echo "rm -f /home/krause/SW-DEV/archives/${i}.tar.gz"
+ rm -f /home/krause/SW-DEV/archives/${i}.tar.gz
+ fi
+ # if [ -f /home/krause/rpmbuild/SOURCES/${i}.tar.gz ]
+ # then
+ # echo "rm -f /home/krause/rpmbuild/SOURCES/${i}.tar.gz"
+ # rm -f /home/krause/rpmbuild/SOURCES/${i}.tar.gz
+ # fi
+done
+
+# Update version number in debian/changelog
+# sed -e "s/@VERSION@/$VERSION/" < debian/changelog.in > debian/changelog
+echo 'Changing @VERSION@ to' "$VERSION" in doc/debian/changelog and devdoc/debian/changelog
+
+sed -e "s/@VERSION@/$VERSION/" < doc/debian/changelog.in > doc/debian/changelog
+sed -e "s/@VERSION@/$VERSION/" < devdoc/debian/changelog.in > devdoc/debian/changelog
+
+# dktools-${VERSION}
+mkdir -p ${DOWNLOADS}/dktools-${VERSION}
+cd ${DOWNLOADS}/dktools-${VERSION}
+echo Copying files to ${DOWNLOADS}/dktools-${VERSION}
+(cd ${SRCDIR} ; tar cf - * --exclude .git --exclude doc/doxygen --exclude dk4wx-v1) | tar xf -
+rm -fr ${DOWNLOADS}/dktools-${VERSION}/doc
+rm -fr ${DOWNLOADS}/dktools-${VERSION}/devdoc
+rm -fr ${DOWNLOADS}/dktools-${VERSION}/debian/*.ex
+rm -fr ${DOWNLOADS}/dktools-${VERSION}/debian/*.EX
+[ ! -f configure.out ] || rm -f configure.out
+tar cf help-src.tar help-src
+gzip -9 help-src.tar
+rm -fr "${DOWNLOADS}/dktools-${VERSION}/help-src"
+tar cf help-html.tar help-html
+gzip -9 help-html.tar
+rm -fr "${DOWNLOADS}/dktools-${VERSION}/help-html"
+tar cf man-src.tar man-src
+gzip -9 man-src.tar
+rm -fr "${DOWNLOADS}/dktools-${VERSION}/man-src"
+
+find . -type d -exec chmod 755 {} \;
+find . -type f -exec chmod ugo+r {} \;
+find . -name '*.sh' -exec chmod ugo+x {} \;
+find . -name '*.pl' -exec chmod ugo+x {} \;
+
+# dktools-doc-${VERSION}
+mkdir -p ${DOWNLOADS}/dktools-doc-${VERSION}
+cd ${DOWNLOADS}/dktools-doc-${VERSION}
+echo Copying files to ${DOWNLOADS}/dktools-doc-${VERSION}
+(cd ${SRCDIR}/doc ; tar cf - *) | tar xf -
+cp ${SRCDIR}/version.txt .
+rm -fr ${DOWNLOADS}/dktools-doc-${VERSION}/doxygen
+rm -fr ${DOWNLOADS}/dktools-doc-${VERSION}/html/devdoc
+# rm -fr ${DOWNLOADS}/dktools-doc-${VERSION}/src
+find . -type d -exec chmod 755 {} \;
+find . -type f -exec chmod ugo+r {} \;
+find . -name '*.sh' -exec chmod ugo+x {} \;
+find . -name '*.pl' -exec chmod ugo+x {} \;
+
+# dktools-devdoc-${VERSION}
+mkdir -p ${DOWNLOADS}/dktools-devdoc-${VERSION}
+cd ${DOWNLOADS}/dktools-devdoc-${VERSION}
+echo Copying files to ${DOWNLOADS}/dktools-devdoc-${VERSION}
+(cd ${SRCDIR}/devdoc ; tar cf - *) | tar xf -
+(cd ${SRCDIR}/doc/doxygen; tar cf - html) | tar xf -
+cp ${SRCDIR}/version.txt .
+find . -type d -exec chmod 755 {} \;
+find . -type f -exec chmod ugo+r {} \;
+find . -name '*.sh' -exec chmod ugo+x {} \;
+find . -name '*.pl' -exec chmod ugo+x {} \;
+
+# dktools-full-${VERSION}
+mkdir -p ${DOWNLOADS}/dktools-full-${VERSION}
+cd ${DOWNLOADS}/dktools-full-${VERSION}
+echo Copying files to ${DOWNLOADS}/dktools-full-${VERSION}
+(cd ${SRCDIR} ; tar cf - * --exclude .git) | tar xf -
+find . -type d -exec chmod 755 {} \;
+find . -type f -exec chmod ugo+r {} \;
+find . -name '*.sh' -exec chmod ugo+x {} \;
+find . -name '*.pl' -exec chmod ugo+x {} \;
+
+# dktools-sf-doc-${VERSION}
+mkdir -p ${DOWNLOADS}/dktools-sf-doc-${VERSION}
+cd ${SRCDIR}/doc/src
+touch index.prj
+make webinstall
+cd ${DOWNLOADS}/dktools-sf-doc-${VERSION}
+echo Copying files to ${DOWNLOADS}/dktools-sf-doc-${VERSION}
+(cd ${SRCDIR}/doc ; tar cf - *) | tar xf -
+cp ${SRCDIR}/version.txt .
+[ -d html ] || mkdir -p html
+mkdir html/devdoc
+cd html/devdoc
+(cd ${SRCDIR}/doc/doxygen/html ; tar cf - *) | tar xf -
+cd ../..
+find . -type d -exec chmod 755 {} \;
+find . -type f -exec chmod ugo+r {} \;
+find . -name '*.sh' -exec chmod ugo+x {} \;
+find . -name '*.pl' -exec chmod ugo+x {} \;
+find . -type f -exec chmod go-w {} \;
+rm -fr ${DOWNLOADS}/dktools-doc-${VERSION}/doxygen
+# rm -fr ${DOWNLOADS}/dktools-doc-${VERSION}/src
+cd ${SRCDIR}/doc/src
+touch index.prj
+make install
+cd ..
+find . -type d -exec chmod 755 {} \;
+find . -type f -exec chmod ugo+r {} \;
+find . -name '*.sh' -exec chmod ugo+x {} \;
+find . -name '*.pl' -exec chmod ugo+x {} \;
+
+# Copy files
+echo "cd ${DOWNLOADS}"
+cd ${DOWNLOADS}
+
+for i in $A
+do
+ echo "tar cf ${i}.tar ${i}"
+ tar cf ${i}.tar ${i}
+ echo "gzip -9 ${i}.tar"
+ gzip -9 ${i}.tar
+ echo "cp ${i}.tar.gz ~/SW-DEV/archives"
+ cp ${i}.tar.gz ~/SW-DEV/archives
+ # echo "cp ${i}.tar.gz ~/rpmbuild/SOURCES"
+ # cp ${i}.tar.gz ~/rpmbuild/SOURCES
+done
+
+# echo "cp dktools-${VERSION}/*.spec ~/rpmbuild/SPECS"
+# cp dktools-${VERSION}/*.spec ~/rpmbuild/SPECS
+# echo "cp dktools-doc-${VERSION}/*.spec ~/rpmbuild/SPECS"
+# cp dktools-doc-${VERSION}/*.spec ~/rpmbuild/SPECS
+# echo "cp dktools-devdoc-${VERSION}/*.spec ~/rpmbuild/SPECS"
+# cp dktools-devdoc-${VERSION}/*.spec ~/rpmbuild/SPECS
+
+# Clean up
+for i in $A
+do
+ if [ -d ${DOWNLOADS}/$i ]
+ then
+ echo "rm -fr ${DOWNLOADS}/$i"
+ rm -fr ${DOWNLOADS}/$i
+ fi
+ if [ -f ${DOWNLOADS}/${i}.tar ]
+ then
+ echo "rm -f ${DOWNLOADS}/${i}.tar"
+ rm -f ${DOWNLOADS}/${i}.tar
+ fi
+ if [ -f ${DOWNLOADS}/${i}.tar.gz ]
+ then
+ echo "rm -f ${DOWNLOADS}/${i}.tar.gz"
+ rm -f ${DOWNLOADS}/${i}.tar.gz
+ fi
+done
+
+echo `date '+%Y-%m-%d %H:%M:%S'` Finished scripts/create-distribution.sh
+
diff --git a/support/dktools/scripts/create-iss.sed b/support/dktools/scripts/create-iss.sed
new file mode 100644
index 0000000000..7536783756
--- /dev/null
+++ b/support/dktools/scripts/create-iss.sed
@@ -0,0 +1,6 @@
+/^AppId=/s/E8178AB5-99E3-4C64-A242-289A0601F67B/9746B24E-DEA3-4597-9E07-F27A15070592/g
+s/64 bits/32 bits/g
+/^ArchitecturesInstallIn64BitMode/d
+s/win64/win32/g
+s/[Kk]rause64/krause32/g
+
diff --git a/support/dktools/scripts/create-spec-iss.sh b/support/dktools/scripts/create-spec-iss.sh
new file mode 100755
index 0000000000..367c581796
--- /dev/null
+++ b/support/dktools/scripts/create-spec-iss.sh
@@ -0,0 +1,78 @@
+#! /bin/sh
+
+# Copyright (c) 2002-2016, Dirk Krause
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms,
+# with or without modification, are permitted provided
+# that the following conditions are met:
+#
+# * Redistributions of source code must retain the above
+# copyright notice, this list of conditions and the
+# following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# opyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials
+# provided with the distribution.
+# * Neither the name of the Dirk Krause nor the names of
+# contributors may be used to endorse or promote
+# products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED.
+# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+# DAMAGE.
+
+echo `date '+%Y-%m-%d %H:%M:%S'` Start scripts/create-spec-iss.sh
+
+VERSION=`cat version.txt`
+SOVERS=`echo $VERSION | cut -f 1,2 -d .`
+
+IN=dktools-el6.spec.in
+OUT=dktools-el6.spec
+sed -e "s/VERSNO/$VERSION/g" < $IN | sed -e "s/SOVERS/$SOVERS/g" > $OUT
+
+IN=doc/dktools-doc.spec.in
+OUT=doc/dktools-doc.spec
+sed -e "s/VERSNO/$VERSION/g" < $IN > $OUT
+
+IN=devdoc/dktools-devdoc.spec.in
+OUT=devdoc/dktools-devdoc.spec
+sed -e "s/VERSNO/$VERSION/g" < $IN > $OUT
+
+IN=dktools-el6.spec
+OUT=dktools-fedora.spec
+sed -e "s/mysql-devel/community-mysql-devel/g" < $IN > $OUT
+
+IN=dktools-el6.spec
+OUT=dktools-el7.spec
+
+sed -e '/___PROVIDES___/,$d' < $IN > $OUT
+for i in `grep '^libdk[a-zA-Z01-9]*\.so' Makefile | cut -f 1 -d : | sort -u`
+do
+echo "Provides: ${i}.${SOVERS}()(64bit)" >> $OUT
+done
+sed -e "1,/___PROVIDES___/d" < $IN >> $OUT
+
+IN=win32/user64.iss.in
+OUT=win32/user64.iss
+sed -e "s/VERSNO/$VERSION/g" < $IN > $OUT
+
+IN=win32/user64.iss
+OUT=win32/user32.iss
+sed -f scripts/create-iss.sed < $IN > $OUT
+
+echo `date '+%Y-%m-%d %H:%M:%S'` Finished scripts/create-spec-iss.sh
+
diff --git a/support/dktools/scripts/distrenew.sh b/support/dktools/scripts/distrenew.sh
new file mode 100755
index 0000000000..45383f3e5e
--- /dev/null
+++ b/support/dktools/scripts/distrenew.sh
@@ -0,0 +1,69 @@
+#! /bin/sh
+
+# Copyright (c) 2002-2016, Dirk Krause
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms,
+# with or without modification, are permitted provided
+# that the following conditions are met:
+#
+# * Redistributions of source code must retain the above
+# copyright notice, this list of conditions and the
+# following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# opyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials
+# provided with the distribution.
+# * Neither the name of the Dirk Krause nor the names of
+# contributors may be used to endorse or promote
+# products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED.
+# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+# DAMAGE.
+
+echo `date '+%Y-%m-%d %H:%M:%S'` Start scripts/distrenew.sh
+
+[ ! -x scripts/filechk.pl ] || perl scripts/filechk.pl
+(cd icons ; make install)
+[ ! -f doc/version.txt ] || rm -f doc/version.txt
+[ -f doc/version.txt ] || ln version.txt doc/version.txt
+[ -f devdoc/version.txt ] || ln version.txt devdoc/version.txt
+scripts/update-tex-version.sh
+scripts/update-doxyfile.sh
+scripts/build-help.sh
+scripts/create-spec-iss.sh
+perl scripts/mkrc.pl
+[ -d devdoc ] || (mkdir devdoc ; chmod 755 devdoc)
+[ -d devdoc/html ] || (mkdir devdoc/html ; chmod 755 devdoc/html)
+(cd doc/tex ; make)
+(cd doc/src ; make install)
+(cd doc/src ; make webinstall)
+scripts/clean-help-doc.sh
+perl ./scripts/transform-config.pl
+perl ./scripts/create-wschksz.pl
+autoconf
+(cd doc ; autoconf)
+(cd devdoc ; autoconf)
+dkct -l
+cat dk3sockx.txt dk3sock.c > dk3sockx.c
+rm -fr DELSTR DELTXT
+./configure
+cp dk3conf.h win32
+doxygen
+
+echo `date '+%Y-%m-%d %H:%M:%S'` Finished scripts/distrenew.sh
+
diff --git a/support/dktools/scripts/dkmkproto.pl b/support/dktools/scripts/dkmkproto.pl
new file mode 100755
index 0000000000..e71050999c
--- /dev/null
+++ b/support/dktools/scripts/dkmkproto.pl
@@ -0,0 +1,248 @@
+#! /usr/bin/perl
+
+# Copyright (C) 2010-2016 by Dirk Krause
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms,
+# with or without modification, are permitted provided
+# that the following conditions are met:
+#
+# * Redistributions of source code must retain the above
+# copyright notice, this list of conditions and the
+# following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# opyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials
+# provided with the distribution.
+# * Neither the name of the Dirk Krause nor the names of
+# contributors may be used to endorse or promote
+# products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED.
+# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+# DAMAGE.
+
+#
+# Hash table containing dirname=1 for directory
+# names to ignore (to avoid conflicts).
+#
+
+my %dirs_to_ignore;
+
+$dirs_to_ignore{"/usr"} = 1;
+$dirs_to_ignore{"/usr/share"} = 1;
+$dirs_to_ignore{"/usr/share/man"} = 1;
+$dirs_to_ignore{"/usr/share/man/man1"} = 1;
+$dirs_to_ignore{"/usr/share/man/man2"} = 1;
+$dirs_to_ignore{"/usr/share/man/man3"} = 1;
+$dirs_to_ignore{"/usr/share/man/man4"} = 1;
+$dirs_to_ignore{"/usr/share/man/man5"} = 1;
+$dirs_to_ignore{"/usr/share/man/man6"} = 1;
+$dirs_to_ignore{"/usr/share/man/man7"} = 1;
+$dirs_to_ignore{"/usr/share/applications"} = 1;
+$dirs_to_ignore{"/usr/include"} = 1;
+$dirs_to_ignore{"/usr/bin"} = 1;
+$dirs_to_ignore{"/usr/sbin"} = 1;
+$dirs_to_ignore{"/usr/lib"} = 1;
+$dirs_to_ignore{"/usr/lib/pkgconfig"} = 1;
+$dirs_to_ignore{"/usr/libexec"} = 1;
+$dirs_to_ignore{"/usr/libexec/filters"} = 1;
+$dirs_to_ignore{"/etc"} = 1;
+$dirs_to_ignore{"/var"} = 1;
+$dirs_to_ignore{"/var/run"} = 1;
+$dirs_to_ignore{"/var/spool"} = 1;
+$dirs_to_ignore{"/var/log"} = 1;
+$dirs_to_ignore{"/var/tmp"} = 1;
+$dirs_to_ignore{"/usr/local"} = 1;
+$dirs_to_ignore{"/usr/local/share"} = 1;
+$dirs_to_ignore{"/usr/local/share/man"} = 1;
+$dirs_to_ignore{"/usr/local/share/man/man1"} = 1;
+$dirs_to_ignore{"/usr/local/share/man/man2"} = 1;
+$dirs_to_ignore{"/usr/local/share/man/man3"} = 1;
+$dirs_to_ignore{"/usr/local/share/man/man4"} = 1;
+$dirs_to_ignore{"/usr/local/share/man/man5"} = 1;
+$dirs_to_ignore{"/usr/local/share/man/man6"} = 1;
+$dirs_to_ignore{"/usr/local/share/man/man7"} = 1;
+$dirs_to_ignore{"/usr/local/share/applications"} = 1;
+$dirs_to_ignore{"/usr/local/include"} = 1;
+$dirs_to_ignore{"/usr/local/bin"} = 1;
+$dirs_to_ignore{"/usr/local/sbin"} = 1;
+$dirs_to_ignore{"/usr/local/lib"} = 1;
+$dirs_to_ignore{"/usr/local/lib/pkgconfig"} = 1;
+$dirs_to_ignore{"/usr/local/libexec"} = 1;
+$dirs_to_ignore{"/usr/local/libexec/filters"} = 1;
+$dirs_to_ignore{"/usr/local/etc"} = 1;
+$dirs_to_ignore{"/usr/local/var"} = 1;
+$dirs_to_ignore{"/usr/local/var/run"} = 1;
+$dirs_to_ignore{"/usr/local/var/spool"} = 1;
+$dirs_to_ignore{"/usr/local/var/log"} = 1;
+$dirs_to_ignore{"/usr/local/var/tmp"} = 1;
+
+sub getpwd() {
+ my $back = undef;
+ my $line;
+ if(open(INPUT, "pwd |")) {
+ while(<INPUT>) {
+ $line = $_; chomp $line;
+ if($line =~ /\S+/o) {
+ $back = $line;
+ }
+ }
+ close(INPUT);
+ }
+ return $back;
+}
+
+my $cwd = getpwd();
+
+my @files = (
+"compver", "depend", "space", "copyright", "request",
+"checkinstall", "preinstall", "postinstall",
+"preremove", "postremove", "pkginfo"
+);
+
+if(open(OUTPUT, ">prototype")) {
+ if( -f "pkginfo") {
+ system("chmod 644 pkginfo");
+ print OUTPUT "i pkginfo=$cwd/pkginfo\n";
+ foreach my $i (@files) {
+ if( -f "$i" ) {
+ if ( "$i" ne "pkginfo" ) {
+ system("chmod 644 $i");
+ print OUTPUT "i $i=$cwd/$i\n";
+ }
+ }
+ }
+ if(open(INPUT, "find . -type d -print |")) {
+ my $line;
+ while(<INPUT>) {
+ $line = $_; chomp $line;
+ if("$line" ne ".") {
+ if($line =~ /^\.(.*)$/o) {
+ $line = $1;
+ }
+ if ( ! ( exists( $dirs_to_ignore{"$line"} ) ) ) {
+ print OUTPUT "d none $line 0755 bin bin\n";
+ }
+ }
+ }
+ close(INPUT);
+ }
+ if(open(INPUT, "find . -type f |")) {
+ my $mode = "0644";
+ my $line;
+ my $must_use_this;
+ while(<INPUT>) {
+ $line = $_; chomp $line;
+ $must_use_this = 1;
+ $mode = "0644";
+ foreach my $i (@files) {
+ if ("$i" eq "$line") {
+ $must_use_this = 0;
+ }
+ if ("/$i" eq "$line") {
+ $must_use_this = 0;
+ }
+ if ("./$i" eq "$line") {
+ $must_use_this = 0;
+ }
+ }
+ if($line =~ /^\.(.*)$/o) {
+ $line = $1;
+ }
+ if("$line" ne "prototype") {
+ if("$line" ne "/prototype") {
+ if($line =~ /\/bin\//o) {
+ $mode = "0755";
+ }
+ if($line =~ /\/sbin\//o) {
+ $mode = "0755";
+ }
+ if($line =~ /\/libexec\//o) {
+ $mode = "0755";
+ }
+ if($must_use_this) {
+ print OUTPUT "f none $line=$cwd$line";
+ print OUTPUT " $mode bin bin\n";
+ }
+ }
+ }
+ }
+ close(INPUT);
+ }
+ if(open(INPUT, "find . -type l |")) {
+ my $mode = "0644";
+ my $line;
+ my $must_use_this;
+ my $target;
+ my $l2;
+ my $origline;
+ while(<INPUT>) {
+ $line = $_; chomp $line;
+ $origline = $line;
+ $must_use_this = 1;
+ $mode = "0644";
+ $target = undef;
+ foreach my $i (@files) {
+ if ("$i" eq "$line") {
+ $must_use_this = 0;
+ }
+ if ("/$i" eq "$line") {
+ $must_use_this = 0;
+ }
+ if ("./$i" eq "$line") {
+ $must_use_this = 0;
+ }
+ }
+ if($line =~ /^\.(.*)$/o) {
+ $line = $1;
+ }
+ if("$line" ne "prototype") {
+ if("$line" ne "/prototype") {
+ if($line =~ /\/bin\//o) {
+ $mode = "0755";
+ }
+ if($line =~ /\/sbin\//o) {
+ $mode = "0755";
+ }
+ if($line =~ /\/libexec\//o) {
+ $mode = "0755";
+ }
+ if (open(IN2, "ls -l \"$origline\" |")) {
+ while(<IN2>) {
+ $l2 = $_; chomp $l2;
+ if ("$l2" =~ /.*\->\s+(\S.*)/o) {
+ $target = $1;
+ }
+ }
+ close(IN2);
+ if(($must_use_this) && (defined($target))) {
+ print OUTPUT "s none $line=$target";
+ print OUTPUT " $mode bin bin\n";
+ }
+ }
+ }
+ }
+ }
+ close(INPUT);
+ }
+
+ } else {
+ print "dkmkproto: ERROR: Missing pkginfo file!\n";
+ }
+ close(OUTPUT);
+}
+
diff --git a/support/dktools/scripts/doc-install.sh b/support/dktools/scripts/doc-install.sh
new file mode 100755
index 0000000000..6f59fb28fd
--- /dev/null
+++ b/support/dktools/scripts/doc-install.sh
@@ -0,0 +1,44 @@
+#! /bin/sh
+
+# Copyright (c) 2002-2016, Dirk Krause
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms,
+# with or without modification, are permitted provided
+# that the following conditions are met:
+#
+# * Redistributions of source code must retain the above
+# copyright notice, this list of conditions and the
+# following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# opyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials
+# provided with the distribution.
+# * Neither the name of the Dirk Krause nor the names of
+# contributors may be used to endorse or promote
+# products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED.
+# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+# DAMAGE.
+
+echo `date '+%Y-%m-%d %H:%M:%S'` Start scripts/doc-install.sh
+
+cd doc/src
+make install && cd ../..
+
+echo `date '+%Y-%m-%d %H:%M:%S'` Finished scripts/doc-install.sh
+
diff --git a/support/dktools/scripts/filechk.pl b/support/dktools/scripts/filechk.pl
new file mode 100755
index 0000000000..5d4f9ec878
--- /dev/null
+++ b/support/dktools/scripts/filechk.pl
@@ -0,0 +1,80 @@
+#! /usr/bin/perl
+
+# Copyright (c) 2002-2016, Dirk Krause
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms,
+# with or without modification, are permitted provided
+# that the following conditions are met:
+#
+# * Redistributions of source code must retain the above
+# copyright notice, this list of conditions and the
+# following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# opyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials
+# provided with the distribution.
+# * Neither the name of the Dirk Krause nor the names of
+# contributors may be used to endorse or promote
+# products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED.
+# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+# DAMAGE.
+
+my %filenames;
+my $fh = undef;
+my $line;
+
+if(open($fh, "<filelist.txt")) {
+ while(<$fh>) {
+ $line = $_;
+ chomp($line);
+ $line = "./$line";
+ $filenames{"$line"} = 1;
+ }
+ close($fh); $fh = undef;
+}
+if(open($fh, "find . -type f | sort |")) {
+ while(<$fh>) {
+ $line = $_; chomp($line);
+ $runtest = 1;
+ if($line =~ /\.git\//o) {
+ $runtest = 0;
+ }
+ if($line =~ /\.\/doc\//o) {
+ $runtest = 0;
+ }
+ if($line =~ /\.\/devdoc\//o) {
+ $runtest = 0;
+ }
+ if(0 != $runtest) {
+ if(!(exists($filenames{"$line"}))) {
+ print "Extra file: $line\n";
+ } else {
+ $filenames{"$line"} = 0;
+ }
+ }
+ }
+ close($fh);
+}
+
+my $fn;
+foreach $fn (sort (keys %filenames)) {
+ if (1 == $filenames{"$line"}) {
+ print "Not found: $fn\n";
+ }
+}
diff --git a/support/dktools/scripts/find-headers-without-modules.sh b/support/dktools/scripts/find-headers-without-modules.sh
new file mode 100755
index 0000000000..a47f59cecb
--- /dev/null
+++ b/support/dktools/scripts/find-headers-without-modules.sh
@@ -0,0 +1,61 @@
+:
+
+# Copyright (c) 2002-2016, Dirk Krause
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms,
+# with or without modification, are permitted provided
+# that the following conditions are met:
+#
+# * Redistributions of source code must retain the above
+# copyright notice, this list of conditions and the
+# following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# opyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials
+# provided with the distribution.
+# * Neither the name of the Dirk Krause nor the names of
+# contributors may be used to endorse or promote
+# products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED.
+# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+# DAMAGE.
+
+for i in *.h
+do
+ found=no
+ j=`echo $i | sed -e 's/\.h/.ctr/g'`
+ if [ -f $j ]
+ then
+ found=yes
+ fi
+ j=`echo $i | sed -e 's/\.h/.cpt/g'`
+ if [ -f $j ]
+ then
+ found=yes
+ fi
+ j=`echo $i | sed -e 's/\.h/.wxc/g'`
+ if [ -f $j ]
+ then
+ found=yes
+ fi
+ if [ "X$found" = "Xno" ]
+ then
+ echo $i
+ fi
+done
+
diff --git a/support/dktools/scripts/git-add.sh b/support/dktools/scripts/git-add.sh
new file mode 100755
index 0000000000..ffa5eb118e
--- /dev/null
+++ b/support/dktools/scripts/git-add.sh
@@ -0,0 +1,95 @@
+:
+
+# Copyright (c) 2002-2016, Dirk Krause
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms,
+# with or without modification, are permitted provided
+# that the following conditions are met:
+#
+# * Redistributions of source code must retain the above
+# copyright notice, this list of conditions and the
+# following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# opyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials
+# provided with the distribution.
+# * Neither the name of the Dirk Krause nor the names of
+# contributors may be used to endorse or promote
+# products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED.
+# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+# DAMAGE.
+
+echo `date '+%Y-%m-%d %H:%M:%S'` Start scripts/git-add.sh
+
+git add TODO
+git add dk4*.ctr
+git add dk3trace.ctr
+git add *.dox
+git add *.vc
+git add *.sed
+git add dk-cat.ctr
+git add version.txt
+git add scripts/*
+git add `find dktools -type f`
+git add `find dk4app -type f`
+git add `scripts/find-headers-without-modules.sh`
+git add doc/src/*.txt
+git add doc/src/*.tex
+git add doc/src/*.fig
+git add doc/src/*.sh
+git add doc/src/*.hbt
+git add doc/src/*.prj
+git add configure.ac
+git add Makefile.in
+git add doc/src/favicon.ico
+git add doc/src/GNUmakefile
+git add doc/src/*.css
+git add win32/*
+git add *.rc
+git add filelist.txt
+git add help-src/*/*/*.prj
+git add help-src/*/*/*.hbt
+git add help-src/*/*/GNUmakefile
+git add help-src/*/*/*.fig
+git add help-src/*/*/*.css
+git add help-src/*/*/*.txt
+git add man-src/GNUmakefile
+git add man-src/*.adoc
+
+for i in svg png pdf
+do
+ for j in index next prev toc
+ do
+ [ ! -f doc/src/$j.$i ] || git add doc/src/$j.$i
+ done
+done
+FILES=`find dktools -type f`
+if [ "X$FILES" != "X" ]
+then
+ git add $FILES
+fi
+FILES=`find dktools -type f`
+if [ "X$FILES" != "X" ]
+then
+ git add $FILES
+fi
+git add `find livesys-data -type f`
+
+echo `date '+%Y-%m-%d %H:%M:%S'` Finished scripts/git-add.sh
+
diff --git a/support/dktools/scripts/make-resources.sh b/support/dktools/scripts/make-resources.sh
new file mode 100755
index 0000000000..de324738cd
--- /dev/null
+++ b/support/dktools/scripts/make-resources.sh
@@ -0,0 +1,44 @@
+#! /bin/sh
+
+# Copyright (c) 2002-2016, Dirk Krause
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms,
+# with or without modification, are permitted provided
+# that the following conditions are met:
+#
+# * Redistributions of source code must retain the above
+# copyright notice, this list of conditions and the
+# following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# opyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials
+# provided with the distribution.
+# * Neither the name of the Dirk Krause nor the names of
+# contributors may be used to endorse or promote
+# products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED.
+# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+# DAMAGE.
+
+echo `date '+%Y-%m-%d %H:%M:%S'` Start scripts/make-resources.sh
+
+cd resources
+make && cd ..
+
+echo `date '+%Y-%m-%d %H:%M:%S'` Finished scripts/make-resources.sh
+
diff --git a/support/dktools/scripts/man-install.sh b/support/dktools/scripts/man-install.sh
new file mode 100755
index 0000000000..eb1db35bc4
--- /dev/null
+++ b/support/dktools/scripts/man-install.sh
@@ -0,0 +1,44 @@
+#! /bin/sh
+
+# Copyright (c) 2002-2016, Dirk Krause
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms,
+# with or without modification, are permitted provided
+# that the following conditions are met:
+#
+# * Redistributions of source code must retain the above
+# copyright notice, this list of conditions and the
+# following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# opyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials
+# provided with the distribution.
+# * Neither the name of the Dirk Krause nor the names of
+# contributors may be used to endorse or promote
+# products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED.
+# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+# DAMAGE.
+
+echo `date '+%Y-%m-%d %H:%M:%S'` Start scripts/man-install.sh
+
+cd man-src
+make install && cd ..
+
+echo `date '+%Y-%m-%d %H:%M:%S'` Finished scripts/man-install.sh
+
diff --git a/support/dktools/scripts/mkrc.pl b/support/dktools/scripts/mkrc.pl
new file mode 100755
index 0000000000..6eec882fb6
--- /dev/null
+++ b/support/dktools/scripts/mkrc.pl
@@ -0,0 +1,647 @@
+#! /usr/bin/perl
+
+# Copyright (c) 2002-2016, Dirk Krause
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms,
+# with or without modification, are permitted provided
+# that the following conditions are met:
+#
+# * Redistributions of source code must retain the above
+# copyright notice, this list of conditions and the
+# following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# opyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials
+# provided with the distribution.
+# * Neither the name of the Dirk Krause nor the names of
+# contributors may be used to endorse or promote
+# products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED.
+# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+# DAMAGE.
+
+my $version = "4.8.0";
+my $copyrightyears = "2017";
+
+sub create_rc_file($$$$$$$$$)
+{
+ my $filename = shift;
+ my $vendor = shift;
+ my $iconfile = shift;
+ my $swname = shift;
+ my $version = shift;
+ my $prodname = shift;
+ my $internalname = shift;
+ my $fileversion = shift;
+ my $prodversion = shift;
+ my $outfile = undef;
+ if($version =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)/o) {
+ $fileversion = $1 . "," . $2 . "," . $3 . "," . $4;
+ $prodversion = $fileversion;
+ } else {
+ if($version =~ /(\d+)\.(\d+)\.(\d+)/o) {
+ $fileversion = $1 . "," . $2 . "," . $3 . ",0";
+ $prodversion = $fileversion;
+ } else {
+ if($version =~ /(\d+)\.(\d+)/o) {
+ $fileversion = $1 . "," . $2 . ",0,0";
+ $prodversion = $fileversion;
+ } else {
+ if($version =~ /(\d+)/o) {
+ $fileversion = $1 . ",0,0,0";
+ $prodversion = $fileversion;
+ }
+ }
+ }
+ }
+ if(open($outfile, ">$filename")) {
+ if(defined($iconfile)) {
+ print $outfile "aaaaa ICON $iconfile\r\n\r\n";
+ # print $outfile "#include \"wx/msw/wx.rc\"\r\n";
+ }
+ print $outfile "#include <windows.h>\r\n";
+ print $outfile "\r\n";
+ print $outfile "VS_VERSION_INFO VERSIONINFO\r\n";
+ print $outfile " FILEVERSION $fileversion\r\n";
+ print $outfile " PRODUCTVERSION $prodversion\r\n";
+ print $outfile " FILEFLAGSMASK 0x3fL\r\n";
+ print $outfile "#ifdef _DEBUG\r\n";
+ print $outfile " FILEFLAGS 0x1L\r\n";
+ print $outfile "#else\r\n";
+ print $outfile " FILEFLAGS 0x0L\r\n";
+ print $outfile "#endif\r\n";
+ print $outfile " FILEOS 0x4L\r\n";
+ print $outfile " FILETYPE 0x1L\r\n";
+ print $outfile " FILESUBTYPE 0x0L\r\n";
+ print $outfile "BEGIN\r\n";
+ print $outfile " BLOCK \"StringFileInfo\"\r\n";
+ print $outfile " BEGIN\r\n";
+ print $outfile " BLOCK \"040904b0\"\r\n";
+ print $outfile " BEGIN\r\n";
+ print $outfile " VALUE \"Comments\", \"$swname\\0\"\r\n";
+ print $outfile " VALUE \"CompanyName\", \"$vendor\\0\"\r\n";
+ print $outfile " VALUE \"FileDescription\", \"$swname\\0\"\r\n";
+ print $outfile " VALUE \"FileVersion\", \"$version\\0\"\r\n";
+ print $outfile " VALUE \"InternalName\", \"$internalname\\0\"\r\n";
+ print $outfile " VALUE \"LegalCopyright\", \"Copyright \251 $copyrightyears $vendor\\0\"\r\n";
+ print $outfile " VALUE \"ProductName\", \"$prodname\\0\"\r\n";
+ print $outfile " VALUE \"ProductVersion\", \"$version\\0\"\r\n";
+ print $outfile " END\r\n";
+ print $outfile " END\r\n";
+ print $outfile " BLOCK \"VarFileInfo\"\r\n";
+ print $outfile " BEGIN\r\n";
+ print $outfile " VALUE \"Translation\", 0x409, 1200\r\n";
+ print $outfile " END\r\n";
+ print $outfile "END\r\n";
+ print $outfile "\r\n";
+ close($outfile);
+ }
+}
+
+
+my $infile = undef;
+my $firstline = 1;
+if(open($infile, "<version.txt")) {
+ while(<$infile>) {
+ $line = $_; chomp($line);
+ if($firstline) {
+ if($line =~ /(\S+)/o) {
+ $version = $1;
+ $firstline = 0;
+ }
+ }
+ }
+ close($infile);
+}
+
+create_rc_file(
+ "dk-cat.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "A cat clone, shows text file contents",
+ $version,
+ "Dirk Krause's tools",
+ "dk-cat",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "dk-blks.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "Blocksize corrector, creates sequence of fixed size blocks",
+ $version,
+ "Dirk Krause's tools",
+ "dk-blks",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "dk-eradisk.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "Create data stream to erase a disk",
+ $version,
+ "Dirk Krause's tools",
+ "dk-eradisk",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "dk-ls.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "An ls clone, configurable output column order",
+ $version,
+ "Dirk Krause's tools",
+ "dk-ls",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "dk-sort.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "A sort clone, mainly intended for Windows",
+ $version,
+ "Dirk Krause's tools",
+ "dk-sort",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "dk-fic.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "File integrity check",
+ $version,
+ "Dirk Krause's tools",
+ "dk-fic",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "dk-sqlsplit.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "Split overlong SQL lines",
+ $version,
+ "Dirk Krause's tools",
+ "dk-sqlsplit",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "dk-pwgen.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "Generator for passwords, PINs and hexadecimal keys",
+ $version,
+ "Dirk Krause's tools",
+ "dk-pwgen",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "dk-rand.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "Random data generator",
+ $version,
+ "Dirk Krause's tools",
+ "dk-rand",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "dk-t2h.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "Text to HTML converter",
+ $version,
+ "Dirk Krause's tools",
+ "dk-t2h",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "dk-t2l.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "Text to LaTeX converter",
+ $version,
+ "Dirk Krause's tools",
+ "dk-t2l",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "dk-hex.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "Show file contents in hexadecimal notation",
+ $version,
+ "Dirk Krause's tools",
+ "dk-hex",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "dk-bmm.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "Backup media manager",
+ $version,
+ "Dirk Krause's tools",
+ "dk-bmm",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "dk-recv.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "Receive data transmission",
+ $version,
+ "Dirk Krause's tools",
+ "dk-recv",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "dk-send.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "Send data transmission",
+ $version,
+ "Dirk Krause's tools",
+ "dk-send",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "dk-t2db.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "Convert text to simple text database",
+ $version,
+ "Dirk Krause's tools",
+ "dk-t2db",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "dk-db2t.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "Write simple text database to standard output",
+ $version,
+ "Dirk Krause's tools",
+ "dk-db2t",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "dk-dbco.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "Copy and convert simple databases",
+ $version,
+ "Dirk Krause's tools",
+ "dk-dbco",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "dk4info.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "Show setup information",
+ $version,
+ "Dirk Krause's tools",
+ "dk4info",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "dkct.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "Dirk Krause's C tool",
+ $version,
+ "Dirk Krause's tools",
+ "dkct",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "addctrld.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "Ensure final Ctrl-D",
+ $version,
+ "Dirk Krause's tools",
+ "addctrld",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "dkdbt.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "Database tool",
+ $version,
+ "Dirk Krause's tools",
+ "dkdbt",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "bmpp.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "Bitmap to PS/PDF converter",
+ $version,
+ "Dirk Krause's tools",
+ "bmpp",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "fig2lat.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "Fig to LaTeX converter",
+ $version,
+ "Dirk Krause's tools",
+ "fig2lat",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "htmlbook.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "Publish book-like HTML",
+ $version,
+ "Dirk Krause's tools",
+ "htmlbook",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "plpdftex.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "Output driver for octpgfpl",
+ $version,
+ "Dirk Krause's tools",
+ "plpdftex",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "dkwxwiz.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "Project wizard",
+ $version,
+ "Dirk Krause's tools",
+ "dkwxwiz",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "wxdkct.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "Dirk Krause's C tool (GUI)",
+ $version,
+ "Dirk Krause's tools",
+ "wxdkct",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "wxbmpp.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "Bitmap to PS/PDF converter (GUI)",
+ $version,
+ "Dirk Krause's tools",
+ "wxbmpp",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "wxpqdic.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "Printqdi client (GUI)",
+ $version,
+ "Dirk Krause's tools",
+ "wxpqdic",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "wximgsz.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "Image rescale calculator (GUI)",
+ $version,
+ "Dirk Krause's tools",
+ "wximgsz",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "wxdkclock.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "Simple clock with one alert (GUI)",
+ $version,
+ "Dirk Krause's tools",
+ "wxdkclock",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "wxdkhtb.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "HTB help file viewer (GUI)",
+ $version,
+ "Dirk Krause's tools",
+ "wxdkhtb",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "lprngcl.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "LPRng print queue cleaner",
+ $version,
+ "Dirk Krause's tools",
+ "lprngcl",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "itadmin.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "IT management using a MySQL DB",
+ $version,
+ "Dirk Krause's tools",
+ "itadmin",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "dk3info.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "Show setup information",
+ $version,
+ "Dirk Krause's tools",
+ "dk3info",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "dkwt.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "Dirk Krause's Windows tool",
+ $version,
+ "Dirk Krause's tools",
+ "dkwt",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "dkwtadm.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "Dirk Krause's Windows adm tool",
+ $version,
+ "Dirk Krause's tools",
+ "dkwtadm",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "wprclean.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "Clean Windows print queue",
+ $version,
+ "Dirk Krause's tools",
+ "wprclean",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "winprint.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "Schedule file to Windows print queue",
+ $version,
+ "Dirk Krause's tools",
+ "winprint",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "dkwxpath.rc",
+ "Dirk Krause",
+ "dkctinst.ico",
+ "Path setup during installation",
+ $version,
+ "Dirk Krause's tools",
+ "dkwxpath",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "wxdkfcs.rc",
+ "Dirk Krause",
+ "dkicon.ico",
+ "Checksum builder with GUI",
+ $version,
+ "Dirk Krause's tools",
+ "wxdkfcs",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
+create_rc_file(
+ "wxdkscrsz.rc",
+ "Dirk Krause",
+ "wxdkscrsz.ico",
+ "Change Screen Size",
+ $version,
+ "Dirk Krause's tools",
+ "ChangeScreenSize",
+ "0,0,0,1",
+ "0,0,0,1"
+);
+
diff --git a/support/dktools/scripts/show-dependencies.pl b/support/dktools/scripts/show-dependencies.pl
new file mode 100755
index 0000000000..1e3a1a05ff
--- /dev/null
+++ b/support/dktools/scripts/show-dependencies.pl
@@ -0,0 +1,98 @@
+#! /usr/bin/perl
+
+# Copyright (c) 2002-2016, Dirk Krause
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms,
+# with or without modification, are permitted provided
+# that the following conditions are met:
+#
+# * Redistributions of source code must retain the above
+# copyright notice, this list of conditions and the
+# following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# opyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials
+# provided with the distribution.
+# * Neither the name of the Dirk Krause nor the names of
+# contributors may be used to endorse or promote
+# products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED.
+# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+# DAMAGE.
+
+my $ifh = undef;
+my $args = undef;
+my $arg = undef;
+my $line;
+my $libname;
+my $pkgname;
+my $architecture;
+my $lastname;
+my $namefound;
+my %libnames;
+my %pkgnames;
+
+while($#ARGV > -1) {
+ $arg = shift @ARGV;
+ if (defined($args)) {
+ $args = "$args $arg";
+ } else {
+ $args = "$arg";
+ }
+}
+
+if (open($ifh, "objdump -p $args |")) {
+ while(<$ifh>) {
+ $line = $_; chomp $line;
+ if ($line =~ /^\s+NEEDED\s+(\S+)/o) {
+ $libname = $1;
+ $libnames{"$libname"} = 1;
+ }
+ }
+ close($ifh);
+ foreach $libname (sort (keys %libnames)) {
+ $ifh = undef;
+ if (open($ifh, "dpkg -S $libname |")) {
+ while(<$ifh>) {
+ $line = $_; chomp $line;
+ if ($line =~ /^\s*(\S+)\s+(\S+)/o) {
+ $pkgname = $1; $namefound = $2;
+ if ($pkgname =~ /^([^:]+):/o) {
+ $pkgname = $1;
+ }
+ $lastname = undef;
+ if ($namefound =~ /\/lib\/[^\/]+\/(lib[^\/]+)/o) {
+ $lastname = $1;
+ }
+ if ($namefound =~ /\/usr\/lib\/[^\/]+\/(lib[^\/]+)/o) {
+ $lastname = $1;
+ }
+ if (defined($lastname)) {
+ if ("$lastname" eq "$libname") {
+ $pkgnames{"$pkgname"} = 1;
+ }
+ }
+ }
+ }
+ close($ifh);
+ }
+ }
+ foreach $pkgname (sort (keys %pkgnames)) {
+ print "$pkgname\n";
+ }
+}
diff --git a/support/dktools/scripts/transform-config.pl b/support/dktools/scripts/transform-config.pl
new file mode 100755
index 0000000000..b8a3b34705
--- /dev/null
+++ b/support/dktools/scripts/transform-config.pl
@@ -0,0 +1,302 @@
+#! /usr/bin/perl
+
+# Copyright (c) 2002-2016, Dirk Krause
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms,
+# with or without modification, are permitted provided
+# that the following conditions are met:
+#
+# * Redistributions of source code must retain the above
+# copyright notice, this list of conditions and the
+# following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# opyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials
+# provided with the distribution.
+# * Neither the name of the Dirk Krause nor the names of
+# contributors may be used to endorse or promote
+# products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED.
+# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+# DAMAGE.
+
+my @constnames;
+my $nconstnames = 0;
+
+my @oldconstnames;
+my $noldconstnames = 0;
+
+sub read_config_h_in_file()
+{
+ my $back = 0;
+ my $lineno = 0;
+ my $fh = undef;
+ my $line;
+ my $name;
+ my $nfound = 0;
+ my $inscope = 1;
+ if ( open($fh, "<config.h.in") ) {
+ $back = 1;
+ while(<$fh>) {
+ $line = $_; chomp $line; $lineno++;
+ if ($line =~ /Backward\s+compatibility\s+section\s+start/o) {
+ $inscope = 0;
+ } else {
+ if ($line =~ /Backward\s+compatibility\s+section\s+end/o) {
+ $inscope = 1;
+ } else {
+ if (0 != $inscope) {
+ if ($line =~ /^#define\s*(\S*)\s+/o) {
+ $name = $1;
+ if (0 < $nfound) {
+ $constnames[$nconstnames++] = $name;
+ }
+ $nfound++;
+ }
+ } else {
+ if ($line =~ /^#define\s*(\S*)\s+/o) {
+ $name = $1;
+ if (0 < $nfound) {
+ $oldconstnames[$noldconstnames++] = $name;
+ }
+ $nfound++;
+ }
+ }
+ }
+ }
+ }
+ close($fh);
+ } else {
+ print "ERROR: Failed to read config.h.in file!\n";
+ }
+ return $back;
+}
+
+sub write_dk4info1_c_file()
+{
+ my $fh = undef;
+ my $name;
+ if ( open($fh, ">dk4info1.c") ) {
+ print $fh "static\nvoid\nshowdefines(void)\n{\n dkChar buf[64];\n\n";
+ foreach $name (sort @constnames) {
+ if ($name =~ /SIZEOF/o) {
+ print $fh "#ifdef DK4_$name\n";
+ print $fh " dk4ma_write_decimal_unsigned(buf, DK4_SIZEOF(buf, dkChar), (dk4_um_t)DK4_$name, 0, NULL);\n";
+ print $fh " dk4fputs(dkT(\"DK4_$name = \"), stdout, NULL);\n";
+ print $fh " dk4fputs(buf, stdout, NULL);\n";
+ print $fh " dk4fputc(dkT('\\n'), stdout, NULL);\n";
+ print $fh "#else\n";
+ print $fh " dk4fputs(dkT(\"DK4_$name = 0\\n\"), stdout, NULL);\n";
+ print $fh "#endif\n";
+ }
+ elsif ($name =~ /HAVE/o) {
+ print $fh "#if DK4_$name\n";
+ print $fh " dk4fputs(dkT(\"DK4_$name = 1\\n\"), stdout, NULL);\n";
+ print $fh "#else\n";
+ print $fh " dk4fputs(dkT(\"DK4_$name = 0\\n\"), stdout, NULL);\n";
+ print $fh "#endif\n";
+ }
+ else {
+ print $fh "#ifdef DK4_$name\n";
+ print $fh " dk4ma_write_decimal_unsigned(buf, DK4_SIZEOF(buf, dkChar), (dk4_um_t)DK4_$name, 0, NULL);\n";
+ print $fh " dk4fputs(dkT(\"DK4_$name = \"), stdout, NULL);\n";
+ print $fh " dk4fputs(buf, stdout, NULL);\n";
+ print $fh " dk4fputc(dkT('\\n'), stdout, NULL);\n";
+ print $fh "#else\n";
+ print $fh " dk4fputs(dkT(\"DK4_$name = 0\\n\"), stdout, NULL);\n";
+ print $fh "#endif\n";
+ }
+ print $fh "\n";
+ }
+ print $fh "}\n";
+ close($fh);
+ } else {
+ print "ERROR: Failed to write dk4info1.c file!\n";
+ }
+}
+
+sub write_dkconfig_c_file()
+{
+ my $fh = undef;
+
+ if ( open($fh, ">dk4config.cpp") ) {
+ print $fh "/**\t\@file dk4config.cpp Fix configure results.\n";
+ print $fh "\tRedirect output from this program to the dk4conf.h file.\n";
+ print $fh "*/\n\n";
+ print $fh "#include <stdio.h>\n";
+ print $fh "#include \"config.h\"\n\n";
+ print $fh "/* wxWidgets_header_start */\n";
+ print $fh "#if HAVE_WXWIDGETS\n";
+ print $fh "#include <wx/wxprec.h>\n";
+ print $fh "#ifdef __BORLANDC__\n";
+ print $fh "#pragma hdrstop\n";
+ print $fh "#endif \n";
+ print $fh "#ifndef WX_PRECOMP\n";
+ print $fh "#if DK4_HAVE_WX_CHARTYPE_H\n";
+ print $fh "#ifndef WX_CHARTYPE_H_INCLUDED\n";
+ print $fh "#include <wx/chartype.h>\n";
+ print $fh "#define WX_CHARTYPE_H_INCLUDED 1\n";
+ print $fh "#endif\n";
+ print $fh "#else\n";
+ print $fh "#if\tDK4_HAVE_WX_WXCHAR_H\n";
+ print $fh "#ifndef WX_WXCHAR_H_INCLUDED\n";
+ print $fh "#include <wx/wxchar.h>\n";
+ print $fh "#define WX_WXCHAR_H_INCLUDED 1\n";
+ print $fh "#endif\n";
+ print $fh "#else\n";
+ print $fh "#ifndef WX_WX_H_INCLUDED\n";
+ print $fh "#include <wx/wx.h>\n";
+ print $fh "#define WX_WX_H_INCLUDED 1\n";
+ print $fh "#endif\n";
+ print $fh "#endif\n";
+ print $fh "#endif\n";
+ print $fh "#endif\n";
+ print $fh "#endif\n";
+ print $fh "/* wxWidgets_header_end*/\n\n";
+
+ print $fh "#include <dk3trace.h>\n";
+ print $fh "#ifndef TRACE_DEBUG\n";
+ print $fh "#define TRACE_DEBUG 1\n";
+ print $fh "#endif\n";
+
+ print $fh "int main(void)\n{\n";
+ print $fh "\n";
+ print $fh " fputs(\"/**\\t\@file dk4conf.h\tFixed configure results.\\n*/\\n\\n\", stdout);\n";
+ print $fh " fputs(\"#ifndef DK4CONF_H_INCLUDED\\n\", stdout);\n";
+ print $fh " fputs(\"/**\\tProtection against multiple inclusion.\\n*/\\n\", stdout);\n";
+ print $fh " fputs(\"#define DK4CONF_H_INCLUDED 1\\n\\n\", stdout);\n";
+ foreach $name (sort @constnames) {
+ if ($name =~ /SIZEOF/o) {
+ print $fh "#if $name\n";
+ print $fh " fputs(\"/**\tDK4 version of $name.\\n*/\\n\", stdout);\n";
+ print $fh " printf(\"#define DK4_$name %u\\n\", (unsigned)$name);\n";
+ print $fh "#else\n";
+ print $fh " fputs(\"/**\tDK4 version of $name.\\n*/\\n\", stdout);\n";
+ print $fh " fputs(\"#define DK4_$name 0\\n\", stdout);\n";
+ print $fh "#endif\n";
+ }
+ elsif ($name =~ /HAVE/o) {
+ print $fh "#if $name\n";
+ print $fh " fputs(\"/**\tDK4 version of $name.\\n*/\\n\", stdout);\n";
+ print $fh " fputs(\"#define DK4_$name 1\\n\", stdout);\n";
+ print $fh "#else\n";
+ print $fh " fputs(\"/**\tDK4 version of $name.\\n*/\\n\", stdout);\n";
+ print $fh " fputs(\"#define DK4_$name 0\\n\", stdout);\n";
+ print $fh "#endif\n";
+ }
+ else {
+ print $fh "#if $name\n";
+ print $fh " fputs(\"/**\tDK4 version of $name.\\n*/\\n\", stdout);\n";
+ print $fh " printf(\"#define DK4_$name %u\\n\", (unsigned)$name);\n";
+ print $fh "#else\n";
+ print $fh " fputs(\"/**\tDK4 version of $name.\\n*/\\n\", stdout);\n";
+ print $fh " fputs(\"#define DK4_$name 0\\n\", stdout);\n";
+ print $fh "#endif\n";
+ }
+ print $fh " fputc('\\n', stdout);\n";
+ }
+
+ print $fh "/* wxWidgets_body_start */\n";
+ print $fh "#if HAVE_WXWIDGETS\n";
+ print $fh " fputs(\"/**\tSize of wchar_t.\\n*/\\n\", stdout);\n";
+ print $fh " printf(\"#define DK4_SIZEOF_WXCHAR %u\\n\\n\", (unsigned)sizeof(wxChar));\n";
+ print $fh "#else\n";
+ print $fh " fputs(\"/**\tSize of wchar_t.\\n*/\\n\", stdout);\n";
+ print $fh " fputs(\"#define DK4_SIZEOF_WXCHAR 0\\n\\n\", stdout);\n";
+ print $fh "#endif\n";
+ print $fh "/* wxWidgets_body_end */\n\n";
+
+
+ print $fh " fputs(\"#endif\\n/* ifndef DK4CONF_H_INCLUDED */\\n\", stdout);\n";
+ print $fh " return 0;\n}\n";
+ close($fh);
+ } else {
+ print "ERROR: Failed to write dk4config.c file!\n";
+ }
+}
+
+sub write_dkconfig_cross()
+{
+ my $fh = undef;
+
+ if ( open($fh, ">dk4conf.cross") ) {
+ print $fh "#ifndef DK4CONF_H_INCLUDED\n\n";
+ print $fh "/** Protection against multiple inclusions. */\n";
+ print $fh "#define DK4CONF_H_INCLUDED 1\n\n";
+ print $fh "#include \"config.h\"\n\n";
+
+ print $fh "#ifndef DK4_ON_WINDOWS\n";
+ print $fh "#ifdef _WIN32\n";
+ print $fh "#define DK4_ON_WINDOWS 1\n";
+ print $fh "#ifndef\tHAVE_BACKSLASH_AS_SEP\n";
+ print $fh "#define\tHAVE_BACKSLASH_AS_SEP\ŧ1\n";
+ print $fh "#endif\n";
+ print $fh "#else\n";
+ print $fh "#define DK4_ON_WINDOWS 0\n";
+ print $fh "#endif\n";
+ print $fh "#endif\n\n";
+
+ foreach $name (sort @constnames) {
+ if ($name =~ /SIZEOF/o) {
+ print $fh "#ifndef DK4_$name\n";
+ print $fh "/**\tDK4 version of $name.\n";
+ print $fh "*/\n";
+ print $fh "#define DK4_$name $name\n";
+ print $fh "#endif\n";
+ }
+ elsif ($name =~ /HAVE/o) {
+ print $fh "#ifndef DK4_$name\n";
+ print $fh "#if $name\n";
+ print $fh "/** DK4 version of $name, available.\n";
+ print $fh "*/\n";
+ print $fh "#define DK4_$name 1\n";
+ print $fh "#else\n";
+ print $fh "/** DK4 version of $name, not available.\n";
+ print $fh "*/\n";
+ print $fh "#define DK4_$name 0\n";
+ print $fh "#endif\n";
+ print $fh "#endif\n";
+ }
+ else {
+ print $fh "#ifndef DK4_$name\n";
+ print $fh "#if $name\n";
+ print $fh "/** DK4 version of $name, available.\n";
+ print $fh "*/\n";
+ print $fh "#define DK4_$name $name\n";
+ print $fh "#else\n";
+ print $fh "/** DK4 version of $name, not available.\n";
+ print $fh "*/\n";
+ print $fh "#define DK4_$name 0\n";
+ print $fh "#endif\n";
+ print $fh "#endif\n";
+ }
+ print $fh "\n";
+ }
+ print $fh "#endif\n/* if DK4CONF_H_INCLUDED */\n";
+ close($fh);
+ } else {
+ print "ERROR: Failed to write dk4config.c file!\n";
+ }
+}
+
+if ( read_config_h_in_file() ) {
+ write_dk4info1_c_file();
+ write_dkconfig_c_file();
+ write_dkconfig_cross();
+}
+
diff --git a/support/dktools/scripts/update-doxyfile.sh b/support/dktools/scripts/update-doxyfile.sh
new file mode 100755
index 0000000000..557cf9f162
--- /dev/null
+++ b/support/dktools/scripts/update-doxyfile.sh
@@ -0,0 +1,47 @@
+#! /bin/sh
+
+# Copyright (c) 2002-2016, Dirk Krause
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms,
+# with or without modification, are permitted provided
+# that the following conditions are met:
+#
+# * Redistributions of source code must retain the above
+# copyright notice, this list of conditions and the
+# following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# opyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials
+# provided with the distribution.
+# * Neither the name of the Dirk Krause nor the names of
+# contributors may be used to endorse or promote
+# products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED.
+# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+# DAMAGE.
+
+echo `date '+%Y-%m-%d %H:%M:%S'` Start scripts/update-doxyfile.sh
+
+VERSNO=`cat version.txt`
+cp Doxyfile Doxyfile.tmp
+cat Doxyfile.tmp | sed -e "/^PROJECT_NUMBER/cPROJECT_NUMBER = $VERSNO" > Doxyfile
+rm Doxyfile.tmp
+
+
+echo `date '+%Y-%m-%d %H:%M:%S'` Finished scripts/update-doxyfile.sh
+
diff --git a/support/dktools/scripts/wr-dk3inst.sh.in b/support/dktools/scripts/wr-dk3inst.sh.in
new file mode 100644
index 0000000000..1c6e098b20
--- /dev/null
+++ b/support/dktools/scripts/wr-dk3inst.sh.in
@@ -0,0 +1,106 @@
+:
+
+# Copyright (c) 2002-2016, Dirk Krause
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms,
+# with or without modification, are permitted provided
+# that the following conditions are met:
+#
+# * Redistributions of source code must retain the above
+# copyright notice, this list of conditions and the
+# following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# opyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials
+# provided with the distribution.
+# * Neither the name of the Dirk Krause nor the names of
+# contributors may be used to endorse or promote
+# products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED.
+# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+# DAMAGE.
+
+# Standard directory variables from autoconf
+prefix=@prefix@
+datarootdir=@datarootdir@
+exec_prefix=@exec_prefix@
+bindir=@bindir@
+sbindir=@sbindir@
+libexecdir=@libexecdir@
+datadir=${datarootdir}
+sysconfdir=@sysconfdir@
+scd=${sysconfdir}
+libdir=@libdir@
+sharedlibdir=${libdir}/shared
+mandir=@mandir@
+includedir=@includedir@
+localstatedir=@localstatedir@
+
+cat <<EOF
+
+#include "dk3conf.h"
+#include "dk3types.h"
+#include "dk3inst.h"
+
+
+dkChar const * const dk3inst_directories[] = {
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+ /* 0 */ dkT("C:\\\\Program Files\\\\Krause"),
+ /* 1 */ dkT("C:\\\\Program Files\\\\Krause\\\\etc"),
+ /* 2 */ dkT("C:\\\\Program Files\\\\Krause\\\\share"),
+ /* 3 */ dkT("C:\\\\Program Files\\\\Krause\\\\var"),
+ /* 4 */ dkT("C:\\\\Program Files\\\\Krause\\\\bin"),
+ /* 5 */ dkT("C:\\\\Program Files\\\\Krause\\\\sbin"),
+ /* 6 */ dkT("C:\\\\Program Files\\\\Krause\\\\lib"),
+ /* 7 */ dkT("C:\\\\Program Files\\\\Krause\\\\include"),
+ /* 8 */ dkT("C:\\\\Program Files\\\\Krause\\\\man"),
+ /* 9 */ dkT("C:\\\\Program Files\\\\Krause"),
+ /* 10 */ dkT("C:\\\\Program Files\\\\Krause\\\\libexec"),
+#else
+ /* 0 */ dkT("$prefix"),
+ /* 1 */ dkT("$sysconfdir"),
+ /* 2 */ dkT("$datarootdir"),
+ /* 3 */ dkT("$localstatedir"),
+ /* 4 */ dkT("$bindir"),
+ /* 5 */ dkT("$sbindir"),
+ /* 6 */ dkT("$libdir"),
+ /* 7 */ dkT("$includedir"),
+ /* 8 */ dkT("$mandir"),
+ /* 9 */ dkT("$exec_prefix"),
+ /* 10 */ dkT("$libexecdir"),
+#endif
+};
+
+
+
+dkChar const *
+dk3inst_get_directory(size_t i)
+/* {{{ */
+{
+ dkChar const *back = NULL;
+ if(i <= 10) { back = dk3inst_directories[i]; }
+ return back;
+}
+/* }}} */
+
+
+
+/* vim: set ai sw=2 filetype=c foldmethod=marker foldopen=all : */
+
+EOF
+
diff --git a/support/dktools/scripts/wr-dk4inst.sh.in b/support/dktools/scripts/wr-dk4inst.sh.in
new file mode 100644
index 0000000000..b8c6f60a2b
--- /dev/null
+++ b/support/dktools/scripts/wr-dk4inst.sh.in
@@ -0,0 +1,274 @@
+:
+
+# Copyright (c) 2002-2016, Dirk Krause
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms,
+# with or without modification, are permitted provided
+# that the following conditions are met:
+#
+# * Redistributions of source code must retain the above
+# copyright notice, this list of conditions and the
+# following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# opyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials
+# provided with the distribution.
+# * Neither the name of the Dirk Krause nor the names of
+# contributors may be used to endorse or promote
+# products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED.
+# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+# DAMAGE.
+
+# Standard directory variables from autoconf
+prefix=@prefix@
+datarootdir=@datarootdir@
+exec_prefix=@exec_prefix@
+bindir=@bindir@
+sbindir=@sbindir@
+libexecdir=@libexecdir@
+datadir=${datarootdir}
+sysconfdir=@sysconfdir@
+scd=${sysconfdir}
+libdir=@libdir@
+sharedlibdir=${libdir}/shared
+mandir=@mandir@
+includedir=@includedir@
+localstatedir=@localstatedir@
+
+CURRENT_TIMESTAMP=`date '+%Y-%m-%d %H:%M:%S'`
+
+cat >dk4inst.c <<EOF
+/** @file dk4inst.c Installation directories.
+ Produced by configure, $CURRENT_TIMESTAMP.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4INST_H_INCLUDED
+#include "dk4inst.h"
+#endif
+
+
+
+/** Directory names.
+*/
+const dkChar * const dk4inst_directories[] = {
+#if DK4_ON_WINDOWS || DK4_HAVE_BACKSLASH_AS_SEP
+ /* 0 */ dkT("C:\\\\Program Files\\\\Krause"),
+ /* 1 */ dkT("C:\\\\Program Files\\\\Krause\\\\etc"),
+ /* 2 */ dkT("C:\\\\Program Files\\\\Krause\\\\share"),
+ /* 3 */ dkT("C:\\\\Program Files\\\\Krause\\\\var"),
+ /* 4 */ dkT("C:\\\\Program Files\\\\Krause\\\\bin"),
+ /* 5 */ dkT("C:\\\\Program Files\\\\Krause\\\\sbin"),
+ /* 6 */ dkT("C:\\\\Program Files\\\\Krause\\\\lib"),
+ /* 7 */ dkT("C:\\\\Program Files\\\\Krause\\\\include"),
+ /* 8 */ dkT("C:\\\\Program Files\\\\Krause\\\\man"),
+ /* 9 */ dkT("C:\\\\Program Files\\\\Krause"),
+ /* 10 */ dkT("C:\\\\Program Files\\\\Krause\\\\libexec"),
+#else
+ /* 0 */ dkT("$prefix"),
+ /* 1 */ dkT("$sysconfdir"),
+ /* 2 */ dkT("$datarootdir"),
+ /* 3 */ dkT("$localstatedir"),
+ /* 4 */ dkT("$bindir"),
+ /* 5 */ dkT("$sbindir"),
+ /* 6 */ dkT("$libdir"),
+ /* 7 */ dkT("$includedir"),
+ /* 8 */ dkT("$mandir"),
+ /* 9 */ dkT("$exec_prefix"),
+ /* 10 */ dkT("$libexecdir"),
+#endif
+};
+
+
+
+const dkChar *
+dk4inst_get_directory(size_t i)
+{
+ const dkChar *back = NULL;
+ if(i <= 10) { back = dk4inst_directories[i]; }
+ return back;
+}
+
+
+
+/* vim: set ai sw=2 filetype=c : */
+
+EOF
+
+cat >dk4inst.h <<EOF
+#ifndef DK4INST_H_INCLUDED
+#define DK4INST_H_INCLUDED 1
+
+/** @file dk4inst.h Installation directories.
+
+ Obtain installation prefix, system configuration directory,
+ data directory, local state directory, binary directory,
+ root binary directory, library directory, include directory,
+ man page directory, executable files prefix and libexec
+ directory is configured during build process.
+
+ CRT on Windows: Not used.
+
+ Produced by configure, $CURRENT_TIMESTAMP.
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Retrieve one installation directory.
+ @param i Directory index:
+ 0 = prefix,
+ 1 = system configuration directory,
+ 2 = data directory,
+ 3 = local state directory,
+ 4 = binary directory,
+ 5 = root binary directory,
+ 6 = library directory,
+ 7 = include directory,
+ 8 = man page directory,
+ 9 = executable files prefix,
+ 10 = libexec directory.
+ @return Pointer to directory name on success, NULL on error.
+*/
+const dkChar *
+dk4inst_get_directory(size_t i);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @defgroup instdirs Installation directories. */
+/**@{*/
+#ifdef _WIN32
+
+/** Installation prefix, typlically /usr or /usr/local.
+*/
+#define DK4_INST_DIR_PREFIX "C:\\\\Program Files\\\\Krause"
+
+/** System configuration directory, typically /etc or /usr/local/etc.
+*/
+#define DK4_INST_DIR_ETC "C:\\\\Program Files\\\\Krause\\\\etc"
+
+/** Data directory, typically /usr/share or /usr/local/share.
+*/
+#define DK4_INST_DIR_SHARE "C:\\\\Program Files\\\\Krause\\\\share"
+
+/** Local state directory, typically /var or /usr/local/var.
+*/
+#define DK4_INST_DIR_VAR "C:\\\\Program Files\\\\Krause\\\\var"
+
+/** Binaries directory, typically /usr/bin or /usr/local/bin.
+*/
+#define DK4_INST_DIR_BIN "C:\\\\Program Files\\\\Krause\\\\bin"
+
+/** System binaries directory, typically /usr/sbin or /usr/local/sbin.
+*/
+#define DK4_INST_DIR_SBIN "C:\\\\Program Files\\\\Krause\\\\sbin"
+
+/** Libraries directory, typically /usr/lib or /usr/local/lib.
+*/
+#define DK4_INST_DIR_LIB "C:\\\\Program Files\\\\Krause\\\\lib"
+
+/** Include files directory, typically /usr/include or /usr/local/include.
+*/
+#define DK4_INST_DIR_INCLUDE "C:\\\\Program Files\\\\Krause\\\\include"
+
+/** Man pages directory, typically /usr/share/man or /usr/local/share/man.
+*/
+#define DK4_INST_DIR_MAN "C:\\\\Program Files\\\\Krause\\\\man"
+
+/** Prefix directory for executables.
+*/
+#define DK4_INST_DIR_EXECPRE "C:\\\\Program Files\\\\Krause"
+
+/** Libexec directory, typically /usr/libexec or /usr/local/libexec.
+*/
+#define DK4_INST_DIR_LIBEXEC "C:\\\\Program Files\\\\Krause\\\\libexec"
+
+#else
+
+/** Installation prefix, typlically /usr or /usr/local.
+*/
+#define DK4_INST_DIR_PREFIX "$prefix"
+
+/** System configuration directory, typically /etc or /usr/local/etc.
+*/
+#define DK4_INST_DIR_ETC "$sysconfdir"
+
+/** Data directory, typically /usr/share or /usr/local/share.
+*/
+#define DK4_INST_DIR_SHARE "$datarootdir"
+
+/** Local state directory, typically /var or /usr/local/var.
+*/
+#define DK4_INST_DIR_VAR "$localstatedir"
+
+/** Binaries directory, typically /usr/bin or /usr/local/bin.
+*/
+#define DK4_INST_DIR_BIN "$bindir"
+
+/** System binaries directory, typically /usr/sbin or /usr/local/sbin.
+*/
+#define DK4_INST_DIR_SBIN "$sbindir"
+
+/** Libraries directory, typically /usr/lib or /usr/local/lib.
+*/
+#define DK4_INST_DIR_LIB "$libdir"
+
+/** Include files directory, typically /usr/include or /usr/local/include.
+*/
+#define DK4_INST_DIR_INCLUDE "$includedir"
+
+/** Man pages directory, typically /usr/share/man or /usr/local/share/man.
+*/
+#define DK4_INST_DIR_MAN "$mandir"
+
+/** Prefix directory for executables.
+*/
+#define DK4_INST_DIR_EXECPRE "$exec_prefix"
+
+/** Libexec directory, typically /usr/libexec or /usr/local/libexec.
+*/
+#define DK4_INST_DIR_LIBEXEC "$libexecdir"
+
+#endif
+/**@}*/
+
+#endif
+
+/* vim: set ai sw=2 filetype=c : */
+
+EOF
+
diff --git a/support/dktools/sep.txt b/support/dktools/sep.txt
new file mode 100644
index 0000000000..dffc0e31ab
--- /dev/null
+++ b/support/dktools/sep.txt
@@ -0,0 +1,2 @@
+ \
+
diff --git a/support/dktools/set-options.xpm b/support/dktools/set-options.xpm
new file mode 100644
index 0000000000..14999016f1
--- /dev/null
+++ b/support/dktools/set-options.xpm
@@ -0,0 +1,38 @@
+/* XPM */
+static const char *xpm_set_options[] = {
+/* width height ncolors chars_per_pixel */
+"16 15 16 1",
+/* colors */
+" c #AFAFAF",
+". c #549954",
+"X c #289728",
+"o c #F3F4F3",
+"O c #109110",
+"+ c #D0EAD0",
+"@ c #BDE2BD",
+"# c #9CBA9C",
+"$ c #7D807D",
+"% c #5E6E5E",
+"& c #FFFFFF",
+"* c #BFBFBF",
+"= c #BBBDBB",
+"- c #B7B7B7",
+"; c #B3B9B3",
+": c None",
+/* pixels */
+"::::::::::::::::",
+"::::::::::::::::",
+":::::::::::::X::",
+":::::::::::::X::",
+"::::%$$$$$$%O:::",
+"::::$******.X:::",
+"::::$*****;O::::",
+":::O$*****.X::::",
+":::.O;***#O$::::",
+"::::XX***..$::::",
+"::::$X.*#O=$::::",
+"::::%$O.O.$%::::",
+":::::::OX:::::::",
+"::::::::::::::::",
+"::::::::::::::::"
+};
diff --git a/support/dktools/sf-readme/readme.md b/support/dktools/sf-readme/readme.md
new file mode 100644
index 0000000000..ea87677976
--- /dev/null
+++ b/support/dktools/sf-readme/readme.md
@@ -0,0 +1,79 @@
+src
+===
+
+Source code:
+
+ * **dktools-x.y.z.tar.gz**
+ DK tools and libraries source code.
+ * **dktools-doc-x.y.z.tar.gz**
+ User documentation.
+ * **dktools-devdoc-x.y.z.tar.gz**
+ Developer documentation (API reference generated by doxygen).
+
+windows
+=======
+
+Executable setup files for Windows:
+
+* **dktools-win64-x.y.z.exe**
+ Default, recommended for recent computers.
+* **dktools-win32-x.y.z.exe**
+ 32 bit installation for Windows 7 and above.
+* **dktools-win32-legacy-x.y.z.exe**
+ 32 bit installation for Windows XP and below.
+
+debian
+======
+
+Binary packages for Debian Jessie 64 bit systems.
+
+User installation
+-----------------
+
+* **dktools-lib-data_x.y.z-1_all.deb**
+ Data files for DK libraries (required).
+* **dktools-data_x.y.z-1_all.deb**
+ Data files for DK tools (required).
+* **dktools-lib-4.4_x.y.z-1_amd64.deb**
+ DK libraries (required).
+* **dktools_x.y.z-1_amd64.deb**
+ DK tools (required).
+* **dktools-doc_x.y.z-1_all.deb**
+ User documentation (optional).
+
+Developer installation (requires user installation)
+---------------------------------------------------
+
+* **dktools-lib-4.4-dev_x.y.z-1_amd64.deb**
+ DK libraries developer support (required).
+* **dktools-devdoc_x.y.z-1_all.deb**
+ Dk libraries API reference generated by doxygen (optional).
+
+sl6x
+====
+
+User installation
+-----------------
+
+* **dktools-x.y.z-1.el6.x86_64.rpm**
+ DK tools and libraries (required).
+* **dktools-doc-x.y.z-1.el6.x86_64.rpm**
+ User documentation for DK tools and libraries (optional).
+* **dktools-debuginfo-x.y.z-1.el6.x86_64.rpm**
+ Debug information (optional).
+
+Developer installation (requires user installation)
+---------------------------------------------------
+
+* **dktools-devel-x.y.z-1.el6.x86_64.rpm**
+ DK libraries developer support (required).
+* **dktools-devdoc-x.y.z-1.el6.x86_64.rpm**
+ API reference generated by doxygen (optional).
+
+Rescue systems
+--------------
+
+* **dktools-rescue-x.y.z-1.el6.x86_64.rpm**
+ Package for DK tools installation on rescue live systems, stripped
+ down to those programs useful on a rescue system.
+
diff --git a/support/dktools/sl6-build-rpm.sh b/support/dktools/sl6-build-rpm.sh
new file mode 100755
index 0000000000..36dc0edffd
--- /dev/null
+++ b/support/dktools/sl6-build-rpm.sh
@@ -0,0 +1,76 @@
+#! /bin/sh
+
+VERSION=`cat version.txt`
+
+# Check whether this script is run as unprivileged user
+if [ "X$LOGNAME" = "Xroot" ]
+then
+ echo 'ERROR: This script must not be run as root!'
+ exit 1
+fi
+
+# Check whether HOME environment variable is set
+if [ "X$HOME" = "X" ]
+then
+ echo 'ERROR: Environment variable HOME not set!'
+ exit 1
+fi
+
+# Check whether the version number was obtained
+if [ "X$VERSION" = "X" ]
+then
+ echo 'ERROR: Failed to find version number!'
+ echo 'Make sure to call this script in the correct directory!'
+ exit 1
+fi
+
+# Create HOME/rpmbuild directory if not yet present
+if [ ! -d ${HOME}/rpmbuild ]
+then
+ mkdir -p ${HOME}/rpmbuild
+ chmod 755 ${HOME}/rpmbuild
+fi
+
+# Create subdirectories of HOME/rpmbuild if not yet present
+for i in BUILD BUILDROOT RPMS SOURCES SPECS SRPMS
+do
+ if [ ! -d ${HOME}/rpmbuild/${i} ]
+ then
+ mkdir -p ${HOME}/rpmbuild/${i}
+ chmod 755 ${HOME}/rpmbuild/${i}
+ fi
+done
+
+# Copy source tarball to HOME/rpmbuild/SOURCES
+if [ -f ../dktools-${VERSION}.tar.gz ]
+then
+ cp ../dktools-${VERSION}.tar.gz ${HOME}/rpmbuild/SOURCES
+else
+ echo 'ERROR: File' ../dktools-${VERSION}.ta.gz 'not found!'
+ exit 1
+fi
+
+# Copy *.spec file to HOME/rpmbuild/SPECS
+if [ -f dktools-el6.spec ]
+then
+ cp dktools-el6.spec ${HOME}/rpmbuild/SPECS/dktools-el6.spec
+ chmod 644 ${HOME}/rpmbuild/SPECS/dktools-el6.spec
+else
+ echo 'ERROR: File dktools-el6.spec not found!'
+ exit 1
+fi
+
+# Build RPM file
+cd ${HOME}/rpmbuild/SPECS
+rpmbuild -ba dktools-el6.spec 2>&1 | tee errors
+
+# Some final notes
+echo ''
+ls ${HOME}/rpmbuild/RPMS/*/dktools-*${VERSION}*.rpm
+echo ''
+echo 'If the previous command succeeded, you find your *.rpm files'
+echo "in a subdirectory of the the ${HOME}/rpmbuild/RPMS directory."
+echo 'If the rpmbuild command showed errors, make sure to run the'
+echo 'sl6-prepare.sh script as root before running this one.'
+echo ''
+
diff --git a/support/dktools/sl6-prepare.sh b/support/dktools/sl6-prepare.sh
new file mode 100755
index 0000000000..f74f79fbaf
--- /dev/null
+++ b/support/dktools/sl6-prepare.sh
@@ -0,0 +1,28 @@
+#! /bin/sh
+
+# Check whether the script runs as root
+if [ "X$LOGNAME" != "Xroot" ]
+then
+ echo 'ERROR: This script must be run as root!'
+ exit 1
+fi
+
+# Install the yum-builddep tool
+yum -y install yum-utils
+
+
+# Installing everything necessary to build a kernel should install
+# all developer tools required for us.
+yum-builddep kernel
+
+# Explicit dependencies to build our project and to create RPM files
+P="zlib-devel bzip2-devel openssl-devel db4-devel db4-cxx mysql-devel"
+P="$P libpng-devel libjpeg-turbo-devel openjpeg-devel libtiff-devel"
+P="$P net-snmp-devel wxGTK-devel"
+P="$P gcc g++ make rpm rpm-build rpm-devel rpmdevtools rpmlint"
+yum -y install $P
+
+echo ''
+echo 'Remember to switch back to an unprivileged user to build the RPM.'
+echo ''
+
diff --git a/support/dktools/sl7-build-rpm.sh b/support/dktools/sl7-build-rpm.sh
new file mode 100755
index 0000000000..14b418e1a5
--- /dev/null
+++ b/support/dktools/sl7-build-rpm.sh
@@ -0,0 +1,76 @@
+#! /bin/sh
+
+VERSION=`cat version.txt`
+
+# Check whether this script is run as unprivileged user
+if [ "X$LOGNAME" = "Xroot" ]
+then
+ echo 'ERROR: This script must not be run as root!'
+ exit 1
+fi
+
+# Check whether HOME environment variable is set
+if [ "X$HOME" = "X" ]
+then
+ echo 'ERROR: Environment variable HOME not set!'
+ exit 1
+fi
+
+# Check whether the version number was obtained
+if [ "X$VERSION" = "X" ]
+then
+ echo 'ERROR: Failed to find version number!'
+ echo 'Make sure to call this script in the correct directory!'
+ exit 1
+fi
+
+# Create HOME/rpmbuild directory if not yet present
+if [ ! -d ${HOME}/rpmbuild ]
+then
+ mkdir -p ${HOME}/rpmbuild
+ chmod 755 ${HOME}/rpmbuild
+fi
+
+# Create subdirectories of HOME/rpmbuild if not yet present
+for i in BUILD BUILDROOT RPMS SOURCES SPECS SRPMS
+do
+ if [ ! -d ${HOME}/rpmbuild/${i} ]
+ then
+ mkdir -p ${HOME}/rpmbuild/${i}
+ chmod 755 ${HOME}/rpmbuild/${i}
+ fi
+done
+
+# Copy source tarball to HOME/rpmbuild/SOURCES
+if [ -f ../dktools-${VERSION}.tar.gz ]
+then
+ cp ../dktools-${VERSION}.tar.gz ${HOME}/rpmbuild/SOURCES
+else
+ echo 'ERROR: File' ../dktools-${VERSION}.ta.gz 'not found!'
+ exit 1
+fi
+
+# Copy *.spec file to HOME/rpmbuild/SPECS
+if [ -f dktools-el7.spec ]
+then
+ cp dktools-el7.spec ${HOME}/rpmbuild/SPECS/dktools-el7.spec
+ chmod 644 ${HOME}/rpmbuild/SPECS/dktools-el7.spec
+else
+ echo 'ERROR: File dktools-el7.spec not found!'
+ exit 1
+fi
+
+# Build RPM file
+cd ${HOME}/rpmbuild/SPECS
+rpmbuild -ba dktools-el7.spec 2>&1 | tee errors
+
+# Some final notes
+echo ''
+ls ${HOME}/rpmbuild/RPMS/*/dktools-*${VERSION}*.rpm
+echo ''
+echo 'If the previous command succeeded, you find your *.rpm files'
+echo "in a subdirectory of the the ${HOME}/rpmbuild/RPMS directory."
+echo 'If the rpmbuild command showed errors, make sure to run the'
+echo 'sl6-prepare.sh script as root before running this one.'
+echo ''
+
diff --git a/support/dktools/splash-dktoolian.eps b/support/dktools/splash-dktoolian.eps
new file mode 100644
index 0000000000..c4939e793e
--- /dev/null
+++ b/support/dktools/splash-dktoolian.eps
@@ -0,0 +1,945 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%BoundingBox: 0 0 640 480
+%%LanguageLevel: 2
+{
+gsave
+640 480 scale
+13 dict begin
+/DeviceRGB setcolorspace
+/fa currentfile /ASCII85Decode filter def
+/fb fa /RunLengthDecode filter def
+/sr 640 string def
+/sg 640 string def
+/sb 640 string def
+<<
+/ImageType 1
+/Width 640
+/Height 480
+/ImageMatrix [640 0 0 -480 0 480]
+/BitsPerComponent 8
+/MultipleDataSources true
+/DataSource [
+{ fb sr readstring pop }
+{ fb sg readstring pop }
+{ fb sb readstring pop }
+]
+/Decode [0 1 0 1 0 1]
+/Interpolate true
+>>
+image
+fb closefile
+fa flushfile fa closefile
+end
+grestore
+} exec
+Jsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4Y
+Jsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4Y
+Jsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4Y
+Jsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4Y
+Jsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4Y
+Jsh4YJsh4YJsh4YJsh4YJsh4YJskPbJnBUHJnBUHO_4!KJnBUHJnBUHO_4!KJnBUHJnBUH
+O_4!KJnBUHJnBUHO_4!KJnBUHJnBUHO_4!KJnBUHJnBUHO_4!KJnBUHJnBUHO_4!KJnBUH
+JnBUHO_4!KJnBUHJnBUHO_4!KJnBUHJnBUHO_4!KJnBUHJnBUHO_4!KJnBUHJnBUHO_4!K
+JnBUHJnBUHO_4!KJnBUHJnBUHO_4!KJnBUHJnBUHO_4!KJnBUHJnBUHO_4!KJnBUHJnBUH
+O_4!KJnBUHJnBUHO_4!KJnBUHJnBUHO_4!KJnBUHJnBUHO_4!KJnBUHJnBUHO_4!KJnBUH
+JnBUHO_4!KJnBUHJnBUHO_4!KJnBUHJnBUHO_4!KJnBUHJnBUHO_4!KJnBUHJnBUHO_4!K
+JnBUHJnBUHO_4!KJnBUHJnBUHO_4!KJnBUHJnBUHO_4!KJnBUHJnBUHO_4!KpL]"4Jhhp5
+Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\
+pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5
+Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\
+pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5
+Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\
+pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5
+Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\
+pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5
+Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&^&S3E<L!7Y!W`o7JcL`0pG2JTm@!]\pG.=#JcNLb!XhJEpAb1'
+JcL]/pG2JTm@!]\pG.=#JcLB&JcN=]pG2JTm@!]\pG.=#^&SNR*Z,M&%LEFL%MBER(]tg#
+%Kl;&$k=<q&eYQY$P!dd(`rJQ#8e9j$P!dd%`JDQ%Ob>/_#"*-q#CP*kPs^:JcLc1pG2JT
+m@!]\pG.=#^&SNN)&!Ji$O6nC$P![G'*B*i$Nfo"$k!pd%LrdM#n%4V',gTG#87a\#n%4V
+$cN)N$R%uVU!_H=q#COo_:HFcJcLc1pG2JTm@!]\pG.=#JcLB&JcN=]pG2JTm@!]\pG.=#
+^&S.tn,EOebGB(tp](;3pAY-hq#CEXqu6Y6`W,uHqYpQlq>^LDrVlop*eFBP!;A8CB'l#\
+B(n'4!58F5HgfMgdAi(/)>F13>kZ_KdJ3bB_>Dd`>fHaD$2W3QdJ<hC+oTsmd2@N9NWAf/
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcNLb"$(7`qYU9pqWI&<p\t8j3Vi^X3JjTq
+qu6`5P]$<t!>>8.rr_GlM(&0"!<it[!!<IQM89)i!;cNl!,h`7!+:BYNWAf/pL`f\pLa.T
+JcNLb"#!o+dJMJsdD<ZHpXTA&0DYYN062rdqpkhBHX-CI!=mNVecWaTEZt5Y!<`eW!!<C;
+EhWH_!7CWC!*oHQ!)S7INWAf/pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcNC_!,h`7
+!,h`8"9fiHK'3%2!r?d8q#CCdr;Qf5!Vl]r"1A..!J1XQ!!='bkI&P7!"Su-!;cNl!+>a)
+!*+UNNWAf/pL`f\pLa.TJcNC_!*oHQ!*oI&"9]T3D8H,#!RY0I!!#1[ec;E=!!*.frmh*e
+#P\9$'5,.Jbl@_OrRLtrq>^Llr71j;JcLf2pG2JTm@!]\pG.=#JcLB&JcN=]pG2JTm@!]\
+pG.=#])Vgtr;Qb7q#CHt6Hf9+!.t"H!#YY6!0m9Z"Takfs8#=^!!PBZqZ$S[bl@bFqYpKp
+qYC0m''K8o!Tsc@!0.'R1A>DJRJ1=f14fM<!!"tUec8tN!!30[Wr(?ID>=/3'E$D]Hh[RD
+He-cq4no!\08e0.epGU@!7Ces!7CWC!=lsFecESlJcLf2pG2JTm@!]\pG.=#JcLB&JcN=]
+pG2JTm@!]\pG.=#])Vgtr;Qb7pAb4!Pl(I\8brDe')_b0Pkb:^M?!VP6MCH[V>^DoDTi(\
+kPkJ]qY:*o+f3AH(kMaI!;A8CB'l#\B(n'4!4r422uM5,>k\4!"ag-t!'U/Y!"SqX!.4MA
+"EN)Ed5Ue"!/ga+!*m_J!5\Zc!7CTB"<35uHP:u2N<&].pL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcNC_!'0uW!,hK1!<KV+rrM9dqZ$U/r;QbRq>^Y9s8V7Bp&G)WrVlk*bQ%Y+
+rr2upJcLB&!<<,o1A>DJRJ1=f14fM<!!"\Mec8tJ!!&A`ecESiqZ$U+r71jgq>^Y'f%.Yj
+p&G)>rRLsFbQ%XZrmh(sJcLB&!<<,o1A>DJRJ1=f14fLX!.k3&!4`+(1A>DJRJ1=f14fM<
+!!#%Wrr?s0!!*`/r;QasqZ$U/r;QbRqZ$b:s8V71o`+uKrVljtbQ%Y+rr2upJcLB&!<<,o
+1A>DJRJ1=f14fM<!!"\Mec8tJ!!*SWr71j;qZ$U+r71jgqZ$b(f%.Y\o`+u4rRLs<bQ%XZ
+rmh(sJcLB&!<<,o1A>DJRJ1=f14fLX!.k3&!4`+(1A>DJRJ1=f14fM<!!#%Wrr?s/!!&8]
+rrAnm!!!Z0rr@oR!!IZKs5tHq!!%WLrr>X7!!)3]rrDnI!.k1O!!)aKpL`f\pLa.TJcNC_
+!&+9$!*o-r!.4Xp!/gXR!"SqX!-7u;"D?<:_&;kF!,_\c!'SO+!5\Zc!7?AuJcGfO!;A8C
+B'l#\B(n'4!.k3&!.k3]!;A8CB'l#\B(n'4!4r423W/mWDY*o/3W/mXk5kJ\!##50!/^[T
+"Ta5Ts2u8N!!%WLrr>Xa!!rZSDPabV[?P&9o`,:!-uPlh^pTD7)#""1kPkJ]qY'sl(gs0F
+pAbF!6@u&LP\qoD!"8ohJo1Pg"')25V/A;F!4Mt&1A>DJRJ1=f14fM<!!"\Mec8tI!!"\M
+ec<P`!!!N,ec9ah!!I/ieuBDT!!$m7ec7l+!!j`QMO1$'HVbCJ!!j`QMO1$'HVbCM!!'k7
+ec=+l!!<m2M?W\R"ugCVTmL#fpAbU&05Xqo!!5WITo*).JcN7[pG2JTm@!]\pG.=#JcLB&
+JcN=]pG2JTm@!]\pG.=#])Vgkr;Qb7oDemuqY^?n*rH!<')_b8M#[MVM?!Uk%e9T"K)P]P
+<?WbN3VrdW6GWEs!rA,op](=]_"n!3qNMWg!!)3]rrDon!!Ep$DPbPUrr<H&!!340bPM5>
+PRdZm$NVD;@&<&ds.o]4_#+-4V%/(W\H)@ZpL`f\pLa.TJcNC_!&+9$!*o-r!=.$Mec6Tc
+!!!N,ec9ai!!I>netEKB!!$m7ec\G]+YPMG!!,$Pq:5VpHOffN!B6_JecO6G%f$))_>`!c
+dJNtI%Q@XMWrCQL$2FQ&!DofmecC+*r;[0D2c,CJf%,]Y';><S!K%8:!4`+(1A>DJRJ1=f
+14fLX!.k3&!4`+(1A>DJRJ1=f14fM<!!#%Wrr?s.!!(4?rr>(W!!!Z0rs+A\!L3Wa[0cF)
+!X3rIq>UH1r;Zj!K)YcQqKkOhM>dGTk:$3-!<IfOrri1F690o$rrM:2q>^NYrr2upqu?_n
+qYpO'q>^OE_"[j3^]=E8$i9l)V)d`7rrAmI!4`+(1A>DJRJ1=f14fM<!!"\Mec8tH!!'%s
+ec7B$!!!N,ed$3q!.3;JQO!*^!X*/`q:5P>qu?_6rmh5"B/_JarRM"c+o20=D>r)hd:YBk
+ErFPi_'/XT!5\Zc!7C]E!/gX(!"&K%!?n02ec;EC!!!?%ecL^^_>2X^MLki=!;A8CB'l#\
+B(n'4!.k3&!.k3]!;A8CB'l#\B(n'4!4r423W/mWDY!i._#4348c/Pg')_b2M#rq@rrJ>b
+oDen%bP2#:V>UAoDZ0S83W/pX@/^*+b7=FM!,hc8!'0uX!+>d*!QtuM!!)3]rrDon!!5K)
+V>U>n$i0i-M>uaq?uDh<rru$p!!R7ebPhGEkPG%j^utUp!%<F!\cDI[pL`f\pLa.TJcNC_
+!&+9$!*o*q!29>A!'U5[!"SqX!ce<grmh'ro)Je!WqY'EMZ!MT>lE4R0DtkN;#SrGWXJ_)
+!*oKR!&+9N!)WXF!NHP)!!'k7ec=+q!!5)aMYu$*$2OW+En8'I:gAnTecn8;!!HP>Wr:KP
+_9pZ(Tu$WW!$Qpo\cDI[pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcNC_!'0uW!,hB.
+!4Db)!(m(g!##50!L/iHrr?s/!!<^K@(#t5!.t2A!%@gH!?q==rrBk4!!*,DrVlkLr;ZjA
+qYpKp_#+05!R(HA!.t(J!9a@]!;cNl!<N&qrr<H'!!8#W8c8Vh6N$i`V>L;n@/U$.[28lD
+"+0tG!+:BY\cDI[pL`f\pLa.TJcNC_!&+9$!*o*q!13W7!'U5[!"SqX!IK1kec8tI!!<U6
+:m_.3!,_]u!$V=A!?9Gcec;E@!!'%tec9Rc!!+%drmh(CqZ$VrrRLscqZ$W4rmh(sq#CEB
+rRLrTq>^S;eiis3!&si,!/g[S!)WUE"d]l&!!6g2ec8Nu!4i1)1A>DJRJ1=f14fLX!.k3&
+!4`+(1A>DJRJ1=f14fM<!!#%Wrr?s.!!'G)rr=JF!!!Z0rrD6Yrr>X]!!&8^rr>Xe!!&8^
+rr?s6!!%lSrrM9frVuq_rVlk8qZ$VQrVlo]#Q+Q%kPkJ]qY:*kkPbD\$i0i)@))jA!!&ko
+rrBk4!!#UhrrM9hqu?`4rVlk8JcN@^pG2JTm@!]\pG.=#])Vgar71jQo)JcWr71ikqu?^,
+r71kaqUPX0nc/Z:rRLs3q>^MBrRLsRqZ$V:rRM"c"o\K%Hi;Lq>l+L$ErFPi_$0`:!5\Zc
+!7CTB!5\Wb!"&K%!`5Qkqu?_SrRLtBqu?^[rRM"c#Q+Q%U&EOB>_2se!;A8CB'l#\B(n'4
+!.k3&!.k3]!;A8CB'l#\B(n'4!4r423W/mWDY!i._#434)#O@6')_b1P^E<-!W"59!!&8^
+rr>Xf!!*,`rVljXqZ$UVr;Qm[!!!&_rVljXqZ$UVr;QaWqu?`[rr2upq#CE<rVlj*nc/Yi
+rVll5qu?^WrVll*qZ$V6rVlkSJcN@^pG2JTm@!]\pG.=#])Vgar71jQo)Jcar71i]qu?^,
+r71mqBD^6\d38)]!.4[q!'U/Y!5\Wb!&+3L!&+9$!&+<O!5\Wb!&+3L!&+9$!&+6M!5\Zc
+!7CTB!36"K!"&2r!(Qq<!29;j!&+<%!13Q_!*oKR!-3Yk\cDI[pL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcNC_!'0uW!,hB.!6b?@!TsR_!!!Z0rrS#WDYsG7k8<gk!0mH^!(m%f
+!%@dF!$V4>!"Sr,")\)=./a)F+o;6>%fH>,DYsJ7kPkJ]qY:*kbPhG@$h=8t./j/G_#+04
+3W8sXV>C5m8cAYhV1J]Y!;A8CB'l#\B(n'4!4r420DsB$>k7pqWr:KL_#jN7!"SqX!ce9G
+qpkea'D)8)Hi;Lq4o53Z+oKmk)uBU8$iJQX>Q=aIr71ieqZ$U(r71jQqu?`5rmh(sq#CDp
+rRLrTnc/Y5rRLtBqu?^MrRLt+qZ$UZrRLt+JcN@^pG2JTm@!]\pG.=#JcLB&JcN=]pG2JT
+m@!]\pG.=#])Vgkr;Qb7oDemqqYgEoV>C5m')_b3M#[R@qu6]?$2"8uPl:U^8c&Jf8c8Sg
+%f65+!W;s"M#[NIr;Qa,qZ$Tsr;QbRqu?`[rr2upq#CE<rVlj*p&G4%6>iX_rVll*qu?^W
+rVlkoqZ$UVrVlkoJcN@^pG2JTm@!]\pG.=#])Vgar71jQoDempdJ_VrMYdAR%fFl[EW?)d
+qpkeJ#PA&sHi;Lq4o53Z4oEk2$i0l$ecTpm!'U82!"8W'r71jgqu?`5rmh(sq#CDprRLrT
+p&G4#2dD6VrRLt8qu?^MrRLt+qZ$ULrRLt+JcN@^pG2JTm@!]\pG.=#JcLB&JcN=]pG2JT
+m@!]\pG.=#])Vgkr;Qb7oDekOr;Qb)qZ$U/r;QnV!!!,/qu6])!qlToPl:U^8c&Jf@/U$)
+$i0i'kPbD_PQ1\kr;Qa)q>^NYrVlk^qu?`[rr2upq#CE<rVlj*q#CL)DRK??rrD6\rrBJ)
+!!#%XrrAnm!!#%XrrAmI!4i1)1A>DJRJ1=f14fM<!!"\Mec8tI!!"\Mec8PD!!!N,ec^!n
+!!8MaecD*<p&G)>rRLs3qZ$Umr71iSq>^N3rRM't!!#jnec6$Q!!'k6ec:'p!!'k7ec=+n
+!!'%tec6$P!!<O4QdPf`!5\Wb!13T`!&+<%!/gXR!&+<%!/c@.\cDI[pL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcNC_!'0uW!,hE/!,hc8!Tsdd!!!Z0rr@oT!!*SQqu6YQp&G)W
+rVljhqZ$V(r;Qa<q>^NYrVltV!!$F)rr=,:!!)3\rr@oR!!)3]rrDok!!(4@rr<H(!!31/
+kPkJ`^gIurrVlkoqu?^WrVlkoqZ$UVrVlkoJcN@^pG2JTm@!]\pG.=#])Vgar71jQoDekr
+rRM"c#Q"K$%fFlXErH%>$`a*T!-7c5!.4[q!'U2Z!)WUE!#bV5!5\Wb"*+AA;#JlE)>X=5
+_>VpbEr5n;_>`!cdJ3bBWr:KK$2OW&:r3.^"//O)'E-J^MYmGS0E'H%MYdAR0E'H%MLki>
+!;A8CB'l#\B(n'4!.k3&!.k3]!;A8CB'l#\B(n'4!4r423W/mWDY3u1"m>ja!,hW5!##50
+!/^XS!?pY'rr?I$!!&8^rr>Xf!!$$srr>(U!!)3\rr[-=!*/ss!'0lU!9a=\!,h]7!9a@]
+!;cKk!6b?@!"8Z(!,hc8"B>I&!#Y\7!2]Sn!'1#X!2]Pm!'1#X!2Y8I\cDI[pL`f\pLa.T
+JcNC_!&+9$!*o0s!<g7;ec8tO!!!N,ec9ah!!+%TqpkaDpAb2?rRLs3qZ$Ucr71j$q>^N3
+rRM'U!!#Ldec7B"!!'k6ec8tQ!!'k7ec=+n!!'%tec6$R!!$:&ec82=!!!]2ec:U*!!"\N
+ec:U)!!"\Nec:SZ!4i1)1A>DJRJ1=f14fLX!.k3&!4`+(1A>DJRJ1=f14fM<!!#%Wrr?s0
+!!$F*rrL:Jq>^L.r;QbRqu?aXqY^?oqEjrW!0mH^!(m%f!'0uW!(-M^!;cZo"%`Im3W/mW
+6M^Z^qYgEo8c/PgkPkJ]qY:*kbPhG@$iBu*$i9l&!2]Vo!#Y\7!4D_)!'1#X!2]Pm!'1#X
+!2Y8I\cDI[pL`f\pLa.TJcNC_!&+9$!*o0s!)WXF!NH>"!!!N,ec9ag!!+b#r71nr2u!@Q
+Hi;Lq4o53Z0DsB$2u3LSdJ_Vu4TGI8r71j,q>^NCrRLs3qu?`5rmh(sq#CDprRLrTqu?a(
+dJh\sMZ!MT'E-J^Qi$g`0E'H%MYdAR0E'H%MLki>!;A8CB'l#\B(n'4!.k3&!.k3]!;A8C
+B'l#\B(n'4!4r423W/mWDY=&2./NrC!TtO"!!!Z0rr@oQ!!$F(rrM:2q#CDZrVljhqZ$X#
+qYgEoDYjD6"oSB'%KHJ4qYgEoDYjD6"oSB#%f?;,kPkJ]qY:*kbPhG@$iBu)3W8sXHi3pE
+)#aI7[JU")3W8sXV>C5m3W8sXV1J]Y!;A8CB'l#\B(n'4!4r420DsB$>kS-u+jp;?!PoZL
+!!!N,ec9af!!#jmecET1q#CDArRLs3qZ$X"dJ_Vr>l+L$"T6gR$NL/0dJ_Vr>l+L$"T6gN
+$iBu)_>`!cdJ3bBWr:KK$2ac'0E'H%BDhf1'E-J^Qi$g`0E'H%MYdAR0E'H%MLki>!;A8C
+B'l#\B(n'4!.k3&!.k3]!;A8CB'l#\B(n'4!4r423W/mWDYF,33TpDA!TuK<!!!l6rrA;[
+!!%lQrrM9qq>^M[rVljtq>^MlrVll@qZ$UVrVlkor;ZhorVll@qZ$UVrVlkoqZ$WZrr2up
+q#CE<rVlj*qu?_)rVlk^r;ZgarVll5qu?^WrVlkoqZ$UVrVlkoJcN@^pG2JTm@!]\pG.=#
+])Vgar71jQpAb4I_>`!d_(YQ`!#,:]!.4PB!-7tf!Po9B!!%BEec829!!%oTec;`I!!"\N
+ec:U+!!%oTec;`I!!"\Nec:U)!!'k7ec=+n!!'%tec6$S!!#joec:'q!!"tVec;EA!!"\N
+ec:U)!!"\Nec:SZ!4i1)1A>DJRJ1=f14fLX!.k3&!4`+(1A>DJRJ1=f14fM<!!#@`rr?s4
+!!43uqYpKqb9$BX!$;(<!0m<[!<]b,rrKnFqZ$V6rVm"s!WW3*rVupYr;Qa<qu?_RrVljX
+r;ZgXr;Qa<qu?_RrVljXqZ$WZrVlj(q>^N=rVlj=qu?^grVm&a+TN-mqYgEobPV>?6N-oa
+[JKq(3W8sX[=SCi!;A8CB'l#\B(n'4!4r422uM5,>kn@$)04.(ecDcgpAb12r71jpq>^Nt
+Qi#>7TaU_t!*oKR"H!3[!!W?%!&+9$!#b\7!-8%h!&+9N!&+9$!#b\7!-8%h!&+3L!5\Wb
+!!i?#!36"K!#b\7!'U;3"i2,X%U@E[ec;`J!!"tVec;'6!!"\Nec;%g!4i1)1A>DJRJ1=f
+14fLX!.k3&!4`+(1A>DJRJ1=f14fM<!!$F)rs4iL*Z-:c8V4bVrrW%R#PJ,t8c8Shb5qG>
+!=m<MrrL:aqu?^sr;QlBV80nF!!&8^rrKM4rVus9kPkJ]DYjD6Pl:U_[0Q[2!>t#!rr?s6
+!!*E&rVljGqZ$WukPbD\3W&jW./a)JqWInY_#=96k5kM]!*0!t!5SI3!'1#X!6]ro\cDI[
+pL`f\pLa.TJcNC_!)WUE#^\3B'-T"lD5$pZ!mu#lp&G(Ur71kJq#CF'Wr(?JWYt^7!(Qn;
+"0.6PU&=rkHi;LrQNd?g!>E<Kec8tP!!%BEecD*@rVus4_>`!c>l+L%#LWM$!$V4>!<L%8
+ec7B$!!"2?ecaC:f%-Pnec<Pa!!#Leec;E@!!"\Nec;_%!4i1)1A>DJRJ1=f14fLX!.k3&
+!4`+(1A>DJRJ1=f14fM=!!,FLnc&[ePSj,p"$)UBqYU9obERVU!!+/(qu6`oV)eMT!=n;i
+rrMsVr;Zj'V>^Dsb@!nnkPkJ^HNF!D!=,J"rrgMQ8V6.)rrIHIr;ZmjDRKEB#Jb4K!!#?'
+V>U>p^i!0O!!*,9qu6`oDE7Xp"f6)C?uG0*rrSF&./j2H3W/mYP\qn$!5/C,1A>DJRJ1=f
+14fM=!!,$pn^[chHP?,R"##"YdJMJrWdAU[!!*tRqpkhrMD+r/!=Qa@ecF/Or;Zj%MZ)*/
+W_biq_>`!cBDMT/"cE90"KG9]D8H5&!,)30!^0eTr72+H>Wi&e2dD7<ecMOM7f<;eU&3CB
+d9J@&ecgq9#>e[Ar71pr>Ts(H!&+9$!de/qJcNIapG2JTm@!]\pG.=#JcLB&JcN=]pG2JT
+m@!]\pG.=#]`8%!oD\sVbEPR)o`+u0pAY-hq>^OVqYL3lDZ'P9<VlXn!*/mr!Wc]lq>UK2
+3VWRU!FY*drrKnqqZ$W3q#:H>!!&kjrrD6\!!+M2rVlu_3<2DBrr<o1rr?s9!!#%Urr?GY
+!5/C,1A>DJRJ1=f14fM>!!"tLec`ghHT_W,!!$9tec=+o!!+b#qUPXOr;ZjfdJVPq7f!)c
+:r2tY!MM1@!!,p4q:5S?0Db_LU%m1@WW3$VpsoG]r;ZjA_>Vpe_(PdIqUPW[pXT=LrVupO
+qUPXCJcNIapG2JTm@!]\pG.=#JcLB&JcN=]pG2JTm@!]\pG.=#]`8NK*Z,M"#6P,9%MBU"
+(^'7-$k=<q&dnpG"UPYO(`rJQ#T+Bg#6P8F(_6HD"W2-AV3F"8!!ifrH^(A'P[GR)!!ifr
+H^(A'P[GR.!#HIh&e5-J#7_@`(]XOK(_R;`!XB)G(`</N)[To:V1K<[!!ODV#m1JH*WmH#
+&dnjF#n@dh%fQG6#8e'[!soSW$\AAl!;A8CB'l#\B(n'4!5/@B#8n0b$O$S7#7D"T)&!)@
+!"95Q'+P<P!<`W8%MK`U!!j5O$O$S:%MK6J!!O$@H]!/'p](R'2eRJpML//;oDf.#2eRJp
+ML//;q#D3E'+PBR!<ii@',(?G%MK<["T\c5%MKNR!#l/>H\uYM!!!->%L3%?%N,<c'+P<O
+!XB)H'+=d>#R(kO#6G,?'+'6j]`@d^pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T`W-#f$\A?[!(&]N!!*<Q`W-#A.&-bC
+![rX#l2^Q6pL`f\pLa.T`W-#_$%`-Y!&lR9!!*6H`W-#@+eo#<!?m$pl2^Q6pL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.Tl2UlP?srk3"CPV;3=#!Q"V,F7bPsTq!!30L!Rq)Z-uPls
+bKI;iDE.k#!$5PI<<,&S!!+KUr`'&.<@D8Q<<6JUqu?at@/a.,?mt^K"t9Lh!!"ETr)Ec*
+./*]B&e`@f"@@^JqS:2Q"=SVnkNA]B"<hZZkPtG[!Wa\MJcP?ApG2JTm@!]\pG2"6!]NqP
+qaL]b:e!)Amf3M!>^NL%0D#5E+k$E$+^BnuWiDDC>V?3[!#\W47K>+:!!+6>r^Hud7NkV+
+7KH=/qu?ae;#Wob:a,N4"sMQ&!!"0=r'g]`+nks;%M$Y^"?11ad@nY^"<hE8_82uK"<1U'
+_:JJ`!$QponGr;=pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.Tl2V>dK'316kKCZKbNJa%
+qR&Z[!!O!QPlLbDo`,&Xs/"<I('.FYqPA(08QBZ9qZ$CY!$Q6Vs8V7*q#C^LDRKN-M-q`L
+V>gJrV/@^Z!!ZhfkPqr-./!WGPkkji!%;`]rr3%rDCG8[""=$B.*MYo8T*_k^rZQZ3GuY4
+kGA4^-uQHms82iuPlIS3!:g-a1A>DJRJ1=f1?niM4`/$df"nA[Q`@mLf$TgCnGi_&>^P&Q
+0D,;HHe+)*!#7u'd>D0u4[r\CdFQ](!#o1#f%.YVq#C^E>aO$XE_moaMZ20.MHh>&!!Z8?
+_:FrX+nbm@HdN3$!$PU)rmh..>TrkB"!Q(>+j9oh4^>hSTud9;03k4%_5728+^CAbf),LL
+He+(+!:g-a1A>DJRJ1=f14fLX!.k3&!4`+(1A>DJRJ1=f1?\]?DZB`'qu?p/8YuIeV%3"q
+!sel+3V<@RbQ$bX!!F.Hs-+As!!=CPruq=@"R#gbb7"(F!Y56Wr;Zp#qZ#aQ!!7NI$hXK$
+)#BKo!!<#skOefW<WE)!aoDL"s1lYT!`f9`U]:H_s8Vus!mCW,ZiC.4<=-PCpG2JTm@!]\
+pG1q4"'jF.2uEX[#sF0seqsk*!!<DUeh?[r!ijhffDl$fQe$Ksq>^U:Qe!,S!!L-heuB&O
+!!3PZBD_`2dFQ/.!!6fa$2"9"'@D1(!!:R!_=[d17b6-[aoDK`etL+a!_1bWU]:HTf%0a!
+!ijhfZiC.27L-g2pG2JTm@!]\pG.=#JcLB&JcN=]pG2JTm@!]\pG1q4"%iOm6MUTa8c&J&
+#Oqcqs8P+P!!50F3S=B7(sDqspAb7-q>pNp"j?*/s.obl!!32t@/L!+kPr?l!!-L(oDer>
+ruq7>!mCVeo`,'tH[?"?!!7cP^rHEV8cRtL!!51\s82iu3KuP3!!>RNrtrWRpG2JTm@!]\
+pG1q4"$P5d2u*FV4jhiS"n;Qof%)MI!!4g#0A-=-'<9VgpAb4(dJNtIWkm9;MY@)Od89`@
+!l<H]pAb4jdI[D?B@\%!!!91OWq?>o"D;?NaoDK[etL+a!^5,NU]:HLf%0a!!\\mR[/^:f
+_:B:;!;A8CB'l#\B(n'4!.k3&!.k3]!;A8CB'l#\B(n(E!!>Rfs$HJ\"(;0/K(/gBs8P+&
+!!E><s.obi!!)3[!!U/U_#OFPp](?X<VugubQ#BP!!-*_o`,$ukI(-d!mCVZ\c;e`s1lYT
+!_NFTU]:HVs8T2$")e/="2b-51A>DJRJ1=f1?\]?2qHP=p](Cmf%+^.!!:a&0?O7rU"5+o
+!!'k5!!T'$U"7e"p](?27f35fWn*m<!!,R*o`,$s_3auu!ijhF\c;eKetL+a!^5,NU]:HL
+f%-r'"'jF.!lG$41A>DJRJ1=f14fLX!.k3&!4`+(1A>DJRJ1=f1?\]?6N@'Pp](EubQ%DO
+nc/aks#J7&"(;0/..mQ?3W&j]^hseJs8P[d!!27_qu?fAs1n@/!EJ=U!!6R.6M^Z`bQ#Ah
+!!7cP^rHEV8cRtL!!51\s/c8&@/oE,!;A8CB'l#\B(n(E!!>12ei3@("9GORd15^I!nPpU
+b5_W@f%)#;!!"\M!!]-%%`-`I4o#'Y_++>&!ijhFpAb4`_=[d0:t@T%!!91OTt14*D:YE$
+!!5=7_5%&40@n^V!!6!J_863H1A>DJRJ1=f14fLX!.k3&!4`+(1A>DJRJ1=f1?\]?6N@'P
+pAb;Is8QL)!!Ep+DF,!6!!rW)3<0(??r\BH!!+67qZ$d$3FH5]#Q"K,"[X@4#?>Y5)"dk1
+bQ#cR!!g;W!'0oUqC)1?!U!J\!!:@D_"Rg0<Tj&U!s-Tg!VuctbQ#BM!!3Bs)#XF?!@Tr.
+!CC[(./EoF"%"F5!!*p:rW!$*-rh\n!!<<`3=5K]$%i2m!!!X'DE/%"!!NEa?sl;+q>^[?
+8T%p&#Q"K)!BFOq-j'2E#7!h<<>%n'kO\`Y+\;Y63FF96!!ENnDH.kV!!OcNDH/(cq>^X.
+6>fd?r;Zm$67D^2!>ni5!!Ep+DF,!/!!51\s8)d/+\;Y6*[i0Q+XeB3!"p\'+Xe3*!!FHF
+?o\Pc!#?VIDI>d9!!"&g+W_dT(]XOW-m9`^)#aL=*_C6W63mGh!`f9`q#CO&6>fdHqZ$m(
+67;gA<GkeArW!'/<Gk,,joG-2pL`f\pLa.TkPt]Df%)eS!!@)hekl8E":dS"2\,`c#hIQ[
+!!"ZK7N;1(!?43!!!NBV:f'(SqZ$m)2]D`#7U/(io`,&neuJ-<#GGB&0@A@u+o20>_++>&
+!ijhFpAb4`_=[d/WiGjp!ijhFoDepr4VR_n#9b`#!&n.P+o20?!]M;"!!*a&rW!$(+\!XQ
+!!<9U0*h:Q$#S7e!!!Kl>V??Y!!NBV:f'(Sq>^[:4^:fB"o83%02PIg!Vl^#"[-*[%R&CZ
+oDf(74TGI8:a,c;"9g_h7N;1("<g6>7NqR-":I.n7MG_#!Wk;(qZ$X17f!)f%R"&U%eTf'
+0@n_O!"p56!!!l[)]9S<)#sXH+WD@D'Dqh5)b*XW#P8!3)*M5$2['0])'Kq:)^,jp!#Zq!
+)^,mo!!O6'>Ym?_r;Zmgf"q.^"9g_h7N;4)#Qcq.!!u,"7Krbk":7P&2[&7CpG2JTm@!]\
+pG.=#JcLB&JcN=]pG2JTm@!]\pG1q4"%*%f6MCH^8cSgTrW!36Pfno8bPH)XrW!*$s#DLC
+rVm.f$NL/uPfs*Br;Zm"@-@Lg$d0[n!!dkIkPnO1kPkJ^qJQ$-"!7LBPjSMW^hs,P<WE*B
+%f65,k>hE[!mCVZpAb4okOnlW6N:Hh!!:@D_"Rg=%XYVHs$?\c@&<&dPRb,"rs>M.!!!(<
+V<@kdrW!']Ped=^rW!):s8V7!r;ZqHqP>8/!!RuS^]JEMrr3#^6N$lc!FY*hrrL:dr;[*5
+V9=I;V>pB5r;['obGB*Qs1g&\!!*=BroXFaqTJp%pAbn!Pfs*B!gN`bV#UJsDTe8k_#KW/
+rW!0O^qb;K_#MUU!"Bd%qYL6lqLScdV<@kdrW!']Ped=^qu@!4Pfno8bPH)XpAb7Ts8W&u
+'hOY5s1eU7<P\Y7kG;/Y!(*OYs3"FA!!ap[^jD=/k=PCJ5RsX6JpX?oqAoWSkPtSYV+CXe
+<P\Y7^d8#2V9=I;V>pB5!!!Xrs6"9HM*_1B!cH2GHbfZG%KHQJV<@kd3TpDA"Qq053TpDA
+!QuYL!;A8CB'l#\B(n(E!!>12ei3='"$P5dHi=!N$[\moD5tug!WE'%f%)JtU&EOJHO0ZP
+4aX3[U&4lk:r3+]$`Y-G!!R"m_:D(!_>`!dd9QDG!u]\@HgUk>Tj.Qt7b6.j$i9o)_++>&
+!ijhFpAb4`_=dj12qCh$!!91OU%\Ns$YPgBei*R/:l<*?HOH2=ed73=!!!%)MS[k?rW!'S
+H_K$,rW!(pf%.YNr;Zq4d>Ah;!!R5jT`JEGrmh+d2uEXV:r3+]!NI+;!!isiWblC+f$PB6
+!!bZeMHl%iTcs=6!<la-_$&?:Wn,#\!#.SCWn*jEHe-c*!!!%)WdABPep@f(!!a[@TkA59
+euJWJ%23d0dFQmrD#mn!_:DH^!!Fs%U"7'X!!isZWcDsVd9H_H!!4h)f)>Xa4aX3[T`>'^
+U"7f2MFIRG2i?#6W^csf#9fG-B7%J24neqA$]:s$B8Y9f)$!pXf%/6+4TGIOU"7eg2ZO5C
+WblC+f$P?8!"OA,_-CVn2ZNgY>cN-`U"4Pu!!->^_:DF9_>`!g_'&e3_>`!dWZ1+$pG2JT
+m@!]\pG.=#JcLB&JcN=]pG2JTm@!]\pG1q4"%*%f6MCHj3WK,U!!"G1^^0u@%a4lirW!Q1
+s)."V<GoVPs0Vh,6=B!V_#46MM<?8g&n'o&V#UK#@"SFYM9Bcs<QkFB6MLN_8cSg;mJm:'
+DZ0V=M?!U`!rN$!k>hE[!mCVZpAb4okOnlW[H@ej!!:@D_"RgK%UbP$s$?\c8T+D)V8.pS
+6Da_^HN4$I@"SFY@/^-/3FL&1kPYAe.-LWR!rr<]qI'$t$\JDoPe_0:M>I8P3W9!aM<?8g
+&n'o&V>UAq[H@kq!!51W)#aL:M>BgC!!?X/k6q7h$9@:G&c_n[V>pSYpAc't@-@R*K)4[1
+PQ2$*k90g*!i>pn!!!YpV>UApDWgru%TW@^*W[F2qNM%hK)bjYrW!']@*AT5r;[-PkJ.B(
+!"R3PDYF,43WK-Y!!GVrkPr?s!!<Dfs1nL3!mA@[rW!7)qLS_J!%@^D./3cD[H@kq!!kU]
+(]XOWqZ!Dh!!h\p!<<,-k6_+f#W__u!(,l3s8)`X,!l89^ulj@!!9"sV#UR)K)bkIbAK=J
+qZ"`=kAE:fqZ">3kQ(?4pL`f\pLa.TkPt]Df%)eS!"Ua6eqsG-+i0iW!!!D,em/1S&_>N<
+_/`"MU"7e]!!"rS_:G=Y!#Tam+TW'L_:FJD!!Q29f%+lA>VARHf%)eT!!>C8en=CN!MNct
+!!I>nes?F8!!0o*qu?euetMg<!Cjp!!!8M'"o/-"Wn*m<!#uACHe-b,!!#/edFO2KE]5q7
+f%+I6!!,o5f%*[s!!FrOWn,#b!!sgbeuAcO!&)_rpAbS<etIGa>Xib]f%)MR!!mV]+TW'L
+_:FMB!!8M'#Q=])0@:I4!!72g4oPE`:tEGhrW!9Y_28^&!$R6Nf"q(\))kC.etHs._:Er5
+#GJsQ!!!%WeqsG-%`+&$!!-?@r;[<sd;g*))e[QF!DmXaekl>G"><TOf"q:b#pI-Y#64`3
+Wn(GL!!4h)f)>XP2c.?AU&G#o"MrZ_qZ$YsU&=rm7aZ)P!!=Clefjeg!gg_.rW!3Wd1ZK[
+):@#mqZ$Z5Qi6sdQb`q+!!k7*'*'u-_:I$5_'(`;#GJsQ!!!%WeqsG.:i4e7MQ0o7:smjo
+7_r=_:smjfk5b63pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TkPt]Os8PF[!!k"Qs.o]%
+bPrX^!"!'5q?m9's8V7*rW!')V>pQ^rW!"as1nR5!L.L#!!?7$q?R!""9ni*b7adS!t4;l
+V>(#m@/p7EmJm:'DZ0V="2Os:K)>TLk>hE[!mCVZpAb4okP"rX+ocoa!!:@D_"@[0)#sV&
+r;Zr8s8"bT!!<80s6'=\!s/8u@/L!+DZAnt!!cO(s)%fEkCWC-"G6[RHNO0H"$-5X_#=<7
+P]$F"#Z^p$#64`@s/#Vn#/CTH!+>hkr;[-+kPol/!%@]Z!W2p!DZAnm!"5%kqP=DuM0f6!
+s'Yd*#9j-I63($c@/U'+$-W;J!_NEKqu?tYHN4$HqYst$!!7'<kPbG`$-W>ir;Zq-s8!,u
+!!51\s82iuPlJPt!!@-=q@``,!XnibrW!$KqW@tZ!!9"s_"ds3)#pH1!!0kCrW!%bs5sL_
+!!aqP-ia5as/#Vn!Pf*B!!7'<bPV>AV>js%!"'nLs$?\c!W)iZ)#aL<@/p8i)#aL;@/p6M
+kQ(?4pL`f\pLa.TkPt]Df%)eS!!jb!eqsG4Wn&'d!!uKQd0TdQf%.YVrW!'(MUp?;rW!"H
+etN$B!IJ)M!!>^Ad09LL"9d<,WXf".!sufpMYI/R:tF3&mJm9]>lF^+!hn2rD>XA7_++>&
+!ijhFpAb4`_=mp2)qJZs!!91OU%JBf'@t_nr;Zqnf$Q/L!!8M<_>F97dFM.l!!6EV_>F9<
+7b6-q!"$JYp&G54f%+I7rW!$RdFP#j!!.FOr;[*mf$OX$!#*q@qu?qp#ljs%epI>q#Qhin
+B)hoTd@pF;!aO<mo`,AHf$T?Y!HMfQMUkW&!!aIoei*Ruekl;F!=,Y(!!5=7Er5n<EbG@O
+!n#Rqqu?e'f"q=c!sbjW)>sO;:tF##p](@Kf%0a!!diLlr;Zq)f$P!+!!3JS0E(qR+jn+-
+r;ZnVetMm>!Ya.Bqu?bk$2so,He-"7r;['Gefb"n'@r'=!!/c"rW!")euJWJ!fGQ*r;Zp=
+f%)eZ!!CX"_%ZeJ"Am\#_%ZeJ"&RS")s@:r1A>DJRJ1=f14fLX!.k3&!4`+(1A>DJRJ1=f
+1?\]?6N@'PpAbFYs8RoU@/nFJ!!jbJs#C&Zs8Q*s!!=)7s,$^T!djs_r;Zj.#Q4W)$31#H
+r;Zo^s'Ya)!f?s#p](D(s8R]=!!0lQr;Zs5kPtQ^r;Zl]<VugubQ#BP!!-*_pAb8Zq@`Q'
+!mCVZo`,'ps8PFa!!9"sV>L;q8cSesr;Zo^s'Ya)!au&kqZ$hss8"..V#g8i"+pQr!W2p&
+PlLai!!!K6r;[-1s8O,?!'1)B')_e7-isALkPnQ[!!fA#^]4AMs%3(f!_NFTo`,AHs8!?.
+!!*-Bs8N`0!!h]eD?,%`[0-@-"t0HO"m>muqu?at8cA\kkPnrf!!6R.kPbG_@/nFJ!!=DE
+s#KiS!]g;\qu?eFs1nR5!tP2-DZ'P9<P\P5!gN_Lqu?h,s7uio!!>7]k7[^n!@S$K!!=YL
+s%3.h!L0G[!!>7]k7[^n!@S$K!!7'<bP_DC*rl6Qqu?f]s).f9!pBT$r;Zp)s8R!8!!<K+
+s%2DSpG2JTm@!]\pG1q4"#nf^2tm:W0@n]p!)V7Hqu@!Af%)JS!7o^jqu?g4dFN@;!!6fa
+U&=rl$O-J/!sdE.)>sO:_:DH\!!72lWqZPr:tF37mJm9]>l=X*%`-`I7f<;f_++>&!ijhF
+pAb4`_=mp2HdN>u!!91OU%A<df%)eY!!8&/MYmGV4kA0hr;Zo8ekl8E!`7IaqZ$eWf$PXf
+MY-rND:Y`a!!dl%ecu0T$O-J/#m]&4)#sXif"hjp!!XSI!!'jd7f35kMUnI$!27t,qZ$[\
+f"q"Z")$34%fQG2!?'J>%f?;3_:DikB@`CNr;[$F!!!/<edhTX!Cf6O!!:!f;#C:p:tEJ^
+!!6!JWr)i!)qNRnp](@Kf%0a!!b^)Xr;Zp-dFMS$!!,Q_r;ZnGepI;p"&RRr!r;m!0@mrL
+r;ZjA!WE'$+kG4-r;ZkFMZ*SX0@mrLr;ZjA!WE'#>h5qR!!=+iedhTX!l<GmrW!#9em/.R
+!sR9,>l=X)"kM6fkQ(?4pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TkPt]Os8PF[!#8N6
+s&B&qs2uf-$O7.Ys8QI,!<<'ZqZ$]5s0_h+!djs_q>^^$-t%o.s#L#X!pBS`qu?e+s6'.W
+"%iOmV>1)k%f7XS$iU,,^i'&M"=X-HqC)=C!U!J\!!:@D_"Rg0<Tj,W!Y5'kpAb9<s1n7,
+!rr9er;Znqs-3E]"!R^E+oMBBkPnrf!!6R.kPG5_''K;X^^'N4!eUHfqZ$^bs8P+W!"T,Z
+@#=a[3<0$rqZ#`C<>bZ7&1ISY?lfpc#niL&k5ZA!ruV%;!_NFTo`,&?s3(<?'4Ck?-lrj'
+$PLY_V#X*es6"u#$iL&,8cRuI!!;?`@/L!+@/oEh!"5Y'b:"28#7_UNs'YU%!]g;\qu?eF
+s1nO4"-iiK!r`0#[7U;s$g7PS+W(Ll%TWQ/+o20C)#F9qPZ8Rs!!9t9V>^Gr%f.UQ!!X;:
+s6#VH)#F:7DZ@oY!"337s!Sou#7D0fs/#\p!pBSkqu?f]s'Ya)!pBS`kQ(?4pL`f\pLa.T
+kPt]Df%)eS!#7uSej]XseuBl,#mC\Mf%*Xt!7o^SqZ$\kesH@9!b^)Xq>^^#+]*4,eh?t%
+!l<GWqu?dpf"q+]"$P5dMYR5P$i;(I$2so*Tj7Kq"<l1Dd38Jh!Pq8'!!91OU%\Nf7`"j"
+!XmD&pAb8petM^9!nPp]r;ZnVepI;p!uohB)uTa<_:DH\!!6!J_>=39%`-`4T`t)h!c?M^
+qZ$^Wf%)MP!"T)R:iat70)ttcdFQ-\7MG_#&0]WU:`0`H#7c+3_#P/"ef">b!^5,No`,&+
+euJWJ'2[92+W1Xk#nEudM?#fjf"l2^$2ji*4k@IC!!:!f;#C:p:tEJ^!"4\8WZ`#^"Uc!p
+ekl,A!\`-Uqu?e2etN!A"+/V8!WE'"QTb9I$c1D@)\WG]$V&^u)u9O='@GCIHU\\F!!8kF
+MZ*SW$dg-s!!X+af"l]&'Dhb2>h5qR!"2WSefbn="UP[=er'G,!l<Gaqu?f7ekl8E!l<GW
+kQ(?4pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TkPt]Os8PF[!!ebgq?m;=s8)]W$-U,\
+PW8^Ds8P+V!!9"sV>^GrHiLnZ!!kT]kJ2[LkPmR@!!;?`<Vugu@/oEb!!=)<s6'1X#:QFa
+qZ$T=./j2I^i'#L#Z^p)k7Rapk>hE[!mCVZpAb5%bP2&=DZ;-Z!!:@D_"7U.s8PFa!!9"s
+Pl(L`*rl6`r;Zo^s'Ya)!au&kq>^Uas8QL!!!7cP_#"*6+ohQjrW!3aV<>XG<TjBBrVut,
+qYgEubAII`6N@)`k6T8=V0`2/s8NE&!!5alkOefVHiLnZ!!7cPs8D*cbJ:NM<<*)brVm-!
+^e"M+DZ@oR!!;?`@/L!+@/oEh!!9t9qYfR[bJ9s=3VWRU3WK-W!!7NI_#+0<.0'<=!!"(`
+!r`0%"onW!rT==,^nm8.q#CG'qYgEqbAIL^!!cO(q@Wc.@)2[?!FYd&rrUA]"o\K'DZ@oY
+!!7cPs8D*`bJ:NM<W2t"kPnrf!!;?`@/L!+kPnQG!;A8CB'l#\B(n(E!!>12ei3='#CG%L
+#lp[MdJ^lfWhG;s0)u"'eh?n#!fGQdrW!"4etN!A#VV(OTl!98eh?t%!l<GWqu?dpf"q+]
+!u'8:_>+'9+c;u@f%-iErVutm>l+L,7b6/,%KHLF7f35fWn*m<!!,orp](A#efjbf!ijhF
+oDesDei3O-!fGQUqu?g:f%(f=!!:!f;#C:p:tEJZ!!>12ekku=!c?M^qZ$^;f%)#D!!k68
+_4b^8_:C:=!!,pDrRM1Q>Qb$cf%0c8#ca5KB)jmAed)'P!^5,No`,&+etN!A!c?N>rP8`=
+TpL*q!!.HFed'Tr4TGIeeuJED!l<Gaqu?dpf"q=c!hn2mrP8W:To+1Mp](@Kf%0a!!b^)X
+qu@!Gf%)ta!#_d;rW!$'f%/7I_$$d3ML,j/!!,pDrRM%M>Qk!*#=d:l%KHK*U&4lk:so6m
+!ifK.rW!")euJZK!c?N>rP8W:TpL*qrW!#9ekl8E!l<Gaqu?f7ejej'pG2JTm@!]\pG.=#
+JcLB&JcN=]pG2JTm@!]\pG1q4"%*%f6MLNd"m>oM!!(4B_"Ia0s8P+V!!9"sK)P`OHiLn[
+!!A)X[2AlC!pBSDr;Zo^s&Jss!au&kpAb<=s8P+R!!>Rfs%3.h!PiUL!!e,Us1ed<k>hE[
+!l4iZpAb5@bP;,>"6[Jn!!:@D_"7U.s8PFa!!9"sPl(L`*rl6`r;Zo^s'Ya)!au&kq>^X>
+kPtB%o`,&Fs1nL3#q5iM$NL0`s0W^C!!;?`3W/p[(iHbXrr3.u!(m4j3VWRV8cSf=qZ$[t
+s6'%T!djs_qu?hUs7ufj!!4Qq_#=9:?iZ&`q>p<j!pBSkqu?e+s6'@]!mCVZmf3DLs8Vus
+!djs_qZ$i9s0Vh,M.$8^!sel+Hg^q:(iHbXrr2tpr;['+kPoE"!R"L?!!='U[JKn&!2]Yp
+!cJ%]r;ZqVs7ufj!!;?`@/L!+kPnrf!!;?`<TjGW1A>DJRJ1=f1?\]?2qHP=p](R&_:Er5
+!34VDp&G0Feh?n#!fGQGrW!"4etN$B"*2tZ'E.t5_:C:<!!:!f7f35f:tEJW!!B7Peh?at
+"#nf^4oG?]Tj7Eo#Ar&CT`bA37f35fU"67<!!-`4q#CHt_4gQ&!ijhFoDesDei3O-!fGQU
+qu?g:f%(f=!!:!f;#C:p:tEJZ!!F1Uf$PH0!!7#gU&+fr+kG$I!!%&jQP9>u!l<G@r;Zp5
+>aNk;ecgp24kA1;p](CZf%)#A!!5X@_=[d0B@`dS!!@8md/iq@![23MrRM*J!-6Z<p&G01
+ekl8E!`7IarW!#"etMO4!\`-Uqu?e2etMs@#,0V7!!%%9r;Zp'f%+L&!!<m>QdPf`!/g^T
+#6_lo>Q=c(7f*/f'3pmOrmh(,rW!")euJZK"*2u?!VQKp_:DH\!!:!f;#C:p_:D*>!;A8C
+B'l#\B(n'4!.k3&!.k3]!;A8CB'l#\B(n(E!!>Rfs$HJ\#]B\=(]XQ4s6'+V!s/H%3VrdX
+bPsU%!!7NI_#=<98cRr[r;Zo^s#L#X!pBS`qu?e+s6'+V"BGL%[/p%&""=3L8c8Vi^i&uK
+#6M=5s-*NH<VuguV>o`Q!!/p\q#CIrs%2na!mCVZq#CFU8cA\ks8PFa!!9"sPl(L`*rl6`
+r;Zo^s'Ya)!au&kqZ$g1bAP,qb6R_@!eUHfqZ$mns0Vh,8cRr[r;Zo^s#KoU#mXJRs8NQW
+s8Q*o!!>7]s&Jpr!au&ko`,&?s1nO4"(;0/)"R_6&oQn4b5cG[rttJ1!pBSkqu?e+s6'@]
+!i>q[mf3DLs8Vus!djs_qZ$gls8O,Jb6RqF!pBTJli71o<QkFB%fHA3HiN723TgM>!"&s2
+bQ%SP!!$p:bP_DC@/p6Dp&G0Ws'Ya)!pBSkqu?f]s&J7_pG2JTm@!]\pG1q4"#nf^2u!@Y
+>h7:9!!%o-_=dj1f%)MO!!91O0E(qQB@`dU!!>C8_$Bo=!l<G@r;Zo8ejfQ;!`7IapAb:b
+f%-2^!!=Cqeiis3!MNcp!!`Okf%,0J_++>&!fGRFpAb5OHhdXC7b0`r!!91OU%nZh00T:7
+!nPp]r;ZnVepI;p!u]\@)uTa<_:DH\!!6!J_>=3:$`[I*euAoI!!7#gU&+fq4k>r"!'SoL
+#Q4W(_:C:9!!rfuWn,`/+kG46p](CLf%*=f!!6!J_=[d0B@`dS!!?'Kee@WT#nC4VeuA^T
+f%(N/!!:!f;#C:p:tEJ^!!8&/_=%@*0@n_P!!6faU&+fo4kA1%$*"1,!!:!fHgC_9"\,NC
+edMEV#%uN'!\_@kp](X)7]P%j$NL03euJZK"&RS"'D;D-_:DH\!!:!f;#C:p_:D*>!;A8C
+B'l#\B(n'4!.k3&!.k3]!;A8CB'l#\B(n(E!!>Rfs$HM]"$-5X<W2t#HiO*op](C$s8P+W
+!!4SK[J^(,HiLn\!!8Db[J^(-#Nu+Ir;Zo^s&Jss!au&kpAb<u_#OFBp](CEs8P[h!!0lQ
+q#CU/kPtQik>hE["+pRQ3V`XV%f03$!!9sZ!qlTqbQ#BR!!.porW!$"s$HYa!i>p]qu?g?
+s8O8@!!:@DDYsJ9V>o`V!!`V6V#_Y6s-33W!f?rmqZ$kts#C&ZPlJ/i!!`bls#C&Z."_?s
+#7'Gl%L;k1[J0_($2X\;qZ$\os6'%T!djs_qu?gZs8R!3!!-)"qu?s^s2tC&s8RrM!!:@D
+DYsJ9V>o`X!!@TJs![@:!]g;\qu?eFs1nL3"U!rfJo5r4!!C%:k6LPX!@WQt!!<Jhrsnu-
+"W7+9<MaU2!!+L"qu@!-kPl"l!,hh[r;Zp[s8R!1!!;?`@/L!+kPnrf!!;?`<TjGW1A>DJ
+RJ1=f1?\]?2qHP=q#CLMdFLed!!?lbefjeg!sR9,0DkeO+kE"Y!!6faU&G#nHe+P^!!<D@
+eh?t%!l<GWqu?dpf"q(\"9P:Jekl,A"!Q7H4oG?]Tj7Bn"q/8uekj1Pqu?h9f%)MM!!3PU
+7em#cTrJ.e!!91OU%nZhEa8SD!nPp]r;ZnVepI;p!u]\@)uTa<Wn(GQ!!8&/_>F9<!gecE
+):@#^p&G/7etMs@#E%(c!!%AsQi-mh"i8bC!!"0Zqu?s*_:AttdFOZZ!!<JRetMs@!fGRF
+o`,&+etN!A"#&6V>ke:"7Rm:U#;=Z.!&)pSEq]P8Wn(GQ!!8&/_>XE:B@bWWn,NMCf%0a!
+!b^)XqZ$d$_:EI.BDVZ2U"7$`nc/\6D>XA9"i8atr;[!7dFLdE>l4R&+`7,W#R/&q$NL03
+euJZK"#&6V>kS.!_:DH\!!:!f;#C:p_:D*>!;A8CB'l#\B(n'4!.k3&!.k3]!;A8CB'l#\
+B(n(E!!>gms$HS_"9Dp,s).c8";q"8^]jW9"pY,.)#sV9r;Zp'[HAD*!!7cPbPhJKPlKnM
+!!!MEs8PFa!!;?`<Vugu@/oE`!!EqXs8QL&!!>7]s%3.h!U#=7!!OeIs8)Rlqu?j[s8U7T
+qZ$^8[H@ek!!51\@.aL$bQ#BS!!iVK<<*"&s8P[h!!9S.Pl(L`*rl6gr;Zr8s1e[7!!?Wl
+s6':[#aFK^!!$p:s%2qb"-ii/!W<!"3VmXm!"P7nk61hc%`&,E63%!P[JU"1!p@`,!0mN`
+6Mg`e#64ags8QL*!!?6as8)Bg!eUHqqu?j#bQ$`Bqu?j'"TX-lqu@!Ns+p^V_#O6Zp](E3
+s1e[7!!?Wls6'@]";q"8^]jW9!!i5u"%*%f#Q4W(K)a$j!!I3>kK=M8!!>gms+:+J!!i<"
+!CF3l!!35bbPM8BV>na%')V_16FH^k!WqQ.rW!%.s8!!"!!E>Gs5t6s!!*6,rW!#_s'Ya)
+!pBSkqu?f]s'Y$jpG2JTm@!]\pG1q4"$P5d2u3LV:smj!r;Zs6dFOuoqu?p)!!!\`ejfT<
+!sFt,'E%n4D:Y`d!"+)(_#s`<$_c/&2uN^X_:D*R!!6!J_=dj3%]\+2;#((n0@n];r;Zl7
+EqfV<+jnlgd74$6">A?WWXen+!u%$;"o83#0@itm!!91OU%nZnW^Zsg"P2-er;ZncepI;p
+!u]\@+oMBBU"5q9!!?'6f"q7a#^aAq!!$9Teiia-!diLuqu?dOd9QYN%XZdC"98E0U"7dR
+!!"sEqu@!'_5[J8He-b,qZ$g(!!%Asekl;F"%L,XdIdJ@D:Y`a!!B7P_%Z_H"9\i-D-Zu=
+#U.c>!!&_Dd388b!hn2=r;Zpr_:HI%!!Et_etE6E!!!2s!!>12ecl!P!c?Mgq>^Y'f"n?r
+qZ$^]f%+^8!!!2u!!,$Fqu?d!_5dA4"H(d1_%-AC!B6AC!!32;Wr;u#:tF"tr;Zr"f"i$t
+!!*3*rW!#9ekl8E!l<Gaqu?f7ekkQ1pG2JTm@!]\pG.=#JcLB&JcN=]pG2JTm@!]\pG1q4
+%>k,bDE/j]-phgps3!b+!#BJPs1gVq!"s1m"TT_Gs8%RD(dbX,%f?;<V>o]Z!!$%!s.r&"
+^d@5a<W2t#$31$Cqu?h,s8N8r!!Wq@s8TJe!rW*%"ag:L8cA\k$2ULm!!#Uirr?'r!">+l
+s8%==-ok:ZqYEPS!!9"[$2+?4)#F9U-kZn#*[j@%s#C&Z*rl7Jr;ZoBs0_b)"!7LB6N$ll
+HiO,]?uDg;DZBP:rW!";s$H\b"9QC=k99U#$)R\%^gJQ6DWaUi!"W*0s.r&"^d@5a<<*#!
+qDnKS*cCg7!!!l!s8$UG!!PBu?iU0DkPtRY<Cs$p8cSf#p&G2ks5sF\!"M?ls6!Ae!!uZK
+-ifLp)#aLG"f9BT!!")'s8$UM!!,)[rW!=Qs8TlBDPa1Is7uou!"*WDs1gVq!"s1m"o&'"
+@/p6Mr;Zqrs5sF[!!<l1s/#Pl$3IX8s-+o3!@X2/q#CIrqDnKS!cIipqZ$^is8S>\!!60s
+3W/pZDYcBm!#S'&s.sV@%KJils6!Ae!!uZK-ia5Ns8RHE!!<E)s*OYD!pBT1kQ(?4pL`f\
+pLa.TkPu'4f%+(Z)]9eX>cQAT2u<Rj>h7K"0)tt^>cIo,)qNTfE]k'pQ\l1K!!8&/_>XEA
+7b6.J2dE%8_:D*T!!<JWem/+Q"&RS""SMg"$^]GqQS/C<!!EF;f%*"`!!3DQMY@)N4oX"4
+7f*/oHe-cqD*9$q7W$Q#2u*FTMSTPk!#$$neuBl'#n@gr2eU\p!!!nfekl;F!ijh<qu?g:
+f%)eY!"3GjetGoFMMbZid00FK!aO;8rW!'%U"7%!p](VXf%-Nk+WF\&4oG?k7b6.J2dE%8
+_:D'U!(P?hr;[mDd4YJ"'>`8I>Rg`:0;22B!#*3"equp[MO-KWedM0O!fGRFqZ%*bdFQ-'
+"TScsWZ_@h_%ZeJ%g7ci%KHJH_:I"='*&"c7fEAqB@bY-:gAm8>h7:*rW!:1f%-NJ!!!L6
+WW`(s"&RS")uTa<MUoW?!!<_Yer';($3?LEepAP?!$Q]Hq#CIcd4bFu!aO,+qZ$^]f%,3F
+!!5X;0DtkP>gY5(!#RZGer!_!$NN-5f"jfZ!!bun+TMKFf%+L4!!<ATen=m\!l<H#kQ(?4
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.Tkl:^?q>UTobEPR"q>_$,@-@RiqWImT+TML&
+kDAC$rrV@k!W<!!M9Gnu"R!/m!L3T`%]'X:s8Vr2'#<]1s8'oHrW!(/s8V8io`,^n[JKpd
+[AB_8kNA[L%KJN4kPtSF_"[m3HiO+GqZ$["Hft8*!R!M!!!4#6M=poM.-L:'$5+c&kPtSY
+b>kC^rr3#BPl:Xh*rl9'^``[X%]01)$i52PDZBb"[/e#BV>L;r+m8n%K)#BJ[AC;0rrKME
+qu?`uPlC[oV%*S,s8'M5@/p87Jr.:Y3W/pY*ju"I"R#XE?ip<-!>q[3rs+bl8cShR^_lnJ
+!K##!rrVB!8c8Vi6Ke@J%d3l863%"^s8&R=Pinkar;Zj>[Jp1.kPF@.rVus/V>gK.qKi<^
+s8V8i!!!%-kPtSYkPqA%q#C_$bPM8=kJ/6tbPqMBkI(0e!gN^Oq#CF%PlC^^q>lE_q#C\.
+s8TKYM86neq>^U"kPlt-!!m!4s0[H8^q_u/!!*2;rr2t+rVusckPkJqkPr^l!"6U*s8Vr=
+<=Zh-s8Vr=DZ0V=kPtD%DX%5r1A>DJRJ1=f1?ec=Er"8hdAhOV!Vl^*:r1`6dD=Ck)ZTjk
+_/dBkecET`qu?b<WrCQP_3Y-%HiDS+M@0I9f$U0$Tu#=2dAg%B!!H-Lf"m^G!#7GZdFQ.#
+MMe+D_2;%s!&(@gf%.[2p](D/f%*=f!!347_>;^`W\=/J!Y`t%p&G+:_=c@d%O%O^f%/6K
+7Z+5FecDdtrW!6Bf%.[2)ZTjGMZ207d:WMcf%.[(!27u$qu?j=_:I"Nq#CJ_MO4:m!LFJs
+!!%BFee!]H!S5iLT`S'AesC5oTqO.<!!*t(rmh4gdD8W[rVus4MZ)*2HNZL_f"n$nq>^P:
+WrCQN_4a$j!!,$prmhRqeuCY/!/f@TMJ%:PMAc?m!?%7'ecWb9_)M>n!=Oeaed'T8!aO=-
+_3b-$#Z/@gf$V=bMAu?k#tCrBf%.[2)fhtXecEURqZ$\Eei3C)!=*uNf)F%tEXV[C#Z0+'
+QYgc:TeH6B!s6<i+o;6F:tF3aD/u>D0DtkO!hoVE!)WXp!B7joeeGsOW]'naTu#=2dAfYD
+Tu#=2dAgIN!!L-hdAgI:!;A8CB'l#\B(n'4!.k3&!.k3]!;A8CB'l#\B(n(F!!j&E#m1>;
+%MB*>!!N[/DL5b.r;['1+TMa-8O<g^!!WoC#6G,<')hkC+\='^!!*];"V(SH$O$V;%LN+7
+":#D?#7g>*#7F+@JpUls*rH!B#8.=F"Ubt<!!<6^?oe#_#7!S5H\--C./*]CK)->X!!WZ<
+#6P2=%fI"Q$O6b6"VM+F!soGD%LWLC#7_7C!!NH7"U>M@rW!<,*^Vk"!!!<5!s]>1!!<T6
+#7L>-"t0KP(d^eBp](mL8LOQ=!>5V@%KQSY@!d6.3V`XY-uOWS63I&a$PGHk-ia5P$NgVD
+"8W!&%Lr^F#7D.Lqu?m%6>hBm./a,M"$(7NDH.bS!!WHaDLu7_"oJ?.!?OQf&c_n<$NgVD
+r;[!-<Gm.k)#""?#n@7D"UPeF%Lr^F#7D1A!!3cn"8;d!(gq].<=AO$"p$,[H[B-\pAb5N
+[JBk-!@V?&HXJl1!!<6^8Jq@*"Th#.Jo3"9!"T,D$O$V;%LE1L$O$V;%L`79":bY?$Oc5"
+pG2JTm@!]\pG1t5#R_"F!X&`9%L;S*"U@M%B2B9?!!`fL!!P#=2[T?]"q(eB!<ic>rW!!=
+4X'e)$P!=C$NU_D"9J`7#Q=]+"UbG:$hF?'#sDO1B2C`/qu?p)%L3%<#nH\0!\[A'q#CX'
+2dC!4>YlU<!!7#b'D;D1"UbJ8"UPS8%MB'O!WW?5#6Y)5$O7%G"T\c7$iU,0!Xf,7$O$D.
+$5kcU%KHJ6#m(8<pAb:%"U,5.!!XSH!#%:S+nu$=)a,AD!"08?":G20+])fa:bVVE"X.,f
+>W2`\!"08i4Wse*"UP56$Ng/)#7CnC!<ic>"oJ?(!B48#>Ts%G"p-G_D-TOJq#CRO>]!:r
+"T&0+))j2Y!!!61!X/u1!!NTs>\?kHpAb[.$O6_9#7^kE$O$P7#nHh4!Y-jbpAb@1:hO$&
+$2+?&+])fa:bVPC!HOP&!!ONBB4k$oq#CIL4VR_n"T^PeD-S7`!"T)?#m:;5$O6\B#m:;5
+$OQe4":GA9#mokspG2JTm@!]\pG.=#JcLB&JcN=]pG2JTm@!]\pG.=#bl@eOkG<b1JcNmm
+!Ph:-!;A8CB'l#\B(n'4!6kKF#Jl:L!.k3m!!/cVWrVlLpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcO$q!au$gJcLB&aoDK'k5q[apG2JTm@!]\pG.=#bl@fAeh;UTJcNpn!\_@j
+WrVlLpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcO$q!?NY@!.k3m!!0KFWW;cKpL`f\
+pLa.TJcO$q!?!&4!.k3m!!/EkWW;cKpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcM#8!^c&XWW;cKpL`f\pLa.TJcLB&JcM#8!]Rq%WW;cKpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcM,;"Jp!RqJN84pG2JTm@!]\pG.=#JcLB&QN./G>[5Z]W;uZJpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcM/<!#Y_8!L*Va!;A8CB'l#\B(n'4!.k3&
+!13`d'E6P_H`-r=1A>DJRJ1=f14fLX!.k3&!4`+(1A>DJRJ1=f14fLX!.k3<!!<U/DE4Tp
+pG2JTm@!]\pG.=#JcLB&QiI3p7U.UE!;A8CB'l#\B(n'4!.k3&!.k3]!;A8CB'l#\B(n'4
+!.k3&!.k3]!;A8CB'l#\B(n'4!.k3&!.k3]!;A8CB'l#\B(n'4!.k3&!.k3]!;A8CB'l#\
+B(n'4!.k3&!.k3]!;A8CB'l#\B(n'4!.k3&!.k3]!;A8CB'l#\B(n'4!.k3&!.k3]!;A8C
+B'l#\B(n'4!2fet&g$'5!>lZ*!;QTq-jtV,^]=*apL`f\pLa.TJcM\K!=g"-!!*`HJcPTH
+!?hc$!5JU/1A>DJRJ1=f14fLX!.k3&!4`+(1A>DJRJ1=f14fML!!*<GiW'*]Ped<Njo>Nl
+Pfs)Equ?a&*n^Mp-t$H[<<Q];<C.2l!!,DorD`o,?jlo5"X.8R<F?<e!!NaJPfs(nJcNRd
+pG2JTm@!]\pG.=#b5_PH)<(W!7XLi[D<:g$:j]4n>l4R&"W>tn![1B:qaL]b:e!AOq>^OT
+;#Nib:f%Js!!O<<7Rg2^eGoaZ>^NL%2hD%F!;A8CB'l#\B(n'4!.k3&!.k3]!;A8CB'l#\
+B(n'4!6bEF"m>nnirB3iHi!bojo>O%Hi!b[r;Zp'kPnrD!"^Q*_#OH2bJ:O$kPG5Yb?tMP
+!!l/C_#OH2M/E_"!!S5ZqNPk-eGoacDNt2$6@o3Q!;A8CB'l#\B(n'4!6bEF"MrYcirB3Y
+B@5:Ijo>NhB@5:8r;Zp&_:DH:!"^;dU"7fBWhGcQ_9pibW_`is!!k`#U"7fBEa/qL!!RDo
+d<f++eGoa_>^P&Q2hD%F!;A8CB'l#\B(n'4!.k3&!.k3]!;A8CB'l#\B(n'4!6bEF)#sW#
+i;`qps+9;3!mCU]r;Zp:s8S>9!!=YLs+:.K"pI#=qZ"_equ?gZs8Sqm!!>gmb9?KX!@U:l
+!!<E)s$D;;^]=*apL`f\pLa.TJcO!p!u'8:Hf4r+U"4)A!!91O>l=X)'@t`]fDl!sf%+^9
+!!WQZD:-q7+oD<B0@n^3qZ$^]euB\]!!+6%hZ*`]f%)d3!5JU/1A>DJRJ1=f14fLX!.k3&
+!4`+(1A>DJRJ1=f14fML!!6/b(uYGr_#K#I!!:@DDYsJ9<Kn?Q!!<W/s+:%H"=WI5k8sR%
+!ttY6M>R>U<VjK@oDerhs-2@?!rr9eJcNRdpG2JTm@!]\pG.=#b5_T5HP>?<!hn1^j8]7]
+em/+Q!_.MMfDl![f%+^6!!FI]f"i7&!!<_^eoLZg"%L\3$hOE#MUm.2!!:a&2hD%F!;A8C
+B'l#\B(n'4!.k3&!.k3]!;A8CB'l#\B(n'4!2ol!_#K#I!!:@DDU/:as8R]G!!F_Hs1e[7
+!!<K+s*O\E"',At#P.oskPp.j!!<3#6@o3Q!;A8CB'l#\B(n'4!2ol!U"4)A!!91O>gEBO
+f%+^5!!=CletN$B!sR9,BDhf47b3G#o)Jj.ens7D!nPp]JcNRdpG2JTm@!]\pG.=#JcLB&
+JcN=]pG2JTm@!]\pG.=#VuQn7s+9;3!mCU]cN"%Hs+9tF"-iic8cA\l#QOgNrW!%.s-*WV
+!!;?`DVb?ps8PE;!5JU/1A>DJRJ1=f14fM)!!8kFD<(ZuWn(G$!!:a&D>+#4He-b2rW!$(
+f%+L5!!?'KHNNa<!l<Gmh>dW.ei/0\^]=*apL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcNso!Wb;Aqu@!>8H8`=?sktrp](F,6>fd?r;Zo7s+:.K!XVj7qZ$XF6MUTd-t$FC!R(L\
+qu?d!3B@!;#T-,5!%;5_3<K!V"Tpbm?pXte!!<3#K(f6I6N@(^rW!60s8REG!+>hR!V$-k
+kPnQX!!OEDDI=jnq#CR'6==\&%f-/,s8PF`!!O!%?slP=JcNsopG2JTm@!]\pG.=#aoDGq
+0DkeU'0Q<q+](ug!VcWt$TD<['E%n4U"4)Y!!3Bp$2X]'+ZK2s#9co?0*&$'>l+L%0/*5'
+#ST?$!$P080*1kK"Tg>R:cAII!!:a&D>+#42qHQ;rW!3-f%+I6!)V6Zn,NO+ejfH8";s[6
+:a,T6"U-h]>WiJk!!:a&2uEXZ%Q@3\4V!&Db5h8lpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcO$q%;r$*s+14N6Bo[nb5m4nrrL:dqZ$j<M>I)Ks8%?H!"-OAJcGclK!kIT*rZ-B
+<Kt],PktFe.(/p7qZ#aAs).f9%;r$*s+14N6Bo[nb5m4nrrL:dqu@--DTe9$bQ#an?uBip
+p](Bqs+9tF!tPA2bPhJH#QOgN!+>h7nGidp3TpF=DM!K>!!jaUkEL>/s2uhg!!r[DkI#Z$
+kPB'"qu?fus$H\b#Q];8P\u`^s&FXNbQ.AmpL`f\pLa.TJcO$q%:"e,enkBe2g_RUWW6o7
+ecDciqZ$j7Em`:cf$S@6!",FND#aPRD3rZ$)?'U=7XM/dHi!dL+d^TmdFQ.Mem/1S%:"e,
+enkBe2g_RUWW6o7ecDciqu@-,>cN-kWn+1H:g@68p](BHent-]!t3]2Wr;u'"kM7;!)V6C
+n,NYG_:FKKD/K7P#TK,HHY9&'WZh6>#[G34B7%JB>Qjs)!nPp]r;[(8_0]F6dFLd=!6bH;
+1A>DJRJ1=f14fLX!.k3&!4`+(1A>DJRJ1=f14fMN!#/FNqYu-I!'+H1s3%788NDD&s1e[6
+!!lU$M&l[@Hhs!+!"-OAJcGcf@&<o'*rZ-B8T*_kPl1Ri#F+CC!WWC3kPtR"rW!X4DYjBb
+!!##ebQ#b^V+E\!s8Tk8rW!B/V>;55!!g=>s8)T8"o&'!s8R]E!!<#skPbGc#QOgNDZ<`+
+!!BXls8W)]%CH093Tn0c!!!%Os8#ap!!<7uqFUYd"<lt.^^9r>!rr9erW!";s![jH!Z:*#
+JcO!ppG2JTm@!]\pG.=#blADH>g_,>!!"ZKWn+2-MENV0f%-Pm!!l'AEZ"irB@2)*!",FN
+D#aPL:l<iT)?'U=4^>hSHi3pP"ae'K!<<7!_:I1BrW!U$>g_,>!!"ZKWn+2-MENV0f%-Pn
+!"Asdd2;oa"ejMudF"rsp](BHent*\!n#T8rW!-+f%+J=ejf-/".-jTf)EJiQN."=_4_27
+!!@)hd74'7!fGAgrW!'?_:G:br;ZoMei3R.!aO;"rW!!5_+'"VbQ.AmpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcNso!mCUqr;ZqOs8QL*!!@-=s![jH!_NEKqu?bSHi=!H_#K#b
+!!>7]ruV(<!l4i#rW!$$V>im[!!<kss).`7!mCUqr;ZqOs8QL*!!@-=s![jH!au%mr;ZpJ
+s8P+P!!<3#K(]0GkPs`E!!`c/s3(HBPQL:R!pBS`r;Zp)kPlt.!!oG$qA924@/m)$!!=YL
+s,$[S!rr9erVuuBkPP;\M+N:!bQ.AmpL`f\pLa.TJcNso!ijggr;Zq:f%*[r!!?KWefk"m
+!^5+Tqu?b<BDql4U"4)Z!!=n*ef"Ac!hn1lr;ZnVei3L,!tN/u>l4R'Wn)%c!!@)hekl;F
+"'jF.+oVHC:tC!l!!=Cqeh?[r!nPq>p&G01f"q=c#6i]0Wn,aJ!Ug!i_:D*S!!<D@efjqk
+#`@3\'*&#/er'A*"!Q7HEr>t>f%)eZ!!0+9qu?b<4b<[X!;A8CB'l#\B(n'4!.k3&!.k3]
+!;A8CB'l#\B(n'4!6Y?D_#K#b!!@-=k5kM]#mpY38H8_okPl1m!!-(krW!#8s+:1L"!R^E
+*rH!>V>leZ!!5LebPD2?bPuJX!!9t9K)GZODZAl#r;Zp+s8P[i!!9S.Hi3pH!W)h(o`,'n
+s+9tF!s/8ubPhJI#QOh#bQ%U="7Q9lkPnQ\!!6R.bPM8F3WK,2!!;?`8c&Ji[K$(2rW!6(
+s$?\c!W)gVr;Zj8%Y=])!;A8CB'l#\B(n'4!6Y?DU"4)Z!!6EV_>F9>#M.Hh!!!/<edhTX
+!Cf6O!!8kFD>aG:)qNRXqu?eUepIAr!]S]1q>^Ssem/+Q!hn1^r;Zn(f"q7a!sdE.4oPE_
+Qe#gI!!:R!;"Xeif%+^3!!:R!Wr;u("kM7^Wn,aY!q60k_:D*S!!6!JWquc%0@n]k!!0pe
+4o53]Qe'OjrW!#Nei3R.!n#RPr;Zj3$\AB&!;A8CB'l#\B(n'4!.k3&!.k3]!;A8CB'l#\
+B(n'4!6Y?D_#K#b!!7'<bPM8EkPnoi!(m4Rp&G00s+:1L"!R^E*rH!>V>leZ!!8DbV>:/n
+bPuJX!!9t9K)GZNDZ@oW!!;?`@/^--_#KYs!!;?`3V<@Rs8R]F!!<l6s-3K_#m^M1HP4O%
+s.otj!!;?`<W)n![K!*"!!h]eb5aR&s![aE"(;0/8cA\ks8PFb!!^XHqP@RJ!J1<o!;A8C
+B'l#\B(n'4!6Y?DU"4)Z!!6EVWquc$_:DE_!'SoLp&G/fent?c!uohB)>jI9MUm.R!!7Mu
+MY[;SWn(GQ!!8kFD>aG9>h5qP!!:!f;#UFrU"4Sg!!:!f0D,;Hf%+^4!!<_^epIAr#mJo2
+B+CrmeqsY$!!:!f7f<;gQe%&j!!g?kWW4^'efjnj"&RS"4oPE_f%)eZ!!TCRd>CaDJcNmm
+pG2JTm@!]\pG.=#JcLB&JcN=]pG2JTm@!]\pG.=#b5_UZs+:1L!cJ%]qZ$las'Pg,DZ@oR
+!!9t9K)GZO+ohQ`qu?eps-3K_!l4hmq>^T?s).`7!l4hfr;Zn:s3(9>!pBSkrW!%bs5sXd
+!!=YL[/oq#!rr:PpAb:qs8PFb!"&u2s*F_U_#OGB$1\&tkPnQ\!!;?`V>:/s_#NQt<WE(?
+qZ$^Ys8QL+!!<3#6N-rc3TpA@!p>d\JcO!ppG2JTm@!]\pG.=#b5_U;ent?c!aO<VqZ$l;
+ekc>H>h5qK!!8kFD>aG:)qNRXqu?eUepIAr!hn1cq>^Ssem/+Q!hn1^r;Zn(euJTI!l<Ga
+rW!%If"hOh!!4=pQh17Zf%+^4!!>^Aei3R.$3f#3B)i=5f%-/mnc/a-ejfT<!l<HFq>^bo
+f"h>Uf%(`9!!=n*ekl>G!nPp]rVusP_>Vpd_0ZZD!6bH;1A>DJRJ1=f14fLX!.k3&!4`+(
+1A>DJRJ1=f14fML!!9t9K)GZNDZ@oW!!qcf?iU1`s7ucj!!9t9K)GZO+ohQ`qu?eps-3K_
+!mCV?q>^T?s).`7!l4hfr;Zn:s3(9>!pBSkrW!6JqZ!B/!%?%+$hOE#s8R]F!!B(tb6%YC
+$O?_3HN4$R_#OGM%eBZ%kPnQ\!!;?`_"n$9V>n^=@/p6eqZ$^>s8Q*u!!<3#6N$ld%TT@g
+rr3#^$%`0%!;A8CB'l#\B(n'4!6Y?DU"4)Z!!6EVWquc$_:DE_!-6Z<p&G/fent?c!uohB
+)>jI9MUm.R!!91OMY[;SWn(GQ!!8kFD>aG9>h5qP!!:!f;#UG$)q!5o'*'2UTaC>k!nPq>
+pAb;QeuAcM!"/t]en4s_$),r$TaUGl!l<GWr;Zo8etMp?#E%*4!)V7t0Db_O):mA.rW!#N
+ei3O-!t.SU_>`!d_$>PlblIJnpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcNso!l4hf
+r;Zn:s3(9>#j;4q!!$p:rttJ1!l4hfr;ZpCs8O8?!!9"sPl:Xa_#MUS!!;?`DYsJ9_#K#b
+!!7'<bPM8@kPnrg!!a[3qZ#`o<<;[k!rr:Pp](CEs8P[h!!<K+s*O_F"UVU:s2u&I!!;?`
+<W)n![K#Fd!!fq3V#WOUs&Jpr""=3L./j2Js8PF^!!NEaV>pQeJcO$qpG2JTm@!]\pG.=#
+b5_U;ent?c!aO<VqZ$o<ekc>H>h7I>pAb8gent?c!uohB)uK[;MUm.R!!8kFWql\s_:Dlh
+!!8kFD>aG9>h5qP!!:!f;#L@u)gfu`_4a?h!!:a&D>4)5+kG4-r;Zp'f%+L5!!NUof%-i2
+oDes/ejfT<!ghKSq>^beeqsG\f%*=f!!=Cqefk"m!nPp]q>^["08e?34b<[Y!;A8CB'l#\
+B(n'4!.k3&!.k3]!;A8CB'l#\B(n'4!6Y?D_#K#b!!7'<bPM8FkPnoi!'1)ZM>$uO_#K#b
+!!=)<s#L#X!se#hPl:XbHiO+4qu?gIs8R!7!!9t9K)GZNDZ@oW!!;?`@/U'.!H,:O!Up'j
+s8R]H!!=)$s-3E]!t##-Hi3pJ#IXU3b8BmP!pBS`r;ZqVs8OME!!g^I<<*F,s/#Sm"',BE
+!WE'#s8PFb!!&km!!9S.8V-re!;A8CB'l#\B(n'4!6Y?DU"4)Z!!6EVWquc%_:DE_!&)pS
+Eq]P8U"4)Z!!<nceh?t%!sQNlHi=!IB@bWmqu?gBf%++(!!8kFD>aG9>h5qP!!:!f;#C:p
+>aG]a!!:a&D>=/6'>`7Hqu?g(f%+L4!!NOmf%-i7o`,'0ejfT<"*2uD+o;6EWn'W>$.d[b
+qZ$[eeuJZK!nPp]rVuqUqZ$\aeieTbblIJnpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcNso!l4hmr;Zn:s3(9>$0V=r!!!&8s8"/=!!9t9M>[DV"onUSrW!')Pir(CrW!'EqZ"_U
+rW!'2bNJnCqu?f6s,$[S!cJ%]qZ$]\s'Yd*!gN^5mf3Fps8R]I!!G=Fs.ons!!=;Bs-3E]
+"U1b&s5tHs!!;?`K)GZO*r>o$qu@$Os2tHD!0mN`*rH!>V>jQp!!ic.s%*1j"o8?!!!9S)
+%Y=]*!;A8CB'l#\B(n'4!6Y?DU"48_!!6EVWqubt_:DH^!!AqGd388b!hn1cr;Zp&f%+^;
+!!EFO_:FMC!!F7geuBD_!!E\0_:Dlh!!8kFEr>t>>h5qP!!:!f;#L@qHe'A/!!<DUent6`
+">@UBM?NhW!u]\@Hi*jI"H(d]_&;qH!l<H)r;Zp;dFN[B!!sh"WW<)"He-acqu?eUejfW=
+#R&`04TGHbd/s4G!gh:BJcO$qpG2JTm@!]\pG.=#JcLB&JcN=]pG2JTm@!]\pG.=#bQ%_G
+kPqCW!!A)Xk5tP]!pBT8rW!HMkPtBr(]XRs<<*""kPqCV!"-OAs--o/bAO0V_#46@DZBb"
+DF/6a<P\Wkr;Zp#kPqCW!!A)Xk5tP]!pBT8rW!'+qZ"a'rHeT`636f\%S?^#V)]qF-ol1\
+s6"8#qZ$^bs8TM(!!NP&s8V7BpAbT:s6"9aD?'ZSs8R!9!!<PCk8sU&";9ntb8C3Y!_NED
+r;[-Fs8QI,!#Y`R!WE'#3Vm-8!6bH;1A>DJRJ1=f14fML!!:!fMZ!MWEn8&-qu?f7entBd
+#oUS1d9I=b!&$h@!!:!fMYmG]U"7eA:gC#*MUnL"!"3&_f"kTM>cL8eeoLZg!l<HFr;Zq?
+f"hCb!!:!fD>jM<"jto$Hi7RX>W;?V%6`:nMD$+j+YR)of"kVf!!>12esH76"U'_6f"j$6
+!"5LO_-D=l!!$9Tem/1S!sbO9)?'U=%`-_r'E.t54k=KK!!jInekc>H'@pFe!!4h$:kA\k
+!;A8CB'l#\B(n'4!.k3&!.k3]!;A8CB'l#\B(n'4!6kKE[HIPh#g7g;bPM8=kJ7#r#j;6a
+b>eNB*ju"I#3YjG63+FVrr3#BK)P`N.*MVi#No(e[K$9MK)P`N<TjA]$KjDLbQ%F^HN:J:
+rr38IJo8d.s8V8tr;[,ds8'o=!!%lPq>UJl!Vl]r<VlRl"T%;X?jli3!eSVlrr3&_^_m"M
+!<SMbrrAnj!"hg!s8U7T!!!%;qZ!s@Hcr6&qu@!GbQ$aiDNs<arW!KX^utatqTDkes8U9!
+Ju.X<JcNsopG2JTm@!]\pG.=#bl@d2_>`!kWbl"@dFQmbU&=rs_:I#67K<E+Qi>P?_9p(X
+!11P$ecDdfrVusBWrCQS_+"Ekf%-j<rVusg_>`!m_(Pegf$UL1!11P$ed/9m>cQ3&f"n'Y
+!!pEldAfY9!-6K_ec:U&!!,R:qUPes_2;%qqZ$\7WmUgs!l:QDr;Zj!HiDRrMYI/T4jhj3
+WXf".#[Gd.QX"1'MA,mf#TKep_0]F6_++D(&0[a`f%/6K7Np@6WcDs6_,,^`b5h8lpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcO$q%2'$R!XB2F$P!CD"UbtA!!Ec:"UbY9!"T)j
+DLu7_"TSN8$O6_<%M&F;$O%qM3<oNa%LE4D$iL&D"Xl](%KHJ=#6P8?!"oYE!XB2F$P!CD
+"UbtA!"obH"UbV:!'/6!M/H^=Pir)H6MUTf#n@7F!s];K%KZ;(#S%=N"Tnu>&d/%3"9B,?
+"V18,!uO?b#Q+Q*&n$<<?l8\>"p$`%Jo3RPr;[?3&d\^D#n@7A(fbI*?pY$K!6P<91A>DJ
+RJ1=f14fMN!"BDE"T\c7$OI1E!X&f>r;Zs."U#,:r;[<\>]!:r"98E3#mC>5$Ocn5$NqV9
+0*M=U$O6_<$2jiB"<f]_$NL/7"Teo8!"K;=!<ii=#n$n<":5S:!"oYC":5;5!&(@0Ea2FG
+Hbn:a2u*FZ#7Cb>!X/rA$haQ+$O[1B!X/rA!rDs"%KutCpAb:/2_P@4!!Nj/D.cZYp](IN
+>]!_!"T8<2":bY>!XB)<!#%h,D,<.oJcNpnpG2JTm@!]\pG.=#JcLB&JcN=]pG2JTm@!]\
+pG.=#JcP'9!s,7u<Vlau''K:4JcLB&h>m:*pL`f\pLa.TJcLB&kl:dBejfN:!tN/u>_2s-
+!8[_M1A>DJRJ1=f14fLX!.k3&!4`+(1A>DJRJ1=f14fLX!9sOc3WI:u!!9"sDLqk?!8[_M
+1A>DJRJ1=f14fLX!9sOc0@m0!!!8&/>_2s-!8[_M1A>DJRJ1=f14fLX!.k3&!4`+(1A>DJ
+RJ1=f14fLX!9sOc<WBK&!!9t9."VGN!8[_M1A>DJRJ1=f14fLX!9sOc7b3q%!!8kF+bB]G
+!8[_M1A>DJRJ1=f14fLX!.k3&!4`+(1A>DJRJ1=f14fLX!9sOd+og^-qZ$[GqPAcDJcOU,
+pG2JTm@!]\pG.=#JcP'9!uoh-!rDs!+jl1!!.k4,!;A8CB'l#\B(n'4!.k3&!.k3]!;A8C
+B'l#\B(n'4!.k49!!E=es+pgU!!=Y4^^G_oJcOU,pG2JTm@!]\pG.=#JcP$8"+/U>!W<!#
++i0iYJcLB&h#R1)pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&kl;%oK'1<p<GnYr
+<<@aPJcOR+pG2JTm@!]\pG.=#JcP$8$3Y4^Wa&"uMSVa_JcLB&g]7((pL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&k5Y\r8T&lT-j>2&JcOL)pG2JTm@!]\pG.=#JcOs6"q*S!
+B1=$IJcLB&g&Uk&pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@Z
+pL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&
+\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&
+JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.T
+JcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\pLa.TJcLB&JcLB&\H)@ZpL`f\
+pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5
+Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\
+pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5
+Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\
+pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5
+Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\
+pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5
+Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\
+pL]"4Jhhp5Jhj/XpL`f\pL]"4Jhhp5Jhj/XpL`f\JnBUHJnBUHO_4!KJnBUHJnBUHO_4!K
+JnBUHJnBUHO_4!KJnBUHJnBUHO_4!KJnBUHJnBUHO_4!KJnBUHJnBUHO_4!KJnBUHJnBUH
+O_4!KJnBUHJnBUHO_4!KJnBUHJnBUHO_4!KJnBUHJnBUHO_4!KJnBUHJnBUHO_4!KJnBUH
+JnBUHO_4!KJnBUHJnBUHO_4!KJnBUHJnBUHO_4!KJnBUHJnBUHO_4!KJnBUHJnBUHO_4!K
+JnBUHJnBUHO_4!KJnBUHJnBUHO_4!KJnBUHJnBUHO_4!KJnBUHJnBUHO_4!KJnBUHJnBUH
+O_4!KJnBUHJnBUHO_4!KJnBUHJnBUHO_4!KJnBUHJnBUHO_4!KJnBUHJnBUHO_4!KJnBUH
+JnBUHO_4!KJnBUHJnBUHO_4!KJnBUHJnBUHO_4!KJnBUHJnBUHO_4!KJnBUHJnBUHO_035
+Jsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4Y
+Jsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4Y
+Jsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4Y
+Jsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4Y
+Jsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4YJsh4Y
+Jsh4YJsh4YJsh4YJsh4YJsh4Yi0a~>
diff --git a/support/dktools/splash-dktoolian.png b/support/dktools/splash-dktoolian.png
new file mode 100644
index 0000000000..d72915cea7
--- /dev/null
+++ b/support/dktools/splash-dktoolian.png
Binary files differ
diff --git a/support/dktools/standard-headers.txt b/support/dktools/standard-headers.txt
new file mode 100644
index 0000000000..b36e97e62a
--- /dev/null
+++ b/support/dktools/standard-headers.txt
@@ -0,0 +1,29 @@
+assert.h
+complex.h
+ctype.h
+errno.h
+fenv.h
+float.h ?
+inttypes.h
+iso646.h ?
+limits.h
+locale.h
+math.h
+setjmp.h
+signal.h
+stdalign.h ?
+stdarg.h ?
+stdatomic.h ?
+stdbool.h ?
+stddef.h ?
+stdint.h
+stdio.h
+stdlib.h
+stdnoreturn.h ?
+string.h
+tgmath.h
+threads.h ?
+time.h
+uchar.h ?
+wchar.h
+wctype.h
diff --git a/support/dktools/sttfiles.dox b/support/dktools/sttfiles.dox
new file mode 100644
index 0000000000..d79bf7aafc
--- /dev/null
+++ b/support/dktools/sttfiles.dox
@@ -0,0 +1,89 @@
+/** @page sttfiles String table files
+
+@section secsttfiles String table files
+
+An application can contain a set of default strings, i.e. in English.
+These default strings are hard-coded in the sources.
+
+When the application is run, it can detect the users language and region
+and search for an appropriate string table files containing replacement
+strings to use instead of the default strings.
+
+@section secsttsource String tables in source code
+
+We use an example to show it.
+
+In the *.ctr, *.cpt or *.wxc file write:
+~~~~~~~~~~~~~~~{.c}
+const dkChar * const default_strings[] = {
+$!string-table macro=dkT
+#
+# 0: Welcome greeting "Hello"
+#
+Hello.
+#
+# 1: Goodbye greeting "Goodbye"
+#
+Goodbye.
+$!end
+};
+
+const dkChar * const *msgs = default_strings;
+
+static size_t sz_msg = (sizeof(default_strings)/sizeof(DK4_PDKCHAR) - 1);
+~~~~~~~~~~~~~~~
+The lines started by '#' character are comments.
+I recommend to have index numbers in comments as you later use
+msgs[index] to access the strings.
+
+This will result in the following code in the *.c or *.cpp file created:
+~~~~~~~~~~~~~~~{.c}
+const dkChar * const default_strings[] = {
+/* 0 */
+dkT("Hello"),
+
+/* 1 */
+dkT("Goodbye"),
+
+NULL
+};
+
+const dkChar * const *msgs = default_strings;
+
+static size_t sz_msg = (sizeof(default_strings)/sizeof(DK4_PDKCHAR) - 1);
+~~~~~~~~~~~~~~~
+The index numbers here are generated automatically.
+
+We create a file ${datarootdir}/program/de/greetings.str:
+~~~~~~~~~~~~~~~
+#
+# 0: Welcome greeting "Hello"
+#
+Guten Tag.
+#
+# 1: Goodbye greeting "Goodbye"
+#
+Auf Wiedersehen.
+~~~~~~~~~~~~~~~
+As you see we copied the contents from $!string-table to $!end into the
+new text file. We left all comments and indices untouched, only the
+texts were changed.
+
+After
+~~~~~~~~~~~~~~~{.c}
+sz_msg = dk4app_string_table_size(default_strings);
+msgs = dk4app_string_table(app, dkT("greetings.str"), default_strings);
+~~~~~~~~~~~~~~~
+you can access msgs[0] and msgs[1] to use localized texts.
+
+@section secsttfileformat File format
+
+- The file consists of comment lines and text lines.
+- Each line started by '#' is a comment line, all other lines are text lines.
+- If a '#' character is required as start of the text, write "\#" instead.
+- If a newline or tabulator is required, use "\n" or "\t".
+- Strings are accessed by index in an array, so make sure to keep the
+ indices unchanged (do not accidently add empty lines).
+- The file must be saved UTF-8 encoded without leading byte order mark (BOM).
+
+*/
diff --git a/support/dktools/test-a85d.c b/support/dktools/test-a85d.c
new file mode 100644
index 0000000000..2c8d8410f2
--- /dev/null
+++ b/support/dktools/test-a85d.c
@@ -0,0 +1,148 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-a85d.ctr
+*/
+
+
+#line 1 "test-a85d.ctr"
+/** @file test-dk4a85d.c Decoding ASCII-85 encoded data.
+ The program converts ASCII-85 encoded text read from stdin
+ and writes binary data to stdout.
+
+ This file is an example how to use the dk4_a85_dec_t type.
+*/
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+#if DK4_ON_WINDOWS
+#include <io.h>
+#endif
+
+#include "dk4a85d.h"
+#include "dk4edstm.h"
+
+
+
+
+
+#line 21 "test-a85d.ctr"
+
+
+
+int main(int argc, char *argv[])
+{
+ dk4_a85_dec_t a85d; /* Decoder */
+ const unsigned char *uptr; /* Pointer to decoders output buffer */
+ size_t sz; /* Decoder output buffer size */
+ size_t i; /* Current output buffer index */
+ int c; /* Input character from stdin */
+ int cc = 1; /* Flag: Can continue */
+ int exval = 0; /* Exit status code */
+#if DK4_ON_WINDOWS
+ int oldmode; /* Previous file mode for stdout */
+#endif
+
+
+
+#line 38 "test-a85d.ctr"
+
+
+#line 39 "test-a85d.ctr"
+
+ /* Initialize decoder.
+ */
+ dk4a85_dec_init(&a85d, NULL);
+
+ /* Change file mode for stdout to binary on Windows.
+ */
+#if DK4_ON_WINDOWS
+ oldmode = _setmode(_fileno(stdout), _O_BINARY);
+#endif
+
+ /* Process standard input contents.
+ */
+ while (1 == cc) {
+ c = fgetc(stdin);
+ if (EOF != c) {
+ switch (dk4a85_dec_add(&a85d, c, NULL)) {
+ case DK4_EDSTM_FINISHED : {
+ /* Decoder indicates that output is available.
+ */
+ uptr = NULL; sz = 0;
+ if (1 == dk4a85_dec_output(&uptr, &sz, &a85d, NULL)) {
+ if ((NULL != uptr) && (0 < sz)) {
+ /* Output really found, write to stdout.
+ */
+ for (i = 0; i < sz; i++) {
+ if (EOF == fputc(uptr[i], stdout)) {
+ exval = 1;
+ /* ERROR: Failed to write output */
+ }
+ }
+ }
+ }
+ } break;
+ case DK4_EDSTM_STOP : {
+ /* EOD marker found, stop processing.
+ */
+ cc = 0;
+ } break;
+ case DK4_EDSTM_ERROR : {
+ /* ERROR: Decoding error occured. */
+ exval = 1;
+ cc = -1;
+ } break;
+ }
+ } else {
+ cc = 0;
+ }
+ }
+
+ /* Check for incomplete final sequence in decoder.
+ */
+ if (0 == cc) {
+ switch (dk4a85_dec_finish(&a85d, NULL)) {
+ case DK4_EDSTM_FINISHED : {
+ /* Decoder indicates that output is available.
+ */
+ uptr = NULL; sz = 0;
+ if (1 == dk4a85_dec_output(&uptr, &sz, &a85d, NULL)) {
+ if ((NULL != uptr) && (0 < sz)) {
+ /* Output really found, write to stdout.
+ */
+ for (i = 0; i < sz; i++) {
+ if (EOF == fputc(uptr[i], stdout)) {
+ exval = 1;
+ /* ERROR: Failed to write output */
+ }
+ }
+ }
+ }
+ } break;
+ case DK4_EDSTM_ERROR : {
+ exval = 1;
+ /* ERROR: Decoding error occured */
+ } break;
+ }
+ }
+
+ /* Restore previous file mode on Windows.
+ */
+ fflush(stdout);
+#if DK4_ON_WINDOWS
+ _setmode(_fileno(stdout), oldmode);
+#endif
+
+
+
+#line 125 "test-a85d.ctr"
+
+
+#line 126 "test-a85d.ctr"
+
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/test-a85d.ctr b/support/dktools/test-a85d.ctr
new file mode 100644
index 0000000000..febb9e2df6
--- /dev/null
+++ b/support/dktools/test-a85d.ctr
@@ -0,0 +1,129 @@
+/** @file test-dk4a85d.c Decoding ASCII-85 encoded data.
+ The program converts ASCII-85 encoded text read from stdin
+ and writes binary data to stdout.
+
+ This file is an example how to use the dk4_a85_dec_t type.
+*/
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+#if DK4_ON_WINDOWS
+#include <io.h>
+#endif
+
+#include "dk4a85d.h"
+#include "dk4edstm.h"
+
+
+
+$!trace-include
+
+
+
+int main(int argc, char *argv[])
+{
+ dk4_a85_dec_t a85d; /* Decoder */
+ const unsigned char *uptr; /* Pointer to decoders output buffer */
+ size_t sz; /* Decoder output buffer size */
+ size_t i; /* Current output buffer index */
+ int c; /* Input character from stdin */
+ int cc = 1; /* Flag: Can continue */
+ int exval = 0; /* Exit status code */
+#if DK4_ON_WINDOWS
+ int oldmode; /* Previous file mode for stdout */
+#endif
+
+ $!trace-init test-a85d.deb
+ $? "+ main"
+
+ /* Initialize decoder.
+ */
+ dk4a85_dec_init(&a85d, NULL);
+
+ /* Change file mode for stdout to binary on Windows.
+ */
+#if DK4_ON_WINDOWS
+ oldmode = _setmode(_fileno(stdout), _O_BINARY);
+#endif
+
+ /* Process standard input contents.
+ */
+ while (1 == cc) {
+ c = fgetc(stdin);
+ if (EOF != c) {
+ switch (dk4a85_dec_add(&a85d, c, NULL)) {
+ case DK4_EDSTM_FINISHED : {
+ /* Decoder indicates that output is available.
+ */
+ uptr = NULL; sz = 0;
+ if (1 == dk4a85_dec_output(&uptr, &sz, &a85d, NULL)) {
+ if ((NULL != uptr) && (0 < sz)) {
+ /* Output really found, write to stdout.
+ */
+ for (i = 0; i < sz; i++) {
+ if (EOF == fputc(uptr[i], stdout)) {
+ exval = 1;
+ /* ERROR: Failed to write output */
+ }
+ }
+ }
+ }
+ } break;
+ case DK4_EDSTM_STOP : {
+ /* EOD marker found, stop processing.
+ */
+ cc = 0;
+ } break;
+ case DK4_EDSTM_ERROR : {
+ /* ERROR: Decoding error occured. */
+ exval = 1;
+ cc = -1;
+ } break;
+ }
+ } else {
+ cc = 0;
+ }
+ }
+
+ /* Check for incomplete final sequence in decoder.
+ */
+ if (0 == cc) {
+ switch (dk4a85_dec_finish(&a85d, NULL)) {
+ case DK4_EDSTM_FINISHED : {
+ /* Decoder indicates that output is available.
+ */
+ uptr = NULL; sz = 0;
+ if (1 == dk4a85_dec_output(&uptr, &sz, &a85d, NULL)) {
+ if ((NULL != uptr) && (0 < sz)) {
+ /* Output really found, write to stdout.
+ */
+ for (i = 0; i < sz; i++) {
+ if (EOF == fputc(uptr[i], stdout)) {
+ exval = 1;
+ /* ERROR: Failed to write output */
+ }
+ }
+ }
+ }
+ } break;
+ case DK4_EDSTM_ERROR : {
+ exval = 1;
+ /* ERROR: Decoding error occured */
+ } break;
+ }
+ }
+
+ /* Restore previous file mode on Windows.
+ */
+ fflush(stdout);
+#if DK4_ON_WINDOWS
+ _setmode(_fileno(stdout), oldmode);
+#endif
+
+ $? "- main 0"
+ $!trace-end
+
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/test-a85e.c b/support/dktools/test-a85e.c
new file mode 100644
index 0000000000..98ac10a8a2
--- /dev/null
+++ b/support/dktools/test-a85e.c
@@ -0,0 +1,134 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-a85e.ctr
+*/
+
+
+#line 1 "test-a85e.ctr"
+/** @file test-a85e.c
+ Convert binary input from stdin to ASCII-85 encoded text on stdout.
+
+ This is an example how to used the dk4_a85_enc_t type.
+*/
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+#if DK4_ON_WINDOWS
+#include <io.h>
+#endif
+
+#include "dk4a85e.h"
+#include "dk4edstm.h"
+
+
+
+
+
+#line 20 "test-a85e.ctr"
+
+
+
+int main(int argc, char *argv[])
+{
+ dk4_a85_enc_t a85e; /* Encoder */
+ const char *dptr; /* Pointer to encoder output buffer */
+ size_t sz; /* Size of encoder output buffer */
+ size_t i; /* Current output buffer index to process */
+ int c; /* Input character */
+ int linepos = 0; /* Position within output text line */
+#if DK4_ON_WINDOWS
+ int oldmode; /* Previous file mode for stdin */
+#endif
+
+
+
+#line 36 "test-a85e.ctr"
+
+
+#line 37 "test-a85e.ctr"
+
+ /* Set file mode for standard input to binary on Windows.
+ */
+#if DK4_ON_WINDOWS
+ oldmode = _setmode(0, _O_BINARY);
+#endif
+
+ /* Initialize encoder.
+ */
+ dk4a85_enc_init(&a85e, 1, NULL);
+
+ /* Process contents from stdin.
+ */
+ while (EOF != (c = fgetc(stdin))) {
+ switch (dk4a85_enc_add(&a85e, (unsigned char)c, NULL)) {
+ case DK4_EDSTM_FINISHED: {
+ /* Encoder indicates that output is available.
+ */
+ dptr = NULL; sz = 0;
+ if (0 != dk4a85_enc_output(&dptr, &sz, &a85e, NULL)) {
+ if ((NULL != dptr) && (0 < sz)) {
+ /* Output really found, write to stdout.
+ */
+ for (i = 0; i < sz; i++) {
+ fputc(dptr[i], stdout);
+ if (++linepos >= 75) {
+ fputc('\n', stdout);
+ linepos = 0;
+ }
+ }
+ }
+ }
+ } break;
+ }
+ }
+
+ /* Restore previous file mode for stdin on Windows
+ */
+#if DK4_ON_WINDOWS
+ _setmode(0, oldmode);
+#endif
+
+ /* Check for final unprocessed sequence in encoder.
+ */
+ switch (dk4a85_enc_finish(&a85e, NULL)) {
+ case DK4_EDSTM_FINISHED: {
+ /* Encoder indicates that output is available.
+ */
+ dptr = NULL; sz = 0;
+ if (0 != dk4a85_enc_output(&dptr, &sz, &a85e, NULL)) {
+ if ((NULL != dptr) && (0 < sz)) {
+ /* Output really found, write to stdout.
+ */
+ for (i = 0; i < sz; i++) {
+ fputc(dptr[i], stdout);
+ if (++linepos >= 75) {
+ fputc('\n', stdout);
+ linepos = 0;
+ }
+ }
+ }
+ }
+ } break;
+ }
+
+ /* Write EOD marker to output.
+ */
+ if (74 <= linepos) {
+ fputc('\n', stdout);
+ }
+ fputs("~>\n", stdout);
+
+
+
+#line 110 "test-a85e.ctr"
+
+
+#line 111 "test-a85e.ctr"
+
+ exit(0); return 0;
+}
+
+
diff --git a/support/dktools/test-a85e.ctr b/support/dktools/test-a85e.ctr
new file mode 100644
index 0000000000..2c3db881f8
--- /dev/null
+++ b/support/dktools/test-a85e.ctr
@@ -0,0 +1,115 @@
+/** @file test-a85e.c
+ Convert binary input from stdin to ASCII-85 encoded text on stdout.
+
+ This is an example how to used the dk4_a85_enc_t type.
+*/
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+#if DK4_ON_WINDOWS
+#include <io.h>
+#endif
+
+#include "dk4a85e.h"
+#include "dk4edstm.h"
+
+
+
+$!trace-include
+
+
+
+int main(int argc, char *argv[])
+{
+ dk4_a85_enc_t a85e; /* Encoder */
+ const char *dptr; /* Pointer to encoder output buffer */
+ size_t sz; /* Size of encoder output buffer */
+ size_t i; /* Current output buffer index to process */
+ int c; /* Input character */
+ int linepos = 0; /* Position within output text line */
+#if DK4_ON_WINDOWS
+ int oldmode; /* Previous file mode for stdin */
+#endif
+
+ $!trace-init test-a85e.deb
+ $? "+ main"
+
+ /* Set file mode for standard input to binary on Windows.
+ */
+#if DK4_ON_WINDOWS
+ oldmode = _setmode(0, _O_BINARY);
+#endif
+
+ /* Initialize encoder.
+ */
+ dk4a85_enc_init(&a85e, 1, NULL);
+
+ /* Process contents from stdin.
+ */
+ while (EOF != (c = fgetc(stdin))) {
+ switch (dk4a85_enc_add(&a85e, (unsigned char)c, NULL)) {
+ case DK4_EDSTM_FINISHED: {
+ /* Encoder indicates that output is available.
+ */
+ dptr = NULL; sz = 0;
+ if (0 != dk4a85_enc_output(&dptr, &sz, &a85e, NULL)) {
+ if ((NULL != dptr) && (0 < sz)) {
+ /* Output really found, write to stdout.
+ */
+ for (i = 0; i < sz; i++) {
+ fputc(dptr[i], stdout);
+ if (++linepos >= 75) {
+ fputc('\n', stdout);
+ linepos = 0;
+ }
+ }
+ }
+ }
+ } break;
+ }
+ }
+
+ /* Restore previous file mode for stdin on Windows
+ */
+#if DK4_ON_WINDOWS
+ _setmode(0, oldmode);
+#endif
+
+ /* Check for final unprocessed sequence in encoder.
+ */
+ switch (dk4a85_enc_finish(&a85e, NULL)) {
+ case DK4_EDSTM_FINISHED: {
+ /* Encoder indicates that output is available.
+ */
+ dptr = NULL; sz = 0;
+ if (0 != dk4a85_enc_output(&dptr, &sz, &a85e, NULL)) {
+ if ((NULL != dptr) && (0 < sz)) {
+ /* Output really found, write to stdout.
+ */
+ for (i = 0; i < sz; i++) {
+ fputc(dptr[i], stdout);
+ if (++linepos >= 75) {
+ fputc('\n', stdout);
+ linepos = 0;
+ }
+ }
+ }
+ }
+ } break;
+ }
+
+ /* Write EOD marker to output.
+ */
+ if (74 <= linepos) {
+ fputc('\n', stdout);
+ }
+ fputs("~>\n", stdout);
+
+ $? "- main 0"
+ $!trace-end
+
+ exit(0); return 0;
+}
+
+
diff --git a/support/dktools/test-binenc.c b/support/dktools/test-binenc.c
new file mode 100644
index 0000000000..e5c3dfe101
--- /dev/null
+++ b/support/dktools/test-binenc.c
@@ -0,0 +1,45 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-binenc.ctr
+*/
+
+/** @file test-binenc.c The test-binenc module.
+*/
+
+
+#line 1 "test-binenc.ctr"
+
+
+#include "dk4conf.h"
+#include <stdio.h>
+
+
+#include "dk4binenc.h"
+
+
+static char tbuf[9];
+
+
+static const unsigned char srcbuf[] = {
+ 0x01, 0x02, 0x0A, 0x0F, 0x20, 0x24, 0xFF
+};
+
+int main(void)
+{
+ int res;
+
+ res = dk4binenc(
+ tbuf, sizeof(tbuf), srcbuf, sizeof(srcbuf),
+ DK4_BINARY_TO_TEXT_ENCODING_A85,
+ NULL
+ );
+ if (0 < res) {
+ fputs(tbuf, stdout);
+ fputc('\n', stdout);
+ } else {
+ fputs("buffer to small\n", stdout);
+ }
+ return 0;
+}
diff --git a/support/dktools/test-binenc.ctr b/support/dktools/test-binenc.ctr
new file mode 100644
index 0000000000..0a995eb792
--- /dev/null
+++ b/support/dktools/test-binenc.ctr
@@ -0,0 +1,33 @@
+
+
+#include "dk4conf.h"
+#include <stdio.h>
+
+
+#include "dk4binenc.h"
+
+
+static char tbuf[9];
+
+
+static const unsigned char srcbuf[] = {
+ 0x01, 0x02, 0x0A, 0x0F, 0x20, 0x24, 0xFF
+};
+
+int main(void)
+{
+ int res;
+
+ res = dk4binenc(
+ tbuf, sizeof(tbuf), srcbuf, sizeof(srcbuf),
+ DK4_BINARY_TO_TEXT_ENCODING_A85,
+ NULL
+ );
+ if (0 < res) {
+ fputs(tbuf, stdout);
+ fputc('\n', stdout);
+ } else {
+ fputs("buffer to small\n", stdout);
+ }
+ return 0;
+}
diff --git a/support/dktools/test-bool.c b/support/dktools/test-bool.c
new file mode 100644
index 0000000000..229e150db5
--- /dev/null
+++ b/support/dktools/test-bool.c
@@ -0,0 +1,210 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-bool.ctr
+*/
+
+/** @file test-bool.c The test-bool module.
+*/
+
+
+#line 1 "test-bool.ctr"
+
+#include "dk4conf.h"
+#include "dk4str8.h"
+
+#include <stdio.h>
+
+
+
+
+
+#line 10 "test-bool.ctr"
+
+
+
+static const char * const teststr[] = {
+/* 0 */
+"ja",
+
+/* 1 */
+"nein",
+
+/* 2 */
+"yes",
+
+/* 3 */
+"no",
+
+/* 4 */
+"y",
+
+/* 5 */
+"n",
+
+/* 6 */
+"on",
+
+/* 7 */
+"off",
+
+/* 8 */
+"o",
+
+/* 9 */
+"of",
+
+/* 10 */
+"true",
+
+/* 11 */
+"tru",
+
+/* 12 */
+"tr",
+
+/* 13 */
+"t",
+
+/* 14 */
+"false",
+
+/* 15 */
+"fals",
+
+/* 16 */
+"fal",
+
+/* 17 */
+"fa",
+
+/* 18 */
+"f",
+
+/* 19 */
+"0",
+
+/* 20 */
+"1",
+
+/* 21 */
+"2",
+
+/* 22 */
+"+",
+
+/* 23 */
+"-",
+
+/* 24 */
+"*",
+
+/* 25 */
+"/",
+
+/* 26 */
+"JA",
+
+/* 27 */
+"J",
+
+/* 28 */
+"NEIN",
+
+/* 29 */
+"N",
+
+/* 30 */
+"YES",
+
+/* 31 */
+"NO",
+
+/* 32 */
+"YE",
+
+/* 33 */
+"N",
+
+/* 34 */
+"Y",
+
+/* 35 */
+"OFF",
+
+/* 36 */
+"OF",
+
+/* 37 */
+"O",
+
+/* 38 */
+"OfF",
+
+/* 39 */
+"TRUE",
+
+/* 40 */
+"TRU",
+
+/* 41 */
+"TR",
+
+/* 42 */
+"T",
+
+/* 43 */
+"B",
+
+/* 44 */
+"FALSE",
+
+/* 45 */
+"FALSCH",
+
+/* 46 */
+"FAL",
+
+/* 47 */
+"FA",
+
+/* 48 */
+"F",
+
+/* 49 */
+"0815",
+
+NULL
+
+
+#line 66 "test-bool.ctr"
+};
+
+int main(void)
+{
+ const char * const *ptr;
+
+
+#line 72 "test-bool.ctr"
+
+
+#line 73 "test-bool.ctr"
+ ptr = teststr;
+ while (NULL != *ptr) {
+ printf("%d %d \"%s\"\n",
+ dk4str8_is_bool(*ptr),
+ dk4str8_is_on(*ptr),
+ *ptr
+ );
+ ptr++;
+ }
+
+
+#line 83 "test-bool.ctr"
+
+
+#line 84 "test-bool.ctr"
+ return 0;
+}
+
diff --git a/support/dktools/test-bool.ctr b/support/dktools/test-bool.ctr
new file mode 100644
index 0000000000..c717e2f2f5
--- /dev/null
+++ b/support/dktools/test-bool.ctr
@@ -0,0 +1,86 @@
+
+#include "dk4conf.h"
+#include "dk4str8.h"
+
+#include <stdio.h>
+
+
+
+$!trace-include
+
+
+
+static const char * const teststr[] = {
+$!string-table
+ja
+nein
+yes
+no
+y
+n
+on
+off
+o
+of
+true
+tru
+tr
+t
+false
+fals
+fal
+fa
+f
+0
+1
+2
++
+-
+*
+/
+JA
+J
+NEIN
+N
+YES
+NO
+YE
+N
+Y
+OFF
+OF
+O
+OfF
+TRUE
+TRU
+TR
+T
+B
+FALSE
+FALSCH
+FAL
+FA
+F
+0815
+$!end
+};
+
+int main(void)
+{
+ const char * const *ptr;
+ $!trace-init test-bool.deb
+ $? "+ main"
+ ptr = teststr;
+ while (NULL != *ptr) {
+ printf("%d %d \"%s\"\n",
+ dk4str8_is_bool(*ptr),
+ dk4str8_is_on(*ptr),
+ *ptr
+ );
+ ptr++;
+ }
+ $? "- main"
+ $!trace-end
+ return 0;
+}
+
diff --git a/support/dktools/test-container.cpp b/support/dktools/test-container.cpp
new file mode 100644
index 0000000000..15b541c8f8
--- /dev/null
+++ b/support/dktools/test-container.cpp
@@ -0,0 +1,132 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-container.cpt
+*/
+
+/** @file test-container.cpp The test-container module.
+*/
+
+
+#line 1 "test-container.cpt"
+
+
+
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if DK4_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if DK4_TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else
+#if DK4_HAVE_TIME_H
+#include <time.h>
+#else
+#if DK4_HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#endif
+#endif
+
+#include "Dk4Comparable.h"
+#include "Dk4Container.h"
+
+class RandomNumber: public DkTools4::Comparable
+{
+ private:
+
+ int i;
+
+ public:
+
+ RandomNumber(void);
+
+ ~RandomNumber();
+
+ int getNumber() const;
+
+ int compareAgainst(void const *data, int cr) const;
+};
+
+
+
+RandomNumber::RandomNumber(void)
+{
+ i = rand();
+}
+
+
+
+RandomNumber::~RandomNumber()
+{
+ fputs("Destructor for RandomNumber\n", stdout);
+}
+
+
+
+int
+RandomNumber::getNumber() const
+{
+ return i;
+}
+
+
+
+int
+RandomNumber::compareAgainst(void const *data, int cr) const
+{
+ int back = 0;
+ int j;
+ RandomNumber *pr = (RandomNumber *)data;
+ j = pr->getNumber();
+ if(i > j) {
+ back = 1;
+ } else {
+ if(i < j) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+int main(int argc, char *argv[])
+{
+ int i;
+ time_t timer;
+ RandomNumber *rndn;
+
+ time(&timer);
+ srand(timer);
+ try {
+ DkTools4::Container<RandomNumber> container(0, true);
+ for(i = 0; i < 100; i++) {
+ RandomNumber *rndn = new RandomNumber();
+ if(!container.add(rndn)) {
+ delete rndn ;
+ }
+ }
+ container.reset();
+ i = 0;
+ while(NULL != (rndn = container.next())) {
+ printf("%04d: %d\n", ++i, rndn->getNumber());
+#if 0
+ if (50 == i) { throw(std::bad_alloc()); }
+#endif
+ }
+ }
+ catch(...) {
+ printf("Poese Exception beim Container\n");
+ }
+ return 0;
+}
+
+
diff --git a/support/dktools/test-container.cpt b/support/dktools/test-container.cpt
new file mode 100644
index 0000000000..22b416314d
--- /dev/null
+++ b/support/dktools/test-container.cpt
@@ -0,0 +1,121 @@
+
+
+%% module
+
+
+#include "dk4conf.h"
+
+#if DK4_HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if DK4_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if DK4_TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else
+#if DK4_HAVE_TIME_H
+#include <time.h>
+#else
+#if DK4_HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#endif
+#endif
+
+#include "Dk4Comparable.h"
+#include "Dk4Container.h"
+
+class RandomNumber: public DkTools4::Comparable
+{
+ private:
+
+ int i;
+
+ public:
+
+ RandomNumber(void);
+
+ ~RandomNumber();
+
+ int getNumber() const;
+
+ int compareAgainst(void const *data, int cr) const;
+};
+
+
+
+RandomNumber::RandomNumber(void)
+{
+ i = rand();
+}
+
+
+
+RandomNumber::~RandomNumber()
+{
+ fputs("Destructor for RandomNumber\n", stdout);
+}
+
+
+
+int
+RandomNumber::getNumber() const
+{
+ return i;
+}
+
+
+
+int
+RandomNumber::compareAgainst(void const *data, int cr) const
+{
+ int back = 0;
+ int j;
+ RandomNumber *pr = (RandomNumber *)data;
+ j = pr->getNumber();
+ if(i > j) {
+ back = 1;
+ } else {
+ if(i < j) {
+ back = -1;
+ }
+ }
+ return back;
+}
+
+
+
+int main(int argc, char *argv[])
+{
+ int i;
+ time_t timer;
+ RandomNumber *rndn;
+
+ time(&timer);
+ srand(timer);
+ try {
+ DkTools4::Container<RandomNumber> container(0, true);
+ for(i = 0; i < 100; i++) {
+ RandomNumber *rndn = new RandomNumber();
+ if(!container.add(rndn)) {
+ delete rndn ;
+ }
+ }
+ container.reset();
+ i = 0;
+ while(NULL != (rndn = container.next())) {
+ printf("%04d: %d\n", ++i, rndn->getNumber());
+#if 0
+ if (50 == i) { throw(std::bad_alloc()); }
+#endif
+ }
+ }
+ catch(...) {
+ printf("Poese Exception beim Container\n");
+ }
+ return 0;
+}
+
+
diff --git a/support/dktools/test-deldir.c b/support/dktools/test-deldir.c
new file mode 100644
index 0000000000..3055308a58
--- /dev/null
+++ b/support/dktools/test-deldir.c
@@ -0,0 +1,132 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-deldir.ctr
+*/
+
+/** @file test-deldir.c The test-deldir module.
+*/
+
+
+#line 1 "test-deldir.ctr"
+
+
+#include <stdio.h>
+
+
+
+#include "dk4app.h"
+#include "dk4fput.h"
+#include "dk4appmkdh.h"
+
+
+
+
+
+#line 14 "test-deldir.ctr"
+
+
+
+static const dkChar * const test_mkdir_help_text[] = {
+dkT("This is a test program to create directories."),
+NULL
+
+
+#line 21 "test-deldir.ctr"
+};
+
+static const dkChar * const test_mkdir_license_text[] = {
+dkT("Copyright (c) 2014-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions"),
+dkT("are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above copyright notice,"),
+dkT(" this list of conditions and the following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("* Neither the name of the Dirk Krause nor the names of contributors may be"),
+dkT(" used to endorse or promote products derived from this software without"),
+dkT(" specific prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS"),
+dkT("\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT"),
+dkT("LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR"),
+dkT("A PARTICULAR PURPOSE ARE DISCLAIMED."),
+dkT(""),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS"),
+dkT("OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)"),
+dkT("HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,"),
+dkT("STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN"),
+dkT("ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE"),
+dkT("POSSIBILITY OF SUCH DAMAGE."),
+NULL
+
+
+#line 55 "test-deldir.ctr"
+};
+
+static dk4_app_t *app = NULL;
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ int res;
+ int nargs;
+ int i;
+ const dkChar *arg;
+
+
+#line 75 "test-deldir.ctr"
+ app = dk4app_open_cmd(
+ argc, argv, NULL, 0,
+ dkT("dktools-4-test"), dkT("1.0.0"),
+ dkT("test-mkdir.txt"), test_mkdir_help_text,
+ test_mkdir_license_text
+ );
+ if (NULL != app) {
+
+#line 82 "test-deldir.ctr"
+ nargs = dk4app_get_argc(app);
+ if (0 < nargs) {
+ dk4fput_initialize_stdout();
+ for (i = 0; i < nargs; i++) {
+ arg = dk4app_get_argv(app, i);
+ if (NULL != arg) {
+ res = dk4app_del_dir(arg, app);
+ dk4fputs(arg, stdout, NULL);
+ dk4fputc(dkT(' '), stdout, NULL);
+ if (0 < res) {
+ dk4fputs(dkT("SUCCESS"), stdout, NULL);
+ } else {
+ dk4fputs(dkT("FAILED"), stdout, NULL);
+ }
+ dk4fputc(dkT('\n'), stdout, NULL);
+ }
+ }
+ }
+ dk4app_close(app);
+ } else {
+
+#line 102 "test-deldir.ctr"
+ }
+
+
+#line 104 "test-deldir.ctr"
+ return 0;
+}
+
diff --git a/support/dktools/test-deldir.ctr b/support/dktools/test-deldir.ctr
new file mode 100644
index 0000000000..15d6008155
--- /dev/null
+++ b/support/dktools/test-deldir.ctr
@@ -0,0 +1,106 @@
+
+
+#include <stdio.h>
+
+
+
+#include "dk4app.h"
+#include "dk4fput.h"
+#include "dk4appmkdh.h"
+
+
+
+$!trace-include
+
+
+
+static const dkChar * const test_mkdir_help_text[] = {
+$!text macro=dkT
+This is a test program to create directories.
+$!end
+};
+
+static const dkChar * const test_mkdir_license_text[] = {
+$!text macro=dkT
+Copyright (c) 2014-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+$!end
+};
+
+static dk4_app_t *app = NULL;
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ int res;
+ int nargs;
+ int i;
+ const dkChar *arg;
+ $!trace-init test-deldir.deb
+ app = dk4app_open_cmd(
+ argc, argv, NULL, 0,
+ dkT("dktools-4-test"), dkT("1.0.0"),
+ dkT("test-mkdir.txt"), test_mkdir_help_text,
+ test_mkdir_license_text
+ );
+ if (NULL != app) { $? ". app"
+ nargs = dk4app_get_argc(app);
+ if (0 < nargs) {
+ dk4fput_initialize_stdout();
+ for (i = 0; i < nargs; i++) {
+ arg = dk4app_get_argv(app, i);
+ if (NULL != arg) {
+ res = dk4app_del_dir(arg, app);
+ dk4fputs(arg, stdout, NULL);
+ dk4fputc(dkT(' '), stdout, NULL);
+ if (0 < res) {
+ dk4fputs(dkT("SUCCESS"), stdout, NULL);
+ } else {
+ dk4fputs(dkT("FAILED"), stdout, NULL);
+ }
+ dk4fputc(dkT('\n'), stdout, NULL);
+ }
+ }
+ }
+ dk4app_close(app);
+ } else { $? "! app"
+ }
+ $!trace-end
+ return 0;
+}
+
diff --git a/support/dktools/test-deldirwc.c b/support/dktools/test-deldirwc.c
new file mode 100644
index 0000000000..81b04baa0d
--- /dev/null
+++ b/support/dktools/test-deldirwc.c
@@ -0,0 +1,29 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-deldirwc.ctr
+*/
+
+/** @file test-deldirwc.c The test-deldirwc module.
+*/
+
+
+#line 1 "test-deldirwc.ctr"
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4deldirwc.h"
+
+
+int main(void)
+{
+ int exval = 1;
+ if (0 != dk4delete_directory_wc(L".\\%SystemDrive%", NULL)) {
+ exval = 0;
+ }
+ return exval;
+}
+
diff --git a/support/dktools/test-deldirwc.ctr b/support/dktools/test-deldirwc.ctr
new file mode 100644
index 0000000000..4bf55490e8
--- /dev/null
+++ b/support/dktools/test-deldirwc.ctr
@@ -0,0 +1,17 @@
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4deldirwc.h"
+
+
+int main(void)
+{
+ int exval = 1;
+ if (0 != dk4delete_directory_wc(L".\\%SystemDrive%", NULL)) {
+ exval = 0;
+ }
+ return exval;
+}
+
diff --git a/support/dktools/test-deltree.c b/support/dktools/test-deltree.c
new file mode 100644
index 0000000000..a6feaa152c
--- /dev/null
+++ b/support/dktools/test-deltree.c
@@ -0,0 +1,132 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-deltree.ctr
+*/
+
+/** @file test-deltree.c The test-deltree module.
+*/
+
+
+#line 1 "test-deltree.ctr"
+
+
+#include <stdio.h>
+
+
+
+#include "dk4app.h"
+#include "dk4fput.h"
+#include "dk4appmkdh.h"
+
+
+
+
+
+#line 14 "test-deltree.ctr"
+
+
+
+static const dkChar * const test_mkdir_help_text[] = {
+dkT("This is a test program to create directories."),
+NULL
+
+
+#line 21 "test-deltree.ctr"
+};
+
+static const dkChar * const test_mkdir_license_text[] = {
+dkT("Copyright (c) 2014-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions"),
+dkT("are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above copyright notice,"),
+dkT(" this list of conditions and the following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("* Neither the name of the Dirk Krause nor the names of contributors may be"),
+dkT(" used to endorse or promote products derived from this software without"),
+dkT(" specific prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS"),
+dkT("\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT"),
+dkT("LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR"),
+dkT("A PARTICULAR PURPOSE ARE DISCLAIMED."),
+dkT(""),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS"),
+dkT("OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)"),
+dkT("HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,"),
+dkT("STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN"),
+dkT("ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE"),
+dkT("POSSIBILITY OF SUCH DAMAGE."),
+NULL
+
+
+#line 55 "test-deltree.ctr"
+};
+
+static dk4_app_t *app = NULL;
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ int res;
+ int nargs;
+ int i;
+ const dkChar *arg;
+
+
+#line 75 "test-deltree.ctr"
+ app = dk4app_open_cmd(
+ argc, argv, NULL, 0,
+ dkT("dktools-4-test"), dkT("1.0.0"),
+ dkT("test-mkdir.txt"), test_mkdir_help_text,
+ test_mkdir_license_text
+ );
+ if (NULL != app) {
+
+#line 82 "test-deltree.ctr"
+ nargs = dk4app_get_argc(app);
+ if (0 < nargs) {
+ dk4fput_initialize_stdout();
+ for (i = 0; i < nargs; i++) {
+ arg = dk4app_get_argv(app, i);
+ if (NULL != arg) {
+ res = dk4app_del_tree(arg, app);
+ dk4fputs(arg, stdout, NULL);
+ dk4fputc(dkT(' '), stdout, NULL);
+ if (0 < res) {
+ dk4fputs(dkT("SUCCESS"), stdout, NULL);
+ } else {
+ dk4fputs(dkT("FAILED"), stdout, NULL);
+ }
+ dk4fputc(dkT('\n'), stdout, NULL);
+ }
+ }
+ }
+ dk4app_close(app);
+ } else {
+
+#line 102 "test-deltree.ctr"
+ }
+
+
+#line 104 "test-deltree.ctr"
+ return 0;
+}
+
diff --git a/support/dktools/test-deltree.ctr b/support/dktools/test-deltree.ctr
new file mode 100644
index 0000000000..83953eb9c1
--- /dev/null
+++ b/support/dktools/test-deltree.ctr
@@ -0,0 +1,106 @@
+
+
+#include <stdio.h>
+
+
+
+#include "dk4app.h"
+#include "dk4fput.h"
+#include "dk4appmkdh.h"
+
+
+
+$!trace-include
+
+
+
+static const dkChar * const test_mkdir_help_text[] = {
+$!text macro=dkT
+This is a test program to create directories.
+$!end
+};
+
+static const dkChar * const test_mkdir_license_text[] = {
+$!text macro=dkT
+Copyright (c) 2014-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+$!end
+};
+
+static dk4_app_t *app = NULL;
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ int res;
+ int nargs;
+ int i;
+ const dkChar *arg;
+ $!trace-init test-deltree.deb
+ app = dk4app_open_cmd(
+ argc, argv, NULL, 0,
+ dkT("dktools-4-test"), dkT("1.0.0"),
+ dkT("test-mkdir.txt"), test_mkdir_help_text,
+ test_mkdir_license_text
+ );
+ if (NULL != app) { $? ". app"
+ nargs = dk4app_get_argc(app);
+ if (0 < nargs) {
+ dk4fput_initialize_stdout();
+ for (i = 0; i < nargs; i++) {
+ arg = dk4app_get_argv(app, i);
+ if (NULL != arg) {
+ res = dk4app_del_tree(arg, app);
+ dk4fputs(arg, stdout, NULL);
+ dk4fputc(dkT(' '), stdout, NULL);
+ if (0 < res) {
+ dk4fputs(dkT("SUCCESS"), stdout, NULL);
+ } else {
+ dk4fputs(dkT("FAILED"), stdout, NULL);
+ }
+ dk4fputc(dkT('\n'), stdout, NULL);
+ }
+ }
+ }
+ dk4app_close(app);
+ } else { $? "! app"
+ }
+ $!trace-end
+ return 0;
+}
+
diff --git a/support/dktools/test-dk4c8dbl.c b/support/dktools/test-dk4c8dbl.c
new file mode 100644
index 0000000000..a07d5b0662
--- /dev/null
+++ b/support/dktools/test-dk4c8dbl.c
@@ -0,0 +1,260 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-dk4c8dbl.ctr
+*/
+
+/** @file test-dk4c8dbl.c The test-dk4c8dbl module.
+*/
+
+
+#line 1 "test-dk4c8dbl.ctr"
+
+#include <stdio.h>
+
+#include "dk4c8dbl.h"
+
+
+
+
+#line 8 "test-dk4c8dbl.ctr"
+
+
+
+static const char * const test_strings[] = {
+/* 0 */
+"1.0",
+
+/* 1 */
+"0.1",
+
+/* 2 */
+"0.01",
+
+/* 3 */
+"10.0",
+
+/* 4 */
+"100.0",
+
+/* 5 */
+"1.00500",
+
+/* 6 */
+"0.10500",
+
+/* 7 */
+"0.010500",
+
+/* 8 */
+"10.00500",
+
+/* 9 */
+"100.00500",
+
+/* 10 */
+"100.00500e-5",
+
+/* 11 */
+"100.00500e-4",
+
+/* 12 */
+"100.00500e-3",
+
+/* 13 */
+"100.00500e-2",
+
+/* 14 */
+"100.00500e-1",
+
+/* 15 */
+"100.00500",
+
+/* 16 */
+"100.00500e1",
+
+/* 17 */
+"100.00500e2",
+
+/* 18 */
+"100.00500e3",
+
+/* 19 */
+"100.00500e4",
+
+/* 20 */
+"100.00500e5",
+
+/* 21 */
+"100.00500e6",
+
+/* 22 */
+"100.00500e7",
+
+/* 23 */
+"100.00500e8",
+
+/* 24 */
+"100.00500e9",
+
+/* 25 */
+"1.25e3",
+
+/* 26 */
+"1.25e2",
+
+/* 27 */
+"1.25e1",
+
+/* 28 */
+"1.25e0",
+
+/* 29 */
+"1.25e-1",
+
+/* 30 */
+"1.25e-2",
+
+/* 31 */
+"1.25e-3",
+
+/* 32 */
+"-1.0",
+
+/* 33 */
+"-0.1",
+
+/* 34 */
+"-0.01",
+
+/* 35 */
+"-10.0",
+
+/* 36 */
+"-100.0",
+
+/* 37 */
+"-1.00500",
+
+/* 38 */
+"-0.10500",
+
+/* 39 */
+"-0.010500",
+
+/* 40 */
+"-10.00500",
+
+/* 41 */
+"-100.00500",
+
+/* 42 */
+"-100.00500e-5",
+
+/* 43 */
+"-100.00500e-4",
+
+/* 44 */
+"-100.00500e-3",
+
+/* 45 */
+"-100.00500e-2",
+
+/* 46 */
+"-100.00500e-1",
+
+/* 47 */
+"-100.00500",
+
+/* 48 */
+"-100.00500e1",
+
+/* 49 */
+"-100.00500e2",
+
+/* 50 */
+"-100.00500e3",
+
+/* 51 */
+"-100.00500e4",
+
+/* 52 */
+"-100.00500e5",
+
+/* 53 */
+"-100.00500e6",
+
+/* 54 */
+"-100.00500e7",
+
+/* 55 */
+"-100.00500e8",
+
+/* 56 */
+"-100.00500e9",
+
+/* 57 */
+"-1.25e3",
+
+/* 58 */
+"-1.25e2",
+
+/* 59 */
+"-1.25e1",
+
+/* 60 */
+"-1.25e0",
+
+/* 61 */
+"-1.25e-1",
+
+/* 62 */
+"-1.25e-2",
+
+/* 63 */
+"-1.25e-3",
+
+/* 64 */
+"000500e3",
+
+/* 65 */
+"5.50500000",
+
+/* 66 */
+"000500",
+
+NULL
+
+
+#line 81 "test-dk4c8dbl.ctr"
+};
+
+int main(int argc, char *argv[])
+{
+ const char * const *ptr;
+
+
+
+#line 88 "test-dk4c8dbl.ctr"
+
+
+#line 89 "test-dk4c8dbl.ctr"
+ ptr = test_strings;
+ while (NULL != *ptr) {
+ fputs(*ptr, stdout);
+ fputc('\n', stdout);
+ dk4c8dbl_str_double_to_file(stdout, *ptr, NULL);
+ fputc('\n', stdout);
+ fputc('\n', stdout);
+ ptr++;
+ }
+
+
+#line 99 "test-dk4c8dbl.ctr"
+
+
+#line 100 "test-dk4c8dbl.ctr"
+ return 0;
+}
+
diff --git a/support/dktools/test-dk4c8dbl.ctr b/support/dktools/test-dk4c8dbl.ctr
new file mode 100644
index 0000000000..75d281e15b
--- /dev/null
+++ b/support/dktools/test-dk4c8dbl.ctr
@@ -0,0 +1,102 @@
+
+#include <stdio.h>
+
+#include "dk4c8dbl.h"
+
+
+$!trace-include
+
+
+
+static const char * const test_strings[] = {
+$!string-table
+1.0
+0.1
+0.01
+10.0
+100.0
+1.00500
+0.10500
+0.010500
+10.00500
+100.00500
+100.00500e-5
+100.00500e-4
+100.00500e-3
+100.00500e-2
+100.00500e-1
+100.00500
+100.00500e1
+100.00500e2
+100.00500e3
+100.00500e4
+100.00500e5
+100.00500e6
+100.00500e7
+100.00500e8
+100.00500e9
+1.25e3
+1.25e2
+1.25e1
+1.25e0
+1.25e-1
+1.25e-2
+1.25e-3
+-1.0
+-0.1
+-0.01
+-10.0
+-100.0
+-1.00500
+-0.10500
+-0.010500
+-10.00500
+-100.00500
+-100.00500e-5
+-100.00500e-4
+-100.00500e-3
+-100.00500e-2
+-100.00500e-1
+-100.00500
+-100.00500e1
+-100.00500e2
+-100.00500e3
+-100.00500e4
+-100.00500e5
+-100.00500e6
+-100.00500e7
+-100.00500e8
+-100.00500e9
+-1.25e3
+-1.25e2
+-1.25e1
+-1.25e0
+-1.25e-1
+-1.25e-2
+-1.25e-3
+000500e3
+5.50500000
+000500
+$!end
+};
+
+int main(int argc, char *argv[])
+{
+ const char * const *ptr;
+
+ $!trace-init test-ppptf.deb
+ $? "+ main"
+ ptr = test_strings;
+ while (NULL != *ptr) {
+ fputs(*ptr, stdout);
+ fputc('\n', stdout);
+ dk4c8dbl_str_double_to_file(stdout, *ptr, NULL);
+ fputc('\n', stdout);
+ fputc('\n', stdout);
+ ptr++;
+ }
+ $? "- main"
+ $!trace-end
+ return 0;
+}
+
diff --git a/support/dktools/test-dk4dir.c b/support/dktools/test-dk4dir.c
new file mode 100644
index 0000000000..003386e299
--- /dev/null
+++ b/support/dktools/test-dk4dir.c
@@ -0,0 +1,141 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-dk4dir.ctr
+*/
+
+/** @file test-dk4dir.c The test-dk4dir module.
+*/
+
+
+#line 1 "test-dk4dir.ctr"
+
+
+#include <stdio.h>
+
+
+
+#include "dk4app.h"
+#include "dk4fput.h"
+#include "dk4appmkdh.h"
+#include "dk4dir.h"
+
+
+
+
+
+#line 15 "test-dk4dir.ctr"
+
+
+
+static const dkChar * const test_mkdir_help_text[] = {
+dkT("This is a test program to create directories."),
+NULL
+
+
+#line 22 "test-dk4dir.ctr"
+};
+
+static const dkChar * const test_mkdir_license_text[] = {
+dkT("Copyright (c) 2014-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions"),
+dkT("are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above copyright notice,"),
+dkT(" this list of conditions and the following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("* Neither the name of the Dirk Krause nor the names of contributors may be"),
+dkT(" used to endorse or promote products derived from this software without"),
+dkT(" specific prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS"),
+dkT("\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT"),
+dkT("LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR"),
+dkT("A PARTICULAR PURPOSE ARE DISCLAIMED."),
+dkT(""),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS"),
+dkT("OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)"),
+dkT("HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,"),
+dkT("STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN"),
+dkT("ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE"),
+dkT("POSSIBILITY OF SUCH DAMAGE."),
+NULL
+
+
+#line 56 "test-dk4dir.ctr"
+};
+
+static dk4_app_t *app = NULL;
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ int nargs;
+ int i;
+ const dkChar *arg;
+ const dkChar *fn;
+ dk4_dir_t *dir;
+
+
+#line 77 "test-dk4dir.ctr"
+ app = dk4app_open_cmd(
+ argc, argv, NULL, 0,
+ dkT("dktools-4-test"), dkT("1.0.0"),
+ dkT("test-mkdir.txt"), test_mkdir_help_text,
+ test_mkdir_license_text
+ );
+ if (NULL != app) {
+
+#line 84 "test-dk4dir.ctr"
+ nargs = dk4app_get_argc(app);
+ if (0 < nargs) {
+ dk4fput_initialize_stdout();
+ for (i = 0; i < nargs; i++) {
+ arg = dk4app_get_argv(app, i);
+ if (NULL != arg) {
+ dk4fputs(arg, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ dir = dk4dir_open(arg, DK4_DIR_OPEN_SORTED, NULL);
+ if (NULL != dir) {
+ while (NULL != (fn = dk4dir_next_dir(dir))) {
+ dk4fputs(dkT("D "), stdout, NULL);
+ dk4fputs(fn, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ }
+ while (NULL != (fn = dk4dir_next_file(dir))) {
+ dk4fputs(dkT("F "), stdout, NULL);
+ dk4fputs(fn, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ }
+ dk4dir_close(dir);
+ }
+ }
+ }
+ }
+ dk4app_close(app);
+ } else {
+
+#line 111 "test-dk4dir.ctr"
+ }
+
+
+#line 113 "test-dk4dir.ctr"
+ return 0;
+}
+
diff --git a/support/dktools/test-dk4dir.ctr b/support/dktools/test-dk4dir.ctr
new file mode 100644
index 0000000000..d83d56e1f5
--- /dev/null
+++ b/support/dktools/test-dk4dir.ctr
@@ -0,0 +1,115 @@
+
+
+#include <stdio.h>
+
+
+
+#include "dk4app.h"
+#include "dk4fput.h"
+#include "dk4appmkdh.h"
+#include "dk4dir.h"
+
+
+
+$!trace-include
+
+
+
+static const dkChar * const test_mkdir_help_text[] = {
+$!text macro=dkT
+This is a test program to create directories.
+$!end
+};
+
+static const dkChar * const test_mkdir_license_text[] = {
+$!text macro=dkT
+Copyright (c) 2014-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+$!end
+};
+
+static dk4_app_t *app = NULL;
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ int nargs;
+ int i;
+ const dkChar *arg;
+ const dkChar *fn;
+ dk4_dir_t *dir;
+ $!trace-init test-mkdir.deb
+ app = dk4app_open_cmd(
+ argc, argv, NULL, 0,
+ dkT("dktools-4-test"), dkT("1.0.0"),
+ dkT("test-mkdir.txt"), test_mkdir_help_text,
+ test_mkdir_license_text
+ );
+ if (NULL != app) { $? ". app"
+ nargs = dk4app_get_argc(app);
+ if (0 < nargs) {
+ dk4fput_initialize_stdout();
+ for (i = 0; i < nargs; i++) {
+ arg = dk4app_get_argv(app, i);
+ if (NULL != arg) {
+ dk4fputs(arg, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ dir = dk4dir_open(arg, DK4_DIR_OPEN_SORTED, NULL);
+ if (NULL != dir) {
+ while (NULL != (fn = dk4dir_next_dir(dir))) {
+ dk4fputs(dkT("D "), stdout, NULL);
+ dk4fputs(fn, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ }
+ while (NULL != (fn = dk4dir_next_file(dir))) {
+ dk4fputs(dkT("F "), stdout, NULL);
+ dk4fputs(fn, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ }
+ dk4dir_close(dir);
+ }
+ }
+ }
+ }
+ dk4app_close(app);
+ } else { $? "! app"
+ }
+ $!trace-end
+ return 0;
+}
+
diff --git a/support/dktools/test-dk4dir08.c b/support/dktools/test-dk4dir08.c
new file mode 100644
index 0000000000..8f901786ef
--- /dev/null
+++ b/support/dktools/test-dk4dir08.c
@@ -0,0 +1,54 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-dk4dir08.ctr
+*/
+
+/** @file test-dk4dir08.c The test-dk4dir08 module.
+*/
+
+
+#line 1 "test-dk4dir08.ctr"
+
+
+#include <stdio.h>
+
+#include "dk4dir.h"
+#include "dk4dir08.h"
+
+
+int main(int argc, char *argv[])
+{
+ dk4_dir_c8_t *dir;
+ const char *fn;
+ int i;
+
+
+#line 15 "test-dk4dir08.ctr"
+
+
+#line 16 "test-dk4dir08.ctr"
+ for (i = 1; i < argc; i++) {
+ printf("argv[%02d] = \"%s\"\n", i, argv[i]);
+ dir = dk4dir_c8_open(argv[i], DK4_DIR_OPEN_SORTED, NULL);
+ if (NULL != dir) {
+ while (NULL != (fn = dk4dir_c8_next_dir(dir))) {
+ printf("D %s\n", fn);
+ }
+ while (NULL != (fn = dk4dir_c8_next_file(dir))) {
+ printf("F %s\n", fn);
+ }
+ dk4dir_c8_close(dir);
+ }
+ }
+
+
+#line 30 "test-dk4dir08.ctr"
+
+
+#line 31 "test-dk4dir08.ctr"
+ return 0;
+}
+
+
diff --git a/support/dktools/test-dk4dir08.ctr b/support/dktools/test-dk4dir08.ctr
new file mode 100644
index 0000000000..b534f89aad
--- /dev/null
+++ b/support/dktools/test-dk4dir08.ctr
@@ -0,0 +1,34 @@
+
+
+#include <stdio.h>
+
+#include "dk4dir.h"
+#include "dk4dir08.h"
+
+
+int main(int argc, char *argv[])
+{
+ dk4_dir_c8_t *dir;
+ const char *fn;
+ int i;
+ $!trace-init dk4dir08.deb
+ $? "+ main"
+ for (i = 1; i < argc; i++) {
+ printf("argv[%02d] = \"%s\"\n", i, argv[i]);
+ dir = dk4dir_c8_open(argv[i], DK4_DIR_OPEN_SORTED, NULL);
+ if (NULL != dir) {
+ while (NULL != (fn = dk4dir_c8_next_dir(dir))) {
+ printf("D %s\n", fn);
+ }
+ while (NULL != (fn = dk4dir_c8_next_file(dir))) {
+ printf("F %s\n", fn);
+ }
+ dk4dir_c8_close(dir);
+ }
+ }
+ $? "- main"
+ $!trace-end
+ return 0;
+}
+
+
diff --git a/support/dktools/test-dk4enc.c b/support/dktools/test-dk4enc.c
new file mode 100644
index 0000000000..160a8a6c5a
--- /dev/null
+++ b/support/dktools/test-dk4enc.c
@@ -0,0 +1,41 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-dk4enc.ctr
+*/
+
+/** @file test-dk4enc.c The test-dk4enc module.
+*/
+
+
+#line 1 "test-dk4enc.ctr"
+
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4enc.h"
+
+
+
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ dk4_er_t er;
+ int enc = 0;
+ int bom = 0;
+ if (argc > 1) {
+ dk4error_init(&er);
+ if (0 != dk4enc_find(&enc, &bom, argv[1], &er)) {
+ printf("Encoding: %d\nBOM: %d\n", enc, bom);
+ } else {
+ printf("Fehlgeschlagen, Grund: %d\n", er.ec);
+ }
+ }
+ return 0;
+}
+
diff --git a/support/dktools/test-dk4enc.ctr b/support/dktools/test-dk4enc.ctr
new file mode 100644
index 0000000000..dda4e78470
--- /dev/null
+++ b/support/dktools/test-dk4enc.ctr
@@ -0,0 +1,29 @@
+
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4error.h"
+#include "dk4enc.h"
+
+
+
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ dk4_er_t er;
+ int enc = 0;
+ int bom = 0;
+ if (argc > 1) {
+ dk4error_init(&er);
+ if (0 != dk4enc_find(&enc, &bom, argv[1], &er)) {
+ printf("Encoding: %d\nBOM: %d\n", enc, bom);
+ } else {
+ printf("Fehlgeschlagen, Grund: %d\n", er.ec);
+ }
+ }
+ return 0;
+}
+
diff --git a/support/dktools/test-dk4exep8.c b/support/dktools/test-dk4exep8.c
new file mode 100644
index 0000000000..d5d6c58cb4
--- /dev/null
+++ b/support/dktools/test-dk4exep8.c
@@ -0,0 +1,48 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-dk4exep8.ctr
+*/
+
+/** @file test-dk4exep8.c The test-dk4exep8 module.
+*/
+
+
+#line 1 "test-dk4exep8.ctr"
+
+#include <stdio.h>
+
+#include "dk4exep8.h"
+
+
+
+
+#line 8 "test-dk4exep8.ctr"
+
+
+int main(int argc, char *argv[])
+{
+ char buf[256];
+ dk4_er_t er;
+
+
+#line 15 "test-dk4exep8.ctr"
+
+
+#line 16 "test-dk4exep8.ctr"
+ dk4error_init(&er);
+ if (0 != dk4execpath_c8(buf, sizeof(buf), argv[0], &er)) {
+ printf("%s\n", buf);
+ } else {
+ printf("ERROR: Not found!n");
+ }
+
+
+#line 23 "test-dk4exep8.ctr"
+
+
+#line 24 "test-dk4exep8.ctr"
+ return 0;
+}
+
diff --git a/support/dktools/test-dk4exep8.ctr b/support/dktools/test-dk4exep8.ctr
new file mode 100644
index 0000000000..00285a6b00
--- /dev/null
+++ b/support/dktools/test-dk4exep8.ctr
@@ -0,0 +1,26 @@
+
+#include <stdio.h>
+
+#include "dk4exep8.h"
+
+
+$!trace-include
+
+
+int main(int argc, char *argv[])
+{
+ char buf[256];
+ dk4_er_t er;
+ $!trace-init test-dk4exep8.deb"
+ $? "+ main"
+ dk4error_init(&er);
+ if (0 != dk4execpath_c8(buf, sizeof(buf), argv[0], &er)) {
+ printf("%s\n", buf);
+ } else {
+ printf("ERROR: Not found!n");
+ }
+ $? "- main"
+ $!trace-end
+ return 0;
+}
+
diff --git a/support/dktools/test-dk4loc.c b/support/dktools/test-dk4loc.c
new file mode 100644
index 0000000000..094b5b2769
--- /dev/null
+++ b/support/dktools/test-dk4loc.c
@@ -0,0 +1,86 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-dk4loc.ctr
+*/
+
+/** @file test-dk4loc.c The test-dk4loc module.
+*/
+
+
+#line 1 "test-dk4loc.ctr"
+
+#include <stdio.h>
+
+
+#include "dk4loc.h"
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+
+
+
+
+#line 14 "test-dk4loc.ctr"
+
+
+
+dkChar langbuf[16];
+dkChar regbuf[16];
+
+
+
+int main(void)
+{
+ dk4_er_t er;
+ int encoding;
+ int res;
+
+
+
+#line 29 "test-dk4loc.ctr"
+
+
+#line 30 "test-dk4loc.ctr"
+ dk4error_init(&er);
+
+
+#line 32 "test-dk4loc.ctr"
+ res = dk4loc_get_settings(
+ langbuf, DK4_SIZEOF(langbuf,dkChar),
+ regbuf, DK4_SIZEOF(regbuf,dkChar),
+ &encoding, &er
+ );
+
+
+#line 38 "test-dk4loc.ctr"
+ if (0 != res) {
+
+#line 39 "test-dk4loc.ctr"
+ printf("Einstellungen gefunden.\n");
+#if DK4_ON_WINDOWS
+ printf("Language: \"%ls\"\n", langbuf);
+ printf("Region: \"%ls\"\n", regbuf);
+ printf("Encoding: %d\n", encoding);
+#else
+ printf("Language: \"%s\"\n", langbuf);
+ printf("Region: \"%s\"\n", regbuf);
+ printf("Encoding: %d\n", encoding);
+#endif
+ } else {
+
+#line 50 "test-dk4loc.ctr"
+ printf("Einstellungen nicht gefunden.\n");
+ printf("Fehlercode: %d\n", er.ec);
+ }
+
+
+#line 54 "test-dk4loc.ctr"
+
+
+#line 55 "test-dk4loc.ctr"
+ return 0;
+}
diff --git a/support/dktools/test-dk4loc.ctr b/support/dktools/test-dk4loc.ctr
new file mode 100644
index 0000000000..e4c2aa0970
--- /dev/null
+++ b/support/dktools/test-dk4loc.ctr
@@ -0,0 +1,56 @@
+
+#include <stdio.h>
+
+
+#include "dk4loc.h"
+
+#ifndef DK4MEM_H_INCLUDED
+#include "dk4mem.h"
+#endif
+
+
+
+$!trace-include
+
+
+
+dkChar langbuf[16];
+dkChar regbuf[16];
+
+
+
+int main(void)
+{
+ dk4_er_t er;
+ int encoding;
+ int res;
+
+ $!trace-init test-dk4loc.deb
+ $? "+ main"
+ dk4error_init(&er);
+ $? ". ready to retrieve settings"
+ res = dk4loc_get_settings(
+ langbuf, DK4_SIZEOF(langbuf,dkChar),
+ regbuf, DK4_SIZEOF(regbuf,dkChar),
+ &encoding, &er
+ );
+ $? ". settings retrieved"
+ if (0 != res) { $? ". success"
+ printf("Einstellungen gefunden.\n");
+#if DK4_ON_WINDOWS
+ printf("Language: \"%ls\"\n", langbuf);
+ printf("Region: \"%ls\"\n", regbuf);
+ printf("Encoding: %d\n", encoding);
+#else
+ printf("Language: \"%s\"\n", langbuf);
+ printf("Region: \"%s\"\n", regbuf);
+ printf("Encoding: %d\n", encoding);
+#endif
+ } else { $? "! error"
+ printf("Einstellungen nicht gefunden.\n");
+ printf("Fehlercode: %d\n", er.ec);
+ }
+ $? "- main"
+ $!trace-end
+ return 0;
+}
diff --git a/support/dktools/test-dk4maac.c b/support/dktools/test-dk4maac.c
new file mode 100644
index 0000000000..9b78ffe401
--- /dev/null
+++ b/support/dktools/test-dk4maac.c
@@ -0,0 +1,110 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-dk4maac.ctr
+*/
+
+/** @file test-dk4maac.c The test-dk4maac module.
+*/
+
+
+#line 1 "test-dk4maac.ctr"
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4error.h"
+#include "dk4maac.h"
+
+
+
+#line 10 "test-dk4maac.ctr"
+
+
+static
+void
+show_error(dk4_er_t *erp)
+{
+ if (DK4_E_NONE != erp->ec) {
+ switch(erp->ec) {
+ case DK4_E_MATH_OVERFLOW: {
+ printf(" overflow");
+ } break;
+ case DK4_E_MATH_DIVZERO: {
+ printf(" divzero");
+ } break;
+ default: {
+ printf(" %d", erp->ec);
+ } break;
+ }
+ }
+}
+
+
+
+int main(void)
+{
+ char buffer[128]; /* Input line buffer */
+ dk4_er_t er; /* Error report */
+ int i1; /* First operand */
+ int i2; /* Second operand */
+ int exc; /* Exit code */
+ int cc; /* Flag: Can continue */
+ char c1; /* First operand as char */
+ char c2; /* Second operand as char */
+ char c3; /* Result as char */
+
+
+
+#line 46 "test-dk4maac.ctr"
+
+
+#line 47 "test-dk4maac.ctr"
+ exc = 0;
+ cc = 1;
+ while((1 == cc) && (fgets(buffer, sizeof(buffer), stdin))) {
+ if (sscanf(buffer, "%d %d", &i1, &i2) == 2) {
+ c1 = i1;
+ c2 = i2;
+ printf("%d %d\n", (int)c1, (int)c2);
+ dk4error_init(&er);
+ c3 = dk4ma_char_add(c1, c2, &er);
+ printf("\t+ %d", (int)c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_char_sub(c1, c2, &er);
+ printf("\t- %d", (int)c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_char_mul(c1, c2, &er);
+ printf("\t* %d", (int)c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_char_div(c1, c2, &er);
+ printf("\t/ %d", (int)c3);
+ show_error(&er);
+ printf("\n");
+ } else {
+ exc = 1;
+ fprintf(stderr, "test-dk4maac:ERROR: Invalid input line!\n");
+ fflush(stderr);
+ cc = 0;
+ }
+ }
+
+
+#line 85 "test-dk4maac.ctr"
+
+
+#line 86 "test-dk4maac.ctr"
+ return exc;
+}
+
diff --git a/support/dktools/test-dk4maac.ctr b/support/dktools/test-dk4maac.ctr
new file mode 100644
index 0000000000..e93ae20697
--- /dev/null
+++ b/support/dktools/test-dk4maac.ctr
@@ -0,0 +1,88 @@
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4error.h"
+#include "dk4maac.h"
+
+$!trace-include
+
+
+static
+void
+show_error(dk4_er_t *erp)
+{
+ if (DK4_E_NONE != erp->ec) {
+ switch(erp->ec) {
+ case DK4_E_MATH_OVERFLOW: {
+ printf(" overflow");
+ } break;
+ case DK4_E_MATH_DIVZERO: {
+ printf(" divzero");
+ } break;
+ default: {
+ printf(" %d", erp->ec);
+ } break;
+ }
+ }
+}
+
+
+
+int main(void)
+{
+ char buffer[128]; /* Input line buffer */
+ dk4_er_t er; /* Error report */
+ int i1; /* First operand */
+ int i2; /* Second operand */
+ int exc; /* Exit code */
+ int cc; /* Flag: Can continue */
+ char c1; /* First operand as char */
+ char c2; /* Second operand as char */
+ char c3; /* Result as char */
+
+ $!trace-init test-dk4maac.deb
+ $? "+ main"
+ exc = 0;
+ cc = 1;
+ while((1 == cc) && (fgets(buffer, sizeof(buffer), stdin))) {
+ if (sscanf(buffer, "%d %d", &i1, &i2) == 2) {
+ c1 = i1;
+ c2 = i2;
+ printf("%d %d\n", (int)c1, (int)c2);
+ dk4error_init(&er);
+ c3 = dk4ma_char_add(c1, c2, &er);
+ printf("\t+ %d", (int)c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_char_sub(c1, c2, &er);
+ printf("\t- %d", (int)c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_char_mul(c1, c2, &er);
+ printf("\t* %d", (int)c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_char_div(c1, c2, &er);
+ printf("\t/ %d", (int)c3);
+ show_error(&er);
+ printf("\n");
+ } else {
+ exc = 1;
+ fprintf(stderr, "test-dk4maac:ERROR: Invalid input line!\n");
+ fflush(stderr);
+ cc = 0;
+ }
+ }
+ $? "- main"
+ $!trace-end
+ return exc;
+}
+
diff --git a/support/dktools/test-dk4maai.c b/support/dktools/test-dk4maai.c
new file mode 100644
index 0000000000..9c62d0fa33
--- /dev/null
+++ b/support/dktools/test-dk4maai.c
@@ -0,0 +1,109 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-dk4maai.ctr
+*/
+
+/** @file test-dk4maai.c The test-dk4maai module.
+*/
+
+
+#line 1 "test-dk4maai.ctr"
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4error.h"
+#include "dk4maai.h"
+
+
+
+#line 9 "test-dk4maai.ctr"
+
+
+static
+void
+show_error(dk4_er_t *erp)
+{
+ if (DK4_E_NONE != erp->ec) {
+ switch(erp->ec) {
+ case DK4_E_MATH_OVERFLOW: {
+ printf(" overflow");
+ } break;
+ case DK4_E_MATH_DIVZERO: {
+ printf(" divzero");
+ } break;
+ default: {
+ printf(" %d", erp->ec);
+ } break;
+ }
+ }
+}
+
+
+
+int main(void)
+{
+ char buffer[128]; /* Input line buffer */
+ dk4_er_t er; /* Error report */
+ int i1; /* First operand */
+ int i2; /* Second operand */
+ int exc; /* Exit code */
+ int cc; /* Flag: Can continue */
+ int c1; /* First operand as char */
+ int c2; /* Second operand as char */
+ int c3; /* Result as char */
+
+
+
+#line 45 "test-dk4maai.ctr"
+
+
+#line 46 "test-dk4maai.ctr"
+ exc = 0;
+ cc = 1;
+ while((1 == cc) && (fgets(buffer, sizeof(buffer), stdin))) {
+ if (sscanf(buffer, "%d %d", &i1, &i2) == 2) {
+ c1 = i1;
+ c2 = i2;
+ printf("%d %d\n", (int)c1, (int)c2);
+ dk4error_init(&er);
+ c3 = dk4ma_int_add(c1, c2, &er);
+ printf("\t+ %d", (int)c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_int_sub(c1, c2, &er);
+ printf("\t- %d", (int)c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_int_mul(c1, c2, &er);
+ printf("\t* %d", (int)c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_int_div(c1, c2, &er);
+ printf("\t/ %d", (int)c3);
+ show_error(&er);
+ printf("\n");
+ } else {
+ exc = 1;
+ fprintf(stderr, "test-dk4maac:ERROR: Invalid input line!\n");
+ fflush(stderr);
+ cc = 0;
+ }
+ }
+
+
+#line 84 "test-dk4maai.ctr"
+
+
+#line 85 "test-dk4maai.ctr"
+ return exc;
+}
+
diff --git a/support/dktools/test-dk4maai.ctr b/support/dktools/test-dk4maai.ctr
new file mode 100644
index 0000000000..c828dbfb77
--- /dev/null
+++ b/support/dktools/test-dk4maai.ctr
@@ -0,0 +1,87 @@
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4error.h"
+#include "dk4maai.h"
+
+$!trace-include
+
+
+static
+void
+show_error(dk4_er_t *erp)
+{
+ if (DK4_E_NONE != erp->ec) {
+ switch(erp->ec) {
+ case DK4_E_MATH_OVERFLOW: {
+ printf(" overflow");
+ } break;
+ case DK4_E_MATH_DIVZERO: {
+ printf(" divzero");
+ } break;
+ default: {
+ printf(" %d", erp->ec);
+ } break;
+ }
+ }
+}
+
+
+
+int main(void)
+{
+ char buffer[128]; /* Input line buffer */
+ dk4_er_t er; /* Error report */
+ int i1; /* First operand */
+ int i2; /* Second operand */
+ int exc; /* Exit code */
+ int cc; /* Flag: Can continue */
+ int c1; /* First operand as char */
+ int c2; /* Second operand as char */
+ int c3; /* Result as char */
+
+ $!trace-init test-dk4maac.deb
+ $? "+ main"
+ exc = 0;
+ cc = 1;
+ while((1 == cc) && (fgets(buffer, sizeof(buffer), stdin))) {
+ if (sscanf(buffer, "%d %d", &i1, &i2) == 2) {
+ c1 = i1;
+ c2 = i2;
+ printf("%d %d\n", (int)c1, (int)c2);
+ dk4error_init(&er);
+ c3 = dk4ma_int_add(c1, c2, &er);
+ printf("\t+ %d", (int)c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_int_sub(c1, c2, &er);
+ printf("\t- %d", (int)c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_int_mul(c1, c2, &er);
+ printf("\t* %d", (int)c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_int_div(c1, c2, &er);
+ printf("\t/ %d", (int)c3);
+ show_error(&er);
+ printf("\n");
+ } else {
+ exc = 1;
+ fprintf(stderr, "test-dk4maac:ERROR: Invalid input line!\n");
+ fflush(stderr);
+ cc = 0;
+ }
+ }
+ $? "- main"
+ $!trace-end
+ return exc;
+}
+
diff --git a/support/dktools/test-dk4maal.c b/support/dktools/test-dk4maal.c
new file mode 100644
index 0000000000..fd76818dc1
--- /dev/null
+++ b/support/dktools/test-dk4maal.c
@@ -0,0 +1,109 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-dk4maal.ctr
+*/
+
+/** @file test-dk4maal.c The test-dk4maal module.
+*/
+
+
+#line 1 "test-dk4maal.ctr"
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4error.h"
+#include "dk4maal.h"
+
+
+
+#line 9 "test-dk4maal.ctr"
+
+
+static
+void
+show_error(dk4_er_t *erp)
+{
+ if (DK4_E_NONE != erp->ec) {
+ switch(erp->ec) {
+ case DK4_E_MATH_OVERFLOW: {
+ printf(" overflow");
+ } break;
+ case DK4_E_MATH_DIVZERO: {
+ printf(" divzero");
+ } break;
+ default: {
+ printf(" %d", erp->ec);
+ } break;
+ }
+ }
+}
+
+
+
+int main(void)
+{
+ char buffer[128]; /* Input line buffer */
+ dk4_er_t er; /* Error report */
+ long i1; /* First operand */
+ long i2; /* Second operand */
+ int exc; /* Exit code */
+ int cc; /* Flag: Can continue */
+ long c1; /* First operand as char */
+ long c2; /* Second operand as char */
+ long c3; /* Result as char */
+
+
+
+#line 45 "test-dk4maal.ctr"
+
+
+#line 46 "test-dk4maal.ctr"
+ exc = 0;
+ cc = 1;
+ while((1 == cc) && (fgets(buffer, sizeof(buffer), stdin))) {
+ if (sscanf(buffer, "%ld %ld", &i1, &i2) == 2) {
+ c1 = i1;
+ c2 = i2;
+ printf("%ld %ld\n", (long)c1, (long)c2);
+ dk4error_init(&er);
+ c3 = dk4ma_long_add(c1, c2, &er);
+ printf("\t+ %ld", c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_long_sub(c1, c2, &er);
+ printf("\t- %ld", c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_long_mul(c1, c2, &er);
+ printf("\t* %ld", c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_long_div(c1, c2, &er);
+ printf("\t/ %ld", c3);
+ show_error(&er);
+ printf("\n");
+ } else {
+ exc = 1;
+ fprintf(stderr, "test-dk4maac:ERROR: Invalid input line!\n");
+ fflush(stderr);
+ cc = 0;
+ }
+ }
+
+
+#line 84 "test-dk4maal.ctr"
+
+
+#line 85 "test-dk4maal.ctr"
+ return exc;
+}
+
diff --git a/support/dktools/test-dk4maal.ctr b/support/dktools/test-dk4maal.ctr
new file mode 100644
index 0000000000..285a3258ca
--- /dev/null
+++ b/support/dktools/test-dk4maal.ctr
@@ -0,0 +1,87 @@
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4error.h"
+#include "dk4maal.h"
+
+$!trace-include
+
+
+static
+void
+show_error(dk4_er_t *erp)
+{
+ if (DK4_E_NONE != erp->ec) {
+ switch(erp->ec) {
+ case DK4_E_MATH_OVERFLOW: {
+ printf(" overflow");
+ } break;
+ case DK4_E_MATH_DIVZERO: {
+ printf(" divzero");
+ } break;
+ default: {
+ printf(" %d", erp->ec);
+ } break;
+ }
+ }
+}
+
+
+
+int main(void)
+{
+ char buffer[128]; /* Input line buffer */
+ dk4_er_t er; /* Error report */
+ long i1; /* First operand */
+ long i2; /* Second operand */
+ int exc; /* Exit code */
+ int cc; /* Flag: Can continue */
+ long c1; /* First operand as char */
+ long c2; /* Second operand as char */
+ long c3; /* Result as char */
+
+ $!trace-init test-dk4maac.deb
+ $? "+ main"
+ exc = 0;
+ cc = 1;
+ while((1 == cc) && (fgets(buffer, sizeof(buffer), stdin))) {
+ if (sscanf(buffer, "%ld %ld", &i1, &i2) == 2) {
+ c1 = i1;
+ c2 = i2;
+ printf("%ld %ld\n", (long)c1, (long)c2);
+ dk4error_init(&er);
+ c3 = dk4ma_long_add(c1, c2, &er);
+ printf("\t+ %ld", c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_long_sub(c1, c2, &er);
+ printf("\t- %ld", c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_long_mul(c1, c2, &er);
+ printf("\t* %ld", c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_long_div(c1, c2, &er);
+ printf("\t/ %ld", c3);
+ show_error(&er);
+ printf("\n");
+ } else {
+ exc = 1;
+ fprintf(stderr, "test-dk4maac:ERROR: Invalid input line!\n");
+ fflush(stderr);
+ cc = 0;
+ }
+ }
+ $? "- main"
+ $!trace-end
+ return exc;
+}
+
diff --git a/support/dktools/test-dk4maall.c b/support/dktools/test-dk4maall.c
new file mode 100644
index 0000000000..a6edc80697
--- /dev/null
+++ b/support/dktools/test-dk4maall.c
@@ -0,0 +1,109 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-dk4maall.ctr
+*/
+
+/** @file test-dk4maall.c The test-dk4maall module.
+*/
+
+
+#line 1 "test-dk4maall.ctr"
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4error.h"
+#include "dk4maall.h"
+
+
+
+#line 9 "test-dk4maall.ctr"
+
+
+static
+void
+show_error(dk4_er_t *erp)
+{
+ if (DK4_E_NONE != erp->ec) {
+ switch(erp->ec) {
+ case DK4_E_MATH_OVERFLOW: {
+ printf(" overflow");
+ } break;
+ case DK4_E_MATH_DIVZERO: {
+ printf(" divzero");
+ } break;
+ default: {
+ printf(" %d", erp->ec);
+ } break;
+ }
+ }
+}
+
+
+
+int main(void)
+{
+ char buffer[128]; /* Input line buffer */
+ dk4_er_t er; /* Error report */
+ long long i1; /* First operand */
+ long long i2; /* Second operand */
+ int exc; /* Exit code */
+ int cc; /* Flag: Can continue */
+ long long c1; /* First operand as char */
+ long long c2; /* Second operand as char */
+ long long c3; /* Result as char */
+
+
+
+#line 45 "test-dk4maall.ctr"
+
+
+#line 46 "test-dk4maall.ctr"
+ exc = 0;
+ cc = 1;
+ while((1 == cc) && (fgets(buffer, sizeof(buffer), stdin))) {
+ if (sscanf(buffer, "%lld %lld", &i1, &i2) == 2) {
+ c1 = i1;
+ c2 = i2;
+ printf("%lld %lld\n", c1, c2);
+ dk4error_init(&er);
+ c3 = dk4ma_ll_add(c1, c2, &er);
+ printf("\t+ %lld", c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_ll_sub(c1, c2, &er);
+ printf("\t- %lld", c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_ll_mul(c1, c2, &er);
+ printf("\t* %lld", c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_ll_div(c1, c2, &er);
+ printf("\t/ %lld", c3);
+ show_error(&er);
+ printf("\n");
+ } else {
+ exc = 1;
+ fprintf(stderr, "test-dk4maac:ERROR: Invalid input line!\n");
+ fflush(stderr);
+ cc = 0;
+ }
+ }
+
+
+#line 84 "test-dk4maall.ctr"
+
+
+#line 85 "test-dk4maall.ctr"
+ return exc;
+}
+
diff --git a/support/dktools/test-dk4maall.ctr b/support/dktools/test-dk4maall.ctr
new file mode 100644
index 0000000000..a5e657572c
--- /dev/null
+++ b/support/dktools/test-dk4maall.ctr
@@ -0,0 +1,87 @@
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4error.h"
+#include "dk4maall.h"
+
+$!trace-include
+
+
+static
+void
+show_error(dk4_er_t *erp)
+{
+ if (DK4_E_NONE != erp->ec) {
+ switch(erp->ec) {
+ case DK4_E_MATH_OVERFLOW: {
+ printf(" overflow");
+ } break;
+ case DK4_E_MATH_DIVZERO: {
+ printf(" divzero");
+ } break;
+ default: {
+ printf(" %d", erp->ec);
+ } break;
+ }
+ }
+}
+
+
+
+int main(void)
+{
+ char buffer[128]; /* Input line buffer */
+ dk4_er_t er; /* Error report */
+ long long i1; /* First operand */
+ long long i2; /* Second operand */
+ int exc; /* Exit code */
+ int cc; /* Flag: Can continue */
+ long long c1; /* First operand as char */
+ long long c2; /* Second operand as char */
+ long long c3; /* Result as char */
+
+ $!trace-init test-dk4maac.deb
+ $? "+ main"
+ exc = 0;
+ cc = 1;
+ while((1 == cc) && (fgets(buffer, sizeof(buffer), stdin))) {
+ if (sscanf(buffer, "%lld %lld", &i1, &i2) == 2) {
+ c1 = i1;
+ c2 = i2;
+ printf("%lld %lld\n", c1, c2);
+ dk4error_init(&er);
+ c3 = dk4ma_ll_add(c1, c2, &er);
+ printf("\t+ %lld", c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_ll_sub(c1, c2, &er);
+ printf("\t- %lld", c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_ll_mul(c1, c2, &er);
+ printf("\t* %lld", c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_ll_div(c1, c2, &er);
+ printf("\t/ %lld", c3);
+ show_error(&er);
+ printf("\n");
+ } else {
+ exc = 1;
+ fprintf(stderr, "test-dk4maac:ERROR: Invalid input line!\n");
+ fflush(stderr);
+ cc = 0;
+ }
+ }
+ $? "- main"
+ $!trace-end
+ return exc;
+}
+
diff --git a/support/dktools/test-dk4maami.c b/support/dktools/test-dk4maami.c
new file mode 100644
index 0000000000..dc7bed5797
--- /dev/null
+++ b/support/dktools/test-dk4maami.c
@@ -0,0 +1,109 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-dk4maami.ctr
+*/
+
+/** @file test-dk4maami.c The test-dk4maami module.
+*/
+
+
+#line 1 "test-dk4maami.ctr"
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4error.h"
+#include "dk4maami.h"
+
+
+
+#line 9 "test-dk4maami.ctr"
+
+
+static
+void
+show_error(dk4_er_t *erp)
+{
+ if (DK4_E_NONE != erp->ec) {
+ switch(erp->ec) {
+ case DK4_E_MATH_OVERFLOW: {
+ printf(" overflow");
+ } break;
+ case DK4_E_MATH_DIVZERO: {
+ printf(" divzero");
+ } break;
+ default: {
+ printf(" %d", erp->ec);
+ } break;
+ }
+ }
+}
+
+
+
+int main(void)
+{
+ char buffer[128]; /* Input line buffer */
+ dk4_er_t er; /* Error report */
+ intmax_t i1; /* First operand */
+ intmax_t i2; /* Second operand */
+ int exc; /* Exit code */
+ int cc; /* Flag: Can continue */
+ intmax_t c1; /* First operand as char */
+ intmax_t c2; /* Second operand as char */
+ intmax_t c3; /* Result as char */
+
+
+
+#line 45 "test-dk4maami.ctr"
+
+
+#line 46 "test-dk4maami.ctr"
+ exc = 0;
+ cc = 1;
+ while((1 == cc) && (fgets(buffer, sizeof(buffer), stdin))) {
+ if (sscanf(buffer, "%jd %jd", &i1, &i2) == 2) {
+ c1 = i1;
+ c2 = i2;
+ printf("%jd %jd\n", c1, c2);
+ dk4error_init(&er);
+ c3 = dk4ma_intmax_t_add(c1, c2, &er);
+ printf("\t+ %jd", c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_intmax_t_sub(c1, c2, &er);
+ printf("\t- %jd", c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_intmax_t_mul(c1, c2, &er);
+ printf("\t* %jd", c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_intmax_t_div(c1, c2, &er);
+ printf("\t/ %jd", c3);
+ show_error(&er);
+ printf("\n");
+ } else {
+ exc = 1;
+ fprintf(stderr, "test-dk4maac:ERROR: Invalid input line!\n");
+ fflush(stderr);
+ cc = 0;
+ }
+ }
+
+
+#line 84 "test-dk4maami.ctr"
+
+
+#line 85 "test-dk4maami.ctr"
+ return exc;
+}
+
diff --git a/support/dktools/test-dk4maami.ctr b/support/dktools/test-dk4maami.ctr
new file mode 100644
index 0000000000..22431066c6
--- /dev/null
+++ b/support/dktools/test-dk4maami.ctr
@@ -0,0 +1,87 @@
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4error.h"
+#include "dk4maami.h"
+
+$!trace-include
+
+
+static
+void
+show_error(dk4_er_t *erp)
+{
+ if (DK4_E_NONE != erp->ec) {
+ switch(erp->ec) {
+ case DK4_E_MATH_OVERFLOW: {
+ printf(" overflow");
+ } break;
+ case DK4_E_MATH_DIVZERO: {
+ printf(" divzero");
+ } break;
+ default: {
+ printf(" %d", erp->ec);
+ } break;
+ }
+ }
+}
+
+
+
+int main(void)
+{
+ char buffer[128]; /* Input line buffer */
+ dk4_er_t er; /* Error report */
+ intmax_t i1; /* First operand */
+ intmax_t i2; /* Second operand */
+ int exc; /* Exit code */
+ int cc; /* Flag: Can continue */
+ intmax_t c1; /* First operand as char */
+ intmax_t c2; /* Second operand as char */
+ intmax_t c3; /* Result as char */
+
+ $!trace-init test-dk4maac.deb
+ $? "+ main"
+ exc = 0;
+ cc = 1;
+ while((1 == cc) && (fgets(buffer, sizeof(buffer), stdin))) {
+ if (sscanf(buffer, "%jd %jd", &i1, &i2) == 2) {
+ c1 = i1;
+ c2 = i2;
+ printf("%jd %jd\n", c1, c2);
+ dk4error_init(&er);
+ c3 = dk4ma_intmax_t_add(c1, c2, &er);
+ printf("\t+ %jd", c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_intmax_t_sub(c1, c2, &er);
+ printf("\t- %jd", c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_intmax_t_mul(c1, c2, &er);
+ printf("\t* %jd", c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_intmax_t_div(c1, c2, &er);
+ printf("\t/ %jd", c3);
+ show_error(&er);
+ printf("\n");
+ } else {
+ exc = 1;
+ fprintf(stderr, "test-dk4maac:ERROR: Invalid input line!\n");
+ fflush(stderr);
+ cc = 0;
+ }
+ }
+ $? "- main"
+ $!trace-end
+ return exc;
+}
+
diff --git a/support/dktools/test-dk4maamu.c b/support/dktools/test-dk4maamu.c
new file mode 100644
index 0000000000..e5dbca4b57
--- /dev/null
+++ b/support/dktools/test-dk4maamu.c
@@ -0,0 +1,109 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-dk4maamu.ctr
+*/
+
+/** @file test-dk4maamu.c The test-dk4maamu module.
+*/
+
+
+#line 1 "test-dk4maamu.ctr"
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4error.h"
+#include "dk4maamu.h"
+
+
+
+#line 9 "test-dk4maamu.ctr"
+
+
+static
+void
+show_error(dk4_er_t *erp)
+{
+ if (DK4_E_NONE != erp->ec) {
+ switch(erp->ec) {
+ case DK4_E_MATH_OVERFLOW: {
+ printf(" overflow");
+ } break;
+ case DK4_E_MATH_DIVZERO: {
+ printf(" divzero");
+ } break;
+ default: {
+ printf(" %d", erp->ec);
+ } break;
+ }
+ }
+}
+
+
+
+int main(void)
+{
+ char buffer[128]; /* Input line buffer */
+ dk4_er_t er; /* Error report */
+ uintmax_t i1; /* First operand */
+ uintmax_t i2; /* Second operand */
+ int exc; /* Exit code */
+ int cc; /* Flag: Can continue */
+ uintmax_t c1; /* First operand as char */
+ uintmax_t c2; /* Second operand as char */
+ uintmax_t c3; /* Result as char */
+
+
+
+#line 45 "test-dk4maamu.ctr"
+
+
+#line 46 "test-dk4maamu.ctr"
+ exc = 0;
+ cc = 1;
+ while((1 == cc) && (fgets(buffer, sizeof(buffer), stdin))) {
+ if (sscanf(buffer, "%ju %ju", &i1, &i2) == 2) {
+ c1 = i1;
+ c2 = i2;
+ printf("%ju %ju\n", c1, c2);
+ dk4error_init(&er);
+ c3 = dk4ma_uintmax_t_add(c1, c2, &er);
+ printf("\t+ %ju", c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_uintmax_t_sub(c1, c2, &er);
+ printf("\t- %ju", c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_uintmax_t_mul(c1, c2, &er);
+ printf("\t* %ju", c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_uintmax_t_div(c1, c2, &er);
+ printf("\t/ %ju", c3);
+ show_error(&er);
+ printf("\n");
+ } else {
+ exc = 1;
+ fprintf(stderr, "test-dk4maac:ERROR: Invalid input line!\n");
+ fflush(stderr);
+ cc = 0;
+ }
+ }
+
+
+#line 84 "test-dk4maamu.ctr"
+
+
+#line 85 "test-dk4maamu.ctr"
+ return exc;
+}
+
diff --git a/support/dktools/test-dk4maamu.ctr b/support/dktools/test-dk4maamu.ctr
new file mode 100644
index 0000000000..1cf58eaaee
--- /dev/null
+++ b/support/dktools/test-dk4maamu.ctr
@@ -0,0 +1,87 @@
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4error.h"
+#include "dk4maamu.h"
+
+$!trace-include
+
+
+static
+void
+show_error(dk4_er_t *erp)
+{
+ if (DK4_E_NONE != erp->ec) {
+ switch(erp->ec) {
+ case DK4_E_MATH_OVERFLOW: {
+ printf(" overflow");
+ } break;
+ case DK4_E_MATH_DIVZERO: {
+ printf(" divzero");
+ } break;
+ default: {
+ printf(" %d", erp->ec);
+ } break;
+ }
+ }
+}
+
+
+
+int main(void)
+{
+ char buffer[128]; /* Input line buffer */
+ dk4_er_t er; /* Error report */
+ uintmax_t i1; /* First operand */
+ uintmax_t i2; /* Second operand */
+ int exc; /* Exit code */
+ int cc; /* Flag: Can continue */
+ uintmax_t c1; /* First operand as char */
+ uintmax_t c2; /* Second operand as char */
+ uintmax_t c3; /* Result as char */
+
+ $!trace-init test-dk4maac.deb
+ $? "+ main"
+ exc = 0;
+ cc = 1;
+ while((1 == cc) && (fgets(buffer, sizeof(buffer), stdin))) {
+ if (sscanf(buffer, "%ju %ju", &i1, &i2) == 2) {
+ c1 = i1;
+ c2 = i2;
+ printf("%ju %ju\n", c1, c2);
+ dk4error_init(&er);
+ c3 = dk4ma_uintmax_t_add(c1, c2, &er);
+ printf("\t+ %ju", c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_uintmax_t_sub(c1, c2, &er);
+ printf("\t- %ju", c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_uintmax_t_mul(c1, c2, &er);
+ printf("\t* %ju", c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_uintmax_t_div(c1, c2, &er);
+ printf("\t/ %ju", c3);
+ show_error(&er);
+ printf("\n");
+ } else {
+ exc = 1;
+ fprintf(stderr, "test-dk4maac:ERROR: Invalid input line!\n");
+ fflush(stderr);
+ cc = 0;
+ }
+ }
+ $? "- main"
+ $!trace-end
+ return exc;
+}
+
diff --git a/support/dktools/test-dk4maas.c b/support/dktools/test-dk4maas.c
new file mode 100644
index 0000000000..75dbe0c7cc
--- /dev/null
+++ b/support/dktools/test-dk4maas.c
@@ -0,0 +1,109 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-dk4maas.ctr
+*/
+
+/** @file test-dk4maas.c The test-dk4maas module.
+*/
+
+
+#line 1 "test-dk4maas.ctr"
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4error.h"
+#include "dk4maas.h"
+
+
+
+#line 9 "test-dk4maas.ctr"
+
+
+static
+void
+show_error(dk4_er_t *erp)
+{
+ if (DK4_E_NONE != erp->ec) {
+ switch(erp->ec) {
+ case DK4_E_MATH_OVERFLOW: {
+ printf(" overflow");
+ } break;
+ case DK4_E_MATH_DIVZERO: {
+ printf(" divzero");
+ } break;
+ default: {
+ printf(" %d", erp->ec);
+ } break;
+ }
+ }
+}
+
+
+
+int main(void)
+{
+ char buffer[128]; /* Input line buffer */
+ dk4_er_t er; /* Error report */
+ int i1; /* First operand */
+ int i2; /* Second operand */
+ int exc; /* Exit code */
+ int cc; /* Flag: Can continue */
+ short c1; /* First operand as char */
+ short c2; /* Second operand as char */
+ short c3; /* Result as char */
+
+
+
+#line 45 "test-dk4maas.ctr"
+
+
+#line 46 "test-dk4maas.ctr"
+ exc = 0;
+ cc = 1;
+ while((1 == cc) && (fgets(buffer, sizeof(buffer), stdin))) {
+ if (sscanf(buffer, "%d %d", &i1, &i2) == 2) {
+ c1 = i1;
+ c2 = i2;
+ printf("%d %d\n", (int)c1, (int)c2);
+ dk4error_init(&er);
+ c3 = dk4ma_short_add(c1, c2, &er);
+ printf("\t+ %d", (int)c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_short_sub(c1, c2, &er);
+ printf("\t- %d", (int)c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_short_mul(c1, c2, &er);
+ printf("\t* %d", (int)c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_short_div(c1, c2, &er);
+ printf("\t/ %d", (int)c3);
+ show_error(&er);
+ printf("\n");
+ } else {
+ exc = 1;
+ fprintf(stderr, "test-dk4maac:ERROR: Invalid input line!\n");
+ fflush(stderr);
+ cc = 0;
+ }
+ }
+
+
+#line 84 "test-dk4maas.ctr"
+
+
+#line 85 "test-dk4maas.ctr"
+ return exc;
+}
+
diff --git a/support/dktools/test-dk4maas.ctr b/support/dktools/test-dk4maas.ctr
new file mode 100644
index 0000000000..d402ee251f
--- /dev/null
+++ b/support/dktools/test-dk4maas.ctr
@@ -0,0 +1,87 @@
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4error.h"
+#include "dk4maas.h"
+
+$!trace-include
+
+
+static
+void
+show_error(dk4_er_t *erp)
+{
+ if (DK4_E_NONE != erp->ec) {
+ switch(erp->ec) {
+ case DK4_E_MATH_OVERFLOW: {
+ printf(" overflow");
+ } break;
+ case DK4_E_MATH_DIVZERO: {
+ printf(" divzero");
+ } break;
+ default: {
+ printf(" %d", erp->ec);
+ } break;
+ }
+ }
+}
+
+
+
+int main(void)
+{
+ char buffer[128]; /* Input line buffer */
+ dk4_er_t er; /* Error report */
+ int i1; /* First operand */
+ int i2; /* Second operand */
+ int exc; /* Exit code */
+ int cc; /* Flag: Can continue */
+ short c1; /* First operand as char */
+ short c2; /* Second operand as char */
+ short c3; /* Result as char */
+
+ $!trace-init test-dk4maac.deb
+ $? "+ main"
+ exc = 0;
+ cc = 1;
+ while((1 == cc) && (fgets(buffer, sizeof(buffer), stdin))) {
+ if (sscanf(buffer, "%d %d", &i1, &i2) == 2) {
+ c1 = i1;
+ c2 = i2;
+ printf("%d %d\n", (int)c1, (int)c2);
+ dk4error_init(&er);
+ c3 = dk4ma_short_add(c1, c2, &er);
+ printf("\t+ %d", (int)c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_short_sub(c1, c2, &er);
+ printf("\t- %d", (int)c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_short_mul(c1, c2, &er);
+ printf("\t* %d", (int)c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_short_div(c1, c2, &er);
+ printf("\t/ %d", (int)c3);
+ show_error(&er);
+ printf("\n");
+ } else {
+ exc = 1;
+ fprintf(stderr, "test-dk4maac:ERROR: Invalid input line!\n");
+ fflush(stderr);
+ cc = 0;
+ }
+ }
+ $? "- main"
+ $!trace-end
+ return exc;
+}
+
diff --git a/support/dktools/test-dk4maauc.c b/support/dktools/test-dk4maauc.c
new file mode 100644
index 0000000000..10a22ee782
--- /dev/null
+++ b/support/dktools/test-dk4maauc.c
@@ -0,0 +1,110 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-dk4maauc.ctr
+*/
+
+/** @file test-dk4maauc.c The test-dk4maauc module.
+*/
+
+
+#line 1 "test-dk4maauc.ctr"
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4error.h"
+#include "dk4maauc.h"
+
+
+
+#line 10 "test-dk4maauc.ctr"
+
+
+static
+void
+show_error(dk4_er_t *erp)
+{
+ if (DK4_E_NONE != erp->ec) {
+ switch(erp->ec) {
+ case DK4_E_MATH_OVERFLOW: {
+ printf(" overflow");
+ } break;
+ case DK4_E_MATH_DIVZERO: {
+ printf(" divzero");
+ } break;
+ default: {
+ printf(" %u", erp->ec);
+ } break;
+ }
+ }
+}
+
+
+
+int main(void)
+{
+ char buffer[128]; /* Input line buffer */
+ dk4_er_t er; /* Error report */
+ unsigned i1; /* First operand */
+ unsigned i2; /* Second operand */
+ int exc; /* Exit code */
+ int cc; /* Flag: Can continue */
+ unsigned char c1; /* First operand as char */
+ unsigned char c2; /* Second operand as char */
+ unsigned char c3; /* Result as char */
+
+
+
+#line 46 "test-dk4maauc.ctr"
+
+
+#line 47 "test-dk4maauc.ctr"
+ exc = 0;
+ cc = 1;
+ while((1 == cc) && (fgets(buffer, sizeof(buffer), stdin))) {
+ if (sscanf(buffer, "%u %u", &i1, &i2) == 2) {
+ c1 = i1;
+ c2 = i2;
+ printf("%u %u\n", (unsigned)c1, (unsigned)c2);
+ dk4error_init(&er);
+ c3 = dk4ma_uchar_add(c1, c2, &er);
+ printf("\t+ %u", (unsigned)c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_uchar_sub(c1, c2, &er);
+ printf("\t- %u", (unsigned)c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_uchar_mul(c1, c2, &er);
+ printf("\t* %u", (unsigned)c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_uchar_div(c1, c2, &er);
+ printf("\t/ %u", (unsigned)c3);
+ show_error(&er);
+ printf("\n");
+ } else {
+ exc = 1;
+ fprintf(stderr, "test-dk4maac:ERROR: Invalid input line!\n");
+ fflush(stderr);
+ cc = 0;
+ }
+ }
+
+
+#line 85 "test-dk4maauc.ctr"
+
+
+#line 86 "test-dk4maauc.ctr"
+ return exc;
+}
+
diff --git a/support/dktools/test-dk4maauc.ctr b/support/dktools/test-dk4maauc.ctr
new file mode 100644
index 0000000000..21ab0f490f
--- /dev/null
+++ b/support/dktools/test-dk4maauc.ctr
@@ -0,0 +1,88 @@
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4error.h"
+#include "dk4maauc.h"
+
+$!trace-include
+
+
+static
+void
+show_error(dk4_er_t *erp)
+{
+ if (DK4_E_NONE != erp->ec) {
+ switch(erp->ec) {
+ case DK4_E_MATH_OVERFLOW: {
+ printf(" overflow");
+ } break;
+ case DK4_E_MATH_DIVZERO: {
+ printf(" divzero");
+ } break;
+ default: {
+ printf(" %u", erp->ec);
+ } break;
+ }
+ }
+}
+
+
+
+int main(void)
+{
+ char buffer[128]; /* Input line buffer */
+ dk4_er_t er; /* Error report */
+ unsigned i1; /* First operand */
+ unsigned i2; /* Second operand */
+ int exc; /* Exit code */
+ int cc; /* Flag: Can continue */
+ unsigned char c1; /* First operand as char */
+ unsigned char c2; /* Second operand as char */
+ unsigned char c3; /* Result as char */
+
+ $!trace-init test-dk4maac.deb
+ $? "+ main"
+ exc = 0;
+ cc = 1;
+ while((1 == cc) && (fgets(buffer, sizeof(buffer), stdin))) {
+ if (sscanf(buffer, "%u %u", &i1, &i2) == 2) {
+ c1 = i1;
+ c2 = i2;
+ printf("%u %u\n", (unsigned)c1, (unsigned)c2);
+ dk4error_init(&er);
+ c3 = dk4ma_uchar_add(c1, c2, &er);
+ printf("\t+ %u", (unsigned)c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_uchar_sub(c1, c2, &er);
+ printf("\t- %u", (unsigned)c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_uchar_mul(c1, c2, &er);
+ printf("\t* %u", (unsigned)c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_uchar_div(c1, c2, &er);
+ printf("\t/ %u", (unsigned)c3);
+ show_error(&er);
+ printf("\n");
+ } else {
+ exc = 1;
+ fprintf(stderr, "test-dk4maac:ERROR: Invalid input line!\n");
+ fflush(stderr);
+ cc = 0;
+ }
+ }
+ $? "- main"
+ $!trace-end
+ return exc;
+}
+
diff --git a/support/dktools/test-dk4maaui.c b/support/dktools/test-dk4maaui.c
new file mode 100644
index 0000000000..4f0bb90af5
--- /dev/null
+++ b/support/dktools/test-dk4maaui.c
@@ -0,0 +1,110 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-dk4maaui.ctr
+*/
+
+/** @file test-dk4maaui.c The test-dk4maaui module.
+*/
+
+
+#line 1 "test-dk4maaui.ctr"
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4error.h"
+#include "dk4maaui.h"
+
+
+
+#line 10 "test-dk4maaui.ctr"
+
+
+static
+void
+show_error(dk4_er_t *erp)
+{
+ if (DK4_E_NONE != erp->ec) {
+ switch(erp->ec) {
+ case DK4_E_MATH_OVERFLOW: {
+ printf(" overflow");
+ } break;
+ case DK4_E_MATH_DIVZERO: {
+ printf(" divzero");
+ } break;
+ default: {
+ printf(" %u", erp->ec);
+ } break;
+ }
+ }
+}
+
+
+
+int main(void)
+{
+ char buffer[128]; /* Input line buffer */
+ dk4_er_t er; /* Error report */
+ unsigned i1; /* First operand */
+ unsigned i2; /* Second operand */
+ int exc; /* Exit code */
+ int cc; /* Flag: Can continue */
+ unsigned c1; /* First operand as char */
+ unsigned c2; /* Second operand as char */
+ unsigned c3; /* Result as char */
+
+
+
+#line 46 "test-dk4maaui.ctr"
+
+
+#line 47 "test-dk4maaui.ctr"
+ exc = 0;
+ cc = 1;
+ while((1 == cc) && (fgets(buffer, sizeof(buffer), stdin))) {
+ if (sscanf(buffer, "%u %u", &i1, &i2) == 2) {
+ c1 = i1;
+ c2 = i2;
+ printf("%u %u\n", (unsigned)c1, (unsigned)c2);
+ dk4error_init(&er);
+ c3 = dk4ma_uint_add(c1, c2, &er);
+ printf("\t+ %u", (unsigned)c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_uint_sub(c1, c2, &er);
+ printf("\t- %u", (unsigned)c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_uint_mul(c1, c2, &er);
+ printf("\t* %u", (unsigned)c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_uint_div(c1, c2, &er);
+ printf("\t/ %u", (unsigned)c3);
+ show_error(&er);
+ printf("\n");
+ } else {
+ exc = 1;
+ fprintf(stderr, "test-dk4maac:ERROR: Invalid input line!\n");
+ fflush(stderr);
+ cc = 0;
+ }
+ }
+
+
+#line 85 "test-dk4maaui.ctr"
+
+
+#line 86 "test-dk4maaui.ctr"
+ return exc;
+}
+
diff --git a/support/dktools/test-dk4maaui.ctr b/support/dktools/test-dk4maaui.ctr
new file mode 100644
index 0000000000..bfeb038243
--- /dev/null
+++ b/support/dktools/test-dk4maaui.ctr
@@ -0,0 +1,88 @@
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4error.h"
+#include "dk4maaui.h"
+
+$!trace-include
+
+
+static
+void
+show_error(dk4_er_t *erp)
+{
+ if (DK4_E_NONE != erp->ec) {
+ switch(erp->ec) {
+ case DK4_E_MATH_OVERFLOW: {
+ printf(" overflow");
+ } break;
+ case DK4_E_MATH_DIVZERO: {
+ printf(" divzero");
+ } break;
+ default: {
+ printf(" %u", erp->ec);
+ } break;
+ }
+ }
+}
+
+
+
+int main(void)
+{
+ char buffer[128]; /* Input line buffer */
+ dk4_er_t er; /* Error report */
+ unsigned i1; /* First operand */
+ unsigned i2; /* Second operand */
+ int exc; /* Exit code */
+ int cc; /* Flag: Can continue */
+ unsigned c1; /* First operand as char */
+ unsigned c2; /* Second operand as char */
+ unsigned c3; /* Result as char */
+
+ $!trace-init test-dk4maac.deb
+ $? "+ main"
+ exc = 0;
+ cc = 1;
+ while((1 == cc) && (fgets(buffer, sizeof(buffer), stdin))) {
+ if (sscanf(buffer, "%u %u", &i1, &i2) == 2) {
+ c1 = i1;
+ c2 = i2;
+ printf("%u %u\n", (unsigned)c1, (unsigned)c2);
+ dk4error_init(&er);
+ c3 = dk4ma_uint_add(c1, c2, &er);
+ printf("\t+ %u", (unsigned)c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_uint_sub(c1, c2, &er);
+ printf("\t- %u", (unsigned)c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_uint_mul(c1, c2, &er);
+ printf("\t* %u", (unsigned)c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_uint_div(c1, c2, &er);
+ printf("\t/ %u", (unsigned)c3);
+ show_error(&er);
+ printf("\n");
+ } else {
+ exc = 1;
+ fprintf(stderr, "test-dk4maac:ERROR: Invalid input line!\n");
+ fflush(stderr);
+ cc = 0;
+ }
+ }
+ $? "- main"
+ $!trace-end
+ return exc;
+}
+
diff --git a/support/dktools/test-dk4maaul.c b/support/dktools/test-dk4maaul.c
new file mode 100644
index 0000000000..1b439c5c7c
--- /dev/null
+++ b/support/dktools/test-dk4maaul.c
@@ -0,0 +1,109 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-dk4maaul.ctr
+*/
+
+/** @file test-dk4maaul.c The test-dk4maaul module.
+*/
+
+
+#line 1 "test-dk4maaul.ctr"
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4error.h"
+#include "dk4maaul.h"
+
+
+
+#line 9 "test-dk4maaul.ctr"
+
+
+static
+void
+show_error(dk4_er_t *erp)
+{
+ if (DK4_E_NONE != erp->ec) {
+ switch(erp->ec) {
+ case DK4_E_MATH_OVERFLOW: {
+ printf(" overflow");
+ } break;
+ case DK4_E_MATH_DIVZERO: {
+ printf(" divzero");
+ } break;
+ default: {
+ printf(" %d", erp->ec);
+ } break;
+ }
+ }
+}
+
+
+
+int main(void)
+{
+ char buffer[128]; /* Input line buffer */
+ dk4_er_t er; /* Error report */
+ unsigned long i1; /* First operand */
+ unsigned long i2; /* Second operand */
+ int exc; /* Exit code */
+ int cc; /* Flag: Can continue */
+ unsigned long c1; /* First operand as char */
+ unsigned long c2; /* Second operand as char */
+ unsigned long c3; /* Result as char */
+
+
+
+#line 45 "test-dk4maaul.ctr"
+
+
+#line 46 "test-dk4maaul.ctr"
+ exc = 0;
+ cc = 1;
+ while((1 == cc) && (fgets(buffer, sizeof(buffer), stdin))) {
+ if (sscanf(buffer, "%lu %lu", &i1, &i2) == 2) {
+ c1 = i1;
+ c2 = i2;
+ printf("%lu %lu\n", c1, c2);
+ dk4error_init(&er);
+ c3 = dk4ma_ulong_add(c1, c2, &er);
+ printf("\t+ %lu", c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_ulong_sub(c1, c2, &er);
+ printf("\t- %lu", c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_ulong_mul(c1, c2, &er);
+ printf("\t* %lu", c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_ulong_div(c1, c2, &er);
+ printf("\t/ %lu", c3);
+ show_error(&er);
+ printf("\n");
+ } else {
+ exc = 1;
+ fprintf(stderr, "test-dk4maac:ERROR: Invalid input line!\n");
+ fflush(stderr);
+ cc = 0;
+ }
+ }
+
+
+#line 84 "test-dk4maaul.ctr"
+
+
+#line 85 "test-dk4maaul.ctr"
+ return exc;
+}
+
diff --git a/support/dktools/test-dk4maaul.ctr b/support/dktools/test-dk4maaul.ctr
new file mode 100644
index 0000000000..9f10ab4b3f
--- /dev/null
+++ b/support/dktools/test-dk4maaul.ctr
@@ -0,0 +1,87 @@
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4error.h"
+#include "dk4maaul.h"
+
+$!trace-include
+
+
+static
+void
+show_error(dk4_er_t *erp)
+{
+ if (DK4_E_NONE != erp->ec) {
+ switch(erp->ec) {
+ case DK4_E_MATH_OVERFLOW: {
+ printf(" overflow");
+ } break;
+ case DK4_E_MATH_DIVZERO: {
+ printf(" divzero");
+ } break;
+ default: {
+ printf(" %d", erp->ec);
+ } break;
+ }
+ }
+}
+
+
+
+int main(void)
+{
+ char buffer[128]; /* Input line buffer */
+ dk4_er_t er; /* Error report */
+ unsigned long i1; /* First operand */
+ unsigned long i2; /* Second operand */
+ int exc; /* Exit code */
+ int cc; /* Flag: Can continue */
+ unsigned long c1; /* First operand as char */
+ unsigned long c2; /* Second operand as char */
+ unsigned long c3; /* Result as char */
+
+ $!trace-init test-dk4maac.deb
+ $? "+ main"
+ exc = 0;
+ cc = 1;
+ while((1 == cc) && (fgets(buffer, sizeof(buffer), stdin))) {
+ if (sscanf(buffer, "%lu %lu", &i1, &i2) == 2) {
+ c1 = i1;
+ c2 = i2;
+ printf("%lu %lu\n", c1, c2);
+ dk4error_init(&er);
+ c3 = dk4ma_ulong_add(c1, c2, &er);
+ printf("\t+ %lu", c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_ulong_sub(c1, c2, &er);
+ printf("\t- %lu", c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_ulong_mul(c1, c2, &er);
+ printf("\t* %lu", c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_ulong_div(c1, c2, &er);
+ printf("\t/ %lu", c3);
+ show_error(&er);
+ printf("\n");
+ } else {
+ exc = 1;
+ fprintf(stderr, "test-dk4maac:ERROR: Invalid input line!\n");
+ fflush(stderr);
+ cc = 0;
+ }
+ }
+ $? "- main"
+ $!trace-end
+ return exc;
+}
+
diff --git a/support/dktools/test-dk4maaull.c b/support/dktools/test-dk4maaull.c
new file mode 100644
index 0000000000..f39c0c3164
--- /dev/null
+++ b/support/dktools/test-dk4maaull.c
@@ -0,0 +1,109 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-dk4maaull.ctr
+*/
+
+/** @file test-dk4maaull.c The test-dk4maaull module.
+*/
+
+
+#line 1 "test-dk4maaull.ctr"
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4error.h"
+#include "dk4maalu.h"
+
+
+
+#line 9 "test-dk4maaull.ctr"
+
+
+static
+void
+show_error(dk4_er_t *erp)
+{
+ if (DK4_E_NONE != erp->ec) {
+ switch(erp->ec) {
+ case DK4_E_MATH_OVERFLOW: {
+ printf(" overflow");
+ } break;
+ case DK4_E_MATH_DIVZERO: {
+ printf(" divzero");
+ } break;
+ default: {
+ printf(" %d", erp->ec);
+ } break;
+ }
+ }
+}
+
+
+
+int main(void)
+{
+ char buffer[128]; /* Input line buffer */
+ dk4_er_t er; /* Error report */
+ unsigned long long i1; /* First operand */
+ unsigned long long i2; /* Second operand */
+ int exc; /* Exit code */
+ int cc; /* Flag: Can continue */
+ unsigned long long c1; /* First operand as char */
+ unsigned long long c2; /* Second operand as char */
+ unsigned long long c3; /* Result as char */
+
+
+
+#line 45 "test-dk4maaull.ctr"
+
+
+#line 46 "test-dk4maaull.ctr"
+ exc = 0;
+ cc = 1;
+ while((1 == cc) && (fgets(buffer, sizeof(buffer), stdin))) {
+ if (sscanf(buffer, "%llu %llu", &i1, &i2) == 2) {
+ c1 = i1;
+ c2 = i2;
+ printf("%llu %llu\n", c1, c2);
+ dk4error_init(&er);
+ c3 = dk4ma_ull_add(c1, c2, &er);
+ printf("\t+ %llu", c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_ull_sub(c1, c2, &er);
+ printf("\t- %llu", c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_ull_mul(c1, c2, &er);
+ printf("\t* %llu", c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_ull_div(c1, c2, &er);
+ printf("\t/ %llu", c3);
+ show_error(&er);
+ printf("\n");
+ } else {
+ exc = 1;
+ fprintf(stderr, "test-dk4maac:ERROR: Invalid input line!\n");
+ fflush(stderr);
+ cc = 0;
+ }
+ }
+
+
+#line 84 "test-dk4maaull.ctr"
+
+
+#line 85 "test-dk4maaull.ctr"
+ return exc;
+}
+
diff --git a/support/dktools/test-dk4maaull.ctr b/support/dktools/test-dk4maaull.ctr
new file mode 100644
index 0000000000..8462992b6e
--- /dev/null
+++ b/support/dktools/test-dk4maaull.ctr
@@ -0,0 +1,87 @@
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4error.h"
+#include "dk4maalu.h"
+
+$!trace-include
+
+
+static
+void
+show_error(dk4_er_t *erp)
+{
+ if (DK4_E_NONE != erp->ec) {
+ switch(erp->ec) {
+ case DK4_E_MATH_OVERFLOW: {
+ printf(" overflow");
+ } break;
+ case DK4_E_MATH_DIVZERO: {
+ printf(" divzero");
+ } break;
+ default: {
+ printf(" %d", erp->ec);
+ } break;
+ }
+ }
+}
+
+
+
+int main(void)
+{
+ char buffer[128]; /* Input line buffer */
+ dk4_er_t er; /* Error report */
+ unsigned long long i1; /* First operand */
+ unsigned long long i2; /* Second operand */
+ int exc; /* Exit code */
+ int cc; /* Flag: Can continue */
+ unsigned long long c1; /* First operand as char */
+ unsigned long long c2; /* Second operand as char */
+ unsigned long long c3; /* Result as char */
+
+ $!trace-init test-dk4maac.deb
+ $? "+ main"
+ exc = 0;
+ cc = 1;
+ while((1 == cc) && (fgets(buffer, sizeof(buffer), stdin))) {
+ if (sscanf(buffer, "%llu %llu", &i1, &i2) == 2) {
+ c1 = i1;
+ c2 = i2;
+ printf("%llu %llu\n", c1, c2);
+ dk4error_init(&er);
+ c3 = dk4ma_ull_add(c1, c2, &er);
+ printf("\t+ %llu", c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_ull_sub(c1, c2, &er);
+ printf("\t- %llu", c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_ull_mul(c1, c2, &er);
+ printf("\t* %llu", c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_ull_div(c1, c2, &er);
+ printf("\t/ %llu", c3);
+ show_error(&er);
+ printf("\n");
+ } else {
+ exc = 1;
+ fprintf(stderr, "test-dk4maac:ERROR: Invalid input line!\n");
+ fflush(stderr);
+ cc = 0;
+ }
+ }
+ $? "- main"
+ $!trace-end
+ return exc;
+}
+
diff --git a/support/dktools/test-dk4maaus.c b/support/dktools/test-dk4maaus.c
new file mode 100644
index 0000000000..91003dd3f8
--- /dev/null
+++ b/support/dktools/test-dk4maaus.c
@@ -0,0 +1,110 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-dk4maaus.ctr
+*/
+
+/** @file test-dk4maaus.c The test-dk4maaus module.
+*/
+
+
+#line 1 "test-dk4maaus.ctr"
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4error.h"
+#include "dk4maaus.h"
+
+
+
+#line 10 "test-dk4maaus.ctr"
+
+
+static
+void
+show_error(dk4_er_t *erp)
+{
+ if (DK4_E_NONE != erp->ec) {
+ switch(erp->ec) {
+ case DK4_E_MATH_OVERFLOW: {
+ printf(" overflow");
+ } break;
+ case DK4_E_MATH_DIVZERO: {
+ printf(" divzero");
+ } break;
+ default: {
+ printf(" %u", erp->ec);
+ } break;
+ }
+ }
+}
+
+
+
+int main(void)
+{
+ char buffer[128]; /* Input line buffer */
+ dk4_er_t er; /* Error report */
+ unsigned i1; /* First operand */
+ unsigned i2; /* Second operand */
+ int exc; /* Exit code */
+ int cc; /* Flag: Can continue */
+ unsigned short c1; /* First operand as char */
+ unsigned short c2; /* Second operand as char */
+ unsigned short c3; /* Result as char */
+
+
+
+#line 46 "test-dk4maaus.ctr"
+
+
+#line 47 "test-dk4maaus.ctr"
+ exc = 0;
+ cc = 1;
+ while((1 == cc) && (fgets(buffer, sizeof(buffer), stdin))) {
+ if (sscanf(buffer, "%u %u", &i1, &i2) == 2) {
+ c1 = i1;
+ c2 = i2;
+ printf("%u %u\n", (unsigned)c1, (unsigned)c2);
+ dk4error_init(&er);
+ c3 = dk4ma_ushort_add(c1, c2, &er);
+ printf("\t+ %u", (unsigned)c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_ushort_sub(c1, c2, &er);
+ printf("\t- %u", (unsigned)c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_ushort_mul(c1, c2, &er);
+ printf("\t* %u", (unsigned)c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_ushort_div(c1, c2, &er);
+ printf("\t/ %u", (unsigned)c3);
+ show_error(&er);
+ printf("\n");
+ } else {
+ exc = 1;
+ fprintf(stderr, "test-dk4maac:ERROR: Invalid input line!\n");
+ fflush(stderr);
+ cc = 0;
+ }
+ }
+
+
+#line 85 "test-dk4maaus.ctr"
+
+
+#line 86 "test-dk4maaus.ctr"
+ return exc;
+}
+
diff --git a/support/dktools/test-dk4maaus.ctr b/support/dktools/test-dk4maaus.ctr
new file mode 100644
index 0000000000..d328766b50
--- /dev/null
+++ b/support/dktools/test-dk4maaus.ctr
@@ -0,0 +1,88 @@
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4error.h"
+#include "dk4maaus.h"
+
+$!trace-include
+
+
+static
+void
+show_error(dk4_er_t *erp)
+{
+ if (DK4_E_NONE != erp->ec) {
+ switch(erp->ec) {
+ case DK4_E_MATH_OVERFLOW: {
+ printf(" overflow");
+ } break;
+ case DK4_E_MATH_DIVZERO: {
+ printf(" divzero");
+ } break;
+ default: {
+ printf(" %u", erp->ec);
+ } break;
+ }
+ }
+}
+
+
+
+int main(void)
+{
+ char buffer[128]; /* Input line buffer */
+ dk4_er_t er; /* Error report */
+ unsigned i1; /* First operand */
+ unsigned i2; /* Second operand */
+ int exc; /* Exit code */
+ int cc; /* Flag: Can continue */
+ unsigned short c1; /* First operand as char */
+ unsigned short c2; /* Second operand as char */
+ unsigned short c3; /* Result as char */
+
+ $!trace-init test-dk4maac.deb
+ $? "+ main"
+ exc = 0;
+ cc = 1;
+ while((1 == cc) && (fgets(buffer, sizeof(buffer), stdin))) {
+ if (sscanf(buffer, "%u %u", &i1, &i2) == 2) {
+ c1 = i1;
+ c2 = i2;
+ printf("%u %u\n", (unsigned)c1, (unsigned)c2);
+ dk4error_init(&er);
+ c3 = dk4ma_ushort_add(c1, c2, &er);
+ printf("\t+ %u", (unsigned)c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_ushort_sub(c1, c2, &er);
+ printf("\t- %u", (unsigned)c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_ushort_mul(c1, c2, &er);
+ printf("\t* %u", (unsigned)c3);
+ show_error(&er);
+ printf("\n");
+
+ dk4error_init(&er);
+ c3 = dk4ma_ushort_div(c1, c2, &er);
+ printf("\t/ %u", (unsigned)c3);
+ show_error(&er);
+ printf("\n");
+ } else {
+ exc = 1;
+ fprintf(stderr, "test-dk4maac:ERROR: Invalid input line!\n");
+ fflush(stderr);
+ cc = 0;
+ }
+ }
+ $? "- main"
+ $!trace-end
+ return exc;
+}
+
diff --git a/support/dktools/test-dk4mai8dbl.c b/support/dktools/test-dk4mai8dbl.c
new file mode 100644
index 0000000000..54fd96181e
--- /dev/null
+++ b/support/dktools/test-dk4mai8dbl.c
@@ -0,0 +1,35 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-dk4mai8dbl.ctr
+*/
+
+/** @file test-dk4mai8dbl.c The test-dk4mai8dbl module.
+*/
+
+
+#line 1 "test-dk4mai8dbl.ctr"
+
+#include "dk4conf.h"
+#include <stdio.h>
+#include "dk4mai8dbl.h"
+
+
+
+int main(void)
+{
+ char buf[256];
+ dk4_er_t er;
+ double value;
+ const char *endp;
+ while(fgets(buf, sizeof(buf), stdin)) {
+ dk4error_init(&er);
+ if (0 != dk4ma_input_c8_double(&value, buf, &endp, 1, &er)) {
+ printf("Value: %g\n", value);
+ } else {
+ printf("ERROR: %d\n", er.ec);
+ }
+ }
+ return 0;
+}
diff --git a/support/dktools/test-dk4mai8dbl.ctr b/support/dktools/test-dk4mai8dbl.ctr
new file mode 100644
index 0000000000..f8b7e96761
--- /dev/null
+++ b/support/dktools/test-dk4mai8dbl.ctr
@@ -0,0 +1,23 @@
+
+#include "dk4conf.h"
+#include <stdio.h>
+#include "dk4mai8dbl.h"
+
+
+
+int main(void)
+{
+ char buf[256];
+ dk4_er_t er;
+ double value;
+ const char *endp;
+ while(fgets(buf, sizeof(buf), stdin)) {
+ dk4error_init(&er);
+ if (0 != dk4ma_input_c8_double(&value, buf, &endp, 1, &er)) {
+ printf("Value: %g\n", value);
+ } else {
+ printf("ERROR: %d\n", er.ec);
+ }
+ }
+ return 0;
+}
diff --git a/support/dktools/test-dk4mai8ddi.c b/support/dktools/test-dk4mai8ddi.c
new file mode 100644
index 0000000000..c3c20a99ac
--- /dev/null
+++ b/support/dktools/test-dk4mai8ddi.c
@@ -0,0 +1,52 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-dk4mai8ddi.ctr
+*/
+
+/** @file test-dk4mai8ddi.c The test-dk4mai8ddi module.
+*/
+
+
+#line 1 "test-dk4mai8ddi.ctr"
+
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4str8.h"
+#include "dk4mao8d.h"
+#include "dk4mai8ddi.h"
+
+
+
+int main(void)
+{
+ char buf[128];
+ char oub[128];
+ dk4_er_t er;
+ const char *endptr = NULL;
+ dk4_im_t um;
+ int res;
+ while(fgets(buf, sizeof(buf), stdin)) {
+ dk4str8_normalize(buf, NULL);
+ dk4error_init(&er);
+ res = dk4ma_input_c8_dec_dk4_im_t(&um, buf, &endptr, 1, &er);
+ if (0 != res) {
+ if (dk4ma_write_c8_decimal_signed(oub, sizeof(oub), um, 0, &er)) {
+ printf("Zahl gelesen: ");
+ fputs(oub, stdout);
+ printf("\n");
+ } else {
+ printf("Fehler beim String-Erzeugen!\n");
+ }
+ } else {
+ printf("Fehler beim Einlesen: %d\n", er.ec);
+ printf("Fehlerstelle: \"%s\"\n", (endptr ? endptr : "(NULL)"));
+ }
+ }
+ return 0;
+}
+
diff --git a/support/dktools/test-dk4mai8ddi.ctr b/support/dktools/test-dk4mai8ddi.ctr
new file mode 100644
index 0000000000..027765c2de
--- /dev/null
+++ b/support/dktools/test-dk4mai8ddi.ctr
@@ -0,0 +1,40 @@
+
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4str8.h"
+#include "dk4mao8d.h"
+#include "dk4mai8ddi.h"
+
+
+
+int main(void)
+{
+ char buf[128];
+ char oub[128];
+ dk4_er_t er;
+ const char *endptr = NULL;
+ dk4_im_t um;
+ int res;
+ while(fgets(buf, sizeof(buf), stdin)) {
+ dk4str8_normalize(buf, NULL);
+ dk4error_init(&er);
+ res = dk4ma_input_c8_dec_dk4_im_t(&um, buf, &endptr, 1, &er);
+ if (0 != res) {
+ if (dk4ma_write_c8_decimal_signed(oub, sizeof(oub), um, 0, &er)) {
+ printf("Zahl gelesen: ");
+ fputs(oub, stdout);
+ printf("\n");
+ } else {
+ printf("Fehler beim String-Erzeugen!\n");
+ }
+ } else {
+ printf("Fehler beim Einlesen: %d\n", er.ec);
+ printf("Fehlerstelle: \"%s\"\n", (endptr ? endptr : "(NULL)"));
+ }
+ }
+ return 0;
+}
+
diff --git a/support/dktools/test-dk4mai8ddu.c b/support/dktools/test-dk4mai8ddu.c
new file mode 100644
index 0000000000..11c56c7025
--- /dev/null
+++ b/support/dktools/test-dk4mai8ddu.c
@@ -0,0 +1,52 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-dk4mai8ddu.ctr
+*/
+
+/** @file test-dk4mai8ddu.c The test-dk4mai8ddu module.
+*/
+
+
+#line 1 "test-dk4mai8ddu.ctr"
+
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4str8.h"
+#include "dk4mao8d.h"
+#include "dk4mai8ddu.h"
+
+
+
+int main(void)
+{
+ char buf[128];
+ char oub[128];
+ dk4_er_t er;
+ const char *endptr = NULL;
+ dk4_um_t um;
+ int res;
+ while(fgets(buf, sizeof(buf), stdin)) {
+ dk4str8_normalize(buf, NULL);
+ dk4error_init(&er);
+ res = dk4ma_input_c8_dec_dk4_um_t(&um, buf, &endptr, 1, &er);
+ if (0 != res) {
+ if (dk4ma_write_c8_decimal_unsigned(oub, sizeof(oub), um, 0, &er)) {
+ printf("Zahl gelesen: ");
+ fputs(oub, stdout);
+ printf("\n");
+ } else {
+ printf("Fehler beim String-Erzeugen!\n");
+ }
+ } else {
+ printf("Fehler beim Einlesen: %d\n", er.ec);
+ printf("Fehlerstelle: \"%s\"\n", (endptr ? endptr : "(NULL)"));
+ }
+ }
+ return 0;
+}
+
diff --git a/support/dktools/test-dk4mai8ddu.ctr b/support/dktools/test-dk4mai8ddu.ctr
new file mode 100644
index 0000000000..8f66f785a2
--- /dev/null
+++ b/support/dktools/test-dk4mai8ddu.ctr
@@ -0,0 +1,40 @@
+
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4str8.h"
+#include "dk4mao8d.h"
+#include "dk4mai8ddu.h"
+
+
+
+int main(void)
+{
+ char buf[128];
+ char oub[128];
+ dk4_er_t er;
+ const char *endptr = NULL;
+ dk4_um_t um;
+ int res;
+ while(fgets(buf, sizeof(buf), stdin)) {
+ dk4str8_normalize(buf, NULL);
+ dk4error_init(&er);
+ res = dk4ma_input_c8_dec_dk4_um_t(&um, buf, &endptr, 1, &er);
+ if (0 != res) {
+ if (dk4ma_write_c8_decimal_unsigned(oub, sizeof(oub), um, 0, &er)) {
+ printf("Zahl gelesen: ");
+ fputs(oub, stdout);
+ printf("\n");
+ } else {
+ printf("Fehler beim String-Erzeugen!\n");
+ }
+ } else {
+ printf("Fehler beim Einlesen: %d\n", er.ec);
+ printf("Fehlerstelle: \"%s\"\n", (endptr ? endptr : "(NULL)"));
+ }
+ }
+ return 0;
+}
+
diff --git a/support/dktools/test-dk4mai8dsz.c b/support/dktools/test-dk4mai8dsz.c
new file mode 100644
index 0000000000..b0a492683f
--- /dev/null
+++ b/support/dktools/test-dk4mai8dsz.c
@@ -0,0 +1,52 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-dk4mai8dsz.ctr
+*/
+
+/** @file test-dk4mai8dsz.c The test-dk4mai8dsz module.
+*/
+
+
+#line 1 "test-dk4mai8dsz.ctr"
+
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4str8.h"
+#include "dk4mao8d.h"
+#include "dk4mai8dsz.h"
+
+
+
+int main(void)
+{
+ char buf[128];
+ char oub[128];
+ dk4_er_t er;
+ const char *endptr = NULL;
+ size_t um;
+ int res;
+ while(fgets(buf, sizeof(buf), stdin)) {
+ dk4str8_normalize(buf, NULL);
+ dk4error_init(&er);
+ res = dk4ma_input_c8_dec_size_t(&um, buf, &endptr, 1, &er);
+ if (0 != res) {
+ if (dk4ma_write_c8_decimal_unsigned(oub,sizeof(oub),(dk4_um_t)um,0,&er)) {
+ printf("Zahl gelesen: ");
+ fputs(oub, stdout);
+ printf("\n");
+ } else {
+ printf("Fehler beim String-Erzeugen!\n");
+ }
+ } else {
+ printf("Fehler beim Einlesen: %d\n", er.ec);
+ printf("Fehlerstelle: \"%s\"\n", (endptr ? endptr : "(NULL)"));
+ }
+ }
+ return 0;
+}
+
diff --git a/support/dktools/test-dk4mai8dsz.ctr b/support/dktools/test-dk4mai8dsz.ctr
new file mode 100644
index 0000000000..4cee4ab620
--- /dev/null
+++ b/support/dktools/test-dk4mai8dsz.ctr
@@ -0,0 +1,40 @@
+
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4str8.h"
+#include "dk4mao8d.h"
+#include "dk4mai8dsz.h"
+
+
+
+int main(void)
+{
+ char buf[128];
+ char oub[128];
+ dk4_er_t er;
+ const char *endptr = NULL;
+ size_t um;
+ int res;
+ while(fgets(buf, sizeof(buf), stdin)) {
+ dk4str8_normalize(buf, NULL);
+ dk4error_init(&er);
+ res = dk4ma_input_c8_dec_size_t(&um, buf, &endptr, 1, &er);
+ if (0 != res) {
+ if (dk4ma_write_c8_decimal_unsigned(oub,sizeof(oub),(dk4_um_t)um,0,&er)) {
+ printf("Zahl gelesen: ");
+ fputs(oub, stdout);
+ printf("\n");
+ } else {
+ printf("Fehler beim String-Erzeugen!\n");
+ }
+ } else {
+ printf("Fehler beim Einlesen: %d\n", er.ec);
+ printf("Fehlerstelle: \"%s\"\n", (endptr ? endptr : "(NULL)"));
+ }
+ }
+ return 0;
+}
+
diff --git a/support/dktools/test-dk4mai8sz.c b/support/dktools/test-dk4mai8sz.c
new file mode 100644
index 0000000000..326aa9a12e
--- /dev/null
+++ b/support/dktools/test-dk4mai8sz.c
@@ -0,0 +1,52 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-dk4mai8sz.ctr
+*/
+
+/** @file test-dk4mai8sz.c The test-dk4mai8sz module.
+*/
+
+
+#line 1 "test-dk4mai8sz.ctr"
+
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4str8.h"
+#include "dk4mao8d.h"
+#include "dk4mai8dsz.h"
+
+
+
+int main(void)
+{
+ char buf[128];
+ char oub[128];
+ dk4_er_t er;
+ char *endptr = NULL;
+ size_t um;
+ int res;
+ while(fgets(buf, sizeof(buf), stdin)) {
+ dk4str8_normalize(buf, NULL);
+ dk4error_init(&er);
+ res = dk4ma_input_c8_dec_size_t(&um, buf, &endptr, 1, &er);
+ if (0 != res) {
+ if (dk4ma_write_c8_decimal_unsigned(oub, sizeof(oub), (dk4_um_t)um, &er)) {
+ printf("Zahl gelesen: ");
+ fputs(oub, stdout);
+ printf("\n");
+ } else {
+ printf("Fehler beim String-Erzeugen!\n");
+ }
+ } else {
+ printf("Fehler beim Einlesen: %d\n", er.ec);
+ printf("Fehlerstelle: \"%s\"\n", (endptr ? endptr : "(NULL)"));
+ }
+ }
+ return 0;
+}
+
diff --git a/support/dktools/test-dk4numl.c b/support/dktools/test-dk4numl.c
new file mode 100644
index 0000000000..fdd0165477
--- /dev/null
+++ b/support/dktools/test-dk4numl.c
@@ -0,0 +1,36 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-dk4numl.ctr
+*/
+
+/** @file test-dk4numl.c The test-dk4numl module.
+*/
+
+
+#line 1 "test-dk4numl.ctr"
+
+#include <stdio.h>
+
+#include "dk4numl.h"
+
+static const size_t sizes[] = {
+ 1, 2, 4, 8, 16, 32, 64, 65, 128, 256
+};
+static const size_t sz_sizes = sizeof(sizes)/sizeof(size_t);
+
+int main(void)
+{
+ size_t i;
+
+ for (i = 0; i < sz_sizes; i++) {
+ printf("Bytes: %u Unsigned: %u Signed: %u\n",
+ (unsigned)sizes[i],
+ (unsigned)dk4numlength(sizes[i], 0),
+ (unsigned)dk4numlength(sizes[i], 1)
+ );
+ }
+ return 0;
+}
+
diff --git a/support/dktools/test-dk4numl.ctr b/support/dktools/test-dk4numl.ctr
new file mode 100644
index 0000000000..8d66df1ffc
--- /dev/null
+++ b/support/dktools/test-dk4numl.ctr
@@ -0,0 +1,24 @@
+
+#include <stdio.h>
+
+#include "dk4numl.h"
+
+static const size_t sizes[] = {
+ 1, 2, 4, 8, 16, 32, 64, 65, 128, 256
+};
+static const size_t sz_sizes = sizeof(sizes)/sizeof(size_t);
+
+int main(void)
+{
+ size_t i;
+
+ for (i = 0; i < sz_sizes; i++) {
+ printf("Bytes: %u Unsigned: %u Signed: %u\n",
+ (unsigned)sizes[i],
+ (unsigned)dk4numlength(sizes[i], 0),
+ (unsigned)dk4numlength(sizes[i], 1)
+ );
+ }
+ return 0;
+}
+
diff --git a/support/dktools/test-dk4path8.c b/support/dktools/test-dk4path8.c
new file mode 100644
index 0000000000..2770be8f70
--- /dev/null
+++ b/support/dktools/test-dk4path8.c
@@ -0,0 +1,54 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-dk4path8.ctr
+*/
+
+/** @file test-dk4path8.c The test-dk4path8 module.
+*/
+
+
+#line 1 "test-dk4path8.ctr"
+
+#include <stdio.h>
+
+#include "dk4path8.h"
+#include "string.h"
+
+static const char * const p1[] = {
+"/usr/local",
+"my/file"
+};
+
+static const char * const p2[] = {
+"../erwin.txt",
+"../../bla.blubb",
+"../../../test.was.passiert",
+"ganz-langer-test-was-nun-wohl-passiert"
+};
+
+int main(void)
+{
+ char buf[256];
+ dk4_er_t er;
+ const size_t szp1 = sizeof(p1)/sizeof(DK4_PCHAR);
+ const size_t szp2 = sizeof(p2)/sizeof(DK4_PCHAR);
+ size_t i;
+ size_t j;
+
+ for (i = 0; i < szp1; i++) {
+ for (j = 0; j < szp2; j++) {
+ strcpy(buf, p1[i]);
+ dk4error_init(&er);
+ if (dk4path8_append(buf, sizeof(buf), p2[j], &er)) {
+ printf("%u %u = \"%s\"\n", (unsigned)i, (unsigned)j, buf);
+ } else {
+ printf("%u %u ERROR %d\n", (unsigned)i, (unsigned)j, er.ec);
+ }
+ }
+ }
+ return 0;
+}
+
+
diff --git a/support/dktools/test-dk4path8.ctr b/support/dktools/test-dk4path8.ctr
new file mode 100644
index 0000000000..788aa705dd
--- /dev/null
+++ b/support/dktools/test-dk4path8.ctr
@@ -0,0 +1,42 @@
+
+#include <stdio.h>
+
+#include "dk4path8.h"
+#include "string.h"
+
+static const char * const p1[] = {
+"/usr/local",
+"my/file"
+};
+
+static const char * const p2[] = {
+"../erwin.txt",
+"../../bla.blubb",
+"../../../test.was.passiert",
+"ganz-langer-test-was-nun-wohl-passiert"
+};
+
+int main(void)
+{
+ char buf[256];
+ dk4_er_t er;
+ const size_t szp1 = sizeof(p1)/sizeof(DK4_PCHAR);
+ const size_t szp2 = sizeof(p2)/sizeof(DK4_PCHAR);
+ size_t i;
+ size_t j;
+
+ for (i = 0; i < szp1; i++) {
+ for (j = 0; j < szp2; j++) {
+ strcpy(buf, p1[i]);
+ dk4error_init(&er);
+ if (dk4path8_append(buf, sizeof(buf), p2[j], &er)) {
+ printf("%u %u = \"%s\"\n", (unsigned)i, (unsigned)j, buf);
+ } else {
+ printf("%u %u ERROR %d\n", (unsigned)i, (unsigned)j, er.ec);
+ }
+ }
+ }
+ return 0;
+}
+
+
diff --git a/support/dktools/test-dk4str8.c b/support/dktools/test-dk4str8.c
new file mode 100644
index 0000000000..05e48be6e3
--- /dev/null
+++ b/support/dktools/test-dk4str8.c
@@ -0,0 +1,60 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-dk4str8.ctr
+*/
+
+/** @file test-dk4str8.c The test-dk4str8 module.
+*/
+
+
+#line 1 "test-dk4str8.ctr"
+
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+#include <stdio.h>
+
+#include "dk4mem.h"
+#include "dk4error.h"
+#include "dk4str8.h"
+
+
+int main(void)
+{
+ char buffer[256];
+ char *p1;
+ char *p2;
+
+
+#line 19 "test-dk4str8.ctr"
+
+
+#line 20 "test-dk4str8.ctr"
+ while(NULL != fgets(buffer, sizeof(buffer), stdin)) {
+ dk4str8_normalize(buffer, NULL);
+ p1 = dk4str8_start(buffer, NULL);
+ if (NULL != p1) {
+ p2 = dk4str8_next(p1, NULL);
+ if (NULL != p2) {
+ printf("p1 = \"%s\"\n", p1);
+ printf("p2 = \"%s\"\n", p2);
+ if (dk4str8_is_abbr(p1, p2, '$', 1)) {
+ printf("yes\n");
+ } else {
+ printf("no\n");
+ }
+ }
+ }
+ }
+
+
+#line 37 "test-dk4str8.ctr"
+
+
+#line 38 "test-dk4str8.ctr"
+ return 0;
+}
+
diff --git a/support/dktools/test-dk4str8.ctr b/support/dktools/test-dk4str8.ctr
new file mode 100644
index 0000000000..9d22ae90f7
--- /dev/null
+++ b/support/dktools/test-dk4str8.ctr
@@ -0,0 +1,40 @@
+
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+#include <stdio.h>
+
+#include "dk4mem.h"
+#include "dk4error.h"
+#include "dk4str8.h"
+
+
+int main(void)
+{
+ char buffer[256];
+ char *p1;
+ char *p2;
+ $!trace-init test-dk4str8.deb
+ $? "+ main"
+ while(NULL != fgets(buffer, sizeof(buffer), stdin)) {
+ dk4str8_normalize(buffer, NULL);
+ p1 = dk4str8_start(buffer, NULL);
+ if (NULL != p1) {
+ p2 = dk4str8_next(p1, NULL);
+ if (NULL != p2) {
+ printf("p1 = \"%s\"\n", p1);
+ printf("p2 = \"%s\"\n", p2);
+ if (dk4str8_is_abbr(p1, p2, '$', 1)) {
+ printf("yes\n");
+ } else {
+ printf("no\n");
+ }
+ }
+ }
+ }
+ $? "- main"
+ $!trace-end
+ return 0;
+}
+
diff --git a/support/dktools/test-dk4strm.c b/support/dktools/test-dk4strm.c
new file mode 100644
index 0000000000..f817411606
--- /dev/null
+++ b/support/dktools/test-dk4strm.c
@@ -0,0 +1,89 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-dk4strm.ctr
+*/
+
+/** @file test-dk4strm.c The test-dk4strm module.
+*/
+
+
+#line 1 "test-dk4strm.ctr"
+
+#include "dk4strm.h"
+#include "dk4strmf.h"
+#include "dk4fopc8.h"
+#include <stdio.h>
+
+
+
+
+
+#line 10 "test-dk4strm.ctr"
+
+
+
+
+int main(int argc, char *argv[])
+{
+ FILE *fipo;
+ dk4_stream_t *outstrm;
+ dk4_stream_t *instrm;
+ dk4_er_t er;
+ char c;
+
+
+#line 22 "test-dk4strm.ctr"
+
+
+#line 23 "test-dk4strm.ctr"
+ if (1 < argc) {
+ dk4error_init(&er);
+ fipo = dk4fopen_c8(argv[1], "w", 0, &er);
+ if (NULL != fipo) {
+ dk4error_init(&er);
+ instrm = dk4stream_open_for_file(stdin, DK4_STREAM_READ, 4096, 0, &er);
+ if (NULL != instrm) {
+ outstrm = dk4stream_open_for_file(fipo, DK4_STREAM_WRITE, 0, 4096, &er);
+ if (NULL != outstrm) {
+ while (dk4stream_c8_read_byte(&c, instrm, &er)) {
+ dk4stream_write_byte(outstrm, (char)c, &er);
+ }
+ (void)dk4stream_close(outstrm, &er);
+ }
+ (void)dk4stream_close(instrm, &er);
+ }
+ fclose(fipo);
+ } else {
+ fprintf(stderr, "Failed to open file %d %d\n", er.ec, er.dt.iDetails1);
+ }
+ } else {
+ dk4error_init(&er);
+ instrm = dk4stream_open_for_file(stdin, DK4_STREAM_READ, 4096, 0, &er);
+ if (NULL != instrm) {
+
+#line 47 "test-dk4strm.ctr"
+ outstrm = dk4stream_open_for_file(stdout, DK4_STREAM_WRITE, 0, 4096, &er);
+ if (NULL != outstrm) {
+
+#line 49 "test-dk4strm.ctr"
+ while (dk4stream_c8_read_byte(&c, instrm, &er)) {
+ dk4stream_write_byte(outstrm, (char)c, &er);
+ }
+ dk4stream_close(outstrm, &er);
+ }
+ dk4stream_close(instrm, &er);
+ }
+ }
+
+
+#line 58 "test-dk4strm.ctr"
+
+
+#line 59 "test-dk4strm.ctr"
+ fprintf(stderr, "Error code: %d\n", er.ec);
+ return 0;
+}
+
+
diff --git a/support/dktools/test-dk4strm.ctr b/support/dktools/test-dk4strm.ctr
new file mode 100644
index 0000000000..e269597891
--- /dev/null
+++ b/support/dktools/test-dk4strm.ctr
@@ -0,0 +1,63 @@
+
+#include "dk4strm.h"
+#include "dk4strmf.h"
+#include "dk4fopc8.h"
+#include <stdio.h>
+
+
+
+$!trace-include
+
+
+
+
+int main(int argc, char *argv[])
+{
+ FILE *fipo;
+ dk4_stream_t *outstrm;
+ dk4_stream_t *instrm;
+ dk4_er_t er;
+ char c;
+ $!trace-init "test-dk4strm.deb"
+ $? "+ main"
+ if (1 < argc) {
+ dk4error_init(&er);
+ fipo = dk4fopen_c8(argv[1], "w", 0, &er);
+ if (NULL != fipo) {
+ dk4error_init(&er);
+ instrm = dk4stream_open_for_file(stdin, DK4_STREAM_READ, 4096, 0, &er);
+ if (NULL != instrm) {
+ outstrm = dk4stream_open_for_file(fipo, DK4_STREAM_WRITE, 0, 4096, &er);
+ if (NULL != outstrm) {
+ while (dk4stream_c8_read_byte(&c, instrm, &er)) {
+ dk4stream_write_byte(outstrm, (char)c, &er);
+ }
+ (void)dk4stream_close(outstrm, &er);
+ }
+ (void)dk4stream_close(instrm, &er);
+ }
+ fclose(fipo);
+ } else {
+ fprintf(stderr, "Failed to open file %d %d\n", er.ec, er.dt.iDetails1);
+ }
+ } else {
+ dk4error_init(&er);
+ instrm = dk4stream_open_for_file(stdin, DK4_STREAM_READ, 4096, 0, &er);
+ if (NULL != instrm) { $? ". instream ok"
+ outstrm = dk4stream_open_for_file(stdout, DK4_STREAM_WRITE, 0, 4096, &er);
+ if (NULL != outstrm) { $? ". outstream ok"
+ while (dk4stream_c8_read_byte(&c, instrm, &er)) {
+ dk4stream_write_byte(outstrm, (char)c, &er);
+ }
+ dk4stream_close(outstrm, &er);
+ }
+ dk4stream_close(instrm, &er);
+ }
+ }
+ $? "- main"
+ $!trace-end
+ fprintf(stderr, "Error code: %d\n", er.ec);
+ return 0;
+}
+
+
diff --git a/support/dktools/test-dk4strmco.c b/support/dktools/test-dk4strmco.c
new file mode 100644
index 0000000000..fb89b49fd4
--- /dev/null
+++ b/support/dktools/test-dk4strmco.c
@@ -0,0 +1,101 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-dk4strmco.ctr
+*/
+
+/** @file test-dk4strmco.c The test-dk4strmco module.
+*/
+
+
+#line 1 "test-dk4strmco.ctr"
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4strmf.h"
+#include "dk4strmco.h"
+
+
+
+
+
+#line 12 "test-dk4strmco.ctr"
+
+
+
+int main(void)
+{
+ char buf[4096];
+ dk4_stream_t *fstrm = NULL;
+ dk4_stream_t *cstrm = NULL;
+ size_t szbuf = sizeof(buf);
+ size_t br;
+ int res;
+
+
+#line 24 "test-dk4strmco.ctr"
+
+
+#line 25 "test-dk4strmco.ctr"
+ fstrm = dk4stream_open_for_file(
+ stdout, DK4_STREAM_WRITE, 0, 4096, NULL
+ );
+ if (NULL == fstrm) {
+ fputs("ERROR: Failed to open stream for stdout!\n", stderr);
+ fflush(stderr);
+ goto finished;
+ }
+
+ cstrm = dk4strmco_open(
+ fstrm,
+ DK4_STRMCO_PP_NONE, DK4_STRMCO_CO_FLATE, DK4_STRMCO_OE_ASCII85,
+ (DK4_STRMCO_FL_EOD_OE | DK4_STRMCO_FL_NL_OE),
+ NULL
+ );
+ if (NULL == cstrm) {
+ fputs("ERROR: Failed to open compressing stream!\n", stderr);
+ fflush(stderr);
+ goto finished;
+ }
+
+ do {
+ br = fread(buf, 1, szbuf, stdin);
+ if (0 < br) {
+ res = dk4stream_write(cstrm, buf, br, NULL);
+ if (0 == res) {
+ fputs("ERROR: Write operation failed!\n", stderr);
+ fflush(stderr);
+ }
+ }
+ } while ((!feof(stdin)) && (0 < br));
+
+ finished:
+ if (NULL != cstrm) {
+ res = dk4stream_close(cstrm, NULL);
+ if (0 == res) {
+ fputs("ERROR: Failed to close compressed stream!\n", stderr);
+ fflush(stderr);
+ }
+ }
+ if (NULL != fstrm) {
+ res = dk4stream_close(fstrm, NULL);
+ if (0 == res) {
+ fputs("ERROR: Failed to close file stream!\n", stderr);
+ fflush(stderr);
+ }
+ }
+
+
+#line 73 "test-dk4strmco.ctr"
+
+
+#line 74 "test-dk4strmco.ctr"
+ return 0;
+}
+
+
+/* vim: set ai sw=4 ts=4 : */
+
diff --git a/support/dktools/test-dk4strmco.ctr b/support/dktools/test-dk4strmco.ctr
new file mode 100644
index 0000000000..4f2e20855e
--- /dev/null
+++ b/support/dktools/test-dk4strmco.ctr
@@ -0,0 +1,79 @@
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4strmf.h"
+#include "dk4strmco.h"
+
+
+
+$!trace-include
+
+
+
+int main(void)
+{
+ char buf[4096];
+ dk4_stream_t *fstrm = NULL;
+ dk4_stream_t *cstrm = NULL;
+ size_t szbuf = sizeof(buf);
+ size_t br;
+ int res;
+ $!trace-init test-dk4strmco.deb
+ $? "+ main"
+ fstrm = dk4stream_open_for_file(
+ stdout, DK4_STREAM_WRITE, 0, 4096, NULL
+ );
+ if (NULL == fstrm) {
+ fputs("ERROR: Failed to open stream for stdout!\n", stderr);
+ fflush(stderr);
+ goto finished;
+ }
+
+ cstrm = dk4strmco_open(
+ fstrm,
+ DK4_STRMCO_PP_NONE, DK4_STRMCO_CO_FLATE, DK4_STRMCO_OE_ASCII85,
+ (DK4_STRMCO_FL_EOD_OE | DK4_STRMCO_FL_NL_OE),
+ NULL
+ );
+ if (NULL == cstrm) {
+ fputs("ERROR: Failed to open compressing stream!\n", stderr);
+ fflush(stderr);
+ goto finished;
+ }
+
+ do {
+ br = fread(buf, 1, szbuf, stdin);
+ if (0 < br) {
+ res = dk4stream_write(cstrm, buf, br, NULL);
+ if (0 == res) {
+ fputs("ERROR: Write operation failed!\n", stderr);
+ fflush(stderr);
+ }
+ }
+ } while ((!feof(stdin)) && (0 < br));
+
+ finished:
+ if (NULL != cstrm) {
+ res = dk4stream_close(cstrm, NULL);
+ if (0 == res) {
+ fputs("ERROR: Failed to close compressed stream!\n", stderr);
+ fflush(stderr);
+ }
+ }
+ if (NULL != fstrm) {
+ res = dk4stream_close(fstrm, NULL);
+ if (0 == res) {
+ fputs("ERROR: Failed to close file stream!\n", stderr);
+ fflush(stderr);
+ }
+ }
+ $? "- main"
+ $!trace-end
+ return 0;
+}
+
+
+/* vim: set ai sw=4 ts=4 : */
+
diff --git a/support/dktools/test-dk4time.c b/support/dktools/test-dk4time.c
new file mode 100644
index 0000000000..209a96c4a1
--- /dev/null
+++ b/support/dktools/test-dk4time.c
@@ -0,0 +1,32 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-dk4time.ctr
+*/
+
+/** @file test-dk4time.c The test-dk4time module.
+*/
+
+
+#line 1 "test-dk4time.ctr"
+
+#include <stdio.h>
+
+#include "dk4conf.h"
+#include "dk4time.h"
+
+
+
+int main(void)
+{
+ char buffer[64];
+ dk4_time_t timer;
+
+ dk4time_get(&timer);
+ if (dk4time_as_text(buffer, sizeof(buffer), &timer, NULL)) {
+ fputs(buffer, stdout);
+ fputc('\n', stdout);
+ }
+ return 0;
+}
diff --git a/support/dktools/test-dk4time.ctr b/support/dktools/test-dk4time.ctr
new file mode 100644
index 0000000000..cf184ac23b
--- /dev/null
+++ b/support/dktools/test-dk4time.ctr
@@ -0,0 +1,20 @@
+
+#include <stdio.h>
+
+#include "dk4conf.h"
+#include "dk4time.h"
+
+
+
+int main(void)
+{
+ char buffer[64];
+ dk4_time_t timer;
+
+ dk4time_get(&timer);
+ if (dk4time_as_text(buffer, sizeof(buffer), &timer, NULL)) {
+ fputs(buffer, stdout);
+ fputc('\n', stdout);
+ }
+ return 0;
+}
diff --git a/support/dktools/test-dk4time08.c b/support/dktools/test-dk4time08.c
new file mode 100644
index 0000000000..d9ef9a1510
--- /dev/null
+++ b/support/dktools/test-dk4time08.c
@@ -0,0 +1,32 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-dk4time08.ctr
+*/
+
+/** @file test-dk4time08.c The test-dk4time08 module.
+*/
+
+
+#line 1 "test-dk4time08.ctr"
+
+#include <stdio.h>
+#include "dk4time08.h"
+
+int main(int argc, char *argv[])
+{
+ char buffer[64];
+ int res;
+ res = dk4time_to_text_c8(
+ buffer, sizeof(buffer), DK4_TIMEFORMAT_DATE_GERMAN,
+ 2015, 1, 25, 14, 10, 35, NULL
+ );
+ if (0 != res) {
+ fputs(buffer, stdout);
+ fputc('\n', stdout);
+ }
+ return 0;
+}
+
+
diff --git a/support/dktools/test-dk4time08.ctr b/support/dktools/test-dk4time08.ctr
new file mode 100644
index 0000000000..7dbe20ee6a
--- /dev/null
+++ b/support/dktools/test-dk4time08.ctr
@@ -0,0 +1,20 @@
+
+#include <stdio.h>
+#include "dk4time08.h"
+
+int main(int argc, char *argv[])
+{
+ char buffer[64];
+ int res;
+ res = dk4time_to_text_c8(
+ buffer, sizeof(buffer), DK4_TIMEFORMAT_DATE_GERMAN,
+ 2015, 1, 25, 14, 10, 35, NULL
+ );
+ if (0 != res) {
+ fputs(buffer, stdout);
+ fputc('\n', stdout);
+ }
+ return 0;
+}
+
+
diff --git a/support/dktools/test-dk4tsp08.c b/support/dktools/test-dk4tsp08.c
new file mode 100644
index 0000000000..3dec48053f
--- /dev/null
+++ b/support/dktools/test-dk4tsp08.c
@@ -0,0 +1,191 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-dk4tsp08.ctr
+*/
+
+/** @file test-dk4tsp08.c The test-dk4tsp08 module.
+*/
+
+
+#line 1 "test-dk4tsp08.ctr"
+
+#include "dk4conf.h"
+#include "dk4enc.h"
+#include "dk4tsp08.h"
+#include "dk4strm.h"
+#include "dk4strmf.h"
+#include "dk4strmo32.h"
+#include "dk4ansi.h"
+#include <string.h>
+
+
+
+
+#line 13 "test-dk4tsp08.ctr"
+
+
+
+#define LINE_VERSION 1
+
+
+/** Buffer for input from file.
+*/
+static char fbuf[4096];
+
+
+#if LINE_VERSION
+static char lbuf[4096];
+#endif
+
+
+#if LINE_VERSION
+int
+line_handler(void *obj, char *line, dk4_um_t lineno, dk4_er_t *erp)
+{
+ size_t sz;
+ int back = DK4_TSP_RES_ERROR;
+ sz = strlen(line);
+ if (0 < sz) {
+ if (0 != dk4stream_write( (dk4_stream_t *)obj, line, sz, erp)) {
+ back = DK4_TSP_RES_OK;
+ }
+ } else {
+ back = DK4_TSP_RES_OK;
+ }
+ return back;
+}
+#else
+int
+char_handler(void *obj, char c, dk4_text_stream_position_t *pos, dk4_er_t *erp)
+{
+ dk4_c32_t c32;
+ int back = DK4_TSP_RES_ERROR;
+ if (dk4ansi_decode(&c32, (unsigned char)c)) {
+ if (dk4stream_c32_putc((dk4_stream_t *)obj, c32, erp)) {
+ back = DK4_TSP_RES_OK;
+ }
+ }
+ return back;
+}
+#endif
+
+
+
+int main(void)
+{
+ dk4_tsp08_t tsp; /* Text stream processor. */
+ dk4_er_t er; /* Error report */
+ dk4_stream_t *outstream; /* Output stream */
+ size_t nread; /* Number of bytes read */
+#if DK4_ON_WINDOWS
+ int oldmode; /* Output text or binary mode */
+ int oldinmode; /* Input text or binary mode */
+#endif
+ int res; /* Result for text stream processing */
+ int oldres; /* Previous result */
+ int cc; /* Flag: Can continue */
+
+
+#line 76 "test-dk4tsp08.ctr"
+
+
+#line 77 "test-dk4tsp08.ctr"
+#if DK4_ON_WINDOWS
+ oldmode = _setmode(_fileno(stdout), _O_BINARY);
+ oldinmode = _setmode(_fileno(stdin), _O_BINARY);
+#endif
+ dk4error_init(&er);
+ outstream = dk4stream_open_for_file( stdout, DK4_STREAM_WRITE, 0, 0, &er);
+ if (NULL != outstream) {
+ dk4stream_set_output_encoding(outstream, DK4_FILE_ENCODING_ASCII);
+#if 1
+ (void)dk4stream_write_bom_if_necessary(outstream, NULL);
+#endif
+#if LINE_VERSION
+ res = dk4tsp08_setup_line(
+ &tsp, (void *)outstream, line_handler, lbuf, sizeof(lbuf),
+ DK4_ENCODING_ASCII, DK4_ENCODING_UTF8, &er
+ );
+#else
+ res = dk4tsp08_setup_char(
+ &tsp, (void *)outstream, char_handler,
+ DK4_ENCODING_UTF8, DK4_ENCODING_UTF8, &er
+ );
+#endif
+ if (DK4_TSP_RES_OK == res) {
+ oldres = DK4_TSP_RES_OK;
+ cc = 1;
+ while (1 == cc) {
+ nread = fread(fbuf, 1, sizeof(fbuf), stdin);
+ if (0 < nread) {
+ res = dk4tsp08_add_bytes(&tsp, (unsigned char *)fbuf, nread);
+ switch (res) {
+ case DK4_TSP_RES_OK: {
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == oldres) {
+ oldres = DK4_TSP_RES_ERROR;
+
+
+#line 113 "test-dk4tsp08.ctr"
+ }
+ } break;
+ case DK4_TSP_RES_FATAL: {
+ if (DK4_TSP_RES_FATAL != oldres) {
+ oldres = DK4_TSP_RES_FATAL;
+
+
+#line 119 "test-dk4tsp08.ctr"
+ }
+ } break;
+ }
+ } else {
+ cc = 0;
+ }
+ }
+ res = dk4tsp08_finish(&tsp);
+ switch (res) {
+ case DK4_TSP_RES_OK: {
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == oldres) {
+ oldres = DK4_TSP_RES_ERROR;
+
+
+#line 134 "test-dk4tsp08.ctr"
+ }
+ } break;
+ case DK4_TSP_RES_FATAL: {
+ if (DK4_TSP_RES_FATAL != oldres) {
+ oldres = DK4_TSP_RES_FATAL;
+
+
+#line 140 "test-dk4tsp08.ctr"
+ }
+ } break;
+ }
+ } else {
+
+#line 144 "test-dk4tsp08.ctr"
+ }
+ dk4stream_close(outstream, NULL);
+ } else {
+
+#line 147 "test-dk4tsp08.ctr"
+ }
+ fflush(stdout);
+#if DK4_ON_WINDOWS
+ _setmode(_fileno(stdin), oldinmode);
+ _setmode(_fileno(stdout), oldmode);
+#endif
+
+
+#line 154 "test-dk4tsp08.ctr"
+
+
+#line 155 "test-dk4tsp08.ctr"
+ return 0;
+}
+
diff --git a/support/dktools/test-dk4tsp08.ctr b/support/dktools/test-dk4tsp08.ctr
new file mode 100644
index 0000000000..91a7233c36
--- /dev/null
+++ b/support/dktools/test-dk4tsp08.ctr
@@ -0,0 +1,157 @@
+
+#include "dk4conf.h"
+#include "dk4enc.h"
+#include "dk4tsp08.h"
+#include "dk4strm.h"
+#include "dk4strmf.h"
+#include "dk4strmo32.h"
+#include "dk4ansi.h"
+#include <string.h>
+
+
+$!trace-include
+
+
+
+#define LINE_VERSION 1
+
+
+/** Buffer for input from file.
+*/
+static char fbuf[4096];
+
+
+#if LINE_VERSION
+static char lbuf[4096];
+#endif
+
+
+#if LINE_VERSION
+int
+line_handler(void *obj, char *line, dk4_um_t lineno, dk4_er_t *erp)
+{
+ size_t sz;
+ int back = DK4_TSP_RES_ERROR;
+ sz = strlen(line);
+ if (0 < sz) {
+ if (0 != dk4stream_write( (dk4_stream_t *)obj, line, sz, erp)) {
+ back = DK4_TSP_RES_OK;
+ }
+ } else {
+ back = DK4_TSP_RES_OK;
+ }
+ return back;
+}
+#else
+int
+char_handler(void *obj, char c, dk4_text_stream_position_t *pos, dk4_er_t *erp)
+{
+ dk4_c32_t c32;
+ int back = DK4_TSP_RES_ERROR;
+ if (dk4ansi_decode(&c32, (unsigned char)c)) {
+ if (dk4stream_c32_putc((dk4_stream_t *)obj, c32, erp)) {
+ back = DK4_TSP_RES_OK;
+ }
+ }
+ return back;
+}
+#endif
+
+
+
+int main(void)
+{
+ dk4_tsp08_t tsp; /* Text stream processor. */
+ dk4_er_t er; /* Error report */
+ dk4_stream_t *outstream; /* Output stream */
+ size_t nread; /* Number of bytes read */
+#if DK4_ON_WINDOWS
+ int oldmode; /* Output text or binary mode */
+ int oldinmode; /* Input text or binary mode */
+#endif
+ int res; /* Result for text stream processing */
+ int oldres; /* Previous result */
+ int cc; /* Flag: Can continue */
+ $!trace-init test-dk4tsp08.deb
+ $? "+ main"
+#if DK4_ON_WINDOWS
+ oldmode = _setmode(_fileno(stdout), _O_BINARY);
+ oldinmode = _setmode(_fileno(stdin), _O_BINARY);
+#endif
+ dk4error_init(&er);
+ outstream = dk4stream_open_for_file( stdout, DK4_STREAM_WRITE, 0, 0, &er);
+ if (NULL != outstream) {
+ dk4stream_set_output_encoding(outstream, DK4_FILE_ENCODING_ASCII);
+#if 1
+ (void)dk4stream_write_bom_if_necessary(outstream, NULL);
+#endif
+#if LINE_VERSION
+ res = dk4tsp08_setup_line(
+ &tsp, (void *)outstream, line_handler, lbuf, sizeof(lbuf),
+ DK4_ENCODING_ASCII, DK4_ENCODING_UTF8, &er
+ );
+#else
+ res = dk4tsp08_setup_char(
+ &tsp, (void *)outstream, char_handler,
+ DK4_ENCODING_UTF8, DK4_ENCODING_UTF8, &er
+ );
+#endif
+ if (DK4_TSP_RES_OK == res) {
+ oldres = DK4_TSP_RES_OK;
+ cc = 1;
+ while (1 == cc) {
+ nread = fread(fbuf, 1, sizeof(fbuf), stdin);
+ if (0 < nread) {
+ res = dk4tsp08_add_bytes(&tsp, (unsigned char *)fbuf, nread);
+ switch (res) {
+ case DK4_TSP_RES_OK: {
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == oldres) {
+ oldres = DK4_TSP_RES_ERROR;
+ $? "! STATE CHANGE: ERROR"
+ }
+ } break;
+ case DK4_TSP_RES_FATAL: {
+ if (DK4_TSP_RES_FATAL != oldres) {
+ oldres = DK4_TSP_RES_FATAL;
+ $? "! STATE CHANGE: FATAL"
+ }
+ } break;
+ }
+ } else {
+ cc = 0;
+ }
+ }
+ res = dk4tsp08_finish(&tsp);
+ switch (res) {
+ case DK4_TSP_RES_OK: {
+ } break;
+ case DK4_TSP_RES_ERROR: {
+ if (DK4_TSP_RES_OK == oldres) {
+ oldres = DK4_TSP_RES_ERROR;
+ $? "! STATE CHANGE: ERROR"
+ }
+ } break;
+ case DK4_TSP_RES_FATAL: {
+ if (DK4_TSP_RES_FATAL != oldres) {
+ oldres = DK4_TSP_RES_FATAL;
+ $? "! STATE CHANGE: FATAL"
+ }
+ } break;
+ }
+ } else { $? "! failed to initialize text processing"
+ }
+ dk4stream_close(outstream, NULL);
+ } else { $? "! failed to create output stream"
+ }
+ fflush(stdout);
+#if DK4_ON_WINDOWS
+ _setmode(_fileno(stdin), oldinmode);
+ _setmode(_fileno(stdout), oldmode);
+#endif
+ $? "- main"
+ $!trace-end
+ return 0;
+}
+
diff --git a/support/dktools/test-dk4user.c b/support/dktools/test-dk4user.c
new file mode 100644
index 0000000000..8798f67835
--- /dev/null
+++ b/support/dktools/test-dk4user.c
@@ -0,0 +1,75 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-dk4user.ctr
+*/
+
+/** @file test-dk4user.c The test-dk4user module.
+*/
+
+
+#line 1 "test-dk4user.ctr"
+
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4mem.h"
+#include <stdio.h>
+#include "dk4user.h"
+#include "dk4mpl.h"
+#include "dk4fput.h"
+
+#if DK4_HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#include <process.h>
+#endif
+
+
+
+
+
+#line 26 "test-dk4user.ctr"
+
+
+
+int main(void)
+{
+ dkChar logname[128];
+ dkChar homedir[DK4_MAX_PATH];
+ dk4_er_t er;
+
+
+
+#line 36 "test-dk4user.ctr"
+
+
+#line 37 "test-dk4user.ctr"
+ dk4error_init(&er);
+ dk4fput_initialize_stdout();
+ if (dk4user_get_logname(logname, DK4_SIZEOF(logname,dkChar), 0, &er)) {
+ dk4fputs(dkT("LOGNAME: "), stdout, &er);
+ dk4fputs(logname, stdout, &er);
+ dk4fputc(dkT('\n'), stdout, &er);
+ }
+ if (dk4user_get_homedir(homedir, DK4_SIZEOF(homedir,dkChar), 0, &er)) {
+ dk4fputs(dkT("HOMEDIR: "), stdout, &er);
+ dk4fputs(homedir, stdout, &er);
+ dk4fputc(dkT('\n'), stdout, &er);
+ }
+
+
+#line 50 "test-dk4user.ctr"
+
+
+#line 51 "test-dk4user.ctr"
+ exit(0); return 0;
+}
+
diff --git a/support/dktools/test-dk4user.ctr b/support/dktools/test-dk4user.ctr
new file mode 100644
index 0000000000..291285bbfc
--- /dev/null
+++ b/support/dktools/test-dk4user.ctr
@@ -0,0 +1,53 @@
+
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4mem.h"
+#include <stdio.h>
+#include "dk4user.h"
+#include "dk4mpl.h"
+#include "dk4fput.h"
+
+#if DK4_HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#include <process.h>
+#endif
+
+
+
+$!trace-include
+
+
+
+int main(void)
+{
+ dkChar logname[128];
+ dkChar homedir[DK4_MAX_PATH];
+ dk4_er_t er;
+
+ $!trace-init test-dk4user.deb
+ $? "+ main"
+ dk4error_init(&er);
+ dk4fput_initialize_stdout();
+ if (dk4user_get_logname(logname, DK4_SIZEOF(logname,dkChar), 0, &er)) {
+ dk4fputs(dkT("LOGNAME: "), stdout, &er);
+ dk4fputs(logname, stdout, &er);
+ dk4fputc(dkT('\n'), stdout, &er);
+ }
+ if (dk4user_get_homedir(homedir, DK4_SIZEOF(homedir,dkChar), 0, &er)) {
+ dk4fputs(dkT("HOMEDIR: "), stdout, &er);
+ dk4fputs(homedir, stdout, &er);
+ dk4fputc(dkT('\n'), stdout, &er);
+ }
+ $? "- main"
+ $!trace-end
+ exit(0); return 0;
+}
+
diff --git a/support/dktools/test-dk4wxah.cpp b/support/dktools/test-dk4wxah.cpp
new file mode 100644
index 0000000000..a8f835fea8
--- /dev/null
+++ b/support/dktools/test-dk4wxah.cpp
@@ -0,0 +1,69 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-dk4wxah.cpt
+*/
+
+/** @file test-dk4wxah.cpp The test-dk4wxah module.
+*/
+
+
+#line 1 "test-dk4wxah.cpt"
+
+#include <Dk4WxApplicationHelper.h>
+
+
+
+
+
+#line 7 "test-dk4wxah.cpt"
+
+
+static const wxChar progname[] = { wxT("test-dk4wxah") };
+static const wxChar vendorname[] = { wxT("Dirk Krause") };
+static const dkChar groupname[] = { dkT("dktools") };
+
+static const wxChar * const kw_def[] = {
+/* 0 */
+wxT("Test"),
+
+/* 1 */
+wxT("Yet another test"),
+
+NULL
+
+
+#line 24 "test-dk4wxah.cpt"
+};
+
+
+int main(int argc, char *argv[])
+{
+ const wxChar * const *stringtable = NULL;
+
+
+#line 31 "test-dk4wxah.cpt"
+
+
+#line 32 "test-dk4wxah.cpt"
+ {
+ Dk4WxApplicationHelper ah(progname, vendorname, groupname);
+ if (ah.checkSetup()) {
+
+#line 35 "test-dk4wxah.cpt"
+ stringtable = ah.stringTable(dkT("dk3app.str"), kw_def);
+ } else {
+
+#line 37 "test-dk4wxah.cpt"
+ }
+ }
+
+
+#line 40 "test-dk4wxah.cpt"
+
+
+#line 41 "test-dk4wxah.cpt"
+ return 0;
+}
+
diff --git a/support/dktools/test-dk4wxah.cpt b/support/dktools/test-dk4wxah.cpt
new file mode 100644
index 0000000000..8e8d8471bf
--- /dev/null
+++ b/support/dktools/test-dk4wxah.cpt
@@ -0,0 +1,43 @@
+
+#include <Dk4WxApplicationHelper.h>
+
+
+
+$!trace-include
+
+
+static const wxChar progname[] = { wxT("test-dk4wxah") };
+static const wxChar vendorname[] = { wxT("Dirk Krause") };
+static const dkChar groupname[] = { dkT("dktools") };
+
+static const wxChar * const kw_def[] = {
+$!string-table macro=wxT
+#
+# 0
+#
+Test
+#
+# 1
+#
+Yet another test
+$!end
+};
+
+
+int main(int argc, char *argv[])
+{
+ const wxChar * const *stringtable = NULL;
+ $!trace-init test-dk4wxah.deb
+ $? "+ main"
+ {
+ Dk4WxApplicationHelper ah(progname, vendorname, groupname);
+ if (ah.checkSetup()) { $? ". setup ok"
+ stringtable = ah.stringTable(dkT("dk3app.str"), kw_def);
+ } else { $? ". setup failed"
+ }
+ }
+ $? "- main"
+ $!trace-end
+ return 0;
+}
+
diff --git a/support/dktools/test-eradisk.c b/support/dktools/test-eradisk.c
new file mode 100644
index 0000000000..3abc64fdd2
--- /dev/null
+++ b/support/dktools/test-eradisk.c
@@ -0,0 +1,48 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-eradisk.ctr
+*/
+
+/** @file test-eradisk.c The test-eradisk module.
+*/
+
+
+#line 1 "test-eradisk.ctr"
+
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "dk4mai8dsz.h"
+
+int main(int argc, char *argv[])
+{
+ size_t ts = 512;
+ size_t as = 512;
+ size_t is = 0;
+ int cc = 1;
+ int ic;
+ const char *ep = NULL;
+ if (1 < argc) {
+ if (0 != dk4ma_input_c8_dec_size_t(&as, argv[1], &ep, 1, NULL)) {
+ ts = as;
+ printf("ts = %u\n", (unsigned)ts);
+ }
+ }
+ while (1 == cc) {
+ ic = fgetc(stdin);
+ if (EOF == ic) {
+ cc = 0;
+ } else {
+ if (++is >= ts) {
+ cc = 0;
+ } else {
+ printf("%u / %u\n", (unsigned)is, (unsigned)ts);
+ }
+ }
+ }
+ exit(0); return 0;
+}
+
diff --git a/support/dktools/test-eradisk.ctr b/support/dktools/test-eradisk.ctr
new file mode 100644
index 0000000000..540359db99
--- /dev/null
+++ b/support/dktools/test-eradisk.ctr
@@ -0,0 +1,36 @@
+
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "dk4mai8dsz.h"
+
+int main(int argc, char *argv[])
+{
+ size_t ts = 512;
+ size_t as = 512;
+ size_t is = 0;
+ int cc = 1;
+ int ic;
+ const char *ep = NULL;
+ if (1 < argc) {
+ if (0 != dk4ma_input_c8_dec_size_t(&as, argv[1], &ep, 1, NULL)) {
+ ts = as;
+ printf("ts = %u\n", (unsigned)ts);
+ }
+ }
+ while (1 == cc) {
+ ic = fgetc(stdin);
+ if (EOF == ic) {
+ cc = 0;
+ } else {
+ if (++is >= ts) {
+ cc = 0;
+ } else {
+ printf("%u / %u\n", (unsigned)is, (unsigned)ts);
+ }
+ }
+ }
+ exit(0); return 0;
+}
+
diff --git a/support/dktools/test-filei.c b/support/dktools/test-filei.c
new file mode 100644
index 0000000000..f4779798b5
--- /dev/null
+++ b/support/dktools/test-filei.c
@@ -0,0 +1,86 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-filei.ctr
+*/
+
+/** @file test-filei.c The test-filei module.
+*/
+
+
+#line 1 "test-filei.ctr"
+
+#include <stdio.h>
+
+#include "dk4filei.h"
+#include "dk4filei8.h"
+#include "dk4fileig8.h"
+#include "dk4fput.h"
+#include "dk4mem.h"
+
+
+
+
+
+#line 13 "test-filei.ctr"
+
+
+
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ dkChar buf[256];
+ dk4_file_info_t fi;
+ int i;
+
+
+
+#line 27 "test-filei.ctr"
+
+
+#line 28 "test-filei.ctr"
+ dk4fput_initialize_stdout();
+ for (i = 1; i < argc; i++) {
+ dk4fputs(argv[i], stdout, NULL);
+ dk4fputc('\n', stdout, NULL);
+ dk4fileinfo_init(&fi);
+ if (dk4fileinfo(&fi, argv[i], NULL)) {
+
+#line 34 "test-filei.ctr"
+ if (dk4fileinfo_timestamp(buf, DK4_SIZEOF(buf,dkChar), &fi, 0, 0, NULL)) {
+ dk4fputs(buf, stdout, NULL);
+ dk4fputc('\n', stdout, NULL);
+
+#line 37 "test-filei.ctr"
+ } else {
+
+#line 38 "test-filei.ctr"
+ }
+ if (dk4fileinfo_type_attributes(buf, sizeof(buf), &fi, NULL)) {
+ dk4fputs(buf, stdout, NULL);
+ dk4fputc('\n', stdout, NULL);
+
+#line 42 "test-filei.ctr"
+ } else {
+
+#line 43 "test-filei.ctr"
+ }
+ } else {
+
+#line 45 "test-filei.ctr"
+ }
+ dk4fputc('\n', stdout, NULL);
+ }
+
+
+#line 49 "test-filei.ctr"
+
+
+#line 50 "test-filei.ctr"
+ return 0;
+}
+
diff --git a/support/dktools/test-filei.ctr b/support/dktools/test-filei.ctr
new file mode 100644
index 0000000000..b07c00a3df
--- /dev/null
+++ b/support/dktools/test-filei.ctr
@@ -0,0 +1,52 @@
+
+#include <stdio.h>
+
+#include "dk4filei.h"
+#include "dk4filei8.h"
+#include "dk4fileig8.h"
+#include "dk4fput.h"
+#include "dk4mem.h"
+
+
+
+$!trace-include
+
+
+
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ dkChar buf[256];
+ dk4_file_info_t fi;
+ int i;
+
+ $!trace-init test-filei.deb
+ $? "+ main"
+ dk4fput_initialize_stdout();
+ for (i = 1; i < argc; i++) {
+ dk4fputs(argv[i], stdout, NULL);
+ dk4fputc('\n', stdout, NULL);
+ dk4fileinfo_init(&fi);
+ if (dk4fileinfo(&fi, argv[i], NULL)) { $? ". ok"
+ if (dk4fileinfo_timestamp(buf, DK4_SIZEOF(buf,dkChar), &fi, 0, 0, NULL)) {
+ dk4fputs(buf, stdout, NULL);
+ dk4fputc('\n', stdout, NULL); $? ". ok"
+ } else { $? "! failed"
+ }
+ if (dk4fileinfo_type_attributes(buf, sizeof(buf), &fi, NULL)) {
+ dk4fputs(buf, stdout, NULL);
+ dk4fputc('\n', stdout, NULL); $? ". ok"
+ } else { $? "! failed"
+ }
+ } else { $? "! failed"
+ }
+ dk4fputc('\n', stdout, NULL);
+ }
+ $? "- main"
+ $!trace-end
+ return 0;
+}
+
diff --git a/support/dktools/test-fne.c b/support/dktools/test-fne.c
new file mode 100644
index 0000000000..fd25a12273
--- /dev/null
+++ b/support/dktools/test-fne.c
@@ -0,0 +1,42 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-fne.ctr
+*/
+
+/** @file test-fne.c The test-fne module.
+*/
+
+
+#line 1 "test-fne.ctr"
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4fput.h"
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ int i;
+
+ dk4fput_initialize_stdout();
+ for (i = 0; i < argc; i++) {
+ dk4fputs(argv[i], stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ }
+ return 0;
+}
+
diff --git a/support/dktools/test-fne.ctr b/support/dktools/test-fne.ctr
new file mode 100644
index 0000000000..c426d32c26
--- /dev/null
+++ b/support/dktools/test-fne.ctr
@@ -0,0 +1,30 @@
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4fput.h"
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ int i;
+
+ dk4fput_initialize_stdout();
+ for (i = 0; i < argc; i++) {
+ dk4fputs(argv[i], stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ }
+ return 0;
+}
+
diff --git a/support/dktools/test-home.c b/support/dktools/test-home.c
new file mode 100644
index 0000000000..c65e3acb6a
--- /dev/null
+++ b/support/dktools/test-home.c
@@ -0,0 +1,58 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-home.ctr
+*/
+
+/** @file test-home.c The test-home module.
+*/
+
+
+#line 1 "test-home.ctr"
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4mem.h"
+#include "dk4user.h"
+#include "dk4fput.h"
+#include "dk4mpl.h"
+
+static const dkChar *test_home_kw[] = {
+/* 0 */
+dkT("LOGNAME: "),
+
+/* 1 */
+dkT("HOME: "),
+
+NULL
+
+
+#line 16 "test-home.ctr"
+};
+
+
+int main(void)
+{
+ dkChar buf[DK4_MAX_PATH];
+ size_t szbuf = DK4_SIZEOF(buf,dkChar);
+ int exval = 1;
+
+ if (0 != dk4user_get_logname(buf, szbuf, 1, NULL)) {
+ dk4fput_initialize_stdout();
+ dk4fputs(test_home_kw[0], stdout, NULL);
+ dk4fputs(buf, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ if (0 != dk4user_get_homedir(buf, szbuf, 1, NULL)) {
+ dk4fputs(test_home_kw[1], stdout, NULL);
+ dk4fputs(buf, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ exval = 0;
+ }
+ dk4fput_cleanup_stdout();
+ }
+ return exval;
+}
+
diff --git a/support/dktools/test-home.ctr b/support/dktools/test-home.ctr
new file mode 100644
index 0000000000..af7c2e6630
--- /dev/null
+++ b/support/dktools/test-home.ctr
@@ -0,0 +1,40 @@
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4mem.h"
+#include "dk4user.h"
+#include "dk4fput.h"
+#include "dk4mpl.h"
+
+static const dkChar *test_home_kw[] = {
+$!string-table macro=dkT
+LOGNAME:
+HOME:
+$!end
+};
+
+
+int main(void)
+{
+ dkChar buf[DK4_MAX_PATH];
+ size_t szbuf = DK4_SIZEOF(buf,dkChar);
+ int exval = 1;
+
+ if (0 != dk4user_get_logname(buf, szbuf, 1, NULL)) {
+ dk4fput_initialize_stdout();
+ dk4fputs(test_home_kw[0], stdout, NULL);
+ dk4fputs(buf, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ if (0 != dk4user_get_homedir(buf, szbuf, 1, NULL)) {
+ dk4fputs(test_home_kw[1], stdout, NULL);
+ dk4fputs(buf, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ exval = 0;
+ }
+ dk4fput_cleanup_stdout();
+ }
+ return exval;
+}
+
diff --git a/support/dktools/test-inet-pton.c b/support/dktools/test-inet-pton.c
new file mode 100644
index 0000000000..e065bfa1ca
--- /dev/null
+++ b/support/dktools/test-inet-pton.c
@@ -0,0 +1,133 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-inet-pton.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file test-inet-pton.c The test-inet-pton module.
+*/
+
+
+#line 9 "test-inet-pton.ctr"
+
+#include "dk4conf.h"
+#include "dk4sock.h"
+
+
+
+
+
+#line 16 "test-inet-pton.ctr"
+
+
+
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6 && defined(AF_INET6)
+
+struct in6_addr sin6;
+
+#endif
+
+struct in_addr sin4;
+
+static
+void
+run_test(const char *addrtext)
+{
+ char buf[1040];
+ dk4_er_t er;
+ int res;
+ printf("Text: \"%s\"\n", addrtext);
+ dk4error_init(&er);
+ res = dk4socket_c8_inet_pton(&sin4, sizeof(sin4), AF_INET, addrtext, &er);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ res = dk4socket_c8_inet_ntop(buf, sizeof(buf), AF_INET, &sin4, &er);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ printf("Address: \"%s\"\n", buf);
+ } else {
+ printf("Conversion succeeded.\n");
+ }
+ } else {
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6 && defined(AF_INET6)
+ res = dk4socket_c8_inet_pton(&sin6, sizeof(sin6), AF_INET6, addrtext, &er);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ res = dk4socket_c8_inet_ntop(buf, sizeof(buf), AF_INET6, &sin6, &er);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ printf("Address: \"%s\"\n", buf);
+ } else {
+ printf("Conversion succeeded.\n");
+ }
+ } else {
+#endif
+ printf("!!!!! Conversion failed!\n");
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6 && defined(AF_INET6)
+ }
+#endif
+ }
+}
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ dk4_er_t er;
+ int i;
+
+
+#line 79 "test-inet-pton.ctr"
+
+
+#line 80 "test-inet-pton.ctr"
+ dk4error_init(&er);
+ if (DK4_SOCKET_RESULT_SUCCESS == dk4socket_up(&er)) {
+ for (i = 1; i < argc; i++) {
+ run_test(argv[i]);
+ }
+ dk4socket_down(&er);
+ }
+
+
+#line 88 "test-inet-pton.ctr"
+
+
+#line 89 "test-inet-pton.ctr"
+ return 0;
+}
+
diff --git a/support/dktools/test-inet-pton.ctr b/support/dktools/test-inet-pton.ctr
new file mode 100644
index 0000000000..74401debac
--- /dev/null
+++ b/support/dktools/test-inet-pton.ctr
@@ -0,0 +1,91 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4sock.h"
+
+
+
+$!trace-include
+
+
+
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6 && defined(AF_INET6)
+
+struct in6_addr sin6;
+
+#endif
+
+struct in_addr sin4;
+
+static
+void
+run_test(const char *addrtext)
+{
+ char buf[1040];
+ dk4_er_t er;
+ int res;
+ printf("Text: \"%s\"\n", addrtext);
+ dk4error_init(&er);
+ res = dk4socket_c8_inet_pton(&sin4, sizeof(sin4), AF_INET, addrtext, &er);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ res = dk4socket_c8_inet_ntop(buf, sizeof(buf), AF_INET, &sin4, &er);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ printf("Address: \"%s\"\n", buf);
+ } else {
+ printf("Conversion succeeded.\n");
+ }
+ } else {
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6 && defined(AF_INET6)
+ res = dk4socket_c8_inet_pton(&sin6, sizeof(sin6), AF_INET6, addrtext, &er);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ res = dk4socket_c8_inet_ntop(buf, sizeof(buf), AF_INET6, &sin6, &er);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ printf("Address: \"%s\"\n", buf);
+ } else {
+ printf("Conversion succeeded.\n");
+ }
+ } else {
+#endif
+ printf("!!!!! Conversion failed!\n");
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6 && defined(AF_INET6)
+ }
+#endif
+ }
+}
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ dk4_er_t er;
+ int i;
+ $!trace-init test-inet-pton.deb
+ $? "+ main"
+ dk4error_init(&er);
+ if (DK4_SOCKET_RESULT_SUCCESS == dk4socket_up(&er)) {
+ for (i = 1; i < argc; i++) {
+ run_test(argv[i]);
+ }
+ dk4socket_down(&er);
+ }
+ $? "- main"
+ $!trace-end
+ return 0;
+}
+
diff --git a/support/dktools/test-mbstr.c b/support/dktools/test-mbstr.c
new file mode 100644
index 0000000000..dd47c626ad
--- /dev/null
+++ b/support/dktools/test-mbstr.c
@@ -0,0 +1,51 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-mbstr.ctr
+*/
+
+/** @file test-mbstr.c The test-mbstr module.
+*/
+
+
+#line 1 "test-mbstr.ctr"
+
+#include "dk4conf.h"
+#include "dk4strm.h"
+#include "dk4membuf.h"
+#include "dk4mbstrm.h"
+
+
+static const char test[] = { "0123456789ABCDEF" };
+
+int main(int argc, char *argv[])
+{
+ dk4_membuf_t *mb = NULL;
+ dk4_stream_t *strm = NULL;
+ size_t i;
+
+ mb = dk4membuf_open(NULL);
+ if (NULL != mb) {
+ strm = dk4stream_open_membuf_writer(mb, NULL);
+ if (NULL != strm) {
+ for (i = 0; i < 1024; i++) {
+ dk4stream_write(strm, test, 16, NULL);
+ }
+ if (dk4membuf_size(&i, mb, NULL)) {
+ printf("Bytes: %lu\n", (unsigned long)i);
+ }
+ dk4stream_close(strm, NULL);
+ }
+ else {
+ }
+ dk4membuf_close(mb);
+ }
+ else {
+ }
+
+ return 0;
+}
+
+/* vim: set ai sw=4 ts=4 : */
+
diff --git a/support/dktools/test-mbstr.ctr b/support/dktools/test-mbstr.ctr
new file mode 100644
index 0000000000..36bd737fb7
--- /dev/null
+++ b/support/dktools/test-mbstr.ctr
@@ -0,0 +1,39 @@
+
+#include "dk4conf.h"
+#include "dk4strm.h"
+#include "dk4membuf.h"
+#include "dk4mbstrm.h"
+
+
+static const char test[] = { "0123456789ABCDEF" };
+
+int main(int argc, char *argv[])
+{
+ dk4_membuf_t *mb = NULL;
+ dk4_stream_t *strm = NULL;
+ size_t i;
+
+ mb = dk4membuf_open(NULL);
+ if (NULL != mb) {
+ strm = dk4stream_open_membuf_writer(mb, NULL);
+ if (NULL != strm) {
+ for (i = 0; i < 1024; i++) {
+ dk4stream_write(strm, test, 16, NULL);
+ }
+ if (dk4membuf_size(&i, mb, NULL)) {
+ printf("Bytes: %lu\n", (unsigned long)i);
+ }
+ dk4stream_close(strm, NULL);
+ }
+ else {
+ }
+ dk4membuf_close(mb);
+ }
+ else {
+ }
+
+ return 0;
+}
+
+/* vim: set ai sw=4 ts=4 : */
+
diff --git a/support/dktools/test-membuf.c b/support/dktools/test-membuf.c
new file mode 100644
index 0000000000..1785e53de2
--- /dev/null
+++ b/support/dktools/test-membuf.c
@@ -0,0 +1,60 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-membuf.ctr
+*/
+
+/** @file test-membuf.c The test-membuf module.
+*/
+
+
+#line 1 "test-membuf.ctr"
+
+#include <stdio.h>
+
+#include "dk4membuf.h"
+#include "dk4membf.h"
+
+
+
+int main(void)
+{
+ char buf[32];
+ dk4_er_t er;
+ dk4_membuf_t *mbptr;
+ size_t rdb;
+ int cc;
+ int res;
+
+ dk4error_init(&er);
+ mbptr = dk4membuf_open(&er);
+ if (NULL != mbptr) {
+ cc = 1;
+ while (1 == cc) {
+ rdb = fread(buf, 1, sizeof(buf), stdin);
+ if (0 < rdb) {
+ if (0 != feof(stdin)) { cc = 0; }
+ res = dk4membuf_store(mbptr, buf, rdb, &er);
+ if (0 == res) {
+ fprintf(stderr, "Failed to save data!\n"); fflush(stderr);
+ }
+ } else {
+ cc = 0;
+ }
+ }
+ res = dk4membuf_size(&rdb, mbptr, &er);
+ if (0 != res) {
+ fprintf(stderr, "Size: %lu\n", (unsigned long)rdb); fflush(stderr);
+ } else {
+ fprintf(stderr, "Size calculation failed!\n"); fflush(stderr);
+ }
+ res = dk4membuf_to_file(stdout, mbptr, &er);
+ if (0 == res) {
+ fprintf(stderr, "Failed to write output!\n"); fflush(stderr);
+ }
+ dk4membuf_close(mbptr);
+ }
+ return 0;
+}
+
diff --git a/support/dktools/test-membuf.ctr b/support/dktools/test-membuf.ctr
new file mode 100644
index 0000000000..d172834e49
--- /dev/null
+++ b/support/dktools/test-membuf.ctr
@@ -0,0 +1,48 @@
+
+#include <stdio.h>
+
+#include "dk4membuf.h"
+#include "dk4membf.h"
+
+
+
+int main(void)
+{
+ char buf[32];
+ dk4_er_t er;
+ dk4_membuf_t *mbptr;
+ size_t rdb;
+ int cc;
+ int res;
+
+ dk4error_init(&er);
+ mbptr = dk4membuf_open(&er);
+ if (NULL != mbptr) {
+ cc = 1;
+ while (1 == cc) {
+ rdb = fread(buf, 1, sizeof(buf), stdin);
+ if (0 < rdb) {
+ if (0 != feof(stdin)) { cc = 0; }
+ res = dk4membuf_store(mbptr, buf, rdb, &er);
+ if (0 == res) {
+ fprintf(stderr, "Failed to save data!\n"); fflush(stderr);
+ }
+ } else {
+ cc = 0;
+ }
+ }
+ res = dk4membuf_size(&rdb, mbptr, &er);
+ if (0 != res) {
+ fprintf(stderr, "Size: %lu\n", (unsigned long)rdb); fflush(stderr);
+ } else {
+ fprintf(stderr, "Size calculation failed!\n"); fflush(stderr);
+ }
+ res = dk4membuf_to_file(stdout, mbptr, &er);
+ if (0 == res) {
+ fprintf(stderr, "Failed to write output!\n"); fflush(stderr);
+ }
+ dk4membuf_close(mbptr);
+ }
+ return 0;
+}
+
diff --git a/support/dktools/test-mkdir.c b/support/dktools/test-mkdir.c
new file mode 100644
index 0000000000..d39f55d083
--- /dev/null
+++ b/support/dktools/test-mkdir.c
@@ -0,0 +1,132 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-mkdir.ctr
+*/
+
+/** @file test-mkdir.c The test-mkdir module.
+*/
+
+
+#line 1 "test-mkdir.ctr"
+
+
+#include <stdio.h>
+
+
+
+#include "dk4app.h"
+#include "dk4fput.h"
+#include "dk4appmkdh.h"
+
+
+
+
+
+#line 14 "test-mkdir.ctr"
+
+
+
+static const dkChar * const test_mkdir_help_text[] = {
+dkT("This is a test program to create directories."),
+NULL
+
+
+#line 21 "test-mkdir.ctr"
+};
+
+static const dkChar * const test_mkdir_license_text[] = {
+dkT("Copyright (c) 2014-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions"),
+dkT("are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above copyright notice,"),
+dkT(" this list of conditions and the following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("* Neither the name of the Dirk Krause nor the names of contributors may be"),
+dkT(" used to endorse or promote products derived from this software without"),
+dkT(" specific prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS"),
+dkT("\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT"),
+dkT("LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR"),
+dkT("A PARTICULAR PURPOSE ARE DISCLAIMED."),
+dkT(""),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS"),
+dkT("OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)"),
+dkT("HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,"),
+dkT("STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN"),
+dkT("ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE"),
+dkT("POSSIBILITY OF SUCH DAMAGE."),
+NULL
+
+
+#line 55 "test-mkdir.ctr"
+};
+
+static dk4_app_t *app = NULL;
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ int res;
+ int nargs;
+ int i;
+ const dkChar *arg;
+
+
+#line 75 "test-mkdir.ctr"
+ app = dk4app_open_cmd(
+ argc, argv, NULL, 0,
+ dkT("dktools-4-test"), dkT("1.0.0"),
+ dkT("test-mkdir.txt"), test_mkdir_help_text,
+ test_mkdir_license_text
+ );
+ if (NULL != app) {
+
+#line 82 "test-mkdir.ctr"
+ nargs = dk4app_get_argc(app);
+ if (0 < nargs) {
+ dk4fput_initialize_stdout();
+ for (i = 0; i < nargs; i++) {
+ arg = dk4app_get_argv(app, i);
+ if (NULL != arg) {
+ res = dk4app_mkdir_hierarchy(arg, 1, app);
+ dk4fputs(arg, stdout, NULL);
+ dk4fputc(dkT(' '), stdout, NULL);
+ if (0 < res) {
+ dk4fputs(dkT("SUCCESS"), stdout, NULL);
+ } else {
+ dk4fputs(dkT("FAILED"), stdout, NULL);
+ }
+ dk4fputc(dkT('\n'), stdout, NULL);
+ }
+ }
+ }
+ dk4app_close(app);
+ } else {
+
+#line 102 "test-mkdir.ctr"
+ }
+
+
+#line 104 "test-mkdir.ctr"
+ return 0;
+}
+
diff --git a/support/dktools/test-mkdir.ctr b/support/dktools/test-mkdir.ctr
new file mode 100644
index 0000000000..51be7cabd6
--- /dev/null
+++ b/support/dktools/test-mkdir.ctr
@@ -0,0 +1,106 @@
+
+
+#include <stdio.h>
+
+
+
+#include "dk4app.h"
+#include "dk4fput.h"
+#include "dk4appmkdh.h"
+
+
+
+$!trace-include
+
+
+
+static const dkChar * const test_mkdir_help_text[] = {
+$!text macro=dkT
+This is a test program to create directories.
+$!end
+};
+
+static const dkChar * const test_mkdir_license_text[] = {
+$!text macro=dkT
+Copyright (c) 2014-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+$!end
+};
+
+static dk4_app_t *app = NULL;
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ int res;
+ int nargs;
+ int i;
+ const dkChar *arg;
+ $!trace-init test-mkdir.deb
+ app = dk4app_open_cmd(
+ argc, argv, NULL, 0,
+ dkT("dktools-4-test"), dkT("1.0.0"),
+ dkT("test-mkdir.txt"), test_mkdir_help_text,
+ test_mkdir_license_text
+ );
+ if (NULL != app) { $? ". app"
+ nargs = dk4app_get_argc(app);
+ if (0 < nargs) {
+ dk4fput_initialize_stdout();
+ for (i = 0; i < nargs; i++) {
+ arg = dk4app_get_argv(app, i);
+ if (NULL != arg) {
+ res = dk4app_mkdir_hierarchy(arg, 1, app);
+ dk4fputs(arg, stdout, NULL);
+ dk4fputc(dkT(' '), stdout, NULL);
+ if (0 < res) {
+ dk4fputs(dkT("SUCCESS"), stdout, NULL);
+ } else {
+ dk4fputs(dkT("FAILED"), stdout, NULL);
+ }
+ dk4fputc(dkT('\n'), stdout, NULL);
+ }
+ }
+ }
+ dk4app_close(app);
+ } else { $? "! app"
+ }
+ $!trace-end
+ return 0;
+}
+
diff --git a/support/dktools/test-opt.c b/support/dktools/test-opt.c
new file mode 100644
index 0000000000..339fec4782
--- /dev/null
+++ b/support/dktools/test-opt.c
@@ -0,0 +1,102 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-opt.ctr
+*/
+
+/** @file test-opt.c The test-opt module.
+*/
+
+
+#line 1 "test-opt.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4mem.h"
+#include "dk4opt.h"
+
+
+
+
+
+#line 10 "test-opt.ctr"
+
+
+
+/** Command line options for program.
+*/
+static dk4_option_t options[] = {
+ { { dkT('i'), dkT("interactive"), DK4_OPT_ARG_NONE }, { NULL }, 0},
+ { { dkT('s'), dkT("socket"), DK4_OPT_ARG_STRING }, { NULL }, 0},
+ { { dkT('h'), dkT("host"), DK4_OPT_ARG_STRING }, { NULL }, 0},
+ { { dkT('p'), dkT("port"), DK4_OPT_ARG_UNSIGNED }, { NULL }, 0}
+};
+
+
+
+static const size_t szoptions = sizeof(options)/sizeof(dk4_option_t);
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int
+wmain(int argc, wchar_t *argv[])
+#else
+int
+main(int argc, char *argv[])
+#endif
+{
+ dkChar *filenames[32];
+ size_t szfn = DK4_SIZEOF(filenames,DK4_PDKCHAR);
+ int res;
+
+
+
+#line 45 "test-opt.ctr"
+
+
+#line 46 "test-opt.ctr"
+ res = dk4opt_process_argv(
+ options, szoptions, argc, argv,
+ filenames, &szfn, 1, 1, NULL
+ );
+ if (0 != res) {
+ if (0 != options[0].found) {
+ fputs("Option -i found.\n", stdout);
+ }
+ if (0 != options[1].found) {
+ fputs("Option -s found.\nArgument: ", stdout);
+ if (NULL != options[1].val.t) {
+ fputs(options[1].val.t, stdout);
+ }
+ fputc('\n', stdout);
+ fflush(stdout);
+ }
+ if (0 != options[2].found) {
+ fputs("Option -h found.\n", stdout);
+ if (NULL != options[2].val.t) {
+ fputs(options[2].val.t, stdout);
+ }
+ fputc('\n', stdout);
+ fflush(stdout);
+ }
+ if (0 != options[3].found) {
+ fputs("Option -p found.\n", stdout);
+ fprintf(stdout, "Argument: %ju\n", options[3].val.u);
+ fflush(stdout);
+ }
+ }
+
+
+#line 77 "test-opt.ctr"
+
+
+#line 78 "test-opt.ctr"
+ exit(0); return 0;
+}
+
diff --git a/support/dktools/test-opt.ctr b/support/dktools/test-opt.ctr
new file mode 100644
index 0000000000..2b9e7f6dc4
--- /dev/null
+++ b/support/dktools/test-opt.ctr
@@ -0,0 +1,80 @@
+
+#include "dk4conf.h"
+#include "dk4types.h"
+#include "dk4mem.h"
+#include "dk4opt.h"
+
+
+
+$!trace-include
+
+
+
+/** Command line options for program.
+*/
+static dk4_option_t options[] = {
+ { { dkT('i'), dkT("interactive"), DK4_OPT_ARG_NONE }, { NULL }, 0},
+ { { dkT('s'), dkT("socket"), DK4_OPT_ARG_STRING }, { NULL }, 0},
+ { { dkT('h'), dkT("host"), DK4_OPT_ARG_STRING }, { NULL }, 0},
+ { { dkT('p'), dkT("port"), DK4_OPT_ARG_UNSIGNED }, { NULL }, 0}
+};
+
+
+
+static const size_t szoptions = sizeof(options)/sizeof(dk4_option_t);
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int
+wmain(int argc, wchar_t *argv[])
+#else
+int
+main(int argc, char *argv[])
+#endif
+{
+ dkChar *filenames[32];
+ size_t szfn = DK4_SIZEOF(filenames,DK4_PDKCHAR);
+ int res;
+
+ $!trace-init test-opt.deb
+ $? "+ main"
+ res = dk4opt_process_argv(
+ options, szoptions, argc, argv,
+ filenames, &szfn, 1, 1, NULL
+ );
+ if (0 != res) {
+ if (0 != options[0].found) {
+ fputs("Option -i found.\n", stdout);
+ }
+ if (0 != options[1].found) {
+ fputs("Option -s found.\nArgument: ", stdout);
+ if (NULL != options[1].val.t) {
+ fputs(options[1].val.t, stdout);
+ }
+ fputc('\n', stdout);
+ fflush(stdout);
+ }
+ if (0 != options[2].found) {
+ fputs("Option -h found.\n", stdout);
+ if (NULL != options[2].val.t) {
+ fputs(options[2].val.t, stdout);
+ }
+ fputc('\n', stdout);
+ fflush(stdout);
+ }
+ if (0 != options[3].found) {
+ fputs("Option -p found.\n", stdout);
+ fprintf(stdout, "Argument: %ju\n", options[3].val.u);
+ fflush(stdout);
+ }
+ }
+ $? "- main"
+ $!trace-end
+ exit(0); return 0;
+}
+
diff --git a/support/dktools/test-paper.c b/support/dktools/test-paper.c
new file mode 100644
index 0000000000..23919e27fc
--- /dev/null
+++ b/support/dktools/test-paper.c
@@ -0,0 +1,132 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-paper.ctr
+*/
+
+/** @file test-paper.c The test-paper module.
+*/
+
+
+#line 1 "test-paper.ctr"
+#include <stdio.h>
+#include <stdint.h>
+#define _USE_MATH_DEFINES 1
+#include <math.h>
+
+
+#include "dk4mem.h"
+#include "dk4serf.h"
+#include "dk4userf.h"
+#include "dk4app.h"
+#include "dk4str8.h"
+#include "dk4maodd.h"
+#include "dk4fput.h"
+#include "dk4paper.h"
+#include "dk4papea.h"
+
+
+
+
+#line 19 "test-paper.ctr"
+
+
+
+static const dkChar * const test_paper_help_text[] = {
+dkT("This is a test program to create directories."),
+NULL
+
+
+#line 26 "test-paper.ctr"
+};
+
+static const dkChar * const test_paper_license_text[] = {
+dkT("Copyright (c) 2014-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions"),
+dkT("are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above copyright notice,"),
+dkT(" this list of conditions and the following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("* Neither the name of the Dirk Krause nor the names of contributors may be"),
+dkT(" used to endorse or promote products derived from this software without"),
+dkT(" specific prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS"),
+dkT("\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT"),
+dkT("LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR"),
+dkT("A PARTICULAR PURPOSE ARE DISCLAIMED."),
+dkT(""),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS"),
+dkT("OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)"),
+dkT("HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,"),
+dkT("STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN"),
+dkT("ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE"),
+dkT("POSSIBILITY OF SUCH DAMAGE."),
+NULL
+
+
+#line 60 "test-paper.ctr"
+};
+
+
+static int exv = EXIT_FAILURE;
+
+
+static dk4_app_t *app = NULL;
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ dk4_paper_size_collection_t *psc;
+
+
+
+#line 83 "test-paper.ctr"
+
+
+#line 84 "test-paper.ctr"
+ app = dk4app_open_cmd(
+ argc, argv, NULL, 0,
+ dkT("dktools-4-test"), dkT("1.0.0"),
+ dkT("test-paper.txt"), test_paper_help_text,
+ test_paper_license_text
+ );
+ if (NULL != app) {
+ psc = dk4app_get_paper_sizes(app);
+ if (NULL != psc) {
+ dk4papersize_coll_close(psc);
+ }
+ dk4app_close(app);
+ }
+ psc = dk4papersize_coll_for_application(
+ dkT("test-paper"), dkT("dktools"), NULL
+ );
+ if (NULL != psc) {
+ dk4papersize_coll_close(psc);
+ }
+
+
+#line 104 "test-paper.ctr"
+
+
+#line 105 "test-paper.ctr"
+ return exv;
+}
diff --git a/support/dktools/test-paper.ctr b/support/dktools/test-paper.ctr
new file mode 100644
index 0000000000..e14c1c0019
--- /dev/null
+++ b/support/dktools/test-paper.ctr
@@ -0,0 +1,106 @@
+#include <stdio.h>
+#include <stdint.h>
+#define _USE_MATH_DEFINES 1
+#include <math.h>
+
+
+#include "dk4mem.h"
+#include "dk4serf.h"
+#include "dk4userf.h"
+#include "dk4app.h"
+#include "dk4str8.h"
+#include "dk4maodd.h"
+#include "dk4fput.h"
+#include "dk4paper.h"
+#include "dk4papea.h"
+
+
+$!trace-include
+
+
+
+static const dkChar * const test_paper_help_text[] = {
+$!text macro=dkT
+This is a test program to create directories.
+$!end
+};
+
+static const dkChar * const test_paper_license_text[] = {
+$!text macro=dkT
+Copyright (c) 2014-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+$!end
+};
+
+
+static int exv = EXIT_FAILURE;
+
+
+static dk4_app_t *app = NULL;
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ dk4_paper_size_collection_t *psc;
+
+ $!trace-init test-paper.deb
+ $? "+ main"
+ app = dk4app_open_cmd(
+ argc, argv, NULL, 0,
+ dkT("dktools-4-test"), dkT("1.0.0"),
+ dkT("test-paper.txt"), test_paper_help_text,
+ test_paper_license_text
+ );
+ if (NULL != app) {
+ psc = dk4app_get_paper_sizes(app);
+ if (NULL != psc) {
+ dk4papersize_coll_close(psc);
+ }
+ dk4app_close(app);
+ }
+ psc = dk4papersize_coll_for_application(
+ dkT("test-paper"), dkT("dktools"), NULL
+ );
+ if (NULL != psc) {
+ dk4papersize_coll_close(psc);
+ }
+ $? "- main %d", exv
+ $!trace-end
+ return exv;
+}
diff --git a/support/dktools/test-peer.c b/support/dktools/test-peer.c
new file mode 100644
index 0000000000..fbf9317fee
--- /dev/null
+++ b/support/dktools/test-peer.c
@@ -0,0 +1,160 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-peer.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file test-peer.c The test-peer module.
+*/
+
+
+#line 10 "test-peer.ctr"
+
+#include "dk4conf.h"
+#include "dk4app.h"
+#include "dk4sock.h"
+#include "dk4socka.h"
+#include "dk4vers.h"
+#include "dk4fput.h"
+
+
+
+
+
+#line 21 "test-peer.ctr"
+
+
+static
+void
+dk4socket_c8_debug_allowed_peer(dk4_allowed_peer_t *peerptr)
+{
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6 && defined(AF_INET6)
+ unsigned char *ucptr;
+ size_t i;
+ size_t pass;
+#endif
+ unsigned long ul1, ul2;
+
+ if (NULL != stdout) {
+ switch (peerptr->af) {
+ case AF_INET : {
+ ul1 = (peerptr->data).ipv4.ad.s_addr;
+ ul2 = (peerptr->data).ipv4.ma.s_addr;
+ ul1 = dk4socket_ntohl(ul1);
+ ul2 = dk4socket_ntohl(ul2);
+ fprintf(
+ stdout,
+ "Address/Mask: %lu.%lu.%lu.%lu/%lu.%lu.%lu.%lu\n",
+ ((ul1 >> 24) & 0x000000FFUL),
+ ((ul1 >> 16) & 0x000000FFUL),
+ ((ul1 >> 8) & 0x000000FFUL),
+ ((ul1 ) & 0x000000FFUL),
+ ((ul2 >> 24) & 0x000000FFUL),
+ ((ul2 >> 16) & 0x000000FFUL),
+ ((ul2 >> 8) & 0x000000FFUL),
+ ((ul2 ) & 0x000000FFUL)
+ );
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6 && defined(AF_INET6)
+ case AF_INET6 : {
+ fputs("Address/Mask: ", stdout);
+ for (pass = 0; pass < 2; pass++) {
+ if (0 != pass) {
+ fputc('/', stdout);
+ ucptr = &((peerptr->data).ipv6.ma.s6_addr[0]);
+ } else {
+ ucptr = &((peerptr->data).ipv6.ad.s6_addr[0]);
+ }
+ for (i = 0; i < 16; i++) {
+ if ((0 != i) && (0 == (i % 2))) {
+ fputc(':', stdout);
+ }
+ fprintf(stdout, "%02x", *(ucptr++));
+ }
+ }
+ fputc('\n', stdout);
+ } break;
+#endif
+ }
+ }
+}
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ dk4_allowed_peer_t apeer;
+ dk4_er_t er;
+ size_t i;
+ int res;
+
+
+#line 95 "test-peer.ctr"
+
+
+#line 96 "test-peer.ctr"
+ if (DK4_SOCKET_RESULT_SUCCESS == dk4socket_up(NULL)) {
+
+#line 97 "test-peer.ctr"
+ for (i = 1; i < argc; i++) {
+ dk4error_init(&er);
+ res = dk4socket_get_allowed_peer(&apeer, argv[i], &er);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ printf("SUCCESS: %s\n", argv[i]);
+ dk4socket_c8_debug_allowed_peer(&apeer);
+ } else {
+ printf("FAILED: %s\n", argv[i]);
+ }
+ }
+ dk4socket_down(NULL);
+ } else {
+
+#line 109 "test-peer.ctr"
+ }
+
+
+#line 111 "test-peer.ctr"
+
+
+#line 112 "test-peer.ctr"
+ exit(0); return 0;
+}
+
+
diff --git a/support/dktools/test-peer.ctr b/support/dktools/test-peer.ctr
new file mode 100644
index 0000000000..d66bb4cb20
--- /dev/null
+++ b/support/dktools/test-peer.ctr
@@ -0,0 +1,115 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#include "dk4conf.h"
+#include "dk4app.h"
+#include "dk4sock.h"
+#include "dk4socka.h"
+#include "dk4vers.h"
+#include "dk4fput.h"
+
+
+
+$!trace-include
+
+
+static
+void
+dk4socket_c8_debug_allowed_peer(dk4_allowed_peer_t *peerptr)
+{
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6 && defined(AF_INET6)
+ unsigned char *ucptr;
+ size_t i;
+ size_t pass;
+#endif
+ unsigned long ul1, ul2;
+
+ if (NULL != stdout) {
+ switch (peerptr->af) {
+ case AF_INET : {
+ ul1 = (peerptr->data).ipv4.ad.s_addr;
+ ul2 = (peerptr->data).ipv4.ma.s_addr;
+ ul1 = dk4socket_ntohl(ul1);
+ ul2 = dk4socket_ntohl(ul2);
+ fprintf(
+ stdout,
+ "Address/Mask: %lu.%lu.%lu.%lu/%lu.%lu.%lu.%lu\n",
+ ((ul1 >> 24) & 0x000000FFUL),
+ ((ul1 >> 16) & 0x000000FFUL),
+ ((ul1 >> 8) & 0x000000FFUL),
+ ((ul1 ) & 0x000000FFUL),
+ ((ul2 >> 24) & 0x000000FFUL),
+ ((ul2 >> 16) & 0x000000FFUL),
+ ((ul2 >> 8) & 0x000000FFUL),
+ ((ul2 ) & 0x000000FFUL)
+ );
+ } break;
+#if DK4_HAVE_STRUCT_SOCKADDR_IN6 && defined(AF_INET6)
+ case AF_INET6 : {
+ fputs("Address/Mask: ", stdout);
+ for (pass = 0; pass < 2; pass++) {
+ if (0 != pass) {
+ fputc('/', stdout);
+ ucptr = &((peerptr->data).ipv6.ma.s6_addr[0]);
+ } else {
+ ucptr = &((peerptr->data).ipv6.ad.s6_addr[0]);
+ }
+ for (i = 0; i < 16; i++) {
+ if ((0 != i) && (0 == (i % 2))) {
+ fputc(':', stdout);
+ }
+ fprintf(stdout, "%02x", *(ucptr++));
+ }
+ }
+ fputc('\n', stdout);
+ } break;
+#endif
+ }
+ }
+}
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ dk4_allowed_peer_t apeer;
+ dk4_er_t er;
+ size_t i;
+ int res;
+ $!trace-init test-sock.deb
+ $? "+ main"
+ if (DK4_SOCKET_RESULT_SUCCESS == dk4socket_up(NULL)) { $? ". up"
+ for (i = 1; i < argc; i++) {
+ dk4error_init(&er);
+ res = dk4socket_get_allowed_peer(&apeer, argv[i], &er);
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ printf("SUCCESS: %s\n", argv[i]);
+ dk4socket_c8_debug_allowed_peer(&apeer);
+ } else {
+ printf("FAILED: %s\n", argv[i]);
+ }
+ }
+ dk4socket_down(NULL);
+ } else { $? "! failed to bring Winsock up"
+ }
+ $? "- main"
+ $!trace-end
+ exit(0); return 0;
+}
+
+
diff --git a/support/dktools/test-rld.c b/support/dktools/test-rld.c
new file mode 100644
index 0000000000..d818b3622e
--- /dev/null
+++ b/support/dktools/test-rld.c
@@ -0,0 +1,124 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-rld.ctr
+*/
+
+/** @file test-rld.c The test-rld module.
+*/
+
+
+#line 1 "test-rld.ctr"
+
+#include <stdio.h>
+#include "dk4rld.h"
+#include "dk4edstm.h"
+
+/*
+ Example file for run-length decoding.
+ The program reads data from standard input, applies
+ run-length decoding and writes result data to standard
+ output.
+
+ For better understanding we only do minimal diagnostics
+ here (set exit status code).
+ In real world programs one would issue more diagnostics
+ on problems.
+*/
+
+
+int main(int argc, char *argv[])
+{
+ dk4_rl_dec_t dec; /* Decoder */
+ const unsigned char *ucptr; /* Address of output buffer */
+ size_t sz; /* Number of output characters */
+ size_t i; /* Current output char index */
+#if DK4_ON_WINDOWS
+ int oldimode; /* Old file mode for stdin */
+ int oldomode; /* Old file mode for stdout */
+#endif
+ int ic; /* Current input char from stdin */
+ int stopped = 0; /* Flag: EOD found */
+ int exval = 0; /* Exit status code */
+
+ /* On Windows we must set stdin and stdout to binary mode explicitly.
+ */
+#if DK4_ON_WINDOWS
+ oldimode = _setmode(_fileno(stdin), _O_BINARY);
+ oldomode = _setmode(_fileno(stdout), _O_BINARY);
+#endif
+
+ /* Initialize decoder
+ */
+ dk4rld_init(&dec, NULL);
+
+ /* Process standard input.
+ */
+ while (EOF != (ic = fgetc(stdin))) {
+ if (1 == stopped) {
+ stopped = 2;
+ /* Error: Addtional bytes after EOD marker */
+ }
+ switch (dk4rld_add(&dec, (unsigned char)ic, NULL)) {
+ case DK4_EDSTM_FINISHED : {
+ ucptr = NULL; sz = 0;
+ if (0 != dk4rld_output(&ucptr, &sz, &dec, NULL)) {
+ if ((NULL != ucptr) && (0 < sz)) {
+ for (i = 0; i < sz; i++) {
+ if (EOF == fputc((int)(ucptr[i]), stdout)) {
+ exval = 1;
+ /* Error: Failed to write to standard output */
+ }
+ }
+ }
+ }
+ } break;
+ case DK4_EDSTM_STOP : {
+ if (0 == stopped) { stopped = 1; }
+ } break;
+ case DK4_EDSTM_ERROR : {
+ exval = 1;
+ /* Error: Not properly run-length encoded data */
+ } break;
+ }
+ }
+
+ /* If successful so far, process final data from decoder
+ and check for syntax error.
+ */
+ if (0 == exval) {
+ switch (dk4rld_finish(&dec, NULL)) {
+ case DK4_EDSTM_FINISHED : {
+ ucptr = NULL; sz = 0;
+ if (0 != dk4rld_output(&ucptr, &sz, &dec, NULL)) {
+ if ((NULL != ucptr) && (0 < sz)) {
+ for (i = 0; i < sz; i++) {
+ if (EOF == fputc((int)(ucptr[i]), stdout)) {
+ exval = 1;
+ /* Error: Failed to write to standard output */
+ }
+ }
+ }
+ }
+ } break;
+ case DK4_EDSTM_ERROR : {
+ exval = 1;
+ /* Error: Not properly run-length encoded data */
+ } break;
+ }
+ }
+
+ /* Restore previous file mode for stdin and stdout on Windows.
+ */
+#if DK4_ON_WINDOWS
+ fflush(stdout);
+ _setmode(_fileno(stdout), oldomode);
+ _setmode(_fileno(stdin), oldimode);
+#endif
+
+ /* Exit, indicate success or error.
+ */
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/test-rld.ctr b/support/dktools/test-rld.ctr
new file mode 100644
index 0000000000..2bd2984ceb
--- /dev/null
+++ b/support/dktools/test-rld.ctr
@@ -0,0 +1,112 @@
+
+#include <stdio.h>
+#include "dk4rld.h"
+#include "dk4edstm.h"
+
+/*
+ Example file for run-length decoding.
+ The program reads data from standard input, applies
+ run-length decoding and writes result data to standard
+ output.
+
+ For better understanding we only do minimal diagnostics
+ here (set exit status code).
+ In real world programs one would issue more diagnostics
+ on problems.
+*/
+
+
+int main(int argc, char *argv[])
+{
+ dk4_rl_dec_t dec; /* Decoder */
+ const unsigned char *ucptr; /* Address of output buffer */
+ size_t sz; /* Number of output characters */
+ size_t i; /* Current output char index */
+#if DK4_ON_WINDOWS
+ int oldimode; /* Old file mode for stdin */
+ int oldomode; /* Old file mode for stdout */
+#endif
+ int ic; /* Current input char from stdin */
+ int stopped = 0; /* Flag: EOD found */
+ int exval = 0; /* Exit status code */
+
+ /* On Windows we must set stdin and stdout to binary mode explicitly.
+ */
+#if DK4_ON_WINDOWS
+ oldimode = _setmode(_fileno(stdin), _O_BINARY);
+ oldomode = _setmode(_fileno(stdout), _O_BINARY);
+#endif
+
+ /* Initialize decoder
+ */
+ dk4rld_init(&dec, NULL);
+
+ /* Process standard input.
+ */
+ while (EOF != (ic = fgetc(stdin))) {
+ if (1 == stopped) {
+ stopped = 2;
+ /* Error: Addtional bytes after EOD marker */
+ }
+ switch (dk4rld_add(&dec, (unsigned char)ic, NULL)) {
+ case DK4_EDSTM_FINISHED : {
+ ucptr = NULL; sz = 0;
+ if (0 != dk4rld_output(&ucptr, &sz, &dec, NULL)) {
+ if ((NULL != ucptr) && (0 < sz)) {
+ for (i = 0; i < sz; i++) {
+ if (EOF == fputc((int)(ucptr[i]), stdout)) {
+ exval = 1;
+ /* Error: Failed to write to standard output */
+ }
+ }
+ }
+ }
+ } break;
+ case DK4_EDSTM_STOP : {
+ if (0 == stopped) { stopped = 1; }
+ } break;
+ case DK4_EDSTM_ERROR : {
+ exval = 1;
+ /* Error: Not properly run-length encoded data */
+ } break;
+ }
+ }
+
+ /* If successful so far, process final data from decoder
+ and check for syntax error.
+ */
+ if (0 == exval) {
+ switch (dk4rld_finish(&dec, NULL)) {
+ case DK4_EDSTM_FINISHED : {
+ ucptr = NULL; sz = 0;
+ if (0 != dk4rld_output(&ucptr, &sz, &dec, NULL)) {
+ if ((NULL != ucptr) && (0 < sz)) {
+ for (i = 0; i < sz; i++) {
+ if (EOF == fputc((int)(ucptr[i]), stdout)) {
+ exval = 1;
+ /* Error: Failed to write to standard output */
+ }
+ }
+ }
+ }
+ } break;
+ case DK4_EDSTM_ERROR : {
+ exval = 1;
+ /* Error: Not properly run-length encoded data */
+ } break;
+ }
+ }
+
+ /* Restore previous file mode for stdin and stdout on Windows.
+ */
+#if DK4_ON_WINDOWS
+ fflush(stdout);
+ _setmode(_fileno(stdout), oldomode);
+ _setmode(_fileno(stdin), oldimode);
+#endif
+
+ /* Exit, indicate success or error.
+ */
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/test-rle-rld.sh b/support/dktools/test-rle-rld.sh
new file mode 100755
index 0000000000..13a21ca244
--- /dev/null
+++ b/support/dktools/test-rle-rld.sh
@@ -0,0 +1,14 @@
+:
+for i in `find . -type f`
+do
+ echo Checking $i
+ CSA=`dkt ls -px $i`
+ cat $i | ./test-rle | ./test-rld > ../x.dat
+ CSB=`dkt ls -px ../x.dat`
+ if [ "X$CSA" != "X$CSB" ]
+ then
+ echo Difference for $i
+ fi
+ rm -f ../x.dat
+done
+
diff --git a/support/dktools/test-rle.c b/support/dktools/test-rle.c
new file mode 100644
index 0000000000..5aa2f27288
--- /dev/null
+++ b/support/dktools/test-rle.c
@@ -0,0 +1,181 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-rle.ctr
+*/
+
+/** @file test-rle.c The test-rle module.
+*/
+
+
+#line 1 "test-rle.ctr"
+
+#include <stdio.h>
+#include "dk4rle.h"
+#include "dk4edstm.h"
+
+
+
+
+
+#line 9 "test-rle.ctr"
+
+
+
+/*
+ Example file for run-length encoding.
+ The program reads data from standard input, applies
+ run-length encoding and writes result data to standard
+ output.
+
+ For better understanding we only do minimal diagnostics
+ here (set exit status code).
+ In real world programs one would issue more diagnostics
+ on problems.
+*/
+
+
+int main(int argc, char *argv[])
+{
+ dk4_rl_enc_t enc; /* Encoder */
+ const unsigned char *ucptr; /* Address of output buffer */
+ unsigned long offset; /* Current offset in file */
+ size_t sz; /* Number of output characters */
+ size_t i; /* Current output char index */
+#if DK4_ON_WINDOWS
+ int oldimode; /* Old file mode for stdin */
+ int oldomode; /* Old file mode for stdout */
+#endif
+ int ic; /* Current input char from stdin */
+ int exval = 0; /* Exit status code */
+
+
+
+#line 40 "test-rle.ctr"
+
+
+#line 41 "test-rle.ctr"
+ /* On Windows we must set stdin and stdout to binary mode explicitly.
+ */
+#if DK4_ON_WINDOWS
+ oldimode = _setmode(_fileno(stdin), _O_BINARY);
+ oldomode = _setmode(_fileno(stdout), _O_BINARY);
+#endif
+
+ /* Initialize encoder.
+ */
+ dk4rle_init(&enc, 0, NULL);
+
+#line 51 "test-rle.ctr"
+
+
+#line 52 "test-rle.ctr"
+
+ /* Process standard input.
+ */
+ offset = 0UL;
+ while (EOF != (ic = fgetc(stdin))) {
+
+
+#line 58 "test-rle.ctr"
+ switch (dk4rle_add(&enc, (unsigned char)ic, NULL)) {
+ case DK4_EDSTM_FINISHED : {
+
+#line 60 "test-rle.ctr"
+ ucptr = NULL; sz = 0;
+ if (0 != dk4rle_output(&ucptr, &sz, &enc, NULL)) {
+
+#line 62 "test-rle.ctr"
+ if ((NULL != ucptr) && (0 < sz)) {
+
+#line 63 "test-rle.ctr"
+
+
+#line 64 "test-rle.ctr"
+ for (i = 0; i < sz; i++) {
+
+
+#line 66 "test-rle.ctr"
+ if (EOF == fputc((int)(ucptr[i]), stdout)) {
+
+#line 67 "test-rle.ctr"
+ exval = 1;
+ }
+ }
+ }
+ }
+ } break;
+ case DK4_EDSTM_ERROR : {
+
+#line 74 "test-rle.ctr"
+ exval = 1;
+ } break;
+ default : {
+
+#line 77 "test-rle.ctr"
+ } break;
+ }
+ offset++;
+ }
+
+
+#line 82 "test-rle.ctr"
+
+ /* If successful so far, process final data from encoder.
+ */
+ if (0 == exval) {
+
+#line 86 "test-rle.ctr"
+ switch (dk4rle_finish(&enc, NULL)) {
+ case DK4_EDSTM_FINISHED : {
+
+#line 88 "test-rle.ctr"
+ ucptr = NULL; sz = 0;
+ if (0 != dk4rle_output(&ucptr, &sz, &enc, NULL)) {
+ if ((NULL != ucptr) && (0 < sz)) {
+
+
+#line 92 "test-rle.ctr"
+ for (i = 0; i < sz; i++) {
+
+
+#line 94 "test-rle.ctr"
+ if (EOF == fputc((int)(ucptr[i]), stdout)) {
+ exval = 1;
+ }
+ }
+ }
+ }
+ } break;
+ case DK4_EDSTM_ERROR : {
+
+#line 102 "test-rle.ctr"
+ exval = 1;
+ } break;
+ default : {
+
+#line 105 "test-rle.ctr"
+ } break;
+ }
+ }
+
+ /* Restore previous file mode for stdin and stdout on Windows.
+ */
+#if DK4_ON_WINDOWS
+ fflush(stdout);
+ _setmode(_fileno(stdout), oldomode);
+ _setmode(_fileno(stdin), oldimode);
+#endif
+
+ /* Exit, indicate success or error.
+ */
+
+
+#line 120 "test-rle.ctr"
+
+
+#line 121 "test-rle.ctr"
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/test-rle.ctr b/support/dktools/test-rle.ctr
new file mode 100644
index 0000000000..bb20304f78
--- /dev/null
+++ b/support/dktools/test-rle.ctr
@@ -0,0 +1,123 @@
+
+#include <stdio.h>
+#include "dk4rle.h"
+#include "dk4edstm.h"
+
+
+
+$!trace-include
+
+
+
+/*
+ Example file for run-length encoding.
+ The program reads data from standard input, applies
+ run-length encoding and writes result data to standard
+ output.
+
+ For better understanding we only do minimal diagnostics
+ here (set exit status code).
+ In real world programs one would issue more diagnostics
+ on problems.
+*/
+
+
+int main(int argc, char *argv[])
+{
+ dk4_rl_enc_t enc; /* Encoder */
+ const unsigned char *ucptr; /* Address of output buffer */
+ unsigned long offset; /* Current offset in file */
+ size_t sz; /* Number of output characters */
+ size_t i; /* Current output char index */
+#if DK4_ON_WINDOWS
+ int oldimode; /* Old file mode for stdin */
+ int oldomode; /* Old file mode for stdout */
+#endif
+ int ic; /* Current input char from stdin */
+ int exval = 0; /* Exit status code */
+
+ $!trace-init test-rle.deb
+ $? "+ main"
+ /* On Windows we must set stdin and stdout to binary mode explicitly.
+ */
+#if DK4_ON_WINDOWS
+ oldimode = _setmode(_fileno(stdin), _O_BINARY);
+ oldomode = _setmode(_fileno(stdout), _O_BINARY);
+#endif
+
+ /* Initialize encoder.
+ */
+ dk4rle_init(&enc, 0, NULL); $? ". initialized"
+ $? ". enc->iused = %u", (unsigned)(enc.iused)
+
+ /* Process standard input.
+ */
+ offset = 0UL;
+ while (EOF != (ic = fgetc(stdin))) {
+ $? ". new char, offset = %lu %lx", offset, offset
+ switch (dk4rle_add(&enc, (unsigned char)ic, NULL)) {
+ case DK4_EDSTM_FINISHED : { $? ". must retrieve output"
+ ucptr = NULL; sz = 0;
+ if (0 != dk4rle_output(&ucptr, &sz, &enc, NULL)) { $? ". output"
+ if ((NULL != ucptr) && (0 < sz)) { $? ". pointers"
+ $? ". write %u bytes", (unsigned)sz
+ for (i = 0; i < sz; i++) {
+ $? ". fputc %u = %02x", (unsigned)i, (unsigned)(ucptr[i])
+ if (EOF == fputc((int)(ucptr[i]), stdout)) { $? "! EOF"
+ exval = 1;
+ }
+ }
+ }
+ }
+ } break;
+ case DK4_EDSTM_ERROR : { $? ". error"
+ exval = 1;
+ } break;
+ default : { $? ". no action required"
+ } break;
+ }
+ offset++;
+ }
+ $? ". all input processed"
+
+ /* If successful so far, process final data from encoder.
+ */
+ if (0 == exval) { $? ". finish"
+ switch (dk4rle_finish(&enc, NULL)) {
+ case DK4_EDSTM_FINISHED : { $? ". output"
+ ucptr = NULL; sz = 0;
+ if (0 != dk4rle_output(&ucptr, &sz, &enc, NULL)) {
+ if ((NULL != ucptr) && (0 < sz)) {
+ $? ". write %u bytes", (unsigned)sz
+ for (i = 0; i < sz; i++) {
+ $? ". fputc %u %02x", (unsigned)i, (unsigned)(ucptr[i])
+ if (EOF == fputc((int)(ucptr[i]), stdout)) {
+ exval = 1;
+ }
+ }
+ }
+ }
+ } break;
+ case DK4_EDSTM_ERROR : { $? "! error"
+ exval = 1;
+ } break;
+ default : { $? ". no action required"
+ } break;
+ }
+ }
+
+ /* Restore previous file mode for stdin and stdout on Windows.
+ */
+#if DK4_ON_WINDOWS
+ fflush(stdout);
+ _setmode(_fileno(stdout), oldomode);
+ _setmode(_fileno(stdin), oldimode);
+#endif
+
+ /* Exit, indicate success or error.
+ */
+ $? "- main %d", exval
+ $!trace-end
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/test-ser.c b/support/dktools/test-ser.c
new file mode 100644
index 0000000000..f8c9af214f
--- /dev/null
+++ b/support/dktools/test-ser.c
@@ -0,0 +1,162 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-ser.ctr
+*/
+
+/** @file test-ser.c The test-ser module.
+*/
+
+
+#line 1 "test-ser.ctr"
+
+#include <stdio.h>
+#include <stdint.h>
+#define _USE_MATH_DEFINES 1
+#include <math.h>
+
+
+#include "dk4mem.h"
+#include "dk4serf.h"
+#include "dk4userf.h"
+#include "dk4app.h"
+#include "dk4str8.h"
+
+
+
+static const dkChar * const test_ser_help_text[] = {
+dkT("This is a test program to create directories."),
+NULL
+
+
+#line 20 "test-ser.ctr"
+};
+
+static const dkChar * const test_ser_license_text[] = {
+dkT("Copyright (c) 2014-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions"),
+dkT("are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above copyright notice,"),
+dkT(" this list of conditions and the following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("* Neither the name of the Dirk Krause nor the names of contributors may be"),
+dkT(" used to endorse or promote products derived from this software without"),
+dkT(" specific prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS"),
+dkT("\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT"),
+dkT("LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR"),
+dkT("A PARTICULAR PURPOSE ARE DISCLAIMED."),
+dkT(""),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS"),
+dkT("OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)"),
+dkT("HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,"),
+dkT("STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN"),
+dkT("ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE"),
+dkT("POSSIBILITY OF SUCH DAMAGE."),
+NULL
+
+
+#line 54 "test-ser.ctr"
+};
+
+static uint16_t td1[] = { 2U, 4U, 6U, 8U, 1U , 3U, 5U, 7U };
+
+static const size_t sztd1 = DK4_SIZEOF(td1,uint16_t);
+
+static uint32_t td2[] = { 64UL, 66UL, 68UL, 70UL, 65UL, 67UL, 69UL, 71UL};
+
+static const size_t sztd2 = DK4_SIZEOF(td2,uint32_t);
+
+static int16_t td3[] = { 128, 130, 132, 129, 131, 133 };
+
+static const size_t sztd3 = DK4_SIZEOF(td3,int16_t);
+
+static int32_t td4[] = { 256L, 258L, 260L, 257L, 259L, 261L };
+
+static double td5[] = { M_PI, (M_PI_2 / 10.0) , (M_PI_4 * 100.0) };
+
+static const size_t sztd5 = DK4_SIZEOF(td5,double);
+
+static const size_t sztd4 = DK4_SIZEOF(td4,int32_t);
+
+static const dkChar ts[] = { dkT("Dies ist ein Test mit äöüßÄÖÜ blubb.") };
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ char buf[64];
+ FILE *fipo;
+ size_t i;
+ int exv = EXIT_FAILURE;
+ int de = 0;
+
+ app = dk4app_open_cmd(
+ argc, argv, NULL, 0,
+ dkT("dktools-4-test"), dkT("1.0.0"),
+ dkT("test-ser.txt"), test_ser_help_text,
+ test_ser_license_text
+ );
+ if (NULL != app) {
+ de = dk4app_get_encoding(app);
+ fipo = fopen("test-ser.out", "wb");
+ if (NULL != fipo) {
+ exv = EXIT_SUCCESS;
+ for (i = 0; i < sztd1; i++) {
+ if (0 == dk4serialize_file_uint16_t(fipo, td1[i], NULL)) {
+ exv = EXIT_FAILURE;
+ }
+ }
+ for (i = 0; i < sztd3; i++) {
+ if (0 == dk4serialize_file_int16_t(fipo, td3[i], NULL)) {
+ exv = EXIT_FAILURE;
+ }
+ }
+ if (0 == dk4serialize_file_dk_string(fipo, ts, de, NULL)) {
+ exv = EXIT_FAILURE;
+ }
+ for (i = 0; i < sztd2; i++) {
+ if (0 == dk4serialize_file_uint32_t(fipo, td2[i], NULL)) {
+ exv = EXIT_FAILURE;
+ }
+ }
+ for (i = 0; i < sztd4; i++) {
+ if (0 == dk4serialize_file_int32_t(fipo, td4[i], NULL)) {
+ exv = EXIT_FAILURE;
+ }
+ }
+ for (i = 0; i < sztd5; i++) {
+ if (0 == dk4serialize_file_double(fipo, td5[i], NULL)) {
+ exv = EXIT_FAILURE;
+ }
+ }
+ fclose(fipo);
+ }
+ dk4app_close(app);
+ }
+ return exv;
+}
+
diff --git a/support/dktools/test-ser.ctr b/support/dktools/test-ser.ctr
new file mode 100644
index 0000000000..1fc37470f6
--- /dev/null
+++ b/support/dktools/test-ser.ctr
@@ -0,0 +1,146 @@
+
+#include <stdio.h>
+#include <stdint.h>
+#define _USE_MATH_DEFINES 1
+#include <math.h>
+
+
+#include "dk4mem.h"
+#include "dk4serf.h"
+#include "dk4userf.h"
+#include "dk4app.h"
+#include "dk4str8.h"
+
+
+
+static const dkChar * const test_ser_help_text[] = {
+$!text macro=dkT
+This is a test program to create directories.
+$!end
+};
+
+static const dkChar * const test_ser_license_text[] = {
+$!text macro=dkT
+Copyright (c) 2014-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+$!end
+};
+
+static uint16_t td1[] = { 2U, 4U, 6U, 8U, 1U , 3U, 5U, 7U };
+
+static const size_t sztd1 = DK4_SIZEOF(td1,uint16_t);
+
+static uint32_t td2[] = { 64UL, 66UL, 68UL, 70UL, 65UL, 67UL, 69UL, 71UL};
+
+static const size_t sztd2 = DK4_SIZEOF(td2,uint32_t);
+
+static int16_t td3[] = { 128, 130, 132, 129, 131, 133 };
+
+static const size_t sztd3 = DK4_SIZEOF(td3,int16_t);
+
+static int32_t td4[] = { 256L, 258L, 260L, 257L, 259L, 261L };
+
+static double td5[] = { M_PI, (M_PI_2 / 10.0) , (M_PI_4 * 100.0) };
+
+static const size_t sztd5 = DK4_SIZEOF(td5,double);
+
+static const size_t sztd4 = DK4_SIZEOF(td4,int32_t);
+
+static const dkChar ts[] = { dkT("Dies ist ein Test mit äöüßÄÖÜ blubb.") };
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ char buf[64];
+ FILE *fipo;
+ size_t i;
+ int exv = EXIT_FAILURE;
+ int de = 0;
+
+ app = dk4app_open_cmd(
+ argc, argv, NULL, 0,
+ dkT("dktools-4-test"), dkT("1.0.0"),
+ dkT("test-ser.txt"), test_ser_help_text,
+ test_ser_license_text
+ );
+ if (NULL != app) {
+ de = dk4app_get_encoding(app);
+ fipo = fopen("test-ser.out", "wb");
+ if (NULL != fipo) {
+ exv = EXIT_SUCCESS;
+ for (i = 0; i < sztd1; i++) {
+ if (0 == dk4serialize_file_uint16_t(fipo, td1[i], NULL)) {
+ exv = EXIT_FAILURE;
+ }
+ }
+ for (i = 0; i < sztd3; i++) {
+ if (0 == dk4serialize_file_int16_t(fipo, td3[i], NULL)) {
+ exv = EXIT_FAILURE;
+ }
+ }
+ if (0 == dk4serialize_file_dk_string(fipo, ts, de, NULL)) {
+ exv = EXIT_FAILURE;
+ }
+ for (i = 0; i < sztd2; i++) {
+ if (0 == dk4serialize_file_uint32_t(fipo, td2[i], NULL)) {
+ exv = EXIT_FAILURE;
+ }
+ }
+ for (i = 0; i < sztd4; i++) {
+ if (0 == dk4serialize_file_int32_t(fipo, td4[i], NULL)) {
+ exv = EXIT_FAILURE;
+ }
+ }
+ for (i = 0; i < sztd5; i++) {
+ if (0 == dk4serialize_file_double(fipo, td5[i], NULL)) {
+ exv = EXIT_FAILURE;
+ }
+ }
+ fclose(fipo);
+ }
+ dk4app_close(app);
+ }
+ return exv;
+}
+
diff --git a/support/dktools/test-skip.c b/support/dktools/test-skip.c
new file mode 100644
index 0000000000..7a1c2a4f67
--- /dev/null
+++ b/support/dktools/test-skip.c
@@ -0,0 +1,31 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-skip.ctr
+*/
+
+/** @file test-skip.c The test-skip module.
+*/
+
+
+#line 1 "test-skip.ctr"
+
+#include <stdio.h>
+
+#include <dk4str8.h>
+
+const char testline[] = { " Dies ist ein Test." };
+
+
+int main(void)
+{
+ const char *text;
+ size_t i;
+
+ for (i = 0; i < 6; i++) {
+ text = dk4str8_skip(testline, i);
+ printf("%u \"%s\"\n", (unsigned)i, ((NULL != text) ? text : "(NULL)"));
+ }
+ return 0;
+}
diff --git a/support/dktools/test-skip.ctr b/support/dktools/test-skip.ctr
new file mode 100644
index 0000000000..651375b86d
--- /dev/null
+++ b/support/dktools/test-skip.ctr
@@ -0,0 +1,19 @@
+
+#include <stdio.h>
+
+#include <dk4str8.h>
+
+const char testline[] = { " Dies ist ein Test." };
+
+
+int main(void)
+{
+ const char *text;
+ size_t i;
+
+ for (i = 0; i < 6; i++) {
+ text = dk4str8_skip(testline, i);
+ printf("%u \"%s\"\n", (unsigned)i, ((NULL != text) ? text : "(NULL)"));
+ }
+ return 0;
+}
diff --git a/support/dktools/test-sock.c b/support/dktools/test-sock.c
new file mode 100644
index 0000000000..3b506ddf21
--- /dev/null
+++ b/support/dktools/test-sock.c
@@ -0,0 +1,253 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-sock.ctr
+*/
+
+/*
+Copyright (C) 2015-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file test-sock.c The test-sock module.
+*/
+
+
+#line 10 "test-sock.ctr"
+
+#define TEST_SOCK_USE_APP 1
+#define TEST_SOCK_REMOTE_SERVER "s-ka.e-technik.fh-schmalkalden.de"
+#define TEST_SOCK_REMOTE_PORT 80
+#define TEST_SOCK_LOCAL_PORT 55555
+#define TEST_SOCK_TIMEOUT_SEC 0L
+#define TEST_SOCK_TIMEOUT_USEC 0L
+
+#include "dk4conf.h"
+#include "dk4app.h"
+#include "dk4sock.h"
+#include "dk4socka.h"
+#include "dk4vers.h"
+#include "dk4fput.h"
+
+
+
+
+
+#line 28 "test-sock.ctr"
+
+
+
+static const dkChar server[] = { dkT("s-ka.e-technik.fh-schmalkalden.de") };
+
+static const char request[] = {
+ "GET /index.html HTTP/1.0\r\n\r\n"
+};
+
+
+static const dkChar * const help_text[] = {
+/* 0 */
+dkT("Nix Hilfe!"),
+
+NULL
+
+
+#line 42 "test-sock.ctr"
+};
+
+static const dkChar * const license_text[] = {
+/* 0 */
+dkT("BSD"),
+
+NULL
+
+
+#line 48 "test-sock.ctr"
+};
+
+static const dkChar * const kw_def[] = {
+/* 0 */
+dkT("Failed to create socket!"),
+
+/* 1 */
+dkT("Failed to bring Winsock up!"),
+
+/* 2 */
+dkT("Failed to send data!"),
+
+NULL
+
+
+#line 65 "test-sock.ctr"
+};
+
+static size_t sz_kw_def = sizeof(kw_def)/sizeof(DK4_PCDKCHAR);
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+#if TEST_SOCK_USE_APP
+ char buf[512];
+ dk4_app_t *app = NULL;
+ size_t rql;
+ dk4_socket_t sock;
+#if DK4_ON_WINDOWS
+ int bytes;
+#else
+ ssize_t bytes;
+#endif
+
+
+#line 91 "test-sock.ctr"
+
+
+#line 92 "test-sock.ctr"
+ dk4fput_initialize_stderr();
+ app = dk4app_open_cmd(
+ argc, argv, NULL, 0, dkT("dktools"), DKT_VERSION_DK,
+ dkT("test-sock.txt"), help_text, license_text
+ );
+ if (NULL != app) {
+ if (DK4_SOCKET_RESULT_SUCCESS == dk4socket_up_app(app)) {
+
+#line 99 "test-sock.ctr"
+ rql = strlen(request);
+ sock = dk4socket_tcp_client_for_host_port_app(
+ server, TEST_SOCK_REMOTE_PORT, TEST_SOCK_LOCAL_PORT,
+ TEST_SOCK_TIMEOUT_SEC, TEST_SOCK_TIMEOUT_USEC, app
+ );
+ if (INVALID_SOCKET != sock) {
+
+#line 105 "test-sock.ctr"
+ bytes = send(sock, request, rql, 0);
+ if (bytes == rql) {
+
+#line 107 "test-sock.ctr"
+ do {
+ bytes = recv(sock, buf, sizeof(buf), 0);
+ if (0 < bytes) {
+ fwrite(buf, 1, bytes, stdout);
+ }
+ } while(0 < bytes);
+ fputc('\n', stdout);
+ } else {
+
+#line 115 "test-sock.ctr"
+ dk4app_log_1(app, kw_def, sz_kw_def, DK4_LL_ERROR, 2);
+ }
+ dk4socket_close(sock, NULL);
+ } else {
+
+#line 119 "test-sock.ctr"
+ dk4app_log_1(app, kw_def, sz_kw_def, DK4_LL_ERROR, 0);
+ }
+ dk4socket_down_app(app);
+ } else {
+
+#line 123 "test-sock.ctr"
+ dk4app_log_1(app, kw_def, sz_kw_def, DK4_LL_ERROR, 1);
+ }
+ dk4app_close(app);
+ }
+ fflush(stderr);
+ dk4fput_cleanup_stderr();
+
+
+#line 130 "test-sock.ctr"
+
+
+#line 131 "test-sock.ctr"
+ exit(0); return 0;
+#else
+ char buf[512];
+ size_t rql;
+ dk4_socket_t sock;
+#if DK4_ON_WINDOWS
+ int bytes;
+#else
+ ssize_t bytes;
+#endif
+
+
+#line 142 "test-sock.ctr"
+
+
+#line 143 "test-sock.ctr"
+ rql = strlen(request);
+ if (DK4_SOCKET_RESULT_SUCCESS == dk4socket_up(NULL)) {
+
+#line 145 "test-sock.ctr"
+ sock = dk4socket_tcp_client_host_port(
+ server, TEST_SOCK_REMOTE_PORT, TEST_SOCK_LOCAL_PORT,
+ TEST_SOCK_TIMEOUT_SEC, TEST_SOCK_TIMEOUT_USEC, NULL
+ );
+ if (INVALID_SOCKET != sock) {
+
+#line 150 "test-sock.ctr"
+ bytes = send(sock, request, rql, 0);
+ if (bytes == rql) {
+
+#line 152 "test-sock.ctr"
+ do {
+ bytes = recv(sock, buf, sizeof(buf), 0);
+ if (0 < bytes) {
+ fwrite(buf, 1, bytes, stdout);
+ }
+ } while(0 < bytes);
+ fputc('\n', stdout);
+ } else {
+
+#line 160 "test-sock.ctr"
+ }
+ dk4socket_close(sock, NULL);
+ } else {
+
+#line 163 "test-sock.ctr"
+ }
+ dk4socket_down(NULL);
+ } else {
+
+#line 166 "test-sock.ctr"
+ }
+
+
+#line 168 "test-sock.ctr"
+
+
+#line 169 "test-sock.ctr"
+ exit(0); return 0;
+#endif
+}
+
+
diff --git a/support/dktools/test-sock.ctr b/support/dktools/test-sock.ctr
new file mode 100644
index 0000000000..57f4570b7e
--- /dev/null
+++ b/support/dktools/test-sock.ctr
@@ -0,0 +1,173 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% module
+
+#define TEST_SOCK_USE_APP 1
+#define TEST_SOCK_REMOTE_SERVER "s-ka.e-technik.fh-schmalkalden.de"
+#define TEST_SOCK_REMOTE_PORT 80
+#define TEST_SOCK_LOCAL_PORT 55555
+#define TEST_SOCK_TIMEOUT_SEC 0L
+#define TEST_SOCK_TIMEOUT_USEC 0L
+
+#include "dk4conf.h"
+#include "dk4app.h"
+#include "dk4sock.h"
+#include "dk4socka.h"
+#include "dk4vers.h"
+#include "dk4fput.h"
+
+
+
+$!trace-include
+
+
+
+static const dkChar server[] = { dkT("s-ka.e-technik.fh-schmalkalden.de") };
+
+static const char request[] = {
+ "GET /index.html HTTP/1.0\r\n\r\n"
+};
+
+
+static const dkChar * const help_text[] = {
+$!string-table macro=dkT
+Nix Hilfe!
+$!end
+};
+
+static const dkChar * const license_text[] = {
+$!string-table macro=dkT
+BSD
+$!end
+};
+
+static const dkChar * const kw_def[] = {
+$!string-table macro=dkT
+#
+# 0
+#
+Failed to create socket!
+#
+# 1
+#
+Failed to bring Winsock up!
+#
+# 2
+#
+Failed to send data!
+$!end
+};
+
+static size_t sz_kw_def = sizeof(kw_def)/sizeof(DK4_PCDKCHAR);
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+#if TEST_SOCK_USE_APP
+ char buf[512];
+ dk4_app_t *app = NULL;
+ size_t rql;
+ dk4_socket_t sock;
+#if DK4_ON_WINDOWS
+ int bytes;
+#else
+ ssize_t bytes;
+#endif
+ $!trace-init test-sock.deb
+ $? "+ main"
+ dk4fput_initialize_stderr();
+ app = dk4app_open_cmd(
+ argc, argv, NULL, 0, dkT("dktools"), DKT_VERSION_DK,
+ dkT("test-sock.txt"), help_text, license_text
+ );
+ if (NULL != app) {
+ if (DK4_SOCKET_RESULT_SUCCESS == dk4socket_up_app(app)) { $? ". up"
+ rql = strlen(request);
+ sock = dk4socket_tcp_client_for_host_port_app(
+ server, TEST_SOCK_REMOTE_PORT, TEST_SOCK_LOCAL_PORT,
+ TEST_SOCK_TIMEOUT_SEC, TEST_SOCK_TIMEOUT_USEC, app
+ );
+ if (INVALID_SOCKET != sock) { $? ". socket ok"
+ bytes = send(sock, request, rql, 0);
+ if (bytes == rql) { $? ". send ok"
+ do {
+ bytes = recv(sock, buf, sizeof(buf), 0);
+ if (0 < bytes) {
+ fwrite(buf, 1, bytes, stdout);
+ }
+ } while(0 < bytes);
+ fputc('\n', stdout);
+ } else { $? "! send failed"
+ dk4app_log_1(app, kw_def, sz_kw_def, DK4_LL_ERROR, 2);
+ }
+ dk4socket_close(sock, NULL);
+ } else { $? "! invalid socket"
+ dk4app_log_1(app, kw_def, sz_kw_def, DK4_LL_ERROR, 0);
+ }
+ dk4socket_down_app(app);
+ } else { $? "! Winsock up"
+ dk4app_log_1(app, kw_def, sz_kw_def, DK4_LL_ERROR, 1);
+ }
+ dk4app_close(app);
+ }
+ fflush(stderr);
+ dk4fput_cleanup_stderr();
+ $? "- main"
+ $!trace-end
+ exit(0); return 0;
+#else
+ char buf[512];
+ size_t rql;
+ dk4_socket_t sock;
+#if DK4_ON_WINDOWS
+ int bytes;
+#else
+ ssize_t bytes;
+#endif
+ $!trace-init test-sock.deb
+ $? "+ main"
+ rql = strlen(request);
+ if (DK4_SOCKET_RESULT_SUCCESS == dk4socket_up(NULL)) { $? ". up"
+ sock = dk4socket_tcp_client_host_port(
+ server, TEST_SOCK_REMOTE_PORT, TEST_SOCK_LOCAL_PORT,
+ TEST_SOCK_TIMEOUT_SEC, TEST_SOCK_TIMEOUT_USEC, NULL
+ );
+ if (INVALID_SOCKET != sock) { $? ". socket"
+ bytes = send(sock, request, rql, 0);
+ if (bytes == rql) { $? ". send"
+ do {
+ bytes = recv(sock, buf, sizeof(buf), 0);
+ if (0 < bytes) {
+ fwrite(buf, 1, bytes, stdout);
+ }
+ } while(0 < bytes);
+ fputc('\n', stdout);
+ } else { $? "! send"
+ }
+ dk4socket_close(sock, NULL);
+ } else { $? "! socket"
+ }
+ dk4socket_down(NULL);
+ } else { $? "! failed to bring Winsock up"
+ }
+ $? "- main"
+ $!trace-end
+ exit(0); return 0;
+#endif
+}
+
+
diff --git a/support/dktools/test-sqdbl.c b/support/dktools/test-sqdbl.c
new file mode 100644
index 0000000000..2f307a1aad
--- /dev/null
+++ b/support/dktools/test-sqdbl.c
@@ -0,0 +1,51 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-sqdbl.ctr
+*/
+
+/** @file test-sqdbl.c The test-sqdbl module.
+*/
+
+
+#line 1 "test-sqdbl.ctr"
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+#include <stdio.h>
+#include <math.h>
+
+#include "dk4str8.h"
+
+
+
+
+
+#line 13 "test-sqdbl.ctr"
+
+
+
+int main(void)
+{
+ char buf[64];
+ double v;
+ int i;
+
+ v = 5.555 / 1000000.0;
+ for (i = 0; i < 12; i++) {
+ if (0 != dk4str8_double_to_string(buf, sizeof(buf), v, 0, NULL)) {
+ fputs(buf, stdout);
+ fputc('\n', stdout);
+ }
+ if (0 != dk4str8_double_to_string(buf, sizeof(buf), v, 1, NULL)) {
+ fputs(buf, stdout);
+ fputc('\n', stdout);
+ }
+ v = 10.0 * v;
+ fputc('\n', stdout);
+ }
+ return 0;
+}
+
diff --git a/support/dktools/test-sqdbl.ctr b/support/dktools/test-sqdbl.ctr
new file mode 100644
index 0000000000..6ec065e36f
--- /dev/null
+++ b/support/dktools/test-sqdbl.ctr
@@ -0,0 +1,37 @@
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+#include <stdio.h>
+#include <math.h>
+
+#include "dk4str8.h"
+
+
+
+$!trace-include
+
+
+
+int main(void)
+{
+ char buf[64];
+ double v;
+ int i;
+
+ v = 5.555 / 1000000.0;
+ for (i = 0; i < 12; i++) {
+ if (0 != dk4str8_double_to_string(buf, sizeof(buf), v, 0, NULL)) {
+ fputs(buf, stdout);
+ fputc('\n', stdout);
+ }
+ if (0 != dk4str8_double_to_string(buf, sizeof(buf), v, 1, NULL)) {
+ fputs(buf, stdout);
+ fputc('\n', stdout);
+ }
+ v = 10.0 * v;
+ fputc('\n', stdout);
+ }
+ return 0;
+}
+
diff --git a/support/dktools/test-strms.c b/support/dktools/test-strms.c
new file mode 100644
index 0000000000..17b860fe3d
--- /dev/null
+++ b/support/dktools/test-strms.c
@@ -0,0 +1,48 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-strms.ctr
+*/
+
+/** @file test-strms.c The test-strms module.
+*/
+
+
+#line 1 "test-strms.ctr"
+
+#include "dk4conf.h"
+
+#include <math.h>
+
+#include "dk4strm.h"
+#include "dk4strmw.h"
+#include "dk4strms.h"
+
+static const char t1[] = { "Dies ist ein Test-String." };
+
+int main(void)
+{
+ dk4_stream_t *wrstr;
+
+ wrstr = dk4stream_open_file_writer("/tmp/test.dat.gz", NULL);
+ if (NULL != wrstr) {
+ dk4stream_serialize_u32(wrstr, 25UL, NULL);
+ dk4stream_serialize_i32(wrstr, -16L, NULL);
+ dk4stream_serialize_string(wrstr, t1, NULL);
+ dk4stream_serialize_u16(wrstr, 50U, NULL);
+ dk4stream_serialize_double(wrstr, M_PI, 1.0e-6, NULL);
+ dk4stream_serialize_i16(wrstr, -32, NULL);
+ dk4stream_serialize_double_0(wrstr, NULL);
+ dk4stream_serialize_u8(wrstr, 100, NULL);
+ dk4stream_serialize_i8(wrstr, -64, NULL);
+ dk4stream_close(wrstr, NULL);
+ }
+ else {
+ }
+ return 0;
+}
+
+
+/* vim: set ai sw=4 ts=4 : */
+
diff --git a/support/dktools/test-strms.ctr b/support/dktools/test-strms.ctr
new file mode 100644
index 0000000000..dd4910804c
--- /dev/null
+++ b/support/dktools/test-strms.ctr
@@ -0,0 +1,36 @@
+
+#include "dk4conf.h"
+
+#include <math.h>
+
+#include "dk4strm.h"
+#include "dk4strmw.h"
+#include "dk4strms.h"
+
+static const char t1[] = { "Dies ist ein Test-String." };
+
+int main(void)
+{
+ dk4_stream_t *wrstr;
+
+ wrstr = dk4stream_open_file_writer("/tmp/test.dat.gz", NULL);
+ if (NULL != wrstr) {
+ dk4stream_serialize_u32(wrstr, 25UL, NULL);
+ dk4stream_serialize_i32(wrstr, -16L, NULL);
+ dk4stream_serialize_string(wrstr, t1, NULL);
+ dk4stream_serialize_u16(wrstr, 50U, NULL);
+ dk4stream_serialize_double(wrstr, M_PI, 1.0e-6, NULL);
+ dk4stream_serialize_i16(wrstr, -32, NULL);
+ dk4stream_serialize_double_0(wrstr, NULL);
+ dk4stream_serialize_u8(wrstr, 100, NULL);
+ dk4stream_serialize_i8(wrstr, -64, NULL);
+ dk4stream_close(wrstr, NULL);
+ }
+ else {
+ }
+ return 0;
+}
+
+
+/* vim: set ai sw=4 ts=4 : */
+
diff --git a/support/dktools/test-strmu.c b/support/dktools/test-strmu.c
new file mode 100644
index 0000000000..a16915a5c4
--- /dev/null
+++ b/support/dktools/test-strmu.c
@@ -0,0 +1,116 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-strmu.ctr
+*/
+
+/** @file test-strmu.c The test-strmu module.
+*/
+
+
+#line 1 "test-strmu.ctr"
+
+
+#include "dk4conf.h"
+
+#include "dk4mem.h"
+#include "dk4strmr.h"
+#include "dk4strmu.h"
+
+
+
+int main(void)
+{
+ dk4_er_t er;
+ dk4_stream_t *rdstrm = NULL;
+ char *cptr = NULL;
+ double d = 0.0;
+ uint32_t u32 = 0UL;
+ int32_t i32 = 0L;
+ uint16_t u16 = 0U;
+ int16_t i16 = 0;
+ uint8_t u8 = (uint8_t)0;
+ int8_t i8 = (int8_t)0;
+
+
+ rdstrm = dk4stream_open_file_reader("/tmp/test.dat.gz", NULL);
+ if (NULL == rdstrm) {
+ goto finished;
+ }
+
+ if (0 == dk4stream_unser_u32(&u32, rdstrm, NULL)) {
+ fputs("u32 failed!\n", stderr); fflush(stderr);
+ goto finished;
+ }
+ printf("u32 = %lu\n", (unsigned long)u32);
+
+ if (0 == dk4stream_unser_i32(&i32, rdstrm, NULL)) {
+ fputs("i32 failed!\n", stderr); fflush(stderr);
+ goto finished;
+ }
+ printf("i32 = %ld\n", (long)i32);
+
+ if (0 == dk4stream_unser_string(&cptr, rdstrm, NULL)) {
+ fputs("str failed!\n", stderr); fflush(stderr);
+ goto finished;
+ }
+ printf("str = \"%s\"\n", ((NULL != cptr) ? cptr : "NULL"));
+
+ if (0 == dk4stream_unser_u16(&u16, rdstrm, NULL)) {
+ fputs("u16 failed!\n", stderr); fflush(stderr);
+ goto finished;
+ }
+ printf("u16 = %u\n", (unsigned)u16);
+
+ if (0 == dk4stream_unser_double(&d, rdstrm, NULL)) {
+ fputs("dbl failed!\n", stderr); fflush(stderr);
+ goto finished;
+ }
+ printf("d = %g\n", d);
+
+ if (0 == dk4stream_unser_i16(&i16, rdstrm, NULL)) {
+ fputs("i16 failed!\n", stderr); fflush(stderr);
+ goto finished;
+ }
+ printf("i16 = %d\n", (int)i16);
+
+ d = 5.0;
+ if (0 == dk4stream_unser_double(&d, rdstrm, NULL)) {
+ fputs("dbl failed!\n", stderr); fflush(stderr);
+ goto finished;
+ }
+ printf("d = %g\n", d);
+
+ if (0 == dk4stream_unser_u8(&u8, rdstrm, NULL)) {
+ fputs("u8 failed!\n", stderr); fflush(stderr);
+ goto finished;
+ }
+ printf("u8 = %u\n", (unsigned)u8);
+
+ if (0 == dk4stream_unser_i8(&i8, rdstrm, NULL)) {
+ fputs("i8 failed!\n", stderr); fflush(stderr);
+ goto finished;
+ }
+ printf("i8 = %d\n", (int)i8);
+
+ dk4error_init(&er);
+ if (0 == dk4stream_unser_i8(&i8, rdstrm, &er)) {
+ fputs("i8 failed!\n", stderr); fflush(stderr);
+ fprintf(stderr, "Error code: %d\n", er.ec);
+ goto finished;
+ }
+ printf("i8 = %d\n", (int)i8);
+
+ finished:
+ if (NULL != cptr) {
+ dk4mem_free(cptr);
+ }
+ if (NULL != rdstrm) {
+ dk4stream_close(rdstrm, NULL);
+ }
+ return 0;
+}
+
+/* vim: set ai sw=4 ts=4 : */
+
diff --git a/support/dktools/test-strmu.ctr b/support/dktools/test-strmu.ctr
new file mode 100644
index 0000000000..3653cf6f6b
--- /dev/null
+++ b/support/dktools/test-strmu.ctr
@@ -0,0 +1,104 @@
+
+
+#include "dk4conf.h"
+
+#include "dk4mem.h"
+#include "dk4strmr.h"
+#include "dk4strmu.h"
+
+
+
+int main(void)
+{
+ dk4_er_t er;
+ dk4_stream_t *rdstrm = NULL;
+ char *cptr = NULL;
+ double d = 0.0;
+ uint32_t u32 = 0UL;
+ int32_t i32 = 0L;
+ uint16_t u16 = 0U;
+ int16_t i16 = 0;
+ uint8_t u8 = (uint8_t)0;
+ int8_t i8 = (int8_t)0;
+
+
+ rdstrm = dk4stream_open_file_reader("/tmp/test.dat.gz", NULL);
+ if (NULL == rdstrm) {
+ goto finished;
+ }
+
+ if (0 == dk4stream_unser_u32(&u32, rdstrm, NULL)) {
+ fputs("u32 failed!\n", stderr); fflush(stderr);
+ goto finished;
+ }
+ printf("u32 = %lu\n", (unsigned long)u32);
+
+ if (0 == dk4stream_unser_i32(&i32, rdstrm, NULL)) {
+ fputs("i32 failed!\n", stderr); fflush(stderr);
+ goto finished;
+ }
+ printf("i32 = %ld\n", (long)i32);
+
+ if (0 == dk4stream_unser_string(&cptr, rdstrm, NULL)) {
+ fputs("str failed!\n", stderr); fflush(stderr);
+ goto finished;
+ }
+ printf("str = \"%s\"\n", ((NULL != cptr) ? cptr : "NULL"));
+
+ if (0 == dk4stream_unser_u16(&u16, rdstrm, NULL)) {
+ fputs("u16 failed!\n", stderr); fflush(stderr);
+ goto finished;
+ }
+ printf("u16 = %u\n", (unsigned)u16);
+
+ if (0 == dk4stream_unser_double(&d, rdstrm, NULL)) {
+ fputs("dbl failed!\n", stderr); fflush(stderr);
+ goto finished;
+ }
+ printf("d = %g\n", d);
+
+ if (0 == dk4stream_unser_i16(&i16, rdstrm, NULL)) {
+ fputs("i16 failed!\n", stderr); fflush(stderr);
+ goto finished;
+ }
+ printf("i16 = %d\n", (int)i16);
+
+ d = 5.0;
+ if (0 == dk4stream_unser_double(&d, rdstrm, NULL)) {
+ fputs("dbl failed!\n", stderr); fflush(stderr);
+ goto finished;
+ }
+ printf("d = %g\n", d);
+
+ if (0 == dk4stream_unser_u8(&u8, rdstrm, NULL)) {
+ fputs("u8 failed!\n", stderr); fflush(stderr);
+ goto finished;
+ }
+ printf("u8 = %u\n", (unsigned)u8);
+
+ if (0 == dk4stream_unser_i8(&i8, rdstrm, NULL)) {
+ fputs("i8 failed!\n", stderr); fflush(stderr);
+ goto finished;
+ }
+ printf("i8 = %d\n", (int)i8);
+
+ dk4error_init(&er);
+ if (0 == dk4stream_unser_i8(&i8, rdstrm, &er)) {
+ fputs("i8 failed!\n", stderr); fflush(stderr);
+ fprintf(stderr, "Error code: %d\n", er.ec);
+ goto finished;
+ }
+ printf("i8 = %d\n", (int)i8);
+
+ finished:
+ if (NULL != cptr) {
+ dk4mem_free(cptr);
+ }
+ if (NULL != rdstrm) {
+ dk4stream_close(rdstrm, NULL);
+ }
+ return 0;
+}
+
+/* vim: set ai sw=4 ts=4 : */
+
diff --git a/support/dktools/test-strmw.c b/support/dktools/test-strmw.c
new file mode 100644
index 0000000000..955cfebac8
--- /dev/null
+++ b/support/dktools/test-strmw.c
@@ -0,0 +1,360 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-strmw.ctr
+*/
+
+/** @file test-strmw.c The test-strmw module.
+*/
+
+
+#line 1 "test-strmw.ctr"
+
+
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include "dk4strm.h"
+#include "dk4strmf.h"
+#include "dk4fopc8.h"
+#include "dk4strmw.h"
+
+
+
+
+
+#line 18 "test-strmw.ctr"
+
+
+
+/** License conditions.
+*/
+static const char * const test_text[] = {
+"This software uses code from the following projects, either directly or as",
+"a library:",
+"",
+"dktools\t\tDirk Krause's tools and libraries.",
+"\t\tSee http://dktools.sourceforge.net/ for more information.",
+#if DK4_HAVE_ZLIB_H
+"",
+"zlib\t\tData compression library.",
+"\t\tSee http://www.zlib.net/ for more information.",
+#endif
+#if DK4_HAVE_BZLIB_H
+"",
+"bzip2\t\tData compression program and library.",
+"\t\tSee http://www.bzip.org/ for more information.",
+#endif
+#if DK4_HAVE_OPENSSL_MD5_H && DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_OPENSSL_RIPEMD_H
+"",
+"OpenSSL\t\tCryptographic toolkit, used to build file checksums here.",
+"\t\tSee http://www.openssl.org/ for more information.",
+"",
+"This product includes software developed by the OpenSSL Project for use in",
+"the OpenSSL Toolkit (http://www.openssl.org/).",
+"This product includes cryptographic software written by",
+"Eric Young (eay@cryptsoft.com).",
+"This product includes software written by Tim Hudson (tjh@cryptsoft.com).",
+#endif
+"",
+"All the licenses below apply to the program.",
+"Licenses for used libraries are shown as found on my Scientific Linux 6.x",
+"computer in the /usr/share/doc directory on 2015-04-01. Check the project",
+"homepages of the used libraries for additional information and/or updated",
+"license terms.",
+"",
+"",
+"DK tools and libraries license",
+"==============================",
+"Copyright (c) 2015-2016, Dirk Krause",
+"All rights reserved.",
+"",
+"Redistribution and use in source and binary forms, with or without",
+"modification, are permitted provided that the following conditions are met:",
+"",
+"* Redistributions of source code must retain the above copyright notice,",
+" this list of conditions and the following disclaimer.",
+"* Redistributions in binary form must reproduce the above copyright",
+" notice, this list of conditions and the following disclaimer in the",
+" documentation and/or other materials provided with the distribution.",
+"* Neither the name of the Dirk Krause nor the names of contributors may be",
+" used to endorse or promote products derived from this software without",
+" specific prior written permission.",
+"",
+"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"",
+"AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE",
+"IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE",
+"ARE DISCLAIMED.",
+"",
+"IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,",
+"INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,",
+"BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,",
+"DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY",
+"OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING",
+"NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,",
+"EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.",
+#if DK4_HAVE_ZLIB_H
+"",
+"",
+"Zlib license",
+"============",
+"(C) 1995-2004 Jean-loup Gailly and Mark Adler",
+"",
+"This software is provided 'as-is', without any express or implied",
+"warranty. In no event will the authors be held liable for any damages",
+"arising from the use of this software.",
+"",
+"Permission is granted to anyone to use this software for any purpose,",
+"including commercial applications, and to alter it and redistribute it",
+"freely, subject to the following restrictions:",
+"",
+"1. The origin of this software must not be misrepresented; you must not",
+" claim that you wrote the original software. If you use this software",
+" in a product, an acknowledgment in the product documentation would be",
+" appreciated but is not required.",
+"2. Altered source versions must be plainly marked as such, and must not be",
+" misrepresented as being the original software.",
+"3. This notice may not be removed or altered from any source distribution.",
+"",
+"Jean-loup Gailly Mark Adler",
+"jloup@gzip.org madler@alumni.caltech.edu",
+#endif
+#if DK4_HAVE_BZLIB_H
+"",
+"",
+"Bzip2 and libbzip2 library license",
+"==================================",
+"This program, \"bzip2\", the associated library \"libbzip2\", and all",
+"documentation, are copyright (C) 1996-2007 Julian R Seward. All",
+"rights reserved.",
+"",
+"Redistribution and use in source and binary forms, with or without",
+"modification, are permitted provided that the following conditions",
+"are met:",
+"",
+"1. Redistributions of source code must retain the above copyright",
+" notice, this list of conditions and the following disclaimer.",
+"",
+"2. The origin of this software must not be misrepresented; you must ",
+" not claim that you wrote the original software. If you use this ",
+" software in a product, an acknowledgment in the product ",
+" documentation would be appreciated but is not required.",
+"",
+"3. Altered source versions must be plainly marked as such, and must",
+" not be misrepresented as being the original software.",
+"",
+"4. The name of the author may not be used to endorse or promote ",
+" products derived from this software without specific prior written ",
+" permission.",
+"",
+"THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS",
+"OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED",
+"WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE",
+"ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY",
+"DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL",
+"DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE",
+"GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS",
+"INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,",
+"WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING",
+"NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS",
+"SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.",
+"",
+"Julian Seward, jseward@bzip.org",
+"bzip2/libbzip2 version 1.0.5 of 10 December 2007",
+#endif
+#if DK4_HAVE_OPENSSL_MD5_H && DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_OPENSSL_RIPEMD_H
+"",
+"",
+"OpenSSL license",
+"===============",
+"",
+"LICENSE ISSUES",
+"--------------",
+"",
+"The OpenSSL toolkit stays under a dual license, i.e. both the conditions of",
+"the OpenSSL License and the original SSLeay license apply to the toolkit.",
+"See below for the actual license texts. Actually both licenses are BSD-style",
+"Open Source licenses. In case of any license issues related to OpenSSL",
+"please contact openssl-core@openssl.org.",
+"",
+"OpenSSL License",
+"---------------",
+"",
+"Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved.",
+"",
+"Redistribution and use in source and binary forms, with or without",
+"modification, are permitted provided that the following conditions",
+"are met:",
+"",
+"1. Redistributions of source code must retain the above copyright",
+" notice, this list of conditions and the following disclaimer. ",
+"",
+"2. Redistributions in binary form must reproduce the above copyright",
+" notice, this list of conditions and the following disclaimer in",
+" the documentation and/or other materials provided with the",
+" distribution.",
+"",
+"3. All advertising materials mentioning features or use of this",
+" software must display the following acknowledgment:",
+" \"This product includes software developed by the OpenSSL Project",
+" for use in the OpenSSL Toolkit. (http://www.openssl.org/)\"",
+"",
+"4. The names \"OpenSSL Toolkit\" and \"OpenSSL Project\" must not be used to",
+" endorse or promote products derived from this software without",
+" prior written permission. For written permission, please contact",
+" openssl-core@openssl.org.",
+"",
+"5. Products derived from this software may not be called \"OpenSSL\"",
+" nor may \"OpenSSL\" appear in their names without prior written",
+" permission of the OpenSSL Project.",
+"",
+"6. Redistributions of any form whatsoever must retain the following",
+" acknowledgment:",
+" \"This product includes software developed by the OpenSSL Project",
+" for use in the OpenSSL Toolkit (http://www.openssl.org/)\"",
+"",
+"THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY",
+"EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE",
+"IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR",
+"PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR",
+"ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,",
+"SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT",
+"NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;",
+"LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)",
+"HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,",
+"STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)",
+"ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED",
+"OF THE POSSIBILITY OF SUCH DAMAGE.",
+"",
+"This product includes cryptographic software written by Eric Young",
+"(eay@cryptsoft.com). This product includes software written by Tim",
+"Hudson (tjh@cryptsoft.com).",
+"",
+"",
+"Original SSLeay License",
+"-----------------------",
+"",
+"Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)",
+"All rights reserved.",
+"",
+"This package is an SSL implementation written",
+"by Eric Young (eay@cryptsoft.com).",
+"The implementation was written so as to conform with Netscapes SSL.",
+"",
+"This library is free for commercial and non-commercial use as long as",
+"the following conditions are aheared to. The following conditions",
+"apply to all code found in this distribution, be it the RC4, RSA,",
+"lhash, DES, etc., code; not just the SSL code. The SSL documentation",
+"included with this distribution is covered by the same copyright terms",
+"except that the holder is Tim Hudson (tjh@cryptsoft.com).",
+"",
+"Copyright remains Eric Young's, and as such any Copyright notices in",
+"the code are not to be removed.",
+"If this package is used in a product, Eric Young should be given attribution",
+"as the author of the parts of the library used.",
+"This can be in the form of a textual message at program startup or",
+"in documentation (online or textual) provided with the package.",
+"",
+"Redistribution and use in source and binary forms, with or without",
+"modification, are permitted provided that the following conditions",
+"are met:",
+"1. Redistributions of source code must retain the copyright",
+" notice, this list of conditions and the following disclaimer.",
+"2. Redistributions in binary form must reproduce the above copyright",
+" notice, this list of conditions and the following disclaimer in the",
+" documentation and/or other materials provided with the distribution.",
+"3. All advertising materials mentioning features or use of this software",
+" must display the following acknowledgement:",
+" \"This product includes cryptographic software written by",
+" Eric Young (eay@cryptsoft.com)\"",
+" The word 'cryptographic' can be left out if the rouines from the library",
+" being used are not cryptographic related :-).",
+"4. If you include any Windows specific code (or a derivative thereof) from ",
+" the apps directory (application code) you must include an acknowledgement:",
+" \"This product includes software written by Tim Hudson (tjh@cryptsoft.com)\"",
+"",
+"THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND",
+"ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE",
+"IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE",
+"ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE",
+"FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL",
+"DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS",
+"OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)",
+"HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT",
+"LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY",
+"OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF",
+"SUCH DAMAGE.",
+"",
+"The licence and distribution terms for any publically available version or",
+"derivative of this code cannot be changed. i.e. this code cannot simply be",
+"copied and put under another distribution licence",
+"[including the GNU Public Licence.]",
+"",
+#endif
+"",
+NULL
+
+
+#line 288 "test-strmw.ctr"
+};
+
+
+
+static const dkChar filename[] = { dkT("output.txt.gz") };
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ dk4_er_t er;
+ dk4_stream_t *ostrm;
+ const char * const *cptr;
+ size_t sl;
+ int exv = EXIT_FAILURE;
+
+
+
+#line 314 "test-strmw.ctr"
+
+
+#line 315 "test-strmw.ctr"
+ dk4error_init(&er);
+ ostrm = dk4stream_open_file_writer(filename, &er);
+ if (NULL != ostrm) {
+ exv = EXIT_SUCCESS;
+ cptr = test_text;
+ while (NULL != *cptr) {
+ sl = strlen(*cptr);
+ if (0 < sl) {
+ if (0 == dk4stream_write(ostrm, *cptr, sl, &er)) { exv = EXIT_FAILURE; }
+ if (0 == dk4stream_write_byte(ostrm, '\n', &er)) { exv = EXIT_FAILURE; }
+ }
+ cptr++;
+ }
+ if (0 == dk4stream_close(ostrm, &er)) { exv = EXIT_FAILURE; }
+ }
+
+
+#line 331 "test-strmw.ctr"
+
+
+#line 332 "test-strmw.ctr"
+ return exv;
+}
+
+
+
diff --git a/support/dktools/test-strmw.ctr b/support/dktools/test-strmw.ctr
new file mode 100644
index 0000000000..aa0dec6da9
--- /dev/null
+++ b/support/dktools/test-strmw.ctr
@@ -0,0 +1,336 @@
+
+
+
+#include "dk4conf.h"
+#include "dk4types.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include "dk4strm.h"
+#include "dk4strmf.h"
+#include "dk4fopc8.h"
+#include "dk4strmw.h"
+
+
+
+$!trace-include
+
+
+
+/** License conditions.
+*/
+static const char * const test_text[] = {
+$!text preprocessor
+This software uses code from the following projects, either directly or as
+a library:
+
+dktools Dirk Krause's tools and libraries.
+ See http://dktools.sourceforge.net/ for more information.
+#if DK4_HAVE_ZLIB_H
+
+zlib Data compression library.
+ See http://www.zlib.net/ for more information.
+#endif
+#if DK4_HAVE_BZLIB_H
+
+bzip2 Data compression program and library.
+ See http://www.bzip.org/ for more information.
+#endif
+#if DK4_HAVE_OPENSSL_MD5_H && DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_OPENSSL_RIPEMD_H
+
+OpenSSL Cryptographic toolkit, used to build file checksums here.
+ See http://www.openssl.org/ for more information.
+
+This product includes software developed by the OpenSSL Project for use in
+the OpenSSL Toolkit (http://www.openssl.org/).
+This product includes cryptographic software written by
+Eric Young (eay@cryptsoft.com).
+This product includes software written by Tim Hudson (tjh@cryptsoft.com).
+#endif
+
+All the licenses below apply to the program.
+Licenses for used libraries are shown as found on my Scientific Linux 6.x
+computer in the /usr/share/doc directory on 2015-04-01. Check the project
+homepages of the used libraries for additional information and/or updated
+license terms.
+
+
+DK tools and libraries license
+==============================
+Copyright (c) 2015-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#if DK4_HAVE_ZLIB_H
+
+
+Zlib license
+============
+(C) 1995-2004 Jean-loup Gailly and Mark Adler
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+
+Jean-loup Gailly Mark Adler
+jloup@gzip.org madler@alumni.caltech.edu
+#endif
+#if DK4_HAVE_BZLIB_H
+
+
+Bzip2 and libbzip2 library license
+==================================
+This program, "bzip2", the associated library "libbzip2", and all
+documentation, are copyright (C) 1996-2007 Julian R Seward. All
+rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+3. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Julian Seward, jseward@bzip.org
+bzip2/libbzip2 version 1.0.5 of 10 December 2007
+#endif
+#if DK4_HAVE_OPENSSL_MD5_H && DK4_HAVE_OPENSSL_SHA_H && DK4_HAVE_OPENSSL_RIPEMD_H
+
+
+OpenSSL license
+===============
+
+LICENSE ISSUES
+--------------
+
+The OpenSSL toolkit stays under a dual license, i.e. both the conditions of
+the OpenSSL License and the original SSLeay license apply to the toolkit.
+See below for the actual license texts. Actually both licenses are BSD-style
+Open Source licenses. In case of any license issues related to OpenSSL
+please contact openssl-core@openssl.org.
+
+OpenSSL License
+---------------
+
+Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+3. All advertising materials mentioning features or use of this
+ software must display the following acknowledgment:
+ "This product includes software developed by the OpenSSL Project
+ for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+
+4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ endorse or promote products derived from this software without
+ prior written permission. For written permission, please contact
+ openssl-core@openssl.org.
+
+5. Products derived from this software may not be called "OpenSSL"
+ nor may "OpenSSL" appear in their names without prior written
+ permission of the OpenSSL Project.
+
+6. Redistributions of any form whatsoever must retain the following
+ acknowledgment:
+ "This product includes software developed by the OpenSSL Project
+ for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+
+THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+OF THE POSSIBILITY OF SUCH DAMAGE.
+
+This product includes cryptographic software written by Eric Young
+(eay@cryptsoft.com). This product includes software written by Tim
+Hudson (tjh@cryptsoft.com).
+
+
+Original SSLeay License
+-----------------------
+
+Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+All rights reserved.
+
+This package is an SSL implementation written
+by Eric Young (eay@cryptsoft.com).
+The implementation was written so as to conform with Netscapes SSL.
+
+This library is free for commercial and non-commercial use as long as
+the following conditions are aheared to. The following conditions
+apply to all code found in this distribution, be it the RC4, RSA,
+lhash, DES, etc., code; not just the SSL code. The SSL documentation
+included with this distribution is covered by the same copyright terms
+except that the holder is Tim Hudson (tjh@cryptsoft.com).
+
+Copyright remains Eric Young's, and as such any Copyright notices in
+the code are not to be removed.
+If this package is used in a product, Eric Young should be given attribution
+as the author of the parts of the library used.
+This can be in the form of a textual message at program startup or
+in documentation (online or textual) provided with the package.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. All advertising materials mentioning features or use of this software
+ must display the following acknowledgement:
+ "This product includes cryptographic software written by
+ Eric Young (eay@cryptsoft.com)"
+ The word 'cryptographic' can be left out if the rouines from the library
+ being used are not cryptographic related :-).
+4. If you include any Windows specific code (or a derivative thereof) from
+ the apps directory (application code) you must include an acknowledgement:
+ "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+
+THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+The licence and distribution terms for any publically available version or
+derivative of this code cannot be changed. i.e. this code cannot simply be
+copied and put under another distribution licence
+[including the GNU Public Licence.]
+
+#endif
+
+$!end
+};
+
+
+
+static const dkChar filename[] = { dkT("output.txt.gz") };
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ dk4_er_t er;
+ dk4_stream_t *ostrm;
+ const char * const *cptr;
+ size_t sl;
+ int exv = EXIT_FAILURE;
+
+ $!trace-init test-strmw.deb
+ $? "+ main"
+ dk4error_init(&er);
+ ostrm = dk4stream_open_file_writer(filename, &er);
+ if (NULL != ostrm) {
+ exv = EXIT_SUCCESS;
+ cptr = test_text;
+ while (NULL != *cptr) {
+ sl = strlen(*cptr);
+ if (0 < sl) {
+ if (0 == dk4stream_write(ostrm, *cptr, sl, &er)) { exv = EXIT_FAILURE; }
+ if (0 == dk4stream_write_byte(ostrm, '\n', &er)) { exv = EXIT_FAILURE; }
+ }
+ cptr++;
+ }
+ if (0 == dk4stream_close(ostrm, &er)) { exv = EXIT_FAILURE; }
+ }
+ $? "- main %d", exv
+ $!trace-end
+ return exv;
+}
+
+
+
diff --git a/support/dktools/test-udpa.c b/support/dktools/test-udpa.c
new file mode 100644
index 0000000000..4292cde202
--- /dev/null
+++ b/support/dktools/test-udpa.c
@@ -0,0 +1,99 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-udpa.ctr
+*/
+
+/** @file test-udpa.c The test-udpa module.
+*/
+
+
+#line 1 "test-udpa.ctr"
+
+/*
+ test-udap hostname...
+
+ Test the dk4socket_c8_udp_addresses_numeric() function from the
+ dk4sock32 module.
+*/
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4sock.h"
+
+
+
+static
+void
+show_address(dk4_sockaddr_storage_t *addr)
+{
+ struct sockaddr *sa;
+ struct sockaddr_in *sa4;
+ struct sockaddr_in6 *sa6;
+ unsigned long ul;
+ unsigned short us;
+ size_t i;
+ unsigned char uc;
+
+ sa = (struct sockaddr *)addr;
+ sa4 = (struct sockaddr_in *)addr;
+ sa6 = (struct sockaddr_in6 *)addr;
+
+ switch (sa->sa_family) {
+ case AF_INET : {
+ ul = ntohl(sa4->sin_addr.s_addr);
+ us = ntohs(sa4->sin_port);
+ printf(
+ "IPv4 %lu.%lu.%lu.%lu %u\n",
+ ((ul >> 24) & 0x000000FFUL),
+ ((ul >> 16) & 0x000000FFUL),
+ ((ul >> 8) & 0x000000FFUL),
+ ((ul ) & 0x000000FFUL),
+ (unsigned)us
+ );
+ } break;
+ case AF_INET6 : {
+ us = ntohs(sa6->sin6_port);
+ printf("IPv6 ");
+ for (i = 0; i < 16; i++) {
+ uc = sa6->sin6_addr.s6_addr[i];
+ if ((0 < i) && (0 == (i % 2))) {
+ printf(":");
+ }
+ printf("%02X", uc);
+ }
+ printf(" %u\n", (unsigned short)us);
+ } break;
+ default: {
+ printf("ERROR: Unknown address family!\n");
+ } break;
+ }
+}
+
+
+
+int main(int argc, char *argv[])
+{
+ dk4_sockaddr_storage_t array[2];
+ int i;
+ int res;
+
+ for (i = 1; i < argc; i++) {
+ printf("Test \"%s\"\n", argv[i]);
+ res = dk4socket_c8_udp_addresses_numeric(
+ array, argv[i], 9876, 9876, 0, NULL
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ show_address(array);
+ show_address(&(array[1]));
+ } else {
+ printf("ERROR: Not found!\n");
+ }
+ printf("\n");
+ }
+ return 0;
+}
+
diff --git a/support/dktools/test-udpa.ctr b/support/dktools/test-udpa.ctr
new file mode 100644
index 0000000000..5127744015
--- /dev/null
+++ b/support/dktools/test-udpa.ctr
@@ -0,0 +1,87 @@
+
+/*
+ test-udap hostname...
+
+ Test the dk4socket_c8_udp_addresses_numeric() function from the
+ dk4sock32 module.
+*/
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#include "dk4sock.h"
+
+
+
+static
+void
+show_address(dk4_sockaddr_storage_t *addr)
+{
+ struct sockaddr *sa;
+ struct sockaddr_in *sa4;
+ struct sockaddr_in6 *sa6;
+ unsigned long ul;
+ unsigned short us;
+ size_t i;
+ unsigned char uc;
+
+ sa = (struct sockaddr *)addr;
+ sa4 = (struct sockaddr_in *)addr;
+ sa6 = (struct sockaddr_in6 *)addr;
+
+ switch (sa->sa_family) {
+ case AF_INET : {
+ ul = ntohl(sa4->sin_addr.s_addr);
+ us = ntohs(sa4->sin_port);
+ printf(
+ "IPv4 %lu.%lu.%lu.%lu %u\n",
+ ((ul >> 24) & 0x000000FFUL),
+ ((ul >> 16) & 0x000000FFUL),
+ ((ul >> 8) & 0x000000FFUL),
+ ((ul ) & 0x000000FFUL),
+ (unsigned)us
+ );
+ } break;
+ case AF_INET6 : {
+ us = ntohs(sa6->sin6_port);
+ printf("IPv6 ");
+ for (i = 0; i < 16; i++) {
+ uc = sa6->sin6_addr.s6_addr[i];
+ if ((0 < i) && (0 == (i % 2))) {
+ printf(":");
+ }
+ printf("%02X", uc);
+ }
+ printf(" %u\n", (unsigned short)us);
+ } break;
+ default: {
+ printf("ERROR: Unknown address family!\n");
+ } break;
+ }
+}
+
+
+
+int main(int argc, char *argv[])
+{
+ dk4_sockaddr_storage_t array[2];
+ int i;
+ int res;
+
+ for (i = 1; i < argc; i++) {
+ printf("Test \"%s\"\n", argv[i]);
+ res = dk4socket_c8_udp_addresses_numeric(
+ array, argv[i], 9876, 9876, 0, NULL
+ );
+ if (DK4_SOCKET_RESULT_SUCCESS == res) {
+ show_address(array);
+ show_address(&(array[1]));
+ } else {
+ printf("ERROR: Not found!\n");
+ }
+ printf("\n");
+ }
+ return 0;
+}
+
diff --git a/support/dktools/test-unser.c b/support/dktools/test-unser.c
new file mode 100644
index 0000000000..2e2a2950a6
--- /dev/null
+++ b/support/dktools/test-unser.c
@@ -0,0 +1,164 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: test-unser.ctr
+*/
+
+/** @file test-unser.c The test-unser module.
+*/
+
+
+#line 1 "test-unser.ctr"
+
+#include <stdio.h>
+#include <stdint.h>
+#define _USE_MATH_DEFINES 1
+#include <math.h>
+
+
+#include "dk4mem.h"
+#include "dk4serf.h"
+#include "dk4userf.h"
+#include "dk4app.h"
+#include "dk4str8.h"
+#include "dk4maodd.h"
+#include "dk4fput.h"
+
+
+
+static const dkChar * const test_ser_help_text[] = {
+dkT("This is a test program to create directories."),
+NULL
+
+
+#line 22 "test-unser.ctr"
+};
+
+static const dkChar * const test_ser_license_text[] = {
+dkT("Copyright (c) 2014-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions"),
+dkT("are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above copyright notice,"),
+dkT(" this list of conditions and the following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("* Neither the name of the Dirk Krause nor the names of contributors may be"),
+dkT(" used to endorse or promote products derived from this software without"),
+dkT(" specific prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS"),
+dkT("\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT"),
+dkT("LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR"),
+dkT("A PARTICULAR PURPOSE ARE DISCLAIMED."),
+dkT(""),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS"),
+dkT("OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)"),
+dkT("HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,"),
+dkT("STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN"),
+dkT("ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE"),
+dkT("POSSIBILITY OF SUCH DAMAGE."),
+NULL
+
+
+#line 56 "test-unser.ctr"
+};
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ dkChar buf[64];
+ dkChar *dkptr = NULL;
+ FILE *fipo;
+ size_t i;
+ double dbl;
+ uint32_t ui32;
+ int32_t i32;
+ int exv = EXIT_FAILURE;
+ int de = 0;
+ uint16_t ui16;
+ int16_t i16;
+
+ dk4fput_initialize_stdout();
+ app = dk4app_open_cmd(
+ argc, argv, NULL, 0,
+ dkT("dktools-4-test"), dkT("1.0.0"),
+ dkT("test-ser.txt"), test_ser_help_text,
+ test_ser_license_text
+ );
+ if (NULL != app) {
+ de = dk4app_get_encoding(app);
+ fipo = fopen("test-ser.out", "rb");
+ if (NULL != fipo) {
+ exv = EXIT_SUCCESS;
+ for (i = 0; i < 8; i++) {
+ if (0 != dk4unserialize_file_uint16_t(&ui16, fipo, NULL)) {
+ dk4ma_write_decimal_unsigned(buf, DK4_SIZEOF(buf,dkChar), (dk4_um_t)ui16, 0, NULL);
+ dk4fputs(buf, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ }
+ }
+ for (i = 0; i < 6; i++) {
+ if (0 != dk4unserialize_file_int16_t(&i16, fipo, NULL)) {
+ dk4ma_write_decimal_signed(buf, DK4_SIZEOF(buf,dkChar), (dk4_im_t)i16, 0, NULL);
+ dk4fputs(buf, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ }
+ }
+ if (0 != dk4unserialize_file_dk_string(&dkptr, de, fipo, NULL)) {
+ dk4fputs(dkptr, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ if (NULL != dkptr) { dk4mem_free(dkptr); dkptr = NULL; }
+ }
+ for (i = 0; i < 8; i++) {
+
+#line 120 "test-unser.ctr"
+ if (0 != dk4unserialize_file_uint32_t(&ui32, fipo, NULL)) {
+ dk4ma_write_decimal_unsigned(buf, DK4_SIZEOF(buf,dkChar), (dk4_um_t)ui32, 0, NULL);
+ dk4fputs(buf, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ }
+ }
+ for (i = 0; i < 6; i++) {
+ if (0 != dk4unserialize_file_int32_t(&i32, fipo, NULL)) {
+ dk4ma_write_decimal_signed(buf, DK4_SIZEOF(buf,dkChar), (dk4_im_t)i32, 0, NULL);
+ dk4fputs(buf, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ }
+ }
+ for (i = 0; i < 3; i++) {
+ if (0 != dk4unserialize_file_double(&dbl, fipo, NULL)) {
+ printf("%g\n", dbl);
+ }
+ }
+ fclose(fipo);
+ }
+ dk4app_close(app);
+ }
+ fflush(stdout);
+ dk4fput_cleanup_stdout();
+ return exv;
+}
+
diff --git a/support/dktools/test-unser.ctr b/support/dktools/test-unser.ctr
new file mode 100644
index 0000000000..8a68d1a49e
--- /dev/null
+++ b/support/dktools/test-unser.ctr
@@ -0,0 +1,146 @@
+
+#include <stdio.h>
+#include <stdint.h>
+#define _USE_MATH_DEFINES 1
+#include <math.h>
+
+
+#include "dk4mem.h"
+#include "dk4serf.h"
+#include "dk4userf.h"
+#include "dk4app.h"
+#include "dk4str8.h"
+#include "dk4maodd.h"
+#include "dk4fput.h"
+
+
+
+static const dkChar * const test_ser_help_text[] = {
+$!text macro=dkT
+This is a test program to create directories.
+$!end
+};
+
+static const dkChar * const test_ser_license_text[] = {
+$!text macro=dkT
+Copyright (c) 2014-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+$!end
+};
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ dkChar buf[64];
+ dkChar *dkptr = NULL;
+ FILE *fipo;
+ size_t i;
+ double dbl;
+ uint32_t ui32;
+ int32_t i32;
+ int exv = EXIT_FAILURE;
+ int de = 0;
+ uint16_t ui16;
+ int16_t i16;
+
+ dk4fput_initialize_stdout();
+ app = dk4app_open_cmd(
+ argc, argv, NULL, 0,
+ dkT("dktools-4-test"), dkT("1.0.0"),
+ dkT("test-ser.txt"), test_ser_help_text,
+ test_ser_license_text
+ );
+ if (NULL != app) {
+ de = dk4app_get_encoding(app);
+ fipo = fopen("test-ser.out", "rb");
+ if (NULL != fipo) {
+ exv = EXIT_SUCCESS;
+ for (i = 0; i < 8; i++) {
+ if (0 != dk4unserialize_file_uint16_t(&ui16, fipo, NULL)) {
+ dk4ma_write_decimal_unsigned(buf, DK4_SIZEOF(buf,dkChar), (dk4_um_t)ui16, 0, NULL);
+ dk4fputs(buf, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ }
+ }
+ for (i = 0; i < 6; i++) {
+ if (0 != dk4unserialize_file_int16_t(&i16, fipo, NULL)) {
+ dk4ma_write_decimal_signed(buf, DK4_SIZEOF(buf,dkChar), (dk4_im_t)i16, 0, NULL);
+ dk4fputs(buf, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ }
+ }
+ if (0 != dk4unserialize_file_dk_string(&dkptr, de, fipo, NULL)) {
+ dk4fputs(dkptr, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ if (NULL != dkptr) { dk4mem_free(dkptr); dkptr = NULL; }
+ }
+ for (i = 0; i < 8; i++) { $? ". loop pass %u", (unsigned)i
+ if (0 != dk4unserialize_file_uint32_t(&ui32, fipo, NULL)) {
+ dk4ma_write_decimal_unsigned(buf, DK4_SIZEOF(buf,dkChar), (dk4_um_t)ui32, 0, NULL);
+ dk4fputs(buf, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ }
+ }
+ for (i = 0; i < 6; i++) {
+ if (0 != dk4unserialize_file_int32_t(&i32, fipo, NULL)) {
+ dk4ma_write_decimal_signed(buf, DK4_SIZEOF(buf,dkChar), (dk4_im_t)i32, 0, NULL);
+ dk4fputs(buf, stdout, NULL);
+ dk4fputc(dkT('\n'), stdout, NULL);
+ }
+ }
+ for (i = 0; i < 3; i++) {
+ if (0 != dk4unserialize_file_double(&dbl, fipo, NULL)) {
+ printf("%g\n", dbl);
+ }
+ }
+ fclose(fipo);
+ }
+ dk4app_close(app);
+ }
+ fflush(stdout);
+ dk4fput_cleanup_stdout();
+ return exv;
+}
+
diff --git a/support/dktools/testlzw.c b/support/dktools/testlzw.c
new file mode 100644
index 0000000000..7d28b3b913
--- /dev/null
+++ b/support/dktools/testlzw.c
@@ -0,0 +1,109 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: testlzw.ctr
+*/
+
+/** @file testlzw.c The testlzw module.
+*/
+
+
+#line 1 "testlzw.ctr"
+
+#include <stdio.h>
+
+#include <dk4conf.h>
+#include "dk4lzwe.h"
+#include <dk4edstm.h>
+
+
+
+#line 9 "testlzw.ctr"
+
+
+static const unsigned char teststr[] = {
+ 45, 45, 45, 45, 45, 65, 45, 45, 45, 66
+};
+
+
+
+static
+void
+show_bytes(dk4_lzwe_t *lzwe)
+{
+ const unsigned char *cptr = NULL;
+ size_t nbt = 0;
+ size_t i;
+
+
+
+#line 26 "testlzw.ctr"
+ if (0 != dk4lzwe_output(&cptr, &nbt, lzwe, NULL)) {
+ if ((NULL != cptr) && (0 < nbt)) {
+ for (i = 0; i < nbt; i++) {
+ printf("%2x\n", (unsigned)(cptr[i]));
+ }
+ }
+ else {
+
+#line 33 "testlzw.ctr"
+ }
+ }
+ else {
+
+#line 36 "testlzw.ctr"
+ }
+
+
+#line 38 "testlzw.ctr"
+}
+
+
+
+int main(int argc, char *argv[])
+{
+ dk4_lzwe_t lzwe;
+ size_t i;
+
+
+
+#line 48 "testlzw.ctr"
+
+
+#line 49 "testlzw.ctr"
+ if (0 != dk4lzwe_init(&lzwe, NULL)) {
+ for (i = 0; i < sizeof(teststr); i++) {
+ switch (dk4lzwe_add(&lzwe, teststr[i], NULL)) {
+ case DK4_EDSTM_FINISHED : {
+ show_bytes(&lzwe);
+ } break;
+ case DK4_EDSTM_ERROR : {
+
+#line 56 "testlzw.ctr"
+ } break;
+ }
+ }
+ switch (dk4lzwe_finish(&lzwe, NULL)) {
+ case DK4_EDSTM_FINISHED : {
+ show_bytes(&lzwe);
+ } break;
+ case DK4_EDSTM_ERROR : {
+
+#line 64 "testlzw.ctr"
+ } break;
+ }
+ }
+ else {
+ }
+
+
+#line 70 "testlzw.ctr"
+
+
+#line 71 "testlzw.ctr"
+ return 0;
+}
+
+/* vim: set ai sw=4 ts=4 : */
+
diff --git a/support/dktools/testlzw.ctr b/support/dktools/testlzw.ctr
new file mode 100644
index 0000000000..037e0234b5
--- /dev/null
+++ b/support/dktools/testlzw.ctr
@@ -0,0 +1,75 @@
+
+#include <stdio.h>
+
+#include <dk4conf.h>
+#include "dk4lzwe.h"
+#include <dk4edstm.h>
+
+$!trace-include
+
+
+static const unsigned char teststr[] = {
+ 45, 45, 45, 45, 45, 65, 45, 45, 45, 66
+};
+
+
+
+static
+void
+show_bytes(dk4_lzwe_t *lzwe)
+{
+ const unsigned char *cptr = NULL;
+ size_t nbt = 0;
+ size_t i;
+
+ $? "+ show_bytes"
+ if (0 != dk4lzwe_output(&cptr, &nbt, lzwe, NULL)) {
+ if ((NULL != cptr) && (0 < nbt)) {
+ for (i = 0; i < nbt; i++) {
+ printf("%2x\n", (unsigned)(cptr[i]));
+ }
+ }
+ else { $? "! bug"
+ }
+ }
+ else { $? "! error"
+ }
+ $? "- show_bytes"
+}
+
+
+
+int main(int argc, char *argv[])
+{
+ dk4_lzwe_t lzwe;
+ size_t i;
+
+ $!trace-init testlzwe.deb
+ $? "+ main"
+ if (0 != dk4lzwe_init(&lzwe, NULL)) {
+ for (i = 0; i < sizeof(teststr); i++) {
+ switch (dk4lzwe_add(&lzwe, teststr[i], NULL)) {
+ case DK4_EDSTM_FINISHED : {
+ show_bytes(&lzwe);
+ } break;
+ case DK4_EDSTM_ERROR : { $? "! error indicated"
+ } break;
+ }
+ }
+ switch (dk4lzwe_finish(&lzwe, NULL)) {
+ case DK4_EDSTM_FINISHED : {
+ show_bytes(&lzwe);
+ } break;
+ case DK4_EDSTM_ERROR : { $? "! error indicated"
+ } break;
+ }
+ }
+ else {
+ }
+ $? "- main"
+ $!trace-end
+ return 0;
+}
+
+/* vim: set ai sw=4 ts=4 : */
+
diff --git a/support/dktools/testlzws.c b/support/dktools/testlzws.c
new file mode 100644
index 0000000000..39a05948f6
--- /dev/null
+++ b/support/dktools/testlzws.c
@@ -0,0 +1,73 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: testlzws.ctr
+*/
+
+/** @file testlzws.c The testlzws module.
+*/
+
+
+#line 1 "testlzws.ctr"
+
+#include <stdio.h>
+
+#include "dk4conf.h"
+#include "dk4lzwe.h"
+#include "dk4edstm.h"
+#include "dk4strmf.h"
+#include "dk4strmco.h"
+
+
+
+#line 11 "testlzws.ctr"
+
+
+static const unsigned char teststr[] = {
+ 45, 45, 45, 45, 45, 65, 45, 45, 45, 66
+};
+
+
+
+int main(int argc, char *argv[])
+{
+ dk4_stream_t *strm_stdout;
+ dk4_stream_t *strm_lzw;
+
+
+
+#line 25 "testlzws.ctr"
+
+
+#line 26 "testlzws.ctr"
+ strm_stdout = dk4stream_open_for_file(
+ stdout, DK4_STREAM_WRITE, 0, 4096, NULL
+ );
+ if (NULL != strm_stdout) {
+ strm_lzw = dk4strmco_open(
+ strm_stdout,
+ DK4_STRMCO_PP_NONE, DK4_STRMCO_CO_LZW, DK4_STRMCO_OE_HEX,
+ (DK4_STRMCO_FL_EOD_OE | DK4_STRMCO_FL_NL_OE), NULL
+ );
+ if (NULL != strm_lzw) {
+ dk4stream_write(
+ strm_lzw, teststr, sizeof(teststr), NULL
+ );
+ dk4stream_close(strm_lzw, NULL);
+ }
+ dk4stream_close(strm_stdout, NULL);
+ }
+
+
+#line 44 "testlzws.ctr"
+
+
+#line 45 "testlzws.ctr"
+ return 0;
+}
+
+
+
+/* vim: set ai sw=4 ts=4 : */
+
diff --git a/support/dktools/testlzws.ctr b/support/dktools/testlzws.ctr
new file mode 100644
index 0000000000..d4849a7626
--- /dev/null
+++ b/support/dktools/testlzws.ctr
@@ -0,0 +1,51 @@
+
+#include <stdio.h>
+
+#include "dk4conf.h"
+#include "dk4lzwe.h"
+#include "dk4edstm.h"
+#include "dk4strmf.h"
+#include "dk4strmco.h"
+
+$!trace-include
+
+
+static const unsigned char teststr[] = {
+ 45, 45, 45, 45, 45, 65, 45, 45, 45, 66
+};
+
+
+
+int main(int argc, char *argv[])
+{
+ dk4_stream_t *strm_stdout;
+ dk4_stream_t *strm_lzw;
+
+ $!trace-init testlzws.deb
+ $? "+ main"
+ strm_stdout = dk4stream_open_for_file(
+ stdout, DK4_STREAM_WRITE, 0, 4096, NULL
+ );
+ if (NULL != strm_stdout) {
+ strm_lzw = dk4strmco_open(
+ strm_stdout,
+ DK4_STRMCO_PP_NONE, DK4_STRMCO_CO_LZW, DK4_STRMCO_OE_HEX,
+ (DK4_STRMCO_FL_EOD_OE | DK4_STRMCO_FL_NL_OE), NULL
+ );
+ if (NULL != strm_lzw) {
+ dk4stream_write(
+ strm_lzw, teststr, sizeof(teststr), NULL
+ );
+ dk4stream_close(strm_lzw, NULL);
+ }
+ dk4stream_close(strm_stdout, NULL);
+ }
+ $? "- main"
+ $!trace-end
+ return 0;
+}
+
+
+
+/* vim: set ai sw=4 ts=4 : */
+
diff --git a/support/dktools/translate-wxcs.pl b/support/dktools/translate-wxcs.pl
new file mode 100755
index 0000000000..9c1b307e8c
--- /dev/null
+++ b/support/dktools/translate-wxcs.pl
@@ -0,0 +1,6 @@
+while(<>) {
+ $line = $_;
+ chomp($line);
+ $line =~ s/DK4/DK3/g;
+ print "$line\n";
+}
diff --git a/support/dktools/translate.vc b/support/dktools/translate.vc
new file mode 100644
index 0000000000..57e21f8847
--- /dev/null
+++ b/support/dktools/translate.vc
@@ -0,0 +1,675 @@
+
+# Program Files (x86) directory
+
+!IF $(CONF_BITS) == 64
+PROGRAMSX86=$(CONF_PROGRAMS) (x86)
+WXVCLIB=vc_amd64_lib
+!ELSE
+PROGRAMSX86=$(CONF_PROGRAMS)
+WXVCLIB=vc_lib
+!ENDIF
+
+
+
+# VC: Directory where Visual Studio resides
+
+!IF "$(CONF_VSTUDIO)" == "2013"
+
+VC=$(PROGRAMSX86)\Microsoft Visual Studio 12.0\VC
+LINKMANIFEST= /MANIFEST
+CFLCRT=-D_CRT_SECURE_NO_WARNINGS=1 -D_CRT_SECURE_NO_DEPRECATE=1 \
+ -DNDEBUG=1 -D_CONSOLE=1
+
+!ELSEIF "$(CONF_VSTUDIO)" == "2012"
+
+VC=$(PROGRAMSX86)\Microsoft Visual Studio 11.0\VC
+LINKMANIFEST= /MANIFEST
+CFLCRT=-D_CRT_SECURE_NO_WARNINGS=1 -D_CRT_SECURE_NO_DEPRECATE=1 \
+ -DNDEBUG=1 -D_CONSOLE=1
+
+!ELSEIF "$(CONF_VSTUDIO)" == "2008"
+
+VC=$(PROGRAMSX86)\Microsoft Visual Studio 9.0\VC
+LINKMANIFEST= /MANIFEST
+CFLCRT=-D_CRT_SECURE_NO_WARNINGS=1 -D_CRT_SECURE_NO_DEPRECATE=1 \
+ -DNDEBUG=1 -D_CONSOLE=1
+
+!ELSEIF "$(CONF_VSTUDIO)" == "2005"
+
+VC=$(CONF_PROGRAMS)\Microsoft Visual Studio 8\VC
+LINKMANIFEST=
+CFLCRT=-DNDEBUG=1 -D_CONSOLE=1
+
+!ELSEIF "$(CONF_VSTUDIO)" == "2003"
+
+VC=$(CONF_PROGRAMS)\Microsoft Visual Studio .NET 2003\Vc7
+LINKMANIFEST=
+CFLCRT=-DNDEBUG=1 -D_CONSOLE=1
+
+!ELSEIF "$(CONF_VSTUDIO)" == "6"
+
+VC=$(CONF_PROGRAMS)\Microsoft Visual Studio\Vc98
+LINKMANIFEST=
+CFLCRT=-DNDEBUG=1 -D_CONSOLE=1
+
+!ELSE
+
+VC=$(CONF_PROGRAMS)\DevStudio\Vc
+LINKMANIFEST=
+CFLCRT=-DNDEBUG=1 -D_CONSOLE=1
+
+!ENDIF
+
+
+
+# Check for legacy versions
+
+!IF "$(CONF_LEGACY)" == "yes"
+CFLAGSLEGACY=/DDK4_WINDOWS_LEGACY=1
+!ELSE
+CFLAGSLEGACY=
+!ENDIF
+
+
+
+# PSDK: Directory for Platform SDK
+
+!IF "$(CONF_PSDK)" == "8.1"
+
+PSDK=$(PROGRAMSX86)\Windows Kits\8.1
+
+!ELSEIF "$(CONF_PSDK)" == "8"
+
+PSDK=$(PROGRAMSX86)\Windows Kits\8.0
+
+!ELSEIF "$(CONF_PSDK)" == "7"
+
+PSDK=$(CONF_PROGRAMS)\Microsoft SDKs\Windows\v7.0
+
+!ELSE
+
+PSDK=$(VC)
+
+!ENDIF
+
+
+
+# CFLUC: CFLAGS related to UNICODE
+
+!IF "$(CONF_UNICODE)" == "1"
+CFLUC= /D_UNICODE=1 /DUNICODE=1 /DTRACE_WIDE=1
+!ELSE
+CFLUC=
+!ENDIF
+
+
+
+# CFLRT: CFLAGS for runtime selection
+
+!IF "$(CONF_MSVCRT_THREADED)" == "1"
+!IF "$(CONF_MSVCRT_DLL)" == "1"
+!IF "$(CONF_MSVCRT_DEBUG)" == "1"
+CFLRT= /MDd
+EXEFLREL= /debug
+!ELSE
+CFLRT= /MD
+EXEFLREL= /release
+!ENDIF
+!ELSE
+!IF "$(CONF_MSVCRT_DEBUG)" == "1"
+CFLRT= /MTD
+EXEFLREL= /debug
+!ELSE
+CFLRT= /MT
+EXEFLREL= /release
+!ENDIF
+!ENDIF
+!ELSE
+!IF "$(CONF_MSVCRT_DEBUG)" == "1"
+CFLRT= /MLd
+EXEFLREL= /debug
+!ELSE
+CFLRT= /ML
+EXEFLREL= /release
+!ENDIF
+!ENDIF
+
+
+
+CFLWX= /I"$(CONF_WX_DIR)\lib\$(WXVCLIB)\mswu" \
+ /I"$(CONF_WX_DIR)\include\msvc" \
+ /I"$(CONF_WX_DIR)\include" \
+ -DDK3_USE_WX=1 \
+ /EHsc /GF /Gy /fp:precise
+
+LFLWX= /LIBPATH:"$(CONF_WX_DIR)\lib\$(WXVCLIB)" \
+ /LIBPATH:"$(CONF_WX_DIR)\lib"
+
+
+# Programs
+CC=CL
+RC=RC
+LD=LINK
+LIB=LIB
+
+# Library path to build command line executables
+
+!IF $(CONF_BITS) == 64
+# 64 bit start
+
+!IF "$(CONF_PSDK)" == "8.1"
+
+EXEDLPATH= \
+ /LIBPATH:"$(PSDK)\Lib\winv6.3\um\x64" \
+ /LIBPATH:"$(PSDK)\Lib\winv6.3\um\x86" \
+ /LIBPATH:"$(VC)\LIB\AMD64" \
+ /LIBPATH:"$(VC)\LIB"
+
+!ELSEIF "$(CONF_PSDK)" == "8"
+
+EXEDLPATH= \
+ /LIBPATH:"$(PSDK)\Lib\win8\um\x64" \
+ /LIBPATH:"$(PSDK)\Lib\win8\um\x86" \
+ /LIBPATH:"$(VC)\LIB\AMD64" \
+ /LIBPATH:"$(VC)\LIB"
+
+!ELSEIF "$(CONF_PSDK)" == "7"
+
+EXEDLPATH= \
+ /LIBPATH:"$(PSDK)\Lib\x64" \
+ /LIBPATH:"$(PSDK)\Lib" \
+ /LIBPATH:"$(VC)\LIB\AMD64" \
+ /LIBPATH:"$(VC)\LIB"
+
+!ELSE
+
+EXEDLPATH= \
+ /LIBPATH:"$(VC)\LIB\AMD64" \
+ /LIBPATH:"$(VC)\LIB"
+
+!ENDIF
+
+# 64 biit end
+!ELSE
+# 32 bit start
+
+!IF "$(CONF_PSDK)" == "8.1"
+
+EXEDLPATH= \
+ /LIBPATH:"$(PSDK)\Lib\winv6.3\um\x86" \
+ /LIBPATH:"$(VC)\LIB" \
+ /LIBPATH:"$(LIBSRC)\LIB"
+
+!ELSEIF "$(CONF_PSDK)" == "8"
+
+EXEDLPATH= \
+ /LIBPATH:"$(PSDK)\Lib\win8\um\x86" \
+ /LIBPATH:"$(VC)\LIB"
+
+!ELSEIF "$(CONF_PSDK)" == "7"
+
+EXEDLPATH= \
+ /LIBPATH:"$(PSDK)\Lib" \
+ /LIBPATH:"$(VC)\LIB"
+
+!ELSE
+
+EXEDLPATH= /LIBPATH:"$(VC)\LIB"
+
+!ENDIF
+# 32 bit end
+!ENDIF
+
+
+
+# Popular libraries
+!IF "$(CONF_ZLIB_AVAILABLE)" == "1"
+P01D= $(CONF_ZLIB_DEF)
+P01I= $(CONF_ZLIB_INCLUDE)
+P01L= $(CONF_ZLIB_LIBDIR)
+P01F= $(CONF_ZLIB_LIBFILE)
+!ELSE
+P01D=
+P01I=
+P01L=
+P01F=
+!ENDIF
+
+!IF "$(CONF_BZIP2_AVAILABLE)" == "1"
+P02D= $(CONF_BZIP2_DEF)
+P02I= $(CONF_BZIP2_INCLUDE)
+P02L= $(CONF_BZIP2_LIBDIR)
+P02F= $(CONF_BZIP2_LIBFILE)
+!ELSE
+P02D=
+P02I=
+P02L=
+P02F=
+!ENDIF
+
+!IF "$(CONF_PNG_AVAILABLE)" == "1"
+P03D= $(CONF_PNG_DEF)
+P03I= $(CONF_PNG_INCLUDE)
+P03L= $(CONF_PNG_LIBDIR)
+P03F= $(CONF_PNG_LIBFILE)
+!ELSE
+P03D=
+P03I=
+P03L=
+P03F=
+!ENDIF
+
+!IF "$(CONF_JPG_AVAILABLE)" == "1"
+P04D= $(CONF_JPG_DEF)
+P04I= $(CONF_JPG_INCLUDE)
+P04L= $(CONF_JPG_LIBDIR)
+P04F= $(CONF_JPG_LIBFILE)
+!ELSE
+P04D=
+P04I=
+P04L=
+P04F=
+!ENDIF
+
+!IF "$(CONF_TIFF_AVAILABLE)" == "1"
+P05D= $(CONF_TIFF_DEF)
+P05I= $(CONF_TIFF_INCLUDE)
+P05L= $(CONF_TIFF_LIBDIR)
+P05F= $(CONF_TIFF_LIBFILE)
+!ELSE
+P05D=
+P05I=
+P05L=
+P05F=
+!ENDIF
+
+!IF "$(CONF_OPENSSL_AVAILABLE)" == "1"
+P06D= $(CONF_OPENSSL_DEF)
+P06I= $(CONF_OPENSSL_INCLUDE)
+P06L= $(CONF_OPENSSL_LIBDIR)
+P06F= $(CONF_OPENSSL_LIBFILE)
+!ELSE
+P06D=
+P06I=
+P06L=
+P06F=
+!ENDIF
+
+!IF "$(CONF_NETSNMP_AVAILABLE)" == "1"
+P07D= $(CONF_NETSNMP_DEF)
+P07I= $(CONF_NETSNMP_INCLUDE)
+P07L= $(CONF_NETSNMP_LIBDIR)
+P07F= $(CONF_NETSNMP_LIBFILE)
+!ELSE
+P07D=
+P07I=
+P07L=
+P07F=
+!ENDIF
+
+!IF "$(CONF_WX_AVAILABLE)" == "1"
+P08D= $(CONF_WX_DEF)
+P08I= $(CONF_WX_INCLUDE)
+P08L= $(CONF_WX_LIBDIR)
+P08F= $(CONF_WX_LIBFILE)
+!ELSE
+P08D=
+P08I=
+P08L=
+P08F=
+!ENDIF
+
+!IF "$(CONF_L01_AVAILABLE)" == "1"
+L01D= $(CONF_L01_DEF)
+L01I= $(CONF_L01_INCLUDE)
+L01L= $(CONF_L01_LIBDIR)
+L01F= $(CONF_L01_LIBFILE)
+!ELSE
+L01D=
+L01I=
+L01L=
+L01F=
+!ENDIF
+
+!IF "$(CONF_L02_AVAILABLE)" == "1"
+L02D= $(CONF_L02_DEF)
+L02I= $(CONF_L02_INCLUDE)
+L02L= $(CONF_L02_LIBDIR)
+L02F= $(CONF_L02_LIBFILE)
+!ELSE
+L02D=
+L02I=
+L02L=
+L02F=
+!ENDIF
+
+!IF "$(CONF_L03_AVAILABLE)" == "1"
+L03D= $(CONF_L03_DEF)
+L03I= $(CONF_L03_INCLUDE)
+L03L= $(CONF_L03_LIBDIR)
+L03F= $(CONF_L03_LIBFILE)
+!ELSE
+L03D=
+L03I=
+L03L=
+L03F=
+!ENDIF
+
+!IF "$(CONF_L04_AVAILABLE)" == "1"
+L04D= $(CONF_L04_DEF)
+L04I= $(CONF_L04_INCLUDE)
+L04L= $(CONF_L04_LIBDIR)
+L04F= $(CONF_L04_LIBFILE)
+!ELSE
+L04D=
+L04I=
+L04L=
+L04F=
+!ENDIF
+
+!IF "$(CONF_L05_AVAILABLE)" == "1"
+L05D= $(CONF_L05_DEF)
+L05I= $(CONF_L05_INCLUDE)
+L05L= $(CONF_L05_LIBDIR)
+L05F= $(CONF_L05_LIBFILE)
+!ELSE
+L05D=
+L05I=
+L05L=
+L05F=
+!ENDIF
+
+!IF "$(CONF_L06_AVAILABLE)" == "1"
+L06D= $(CONF_L06_DEF)
+L06I= $(CONF_L06_INCLUDE)
+L06L= $(CONF_L06_LIBDIR)
+L06F= $(CONF_L06_LIBFILE)
+!ELSE
+L06D=
+L06I=
+L06L=
+L06F=
+!ENDIF
+
+!IF "$(CONF_L07_AVAILABLE)" == "1"
+L07D= $(CONF_L07_DEF)
+L07I= $(CONF_L07_INCLUDE)
+L07L= $(CONF_L07_LIBDIR)
+L07F= $(CONF_L07_LIBFILE)
+!ELSE
+L07D=
+L07I=
+L07L=
+L07F=
+!ENDIF
+
+!IF "$(CONF_L08_AVAILABLE)" == "1"
+L08D= $(CONF_L08_DEF)
+L08I= $(CONF_L08_INCLUDE)
+L08L= $(CONF_L08_LIBDIR)
+L08F= $(CONF_L08_LIBFILE)
+!ELSE
+L08D=
+L08I=
+L08L=
+L08F=
+!ENDIF
+
+!IF "$(CONF_L09_AVAILABLE)" == "1"
+L09D= $(CONF_L09_DEF)
+L09I= $(CONF_L09_INCLUDE)
+L09L= $(CONF_L09_LIBDIR)
+L09F= $(CONF_L09_LIBFILE)
+!ELSE
+L09D=
+L09I=
+L09L=
+L09F=
+!ENDIF
+
+!IF "$(CONF_L10_AVAILABLE)" == "1"
+L10D= $(CONF_L10_DEF)
+L10I= $(CONF_L10_INCLUDE)
+L10L= $(CONF_L10_LIBDIR)
+L10F= $(CONF_L10_LIBFILE)
+!ELSE
+L10D=
+L10I=
+L10L=
+L10F=
+!ENDIF
+
+!IF "$(CONF_L11_AVAILABLE)" == "1"
+L11D= $(CONF_L11_DEF)
+L11I= $(CONF_L11_INCLUDE)
+L11L= $(CONF_L11_LIBDIR)
+L11F= $(CONF_L11_LIBFILE)
+!ELSE
+L11D=
+L11I=
+L11L=
+L11F=
+!ENDIF
+
+!IF "$(CONF_L12_AVAILABLE)" == "1"
+L12D= $(CONF_L12_DEF)
+L12I= $(CONF_L12_INCLUDE)
+L12L= $(CONF_L12_LIBDIR)
+L12F= $(CONF_L12_LIBFILE)
+!ELSE
+L12D=
+L12I=
+L12L=
+L12F=
+!ENDIF
+
+!IF "$(CONF_L13_AVAILABLE)" == "1"
+L13D= $(CONF_L13_DEF)
+L13I= $(CONF_L13_INCLUDE)
+L13L= $(CONF_L13_LIBDIR)
+L13F= $(CONF_L13_LIBFILE)
+!ELSE
+L13D=
+L13I=
+L13L=
+L13F=
+!ENDIF
+
+!IF "$(CONF_L14_AVAILABLE)" == "1"
+L14D= $(CONF_L14_DEF)
+L14I= $(CONF_L14_INCLUDE)
+L14L= $(CONF_L14_LIBDIR)
+L14F= $(CONF_L14_LIBFILE)
+!ELSE
+L14D=
+L14I=
+L14L=
+L14F=
+!ENDIF
+
+!IF "$(CONF_L15_AVAILABLE)" == "1"
+L15D= $(CONF_L15_DEF)
+L15I= $(CONF_L15_INCLUDE)
+L15L= $(CONF_L15_LIBDIR)
+L15F= $(CONF_L15_LIBFILE)
+!ELSE
+L15D=
+L15I=
+L15L=
+L15F=
+!ENDIF
+
+!IF "$(CONF_L16_AVAILABLE)" == "1"
+L16D= $(CONF_L16_DEF)
+L16I= $(CONF_L16_INCLUDE)
+L16L= $(CONF_L16_LIBDIR)
+L16F= $(CONF_L16_LIBFILE)
+!ELSE
+L16D=
+L16I=
+L16L=
+L16F=
+!ENDIF
+
+!IF "$(CONF_L17_AVAILABLE)" == "1"
+L17D= $(CONF_L17_DEF)
+L17I= $(CONF_L17_INCLUDE)
+L17L= $(CONF_L17_LIBDIR)
+L17F= $(CONF_L17_LIBFILE)
+!ELSE
+L17D=
+L17I=
+L17L=
+L17F=
+!ENDIF
+
+!IF "$(CONF_L18_AVAILABLE)" == "1"
+L18D= $(CONF_L18_DEF)
+L18I= $(CONF_L18_INCLUDE)
+L18L= $(CONF_L18_LIBDIR)
+L18F= $(CONF_L18_LIBFILE)
+!ELSE
+L18D=
+L18I=
+L18L=
+L18F=
+!ENDIF
+
+!IF "$(CONF_L19_AVAILABLE)" == "1"
+L19D= $(CONF_L19_DEF)
+L19I= $(CONF_L19_INCLUDE)
+L19L= $(CONF_L19_LIBDIR)
+L19F= $(CONF_L19_LIBFILE)
+!ELSE
+L19D=
+L19I=
+L19L=
+L19F=
+!ENDIF
+
+!IF "$(CONF_L20_AVAILABLE)" == "1"
+L20D= $(CONF_L20_DEF)
+L20I= $(CONF_L20_INCLUDE)
+L20L= $(CONF_L20_LIBDIR)
+L20F= $(CONF_L20_LIBFILE)
+!ELSE
+L20D=
+L20I=
+L20L=
+L20F=
+!ENDIF
+
+
+
+LFL= \
+ $(P07L) $(P06L) $(P05L) $(P04L) $(P03L) $(P02L) $(P01L) \
+ $(L01L) $(L02L) $(L03L) $(L04L) $(L05L) \
+ $(L06L) $(L07L) $(L08L) $(L09L) $(L10L) \
+ $(L11L) $(L12L) $(L13L) $(L14L) $(L15L) \
+ $(L16L) $(L17L) $(L18L) $(L19L) $(L20L) \
+ $(P07F) $(P06F) $(P05F) $(P04F) $(P03F) $(P02F) $(P01F) \
+ $(F01F) $(F02F) $(F03F) $(F04F) $(F05F) \
+ $(F06F) $(F07F) $(F08F) $(F09F) $(F10F) \
+ $(F11F) $(F12F) $(F13F) $(F14F) $(F15F) \
+ $(F16F) $(F17F) $(F18F) $(F19F) $(F20F)
+
+CFL= \
+ $(P01D) $(P02D) $(P03D) $(P04D) $(P05D) $(P06D) $(P07D) \
+ $(D01D) $(D02D) $(D03D) $(D04D) $(D05D) \
+ $(D06D) $(D07D) $(D08D) $(D09D) $(D10D) \
+ $(D11D) $(D12D) $(D13D) $(D14D) $(D15D) \
+ $(D16D) $(D17D) $(D18D) $(D19D) $(D20D) \
+ $(P01I) $(P02I) $(P03I) $(P04I) $(P05I) $(P06I) $(P07I) \
+ $(I01I) $(I02I) $(I03I) $(I04I) $(I05I) \
+ $(I06I) $(I07I) $(I08I) $(I09I) $(I10I) \
+ $(I11I) $(I12I) $(I13I) $(I14I) $(I15I) \
+ $(I16I) $(I17I) $(I18I) $(I19I) $(I20I)
+
+GUILFL= \
+ $(P08L) $(P07L) $(P06L) $(P02L) \
+ $(L02L) \
+ $(L06L) $(L07L) $(L08L) $(L09L) $(L10L) \
+ $(L11L) $(L12L) $(L13L) $(L14L) $(L15L) \
+ $(L16L) $(L17L) $(L18L) $(L19L) $(L20L) \
+ $(P08F) $(P07F) $(P06F) $(P03F) $(P02F) $(P01F) \
+ $(F01F) $(F02F) $(F03F) $(F04F) $(F05F) \
+ $(F06F) $(F07F) $(F08F) $(F09F) $(F10F) \
+ $(F11F) $(F12F) $(F13F) $(F14F) $(F15F) \
+ $(F16F) $(F17F) $(F18F) $(F19F) $(F20F)
+
+GUICFL= \
+ $(P08D) $(P07D) $(P06D) $(P05D) $(P04D) $(P03D) $(P02D) $(P01D) \
+ $(D01D) $(D02D) $(D03D) $(D04D) $(D05D) \
+ $(D06D) $(D07D) $(D08D) $(D09D) $(D10D) \
+ $(D11D) $(D12D) $(D13D) $(D14D) $(D15D) \
+ $(D16D) $(D17D) $(D18D) $(D19D) $(D20D) \
+ $(P08I) $(P07I) $(P06I) $(P03I) $(P02I) $(P01I) \
+ $(I01I) $(I02I) $(I03I) $(I04I) $(I05I) \
+ $(I06I) $(I07I) $(I08I) $(I09I) $(I10I) \
+ $(I11I) $(I12I) $(I13I) $(I14I) $(I15I) \
+ $(I16I) $(I17I) $(I18I) $(I19I) $(I20I)
+
+DEFAULTLIBS= kernel32.lib gdi32.lib advapi32.lib user32.lib netapi32.lib
+
+DEFAULTGUILIBS= ole32.lib \
+ oleaut32.lib \
+ shell32.lib \
+ comctl32.lib \
+ comdlg32.lib \
+ winspool.lib \
+ rpcrt4.lib
+
+WINSOCKLIB= ws2_32.lib
+
+# Flags to build executable
+EXEFLAGS= \
+ /nologo /subsystem:console /incremental:no $(EXEFLREL) $(LINKMANIFEST) \
+ /LIBPATH:. $(EXEDLPATH) $(LFL)
+
+GUIEXEFLAGS= \
+ /nologo /subsystem:windows /incremental:no $(EXEFLREL) $(LINKMANIFEST) \
+ /LIBPATH:. $(EXEDLPATH) $(LFLWX) $(GUILFL)
+
+EXE= LINK $(EXEFLAGS) $(DEFAULTLIBS)
+
+GUIEXE= LINK $(GUIEXEFLAGS) $(DEFAULTLIBS) $(DEFAULTGUILIBS)
+
+VC_MANIFEST_EMBED_EXE= \
+if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;1
+
+VC_MANIFEST_EMBED_DLL= \
+if exist $@.manifest mt.exe -manifest $@.manifest -outputresource:$@;2
+
+COBJFL= $(CFLAGSLEGACY) $(CFLUC) $(CFLRT) $(CFLCRT) /W3 \
+ /I. /I.. /I"$(PSDK)\Include" /I"$(VC)\Include" $(GUICFL)
+
+RCOBJFL= $(CFLAGSLEGACY) $(CFLUC) \
+ /I. /I.. /I"$(PSDK)\Include" /I"$(VC)\Include" $(GUICFL)
+
+.cpp.obj:
+ @echo Compile $*.cpp
+ $(CC) /nologo $(CPPFLAGS) $(CFLAGS) $(COBJFL) $(CFLWX) /c $*.cpp
+
+.c.obj:
+ @echo Compile $*.c
+ $(CC) /nologo $(CPPFLAGS) $(CFLAGS) $(COBJFL) /c $*.c
+
+.rc.res:
+ $(RC) /nologo $(CPPFLAGS) $(CFLAGS) $(RCOBJFL) $*.rc
+
+
+# Destination directory for package building
+#
+PREFIX=$(CONF_OUTPUTDIR)\krause$(CONF_BITS)
+BINDIR=$(PREFIX)\bin
+ETCDIR=$(PREFIX)\etc
+SHAREDIR=$(PREFIX)\share
+MANDIR=$(SHAREDIR)\man
+MAN1DIR=$(MANDIR)\man1
+MAN5DIR=$(MANDIR)\man5
+DATADIR=$(SHAREDIR)\dktools
+DK4APPDIR=$(SHAREDIR)\dk4app
+INCLUDEDIR=$(PREFIX)\include
+LIBDIR=$(PREFIX)\lib
+CONTRIBDIR=$(PREFIX)\contrib
+
diff --git a/support/dktools/version.txt b/support/dktools/version.txt
new file mode 100644
index 0000000000..f99c6583c3
--- /dev/null
+++ b/support/dktools/version.txt
@@ -0,0 +1 @@
+4.8.3
diff --git a/support/dktools/win32/dk3conf.h b/support/dktools/win32/dk3conf.h
new file mode 100644
index 0000000000..9801b8e614
--- /dev/null
+++ b/support/dktools/win32/dk3conf.h
@@ -0,0 +1,4222 @@
+/** @file dk3conf.h Configuration for DK3 libraries.
+ Features: Include files, functions, sizes,
+ and endianness.
+*/
+
+#ifndef DK3_CONF_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define DK3_CONF_H_INCLUDED 1
+
+#ifndef DK3_ON_WINDOWS
+#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
+/** On a Windows system. */
+#define DK3_ON_WINDOWS 1
+#else
+/** Not on a Windows system. */
+#define DK3_ON_WINDOWS 0
+#endif
+#endif
+/** ifndef DK3_ON_WINDOWS */
+
+#if DK3_ON_WINDOWS
+
+#ifndef DK3_HAVE_ACOSH
+/** DK3 version of HAVE_ACOSH.
+*/
+#define DK3_HAVE_ACOSH 0
+#endif
+
+#ifndef DK3_HAVE_ACOSHL
+/** DK3 version of HAVE_ACOSHL.
+*/
+#define DK3_HAVE_ACOSHL 1
+#endif
+
+#ifndef DK3_HAVE_ACOSL
+/** DK3 version of HAVE_ACOSL.
+*/
+#define DK3_HAVE_ACOSL 1
+#endif
+
+#ifndef DK3_HAVE_ALLOC_H
+/** DK3 version of HAVE_ALLOC_H.
+*/
+#define DK3_HAVE_ALLOC_H 0
+#endif
+
+#ifndef DK3_HAVE_ARPA_INET_H
+/** DK3 version of HAVE_ARPA_INET_H.
+*/
+#define DK3_HAVE_ARPA_INET_H 0
+#endif
+
+#ifndef DK3_HAVE_ASINH
+/** DK3 version of HAVE_ASINH.
+*/
+#define DK3_HAVE_ASINH 0
+#endif
+
+#ifndef DK3_HAVE_ASINHL
+/** DK3 version of HAVE_ASINHL.
+*/
+#define DK3_HAVE_ASINHL 1
+#endif
+
+#ifndef DK3_HAVE_ASINL
+/** DK3 version of HAVE_ASINL.
+*/
+#define DK3_HAVE_ASINL 1
+#endif
+
+#ifndef DK3_HAVE_ATAN2
+/** DK3 version of HAVE_ATAN2.
+*/
+#define DK3_HAVE_ATAN2 1
+#endif
+
+#ifndef DK3_HAVE_ATAN2L
+/** DK3 version of HAVE_ATAN2L.
+*/
+#define DK3_HAVE_ATAN2L 1
+#endif
+
+#ifndef DK3_HAVE_ATANH
+/** DK3 version of HAVE_ATANH.
+*/
+#define DK3_HAVE_ATANH 0
+#endif
+
+#ifndef DK3_HAVE_ATANHL
+/** DK3 version of HAVE_ATANHL.
+*/
+#define DK3_HAVE_ATANHL 1
+#endif
+
+#ifndef DK3_HAVE_ATANL
+/** DK3 version of HAVE_ATANL.
+*/
+#define DK3_HAVE_ATANL 1
+#endif
+
+#ifndef DK3_HAVE_BACKSLASH
+/** DK3 version of HAVE_BACKSLASH.
+*/
+#define DK3_HAVE_BACKSLASH 1
+#endif
+
+#ifndef DK3_HAVE_BCMP
+/** DK3 version of HAVE_BCMP.
+*/
+#define DK3_HAVE_BCMP 0
+#endif
+
+#ifndef DK3_HAVE_BCOPY
+/** DK3 version of HAVE_BCOPY.
+*/
+#define DK3_HAVE_BCOPY 0
+#endif
+
+#ifndef DK3_HAVE_BZERO
+/** DK3 version of HAVE_BZERO.
+*/
+#define DK3_HAVE_BZERO 0
+#endif
+
+#ifndef DK3_HAVE_CEIL
+/** DK3 version of HAVE_CEIL.
+*/
+#define DK3_HAVE_CEIL 1
+#endif
+
+#ifndef DK3_HAVE_CEILL
+/** DK3 version of HAVE_CEILL.
+*/
+#define DK3_HAVE_CEILL 1
+#endif
+
+#ifndef DK3_HAVE_CHDIR
+/** DK3 version of HAVE_CHDIR.
+*/
+#define DK3_HAVE_CHDIR 1
+#endif
+
+#ifndef DK3_HAVE_CHMOD
+/** DK3 version of HAVE_CHMOD.
+*/
+#define DK3_HAVE_CHMOD 0
+#endif
+
+#ifndef DK3_HAVE_CHOWN
+/** DK3 version of HAVE_CHOWN.
+*/
+#define DK3_HAVE_CHOWN 0
+#endif
+
+#ifndef DK3_HAVE_CLOSEDIR
+/** DK3 version of HAVE_CLOSEDIR.
+*/
+#define DK3_HAVE_CLOSEDIR 0
+#endif
+
+#ifndef DK3_HAVE_CONIO_H
+/** DK3 version of HAVE_CONIO_H.
+*/
+#define DK3_HAVE_CONIO_H 1
+#endif
+
+#ifndef DK3_HAVE_CONST
+/** DK3 version of HAVE_CONST.
+*/
+#define DK3_HAVE_CONST 1
+#endif
+
+#ifndef DK3_HAVE_COSHL
+/** DK3 version of HAVE_COSHL.
+*/
+#define DK3_HAVE_COSHL 1
+#endif
+
+#ifndef DK3_HAVE_COSL
+/** DK3 version of HAVE_COSL.
+*/
+#define DK3_HAVE_COSL 1
+#endif
+
+#ifndef DK3_HAVE_CTYPE_H
+/** DK3 version of HAVE_CTYPE_H.
+*/
+#define DK3_HAVE_CTYPE_H 1
+#endif
+
+#ifndef DK3_HAVE_DEV_RANDOM
+/** DK3 version of HAVE_DEV_RANDOM.
+*/
+#define DK3_HAVE_DEV_RANDOM 0
+#endif
+
+#ifndef DK3_HAVE_DEV_URANDOM
+/** DK3 version of HAVE_DEV_URANDOM.
+*/
+#define DK3_HAVE_DEV_URANDOM 0
+#endif
+
+#ifndef DK3_HAVE_DIRECT_H
+/** DK3 version of HAVE_DIRECT_H.
+*/
+#define DK3_HAVE_DIRECT_H 1
+#endif
+
+#ifndef DK3_HAVE_DIRENT_H
+/** DK3 version of HAVE_DIRENT_H.
+*/
+#define DK3_HAVE_DIRENT_H 0
+#endif
+
+#ifndef DK3_HAVE_DIR_H
+/** DK3 version of HAVE_DIR_H.
+*/
+#define DK3_HAVE_DIR_H 0
+#endif
+
+#ifndef DK3_HAVE_DOS_H
+/** DK3 version of HAVE_DOS_H.
+*/
+#define DK3_HAVE_DOS_H 1
+#endif
+
+#ifndef DK3_HAVE_ENDGRENT
+/** DK3 version of HAVE_ENDGRENT.
+*/
+#define DK3_HAVE_ENDGRENT 0
+#endif
+
+#ifndef DK3_HAVE_ENDPWENT
+/** DK3 version of HAVE_ENDPWENT.
+*/
+#define DK3_HAVE_ENDPWENT 0
+#endif
+
+#ifndef DK3_HAVE_ERRNO_H
+/** DK3 version of HAVE_ERRNO_H.
+*/
+#define DK3_HAVE_ERRNO_H 1
+#endif
+
+#ifndef DK3_HAVE_ERR_H
+/** DK3 version of HAVE_ERR_H.
+*/
+#define DK3_HAVE_ERR_H 0
+#endif
+
+#ifndef DK3_HAVE_EXPL
+/** DK3 version of HAVE_EXPL.
+*/
+#define DK3_HAVE_EXPL 1
+#endif
+
+#ifndef DK3_HAVE_FABS
+/** DK3 version of HAVE_FABS.
+*/
+#define DK3_HAVE_FABS 1
+#endif
+
+#ifndef DK3_HAVE_FABSL
+/** DK3 version of HAVE_FABSL.
+*/
+#define DK3_HAVE_FABSL 1
+#endif
+
+#ifndef DK3_HAVE_FCLOSE
+/** DK3 version of HAVE_FCLOSE.
+*/
+#define DK3_HAVE_FCLOSE 1
+#endif
+
+#ifndef DK3_HAVE_FCNTL_H
+/** DK3 version of HAVE_FCNTL_H.
+*/
+#define DK3_HAVE_FCNTL_H 1
+#endif
+
+#ifndef DK3_HAVE_FENV_H
+/** DK3 version of HAVE_FENV_H.
+*/
+#define DK3_HAVE_FENV_H 0
+#endif
+
+#ifndef DK3_HAVE_FEOF
+/** DK3 version of HAVE_FEOF.
+*/
+#define DK3_HAVE_FEOF 1
+#endif
+
+#ifndef DK3_HAVE_FERROR
+/** DK3 version of HAVE_FERROR.
+*/
+#define DK3_HAVE_FERROR 1
+#endif
+
+#ifndef DK3_HAVE_FETESTEXCEPT
+/** DK3 version of HAVE_FETESTEXCEPT.
+*/
+#define DK3_HAVE_FETESTEXCEPT 0
+#endif
+
+#ifndef DK3_HAVE_FFLUSH
+/** DK3 version of HAVE_FFLUSH.
+*/
+#define DK3_HAVE_FFLUSH 1
+#endif
+
+#ifndef DK3_HAVE_FLOAT_H
+/** DK3 version of HAVE_FLOAT_H.
+*/
+#define DK3_HAVE_FLOAT_H 1
+#endif
+
+#ifndef DK3_HAVE_FLOOR
+/** DK3 version of HAVE_FLOOR.
+*/
+#define DK3_HAVE_FLOOR 1
+#endif
+
+#ifndef DK3_HAVE_FLOORL
+/** DK3 version of HAVE_FLOORL.
+*/
+#define DK3_HAVE_FLOORL 1
+#endif
+
+#ifndef DK3_HAVE_FNCASEINS
+/** DK3 version of HAVE_FNCASEINS.
+*/
+#define DK3_HAVE_FNCASEINS 1
+#endif
+
+#ifndef DK3_HAVE_FOPEN
+/** DK3 version of HAVE_FOPEN.
+*/
+#define DK3_HAVE_FOPEN 1
+#endif
+
+#ifndef DK3_HAVE_FOPEN64
+/** DK3 version of HAVE_FOPEN64.
+*/
+#define DK3_HAVE_FOPEN64 0
+#endif
+
+#ifndef DK3_HAVE_FOPEN_S
+#if (_MSC_VER >= 1700) && (!(DK4_WINDOWS_LEGACY))
+/** DK3 version of HAVE_FOPEN_S.
+*/
+#define DK3_HAVE_FOPEN_S 1
+#else
+/** DK3 version of HAVE_FOPEN_S.
+*/
+#define DK3_HAVE_FOPEN_S 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_FORK
+/** DK3 version of HAVE_FORK.
+*/
+#define DK3_HAVE_FORK 0
+#endif
+
+#ifndef DK3_HAVE_FPCLASSIFY
+/** DK3 version of HAVE_FPCLASSIFY.
+*/
+#define DK3_HAVE_FPCLASSIFY 0
+#endif
+
+#ifndef DK3_HAVE_FREAD
+/** DK3 version of HAVE_FREAD.
+*/
+#define DK3_HAVE_FREAD 0
+#endif
+
+#ifndef DK3_HAVE_FREE
+/** DK3 version of HAVE_FREE.
+*/
+#define DK3_HAVE_FREE 1
+#endif
+
+#ifndef DK3_HAVE_FWRITE
+/** DK3 version of HAVE_FWRITE.
+*/
+#define DK3_HAVE_FWRITE 0
+#endif
+
+#ifndef DK3_HAVE_GDBM_H
+/** DK3 version of HAVE_GDBM_H.
+*/
+#define DK3_HAVE_GDBM_H 0
+#endif
+
+#ifndef DK3_HAVE_GETADDRINFO
+/** DK3 version of HAVE_GETADDRINFO.
+*/
+#if (_MSC_VER >= 1700) && (!(DK4_WINDOWS_LEGACY))
+#define DK3_HAVE_GETADDRINFO 1
+#else
+#define DK3_HAVE_GETADDRINFO 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_GETCWD
+/** DK3 version of HAVE_GETCWD.
+*/
+#define DK3_HAVE_GETCWD 1
+#endif
+
+#ifndef DK3_HAVE_GETENV
+/** DK3 version of HAVE_GETENV.
+*/
+#define DK3_HAVE_GETENV 1
+#endif
+
+#ifndef DK3_HAVE_GETEUID
+/** DK3 version of HAVE_GETEUID.
+*/
+#define DK3_HAVE_GETEUID 0
+#endif
+
+#ifndef DK3_HAVE_GETGRENT
+/** DK3 version of HAVE_GETGRENT.
+*/
+#define DK3_HAVE_GETGRENT 0
+#endif
+
+#ifndef DK3_HAVE_GETGRGID
+/** DK3 version of HAVE_GETGRGID.
+*/
+#define DK3_HAVE_GETGRGID 0
+#endif
+
+#ifndef DK3_HAVE_GETGRNAM
+/** DK3 version of HAVE_GETGRNAM.
+*/
+#define DK3_HAVE_GETGRNAM 0
+#endif
+
+#ifndef DK3_HAVE_GETHOSTBYNAME
+/** DK3 version of HAVE_GETHOSTBYNAME.
+*/
+#define DK3_HAVE_GETHOSTBYNAME 1
+#endif
+
+#ifndef DK3_HAVE_GETHOSTNAME
+/** DK3 version of HAVE_GETHOSTNAME.
+*/
+#define DK3_HAVE_GETHOSTNAME 0
+#endif
+
+#ifndef DK3_HAVE_GETPEERNAME
+/** DK3 version of HAVE_GETPEERNAME.
+*/
+#define DK3_HAVE_GETPEERNAME 1
+#endif
+
+#ifndef DK3_HAVE_GETPID
+/** DK3 version of HAVE_GETPID.
+*/
+#define DK3_HAVE_GETPID 1
+#endif
+
+#ifndef DK3_HAVE_GETPWENT
+/** DK3 version of HAVE_GETPWENT.
+*/
+#define DK3_HAVE_GETPWENT 0
+#endif
+
+#ifndef DK3_HAVE_GETPWNAM
+/** DK3 version of HAVE_GETPWNAM.
+*/
+#define DK3_HAVE_GETPWNAM 0
+#endif
+
+#ifndef DK3_HAVE_GETPWUID
+/** DK3 version of HAVE_GETPWUID.
+*/
+#define DK3_HAVE_GETPWUID 0
+#endif
+
+#ifndef DK3_HAVE_GETRLIMIT
+/** DK3 version of HAVE_GETRLIMIT.
+*/
+#define DK3_HAVE_GETRLIMIT 0
+#endif
+
+#ifndef DK3_HAVE_GETSOCKNAME
+/** DK3 version of HAVE_GETSOCKNAME.
+*/
+#define DK3_HAVE_GETSOCKNAME 1
+#endif
+
+#ifndef DK3_HAVE_GETUID
+/** DK3 version of HAVE_GETUID.
+*/
+#define DK3_HAVE_GETUID 0
+#endif
+
+#ifndef DK3_HAVE_GRP_H
+/** DK3 version of HAVE_GRP_H.
+*/
+#define DK3_HAVE_GRP_H 0
+#endif
+
+#ifndef DK3_HAVE_HTONL
+/** DK3 version of HAVE_HTONL.
+*/
+#define DK3_HAVE_HTONL 1
+#endif
+
+#ifndef DK3_HAVE_IEEE_754_DOUBLE
+/** DK3 version of HAVE_IEEE_754_DOUBLE.
+*/
+#define DK3_HAVE_IEEE_754_DOUBLE 1
+#endif
+
+#ifndef DK3_HAVE_IN6_ADDR
+/** DK3 version of HAVE_IN6_ADDR.
+*/
+#define DK3_HAVE_IN6_ADDR 1
+#endif
+
+#ifndef DK3_HAVE_INET_ADDR
+/** DK3 version of HAVE_INET_ADDR.
+*/
+#define DK3_HAVE_INET_ADDR 0
+#endif
+
+#ifndef DK3_HAVE_INET_ATON
+/** DK3 version of HAVE_INET_ATON.
+*/
+#define DK3_HAVE_INET_ATON 0
+#endif
+
+#ifndef DK3_HAVE_INET_PTON
+/** DK3 version of HAVE_INET_PTON.
+*/
+#if (_MSC_VER >= 1700) && (!(DK4_WINDOWS_LEGACY))
+#define DK3_HAVE_INET_PTON 1
+#else
+#define DK3_HAVE_INET_PTON 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_INITSTATE
+/** DK3 version of HAVE_INITSTATE.
+*/
+#define DK3_HAVE_INITSTATE 0
+#endif
+
+#ifndef DK3_HAVE_INODES
+/** DK3 version of HAVE_INODES.
+*/
+#define DK3_HAVE_INODES 0
+#endif
+
+#ifndef DK3_HAVE_INTMAX_T
+#if (_MSC_VER >= 1700) && (!(DK4_WINDOWS_LEGACY))
+/** DK3 version of HAVE_INTMAX_T.
+*/
+#define DK3_HAVE_INTMAX_T 1
+#else
+/** DK3 version of HAVE_INTMAX_T.
+*/
+#define DK3_HAVE_INTMAX_T 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_INTTYPES_H
+/** DK3 version of HAVE_INTTYPES_H.
+*/
+#define DK3_HAVE_INTTYPES_H 0
+#endif
+
+#ifndef DK3_HAVE_IN_ADDR
+/** DK3 version of HAVE_IN_ADDR.
+*/
+#define DK3_HAVE_IN_ADDR 1
+#endif
+
+#ifndef DK3_HAVE_IO_H
+/** DK3 version of HAVE_IO_H.
+*/
+#define DK3_HAVE_IO_H 1
+#endif
+
+#ifndef DK3_HAVE_ISATTY
+/** DK3 version of HAVE_ISATTY.
+*/
+#define DK3_HAVE_ISATTY 1
+#endif
+
+#ifndef DK3_HAVE_ISFINITE
+/** DK3 version of HAVE_ISFINITE.
+*/
+#define DK3_HAVE_ISFINITE 0
+#endif
+
+#ifndef DK3_HAVE_ISNORMAL
+/** DK3 version of HAVE_ISNORMAL.
+*/
+#define DK3_HAVE_ISNORMAL 0
+#endif
+
+#ifndef DK3_HAVE_LABS
+/** DK3 version of HAVE_LABS.
+*/
+#define DK3_HAVE_LABS 1
+#endif
+
+#ifndef DK3_HAVE_LARGEFILE64_SOURCE
+/** DK3 version of HAVE_LARGEFILE64_SOURCE.
+*/
+#define DK3_HAVE_LARGEFILE64_SOURCE 0
+#endif
+
+#ifndef DK3_HAVE_LIMITS_H
+/** DK3 version of HAVE_LIMITS_H.
+*/
+#define DK3_HAVE_LIMITS_H 1
+#endif
+
+#ifndef DK3_HAVE_LOCALE_H
+/** DK3 version of HAVE_LOCALE_H.
+*/
+#define DK3_HAVE_LOCALE_H 1
+#endif
+
+#ifndef DK3_HAVE_LOCALTIME
+/** DK3 version of HAVE_LOCALTIME.
+*/
+#define DK3_HAVE_LOCALTIME 1
+#endif
+
+#ifndef DK3_HAVE_LOCALTIME
+/** DK3 version of HAVE_LOCALTIME.
+*/
+#define DK3_HAVE_LOCALTIME 1
+#endif
+
+#ifndef DK3_HAVE_LOCALTIME_R
+/** DK3 version of HAVE_LOCALTIME_R.
+*/
+#define DK3_HAVE_LOCALTIME_R 0
+#endif
+
+#ifndef DK3_HAVE_LOCALTIME_S
+#if (_MSC_VER >= 1700) && (!(DK4_WINDOWS_LEGACY))
+/** DK3 version of HAVE_LOCALTIME_S.
+*/
+#define DK3_HAVE_LOCALTIME_S 1
+#else
+/** DK3 version of HAVE_LOCALTIME_S.
+*/
+#define DK3_HAVE_LOCALTIME_S 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_LOGL
+/** DK3 version of HAVE_LOGL.
+*/
+#define DK3_HAVE_LOGL 1
+#endif
+
+#ifndef DK3_HAVE_LONG_DOUBLE
+/** DK3 version of HAVE_LONG_DOUBLE.
+*/
+#define DK3_HAVE_LONG_DOUBLE 1
+#endif
+
+#ifndef DK3_HAVE_LONG_LONG
+/** DK3 version of HAVE_LONG_LONG.
+*/
+#define DK3_HAVE_LONG_LONG 1
+#endif
+
+#ifndef DK3_HAVE_LRAND48
+/** DK3 version of HAVE_LRAND48.
+*/
+#define DK3_HAVE_LRAND48 0
+#endif
+
+#ifndef DK3_HAVE_LSTAT
+/** DK3 version of HAVE_LSTAT.
+*/
+#define DK3_HAVE_LSTAT 1
+#endif
+
+#ifndef DK3_HAVE_LSTAT32
+/** DK3 version of HAVE_LSTAT32.
+*/
+#define DK3_HAVE_LSTAT32 1
+#endif
+
+#ifndef DK3_HAVE_LSTAT64
+/** DK3 version of HAVE_LSTAT64.
+*/
+#define DK3_HAVE_LSTAT64 1
+#endif
+
+#ifndef DK3_HAVE_MALLOC
+/** DK3 version of HAVE_MALLOC.
+*/
+#define DK3_HAVE_MALLOC 1
+#endif
+
+#ifndef DK3_HAVE_MALLOC_H
+/** DK3 version of HAVE_MALLOC_H.
+*/
+#define DK3_HAVE_MALLOC_H 1
+#endif
+
+#ifndef DK3_HAVE_MATH_H
+/** DK3 version of HAVE_MATH_H.
+*/
+#define DK3_HAVE_MATH_H 1
+#endif
+
+#ifndef DK3_HAVE_MEMCMP
+/** DK3 version of HAVE_MEMCMP.
+*/
+#define DK3_HAVE_MEMCMP 1
+#endif
+
+#ifndef DK3_HAVE_MEMCPY
+/** DK3 version of HAVE_MEMCPY.
+*/
+#define DK3_HAVE_MEMCPY 1
+#endif
+
+#ifndef DK3_HAVE_MEMSET
+/** DK3 version of HAVE_MEMSET.
+*/
+#define DK3_HAVE_MEMSET 1
+#endif
+
+#ifndef DK3_HAVE_MKDIR
+/** DK3 version of HAVE_MKDIR.
+*/
+#define DK3_HAVE_MKDIR 0
+#endif
+
+#ifndef DK3_HAVE_MKDIR2
+/** DK3 version of HAVE_MKDIR2.
+*/
+#define DK3_HAVE_MKDIR2 0
+#endif
+
+#ifndef DK3_HAVE_MPCTL
+/** DK3 version of HAVE_MPCTL.
+*/
+#define DK3_HAVE_MPCTL 0
+#endif
+
+#ifndef DK3_HAVE_NDBM_H
+/** DK3 version of HAVE_NDBM_H.
+*/
+#define DK3_HAVE_NDBM_H 0
+#endif
+
+#ifndef DK3_HAVE_NETDB_H
+/** DK3 version of HAVE_NETDB_H.
+*/
+#define DK3_HAVE_NETDB_H 0
+#endif
+
+#ifndef DK3_HAVE_NETINET_IN_H
+/** DK3 version of HAVE_NETINET_IN_H.
+*/
+#define DK3_HAVE_NETINET_IN_H 0
+#endif
+
+#ifndef DK3_HAVE_NRAND48
+/** DK3 version of HAVE_NRAND48.
+*/
+#define DK3_HAVE_NRAND48 0
+#endif
+
+#ifndef DK3_HAVE_OPENDIR
+/** DK3 version of HAVE_OPENDIR.
+*/
+#define DK3_HAVE_OPENDIR 0
+#endif
+
+#ifndef DK3_HAVE_PNG_GET_PIXELS_PER_INCH
+/** DK3 version of HAVE_PNG_GET_PIXELS_PER_INCH.
+*/
+#define DK3_HAVE_PNG_GET_PIXELS_PER_INCH 1
+#endif
+
+#ifndef DK3_HAVE_POPEN
+/** DK3 version of HAVE_POPEN.
+*/
+#define DK3_HAVE_POPEN 0
+#endif
+
+#ifndef DK3_HAVE_PROCESS_H
+/** DK3 version of HAVE_PROCESS_H.
+*/
+#define DK3_HAVE_PROCESS_H 1
+#endif
+
+#ifndef DK3_HAVE_PTHREAD_H
+/** DK3 version of HAVE_PTHREAD_H.
+*/
+#define DK3_HAVE_PTHREAD_H 0
+#endif
+
+#ifndef DK3_HAVE_PWD_H
+/** DK3 version of HAVE_PWD_H.
+*/
+#define DK3_HAVE_PWD_H 0
+#endif
+
+#ifndef DK3_HAVE_RAND
+/** DK3 version of HAVE_RAND.
+*/
+#define DK3_HAVE_RAND 0
+#endif
+
+#ifndef DK3_HAVE_RANDOM
+/** DK3 version of HAVE_RANDOM.
+*/
+#define DK3_HAVE_RANDOM 0
+#endif
+
+#ifndef DK3_HAVE_READ
+/** DK3 version of HAVE_READ.
+*/
+#define DK3_HAVE_READ 1
+#endif
+
+#ifndef DK3_HAVE_READDIR
+/** DK3 version of HAVE_READDIR.
+*/
+#define DK3_HAVE_READDIR 0
+#endif
+
+#ifndef DK3_HAVE_RFC_2249
+/** DK3 version of HAVE_RFC_2249.
+*/
+#define DK3_HAVE_RFC_2249 0
+#endif
+
+#ifndef DK3_HAVE_RINT
+/** DK3 version of HAVE_RINT.
+*/
+#define DK3_HAVE_RINT 0
+#endif
+
+#ifndef DK3_HAVE_RINTL
+/** DK3 version of HAVE_RINTL.
+*/
+#define DK3_HAVE_RINTL 1
+#endif
+
+#ifndef DK3_HAVE_RMDIR
+/** DK3 version of HAVE_RMDIR.
+*/
+#define DK3_HAVE_RMDIR 0
+#endif
+
+#ifndef DK3_HAVE_SEED48
+/** DK3 version of HAVE_SEED48.
+*/
+#define DK3_HAVE_SEED48 0
+#endif
+
+#ifndef DK3_HAVE_SELECT
+/** DK3 version of HAVE_SELECT.
+*/
+#define DK3_HAVE_SELECT 1
+#endif
+
+#ifndef DK3_HAVE_SETGID
+/** DK3 version of HAVE_SETGID.
+*/
+#define DK3_HAVE_SETGID 0
+#endif
+
+#ifndef DK3_HAVE_SETGRENT
+/** DK3 version of HAVE_SETGRENT.
+*/
+#define DK3_HAVE_SETGRENT 0
+#endif
+
+#ifndef DK3_HAVE_SETJMP_H
+/** DK3 version of HAVE_SETJMP_H.
+*/
+#define DK3_HAVE_SETJMP_H 1
+#endif
+
+#ifndef DK3_HAVE_SETPGRP
+/** DK3 version of HAVE_SETPGRP.
+*/
+#define DK3_HAVE_SETPGRP 0
+#endif
+
+#ifndef DK3_HAVE_SETPWENT
+/** DK3 version of HAVE_SETPWENT.
+*/
+#define DK3_HAVE_SETPWENT 0
+#endif
+
+#ifndef DK3_HAVE_SETSID
+/** DK3 version of HAVE_SETSID.
+*/
+#define DK3_HAVE_SETSID 0
+#endif
+
+#ifndef DK3_HAVE_SETSOCKOPT
+/** DK3 version of HAVE_SETSOCKOPT.
+*/
+#define DK3_HAVE_SETSOCKOPT 1
+#endif
+
+#ifndef DK3_HAVE_SETSTATE
+/** DK3 version of HAVE_SETSTATE.
+*/
+#define DK3_HAVE_SETSTATE 0
+#endif
+
+#ifndef DK3_HAVE_SETUID
+/** DK3 version of HAVE_SETUID.
+*/
+#define DK3_HAVE_SETUID 0
+#endif
+
+#ifndef DK3_HAVE_SHADOW_H
+/** DK3 version of HAVE_SHADOW_H.
+*/
+#define DK3_HAVE_SHADOW_H 0
+#endif
+
+#ifndef DK3_HAVE_SIGACTION
+/** DK3 version of HAVE_SIGACTION.
+*/
+#define DK3_HAVE_SIGACTION 0
+#endif
+
+#ifndef DK3_HAVE_SIGNAL
+/** DK3 version of HAVE_SIGNAL.
+*/
+#define DK3_HAVE_SIGNAL 1
+#endif
+
+#ifndef DK3_HAVE_SIGNAL_H
+/** DK3 version of HAVE_SIGNAL_H.
+*/
+#define DK3_HAVE_SIGNAL_H 1
+#endif
+
+#ifndef DK3_HAVE_SIGSET
+/** DK3 version of HAVE_SIGSET.
+*/
+#define DK3_HAVE_SIGSET 0
+#endif
+
+#ifndef DK3_HAVE_SIG_ATOMIC_T
+/** DK3 version of HAVE_SIG_ATOMIC_T.
+*/
+#define DK3_HAVE_SIG_ATOMIC_T 0
+#endif
+
+#ifndef DK3_HAVE_SINHL
+/** DK3 version of HAVE_SINHL.
+*/
+#define DK3_HAVE_SINHL 1
+#endif
+
+#ifndef DK3_HAVE_SINL
+/** DK3 version of HAVE_SINL.
+*/
+#define DK3_HAVE_SINL 1
+#endif
+
+#ifndef DK3_HAVE_SNPRINTF
+/** DK3 version of HAVE_SNPRINTF.
+*/
+#define DK3_HAVE_SNPRINTF 0
+#endif
+
+#ifndef DK3_HAVE_SOCKET
+/** DK3 version of HAVE_SOCKET.
+*/
+#define DK3_HAVE_SOCKET 1
+#endif
+
+#ifndef DK3_HAVE_SOCKLEN_T
+/** DK3 version of HAVE_SOCKLEN_T.
+*/
+#define DK3_HAVE_SOCKLEN_T 0
+#endif
+
+#ifndef DK3_HAVE_SPRINTF_S
+#if (_MSC_VER >= 1700) && (!(DK4_WINDOWS_LEGACY))
+/** DK3 version of HAVE_SPRINTF_S.
+*/
+#define DK3_HAVE_SPRINTF_S 1
+#else
+/** DK3 version of HAVE_SPRINTF_S.
+*/
+#define DK3_HAVE_SPRINTF_S 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_SQRTL
+/** DK3 version of HAVE_SQRTL.
+*/
+#define DK3_HAVE_SQRTL 1
+#endif
+
+#ifndef DK3_HAVE_SRAND
+/** DK3 version of HAVE_SRAND.
+*/
+#define DK3_HAVE_SRAND 0
+#endif
+
+#ifndef DK3_HAVE_SSCANF_S
+#if (_MSC_VER >= 1700) && (!(DK4_WINDOWS_LEGACY))
+/** DK3 version of HAVE_SSCANF_S.
+*/
+#define DK3_HAVE_SSCANF_S 1
+#else
+/** DK3 version of HAVE_SSCANF_S.
+*/
+#define DK3_HAVE_SSCANF_S 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_SSIZE_T
+/** DK3 version of HAVE_SSIZE_T.
+*/
+#define DK3_HAVE_SSIZE_T 0
+#endif
+
+#ifndef DK3_HAVE_STAT
+/** DK3 version of HAVE_STAT.
+*/
+#define DK3_HAVE_STAT 1
+#endif
+
+#ifndef DK3_HAVE_STAT32
+/** DK3 version of HAVE_STAT32.
+*/
+#define DK3_HAVE_STAT32 1
+#endif
+
+#ifndef DK3_HAVE_STAT64
+/** DK3 version of HAVE_STAT64.
+*/
+#define DK3_HAVE_STAT64 1
+#endif
+
+#ifndef DK3_HAVE_STDARG_H
+/** DK3 version of HAVE_STDARG_H.
+*/
+#define DK3_HAVE_STDARG_H 1
+#endif
+
+#ifndef DK3_HAVE_STDDEF_H
+/** DK3 version of HAVE_STDDEF_H.
+*/
+#define DK3_HAVE_STDDEF_H 1
+#endif
+
+#ifndef DK3_HAVE_STDINT_H
+#if (_MSC_VER >= 1700) && (!(DK4_WINDOWS_LEGACY))
+/** DK3 version of HAVE_STDINT_H.
+*/
+#define DK3_HAVE_STDINT_H 1
+#else
+/** DK3 version of HAVE_STDINT_H.
+*/
+#define DK3_HAVE_STDINT_H 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_STDIO_H
+/** DK3 version of HAVE_STDIO_H.
+*/
+#define DK3_HAVE_STDIO_H 1
+#endif
+
+#ifndef DK3_HAVE_STDLIB_H
+/** DK3 version of HAVE_STDLIB_H.
+*/
+#define DK3_HAVE_STDLIB_H 1
+#endif
+
+#ifndef DK3_HAVE_STRCASECMP
+/** DK3 version of HAVE_STRCASECMP.
+*/
+#define DK3_HAVE_STRCASECMP 0
+#endif
+
+#ifndef DK3_HAVE_STRCAT
+/** DK3 version of HAVE_STRCAT.
+*/
+#define DK3_HAVE_STRCAT 1
+#endif
+
+#ifndef DK3_HAVE_STRCAT_S
+#if (_MSC_VER >= 1700) && (!(DK4_WINDOWS_LEGACY))
+/** DK3 version of HAVE_STRCAT_S.
+*/
+#define DK3_HAVE_STRCAT_S 1
+#else
+/** DK3 version of HAVE_STRCAT_S.
+*/
+#define DK3_HAVE_STRCAT_S 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRCHR
+/** DK3 version of HAVE_STRCHR.
+*/
+#define DK3_HAVE_STRCHR 1
+#endif
+
+#ifndef DK3_HAVE_STRCMP
+/** DK3 version of HAVE_STRCMP.
+*/
+#define DK3_HAVE_STRCMP 1
+#endif
+
+#ifndef DK3_HAVE_STRCPY
+/** DK3 version of HAVE_STRCPY.
+*/
+#define DK3_HAVE_STRCPY 1
+#endif
+
+#ifndef DK3_HAVE_STRCPY_S
+#if (_MSC_VER >= 1700) && (!(DK4_WINDOWS_LEGACY))
+/** DK3 version of HAVE_STRCPY_S.
+*/
+#define DK3_HAVE_STRCPY_S 1
+#else
+/** DK3 version of HAVE_STRCPY_S.
+*/
+#define DK3_HAVE_STRCPY_S 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRDUP
+/** DK3 version of HAVE_STRDUP.
+*/
+#define DK3_HAVE_STRDUP 0
+#endif
+
+#ifndef DK3_HAVE_STRERROR
+/** DK3 version of HAVE_STRERROR.
+*/
+#define DK3_HAVE_STRERROR 1
+#endif
+
+#ifndef DK3_HAVE_STRICMP
+/** DK3 version of HAVE_STRICMP.
+*/
+#define DK3_HAVE_STRICMP 0
+#endif
+
+#ifndef DK3_HAVE_STRINGS_H
+/** DK3 version of HAVE_STRINGS_H.
+*/
+#define DK3_HAVE_STRINGS_H 0
+#endif
+
+#ifndef DK3_HAVE_STRING_H
+/** DK3 version of HAVE_STRING_H.
+*/
+#define DK3_HAVE_STRING_H 1
+#endif
+
+#ifndef DK3_HAVE_STRLEN
+/** DK3 version of HAVE_STRLEN.
+*/
+#define DK3_HAVE_STRLEN 1
+#endif
+
+#ifndef DK3_HAVE_STRNCMP
+/** DK3 version of HAVE_STRNCMP.
+*/
+#define DK3_HAVE_STRNCMP 1
+#endif
+
+#ifndef DK3_HAVE_STRNCPY
+/** DK3 version of HAVE_STRNCPY.
+*/
+#define DK3_HAVE_STRNCPY 1
+#endif
+
+#ifndef DK3_HAVE_STRNCPY_S
+#if (_MSC_VER >= 1700) && (!(DK4_WINDOWS_LEGACY))
+/** DK3 version of HAVE_STRNCPY_S.
+*/
+#define DK3_HAVE_STRNCPY_S 1
+#else
+/** DK3 version of HAVE_STRNCPY_S.
+*/
+#define DK3_HAVE_STRNCPY_S 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_STROPTS_H
+/** DK3 version of HAVE_STROPTS_H.
+*/
+#define DK3_HAVE_STROPTS_H 0
+#endif
+
+#ifndef DK3_HAVE_STRRCHR
+/** DK3 version of HAVE_STRRCHR.
+*/
+#define DK3_HAVE_STRRCHR 1
+#endif
+
+#ifndef DK3_HAVE_STRTOD
+/** DK3 version of HAVE_STRTOD.
+*/
+#define DK3_HAVE_STRTOD 1
+#endif
+
+#ifndef DK3_HAVE_STRTOIMAX
+#if (_MSC_VER >= 1800) && (!(DK4_WINDOWS_LEGACY))
+/** DK3 version of HAVE_STRTOIMAX.
+*/
+#define DK3_HAVE_STRTOIMAX 1
+#else
+/** DK3 version of HAVE_STRTOIMAX.
+*/
+#define DK3_HAVE_STRTOIMAX 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRTOL
+#if (_MSC_VER >= 1700) && (!(DK4_WINDOWS_LEGACY))
+/** DK3 version of HAVE_STRTOL.
+*/
+#define DK3_HAVE_STRTOL 1
+#else
+/** DK3 version of HAVE_STRTOL.
+*/
+#define DK3_HAVE_STRTOL 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRTOLL
+#if (_MSC_VER >= 1700) && (!(DK4_WINDOWS_LEGACY))
+/** DK3 version of HAVE_STRTOLL.
+*/
+#define DK3_HAVE_STRTOLL 1
+#else
+/** DK3 version of HAVE_STRTOLL.
+*/
+#define DK3_HAVE_STRTOLL 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRTOUL
+#if (_MSC_VER >= 1700) && (!(DK4_WINDOWS_LEGACY))
+/** DK3 version of HAVE_STRTOUL.
+*/
+#define DK3_HAVE_STRTOUL 1
+#else
+/** DK3 version of HAVE_STRTOUL.
+*/
+#define DK3_HAVE_STRTOUL 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRTOULL
+#if (_MSC_VER >= 1700) && (!(DK4_WINDOWS_LEGACY))
+/** DK3 version of HAVE_STRTOULL.
+*/
+#define DK3_HAVE_STRTOULL 1
+#else
+/** DK3 version of HAVE_STRTOULL.
+*/
+#define DK3_HAVE_STRTOULL 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRTOUMAX
+#if (_MSC_VER >= 1800) && (!(DK4_WINDOWS_LEGACY))
+/** DK3 version of HAVE_STRTOUMAX.
+*/
+#define DK3_HAVE_STRTOUMAX 1
+#else
+/** DK3 version of HAVE_STRTOUMAX.
+*/
+#define DK3_HAVE_STRTOUMAX 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRUCT_ADDRINFO
+/** DK3 version of HAVE_STRUCT_ADDRINFO.
+*/
+#define DK3_HAVE_STRUCT_ADDRINFO 0
+#endif
+
+#ifndef DK3_HAVE_STRUCT_SOCKADDR_IN
+/** DK3 version of HAVE_STRUCT_SOCKADDR_IN.
+*/
+#define DK3_HAVE_STRUCT_SOCKADDR_IN 1
+#endif
+
+#ifndef DK3_HAVE_STRUCT_SOCKADDR_IN6
+/** DK3 version of HAVE_STRUCT_SOCKADDR_IN6.
+*/
+#if (_MSC_VER >= 1700) && (!(DK4_WINDOWS_LEGACY))
+#define DK3_HAVE_STRUCT_SOCKADDR_IN6 1
+#else
+#define DK3_HAVE_STRUCT_SOCKADDR_IN6 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_STRUCT_SOCKADDR_STORAGE
+/** DK3 version of HAVE_STRUCT_SOCKADDR_STORAGE.
+*/
+#define DK3_HAVE_STRUCT_SOCKADDR_STORAGE 0
+#endif
+
+#ifndef DK3_HAVE_STRUCT_SOCKADDR_UN
+/** DK3 version of HAVE_STRUCT_SOCKADDR_UN.
+*/
+#define DK3_HAVE_STRUCT_SOCKADDR_UN 0
+#endif
+
+#ifndef DK3_HAVE_SWSCANF_S
+#if (_MSC_VER >= 1700) && (!(DK4_WINDOWS_LEGACY))
+/** DK3 version of HAVE_SWSCANF_S.
+*/
+#define DK3_HAVE_SWSCANF_S 1
+#else
+/** DK3 version of HAVE_SWSCANF_S.
+*/
+#define DK3_HAVE_SWSCANF_S 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_SYSCONF
+/** DK3 version of HAVE_SYSCONF.
+*/
+#define DK3_HAVE_SYSCONF 0
+#endif
+
+#ifndef DK3_HAVE_SYSCTL
+/** DK3 version of HAVE_SYSCTL.
+*/
+#define DK3_HAVE_SYSCTL 0
+#endif
+
+#ifndef DK3_HAVE_SYSLOG
+/** DK3 version of HAVE_SYSLOG.
+*/
+#define DK3_HAVE_SYSLOG 0
+#endif
+
+#ifndef DK3_HAVE_SYSLOG_H
+/** DK3 version of HAVE_SYSLOG_H.
+*/
+#define DK3_HAVE_SYSLOG_H 0
+#endif
+
+#ifndef DK3_HAVE_SYSRES_H
+/** DK3 version of HAVE_SYSRES_H.
+*/
+#define DK3_HAVE_SYSRES_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_FILE_H
+/** DK3 version of HAVE_SYS_FILE_H.
+*/
+#define DK3_HAVE_SYS_FILE_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_PARAM_H
+/** DK3 version of HAVE_SYS_PARAM_H.
+*/
+#define DK3_HAVE_SYS_PARAM_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_RESOURCE_H
+/** DK3 version of HAVE_SYS_RESOURCE_H.
+*/
+#define DK3_HAVE_SYS_RESOURCE_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_SOCKET_H
+/** DK3 version of HAVE_SYS_SOCKET_H.
+*/
+#define DK3_HAVE_SYS_SOCKET_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_STATVFS_H
+/** DK3 version of HAVE_SYS_STATVFS_H.
+*/
+#define DK3_HAVE_SYS_STATVFS_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_STAT_H
+/** DK3 version of HAVE_SYS_STAT_H.
+*/
+#define DK3_HAVE_SYS_STAT_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_STROPTS_H
+/** DK3 version of HAVE_SYS_STROPTS_H.
+*/
+#define DK3_HAVE_SYS_STROPTS_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_SUNDDI_H
+/** DK3 version of HAVE_SYS_SUNDDI_H.
+*/
+#define DK3_HAVE_SYS_SUNDDI_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_SYSCTL_H
+/** DK3 version of HAVE_SYS_SYSCTL_H.
+*/
+#define DK3_HAVE_SYS_SYSCTL_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_SYSTEMINFO_H
+/** DK3 version of HAVE_SYS_SYSTEMINFO_H.
+*/
+#define DK3_HAVE_SYS_SYSTEMINFO_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_TERMIOS_H
+/** DK3 version of HAVE_SYS_TERMIOS_H.
+*/
+#define DK3_HAVE_SYS_TERMIOS_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_TIME_H
+/** DK3 version of HAVE_SYS_TIME_H.
+*/
+#define DK3_HAVE_SYS_TIME_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_TTOLD_H
+/** DK3 version of HAVE_SYS_TTOLD_H.
+*/
+#define DK3_HAVE_SYS_TTOLD_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_TYPES_H
+/** DK3 version of HAVE_SYS_TYPES_H.
+*/
+#define DK3_HAVE_SYS_TYPES_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_UIO_H
+/** DK3 version of HAVE_SYS_UIO_H.
+*/
+#define DK3_HAVE_SYS_UIO_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_UN_H
+/** DK3 version of HAVE_SYS_UN_H.
+*/
+#define DK3_HAVE_SYS_UN_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_WAIT_H
+/** DK3 version of HAVE_SYS_WAIT_H.
+*/
+#define DK3_HAVE_SYS_WAIT_H 0
+#endif
+
+#ifndef DK3_HAVE_TANHL
+/** DK3 version of HAVE_TANHL.
+*/
+#define DK3_HAVE_TANHL 1
+#endif
+
+#ifndef DK3_HAVE_TANL
+/** DK3 version of HAVE_TANL.
+*/
+#define DK3_HAVE_TANL 1
+#endif
+
+#ifndef DK3_HAVE_TCFLUSH
+/** DK3 version of HAVE_TCFLUSH.
+*/
+#define DK3_HAVE_TCFLUSH 0
+#endif
+
+#ifndef DK3_HAVE_TCGETATTR
+/** DK3 version of HAVE_TCGETATTR.
+*/
+#define DK3_HAVE_TCGETATTR 0
+#endif
+
+#ifndef DK3_HAVE_TERMIOS_H
+/** DK3 version of HAVE_TERMIOS_H.
+*/
+#define DK3_HAVE_TERMIOS_H 0
+#endif
+
+#ifndef DK3_HAVE_TIME
+/** DK3 version of HAVE_TIME.
+*/
+#define DK3_HAVE_TIME 1
+#endif
+
+#ifndef DK3_HAVE_TIME_H
+/** DK3 version of HAVE_TIME_H.
+*/
+#define DK3_HAVE_TIME_H 1
+#endif
+
+#ifndef DK3_HAVE_TWOS_COMPLEMENT
+/** DK3 version of HAVE_TWOS_COMPLEMENT.
+*/
+#define DK3_HAVE_TWOS_COMPLEMENT 1
+#endif
+
+#ifndef DK3_HAVE_UMASK
+/** DK3 version of HAVE_UMASK.
+*/
+#define DK3_HAVE_UMASK 0
+#endif
+
+#ifndef DK3_HAVE_UNISTD_H
+/** DK3 version of HAVE_UNISTD_H.
+*/
+#define DK3_HAVE_UNISTD_H 0
+#endif
+
+#ifndef DK3_HAVE_UNLINK
+/** DK3 version of HAVE_UNLINK.
+*/
+#define DK3_HAVE_UNLINK 0
+#endif
+
+#ifndef DK3_HAVE_USER_NAMES_CASE_INSENSITIVE
+/** DK3 version of HAVE_USER_NAMES_CASE_INSENSITIVE.
+*/
+#define DK3_HAVE_USER_NAMES_CASE_INSENSITIVE 1
+#endif
+
+#ifndef DK3_HAVE_VARARGS_H
+/** DK3 version of HAVE_VARARGS_H.
+*/
+#define DK3_HAVE_VARARGS_H 0
+#endif
+
+#ifndef DK3_HAVE_VARARG_H
+/** DK3 version of HAVE_VARARG_H.
+*/
+#define DK3_HAVE_VARARG_H 0
+#endif
+
+#ifndef DK3_HAVE_VOLATILE
+/** DK3 version of HAVE_VOLATILE.
+*/
+#define DK3_HAVE_VOLATILE 1
+#endif
+
+#ifndef DK3_HAVE_WCHAR_H
+/** DK3 version of HAVE_WCHAR_H.
+*/
+#define DK3_HAVE_WCHAR_H 1
+#endif
+
+#ifndef DK3_HAVE_WCHAR_T
+/** DK3 version of HAVE_WCHAR_T.
+*/
+#define DK3_HAVE_WCHAR_T 1
+#endif
+
+#ifndef DK3_HAVE_WCSCAT
+/** DK3 version of HAVE_WCSCAT.
+*/
+#define DK3_HAVE_WCSCAT 1
+#endif
+
+#ifndef DK3_HAVE_WCSCAT_S
+#if (_MSC_VER >= 1700) && (!(DK4_WINDOWS_LEGACY))
+/** DK3 version of HAVE_WCSCAT_S.
+*/
+#define DK3_HAVE_WCSCAT_S 1
+#else
+/** DK3 version of HAVE_WCSCAT_S.
+*/
+#define DK3_HAVE_WCSCAT_S 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCSCHR
+/** DK3 version of HAVE_WCSCHR.
+*/
+#define DK3_HAVE_WCSCHR 1
+#endif
+
+#ifndef DK3_HAVE_WCSCMP
+/** DK3 version of HAVE_WCSCMP.
+*/
+#define DK3_HAVE_WCSCMP 1
+#endif
+
+#ifndef DK3_HAVE_WCSCPY
+/** DK3 version of HAVE_WCSCPY.
+*/
+#define DK3_HAVE_WCSCPY 1
+#endif
+
+#ifndef DK3_HAVE_WCSCPY_S
+#if (_MSC_VER >= 1700) && (!(DK4_WINDOWS_LEGACY))
+/** DK3 version of HAVE_WCSCPY_S.
+*/
+#define DK3_HAVE_WCSCPY_S 1
+#else
+/** DK3 version of HAVE_WCSCPY_S.
+*/
+#define DK3_HAVE_WCSCPY_S 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCSDUP
+/** DK3 version of HAVE_WCSDUP.
+*/
+#define DK3_HAVE_WCSDUP 0
+#endif
+
+#ifndef DK3_HAVE_WCSICMP
+/** DK3 version of HAVE_WCSICMP.
+*/
+#define DK3_HAVE_WCSICMP 0
+#endif
+
+#ifndef DK3_HAVE_WCSLEN
+/** DK3 version of HAVE_WCSLEN.
+*/
+#define DK3_HAVE_WCSLEN 1
+#endif
+
+#ifndef DK3_HAVE_WCSNCMP
+/** DK3 version of HAVE_WCSNCMP.
+*/
+#define DK3_HAVE_WCSNCMP 1
+#endif
+
+#ifndef DK3_HAVE_WCSNCPY
+/** DK3 version of HAVE_WCSNCPY.
+*/
+#define DK3_HAVE_WCSNCPY 1
+#endif
+
+#ifndef DK3_HAVE_WCSNCPY_S
+#if (_MSC_VER >= 1700) && (!(DK4_WINDOWS_LEGACY))
+/** DK3 version of HAVE_WCSNCPY_S.
+*/
+#define DK3_HAVE_WCSNCPY_S 1
+#else
+/** DK3 version of HAVE_WCSNCPY_S.
+*/
+#define DK3_HAVE_WCSNCPY_S 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCSRCHR
+/** DK3 version of HAVE_WCSRCHR.
+*/
+#define DK3_HAVE_WCSRCHR 1
+#endif
+
+#ifndef DK3_HAVE_WCSTOD
+/** DK3 version of HAVE_WCSTOD.
+*/
+#define DK3_HAVE_WCSTOD 1
+#endif
+
+#ifndef DK3_HAVE_WCSTOIMAX
+#if (_MSC_VER >= 1800) && (!(DK4_WINDOWS_LEGACY))
+/** DK3 version of HAVE_WCSTOIMAX.
+*/
+#define DK3_HAVE_WCSTOIMAX 1
+#else
+/** DK3 version of HAVE_WCSTOIMAX.
+*/
+#define DK3_HAVE_WCSTOIMAX 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCSTOL
+#if (_MSC_VER >= 1700) && (!(DK4_WINDOWS_LEGACY))
+/** DK3 version of HAVE_WCSTOL.
+*/
+#define DK3_HAVE_WCSTOL 1
+#else
+/** DK3 version of HAVE_WCSTOL.
+*/
+#define DK3_HAVE_WCSTOL 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCSTOLL
+#if (_MSC_VER >= 1700) && (!(DK4_WINDOWS_LEGACY))
+/** DK3 version of HAVE_WCSTOLL.
+*/
+#define DK3_HAVE_WCSTOLL 1
+#else
+/** DK3 version of HAVE_WCSTOLL.
+*/
+#define DK3_HAVE_WCSTOLL 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCSTOUL
+#if (_MSC_VER >= 1700) && (!(DK4_WINDOWS_LEGACY))
+/** DK3 version of HAVE_WCSTOUL.
+*/
+#define DK3_HAVE_WCSTOUL 1
+#else
+/** DK3 version of HAVE_WCSTOUL.
+*/
+#define DK3_HAVE_WCSTOUL 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCSTOULL
+#if (_MSC_VER >= 1700) && (!(DK4_WINDOWS_LEGACY))
+/** DK3 version of HAVE_WCSTOULL.
+*/
+#define DK3_HAVE_WCSTOULL 1
+#else
+/** DK3 version of HAVE_WCSTOULL.
+*/
+#define DK3_HAVE_WCSTOULL 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_WCSTOUMAX
+#if (_MSC_VER >= 1800) && (!(DK4_WINDOWS_LEGACY))
+/** DK3 version of HAVE_WCSTOUMAX.
+*/
+#define DK3_HAVE_WCSTOUMAX 1
+#else
+/** DK3 version of HAVE_WCSTOUMAX.
+*/
+#define DK3_HAVE_WCSTOUMAX 0
+#endif
+#endif
+
+#ifndef DK3_HAVE_WINBASE_H
+/** DK3 version of HAVE_WINBASE_H.
+*/
+#define DK3_HAVE_WINBASE_H 1
+#endif
+
+#ifndef DK3_HAVE_WINCON_H
+/** DK3 version of HAVE_WINCON_H.
+*/
+#define DK3_HAVE_WINCON_H 1
+#endif
+
+#ifndef DK3_HAVE_WINDOWS_H
+/** DK3 version of HAVE_WINDOWS_H.
+*/
+#define DK3_HAVE_WINDOWS_H 1
+#endif
+
+#ifndef DK3_HAVE_WINREG_H
+/** DK3 version of HAVE_WINREG_H.
+*/
+#define DK3_HAVE_WINREG_H 1
+#endif
+
+#ifndef DK3_HAVE_WINSOCK2_H
+/** DK3 version of HAVE_WINSOCK2_H.
+*/
+#define DK3_HAVE_WINSOCK2_H 1
+#endif
+
+#ifndef DK3_HAVE_WRITE
+/** DK3 version of HAVE_WRITE.
+*/
+#define DK3_HAVE_WRITE 1
+#endif
+
+#ifndef DK3_HAVE_WS2TCPIP_H
+/** DK3 version of HAVE_WS2TCPIP_H.
+*/
+#define DK3_HAVE_WS2TCPIP_H 1
+#endif
+
+#ifndef DK3_HAVE__CLEARFP
+#if (_MSC_VER >= 1700) && (!(DK4_WINDOWS_LEGACY))
+/** DK3 version of HAVE__CLEARFP.
+*/
+#define DK3_HAVE__CLEARFP 1
+#else
+/** DK3 version of HAVE__CLEARFP.
+*/
+#define DK3_HAVE__CLEARFP 0
+#endif
+#endif
+
+#ifndef DK3_HAVE__FCLOSE
+/** DK3 version of HAVE__FCLOSE.
+*/
+#define DK3_HAVE__FCLOSE 0
+#endif
+
+#ifndef DK3_HAVE__FEOF
+/** DK3 version of HAVE__FEOF.
+*/
+#define DK3_HAVE__FEOF 0
+#endif
+
+#ifndef DK3_HAVE__FERROR
+/** DK3 version of HAVE__FERROR.
+*/
+#define DK3_HAVE__FERROR 0
+#endif
+
+#ifndef DK3_HAVE__FFLUSH
+/** DK3 version of HAVE__FFLUSH.
+*/
+#define DK3_HAVE__FFLUSH 0
+#endif
+
+#ifndef DK3_HAVE__FOPEN
+/** DK3 version of HAVE__FOPEN.
+*/
+#define DK3_HAVE__FOPEN 0
+#endif
+
+#ifndef DK3_HAVE__FREAD
+/** DK3 version of HAVE__FREAD.
+*/
+#define DK3_HAVE__FREAD 1
+#endif
+
+#ifndef DK3_HAVE__FWRITE
+/** DK3 version of HAVE__FWRITE.
+*/
+#define DK3_HAVE__FWRITE 1
+#endif
+
+#ifndef DK3_HAVE__GETCWD
+/** DK3 version of HAVE__GETCWD.
+*/
+#define DK3_HAVE__GETCWD 0
+#endif
+
+#ifndef DK3_HAVE__GETENV_S
+#if (_MSC_VER >= 1700) && (!(DK4_WINDOWS_LEGACY))
+/** DK3 version of HAVE__GETENV_S.
+*/
+#define DK3_HAVE__GETENV_S 1
+#else
+/** DK3 version of HAVE__GETENV_S.
+*/
+#define DK3_HAVE__GETENV_S 0
+#endif
+#endif
+
+#ifndef DK3_HAVE__GETPID
+/** DK3 version of HAVE__GETPID.
+*/
+#define DK3_HAVE__GETPID 0
+#endif
+
+#ifndef DK3_HAVE__LSTAT
+/** DK3 version of HAVE__LSTAT.
+*/
+#define DK3_HAVE__LSTAT 0
+#endif
+
+#ifndef DK3_HAVE__LSTAT32
+/** DK3 version of HAVE__LSTAT32.
+*/
+#define DK3_HAVE__LSTAT32 0
+#endif
+
+#ifndef DK3_HAVE__LSTAT64
+/** DK3 version of HAVE__LSTAT64.
+*/
+#define DK3_HAVE__LSTAT64 0
+#endif
+
+#ifndef DK3_HAVE__MKDIR
+/** DK3 version of HAVE__MKDIR.
+*/
+#define DK3_HAVE__MKDIR 1
+#endif
+
+#ifndef DK3_HAVE__POPEN
+/** DK3 version of HAVE__POPEN.
+*/
+#define DK3_HAVE__POPEN 1
+#endif
+
+#ifndef DK3_HAVE__READ
+/** DK3 version of HAVE__READ.
+*/
+#define DK3_HAVE__READ 0
+#endif
+
+#ifndef DK3_HAVE__RMDIR
+/** DK3 version of HAVE__RMDIR.
+*/
+#define DK3_HAVE__RMDIR 1
+#endif
+
+#ifndef DK3_HAVE__SNPRINTF
+/** DK3 version of HAVE__SNPRINTF.
+*/
+#define DK3_HAVE__SNPRINTF 1
+#endif
+
+#ifndef DK3_HAVE__SNPRINTF_S
+#if (_MSC_VER >= 1) && (!(DK4_WINDOWS_LEGACY))
+/** DK3 version of HAVE__SNPRINTF_S.
+*/
+#define DK3_HAVE__SNPRINTF_S 1
+#else
+/** DK3 version of HAVE__SNPRINTF_S.
+*/
+#define DK3_HAVE__SNPRINTF_S 0
+#endif
+#endif
+
+#ifndef DK3_HAVE__STAT
+/** DK3 version of HAVE__STAT.
+*/
+#define DK3_HAVE__STAT 0
+#endif
+
+#ifndef DK3_HAVE__STAT32
+/** DK3 version of HAVE__STAT32.
+*/
+#define DK3_HAVE__STAT32 0
+#endif
+
+#ifndef DK3_HAVE__STAT64
+/** DK3 version of HAVE__STAT64.
+*/
+#define DK3_HAVE__STAT64 0
+#endif
+
+#ifndef DK3_HAVE__STRDUP
+/** DK3 version of HAVE__STRDUP.
+*/
+#define DK3_HAVE__STRDUP 1
+#endif
+
+#ifndef DK3_HAVE__STRICMP
+/** DK3 version of HAVE__STRICMP.
+*/
+#define DK3_HAVE__STRICMP 1
+#endif
+
+#ifndef DK3_HAVE__UNLINK
+/** DK3 version of HAVE__UNLINK.
+*/
+#define DK3_HAVE__UNLINK 1
+#endif
+
+#ifndef DK3_HAVE__WCSCAT
+/** DK3 version of HAVE__WCSCAT.
+*/
+#define DK3_HAVE__WCSCAT 0
+#endif
+
+#ifndef DK3_HAVE__WCSCHR
+/** DK3 version of HAVE__WCSCHR.
+*/
+#define DK3_HAVE__WCSCHR 0
+#endif
+
+#ifndef DK3_HAVE__WCSCMP
+/** DK3 version of HAVE__WCSCMP.
+*/
+#define DK3_HAVE__WCSCMP 0
+#endif
+
+#ifndef DK3_HAVE__WCSCPY
+/** DK3 version of HAVE__WCSCPY.
+*/
+#define DK3_HAVE__WCSCPY 0
+#endif
+
+#ifndef DK3_HAVE__WCSDUP
+/** DK3 version of HAVE__WCSDUP.
+*/
+#define DK3_HAVE__WCSDUP 1
+#endif
+
+#ifndef DK3_HAVE__WCSICMP
+/** DK3 version of HAVE__WCSICMP.
+*/
+#define DK3_HAVE__WCSICMP 1
+#endif
+
+#ifndef DK3_HAVE__WCSLEN
+/** DK3 version of HAVE__WCSLEN.
+*/
+#define DK3_HAVE__WCSLEN 0
+#endif
+
+#ifndef DK3_HAVE__WCSNCMP
+/** DK3 version of HAVE__WCSNCMP.
+*/
+#define DK3_HAVE__WCSNCMP 0
+#endif
+
+#ifndef DK3_HAVE__WCSNCPY
+/** DK3 version of HAVE__WCSNCPY.
+*/
+#define DK3_HAVE__WCSNCPY 0
+#endif
+
+#ifndef DK3_HAVE__WCSRCHR
+/** DK3 version of HAVE__WCSRCHR.
+*/
+#define DK3_HAVE__WCSRCHR 0
+#endif
+
+#ifndef DK3_HAVE__WFOPEN_S
+#if (_MSC_VER >= 1700) && (!(DK4_WINDOWS_LEGACY))
+/** DK3 version of HAVE__WFOPEN_S.
+*/
+#define DK3_HAVE__WFOPEN_S 1
+#else
+/** DK3 version of HAVE__WFOPEN_S.
+*/
+#define DK3_HAVE__WFOPEN_S 0
+#endif
+#endif
+
+#ifndef DK3_HAVE__WGETENV
+/** DK3 version of HAVE__WGETENV.
+*/
+#define DK3_HAVE__WGETENV 1
+#endif
+
+#ifndef DK3_HAVE__WRITE
+/** DK3 version of HAVE__WRITE.
+*/
+#define DK3_HAVE__WRITE 0
+#endif
+
+#ifndef DK3_TIME_WITH_SYS_TIME
+/** DK3 version of TIME_WITH_SYS_TIME.
+*/
+#define DK3_TIME_WITH_SYS_TIME 0
+#endif
+
+#ifndef DK3_SIZEOF_DOUBLE
+/** DK3 version of SIZEOF_DOUBLE.
+*/
+#define DK3_SIZEOF_DOUBLE 8
+#endif
+
+#ifndef DK3_SIZEOF_INT
+/** DK3 version of SIZEOF_INT.
+*/
+#define DK3_SIZEOF_INT 4
+#endif
+
+#ifndef DK3_SIZEOF_INTMAX_T
+#if (_MSC_VER >= 1700) && (!(DK4_WINDOWS_LEGACY))
+/** DK3 version of SIZEOF_INTMAX_T.
+*/
+#define DK3_SIZEOF_INTMAX_T 8
+#else
+/** DK3 version of SIZEOF_INTMAX_T.
+*/
+#define DK3_SIZEOF_INTMAX_T 0
+#endif
+#endif
+
+#ifndef DK3_SIZEOF_LONG
+/** DK3 version of SIZEOF_LONG.
+*/
+#define DK3_SIZEOF_LONG 4
+#endif
+
+#ifndef DK3_SIZEOF_LONG_DOUBLE
+/** DK3 version of SIZEOF_LONG_DOUBLE.
+*/
+#define DK3_SIZEOF_LONG_DOUBLE 8
+#endif
+
+#ifndef DK3_SIZEOF_LONG_LONG
+/** DK3 version of SIZEOF_LONG_LONG.
+*/
+#define DK3_SIZEOF_LONG_LONG 8
+#endif
+
+#ifndef DK3_SIZEOF_SHORT
+/** DK3 version of SIZEOF_SHORT.
+*/
+#define DK3_SIZEOF_SHORT 2
+#endif
+
+#if defined(WIN64) || defined(_WIN64)
+#ifndef DK3_SIZEOF_SIZE_T
+/** DK3 version of SIZEOF_SIZE_T.
+*/
+#define DK3_SIZEOF_SIZE_T 8
+#endif
+#else
+#ifndef DK3_SIZEOF_SIZE_T
+/** DK3 version of SIZEOF_SIZE_T.
+*/
+#define DK3_SIZEOF_SIZE_T 4
+#endif
+#endif
+
+#ifndef DK3_SIZEOF_WCHAR_T
+/** DK3 version of SIZEOF_WCHAR_T.
+*/
+#define DK3_SIZEOF_WCHAR_T 2
+#endif
+
+#ifndef DK3_HAVE_RFC_2279
+/** DK3 version of HAVE_RFC_2279.
+*/
+#define DK3_HAVE_RFC_2279 0
+#endif
+
+#ifndef DK3_WORDS_BIGENDIAN
+/** DK3 version of WORDS_BIGENDIAN.
+*/
+#define DK3_WORDS_BIGENDIAN 0
+#endif
+
+#else
+/* if DK3_ON_WINDOWS */
+
+
+#ifndef DK3_HAVE_ACOSH
+/** DK3 version of HAVE_ACOSH.
+*/
+#define DK3_HAVE_ACOSH 1
+#endif
+
+#ifndef DK3_HAVE_ACOSHL
+/** DK3 version of HAVE_ACOSHL.
+*/
+#define DK3_HAVE_ACOSHL 1
+#endif
+
+#ifndef DK3_HAVE_ACOSL
+/** DK3 version of HAVE_ACOSL.
+*/
+#define DK3_HAVE_ACOSL 1
+#endif
+
+#ifndef DK3_HAVE_ALLOC_H
+/** DK3 version of HAVE_ALLOC_H.
+*/
+#define DK3_HAVE_ALLOC_H 0
+#endif
+
+#ifndef DK3_HAVE_ARPA_INET_H
+/** DK3 version of HAVE_ARPA_INET_H.
+*/
+#define DK3_HAVE_ARPA_INET_H 1
+#endif
+
+#ifndef DK3_HAVE_ASINH
+/** DK3 version of HAVE_ASINH.
+*/
+#define DK3_HAVE_ASINH 1
+#endif
+
+#ifndef DK3_HAVE_ASINHL
+/** DK3 version of HAVE_ASINHL.
+*/
+#define DK3_HAVE_ASINHL 1
+#endif
+
+#ifndef DK3_HAVE_ASINL
+/** DK3 version of HAVE_ASINL.
+*/
+#define DK3_HAVE_ASINL 1
+#endif
+
+#ifndef DK3_HAVE_ATAN2
+/** DK3 version of HAVE_ATAN2.
+*/
+#define DK3_HAVE_ATAN2 1
+#endif
+
+#ifndef DK3_HAVE_ATAN2L
+/** DK3 version of HAVE_ATAN2L.
+*/
+#define DK3_HAVE_ATAN2L 1
+#endif
+
+#ifndef DK3_HAVE_ATANH
+/** DK3 version of HAVE_ATANH.
+*/
+#define DK3_HAVE_ATANH 1
+#endif
+
+#ifndef DK3_HAVE_ATANHL
+/** DK3 version of HAVE_ATANHL.
+*/
+#define DK3_HAVE_ATANHL 1
+#endif
+
+#ifndef DK3_HAVE_ATANL
+/** DK3 version of HAVE_ATANL.
+*/
+#define DK3_HAVE_ATANL 1
+#endif
+
+#ifndef DK3_HAVE_BACKSLASH
+/** DK3 version of HAVE_BACKSLASH.
+*/
+#define DK3_HAVE_BACKSLASH 0
+#endif
+
+#ifndef DK3_HAVE_BCMP
+/** DK3 version of HAVE_BCMP.
+*/
+#define DK3_HAVE_BCMP 1
+#endif
+
+#ifndef DK3_HAVE_BCOPY
+/** DK3 version of HAVE_BCOPY.
+*/
+#define DK3_HAVE_BCOPY 1
+#endif
+
+#ifndef DK3_HAVE_BZERO
+/** DK3 version of HAVE_BZERO.
+*/
+#define DK3_HAVE_BZERO 1
+#endif
+
+#ifndef DK3_HAVE_BZLIB_H
+/** DK3 version of HAVE_BZLIB_H.
+*/
+#define DK3_HAVE_BZLIB_H 1
+#endif
+
+#ifndef DK3_HAVE_CEIL
+/** DK3 version of HAVE_CEIL.
+*/
+#define DK3_HAVE_CEIL 1
+#endif
+
+#ifndef DK3_HAVE_CEILL
+/** DK3 version of HAVE_CEILL.
+*/
+#define DK3_HAVE_CEILL 1
+#endif
+
+#ifndef DK3_HAVE_CHDIR
+/** DK3 version of HAVE_CHDIR.
+*/
+#define DK3_HAVE_CHDIR 1
+#endif
+
+#ifndef DK3_HAVE_CHMOD
+/** DK3 version of HAVE_CHMOD.
+*/
+#define DK3_HAVE_CHMOD 1
+#endif
+
+#ifndef DK3_HAVE_CHOWN
+/** DK3 version of HAVE_CHOWN.
+*/
+#define DK3_HAVE_CHOWN 1
+#endif
+
+#ifndef DK3_HAVE_CLOSEDIR
+/** DK3 version of HAVE_CLOSEDIR.
+*/
+#define DK3_HAVE_CLOSEDIR 1
+#endif
+
+#ifndef DK3_HAVE_CONIO_H
+/** DK3 version of HAVE_CONIO_H.
+*/
+#define DK3_HAVE_CONIO_H 0
+#endif
+
+#ifndef DK3_HAVE_CONST
+/** DK3 version of HAVE_CONST.
+*/
+#define DK3_HAVE_CONST 1
+#endif
+
+#ifndef DK3_HAVE_COSHL
+/** DK3 version of HAVE_COSHL.
+*/
+#define DK3_HAVE_COSHL 1
+#endif
+
+#ifndef DK3_HAVE_COSL
+/** DK3 version of HAVE_COSL.
+*/
+#define DK3_HAVE_COSL 1
+#endif
+
+#ifndef DK3_HAVE_CTYPE_H
+/** DK3 version of HAVE_CTYPE_H.
+*/
+#define DK3_HAVE_CTYPE_H 1
+#endif
+
+#ifndef DK3_HAVE_DB_CURSOR_C_GET
+/** DK3 version of HAVE_DB_CURSOR_C_GET.
+*/
+#define DK3_HAVE_DB_CURSOR_C_GET 1
+#endif
+
+#ifndef DK3_HAVE_DB_H
+/** DK3 version of HAVE_DB_H.
+*/
+#define DK3_HAVE_DB_H 1
+#endif
+
+#ifndef DK3_HAVE_DEV_RANDOM
+/** DK3 version of HAVE_DEV_RANDOM.
+*/
+#define DK3_HAVE_DEV_RANDOM 1
+#endif
+
+#ifndef DK3_HAVE_DEV_URANDOM
+/** DK3 version of HAVE_DEV_URANDOM.
+*/
+#define DK3_HAVE_DEV_URANDOM 1
+#endif
+
+#ifndef DK3_HAVE_DIRECT_H
+/** DK3 version of HAVE_DIRECT_H.
+*/
+#define DK3_HAVE_DIRECT_H 0
+#endif
+
+#ifndef DK3_HAVE_DIRENT_H
+/** DK3 version of HAVE_DIRENT_H.
+*/
+#define DK3_HAVE_DIRENT_H 1
+#endif
+
+#ifndef DK3_HAVE_DIR_H
+/** DK3 version of HAVE_DIR_H.
+*/
+#define DK3_HAVE_DIR_H 0
+#endif
+
+#ifndef DK3_HAVE_DOS_H
+/** DK3 version of HAVE_DOS_H.
+*/
+#define DK3_HAVE_DOS_H 0
+#endif
+
+#ifndef DK3_HAVE_ENDGRENT
+/** DK3 version of HAVE_ENDGRENT.
+*/
+#define DK3_HAVE_ENDGRENT 1
+#endif
+
+#ifndef DK3_HAVE_ENDPWENT
+/** DK3 version of HAVE_ENDPWENT.
+*/
+#define DK3_HAVE_ENDPWENT 1
+#endif
+
+#ifndef DK3_HAVE_ERRNO_H
+/** DK3 version of HAVE_ERRNO_H.
+*/
+#define DK3_HAVE_ERRNO_H 1
+#endif
+
+#ifndef DK3_HAVE_ERR_H
+/** DK3 version of HAVE_ERR_H.
+*/
+#define DK3_HAVE_ERR_H 1
+#endif
+
+#ifndef DK3_HAVE_EXPL
+/** DK3 version of HAVE_EXPL.
+*/
+#define DK3_HAVE_EXPL 1
+#endif
+
+#ifndef DK3_HAVE_FABS
+/** DK3 version of HAVE_FABS.
+*/
+#define DK3_HAVE_FABS 1
+#endif
+
+#ifndef DK3_HAVE_FABSL
+/** DK3 version of HAVE_FABSL.
+*/
+#define DK3_HAVE_FABSL 1
+#endif
+
+#ifndef DK3_HAVE_FCLOSE
+/** DK3 version of HAVE_FCLOSE.
+*/
+#define DK3_HAVE_FCLOSE 1
+#endif
+
+#ifndef DK3_HAVE_FCNTL_H
+/** DK3 version of HAVE_FCNTL_H.
+*/
+#define DK3_HAVE_FCNTL_H 1
+#endif
+
+#ifndef DK3_HAVE_FENV_H
+/** DK3 version of HAVE_FENV_H.
+*/
+#define DK3_HAVE_FENV_H 1
+#endif
+
+#ifndef DK3_HAVE_FEOF
+/** DK3 version of HAVE_FEOF.
+*/
+#define DK3_HAVE_FEOF 1
+#endif
+
+#ifndef DK3_HAVE_FERROR
+/** DK3 version of HAVE_FERROR.
+*/
+#define DK3_HAVE_FERROR 1
+#endif
+
+#ifndef DK3_HAVE_FETESTEXCEPT
+/** DK3 version of HAVE_FETESTEXCEPT.
+*/
+#define DK3_HAVE_FETESTEXCEPT 0
+#endif
+
+#ifndef DK3_HAVE_FFLUSH
+/** DK3 version of HAVE_FFLUSH.
+*/
+#define DK3_HAVE_FFLUSH 1
+#endif
+
+#ifndef DK3_HAVE_FLOAT_H
+/** DK3 version of HAVE_FLOAT_H.
+*/
+#define DK3_HAVE_FLOAT_H 1
+#endif
+
+#ifndef DK3_HAVE_FLOOR
+/** DK3 version of HAVE_FLOOR.
+*/
+#define DK3_HAVE_FLOOR 1
+#endif
+
+#ifndef DK3_HAVE_FLOORL
+/** DK3 version of HAVE_FLOORL.
+*/
+#define DK3_HAVE_FLOORL 1
+#endif
+
+#ifndef DK3_HAVE_FNCASEINS
+/** DK3 version of HAVE_FNCASEINS.
+*/
+#define DK3_HAVE_FNCASEINS 0
+#endif
+
+#ifndef DK3_HAVE_FOPEN
+/** DK3 version of HAVE_FOPEN.
+*/
+#define DK3_HAVE_FOPEN 1
+#endif
+
+#ifndef DK3_HAVE_FOPEN64
+/** DK3 version of HAVE_FOPEN64.
+*/
+#define DK3_HAVE_FOPEN64 1
+#endif
+
+#ifndef DK3_HAVE_FOPEN_S
+/** DK3 version of HAVE_FOPEN_S.
+*/
+#define DK3_HAVE_FOPEN_S 0
+#endif
+
+#ifndef DK3_HAVE_FORK
+/** DK3 version of HAVE_FORK.
+*/
+#define DK3_HAVE_FORK 1
+#endif
+
+#ifndef DK3_HAVE_FPCLASSIFY
+/** DK3 version of HAVE_FPCLASSIFY.
+*/
+#define DK3_HAVE_FPCLASSIFY 1
+#endif
+
+#ifndef DK3_HAVE_FREAD
+/** DK3 version of HAVE_FREAD.
+*/
+#define DK3_HAVE_FREAD 1
+#endif
+
+#ifndef DK3_HAVE_FREE
+/** DK3 version of HAVE_FREE.
+*/
+#define DK3_HAVE_FREE 1
+#endif
+
+#ifndef DK3_HAVE_FWRITE
+/** DK3 version of HAVE_FWRITE.
+*/
+#define DK3_HAVE_FWRITE 1
+#endif
+
+#ifndef DK3_HAVE_GDBM_H
+/** DK3 version of HAVE_GDBM_H.
+*/
+#define DK3_HAVE_GDBM_H 1
+#endif
+
+#ifndef DK3_HAVE_GETADDRINFO
+/** DK3 version of HAVE_GETADDRINFO.
+*/
+#define DK3_HAVE_GETADDRINFO 1
+#endif
+
+#ifndef DK3_HAVE_GETCWD
+/** DK3 version of HAVE_GETCWD.
+*/
+#define DK3_HAVE_GETCWD 1
+#endif
+
+#ifndef DK3_HAVE_GETENV
+/** DK3 version of HAVE_GETENV.
+*/
+#define DK3_HAVE_GETENV 1
+#endif
+
+#ifndef DK3_HAVE_GETEUID
+/** DK3 version of HAVE_GETEUID.
+*/
+#define DK3_HAVE_GETEUID 1
+#endif
+
+#ifndef DK3_HAVE_GETGRENT
+/** DK3 version of HAVE_GETGRENT.
+*/
+#define DK3_HAVE_GETGRENT 1
+#endif
+
+#ifndef DK3_HAVE_GETGRGID
+/** DK3 version of HAVE_GETGRGID.
+*/
+#define DK3_HAVE_GETGRGID 1
+#endif
+
+#ifndef DK3_HAVE_GETGRNAM
+/** DK3 version of HAVE_GETGRNAM.
+*/
+#define DK3_HAVE_GETGRNAM 1
+#endif
+
+#ifndef DK3_HAVE_GETHOSTBYNAME
+/** DK3 version of HAVE_GETHOSTBYNAME.
+*/
+#define DK3_HAVE_GETHOSTBYNAME 1
+#endif
+
+#ifndef DK3_HAVE_GETHOSTNAME
+/** DK3 version of HAVE_GETHOSTNAME.
+*/
+#define DK3_HAVE_GETHOSTNAME 1
+#endif
+
+#ifndef DK3_HAVE_GETPEERNAME
+/** DK3 version of HAVE_GETPEERNAME.
+*/
+#define DK3_HAVE_GETPEERNAME 1
+#endif
+
+#ifndef DK3_HAVE_GETPID
+/** DK3 version of HAVE_GETPID.
+*/
+#define DK3_HAVE_GETPID 1
+#endif
+
+#ifndef DK3_HAVE_GETPWENT
+/** DK3 version of HAVE_GETPWENT.
+*/
+#define DK3_HAVE_GETPWENT 1
+#endif
+
+#ifndef DK3_HAVE_GETPWNAM
+/** DK3 version of HAVE_GETPWNAM.
+*/
+#define DK3_HAVE_GETPWNAM 1
+#endif
+
+#ifndef DK3_HAVE_GETPWUID
+/** DK3 version of HAVE_GETPWUID.
+*/
+#define DK3_HAVE_GETPWUID 1
+#endif
+
+#ifndef DK3_HAVE_GETRLIMIT
+/** DK3 version of HAVE_GETRLIMIT.
+*/
+#define DK3_HAVE_GETRLIMIT 1
+#endif
+
+#ifndef DK3_HAVE_GETSOCKNAME
+/** DK3 version of HAVE_GETSOCKNAME.
+*/
+#define DK3_HAVE_GETSOCKNAME 1
+#endif
+
+#ifndef DK3_HAVE_GETUID
+/** DK3 version of HAVE_GETUID.
+*/
+#define DK3_HAVE_GETUID 1
+#endif
+
+#ifndef DK3_HAVE_GRP_H
+/** DK3 version of HAVE_GRP_H.
+*/
+#define DK3_HAVE_GRP_H 1
+#endif
+
+#ifndef DK3_HAVE_HTONL
+/** DK3 version of HAVE_HTONL.
+*/
+#define DK3_HAVE_HTONL 1
+#endif
+
+#ifndef DK3_HAVE_IEEE_754_DOUBLE
+/** DK3 version of HAVE_IEEE_754_DOUBLE.
+*/
+#define DK3_HAVE_IEEE_754_DOUBLE 1
+#endif
+
+#ifndef DK3_HAVE_IN6_ADDR
+/** DK3 version of HAVE_IN6_ADDR.
+*/
+#define DK3_HAVE_IN6_ADDR 0
+#endif
+
+#ifndef DK3_HAVE_INET_ADDR
+/** DK3 version of HAVE_INET_ADDR.
+*/
+#define DK3_HAVE_INET_ADDR 1
+#endif
+
+#ifndef DK3_HAVE_INET_ATON
+/** DK3 version of HAVE_INET_ATON.
+*/
+#define DK3_HAVE_INET_ATON 1
+#endif
+
+#ifndef DK3_HAVE_INET_PTON
+/** DK3 version of HAVE_INET_PTON.
+*/
+#define DK3_HAVE_INET_PTON 1
+#endif
+
+#ifndef DK3_HAVE_INITSTATE
+/** DK3 version of HAVE_INITSTATE.
+*/
+#define DK3_HAVE_INITSTATE 1
+#endif
+
+#ifndef DK3_HAVE_INODES
+/** DK3 version of HAVE_INODES.
+*/
+#define DK3_HAVE_INODES 1
+#endif
+
+#ifndef DK3_HAVE_INTMAX_T
+/** DK3 version of HAVE_INTMAX_T.
+*/
+#define DK3_HAVE_INTMAX_T 1
+#endif
+
+#ifndef DK3_HAVE_INTTYPES_H
+/** DK3 version of HAVE_INTTYPES_H.
+*/
+#define DK3_HAVE_INTTYPES_H 1
+#endif
+
+#ifndef DK3_HAVE_IN_ADDR
+/** DK3 version of HAVE_IN_ADDR.
+*/
+#define DK3_HAVE_IN_ADDR 0
+#endif
+
+#ifndef DK3_HAVE_IO_H
+/** DK3 version of HAVE_IO_H.
+*/
+#define DK3_HAVE_IO_H 0
+#endif
+
+#ifndef DK3_HAVE_ISATTY
+/** DK3 version of HAVE_ISATTY.
+*/
+#define DK3_HAVE_ISATTY 1
+#endif
+
+#ifndef DK3_HAVE_ISFINITE
+/** DK3 version of HAVE_ISFINITE.
+*/
+#define DK3_HAVE_ISFINITE 1
+#endif
+
+#ifndef DK3_HAVE_ISNORMAL
+/** DK3 version of HAVE_ISNORMAL.
+*/
+#define DK3_HAVE_ISNORMAL 1
+#endif
+
+#ifndef DK3_HAVE_JPEGLIB_H
+/** DK3 version of HAVE_JPEGLIB_H.
+*/
+#define DK3_HAVE_JPEGLIB_H 1
+#endif
+
+#ifndef DK3_HAVE_LABS
+/** DK3 version of HAVE_LABS.
+*/
+#define DK3_HAVE_LABS 1
+#endif
+
+#ifndef DK3_HAVE_LARGEFILE64_SOURCE
+/** DK3 version of HAVE_LARGEFILE64_SOURCE.
+*/
+#define DK3_HAVE_LARGEFILE64_SOURCE 1
+#endif
+
+#ifndef DK3_HAVE_LIBNETSNMP
+/** DK3 version of HAVE_LIBNETSNMP.
+*/
+#define DK3_HAVE_LIBNETSNMP 1
+#endif
+
+#ifndef DK3_HAVE_LIMITS_H
+/** DK3 version of HAVE_LIMITS_H.
+*/
+#define DK3_HAVE_LIMITS_H 1
+#endif
+
+#ifndef DK3_HAVE_LOCALE_H
+/** DK3 version of HAVE_LOCALE_H.
+*/
+#define DK3_HAVE_LOCALE_H 1
+#endif
+
+#ifndef DK3_HAVE_LOCALTIME
+/** DK3 version of HAVE_LOCALTIME.
+*/
+#define DK3_HAVE_LOCALTIME 1
+#endif
+
+#ifndef DK3_HAVE_LOCALTIME
+/** DK3 version of HAVE_LOCALTIME.
+*/
+#define DK3_HAVE_LOCALTIME 1
+#endif
+
+#ifndef DK3_HAVE_LOCALTIME_R
+/** DK3 version of HAVE_LOCALTIME_R.
+*/
+#define DK3_HAVE_LOCALTIME_R 1
+#endif
+
+#ifndef DK3_HAVE_LOCALTIME_S
+/** DK3 version of HAVE_LOCALTIME_S.
+*/
+#define DK3_HAVE_LOCALTIME_S 0
+#endif
+
+#ifndef DK3_HAVE_LOGL
+/** DK3 version of HAVE_LOGL.
+*/
+#define DK3_HAVE_LOGL 1
+#endif
+
+#ifndef DK3_HAVE_LONG_DOUBLE
+/** DK3 version of HAVE_LONG_DOUBLE.
+*/
+#define DK3_HAVE_LONG_DOUBLE 1
+#endif
+
+#ifndef DK3_HAVE_LONG_LONG
+/** DK3 version of HAVE_LONG_LONG.
+*/
+#define DK3_HAVE_LONG_LONG 1
+#endif
+
+#ifndef DK3_HAVE_LPRNG_H
+/** DK3 version of HAVE_LPRNG_H.
+*/
+#define DK3_HAVE_LPRNG_H 0
+#endif
+
+#ifndef DK3_HAVE_LRAND48
+/** DK3 version of HAVE_LRAND48.
+*/
+#define DK3_HAVE_LRAND48 1
+#endif
+
+#ifndef DK3_HAVE_LSTAT
+/** DK3 version of HAVE_LSTAT.
+*/
+#define DK3_HAVE_LSTAT 1
+#endif
+
+#ifndef DK3_HAVE_LSTAT32
+/** DK3 version of HAVE_LSTAT32.
+*/
+#define DK3_HAVE_LSTAT32 0
+#endif
+
+#ifndef DK3_HAVE_LSTAT64
+/** DK3 version of HAVE_LSTAT64.
+*/
+#define DK3_HAVE_LSTAT64 1
+#endif
+
+#ifndef DK3_HAVE_MALLOC
+/** DK3 version of HAVE_MALLOC.
+*/
+#define DK3_HAVE_MALLOC 1
+#endif
+
+#ifndef DK3_HAVE_MALLOC_H
+/** DK3 version of HAVE_MALLOC_H.
+*/
+#define DK3_HAVE_MALLOC_H 1
+#endif
+
+#ifndef DK3_HAVE_MATH_H
+/** DK3 version of HAVE_MATH_H.
+*/
+#define DK3_HAVE_MATH_H 1
+#endif
+
+#ifndef DK3_HAVE_MEMCMP
+/** DK3 version of HAVE_MEMCMP.
+*/
+#define DK3_HAVE_MEMCMP 1
+#endif
+
+#ifndef DK3_HAVE_MEMCPY
+/** DK3 version of HAVE_MEMCPY.
+*/
+#define DK3_HAVE_MEMCPY 1
+#endif
+
+#ifndef DK3_HAVE_MEMSET
+/** DK3 version of HAVE_MEMSET.
+*/
+#define DK3_HAVE_MEMSET 1
+#endif
+
+#ifndef DK3_HAVE_MKDIR
+/** DK3 version of HAVE_MKDIR.
+*/
+#define DK3_HAVE_MKDIR 1
+#endif
+
+#ifndef DK3_HAVE_MKDIR2
+/** DK3 version of HAVE_MKDIR2.
+*/
+#define DK3_HAVE_MKDIR2 1
+#endif
+
+#ifndef DK3_HAVE_MPCTL
+/** DK3 version of HAVE_MPCTL.
+*/
+#define DK3_HAVE_MPCTL 0
+#endif
+
+#ifndef DK3_HAVE_MYSQL_LIBRARY_END
+/** DK3 version of HAVE_MYSQL_LIBRARY_END.
+*/
+#define DK3_HAVE_MYSQL_LIBRARY_END 0
+#endif
+
+#ifndef DK3_HAVE_MYSQL_LIBRARY_INIT
+/** DK3 version of HAVE_MYSQL_LIBRARY_INIT.
+*/
+#define DK3_HAVE_MYSQL_LIBRARY_INIT 0
+#endif
+
+#ifndef DK3_HAVE_MYSQL_MYSQL_H
+/** DK3 version of HAVE_MYSQL_MYSQL_H.
+*/
+#define DK3_HAVE_MYSQL_MYSQL_H 1
+#endif
+
+#ifndef DK3_HAVE_MYSQL_H
+/** DK3 version of HAVE_MYSQL_H.
+*/
+#define DK3_HAVE_MYSQL_H 0
+#endif
+
+#ifndef DK3_HAVE_MYSQL_SET_CHARACTER_SET
+/** DK3 version of HAVE_MYSQL_SET_CHARACTER_SET.
+*/
+#define DK3_HAVE_MYSQL_SET_CHARACTER_SET 0
+#endif
+
+#ifndef DK3_HAVE_NDBM_H
+/** DK3 version of HAVE_NDBM_H.
+*/
+#define DK3_HAVE_NDBM_H 0
+#endif
+
+#ifndef DK3_HAVE_NETDB_H
+/** DK3 version of HAVE_NETDB_H.
+*/
+#define DK3_HAVE_NETDB_H 1
+#endif
+
+#ifndef DK3_HAVE_NETINET_IN_H
+/** DK3 version of HAVE_NETINET_IN_H.
+*/
+#define DK3_HAVE_NETINET_IN_H 1
+#endif
+
+#ifndef DK3_HAVE_SNMP_ENABLE_FILELOG
+/** DK3 version of HAVE_SNMP_ENABLE_FILELOG.
+*/
+#define DK3_HAVE_SNMP_ENABLE_FILELOG 1
+#endif
+
+#ifndef DK3_HAVE_NRAND48
+/** DK3 version of HAVE_NRAND48.
+*/
+#define DK3_HAVE_NRAND48 1
+#endif
+
+#ifndef DK3_HAVE_OPENDIR
+/** DK3 version of HAVE_OPENDIR.
+*/
+#define DK3_HAVE_OPENDIR 1
+#endif
+
+#ifndef DK3_HAVE_OPENSSL_MD5_H
+/** DK3 version of HAVE_OPENSSL_MD5_H.
+*/
+#define DK3_HAVE_OPENSSL_MD5_H 1
+#endif
+
+#ifndef DK3_HAVE_OPENSSL_RAND_H
+/** DK3 version of HAVE_OPENSSL_RAND_H.
+*/
+#define DK3_HAVE_OPENSSL_RAND_H 1
+#endif
+
+#ifndef DK3_HAVE_OPENSSL_RIPEMD_H
+/** DK3 version of HAVE_OPENSSL_RIPEMD_H.
+*/
+#define DK3_HAVE_OPENSSL_RIPEMD_H 1
+#endif
+
+#ifndef DK3_HAVE_OPENSSL_SHA_H
+/** DK3 version of HAVE_OPENSSL_SHA_H.
+*/
+#define DK3_HAVE_OPENSSL_SHA_H 1
+#endif
+
+#ifndef DK3_HAVE_PNG_GET_PIXELS_PER_INCH
+/** DK3 version of HAVE_PNG_GET_PIXELS_PER_INCH.
+*/
+#define DK3_HAVE_PNG_GET_PIXELS_PER_INCH 0
+#endif
+
+#ifndef DK3_HAVE_PNG_H
+/** DK3 version of HAVE_PNG_H.
+*/
+#define DK3_HAVE_PNG_H 1
+#endif
+
+#ifndef DK3_HAVE_POPEN
+/** DK3 version of HAVE_POPEN.
+*/
+#define DK3_HAVE_POPEN 1
+#endif
+
+#ifndef DK3_HAVE_PROCESS_H
+/** DK3 version of HAVE_PROCESS_H.
+*/
+#define DK3_HAVE_PROCESS_H 0
+#endif
+
+#ifndef DK3_HAVE_PTHREAD_H
+/** DK3 version of HAVE_PTHREAD_H.
+*/
+#define DK3_HAVE_PTHREAD_H 1
+#endif
+
+#ifndef DK3_HAVE_PWD_H
+/** DK3 version of HAVE_PWD_H.
+*/
+#define DK3_HAVE_PWD_H 1
+#endif
+
+#ifndef DK3_HAVE_RAND
+/** DK3 version of HAVE_RAND.
+*/
+#define DK3_HAVE_RAND 1
+#endif
+
+#ifndef DK3_HAVE_RANDOM
+/** DK3 version of HAVE_RANDOM.
+*/
+#define DK3_HAVE_RANDOM 1
+#endif
+
+#ifndef DK3_HAVE_READ
+/** DK3 version of HAVE_READ.
+*/
+#define DK3_HAVE_READ 1
+#endif
+
+#ifndef DK3_HAVE_READDIR
+/** DK3 version of HAVE_READDIR.
+*/
+#define DK3_HAVE_READDIR 1
+#endif
+
+#ifndef DK3_HAVE_RFC_2249
+/** DK3 version of HAVE_RFC_2249.
+*/
+#define DK3_HAVE_RFC_2249 0
+#endif
+
+#ifndef DK3_HAVE_RINT
+/** DK3 version of HAVE_RINT.
+*/
+#define DK3_HAVE_RINT 1
+#endif
+
+#ifndef DK3_HAVE_RINTL
+/** DK3 version of HAVE_RINTL.
+*/
+#define DK3_HAVE_RINTL 1
+#endif
+
+#ifndef DK3_HAVE_RMDIR
+/** DK3 version of HAVE_RMDIR.
+*/
+#define DK3_HAVE_RMDIR 1
+#endif
+
+#ifndef DK3_HAVE_SEED48
+/** DK3 version of HAVE_SEED48.
+*/
+#define DK3_HAVE_SEED48 1
+#endif
+
+#ifndef DK3_HAVE_SELECT
+/** DK3 version of HAVE_SELECT.
+*/
+#define DK3_HAVE_SELECT 1
+#endif
+
+#ifndef DK3_HAVE_SETGID
+/** DK3 version of HAVE_SETGID.
+*/
+#define DK3_HAVE_SETGID 1
+#endif
+
+#ifndef DK3_HAVE_SETGRENT
+/** DK3 version of HAVE_SETGRENT.
+*/
+#define DK3_HAVE_SETGRENT 1
+#endif
+
+#ifndef DK3_HAVE_SETJMP_H
+/** DK3 version of HAVE_SETJMP_H.
+*/
+#define DK3_HAVE_SETJMP_H 1
+#endif
+
+#ifndef DK3_HAVE_SETLOCALE
+/** DK3 version of HAVE_SETLOCALE.
+*/
+#define DK3_HAVE_SETLOCALE 1
+#endif
+
+#ifndef DK3_HAVE_SETPGRP
+/** DK3 version of HAVE_SETPGRP.
+*/
+#define DK3_HAVE_SETPGRP 1
+#endif
+
+#ifndef DK3_HAVE_SETPWENT
+/** DK3 version of HAVE_SETPWENT.
+*/
+#define DK3_HAVE_SETPWENT 1
+#endif
+
+#ifndef DK3_HAVE_SETSID
+/** DK3 version of HAVE_SETSID.
+*/
+#define DK3_HAVE_SETSID 1
+#endif
+
+#ifndef DK3_HAVE_SETSOCKOPT
+/** DK3 version of HAVE_SETSOCKOPT.
+*/
+#define DK3_HAVE_SETSOCKOPT 1
+#endif
+
+#ifndef DK3_HAVE_SETSTATE
+/** DK3 version of HAVE_SETSTATE.
+*/
+#define DK3_HAVE_SETSTATE 1
+#endif
+
+#ifndef DK3_HAVE_SETUID
+/** DK3 version of HAVE_SETUID.
+*/
+#define DK3_HAVE_SETUID 1
+#endif
+
+#ifndef DK3_HAVE_SHA224
+/** DK3 version of HAVE_SHA224.
+*/
+#define DK3_HAVE_SHA224 1
+#endif
+
+#ifndef DK3_HAVE_SHA256
+/** DK3 version of HAVE_SHA256.
+*/
+#define DK3_HAVE_SHA256 1
+#endif
+
+#ifndef DK3_HAVE_SHA384
+/** DK3 version of HAVE_SHA384.
+*/
+#define DK3_HAVE_SHA384 1
+#endif
+
+#ifndef DK3_HAVE_SHA512
+/** DK3 version of HAVE_SHA512.
+*/
+#define DK3_HAVE_SHA512 1
+#endif
+
+#ifndef DK3_HAVE_SHADOW_H
+/** DK3 version of HAVE_SHADOW_H.
+*/
+#define DK3_HAVE_SHADOW_H 1
+#endif
+
+#ifndef DK3_HAVE_SIGACTION
+/** DK3 version of HAVE_SIGACTION.
+*/
+#define DK3_HAVE_SIGACTION 1
+#endif
+
+#ifndef DK3_HAVE_SIGNAL
+/** DK3 version of HAVE_SIGNAL.
+*/
+#define DK3_HAVE_SIGNAL 1
+#endif
+
+#ifndef DK3_HAVE_SIGNAL_H
+/** DK3 version of HAVE_SIGNAL_H.
+*/
+#define DK3_HAVE_SIGNAL_H 1
+#endif
+
+#ifndef DK3_HAVE_SIGSET
+/** DK3 version of HAVE_SIGSET.
+*/
+#define DK3_HAVE_SIGSET 1
+#endif
+
+#ifndef DK3_HAVE_SIG_ATOMIC_T
+/** DK3 version of HAVE_SIG_ATOMIC_T.
+*/
+#define DK3_HAVE_SIG_ATOMIC_T 1
+#endif
+
+#ifndef DK3_HAVE_SINHL
+/** DK3 version of HAVE_SINHL.
+*/
+#define DK3_HAVE_SINHL 1
+#endif
+
+#ifndef DK3_HAVE_SINL
+/** DK3 version of HAVE_SINL.
+*/
+#define DK3_HAVE_SINL 1
+#endif
+
+#ifndef DK3_HAVE_SNPRINTF
+/** DK3 version of HAVE_SNPRINTF.
+*/
+#define DK3_HAVE_SNPRINTF 1
+#endif
+
+#ifndef DK3_HAVE_SNWPRINTF
+/** DK3 version of HAVE_SNWPRINTF.
+*/
+#define DK3_HAVE_SNWPRINTF 0
+#endif
+
+#ifndef DK3_HAVE_SOCKET
+/** DK3 version of HAVE_SOCKET.
+*/
+#define DK3_HAVE_SOCKET 1
+#endif
+
+#ifndef DK3_HAVE_SOCKLEN_T
+/** DK3 version of HAVE_SOCKLEN_T.
+*/
+#define DK3_HAVE_SOCKLEN_T 1
+#endif
+
+#ifndef DK3_HAVE_SPRINTF_S
+/** DK3 version of HAVE_SPRINTF_S.
+*/
+#define DK3_HAVE_SPRINTF_S 0
+#endif
+
+#ifndef DK3_HAVE_SQRTL
+/** DK3 version of HAVE_SQRTL.
+*/
+#define DK3_HAVE_SQRTL 1
+#endif
+
+#ifndef DK3_HAVE_SRAND
+/** DK3 version of HAVE_SRAND.
+*/
+#define DK3_HAVE_SRAND 1
+#endif
+
+#ifndef DK3_HAVE_SSCANF_S
+/** DK3 version of HAVE_SSCANF_S.
+*/
+#define DK3_HAVE_SSCANF_S 0
+#endif
+
+#ifndef DK3_HAVE_SSIZE_T
+/** DK3 version of HAVE_SSIZE_T.
+*/
+#define DK3_HAVE_SSIZE_T 1
+#endif
+
+#ifndef DK3_HAVE_STAT
+/** DK3 version of HAVE_STAT.
+*/
+#define DK3_HAVE_STAT 1
+#endif
+
+#ifndef DK3_HAVE_STAT32
+/** DK3 version of HAVE_STAT32.
+*/
+#define DK3_HAVE_STAT32 0
+#endif
+
+#ifndef DK3_HAVE_STAT64
+/** DK3 version of HAVE_STAT64.
+*/
+#define DK3_HAVE_STAT64 1
+#endif
+
+#ifndef DK3_HAVE_STDARG_H
+/** DK3 version of HAVE_STDARG_H.
+*/
+#define DK3_HAVE_STDARG_H 1
+#endif
+
+#ifndef DK3_HAVE_STDDEF_H
+/** DK3 version of HAVE_STDDEF_H.
+*/
+#define DK3_HAVE_STDDEF_H 1
+#endif
+
+#ifndef DK3_HAVE_STDINT_H
+/** DK3 version of HAVE_STDINT_H.
+*/
+#define DK3_HAVE_STDINT_H 1
+#endif
+
+#ifndef DK3_HAVE_STDIO_H
+/** DK3 version of HAVE_STDIO_H.
+*/
+#define DK3_HAVE_STDIO_H 1
+#endif
+
+#ifndef DK3_HAVE_STDLIB_H
+/** DK3 version of HAVE_STDLIB_H.
+*/
+#define DK3_HAVE_STDLIB_H 1
+#endif
+
+#ifndef DK3_HAVE_STRCASECMP
+/** DK3 version of HAVE_STRCASECMP.
+*/
+#define DK3_HAVE_STRCASECMP 1
+#endif
+
+#ifndef DK3_HAVE_STRCAT
+/** DK3 version of HAVE_STRCAT.
+*/
+#define DK3_HAVE_STRCAT 1
+#endif
+
+#ifndef DK3_HAVE_STRCAT_S
+/** DK3 version of HAVE_STRCAT_S.
+*/
+#define DK3_HAVE_STRCAT_S 0
+#endif
+
+#ifndef DK3_HAVE_STRCHR
+/** DK3 version of HAVE_STRCHR.
+*/
+#define DK3_HAVE_STRCHR 1
+#endif
+
+#ifndef DK3_HAVE_STRCMP
+/** DK3 version of HAVE_STRCMP.
+*/
+#define DK3_HAVE_STRCMP 1
+#endif
+
+#ifndef DK3_HAVE_STRCPY
+/** DK3 version of HAVE_STRCPY.
+*/
+#define DK3_HAVE_STRCPY 1
+#endif
+
+#ifndef DK3_HAVE_STRCPY_S
+/** DK3 version of HAVE_STRCPY_S.
+*/
+#define DK3_HAVE_STRCPY_S 0
+#endif
+
+#ifndef DK3_HAVE_STRDUP
+/** DK3 version of HAVE_STRDUP.
+*/
+#define DK3_HAVE_STRDUP 1
+#endif
+
+#ifndef DK3_HAVE_STRERROR
+/** DK3 version of HAVE_STRERROR.
+*/
+#define DK3_HAVE_STRERROR 1
+#endif
+
+#ifndef DK3_HAVE_STRICMP
+/** DK3 version of HAVE_STRICMP.
+*/
+#define DK3_HAVE_STRICMP 0
+#endif
+
+#ifndef DK3_HAVE_STRINGS_H
+/** DK3 version of HAVE_STRINGS_H.
+*/
+#define DK3_HAVE_STRINGS_H 1
+#endif
+
+#ifndef DK3_HAVE_STRING_H
+/** DK3 version of HAVE_STRING_H.
+*/
+#define DK3_HAVE_STRING_H 1
+#endif
+
+#ifndef DK3_HAVE_STRLEN
+/** DK3 version of HAVE_STRLEN.
+*/
+#define DK3_HAVE_STRLEN 1
+#endif
+
+#ifndef DK3_HAVE_STRNCMP
+/** DK3 version of HAVE_STRNCMP.
+*/
+#define DK3_HAVE_STRNCMP 1
+#endif
+
+#ifndef DK3_HAVE_STRNCPY
+/** DK3 version of HAVE_STRNCPY.
+*/
+#define DK3_HAVE_STRNCPY 1
+#endif
+
+#ifndef DK3_HAVE_STRNCPY_S
+/** DK3 version of HAVE_STRNCPY_S.
+*/
+#define DK3_HAVE_STRNCPY_S 0
+#endif
+
+#ifndef DK3_HAVE_STROPTS_H
+/** DK3 version of HAVE_STROPTS_H.
+*/
+#define DK3_HAVE_STROPTS_H 0
+#endif
+
+#ifndef DK3_HAVE_STRRCHR
+/** DK3 version of HAVE_STRRCHR.
+*/
+#define DK3_HAVE_STRRCHR 1
+#endif
+
+#ifndef DK3_HAVE_STRTOD
+/** DK3 version of HAVE_STRTOD.
+*/
+#define DK3_HAVE_STRTOD 1
+#endif
+
+#ifndef DK3_HAVE_STRTOIMAX
+/** DK3 version of HAVE_STRTOIMAX.
+*/
+#define DK3_HAVE_STRTOIMAX 1
+#endif
+
+#ifndef DK3_HAVE_STRTOL
+/** DK3 version of HAVE_STRTOL.
+*/
+#define DK3_HAVE_STRTOL 1
+#endif
+
+#ifndef DK3_HAVE_STRTOLL
+/** DK3 version of HAVE_STRTOLL.
+*/
+#define DK3_HAVE_STRTOLL 1
+#endif
+
+#ifndef DK3_HAVE_STRTOUL
+/** DK3 version of HAVE_STRTOUL.
+*/
+#define DK3_HAVE_STRTOUL 1
+#endif
+
+#ifndef DK3_HAVE_STRTOULL
+/** DK3 version of HAVE_STRTOULL.
+*/
+#define DK3_HAVE_STRTOULL 1
+#endif
+
+#ifndef DK3_HAVE_STRTOUMAX
+/** DK3 version of HAVE_STRTOUMAX.
+*/
+#define DK3_HAVE_STRTOUMAX 1
+#endif
+
+#ifndef DK3_HAVE_STRUCT_ADDRINFO
+/** DK3 version of HAVE_STRUCT_ADDRINFO.
+*/
+#define DK3_HAVE_STRUCT_ADDRINFO 1
+#endif
+
+#ifndef DK3_HAVE_STRUCT_SOCKADDR_IN
+/** DK3 version of HAVE_STRUCT_SOCKADDR_IN.
+*/
+#define DK3_HAVE_STRUCT_SOCKADDR_IN 1
+#endif
+
+#ifndef DK3_HAVE_STRUCT_SOCKADDR_IN6
+/** DK3 version of HAVE_STRUCT_SOCKADDR_IN6.
+*/
+#define DK3_HAVE_STRUCT_SOCKADDR_IN6 1
+#endif
+
+#ifndef DK3_HAVE_STRUCT_SOCKADDR_STORAGE
+/** DK3 version of HAVE_STRUCT_SOCKADDR_STORAGE.
+*/
+#define DK3_HAVE_STRUCT_SOCKADDR_STORAGE 1
+#endif
+
+#ifndef DK3_HAVE_STRUCT_SOCKADDR_UN
+/** DK3 version of HAVE_STRUCT_SOCKADDR_UN.
+*/
+#define DK3_HAVE_STRUCT_SOCKADDR_UN 1
+#endif
+
+#ifndef DK3_HAVE_SWSCANF_S
+/** DK3 version of HAVE_SWSCANF_S.
+*/
+#define DK3_HAVE_SWSCANF_S 0
+#endif
+
+#ifndef DK3_HAVE_SYSCONF
+/** DK3 version of HAVE_SYSCONF.
+*/
+#define DK3_HAVE_SYSCONF 1
+#endif
+
+#ifndef DK3_HAVE_SYSCTL
+/** DK3 version of HAVE_SYSCTL.
+*/
+#define DK3_HAVE_SYSCTL 1
+#endif
+
+#ifndef DK3_HAVE_SYSLOG
+/** DK3 version of HAVE_SYSLOG.
+*/
+#define DK3_HAVE_SYSLOG 1
+#endif
+
+#ifndef DK3_HAVE_SYSLOG_H
+/** DK3 version of HAVE_SYSLOG_H.
+*/
+#define DK3_HAVE_SYSLOG_H 1
+#endif
+
+#ifndef DK3_HAVE_SYSRES_H
+/** DK3 version of HAVE_SYSRES_H.
+*/
+#define DK3_HAVE_SYSRES_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_FILE_H
+/** DK3 version of HAVE_SYS_FILE_H.
+*/
+#define DK3_HAVE_SYS_FILE_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_PARAM_H
+/** DK3 version of HAVE_SYS_PARAM_H.
+*/
+#define DK3_HAVE_SYS_PARAM_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_RESOURCE_H
+/** DK3 version of HAVE_SYS_RESOURCE_H.
+*/
+#define DK3_HAVE_SYS_RESOURCE_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_SOCKET_H
+/** DK3 version of HAVE_SYS_SOCKET_H.
+*/
+#define DK3_HAVE_SYS_SOCKET_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_STATVFS_H
+/** DK3 version of HAVE_SYS_STATVFS_H.
+*/
+#define DK3_HAVE_SYS_STATVFS_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_STAT_H
+/** DK3 version of HAVE_SYS_STAT_H.
+*/
+#define DK3_HAVE_SYS_STAT_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_STROPTS_H
+/** DK3 version of HAVE_SYS_STROPTS_H.
+*/
+#define DK3_HAVE_SYS_STROPTS_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_SUNDDI_H
+/** DK3 version of HAVE_SYS_SUNDDI_H.
+*/
+#define DK3_HAVE_SYS_SUNDDI_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_SYSCTL_H
+/** DK3 version of HAVE_SYS_SYSCTL_H.
+*/
+#define DK3_HAVE_SYS_SYSCTL_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_SYSTEMINFO_H
+/** DK3 version of HAVE_SYS_SYSTEMINFO_H.
+*/
+#define DK3_HAVE_SYS_SYSTEMINFO_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_TERMIOS_H
+/** DK3 version of HAVE_SYS_TERMIOS_H.
+*/
+#define DK3_HAVE_SYS_TERMIOS_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_TIME_H
+/** DK3 version of HAVE_SYS_TIME_H.
+*/
+#define DK3_HAVE_SYS_TIME_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_TTOLD_H
+/** DK3 version of HAVE_SYS_TTOLD_H.
+*/
+#define DK3_HAVE_SYS_TTOLD_H 0
+#endif
+
+#ifndef DK3_HAVE_SYS_TYPES_H
+/** DK3 version of HAVE_SYS_TYPES_H.
+*/
+#define DK3_HAVE_SYS_TYPES_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_UIO_H
+/** DK3 version of HAVE_SYS_UIO_H.
+*/
+#define DK3_HAVE_SYS_UIO_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_UN_H
+/** DK3 version of HAVE_SYS_UN_H.
+*/
+#define DK3_HAVE_SYS_UN_H 1
+#endif
+
+#ifndef DK3_HAVE_SYS_WAIT_H
+/** DK3 version of HAVE_SYS_WAIT_H.
+*/
+#define DK3_HAVE_SYS_WAIT_H 1
+#endif
+
+#ifndef DK3_HAVE_TANHL
+/** DK3 version of HAVE_TANHL.
+*/
+#define DK3_HAVE_TANHL 1
+#endif
+
+#ifndef DK3_HAVE_TANL
+/** DK3 version of HAVE_TANL.
+*/
+#define DK3_HAVE_TANL 1
+#endif
+
+#ifndef DK3_HAVE_TCFLUSH
+/** DK3 version of HAVE_TCFLUSH.
+*/
+#define DK3_HAVE_TCFLUSH 1
+#endif
+
+#ifndef DK3_HAVE_TCGETATTR
+/** DK3 version of HAVE_TCGETATTR.
+*/
+#define DK3_HAVE_TCGETATTR 1
+#endif
+
+#ifndef DK3_HAVE_TERMIOS_H
+/** DK3 version of HAVE_TERMIOS_H.
+*/
+#define DK3_HAVE_TERMIOS_H 1
+#endif
+
+#ifndef DK3_HAVE_TIFF_H
+/** DK3 version of HAVE_TIFF_H.
+*/
+#define DK3_HAVE_TIFF_H 1
+#endif
+
+#ifndef DK3_HAVE_TIME
+/** DK3 version of HAVE_TIME.
+*/
+#define DK3_HAVE_TIME 1
+#endif
+
+#ifndef DK3_HAVE_TIME_H
+/** DK3 version of HAVE_TIME_H.
+*/
+#define DK3_HAVE_TIME_H 1
+#endif
+
+#ifndef DK3_HAVE_TWOS_COMPLEMENT
+/** DK3 version of HAVE_TWOS_COMPLEMENT.
+*/
+#define DK3_HAVE_TWOS_COMPLEMENT 1
+#endif
+
+#ifndef DK3_HAVE_UMASK
+/** DK3 version of HAVE_UMASK.
+*/
+#define DK3_HAVE_UMASK 1
+#endif
+
+#ifndef DK3_HAVE_UNISTD_H
+/** DK3 version of HAVE_UNISTD_H.
+*/
+#define DK3_HAVE_UNISTD_H 1
+#endif
+
+#ifndef DK3_HAVE_UNLINK
+/** DK3 version of HAVE_UNLINK.
+*/
+#define DK3_HAVE_UNLINK 1
+#endif
+
+#ifndef DK3_HAVE_USER_NAMES_CASE_INSENSITIVE
+/** DK3 version of HAVE_USER_NAMES_CASE_INSENSITIVE.
+*/
+#define DK3_HAVE_USER_NAMES_CASE_INSENSITIVE 0
+#endif
+
+#ifndef DK3_HAVE_VARARGS_H
+/** DK3 version of HAVE_VARARGS_H.
+*/
+#define DK3_HAVE_VARARGS_H 0
+#endif
+
+#ifndef DK3_HAVE_VARARG_H
+/** DK3 version of HAVE_VARARG_H.
+*/
+#define DK3_HAVE_VARARG_H 0
+#endif
+
+#ifndef DK3_HAVE_VOLATILE
+/** DK3 version of HAVE_VOLATILE.
+*/
+#define DK3_HAVE_VOLATILE 1
+#endif
+
+#ifndef DK3_HAVE_WCHAR_H
+/** DK3 version of HAVE_WCHAR_H.
+*/
+#define DK3_HAVE_WCHAR_H 1
+#endif
+
+#ifndef DK3_HAVE_WCHAR_T
+/** DK3 version of HAVE_WCHAR_T.
+*/
+#define DK3_HAVE_WCHAR_T 1
+#endif
+
+#ifndef DK3_HAVE_WCSCAT
+/** DK3 version of HAVE_WCSCAT.
+*/
+#define DK3_HAVE_WCSCAT 1
+#endif
+
+#ifndef DK3_HAVE_WCSCAT_S
+/** DK3 version of HAVE_WCSCAT_S.
+*/
+#define DK3_HAVE_WCSCAT_S 0
+#endif
+
+#ifndef DK3_HAVE_WCSCHR
+/** DK3 version of HAVE_WCSCHR.
+*/
+#define DK3_HAVE_WCSCHR 1
+#endif
+
+#ifndef DK3_HAVE_WCSCMP
+/** DK3 version of HAVE_WCSCMP.
+*/
+#define DK3_HAVE_WCSCMP 1
+#endif
+
+#ifndef DK3_HAVE_WCSCPY
+/** DK3 version of HAVE_WCSCPY.
+*/
+#define DK3_HAVE_WCSCPY 1
+#endif
+
+#ifndef DK3_HAVE_WCSCPY_S
+/** DK3 version of HAVE_WCSCPY_S.
+*/
+#define DK3_HAVE_WCSCPY_S 0
+#endif
+
+#ifndef DK3_HAVE_WCSDUP
+/** DK3 version of HAVE_WCSDUP.
+*/
+#define DK3_HAVE_WCSDUP 1
+#endif
+
+#ifndef DK3_HAVE_WCSICMP
+/** DK3 version of HAVE_WCSICMP.
+*/
+#define DK3_HAVE_WCSICMP 0
+#endif
+
+#ifndef DK3_HAVE_WCSLEN
+/** DK3 version of HAVE_WCSLEN.
+*/
+#define DK3_HAVE_WCSLEN 1
+#endif
+
+#ifndef DK3_HAVE_WCSNCMP
+/** DK3 version of HAVE_WCSNCMP.
+*/
+#define DK3_HAVE_WCSNCMP 1
+#endif
+
+#ifndef DK3_HAVE_WCSNCPY
+/** DK3 version of HAVE_WCSNCPY.
+*/
+#define DK3_HAVE_WCSNCPY 1
+#endif
+
+#ifndef DK3_HAVE_WCSNCPY_S
+/** DK3 version of HAVE_WCSNCPY_S.
+*/
+#define DK3_HAVE_WCSNCPY_S 0
+#endif
+
+#ifndef DK3_HAVE_WCSRCHR
+/** DK3 version of HAVE_WCSRCHR.
+*/
+#define DK3_HAVE_WCSRCHR 1
+#endif
+
+#ifndef DK3_HAVE_WCSTOD
+/** DK3 version of HAVE_WCSTOD.
+*/
+#define DK3_HAVE_WCSTOD 1
+#endif
+
+#ifndef DK3_HAVE_WCSTOIMAX
+/** DK3 version of HAVE_WCSTOIMAX.
+*/
+#define DK3_HAVE_WCSTOIMAX 1
+#endif
+
+#ifndef DK3_HAVE_WCSTOL
+/** DK3 version of HAVE_WCSTOL.
+*/
+#define DK3_HAVE_WCSTOL 1
+#endif
+
+#ifndef DK3_HAVE_WCSTOLL
+/** DK3 version of HAVE_WCSTOLL.
+*/
+#define DK3_HAVE_WCSTOLL 1
+#endif
+
+#ifndef DK3_HAVE_WCSTOUL
+/** DK3 version of HAVE_WCSTOUL.
+*/
+#define DK3_HAVE_WCSTOUL 1
+#endif
+
+#ifndef DK3_HAVE_WCSTOULL
+/** DK3 version of HAVE_WCSTOULL.
+*/
+#define DK3_HAVE_WCSTOULL 1
+#endif
+
+#ifndef DK3_HAVE_WCSTOUMAX
+/** DK3 version of HAVE_WCSTOUMAX.
+*/
+#define DK3_HAVE_WCSTOUMAX 1
+#endif
+
+#ifndef DK3_HAVE_WINBASE_H
+/** DK3 version of HAVE_WINBASE_H.
+*/
+#define DK3_HAVE_WINBASE_H 0
+#endif
+
+#ifndef DK3_HAVE_WINCON_H
+/** DK3 version of HAVE_WINCON_H.
+*/
+#define DK3_HAVE_WINCON_H 0
+#endif
+
+#ifndef DK3_HAVE_WINDOWS_H
+/** DK3 version of HAVE_WINDOWS_H.
+*/
+#define DK3_HAVE_WINDOWS_H 0
+#endif
+
+#ifndef DK3_HAVE_WINREG_H
+/** DK3 version of HAVE_WINREG_H.
+*/
+#define DK3_HAVE_WINREG_H 0
+#endif
+
+#ifndef DK3_HAVE_WINSOCK2_H
+/** DK3 version of HAVE_WINSOCK2_H.
+*/
+#define DK3_HAVE_WINSOCK2_H 0
+#endif
+
+#ifndef DK3_HAVE_WRITE
+/** DK3 version of HAVE_WRITE.
+*/
+#define DK3_HAVE_WRITE 1
+#endif
+
+#ifndef DK3_HAVE_WS2TCPIP_H
+/** DK3 version of HAVE_WS2TCPIP_H.
+*/
+#define DK3_HAVE_WS2TCPIP_H 0
+#endif
+
+#ifndef DK3_HAVE_ZLIB_H
+/** DK3 version of HAVE_ZLIB_H.
+*/
+#define DK3_HAVE_ZLIB_H 1
+#endif
+
+#ifndef DK3_HAVE__CLEARFP
+/** DK3 version of HAVE__CLEARFP.
+*/
+#define DK3_HAVE__CLEARFP 0
+#endif
+
+#ifndef DK3_HAVE__FCLOSE
+/** DK3 version of HAVE__FCLOSE.
+*/
+#define DK3_HAVE__FCLOSE 0
+#endif
+
+#ifndef DK3_HAVE__FEOF
+/** DK3 version of HAVE__FEOF.
+*/
+#define DK3_HAVE__FEOF 0
+#endif
+
+#ifndef DK3_HAVE__FERROR
+/** DK3 version of HAVE__FERROR.
+*/
+#define DK3_HAVE__FERROR 0
+#endif
+
+#ifndef DK3_HAVE__FFLUSH
+/** DK3 version of HAVE__FFLUSH.
+*/
+#define DK3_HAVE__FFLUSH 0
+#endif
+
+#ifndef DK3_HAVE__FOPEN
+/** DK3 version of HAVE__FOPEN.
+*/
+#define DK3_HAVE__FOPEN 0
+#endif
+
+#ifndef DK3_HAVE__FREAD
+/** DK3 version of HAVE__FREAD.
+*/
+#define DK3_HAVE__FREAD 0
+#endif
+
+#ifndef DK3_HAVE__FWRITE
+/** DK3 version of HAVE__FWRITE.
+*/
+#define DK3_HAVE__FWRITE 0
+#endif
+
+#ifndef DK3_HAVE__GETCWD
+/** DK3 version of HAVE__GETCWD.
+*/
+#define DK3_HAVE__GETCWD 0
+#endif
+
+#ifndef DK3_HAVE__GETENV_S
+/** DK3 version of HAVE__GETENV_S.
+*/
+#define DK3_HAVE__GETENV_S 0
+#endif
+
+#ifndef DK3_HAVE__GETPID
+/** DK3 version of HAVE__GETPID.
+*/
+#define DK3_HAVE__GETPID 0
+#endif
+
+#ifndef DK3_HAVE__LSTAT
+/** DK3 version of HAVE__LSTAT.
+*/
+#define DK3_HAVE__LSTAT 0
+#endif
+
+#ifndef DK3_HAVE__LSTAT32
+/** DK3 version of HAVE__LSTAT32.
+*/
+#define DK3_HAVE__LSTAT32 0
+#endif
+
+#ifndef DK3_HAVE__LSTAT64
+/** DK3 version of HAVE__LSTAT64.
+*/
+#define DK3_HAVE__LSTAT64 0
+#endif
+
+#ifndef DK3_HAVE__MKDIR
+/** DK3 version of HAVE__MKDIR.
+*/
+#define DK3_HAVE__MKDIR 0
+#endif
+
+#ifndef DK3_HAVE__POPEN
+/** DK3 version of HAVE__POPEN.
+*/
+#define DK3_HAVE__POPEN 0
+#endif
+
+#ifndef DK3_HAVE__READ
+/** DK3 version of HAVE__READ.
+*/
+#define DK3_HAVE__READ 0
+#endif
+
+#ifndef DK3_HAVE__RMDIR
+/** DK3 version of HAVE__RMDIR.
+*/
+#define DK3_HAVE__RMDIR 0
+#endif
+
+#ifndef DK3_HAVE__SNPRINTF
+/** DK3 version of HAVE__SNPRINTF.
+*/
+#define DK3_HAVE__SNPRINTF 0
+#endif
+
+#ifndef DK3_HAVE__SNPRINTF_S
+/** DK3 version of HAVE__SNPRINTF_S.
+*/
+#define DK3_HAVE__SNPRINTF_S 0
+#endif
+
+#ifndef DK3_HAVE__SNWPRINTF
+/** DK3 version of HAVE__SNWPRINTF.
+*/
+#define DK3_HAVE__SNWPRINTF 0
+#endif
+
+#ifndef DK3_HAVE__SNWPRINTF_S
+/** DK3 version of HAVE__SNWPRINTF_S.
+*/
+#define DK3_HAVE__SNWPRINTF_S 0
+#endif
+
+#ifndef DK3_HAVE__STAT
+/** DK3 version of HAVE__STAT.
+*/
+#define DK3_HAVE__STAT 0
+#endif
+
+#ifndef DK3_HAVE__STAT32
+/** DK3 version of HAVE__STAT32.
+*/
+#define DK3_HAVE__STAT32 0
+#endif
+
+#ifndef DK3_HAVE__STAT64
+/** DK3 version of HAVE__STAT64.
+*/
+#define DK3_HAVE__STAT64 0
+#endif
+
+#ifndef DK3_HAVE__STRDUP
+/** DK3 version of HAVE__STRDUP.
+*/
+#define DK3_HAVE__STRDUP 0
+#endif
+
+#ifndef DK3_HAVE__STRICMP
+/** DK3 version of HAVE__STRICMP.
+*/
+#define DK3_HAVE__STRICMP 0
+#endif
+
+#ifndef DK3_HAVE__UNLINK
+/** DK3 version of HAVE__UNLINK.
+*/
+#define DK3_HAVE__UNLINK 0
+#endif
+
+#ifndef DK3_HAVE__WCSCAT
+/** DK3 version of HAVE__WCSCAT.
+*/
+#define DK3_HAVE__WCSCAT 0
+#endif
+
+#ifndef DK3_HAVE__WCSCHR
+/** DK3 version of HAVE__WCSCHR.
+*/
+#define DK3_HAVE__WCSCHR 0
+#endif
+
+#ifndef DK3_HAVE__WCSCMP
+/** DK3 version of HAVE__WCSCMP.
+*/
+#define DK3_HAVE__WCSCMP 0
+#endif
+
+#ifndef DK3_HAVE__WCSCPY
+/** DK3 version of HAVE__WCSCPY.
+*/
+#define DK3_HAVE__WCSCPY 0
+#endif
+
+#ifndef DK3_HAVE__WCSDUP
+/** DK3 version of HAVE__WCSDUP.
+*/
+#define DK3_HAVE__WCSDUP 0
+#endif
+
+#ifndef DK3_HAVE__WCSICMP
+/** DK3 version of HAVE__WCSICMP.
+*/
+#define DK3_HAVE__WCSICMP 0
+#endif
+
+#ifndef DK3_HAVE__WCSLEN
+/** DK3 version of HAVE__WCSLEN.
+*/
+#define DK3_HAVE__WCSLEN 0
+#endif
+
+#ifndef DK3_HAVE__WCSNCMP
+/** DK3 version of HAVE__WCSNCMP.
+*/
+#define DK3_HAVE__WCSNCMP 0
+#endif
+
+#ifndef DK3_HAVE__WCSNCPY
+/** DK3 version of HAVE__WCSNCPY.
+*/
+#define DK3_HAVE__WCSNCPY 0
+#endif
+
+#ifndef DK3_HAVE__WCSRCHR
+/** DK3 version of HAVE__WCSRCHR.
+*/
+#define DK3_HAVE__WCSRCHR 0
+#endif
+
+#ifndef DK3_HAVE__WFOPEN_S
+/** DK3 version of HAVE__WFOPEN_S.
+*/
+#define DK3_HAVE__WFOPEN_S 0
+#endif
+
+#ifndef DK3_HAVE__WGETENV
+/** DK3 version of HAVE__WGETENV.
+*/
+#define DK3_HAVE__WGETENV 0
+#endif
+
+#ifndef DK3_HAVE__WRITE
+/** DK3 version of HAVE__WRITE.
+*/
+#define DK3_HAVE__WRITE 0
+#endif
+
+#ifndef DK3_TIME_WITH_SYS_TIME
+/** DK3 version of TIME_WITH_SYS_TIME.
+*/
+#define DK3_TIME_WITH_SYS_TIME 1
+#endif
+
+#ifndef DK3_SIZEOF_DOUBLE
+/** DK3 version of SIZEOF_DOUBLE.
+*/
+#define DK3_SIZEOF_DOUBLE 8
+#endif
+
+#ifndef DK3_SIZEOF_INT
+/** DK3 version of SIZEOF_INT.
+*/
+#define DK3_SIZEOF_INT 4
+#endif
+
+#ifndef DK3_SIZEOF_INTMAX_T
+/** DK3 version of SIZEOF_INTMAX_T.
+*/
+#define DK3_SIZEOF_INTMAX_T 8
+#endif
+
+#ifndef DK3_SIZEOF_LONG
+/** DK3 version of SIZEOF_LONG.
+*/
+#define DK3_SIZEOF_LONG 4
+#endif
+
+#ifndef DK3_SIZEOF_LONG_DOUBLE
+/** DK3 version of SIZEOF_LONG_DOUBLE.
+*/
+#define DK3_SIZEOF_LONG_DOUBLE 12
+#endif
+
+#ifndef DK3_SIZEOF_LONG_LONG
+/** DK3 version of SIZEOF_LONG_LONG.
+*/
+#define DK3_SIZEOF_LONG_LONG 8
+#endif
+
+#ifndef DK3_SIZEOF_SHORT
+/** DK3 version of SIZEOF_SHORT.
+*/
+#define DK3_SIZEOF_SHORT 2
+#endif
+
+#ifndef DK3_SIZEOF_SIZE_T
+/** DK3 version of SIZEOF_SIZE_T.
+*/
+#define DK3_SIZEOF_SIZE_T 4
+#endif
+
+#ifndef DK3_SIZEOF_WCHAR_T
+/** DK3 version of SIZEOF_WCHAR_T.
+*/
+#define DK3_SIZEOF_WCHAR_T 4
+#endif
+
+#endif
+/* if DK3_ON_WINDOWS */
+
+#ifndef DK3_WORDS_BIGENDIAN
+/** Little-endian.
+*/
+#define DK3_WORDS_BIGENDIAN 0
+#endif
+
+#ifndef DK3_MAX_PATH
+/** Maximum path length.
+*/
+#define DK3_MAX_PATH 4097
+#endif
+
+#endif
+/* ifndef DK3_CONF_H_INCLUDED */
+
diff --git a/support/dktools/win32/dk3wxcs.h b/support/dktools/win32/dk3wxcs.h
new file mode 100644
index 0000000000..8f63e24061
--- /dev/null
+++ b/support/dktools/win32/dk3wxcs.h
@@ -0,0 +1,9 @@
+#ifndef DK3WXCSZ_H_INCLUDED
+/** Protection against multiple inclusions. */
+#define DK3WXCSZ_H_INCLUDED 1
+
+/** Size of wxChar.
+*/
+#define DK3_SIZEOF_WXCHAR 2
+
+#endif
diff --git a/support/dktools/win32/dk4conf.h b/support/dktools/win32/dk4conf.h
new file mode 100644
index 0000000000..85056d6617
--- /dev/null
+++ b/support/dktools/win32/dk4conf.h
@@ -0,0 +1,2204 @@
+/** @file dk4conf.h Default definitions.
+*/
+
+#ifndef DK4_CONF_H_INCLUDED
+/** Protection against multiple inclusions. */
+#define DK4_CONF_H_INCLUDED 1
+
+#ifndef DK4_ON_WINDOWS
+#ifdef _WIN32
+#define DK4_ON_WINDOWS 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_INLINE
+#ifdef _WIN32
+#define DK4_HAVE_INLINE 0
+#else
+#define DK4_HAVE_INLINE 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_LIBNETSNMP
+#ifdef _WIN32
+#define DK4_HAVE_LIBNETSNMP 0
+#else
+#define DK4_HAVE_LIBNETSNMP 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_SNMP_ENABLE_FILELOG
+#ifdef _WIN32
+#define DK4_HAVE_SNMP_ENABLE_FILELOG 0
+#else
+#define DK4_HAVE_SNMP_ENABLE_FILELOG 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_SNMP_DISABLE_FILELOG
+#ifdef _WIN32
+#define DK4_HAVE_SNMP_DISABLE_FILELOG 0
+#else
+#define DK4_HAVE_SNMP_DISABLE_FILELOG 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_SNMP_DISABLE_SYSLOG
+#ifdef _WIN32
+#define DK4_HAVE_SNMP_DISABLE_SYSLOG 0
+#else
+#define DK4_HAVE_SNMP_DISABLE_SYSLOG 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_SNMP_DISABLE_STDERRLOG
+#ifdef _WIN32
+#define DK4_HAVE_SNMP_DISABLE_STDERRLOG 0
+#else
+#define DK4_HAVE_SNMP_DISABLE_STDERRLOG 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_ERRNO_H
+/** DK4 version of HAVE_ERRNO_H. */
+#define DK4_HAVE_ERRNO_H 1
+#endif
+
+#ifndef DK4_HAVE_UNISTD_H
+/** DK4 version of HAVE_UNISTD_H. */
+#ifdef _WIN32
+#define DK4_HAVE_UNISTD_H 0
+#else
+#define DK4_HAVE_UNISTD_H 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_WINDOWS_H
+#ifdef _WIN32
+#define DK4_HAVE_WINDOWS_H 1
+#else
+#define DK4_HAVE_WINDOWS_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_WINSOCK2_H
+#ifdef _WIN32
+#define DK4_HAVE_WINSOCK2_H 1
+#else
+#define DK4_HAVE_WINSOCK2_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_WS2TCPIP_H
+#ifdef _WIN32
+#define DK4_HAVE_WS2TCPIP_H 1
+#else
+#define DK4_HAVE_WS2TCPIP_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SYS_SELECT_H
+#ifdef _WIN32
+#define DK4_HAVE_SYS_SELECT_H 0
+#else
+#define DK4_HAVE_SYS_SELECT_H 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_PROCESS_H
+/** DK4 version of HAVE_PROCESS_H. */
+#ifdef _WIN32
+#define DK4_HAVE_PROCESS_H 1
+#else
+#define DK4_HAVE_PROCESS_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_CTYPE_H
+/** DK4 version of HAVE_CTYPE_H. */
+#define DK4_HAVE_CTYPE_H 1
+#endif
+
+#ifndef DK4_HAVE_WCHAR_H
+/** DK4 version of HAVE_WCHAR_H. */
+#define DK4_HAVE_WCHAR_H 1
+#endif
+
+#ifndef DK4_HAVE_WCTYPE_H
+/** DK4 version of HAVE_WCTYPE_H. */
+#define DK4_HAVE_WCTYPE_H 1
+#endif
+
+#ifndef DK4_HAVE_STDINT_H
+/** DK4 version of HAVE_STDINT_H. */
+#ifdef _WIN32
+#if _MSC_VER >= 1700
+#define DK4_HAVE_STDINT_H 1
+#else
+#define DK4_HAVE_STDINT_H 0
+#endif
+#else
+#define DK4_HAVE_STDINT_H 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_STDLIB_H
+#ifdef _WIN32
+#define DK4_HAVE_STDLIB_H 1
+#else
+#define DK4_HAVE_STDLIB_H 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_INTTYPES_H
+/** DK4 version of HAVE_INTTYPES_H. */
+#ifdef _WIN32
+#define DK4_HAVE_INTTYPES_H 0
+#else
+#define DK4_HAVE_INTTYPES_H 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_LIMITS_H
+/** DK4 version of HAVE_LIMITS_H. */
+#define DK4_HAVE_LIMITS_H 1
+#endif
+
+#ifndef DK4_HAVE_STRING_H
+/** DK4 version of HAVE_STRING_H. */
+#define DK4_HAVE_STRING_H 1
+#endif
+
+#ifndef DK4_HAVE_ASSERT_H
+/** DK4 version of HAVE_ASSERT_H. */
+#define DK4_HAVE_ASSERT_H 1
+#endif
+
+#ifndef DK4_HAVE_SIGNAL_H
+/** DK4 version of HAVE_SIGNAL_H. */
+#define DK4_HAVE_SIGNAL_H 1
+#endif
+
+#ifndef DK4_HAVE_MATH_H
+/** DK4 version of HAVE_MATH_H. */
+#define DK4_HAVE_MATH_H 1
+#endif
+
+#ifndef DK4_HAVE_FENV_H
+/** DK4 version of HAVE_FENV_H. */
+#define DK4_HAVE_FENV_H 1
+#endif
+
+#ifndef DK4_HAVE_FLOAT_H
+/** DK4 version of HAVE_FLOAT_H. */
+#ifdef _WIN32
+#define DK4_HAVE_FLOAT_H 1
+#else
+#define DK4_HAVE_FLOAT_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_COMPLEX_H
+/** DK4 version of HAVE_COMPLEX_H. */
+#define DK4_HAVE_COMPLEX_H 1
+#endif
+
+#ifndef DK4_HAVE_TIME_H
+/** DK4 version of HAVE_TIME_H. */
+#define DK4_HAVE_TIME_H 1
+#endif
+
+#ifndef DK4_HAVE_TYPE_STAT64
+#ifdef _WIN32
+#define DK4_HAVE_TYPE_STAT64 0
+#else
+#define DK4_HAVE_TYPE_STAT64 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_UCHAR_H
+#ifdef _WIN32
+#define DK4_HAVE_UCHAR_H 0
+#else
+#define DK4_HAVE_UCHAR_H 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_SETJMP_H
+/** DK4 version of HAVE_SETJMP_H. */
+#define DK4_HAVE_SETJMP_H 1
+#endif
+
+#ifndef DK4_HAVE_LOCALE_H
+/** DK4 version of HAVE_LOCALE_H. */
+#define DK4_HAVE_LOCALE_H 1
+#endif
+
+#ifndef DK4_HAVE_ISO646_H
+/** DK4 version of HAVE_ISO646_H. */
+#define DK4_HAVE_ISO646_H 0
+#endif
+
+#ifndef DK4_HAVE_STDALIGN_H
+/** DK4 version of HAVE_STDALIGN_H. */
+#define DK4_HAVE_STDALIGN_H 0
+#endif
+
+#ifndef DK4_HAVE_STDARG_H
+/** DK4 version of HAVE_STDARG_H. */
+#define DK4_HAVE_STDARG_H 1
+#endif
+
+#ifndef DK4_HAVE_STDATOMIC_H
+/** DK4 version of HAVE_STDATOMIC_H. */
+#ifdef _WIN32
+#define DK4_HAVE_STDATOMIC_H 0
+#else
+#define DK4_HAVE_STDATOMIC_H 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_STDBOOL_H
+/** DK4 version of HAVE_STDBOOL_H. */
+#ifdef _WIN32
+#define DK4_HAVE_STDBOOL_H 0
+#else
+#define DK4_HAVE_STDBOOL_H 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_STDDEF_H
+/** DK4 version of HAVE_STDDEF_H. */
+#define DK4_HAVE_STDDEF_H 1
+#endif
+
+#ifndef DK4_HAVE_STDNORETURN_H
+/** DK4 version of HAVE_STDNORETURN_H. */
+#define DK4_HAVE_STDNORETURN_H 0
+#endif
+
+#ifndef DK4_HAVE_TGMATH_H
+/** DK4 version of HAVE_TGMATH_H. */
+#ifdef _WIN32
+#define DK4_HAVE_TGMATH_H 0
+#else
+#define DK4_HAVE_TGMATH_H 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_THREADS_H
+/** DK4 version of HAVE_THREADS_H. */
+#define DK4_HAVE_THREADS_H 0
+#endif
+
+#ifndef DK4_HAVE_SYS_TYPES_H
+/** DK4 version of HAVE_SYS_TYPES_H. */
+#define DK4_HAVE_SYS_TYPES_H 1
+#endif
+
+#ifndef DK4_HAVE_SYS_SOCKET_H
+#ifdef _WIN32
+#define DK4_HAVE_SYS_SOCKET_H 0
+#else
+#define DK4_HAVE_SYS_SOCKET_H 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_SYS_UN_H
+#ifdef _WIN32
+#define DK4_HAVE_SYS_UN_H 0
+#else
+#define DK4_HAVE_SYS_UN_H 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_NETINET_IN_H
+#ifdef _WIN32
+#define DK4_HAVE_NETINET_IN_H 0
+#else
+#define DK4_HAVE_NETINET_IN_H 1
+#endif
+#endif
+
+
+#ifndef DK4_HAVE_NETINET_IN6_H
+#ifdef _WIN32
+#define DK4_HAVE_NETINET_IN6_H 0
+#else
+#define DK4_HAVE_NETINET_IN6_H 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_NETDB_H
+#ifdef _WIN32
+#define DK4_HAVE_NETDB_H 0
+#else
+#define DK4_HAVE_NETDB_H 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_ARPA_INET_H
+#ifdef _WIN32
+#define DK4_HAVE_ARPA_INET_H 0
+#else
+#define DK4_HAVE_ARPA_INET_H 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_PWD_H
+#ifdef _WIN32
+#define DK4_HAVE_PWD_H 0
+#else
+#define DK4_HAVE_PWD_H 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_SYS_PARAM_H
+/** DK4 version of HAVE_SYS_PARAM_H. */
+#ifdef _WIN32
+#define DK4_HAVE_SYS_PARAM_H 0
+#else
+#define DK4_HAVE_SYS_PARAM_H 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_SYS_STAT_H
+/** DK4 version of HAVE_SYS_STAT_H. */
+#define DK4_HAVE_SYS_STAT_H 1
+#endif
+
+#ifndef DK4_HAVE_SYS_TIME_H
+/** DK4 version of HAVE_SYS_TIME_H. */
+#define DK4_HAVE_SYS_TIME_H 1
+#endif
+
+#ifndef DK4_HAVE_STRINGS_H
+/** DK4 version of HAVE_STRINGS_H. */
+#ifdef _WIN32
+#define DK4_HAVE_STRINGS_H 0
+#else
+#define DK4_HAVE_STRINGS_H 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_IO_H
+/** DK4 version of HAVE_IO_H. */
+#ifdef _WIN32
+#define DK4_HAVE_IO_H 1
+#else
+#define DK4_HAVE_IO_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_FCNTL_H
+#define DK4_HAVE_FCNTL_H 1
+#endif
+
+#ifndef DK4_HAVE_SHARE_H
+#ifdef _WIN32
+#define DK4_HAVE_SHARE_H 1
+#else
+#define DK4_HAVE_SHARE_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_BIOS_H
+/** DK4 version of HAVE_BIOS_H. */
+#ifdef _WIN32
+#define DK4_HAVE_BIOS_H 1
+#else
+#define DK4_HAVE_BIOS_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_DOS_H
+/** DK4 version of HAVE_DOS_H. */
+#ifdef _WIN32
+#define DK4_HAVE_DOS_H 1
+#else
+#define DK4_HAVE_DOS_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_ALLOC_H
+/** DK4 version of HAVE_ALLOC_H. */
+#define DK4_HAVE_ALLOC_H 0
+#endif
+
+#ifndef DK4_HAVE_MALLOC_H
+/** DK4 version of HAVE_MALLOC_H. */
+#define DK4_HAVE_MALLOC_H 1
+#endif
+
+#ifndef DK4_HAVE_DIRENT_H
+#ifdef _WIN32
+#define DK4_HAVE_DIRENT_H 0
+#else
+#define DK4_HAVE_DIRENT_H 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_DIRECT_H
+#ifdef _WIN32
+#define DK4_HAVE_DIRECT_H 1
+#else
+#define DK4_HAVE_DIRECT_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_LONG_LONG
+#ifdef _WIN32
+#if _MSC_VER >= 1700
+#define DK4_HAVE_LONG_LONG 1
+#else
+#define DK4_HAVE_LONG_LONG 0
+#endif
+#else
+#define DK4_HAVE_LONG_LONG 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_LONG_DOUBLE
+#ifdef _WIN32
+#if _MSC_VER >= 1700
+#define DK4_HAVE_LONG_DOUBLE 1
+#else
+#define DK4_HAVE_LONG_DOUBLE 0
+#endif
+#else
+#define DK4_HAVE_LONG_DOUBLE 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_INT8_T
+#ifdef _WIN32
+#if _MSC_VER >= 1700
+#define DK4_HAVE_INT8_T 1
+#else
+#define DK4_HAVE_INT8_T 0
+#endif
+#else
+#define DK4_HAVE_INT8_T 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_INT16_T
+#ifdef _WIN32
+#if _MSC_VER >= 1700
+#define DK4_HAVE_INT16_T 1
+#else
+#define DK4_HAVE_INT16_T 0
+#endif
+#else
+#define DK4_HAVE_INT16_T 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_INT32_T
+#ifdef _WIN32
+#if _MSC_VER >= 1700
+#define DK4_HAVE_INT32_T 1
+#else
+#define DK4_HAVE_INT32_T 0
+#endif
+#else
+#define DK4_HAVE_INT32_T 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_UINT8_T
+#ifdef _WIN32
+#if _MSC_VER >= 1700
+#define DK4_HAVE_UINT8_T 1
+#else
+#define DK4_HAVE_UINT8_T 0
+#endif
+#else
+#define DK4_HAVE_UINT8_T 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_UINT16_T
+#ifdef _WIN32
+#if _MSC_VER >= 1700
+#define DK4_HAVE_UINT16_T 1
+#else
+#define DK4_HAVE_UINT16_T 0
+#endif
+#else
+#define DK4_HAVE_UINT16_T 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_UINT32_T
+#ifdef _WIN32
+#if _MSC_VER >= 1700
+#define DK4_HAVE_UINT32_T 1
+#else
+#define DK4_HAVE_UINT32_T 0
+#endif
+#else
+#define DK4_HAVE_UINT32_T 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_SSIZE_T
+#ifdef _WIN32
+#define DK4_HAVE_SSIZE_T 0
+#else
+#define DK4_HAVE_SSIZE_T 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_INTMAX_T
+#ifdef _WIN32
+#if _MSC_VER >= 1800
+#define DK4_HAVE_INTMAX_T 1
+#else
+#define DK4_HAVE_INTMAX_T 0
+#endif
+#else
+#define DK4_HAVE_INTMAX_T 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_VOLATILE
+#ifdef _WIN32
+#define DK4_HAVE_VOLATILE 1
+#else
+#define DK4_HAVE_VOLATILE 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_SIG_ATOMIC_T
+#ifdef _WIN32
+#define DK4_HAVE_SIG_ATOMIC_T 1
+#else
+#define DK4_HAVE_SIG_ATOMIC_T 1
+#endif
+#endif
+
+#ifndef DK4_SIZEOF_SHORT
+/** DK4 version of SIZEOF_SHORT. */
+#define DK4_SIZEOF_SHORT 2
+#endif
+
+#ifndef DK4_SIZEOF_INT
+/** DK4 version of SIZEOF_INT. */
+#define DK4_SIZEOF_INT 4
+#endif
+
+#ifndef DK4_SIZEOF_SIZE_T
+/** DK4 version of SIZEOF_SIZE_T. */
+#ifdef _WIN32
+#ifdef _WIN64
+#define DK4_SIZEOF_SIZE_T 4
+#else
+#define DK4_SIZEOF_SIZE_T 8
+#endif
+#else
+#define DK4_SIZEOF_SIZE_T 8
+#endif
+#endif
+
+#ifndef DK4_SIZEOF_LONG
+/** DK4 version of SIZEOF_LONG. */
+#define DK4_SIZEOF_LONG 4
+#endif
+
+#ifndef DK4_SIZEOF_LONG_LONG
+/** DK4 version of SIZEOF_LONG_LONG. */
+#define DK4_SIZEOF_LONG_LONG 8
+#endif
+
+#ifndef DK4_SIZEOF_INTMAX_T
+/** DK4 version of SIZEOF_INTMAX_T. */
+#define DK4_SIZEOF_INTMAX_T 8
+#endif
+
+#ifndef DK4_SIZEOF_DOUBLE
+/** DK4 version of SIZEOF_DOUBLE. */
+#define DK4_SIZEOF_DOUBLE 8
+#endif
+
+#ifndef DK4_SIZEOF_LONG_DOUBLE
+/** DK4 version of SIZEOF_LONG_DOUBLE. */
+#ifdef _WIN32
+#define DK4_SIZEOF_LONG_DOUBLE 8
+#else
+#define DK4_SIZEOF_LONG_DOUBLE 12
+#endif
+#endif
+
+#ifndef DK4_SIZEOF_WCHAR_T
+/** DK4 version of SIZEOF_WCHAR_T. */
+#ifdef _WIN32
+#define DK4_SIZEOF_WCHAR_T 2
+#else
+#define DK4_SIZEOF_WCHAR_T 4
+#endif
+#endif
+
+#ifndef DK4_SIZEOF_WXCHAR
+#ifdef _WIN32
+#ifdef _UNICODE
+#define DK4_SIZEOF_WXCHAR 2
+#else
+#define DK4_SIZEOF_WXCHAR 1
+#endif
+#else
+#define DK4_SIZEOF_WXCHAR 1
+#endif
+#endif
+
+#ifndef DK4_TIME_WITH_SYS_TIME
+#ifdef _WIN32
+#define DK4_TIME_WITH_SYS_TIME 0
+#else
+#define DK4_TIME_WITH_SYS_TIME 1
+#endif
+#endif
+
+#ifndef DK4_WORDS_BIGENDIAN
+#define DK4_WORDS_BIGENDIAN 0
+#endif
+
+#ifndef DK4_HAVE_MEMSET
+#define DK4_HAVE_MEMSET 1
+#endif
+
+#ifndef DK4_HAVE_BZERO
+#ifdef _WIN32
+#define DK4_HAVE_BZERO 0
+#else
+#define DK4_HAVE_BZERO 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_MEMCPY
+#define DK4_HAVE_MEMCPY 1
+#endif
+
+#ifndef DK4_HAVE_BCOPY
+#ifdef _WIN32
+#define DK4_HAVE_BCOPY 1
+#else
+#define DK4_HAVE_BCOPY 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_MEMCMP
+#define DK4_HAVE_MEMCMP 1
+#endif
+
+#ifndef DK4_HAVE_BCMP
+#ifdef _WIN32
+#define DK4_HAVE_BCMP 0
+#else
+#define DK4_HAVE_BCMP 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_MALLOC
+#define DK4_HAVE_MALLOC 1
+#endif
+
+#ifndef DK4_HAVE_CALLOC
+#define DK4_HAVE_CALLOC 1
+#endif
+
+#ifndef DK4_HAVE_FREE
+#define DK4_HAVE_FREE 1
+#endif
+
+#ifndef DK4_HAVE_STRCPY_S
+#ifdef _WIN32
+#if _MSC_VER >= 1700
+#define DK4_HAVE_STRCPY_S 1
+#else
+#define DK4_HAVE_STRCPY_S 0
+#endif
+#else
+#define DK4_HAVE_STRCPY_S 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_STRCAT_S
+#ifdef _WIN32
+#if _MSC_VER >= 1700
+#define DK4_HAVE_STRCAT_S 1
+#else
+#define DK4_HAVE_STRCAT_S 0
+#endif
+#else
+#define DK4_HAVE_STRCAT_S 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_STRCASECMP
+#ifdef _WIN32
+#define DK4_HAVE_STRCASECMP 0
+#else
+#define DK4_HAVE_STRCASECMP 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_STRICMP
+#ifdef _WIN32
+#define DK4_HAVE_STRICMP 0
+#else
+#define DK4_HAVE_STRICMP 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__STRICMP
+#ifdef _WIN32
+#define DK4_HAVE__STRICMP 1
+#else
+#define DK4_HAVE__STRICMP 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_WCSLEN
+#define DK4_HAVE_WCSLEN 1
+#endif
+
+#ifndef DK4_HAVE_WCSCPY_S
+#ifdef _WIN32
+#define DK4_HAVE_WCSCPY_S 1
+#else
+#define DK4_HAVE_WCSCPY_S 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_WCSCPY
+#define DK4_HAVE_WCSCPY 1
+#endif
+
+#ifndef DK4_HAVE_WCSCAT_S
+#ifdef _WIN32
+#define DK4_HAVE_WCSCAT_S 1
+#else
+#define DK4_HAVE_WCSCAT_S 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_WCSCAT
+#define DK4_HAVE_WCSCAT 1
+#endif
+
+#ifndef DK4_HAVE_WCSCHR
+#define DK4_HAVE_WCSCHR 1
+#endif
+
+#ifndef DK4_HAVE_WCSRCHR
+#define DK4_HAVE_WCSRCHR 1
+#endif
+
+#ifndef DK4_HAVE_WCSNCMP
+#define DK4_HAVE_WCSNCMP 1
+#endif
+
+#ifndef DK4_HAVE__WCSNCMP
+#define DK4_HAVE__WCSNCMP 0
+#endif
+
+#ifndef DK4_HAVE_WCSCMP
+#define DK4_HAVE_WCSCMP 1
+#endif
+
+#ifndef DK4_HAVE__WCSCMP
+#define DK4_HAVE__WCSCMP 0
+#endif
+
+#ifndef DK4_HAVE_WCSCASECMP
+#ifdef _WIN32
+#define DK4_HAVE_WCSCASECMP 0
+#else
+#define DK4_HAVE_WCSCASECMP 1
+#endif
+#endif
+
+#ifndef DK4_HAVE__WCSCASECMP
+#define DK4_HAVE__WCSCASECMP 0
+#endif
+
+#ifndef DK4_HAVE_WCSICMP
+#ifdef _WIN32
+#define DK4_HAVE_WCSICMP 0
+#else
+#define DK4_HAVE_WCSICMP 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__WCSICMP
+#ifdef _WIN32
+#define DK4_HAVE__WCSICMP 1
+#else
+#define DK4_HAVE__WCSICMP 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_GETPID
+#ifdef _WIN32
+#define DK4_HAVE_GETPID 0
+#else
+#define DK4_HAVE_GETPID 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_READLINK
+#ifdef _WIN32
+#define DK4_HAVE_READLINK 0
+#else
+#define DK4_HAVE_READLINK 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_GETENV
+#ifdef _WIN32
+#define DK4_HAVE_GETENV 1
+#else
+#define DK4_HAVE_GETENV 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_GETENV_S
+#ifdef _WIN32
+#if _MSC_VER >= 1700
+#define DK4_HAVE_GETENV_S 1
+#else
+#define DK4_HAVE_GETENV_S 0
+#endif
+#else
+#define DK4_HAVE_GETENV_S 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SETLOCALE
+#ifdef _WIN32
+#define DK4_HAVE_SETLOCALE 1
+#else
+#define DK4_HAVE_SETLOCALE 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_SETSOCKOPT
+#ifdef _WIN32
+#define DK4_HAVE_SETSOCKOPT 1
+#else
+#define DK4_HAVE_SETSOCKOPT 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_SELECT
+#ifdef _WIN32
+#define DK4_HAVE_SELECT 1
+#else
+#define DK4_HAVE_SELECT 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_GETADDRINFO
+#ifdef _WIN32
+#if _MSC_VER >= 1700
+#if DK4_WINDOWS_LEGACY
+#define DK4_HAVE_GETADDRINFO 0
+#else
+#define DK4_HAVE_GETADDRINFO 1
+#endif
+#else
+#define DK4_HAVE_GETADDRINFO 0
+#endif
+#else
+#define DK4_HAVE_GETADDRINFO 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_GETNAMEINFO
+#ifdef _WIN32
+#if _MSC_VER >= 1700
+#if DK4_WINDOWS_LEGACY
+#define DK4_HAVE_GETNAMEINFO 0
+#else
+#define DK4_HAVE_GETNAMEINFO 1
+#endif
+#else
+#define DK4_HAVE_GETNAMEINFO 0
+#endif
+#else
+#define DK4_HAVE_GETNAMEINFO 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_GETHOSTBYNAME
+#ifdef _WIN32
+#define DK4_HAVE_GETHOSTBYNAME 1
+#else
+#define DK4_HAVE_GETHOSTBYNAME 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_HTONS
+#ifdef _WIN32
+#define DK4_HAVE_HTONS 1
+#else
+#define DK4_HAVE_HTONS 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_NTOHS
+#ifdef _WIN32
+#define DK4_HAVE_NTOHS 1
+#else
+#define DK4_HAVE_NTOHS 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_HTONL
+#ifdef _WIN32
+#define DK4_HAVE_HTONL 1
+#else
+#define DK4_HAVE_HTONL 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_NTOHL
+#ifdef _WIN32
+#define DK4_HAVE_NTOHL 1
+#else
+#define DK4_HAVE_NTOHL 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_GETCWD
+#ifdef _WIN32
+#define DK4_HAVE_GETCWD 0
+#else
+#define DK4_HAVE_GETCWD 1
+#endif
+#endif
+
+#ifndef DK4_HAVE__GETCWD
+#ifdef _WIN32
+#define DK4_HAVE__GETCWD 1
+#else
+#define DK4_HAVE__GETCWD 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__WGETCWD
+#ifdef _WIN32
+#define DK4_HAVE__WGETCWD 1
+#else
+#define DK4_HAVE__WGETCWD 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_INET_ADDR
+#ifdef _WIN32
+#define DK4_HAVE_INET_ADDR 1
+#else
+#define DK4_HAVE_INET_ADDR 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_INET_ATON
+#ifdef _WIN32
+#define DK4_HAVE_INET_ATON 0
+#else
+#define DK4_HAVE_INET_ATON 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_INET_PTON
+#ifdef _WIN32
+#if _MSC_VER >= 1700
+#if DK4_WINDOWS_LEGACY
+#define DK4_HAVE_INET_PTON 0
+#else
+#define DK4_HAVE_INET_PTON 1
+#endif
+#else
+#define DK4_HAVE_INET_PTON 0
+#endif
+#else
+#define DK4_HAVE_INET_PTON 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_INET_NTOP
+#ifdef _WIN32
+#if _MSC_VER >= 1700
+#if DK4_WINDOWS_LEGACY
+#define DK4_HAVE_INET_NTOP 0
+#else
+#define DK4_HAVE_INET_NTOP 1
+#endif
+#else
+#define DK4_HAVE_INET_NTOP 0
+#endif
+#else
+#define DK4_HAVE_INET_NTOP 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_PROC_PID_EXE
+#define DK4_HAVE_PROC_PID_EXE 0
+#endif
+
+#ifndef DK4_HAVE_GETEXECNAME
+#define DK4_HAVE_GETEXECNAME 0
+#endif
+
+#ifndef DK4_HAVE_LSTAT
+#ifdef _WIN32
+#define DK4_HAVE_LSTAT 0
+#else
+#define DK4_HAVE_LSTAT 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_STAT64
+#ifdef _WIN32
+#define DK4_HAVE_STAT64 0
+#else
+#define DK4_HAVE_STAT64 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_LSTAT64
+#ifdef _WIN32
+#define DK4_HAVE_LSTAT64 0
+#else
+#define DK4_HAVE_LSTAT64 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_LOCALTIME_R
+#ifdef _WIN32
+#define DK4_HAVE_LOCALTIME_R 0
+#else
+#define DK4_HAVE_LOCALTIME_R 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_GETEUID
+#ifdef _WIN32
+#define DK4_HAVE_GETEUID 0
+#else
+#define DK4_HAVE_GETEUID 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_FOPEN64
+#ifdef _WIN32
+#define DK4_HAVE_FOPEN64 0
+#else
+#define DK4_HAVE_FOPEN64 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_FOPEN_S
+#ifdef _WIN32
+#define DK4_HAVE_FOPEN_S 1
+#else
+#define DK4_HAVE_FOPEN_S 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__WFOPEN
+#ifdef _WIN32
+#define DK4_HAVE__WFOPEN 1
+#else
+#define DK4_HAVE__WFOPEN 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__WFOPEN64
+#ifdef _WIN32
+#define DK4_HAVE__WFOPEN64 0
+#else
+#define DK4_HAVE__WFOPEN64 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__WFOPEN_S
+#ifdef _WIN32
+#define DK4_HAVE__WFOPEN_S 1
+#else
+#define DK4_HAVE__WFOPEN_S 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_FPUTWS
+#ifdef _WIN32
+#define DK4_HAVE_FPUTWS 1
+#else
+#define DK4_HAVE_FPUTWS 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_FPUTWC
+#ifdef _WIN32
+#define DK4_HAVE_FPUTWC 1
+#else
+#define DK4_HAVE_FPUTWC 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SETBUFFER
+#ifdef _WIN32
+#define DK4_HAVE_SETBUFFER 0
+#else
+#define DK4_HAVE_SETBUFFER 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_SETBUF
+#ifdef _WIN32
+#define DK4_HAVE_SETBUF 1
+#else
+#define DK4_HAVE_SETBUF 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_SETVBUF
+#ifdef _WIN32
+#define DK4_HAVE_SETVBUF 1
+#else
+#define DK4_HAVE_SETVBUF 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_ISFINITE
+#ifdef _WIN32
+#define DK4_HAVE_ISFINITE 0
+#else
+#define DK4_HAVE_ISFINITE 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_ISNORMAL
+#ifdef _WIN32
+#define DK4_HAVE_ISNORMAL 0
+#else
+#define DK4_HAVE_ISNORMAL 1
+#endif
+#endif
+
+#ifndef DK4_HAVE__FINITE
+#ifdef _WIN32
+#define DK4_HAVE__FINITE 1
+#else
+#define DK4_HAVE__FINITE 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_FILENO
+#ifdef _WIN32
+#define DK4_HAVE_FILENO 0
+#else
+#define DK4_HAVE_FILENO 1
+#endif
+#endif
+
+#ifndef DK4_HAVE__FILENO
+#ifdef _WIN32
+#define DK4_HAVE__FILENO 1
+#else
+#define DK4_HAVE__FILENO 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SETMODE
+#ifdef _WIN32
+#define DK4_HAVE_SETMODE 0
+#else
+#define DK4_HAVE_SETMODE 1
+#endif
+#endif
+
+#ifndef DK4_HAVE__SETMODE
+#ifdef _WIN32
+#define DK4_HAVE__SETMODE 1
+#else
+#define DK4_HAVE__SETMODE 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_ISATTY
+#ifdef _WIN32
+#define DK4_HAVE_ISATTY 0
+#else
+#define DK4_HAVE_ISATTY 1
+#endif
+#endif
+
+#ifndef DK4_HAVE__ISATTY
+#ifdef _WIN32
+#define DK4_HAVE__ISATTY 1
+#else
+#define DK4_HAVE__ISATTY 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_STRTOD
+#define DK4_HAVE_STRTOD 1
+#endif
+
+#ifndef DK4_HAVE__STRTOD
+#define DK4_HAVE__STRTOD 0
+#endif
+
+#ifndef DK4_HAVE_WCSTOD
+#define DK4_HAVE_WCSTOD 1
+#endif
+
+#ifndef DK4_HAVE__WCSTOD
+#define DK4_HAVE__WCSTOD 0
+#endif
+
+#ifndef DK4_HAVE__SNPRINTF_S
+#ifdef _WIN32
+#define DK4_HAVE__SNPRINTF_S 1
+#else
+#define DK4_HAVE__SNPRINTF_S 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__SNPRINTF
+#ifdef _WIN32
+#define DK4_HAVE__SNPRINTF 1
+#else
+#define DK4_HAVE__SNPRINTF 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SNPRINTF
+#ifdef _WIN32
+#define DK4_HAVE_SNPRINTF 0
+#else
+#define DK4_HAVE_SNPRINTF 1
+#endif
+#endif
+
+#ifndef DK4_HAVE__SNWPRINTF_S
+#ifdef _WIN32
+#define DK4_HAVE__SNWPRINTF_S 1
+#else
+#define DK4_HAVE__SNWPRINTF_S 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__SNWPRINTF
+#ifdef _WIN32
+#define DK4_HAVE__SNWPRINTF 1
+#else
+#define DK4_HAVE__SNWPRINTF 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SNWPRINTF
+#ifdef _WIN32
+#define DK4_HAVE_SNWPRINTF 0
+#else
+#define DK4_HAVE_SNWPRINTF 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_SWPRINTF
+#ifdef _WIN32
+#define DK4_HAVE_SWPRINTF 1
+#else
+#define DK4_HAVE_SWPRINTF 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_UNLINK
+#ifdef _WIN32
+#define DK4_HAVE_UNLINK 0
+#else
+#define DK4_HAVE_UNLINK 1
+#endif
+#endif
+
+#ifndef DK4_HAVE__UNLINK
+#ifdef _WIN32
+#define DK4_HAVE__UNLINK 1
+#else
+#define DK4_HAVE__UNLINK 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_WUNLINK
+#ifdef _WIN32
+#define DK4_HAVE_WUNLINK 0
+#else
+#define DK4_HAVE_WUNLINK 1
+#endif
+#endif
+
+#ifndef DK4_HAVE__WUNLINK
+#ifdef _WIN32
+#define DK4_HAVE__WUNLINK 1
+#else
+#define DK4_HAVE__WUNLINK 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_MKDIR
+#ifdef _WIN32
+#define DK4_HAVE_MKDIR 0
+#else
+#define DK4_HAVE_MKDIR 1
+#endif
+#endif
+
+#ifndef DK4_HAVE__MKDIR
+#ifdef _WIN32
+#define DK4_HAVE__MKDIR 1
+#else
+#define DK4_HAVE__MKDIR 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_WMKDIR
+#ifdef _WIN32
+#define DK4_HAVE_WMKDIR 0
+#else
+#define DK4_HAVE_WMKDIR 1
+#endif
+#endif
+
+#ifndef DK4_HAVE__WMKDIR
+#ifdef _WIN32
+#define DK4_HAVE__WMKDIR 1
+#else
+#define DK4_HAVE__WMKDIR 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SIGACTION
+#ifdef _WIN32
+#define DK4_HAVE_SIGACTION 0
+#else
+#define DK4_HAVE_SIGACTION 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_SIGSET
+#ifdef _WIN32
+#define DK4_HAVE_SIGSET 0
+#else
+#define DK4_HAVE_SIGSET 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_SIGNAL
+#ifdef _WIN32
+#define DK4_HAVE_SIGNAL 1
+#else
+#define DK4_HAVE_SIGNAL 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_SIGPROCMASK
+#ifdef _WIN32
+#define DK4_HAVE_SIGPROCMASK 0
+#else
+#define DK4_HAVE_SIGPROCMASK 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_SIGEMPTYSET
+#ifdef _WIN32
+#define DK4_HAVE_SIGEMPTYSET 0
+#else
+#define DK4_HAVE_SIGEMPTYSET 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_SETPWENT
+#ifdef _WIN32
+#define DK4_HAVE_SETPWENT 0
+#else
+#define DK4_HAVE_SETPWENT 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_GETPWENT
+#ifdef _WIN32
+#define DK4_HAVE_GETPWENT 0
+#else
+#define DK4_HAVE_GETPWENT 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_ENDPWENT
+#ifdef _WIN32
+#define DK4_HAVE_ENDPWENT 0
+#else
+#define DK4_HAVE_ENDPWENT 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_GETPWNAM
+#ifdef _WIN32
+#define DK4_HAVE_GETPWNAM 0
+#else
+#define DK4_HAVE_GETPWNAM 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_GETPWUID
+#ifdef _WIN32
+#define DK4_HAVE_GETPWUID 0
+#else
+#define DK4_HAVE_GETPWUID 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_SETGRENT
+#ifdef _WIN32
+#define DK4_HAVE_SETGRENT 0
+#else
+#define DK4_HAVE_SETGRENT 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_GETGRENT
+#ifdef _WIN32
+#define DK4_HAVE_GETGRENT 0
+#else
+#define DK4_HAVE_GETGRENT 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_GETGRGID
+#ifdef _WIN32
+#define DK4_HAVE_GETGRGID 0
+#else
+#define DK4_HAVE_GETGRGID 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_GETGRNAM
+#ifdef _WIN32
+#define DK4_HAVE_GETGRNAM 0
+#else
+#define DK4_HAVE_GETGRNAM 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_ENDGRENT
+#ifdef _WIN32
+#define DK4_HAVE_ENDGRENT 0
+#else
+#define DK4_HAVE_ENDGRENT 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_SETUID
+#ifdef _WIN32
+#define DK4_HAVE_SETUID 0
+#else
+#define DK4_HAVE_SETUID 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_SETGID
+#ifdef _WIN32
+#define DK4_HAVE_SETGID 0
+#else
+#define DK4_HAVE_SETGID 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_SETPGRP
+#ifdef _WIN32
+#define DK4_HAVE_SETPGRP 0
+#else
+#define DK4_HAVE_SETPGRP 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_SETSID
+#ifdef _WIN32
+#define DK4_HAVE_SETSID 0
+#else
+#define DK4_HAVE_SETSID 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_SYS_RESOURCE_H
+#ifdef _WIN32
+#define DK4_HAVE_SYS_RESOURCE_H 0
+#else
+#define DK4_HAVE_SYS_RESOURCE_H 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_GETRLIMIT
+#ifdef _WIN32
+#define DK4_HAVE_GETRLIMIT 0
+#else
+#define DK4_HAVE_GETRLIMIT 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_SYSLOG
+#ifdef _WIN32
+#define DK4_HAVE_SYSLOG 0
+#else
+#define DK4_HAVE_SYSLOG 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_SYSLOG_H
+#ifdef _WIN32
+#define DK4_HAVE_SYSLOG_H 0
+#else
+#define DK4_HAVE_SYSLOG_H 1
+#endif
+#endif
+
+#ifndef DK4_HAVE__READ
+#ifdef _WIN32
+#define DK4_HAVE__READ 1
+#else
+#define DK4_HAVE__READ 0
+#endif
+#endif
+
+#ifndef DK4_HAVE__WRITE
+#ifdef _WIN32
+#define DK4_HAVE__WRITE 1
+#else
+#define DK4_HAVE__WRITE 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_READ
+#ifdef _WIN32
+#define DK4_HAVE_READ 0
+#else
+#define DK4_HAVE_READ 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_WRITE
+#ifdef _WIN32
+#define DK4_HAVE_WRITE 0
+#else
+#define DK4_HAVE_WRITE 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_PNG_GET_PIXELS_PER_INCH
+#ifdef _WIN32
+#define DK4_HAVE_PNG_GET_PIXELS_PER_INCH 1
+#else
+#define DK4_HAVE_PNG_GET_PIXELS_PER_INCH 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_PNG_H
+#ifdef _WIN32
+#define DK4_HAVE_PNG_H 1
+#else
+#define DK4_HAVE_PNG_H 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_JPEGLIB_H
+#ifdef _WIN32
+#define DK4_HAVE_JPEGLIB_H 1
+#else
+#define DK4_HAVE_JPEGLIB_H 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_TIFF_H
+#ifdef _WIN32
+#define DK4_HAVE_TIFF_H 1
+#else
+#define DK4_HAVE_TIFF_H 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_SHA224
+#ifdef _WIN32
+#define DK4_HAVE_SHA224 1
+#else
+#define DK4_HAVE_SHA224 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_SHA256
+#ifdef _WIN32
+#define DK4_HAVE_SHA256 1
+#else
+#define DK4_HAVE_SHA256 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_SHA384
+#ifdef _WIN32
+#define DK4_HAVE_SHA384 1
+#else
+#define DK4_HAVE_SHA384 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_SHA512
+#ifdef _WIN32
+#define DK4_HAVE_SHA512 1
+#else
+#define DK4_HAVE_SHA512 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_RAND_EGD
+#ifdef _WIN32
+#define DK4_HAVE_RAND_EGD 0
+#else
+#define DK4_HAVE_RAND_EGD 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_RMDIR
+#ifdef _WIN32
+#define DK4_HAVE_RMDIR 0
+#else
+#define DK4_HAVE_RMDIR 1
+#endif
+#endif
+
+#ifndef DK4_HAVE__RMDIR
+#ifdef _WIN32
+#define DK4_HAVE__RMDIR 1
+#else
+#define DK4_HAVE__RMDIR 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_WRMDIR
+#ifdef _WIN32
+#define DK4_HAVE_WRMDIR 0
+#else
+#define DK4_HAVE_WRMDIR 1
+#endif
+#endif
+
+#ifndef DK4_HAVE__WRMDIR
+#ifdef _WIN32
+#define DK4_HAVE__WRMDIR 1
+#else
+#define DK4_HAVE__WRMDIR 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_GETFINALPATHNAMEBYHANDLE
+#ifdef _WIN32
+#if _MSC_VER >= 1700
+#if DK4_WINDOWS_LEGACY
+#define DK4_HAVE_GETFINALPATHNAMEBYHANDLE 0
+#else
+#define DK4_HAVE_GETFINALPATHNAMEBYHANDLE 1
+#endif
+#else
+#define DK4_HAVE_GETFINALPATHNAMEBYHANDLE 0
+#endif
+#else
+#define DK4_HAVE_GETFINALPATHNAMEBYHANDLE 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_DB_CURSOR_C_GET
+#ifdef _WIN32
+#define DK4_HAVE_DB_CURSOR_C_GET 0
+#else
+#define DK4_HAVE_DB_CURSOR_C_GET 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_CHMOD
+#ifdef _WIN32
+#define DK4_HAVE_CHMOD 0
+#else
+#define DK4_HAVE_CHMOD 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_CHOWN
+#ifdef _WIN32
+#define DK4_HAVE_CHOWN 0
+#else
+#define DK4_HAVE_CHOWN 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_REPARSE_DATA_BUFFER
+#ifdef _WIN32
+#if _MSC_VER >= 1800
+#define DK4_HAVE_REPARSE_DATA_BUFFER 1
+#else
+#define DK4_HAVE_REPARSE_DATA_BUFFER 0
+#endif
+#else
+#define DK4_HAVE_REPARSE_DATA_BUFFER 0
+#endif
+#endif
+
+#if DK4_HAVE_NTIFS_H
+#ifdef _WIN32
+#if _MSC_VER >= 1800
+#define DK4_HAVE_NTIFS_H 1
+#else
+#define DK4_HAVE_NTIFS_H 0
+#endif
+#else
+#define DK4_HAVE_NTIFS_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_DEV_T
+#ifdef _WIN32
+#define DK4_HAVE_DEV_T 0
+#else
+#define DK4_HAVE_DEV_T 1
+#endif
+#endif
+
+#ifndef DK4_HAVE__DEV_T
+#ifdef _WIN32
+#define DK4_HAVE__DEV_T 1
+#else
+#define DK4_HAVE__DEV_T 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_INO_T
+#ifdef _WIN32
+#define DK4_HAVE_INO_T 0
+#else
+#define DK4_HAVE_INO_T 1
+#endif
+#endif
+
+#ifndef DK4_HAVE__INO_T
+#ifdef _WIN32
+#define DK4_HAVE__INO_T 1
+#else
+#define DK4_HAVE__INO_T 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_INO64_T
+#ifdef _WIN32
+#define DK4_HAVE_INO64_T 0
+#else
+#define DK4_HAVE_INO64_T 1
+#endif
+#endif
+
+#ifndef DK4_HAVE__INO64_T
+#define DK4_HAVE__INO64_T 0
+#endif
+
+#ifndef DK4_HAVE_MODE_T
+#ifdef _WIN32
+#define DK4_HAVE_MODE_T 0
+#else
+#define DK4_HAVE_MODE_T 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_NLINK_T
+#ifdef _WIN32
+#define DK4_HAVE_NLINK_T 0
+#else
+#define DK4_HAVE_NLINK_T 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_UID_T
+#ifdef _WIN32
+#define DK4_HAVE_UID_T 0
+#else
+#define DK4_HAVE_UID_T 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_GID_T
+#ifdef _WIN32
+#define DK4_HAVE_GID_T 0
+#else
+#define DK4_HAVE_GID_T 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_GRP_H
+#ifdef _WIN32
+#define DK4_HAVE_GRP_H 0
+#else
+#define DK4_HAVE_GRP_H 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_OFF_T
+#ifdef _WIN32
+#define DK4_HAVE_OFF_T 0
+#else
+#define DK4_HAVE_OFF_T 1
+#endif
+#endif
+
+#ifndef DK4_HAVE__OFF_T
+#ifdef _WIN32
+#define DK4_HAVE__OFF_T 1
+#else
+#define DK4_HAVE__OFF_T 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_OFF64_T
+#ifdef _WIN32
+#define DK4_HAVE_OFF64_T 0
+#else
+#define DK4_HAVE_OFF64_T 1
+#endif
+#endif
+
+#ifndef DK_HAVE__OFF64_T
+#define DK4_HAVE__OFF64_T 0
+#endif
+
+#ifndef DK4_HAVE_BLKSIZE_T
+#ifdef _WIN32
+#define DK4_HAVE_BLKSIZE_T 0
+#else
+#define DK4_HAVE_BLKSIZE_T 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_BLKCNT_T
+#ifdef _WIN32
+#define DK4_HAVE_BLKCNT_T 0
+#else
+#define DK4_HAVE_BLKCNT_T 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_FPOS_T
+#ifdef _WIN32
+#define DK4_HAVE_FPOS_T 1
+#else
+#define DK4_HAVE_FPOS_T 1
+#endif
+#endif
+
+#ifndef DK4_HAVE__FPOS_T
+#ifdef _WIN32
+#define DK4_HAVE__FPOS_T 0
+#else
+#define DK4_HAVE__FPOS_T 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SOCKLEN_T
+#ifdef _WIN32
+#if _MSC_VER >= 1700
+#define DK4_HAVE_SOCKLEN_T 1
+#else
+#define DK4_HAVE_SOCKLEN_T 0
+#endif
+#else
+#define DK4_HAVE_SOCKLEN_T 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_STRUCT_SOCKADDR_IN
+#ifdef _WIN32
+#define DK4_HAVE_STRUCT_SOCKADDR_IN 1
+#else
+#define DK4_HAVE_STRUCT_SOCKADDR_IN 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_STRUCT_SOCKADDR_IN6
+#ifdef _WIN32
+#if DK4_WINDOWS_LEGACY
+#define DK4_HAVE_STRUCT_SOCKADDR_IN6 0
+#else
+#define DK4_HAVE_STRUCT_SOCKADDR_IN6 1
+#endif
+#else
+#define DK4_HAVE_STRUCT_SOCKADDR_IN6 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_STRUCT_SOCKADDR_UN
+#ifdef _WIN32
+#define DK4_HAVE_STRUCT_SOCKADDR_UN 0
+#else
+#define DK4_HAVE_STRUCT_SOCKADDR_UN 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_STRUCT_ADDRINFO
+#ifdef _WIN32
+#define DK4_HAVE_STRUCT_ADDRINFO 0
+#else
+#define DK4_HAVE_STRUCT_ADDRINFO 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_STRUCT_SOCKADDR_STORAGE
+#ifdef _WIN32
+#define DK4_HAVE_STRUCT_SOCKADDR_STORAGE 0
+#else
+#define DK4_HAVE_STRUCT_SOCKADDR_STORAGE 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_IN_ADDR
+#ifdef _WIN32
+#define DK4_HAVE_IN_ADDR 1
+#else
+#define DK4_HAVE_IN_ADDR 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_IN6_ADDR
+#ifdef _WIN32
+#define DK4_HAVE_IN6_ADDR 1
+#else
+#define DK4_HAVE_IN6_ADDR 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_LARGEFILE64_SOURCE
+#ifdef _WIN32
+#define DK4_HAVE_LARGEFILE64_SOURCE 0
+#else
+#define DK4_HAVE_LARGEFILE64_SOURCE 1
+#endif
+#endif
+
+#ifndef DK4_USE_FALLBACK_NUMERIC_LIMITS
+#define DK4_USE_FALLBACK_NUMERIC_LIMITS 0
+#endif
+
+#ifndef DK4_USE_WINDOWS_LOCAL_ALLOC
+#ifdef _WIN32
+#define DK4_USE_WINDOWS_LOCAL_ALLOC 1
+#else
+#define DK4_USE_WINDOWS_LOCAL_ALLOC 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_BACKSLASH_AS_SEP
+#ifdef _WIN32
+#define DK4_HAVE_BACKSLASH_AS_SEP 1
+#else
+#define DK4_HAVE_BACKSLASH_AS_SEP 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_LINE_END_CR_NL
+#ifdef _WIN32
+#define DK4_HAVE_LINE_END_CR_NL 1
+#else
+#define DK4_HAVE_LINE_END_CR_NL 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_CASE_INSENSITIVE_PATHNAMES
+#ifdef _WIN32
+#define DK4_HAVE_CASE_INSENSITIVE_PATHNAMES 1
+#else
+#define DK4_HAVE_CASE_INSENSITIVE_PATHNAMES 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_CASE_INSENSITIVE_USERNAMES
+#ifdef _WIN32
+#define DK4_HAVE_CASE_INSENSITIVE_USERNAMES 1
+#else
+#define DK4_HAVE_CASE_INSENSITIVE_USERNAMES 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_FILE_DEVINO
+#ifdef _WIN32
+#define DK4_HAVE_FILE_DEVINO 0
+#else
+#define DK4_HAVE_FILE_DEVINO 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_FILE_UIDGID
+#ifdef _WIN32
+#define DK4_HAVE_FILE_UIDGID 0
+#else
+#define DK4_HAVE_FILE_UIDGID 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_FILE_BLKSIZECNT
+#ifdef _WIN32
+#define DK4_HAVE_FILE_BLKSIZECNT 0
+#else
+#define DK4_HAVE_FILE_BLKSIZECNT 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_FILE_ATIMECTIME
+#ifdef _WIN32
+#define DK4_HAVE_FILE_ATIMECTIME 0
+#else
+#define DK4_HAVE_FILE_ATIMECTIME 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_STRERROR
+#ifdef _WIN32
+#define DK4_HAVE_STRERROR 1
+#else
+#define DK4_HAVE_STRERROR 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_STRERROR_R
+#ifdef _WIN32
+#define DK4_HAVE_STRERROR_R 1
+#else
+#define DK4_HAVE_STRERROR_R 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_RAND
+#ifdef _WIN32
+#define DK4_HAVE_RAND 1
+#else
+#define DK4_HAVE_RAND 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_SRAND
+#ifdef _WIN32
+#define DK4_HAVE_SRAND 0
+#else
+#define DK4_HAVE_SRAND 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_INITSTATE
+#ifdef _WIN32
+#define DK4_HAVE_INITSTATE 0
+#else
+#define DK4_HAVE_INITSTATE 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_SETSTATE
+#ifdef _WIN32
+#define DK4_HAVE_SETSTATE 0
+#else
+#define DK4_HAVE_SETSTATE 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_RANDOM
+#ifdef _WIN32
+#define DK4_HAVE_RANDOM 0
+#else
+#define DK4_HAVE_RANDOM 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_LRAND48
+#ifdef _WIN32
+#define DK4_HAVE_LRAND48 0
+#else
+#define DK4_HAVE_LRAND48 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_SOCKET
+#ifdef _WIN32
+#define DK4_HAVE_SOCKET 1
+#else
+#define DK4_HAVE_SOCKET 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_NRAND48
+#ifdef _WIN32
+#define DK4_HAVE_NRAND48 0
+#else
+#define DK4_HAVE_NRAND48 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_OPENSSL_RAND_H
+#define DK4_HAVE_OPENSSL_RAND_H 1
+#endif
+
+#ifndef DK4_HAVE_OPENSSL_MD5_H
+#define DK4_HAVE_OPENSSL_MD5_H 1
+#endif
+
+#ifndef DK4_HAVE_OPENSSL_SHA_H
+#define DK4_HAVE_OPENSSL_SHA_H 1
+#endif
+
+#ifndef DK4_HAVE_OPENSSL_RIPEMD_H
+#define DK4_HAVE_OPENSSL_RIPEMD_H 1
+#endif
+
+#ifndef DK4_HAVE_DB_H
+#ifdef _WIN32
+#define DK4_HAVE_DB_H 0
+#else
+#define DK4_HAVE_DB_H 1
+#endif
+#endif
+
+#ifndef DK4_HAVE_NDBM_H
+#ifdef _WIN32
+#define DK4_HAVE_NDBM_H 0
+#else
+#define DK4_HAVE_NDBM_H 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_CRNL
+#ifdef _WIN32
+#define DK4_HAVE_CRNL 1
+#else
+#define DK4_HAVE_CRNL 0
+#endif
+#endif
+
+#ifndef DK4_HAVE_FILEMODE_BINARY
+#ifdef _WIN32
+#define DK4_HAVE_FILEMODE_BINARY 1
+#else
+#define DK4_HAVE_FILEMODE_BINARY 0
+#endif
+#endif
+
+#ifndef DK4_USE_PRINTF_SCANF
+#define DK4_USE_PRINTF_SCANF 1
+#endif
+
+#ifndef DK4_HAVE_COMPATDKTOOLS3
+#define DK4_HAVE_COMPATDKTOOLS3 1
+#endif
+
+
+#endif
+/* ifndef DK4_CON_H_INCLUDED */
diff --git a/support/dktools/win32/dk4wxcs.h b/support/dktools/win32/dk4wxcs.h
new file mode 100644
index 0000000000..32d4f05056
--- /dev/null
+++ b/support/dktools/win32/dk4wxcs.h
@@ -0,0 +1,9 @@
+#ifndef DK4WXCSZ_H_INCLUDED
+/** Protection against multiple inclusions. */
+#define DK4WXCSZ_H_INCLUDED 1
+
+/** Size of wxChar.
+*/
+#define DK4_SIZEOF_WXCHAR 2
+
+#endif
diff --git a/support/dktools/win32/user32.iss b/support/dktools/win32/user32.iss
new file mode 100644
index 0000000000..c22cfe327e
--- /dev/null
+++ b/support/dktools/win32/user32.iss
@@ -0,0 +1,59 @@
+; Script generated by the Inno Setup Script Wizard.
+; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
+
+[Setup]
+; NOTE: The value of AppId uniquely identifies this application.
+; Do not use the same AppId value in installers for other applications.
+; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
+AppId={{9746B24E-DEA3-4597-9E07-F27A15070592}
+AppName=DK tools and libraries (32 bits)
+AppVerName=DK tools and libraries (32 bits), version 4.8.3
+AppVersion=4.8.3
+VersionInfoProductVersion=4.8.3.0
+VersionInfoVersion=4.8.3.0
+AppPublisher=Dirk Krause
+AppPublisherURL=http://dktools.sourceforge.net/
+AppSupportURL=http://dktools.sourceforge.net/
+AppUpdatesURL=http://dktools.sourceforge.net/
+AppCopyright=Copyright (C) 2013-2014 Dirk Krause
+DefaultDirName={pf}\Krause
+DirExistsWarning=no
+DefaultGroupName=DK tools and libraries
+AllowNoIcons=yes
+OutputDir=c:\temp\distri
+OutputBaseFilename=dktools-win32-4.8.3
+Compression=lzma
+SolidCompression=yes
+SetupIconFile=dkctinst.ico
+UninstallDisplayIcon={app}\bin\dk-ls.exe
+ChangesEnvironment=yes
+
+
+[Languages]
+Name: "english"; MessagesFile: "compiler:Default.isl"
+Name: "german"; MessagesFile: "compiler:Languages\German.isl"
+
+; Copy all the files for a base installation
+[Files]
+Source: "C:\krause\bindist\krause32\etc\*"; DestDir: "{app}\etc"; Flags: recursesubdirs ignoreversion
+Source: "C:\krause\bindist\krause32\bin\*"; DestDir: "{app}\bin"; Flags: recursesubdirs ignoreversion
+Source: "C:\krause\bindist\krause32\contrib\*"; DestDir: "{app}\contrib"; Flags: recursesubdirs ignoreversion
+Source: "C:\krause\bindist\krause32\share\*"; DestDir: "{app}\share"; Flags: recursesubdirs ignoreversion
+Source: "C:\krause\bindist\krause32\include\*"; DestDir: "{app}\include"; Flags: recursesubdirs ignoreversion
+Source: "C:\krause\bindist\krause32\lib\*"; DestDir: "{app}\lib"; Flags: recursesubdirs ignoreversion
+; Source: "C:\Krause\bindist\readme.html"; DestDir: "{app}"; Flags: isreadme
+
+[Icons]
+Name: "{group}\{cm:ProgramOnTheWeb,dktools-win32}"; Filename: "http://dktools.sourceforge.net/"
+Name: "{group}\WxBmpp"; Filename: "{app}\bin\wxbmpp.exe"; WorkingDir: "{userappdata}"; Comment: "Bitmap to PS or PDF conversion"
+Name: "{group}\WxDkClock"; Filename: "{app}\bin\wxdkclock.exe"; WorkingDir: "{userappdata}"; Parameters: "-t"; Comment: "Alert clock"
+Name: "{group}\WxDkct"; Filename: "{app}\bin\wxdkct.exe"; WorkingDir: "{userappdata}"; Comment: "C tool (trace/debug, code generators for state machines and wxWidgets-based GUIs)"
+Name: "{group}\WxImgSz"; Filename: "{app}\bin\wximgsz.exe"; WorkingDir: "{userappdata}"; Comment: "Suggest new sizes to scale an image"
+Name: "{group}\WinPrint"; Filename: "{app}\bin\winprint.exe"; WorkingDir: "{userappdata}"; Comment: "Schedule print job file to Windows print queue"
+
+[Run]
+Filename: "{app}\bin\dkwxpath.exe"; Description: "Register directory in PATH."
+
+[UninstallRun]
+Filename: "{app}\bin\dkwxpath.exe"; Parameters: "-u"
+
diff --git a/support/dktools/win32/user64.iss b/support/dktools/win32/user64.iss
new file mode 100644
index 0000000000..63b984c778
--- /dev/null
+++ b/support/dktools/win32/user64.iss
@@ -0,0 +1,60 @@
+; Script generated by the Inno Setup Script Wizard.
+; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
+
+[Setup]
+; NOTE: The value of AppId uniquely identifies this application.
+; Do not use the same AppId value in installers for other applications.
+; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
+AppId={{E8178AB5-99E3-4C64-A242-289A0601F67B}
+AppName=DK tools and libraries (64 bits)
+AppVerName=DK tools and libraries (64 bits), version 4.8.3
+AppVersion=4.8.3
+VersionInfoProductVersion=4.8.3.0
+VersionInfoVersion=4.8.3.0
+AppPublisher=Dirk Krause
+AppPublisherURL=http://dktools.sourceforge.net/
+AppSupportURL=http://dktools.sourceforge.net/
+AppUpdatesURL=http://dktools.sourceforge.net/
+AppCopyright=Copyright (C) 2013-2014 Dirk Krause
+DefaultDirName={pf}\Krause
+DirExistsWarning=no
+DefaultGroupName=DK tools and libraries
+AllowNoIcons=yes
+OutputDir=c:\temp\distri
+OutputBaseFilename=dktools-win64-4.8.3
+Compression=lzma
+SolidCompression=yes
+ArchitecturesInstallIn64BitMode=x64
+SetupIconFile=dkctinst.ico
+UninstallDisplayIcon={app}\bin\dk-ls.exe
+ChangesEnvironment=yes
+
+
+[Languages]
+Name: "english"; MessagesFile: "compiler:Default.isl"
+Name: "german"; MessagesFile: "compiler:Languages\German.isl"
+
+; Copy all the files for a base installation
+[Files]
+Source: "C:\krause\bindist\krause64\etc\*"; DestDir: "{app}\etc"; Flags: recursesubdirs ignoreversion
+Source: "C:\krause\bindist\krause64\bin\*"; DestDir: "{app}\bin"; Flags: recursesubdirs ignoreversion
+Source: "C:\krause\bindist\krause64\contrib\*"; DestDir: "{app}\contrib"; Flags: recursesubdirs ignoreversion
+Source: "C:\krause\bindist\krause64\share\*"; DestDir: "{app}\share"; Flags: recursesubdirs ignoreversion
+Source: "C:\krause\bindist\krause64\include\*"; DestDir: "{app}\include"; Flags: recursesubdirs ignoreversion
+Source: "C:\krause\bindist\krause64\lib\*"; DestDir: "{app}\lib"; Flags: recursesubdirs ignoreversion
+; Source: "C:\Krause\bindist\readme.html"; DestDir: "{app}"; Flags: isreadme
+
+[Icons]
+Name: "{group}\{cm:ProgramOnTheWeb,dktools-win32}"; Filename: "http://dktools.sourceforge.net/"
+Name: "{group}\WxBmpp"; Filename: "{app}\bin\wxbmpp.exe"; WorkingDir: "{userappdata}"; Comment: "Bitmap to PS or PDF conversion"
+Name: "{group}\WxDkClock"; Filename: "{app}\bin\wxdkclock.exe"; WorkingDir: "{userappdata}"; Parameters: "-t"; Comment: "Alert clock"
+Name: "{group}\WxDkct"; Filename: "{app}\bin\wxdkct.exe"; WorkingDir: "{userappdata}"; Comment: "C tool (trace/debug, code generators for state machines and wxWidgets-based GUIs)"
+Name: "{group}\WxImgSz"; Filename: "{app}\bin\wximgsz.exe"; WorkingDir: "{userappdata}"; Comment: "Suggest new sizes to scale an image"
+Name: "{group}\WinPrint"; Filename: "{app}\bin\winprint.exe"; WorkingDir: "{userappdata}"; Comment: "Schedule print job file to Windows print queue"
+
+[Run]
+Filename: "{app}\bin\dkwxpath.exe"; Description: "Register directory in PATH."
+
+[UninstallRun]
+Filename: "{app}\bin\dkwxpath.exe"; Parameters: "-u"
+
diff --git a/support/dktools/win32/user64.iss.in b/support/dktools/win32/user64.iss.in
new file mode 100644
index 0000000000..80feb69e9f
--- /dev/null
+++ b/support/dktools/win32/user64.iss.in
@@ -0,0 +1,60 @@
+; Script generated by the Inno Setup Script Wizard.
+; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
+
+[Setup]
+; NOTE: The value of AppId uniquely identifies this application.
+; Do not use the same AppId value in installers for other applications.
+; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
+AppId={{E8178AB5-99E3-4C64-A242-289A0601F67B}
+AppName=DK tools and libraries (64 bits)
+AppVerName=DK tools and libraries (64 bits), version VERSNO
+AppVersion=VERSNO
+VersionInfoProductVersion=VERSNO.0
+VersionInfoVersion=VERSNO.0
+AppPublisher=Dirk Krause
+AppPublisherURL=http://dktools.sourceforge.net/
+AppSupportURL=http://dktools.sourceforge.net/
+AppUpdatesURL=http://dktools.sourceforge.net/
+AppCopyright=Copyright (C) 2013-2014 Dirk Krause
+DefaultDirName={pf}\Krause
+DirExistsWarning=no
+DefaultGroupName=DK tools and libraries
+AllowNoIcons=yes
+OutputDir=c:\temp\distri
+OutputBaseFilename=dktools-win64-VERSNO
+Compression=lzma
+SolidCompression=yes
+ArchitecturesInstallIn64BitMode=x64
+SetupIconFile=dkctinst.ico
+UninstallDisplayIcon={app}\bin\dk-ls.exe
+ChangesEnvironment=yes
+
+
+[Languages]
+Name: "english"; MessagesFile: "compiler:Default.isl"
+Name: "german"; MessagesFile: "compiler:Languages\German.isl"
+
+; Copy all the files for a base installation
+[Files]
+Source: "C:\krause\bindist\krause64\etc\*"; DestDir: "{app}\etc"; Flags: recursesubdirs ignoreversion
+Source: "C:\krause\bindist\krause64\bin\*"; DestDir: "{app}\bin"; Flags: recursesubdirs ignoreversion
+Source: "C:\krause\bindist\krause64\contrib\*"; DestDir: "{app}\contrib"; Flags: recursesubdirs ignoreversion
+Source: "C:\krause\bindist\krause64\share\*"; DestDir: "{app}\share"; Flags: recursesubdirs ignoreversion
+Source: "C:\krause\bindist\krause64\include\*"; DestDir: "{app}\include"; Flags: recursesubdirs ignoreversion
+Source: "C:\krause\bindist\krause64\lib\*"; DestDir: "{app}\lib"; Flags: recursesubdirs ignoreversion
+; Source: "C:\Krause\bindist\readme.html"; DestDir: "{app}"; Flags: isreadme
+
+[Icons]
+Name: "{group}\{cm:ProgramOnTheWeb,dktools-win32}"; Filename: "http://dktools.sourceforge.net/"
+Name: "{group}\WxBmpp"; Filename: "{app}\bin\wxbmpp.exe"; WorkingDir: "{userappdata}"; Comment: "Bitmap to PS or PDF conversion"
+Name: "{group}\WxDkClock"; Filename: "{app}\bin\wxdkclock.exe"; WorkingDir: "{userappdata}"; Parameters: "-t"; Comment: "Alert clock"
+Name: "{group}\WxDkct"; Filename: "{app}\bin\wxdkct.exe"; WorkingDir: "{userappdata}"; Comment: "C tool (trace/debug, code generators for state machines and wxWidgets-based GUIs)"
+Name: "{group}\WxImgSz"; Filename: "{app}\bin\wximgsz.exe"; WorkingDir: "{userappdata}"; Comment: "Suggest new sizes to scale an image"
+Name: "{group}\WinPrint"; Filename: "{app}\bin\winprint.exe"; WorkingDir: "{userappdata}"; Comment: "Schedule print job file to Windows print queue"
+
+[Run]
+Filename: "{app}\bin\dkwxpath.exe"; Description: "Register directory in PATH."
+
+[UninstallRun]
+Filename: "{app}\bin\dkwxpath.exe"; Parameters: "-u"
+
diff --git a/support/dktools/winprint.h b/support/dktools/winprint.h
new file mode 100644
index 0000000000..1acf24b031
--- /dev/null
+++ b/support/dktools/winprint.h
@@ -0,0 +1,95 @@
+
+#ifndef H_INCLUDED_winprint
+/** Include file only once.
+*/
+#define H_INCLUDED_winprint 1
+
+#include <dk3all.h>
+#include <dk3print.h>
+#include <dk3prcfg.h>
+#include <dk3prreq.h>
+
+
+#include <wx/wxprec.h>
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#include <wx/wx.h>
+#endif
+#include <wx/arrstr.h>
+#include <wx/config.h>
+#include <wx/filename.h>
+#include <wx/gbsizer.h>
+#include <wx/thread.h>
+#include <wx/gauge.h>
+#include <wx/help.h>
+#include <wx/fs_zip.h>
+#include <wx/cmdline.h>
+#include <wx/dir.h>
+#include <wx/version.h>
+/* __CHANGE__ 018: Add futher wxWidgets header files.
+*/
+
+#include <dk3wxs.h>
+
+#include <DkWxAppHelper.h>
+#include <DkWxFrame.h>
+#include <DkWxCommunicator.h>
+#include <DkWxProgressDialog.h>
+#include <DkWxHelpController.h>
+#include <DkWxColorView.h>
+
+#include "WinprintApp.h"
+#include "WinprintFrame.h"
+#include "WinprintThread.h"
+#include "WinprintChooserDialog.h"
+
+
+/* __CHANGE__ 018: Add header files for further classes and modules.
+*/
+
+/** @defgroup winprintwxids wxWidgets IDs.
+*/
+/**@{*/
+/** Exit application.
+*/
+#define WinprintFrame_Quit (wxID_EXIT)
+
+/** Main window ID.
+*/
+#define WinprintFrame_MainWindow ((wxID_HIGHEST) + 1)
+
+/** Show version dialog box.
+*/
+#define WinprintFrame_Help_About ((WinprintFrame_MainWindow) + 1)
+
+/** Open table of contents for online help.
+*/
+#define WinprintFrame_Help_Contents ((WinprintFrame_Help_About) + 1)
+
+/** Schedule print data.
+*/
+#define WinprintFrame_Print ((WinprintFrame_Help_Contents) + 1)
+
+/* __CHANGE__ 017: Add further IDs here as needed.
+*/
+/**@}*/
+
+
+
+/** @defgroup winprintprogress Progress levels vor winprint.
+*/
+/**@{*/
+
+/** Printer opened.
+*/
+#define WINPRINT_LEVEL_1 100
+
+/** File created.
+*/
+#define WINPRINT_LEVEL_2 900
+
+/**@}*/
+#endif
+
diff --git a/support/dktools/winprint.rc b/support/dktools/winprint.rc
new file mode 100644
index 0000000000..b2305d6c43
--- /dev/null
+++ b/support/dktools/winprint.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Schedule file to Windows print queue\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "Schedule file to Windows print queue\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "winprint\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/wprclean.c b/support/dktools/wprclean.c
new file mode 100644
index 0000000000..b2bb5a2f5c
--- /dev/null
+++ b/support/dktools/wprclean.c
@@ -0,0 +1,800 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: wprclean.ctr
+*/
+
+/*
+Copyright (C) 2013-2017, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file wprclean.c The wprclean module.
+*/
+
+
+#line 8 "wprclean.ctr"
+
+#include "dk3all.h"
+#include "dk3print.h"
+#include "dk3prcfg.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4vers.h"
+
+
+
+
+
+#line 20 "wprclean.ctr"
+
+
+
+/** Job structure.
+*/
+typedef struct {
+ dk3_app_t *app; /**< Application structure. */
+ dkChar const * const *msg; /**< Localized texts. */
+ dkChar const * const *nlmsg; /**< Not localized texts. */
+ dk3_option_set_t *opt; /**< Options. */
+ dk3_print_conf_t *pc; /**< Print configuration. */
+ int cmd; /**< Command to execute. */
+ int comp; /**< Only jobs from this machine. */
+ int exval; /**< Exit status code. */
+} WPC_JOB;
+
+
+
+#if DK3_ON_WINDOWS
+
+/** Information required to delete a print job.
+*/
+typedef struct {
+ DWORD position; /**< Position in queue. */
+ DWORD jobid; /**< Job ID. */
+} wprclean_printjob_t;
+
+#endif
+
+
+
+#ifndef WPRCLEAN_QUEUE_JOB_LIST_SIZE
+/** Buffer size for job list.
+*/
+#define WPRCLEAN_QUEUE_JOB_LIST_SIZE 4096
+#endif
+
+
+
+#ifndef WPRCLEAN_NUM_JOBS
+/** Number of jobs to retrieve at once.
+*/
+#define WPRCLEAN_NUM_JOBS 64
+#endif
+
+
+
+/** Texts used by the program, not localized.
+*/
+static dkChar const * const wprclean_nlmsg[] = {
+/* 0 */
+dkT("dktools"),
+
+/* 1 */
+dkT("wprclean.str"),
+
+/* 2 */
+dkT("wprclean.txt"),
+
+NULL
+
+
+#line 84 "wprclean.ctr"
+};
+
+
+
+/** Texts used by the program, replaced by localized versions.
+*/
+static dkChar const * const wprclean_msg[] = {
+/* 0 */
+dkT("Print job "),
+
+/* 1 */
+dkT(" deleted."),
+
+/* 2 */
+dkT("Failed to delete print job "),
+
+/* 3 */
+dkT(", reason: "),
+
+/* 4 */
+dkT("."),
+
+/* 5 */
+dkT("Failed to open printer \""),
+
+/* 6 */
+dkT("\"!"),
+
+/* 7 */
+dkT("Printer \""),
+
+/* 8 */
+dkT("\" not found!"),
+
+NULL
+
+
+#line 114 "wprclean.ctr"
+};
+
+
+
+/** Options for the wprclean program.
+*/
+static dk3_option_t const wprclean_options[] = {
+ { dkT('h'), dkT("help"), 0 },
+ { dkT('v'), dkT("version"), 0 },
+ { dkT('L'), dkT("license-terms"), 0 },
+ { dkT('c'), dkT("computer"), 0}
+};
+
+
+/** Number of options in wprclean_options.
+*/
+static size_t const wprclean_sz_options =
+sizeof(wprclean_options)/sizeof(dk3_option_t);
+
+
+
+/** Default help text shown if help file not found.
+*/
+static dkChar const * const wprclean_text_help[] = {
+dkT(""),
+dkT("NAME"),
+dkT(""),
+dkT(" wprclean - Windows print cleanup"),
+dkT(""),
+dkT("SYNOPSIS"),
+dkT(""),
+dkT(" wprclean [-c] [<printers>]"),
+dkT(" wprclean [-h] [-v] [-L]"),
+dkT(""),
+dkT("DESCRIPTION"),
+dkT(""),
+dkT("The wprclean program deletes all print jobs created by the current user."),
+dkT("It is intended for use in computer labs or PC classrooms in schools and"),
+dkT("universities."),
+dkT(""),
+dkT("OPTIONS"),
+dkT(""),
+dkT("-c"),
+dkT("--computer"),
+dkT("\tRemove only print jobs created on the current computer."),
+dkT(""),
+dkT("-h"),
+dkT("--help"),
+dkT("\tShow this help text."),
+dkT(""),
+dkT("-v"),
+dkT("--version"),
+dkT("\tShow version information."),
+dkT(""),
+dkT("-L"),
+dkT("--license-terms"),
+dkT("\tShow the license terms."),
+dkT(""),
+dkT("EXIT STATUS"),
+dkT(""),
+dkT("0 on success, all other exit status codes indicate an error."),
+dkT(""),
+dkT("FILES"),
+dkT(""),
+dkT("The dk3print.conf file can be used to conigure short alias names for"),
+dkT("Windows print queues."),
+dkT(""),
+dkT("AUTHOR"),
+dkT(""),
+dkT("Dirk Krause"),
+dkT(""),
+dkT("COPYRIGHT AND LICENSE"),
+dkT(""),
+dkT("Run"),
+dkT(" wprclean --license"),
+dkT("to see the license conditions."),
+dkT(""),
+dkT("SEE ALSO"),
+dkT(""),
+dkT("http://dktools.sourceforge.net"),
+dkT(""),
+NULL
+
+
+#line 197 "wprclean.ctr"
+};
+
+
+
+/** License conditions.
+*/
+static dkChar const * const wprclean_text_license[] = {
+dkT("Copyright (c) 2013-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above copyright notice,"),
+dkT(" this list of conditions and the following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("* Neither the name of the copyright holder(s) nor the names of"),
+dkT(" contributors may be used to endorse or promote products derived from "),
+dkT(" this software without specific prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS"),
+dkT("\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT"),
+dkT("LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR"),
+dkT("A PARTICULAR PURPOSE ARE DISCLAIMED."),
+dkT(""),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS"),
+dkT("OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)"),
+dkT("HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,"),
+dkT("STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING"),
+dkT("IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE"),
+dkT("POSSIBILITY OF SUCH DAMAGE."),
+dkT(""),
+NULL
+
+
+#line 235 "wprclean.ctr"
+};
+
+
+
+/** Version information.
+*/
+static dkChar const wprclean_version[] = { DKT_VERSION_DK };
+
+
+#if DK3_ON_WINDOWS
+
+
+/** Delete print job information.
+ @param jptr Print job to delete.
+*/
+static
+void
+wprclean_printjob_delete(wprclean_printjob_t *jptr)
+{
+ dk3_release(jptr);
+}
+
+
+
+static
+wprclean_printjob_t *
+wprclean_printjob_new(DWORD pos, DWORD jid, dk3_app_t *app)
+{
+ wprclean_printjob_t *back = NULL;
+ back = dk3_new_app(wprclean_printjob_t,1,app);
+ if(back) {
+ back->position = pos;
+ back->jobid = jid;
+ }
+ return back;
+}
+
+
+
+/** Compare print jobs by position, largest number first.
+ @param l Left job.
+ @param r Right job.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+static
+int
+wprclean_compare_printjobs(void const *l, void const *r, int cr)
+{
+ wprclean_printjob_t const *pl; /* Left print job. */
+ wprclean_printjob_t const *pr; /* Right print job. */
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (wprclean_printjob_t const *)l;
+ pr = (wprclean_printjob_t const *)r;
+ if(pl->position > pr->position) {
+ back = 1;
+ } else {
+ if(pl->position < pr->position) {
+ back = -1;
+ }
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+
+ /* Invert.
+ */
+ switch(back) {
+ case 1: {
+ back = -1;
+ } break;
+ case -1: {
+ back = 1;
+ } break;
+ }
+ return back;
+}
+
+
+#endif
+/* DK3_ON_WINDOWS */
+
+
+
+
+/** Delete the current users jobs from the printer.
+ @param job Job structure.
+ @param pr Printer.
+*/
+static
+void
+wprclean_windows_printer(WPC_JOB *job, dk3_printer_t *pr)
+{
+#if DK3_ON_WINDOWS
+ dkChar cn[DK3_MAX_PATH]; /* Current computer name. */
+ dkChar nb1[64]; /* Job ID as text. */
+ dkChar nb2[64]; /* Last error as text. */
+ char peb[WPRCLEAN_QUEUE_JOB_LIST_SIZE];
+ /* Buffer for enumeration. */
+#if DK3_CHAR_SIZE > 1
+ JOB_INFO_1W *jobptr; /* Current print job. */
+#else
+ JOB_INFO_1A *jobptr; /* Current print job. */
+#endif
+ wprclean_printjob_t *pj; /* Current job to mark for deletion. */
+ dk3_sto_t *sJobs; /* Storage for jobs to delete. */
+ dk3_sto_it_t *iJobs; /* Iterator through storage. */
+ wprclean_printjob_t *jptr; /* Current job to delete. */
+ dkChar const *logname; /* Current users login name. */
+ HANDLE hPr; /* Handle for printer. */
+ DWORD szpeb; /* Size of peb buffer. */
+ DWORD cbNeeded; /* Number of bytes needed. */
+ DWORD cbReturned; /* Number of print jobs returned. */
+ DWORD startindex; /* Start index for enumeration. */
+ DWORD i; /* Index of current job. */
+ DWORD le; /* Last error code. */
+ BOOL bres; /* Operation result. */
+ BOOL cc; /* Flag: Can continue. */
+ BOOL mustsave; /* Flag: Must mark job for deletion. */
+
+
+#line 362 "wprclean.ctr"
+ logname = dk3app_get_logname(job->app);
+ if(logname) {
+
+#line 364 "wprclean.ctr"
+ if(dk3sf_get_hostname_app(cn,DK3_MAX_PATH,job->app)) {
+
+#line 365 "wprclean.ctr"
+ sJobs = dk3sto_open_app(job->app);
+ if(sJobs) {
+
+#line 367 "wprclean.ctr"
+ dk3sto_set_comp(sJobs, wprclean_compare_printjobs, 0);
+ iJobs = dk3sto_it_open(sJobs);
+ if(iJobs) {
+
+#line 370 "wprclean.ctr"
+ hPr = INVALID_HANDLE_VALUE;
+#if DK3_CHAR_SIZE > 1
+ bres = OpenPrinterW((dkChar *)(pr->name), &hPr, NULL);
+#else
+ bres = OpenPrinterA((dkChar *)(pr->name), &hPr, NULL);
+#endif
+ if(bres) {
+
+#line 377 "wprclean.ctr"
+ dk3sf_initialize_stdout();
+ dk3sf_fputs(pr->name, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ fflush(stdout);
+ /* Enumerate print jobs.
+ */
+ cc = TRUE;
+ startindex = 0;
+ while(cc) {
+ cbNeeded = 0; cbReturned = 0; szpeb = sizeof(peb);
+#if DK3_CHAR_SIZE > 1
+ bres = EnumJobsW(
+ hPr, startindex, (DWORD)WPRCLEAN_NUM_JOBS, 1,
+ (LPBYTE)peb, szpeb, &cbNeeded, &cbReturned
+ );
+#else
+ bres = EnumJobsA(
+ hPr, startindex, (DWORD)WPRCLEAN_NUM_JOBS, 1,
+ (LPBYTE)peb, szpeb, &cbNeeded, &cbReturned
+ );
+#endif
+ if(bres) {
+
+#line 399 "wprclean.ctr"
+ if(cbReturned > 0) {
+
+#line 400 "wprclean.ctr"
+#if DK3_CHAR_SIZE > 1
+ jobptr = (JOB_INFO_1W *)peb;
+#else
+ jobptr = (JOB_INFO_1A *)peb;
+#endif
+ for(i = 0; i < cbReturned; i++) {
+ mustsave = FALSE;
+ if(jobptr->pUserName) {
+
+#line 408 "wprclean.ctr"
+ if(dk3str_casecmp(logname, jobptr->pUserName) == 0) {
+
+
+#line 410 "wprclean.ctr"
+ if(job->comp) {
+ if(jobptr->pMachineName) {
+
+
+#line 413 "wprclean.ctr"
+ if(dk3str_casecmp(cn, jobptr->pMachineName) == 0) {
+
+
+#line 415 "wprclean.ctr"
+ mustsave = TRUE;
+ } else {
+ if(dkT('\\') == (jobptr->pMachineName)[0]) {
+ if(dkT('\\') == (jobptr->pMachineName)[1]) {
+ if(dk3str_casecmp(cn, &((jobptr->pMachineName)[2])) == 0) {
+ mustsave = TRUE;
+ }
+ }
+ }
+ }
+ } else {
+
+#line 426 "wprclean.ctr"
+ mustsave = TRUE;
+ }
+ } else {
+ mustsave = TRUE;
+ }
+ }
+ }
+ if(mustsave) {
+
+#line 434 "wprclean.ctr"
+ pj = wprclean_printjob_new(
+ jobptr->Position, jobptr->JobId, job->app
+ );
+ if(pj) {
+
+#line 438 "wprclean.ctr"
+ if(!dk3sto_add(sJobs, (void *)pj)) {
+ wprclean_printjob_delete(pj);
+
+#line 440 "wprclean.ctr"
+ job->exval = 1;
+ }
+ } else {
+
+#line 443 "wprclean.ctr"
+ job->exval = 1;
+ }
+ }
+ jobptr++;
+ }
+ startindex += cbReturned;
+ } else {
+
+#line 450 "wprclean.ctr"
+ cc = FALSE;
+ }
+ } else {
+
+#line 453 "wprclean.ctr"
+ cc = FALSE;
+ }
+ }
+
+ /* Remove saved print jobs from queue.
+ */
+ dk3sto_it_reset(iJobs);
+ while(NULL != (jptr = (wprclean_printjob_t *)dk3sto_it_next(iJobs))) {
+
+
+#line 462 "wprclean.ctr"
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(nb1,dkT("%lu"),(unsigned long)(jptr->jobid));
+#else
+ if (!(dk3ma_um_to_string(nb1,DK3_SIZEOF(nb1,dkChar),(dk3_um_t)(jptr->jobid)))) {
+ nb1[0] = dkT('\0');
+ }
+#endif
+#if DK3_CHAR_SIZE > 1
+ bres = SetJobW(hPr, jptr->jobid, 0, NULL, JOB_CONTROL_DELETE);
+#else
+ bres = SetJobA(hPr, jptr->jobid, 0, NULL, JOB_CONTROL_DELETE);
+#endif
+ if(bres) {
+ /* DELETED */
+ dk3sf_fputc(dkT('\t'), stdout);
+ dk3sf_fputs((job->msg)[0], stdout);
+ dk3sf_fputs(nb1, stdout);
+ dk3sf_fputs((job->msg)[1], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ fflush(stdout);
+ } else {
+ /* FAILED */
+ le = GetLastError();
+ dk3sf_fputc(dkT('\t'), stdout);
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(nb2,dkT("%lu"),(unsigned long)le);
+#else
+ if(!(dk3ma_um_to_string(nb2,DK3_SIZEOF(nb2,dkChar),(dk3_um_t)le)))
+ {
+ nb2[0] = dkT('\0');
+ }
+#endif
+ dk3sf_fputs((job->msg)[2], stdout);
+ dk3sf_fputs(nb1, stdout);
+ dk3sf_fputs((job->msg)[3], stdout);
+ dk3sf_fputs(nb2, stdout);
+ dk3sf_fputs((job->msg)[4], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ fflush(stdout);
+ job->exval = 1;
+ }
+ }
+
+ ClosePrinter(hPr);
+ } else {
+
+#line 507 "wprclean.ctr"
+ /* ERROR: Failed to open printer! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 5, 6, pr->name);
+ job->exval = 1;
+ }
+
+ /* Release saved jobs.
+ */
+ dk3sto_it_reset(iJobs);
+ while(NULL != (jptr = (wprclean_printjob_t *)dk3sto_it_next(iJobs))) {
+ wprclean_printjob_delete(jptr);
+ }
+ dk3sto_it_close(iJobs);
+ } else {
+ job->exval = 1;
+ }
+ dk3sto_close(sJobs);
+ } else {
+ job->exval = 1;
+ }
+ } else {
+ /* ERROR: Failed to find host name */
+ job->exval = 1;
+ }
+ } else {
+ /* ERROR: Failed to find log name */
+ job->exval = 1;
+ }
+
+#line 534 "wprclean.ctr"
+#endif
+}
+
+
+
+/** Clean up all printers on the system.
+ @param job Job structure.
+*/
+static
+void
+wprclean_cleanup_all_printers(WPC_JOB *job)
+{
+ void *vptr; /* Current printer as returned from iterator. */
+ dk3_printer_t *pr; /* Current printer. */
+
+ dk3sto_it_reset((job->pc)->iPrinters);
+ while(NULL != (vptr = dk3sto_it_next((job->pc)->iPrinters))) {
+ pr = (dk3_printer_t *)vptr;
+ if(DK3_PRINTER_TYPE_WINDOWS == pr->t_p) {
+ wprclean_windows_printer(job, pr);
+ }
+ }
+}
+
+
+
+/** Clean up the named printers.
+ @param job Job structure.
+ @param numargs Number of command line arguments.
+*/
+static
+void
+wprclean_cleanup_named_printers(WPC_JOB *job, int numargs)
+{
+ dkChar const *pn; /* Printer name. */
+ dk3_printer_t *pr; /* Printer. */
+ int i; /* Index of current printer. */
+
+ /* Pass 1: Local Windows printers.
+ */
+ for(i = 0; i < numargs; i++) {
+ pn = dk3opt_get_arg(job->opt, i);
+ if(pn) {
+ pr = dk3print_get_printer(job->pc, pn);
+ if(pr) {
+ if(DK3_PRINTER_TYPE_WINDOWS == pr->t_p) {
+ wprclean_windows_printer(job, pr);
+ }
+ } else {
+ job->exval = 1;
+ /* ERROR: Printer not found! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 7, 8, pn);
+ }
+ }
+ }
+}
+
+
+
+/** Do cleanup.
+ @param job Job structure.
+*/
+static
+void
+wprclean_do_cleanup(WPC_JOB *job)
+{
+ int numargs; /* Number of command line arguments. */
+
+ job->pc = dk3print_conf_open(job->app, 1);
+ if(job->pc) {
+ numargs = dk3opt_get_num_args(job->opt);
+ job->exval = 0;
+ if(0 == numargs) {
+ wprclean_cleanup_all_printers(job);
+ } else {
+ wprclean_cleanup_named_printers(job, numargs);
+ }
+ dk3print_conf_close(job->pc); job->pc = NULL;
+ }
+}
+
+
+
+/** Run with a configured job structure.
+ @param job Job structure.
+*/
+static
+void
+wprclean_run(WPC_JOB *job)
+{
+ job->opt = dk3opt_open_from_app(
+ wprclean_options, wprclean_sz_options,
+ dkT('\0'), NULL,
+ job->app
+ );
+ if(job->opt) {
+ if(0 == dk3opt_get_error_code(job->opt)) {
+ if(dk3opt_is_set(job->opt, dkT('h'))) {
+ job->cmd |= DK3_APP_CMD_HELP;
+ }
+ if(dk3opt_is_set(job->opt, dkT('v'))) {
+ job->cmd |= DK3_APP_CMD_VERSION;
+ }
+ if(dk3opt_is_set(job->opt, dkT('L'))) {
+ job->cmd |= DK3_APP_CMD_LICENSE;
+ }
+ if(dk3opt_is_set(job->opt, dkT('c'))) {
+ job->comp = 1;
+ }
+ if(0 == job->cmd) {
+ wprclean_do_cleanup(job);
+ } else {
+ job->exval = 0;
+ dk3sf_initialize_stdout();
+ if((job->cmd) & DK3_APP_CMD_VERSION) {
+ dk3sf_fputs(wprclean_version, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ if((job->cmd) & DK3_APP_CMD_LICENSE) {
+ dk3sf_fputt(wprclean_text_license, stdout);
+ }
+ if((job->cmd) & DK3_APP_CMD_HELP) {
+ dk3app_help(job->app, wprclean_nlmsg[2], wprclean_text_help);
+ }
+ }
+ }
+ dk3opt_close(job->opt); job->opt = NULL;
+ }
+}
+
+
+
+/** Program entry point.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, any other value indicates an error.
+*/
+DK3_MAIN
+{
+ WPC_JOB job; /* wprclean job. */
+ int exval = 1; /* Exit status code. */
+
+
+#line 676 "wprclean.ctr"
+
+
+#line 677 "wprclean.ctr"
+ job.app = dk3app_open_command(
+ argc, (dkChar const * const *)argv, wprclean_nlmsg[0]
+ );
+ if(job.app) {
+ job.msg = dk3app_messages(
+ job.app, wprclean_nlmsg[1], (dkChar const **)wprclean_msg
+ );
+ job.nlmsg = wprclean_nlmsg;
+ job.cmd = 0;
+ job.comp = 0;
+ job.exval = 1;
+ job.pc = NULL;
+ wprclean_run(&job);
+ exval = job.exval;
+ dk3app_close(job.app);
+ } else {
+ fputs("wprclean: ERROR: Not enough memory!\n", stderr);
+ fflush(stderr);
+ }
+
+
+#line 697 "wprclean.ctr"
+
+
+#line 698 "wprclean.ctr"
+ fflush(stdout);
+ exit(exval); return exval;
+}
+
+
diff --git a/support/dktools/wprclean.ctr b/support/dktools/wprclean.ctr
new file mode 100644
index 0000000000..0468a02ced
--- /dev/null
+++ b/support/dktools/wprclean.ctr
@@ -0,0 +1,702 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2013-xxxx
+license = bsd
+
+%% module
+
+#include "dk3all.h"
+#include "dk3print.h"
+#include "dk3prcfg.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4vers.h"
+
+
+
+$!trace-include
+
+
+
+/** Job structure.
+*/
+typedef struct {
+ dk3_app_t *app; /**< Application structure. */
+ dkChar const * const *msg; /**< Localized texts. */
+ dkChar const * const *nlmsg; /**< Not localized texts. */
+ dk3_option_set_t *opt; /**< Options. */
+ dk3_print_conf_t *pc; /**< Print configuration. */
+ int cmd; /**< Command to execute. */
+ int comp; /**< Only jobs from this machine. */
+ int exval; /**< Exit status code. */
+} WPC_JOB;
+
+
+
+#if DK3_ON_WINDOWS
+
+/** Information required to delete a print job.
+*/
+typedef struct {
+ DWORD position; /**< Position in queue. */
+ DWORD jobid; /**< Job ID. */
+} wprclean_printjob_t;
+
+#endif
+
+
+
+#ifndef WPRCLEAN_QUEUE_JOB_LIST_SIZE
+/** Buffer size for job list.
+*/
+#define WPRCLEAN_QUEUE_JOB_LIST_SIZE 4096
+#endif
+
+
+
+#ifndef WPRCLEAN_NUM_JOBS
+/** Number of jobs to retrieve at once.
+*/
+#define WPRCLEAN_NUM_JOBS 64
+#endif
+
+
+
+/** Texts used by the program, not localized.
+*/
+static dkChar const * const wprclean_nlmsg[] = {
+$!string-table macro=dkT
+#
+# 0: Program group name
+#
+dktools
+#
+# 1: String table file name.
+#
+wprclean.str
+#
+# 2: Help file name.
+#
+wprclean.txt
+$!end
+};
+
+
+
+/** Texts used by the program, replaced by localized versions.
+*/
+static dkChar const * const wprclean_msg[] = {
+$!string-table macro=dkT
+#
+# 0 1
+#
+Print job
+ deleted.
+#
+# 2 3 4
+#
+Failed to delete print job
+, reason:
+.
+#
+# 5 6
+#
+Failed to open printer "
+"!
+#
+# 7 8
+#
+Printer "
+" not found!
+$!end
+};
+
+
+
+/** Options for the wprclean program.
+*/
+static dk3_option_t const wprclean_options[] = {
+ { dkT('h'), dkT("help"), 0 },
+ { dkT('v'), dkT("version"), 0 },
+ { dkT('L'), dkT("license-terms"), 0 },
+ { dkT('c'), dkT("computer"), 0}
+};
+
+
+/** Number of options in wprclean_options.
+*/
+static size_t const wprclean_sz_options =
+sizeof(wprclean_options)/sizeof(dk3_option_t);
+
+
+
+/** Default help text shown if help file not found.
+*/
+static dkChar const * const wprclean_text_help[] = {
+$!text macro=dkT
+
+NAME
+
+ wprclean - Windows print cleanup
+
+SYNOPSIS
+
+ wprclean [-c] [<printers>]
+ wprclean [-h] [-v] [-L]
+
+DESCRIPTION
+
+The wprclean program deletes all print jobs created by the current user.
+It is intended for use in computer labs or PC classrooms in schools and
+universities.
+
+OPTIONS
+
+-c
+--computer
+ Remove only print jobs created on the current computer.
+
+-h
+--help
+ Show this help text.
+
+-v
+--version
+ Show version information.
+
+-L
+--license-terms
+ Show the license terms.
+
+EXIT STATUS
+
+0 on success, all other exit status codes indicate an error.
+
+FILES
+
+The dk3print.conf file can be used to conigure short alias names for
+Windows print queues.
+
+AUTHOR
+
+Dirk Krause
+
+COPYRIGHT AND LICENSE
+
+Run
+ wprclean --license
+to see the license conditions.
+
+SEE ALSO
+
+http://dktools.sourceforge.net
+
+$!end
+};
+
+
+
+/** License conditions.
+*/
+static dkChar const * const wprclean_text_license[] = {
+$!text macro=dkT
+Copyright (c) 2013-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the copyright holder(s) nor the names of
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+$!end
+};
+
+
+
+/** Version information.
+*/
+static dkChar const wprclean_version[] = { DKT_VERSION_DK };
+
+
+#if DK3_ON_WINDOWS
+
+
+/** Delete print job information.
+ @param jptr Print job to delete.
+*/
+static
+void
+wprclean_printjob_delete(wprclean_printjob_t *jptr)
+{
+ dk3_release(jptr);
+}
+
+
+
+static
+wprclean_printjob_t *
+wprclean_printjob_new(DWORD pos, DWORD jid, dk3_app_t *app)
+{
+ wprclean_printjob_t *back = NULL;
+ back = dk3_new_app(wprclean_printjob_t,1,app);
+ if(back) {
+ back->position = pos;
+ back->jobid = jid;
+ }
+ return back;
+}
+
+
+
+/** Compare print jobs by position, largest number first.
+ @param l Left job.
+ @param r Right job.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result.
+*/
+static
+int
+wprclean_compare_printjobs(void const *l, void const *r, int cr)
+{
+ wprclean_printjob_t const *pl; /* Left print job. */
+ wprclean_printjob_t const *pr; /* Right print job. */
+ int back = 0;
+ if(l) {
+ if(r) {
+ pl = (wprclean_printjob_t const *)l;
+ pr = (wprclean_printjob_t const *)r;
+ if(pl->position > pr->position) {
+ back = 1;
+ } else {
+ if(pl->position < pr->position) {
+ back = -1;
+ }
+ }
+ } else {
+ back = 1;
+ }
+ } else {
+ if(r) {
+ back = -1;
+ }
+ }
+
+ /* Invert.
+ */
+ switch(back) {
+ case 1: {
+ back = -1;
+ } break;
+ case -1: {
+ back = 1;
+ } break;
+ }
+ return back;
+}
+
+
+#endif
+/* DK3_ON_WINDOWS */
+
+
+
+
+/** Delete the current users jobs from the printer.
+ @param job Job structure.
+ @param pr Printer.
+*/
+static
+void
+wprclean_windows_printer(WPC_JOB *job, dk3_printer_t *pr)
+{
+#if DK3_ON_WINDOWS
+ dkChar cn[DK3_MAX_PATH]; /* Current computer name. */
+ dkChar nb1[64]; /* Job ID as text. */
+ dkChar nb2[64]; /* Last error as text. */
+ char peb[WPRCLEAN_QUEUE_JOB_LIST_SIZE];
+ /* Buffer for enumeration. */
+#if DK3_CHAR_SIZE > 1
+ JOB_INFO_1W *jobptr; /* Current print job. */
+#else
+ JOB_INFO_1A *jobptr; /* Current print job. */
+#endif
+ wprclean_printjob_t *pj; /* Current job to mark for deletion. */
+ dk3_sto_t *sJobs; /* Storage for jobs to delete. */
+ dk3_sto_it_t *iJobs; /* Iterator through storage. */
+ wprclean_printjob_t *jptr; /* Current job to delete. */
+ dkChar const *logname; /* Current users login name. */
+ HANDLE hPr; /* Handle for printer. */
+ DWORD szpeb; /* Size of peb buffer. */
+ DWORD cbNeeded; /* Number of bytes needed. */
+ DWORD cbReturned; /* Number of print jobs returned. */
+ DWORD startindex; /* Start index for enumeration. */
+ DWORD i; /* Index of current job. */
+ DWORD le; /* Last error code. */
+ BOOL bres; /* Operation result. */
+ BOOL cc; /* Flag: Can continue. */
+ BOOL mustsave; /* Flag: Must mark job for deletion. */
+ $? "+ wprclean_windows_printer"
+ logname = dk3app_get_logname(job->app);
+ if(logname) { $? ". logname"
+ if(dk3sf_get_hostname_app(cn,DK3_MAX_PATH,job->app)) { $? ". hostname \"%ls\"", cn
+ sJobs = dk3sto_open_app(job->app);
+ if(sJobs) { $? ". sJobs"
+ dk3sto_set_comp(sJobs, wprclean_compare_printjobs, 0);
+ iJobs = dk3sto_it_open(sJobs);
+ if(iJobs) { $? ". iJobs"
+ hPr = INVALID_HANDLE_VALUE;
+#if DK3_CHAR_SIZE > 1
+ bres = OpenPrinterW((dkChar *)(pr->name), &hPr, NULL);
+#else
+ bres = OpenPrinterA((dkChar *)(pr->name), &hPr, NULL);
+#endif
+ if(bres) { $? ". OpenPrinter"
+ dk3sf_initialize_stdout();
+ dk3sf_fputs(pr->name, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ fflush(stdout);
+ /* Enumerate print jobs.
+ */
+ cc = TRUE;
+ startindex = 0;
+ while(cc) {
+ cbNeeded = 0; cbReturned = 0; szpeb = sizeof(peb);
+#if DK3_CHAR_SIZE > 1
+ bres = EnumJobsW(
+ hPr, startindex, (DWORD)WPRCLEAN_NUM_JOBS, 1,
+ (LPBYTE)peb, szpeb, &cbNeeded, &cbReturned
+ );
+#else
+ bres = EnumJobsA(
+ hPr, startindex, (DWORD)WPRCLEAN_NUM_JOBS, 1,
+ (LPBYTE)peb, szpeb, &cbNeeded, &cbReturned
+ );
+#endif
+ if(bres) { $? ". EnumJobs"
+ if(cbReturned > 0) { $? ". cbReturned %lu", (unsigned long)cbReturned
+#if DK3_CHAR_SIZE > 1
+ jobptr = (JOB_INFO_1W *)peb;
+#else
+ jobptr = (JOB_INFO_1A *)peb;
+#endif
+ for(i = 0; i < cbReturned; i++) {
+ mustsave = FALSE;
+ if(jobptr->pUserName) { $? ". job username"
+ if(dk3str_casecmp(logname, jobptr->pUserName) == 0) {
+ $? ". names match"
+ if(job->comp) {
+ if(jobptr->pMachineName) {
+ $? ". job machinename \"%ls\"", jobptr->pMachineName
+ if(dk3str_casecmp(cn, jobptr->pMachineName) == 0) {
+ $? ". names match"
+ mustsave = TRUE;
+ } else {
+ if(dkT('\\') == (jobptr->pMachineName)[0]) {
+ if(dkT('\\') == (jobptr->pMachineName)[1]) {
+ if(dk3str_casecmp(cn, &((jobptr->pMachineName)[2])) == 0) {
+ mustsave = TRUE;
+ }
+ }
+ }
+ }
+ } else { $? ". no job machinename"
+ mustsave = TRUE;
+ }
+ } else {
+ mustsave = TRUE;
+ }
+ }
+ }
+ if(mustsave) { $? ". must save"
+ pj = wprclean_printjob_new(
+ jobptr->Position, jobptr->JobId, job->app
+ );
+ if(pj) { $? ". pj"
+ if(!dk3sto_add(sJobs, (void *)pj)) {
+ wprclean_printjob_delete(pj); $? "! add"
+ job->exval = 1;
+ }
+ } else { $? "! pj"
+ job->exval = 1;
+ }
+ }
+ jobptr++;
+ }
+ startindex += cbReturned;
+ } else { $? "! cbReturned"
+ cc = FALSE;
+ }
+ } else { $? "! EnumJobs"
+ cc = FALSE;
+ }
+ }
+
+ /* Remove saved print jobs from queue.
+ */
+ dk3sto_it_reset(iJobs);
+ while(NULL != (jptr = (wprclean_printjob_t *)dk3sto_it_next(iJobs))) {
+ $? ". job to delete"
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(nb1,dkT("%lu"),(unsigned long)(jptr->jobid));
+#else
+ if (!(dk3ma_um_to_string(nb1,DK3_SIZEOF(nb1,dkChar),(dk3_um_t)(jptr->jobid)))) {
+ nb1[0] = dkT('\0');
+ }
+#endif
+#if DK3_CHAR_SIZE > 1
+ bres = SetJobW(hPr, jptr->jobid, 0, NULL, JOB_CONTROL_DELETE);
+#else
+ bres = SetJobA(hPr, jptr->jobid, 0, NULL, JOB_CONTROL_DELETE);
+#endif
+ if(bres) {
+ /* DELETED */
+ dk3sf_fputc(dkT('\t'), stdout);
+ dk3sf_fputs((job->msg)[0], stdout);
+ dk3sf_fputs(nb1, stdout);
+ dk3sf_fputs((job->msg)[1], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ fflush(stdout);
+ } else {
+ /* FAILED */
+ le = GetLastError();
+ dk3sf_fputc(dkT('\t'), stdout);
+#if VERSION_BEFORE_20140716
+ dk3sf_sprintf3(nb2,dkT("%lu"),(unsigned long)le);
+#else
+ if(!(dk3ma_um_to_string(nb2,DK3_SIZEOF(nb2,dkChar),(dk3_um_t)le)))
+ {
+ nb2[0] = dkT('\0');
+ }
+#endif
+ dk3sf_fputs((job->msg)[2], stdout);
+ dk3sf_fputs(nb1, stdout);
+ dk3sf_fputs((job->msg)[3], stdout);
+ dk3sf_fputs(nb2, stdout);
+ dk3sf_fputs((job->msg)[4], stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ fflush(stdout);
+ job->exval = 1;
+ }
+ }
+
+ ClosePrinter(hPr);
+ } else { $? "! OpenPrinter"
+ /* ERROR: Failed to open printer! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 5, 6, pr->name);
+ job->exval = 1;
+ }
+
+ /* Release saved jobs.
+ */
+ dk3sto_it_reset(iJobs);
+ while(NULL != (jptr = (wprclean_printjob_t *)dk3sto_it_next(iJobs))) {
+ wprclean_printjob_delete(jptr);
+ }
+ dk3sto_it_close(iJobs);
+ } else {
+ job->exval = 1;
+ }
+ dk3sto_close(sJobs);
+ } else {
+ job->exval = 1;
+ }
+ } else {
+ /* ERROR: Failed to find host name */
+ job->exval = 1;
+ }
+ } else {
+ /* ERROR: Failed to find log name */
+ job->exval = 1;
+ } $? "- wprclean_windows_printer"
+#endif
+}
+
+
+
+/** Clean up all printers on the system.
+ @param job Job structure.
+*/
+static
+void
+wprclean_cleanup_all_printers(WPC_JOB *job)
+{
+ void *vptr; /* Current printer as returned from iterator. */
+ dk3_printer_t *pr; /* Current printer. */
+
+ dk3sto_it_reset((job->pc)->iPrinters);
+ while(NULL != (vptr = dk3sto_it_next((job->pc)->iPrinters))) {
+ pr = (dk3_printer_t *)vptr;
+ if(DK3_PRINTER_TYPE_WINDOWS == pr->t_p) {
+ wprclean_windows_printer(job, pr);
+ }
+ }
+}
+
+
+
+/** Clean up the named printers.
+ @param job Job structure.
+ @param numargs Number of command line arguments.
+*/
+static
+void
+wprclean_cleanup_named_printers(WPC_JOB *job, int numargs)
+{
+ dkChar const *pn; /* Printer name. */
+ dk3_printer_t *pr; /* Printer. */
+ int i; /* Index of current printer. */
+
+ /* Pass 1: Local Windows printers.
+ */
+ for(i = 0; i < numargs; i++) {
+ pn = dk3opt_get_arg(job->opt, i);
+ if(pn) {
+ pr = dk3print_get_printer(job->pc, pn);
+ if(pr) {
+ if(DK3_PRINTER_TYPE_WINDOWS == pr->t_p) {
+ wprclean_windows_printer(job, pr);
+ }
+ } else {
+ job->exval = 1;
+ /* ERROR: Printer not found! */
+ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 7, 8, pn);
+ }
+ }
+ }
+}
+
+
+
+/** Do cleanup.
+ @param job Job structure.
+*/
+static
+void
+wprclean_do_cleanup(WPC_JOB *job)
+{
+ int numargs; /* Number of command line arguments. */
+
+ job->pc = dk3print_conf_open(job->app, 1);
+ if(job->pc) {
+ numargs = dk3opt_get_num_args(job->opt);
+ job->exval = 0;
+ if(0 == numargs) {
+ wprclean_cleanup_all_printers(job);
+ } else {
+ wprclean_cleanup_named_printers(job, numargs);
+ }
+ dk3print_conf_close(job->pc); job->pc = NULL;
+ }
+}
+
+
+
+/** Run with a configured job structure.
+ @param job Job structure.
+*/
+static
+void
+wprclean_run(WPC_JOB *job)
+{
+ job->opt = dk3opt_open_from_app(
+ wprclean_options, wprclean_sz_options,
+ dkT('\0'), NULL,
+ job->app
+ );
+ if(job->opt) {
+ if(0 == dk3opt_get_error_code(job->opt)) {
+ if(dk3opt_is_set(job->opt, dkT('h'))) {
+ job->cmd |= DK3_APP_CMD_HELP;
+ }
+ if(dk3opt_is_set(job->opt, dkT('v'))) {
+ job->cmd |= DK3_APP_CMD_VERSION;
+ }
+ if(dk3opt_is_set(job->opt, dkT('L'))) {
+ job->cmd |= DK3_APP_CMD_LICENSE;
+ }
+ if(dk3opt_is_set(job->opt, dkT('c'))) {
+ job->comp = 1;
+ }
+ if(0 == job->cmd) {
+ wprclean_do_cleanup(job);
+ } else {
+ job->exval = 0;
+ dk3sf_initialize_stdout();
+ if((job->cmd) & DK3_APP_CMD_VERSION) {
+ dk3sf_fputs(wprclean_version, stdout);
+ dk3sf_fputc(dkT('\n'), stdout);
+ }
+ if((job->cmd) & DK3_APP_CMD_LICENSE) {
+ dk3sf_fputt(wprclean_text_license, stdout);
+ }
+ if((job->cmd) & DK3_APP_CMD_HELP) {
+ dk3app_help(job->app, wprclean_nlmsg[2], wprclean_text_help);
+ }
+ }
+ }
+ dk3opt_close(job->opt); job->opt = NULL;
+ }
+}
+
+
+
+/** Program entry point.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, any other value indicates an error.
+*/
+DK3_MAIN
+{
+ WPC_JOB job; /* wprclean job. */
+ int exval = 1; /* Exit status code. */
+ $!trace-init wprclean.deb
+ $? "+ main"
+ job.app = dk3app_open_command(
+ argc, (dkChar const * const *)argv, wprclean_nlmsg[0]
+ );
+ if(job.app) {
+ job.msg = dk3app_messages(
+ job.app, wprclean_nlmsg[1], (dkChar const **)wprclean_msg
+ );
+ job.nlmsg = wprclean_nlmsg;
+ job.cmd = 0;
+ job.comp = 0;
+ job.exval = 1;
+ job.pc = NULL;
+ wprclean_run(&job);
+ exval = job.exval;
+ dk3app_close(job.app);
+ } else {
+ fputs("wprclean: ERROR: Not enough memory!\n", stderr);
+ fflush(stderr);
+ }
+ $? "- main %d", exval
+ $!trace-end
+ fflush(stdout);
+ exit(exval); return exval;
+}
+
+
diff --git a/support/dktools/wprclean.h b/support/dktools/wprclean.h
new file mode 100644
index 0000000000..cac78a770c
--- /dev/null
+++ b/support/dktools/wprclean.h
@@ -0,0 +1,68 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: wprclean.ctr
+*/
+
+/*
+Copyright (C) 2013, Dirk Krause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above opyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+* Neither the name of the author nor the names of contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/** @file wprclean.h Header file for the wprclean module.
+*/
+
+#ifndef WPRCLEAN_H_INCLUDED
+/** Avoid multiple inclusions. */
+#define WPRCLEAN_H_INCLUDED 1
+
+
+#line 8 "wprclean.ctr"
+
+#include "dk3all.h"
+#include "dk3print.h"
+#include "dk3prcfg.h"
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4verswx.h"
+
+
+/** Job structure.
+*/
+typedef struct {
+ dk3_app_t *app; /**< Application structure. */
+ dkChar const * const *msg; /**< Localized texts. */
+ dkChar const * const *nlmsg; /**< Not localized texts. */
+ dk3_option_set_t *opt; /**< Options. */
+ dk3_print_conf_t *pc; /**< Print configuration. */
+ int cmd; /**< Command to execute. */
+ int exval; /**< Exit status code. */
+} WPC_JOB;
+
+
+#endif
diff --git a/support/dktools/wprclean.rc b/support/dktools/wprclean.rc
new file mode 100644
index 0000000000..9353944cd8
--- /dev/null
+++ b/support/dktools/wprclean.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Clean Windows print queue\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "Clean Windows print queue\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "wprclean\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/wprclean2.c b/support/dktools/wprclean2.c
new file mode 100644
index 0000000000..477d24bff0
--- /dev/null
+++ b/support/dktools/wprclean2.c
@@ -0,0 +1,1178 @@
+/*
+ WARNING: This file was generated by dkct.
+ Changes you make here will be lost if dkct is run again!
+ You should modify the original source and run dkct on it.
+ Original source: wprclean2.ctr
+*/
+
+
+#line 5 "wprclean2.ctr"
+
+/** @file wprclean.c Cleanup Windows print queues.
+*/
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED
+#endif
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4error.h"
+#include "dk4mem.h"
+#include "dk4mema.h"
+#include "dk4strd.h"
+#include "dk4app.h"
+#include "dk4aopt.h"
+#include "dk4vers.h"
+#include "dk4hnamed.h"
+#include "dk4user.h"
+
+
+
+
+
+#line 84 "wprclean2.ctr"
+
+
+
+/** Information required to delete a print job.
+*/
+typedef struct {
+ DWORD position; /**< Position in queue. */
+ DWORD jobid; /**< Job ID. */
+} wprclean_printjob_t;
+
+
+
+/** Constant text strings used by program, not localized.
+*/
+static const dkChar * const wprclean_kwnl[] = {
+/* 0 */
+dkT("dktools"),
+
+/* 1 */
+dkT("wprclean.txt"),
+
+/* 2 */
+dkT("wprclean.str"),
+
+NULL
+
+
+#line 113 "wprclean2.ctr"
+};
+
+
+
+/** Constant texts used by the program, replaced by localized versions.
+*/
+static const dkChar * const wprclean_kw_def[] = {
+/* 0 */
+dkT("This program is only available for the Windows platform!"),
+
+/* 1 */
+dkT("Unnamed printer found in enumeration!"),
+
+/* 2 */
+dkT("Failed to enumerate print queues!"),
+
+/* 3 */
+dkT("Failed to open print queue \""),
+
+/* 4 */
+dkT("\"!"),
+
+/* 5 */
+dkT("Failed to obtain size for print queue information \""),
+
+/* 6 */
+dkT("\"!"),
+
+/* 7 */
+dkT("Failed to enumerate jobs for print queue \""),
+
+/* 8 */
+dkT("\"!"),
+
+/* 9 */
+dkT("Failed to obtain number of jobs for queue \""),
+
+/* 10 */
+dkT("\"!"),
+
+/* 11 */
+dkT("Failed to remove job from queue \""),
+
+/* 12 */
+dkT("\"!"),
+
+NULL
+
+
+#line 159 "wprclean2.ctr"
+};
+
+
+
+static const dkChar * const wprclean_help_text[] = {
+/* 0 */
+dkT(""),
+
+/* 1 */
+dkT("Windows print queue cleanup"),
+
+/* 2 */
+dkT(""),
+
+/* 3 */
+dkT("wprclean [-c]"),
+
+/* 4 */
+dkT(""),
+
+/* 5 */
+dkT("Options:"),
+
+/* 6 */
+dkT("-c\t--computer\tDelete print jobs submitted from this computer only."),
+
+/* 7 */
+dkT(""),
+
+/* 8 */
+dkT("\t--help\t\tShow this short help text."),
+
+/* 9 */
+dkT("\t--manual\t*** SHOW FULL MANUAL ***"),
+
+/* 10 */
+dkT("\t--version\tShow version information."),
+
+/* 11 */
+dkT("\t--license\tShow license information."),
+
+NULL
+
+
+#line 178 "wprclean2.ctr"
+};
+
+
+
+
+/** License conditions.
+*/
+static const dkChar * const wprclean_license_text[] = {
+dkT(""),
+dkT("This software uses code from the following projects, either directly or as"),
+dkT("a library:"),
+dkT(""),
+dkT("dktools\t\tDirk Krause's tools and libraries."),
+dkT("\t\tSee http://dktools.sourceforge.net/ for more information."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT("zlib\t\tData compression library."),
+dkT("\t\tSee http://www.zlib.net/ for more information."),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT("bzip2\t\tData compression program and library."),
+dkT("\t\tSee http://www.bzip.org/ for more information."),
+#endif
+dkT(""),
+dkT("All the licenses below apply to the program."),
+dkT("Licenses for used libraries are shown as found on my Scientific Linux 6.x"),
+dkT("computer in the /usr/share/doc directory on 2015-04-01. Check the project"),
+dkT("homepages of the used libraries for additional information and/or updated"),
+dkT("license terms."),
+dkT(""),
+dkT(""),
+dkT("DK tools and libraries license"),
+dkT("=============================="),
+dkT("Copyright (c) 2015-2016, Dirk Krause"),
+dkT("All rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions are met:"),
+dkT(""),
+dkT("* Redistributions of source code must retain the above copyright notice,"),
+dkT(" this list of conditions and the following disclaimer."),
+dkT("* Redistributions in binary form must reproduce the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer in the"),
+dkT(" documentation and/or other materials provided with the distribution."),
+dkT("* Neither the name of the Dirk Krause nor the names of contributors may be"),
+dkT(" used to endorse or promote products derived from this software without"),
+dkT(" specific prior written permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\""),
+dkT("AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE"),
+dkT("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED."),
+dkT(""),
+dkT("IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,"),
+dkT("INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,"),
+dkT("BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,"),
+dkT("DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY"),
+dkT("OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,"),
+dkT("EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+#if DK4_HAVE_ZLIB_H
+dkT(""),
+dkT(""),
+dkT("Zlib license"),
+dkT("============"),
+dkT("(C) 1995-2004 Jean-loup Gailly and Mark Adler"),
+dkT(""),
+dkT("This software is provided 'as-is', without any express or implied"),
+dkT("warranty. In no event will the authors be held liable for any damages"),
+dkT("arising from the use of this software."),
+dkT(""),
+dkT("Permission is granted to anyone to use this software for any purpose,"),
+dkT("including commercial applications, and to alter it and redistribute it"),
+dkT("freely, subject to the following restrictions:"),
+dkT(""),
+dkT("1. The origin of this software must not be misrepresented; you must not"),
+dkT(" claim that you wrote the original software. If you use this software"),
+dkT(" in a product, an acknowledgment in the product documentation would be"),
+dkT(" appreciated but is not required."),
+dkT("2. Altered source versions must be plainly marked as such, and must not be"),
+dkT(" misrepresented as being the original software."),
+dkT("3. This notice may not be removed or altered from any source distribution."),
+dkT(""),
+dkT("Jean-loup Gailly Mark Adler"),
+dkT("jloup@gzip.org madler@alumni.caltech.edu"),
+#endif
+#if DK4_HAVE_BZLIB_H
+dkT(""),
+dkT(""),
+dkT("Bzip2 and libbzip2 library license"),
+dkT("=================================="),
+dkT("This program, \"bzip2\", the associated library \"libbzip2\", and all"),
+dkT("documentation, are copyright (C) 1996-2007 Julian R Seward. All"),
+dkT("rights reserved."),
+dkT(""),
+dkT("Redistribution and use in source and binary forms, with or without"),
+dkT("modification, are permitted provided that the following conditions"),
+dkT("are met:"),
+dkT(""),
+dkT("1. Redistributions of source code must retain the above copyright"),
+dkT(" notice, this list of conditions and the following disclaimer."),
+dkT(""),
+dkT("2. The origin of this software must not be misrepresented; you must "),
+dkT(" not claim that you wrote the original software. If you use this "),
+dkT(" software in a product, an acknowledgment in the product "),
+dkT(" documentation would be appreciated but is not required."),
+dkT(""),
+dkT("3. Altered source versions must be plainly marked as such, and must"),
+dkT(" not be misrepresented as being the original software."),
+dkT(""),
+dkT("4. The name of the author may not be used to endorse or promote "),
+dkT(" products derived from this software without specific prior written "),
+dkT(" permission."),
+dkT(""),
+dkT("THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS"),
+dkT("OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED"),
+dkT("WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE"),
+dkT("ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY"),
+dkT("DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL"),
+dkT("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE"),
+dkT("GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS"),
+dkT("INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,"),
+dkT("WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING"),
+dkT("NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS"),
+dkT("SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."),
+dkT(""),
+dkT("Julian Seward, jseward@bzip.org"),
+dkT("bzip2/libbzip2 version 1.0.5 of 10 December 2007"),
+#endif
+dkT(""),
+NULL
+
+
+#line 311 "wprclean2.ctr"
+};
+
+
+
+/** Full computer name (including domain).
+*/
+static dkChar host_long[256];
+
+
+
+/** Short computer name (just host name).
+*/
+static dkChar host_short[256];
+
+
+
+/** User name.
+*/
+static dkChar user_name[256];
+
+
+
+/** Options used by the program.
+*/
+static const dk4_option_specification_t wprclean_options[] = {
+
+ /* Delete jobs submitted from local computer only.
+ */
+ { dkT('c'), dkT("computer"), DK4_OPT_ARG_NONE },
+
+ /* Produce verbose output.
+ */
+ { dkT('v'), dkT("verbose"), DK4_OPT_ARG_NONE }
+};
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Queue storage.
+*/
+static dk4_sto_t *s_q = NULL;
+
+
+
+/** Iterator for queue storage.
+*/
+static dk4_sto_it_t *i_q = NULL;
+
+
+
+/** Message texts, replaced by localized version if available.
+*/
+static const dkChar * const *msg = wprclean_kw_def;
+
+
+/** Number of elements in the wprclean_options array.
+*/
+static const size_t wprclean_sz_options =
+sizeof(wprclean_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Size of user_name buffer.
+*/
+static const size_t sz_user_name = DK4_SIZEOF(user_name,dkChar);
+
+
+
+/** Number of elements in the wprclean_kw_def array.
+*/
+static size_t sz_msg =
+(sizeof(wprclean_kw_def)/sizeof(DK4_PDKCHAR) - 1);
+
+
+
+/** Size of short host name buffer.
+*/
+static const size_t sz_host_short = DK4_SIZEOF(host_short,dkChar);
+
+
+
+/** Flag: Use separated short host name.
+*/
+static int have_short_host = 0;
+
+
+
+/** Flag: Delete jobs submitted from current host only.
+*/
+static int only_this_host = 0;
+
+
+
+/** Exit status code returned by the program.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+/** Flag: Verbose output.
+*/
+static int verbose = 0;
+
+
+
+/* This program is only available for the Windows platform!
+*/
+#if DK4_ON_WINDOWS
+
+
+
+/** Check presence of -c option, retrieve host name and short
+ host name if necessary.
+*/
+static
+void
+check_options(void)
+{
+ dkChar *ptr;
+
+
+#line 436 "wprclean2.ctr"
+ host_long[0] = dkT('\0');
+ host_short[0] = dkT('\0');
+ user_name[0] = dkT('\0');
+ if (0 != dk4app_opt_is_set_short(app, dkT('v'), NULL)) {
+ verbose = 1;
+
+#line 441 "wprclean2.ctr"
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('c'), NULL)) {
+
+#line 443 "wprclean2.ctr"
+ if (0 != dk4hostname(host_long, DK4_SIZEOF(host_long,dkChar), NULL)) {
+ only_this_host = 1;
+
+#line 445 "wprclean2.ctr"
+ if (0 != dk4str_cpy_s(host_short, sz_host_short, host_long, NULL)) {
+ ptr = dk4str_chr(host_short, dkT('.'));
+
+#line 447 "wprclean2.ctr"
+ if (NULL != ptr) {
+
+#line 448 "wprclean2.ctr"
+ *ptr = dkT('\0');
+ have_short_host = 1;
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 453 "wprclean2.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 458 "wprclean2.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 463 "wprclean2.ctr"
+ }
+#endif
+ }
+
+
+#line 467 "wprclean2.ctr"
+}
+
+
+
+/** Compare two queue names.
+ @param l Left queue name.
+ @param r Right queue name.
+ @param cr Comparison criteria, unused.
+ @return Comparison result.
+*/
+static
+int
+compare_queues(const void *l, const void *r, int cr)
+{
+ int back = 0;
+ if (NULL != l) {
+ if (NULL != r) {
+ back = dk4str_cmp((const dkChar *)l, (const dkChar *)r);
+ if (-1 > back) back = -1;
+ if ( 1 < back) back = 1;
+ } else back = 1;
+ } else {
+ if (NULL != r) back = -1;
+ }
+ return back;
+}
+
+
+
+/** Compare two print jobs within the same queue.
+ @param l Left job.
+ @param r Right job.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result (inverted sort order).
+*/
+static
+int
+compare_print_jobs(const void *l, const void *r, int cr)
+{
+ const wprclean_printjob_t *jl = NULL;
+ const wprclean_printjob_t *jr = NULL;
+ int back = 0;
+ if (NULL != l) {
+ if (NULL != r) {
+ jl = (const wprclean_printjob_t *)l;
+ jr = (const wprclean_printjob_t *)r;
+ if (jl->position > jr->position) {
+ back = -1;
+ } else {
+ if (jr->position > jl->position) {
+ back = 1;
+ } else {
+ if (jl->jobid > jr->jobid) {
+ back = -1;
+ } else {
+ if (jr->jobid > jl->jobid) {
+ back = 1;
+ }
+ }
+ }
+ }
+ } else back = 1;
+ } else {
+ if (NULL != r) back = -1;
+ }
+ return back;
+}
+
+
+/** Allocate resources for list of print queues and iterator.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+setup_for_queue_list(void)
+{
+ int back = 0;
+
+
+#line 545 "wprclean2.ctr"
+ s_q = dk4sto_open(NULL);
+ if (NULL != s_q) {
+
+#line 547 "wprclean2.ctr"
+ dk4sto_set_comp(s_q, compare_queues, 0);
+ i_q = dk4sto_it_open(s_q, NULL);
+ if (NULL != i_q) {
+
+#line 550 "wprclean2.ctr"
+ back = 1;
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 554 "wprclean2.ctr"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else {
+
+#line 559 "wprclean2.ctr"
+ }
+#endif
+
+
+#line 562 "wprclean2.ctr"
+ return back;
+}
+
+
+
+/** Clean up print queues storage and iterator.
+*/
+static
+void
+cleanup_for_queue_list(void)
+{
+ dkChar *p;
+
+
+#line 575 "wprclean2.ctr"
+ /* Release all queue names saved, close iterator.
+ */
+ if (NULL != i_q) {
+
+#line 578 "wprclean2.ctr"
+ dk4sto_it_reset(i_q);
+ do {
+ p = (dkChar *)dk4sto_it_next(i_q);
+ if (NULL != p) {
+ dk4mem_free(p);
+ }
+ } while (NULL != p);
+
+#line 585 "wprclean2.ctr"
+ dk4sto_it_close(i_q); i_q = NULL;
+ }
+ /* Close storage.
+ */
+ if (NULL != s_q) {
+
+#line 590 "wprclean2.ctr"
+ dk4sto_close(s_q); s_q = NULL;
+ }
+
+
+#line 593 "wprclean2.ctr"
+}
+
+
+
+/** Retrieve list of print queue names.
+ @return 1 on success, 0 on error
+*/
+static
+int
+retrieve_queue_list(void)
+{
+#if DK4_ON_WINDOWS
+ char *peb; /* Result buffer */
+ dkChar *pn; /* Printer name */
+#if DK4_CHAR_SIZE > 1
+ PRINTER_INFO_2W *pi2; /* Printer information array */
+#else
+ PRINTER_INFO_2A *pi2; /* Printer information array */
+#endif
+ DWORD cbNeeded; /* Bytes needed */
+ DWORD cbReturned; /* Bytes returned */
+ DWORD szPeb; /* Size of peb */
+ DWORD i; /* Index current print queue */
+ BOOL res; /* Operation result */
+ int back = 0;
+
+
+#line 619 "wprclean2.ctr"
+ cbNeeded = cbReturned = szPeb = (DWORD)0UL;
+#if DK4_CHAR_SIZE > 1
+ EnumPrintersW(PRINTER_ENUM_LOCAL,NULL,2,NULL,szPeb,&cbNeeded,&cbReturned);
+#else
+ EnumPrintersA(PRINTER_ENUM_LOCAL,NULL,2,NULL,szPeb,&cbNeeded,&cbReturned);
+#endif
+ if ((DWORD)0UL < cbNeeded) {
+ szPeb = cbNeeded;
+ peb = dk4mem_new_app(char, (size_t)cbNeeded, app);
+ if (NULL != peb) {
+ cbNeeded = cbReturned = (DWORD)0UL;
+#if DK4_CHAR_SIZE > 1
+ res = EnumPrintersW(
+ PRINTER_ENUM_LOCAL,NULL,2,(LPBYTE)peb,szPeb,&cbNeeded,&cbReturned
+ );
+#else
+ res = EnumPrintersA(
+ PRINTER_ENUM_LOCAL,NULL,2,(LPBYTE)peb,szPeb,&cbNeeded,&cbReturned
+ );
+#endif
+ if (res) {
+ if ((DWORD)0UL < cbReturned) {
+ pi2 = (PRINTER_INFO_2 *)peb;
+ back = 1;
+ for (i = (DWORD)0UL; i < cbReturned; i++) {
+ if (NULL != pi2->pPrinterName) {
+ pn = dk4str_dup(pi2->pPrinterName, NULL);
+ if (NULL != pn) {
+ if (0 == dk4sto_add(s_q, pn, NULL)) {
+ dk4mem_free(pn);
+
+#line 649 "wprclean2.ctr"
+ back = 0;
+ exval = EXIT_FAILURE;
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ }
+ } else {
+
+#line 655 "wprclean2.ctr"
+ back = 0;
+ exval = EXIT_FAILURE;
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ }
+ } else {
+
+#line 661 "wprclean2.ctr"
+ back = 0;
+ exval = EXIT_FAILURE;
+ /* ERROR: Invalid printer configuration */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 1);
+ }
+ pi2++;
+ }
+ } else {
+
+#line 669 "wprclean2.ctr"
+ }
+ } else {
+
+#line 671 "wprclean2.ctr"
+ exval = EXIT_FAILURE;
+ /* ERROR: Printer enumeration failed */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 2);
+ }
+ dk4mem_release(peb);
+ } else {
+
+#line 677 "wprclean2.ctr"
+ exval = EXIT_FAILURE;
+ }
+ } else {
+
+#line 680 "wprclean2.ctr"
+ }
+
+
+#line 682 "wprclean2.ctr"
+ return back;
+#else
+ return 1;
+#endif
+}
+
+
+
+/** Remove jobs from one print queue.
+*/
+static
+void
+handle_one_queue(const dkChar *pn)
+{
+ char *pc1 = NULL; /* First buffer */
+ char *pc2 = NULL; /* Second buffer */
+ dk4_sto_t *s_j = NULL; /* Jobs container */
+ dk4_sto_it_t *i_j = NULL; /* Jobs iterator */
+#if DK4_CHAR_SIZE > 1
+ PRINTER_INFO_2W *pi2 = NULL; /* Printer info */
+ JOB_INFO_1W *ji1 = NULL; /* Print job info */
+#else
+ PRINTER_INFO_2A *pi2 = NULL; /* Printer info */
+ JOB_INFO_1A *ji1 = NULL; /* Print job info */
+#endif
+ wprclean_printjob_t *pj = NULL; /* New print job */
+ HANDLE h_pr = INVALID_HANDLE_VALUE; /* Printer handle */
+ DWORD sz1 = (DWORD)0UL; /* Size provided */
+ DWORD sz2 = (DWORD)0UL; /* Size needed */
+ DWORD sz3 = (DWORD)0UL; /* Size provided */
+ DWORD sz4 = (DWORD)0UL; /* Size needed */
+ DWORD sz5 = (DWORD)0UL; /* No print jobs */
+ DWORD nJobs = (DWORD)0UL; /* Number of jobs */
+ DWORD i = (DWORD)0UL; /* Current job index */
+ int mm = 0; /* Machine matches */
+ int um = 0; /* User matches */
+ BOOL bres = FALSE; /* Printer open res */
+ BOOL br1 = FALSE; /* GetPrinter res */
+ BOOL br2 = FALSE; /* GetPrinter res */
+ BOOL br3 = FALSE; /* EnumJobs res */
+ BOOL br4 = FALSE; /* EnumJobs res */
+ BOOL br5 = FALSE; /* SetJob res */
+
+
+#line 725 "wprclean2.ctr"
+ /* Prepare data structures.
+ */
+ s_j = dk4sto_open(NULL);
+ if (NULL == s_j) {
+
+#line 729 "wprclean2.ctr"
+ exval = EXIT_FAILURE;
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ goto finished;
+ }
+ dk4sto_set_comp(s_j, compare_print_jobs, 0);
+ i_j = dk4sto_it_open(s_j, NULL);
+ if (NULL == i_j) {
+
+#line 737 "wprclean2.ctr"
+ exval = EXIT_FAILURE;
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ goto finished;
+ }
+ /* Open printer
+ */
+#if DK4_CHAR_SIZE > 1
+ bres = OpenPrinterW(pn, &h_pr, NULL);
+#else
+ bres = OpenPrinterA(pn, &h_pr, NULL);
+#endif
+ if (!(bres)) {
+
+#line 750 "wprclean2.ctr"
+ h_pr = INVALID_HANDLE_VALUE;
+ exval = EXIT_FAILURE;
+ /* ERROR: Failed to open printer */
+ dk4app_log_3(app, msg, sz_msg, DK4_LL_ERROR, 3, 4, pn);
+ goto finished;
+ }
+ /* Retrieve number of jobs
+ */
+#if DK4_CHAR_SIZE > 1
+ br1 = GetPrinterW(h_pr, 2, NULL, (DWORD)0UL, &sz1);
+#else
+ br1 = GetPrinterA(h_pr, 2, NULL, (DWORD)0UL, &sz1);
+#endif
+ if ((DWORD)0UL == sz1) {
+
+#line 764 "wprclean2.ctr"
+
+
+#line 765 "wprclean2.ctr"
+
+
+#line 766 "wprclean2.ctr"
+ exval = EXIT_FAILURE;
+ /* ERROR: Failed to request print queue */
+ dk4app_log_3(app, msg, sz_msg, DK4_LL_ERROR, 5, 6, pn);
+ goto finished;
+ }
+ if ((DWORD)0UL == sz1) {
+
+#line 772 "wprclean2.ctr"
+ exval = EXIT_FAILURE;
+ /* ERROR: Failed to request print queue */
+ dk4app_log_3(app, msg, sz_msg, DK4_LL_ERROR, 5, 6, pn);
+ goto finished;
+ }
+ pc1 = dk4mem_new_app(char,(size_t)sz1,app);
+ if (NULL == pc1) {
+
+#line 779 "wprclean2.ctr"
+ exval = EXIT_FAILURE;
+ goto finished;
+ }
+#if DK4_CHAR_SIZE > 1
+ br2 = GetPrinterW(h_pr, 2, pc1, sz1, &sz2);
+#else
+ br2 = GetPrinterA(h_pr, 2, pc1, sz1, &sz2);
+#endif
+ if (!(br2)) {
+
+#line 788 "wprclean2.ctr"
+ exval = EXIT_FAILURE;
+ /* ERROR: GetPrinter failed */
+ dk4app_log_3(app, msg, sz_msg, DK4_LL_ERROR, 9, 10, pn);
+ goto finished;
+ }
+ if (sz2 > sz1) {
+
+#line 794 "wprclean2.ctr"
+ exval = EXIT_FAILURE;
+ /* ERROR: Number of bytes increased. */
+ dk4app_log_3(app, msg, sz_msg, DK4_LL_ERROR, 9, 10, pn);
+ goto finished;
+ }
+ pi2 = (PRINTER_INFO_2 *)pc1;
+ nJobs = pi2->cJobs;
+ if ((DWORD)0UL == nJobs) {
+
+#line 802 "wprclean2.ctr"
+ goto finished;
+ }
+ /* Retrieve job data and build sorted storage
+ */
+#if DK4_CHAR_SIZE > 1
+ br3 = EnumJobsW(
+ h_pr, (DWORD)0UL, nJobs, 1, NULL, (DWORD)0UL, &sz3, &sz4
+ );
+#else
+ br3 = EnumJobsW(
+ h_pr, (DWORD)0UL, nJobs, 1, NULL, (DWORD)0UL, &sz3, &sz4
+ );
+#endif
+ if ((!(br3)) || ((DWORD)0UL == sz3)) {
+
+#line 816 "wprclean2.ctr"
+ exval = EXIT_FAILURE;
+ /* ERROR: Failed to find required byte number */
+ dk4app_log_3(app, msg, sz_msg, DK4_LL_ERROR, 7, 8, pn);
+ goto finished;
+ }
+ pc2 = dk4mem_new_app(char,(size_t)sz3,app);
+ if (NULL == pc2) {
+
+#line 823 "wprclean2.ctr"
+ exval = EXIT_FAILURE;
+ goto finished;
+ }
+ sz4 = (DWORD)0UL;
+#if DK4_CHAR_SIZE > 1
+ br4 = EnumJobsW(
+ h_pr, (DWORD)0UL, nJobs, 1, pc2, sz3, &sz4, &sz5
+ );
+#else
+ br4 = EnumJobsW(
+ h_pr, (DWORD)0UL, nJobs, 1, pc2, sz3, &sz4, &sz5
+ );
+#endif
+ if (!(br4)) {
+
+#line 837 "wprclean2.ctr"
+ exval = EXIT_FAILURE;
+ /* ERROR: EnumJobs */
+ dk4app_log_3(app, msg, sz_msg, DK4_LL_ERROR, 7, 8, pn);
+ goto finished;
+ }
+ if (sz4 > sz3) {
+
+#line 843 "wprclean2.ctr"
+ exval = EXIT_FAILURE;
+ /* ERROR: Number of bytes changed */
+ dk4app_log_3(app, msg, sz_msg, DK4_LL_ERROR, 7, 8, pn);
+ goto finished;
+ }
+#if DK4_CHAR_SIZE > 1
+ ji1 = (JOB_INFO_1W *)pc2;
+#else
+ ji1 = (JOB_INFO_1A *)pc2;
+#endif
+ for (i = (DWORD)0UL; i < sz5; i++) {
+ mm = 1;
+ um = 1;
+ if (0 != only_this_host) {
+
+#line 857 "wprclean2.ctr"
+ if (NULL != ji1->pMachineName) {
+
+#line 858 "wprclean2.ctr"
+ if (0 != dk4str_casecmp(host_long, ji1->pMachineName)) {
+ mm = 0;
+ if (0 != have_short_host) {
+
+#line 861 "wprclean2.ctr"
+ if (0 == dk4str_casecmp(host_short, ji1->pMachineName)) {
+ mm = 1;
+
+#line 863 "wprclean2.ctr"
+ }
+ }
+ }
+ }
+ }
+ if (NULL != ji1->pUserName) {
+ if (0 != dk4str_casecmp(user_name, ji1->pUserName)) {
+ um = 0;
+ }
+ }
+ else {
+
+#line 874 "wprclean2.ctr"
+ um = 0;
+ }
+ if ((0 != mm) && (0 != um)) {
+
+#line 877 "wprclean2.ctr"
+ pj = dk4mem_new_app(wprclean_printjob_t,1,app);
+ if (NULL != pj) {
+ pj->position = i;
+ pj->jobid = ji1->JobId;
+
+
+#line 882 "wprclean2.ctr"
+ if (0 == dk4sto_add(s_j, pj, NULL)) {
+
+#line 883 "wprclean2.ctr"
+ dk4mem_free(pj);
+ exval = EXIT_FAILURE;
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ }
+ } else {
+
+#line 889 "wprclean2.ctr"
+ exval = EXIT_FAILURE;
+ }
+ }
+ ji1++;
+ }
+ /* Remove print jobs from queue
+ */
+ dk4sto_it_reset(i_j);
+ do {
+ pj = (wprclean_printjob_t *)dk4sto_it_next(i_j);
+ if (NULL != pj) {
+
+#line 900 "wprclean2.ctr"
+#if DK4_CHAR_SIZE > 1
+ br5 = SetJobW(h_pr, pj->jobid, 0, NULL, JOB_CONTROL_DELETE);
+#else
+ br5 = SetJobA(h_pr, pj->jobid, 0, NULL, JOB_CONTROL_DELETE);
+#endif
+ if (!(br5)) {
+
+#line 906 "wprclean2.ctr"
+ exval = EXIT_FAILURE;
+ /* ERROR: Failed to remove job */
+ dk4app_log_3(app, msg, sz_msg, DK4_LL_ERROR, 11, 12, pn);
+ }
+ else {
+
+#line 911 "wprclean2.ctr"
+ }
+ }
+ } while(NULL != pj);
+
+ /* Final cleanup.
+ */
+ finished:
+ if (NULL != pc2) {
+ dk4mem_free(pc2);
+ }
+ if (NULL != pc1) {
+ dk4mem_free(pc1);
+ }
+ if (bres) {
+ ClosePrinter(h_pr);
+ }
+ if (NULL != i_j) {
+ dk4sto_it_reset(i_j);
+ do {
+ pj = (wprclean_printjob_t *)dk4sto_it_next(i_j);
+ if (NULL != pj) {
+ dk4mem_free(pj);
+ }
+ } while(NULL != pj);
+ dk4sto_it_close(i_j);
+ }
+ if (NULL != s_j) {
+ dk4sto_close(s_j);
+ }
+
+
+#line 941 "wprclean2.ctr"
+}
+
+
+
+/** Remove all print jobs from local queues.
+*/
+static
+void
+remove_all_print_jobs(void)
+{
+ dkChar *pn;
+
+ check_options();
+ if (0 != dk4user_get_logname(user_name, sz_user_name, 1, NULL)) {
+ if (setup_for_queue_list()) {
+ exval = EXIT_SUCCESS;
+ if (retrieve_queue_list()) {
+ dk4sto_it_reset(i_q);
+ do {
+ pn = (dkChar *)dk4sto_it_next(i_q);
+ if (NULL != pn) {
+ handle_one_queue(pn);
+ }
+ } while (NULL != pn);
+ }
+ }
+ cleanup_for_queue_list();
+ } else {
+ }
+}
+
+#endif
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+
+
+#line 988 "wprclean2.ctr"
+
+
+#line 989 "wprclean2.ctr"
+ app = dk4app_open_cmd(
+ argc, argv, wprclean_options, wprclean_sz_options,
+ wprclean_kwnl[0], DKT_VERSION_DK,
+ wprclean_kwnl[1], wprclean_help_text, wprclean_license_text
+ );
+ if (NULL != app) {
+ sz_msg = dk4app_string_table_size(wprclean_kw_def);
+ msg = dk4app_string_table(app, wprclean_kwnl[2], wprclean_kw_def);
+ if (0 != dk4app_can_run_normally(app)) {
+#if DK4_ON_WINDOWS
+ remove_all_print_jobs();
+#else
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+#endif
+ } else {
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ dk4app_close(app);
+ }
+
+
+#line 1011 "wprclean2.ctr"
+
+
+#line 1012 "wprclean2.ctr"
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/wprclean2.ctr b/support/dktools/wprclean2.ctr
new file mode 100644
index 0000000000..7783544e42
--- /dev/null
+++ b/support/dktools/wprclean2.ctr
@@ -0,0 +1,1014 @@
+%% options
+
+
+%% module
+
+/** @file wprclean.c Cleanup Windows print queues.
+*/
+
+#include "dk4conf.h"
+
+#include <stdio.h>
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED
+#endif
+#endif
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PROCESS_H
+#ifndef PROCESS_H_INCLUDED
+#include <process.h>
+#define PROCESS_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_IO_H
+#ifndef IO_H_INCLUDED
+#include <io.h>
+#define IO_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_FCNTL_H
+#ifndef FCNTL_H_INCLUDED
+#include <fcntl.h>
+#define FCNTL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SIGNAL_H
+#ifndef SIGNAL_H_INCLUDED
+#include <signal.h>
+#define SIGNAL_H_INCLUDED 1
+#endif
+#endif
+
+#include "dk4types.h"
+#include "dk4const.h"
+#include "dk4error.h"
+#include "dk4mem.h"
+#include "dk4mema.h"
+#include "dk4strd.h"
+#include "dk4app.h"
+#include "dk4aopt.h"
+#include "dk4vers.h"
+#include "dk4hnamed.h"
+#include "dk4user.h"
+
+
+
+$!trace-include
+
+
+
+/** Information required to delete a print job.
+*/
+typedef struct {
+ DWORD position; /**< Position in queue. */
+ DWORD jobid; /**< Job ID. */
+} wprclean_printjob_t;
+
+
+
+/** Constant text strings used by program, not localized.
+*/
+static const dkChar * const wprclean_kwnl[] = {
+$!string-table macro=dkT
+#
+# 0 Program group name
+#
+dktools
+#
+# 1 Help text file name
+#
+wprclean.txt
+#
+# 2 String table file name
+#
+wprclean.str
+$!end
+};
+
+
+
+/** Constant texts used by the program, replaced by localized versions.
+*/
+static const dkChar * const wprclean_kw_def[] = {
+$!string-table macro=dkT
+#
+# 0 ERROR: Only for Windows
+#
+This program is only available for the Windows platform!
+#
+# 1 ERROR: Unnamed printer found in enumeration!
+#
+Unnamed printer found in enumeration!
+#
+# 2 ERROR: Failed to enumerate print queues!
+#
+Failed to enumerate print queues!
+#
+# 3 4 ERROR: Failed to open print queue "..."!
+#
+Failed to open print queue "
+"!
+#
+# 5 6 ERROR: Failed to obtain size for print queue information!
+#
+Failed to obtain size for print queue information "
+"!
+#
+# 7 8 ERROR: Failed to enumerate jobs for print queue!
+#
+Failed to enumerate jobs for print queue "
+"!
+#
+# 9 10 ERROR: Failed to obtain number of jobs
+#
+Failed to obtain number of jobs for queue "
+"!
+#
+# 11 12 ERROR: Failed to remove job from queue
+#
+Failed to remove job from queue "
+"!
+$!end
+};
+
+
+
+static const dkChar * const wprclean_help_text[] = {
+$!string-table macro=dkT
+
+Windows print queue cleanup
+
+wprclean [-c]
+
+Options:
+-c --computer Delete print jobs submitted from this computer only.
+
+ --help Show this short help text.
+ --manual *** SHOW FULL MANUAL ***
+ --version Show version information.
+ --license Show license information.
+$!end
+};
+
+
+
+
+/** License conditions.
+*/
+static const dkChar * const wprclean_license_text[] = {
+$!text macro=dkT,preprocessor
+
+This software uses code from the following projects, either directly or as
+a library:
+
+dktools Dirk Krause's tools and libraries.
+ See http://dktools.sourceforge.net/ for more information.
+#if DK4_HAVE_ZLIB_H
+
+zlib Data compression library.
+ See http://www.zlib.net/ for more information.
+#endif
+#if DK4_HAVE_BZLIB_H
+
+bzip2 Data compression program and library.
+ See http://www.bzip.org/ for more information.
+#endif
+
+All the licenses below apply to the program.
+Licenses for used libraries are shown as found on my Scientific Linux 6.x
+computer in the /usr/share/doc directory on 2015-04-01. Check the project
+homepages of the used libraries for additional information and/or updated
+license terms.
+
+
+DK tools and libraries license
+==============================
+Copyright (c) 2015-2016, Dirk Krause
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the Dirk Krause nor the names of contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.
+
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#if DK4_HAVE_ZLIB_H
+
+
+Zlib license
+============
+(C) 1995-2004 Jean-loup Gailly and Mark Adler
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+
+Jean-loup Gailly Mark Adler
+jloup@gzip.org madler@alumni.caltech.edu
+#endif
+#if DK4_HAVE_BZLIB_H
+
+
+Bzip2 and libbzip2 library license
+==================================
+This program, "bzip2", the associated library "libbzip2", and all
+documentation, are copyright (C) 1996-2007 Julian R Seward. All
+rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+3. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Julian Seward, jseward@bzip.org
+bzip2/libbzip2 version 1.0.5 of 10 December 2007
+#endif
+
+$!end
+};
+
+
+
+/** Full computer name (including domain).
+*/
+static dkChar host_long[256];
+
+
+
+/** Short computer name (just host name).
+*/
+static dkChar host_short[256];
+
+
+
+/** User name.
+*/
+static dkChar user_name[256];
+
+
+
+/** Options used by the program.
+*/
+static const dk4_option_specification_t wprclean_options[] = {
+
+ /* Delete jobs submitted from local computer only.
+ */
+ { dkT('c'), dkT("computer"), DK4_OPT_ARG_NONE },
+
+ /* Produce verbose output.
+ */
+ { dkT('v'), dkT("verbose"), DK4_OPT_ARG_NONE }
+};
+
+
+
+/** Application structure.
+*/
+static dk4_app_t *app = NULL;
+
+
+
+/** Queue storage.
+*/
+static dk4_sto_t *s_q = NULL;
+
+
+
+/** Iterator for queue storage.
+*/
+static dk4_sto_it_t *i_q = NULL;
+
+
+
+/** Message texts, replaced by localized version if available.
+*/
+static const dkChar * const *msg = wprclean_kw_def;
+
+
+/** Number of elements in the wprclean_options array.
+*/
+static const size_t wprclean_sz_options =
+sizeof(wprclean_options)/sizeof(dk4_option_specification_t);
+
+
+
+/** Size of user_name buffer.
+*/
+static const size_t sz_user_name = DK4_SIZEOF(user_name,dkChar);
+
+
+
+/** Number of elements in the wprclean_kw_def array.
+*/
+static size_t sz_msg =
+(sizeof(wprclean_kw_def)/sizeof(DK4_PDKCHAR) - 1);
+
+
+
+/** Size of short host name buffer.
+*/
+static const size_t sz_host_short = DK4_SIZEOF(host_short,dkChar);
+
+
+
+/** Flag: Use separated short host name.
+*/
+static int have_short_host = 0;
+
+
+
+/** Flag: Delete jobs submitted from current host only.
+*/
+static int only_this_host = 0;
+
+
+
+/** Exit status code returned by the program.
+*/
+static int exval = EXIT_FAILURE;
+
+
+
+/** Flag: Verbose output.
+*/
+static int verbose = 0;
+
+
+
+/* This program is only available for the Windows platform!
+*/
+#if DK4_ON_WINDOWS
+
+
+
+/** Check presence of -c option, retrieve host name and short
+ host name if necessary.
+*/
+static
+void
+check_options(void)
+{
+ dkChar *ptr;
+ $? "+ check_options"
+ host_long[0] = dkT('\0');
+ host_short[0] = dkT('\0');
+ user_name[0] = dkT('\0');
+ if (0 != dk4app_opt_is_set_short(app, dkT('v'), NULL)) {
+ verbose = 1; $? ". verbose"
+ }
+ if (0 != dk4app_opt_is_set_short(app, dkT('c'), NULL)) { $? ". -c"
+ if (0 != dk4hostname(host_long, DK4_SIZEOF(host_long,dkChar), NULL)) {
+ only_this_host = 1; $? ". -c have host"
+ if (0 != dk4str_cpy_s(host_short, sz_host_short, host_long, NULL)) {
+ ptr = dk4str_chr(host_short, dkT('.')); $? ". -c host copied"
+ if (NULL != ptr) { $? ". -c short host"
+ *ptr = dkT('\0');
+ have_short_host = 1;
+ }
+#if TRACE_DEBUG
+ else { $? ". host name is short"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! buffer too short"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! host name"
+ }
+#endif
+ }
+ $? "- check_options"
+}
+
+
+
+/** Compare two queue names.
+ @param l Left queue name.
+ @param r Right queue name.
+ @param cr Comparison criteria, unused.
+ @return Comparison result.
+*/
+static
+int
+compare_queues(const void *l, const void *r, int cr)
+{
+ int back = 0;
+ if (NULL != l) {
+ if (NULL != r) {
+ back = dk4str_cmp((const dkChar *)l, (const dkChar *)r);
+ if (-1 > back) back = -1;
+ if ( 1 < back) back = 1;
+ } else back = 1;
+ } else {
+ if (NULL != r) back = -1;
+ }
+ return back;
+}
+
+
+
+/** Compare two print jobs within the same queue.
+ @param l Left job.
+ @param r Right job.
+ @param cr Comparison criteria (ignored).
+ @return Comparison result (inverted sort order).
+*/
+static
+int
+compare_print_jobs(const void *l, const void *r, int cr)
+{
+ const wprclean_printjob_t *jl = NULL;
+ const wprclean_printjob_t *jr = NULL;
+ int back = 0;
+ if (NULL != l) {
+ if (NULL != r) {
+ jl = (const wprclean_printjob_t *)l;
+ jr = (const wprclean_printjob_t *)r;
+ if (jl->position > jr->position) {
+ back = -1;
+ } else {
+ if (jr->position > jl->position) {
+ back = 1;
+ } else {
+ if (jl->jobid > jr->jobid) {
+ back = -1;
+ } else {
+ if (jr->jobid > jl->jobid) {
+ back = 1;
+ }
+ }
+ }
+ }
+ } else back = 1;
+ } else {
+ if (NULL != r) back = -1;
+ }
+ return back;
+}
+
+
+/** Allocate resources for list of print queues and iterator.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+setup_for_queue_list(void)
+{
+ int back = 0;
+ $? "+ setup_for_queue_list"
+ s_q = dk4sto_open(NULL);
+ if (NULL != s_q) { $? ". s_q"
+ dk4sto_set_comp(s_q, compare_queues, 0);
+ i_q = dk4sto_it_open(s_q, NULL);
+ if (NULL != i_q) { $? ". i_q"
+ back = 1;
+ }
+#if TRACE_DEBUG
+ else { $? "! i_q"
+ }
+#endif
+ }
+#if TRACE_DEBUG
+ else { $? "! s_q"
+ }
+#endif
+ $? "- setup_for_queue_list %d", back
+ return back;
+}
+
+
+
+/** Clean up print queues storage and iterator.
+*/
+static
+void
+cleanup_for_queue_list(void)
+{
+ dkChar *p;
+ $? "+ cleanup_for_queue_list"
+ /* Release all queue names saved, close iterator.
+ */
+ if (NULL != i_q) { $? ". clean up list contents"
+ dk4sto_it_reset(i_q);
+ do {
+ p = (dkChar *)dk4sto_it_next(i_q);
+ if (NULL != p) {
+ dk4mem_free(p);
+ }
+ } while (NULL != p); $? ". clean up iterator"
+ dk4sto_it_close(i_q); i_q = NULL;
+ }
+ /* Close storage.
+ */
+ if (NULL != s_q) { $? ". clean up container"
+ dk4sto_close(s_q); s_q = NULL;
+ }
+ $? "- cleanup_for_queue_list"
+}
+
+
+
+/** Retrieve list of print queue names.
+ @return 1 on success, 0 on error
+*/
+static
+int
+retrieve_queue_list(void)
+{
+#if DK4_ON_WINDOWS
+ char *peb; /* Result buffer */
+ dkChar *pn; /* Printer name */
+#if DK4_CHAR_SIZE > 1
+ PRINTER_INFO_2W *pi2; /* Printer information array */
+#else
+ PRINTER_INFO_2A *pi2; /* Printer information array */
+#endif
+ DWORD cbNeeded; /* Bytes needed */
+ DWORD cbReturned; /* Bytes returned */
+ DWORD szPeb; /* Size of peb */
+ DWORD i; /* Index current print queue */
+ BOOL res; /* Operation result */
+ int back = 0;
+ $? "+ retrieve_queue_list (Windows)"
+ cbNeeded = cbReturned = szPeb = (DWORD)0UL;
+#if DK4_CHAR_SIZE > 1
+ EnumPrintersW(PRINTER_ENUM_LOCAL,NULL,2,NULL,szPeb,&cbNeeded,&cbReturned);
+#else
+ EnumPrintersA(PRINTER_ENUM_LOCAL,NULL,2,NULL,szPeb,&cbNeeded,&cbReturned);
+#endif
+ if ((DWORD)0UL < cbNeeded) {
+ szPeb = cbNeeded;
+ peb = dk4mem_new_app(char, (size_t)cbNeeded, app);
+ if (NULL != peb) {
+ cbNeeded = cbReturned = (DWORD)0UL;
+#if DK4_CHAR_SIZE > 1
+ res = EnumPrintersW(
+ PRINTER_ENUM_LOCAL,NULL,2,(LPBYTE)peb,szPeb,&cbNeeded,&cbReturned
+ );
+#else
+ res = EnumPrintersA(
+ PRINTER_ENUM_LOCAL,NULL,2,(LPBYTE)peb,szPeb,&cbNeeded,&cbReturned
+ );
+#endif
+ if (res) {
+ if ((DWORD)0UL < cbReturned) {
+ pi2 = (PRINTER_INFO_2 *)peb;
+ back = 1;
+ for (i = (DWORD)0UL; i < cbReturned; i++) {
+ if (NULL != pi2->pPrinterName) {
+ pn = dk4str_dup(pi2->pPrinterName, NULL);
+ if (NULL != pn) {
+ if (0 == dk4sto_add(s_q, pn, NULL)) {
+ dk4mem_free(pn); $? "! sto add"
+ back = 0;
+ exval = EXIT_FAILURE;
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ }
+ } else { $? "! strdup"
+ back = 0;
+ exval = EXIT_FAILURE;
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ }
+ } else { $? "! missing printer name"
+ back = 0;
+ exval = EXIT_FAILURE;
+ /* ERROR: Invalid printer configuration */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 1);
+ }
+ pi2++;
+ }
+ } else { $? ". no printers found"
+ }
+ } else { $? "! enumeration"
+ exval = EXIT_FAILURE;
+ /* ERROR: Printer enumeration failed */
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 2);
+ }
+ dk4mem_release(peb);
+ } else { $? "! memory"
+ exval = EXIT_FAILURE;
+ }
+ } else { $? ". no local printers"
+ }
+ $? "- retrieve_queue_list %d (Windows)", back
+ return back;
+#else
+ return 1;
+#endif
+}
+
+
+
+/** Remove jobs from one print queue.
+*/
+static
+void
+handle_one_queue(const dkChar *pn)
+{
+ char *pc1 = NULL; /* First buffer */
+ char *pc2 = NULL; /* Second buffer */
+ dk4_sto_t *s_j = NULL; /* Jobs container */
+ dk4_sto_it_t *i_j = NULL; /* Jobs iterator */
+#if DK4_CHAR_SIZE > 1
+ PRINTER_INFO_2W *pi2 = NULL; /* Printer info */
+ JOB_INFO_1W *ji1 = NULL; /* Print job info */
+#else
+ PRINTER_INFO_2A *pi2 = NULL; /* Printer info */
+ JOB_INFO_1A *ji1 = NULL; /* Print job info */
+#endif
+ wprclean_printjob_t *pj = NULL; /* New print job */
+ HANDLE h_pr = INVALID_HANDLE_VALUE; /* Printer handle */
+ DWORD sz1 = (DWORD)0UL; /* Size provided */
+ DWORD sz2 = (DWORD)0UL; /* Size needed */
+ DWORD sz3 = (DWORD)0UL; /* Size provided */
+ DWORD sz4 = (DWORD)0UL; /* Size needed */
+ DWORD sz5 = (DWORD)0UL; /* No print jobs */
+ DWORD nJobs = (DWORD)0UL; /* Number of jobs */
+ DWORD i = (DWORD)0UL; /* Current job index */
+ int mm = 0; /* Machine matches */
+ int um = 0; /* User matches */
+ BOOL bres = FALSE; /* Printer open res */
+ BOOL br1 = FALSE; /* GetPrinter res */
+ BOOL br2 = FALSE; /* GetPrinter res */
+ BOOL br3 = FALSE; /* EnumJobs res */
+ BOOL br4 = FALSE; /* EnumJobs res */
+ BOOL br5 = FALSE; /* SetJob res */
+ $? "+ handle_one_queue"
+ /* Prepare data structures.
+ */
+ s_j = dk4sto_open(NULL);
+ if (NULL == s_j) { $? "! memory"
+ exval = EXIT_FAILURE;
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ goto finished;
+ }
+ dk4sto_set_comp(s_j, compare_print_jobs, 0);
+ i_j = dk4sto_it_open(s_j, NULL);
+ if (NULL == i_j) { $? "! memory"
+ exval = EXIT_FAILURE;
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ goto finished;
+ }
+ /* Open printer
+ */
+#if DK4_CHAR_SIZE > 1
+ bres = OpenPrinterW(pn, &h_pr, NULL);
+#else
+ bres = OpenPrinterA(pn, &h_pr, NULL);
+#endif
+ if (!(bres)) { $? "! OpenPrinter"
+ h_pr = INVALID_HANDLE_VALUE;
+ exval = EXIT_FAILURE;
+ /* ERROR: Failed to open printer */
+ dk4app_log_3(app, msg, sz_msg, DK4_LL_ERROR, 3, 4, pn);
+ goto finished;
+ }
+ /* Retrieve number of jobs
+ */
+#if DK4_CHAR_SIZE > 1
+ br1 = GetPrinterW(h_pr, 2, NULL, (DWORD)0UL, &sz1);
+#else
+ br1 = GetPrinterA(h_pr, 2, NULL, (DWORD)0UL, &sz1);
+#endif
+ if ((DWORD)0UL == sz1) { $? "! GetPrinter (1)"
+ $? ". br1 = %d", ((br1) ? 1 : 0)
+ $? ". sz1 = %lu", (unsigned long)sz1
+ exval = EXIT_FAILURE;
+ /* ERROR: Failed to request print queue */
+ dk4app_log_3(app, msg, sz_msg, DK4_LL_ERROR, 5, 6, pn);
+ goto finished;
+ }
+ if ((DWORD)0UL == sz1) { $? "! mem size"
+ exval = EXIT_FAILURE;
+ /* ERROR: Failed to request print queue */
+ dk4app_log_3(app, msg, sz_msg, DK4_LL_ERROR, 5, 6, pn);
+ goto finished;
+ }
+ pc1 = dk4mem_new_app(char,(size_t)sz1,app);
+ if (NULL == pc1) { $? "! memory"
+ exval = EXIT_FAILURE;
+ goto finished;
+ }
+#if DK4_CHAR_SIZE > 1
+ br2 = GetPrinterW(h_pr, 2, pc1, sz1, &sz2);
+#else
+ br2 = GetPrinterA(h_pr, 2, pc1, sz1, &sz2);
+#endif
+ if (!(br2)) { $? "! GetPrinter (2)"
+ exval = EXIT_FAILURE;
+ /* ERROR: GetPrinter failed */
+ dk4app_log_3(app, msg, sz_msg, DK4_LL_ERROR, 9, 10, pn);
+ goto finished;
+ }
+ if (sz2 > sz1) { $? "! size mismatch"
+ exval = EXIT_FAILURE;
+ /* ERROR: Number of bytes increased. */
+ dk4app_log_3(app, msg, sz_msg, DK4_LL_ERROR, 9, 10, pn);
+ goto finished;
+ }
+ pi2 = (PRINTER_INFO_2 *)pc1;
+ nJobs = pi2->cJobs;
+ if ((DWORD)0UL == nJobs) { $? ". no jobs in queue"
+ goto finished;
+ }
+ /* Retrieve job data and build sorted storage
+ */
+#if DK4_CHAR_SIZE > 1
+ br3 = EnumJobsW(
+ h_pr, (DWORD)0UL, nJobs, 1, NULL, (DWORD)0UL, &sz3, &sz4
+ );
+#else
+ br3 = EnumJobsW(
+ h_pr, (DWORD)0UL, nJobs, 1, NULL, (DWORD)0UL, &sz3, &sz4
+ );
+#endif
+ if ((!(br3)) || ((DWORD)0UL == sz3)) { $? "! EnumJobs (1)"
+ exval = EXIT_FAILURE;
+ /* ERROR: Failed to find required byte number */
+ dk4app_log_3(app, msg, sz_msg, DK4_LL_ERROR, 7, 8, pn);
+ goto finished;
+ }
+ pc2 = dk4mem_new_app(char,(size_t)sz3,app);
+ if (NULL == pc2) { $? "! memory"
+ exval = EXIT_FAILURE;
+ goto finished;
+ }
+ sz4 = (DWORD)0UL;
+#if DK4_CHAR_SIZE > 1
+ br4 = EnumJobsW(
+ h_pr, (DWORD)0UL, nJobs, 1, pc2, sz3, &sz4, &sz5
+ );
+#else
+ br4 = EnumJobsW(
+ h_pr, (DWORD)0UL, nJobs, 1, pc2, sz3, &sz4, &sz5
+ );
+#endif
+ if (!(br4)) { $? "! EnumJobs (2)"
+ exval = EXIT_FAILURE;
+ /* ERROR: EnumJobs */
+ dk4app_log_3(app, msg, sz_msg, DK4_LL_ERROR, 7, 8, pn);
+ goto finished;
+ }
+ if (sz4 > sz3) { $? "! EnumJobs (3)"
+ exval = EXIT_FAILURE;
+ /* ERROR: Number of bytes changed */
+ dk4app_log_3(app, msg, sz_msg, DK4_LL_ERROR, 7, 8, pn);
+ goto finished;
+ }
+#if DK4_CHAR_SIZE > 1
+ ji1 = (JOB_INFO_1W *)pc2;
+#else
+ ji1 = (JOB_INFO_1A *)pc2;
+#endif
+ for (i = (DWORD)0UL; i < sz5; i++) {
+ mm = 1;
+ um = 1;
+ if (0 != only_this_host) { $? ". must check host"
+ if (NULL != ji1->pMachineName) { $? ". mismatch"
+ if (0 != dk4str_casecmp(host_long, ji1->pMachineName)) {
+ mm = 0;
+ if (0 != have_short_host) { $? ". also short name"
+ if (0 == dk4str_casecmp(host_short, ji1->pMachineName)) {
+ mm = 1; $? ". short name match"
+ }
+ }
+ }
+ }
+ }
+ if (NULL != ji1->pUserName) {
+ if (0 != dk4str_casecmp(user_name, ji1->pUserName)) {
+ um = 0;
+ }
+ }
+ else { $? ". no user name job"
+ um = 0;
+ }
+ if ((0 != mm) && (0 != um)) { $? ". match"
+ pj = dk4mem_new_app(wprclean_printjob_t,1,app);
+ if (NULL != pj) {
+ pj->position = i;
+ pj->jobid = ji1->JobId;
+ $? ". schedule for deletion %lu %lu", (unsigned long)i, (unsigned long)(ji1->JobId)
+ if (0 == dk4sto_add(s_j, pj, NULL)) { $? "! memory (add)"
+ dk4mem_free(pj);
+ exval = EXIT_FAILURE;
+ /* ERROR: Memory */
+ dk4app_log_base1(app, DK4_LL_ERROR, 90);
+ }
+ } else { $? "! memory"
+ exval = EXIT_FAILURE;
+ }
+ }
+ ji1++;
+ }
+ /* Remove print jobs from queue
+ */
+ dk4sto_it_reset(i_j);
+ do {
+ pj = (wprclean_printjob_t *)dk4sto_it_next(i_j);
+ if (NULL != pj) { $? ". delete job %lu", (unsigned long)(pj->jobid)
+#if DK4_CHAR_SIZE > 1
+ br5 = SetJobW(h_pr, pj->jobid, 0, NULL, JOB_CONTROL_DELETE);
+#else
+ br5 = SetJobA(h_pr, pj->jobid, 0, NULL, JOB_CONTROL_DELETE);
+#endif
+ if (!(br5)) { $? "! failed to delete job"
+ exval = EXIT_FAILURE;
+ /* ERROR: Failed to remove job */
+ dk4app_log_3(app, msg, sz_msg, DK4_LL_ERROR, 11, 12, pn);
+ }
+ else { $? ". job deleted"
+ }
+ }
+ } while(NULL != pj);
+
+ /* Final cleanup.
+ */
+ finished:
+ if (NULL != pc2) {
+ dk4mem_free(pc2);
+ }
+ if (NULL != pc1) {
+ dk4mem_free(pc1);
+ }
+ if (bres) {
+ ClosePrinter(h_pr);
+ }
+ if (NULL != i_j) {
+ dk4sto_it_reset(i_j);
+ do {
+ pj = (wprclean_printjob_t *)dk4sto_it_next(i_j);
+ if (NULL != pj) {
+ dk4mem_free(pj);
+ }
+ } while(NULL != pj);
+ dk4sto_it_close(i_j);
+ }
+ if (NULL != s_j) {
+ dk4sto_close(s_j);
+ }
+ $? "- handle_one_queue"
+}
+
+
+
+/** Remove all print jobs from local queues.
+*/
+static
+void
+remove_all_print_jobs(void)
+{
+ dkChar *pn;
+
+ check_options();
+ if (0 != dk4user_get_logname(user_name, sz_user_name, 1, NULL)) {
+ if (setup_for_queue_list()) {
+ exval = EXIT_SUCCESS;
+ if (retrieve_queue_list()) {
+ dk4sto_it_reset(i_q);
+ do {
+ pn = (dkChar *)dk4sto_it_next(i_q);
+ if (NULL != pn) {
+ handle_one_queue(pn);
+ }
+ } while (NULL != pn);
+ }
+ }
+ cleanup_for_queue_list();
+ } else {
+ }
+}
+
+#endif
+
+
+
+/** Main function.
+ @param argc Number of command line arguments.
+ @param argv Command line arguments array.
+ @return 0 on success, all other values indicate errors.
+*/
+#if DK4_CHAR_SIZE > 1
+int wmain(int argc, wchar_t *argv[])
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ $!trace-init wprclean.deb
+ $? "+ main"
+ app = dk4app_open_cmd(
+ argc, argv, wprclean_options, wprclean_sz_options,
+ wprclean_kwnl[0], DKT_VERSION_DK,
+ wprclean_kwnl[1], wprclean_help_text, wprclean_license_text
+ );
+ if (NULL != app) {
+ sz_msg = dk4app_string_table_size(wprclean_kw_def);
+ msg = dk4app_string_table(app, wprclean_kwnl[2], wprclean_kw_def);
+ if (0 != dk4app_can_run_normally(app)) {
+#if DK4_ON_WINDOWS
+ remove_all_print_jobs();
+#else
+ dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, 0);
+#endif
+ } else {
+ if (0 != dk4app_help_version_license(app)) {
+ exval = EXIT_SUCCESS;
+ }
+ }
+ dk4app_close(app);
+ }
+ $? "- main %d", exval
+ $!trace-end
+ exit(exval); return exval;
+}
+
diff --git a/support/dktools/wxbmeps.h b/support/dktools/wxbmeps.h
new file mode 100644
index 0000000000..20bfed877b
--- /dev/null
+++ b/support/dktools/wxbmeps.h
@@ -0,0 +1,119 @@
+
+#ifndef WXBMEPS_H_INCLUDED
+#define WXBMEPS_H_INCLUDED 1
+
+#ifdef DK3_USE_WX
+#undef DK3_USE_WX
+#endif
+/** Use wxWidgets libraries to build GUI programs.
+*/
+#define DK3_USE_WX 1
+
+#include <dk3all.h>
+#if 0
+#include "dkt-version.h"
+#endif
+#include "dk4verswx.h"
+
+#include <wx/wxprec.h>
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#include <wx/wx.h>
+#endif
+#include <wx/arrstr.h>
+#include <wx/config.h>
+#include <wx/filename.h>
+#include <wx/gbsizer.h>
+#include <wx/thread.h>
+#include <wx/gauge.h>
+#include <wx/help.h>
+#include <wx/fs_zip.h>
+#include <wx/cmdline.h>
+#include <wx/dir.h>
+
+#include "dk3wxs.h"
+#include "dk3bmeo.h"
+#include "dk3bmeps.h"
+#include "dk3paper.h"
+#include "dk3bm.h"
+#include "dk3bmj.h"
+
+#include "DkWxAppHelper.h"
+#include "DkWxFrame.h"
+#include "DkWxCommunicator.h"
+#include "DkWxProgressDialog.h"
+#include "DkWxHelpController.h"
+#include "DkWxColorView.h"
+
+#include "DkWxBmepsThread.h"
+#include "DkWxBmepsApp.h"
+#include "DkWxBmepsFrame.h"
+#include "DkWxBmepsOptionsDialog.h"
+
+
+
+/** @defgroup wxbmepseventids Event ids for wxbmeps. */
+/**@{*/
+/** File / Exit menu item.
+*/
+#define DkWxBmeps_Quit wxID_EXIT
+
+/** Help / About menu item.
+*/
+#define DkWxBmeps_About wxID_ABOUT
+
+/** Id for main frame.
+*/
+#define DkWxBmeps_MainWindow (wxID_HIGHEST + 1)
+
+/** File / Directory menu item.
+*/
+#define DkWxBmeps_ChooseDirectory (DkWxBmeps_MainWindow + 1)
+
+/** File / Options menu item.
+*/
+#define DkWxBmeps_SetOptions (DkWxBmeps_ChooseDirectory + 1)
+
+/** Options / Reset menu.
+*/
+#define DkWxBmeps_ResetOptions (DkWxBmeps_SetOptions + 1)
+
+/** File / Run menu item.
+*/
+#define DkWxBmeps_Run (DkWxBmeps_ResetOptions + 1)
+
+/** Help / Contents menu.
+*/
+#define DkWxBmeps_Help_Contents (DkWxBmeps_Run + 1)
+
+/** Event: Output format changed.
+*/
+#define DkWxBmeps_OuputFormat (DkWxBmeps_Help_Contents + 1)
+
+/** Event: Output type changed.
+*/
+#define DkWxBmeps_OutputType (DkWxBmeps_OuputFormat + 1)
+
+/** Event: Resolution type changed.
+*/
+#define DkWxBmeps_ResolutionType (DkWxBmeps_OutputType + 1)
+
+/** Event: Draft mode setting changed.
+*/
+#define DkWxBmeps_Draft (DkWxBmeps_ResolutionType + 1)
+
+/** Event: PS level changed.
+*/
+#define DkWxBmeps_PsLevel (DkWxBmeps_Draft + 1)
+
+/** Event: Interpolation flag changed.
+*/
+#define DkWxBmeps_Interpolation (DkWxBmeps_PsLevel + 1)
+
+
+/**@}*/
+
+#endif
+
diff --git a/support/dktools/wxbmpp.desktop b/support/dktools/wxbmpp.desktop
new file mode 100644
index 0000000000..4ca335e122
--- /dev/null
+++ b/support/dktools/wxbmpp.desktop
@@ -0,0 +1,12 @@
+
+[Desktop Entry]
+Encoding=UTF-8
+Categories=Application;Graphics;
+Name=wxbmpp
+Comment=Converter from PNG/JPEG/TIFF to PDF/EPS
+Comment[de]=Konvertierung von PNG/JPEG/TIFF zu PDF/EPS
+Exec=/usr/local/bin/wxbmpp %f
+Terminal=0
+Type=Application
+Icon=/usr/local/share/dktools/dkicon.ico
+
diff --git a/support/dktools/wxbmpp.rc b/support/dktools/wxbmpp.rc
new file mode 100644
index 0000000000..5516883654
--- /dev/null
+++ b/support/dktools/wxbmpp.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Bitmap to PS/PDF converter (GUI)\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "Bitmap to PS/PDF converter (GUI)\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "wxbmpp\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/wxcs.cpp b/support/dktools/wxcs.cpp
new file mode 100644
index 0000000000..c78b058ca6
--- /dev/null
+++ b/support/dktools/wxcs.cpp
@@ -0,0 +1,53 @@
+
+#include "dk4conf.h"
+#include <stdio.h>
+#if DK4_HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if DK4_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if DK4_HAVE_PROCESS_H
+#include <process.h>
+#endif
+
+
+
+#if DK4_HAVE_WXWIDGETS
+
+#include "wx/wxprec.h"
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+
+int main(int argc, char *argv[])
+{
+ printf("/**\t@file\tdk4wxcs.h\tConfigure size of wide characters.\n*/\n\n");
+ printf("#ifndef DK4WXCSZ_H_INCLUDED\n");
+ printf("/** Protection against multiple inclusions. */\n");
+ printf("#define DK4WXCSZ_H_INCLUDED 1\n\n");
+ printf("/** Size of wxChar.\n*/\n");
+ printf("#define DK4_SIZEOF_WXCHAR %u\n\n", (unsigned)sizeof(wxChar));
+ printf("#endif\n");
+ return 0;
+}
+
+#else
+
+int main(int argc, char *argv[])
+{
+ printf("/**\t@file\tdk4wxcs.h\tConfigure size of wide characters.\n*/\n\n");
+ printf("#ifndef DK4WXCSZ_H_INCLUDED\n");
+ printf("/** Protection against multiple inclusions. */\n");
+ printf("#define DK4WXCSZ_H_INCLUDED 1\n\n");
+ printf("/** Size of wxChar.\n*/\n");
+ printf("#define DK4_SIZEOF_WXCHAR 0\n\n");
+ printf("#endif\n");
+ return 0;
+}
+
+#endif
+
diff --git a/support/dktools/wxdkclock.desktop b/support/dktools/wxdkclock.desktop
new file mode 100644
index 0000000000..d981e14756
--- /dev/null
+++ b/support/dktools/wxdkclock.desktop
@@ -0,0 +1,12 @@
+
+[Desktop Entry]
+Encoding=UTF-8
+Categories=Application;Clock;
+Name=DK clock
+Name[de]=Uhr
+Comment=Simple clock with one alert
+Comment[de]=Einfache Uhr mit einem Alarm
+Exec=/usr/local/bin/wxdkclock
+Terminal=0
+Type=Application
+Icon=/usr/local/share/dktools/dkclock.ico
diff --git a/support/dktools/wxdkclock.h b/support/dktools/wxdkclock.h
new file mode 100644
index 0000000000..59714b4793
--- /dev/null
+++ b/support/dktools/wxdkclock.h
@@ -0,0 +1,123 @@
+
+#ifndef H_INCLUDED_wxdkclock
+/** Include file only once.
+*/
+#define H_INCLUDED_wxdkclock 1
+
+#ifdef DK3_USE_WX
+#undef DK3_USE_WX
+#endif
+/** Use wxWidgets libraries to build GUI programs.
+*/
+#define DK3_USE_WX 1
+
+#include <dk3all.h>
+
+#include <wx/wxprec.h>
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#include <wx/wx.h>
+#endif
+#include <wx/arrstr.h>
+#include <wx/config.h>
+#include <wx/filename.h>
+#include <wx/gbsizer.h>
+#include <wx/thread.h>
+#include <wx/gauge.h>
+#include <wx/help.h>
+#include <wx/fs_zip.h>
+#include <wx/cmdline.h>
+#include <wx/dir.h>
+#include <wx/spinctrl.h>
+#include <wx/checkbox.h>
+#include <wx/taskbar.h>
+#include <wx/colordlg.h>
+
+/* __CHANGE__ 018: Add futher wxWidgets header files.
+*/
+
+#include <dk3wxs.h>
+
+#include <DkWxAppHelper.h>
+#include <DkWxFrame.h>
+#include <DkWxCommunicator.h>
+#include <DkWxProgressDialog.h>
+#include <DkWxHelpController.h>
+#include <DkWxColorView.h>
+#include <DkWxBufferedControl.h>
+#include <DkWxProcessingController.h>
+#include <DkWxProcessingIdleController.h>
+
+#include "DkClockData.h"
+#include "DkClockView.h"
+#include "DkClockTaskbarIcon.h"
+#include "DkClockOptionsDialog.h"
+#include "DkClockApp.h"
+#include "DkClockFrame.h"
+
+/* __CHANGE__ 018: Add header files for further classes and modules.
+*/
+
+/** @defgroup wxdkclockwxids wxWidgets IDs.
+*/
+/**@{*/
+/** Exit application.
+*/
+#define DkClockFrame_Quit (wxID_EXIT)
+
+/** Main window ID.
+*/
+#define DkClockFrame_MainWindow ((wxID_HIGHEST) + 1)
+
+/** Show version dialog box.
+*/
+#define DkClockFrame_Help_About ((DkClockFrame_MainWindow) + 1)
+
+/** Open table of contents for online help.
+*/
+#define DkClockFrame_Help_Contents ((DkClockFrame_Help_About) + 1)
+
+/** Menu item Edit Options.
+*/
+#define DkClockFrame_Edit_Options ((DkClockFrame_Help_Contents) + 1)
+
+/** Check box to enable or disable alert.
+*/
+#define DkClockOptions_Enable ((DkClockFrame_Edit_Options) + 1)
+
+/** Timer ID.
+*/
+#define DkClockFrame_Timer ((DkClockOptions_Enable) + 1)
+
+/** ID of task bar icon.
+*/
+#define DkClockFrame_TaskBarIcon ((DkClockFrame_Timer) + 1)
+
+/** Task bar icon popup menu item: Restore.
+*/
+#define DkClockTaskBar_Restore ((DkClockFrame_TaskBarIcon) + 1)
+
+/** Task bar icon popup menu item: Exit application.
+*/
+#define DkClockTaskBar_Exit ((DkClockTaskBar_Restore) + 1)
+
+/** Menu item: Hide.
+*/
+#define DkClockFrame_Hide ((DkClockTaskBar_Exit) + 1)
+
+/** Menu item: Set clock colour.
+*/
+#define DkClockFrame_NormalColour ((DkClockFrame_Hide) + 1)
+
+/** Menu item: Set alert colour.
+*/
+#define DkClockFrame_AlertColour ((DkClockFrame_NormalColour) + 1)
+
+/* __CHANGE__ 017: Add further IDs here as needed.
+*/
+/**@}*/
+
+#endif
+
diff --git a/support/dktools/wxdkclock.rc b/support/dktools/wxdkclock.rc
new file mode 100644
index 0000000000..bcf22d938b
--- /dev/null
+++ b/support/dktools/wxdkclock.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Simple clock with one alert (GUI)\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "Simple clock with one alert (GUI)\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "wxdkclock\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/wxdkct.desktop b/support/dktools/wxdkct.desktop
new file mode 100644
index 0000000000..4438f94103
--- /dev/null
+++ b/support/dktools/wxdkct.desktop
@@ -0,0 +1,11 @@
+
+[Desktop Entry]
+Encoding=UTF-8
+Categories=Application;Development;
+Name=wxdkct
+Comment=C, C++, Objective-C and Java Tool
+Comment[de]=Tool für C, C++, Objective-C und Java
+Exec=/usr/local/bin/wxdkct
+Terminal=0
+Type=Application
+Icon=/usr/local/share/dktools/dkicon.ico
diff --git a/support/dktools/wxdkct.rc b/support/dktools/wxdkct.rc
new file mode 100644
index 0000000000..b68af65d7d
--- /dev/null
+++ b/support/dktools/wxdkct.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Dirk Krause's C tool (GUI)\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "Dirk Krause's C tool (GUI)\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "wxdkct\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/wxdkfcs.desktop b/support/dktools/wxdkfcs.desktop
new file mode 100644
index 0000000000..78b7f3f8ae
--- /dev/null
+++ b/support/dktools/wxdkfcs.desktop
@@ -0,0 +1,11 @@
+
+[Desktop Entry]
+Encoding=UTF-8
+Categories=System;Utility;FileTools;
+Name=wxdkfcs
+Comment=Create file checksums
+Comment[de]=Prüfsummen für Dateien
+Exec=/usr/local/bin/wxdkfcs
+Terminal=0
+Type=Application
+Icon=/usr/local/share/dktools/dkicon.ico
diff --git a/support/dktools/wxdkfcs.h b/support/dktools/wxdkfcs.h
new file mode 100644
index 0000000000..83c293520c
--- /dev/null
+++ b/support/dktools/wxdkfcs.h
@@ -0,0 +1,147 @@
+#ifndef H_INCLUDED_wxdkfcs
+/** Include file only once.
+*/
+#define H_INCLUDED_wxdkfcs 1
+
+#ifndef DK4CONF_H_INCLUDED
+#include <dk4conf.h>
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include <dk4types.h>
+#endif
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef WX_ARRSTR_H_INCLUDED
+#include <wx/arrstr.h>
+#define WX_ARRSTR_H_INCLUDED 1
+#endif
+
+#ifndef WX_CONFIG_H_INCLUDED
+#include <wx/config.h>
+#define WX_CONFIG_H_INCLUDED 1
+#endif
+
+#ifndef WX_FILENAME_H_INCLUDED
+#include <wx/filename.h>
+#define WX_FILENAME_H_INCLUDED 1
+#endif
+
+#ifndef WX_FILE_H_INCLUDED
+#include <wx/file.h>
+#define WX_FILE_H_INCLUDED 1
+#endif
+
+#ifndef WX_GBSIZER_H_INCLUDED
+#include <wx/gbsizer.h>
+#define WX_GBSIZER_H_INCLUDED 1
+#endif
+
+#ifndef WX_THREAD_H_INCLUDED
+#include <wx/thread.h>
+#define WX_THREAD_H_INCLUDED 1
+#endif
+
+#ifndef WX_GAUGE_H_INCLUDED
+#include <wx/gauge.h>
+#define WX_GAUGE_H_INCLUDED 1
+#endif
+
+#ifndef WX_HELP_H_INCLUDED
+#include <wx/help.h>
+#define WX_HELP_H_INCLUDED 1
+#endif
+
+#ifndef WX_FS_ZIP_H_INCLUDED
+#include <wx/fs_zip.h>
+#define WX_FS_ZIP_H_INCLUDED 1
+#endif
+
+#ifndef WX_CMDLINE_H_INCLUDED
+#include <wx/cmdline.h>
+#define WX_CMDLINE_H_INCLUDED 1
+#endif
+
+#ifndef WX_DIR_H_INCLUDED
+#include <wx/dir.h>
+#define WX_DIR_H_INCLUDED 1
+#endif
+
+#ifndef WX_GRID_H_INCLUDED
+#include <wx/grid.h>
+#define WX_GRID_H_INCLUDED 1
+#endif
+
+/* __CHANGE__ 018: Add futher wxWidgets header files.
+*/
+
+
+#ifndef DK4WXAPPLICTIONHELPER_H_INCLUDED
+#include <Dk4WxApplicationHelper.h>
+#endif
+
+#ifndef DK4WXFRAME_H_INCLUDED
+#include <Dk4WxFrame.h>
+#endif
+
+#ifndef DK4WXPROGRESSDIALOG_H_INCLUDED
+#include <Dk4WxProgressDialog.h>
+#endif
+
+#ifndef DK4WXHELPCONTROLLER_H_INCLUDED
+#include <Dk4WxHelpController.h>
+#endif
+
+#ifndef DK4WXAUTOSTARTCONTROLLER_H_INCLUDED
+#include <Dk4WxAutostartController.h>
+#endif
+
+#include "Dk4FcsApp.h"
+
+#include "Dk4FcsFrame.h"
+
+/* __CHANGE__ 018: Add header files for further classes and modules.
+*/
+
+/** IDs for menu items, buttons and other elements.
+*/
+enum {
+
+ /** Exit the application.
+ */
+ Dk4FcsFrame_Quit = wxID_EXIT ,
+
+ /** Open a file.
+ */
+ Dk4FcsFrame_Open = wxID_OPEN ,
+
+ /** Main window ID.
+ */
+ Dk4FcsFrame_MainWindow = ((wxID_HIGHEST) + 1) ,
+
+ /** Show version dialog box.
+ */
+ Dk4FcsFrame_Help_About ,
+
+ /** Open table of conents for online help.
+ */
+ Dk4FcsFrame_Help_Contents
+};
+
+#endif
+
diff --git a/support/dktools/wxdkfcs.rc b/support/dktools/wxdkfcs.rc
new file mode 100644
index 0000000000..dc727ba711
--- /dev/null
+++ b/support/dktools/wxdkfcs.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Checksum builder with GUI\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "Checksum builder with GUI\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "wxdkfcs\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/wxdkfcs.str b/support/dktools/wxdkfcs.str
new file mode 100644
index 0000000000..000bf6119d
--- /dev/null
+++ b/support/dktools/wxdkfcs.str
@@ -0,0 +1,83 @@
+#
+# 0: Menu "File"
+#
+File
+#
+# 1: Menu item "File/Exit"
+#
+Exit
+#
+# 2: Tool tip text for menu item "File/Exit"
+#
+Exit the application
+#
+# 3: Menu "Help"
+#
+Help
+#
+# 4: Menu item "Help/About"
+#
+About
+#
+# 5: Tooltip text for menu item "Help/About"
+#
+Show version information
+#
+# 6: Menu item "Help/Contents"
+#
+Contents
+#
+# 7: Tooltip text for menu item "Help/Contents"
+#
+Open table of contents
+#
+# 8: Initial status text
+#
+Ready
+#
+# 9: Copyright notice.
+#
+Copyright (c)
+#
+# 10: Dialog box title "About ..."
+#
+About
+#
+# 11: This program uses the following libraries
+#
+This program uses the following libraries:
+#
+# 12: See
+#
+See:
+#
+# 13: Default file name
+#
+File:
+#
+# 14 15 16 17 18 19 20: Label texts
+#
+MD5:
+SHA-1:
+SHA-224:
+SHA-256:
+SHA-384:
+SHA-512:
+RIPEMD-160:
+#
+# 21 22: Menu item "File / Open" and tool tip
+#
+Open
+Open a file
+#
+# 23 File chooser description: All files
+#
+All files
+#
+# 24 Dialog box title: Please choose file
+#
+Please choose file
+#
+# 25 Progress line.
+#
+Building file checksum.
diff --git a/support/dktools/wxdkhtb.h b/support/dktools/wxdkhtb.h
new file mode 100644
index 0000000000..aab823e607
--- /dev/null
+++ b/support/dktools/wxdkhtb.h
@@ -0,0 +1,80 @@
+
+#ifndef H_INCLUDED_wxdkhtb
+/** Include file only once.
+*/
+#define H_INCLUDED_wxdkhtb 1
+
+#ifdef DK3_USE_WX
+#undef DK3_USE_WX
+#endif
+/** Use wxWidgets libraries to build GUI programs.
+*/
+#define DK3_USE_WX 1
+
+#include <dk3all.h>
+#if 0
+#include "dkt-version.h"
+#endif
+
+#include <wx/wxprec.h>
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#include <wx/wx.h>
+#endif
+#include <wx/arrstr.h>
+#include <wx/config.h>
+#include <wx/filename.h>
+#include <wx/gbsizer.h>
+#include <wx/thread.h>
+#include <wx/gauge.h>
+#include <wx/help.h>
+#include <wx/fs_zip.h>
+#include <wx/cmdline.h>
+#include <wx/dir.h>
+/* __CHANGE__ 018: Add futher wxWidgets header files.
+*/
+#include <wx/html/helpctrl.h>
+
+#include <dk3wxs.h>
+#include "dk4verswx.h"
+
+#include <DkWxAppHelper.h>
+#include <DkWxFrame.h>
+#include <DkWxCommunicator.h>
+#include <DkWxProgressDialog.h>
+#include <DkWxHelpController.h>
+#include <DkWxColorView.h>
+
+#include "DkWxHtbApp.h"
+#include "DkWxHtbFrame.h"
+
+/* __CHANGE__ 018: Add header files for further classes and modules.
+*/
+
+/** @defgroup wxdkhtbwxids wxWidgets IDs.
+*/
+/**@{*/
+/** Exit application.
+*/
+#define DkWxHtbFrame_Quit (wxID_EXIT)
+
+/** Main window ID.
+*/
+#define DkWxHtbFrame_MainWindow ((wxID_HIGHEST) + 1)
+
+/** Show version dialog box.
+*/
+#define DkWxHtbFrame_Help_About ((DkWxHtbFrame_MainWindow) + 1)
+
+/** Open table of contents for online help.
+*/
+#define DkWxHtbFrame_Help_Contents ((DkWxHtbFrame_Help_About) + 1)
+
+/* __CHANGE__ 017: Add further IDs here as needed.
+*/
+/**@}*/
+
+#endif
+
diff --git a/support/dktools/wxdkhtb.rc b/support/dktools/wxdkhtb.rc
new file mode 100644
index 0000000000..a4aabe3027
--- /dev/null
+++ b/support/dktools/wxdkhtb.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "HTB help file viewer (GUI)\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "HTB help file viewer (GUI)\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "wxdkhtb\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/wxdkscrsz.h b/support/dktools/wxdkscrsz.h
new file mode 100644
index 0000000000..2ffcec02ec
--- /dev/null
+++ b/support/dktools/wxdkscrsz.h
@@ -0,0 +1,145 @@
+#ifndef H_INCLUDED_wxdkscrsz
+/** Include file only once.
+*/
+#define H_INCLUDED_wxdkscrsz 1
+
+#ifndef DK4CONF_H_INCLUDED
+#include <dk4conf.h>
+#endif
+
+#include <stdio.h>
+
+#if DK4_HAVE_STDLIB_H
+#ifndef STDLIB_H_INCLUDED
+#include <stdlib.h>
+#define STDLIB_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include <dk4types.h>
+#endif
+
+#if DK4_HAVE_WINDOWS_H
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef WX_ARRSTR_H_INCLUDED
+#include <wx/arrstr.h>
+#define WX_ARRSTR_H_INCLUDED 1
+#endif
+
+#ifndef WX_CONFIG_H_INCLUDED
+#include <wx/config.h>
+#define WX_CONFIG_H_INCLUDED 1
+#endif
+
+#ifndef WX_FILENAME_H_INCLUDED
+#include <wx/filename.h>
+#define WX_FILENAME_H_INCLUDED 1
+#endif
+
+#ifndef WX_GBSIZER_H_INCLUDED
+#include <wx/gbsizer.h>
+#define WX_GBSIZER_H_INCLUDED 1
+#endif
+
+#ifndef WX_THREAD_H_INCLUDED
+#include <wx/thread.h>
+#define WX_THREAD_H_INCLUDED 1
+#endif
+
+#ifndef WX_GAUGE_H_INCLUDED
+#include <wx/gauge.h>
+#define WX_GAUGE_H_INCLUDED 1
+#endif
+
+#ifndef WX_HELP_H_INCLUDED
+#include <wx/help.h>
+#define WX_HELP_H_INCLUDED 1
+#endif
+
+#ifndef WX_FS_ZIP_H_INCLUDED
+#include <wx/fs_zip.h>
+#define WX_FS_ZIP_H_INCLUDED 1
+#endif
+
+#ifndef WX_CMDLINE_H_INCLUDED
+#include <wx/cmdline.h>
+#define WX_CMDLINE_H_INCLUDED 1
+#endif
+
+#ifndef WX_DIR_H_INCLUDED
+#include <wx/dir.h>
+#define WX_DIR_H_INCLUDED 1
+#endif
+
+/* __CHANGE__ 018: Add futher wxWidgets header files.
+*/
+
+
+#ifndef DK4WXAPPLICTIONHELPER_H_INCLUDED
+#include <Dk4WxApplicationHelper.h>
+#endif
+
+#ifndef DK4WXFRAME_H_INCLUDED
+#include <Dk4WxFrame.h>
+#endif
+
+#ifndef DK4WXPROGRESSDIALOG_H_INCLUDED
+#include <Dk4WxProgressDialog.h>
+#endif
+
+#ifndef DK4WXHELPCONTROLLER_H_INCLUDED
+#include <Dk4WxHelpController.h>
+#endif
+
+#include "ScreenSizeApp.h"
+
+#include "ScreenSizeFrame.h"
+
+/* __CHANGE__ 018: Add header files for further classes and modules.
+*/
+
+/** IDs for menu items, buttons and other elements.
+*/
+enum {
+
+ /** Exit the application.
+ */
+ ScreenSizeFrame_Quit = wxID_EXIT ,
+
+ /** Main window ID.
+ */
+ ScreenSizeFrame_MainWindow = ((wxID_HIGHEST) + 1) ,
+
+ /** Show version dialog box.
+ */
+ ScreenSizeFrame_Help_About ,
+
+ /** Open table of conents for online help.
+ */
+ ScreenSizeFrame_Help_Contents
+};
+
+#endif
+
diff --git a/support/dktools/wxdkscrsz.ico b/support/dktools/wxdkscrsz.ico
new file mode 100644
index 0000000000..4ce2dadf44
--- /dev/null
+++ b/support/dktools/wxdkscrsz.ico
Binary files differ
diff --git a/support/dktools/wxdkscrsz.rc b/support/dktools/wxdkscrsz.rc
new file mode 100644
index 0000000000..f5524143a2
--- /dev/null
+++ b/support/dktools/wxdkscrsz.rc
@@ -0,0 +1,37 @@
+aaaaa ICON wxdkscrsz.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Change Screen Size\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "Change Screen Size\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "ChangeScreenSize\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/wxdkscrsz.xpm b/support/dktools/wxdkscrsz.xpm
new file mode 100644
index 0000000000..2da6e1f593
--- /dev/null
+++ b/support/dktools/wxdkscrsz.xpm
@@ -0,0 +1,38 @@
+/* XPM */
+static const char *xpm_wxdkscrsz[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 15 1",
+/* colors */
+" c #F8DD5B",
+". c #F3E6A5",
+"X c #F2E39A",
+"o c #CAC3A0",
+"O c #FFD400",
+"+ c #A28E40",
+"@ c #A58900",
+"# c #E1D8AB",
+"$ c #F1E093",
+"% c #EDD974",
+"& c #6D5A00",
+"* c #FAD62D",
+"= c #D6D2B8",
+"- c #E4D89E",
+"; c None",
+/* pixels */
+"OOOOOOOOOOOOOOOO",
+"OOOOOOOOOOOOOOOO",
+"OOOOOOOOOOOOOOOO",
+"OOOOOOOOOOOOOOOO",
+" =X=X=X=X=X#Xoo ",
+" OOOOOOOOOO&&%%",
+"$=X#X#X#X#.+OO ",
+"$$OOOOOOOO%%OO%%",
+"--O&@@&@@O OO ",
+"$$O&O&@&OO%%OO%%",
+"--O&@@@@&O OO ",
+"$=$#$-$-$-#- %-%",
+"*#$#$-$-$-$% % *",
+"OOOOOOOOOOOOOOOO",
+"OOOOOOOOOOOOOOOO",
+"OOOOOOOOOOOOOOOO"
+};
diff --git a/support/dktools/wximgsz.desktop b/support/dktools/wximgsz.desktop
new file mode 100644
index 0000000000..8e50ad1470
--- /dev/null
+++ b/support/dktools/wximgsz.desktop
@@ -0,0 +1,11 @@
+
+[Desktop Entry]
+Encoding=UTF-8
+Categories=Application;Graphics;
+Name=wximgsz
+Comment=Suggest size pairs to rescale bitmap images
+Comment[de]=Größenvorschläge für Skalierung von Bitmap-Bildern
+Exec=/usr/local/bin/wximgsz
+Terminal=0
+Type=Application
+Icon=/usr/local/share/dktools/dkicon.ico
diff --git a/support/dktools/wximgsz.h b/support/dktools/wximgsz.h
new file mode 100644
index 0000000000..baabc2f3a6
--- /dev/null
+++ b/support/dktools/wximgsz.h
@@ -0,0 +1,86 @@
+
+#ifndef WXIMGSZ_H_INCLUDED
+/** Protection against multiple inclusion. */
+#define WXIMGSZ_H_INCLUDED 1
+
+#ifdef DK3_USE_WX
+#undef DK3_USE_WX
+#endif
+/** Use wxWidgets libraries to build GUI programs.
+*/
+#define DK3_USE_WX 1
+
+#include <dk3all.h>
+
+#if 0
+#include <dk3sock.h>
+#endif
+
+#if 0
+#include <dkt-version.h>
+#endif
+
+#include <wx/wxprec.h>
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#ifndef WX_PRECOMP
+#include <wx/wx.h>
+#endif
+#include <wx/config.h>
+#include <wx/filename.h>
+#include <wx/gbsizer.h>
+#include <wx/thread.h>
+#include <wx/gauge.h>
+#include <wx/help.h>
+#include <wx/fs_zip.h>
+#include <wx/cmdline.h>
+#include <wx/grid.h>
+#include <wx/version.h>
+
+#include "dk3wxs.h"
+#include "dk4verswx.h"
+
+#include "DkWxAppHelper.h"
+#include "DkWxFrame.h"
+#include "DkWxCommunicator.h"
+#include "DkWxProgressDialog.h"
+#include "DkWxHelpController.h"
+
+#include "DkWxImgszApp.h"
+#include "DkWxImgszFrame.h"
+#include "DkWxImgszOptionsDialog.h"
+
+/** Event ID: Exit application.
+*/
+#define DkWxImgsz_Quit wxID_EXIT
+
+/** Event ID: Show about dialog box.
+*/
+#define DkWxImgsz_About wxID_ABOUT
+
+/** Event ID: Main window ID.
+*/
+#define DkWxImgsz_MainWindow (wxID_HIGHEST + 1)
+
+/** Event ID: Open help contents.
+*/
+#define DkWxImgsz_Help (DkWxImgsz_MainWindow + 1)
+
+/** Event ID: Start calculation.
+*/
+#define DkWxImgsz_Run (DkWxImgsz_Help + 1)
+
+/** Choice in the action was made.
+*/
+#define DkWxImgsz_Choice (DkWxImgsz_Run + 1)
+
+/** Event ID: Extras -> Options.
+*/
+#define DkWxImgsz_Options (DkWxImgsz_Choice + 1)
+
+/** Event ID: Open file.
+*/
+#define DkWxImgsz_Open (DkWxImgsz_Options + 1)
+#endif
+
diff --git a/support/dktools/wximgsz.rc b/support/dktools/wximgsz.rc
new file mode 100644
index 0000000000..34686ac9de
--- /dev/null
+++ b/support/dktools/wximgsz.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Image rescale calculator (GUI)\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "Image rescale calculator (GUI)\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "wximgsz\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/wxpqdic.h b/support/dktools/wxpqdic.h
new file mode 100644
index 0000000000..2cbddeb59d
--- /dev/null
+++ b/support/dktools/wxpqdic.h
@@ -0,0 +1,265 @@
+#ifndef H_INCLUDED_wxpqdic
+/** Include file only once.
+*/
+#define H_INCLUDED_wxpqdic 1
+
+#ifndef DK4CONF_H_INCLUDED
+#include <dk4conf.h>
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include <dk4types.h>
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include <dk4error.h>
+#endif
+
+#ifndef DK4MEM_H_INCLUDED
+#include <dk4mem.h>
+#endif
+
+#ifndef DK4SOCK_H_INCLUDED
+#include <dk4sock.h>
+#endif
+
+#ifndef DK4TIME_H_INCLUDED
+#include <dk4time.h>
+#endif
+
+#ifndef WX_WXPREC_H_INCLUDED
+#include <wx/wxprec.h>
+#define WX_WXPREC_H_INCLUDED 1
+#endif
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#ifndef WX_WX_H_INCLUDED
+#include <wx/wx.h>
+#define WX_WX_H_INCLUDED 1
+#endif
+#endif
+
+#ifndef WX_ARRSTR_H_INCLUDED
+#include <wx/arrstr.h>
+#define WX_ARRSTR_H_INCLUDED 1
+#endif
+
+#ifndef WX_CONFIG_H_INCLUDED
+#include <wx/config.h>
+#define WX_CONFIG_H_INCLUDED 1
+#endif
+
+#ifndef WX_FILENAME_H_INCLUDED
+#include <wx/filename.h>
+#define WX_FILENAME_H_INCLUDED 1
+#endif
+
+#ifndef WX_GBSIZER_H_INCLUDED
+#include <wx/gbsizer.h>
+#define WX_GBSIZER_H_INCLUDED 1
+#endif
+
+#ifndef WX_THREAD_H_INCLUDED
+#include <wx/thread.h>
+#define WX_THREAD_H_INCLUDED 1
+#endif
+
+#ifndef WX_GAUGE_H_INCLUDED
+#include <wx/gauge.h>
+#define WX_GAUGE_H_INCLUDED 1
+#endif
+
+#ifndef WX_HELP_H_INCLUDED
+#include <wx/help.h>
+#define WX_HELP_H_INCLUDED 1
+#endif
+
+#ifndef WX_FS_ZIP_H_INCLUDED
+#include <wx/fs_zip.h>
+#define WX_FS_ZIP_H_INCLUDED 1
+#endif
+
+#ifndef WX_CMDLINE_H_INCLUDED
+#include <wx/cmdline.h>
+#define WX_CMDLINE_H_INCLUDED 1
+#endif
+
+#ifndef WX_DIR_H_INCLUDED
+#include <wx/dir.h>
+#define WX_DIR_H_INCLUDED 1
+#endif
+
+/* __CHANGE__ 018: Add futher wxWidgets header files.
+*/
+
+
+#ifndef DK4WXAPPLICTIONHELPER_H_INCLUDED
+#include <Dk4WxApplicationHelper.h>
+#endif
+
+#ifndef DK4WXFRAME_H_INCLUDED
+#include <Dk4WxFrame.h>
+#endif
+
+#ifndef DK4WXPROGRESSDIALOG_H_INCLUDED
+#include <Dk4WxProgressDialog.h>
+#endif
+
+#ifndef DK4WXHELPCONTROLLER_H_INCLUDED
+#include <Dk4WxHelpController.h>
+#endif
+
+#include "WxpqdicApp.h"
+
+#include "WxpqdicFrame.h"
+
+/* __CHANGE__ 018: Add header files for further classes and modules.
+*/
+
+
+
+/** IDs for menu items, buttons and other elements.
+*/
+enum {
+
+ /** Exit the application.
+ */
+ WxpqdicFrame_Quit = wxID_EXIT ,
+
+ /** Main window ID.
+ */
+ WxpqdicFrame_MainWindow = ((wxID_HIGHEST) + 1) ,
+
+ /** Show version dialog box.
+ */
+ WxpqdicFrame_Help_About ,
+
+ /** Open table of conents for online help.
+ */
+ WxpqdicFrame_Help_Contents ,
+
+ /** Update view.
+ */
+ WxpqdicFrame_View_Update ,
+
+ /** Timer event to handle.
+ */
+ WxpqdicFrame_Timer
+};
+
+
+
+/** Error codes during configuration phase.
+*/
+enum {
+
+ /** No error occured.
+ */
+ WXPQDIC_FRAME_ERROR_NONE = 0 ,
+
+ /** Failed to parse command line arguments.
+ */
+ WXPQDIC_FRAME_ERROR_PARSE ,
+
+ /** Not enough memory.
+ */
+ WXPQDIC_FRAME_ERROR_MEMORY ,
+
+ /** String conversion failed for host name.
+ */
+ WXPQDIC_FRAME_ERROR_STRCONV_HOSTNAME ,
+
+ /** No host name specified.
+ */
+ WXPQDIC_FRAME_ERROR_HOSTNAME ,
+
+ /** String conversion failed for queue name.
+ */
+ WXPQDIC_FRAME_ERROR_STRCONV_QUEUENAME ,
+
+ /** Queue name missing.
+ */
+ WXPQDIC_FRAME_ERROR_QUEUENAME ,
+
+ /** Port number out of range.
+ */
+ WXPQDIC_FRAME_ERROR_PORT_OOR ,
+
+ /** Port number is zero.
+ */
+ WXPQDIC_FRAME_ERROR_PORT_ZERO ,
+
+
+ /** String conversion failed for user name.
+ */
+ WXPQDIC_FRAME_ERROR_STRCONV_USERNAME ,
+
+ /** User name not found.
+ */
+ WXPQDIC_FRAME_ERROR_USERNAME ,
+
+ /** Local port number out of range.
+ */
+ WXPQDIC_FRAME_ERROR_LOCALPORT_OOR ,
+
+ /** Local port number 0.
+ */
+ WXPQDIC_FRAME_ERROR_LOCALPORT_ZERO ,
+
+ /** Bug: Failed to copy string to request.
+ */
+ WXPQDIC_FRAME_ERROR_BUG ,
+
+ /** Numeric overflow in size calculation.
+ */
+ WXPQDIC_FRAME_ERROR_SIZE_CALC_OVERFLOW ,
+
+ /** Failed to create UDP socket.
+ */
+ WXPQDIC_FRAME_ERROR_SOCKET
+
+};
+
+
+
+/** States.
+*/
+enum {
+ /** Have response for previous request.
+ */
+ WXPQDIC_STATE_OK = 0 ,
+
+ /** Request was sended, no response yet.
+ */
+ WXPQDIC_STATE_SENDED ,
+
+ /** Waiting too long for response.
+ */
+ WXPQDIC_STATE_TIMEOUT ,
+
+ /** Failed to send request.
+ */
+ WXPQDIC_STATE_SEND_FAILED
+
+};
+
+
+
+/** Error to show in status text.
+*/
+enum {
+ /** Failed to send request.
+ */
+ WXPQDIC_E_SEND_FAILED = 1 ,
+
+ /** No response from server.
+ */
+ WXPQDIC_E_NO_RESPONSE = 2
+};
+
+#endif
+
diff --git a/support/dktools/wxpqdic.rc b/support/dktools/wxpqdic.rc
new file mode 100644
index 0000000000..099f7b886f
--- /dev/null
+++ b/support/dktools/wxpqdic.rc
@@ -0,0 +1,37 @@
+aaaaa ICON dkicon.ico
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 4,8,3,0
+ PRODUCTVERSION 4,8,3,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Printqdi client (GUI)\0"
+ VALUE "CompanyName", "Dirk Krause\0"
+ VALUE "FileDescription", "Printqdi client (GUI)\0"
+ VALUE "FileVersion", "4.8.3\0"
+ VALUE "InternalName", "wxpqdic\0"
+ VALUE "LegalCopyright", "Copyright © 2017 Dirk Krause\0"
+ VALUE "ProductName", "Dirk Krause's tools\0"
+ VALUE "ProductVersion", "4.8.3\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
diff --git a/support/dktools/x.sed b/support/dktools/x.sed
new file mode 100644
index 0000000000..383815eb3c
--- /dev/null
+++ b/support/dktools/x.sed
@@ -0,0 +1,3 @@
+/[Cc]opyright[ \t][ \t]*[Yy]ear/s/\-2016/-xxxx/g
+/[Cc]opyright[ \t][ \t]*[Yy]ear/s/2016/2016-xxxx/g
+